diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index ac59f40000467c..89a0e5a4637dba 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "10.0.0-prerelease.25255.1", + "version": "10.0.0-prerelease.25405.1", "commands": [ "xharness" ] diff --git a/.devcontainer/android/Dockerfile b/.devcontainer/android/Dockerfile index bdbc7d68f258cb..06d8a2c9b23bf6 100644 --- a/.devcontainer/android/Dockerfile +++ b/.devcontainer/android/Dockerfile @@ -28,10 +28,10 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ SHELL ["/bin/bash", "-c"] -ENV NDK_VER=r23c -ENV SDK_VER=9123335_latest -ENV SDK_API_LEVEL=33 -ENV SDK_BUILD_TOOLS=33.0.1 +ENV NDK_VER=r27c +ENV SDK_VER=13114758_latest +ENV SDK_API_LEVEL=35 +ENV SDK_BUILD_TOOLS=35.0.0 ENV HOST_OS=linux ENV HOST_OS_SHORT=linux ENV ANDROID_NDK_ROOT=/android/android-ndk-${NDK_VER} @@ -43,7 +43,7 @@ RUN curl -sSL --tlsv1.2 https://dl.google.com/android/repository/android-ndk-${N curl -sSL --tlsv1.2 https://dl.google.com/android/repository/commandlinetools-${HOST_OS_SHORT}-${SDK_VER}.zip -L --output /tmp/asdk.zip # Check hashes of downloads -RUN (echo "6ce94604b77d28113ecd588d425363624a5228d9662450c48d2e4053f8039242 /tmp/andk.zip"; echo "0bebf59339eaa534f4217f8aa0972d14dc49e7207be225511073c661ae01da0a /tmp/asdk.zip") | cat | sha256sum -c +RUN (echo "59c2f6dc96743b5daf5d1626684640b20a6bd2b1d85b13156b90333741bad5cc /tmp/andk.zip"; echo "7ec965280a073311c339e571cd5de778b9975026cfcbe79f2b1cdcb1e15317ee /tmp/asdk.zip") | cat | sha256sum -c # Unpack the NDK and SDK RUN mkdir -p ${ANDROID_NDK_ROOT} && unzip /tmp/andk.zip -d $(dirname ${ANDROID_NDK_ROOT}) && rm -f /tmp/andk.zip && \ diff --git a/.devcontainer/scripts/onCreateCommand.sh b/.devcontainer/scripts/onCreateCommand.sh index 02e5878bab2de3..7b59f6d0d1d45e 100755 --- a/.devcontainer/scripts/onCreateCommand.sh +++ b/.devcontainer/scripts/onCreateCommand.sh @@ -31,7 +31,7 @@ case "$opt" in android) # prebuild the repo for Mono, so it is ready for development - ./build.sh mono+libs -os android + ./build.sh mono+libs+clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages -os android # restore libs tests so that the project is ready to be loaded by OmniSharp ./build.sh libs.tests -restore ;; diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f634bbfd00239b..e425cc58edb976 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,7 +1,6 @@ # Users referenced in this file will automatically be requested as reviewers for PRs that modify the given paths. # See https://help.github.com/articles/about-code-owners/ -/src/libraries/Common/src/Interop/ @dotnet/platform-deps-team /src/libraries/Common/src/System/Net/Http/aspnetcore/ @dotnet/http /src/libraries/Common/tests/Tests/System/Net/aspnetcore/ @dotnet/http diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index ebf8009acd809a..b9eab826490684 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -37,10 +37,11 @@ In addition to the rules enforced by `.editorconfig`, you SHOULD: - [5.1. How To: Identify Affected Libraries](#51-how-to-identify-affected-libraries) - [5.2. How To: Build and Test Specific Library](#52-how-to-build-and-test-specific-library) - [6. WebAssembly (WASM) Libraries Workflow](#6-webassembly-wasm-libraries-workflow) -- [7. Additional Notes](#7-additional-notes) - - [7.1. Troubleshooting](#71-troubleshooting) - - [7.2. Windows Command Equivalents](#72-windows-command-equivalents) - - [7.3. References](#73-references) +- [7. Host Workflow](#7-host-workflow) +- [8. Additional Notes](#8-additional-notes) + - [8.1. Troubleshooting](#81-troubleshooting) + - [8.2. Windows Command Equivalents](#82-windows-command-equivalents) + - [8.3. References](#83-references) ## 1. Prerequisites @@ -54,6 +55,7 @@ Identify which components will be impacted by the changes. If in doubt, analyze - **Mono Runtime:** Changes in `src/mono/` - **Libraries:** Changes in `src/libraries/` - **WASM/WASI Libraries:** Changes in `src/libraries/` *and* the affected library targets WASM or WASI *and* the changes are included for the target (see below for details). +- **Host:** Changes in `src/native/corehost/`, `src/installer/managed/`, or `src/installer/tests/` - If none above apply, it is most possibly an infra-only or a docs-only change. Skip build and test steps. **WASM/WASI Library Change Detection** @@ -76,6 +78,7 @@ Before applying any changes, ensure you have a full successful build of the need - **Mono Runtime:** `./build.sh mono+libs` - **Libraries:** `./build.sh clr+libs -rc release` - **WASM/WASI Libraries:** `./build.sh mono+libs -os browser` + - **Host:** `./build.sh clr+libs+host -rc release -lc release` 3. Verify the build completed without error. - _If the baseline build failed, report the failure and don't proceed with the changes._ @@ -239,9 +242,24 @@ From the repository root: --- -## 7. Additional Notes +## 7. Host Workflow -### 7.1. Troubleshooting +From the repository root: + +- Build: + `./build.sh host -rc release -lc release` + +- Run all tests: + `./build.sh host.tests -rc release -lc release -test` + +- More info can be found in the dedicated workflow docs: + - [Building and running host tests](/docs/workflow/testing/host/testing.md) + +--- + +## 8. Additional Notes + +### 8.1. Troubleshooting - **Shared Framework Missing** @@ -273,7 +291,7 @@ From the repository root: --- -### 7.2. Windows Command Equivalents +### 8.2. Windows Command Equivalents - Use `build.cmd` instead of `build.sh` on Windows. - Set PATH: `set PATH=%CD%\.dotnet;%PATH%` @@ -281,7 +299,7 @@ From the repository root: --- -### 7.3. References +### 8.3. References - [`.editorconfig`](/.editorconfig) - [Building CoreCLR Guide](/docs/workflow/building/coreclr/README.md) @@ -292,3 +310,4 @@ From the repository root: - [Testing Libraries](/docs/workflow/testing/libraries/testing.md) - [Build libraries for WebAssembly](/docs/workflow/building/libraries/webassembly-instructions.md) - [Testing Libraries on WebAssembly](/docs/workflow/testing/libraries/testing-wasm.md) +- [Building and running host tests](/docs/workflow/testing/host/testing.md) diff --git a/.github/policies/binaryformatter-migration.yml b/.github/policies/binaryformatter-migration.yml index c9eb8ff3f736c0..817b01b2ebc671 100644 --- a/.github/policies/binaryformatter-migration.yml +++ b/.github/policies/binaryformatter-migration.yml @@ -19,7 +19,7 @@ configuration: - adamsitnik - bartonjs - jeffhandley - - terrajobst + - JeremyKuhne replyTemplate: >- Tagging subscribers to 'binaryformatter-migration': ${mentionees} assignMentionees: False diff --git a/.github/policies/resourceManagement.yml b/.github/policies/resourceManagement.yml index 81e93241edc27d..0047d4605b72bb 100644 --- a/.github/policies/resourceManagement.yml +++ b/.github/policies/resourceManagement.yml @@ -1789,7 +1789,6 @@ configuration: mentionees: - vitek-karas - kotlarmilos - - ivanpovazan - steveisok - akoeplinger replyTemplate: >- @@ -1828,7 +1827,6 @@ configuration: mentionees: - vitek-karas - kotlarmilos - - ivanpovazan - steveisok - akoeplinger replyTemplate: >- @@ -1848,7 +1846,6 @@ configuration: mentionees: - vitek-karas - kotlarmilos - - ivanpovazan - steveisok - akoeplinger replyTemplate: >- diff --git a/.github/workflows/aspnetcore-sync.yml b/.github/workflows/aspnetcore-sync.yml index 582f371cf9ab49..dac2581735cfe9 100644 --- a/.github/workflows/aspnetcore-sync.yml +++ b/.github/workflows/aspnetcore-sync.yml @@ -16,14 +16,14 @@ jobs: runs-on: windows-latest steps: - name: Checkout aspnetcore - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: # Test this script using changes in a fork repository: 'dotnet/aspnetcore' path: aspnetcore ref: main - name: Checkout runtime - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: # Test this script using changes in a fork repository: 'dotnet/runtime' diff --git a/.github/workflows/bump-chrome-version.yml b/.github/workflows/bump-chrome-version.yml index c411b4a2fadaf8..29738ac8ae3c13 100644 --- a/.github/workflows/bump-chrome-version.yml +++ b/.github/workflows/bump-chrome-version.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Branch run: | git config user.name github-actions[bot] diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 91edd82f2a3fc0..647c8af540dfce 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -15,7 +15,7 @@ jobs: # You can define any steps you want, and they will run before the agent starts. # If you do not check out your code, Copilot will do this for you. steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v5 - name: Install Dependencies env: diff --git a/.github/workflows/jit-format.yml b/.github/workflows/jit-format.yml index 46c3477d00fb22..135c632af310bb 100644 --- a/.github/workflows/jit-format.yml +++ b/.github/workflows/jit-format.yml @@ -33,7 +33,7 @@ jobs: with: dotnet-version: '8.0.x' - name: Checkout runtime - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: path: runtime - name: Install Python diff --git a/.github/workflows/locker.yml b/.github/workflows/locker.yml index bea3f2fa09f983..c885d35009ac6f 100644 --- a/.github/workflows/locker.yml +++ b/.github/workflows/locker.yml @@ -23,7 +23,7 @@ jobs: if: ${{ github.repository_owner == 'dotnet' }} steps: - name: Checkout Actions - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: "microsoft/vscode-github-triage-actions" path: ./actions diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index 8822e9c556b314..9efcccc2755e51 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Use Node.js uses: actions/setup-node@v4 with: diff --git a/Directory.Build.props b/Directory.Build.props index 06d8ce4df81bd2..99eee260233d71 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -178,7 +178,7 @@ $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', '$(TargetRid).$(HostConfiguration)', 'corehost')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'mscordaccore_universal', '$(Configuration)', '$(NetCoreAppCurrent)', '$(TargetRid)', 'publish')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'mscordaccore_universal', '$(Configuration)', '$(NetCoreAppCurrent)', '$(PortableTargetRid)', 'publish')) diff --git a/docs/area-owners.md b/docs/area-owners.md index 36e950d8bc89cf..df468aa1adb3c0 100644 --- a/docs/area-owners.md +++ b/docs/area-owners.md @@ -17,7 +17,7 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi | area-Build-mono | @lewing | @akoeplinger | | | area-Codeflow | @dotnet/dnr-codeflow | @dotnet/dnr-codeflow | Used for automated PRs that ingest code from other repos | | area-Codegen-AOT-mono | @steveisok | @kotlarmilos | | -| area-CodeGen-coreclr | @JulieLeeMSFT | @BruceForstall @dotnet/jit-contrib | | +| area-CodeGen-coreclr | @JulieLeeMSFT | @dotnet/jit-contrib | | | area-Codegen-Interpreter-coreclr | @vitek-karas | @BrzVlad @janvorli | | | area-Codegen-Interpreter-mono | @vitek-karas | @BrzVlad @kotlarmilos | | | area-Codegen-Intrinsics-mono | @steveisok | | | @@ -25,87 +25,87 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi | area-Codegen-LLVM-mono | @steveisok | | | | area-Codegen-meta-mono | @steveisok | | | | area-crossgen2-coreclr | @mangod9 | @dotnet/crossgen-contrib | | -| area-Debugger-mono | @steveisok | @thaystg @dotnet/dotnet-diag | | -| area-DependencyModel | @ericstj | @dotnet/area-dependencymodel | Included: | -| area-Diagnostics-coreclr | @steveisok | @tommcdon @dotnet/dotnet-diag | | -| area-Diagnostics-mono | @steveisok | @tommcdon @mdh1418 @thaystg | | -| area-EnC-mono | @steveisok | @dotnet/dotnet-diag @thaystg | Hot Reload on WebAssembly, Android, iOS, etc . @lambdageek to consult | +| area-Debugger-mono | @steveisok | @thaystg @dotnet/dotnet-diag | | +| area-DependencyModel | @jeffhandley | @dotnet/area-dependencymodel | Included: | +| area-Diagnostics-coreclr | @steveisok | @tommcdon @dotnet/dotnet-diag | | +| area-Diagnostics-mono | @steveisok | @tommcdon @mdh1418 @thaystg | | +| area-EnC-mono | @steveisok | @dotnet/dotnet-diag @thaystg | Hot Reload on WebAssembly, Android, iOS, etc. | | area-ExceptionHandling-coreclr | @mangod9 | @janvorli | | | area-Extensions-Caching | @jeffhandley | @dotnet/area-extensions-caching | Consultants: @mgravell, @sebastienros | -| area-Extensions-Configuration | @ericstj | @dotnet/area-extensions-configuration | Consultants: @eerhardt | -| area-Extensions-DependencyInjection | @ericstj | @dotnet/area-extensions-dependencyinjection | Consultants: @halter73, @benjaminpetit | +| area-Extensions-Configuration | @jeffhandley | @dotnet/area-extensions-configuration | Consultants: @eerhardt | +| area-Extensions-DependencyInjection | @jeffhandley | @dotnet/area-extensions-dependencyinjection | Consultants: @halter73, @benjaminpetit | | area-Extensions-FileSystem | @jeffhandley | @dotnet/area-extensions-filesystem | | -| area-Extensions-Hosting | @ericstj | @dotnet/area-extensions-hosting | Consultants: @halter73, @tratcher | +| area-Extensions-Hosting | @jeffhandley | @dotnet/area-extensions-hosting | Consultants: @halter73, @tratcher | | area-Extensions-HttpClientFactory | @karelz | @dotnet/ncl | | -| area-Extensions-Logging | @ericstj | @dotnet/area-extensions-logging | Consultants: @brennanconroy | -| area-Extensions-Options | @ericstj | @dotnet/area-extensions-options | Consultants: @eerhardt, @brennanconroy | -| area-Extensions-Primitives | @ericstj | @dotnet/area-extensions-primitives | | +| area-Extensions-Logging | @jeffhandley | @dotnet/area-extensions-logging | Consultants: @brennanconroy | +| area-Extensions-Options | @jeffhandley | @dotnet/area-extensions-options | Consultants: @eerhardt, @brennanconroy | +| area-Extensions-Primitives | @jeffhandley | @dotnet/area-extensions-primitives | | | area-GC-coreclr | @mangod9 | @Maoni0 | | | area-GC-mono | @mangod9 | @mangod9 | @BrzVlad to consult | | area-Host | @agocke | @jeffschwMSFT @elinor-fung | Issues with dotnet.exe including bootstrapping, framework detection, hostfxr.dll and hostpolicy.dll | | area-HostModel | @agocke | @elinor-fung | | -| area-ILTools-coreclr | @JulieLeeMSFT | @BruceForstall @dotnet/jit-contrib | | +| area-ILTools-coreclr | @JulieLeeMSFT | @dotnet/jit-contrib | | | area-Infrastructure | @agocke | @jeffschwMSFT @MichaelSimons | | | area-Infrastructure-coreclr | @agocke | @jeffschwMSFT | | | area-Infrastructure-installer | @MichaelSimons | @NikolaMilosavljevic | | -| area-Infrastructure-libraries | @ericstj | @dotnet/area-infrastructure-libraries | Covers:
| +| area-Infrastructure-libraries | @jeffhandley | @dotnet/area-infrastructure-libraries | Covers:
| | area-Infrastructure-mono | @steveisok | @agocke | | | area-Interop-coreclr | @agocke | @AaronRobinsonMSFT @jkoritzinsky | | | area-Interop-mono | @agocke | @AaronRobinsonMSFT @jkoritzinsky | | | area-Meta | @jeffhandley | @dotnet/area-meta | Cross-cutting concerns that span many or all areas, including project-wide code/test patterns and documentation. | | area-Microsoft.CSharp | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) | | area-Microsoft.VisualBasic | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) | -| area-Microsoft.Win32 | @ericstj | @dotnet/area-microsoft-win32 | Included: | +| area-Microsoft.Win32 | @jeffhandley | @dotnet/area-microsoft-win32 | Included: | | area-NativeAOT-coreclr | @agocke | @dotnet/ilc-contrib | | | area-PAL-coreclr | @mangod9 | @janvorli | | | area-R2RDump-coreclr | @mangod9 | | | | area-ReadyToRun-coreclr | @mangod9 | | | -| area-Serialization | @HongGit | @StephenMolloy @HongGit | Packages: Excluded: | +| area-Serialization | @StephenMolloy | @StephenMolloy @dotnet/Tellurium | Packages: Excluded: | | area-Setup | @MichaelSimons | @NikolaMilosavljevic | Distro-specific (Linux, Mac and Windows) setup packages and msi files | | area-Single-File | @agocke | @elinor-fung @vsadov | | | area-Snap | @MichaelSimons | @NikolaMilosavljevic @leecow @MichaelSimons | | | area-System.Buffers | @jeffhandley | @dotnet/area-system-buffers | | -| area-System.ClientModel | @terrajobst | @dotnet/fxdc | Bugs and feature requests should go to https://github.com/Azure/azure-sdk-for-net/issues. We don't own the code, but FXDC reviews changes to determine overlap with other `System` concepts. The Azure SDK team will post API updates in this repo for us to review. | -| area-System.CodeDom | @ericstj | @dotnet/area-system-codedom | | +| area-System.ClientModel | @jeffhandley | @dotnet/fxdc | Bugs and feature requests should go to https://github.com/Azure/azure-sdk-for-net/issues. We don't own the code, but FXDC reviews changes to determine overlap with other `System` concepts. The Azure SDK team will post API updates in this repo for us to review. | +| area-System.CodeDom | @jeffhandley | @dotnet/area-system-codedom | | | area-System.Collections | @jeffhandley | @dotnet/area-system-collections | Excluded: | -| area-System.ComponentModel | @ericstj | @dotnet/area-system-componentmodel | Consultants: @dotnet/dotnet-winforms | -| area-System.ComponentModel.Composition | @ericstj | @dotnet/area-system-componentmodel-composition | | +| area-System.ComponentModel | @jeffhandley | @dotnet/area-system-componentmodel | Consultants: @dotnet/dotnet-winforms | +| area-System.ComponentModel.Composition | @jeffhandley | @dotnet/area-system-componentmodel-composition | | | area-System.ComponentModel.DataAnnotations | @jeffhandley | @dotnet/area-system-componentmodel-dataannotations | Included: | -| area-System.Composition | @ericstj | @dotnet/area-system-composition | | -| area-System.Configuration | @ericstj | @dotnet/area-system-configuration | | +| area-System.Composition | @jeffhandley | @dotnet/area-system-composition | | +| area-System.Configuration | @jeffhandley | @dotnet/area-system-configuration | | | area-System.Console | @jeffhandley | @dotnet/area-system-console | | | area-System.Data | @sammonort | @ajcvickers @roji | | | area-System.Data.Odbc | @sammonort | @ajcvickers @roji | | | area-System.Data.OleDB | @sammonort | @ajcvickers @roji | | | area-System.Data.SqlClient | @David-Engel | @cheenamalhotra @david-engel | Archived component - limited churn/contributions (see https://devblogs.microsoft.com/dotnet/introducing-the-new-microsoftdatasqlclient/) | -| area-System.DateTime | @ericstj | @dotnet/area-system-datetime | System namespace APIs related to dates and times, including DateOnly, DateTime, DateTimeKind, DateTimeOffset, DayOfWeek, TimeOnly, TimeSpan, TimeZone, and TimeZoneInfo | +| area-System.DateTime | @jeffhandley | @dotnet/area-system-datetime | System namespace APIs related to dates and times, including DateOnly, DateTime, DateTimeKind, DateTimeOffset, DayOfWeek, TimeOnly, TimeSpan, TimeZone, and TimeZoneInfo | | area-System.Diagnostics | @steveisok | @dotnet/area-system-diagnostics | | | area-System.Diagnostics-coreclr | @steveisok | @dotnet/area-system-diagnostics-coreclr | | | area-System.Diagnostics-mono | @steveisok | @dotnet/dotnet-diag | | -| area-System.Diagnostics.Activity | @ericstj | @dotnet/area-system-diagnostics-activity | | -| area-System.Diagnostics.EventLog | @ericstj | @dotnet/area-system-diagnostics-eventlog | | -| area-System.Diagnostics.Metric | @ericstj | @dotnet/area-system-diagnostics-metric | | -| area-System.Diagnostics.PerformanceCounter | @ericstj | @dotnet/area-system-diagnostics-performancecounter | | +| area-System.Diagnostics.Activity | @jeffhandley | @dotnet/area-system-diagnostics-activity | | +| area-System.Diagnostics.EventLog | @jeffhandley | @dotnet/area-system-diagnostics-eventlog | | +| area-System.Diagnostics.Metric | @jeffhandley | @dotnet/area-system-diagnostics-metric | | +| area-System.Diagnostics.PerformanceCounter | @jeffhandley | @dotnet/area-system-diagnostics-performancecounter | | | area-System.Diagnostics.Process | @jeffhandley | @dotnet/area-system-diagnostics-process | | | area-System.Diagnostics.Tracing | @steveisok | @dotnet/area-system-diagnostics-tracing | Included: | -| area-System.Diagnostics.TraceSource | @ericstj | @dotnet/area-system-diagnostics-tracesource | | -| area-System.DirectoryServices | @ericstj | @dotnet/area-system-directoryservices | Consultants: @BRDPM @grubioe @jay98014 | -| area-System.Drawing | @ericstj | @dotnet/area-system-drawing | Excluded: | +| area-System.Diagnostics.TraceSource | @jeffhandley | @dotnet/area-system-diagnostics-tracesource | | +| area-System.DirectoryServices | @jeffhandley | @dotnet/area-system-directoryservices | Consultants: @BRDPM @grubioe @jay98014 | +| area-System.Drawing | @jeffhandley | @dotnet/area-system-drawing | Excluded: | | area-System.Dynamic.Runtime | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) | | area-System.Formats.Asn1 | @jeffhandley | @dotnet/area-system-formats-asn1 | Consultants: @bartonjs @vcsjones | | area-System.Formats.Cbor | @jeffhandley | @dotnet/area-system-formats-cbor | Consultants: @bartonjs @vcsjones | | area-System.Formats.Nrbf | @jeffhandley | @dotnet/area-system-formats-nrbf | Consultants: @bartonjs @grabyourpitchforks | -| area-System.Formats.Tar | @ericstj | @dotnet/area-system-formats-tar | | -| area-System.Globalization | @ericstj | @dotnet/area-system-globalization | | +| area-System.Formats.Tar | @jeffhandley | @dotnet/area-system-formats-tar | | +| area-System.Globalization | @jeffhandley | @dotnet/area-system-globalization | | | area-System.IO | @jeffhandley | @dotnet/area-system-io | | -| area-System.IO.Compression | @ericstj | @dotnet/area-system-io-compression | Included: | +| area-System.IO.Compression | @jeffhandley | @dotnet/area-system-io-compression | Included: | | area-System.IO.Hashing | @jeffhandley | @dotnet/area-system-io-hashing | APIs within the System.IO.Hashing namespace, which align more with cryptography than with I/O | | area-System.IO.Pipelines | @adityamandaleeka | @davidfowl @halter73 | | | area-System.IO.Ports | @jeffhandley | @dotnet/area-system-io-ports | | | area-System.Linq | @jeffhandley | @dotnet/area-system-linq | | | area-System.Linq.Expressions | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) | | area-System.Linq.Parallel | @jeffhandley | @dotnet/area-system-linq-parallel | Consultants: @stephentoub @kouvel | -| area-System.Management | @ericstj | @dotnet/area-system-management | WMI | +| area-System.Management | @jeffhandley | @dotnet/area-system-management | WMI | | area-System.Memory | @jeffhandley | @dotnet/area-system-memory | | | area-System.Net | @karelz | @dotnet/ncl | Included: | | area-System.Net.Http | @karelz | @dotnet/ncl | | @@ -114,25 +114,25 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi | area-System.Net.Sockets | @karelz | @dotnet/ncl | | | area-System.Numerics | @jeffhandley | @dotnet/area-system-numerics | | | area-System.Numerics.Tensors | @jeffhandley | @dotnet/area-system-numerics-tensors | | -| area-System.Reflection | @ericstj | @dotnet/area-system-reflection | | -| area-System.Reflection.Emit | @ericstj | @dotnet/area-system-reflection-emit | | -| area-System.Reflection.Metadata | @ericstj | @dotnet/area-system-reflection-metadata | Consultants: @tmat | -| area-System.Resources | @ericstj | @dotnet/area-system-resources | | +| area-System.Reflection | @jeffhandley | @dotnet/area-system-reflection | | +| area-System.Reflection.Emit | @jeffhandley | @dotnet/area-system-reflection-emit | | +| area-System.Reflection.Metadata | @jeffhandley | @dotnet/area-system-reflection-metadata | Consultants: @tmat | +| area-System.Resources | @jeffhandley | @dotnet/area-system-resources | | | area-System.Runtime | @jeffhandley | @dotnet/area-system-runtime | Included:Excluded: | -| area-System.Runtime.Caching | @HongGit | @StephenMolloy @HongGit | | -| area-System.Runtime.CompilerServices | @ericstj | @dotnet/area-system-runtime-compilerservices | | +| area-System.Runtime.Caching | @StephenMolloy | @StephenMolloy @dotnet/Tellurium | | +| area-System.Runtime.CompilerServices | @jeffhandley | @dotnet/area-system-runtime-compilerservices | | | area-System.Runtime.InteropServices | @agocke | @AaronRobinsonMSFT @jkoritzinsky | Excluded: | | area-System.Runtime.InteropServices.JavaScript | @lewing | @pavelsavara | | | area-System.Runtime.Intrinsics | @jeffhandley | @dotnet/area-system-runtime-intrinsics | Consultants: @echesakovMSFT @kunalspathak | -| area-System.Security | @jeffhandley | @dotnet/area-system-security | Consultants: @bartonjs @GrabYourPitchforks @SteveHarter @vcsjones @wfurt | -| area-System.ServiceModel | @HongGit | @HongGit @mconnew | Repo: https://github.com/dotnet/WCF
Packages: | -| area-System.ServiceModel.Syndication | @HongGit | @StephenMolloy @HongGit | | -| area-System.ServiceProcess | @ericstj | @dotnet/area-system-serviceprocess | | -| area-System.Speech | @ericstj | @dotnet/area-system-speech | | -| area-System.Text.Encoding | @ericstj | @dotnet/area-system-text-encoding | | -| area-System.Text.Encodings.Web | @ericstj | @dotnet/area-system-text-encodings-web | | +| area-System.Security | @jeffhandley | @dotnet/area-system-security | Consultants: @bartonjs @GrabYourPitchforks @vcsjones @wfurt | +| area-System.ServiceModel | @mconnew | @mconnew @dotnet/Tellurium | Repo: https://github.com/dotnet/WCF
Packages: | +| area-System.ServiceModel.Syndication | @StephenMolloy | @StephenMolloy @dotnet/Tellurium | | +| area-System.ServiceProcess | @jeffhandley | @dotnet/area-system-serviceprocess | | +| area-System.Speech | @jeffhandley | @dotnet/area-system-speech | | +| area-System.Text.Encoding | @jeffhandley | @dotnet/area-system-text-encoding | | +| area-System.Text.Encodings.Web | @jeffhandley | @dotnet/area-system-text-encodings-web | | | area-System.Text.Json | @jeffhandley | @dotnet/area-system-text-json | | -| area-System.Text.RegularExpressions | @ericstj | @dotnet/area-system-text-regularexpressions | Consultants: @stephentoub | +| area-System.Text.RegularExpressions | @jeffhandley | @dotnet/area-system-text-regularexpressions | Consultants: @stephentoub | | area-System.Threading | @mangod9 | @kouvel @vsadov | | | area-System.Threading.Channels | @jeffhandley | @dotnet/area-system-threading-channels | Consultants: @stephentoub | | area-System.Threading.RateLimiting | @rafikiassumani-msft | @BrennanConroy @halter73 | | @@ -141,7 +141,7 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi | area-System.Xml | @jeffhandley | @dotnet/area-system-xml | | | area-TieredCompilation-coreclr | @mangod9 | @kouvel | | | area-Tools-ILLink | @agocke | @dotnet/illink | | -| area-Tools-ILVerification | @JulieLeeMSFT | @BruceForstall @dotnet/jit-contrib | | +| area-Tools-ILVerification | @JulieLeeMSFT | @dotnet/jit-contrib | | | area-Tracing-coreclr | @steveisok | @dotnet/area-tracing-coreclr | .NET runtime issues for EventPipe and ICorProfiler | | area-Tracing-mono | @steveisok | @dotnet/dotnet-diag @thaystg | | | area-TypeSystem-coreclr | @mangod9 | @davidwrighton @MichalStrehovsky @janvorli @mangod9 | | diff --git a/docs/coding-guidelines/framework-design-guidelines-digest.md b/docs/coding-guidelines/framework-design-guidelines-digest.md index d48ecc60727dc2..bb512540d38e20 100644 --- a/docs/coding-guidelines/framework-design-guidelines-digest.md +++ b/docs/coding-guidelines/framework-design-guidelines-digest.md @@ -107,7 +107,7 @@ characters. ✓ **DO** name types and properties with nouns or noun phrases. ✓ **DO** name methods and events with verbs or verb phrases. Always give -events names that have a concept of before and after using the present particle +events names that have a concept of before and after using the present participle and simple past tense. For example, an event that is raised before a `Form` closes should be named `Closing`. An event raised after a `Form` is closed should be named `Closed`. diff --git a/docs/coding-guidelines/interop-guidelines.md b/docs/coding-guidelines/interop-guidelines.md index 8338f4c1d04e23..8f3c9e931b508d 100644 --- a/docs/coding-guidelines/interop-guidelines.md +++ b/docs/coding-guidelines/interop-guidelines.md @@ -15,12 +15,6 @@ We have the following goals related to interop code being used in dotnet/runtime - Ensure maximal managed code reuse across different OS flavors which have the same API but not the same ABI. - This is the case for UNIX and addressing it is a work-in-progress (see issue #2137 and section on "shims" below.) -## Submitting Changes - -Interop code implicitly defines the native platform dependencies that .NET has. These dependencies are tracked and modeled according to the [Tracking Platform Dependencies design](https://github.com/dotnet/designs/blob/main/accepted/2021/platform-dependencies/platform-dependencies.md). Whenever a PR is submitted that changes interop code, it needs to be reviewed to determine whether a change to the platform dependencies model is required. - -By default, any change to `src/libraries/Common/src/Interop` folder will add @dotnet/platform-deps-team as a reviewer. If necessary, update the corresponding `https://github.com/dotnet/core/blob/main/release-notes//runtime-deps.json` file to reflect the dependency change. The scope of dependencies is at the file/package level, not individual functions, so interop changes rarely require an update to the model. - ## Approach ### Interop type diff --git a/docs/coding-guidelines/project-guidelines.md b/docs/coding-guidelines/project-guidelines.md index c6c49bf3e131f5..b6e350f9d9eaf7 100644 --- a/docs/coding-guidelines/project-guidelines.md +++ b/docs/coding-guidelines/project-guidelines.md @@ -151,7 +151,7 @@ src\\tests - Contains the test code for a library. ## ref Reference assemblies are required for any library that has more than one implementation or uses a facade. A reference assembly is a surface-area-only assembly that represents the public API of the library. To generate a reference assembly source file you can use the [GenAPI tool](https://www.nuget.org/packages/Microsoft.DotNet.BuildTools.GenAPI). If a library is a pure portable library with a single implementation it need not use a reference assembly at all. Instructions on updating reference sources can be found [here](https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/updating-ref-source.md). -In the ref directory for the library there should be at most **one** `.csproj` that contains the latest API for the reference assembly for the library. That project can contain multiple entries in its `TargetFrameworks` property. Ref projects should use `` for its dependencies. +In the ref directory for the library there should be at most **one** `.csproj` that contains the latest API for the reference assembly for the library. That project can contain multiple entries in its `TargetFrameworks` property. ### ref output All ref outputs should be under @@ -159,11 +159,11 @@ All ref outputs should be under `bin\$(MSBuildProjectName)\ref\$(TargetFramework)` ## src -In the src directory for a library there should be only **one** `.csproj` file that contains any information necessary to build the library in various target frameworks. All supported target frameworks should be listed in the `TargetFrameworks` property. +In the src directory for a library there should be only **one** `.csproj` file that contains any information necessary to build the library for various target frameworks. All supported target frameworks should be listed in the `TargetFramework` or `TargetFrameworks` property. -All libraries should use `` for all their references to libraries that compose the shared framework of the current .NETCoreApp. That will cause them to be resolved against the locally built targeting pack which is located at `artifacts\bin\microsoft.netcore.app.ref`. The only exception to that rule right now is for partial facades which directly reference System.Private.CoreLib and thus need to directly reference other partial facades to avoid type conflicts. +Libraries should use `ProjectReference` items to reference live dependencies. -Other target frameworks than .NETCoreApp latest (i.e. `netstandard2.0`, `net462`, `net8.0`) should use ProjectReference items to reference dependencies. +`Reference` items should only be used when targeting .NET Framework to reference prebuilt assemblies from the targeting pack and which aren't included by default (i.e. `System.DirectoryServices`). For anything else, `Reference` items should not be used as they are not supported in those frameworks. ### src\ILLink Contains the files used to direct the trimming tool. See [ILLink files](../workflow/trimming/ILLink-files.md). diff --git a/docs/coding-guidelines/vectorization-guidelines.md b/docs/coding-guidelines/vectorization-guidelines.md index ab85676263afd6..9ac773872947a9 100644 --- a/docs/coding-guidelines/vectorization-guidelines.md +++ b/docs/coding-guidelines/vectorization-guidelines.md @@ -523,7 +523,7 @@ int ManagedReferencesSum(int[] buffer) Vector128 sum = Vector128.Zero; - while (!Unsafe.IsAddressGreaterThan(ref current, ref oneVectorAwayFromEnd)) + while (Unsafe.IsAddressLessThanOrEqualTo(ref current, ref oneVectorAwayFromEnd)) { sum += Vector128.LoadUnsafe(ref current); @@ -561,7 +561,7 @@ do return ...; } -while (!Unsafe.IsAddressLessThan(ref currentSearchSpace, ref searchSpace)); +while (Unsafe.IsAddressGreaterThanOrEqualTo(ref currentSearchSpace, ref searchSpace)); ``` It was part of `LastIndexOf` implementation, where we were iterating from the end to the beginning of the buffer. In the last iteration of the loop, `currentSearchSpace` could become a pointer to unknown memory that lied before the beginning of the buffer: @@ -573,7 +573,7 @@ currentSearchSpace = ref Unsafe.Subtract(ref currentSearchSpace, Vector128 GetILCodeVersions(TargetPointer methodDesc); +// Return all of the Native code versions for a given ILCodeVersion +public virtual IEnumerable GetNativeCodeVersions(TargetPointer methodDesc, ILCodeVersionHandle ilCodeVersionHandle); // Return a handle to the version of the native code that includes the given instruction pointer public virtual NativeCodeVersionHandle GetNativeCodeVersionForIP(TargetCodePointer ip); // Return a handle to the active version of the native code for a given method descriptor and IL code version. The IL code version and method descriptor must represent the same method @@ -132,7 +134,7 @@ IEnumerable ICodeVersions.GetILCodeVersions(TargetPointer m // CodeVersionManager::GetILCodeVersions GetModuleAndMethodDesc(methodDesc, out TargetPointer module, out uint methodDefToken); - ModuleHandle moduleHandle = _target.Contracts.Loader.GetModuleHandle(module); + ModuleHandle moduleHandle = _target.Contracts.Loader.GetModuleHandleFromModulePtr(module); TargetPointer ilCodeVersionTable = _target.Contracts.Loader.GetLookupTables(moduleHandle).MethodDefToILCodeVersioningState; TargetPointer ilVersionStateAddress = _target.Contracts.Loader.GetModuleLookupMapElement(ilCodeVersionTable, methodDefToken, out var _); @@ -193,18 +195,18 @@ NativeCodeVersionHandle GetSpecificNativeCodeVersion(MethodDescHandle md, Target return first; } - return FindFirstCodeVersion(rts, md, (codeVersion) => + return FindNativeCodeVersionNodes(rts, md, (codeVersion) => { return codeVersion.MethodDesc == md.Address && codeVersion.NativeCode == startAddress; - }); + }).FirstOrDefault(NativeCodeVersionHandle.Invalid); } -NativeCodeVersionHandle FindFirstCodeVersion(IRuntimeTypeSystem rts, MethodDescHandle md, Func predicate) +IEnumerable FindNativeCodeVersionNodes(IRuntimeTypeSystem rts, MethodDescHandle md, Func predicate) { // ImplicitCodeVersion stage of NativeCodeVersionIterator::Next() TargetPointer versioningStateAddr = rts.GetMethodDescVersioningState(md); if (versioningStateAddr == TargetPointer.Null) - return NativeCodeVersionHandle.Invalid; + yield break; Data.MethodDescVersioningState versioningState = _target.ProcessedData.GetOrAdd(versioningStateAddr); @@ -215,14 +217,45 @@ NativeCodeVersionHandle FindFirstCodeVersion(IRuntimeTypeSystem rts, MethodDescH Data.NativeCodeVersionNode current = _target.ProcessedData.GetOrAdd(currentAddress); if (predicate(current)) { - return NativeCodeVersionHandle.OfExplicit(currentAddress); + yield return NativeCodeVersionHandle.OfExplicit(currentAddress); } currentAddress = current.Next; } - return NativeCodeVersionHandle.Invalid; + yield break; +} +``` + +### Finding all of the native code versions of an ILCodeVersion for a method descriptor + +```csharp +IEnumerable ICodeVersions.GetNativeCodeVersions(TargetPointer methodDesc, ILCodeVersionHandle ilCodeVersionHandle) +{ + if (!ilCodeVersionHandle.IsValid) + yield break; + + if (!ilCodeVersionHandle.IsExplicit) + { + // if the ILCodeVersion is synthetic, then yield the synthetic NativeCodeVersion + NativeCodeVersionHandle provisionalHandle = NativeCodeVersionHandle.CreateSynthetic(methodDesc); + yield return provisionalHandle; + } + + // Iterate through versioning state nodes and return the active one, matching any IL code version + Contracts.IRuntimeTypeSystem rts = _target.Contracts.RuntimeTypeSystem; + MethodDescHandle md = rts.GetMethodDescHandle(methodDesc); + TargetNUInt ilVersionId = GetId(ilCodeVersionHandle); + IEnumerable nativeCodeVersions = FindNativeCodeVersionNodes( + rts, + md, + (codeVersion) => ilVersionId == codeVersion.ILVersionId); + foreach (NativeCodeVersionHandle nativeCodeVersion in nativeCodeVersions) + { + yield return nativeCodeVersion; + } } ``` + ### Finding the active native code version of an ILCodeVersion for a method descriptor ```csharp public virtual NativeCodeVersionHandle GetActiveNativeCodeVersionForILCodeVersion(TargetPointer methodDesc, ILCodeVersionHandle ilCodeVersionHandle); @@ -247,7 +280,7 @@ bool ICodeVersions.CodeVersionManagerSupportsMethod(TargetPointer methodDescAddr TypeHandle mt = rts.GetTypeHandle(mtAddr); TargetPointer modAddr = rts.GetModule(mt); ILoader loader = _target.Contracts.Loader; - ModuleHandle mod = loader.GetModuleHandle(modAddr); + ModuleHandle mod = loader.GetModuleHandleFromModulePtr(modAddr); ModuleFlags modFlags = loader.GetFlags(mod); if (modFlags.HasFlag(ModuleFlags.EditAndContinue)) return false; diff --git a/docs/design/datacontracts/DacStreams.md b/docs/design/datacontracts/DacStreams.md index 4ddc1eb84ad3ab..a2da0c4ab1eaf3 100644 --- a/docs/design/datacontracts/DacStreams.md +++ b/docs/design/datacontracts/DacStreams.md @@ -54,8 +54,8 @@ Following the EENameStream header, there are CountOfNames entries. Each entry be ``` csharp string StringFromEEAddress(TargetPointer address) { - TargetPointer miniMetaDataBuffAddress = _target.Read(_target.ReadGlobalPointer(Constants.Globals.MiniMetaDataBuffAddress)); - uint miniMetaDataBuffMaxSize = _target.Read(_target.ReadGlobalPointer(Constants.Globals.MiniMetaDataBuffMaxSize)); + TargetPointer miniMetaDataBuffAddress = _target.Read(_target.ReadGlobalPointer("MiniMetaDataBuffAddress")); + uint miniMetaDataBuffMaxSize = _target.Read(_target.ReadGlobalPointer("MiniMetaDataBuffMaxSize")); // Parse MiniMetadataStream according the the format described above to produce a dictionary from pointer to string from the EENameStream. // Then lookup in the dictionary, to produce a result if it was present in the table. diff --git a/docs/design/datacontracts/DebugInfo.md b/docs/design/datacontracts/DebugInfo.md new file mode 100644 index 00000000000000..034eb3609900ed --- /dev/null +++ b/docs/design/datacontracts/DebugInfo.md @@ -0,0 +1,219 @@ +# Contract DebugInfo + +This contract is for fetching information related to DebugInfo associated with native code. + +## APIs of contract + +```csharp +[Flags] +public enum SourceTypes : uint +{ + SourceTypeInvalid = 0x00, // To indicate that nothing else applies + StackEmpty = 0x01, // The stack is empty here + CallInstruction = 0x02 // The actual instruction of a call. +} +``` + +```csharp +public readonly struct OffsetMapping +{ + public uint NativeOffset { get; init; } + public uint ILOffset { get; init; } + public SourceTypes SourceType { get; init; } +} +``` + +```csharp +// Given a code pointer, return the associated native/IL offset mapping and codeOffset. +// If preferUninstrumented, will always read the uninstrumented bounds. +// Otherwise will read the instrumented bounds and fallback to the uninstrumented bounds. +IEnumerable GetMethodNativeMap(TargetCodePointer pCode, bool preferUninstrumented, out uint codeOffset); +``` + +## Version 1 + +Data descriptors used: +| Data Descriptor Name | Field | Meaning | +| --- | --- | --- | +| `PatchpointInfo` | `LocalCount` | Number of locals in the method associated with the patchpoint. | + +Contracts used: +| Contract Name | +| --- | +| `CodeVersions` | +| `ExecutionManager` | + +Constants: +| Constant Name | Meaning | Value | +| --- | --- | --- | +| IL_OFFSET_BIAS | IL offsets are encoded in the DebugInfo with this bias. | `0xfffffffd` (-3) | +| DEBUG_INFO_BOUNDS_HAS_INSTRUMENTED_BOUNDS | Indicates bounds data contains instrumented bounds | `0xFFFFFFFF` | +| EXTRA_DEBUG_INFO_PATCHPOINT | Indicates debug info contains patchpoint information | 0x1 | +| EXTRA_DEBUG_INFO_RICH | Indicates debug info contains rich information | 0x2 | + +### DebugInfo Stream Encoding + +The DebugInfo stream is encoded using variable length 32-bit values with the following scheme: + +A value can be stored using one or more nibbles (a nibble is a 4-bit value). 3 bits of a nibble are used to store 3 bits of the value, and the top bit indicates if the following nibble contains rest of the value. If the top bit is not set, then this nibble is the last part of the value. The higher bits of the value are written out first, and the lowest 3 bits are written out last. + +In the encoded stream of bytes, the lower nibble of a byte is used before the high nibble. + +A binary value ABCDEFGHI (where A is the highest bit) is encoded as +the follow two bytes : 1DEF1ABC XXXX0GHI + +Examples: +| Decimal Value | Hex Value | Encoded Result | +| --- | --- | --- | +| 0 | 0x0 | X0 | +| 1 | 0x1 | X1 | +| 7 | 0x7 | X7 | +| 8 | 0x8 | 09 | +| 9 | 0x9 | 19 | +| 63 | 0x3F | 7F | +| 64 | 0x40 | F9 X0 | +| 65 | 0x41 | F9 X1 | +| 511 | 0x1FF | FF X7 | +| 512 | 0x200 | 89 08 | +| 513 | 0x201 | 89 18 | + +Based on the encoding specification, we use a decoder defined originally for r2r dump `NibbleReader.cs` + +### Bounds Data Encoding (R2R Major Version 16+) + +For R2R major version 16 and above, the bounds data uses a bit-packed encoding algorithm: + +1. The bounds entry count, bits needed for native deltas, and bits needed for IL offsets are encoded using the nibble scheme above +2. Each bounds entry is then bit-packed with: + - 2 bits for source type (SourceTypeInvalid=0, CallInstruction=1, StackEmpty=2, StackEmpty|CallInstruction=3) + - Variable bits for native offset delta (accumulated from previous offset) + - Variable bits for IL offset (with IL_OFFSET_BIAS applied) + +The bit-packed data is read byte by byte, collecting bits until enough are available for each entry. + +### Implementation + +``` csharp +IEnumerable IDebugInfo.GetMethodNativeMap(TargetCodePointer pCode, bool preferUninstrumented, out uint codeOffset) +{ + // Get the method's DebugInfo + if (_eman.GetCodeBlockHandle(pCode) is not CodeBlockHandle cbh) + throw new InvalidOperationException($"No CodeBlockHandle found for native code {pCode}."); + TargetPointer debugInfo = _eman.GetDebugInfo(cbh, out bool hasFlagByte); + + TargetCodePointer nativeCodeStart = _eman.GetStartAddress(cbh); + codeOffset = (uint)(CodePointerUtils.AddressFromCodePointer(pCode, _target) - CodePointerUtils.AddressFromCodePointer(nativeCodeStart, _target)); + + return RestoreBoundaries(debugInfo, hasFlagByte, preferUninstrumented); +} + +private IEnumerable RestoreBoundaries(TargetPointer debugInfo, bool hasFlagByte, bool preferUninstrumented) +{ + if (hasFlagByte) + { + // Check flag byte and skip over any patchpoint info + byte flagByte = _target.Read(debugInfo++); + + if ((flagByte & EXTRA_DEBUG_INFO_PATCHPOINT) != 0) + { + uint localCount = _target.Read(debugInfo + /*PatchpointInfo::LocalCount offset*/) + debugInfo += /*size of PatchpointInfo*/ + (localCount * 4); + } + + if ((flagByte & EXTRA_DEBUG_INFO_RICH) != 0) + { + uint richDebugInfoSize = _target.Read(debugInfo); + debugInfo += 4; + debugInfo += richDebugInfoSize; + } + } + + NativeReader nibbleNativeReader = new(new TargetStream(_target, debugInfo, 24 /*maximum size of 4 32bit ints compressed*/), _target.IsLittleEndian); + NibbleReader nibbleReader = new(nibbleNativeReader, 0); + + uint cbBounds = nibbleReader.ReadUInt(); + uint cbUninstrumentedBounds = 0; + if (cbBounds == DEBUG_INFO_BOUNDS_HAS_INSTRUMENTED_BOUNDS) + { + // This means we have instrumented bounds. + cbBounds = nibbleReader.ReadUInt(); + cbUninstrumentedBounds = nibbleReader.ReadUInt(); + } + uint _ /*cbVars*/ = nibbleReader.ReadUInt(); + + TargetPointer addrBounds = debugInfo + (uint)nibbleReader.GetNextByteOffset(); + // TargetPointer addrVars = addrBounds + cbBounds + cbUninstrumentedBounds; + + if (preferUninstrumented && cbUninstrumentedBounds != 0) + { + // If we have uninstrumented bounds, we will use them instead of the regular bounds. + addrBounds += cbBounds; + cbBounds = cbUninstrumentedBounds; + } + + if (cbBounds > 0) + { + NativeReader boundsNativeReader = new(new TargetStream(_target, addrBounds, cbBounds), _target.IsLittleEndian); + return DoBounds(boundsNativeReader); + } + + return Enumerable.Empty(); +} + +private static IEnumerable DoBounds(NativeReader nativeReader) +{ + NibbleReader reader = new(nativeReader, 0); + + uint boundsEntryCount = reader.ReadUInt(); + + uint bitsForNativeDelta = reader.ReadUInt() + 1; // Number of bits needed for native deltas + uint bitsForILOffsets = reader.ReadUInt() + 1; // Number of bits needed for IL offsets + + uint bitsPerEntry = bitsForNativeDelta + bitsForILOffsets + 2; // 2 bits for source type + ulong bitsMeaningfulMask = (1UL << ((int)bitsPerEntry)) - 1; + int offsetOfActualBoundsData = reader.GetNextByteOffset(); + + uint bitsCollected = 0; + ulong bitTemp = 0; + uint curBoundsProcessed = 0; + + uint previousNativeOffset = 0; + + while (curBoundsProcessed < boundsEntryCount) + { + bitTemp |= ((uint)nativeReader[offsetOfActualBoundsData++]) << (int)bitsCollected; + bitsCollected += 8; + while (bitsCollected >= bitsPerEntry) + { + ulong mappingDataEncoded = bitsMeaningfulMask & bitTemp; + bitTemp >>= (int)bitsPerEntry; + bitsCollected -= bitsPerEntry; + + SourceTypes sourceType = (mappingDataEncoded & 0x3) switch + { + 0 => SourceTypes.SourceTypeInvalid, + 1 => SourceTypes.CallInstruction, + 2 => SourceTypes.StackEmpty, + 3 => SourceTypes.StackEmpty | SourceTypes.CallInstruction, + _ => throw new InvalidOperationException($"Unknown source type encoding: {mappingDataEncoded & 0x3}") + }; + + mappingDataEncoded >>= 2; + uint nativeOffsetDelta = (uint)(mappingDataEncoded & ((1UL << (int)bitsForNativeDelta) - 1)); + previousNativeOffset += nativeOffsetDelta; + uint nativeOffset = previousNativeOffset; + + mappingDataEncoded >>= (int)bitsForNativeDelta; + uint ilOffset = (uint)mappingDataEncoded + IL_OFFSET_BIAS; + + yield return new OffsetMapping() + { + NativeOffset = nativeOffset, + ILOffset = ilOffset, + SourceType = sourceType + }; + curBoundsProcessed++; + } + } +} +``` diff --git a/docs/design/datacontracts/ECall.md b/docs/design/datacontracts/ECall.md deleted file mode 100644 index f1ea6c4f8cc07d..00000000000000 --- a/docs/design/datacontracts/ECall.md +++ /dev/null @@ -1,39 +0,0 @@ -# Contract ECall - -This contract is for fetching information related to native calls into the runtime. - -## APIs of contract - -``` csharp -// Given an FCall entrypoint returns the corresponding MethodDesc. -// If the address does not correspond to an FCall, returns TargetPointer.Null. -TargetPointer MapTargetBackToMethodDesc(TargetCodePointer address); -``` - -## Version 1 - -Global variables used -| Global Name | Type | Purpose | -| --- | --- | --- | -| FCallMethods | ECHash[] | Hash table containing ECHash structures | -| FCallHashSize | uint | Number of buckets in the hash table | - - -Data descriptors used: -| Data Descriptor Name | Field | Meaning | -| --- | --- | --- | -| `ECHash` | `Next` | Pointer to the next ECHash in the chain | -| `ECHash` | `Implementation` | FCall's Entrypoint address | -| `ECHash` | `MethodDesc` | Pointer to the FCall's method desc | - - -``` csharp -TargetPointer IECall.MapTargetBackToMethodDesc(TargetCodePointer codePointer) -``` - -To map an FCall entrypoint back to a MethodDesc, we read the global `FCallMethods` hash table. This is a array of pointers to `ECHash` objects. The length of this array is defined by the global `FCallHashSize` where each element is an `ECHash` which can form a chain. It uses a simple hash function: ` = codePointer % FCallHashSize` to map code entry points to buckets. To map a `codePointer` back to a MethodDesc pointer: - -1. Calculate the `` corresponding to the given `codePointer`. -2. Take the `` offset into the `FCallMethods` array. -3. Now that we have the correct `ECHash` chain, iterate the chain using the `ECHash.Next` pointer until we find an `ECHash` where the `Implementation` field matches the `codePointer`. If found, return the `MethodDesc` field. -4. If no `ECHash` matches return `TargetPointer.Null` to indicate a MethodDesc was not found. diff --git a/docs/design/datacontracts/ExecutionManager.md b/docs/design/datacontracts/ExecutionManager.md index 1b5e360f6ec308..103aac455a2a48 100644 --- a/docs/design/datacontracts/ExecutionManager.md +++ b/docs/design/datacontracts/ExecutionManager.md @@ -29,6 +29,9 @@ struct CodeBlockHandle TargetPointer GetUnwindInfo(CodeBlockHandle codeInfoHandle); // Gets the base address the UnwindInfo of codeInfoHandle is relative to TargetPointer GetUnwindInfoBaseAddress(CodeBlockHandle codeInfoHandle); + // Gets the DebugInfo associated with the code block and specifies if the DebugInfo contains + // the flag byte which modifies how DebugInfo is parsed. + TargetPointer GetDebugInfo(CodeBlockHandle codeInfoHandle, out bool hasFlagByte); // Gets the GCInfo associated with the code block and its version // **Currently GetGCInfo only supports X86** void GetGCInfo(CodeBlockHandle codeInfoHandle, out TargetPointer gcInfo, out uint gcVersion); @@ -66,9 +69,11 @@ Data descriptors used: | `CodeHeapListNode` | `EndAddress` | End address of the used portion of the code heap | | `CodeHeapListNode` | `MapBase` | Start of the map - start address rounded down based on OS page size | | `CodeHeapListNode` | `HeaderMap` | Bit array used to find the start of methods - relative to `MapBase` | +| `EEJitManager` | `StoreRichDebugInfo` | Boolean value determining if debug info associated with the JitManager contains rich info. | | `RealCodeHeader` | `MethodDesc` | Pointer to the corresponding `MethodDesc` | | `RealCodeHeader` | `NumUnwindInfos` | Number of Unwind Infos | | `RealCodeHeader` | `UnwindInfos` | Start address of Unwind Infos | +| `RealCodeHeader` | `DebugInfo` | Pointer to the DebugInfo | | `RealCodeHeader` | `GCInfo` | Pointer to the GCInfo encoding | | `Module` | `ReadyToRunInfo` | Pointer to the `ReadyToRunInfo` for the module | | `ReadyToRunInfo` | `ReadyToRunHeader` | Pointer to the ReadyToRunHeader | @@ -78,6 +83,7 @@ Data descriptors used: | `ReadyToRunInfo` | `NumHotColdMap` | Number of entries in the `HotColdMap` | | `ReadyToRunInfo` | `HotColdMap` | Pointer to an array of 32-bit integers - [see R2R format](../coreclr/botr/readytorun-format.md#readytorunsectiontypehotcoldmap-v80) | | `ReadyToRunInfo` | `DelayLoadMethodCallThunks` | Pointer to an `ImageDataDirectory` for the delay load method call thunks | +| `ReadyToRunInf` | `DebugInfo` | Pointer to an `ImageDataDirectory` for the debug info | | `ReadyToRunInfo` | `EntryPointToMethodDescMap` | `HashMap` of entry point addresses to `MethodDesc` pointers | | `ReadyToRunHeader` | `MajorVersion` | ReadyToRun major version | | `ReadyToRunHeader` | `MinorVersion` | ReadyToRun minor version | @@ -100,6 +106,7 @@ Global variables used: | `HashMapValueMask` | uint64 | Bitmask used when storing values in a `HashMap` | | `FeatureEHFunclets` | uint8 | 1 if EH funclets are enabled, 0 otherwise | | `GCInfoVersion` | uint32 | JITted code GCInfo version | +| `FeatureOnStackReplacement` | uint8 | 1 if FEATURE_ON_STACK_REPLACEMENT is enabled, 0 otherwise | Contracts used: | Contract Name | @@ -266,9 +273,16 @@ The `GetMethodDesc`, `GetStartAddress`, and `GetRelativeOffset` APIs extract fie Unwind info (`RUNTIME_FUNCTION`) use relative addressing. For managed code, these values are relative to the start of the code's containing range in the RangeSectionMap (described below). This could be the beginning of a `CodeHeap` for jitted code or the base address of the loaded image for ReadyToRun code. `GetUnwindInfoBaseAddress` finds this base address for a given `CodeBlockHandle`. +`IExecutionManager.GetDebugInfo` gets a pointer to the relevant DebugInfo for a `CodeBlockHandle`. The ExecutionManager delegates to the JitManager implementations as the DebugInfo is stored in different ways on jitted and R2R code. + +* For Jitted code (`EEJitManager`) a pointer to the `DebugInfo` is stored on the `RealCodeHeader` which is accessed in the same way as `GetMethodInfo` described above. `hasFlagByte` is `true` if either the global `FeatureOnStackReplacement` is `true` or `StoreRichDebugInfo` is `true` on the `EEJitManager`. + +* For R2R code (`ReadyToRunJitManager`) the `DebugInfo` is stored as part of the R2R image. The relevant `ReadyToRunInfo` stores a pointer to the an `ImageDataDirectory` representing the `DebugInfo` directory. Read the `VirtualAddress` of this data directory as a `NativeArray` containing the `DebugInfos`. To find the specific `DebugInfo`, index into the array using the `index` of the beginning of the R2R function as found like in `GetMethodInfo` above. This yields an offset `offset` value relative to the image base. Read the first variable length uint at `imageBase + offset`, `lookBack`. If `lookBack != 0`, return `imageBase + offset - lookback`. Otherwise return `offset + size of reading lookback`. +For R2R images, `hasFlagByte` is always `false`. + `IExecutionManager.GetGCInfo` gets a pointer to the relevant GCInfo for a `CodeBlockHandle`. The ExecutionManager delegates to the JitManager implementations as the GCInfo is stored differently on jitted and R2R code. -* For jitted code (`EEJitManager`) a pointer to the `GCInfo` is stored on the `RealCodeHeader` which is accessed in the same was as `GetMethodInfo` described above. This can simply be returned as is. The `GCInfoVersion` is defined by the runtime global `GCInfoVersion`. +* For jitted code (`EEJitManager`) a pointer to the `GCInfo` is stored on the `RealCodeHeader` which is accessed in the same way as `GetMethodInfo` described above. This can simply be returned as is. The `GCInfoVersion` is defined by the runtime global `GCInfoVersion`. * For R2R code (`ReadyToRunJitManager`), the `GCInfo` is stored directly after the `UnwindData`. This in turn is found by looking up the `UnwindInfo` (`RUNTIME_FUNCTION`) and reading the `UnwindData` offset. We find the `UnwindInfo` as described above in `IExecutionManager.GetUnwindInfo`. Once we have the relevant unwind data, we calculate the size of the unwind data and return a pointer to the following byte (first byte of the GCInfo). The size of the unwind data is a platform specific. Currently only X86 is supported with a constant unwind data size of 32-bits. * The `GCInfoVersion` of R2R code is mapped from the R2R MajorVersion and MinorVersion which is read from the ReadyToRunHeader which itself is read from the ReadyToRunInfo (can be found as in GetMethodInfo). The current GCInfoVersion mapping is: @@ -301,6 +315,10 @@ On 64-bit targets, we take advantage of the fact that most architectures don't s That is, level 5 has 256 entires pointing to level 4 maps (or nothing if there's no code allocated in that address range), level 4 entires point to level 3 maps and so on. Each level 1 map has 256 entries covering a 128 KiB chunk and pointing to a linked list of range section fragments that fall within that 128 KiB chunk. +### Native Format + +The ReadyToRun image stores data in a compressed native foramt defined in [nativeformatreader.h](../../../src/coreclr/vm/nativeformatreader.h). + ### NibbleMap The ExecutionManager contract depends on a "nibble map" data structure diff --git a/docs/design/datacontracts/Loader.md b/docs/design/datacontracts/Loader.md index 107e7d5617dfc2..30372f60e6eb71 100644 --- a/docs/design/datacontracts/Loader.md +++ b/docs/design/datacontracts/Loader.md @@ -52,9 +52,12 @@ record struct ModuleLookupTables( ``` ``` csharp -ModuleHandle GetModuleHandle(TargetPointer module); -IEnumerable GetModules(TargetPointer appDomain, AssemblyIterationFlags iterationFlags); +ModuleHandle GetModuleHandleFromModulePtr(TargetPointer module); +ModuleHandle GetModuleHandleFromAssemblyPtr(TargetPointer assemblyPointer); +IEnumerable GetModuleHandles(TargetPointer appDomain, AssemblyIterationFlags iterationFlags); TargetPointer GetRootAssembly(); +string GetAppDomainFriendlyName(); +TargetPointer GetModule(ModuleHandle handle); TargetPointer GetAssembly(ModuleHandle handle); TargetPointer GetPEAssembly(ModuleHandle handle); bool TryGetLoadedImageContents(ModuleHandle handle, out TargetPointer baseAddress, out uint size, out uint imageFlags); @@ -67,12 +70,16 @@ ModuleFlags GetFlags(ModuleHandle handle); string GetPath(ModuleHandle handle); string GetFileName(ModuleHandle handle); TargetPointer GetLoaderAllocator(ModuleHandle handle); -TargetPointer GetThunkHeap(ModuleHandle handle); TargetPointer GetILBase(ModuleHandle handle); +TargetPointer GetAssemblyLoadContext(ModuleHandle handle); ModuleLookupTables GetLookupTables(ModuleHandle handle); TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out TargetNUInt flags); bool IsCollectible(ModuleHandle handle); bool IsAssemblyLoaded(ModuleHandle handle); +TargetPointer GetGlobalLoaderAllocator(); +TargetPointer GetHighFrequencyHeap(TargetPointer loaderAllocatorPointer); +TargetPointer GetLowFrequencyHeap(TargetPointer loaderAllocatorPointer); +TargetPointer GetStubHeap(TargetPointer loaderAllocatorPointer); ``` ## Version 1 @@ -85,7 +92,6 @@ bool IsAssemblyLoaded(ModuleHandle handle); | `Module` | `Base` | Pointer to start of PE file in memory | | `Module` | `Flags` | Assembly of the Module | | `Module` | `LoaderAllocator` | LoaderAllocator of the Module | -| `Module` | `ThunkHeap` | Pointer to the thunk heap | | `Module` | `Path` | Path of the Module (UTF-16, null-terminated) | | `Module` | `FileName` | File name of the Module (UTF-16, null-terminated) | | `Module` | `GrowableSymbolStream` | Pointer to the in memory symbol stream | @@ -107,6 +113,8 @@ bool IsAssemblyLoaded(ModuleHandle handle); | `Assembly` | `NotifyFlags` | Flags relating to the debugger/profiler notification state of the assembly | | `Assembly` | `Level` | File load level of the assembly | | `PEAssembly` | `PEImage` | Pointer to the PEAssembly's PEImage | +| `PEAssembly` | `AssemblyBinder` | Pointer to the PEAssembly's binder | +| `AssemblyBinder` | `AssemblyLoadContext` | Pointer to the AssemblyBinder's AssemblyLoadContext | | `PEImage` | `LoadedImageLayout` | Pointer to the PEImage's loaded PEImageLayout | | `PEImage` | `ProbeExtensionResult` | PEImage's ProbeExtensionResult | | `ProbeExtensionResult` | `Type` | Type of ProbeExtensionResult | @@ -117,7 +125,12 @@ bool IsAssemblyLoaded(ModuleHandle handle); | `CGrowableSymbolStream` | `Size` | Size of the raw symbol stream buffer | | `AppDomain` | `RootAssembly` | Pointer to the root assembly | | `AppDomain` | `DomainAssemblyList` | ArrayListBase of assemblies in the AppDomain | +| `AppDomain` | `FriendlyName` | Friendly name of the AppDomain | +| `SystemDomain` | `GlobalLoaderAllocator` | global LoaderAllocator | | `LoaderAllocator` | `ReferenceCount` | Reference count of LoaderAllocator | +| `LoaderAllocator` | `HighFrequencyHeap` | High-frequency heap of LoaderAllocator | +| `LoaderAllocator` | `LowFrequencyHeap` | Low-frequency heap of LoaderAllocator | +| `LoaderAllocator` | `StubHeap` | Stub heap of LoaderAllocator | | `ArrayListBase` | `Count` | Total number of elements in the ArrayListBase | | `ArrayListBase` | `FirstBlock` | First ArrayListBlock | | `ArrayListBlock` | `Next` | Next ArrayListBlock in chain | @@ -137,6 +150,7 @@ bool IsAssemblyLoaded(ModuleHandle handle); | Global Name | Type | Purpose | | --- | --- | --- | | `AppDomain` | TargetPointer | Pointer to the global AppDomain | +| `SystemDomain` | TargetPointer | Pointer to the global SystemDomain | ### Contract Constants: @@ -159,12 +173,18 @@ private enum ModuleFlags_1 : uint ### Method Implementations ``` csharp -ModuleHandle GetModuleHandle(TargetPointer modulePointer) +ModuleHandle GetModuleHandleFromModulePtr(TargetPointer modulePointer) { return new ModuleHandle(modulePointer); } -IEnumerable GetModules(TargetPointer appDomain, AssemblyIterationFlags iterationFlags) +ModuleHandle ILoader.GetModuleHandleFromAssemblyPtr(TargetPointer assemblyPointer) +{ + Data.Assembly assembly = // read Assembly object at assemblyPointer + return new ModuleHandle(assembly.Module); +} + +IEnumerable GetModuleHandles(TargetPointer appDomain, AssemblyIterationFlags iterationFlags) { if (appDomain == TargetPointer.Null) throw new ArgumentException("appDomain must not be null"); @@ -263,11 +283,25 @@ IEnumerable GetModules(TargetPointer appDomain, AssemblyIterationF TargetPointer GetRootAssembly() { - TargetPointer appDomainPointer = target.ReadGlobalPointer(Constants.Globals.AppDomain); + TargetPointer appDomainPointer = target.ReadGlobalPointer("AppDomain"); AppDomain appDomain = // read AppDomain object starting at appDomainPointer return appDomain.RootAssembly; } +string ILoader.GetAppDomainFriendlyName() +{ + TargetPointer appDomainPointer = target.ReadGlobalPointer("AppDomain"); + TargetPointer appDomain = target.ReadPointer(appDomainPointer) + TargetPointer pathStart = appDomain + /* AppDomain::FriendlyName offset */; + char[] name = // Read from target starting at pathStart until null terminator + return new string(name); +} + +TargetPointer ILoader.GetModule(ModuleHandle handle) +{ + return handle.Address; +} + TargetPointer GetAssembly(ModuleHandle handle) { return target.ReadPointer(handle.Address + /* Module::Assembly offset */); @@ -385,14 +419,17 @@ TargetPointer GetLoaderAllocator(ModuleHandle handle) return target.ReadPointer(handle.Address + /* Module::LoaderAllocator offset */); } -TargetPointer GetThunkHeap(ModuleHandle handle) +TargetPointer GetILBase(ModuleHandle handle) { - return target.ReadPointer(handle.Address + /* Module::ThunkHeap offset */); + return target.ReadPointer(handle.Address + /* Module::Base offset */); } -TargetPointer GetILBase(ModuleHandle handle) +TargetPointer ILoader.GetAssemblyLoadContext(ModuleHandle handle) { - return target.ReadPointer(handle.Address + /* Module::Base offset */); + PEAssembly peAssembly = target.ReadPointer(handle.Address + /* Module::PEAssembly offset */); + AssemblyBinder binder = target.ReadPointer(peAssembly + /* PEAssembly::AssemblyBinder offset */); + ObjectHandle objectHandle = new ObjectHandle(binder); + return objectHandle.Object; } ModuleLookupTables GetLookupTables(ModuleHandle handle) @@ -417,40 +454,61 @@ TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out Tar uint index = rid; // have to read lookupMap an extra time upfront because only the first map // has valid supportedFlagsMask - TargetNUInt supportedFlagsMask = _target.ReadNUInt(table + /* ModuleLookupMap::SupportedFlagsMask */); + TargetNUInt supportedFlagsMask = target.ReadNUInt(table + /* ModuleLookupMap::SupportedFlagsMask */); do { - if (index < _target.Read(table + /*ModuleLookupMap::Count*/)) + if (index < target.Read(table + /*ModuleLookupMap::Count*/)) { - TargetPointer entryAddress = _target.ReadPointer(lookupMap + /*ModuleLookupMap::TableData*/) + (ulong)(index * _target.PointerSize); - TargetPointer rawValue = _target.ReadPointer(entryAddress); + TargetPointer entryAddress = target.ReadPointer(lookupMap + /*ModuleLookupMap::TableData*/) + (ulong)(index * target.PointerSize); + TargetPointer rawValue = target.ReadPointer(entryAddress); flags = rawValue & supportedFlagsMask; return rawValue & ~(supportedFlagsMask.Value); } else { - table = _target.ReadPointer(lookupMap + /*ModuleLookupMap::Next*/); - index -= _target.Read(lookupMap + /*ModuleLookupMap::Count*/); + table = target.ReadPointer(lookupMap + /*ModuleLookupMap::Next*/); + index -= target.Read(lookupMap + /*ModuleLookupMap::Count*/); } } while (table != TargetPointer.Null); return TargetPointer.Null; } -``` -```csharp -bool ILoader.IsCollectible(ModuleHandle handle) +bool IsCollectible(ModuleHandle handle) { - TargetPointer assembly = _target.ReadPointer(handle.Address + /*Module::Assembly*/); - byte isCollectible = _target.Read(assembly + /* Assembly::IsCollectible*/); + TargetPointer assembly = target.ReadPointer(handle.Address + /*Module::Assembly*/); + byte isCollectible = target.Read(assembly + /* Assembly::IsCollectible*/); return isCollectible != 0; } -bool ILoader.IsAssemblyLoaded(ModuleHandle handle) +bool IsAssemblyLoaded(ModuleHandle handle) { - TargetPointer assembly = _target.ReadPointer(handle.Address + /*Module::Assembly*/); - uint loadLevel = _target.Read(assembly + /* Assembly::Level*/); + TargetPointer assembly = target.ReadPointer(handle.Address + /*Module::Assembly*/); + uint loadLevel = target.Read(assembly + /* Assembly::Level*/); return assembly.Level >= ASSEMBLY_LEVEL_LOADED; } + +TargetPointer GetGlobalLoaderAllocator() +{ + TargetPointer systemDomainPointer = target.ReadGlobalPointer("SystemDomain"); + TargetPointer systemDomain = target.ReadPointer(systemDomainPointer); + return target.ReadPointer(systemDomain + /* SystemDomain::GlobalLoaderAllocator offset */); +} + +TargetPointer GetHighFrequencyHeap(TargetPointer loaderAllocatorPointer) +{ + return target.ReadPointer(loaderAllocatorPointer + /* LoaderAllocator::HighFrequencyHeap offset */); +} + +TargetPointer GetLowFrequencyHeap(TargetPointer loaderAllocatorPointer) +{ + return target.ReadPointer(loaderAllocatorPointer + /* LoaderAllocator::LowFrequencyHeap offset */); +} + +TargetPointer GetStubHeap(TargetPointer loaderAllocatorPointer) +{ + return target.ReadPointer(loaderAllocatorPointer + /* LoaderAllocator::StubHeap offset */); +} + ``` ### DacEnumerableHash (EETypeHashTable and InstMethodHashTable) diff --git a/docs/design/datacontracts/PrecodeStubs.md b/docs/design/datacontracts/PrecodeStubs.md index 83f593fcf2c0ad..b336b433ac2e13 100644 --- a/docs/design/datacontracts/PrecodeStubs.md +++ b/docs/design/datacontracts/PrecodeStubs.md @@ -9,22 +9,32 @@ This contract provides support for examining [precode](../coreclr/botr/method-de TargetPointer GetMethodDescFromStubAddress(TargetCodePointer entryPoint); ``` -## Version 1 and 2 +## Version 1, 2, and 3 Data descriptors used: | Data Descriptor Name | Field | Meaning | | --- | --- | --- | -| PrecodeMachineDescriptor | OffsetOfPrecodeType | See `ReadPrecodeType` | -| PrecodeMachineDescriptor | ShiftOfPrecodeType | See `ReadPrecodeType` | -| PrecodeMachineDescriptor | ReadWidthOfPrecodeType | See `ReadPrecodeType` | +| PrecodeMachineDescriptor | OffsetOfPrecodeType | See `ReadPrecodeType` (Version 1 and 2 only) | +| PrecodeMachineDescriptor | ShiftOfPrecodeType | See `ReadPrecodeType` (Version 1 and 2 only) | +| PrecodeMachineDescriptor | ReadWidthOfPrecodeType | See `ReadPrecodeType` (Version 1 and 2 only) | | PrecodeMachineDescriptor | StubCodePageSize | Size of a precode code page (in bytes) | | PrecodeMachineDescriptor | CodePointerToInstrPointerMask | mask to apply to code pointers to get an address (see arm32 note) | PrecodeMachineDescriptor | StubPrecodeType | precode sort byte for stub precodes | | PrecodeMachineDescriptor | HasPInvokeImportPrecode | 1 if platform supports PInvoke precode stubs | -| PrecodeMachineDescriptor | PInvokeImportPrecodeType| precode sort byte for PInvoke precode stubs, if supported | +| PrecodeMachineDescriptor | PInvokeImportPrecodeType | precode sort byte for PInvoke precode stubs, if supported | | PrecodeMachineDescriptor | HasFixupPrecode | 1 if platform supports fixup precode stubs | -| PrecodeMachineDescriptor | FixupPrecodeType| precode sort byte for fixup precode stubs, if supported | +| PrecodeMachineDescriptor | FixupPrecodeType | precode sort byte for fixup precode stubs, if supported | | PrecodeMachineDescriptor | ThisPointerRetBufPrecodeType | precode sort byte for this pointer ret buf precodes | +| PrecodeMachineDescriptor | FixupStubPrecodeSize | Byte size of `FixupBytes` and `FixupIgnoredBytes` (Version 3 only) | +| PrecodeMachineDescriptor | FixupBytes | Assembly code of a FixupStub (Version 3 only) | +| PrecodeMachineDescriptor | FixupIgnoredBytes | Bytes to ignore of when comparing `FixupBytes` to an actual block of memory in the target process. (Version 3 only) | +| PrecodeMachineDescriptor | StubPrecodeSize | Byte size of `StubBytes` and `StubIgnoredBytes` (Version 3 only) | +| PrecodeMachineDescriptor | StubBytes | Assembly code of a StubPrecode (Version 3 only) | +| PrecodeMachineDescriptor | StubIgnoredBytes | Bytes to ignore of when comparing `StubBytes` to an actual block of memory in the target process. (Version 3 only) | +| PrecodeMachineDescriptor | FixupCodeOffset | Offset of second entrypoint into a `FixupStub` (Present in data for Version 3 and above only.) | +| PrecodeMachineDescriptor | InterpreterPrecodeType | precode sort byte for the entrypoint into the interpreter (Version 3 only) | +| PrecodeMachineDescriptor | UMEntryPrecodeType | precode sort byte for the entrypoint into the UMEntry thunk (Version 3 only) | +| PrecodeMachineDescriptor | DynamicHelperPrecodeType | precode sort byte for the entrypoint into a dynamic helper (Version 3 only) | | StubPrecodeData | MethodDesc | pointer to the MethodDesc associated with this stub precode (Version 1 only) | | StubPrecodeData | SecretParam | pointer to the MethodDesc associated with this stub precode or a second stub data pointer for other types (Version 2 only) | | StubPrecodeData | Type | precise sort of stub precode | @@ -44,12 +54,75 @@ Contracts used: | --- | | `PlatformMetadata` | -### Determining the precode type +### Determining the precode type (Version 3) +``` csharp + private bool ReadBytesAndCompare(TargetPointer instrAddress, byte[] expectedBytePattern, byte[] bytesToIgnore) + { + byte[] localCopy = new byte[expectedBytePattern.Length]; + for (int i = 0; i < expectedBytePattern.Length; i++) + { + if (bytesToIgnore[i] == 0) + { + byte targetBytePattern = _target.Read(instrAddress + i); + if (expectedBytePattern[i] != targetBytePattern) + { + return false; + } + } + } + + return true; + } + private KnownPrecodeType? TryGetKnownPrecodeType(TargetPointer instrAddress) + { + KnownPrecodeType? basicPrecodeType = default; + if (ReadBytesAndCompare(instrAddress, MachineDescriptor.StubBytes, MachineDescriptor.StubIgnoredBytes)) + { + // get the actual type from the StubPrecodeData + Data.StubPrecodeData stubPrecodeData = GetStubPrecodeData(instrAddress); + byte exactPrecodeType = stubPrecodeData.Type; + if (exactPrecodeType == 0) + return null; + + if (exactPrecodeType == MachineDescriptor.StubPrecodeType) + { + return KnownPrecodeType.Stub; + } + else if (MachineDescriptor.PInvokeImportPrecodeType is byte compareByte1 && compareByte1 == exactPrecodeType) + { + return KnownPrecodeType.PInvokeImport; + } + else if (MachineDescriptor.ThisPointerRetBufPrecodeType is byte compareByte2 && compareByte2 == exactPrecodeType) + { + return KnownPrecodeType.ThisPtrRetBuf; + } + else if (MachineDescriptor.UMEntryPrecodeType is byte compareByte3 && compareByte3 == exactPrecodeType) + { + return KnownPrecodeType.UMEntry; + } + else if (MachineDescriptor.InterpreterPrecodeType is byte compareByte4 && compareByte4 == exactPrecodeType) + { + return KnownPrecodeType.Interpreter; + } + else if (MachineDescriptor.DynamicHelperPrecodeType is byte compareByte5 && compareByte5 == exactPrecodeType) + { + return KnownPrecodeType.DynamicHelper; + } + } + else if (ReadBytesAndCompare(instrAddress, MachineDescriptor.FixupBytes, MachineDescriptor.FixupIgnoredBytes)) + { + return KnownPrecodeType.Fixup; + } + return null; + } +``` + +### Determining the precode type (Version 1 and 2) An initial approximation of the precode type relies on a particular pattern at a known offset from the precode entrypoint. The precode type is expected to be encoded as an immediate. On some platforms the value is spread over multiple instruction bytes and may need to be right-shifted. -``` +```csharp private byte ReadPrecodeType(TargetPointer instrPointer) { if (MachineDescriptor.ReadWidthOfPrecodeType == 1) @@ -121,9 +194,12 @@ After the initial precode type is determined, for stub precodes a refined precod internal enum KnownPrecodeType { Stub = 1, - PInvokeImport, // also known as NDirectImport in the runtime + PInvokeImport, Fixup, ThisPtrRetBuf, + UMEntry, + DynamicHelper, + Interpreter } internal abstract class ValidPrecode diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md index f0bfe7b66eb571..86fe79087fb690 100644 --- a/docs/design/datacontracts/RuntimeTypeSystem.md +++ b/docs/design/datacontracts/RuntimeTypeSystem.md @@ -53,15 +53,25 @@ partial interface IRuntimeTypeSystem : IContract // True if the MethodTable represents a type that contains managed references public virtual bool ContainsGCPointers(TypeHandle typeHandle); public virtual bool IsDynamicStatics(TypeHandle typeHandle); - public virtual ushort GetNumMethods(TypeHandle typeHandle); public virtual ushort GetNumInterfaces(TypeHandle typeHandle); // Returns an ECMA-335 TypeDef table token for this type, or for its generic type definition if it is a generic instantiation public virtual uint GetTypeDefToken(TypeHandle typeHandle); + public virtual ushort GetNumMethods(TypeHandle typeHandle); // Returns the ECMA 335 TypeDef table Flags value (a bitmask of TypeAttributes) for this type, // or for its generic type definition if it is a generic instantiation public virtual uint GetTypeDefTypeAttributes(TypeHandle typeHandle); + public ushort GetNumInstanceFields(TypeHandle typeHandle); + public ushort GetNumStaticFields(TypeHandle typeHandle); + public ushort GetNumThreadStaticFields(TypeHandle typeHandle); + public TargetPointer GetGCThreadStaticsBasePointer(TypeHandle typeHandle, TargetPointer threadPtr); + public TargetPointer GetNonGCThreadStaticsBasePointer(TypeHandle typeHandle, TargetPointer threadPtr); + public TargetPointer GetFieldDescList(TypeHandle typeHandle); + public TargetPointer GetGCStaticsBasePointer(TypeHandle typeHandle); + public TargetPointer GetNonGCStaticsBasePointer(TypeHandle typeHandle); public virtual ReadOnlySpan GetInstantiation(TypeHandle typeHandle); + public bool IsClassInited(TypeHandle typeHandle); + public bool IsInitError(TypeHandle typeHandle); public virtual bool IsGenericTypeDefinition(TypeHandle typeHandle); public virtual bool HasTypeParam(TypeHandle typeHandle); @@ -331,6 +341,7 @@ The contract depends on the following globals | Global name | Meaning | | --- | --- | | `FreeObjectMethodTablePointer` | A pointer to the address of a `MethodTable` used by the GC to indicate reclaimed memory +| `StaticsPointerMask` | For masking out a bit of DynamicStaticsInfo pointer fields The contract additionally depends on these data descriptors @@ -345,12 +356,23 @@ The contract additionally depends on these data descriptors | `MethodTable` | `NumInterfaces` | Number of interfaces of `MethodTable` | | `MethodTable` | `NumVirtuals` | Number of virtual methods in `MethodTable` | | `MethodTable` | `PerInstInfo` | Either the array element type, or pointer to generic information for `MethodTable` | +| `MethodTableAuxiliaryData` | `Flags` | Flags of `MethodTableAuxiliaryData` | +| `MethodTable` | `AuxiliaryData` | Pointer to the AuxiliaryData of a method table | +| `DynamicStaticsInfo` | `NonGCStatics` | Pointer to non-GC statics | +| `DynamicStaticsInfo` | `GCStatics` | Pointer to the GC statics | +| `DynamicStaticsInfo` | `Size` | Size of the data | +| `ThreadStaticsInfo` | `GCTlsIndex` | Pointer to GC thread local storage index | +| `ThreadStaticsInfo` | `NonGCTlsIndex` | Pointer to non-GC thread local storage index | | `EEClass` | `InternalCorElementType` | An InternalCorElementType uses the enum values of a CorElementType to indicate some of the information about the type of the type which uses the EEClass In particular, all reference types are CorElementType.Class, Enums are the element type of their underlying type and ValueTypes which can exactly be represented as an element type are represented as such, all other values types are represented as CorElementType.ValueType. | | `EEClass` | `MethodTable` | Pointer to the canonical MethodTable of this type | | `EEClass` | `MethodDescChunk` | Pointer to the first MethodDescChunk of the EEClass | | `EEClass` | `NumMethods` | Count of methods attached to the EEClass | | `EEClass` | `NumNonVirtualSlots` | Count of non-virtual slots for the EEClass | | `EEClass` | `CorTypeAttr` | Various flags | +| `EEClass` | `NumInstanceFields` | Count of instance fields of the EEClass | +| `EEClass` | `NumStaticFields` | Count of static fields of the EEClass | +| `EEClass` | `NumThreadStaticFields` | Count of threadstatic fields of the EEClass | +| `EEClass` | `FieldDescList` | A list of fields in the type | | `ArrayClass` | `Rank` | Rank of the associated array MethodTable | | `TypeDesc` | `TypeAndFlags` | The lower 8 bits are the CorElementType of the `TypeDesc`, the upper 24 bits are reserved for flags | | `ParamTypeDesc` | `TypeArg` | Associated type argument | @@ -362,6 +384,11 @@ The contract additionally depends on these data descriptors | `GenericsDictInfo` | `NumDicts` | Number of instantiation dictionaries, including inherited ones, in this `GenericsDictInfo` | | `GenericsDictInfo` | `NumTypeArgs` | Number of type arguments in the type or method instantiation described by this `GenericsDictInfo` | +Contracts used: +| Contract Name | +| --- | +| `Thread` | + ```csharp private readonly Dictionary _methodTables; @@ -377,11 +404,35 @@ The contract additionally depends on these data descriptors return TypeHandle { Address = typeHandlePointer } } + public TargetPointer GetModule(TypeHandle TypeHandle) + { + if (typeHandle.IsMethodTable()) + { + return _methodTables[TypeHandle.Address].Module; + } + else if (typeHandle.IsTypeDesc()) + { + if (HasTypeParam(typeHandle)) + { + return GetModule(GetTypeParam(typeHandle)); + } + else if (IsGenericVariable(typeHandle, out TargetPointer genericParamModule, out _)) + { + return genericParamModule; + } + } + return TargetPointer.Null; + } + internal static EEClassOrCanonMTBits GetEEClassOrCanonMTBits(TargetPointer eeClassOrCanonMTPtr) { return (EEClassOrCanonMTBits)(eeClassOrCanonMTPtr & (ulong)EEClassOrCanonMTBits.Mask); } + public TargetPointer GetCanonicalMethodTable(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : GetClassData(TypeHandle).MethodTable; + + public TargetPointer GetParentMethodTable(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : _methodTables[TypeHandle.Address].ParentMethodTable; + public uint GetBaseSize(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? (uint)0 : _methodTables[TypeHandle.Address].Flags.BaseSize; public uint GetComponentSize(TypeHandle TypeHandle) =>!typeHandle.IsMethodTable() ? (uint)0 : GetComponentSize(_methodTables[TypeHandle.Address]); @@ -400,36 +451,16 @@ The contract additionally depends on these data descriptors ... // read Data.EEClass data from eeClassPtr } - - public TargetPointer GetCanonicalMethodTable(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : GetClassData(TypeHandle).MethodTable; - - public TargetPointer GetModule(TypeHandle TypeHandle) - { - if (typeHandle.IsMethodTable()) - { - return _methodTables[TypeHandle.Address].Module; - } - else if (typeHandle.IsTypeDesc()) - { - if (HasTypeParam(typeHandle)) - { - return GetModule(GetTypeParam(typeHandle)); - } - else if (IsGenericVariable(typeHandle, out TargetPointer genericParamModule, out _)) - { - return genericParamModule; - } - } - return TargetPointer.Null; - } - - public TargetPointer GetParentMethodTable(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : _methodTables[TypeHandle.Address].ParentMethodTable; - public bool IsFreeObjectMethodTable(TypeHandle TypeHandle) => FreeObjectMethodTablePointer == TypeHandle.Address; public bool IsString(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.IsString; + public bool ContainsGCPointers(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.ContainsGCPointers; + public bool IsDynamicStatics(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.IsDynamicStatics; + + public ushort GetNumInterfaces(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? 0 : _methodTables[TypeHandle.Address].NumInterfaces; + public uint GetTypeDefToken(TypeHandle TypeHandle) { if (!typeHandle.IsMethodTable()) @@ -441,11 +472,71 @@ The contract additionally depends on these data descriptors public ushort GetNumMethods(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? 0 : GetClassData(TypeHandle).NumMethods; - public ushort GetNumInterfaces(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? 0 : _methodTables[TypeHandle.Address].NumInterfaces; - public uint GetTypeDefTypeAttributes(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? 0 : GetClassData(TypeHandle).CorTypeAttr; - public bool IsDynamicStatics(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.IsDynamicStatics; + public ushort GetNumInstanceFields(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : GetClassData(typeHandle).NumInstanceFields; + + public ushort GetNumStaticFields(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : GetClassData(typeHandle).NumStaticFields; + + public ushort GetNumThreadStaticFields(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : GetClassData(typeHandle).NumThreadStaticFields; + + public TargetPointer GetFieldDescList(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : GetClassData(typeHandle).FieldDescList; + + public TargetPointer GetGCStaticsBasePointer(TypeHandle typeHandle) + { + if (!typeHandle.IsMethodTable()) + return TargetPointer.Null; + + MethodTable methodTable = _methodTables[typeHandle.Address]; + if (!methodTable.Flags.IsDynamicStatics) + return TargetPointer.Null; + TargetPointer dynamicStaticsInfoSize = target.GetTypeInfo(DataType.DynamicStaticsInfo).Size!.Value; + TargetPointer mask = target.ReadGlobalPointer("StaticsPointerMask"); + + TargetPointer dynamicStaticsInfo = methodTable.AuxiliaryData - dynamicStaticsInfoSize; + return (target.ReadPointer(dynamicStaticsInfo + /* DynamicStaticsInfo::GCStatics offset */) & (ulong)mask); + } + + public TargetPointer GetNonGCStaticsBasePointer(TypeHandle typeHandle) + { + if (!typeHandle.IsMethodTable()) + return TargetPointer.Null; + + MethodTable methodTable = _methodTables[typeHandle.Address]; + if (!methodTable.Flags.IsDynamicStatics) + return TargetPointer.Null; + TargetPointer dynamicStaticsInfoSize = target.GetTypeInfo(DataType.DynamicStaticsInfo).Size!.Value; + TargetPointer mask = target.ReadGlobalPointer("StaticsPointerMask"); + + TargetPointer dynamicStaticsInfo = methodTable.AuxiliaryData - dynamicStaticsInfoSize; + return (target.ReadPointer(dynamicStaticsInfo + /* DynamicStaticsInfo::NonGCStatics offset */) & (ulong)mask); + } + + public TargetPointer GetGCThreadStaticsBasePointer(TypeHandle typeHandle, TargetPointer threadPtr) + { + if (!typeHandle.IsMethodTable()) + return TargetPointer.Null; + MethodTable_1 methodTable = _methodTables[typeHandle.Address]; + TargetPointer threadStaticsInfoSize = target.GetTypeInfo(DataType.ThreadStaticsInfo).Size; + TargetPointer threadStaticsInfoAddr = methodTable.AuxiliaryData - threadStaticsInfoSize; + + TargetPointer tlsIndexAddr = threadStaticsInfoAddr + /* ThreadStaticsInfo::GCTlsIndex offset */; + Contracts.IThread threadContract = target.Contracts.Thread; + return threadContract.GetThreadLocalStaticBase(threadPtr, tlsIndexAddr); + } + + public TargetPointer GetNonGCThreadStaticsBasePointer(TypeHandle typeHandle, TargetPointer threadPtr) + { + if (!typeHandle.IsMethodTable()) + return TargetPointer.Null; + MethodTable_1 methodTable = _methodTables[typeHandle.Address]; + TargetPointer threadStaticsInfoSize = target.GetTypeInfo(DataType.ThreadStaticsInfo).Size; + TargetPointer threadStaticsInfoAddr = methodTable.AuxiliaryData - threadStaticsInfoSize; + + TargetPointer tlsIndexAddr = threadStaticsInfoAddr + /* ThreadStaticsInfo::NonGCTlsIndex offset */; + Contracts.IThread threadContract = target.Contracts.Thread; + return threadContract.GetThreadLocalStaticBase(threadPtr, tlsIndexAddr); + } public ReadOnlySpan GetInstantiation(TypeHandle TypeHandle) { @@ -468,6 +559,26 @@ The contract additionally depends on these data descriptors return instantiation; } + public bool IsClassInited(TypeHandle typeHandle) + { + if (!typeHandle.IsMethodTable()) + return false; + TargetPointer auxiliaryDataPtr = target.ReadPointer(typeHandle.Address + /* MethodTable.AuxiliaryData offset */); + TargetPointer flagsPtr = target.ReadPointer(auxiliaryDataPtr + /* MethodTableAuxiliaryData::Flags offset */); + uint flags = target.Read(flagsPtr); + return (flags & (uint)MethodTableAuxiliaryFlags.Initialized) != 0; + } + + public bool IsInitError(TypeHandle typeHandle) + { + if (!typeHandle.IsMethodTable()) + return false; + TargetPointer auxiliaryDataPtr = target.ReadPointer(typeHandle.Address + /* MethodTable.AuxiliaryData offset */); + TargetPointer flagsPtr = target.ReadPointer(auxiliaryDataPtr + /* MethodTableAuxiliaryData::Flags offset */); + uint flags = target.Read(flagsPtr); + return (flags & (uint)MethodTableAuxiliaryFlags.IsInitError) != 0; + } + public bool IsDynamicStatics(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.IsDynamicStatics; public bool HasTypeParam(TypeHandle typeHandle) @@ -675,7 +786,6 @@ The contract depends on the following other contracts | ReJIT | | ExecutionManager | | PrecodeStubs | -| ECall | And the following enumeration definitions @@ -740,6 +850,12 @@ And the following enumeration definitions TemporaryEntryPointAssigned = 0x04, } + internal enum MethodTableAuxiliaryFlags : uint + { + Initialized = 0x0001, + IsInitError = 0x0100, + } + ``` Internal to the contract in order to answer queries about method descriptors, @@ -868,7 +984,7 @@ And the various apis are implemented with the following algorithms ushort FlagsAndTokenRange = // Read FlagsAndTokenRange field from MethodDescChunk contract using address methodDescChunk - int tokenRemainderBitCount = _target.ReadGlobal(Constants.Globals.MethodDescTokenRemainderBitCount); + int tokenRemainderBitCount = _target.ReadGlobal("MethodDescTokenRemainderBitCount"); int tokenRangeBitCount = 24 - tokenRemainderBitCount; uint allRidBitsSet = 0xFFFFFF; uint tokenRemainderMask = allRidBitsSet >> tokenRangeBitCount; @@ -1030,7 +1146,7 @@ Determining if a method is in a collectible module: { MethodDesc md = _methodDescs[methodDesc.Address]; TargetPointer loaderModuleAddr = GetLoaderModule(md); - ModuleHandle mod = _target.Contracts.Loader.GetModuleHandle(loaderModuleAddr); + ModuleHandle mod = _target.Contracts.Loader.GetModuleHandleFromModulePtr(loaderModuleAddr); return _target.Contracts.Loader.IsCollectible(mod); } @@ -1093,7 +1209,7 @@ Checking if a method has a native code slot and getting its address { MethodClassification.IL => /*size of MethodDesc*/, MethodClassification.FCall => /* size of FCallMethodDesc */ - MethodClassification.PInvoke => /* size of NDirectMethodDesc */ + MethodClassification.PInvoke => /* size of PInvokeMethodDesc */ MethodClassification.EEImpl => /* size of EEImplMethodDesc */ MethodClassification.Array => /* size of ArrayMethodDesc */ MethodClassification.Instantiated => /* size of InstantiatedMethodDesc */ @@ -1230,15 +1346,6 @@ Getting a MethodDesc for a certain slot in a MethodTable return methodDescPtr; } - // FCall path, look up address in the FCall table using the ECall contract - { - TargetPointer methodDescPtr = _target.Contracts.ECall.MapTargetBackToMethodDesc(pCode); - if (methodDescPtr != TargetPointer.Null) - { - return methodDescPtr; - } - } - // Stub path, read address as a Precode and get the MethodDesc from it { TargetPointer methodDescPtr = _target.Contracts.PrecodeStubs.GetMethodDescFromStubAddress(pCode); @@ -1258,16 +1365,20 @@ Getting a MethodDesc for a certain slot in a MethodTable if (pCode == TargetCodePointer.Null) { - // if pCode is null, we iterate through the method descs in the MT. - foreach (MethodDescHandle mdh in GetIntroducedMethods(typeHandle)) + // if pCode is null, we iterate through the method descs in the MT + while (true) // arbitrary limit to avoid infinite loop { - MethodDesc md = _methodDescs[mdh.Address]; - - // if a MethodDesc matches the slot, return that MethodDesc - if (md.Slot == slot) + foreach (MethodDescHandle mdh in GetIntroducedMethods(canonMT)) { - return mdh.Address; + MethodDesc md = _methodDescs[mdh.Address]; + + // if a MethodDesc matches the slot, return that MethodDesc + if (md.Slot == slot) + { + return mdh.Address; + } } + canonMT = GetTypeHandle(GetCanonicalMethodTable(GetTypeHandle(GetParentMethodTable(canonMT)))); } } diff --git a/docs/design/datacontracts/StressLog.md b/docs/design/datacontracts/StressLog.md index abb7824a837f0c..3b90a216cfdf50 100644 --- a/docs/design/datacontracts/StressLog.md +++ b/docs/design/datacontracts/StressLog.md @@ -53,6 +53,7 @@ Data descriptors used: | StressLog | TickFrequency | Number of ticks per second for stresslog timestamps | | StressLog | StartTimestamp | Timestamp when the stress log was started | | StressLog | ModuleOffset | Offset of the module in the stress log | +| StressLog | Modules | Offset of the stress log's module table (if StressLogHasModuleTable is `1`) | | StressLog | Logs | Pointer to the thread-specific logs | | StressLogModuleDesc | BaseAddress | Base address of the module | | StressLogModuleDesc | Size | Size of the module | @@ -80,7 +81,6 @@ Global variables used: | StressLogChunkSize | uint | Size of a stress log chunk | | StressLogMaxMessageSize | ulong | Maximum size of a stress log message | | StressLogHasModuleTable | byte | Whether the stress log module table is present | -| StressLogModuleTable | pointer | Pointer to the stress log's module table (if StressLogHasModuleTable is `1`) | ```csharp bool HasStressLog() @@ -95,7 +95,7 @@ StressLogData GetStressLogData() return default; } - StressLog stressLog = new StressLog(Target, Target.ReadGlobalPointer(Constants.Globals.StressLog)); + StressLog stressLog = new StressLog(Target, Target.ReadGlobalPointer("StressLog")); return new StressLogData( stressLog.LoggedFacilities, stressLog.Level, @@ -210,18 +210,27 @@ bool IsPointerInStressLog(StressLogData stressLog, TargetPointer pointer) // This method is a helper for the various specific versions. protected TargetPointer GetFormatPointer(ulong formatOffset) { - if (Target.ReadGlobal(Constants.Globals.StressLogHasModuleTable) == 0) + if (Target.ReadGlobal("StressLogHasModuleTable") == 0) { - StressLog stressLog = new(Target, target.ReadGlobalPointer(Constants.Globals.StressLog)); + StressLog stressLog = new(Target, target.ReadGlobalPointer("StressLog")); return new TargetPointer(stressLog.ModuleOffset + formatOffset); } - TargetPointer moduleTable = target.ReadGlobalPointer(Constants.Globals.StressLogModuleTable); + TargetPointer? moduleTable; + if (!target.TryReadGlobalPointer(Constants.Globals.StressLogModuleTable, out moduleTable)) + { + if (!target.TryReadGlobalPointer(Constants.Globals.StressLog, out TargetPointer? pStressLog)) + { + throw new InvalidOperationException("StressLogModuleTable is not set and StressLog is not available, but StressLogHasModuleTable is set to 1."); + } + Data.StressLog stressLog = target.ProcessedData.GetOrAdd(pStressLog.Value); + moduleTable = stressLog.Modules ?? throw new InvalidOperationException("StressLogModuleTable is not set and StressLog does not contain a ModuleTable offset, but StressLogHasModuleTable is set to 1."); + } uint moduleEntrySize = target.GetTypeInfo(DataType.StressLogModuleDesc).Size!.Value; - uint maxModules = target.ReadGlobal(Constants.Globals.StressLogMaxModules); + uint maxModules = target.ReadGlobal("StressLogMaxModules"); for (uint i = 0; i < maxModules; ++i) { - StressLogModuleDesc module = new(Target, moduleTable + i * moduleEntrySize); + StressLogModuleDesc module = new(Target, moduleTable.Value + i * moduleEntrySize); ulong relativeOffset = formatOffset - cumulativeOffset; if (relativeOffset < module.Size.Value) { @@ -313,7 +322,7 @@ The format offset refers to the cummulative offset into a module referred to in ```csharp StressMsgData GetStressMsgData(StressMsg msg) { - StressLog stressLog = new(Target, target.ReadGlobalPointer(Constants.Globals.StressLog)); + StressLog stressLog = new(Target, target.ReadGlobalPointer("StressLog")); uint pointerSize = Target.GetTypeInfo(DataType.pointer).Size!.Value; ulong payload1 = target.Read(msg.Header); diff --git a/docs/design/datacontracts/Thread.md b/docs/design/datacontracts/Thread.md index efdd7d0bbc653a..dcd0e39e611d13 100644 --- a/docs/design/datacontracts/Thread.md +++ b/docs/design/datacontracts/Thread.md @@ -46,29 +46,73 @@ record struct ThreadData ( ThreadStoreData GetThreadStoreData(); ThreadStoreCounts GetThreadCounts(); ThreadData GetThreadData(TargetPointer threadPointer); -TargetPointer GetManagedThreadObject(TargetPointer threadPointer); +TargetPointer IdToThread(uint id); +TargetPointer GetThreadLocalStaticBase(TargetPointer threadPointer, int indexOffset, int indexType); ``` ## Version 1 -This contract depends on the following descriptors: - -| Data descriptor name | -| --- | -| `GCAllocContext` | -| `RuntimeThreadLocals` | -| `Thread` | -| `ThreadStore` | - -| Global name | -| --- | -| `AppDomain` | -| `ThreadStore` | -| `FeatureEHFunclets` | -| `FinalizerThread` | -| `GCThread` | - +The contract depends on the following globals + +| Global name | Type | Meaning | +| --- | --- | +| `AppDomain` | TargetPointer | A pointer to the address of the one AppDomain +| `ThreadStore` | TargetPointer | A pointer to the address of the ThreadStore +| `FeatureEHFunclets` | TargetPointer | 1 if EH funclets are enabled, 0 otherwise +| `FinalizerThread` | TargetPointer | A pointer to the finalizer thread +| `GCThread` | TargetPointer | A pointer to the GC thread +| `ThinLockThreadIdDispenser` | TargetPointer | Dispenser of thinlock IDs for locking objects +| `NumberOfTlsOffsetsNotUsedInNoncollectibleArray` | byte | Number of unused slots in noncollectible TLS array +| `PtrArrayOffsetToDataArray` | TargetPointer | Offset from PtrArray class address to start of enclosed data array + +The contract additionally depends on these data descriptors + +| Data Descriptor Name | Field | Meaning | +| --- | --- | --- | +| `ExceptionInfo` | `PreviousNestedInfo` | Pointer to previous nested exception info | +| `GCAllocContext` | `Pointer` | GC allocation pointer | +| `GCAllocContext` | `Limit` | Allocation limit pointer | +| `IdDispenser` | `HighestId` | Highest possible small thread ID | +| `IdDispenser` | `IdToThread` | Array mapping small thread IDs to thread pointers | +| `InflightTLSData` | `Next` | Pointer to next in-flight TLS data entry | +| `InflightTLSData` | `TlsIndex` | TLS index for the in-flight static field | +| `InflightTLSData` | `TLSData` | Object handle to the TLS data for the static field | +| `ObjectHandle` | `Object` | Pointer to the managed object | +| `RuntimeThreadLocals` | `AllocContext` | GC allocation context for the thread | +| `TLSIndex` | `IndexOffset` | Offset index for thread local storage | +| `TLSIndex` | `IndexType` | Type of thread local storage index | +| `TLSIndex` | `IsAllocated` | Whether TLS storage has been allocated | +| `TLSIndex` | `TLSIndexRawIndex` | Raw index value containing type and offset | +| `Thread` | `Id` | Thread identifier | +| `Thread` | `OSId` | Operating system thread identifier | +| `Thread` | `State` | Thread state flags | +| `Thread` | `PreemptiveGCDisabled` | Flag indicating if preemptive GC is disabled | +| `Thread` | `Frame` | Pointer to current frame | +| `Thread` | `TEB` | Thread Environment Block pointer | +| `Thread` | `LastThrownObject` | Handle to last thrown exception object | +| `Thread` | `LinkNext` | Pointer to get next thread | +| `Thread` | `ExceptionTracker` | Pointer to exception tracking information | +| `Thread` | `RuntimeThreadLocals` | Pointer to some thread-local storage | +| `Thread` | `ThreadLocalDataPtr` | Pointer to thread local data structure | +| `ThreadLocalData` | `NonCollectibleTlsData` | Count of non-collectible TLS data entries | +| `ThreadLocalData` | `NonCollectibleTlsArrayData` | Pointer to non-collectible TLS array data | +| `ThreadLocalData` | `CollectibleTlsData` | Count of collectible TLS data entries | +| `ThreadLocalData` | `CollectibleTlsArrayData` | Pointer to collectible TLS array data | +| `ThreadLocalData` | `InFlightData` | Pointer to in-flight TLS data for fields being initialized | +| `ThreadStore` | `ThreadCount` | Number of threads | +| `ThreadStore` | `FirstThreadLink` | Pointer to first thread in the linked list | +| `ThreadStore` | `UnstartedCount` | Number of unstarted threads | +| `ThreadStore` | `BackgroundCount` | Number of background threads | +| `ThreadStore` | `PendingCount` | Number of pending threads | +| `ThreadStore` | `DeadCount` | Number of dead threads | ``` csharp +enum TLSIndexType +{ + NonCollectible = 0, + Collectible = 1, + DirectOnThreadLocalData = 2, +}; + ThreadStoreData GetThreadStoreData() { TargetPointer threadStore = target.ReadGlobalPointer("ThreadStore"); @@ -94,11 +138,11 @@ DacThreadStoreCounts GetThreadCounts() ThreadData GetThreadData(TargetPointer address) { - var runtimeThread = new Thread(Target, threadPointer); + var runtimeThread = new Thread(target, threadPointer); // Exception tracker is a pointer when EH funclets are enabled - TargetPointer exceptionTrackerAddr = _target.ReadGlobal("FeatureEHFunclets") != 0 - ? _target.ReadPointer(address + /* Thread::ExceptionTracker offset */) + TargetPointer exceptionTrackerAddr = target.ReadGlobal("FeatureEHFunclets") != 0 + ? target.ReadPointer(address + /* Thread::ExceptionTracker offset */) : address + /* Thread::ExceptionTracker offset */; TargetPointer firstNestedException = exceptionTrackerAddr != TargetPointer.Null ? target.ReadPointer(exceptionTrackerAddr + /* ExceptionInfo::PreviousNestedInfo offset*/) @@ -129,9 +173,71 @@ ThreadData GetThreadData(TargetPointer address) ); } -TargetPointer GetManagedThreadObject(TargetPointer threadPointer) +TargetPointer IThread.IdToThread(uint id) +{ + TargetPointer idDispenserPointer = target.ReadGlobalPointer(Constants.Globals.ThinlockThreadIdDispenser); + TargetPointer idDispenser = target.ReadPointer(idDispenserPointer); + uint HighestId = target.ReadPointer(idDispenser + /* IdDispenser::HighestId offset */); + TargetPointer threadPtr = TargetPointer.Null; + if (id < HighestId) + threadPtr = target.ReadPointer(idDispenser + /* IdDispenser::IdToThread offset + (index into IdToThread array * size of array elements (== size of target pointer)) */); + return threadPtr; +} + +TargetPointer IThread.GetThreadLocalStaticBase(TargetPointer threadPointer, TargetPointer tlsIndexPtr) { - var runtimeThread = new Thread(Target, threadPointer); - return Contracts.GCHandle.GetObject(new DacGCHandle(runtimeThread.m_ExposedObject)); + // Get the thread's TLS base address + TargetPointer threadLocalDataPtr = target.ReadPointer(threadPointer + /* Thread::ThreadLocalDataPtr offset */); + if (threadLocalDataPtr == TargetPointer.Null) + return TargetPointer.Null; + + Data.TLSIndex tlsIndex = new Data.TLSIndex(tlsIndexPtr); + if (!tlsIndex.IsAllocated) + return TargetPointer.Null; + + TargetPointer threadLocalStaticBase = default; + int indexType = tlsIndex.IndexType; + int indexOffset = tlsIndex.IndexOffset; + switch ((TLSIndexType)indexType) + { + case TLSIndexType.NonCollectible: + int nonCollectibleCount = target.ReadPointer(threadLocalDataPtr + /* ThreadLocalData::NonCollectibleTlsDataCount offset */); + // bounds check + if (nonCollectibleCount > indexOffset) + { + TargetPointer nonCollectibleArray = target.ReadPointer(threadLocalDataPtr + /* ThreadLocalData::NonCollectibleTlsArrayData offset */); + int arrayIndex = indexOffset - target.ReadGlobal("NumberOfTlsOffsetsNotUsedInNoncollectibleArray"); + TargetPointer arrayStartAddress = nonCollectibleArray + target.ReadGlobalPointer("PtrArrayOffsetToDataArray"); + threadLocalStaticBase = target.ReadPointer(arrayStartAddress + (ulong)(arrayIndex * target.PointerSize)); + } + break; + case TLSIndexType.Collectible: + int collectibleCount = target.ReadPointer(threadLocalDataPtr + /* ThreadLocalData::CollectibleTlsDataCount offset */); + if (collectibleCount > indexOffset) + { + TargetPointer collectibleArray = target.ReadPointer(threadLocalDataPtr + /* ThreadLocalData::CollectibleTlsArrayData offset */); + threadLocalStaticBase = target.ReadPointer(collectibleArray + (ulong)(indexOffset * target.PointerSize)); + } + break; + case TLSIndexType.DirectOnThreadLocalData: + threadLocalStaticBase = threadLocalDataPtr; + break; + } + if (threadLocalStaticBase == TargetPointer.Null) + { + TargetPointer inFlightData = target.ReadPointer(threadLocalDataPtr + /* ThreadLocalData::inFlightData offset */); + while (inFlightData != TargetPointer.Null) + { + TargetPointer tlsIndexInFlightPtr = target.ReadPointer(inFlightData + /* InflightTLSData::TlsIndex offset */); + Data.TLSIndex tlsIndexInFlight = new Data.TLSIndex(tlsIndexInFlightPtr); + if (tlsIndexInFlight.TLSIndexRawIndex == tlsIndex.TLSIndexRawIndex) + { + threadLocalStaticBase = target.ReadPointer(tlsIndexInFlightPtr + /* InflightTLSData::TLSData offset */); + break; + } + inFlightData = target.ReadPointer(inFlightData + /* InflightTLSData::Next offset */); + } + } + return threadLocalStaticBase; } ``` diff --git a/docs/design/datacontracts/debug_interface_globals.md b/docs/design/datacontracts/debug_interface_globals.md new file mode 100644 index 00000000000000..c4d1348f138ce0 --- /dev/null +++ b/docs/design/datacontracts/debug_interface_globals.md @@ -0,0 +1,22 @@ +# Debug Interface Globals + +The following document lists the global variables that are used directly in the debug interface managed code (SOSDacImpl.cs, etc.) + +Global variables used +| Global Name | Type | Purpose | +| --- | --- | --- | +| StringMethodTable | TargetPointer | Identify where the string MethodTable exists | +| ObjectMethodTable | TargetPointer | Identify where the object MethodTable exists | +| SystemDomain | TargetPointer | Identify where the SystemDomain exists | +| DirectorySeparator | TargetPointer | Identify where the directory separator exists | +| FeatureCOMInterop | TargetPointer | Identify where the flag for FeatureCOMInterop exists | +| StressLog | TargetPointer | Identify where the StressLog exists | +| AppDomain | TargetPointer | Identify where the AppDomain exists | +| ObjectArrayMethodTable | TargetPointer | Identify where the ObjectArrayMethodTable exists | +| ExceptionMethodTable | TargetPointer | Identify where the ExceptionMethodTable exists | +| FreeObjectMethodTable | TargetPointer | Identify where the FreeObjectMethodTable exists | +| SOSBreakingChangeVersion | TargetPointer | Identify where the SOSBreakingChangeVersion exists | +| DacNotificationFlags | TargetPointer | Identify where the DacNotificationFlags exists | +| MaxClrNotificationArgs | uint32 | Identify the maximum number of CLR notification arguments | +| ClrNotificationArguments | TargetPointer | Identify where the ClrNotificationArguments exists | +| DefaultADID | uint | Identify the default AppDomain ID | diff --git a/docs/design/features/typemap.md b/docs/design/features/typemap.md index 6501b3b0b33b8a..9e1e7572491625 100644 --- a/docs/design/features/typemap.md +++ b/docs/design/features/typemap.md @@ -134,7 +134,7 @@ Given the above types the following would take place. `TypeMapAttribute` assembly attribute that declared the external type system name, a target type, and optionally a "trim-target" to determine if the target type should be included in the map. If the `TypeMapAttribute` constructor that doesn't -take a trim-target is used, the "target type" will be treated as the "trim-target". +take a trim-target is used the entry will always be emitted into the type map. 2. Types used in a managed-to-unmanaged interop operation would use `TypeMapAssociationAttribute` to define a conditional link between the source and proxy type. In other words, if the @@ -188,14 +188,12 @@ An entry in an External Type Map is included when the "trim target" type is refe - The argument to the `isinst` IL instruction. - The argument to the `castclass` IL instruction. - The argument to the `box` instruction. + - If the trimming tool can determine that this box does not escape and could be stack allocated, it can ignore this `box` instruction and any corresponding `unbox` or `unbox.any` instructions. - The argument to the `mkrefany` instruction. - The argument to the `refanyval` instruction. - The argument to the `newarr` instruction. -- The argument to the `ldobj` instruction. -- The argument to the `stobj` instruction. -- The argument to the `.constrained` instruction prefix. -- The type of a method argument to the `newobj` instruction. -- The owning type of the method argument to `call`, `callvirt`, `ldftn`, or `ldvirtftn`. +- The type of a method argument to the `newobj` instruction if it is a class type. +- The owning type of an instance method argument to `call` or `ldftn`, or the owning type of any method argument to `callvirt` or `ldvirtftn`. - If the owning type is an interface and the trimming tool can determine that there is only one implementation of the interface, it is free to interpret the method token argument as though it is the method on the only implementing type. - The generic argument to the `Activator.CreateInstance` method. - Calls to `Type.GetType` with a constant string representing the type name. @@ -212,7 +210,6 @@ An entry in the Proxy Type Map is included when the "source type" is referenced - The generic argument to the `Activator.CreateInstance` method. - The argument to the `box` instruction. - The argument to the `newarr` instruction. -- The argument to the `.constrained` instruction prefix. - The argument to the `mkrefany` instruction. - The argument to the `refanyval` instruction. @@ -221,3 +218,5 @@ If the type is an interface type and the user could possibly see a `RuntimeTypeH - The argument to the `isinst` IL instruction. - The argument to the `castclass` IL instruction. - The owning type of the method argument to `callvirt`, or `ldvirtftn`. + +Finally, if the trimming tool determines that it is impossible to retrieve a `System.Type` instance the represents the "source type" at runtime, then the entry may be omitted from the Proxy Type Map as its existence is unobservable. diff --git a/docs/design/mono/web/linear-ir.md b/docs/design/mono/web/linear-ir.md index b72e6c28c911c1..4abb62d111ba7a 100644 --- a/docs/design/mono/web/linear-ir.md +++ b/docs/design/mono/web/linear-ir.md @@ -41,7 +41,7 @@ Each IR instruction is represented by a MonoInst structure. The fields of the st - ins-\>opcode contains the opcode of the instruction. It is always set. -- ins-\>dreg, ins-\>sreg1, ins-\>sreg2 contain the the destination and source vregs of the instruction. If the instruction doesn't have a destination/and our source, the corresponding field is set to -1. +- ins-\>dreg, ins-\>sreg1, ins-\>sreg2 contain the destination and source vregs of the instruction. If the instruction doesn't have a destination/and our source, the corresponding field is set to -1. - ins-\>backend is used for various purposes: - for MonoInst's representing vtype variables, it indicates that the variable is in unmanaged format (used during marshalling) diff --git a/docs/design/mono/web/soft-debugger-wire-format.md b/docs/design/mono/web/soft-debugger-wire-format.md index 49facbc283df79..f49f395de0905d 100644 --- a/docs/design/mono/web/soft-debugger-wire-format.md +++ b/docs/design/mono/web/soft-debugger-wire-format.md @@ -392,7 +392,7 @@ Each command requires at least one TypeID (of type id) parameter before any addi | GET_FIELD_CATTRS | 11 | Returns a list of custom attributes of a type's field. Custom attribute definition is given below. | Ask for a FieldID of one the type field and a TypeID of an custom attribute type | INVALID_TYPEID, INVALID_FIELDID | | GET_PROPERTY_CATTRS | 12 | Returns a list of custom attributes of a type's property. Custom attribute definition is given below. | Ask for a PropertyID of one the type field and a TypeID of an custom attribute type | INVALID_TYPEID, INVALID_PROPERTYID | | GET_SOURCE_FILES_2 | 13 | Returns a list of source file full paths (string) where the type is defined | None | INVALID_TYPEID | -| GET_VALUES_2 | 14 | Returns a number of variant value equals to the number of FieldID that was passed as parameter. If the field had a ThreadStatic attribute applied to it, value fetched are from the thread parameter point of view. | Ask for an ObjectID representing a System.Thread instance and a list of FieldID representing this type static fields to the the value of. Only static field are supported. | INVALID_OBJECT, INVALID_TYPEID, INVALID_FIELDID | +| GET_VALUES_2 | 14 | Returns a number of variant value equals to the number of FieldID that was passed as parameter. If the field had a ThreadStatic attribute applied to it, value fetched are from the thread parameter point of view. | Ask for an ObjectID representing a System.Thread instance and a list of FieldID representing this type static fields to the value of. Only static field are supported. | INVALID_OBJECT, INVALID_TYPEID, INVALID_FIELDID | The main functions handling these commands are `type_commands` and `type_commands_internal` and are situated at `debugger-agent.c:6726` and `debugger-agent.c:6403` respectively. diff --git a/docs/design/security/System.HashCode.md b/docs/design/security/System.HashCode.md index fb177ac2d0c38d..946c611f409129 100644 --- a/docs/design/security/System.HashCode.md +++ b/docs/design/security/System.HashCode.md @@ -128,7 +128,7 @@ Concretely, in the face of adversarial input: ## Implementation -The `HashCode` type uses the [**xxHash32**](https://github.com/Cyan4973/xxHash) algorithm, which is a non-cryptographic hash algorithm with a 32-bit seed and a 32-bit digest. All instances of the `HashCode` type use the same seed value, generated randomly at app start. This value is chosen independently of other random seed values in the runtime, such as the the global 64-bit seed used in `string.GetHashCode`'s Marvin32 routine. +The `HashCode` type uses the [**xxHash32**](https://github.com/Cyan4973/xxHash) algorithm, which is a non-cryptographic hash algorithm with a 32-bit seed and a 32-bit digest. All instances of the `HashCode` type use the same seed value, generated randomly at app start. This value is chosen independently of other random seed values in the runtime, such as the global 64-bit seed used in `string.GetHashCode`'s Marvin32 routine. The xxHash32 repo's README file touts good performance and avalanching. This can be validated through a simple C# program. diff --git a/docs/design/tools/illink/compiler-generated-code-handling.md b/docs/design/tools/illink/compiler-generated-code-handling.md index 4ed908db0eab76..df5661ea01ed96 100644 --- a/docs/design/tools/illink/compiler-generated-code-handling.md +++ b/docs/design/tools/illink/compiler-generated-code-handling.md @@ -95,6 +95,24 @@ static IEnumerable TestLocalVariable () } ``` +## Attribute propagation via CompilerLoweringPreserveAttribute + +To address the challenges of propagating user-authored attributes to compiler-generated code, .NET 10 introduced a general mechanism: `[CompilerLoweringPreserveAttribute]`. This attribute can be applied to other attribute types to instruct compilers to propagate those attributes to compiler-generated code. + +`DynamicallyAccessedMembersAttribute` is now marked with `[CompilerLoweringPreserve]`, so when the compiler generates new fields or type parameters (such as for local functions, iterator/async state machines, or primary constructor parameters), the relevant `DynamicallyAccessedMembers` annotations are automatically applied to the generated members. This allows trimming tools to directly use the annotations present in the generated code, without needing to reverse-engineer the mapping to user code. + +### .NET 10 and later + +For .NET 10 and later, trimming tools should rely on the compiler to propagate attributes such as `DynamicallyAccessedMembersAttribute` to all relevant compiler-generated code, as indicated by `[CompilerLoweringPreserve]`. No heuristics are needed for these assemblies. This isn't perfect because it's possible for such assemblies to be compiled with new Roslyn versions that could use different lowering strategies, so it's possible that the existing heuristics will break for new releases of a pre-`net10.0` assembly. + +To mitigate this there are a few options: + +1. Multitarget the library to `net10.0` (so that it is built with the new `CompilerLoweringPreserve` behavior and will avoid the heuristics) +2. Fix the heuristics to work for code produced by new Roslyn versions +3. The trimming tools could detect the presence of a polyfilled `DynamicallyAccessedMembersAttribute` type with `CompilerLoweringPreserve`. When present this would turn off the heuristics for the containing assembly. + +Another issue is that .NET 10 libraries might be built with `false`, and the tooling would not be able to detect the TargetFramework. Aside from setting `true`, mitigations 1. and 2. above would also apply to this scenario. + ### Compiler dependent behavior Since the problems are all caused by compiler generated code, the behaviors depend on the specific compiler in use. The main focus of this document is the Roslyn C# compiler right now. Mainly since it's by far the most used compiler for .NET code. That said, we would like to design the solution in such a way that other compilers using similar patterns could also benefit from it. @@ -560,9 +578,9 @@ and fields on the closure types. ### Long term solution Detecting which compiler generated items are used by any given user method is currently relatively tricky. -There's no definitive marker in the IL which would let the trimmer confidently determine this information. -Good long term solution will need the compilers to produce some kind of marker in the IL so that -static analysis tools can reliably detect all of the compiler generated items. +There's no definitive marker in the IL which would let the trimmer confidently determine this information +for all of the above cases. Good long term solution will need the compilers to produce some kind of marker +in the IL so that static analysis tools can reliably detect all of the compiler generated items. This ask can be described as: For a given user method, ability to determine all of the items (methods, fields, types, IL code) which were @@ -573,6 +591,10 @@ helpers and other infrastructure which may be needed but is not directly attribu This should be enough to implement solutions for both suppression propagation and data flow analysis. +For `DynamicallyAccessedMembersAttribute`, we have a long-term solution that relies on the +`[CompilerLoweringPreserve]` attribute, which tells Roslyn to propagate `DynamicallyAccessedMembers` +annotations to compiler-generated code. + ### Possible short term solution #### Heuristic based solution diff --git a/docs/project/list-of-diagnostics.md b/docs/project/list-of-diagnostics.md index 0b3da600c53b13..bb6a670802c733 100644 --- a/docs/project/list-of-diagnostics.md +++ b/docs/project/list-of-diagnostics.md @@ -116,6 +116,7 @@ The PR that reveals the implementation of the ` are obsolete. Use the new ones that take an IComparer\. | +| __`SYSLIB0062`__ | XSLT Script blocks are not supported. | ## Analyzer Warnings @@ -296,7 +297,7 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL APIs can be marked as `[Experimental]` if their shape or functionality is included in a release but not yet officially supported. Experimental APIs offer the opportunity to collect customer feedback on these APIs in a major release, usually refining the APIs and removing the `[Experimental]` attribute in the next release. The `[Experimental]` attribute differs from `[RequiresPreviewFeatures]`, wherein: * `[RequiresPreviewFeatures]` APIs require a corresponding preview feature in another product area such as the compiler or SDK - - Using these APIs requires enabling preview features for the the project and all its consumers + - Using these APIs requires enabling preview features for the project and all its consumers * `[Experimental]` APIs are self-contained within the libraries and do not require preview features in other parts of the product - These APIs can be used by suppressing specific diagnostics without enabling preview features for the project diff --git a/docs/workflow/building/coreclr/android.md b/docs/workflow/building/coreclr/android.md index 3a6769d062acdc..473ee4a2b05a09 100644 --- a/docs/workflow/building/coreclr/android.md +++ b/docs/workflow/building/coreclr/android.md @@ -1,23 +1,29 @@ # Experimental support of CoreCLR on Android -This is the internal documentation which outlines experimental support of CoreCLR on Android and includes instructions on how to: -- [Build CoreCLR for Android](./android.md#building-coreclr-for-android) -- [Build and run a sample application with CoreCLR](./android.md#building-and-running-a-sample-app) -- [Debug the sample app and the runtime](./android.md#debugging-the-runtime-and-the-sample-app) - -## Prerequisite - -- Download and install [OpenJDK 23](https://openjdk.org/projects/jdk/23/) -- Download and install [Android Studio](https://developer.android.com/studio/install) and the following: - - Android SDK (minimum supported API level is 21) - - Android NDK r27 - -> [!NOTE] -> Prerequisites can also be downloaded and installed manually: -> - by running the automated script as described in [Testing Libraries on Android](../../testing/libraries/testing-android.md#using-a-terminal) -> - by downloading the archives: -> - Android SDK - Download [command-line tools](https://developer.android.com/studio#command-line-tools-only) and use `sdkmanager` to download the SDK. -> - Android NDK - Download [NDK](https://developer.android.com/ndk/downloads) +This is the internal documentation which outlines experimental support of CoreCLR on Android. + +## Table of Contents + +- [Prerequisite](#prerequisite) +- [Building CoreCLR for Android](#building-coreclr-for-android) + - [MacOS and Linux](#macos-and-linux) + - [Requirements](#requirements) + - [Building the runtime, libraries and tools](#building-the-runtime-libraries-and-tools) + - [Windows + WSL2](#windows--wsl2) + - [Windows requirements](#windows-requirements) + - [WSL requirements](#wsl-requirements) + - [Building the runtime, libraries and tools](#building-the-runtime-libraries-and-tools-1) +- [Building and running a sample app](#building-and-running-a-sample-app) + - [Building HelloAndroid sample](#building-helloandroid-sample) + - [Running HelloAndroid sample on an emulator](#running-helloandroid-sample-on-an-emulator) + - [WSL2](#wsl2) +- [Building and running tests on an emulator](#building-and-running-tests-on-an-emulator) +- [Debugging the runtime and the sample app](#debugging-the-runtime-and-the-sample-app) + - [Steps](#steps) +- [See also](#see-also) +- [Troubleshooting](#troubleshooting) + - [Android samples or functional tests fail to build](#android-samples-or-functional-tests-fail-to-build) + - [java.lang.NullPointerException: Cannot invoke String.length()](#javalangnullpointerexception-cannot-invoke-stringlength) ## Building CoreCLR for Android @@ -34,11 +40,23 @@ Supported target architectures: ### MacOS and Linux -#### Requirements +#### Prerequisites + +- Download and install [OpenJDK 23](https://openjdk.org/projects/jdk/23/) +- Download and install [Android Studio](https://developer.android.com/studio/install) and the following: + - Android SDK (minimum supported API level is 21) + - Android NDK r27c + +> [!NOTE] +> Prerequisites can also be downloaded and installed manually: +> - An automated script as described in [Testing Libraries on Android](../../testing/libraries/testing-android.md#using-a-terminal) +> - Downloading the archives: +> - Android SDK - Download [command-line tools](https://developer.android.com/studio#command-line-tools-only) and use `sdkmanager` to download the SDK. +> - Android NDK - Download [NDK](https://developer.android.com/ndk/downloads) Set the following environment variables: - - ANDROID_SDK_ROOT=`` - - ANDROID_NDK_ROOT=`` + - `export ANDROID_SDK_ROOT=` + - `export ANDROID_NDK_ROOT=` #### Building the runtime, libraries and tools @@ -57,22 +75,32 @@ To build CoreCLR runtime NuGet packages, run the following command from ` [!NOTE] > The runtime packages will be located at: `/artifacts/packages//Shipping/` -### Windows +### Windows + WSL2 Building on Windows is not directly supported yet. However it is possible to use WSL2 for this purpose. -#### WSL2 +#### Windows prerequisites + +- Download and install [Android Studio](https://developer.android.com/studio/install) +- Enable [long paths](../../requirements/windows-requirements.md#enable-long-paths) -##### Requirements +#### WSL prerequisites -1. Install the Android SDK and NDK in WSL per the [prerequisites](#prerequisite). This can be done by downloading the archives or using Android Studio. +1. Follow [linux-requirements.md](../../requirements/linux-requirements.md). +2. Install OpenJDK, Android SDK and Android NDK in as described in [Linux prerequisites](#prerequisites). There is a convenient automated script, but it can also be done manually by downloading the archives or using Android Studio. - In case of Android Studio: - Make sure WSL is updated: from Windows host, `wsl --update` - [Enabled systemd](https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/#set-the-systemd-flag-set-in-your-wsl-distro-settings) - `sudo snap install android-studio --classic` -2. Set the following environment variables: - - ANDROID_SDK_ROOT=`` - - ANDROID_NDK_ROOT=`` +- For Ubuntu, OpenJDK 21 is sufficient: + +``` +apt install openjdk-21-jdk +``` + +3. Set the following environment variables: + - `export ANDROID_SDK_ROOT=` + - `export ANDROID_NDK_ROOT=` #### Building the runtime, libraries and tools @@ -84,9 +112,7 @@ To build CoreCLR runtime, libraries and tools, run the following command from `< ## Building and running a sample app -To demonstrate building and running an Android sample application with CoreCLR, we will use: -- the [HelloAndroid sample app](../../../../src/mono/sample/Android/AndroidSampleApp.csproj). -- a functional tests [Android.Device_Emulator.JIT.Test](../../../../src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj) +To demonstrate building and running an Android application with CoreCLR, we will use the [HelloAndroid sample app](../../../../src/mono/sample/Android/AndroidSampleApp.csproj). A prerequisite for building and running samples locally is to have CoreCLR successfully built for desired Android platform. @@ -128,30 +154,24 @@ The app can be run on an emulator running on the Windows host. 2. In Windows, create and start an emulator 3. In WSL, swap the `adb` from the Android SDK in WSL2 with that from Windows - `mv $ANDROID_SDK_ROOT/platform-tools/adb $ANDROID_SDK_ROOT/platform-tools/adb-orig` - - `ln -s /mnt/ $ANDROID_SDK_ROOT/platform-tools/adb` + - `ln -s /mnt//platform-tools/adb.exe $ANDROID_SDK_ROOT/platform-tools/adb` + - On Windows host, you can find the SDK location in Android Studio's SDK Manager. 4. In WSL, Make xharness use the `adb` corresponding to the Windows host: - `export ADB_EXE_PATH=$ANDROID_SDK_ROOT/platform-tools/adb` 5. In WSL, run the `make` command as [above](#running-helloandroid-sample-on-an-emulator) -### Building and running functional tests on an emulator +## Building and running tests on an emulator -Similarly to the `HelloAndroid` sample, it is possible to build and run a functional test on Android with CoreCLR on an emulator. +To demonstrate building and running tests on CoreCLR Android, we will use the [Android.Device_Emulator.JIT.Test](../../../../src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj) test project. -To build and run a functional test on Android with CoreCLR, run the following command from ``: +To build and run the test on Android with CoreCLR, run the following command from ``: ``` -./dotnet.sh build -c Release src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj /p:TargetOS=android /p:TargetArchitecture=arm64 /t:Test /p:RuntimeFlavor=coreclr +./dotnet.sh build -c src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj /p:TargetOS=android /p:TargetArchitecture= /t:Test /p:RuntimeFlavor=coreclr ``` > [!NOTE] -> Similarly to the `HelloAndroid` sample the emulator needs to be up and running. - -### Useful make commands - -For convenience it is possible to run a single make command which builds all required dependencies, the app and runs it: -``` -make BUILD_CONFIG= TARGET_ARCH= RUNTIME_FLAVOR=CoreCLR DEPLOY_AND_RUN=true all -C src/mono/sample/Android -``` +> Similarly to the `HelloAndroid` sample, the emulator needs to be up and running. ## Debugging the runtime and the sample app @@ -191,6 +211,8 @@ Similar instructions for debugging Android apps with Mono runtime can be found [ ### Android samples or functional tests fail to build +#### java.lang.NullPointerException: Cannot invoke String.length() + If multiple JDKs are installed on your system, you may encounter the following error: ``` diff --git a/docs/workflow/requirements/linux-requirements.md b/docs/workflow/requirements/linux-requirements.md index cb22d31172780a..c2831776940417 100644 --- a/docs/workflow/requirements/linux-requirements.md +++ b/docs/workflow/requirements/linux-requirements.md @@ -95,6 +95,10 @@ If you're planning to use your environment to do Linux cross-building to other a - `qemu` - `qemu-user-static` +```bash +apt install binfmt-support debootstrap qemu qemu-user-static +``` + ### Fedora These instructions are written assuming *Fedora 40*. diff --git a/docs/workflow/requirements/macos-requirements.md b/docs/workflow/requirements/macos-requirements.md index 67e7840a64d1be..cd1aed4b8f142b 100644 --- a/docs/workflow/requirements/macos-requirements.md +++ b/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/docs/workflow/requirements/windows-requirements.md b/docs/workflow/requirements/windows-requirements.md index aa2c54c3976a18..922824f274bb9f 100644 --- a/docs/workflow/requirements/windows-requirements.md +++ b/docs/workflow/requirements/windows-requirements.md @@ -46,9 +46,9 @@ It is highly recommended to use the *Workloads* approach, as that installs the f - .NET desktop development - Desktop development with C++ -To build the tests and do ARM32/ARM64 development, you'll need some additional components. You can find them by clicking on the *Individual components* tab in the *Visual Studio Installer*: +To build the tests and do ARM64 development, you'll need some additional components. You can find them by clicking on the *Individual components* tab in the *Visual Studio Installer*: -- For ARM stuff: *MSVC v143 - VS 2022 C++ ARM64/ARM64EC build tools (Latest)* for Arm64, and *MSVC v143 - VS 2022 C++ ARM build tools (Latest)* for Arm32. +- For Arm64: *MSVC v143 - VS 2022 C++ ARM64/ARM64EC build tools (Latest)* - For building tests: *C++/CLI support for v143 build tools (Latest)* Alternatively, there is also a `.vsconfig` file included at the root of the runtime repo. It includes all the necessary components required, outlined in a JSON format that Visual Studio can read and parse. You can boot up Visual Studio directly and [import this `.vsconfig` file](https://learn.microsoft.com/visualstudio/install/import-export-installation-configurations?view=vs-2022#import-a-configuration) instead of installing the workloads yourself. It is worth mentioning however, that while we are very careful in maintaining this file up-to-date, sometimes it might get a tad obsolete and miss important components. So, it is always a good idea to double check that the full workloads are installed. diff --git a/docs/workflow/testing/coreclr/running-arm32-tests.md b/docs/workflow/testing/coreclr/running-arm32-tests.md new file mode 100644 index 00000000000000..c7bac99960c921 --- /dev/null +++ b/docs/workflow/testing/coreclr/running-arm32-tests.md @@ -0,0 +1,36 @@ +# Running ARM32 tests on modern hardware + +One of our supported targets is 32-bit ARM. It can be quite challenging to construct a realistic ARM32 environment where you can build or run tests in a reasonable amount of time. Thankfully, it's possible to configure an ARM64 linux environment so that you can cross-build from ARM64 to ARM32, and run tests there using native hardware support instead of software emulation. This is not possible on ARM64-based Windows (this functionality is not offered by the OS). + +## Configuring your ARM64 environment to run ARM32 binaries + +By default your ARM64 Linux install probably doesn't have support for ARM32 binaries enabled, which will cause running the binaries to fail with a cryptic error. So you'll need to add the architecture to dpkg and install some core userspace libraries that CoreCLR will need to actually run your tests, which on Debian or Ubuntu will look like: + +```bash +$ sudo dpkg --add-architecture armhf + +$ sudo apt-get update +Reading package lists... Done + +$ sudo apt-get install libc6:armhf libstdc++6:armhf libicu74:armhf +The following additional packages will be installed: +``` + +Note that when installing a package for another architecture, you need to suffix the package name with the architecture name. For me, the three packages above were sufficient to run an ARM32 JIT test. + +## Cross-building for ARM32 on ARM64 + +Follow the steps from https://github.com/dotnet/runtime/blob/main/docs/workflow/building/coreclr/cross-building.md#linux-cross-building as-is. You should end up with a `linux.arm` `Core_Root` and test artifacts. + +## Running an ARM32 test in your ARM64 environment + +We're finally ready to go, probably. Export an environment variable to point to your ARM32 core root, and then run your test, i.e.: + +```bash +$ export CORE_ROOT=/home/kg/runtime/artifacts/tests/coreclr/linux.arm.Release/Tests/Core_Root/ + +$ bash artifacts/tests/coreclr/linux.arm.Release/JIT/Directed/StructABI/StructABI/StructABI.sh +BEGIN EXECUTION +/home/kg/runtime/artifacts/tests/coreclr/linux.arm.Release/Tests/Core_Root//corerun -p System.Reflection.Metadata.MetadataUpdater.IsSupported=false -p System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization=true StructABI.dll '' +Issue80393_HFA failed. Retval: f1=1 f3=3 +``` diff --git a/docs/workflow/testing/libraries/testing-android.md b/docs/workflow/testing/libraries/testing-android.md index 9b138a0b61b5b1..1afa6786c46199 100644 --- a/docs/workflow/testing/libraries/testing-android.md +++ b/docs/workflow/testing/libraries/testing-android.md @@ -23,9 +23,9 @@ Android SDK and NDK can be automatically installed via the following script: set -e NDK_VER=r27c -SDK_VER=9123335_latest -SDK_API_LEVEL=33 -SDK_BUILD_TOOLS=33.0.1 +ANDROID_CLI_TOOLS_VER=13114758_latest +SDK_API_LEVEL=36 +SDK_BUILD_TOOLS=36.0.0 if [[ "$OSTYPE" == "darwin"* ]]; then HOST_OS=darwin @@ -45,7 +45,7 @@ unzip ~/andk.zip -d $(dirname ${ANDROID_NDK_ROOT}) && rm -rf ~/andk.zip # download Android SDK, accept licenses and download additional packages such as # platform-tools, platforms and build-tools export ANDROID_SDK_ROOT=~/android-sdk -curl https://dl.google.com/android/repository/commandlinetools-${HOST_OS_SHORT}-${SDK_VER}.zip -L --output ~/asdk.zip +curl https://dl.google.com/android/repository/commandlinetools-${HOST_OS_SHORT}-${ANDROID_CLI_TOOLS_VER}.zip -L --output ~/asdk.zip mkdir ${ANDROID_SDK_ROOT} && unzip ~/asdk.zip -d ${ANDROID_SDK_ROOT}/cmdline-tools && rm -rf ~/asdk.zip yes | ${ANDROID_SDK_ROOT}/cmdline-tools/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_SDK_ROOT} --licenses ${ANDROID_SDK_ROOT}/cmdline-tools/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_SDK_ROOT} "platform-tools" "platforms;android-${SDK_API_LEVEL}" "build-tools;${SDK_BUILD_TOOLS}" diff --git a/docs/workflow/testing/using-dev-shipping-packages.md b/docs/workflow/testing/using-dev-shipping-packages.md index d09bd7b27f6fbd..2c90c1e0118a6e 100644 --- a/docs/workflow/testing/using-dev-shipping-packages.md +++ b/docs/workflow/testing/using-dev-shipping-packages.md @@ -118,11 +118,9 @@ Console.WriteLine($"The location of System.Private.CoreLib.dll is '{typeof(objec The following command will build and publish your app: ```cmd -dotnet publish -r win-x64 +dotnet publish --self-contained ``` -Adjust the `win-x64` to match your machine's OS and architecture. - Running this little app should yield an output like the following: ```text diff --git a/eng/SignCheckExclusionsFile.txt b/eng/SignCheckExclusionsFile.txt deleted file mode 100644 index f41753338155eb..00000000000000 --- a/eng/SignCheckExclusionsFile.txt +++ /dev/null @@ -1,15 +0,0 @@ -;; Exclusions for SignCheck. Corresponds to info in Signing.props. -;; Format: https://github.com/dotnet/arcade/blob/397316e195639450b6c76bfeb9823b40bee72d6d/src/SignCheck/Microsoft.SignCheck/Verification/Exclusion.cs#L23-L35 -;; -;; This issue tracks a way to implement exclusions via Signing.props and avoid this extra file: https://github.com/dotnet/arcade/issues/2888 - -;; The apphost and comhost are template files, modified by the SDK to produce the executable for FDE -;; and SCD apps. If they are signed, the file that the SDK produces has an invalid signature and -;; can't be signed again. More info at https://github.com/dotnet/core-setup/pull/7549. -*apphost.exe;;Template, DO-NOT-SIGN, https://github.com/dotnet/core-setup/pull/7549 -*singlefilehost.exe;;Template, DO-NOT-SIGN, https://github.com/dotnet/core-setup/pull/7549 -*comhost.dll;;Template, DO-NOT-SIGN, https://github.com/dotnet/core-setup/pull/7549 -*apphosttemplateapphostexe.exe;;Template, DO-NOT-SIGN, https://github.com/dotnet/core-setup/pull/7549 -*comhosttemplatecomhostdll.dll;;Template, DO-NOT-SIGN, https://github.com/dotnet/core-setup/pull/7549 -*staticapphosttemplateapphostexe.exe;;Template, DO-NOT-SIGN, https://github.com/dotnet/core-setup/pull/7549 -*dotnet.js;;Workaround, https://github.com/dotnet/core-eng/issues/9933 \ No newline at end of file diff --git a/eng/Subsets.props b/eng/Subsets.props index c0d6664a1fc7d4..5770eec315eb4d 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -47,7 +47,7 @@ true - <_NativeAotSupportedOS Condition="'$(TargetOS)' == 'windows' or '$(TargetOS)' == 'linux' or '$(TargetOS)' == 'osx' or '$(TargetOS)' == 'maccatalyst' or '$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvossimulator' or '$(TargetOS)' == 'tvos' or '$(TargetOS)' == 'freebsd'">true + <_NativeAotSupportedOS Condition="'$(TargetOS)' != 'browser' and '$(TargetOS)' != 'haiku' and '$(TargetOS)' != 'illumos' and '$(TargetOS)' != 'netbsd' and '$(TargetOS)' != 'solaris'">true <_NativeAotSupportedArch Condition="'$(TargetArchitecture)' == 'x64' or '$(TargetArchitecture)' == 'arm64' or '$(TargetArchitecture)' == 'arm' or '$(TargetArchitecture)' == 'loongarch64' or '$(TargetArchitecture)' == 'riscv64' or ('$(TargetOS)' == 'windows' and '$(TargetArchitecture)' == 'x86')">true true @@ -71,6 +71,7 @@ clr+mono+libs+tools+host+packs mono+libs+packs clr+mono+libs+host+packs + clr.nativeaotruntime+clr.nativeaotlibs+mono+libs+packs clr.nativeaotruntime+clr.nativeaotlibs+mono+libs+packs clr.nativeaotruntime+clr.nativeaotlibs+mono+libs+host+packs clr.nativeaotruntime+clr.nativeaotlibs+libs+packs @@ -153,9 +154,21 @@ $(BootstrapSubsets)+clr.nativeaotlibs+clr.nativeaotruntime+libs.native true + + + clr.nativeprereqs+clr.iltools+clr.runtime+clr.native+clr.aot+clr.nativeaotlibs+clr.nativeaotruntime+clr.crossarchtools + $(AllSubsetsExpansion)+clr.paltests+clr.paltestlist+clr.hosts+clr.jit+clr.alljits+clr.alljitscommunity+clr.spmi+clr.corelib+clr.nativecorelib+clr.tools+clr.toolstests+clr.packages + $(AllSubsetsExpansion)+linuxdac+alpinedac + $(AllSubsetsExpansion)+mono.runtime+mono.emsdk+mono.aotcross+mono.corelib+mono.manifests+mono.packages+mono.tools+mono.wasmruntime+mono.wasiruntime+mono.wasmworkload+mono.mscordbi+mono.workloads + $(AllSubsetsExpansion)+tools.illink+tools.cdac+tools.illinktests+tools.cdactests + $(AllSubsetsExpansion)+host.native+host.pkg+host.tools+host.pretest+host.tests + $(AllSubsetsExpansion)+libs.native+libs.sfx+libs.oob+libs.pretest+libs.tests + $(AllSubsetsExpansion)+packs.product+packs.installers+packs.tests + $(AllSubsetsExpansion)+regeneratedownloadtable+regeneratethirdpartynotices+tasks + <_subset>$(_subset.Replace('+allsubsets+', '+$(AllSubsetsExpansion)+')) <_subset>$(_subset.Replace('+clr.paltests+', '+clr.paltests+clr.paltestlist+')) <_subset>$(_subset.Replace('+clr+', '+$(DefaultCoreClrSubsets)+')) <_subset>$(_subset.Replace('+clr.aot+', '+$(DefaultNativeAotSubsets)+')) @@ -264,6 +277,9 @@ + + + @@ -640,8 +656,9 @@ <_BuildCoreCLRRuntimePack Condition="'$(RuntimeFlavor)' == 'CoreCLR' and '$(CoreCLRSupported)' == 'true'">true <_BuildMonoRuntimePack Condition="'$(RuntimeFlavor)' == 'Mono' and '$(MonoSupported)' == 'true'">true <_BuildHostPack Condition="'$(RuntimeFlavor)' == '$(PrimaryRuntimeFlavor)' and '$(TargetsMobile)' != 'true'">true - <_BuildCdacPack Condition="'$(_CDacToolsBuilt)' == 'true' and '$(RuntimeFlavor)' == 'CoreCLR' and '$(TargetsMobile)' != 'true' and '$(TargetsLinuxMusl)' != 'true' and ('$(TargetOS)' == 'windows' or '$(TargetOS)' == 'osx' or '$(TargetOS)' == 'linux')">true - <_BuildCdacPack Condition="'$(DotNetBuildSourceOnly)' == 'true' or '$(TargetArchitecture)' == 'arm' or '$(TargetArchitecture)' == 'armel' or '$(TargetArchitecture)' == 'x86' or '$(TargetArchitecture)' == 'riscv64'">false + <_BuildCdacPack Condition="'$(_CDacToolsBuilt)' == 'true' and '$(RuntimeFlavor)' == 'CoreCLR' and '$(TargetsMobile)' != 'true' and ('$(TargetOS)' == 'windows' or '$(TargetOS)' == 'osx' or '$(TargetOS)' == 'linux')">true + + <_BuildCdacPack Condition="'$(DotNetBuildSourceOnly)' == 'true' or '$(TargetsLinuxMusl)' == 'true'">false <_BuildBundle Condition="'$(RuntimeFlavor)' == '$(PrimaryRuntimeFlavor)' and '$(TargetsMobile)' != 'true'">true diff --git a/eng/Version.Details.props b/eng/Version.Details.props new file mode 100644 index 00000000000000..eebe1bbe032748 --- /dev/null +++ b/eng/Version.Details.props @@ -0,0 +1,237 @@ + + + + + + 10.0.0-preview.6.25302.1 + + 4.9.0-rc2.21473.1 + + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + 19.1.0-alpha.1.25167.1 + + 5.0.0-2.25418.105 + 5.0.0-2.25418.105 + 5.0.0-2.25418.105 + 10.0.0-preview.25418.105 + 10.0.100-rc.1.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 0.11.5-alpha.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 10.0.0-beta.25418.105 + 2.9.3-beta.25418.105 + 2.9.3-beta.25418.105 + 10.0.0-beta.25418.105 + 5.0.0-2.25418.105 + 10.0.0-rc.1.25418.105 + 10.0.100-rc.1.25418.105 + 10.0.0-rc.1.25418.105 + 10.0.0-rc.1.25418.105 + 7.0.0-preview.1.41905 + 7.0.0-preview.1.41905 + 7.0.0-preview.1.41905 + 7.0.0-preview.1.41905 + 10.0.0-rc.1.25418.105 + 2.0.0-rc.1.25418.105 + 10.0.0-rc.1.25418.105 + 10.0.0-rc.1.25418.105 + 10.0.0-rc.1.25418.105 + + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + 10.0.0-beta.25310.1 + + 10.0.0-prerelease.25405.1 + 10.0.0-prerelease.25405.1 + 10.0.0-prerelease.25405.1 + + 1.0.0-prerelease.25413.5 + 1.0.0-prerelease.25413.5 + 1.0.0-prerelease.25413.5 + 1.0.0-prerelease.25413.5 + 1.0.0-prerelease.25413.5 + 1.0.0-prerelease.25413.5 + + 10.0.0-alpha.0.25302.2 + + 10.0.0-alpha.1.25169.1 + 10.0.0-alpha.1.25169.1 + 10.0.0-alpha.1.25169.1 + 10.0.0-alpha.1.25169.1 + 10.0.0-alpha.1.25169.1 + 10.0.0-alpha.1.25169.1 + 10.0.0-alpha.1.25169.1 + 10.0.0-alpha.1.25169.1 + + + + + $(MicrosoftNETCoreRuntimeICUTransportPackageVersion) + + $(SystemServiceModelPrimitivesPackageVersion) + + $(runtimelinuxarm64MicrosoftNETCoreRuntimeJITToolsPackageVersion) + $(runtimelinuxarm64MicrosoftNETCoreRuntimeMonoLLVMLibclangPackageVersion) + $(runtimelinuxarm64MicrosoftNETCoreRuntimeMonoLLVMSdkPackageVersion) + $(runtimelinuxarm64MicrosoftNETCoreRuntimeMonoLLVMToolsPackageVersion) + $(runtimelinuxmuslarm64MicrosoftNETCoreRuntimeJITToolsPackageVersion) + $(runtimelinuxmuslarm64MicrosoftNETCoreRuntimeMonoLLVMLibclangPackageVersion) + $(runtimelinuxmuslarm64MicrosoftNETCoreRuntimeMonoLLVMSdkPackageVersion) + $(runtimelinuxmuslarm64MicrosoftNETCoreRuntimeMonoLLVMToolsPackageVersion) + $(runtimelinuxmuslx64MicrosoftNETCoreRuntimeJITToolsPackageVersion) + $(runtimelinuxmuslx64MicrosoftNETCoreRuntimeMonoLLVMLibclangPackageVersion) + $(runtimelinuxmuslx64MicrosoftNETCoreRuntimeMonoLLVMSdkPackageVersion) + $(runtimelinuxmuslx64MicrosoftNETCoreRuntimeMonoLLVMToolsPackageVersion) + $(runtimelinuxx64MicrosoftNETCoreRuntimeJITToolsPackageVersion) + $(runtimelinuxx64MicrosoftNETCoreRuntimeMonoLLVMLibclangPackageVersion) + $(runtimelinuxx64MicrosoftNETCoreRuntimeMonoLLVMSdkPackageVersion) + $(runtimelinuxx64MicrosoftNETCoreRuntimeMonoLLVMToolsPackageVersion) + $(runtimeosxarm64MicrosoftNETCoreRuntimeJITToolsPackageVersion) + $(runtimeosxarm64MicrosoftNETCoreRuntimeMonoLLVMLibclangPackageVersion) + $(runtimeosxarm64MicrosoftNETCoreRuntimeMonoLLVMSdkPackageVersion) + $(runtimeosxarm64MicrosoftNETCoreRuntimeMonoLLVMToolsPackageVersion) + $(runtimeosxx64MicrosoftNETCoreRuntimeJITToolsPackageVersion) + $(runtimeosxx64MicrosoftNETCoreRuntimeMonoLLVMLibclangPackageVersion) + $(runtimeosxx64MicrosoftNETCoreRuntimeMonoLLVMSdkPackageVersion) + $(runtimeosxx64MicrosoftNETCoreRuntimeMonoLLVMToolsPackageVersion) + $(runtimewinarm64MicrosoftNETCoreRuntimeJITToolsPackageVersion) + $(runtimewinx64MicrosoftNETCoreRuntimeJITToolsPackageVersion) + $(runtimewinx64MicrosoftNETCoreRuntimeMonoLLVMLibclangPackageVersion) + $(runtimewinx64MicrosoftNETCoreRuntimeMonoLLVMSdkPackageVersion) + $(runtimewinx64MicrosoftNETCoreRuntimeMonoLLVMToolsPackageVersion) + + $(MicrosoftCodeAnalysisPackageVersion) + $(MicrosoftCodeAnalysisAnalyzersPackageVersion) + $(MicrosoftCodeAnalysisCSharpPackageVersion) + $(MicrosoftCodeAnalysisNetAnalyzersPackageVersion) + $(MicrosoftDotNetApiCompatTaskPackageVersion) + $(MicrosoftDotNetArcadeSdkPackageVersion) + $(MicrosoftDotNetBuildTasksArchivesPackageVersion) + $(MicrosoftDotNetBuildTasksFeedPackageVersion) + $(MicrosoftDotNetBuildTasksInstallersPackageVersion) + $(MicrosoftDotNetBuildTasksPackagingPackageVersion) + $(MicrosoftDotNetBuildTasksTargetFrameworkPackageVersion) + $(MicrosoftDotNetBuildTasksTemplatingPackageVersion) + $(MicrosoftDotNetBuildTasksWorkloadsPackageVersion) + $(MicrosoftDotNetCecilPackageVersion) + $(MicrosoftDotNetCodeAnalysisPackageVersion) + $(MicrosoftDotNetGenAPIPackageVersion) + $(MicrosoftDotNetGenFacadesPackageVersion) + $(MicrosoftDotNetHelixSdkPackageVersion) + $(MicrosoftDotNetPackageTestingPackageVersion) + $(MicrosoftDotNetRemoteExecutorPackageVersion) + $(MicrosoftDotNetSharedFrameworkSdkPackageVersion) + $(MicrosoftDotNetXliffTasksPackageVersion) + $(MicrosoftDotNetXUnitAssertPackageVersion) + $(MicrosoftDotNetXUnitConsoleRunnerPackageVersion) + $(MicrosoftDotNetXUnitExtensionsPackageVersion) + $(MicrosoftNetCompilersToolsetPackageVersion) + $(MicrosoftNETSdkILPackageVersion) + $(MicrosoftNETWorkloadEmscriptenCurrentManifest100100TransportPackageVersion) + $(MicrosoftNETCoreAppRefPackageVersion) + $(MicrosoftNETCoreILAsmPackageVersion) + $(NuGetFrameworksPackageVersion) + $(NuGetPackagingPackageVersion) + $(NuGetProjectModelPackageVersion) + $(NuGetVersioningPackageVersion) + $(runtimenativeSystemIOPortsPackageVersion) + $(SystemCommandLinePackageVersion) + $(SystemReflectionMetadataPackageVersion) + $(SystemReflectionMetadataLoadContextPackageVersion) + $(SystemTextJsonPackageVersion) + + $(MicrosoftDotNetCilStripSourcesPackageVersion) + $(MicrosoftNETHostModelTestDataPackageVersion) + $(SystemComponentModelTypeConverterTestDataPackageVersion) + $(SystemDataCommonTestDataPackageVersion) + $(SystemDrawingCommonTestDataPackageVersion) + $(SystemFormatsTarTestDataPackageVersion) + $(SystemIOCompressionTestDataPackageVersion) + $(SystemIOPackagingTestDataPackageVersion) + $(SystemNetTestDataPackageVersion) + $(SystemPrivateRuntimeUnicodeDataPackageVersion) + $(SystemRuntimeNumericsTestDataPackageVersion) + $(SystemRuntimeTimeZoneDataPackageVersion) + $(SystemSecurityCryptographyX509CertificatesTestDataPackageVersion) + $(SystemTextRegularExpressionsTestDataPackageVersion) + $(SystemWindowsExtensionsTestDataPackageVersion) + + $(MicrosoftDotNetXHarnessCLIPackageVersion) + $(MicrosoftDotNetXHarnessTestRunnersCommonPackageVersion) + $(MicrosoftDotNetXHarnessTestRunnersXunitPackageVersion) + + $(optimizationlinuxarm64MIBCRuntimePackageVersion) + $(optimizationlinuxx64MIBCRuntimePackageVersion) + $(optimizationPGOCoreCLRPackageVersion) + $(optimizationwindows_ntarm64MIBCRuntimePackageVersion) + $(optimizationwindows_ntx64MIBCRuntimePackageVersion) + $(optimizationwindows_ntx86MIBCRuntimePackageVersion) + + $(MicrosoftDotNetHotReloadUtilsGeneratorBuildToolPackageVersion) + + $(runtimelinuxarm64MicrosoftNETCoreRuntimeWasmNodeTransportPackageVersion) + $(runtimelinuxmuslarm64MicrosoftNETCoreRuntimeWasmNodeTransportPackageVersion) + $(runtimelinuxmuslx64MicrosoftNETCoreRuntimeWasmNodeTransportPackageVersion) + $(runtimelinuxx64MicrosoftNETCoreRuntimeWasmNodeTransportPackageVersion) + $(runtimeosxarm64MicrosoftNETCoreRuntimeWasmNodeTransportPackageVersion) + $(runtimeosxx64MicrosoftNETCoreRuntimeWasmNodeTransportPackageVersion) + $(runtimewinarm64MicrosoftNETCoreRuntimeWasmNodeTransportPackageVersion) + $(runtimewinx64MicrosoftNETCoreRuntimeWasmNodeTransportPackageVersion) + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cc791158eb2c5c..2ea152526c443f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,5 +1,5 @@ - + https://github.com/dotnet/icu @@ -41,91 +41,91 @@ https://github.com/dotnet/llvm-project da5dd054a531e6fea65643b7e754285b73eab433 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 https://github.com/dotnet/runtime-assets @@ -263,65 +263,65 @@ https://github.com/dotnet/llvm-project da5dd054a531e6fea65643b7e754285b73eab433 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/xharness - e85bb14e85357ab678c2bcb0b6f2bac634fdd49b + 4c17e23fcb7575baa9de575e5a96258096cbaea1 - + https://github.com/dotnet/xharness - e85bb14e85357ab678c2bcb0b6f2bac634fdd49b + 4c17e23fcb7575baa9de575e5a96258096cbaea1 - + https://github.com/dotnet/xharness - e85bb14e85357ab678c2bcb0b6f2bac634fdd49b + 4c17e23fcb7575baa9de575e5a96258096cbaea1 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - a68196f69e40740fce716778138acaa26488b333 + e7f12ca10fc5b13e4ebc33244b585081da7f8bfb - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - a68196f69e40740fce716778138acaa26488b333 + e7f12ca10fc5b13e4ebc33244b585081da7f8bfb - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - a68196f69e40740fce716778138acaa26488b333 + e7f12ca10fc5b13e4ebc33244b585081da7f8bfb - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - a68196f69e40740fce716778138acaa26488b333 + e7f12ca10fc5b13e4ebc33244b585081da7f8bfb https://github.com/dotnet/hotreload-utils @@ -331,55 +331,55 @@ https://github.com/dotnet/runtime-assets 385d085eb055cabeaed3dde958a900e7b31cf6ce - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 5c3434d8b831745673c31e186906f463e1036301 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - a68196f69e40740fce716778138acaa26488b333 + e7f12ca10fc5b13e4ebc33244b585081da7f8bfb - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - a68196f69e40740fce716778138acaa26488b333 + e7f12ca10fc5b13e4ebc33244b585081da7f8bfb - - https://github.com/NuGet/NuGet.Client - 8fef55f5a55a3b4f2c96cd1a9b5ddc51d4b927f8 + + https://github.com/dotnet/dotnet + 5c3434d8b831745673c31e186906f463e1036301 - - https://github.com/NuGet/NuGet.Client - 8fef55f5a55a3b4f2c96cd1a9b5ddc51d4b927f8 + + https://github.com/dotnet/dotnet + 5c3434d8b831745673c31e186906f463e1036301 - - https://github.com/NuGet/NuGet.Client - 8fef55f5a55a3b4f2c96cd1a9b5ddc51d4b927f8 + + https://github.com/dotnet/dotnet + 5c3434d8b831745673c31e186906f463e1036301 - - https://github.com/NuGet/NuGet.Client - 8fef55f5a55a3b4f2c96cd1a9b5ddc51d4b927f8 + + https://github.com/dotnet/dotnet + 5c3434d8b831745673c31e186906f463e1036301 https://github.com/dotnet/node diff --git a/eng/Versions.props b/eng/Versions.props index 414939064fe53a..d61001668130e5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,4 +1,5 @@ + 10.0.0 @@ -11,8 +12,8 @@ 8.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet9)').Build),11)) 7.0.20 6.0.36 - preview - 7 + rc + 1 false release @@ -28,26 +29,11 @@ true true - - true + true - - - 10.0.0-preview.25351.106 - - 5.0.0-1.25351.106 - - 5.0.0-1.25351.106 - 5.0.0-1.25351.106 - 5.0.0-1.25351.106 - - 10.0.100-preview.7.25351.106 - - 10.0.0-beta.25351.106 - 10.0.0-beta.25351.106 - 10.0.0-beta.25351.106 - 10.0.0-beta.25351.106 - 2.9.2-beta.25351.106 - 10.0.0-beta.25351.106 - 2.9.2-beta.25351.106 - 10.0.0-beta.25351.106 - 10.0.0-beta.25351.106 - 10.0.0-beta.25351.106 - 10.0.0-beta.25351.106 - 10.0.0-beta.25351.106 - 10.0.0-beta.25351.106 - 10.0.0-beta.25351.106 - 10.0.0-beta.25351.106 - 10.0.0-beta.25351.106 - - 1.4.0 6.0.0-preview.1.102 - 10.0.0-preview.7.25351.106 6.0.0 - - 10.0.0-preview.7.25351.106 - 10.0.0-preview.7.25351.106 6.0.0 4.6.1 @@ -128,16 +89,12 @@ 8.0.0 8.0.1 5.0.0 - 10.0.0-preview.7.25351.106 - 10.0.0-preview.7.25351.106 6.0.0 5.0.0 5.0.0 5.0.0 7.0.0 - 10.0.0-preview.7.25351.106 7.0.0 - 10.0.0-preview.7.25351.106 8.0.0 4.5.1 @@ -148,39 +105,9 @@ 8.0.0 8.0.0 4.5.4 - - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - 10.0.0-beta.25310.1 - - 10.0.0-prerelease.25255.1 - 10.0.0-prerelease.25255.1 - 10.0.0-prerelease.25255.1 - - 10.0.0-alpha.0.25302.2 - - 1.0.0-prerelease.25256.1 - 1.0.0-prerelease.25256.1 - 1.0.0-prerelease.25256.1 - 1.0.0-prerelease.25256.1 - 1.0.0-prerelease.25256.1 - 1.0.0-prerelease.25256.1 2.0.0 17.10.0-beta1.24272.1 - 2.0.0-beta6.25351.106 3.1.16 2.1.0 2.0.3 @@ -190,10 +117,6 @@ 17.8.3 17.8.3 17.8.3 - 6.2.4 - 6.2.4 - 6.2.4 - 6.2.4 7.0.412701 6.0 @@ -206,7 +129,6 @@ 7.0.2 13.0.3 1.0.2 - 2.0.4 4.18.4 8.0.2 2.14.3 @@ -225,60 +147,23 @@ 17.0.46 9.0.0-preview-20241010.1 - - 0.11.5-alpha.25351.106 - - 10.0.0-preview.6.25302.1 2.4.8 9.0.0-alpha.1.24167.3 - - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 10.0.100-preview.7.25351.106 $(MicrosoftNETWorkloadEmscriptenCurrentManifest100100TransportVersion) 1.1.87-gba258badda 1.0.0-v3.14.0.5722 - - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 - 19.1.0-alpha.1.25167.1 3.1.7 1.0.406601 $(MicrosoftDotNetApiCompatTaskVersion) - 10.0.0-alpha.1.25169.1 - 10.0.0-preview.4.25217.3 + 10.0.0-preview.7.25359.101 $(runtimewinx64MicrosoftNETCoreRuntimeWasmNodeTransportPackageVersion) 3.1.56 diff --git a/eng/build.ps1 b/eng/build.ps1 index e6810524b6357a..f642b35f228900 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -176,8 +176,8 @@ if ($vs) { } # Auto-generated solution file that still uses the sln format - if ($vs -ieq "coreclr.sln") { - # If someone passes in coreclr.sln (case-insensitive), + if ($vs -ieq "coreclr.sln" -or $vs -ieq "coreclr") { + # If someone passes in coreclr.sln or just coreclr (case-insensitive), # launch the generated CMake solution. $vs = Split-Path $PSScriptRoot -Parent | Join-Path -ChildPath "artifacts\obj\coreclr" | Join-Path -ChildPath "windows.$archToOpen.$((Get-Culture).TextInfo.ToTitleCase($configToOpen))" | Join-Path -ChildPath "ide" | Join-Path -ChildPath "CoreCLR.sln" if (-Not (Test-Path $vs)) { @@ -192,7 +192,7 @@ if ($vs) { } } # Auto-generated solution file that still uses the sln format - elseif ($vs -ieq "corehost.sln") { + elseif ($vs -ieq "corehost.sln" -or $vs -ieq "corehost") { $vs = Split-Path $PSScriptRoot -Parent | Join-Path -ChildPath "artifacts\obj\" | Join-Path -ChildPath "win-$archToOpen.$((Get-Culture).TextInfo.ToTitleCase($configToOpen))" | Join-Path -ChildPath "corehost" | Join-Path -ChildPath "ide" | Join-Path -ChildPath "corehost.sln" if (-Not (Test-Path $vs)) { Invoke-Expression "& `"$repoRoot/eng/common/msbuild.ps1`" $repoRoot/src/native/corehost/corehost.proj /clp:nosummary /restore /p:Ninja=false /p:Configuration=$configToOpen /p:TargetArchitecture=$archToOpen /p:ConfigureOnly=true" @@ -214,6 +214,11 @@ if ($vs) { } else { # Search for the solution in coreclr $vs = Split-Path $PSScriptRoot -Parent | Join-Path -ChildPath "src\coreclr" | Join-Path -ChildPath $vs | Join-Path -ChildPath "$vs.slnx" + + # Also, search for the solution in coreclr\tools\aot + if (-Not (Test-Path $vs)) { + $vs = Split-Path $PSScriptRoot -Parent | Join-Path -ChildPath "src\coreclr\tools\aot\$solution.slnx" + } } if (-Not (Test-Path $vs)) { diff --git a/eng/build.sh b/eng/build.sh index 294afc4031dd50..2a79304978faae 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -150,7 +150,7 @@ initDistroRid() showSubsetHelp() { - "$scriptroot/common/build.sh" "-restore" "-build" "/p:Subset=help" "/clp:nosummary /tl:false" + "$scriptroot/common/build.sh" "-restore" "-build" "/p:Subset=help" "/clp:nosummary" "/tl:false" } arguments=() diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1 index 5db4ad71ee2f3e..792b60b49d424d 100644 --- a/eng/common/SetupNugetSources.ps1 +++ b/eng/common/SetupNugetSources.ps1 @@ -10,8 +10,8 @@ # displayName: Setup Private Feeds Credentials # condition: eq(variables['Agent.OS'], 'Windows_NT') # inputs: -# filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 -# arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token +# filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.ps1 +# arguments: -ConfigFile $(System.DefaultWorkingDirectory)/NuGet.config -Password $Env:Token # env: # Token: $(dn-bot-dnceng-artifact-feeds-rw) # diff --git a/eng/common/SetupNugetSources.sh b/eng/common/SetupNugetSources.sh index 4604b61b0323ae..facb415ca6ff35 100755 --- a/eng/common/SetupNugetSources.sh +++ b/eng/common/SetupNugetSources.sh @@ -11,8 +11,8 @@ # - task: Bash@3 # displayName: Setup Internal Feeds # inputs: -# filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh -# arguments: $(Build.SourcesDirectory)/NuGet.config +# filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.sh +# arguments: $(System.DefaultWorkingDirectory)/NuGet.config # condition: ne(variables['Agent.OS'], 'Windows_NT') # - task: NuGetAuthenticate@1 # diff --git a/eng/common/core-templates/job/job.yml b/eng/common/core-templates/job/job.yml index 6badecba7bcc4d..5ce51840619888 100644 --- a/eng/common/core-templates/job/job.yml +++ b/eng/common/core-templates/job/job.yml @@ -20,6 +20,7 @@ parameters: artifacts: '' enableMicrobuild: false enableMicrobuildForMacAndLinux: false + microbuildUseESRP: true enablePublishBuildArtifacts: false enablePublishBuildAssets: false enablePublishTestResults: false @@ -128,6 +129,7 @@ jobs: parameters: enableMicrobuild: ${{ parameters.enableMicrobuild }} enableMicrobuildForMacAndLinux: ${{ parameters.enableMicrobuildForMacAndLinux }} + microbuildUseESRP: ${{ parameters.microbuildUseESRP }} continueOnError: ${{ parameters.continueOnError }} - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}: @@ -161,7 +163,7 @@ jobs: inputs: testResultsFormat: 'xUnit' testResultsFiles: '*.xml' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + searchFolder: '$(System.DefaultWorkingDirectory)/artifacts/TestResults/$(_BuildConfig)' testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit mergeTestResults: ${{ parameters.mergeTestResults }} continueOnError: true @@ -172,7 +174,7 @@ jobs: inputs: testResultsFormat: 'VSTest' testResultsFiles: '*.trx' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + searchFolder: '$(System.DefaultWorkingDirectory)/artifacts/TestResults/$(_BuildConfig)' testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx mergeTestResults: ${{ parameters.mergeTestResults }} continueOnError: true @@ -216,7 +218,7 @@ jobs: - task: CopyFiles@2 displayName: Gather buildconfiguration for build retry inputs: - SourceFolder: '$(Build.SourcesDirectory)/eng/common/BuildConfiguration' + SourceFolder: '$(System.DefaultWorkingDirectory)/eng/common/BuildConfiguration' Contents: '**' TargetFolder: '$(Build.ArtifactStagingDirectory)/eng/common/BuildConfiguration' continueOnError: true diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml index 8034815f4213b1..c5788829a872e5 100644 --- a/eng/common/core-templates/job/onelocbuild.yml +++ b/eng/common/core-templates/job/onelocbuild.yml @@ -4,11 +4,11 @@ parameters: # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool pool: '' - + CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex GithubPat: $(BotAccount-dotnet-bot-repo-PAT) - SourcesDirectory: $(Build.SourcesDirectory) + SourcesDirectory: $(System.DefaultWorkingDirectory) CreatePr: true AutoCompletePr: false ReusePr: true @@ -27,7 +27,7 @@ parameters: is1ESPipeline: '' jobs: - job: OneLocBuild${{ parameters.JobNameSuffix }} - + dependsOn: ${{ parameters.dependsOn }} displayName: OneLocBuild${{ parameters.JobNameSuffix }} @@ -68,7 +68,7 @@ jobs: - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}: - task: Powershell@2 inputs: - filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1 + filePath: $(System.DefaultWorkingDirectory)/eng/common/generate-locproject.ps1 arguments: $(_GenerateLocProjectArguments) displayName: Generate LocProject.json condition: ${{ parameters.condition }} @@ -99,22 +99,20 @@ jobs: mirrorBranch: ${{ parameters.MirrorBranch }} condition: ${{ parameters.condition }} - - template: /eng/common/core-templates/steps/publish-build-artifacts.yml - parameters: - is1ESPipeline: ${{ parameters.is1ESPipeline }} - args: - displayName: Publish Localization Files - pathToPublish: '$(Build.ArtifactStagingDirectory)/loc' - publishLocation: Container - artifactName: Loc - condition: ${{ parameters.condition }} + # Copy the locProject.json to the root of the Loc directory, then publish a pipeline artifact + - task: CopyFiles@2 + displayName: Copy LocProject.json + inputs: + SourceFolder: '$(System.DefaultWorkingDirectory)/eng/Localize/' + Contents: 'LocProject.json' + TargetFolder: '$(Build.ArtifactStagingDirectory)/loc' + condition: ${{ parameters.condition }} - - template: /eng/common/core-templates/steps/publish-build-artifacts.yml + - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml parameters: is1ESPipeline: ${{ parameters.is1ESPipeline }} args: - displayName: Publish LocProject.json - pathToPublish: '$(Build.SourcesDirectory)/eng/Localize/' - publishLocation: Container - artifactName: Loc + targetPath: '$(Build.ArtifactStagingDirectory)/loc' + artifactName: 'Loc' + displayName: 'Publish Localization Files' condition: ${{ parameters.condition }} diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml index d5303229c97e27..348cd16376f10d 100644 --- a/eng/common/core-templates/job/publish-build-assets.yml +++ b/eng/common/core-templates/job/publish-build-assets.yml @@ -38,6 +38,8 @@ parameters: # Optional: A minimatch pattern for the asset manifests to publish to BAR assetManifestsPattern: '*/manifests/**/*.xml' + repositoryAlias: self + jobs: - job: Asset_Registry_Publish @@ -78,7 +80,7 @@ jobs: - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - checkout: self + - checkout: ${{ parameters.repositoryAlias }} fetchDepth: 3 clean: true @@ -117,7 +119,7 @@ jobs: azureSubscription: "Darc: Maestro Production" scriptType: ps scriptLocation: scriptPath - scriptPath: $(Build.SourcesDirectory)/eng/common/sdk-task.ps1 + scriptPath: $(System.DefaultWorkingDirectory)/eng/common/sdk-task.ps1 arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet /p:ManifestsPath='$(Build.StagingDirectory)/AssetManifests' /p:IsAssetlessBuild=${{ parameters.isAssetlessBuild }} @@ -137,7 +139,7 @@ jobs: Add-Content -Path $filePath -Value "$(DefaultChannels)" Add-Content -Path $filePath -Value $(IsStableBuild) - $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt" + $symbolExclusionfile = "$(System.DefaultWorkingDirectory)/eng/SymbolPublishingExclusionsFile.txt" if (Test-Path -Path $symbolExclusionfile) { Write-Host "SymbolExclusionFile exists" @@ -177,7 +179,7 @@ jobs: azureSubscription: "Darc: Maestro Production" scriptType: ps scriptLocation: scriptPath - scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 + scriptPath: $(System.DefaultWorkingDirectory)/eng/common/post-build/publish-using-darc.ps1 arguments: > -BuildId $(BARBuildId) -PublishingInfraVersion 3 diff --git a/eng/common/core-templates/jobs/codeql-build.yml b/eng/common/core-templates/jobs/codeql-build.yml index 693b00b370447b..dbc14ac580a271 100644 --- a/eng/common/core-templates/jobs/codeql-build.yml +++ b/eng/common/core-templates/jobs/codeql-build.yml @@ -24,7 +24,7 @@ jobs: - name: DefaultGuardianVersion value: 0.109.0 - name: GuardianPackagesConfigFile - value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config + value: $(System.DefaultWorkingDirectory)\eng\common\sdl\packages.config - name: GuardianVersion value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} diff --git a/eng/common/core-templates/jobs/jobs.yml b/eng/common/core-templates/jobs/jobs.yml index bf35b78faa60e8..b637cb6e94808e 100644 --- a/eng/common/core-templates/jobs/jobs.yml +++ b/eng/common/core-templates/jobs/jobs.yml @@ -43,6 +43,7 @@ parameters: artifacts: {} is1ESPipeline: '' + repositoryAlias: self # Internal resources (telemetry, microbuild) can only be accessed from non-public projects, # and some (Microbuild) should only be applied to non-PR cases for internal builds. @@ -83,7 +84,6 @@ jobs: - template: /eng/common/core-templates/jobs/source-build.yml parameters: is1ESPipeline: ${{ parameters.is1ESPipeline }} - allCompletedJobId: Source_Build_Complete ${{ each parameter in parameters.sourceBuildParameters }}: ${{ parameter.key }}: ${{ parameter.value }} @@ -108,8 +108,6 @@ jobs: - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: - ${{ each job in parameters.jobs }}: - ${{ job.job }} - - ${{ if eq(parameters.enableSourceBuild, true) }}: - - Source_Build_Complete runAsPublic: ${{ parameters.runAsPublic }} publishAssetsImmediately: ${{ or(parameters.publishAssetsImmediately, parameters.isAssetlessBuild) }} @@ -117,3 +115,4 @@ jobs: enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }} + repositoryAlias: ${{ parameters.repositoryAlias }} diff --git a/eng/common/core-templates/jobs/source-build.yml b/eng/common/core-templates/jobs/source-build.yml index df24c948ba1279..d92860cba20874 100644 --- a/eng/common/core-templates/jobs/source-build.yml +++ b/eng/common/core-templates/jobs/source-build.yml @@ -2,12 +2,6 @@ parameters: # This template adds arcade-powered source-build to CI. A job is created for each platform, as # well as an optional server job that completes when all platform jobs complete. - # The name of the "join" job for all source-build platforms. If set to empty string, the job is - # not included. Existing repo pipelines can use this job depend on all source-build jobs - # completing without maintaining a separate list of every single job ID: just depend on this one - # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'. - allCompletedJobId: '' - # See /eng/common/core-templates/job/source-build.yml jobNamePrefix: 'Source_Build' @@ -31,16 +25,6 @@ parameters: jobs: -- ${{ if ne(parameters.allCompletedJobId, '') }}: - - job: ${{ parameters.allCompletedJobId }} - displayName: Source-Build Complete - pool: server - dependsOn: - - ${{ each platform in parameters.platforms }}: - - ${{ parameters.jobNamePrefix }}_${{ platform.name }} - - ${{ if eq(length(parameters.platforms), 0) }}: - - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }} - - ${{ each platform in parameters.platforms }}: - template: /eng/common/core-templates/job/source-build.yml parameters: diff --git a/eng/common/core-templates/post-build/post-build.yml b/eng/common/core-templates/post-build/post-build.yml index a151fd811e3e48..f6f87fe5c675d9 100644 --- a/eng/common/core-templates/post-build/post-build.yml +++ b/eng/common/core-templates/post-build/post-build.yml @@ -154,7 +154,7 @@ stages: - task: PowerShell@2 displayName: Validate inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 + filePath: $(System.DefaultWorkingDirectory)/eng/common/post-build/nuget-validation.ps1 arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ - job: @@ -208,7 +208,7 @@ stages: filePath: eng\common\sdk-task.ps1 arguments: -task SigningValidation -restore -msbuildEngine vs /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts' - /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt' + /p:SignCheckExclusionsFile='$(System.DefaultWorkingDirectory)/eng/SignCheckExclusionsFile.txt' ${{ parameters.signingValidationAdditionalParameters }} - template: /eng/common/core-templates/steps/publish-logs.yml @@ -258,7 +258,7 @@ stages: - task: PowerShell@2 displayName: Validate inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1 + filePath: $(System.DefaultWorkingDirectory)/eng/common/post-build/sourcelink-validation.ps1 arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Extract/ -GHRepoName $(Build.Repository.Name) @@ -313,7 +313,7 @@ stages: azureSubscription: "Darc: Maestro Production" scriptType: ps scriptLocation: scriptPath - scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 + scriptPath: $(System.DefaultWorkingDirectory)/eng/common/post-build/publish-using-darc.ps1 arguments: > -BuildId $(BARBuildId) -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} diff --git a/eng/common/core-templates/post-build/setup-maestro-vars.yml b/eng/common/core-templates/post-build/setup-maestro-vars.yml index f7602980dbe721..a7abd58c4bb609 100644 --- a/eng/common/core-templates/post-build/setup-maestro-vars.yml +++ b/eng/common/core-templates/post-build/setup-maestro-vars.yml @@ -36,7 +36,7 @@ steps: $AzureDevOpsBuildId = $Env:Build_BuildId } else { - . $(Build.SourcesDirectory)\eng\common\tools.ps1 + . $(System.DefaultWorkingDirectory)\eng\common\tools.ps1 $darc = Get-Darc $buildInfo = & $darc get-build ` --id ${{ parameters.BARBuildId }} ` diff --git a/eng/common/core-templates/steps/enable-internal-sources.yml b/eng/common/core-templates/steps/enable-internal-sources.yml index 64f881bffc3cf1..4085512b690910 100644 --- a/eng/common/core-templates/steps/enable-internal-sources.yml +++ b/eng/common/core-templates/steps/enable-internal-sources.yml @@ -17,8 +17,8 @@ steps: - task: PowerShell@2 displayName: Setup Internal Feeds inputs: - filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 - arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token + filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.ps1 + arguments: -ConfigFile $(System.DefaultWorkingDirectory)/NuGet.config -Password $Env:Token env: Token: ${{ parameters.legacyCredential }} # If running on dnceng (internal project), just use the default behavior for NuGetAuthenticate. @@ -29,8 +29,8 @@ steps: - task: PowerShell@2 displayName: Setup Internal Feeds inputs: - filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 - arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config + filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.ps1 + arguments: -ConfigFile $(System.DefaultWorkingDirectory)/NuGet.config - ${{ else }}: - template: /eng/common/templates/steps/get-federated-access-token.yml parameters: @@ -39,8 +39,8 @@ steps: - task: PowerShell@2 displayName: Setup Internal Feeds inputs: - filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 - arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $(dnceng-artifacts-feeds-read-access-token) + filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.ps1 + arguments: -ConfigFile $(System.DefaultWorkingDirectory)/NuGet.config -Password $(dnceng-artifacts-feeds-read-access-token) # This is required in certain scenarios to install the ADO credential provider. # It installed by default in some msbuild invocations (e.g. VS msbuild), but needs to be installed for others # (e.g. dotnet msbuild). diff --git a/eng/common/core-templates/steps/generate-sbom.yml b/eng/common/core-templates/steps/generate-sbom.yml index 44a9636cdff90a..c05f650279795f 100644 --- a/eng/common/core-templates/steps/generate-sbom.yml +++ b/eng/common/core-templates/steps/generate-sbom.yml @@ -6,7 +6,7 @@ parameters: PackageVersion: 10.0.0 - BuildDropPath: '$(Build.SourcesDirectory)/artifacts' + BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts' PackageName: '.NET' ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom IgnoreDirectories: '' diff --git a/eng/common/core-templates/steps/install-microbuild.yml b/eng/common/core-templates/steps/install-microbuild.yml index f3064a7834edca..d6b9878f54db7f 100644 --- a/eng/common/core-templates/steps/install-microbuild.yml +++ b/eng/common/core-templates/steps/install-microbuild.yml @@ -4,8 +4,17 @@ parameters: # Enable install tasks for MicroBuild on Mac and Linux # Will be ignored if 'enableMicrobuild' is false or 'Agent.Os' is 'Windows_NT' enableMicrobuildForMacAndLinux: false + # Determines whether the ESRP service connection information should be passed to the signing plugin. + # This overlaps with _SignType to some degree. We only need the service connection for real signing. + # It's important that the service connection not be passed to the MicroBuildSigningPlugin task in this place. + # Doing so will cause the service connection to be authorized for the pipeline, which isn't allowed and won't work for non-prod. + # Unfortunately, _SignType can't be used to exclude the use of the service connection in non-real sign scenarios. The + # variable is not available in template expression. _SignType has a very large proliferation across .NET, so replacing it is tough. + microbuildUseESRP: true # Location of the MicroBuild output folder + # NOTE: There's something that relies on this being in the "default" source directory for tasks such as Signing to work properly. microBuildOutputFolder: '$(Build.SourcesDirectory)' + continueOnError: false steps: @@ -21,34 +30,62 @@ steps: workingDirectory: ${{ parameters.microBuildOutputFolder }} condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT')) + - script: | + REM Check if ESRP is disabled while SignType is real + if /I "${{ parameters.microbuildUseESRP }}"=="false" if /I "$(_SignType)"=="real" ( + echo Error: ESRP must be enabled when SignType is real. + exit /b 1 + ) + displayName: 'Validate ESRP usage (Windows)' + condition: and(succeeded(), eq(variables['Agent.Os'], 'Windows_NT')) + - script: | + # Check if ESRP is disabled while SignType is real + if [ "${{ parameters.microbuildUseESRP }}" = "false" ] && [ "$(_SignType)" = "real" ]; then + echo "Error: ESRP must be enabled when SignType is real." + exit 1 + fi + displayName: 'Validate ESRP usage (Non-Windows)' + condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT')) + + # Two different MB install steps. This is due to not being able to use the agent OS during + # YAML expansion, and Windows vs. Linux/Mac uses different service connections. However, + # we can avoid including the MB install step if not enabled at all. This avoids a bunch of + # extra pipeline authorizations, since most pipelines do not sign on non-Windows. - task: MicroBuildSigningPlugin@4 - displayName: Install MicroBuild plugin + displayName: Install MicroBuild plugin (Windows) inputs: signType: $(_SignType) zipSources: false feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json - ${{ if and(eq(parameters.enableMicrobuildForMacAndLinux, 'true'), ne(variables['Agent.Os'], 'Windows_NT')) }}: - azureSubscription: 'MicroBuild Signing Task (DevDiv)' - useEsrpCli: true - ${{ elseif eq(variables['System.TeamProject'], 'DevDiv') }}: - ConnectedPMEServiceName: 6cc74545-d7b9-4050-9dfa-ebefcc8961ea - ${{ else }}: - ConnectedPMEServiceName: 248d384a-b39b-46e3-8ad5-c2c210d5e7ca + ${{ if eq(parameters.microbuildUseESRP, true) }}: + ConnectedServiceName: 'MicroBuild Signing Task (DevDiv)' + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + ConnectedPMEServiceName: 6cc74545-d7b9-4050-9dfa-ebefcc8961ea + ${{ else }}: + ConnectedPMEServiceName: 248d384a-b39b-46e3-8ad5-c2c210d5e7ca env: TeamName: $(_TeamName) MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }} SYSTEM_ACCESSTOKEN: $(System.AccessToken) continueOnError: ${{ parameters.continueOnError }} - condition: and( - succeeded(), - or( - and( - eq(variables['Agent.Os'], 'Windows_NT'), - in(variables['_SignType'], 'real', 'test') - ), - and( - ${{ eq(parameters.enableMicrobuildForMacAndLinux, true) }}, - ne(variables['Agent.Os'], 'Windows_NT'), - eq(variables['_SignType'], 'real') - ) - )) + condition: and(succeeded(), eq(variables['Agent.Os'], 'Windows_NT'), in(variables['_SignType'], 'real', 'test')) + + - ${{ if eq(parameters.enableMicrobuildForMacAndLinux, true) }}: + - task: MicroBuildSigningPlugin@4 + displayName: Install MicroBuild plugin (non-Windows) + inputs: + signType: $(_SignType) + zipSources: false + feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + ${{ if eq(parameters.microbuildUseESRP, true) }}: + ConnectedServiceName: 'MicroBuild Signing Task (DevDiv)' + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + ConnectedPMEServiceName: beb8cb23-b303-4c95-ab26-9e44bc958d39 + ${{ else }}: + ConnectedPMEServiceName: c24de2a5-cc7a-493d-95e4-8e5ff5cad2bc + env: + TeamName: $(_TeamName) + MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + continueOnError: ${{ parameters.continueOnError }} + condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'), eq(variables['_SignType'], 'real')) diff --git a/eng/common/core-templates/steps/publish-logs.yml b/eng/common/core-templates/steps/publish-logs.yml index de24d0087c58bb..10f825e270a03b 100644 --- a/eng/common/core-templates/steps/publish-logs.yml +++ b/eng/common/core-templates/steps/publish-logs.yml @@ -12,22 +12,22 @@ steps: inputs: targetType: inline script: | - New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ - Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + New-Item -ItemType Directory $(System.DefaultWorkingDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + Move-Item -Path $(System.DefaultWorkingDirectory)/artifacts/log/Debug/* $(System.DefaultWorkingDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ continueOnError: true condition: always() - task: PowerShell@2 displayName: Redact Logs inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/redact-logs.ps1 + filePath: $(System.DefaultWorkingDirectory)/eng/common/post-build/redact-logs.ps1 # For now this needs to have explicit list of all sensitive data. Taken from eng/publishing/v3/publish.yml - # Sensitive data can as well be added to $(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt' + # Sensitive data can as well be added to $(System.DefaultWorkingDirectory)/eng/BinlogSecretsRedactionFile.txt' # If the file exists - sensitive data for redaction will be sourced from it # (single entry per line, lines starting with '# ' are considered comments and skipped) - arguments: -InputPath '$(Build.SourcesDirectory)/PostBuildLogs' + arguments: -InputPath '$(System.DefaultWorkingDirectory)/PostBuildLogs' -BinlogToolVersion ${{parameters.BinlogToolVersion}} - -TokensFilePath '$(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt' + -TokensFilePath '$(System.DefaultWorkingDirectory)/eng/BinlogSecretsRedactionFile.txt' '$(publishing-dnceng-devdiv-code-r-build-re)' '$(MaestroAccessToken)' '$(dn-bot-all-orgs-artifact-feeds-rw)' @@ -44,7 +44,7 @@ steps: - task: CopyFiles@2 displayName: Gather post build logs inputs: - SourceFolder: '$(Build.SourcesDirectory)/PostBuildLogs' + SourceFolder: '$(System.DefaultWorkingDirectory)/PostBuildLogs' Contents: '**' TargetFolder: '$(Build.ArtifactStagingDirectory)/PostBuildLogs' condition: always() diff --git a/eng/common/core-templates/steps/source-index-stage1-publish.yml b/eng/common/core-templates/steps/source-index-stage1-publish.yml index c2917c1efc1cb7..75600735f175e6 100644 --- a/eng/common/core-templates/steps/source-index-stage1-publish.yml +++ b/eng/common/core-templates/steps/source-index-stage1-publish.yml @@ -20,7 +20,7 @@ steps: # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. workingDirectory: $(Agent.TempDirectory) -- script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i ${{parameters.BinlogPath}} -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output +- script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i ${{parameters.BinlogPath}} -r $(System.DefaultWorkingDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output displayName: "Source Index: Process Binlog into indexable sln" - ${{ if and(ne(parameters.runAsPublic, 'true'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: diff --git a/eng/common/generate-locproject.ps1 b/eng/common/generate-locproject.ps1 index 524aaa57f2b742..fa1cdc2b30076a 100644 --- a/eng/common/generate-locproject.ps1 +++ b/eng/common/generate-locproject.ps1 @@ -33,15 +33,27 @@ $jsonTemplateFiles | ForEach-Object { $jsonWinformsTemplateFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "en\\strings\.json" } # current winforms pattern +$wxlFilesV3 = @() +$wxlFilesV5 = @() $wxlFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "\\.+\.wxl" -And -Not( $_.Directory.Name -Match "\d{4}" ) } # localized files live in four digit lang ID directories; this excludes them if (-not $wxlFiles) { $wxlEnFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "\\1033\\.+\.wxl" } # pick up en files (1033 = en) specifically so we can copy them to use as the neutral xlf files if ($wxlEnFiles) { - $wxlFiles = @() - $wxlEnFiles | ForEach-Object { - $destinationFile = "$($_.Directory.Parent.FullName)\$($_.Name)" - $wxlFiles += Copy-Item "$($_.FullName)" -Destination $destinationFile -PassThru - } + $wxlFiles = @() + $wxlEnFiles | ForEach-Object { + $destinationFile = "$($_.Directory.Parent.FullName)\$($_.Name)" + $content = Get-Content $_.FullName -Raw + + # Split files on schema to select different parser settings in the generated project. + if ($content -like "*http://wixtoolset.org/schemas/v4/wxl*") + { + $wxlFilesV5 += Copy-Item $_.FullName -Destination $destinationFile -PassThru + } + elseif ($content -like "*http://schemas.microsoft.com/wix/2006/localization*") + { + $wxlFilesV3 += Copy-Item $_.FullName -Destination $destinationFile -PassThru + } + } } } @@ -114,7 +126,32 @@ $locJson = @{ CloneLanguageSet = "WiX_CloneLanguages" LssFiles = @( "wxl_loc.lss" ) LocItems = @( - $wxlFiles | ForEach-Object { + $wxlFilesV3 | ForEach-Object { + $outputPath = "$($_.Directory.FullName | Resolve-Path -Relative)\" + $continue = $true + foreach ($exclusion in $exclusions.Exclusions) { + if ($_.FullName.Contains($exclusion)) { + $continue = $false + } + } + $sourceFile = ($_.FullName | Resolve-Path -Relative) + if ($continue) + { + return @{ + SourceFile = $sourceFile + CopyOption = "LangIDOnPath" + OutputPath = $outputPath + } + } + } + ) + }, + @{ + LanguageSet = $LanguageSet + CloneLanguageSet = "WiX_CloneLanguages" + LssFiles = @( "P210WxlSchemaV4.lss" ) + LocItems = @( + $wxlFilesV5 | ForEach-Object { $outputPath = "$($_.Directory.FullName | Resolve-Path -Relative)\" $continue = $true foreach ($exclusion in $exclusions.Exclusions) { diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md index 98bbc1ded0ba88..4bf4cf41bd7c76 100644 --- a/eng/common/template-guidance.md +++ b/eng/common/template-guidance.md @@ -50,7 +50,7 @@ extends: - task: CopyFiles@2 displayName: Gather build output inputs: - SourceFolder: '$(Build.SourcesDirectory)/artifacts/marvel' + SourceFolder: '$(System.DefaultWorkingDirectory)/artifacts/marvel' Contents: '**' TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/marvel' ``` diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml index a8a94328745823..92a0664f5647d5 100644 --- a/eng/common/templates-official/job/job.yml +++ b/eng/common/templates-official/job/job.yml @@ -3,7 +3,7 @@ parameters: enableSbom: true runAsPublic: false PackageVersion: 9.0.0 - BuildDropPath: '$(Build.SourcesDirectory)/artifacts' + BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts' jobs: - template: /eng/common/core-templates/job/job.yml diff --git a/eng/common/templates-official/variables/sdl-variables.yml b/eng/common/templates-official/variables/sdl-variables.yml index dbdd66d4a4b3a0..f1311bbb1b33d9 100644 --- a/eng/common/templates-official/variables/sdl-variables.yml +++ b/eng/common/templates-official/variables/sdl-variables.yml @@ -4,4 +4,4 @@ variables: - name: DefaultGuardianVersion value: 0.109.0 - name: GuardianPackagesConfigFile - value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config \ No newline at end of file + value: $(System.DefaultWorkingDirectory)\eng\common\sdl\packages.config \ No newline at end of file diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index 7cbf668c22bc04..238fa0818f7b27 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -6,7 +6,7 @@ parameters: enableSbom: true runAsPublic: false PackageVersion: 9.0.0 - BuildDropPath: '$(Build.SourcesDirectory)/artifacts' + BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts' jobs: - template: /eng/common/core-templates/job/job.yml @@ -77,7 +77,7 @@ jobs: parameters: is1ESPipeline: false args: - targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration' + targetPath: '$(System.DefaultWorkingDirectory)\eng\common\BuildConfiguration' artifactName: 'BuildConfiguration' displayName: 'Publish build retry configuration' continueOnError: true diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 40f0aa86128e48..4920464cc4ae3e 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -257,7 +257,20 @@ function Retry($downloadBlock, $maxRetries = 5) { function GetDotNetInstallScript([string] $dotnetRoot) { $installScript = Join-Path $dotnetRoot 'dotnet-install.ps1' + $shouldDownload = $false + if (!(Test-Path $installScript)) { + $shouldDownload = $true + } else { + # Check if the script is older than 30 days + $fileAge = (Get-Date) - (Get-Item $installScript).LastWriteTime + if ($fileAge.Days -gt 30) { + Write-Host "Existing install script is too old, re-downloading..." + $shouldDownload = $true + } + } + + if ($shouldDownload) { Create-Directory $dotnetRoot $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit $uri = "https://builds.dotnet.microsoft.com/dotnet/scripts/$dotnetInstallScriptVersion/dotnet-install.ps1" @@ -414,7 +427,7 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = # Locate Visual Studio installation or download x-copy msbuild. $vsInfo = LocateVisualStudio $vsRequirements - if ($vsInfo -ne $null) { + if ($vsInfo -ne $null -and $env:ForceUseXCopyMSBuild -eq $null) { # Ensure vsInstallDir has a trailing slash $vsInstallDir = Join-Path $vsInfo.installationPath "\" $vsMajorVersion = $vsInfo.installationVersion.Split('.')[0] @@ -531,7 +544,8 @@ function LocateVisualStudio([object]$vsRequirements = $null){ if (Get-Member -InputObject $GlobalJson.tools -Name 'vswhere') { $vswhereVersion = $GlobalJson.tools.vswhere } else { - $vswhereVersion = '2.5.2' + # keep this in sync with the VSWhereVersion in DefaultVersions.props + $vswhereVersion = '3.1.7' } $vsWhereDir = Join-Path $ToolsDir "vswhere\$vswhereVersion" @@ -539,7 +553,8 @@ function LocateVisualStudio([object]$vsRequirements = $null){ if (!(Test-Path $vsWhereExe)) { Create-Directory $vsWhereDir - Write-Host 'Downloading vswhere' + Write-Host 'Downloading vswhere $vswhereVersion' + $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit Retry({ Invoke-WebRequest "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/vswhere/$vswhereVersion/vswhere.exe" -OutFile $vswhereExe }) diff --git a/eng/common/tools.sh b/eng/common/tools.sh index 3def02a638d2e8..c1841c9dfd0f4e 100755 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -300,8 +300,29 @@ function GetDotNetInstallScript { local root=$1 local install_script="$root/dotnet-install.sh" local install_script_url="https://builds.dotnet.microsoft.com/dotnet/scripts/$dotnetInstallScriptVersion/dotnet-install.sh" + local timestamp_file="$root/.dotnet-install.timestamp" + local should_download=false if [[ ! -a "$install_script" ]]; then + should_download=true + elif [[ -f "$timestamp_file" ]]; then + # Check if the script is older than 30 days using timestamp file + local download_time=$(cat "$timestamp_file" 2>/dev/null || echo "0") + local current_time=$(date +%s) + local age_seconds=$((current_time - download_time)) + + # 30 days = 30 * 24 * 60 * 60 = 2592000 seconds + if [[ $age_seconds -gt 2592000 ]]; then + echo "Existing install script is too old, re-downloading..." + should_download=true + fi + else + # No timestamp file exists, assume script is old and re-download + echo "No timestamp found for existing install script, re-downloading..." + should_download=true + fi + + if [[ "$should_download" == true ]]; then mkdir -p "$root" echo "Downloading '$install_script_url'" @@ -328,6 +349,9 @@ function GetDotNetInstallScript { ExitWithExitCode $exit_code } fi + + # Create timestamp file to track download time in seconds from epoch + date +%s > "$timestamp_file" fi # return value _GetDotNetInstallScript="$install_script" diff --git a/eng/generators.targets b/eng/generators.targets index e4c4336b21edb5..1a25554a78f1b5 100644 --- a/eng/generators.targets +++ b/eng/generators.targets @@ -25,7 +25,7 @@ ( '$(DisableImplicitFrameworkReferences)' == 'true' and ( - '@(Reference->AnyHaveMetadataValue('Identity', 'System.Runtime.InteropServices'))' == 'true' or + '@(ProjectReference->AnyHaveMetadataValue('Filename', 'System.Runtime.InteropServices'))' == 'true' or '@(ProjectReference->AnyHaveMetadataValue('Identity', '$(CoreLibProject)'))' == 'true' ) )" /> @@ -38,7 +38,7 @@ '$(MSBuildProjectExtension)' == '.csproj' and ( '$(DisableImplicitFrameworkReferences)' == 'true' and - '@(Reference->AnyHaveMetadataValue('Identity', 'System.Runtime.InteropServices'))' == 'true' + '@(ProjectReference->AnyHaveMetadataValue('Filename', 'System.Runtime.InteropServices'))' == 'true' )" /> @@ -49,7 +49,7 @@ + That is required as the EnabledGenerators condition checks on the ProjectReference items and hence can't be a property condition. --> DESTINATION ${destination} COMPONENT ${INSTALL_CLR_COMPONENT}) + install(PROGRAMS $ DESTINATION ${destination} COMPONENT ${INSTALL_CLR_COMPONENT} ${INSTALL_CLR_OPTIONAL}) if (NOT "${symbolFile}" STREQUAL "") - install_symbol_file(${symbolFile} ${destination} COMPONENT ${INSTALL_CLR_COMPONENT}) + install_symbol_file(${symbolFile} ${destination} COMPONENT ${INSTALL_CLR_COMPONENT} ${INSTALL_CLR_OPTIONAL}) endif() if(CLR_CMAKE_PGO_INSTRUMENT) diff --git a/eng/native/gen-buildsys.cmd b/eng/native/gen-buildsys.cmd index 3a6e1b5426d65f..4a6bd162063682 100644 --- a/eng/native/gen-buildsys.cmd +++ b/eng/native/gen-buildsys.cmd @@ -45,19 +45,11 @@ if /i "%__Arch%" == "wasm" ( ) if /i "%__Os%" == "browser" ( if "%EMSDK_PATH%" == "" ( - if not exist "%__repoRoot%\src\mono\browser\emsdk" ( - echo Error: Should set EMSDK_PATH environment variable pointing to emsdk root. - exit /B 1 - ) - - set "EMSDK_PATH=%__repoRoot%\src\mono\browser\emsdk" + echo Error: Should set EMSDK_PATH environment variable pointing to emsdk root. + exit /B 1 ) - :: replace backslash with forward slash and append last slash - set "EMSDK_PATH=!EMSDK_PATH:\=/!" - if not "!EMSDK_PATH:~-1!" == "/" set "EMSDK_PATH=!EMSDK_PATH!/" - set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCMAKE_TOOLCHAIN_FILE=!EMSDK_PATH!/emscripten/cmake/Modules/Platform/Emscripten.cmake" - set __UseEmcmake=1 + set CMakeToolPrefix=emcmake ) if /i "%__Os%" == "wasi" ( set "__repoRoot=!__repoRoot:\=/!" @@ -135,12 +127,8 @@ if not "%__ConfigureOnly%" == "1" ( ) ) -if /i "%__UseEmcmake%" == "1" ( - call "!EMSDK_PATH!/emsdk_env.cmd" > nul 2>&1 && emcmake "%CMakePath%" %__ExtraCmakeParams% --no-warn-unused-cli -G "%__CmakeGenerator%" -B %__IntermediatesDir% -S %__SourceDir% -) else ( - echo "%CMakePath% %__ExtraCmakeParams% --no-warn-unused-cli -G %__CmakeGenerator% -B %__IntermediatesDir% -S %__SourceDir%" - "%CMakePath%" %__ExtraCmakeParams% --no-warn-unused-cli -G "%__CmakeGenerator%" -B %__IntermediatesDir% -S %__SourceDir% -) +echo %CMakeToolPrefix% "%CMakePath% %__ExtraCmakeParams% --no-warn-unused-cli -G %__CmakeGenerator% -B %__IntermediatesDir% -S %__SourceDir%" +%CMakeToolPrefix% "%CMakePath%" %__ExtraCmakeParams% --no-warn-unused-cli -G "%__CmakeGenerator%" -B %__IntermediatesDir% -S %__SourceDir% if "%errorlevel%" == "0" ( echo %__ExtraCmakeParams% > %__CmdLineOptionsUpToDateFile% diff --git a/eng/pipelines/coreclr/interpreter.yml b/eng/pipelines/coreclr/interpreter.yml index 746508b7372530..6392f36750f434 100644 --- a/eng/pipelines/coreclr/interpreter.yml +++ b/eng/pipelines/coreclr/interpreter.yml @@ -1,5 +1,13 @@ trigger: none +schedules: +- cron: "0 13 * * 1,3,5" + displayName: Every Monday, Wednesday and Friday at 5:00 AM (UTC-8:00) + branches: + include: + - main + always: true + variables: - template: /eng/pipelines/common/variables.yml diff --git a/eng/pipelines/coreclr/superpmi-diffs.yml b/eng/pipelines/coreclr/superpmi-diffs.yml index 10ba7a7a1df002..5e8b4f12b31da6 100644 --- a/eng/pipelines/coreclr/superpmi-diffs.yml +++ b/eng/pipelines/coreclr/superpmi-diffs.yml @@ -55,8 +55,11 @@ extends: platforms: - osx_arm64 - windows_x86 + # Not needed for subsequent steps, but this ensures we get some build + # coverage of community JITs in CI on JIT PRs. + - windows_x64 jobParameters: - buildArgs: -s clr.alljits+clr.spmi -c $(_BuildConfig) + buildArgs: -s clr.alljitscommunity+clr.spmi -c $(_BuildConfig) postBuildSteps: # Build CLR assets for x64 as well as the target as we need an x64 mcs - template: /eng/pipelines/common/templates/global-build-step.yml diff --git a/eng/pipelines/coreclr/templates/jit-replay-pipeline.yml b/eng/pipelines/coreclr/templates/jit-replay-pipeline.yml index 3ee415cb881a73..74f2caf2ff3852 100644 --- a/eng/pipelines/coreclr/templates/jit-replay-pipeline.yml +++ b/eng/pipelines/coreclr/templates/jit-replay-pipeline.yml @@ -32,7 +32,7 @@ extends: buildConfig: checked platforms: ${{ parameters.platforms }} jobParameters: - buildArgs: -s clr.alljitscommunity+clr.spmi -c $(_BuildConfig) + buildArgs: -s clr.alljits+clr.spmi -c $(_BuildConfig) postBuildSteps: - template: /eng/pipelines/common/upload-artifact-step.yml parameters: diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml index 417241706c4c91..3a01170b624758 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml +++ b/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,10 +107,41 @@ 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 parameters: creator: dotnet-bot testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig) + +# +# Android arm64 devices and x64 emulators +# Build the whole product using NativeAOT and run functional tests +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: Release + runtimeFlavor: coreclr + platforms: + - android_arm64 + variables: + # map dependencies variables to local variables + - name: librariesContainsChange + value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ] + - name: coreclrContainsChange + value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'] ] + jobParameters: + testGroup: innerloop + nameSuffix: NativeAOT + isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }} + buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true /p:RuntimeFlavor=coreclr /p:TestNativeAOT=true + timeoutInMinutes: 120 + # extra steps, run tests + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml index b7b3774f0b5a35..4f0c526aff1d38 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml +++ b/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 @@ -149,3 +149,36 @@ jobs: parameters: creator: dotnet-bot testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig) + +# +# Android arm64 devices and x64 emulators +# Build the whole product using NativeAOT and run functional tests +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: Release + runtimeFlavor: coreclr + isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }} + isAndroidEmulatorOnlyBuild: ${{ parameters.isAndroidEmulatorOnlyBuild }} + platforms: + - android_x64 + variables: + # map dependencies variables to local variables + - name: librariesContainsChange + value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ] + - name: coreclrContainsChange + value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'] ] + jobParameters: + testGroup: innerloop + nameSuffix: NativeAOT + isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }} + buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:UseNativeAOTRuntime=true /p:RuntimeFlavor=coreclr /p:TestNativeAOT=true + timeoutInMinutes: 120 + # extra steps, run tests + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml index 7f10d317464cf8..82726e28094227 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml +++ b/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/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml index 9f483dbbe75eb3..80f29f2d8567eb 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml +++ b/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: @@ -133,3 +133,37 @@ jobs: testBuildArgs: tree nativeaot/SmokeTests /p:BuildNativeAOTRuntimePack=true testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) buildAllTestsAsStandalone: true + +# +# iOS simulator +# Build the whole product using CoreCLR and run functional tests +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: checked + runtimeFlavor: coreclr + isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }} + isiOSLikeSimulatorOnlyBuild: ${{ parameters.isiOSLikeSimulatorOnlyBuild }} + platforms: + - iossimulator_arm64 + variables: + # map dependencies variables to local variables + - name: librariesContainsChange + value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ] + - name: coreclrContainsChange + value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'] ] + - name: illinkContainsChange + value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'] ] + jobParameters: + testGroup: innerloop + nameSuffix: AllSubsets_CoreCLR + buildArgs: -s clr+clr.runtime+libs+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=false /p:UseMonoRuntime=false /p:MonoForceInterpreter=false /p:RunSmokeTestsOnly=true + timeoutInMinutes: 120 + # extra steps, run tests + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig) diff --git a/eng/pipelines/installer/helix-queues-setup.yml b/eng/pipelines/installer/helix-queues-setup.yml index 57cd037c9ed28f..582294a4a39d6a 100644 --- a/eng/pipelines/installer/helix-queues-setup.yml +++ b/eng/pipelines/installer/helix-queues-setup.yml @@ -42,7 +42,6 @@ jobs: # Linux x64 - ${{ if eq(parameters.platform, 'linux_x64') }}: - AzureLinux.3.Amd64.Open - - Ubuntu.2204.Amd64.Open # OSX arm64 - ${{ if eq(parameters.platform, 'osx_arm64') }}: diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index fdebac85bc327a..71713d3bccb3c7 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -37,7 +37,7 @@ jobs: # Linux musl x64 - ${{ if eq(parameters.platform, 'linux_musl_x64') }}: - - ${{ if or(eq(parameters.jobParameters.isExtraPlatformsBuild, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: + - ${{ if or(eq(parameters.jobParameters.isExtraPlatformsBuild, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - (Alpine.edge.Amd64.Open)AzureLinux.3.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-edge-helix-amd64 - ${{ if or(ne(parameters.jobParameters.isExtraPlatformsBuild, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - (Alpine.322.Amd64.Open)AzureLinux.3.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.22-helix-amd64 @@ -75,7 +75,7 @@ jobs: - Ubuntu.2204.Amd64.Open - (AzureLinux.3.0.Amd64.Open)AzureLinux.3.Amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-helix-amd64 - (Centos.10.Amd64.Open)AzureLinux.3.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream-10-helix-amd64 - + # OSX arm64 - ${{ if eq(parameters.platform, 'osx_arm64') }}: - osx.13.arm64.open diff --git a/eng/pipelines/performance/perf-build.yml b/eng/pipelines/performance/perf-build.yml index ef418994581d99..10cc3606d94bdf 100644 --- a/eng/pipelines/performance/perf-build.yml +++ b/eng/pipelines/performance/perf-build.yml @@ -14,10 +14,6 @@ parameters: displayName: Build Coreclr Arm64 Windows type: boolean default: true -- name: coreclr_muslx64_linux - displayName: Build Coreclr Musl x64 Linux - type: boolean - default: true - name: coreclr_x64_linux displayName: Build Coreclr x64 Linux type: boolean @@ -110,8 +106,6 @@ extends: - coreclr_arm64_linux - ${{ if eq(parameters.coreclr_arm64_windows, true) }}: - coreclr_arm64_windows - - ${{ if eq(parameters.coreclr_muslx64_linux, true) }}: - - coreclr_muslx64_linux - ${{ if eq(parameters.coreclr_x64_linux, true) }}: - coreclr_x64_linux - ${{ if eq(parameters.coreclr_x64_windows, true) }}: @@ -152,8 +146,6 @@ extends: - coreclr_arm64_linux - ${{ if eq(parameters.coreclr_arm64_windows, true) }}: - coreclr_arm64_windows - - ${{ if eq(parameters.coreclr_muslx64_linux, true) }}: - - coreclr_muslx64_linux - ${{ if eq(parameters.coreclr_x64_linux, true) }}: - coreclr_x64_linux - ${{ if eq(parameters.coreclr_x64_windows, true) }}: @@ -182,7 +174,7 @@ extends: - nativeAot_arm64_ios ${{ if parameters.mauiFramework }}: mauiFramework: ${{ parameters.mauiFramework }} - + - ${{ if and(ne(variables['System.TeamProject'], 'public'), or(eq(variables['Build.Reason'], 'IndividualCI'), parameters.runPrivateJobs)) }}: - stage: UploadArtifacts displayName: 'Upload Artifacts' @@ -200,8 +192,6 @@ extends: - coreclr_arm64_linux - ${{ if eq(parameters.coreclr_arm64_windows, true) }}: - coreclr_arm64_windows - - ${{ if eq(parameters.coreclr_muslx64_linux, true) }}: - - coreclr_muslx64_linux - ${{ if eq(parameters.coreclr_x64_linux, true) }}: - coreclr_x64_linux - ${{ if eq(parameters.coreclr_x64_windows, true) }}: diff --git a/eng/pipelines/performance/perf.yml b/eng/pipelines/performance/perf.yml index 01b80b580db2bd..17b77bffe7e16d 100644 --- a/eng/pipelines/performance/perf.yml +++ b/eng/pipelines/performance/perf.yml @@ -8,6 +8,7 @@ trigger: branches: include: - main + - release/10.0 - release/9.0 - release/8.0 paths: diff --git a/eng/pipelines/performance/templates/build-perf-sample-apps.yml b/eng/pipelines/performance/templates/build-perf-sample-apps.yml index 36ca31eb80ca4d..be23c6465cbd44 100644 --- a/eng/pipelines/performance/templates/build-perf-sample-apps.yml +++ b/eng/pipelines/performance/templates/build-perf-sample-apps.yml @@ -20,7 +20,7 @@ steps: artifactName: AndroidMonoArm64BuildLog - template: /eng/pipelines/common/upload-artifact-step.yml parameters: - rootFolder: $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp/arm64/Release/android-arm64/Bundle/bin/HelloAndroid.apk + rootFolder: $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp/arm64/Release/android-arm64/AppBundle/bin/HelloAndroid.apk includeRootFolder: true displayName: Android Sample App JIT Mono artifactName: AndroidHelloWorldArm64Mono @@ -43,7 +43,7 @@ steps: artifactName: AndroidMonoAOTArm64BuildLog - template: /eng/pipelines/common/upload-artifact-step.yml parameters: - rootFolder: $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp/arm64/Release/android-arm64/Bundle/bin/HelloAndroid.apk + rootFolder: $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp/arm64/Release/android-arm64/AppBundle/bin/HelloAndroid.apk includeRootFolder: true displayName: Android Sample App AOT Mono artifactName: AndroidHelloWorldArm64MonoAOT @@ -67,7 +67,7 @@ steps: artifactName: AndroidCoreCLRArm64BuildLog - template: /eng/pipelines/common/upload-artifact-step.yml parameters: - rootFolder: $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp/arm64/Release/android-arm64/Bundle/bin/HelloAndroid.apk + rootFolder: $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp/arm64/Release/android-arm64/AppBundle/bin/HelloAndroid.apk includeRootFolder: true displayName: Android Sample App JIT CoreCLR artifactName: AndroidHelloWorldArm64CoreCLR @@ -90,7 +90,7 @@ steps: artifactName: AndroidCoreCLRArm64StaticLinkingBuildLog - template: /eng/pipelines/common/upload-artifact-step.yml parameters: - rootFolder: $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp/arm64/Release/android-arm64/Bundle/bin/HelloAndroid.apk + rootFolder: $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp/arm64/Release/android-arm64/AppBundle/bin/HelloAndroid.apk includeRootFolder: true displayName: Android Sample App JIT CoreCLR Static Linking artifactName: AndroidHelloWorldArm64CoreCLRStaticLinking @@ -113,7 +113,7 @@ steps: artifactName: AndroidCoreCLRR2RArm64BuildLog - template: /eng/pipelines/common/upload-artifact-step.yml parameters: - rootFolder: $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp/arm64/Release/android-arm64/Bundle/bin/HelloAndroid.apk + rootFolder: $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp/arm64/Release/android-arm64/AppBundle/bin/HelloAndroid.apk includeRootFolder: true displayName: Android Sample App R2R CoreCLR artifactName: AndroidHelloWorldArm64CoreCLRR2R diff --git a/eng/pipelines/performance/templates/perf-build-jobs.yml b/eng/pipelines/performance/templates/perf-build-jobs.yml index 4defede2528db2..a7ecb34a3f0f9e 100644 --- a/eng/pipelines/performance/templates/perf-build-jobs.yml +++ b/eng/pipelines/performance/templates/perf-build-jobs.yml @@ -8,7 +8,6 @@ jobs: linux_x64: true windows_x64: true windows_x86: true - linux_musl_x64: true android_arm64: true # build mono for AOT diff --git a/eng/pipelines/performance/templates/perf-coreclr-build-jobs.yml b/eng/pipelines/performance/templates/perf-coreclr-build-jobs.yml index ddf103aaf4c0d9..85704ada6a297e 100644 --- a/eng/pipelines/performance/templates/perf-coreclr-build-jobs.yml +++ b/eng/pipelines/performance/templates/perf-coreclr-build-jobs.yml @@ -1,6 +1,5 @@ parameters: linux_x64: false - linux_musl_x64: false linux_arm64: false windows_x64: false windows_x86: false @@ -8,7 +7,7 @@ parameters: android_arm64: false jobs: - - ${{ if or(eq(parameters.linux_x64, true), eq(parameters.windows_x64, true), eq(parameters.windows_x86, true), eq(parameters.linux_musl_x64, true), eq(parameters.linux_arm64, true), eq(parameters.windows_arm64, true)) }}: + - ${{ if or(eq(parameters.linux_x64, true), eq(parameters.windows_x64, true), eq(parameters.windows_x86, true), eq(parameters.linux_arm64, true), eq(parameters.windows_arm64, true)) }}: # build coreclr and libraries - template: /eng/pipelines/common/platform-matrix.yml parameters: @@ -21,8 +20,6 @@ jobs: - windows_x64 - ${{ if eq(parameters.windows_x86, true) }}: - windows_x86 - - ${{ if eq(parameters.linux_musl_x64, true) }}: - - linux_musl_x64 - ${{ if eq(parameters.linux_arm64, true) }}: - linux_arm64 - ${{ if eq(parameters.windows_arm64, true) }}: diff --git a/eng/pipelines/runtime-linker-tests.yml b/eng/pipelines/runtime-linker-tests.yml index 9df8042e7af0af..3f2e6c1da8b5d1 100644 --- a/eng/pipelines/runtime-linker-tests.yml +++ b/eng/pipelines/runtime-linker-tests.yml @@ -82,7 +82,11 @@ extends: or( eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'], true), eq(variables['isRollingBuild'], true)) - buildArgs: -s tools.illinktests -test -c $(_BuildConfig) + # Build libs.sfx subset first so that Roslyn analyzer tests can use live ref pack + buildArgs: -s libs.sfx -c $(_BuildConfig) + postBuildSteps: + - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -ci -arch $(archType) $(_osParameter) -s tools.illinktests -test -c $(_BuildConfig) $(crossArg) $(_officialBuildParameter) + displayName: Run ILLink Tests # # Build Release config vertical for Windows, Linux, and OSX diff --git a/eng/pipelines/runtime-llvm.yml b/eng/pipelines/runtime-llvm.yml index b315a1541d1fd8..82f4bb1970a28b 100644 --- a/eng/pipelines/runtime-llvm.yml +++ b/eng/pipelines/runtime-llvm.yml @@ -162,7 +162,7 @@ extends: nameSuffix: AllSubsets_Mono_LLVMFULLAOT_RuntimeTests runtimeVariant: llvmfullaot buildArgs: -s mono+libs+clr.hosts+clr.iltools -c $(_BuildConfig) /p:MonoEnableLLVM=true - timeoutInMinutes: 400 + timeoutInMinutes: 480 condition: >- or( eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), @@ -177,9 +177,9 @@ extends: testRunNamePrefixSuffix: Mono_Release testBuildArgs: >- -tree:CoreMangLib -tree:Exceptions -tree:GC -tree:Interop -tree:Loader -tree:Regressions -tree:baseservices - -tree:ilasm -tree:ilverify -tree:managed -tree:profiler -tree:readytorun -tree:reflection -tree:tracing + -tree:ilverify -tree:managed -tree:profiler -tree:reflection -tree:tracing -tree:JIT/BBT -tree:JIT/CodeGenBringUpTests -tree:JIT/Directed -tree:JIT/Generics -tree:JIT/IL_Conformance - -tree:JIT/Math -tree:JIT/Methodical -tree:JIT/PGO -tree:JIT/Performance -tree:JIT/Regression -tree:JIT/RyuJIT + -tree:JIT/Math -tree:JIT/Methodical -tree:JIT/Performance -tree:JIT/Regression -tree:JIT/RyuJIT -tree:JIT/Stress -tree:JIT/common -tree:JIT/jit64 -tree:JIT/opt -tree:JIT/superpmi extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml @@ -209,7 +209,7 @@ extends: nameSuffix: AllSubsets_Mono_LLVMFULLAOT_RuntimeIntrinsicsTests runtimeVariant: llvmfullaot buildArgs: -s mono+libs+clr.hosts+clr.iltools -c $(_BuildConfig) /p:MonoEnableLLVM=true - timeoutInMinutes: 400 + timeoutInMinutes: 480 condition: >- or( eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 44740dd5181d2e..7460b60a32f93c 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -86,21 +86,6 @@ extends: eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_non_mono_and_wasm.containsChange'], true), eq(variables['isRollingBuild'], true)) - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - buildConfig: ${{ variables.debugOnPrReleaseOnRolling }} - platforms: - - osx_arm64 - jobParameters: - nameSuffix: AllSubsets_CoreCLR - buildArgs: -s clr+libs+host+packs -rc Release -c Release -lc $(_BuildConfig) - timeoutInMinutes: 120 - condition: >- - or( - eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_non_mono_and_wasm.containsChange'], true), - eq(variables['isRollingBuild'], true)) - - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/common/global-build-job.yml @@ -208,6 +193,36 @@ extends: eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), eq(variables['isRollingBuild'], true)) + # + # Build CoreCLR and Libraries + # For running installer tests + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: release + platforms: + - osx_arm64 + jobParameters: + nameSuffix: CoreCLR_Libraries + buildArgs: -s clr+libs -c $(_BuildConfig) + timeoutInMinutes: 120 + postBuildSteps: + - template: /eng/pipelines/common/upload-artifact-step.yml + parameters: + rootFolder: $(Build.SourcesDirectory)/artifacts/bin + includeRootFolder: false + archiveType: $(archiveType) + archiveExtension: $(archiveExtension) + tarCompression: $(tarCompression) + artifactName: CoreCLR_Libraries_BuildArtifacts_$(osGroup)$(osSubgroup)_$(archType)_$(_BuildConfig) + displayName: Build Assets + condition: >- + or( + eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_non_mono_and_wasm.containsChange'], true), + eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), + eq(variables['isRollingBuild'], true)) + # # Build CoreCLR and Libraries with the respective tests # for the test configurations we run. @@ -885,13 +900,13 @@ extends: # WASI/WASM - - template: /eng/pipelines/common/templates/simple-wasm-build-tests.yml - parameters: - platforms: - - wasi_wasm - - wasi_wasm_win - extraBuildArgs: /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS) - alwaysRun: ${{ variables.isRollingBuild }} + # - template: /eng/pipelines/common/templates/simple-wasm-build-tests.yml + # parameters: + # platforms: + # - wasi_wasm + # - wasi_wasm_win + # extraBuildArgs: /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS) + # alwaysRun: ${{ variables.isRollingBuild }} # # Android devices @@ -916,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), @@ -958,7 +973,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: 180 condition: >- or( eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), @@ -1002,7 +1017,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), @@ -1261,6 +1276,7 @@ extends: buildConfig: ${{ variables.debugOnPrReleaseOnRolling }} platforms: - windows_x86 + - osx_arm64 helixQueuesTemplate: /eng/pipelines/installer/helix-queues-setup.yml jobParameters: nameSuffix: Installer_Build_And_Test diff --git a/eng/references.targets b/eng/references.targets index 2b0035d3054a1f..6edd9720538136 100644 --- a/eng/references.targets +++ b/eng/references.targets @@ -1,4 +1,5 @@ + <_coreLibProjectReference Include="@(ProjectReference->WithMetadataValue('Identity', '$(CoreLibProject)'))" /> - + Configuration=$(CoreCLRConfiguration) Configuration=$(MonoConfiguration) - - - - - - - - + + + <_ProjectReferenceWithOriginalIdentity Include="@(ProjectReference)" + OriginalIdentity="%(Identity)" /> + <_projectReferenceWithFilename Include="@(_ProjectReferenceWithOriginalIdentity->Metadata('Filename'))" /> + + <_projectReferenceExcludedWithFilename Include="@(_projectReferenceWithFilename)" + Exclude="@(NetCoreAppLibrary)" /> + <_frameworkProjectReference Include="@(_projectReferenceWithFilename)" + Exclude="@(_projectReferenceExcludedWithFilename)" /> + + + all + false + + + diff --git a/eng/resolveContract.targets b/eng/resolveContract.targets index 14bf17e8ed4f93..e9f2e0b48a0873 100644 --- a/eng/resolveContract.targets +++ b/eng/resolveContract.targets @@ -119,6 +119,7 @@ true + ReferencePathWithRefAssemblies diff --git a/eng/slngen.targets b/eng/slngen.targets index d7622098f1e42d..382ca8d684aad5 100644 --- a/eng/slngen.targets +++ b/eng/slngen.targets @@ -4,7 +4,7 @@ $(SlnGenSolutionFolder)gen$(SlnGenSolutionInnerFolder) $(SlnGenSolutionFolder)ref$(SlnGenSolutionInnerFolder) $(SlnGenSolutionFolder)tests$(SlnGenSolutionInnerFolder) - $(SlnGenSolutionFolder)src$(SlnGenSolutionInnerFolder) + $(SlnGenSolutionFolder)src$(SlnGenSolutionInnerFolder) diff --git a/eng/targetingpacks.targets b/eng/targetingpacks.targets index 6869d63c852186..15e62c05e04b4e 100644 --- a/eng/targetingpacks.targets +++ b/eng/targetingpacks.targets @@ -1,16 +1,16 @@ - - + + $(MicrosoftNetCoreAppFrameworkName) true @@ -90,26 +90,6 @@ Condition="'$(UseLocalAppHostPack)' == 'true' and '@(KnownAppHostPack->AnyHaveMetadataValue('TargetFramework', '$(NetCoreAppCurrent)'))' != 'true'" /> - - - - false - - - - - - - $(AssemblySearchPaths);$(MicrosoftNetCoreAppRefPackRefDir.TrimEnd('/\')) - $(DesignTimeAssemblySearchPaths);$(MicrosoftNetCoreAppRefPackRefDir.TrimEnd('/\')) - - - $(BootstrapRuntimePackDir)/runtimes/$(TargetRid)/native/ $(BootstrapAotSdkDir)/ + diff --git a/eng/testing/BrowserVersions.props b/eng/testing/BrowserVersions.props index e09e3c3be90ca0..c7b40839e4a520 100644 --- a/eng/testing/BrowserVersions.props +++ b/eng/testing/BrowserVersions.props @@ -1,13 +1,13 @@ - 138.0.7204.49 - 1465706 - https://storage.googleapis.com/chromium-browser-snapshots/Linux_x64/1465706 - 13.8.258 - 138.0.7204.35 - 1465706 - https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/1465706 - 13.8.258 + 139.0.7258.127 + 1477651 + https://storage.googleapis.com/chromium-browser-snapshots/Linux_x64/1477657 + 13.9.205 + 139.0.7258.66 + 1477651 + https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/1477667 + 13.9.205 125.0.1 0.34.0 125.0.1 diff --git a/eng/testing/scenarios/BuildWasiAppsJobsList.txt b/eng/testing/scenarios/BuildWasiAppsJobsList.txt index 86c0517585a480..8b137891791fe9 100644 --- a/eng/testing/scenarios/BuildWasiAppsJobsList.txt +++ b/eng/testing/scenarios/BuildWasiAppsJobsList.txt @@ -1,7 +1 @@ -Wasi.Build.Tests.InvariantTests -Wasi.Build.Tests.ILStripTests -Wasi.Build.Tests.SdkMissingTests -Wasi.Build.Tests.RuntimeConfigTests -Wasi.Build.Tests.WasiTemplateTests -Wasi.Build.Tests.PInvokeTableGeneratorTests -Wasi.Build.Tests.WasiLibraryModeTests + diff --git a/eng/testing/scenarios/BuildWasmAppsJobsList.txt b/eng/testing/scenarios/BuildWasmAppsJobsList.txt index 82c8b0c827964d..60f2a2187e3e14 100644 --- a/eng/testing/scenarios/BuildWasmAppsJobsList.txt +++ b/eng/testing/scenarios/BuildWasmAppsJobsList.txt @@ -14,7 +14,6 @@ Wasm.Build.Tests.Blazor.DllImportTests Wasm.Build.Tests.Blazor.NativeTests Wasm.Build.Tests.Blazor.NoopNativeRebuildTest Wasm.Build.Tests.Blazor.WorkloadRequiredTests -Wasm.Build.Tests.Blazor.SignalRClientTests Wasm.Build.Tests.Blazor.EventPipeDiagnosticsTests Wasm.Build.Tests.BuildPublishTests Wasm.Build.Tests.ConfigSrcTests @@ -38,7 +37,6 @@ Wasm.Build.Tests.LibraryInitializerTests Wasm.Build.Tests.SatelliteLoadingTests Wasm.Build.Tests.ModuleConfigTests Wasm.Build.Tests.MemoryTests -Wasm.Build.Tests.AspNetCore.SignalRClientTests Wasm.Build.Tests.WasmBuildAppTest Wasm.Build.Tests.WasmNativeDefaultsTests Wasm.Build.Tests.WasmRunOutOfAppBundleTests diff --git a/eng/testing/tests.android.targets b/eng/testing/tests.android.targets index 4144799c78f908..5bcd9d4bc63d2e 100644 --- a/eng/testing/tests.android.targets +++ b/eng/testing/tests.android.targets @@ -28,7 +28,6 @@ AndroidTestRunner.dll $(PublishDir) - $(BundleDir) diff --git a/eng/testing/tests.singlefile.targets b/eng/testing/tests.singlefile.targets index fab26560f4b61f..05b2c15a018946 100644 --- a/eng/testing/tests.singlefile.targets +++ b/eng/testing/tests.singlefile.targets @@ -1,8 +1,8 @@ - Exe + Exe - $([MSBuild]::NormalizeDirectory('$(OutDir)', 'publish')) + $([MSBuild]::NormalizeDirectory('$(OutDir)', 'publish')) $([MSBuild]::NormalizePath('$(BundleDir)', '$(RunScriptOutputName)')) $(TargetRid) @@ -49,7 +49,8 @@ + Link="Common\SingleFileTestRunner\SingleFileTestRunner.cs" + Condition="'$(IsFunctionalTest)' != 'true'" /> diff --git a/github-merge-flow.jsonc b/github-merge-flow.jsonc index b42b4e156afa38..0439bc3c57e163 100644 --- a/github-merge-flow.jsonc +++ b/github-merge-flow.jsonc @@ -15,6 +15,11 @@ "release/9.0":{ "MergeToBranch": "release/9.0-staging", "ExtraSwitches": "-QuietComments" + }, + // Automate merging runtime release/10.0-rc1 branch into release/10.0 + "release/10.0-rc1":{ + "MergeToBranch": "release/10.0", + "ExtraSwitches": "-QuietComments" } } } diff --git a/global.json b/global.json index 35c4959162e898..7f8070a6693aec 100644 --- a/global.json +++ b/global.json @@ -1,18 +1,18 @@ { "sdk": { - "version": "10.0.100-preview.6.25315.102", + "version": "10.0.100-rc.1.25411.109", "allowPrerelease": true, "rollForward": "major" }, "tools": { - "dotnet": "10.0.100-preview.6.25315.102" + "dotnet": "10.0.100-rc.1.25411.109" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25351.106", - "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25351.106", - "Microsoft.DotNet.SharedFramework.Sdk": "10.0.0-beta.25351.106", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25418.105", + "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25418.105", + "Microsoft.DotNet.SharedFramework.Sdk": "10.0.0-beta.25418.105", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", - "Microsoft.NET.Sdk.IL": "10.0.0-preview.7.25351.106" + "Microsoft.NET.Sdk.IL": "10.0.0-rc.1.25418.105" } } diff --git a/src/coreclr/.nuget/ILCompiler.Reflection.ReadyToRun.Experimental/ILCompiler.Reflection.ReadyToRun.Experimental.pkgproj b/src/coreclr/.nuget/ILCompiler.Reflection.ReadyToRun.Experimental/ILCompiler.Reflection.ReadyToRun.Experimental.pkgproj index 0480327017db55..7d202885cc77c5 100644 --- a/src/coreclr/.nuget/ILCompiler.Reflection.ReadyToRun.Experimental/ILCompiler.Reflection.ReadyToRun.Experimental.pkgproj +++ b/src/coreclr/.nuget/ILCompiler.Reflection.ReadyToRun.Experimental/ILCompiler.Reflection.ReadyToRun.Experimental.pkgproj @@ -12,11 +12,11 @@ - \lib\netstandard2.0\ + \lib\$(NetCoreAppMinimum)\ $(SystemReflectionMetadataVersion) - netstandard2.0 + $(NetCoreAppMinimum) Build,Analyzers diff --git a/src/coreclr/CMakeLists.txt b/src/coreclr/CMakeLists.txt index 7286f655004ca9..b1433e14def45b 100644 --- a/src/coreclr/CMakeLists.txt +++ b/src/coreclr/CMakeLists.txt @@ -39,6 +39,10 @@ if (DEFINED CLR_CMAKE_ICU_DIR) include_directories(${CLR_CMAKE_ICU_DIR}/include) endif(DEFINED CLR_CMAKE_ICU_DIR) +if (CLR_CMAKE_TARGET_ARCH_WASM) + add_compile_options(-fwasm-exceptions) +endif() + #---------------------------------------------------- # Cross target Component build specific configuration #---------------------------------------------------- @@ -174,6 +178,12 @@ endif(CLR_CMAKE_HOST_WIN32) #---------------------------------- include(clrdefinitions.cmake) +#-------------------------------- +# Data descriptors mechanics +# - all clr specific data descriptor helpers should be included in this file +#---------------------------------- +include(clrdatadescriptors.cmake) + if(FEATURE_STANDALONE_GC) add_definitions(-DFEATURE_STANDALONE_GC) endif(FEATURE_STANDALONE_GC) diff --git a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj index 2fb4c3e7ffa6bb..c12d6c854ac0c0 100644 --- a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -223,6 +223,7 @@ + diff --git a/src/coreclr/System.Private.CoreLib/src/System/Attribute.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Attribute.CoreCLR.cs index 7fbb594a1844de..3634e8012c21fd 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Attribute.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Attribute.CoreCLR.cs @@ -170,7 +170,7 @@ private static Attribute[] InternalGetCustomAttributes(EventInfo element, Type t { rtAdd = rtAdd.GetParentDefinition(); if (rtAdd != null) - return rtAdd.DeclaringType!.GetEvent(ev.Name!); + return rtAdd.DeclaringType!.GetEvent(ev.Name); } return null; } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrameHelper.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrameHelper.cs index 4e0736cb78aa4f..763259a20a257e 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrameHelper.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/StackFrameHelper.cs @@ -118,7 +118,7 @@ internal void InitializeSourceInfo(bool fNeedFileInfo, Exception? exception) // ENC or the source/line info was already retrieved, the method token is 0. if (rgiMethodToken![index] != 0) { - GetSourceLineInfo(s_stackTraceSymbolsCache!, rgAssembly![index], rgAssemblyPath![index]!, rgLoadedPeAddress![index], rgiLoadedPeSize![index], rgiIsFileLayout![index], + GetSourceLineInfo(s_stackTraceSymbolsCache, rgAssembly![index], rgAssemblyPath![index], rgLoadedPeAddress![index], rgiLoadedPeSize![index], rgiIsFileLayout![index], rgInMemoryPdbAddress![index], rgiInMemoryPdbSize![index], rgiMethodToken![index], rgiILOffset![index], out rgFilename![index], out rgiLineNumber![index], out rgiColumnNumber![index]); } diff --git a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs index 101fbfa7c6bc45..5b05fe76d08136 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs @@ -884,7 +884,7 @@ private static unsafe void ConfigCallback(void* configurationContext, void* name ref GCConfigurationContext context = ref Unsafe.As(ref *(byte*)configurationContext); Debug.Assert(context.Configurations != null); - Dictionary configurationDictionary = context.Configurations!; + Dictionary configurationDictionary = context.Configurations; string nameAsString = Marshal.PtrToStringUTF8((IntPtr)name)!; switch (type) diff --git a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.CoreCLR.cs index 9740d23843f42b..1c9a4c6c384b29 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.CoreCLR.cs @@ -9,6 +9,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; +using System.Threading; namespace System { @@ -144,7 +145,7 @@ private bool InvocationListEquals(MulticastDelegate d) private static bool TrySetSlot(object?[] a, int index, object o) { - if (a[index] == null && Threading.Interlocked.CompareExchange(ref a[index], o, null) == null) + if (a[index] == null && Interlocked.CompareExchange(ref a[index], o, null) == null) return true; // The slot may be already set because we have added and removed the same method before. diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.cs index 2aad5096f25f05..5c5bc5d0e52217 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.cs @@ -416,7 +416,7 @@ private static MethodBase GetGenericMethodBaseDefinition(MethodBase methodBase) { Debug.Assert(masmi != null); - methDef = masmi.GetGenericMethodDefinition()!; + methDef = masmi.GetGenericMethodDefinition(); methDef = methDef.Module.ResolveMethod( methodBase.MetadataToken, methDef.DeclaringType?.GetGenericArguments(), @@ -1070,7 +1070,7 @@ internal int GetMethodTokenInternal(MethodBase method, Type[]? optionalParameter if (!isGenericMethodDef) { - methodInfoUnbound = methodInfo.GetGenericMethodDefinition()!; + methodInfoUnbound = methodInfo.GetGenericMethodDefinition(); } if (!Equals(methodInfoUnbound.Module) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs index 17bb50457648f5..f9c11e07891095 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs @@ -34,7 +34,7 @@ internal sealed partial class RuntimeAssembly : Assembly #endregion - internal IntPtr GetUnderlyingNativeHandle() { return m_assembly; } + internal IntPtr GetUnderlyingNativeHandle() => m_assembly; private sealed class ManifestResourceStream : UnmanagedMemoryStream { @@ -52,17 +52,8 @@ internal unsafe ManifestResourceStream(RuntimeAssembly manifestAssembly, byte* p // NOTE: no reason to override Write(Span), since a ManifestResourceStream is read-only. } - internal object SyncRoot - { - get - { - if (m_syncRoot == null) - { - Interlocked.CompareExchange(ref m_syncRoot, new object(), null); - } - return m_syncRoot; - } - } + internal object SyncRoot => + m_syncRoot ?? Interlocked.CompareExchange(ref m_syncRoot, new object(), null) ?? m_syncRoot; public override event ModuleResolveEventHandler? ModuleResolve { diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs index eab9a97e8ba8e4..de2f6cf1d2d197 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs @@ -170,7 +170,7 @@ internal static CustomAttributeEncoding TypeToCustomAttributeEncoding(RuntimeTyp if (type.IsClass) return CustomAttributeEncoding.Object; - if (type.IsInterface) + if (type.IsActualInterface) return CustomAttributeEncoding.Object; if (type.IsActualValueType) @@ -253,10 +253,10 @@ private RuntimeCustomAttributeData(RuntimeModule scope, MetadataToken caCtorToke m_scope = scope; m_ctor = (RuntimeConstructorInfo)RuntimeType.GetMethodBase(m_scope, caCtorToken)!; - if (m_ctor!.DeclaringType!.IsGenericType) + if (m_ctor.DeclaringType!.IsGenericType) { MetadataImport metadataScope = m_scope.MetadataImport; - Type attributeType = m_scope.ResolveType(metadataScope.GetParentToken(caCtorToken), null, null)!; + Type attributeType = m_scope.ResolveType(metadataScope.GetParentToken(caCtorToken), null, null); m_ctor = (RuntimeConstructorInfo)m_scope.ResolveMethod(caCtorToken, attributeType.GenericTypeArguments, null)!.MethodHandle.GetMethodInfo(); } @@ -1270,12 +1270,12 @@ internal static object[] GetCustomAttributes(RuntimeType type, RuntimeType caTyp for (int i = 0; i < pcas.Count; i++) result.Add(pcas[i]); - while (type != (RuntimeType)typeof(object) && type != null) + do { AddCustomAttributes(ref result, type.GetRuntimeModule(), type.MetadataToken, caType, mustBeInheritable, result); mustBeInheritable = true; type = (type.BaseType as RuntimeType)!; - } + } while (type != (RuntimeType)typeof(object) && type != null); object[] typedResult = CreateAttributeArrayHelper(caType, result.Count); for (int i = 0; i < result.Count; i++) @@ -2263,7 +2263,7 @@ internal static bool IsDefined(RuntimeFieldInfo field, RuntimeType? caType) internal static StructLayoutAttribute? GetStructLayoutCustomAttribute(RuntimeType type) { - if (type.IsInterface || type.HasElementType || type.IsGenericParameter) + if (type.IsActualInterface || type.HasElementType || type.IsGenericParameter) return null; LayoutKind layoutKind = LayoutKind.Auto; diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.CoreCLR.cs index a4bd430b620082..3a72a2e1174e4b 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.CoreCLR.cs @@ -105,7 +105,7 @@ Signature LazyCreateSignature() internal RuntimeMethodInfo? GetParentDefinition() { - if (!IsVirtual || m_declaringType.IsInterface) + if (!IsVirtual || m_declaringType.IsActualInterface) return null; RuntimeType? parent = (RuntimeType?)m_declaringType.BaseType; @@ -323,7 +323,7 @@ internal void InvokePropertySetter(object? obj, BindingFlags invokeAttr, Binder? public override MethodInfo GetBaseDefinition() { - if (!IsVirtual || IsStatic || m_declaringType == null || m_declaringType.IsInterface) + if (!IsVirtual || IsStatic || m_declaringType == null || m_declaringType.IsActualInterface) return this; int slot = RuntimeMethodHandle.GetSlot(this); diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs index 51b1f84864b1a9..8666910e37318b 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs @@ -305,7 +305,7 @@ internal ReadOnlySpan GetIndexParametersSpan() Array.Empty(); for (int i = 0; i < propParams.Length; i++) - propParams[i] = new RuntimeParameterInfo((RuntimeParameterInfo)methParams![i], this); + propParams[i] = new RuntimeParameterInfo((RuntimeParameterInfo)methParams[i], this); m_parameters = propParams; } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs index b9b6dbb87947c0..ba703738d3c7c3 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs @@ -61,6 +61,15 @@ internal enum CorInfoContinuationFlags // OSR method saved in the beginning of 'Data', or -1 if the continuation // belongs to a tier 0 method. CORINFO_CONTINUATION_OSR_IL_OFFSET_IN_DATA = 4, + // If this bit is set the continuation should continue on the thread + // pool. + CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL = 8, + // If this bit is set the continuation has a SynchronizationContext + // that we should continue on. + CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT = 16, + // If this bit is set the continuation has a TaskScheduler + // that we should continue on. + CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER = 32, } internal sealed unsafe class Continuation @@ -93,6 +102,29 @@ internal sealed unsafe class Continuation // public byte[]? Data; public object?[]? GCData; + + public object GetContinuationContext() + { + int index = 0; + if ((Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA) != 0) + index++; + if ((Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION) != 0) + index++; + Debug.Assert(GCData != null && GCData.Length > index); + object? continuationContext = GCData[index]; + Debug.Assert(continuationContext != null); + return continuationContext; + } + + public void SetException(Exception ex) + { + int index = 0; + if ((Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA) != 0) + index++; + + Debug.Assert(GCData != null && GCData.Length > index); + GCData[index] = ex; + } } public static partial class AsyncHelpers @@ -171,122 +203,338 @@ private static unsafe object AllocContinuationResultBox(void* ptr) return RuntimeTypeHandle.InternalAllocNoChecks((MethodTable*)pMT); } - // wrapper to await a notifier - private struct AwaitableProxy : ICriticalNotifyCompletion + private interface IThunkTaskOps { - private readonly INotifyCompletion _notifier; + static abstract Action GetContinuationAction(T task); + static abstract Continuation GetContinuationState(T task); + static abstract void SetContinuationState(T task, Continuation value); + static abstract bool SetCompleted(T task, Continuation continuation); + static abstract void PostToSyncContext(T task, SynchronizationContext syncCtx); + } + + private sealed class ThunkTask : Task + { + public ThunkTask() + { + // We use the base Task's state object field to store the Continuation while posting the task around. + // Ensure that state object isn't published out for others to see. + Debug.Assert((m_stateFlags & (int)InternalTaskOptions.PromiseTask) != 0, "Expected state flags to already be configured."); + Debug.Assert(m_stateObject is null, "Expected to be able to use the state object field for Continuation."); + m_action = MoveNext; + m_stateFlags |= (int)InternalTaskOptions.HiddenState; + } - public AwaitableProxy(INotifyCompletion notifier) + internal override void ExecuteFromThreadPool(Thread threadPoolThread) { - _notifier = notifier; + MoveNext(); } - public bool IsCompleted => false; + private void MoveNext() + { + ThunkTaskCore.MoveNext, Ops>(this); + } - public void OnCompleted(Action action) + public void HandleSuspended() { - _notifier!.OnCompleted(action); + ThunkTaskCore.HandleSuspended, Ops>(this); } - public AwaitableProxy GetAwaiter() { return this; } + private static readonly SendOrPostCallback s_postCallback = static state => + { + Debug.Assert(state is ThunkTask); + ((ThunkTask)state).MoveNext(); + }; - public void UnsafeOnCompleted(Action action) + private struct Ops : IThunkTaskOps> { - if (_notifier is ICriticalNotifyCompletion criticalNotification) + public static Action GetContinuationAction(ThunkTask task) => (Action)task.m_action!; + public static void MoveNext(ThunkTask task) => task.MoveNext(); + public static Continuation GetContinuationState(ThunkTask task) => (Continuation)task.m_stateObject!; + public static void SetContinuationState(ThunkTask task, Continuation value) { - criticalNotification.UnsafeOnCompleted(action); + task.m_stateObject = value; + } + + public static bool SetCompleted(ThunkTask task, Continuation continuation) + { + T result; + if (RuntimeHelpers.IsReferenceOrContainsReferences()) + { + if (typeof(T).IsValueType) + { + result = Unsafe.As(ref continuation.GCData![0]!.GetRawData()); + } + else + { + result = Unsafe.As(ref continuation.GCData![0]!); + } + } + else + { + result = Unsafe.As(ref continuation.Data![0]); + } + + return task.TrySetResult(result); } - else + + public static void PostToSyncContext(ThunkTask task, SynchronizationContext syncContext) { - _notifier!.OnCompleted(action); + syncContext.Post(s_postCallback, task); } } - - public void GetResult() { } } - private static Continuation UnlinkHeadContinuation(out AwaitableProxy awaitableProxy) + private sealed class ThunkTask : Task { - ref RuntimeAsyncAwaitState state = ref t_runtimeAsyncAwaitState; - awaitableProxy = new AwaitableProxy(state.Notifier!); - state.Notifier = null; - - Continuation sentinelContinuation = state.SentinelContinuation!; - Continuation head = sentinelContinuation.Next!; - sentinelContinuation.Next = null; - return head; - } + public ThunkTask() + { + // We use the base Task's state object field to store the Continuation while posting the task around. + // Ensure that state object isn't published out for others to see. + Debug.Assert((m_stateFlags & (int)InternalTaskOptions.PromiseTask) != 0, "Expected state flags to already be configured."); + Debug.Assert(m_stateObject is null, "Expected to be able to use the state object field for Continuation."); + m_action = MoveNext; + m_stateFlags |= (int)InternalTaskOptions.HiddenState; + } - // When a Task-returning thunk gets a continuation result - // it calls here to make a Task that awaits on the current async state. - // NOTE: This cannot be Runtime Async. Must use C# state machine or make one by hand. - private static async Task FinalizeTaskReturningThunk(Continuation continuation) - { - Continuation finalContinuation = new Continuation(); + internal override void ExecuteFromThreadPool(Thread threadPoolThread) + { + MoveNext(); + } - // Note that the exact location the return value is placed is tied - // into getAsyncResumptionStub in the VM, so do not change this - // without also changing that code (and the JIT). - if (RuntimeHelpers.IsReferenceOrContainsReferences()) + private void MoveNext() { - finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA | CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION; - finalContinuation.GCData = new object[1]; + ThunkTaskCore.MoveNext(this); } - else + + public void HandleSuspended() { - finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION; - finalContinuation.Data = new byte[Unsafe.SizeOf()]; + ThunkTaskCore.HandleSuspended(this); } - continuation.Next = finalContinuation; + private static readonly SendOrPostCallback s_postCallback = static state => + { + Debug.Assert(state is ThunkTask); + ((ThunkTask)state).MoveNext(); + }; - while (true) + private struct Ops : IThunkTaskOps { - Continuation headContinuation = UnlinkHeadContinuation(out var awaitableProxy); - await awaitableProxy; - Continuation? finalResult = DispatchContinuations(headContinuation); - if (finalResult != null) + public static Action GetContinuationAction(ThunkTask task) => (Action)task.m_action!; + public static void MoveNext(ThunkTask task) => task.MoveNext(); + public static Continuation GetContinuationState(ThunkTask task) => (Continuation)task.m_stateObject!; + public static void SetContinuationState(ThunkTask task, Continuation value) { - Debug.Assert(finalResult == finalContinuation); - if (RuntimeHelpers.IsReferenceOrContainsReferences()) + task.m_stateObject = value; + } + + public static bool SetCompleted(ThunkTask task, Continuation continuation) + { + return task.TrySetResult(); + } + + public static void PostToSyncContext(ThunkTask task, SynchronizationContext syncContext) + { + syncContext.Post(s_postCallback, task); + } + } + } + + private static class ThunkTaskCore + { + public static unsafe void MoveNext(T task) where T : Task where TOps : IThunkTaskOps + { + ExecutionAndSyncBlockStore contexts = default; + contexts.Push(); + Continuation continuation = TOps.GetContinuationState(task); + + while (true) + { + try { - if (typeof(T).IsValueType) + Continuation? newContinuation = continuation.Resume(continuation); + + if (newContinuation != null) { - return Unsafe.As(ref finalResult.GCData![0]!.GetRawData()); + newContinuation.Next = continuation.Next; + HandleSuspended(task); + contexts.Pop(); + return; } - return Unsafe.As(ref finalResult.GCData![0]!); + Debug.Assert(continuation.Next != null); + continuation = continuation.Next; + } + catch (Exception ex) + { + Continuation nextContinuation = UnwindToPossibleHandler(continuation); + if (nextContinuation.Resume == null) + { + // Tail of AsyncTaskMethodBuilderT.SetException + bool successfullySet = ex is OperationCanceledException oce ? + task.TrySetCanceled(oce.CancellationToken, oce) : + task.TrySetException(ex); + + contexts.Pop(); + + if (!successfullySet) + { + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted); + } + + return; + } + + nextContinuation.SetException(ex); + + continuation = nextContinuation; + } + + if (continuation.Resume == null) + { + bool successfullySet = TOps.SetCompleted(task, continuation); + + contexts.Pop(); + + if (!successfullySet) + { + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted); + } + + return; + } + + if (QueueContinuationFollowUpActionIfNecessary(task, continuation)) + { + contexts.Pop(); + return; + } + } + } + + private static Continuation UnwindToPossibleHandler(Continuation continuation) + { + while (true) + { + Debug.Assert(continuation.Next != null); + continuation = continuation.Next; + if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION) != 0) + return continuation; + } + } + + public static void HandleSuspended(T task) where T : Task where TOps : IThunkTaskOps + { + Continuation headContinuation = UnlinkHeadContinuation(out INotifyCompletion? notifier); + + // Head continuation should be the result of async call to AwaitAwaiter or UnsafeAwaitAwaiter. + // These never have special continuation handling. + const CorInfoContinuationFlags continueFlags = + CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT | + CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL | + CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER; + Debug.Assert((headContinuation.Flags & continueFlags) == 0); + + TOps.SetContinuationState(task, headContinuation); + + try + { + if (notifier is ICriticalNotifyCompletion crit) + { + crit.UnsafeOnCompleted(TOps.GetContinuationAction(task)); } else { - return Unsafe.As(ref finalResult.Data![0]); + Debug.Assert(notifier != null); + notifier.OnCompleted(TOps.GetContinuationAction(task)); } } + catch (Exception ex) + { + Task.ThrowAsync(ex, targetContext: null); + } } - } - private static async Task FinalizeTaskReturningThunk(Continuation continuation) - { - Continuation finalContinuation = new Continuation + private static Continuation UnlinkHeadContinuation(out INotifyCompletion? notifier) { - Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION, - }; - continuation.Next = finalContinuation; + ref RuntimeAsyncAwaitState state = ref t_runtimeAsyncAwaitState; + notifier = state.Notifier; + state.Notifier = null; + + Continuation sentinelContinuation = state.SentinelContinuation!; + Continuation head = sentinelContinuation.Next!; + sentinelContinuation.Next = null; + return head; + } - while (true) + private static bool QueueContinuationFollowUpActionIfNecessary(T task, Continuation continuation) where T : Task where TOps : IThunkTaskOps { - Continuation headContinuation = UnlinkHeadContinuation(out var awaitableProxy); - await awaitableProxy; - Continuation? finalResult = DispatchContinuations(headContinuation); - if (finalResult != null) + if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL) != 0) { - Debug.Assert(finalResult == finalContinuation); - return; + SynchronizationContext? ctx = Thread.CurrentThreadAssumedInitialized._synchronizationContext; + if (ctx == null || ctx.GetType() == typeof(SynchronizationContext)) + { + TaskScheduler? sched = TaskScheduler.InternalCurrent; + if (sched == null || sched == TaskScheduler.Default) + { + // Can inline + return false; + } + } + + TOps.SetContinuationState(task, continuation); + ThreadPool.UnsafeQueueUserWorkItemInternal(task, preferLocal: true); + return true; } + + if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT) != 0) + { + object continuationContext = continuation.GetContinuationContext(); + Debug.Assert(continuationContext is SynchronizationContext { }); + SynchronizationContext continuationSyncCtx = (SynchronizationContext)continuationContext; + + if (continuationSyncCtx == Thread.CurrentThreadAssumedInitialized._synchronizationContext) + { + // Inline + return false; + } + + TOps.SetContinuationState(task, continuation); + + try + { + TOps.PostToSyncContext(task, continuationSyncCtx); + } + catch (Exception ex) + { + Task.ThrowAsync(ex, targetContext: null); + } + + return true; + } + + if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER) != 0) + { + object continuationContext = continuation.GetContinuationContext(); + Debug.Assert(continuationContext is TaskScheduler { }); + TaskScheduler sched = (TaskScheduler)continuationContext; + + TOps.SetContinuationState(task, continuation); + // TODO: We do not need TaskSchedulerAwaitTaskContinuation here, just need to refactor its Run method... + var taskSchedCont = new TaskSchedulerAwaitTaskContinuation(sched, TOps.GetContinuationAction(task), flowExecutionContext: false); + taskSchedCont.Run(Task.CompletedTask, canInlineContinuationTask: true); + + return true; + } + + return false; } } - private static async ValueTask FinalizeValueTaskReturningThunk(Continuation continuation) + // Change return type to ThunkTask -- no benefit since this is used for Task returning thunks only +#pragma warning disable CA1859 + // When a Task-returning thunk gets a continuation result + // it calls here to make a Task that awaits on the current async state. + private static Task FinalizeTaskReturningThunk(Continuation continuation) { Continuation finalContinuation = new Continuation(); @@ -306,32 +554,12 @@ private static async Task FinalizeTaskReturningThunk(Continuation continuation) continuation.Next = finalContinuation; - while (true) - { - Continuation headContinuation = UnlinkHeadContinuation(out var awaitableProxy); - await awaitableProxy; - Continuation? finalResult = DispatchContinuations(headContinuation); - if (finalResult != null) - { - Debug.Assert(finalResult == finalContinuation); - if (RuntimeHelpers.IsReferenceOrContainsReferences()) - { - if (typeof(T).IsValueType) - { - return Unsafe.As(ref finalResult.GCData![0]!.GetRawData()); - } - - return Unsafe.As(ref finalResult.GCData![0]!); - } - else - { - return Unsafe.As(ref finalResult.Data![0]); - } - } - } + ThunkTask result = new(); + result.HandleSuspended(); + return result; } - private static async ValueTask FinalizeValueTaskReturningThunk(Continuation continuation) + private static Task FinalizeTaskReturningThunk(Continuation continuation) { Continuation finalContinuation = new Continuation { @@ -339,89 +567,82 @@ private static async ValueTask FinalizeValueTaskReturningThunk(Continuation cont }; continuation.Next = finalContinuation; - while (true) - { - Continuation headContinuation = UnlinkHeadContinuation(out var awaitableProxy); - await awaitableProxy; - Continuation? finalResult = DispatchContinuations(headContinuation); - if (finalResult != null) - { - Debug.Assert(finalResult == finalContinuation); - return; - } - } + ThunkTask result = new(); + result.HandleSuspended(); + return result; } - // Return a continuation object if that is the one which has the final - // result of the Task, if the real output of the series of continuations was - // an exception, it is allowed to propagate out. - // OR - // return NULL to indicate that this isn't yet done. - private static unsafe Continuation? DispatchContinuations(Continuation? continuation) + private static ValueTask FinalizeValueTaskReturningThunk(Continuation continuation) { - Debug.Assert(continuation != null); - - while (true) - { - Continuation? newContinuation; - try - { - newContinuation = continuation.Resume(continuation); - } - catch (Exception ex) - { - continuation = UnwindToPossibleHandler(continuation); - if (continuation.Resume == null) - { - throw; - } - - continuation.GCData![(continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA) != 0 ? 1 : 0] = ex; - continue; - } - - if (newContinuation != null) - { - newContinuation.Next = continuation.Next; - return null; - } + // We only come to these methods in the expensive case (already + // suspended), so ValueTask optimization here is not relevant. + return new ValueTask(FinalizeTaskReturningThunk(continuation)); + } - continuation = continuation.Next; - Debug.Assert(continuation != null); + private static ValueTask FinalizeValueTaskReturningThunk(Continuation continuation) + { + return new ValueTask(FinalizeTaskReturningThunk(continuation)); + } - if (continuation.Resume == null) - { - return continuation; // Return the result containing Continuation - } - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ExecutionContext? CaptureExecutionContext() + { + return Thread.CurrentThreadAssumedInitialized._executionContext; } - private static Continuation UnwindToPossibleHandler(Continuation continuation) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void RestoreExecutionContext(ExecutionContext? previousExecCtx) { - while (true) + Thread thread = Thread.CurrentThreadAssumedInitialized; + ExecutionContext? currentExecCtx = thread._executionContext; + if (previousExecCtx != currentExecCtx) { - Debug.Assert(continuation.Next != null); - continuation = continuation.Next; - if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION) != 0) - return continuation; + ExecutionContext.RestoreChangedContextToThread(thread, previousExecCtx, currentExecCtx); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ExecutionContext? CaptureExecutionContext() + private static void CaptureContexts(out ExecutionContext? execCtx, out SynchronizationContext? syncCtx) { - return Thread.CurrentThreadAssumedInitialized._executionContext; + Thread thread = Thread.CurrentThreadAssumedInitialized; + execCtx = thread._executionContext; + syncCtx = thread._synchronizationContext; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void RestoreExecutionContext(ExecutionContext? previousExecutionCtx) + private static void RestoreContexts(bool suspended, ExecutionContext? previousExecCtx, SynchronizationContext? previousSyncCtx) { Thread thread = Thread.CurrentThreadAssumedInitialized; - ExecutionContext? currentExecutionCtx = thread._executionContext; - if (previousExecutionCtx != currentExecutionCtx) + if (!suspended && previousSyncCtx != thread._synchronizationContext) { - ExecutionContext.RestoreChangedContextToThread(thread, previousExecutionCtx, currentExecutionCtx); + thread._synchronizationContext = previousSyncCtx; } + + ExecutionContext? currentExecCtx = thread._executionContext; + if (previousExecCtx != currentExecCtx) + { + ExecutionContext.RestoreChangedContextToThread(thread, previousExecCtx, currentExecCtx); + } + } + + private static void CaptureContinuationContext(SynchronizationContext syncCtx, ref object context, ref CorInfoContinuationFlags flags) + { + if (syncCtx != null && syncCtx.GetType() != typeof(SynchronizationContext)) + { + flags |= CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT; + context = syncCtx; + return; + } + + TaskScheduler? sched = TaskScheduler.InternalCurrent; + if (sched != null && sched != TaskScheduler.Default) + { + flags |= CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER; + context = sched; + return; + } + + flags |= CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL; } } } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index 91582d975d9ee0..95ceb043c386cc 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -488,15 +488,41 @@ public static IntPtr AllocateTypeAssociatedMemory(Type type, int size) private static partial IntPtr AllocateTypeAssociatedMemory(QCallTypeHandle type, uint size); [MethodImpl(MethodImplOptions.InternalCall)] - private static extern IntPtr AllocTailCallArgBufferWorker(int size, IntPtr gcDesc); + private static extern unsafe TailCallArgBuffer* GetTailCallArgBuffer(); - private static IntPtr AllocTailCallArgBuffer(int size, IntPtr gcDesc) + [LibraryImport(QCall, EntryPoint = "TailCallHelp_AllocTailCallArgBufferInternal")] + private static unsafe partial TailCallArgBuffer* AllocTailCallArgBufferInternal(int size); + + private const int TAILCALLARGBUFFER_ACTIVE = 0; + // private const int TAILCALLARGBUFFER_INSTARG_ONLY = 1; + private const int TAILCALLARGBUFFER_INACTIVE = 2; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] // To allow unrolling of Span.Clear + private static unsafe TailCallArgBuffer* AllocTailCallArgBuffer(int size, IntPtr gcDesc) { - IntPtr buffer = AllocTailCallArgBufferWorker(size, gcDesc); - if (buffer == IntPtr.Zero) + TailCallArgBuffer* buffer = GetTailCallArgBuffer(); + if (buffer != null && buffer->Size >= size) + { + buffer->State = TAILCALLARGBUFFER_INACTIVE; + } + else { - throw new OutOfMemoryException(); + buffer = AllocTailCallArgBufferWorker(size); + + [MethodImpl(MethodImplOptions.NoInlining)] + static TailCallArgBuffer* AllocTailCallArgBufferWorker(int size) => AllocTailCallArgBufferInternal(size); } + Debug.Assert(buffer != null); + Debug.Assert(buffer->Size >= size); + Debug.Assert(buffer->State == TAILCALLARGBUFFER_INACTIVE); + + buffer->GCDesc = gcDesc; + + new Span(buffer + 1, size - sizeof(TailCallArgBuffer)).Clear(); + + // The buffer is now ready to be used. + buffer->State = TAILCALLARGBUFFER_ACTIVE; + return buffer; } @@ -506,7 +532,7 @@ private static IntPtr AllocTailCallArgBuffer(int size, IntPtr gcDesc) [StackTraceHidden] private static unsafe void DispatchTailCalls( IntPtr callersRetAddrSlot, - delegate* callTarget, + delegate* callTarget, ref byte retVal) { IntPtr callersRetAddr; @@ -537,11 +563,8 @@ private static unsafe void DispatchTailCalls( { tls->Frame = prevFrame; - // If the arg buffer is reporting inst argument, it is safe to abandon it now - if (tls->ArgBuffer != IntPtr.Zero && *(int*)tls->ArgBuffer == 1 /* TAILCALLARGBUFFER_INSTARG_ONLY */) - { - *(int*)tls->ArgBuffer = 2 /* TAILCALLARGBUFFER_ABANDONED */; - } + // If the arg buffer is reporting inst argument (TAILCALLARGBUFFER_INSTARG_ONLY), it is safe to abandon it now. + tls->ArgBuffer->State = TAILCALLARGBUFFER_INACTIVE; } } @@ -1217,13 +1240,22 @@ private static bool CanCastToWorker(TypeHandle srcTH, TypeHandle destTH, bool nu internal unsafe struct PortableTailCallFrame { public IntPtr TailCallAwareReturnAddress; - public delegate* NextCall; + public delegate* NextCall; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct TailCallArgBuffer + { + public int State; + public int Size; + public IntPtr GCDesc; + // Args } [StructLayout(LayoutKind.Sequential)] internal unsafe struct TailCallTls { public PortableTailCallFrame* Frame; - public IntPtr ArgBuffer; + public TailCallArgBuffer* ArgBuffer; } } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs index df3da7a876b787..86cb928e36e89d 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs @@ -51,9 +51,9 @@ class AsmOffsets public const int OFFSETOF__REGDISPLAY__SP = 0xba8; public const int OFFSETOF__REGDISPLAY__ControlPC = 0xbb0; #elif TARGET_WASM - public const int SIZEOF__REGDISPLAY = 0x3c; - public const int OFFSETOF__REGDISPLAY__SP = 0x34; - public const int OFFSETOF__REGDISPLAY__ControlPC = 0x38; + public const int SIZEOF__REGDISPLAY = 0x38; + public const int OFFSETOF__REGDISPLAY__SP = 0x30; + public const int OFFSETOF__REGDISPLAY__ControlPC = 0x34; #endif #if TARGET_64BIT @@ -73,9 +73,14 @@ class AsmOffsets public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x3d0; #else // TARGET_64BIT public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4; +#if FEATURE_INTERPRETER + public const int SIZEOF__StackFrameIterator = 0xdc; + public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xd8; +#else public const int SIZEOF__StackFrameIterator = 0xcc; - public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xba; public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xc8; +#endif + public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xba; #endif // TARGET_64BIT #else // DEBUG @@ -117,9 +122,9 @@ class AsmOffsets public const int OFFSETOF__REGDISPLAY__SP = 0xba0; public const int OFFSETOF__REGDISPLAY__ControlPC = 0xba8; #elif TARGET_WASM - public const int SIZEOF__REGDISPLAY = 0x3c; - public const int OFFSETOF__REGDISPLAY__SP = 0x34; - public const int OFFSETOF__REGDISPLAY__ControlPC = 0x38; + public const int SIZEOF__REGDISPLAY = 0x34; + public const int OFFSETOF__REGDISPLAY__SP = 0x2c; + public const int OFFSETOF__REGDISPLAY__ControlPC = 0x30; #endif #if TARGET_64BIT @@ -139,9 +144,14 @@ class AsmOffsets public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x3c8; #else // TARGET_64BIT public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4; +#if FEATURE_INTERPRETER + public const int SIZEOF__StackFrameIterator = 0xd4; + public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xd0; +#else public const int SIZEOF__StackFrameIterator = 0xc4; - public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xb2; public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xc0; +#endif + public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xb2; #endif // TARGET_64BIT #endif // DEBUG @@ -167,7 +177,7 @@ class AsmOffsets #elif TARGET_LOONGARCH64 public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x520; #elif TARGET_WASM - public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x08; + public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x04; #endif #if TARGET_AMD64 diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/DynamicInterfaceCastableHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/DynamicInterfaceCastableHelpers.cs index 0314219f14ce97..260534b1ce799a 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/DynamicInterfaceCastableHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/DynamicInterfaceCastableHelpers.cs @@ -30,7 +30,7 @@ internal static bool IsInterfaceImplemented(IDynamicInterfaceCastable castable, throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, castable.GetType(), interfaceType)); RuntimeType implType = handle.GetRuntimeType(); - if (!implType.IsInterface) + if (!implType.IsActualInterface) throw new InvalidOperationException(SR.Format(SR.IDynamicInterfaceCastable_NotInterface, implType.ToString())); if (!implType.IsDefined(typeof(DynamicInterfaceCastableImplementationAttribute), inherit: false)) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Java/JavaMarshal.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Java/JavaMarshal.CoreCLR.cs similarity index 81% rename from src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Java/JavaMarshal.cs rename to src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Java/JavaMarshal.CoreCLR.cs index 42f3b023a4803c..357e3575812e5c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Java/JavaMarshal.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Java/JavaMarshal.CoreCLR.cs @@ -12,39 +12,24 @@ public static partial class JavaMarshal { public static unsafe void Initialize(delegate* unmanaged markCrossReferences) { -#if NATIVEAOT - throw new NotImplementedException(); -#elif FEATURE_JAVAMARSHAL ArgumentNullException.ThrowIfNull(markCrossReferences); if (!InitializeInternal((IntPtr)markCrossReferences)) { throw new InvalidOperationException(SR.InvalidOperation_ReinitializeJavaMarshal); } -#else - throw new PlatformNotSupportedException(); -#endif } public static unsafe GCHandle CreateReferenceTrackingHandle(object obj, void* context) { -#if NATIVEAOT - throw new NotImplementedException(); -#elif FEATURE_JAVAMARSHAL ArgumentNullException.ThrowIfNull(obj); IntPtr handle = CreateReferenceTrackingHandleInternal(ObjectHandleOnStack.Create(ref obj), context); return GCHandle.FromIntPtr(handle); -#else - throw new PlatformNotSupportedException(); -#endif } public static unsafe void* GetContext(GCHandle obj) { -#if NATIVEAOT - throw new NotImplementedException(); -#elif FEATURE_JAVAMARSHAL IntPtr handle = GCHandle.ToIntPtr(obj); if (handle == IntPtr.Zero || !GetContextInternal(handle, out void* context)) @@ -53,18 +38,12 @@ public static unsafe GCHandle CreateReferenceTrackingHandle(object obj, void* co } return context; -#else - throw new PlatformNotSupportedException(); -#endif } public static unsafe void FinishCrossReferenceProcessing( MarkCrossReferencesArgs* crossReferences, ReadOnlySpan unreachableObjectHandles) { -#if NATIVEAOT - throw new NotImplementedException(); -#elif FEATURE_JAVAMARSHAL fixed (GCHandle* pHandles = unreachableObjectHandles) { FinishCrossReferenceProcessing( @@ -72,12 +51,8 @@ public static unsafe void FinishCrossReferenceProcessing( (nuint)unreachableObjectHandles.Length, pHandles); } -#else - throw new PlatformNotSupportedException(); -#endif } -#if FEATURE_JAVAMARSHAL && !NATIVEAOT [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "JavaMarshal_Initialize")] [return: MarshalAs(UnmanagedType.Bool)] private static partial bool InitializeInternal(IntPtr callback); @@ -92,6 +67,5 @@ public static unsafe void FinishCrossReferenceProcessing( [SuppressGCTransition] [return: MarshalAs(UnmanagedType.Bool)] private static unsafe partial bool GetContextInternal(IntPtr handle, out void* context); -#endif } } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs index bd2a5414a719aa..a0a16ed52480c7 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs @@ -110,9 +110,9 @@ internal Assembly LoadFromInMemoryModule(IntPtr moduleHandle) // This method is invoked by the VM to resolve a satellite assembly reference // after trying assembly resolution via Load override without success. - private static RuntimeAssembly? ResolveSatelliteAssembly(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName) + private static RuntimeAssembly? ResolveSatelliteAssembly(IntPtr gchAssemblyLoadContext, AssemblyName assemblyName) { - AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target)!; + AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchAssemblyLoadContext).Target)!; // Invoke the ResolveSatelliteAssembly method return context.ResolveSatelliteAssembly(assemblyName); @@ -120,25 +120,25 @@ internal Assembly LoadFromInMemoryModule(IntPtr moduleHandle) // This method is invoked by the VM when using the host-provided assembly load context // implementation. - private static IntPtr ResolveUnmanagedDll(string unmanagedDllName, IntPtr gchManagedAssemblyLoadContext) + private static IntPtr ResolveUnmanagedDll(string unmanagedDllName, IntPtr gchAssemblyLoadContext) { - AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target)!; + AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchAssemblyLoadContext).Target)!; return context.LoadUnmanagedDll(unmanagedDllName); } // This method is invoked by the VM to resolve a native library using the ResolvingUnmanagedDll event // after trying all other means of resolution. - private static IntPtr ResolveUnmanagedDllUsingEvent(string unmanagedDllName, Assembly assembly, IntPtr gchManagedAssemblyLoadContext) + private static IntPtr ResolveUnmanagedDllUsingEvent(string unmanagedDllName, Assembly assembly, IntPtr gchAssemblyLoadContext) { - AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target)!; + AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchAssemblyLoadContext).Target)!; return context.GetResolvedUnmanagedDll(assembly, unmanagedDllName); } // This method is invoked by the VM to resolve an assembly reference using the Resolving event // after trying assembly resolution via Load override and TPA load context without success. - private static RuntimeAssembly? ResolveUsingResolvingEvent(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName) + private static RuntimeAssembly? ResolveUsingResolvingEvent(IntPtr gchAssemblyLoadContext, AssemblyName assemblyName) { - AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target)!; + AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchAssemblyLoadContext).Target)!; // Invoke the AssemblyResolve event callbacks if wired up return context.ResolveUsingEvent(assemblyName); } diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index b8ae179ff25ce5..2bc71d3dfbd59f 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -1048,7 +1048,7 @@ internal bool IsNullHandle() public IntPtr GetFunctionPointer() { - IntPtr ptr = GetFunctionPointer(EnsureNonNullMethodInfo(m_value!).Value); + IntPtr ptr = GetFunctionPointer(EnsureNonNullMethodInfo(m_value).Value); GC.KeepAlive(m_value); return ptr; } diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index 5e872581a02f60..cc4ae643e1beb3 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -25,7 +25,7 @@ internal enum TypeNameFormatFlags FormatFullInst = 0x00000002, // Include namespace and assembly in generic types (regardless of other flag settings) FormatAssembly = 0x00000004, // Include assembly display name in type names FormatSignature = 0x00000008, // Include signature in method names - FormatNoVersion = 0x00000010, // Suppress version and culture information in all assembly names + // unused = 0x00000010, #if DEBUG FormatDebug = 0x00000020, // For debug printing of types only #endif @@ -34,13 +34,6 @@ internal enum TypeNameFormatFlags FormatGenericParam = 0x00000100, // Use !name and !!name for generic type and method parameters } - internal enum TypeNameKind - { - Name, - ToString, - FullName, - } - internal sealed partial class RuntimeType : TypeInfo, ICloneable { #region Definitions @@ -567,7 +560,7 @@ private void MergeWithGlobalList(T[] list) cachedMembers = cachedMembers2; } - Debug.Assert(cachedMembers![freeSlotIndex] == null); + Debug.Assert(cachedMembers[freeSlotIndex] == null); Volatile.Write(ref cachedMembers[freeSlotIndex], newMemberInfo); // value may be read outside of lock freeSlotIndex++; } @@ -586,7 +579,7 @@ private unsafe RuntimeMethodInfo[] PopulateMethods(Filter filter) RuntimeType declaringType = ReflectedType; Debug.Assert(declaringType != null); - if (declaringType.IsInterface) + if (declaringType.IsActualInterface) { #region IsInterface @@ -1005,7 +998,7 @@ private RuntimeType[] PopulateInterfaces(Filter filter) continue; } - Debug.Assert(interfaceType.IsInterface); + Debug.Assert(interfaceType.IsActualInterface); list.Add(interfaceType); } @@ -1035,7 +1028,7 @@ private RuntimeType[] PopulateInterfaces(Filter filter) for (int i = 0; i < constraints.Length; i++) { RuntimeType constraint = (RuntimeType)constraints[i]; - if (constraint.IsInterface) + if (constraint.IsActualInterface) al.Add(constraint); Type[] temp = constraint.GetInterfaces(); @@ -1120,7 +1113,7 @@ private RuntimeEventInfo[] PopulateEvents(Filter filter) RuntimeType declaringType = ReflectedType; ListBuilder list = default; - if (!declaringType.IsInterface) + if (!declaringType.IsActualInterface) { while (RuntimeTypeHandle.IsGenericVariable(declaringType)) declaringType = declaringType.GetBaseType()!; @@ -1213,7 +1206,7 @@ private RuntimePropertyInfo[] PopulateProperties(Filter filter) ListBuilder list = default; - if (!declaringType.IsInterface) + if (!declaringType.IsActualInterface) { while (RuntimeTypeHandle.IsGenericVariable(declaringType)) declaringType = declaringType.GetBaseType()!; @@ -1265,8 +1258,8 @@ private void PopulateProperties( int numVirtuals = RuntimeTypeHandle.GetNumVirtuals(declaringType); - Debug.Assert((declaringType.IsInterface && isInterface && csPropertyInfos == null) || - (!declaringType.IsInterface && !isInterface && usedSlots.Length >= numVirtuals)); + Debug.Assert((declaringType.IsActualInterface && isInterface && csPropertyInfos == null) || + (!declaringType.IsActualInterface && !isInterface && usedSlots.Length >= numVirtuals)); for (int i = 0; i < tkProperties.Length; i++) { @@ -1357,7 +1350,7 @@ private void PopulateProperties( for (int j = 0; j < list.Count; j++) { - if (propertyInfo.EqualsSig(list[j]!)) + if (propertyInfo.EqualsSig(list[j])) { duplicate = true; break; @@ -1408,7 +1401,8 @@ internal T[] GetMemberList(MemberListType listType, string? name, CacheType cach private RuntimeType? m_enclosingType; private TypeCode m_typeCode; private string? m_name; - private string? m_fullname; + private string? m_fullName; + private string? m_assemblyQualifiedName; private string? m_toString; private string? m_namespace; private readonly bool m_isGlobal; @@ -1438,8 +1432,10 @@ internal RuntimeTypeCache(RuntimeType runtimeType) #endregion #region Private Members - private string ConstructName([NotNull] ref string? name, TypeNameFormatFlags formatFlags) => - name ??= new RuntimeTypeHandle(m_runtimeType).ConstructName(formatFlags); + // This is the slow path for construction. Mark it to avoid inlining it into the caller. + [MethodImpl(MethodImplOptions.NoInlining)] + private string ConstructName(ref string? name, TypeNameFormatFlags formatFlags) => + name = new RuntimeTypeHandle(m_runtimeType).ConstructName(formatFlags); private T[] GetMemberList(ref MemberInfoCache? m_cache, MemberListType listType, string? name, CacheType cacheType) where T : MemberInfo @@ -1494,52 +1490,32 @@ internal Type[] FunctionPointerReturnAndParameterTypes } } - internal string? GetName(TypeNameKind kind) - { - switch (kind) - { - case TypeNameKind.Name: - // No namespace, full instantiation, and assembly. - return ConstructName(ref m_name, TypeNameFormatFlags.FormatBasic); - - case TypeNameKind.FullName: - // We exclude the types that contain generic parameters because their names cannot be roundtripped. - // We allow generic type definitions (and their refs, ptrs, and arrays) because their names can be roundtriped. - // Theoretically generic types instantiated with generic type definitions can be roundtripped, e.g. List`1. - // But these kind of types are useless, rare, and hard to identity. We would need to recursively examine all the - // generic arguments with the same criteria. We will exclude them unless we see a real user scenario. - if (!m_runtimeType.GetRootElementType().IsGenericTypeDefinition && m_runtimeType.ContainsGenericParameters) - return null; - - // Exclude function pointer; it requires a grammar update and parsing support for Type.GetType() and friends. - // See https://learn.microsoft.com/dotnet/framework/reflection-and-codedom/specifying-fully-qualified-type-names. - if (m_runtimeType.IsFunctionPointer) - return null; - - // No assembly. - return ConstructName(ref m_fullname, TypeNameFormatFlags.FormatNamespace | TypeNameFormatFlags.FormatFullInst); - - case TypeNameKind.ToString: - // No full instantiation and assembly. - return ConstructName(ref m_toString, TypeNameFormatFlags.FormatNamespace); - - default: - throw new InvalidOperationException(); - } - } + // No namespace, full instantiation, and assembly. + internal string GetName() => m_name ?? ConstructName(ref m_name, TypeNameFormatFlags.FormatBasic)!; + + // No assembly. + internal string? GetFullName() => m_fullName ?? + (IsFullNameRoundtripCompatible(m_runtimeType) + ? ConstructName(ref m_fullName, TypeNameFormatFlags.FormatNamespace | TypeNameFormatFlags.FormatFullInst) + : null); + + // No full instantiation and assembly. + internal string GetToString() => m_toString ?? ConstructName(ref m_toString, TypeNameFormatFlags.FormatNamespace)!; - internal string? GetNameSpace() + internal string? GetAssemblyQualifiedName() => m_assemblyQualifiedName ?? + (IsFullNameRoundtripCompatible(m_runtimeType) + ? ConstructName(ref m_assemblyQualifiedName, TypeNameFormatFlags.FormatNamespace | TypeNameFormatFlags.FormatFullInst | TypeNameFormatFlags.FormatAssembly) + : null); + + internal string? GetNamespace() { // @Optimization - Use ConstructName to populate m_namespace if (m_namespace == null) { - Type type = m_runtimeType; - + Type type = m_runtimeType.GetRootElementType(); if (type.IsFunctionPointer) return null; - type = type.GetRootElementType(); - while (type.IsNested) type = type.DeclaringType!; @@ -2721,7 +2697,7 @@ public override InterfaceMapping GetInterfaceMap([DynamicallyAccessedMembers(Dyn TypeHandle.VerifyInterfaceIsImplemented(ifaceRtTypeHandle); Debug.Assert(interfaceType.IsInterface); // VerifyInterfaceIsImplemented enforces this invariant - Debug.Assert(!IsInterface); // VerifyInterfaceIsImplemented enforces this invariant + Debug.Assert(!IsActualInterface); // VerifyInterfaceIsImplemented enforces this invariant // SZArrays implement the methods on IList`1, IEnumerable`1, and ICollection`1 with // SZArrayHelper and some runtime magic. We don't have accurate interface maps for them. @@ -2736,24 +2712,34 @@ public override InterfaceMapping GetInterfaceMap([DynamicallyAccessedMembers(Dyn im.InterfaceMethods = new MethodInfo[ifaceVirtualMethodCount]; im.TargetMethods = new MethodInfo[ifaceVirtualMethodCount]; + int actualCount = 0; for (int i = 0; i < ifaceVirtualMethodCount; i++) { RuntimeMethodHandleInternal ifaceRtMethodHandle = RuntimeTypeHandle.GetMethodAt(ifaceRtType, i); + // GetMethodAt may return null handle for methods that do not exist or are not supposed + // to be seen in reflection. One example is async variant methods. + // We do not record mapping for interface methods that do not exist. + if (ifaceRtMethodHandle.IsNullHandle()) + continue; + // GetMethodBase will convert this to the instantiating/unboxing stub if necessary MethodBase ifaceMethodBase = GetMethodBase(ifaceRtType, ifaceRtMethodHandle)!; Debug.Assert(ifaceMethodBase is RuntimeMethodInfo); - im.InterfaceMethods[i] = (MethodInfo)ifaceMethodBase; + im.InterfaceMethods[actualCount] = (MethodInfo)ifaceMethodBase; // If the impl is null, then virtual stub dispatch is active. RuntimeMethodHandleInternal classRtMethodHandle = TypeHandle.GetInterfaceMethodImplementation(ifaceRtTypeHandle, ifaceRtMethodHandle); if (classRtMethodHandle.IsNullHandle()) + { + actualCount++; continue; + } // If we resolved to an interface method, use the interface type as reflected type. Otherwise use `this`. RuntimeType reflectedType = RuntimeMethodHandle.GetDeclaringType(classRtMethodHandle); - if (!reflectedType.IsInterface) + if (!reflectedType.IsActualInterface) reflectedType = this; // GetMethodBase will convert this to the instantiating/unboxing stub if necessary @@ -2764,10 +2750,16 @@ public override InterfaceMapping GetInterfaceMap([DynamicallyAccessedMembers(Dyn // the TargetMethod provided to us by runtime internals may be a generic method instance, // potentially with invalid arguments. TargetMethods in the InterfaceMap should never be // instances, only definitions. - im.TargetMethods[i] = (targetMethod is { IsGenericMethod: true, IsGenericMethodDefinition: false }) + im.TargetMethods[actualCount++] = (targetMethod is { IsGenericMethod: true, IsGenericMethodDefinition: false }) ? targetMethod.GetGenericMethodDefinition() : targetMethod!; } + if (actualCount != ifaceVirtualMethodCount) + { + Array.Resize(ref im.InterfaceMethods, actualCount); + Array.Resize(ref im.TargetMethods, actualCount); + } + return im; } #endregion @@ -3318,28 +3310,15 @@ public override bool IsEquivalentTo([NotNullWhen(true)] Type? other) #region Name - public override string? FullName => GetCachedName(TypeNameKind.FullName); - - public override string? AssemblyQualifiedName - { - get - { - string? fullname = FullName; - - // FullName is null if this type contains generic parameters but is not a generic type definition - // or if it is a function pointer. - if (fullname == null) - return null; + public override string? FullName => Cache.GetFullName(); - return Assembly.CreateQualifiedName(Assembly.FullName, fullname); - } - } + public override string? AssemblyQualifiedName => Cache.GetAssemblyQualifiedName(); public override string? Namespace { get { - string? ns = Cache.GetNameSpace(); + string? ns = Cache.GetNamespace(); if (string.IsNullOrEmpty(ns)) { return null; @@ -3453,7 +3432,7 @@ internal unsafe bool IsActualEnum } } - internal new unsafe bool IsInterface + internal unsafe bool IsActualInterface { get { @@ -3811,17 +3790,11 @@ public override Type GetFunctionPointerReturnType() #endregion - public override string ToString() => GetCachedName(TypeNameKind.ToString)!; + public override string ToString() => Cache.GetToString(); #region MemberInfo Overrides - public override string Name => GetCachedName(TypeNameKind.Name)!; - - // This method looks like an attractive inline but expands to two calls, - // neither of which can be inlined or optimized further. So block it - // from inlining. - [MethodImpl(MethodImplOptions.NoInlining)] - private string? GetCachedName(TypeNameKind kind) => Cache.GetName(kind); + public override string Name => Cache.GetName(); public override Type? DeclaringType => Cache.GetEnclosingType(); @@ -3974,6 +3947,11 @@ internal object GetUninitializedObject() throw new MissingMethodException(SR.Format(SR.Arg_NoDefCTor, this)); } + if (IsByRefLike) + { + throw new NotSupportedException(SR.NotSupported_ByRefLike); + } + // Compat: allocation always takes place outside the try block so that OOMs // bubble up to the caller; the ctor invocation is within the try block so // that it can be wrapped in TIE if needed. @@ -3996,6 +3974,8 @@ internal object GetUninitializedObject() [DebuggerHidden] internal object? CreateInstanceOfT() { + Debug.Assert(!IsValueType); + ActivatorCache cache = GetOrCreateCacheEntry(); if (!cache.CtorIsPublic) diff --git a/src/coreclr/System.Private.CoreLib/src/System/String.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/String.CoreCLR.cs index e66db58ba95f52..a2c9f4f6e4e98c 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/String.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/String.CoreCLR.cs @@ -25,10 +25,10 @@ internal static unsafe string StrCns(uint rid, IntPtr scopeHandle) } [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern unsafe string FastAllocateString(MethodTable *pMT, int length); + internal static extern unsafe string FastAllocateString(MethodTable *pMT, nint length); [DebuggerHidden] - internal static unsafe string FastAllocateString(int length) + internal static unsafe string FastAllocateString(nint length) { return FastAllocateString(TypeHandle.TypeHandleOf().AsMethodTable(), length); } @@ -40,7 +40,7 @@ public static string Intern(string str) { ArgumentNullException.ThrowIfNull(str); Intern(new StringHandleOnStack(ref str!)); - return str!; + return str; } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "String_IsInterned")] diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index a6494bf27883e7..61e71adcff477a 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -944,7 +944,7 @@ private unsafe IntPtr ConvertArrayToNative(object pManagedHome, int dwFlags) } default: - throw new ArgumentException(SR.Arg_NDirectBadObject); + throw new ArgumentException(SR.Arg_PInvokeBadObject); } // marshal the object as C-style array (UnmanagedType.LPArray) @@ -1151,7 +1151,7 @@ internal IntPtr ConvertToNative(object pManagedHome, int dwFlags) else { // this type is not supported for AsAny marshaling - throw new ArgumentException(SR.Arg_NDirectBadObject); + throw new ArgumentException(SR.Arg_PInvokeBadObject); } } @@ -1351,26 +1351,20 @@ internal static void DestroyCleanupList(ref CleanupWorkListElement? pCleanupWork internal static Exception GetHRExceptionObject(int hr) { - Exception? ex = null; - GetHRExceptionObject(hr, ObjectHandleOnStack.Create(ref ex)); - ex!.InternalPreserveStackTrace(); - return ex!; + Exception ex = Marshal.GetExceptionForHR(hr)!; + ex.InternalPreserveStackTrace(); + return ex; } - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_GetHRExceptionObject")] - private static partial void GetHRExceptionObject(int hr, ObjectHandleOnStack throwable); - #if FEATURE_COMINTEROP - internal static Exception GetCOMHRExceptionObject(int hr, IntPtr pCPCMD, object pThis) + internal static Exception GetCOMHRExceptionObject(int hr, IntPtr pCPCMD, IntPtr pUnk) { - Exception? ex = null; - GetCOMHRExceptionObject(hr, pCPCMD, ObjectHandleOnStack.Create(ref pThis), ObjectHandleOnStack.Create(ref ex)); - ex!.InternalPreserveStackTrace(); - return ex!; + RuntimeMethodHandle handle = RuntimeMethodHandle.FromIntPtr(pCPCMD); + RuntimeType declaringType = RuntimeMethodHandle.GetDeclaringType(handle.GetMethodInfo()); + Exception ex = Marshal.GetExceptionForHR(hr, declaringType.GUID, pUnk)!; + ex.InternalPreserveStackTrace(); + return ex; } - - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_GetCOMHRExceptionObject")] - private static partial void GetCOMHRExceptionObject(int hr, IntPtr pCPCMD, ObjectHandleOnStack pThis, ObjectHandleOnStack throwable); #endif // FEATURE_COMINTEROP [ThreadStatic] @@ -1583,8 +1577,7 @@ internal static void ValidateObject(object obj, IntPtr pMD) internal static partial void ValidateByref(IntPtr byref, IntPtr pMD); // the byref is pinned so we can safely "cast" it to IntPtr [Intrinsic] - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern IntPtr GetStubContext(); + internal static IntPtr GetStubContext() => throw new UnreachableException(); // Unconditionally expanded intrinsic [MethodImpl(MethodImplOptions.NoInlining)] internal static void MulticastDebuggerTraceHelper(object o, int count) @@ -1596,11 +1589,10 @@ internal static void MulticastDebuggerTraceHelper(object o, int count) private static partial void MulticastDebuggerTraceHelperQCall(ObjectHandleOnStack obj, int count); [Intrinsic] - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern IntPtr NextCallReturnAddress(); + internal static IntPtr NextCallReturnAddress() => throw new UnreachableException(); // Unconditionally expanded intrinsic [Intrinsic] - internal static Continuation? AsyncCallContinuation() => null; + internal static Continuation? AsyncCallContinuation() => throw new UnreachableException(); // Unconditionally expanded intrinsic } // class StubHelpers #if FEATURE_COMINTEROP diff --git a/src/coreclr/binder/assemblybindercommon.cpp b/src/coreclr/binder/assemblybindercommon.cpp index 4ae509125ecb52..6321e50630bc45 100644 --- a/src/coreclr/binder/assemblybindercommon.cpp +++ b/src/coreclr/binder/assemblybindercommon.cpp @@ -27,7 +27,7 @@ #if !defined(DACCESS_COMPILE) #include "defaultassemblybinder.h" // Helper function in the VM, invoked by the Binder, to invoke the host assembly resolver -extern HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToBindWithin, +extern HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pAssemblyLoadContextToBindWithin, BINDER_SPACE::AssemblyName *pAssemblyName, DefaultAssemblyBinder *pDefaultBinder, AssemblyBinder *pBinder, @@ -1147,7 +1147,7 @@ namespace BINDER_SPACE #if !defined(DACCESS_COMPILE) -HRESULT AssemblyBinderCommon::BindUsingHostAssemblyResolver(/* in */ INT_PTR pManagedAssemblyLoadContextToBindWithin, +HRESULT AssemblyBinderCommon::BindUsingHostAssemblyResolver(/* in */ INT_PTR pAssemblyLoadContextToBindWithin, /* in */ AssemblyName *pAssemblyName, /* in */ DefaultAssemblyBinder *pDefaultBinder, /* in */ AssemblyBinder *pBinder, @@ -1155,11 +1155,11 @@ HRESULT AssemblyBinderCommon::BindUsingHostAssemblyResolver(/* in */ INT_PTR pMa { HRESULT hr = E_FAIL; - _ASSERTE(pManagedAssemblyLoadContextToBindWithin != (INT_PTR)NULL); + _ASSERTE(pAssemblyLoadContextToBindWithin != (INT_PTR)NULL); // RuntimeInvokeHostAssemblyResolver will perform steps 2-4 of CustomAssemblyBinder::BindAssemblyByName. BINDER_SPACE::Assembly *pLoadedAssembly = NULL; - hr = RuntimeInvokeHostAssemblyResolver(pManagedAssemblyLoadContextToBindWithin, + hr = RuntimeInvokeHostAssemblyResolver(pAssemblyLoadContextToBindWithin, pAssemblyName, pDefaultBinder, pBinder, &pLoadedAssembly); if (SUCCEEDED(hr)) { @@ -1297,7 +1297,7 @@ HRESULT AssemblyBinderCommon::CreateDefaultBinder(DefaultAssemblyBinder** ppDefa hr = pApplicationContext->Init(); if (SUCCEEDED(hr)) { - pBinder->SetManagedAssemblyLoadContext((INT_PTR)NULL); + pBinder->SetAssemblyLoadContext((INT_PTR)NULL); *ppDefaultBinder = pBinder.Extract(); } } diff --git a/src/coreclr/binder/customassemblybinder.cpp b/src/coreclr/binder/customassemblybinder.cpp index 99297c2bd9ce31..950e462d512ae5 100644 --- a/src/coreclr/binder/customassemblybinder.cpp +++ b/src/coreclr/binder/customassemblybinder.cpp @@ -72,7 +72,7 @@ HRESULT CustomAssemblyBinder::BindUsingAssemblyName(BINDER_SPACE::AssemblyName* // of what to do next. The host-overridden binder can either fail the bind or return reference to an existing assembly // that has been loaded. // - hr = AssemblyBinderCommon::BindUsingHostAssemblyResolver(GetManagedAssemblyLoadContext(), pAssemblyName, + hr = AssemblyBinderCommon::BindUsingHostAssemblyResolver(GetAssemblyLoadContext(), pAssemblyName, m_pDefaultBinder, this, &pCoreCLRFoundAssembly); if (SUCCEEDED(hr)) { @@ -178,7 +178,7 @@ HRESULT CustomAssemblyBinder::SetupContext(DefaultAssemblyBinder *pDefaultBinder // Save the reference to the IntPtr for GCHandle for the managed // AssemblyLoadContext instance - pBinder->SetManagedAssemblyLoadContext(ptrAssemblyLoadContext); + pBinder->SetAssemblyLoadContext(ptrAssemblyLoadContext); if (pLoaderAllocator != NULL) { @@ -247,16 +247,16 @@ CustomAssemblyBinder::CustomAssemblyBinder() void CustomAssemblyBinder::ReleaseLoadContext() { - VERIFY(GetManagedAssemblyLoadContext() != (INT_PTR)NULL); + VERIFY(GetAssemblyLoadContext() != (INT_PTR)NULL); VERIFY(m_ptrManagedStrongAssemblyLoadContext != (INT_PTR)NULL); // This method is called to release the weak and strong handles on the managed AssemblyLoadContext // once the Unloading event has been fired - OBJECTHANDLE handle = reinterpret_cast(GetManagedAssemblyLoadContext()); + OBJECTHANDLE handle = reinterpret_cast(GetAssemblyLoadContext()); DestroyLongWeakHandle(handle); handle = reinterpret_cast(m_ptrManagedStrongAssemblyLoadContext); DestroyHandle(handle); - SetManagedAssemblyLoadContext((INT_PTR)NULL); + SetAssemblyLoadContext((INT_PTR)NULL); // The AssemblyLoaderAllocator is in a process of shutdown and should not be used // after this point. diff --git a/src/coreclr/binder/defaultassemblybinder.cpp b/src/coreclr/binder/defaultassemblybinder.cpp index 54a70e51f05ece..9900da40a7d263 100644 --- a/src/coreclr/binder/defaultassemblybinder.cpp +++ b/src/coreclr/binder/defaultassemblybinder.cpp @@ -62,8 +62,8 @@ HRESULT DefaultAssemblyBinder::BindUsingAssemblyName(BINDER_SPACE::AssemblyName // // Attempt to resolve the assembly via managed ALC instance. This can either fail the bind or return reference to an existing // assembly that has been loaded - INT_PTR pManagedAssemblyLoadContext = GetManagedAssemblyLoadContext(); - if (pManagedAssemblyLoadContext == (INT_PTR)NULL) + INT_PTR pAssemblyLoadContext = GetAssemblyLoadContext(); + if (pAssemblyLoadContext == (INT_PTR)NULL) { // For satellite assemblies, the managed ALC has additional resolution logic (defined by the runtime) which // should be run even if the managed default ALC has not yet been used. (For non-satellite assemblies, any @@ -77,14 +77,14 @@ HRESULT DefaultAssemblyBinder::BindUsingAssemblyName(BINDER_SPACE::AssemblyName DECLARE_ARGHOLDER_ARRAY(args, 0); CALL_MANAGED_METHOD_NORET(args) - pManagedAssemblyLoadContext = GetManagedAssemblyLoadContext(); - _ASSERTE(pManagedAssemblyLoadContext != (INT_PTR)NULL); + pAssemblyLoadContext = GetAssemblyLoadContext(); + _ASSERTE(pAssemblyLoadContext != (INT_PTR)NULL); } } - if (pManagedAssemblyLoadContext != (INT_PTR)NULL) + if (pAssemblyLoadContext != (INT_PTR)NULL) { - hr = AssemblyBinderCommon::BindUsingHostAssemblyResolver(pManagedAssemblyLoadContext, pAssemblyName, + hr = AssemblyBinderCommon::BindUsingHostAssemblyResolver(pAssemblyLoadContext, pAssemblyName, NULL, this, &pCoreCLRFoundAssembly); if (SUCCEEDED(hr)) { diff --git a/src/coreclr/binder/inc/assemblybindercommon.hpp b/src/coreclr/binder/inc/assemblybindercommon.hpp index 184d2cd3b8fb86..55049c894f3ba6 100644 --- a/src/coreclr/binder/inc/assemblybindercommon.hpp +++ b/src/coreclr/binder/inc/assemblybindercommon.hpp @@ -47,7 +47,7 @@ namespace BINDER_SPACE /* in */ ProbeExtensionResult probeExtensionResult = ProbeExtensionResult::Invalid()); #if !defined(DACCESS_COMPILE) - static HRESULT BindUsingHostAssemblyResolver (/* in */ INT_PTR pManagedAssemblyLoadContextToBindWithin, + static HRESULT BindUsingHostAssemblyResolver (/* in */ INT_PTR pAssemblyLoadContextToBindWithin, /* in */ AssemblyName *pAssemblyName, /* in */ DefaultAssemblyBinder *pDefaultBinder, /* in */ AssemblyBinder *pBinder, diff --git a/src/coreclr/clrdatadescriptors.cmake b/src/coreclr/clrdatadescriptors.cmake new file mode 100644 index 00000000000000..bd3d13836b4f08 --- /dev/null +++ b/src/coreclr/clrdatadescriptors.cmake @@ -0,0 +1,90 @@ +# cDAC contract descriptor + +function(generate_data_descriptors) + set(options EXPORT_VISIBLE) + set(oneValueArgs LIBRARY_NAME CONTRACT_FILE CONTRACT_NAME INTERFACE_TARGET) + set(multiValueArgs "") + cmake_parse_arguments(DATA_DESCRIPTORS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV}) + + # INTERMEDIARY_LIBRARY is used as part of the build and not linked into the final product. + set(INTERMEDIARY_LIBRARY ${DATA_DESCRIPTORS_LIBRARY_NAME}_temp) + set(LIBRARY ${DATA_DESCRIPTORS_LIBRARY_NAME}) + + set(DATA_DESCRIPTOR_SHARED_SOURCE_DIR "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/debug/datadescriptor-shared") + set(GENERATED_CDAC_DESCRIPTOR_DIR "${CMAKE_CURRENT_BINARY_DIR}/cdac-${LIBRARY}") + + # configure contract export name + set(POINTER_DATA_NAME ${DATA_DESCRIPTORS_CONTRACT_NAME}PointerData) + set(CONTRACT_NAME ${DATA_DESCRIPTORS_CONTRACT_NAME}) + if (DATA_DESCRIPTORS_EXPORT_VISIBLE) + set(EXPORT_CONTRACT 1) + else() + set(EXPORT_CONTRACT 0) + endif() + configure_file("${DATA_DESCRIPTOR_SHARED_SOURCE_DIR}/contractconfiguration.h.in" "${GENERATED_CDAC_DESCRIPTOR_DIR}/contractconfiguration.h") + + if (NOT CDAC_BUILD_TOOL_BINARY_PATH) + # if CDAC_BUILD_TOOL_BINARY_PATH is unspecified (for example for a build without a .NET SDK or msbuild), + # link a stub contract descriptor into the runtime + add_library_clr(${LIBRARY} OBJECT "${DATA_DESCRIPTOR_SHARED_SOURCE_DIR}/contractdescriptorstub.c") + target_include_directories(${LIBRARY} PRIVATE ${GENERATED_CDAC_DESCRIPTOR_DIR}) + message(STATUS "Using a stub cDAC contract descriptor") + else() + # generate a contract descriptor using cdac-build-tool from a data descriptor and contract json file + + if(NOT EXISTS "${CDAC_BUILD_TOOL_BINARY_PATH}") + message(FATAL_ERROR "${CDAC_BUILD_TOOL_BINARY_PATH} does not exist") + endif() + + add_library(${INTERMEDIARY_LIBRARY} OBJECT "${DATA_DESCRIPTOR_SHARED_SOURCE_DIR}/datadescriptor.cpp") + + if(CLR_CMAKE_TARGET_WIN32) + # turn off whole program optimization: + # 1. it creates object files that cdac-build-tool can't read + # 2. we never link INTERMEDIARY_LIBRARY into the final product - it's only job is to be scraped + set_target_properties(${INTERMEDIARY_LIBRARY} PROPERTIES + INTERPROCEDURAL_OPTIMIZATION_RELEASE OFF + INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO OFF) + endif() + + # inherit definitions, include directories, and dependencies from the INTERFACE target + target_link_libraries(${INTERMEDIARY_LIBRARY} PRIVATE ${DATA_DESCRIPTORS_INTERFACE_TARGET}) + + set(CONTRACT_BASELINE_DIR "${CLR_REPO_ROOT_DIR}/docs/design/datacontracts/data") + set(CONTRACT_DESCRIPTOR_INPUT "${DATA_DESCRIPTOR_SHARED_SOURCE_DIR}/contract-descriptor.c.in") + set(CONTRACT_DESCRIPTOR_OUTPUT "${GENERATED_CDAC_DESCRIPTOR_DIR}/contract-descriptor.c") + set(CONTRACT_FILE "${DATA_DESCRIPTORS_CONTRACT_FILE}") + + # generate the contract descriptor by running cdac-build-tool + # n.b. this just uses `dotnet` from the PATH. InitializeDotNetCli adds the appropriate directory + add_custom_command( + OUTPUT "${CONTRACT_DESCRIPTOR_OUTPUT}" + VERBATIM + COMMAND ${CLR_DOTNET_HOST_PATH} ${CDAC_BUILD_TOOL_BINARY_PATH} compose -i "${CONTRACT_DESCRIPTOR_INPUT}" -o "${CONTRACT_DESCRIPTOR_OUTPUT}" -b "${CONTRACT_BASELINE_DIR}" -c "${CONTRACT_FILE}" $ + DEPENDS ${INTERMEDIARY_LIBRARY} ${DATA_DESCRIPTORS_DEPENDENCIES} $ "${CONTRACT_FILE}" "${CONTRACT_DESCRIPTOR_INPUT}" + USES_TERMINAL + ) + + # It is important that LIBRARY is an object library; + # if it was static, linking it into the final dll would not export + # ${CONTRACT_NAME} since it is not referenced anywhere. + add_library_clr(${LIBRARY} OBJECT + "${CONTRACT_DESCRIPTOR_OUTPUT}" + "${DATA_DESCRIPTOR_SHARED_SOURCE_DIR}/contractpointerdata.cpp" + ) + add_dependencies(${LIBRARY} ${INTERMEDIARY_LIBRARY}) + + target_include_directories(${LIBRARY} PRIVATE ${GENERATED_CDAC_DESCRIPTOR_DIR}) + + # inherit definitions, include directories, and dependencies from the INTERFACE target + target_link_libraries(${LIBRARY} PRIVATE ${DATA_DESCRIPTORS_INTERFACE_TARGET}) + + if(MSVC) + # /Zc:externConstexpr is required to export constexpr variables + # from the object file, otherwise the linker will not export them. + # See https://learn.microsoft.com/en-us/cpp/build/reference/zc-externconstexpr + # for more details. + target_compile_options(${LIBRARY} PRIVATE /Zc:externConstexpr) + endif(MSVC) + endif() +endfunction(generate_data_descriptors) diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index 5e427d41f63210..ece4f875dcb0ee 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -152,8 +152,6 @@ if(FEATURE_OBJCMARSHAL) add_compile_definitions(FEATURE_OBJCMARSHAL) endif() -# add_compile_definitions(FEATURE_RUNTIME_ASYNC) - add_compile_definitions($<${FEATURE_JAVAMARSHAL}:FEATURE_JAVAMARSHAL>) add_compile_definitions($<$>>:FEATURE_PROFAPI_ATTACH_DETACH>) @@ -209,6 +207,10 @@ if (FEATURE_STUBPRECODE_DYNAMIC_HELPERS) add_definitions(-DFEATURE_STUBPRECODE_DYNAMIC_HELPERS) endif() +if (FEATURE_CORECLR_FLUSH_INSTRUCTION_CACHE_TO_PROTECT_STUB_READS) + add_definitions(-DFEATURE_CORECLR_FLUSH_INSTRUCTION_CACHE_TO_PROTECT_STUB_READS) +endif() + if (CLR_CMAKE_TARGET_APPLE) # Re-enable when dbgshim containing https://github.com/dotnet/diagnostics/pull/5487 is generally available # add_definitions(-DFEATURE_MAP_THUNKS_FROM_IMAGE) diff --git a/src/coreclr/clrfeatures.cmake b/src/coreclr/clrfeatures.cmake index 01387330ed0694..9eb037300cd4f1 100644 --- a/src/coreclr/clrfeatures.cmake +++ b/src/coreclr/clrfeatures.cmake @@ -2,6 +2,10 @@ if (NOT CLR_CMAKE_TARGET_ARCH_WASM) set(FEATURE_JIT 1) endif() +if (CLR_CMAKE_TARGET_ARCH_WASM OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) + set(FEATURE_STATICALLY_LINKED 1) +endif() + if(CLR_CMAKE_TARGET_TIZEN_LINUX) set(FEATURE_GDBJIT_LANGID_CS 1) endif() @@ -32,13 +36,15 @@ endif(NOT DEFINED FEATURE_DBGIPC) if(NOT DEFINED FEATURE_INTERPRETER) if(CLR_CMAKE_TARGET_ANDROID) - set(FEATURE_INTERPRETER 0) + set(FEATURE_INTERPRETER 0) + elseif(CLR_CMAKE_TARGET_ARCH_WASM) + set(FEATURE_INTERPRETER 1) else() - if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) - set(FEATURE_INTERPRETER $,1,0>) - else(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) - set(FEATURE_INTERPRETER 0) - endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) + if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) + set(FEATURE_INTERPRETER $,1,0>) + else(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) + set(FEATURE_INTERPRETER 0) + endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) endif() endif(NOT DEFINED FEATURE_INTERPRETER) @@ -54,7 +60,7 @@ if(NOT DEFINED FEATURE_SINGLE_FILE_DIAGNOSTICS) set(FEATURE_SINGLE_FILE_DIAGNOSTICS 1) endif(NOT DEFINED FEATURE_SINGLE_FILE_DIAGNOSTICS) -if (CLR_CMAKE_TARGET_WIN32 OR CLR_CMAKE_TARGET_UNIX) +if ((CLR_CMAKE_TARGET_WIN32 OR CLR_CMAKE_TARGET_UNIX) AND NOT CLR_CMAKE_TARGET_ARCH_WASM) set(FEATURE_COMWRAPPERS 1) endif() @@ -74,6 +80,9 @@ if (CLR_CMAKE_TARGET_WIN32) set(FEATURE_TYPEEQUIVALENCE 1) endif(CLR_CMAKE_TARGET_WIN32) +if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS) + set(FEATURE_STUBPRECODE_DYNAMIC_HELPERS 1) +endif() if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_ARCH_WASM) set(FEATURE_CORECLR_CACHED_INTERFACE_DISPATCH 1) @@ -89,6 +98,12 @@ else() set(FEATURE_CORECLR_VIRTUAL_STUB_DISPATCH 1) endif() +# We use a flush instruction cache to protect reads from the StubPrecodeData/CallCountingStub structures in the stubs. +# This is needed because the StubPrecodeData structure is initialized after the stub code is written, and we need to ensure that +# the reads in the stub happen after the writes to the StubPrecodeData structure. We could do this with a barrier instruction in the stub, +# but that would be more expensive. +set(FEATURE_CORECLR_FLUSH_INSTRUCTION_CACHE_TO_PROTECT_STUB_READS 1) + if (CLR_CMAKE_HOST_UNIX AND CLR_CMAKE_HOST_ARCH_AMD64) # Allow 16 byte compare-exchange (cmpxchg16b) add_compile_options($<${FEATURE_CORECLR_CACHED_INTERFACE_DISPATCH}:-mcx16>) diff --git a/src/coreclr/debug/daccess/cdac.cpp b/src/coreclr/debug/daccess/cdac.cpp index 780b0d2abe29bb..738db6aeb6b2ed 100644 --- a/src/coreclr/debug/daccess/cdac.cpp +++ b/src/coreclr/debug/daccess/cdac.cpp @@ -43,6 +43,16 @@ namespace return S_OK; } + int WriteToTargetCallback(uint64_t addr, const uint8_t* buff, uint32_t count, void* context) + { + ICorDebugMutableDataTarget* target = static_cast(context); + HRESULT hr = target->WriteVirtual((CORDB_ADDRESS)addr, buff, count); + if (FAILED(hr)) + return hr; + + return S_OK; + } + int ReadThreadContext(uint32_t threadId, uint32_t contextFlags, uint32_t contextBufferSize, uint8_t* contextBuffer, void* context) { ICorDebugDataTarget* target = reinterpret_cast(context); @@ -54,7 +64,7 @@ namespace } } -CDAC CDAC::Create(uint64_t descriptorAddr, ICorDebugDataTarget* target, IUnknown* legacyImpl) +CDAC CDAC::Create(uint64_t descriptorAddr, ICorDebugMutableDataTarget* target, IUnknown* legacyImpl) { HMODULE cdacLib; if (!TryLoadCDACLibrary(&cdacLib)) @@ -64,7 +74,7 @@ CDAC CDAC::Create(uint64_t descriptorAddr, ICorDebugDataTarget* target, IUnknown _ASSERTE(init != nullptr); intptr_t handle; - if (init(descriptorAddr, &ReadFromTargetCallback, &ReadThreadContext, target, &handle) != 0) + if (init(descriptorAddr, &ReadFromTargetCallback, &WriteToTargetCallback, &ReadThreadContext, target, &handle) != 0) { ::FreeLibrary(cdacLib); return {}; diff --git a/src/coreclr/debug/daccess/cdac.h b/src/coreclr/debug/daccess/cdac.h index f6d1cdcbe5035b..559f20226df339 100644 --- a/src/coreclr/debug/daccess/cdac.h +++ b/src/coreclr/debug/daccess/cdac.h @@ -7,7 +7,7 @@ class CDAC final { public: // static - static CDAC Create(uint64_t descriptorAddr, ICorDebugDataTarget *pDataTarget, IUnknown* legacyImpl); + static CDAC Create(uint64_t descriptorAddr, ICorDebugMutableDataTarget *pDataTarget, IUnknown* legacyImpl); public: CDAC() = default; diff --git a/src/coreclr/debug/daccess/daccess.cpp b/src/coreclr/debug/daccess/daccess.cpp index 1cdb0ce5c1d735..1282ed4e1ea4a0 100644 --- a/src/coreclr/debug/daccess/daccess.cpp +++ b/src/coreclr/debug/daccess/daccess.cpp @@ -4175,7 +4175,7 @@ ClrDataAccess::StartEnumMethodInstancesByAddress( goto Exit; } - if (IsPossibleCodeAddress(taddr) != S_OK) + if ( (status = IsPossibleCodeAddress(taddr)) != S_OK) { goto Exit; } @@ -5990,6 +5990,7 @@ ClrDataAccess::GetMethodVarInfo(MethodDesc* methodDesc, BOOL success = DebugInfoManager::GetBoundariesAndVars( request, DebugInfoStoreNew, NULL, // allocator + BoundsType::Instrumented, NULL, NULL, &countNativeVarInfo, &nativeVars); @@ -6052,6 +6053,7 @@ ClrDataAccess::GetMethodNativeMap(MethodDesc* methodDesc, BOOL success = DebugInfoManager::GetBoundariesAndVars( request, DebugInfoStoreNew, NULL, // allocator + BoundsType::Instrumented, &countMapCopy, &mapCopy, NULL, NULL); @@ -7031,7 +7033,7 @@ CLRDataCreateInstance(REFIID iid, HRESULT qiRes = pClrDataAccess->QueryInterface(IID_IUnknown, (void**)&thisImpl); _ASSERTE(SUCCEEDED(qiRes)); CDAC& cdac = pClrDataAccess->m_cdac; - cdac = CDAC::Create(contractDescriptorAddr, pClrDataAccess->m_pTarget, thisImpl); + cdac = CDAC::Create(contractDescriptorAddr, pClrDataAccess->m_pMutableTarget, thisImpl); if (cdac.IsValid()) { // Get SOS interfaces from the cDAC if available. diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp index 992bbf5046a11e..0fa75ad43cf054 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -868,6 +868,7 @@ void DacDbiInterfaceImpl::GetNativeVarData(MethodDesc * pMethodDesc, BOOL success = DebugInfoManager::GetBoundariesAndVars(request, InfoStoreNew, NULL, // allocator + BoundsType::Instrumented, NULL, NULL, &entryCount, &nativeVars); @@ -879,76 +880,6 @@ void DacDbiInterfaceImpl::GetNativeVarData(MethodDesc * pMethodDesc, } // GetNativeVarData -//----------------------------------------------------------------------------- -// Given a instrumented IL map from the profiler that maps: -// Original offset IL_A -> Instrumentend offset IL_B -// And a native mapping from the JIT that maps: -// Instrumented offset IL_B -> native offset Native_C -// This function merges the two maps and stores the result back into the nativeMap. -// The nativeMap now maps: -// Original offset IL_A -> native offset Native_C -// pEntryCount is the number of valid entries in nativeMap, and it may be adjusted downwards -// as part of the composition. -//----------------------------------------------------------------------------- -void DacDbiInterfaceImpl::ComposeMapping(const InstrumentedILOffsetMapping * pProfilerILMap, ICorDebugInfo::OffsetMapping nativeMap[], ULONG32* pEntryCount) -{ - // Translate the IL offset if the profiler has provided us with a mapping. - // The ICD public API should always expose the original IL offsets, but GetBoundaries() - // directly accesses the debug info, which stores the instrumented IL offsets. - - ULONG32 entryCount = *pEntryCount; - // The map pointer could be NULL or there could be no entries in the map, in either case no work to do - if (pProfilerILMap && !pProfilerILMap->IsNull()) - { - // If we did instrument, then we can't have any sequence points that - // are "in-between" the old-->new map that the profiler gave us. - // Ex, if map is: - // (6 old -> 36 new) - // (8 old -> 50 new) - // And the jit gives us an entry for 44 new, that will map back to 6 old. - // Since the map can only have one entry for 6 old, we remove 44 new. - - // First Pass: invalidate all the duplicate entries by setting their IL offset to MAX_ILNUM - ULONG32 cDuplicate = 0; - ULONG32 prevILOffset = (ULONG32)(ICorDebugInfo::MAX_ILNUM); - for (ULONG32 i = 0; i < entryCount; i++) - { - ULONG32 origILOffset = TranslateInstrumentedILOffsetToOriginal(nativeMap[i].ilOffset, pProfilerILMap); - - if (origILOffset == prevILOffset) - { - // mark this sequence point as invalid; refer to the comment above - nativeMap[i].ilOffset = (ULONG32)(ICorDebugInfo::MAX_ILNUM); - cDuplicate += 1; - } - else - { - // overwrite the instrumented IL offset with the original IL offset - nativeMap[i].ilOffset = origILOffset; - prevILOffset = origILOffset; - } - } - - // Second Pass: move all the valid entries up front - ULONG32 realIndex = 0; - for (ULONG32 curIndex = 0; curIndex < entryCount; curIndex++) - { - if (nativeMap[curIndex].ilOffset != (ULONG32)(ICorDebugInfo::MAX_ILNUM)) - { - // This is a valid entry. Move it up front. - nativeMap[realIndex] = nativeMap[curIndex]; - realIndex += 1; - } - } - - // make sure we have done the bookkeeping correctly - _ASSERTE((realIndex + cDuplicate) == entryCount); - - // Final Pass: derecement entryCount - entryCount -= cDuplicate; - *pEntryCount = entryCount; - } -} //----------------------------------------------------------------------------- @@ -983,38 +914,14 @@ void DacDbiInterfaceImpl::GetSequencePoints(MethodDesc * pMethodDesc, ULONG32 entryCount; BOOL success = DebugInfoManager::GetBoundariesAndVars(request, - InfoStoreNew, NULL, // allocator + InfoStoreNew, + NULL, // allocator + BoundsType::Uninstrumented, &entryCount, &mapCopy, NULL, NULL); if (!success) ThrowHR(E_FAIL); -#ifdef FEATURE_REJIT - CodeVersionManager * pCodeVersionManager = pMethodDesc->GetCodeVersionManager(); - ILCodeVersion ilVersion; - NativeCodeVersion nativeCodeVersion = pCodeVersionManager->GetNativeCodeVersion(dac_cast(pMethodDesc), (PCODE)startAddr); - if (!nativeCodeVersion.IsNull()) - { - ilVersion = nativeCodeVersion.GetILCodeVersion(); - } - - // if there is a rejit IL map for this function, apply that in preference to load-time mapping - if (!ilVersion.IsNull() && !ilVersion.IsDefaultVersion()) - { - const InstrumentedILOffsetMapping * pRejitMapping = ilVersion.GetInstrumentedILMap(); - ComposeMapping(pRejitMapping, mapCopy, &entryCount); - } - else - { -#endif - // if there is a profiler load-time mapping and not a rejit mapping, apply that instead - InstrumentedILOffsetMapping loadTimeMapping = - pMethodDesc->GetAssembly()->GetModule()->GetInstrumentedILOffsetMapping(pMethodDesc->GetMemberDef()); - ComposeMapping(&loadTimeMapping, mapCopy, &entryCount); -#ifdef FEATURE_REJIT - } -#endif - pSeqPoints->InitSequencePoints(entryCount); // mapCopy and pSeqPoints have elements of different types. Thus, we @@ -1024,46 +931,6 @@ void DacDbiInterfaceImpl::GetSequencePoints(MethodDesc * pMethodDesc, } // GetSequencePoints -// ---------------------------------------------------------------------------- -// DacDbiInterfaceImpl::TranslateInstrumentedILOffsetToOriginal -// -// Description: -// Helper function to convert an instrumented IL offset to the corresponding original IL offset. -// -// Arguments: -// * ilOffset - offset to be translated -// * pMapping - the profiler-provided mapping between original IL offsets and instrumented IL offsets -// -// Return Value: -// Return the translated offset. -// - -ULONG DacDbiInterfaceImpl::TranslateInstrumentedILOffsetToOriginal(ULONG ilOffset, - const InstrumentedILOffsetMapping * pMapping) -{ - SIZE_T cMap = pMapping->GetCount(); - ARRAY_PTR_COR_IL_MAP rgMap = pMapping->GetOffsets(); - - _ASSERTE((cMap == 0) == (rgMap == NULL)); - - // Early out if there is no mapping, or if we are dealing with a special IL offset such as - // prolog, epilog, etc. - if ((cMap == 0) || ((int)ilOffset < 0)) - { - return ilOffset; - } - - SIZE_T i = 0; - for (i = 1; i < cMap; i++) - { - if (ilOffset < rgMap[i].newOffset) - { - return rgMap[i - 1].oldOffset; - } - } - return rgMap[i - 1].oldOffset; -} - //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Function Data //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3556,9 +3423,9 @@ void DacDbiInterfaceImpl::EnumerateMemRangesForJitCodeHeaps(CQuickArrayListm_pCodeHeap.IsValid()); + _ASSERTE(pEM != NULL && pEM->m_pAllCodeHeaps.IsValid()); - PTR_HeapList pHeapList = pEM->m_pCodeHeap; + PTR_HeapList pHeapList = pEM->m_pAllCodeHeaps; while (pHeapList != NULL) { CodeHeap *pHeap = pHeapList->pHeap; @@ -5096,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); @@ -7445,6 +7324,23 @@ HRESULT DacDbiInterfaceImpl::EnableGCNotificationEvents(BOOL fEnable) return hr; } +HRESULT DacDbiInterfaceImpl::GetDomainAssemblyFromModule(VMPTR_Module vmModule, OUT VMPTR_DomainAssembly *pVmDomainAssembly) +{ + DD_ENTER_MAY_THROW; + + if (vmModule.IsNull() || pVmDomainAssembly == NULL) + return E_INVALIDARG; + + Module *pModule = vmModule.GetDacPtr(); + if (pModule == NULL) + return E_INVALIDARG; + + *pVmDomainAssembly = VMPTR_DomainAssembly::NullPtr(); + pVmDomainAssembly->SetHostPtr(pModule->GetDomainAssembly()); + + return S_OK; +} + DacRefWalker::DacRefWalker(ClrDataAccess *dac, BOOL walkStacks, BOOL walkFQ, UINT32 handleMask, BOOL resolvePointers) : mDac(dac), mWalkStacks(walkStacks), mWalkFQ(walkFQ), mHandleMask(handleMask), mStackWalker(NULL), mResolvePointers(resolvePointers), mHandleWalker(NULL), mFQStart(PTR_NULL), mFQEnd(PTR_NULL), mFQCurr(PTR_NULL) diff --git a/src/coreclr/debug/daccess/dacdbiimpl.h b/src/coreclr/debug/daccess/dacdbiimpl.h index dffc8115e603b0..c1ae09a3feaf0a 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.h +++ b/src/coreclr/debug/daccess/dacdbiimpl.h @@ -162,6 +162,7 @@ class DacDbiInterfaceImpl : HRESULT GetDefinesBitField(ULONG32 *pDefines); HRESULT GetMDStructuresVersion(ULONG32* pMDStructuresVersion); HRESULT EnableGCNotificationEvents(BOOL fEnable); + HRESULT GetDomainAssemblyFromModule(VMPTR_Module vmModule, OUT VMPTR_DomainAssembly *pVmDomainAssembly); private: void TypeHandleToExpandedTypeInfoImpl(AreValueTypesBoxed boxed, @@ -183,13 +184,6 @@ class DacDbiInterfaceImpl : CORDB_ADDRESS startAddr, SequencePoints * pNativeMap); - // Helper to compose a IL->IL and IL->Native mapping - void ComposeMapping(const InstrumentedILOffsetMapping * pProfilerILMap, ICorDebugInfo::OffsetMapping nativeMap[], ULONG32* pEntryCount); - - // Helper function to convert an instrumented IL offset to the corresponding original IL offset. - ULONG TranslateInstrumentedILOffsetToOriginal(ULONG ilOffset, - const InstrumentedILOffsetMapping * pMapping); - public: //---------------------------------------------------------------------------------- // class MapSortILMap: A template class that will sort an array of DebuggerILToNativeMap. diff --git a/src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp b/src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp index eb5464275d0dc2..dc13cf59a7f006 100644 --- a/src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp +++ b/src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp @@ -474,7 +474,7 @@ ULONG32 DacDbiInterfaceImpl::GetCountOfInternalFrames(VMPTR_Thread vmThread) { // Skip new exception handling helpers InlinedCallFrame *pInlinedCallFrame = dac_cast(pFrame); - PTR_NDirectMethodDesc pMD = pInlinedCallFrame->m_Datum; + PTR_PInvokeMethodDesc pMD = pInlinedCallFrame->m_Datum; TADDR datum = dac_cast(pMD); if ((datum & (TADDR)InlinedCallFrameMarker::Mask) == (TADDR)InlinedCallFrameMarker::ExceptionHandlingHelper) { @@ -527,7 +527,7 @@ void DacDbiInterfaceImpl::EnumerateInternalFrames(VMPTR_Thread { // Skip new exception handling helpers InlinedCallFrame *pInlinedCallFrame = dac_cast(pFrame); - PTR_NDirectMethodDesc pMD = pInlinedCallFrame->m_Datum; + PTR_PInvokeMethodDesc pMD = pInlinedCallFrame->m_Datum; TADDR datum = dac_cast(pMD); if ((datum & (TADDR)InlinedCallFrameMarker::Mask) == (TADDR)InlinedCallFrameMarker::ExceptionHandlingHelper) { diff --git a/src/coreclr/debug/daccess/enummem.cpp b/src/coreclr/debug/daccess/enummem.cpp index 4c360628edfac5..828ae77d6aae16 100644 --- a/src/coreclr/debug/daccess/enummem.cpp +++ b/src/coreclr/debug/daccess/enummem.cpp @@ -25,6 +25,8 @@ #include #endif // FEATURE_COMWRAPPERS +#include "cdacplatformmetadata.hpp" + extern HRESULT GetDacTableAddress(ICorDebugDataTarget* dataTarget, ULONG64 baseAddress, PULONG64 dacTableAddress); #if defined(DAC_MEASURE_PERF) diff --git a/src/coreclr/debug/daccess/fntableaccess.cpp b/src/coreclr/debug/daccess/fntableaccess.cpp index 023a82e268c8ed..5583da327a6727 100644 --- a/src/coreclr/debug/daccess/fntableaccess.cpp +++ b/src/coreclr/debug/daccess/fntableaccess.cpp @@ -169,7 +169,7 @@ extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx(IN ReadMemoryFunction *ppFunctions = 0; *pnEntries = 0; - DWORD_PTR pHp = JitMan + (DWORD_PTR)offsetof(FakeEEJitManager, m_pCodeHeap); + DWORD_PTR pHp = JitMan + (DWORD_PTR)offsetof(FakeEEJitManager, m_pAllCodeHeaps); move(pHp, pHp); diff --git a/src/coreclr/debug/daccess/fntableaccess.h b/src/coreclr/debug/daccess/fntableaccess.h index f76056cfba0379..db4bdfe1e3414c 100644 --- a/src/coreclr/debug/daccess/fntableaccess.h +++ b/src/coreclr/debug/daccess/fntableaccess.h @@ -15,8 +15,8 @@ struct FakeEEJitManager { LPVOID __VFN_table; LPVOID m_runtimeSupport; - LPVOID m_pCodeHeap; - // Nothing after this point matters: we only need the correct offset of m_pCodeHeap. + LPVOID m_pAllCodeHeaps; + // Nothing after this point matters: we only need the correct offset of m_pAllCodeHeaps. }; struct FakeHeapList @@ -76,7 +76,7 @@ class CheckDuplicatedStructLayouts { #define CHECK_OFFSET(cls, fld) CPP_ASSERT(cls##fld, offsetof(Fake##cls, fld) == offsetof(cls, fld)) - CHECK_OFFSET(EEJitManager, m_pCodeHeap); + CHECK_OFFSET(EEJitManager, m_pAllCodeHeaps); CHECK_OFFSET(HeapList, hpNext); CHECK_OFFSET(HeapList, startAddress); diff --git a/src/coreclr/debug/daccess/reimpl.cpp b/src/coreclr/debug/daccess/reimpl.cpp index 1935eacce97258..fe6f1adddc786e 100644 --- a/src/coreclr/debug/daccess/reimpl.cpp +++ b/src/coreclr/debug/daccess/reimpl.cpp @@ -38,9 +38,9 @@ DacGetThread(ULONG32 osThread) UNREACHABLE(); } - // Note that if we had access to TLS, we could get this at index gThreadTLSIndex for the specified - // thread. However, this is the only place we might want to use TLS, and it's not performance critical, - // so we haven't added TLS support to ICorDebugDataTarget (the legacy ICLRDataTarget interface has it though) + // Note that if we had access to TLS, we could get this at TLS for the specified thread. However, this is + // the only place we might want to use TLS, and it's not performance critical, so we haven't added TLS support + // to ICorDebugDataTarget (the legacy ICLRDataTarget interface has it though) // Scan the whole thread store to see if there's a matching thread. diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp index ccb303453b5626..9f567d48809b39 100644 --- a/src/coreclr/debug/daccess/request.cpp +++ b/src/coreclr/debug/daccess/request.cpp @@ -362,7 +362,7 @@ ClrDataAccess::GetJitManagerList(unsigned int count, struct DacpJitManagerInfo m currentPtr->codeType = managerPtr->GetCodeType(); EEJitManager *eeJitManager = PTR_EEJitManager(PTR_HOST_TO_TADDR(managerPtr)); - currentPtr->ptrHeapList = HOST_CDADDR(eeJitManager->m_pCodeHeap); + currentPtr->ptrHeapList = HOST_CDADDR(eeJitManager->m_pAllCodeHeaps); } } else if (pNeeded) @@ -528,7 +528,7 @@ ClrDataAccess::GetCodeHeapList(CLRDATA_ADDRESS jitManager, unsigned int count, s SOSDacEnter(); EEJitManager *pJitManager = PTR_EEJitManager(TO_TADDR(jitManager)); - HeapList *heapList = pJitManager->m_pCodeHeap; + HeapList *heapList = pJitManager->m_pAllCodeHeaps; if (codeHeaps) { @@ -2434,32 +2434,26 @@ ClrDataAccess::GetAppDomainData(CLRDATA_ADDRESS addr, struct DacpAppDomainData * if (addr != HOST_CDADDR(SystemDomain::System())) { PTR_AppDomain pAppDomain = PTR_AppDomain(TO_TADDR(addr)); - appdomainData->DomainLocalBlock = 0; - appdomainData->pDomainLocalModules = 0; appdomainData->dwId = DefaultADID; - appdomainData->appDomainStage = (DacpAppDomainDataStage)pAppDomain->m_Stage.Load(); - if (pAppDomain->IsActive()) - { - // The assembly list is not valid in a closed appdomain. - AppDomain::AssemblyIterator i = pAppDomain->IterateAssembliesEx((AssemblyIterationFlags)( - kIncludeLoading | kIncludeLoaded | kIncludeExecution)); - CollectibleAssemblyHolder pAssembly; - while (i.Next(pAssembly.This())) - { - if (pAssembly->IsLoaded()) - { - appdomainData->AssemblyCount++; - } - } + AppDomain::AssemblyIterator i = pAppDomain->IterateAssembliesEx((AssemblyIterationFlags)( + kIncludeLoading | kIncludeLoaded | kIncludeExecution)); + CollectibleAssemblyHolder pAssembly; - AppDomain::FailedAssemblyIterator j = pAppDomain->IterateFailedAssembliesEx(); - while (j.Next()) + while (i.Next(pAssembly.This())) + { + if (pAssembly->IsLoaded()) { - appdomainData->FailedAssemblyCount++; + appdomainData->AssemblyCount++; } } + + AppDomain::FailedAssemblyIterator j = pAppDomain->IterateFailedAssembliesEx(); + while (j.Next()) + { + appdomainData->FailedAssemblyCount++; + } } } @@ -5030,15 +5024,15 @@ HRESULT ClrDataAccess::GetAssemblyLoadContext(CLRDATA_ADDRESS methodTable, CLRDA PTR_PEAssembly pPEAssembly = pModule->GetPEAssembly(); PTR_AssemblyBinder pBinder = pPEAssembly->GetAssemblyBinder(); - INT_PTR managedAssemblyLoadContextHandle = pBinder->GetManagedAssemblyLoadContext(); + INT_PTR AssemblyLoadContextHandle = pBinder->GetAssemblyLoadContext(); - TADDR managedAssemblyLoadContextAddr = 0; - if (managedAssemblyLoadContextHandle != 0) + TADDR AssemblyLoadContextAddr = 0; + if (AssemblyLoadContextHandle != 0) { - DacReadAll(managedAssemblyLoadContextHandle,&managedAssemblyLoadContextAddr,sizeof(TADDR),true); + DacReadAll(AssemblyLoadContextHandle,&AssemblyLoadContextAddr,sizeof(TADDR),true); } - *assemblyLoadContext = TO_CDADDR(managedAssemblyLoadContextAddr); + *assemblyLoadContext = TO_CDADDR(AssemblyLoadContextAddr); SOSDacLeave(); return hr; diff --git a/src/coreclr/debug/daccess/stdafx.h b/src/coreclr/debug/daccess/stdafx.h index bb7b7b2365de59..bff6a4f660379b 100644 --- a/src/coreclr/debug/daccess/stdafx.h +++ b/src/coreclr/debug/daccess/stdafx.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/src/coreclr/debug/daccess/task.cpp b/src/coreclr/debug/daccess/task.cpp index b55626e2d33185..edbb360a988c36 100644 --- a/src/coreclr/debug/daccess/task.cpp +++ b/src/coreclr/debug/daccess/task.cpp @@ -3573,13 +3573,13 @@ ClrDataMethodDefinition::GetIlMethod(void) { if (m_methodDesc) { - if (!m_methodDesc->HasILHeader()) + if (m_methodDesc->MayHaveILHeader()) { - return NULL; + return m_methodDesc->GetILHeader(); } else { - return m_methodDesc->GetILHeader(); + return NULL; } } else diff --git a/src/coreclr/debug/datadescriptor-shared/README.md b/src/coreclr/debug/datadescriptor-shared/README.md new file mode 100644 index 00000000000000..b0bb9e8e3dc1d3 --- /dev/null +++ b/src/coreclr/debug/datadescriptor-shared/README.md @@ -0,0 +1,99 @@ +# Datadescriptor Implementation Infrastructure + +This folder contains infrastructure to create data descriptors as defined in the [data_descriptor.md](../../../../docs/design/datacontracts/data_descriptor.md). Data descriptors enable diagnostic tooling (debuggers, profilers, etc.) to understand the internal layout and structure of .NET runtime objects without requiring intimate knowledge of implementation details. + +## CMake Integration and Build System + +### Function Parameters + +The `generate_data_descriptors` function defined in `clrdatadescriptors.cmake` takes the following arguments: + +* **`LIBRARY_NAME`** (Required) - Sets the name of the target object being created +* **`CONTRACT_FILE`** (Required) - Path to the contract JSON file defining supported contracts +* **`CONTRACT_NAME`** (Required) - Name of the `ContractDescriptor` export symbol +* **`INTERFACE_TARGET`** (Required) - Interface target providing dependencies, include directories, and definitions +* **`EXPORT_VISIBLE`** (Optional) - Controls if the `CONTRACT_NAME` will be exported from the DLL + +### Two-Phase Build Process + +The build system uses a two-phase approach: + +**Phase 1: Intermediary Library** +- Compiles `datadescriptor.cpp` with your `datadescriptor.h` and `datadescriptor.inc` +- Creates object files that the `cdac-build-tool` can analyze +- Extracts type layout information and generates string pools + +**Phase 2: Contract Descriptor Generation** +- Runs `cdac-build-tool` to process the intermediary object files +- Generates the final contract descriptor C source file +- Compiles this into the final library that gets linked into the runtime + + +## Macro Reference + +### Structure Definition Macros + +**`CDAC_BASELINE("identifier")`** +- Specifies the baseline data contract version +- Use `"empty"` for new descriptors +- Must appear before any other content + +**`CDAC_TYPES_BEGIN()` / `CDAC_TYPES_END()`** +- Delimits the type definitions section +- Must contain all `CDAC_TYPE_*` macros + +**`CDAC_TYPE_BEGIN(typeName)`** +- Starts a new type definition +- `typeName` must be globally unique within the descriptor + +**`CDAC_TYPE_SIZE(sizeInBytes)`** +- Specifies the type has a determinate size +- Usually `sizeof(YourNativeType)` + +**`CDAC_TYPE_INDETERMINATE(typeName)`** +- Specifies the type has indeterminate size +- Alternative to `CDAC_TYPE_SIZE` + +**`CDAC_TYPE_FIELD(typeName, fieldType, fieldName, offset)`** +- Defines a field within the type +- `fieldType`: primitive type or another defined type +- `fieldName`: diagnostic-friendly name (use managed names for managed types) +- `offset`: byte offset, usually `offsetof()` or `cdac_data::FieldName` + +**`CDAC_TYPE_END(typeName)`** +- Closes the type definition +- `typeName` must match the corresponding `CDAC_TYPE_BEGIN` + +### Global Value Macros + +**`CDAC_GLOBALS_BEGIN()` / `CDAC_GLOBALS_END()`** +- Delimits the global values section + +**`CDAC_GLOBAL(globalName, typeName, value)`** +- Defines a global literal value +- `value` must be a compile-time constant +- `typeName` can be a primitive type or defined type + +**`CDAC_GLOBAL_POINTER(globalName, address)`** +- Defines a global pointer value +- `address` must be a compile-time constant pointer or `uintptr_t` + +**`CDAC_GLOBAL_STRING(globalName, stringValue)`** +- Defines a global string value +- `stringValue` must be a compile-time string literal + + +## Current Implementation + +For reference, see the current implementation in: +- **`src/coreclr/vm/datadescriptor/`** - Complete real-world implementation + - `datadescriptor.h` - Headers and includes + - `datadescriptor.inc` - Full type definitions for runtime objects + - `contracts.jsonc` - Contract definitions + - `CMakeLists.txt` - Build integration + +## Related Documentation + +- **[Data Contracts Design](../../../../docs/design/datacontracts/datacontracts_design.md)** - Overall design and motivation +- **[Contract Descriptor](../../../../docs/design/datacontracts/contract-descriptor.md)** - Binary format specification +- **[Data Descriptor](../../../../docs/design/datacontracts/data_descriptor.md)** - Logical format specification diff --git a/src/coreclr/debug/runtimeinfo/contract-descriptor.c.in b/src/coreclr/debug/datadescriptor-shared/contract-descriptor.c.in similarity index 63% rename from src/coreclr/debug/runtimeinfo/contract-descriptor.c.in rename to src/coreclr/debug/datadescriptor-shared/contract-descriptor.c.in index c1f0edd7a66f9c..8da6f70498461f 100644 --- a/src/coreclr/debug/runtimeinfo/contract-descriptor.c.in +++ b/src/coreclr/debug/datadescriptor-shared/contract-descriptor.c.in @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. #include +#include "contractconfiguration.h" #ifdef _MSC_VER #define DLLEXPORT __declspec(dllexport) @@ -9,7 +10,7 @@ #define DLLEXPORT __attribute__((visibility("default"))) #endif -struct DotNetRuntimeContractDescriptor +struct ContractDescriptor { uint64_t magic; uint32_t flags; @@ -17,18 +18,21 @@ struct DotNetRuntimeContractDescriptor const char *descriptor; const uint32_t pointer_data_count; uint32_t pad0; - const uintptr_t *pointer_data; + const void** pointer_data; }; -extern const uintptr_t contractDescriptorPointerData[]; +// POINTER_DATA_NAME and CONTRACT_NAME are macros provided by +// contractconfiguration.h which is configured by CMake +extern const void* POINTER_DATA_NAME[]; -DLLEXPORT struct DotNetRuntimeContractDescriptor DotNetRuntimeContractDescriptor; - -DLLEXPORT struct DotNetRuntimeContractDescriptor DotNetRuntimeContractDescriptor = { +#if EXPORT_CONTRACT +DLLEXPORT +#endif // EXPORT_CONTRACT +struct ContractDescriptor CONTRACT_NAME = { .magic = 0x0043414443434e44ull, // "DNCCDAC\0" .flags = %%platformFlags%%, .descriptor_size = %%jsonDescriptorSize%%, .descriptor = "%%jsonDescriptor%%", .pointer_data_count = %%pointerDataCount%%, - .pointer_data = &contractDescriptorPointerData[0], + .pointer_data = &POINTER_DATA_NAME[0], }; diff --git a/src/coreclr/debug/datadescriptor-shared/contractconfiguration.h.in b/src/coreclr/debug/datadescriptor-shared/contractconfiguration.h.in new file mode 100644 index 00000000000000..e38f320a8de5ac --- /dev/null +++ b/src/coreclr/debug/datadescriptor-shared/contractconfiguration.h.in @@ -0,0 +1,6 @@ +#pragma once + +#define POINTER_DATA_NAME @POINTER_DATA_NAME@ +#define CONTRACT_NAME @CONTRACT_NAME@ + +#define EXPORT_CONTRACT @EXPORT_CONTRACT@ diff --git a/src/coreclr/debug/runtimeinfo/contractdescriptorstub.c b/src/coreclr/debug/datadescriptor-shared/contractdescriptorstub.c similarity index 64% rename from src/coreclr/debug/runtimeinfo/contractdescriptorstub.c rename to src/coreclr/debug/datadescriptor-shared/contractdescriptorstub.c index 59421a6692d2a7..e403b4711eb61d 100644 --- a/src/coreclr/debug/runtimeinfo/contractdescriptorstub.c +++ b/src/coreclr/debug/datadescriptor-shared/contractdescriptorstub.c @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. #include +#include "contractconfiguration.h" #ifdef _MSC_VER #define DLLEXPORT __declspec(dllexport) @@ -9,7 +10,7 @@ #define DLLEXPORT __attribute__((visibility("default"))) #endif -struct DotNetRuntimeContractDescriptor +struct ContractDescriptor { uint64_t magic; uint32_t flags; @@ -17,23 +18,25 @@ struct DotNetRuntimeContractDescriptor const char *descriptor; const uint32_t pointer_data_count; uint32_t pad0; - const uintptr_t *pointer_data; + const void** pointer_data; }; -extern const uintptr_t contractDescriptorPointerData[]; +// POINTER_DATA_NAME and CONTRACT_NAME are macros provided by +// contractconfiguration.h which is configured by CMake +extern const void* POINTER_DATA_NAME[]; // just the placeholder pointer -const uintptr_t contractDescriptorPointerData[] = { (uintptr_t)0 }; +const void* POINTER_DATA_NAME[] = { (void*)0 }; -DLLEXPORT struct DotNetRuntimeContractDescriptor DotNetRuntimeContractDescriptor; +DLLEXPORT struct ContractDescriptor CONTRACT_NAME; #define STUB_DESCRIPTOR "{\"version\":0,\"baseline\":\"empty\",\"contracts\":{},\"types\":{},\"globals\":{}}" -DLLEXPORT struct DotNetRuntimeContractDescriptor DotNetRuntimeContractDescriptor = { +DLLEXPORT struct ContractDescriptor CONTRACT_NAME = { .magic = 0x0043414443434e44ull, // "DNCCDAC\0" .flags = 0x1u & (sizeof(void*) == 4 ? 0x02u : 0x00u), .descriptor_size = sizeof(STUB_DESCRIPTOR), .descriptor = STUB_DESCRIPTOR, .pointer_data_count = 1, - .pointer_data = &contractDescriptorPointerData[0], + .pointer_data = &POINTER_DATA_NAME[0], }; diff --git a/src/coreclr/debug/datadescriptor-shared/contractpointerdata.cpp b/src/coreclr/debug/datadescriptor-shared/contractpointerdata.cpp new file mode 100644 index 00000000000000..443c7f182c001f --- /dev/null +++ b/src/coreclr/debug/datadescriptor-shared/contractpointerdata.cpp @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "datadescriptor.h" +#include "contractconfiguration.h" + +extern "C" +{ + // without an extern declaration, clang does not emit this global into the object file + extern constexpr const void* POINTER_DATA_NAME[] = { + (void*)0, // placeholder + #define CDAC_GLOBAL_POINTER(name,value) (void*)(value), + #define CDAC_GLOBAL_SUB_DESCRIPTOR(name,value) (void*)(value), + #include "wrappeddatadescriptor.inc" + }; +}; + diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.cpp b/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp similarity index 94% rename from src/coreclr/debug/runtimeinfo/datadescriptor.cpp rename to src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp index 61e9732d5e133a..0e3332539df9ec 100644 --- a/src/coreclr/debug/runtimeinfo/datadescriptor.cpp +++ b/src/coreclr/debug/datadescriptor-shared/datadescriptor.cpp @@ -1,27 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#include "common.h" - -#include -#include - -#include "static_assert.h" - -#include -#include "cdacplatformmetadata.hpp" -#include "methodtable.h" -#include "threads.h" -#include "exinfo.h" - -#include "configure.h" - -#include "../debug/ee/debugger.h" -#include "ecall.h" - -#ifdef HAVE_GCCOVER -#include "gccover.h" -#endif // HAVE_GCCOVER +#include "datadescriptor.h" // begin blob definition @@ -90,7 +70,7 @@ struct CDacStringPoolSizes #define CDAC_GLOBAL_POINTER(name,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) #define CDAC_GLOBAL(name,tyname,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) \ DECL_LEN(MAKE_GLOBALTYPELEN_NAME(name), sizeof(#tyname)) -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" char cdac_string_pool_trailing_nil; #undef DECL_LEN }; @@ -108,7 +88,7 @@ enum CDacBlobTypesCount = #define CDAC_TYPES_BEGIN() 0 #define CDAC_TYPE_BEGIN(name) + 1 -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" }; // count the field pool size. @@ -119,7 +99,7 @@ enum #define CDAC_TYPES_BEGIN() 1 #define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) + 1 #define CDAC_TYPE_END(name) + 1 -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" }; // count the literal globals @@ -128,7 +108,7 @@ enum CDacBlobGlobalLiteralsCount = #define CDAC_GLOBALS_BEGIN() 0 #define CDAC_GLOBAL(name,tyname,value) + 1 -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" }; // count the aux vector globals @@ -137,7 +117,7 @@ enum CDacBlobGlobalPointersCount = #define CDAC_GLOBALS_BEGIN() 0 #define CDAC_GLOBAL_POINTER(name,value) + 1 -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" }; // count the global strings @@ -146,7 +126,7 @@ enum CDacBlobGlobalStringsCount = #define CDAC_GLOBALS_BEGIN() 0 #define CDAC_GLOBAL_STRING(name,value) + 1 -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" }; @@ -176,7 +156,7 @@ struct CDacFieldsPoolSizes #define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) DECL_LEN(CONCAT4(cdac_fields_pool_member__, tyname, __, membername)) #define CDAC_TYPE_END(name) DECL_LEN(CONCAT4(cdac_fields_pool_member__, tyname, _, endmarker)) \ } MAKE_TYPEFIELDS_TYNAME(name); -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" #undef DECL_LEN }; @@ -198,7 +178,7 @@ struct CDacGlobalPointerIndex #define DECL_LEN(membername) char membername; #define CDAC_GLOBALS_BEGIN() DECL_LEN(cdac_global_pointer_index_start_placeholder__) #define CDAC_GLOBAL_POINTER(name,value) DECL_LEN(CONCAT(cdac_global_pointer_index__, name)) -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" #undef DECL_LEN }; @@ -296,7 +276,7 @@ struct MagicAndBlob BlobDataDescriptor = { #define CDAC_TYPE_INDETERMINATE(name) /*.Size = */ 0, #define CDAC_TYPE_SIZE(size) /* .Size = */ size, #define CDAC_TYPE_END(name) }, -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" }, /* .FieldsPool = */ { @@ -307,22 +287,22 @@ struct MagicAndBlob BlobDataDescriptor = { /* .FieldOffset = */ offset, \ }, #define CDAC_TYPE_END(name) { 0, }, -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" }, /* .GlobalLiteralValues = */ { #define CDAC_GLOBAL(name,tyname,value) { /*.Name = */ GET_GLOBAL_NAME(name), /* .TypeName = */ GET_GLOBALTYPE_NAME(name), /* .Value = */ value }, -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" }, /* .GlobalPointerValues = */ { #define CDAC_GLOBAL_POINTER(name,value) { /* .Name = */ GET_GLOBAL_NAME(name), /* .PointerDataIndex = */ GET_GLOBAL_POINTER_INDEX(name) }, -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" }, /* .GlobalStringValues = */ { #define CDAC_GLOBAL_STRING(name,value) { /* .Name = */ GET_GLOBAL_NAME(name), /* .Value = */ GET_GLOBALSTRING_VALUE(name) }, -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" }, /* .NamesPool = */ ("\0" // starts with a nul @@ -332,7 +312,7 @@ struct MagicAndBlob BlobDataDescriptor = { #define CDAC_GLOBAL_STRING(name,value) #name "\0" STRINGIFY(value) "\0" #define CDAC_GLOBAL_POINTER(name,value) #name "\0" #define CDAC_GLOBAL(name,tyname,value) #name "\0" #tyname "\0" -#include "datadescriptor.h" +#include "wrappeddatadescriptor.inc" ), /* .EndMagic = */ { 0x01, 0x02, 0x03, 0x04 }, diff --git a/src/coreclr/debug/datadescriptor-shared/wrappeddatadescriptor.inc b/src/coreclr/debug/datadescriptor-shared/wrappeddatadescriptor.inc new file mode 100644 index 00000000000000..7500ac93388803 --- /dev/null +++ b/src/coreclr/debug/datadescriptor-shared/wrappeddatadescriptor.inc @@ -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. + +// No include guards. This file is included multiple times. +// Wraps datadescriptor.inc to define and undefine macros used in the file. + +#ifndef CDAC_BASELINE +#define CDAC_BASELINE(identifier) +#endif +#ifndef CDAC_TYPES_BEGIN +#define CDAC_TYPES_BEGIN() +#endif +#ifndef CDAC_TYPE_BEGIN +#define CDAC_TYPE_BEGIN(tyname) +#endif +#ifndef CDAC_TYPE_SIZE +#define CDAC_TYPE_SIZE(k) +#endif +#ifndef CDAC_TYPE_INDETERMINATE +#define CDAC_TYPE_INDETERMINATE(tyname) +#endif +#ifndef CDAC_TYPE_FIELD +#define CDAC_TYPE_FIELD(tyname,fieldtyname,fieldname,off) +#endif +#ifndef CDAC_TYPE_END +#define CDAC_TYPE_END(tyname) +#endif +#ifndef CDAC_TYPES_END +#define CDAC_TYPES_END() +#endif +#ifndef CDAC_GLOBALS_BEGIN +#define CDAC_GLOBALS_BEGIN() +#endif +#ifndef CDAC_GLOBAL +#define CDAC_GLOBAL(globalname,tyname,val) +#endif +#ifndef CDAC_GLOBAL_POINTER +#define CDAC_GLOBAL_POINTER(globalname,addr) +#endif +#ifndef CDAC_GLOBAL_STRING +#define CDAC_GLOBAL_STRING(globalname,stringval) +#endif +#ifndef CDAC_GLOBALS_END +#define CDAC_GLOBALS_END() +#endif + +#include "datadescriptor.inc" + +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef CDAC_TYPES_END +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBAL_STRING +#undef CDAC_GLOBALS_END diff --git a/src/coreclr/debug/di/cordb.cpp b/src/coreclr/debug/di/cordb.cpp index d7d3957ec7db26..9f93d0bcfd6dfe 100644 --- a/src/coreclr/debug/di/cordb.cpp +++ b/src/coreclr/debug/di/cordb.cpp @@ -32,10 +32,9 @@ //----------------------------------------------------------------------------- // In v1.0, we declared that mscordbi was a "shared" component, which means // that we promised to provide it from now until the end of time. So every CLR implementation -// needs an Mscordbi that implements the everett guids for CorDebug + CorPublish. +// needs an Mscordbi that implements the everett guids for CorDebug // -// This works fine for CorPublish, which is truly shared. -// CorDebug however is "versioned" not "shared" - each version of the CLR has its own disjoint copy. +// CorDebug is "versioned" not "shared" - each version of the CLR has its own disjoint copy. // // Thus creating a CorDebug object requires a version parameter. // CoCreateInstance doesn't have a the version param, so we use the new (v2.0+) @@ -307,14 +306,6 @@ STDAPI DLLEXPORT DllGetClassObjectInternal( // Return code. CClassFactory *pClassFactory; // To create class factory object. PFN_CREATE_OBJ pfnCreateObject = NULL; - -#if defined(FEATURE_DBG_PUBLISH) - if (rclsid == CLSID_CorpubPublish) - { - pfnCreateObject = CorpubPublish::CreateObject; - } - else -#endif #if defined(FEATURE_DBGIPC_TRANSPORT_DI) if (rclsid == CLSID_CorDebug_Telesto) { diff --git a/src/coreclr/debug/di/module.cpp b/src/coreclr/debug/di/module.cpp index 952f3fd71bd86c..b2736c8b4b8109 100644 --- a/src/coreclr/debug/di/module.cpp +++ b/src/coreclr/debug/di/module.cpp @@ -27,7 +27,7 @@ CordbModule::CordbModule( CordbProcess * pProcess, VMPTR_Module vmModule, VMPTR_DomainAssembly vmDomainAssembly) -: CordbBase(pProcess, vmDomainAssembly.IsNull() ? VmPtrToCookie(vmModule) : VmPtrToCookie(vmDomainAssembly), enumCordbModule), +: CordbBase(pProcess, VmPtrToCookie(vmModule), enumCordbModule), m_pAssembly(0), m_pAppDomain(0), m_classes(11), diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index 28de989969e501..57e436c006300d 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/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)); @@ -15246,7 +15240,10 @@ CordbClass * CordbProcess::LookupClass(ICorDebugAppDomain * pAppDomain, VMPTR_Do if (pAppDomain != NULL) { - CordbModule * pModule = ((CordbAppDomain *)pAppDomain)->m_modules.GetBase(VmPtrToCookie(vmDomainAssembly)); + VMPTR_Module vmModule = VMPTR_Module::NullPtr(); + GetProcess()->GetDAC()->GetModuleForDomainAssembly(vmDomainAssembly, &vmModule); + _ASSERTE(!vmModule.IsNull()); + CordbModule * pModule = ((CordbAppDomain *)pAppDomain)->m_modules.GetBase(VmPtrToCookie(vmModule)); if (pModule != NULL) { return pModule->LookupClass(classToken); diff --git a/src/coreclr/debug/di/publish.cpp b/src/coreclr/debug/di/publish.cpp deleted file mode 100644 index 0a7bad24642885..00000000000000 --- a/src/coreclr/debug/di/publish.cpp +++ /dev/null @@ -1,1198 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// File: publish.cpp -// - -// -//***************************************************************************** - - -#include "stdafx.h" -#ifdef FEATURE_DBG_PUBLISH - -#include "check.h" - -#include - -#ifndef SM_REMOTESESSION -#define SM_REMOTESESSION 0x1000 -#endif - -#include "corpriv.h" -#include "../../dlls/mscorrc/resource.h" -#include - -// Publish shares header files with the rest of ICorDebug. -// ICorDebug should not call ReadProcessMemory & other APIs directly, it should instead go through -// the Data-target. ICD headers #define these APIs to help enforce this. -// Since Publish is separate and doesn't use data-targets, it can access the APIs directly. -// see code:RSDebuggingInfo#UseDataTarget -#undef ReadProcessMemory - -//**************************************************************************** -//************ App Domain Publishing Service API Implementation ************** -//**************************************************************************** - -// This function enumerates all the process in the system and returns -// their PIDs -BOOL GetAllProcessesInSystem(DWORD *ProcessId, - DWORD dwArraySize, - DWORD *pdwNumEntries) -{ - HandleHolder hSnapshotHolder; - - // Create the Process' Snapshot - HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); - if (hSnapshot == INVALID_HANDLE_VALUE) - { - LOG((LF_CORDB, LL_INFO1000, - "Unable to create snapshot of processes in the system. " - "CreateToolhelp32Snapshot() failed.\n")); - return FALSE; - } - // HandleHolder doesn't deal with INVALID_HANDLE_VALUE, so we only assign if we have a legal value. - hSnapshotHolder.Assign(hSnapshot); - - PROCESSENTRY32 PE32; - - // need to initialize the dwSize field before calling Process32First - PE32.dwSize = sizeof (PROCESSENTRY32); - - // Get the first process in the process list - BOOL succ = Process32First(hSnapshot, &PE32); - if (succ != TRUE) - { - LOG((LF_CORDB, LL_INFO1000, - "Unable to create snapshot of processes in the system. " - "Process32First() returned FALSE.\n")); - return FALSE; - } - - // Loop over and get all the remaining processes - int iIndex = 0; - - do - { - ProcessId [iIndex++] = PE32.th32ProcessID; - - succ = Process32Next(hSnapshot, &PE32); - - } while ((succ == TRUE) && (iIndex < (int)dwArraySize)); - - _ASSERTE (iIndex < (int)dwArraySize); - - *pdwNumEntries = iIndex; - - // If we made it this far, we succeeded - return TRUE; -} - - -// We never want to wait infinite on an object that we can't verify. -// Wait with a timeout. -const DWORD SAFETY_TIMEOUT = 2000; - -// ****************************************** -// CorpubPublish -// ****************************************** - -CorpubPublish::CorpubPublish() - : CordbCommonBase(0) - , m_fpGetModuleFileNameEx(NULL) -{ - // Try to get psapi!GetModuleFileNameExW once, and then every process object can use it. - // If we can't get it, then we'll fallback to getting information from the IPC block. - m_hPSAPIdll = WszLoadLibrary(W("api-ms-win-obsolete-psapi-l1-1-0.dll")); - - if (m_hPSAPIdll != NULL) - { - m_fpGetModuleFileNameEx = (FPGetModuleFileNameEx*) GetProcAddress(m_hPSAPIdll, "GetModuleFileNameExW"); - } - - CordbCommonBase::InitializeCommon(); -} - -CorpubPublish::~CorpubPublish() -{ - // m_hPSAPIdll is a module holder, so the dtor will free it automatically for us. -} - - -COM_METHOD CorpubPublish::QueryInterface(REFIID id, void **ppInterface) -{ - if (id == IID_ICorPublish) - *ppInterface = (ICorPublish*)this; - else if (id == IID_IUnknown) - *ppInterface = (IUnknown*)(ICorPublish*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - ExternalAddRef(); - return S_OK; -} - - -COM_METHOD CorpubPublish::EnumProcesses(COR_PUB_ENUMPROCESS Type, - ICorPublishProcessEnum **ppIEnum) -{ - HRESULT hr = E_FAIL; - CorpubProcess* pProcessList = NULL ; - CorpubProcessEnum* pProcEnum = NULL; - *ppIEnum = NULL; - - if( Type != COR_PUB_MANAGEDONLY ) - { - hr = E_INVALIDARG; - goto exit; - } - - // call function to get PIDs for all processes in the system -#define MAX_PROCESSES 512 - - DWORD ProcessId[MAX_PROCESSES]; - DWORD dwNumProcesses = 0; - if( !GetAllProcessesInSystem(ProcessId, MAX_PROCESSES, &dwNumProcesses) ) - { - hr = E_FAIL; - goto exit; - } - - // iterate over all the processes to fetch all the managed processes - for (int i = 0; i < (int)dwNumProcesses; i++) - { - CorpubProcess *pProcess = NULL; - hr = GetProcessInternal( ProcessId[i], &pProcess ); - if( FAILED(hr) ) - { - _ASSERTE( pProcess == NULL ); - goto exit; // a serious error has occurred, abort - } - - if( hr == S_OK ) - { - // Success, Add the process to the list. - _ASSERTE( pProcess != NULL ); - pProcess->SetNext( pProcessList ); - pProcessList = pProcess; - } - else - { - // Ignore this process (isn't managed, or shut down, etc.) - _ASSERTE( pProcess == NULL ); - } - } - - // create and return the ICorPublishProcessEnum - pProcEnum = new (nothrow) CorpubProcessEnum(pProcessList); - if (pProcEnum == NULL) - { - hr = E_OUTOFMEMORY; - goto exit; - } - pProcEnum->AddRef(); - - hr = pProcEnum->QueryInterface(IID_ICorPublishProcessEnum, (void**)ppIEnum); - if( FAILED(hr) ) - { - goto exit; - } - - hr = S_OK; - -exit: - // release our handle on the process objects - while (pProcessList != NULL) - { - CorpubProcess *pTmp = pProcessList; - pProcessList = pProcessList->GetNextProcess(); - pTmp->Release(); - } - if( pProcEnum != NULL ) - { - pProcEnum->Release(); - pProcEnum = NULL; - } - - return hr; -} - - -HRESULT CorpubPublish::GetProcess(unsigned pid, - ICorPublishProcess **ppProcess) -{ - *ppProcess = NULL; - - // Query for this specific process (even if we've already handed out a - // now-stale process object for this pid) - CorpubProcess * pProcess = NULL; - HRESULT hr = GetProcessInternal( pid, &pProcess ); - if( hr != S_OK ) - { - // Couldn't get this process (doesn't exist, or isn't managed) - _ASSERTE( pProcess == NULL ); - if( FAILED(hr) ) - { - return hr; // there was a serious error trying to get this process info - } - return E_INVALIDARG; // this process doesn't exist, isn't managed or is shutting down - } - - // QI to ICorPublishProcess and return it - _ASSERTE( pProcess != NULL ); - hr = pProcess->QueryInterface(IID_ICorPublishProcess, (void**)ppProcess); - pProcess->Release(); - return hr; -} - - -// Attempts to create a CorpubProcess object for a specific managed process -// On success returns S_OK and sets ppProcess to a new AddRef'd CorpubProcess -// object. Otherwise, returns S_FALSE if the process isn't managed or if it has -// terminated (i.e. it should be ignored), or and error code on a serious failure. -HRESULT CorpubPublish::GetProcessInternal( - unsigned pid, - CorpubProcess **ppProcess ) -{ -#if defined(FEATURE_DBGIPC_TRANSPORT_DI) - return E_NOTIMPL; - -#else // !FEATURE_DBGIPC_TRANSPORT_DI - HRESULT hr = S_OK; - *ppProcess = NULL; - - NewHolder pIPCReader( new (nothrow) IPCReaderInterface() ); - if (pIPCReader == NULL) - { - LOG((LF_CORDB, LL_INFO100, "CP::EP: Failed to allocate memory for IPCReaderInterface.\n")); - return E_OUTOFMEMORY; - } - - // See if it is a managed process by trying to open the shared - // memory block. - hr = pIPCReader->OpenLegacyPrivateBlockTempV4OnPid(pid); - if (FAILED(hr)) - { - return S_FALSE; // Not a managed process - } - - // Get the AppDomainIPCBlock - AppDomainEnumerationIPCBlock *pAppDomainCB = pIPCReader->GetAppDomainBlock(); - if (pAppDomainCB == NULL) - { - LOG((LF_CORDB, LL_INFO1000, "CP::EP: Failed to obtain AppDomainIPCBlock.\n")); - return S_FALSE; - } - - // Get the process handle. - HANDLE hProcess = OpenProcess((PROCESS_VM_READ | - PROCESS_QUERY_INFORMATION | - PROCESS_DUP_HANDLE | - SYNCHRONIZE), - FALSE, pid); - if (hProcess == NULL) - { - LOG((LF_CORDB, LL_INFO1000, "CP::EP: OpenProcess() returned NULL handle.\n")); - return S_FALSE; - } - - // If the mutex isn't filled in, the CLR is either starting up or shutting down - if (pAppDomainCB->m_hMutex == NULL) - { - LOG((LF_CORDB, LL_INFO1000, "CP::EP: IPC block isn't properly filled in.\n")); - return S_FALSE; - } - - // Dup the valid mutex handle into this process. - HANDLE hMutex; - if( !pAppDomainCB->m_hMutex.DuplicateToLocalProcess(hProcess, &hMutex) ) - { - return S_FALSE; - } - - // Acquire the mutex, only waiting two seconds. - // We can't actually guarantee that the target put a mutex object in here. - DWORD dwRetVal = WaitForSingleObject(hMutex, SAFETY_TIMEOUT); - - if (dwRetVal == WAIT_OBJECT_0) - { - // Make sure the mutex handle is still valid. If - // its not, then we lost a shutdown race. - if (pAppDomainCB->m_hMutex == NULL) - { - LOG((LF_CORDB, LL_INFO1000, "CP::EP: lost shutdown race, skipping...\n")); - - ReleaseMutex(hMutex); - CloseHandle(hMutex); - return S_FALSE; - } - } - else - { - // Again, landing here is most probably a shutdown race. Its okay, though... - LOG((LF_CORDB, LL_INFO1000, "CP::EP: failed to get IPC mutex.\n")); - - if (dwRetVal == WAIT_ABANDONED) - { - ReleaseMutex(hMutex); - } - CloseHandle(hMutex); - return S_FALSE; - } - // Beware: if the target pid is not properly honoring the mutex, the data in the - // IPC block may still shift underneath us. - - // If we get here, then hMutex is held by this process. - - // Now create the CorpubProcess object for the ProcessID - CorpubProcess *pProc = new (nothrow) CorpubProcess(pid, - true, - hProcess, - hMutex, - pAppDomainCB, - pIPCReader, - m_fpGetModuleFileNameEx); - - // Release our lock on the IPC block. - ReleaseMutex(hMutex); - - if (pProc == NULL) - { - return E_OUTOFMEMORY; - } - pIPCReader.SuppressRelease(); - - // Success, return the Process object - pProc->AddRef(); - *ppProcess = pProc; - return S_OK; - -#endif // FEATURE_DBGIPC_TRANSPORT_DI -} - - - -// ****************************************** -// CorpubProcess -// ****************************************** - -// Constructor -CorpubProcess::CorpubProcess(DWORD dwProcessId, - bool fManaged, - HANDLE hProcess, - HANDLE hMutex, - AppDomainEnumerationIPCBlock *pAD, -#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) - IPCReaderInterface *pIPCReader, -#endif // !FEATURE_DBGIPC_TRANSPORT_DI - FPGetModuleFileNameEx * fpGetModuleFileNameEx) - : CordbCommonBase(0, enumCorpubProcess), - m_dwProcessId(dwProcessId), - m_fIsManaged(fManaged), - m_hProcess(hProcess), - m_hMutex(hMutex), - m_AppDomainCB(pAD), -#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) - m_pIPCReader(pIPCReader), -#endif // !FEATURE_DBGIPC_TRANSPORT_DI - m_pNext(NULL) -{ - { - // First try to get the process name from the OS. That can't be spoofed by badly formed IPC block. - // psapi!GetModuleFileNameExW can get that, but it's not available on all platforms so we - // need to load it dynamically. - if (fpGetModuleFileNameEx != NULL) - { - // MSDN is very confused about whether the length is in bytes (MSDN 2002) or chars (MSDN 2004). - // We err on the safe side by having buffer that's twice as large, and ignoring - // the units on the return value. - WCHAR szName[MAX_LONGPATH * sizeof(WCHAR)]; - - DWORD lenInCharsOrBytes = MAX_LONGPATH*sizeof(WCHAR); - - // Pass NULL module handle to get "Main Module", which will give us the process name. - DWORD ret = (*fpGetModuleFileNameEx) (hProcess, NULL, szName, lenInCharsOrBytes); - if (ret > 0) - { - // Recompute string length because we don't know if 'ret' is in bytes or char. - SIZE_T len = u16_strlen(szName) + 1; - m_szProcessName = new (nothrow) WCHAR[len]; - if (m_szProcessName != NULL) - { - wcscpy_s(m_szProcessName, len, szName); - goto exit; - } - } - } - - // This is a security feature on WinXp + above, so make sure it worked there. - CONSISTENCY_CHECK_MSGF(FALSE, ("On XP/2k03 OSes + above, we should have been able to get\n" - "the module name from psapi!GetModuleFileNameEx. fp=0x%p\n.", fpGetModuleFileNameEx)); - } - // We couldn't get it from the OS, so fallthrough to getting it from the IPC block. - - // Fetch the process name from the AppDomainIPCBlock - _ASSERTE (pAD->m_szProcessName != NULL); - - if (pAD->m_szProcessName == NULL) - m_szProcessName = NULL; - else - { - SIZE_T nBytesRead; - - _ASSERTE(pAD->m_iProcessNameLengthInBytes > 0); - - // Note: this assumes we're reading the null terminator from - // the IPC block. - m_szProcessName = (WCHAR*) new (nothrow) char[pAD->m_iProcessNameLengthInBytes]; - - if (m_szProcessName == NULL) - { - LOG((LF_CORDB, LL_INFO1000, - "CP::CP: Failed to allocate memory for ProcessName.\n")); - - goto exit; - } - - BOOL bSucc = ReadProcessMemory(hProcess, - pAD->m_szProcessName, - m_szProcessName, - pAD->m_iProcessNameLengthInBytes, - &nBytesRead); - - if ((bSucc == 0) || - (nBytesRead != (SIZE_T)pAD->m_iProcessNameLengthInBytes)) - { - // The EE may have done a rude exit - LOG((LF_CORDB, LL_INFO1000, - "CP::EAD: ReadProcessMemory (ProcessName) failed.\n")); - } - } - -exit: - ; -} - -CorpubProcess::~CorpubProcess() -{ - delete [] m_szProcessName; -#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) - delete m_pIPCReader; -#endif // !FEATURE_DBGIPC_TRANSPORT_DI - CloseHandle(m_hProcess); - CloseHandle(m_hMutex); -} - - -HRESULT CorpubProcess::QueryInterface(REFIID id, void **ppInterface) -{ - if (id == IID_ICorPublishProcess) - *ppInterface = (ICorPublishProcess*)this; - else if (id == IID_IUnknown) - *ppInterface = (IUnknown*)(ICorPublishProcess*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - - -// Helper to tell if this process has exited. -bool CorpubProcess::IsExited() -{ - DWORD res = WaitForSingleObject(this->m_hProcess, 0); - return (res == WAIT_OBJECT_0); -} - - -HRESULT CorpubProcess::IsManaged(BOOL *pbManaged) -{ - *pbManaged = (m_fIsManaged == true) ? TRUE : FALSE; - - return S_OK; -} - -// Helper. -// Allocates a local buffer (using 'new') and fills it by copying it from remote memory. -// Returns: -// - on success, S_OK, *ppNewLocalBuffer points to a newly allocated buffer containing -// the full copy from remote memoy. Caller must use 'delete []' to free this. -// - on failure, a failing HR. No memory is allocated. -HRESULT AllocateAndReadRemoteBuffer( - HANDLE hProcess, - void * pRemotePtr, - SIZE_T cbSize, // size of buffer to allocate + copy. - BYTE * * ppNewLocalBuffer -) -{ - _ASSERTE(ppNewLocalBuffer != NULL); - *ppNewLocalBuffer = NULL; - - - if (pRemotePtr == NULL) - { - return E_INVALIDARG; - } - - BYTE *pLocalBuffer = new (nothrow) BYTE[cbSize]; - - if (pLocalBuffer == NULL) - { - _ASSERTE(!"Failed to alloc memory. Likely size is bogusly large, perhaps from an attacker."); - return E_OUTOFMEMORY; - } - - SIZE_T nBytesRead; - - // Need to read in the remote process' memory - BOOL bSucc = ReadProcessMemory(hProcess, - pRemotePtr, - pLocalBuffer, cbSize, - &nBytesRead); - - if ((bSucc == 0) || (nBytesRead != cbSize)) - { - // The EE may have done a rude exit - delete [] pLocalBuffer; - return E_FAIL; - } - - *ppNewLocalBuffer = pLocalBuffer; - return S_OK; -} - -// Wrapper around AllocateAndReadRemoteBuffer, -// to ensure that we're reading an remote-null terminated string. -// Ensures that string is null-terminated. -HRESULT AllocateAndReadRemoteString( - HANDLE hProcess, - void * pRemotePtr, - SIZE_T cbSize, // size of buffer to allocate + copy. - _Outptr_result_bytebuffer_(cbSize) WCHAR * * ppNewLocalBuffer - ) -{ - // Make sure buffer has right geometry. - if (cbSize < 0) - { - return E_INVALIDARG; - } - - // If it's not on a WCHAR boundary, then we may have a 1-byte buffer-overflow. - SIZE_T ceSize = cbSize / sizeof(WCHAR); - if ((ceSize * sizeof(WCHAR)) != cbSize) - { - return E_INVALIDARG; - } - - // It should at least have 1 char for the null terminator. - if (ceSize < 1) - { - return E_INVALIDARG; - } - - - HRESULT hr = AllocateAndReadRemoteBuffer(hProcess, pRemotePtr, cbSize, (BYTE**) ppNewLocalBuffer); - if (SUCCEEDED(hr)) - { - // Ensure that the string we just read is actually null terminated. - // We can't call u16_strlen() on it yet, since that may AV on a non-null terminated string. - WCHAR * pString = *ppNewLocalBuffer; - - if (pString[ceSize - 1] == W('\0')) - { - // String is null terminated. - return S_OK; - } - pString[ceSize - 1] = W('\0'); - - SIZE_T ceTestLen = u16_strlen(pString); - if (ceTestLen == ceSize - 1) - { - // String was not previously null-terminated. - delete [] ppNewLocalBuffer; - return E_INVALIDARG; - } - } - return S_OK; -} - -// -// Enumerate the list of known application domains in the target process. -// -HRESULT CorpubProcess::EnumAppDomains(ICorPublishAppDomainEnum **ppIEnum) -{ - VALIDATE_POINTER_TO_OBJECT(ppIEnum, ICorPublishAppDomainEnum **); - *ppIEnum = NULL; - - int i; - - HRESULT hr = S_OK; - WCHAR *pAppDomainName = NULL; - CorpubAppDomain *pAppDomainHead = NULL; - - // Lock the IPC block: - // We can't trust any of the data in the IPC block (including our own mutex handle), - // because we don't want bugs in the debuggee escalating into bugs in the debugger. - DWORD res = WaitForSingleObject(m_hMutex, SAFETY_TIMEOUT); - - if (res == WAIT_TIMEOUT) - { - // This should only happen if the target process is illbehaved. - return CORDBG_E_TIMEOUT; - } - - // If the process has gone away, or if it has cleared out its control block, then - // we've lost the race to access this process before it is terminated. - // Note that if the EE does a rude process exit, it won't have cleared the control block so there - // will be a small race window. - if (this->IsExited() || this->m_AppDomainCB->m_hMutex == NULL ) - { - // This is the common case. A process holding the mutex shouldn't normally exit, - // but once it releases the mutex, it may exit asynchronously. - return CORDBG_E_PROCESS_TERMINATED; - } - - if (res == WAIT_FAILED) - { - // This should be the next most common failure case - return HRESULT_FROM_GetLastError(); - } - - if (res != WAIT_OBJECT_0) - { - // Catch all other possible failures - return E_FAIL; - } - - int iAppDomainCount = 0; - AppDomainInfo *pADI = NULL; - - // Make a copy of the IPC block so that we can guarantee that it's not changing on us. - AppDomainEnumerationIPCBlock tempBlock; - memcpy(&tempBlock, m_AppDomainCB, sizeof(tempBlock)); - - // Allocate memory to read the remote process' memory into - const SIZE_T cbADI = tempBlock.m_iSizeInBytes; - - // It's possible the process will not have any appdomains. - if ((tempBlock.m_rgListOfAppDomains == NULL) != (tempBlock.m_iSizeInBytes == 0)) - { - _ASSERTE(!"Inconsistent IPC block in publish."); - hr = E_FAIL; - goto exit; - } - - // All the data in the IPC block is signed integers. They should never be negative, - // so check that now. - if ((tempBlock.m_iTotalSlots < 0) || - (tempBlock.m_iNumOfUsedSlots < 0) || - (tempBlock.m_iLastFreedSlot < 0) || - (tempBlock.m_iSizeInBytes < 0) || - (tempBlock.m_iProcessNameLengthInBytes < 0)) - { - hr = E_FAIL; - goto exit; - } - - // Check other invariants. - if (cbADI != tempBlock.m_iTotalSlots * sizeof(AppDomainInfo)) - { - _ASSERTE(!"Size mismatch"); - hr = E_FAIL; - goto exit; - } - - hr = AllocateAndReadRemoteBuffer(m_hProcess, tempBlock.m_rgListOfAppDomains, cbADI, (BYTE**) &pADI); - if (FAILED(hr)) - { - goto exit; - } - _ASSERTE(pADI != NULL); - - // Collect all the AppDomain info info a list of CorpubAppDomains - for (i = 0; i < tempBlock.m_iTotalSlots; i++) - { - if (!pADI[i].IsEmpty()) - { - // Should be positive, and at least have a null-terminator character. - if (pADI[i].m_iNameLengthInBytes <= 1) - { - hr = E_INVALIDARG; - goto exit; - } - hr = AllocateAndReadRemoteString(m_hProcess, - (void*) pADI[i].m_szAppDomainName, pADI[i].m_iNameLengthInBytes, // remote string + size in bytes - &pAppDomainName); - if (FAILED(hr)) - { - goto exit; - } - - // create a new AppDomainObject. This will take ownership of pAppDomainName. - // We know the string is a well-formed null-terminated string, - // but beyond that, we can't verify that the data is actually truthful. - CorpubAppDomain *pCurrentAppDomain = new (nothrow) CorpubAppDomain(pAppDomainName, - pADI[i].m_id); - - if (pCurrentAppDomain == NULL) - { - LOG((LF_CORDB, LL_INFO1000, - "CP::EAD: Failed to allocate memory for CorpubAppDomain.\n")); - - hr = E_OUTOFMEMORY; - goto exit; - } - - // Since CorpubAppDomain now owns pAppDomain's memory, we don't worry about freeing it. - pAppDomainName = NULL; - - // Add the appdomain to the list. - pCurrentAppDomain->SetNext(pAppDomainHead); - pAppDomainHead = pCurrentAppDomain; - - // Shortcut to opt out of reading the rest of the array if it's empty. - if (++iAppDomainCount >= tempBlock.m_iNumOfUsedSlots) - break; - } - } - - { - _ASSERTE ((iAppDomainCount >= tempBlock.m_iNumOfUsedSlots) - && (i <= tempBlock.m_iTotalSlots)); - - // create and return the ICorPublishAppDomainEnum object, handing off the AppDomain list to it - CorpubAppDomainEnum *pTemp = new (nothrow) CorpubAppDomainEnum(pAppDomainHead); - - if (pTemp == NULL) - { - hr = E_OUTOFMEMORY; - goto exit; - } - - pAppDomainHead = NULL; // handed off AppDomain list to enum, don't delete below - - hr = pTemp->QueryInterface(IID_ICorPublishAppDomainEnum, - (void **)ppIEnum); - } - -exit: - ReleaseMutex(m_hMutex); - - // If we didn't hand off the AppDomain objects, delete them - while( pAppDomainHead != NULL ) - { - CorpubAppDomain *pTemp = pAppDomainHead; - pAppDomainHead = pAppDomainHead->GetNextAppDomain(); - delete pTemp; - } - - if (pADI != NULL) - delete[] pADI; - - if (pAppDomainName != NULL) - delete [] pAppDomainName; - - // Either we succeeded && provided an enumerator; or we failed and didn't provide an enum. - _ASSERTE(SUCCEEDED(hr) == (*ppIEnum != NULL)); - return hr; -} - -/* - * Returns the OS ID for the process in question. - */ -HRESULT CorpubProcess::GetProcessID(unsigned *pid) -{ - *pid = m_dwProcessId; - - return S_OK; -} - -/* - * Get the display name for a process. - */ -HRESULT CorpubProcess::GetDisplayName(ULONG32 cchName, - ULONG32 *pcchName, - _Out_writes_to_opt_(cchName, *pcchName) WCHAR szName[]) -{ - VALIDATE_POINTER_TO_OBJECT_ARRAY_OR_NULL(szName, WCHAR, cchName, true, true); - VALIDATE_POINTER_TO_OBJECT_OR_NULL(pcchName, ULONG32 *); - - // Reasonable defaults - if (szName) - *szName = 0; - - if (pcchName) - *pcchName = 0; - - const WCHAR *szTempName = m_szProcessName; - - // In case we didn't get the name (most likely out of memory on ctor). - if (!szTempName) - szTempName = W(""); - - return CopyOutString(szTempName, cchName, pcchName, szName); -} - - -// ****************************************** -// CorpubAppDomain -// ****************************************** - -CorpubAppDomain::CorpubAppDomain (_In_ LPWSTR szAppDomainName, ULONG Id) - : CordbCommonBase (0, enumCorpubAppDomain), - m_pNext (NULL), - m_szAppDomainName (szAppDomainName), - m_id (Id) -{ - _ASSERTE(m_szAppDomainName != NULL); -} - -CorpubAppDomain::~CorpubAppDomain() -{ - delete [] m_szAppDomainName; -} - -HRESULT CorpubAppDomain::QueryInterface (REFIID id, void **ppInterface) -{ - if (id == IID_ICorPublishAppDomain) - *ppInterface = (ICorPublishAppDomain*)this; - else if (id == IID_IUnknown) - *ppInterface = (IUnknown*)(ICorPublishAppDomain*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - - -/* - * Get the name and ID for an application domain. - */ -HRESULT CorpubAppDomain::GetID (ULONG32 *pId) -{ - VALIDATE_POINTER_TO_OBJECT(pId, ULONG32 *); - - *pId = m_id; - - return S_OK; -} - -/* - * Get the name for an application domain. - */ -HRESULT CorpubAppDomain::GetName(ULONG32 cchName, - ULONG32 *pcchName, - _Out_writes_to_opt_(cchName, *pcchName) WCHAR szName[]) -{ - VALIDATE_POINTER_TO_OBJECT_ARRAY_OR_NULL(szName, WCHAR, cchName, true, true); - VALIDATE_POINTER_TO_OBJECT_OR_NULL(pcchName, ULONG32 *); - - const WCHAR *szTempName = m_szAppDomainName; - - // In case we didn't get the name (most likely out of memory on ctor). - if (!szTempName) - szTempName = W(""); - - return CopyOutString(szTempName, cchName, pcchName, szName); -} - - - -// ****************************************** -// CorpubProcessEnum -// ****************************************** - -CorpubProcessEnum::CorpubProcessEnum (CorpubProcess *pFirst) - : CordbCommonBase (0, enumCorpubProcessEnum), - m_pFirst (pFirst), - m_pCurrent (pFirst) -{ - // Increment the ref count on each process, we own the list - CorpubProcess * cur = pFirst; - while( cur != NULL ) - { - cur->AddRef(); - cur = cur->GetNextProcess(); - } -} - -CorpubProcessEnum::~CorpubProcessEnum() -{ - // Release each process in the list (our client may still have a reference - // to some of them) - while (m_pFirst != NULL) - { - CorpubProcess *pTmp = m_pFirst; - m_pFirst = m_pFirst->GetNextProcess(); - pTmp->Release(); - } -} - -HRESULT CorpubProcessEnum::QueryInterface (REFIID id, void **ppInterface) -{ - if (id == IID_ICorPublishProcessEnum) - *ppInterface = (ICorPublishProcessEnum*)this; - else if (id == IID_IUnknown) - *ppInterface = (IUnknown*)(ICorPublishProcessEnum*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - - -HRESULT CorpubProcessEnum::Skip(ULONG celt) -{ - while ((m_pCurrent != NULL) && (celt-- > 0)) - { - m_pCurrent = m_pCurrent->GetNextProcess(); - } - - return S_OK; -} - -HRESULT CorpubProcessEnum::Reset() -{ - m_pCurrent = m_pFirst; - - return S_OK; -} - -HRESULT CorpubProcessEnum::Clone(ICorPublishEnum **ppEnum) -{ - VALIDATE_POINTER_TO_OBJECT(ppEnum, ICorPublishEnum **); - return E_NOTIMPL; -} - -HRESULT CorpubProcessEnum::GetCount(ULONG *pcelt) -{ - VALIDATE_POINTER_TO_OBJECT(pcelt, ULONG *); - - CorpubProcess *pTemp = m_pFirst; - - *pcelt = 0; - - while (pTemp != NULL) - { - (*pcelt)++; - pTemp = pTemp->GetNextProcess(); - } - - return S_OK; -} - -HRESULT CorpubProcessEnum::Next(ULONG celt, - ICorPublishProcess *objects[], - ULONG *pceltFetched) -{ - VALIDATE_POINTER_TO_OBJECT_ARRAY(objects, ICorPublishProcess *, - celt, true, true); - VALIDATE_POINTER_TO_OBJECT_OR_NULL(pceltFetched, ULONG *); - - if ((pceltFetched == NULL) && (celt != 1)) - { - return E_INVALIDARG; - } - - if (celt == 0) - { - if (pceltFetched != NULL) - { - *pceltFetched = 0; - } - return S_OK; - } - - HRESULT hr = S_OK; - - ULONG count = 0; - - while ((m_pCurrent != NULL) && (count < celt)) - { - hr = m_pCurrent->QueryInterface (IID_ICorPublishProcess, - (void**)&objects[count]); - - if (hr != S_OK) - { - break; - } - - count++; - m_pCurrent = m_pCurrent->GetNextProcess(); - } - - if (pceltFetched != NULL) - { - *pceltFetched = count; - } - - // - // If we reached the end of the enumeration, but not the end - // of the number of requested items, we return S_FALSE. - // - if (count < celt) - { - return S_FALSE; - } - - return hr; -} - -// ****************************************** -// CorpubAppDomainEnum -// ****************************************** -CorpubAppDomainEnum::CorpubAppDomainEnum (CorpubAppDomain *pFirst) - : CordbCommonBase (0, enumCorpubAppDomainEnum), - m_pFirst (pFirst), - m_pCurrent (pFirst) -{ - CorpubAppDomain *pCur = pFirst; - while( pCur != NULL ) - { - pCur->AddRef(); - pCur = pCur->GetNextAppDomain(); - } -} - -CorpubAppDomainEnum::~CorpubAppDomainEnum() -{ - // Delete all the app domains - while (m_pFirst != NULL ) - { - CorpubAppDomain *pTemp = m_pFirst; - m_pFirst = m_pFirst->GetNextAppDomain(); - pTemp->Release(); - } -} - -HRESULT CorpubAppDomainEnum::QueryInterface (REFIID id, void **ppInterface) -{ - if (id == IID_ICorPublishAppDomainEnum) - *ppInterface = (ICorPublishAppDomainEnum*)this; - else if (id == IID_IUnknown) - *ppInterface = (IUnknown*)(ICorPublishAppDomainEnum*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - - -HRESULT CorpubAppDomainEnum::Skip(ULONG celt) -{ - while ((m_pCurrent != NULL) && (celt-- > 0)) - { - m_pCurrent = m_pCurrent->GetNextAppDomain(); - } - - return S_OK; -} - -HRESULT CorpubAppDomainEnum::Reset() -{ - m_pCurrent = m_pFirst; - - return S_OK; -} - -HRESULT CorpubAppDomainEnum::Clone(ICorPublishEnum **ppEnum) -{ - VALIDATE_POINTER_TO_OBJECT(ppEnum, ICorPublishEnum **); - return E_NOTIMPL; -} - -HRESULT CorpubAppDomainEnum::GetCount(ULONG *pcelt) -{ - VALIDATE_POINTER_TO_OBJECT(pcelt, ULONG *); - - CorpubAppDomain *pTemp = m_pFirst; - - *pcelt = 0; - - while (pTemp != NULL) - { - (*pcelt)++; - pTemp = pTemp->GetNextAppDomain(); - } - - return S_OK; -} - -HRESULT CorpubAppDomainEnum::Next(ULONG celt, - ICorPublishAppDomain *objects[], - ULONG *pceltFetched) -{ - VALIDATE_POINTER_TO_OBJECT_ARRAY(objects, ICorPublishProcess *, - celt, true, true); - VALIDATE_POINTER_TO_OBJECT_OR_NULL(pceltFetched, ULONG *); - - if ((pceltFetched == NULL) && (celt != 1)) - { - return E_INVALIDARG; - } - - if (celt == 0) - { - if (pceltFetched != NULL) - { - *pceltFetched = 0; - } - return S_OK; - } - - HRESULT hr = S_OK; - - ULONG count = 0; - - while ((m_pCurrent != NULL) && (count < celt)) - { - hr = m_pCurrent->QueryInterface (IID_ICorPublishAppDomain, - (void **)&objects[count]); - - if (hr != S_OK) - { - break; - } - - count++; - m_pCurrent = m_pCurrent->GetNextAppDomain(); - } - - - if (pceltFetched != NULL) - { - *pceltFetched = count; - } - - // - // If we reached the end of the enumeration, but not the end - // of the number of requested items, we return S_FALSE. - // - if (count < celt) - { - return S_FALSE; - } - - return hr; -} - -#endif // defined(FEATURE_DBG_PUBLISH) diff --git a/src/coreclr/debug/di/rsappdomain.cpp b/src/coreclr/debug/di/rsappdomain.cpp index dfc3c774ea7a18..a4a59d09ffbd77 100644 --- a/src/coreclr/debug/di/rsappdomain.cpp +++ b/src/coreclr/debug/di/rsappdomain.cpp @@ -834,15 +834,25 @@ CordbModule* CordbAppDomain::LookupOrCreateModule(VMPTR_Module vmModule, VMPTR_D _ASSERTE(!vmDomainAssembly.IsNull() || !vmModule.IsNull()); + if (vmModule.IsNull()) + GetProcess()->GetDAC()->GetModuleForDomainAssembly(vmDomainAssembly, &vmModule); + + _ASSERTE(!vmModule.IsNull()); + // check to see if the module is present in this app domain - pModule = m_modules.GetBase(vmDomainAssembly.IsNull() ? VmPtrToCookie(vmModule) : VmPtrToCookie(vmDomainAssembly)); + pModule = m_modules.GetBase(VmPtrToCookie(vmModule)); if (pModule != NULL) { return pModule; } - if (vmModule.IsNull()) - GetProcess()->GetDAC()->GetModuleForDomainAssembly(vmDomainAssembly, &vmModule); + if (vmDomainAssembly.IsNull()) + { + // If we don't have a domain assembly, we can look it up from the module. + GetProcess()->GetDAC()->GetDomainAssemblyFromModule(vmModule, &vmDomainAssembly); + } + + _ASSERTE(!vmDomainAssembly.IsNull()); RSInitHolder pModuleInit(new CordbModule(GetProcess(), vmModule, vmDomainAssembly)); pModule = pModuleInit.TransferOwnershipToHash(&m_modules); diff --git a/src/coreclr/debug/di/rsmain.cpp b/src/coreclr/debug/di/rsmain.cpp index 33c9e82878c30e..d34c84974a0bb7 100644 --- a/src/coreclr/debug/di/rsmain.cpp +++ b/src/coreclr/debug/di/rsmain.cpp @@ -452,7 +452,7 @@ void LeftSideResourceCleanupList::SweepNeuterLeftSideResources(CordbProcess * pP * ------------------------------------------------------------------------- */ extern void* GetClrModuleBase(); -// Do any initialization necessary for both CorPublish and CorDebug +// Do any initialization necessary for CorDebug // This includes enabling logging and adding the SEDebug priv. void CordbCommonBase::InitializeCommon() { diff --git a/src/coreclr/debug/di/rspriv.h b/src/coreclr/debug/di/rspriv.h index d0be92394f1500..21a7703838f134 100644 --- a/src/coreclr/debug/di/rspriv.h +++ b/src/coreclr/debug/di/rspriv.h @@ -114,13 +114,6 @@ class CordbEval; class CordbMDA; -class CorpubPublish; -class CorpubProcess; -class CorpubAppDomain; -class CorpubProcessEnum; -class CorpubAppDomainEnum; - - class RSLock; class NeuterList; @@ -1094,11 +1087,11 @@ typedef enum { enumCordbEnCSnapshot, // 21 enumCordbEval, // 22 enumCordbUnmanagedThread,// 23 - enumCorpubPublish, // 24 - enumCorpubProcess, // 25 - enumCorpubAppDomain, // 26 - enumCorpubProcessEnum, // 27 - enumCorpubAppDomainEnum,// 28 + // unused, // 24 + // unused, // 25 + // unused, // 26 + // unused, // 27 + // unused, // 28 enumCordbEnumFilter, // 29 enumCordbEnCErrorInfo, // 30 enumCordbEnCErrorInfoEnum,//31 @@ -1157,7 +1150,7 @@ class CordbHashTable; #define CORDB_COMMON_BASE_SIGNATURE 0x0d00d96a #define CORDB_COMMON_BASE_SIGNATURE_DEAD 0x0dead0b1 -// Common base for both CorPublish + CorDebug objects. +// Common base for CorDebug objects. class CordbCommonBase : public IUnknown { public: @@ -10691,12 +10684,6 @@ class CordbUnmanagedThread : public CordbBase }; #endif // FEATURE_INTEROP_DEBUGGING - -//******************************************************************************** -//**************** App Domain Publishing Service API ***************************** -//******************************************************************************** - - class EnumElement { public: @@ -10716,293 +10703,6 @@ class EnumElement EnumElement *m_pNext; }; -#if defined(FEATURE_DBG_PUBLISH) - -// Prototype of psapi!GetModuleFileNameEx. -typedef DWORD FPGetModuleFileNameEx(HANDLE, HMODULE, LPTSTR, DWORD); - - -class CorpubPublish : public CordbCommonBase, public ICorPublish -{ -public: - CorpubPublish(); - virtual ~CorpubPublish(); - -#ifdef _DEBUG - virtual const char * DbgGetName() { return "CordbPublish"; } -#endif - - //----------------------------------------------------------- - // IUnknown - //----------------------------------------------------------- - - ULONG STDMETHODCALLTYPE AddRef() - { - return (BaseAddRef()); - } - ULONG STDMETHODCALLTYPE Release() - { - return (BaseRelease()); - } - COM_METHOD QueryInterface(REFIID riid, void **ppInterface); - - //----------------------------------------------------------- - // ICorPublish - //----------------------------------------------------------- - - COM_METHOD EnumProcesses( - COR_PUB_ENUMPROCESS Type, - ICorPublishProcessEnum **ppIEnum); - - COM_METHOD GetProcess( - unsigned pid, - ICorPublishProcess **ppProcess); - - //----------------------------------------------------------- - // CreateObject - //----------------------------------------------------------- - static COM_METHOD CreateObject(REFIID id, void **object) - { - *object = NULL; - - if (id != IID_IUnknown && id != IID_ICorPublish) - return (E_NOINTERFACE); - - CorpubPublish *pCorPub = new (nothrow) CorpubPublish(); - - if (pCorPub == NULL) - return (E_OUTOFMEMORY); - - *object = (ICorPublish*)pCorPub; - pCorPub->AddRef(); - - return (S_OK); - } - -private: - HRESULT GetProcessInternal( unsigned pid, CorpubProcess **ppProcess ); - - // Cached information to get the process name. Not available on all platforms, so may be null. - HModuleHolder m_hPSAPIdll; - FPGetModuleFileNameEx * m_fpGetModuleFileNameEx; -}; - -class CorpubProcess : public CordbCommonBase, public ICorPublishProcess -{ -public: - CorpubProcess(const ProcessDescriptor * pProcessDescriptor, - bool fManaged, - HANDLE hProcess, - HANDLE hMutex, - AppDomainEnumerationIPCBlock *pAD, -#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) - IPCReaderInterface *pIPCReader, -#endif // !FEATURE_DBGIPC_TRANSPORT_DI - FPGetModuleFileNameEx * fpGetModuleFileNameEx); - virtual ~CorpubProcess(); - -#ifdef _DEBUG - virtual const char * DbgGetName() { return "CorpubProcess"; } -#endif - - - //----------------------------------------------------------- - // IUnknown - //----------------------------------------------------------- - - ULONG STDMETHODCALLTYPE AddRef() - { - return (BaseAddRef()); - } - ULONG STDMETHODCALLTYPE Release() - { - return (BaseRelease()); - } - COM_METHOD QueryInterface(REFIID riid, void **ppInterface); - - //----------------------------------------------------------- - // ICorPublishProcess - //----------------------------------------------------------- - COM_METHOD IsManaged(BOOL *pbManaged); - - /* - * Enumerate the list of known application domains in the target process. - */ - COM_METHOD EnumAppDomains(ICorPublishAppDomainEnum **ppEnum); - - /* - * Returns the OS ID for the process in question. - */ - COM_METHOD GetProcessID(unsigned *pid); - - /* - * Get the display name for a process. - */ - COM_METHOD GetDisplayName(ULONG32 cchName, - ULONG32 *pcchName, - _Out_writes_to_opt_(cchName, *pcchName) WCHAR szName[]); - - CorpubProcess *GetNextProcess () { return m_pNext;} - void SetNext (CorpubProcess *pNext) { m_pNext = pNext;} - - // Helper to tell if this process has exited - bool IsExited(); - -public: - ProcessDescriptor m_processDescriptor; - -private: - bool m_fIsManaged; - HANDLE m_hProcess; - HANDLE m_hMutex; - AppDomainEnumerationIPCBlock *m_AppDomainCB; -#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) - IPCReaderInterface *m_pIPCReader; // controls the lifetime of the AppDomainEnumerationIPCBlock -#endif // !FEATURE_DBGIPC_TRANSPORT_DI - CorpubProcess *m_pNext; // pointer to the next process in the process list - WCHAR *m_szProcessName; - -}; - -class CorpubAppDomain : public CordbCommonBase, public ICorPublishAppDomain -{ -public: - CorpubAppDomain (_In_ LPWSTR szAppDomainName, ULONG Id); - virtual ~CorpubAppDomain(); - -#ifdef _DEBUG - virtual const char * DbgGetName() { return "CorpubAppDomain"; } -#endif - - //----------------------------------------------------------- - // IUnknown - //----------------------------------------------------------- - - ULONG STDMETHODCALLTYPE AddRef() - { - return (BaseAddRef()); - } - ULONG STDMETHODCALLTYPE Release() - { - return (BaseRelease()); - } - COM_METHOD QueryInterface (REFIID riid, void **ppInterface); - - //----------------------------------------------------------- - // ICorPublishAppDomain - //----------------------------------------------------------- - - /* - * Get the name and ID for an application domain. - */ - COM_METHOD GetID (ULONG32 *pId); - - /* - * Get the name for an application domain. - */ - COM_METHOD GetName (ULONG32 cchName, - ULONG32 *pcchName, - _Out_writes_to_opt_(cchName, *pcchName) WCHAR szName[]); - - CorpubAppDomain *GetNextAppDomain () { return m_pNext;} - void SetNext (CorpubAppDomain *pNext) { m_pNext = pNext;} - -private: - CorpubAppDomain *m_pNext; - WCHAR *m_szAppDomainName; - ULONG m_id; - -}; - -class CorpubProcessEnum : public CordbCommonBase, public ICorPublishProcessEnum -{ -public: - CorpubProcessEnum(CorpubProcess *pFirst); - virtual ~CorpubProcessEnum(); - -#ifdef _DEBUG - virtual const char * DbgGetName() { return "CorpubProcessEnum"; } -#endif - - - //----------------------------------------------------------- - // IUnknown - //----------------------------------------------------------- - - ULONG STDMETHODCALLTYPE AddRef() - { - return (BaseAddRef()); - } - ULONG STDMETHODCALLTYPE Release() - { - return (BaseRelease()); - } - COM_METHOD QueryInterface(REFIID riid, void **ppInterface); - - //----------------------------------------------------------- - // ICorPublishProcessEnum - //----------------------------------------------------------- - - COM_METHOD Skip(ULONG celt); - COM_METHOD Reset(); - COM_METHOD Clone(ICorPublishEnum **ppEnum); - COM_METHOD GetCount(ULONG *pcelt); - COM_METHOD Next(ULONG celt, - ICorPublishProcess *objects[], - ULONG *pceltFetched); - -private: - CorpubProcess *m_pFirst; - CorpubProcess *m_pCurrent; - -}; - -class CorpubAppDomainEnum : public CordbCommonBase, public ICorPublishAppDomainEnum -{ -public: - CorpubAppDomainEnum(CorpubAppDomain *pFirst); - virtual ~CorpubAppDomainEnum(); - - -#ifdef _DEBUG - virtual const char * DbgGetName() { return "CordbAppDomainEnum"; } -#endif - - - //----------------------------------------------------------- - // IUnknown - //----------------------------------------------------------- - - ULONG STDMETHODCALLTYPE AddRef() - { - return (BaseAddRef()); - } - ULONG STDMETHODCALLTYPE Release() - { - return (BaseRelease()); - } - COM_METHOD QueryInterface(REFIID riid, void **ppInterface); - - //----------------------------------------------------------- - // ICorPublishAppDomainEnum - //----------------------------------------------------------- - COM_METHOD Skip(ULONG celt); - COM_METHOD Reset(); - COM_METHOD Clone(ICorPublishEnum **ppEnum); - COM_METHOD GetCount(ULONG *pcelt); - - COM_METHOD Next(ULONG celt, - ICorPublishAppDomain *objects[], - ULONG *pceltFetched); - -private: - CorpubAppDomain *m_pFirst; - CorpubAppDomain *m_pCurrent; - -}; - -#endif // defined(FEATURE_DBG_PUBLISH) - class CordbHeapEnum : public CordbBase, public ICorDebugHeapEnum { public: diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index 8b9ec41240ea59..07e591d15fb116 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/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/coreclr/debug/di/shimstackwalk.cpp b/src/coreclr/debug/di/shimstackwalk.cpp index 64ea5d7ad7d918..d3385d2cc40ceb 100644 --- a/src/coreclr/debug/di/shimstackwalk.cpp +++ b/src/coreclr/debug/di/shimstackwalk.cpp @@ -1202,7 +1202,7 @@ BOOL ShimStackWalk::CheckInternalFrame(ICorDebugFrame * pNextStackFrame, // Special handling for the case where a managed method contains a M2U internal frame. // Normally only IL stubs contain M2U internal frames, but we may have inlined pinvoke calls in // optimized code. In that case, we would have an InlinedCallFrame in a normal managed method on x86. - // On WIN64, we would have a normal NDirectMethodFrame* in a normal managed method. + // On WIN64, we would have a normal PInvokeMethodFrame* in a normal managed method. if (pStackWalkInfo->m_internalFrameType == STUBFRAME_M2U) { // create a temporary ICDStackWalk diff --git a/src/coreclr/debug/di/stdafx.h b/src/coreclr/debug/di/stdafx.h index 8ee806f88f2718..0f1ae48265b9de 100644 --- a/src/coreclr/debug/di/stdafx.h +++ b/src/coreclr/debug/di/stdafx.h @@ -29,7 +29,6 @@ using std::max; #include "ex.h" #include "sigparser.h" -#include "corpub.h" #include "rspriv.h" // This is included to deal with GCC limitations around templates. diff --git a/src/coreclr/debug/ee/controller.cpp b/src/coreclr/debug/ee/controller.cpp index a7bed1a1001bfd..794f0a693bfeb8 100644 --- a/src/coreclr/debug/ee/controller.cpp +++ b/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) @@ -5929,7 +5921,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in) #endif // Note: we used to pass in the IP from the active frame to GetJitInfo, but there seems to be no value in that, and - // it was causing problems creating a stepper while sitting in ndirect stubs after we'd returned from the unmanaged + // it was causing problems creating a stepper while sitting in PInvoke stubs after we'd returned from the unmanaged // function that had been called. DebuggerJitInfo *ji = info->m_activeFrame.GetJitInfoFromFrame(); if( ji != NULL ) @@ -6545,7 +6537,7 @@ void DebuggerStepper::TrapStepOut(ControllerStackInfo *info, bool fForceTraditio _ASSERTE(dji != NULL); // Note: we used to pass in the IP from the active frame to GetJitInfo, but there seems to be no value - // in that, and it was causing problems creating a stepper while sitting in ndirect stubs after we'd + // in that, and it was causing problems creating a stepper while sitting in PInvoke stubs after we'd // returned from the unmanaged function that had been called. ULONG reloffset = info->m_activeFrame.relOffset; @@ -6824,7 +6816,7 @@ bool DebuggerStepper::SetRangesFromIL(DebuggerJitInfo *dji, COR_DEBUG_STEP_RANGE CONTRACTL_END; // Note: we used to pass in the IP from the active frame to GetJitInfo, but there seems to be no value in that, and - // it was causing problems creating a stepper while sitting in ndirect stubs after we'd returned from the unmanaged + // it was causing problems creating a stepper while sitting in PInvoke stubs after we'd returned from the unmanaged // function that had been called. MethodDesc *fd = dji->m_nativeCodeVersion.GetMethodDesc(); diff --git a/src/coreclr/debug/ee/controller.h b/src/coreclr/debug/ee/controller.h index b02cd2802d91ad..32138edc36aba7 100644 --- a/src/coreclr/debug/ee/controller.h +++ b/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/coreclr/debug/ee/dactable.cpp b/src/coreclr/debug/ee/dactable.cpp index 80d1995acf8928..9c65b163cf2799 100644 --- a/src/coreclr/debug/ee/dactable.cpp +++ b/src/coreclr/debug/ee/dactable.cpp @@ -18,15 +18,11 @@ #include "../../vm/common.h" #include "../../vm/gcenv.h" #include "../../vm/ecall.h" +#include "../../vm/cdacplatformmetadata.hpp" #ifdef DEBUGGING_SUPPORTED -extern PTR_ECHash gFCallMethods[FCALL_HASH_SIZE]; -extern TADDR gLowestFCall; -extern TADDR gHighestFCall; extern PCODE g_FCDynamicallyAssignedImplementations[ECall::NUM_DYNAMICALLY_ASSIGNED_FCALL_IMPLEMENTATIONS]; -extern DWORD gThreadTLSIndex; -extern DWORD gAppDomainTLSIndex; extern "C" void STDCALL ThePreStubPatchLabel(void); #ifdef FEATURE_COMWRAPPERS diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 914b4abf61957a..9bc5cda485d176 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -926,7 +926,6 @@ Debugger::Debugger() m_jitAttachInProgress(FALSE), m_launchingDebugger(FALSE), m_LoggingEnabled(TRUE), - m_pAppDomainCB(NULL), m_dClassLoadCallbackCount(0), m_pModules(NULL), m_RSRequestedSync(FALSE), @@ -1896,22 +1895,6 @@ HRESULT Debugger::Startup(void) InitializeHijackFunctionAddress(); - // Also initialize the AppDomainEnumerationIPCBlock - #if !defined(FEATURE_IPCMAN) || defined(FEATURE_DBGIPC_TRANSPORT_VM) - m_pAppDomainCB = new (nothrow) AppDomainEnumerationIPCBlock(); - #else - m_pAppDomainCB = g_pIPCManagerInterface->GetAppDomainBlock(); - #endif - - if (m_pAppDomainCB == NULL) - { - LOG((LF_CORDB, LL_INFO100, "D::S: Failed to get AppDomain IPC block from IPCManager.\n")); - ThrowHR(E_FAIL); - } - - hr = InitAppDomainIPC(); - _ASSERTE(SUCCEEDED(hr)); // throws on error. - // Allows the debugger (and profiler) diagnostics to be disabled so resources like // the named pipes and semaphores are not created. if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableDiagnostics) == 0) @@ -1939,7 +1922,7 @@ HRESULT Debugger::Startup(void) #if defined(FEATURE_DBGIPC_TRANSPORT_VM) // Create transport session and initialize it. g_pDbgTransport = new DbgTransportSession(); - hr = g_pDbgTransport->Init(m_pRCThread->GetDCB(), m_pAppDomainCB); + hr = g_pDbgTransport->Init(m_pRCThread->GetDCB()); if (FAILED(hr)) { ShutdownTransport(); @@ -2286,10 +2269,10 @@ void DebuggerLazyInit::Init() DebuggerLazyInit::~DebuggerLazyInit() { { - USHORT cBlobs = m_pMemBlobs.Count(); + INT32 cBlobs = m_pMemBlobs.Count(); void **rgpBlobs = m_pMemBlobs.Table(); - for (int i = 0; i < cBlobs; i++) + for (INT32 i = 0; i < cBlobs; i++) { g_pDebugger->ReleaseRemoteBuffer(rgpBlobs[i], false); } @@ -2406,9 +2389,6 @@ void Debugger::StopDebugger(void) m_pRCThread->AsyncStop(); } - // Also clean up the AppDomain stuff since this is cross-process. - TerminateAppDomainIPC (); - // // Tell the VM to clear out all references to the debugger before we start cleaning up, // so that nothing will reference (accidentally) through the partially cleaned up debugger. @@ -2508,7 +2488,10 @@ void Debugger::JITComplete(NativeCodeVersion nativeCodeVersion, TADDR newAddress // Can be called on managed thread only // This API Implements DebugInterface +#ifndef DEBUG // We need to do this in debug builds so that the ValidateILOffsets method can be called + // TODO: We may wish to remove this in the future. if (CORDebuggerAttached()) +#endif { // Populate the debugger's cache of DJIs. Normally we can do this lazily, // the only reason we do it here is b/c the MethodDesc is not yet officially marked as "jitted", @@ -2876,10 +2859,11 @@ HRESULT Debugger::GetILToNativeMapping(PCODE pNativeCodeStartAddress, ULONG32 cM { DebugInfoRequest diq; diq.InitFromStartingAddr(fd, pNativeCodeStartAddress); + // TODO This is currently returning the instrumented boundaries, but the path for non-dynamic methods returns uninstrumented ones. if (cMap == 0) { - if (DebugInfoManager::GetBoundariesAndVars(diq, nullptr, nullptr, pcMap, nullptr, nullptr, nullptr)) + if (DebugInfoManager::GetBoundariesAndVars(diq, nullptr, nullptr, BoundsType::Instrumented, pcMap, nullptr, nullptr, nullptr)) { return S_OK; } @@ -2888,7 +2872,7 @@ HRESULT Debugger::GetILToNativeMapping(PCODE pNativeCodeStartAddress, ULONG32 cM } ICorDebugInfo::OffsetMapping* pMap = nullptr; - if (DebugInfoManager::GetBoundariesAndVars(diq, InteropSafeNoThrowNew, nullptr, pcMap, &pMap, nullptr, nullptr)) + if (DebugInfoManager::GetBoundariesAndVars(diq, InteropSafeNoThrowNew, nullptr, BoundsType::Instrumented, pcMap, &pMap, nullptr, nullptr)) { for (ULONG32 i = 0; i < cMap; ++i) { @@ -2992,7 +2976,7 @@ HRESULT Debugger::GetILToNativeMapping(PCODE pNativeCodeStartAddress, ULONG32 cM // events for the same MethodDesc (each time it's EnC'd), with each event // corresponding to the most recent EnC version at the time. // - +#ifdef DEBUG HRESULT Debugger::GetILToNativeMappingIntoArrays( MethodDesc * pMethodDesc, PCODE pNativeCodeStartAddress, @@ -3063,8 +3047,7 @@ HRESULT Debugger::GetILToNativeMappingIntoArrays( return S_OK; } - - +#endif // DEBUG #endif // #ifndef DACCESS_COMPILE @@ -9177,7 +9160,7 @@ BOOL Debugger::SuspendComplete(bool isEESuspendedForGC) //--------------------------------------------------------------------------------------- // -// Debugger::SendCreateAppDomainEvent - notify the RS of an AppDomain +// Debugger::AppDomainCreated - notify the RS of an AppDomain // // Arguments: // pRuntimeAppdomain - pointer to the AppDomain @@ -9187,18 +9170,13 @@ BOOL Debugger::SuspendComplete(bool isEESuspendedForGC) // // Notes: // This is used to notify the debugger of either a newly created -// AppDomain (when fAttaching is FALSE) or of existing AppDomains -// at attach time (fAttaching is TRUE). In both cases, this should +// AppDomain. This should // be called before any LoadModule/LoadAssembly events are sent for // this domain. Otherwise the RS will get an event for an AppDomain // it doesn't recognize and ASSERT. // -// For the non-attach case this means there is no need to enumerate -// the assemblies/modules in an AppDomain after sending this event -// because we know there won't be any. -// -void Debugger::SendCreateAppDomainEvent(AppDomain * pRuntimeAppDomain) +void Debugger::AppDomainCreated(AppDomain * pRuntimeAppDomain) { CONTRACTL { @@ -9222,8 +9200,6 @@ void Debugger::SendCreateAppDomainEvent(AppDomain * pRuntimeAppDomain) Thread *pThread = g_pEEInterface->GetThread(); SENDIPCEVENT_BEGIN(this, pThread); - - // We may have detached while waiting in LockForEventSending, // in which case we can't send the event. if (CORDebuggerAttached()) @@ -9247,62 +9223,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. // @@ -9787,43 +9707,31 @@ BOOL Debugger::SendSystemClassLoadUnloadEvent(mdTypeDef classMetadataToken, Assembly *pAssembly = classModule->GetAssembly(); - if (!m_pAppDomainCB->Lock()) - return (FALSE); + AppDomain *pAppDomain = GetAppDomain(); + _ASSERTE(pAppDomain != NULL); - AppDomainInfo *pADInfo = m_pAppDomainCB->FindFirst(); - - while (pADInfo != NULL) + // Only notify for app domains where the module has been fully loaded already + // We used to make a different check here domain->ContainsAssembly() but that + // triggers too early in the loading process. FindDomainAssembly will not become + // non-NULL until the module is fully loaded into the domain which is what we + // want. + if (classModule->GetDomainAssembly() != NULL ) { - AppDomain *pAppDomain = pADInfo->m_pAppDomain; - _ASSERTE(pAppDomain != NULL); + // Find the Left Side module that this class belongs in. + DebuggerModule* pModule = LookupOrCreateModule(classModule); + _ASSERTE(pModule != NULL); - // Only notify for app domains where the module has been fully loaded already - // We used to make a different check here domain->ContainsAssembly() but that - // triggers too early in the loading process. FindDomainAssembly will not become - // non-NULL until the module is fully loaded into the domain which is what we - // want. - if (classModule->GetDomainAssembly() != NULL ) + // Only send a class load event if they're enabled for this module. + if (pModule && pModule->ClassLoadCallbacksEnabled()) { - // Find the Left Side module that this class belongs in. - DebuggerModule* pModule = LookupOrCreateModule(classModule); - _ASSERTE(pModule != NULL); - - // Only send a class load event if they're enabled for this module. - if (pModule && pModule->ClassLoadCallbacksEnabled()) - { - SendClassLoadUnloadEvent(classMetadataToken, - pModule, - pAssembly, - fIsLoadEvent); - fRetVal = TRUE; - } + SendClassLoadUnloadEvent(classMetadataToken, + pModule, + pAssembly, + fIsLoadEvent); + fRetVal = TRUE; } - - pADInfo = m_pAppDomainCB->FindNext(pADInfo); } - m_pAppDomainCB->Unlock(); - return fRetVal; } @@ -12151,10 +12059,10 @@ HRESULT Debugger::ReleaseRemoteBuffer(void *pBuffer, bool removeFromBlobList) // Remove the buffer from the blob list if necessary. if (removeFromBlobList) { - USHORT cBlobs = GetMemBlobs()->Count(); + INT32 cBlobs = GetMemBlobs()->Count(); void **rgpBlobs = GetMemBlobs()->Table(); - USHORT i; + INT32 i; for (i = 0; i < cBlobs; i++) { if (rgpBlobs[i] == pBuffer) @@ -14540,399 +14448,6 @@ void Debugger::SendCustomDebuggerNotification(Thread * pThread, SENDIPCEVENT_END; } - -//----------------------------------------------------------------------------- -// -// Add the AppDomain to the list stored in the IPC block. It adds the id and -// the name. -// -// Arguments: -// pAppDomain - The runtime app domain object to add. -// -// Return Value: -// S_OK on success, else detailed error code. -// -HRESULT Debugger::AddAppDomainToIPC(AppDomain *pAppDomain) -{ - CONTRACTL - { - MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - LPCWSTR szName = NULL; - - LOG((LF_CORDB, LL_INFO100, "D::AADTIPC: Executing AADTIPC for AppDomain 0x%08x.\n", - pAppDomain)); - - STRESS_LOG1(LF_CORDB, LL_INFO10000, "D::AADTIPC: AddAppDomainToIPC:%#08x\n", - pAppDomain); - - - - _ASSERTE(m_pAppDomainCB->m_iTotalSlots > 0); - _ASSERTE(m_pAppDomainCB->m_rgListOfAppDomains != NULL); - - { - // - // We need to synchronize this routine with the attach logic. The "normal" - // attach case uses the HelperThread and TrapAllRuntimeThreads to synchronize - // the runtime before sending any of the events (including AppDomainCreates) - // to the right-side. Thus, we can synchronize with this case by forcing us - // to go co-operative. If we were already co-op, then the helper thread will - // wait to start the attach until all co-op threads are paused. If we were - // pre-emptive, then going co-op will suspend us until the HelperThread finishes. - // - // The second case is under the IPC event for ATTACHING, which is where there are - // zero app domains, so it is considered an 'early attach' case. To synchronize - // with this we have to grab and hold the AppDomainDB lock. - // - - GCX_COOP(); - - // Lock the list - if (!m_pAppDomainCB->Lock()) - { - return E_FAIL; - } - - // Get a free entry from the list - AppDomainInfo *pAppDomainInfo = m_pAppDomainCB->GetFreeEntry(); - - // Function returns NULL if the list is full and a realloc failed. - if (!pAppDomainInfo) - { - hr = E_OUTOFMEMORY; - goto LErrExit; - } - - // Now set the AppDomainName. - - /* - * TODO : - * - * Make sure that returning NULL here does not result in a catastrophic - * failure. - * - * GetFriendlyNameNoThrow may call SetFriendlyName, which may call - * UpdateAppDomainEntryInIPC. There is no recursive death, however, because - * the AppDomainInfo object does not contain a pointer to the app domain - * yet. - */ - szName = pAppDomain->GetFriendlyNameForDebugger(); - pAppDomainInfo->SetName(szName); - - // Save on to the appdomain pointer - pAppDomainInfo->m_pAppDomain = pAppDomain; - - // bump the used slot count - m_pAppDomainCB->m_iNumOfUsedSlots++; - -LErrExit: - // UnLock the list - m_pAppDomainCB->Unlock(); - - // Send event to debugger if one is attached. - if (CORDebuggerAttached()) - { - SendCreateAppDomainEvent(pAppDomain); - } - } - - return hr; -} - - -/****************************************************************************** - * Remove the AppDomain from the list stored in the IPC block and send an ExitAppDomain - * event to the debugger if attached. - ******************************************************************************/ -HRESULT Debugger::RemoveAppDomainFromIPC (AppDomain *pAppDomain) -{ - CONTRACTL - { - MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT; - MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT; - } - CONTRACTL_END; - - HRESULT hr = E_FAIL; - - LOG((LF_CORDB, LL_INFO100, "D::RADFIPC: Executing RADFIPC for AppDomain 0x%08x.\n", - pAppDomain)); - - // if none of the slots are occupied, then simply return. - if (m_pAppDomainCB->m_iNumOfUsedSlots == 0) - return hr; - - // Lock the list - if (!m_pAppDomainCB->Lock()) - return (E_FAIL); - - - // Look for the entry - AppDomainInfo *pADInfo = m_pAppDomainCB->FindEntry(pAppDomain); - - // Shouldn't be trying to remove an appdomain that was never added - if (!pADInfo) - { - // We'd like to assert this, but there is a small window where we may have - // called AppDomain::Init (and so it's fair game to call Stop, and hence come here), - // but not yet published the app domain. - // _ASSERTE(!"D::RADFIPC: trying to remove an AppDomain that was never added"); - hr = (E_FAIL); - goto ErrExit; - } - - // Release the entry - m_pAppDomainCB->FreeEntry(pADInfo); - -ErrExit: - // UnLock the list - m_pAppDomainCB->Unlock(); - - // - // The Debugger expects to never get an unload event for the default AppDomain. - // - - return hr; -} - -/****************************************************************************** - * Update the AppDomain in the list stored in the IPC block. - ******************************************************************************/ -HRESULT Debugger::UpdateAppDomainEntryInIPC(AppDomain *pAppDomain) -{ - CONTRACTL - { - NOTHROW; - if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);} - } - CONTRACTL_END; - - HRESULT hr = S_OK; - LPCWSTR szName = NULL; - - LOG((LF_CORDB, LL_INFO100, - "D::UADEIIPC: Executing UpdateAppDomainEntryInIPC ad:0x%x.\n", - pAppDomain)); - - // if none of the slots are occupied, then simply return. - if (m_pAppDomainCB->m_iNumOfUsedSlots == 0) - return (E_FAIL); - - // Lock the list - if (!m_pAppDomainCB->Lock()) - return (E_FAIL); - - // Look up the info entry - AppDomainInfo *pADInfo = m_pAppDomainCB->FindEntry(pAppDomain); - - if (!pADInfo) - { - hr = E_FAIL; - goto ErrExit; - } - - // Update the name only if new name is non-null - szName = pADInfo->m_pAppDomain->GetFriendlyNameForDebugger(); - pADInfo->SetName(szName); - -ErrExit: - // UnLock the list - m_pAppDomainCB->Unlock(); - - return hr; -} - -/****************************************************************************** - * - ******************************************************************************/ -HRESULT Debugger::InitAppDomainIPC(void) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - - PRECONDITION(CheckPointer(m_pAppDomainCB)); - } - CONTRACTL_END; - - // Ensure that if we throw here, the Terminate will get called and cleanup all resources. - // This will make Init an atomic operation - it either fully inits or fully fails. - class EnsureCleanup - { - Debugger * m_pThis; - - public: - EnsureCleanup(Debugger * pThis) - { - m_pThis = pThis; - } - - void SuppressCleanup() - { - m_pThis = NULL; - } - - ~EnsureCleanup() - { - if (m_pThis != NULL) - { - m_pThis->TerminateAppDomainIPC(); - } - } - } hEnsureCleanup(this); - - DWORD dwStrLen = 0; - SString szExeName; - int i; - - // all fields in the object can be zero initialized. - // If we throw, before fully initializing this, then cleanup won't try to free - // uninited values. - ZeroMemory(m_pAppDomainCB, sizeof(*m_pAppDomainCB)); - - // Create a mutex to allow the Left and Right Sides to properly - // synchronize. The Right Side will spin until m_hMutex is valid, - // then it will acquire it before accessing the data. - HandleHolder hMutex(CreateMutex(NULL, TRUE/*hold*/, NULL)); - if (hMutex == NULL) - { - ThrowLastError(); - } - if (!m_pAppDomainCB->m_hMutex.SetLocal(hMutex)) - { - ThrowLastError(); - } - hMutex.SuppressRelease(); - - m_pAppDomainCB->m_iSizeInBytes = INITIAL_APP_DOMAIN_INFO_LIST_SIZE * - sizeof (AppDomainInfo); - - // Number of slots in AppDomainListElement array - m_pAppDomainCB->m_rgListOfAppDomains = new AppDomainInfo[INITIAL_APP_DOMAIN_INFO_LIST_SIZE]; - _ASSERTE(m_pAppDomainCB->m_rgListOfAppDomains != NULL); // throws on oom - - - m_pAppDomainCB->m_iTotalSlots = INITIAL_APP_DOMAIN_INFO_LIST_SIZE; - - // Initialize each AppDomainListElement - for (i = 0; i < INITIAL_APP_DOMAIN_INFO_LIST_SIZE; i++) - { - m_pAppDomainCB->m_rgListOfAppDomains[i].FreeEntry(); - } - - // also initialize the process name - dwStrLen = WszGetModuleFileName(NULL, - szExeName); - - - // If we couldn't get the name, then use a nice default. - if (dwStrLen == 0) - { - szExeName.Set(W("")); - dwStrLen = szExeName.GetCount(); - } - - // If we got the name, copy it into a buffer. dwStrLen is the - // count of characters in the name, not including the null - // terminator. - m_pAppDomainCB->m_szProcessName = new WCHAR[dwStrLen + 1]; - _ASSERTE(m_pAppDomainCB->m_szProcessName != NULL); // throws on oom - - wcscpy_s(m_pAppDomainCB->m_szProcessName, dwStrLen + 1, szExeName); - - // Add 1 to the string length so the Right Side will copy out the - // null terminator, too. - m_pAppDomainCB->m_iProcessNameLengthInBytes = (dwStrLen + 1) * sizeof(WCHAR); - - if (m_pAppDomainCB->m_hMutex != NULL) - { - m_pAppDomainCB->Unlock(); - } - - hEnsureCleanup.SuppressCleanup(); - return S_OK; -} - -/****************************************************************************** - * Uninitialize the AppDomain IPC block - * Returns: - * S_OK -if fully uninitialized - * E_FAIL - if we can't get ownership of the block, and thus no uninitialization - * work is done. - ******************************************************************************/ -HRESULT Debugger::TerminateAppDomainIPC(void) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - // If we have no AppDomain block, then we can consider it's already terminated. - if (m_pAppDomainCB == NULL) - return S_OK; - - HRESULT hr = S_OK; - - // Lock the list - // If there's no mutex, then we're in a partially created state. - // This means InitAppDomainIPC failed halfway through. But we're still thread safe - // since other threads can't access us if we don't have the mutex. - if ((m_pAppDomainCB->m_hMutex != NULL) && !m_pAppDomainCB->Lock()) - { - // The callers don't check our return value, we may want to know when we can't gracefully clean up - LOG((LF_CORDB, LL_INFO10, "Debugger::TerminateAppDomainIPC: Failed to get AppDomain IPC lock, not cleaning up.\n")); - - // If the lock is valid, but we can't get it, then we can't really - // uninitialize since someone else is using the block. - return (E_FAIL); - } - - // The shared IPC segment could still be around after the debugger - // object has been destroyed during process shutdown. So, reset - // the UsedSlots count to 0 so that any out of process clients - // enumeratingthe app domains in this process see 0 AppDomains. - m_pAppDomainCB->m_iNumOfUsedSlots = 0; - m_pAppDomainCB->m_iTotalSlots = 0; - - // Now delete the memory allocated for AppDomainInfo array - delete [] m_pAppDomainCB->m_rgListOfAppDomains; - m_pAppDomainCB->m_rgListOfAppDomains = NULL; - - delete [] m_pAppDomainCB->m_szProcessName; - m_pAppDomainCB->m_szProcessName = NULL; - m_pAppDomainCB->m_iProcessNameLengthInBytes = 0; - - // Set the mutex handle to NULL. - // If the Right Side acquires the mutex, it will verify - // that the handle is still not NULL. If it is, then it knows it - // really lost. - RemoteHANDLE m = m_pAppDomainCB->m_hMutex; - m_pAppDomainCB->m_hMutex.m_hLocal = NULL; - - // And bring us back to a fully uninitialized state. - ZeroMemory(m_pAppDomainCB, sizeof(*m_pAppDomainCB)); - - // We're done. release and close the mutex. Note that this must be done - // after we clear it out above to ensure there is no race condition. - if( m != NULL ) - { - VERIFY(ReleaseMutex(m)); - m.Close(); - } - - return hr; -} - - #ifndef DACCESS_COMPILE // diff --git a/src/coreclr/debug/ee/debugger.h b/src/coreclr/debug/ee/debugger.h index 0e141c94a14e1e..403add11227084 100644 --- a/src/coreclr/debug/ee/debugger.h +++ b/src/coreclr/debug/ee/debugger.h @@ -1116,8 +1116,8 @@ class DebuggerMethodInfo // different part of the address space (not on the heap). // ------------------------------------------------------------------------ */ -constexpr uint64_t DBG_MAX_EXECUTABLE_ALLOC_SIZE=112; -constexpr uint64_t EXPECTED_CHUNKSIZE=128; +constexpr uint64_t DBG_MAX_EXECUTABLE_ALLOC_SIZE=120; // sizeof (SharedPatchBypassBuffer) +constexpr uint64_t EXPECTED_CHUNKSIZE=256; // This must be a power of 2. It represents the size of DebuggerHeapExecutableMemoryChunk, can be the sizeof (DataChunk) or sizeof (BookkeepingChunk). Changes to DBG_MAX_EXECUTABLE_ALLOC_SIZE can affect this number. Currently we require 136 bytes, and so the closest power of 2 is 256. constexpr uint64_t DEBUGGERHEAP_PAGESIZE=4096; constexpr uint64_t CHUNKS_PER_DEBUGGERHEAP=(DEBUGGERHEAP_PAGESIZE / EXPECTED_CHUNKSIZE); constexpr uint64_t MAX_CHUNK_MASK=((1ull << CHUNKS_PER_DEBUGGERHEAP) - 1); @@ -2105,6 +2105,7 @@ class Debugger : public DebugInterface HRESULT GetILToNativeMapping(PCODE pNativeCodeStartAddress, ULONG32 cMap, ULONG32 *pcMap, COR_DEBUG_IL_TO_NATIVE_MAP map[]); +#ifdef DEBUG HRESULT GetILToNativeMappingIntoArrays( MethodDesc * pMethodDesc, PCODE pNativeCodeStartAddress, @@ -2112,6 +2113,7 @@ class Debugger : public DebugInterface USHORT * pcMap, UINT ** prguiILOffset, UINT ** prguiNativeOffset); +#endif // DEBUG PRD_TYPE GetPatchedOpcode(CORDB_ADDRESS_TYPE *ip); BOOL CheckGetPatchedOpcode(CORDB_ADDRESS_TYPE *address, /*OUT*/ PRD_TYPE *pOpcode); @@ -2615,14 +2617,7 @@ class Debugger : public DebugInterface BOOL ShouldAutoAttach(); BOOL FallbackJITAttachPrompt(); - HRESULT AddAppDomainToIPC (AppDomain *pAppDomain); - HRESULT RemoveAppDomainFromIPC (AppDomain *pAppDomain); - HRESULT UpdateAppDomainEntryInIPC (AppDomain *pAppDomain); - - void SendCreateAppDomainEvent(AppDomain * pAppDomain); - - // Notify the debugger that an assembly has been loaded - void LoadAssembly(DomainAssembly * pDomainAssembly); + void AppDomainCreated(AppDomain * pAppDomain); // Notify the debugger that an assembly has been unloaded void UnloadAssembly(DomainAssembly * pDomainAssembly); @@ -2838,9 +2833,6 @@ class Debugger : public DebugInterface DebuggerLaunchSetting GetDbgJITDebugLaunchSetting(); public: - HRESULT InitAppDomainIPC(void); - HRESULT TerminateAppDomainIPC(void); - bool ResumeThreads(AppDomain* pAppDomain); void ProcessAnyPendingEvals(Thread *pThread); @@ -2921,7 +2913,6 @@ class Debugger : public DebugInterface Volatile m_jitAttachInProgress; BOOL m_launchingDebugger; BOOL m_LoggingEnabled; - AppDomainEnumerationIPCBlock *m_pAppDomainCB; LONG m_dClassLoadCallbackCount; diff --git a/src/coreclr/debug/ee/frameinfo.cpp b/src/coreclr/debug/ee/frameinfo.cpp index 7060087ac24afc..c313c648f27cc9 100644 --- a/src/coreclr/debug/ee/frameinfo.cpp +++ b/src/coreclr/debug/ee/frameinfo.cpp @@ -1503,7 +1503,7 @@ StackWalkAction DebuggerWalkStackProc(CrawlFrame *pCF, void *data) (pPrevFrame->GetFrameType() == Frame::TYPE_EXIT) && !HasExitRuntime(pPrevFrame, d, NULL) ) { - // This is for the inlined NDirectMethodFrameGeneric case. We have not exit the runtime yet, so the current + // This is for the inlined PInvokeMethodFrameGeneric case. We have not exit the runtime yet, so the current // frame should still be regarded as the leaf frame. d->info.fIsLeaf = true; } diff --git a/src/coreclr/debug/ee/functioninfo.cpp b/src/coreclr/debug/ee/functioninfo.cpp index 6e2db4cab721a1..191cc7c278b00b 100644 --- a/src/coreclr/debug/ee/functioninfo.cpp +++ b/src/coreclr/debug/ee/functioninfo.cpp @@ -920,6 +920,7 @@ void DebuggerJitInfo::LazyInitBounds() BOOL fSuccess = DebugInfoManager::GetBoundariesAndVars( request, InteropSafeNew, NULL, // allocator + BoundsType::Instrumented, // TODO We currently don't use the uninstrumented bounds here but we should and remove the instrumented bounds logic from the SetBoundaries function. &cMap, &pMap, &cVars, &pVars); @@ -1045,6 +1046,12 @@ void DebuggerJitInfo::SetBoundaries(ULONG32 cMap, ICorDebugInfo::OffsetMapping * DebuggerILToNativeMap *m = m_sequenceMap; + // TODO: Consider removing the handling for the InstrumentedILMap here. + // since we now have the ability to get an uninstrumented IL offset mapping + // directly from the VM. This work was not done when adding the instrumented + // IL mapping due to the work ocurring too close to the shipping deadline for .NET 10. + // If we do so, we need to change the input to this function to be the uninstrumented IL offset mapping + // For the instrumented-IL case, we need to remove all duplicate entries. // So we keep a record of the last old IL offset. If the current old IL // offset is the same as the last old IL offset, we remove it. diff --git a/src/coreclr/debug/ee/walker.h b/src/coreclr/debug/ee/walker.h index 63bd4cfa2fd273..4dcae6d75ed273 100644 --- a/src/coreclr/debug/ee/walker.h +++ b/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/coreclr/debug/inc/dacdbiinterface.h b/src/coreclr/debug/inc/dacdbiinterface.h index b4b5c4b006ccf1..66b33aab1fa51d 100644 --- a/src/coreclr/debug/inc/dacdbiinterface.h +++ b/src/coreclr/debug/inc/dacdbiinterface.h @@ -2729,6 +2729,9 @@ class IDacDbiInterface virtual bool MetadataUpdatesApplied() = 0; + virtual + HRESULT GetDomainAssemblyFromModule(VMPTR_Module vmModule, OUT VMPTR_DomainAssembly *pVmDomainAssembly) = 0; + // The following tag tells the DD-marshalling tool to stop scanning. // END_MARSHAL diff --git a/src/coreclr/debug/inc/dbgappdomain.h b/src/coreclr/debug/inc/dbgappdomain.h index de8a06b38c9e51..1e77c89d71ee0f 100644 --- a/src/coreclr/debug/inc/dbgappdomain.h +++ b/src/coreclr/debug/inc/dbgappdomain.h @@ -140,239 +140,6 @@ struct RemoteHANDLE { } }; - -// AppDomain publishing server support: -// Information about all appdomains in the process will be maintained -// in the shared memory block for use by the debugger, etc. -// This structure defines the layout of the information that will -// be maintained. -struct AppDomainEnumerationIPCBlock -{ - // !!! The binary format of this layout must remain the same across versions so that - // !!! a V2.0 publisher can inspect a v1.0 app. - - // lock for serialization while manipulating AppDomain list. - RemoteHANDLE m_hMutex; - - // Number of slots in AppDomainListElement array - int m_iTotalSlots; - int m_iNumOfUsedSlots; - int m_iLastFreedSlot; - int m_iSizeInBytes; // Size of AppDomainInfo in bytes - - // We can use psapi!GetModuleFileNameEx to get the module name. - // This provides an alternative. - int m_iProcessNameLengthInBytes; - WCHAR *m_szProcessName; - - AppDomainInfo *m_rgListOfAppDomains; - BOOL m_fLockInvalid; - - -#ifndef RIGHT_SIDE_COMPILE - /************************************************************************* - * Locks the list - *************************************************************************/ - BOOL Lock() - { - DWORD dwRes = WaitForSingleObject(m_hMutex, 3000); - if (dwRes == WAIT_TIMEOUT) - { - // Nobody should get stuck holding this lock. - // If we timeout on the wait, then either: - // - it's a really bad race and somebody got preempted for a long time - // - perhaps somebody's doing a DOS attack and holding onto the mutex. - m_fLockInvalid = TRUE; - } - - - // The only time this can happen is if we're in shutdown and a thread - // that held this lock is killed. If this happens, assume that this - // IPC block is in an invalid state and return FALSE to indicate - // that people shouldn't do anything with the block anymore. - if (dwRes == WAIT_ABANDONED) - { - m_fLockInvalid = TRUE; - } - - if (m_fLockInvalid) - { - Unlock(); - } - - return (dwRes == WAIT_OBJECT_0 && !m_fLockInvalid); - } - - /************************************************************************* - * Unlocks the list - *************************************************************************/ - void Unlock() - { - // Lock may or may not be valid at this point. Thus Release may fail, - // but we'll just ignore that. - ReleaseMutex(m_hMutex); - } - - /************************************************************************* - * Gets a free AppDomainInfo entry, and will allocate room if there are - * no free slots left. - *************************************************************************/ - AppDomainInfo *GetFreeEntry() - { - // first check to see if there is space available. If not, then realloc. - if (m_iNumOfUsedSlots == m_iTotalSlots) - { - // need to realloc - AppDomainInfo *pTemp = - new (nothrow) AppDomainInfo [m_iTotalSlots*2]; - - if (pTemp == NULL) - { - return (NULL); - } - - memcpy (pTemp, m_rgListOfAppDomains, m_iSizeInBytes); - - delete [] m_rgListOfAppDomains; - - // Initialize the increased portion of the realloced memory - int iNewSlotSize = m_iTotalSlots * 2; - - for (int iIndex = m_iTotalSlots; iIndex < iNewSlotSize; iIndex++) - pTemp[iIndex].FreeEntry(); - - m_rgListOfAppDomains = pTemp; - m_iTotalSlots = iNewSlotSize; - m_iSizeInBytes *= 2; - } - - // Walk the list looking for an empty slot. Start from the last - // one which was freed. - { - int i = m_iLastFreedSlot; - - do - { - // Pointer to the entry being examined - AppDomainInfo *pADInfo = &(m_rgListOfAppDomains[i]); - - // is the slot available? - if (pADInfo->IsEmpty()) - return (pADInfo); - - i = (i + 1) % m_iTotalSlots; - - } while (i != m_iLastFreedSlot); - } - - _ASSERTE(!"ADInfo::GetFreeEntry: should never get here."); - return (NULL); - } - - /************************************************************************* - * Returns an AppDomainInfo slot to the free list. - *************************************************************************/ - void FreeEntry(AppDomainInfo *pADInfo) - { - _ASSERTE(pADInfo >= m_rgListOfAppDomains && - pADInfo < m_rgListOfAppDomains + m_iSizeInBytes); - _ASSERTE(((size_t)pADInfo - (size_t)m_rgListOfAppDomains) % - sizeof(AppDomainInfo) == 0); - - // Mark this slot as free - pADInfo->FreeEntry(); - -#ifdef _DEBUG - *pADInfo = {}; -#endif - - // decrement the used slot count - m_iNumOfUsedSlots--; - - // Save the last freed slot. - m_iLastFreedSlot = (int)((size_t)pADInfo - (size_t)m_rgListOfAppDomains) / - sizeof(AppDomainInfo); - } - - /************************************************************************* - * Finds an AppDomainInfo entry corresponding to the AppDomain pointer. - * Returns NULL if no such entry exists. - *************************************************************************/ - AppDomainInfo *FindEntry(AppDomain *pAD) - { - // Walk the list looking for a matching entry - for (int i = 0; i < m_iTotalSlots; i++) - { - AppDomainInfo *pADInfo = &(m_rgListOfAppDomains[i]); - - if (!pADInfo->IsEmpty() && - pADInfo->m_pAppDomain == pAD) - return pADInfo; - } - - return (NULL); - } - - /************************************************************************* - * Returns the first AppDomainInfo entry in the list. Returns NULL if - * no such entry exists. - *************************************************************************/ - AppDomainInfo *FindFirst() - { - // Walk the list looking for a non-empty entry - for (int i = 0; i < m_iTotalSlots; i++) - { - AppDomainInfo *pADInfo = &(m_rgListOfAppDomains[i]); - - if (!pADInfo->IsEmpty()) - return pADInfo; - } - - return (NULL); - } - - /************************************************************************* - * Returns the next AppDomainInfo entry after pADInfo. Returns NULL if - * pADInfo was the last in the list. - *************************************************************************/ - AppDomainInfo *FindNext(AppDomainInfo *pADInfo) - { - _ASSERTE(pADInfo >= m_rgListOfAppDomains && - pADInfo < m_rgListOfAppDomains + m_iSizeInBytes); - _ASSERTE(((size_t)pADInfo - (size_t)m_rgListOfAppDomains) % - sizeof(AppDomainInfo) == 0); - - // Walk the list looking for the next non-empty entry - for (int i = (int)((size_t)pADInfo - (size_t)m_rgListOfAppDomains) - / sizeof(AppDomainInfo) + 1; - i < m_iTotalSlots; - i++) - { - AppDomainInfo *pADInfoTemp = &(m_rgListOfAppDomains[i]); - - if (!pADInfoTemp->IsEmpty()) - return pADInfoTemp; - } - - return (NULL); - } -#endif // RIGHT_SIDE_COMPILE -}; - -// Enforce the AppDomain IPC block binary layout doesn't change between versions. -// Only an issue for x86 since that's the only platform w/ multiple versions. -#if defined(TARGET_X86) -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_hMutex) == 0x0); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iTotalSlots) == 0x4); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iNumOfUsedSlots) == 0x8); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iLastFreedSlot) == 0xc); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iSizeInBytes) == 0x10); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iProcessNameLengthInBytes) == 0x14); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_szProcessName) == 0x18); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_rgListOfAppDomains) == 0x1c); -static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_fLockInvalid) == 0x20); -#endif - #endif //DbgAppDomain_H diff --git a/src/coreclr/debug/inc/dbgtargetcontext.h b/src/coreclr/debug/inc/dbgtargetcontext.h index ea374cf8b6def6..606e4954b35272 100644 --- a/src/coreclr/debug/inc/dbgtargetcontext.h +++ b/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/coreclr/debug/inc/dbgtransportsession.h b/src/coreclr/debug/inc/dbgtransportsession.h index 3bc9521e9c5251..276bd00a6aa93b 100644 --- a/src/coreclr/debug/inc/dbgtransportsession.h +++ b/src/coreclr/debug/inc/dbgtransportsession.h @@ -341,7 +341,7 @@ class DbgTransportSession #ifdef RIGHT_SIDE_COMPILE HRESULT Init(const ProcessDescriptor& pd, HANDLE hProcessExited); #else - HRESULT Init(DebuggerIPCControlBlock * pDCB, AppDomainEnumerationIPCBlock * pADB); + HRESULT Init(DebuggerIPCControlBlock * pDCB); #endif // RIGHT_SIDE_COMPILE // Drive the session to the SS_Closed state, which will deallocate all remaining transport resources @@ -426,9 +426,6 @@ class DbgTransportSession HRESULT GetDCB(DebuggerIPCControlBlock *pDCB); HRESULT SetDCB(DebuggerIPCControlBlock *pDCB); - // Read the AppDomain control block on the LS from the RS. - HRESULT GetAppDomainCB(AppDomainEnumerationIPCBlock *pADB); - #endif // RIGHT_SIDE_COMPILE private: @@ -469,7 +466,6 @@ class DbgTransportSession MT_WriteMemory, // RS <-> LS : RS wants to write LS memory block (or LS is replying to such a request) MT_GetDCB, // RS <-> LS : RS wants to read LS DCB (or LS is replying to such a request) MT_SetDCB, // RS <-> LS : RS wants to write LS DCB (or LS is replying to such a request) - MT_GetAppDomainCB, // RS <-> LS : RS wants to read LS AppDomainCB (or LS is replying to such a request) }; // Reasons the LS can give for rejecting a session. These codes should *not* be changed other than by @@ -589,7 +585,6 @@ class DbgTransportSession LONG m_cSentWriteMemory; LONG m_cSentGetDCB; LONG m_cSentSetDCB; - LONG m_cSentGetAppDomainCB; LONG m_cSentDDMessage; // Message type counts for receives. @@ -603,7 +598,6 @@ class DbgTransportSession LONG m_cReceivedWriteMemory; LONG m_cReceivedGetDCB; LONG m_cReceivedSetDCB; - LONG m_cReceivedGetAppDomainCB; LONG m_cReceivedDDMessage; // Low level block counts. @@ -747,7 +741,6 @@ class DbgTransportSession // The LS requires the addresses of a couple of runtime data structures in order to service MT_GetDCB etc. // These are provided by the runtime at initialization time. DebuggerIPCControlBlock *m_pDCB; - AppDomainEnumerationIPCBlock *m_pADB; #endif // !RIGHT_SIDE_COMPILE HRESULT SendEventWorker(DebuggerIPCEvent * pEvent, IPCEventType type); diff --git a/src/coreclr/debug/runtimeinfo/CMakeLists.txt b/src/coreclr/debug/runtimeinfo/CMakeLists.txt index 1d0abd332c6011..a31d4b6f9812c3 100644 --- a/src/coreclr/debug/runtimeinfo/CMakeLists.txt +++ b/src/coreclr/debug/runtimeinfo/CMakeLists.txt @@ -38,67 +38,3 @@ endif() # publish runtimeinfo lib install_clr(TARGETS runtimeinfo DESTINATIONS lib COMPONENT runtime) - - -# cDAC contract descriptor - -if(CDAC_BUILD_TOOL_BINARY_PATH AND "${CLR_DOTNET_RID}" STREQUAL "") - message(FATAL_ERROR "CLR_DOTNET_RID is not set. Please ensure it is being set to the portable RID of the target platform by runtime.proj.") -endif() -configure_file(configure.h.in ${CMAKE_CURRENT_BINARY_DIR}/configure.h) - -if (NOT CDAC_BUILD_TOOL_BINARY_PATH) - # if CDAC_BUILD_TOOL_BINARY_PATH is unspecified (for example for a build without a .NET SDK or msbuild), - # link a stub contract descriptor into the runtime - add_library_clr(cdac_contract_descriptor OBJECT contractdescriptorstub.c) - message(STATUS "Using a stub cDAC contract descriptor") -else() - # generate a contract descriptor using cdac-build-tool from a data descriptor and contract json file - - add_library(cdac_data_descriptor OBJECT datadescriptor.cpp) - # don't build the data descriptor before the VM (and any of its dependencies' generated headers) - add_dependencies(cdac_data_descriptor cee_wks_core) - if(CLR_CMAKE_TARGET_WIN32) - # turn off whole program optimization: - # 1. it creates object files that cdac-build-tool can't read - # 2. we never link cdac_data_descriptor into the final product - it's only job is to be scraped - set_target_properties(cdac_data_descriptor PROPERTIES - INTERPROCEDURAL_OPTIMIZATION_RELEASE OFF - INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO OFF) - endif() - target_include_directories(cdac_data_descriptor BEFORE PRIVATE ${VM_DIR}) - target_include_directories(cdac_data_descriptor BEFORE PRIVATE ${VM_DIR}/${ARCH_SOURCES_DIR}) - target_include_directories(cdac_data_descriptor PRIVATE ${CLR_DIR}/interop/inc) - - set(GENERATED_CDAC_DESCRIPTOR_DIR "${CMAKE_CURRENT_BINARY_DIR}/cdac") - set(CONTRACT_DESCRIPTOR_OUTPUT "${GENERATED_CDAC_DESCRIPTOR_DIR}/contract-descriptor.c") - if(NOT EXISTS "${CDAC_BUILD_TOOL_BINARY_PATH}") - message(FATAL_ERROR "${CDAC_BUILD_TOOL_BINARY_PATH} does not exist") - endif() - set(CONTRACT_DESCRIPTOR_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/contract-descriptor.c.in") - - set(CONTRACT_BASELINE_DIR "${CLR_REPO_ROOT_DIR}/docs/design/datacontracts/data") - set(CONTRACT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/contracts.jsonc") - - # generate the contract descriptor by running cdac-build-tool - # n.b. this just uses `dotnet` from the PATH. InitializeDotNetCli adds the apropropriate directory - add_custom_command( - OUTPUT "${CONTRACT_DESCRIPTOR_OUTPUT}" - VERBATIM - COMMAND ${CLR_DOTNET_HOST_PATH} ${CDAC_BUILD_TOOL_BINARY_PATH} compose -i "${CONTRACT_DESCRIPTOR_INPUT}" -o "${CONTRACT_DESCRIPTOR_OUTPUT}" -b "${CONTRACT_BASELINE_DIR}" -c "${CONTRACT_FILE}" $ - DEPENDS cdac_data_descriptor cee_wks_core $ "${CONTRACT_FILE}" "${CONTRACT_DESCRIPTOR_INPUT}" - USES_TERMINAL - ) - - # It is important that cdac_contract_descriptor is an object library; - # if it was static, linking it into the final dll would not export - # DotNetRuntimeContractDescriptor since it is not referenced anywhere. - add_library_clr(cdac_contract_descriptor OBJECT - "${CONTRACT_DESCRIPTOR_OUTPUT}" - contractpointerdata.cpp - ) - target_include_directories(cdac_contract_descriptor BEFORE PRIVATE ${VM_DIR}) - target_include_directories(cdac_contract_descriptor BEFORE PRIVATE ${VM_DIR}/${ARCH_SOURCES_DIR}) - target_include_directories(cdac_contract_descriptor PRIVATE ${CLR_DIR}/interop/inc) - add_dependencies(cdac_contract_descriptor cdac_data_descriptor cee_wks_core) -endif() diff --git a/src/coreclr/debug/runtimeinfo/contractpointerdata.cpp b/src/coreclr/debug/runtimeinfo/contractpointerdata.cpp deleted file mode 100644 index c7d5bf15cb1b01..00000000000000 --- a/src/coreclr/debug/runtimeinfo/contractpointerdata.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#include "common.h" - -#include -#include - -#include "cdacplatformmetadata.hpp" -#include "threads.h" -#include "vars.hpp" -#include "ecall.h" - -extern "C" -{ -// without an extern declaration, clang does not emit this global into the object file -extern const uintptr_t contractDescriptorPointerData[]; - -const uintptr_t contractDescriptorPointerData[] = { - (uintptr_t)0, // placeholder -#define CDAC_GLOBAL_POINTER(name,value) (uintptr_t)(value), -#include "datadescriptor.h" -}; - -} diff --git a/src/coreclr/debug/shared/dbgtransportsession.cpp b/src/coreclr/debug/shared/dbgtransportsession.cpp index f2547ffc8aefcf..edd2897f02c104 100644 --- a/src/coreclr/debug/shared/dbgtransportsession.cpp +++ b/src/coreclr/debug/shared/dbgtransportsession.cpp @@ -67,7 +67,7 @@ DbgTransportSession::~DbgTransportSession() #ifdef RIGHT_SIDE_COMPILE HRESULT DbgTransportSession::Init(const ProcessDescriptor& pd, HANDLE hProcessExited) #else // RIGHT_SIDE_COMPILE -HRESULT DbgTransportSession::Init(DebuggerIPCControlBlock *pDCB, AppDomainEnumerationIPCBlock *pADB) +HRESULT DbgTransportSession::Init(DebuggerIPCControlBlock *pDCB) #endif // RIGHT_SIDE_COMPILE { _ASSERTE(m_eState == SS_Closed); @@ -111,7 +111,6 @@ HRESULT DbgTransportSession::Init(DebuggerIPCControlBlock *pDCB, AppDomainEnumer m_fDebuggerAttached = false; #else // RIGHT_SIDE_COMPILE m_pDCB = pDCB; - m_pADB = pADB; #endif // RIGHT_SIDE_COMPILE m_sStateLock.Init(); @@ -555,17 +554,6 @@ HRESULT DbgTransportSession::SetDCB(DebuggerIPCControlBlock *pDCB) } -// Read the AppDomain control block on the LS from the RS. -HRESULT DbgTransportSession::GetAppDomainCB(AppDomainEnumerationIPCBlock *pADB) -{ - DbgTransportLog(LC_Requests, "Sending 'GetAppDomainCB'"); - DBG_TRANSPORT_INC_STAT(SentGetAppDomainCB); - - Message sMessage; - sMessage.Init(MT_GetAppDomainCB, NULL, 0, (PBYTE)pADB, sizeof(AppDomainEnumerationIPCBlock)); - return SendRequestMessageAndWait(&sMessage); -} - #endif // RIGHT_SIDE_COMPILE // Worker function for code:DbgTransportSession::SendEvent and code:DbgTransportSession::SendDebugEvent. @@ -948,8 +936,7 @@ void DbgTransportSession::FlushSendQueue(DWORD dwLastProcessedId) if (eType != MT_ReadMemory && eType != MT_WriteMemory && eType != MT_GetDCB && - eType != MT_SetDCB && - eType != MT_GetAppDomainCB) + eType != MT_SetDCB) #endif // RIGHT_SIDE_COMPILE { #ifdef RIGHT_SIDE_COMPILE @@ -1658,8 +1645,7 @@ void DbgTransportSession::TransportWorker() // Since we care about security here, perform some additional validation checks that make it // harder for a malicious sender to attack with random message data. - if (sReceiveHeader.m_eType > MT_GetAppDomainCB || - (sReceiveHeader.m_dwId <= m_dwLastMessageIdSeen && + if ((sReceiveHeader.m_dwId <= m_dwLastMessageIdSeen && sReceiveHeader.m_dwId != (DWORD)0) || (sReceiveHeader.m_dwReplyId >= m_dwNextMessageId && sReceiveHeader.m_dwReplyId != (DWORD)0) || @@ -1974,17 +1960,6 @@ void DbgTransportSession::TransportWorker() #endif // RIGHT_SIDE_COMPILE break; - case MT_GetAppDomainCB: -#ifdef RIGHT_SIDE_COMPILE - if (!ProcessReply(&sReceiveHeader)) - HANDLE_TRANSIENT_ERROR(); -#else // RIGHT_SIDE_COMPILE - fReplyRequired = true; - pbOptReplyData = (PBYTE)m_pADB; - cbOptReplyData = sizeof(AppDomainEnumerationIPCBlock); -#endif // RIGHT_SIDE_COMPILE - break; - default: _ASSERTE(!"Unknown message type"); HANDLE_CRITICAL_ERROR(); @@ -2089,7 +2064,6 @@ void DbgTransportSession::TransportWorker() case MT_WriteMemory: case MT_GetDCB: case MT_SetDCB: - case MT_GetAppDomainCB: // On the RS these are the original requests. Signal the completion event. SignalReplyEvent(pMsg); break; @@ -2098,7 +2072,6 @@ void DbgTransportSession::TransportWorker() case MT_WriteMemory: case MT_GetDCB: case MT_SetDCB: - case MT_GetAppDomainCB: // On the LS these are replies to the original request. Nobody's waiting on these. break; #endif // RIGHT_SIDE_COMPILE @@ -2501,8 +2474,6 @@ const char *DbgTransportSession::MessageName(MessageType eType) return "GetDCB"; case MT_SetDCB: return "SetDCB"; - case MT_GetAppDomainCB: - return "GetAppDomainCB"; default: _ASSERTE(!"Unknown message type"); return NULL; @@ -2561,10 +2532,6 @@ void DbgTransportSession::DbgTransportLogMessageReceived(MessageHeader *pHeader) DbgTransportLog(LC_Requests, "Received 'SetDCB' reply"); DBG_TRANSPORT_INC_STAT(ReceivedSetDCB); return; - case MT_GetAppDomainCB: - DbgTransportLog(LC_Requests, "Received 'GetAppDomainCB' reply"); - DBG_TRANSPORT_INC_STAT(ReceivedGetAppDomainCB); - return; #else // RIGHT_SIDE_COMPILE case MT_ReadMemory: DbgTransportLog(LC_Requests, "Received 'ReadMemory(0x%08X, %u)'", @@ -2586,10 +2553,6 @@ void DbgTransportSession::DbgTransportLogMessageReceived(MessageHeader *pHeader) DbgTransportLog(LC_Requests, "Received 'SetDCB'"); DBG_TRANSPORT_INC_STAT(ReceivedSetDCB); return; - case MT_GetAppDomainCB: - DbgTransportLog(LC_Requests, "Received 'GetAppDomainCB'"); - DBG_TRANSPORT_INC_STAT(ReceivedGetAppDomainCB); - return; #endif // RIGHT_SIDE_COMPILE default: _ASSERTE(!"Unknown message type"); diff --git a/src/coreclr/dlls/mscordac/CMakeLists.txt b/src/coreclr/dlls/mscordac/CMakeLists.txt index 71b69336e2eeb3..dc3b79d6933165 100644 --- a/src/coreclr/dlls/mscordac/CMakeLists.txt +++ b/src/coreclr/dlls/mscordac/CMakeLists.txt @@ -157,6 +157,12 @@ set(COREDAC_LIBRARIES ${END_LIBRARY_GROUP} # End group of libraries that have circular references ) +if(CLR_CMAKE_HOST_UNIX) + list(APPEND COREDAC_LIBRARIES + coreclrpal_dac + ) +endif(CLR_CMAKE_HOST_UNIX) + if(CLR_CMAKE_HOST_WIN32) # mscordac.def should be generated before mscordaccore.dll is built add_dependencies(mscordaccore mscordaccore_def) @@ -205,12 +211,6 @@ if(CLR_CMAKE_HOST_WIN32 AND CLR_CMAKE_TARGET_UNIX) ) endif(CLR_CMAKE_HOST_WIN32 AND CLR_CMAKE_TARGET_UNIX) -if(CLR_CMAKE_HOST_UNIX) - list(APPEND COREDAC_LIBRARIES - coreclrpal_dac - ) -endif(CLR_CMAKE_HOST_UNIX) - target_link_libraries(mscordaccore PRIVATE ${COREDAC_LIBRARIES}) esrp_sign(mscordaccore) diff --git a/src/coreclr/dlls/mscordbi/mscordbi.src b/src/coreclr/dlls/mscordbi/mscordbi.src index ec3aa1303fb232..3cb62f540475db 100644 --- a/src/coreclr/dlls/mscordbi/mscordbi.src +++ b/src/coreclr/dlls/mscordbi/mscordbi.src @@ -4,7 +4,7 @@ LIBRARY mscordbi EXPORTS - // COM-instantiation - for CorPublish + // COM-instantiation DllGetClassObjectInternal private // In-proc (Whidbey-style) creation path from the shim - CDIFV and it's replacement diff --git a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt index 60f6a310451d90..8b937537c554f9 100644 --- a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt @@ -56,23 +56,28 @@ endif (CLR_CMAKE_HOST_WIN32) add_definitions(-DFX_VER_INTERNALNAME_STR=CoreCLR.dll) -add_library_clr(coreclr - SHARED - ${CLR_SOURCES} -) +if (NOT CLR_CMAKE_HOST_ARCH_WASM) + add_library_clr(coreclr + SHARED + ${CLR_SOURCES} + ) -add_custom_target(coreclr_exports DEPENDS ${EXPORTS_FILE}) -add_custom_target(coreclr_def DEPENDS ${DEF_FILE}) + add_custom_target(coreclr_exports DEPENDS ${EXPORTS_FILE}) + add_custom_target(coreclr_def DEPENDS ${DEF_FILE}) -add_dependencies(coreclr coreclr_def) -add_dependencies(coreclr coreclr_exports) + add_dependencies(coreclr coreclr_def) + add_dependencies(coreclr coreclr_exports) -set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION}) -set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE}) + set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION}) + set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE}) + set(LIB_CORDBEE cordbee_wks) + set(LIB_INTEROP interop) + set(LIB_CDAC_CONTRACT_DESCRIPTOR cdac_contract_descriptor) +endif(NOT CLR_CMAKE_HOST_ARCH_WASM) -if (CLR_CMAKE_HOST_UNIX) +if (CLR_CMAKE_HOST_UNIX AND NOT CLR_CMAKE_TARGET_ARCH_WASM) set(LIB_UNWINDER unwinder_wks) -endif (CLR_CMAKE_HOST_UNIX) +endif (CLR_CMAKE_HOST_UNIX AND NOT CLR_CMAKE_TARGET_ARCH_WASM) # IMPORTANT! Please do not rearrange the order of the libraries. The linker on Linux is # order dependent and changing the order can result in undefined symbols in the shared @@ -80,7 +85,7 @@ endif (CLR_CMAKE_HOST_UNIX) set(CORECLR_LIBRARIES utilcode ${START_LIBRARY_GROUP} # Start group of libraries that have circular references - cordbee_wks + ${LIB_CORDBEE} debug-pal ${LIB_UNWINDER} v3binder @@ -95,10 +100,10 @@ set(CORECLR_LIBRARIES utilcode v3binder System.Globalization.Native-Static - interop + ${LIB_INTEROP} coreclrminipal gc_pal - cdac_contract_descriptor + ${LIB_CDAC_CONTRACT_DESCRIPTOR} ) if(CLR_CMAKE_TARGET_ARCH_AMD64) @@ -168,16 +173,34 @@ if(FEATURE_PERFTRACING) endif(CLR_CMAKE_TARGET_LINUX) endif(FEATURE_PERFTRACING) -if(FEATURE_STATICALLY_LINKED) - set(CLRJIT_STATIC clrjit_static) +if (FEATURE_STATICALLY_LINKED) + if (FEATURE_JIT) + set(CLRJIT_STATIC clrjit_static gcinfo) + endif(FEATURE_JIT) + if (FEATURE_INTERPRETER) + set(CLRINTERPRETER_STATIC clrinterpreter) + endif(FEATURE_INTERPRETER) endif(FEATURE_STATICALLY_LINKED) +if(FEATURE_JIT) + set(CORECLR_STATIC_CLRJIT_STATIC clrjit_static) +endif(FEATURE_JIT) + +if(NOT CLR_CMAKE_HOST_ARCH_WASM) + set(CEE_WKS_STATIC cee_wks_mergeable) +else() + set(CEE_WKS_STATIC cee_wks) +endif(NOT CLR_CMAKE_HOST_ARCH_WASM) + if (CLR_CMAKE_TARGET_OSX) find_library(FOUNDATION Foundation REQUIRED) endif() -target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} cee_wks_core cee_wks ${FOUNDATION}) -target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} cee_wks_core clrjit_static cee_wks_mergeable ${FOUNDATION}) +if(NOT CLR_CMAKE_HOST_ARCH_WASM) + target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} ${CLRINTERPRETER_STATIC} cee_wks_core cee_wks ${FOUNDATION}) +endif(NOT CLR_CMAKE_HOST_ARCH_WASM) + +target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} cee_wks_core ${CORECLR_STATIC_CLRJIT_STATIC} ${CEE_WKS_STATIC} ${FOUNDATION}) target_compile_definitions(coreclr_static PUBLIC CORECLR_EMBEDDED) if (CLR_CMAKE_HOST_ANDROID) @@ -227,10 +250,13 @@ if(CLR_CMAKE_TARGET_WIN32) endif(CLR_CMAKE_TARGET_WIN32) # add the install targets -install_clr(TARGETS coreclr DESTINATIONS . sharedFramework COMPONENT runtime) -if(CLR_CMAKE_HOST_MACCATALYST OR CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID) +if(NOT CLR_CMAKE_HOST_ARCH_WASM) + install_clr(TARGETS coreclr DESTINATIONS . sharedFramework COMPONENT runtime) +endif(NOT CLR_CMAKE_HOST_ARCH_WASM) + +if(CLR_CMAKE_HOST_MACCATALYST OR CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID OR CLR_CMAKE_HOST_ARCH_WASM) install_clr(TARGETS coreclr_static DESTINATIONS . sharedFramework COMPONENT runtime) -endif(CLR_CMAKE_HOST_MACCATALYST OR CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID) +endif(CLR_CMAKE_HOST_MACCATALYST OR CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID OR CLR_CMAKE_HOST_ARCH_WASM) # Enable profile guided optimization add_pgo(coreclr) diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc index e85b88fcdd07aa..0fed12722a1139 100644 --- a/src/coreclr/dlls/mscorrc/mscorrc.rc +++ b/src/coreclr/dlls/mscorrc/mscorrc.rc @@ -308,6 +308,7 @@ BEGIN IDS_CLASSLOAD_INLINE_ARRAY_FIELD_COUNT "InlineArrayAttribute requires that the target type has a single instance field. Type: '%1'. Assembly: '%2'." IDS_CLASSLOAD_INLINE_ARRAY_LENGTH "InlineArrayAttribute requires that the length argument is greater than 0. Type: '%1'. Assembly: '%2'." IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT "InlineArrayAttribute cannot be applied to a type with explicit layout. Type: '%1'. Assembly: '%2'." + IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT_SIZE "InlineArrayAttribute cannot be applied to a type with explicit size. Type: '%1'. Assembly: '%2'." IDS_CLASSLOAD_BYREF_OF_BYREF "Could not create a ByRef of a ByRef. Type: '%1'. Assembly: '%2'." IDS_CLASSLOAD_POINTER_OF_BYREF "Could not create a pointer to a ByRef. Type: '%1'. Assembly: '%2'." diff --git a/src/coreclr/dlls/mscorrc/resource.h b/src/coreclr/dlls/mscorrc/resource.h index 397efa1f2ae768..f7ae1dea4a6259 100644 --- a/src/coreclr/dlls/mscorrc/resource.h +++ b/src/coreclr/dlls/mscorrc/resource.h @@ -160,6 +160,8 @@ #define IDS_CLASSLOAD_BYREF_OF_BYREF 0x17af #define IDS_CLASSLOAD_POINTER_OF_BYREF 0x17b0 +#define IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT_SIZE 0x17b1 + #define IDS_INVALID_REDIM 0x17c3 #define IDS_INVALID_PINVOKE_CALLCONV 0x17c4 #define IDS_CLASSLOAD_NSTRUCT_EXPLICIT_OFFSET 0x17c7 diff --git a/src/coreclr/gc/env/gcenv.h b/src/coreclr/gc/env/gcenv.h index 1afd5aa6ebea13..8ec661b9e353e4 100644 --- a/src/coreclr/gc/env/gcenv.h +++ b/src/coreclr/gc/env/gcenv.h @@ -97,7 +97,6 @@ enum LogFacility LF_GC = 0x00000001, LF_GCALLOC = 0x00000100, LF_GCROOTS = 0x00080000, - LF_ALWAYS = 0x80000000, }; enum LogLevel @@ -192,19 +191,25 @@ struct StressLogMsg } }; -template<> -void* StressLogMsg::ConvertArgument(float arg) = delete; - #if TARGET_64BIT template<> inline void* StressLogMsg::ConvertArgument(double arg) { return (void*)(size_t)(*((uint64_t*)&arg)); } +// COMPAT: Convert 32-bit floats to 64-bit doubles. +template<> +inline void* StressLogMsg::ConvertArgument(float arg) +{ + return StressLogMsg::ConvertArgument((double)arg); +} #else template<> void* StressLogMsg::ConvertArgument(double arg) = delete; +template<> +void* StressLogMsg::ConvertArgument(float arg) = delete; + // COMPAT: Truncate 64-bit integer arguments to 32-bit template<> inline void* StressLogMsg::ConvertArgument(uint64_t arg) @@ -234,7 +239,7 @@ class StressLog static void LogMsg(unsigned dprintfLevel, const StressLogMsg& msg) { - GCToEEInterface::LogStressMsg(LL_ALWAYS, LF_ALWAYS|(dprintfLevel<<16)|LF_GC, msg); + GCToEEInterface::LogStressMsg(LL_ALWAYS, (dprintfLevel<<16)|LF_GC, msg); } static void LogMsg(unsigned level, unsigned facility, const StressLogMsg& msg) diff --git a/src/coreclr/gc/env/gcenv.os.h b/src/coreclr/gc/env/gcenv.os.h index 08e9b39e36eb1a..6a73ba6d378bc6 100644 --- a/src/coreclr/gc/env/gcenv.os.h +++ b/src/coreclr/gc/env/gcenv.os.h @@ -451,9 +451,6 @@ class GCToOSInterface // Misc // - // Flush write buffers of processors that are executing threads of the current process - static void FlushProcessWriteBuffers(); - // Break into a debugger static void DebugBreak(); diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 3845048743a2de..238f6986efd7cd 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -27,6 +27,7 @@ #include "handletable.inl" #include "gcenv.inl" #include "gceventstatus.h" +#include #ifdef __INTELLISENSE__ #if defined(FEATURE_SVR_GC) @@ -428,9 +429,26 @@ size_t gib (size_t num) #ifdef BACKGROUND_GC uint32_t bgc_alloc_spin_count = 140; -uint32_t bgc_alloc_spin_count_uoh = 16; uint32_t bgc_alloc_spin = 2; +// The following 2 ratios dictate how UOH allocations that happen during a BGC should be handled. Because +// UOH is not collected till the very end of a BGC, by default we don't want to allow UOH to grow too large +// during a BGC. So if we only increase the size by 10%, we will allow to allocate normally. But if it's +// too much (ie, > bgc_uoh_inc_ratio_alloc_wait), we will make the allocation wait till the BGC is done. +// +// This means threads that allocate heavily on UOH may be paused during a BGC. If you're willing to accept +// larger UOH sizes in exchange for fewer pauses, you can use the UOHWaitBGCSizeIncPercent config to increase +// the wait ratio. Likewise, set it to use a smaller ratio if you observe that UOH grows too large during +// BGCs. +float bgc_uoh_inc_ratio_alloc_normal = 0.1f; +// This ratio is 2x for regions because regions could start with a much smaller size since a lot of +// memory could be in the free pool. +#ifdef USE_REGIONS +float bgc_uoh_inc_ratio_alloc_wait = 2.0f; +#else +float bgc_uoh_inc_ratio_alloc_wait = 1.0f; +#endif //USE_REGIONS + inline void c_write (uint32_t& place, uint32_t value) { @@ -2720,10 +2738,9 @@ heap_segment* gc_heap::freeable_soh_segment = 0; size_t gc_heap::bgc_overflow_count = 0; -size_t gc_heap::bgc_begin_loh_size = 0; -size_t gc_heap::end_loh_size = 0; -size_t gc_heap::bgc_begin_poh_size = 0; -size_t gc_heap::end_poh_size = 0; +size_t gc_heap::bgc_begin_uoh_size[uoh_generation_count] = {}; +size_t gc_heap::bgc_uoh_current_size[uoh_generation_count] = {}; +size_t gc_heap::end_uoh_size[uoh_generation_count] = {}; size_t gc_heap::uoh_a_no_bgc[uoh_generation_count] = {}; size_t gc_heap::uoh_a_bgc_marking[uoh_generation_count] = {}; @@ -2732,16 +2749,10 @@ size_t gc_heap::uoh_a_bgc_planning[uoh_generation_count] = {}; size_t gc_heap::bgc_maxgen_end_fl_size = 0; #endif //BGC_SERVO_TUNING -size_t gc_heap::bgc_loh_size_increased = 0; - -size_t gc_heap::bgc_poh_size_increased = 0; - size_t gc_heap::background_soh_size_end_mark = 0; size_t gc_heap::background_soh_alloc_count = 0; -size_t gc_heap::background_uoh_alloc_count = 0; - uint8_t** gc_heap::background_mark_stack_tos = 0; uint8_t** gc_heap::background_mark_stack_array = 0; @@ -7463,7 +7474,7 @@ bool gc_heap::virtual_commit (void* address, size_t size, int bucket, int h_numb if ((base + size) > limit) { - dprintf (1, ("%zd + %zd = %zd > limit %zd ", base, size, (base + size), limit)); + dprintf (2, ("%zd + %zd = %zd > limit %zd ", base, size, (base + size), limit)); exceeded_p = true; } } @@ -8166,19 +8177,6 @@ bool gc_heap::new_allocation_allowed (int gen_number) { if (dd_new_allocation (dynamic_data_of (gen_number)) < 0) { - if (gen_number != 0) - { - // For UOH we will give it more budget before we try a GC. - if (settings.concurrent) - { - dynamic_data* dd2 = dynamic_data_of (gen_number); - - if (dd_new_allocation (dd2) <= (ptrdiff_t)(-2 * dd_desired_allocation (dd2))) - { - return TRUE; - } - } - } return FALSE; } #ifndef MULTIPLE_HEAPS @@ -8280,9 +8278,9 @@ uint8_t* get_plug_start_in_saved (uint8_t* old_loc, mark* pinned_plug_entry) { uint8_t* saved_pre_plug_info = (uint8_t*)(pinned_plug_entry->get_pre_plug_reloc_info()); uint8_t* plug_start_in_saved = saved_pre_plug_info + (old_loc - (pinned_plug (pinned_plug_entry) - sizeof (plug_and_gap))); - //dprintf (1, ("detected a very short plug: %zx before PP %zx, pad %zx", + //dprintf (2, ("detected a very short plug: %zx before PP %zx, pad %zx", // old_loc, pinned_plug (pinned_plug_entry), plug_start_in_saved)); - dprintf (1, ("EP: %p(%p), %p", old_loc, pinned_plug (pinned_plug_entry), plug_start_in_saved)); + dprintf (2, ("EP: %p(%p), %p", old_loc, pinned_plug (pinned_plug_entry), plug_start_in_saved)); return plug_start_in_saved; } @@ -9874,7 +9872,7 @@ int gc_heap::grow_brick_card_tables (uint8_t* start, if (!write_barrier_updated) { seg_mapping_table = new_seg_mapping_table; - GCToOSInterface::FlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); g_gc_lowest_address = saved_g_lowest_address; g_gc_highest_address = saved_g_highest_address; @@ -13531,7 +13529,7 @@ void gc_heap::distribute_free_regions() size_t total_basic_free_regions = total_num_free_regions[basic_free_region] + surplus_regions[basic_free_region].get_num_free_regions(); total_budget_in_region_units[basic_free_region] = compute_basic_region_budgets(heap_budget_in_region_units[basic_free_region], min_heap_budget_in_region_units[basic_free_region], total_basic_free_regions); - + bool aggressive_decommit_large_p = joined_last_gc_before_oom || dt_high_memory_load_p() || near_heap_hard_limit_p(); int region_factor[count_distributed_free_region_kinds] = { 1, LARGE_REGION_FACTOR }; @@ -14515,6 +14513,26 @@ HRESULT gc_heap::initialize_gc (size_t soh_segment_size, #endif //WRITE_WATCH #ifdef BACKGROUND_GC +#ifdef USE_REGIONS + int bgc_uoh_inc_percent_alloc_wait = (int)GCConfig::GetUOHWaitBGCSizeIncPercent(); + if (bgc_uoh_inc_percent_alloc_wait != -1) + { + bgc_uoh_inc_ratio_alloc_wait = (float)bgc_uoh_inc_percent_alloc_wait / 100.0f; + } + else + { + bgc_uoh_inc_percent_alloc_wait = (int)(bgc_uoh_inc_ratio_alloc_wait * 100.0f); + } + + if (bgc_uoh_inc_ratio_alloc_normal > bgc_uoh_inc_ratio_alloc_wait) + { + bgc_uoh_inc_ratio_alloc_normal = bgc_uoh_inc_ratio_alloc_wait; + } + GCConfig::SetUOHWaitBGCSizeIncPercent (bgc_uoh_inc_percent_alloc_wait); + dprintf (1, ("UOH allocs during BGC are allowed normally when inc ratio is < %.3f, will wait when > %.3f", + bgc_uoh_inc_ratio_alloc_normal, bgc_uoh_inc_ratio_alloc_wait)); +#endif + // leave the first page to contain only segment info // because otherwise we could need to revisit the first page frequently in // background GC. @@ -15584,10 +15602,11 @@ gc_heap::init_gc_heap (int h_number) bgc_threads_timeout_cs.Initialize(); current_bgc_state = bgc_not_in_process; background_soh_alloc_count = 0; - background_uoh_alloc_count = 0; bgc_overflow_count = 0; - end_loh_size = dd_min_size (dynamic_data_of (loh_generation)); - end_poh_size = dd_min_size (dynamic_data_of (poh_generation)); + for (int i = uoh_start_generation; i < total_generation_count; i++) + { + end_uoh_size[i - uoh_start_generation] = dd_min_size (dynamic_data_of (i)); + } current_sweep_pos = 0; #ifdef DOUBLY_LINKED_FL @@ -18023,6 +18042,7 @@ BOOL gc_heap::a_fit_segment_end_p (int gen_number, #ifdef BACKGROUND_GC if (cookie != -1) { + bgc_record_uoh_end_seg_allocation (gen_number, limit); allocated += limit; bgc_uoh_alloc_clr (old_alloc, limit, acontext, flags, gen_number, align_const, cookie, TRUE, seg); } @@ -18050,6 +18070,10 @@ BOOL gc_heap::a_fit_segment_end_p (int gen_number, limit += Align(min_obj_size, align_const); } +#ifdef BACKGROUND_GC + bgc_record_uoh_end_seg_allocation (gen_number, limit); +#endif + allocated += limit; adjust_limit_clr (old_alloc, limit, size, acontext, flags, seg, align_const, gen_number); } @@ -18562,60 +18586,6 @@ void gc_heap::bgc_untrack_uoh_alloc() dprintf (3, ("h%d: dec lc: %d", heap_number, (int32_t)uoh_alloc_thread_count)); } } - -// We need to throttle the UOH allocations during BGC since we can't -// collect UOH when BGC is in progress (when BGC sweeps UOH allocations on UOH are disallowed) -// We allow the UOH heap size to double during a BGC. And for every -// 10% increase we will have the UOH allocating thread sleep for one more -// ms. So we are already 30% over the original heap size the thread will -// sleep for 3ms. -int bgc_allocate_spin(size_t min_gc_size, size_t bgc_begin_size, size_t bgc_size_increased, size_t end_size) -{ - if ((bgc_begin_size + bgc_size_increased) < (min_gc_size * 10)) - { - // just do it, no spinning - return 0; - } - - if ((bgc_begin_size >= (2 * end_size)) || (bgc_size_increased >= bgc_begin_size)) - { - if (bgc_begin_size >= (2 * end_size)) - { - dprintf (3, ("alloc-ed too much before bgc started")); - } - else - { - dprintf (3, ("alloc-ed too much after bgc started")); - } - - // -1 means wait for bgc - return -1; - } - else - { - return (int)(((float)bgc_size_increased / (float)bgc_begin_size) * 10); - } -} - -int gc_heap::bgc_loh_allocate_spin() -{ - size_t min_gc_size = dd_min_size (dynamic_data_of (loh_generation)); - size_t bgc_begin_size = bgc_begin_loh_size; - size_t bgc_size_increased = bgc_loh_size_increased; - size_t end_size = end_loh_size; - - return bgc_allocate_spin(min_gc_size, bgc_begin_size, bgc_size_increased, end_size); -} - -int gc_heap::bgc_poh_allocate_spin() -{ - size_t min_gc_size = dd_min_size (dynamic_data_of (poh_generation)); - size_t bgc_begin_size = bgc_begin_poh_size; - size_t bgc_size_increased = bgc_poh_size_increased; - size_t end_size = end_poh_size; - - return bgc_allocate_spin(min_gc_size, bgc_begin_size, bgc_size_increased, end_size); -} #endif //BACKGROUND_GC size_t gc_heap::get_uoh_seg_size (size_t size) @@ -18728,19 +18698,6 @@ BOOL gc_heap::uoh_try_fit (int gen_number, acontext, flags, align_const, commit_failed_p, oom_r); -#ifdef BACKGROUND_GC - if (can_allocate && gc_heap::background_running_p()) - { - if (gen_number == poh_generation) - { - bgc_poh_size_increased += size; - } - else - { - bgc_loh_size_increased += size; - } - } -#endif //BACKGROUND_GC } return can_allocate; @@ -18853,26 +18810,83 @@ bool gc_heap::should_retry_other_heap (int gen_number, size_t size) } #ifdef BACKGROUND_GC +uoh_allocation_action gc_heap::get_bgc_allocate_action (int gen_number) +{ + int uoh_idx = gen_number - uoh_start_generation; + + // We always allocate normally if the total size is small enough. + if (bgc_uoh_current_size[uoh_idx] < (dd_min_size (dynamic_data_of (gen_number)) * 10)) + { + return uoh_alloc_normal; + } + +#ifndef USE_REGIONS + // This is legacy behavior for segments - segments' sizes are usually very stable. But for regions we could + // have released a bunch of regions into the free pool during the last gen2 GC so checking the last UOH size + // doesn't make sense. + if (bgc_begin_uoh_size[uoh_idx] >= (2 * end_uoh_size[uoh_idx])) + { + dprintf (3, ("h%d alloc-ed too much before bgc started, last end %Id, this start %Id, wait", + heap_number, end_uoh_size[uoh_idx], bgc_begin_uoh_size[uoh_idx])); + return uoh_alloc_wait; + } +#endif //USE_REGIONS + + size_t size_increased = bgc_uoh_current_size[uoh_idx] - bgc_begin_uoh_size[uoh_idx]; + float size_increased_ratio = (float)size_increased / (float)bgc_begin_uoh_size[uoh_idx]; + + if (size_increased_ratio < bgc_uoh_inc_ratio_alloc_normal) + { + return uoh_alloc_normal; + } + else if (size_increased_ratio > bgc_uoh_inc_ratio_alloc_wait) + { + return uoh_alloc_wait; + } + else + { + return uoh_alloc_yield; + } +} + void gc_heap::bgc_record_uoh_allocation(int gen_number, size_t size) { assert((gen_number >= uoh_start_generation) && (gen_number < total_generation_count)); + int uoh_idx = gen_number - uoh_start_generation; + if (gc_heap::background_running_p()) { - background_uoh_alloc_count++; - if (current_c_gc_state == c_gc_state_planning) { - uoh_a_bgc_planning[gen_number - uoh_start_generation] += size; + uoh_a_bgc_planning[uoh_idx] += size; } else { - uoh_a_bgc_marking[gen_number - uoh_start_generation] += size; + uoh_a_bgc_marking[uoh_idx] += size; } } else { - uoh_a_no_bgc[gen_number - uoh_start_generation] += size; + uoh_a_no_bgc[uoh_idx] += size; + } +} + +void gc_heap::bgc_record_uoh_end_seg_allocation (int gen_number, size_t size) +{ + if ((gen_number >= uoh_start_generation) && gc_heap::background_running_p()) + { + int uoh_idx = gen_number - uoh_start_generation; + bgc_uoh_current_size[uoh_idx] += size; + +#ifdef SIMPLE_DPRINTF + dynamic_data* dd_uoh = dynamic_data_of (gen_number); + size_t gen_size = generation_size (gen_number); + dprintf (3, ("h%d g%d size is now %Id (inc-ed %Id), size is %Id (gen size is %Id), budget %.3fmb, new alloc %.3fmb", + heap_number, gen_number, bgc_uoh_current_size[uoh_idx], + (bgc_uoh_current_size[uoh_idx] - bgc_begin_uoh_size[uoh_idx]), size, gen_size, + mb (dd_desired_allocation (dd_uoh)), (dd_new_allocation (dd_uoh) / 1000.0 / 1000.0))); +#endif //SIMPLE_DPRINTF } } #endif //BACKGROUND_GC @@ -18903,31 +18917,33 @@ allocation_state gc_heap::allocate_uoh (int gen_number, if (gc_heap::background_running_p()) { - //if ((background_uoh_alloc_count % bgc_alloc_spin_count_uoh) == 0) + uoh_allocation_action action = get_bgc_allocate_action (gen_number); + + if (action == uoh_alloc_yield) { - int spin_for_allocation = (gen_number == loh_generation) ? - bgc_loh_allocate_spin() : - bgc_poh_allocate_spin(); + add_saved_spinlock_info (true, me_release, mt_alloc_large, msl_status); + leave_spin_lock (&more_space_lock_uoh); + bool cooperative_mode = enable_preemptive(); + GCToOSInterface::YieldThread (0); + disable_preemptive (cooperative_mode); - if (spin_for_allocation > 0) - { - add_saved_spinlock_info (true, me_release, mt_alloc_large, msl_status); - leave_spin_lock (&more_space_lock_uoh); - bool cooperative_mode = enable_preemptive(); - GCToOSInterface::YieldThread (spin_for_allocation); - disable_preemptive (cooperative_mode); + msl_status = enter_spin_lock_msl (&more_space_lock_uoh); + if (msl_status == msl_retry_different_heap) return a_state_retry_allocate; - msl_status = enter_spin_lock_msl (&more_space_lock_uoh); - if (msl_status == msl_retry_different_heap) return a_state_retry_allocate; + add_saved_spinlock_info (true, me_acquire, mt_alloc_large, msl_status); + dprintf (SPINLOCK_LOG, ("[%d]spin Emsl uoh", heap_number)); + } + else if (action == uoh_alloc_wait) + { + dynamic_data* dd_uoh = dynamic_data_of (loh_generation); + dprintf (3, ("h%d WAIT loh begin %.3fmb, current size recorded is %.3fmb(begin+%.3fmb), budget %.3fmb, new alloc %.3fmb (alloc-ed %.3fmb)", + heap_number, mb (bgc_begin_uoh_size[0]), mb (bgc_uoh_current_size[0]), + mb (bgc_uoh_current_size[0] - bgc_begin_uoh_size[0]), + mb (dd_desired_allocation (dd_uoh)), (dd_new_allocation (dd_uoh) / 1000.0 / 1000.0), + mb (dd_desired_allocation (dd_uoh) - dd_new_allocation (dd_uoh)))); - add_saved_spinlock_info (true, me_acquire, mt_alloc_large, msl_status); - dprintf (SPINLOCK_LOG, ("[%d]spin Emsl uoh", heap_number)); - } - else if (spin_for_allocation < 0) - { - msl_status = wait_for_background (awr_uoh_alloc_during_bgc, true); - check_msl_status ("uoh a_state_acquire_seg", size); - } + msl_status = wait_for_background (awr_uoh_alloc_during_bgc, true); + check_msl_status ("uoh a_state_acquire_seg", size); } } #endif //BACKGROUND_GC @@ -31148,7 +31164,7 @@ void gc_heap::realloc_plan_generation_start (generation* gen, generation* consin generation_allocation_pointer (consing_gen) += allocation_left; } - dprintf (1, ("plan re-alloc gen%d start at %p (ptr: %p, limit: %p)", gen->gen_num, + dprintf (2, ("plan re-alloc gen%d start at %p (ptr: %p, limit: %p)", gen->gen_num, generation_plan_allocation_start (consing_gen), generation_allocation_pointer (consing_gen), generation_allocation_limit (consing_gen))); @@ -32751,7 +32767,7 @@ void gc_heap::process_remaining_regions (int current_plan_gen_num, generation* c } } - dprintf (1, ("we still need %d regions, %d will be empty", plan_regions_needed, to_be_empty_regions)); + dprintf (REGIONS_LOG, ("we still need %d regions, %d will be empty", plan_regions_needed, to_be_empty_regions)); if (plan_regions_needed > to_be_empty_regions) { dprintf (REGIONS_LOG, ("h%d %d regions will be empty but we still need %d regions!!", heap_number, to_be_empty_regions, plan_regions_needed)); @@ -34104,7 +34120,7 @@ void gc_heap::plan_phase (int condemned_gen_number) #else 0; #endif //SHORT_PLUGS - dprintf (1, ("gen%d: NON PIN alloc: %zd, pin com: %zd, sweep: %zd, surv: %zd, pinsurv: %zd(%d%% added, %d%% art), np surv: %zd, pad: %zd", + dprintf (2, ("gen%d: NON PIN alloc: %zd, pin com: %zd, sweep: %zd, surv: %zd, pinsurv: %zd(%d%% added, %d%% art), np surv: %zd, pad: %zd", gen_idx, generation_allocation_size (temp_gen), generation_pinned_allocation_compact_size (temp_gen), @@ -38792,7 +38808,6 @@ void gc_heap::background_mark_phase () gen0_must_clear_bricks--; background_soh_alloc_count = 0; - background_uoh_alloc_count = 0; bgc_overflow_count = 0; bpromoted_bytes (heap_number) = 0; @@ -38824,8 +38839,6 @@ void gc_heap::background_mark_phase () slow = MAX_PTR; #endif //MULTIPLE_HEAPS - generation* gen = generation_of (max_generation); - dprintf(3,("BGC: stack marking")); sc.concurrent = TRUE; @@ -38836,16 +38849,19 @@ void gc_heap::background_mark_phase () dprintf(3,("BGC: finalization marking")); finalize_queue->GcScanRoots(background_promote_callback, heap_number, 0); - size_t total_soh_size = generation_sizes (generation_of (max_generation)); - size_t total_loh_size = generation_size (loh_generation); - size_t total_poh_size = generation_size (poh_generation); - bgc_begin_loh_size = total_loh_size; - bgc_begin_poh_size = total_poh_size; - bgc_loh_size_increased = 0; - bgc_poh_size_increased = 0; background_soh_size_end_mark = 0; - dprintf (GTC_LOG, ("BM: h%d: loh: %zd, soh: %zd, poh: %zd", heap_number, total_loh_size, total_soh_size, total_poh_size)); + for (int uoh_gen_idx = uoh_start_generation; uoh_gen_idx < total_generation_count; uoh_gen_idx++) + { + size_t uoh_size = generation_size (uoh_gen_idx); + int uoh_idx = uoh_gen_idx - uoh_start_generation; + bgc_begin_uoh_size[uoh_idx] = uoh_size; + bgc_uoh_current_size[uoh_idx] = uoh_size; + } + + dprintf (GTC_LOG, ("BM: h%d: soh: %zd, loh: %zd, poh: %zd", + heap_number, generation_sizes (generation_of (max_generation)), + bgc_uoh_current_size[loh_generation - uoh_start_generation], bgc_uoh_current_size[poh_generation - uoh_start_generation])); //concurrent_print_time_delta ("copying stack roots"); concurrent_print_time_delta ("CS"); @@ -39158,11 +39174,10 @@ void gc_heap::background_mark_phase () //marking sc.concurrent = FALSE; - total_soh_size = generation_sizes (generation_of (max_generation)); - total_loh_size = generation_size (loh_generation); - total_poh_size = generation_size (poh_generation); - - dprintf (GTC_LOG, ("FM: h%d: loh: %zd, soh: %zd, poh: %zd", heap_number, total_loh_size, total_soh_size, total_poh_size)); + dprintf (GTC_LOG, ("FM: h%d: soh: %zd, loh: %zd, poh: %zd", heap_number, + generation_sizes (generation_of (max_generation)), + bgc_uoh_current_size[loh_generation - uoh_start_generation], + bgc_uoh_current_size[poh_generation - uoh_start_generation])); #if defined(FEATURE_BASICFREEZE) && !defined(USE_REGIONS) if (ro_segments_in_range) @@ -42140,10 +42155,13 @@ BOOL gc_heap::card_transition (uint8_t* po, uint8_t* end, size_t card_word_end, //dprintf(3,(" Clearing cards [%zx, %zx[ ", dprintf(3,(" CC [%zx, %zx[ ", (size_t)card_address(card), (size_t)po)); - clear_cards (card, card_of(po)); - n_card_set -= (card_of (po) - card); - n_cards_cleared += (card_of (po) - card); - + uint8_t* card_clearing_limit = po; +#ifdef FEATURE_CARD_MARKING_STEALING + card_clearing_limit = min (limit, po); +#endif // FEATURE_CARD_MARKING_STEALING + clear_cards (card, card_of (card_clearing_limit)); + n_card_set -= (card_of (card_clearing_limit) - card); + n_cards_cleared += (card_of (card_clearing_limit) - card); } n_eph +=cg_pointers_found; cg_pointers_found = 0; @@ -43929,7 +43947,7 @@ generation* gc_heap::expand_heap (int condemned_generation, BOOL should_promote_ephemeral = FALSE; ptrdiff_t eph_size = total_ephemeral_size; #ifdef BACKGROUND_GC - dprintf(2,("%s: ---- Heap Expansion ----", (gc_heap::background_running_p() ? "FGC" : "NGC"))); + dprintf(2,("%s: ---- Heap Expansion ----", get_str_gc_type())); #endif //BACKGROUND_GC settings.heap_expansion = TRUE; @@ -44199,42 +44217,48 @@ void gc_heap::init_static_data() { size_t gen0_min_size = get_gen0_min_size(); - size_t gen0_max_size = -#ifdef MULTIPLE_HEAPS - max ((size_t)6*1024*1024, min ( Align(soh_segment_size/2), (size_t)200*1024*1024)); -#else //MULTIPLE_HEAPS - ( -#ifdef BACKGROUND_GC - gc_can_use_concurrent ? - 6*1024*1024 : -#endif //BACKGROUND_GC - max ((size_t)6*1024*1024, min ( Align(soh_segment_size/2), (size_t)200*1024*1024)) - ); -#endif //MULTIPLE_HEAPS - - gen0_max_size = max (gen0_min_size, gen0_max_size); - - if (heap_hard_limit) - { - size_t gen0_max_size_seg = soh_segment_size / 4; - dprintf (GTC_LOG, ("limit gen0 max %zd->%zd", gen0_max_size, gen0_max_size_seg)); - gen0_max_size = min (gen0_max_size, gen0_max_size_seg); - } + size_t gen0_max_size = 0; size_t gen0_max_size_config = (size_t)GCConfig::GetGCGen0MaxBudget(); if (gen0_max_size_config) { - gen0_max_size = min (gen0_max_size, gen0_max_size_config); + gen0_max_size = gen0_max_size_config; #ifdef FEATURE_EVENT_TRACE gen0_max_budget_from_config = gen0_max_size; #endif //FEATURE_EVENT_TRACE } + else + { + gen0_max_size = +#ifdef MULTIPLE_HEAPS + max ((size_t)6 * 1024 * 1024, min (Align(soh_segment_size / 2), (size_t)200 * 1024 * 1024)); +#else //MULTIPLE_HEAPS + ( +#ifdef BACKGROUND_GC + gc_can_use_concurrent ? + 6 * 1024 * 1024 : +#endif //BACKGROUND_GC + max ((size_t)6 * 1024 * 1024, min (Align(soh_segment_size / 2), (size_t)200 * 1024 * 1024)) + ); +#endif //MULTIPLE_HEAPS + + gen0_max_size = max (gen0_min_size, gen0_max_size); + + if (heap_hard_limit) + { + size_t gen0_max_size_seg = soh_segment_size / 4; + dprintf (GTC_LOG, ("limit gen0 max %zd->%zd", gen0_max_size, gen0_max_size_seg)); + gen0_max_size = min (gen0_max_size, gen0_max_size_seg); + } + } gen0_max_size = Align (gen0_max_size); gen0_min_size = min (gen0_min_size, gen0_max_size); + GCConfig::SetGCGen0MaxBudget (gen0_max_size); + // TODO: gen0_max_size has a 200mb cap; gen1_max_size should also have a cap. size_t gen1_max_size = (size_t) #ifdef MULTIPLE_HEAPS @@ -44267,6 +44291,17 @@ void gc_heap::init_static_data() static_data_table[i][0].max_size = gen0_max_size; static_data_table[i][1].max_size = gen1_max_size; } + +#ifdef DYNAMIC_HEAP_COUNT + if (gc_heap::dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes) + { + gc_heap::dynamic_heap_count_data.min_gen0_new_allocation = gen0_min_size; + if (gen0_max_size_config) + { + gc_heap::dynamic_heap_count_data.max_gen0_new_allocation = gen0_max_size; + } + } +#endif //DYNAMIC_HEAP_COUNT } bool gc_heap::init_dynamic_data() @@ -44431,7 +44466,7 @@ size_t gc_heap::desired_new_allocation (dynamic_data* dd, { size_t allocated = 0; size_t committed = uoh_committed_size (gen_number, &allocated); - dprintf (1, ("GC#%zd h%d, GMI: UOH budget, UOH commit %zd (obj %zd, frag %zd), total commit: %zd (recorded: %zd)", + dprintf (2, ("GC#%zd h%d, GMI: UOH budget, UOH commit %zd (obj %zd, frag %zd), total commit: %zd (recorded: %zd)", (size_t)settings.gc_index, heap_number, committed, allocated, dd_fragmentation (dynamic_data_of (gen_number)), @@ -44508,7 +44543,7 @@ size_t gc_heap::desired_new_allocation (dynamic_data* dd, dd_surv (dd) = cst; - dprintf (1, (ThreadStressLog::gcDesiredNewAllocationMsg(), + dprintf (2, (ThreadStressLog::gcDesiredNewAllocationMsg(), heap_number, gen_number, out, current_size, (dd_desired_allocation (dd) - dd_gc_new_allocation (dd)), (int)(cst*100), (int)(f*100), current_size + new_allocation, new_allocation)); @@ -44883,11 +44918,7 @@ void gc_heap::compute_new_dynamic_data (int gen_number) gen_data->free_obj_space_after = generation_free_obj_space (gen); gen_data->npinned_surv = out; #ifdef BACKGROUND_GC - if (i == loh_generation) - end_loh_size = total_gen_size; - - if (i == poh_generation) - end_poh_size = total_gen_size; + end_uoh_size[i - uoh_start_generation] = total_gen_size; #endif //BACKGROUND_GC dd_promoted_size (dd) = out; } @@ -47802,18 +47833,18 @@ void gc_heap::descr_generations (const char* msg) #endif //!TRACE_GC #ifdef STRESS_LOG - if (StressLog::StressLogOn(LF_GC, LL_INFO10)) + if (StressLog::StressLogOn(LF_GC, LL_INFO1000)) { gc_heap* hp = 0; #ifdef MULTIPLE_HEAPS hp= this; #endif //MULTIPLE_HEAPS - STRESS_LOG1(LF_GC, LL_INFO10, "GC Heap %p\n", hp); + STRESS_LOG1(LF_GC, LL_INFO1000, "GC Heap %p\n", hp); for (int n = max_generation; n >= 0; --n) { #ifndef USE_REGIONS - STRESS_LOG4(LF_GC, LL_INFO10, " Generation %d [%p, %p] cur = %p\n", + STRESS_LOG4(LF_GC, LL_INFO1000, " Generation %d [%p, %p] cur = %p\n", n, generation_allocation_start(generation_of(n)), generation_allocation_limit(generation_of(n)), @@ -47823,7 +47854,7 @@ void gc_heap::descr_generations (const char* msg) heap_segment* seg = generation_start_segment(generation_of(n)); while (seg) { - STRESS_LOG4(LF_GC, LL_INFO10, " Segment mem %p alloc = %p used %p committed %p\n", + STRESS_LOG4(LF_GC, LL_INFO1000, " Segment mem %p alloc = %p used %p committed %p\n", heap_segment_mem(seg), heap_segment_allocated(seg), heap_segment_used(seg), @@ -48653,7 +48684,7 @@ void gc_heap::verify_heap (BOOL begin_gc_p) dprintf (2,("[%s]GC#%zu(%s): Verifying heap - begin", (begin_gc_p ? "BEG" : "END"), VolatileLoad(&settings.gc_index), - (settings.concurrent ? "BGC" : (gc_heap::background_running_p() ? "FGC" : "NGC")))); + get_str_gc_type())); #else dprintf (2,("[%s]GC#%zu: Verifying heap - begin", (begin_gc_p ? "BEG" : "END"), VolatileLoad(&settings.gc_index))); @@ -49060,7 +49091,7 @@ void gc_heap::verify_heap (BOOL begin_gc_p) #ifdef BACKGROUND_GC dprintf (2, ("(%s)(%s)(%s) total_objects_verified is %zd, total_objects_verified_deep is %zd", - (settings.concurrent ? "BGC" : (gc_heap::background_running_p () ? "FGC" : "NGC")), + get_str_gc_type(), (begin_gc_p ? "BEG" : "END"), ((current_c_gc_state == c_gc_state_planning) ? "in plan" : "not in plan"), total_objects_verified, total_objects_verified_deep)); @@ -49113,7 +49144,7 @@ void gc_heap::verify_heap (BOOL begin_gc_p) } dprintf (2,("GC%zu(%s): Verifying heap - end", VolatileLoad(&settings.gc_index), - (settings.concurrent ? "BGC" : (gc_heap::background_running_p() ? "FGC" : "NGC")))); + get_str_gc_type())); #else dprintf (2,("GC#d: Verifying heap - end", VolatileLoad(&settings.gc_index))); #endif //BACKGROUND_GC @@ -49722,13 +49753,43 @@ HRESULT GCHeap::Initialize() } // This should be adjusted based on the target tcp. See comments in gcpriv.h gc_heap::dynamic_heap_count_data.around_target_threshold = 10.0; - // This should really be set as part of computing static data and should take conserve_mem_setting into consideration. - gc_heap::dynamic_heap_count_data.max_gen0_new_allocation = Align (min (dd_max_size (gc_heap::g_heaps[0]->dynamic_data_of (0)), (size_t)(64 * 1024 * 1024)), get_alignment_constant (TRUE)); - gc_heap::dynamic_heap_count_data.min_gen0_new_allocation = Align (dd_min_size (gc_heap::g_heaps[0]->dynamic_data_of (0)), get_alignment_constant (TRUE)); - dprintf (6666, ("datas max gen0 budget %Id, min %Id", - gc_heap::dynamic_heap_count_data.max_gen0_new_allocation, gc_heap::dynamic_heap_count_data.min_gen0_new_allocation)); + int gen0_growth_soh_ratio_percent = (int)GCConfig::GetGCDGen0GrowthPercent(); + if (gen0_growth_soh_ratio_percent) + { + gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_percent = (int)GCConfig::GetGCDGen0GrowthPercent() * 0.01f; + } + // You can specify what sizes you want to allow DATAS to stay within wrt the SOH stable size. + // By default DATAS allows 10x this size for gen0 budget when the size is small, and 0.1x when the size is large. + int gen0_growth_min_permil = (int)GCConfig::GetGCDGen0GrowthMinFactor(); + int gen0_growth_max_permil = (int)GCConfig::GetGCDGen0GrowthMaxFactor(); + if (gen0_growth_min_permil) + { + gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_min = gen0_growth_min_permil * 0.001f; + } + if (gen0_growth_max_permil) + { + gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_max = gen0_growth_max_permil * 0.001f; + } + + if (gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_min > gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_max) + { + log_init_error_to_host ("DATAS min permil for gen0 growth %d is greater than max %d, it needs to be lower", + gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_min, gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_max); + return E_FAIL; + } + + GCConfig::SetGCDTargetTCP ((int)gc_heap::dynamic_heap_count_data.target_tcp); + GCConfig::SetGCDGen0GrowthPercent ((int)(gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_percent * 100.0f)); + GCConfig::SetGCDGen0GrowthMinFactor ((int)(gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_min * 1000.0f)); + GCConfig::SetGCDGen0GrowthMaxFactor ((int)(gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_max * 1000.0f)); + dprintf (6666, ("DATAS gen0 growth multiplier will be adjusted by %d%%, cap %.3f-%.3f, min budget %Id, max %Id", + (int)GCConfig::GetGCDGen0GrowthPercent(), + gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_min, gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_max, + gc_heap::dynamic_heap_count_data.min_gen0_new_allocation, gc_heap::dynamic_heap_count_data.max_gen0_new_allocation)); } + + GCConfig::SetGCDynamicAdaptationMode (gc_heap::dynamic_adaptation_mode); #endif //DYNAMIC_HEAP_COUNT GCScan::GcRuntimeStructuresValid (TRUE); @@ -49779,10 +49840,10 @@ HRESULT GCHeap::Initialize() // GC callback functions bool GCHeap::IsPromoted(Object* object) { - return IsPromoted(object, true); + return IsPromoted2(object, true); } -bool GCHeap::IsPromoted(Object* object, bool bVerifyNextHeader) +bool GCHeap::IsPromoted2(Object* object, bool bVerifyNextHeader) { uint8_t* o = (uint8_t*)object; @@ -50878,6 +50939,15 @@ last_recorded_gc_info* gc_heap::get_completed_bgc_info() } #endif //BACKGROUND_GC +const char* gc_heap::get_str_gc_type() +{ +#ifdef BACKGROUND_GC + return (settings.concurrent ? "BGC" : (gc_heap::background_running_p () ? "FGC" : "NGC")); +#else // BACKGROUND_GC + return "NGC"; +#endif // BACKGROUND_GC +} + void gc_heap::do_pre_gc() { STRESS_LOG_GC_STACK; @@ -50906,14 +50976,21 @@ void gc_heap::do_pre_gc() #ifdef TRACE_GC size_t total_allocated_since_last_gc[total_oh_count]; get_total_allocated_since_last_gc (total_allocated_since_last_gc); - + bool compatibleWithStressLog = true; +#ifdef SIMPLE_DPRINTF + compatibleWithStressLog = false; +#endif //SIMPLE_DPRINTF + bgc_state b_state = bgc_not_in_process; #ifdef BACKGROUND_GC + b_state = settings.b_state; +#endif //BACKGROUND_GC + size_t heap_size_before = get_total_heap_size(); uint64_t start_gc_time = GetHighPrecisionTimeStamp(); uint64_t elapsed_since_last_gc_us = start_gc_time - last_alloc_reset_suspended_end_time; max_peak_heap_size = max (max_peak_heap_size, heap_size_before); - dprintf (6666, (ThreadStressLog::gcDetailedStartMsg(), + dprintf (6666, (ThreadStressLog::gcDetailedStartMsg(compatibleWithStressLog), VolatileLoad(&settings.gc_index), dd_collection_count (hp->dynamic_data_of (0)), settings.condemned_generation, @@ -50926,18 +51003,11 @@ void gc_heap::do_pre_gc() (elapsed_since_last_gc_us ? (total_allocated_since_last_gc[gc_oh_num::loh] / 1000.0 / elapsed_since_last_gc_us) : 0), total_allocated_since_last_gc[gc_oh_num::poh], (elapsed_since_last_gc_us ? (total_allocated_since_last_gc[gc_oh_num::poh] / 1000.0 / elapsed_since_last_gc_us) : 0), - (settings.concurrent ? "BGC" : (gc_heap::background_running_p() ? "FGC" : "NGC")), - settings.b_state, - n_heaps, - (heap_size_before / 1000.0 / 1000.0), - (max_peak_heap_size / 1000.0 / 1000.0))); -#else - dprintf (1, ("*GC* %d(gen0:%d)(%d)(alloc: %zd)", - VolatileLoad(&settings.gc_index), - dd_collection_count(hp->dynamic_data_of(0)), - settings.condemned_generation, - (total_allocated_since_last_gc[0] + total_allocated_since_last_gc[1] + total_allocated_since_last_gc[2]))); -#endif //BACKGROUND_GC + get_str_gc_type(), + b_state, + n_heaps + SIMPLE_DPRINTF_ARG(heap_size_before / 1000.0 / 1000.0) + SIMPLE_DPRINTF_ARG(max_peak_heap_size / 1000.0 / 1000.0))); if (heap_hard_limit) { @@ -51356,18 +51426,12 @@ void gc_heap::do_post_gc() } #endif //BGC_SERVO_TUNING -#ifdef BACKGROUND_GC - const char* str_gc_type = (settings.concurrent ? "BGC" : (gc_heap::background_running_p () ? "FGC" : "NGC")); -#else - const char* str_gc_type = "NGC"; -#endif //BACKGROUND_GC - dprintf (6666, (ThreadStressLog::gcDetailedEndMsg(), VolatileLoad (&settings.gc_index), dd_collection_count (hp->dynamic_data_of (0)), (get_total_heap_size() / 1000.0 / 1000.0), settings.condemned_generation, - str_gc_type, + get_str_gc_type(), (settings.compaction ? "C" : "S"), (settings.promotion ? "P" : "S"), settings.entry_memory_load, @@ -52264,13 +52328,11 @@ size_t gc_heap::get_gen0_min_size() gen0size = gen0size / 8 * 5; } -#ifdef USE_REGIONS #ifdef STRESS_REGIONS // This is just so we can test allocation using more than one region on machines with very // small caches. gen0size = ((size_t)1 << min_segment_size_shr) * 3; #endif //STRESS_REGIONS -#endif //USE_REGIONS gen0size = Align (gen0size); @@ -53867,6 +53929,8 @@ bool gc_heap::compute_memory_settings(bool is_initialization, uint32_t& nhp, uin m_high_memory_load_th = min ((high_memory_load_th + 5), v_high_memory_load_th); almost_high_memory_load_th = (high_memory_load_th > 5) ? (high_memory_load_th - 5) : 1; // avoid underflow of high_memory_load_th - 5 + GCConfig::SetGCHighMemPercent (high_memory_load_th); + return true; } diff --git a/src/coreclr/gc/gc.h b/src/coreclr/gc/gc.h index 20a51633957363..05ddbf909e21c2 100644 --- a/src/coreclr/gc/gc.h +++ b/src/coreclr/gc/gc.h @@ -285,11 +285,16 @@ struct alloc_context : gc_alloc_context #endif // FEATURE_SVR_GC }; +// NOTE! +// Do not add overloaded methods, always use a different name, different from any methods declared here or +// on the IGCHeap interface. class IGCHeapInternal : public IGCHeap { public: virtual int GetNumberOfHeaps () PURE_VIRTUAL virtual int GetHomeHeapNumber () PURE_VIRTUAL virtual size_t GetPromotedBytes(int heap_index) PURE_VIRTUAL + // Used by the bridge code. + virtual bool IsPromoted2(Object* object, bool bVerifyNextHeader) PURE_VIRTUAL unsigned GetMaxGeneration() { @@ -344,9 +349,23 @@ inline bool IsServerHeap() #define MAX_LONGPATH 1024 #endif // MAX_LONGPATH -// #define TRACE_GC +// TRACE_GC has two sub-modes: the standard VM stress log mechanism and +// SIMPLE_DPRINTF, which is text output. By default, we enable TRACE_GC (not +// SIMPLE_DPRINTF) for debug/checked builds so that we can catch build breaks. +// HOST_64BIT is required because logging dprintf to the stress log is only +// supported on 64 bit platforms. We could consider enabling it in release +// builds and for more logging sites (see below for details) but are being +// conservative about performance impact. +// +// Normal development time changes are to enable SIMPLE_DPRINTF here (which +// will automatically set TRACE_GC) or to only enable TRACE_GC. + // #define SIMPLE_DPRINTF +#if defined(SIMPLE_DPRINTF) || (defined(_DEBUG) && defined(HOST_64BIT)) +#define TRACE_GC +#endif // _DEBUG + #ifdef TRACE_GC #define MIN_CUSTOM_LOG_LEVEL 7 #define SEG_REUSE_LOG_0 (MIN_CUSTOM_LOG_LEVEL) @@ -375,10 +394,79 @@ HRESULT initialize_log_file(); void flush_gc_log (bool); void GCLog (const char *fmt, ... ); #define dprintf(l,x) {if ((l == 1) || (l == GTC_LOG)) {GCLog x;}} +#define SIMPLE_DPRINTF_ARG(x) , x + #else //SIMPLE_DPRINTF + #ifdef HOST_64BIT -#define dprintf(l,x) STRESS_LOG_VA(l,x); + +// ------------------------------- +// Stress log / dprintf background +// ------------------------------- +// +// This code connects dprintf to the stress log mechanism. These machanisms +// and their usage has evolved a bit separately over time, so there are some +// rough edges here. +// +// The stress log mechanism has a LogFacility and a LogLevel. Facilities can be +// chosen through DOTNET_LogFacility, and the facility is recorded in the +// stress log. LogFacility is a bitmask. The GC only has a few bits reserved +// in the bitmask, and most GC logging uses a single value (LF_GC, which is 0x1). +// +// The stress log logging level can be chosen through DOTNET_LogLevel. This +// causes filtering at runtime, and the level is not recorded in the stress log. +// The first argument to dprintf is similar, though it can record either a level +// (values below 7) or a GC area (values starting with SEG_REUSE_LOG_0 above). +// Developers often use StressLogAnalyzer to filter by this value at _analysis_ +// time, which doesn't match usual stress log usage. +// +// In practice, dprintf(1) and LL_INFO10 (which has the value 4) have been used +// similarly on log messages. A dprintf(1) is generally called about a few times per +// GC, and LL_INFO10 is "10 logs per small but not trivial run". Other values +// have been audited. We could consider moving the GC values to be in line with +// the rest of the runtime (change 1 to 4 to make room for errors/warnings, etc.) +// or (to avoid churn) convert them by adding 3. +// +// To allow StressLogAnalyzer to use the GC level values, we abuse the stress +// log LogLevel by storing the GC value in the upper 16 bits of LogLevel and +// also settings LF_GC (0x1). This works because we don't enable other logging +// when doing GC investigations. However, we don't want to do this by default +// because setting the upper bits will cause GC logging to masquerade as non-GC +// logging. For example, dprintf(3) would use (3 << 16) | LF_GC == 0x30001, +// which is LF_ASSERT | LF_VERIFIER | LF_GC in other contexts. +// +// Lastly, we have GC logging for some very low level operations, so by default +// we don't want to even have the check that logging is enabled for performance +// reasons. Right now we are very conservative and only allow dprintf(1) to go +// to the stress log in default builds, but we could consider allowing more in +// the future. + +// ----------------------------- +// Stress log / dprintf settings +// ----------------------------- +// +// (See above for details.) +// +// The following line works for normal debug/checked builds (where STRESS_LOG is +// defined and SIMPLE_DPRINTF is not). All dprintf sites are checked for +// compilation errors, yet all but those with level 1 can be statically +// optimized away. In the future after more auditing, this could be expanded to +// more levels. +// +// Note that zero is passed because STRESS_LOG_VA/LogMsg will add LF_GC and in +// normal builds we don't want conflicts in the upper bits of LogFacility. +#define dprintf(l,x) if (l == 1) {STRESS_LOG_VA(0,x);} + +// For private builds where it is ok (and useful) to have conflicts in the upper +// bits of LogFacility, more events can be allowed and the dprintf level can be +// passed through. Usually this is going to be a GC investigation and the other +// logging will be disabled, so the theoretical conflict won't happen in +// practice. Note that in these examples, 'l' ("ell", not "one") is passed +// rather than '0'. +//#define dprintf(l,x) STRESS_LOG_VA(l,x); //#define dprintf(l,x) {if ((l <= 2) || (l == 6666)) {STRESS_LOG_VA(l,x);}} + +#define SIMPLE_DPRINTF_ARG(x) #else //HOST_64BIT #error Logging dprintf to stress log on 32 bits platforms is not supported. #endif //HOST_64BIT diff --git a/src/coreclr/gc/gcbridge.cpp b/src/coreclr/gc/gcbridge.cpp index 3b29af418c30c5..ea008244ac3163 100644 --- a/src/coreclr/gc/gcbridge.cpp +++ b/src/coreclr/gc/gcbridge.cpp @@ -666,7 +666,7 @@ static bool PushObject(Object* obj, void* unused) } // We only care about dead objects - if (!data && g_theGCHeap->IsPromoted(obj, false)) + if (!data && g_theGCHeap->IsPromoted2(obj, false)) { #if DUMP_GRAPH printf ("alive\n"); diff --git a/src/coreclr/gc/gcconfig.h b/src/coreclr/gc/gcconfig.h index 0378323b6e96c5..aa23ff7ebc59c8 100644 --- a/src/coreclr/gc/gcconfig.h +++ b/src/coreclr/gc/gcconfig.h @@ -98,7 +98,7 @@ class GCConfigStringHolder "prefixed by the CPU group number. Example: Unix - 1,3,5,7-9,12, Windows - 0:1,1:7-9") \ INT_CONFIG (GCHighMemPercent, "GCHighMemPercent", "System.GC.HighMemoryPercent", 0, "The percent for GC to consider as high memory") \ INT_CONFIG (GCProvModeStress, "GCProvModeStress", NULL, 0, "Stress the provisional modes") \ - INT_CONFIG (GCGen0MaxBudget, "GCGen0MaxBudget", NULL, 0, "Specifies the largest gen0 allocation budget") \ + INT_CONFIG (GCGen0MaxBudget, "GCGen0MaxBudget", "System.GC.Gen0MaxBudget", 0, "Specifies the largest gen0 allocation budget") \ INT_CONFIG (GCGen1MaxBudget, "GCGen1MaxBudget", NULL, 0, "Specifies the largest gen1 allocation budget") \ INT_CONFIG (GCLowSkipRatio, "GCLowSkipRatio", NULL, 30, "Specifies the low generation skip ratio") \ INT_CONFIG (GCHeapHardLimit, "GCHeapHardLimit", "System.GC.HeapHardLimit", 0, "Specifies a hard limit for the GC heap") \ @@ -128,6 +128,7 @@ class GCConfigStringHolder INT_CONFIG (BGCFLEnableTBH, "BGCFLEnableTBH", NULL, 0, "Enables TBH") \ INT_CONFIG (BGCFLEnableFF, "BGCFLEnableFF", NULL, 0, "Enables FF") \ INT_CONFIG (BGCG2RatioStep, "BGCG2RatioStep", NULL, 5, "Ratio correction factor for ML loop") \ + INT_CONFIG (UOHWaitBGCSizeIncPercent, "UOHWaitBGCSizeIncPercent", "System.GC.UOHWaitBGCSizeIncPercent",-1, "UOH allocation during a BGC waits till end of BGC after UOH increases by this percent") \ INT_CONFIG (GCHeapHardLimitSOH, "GCHeapHardLimitSOH", "System.GC.HeapHardLimitSOH", 0, "Specifies a hard limit for the GC heap SOH") \ INT_CONFIG (GCHeapHardLimitLOH, "GCHeapHardLimitLOH", "System.GC.HeapHardLimitLOH", 0, "Specifies a hard limit for the GC heap LOH") \ INT_CONFIG (GCHeapHardLimitPOH, "GCHeapHardLimitPOH", "System.GC.HeapHardLimitPOH", 0, "Specifies a hard limit for the GC heap POH") \ @@ -143,6 +144,9 @@ class GCConfigStringHolder INT_CONFIG (GCDynamicAdaptationMode, "GCDynamicAdaptationMode", "System.GC.DynamicAdaptationMode", 1, "Enable the GC to dynamically adapt to application sizes.") \ INT_CONFIG (GCDTargetTCP, "GCDTargetTCP", "System.GC.DTargetTCP", 0, "Specifies the target tcp for DATAS") \ INT_CONFIG (GCDBGCRatio, "GCDBGCRatio", NULL, 0, "Specifies the ratio of BGC to NGC2 for HC change") \ + INT_CONFIG (GCDGen0GrowthPercent, "GCDGen0GrowthPercent", "System.GC.DGen0GrowthPercent", 0, "Specifies the percentage of the default growth factor") \ + INT_CONFIG (GCDGen0GrowthMinFactor, "GCDGen0GrowthMinFactor", "System.GC.DGen0GrowthMinFactor", 0, "Specifies the minimum growth factor in permil") \ + INT_CONFIG (GCDGen0GrowthMaxFactor, "GCDGen0GrowthMaxFactor", "System.GC.DGen0GrowthMaxFactor", 0, "Specifies the maximum growth factor in permil") \ BOOL_CONFIG (GCCacheSizeFromSysConf, "GCCacheSizeFromSysConf", NULL, false, "Specifies using sysconf to retrieve the last level cache size for Unix.") // This class is responsible for retreiving configuration information diff --git a/src/coreclr/gc/gcimpl.h b/src/coreclr/gc/gcimpl.h index 93c856a2145f0d..0ab8741e96fdb3 100644 --- a/src/coreclr/gc/gcimpl.h +++ b/src/coreclr/gc/gcimpl.h @@ -126,7 +126,7 @@ class GCHeap : public IGCHeapInternal // Check if an argument is promoted (ONLY CALL DURING // THE PROMOTIONSGRANTED CALLBACK.) bool IsPromoted (Object *object); - bool IsPromoted (Object *object, bool bVerifyNextHeader); + bool IsPromoted2 (Object *object, bool bVerifyNextHeader); size_t GetPromotedBytes (int heap_index); diff --git a/src/coreclr/gc/gcinterface.h b/src/coreclr/gc/gcinterface.h index 5cb43429c09896..d24e2c1209881d 100644 --- a/src/coreclr/gc/gcinterface.h +++ b/src/coreclr/gc/gcinterface.h @@ -644,6 +644,9 @@ enum class GCConfigurationType using ConfigurationValueFunc = void (*)(void* context, void* name, void* publicKey, GCConfigurationType type, int64_t data); // IGCHeap is the interface that the VM will use when interacting with the GC. +// NOTE! +// Only add methods to the end. +// Do not add overloaded methods. Always use a different name. class IGCHeap { public: /* @@ -1065,9 +1068,6 @@ class IGCHeap { virtual void DiagWalkHeapWithACHandling(walk_fn fn, void* context, int gen_number, bool walk_large_object_heap_p) PURE_VIRTUAL virtual void NullBridgeObjectsWeakRefs(size_t length, void* unreachableObjectHandles) PURE_VIRTUAL; - - // Returns whether nor this GC was promoted by the last GC. - virtual bool IsPromoted(Object* object, bool bVerifyNextHeader) PURE_VIRTUAL }; #ifdef WRITE_BARRIER_CHECK diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h index 6771884e58ca46..79a2dd1b2d4ba5 100644 --- a/src/coreclr/gc/gcpriv.h +++ b/src/coreclr/gc/gcpriv.h @@ -561,6 +561,15 @@ enum allocation_state a_state_max }; +#ifdef BACKGROUND_GC +enum uoh_allocation_action +{ + uoh_alloc_normal, + uoh_alloc_yield, + uoh_alloc_wait +}; +#endif //BACKGROUND_GC + enum enter_msl_status { msl_entered, @@ -1578,6 +1587,8 @@ class gc_heap private: + PER_HEAP_ISOLATED_METHOD const char* get_str_gc_type(); + #ifdef TRACE_GC PER_HEAP_METHOD void print_free_list (int gen, heap_segment* seg); #endif // TRACE_GC @@ -2306,18 +2317,16 @@ class gc_heap int lock_index, BOOL check_used_p, heap_segment* seg); -#endif //BACKGROUND_GC -#ifdef BACKGROUND_GC PER_HEAP_METHOD void bgc_track_uoh_alloc(); PER_HEAP_METHOD void bgc_untrack_uoh_alloc(); - PER_HEAP_METHOD BOOL bgc_loh_allocate_spin(); - - PER_HEAP_METHOD BOOL bgc_poh_allocate_spin(); + PER_HEAP_METHOD uoh_allocation_action get_bgc_allocate_action (int gen_number); PER_HEAP_METHOD void bgc_record_uoh_allocation(int gen_number, size_t size); + + PER_HEAP_METHOD void bgc_record_uoh_end_seg_allocation (int gen_number, size_t size); #endif //BACKGROUND_GC PER_HEAP_METHOD void add_saved_spinlock_info ( @@ -3549,11 +3558,6 @@ class gc_heap #ifdef BACKGROUND_GC PER_HEAP_FIELD_SINGLE_GC VOLATILE(bgc_state) current_bgc_state; - PER_HEAP_FIELD_SINGLE_GC size_t bgc_begin_loh_size; - PER_HEAP_FIELD_SINGLE_GC size_t bgc_begin_poh_size; - PER_HEAP_FIELD_SINGLE_GC size_t end_loh_size; - PER_HEAP_FIELD_SINGLE_GC size_t end_poh_size; - // We can't process the ephemeral range concurrently so we // wait till final mark to process it. PER_HEAP_FIELD_SINGLE_GC BOOL processed_eph_overflow_p; @@ -3565,6 +3569,9 @@ class gc_heap PER_HEAP_FIELD_SINGLE_GC uint8_t* next_sweep_obj; PER_HEAP_FIELD_SINGLE_GC uint8_t* current_sweep_pos; + PER_HEAP_FIELD_SINGLE_GC size_t bgc_begin_uoh_size[uoh_generation_count]; + PER_HEAP_FIELD_SINGLE_GC size_t end_uoh_size[uoh_generation_count]; + PER_HEAP_FIELD_SINGLE_GC size_t uoh_a_no_bgc[uoh_generation_count]; PER_HEAP_FIELD_SINGLE_GC size_t uoh_a_bgc_marking[uoh_generation_count]; PER_HEAP_FIELD_SINGLE_GC size_t uoh_a_bgc_planning[uoh_generation_count]; @@ -3775,14 +3782,10 @@ class gc_heap #endif //MULTIPLE_HEAPS #ifdef BACKGROUND_GC - // This includes what we allocate at the end of segment - allocating - // in free list doesn't increase the heap size. - PER_HEAP_FIELD_SINGLE_GC_ALLOC size_t bgc_loh_size_increased; - PER_HEAP_FIELD_SINGLE_GC_ALLOC size_t bgc_poh_size_increased; - // Updated by the allocator and reinit-ed in each BGC - PER_HEAP_FIELD_SINGLE_GC_ALLOC size_t background_soh_alloc_count; - PER_HEAP_FIELD_SINGLE_GC_ALLOC size_t background_uoh_alloc_count; + PER_HEAP_FIELD_SINGLE_GC_ALLOC size_t bgc_uoh_current_size[uoh_generation_count]; + + PER_HEAP_FIELD_SINGLE_GC_ALLOC size_t background_soh_alloc_count; PER_HEAP_FIELD_SINGLE_GC_ALLOC VOLATILE(int32_t) uoh_alloc_thread_count; #endif //BACKGROUND_GC @@ -4385,6 +4388,18 @@ class gc_heap float target_tcp = 2.0; float target_gen2_tcp = 10.0; + // The following 3 constants are used in the computation for the total gen0 budget relative to the stable soh size. + // + // By default DATAS computes a multiplier (gen0_growth_soh_ratio) that scales the size. This multiplier follows + // a power decay curve where the multiplier decreases rapidly as the size increases. We cap it at 10x at the low + // end and 10% at the high end. + // + // You can choose to modify these by specifying gen0_growth_factor_percent to reduce or increase this multiplier + // and the min/max multipliers. + float gen0_growth_soh_ratio_percent = 1.0; + float gen0_growth_soh_ratio_min = 0.1f; + float gen0_growth_soh_ratio_max = 10.0; + static const int recorded_adjustment_size = 4; static const int sample_size = 3; static const int recorded_tcp_array_size = 64; @@ -5066,23 +5081,23 @@ class gc_heap // time in msl). // - size_t max_gen0_new_allocation; - size_t min_gen0_new_allocation; + size_t max_gen0_new_allocation = 64 * 1024 * 1024; + size_t min_gen0_new_allocation = 0; size_t compute_total_gen0_budget (size_t total_soh_stable_size) { assert (total_soh_stable_size > 0); - float factor = (float)(20 - conserve_mem_setting); - double old_gen_growth_factor = factor / sqrt ((double)total_soh_stable_size / 1000.0 / 1000.0); - double saved_old_gen_growth_factor = old_gen_growth_factor; - old_gen_growth_factor = min (10.0, old_gen_growth_factor); - old_gen_growth_factor = max (0.1, old_gen_growth_factor); + float factor = (float)(20 - conserve_mem_setting) * gen0_growth_soh_ratio_percent; + double gen0_growth_soh_ratio = factor / sqrt ((double)total_soh_stable_size / 1000.0 / 1000.0); + double saved_gen0_growth_soh_ratio = gen0_growth_soh_ratio; + gen0_growth_soh_ratio = min ((double)gen0_growth_soh_ratio_max, gen0_growth_soh_ratio); + gen0_growth_soh_ratio = max ((double)gen0_growth_soh_ratio_min, gen0_growth_soh_ratio); - size_t total_new_allocation_old_gen = (size_t)(old_gen_growth_factor * (double)total_soh_stable_size); + size_t total_new_allocation_old_gen = (size_t)(gen0_growth_soh_ratio * (double)total_soh_stable_size); dprintf (6666, ("stable soh %Id (%.3fmb), factor %.3f=>%.3f -> total gen0 new_alloc %Id (%.3fmb)", total_soh_stable_size, ((double)total_soh_stable_size / 1000.0 / 1000.0), - saved_old_gen_growth_factor, old_gen_growth_factor, total_new_allocation_old_gen, + saved_gen0_growth_soh_ratio, gen0_growth_soh_ratio, total_new_allocation_old_gen, ((double)total_new_allocation_old_gen / 1000.0 / 1000.0))); return total_new_allocation_old_gen; } @@ -5364,11 +5379,6 @@ class gc_heap #ifdef BACKGROUND_GC PER_HEAP_ISOLATED_FIELD_INIT_ONLY bool gc_can_use_concurrent; - -#ifdef BGC_SERVO_TUNING - // This tells us why we chose to do a bgc in tuning. - PER_HEAP_ISOLATED_FIELD_DIAG_ONLY int saved_bgc_tuning_reason; -#endif //BGC_SERVO_TUNING #endif //BACKGROUND_GC PER_HEAP_ISOLATED_FIELD_INIT_ONLY uint8_t* bookkeeping_start; @@ -5481,6 +5491,11 @@ class gc_heap // This can only go from false to true concurrently so if it is true, // it means the bgc info is ready. PER_HEAP_ISOLATED_FIELD_DIAG_ONLY VOLATILE(bool) is_last_recorded_bgc; + +#ifdef BGC_SERVO_TUNING + // This tells us why we chose to do a bgc in tuning. + PER_HEAP_ISOLATED_FIELD_DIAG_ONLY int saved_bgc_tuning_reason; +#endif //BGC_SERVO_TUNING #endif //BACKGROUND_GC #ifdef DYNAMIC_HEAP_COUNT @@ -6231,10 +6246,13 @@ class heap_segment int plan_gen_num; int old_card_survived; int pinned_survived; - // at the end of each GC, we increase each region in the region free list - // by 1. So we can observe if a region stays in the free list over many - // GCs. We stop at 99. It's initialized to 0 when a region is added to - // the region's free list. + // at the end of each GC, we increase the age of each region in the relevant region + // free list(s) by 1. So we can observe if a region stays in the free list over many + // GCs. We stop at 99. It's initialized to 0 when a region is added to the region's free list. + // + // "Relevant" means we only age basic regions during ephemeral GCs and age all regions + // during gen2 GCs. The only exception is we do age all regions during an ephemeral GC + // done at the beginning of a BGC. #define MAX_AGE_IN_FREE 99 #define AGE_IN_FREE_TO_DECOMMIT_BASIC 20 #define AGE_IN_FREE_TO_DECOMMIT_LARGE 5 diff --git a/src/coreclr/gc/softwarewritewatch.cpp b/src/coreclr/gc/softwarewritewatch.cpp index c72e2c6fcb9db5..c42c63dcd0d47a 100644 --- a/src/coreclr/gc/softwarewritewatch.cpp +++ b/src/coreclr/gc/softwarewritewatch.cpp @@ -5,6 +5,7 @@ #include "gcenv.h" #include "env/gcenv.os.h" #include "softwarewritewatch.h" +#include #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP #ifndef DACCESS_COMPILE @@ -131,7 +132,7 @@ void SoftwareWriteWatch::GetDirty( { // When a page is marked as dirty, a memory barrier is not issued after the write most of the time. Issue a memory // barrier on all active threads of the process now to make recent changes to dirty state visible to this thread. - GCToOSInterface::FlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); } uint8_t *tableRegionStart; @@ -233,7 +234,7 @@ void SoftwareWriteWatch::GetDirty( // that the GC will not miss marking through dirtied objects in the page. Issue a memory barrier on all active threads // of the process now. MemoryBarrier(); // flush writes from this thread first to guarantee ordering - GCToOSInterface::FlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); } } diff --git a/src/coreclr/gc/unix/gcenv.unix.cpp b/src/coreclr/gc/unix/gcenv.unix.cpp index 720828b2565f85..682c6adac7807c 100644 --- a/src/coreclr/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/gc/unix/gcenv.unix.cpp @@ -23,6 +23,7 @@ #include "volatile.h" #include "gcconfig.h" #include "numasupport.h" +#include #include #include @@ -30,17 +31,6 @@ #include #endif -#ifdef __linux__ -#include -#include -#define membarrier(...) syscall(__NR_membarrier, __VA_ARGS__) -#elif HAVE_SYS_MEMBARRIER_H -#include -#ifdef TARGET_BROWSER -#define membarrier(cmd, flags, cpu_id) 0 // browser/wasm is currently single threaded -#endif -#endif - #include #undef min @@ -85,21 +75,6 @@ #include #include -extern "C" -{ -# include -} - -#define CHECK_MACH(_msg, machret) do { \ - if (machret != KERN_SUCCESS) \ - { \ - char _szError[1024]; \ - snprintf(_szError, ARRAY_SIZE(_szError), "%s: %u: %s", __FUNCTION__, __LINE__, _msg); \ - mach_error(_szError, machret); \ - abort(); \ - } \ - } while (false) - #endif // __APPLE__ #ifdef __HAIKU__ @@ -140,48 +115,6 @@ typedef cpuset_t cpu_set_t; // The cached total number of CPUs that can be used in the OS. static uint32_t g_totalCpuCount = 0; -bool CanFlushUsingMembarrier() -{ -#if defined(__linux__) || HAVE_SYS_MEMBARRIER_H - -#ifdef TARGET_ANDROID - // Avoid calling membarrier on older Android versions where membarrier - // may be barred by seccomp causing the process to be killed. - int apiLevel = android_get_device_api_level(); - if (apiLevel < __ANDROID_API_Q__) - { - return false; - } -#endif - - // Starting with Linux kernel 4.14, process memory barriers can be generated - // using MEMBARRIER_CMD_PRIVATE_EXPEDITED. - - int mask = membarrier(MEMBARRIER_CMD_QUERY, 0, 0); - - if (mask >= 0 && - mask & MEMBARRIER_CMD_PRIVATE_EXPEDITED && - // Register intent to use the private expedited command. - membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0, 0) == 0) - { - return true; - } -#endif - - return false; -} - -// -// Tracks if the OS supports FlushProcessWriteBuffers using membarrier -// -static int s_flushUsingMemBarrier = 0; - -// Helper memory page used by the FlushProcessWriteBuffers -static uint8_t* g_helperPage = 0; - -// Mutex to make the FlushProcessWriteBuffersMutex thread safe -static pthread_mutex_t g_flushProcessWriteBuffersMutex; - size_t GetRestrictedPhysicalMemoryLimit(); bool GetPhysicalMemoryUsed(size_t* val); @@ -219,49 +152,10 @@ bool GCToOSInterface::Initialize() g_totalCpuCount = cpuCount; - // - // support for FlusProcessWriteBuffers - // - - assert(s_flushUsingMemBarrier == 0); - - if (CanFlushUsingMembarrier()) + if (!minipal_initialize_memory_barrier_process_wide()) { - s_flushUsingMemBarrier = TRUE; - } -#ifndef TARGET_APPLE - else - { - assert(g_helperPage == 0); - - g_helperPage = static_cast(mmap(0, OS_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); - - if (g_helperPage == MAP_FAILED) - { - return false; - } - - // Verify that the s_helperPage is really aligned to the g_SystemInfo.dwPageSize - assert((((size_t)g_helperPage) & (OS_PAGE_SIZE - 1)) == 0); - - // Locking the page ensures that it stays in memory during the two mprotect - // calls in the FlushProcessWriteBuffers below. If the page was unmapped between - // those calls, they would not have the expected effect of generating IPI. - int status = mlock(g_helperPage, OS_PAGE_SIZE); - - if (status != 0) - { - return false; - } - - status = pthread_mutex_init(&g_flushProcessWriteBuffersMutex, NULL); - if (status != 0) - { - munlock(g_helperPage, OS_PAGE_SIZE); - return false; - } + return false; } -#endif // !TARGET_APPLE InitializeCGroup(); @@ -353,13 +247,6 @@ bool GCToOSInterface::Initialize() // Shutdown the interface implementation void GCToOSInterface::Shutdown() { - int ret = munlock(g_helperPage, OS_PAGE_SIZE); - assert(ret == 0); - ret = pthread_mutex_destroy(&g_flushProcessWriteBuffersMutex); - assert(ret == 0); - - munmap(g_helperPage, OS_PAGE_SIZE); - CleanupCGroup(); } @@ -409,89 +296,6 @@ bool GCToOSInterface::CanGetCurrentProcessorNumber() return HAVE_SCHED_GETCPU; } -// Flush write buffers of processors that are executing threads of the current process -void GCToOSInterface::FlushProcessWriteBuffers() -{ -#if defined(__linux__) || HAVE_SYS_MEMBARRIER_H - if (s_flushUsingMemBarrier) - { - int status = membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0, 0); - assert(status == 0 && "Failed to flush using membarrier"); - } - else -#endif - if (g_helperPage != 0) - { - int status = pthread_mutex_lock(&g_flushProcessWriteBuffersMutex); - assert(status == 0 && "Failed to lock the flushProcessWriteBuffersMutex lock"); - - // Changing a helper memory page protection from read / write to no access - // causes the OS to issue IPI to flush TLBs on all processors. This also - // results in flushing the processor buffers. - status = mprotect(g_helperPage, OS_PAGE_SIZE, PROT_READ | PROT_WRITE); - assert(status == 0 && "Failed to change helper page protection to read / write"); - - // Ensure that the page is dirty before we change the protection so that - // we prevent the OS from skipping the global TLB flush. - __sync_add_and_fetch((size_t*)g_helperPage, 1); - - status = mprotect(g_helperPage, OS_PAGE_SIZE, PROT_NONE); - assert(status == 0 && "Failed to change helper page protection to no access"); - - status = pthread_mutex_unlock(&g_flushProcessWriteBuffersMutex); - assert(status == 0 && "Failed to unlock the flushProcessWriteBuffersMutex lock"); - } -#ifdef TARGET_APPLE - else - { - mach_msg_type_number_t cThreads; - thread_act_t *pThreads; - kern_return_t machret = task_threads(mach_task_self(), &pThreads, &cThreads); - CHECK_MACH("task_threads()", machret); - - uintptr_t sp; - uintptr_t registerValues[128]; - - // Iterate through each of the threads in the list. - for (mach_msg_type_number_t i = 0; i < cThreads; i++) - { - if (__builtin_available (macOS 10.14, iOS 12, tvOS 9, *)) - { - // Request the threads pointer values to force the thread to emit a memory barrier - size_t registers = 128; - machret = thread_get_register_pointer_values(pThreads[i], &sp, ®isters, registerValues); - } - else - { - // fallback implementation for older OS versions -#if defined(HOST_AMD64) - x86_thread_state64_t threadState; - mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; - machret = thread_get_state(pThreads[i], x86_THREAD_STATE64, (thread_state_t)&threadState, &count); -#elif defined(HOST_ARM64) - arm_thread_state64_t threadState; - mach_msg_type_number_t count = ARM_THREAD_STATE64_COUNT; - machret = thread_get_state(pThreads[i], ARM_THREAD_STATE64, (thread_state_t)&threadState, &count); -#else - #error Unexpected architecture -#endif - } - - if (machret == KERN_INSUFFICIENT_BUFFER_SIZE) - { - CHECK_MACH("thread_get_register_pointer_values()", machret); - } - - machret = mach_port_deallocate(mach_task_self(), pThreads[i]); - CHECK_MACH("mach_port_deallocate()", machret); - } - // Deallocate the thread list now we're done with it. - machret = vm_deallocate(mach_task_self(), (vm_address_t)pThreads, cThreads * sizeof(thread_act_t)); - CHECK_MACH("vm_deallocate()", machret); - } -#endif // TARGET_APPLE -} - // Break into a debugger. Uses a compiler intrinsic if one is available, // otherwise raises a SIGTRAP. void GCToOSInterface::DebugBreak() @@ -576,7 +380,7 @@ static void* VirtualReserveInner(size_t size, size_t alignment, uint32_t flags, } pRetVal = pAlignedRetVal; -#ifdef MADV_DONTDUMP +#if defined(MADV_DONTDUMP) && !defined(TARGET_WASM) // Do not include reserved uncommitted memory in coredump. if (!committing) { @@ -624,9 +428,13 @@ bool GCToOSInterface::VirtualRelease(void* address, size_t size) // true if it has succeeded, false if it has failed static bool VirtualCommitInner(void* address, size_t size, uint16_t node, bool newMemory) { +#ifndef TARGET_WASM bool success = mprotect(address, size, PROT_WRITE | PROT_READ) == 0; +#else + bool success = true; +#endif // !TARGET_WASM -#ifdef MADV_DODUMP +#if defined(MADV_DONTDUMP) && !defined(TARGET_WASM) if (success && !newMemory) { // Include committed memory in coredump. New memory is included by default. diff --git a/src/coreclr/gc/windows/gcenv.windows.cpp b/src/coreclr/gc/windows/gcenv.windows.cpp index 3e8040be0bcbb1..8285e71d354aaf 100644 --- a/src/coreclr/gc/windows/gcenv.windows.cpp +++ b/src/coreclr/gc/windows/gcenv.windows.cpp @@ -640,12 +640,6 @@ bool GCToOSInterface::CanGetCurrentProcessorNumber() return true; } -// Flush write buffers of processors that are executing threads of the current process -void GCToOSInterface::FlushProcessWriteBuffers() -{ - ::FlushProcessWriteBuffers(); -} - // Break into a debugger void GCToOSInterface::DebugBreak() { diff --git a/src/coreclr/hosts/CMakeLists.txt b/src/coreclr/hosts/CMakeLists.txt index dba881f7c6a3a7..4be3bbe8b95805 100644 --- a/src/coreclr/hosts/CMakeLists.txt +++ b/src/coreclr/hosts/CMakeLists.txt @@ -1,7 +1,11 @@ include_directories(inc) -if(CLR_CMAKE_HOST_WIN32) - add_subdirectory(coreshim) -endif(CLR_CMAKE_HOST_WIN32) +if (CLR_CMAKE_TARGET_ARCH_WASM) + add_subdirectory(corewasmrun) +else() + if(CLR_CMAKE_HOST_WIN32) + add_subdirectory(coreshim) + endif(CLR_CMAKE_HOST_WIN32) -add_subdirectory(corerun) + add_subdirectory(corerun) +endif() diff --git a/src/coreclr/hosts/corewasmrun/CMakeLists.txt b/src/coreclr/hosts/corewasmrun/CMakeLists.txt new file mode 100644 index 00000000000000..01613dde60315a --- /dev/null +++ b/src/coreclr/hosts/corewasmrun/CMakeLists.txt @@ -0,0 +1,28 @@ +project(corewasmrun) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +if (DEFINED CLR_CMAKE_ICU_DIR) + link_directories(${CLR_CMAKE_ICU_DIR}/lib) +endif(DEFINED CLR_CMAKE_ICU_DIR) + +add_executable_clr(corewasmrun + corewasmrun.cpp +) + +set(_WASM_PRELOAD_DIR "${CMAKE_INSTALL_PREFIX}/IL") +if (EXISTS "${_WASM_PRELOAD_DIR}") + set(_WASM_PRELOAD_FILE --preload-file ${_WASM_PRELOAD_DIR}@/) +endif (EXISTS "${_WASM_PRELOAD_DIR}") + +target_compile_options(corewasmrun PRIVATE -fwasm-exceptions) +target_link_options(corewasmrun PRIVATE -fwasm-exceptions -sEXIT_RUNTIME=1 -sINITIAL_MEMORY=134217728 -sFORCE_FILESYSTEM=1 ${_WASM_PRELOAD_FILE} -Wl,-error-limit=0) + +target_link_libraries(corewasmrun PRIVATE coreclr_static) +target_link_libraries(corewasmrun PRIVATE clrinterpreter) + +target_link_libraries(corewasmrun PRIVATE icuuc) +target_link_libraries(corewasmrun PRIVATE icui18n) +target_link_libraries(corewasmrun PRIVATE icudata) + +install_clr(TARGETS corewasmrun DESTINATIONS . COMPONENT hosts) diff --git a/src/coreclr/hosts/corewasmrun/corewasmrun.cpp b/src/coreclr/hosts/corewasmrun/corewasmrun.cpp new file mode 100644 index 00000000000000..2fff454fc0200b --- /dev/null +++ b/src/coreclr/hosts/corewasmrun/corewasmrun.cpp @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// + +#include +#include + +static void log_error_info(const char* line) +{ + std::fprintf(stderr, "log error: %s\n", line); +} + +// The current CoreCLR instance details. +static void* CurrentClrInstance; +static unsigned int CurrentAppDomainId; + +static int run() +{ + const char* exe_path = ""; + const char* app_domain_name = "corewasmrun"; + const char* entry_assembly = "ManagedAssembly.dll"; + + coreclr_set_error_writer(log_error_info); + + printf("call coreclr_initialize\n"); + int retval = coreclr_initialize(exe_path, app_domain_name, 0, nullptr, nullptr, &CurrentClrInstance, &CurrentAppDomainId); + + if (retval < 0) + { + std::fprintf(stderr, "coreclr_initialize failed - Error: 0x%08x\n", retval); + return -1; + } + else + { + printf("coreclr_initialize succeeded - retval: 0x%08x\n", retval); + } + + // coreclr_execute_assembly(); + // coreclr_shutdown(); + + return retval; +} + +int main() +{ + int retval = run(); + + return retval; +} diff --git a/src/coreclr/hosts/corewasmrun/index.html b/src/coreclr/hosts/corewasmrun/index.html new file mode 100644 index 00000000000000..7fecf3afe85302 --- /dev/null +++ b/src/coreclr/hosts/corewasmrun/index.html @@ -0,0 +1,52 @@ + + + + + corewasmrun + + +

corewasmrun

+

+    
+    
+
diff --git a/src/coreclr/ilasm/assem.cpp b/src/coreclr/ilasm/assem.cpp
index 8daec130bcc76a..912ab2f3c9b2b3 100644
--- a/src/coreclr/ilasm/assem.cpp
+++ b/src/coreclr/ilasm/assem.cpp
@@ -1521,7 +1521,7 @@ unsigned hash(
      unsigned  length,   /* the length of the key */
      unsigned  initval)  /* the previous hash, or an arbitrary value */
 {
-   register unsigned a,b,c,len;
+   unsigned a,b,c,len;
 
    /* Set up the internal state */
    len = length;
diff --git a/src/coreclr/inc/CMakeLists.txt b/src/coreclr/inc/CMakeLists.txt
index 714bde62d01117..4edac3b4f1ed9c 100644
--- a/src/coreclr/inc/CMakeLists.txt
+++ b/src/coreclr/inc/CMakeLists.txt
@@ -5,7 +5,6 @@ set( CORGUIDS_IDL_SOURCES
   clrinternal.idl
   xclrdata.idl
   corprof.idl
-  corpub.idl
   corsym.idl
   sospriv.idl
 )
diff --git a/src/coreclr/inc/CrstTypes.def b/src/coreclr/inc/CrstTypes.def
index 3d240e40cb9533..8cd820022658cd 100644
--- a/src/coreclr/inc/CrstTypes.def
+++ b/src/coreclr/inc/CrstTypes.def
@@ -78,7 +78,7 @@ Crst AppDomainCache
 End
 
 Crst PinnedHeapHandleTable
-    AcquiredBefore AvailableParamTypes HandleTable IbcProfile SyncBlockCache SystemDomainDelayedUnloadList
+    AcquiredBefore AvailableParamTypes HandleTable SyncBlockCache SystemDomainDelayedUnloadList
                    SystemDomain
 End
 
@@ -91,7 +91,7 @@ Crst AvailableClass
 End
 
 Crst AvailableParamTypes
-    AcquiredBefore ModuleLookupTable IbcProfile LoaderHeap
+    AcquiredBefore ModuleLookupTable LoaderHeap
 End
 
 Crst CCompRC
@@ -103,7 +103,7 @@ Crst ClassFactInfoHash
 End
 
 Crst ClassInit
-    AcquiredBefore DeadlockDetection IbcProfile
+    AcquiredBefore DeadlockDetection
     SameLevelAs Jit
 End
 
@@ -176,14 +176,14 @@ Crst DbgTransport
 End
 
 Crst GenericDictionaryExpansion
-    AcquiredBefore PinnedHeapHandleTable IbcProfile LoaderHeap SystemDomainDelayedUnloadList UniqueStack
+    AcquiredBefore PinnedHeapHandleTable LoaderHeap SystemDomainDelayedUnloadList UniqueStack
 End
 
 Crst DynamicIL
 End
 
 Crst DynamicMT
-    AcquiredBefore IbcProfile CodeVersioning
+    AcquiredBefore CodeVersioning
 End
 
 Crst EventStore
@@ -209,7 +209,7 @@ Crst MethodTableExposedObject
 End
 
 Crst FuncPtrStubs
-    AcquiredBefore IbcProfile LoaderHeap UniqueStack CodeFragmentHeap JumpStubCache
+    AcquiredBefore LoaderHeap UniqueStack CodeFragmentHeap JumpStubCache
 End
 
 Crst FusionAppCtx
@@ -221,16 +221,13 @@ Crst GCCover
 End
 
 Crst GlobalStrLiteralMap
-    AcquiredBefore PinnedHeapHandleTable HandleTable IbcProfile SyncBlockCache SystemDomainDelayedUnloadList ThreadStore UniqueStack
+    AcquiredBefore PinnedHeapHandleTable HandleTable SyncBlockCache SystemDomainDelayedUnloadList ThreadStore UniqueStack
 End
 
 Crst HandleTable
     SameLevelAs HandleTable
 End
 
-Crst IbcProfile
-End
-
 Crst IJWFixupData
     AcquiredBefore FuncPtrStubs IJWHash LoaderHeap
 End
@@ -329,7 +326,7 @@ Crst PendingTypeLoadEntry
     AcquiredBefore AppDomainCache PinnedHeapHandleTable AssemblyLoader AvailableClass AvailableParamTypes
                    ClassInit DeadlockDetection DebuggerController DebuggerJitInfo DebuggerMutex
                    GenericDictionaryExpansion Exception FuncPtrStubs
-                   FusionAppCtx GlobalStrLiteralMap HandleTable IbcProfile
+                   FusionAppCtx GlobalStrLiteralMap HandleTable
                    IJWFixupData IJWHash ISymUnmanagedReader Jit JumpStubCache LoaderHeap
                    Module ModuleLookupTable PEImage
                    SigConvert SingleUseLock StubDispatchCache
@@ -352,7 +349,7 @@ Crst ProfilingAPIStatus
 End
 
 Crst RCWCache
-    AcquiredBefore IbcProfile LoaderHeap RCWCleanupList
+    AcquiredBefore LoaderHeap RCWCleanupList
 End
 
 Crst RCWCleanupList
@@ -415,7 +412,7 @@ Crst SyncHashLock
 End
 
 Crst SystemDomain
-    AcquiredBefore DebuggerMutex HandleTable IbcProfile
+    AcquiredBefore DebuggerMutex HandleTable
                    ThreadIdDispenser ThreadStore
 End
 
@@ -431,7 +428,7 @@ End
 
 Crst ThreadStore
     AcquiredBefore AvailableParamTypes DeadlockDetection DebuggerController
-                   DebuggerHeapLock DebuggerJitInfo DynamicIL HandleTable IbcProfile
+                   DebuggerHeapLock DebuggerJitInfo DynamicIL HandleTable
                    JumpStubCache LoaderHeap ModuleLookupTable ProfilerGCRefDataFreeList
                    SingleUseLock SyncBlockCache SystemDomainDelayedUnloadList ThreadIdDispenser DebuggerMutex
                    JitInlineTrackingMap
@@ -453,11 +450,11 @@ Crst UniqueStack
 End
 
 Crst UnresolvedClassLock
-    AcquiredBefore AvailableParamTypes IbcProfile JumpStubCache
+    AcquiredBefore AvailableParamTypes JumpStubCache
 End
 
 Crst WrapperTemplate
-    AcquiredBefore IbcProfile
+    AcquiredBefore ExecutableAllocatorLock
 End
 
 Crst UMEntryThunkCache
@@ -479,7 +476,6 @@ Crst MulticoreJitManager
 End
 
 Crst InlineTrackingMap
-    AcquiredBefore IbcProfile
 End
 
 Crst JitInlineTrackingMap
diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h
index 6f72d0a9094df3..882a88839a933e 100644
--- a/src/coreclr/inc/clrconfigvalues.h
+++ b/src/coreclr/inc/clrconfigvalues.h
@@ -453,7 +453,7 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadSuspendInjection, W("INTERNAL_ThreadSusp
 ///
 /// Thread (miscellaneous)
 ///
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_DefaultStackSize, W("DefaultStackSize"), 0, "Stack size to use for new VM threads when thread is created with default stack size (dwStackSize == 0).")
+RETAIL_CONFIG_DWORD_INFO(EXTERNAL_Thread_DefaultStackSize, W("Thread_DefaultStackSize"), 0, "Stack size to use for new VM threads when thread is created with default stack size (dwStackSize == 0).")
 RETAIL_CONFIG_DWORD_INFO(INTERNAL_Thread_DeadThreadCountThresholdForGCTrigger, W("Thread_DeadThreadCountThresholdForGCTrigger"), 75, "In the heuristics to clean up dead threads, this threshold must be reached before triggering a GC will be considered. Set to 0 to disable triggering a GC based on dead threads.")
 RETAIL_CONFIG_DWORD_INFO(INTERNAL_Thread_DeadThreadGCTriggerPeriodMilliseconds, W("Thread_DeadThreadGCTriggerPeriodMilliseconds"), 1000 * 60 * 30, "In the heuristics to clean up dead threads, this much time must have elapsed since the previous max-generation GC before triggering another GC will be considered")
 RETAIL_CONFIG_DWORD_INFO(EXTERNAL_Thread_UseAllCpuGroups, W("Thread_UseAllCpuGroups"), 0, "Specifies whether to query and use CPU group information for determining the processor count.")
@@ -708,6 +708,9 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableRiscV64Zba,             W("EnableRiscV64
 RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableRiscV64Zbb,             W("EnableRiscV64Zbb"),          1, "Allows RiscV64 Zbb hardware intrinsics to be disabled")
 #endif
 
+// Runtime-async
+RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_RuntimeAsync, W("RuntimeAsync"), 0, "Enables runtime async method support")
+
 ///
 /// Uncategorized
 ///
diff --git a/src/coreclr/inc/clrnt.h b/src/coreclr/inc/clrnt.h
index 8040117a28b8f6..f9b63c824e261e 100644
--- a/src/coreclr/inc/clrnt.h
+++ b/src/coreclr/inc/clrnt.h
@@ -510,7 +510,7 @@ RtlVirtualUnwind(
 #define UNW_FLAG_EHANDLER               0x1             /* filter handler */
 #define UNW_FLAG_UHANDLER               0x2             /* unwind handler */
 
-PEXCEPTION_ROUTINE
+inline PEXCEPTION_ROUTINE
 RtlVirtualUnwind (
     _In_ DWORD HandlerType,
     _In_ DWORD ImageBase,
@@ -520,7 +520,11 @@ RtlVirtualUnwind (
     _Out_ PVOID *HandlerData,
     _Out_ PDWORD EstablisherFrame,
     __inout_opt PT_KNONVOLATILE_CONTEXT_POINTERS ContextPointers
-    );
+    )
+{
+    PORTABILITY_ASSERT("The function RtlVirtualUnwind is not implemented on wasm");
+    return nullptr;
+}
 
 FORCEINLINE
 ULONG
@@ -529,7 +533,7 @@ RtlpGetFunctionEndAddress (
     _In_ TADDR ImageBase
     )
 {
-    _ASSERTE("The function RtlpGetFunctionEndAddress is not implemented on wasm");
+    PORTABILITY_ASSERT("The function RtlpGetFunctionEndAddress is not implemented on wasm");
     return 0;
 }
 
diff --git a/src/coreclr/inc/clrtypes.h b/src/coreclr/inc/clrtypes.h
index b1990054c48738..408cdf540c2939 100644
--- a/src/coreclr/inc/clrtypes.h
+++ b/src/coreclr/inc/clrtypes.h
@@ -370,6 +370,15 @@ inline UINT64 AlignDown(UINT64 value, UINT alignment)
     return (value&~(UINT64)(alignment-1));
 }
 
+#ifdef __wasm__
+inline uintptr_t AlignDown(uintptr_t value, UINT alignment)
+{
+    STATIC_CONTRACT_LEAF;
+    STATIC_CONTRACT_SUPPORTS_DAC;
+    return (value&~(uintptr_t)(alignment-1));
+}
+#endif
+
 #ifdef __APPLE__
 inline SIZE_T AlignDown(SIZE_T value, UINT alignment)
 {
diff --git a/src/coreclr/inc/contract.inl b/src/coreclr/inc/contract.inl
index 1bf58ab5772a34..5f53bd27f14ae2 100644
--- a/src/coreclr/inc/contract.inl
+++ b/src/coreclr/inc/contract.inl
@@ -585,7 +585,7 @@ void CONTRACT_ASSERT(const char *szElaboration,
             }
             else
             {
-                strcat_s(Buf,ARRAY_SIZE(Buf), "We can't find the violated contract. Look for an old-style non-holder-based contract.\n");
+                strcat_s(Buf,ARRAY_SIZE(Buf), "Missing tracking information. Look for data structures that manipulate contract state (i.e., CrstHolder).\n");
             }
         }
 
diff --git a/src/coreclr/inc/corhdr.h b/src/coreclr/inc/corhdr.h
index 0bd7755e3b0d5e..01a2d602b2befd 100644
--- a/src/coreclr/inc/corhdr.h
+++ b/src/coreclr/inc/corhdr.h
@@ -975,7 +975,8 @@ typedef enum CorCallingConvention
     IMAGE_CEE_CS_CALLCONV_UNMANAGED     = 0x9,  // Unmanaged calling convention encoded as modopts
     IMAGE_CEE_CS_CALLCONV_GENERICINST   = 0xa,  // generic method instantiation
     IMAGE_CEE_CS_CALLCONV_NATIVEVARARG  = 0xb,  // used ONLY for 64bit vararg PInvoke calls
-    IMAGE_CEE_CS_CALLCONV_MAX           = 0xc,  // first invalid calling convention
+    IMAGE_CEE_CS_CALLCONV_ASYNC         = 0xc,  // used for calli in IL stubs
+    IMAGE_CEE_CS_CALLCONV_MAX           = 0xd,  // first invalid calling convention
 
 
         // The high bits of the calling convention convey additional info
diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h
index 6182619dbbf77e..b0d0108a31dffe 100644
--- a/src/coreclr/inc/corinfo.h
+++ b/src/coreclr/inc/corinfo.h
@@ -1712,6 +1712,15 @@ enum CorInfoContinuationFlags
     // OSR method saved in the beginning of 'Data', or -1 if the continuation
     // belongs to a tier 0 method.
     CORINFO_CONTINUATION_OSR_IL_OFFSET_IN_DATA = 4,
+    // If this bit is set the continuation should continue on the thread
+    // pool.
+    CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL = 8,
+    // If this bit is set the continuation has a SynchronizationContext
+    // that we should continue on.
+    CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT = 16,
+    // If this bit is set the continuation has a TaskScheduler
+    // that we should continue on.
+    CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER = 32,
 };
 
 struct CORINFO_ASYNC_INFO
@@ -1737,6 +1746,9 @@ struct CORINFO_ASYNC_INFO
     CORINFO_METHOD_HANDLE captureExecutionContextMethHnd;
     // Method handle for AsyncHelpers.RestoreExecutionContext
     CORINFO_METHOD_HANDLE restoreExecutionContextMethHnd;
+    CORINFO_METHOD_HANDLE captureContinuationContextMethHnd;
+    CORINFO_METHOD_HANDLE captureContextsMethHnd;
+    CORINFO_METHOD_HANDLE restoreContextsMethHnd;
 };
 
 // Flags passed from JIT to runtime.
@@ -3129,12 +3141,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(
@@ -3200,12 +3206,6 @@ class ICorDynamicInfo : public ICorStaticInfo
             void**              ppIndirection = NULL
             ) = 0;
 
-    // returns true if a VM cookie can be generated for it (might be false due to cross-module
-    // inlining, in which case the inlining should be aborted)
-    virtual bool canGetCookieForPInvokeCalliSig(
-            CORINFO_SIG_INFO*   szMetaSig
-            ) = 0;
-
     // Generate a cookie based on the signature to pass to INTOP_CALLI in the interpreter.
     virtual void* GetCookieForInterpreterCalliSig(
             CORINFO_SIG_INFO*   szMetaSig) = 0;
@@ -3291,15 +3291,10 @@ class ICorDynamicInfo : public ICorStaticInfo
     // registers a vararg sig & returns a VM cookie for it (which can contain other stuff)
     virtual CORINFO_VARARGS_HANDLE getVarArgsHandle(
             CORINFO_SIG_INFO       *pSig,
+            CORINFO_METHOD_HANDLE   methHnd,
             void                  **ppIndirection = NULL
             ) = 0;
 
-    // returns true if a VM cookie can be generated for it (might be false due to cross-module
-    // inlining, in which case the inlining should be aborted)
-    virtual bool canGetVarArgsHandle(
-            CORINFO_SIG_INFO       *pSig
-            ) = 0;
-
     // Allocate a string literal on the heap and return a handle to it
     virtual InfoAccessType constructStringLiteral(
             CORINFO_MODULE_HANDLE   module,
diff --git a/src/coreclr/inc/corpub.idl b/src/coreclr/inc/corpub.idl
deleted file mode 100644
index 16d3e6359a60db..00000000000000
--- a/src/coreclr/inc/corpub.idl
+++ /dev/null
@@ -1,264 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-/* -------------------------------------------------------------------------- *
- * Common Language Runtime Process Publishing Interfaces
- * -------------------------------------------------------------------------- */
-
-cpp_quote("#if 0")
-#ifndef DO_NO_IMPORTS
-import "unknwn.idl";
-#endif
-cpp_quote("#endif")
-
-typedef enum
-{
-    COR_PUB_MANAGEDONLY                 = 0x00000001    // Must always be set,
-                                                        // only enumerates
-                                                        // managed processes
-} COR_PUB_ENUMPROCESS;
-
-
-/* -------------------------------------------------------------------------- *
- * Forward declarations
- * -------------------------------------------------------------------------- */
-#pragma warning(push)
-#pragma warning(disable:28718)    //Unable to annotate as this is not a local interface
-
-interface ICorPublish;
-interface ICorPublishProcess;
-interface ICorPublishAppDomain;
-interface ICorPublishProcessEnum;
-interface ICorPublishAppDomainEnum;
-
-#pragma warning(pop)
-
-/* ------------------------------------------------------------------------- *
- * Library definition
- * ------------------------------------------------------------------------- */
-
-[
-  uuid(e97ca460-657d-11d3-8d5b-00104b35e7ef),
-  version(1.0),
-  helpstring("Common Language Runtime Process Publishing Library")
-]
-library CorpubProcessLib
-{
-    importlib("STDOLE2.TLB");
-
-    // CorPublish is a shared component across all version of the runtime.
-    [
-        uuid(047a9a40-657e-11d3-8d5b-00104b35e7ef)
-    ]
-    coclass CorpubPublish
-    {
-        [default] interface ICorPublish;
-        interface            ICorPublishProcess;
-        interface            ICorPublishAppDomain;
-        interface            ICorPublishProcessEnum;
-        interface            ICorPublishAppDomainEnum;
-    };
-};
-
-
-/* -------------------------------------------------------------------------- *
- * Interface definitions
- * -------------------------------------------------------------------------- */
-
-/*
- * This interface is the top level interface for publishing of processes.
- */
-[
-    object,
-    uuid(9613A0E7-5A68-11d3-8F84-00A0C9B4D50C),
-    pointer_default(unique),
-    local
-]
-interface ICorPublish : IUnknown
-{
-    /*
-     * Retrieves a list of managed processes on this machine which
-     * the current user has permission to debug.  In this version,
-     * Type must always be equal to COR_PUB_MANAGEDONLY.
-     * The list is based on a snapshot of the processes running when
-     * the enum method is called.  The enumerator will not reflect any
-     * processes that start before or terminate after EnumProcesses is called.
-     * If EnumProcesses is called more than once on this ICorPublish
-     * instance, a new up-to-date enumeration will be returned without
-     * affecting any previous ones.
-     */
-    HRESULT EnumProcesses([in] COR_PUB_ENUMPROCESS Type,
-                          [out] ICorPublishProcessEnum **ppIEnum);
-
-    /*
-     * Gets a new ICorPublishProcess object for the managed process
-     * with the given process ID.  Returns failure if the process doesn't
-     * exist, or isn't a managed process that can be debugged by the current
-     * user.
-     */
-    HRESULT GetProcess([in] unsigned pid,
-                       [out] ICorPublishProcess **ppProcess);
-}
-
-/*
- * An abstract enumerator.
- */
-[
-    object,
-    uuid(C0B22967-5A69-11d3-8F84-00A0C9B4D50C),
-    pointer_default(unique),
-    local
-]
-interface ICorPublishEnum : IUnknown
-{
-    /*
-     * Moves the current position forward the given number of
-     * elements.
-     */
-    HRESULT Skip([in] ULONG celt);
-
-    /*
-     * Sets the position of the enumerator to the beginning of the
-     * enumeration.
-     */
-    HRESULT Reset();
-
-    /*
-     * Creates another enumerator with the same current position
-     * as this one.
-     */
-    HRESULT Clone([out] ICorPublishEnum **ppEnum);
-
-    /*
-     * Gets the number of elements in the enumeration
-     */
-    HRESULT GetCount([out] ULONG *pcelt);
-};
-
-#pragma warning(push)
-#pragma warning(disable:28718)
-/*
- * Describes a process on a machine.
- */
-[
-    object,
-    uuid(18D87AF1-5A6A-11d3-8F84-00A0C9B4D50C),
-    pointer_default(unique),
-    local
-]
-interface ICorPublishProcess : IUnknown
-{
-    /*
-     * Returns true if the process is known to have managed code
-     * running in it.  Since this version of ICorPublish only provides access
-     * to managed processes, this method always returns true.
-     */
-    HRESULT IsManaged([out] BOOL *pbManaged);
-
-    /*
-     * Enumerates the list of known application domains in this process.
-     * This list is based on a snapshot of the existing AppDomains when
-     * this method is called.  This method may be called more than
-     * once to create a new up-to-date list.  Existing enumerations will not
-     * be affected by calls to this method.  If the process has been
-     * terminated, this will fail with CORDBG_E_PROCESS_TERMINATED.
-     */
-    HRESULT EnumAppDomains([out] ICorPublishAppDomainEnum **ppEnum);
-
-    /*
-     * Returns the OS ID for this process.
-     */
-    HRESULT GetProcessID([out] unsigned *pid);
-
-    /*
-     * Get the full path of the executable for this process.
-     * If szName is non-null, this copies up to cchName characters (including
-     * the null terminator) into szName, and ensures it is null-terminated.
-     * If pcchName is non-null, the actual number of characters in the name
-     * (including the null terminator) is stored there.  This method returns
-     * S_OK regardless of how many characters were copied.
-     */
-    HRESULT GetDisplayName([in] ULONG32 cchName,
-                           [out] ULONG32 *pcchName,
-                           [out, size_is(cchName),
-                           length_is(*pcchName)] WCHAR *szName);
-}
-#pragma warning(pop)
-
-#pragma warning(push)
-#pragma warning(disable:28718)
-/*
- * Provide information on an Application Domain object.
- */
-[
-    object,
-    uuid(D6315C8F-5A6A-11d3-8F84-00A0C9B4D50C),
-    pointer_default(unique),
-    local
-]
-interface ICorPublishAppDomain : IUnknown
-{
-    /*
-     * Gets the identification number of this application domain.
-     * Note that this number is unique to this AppDomain, but only
-     * within the containing process.
-     */
-    HRESULT GetID([out] ULONG32 *puId);
-
-    /*
-     * Get the name for an application domain.
-     * If szName is non-null, this copies up to cchName characters (including
-     * the null terminator) into szName, and ensures it is null-terminated.
-     * If pcchName is non-null, the actual number of characters in the name
-     * (including the null terminator) is stored there.  This method returns
-     * S_OK regardless of how many characters were copied.
-     */
-    HRESULT GetName([in] ULONG32 cchName,
-                    [out] ULONG32 *pcchName,
-                    [out, size_is(cchName),
-                    length_is(*pcchName)] WCHAR *szName);
-}
-#pragma warning(pop)
-
-
-/*
- * Enumerate a list of processes based on the filter criteria given
- * when the enumerator object was created.
- */
-[
-    object,
-    uuid(A37FBD41-5A69-11d3-8F84-00A0C9B4D50C),
-    pointer_default(unique),
-    local
-]
-interface ICorPublishProcessEnum : ICorPublishEnum
-{
-    /*
-     * Gets the next "celt" processes in the enumeration.
-     */
-    HRESULT Next([in] ULONG celt,
-                 [out, size_is(celt),
-                  length_is(*pceltFetched)] ICorPublishProcess **objects,
-                 [out] ULONG *pceltFetched);
-}
-
-/*
- * Enumerate a list of app domains based in a process.
- */
-[
-    object,
-    uuid(9F0C98F5-5A6A-11d3-8F84-00A0C9B4D50C),
-    pointer_default(unique),
-    local
-]
-interface ICorPublishAppDomainEnum : ICorPublishEnum
-{
-    /*
-     * Gets the next "celt" application domains in the enumeration.
-     */
-    HRESULT Next([in] ULONG celt,
-                 [out, size_is(celt),
-                  length_is(*pceltFetched)] ICorPublishAppDomain **objects,
-                 [out] ULONG *pceltFetched);
-}
-
diff --git a/src/coreclr/inc/crsttypes_generated.h b/src/coreclr/inc/crsttypes_generated.h
index 55f445271a7f0a..713f6bd5b33f33 100644
--- a/src/coreclr/inc/crsttypes_generated.h
+++ b/src/coreclr/inc/crsttypes_generated.h
@@ -54,72 +54,71 @@ enum CrstType
     CrstGenericDictionaryExpansion = 36,
     CrstGlobalStrLiteralMap = 37,
     CrstHandleTable = 38,
-    CrstIbcProfile = 39,
-    CrstIJWFixupData = 40,
-    CrstIJWHash = 41,
-    CrstILStubGen = 42,
-    CrstInlineTrackingMap = 43,
-    CrstInstMethodHashTable = 44,
-    CrstInterfaceDispatchGlobalLists = 45,
-    CrstInterop = 46,
-    CrstInteropData = 47,
-    CrstIsJMCMethod = 48,
-    CrstISymUnmanagedReader = 49,
-    CrstJit = 50,
-    CrstJitInlineTrackingMap = 51,
-    CrstJitPatchpoint = 52,
-    CrstJumpStubCache = 53,
-    CrstLeafLock = 54,
-    CrstListLock = 55,
-    CrstLoaderAllocator = 56,
-    CrstLoaderAllocatorReferences = 57,
-    CrstLoaderHeap = 58,
-    CrstManagedObjectWrapperMap = 59,
-    CrstMethodDescBackpatchInfoTracker = 60,
-    CrstMethodTableExposedObject = 61,
-    CrstModule = 62,
-    CrstModuleLookupTable = 63,
-    CrstMulticoreJitHash = 64,
-    CrstMulticoreJitManager = 65,
-    CrstNativeImageEagerFixups = 66,
-    CrstNativeImageLoad = 67,
-    CrstNotifyGdb = 68,
-    CrstPEImage = 69,
-    CrstPendingTypeLoadEntry = 70,
-    CrstPerfMap = 71,
-    CrstPgoData = 72,
-    CrstPinnedByrefValidation = 73,
-    CrstPinnedHeapHandleTable = 74,
-    CrstProfilerGCRefDataFreeList = 75,
-    CrstProfilingAPIStatus = 76,
-    CrstRCWCache = 77,
-    CrstRCWCleanupList = 78,
-    CrstReadyToRunEntryPointToMethodDescMap = 79,
-    CrstReflection = 80,
-    CrstReJITGlobalRequest = 81,
-    CrstSigConvert = 82,
-    CrstSingleUseLock = 83,
-    CrstStressLog = 84,
-    CrstStubCache = 85,
-    CrstStubDispatchCache = 86,
-    CrstSyncBlockCache = 87,
-    CrstSyncHashLock = 88,
-    CrstSystemDomain = 89,
-    CrstSystemDomainDelayedUnloadList = 90,
-    CrstThreadIdDispenser = 91,
-    CrstThreadLocalStorageLock = 92,
-    CrstThreadStore = 93,
-    CrstTieredCompilation = 94,
-    CrstTypeEquivalenceMap = 95,
-    CrstTypeIDMap = 96,
-    CrstUMEntryThunkCache = 97,
-    CrstUMEntryThunkFreeListLock = 98,
-    CrstUniqueStack = 99,
-    CrstUnresolvedClassLock = 100,
-    CrstUnwindInfoTableLock = 101,
-    CrstVSDIndirectionCellLock = 102,
-    CrstWrapperTemplate = 103,
-    kNumberOfCrstTypes = 104
+    CrstIJWFixupData = 39,
+    CrstIJWHash = 40,
+    CrstILStubGen = 41,
+    CrstInlineTrackingMap = 42,
+    CrstInstMethodHashTable = 43,
+    CrstInterfaceDispatchGlobalLists = 44,
+    CrstInterop = 45,
+    CrstInteropData = 46,
+    CrstIsJMCMethod = 47,
+    CrstISymUnmanagedReader = 48,
+    CrstJit = 49,
+    CrstJitInlineTrackingMap = 50,
+    CrstJitPatchpoint = 51,
+    CrstJumpStubCache = 52,
+    CrstLeafLock = 53,
+    CrstListLock = 54,
+    CrstLoaderAllocator = 55,
+    CrstLoaderAllocatorReferences = 56,
+    CrstLoaderHeap = 57,
+    CrstManagedObjectWrapperMap = 58,
+    CrstMethodDescBackpatchInfoTracker = 59,
+    CrstMethodTableExposedObject = 60,
+    CrstModule = 61,
+    CrstModuleLookupTable = 62,
+    CrstMulticoreJitHash = 63,
+    CrstMulticoreJitManager = 64,
+    CrstNativeImageEagerFixups = 65,
+    CrstNativeImageLoad = 66,
+    CrstNotifyGdb = 67,
+    CrstPEImage = 68,
+    CrstPendingTypeLoadEntry = 69,
+    CrstPerfMap = 70,
+    CrstPgoData = 71,
+    CrstPinnedByrefValidation = 72,
+    CrstPinnedHeapHandleTable = 73,
+    CrstProfilerGCRefDataFreeList = 74,
+    CrstProfilingAPIStatus = 75,
+    CrstRCWCache = 76,
+    CrstRCWCleanupList = 77,
+    CrstReadyToRunEntryPointToMethodDescMap = 78,
+    CrstReflection = 79,
+    CrstReJITGlobalRequest = 80,
+    CrstSigConvert = 81,
+    CrstSingleUseLock = 82,
+    CrstStressLog = 83,
+    CrstStubCache = 84,
+    CrstStubDispatchCache = 85,
+    CrstSyncBlockCache = 86,
+    CrstSyncHashLock = 87,
+    CrstSystemDomain = 88,
+    CrstSystemDomainDelayedUnloadList = 89,
+    CrstThreadIdDispenser = 90,
+    CrstThreadLocalStorageLock = 91,
+    CrstThreadStore = 92,
+    CrstTieredCompilation = 93,
+    CrstTypeEquivalenceMap = 94,
+    CrstTypeIDMap = 95,
+    CrstUMEntryThunkCache = 96,
+    CrstUMEntryThunkFreeListLock = 97,
+    CrstUniqueStack = 98,
+    CrstUnresolvedClassLock = 99,
+    CrstUnwindInfoTableLock = 100,
+    CrstVSDIndirectionCellLock = 101,
+    CrstWrapperTemplate = 102,
+    kNumberOfCrstTypes = 103
 };
 
 #endif // __CRST_TYPES_INCLUDED
@@ -169,11 +168,10 @@ int g_rgCrstLevelMap[] =
     17,         // CrstGenericDictionaryExpansion
     16,         // CrstGlobalStrLiteralMap
     1,          // CrstHandleTable
-    0,          // CrstIbcProfile
     7,          // CrstIJWFixupData
     0,          // CrstIJWHash
     6,          // CrstILStubGen
-    2,          // CrstInlineTrackingMap
+    0,          // CrstInlineTrackingMap
     18,         // CrstInstMethodHashTable
     0,          // CrstInterfaceDispatchGlobalLists
     21,         // CrstInterop
@@ -278,7 +276,6 @@ LPCSTR g_rgCrstNameMap[] =
     "CrstGenericDictionaryExpansion",
     "CrstGlobalStrLiteralMap",
     "CrstHandleTable",
-    "CrstIbcProfile",
     "CrstIJWFixupData",
     "CrstIJWHash",
     "CrstILStubGen",
diff --git a/src/coreclr/inc/daccess.h b/src/coreclr/inc/daccess.h
index e58ee7810f3997..a26146c05a88d3 100644
--- a/src/coreclr/inc/daccess.h
+++ b/src/coreclr/inc/daccess.h
@@ -290,9 +290,9 @@
 //
 //     SystemDomain::m_appDomainIndexList;
 //
-//     extern DWORD gThreadTLSIndex;
+//     extern DWORD g_TlsIndex;
 //
-//     DWORD gThreadTLSIndex = TLS_OUT_OF_INDEXES;
+//     DWORD g_TlsIndex = TLS_OUT_OF_INDEXES;
 //
 // Modified Code:
 //
@@ -312,9 +312,9 @@
 //
 //     SVAL_IMPL(ArrayListStatic, SystemDomain, m_appDomainIndexList);
 //
-//     GVAL_DECL(DWORD, gThreadTLSIndex);
+//     GVAL_DECL(DWORD, g_TlsIndex);
 //
-//     GVAL_IMPL_INIT(DWORD, gThreadTLSIndex, TLS_OUT_OF_INDEXES);
+//     GVAL_IMPL_INIT(DWORD, g_TlsIndex, TLS_OUT_OF_INDEXES);
 //
 // When declaring the variable, the first argument declares the
 // variable's type and the second argument declares the variable's
diff --git a/src/coreclr/inc/dacvars.h b/src/coreclr/inc/dacvars.h
index 60b9f11dfbddf4..31a618b33d0369 100644
--- a/src/coreclr/inc/dacvars.h
+++ b/src/coreclr/inc/dacvars.h
@@ -115,6 +115,7 @@ DEFINE_DACVAR(PTR_SystemDomain, SystemDomain__m_pSystemDomain, SystemDomain::m_p
 DEFINE_DACVAR(DWORD, dac__g_debuggerWordTLSIndex, g_debuggerWordTLSIndex)
 #endif
 DEFINE_DACVAR(DWORD, dac__g_TlsIndex, g_TlsIndex)
+DEFINE_DACVAR(DWORD, dac__g_offsetOfCurrentThreadInfo, g_offsetOfCurrentThreadInfo)
 
 #ifdef FEATURE_EH_FUNCLETS
 DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pEHClass, ::g_pEHClass)
@@ -194,10 +195,6 @@ DEFINE_DACVAR(BOOL, Debugger__s_fCanChangeNgenFlags, Debugger::s_fCanChangeNgenF
 DEFINE_DACVAR(PTR_DebuggerPatchTable, DebuggerController__g_patches, DebuggerController::g_patches)
 DEFINE_DACVAR(BOOL, DebuggerController__g_patchTableValid, DebuggerController::g_patchTableValid)
 
-DEFINE_DACVAR(SIZE_T, dac__gLowestFCall, ::gLowestFCall)
-DEFINE_DACVAR(SIZE_T, dac__gHighestFCall, ::gHighestFCall)
-DEFINE_DACVAR(SIZE_T, dac__gFCallMethods, ::gFCallMethods)
-
 DEFINE_DACVAR(PTR_SyncTableEntry, dac__g_pSyncTable, ::g_pSyncTable)
 #ifdef FEATURE_COMINTEROP
 DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pRCWCleanupList, ::g_pRCWCleanupList)
@@ -236,5 +233,7 @@ DEFINE_DACVAR(bool, dac__g_metadataUpdatesApplied, ::g_metadataUpdatesApplied)
 
 DEFINE_DACVAR(PTR_WSTR, dac__g_EntryAssemblyPath, ::g_EntryAssemblyPath)
 
+DEFINE_DACVAR(CDacPlatformMetadata, dac__g_cdacPlatformMetadata, ::g_cdacPlatformMetadata)
+
 #undef DEFINE_DACVAR
 #undef DEFINE_DACVAR_NO_DUMP
diff --git a/src/coreclr/inc/eetwain.h b/src/coreclr/inc/eetwain.h
index 78dd453f55b2a2..1062ebf5692409 100644
--- a/src/coreclr/inc/eetwain.h
+++ b/src/coreclr/inc/eetwain.h
@@ -191,6 +191,8 @@ virtual bool UnwindStackFrame(PREGDISPLAY     pRD,
                               EECodeInfo     *pCodeInfo,
                               unsigned        flags) = 0;
 
+virtual void UnwindStackFrame(T_CONTEXT *pContext) = 0;
+
 #ifdef FEATURE_EH_FUNCLETS
 virtual void EnsureCallerContextIsValid(PREGDISPLAY pRD, EECodeInfo * pCodeInfo = NULL, unsigned flags = 0) = 0;
 #endif // FEATURE_EH_FUNCLETS
@@ -405,6 +407,9 @@ bool UnwindStackFrame(
                 EECodeInfo     *pCodeInfo,
                 unsigned        flags);
 
+virtual
+void UnwindStackFrame(T_CONTEXT *pContext);
+
 #ifdef HAS_LIGHTUNWIND
 enum LightUnwindFlag
 {
@@ -654,6 +659,9 @@ bool UnwindStackFrame(
                 EECodeInfo     *pCodeInfo,
                 unsigned        flags);
 
+virtual
+void UnwindStackFrame(T_CONTEXT *pContext);
+
 #ifdef FEATURE_EH_FUNCLETS
 virtual 
 void EnsureCallerContextIsValid(PREGDISPLAY pRD, EECodeInfo * pCodeInfo = NULL, unsigned flags = 0);
diff --git a/src/coreclr/inc/executableallocator.h b/src/coreclr/inc/executableallocator.h
index 973b950ad369bc..93c4758956f579 100644
--- a/src/coreclr/inc/executableallocator.h
+++ b/src/coreclr/inc/executableallocator.h
@@ -267,7 +267,7 @@ class ExecutableAllocator
     void UnmapRW(void* pRW);
 
     // Allocate thunks from a template. pTemplate is the return value from CreateTemplate
-    void* AllocateThunksFromTemplate(void *pTemplate, size_t templateSize);
+    void* AllocateThunksFromTemplate(void *pTemplate, size_t templateSize, void (*dataPageGenerator)(uint8_t* pageBase, size_t size));
 
     // Free a set of thunks allocated from templates. pThunks must have been returned from AllocateThunksFromTemplate
     void FreeThunksFromTemplate(void *pThunks, size_t templateSize);
diff --git a/src/coreclr/inc/gcmsg.inl b/src/coreclr/inc/gcmsg.inl
index d2461a3cdbf03c..d1da723b0987be 100644
--- a/src/coreclr/inc/gcmsg.inl
+++ b/src/coreclr/inc/gcmsg.inl
@@ -41,12 +41,33 @@
         return "%d gc thread waiting... Done";
     }
 
-    static const char* gcDetailedStartMsg()
+#define GC_DETAILED_START_PREFIX "*GC* %d(gen0:%d)(%d)"
+#define GC_DETAILED_START_STRESSLOG "(alloced for %.3fms, g0 %zd (b: %zd, %zd/h) (%.3fmb/ms), g3 %zd (%.3fmb/ms), g4 %zd (%.3fmb/ms))(%s)(%d)(%d)"
+#define GC_DETAILED_START_DPRINTF_EXTRA "(heap size: %.3fmb max: %.3fmb)"
+
+    static const char* gcDetailedStartPrefix()
+    {
+        STATIC_CONTRACT_LEAF;
+        return GC_DETAILED_START_PREFIX;
+    }
+
+    static const char* gcDetailedStartMsg(bool compatibleWithStressLog)
     {
         STATIC_CONTRACT_LEAF;
-        return "*GC* %d(gen0:%d)(%d)(alloced for %.3fms, g0 %zd (b: %zd, %zd/h) (%.3fmb/ms), g3 %zd (%.3fmb/ms), g4 %zd (%.3fmb/ms))(%s)(%d)(%d)(heap size: %.3fmb max: %.3fmb)";
+        if (compatibleWithStressLog)
+        {
+            return GC_DETAILED_START_PREFIX GC_DETAILED_START_STRESSLOG;
+        }
+        else
+        {
+            return GC_DETAILED_START_PREFIX GC_DETAILED_START_STRESSLOG GC_DETAILED_START_DPRINTF_EXTRA;
+        }
     }
 
+#undef GC_DETAILED_START_PREFIX
+#undef GC_DETAILED_START_STRESSLOG
+#undef GC_DETAILED_START_DPRINTF_EXTRA
+
     static const char* gcDetailedEndMsg()
     {
         STATIC_CONTRACT_LEAF;
diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h
index ee74e9c984fa98..6f4908d9c05235 100644
--- a/src/coreclr/inc/icorjitinfoimpl_generated.h
+++ b/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;
 
@@ -594,9 +590,6 @@ void* GetCookieForPInvokeCalliSig(
 void* GetCookieForInterpreterCalliSig(
           CORINFO_SIG_INFO* szMetaSig) override;
 
-bool canGetCookieForPInvokeCalliSig(
-          CORINFO_SIG_INFO* szMetaSig) override;
-
 CORINFO_JUST_MY_CODE_HANDLE getJustMyCodeHandle(
           CORINFO_METHOD_HANDLE method,
           CORINFO_JUST_MY_CODE_HANDLE** ppIndirection) override;
@@ -632,11 +625,9 @@ CORINFO_CLASS_HANDLE getStaticFieldCurrentClass(
 
 CORINFO_VARARGS_HANDLE getVarArgsHandle(
           CORINFO_SIG_INFO* pSig,
+          CORINFO_METHOD_HANDLE methHnd,
           void** ppIndirection) override;
 
-bool canGetVarArgsHandle(
-          CORINFO_SIG_INFO* pSig) override;
-
 InfoAccessType constructStringLiteral(
           CORINFO_MODULE_HANDLE module,
           mdToken metaTok,
diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h
index 43c4c32332df8d..203f13bb671239 100644
--- a/src/coreclr/inc/jiteeversionguid.h
+++ b/src/coreclr/inc/jiteeversionguid.h
@@ -37,11 +37,11 @@
 
 #include 
 
-constexpr GUID JITEEVersionIdentifier = { /* 5c7eb9f1-a9cb-4a35-aea6-ae93d1f54c56 */
-    0x5c7eb9f1,
-    0xa9cb,
-    0x4a35,
-    {0xae, 0xa6, 0xae, 0x93, 0xd1, 0xf5, 0x4c, 0x56}
+constexpr GUID JITEEVersionIdentifier = { /* 7a8cbc56-9e19-4321-80b9-a0d2c578c945 */
+    0x7a8cbc56,
+    0x9e19,
+    0x4321,
+    {0x80, 0xb9, 0xa0, 0xd2, 0xc5, 0x78, 0xc9, 0x45}
   };
 
 #endif // JIT_EE_VERSIONING_GUID_H
diff --git a/src/coreclr/inc/loaderheap.h b/src/coreclr/inc/loaderheap.h
index d3040e0b4aa448..79228c7eb5410d 100644
--- a/src/coreclr/inc/loaderheap.h
+++ b/src/coreclr/inc/loaderheap.h
@@ -158,7 +158,7 @@ struct LoaderHeapEvent;
 // When an interleaved LoaderHeap is constructed, this is the interleaving size
 inline UINT32 GetStubCodePageSize()
 {
-#if defined(TARGET_ARM64) && defined(TARGET_UNIX)
+#if (defined(TARGET_ARM64) && defined(TARGET_UNIX)) || defined(TARGET_WASM)
     return max(16*1024u, GetOsPageSize());
 #elif defined(TARGET_ARM)
     return 4096; // ARM is special as the 32bit instruction set does not easily permit a 16KB offset
@@ -460,12 +460,13 @@ struct InterleavedLoaderHeapConfig
     uint32_t StubSize;
     void* Template;
     void (*CodePageGenerator)(uint8_t* pageBase, uint8_t* pageBaseRX, size_t size);
+    void (*DataPageGenerator)(uint8_t* pageBase, size_t size);
 };
 
-void InitializeLoaderHeapConfig(InterleavedLoaderHeapConfig *pConfig, size_t stubSize, void* templateInImage, void (*codePageGenerator)(uint8_t* pageBase, uint8_t* pageBaseRX, size_t size));
+void InitializeLoaderHeapConfig(InterleavedLoaderHeapConfig *pConfig, size_t stubSize, void* templateInImage, void (*codePageGenerator)(uint8_t* pageBase, uint8_t* pageBaseRX, size_t size), void (*dataPageGenerator)(uint8_t* pageBase, size_t size));
 
 //===============================================================================
-// This is the base class for InterleavedLoaderHeap It's used as a simple
+// This is the base class for InterleavedLoaderHeap. It's used as a simple
 // allocator for stubs in a scheme where each stub is a small fixed size, and is paired
 // with memory which is GetStubCodePageSize() bytes away. In addition there is an
 // ability to free is via a "backout" mechanism that is not considered to have good performance.
@@ -573,7 +574,7 @@ class UnlockedInterleavedLoaderHeap : public UnlockedLoaderHeapBase
                                  );
 
 protected:
-    // This frees memory allocated by UnlockAllocMem. It's given this horrible name to emphasize
+    // This frees memory allocated by UnlockedAllocStub. It's given this horrible name to emphasize
     // that it's purpose is for error path leak prevention purposes. You shouldn't
     // use LoaderHeap's as general-purpose alloc-free heaps.
     void UnlockedBackoutStub(void *pMem
@@ -701,8 +702,7 @@ inline CRITSEC_COOKIE CreateLoaderHeapLock()
 }
 
 //===============================================================================
-// The LoaderHeap is the black-box heap and has a Backout() method but none
-// of the advanced features that let you control address ranges.
+// Thread-safe variant of UnlockedLoaderHeap.
 //===============================================================================
 typedef DPTR(class LoaderHeap) PTR_LoaderHeap;
 class LoaderHeap : public UnlockedLoaderHeap
@@ -971,7 +971,7 @@ class LoaderHeap : public UnlockedLoaderHeap
 
 
 public:
-    // This frees memory allocated by AllocMem. It's given this horrible name to emphasize
+    // This frees memory allocated by RealAllocMem. It's given this horrible name to emphasize
     // that it's purpose is for error path leak prevention purposes. You shouldn't
     // use LoaderHeap's as general-purpose alloc-free heaps.
     void RealBackoutMem(void *pMem
@@ -1032,8 +1032,7 @@ class LoaderHeap : public UnlockedLoaderHeap
 #endif
 
 //===============================================================================
-// The LoaderHeap is the black-box heap and has a Backout() method but none
-// of the advanced features that let you control address ranges.
+// Thread-safe variant of UnlockedInterleavedLoaderHeap.
 //===============================================================================
 typedef DPTR(class InterleavedLoaderHeap) PTR_InterleavedLoaderHeap;
 class InterleavedLoaderHeap : public UnlockedInterleavedLoaderHeap
@@ -1106,7 +1105,7 @@ class InterleavedLoaderHeap : public UnlockedInterleavedLoaderHeap
 
 
 public:
-    // This frees memory allocated by AllocMem. It's given this horrible name to emphasize
+    // This frees memory allocated by RealAllocStub. It's given this horrible name to emphasize
     // that it's purpose is for error path leak prevention purposes. You shouldn't
     // use LoaderHeap's as general-purpose alloc-free heaps.
     void RealBackoutMem(void *pMem
diff --git a/src/coreclr/inc/nibblestream.h b/src/coreclr/inc/nibblestream.h
index aa4212cba43417..512b79a514b891 100644
--- a/src/coreclr/inc/nibblestream.h
+++ b/src/coreclr/inc/nibblestream.h
@@ -58,7 +58,10 @@ class NibbleWriter
     void Flush()
     {
         if (m_fPending)
+        {
             m_SigBuilder.AppendByte(m_PendingNibble);
+            m_fPending = false;
+        }
     }
 
     PVOID GetBlob(DWORD * pdwLength)
@@ -79,12 +82,7 @@ class NibbleWriter
     // Write a single nibble to the stream.
     void WriteNibble(NIBBLE i)
     {
-        CONTRACTL
-        {
-            THROWS;
-            GC_NOTRIGGER;
-        }
-        CONTRACTL_END;
+        WRAPPER_NO_CONTRACT;
 
         _ASSERTE(i <= 0xF);
 
@@ -111,12 +109,7 @@ class NibbleWriter
 
     void WriteEncodedU32(DWORD dw)
     {
-        CONTRACTL
-        {
-            THROWS;
-            GC_NOTRIGGER;
-        }
-        CONTRACTL_END;
+        WRAPPER_NO_CONTRACT;
 
         // Fast path for common small inputs
         if (dw <= 63)
@@ -148,12 +141,7 @@ class NibbleWriter
     // Write a signed 32 bit value.
     void WriteEncodedI32(int x)
     {
-        CONTRACTL
-        {
-            THROWS;
-            GC_NOTRIGGER;
-        }
-        CONTRACTL_END;
+        WRAPPER_NO_CONTRACT;
 
         DWORD dw = (x < 0) ? (((-x) << 1) + 1) : (x << 1);
         WriteEncodedU32(dw);
@@ -175,6 +163,12 @@ class NibbleWriter
         }
     }
 
+    void WriteRawByte(uint8_t b)
+    {
+        Flush();
+        m_SigBuilder.AppendByte(b);
+    }
+
 protected:
     NIBBLE m_PendingNibble;     // Pending value, not yet written out.
     bool m_fPending;
@@ -188,15 +182,47 @@ class NibbleWriter
 class NibbleReader
 {
 public:
+#ifdef BIGENDIAN
+    typedef uint8_t NibbleChunkType; // Alternatively we could byteswap the data after we load it, but I don't have a convenient helper here, so we just use a byte type
+#else
+#ifdef HOST_64BIT
+    typedef uint64_t NibbleChunkType;
+#else
+    typedef uint32_t NibbleChunkType;
+#endif // HOST_64BIT
+#endif // !BIGENDIAN
     NibbleReader(PTR_BYTE pBuffer, size_t size)
     {
         LIMITED_METHOD_CONTRACT;
         SUPPORTS_DAC;
         _ASSERTE(pBuffer != NULL);
 
-        m_pBuffer = pBuffer;
-        m_cBytes = size;
-        m_cNibble = 0;
+        TADDR pBufferAddr = dac_cast(pBuffer);
+        TADDR pBufferChunkAddr = AlignDown(pBufferAddr, sizeof(NibbleChunkType));
+
+        m_pNibblesBuffer = dac_cast(pBufferChunkAddr);
+        m_curNibbleData = m_pNibblesBuffer[0];
+        m_cNibbleMapOffset = (pBufferAddr - pBufferChunkAddr);
+        m_curNibbleData >>= 8 * m_cNibbleMapOffset; // Adjust to the first nibble in the first chunk
+        m_nibblesInCurrentNibbleData = (uint32_t)((sizeof(NibbleChunkType) * 2) - m_cNibbleMapOffset * 2); // Calculate how many nibbles are in the first chunk
+
+        m_cNibbleChunksConsumed = 1;
+
+        if (size >= 0xFFFFFFFF)
+        {
+            m_cNibbleChunksTotal = 0xFFFFFFFF;
+        }
+        else
+        {
+            if ((m_nibblesInCurrentNibbleData / 2) >= size)
+            {
+                m_cNibbleChunksTotal = 1; // No more chunks to read, we have enough nibbles in the first chunk
+            }
+            else
+            {
+                m_cNibbleChunksTotal = 1 + AlignUp((size * 2 - m_nibblesInCurrentNibbleData), sizeof(NibbleChunkType) * 2)/(sizeof(NibbleChunkType) * 2);
+            }
+        }
     }
 
     // Get the index of the next Byte.
@@ -207,7 +233,10 @@ class NibbleReader
         LIMITED_METHOD_CONTRACT;
         SUPPORTS_DAC;
 
-        return (m_cNibble + 1) / 2;
+        size_t nextNibbleChunkOffset = m_cNibbleChunksConsumed * sizeof(NibbleChunkType) - m_cNibbleMapOffset;
+        size_t result = nextNibbleChunkOffset - m_nibblesInCurrentNibbleData / 2;
+
+        return result;
     }
 
     NIBBLE ReadNibble()
@@ -220,27 +249,23 @@ class NibbleReader
         }
         CONTRACTL_END;
 
-        NIBBLE i = 0;
-        // Bufer should have been allocated large enough to hold data.
-        if (!(m_cNibble / 2 < m_cBytes))
+        if (m_nibblesInCurrentNibbleData == 0)
         {
-            // We should never get here in a normal retail scenario.
-            // We could wind up here if somebody provided us invalid data (maybe by corrupting an ngenned image).
-            EX_THROW(HRException, (E_INVALIDARG));
-        }
+            // We have consumed all nibbles in the current nibble data.
+            // Move to the next chunk of nibbles.
+            if (m_cNibbleChunksConsumed >= m_cNibbleChunksTotal)
+            {
+                // No more nibbles left to read.
+                EX_THROW(HRException, (E_INVALIDARG));
+            }
 
-        BYTE p = m_pBuffer[m_cNibble / 2];
-        if ((m_cNibble & 1) == 0)
-        {
-            // Read the low nibble first
-            i = (NIBBLE) (p & 0xF);
-        }
-        else
-        {
-            // Read the high nibble after the low nibble has been read
-            i = (NIBBLE) (p >> 4) & 0xF;
+            m_curNibbleData = m_pNibblesBuffer[m_cNibbleChunksConsumed++];
+            m_nibblesInCurrentNibbleData = (sizeof(NibbleChunkType) * 2);
         }
-        m_cNibble++;
+
+        m_nibblesInCurrentNibbleData--;
+        NIBBLE i = (NIBBLE) (m_curNibbleData & 0xF);
+        m_curNibbleData >>= 4; // Shift right to get the next nibble for the next call
 
         return i;
     }
@@ -289,6 +314,68 @@ class NibbleReader
         return dw;
     }
 
+    FORCEINLINE NIBBLE ReadNibble_NoThrow()
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+
+        if (m_nibblesInCurrentNibbleData == 0)
+        {
+            // We have consumed all nibbles in the current nibble data.
+            // Move to the next chunk of nibbles.
+            if (m_cNibbleChunksConsumed < m_cNibbleChunksTotal)
+            {
+                // Read the next nibble chunk. If we're past the end, we'll just skip
+                // that, and the nibble data will just be 0.
+                m_curNibbleData = m_pNibblesBuffer[m_cNibbleChunksConsumed++];
+            }
+
+            m_nibblesInCurrentNibbleData = (sizeof(NibbleChunkType) * 2);
+        }
+
+        m_nibblesInCurrentNibbleData--;
+        NIBBLE i = (NIBBLE) (m_curNibbleData & 0xF);
+        m_curNibbleData >>= 4; // Shift right to get the next nibble for the next call
+
+        return i;
+    }
+
+    // Read an unsigned int that was encoded via variable length nibble encoding
+    // from NibbleWriter::WriteEncodedU32.
+    DWORD ReadEncodedU32_NoThrow()
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+
+        DWORD dw = 0;
+
+#if defined(_DEBUG) || defined(DACCESS_COMPILE)
+        int dwCount = 0;
+#endif
+
+        // The encoding is variably lengthed, with the high-bit of every nibble indicating whether
+        // there is another nibble in the value.  Each nibble contributes 3 bits to the value.
+        NIBBLE n;
+        do
+        {
+#if defined(_DEBUG) || defined(DACCESS_COMPILE)
+            // If we've already read 11 nibbles (with 3 bits of usable data each), then we
+            // should be done reading a 32-bit integer.
+            // Avoid working with corrupted data and potentially long loops by failing
+            if(dwCount > 11)
+            {
+                _ASSERTE_MSG(false, "Corrupt nibble stream - value exceeded 32-bits in size");
+#ifdef DACCESS_COMPILE
+                DacError(CORDBG_E_TARGET_INCONSISTENT);
+#endif
+            }
+            dwCount++;
+#endif
+
+            n = ReadNibble_NoThrow();
+            dw = (dw << 3) + (n & 0x7);
+        } while((n & 0x8) > 0);
+
+        return dw;
+    }
     int ReadEncodedI32()
     {
         CONTRACTL
@@ -304,6 +391,15 @@ class NibbleReader
         return (dw & 1) ? (-x) : (x);
     }
 
+    int ReadEncodedI32_NoThrow()
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+
+        DWORD dw = ReadEncodedU32_NoThrow();
+        int x = dw >> 1;
+        return (dw & 1) ? (-x) : (x);
+    }
+
     DWORD ReadUnencodedU32()
     {
         CONTRACTL
@@ -324,10 +420,27 @@ class NibbleReader
         return result;
     }
 
+    DWORD ReadUnencodedU32_NoThrow()
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+
+        DWORD result = 0;
+
+        for (int i = 0; i < 8; i++)
+        {
+            result |= static_cast(ReadNibble_NoThrow()) << (i * 4);
+        }
+
+        return result;
+    }
+
 protected:
-    PTR_BYTE m_pBuffer;
-    size_t m_cBytes; // size of buffer.
-    size_t m_cNibble; // Which nibble are we at?
+    DPTR(NibbleChunkType) m_pNibblesBuffer;
+    size_t m_cNibbleChunksTotal; // size of buffer remaining
+    size_t m_cNibbleChunksConsumed; // How many chunks of nibbles have we consumed?
+    size_t m_cNibbleMapOffset; // Offset in the nibble stream the nibble stream started
+    NibbleChunkType m_curNibbleData;
+    uint32_t m_nibblesInCurrentNibbleData;
 };
 
 
diff --git a/src/coreclr/inc/palclr.h b/src/coreclr/inc/palclr.h
index 1eca4438311e92..dd9db6958c1441 100644
--- a/src/coreclr/inc/palclr.h
+++ b/src/coreclr/inc/palclr.h
@@ -362,30 +362,6 @@
     {                                                                           \
         PAL_TRY_HANDLER_DBG_BEGIN
 
-// PAL_TRY implementation that abstracts usage of COMPILER_INSTANCE*, which is used by
-// JIT64. On Windows, we dont need to do anything special as we dont have nested classes/methods
-// as on PAL.
-#define PAL_TRY_CI(__ParamType, __paramDef, __paramRef)                         \
-{                                                                               \
-    struct __HandlerData {                                                      \
-        __ParamType __param;                                                    \
-        COMPILER_INSTANCE *__ciPtr;                                             \
-    };                                                                          \
-    __HandlerData handlerData;                                                  \
-    handlerData.__param = __paramRef;                                           \
-    handlerData.__ciPtr = ciPtr;                                                \
-     __HandlerData* __param = &handlerData;                                     \
-    __ParamType __paramToPassToFilter = __paramRef;                             \
-    class __Body                                                                \
-    {                                                                           \
-    public:                                                                     \
-    static void Run(__HandlerData* __pHandlerData)                              \
-    {                                                                           \
-    PAL_TRY_HANDLER_DBG_BEGIN                                                   \
-        COMPILER_INSTANCE *ciPtr = __pHandlerData->__ciPtr;                     \
-        __ParamType __paramDef = __pHandlerData->__param;
-
-
 #define PAL_TRY_FOR_DLLMAIN(__ParamType, __paramDef, __paramRef, __reason)      \
 {                                                                               \
     __ParamType __param = __paramRef;                                           \
@@ -434,11 +410,6 @@
     PAL_TRY_NAKED                                                               \
     PAL_TRY_HANDLER_DBG_BEGIN
 
-// PAL_TRY implementation that abstracts usage of COMPILER_INSTANCE*, which is used by
-// JIT64. On Windows, we dont need to do anything special as we dont have nested classes/methods
-// as on PAL.
-#define PAL_TRY_CI(__ParamType, __paramDef, __paramRef) PAL_TRY(__ParamType, __paramDef, __paramRef)
-
 #define PAL_TRY_FOR_DLLMAIN(__ParamType, __paramDef, __paramRef, __reason)      \
 {                                                                               \
     __ParamType __param = __paramRef;                                           \
@@ -464,10 +435,6 @@
 
 #endif // _DEBUG
 
-// Executes the handler if the specified exception code matches
-// the one in the exception. Otherwise, returns EXCEPTION_CONTINUE_SEARCH.
-#define PAL_EXCEPT_IF_EXCEPTION_CODE(dwExceptionCode) PAL_EXCEPT((GetExceptionCode() == (dwExceptionCode))?EXCEPTION_EXECUTE_HANDLER:EXCEPTION_CONTINUE_SEARCH)
-
 #define PAL_CPP_TRY try
 #define PAL_CPP_ENDTRY
 #define PAL_CPP_THROW(type, obj) do { throw obj; } while (false)
diff --git a/src/coreclr/inc/patchpointinfo.h b/src/coreclr/inc/patchpointinfo.h
index f2c01d351c67c2..f403d268d20a7c 100644
--- a/src/coreclr/inc/patchpointinfo.h
+++ b/src/coreclr/inc/patchpointinfo.h
@@ -7,6 +7,10 @@
 
 #include 
 
+#ifndef JIT_BUILD
+#include "cdacdata.h"
+#endif // JIT_BUILD
+
 #ifndef _PATCHPOINTINFO_H_
 #define _PATCHPOINTINFO_H_
 
@@ -201,7 +205,19 @@ struct PatchpointInfo
     int32_t      m_securityCookieOffset;
     int32_t      m_monitorAcquiredOffset;
     int32_t      m_offsetAndExposureData[];
+
+#ifndef JIT_BUILD
+    friend struct ::cdac_data;
+#endif // JIT_BUILD
+};
+
+#ifndef JIT_BUILD
+template<>
+struct cdac_data
+{
+    static constexpr size_t LocalCount = offsetof(PatchpointInfo, m_numberOfLocals);
 };
+#endif // JIT_BUILD
 
 typedef DPTR(struct PatchpointInfo) PTR_PatchpointInfo;
 
diff --git a/src/coreclr/inc/pedecoder.h b/src/coreclr/inc/pedecoder.h
index c1b203e419b552..7aac8a84ae210a 100644
--- a/src/coreclr/inc/pedecoder.h
+++ b/src/coreclr/inc/pedecoder.h
@@ -431,12 +431,19 @@ class MethodSectionIterator
     BYTE *m_current;
 
   public:
+    MethodSectionIterator() = default;
 
     //If code is a target pointer, then GetMethodCode and FindMethodCode return
     //target pointers.  codeTable may be a pointer of either type, since it is
     //converted internally into a host pointer.
-    MethodSectionIterator(const void *code, SIZE_T codeSize,
-                          const void *codeTable, SIZE_T codeTableSize);
+    MethodSectionIterator(void *code, SIZE_T codeSize,
+                          void *codeTable, SIZE_T codeTableSize);
+
+    MethodSectionIterator(MethodSectionIterator const&) = delete;
+    MethodSectionIterator& operator=(MethodSectionIterator const&) = delete;
+    MethodSectionIterator(MethodSectionIterator&&) = default;
+    MethodSectionIterator& operator=(MethodSectionIterator&&) = default;
+
     BOOL Next();
     BYTE *GetMethodCode() { return m_current; } // Get the start of method code of the current method in the iterator
 };
diff --git a/src/coreclr/inc/readytorun.h b/src/coreclr/inc/readytorun.h
index e5fbd43815dab4..134b685ff9fbe6 100644
--- a/src/coreclr/inc/readytorun.h
+++ b/src/coreclr/inc/readytorun.h
@@ -19,10 +19,10 @@
 //  src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h
 // If you update this, ensure you run `git grep MINIMUM_READYTORUN_MAJOR_VERSION`
 // and handle pending work.
-#define READYTORUN_MAJOR_VERSION 15
+#define READYTORUN_MAJOR_VERSION 16
 #define READYTORUN_MINOR_VERSION 0x0000
 
-#define MINIMUM_READYTORUN_MAJOR_VERSION 15
+#define MINIMUM_READYTORUN_MAJOR_VERSION 16
 
 // R2R Version 2.1 adds the InliningInfo section
 // R2R Version 2.2 adds the ProfileDataInfo section
@@ -46,6 +46,7 @@
 // R2R Version 13.1 added long/ulong to float helper calls
 // R2R Version 14 changed x86 code generation to use funclets
 // R2R Version 15 removes double to int/uint helper calls
+// R2R Version 16 replaces the compression format for debug boundaries with a new format that is smaller and more efficient to parse
 
 struct READYTORUN_CORE_HEADER
 {
diff --git a/src/coreclr/inc/stresslog.h b/src/coreclr/inc/stresslog.h
index eb437a6bf7db7b..9219a4b32fa9eb 100644
--- a/src/coreclr/inc/stresslog.h
+++ b/src/coreclr/inc/stresslog.h
@@ -347,19 +347,24 @@ typedef USHORT
     static StressLog theLog;    // We only have one log, and this is it
 };
 
-
-template<>
-void* StressLog::ConvertArgument(float arg) = delete;
-
 #if TARGET_64BIT
 template<>
 inline void* StressLog::ConvertArgument(double arg)
 {
     return (void*)(size_t)(*((uint64_t*)&arg));
 }
+
+// COMPAT: Convert 32-bit floats to 64-bit doubles.
+template<>
+inline void* StressLog::ConvertArgument(float arg)
+{
+    return StressLog::ConvertArgument((double)arg);
+}
 #else
 template<>
 void* StressLog::ConvertArgument(double arg) = delete;
+template<>
+void* StressLog::ConvertArgument(float arg) = delete;
 
 // COMPAT: Truncate 64-bit integer arguments to 32-bit
 template<>
@@ -391,23 +396,24 @@ inline BOOL StressLog::LogOn(unsigned facility, unsigned level)
 template<>
 struct cdac_offsets
 {
-    static const size_t facilitiesToLog = offsetof(StressLog, facilitiesToLog);
-    static const size_t levelToLog = offsetof(StressLog, levelToLog);
-    static const size_t MaxSizePerThread = offsetof(StressLog, MaxSizePerThread);
-    static const size_t MaxSizeTotal = offsetof(StressLog, MaxSizeTotal);
-    static const size_t totalChunk = offsetof(StressLog, totalChunk);
-    static const size_t logs = offsetof(StressLog, logs);
-    static const size_t tickFrequency = offsetof(StressLog, tickFrequency);
-    static const size_t startTimeStamp = offsetof(StressLog, startTimeStamp);
-    static const size_t startTime = offsetof(StressLog, startTime);
-    static const size_t moduleOffset = offsetof(StressLog, moduleOffset);
-    static constexpr uint64_t MAX_MODULES = StressLog::MAX_MODULES;
+    static constexpr size_t facilitiesToLog = offsetof(StressLog, facilitiesToLog);
+    static constexpr size_t levelToLog = offsetof(StressLog, levelToLog);
+    static constexpr size_t MaxSizePerThread = offsetof(StressLog, MaxSizePerThread);
+    static constexpr size_t MaxSizeTotal = offsetof(StressLog, MaxSizeTotal);
+    static constexpr size_t totalChunk = offsetof(StressLog, totalChunk);
+    static constexpr size_t logs = offsetof(StressLog, logs);
+    static constexpr size_t tickFrequency = offsetof(StressLog, tickFrequency);
+    static constexpr size_t startTimeStamp = offsetof(StressLog, startTimeStamp);
+    static constexpr size_t startTime = offsetof(StressLog, startTime);
+    static constexpr size_t moduleOffset = offsetof(StressLog, moduleOffset);
+    static constexpr size_t MAX_MODULES = StressLog::MAX_MODULES;
+    static constexpr size_t modules = offsetof(StressLog, modules);
 
     struct ModuleDesc
     {
         static constexpr size_t type_size = sizeof(StressLog::ModuleDesc);
-        static const size_t baseAddress = offsetof(StressLog::ModuleDesc, baseAddress);
-        static const size_t size = offsetof(StressLog::ModuleDesc, size);
+        static constexpr size_t baseAddress = offsetof(StressLog::ModuleDesc, baseAddress);
+        static constexpr size_t size = offsetof(StressLog::ModuleDesc, size);
     };
 };
 
diff --git a/src/coreclr/inc/switches.h b/src/coreclr/inc/switches.h
index 5e8f90c0548a30..7915e0944f4175 100644
--- a/src/coreclr/inc/switches.h
+++ b/src/coreclr/inc/switches.h
@@ -165,3 +165,7 @@
 // If this is uncommented, leaves a file "StubLog_.log" with statistics on the behavior
 // of stub-based interface dispatch.
 //#define STUB_LOGGING
+
+#ifdef TARGET_WASM
+#define PEIMAGE_FLAT_LAYOUT_ONLY
+#endif // !TARGET_WASM
diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h
index a65140ea80331a..6c7023f3259c1e 100644
--- a/src/coreclr/inc/utilcode.h
+++ b/src/coreclr/inc/utilcode.h
@@ -844,13 +844,14 @@ inline void SetBit(BYTE * pcBits,int iBit,int bOn)
 #endif
 
 template
-class SimpleListNode
+class SimpleListNode final
 {
 public:
-    SimpleListNode(const T& _t)
+    SimpleListNode(T const& _t)
+        : data{ _t }
+        , next{}
     {
-        data = _t;
-        next = 0;
+        LIMITED_METHOD_CONTRACT;
     }
 
     T                  data;
@@ -858,44 +859,46 @@ class SimpleListNode
 };
 
 template
-class SimpleList
+class SimpleList final
 {
 public:
-    typedef SimpleListNode NodeType;
+    typedef SimpleListNode Node;
 
     SimpleList()
+        : _head{}
     {
-        head = NULL;
+        LIMITED_METHOD_CONTRACT;
     }
 
-    void LinkHead(NodeType* pNode)
+    void LinkHead(Node* pNode)
     {
-        pNode->next = head;
-                      head = pNode;
+        LIMITED_METHOD_CONTRACT;
+        pNode->next = _head;
+        _head = pNode;
     }
 
-    NodeType* UnlinkHead()
+    Node* UnlinkHead()
     {
-        NodeType* ret = head;
+        LIMITED_METHOD_CONTRACT;
+        Node* ret = _head;
 
-        if (head)
+        if (_head)
         {
-            head = head->next;
+            _head = _head->next;
         }
         return ret;
     }
 
-    NodeType* Head()
+    Node* Head()
     {
-        return head;
+        LIMITED_METHOD_CONTRACT;
+        return _head;
     }
 
-protected:
-
-    NodeType* head;
+private:
+    Node* _head;
 };
 
-
 //*****************************************************************************
 // This class implements a dynamic array of structures for which the order of
 // the elements is unimportant.  This means that any item placed in the list
@@ -937,6 +940,37 @@ class CUnorderedArrayWithAllocator
             ALLOCATOR::Free(this, m_pTable);
     }
 
+    CUnorderedArrayWithAllocator(CUnorderedArrayWithAllocator const&) = delete;
+    CUnorderedArrayWithAllocator& operator=(CUnorderedArrayWithAllocator const&) = delete;
+    CUnorderedArrayWithAllocator(CUnorderedArrayWithAllocator&& other)
+        : m_iCount{ 0 }
+        , m_iSize{ 0 }
+        , m_pTable{ NULL}
+    {
+        LIMITED_METHOD_CONTRACT;
+        other.m_iCount = 0;
+        other.m_iSize = 0;
+        other.m_pTable = NULL;
+    }
+    CUnorderedArrayWithAllocator& operator=(CUnorderedArrayWithAllocator&& other)
+    {
+        LIMITED_METHOD_CONTRACT;
+        if (this != &other)
+        {
+            if (m_pTable != NULL)
+                ALLOCATOR::Free(this, m_pTable);
+
+            m_iCount = other.m_iCount;
+            m_iSize = other.m_iSize;
+            m_pTable = other.m_pTable;
+
+            other.m_iCount = 0;
+            other.m_iSize = 0;
+            other.m_pTable = NULL;
+        }
+        return *this;
+    }
+
     void Clear()
     {
         WRAPPER_NO_CONTRACT;
@@ -1057,12 +1091,11 @@ class CUnorderedArrayWithAllocator
 
 #endif // #ifndef DACCESS_COMPILE
 
-    USHORT Count()
+    INT32 Count()
     {
         LIMITED_METHOD_CONTRACT;
         SUPPORTS_DAC;
-        _ASSERTE(FitsIn(m_iCount));
-        return static_cast(m_iCount);
+        return m_iCount;
     }
 
 private:
@@ -3315,6 +3348,16 @@ void PutLoongArch64PC12(UINT32 * pCode, INT64 imm);
 //*****************************************************************************
 void PutLoongArch64JIR(UINT32 * pCode, INT64 imm);
 
+//*****************************************************************************
+//  Extract the PC-Relative offset from auipc + I-type adder (addi/ld/jalr)
+//*****************************************************************************
+INT64 GetRiscV64AuipcItype(UINT32 * pCode);
+
+//*****************************************************************************
+//  Deposit the PC-Relative offset into auipc + I-type adder (addi/ld/jalr)
+//*****************************************************************************
+void PutRiscV64AuipcItype(UINT32 * pCode, INT64 offset);
+
 //*****************************************************************************
 // Returns whether the offset fits into bl instruction
 //*****************************************************************************
diff --git a/src/coreclr/inc/volatile.h b/src/coreclr/inc/volatile.h
index ce49c38ef7ac22..5f186352044000 100644
--- a/src/coreclr/inc/volatile.h
+++ b/src/coreclr/inc/volatile.h
@@ -73,6 +73,11 @@
 #endif
 
 #if defined(__GNUC__)
+#if defined(HOST_X86) || defined(HOST_AMD64)
+#define SFENCE_MEMORY_BARRIER() asm volatile ("sfence" : : : "memory")
+#else
+#define SFENCE_MEMORY_BARRIER()
+#endif
 #if defined(HOST_ARMV6)
 // DMB ISH not valid on ARMv6
 #define VOLATILE_MEMORY_BARRIER() asm volatile ("mcr p15, 0, r0, c7, c10, 5" : : : "memory")
@@ -97,13 +102,22 @@
 //
 #define VOLATILE_MEMORY_BARRIER() asm volatile ("" : : : "memory")
 #endif // HOST_ARM || HOST_ARM64
+
 #elif (defined(HOST_ARM) || defined(HOST_ARM64)) && _ISO_VOLATILE
 // ARM & ARM64 have a very weak memory model and very few tools to control that model. We're forced to perform a full
 // memory barrier to preserve the volatile semantics. Technically this is only necessary on MP systems but we
 // currently don't have a cheap way to determine the number of CPUs from this header file. Revisit this if it
 // turns out to be a performance issue for the uni-proc case.
+
 #define VOLATILE_MEMORY_BARRIER() MemoryBarrier()
+#define SFENCE_MEMORY_BARRIER()
 #else
+
+#if defined(HOST_X86) || defined(HOST_AMD64)
+#define SFENCE_MEMORY_BARRIER() _mm_sfence()
+#else
+#define SFENCE_MEMORY_BARRIER()
+#endif
 //
 // On VC++, reorderings at the compiler and machine level are prevented by the use of the
 // "volatile" keyword in VolatileLoad and VolatileStore.  This should work on any CPU architecture
diff --git a/src/coreclr/inc/vptr_list.h b/src/coreclr/inc/vptr_list.h
index b5581b019478b5..8fade7caa332bf 100644
--- a/src/coreclr/inc/vptr_list.h
+++ b/src/coreclr/inc/vptr_list.h
@@ -42,6 +42,7 @@ VPTR_CLASS(CallCountingStubManager)
 VPTR_CLASS(PEImageLayout)
 VPTR_CLASS(ConvertedImageLayout)
 VPTR_CLASS(LoadedImageLayout)
+VPTR_CLASS(NativeImageLayout)
 VPTR_CLASS(FlatImageLayout)
 
 #ifdef DEBUGGING_SUPPORTED
diff --git a/src/coreclr/interpreter/CMakeLists.txt b/src/coreclr/interpreter/CMakeLists.txt
index 06536580d1a440..3c0b977fca8490 100644
--- a/src/coreclr/interpreter/CMakeLists.txt
+++ b/src/coreclr/interpreter/CMakeLists.txt
@@ -12,6 +12,7 @@ set(INTERPRETER_SOURCES
   stackmap.cpp
   naming.cpp
   methodset.cpp
+  intrinsics.cpp
   ../../native/containers/dn-simdhash.c
   ../../native/containers/dn-simdhash-ght-compatible.c
   ../../native/containers/dn-simdhash-ptr-ptr.c)
@@ -40,7 +41,7 @@ else()
     add_custom_target(interpreter_exports DEPENDS ${EXPORTS_FILE})
 endif()
 
-if(CLR_CMAKE_TARGET_BROWSER)
+if(FEATURE_STATICALLY_LINKED AND NOT FEATURE_JIT)
   set(LIBRARY_TYPE STATIC)
 else()
   set(LIBRARY_TYPE SHARED)
@@ -48,6 +49,10 @@ endif()
 
 add_library_clr(clrinterpreter ${LIBRARY_TYPE} ${INTERPRETER_SOURCES})
 
+if (NOT CMAKE_GENERATOR MATCHES "Visual Studio")
+  set_target_properties(clrinterpreter PROPERTIES EXCLUDE_FROM_ALL $)
+endif()
+
 add_dependencies(clrinterpreter interpreter_exports)
 
 if(NOT CLR_CMAKE_HOST_WIN32)
@@ -62,4 +67,4 @@ target_link_libraries(clrinterpreter
 
 set_property(TARGET clrinterpreter APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE})
 
-install_clr(TARGETS clrinterpreter DESTINATIONS . COMPONENT runtime)
+install_clr(TARGETS clrinterpreter DESTINATIONS . sharedFramework COMPONENT runtime OPTIONAL)
diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp
index b5bf7dae4e5c3d..d8312a164cd73f 100644
--- a/src/coreclr/interpreter/compiler.cpp
+++ b/src/coreclr/interpreter/compiler.cpp
@@ -828,6 +828,7 @@ int32_t* InterpCompiler::EmitCodeIns(int32_t *ip, InterpInst *ins, TArrayoptions & CORINFO_OPT_INIT_LOCALS) != 0;
+    CORJIT_FLAGS corJitFlags;
+    DWORD jitFlagsSize = m_compHnd->getJitFlags(&corJitFlags, sizeof(corJitFlags));
+    assert(jitFlagsSize == sizeof(corJitFlags));
 
-    InterpMethod *pMethod = new InterpMethod(m_methodHnd, m_totalVarsStackSize, pDataItems, initLocals);
+    bool unmanagedCallersOnly = corJitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_REVERSE_PINVOKE);
+
+    InterpMethod *pMethod = new InterpMethod(m_methodHnd, m_totalVarsStackSize, pDataItems, initLocals, unmanagedCallersOnly);
 
     return pMethod;
 }
@@ -1391,8 +1397,6 @@ int32_t InterpCompiler::GetInterpTypeStackSize(CORINFO_CLASS_HANDLE clsHnd, Inte
         size = m_compHnd->getClassSize(clsHnd);
         align = m_compHnd->getClassAlignmentRequirement(clsHnd);
 
-        assert(align <= INTERP_STACK_ALIGNMENT);
-
         // All vars are stored at 8 byte aligned offsets
         if (align < INTERP_STACK_SLOT_SIZE)
             align = INTERP_STACK_SLOT_SIZE;
@@ -2156,72 +2160,229 @@ 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_PVALUE)
-    {
-        addr = (void*)((size_t)addr | INTERP_INDIRECT_HELPER_TAG);
-    }
 
 #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)
+{
+    switch (interpType)
+    {
+        case InterpTypeI1: return INTOP_LDIND_I1;
+        case InterpTypeU1: return INTOP_LDIND_U1;
+        case InterpTypeI2: return INTOP_LDIND_I2;
+        case InterpTypeU2: return INTOP_LDIND_U2;
+        case InterpTypeI4: return INTOP_LDIND_I4;
+        case InterpTypeI8: return INTOP_LDIND_I8;
+        case InterpTypeR4: return INTOP_LDIND_R4;
+        case InterpTypeR8: return INTOP_LDIND_R8;
+        case InterpTypeO: return INTOP_LDIND_I;
+        case InterpTypeVT: return INTOP_LDIND_VT;
+        case InterpTypeByRef: return INTOP_LDIND_I;
+        default:
+            assert(0);
+    }
+    return -1;
+}
+
+static bool DoesValueTypeContainGCRefs(COMP_HANDLE compHnd, CORINFO_CLASS_HANDLE clsHnd)
+{
+    unsigned size = compHnd->getClassSize(clsHnd);
+    // getClassGClayout assumes it's given a buffer of exactly this size
+    unsigned maxGcPtrs = (size + sizeof(void *) - 1) / sizeof(void *);
+    BYTE *gcLayout = (BYTE *)alloca(maxGcPtrs + 1);
+    uint32_t numSlots = compHnd->getClassGClayout(clsHnd, gcLayout);
+
+    for (uint32_t i = 0; i < numSlots; ++i)
+    {
+        if (gcLayout[i] != TYPE_GC_NONE)
+        {
+            return true;
+        }
+    }
+
+    return false;
 }
 
-bool InterpCompiler::EmitCallIntrinsics(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO sig)
+bool InterpCompiler::EmitNamedIntrinsicCall(NamedIntrinsic ni, CORINFO_CLASS_HANDLE clsHnd, 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);
+    bool mustExpand = (method == m_methodHnd);
+    if (!mustExpand && (ni == NI_Illegal))
+        return false;
 
-    if (namespaceName && !strcmp(namespaceName, "System"))
+    switch (ni)
     {
-        if (className && !strcmp(className, "Environment"))
+        case NI_IsSupported_False:
+        case NI_IsSupported_True:
+            AddIns(INTOP_LDC_I4);
+            m_pLastNewIns->data[0] = ni == NI_IsSupported_True;
+            PushStackType(StackTypeI4, NULL);
+            m_pLastNewIns->SetDVar(m_pStackPointer[-1].var);
+            return true;
+
+        case NI_Throw_PlatformNotSupportedException:
+            AddIns(INTOP_THROW_PNSE);
+            return true;
+
+        case NI_System_Runtime_CompilerServices_StaticsHelpers_VolatileReadAsByref:
         {
-            if (methodName && !strcmp(methodName, "FailFast"))
+            CHECK_STACK(1);
+
+            m_pStackPointer--;
+            int32_t addrVar = m_pStackPointer[0].var;
+
+            InterpType retType = GetInterpType(sig.retType);
+            int32_t opcode = GetLdindForType(retType);
+            AddIns(opcode);
+            m_pLastNewIns->SetSVar(addrVar);
+
+            CORINFO_CLASS_HANDLE clsHnd = NULL;
+            if (sig.retType == CORINFO_TYPE_CLASS)
             {
-                AddIns(INTOP_FAILFAST); // to be removed, not really an intrisic
-                m_pStackPointer--;
-                return true;
+                clsHnd = sig.retTypeClass;
+            }
+            PushInterpType(retType, clsHnd);
+            m_pLastNewIns->SetDVar(m_pStackPointer[-1].var);
+
+            // Acquire barrier after the load
+            AddIns(INTOP_MEMBAR);
+            return true;
+        }
+
+        case NI_System_Threading_Volatile_ReadBarrier:
+            AddIns(INTOP_MEMBAR);
+            return true;
+
+        case NI_System_Runtime_CompilerServices_RuntimeHelpers_GetMethodTable:
+        {
+            CHECK_STACK(1);
+            m_pStackPointer--;
+            AddIns(INTOP_LDIND_I);
+            m_pLastNewIns->data[0] = 0;
+            m_pLastNewIns->SetSVar(m_pStackPointer[0].var);
+            PushStackType(StackTypeI, NULL);
+            m_pLastNewIns->SetDVar(m_pStackPointer[-1].var);
+            return true;
+        }
+
+        case NI_System_Threading_Interlocked_CompareExchange:
+        {
+            CHECK_STACK(3);
+            InterpType retType = GetInterpType(sig.retType);
+
+            int32_t opcode;
+            switch (retType)
+            {
+                case InterpTypeI4:
+                    opcode = INTOP_COMPARE_EXCHANGE_I4;
+                    break;
+                case InterpTypeI8:
+                    opcode = INTOP_COMPARE_EXCHANGE_I8;
+                    break;
+                default:
+                    return false;
             }
+
+            AddIns(opcode);
+            m_pStackPointer -= 3;
+
+            int32_t addrVar = m_pStackPointer[0].var;
+            int32_t valueVar = m_pStackPointer[1].var;
+            int32_t comparandVar = m_pStackPointer[2].var;
+
+            PushInterpType(retType, nullptr);
+            m_pLastNewIns->SetSVars3(addrVar, valueVar, comparandVar);
+            m_pLastNewIns->SetDVar(m_pStackPointer[-1].var);
+            return true;
         }
-        else if (className && !strcmp(className, "Object"))
+
+        case NI_System_Runtime_CompilerServices_RuntimeHelpers_IsReferenceOrContainsReferences:
         {
-            // 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"))
+            CORINFO_CLASS_HANDLE clsHnd = sig.sigInst.methInst[0];
+            bool isValueType = (m_compHnd->getClassAttribs(clsHnd) & CORINFO_FLG_VALUECLASS) != 0;
+            bool hasGCRefs = false;
+
+            if (isValueType)
             {
-                AddIns(INTOP_NOP);
-                m_pStackPointer--;
-                return true;
+                hasGCRefs = DoesValueTypeContainGCRefs(m_compHnd, clsHnd);
             }
+
+            int32_t result = (!isValueType || hasGCRefs) ? 1 : 0;
+
+            AddIns(INTOP_LDC_I4);
+            m_pLastNewIns->data[0] = result;
+
+            PushInterpType(InterpTypeI4, nullptr);
+            m_pLastNewIns->SetDVar(m_pStackPointer[-1].var);
+
+            return true;
         }
-        else if (className && !strcmp(className, "GC"))
+        case NI_System_Runtime_InteropService_MemoryMarshal_GetArrayDataReference:
         {
-            if (methodName && !strcmp(methodName, "Collect"))
+            CHECK_STACK(1);
+
+            m_pStackPointer--;
+            int32_t arrayVar = m_pStackPointer[0].var;
+
+            AddIns(INTOP_NULLCHECK);
+            m_pLastNewIns->SetSVar(arrayVar);
+
+            AddIns(INTOP_ADD_P_IMM);
+            m_pLastNewIns->SetSVar(arrayVar);
+            m_pLastNewIns->data[0] = OFFSETOF__CORINFO_Array__data;
+
+            PushInterpType(InterpTypeByRef, NULL);
+            m_pLastNewIns->SetDVar(m_pStackPointer[-1].var);
+
+            return true;
+        }
+
+        case NI_System_Threading_Thread_FastPollGC:
+            AddIns(INTOP_SAFEPOINT);
+            return true;
+
+        default:
+        {
+#ifdef DEBUG
+            if (m_verbose)
             {
-                AddIns(INTOP_GC_COLLECT);
-                // Not reducing the stack pointer because we expect the version with no arguments
-                return true;
+                const char* className = NULL;
+                const char* namespaceName = NULL;
+                const char* methodName = m_compHnd->getMethodNameFromMetadata(method, &className, &namespaceName, NULL, 0);
+                printf("WARNING: Intrinsic not implemented in EmitNamedIntrinsicCall: %d (for %s.%s.%s)\n", ni, namespaceName, className, methodName);
             }
+#endif
+            if (mustExpand)
+                NO_WAY("EmitNamedIntrinsicCall not implemented must-expand intrinsic");
+            return false;
         }
-        // TODO: Add multi-dimensional array getters and setters
     }
-
-    return false;
 }
 
 void InterpCompiler::ResolveToken(uint32_t token, CorInfoTokenKind tokenKind, CORINFO_RESOLVED_TOKEN *pResolvedToken)
@@ -2328,7 +2489,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);
@@ -2337,7 +2498,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);
@@ -2355,7 +2516,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);
@@ -2364,7 +2525,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);
@@ -2382,16 +2543,16 @@ 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);
         m_pLastNewIns->SetDVar(resultVar);
     }
     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);
@@ -2409,7 +2570,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);
@@ -2418,7 +2579,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);
@@ -2436,7 +2597,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);
@@ -2445,7 +2606,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);
@@ -2484,7 +2645,7 @@ int InterpCompiler::EmitGenericHandleAsVar(const CORINFO_GENERICHANDLE_RESULT &e
     PushStackType(StackTypeI, NULL);
     int resultVar = m_pStackPointer[-1].var;
     m_pStackPointer--;
-    
+
     GenericHandleData handleData = GenericHandleToGenericHandleData(embedInfo);
 
     if (handleData.argType == HelperArgType::GenericResolution)
@@ -2551,6 +2712,7 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
 {
     uint32_t token = getU4LittleEndian(m_ip + 1);
     bool isVirtual = (*m_ip == CEE_CALLVIRT);
+    bool isDelegateInvoke = false;
 
     CORINFO_RESOLVED_TOKEN resolvedCallToken;
     CORINFO_CALL_INFO callInfo;
@@ -2581,13 +2743,38 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
 
         CORINFO_CALLINFO_FLAGS flags = (CORINFO_CALLINFO_FLAGS)(CORINFO_CALLINFO_ALLOWINSTPARAM | CORINFO_CALLINFO_SECURITYCHECKS | CORINFO_CALLINFO_DISALLOW_STUB);
         if (isVirtual)
-        flags = (CORINFO_CALLINFO_FLAGS)(flags | CORINFO_CALLINFO_CALLVIRT);
+            flags = (CORINFO_CALLINFO_FLAGS)(flags | CORINFO_CALLINFO_CALLVIRT);
 
         m_compHnd->getCallInfo(&resolvedCallToken, pConstrainedToken, m_methodInfo->ftn, flags, &callInfo);
-        if (EmitCallIntrinsics(callInfo.hMethod, callInfo.sig))
+        if (callInfo.methodFlags & CORINFO_FLG_INTRINSIC)
         {
-            m_ip += 5;
-            return;
+            NamedIntrinsic ni = GetNamedIntrinsic(m_compHnd, m_methodHnd, callInfo.hMethod);
+            if ((ni == NI_System_StubHelpers_NextCallReturnAddress) && (m_ip[5] == CEE_POP))
+            {
+                // Call to System.StubHelpers.NextCallReturnAddress followed by CEE_POP is a special case that we handle
+                // as a no-op.
+                m_ip += 6; // Skip the call and the CEE_POP
+                return;
+            }
+
+            // If we are being asked explicitly to compile an intrinsic for interpreting, we need to forcibly enable
+            //  intrinsics for the recursive call. Otherwise we will just recurse infinitely and overflow stack.
+            //  This expansion can produce value that is inconsistent with the value seen by JIT/R2R code that can
+            //  cause user code to misbehave. This is by design. One-off method Interpretation is for internal use only.
+            bool isMustExpand = (callInfo.hMethod == m_methodHnd);
+            if ((InterpConfig.InterpMode() == 3) || isMustExpand)
+            {
+                if (EmitNamedIntrinsicCall(ni, resolvedCallToken.hClass, callInfo.hMethod, callInfo.sig))
+                {
+                    m_ip += 5;
+                    return;
+                }
+            }
+        }
+
+        if (callInfo.methodFlags & CORINFO_FLG_DELEGATE_INVOKE)
+        {
+            isDelegateInvoke = true;
         }
 
         if (callInfo.thisTransform != CORINFO_NO_THIS_TRANSFORM)
@@ -2620,6 +2807,9 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
         doCallInsteadOfNew = true;
     }
 
+    bool isPInvoke = callInfo.methodFlags & CORINFO_FLG_PINVOKE;
+    bool isMarshaledPInvoke = isPInvoke && m_compHnd->pInvokeMarshalingRequired(callInfo.hMethod, &callInfo.sig);
+
     // Process sVars
     int numArgsFromStack = callInfo.sig.numArgs + (newObj ? 0 : callInfo.sig.hasThis());
     int newObjThisArgLocation = newObj && !doCallInsteadOfNew ? 0 : INT_MAX;
@@ -2663,7 +2853,7 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
     if (newObjThisArgLocation != INT_MAX)
     {
         ctorType = GetInterpType(m_compHnd->asCorInfoType(resolvedCallToken.hClass));
-        if (ctorType == InterpTypeVT)
+        if (ctorType != InterpTypeO)
         {
             vtsize = m_compHnd->getClassSize(resolvedCallToken.hClass);
             PushTypeVT(resolvedCallToken.hClass, vtsize);
@@ -2675,7 +2865,7 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
             PushInterpType(ctorType, resolvedCallToken.hClass);
 
             CORINFO_GENERICHANDLE_RESULT newObjGenericHandleEmbedInfo;
-            m_compHnd->embedGenericHandle(&resolvedCallToken, true, m_methodInfo->ftn, &newObjGenericHandleEmbedInfo); 
+            m_compHnd->embedGenericHandle(&resolvedCallToken, true, m_methodInfo->ftn, &newObjGenericHandleEmbedInfo);
             newObjData = GenericHandleToGenericHandleData(newObjGenericHandleEmbedInfo);
         }
         newObjDVar = m_pStackPointer[-2].var;
@@ -2795,7 +2985,7 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
         case CORINFO_CALL:
             if (newObj && !doCallInsteadOfNew)
             {
-                if (ctorType == InterpTypeVT)
+                if (ctorType != InterpTypeO)
                 {
                     // If this is a newobj for a value type, we need to call the constructor
                     // and then copy the value type to the stack.
@@ -2819,13 +3009,17 @@ 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)
             {
                 CORINFO_GENERICHANDLE_RESULT newObjGenericHandleEmbedInfo;
-                m_compHnd->embedGenericHandle(&resolvedCallToken, true, m_methodInfo->ftn, &newObjGenericHandleEmbedInfo); 
+                m_compHnd->embedGenericHandle(&resolvedCallToken, true, m_methodInfo->ftn, &newObjGenericHandleEmbedInfo);
                 newObjData = GenericHandleToGenericHandleData(newObjGenericHandleEmbedInfo);
-                
+
                 if (newObjData.argType == HelperArgType::GenericResolution)
                 {
                     AddIns(INTOP_NEWMDARR_GENERIC);
@@ -2856,8 +3050,29 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
                     // before the call.
                     // TODO: Add null checking behavior somewhere here!
                 }
-                AddIns(INTOP_CALL);
+                if (isDelegateInvoke)
+                {
+                    assert(!isPInvoke && !isMarshaledPInvoke);
+                    AddIns(INTOP_CALLDELEGATE);
+                }
+                else
+                {
+                    AddIns((isPInvoke && !isMarshaledPInvoke) ? INTOP_CALL_PINVOKE : INTOP_CALL);
+                }
                 m_pLastNewIns->data[0] = GetMethodDataItemIndex(callInfo.hMethod);
+                if (isPInvoke && !isMarshaledPInvoke)
+                {
+                    CORINFO_CONST_LOOKUP lookup;
+                    m_compHnd->getAddressOfPInvokeTarget(callInfo.hMethod, &lookup);
+                    m_pLastNewIns->data[1] = GetDataItemIndex(lookup.addr);
+                    if (lookup.accessType == IAT_PPVALUE)
+                        NO_WAY("IAT_PPVALUE pinvokes not implemented in interpreter");
+                    bool suppressGCTransition = false;
+                    m_compHnd->getUnmanagedCallConv(callInfo.hMethod, nullptr, &suppressGCTransition);
+                    m_pLastNewIns->data[2] =
+                        ((lookup.accessType == IAT_PVALUE) ? (int32_t)PInvokeCallFlags::Indirect : 0) |
+                        (suppressGCTransition ? (int32_t)PInvokeCallFlags::SuppressGCTransition : 0);
+                }
             }
             break;
 
@@ -2888,7 +3103,7 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
             break;
 
         case CORINFO_VIRTUALCALL_LDVIRTFTN:
-            if ((callInfo.sig.sigInst.methInstCount != 0) || (m_compHnd->getClassAttribs(resolvedCallToken.hClass) & CORINFO_FLG_SHAREDINST))
+            if ((callInfo.sig.sigInst.methInstCount != 0) || (m_compHnd->getMethodAttribs(callInfo.hMethod) & CORINFO_FLG_SHAREDINST))
             {
                 assert(extraParamArgLocation == INT_MAX);
                 // We should not have a type argument for the ldvirtftn path since we don't know
@@ -2938,27 +3153,6 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
     m_ip += 5;
 }
 
-static int32_t GetLdindForType(InterpType interpType)
-{
-    switch (interpType)
-    {
-        case InterpTypeI1: return INTOP_LDIND_I1;
-        case InterpTypeU1: return INTOP_LDIND_U1;
-        case InterpTypeI2: return INTOP_LDIND_I2;
-        case InterpTypeU2: return INTOP_LDIND_U2;
-        case InterpTypeI4: return INTOP_LDIND_I4;
-        case InterpTypeI8: return INTOP_LDIND_I8;
-        case InterpTypeR4: return INTOP_LDIND_R4;
-        case InterpTypeR8: return INTOP_LDIND_R8;
-        case InterpTypeO: return INTOP_LDIND_I;
-        case InterpTypeVT: return INTOP_LDIND_VT;
-        case InterpTypeByRef: return INTOP_LDIND_I;
-        default:
-            assert(0);
-    }
-    return -1;
-}
-
 static int32_t GetStindForType(InterpType interpType)
 {
     switch (interpType)
@@ -3130,7 +3324,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);
@@ -3325,7 +3519,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);
@@ -3337,7 +3531,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);
@@ -3354,7 +3548,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);
@@ -3365,7 +3559,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);
@@ -4131,6 +4325,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
                     EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U4_R8);
                     break;
                 case StackTypeI4:
+                    EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U4_I4);
                     break;
                 case StackTypeI8:
                     EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U4_I8);
@@ -4171,9 +4366,10 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
                     EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_OVF_U8_R8);
                     break;
                 case StackTypeI4:
-                    EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_I8_U4);
+                    EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_OVF_U8_I4);
                     break;
                 case StackTypeI8:
+                    EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_OVF_U8_I8);
                     break;
                 default:
                     assert(0);
@@ -4237,17 +4433,218 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
                     break;
                 case StackTypeI4:
 #ifdef TARGET_64BIT
-                    // FIXME: Is this the right conv opcode?
-                    EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_I8_I4);
+                    EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_U8_I4);
 #else
-                    EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_MOV_4);
+                    EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_U4_I4);
 #endif
                     break;
                 case StackTypeI8:
 #ifdef TARGET_64BIT
-                    EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_MOV_8);
+                    EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_U8_I8);
 #else
                     EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_U4_I8);
+#endif
+                    break;
+                default:
+                    assert(0);
+                }
+                m_ip++;
+                break;
+            case CEE_CONV_OVF_I1_UN:
+                CHECK_STACK(1);
+                switch (m_pStackPointer[-1].type)
+                {
+                case StackTypeR4:
+                case StackTypeR8:
+                    assert(!"Floating point unsigned conversions");
+                    break;
+                case StackTypeI4:
+                    EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I1_U4);
+                    break;
+                case StackTypeI8:
+                    EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I1_U8);
+                    break;
+                default:
+                    assert(0);
+                }
+                m_ip++;
+                break;
+            case CEE_CONV_OVF_U1_UN:
+                CHECK_STACK(1);
+                switch (m_pStackPointer[-1].type)
+                {
+                case StackTypeR4:
+                case StackTypeR8:
+                    assert(!"Floating point unsigned conversions");
+                    break;
+                case StackTypeI4:
+                    EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U1_U4);
+                    break;
+                case StackTypeI8:
+                    EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U1_U8);
+                    break;
+                default:
+                    assert(0);
+                }
+                m_ip++;
+                break;
+            case CEE_CONV_OVF_I2_UN:
+                CHECK_STACK(1);
+                switch (m_pStackPointer[-1].type)
+                {
+                case StackTypeR4:
+                case StackTypeR8:
+                    assert(!"Floating point unsigned conversions");
+                    break;
+                case StackTypeI4:
+                    EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I2_U4);
+                    break;
+                case StackTypeI8:
+                    EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I2_U8);
+                    break;
+                default:
+                    assert(0);
+                }
+                m_ip++;
+                break;
+            case CEE_CONV_OVF_U2_UN:
+                CHECK_STACK(1);
+                switch (m_pStackPointer[-1].type)
+                {
+                case StackTypeR4:
+                case StackTypeR8:
+                    assert(!"Floating point unsigned conversions");
+                    break;
+                case StackTypeI4:
+                    EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U2_U4);
+                    break;
+                case StackTypeI8:
+                    EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U2_U8);
+                    break;
+                default:
+                    assert(0);
+                }
+                m_ip++;
+                break;
+            case CEE_CONV_OVF_I4_UN:
+                CHECK_STACK(1);
+                switch (m_pStackPointer[-1].type)
+                {
+                case StackTypeR4:
+                case StackTypeR8:
+                    assert(!"Floating point unsigned conversions");
+                    break;
+                case StackTypeI4:
+                    EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I4_U4);
+                    break;
+                case StackTypeI8:
+                    EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I4_U8);
+                    break;
+                default:
+                    assert(0);
+                }
+                m_ip++;
+                break;
+            case CEE_CONV_OVF_U4_UN:
+                CHECK_STACK(1);
+                switch (m_pStackPointer[-1].type)
+                {
+                case StackTypeR4:
+                case StackTypeR8:
+                    assert(!"Floating point unsigned conversions");
+                    break;
+                case StackTypeI4:
+                    break;
+                case StackTypeI8:
+                    EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U4_U8);
+                    break;
+                default:
+                    assert(0);
+                }
+                m_ip++;
+                break;
+            case CEE_CONV_OVF_I8_UN:
+                CHECK_STACK(1);
+                switch (m_pStackPointer[-1].type)
+                {
+                case StackTypeR4:
+                case StackTypeR8:
+                    assert(!"Floating point unsigned conversions");
+                    break;
+                case StackTypeI4:
+                    EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_I8_U4);
+                    break;
+                case StackTypeI8:
+                    EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_OVF_I8_U8);
+                    break;
+                default:
+                    assert(0);
+                }
+                m_ip++;
+                break;
+            case CEE_CONV_OVF_U8_UN:
+                CHECK_STACK(1);
+                switch (m_pStackPointer[-1].type)
+                {
+                case StackTypeR4:
+                case StackTypeR8:
+                    assert(!"Floating point unsigned conversions");
+                    break;
+                case StackTypeI4:
+                    EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_U8_U4);
+                    break;
+                case StackTypeI8:
+                    break;
+                default:
+                    assert(0);
+                }
+                m_ip++;
+                break;
+            case CEE_CONV_OVF_I_UN:
+                CHECK_STACK(1);
+                switch (m_pStackPointer[-1].type)
+                {
+                case StackTypeR4:
+                case StackTypeR8:
+                    assert(!"Floating point unsigned conversions");
+                    break;
+                case StackTypeI4:
+#ifdef TARGET_64BIT
+                    EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_I8_U4);
+#else
+                    EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_I4_U4);
+#endif
+                    break;
+                case StackTypeI8:
+#ifdef TARGET_64BIT
+                    EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_I8_U8);
+#else
+                    EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_I4_U8);
+#endif
+                    break;
+                default:
+                    assert(0);
+                }
+                m_ip++;
+                break;
+            case CEE_CONV_OVF_U_UN:
+                CHECK_STACK(1);
+                switch (m_pStackPointer[-1].type)
+                {
+                case StackTypeR4:
+                case StackTypeR8:
+                    assert(!"Floating point unsigned conversions");
+                    break;
+                case StackTypeI4:
+#ifdef TARGET_64BIT
+                    EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_U8_U4);
+#else
+#endif
+                    break;
+                case StackTypeI8:
+#ifdef TARGET_64BIT
+#else
+                    EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_U4_U8);
 #endif
                     break;
                 default:
@@ -4828,10 +5225,107 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
                 m_ip++;
                 break;
             }
+            case CEE_MKREFANY:
+            {
+                uint32_t token = getU4LittleEndian(m_ip + 1);
+                int32_t addressVar = m_pStackPointer[-1].var;
+                m_pStackPointer--;
+
+                CORINFO_RESOLVED_TOKEN resolvedToken;
+                ResolveToken(token, CORINFO_TOKENKIND_Class, &resolvedToken);
+                CORINFO_GENERICHANDLE_RESULT embedInfo;
+                m_compHnd->embedGenericHandle(&resolvedToken, true, m_methodInfo->ftn, &embedInfo);
+                assert(embedInfo.compileTimeHandle != NULL);
+                int typeVar = EmitGenericHandleAsVar(embedInfo);
+
+                PushInterpType(InterpTypeVT, m_compHnd->getBuiltinClass(CLASSID_TYPED_BYREF));
+
+                int32_t typedByRefVar = m_pStackPointer[-1].var;
+
+                AddIns(INTOP_DEF);
+                m_pLastNewIns->SetDVar(typedByRefVar);
+
+                AddIns(INTOP_LDLOCA);
+                m_pLastNewIns->SetSVar(typedByRefVar);
+                PushInterpType(InterpTypeByRef, NULL);
+                int byrefOfTypedRefVar = m_pStackPointer[-1].var;
+                m_pLastNewIns->SetDVar(byrefOfTypedRefVar);
+                m_pStackPointer--;
+                
+                AddIns(GetStindForType(InterpTypeByRef));
+                m_pLastNewIns->data[0] = OFFSETOF__CORINFO_TypedReference__dataPtr;
+                m_pLastNewIns->SetSVars2(byrefOfTypedRefVar, addressVar);
+
+                AddIns(GetStindForType(InterpTypeI));
+                m_pLastNewIns->data[0] = OFFSETOF__CORINFO_TypedReference__type;
+                m_pLastNewIns->SetSVars2(byrefOfTypedRefVar, typeVar);
+                m_ip += 5;
+                break;
+            }
+            case CEE_REFANYVAL:
+            {
+                uint32_t token = getU4LittleEndian(m_ip + 1);
+                int32_t typedRefVar = m_pStackPointer[-1].var;
+                m_pStackPointer--;
+
+                CORINFO_RESOLVED_TOKEN resolvedToken;
+                ResolveToken(token, CORINFO_TOKENKIND_Class, &resolvedToken);
+                CORINFO_GENERICHANDLE_RESULT embedInfo;
+                m_compHnd->embedGenericHandle(&resolvedToken, true, m_methodInfo->ftn, &embedInfo);
+                assert(embedInfo.compileTimeHandle != NULL);
+                int typeVar = EmitGenericHandleAsVar(embedInfo);
+
+                CORINFO_METHOD_HANDLE getRefAnyHelper;
+                m_compHnd->getHelperFtn(CORINFO_HELP_GETREFANY, NULL, &getRefAnyHelper);
+                assert(getRefAnyHelper != NULL);
+
+                PushInterpType(InterpTypeByRef, NULL);
+                int32_t dVar = m_pStackPointer[-1].var;
+
+                int *callArgs = (int*) AllocMemPool((2 + 1) * sizeof(int));
+                callArgs[0] = typeVar;
+                callArgs[1] = typedRefVar;
+                callArgs[2] = CALL_ARGS_TERMINATOR;
+
+                AddIns(INTOP_CALL);
+                m_pLastNewIns->data[0] = GetMethodDataItemIndex(getRefAnyHelper);
+                m_pLastNewIns->SetDVar(dVar);
+                m_pLastNewIns->SetSVar(CALL_ARGS_SVAR);
+                m_pLastNewIns->flags |= INTERP_INST_FLAG_CALL;
+                m_pLastNewIns->info.pCallInfo = (InterpCallInfo*)AllocMemPool0(sizeof (InterpCallInfo));
+                m_pLastNewIns->info.pCallInfo->pCallArgs = callArgs;
+
+                m_ip += 5;
+                break;
+            }
             case CEE_PREFIX1:
                 m_ip++;
                 switch (*m_ip + 256)
                 {
+                    case CEE_REFANYTYPE:
+                    {
+                        int32_t typedByRefVar = m_pStackPointer[-1].var;
+                        m_pStackPointer--;
+                        PushInterpType(InterpTypeI, NULL);
+                        int32_t classHandleVar = m_pStackPointer[-1].var;
+                        m_pStackPointer--;
+
+                        AddIns(INTOP_MOV_SRC_OFF);
+                        m_pLastNewIns->data[0] = (int32_t)OFFSETOF__CORINFO_TypedReference__type;
+                        m_pLastNewIns->data[1] = InterpTypeI;
+                        m_pLastNewIns->data[2] = 0;
+                        m_pLastNewIns->SetSVar(typedByRefVar);
+                        m_pLastNewIns->SetDVar(classHandleVar);
+                        
+                        AddIns(INTOP_CALL_HELPER_P_S);
+                        m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL);
+                        m_pLastNewIns->SetSVar(classHandleVar);
+                        PushInterpType(InterpTypeVT, m_compHnd->getBuiltinClass(CLASSID_TYPE_HANDLE));
+                        m_pLastNewIns->SetDVar(m_pStackPointer[-1].var);
+
+                        m_ip += 1;
+                        break;
+                    }
                     case CEE_LDARG:
                         EmitLoadVar(getU2LittleEndian(m_ip + 1));
                         m_ip += 3;
@@ -4898,6 +5392,9 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
                         volatile_ = true;
                         m_ip++;
                         break;
+                    case CEE_UNALIGNED:
+                        m_ip += 2;
+                        break;
                     case CEE_INITOBJ:
                     {
                         CHECK_STACK(1);
@@ -5043,6 +5540,18 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
                         m_ip += 5;
                         break;
                     }
+                    case CEE_CPBLK:
+                        CHECK_STACK(3);
+                        if (volatile_)
+                        {
+                            AddIns(INTOP_MEMBAR);
+                            volatile_ = false;
+                        }
+                        AddIns(INTOP_CPBLK);
+                        m_pStackPointer -= 3;
+                        m_pLastNewIns->SetSVars3(m_pStackPointer[0].var, m_pStackPointer[1].var, m_pStackPointer[2].var);
+                        m_ip++;
+                        break;
                     default:
                     {
                         const uint8_t *ip = m_ip - 1;
@@ -5175,17 +5684,17 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
                     {
                         // Unbox.any of a reference type is just a cast
                         CorInfoHelpFunc castingHelper = m_compHnd->getCastingHelper(&resolvedToken, true /* throwing */);
-                        
+
                         CORINFO_GENERICHANDLE_RESULT embedInfo;
                         InterpEmbedGenericResult result;
                         m_compHnd->embedGenericHandle(&resolvedToken, false, m_methodInfo->ftn, &embedInfo);
-                        
+
                         EmitPushHelperCall_2(castingHelper, embedInfo, m_pStackPointer[0].var, g_stackTypeFromInterpType[InterpTypeO], NULL);
                     }
                     else
                     {
                         CorInfoHelpFunc helpFunc = m_compHnd->getUnBoxHelper((CORINFO_CLASS_HANDLE)embedInfo.compileTimeHandle);
-                        
+
                         if (helpFunc == CORINFO_HELP_UNBOX)
                         {
                             EmitPushUnboxAny(embedInfo, m_pStackPointer[0].var, g_stackTypeFromInterpType[GetInterpType(m_compHnd->asCorInfoType(resolvedToken.hClass))], resolvedToken.hClass);
@@ -5226,9 +5735,9 @@ 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);
                     m_pLastNewIns->SetDVar(m_pStackPointer[-1].var);
                 }
@@ -5236,7 +5745,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);
@@ -5401,17 +5910,34 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
                 CorInfoType elemCorType = m_compHnd->asCorInfoType(elemClsHnd);
 
                 m_pStackPointer -= 2;
-                if (elemCorType == CORINFO_TYPE_CLASS)
+                if ((elemCorType == CORINFO_TYPE_CLASS) && !readonly)
                 {
-                    AddIns(INTOP_LDELEMA_REF);
-                    m_pLastNewIns->SetSVars2(m_pStackPointer[0].var, m_pStackPointer[1].var);
-                    PushInterpType(InterpTypeByRef, elemClsHnd);
-                    m_pLastNewIns->SetDVar(m_pStackPointer[-1].var);
-                    m_pLastNewIns->data[0] = m_compHnd->getClassSize(elemClsHnd);
-                    m_pLastNewIns->data[1] = GetDataItemIndex(elemClsHnd);
+                    CORINFO_GENERICHANDLE_RESULT embedInfo;
+                    m_compHnd->embedGenericHandle(&resolvedToken, false, m_methodInfo->ftn, &embedInfo);
+                    DeclarePointerIsClass((CORINFO_CLASS_HANDLE)embedInfo.compileTimeHandle);
+
+                    if (embedInfo.lookup.lookupKind.needsRuntimeLookup)
+                    {
+                        GenericHandleData handleData = GenericHandleToGenericHandleData(embedInfo);
+
+                        AddIns(INTOP_LDELEMA_REF_GENERIC);
+                        m_pLastNewIns->SetSVars3(m_pStackPointer[0].var, m_pStackPointer[1].var, handleData.genericVar);
+                        PushInterpType(InterpTypeByRef, elemClsHnd);
+                        m_pLastNewIns->SetDVar(m_pStackPointer[-1].var);
+                        m_pLastNewIns->data[0] = handleData.dataItemIndex;
+                    }
+                    else
+                    {
+                        AddIns(INTOP_LDELEMA_REF);
+                        m_pLastNewIns->SetSVars2(m_pStackPointer[0].var, m_pStackPointer[1].var);
+                        PushInterpType(InterpTypeByRef, elemClsHnd);
+                        m_pLastNewIns->SetDVar(m_pStackPointer[-1].var);
+                        m_pLastNewIns->data[0] = GetDataItemIndex(elemClsHnd);
+                    }
                 }
                 else
                 {
+                    readonly = false; // If readonly was set, it is no longer needed as its been handled.
                     AddIns(INTOP_LDELEMA);
                     m_pLastNewIns->SetSVars2(m_pStackPointer[0].var, m_pStackPointer[1].var);
                     PushInterpType(InterpTypeByRef, elemClsHnd);
@@ -5906,19 +6432,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_INDIRECT_HELPER_TAG)
-    {
-        helperAddr = (void*)(((size_t)helperDirectOrIndirect) & ~INTERP_INDIRECT_HELPER_TAG);
-        printf(" (indirect)");
-    }
-    else
-        printf(" (direct)");
+    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)
@@ -5965,7 +6500,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;
@@ -6009,21 +6544,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/coreclr/interpreter/compiler.h b/src/coreclr/interpreter/compiler.h
index a5cf428c876339..24381d5ec529c7 100644
--- a/src/coreclr/interpreter/compiler.h
+++ b/src/coreclr/interpreter/compiler.h
@@ -9,52 +9,9 @@
 #include "datastructs.h"
 #include "enum_class_flags.h"
 #include 
-
-#include "../../native/containers/dn-simdhash.h"
-#include "../../native/containers/dn-simdhash-specializations.h"
-#include "../../native/containers/dn-simdhash-utils.h"
-
-class dn_simdhash_ptr_ptr_holder
-{
-    dn_simdhash_ptr_ptr_t *Value;
-public:
-    dn_simdhash_ptr_ptr_holder() :
-        Value(nullptr)
-    {
-    }
-
-    dn_simdhash_ptr_ptr_t* GetValue()
-    {
-        if (!Value)
-            Value = dn_simdhash_ptr_ptr_new(0, nullptr);
-        return Value;
-    }
-
-    dn_simdhash_ptr_ptr_holder(const dn_simdhash_ptr_ptr_holder&) = delete;
-    dn_simdhash_ptr_ptr_holder& operator=(const dn_simdhash_ptr_ptr_holder&) = delete;
-    dn_simdhash_ptr_ptr_holder(dn_simdhash_ptr_ptr_holder&& other)
-    {
-        Value = other.Value;
-        other.Value = nullptr;
-    }
-    dn_simdhash_ptr_ptr_holder& operator=(dn_simdhash_ptr_ptr_holder&& other)
-    {
-        if (this != &other)
-        {
-            if (Value != nullptr)
-                dn_simdhash_free(Value);
-            Value = other.Value;
-            other.Value = nullptr;
-        }
-        return *this;
-    }
-
-    ~dn_simdhash_ptr_ptr_holder()
-    {
-        if (Value != nullptr)
-            dn_simdhash_free(Value);
-    }
-};
+#include "failures.h"
+#include "simdhash.h"
+#include "intrinsics.h"
 
 struct InterpException
 {
@@ -67,16 +24,6 @@ struct InterpException
     const CorJitResult m_result;
 };
 
-#if defined(__GNUC__) || defined(__clang__)
-#define INTERPRETER_NORETURN    __attribute__((noreturn))
-#else
-#define INTERPRETER_NORETURN    __declspec(noreturn)
-#endif
-
-INTERPRETER_NORETURN void NO_WAY(const char* message);
-INTERPRETER_NORETURN void BADCODE(const char* message);
-INTERPRETER_NORETURN void NOMEM();
-
 class InterpCompiler;
 
 class InterpDataItemIndexMap
@@ -531,7 +478,12 @@ class InterpCompiler
     CORINFO_CLASS_HANDLE m_classHnd;
     #ifdef DEBUG
     TArray m_methodName;
+#ifdef TARGET_WASM
+    // enable verbose output on wasm temporarily
+    bool m_verbose = true;
+#else
     bool m_verbose = false;
+#endif // TARGET_WASM
 
     const char* PointerIsClassHandle = (const char*)0x1;
     const char* PointerIsMethodHandle = (const char*)0x2;
@@ -540,18 +492,14 @@ class InterpCompiler
     dn_simdhash_ptr_ptr_holder m_pointerToNameMap;
     bool PointerInNameMap(void* ptr)
     {
-        if (dn_simdhash_ptr_ptr_try_get_value(m_pointerToNameMap.GetValue(), ptr, NULL))
-        {
-            return true;
-        }
-        return false;
+        return dn_simdhash_ptr_ptr_try_get_value(m_pointerToNameMap.GetValue(), ptr, NULL) != 0;
     }
     void AddPointerToNameMap(void* ptr, const char* name)
     {
-        dn_simdhash_ptr_ptr_try_add(m_pointerToNameMap.GetValue(), ptr, (void*)name);
+        checkNoError(dn_simdhash_ptr_ptr_try_add(m_pointerToNameMap.GetValue(), ptr, (void*)name));
     }
     void PrintNameInPointerMap(void* ptr);
-#endif
+#endif // DEBUG
 
     static int32_t InterpGetMovForType(InterpType interpType, bool signExtend);
 
@@ -584,7 +532,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);
@@ -753,7 +701,7 @@ class InterpCompiler
     void    EmitShiftOp(int32_t opBase);
     void    EmitCompareOp(int32_t opBase);
     void    EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool readonly, bool tailcall, bool newObj, bool isCalli);
-    bool    EmitCallIntrinsics(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO sig);
+    bool    EmitNamedIntrinsicCall(NamedIntrinsic ni, CORINFO_CLASS_HANDLE clsHnd, 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);
@@ -801,7 +749,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);
@@ -865,7 +813,10 @@ int32_t InterpDataItemIndexMap::GetDataItemIndexForT(const T& lookup)
     VarSizedDataWithPayload* pLookup = new(hashItemPayload) VarSizedDataWithPayload();
     memcpy(&pLookup->payload, &lookup, sizeof(T));
 
-    dn_simdhash_ght_insert(hash, (void*)pLookup, (void*)(size_t)dataItemIndex);
+    checkAddedNew(dn_simdhash_ght_try_insert(
+        hash, (void*)pLookup, (void*)(size_t)dataItemIndex, DN_SIMDHASH_INSERT_MODE_ENSURE_UNIQUE
+    ));
+
     return dataItemIndex;
 }
 
diff --git a/src/coreclr/interpreter/eeinterp.cpp b/src/coreclr/interpreter/eeinterp.cpp
index c449a53714949a..d0351825e06120 100644
--- a/src/coreclr/interpreter/eeinterp.cpp
+++ b/src/coreclr/interpreter/eeinterp.cpp
@@ -48,27 +48,55 @@ CorJitResult CILInterp::compileMethod(ICorJitInfo*         compHnd,
                                    uint32_t*            nativeSizeOfCode)
 {
 
-    bool doInterpret;
+    bool doInterpret = false;
+
+    if ((g_interpModule != NULL) && (methodInfo->scope == g_interpModule))
+        doInterpret = true;
 
-    if (g_interpModule != NULL)
-    {
-        if (methodInfo->scope == g_interpModule)
-            doInterpret = true;
-        else
-            doInterpret = false;
-    }
-    else
     {
-        const char *methodName = compHnd->getMethodNameFromMetadata(methodInfo->ftn, nullptr, nullptr, nullptr, 0);
+        switch (InterpConfig.InterpMode())
+        {
+            // 0: default, do not use interpreter except explicit opt-in via DOTNET_Interpreter
+            case 0:
+                break;
+
+            // 1: use interpreter for everything except (1) methods that have R2R compiled code and (2) all code in System.Private.CoreLib. All code in System.Private.CoreLib falls back to JIT if there is no R2R available for it.
+            case 1:
+            {
+                doInterpret = true;
+                const char *assemblyName = compHnd->getClassAssemblyName(compHnd->getMethodClass(methodInfo->ftn));
+                if (assemblyName && !strcmp(assemblyName, "System.Private.CoreLib"))
+                    doInterpret = false;
+                break;
+            }
+
+            // 2: use interpreter for everything except intrinsics. All intrinsics fallback to JIT. Implies DOTNET_ReadyToRun=0.
+            case 2:
+                doInterpret = !(compHnd->getMethodAttribs(methodInfo->ftn) & CORINFO_FLG_INTRINSIC);
+                break;
+
+            // 3: use interpreter for everything, the full interpreter-only mode, no fallbacks to R2R or JIT whatsoever. Implies DOTNET_ReadyToRun=0, DOTNET_EnableHWIntrinsic=0
+            case 3:
+                doInterpret = true;
+                break;
+
+            default:
+                NO_WAY("Unsupported value for DOTNET_InterpMode");
+                break;
+        }
+
 #ifdef TARGET_WASM
         // interpret everything on wasm
         doInterpret = true;
 #else
-        doInterpret = (InterpConfig.Interpreter().contains(compHnd, methodInfo->ftn, compHnd->getMethodClass(methodInfo->ftn), &methodInfo->args));
-#endif
-
-        if (doInterpret)
+        // NOTE: We do this check even if doInterpret==true in order to populate g_interpModule
+        const char *methodName = compHnd->getMethodNameFromMetadata(methodInfo->ftn, nullptr, nullptr, nullptr, 0);
+        if (InterpConfig.Interpreter().contains(compHnd, methodInfo->ftn, compHnd->getMethodClass(methodInfo->ftn), &methodInfo->args))
+        {
+            doInterpret = true;
             g_interpModule = methodInfo->scope;
+        }
+#endif
     }
 
     if (!doInterpret)
diff --git a/src/coreclr/interpreter/failures.h b/src/coreclr/interpreter/failures.h
new file mode 100644
index 00000000000000..9532b7bfba0c45
--- /dev/null
+++ b/src/coreclr/interpreter/failures.h
@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#ifndef _FAILURES_H_
+#define _FAILURES_H_
+
+#if defined(__GNUC__) || defined(__clang__)
+#define INTERPRETER_NORETURN    __attribute__((noreturn))
+#else
+#define INTERPRETER_NORETURN    __declspec(noreturn)
+#endif
+
+INTERPRETER_NORETURN void NO_WAY(const char* message);
+INTERPRETER_NORETURN void BADCODE(const char* message);
+INTERPRETER_NORETURN void NOMEM();
+
+#endif
diff --git a/src/coreclr/interpreter/interpconfigvalues.h b/src/coreclr/interpreter/interpconfigvalues.h
index 53ff3cbf7c491a..a76685a1fc7011 100644
--- a/src/coreclr/interpreter/interpconfigvalues.h
+++ b/src/coreclr/interpreter/interpconfigvalues.h
@@ -23,6 +23,11 @@ RELEASE_CONFIG_METHODSET(Interpreter, "Interpreter")
 CONFIG_METHODSET(InterpHalt, "InterpHalt");
 CONFIG_METHODSET(InterpDump, "InterpDump");
 CONFIG_INTEGER(InterpList, "InterpList", 0); // List the methods which are compiled by the interpreter JIT
+RELEASE_CONFIG_INTEGER(InterpMode, "InterpMode", 0); // Interpreter mode, one of the following:
+// 0: default, do not use interpreter except explicit opt-in via DOTNET_Interpreter
+// 1: use interpreter for everything except (1) methods that have R2R compiled code and (2) all code in System.Private.CoreLib. All code in System.Private.CoreLib falls back to JIT if there is no R2R available for it.
+// 2: use interpreter for everything except intrinsics. All intrinsics fallback to JIT. Implies DOTNET_ReadyToRun=0.
+// 3: use interpreter for everything, the full interpreter-only mode, no fallbacks to R2R or JIT whatsoever. Implies DOTNET_ReadyToRun=0, DOTNET_EnableHWIntrinsic=0
 
 #undef CONFIG_STRING
 #undef RELEASE_CONFIG_STRING
diff --git a/src/coreclr/interpreter/interpreter.h b/src/coreclr/interpreter/interpreter.h
index 90c62b98af6dfe..969a3c3c73ee0c 100644
--- a/src/coreclr/interpreter/interpreter.h
+++ b/src/coreclr/interpreter/interpreter.h
@@ -27,6 +27,7 @@
 
 #ifdef DEBUG
 extern "C" void assertAbort(const char* why, const char* file, unsigned line);
+
 #undef assert
 #define assert(p) (void)((p) || (assertAbort(#p, __FILE__, __LINE__), 0))
 #endif // DEBUG
diff --git a/src/coreclr/interpreter/interpretershared.h b/src/coreclr/interpreter/interpretershared.h
index 388fa3502e8065..d9338543d8ea24 100644
--- a/src/coreclr/interpreter/interpretershared.h
+++ b/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_INDIRECT_HELPER_TAG 1 // When a helper ftn's address is indirect we tag it with this tag bit
+struct InterpHelperData {
+    uint32_t addressDataItemIndex : 29;
+    uint32_t accessType : 3;
+};
 
 struct CallStubHeader;
 
@@ -32,8 +35,9 @@ struct InterpMethod
     // This stub is used for calling the interpreted method from JITted/AOTed code
     CallStubHeader *pCallStub;
     bool initLocals;
+    bool unmanagedCallersOnly;
 
-    InterpMethod(CORINFO_METHOD_HANDLE methodHnd, int32_t allocaSize, void** pDataItems, bool initLocals)
+    InterpMethod(CORINFO_METHOD_HANDLE methodHnd, int32_t allocaSize, void** pDataItems, bool initLocals, bool unmanagedCallersOnly)
     {
 #if DEBUG
         this->self = this;
@@ -42,6 +46,7 @@ struct InterpMethod
         this->allocaSize = allocaSize;
         this->pDataItems = pDataItems;
         this->initLocals = initLocals;
+        this->unmanagedCallersOnly = unmanagedCallersOnly;
         pCallStub = NULL;
     }
 
@@ -137,7 +142,7 @@ struct InterpGenericLookup
     void*                   signature;
 
     // Here is the helper you must call. It is one of CORINFO_HELP_RUNTIMEHANDLE_* helpers.
-    
+
     InterpGenericLookupType lookupType;
 
     // Number of indirections to get there
@@ -154,4 +159,11 @@ struct InterpGenericLookup
     uint16_t                offsets[InterpGenericLookup_MaxIndirections];
 };
 
+enum class PInvokeCallFlags : int32_t
+{
+    None = 0,
+    Indirect = 1 << 0, // The call target address is indirect
+    SuppressGCTransition = 1 << 1, // The pinvoke is marked by the SuppressGCTransition attribute
+};
+
 #endif
diff --git a/src/coreclr/interpreter/intops.def b/src/coreclr/interpreter/intops.def
index cf74817915eb50..95ea7a745e66f6 100644
--- a/src/coreclr/interpreter/intops.def
+++ b/src/coreclr/interpreter/intops.def
@@ -23,6 +23,7 @@ OPDEF(INTOP_LDC_R8, "ldc.r8", 4, 1, 0, InterpOpDouble)
 
 OPDEF(INTOP_LDPTR, "ldptr", 3, 1, 0, InterpOpLdPtr)
 OPDEF(INTOP_LDPTR_DEREF, "ldptr.deref", 3, 1, 0, InterpOpLdPtr)
+OPDEF(INTOP_NULLCHECK, "nullcheck", 2, 1, 0, InterpOpNoArgs)
 OPDEF(INTOP_NEWARR, "newarr", 5, 1, 1, InterpOpPointerHelperFtn)
 OPDEF(INTOP_NEWARR_GENERIC, "newarr.generic", 6, 1, 2, InterpOpGenericHelperFtn)
 OPDEF(INTOP_NEWMDARR, "newmdarr", 5, 1, 1, InterpOpPointerInt)
@@ -52,7 +53,8 @@ OPDEF(INTOP_STELEM_VT, "stelem.vt", 6, 0, 3, InterpOpTwoInts)
 OPDEF(INTOP_STELEM_VT_NOREF, "stelem.vt.noref", 5, 0, 3, InterpOpInt)
 
 OPDEF(INTOP_LDELEMA, "ldelema", 5, 1, 2, InterpOpInt)
-OPDEF(INTOP_LDELEMA_REF, "ldelema.ref", 6, 1, 2, InterpOpTwoInts)
+OPDEF(INTOP_LDELEMA_REF, "ldelema.ref", 5, 1, 2, InterpOpClassHandle)
+OPDEF(INTOP_LDELEMA_REF_GENERIC, "ldelema.ref.generic", 6, 1, 3, InterpOpGenericLookup)
 
 OPDEF(INTOP_MOV_I4_I1, "mov.i4.i1", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_MOV_I4_U1, "mov.i4.u1", 3, 1, 1, InterpOpNoArgs)
@@ -168,6 +170,7 @@ OPDEF(INTOP_CONV_R8_I4, "conv.r8.i4", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_R8_I8, "conv.r8.i8", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_R8_R4, "conv.r8.r4", 3, 1, 1, InterpOpNoArgs)
 
+OPDEF(INTOP_CONV_U8_U4, "conv.u8.u4", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_U8_R4, "conv.u8.r4", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_U8_R8, "conv.u8.r8", 3, 1, 1, InterpOpNoArgs)
 
@@ -191,20 +194,41 @@ OPDEF(INTOP_CONV_OVF_U2_I8, "conv.ovf.u2.i8", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_OVF_U2_R4, "conv.ovf.u2.r4", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_OVF_U2_R8, "conv.ovf.u2.r8", 3, 1, 1, InterpOpNoArgs)
 
+OPDEF(INTOP_CONV_OVF_I4_U4, "conv.ovf.i4.u4", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_OVF_I4_I8, "conv.ovf.i4.i8", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_OVF_I4_R4, "conv.ovf.i4.r4", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_OVF_I4_R8, "conv.ovf.i4.r8", 3, 1, 1, InterpOpNoArgs)
 
+OPDEF(INTOP_CONV_OVF_U4_I4, "conv.ovf.u4.i4", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_OVF_U4_I8, "conv.ovf.u4.i8", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_OVF_U4_R4, "conv.ovf.u4.r4", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_OVF_U4_R8, "conv.ovf.u4.r8", 3, 1, 1, InterpOpNoArgs)
 
+OPDEF(INTOP_CONV_OVF_I8_U8, "conv.ovf.i8.u8", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_OVF_I8_R4, "conv.ovf.i8.r4", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_OVF_I8_R8, "conv.ovf.i8.r8", 3, 1, 1, InterpOpNoArgs)
 
+OPDEF(INTOP_CONV_OVF_U8_I4, "conv.ovf.u8.i4", 3, 1, 1, InterpOpNoArgs)
+OPDEF(INTOP_CONV_OVF_U8_I8, "conv.ovf.u8.i8", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_OVF_U8_R4, "conv.ovf.u8.r4", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_CONV_OVF_U8_R8, "conv.ovf.u8.r8", 3, 1, 1, InterpOpNoArgs)
 
+OPDEF(INTOP_CONV_OVF_I1_U4, "conv.ovf.i1.u4", 3, 1, 1, InterpOpNoArgs)
+OPDEF(INTOP_CONV_OVF_I1_U8, "conv.ovf.i1.u8", 3, 1, 1, InterpOpNoArgs)
+
+OPDEF(INTOP_CONV_OVF_U1_U4, "conv.ovf.u1.u4", 3, 1, 1, InterpOpNoArgs)
+OPDEF(INTOP_CONV_OVF_U1_U8, "conv.ovf.u1.u8", 3, 1, 1, InterpOpNoArgs)
+
+OPDEF(INTOP_CONV_OVF_I2_U4, "conv.ovf.i2.u4", 3, 1, 1, InterpOpNoArgs)
+OPDEF(INTOP_CONV_OVF_I2_U8, "conv.ovf.i2.u8", 3, 1, 1, InterpOpNoArgs)
+
+OPDEF(INTOP_CONV_OVF_U2_U4, "conv.ovf.u2.u4", 3, 1, 1, InterpOpNoArgs)
+OPDEF(INTOP_CONV_OVF_U2_U8, "conv.ovf.u2.u8", 3, 1, 1, InterpOpNoArgs)
+
+OPDEF(INTOP_CONV_OVF_I4_U8, "conv.ovf.i4.u8", 3, 1, 1, InterpOpNoArgs)
+
+OPDEF(INTOP_CONV_OVF_U4_U8, "conv.ovf.u4.u8", 3, 1, 1, InterpOpNoArgs)
+
 OPDEF(INTOP_UNBOX_ANY, "unbox.any", 5, 1, 1, InterpOpHelperFtn) // [class handle data item] [helper data item]
 OPDEF(INTOP_UNBOX_ANY_GENERIC, "unbox.any.generic", 6, 1, 2, InterpOpGenericHelperFtn) // [class handle data item] [helper data item]
 // Unary operations end
@@ -333,8 +357,10 @@ OPDEF(INTOP_LDFLDA, "ldflda", 4, 1, 1, InterpOpInt)
 
 // Calls
 OPDEF(INTOP_CALL, "call", 4, 1, 1, InterpOpMethodHandle)
+OPDEF(INTOP_CALLDELEGATE, "call.delegate", 4, 1, 1, InterpOpMethodHandle)
 OPDEF(INTOP_CALLI, "calli", 5, 1, 2, InterpOpLdPtr)
 OPDEF(INTOP_CALLVIRT, "callvirt", 4, 1, 1, InterpOpMethodHandle)
+OPDEF(INTOP_CALL_PINVOKE, "call.pinvoke", 6, 1, 1, InterpOpMethodHandle) // inlined (no marshaling wrapper) pinvokes only
 OPDEF(INTOP_NEWOBJ, "newobj", 5, 1, 1, InterpOpMethodHandle)
 OPDEF(INTOP_NEWOBJ_GENERIC, "newobj.generic", 6, 1, 2, InterpOpMethodHandle)
 OPDEF(INTOP_NEWOBJ_VT, "newobj.vt", 5, 1, 1, InterpOpMethodHandle)
@@ -366,6 +392,7 @@ OPDEF(INTOP_GENERICLOOKUP, "generic", 4, 1, 1, InterpOpGenericLookup)
 OPDEF(INTOP_CALL_FINALLY, "call.finally", 2, 0, 0, InterpOpBranch)
 
 OPDEF(INTOP_ZEROBLK_IMM, "zeroblk.imm", 3, 0, 1, InterpOpInt)
+OPDEF(INTOP_CPBLK, "cpblk", 4, 0, 3, InterpOpNoArgs)
 OPDEF(INTOP_LOCALLOC, "localloc", 3, 1, 1, InterpOpNoArgs)
 OPDEF(INTOP_BREAKPOINT, "breakpoint", 1, 0, 0, InterpOpNoArgs)
 
@@ -375,11 +402,14 @@ OPDEF(INTOP_LEAVE_FILTER, "leavefilter", 2, 0, 1, InterpOpNoArgs)
 OPDEF(INTOP_LEAVE_CATCH, "leavecatch", 2, 0, 0, InterpOpBranch)
 OPDEF(INTOP_LOAD_EXCEPTION, "load.exception", 2, 1, 0, InterpOpNoArgs)
 
-OPDEF(INTOP_FAILFAST, "failfast", 1, 0, 0, InterpOpNoArgs)
-OPDEF(INTOP_GC_COLLECT, "gc.collect", 1, 0, 0, InterpOpNoArgs)
+OPDEF(INTOP_THROW_PNSE, "throw.pnse", 1, 0, 0, InterpOpNoArgs)
 
 OPDEF(INTOP_LOAD_FRAMEVAR, "load.framevar", 2, 1, 0, InterpOpNoArgs)
 
+// Intrinsics
+OPDEF(INTOP_COMPARE_EXCHANGE_I4, "compare.exchange.i4", 5, 1, 3, InterpOpNoArgs)
+OPDEF(INTOP_COMPARE_EXCHANGE_I8, "compare.exchange.i8", 5, 1, 3, InterpOpNoArgs)
+
 // All instructions after this point are IROPS, instructions that are not emitted/executed
 OPDEF(INTOP_NOP, "nop", 1, 0, 0, InterpOpNoArgs)
 OPDEF(INTOP_DEF, "def", 2, 1, 0, InterpOpNoArgs)
diff --git a/src/coreclr/interpreter/intrinsics.cpp b/src/coreclr/interpreter/intrinsics.cpp
new file mode 100644
index 00000000000000..af57f45c414d4a
--- /dev/null
+++ b/src/coreclr/interpreter/intrinsics.cpp
@@ -0,0 +1,125 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#include "interpreter.h"
+#include "intrinsics.h"
+
+#define HAS_PREFIX(haystack, needle) \
+    (strncmp(haystack, needle, strlen(needle)) == 0)
+
+NamedIntrinsic GetNamedIntrinsic(COMP_HANDLE compHnd, CORINFO_METHOD_HANDLE compMethod, CORINFO_METHOD_HANDLE method)
+{
+    const char* className = NULL;
+    const char* namespaceName = NULL;
+    const char* enclosingClassNames[2] = {nullptr};
+    const char* methodName = compHnd->getMethodNameFromMetadata(method, &className, &namespaceName, enclosingClassNames, ArrLen(enclosingClassNames));
+
+    // Array methods don't have metadata
+    if (!namespaceName)
+        return NI_Illegal;
+
+    if (!HAS_PREFIX(namespaceName, "System"))
+        return NI_Illegal;
+
+    if (!strcmp(namespaceName, "System"))
+    {
+        if (!strcmp(className, "Double") || !strcmp(className, "Single"))
+        {
+            if (!strcmp(methodName, "ConvertToIntegerNative"))
+                return NI_PRIMITIVE_ConvertToIntegerNative;
+            else if (!strcmp(methodName, "MultiplyAddEstimate"))
+                return NI_System_Math_MultiplyAddEstimate;
+        }
+        else if (!strcmp(className, "Math") || !strcmp(className, "MathF"))
+        {
+            if (!strcmp(methodName, "ReciprocalEstimate"))
+                return NI_System_Math_ReciprocalEstimate;
+            else if (!strcmp(methodName, "ReciprocalSqrtEstimate"))
+                return NI_System_Math_ReciprocalSqrtEstimate;
+        }
+    }
+    else if (!strcmp(namespaceName, "System.StubHelpers"))
+    {
+        if (!strcmp(className, "StubHelpers"))
+        {
+            if (!strcmp(methodName, "NextCallReturnAddress"))
+                return NI_System_StubHelpers_NextCallReturnAddress;
+        }
+    }
+    else if (!strcmp(namespaceName, "System.Numerics"))
+    {
+        if (!strcmp(className, "Vector") && !strcmp(methodName, "get_IsHardwareAccelerated"))
+            return NI_IsSupported_False;
+
+        // Fall back to managed implementation for everything else.
+        return NI_Illegal;
+    }
+    else if (!strcmp(namespaceName, "System.Runtime.Intrinsics"))
+    {
+        // Vector128 etc
+        if (HAS_PREFIX(className, "Vector") && !strcmp(methodName, "get_IsHardwareAccelerated"))
+            return NI_IsSupported_False;
+
+        // Fall back to managed implementation for everything else.
+        return NI_Illegal;
+    }
+    else if (HAS_PREFIX(namespaceName, "System.Runtime.Intrinsics"))
+    {
+        // Architecture-specific intrinsics.
+        if (!strcmp(methodName, "get_IsSupported"))
+            return NI_IsSupported_False;
+
+        // Every intrinsic except IsSupported is PNSE in interpreted-only mode.
+        return NI_Throw_PlatformNotSupportedException;
+    }
+    else if (HAS_PREFIX(namespaceName, "System.Runtime"))
+    {
+        if (!strcmp(namespaceName, "System.Runtime.CompilerServices"))
+        {
+            if (!strcmp(className, "StaticsHelpers"))
+            {
+                if (!strcmp(methodName, "VolatileReadAsByref"))
+                    return NI_System_Runtime_CompilerServices_StaticsHelpers_VolatileReadAsByref;
+            }
+            else if (!strcmp(className, "RuntimeHelpers"))
+            {
+                if (!strcmp(methodName, "IsReferenceOrContainsReferences"))
+                    return NI_System_Runtime_CompilerServices_RuntimeHelpers_IsReferenceOrContainsReferences;
+                else if (!strcmp(methodName, "GetMethodTable"))
+                    return NI_System_Runtime_CompilerServices_RuntimeHelpers_GetMethodTable;
+            }
+        }
+        else if (!strcmp(namespaceName, "System.Runtime.InteropServices"))
+        {
+            if (!strcmp(className, "MemoryMarshal"))
+            {
+                if (!strcmp(methodName, "GetArrayDataReference"))
+                    return NI_System_Runtime_InteropService_MemoryMarshal_GetArrayDataReference;
+            }
+        }
+    }
+    else if (!strcmp(namespaceName, "System.Threading"))
+    {
+        if (!strcmp(className, "Interlocked"))
+        {
+            if (!strcmp(methodName, "CompareExchange"))
+                return NI_System_Threading_Interlocked_CompareExchange;
+            else if (!strcmp(methodName, "MemoryBarrier"))
+                return NI_System_Threading_Interlocked_MemoryBarrier;
+        }
+        else if (!strcmp(className, "Thread"))
+        {
+            if (!strcmp(methodName, "FastPollGC"))
+                return NI_System_Threading_Thread_FastPollGC;
+        }
+        else if (!strcmp(className, "Volatile"))
+        {
+            if (!strcmp(methodName, "ReadBarrier"))
+                return NI_System_Threading_Volatile_ReadBarrier;
+            else if (!strcmp(methodName, "WriteBarrier"))
+                return NI_System_Threading_Volatile_WriteBarrier;
+        }
+    }
+
+    return NI_Illegal;
+}
diff --git a/src/coreclr/interpreter/intrinsics.h b/src/coreclr/interpreter/intrinsics.h
new file mode 100644
index 00000000000000..0fb29eb417aaa6
--- /dev/null
+++ b/src/coreclr/interpreter/intrinsics.h
@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#ifndef __INTERPRETER_INTRINSICS_H__
+#define __INTERPRETER_INTRINSICS_H__
+
+#include "../jit/namedintrinsiclist.h"
+
+NamedIntrinsic GetNamedIntrinsic(COMP_HANDLE compHnd, CORINFO_METHOD_HANDLE compMethod, CORINFO_METHOD_HANDLE method);
+
+template 
+inline constexpr unsigned ArrLen(T (&)[size])
+{
+    return size;
+}
+
+#endif // __INTERPRETER_INTRINSICS_H__
diff --git a/src/coreclr/interpreter/simdhash.h b/src/coreclr/interpreter/simdhash.h
new file mode 100644
index 00000000000000..6396e4fb325f2b
--- /dev/null
+++ b/src/coreclr/interpreter/simdhash.h
@@ -0,0 +1,72 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#ifndef _SIMDHASH_H_
+#define _SIMDHASH_H_
+
+#include "failures.h"
+#include "../../native/containers/dn-simdhash.h"
+#include "../../native/containers/dn-simdhash-specializations.h"
+#include "../../native/containers/dn-simdhash-utils.h"
+
+class dn_simdhash_ptr_ptr_holder
+{
+    dn_simdhash_ptr_ptr_t *Value;
+public:
+    dn_simdhash_ptr_ptr_holder() :
+        Value(nullptr)
+    {
+    }
+
+    dn_simdhash_ptr_ptr_t* GetValue()
+    {
+        if (!Value)
+            Value = dn_simdhash_ptr_ptr_new(0, nullptr);
+        return Value;
+    }
+
+    dn_simdhash_ptr_ptr_holder(const dn_simdhash_ptr_ptr_holder&) = delete;
+    dn_simdhash_ptr_ptr_holder& operator=(const dn_simdhash_ptr_ptr_holder&) = delete;
+    dn_simdhash_ptr_ptr_holder(dn_simdhash_ptr_ptr_holder&& other)
+    {
+        Value = other.Value;
+        other.Value = nullptr;
+    }
+    dn_simdhash_ptr_ptr_holder& operator=(dn_simdhash_ptr_ptr_holder&& other)
+    {
+        if (this != &other)
+        {
+            if (Value != nullptr)
+                dn_simdhash_free(Value);
+            Value = other.Value;
+            other.Value = nullptr;
+        }
+        return *this;
+    }
+
+    ~dn_simdhash_ptr_ptr_holder()
+    {
+        if (Value != nullptr)
+            dn_simdhash_free(Value);
+    }
+};
+
+// Asserts that no error occurred during a simdhash add, but does not mind if no new item was inserted
+inline void checkNoError(dn_simdhash_add_result result)
+{
+    if (result == DN_SIMDHASH_OUT_OF_MEMORY)
+        NOMEM();
+    else if (result < 0)
+        NO_WAY("Internal error in simdhash");
+}
+
+// Asserts that a new item was successfully inserted into the simdhash
+inline void checkAddedNew(dn_simdhash_add_result result)
+{
+    if (result == DN_SIMDHASH_OUT_OF_MEMORY)
+        NOMEM();
+    else if (result != DN_SIMDHASH_ADD_INSERTED)
+        NO_WAY("Failed to add new item into simdhash");
+}
+
+#endif // _SIMDHASH_H_
diff --git a/src/coreclr/interpreter/stackmap.cpp b/src/coreclr/interpreter/stackmap.cpp
index 340b5dbb7fce76..525115f3ca6e79 100644
--- a/src/coreclr/interpreter/stackmap.cpp
+++ b/src/coreclr/interpreter/stackmap.cpp
@@ -6,15 +6,16 @@
 #include "interpreter.h"
 #include "stackmap.h"
 
-#include "../../native/containers/dn-simdhash.h"
-#include "../../native/containers/dn-simdhash-specializations.h"
-#include "../../native/containers/dn-simdhash-utils.h"
-
-extern "C" void assertAbort(const char* why, const char* file, unsigned line);
+#include "failures.h"
+#include "simdhash.h"
 
 void
 dn_simdhash_assert_fail (const char* file, int line, const char* condition) {
+#if DEBUG
     assertAbort(condition, file, line);
+#else
+    NO_WAY(condition);
+#endif
 }
 
 thread_local dn_simdhash_ptr_ptr_t *t_sharedStackMapLookup = nullptr;
@@ -24,10 +25,13 @@ InterpreterStackMap* GetInterpreterStackMap(ICorJitInfo* jitInfo, CORINFO_CLASS_
     InterpreterStackMap* result = nullptr;
     if (!t_sharedStackMapLookup)
         t_sharedStackMapLookup = dn_simdhash_ptr_ptr_new(0, nullptr);
+    if (!t_sharedStackMapLookup)
+        NOMEM();
+
     if (!dn_simdhash_ptr_ptr_try_get_value(t_sharedStackMapLookup, classHandle, (void **)&result))
     {
         result = new InterpreterStackMap(jitInfo, classHandle);
-        dn_simdhash_ptr_ptr_try_add(t_sharedStackMapLookup, classHandle, result);
+        checkAddedNew(dn_simdhash_ptr_ptr_try_add(t_sharedStackMapLookup, classHandle, result));
     }
     return result;
 }
diff --git a/src/coreclr/jit/CMakeLists.txt b/src/coreclr/jit/CMakeLists.txt
index a26bc8a5b64a95..f390f36b2134ed 100644
--- a/src/coreclr/jit/CMakeLists.txt
+++ b/src/coreclr/jit/CMakeLists.txt
@@ -304,6 +304,7 @@ set( JIT_HEADERS
   compilerbitsettraits.hpp
   compmemkind.h
   compphases.h
+  handlekinds.h
   dataflow.h
   debuginfo.h
   decomposelongs.h
diff --git a/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/coreclr/jit/ICorJitInfo_names_generated.h
index e8e089f0b1dd59..1e455eb98bc74e 100644
--- a/src/coreclr/jit/ICorJitInfo_names_generated.h
+++ b/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)
@@ -147,7 +146,6 @@ DEF_CLR_API(getLocationOfThisType)
 DEF_CLR_API(getAddressOfPInvokeTarget)
 DEF_CLR_API(GetCookieForPInvokeCalliSig)
 DEF_CLR_API(GetCookieForInterpreterCalliSig)
-DEF_CLR_API(canGetCookieForPInvokeCalliSig)
 DEF_CLR_API(getJustMyCodeHandle)
 DEF_CLR_API(GetProfilingHandle)
 DEF_CLR_API(getCallInfo)
@@ -155,7 +153,6 @@ DEF_CLR_API(getStaticFieldContent)
 DEF_CLR_API(getObjectContent)
 DEF_CLR_API(getStaticFieldCurrentClass)
 DEF_CLR_API(getVarArgsHandle)
-DEF_CLR_API(canGetVarArgsHandle)
 DEF_CLR_API(constructStringLiteral)
 DEF_CLR_API(emptyStringLiteral)
 DEF_CLR_API(getFieldThreadLocalStoreID)
diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp
index c2a8418e30256d..71dc8eaf7119af 100644
--- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp
+++ b/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)
 {
@@ -1406,15 +1396,6 @@ void* WrapICorJitInfo::GetCookieForInterpreterCalliSig(
     return temp;
 }
 
-bool WrapICorJitInfo::canGetCookieForPInvokeCalliSig(
-          CORINFO_SIG_INFO* szMetaSig)
-{
-    API_ENTER(canGetCookieForPInvokeCalliSig);
-    bool temp = wrapHnd->canGetCookieForPInvokeCalliSig(szMetaSig);
-    API_LEAVE(canGetCookieForPInvokeCalliSig);
-    return temp;
-}
-
 CORINFO_JUST_MY_CODE_HANDLE WrapICorJitInfo::getJustMyCodeHandle(
           CORINFO_METHOD_HANDLE method,
           CORINFO_JUST_MY_CODE_HANDLE** ppIndirection)
@@ -1484,23 +1465,15 @@ CORINFO_CLASS_HANDLE WrapICorJitInfo::getStaticFieldCurrentClass(
 
 CORINFO_VARARGS_HANDLE WrapICorJitInfo::getVarArgsHandle(
           CORINFO_SIG_INFO* pSig,
+          CORINFO_METHOD_HANDLE methHnd,
           void** ppIndirection)
 {
     API_ENTER(getVarArgsHandle);
-    CORINFO_VARARGS_HANDLE temp = wrapHnd->getVarArgsHandle(pSig, ppIndirection);
+    CORINFO_VARARGS_HANDLE temp = wrapHnd->getVarArgsHandle(pSig, methHnd, ppIndirection);
     API_LEAVE(getVarArgsHandle);
     return temp;
 }
 
-bool WrapICorJitInfo::canGetVarArgsHandle(
-          CORINFO_SIG_INFO* pSig)
-{
-    API_ENTER(canGetVarArgsHandle);
-    bool temp = wrapHnd->canGetVarArgsHandle(pSig);
-    API_LEAVE(canGetVarArgsHandle);
-    return temp;
-}
-
 InfoAccessType WrapICorJitInfo::constructStringLiteral(
           CORINFO_MODULE_HANDLE module,
           mdToken metaTok,
diff --git a/src/coreclr/jit/alloc.h b/src/coreclr/jit/alloc.h
index 8899b87ad35523..5d9253cf5d1c18 100644
--- a/src/coreclr/jit/alloc.h
+++ b/src/coreclr/jit/alloc.h
@@ -316,6 +316,9 @@ class CompIAllocator : public IAllocator
     // Frees the block of memory pointed to by p.
     virtual void Free(void* p) override
     {
+        if (p == &m_zeroLenAllocTarg)
+            return;
+
         m_alloc.deallocate(p);
     }
 };
diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp
index b63ea4084e11d8..c30f63f7be3281 100644
--- a/src/coreclr/jit/assertionprop.cpp
+++ b/src/coreclr/jit/assertionprop.cpp
@@ -1232,9 +1232,18 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1, GenTree* op2, optAsser
                     if (op2->OperIs(GT_CNS_INT))
                     {
                         ssize_t iconVal = op2->AsIntCon()->IconValue();
-                        if (varTypeIsSmall(lclVar) && op1->OperIs(GT_STORE_LCL_VAR))
+                        if (varTypeIsSmall(lclVar))
                         {
-                            iconVal = optCastConstantSmall(iconVal, lclVar->TypeGet());
+                            ssize_t truncatedIconVal = optCastConstantSmall(iconVal, lclVar->TypeGet());
+                            if (!op1->OperIs(GT_STORE_LCL_VAR) && (truncatedIconVal != iconVal))
+                            {
+                                // This assertion would be saying that a small local is equal to a value
+                                // outside its range. It means this block is unreachable. Avoid creating
+                                // such impossible assertions which can hit assertions in other places.
+                                goto DONE_ASSERTION;
+                            }
+
+                            iconVal = truncatedIconVal;
                             if (!optLocalAssertionProp)
                             {
                                 assertion.op2.vn = vnStore->VNForIntCon(static_cast(iconVal));
@@ -2665,7 +2674,10 @@ GenTree* Compiler::optVNBasedFoldExpr_Call(BasicBlock* block, GenTree* parent, G
                 if (castFrom != NO_CLASS_HANDLE)
                 {
                     CORINFO_CLASS_HANDLE castTo = gtGetHelperArgClassHandle(castClsArg);
-                    if (info.compCompHnd->compareTypesForCast(castFrom, castTo) == TypeCompareState::Must)
+                    // Constant prop may fail to propagate compile time class handles, so verify we have
+                    // a handle before invoking the runtime.
+                    if ((castTo != NO_CLASS_HANDLE) &&
+                        info.compCompHnd->compareTypesForCast(castFrom, castTo) == TypeCompareState::Must)
                     {
                         // if castObjArg is not simple, we replace the arg with a temp assignment and
                         // continue using that temp - it allows us reliably extract all side effects
@@ -4166,7 +4178,7 @@ AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP as
 
         // Look for matching exact type assertions based on vtable accesses. E.g.:
         //
-        //   op1:       VNF_InvariantLoad(myObj) or in other words: a vtable access
+        //   op1:       VNF_InvariantNonNullLoad(myObj) or in other words: a vtable access
         //   op2:       'MyType' class handle
         //   Assertion: 'myObj's type is exactly MyType
         //
@@ -4175,7 +4187,7 @@ AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP as
         {
             VNFuncApp funcApp;
             if (vnStore->GetVNFunc(vnStore->VNConservativeNormalValue(op1->gtVNPair), &funcApp) &&
-                (funcApp.m_func == VNF_InvariantLoad) && (curAssertion->op1.vn == funcApp.m_args[0]))
+                (funcApp.m_func == VNF_InvariantNonNullLoad) && (curAssertion->op1.vn == funcApp.m_args[0]))
             {
                 return assertionIndex;
             }
@@ -5630,8 +5642,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)
@@ -5649,9 +5661,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++)
     {
@@ -5663,14 +5675,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/coreclr/jit/async.cpp b/src/coreclr/jit/async.cpp
index e72f1fe7007afa..e685e632aef289 100644
--- a/src/coreclr/jit/async.cpp
+++ b/src/coreclr/jit/async.cpp
@@ -6,11 +6,11 @@
 // machines. The following key operations are performed:
 //
 // 1. Early, after import but before inlining: for async calls that require
-//    ExecutionContext save/restore semantics, ExecutionContext capture and
+//    ExecutionContext/SynchronizationContext save/restore semantics, capture and
 //    restore calls are inserted around the async call site. This ensures proper
 //    context flow across await boundaries when the continuation may run on
-//    different threads or synchronization contexts. The captured ExecutionContext
-//    is stored in a temporary local and restored after the async call completes,
+//    different threads or synchronization contexts. The captured contexts
+//    are stored in temporary locals and restored after the async call completes,
 //    with special handling for calls inside try regions using try-finally blocks.
 //
 // Later, right before lowering the actual transformation to a state machine is
@@ -47,7 +47,7 @@
 
 //------------------------------------------------------------------------
 // Compiler::SaveAsyncContexts:
-//   Insert code to save and restore ExecutionContext around async call sites.
+//   Insert code to save and restore contexts around async call sites.
 //
 // Returns:
 //   Suitable phase status.
@@ -80,53 +80,75 @@ PhaseStatus Compiler::SaveAsyncContexts()
                 tree = tree->AsLclVarCommon()->Data();
             }
 
-            if (!tree->IsCall() || !tree->AsCall()->IsAsyncAndAlwaysSavesAndRestoresExecutionContext())
+            if (!tree->IsCall())
             {
                 ValidateNoAsyncSavesNecessaryInStatement(stmt);
                 continue;
             }
 
             GenTreeCall* call = tree->AsCall();
+            if (!call->IsAsync())
+            {
+                ValidateNoAsyncSavesNecessaryInStatement(stmt);
+                continue;
+            }
 
-            unsigned lclNum = lvaGrabTemp(false DEBUGARG("ExecutionContext for SaveAndRestore async call"));
+            const AsyncCallInfo& asyncCallInfo = call->GetAsyncInfo();
 
-            JITDUMP("Saving ExecutionContext in V%02u around [%06u]\n", lclNum, call->gtTreeID);
+            // Currently we always expect that ExecutionContext and
+            // SynchronizationContext correlate about their save/restore
+            // behavior.
+            assert((asyncCallInfo.ExecutionContextHandling == ExecutionContextHandling::SaveAndRestore) ==
+                   asyncCallInfo.SaveAndRestoreSynchronizationContextField);
 
-            CORINFO_ASYNC_INFO* asyncInfo = eeGetAsyncInfo();
+            if (asyncCallInfo.ExecutionContextHandling != ExecutionContextHandling::SaveAndRestore)
+            {
+                continue;
+            }
 
-            GenTreeCall*      capture = gtNewCallNode(CT_USER_FUNC, asyncInfo->captureExecutionContextMethHnd, TYP_REF);
-            CORINFO_CALL_INFO callInfo = {};
-            callInfo.hMethod           = capture->gtCallMethHnd;
-            callInfo.methodFlags       = info.compCompHnd->getMethodAttribs(callInfo.hMethod);
-            impMarkInlineCandidate(capture, MAKE_METHODCONTEXT(callInfo.hMethod), false, &callInfo, compInlineContext);
+            unsigned suspendedLclNum =
+                lvaGrabTemp(false DEBUGARG(printfAlloc("Suspended indicator for [%06u]", dspTreeID(call))));
+            unsigned execCtxLclNum =
+                lvaGrabTemp(false DEBUGARG(printfAlloc("ExecutionContext for [%06u]", dspTreeID(call))));
+            unsigned syncCtxLclNum =
+                lvaGrabTemp(false DEBUGARG(printfAlloc("SynchronizationContext for [%06u]", dspTreeID(call))));
 
-            if (capture->IsInlineCandidate())
-            {
-                Statement* captureStmt = fgNewStmtFromTree(capture);
+            LclVarDsc* suspendedLclDsc     = lvaGetDesc(suspendedLclNum);
+            suspendedLclDsc->lvType        = TYP_UBYTE;
+            suspendedLclDsc->lvHasLdAddrOp = true;
 
-                GenTreeRetExpr* retExpr = gtNewInlineCandidateReturnExpr(capture, TYP_REF);
+            LclVarDsc* execCtxLclDsc     = lvaGetDesc(execCtxLclNum);
+            execCtxLclDsc->lvType        = TYP_REF;
+            execCtxLclDsc->lvHasLdAddrOp = true;
 
-                capture->GetSingleInlineCandidateInfo()->retExpr = retExpr;
-                GenTree*   storeCapture                          = gtNewTempStore(lclNum, retExpr);
-                Statement* storeCaptureStmt                      = fgNewStmtFromTree(storeCapture);
+            LclVarDsc* syncCtxLclDsc     = lvaGetDesc(syncCtxLclNum);
+            syncCtxLclDsc->lvType        = TYP_REF;
+            syncCtxLclDsc->lvHasLdAddrOp = true;
 
-                fgInsertStmtBefore(curBB, stmt, captureStmt);
-                fgInsertStmtBefore(curBB, stmt, storeCaptureStmt);
+            call->asyncInfo->SynchronizationContextLclNum = syncCtxLclNum;
 
-                JITDUMP("Inserted capture:\n");
-                DISPSTMT(captureStmt);
-                DISPSTMT(storeCaptureStmt);
-            }
-            else
-            {
-                GenTree*   storeCapture     = gtNewTempStore(lclNum, capture);
-                Statement* storeCaptureStmt = fgNewStmtFromTree(storeCapture);
+            call->gtArgs.PushBack(this, NewCallArg::Primitive(gtNewLclAddrNode(suspendedLclNum, 0))
+                                            .WellKnown(WellKnownArg::AsyncSuspendedIndicator));
 
-                fgInsertStmtBefore(curBB, stmt, storeCaptureStmt);
+            JITDUMP("Saving contexts around [%06u], ExecutionContext = V%02u, SynchronizationContext = V%02u\n",
+                    call->gtTreeID, execCtxLclNum, syncCtxLclNum);
 
-                JITDUMP("Inserted capture:\n");
-                DISPSTMT(storeCaptureStmt);
-            }
+            CORINFO_ASYNC_INFO* asyncInfo = eeGetAsyncInfo();
+
+            GenTreeCall* capture = gtNewCallNode(CT_USER_FUNC, asyncInfo->captureContextsMethHnd, TYP_VOID);
+            capture->gtArgs.PushFront(this, NewCallArg::Primitive(gtNewLclAddrNode(syncCtxLclNum, 0)));
+            capture->gtArgs.PushFront(this, NewCallArg::Primitive(gtNewLclAddrNode(execCtxLclNum, 0)));
+
+            CORINFO_CALL_INFO callInfo = {};
+            callInfo.hMethod           = capture->gtCallMethHnd;
+            callInfo.methodFlags       = info.compCompHnd->getMethodAttribs(callInfo.hMethod);
+            impMarkInlineCandidate(capture, MAKE_METHODCONTEXT(callInfo.hMethod), false, &callInfo, compInlineContext);
+
+            Statement* captureStmt = fgNewStmtFromTree(capture);
+            fgInsertStmtBefore(curBB, stmt, captureStmt);
+
+            JITDUMP("Inserted capture:\n");
+            DISPSTMT(captureStmt);
 
             BasicBlock* restoreBB        = curBB;
             Statement*  restoreAfterStmt = stmt;
@@ -150,8 +172,10 @@ PhaseStatus Compiler::SaveAsyncContexts()
 #endif
             }
 
-            GenTreeCall* restore = gtNewCallNode(CT_USER_FUNC, asyncInfo->restoreExecutionContextMethHnd, TYP_VOID);
-            restore->gtArgs.PushFront(this, NewCallArg::Primitive(gtNewLclVarNode(lclNum)));
+            GenTreeCall* restore = gtNewCallNode(CT_USER_FUNC, asyncInfo->restoreContextsMethHnd, TYP_VOID);
+            restore->gtArgs.PushFront(this, NewCallArg::Primitive(gtNewLclVarNode(syncCtxLclNum)));
+            restore->gtArgs.PushFront(this, NewCallArg::Primitive(gtNewLclVarNode(execCtxLclNum)));
+            restore->gtArgs.PushFront(this, NewCallArg::Primitive(gtNewLclVarNode(suspendedLclNum)));
 
             callInfo             = {};
             callInfo.hMethod     = restore->gtCallMethHnd;
@@ -290,12 +314,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));
@@ -362,7 +385,8 @@ class AsyncLiveness
     void StartBlock(BasicBlock* block);
     void Update(GenTree* node);
     bool IsLive(unsigned lclNum);
-    void GetLiveLocals(jitstd::vector& liveLocals, unsigned fullyDefinedRetBufLcl);
+    template 
+    void GetLiveLocals(jitstd::vector& liveLocals, Functor includeLocal);
 
 private:
     bool IsLocalCaptureUnnecessary(unsigned lclNum);
@@ -540,14 +564,15 @@ bool AsyncLiveness::IsLive(unsigned lclNum)
 //   Get live locals that should be captured at this point.
 //
 // Parameters:
-//   liveLocals            - Vector to add live local information into
-//   fullyDefinedRetBufLcl - Local to skip even if live
+//   liveLocals   - Vector to add live local information into
+//   includeLocal - Functor to check if a local should be included
 //
-void AsyncLiveness::GetLiveLocals(jitstd::vector& liveLocals, unsigned fullyDefinedRetBufLcl)
+template 
+void AsyncLiveness::GetLiveLocals(jitstd::vector& liveLocals, Functor includeLocal)
 {
     for (unsigned lclNum = 0; lclNum < m_numVars; lclNum++)
     {
-        if ((lclNum != fullyDefinedRetBufLcl) && IsLive(lclNum))
+        if (includeLocal(lclNum) && IsLive(lclNum))
         {
             liveLocals.push_back(LiveLocalInfo(lclNum));
         }
@@ -777,6 +802,8 @@ void AsyncTransformation::Transform(
 
     ContinuationLayout layout = LayOutContinuation(block, call, liveLocals);
 
+    ClearSuspendedIndicator(block, call);
+
     CallDefinitionInfo callDefInfo = CanonicalizeCallDefinition(block, call, life);
 
     unsigned stateNum = (unsigned)m_resumptionBBs.size();
@@ -784,7 +811,7 @@ void AsyncTransformation::Transform(
 
     BasicBlock* suspendBB = CreateSuspension(block, call, stateNum, life, layout);
 
-    CreateCheckAndSuspendAfterCall(block, callDefInfo, life, suspendBB, remainder);
+    CreateCheckAndSuspendAfterCall(block, call, callDefInfo, life, suspendBB, remainder);
 
     BasicBlock* resumeBB = CreateResumption(block, *remainder, call, callDefInfo, stateNum, layout);
 
@@ -809,27 +836,30 @@ void AsyncTransformation::CreateLiveSetForSuspension(BasicBlock*
                                                      AsyncLiveness&                  life,
                                                      jitstd::vector&  liveLocals)
 {
-    unsigned fullyDefinedRetBufLcl = BAD_VAR_NUM;
-    CallArg* retbufArg             = call->gtArgs.GetRetBufferArg();
-    if (retbufArg != nullptr)
-    {
-        GenTree* retbuf = retbufArg->GetNode();
-        if (retbuf->IsLclVarAddr())
+    SmallHashTable excludedLocals(m_comp->getAllocator(CMK_Async));
+
+    auto visitDef = [&](const LocalDef& def) {
+        if (def.IsEntire)
         {
-            LclVarDsc*   dsc       = m_comp->lvaGetDesc(retbuf->AsLclVarCommon());
-            ClassLayout* defLayout = m_comp->typGetObjLayout(call->gtRetClsHnd);
-            if (defLayout->GetSize() == dsc->lvExactSize())
-            {
-                // This call fully defines this retbuf. There is no need to
-                // consider it live across the call since it is going to be
-                // overridden anyway.
-                fullyDefinedRetBufLcl = retbuf->AsLclVarCommon()->GetLclNum();
-                JITDUMP("  V%02u is a fully defined retbuf and will not be considered live\n", fullyDefinedRetBufLcl);
-            }
+            JITDUMP("  V%02u is fully defined and will not be considered live\n", def.Def->GetLclNum());
+            excludedLocals.AddOrUpdate(def.Def->GetLclNum(), true);
         }
+        return GenTree::VisitResult::Continue;
+    };
+
+    call->VisitLocalDefs(m_comp, visitDef);
+
+    const AsyncCallInfo& asyncInfo = call->GetAsyncInfo();
+
+    if (asyncInfo.SynchronizationContextLclNum != BAD_VAR_NUM)
+    {
+        // This one is only live on the synchronous path, which liveness cannot prove
+        excludedLocals.AddOrUpdate(asyncInfo.SynchronizationContextLclNum, true);
     }
 
-    life.GetLiveLocals(liveLocals, fullyDefinedRetBufLcl);
+    life.GetLiveLocals(liveLocals, [&](unsigned lclNum) {
+        return !excludedLocals.Contains(lclNum);
+    });
     LiftLIREdges(block, defs, liveLocals);
 
 #ifdef DEBUG
@@ -1040,6 +1070,13 @@ ContinuationLayout AsyncTransformation::LayOutContinuation(BasicBlock*
                 block->getTryIndex(), layout.ExceptionGCDataIndex);
     }
 
+    if (call->GetAsyncInfo().ContinuationContextHandling == ContinuationContextHandling::ContinueOnCapturedContext)
+    {
+        layout.ContinuationContextGCDataIndex = layout.GCRefsCount++;
+        JITDUMP("  Continuation continues on captured context; context will be at GC@+%02u in GC data\n",
+                layout.ContinuationContextGCDataIndex);
+    }
+
     if (call->GetAsyncInfo().ExecutionContextHandling == ExecutionContextHandling::AsyncSaveAndRestore)
     {
         layout.ExecContextGCDataIndex = layout.GCRefsCount++;
@@ -1074,6 +1111,80 @@ ContinuationLayout AsyncTransformation::LayOutContinuation(BasicBlock*
     return layout;
 }
 
+//------------------------------------------------------------------------
+// AsyncTransformation::ClearSuspendedIndicator:
+//   Generate IR to clear the value of the suspended indicator local.
+//
+// Parameters:
+//   block - Block to generate IR into
+//   call  - The async call (not contained in "block")
+//
+void AsyncTransformation::ClearSuspendedIndicator(BasicBlock* block, GenTreeCall* call)
+{
+    CallArg* suspendedArg = call->gtArgs.FindWellKnownArg(WellKnownArg::AsyncSuspendedIndicator);
+    if (suspendedArg == nullptr)
+    {
+        return;
+    }
+
+    GenTree* suspended = suspendedArg->GetNode();
+    if (!suspended->IsLclVarAddr() &&
+        (!suspended->OperIs(GT_LCL_VAR) || m_comp->lvaVarAddrExposed(suspended->AsLclVarCommon()->GetLclNum())))
+    {
+        // We will need a second use of this, so spill to a local
+        LIR::Use use(LIR::AsRange(block), &suspendedArg->NodeRef(), call);
+        use.ReplaceWithLclVar(m_comp);
+        suspended = use.Def();
+    }
+
+    GenTree* value = m_comp->gtNewIconNode(0);
+    GenTree* storeSuspended =
+        m_comp->gtNewStoreValueNode(TYP_UBYTE, m_comp->gtCloneExpr(suspended), value, GTF_IND_NONFAULTING);
+
+    LIR::AsRange(block).InsertBefore(call, LIR::SeqTree(m_comp, storeSuspended));
+}
+
+//------------------------------------------------------------------------
+// AsyncTransformation::SetSuspendedIndicator:
+//   Generate IR to set the value of the suspended indicator local, and remove
+//   the argument from the call.
+//
+// Parameters:
+//   block     - Block to generate IR into
+//   callBlock - Block containing the call
+//   call      - The async call
+//
+void AsyncTransformation::SetSuspendedIndicator(BasicBlock* block, BasicBlock* callBlock, GenTreeCall* call)
+{
+    CallArg* suspendedArg = call->gtArgs.FindWellKnownArg(WellKnownArg::AsyncSuspendedIndicator);
+    if (suspendedArg == nullptr)
+    {
+        return;
+    }
+
+    GenTree* suspended = suspendedArg->GetNode();
+    assert(suspended->IsLclVarAddr() || suspended->OperIs(GT_LCL_VAR)); // Ensured by ClearSuspendedIndicator
+
+    GenTree* value = m_comp->gtNewIconNode(1);
+    GenTree* storeSuspended =
+        m_comp->gtNewStoreValueNode(TYP_UBYTE, m_comp->gtCloneExpr(suspended), value, GTF_IND_NONFAULTING);
+
+    LIR::AsRange(block).InsertAtEnd(LIR::SeqTree(m_comp, storeSuspended));
+
+    call->gtArgs.RemoveUnsafe(suspendedArg);
+    call->asyncInfo->HasSuspensionIndicatorDef = false;
+
+    // Avoid leaving LCL_ADDR around which will DNER the local.
+    if (suspended->IsLclVarAddr())
+    {
+        LIR::AsRange(callBlock).Remove(suspended);
+    }
+    else
+    {
+        suspended->SetUnusedValue();
+    }
+}
+
 //------------------------------------------------------------------------
 // AsyncTransformation::CanonicalizeCallDefinition:
 //   Put the call definition in a canonical form. This ensures that either the
@@ -1200,13 +1311,16 @@ BasicBlock* AsyncTransformation::CreateSuspension(
     LIR::AsRange(suspendBB).InsertAtEnd(LIR::SeqTree(m_comp, storeState));
 
     // Fill in 'flags'
-    unsigned continuationFlags = 0;
+    const AsyncCallInfo& callInfo          = call->GetAsyncInfo();
+    unsigned             continuationFlags = 0;
     if (layout.ReturnInGCData)
         continuationFlags |= CORINFO_CONTINUATION_RESULT_IN_GCDATA;
     if (block->hasTryIndex())
         continuationFlags |= CORINFO_CONTINUATION_NEEDS_EXCEPTION;
     if (m_comp->doesMethodHavePatchpoints() || m_comp->opts.IsOSR())
         continuationFlags |= CORINFO_CONTINUATION_OSR_IL_OFFSET_IN_DATA;
+    if (callInfo.ContinuationContextHandling == ContinuationContextHandling::ContinueOnThreadPool)
+        continuationFlags |= CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL;
 
     newContinuation      = m_comp->gtNewLclvNode(m_newContinuationVar, TYP_REF);
     unsigned flagsOffset = m_comp->info.compCompHnd->getFieldOffset(m_asyncInfo->continuationFlagsFldHnd);
@@ -1216,7 +1330,7 @@ BasicBlock* AsyncTransformation::CreateSuspension(
 
     if (layout.GCRefsCount > 0)
     {
-        FillInGCPointersOnSuspension(layout, suspendBB);
+        FillInGCPointersOnSuspension(call, layout, suspendBB);
     }
 
     if (layout.DataSize > 0)
@@ -1296,10 +1410,13 @@ GenTreeCall* AsyncTransformation::CreateAllocContinuationCall(AsyncLiveness& lif
 //   parts that need to be stored.
 //
 // Parameters:
+//   call      - The async call that is being transformed
 //   layout    - Layout information
 //   suspendBB - Basic block to add IR to.
 //
-void AsyncTransformation::FillInGCPointersOnSuspension(const ContinuationLayout& layout, BasicBlock* suspendBB)
+void AsyncTransformation::FillInGCPointersOnSuspension(GenTreeCall*              call,
+                                                       const ContinuationLayout& layout,
+                                                       BasicBlock*               suspendBB)
 {
     unsigned objectArrLclNum = GetGCDataArrayVar();
 
@@ -1386,6 +1503,68 @@ void AsyncTransformation::FillInGCPointersOnSuspension(const ContinuationLayout&
         }
     }
 
+    if (layout.ContinuationContextGCDataIndex != UINT_MAX)
+    {
+        const AsyncCallInfo& callInfo = call->GetAsyncInfo();
+        assert(callInfo.SaveAndRestoreSynchronizationContextField &&
+               (callInfo.SynchronizationContextLclNum != BAD_VAR_NUM));
+
+        // Insert call
+        //   AsyncHelpers.CaptureContinuationContext(
+        //     syncContextFromBeforeCall,
+        //     ref newContinuation.GCData[ContinuationContextGCDataIndex],
+        //     ref newContinuation.Flags).
+        GenTree*     syncContextPlaceholder    = m_comp->gtNewNull();
+        GenTree*     contextElementPlaceholder = m_comp->gtNewZeroConNode(TYP_BYREF);
+        GenTree*     flagsPlaceholder          = m_comp->gtNewZeroConNode(TYP_BYREF);
+        GenTreeCall* captureCall =
+            m_comp->gtNewCallNode(CT_USER_FUNC, m_asyncInfo->captureContinuationContextMethHnd, TYP_VOID);
+
+        captureCall->gtArgs.PushFront(m_comp, NewCallArg::Primitive(flagsPlaceholder));
+        captureCall->gtArgs.PushFront(m_comp, NewCallArg::Primitive(contextElementPlaceholder));
+        captureCall->gtArgs.PushFront(m_comp, NewCallArg::Primitive(syncContextPlaceholder));
+
+        m_comp->compCurBB = suspendBB;
+        m_comp->fgMorphTree(captureCall);
+
+        LIR::AsRange(suspendBB).InsertAtEnd(LIR::SeqTree(m_comp, captureCall));
+
+        // Replace sync context placeholder with actual sync context from before call
+        LIR::Use use;
+        bool     gotUse = LIR::AsRange(suspendBB).TryGetUse(syncContextPlaceholder, &use);
+        assert(gotUse);
+        GenTree* syncContextLcl = m_comp->gtNewLclvNode(callInfo.SynchronizationContextLclNum, TYP_REF);
+        LIR::AsRange(suspendBB).InsertBefore(syncContextPlaceholder, syncContextLcl);
+        use.ReplaceWith(syncContextLcl);
+        LIR::AsRange(suspendBB).Remove(syncContextPlaceholder);
+
+        // Replace contextElementPlaceholder with actual address of the context element
+        gotUse = LIR::AsRange(suspendBB).TryGetUse(contextElementPlaceholder, &use);
+        assert(gotUse);
+
+        GenTree* objectArr = m_comp->gtNewLclvNode(objectArrLclNum, TYP_REF);
+        unsigned offset = OFFSETOF__CORINFO_Array__data + (layout.ContinuationContextGCDataIndex * TARGET_POINTER_SIZE);
+        GenTree* contextElementOffset =
+            m_comp->gtNewOperNode(GT_ADD, TYP_BYREF, objectArr, m_comp->gtNewIconNode((ssize_t)offset, TYP_I_IMPL));
+
+        LIR::AsRange(suspendBB).InsertBefore(contextElementPlaceholder, LIR::SeqTree(m_comp, contextElementOffset));
+        use.ReplaceWith(contextElementOffset);
+        LIR::AsRange(suspendBB).Remove(contextElementPlaceholder);
+
+        // Replace flagsPlaceholder with actual address of the flags
+        gotUse = LIR::AsRange(suspendBB).TryGetUse(flagsPlaceholder, &use);
+        assert(gotUse);
+
+        newContinuation          = m_comp->gtNewLclvNode(m_newContinuationVar, TYP_REF);
+        unsigned flagsOffset     = m_comp->info.compCompHnd->getFieldOffset(m_asyncInfo->continuationFlagsFldHnd);
+        GenTree* flagsOffsetNode = m_comp->gtNewOperNode(GT_ADD, TYP_BYREF, newContinuation,
+                                                         m_comp->gtNewIconNode((ssize_t)flagsOffset, TYP_I_IMPL));
+
+        LIR::AsRange(suspendBB).InsertBefore(flagsPlaceholder, LIR::SeqTree(m_comp, flagsOffsetNode));
+        use.ReplaceWith(flagsOffsetNode);
+        LIR::AsRange(suspendBB).Remove(flagsPlaceholder);
+    }
+
     if (layout.ExecContextGCDataIndex != UINT_MAX)
     {
         GenTreeCall* captureExecContext =
@@ -1485,12 +1664,14 @@ void AsyncTransformation::FillInDataOnSuspension(const jitstd::vectorfgNewBBafter(BBJ_ALWAYS, m_lastResumptionBB, true);
     FlowEdge*   remainderEdge = m_comp->fgAddRefPred(remainder, resumeBB);
 
-    // It does not really make sense to inherit from the target, but given this
-    // is always 0% this just propagates the profile weight flag + sets
-    // BBF_RUN_RARELY.
-    resumeBB->inheritWeightPercentage(remainder, 0);
+    resumeBB->bbSetRunRarely();
+    resumeBB->CopyFlags(remainder, BBF_PROF_WEIGHT);
     resumeBB->SetTargetEdge(remainderEdge);
     resumeBB->clearTryIndex();
     resumeBB->clearHndIndex();
@@ -1561,6 +1740,8 @@ BasicBlock* AsyncTransformation::CreateResumption(BasicBlock*               bloc
 
     JITDUMP("  Creating resumption " FMT_BB " for state %u\n", resumeBB->bbNum, stateNum);
 
+    SetSuspendedIndicator(resumeBB, block, call);
+
     // We need to restore data before we restore GC pointers, since restoring
     // the data may also write the GC pointer fields with nulls.
     unsigned resumeByteArrLclNum = BAD_VAR_NUM;
@@ -1595,7 +1776,7 @@ BasicBlock* AsyncTransformation::CreateResumption(BasicBlock*               bloc
 
         if (layout.ExceptionGCDataIndex != UINT_MAX)
         {
-            storeResultBB = RethrowExceptionOnResumption(block, remainder, resumeObjectArrLclNum, layout, resumeBB);
+            storeResultBB = RethrowExceptionOnResumption(block, resumeObjectArrLclNum, layout, resumeBB);
         }
     }
 
@@ -1768,7 +1949,6 @@ void AsyncTransformation::RestoreFromGCPointersOnResumption(unsigned
 //
 // Parameters:
 //   block                 - The block containing the async call
-//   remainder             - The block that contains the IR after the (split) async call
 //   resumeObjectArrLclNum - Local that has the continuation object's GC pointers array
 //   layout                - Layout information for the continuation object
 //   resumeBB              - Basic block to append IR to
@@ -1779,7 +1959,6 @@ void AsyncTransformation::RestoreFromGCPointersOnResumption(unsigned
 //   rethrow.
 //
 BasicBlock* AsyncTransformation::RethrowExceptionOnResumption(BasicBlock*               block,
-                                                              BasicBlock*               remainder,
                                                               unsigned                  resumeObjectArrLclNum,
                                                               const ContinuationLayout& layout,
                                                               BasicBlock*               resumeBB)
@@ -1797,6 +1976,7 @@ BasicBlock* AsyncTransformation::RethrowExceptionOnResumption(BasicBlock*
     FlowEdge* storeResultEdge = m_comp->fgAddRefPred(storeResultBB, resumeBB);
 
     assert(resumeBB->KindIs(BBJ_ALWAYS));
+    BasicBlock* remainder = resumeBB->GetTarget();
     m_comp->fgRemoveRefPred(resumeBB->GetTargetEdge());
 
     resumeBB->SetCond(rethrowEdge, storeResultEdge);
@@ -1927,6 +2107,9 @@ void AsyncTransformation::CopyReturnValueOnResumption(GenTreeCall*
                 LIR::AsRange(storeResultBB).InsertAtEnd(LIR::SeqTree(m_comp, storeResultBase));
 
                 resultBase = m_comp->gtNewLclVarNode(resultBaseVar, TYP_REF);
+
+                // Can be reallocated by above call to GetResultBaseVar
+                resultLcl = m_comp->lvaGetDesc(callDefInfo.DefinitionNode);
             }
 
             assert(callDefInfo.DefinitionNode->OperIs(GT_STORE_LCL_VAR));
@@ -2233,18 +2416,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(succs, numUniqueSuccs, cases, (unsigned)numCases, /* hasDefault */ true);
         switchBB->SetSwitch(swtDesc);
     }
 
diff --git a/src/coreclr/jit/async.h b/src/coreclr/jit/async.h
index 83732fd241187c..e30aaf760e6395 100644
--- a/src/coreclr/jit/async.h
+++ b/src/coreclr/jit/async.h
@@ -18,14 +18,15 @@ struct LiveLocalInfo
 
 struct ContinuationLayout
 {
-    unsigned                             DataSize               = 0;
-    unsigned                             GCRefsCount            = 0;
-    ClassLayout*                         ReturnStructLayout     = nullptr;
-    unsigned                             ReturnSize             = 0;
-    bool                                 ReturnInGCData         = false;
-    unsigned                             ReturnValDataOffset    = UINT_MAX;
-    unsigned                             ExceptionGCDataIndex   = UINT_MAX;
-    unsigned                             ExecContextGCDataIndex = UINT_MAX;
+    unsigned                             DataSize                       = 0;
+    unsigned                             GCRefsCount                    = 0;
+    ClassLayout*                         ReturnStructLayout             = nullptr;
+    unsigned                             ReturnSize                     = 0;
+    bool                                 ReturnInGCData                 = false;
+    unsigned                             ReturnValDataOffset            = UINT_MAX;
+    unsigned                             ExceptionGCDataIndex           = UINT_MAX;
+    unsigned                             ExecContextGCDataIndex         = UINT_MAX;
+    unsigned                             ContinuationContextGCDataIndex = UINT_MAX;
     const jitstd::vector& Locals;
 
     explicit ContinuationLayout(const jitstd::vector& locals)
@@ -83,6 +84,8 @@ class AsyncTransformation
                                           GenTreeCall*                   call,
                                           jitstd::vector& liveLocals);
 
+    void ClearSuspendedIndicator(BasicBlock* block, GenTreeCall* call);
+
     CallDefinitionInfo CanonicalizeCallDefinition(BasicBlock* block, GenTreeCall* call, AsyncLiveness& life);
 
     BasicBlock* CreateSuspension(
@@ -91,20 +94,21 @@ class AsyncTransformation
                                              GenTree*       prevContinuation,
                                              unsigned       gcRefsCount,
                                              unsigned int   dataSize);
-    void         FillInGCPointersOnSuspension(const ContinuationLayout& layout, BasicBlock* suspendBB);
-    void         FillInDataOnSuspension(const jitstd::vector& liveLocals, BasicBlock* suspendBB);
-    void         CreateCheckAndSuspendAfterCall(BasicBlock*               block,
-                                                const CallDefinitionInfo& callDefInfo,
-                                                AsyncLiveness&            life,
-                                                BasicBlock*               suspendBB,
-                                                BasicBlock**              remainder);
-
+    void FillInGCPointersOnSuspension(GenTreeCall* call, const ContinuationLayout& layout, BasicBlock* suspendBB);
+    void FillInDataOnSuspension(const jitstd::vector& liveLocals, BasicBlock* suspendBB);
+    void CreateCheckAndSuspendAfterCall(BasicBlock*               block,
+                                        GenTreeCall*              call,
+                                        const CallDefinitionInfo& callDefInfo,
+                                        AsyncLiveness&            life,
+                                        BasicBlock*               suspendBB,
+                                        BasicBlock**              remainder);
     BasicBlock* CreateResumption(BasicBlock*               block,
                                  BasicBlock*               remainder,
                                  GenTreeCall*              call,
                                  const CallDefinitionInfo& callDefInfo,
                                  unsigned                  stateNum,
                                  const ContinuationLayout& layout);
+    void        SetSuspendedIndicator(BasicBlock* block, BasicBlock* callBlock, GenTreeCall* call);
     void        RestoreFromDataOnResumption(unsigned                             resumeByteArrLclNum,
                                             const jitstd::vector& liveLocals,
                                             BasicBlock*                          resumeBB);
@@ -112,7 +116,6 @@ class AsyncTransformation
                                                   const ContinuationLayout& layout,
                                                   BasicBlock*               resumeBB);
     BasicBlock* RethrowExceptionOnResumption(BasicBlock*               block,
-                                             BasicBlock*               remainder,
                                              unsigned                  resumeObjectArrLclNum,
                                              const ContinuationLayout& layout,
                                              BasicBlock*               resumeBB);
diff --git a/src/coreclr/jit/block.cpp b/src/coreclr/jit/block.cpp
index 6a3bc744bcda73..f36e55e216a5aa 100644
--- a/src/coreclr/jit/block.cpp
+++ b/src/coreclr/jit/block.cpp
@@ -491,7 +491,6 @@ void BasicBlock::dspFlags() const
         {BBF_IMPORTED, "i"},
         {BBF_IS_LIR, "LIR"},
         {BBF_PROF_WEIGHT, "IBC"},
-        {BBF_RUN_RARELY, "rare"},
         {BBF_MARKED, "m"},
         {BBF_REMOVED, "del"},
         {BBF_DONT_REMOVE, "keep"},
@@ -502,11 +501,8 @@ void BasicBlock::dspFlags() const
         {BBF_HAS_CALL, "hascall"},
         {BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY, "xentry"},
         {BBF_GC_SAFE_POINT, "gcsafe"},
-        {BBF_HAS_IDX_LEN, "idxlen"},
-        {BBF_HAS_MD_IDX_LEN, "mdidxlen"},
         {BBF_HAS_NEWOBJ, "newobj"},
         {BBF_HAS_NEWARR, "newarr"},
-        {BBF_HAS_NULLCHECK, "nullcheck"},
         {BBF_BACKWARD_JUMP, "bwd"},
         {BBF_BACKWARD_JUMP_TARGET, "bwd-target"},
         {BBF_BACKWARD_JUMP_SOURCE, "bwd-src"},
@@ -583,45 +579,13 @@ unsigned BasicBlock::dspPreds() const
 //------------------------------------------------------------------------
 // dspSuccs: Display the basic block successors.
 //
-// Arguments:
-//    compiler - compiler instance; passed to NumSucc(Compiler*) -- see that function for implications.
-//
-void BasicBlock::dspSuccs(Compiler* compiler)
+void BasicBlock::dspSuccs() const
 {
     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())
     {
-        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;
     }
 }
 
@@ -675,12 +639,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)));
                 }
             }
 
@@ -739,20 +700,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]");
@@ -769,10 +730,7 @@ void BasicBlock::dspKind() const
     }
 }
 
-void BasicBlock::dspBlockHeader(Compiler* compiler,
-                                bool      showKind /*= true*/,
-                                bool      showFlags /*= false*/,
-                                bool      showPreds /*= true*/)
+void BasicBlock::dspBlockHeader(bool showKind /*= true*/, bool showFlags /*= false*/, bool showPreds /*= true*/) const
 {
     printf("%s ", dspToString());
     dspBlockILRange();
@@ -785,7 +743,7 @@ void BasicBlock::dspBlockHeader(Compiler* compiler,
         printf(", preds={");
         dspPreds();
         printf("} succs={");
-        dspSuccs(compiler);
+        dspSuccs();
         printf("}");
     }
     if (showFlags)
@@ -1101,41 +1059,6 @@ Statement* BasicBlock::FirstNonPhiDefOrCatchArgStore() const
     return stmt;
 }
 
-//------------------------------------------------------------------------
-// bbFallsThrough: Check if inserting a BasicBlock after this one will alter
-// the flowgraph.
-//
-// Returns:
-//    True if so.
-//
-bool BasicBlock::bbFallsThrough() const
-{
-    switch (bbKind)
-    {
-        case BBJ_THROW:
-        case BBJ_EHFINALLYRET:
-        case BBJ_EHFAULTRET:
-        case BBJ_EHFILTERRET:
-        case BBJ_EHCATCHRET:
-        case BBJ_RETURN:
-        case BBJ_ALWAYS:
-        case BBJ_CALLFINALLYRET:
-        case BBJ_LEAVE:
-        case BBJ_SWITCH:
-            return false;
-
-        case BBJ_COND:
-            return true;
-
-        case BBJ_CALLFINALLY:
-            return !HasFlag(BBF_RETLESS_CALL);
-
-        default:
-            assert(!"Unknown bbKind in bbFallsThrough()");
-            return true;
-    }
-}
-
 //------------------------------------------------------------------------
 // NumSucc: Returns the count of block successors. See the declaration comment for details.
 //
@@ -1187,10 +1110,10 @@ unsigned BasicBlock::NumSucc() const
                 return 0;
             }
 
-            return bbEhfTargets->bbeCount;
+            return bbEhfTargets->GetSuccCount();
 
         case BBJ_SWITCH:
-            return bbSwtTargets->bbsCount;
+            return bbSwtTargets->GetSuccCount();
 
         default:
             unreached();
@@ -1198,7 +1121,7 @@ unsigned BasicBlock::NumSucc() const
 }
 
 //------------------------------------------------------------------------
-// GetSucc: Returns the requested successor edge. See the declaration comment for details.
+// GetSuccEdge: Returns the requested successor edge. See the declaration comment for details.
 //
 // Arguments:
 //    i - index of successor to return. 0 <= i <= NumSucc().
@@ -1232,10 +1155,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->GetSucc(i);
 
         default:
             unreached();
@@ -1256,145 +1179,6 @@ BasicBlock* BasicBlock::GetSucc(unsigned i) const
     return GetSuccEdge(i)->getDestinationBlock();
 }
 
-//------------------------------------------------------------------------
-// NumSucc: Returns the count of block successors. See the declaration comment for details.
-//
-// Arguments:
-//    comp - Compiler instance
-//
-// Return Value:
-//    Count of block successors.
-//
-unsigned BasicBlock::NumSucc(Compiler* comp)
-{
-    assert(comp != nullptr);
-
-    switch (bbKind)
-    {
-        case BBJ_THROW:
-        case BBJ_RETURN:
-        case BBJ_EHFAULTRET:
-            return 0;
-
-        case BBJ_EHFINALLYRET:
-            // We may call this method before we realize we have invalid IL. Tolerate.
-            //
-            if (!hasHndIndex())
-            {
-                return 0;
-            }
-
-            // We may call this before we've computed the BBJ_EHFINALLYRET successors in the importer. Tolerate.
-            //
-            if (bbEhfTargets == nullptr)
-            {
-                return 0;
-            }
-
-            return bbEhfTargets->bbeCount;
-
-        case BBJ_CALLFINALLY:
-        case BBJ_CALLFINALLYRET:
-        case BBJ_ALWAYS:
-        case BBJ_EHCATCHRET:
-        case BBJ_EHFILTERRET:
-        case BBJ_LEAVE:
-            return 1;
-
-        case BBJ_COND:
-            if (bbTrueEdge == bbFalseEdge)
-            {
-                return 1;
-            }
-            else
-            {
-                return 2;
-            }
-
-        case BBJ_SWITCH:
-        {
-            Compiler::SwitchUniqueSuccSet sd = comp->GetDescriptorForSwitch(this);
-            return sd.numDistinctSuccs;
-        }
-
-        default:
-            unreached();
-    }
-}
-
-//------------------------------------------------------------------------
-// GetSucc: Returns the requested successor edge. See the declaration comment for details.
-//
-// Arguments:
-//    i - index of successor to return. 0 <= i <= NumSucc(comp).
-//    comp - Compiler instance
-//
-// Return Value:
-//    Requested successor edge
-//
-FlowEdge* BasicBlock::GetSuccEdge(unsigned i, Compiler* comp)
-{
-    assert(comp != nullptr);
-
-    assert(i < NumSucc(comp)); // Index bounds check.
-    switch (bbKind)
-    {
-        case BBJ_EHFILTERRET:
-            // Handler is the (sole) normal successor of the filter.
-            assert(comp->fgFirstBlockOfHandler(this) == GetTarget());
-            return GetTargetEdge();
-
-        case BBJ_EHFINALLYRET:
-            assert(bbEhfTargets != nullptr);
-            assert(i < bbEhfTargets->bbeCount);
-            return bbEhfTargets->bbeSuccs[i];
-
-        case BBJ_CALLFINALLY:
-        case BBJ_CALLFINALLYRET:
-        case BBJ_ALWAYS:
-        case BBJ_EHCATCHRET:
-        case BBJ_LEAVE:
-            return GetTargetEdge();
-
-        case BBJ_COND:
-            if (i == 0)
-            {
-                return GetFalseEdge();
-            }
-            else
-            {
-                assert(i == 1);
-                assert(bbTrueEdge != bbFalseEdge);
-                return GetTrueEdge();
-            }
-
-        case BBJ_SWITCH:
-        {
-            Compiler::SwitchUniqueSuccSet sd = comp->GetDescriptorForSwitch(this);
-            assert(i < sd.numDistinctSuccs); // Range check.
-            return sd.nonDuplicates[i];
-        }
-
-        default:
-            unreached();
-    }
-}
-
-//------------------------------------------------------------------------
-// GetSucc: Returns the requested block successor. See the declaration comment for details.
-//
-// Arguments:
-//    i - index of successor to return. 0 <= i <= NumSucc(comp).
-//    comp - Compiler instance
-//
-// Return Value:
-//    Requested successor block
-//
-BasicBlock* BasicBlock::GetSucc(unsigned i, Compiler* comp)
-{
-    return GetSuccEdge(i, comp)->getDestinationBlock();
-}
-
 void BasicBlock::InitVarSets(Compiler* comp)
 {
     VarSetOps::AssignNoCopy(comp, bbVarUse, VarSetOps::MakeEmpty(comp));
@@ -1639,7 +1423,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);
@@ -1761,21 +1545,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
 //
@@ -1784,38 +1553,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);
 }
 
 //------------------------------------------------------------------------
@@ -1970,79 +1734,3 @@ bool BasicBlock::StatementCountExceeds(unsigned limit, unsigned* count /* = null
 
     return overLimit;
 }
-
-//------------------------------------------------------------------------
-// ComplexityExceeds: check if the number of nodes in the trees in the block
-//   exceeds some limit
-//
-// Arguments:
-//    comp   - compiler instance
-//    limit  - limit on the number of nodes
-//    count  - [out, optional] actual number of nodes (if less than or equal to limit)
-//
-// Returns:
-//   true if the number of nodes is greater than limit
-//
-bool BasicBlock::ComplexityExceeds(Compiler* comp, unsigned limit, unsigned* count /* = nullptr */)
-{
-    unsigned localCount = 0;
-    bool     overLimit  = false;
-
-    for (Statement* const stmt : Statements())
-    {
-        unsigned slack  = limit - localCount;
-        unsigned actual = 0;
-        if (comp->gtComplexityExceeds(stmt->GetRootNode(), slack, &actual))
-        {
-            overLimit = true;
-            break;
-        }
-
-        localCount += actual;
-    }
-
-    if (count != nullptr)
-    {
-        *count = localCount;
-    }
-
-    return overLimit;
-}
-
-//------------------------------------------------------------------------
-// ComplexityExceeds: check if the number of nodes in the trees in the blocks
-//   in the range exceeds some limit
-//
-// Arguments:
-//    comp   - compiler instance
-//    limit  - limit on the number of nodes
-//    count  - [out, optional] actual number of nodes (if less than or equal to limit)
-//
-// Returns:
-//   true if the number of nodes is greater than limit
-//
-bool BasicBlockRangeList::ComplexityExceeds(Compiler* comp, unsigned limit, unsigned* count /* = nullptr */)
-{
-    unsigned localCount = 0;
-    bool     overLimit  = false;
-
-    for (BasicBlock* const block : *this)
-    {
-        unsigned slack  = limit - localCount;
-        unsigned actual = 0;
-        if (block->ComplexityExceeds(comp, slack, &actual))
-        {
-            overLimit = true;
-            break;
-        }
-
-        localCount += actual;
-    }
-
-    if (count != nullptr)
-    {
-        *count = localCount;
-    }
-
-    return overLimit;
-}
diff --git a/src/coreclr/jit/block.h b/src/coreclr/jit/block.h
index 3bb90fba0a5256..b391720927d60b 100644
--- a/src/coreclr/jit/block.h
+++ b/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;
 };
@@ -428,48 +414,44 @@ enum BasicBlockFlags : uint64_t
     BBF_NEEDS_GCPOLL         = MAKE_BBFLAG( 6), // BB may need a GC poll because it uses the slow tail call helper
     BBF_CLONED_FINALLY_BEGIN = MAKE_BBFLAG( 7), // First block of a cloned finally region
     BBF_CLONED_FINALLY_END   = MAKE_BBFLAG( 8), // Last block of a cloned finally region
-    BBF_HAS_NULLCHECK        = MAKE_BBFLAG( 9), // BB contains a null check
-    BBF_HAS_SUPPRESSGC_CALL  = MAKE_BBFLAG(10), // BB contains a call to a method with SuppressGCTransitionAttribute
-    BBF_RUN_RARELY           = MAKE_BBFLAG(11), // BB is rarely run (catch clauses, blocks with throws etc)
-    BBF_HAS_LABEL            = MAKE_BBFLAG(12), // BB needs a label
-    BBF_LOOP_ALIGN           = MAKE_BBFLAG(13), // Block is lexically the first block in a loop we intend to align.
-    BBF_HAS_ALIGN            = MAKE_BBFLAG(14), // BB ends with 'align' instruction
-    BBF_HAS_JMP              = MAKE_BBFLAG(15), // BB executes a JMP instruction (instead of return)
-    BBF_GC_SAFE_POINT        = MAKE_BBFLAG(16), // BB has a GC safe point (e.g. a call)
-    BBF_HAS_IDX_LEN          = MAKE_BBFLAG(17), // BB contains simple index or length expressions on an SD array local var.
-    BBF_HAS_MD_IDX_LEN       = MAKE_BBFLAG(18), // BB contains simple index, length, or lower bound expressions on an MD array local var.
-    BBF_HAS_MDARRAYREF       = MAKE_BBFLAG(19), // Block has a multi-dimensional array reference
-    BBF_HAS_NEWOBJ           = MAKE_BBFLAG(20), // BB contains 'new' of an object type.
-
-    BBF_RETLESS_CALL                   = MAKE_BBFLAG(21), // BBJ_CALLFINALLY that will never return (and therefore, won't need a paired
+    BBF_HAS_SUPPRESSGC_CALL  = MAKE_BBFLAG( 9), // BB contains a call to a method with SuppressGCTransitionAttribute
+    BBF_HAS_LABEL            = MAKE_BBFLAG(10), // BB needs a label
+    BBF_LOOP_ALIGN           = MAKE_BBFLAG(11), // Block is lexically the first block in a loop we intend to align.
+    BBF_HAS_ALIGN            = MAKE_BBFLAG(12), // BB ends with 'align' instruction
+    BBF_HAS_JMP              = MAKE_BBFLAG(13), // BB executes a JMP instruction (instead of return)
+    BBF_GC_SAFE_POINT        = MAKE_BBFLAG(14), // BB has a GC safe point (e.g. a call)
+    BBF_HAS_MDARRAYREF       = MAKE_BBFLAG(15), // Block has a multi-dimensional array reference
+    BBF_HAS_NEWOBJ           = MAKE_BBFLAG(16), // BB contains 'new' of an object type.
+
+    BBF_RETLESS_CALL                   = MAKE_BBFLAG(17), // BBJ_CALLFINALLY that will never return (and therefore, won't need a paired
                                                           // BBJ_CALLFINALLYRET); see isBBCallFinallyPair().
-    BBF_COLD                           = MAKE_BBFLAG(22), // BB is cold
-    BBF_PROF_WEIGHT                    = MAKE_BBFLAG(23), // BB weight is computed from profile data
-    BBF_KEEP_BBJ_ALWAYS                = MAKE_BBFLAG(24), // A special BBJ_ALWAYS block, used by EH code generation. Keep the jump kind
+    BBF_COLD                           = MAKE_BBFLAG(18), // BB is cold
+    BBF_PROF_WEIGHT                    = MAKE_BBFLAG(19), // BB weight is computed from profile data
+    BBF_KEEP_BBJ_ALWAYS                = MAKE_BBFLAG(20), // A special BBJ_ALWAYS block, used by EH code generation. Keep the jump kind
                                                           // as BBJ_ALWAYS. Used on x86 for the final step block out of a finally.
-    BBF_HAS_CALL                       = MAKE_BBFLAG(25), // BB contains a call
-    BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY = MAKE_BBFLAG(26), // Block is dominated by exceptional entry.
-    BBF_BACKWARD_JUMP                  = MAKE_BBFLAG(27), // BB is surrounded by a backward jump/switch arc
-    BBF_BACKWARD_JUMP_SOURCE           = MAKE_BBFLAG(28), // Block is a source of a backward jump
-    BBF_BACKWARD_JUMP_TARGET           = MAKE_BBFLAG(29), // Block is a target of a backward jump
-    BBF_PATCHPOINT                     = MAKE_BBFLAG(30), // Block is a patchpoint
-    BBF_PARTIAL_COMPILATION_PATCHPOINT = MAKE_BBFLAG(31), // Block is a partial compilation patchpoint
-    BBF_HAS_HISTOGRAM_PROFILE          = MAKE_BBFLAG(32), // BB contains a call needing a histogram profile
-    BBF_TAILCALL_SUCCESSOR             = MAKE_BBFLAG(33), // BB has pred that has potential tail call
-    BBF_RECURSIVE_TAILCALL             = MAKE_BBFLAG(34), // Block has recursive tailcall that may turn into a loop
-    BBF_NO_CSE_IN                      = MAKE_BBFLAG(35), // Block should kill off any incoming CSE
-    BBF_CAN_ADD_PRED                   = MAKE_BBFLAG(36), // Ok to add pred edge to this block, even when "safe" edge creation disabled
-    BBF_HAS_VALUE_PROFILE              = MAKE_BBFLAG(37), // Block has a node that needs a value probing
-    BBF_HAS_NEWARR                     = MAKE_BBFLAG(38), // BB contains 'new' of an array type.
-    BBF_MAY_HAVE_BOUNDS_CHECKS         = MAKE_BBFLAG(39), // BB *likely* has a bounds check (after rangecheck phase).
-    BBF_ASYNC_RESUMPTION               = MAKE_BBFLAG(40), // Block is a resumption block in an async method
+    BBF_HAS_CALL                       = MAKE_BBFLAG(21), // BB contains a call
+    BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY = MAKE_BBFLAG(22), // Block is dominated by exceptional entry.
+    BBF_BACKWARD_JUMP                  = MAKE_BBFLAG(23), // BB is surrounded by a backward jump/switch arc
+    BBF_BACKWARD_JUMP_SOURCE           = MAKE_BBFLAG(24), // Block is a source of a backward jump
+    BBF_BACKWARD_JUMP_TARGET           = MAKE_BBFLAG(25), // Block is a target of a backward jump
+    BBF_PATCHPOINT                     = MAKE_BBFLAG(26), // Block is a patchpoint
+    BBF_PARTIAL_COMPILATION_PATCHPOINT = MAKE_BBFLAG(27), // Block is a partial compilation patchpoint
+    BBF_HAS_HISTOGRAM_PROFILE          = MAKE_BBFLAG(28), // BB contains a call needing a histogram profile
+    BBF_TAILCALL_SUCCESSOR             = MAKE_BBFLAG(29), // BB has pred that has potential tail call
+    BBF_RECURSIVE_TAILCALL             = MAKE_BBFLAG(30), // Block has recursive tailcall that may turn into a loop
+    BBF_NO_CSE_IN                      = MAKE_BBFLAG(31), // Block should kill off any incoming CSE
+    BBF_CAN_ADD_PRED                   = MAKE_BBFLAG(32), // Ok to add pred edge to this block, even when "safe" edge creation disabled
+    BBF_HAS_VALUE_PROFILE              = MAKE_BBFLAG(33), // Block has a node that needs a value probing
+    BBF_HAS_NEWARR                     = MAKE_BBFLAG(34), // BB contains 'new' of an array type.
+    BBF_MAY_HAVE_BOUNDS_CHECKS         = MAKE_BBFLAG(35), // BB *likely* has a bounds check (after rangecheck phase).
+    BBF_ASYNC_RESUMPTION               = MAKE_BBFLAG(36), // Block is a resumption block in an async method
 
     // The following are sets of flags.
 
     // Flags to update when two blocks are compacted
 
-    BBF_COMPACT_UPD = BBF_GC_SAFE_POINT | BBF_NEEDS_GCPOLL | BBF_HAS_JMP | BBF_HAS_IDX_LEN | BBF_HAS_MD_IDX_LEN | BBF_BACKWARD_JUMP | \
-                      BBF_HAS_NEWOBJ | BBF_HAS_NEWARR | BBF_HAS_NULLCHECK | BBF_HAS_MDARRAYREF | BBF_MAY_HAVE_BOUNDS_CHECKS,
+    BBF_COMPACT_UPD = BBF_GC_SAFE_POINT | BBF_NEEDS_GCPOLL | BBF_HAS_JMP | BBF_BACKWARD_JUMP | \
+                      BBF_HAS_NEWOBJ | BBF_HAS_NEWARR | BBF_HAS_MDARRAYREF | BBF_MAY_HAVE_BOUNDS_CHECKS,
 
     // Flags a block should not have had before it is split.
 
@@ -484,18 +466,17 @@ enum BasicBlockFlags : uint64_t
 
     // Flags gained by the bottom block when a block is split.
     // Note, this is a conservative guess.
-    // For example, the bottom block might or might not have BBF_HAS_NULLCHECK, but we assume it has BBF_HAS_NULLCHECK.
-    // TODO: Should BBF_RUN_RARELY be added to BBF_SPLIT_GAINED ?
+    // For example, the bottom block might or might not have BBF_HAS_NEWARR, but we assume it has BBF_HAS_NEWARR.
 
-    BBF_SPLIT_GAINED = BBF_DONT_REMOVE | BBF_HAS_JMP | BBF_BACKWARD_JUMP | BBF_HAS_IDX_LEN | BBF_HAS_MD_IDX_LEN | BBF_PROF_WEIGHT | BBF_HAS_NEWARR | \
-                       BBF_HAS_NEWOBJ | BBF_KEEP_BBJ_ALWAYS | BBF_CLONED_FINALLY_END | BBF_HAS_NULLCHECK | BBF_HAS_HISTOGRAM_PROFILE | BBF_HAS_VALUE_PROFILE | BBF_HAS_MDARRAYREF | BBF_NEEDS_GCPOLL | BBF_MAY_HAVE_BOUNDS_CHECKS | BBF_ASYNC_RESUMPTION,
+    BBF_SPLIT_GAINED = BBF_DONT_REMOVE | BBF_HAS_JMP | BBF_BACKWARD_JUMP | BBF_PROF_WEIGHT | BBF_HAS_NEWARR | \
+                       BBF_HAS_NEWOBJ | BBF_KEEP_BBJ_ALWAYS | BBF_CLONED_FINALLY_END | BBF_HAS_HISTOGRAM_PROFILE | BBF_HAS_VALUE_PROFILE | BBF_HAS_MDARRAYREF | BBF_NEEDS_GCPOLL | BBF_MAY_HAVE_BOUNDS_CHECKS | BBF_ASYNC_RESUMPTION,
 
     // Flags that must be propagated to a new block if code is copied from a block to a new block. These are flags that
     // limit processing of a block if the code in question doesn't exist. This is conservative; we might not
     // have actually copied one of these type of tree nodes, but if we only copy a portion of the block's statements,
     // we don't know (unless we actually pay close attention during the copy).
 
-    BBF_COPY_PROPAGATE = BBF_HAS_NEWOBJ | BBF_HAS_NEWARR | BBF_HAS_NULLCHECK | BBF_HAS_IDX_LEN | BBF_HAS_MD_IDX_LEN | BBF_HAS_MDARRAYREF | BBF_MAY_HAVE_BOUNDS_CHECKS,
+    BBF_COPY_PROPAGATE = BBF_HAS_NEWOBJ | BBF_HAS_NEWARR | BBF_HAS_MDARRAYREF | BBF_MAY_HAVE_BOUNDS_CHECKS,
 };
 
 FORCEINLINE
@@ -743,11 +724,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
@@ -756,7 +737,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);
 
@@ -1032,19 +1013,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;
@@ -1186,9 +1167,16 @@ struct BasicBlock : private LIR::Range
     unsigned bbRefs; // number of blocks that can reach here, either by fall-through or a branch. If this falls to zero,
                      // the block is unreachable.
 
+#define BB_UNITY_WEIGHT          100.0 // how much a normal execute once block weighs
+#define BB_UNITY_WEIGHT_UNSIGNED 100   // how much a normal execute once block weighs
+#define BB_LOOP_WEIGHT_SCALE     8.0   // synthetic profile scale factor for loops
+#define BB_ZERO_WEIGHT           0.0
+#define BB_COLD_WEIGHT           0.01    // Upper bound for cold weights; used during block layout
+#define BB_MAX_WEIGHT            FLT_MAX // maximum finite weight -- needs rethinking.
+
     bool isRunRarely() const
     {
-        return HasFlag(BBF_RUN_RARELY);
+        return (bbWeight == BB_ZERO_WEIGHT);
     }
 
     bool isLoopAlign() const
@@ -1202,25 +1190,17 @@ struct BasicBlock : private LIR::Range
     }
 
 #ifdef DEBUG
-    void     dspFlags() const;             // Print the flags
-    unsigned dspPreds() const;             // Print the predecessors (bbPreds)
-    void     dspSuccs(Compiler* compiler); // Print the successors. The 'compiler' argument determines whether EH
-                                           // regions are printed: see NumSucc() for details.
-    void dspKind() const;                  // Print the block jump kind (e.g., BBJ_ALWAYS, BBJ_COND, etc.).
+    void     dspFlags() const; // Print the flags
+    unsigned dspPreds() const; // Print the predecessors (bbPreds)
+    void     dspSuccs() const; // Print the successors.
+    void     dspKind() const;  // Print the block jump kind (e.g., BBJ_ALWAYS, BBJ_COND, etc.).
 
     // Print a simple basic block header for various output, including a list of predecessors and successors.
-    void dspBlockHeader(Compiler* compiler, bool showKind = true, bool showFlags = false, bool showPreds = true);
+    void dspBlockHeader(bool showKind = true, bool showFlags = false, bool showPreds = true) const;
 
     const char* dspToString(int blockNumPadding = 0) const;
 #endif // DEBUG
 
-#define BB_UNITY_WEIGHT          100.0 // how much a normal execute once block weighs
-#define BB_UNITY_WEIGHT_UNSIGNED 100   // how much a normal execute once block weighs
-#define BB_LOOP_WEIGHT_SCALE     8.0   // synthetic profile scale factor for loops
-#define BB_ZERO_WEIGHT           0.0
-#define BB_COLD_WEIGHT           0.01    // Upper bound for cold weights; used during block layout
-#define BB_MAX_WEIGHT            FLT_MAX // maximum finite weight  -- needs rethinking.
-
     weight_t bbWeight; // The dynamic execution weight of this block
 
     // getCalledCount -- get the value used to normalize weights for this method
@@ -1253,15 +1233,6 @@ struct BasicBlock : private LIR::Range
     {
         this->SetFlags(BBF_PROF_WEIGHT);
         this->bbWeight = weight;
-
-        if (weight == BB_ZERO_WEIGHT)
-        {
-            this->SetFlags(BBF_RUN_RARELY);
-        }
-        else
-        {
-            this->RemoveFlags(BBF_RUN_RARELY);
-        }
     }
 
     // increaseBBProfileWeight -- Increase the profile-derived weight for a basic block
@@ -1296,25 +1267,10 @@ struct BasicBlock : private LIR::Range
     {
         assert(0 <= percentage && percentage <= 100);
 
-        this->bbWeight = (bSrc->bbWeight * percentage) / 100;
-
-        if (bSrc->hasProfileWeight())
-        {
-            this->SetFlags(BBF_PROF_WEIGHT);
-        }
-        else
-        {
-            this->RemoveFlags(BBF_PROF_WEIGHT);
-        }
-
-        if (this->bbWeight == BB_ZERO_WEIGHT)
-        {
-            this->SetFlags(BBF_RUN_RARELY);
-        }
-        else
-        {
-            this->RemoveFlags(BBF_RUN_RARELY);
-        }
+        this->bbWeight                         = (bSrc->bbWeight * percentage) / 100;
+        const BasicBlockFlags hasProfileWeight = bSrc->GetFlagsRaw() & BBF_PROF_WEIGHT;
+        this->RemoveFlags(BBF_PROF_WEIGHT);
+        this->SetFlags(hasProfileWeight);
     }
 
     // Scale a blocks' weight by some factor.
@@ -1322,18 +1278,9 @@ struct BasicBlock : private LIR::Range
     void scaleBBWeight(weight_t scale)
     {
         this->bbWeight = this->bbWeight * scale;
-
-        if (this->bbWeight == BB_ZERO_WEIGHT)
-        {
-            this->SetFlags(BBF_RUN_RARELY);
-        }
-        else
-        {
-            this->RemoveFlags(BBF_RUN_RARELY);
-        }
     }
 
-    // Set block weight to zero, and set run rarely flag.
+    // Set block weight to zero.
     //
     void bbSetRunRarely()
     {
@@ -1398,33 +1345,31 @@ struct BasicBlock : private LIR::Range
     //
     // NumSucc: Returns the number of successors of "this".
     unsigned NumSucc() const;
-    unsigned NumSucc(Compiler* comp);
 
     // GetSuccEdge: Returns the "i"th successor edge. Requires (0 <= i < NumSucc()).
     FlowEdge* GetSuccEdge(unsigned i) const;
-    FlowEdge* GetSuccEdge(unsigned i, Compiler* comp);
 
     // GetSucc: Returns the "i"th successor block. Requires (0 <= i < NumSucc()).
     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;
@@ -1748,8 +1693,6 @@ struct BasicBlock : private LIR::Range
     static size_t s_Count;
 #endif // MEASURE_BLOCK_SIZE
 
-    bool bbFallsThrough() const;
-
 #ifdef DEBUG
     unsigned        bbTgtStkDepth; // Native stack depth on entry (for throw-blocks)
     static unsigned s_nMaxTrees;   // The max # of tree nodes in any BB
@@ -1801,7 +1744,9 @@ struct BasicBlock : private LIR::Range
     //
     unsigned StatementCount();
     bool     StatementCountExceeds(unsigned limit, unsigned* count = nullptr);
-    bool     ComplexityExceeds(Compiler* comp, unsigned limit, unsigned* complexity = nullptr);
+
+    template 
+    bool ComplexityExceeds(Compiler* comp, unsigned limit, TFunc getTreeComplexity);
 
     GenTree* lastNode() const;
 
@@ -1828,71 +1773,6 @@ struct BasicBlock : private LIR::Range
     {
     }
 
-    // Iteratable collection of successors of a block.
-    template 
-    class Successors
-    {
-        Compiler*   m_comp;
-        BasicBlock* m_block;
-
-    public:
-        Successors(Compiler* comp, BasicBlock* block)
-            : m_comp(comp)
-            , m_block(block)
-        {
-        }
-
-        class iterator
-        {
-            Compiler*   m_comp;
-            BasicBlock* m_block;
-            TPosition   m_pos;
-
-        public:
-            iterator(Compiler* comp, BasicBlock* block)
-                : m_comp(comp)
-                , m_block(block)
-                , m_pos(comp, block)
-            {
-            }
-
-            iterator()
-                : m_pos()
-            {
-            }
-
-            void operator++(void)
-            {
-                m_pos.Advance(m_comp, m_block);
-            }
-
-            BasicBlock* operator*()
-            {
-                return m_pos.Current(m_comp, m_block);
-            }
-
-            bool operator==(const iterator& other)
-            {
-                return m_pos == other.m_pos;
-            }
-
-            bool operator!=(const iterator& other)
-            {
-                return m_pos != other.m_pos;
-            }
-        };
-
-        iterator begin()
-        {
-            return iterator(m_comp, m_block);
-        }
-
-        iterator end()
-        {
-            return iterator();
-        }
-    };
-
     template 
     BasicBlockVisit VisitEHEnclosedHandlerSecondPassSuccs(Compiler* comp, TFunc func);
 
@@ -1907,222 +1787,50 @@ struct BasicBlock : private LIR::Range
 
     bool HasPotentialEHSuccs(Compiler* comp);
 
-    // Base class for Successor block/edge iterators.
+    // BBSuccList: adapter class for forward iteration of block successors, using range-based `for`,
+    // normally used via BasicBlock::Succs(), e.g.:
+    //    for (BasicBlock* const target : block->Succs()) ...
     //
-    class SuccList
+    template 
+    class BBSuccList
     {
-    protected:
+    private:
         // For one or two successors, pre-compute and stash the successors inline, in m_succs[], so we don't
         // need to call a function or execute another `switch` to get them. Also, pre-compute the begin and end
-        // points of the iteration, for use by BBArrayIterator. `m_begin` and `m_end` will either point at
+        // points of the iteration, for use by the iterator. `m_begin` and `m_end` will either point at
         // `m_succs` or at the switch table successor array.
         FlowEdge*        m_succs[2];
         FlowEdge* const* m_begin;
         FlowEdge* const* m_end;
 
-        SuccList(const BasicBlock* block);
-    };
-
-    // BBSuccList: adapter class for forward iteration of block successors, using range-based `for`,
-    // normally used via BasicBlock::Succs(), e.g.:
-    //    for (BasicBlock* const target : block->Succs()) ...
-    //
-    class BBSuccList : private SuccList
-    {
-    public:
-        BBSuccList(const BasicBlock* block)
-            : SuccList(block)
-        {
-        }
-
-        BBArrayIterator begin() const
-        {
-            return BBArrayIterator(m_begin);
-        }
-
-        BBArrayIterator end() const
-        {
-            return BBArrayIterator(m_end);
-        }
-    };
-
-    // BBSuccEdgeList: adapter class for forward iteration of block successors edges, using range-based `for`,
-    // normally used via BasicBlock::SuccEdges(), e.g.:
-    //    for (FlowEdge* const succEdge : block->SuccEdges()) ...
-    //
-    class BBSuccEdgeList : private SuccList
-    {
-    public:
-        BBSuccEdgeList(const BasicBlock* block)
-            : SuccList(block)
-        {
-        }
-
-        FlowEdgeArrayIterator begin() const
-        {
-            return FlowEdgeArrayIterator(m_begin);
-        }
-
-        FlowEdgeArrayIterator end() const
-        {
-            return FlowEdgeArrayIterator(m_end);
-        }
-    };
-
-    // BBCompilerSuccList: adapter class for forward iteration of block successors, using range-based `for`,
-    // normally used via BasicBlock::Succs(), e.g.:
-    //    for (BasicBlock* const target : block->Succs(compiler)) ...
-    //
-    // This version uses NumSucc(Compiler*)/GetSucc(Compiler*). See the documentation there for the explanation
-    // of the implications of this versus the version that does not take `Compiler*`.
-    class BBCompilerSuccList
-    {
-        Compiler*   m_comp;
-        BasicBlock* m_block;
-
-        // iterator: forward iterator for an array of BasicBlock*
-        //
-        class iterator
-        {
-            Compiler*   m_comp;
-            BasicBlock* m_block;
-            unsigned    m_succNum;
-
-        public:
-            iterator(Compiler* comp, BasicBlock* block, unsigned succNum)
-                : m_comp(comp)
-                , m_block(block)
-                , m_succNum(succNum)
-            {
-            }
-
-            BasicBlock* operator*() const
-            {
-                assert(m_block != nullptr);
-                BasicBlock* bTarget = m_block->GetSucc(m_succNum, m_comp);
-                assert(bTarget != nullptr);
-                return bTarget;
-            }
-
-            iterator& operator++()
-            {
-                ++m_succNum;
-                return *this;
-            }
-
-            bool operator!=(const iterator& i) const
-            {
-                return m_succNum != i.m_succNum;
-            }
-        };
-
     public:
-        BBCompilerSuccList(Compiler* comp, BasicBlock* block)
-            : m_comp(comp)
-            , m_block(block)
-        {
-        }
+        BBSuccList(const BasicBlock* block);
 
-        iterator begin() const
+        IteratorType begin() const
         {
-            return iterator(m_comp, m_block, 0);
+            return IteratorType(m_begin);
         }
 
-        iterator end() const
+        IteratorType end() const
         {
-            return iterator(m_comp, m_block, m_block->NumSucc(m_comp));
+            return IteratorType(m_end);
         }
     };
 
-    // BBCompilerSuccEdgeList: adapter class for forward iteration of block successors edges, using range-based `for`,
-    // normally used via BasicBlock::SuccEdges(), e.g.:
-    //    for (FlowEdge* const succEdge : block->SuccEdges(compiler)) ...
-    //
-    // This version uses NumSucc(Compiler*)/GetSucc(Compiler*). See the documentation there for the explanation
-    // of the implications of this versus the version that does not take `Compiler*`.
-    class BBCompilerSuccEdgeList
-    {
-        Compiler*   m_comp;
-        BasicBlock* m_block;
-
-        // iterator: forward iterator for an array of BasicBlock*
-        //
-        class iterator
-        {
-            Compiler*   m_comp;
-            BasicBlock* m_block;
-            unsigned    m_succNum;
-
-        public:
-            iterator(Compiler* comp, BasicBlock* block, unsigned succNum)
-                : m_comp(comp)
-                , m_block(block)
-                , m_succNum(succNum)
-            {
-            }
-
-            FlowEdge* operator*() const
-            {
-                assert(m_block != nullptr);
-                FlowEdge* succEdge = m_block->GetSuccEdge(m_succNum, m_comp);
-                assert(succEdge != nullptr);
-                return succEdge;
-            }
-
-            iterator& operator++()
-            {
-                ++m_succNum;
-                return *this;
-            }
-
-            bool operator!=(const iterator& i) const
-            {
-                return m_succNum != i.m_succNum;
-            }
-        };
-
-    public:
-        BBCompilerSuccEdgeList(Compiler* comp, BasicBlock* block)
-            : m_comp(comp)
-            , m_block(block)
-        {
-        }
-
-        iterator begin() const
-        {
-            return iterator(m_comp, m_block, 0);
-        }
-
-        iterator end() const
-        {
-            return iterator(m_comp, m_block, m_block->NumSucc(m_comp));
-        }
-    };
-
-    // Succs: convenience methods for enabling range-based `for` iteration over a block's successors, e.g.:
+    // Succs: convenience method for enabling range-based `for` iteration over unique successor blocks, e.g.:
     //    for (BasicBlock* const succ : block->Succs()) ...
     //
-    // There are two options: one that takes a Compiler* and one that doesn't. These correspond to the
-    // NumSucc()/GetSucc() functions that do or do not take a Compiler*. See the comment for NumSucc()/GetSucc()
-    // for the distinction.
-    BBSuccList Succs() const
+    BBSuccList Succs() const
     {
-        return BBSuccList(this);
+        return BBSuccList(this);
     }
 
-    BBCompilerSuccList Succs(Compiler* comp)
-    {
-        return BBCompilerSuccList(comp, this);
-    }
-
-    BBSuccEdgeList SuccEdges()
-    {
-        return BBSuccEdgeList(this);
-    }
-
-    BBCompilerSuccEdgeList SuccEdges(Compiler* comp)
+    // SuccEdges: convenience method for enabling range-based `for` iteration over unique successor edges, e.g.:
+    //    for (FlowEdge* const edge : block->SuccEdges()) ...
+    //
+    BBSuccList SuccEdges()
     {
-        return BBCompilerSuccEdgeList(comp, this);
+        return BBSuccList(this);
     }
 
     // Clone block state and statements from `from` block to `to` block (which must be new/empty)
@@ -2280,7 +1988,72 @@ class BasicBlockRangeList
         return BasicBlockIterator(m_end->Next()); // walk until we see the block *following* the `m_end` block
     }
 
-    bool ComplexityExceeds(Compiler* comp, unsigned limit, unsigned* count = nullptr);
+    template 
+    bool ComplexityExceeds(Compiler* comp, unsigned limit, TFunc getTreeComplexity);
+};
+
+// 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
@@ -2292,11 +2065,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)
@@ -2305,91 +2087,120 @@ 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
+// BBSuccList out-of-class-declaration implementations
 //
-inline BasicBlock::SuccList::SuccList(const BasicBlock* block)
+template 
+inline BasicBlock::BBSuccList::BBSuccList(const BasicBlock* block)
 {
     assert(block != nullptr);
 
@@ -2418,7 +2229,7 @@ inline BasicBlock::SuccList::SuccList(const BasicBlock* block)
             m_succs[0] = block->GetFalseEdge();
             m_begin    = &m_succs[0];
 
-            // If both fall-through and branch successors are identical, then only include
+            // If the true/false successors are identical, then only include
             // them once in the iteration (this is the same behavior as NumSucc()/GetSucc()).
             if (block->TrueEdgeIs(block->GetFalseEdge()))
             {
@@ -2442,17 +2253,16 @@ 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->GetSwitchTargets() != nullptr);
+            m_begin = block->GetSwitchTargets()->GetSuccs();
+            m_end   = block->GetSwitchTargets()->GetSuccs() + block->GetSwitchTargets()->GetSuccCount();
             break;
 
         default:
diff --git a/src/coreclr/jit/clrjit.natvis b/src/coreclr/jit/clrjit.natvis
index 424bd4e3f2dca0..b38738ea9eddb5 100644
--- a/src/coreclr/jit/clrjit.natvis
+++ b/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/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h
index b099e7df8cba1e..2a2c7a6b8656fd 100644
--- a/src/coreclr/jit/codegen.h
+++ b/src/coreclr/jit/codegen.h
@@ -742,6 +742,7 @@ class CodeGen final : public CodeGenInterface
 #endif
     void genCodeForTreeNode(GenTree* treeNode);
     void genCodeForBinary(GenTreeOp* treeNode);
+    bool genIsSameLocalVar(GenTree* tree1, GenTree* tree2);
 
 #if defined(TARGET_X86)
     void genCodeForLongUMod(GenTreeOp* node);
@@ -1338,7 +1339,7 @@ class CodeGen final : public CodeGenInterface
     void inst_JMP(emitJumpKind jmp, BasicBlock* tgtBlock);
 #endif
 
-    void inst_SET(emitJumpKind condition, regNumber reg);
+    void inst_SET(emitJumpKind condition, regNumber reg, insOpts instOptions = INS_OPTS_NONE);
 
     void inst_RV(instruction ins, regNumber reg, var_types type, emitAttr size = EA_UNKNOWN);
 
diff --git a/src/coreclr/jit/codegenarm.cpp b/src/coreclr/jit/codegenarm.cpp
index 0a7f9b21d9eeab..d8d3a191d41b6f 100644
--- a/src/coreclr/jit/codegenarm.cpp
+++ b/src/coreclr/jit/codegenarm.cpp
@@ -61,6 +61,11 @@ bool CodeGen::genInstrWithConstant(
     {
         case INS_add:
         case INS_sub:
+            if (imm < 0)
+            {
+                imm = -imm;
+                ins = (ins == INS_add) ? INS_sub : INS_add;
+            }
             immFitsInIns = validImmForInstr(ins, (target_ssize_t)imm, flags);
             break;
 
diff --git a/src/coreclr/jit/codegenarm64test.cpp b/src/coreclr/jit/codegenarm64test.cpp
index a66e626a6e22a6..2c7de903fded27 100644
--- a/src/coreclr/jit/codegenarm64test.cpp
+++ b/src/coreclr/jit/codegenarm64test.cpp
@@ -4685,11 +4685,13 @@ void CodeGen::genArm64EmitterUnitTestsSve()
     theEmitter->emitIns_R_R_R(INS_sve_urshlr, EA_SCALABLE, REG_V15, REG_P2, REG_V20,
                               INS_OPTS_SCALABLE_D); // URSHLR  ., /M, ., .
 
+#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED
     // IF_SVE_AB_3B
     theEmitter->emitIns_R_R_R(INS_sve_addpt, EA_SCALABLE, REG_V0, REG_P1, REG_V2,
                               INS_OPTS_SCALABLE_D); // ADDPT .D, /M, .D, .D
     theEmitter->emitIns_R_R_R(INS_sve_subpt, EA_SCALABLE, REG_V0, REG_P1, REG_V2,
                               INS_OPTS_SCALABLE_D); // SUBPT .D, /M, .D, .D
+#endif                                              // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED
 
     // IF_SVE_AC_3A
     theEmitter->emitIns_R_R_R(INS_sve_sdiv, EA_SCALABLE, REG_V3, REG_P2, REG_V9,
@@ -5117,10 +5119,12 @@ void CodeGen::genArm64EmitterUnitTestsSve()
                               INS_OPTS_SCALABLE_H); // FABD    ., /M, ., .
     theEmitter->emitIns_R_R_R(INS_sve_fadd, EA_SCALABLE, REG_V25, REG_P2, REG_V10,
                               INS_OPTS_SCALABLE_S); // FADD    ., /M, ., .
+#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED
     theEmitter->emitIns_R_R_R(INS_sve_famax, EA_SCALABLE, REG_V26, REG_P1, REG_V9,
                               INS_OPTS_SCALABLE_D); // FAMAX   ., /M, ., .
     theEmitter->emitIns_R_R_R(INS_sve_famin, EA_SCALABLE, REG_V27, REG_P0, REG_V8,
                               INS_OPTS_SCALABLE_H); // FAMIN   ., /M, ., .
+#endif                                              // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED
     theEmitter->emitIns_R_R_R(INS_sve_fdiv, EA_SCALABLE, REG_V28, REG_P0, REG_V7,
                               INS_OPTS_SCALABLE_S); // FDIV    ., /M, ., .
     theEmitter->emitIns_R_R_R(INS_sve_fdivr, EA_SCALABLE, REG_V29, REG_P1, REG_V6,
@@ -5288,6 +5292,7 @@ void CodeGen::genArm64EmitterUnitTestsSve()
     theEmitter->emitIns_R_R_R(INS_sve_orv, EA_SCALABLE, REG_V3, REG_P3, REG_V3,
                               INS_OPTS_SCALABLE_D); // ORV     , , .
 
+#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED
     // IF_SVE_AG_3A
     theEmitter->emitIns_R_R_R(INS_sve_andqv, EA_8BYTE, REG_V4, REG_P4, REG_V4,
                               INS_OPTS_SCALABLE_B); // ANDQV   ., , .
@@ -5298,6 +5303,11 @@ void CodeGen::genArm64EmitterUnitTestsSve()
     theEmitter->emitIns_R_R_R(INS_sve_orqv, EA_8BYTE, REG_V7, REG_P7, REG_V7,
                               INS_OPTS_SCALABLE_D); // ORQV    ., , .
 
+    // IF_SVE_AJ_3A
+    theEmitter->emitIns_R_R_R(INS_sve_addqv, EA_8BYTE, REG_V21, REG_P7, REG_V22,
+                              INS_OPTS_SCALABLE_B); // ADDQV   ., , .
+#endif                                              // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED
+
     // IF_SVE_AI_3A
     theEmitter->emitIns_R_R_R(INS_sve_saddv, EA_SCALABLE, REG_V1, REG_P4, REG_V2,
                               INS_OPTS_SCALABLE_B); // SADDV   
, , . @@ -5306,10 +5316,6 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R_R(INS_sve_uaddv, EA_SCALABLE, REG_V3, REG_P6, REG_V4, INS_OPTS_SCALABLE_S); // UADDV
, , . - // IF_SVE_AJ_3A - theEmitter->emitIns_R_R_R(INS_sve_addqv, EA_8BYTE, REG_V21, REG_P7, REG_V22, - INS_OPTS_SCALABLE_B); // ADDQV ., , . - // IF_SVE_AK_3A theEmitter->emitIns_R_R_R(INS_sve_smaxv, EA_SCALABLE, REG_V15, REG_P7, REG_V4, INS_OPTS_SCALABLE_D); // SMAXV , , . @@ -5320,6 +5326,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R_R(INS_sve_uminv, EA_SCALABLE, REG_V18, REG_P4, REG_V31, INS_OPTS_SCALABLE_B); // UMINV , , . +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_AL_3A theEmitter->emitIns_R_R_R(INS_sve_smaxqv, EA_8BYTE, REG_V0, REG_P5, REG_V25, INS_OPTS_SCALABLE_B); // SMAXQV ., , . @@ -5329,6 +5336,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_OPTS_SCALABLE_S); // UMAXQV ., , . theEmitter->emitIns_R_R_R(INS_sve_uminqv, EA_8BYTE, REG_V3, REG_P2, REG_V22, INS_OPTS_SCALABLE_D); // UMINQV ., , . +#endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_AP_3A theEmitter->emitIns_R_R_R(INS_sve_cls, EA_SCALABLE, REG_V31, REG_P0, REG_V0, @@ -5722,13 +5730,13 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R_R(INS_sve_sqdmlslbt, EA_SCALABLE, REG_V6, REG_V7, REG_V8, INS_OPTS_SCALABLE_D); // SQDMLSLBT ., ., . theEmitter->emitIns_R_R_R(INS_sve_sqdmlalb, EA_SCALABLE, REG_V0, REG_V1, REG_V2, - INS_OPTS_SCALABLE_H); // SQDMLALB ., ., . + INS_OPTS_SCALABLE_S); // SQDMLALB ., ., . theEmitter->emitIns_R_R_R(INS_sve_sqdmlalt, EA_SCALABLE, REG_V3, REG_V4, REG_V5, INS_OPTS_SCALABLE_S); // SQDMLALT ., ., . theEmitter->emitIns_R_R_R(INS_sve_sqdmlslb, EA_SCALABLE, REG_V6, REG_V7, REG_V8, INS_OPTS_SCALABLE_D); // SQDMLSLB ., ., . theEmitter->emitIns_R_R_R(INS_sve_sqdmlslt, EA_SCALABLE, REG_V9, REG_V10, REG_V11, - INS_OPTS_SCALABLE_H); // SQDMLSLT ., ., . + INS_OPTS_SCALABLE_D); // SQDMLSLT ., ., . theEmitter->emitIns_R_R_R(INS_sve_sabalb, EA_SCALABLE, REG_V0, REG_V1, REG_V2, INS_OPTS_SCALABLE_H); // SABALB ., ., . theEmitter->emitIns_R_R_R(INS_sve_sabalt, EA_SCALABLE, REG_V3, REG_V4, REG_V5, @@ -5884,11 +5892,13 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R_R(INS_sve_bfsub, EA_SCALABLE, REG_V6, REG_V7, REG_V8, INS_OPTS_SCALABLE_H); // BFSUB .H, .H, .H +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_AT_3B theEmitter->emitIns_R_R_R(INS_sve_addpt, EA_SCALABLE, REG_V0, REG_V1, REG_V2, INS_OPTS_SCALABLE_D); // ADDPT .D, .D, .D theEmitter->emitIns_R_R_R(INS_sve_subpt, EA_SCALABLE, REG_V3, REG_V4, REG_V5, INS_OPTS_SCALABLE_D); // SUBPT .D, .D, .D +#endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_AU_3A theEmitter->emitIns_R_R_R(INS_sve_and, EA_SCALABLE, REG_V0, REG_V1, REG_V2, INS_OPTS_SCALABLE_D); // AND .D, @@ -6093,6 +6103,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_PATTERN_I(INS_sve_uqincw, EA_SCALABLE, REG_V11, SVE_PATTERN_ALL, 16, INS_OPTS_SCALABLE_S); // UQINCW .S{, {, MUL #}} +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_BQ_2A theEmitter->emitIns_R_R_I(INS_sve_ext, EA_SCALABLE, REG_V0, REG_V1, 0, INS_OPTS_SCALABLE_B, INS_SCALABLE_OPTS_WITH_VECTOR_PAIR); // EXT .B, {.B, .B }, # @@ -6102,6 +6113,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_SCALABLE_OPTS_WITH_VECTOR_PAIR); // EXT .B, {.B, .B }, # theEmitter->emitIns_R_R_I(INS_sve_ext, EA_SCALABLE, REG_V6, REG_FP_LAST, 255, INS_OPTS_SCALABLE_B, INS_SCALABLE_OPTS_WITH_VECTOR_PAIR); // EXT .B, {.B, .B }, # +#endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_BQ_2B theEmitter->emitIns_R_R_I(INS_sve_ext, EA_SCALABLE, REG_V0, REG_V1, 0, @@ -6283,11 +6295,13 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R(INS_sve_sqcvtun, EA_SCALABLE, REG_V6, REG_V8); // SQCVTUN .H, {.S-.S } theEmitter->emitIns_R_R(INS_sve_uqcvtn, EA_SCALABLE, REG_V14, REG_V16); // UQCVTN .H, {.S-.S } +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_HG_2A theEmitter->emitIns_R_R(INS_sve_bfcvtn, EA_SCALABLE, REG_V0, REG_V2); // BFCVTN .B, {.H-.H } theEmitter->emitIns_R_R(INS_sve_fcvtn, EA_SCALABLE, REG_V2, REG_V4); // FCVTN .B, {.H-.H } theEmitter->emitIns_R_R(INS_sve_fcvtnb, EA_SCALABLE, REG_V6, REG_V8); // FCVTNB .B, {.S-.S } theEmitter->emitIns_R_R(INS_sve_fcvtnt, EA_SCALABLE, REG_V14, REG_V16); // FCVTNT .B, {.S-.S } +#endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_GA_2A theEmitter->emitIns_R_R_I(INS_sve_sqrshrn, EA_SCALABLE, REG_V0, REG_V0, 5, @@ -6522,6 +6536,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R(INS_sve_aesimc, EA_SCALABLE, REG_V0); // AESIMC .B, .B theEmitter->emitIns_R(INS_sve_aesmc, EA_SCALABLE, REG_V5); // AESMC .B, .B +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_GN_3A theEmitter->emitIns_R_R_R(INS_sve_fmlalb, EA_SCALABLE, REG_V0, REG_V1, REG_V2, INS_OPTS_SCALABLE_B); // FMLALB .H, .B, .B @@ -6549,6 +6564,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_OPTS_SCALABLE_H); // FMINNMQV ., , . theEmitter->emitIns_R_R_R(INS_sve_fminqv, EA_8BYTE, REG_V20, REG_P5, REG_V8, INS_OPTS_SCALABLE_D); // FMINQV ., , . +#endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_GU_3A theEmitter->emitIns_R_R_R_I(INS_sve_fmla, EA_SCALABLE, REG_V0, REG_V2, REG_V1, 0, @@ -6630,6 +6646,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R_R_I(INS_sve_bfdot, EA_SCALABLE, REG_V12, REG_V14, REG_V7, 3, INS_OPTS_SCALABLE_H); // BFDOT .S, .H, .H[] +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_GY_3A theEmitter->emitIns_R_R_R_I(INS_sve_fdot, EA_SCALABLE, REG_V0, REG_V2, REG_V1, 1); // FDOT .H, .B, .B[] @@ -6649,6 +6666,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_OPTS_SCALABLE_B); // FDOT .S, .B, .B[] theEmitter->emitIns_R_R_R_I(INS_sve_fdot, EA_SCALABLE, REG_V12, REG_V14, REG_V7, 3, INS_OPTS_SCALABLE_B); // FDOT .S, .B, .B[] +#endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_GZ_3A theEmitter->emitIns_R_R_R_I(INS_sve_bfmlalb, EA_SCALABLE, REG_V0, REG_V1, REG_V0, 0, @@ -6674,12 +6692,14 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R_R(INS_sve_fdot, EA_SCALABLE, REG_V3, REG_V4, REG_V5, INS_OPTS_SCALABLE_H); // FDOT .S, .H, .H +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_HA_3A_E theEmitter->emitIns_R_R_R(INS_sve_fdot, EA_SCALABLE, REG_V6, REG_V7, REG_V8, INS_OPTS_SCALABLE_B); // FDOT .H, .B, .B // IF_SVE_HA_3A_F theEmitter->emitIns_R_R_R(INS_sve_fdot, EA_SCALABLE, REG_V9, REG_V10, REG_V11); // FDOT .S, .B, .B +#endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_HB_3A theEmitter->emitIns_R_R_R(INS_sve_bfmlalb, EA_SCALABLE, REG_V0, REG_V1, REG_V2, @@ -6703,9 +6723,11 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R_R(INS_sve_bfmmla, EA_SCALABLE, REG_V0, REG_V1, REG_V2, INS_OPTS_SCALABLE_H); // BFMMLA .S, .H, .H +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_HD_3A_A theEmitter->emitIns_R_R_R(INS_sve_fmmla, EA_SCALABLE, REG_V3, REG_V4, REG_V5, INS_OPTS_SCALABLE_D); // FMMLA .D, .D, .D +#endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_HE_3A theEmitter->emitIns_R_R_R(INS_sve_faddv, EA_SCALABLE, REG_V21, REG_P7, REG_V7, @@ -6793,6 +6815,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R_R(INS_sve_whilewr, EA_8BYTE, REG_P7, REG_R14, REG_R15, INS_OPTS_SCALABLE_D); // WHILEWR ., , +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_DV_4A theEmitter->emitIns_R_R_R_R_I(INS_sve_psel, EA_SCALABLE, REG_P0, REG_P1, REG_P2, REG_R12, 15, INS_OPTS_SCALABLE_B); // PSEL , , .[, ] @@ -6802,6 +6825,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_OPTS_SCALABLE_S); // PSEL , , .[, ] theEmitter->emitIns_R_R_R_R_I(INS_sve_psel, EA_SCALABLE, REG_P9, REG_P10, REG_P11, REG_R15, 1, INS_OPTS_SCALABLE_D); // PSEL , , .[, ] +#endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_DW_2A theEmitter->emitIns_R_R_I(INS_sve_pext, EA_SCALABLE, REG_P0, REG_P8, 0, @@ -6953,26 +6977,28 @@ void CodeGen::genArm64EmitterUnitTestsSve() // IF_SVE_EK_3A theEmitter->emitIns_R_R_R_I(INS_sve_cmla, EA_SCALABLE, REG_V0, REG_V1, REG_V2, 0, INS_OPTS_SCALABLE_B); // CMLA ., ., ., - theEmitter->emitIns_R_R_R_I(INS_sve_cmla, EA_SCALABLE, REG_V3, REG_V4, REG_V5, 90, + theEmitter->emitIns_R_R_R_I(INS_sve_cmla, EA_SCALABLE, REG_V3, REG_V4, REG_V5, 1, INS_OPTS_SCALABLE_H); // CMLA ., ., ., - theEmitter->emitIns_R_R_R_I(INS_sve_cmla, EA_SCALABLE, REG_V6, REG_V7, REG_V8, 180, + theEmitter->emitIns_R_R_R_I(INS_sve_cmla, EA_SCALABLE, REG_V6, REG_V7, REG_V8, 2, INS_OPTS_SCALABLE_S); // CMLA ., ., ., - theEmitter->emitIns_R_R_R_I(INS_sve_cmla, EA_SCALABLE, REG_V9, REG_V10, REG_V11, 270, + theEmitter->emitIns_R_R_R_I(INS_sve_cmla, EA_SCALABLE, REG_V9, REG_V10, REG_V11, 3, INS_OPTS_SCALABLE_D); // CMLA ., ., ., theEmitter->emitIns_R_R_R_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V12, REG_V13, REG_V14, 0, INS_OPTS_SCALABLE_B); // SQRDCMLAH ., ., ., - theEmitter->emitIns_R_R_R_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V15, REG_V16, REG_V17, 90, + theEmitter->emitIns_R_R_R_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V15, REG_V16, REG_V17, 1, INS_OPTS_SCALABLE_H); // SQRDCMLAH ., ., ., - theEmitter->emitIns_R_R_R_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V18, REG_V19, REG_V20, 180, + theEmitter->emitIns_R_R_R_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V18, REG_V19, REG_V20, 2, INS_OPTS_SCALABLE_S); // SQRDCMLAH ., ., ., - theEmitter->emitIns_R_R_R_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V21, REG_V22, REG_V23, 270, + theEmitter->emitIns_R_R_R_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V21, REG_V22, REG_V23, 3, INS_OPTS_SCALABLE_D); // SQRDCMLAH ., ., ., +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_EW_3A theEmitter->emitIns_R_R_R(INS_sve_mlapt, EA_SCALABLE, REG_V0, REG_V1, REG_V2); // MLAPT .D, .D, .D // IF_SVE_EW_3B theEmitter->emitIns_R_R_R(INS_sve_madpt, EA_SCALABLE, REG_V3, REG_V4, REG_V5); // MADPT .D, .D, .D +#endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_EY_3A theEmitter->emitIns_R_R_R_I(INS_sve_sdot, EA_SCALABLE, REG_V9, REG_V10, REG_V4, 0, @@ -7036,95 +7062,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 +7184,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, @@ -7263,21 +7289,21 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_OPTS_SCALABLE_D); // USHLLT ., ., # // IF_SVE_FV_2A - theEmitter->emitIns_R_R_I(INS_sve_cadd, EA_SCALABLE, REG_V0, REG_V1, 90, + theEmitter->emitIns_R_R_I(INS_sve_cadd, EA_SCALABLE, REG_V0, REG_V1, 0, INS_OPTS_SCALABLE_B); // CADD ., ., ., - theEmitter->emitIns_R_R_I(INS_sve_cadd, EA_SCALABLE, REG_V2, REG_V3, 90, + theEmitter->emitIns_R_R_I(INS_sve_cadd, EA_SCALABLE, REG_V2, REG_V3, 0, INS_OPTS_SCALABLE_H); // CADD ., ., ., - theEmitter->emitIns_R_R_I(INS_sve_cadd, EA_SCALABLE, REG_V4, REG_V5, 270, + theEmitter->emitIns_R_R_I(INS_sve_cadd, EA_SCALABLE, REG_V4, REG_V5, 1, INS_OPTS_SCALABLE_S); // CADD ., ., ., - theEmitter->emitIns_R_R_I(INS_sve_cadd, EA_SCALABLE, REG_V6, REG_V7, 270, + theEmitter->emitIns_R_R_I(INS_sve_cadd, EA_SCALABLE, REG_V6, REG_V7, 1, INS_OPTS_SCALABLE_D); // CADD ., ., ., - theEmitter->emitIns_R_R_I(INS_sve_sqcadd, EA_SCALABLE, REG_V8, REG_V9, 270, + theEmitter->emitIns_R_R_I(INS_sve_sqcadd, EA_SCALABLE, REG_V8, REG_V9, 1, INS_OPTS_SCALABLE_B); // SQCADD ., ., ., - theEmitter->emitIns_R_R_I(INS_sve_sqcadd, EA_SCALABLE, REG_V10, REG_V11, 270, + theEmitter->emitIns_R_R_I(INS_sve_sqcadd, EA_SCALABLE, REG_V10, REG_V11, 1, INS_OPTS_SCALABLE_H); // SQCADD ., ., ., - theEmitter->emitIns_R_R_I(INS_sve_sqcadd, EA_SCALABLE, REG_V12, REG_V13, 90, + theEmitter->emitIns_R_R_I(INS_sve_sqcadd, EA_SCALABLE, REG_V12, REG_V13, 0, INS_OPTS_SCALABLE_S); // SQCADD ., ., ., - theEmitter->emitIns_R_R_I(INS_sve_sqcadd, EA_SCALABLE, REG_V14, REG_V15, 90, + theEmitter->emitIns_R_R_I(INS_sve_sqcadd, EA_SCALABLE, REG_V14, REG_V15, 0, INS_OPTS_SCALABLE_D); // SQCADD ., ., ., // IF_SVE_FY_3A @@ -7339,61 +7365,61 @@ void CodeGen::genArm64EmitterUnitTestsSve() // IF_SVE_FA_3A theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V0, REG_V7, REG_V1, 3, 0, INS_OPTS_SCALABLE_B); // CDOT .S, .B, .B[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V2, REG_V5, REG_V3, 2, 90, + theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V2, REG_V5, REG_V3, 2, 1, INS_OPTS_SCALABLE_B); // CDOT .S, .B, .B[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V4, REG_V3, REG_V5, 1, 180, + theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V4, REG_V3, REG_V5, 1, 2, INS_OPTS_SCALABLE_B); // CDOT .S, .B, .B[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V6, REG_V1, REG_V7, 0, 270, + theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V6, REG_V1, REG_V7, 0, 3, INS_OPTS_SCALABLE_B); // CDOT .S, .B, .B[], // IF_SVE_FA_3B theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V0, REG_V1, REG_V0, 0, 0, INS_OPTS_SCALABLE_H); // CDOT .D, .H, .H[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V2, REG_V3, REG_V5, 1, 90, + theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V2, REG_V3, REG_V5, 1, 1, INS_OPTS_SCALABLE_H); // CDOT .D, .H, .H[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V4, REG_V5, REG_V10, 0, 180, + theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V4, REG_V5, REG_V10, 0, 2, INS_OPTS_SCALABLE_H); // CDOT .D, .H, .H[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V6, REG_V7, REG_V15, 1, 270, + theEmitter->emitIns_R_R_R_I_I(INS_sve_cdot, EA_SCALABLE, REG_V6, REG_V7, REG_V15, 1, 3, INS_OPTS_SCALABLE_H); // CDOT .D, .H, .H[], // IF_SVE_FB_3A theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V0, REG_V7, REG_V1, 3, 0, INS_OPTS_SCALABLE_H); // CMLA .H, .H, .H[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V2, REG_V5, REG_V3, 2, 90, + theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V2, REG_V5, REG_V3, 2, 1, INS_OPTS_SCALABLE_H); // CMLA .H, .H, .H[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V4, REG_V3, REG_V5, 1, 180, + theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V4, REG_V3, REG_V5, 1, 2, INS_OPTS_SCALABLE_H); // CMLA .H, .H, .H[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V6, REG_V1, REG_V7, 0, 270, + theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V6, REG_V1, REG_V7, 0, 3, INS_OPTS_SCALABLE_H); // CMLA .H, .H, .H[], // IF_SVE_FB_3B theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V0, REG_V1, REG_V0, 0, 0, INS_OPTS_SCALABLE_S); // CMLA .S, .S, .S[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V2, REG_V3, REG_V5, 1, 90, + theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V2, REG_V3, REG_V5, 1, 1, INS_OPTS_SCALABLE_S); // CMLA .S, .S, .S[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V4, REG_V5, REG_V10, 0, 180, + theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V4, REG_V5, REG_V10, 0, 2, INS_OPTS_SCALABLE_S); // CMLA .S, .S, .S[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V6, REG_V7, REG_V15, 1, 270, + theEmitter->emitIns_R_R_R_I_I(INS_sve_cmla, EA_SCALABLE, REG_V6, REG_V7, REG_V15, 1, 3, INS_OPTS_SCALABLE_S); // CMLA .S, .S, .S[], // IF_SVE_FC_3A theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V0, REG_V7, REG_V1, 3, 0, INS_OPTS_SCALABLE_H); // SQRDCMLAH .H, .H, .H[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V2, REG_V5, REG_V3, 2, 90, + theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V2, REG_V5, REG_V3, 2, 1, INS_OPTS_SCALABLE_H); // SQRDCMLAH .H, .H, .H[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V4, REG_V3, REG_V5, 1, 180, + theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V4, REG_V3, REG_V5, 1, 2, INS_OPTS_SCALABLE_H); // SQRDCMLAH .H, .H, .H[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V6, REG_V1, REG_V7, 0, 270, + theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V6, REG_V1, REG_V7, 0, 3, INS_OPTS_SCALABLE_H); // SQRDCMLAH .H, .H, .H[], // IF_SVE_FC_3B theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V0, REG_V1, REG_V0, 0, 0, INS_OPTS_SCALABLE_S); // SQRDCMLAH .S, .S, .S[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V2, REG_V3, REG_V5, 1, 90, + theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V2, REG_V3, REG_V5, 1, 1, INS_OPTS_SCALABLE_S); // SQRDCMLAH .S, .S, .S[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V4, REG_V5, REG_V10, 0, 180, + theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V4, REG_V5, REG_V10, 0, 2, INS_OPTS_SCALABLE_S); // SQRDCMLAH .S, .S, .S[], - theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V6, REG_V7, REG_V15, 1, 270, + theEmitter->emitIns_R_R_R_I_I(INS_sve_sqrdcmlah, EA_SCALABLE, REG_V6, REG_V7, REG_V15, 1, 3, INS_OPTS_SCALABLE_S); // SQRDCMLAH .S, .S, .S[], // IF_SVE_IH_3A @@ -8512,6 +8538,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R_I(INS_sve_str, EA_SCALABLE, REG_V2, REG_R3, -256, INS_OPTS_NONE); theEmitter->emitIns_R_R_I(INS_sve_str, EA_SCALABLE, REG_V2, REG_R3, 255, INS_OPTS_NONE); +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_GG_3A // LUTI2 .B, {.B }, [] // luti2 z0.b, {z0.b}, z0[0] // 01000101-00100000-10110000-00000000 @@ -8581,6 +8608,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() // CHECK-INST: luti4 z31.b, { z31.b }, z31[1] // CHECK-ENCODING: [0xff,0xa7,0xff,0x45] theEmitter->emitIns_R_R_R_I(INS_sve_luti4, EA_SCALABLE, REG_V31, REG_V31, REG_V31, 1, INS_OPTS_SCALABLE_B); +#endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_HY_3A theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P1, REG_R2, REG_V3, @@ -8876,6 +8904,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() // FEXPA ., . theEmitter->emitIns_R_R(INS_sve_fexpa, EA_SCALABLE, REG_V1, REG_V0, INS_OPTS_SCALABLE_D); +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_HH_2A // BF1CVT .H, .B theEmitter->emitIns_R_R(INS_sve_bf1cvt, EA_SCALABLE, REG_V2, REG_V3, INS_OPTS_SCALABLE_H); @@ -8893,6 +8922,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R(INS_sve_f2cvt, EA_SCALABLE, REG_V3, REG_V4, INS_OPTS_SCALABLE_H); // F2CVTLT .H, .B theEmitter->emitIns_R_R(INS_sve_f2cvtlt, EA_SCALABLE, REG_V1, REG_V2, INS_OPTS_SCALABLE_H); +#endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_BI_2A // MOVPRFX , diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 22ec04909917e9..d5d04802c56125 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/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); @@ -636,6 +636,25 @@ regMaskTP CodeGenInterface::genGetRegMask(GenTree* tree) return regMask; } +//------------------------------------------------------------------------ +// genIsSameLocalVar: +// Check if two trees represent the same scalar local value. +// +// Arguments: +// op1 - first tree +// op2 - second tree +// +// Returns: +// True if so. +// +bool CodeGen::genIsSameLocalVar(GenTree* op1, GenTree* op2) +{ + GenTree* op1Skip = op1->gtSkipReloadOrCopy(); + GenTree* op2Skip = op2->gtSkipReloadOrCopy(); + return op1Skip->OperIs(GT_LCL_VAR) && op2Skip->OperIs(GT_LCL_VAR) && + (op1Skip->AsLclVar()->GetLclNum() == op2Skip->AsLclVar()->GetLclNum()); +} + // The given lclVar is either going live (being born) or dying. // It might be both going live and dying (that is, it is a dead store) under MinOpts. // Update regSet.GetMaskVars() accordingly. @@ -5564,17 +5583,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/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index 67467b5c71ee85..339ac1eab1610d 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -174,7 +174,7 @@ void CodeGen::genCodeForBBlist() if (compiler->verbose) { printf("\n=============== Generating "); - block->dspBlockHeader(compiler, true, true); + block->dspBlockHeader(true, true); compiler->fgDispBBLiveness(block); } #endif // DEBUG diff --git a/src/coreclr/jit/codegenloongarch64.cpp b/src/coreclr/jit/codegenloongarch64.cpp index 4111afcafd9b53..5372b7f62f3d93 100644 --- a/src/coreclr/jit/codegenloongarch64.cpp +++ b/src/coreclr/jit/codegenloongarch64.cpp @@ -632,6 +632,8 @@ void CodeGen::genFnEpilog(BasicBlock* block) compiler->unwindBegEpilog(); + genPopCalleeSavedRegisters(); + if (jmpEpilog) { SetHasTailCalls(true); @@ -644,7 +646,6 @@ void CodeGen::genFnEpilog(BasicBlock* block) #if !FEATURE_FASTTAILCALL noway_assert(jmpNode->OperIs(GT_JMP)); #else // FEATURE_FASTTAILCALL - // armarch // If jmpNode is GT_JMP then gtNext must be null. // If jmpNode is a fast tail call, gtNext need not be null since it could have embedded stmts. noway_assert(!jmpNode->OperIs(GT_JMP) || (jmpNode->gtNext == nullptr)); @@ -699,28 +700,20 @@ void CodeGen::genFnEpilog(BasicBlock* block) NO_WAY("Unsupported JMP indirection"); } - /* Simply emit a jump to the methodHnd. This is similar to a call so we can use - * the same descriptor with some minor adjustments. - */ - - genPopCalleeSavedRegisters(true); - + // Simply emit a jump to the methodHnd. This is similar to a call so we can use + // the same descriptor with some minor adjustments. params.isJump = true; - genEmitCallWithCurrentGC(params); } #if FEATURE_FASTTAILCALL else { - genPopCalleeSavedRegisters(true); genCallInstruction(jmpNode->AsCall()); } #endif // FEATURE_FASTTAILCALL } else { - genPopCalleeSavedRegisters(false); - GetEmitter()->emitIns_R_R_I(INS_jirl, EA_PTRSIZE, REG_R0, REG_RA, 0); compiler->unwindReturn(REG_RA); } diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp index ada2c9268d527a..33aa6649261d7a 100644 --- a/src/coreclr/jit/codegenriscv64.cpp +++ b/src/coreclr/jit/codegenriscv64.cpp @@ -981,7 +981,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(constValue, size); // Compute the address of the FP constant and load the data. - emit->emitIns_R_C(size == EA_4BYTE ? INS_flw : INS_fld, size, targetReg, REG_NA, hnd, 0); + emit->emitIns_R_C(size == EA_4BYTE ? INS_flw : INS_fld, size, targetReg, REG_NA, hnd); } break; @@ -1009,7 +1009,7 @@ void CodeGen::genCodeForIncSaturate(GenTree* tree) GetEmitter()->emitIns_R_R_I(INS_addi, attr, targetReg, operandReg, 1); // bne targetReg, zero, 2 * 4 GetEmitter()->emitIns_R_R_I(INS_bne, attr, targetReg, REG_R0, 8); - GetEmitter()->emitIns_R_R_I(INS_xori, attr, targetReg, targetReg, -1); + GetEmitter()->emitIns_R_R(INS_not, attr, targetReg, targetReg); genProduceReg(tree); } @@ -1691,7 +1691,7 @@ void CodeGen::genCodeForNegNot(GenTree* tree) else if (tree->OperIs(GT_NOT)) { assert(!varTypeIsFloating(targetType)); - GetEmitter()->emitIns_R_R_I(INS_xori, attr, targetReg, operandReg, -1); + GetEmitter()->emitIns_R_R(INS_not, attr, targetReg, operandReg); } genProduceReg(tree); @@ -2190,8 +2190,19 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode) regNumber tmpReg = internalRegisters.GetSingle(treeNode); // load the ip-relative offset (which is relative to start of fgFirstBB) - GetEmitter()->emitIns_R_R_I(INS_slli, EA_8BYTE, tmpReg, idxReg, 2); - GetEmitter()->emitIns_R_R_R(INS_add, EA_8BYTE, baseReg, baseReg, tmpReg); + assert(treeNode->gtGetOp2()->TypeIs(TYP_I_IMPL)); + if (compiler->compOpportunisticallyDependsOn(InstructionSet_Zba)) + { + emitAttr idxSize = emitTypeSize(treeNode->gtGetOp1()); + instruction sh2add = (idxSize == EA_4BYTE) ? INS_sh2add_uw : INS_sh2add; + GetEmitter()->emitIns_R_R_R(sh2add, idxSize, baseReg, idxReg, baseReg); + } + else + { + assert(treeNode->gtGetOp1()->TypeIs(TYP_I_IMPL)); + GetEmitter()->emitIns_R_R_I(INS_slli, EA_8BYTE, tmpReg, idxReg, 2); + GetEmitter()->emitIns_R_R_R(INS_add, EA_8BYTE, baseReg, baseReg, tmpReg); + } GetEmitter()->emitIns_R_R_I(INS_lw, EA_4BYTE, baseReg, baseReg, 0); // add it to the absolute address of fgFirstBB @@ -2209,8 +2220,8 @@ void CodeGen::genJumpTable(GenTree* treeNode) // Access to inline data is 'abstracted' by a special type of static member // (produced by eeFindJitDataOffs) which the emitter recognizes as being a reference // to constant data, not a real static field. - GetEmitter()->emitIns_R_C(INS_jal, emitActualTypeSize(TYP_I_IMPL), treeNode->GetRegNum(), REG_NA, - compiler->eeFindJitDataOffs(jmpTabBase), 0); + GetEmitter()->emitIns_R_C(INS_addi, emitActualTypeSize(TYP_I_IMPL), treeNode->GetRegNum(), REG_NA, + compiler->eeFindJitDataOffs(jmpTabBase)); genProduceReg(treeNode); } @@ -6511,12 +6522,7 @@ void CodeGen::genJumpToThrowHlpBlk_la( params.addr = helperFunction.addr; params.callType = EC_FUNC_TOKEN; - ssize_t imm = 9 << 2; - if (compiler->opts.compReloc) - { - imm = 3 << 2; - } - + ssize_t imm = 3 * sizeof(emitter::code_t); emit->emitIns_R_R_I(ins, EA_PTRSIZE, reg1, reg2, imm); } else diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 7561351315bd4a..af4031d3520511 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -1143,28 +1143,11 @@ void CodeGen::genCodeForBinary(GenTreeOp* treeNode) // In order for this operation to be correct // we need that op is a commutative operation so // we can convert it into reg1 = reg1 op reg2 and emit - // the same code as above + // the same code as above. Or we need both operands to + // be the same local. else if (op2reg == targetReg) { - -#ifdef DEBUG - unsigned lclNum1 = (unsigned)-1; - unsigned lclNum2 = (unsigned)-2; - - GenTree* op1Skip = op1->gtSkipReloadOrCopy(); - GenTree* op2Skip = op2->gtSkipReloadOrCopy(); - - if (op1Skip->OperIsLocalRead()) - { - lclNum1 = op1Skip->AsLclVarCommon()->GetLclNum(); - } - if (op2Skip->OperIsLocalRead()) - { - lclNum2 = op2Skip->AsLclVarCommon()->GetLclNum(); - } - - assert(GenTree::OperIsCommutative(oper) || (lclNum1 == lclNum2)); -#endif + assert(GenTree::OperIsCommutative(oper) || genIsSameLocalVar(op1, op2)); dst = op2; src = op1; @@ -1807,19 +1790,29 @@ void CodeGen::inst_SETCC(GenCondition condition, var_types type, regNumber dstRe assert(varTypeIsIntegral(type)); assert(genIsValidIntReg(dstReg) && isByteReg(dstReg)); - const GenConditionDesc& desc = GenConditionDesc::Get(condition); + const GenConditionDesc& desc = GenConditionDesc::Get(condition); + insOpts instOptions = INS_OPTS_NONE; - inst_SET(desc.jumpKind1, dstReg); + bool needsMovzx = !varTypeIsByte(type); + if (needsMovzx && compiler->canUseApxEvexEncoding() && JitConfig.EnableApxZU()) + { + instOptions = INS_OPTS_EVEX_zu; + needsMovzx = false; + } + + inst_SET(desc.jumpKind1, dstReg, instOptions); if (desc.oper != GT_NONE) { BasicBlock* labelNext = genCreateTempLabel(); inst_JMP((desc.oper == GT_OR) ? desc.jumpKind1 : emitter::emitReverseJumpKind(desc.jumpKind1), labelNext); - inst_SET(desc.jumpKind2, dstReg); + inst_SET(desc.jumpKind2, dstReg, instOptions); genDefineTempLabel(labelNext); } - if (!varTypeIsByte(type)) + // we can apply EVEX.ZU to avoid this movzx. + // TODO-XArch-apx: evaluate setcc + movzx and xor + set + if (needsMovzx) { GetEmitter()->emitIns_Mov(INS_movzx, EA_1BYTE, dstReg, dstReg, /* canSkip */ false); } @@ -5806,9 +5799,37 @@ void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree) ins = HWIntrinsicInfo::lookupIns(intrinsicId, baseType, compiler); attr = emitActualTypeSize(Compiler::getSIMDTypeForSize(hwintrinsic->GetSimdSize())); - if (intrinsicId == NI_X86Base_Extract) + // We may have opportunistically selected an EVEX only instruction + // that isn't actually required, so fallback to the VEX compatible + // encoding to potentially save on the number of bytes emitted. + + switch (ins) { - ins = INS_pextrw_sse42; + case INS_pextrw: + { + // The encoding which supports containment is SSE4.1+ only + assert(compiler->compIsaSupportedDebugOnly(InstructionSet_SSE42)); + + ins = INS_pextrw_sse42; + break; + } + + case INS_vextractf64x2: + { + ins = INS_vextractf32x4; + break; + } + + case INS_vextracti64x2: + { + ins = INS_vextracti32x4; + break; + } + + default: + { + break; + } } // The hardware intrinsics take unsigned bytes between [0, 255]. @@ -9450,6 +9471,8 @@ void CodeGen::genAmd64EmitterUnitTestsApx() theEmitter->emitIns_Mov(INS_movd32, EA_4BYTE, REG_R16, REG_XMM0, false); theEmitter->emitIns_Mov(INS_movd32, EA_4BYTE, REG_R16, REG_XMM16, false); + + theEmitter->emitIns_R(INS_seto_apx, EA_1BYTE, REG_R11, INS_OPTS_EVEX_zu); } void CodeGen::genAmd64EmitterUnitTestsAvx10v2() @@ -9531,7 +9554,7 @@ void CodeGen::genAmd64EmitterUnitTestsAvx10v2() theEmitter->emitIns_R_R(INS_vcvttps2ibs, EA_16BYTE, REG_XMM0, REG_XMM1); theEmitter->emitIns_R_R(INS_vcvttps2ibs, EA_32BYTE, REG_XMM0, REG_XMM1); - theEmitter->emitIns_R_R(INS_vcvttps2ibs, EA_32BYTE, REG_XMM0, REG_XMM1, INS_OPTS_EVEX_eb_er_rd); + theEmitter->emitIns_R_R(INS_vcvttps2ibs, EA_32BYTE, REG_XMM0, REG_XMM1, INS_OPTS_EVEX_er_rd); theEmitter->emitIns_R_R(INS_vcvttps2ibs, EA_64BYTE, REG_XMM0, REG_XMM1); theEmitter->emitIns_R_R(INS_vcvttps2iubs, EA_16BYTE, REG_XMM0, REG_XMM1); @@ -10351,7 +10374,7 @@ void CodeGen::genPushCalleeSavedRegisters() #endif // DEBUG #ifdef TARGET_AMD64 - if (compiler->canUseApxEncoding() && compiler->canUseEvexEncoding() && JitConfig.EnableApxPPX()) + if (compiler->canUseApxEvexEncoding() && JitConfig.EnableApxPPX()) { genPushCalleeSavedRegistersFromMaskAPX(rsPushRegs); return; @@ -10477,7 +10500,7 @@ void CodeGen::genPopCalleeSavedRegisters(bool jmpEpilog) return; } - if (compiler->canUseApxEncoding() && compiler->canUseEvexEncoding() && JitConfig.EnableApxPPX()) + if (compiler->canUseApxEvexEncoding() && JitConfig.EnableApxPPX()) { regMaskTP rsPopRegs = regSet.rsGetModifiedIntCalleeSavedRegsMask(); const unsigned popCount = genPopCalleeSavedRegistersFromMaskAPX(rsPopRegs); diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index ca4bd2a1366010..4680ba9eda5227 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -24,6 +24,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #include "fgprofilesynthesis.h" #include "jitstd/algorithm.h" #include "minipal/time.h" +#include "minipal/utf8.h" extern ICorJitHost* g_jitHost; @@ -2550,8 +2551,9 @@ void Compiler::compInitOptions(JitFlags* jitFlags) opts.genFPorder = true; opts.genFPopt = true; - opts.instrCount = 0; - opts.lvRefCount = 0; + opts.instrCount = 0; + opts.callInstrCount = 0; + opts.lvRefCount = 0; #ifdef PROFILING_SUPPORTED opts.compJitELTHookEnabled = false; @@ -9241,7 +9243,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX * cVars, dVars : Display the local variable table (call lvaTableDump()). * cVarsFinal, dVarsFinal : Display the local variable table (call lvaTableDump(FINAL_FRAME_LAYOUT)). * cBlockPreds, dBlockPreds : Display a block's predecessors (call block->dspPreds()). - * cBlockSuccs, dBlockSuccs : Display a block's successors (call block->dspSuccs(compiler)). + * cBlockSuccs, dBlockSuccs : Display a block's successors (call block->dspSuccs()). * cReach, dReach : Display all block reachability (call BlockReachabilitySets::Dump). * cDoms, dDoms : Display all block dominators (call FlowGraphDominatorTree::Dump). * cLiveness, dLiveness : Display per-block variable liveness (call fgDispBBLiveness()). @@ -9535,7 +9537,7 @@ JITDBGAPI void __cdecl cBlockSuccs(Compiler* comp, BasicBlock* block) { static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called printf("===================================================================== *BlockSuccs %u\n", sequenceNumber++); - block->dspSuccs(comp); + block->dspSuccs(); } JITDBGAPI void __cdecl cReach(Compiler* comp) @@ -10505,20 +10507,18 @@ var_types Compiler::gtTypeForNullCheck(GenTree* tree) // // Arguments: // tree - the node to change; -// block - basic block of the node. // // Notes: // the function should not be called after lowering for platforms that do not support // emitting NULLCHECK nodes, like arm32. Use `Lowering::TransformUnusedIndirection` // that handles it and calls this function when appropriate. // -void Compiler::gtChangeOperToNullCheck(GenTree* tree, BasicBlock* block) +void Compiler::gtChangeOperToNullCheck(GenTree* tree) { assert(tree->OperIs(GT_IND, GT_BLK)); tree->ChangeOper(GT_NULLCHECK); tree->ChangeType(gtTypeForNullCheck(tree)); tree->SetIndirExceptionFlags(this); - block->SetFlags(BBF_HAS_NULLCHECK); optMethodFlags |= OMF_HAS_NULLCHECK; } @@ -10613,26 +10613,30 @@ const char* Compiler::printfAlloc(const char* format, ...) // Convert a string from UTF16 to UTF8 to be printed to output. // // Arguments: -// utf16String - The string +// utf16Src - source string in UTF16 encoding +// utf16SrcLen - length of the source string in UTF16 encoding +// utf8Dst - destination buffer for the UTF8 string +// utf8DstLen - length of the destination buffer in bytes // -// Returns: -// Converted string, or a marker string if conversion failed. +// Notes: +// "" is written to the destination buffer if the +// converted string exceeds the buffer size. // -const char* Compiler::convertUtf16ToUtf8ForPrinting(const WCHAR* utf16String) +void Compiler::convertUtf16ToUtf8ForPrinting(const char16_t* utf16Src, + size_t utf16SrcLen, + char* utf8Dst, + size_t utf8DstLen) { - const char* utf8Str = ""; - int utf8Len = WideCharToMultiByte(CP_UTF8, 0, utf16String, -1, nullptr, 0, nullptr, nullptr); - if (utf8Len == 0) + const CHAR16_T* utf16src = reinterpret_cast(utf16Src); + size_t actualUtf8Len = minipal_get_length_utf16_to_utf8(utf16src, utf16SrcLen, 0); + if (actualUtf8Len >= utf8DstLen) { - char* allocated = new (this, CMK_DebugOnly) char[utf8Len]; - - if (WideCharToMultiByte(CP_UTF8, 0, (WCHAR*)utf16String, -1, allocated, utf8Len, nullptr, nullptr) != 0) - { - utf8Str = allocated; - } + strcpy_s(utf8Dst, utf8DstLen, ""); + return; } - - return utf8Str; + size_t written = minipal_convert_utf16_to_utf8(utf16src, utf16SrcLen, utf8Dst, utf8DstLen, 0); + assert(written < utf8DstLen); + utf8Dst[written] = '\0'; } #endif // defined(DEBUG) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 9a2305d3eefb1c..90a74bd016dbe2 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -601,8 +601,7 @@ class LclVarDsc unsigned char lvIsMultiRegDest : 1; // true if this is a multireg LclVar struct that is stored from a multireg node #ifdef DEBUG - unsigned char lvHiddenBufferStructArg : 1; // True when this struct (or its field) are passed as hidden buffer - // pointer. + unsigned char lvDefinedViaAddress : 1; // True when this local may have LCL_ADDRs representing definitions #endif #ifdef FEATURE_HFA_FIELDS_PRESENT @@ -753,14 +752,14 @@ class LclVarDsc } #ifdef DEBUG - void SetHiddenBufferStructArg(char value) + void SetDefinedViaAddress(char value) { - lvHiddenBufferStructArg = value; + lvDefinedViaAddress = value; } - bool IsHiddenBufferStructArg() const + bool IsDefinedViaAddress() const { - return lvHiddenBufferStructArg; + return lvDefinedViaAddress; } #endif @@ -3000,7 +2999,7 @@ class Compiler GenTree* gtNewJmpTableNode(); - GenTree* gtNewIndOfIconHandleNode(var_types indType, size_t addr, GenTreeFlags iconFlags, bool isInvariant); + GenTree* gtNewIndOfIconHandleNode(var_types indType, size_t addr, GenTreeFlags iconFlags); GenTreeIntCon* gtNewIconHandleNode(size_t value, GenTreeFlags flags, FieldSeq* fields = nullptr); @@ -3481,13 +3480,13 @@ class Compiler GenTreeIndir* gtNewIndexIndir(GenTreeIndexAddr* indexAddr); - void gtAnnotateNewArrLen(GenTree* arrLen, BasicBlock* block); + void gtAnnotateNewArrLen(GenTree* arrLen); - GenTreeArrLen* gtNewArrLen(var_types typ, GenTree* arrayOp, int lenOffset, BasicBlock* block); + GenTreeArrLen* gtNewArrLen(var_types typ, GenTree* arrayOp, int lenOffset); - GenTreeMDArr* gtNewMDArrLen(GenTree* arrayOp, unsigned dim, unsigned rank, BasicBlock* block); + GenTreeMDArr* gtNewMDArrLen(GenTree* arrayOp, unsigned dim, unsigned rank); - GenTreeMDArr* gtNewMDArrLowerBound(GenTree* arrayOp, unsigned dim, unsigned rank, BasicBlock* block); + GenTreeMDArr* gtNewMDArrLowerBound(GenTree* arrayOp, unsigned dim, unsigned rank); void gtInitializeStoreNode(GenTree* store, GenTree* value); @@ -3530,10 +3529,10 @@ class Compiler return gtNewStoreValueNode(type, nullptr, addr, value, indirFlags); } - GenTree* gtNewNullCheck(GenTree* addr, BasicBlock* basicBlock); + GenTree* gtNewNullCheck(GenTree* addr); var_types gtTypeForNullCheck(GenTree* tree); - void gtChangeOperToNullCheck(GenTree* tree, BasicBlock* block); + void gtChangeOperToNullCheck(GenTree* tree); GenTree* gtNewAtomicNode( genTreeOps oper, var_types type, GenTree* addr, GenTree* value, GenTree* comparand = nullptr); @@ -3603,11 +3602,11 @@ class Compiler void gtUpdateNodeOperSideEffects(GenTree* tree); - // Returns "true" iff the complexity (not formally defined, but first interpretation - // is #of nodes in subtree) of "tree" is greater than "limit". + // Returns "true" iff the complexity (defined by 'getComplexity') of "tree" is greater than "limit". // (This is somewhat redundant with the "GetCostEx()/GetCostSz()" fields, but can be used - // before they have been set.) - bool gtComplexityExceeds(GenTree* tree, unsigned limit, unsigned* complexity = nullptr); + // before they have been set, if 'getComplexity' is independent of them.) + template + bool gtComplexityExceeds(GenTree* tree, unsigned limit, TFunc getComplexity); GenTree* gtReverseCond(GenTree* tree); @@ -3741,6 +3740,7 @@ class Compiler bool gtIsTypeof(GenTree* tree, CORINFO_CLASS_HANDLE* handle = nullptr); GenTreeLclVarCommon* gtCallGetDefinedRetBufLclAddr(GenTreeCall* call); + GenTreeLclVarCommon* gtCallGetDefinedAsyncSuspendedIndicatorLclAddr(GenTreeCall* call); //------------------------------------------------------------------------- // Functions to display the trees @@ -4430,6 +4430,7 @@ class Compiler #endif // This call is a task await PREFIX_IS_TASK_AWAIT = 0x00000080, + PREFIX_TASK_AWAIT_CONTINUE_ON_CAPTURED_CONTEXT = 0x00000100, }; static void impValidateMemoryAccessOpcode(const BYTE* codeAddr, const BYTE* codeEndp, bool volatilePrefix); @@ -4487,9 +4488,16 @@ class Compiler // Enumerator de-abstraction support // + struct InferredGdvEntry + { + CORINFO_CLASS_HANDLE m_classHandle; + unsigned m_likelihood; + }; + typedef JitHashTable, unsigned> NodeToUnsignedMap; + typedef JitHashTable, InferredGdvEntry> VarToLikelyClassMap; - // Map is only set on the root instance. + // Maps are only set on the root instance. // NodeToUnsignedMap* impEnumeratorGdvLocalMap = nullptr; bool hasImpEnumeratorGdvLocalMap() { return impInlineRoot()->impEnumeratorGdvLocalMap != nullptr; } @@ -4505,6 +4513,20 @@ class Compiler return compiler->impEnumeratorGdvLocalMap; } + VarToLikelyClassMap* impEnumeratorLikelyTypeMap = nullptr; + bool hasEnumeratorLikelyTypeMap() { return impInlineRoot()->impEnumeratorLikelyTypeMap != nullptr; } + VarToLikelyClassMap* getImpEnumeratorLikelyTypeMap() + { + Compiler* compiler = impInlineRoot(); + if (compiler->impEnumeratorLikelyTypeMap == nullptr) + { + CompAllocator alloc(compiler->getAllocator(CMK_Generic)); + compiler->impEnumeratorLikelyTypeMap = new (alloc) VarToLikelyClassMap(alloc); + } + + return compiler->impEnumeratorLikelyTypeMap; + } + bool hasUpdatedTypeLocals = false; #define SMALL_STACK_SIZE 16 // number of elements in impSmallStack @@ -4516,7 +4538,7 @@ class Compiler }; bool impIsPrimitive(CorInfoType type); - bool impILConsumesAddr(const BYTE* codeAddr); + bool impILConsumesAddr(const BYTE* codeAddr, const BYTE* codeEndp); void impResolveToken(const BYTE* addr, CORINFO_RESOLVED_TOKEN* pResolvedToken, CorInfoTokenKind kind); @@ -4577,6 +4599,10 @@ class Compiler CORINFO_CALL_INFO* callInfo, IL_OFFSET rawILOffset); + void impSetupAndSpillForAsyncCall(GenTreeCall* call, OPCODE opcode, unsigned prefixFlags); + + void impInsertAsyncContinuationForLdvirtftnCall(GenTreeCall* call); + CORINFO_CLASS_HANDLE impGetSpecialIntrinsicExactReturnType(GenTreeCall* call); GenTree* impFixupCallStructReturn(GenTreeCall* call, CORINFO_CLASS_HANDLE retClsHnd); @@ -4740,11 +4766,6 @@ class Compiler void getHWIntrinsicImmTypes(NamedIntrinsic intrinsic, CORINFO_SIG_INFO* sig, unsigned immNumber, - var_types simdBaseType, - CorInfoType simdBaseJitType, - CORINFO_CLASS_HANDLE op1ClsHnd, - CORINFO_CLASS_HANDLE op2ClsHnd, - CORINFO_CLASS_HANDLE op3ClsHnd, unsigned* immSimdSize, var_types* immSimdBaseType); @@ -6027,45 +6048,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); @@ -6152,8 +6134,6 @@ class Compiler bool fgExpandRarelyRunBlocks(); - bool fgEhAllowsMoveBlock(BasicBlock* bBefore, BasicBlock* bAfter); - void fgMoveBlocksAfter(BasicBlock* bStart, BasicBlock* bEnd, BasicBlock* insertAfterBlk); PhaseStatus fgHeadTailMerge(bool early); @@ -6240,8 +6220,6 @@ class Compiler bool fgDedupReturnComparison(BasicBlock* block); - bool fgIsForwardBranch(BasicBlock* bJump, BasicBlock* bDest, BasicBlock* bSrc = nullptr); - bool fgUpdateFlowGraph(bool doTailDup = false, bool isPhase = false); PhaseStatus fgUpdateFlowGraphPhase(); @@ -6994,13 +6972,13 @@ class Compiler // Hoist all expressions in "blocks" that are invariant in "loop" // outside of that loop. - void optHoistLoopBlocks(FlowGraphNaturalLoop* loop, ArrayStack* blocks, LoopHoistContext* hoistContext); + void optHoistLoopBlocks(FlowGraphNaturalLoop* loop, BitVecTraits* traits, BitVec blocks, LoopHoistContext* hoistContext); // Return true if the tree looks profitable to hoist out of "loop" - bool optIsProfitableToHoistTree(GenTree* tree, FlowGraphNaturalLoop* loop, LoopHoistContext* hoistCtxt); + bool optIsProfitableToHoistTree(GenTree* tree, FlowGraphNaturalLoop* loop, LoopHoistContext* hoistCtxt, bool defExecuted); // Performs the hoisting "tree" into the PreHeader for "loop" - void optHoistCandidate(GenTree* tree, BasicBlock* treeBb, FlowGraphNaturalLoop* loop, LoopHoistContext* hoistCtxt); + void optHoistCandidate(GenTree* tree, BasicBlock* treeBb, FlowGraphNaturalLoop* loop, LoopHoistContext* hoistCtxt, bool defExecuted); // Note the new SSA uses in tree void optRecordSsaUses(GenTree* tree, BasicBlock* block); @@ -7030,8 +7008,8 @@ class Compiler public: PhaseStatus optOptimizeBools(); PhaseStatus optRecognizeAndOptimizeSwitchJumps(); - bool optSwitchConvert(BasicBlock* firstBlock, int testsCount, ssize_t* testValues, weight_t falseLikelihood, GenTree* nodeToTest); - bool optSwitchDetectAndConvert(BasicBlock* firstBlock, bool testingForConversion = false); + bool optSwitchConvert(BasicBlock* firstBlock, int testsCount, ssize_t* testValues, weight_t falseLikelihood, GenTree* nodeToTest, bool testingForConversion = false, BitVec* ccmpVec = nullptr); + bool optSwitchDetectAndConvert(BasicBlock* firstBlock, bool testingForConversion = false, BitVec* ccmpVec = nullptr); PhaseStatus optInvertLoops(); // Invert loops so they're entered at top and tested at bottom. PhaseStatus optOptimizeFlow(); // Simplify flow graph and do tail duplication @@ -7052,7 +7030,8 @@ class Compiler bool optCanonicalizeExits(FlowGraphNaturalLoop* loop); bool optCanonicalizeExit(FlowGraphNaturalLoop* loop, BasicBlock* exit); - bool optLoopComplexityExceeds(FlowGraphNaturalLoop* loop, unsigned limit); + template + bool optLoopComplexityExceeds(FlowGraphNaturalLoop* loop, unsigned limit, TFunc getTreeComplexity); PhaseStatus optCloneLoops(); PhaseStatus optRangeCheckCloning(); @@ -7361,7 +7340,7 @@ class Compiler LclNumToLiveDefsMap* curSsaName); void optBlockCopyPropPopStacks(BasicBlock* block, LclNumToLiveDefsMap* curSsaName); bool optBlockCopyProp(BasicBlock* block, LclNumToLiveDefsMap* curSsaName); - void optCopyPropPushDef(GenTree* defNode, GenTreeLclVarCommon* lclNode, LclNumToLiveDefsMap* curSsaName); + void optCopyPropPushDef(GenTreeLclVarCommon* lclNode, LclNumToLiveDefsMap* curSsaName); int optCopyProp_LclVarScore(const LclVarDsc* lclVarDsc, const LclVarDsc* copyVarDsc, bool preferOp2); PhaseStatus optVnCopyProp(); INDEBUG(void optDumpCopyPropStack(LclNumToLiveDefsMap* curSsaName)); @@ -7645,14 +7624,6 @@ class Compiler GenTree** nullCheckParent, Statement** nullCheckStmt); bool optCanMoveNullCheckPastTree(GenTree* tree, bool isInsideTry, bool checkSideEffectSummary); -#if DEBUG - void optCheckFlagsAreSet(unsigned methodFlag, - const char* methodFlagStr, - unsigned bbFlag, - const char* bbFlagStr, - GenTree* tree, - BasicBlock* basicBlock); -#endif PhaseStatus optInductionVariables(); @@ -8332,6 +8303,8 @@ class Compiler const char* eeGetClassAssemblyName(CORINFO_CLASS_HANDLE clsHnd); #if defined(DEBUG) + void eePrintStringLiteral(CORINFO_MODULE_HANDLE module, unsigned token); + unsigned eeTryGetClassSize(CORINFO_CLASS_HANDLE clsHnd); #endif @@ -9726,6 +9699,17 @@ class Compiler return compOpportunisticallyDependsOn(InstructionSet_APX); } + //------------------------------------------------------------------------ + // canUseApxEvexEncoding - Answer the question: Are APX-EVEX encodings supported on this target. + // + // Returns: + // `true` if APX-EVEX encoding is supported, `false` if not. + // + bool canUseApxEvexEncoding() const + { + return canUseApxEncoding() && canUseEvexEncoding(); + } + private: //------------------------------------------------------------------------ // DoJitStressEvexEncoding- Answer the question: Do we force EVEX encoding. @@ -9913,8 +9897,9 @@ class Compiler compSupportsISA = isas; } - unsigned compFlags; // method attributes - unsigned instrCount = 0; + unsigned compFlags; // method attributes + unsigned instrCount = 0; // number of IL opcodes + unsigned callInstrCount = 0; // number of IL opcodes (calls only). unsigned lvRefCount; codeOptimize compCodeOpt; // what type of code optimizations @@ -10373,7 +10358,7 @@ class Compiler const char* printfAlloc(const char* format, ...); - const char* convertUtf16ToUtf8ForPrinting(const WCHAR* utf16String); + void convertUtf16ToUtf8ForPrinting(const char16_t* utf16Src, size_t utf16SrcLen, char* utf8Dst, size_t utf8DstLen); #endif // DEBUG @@ -11272,7 +11257,7 @@ class Compiler #define DEFAULT_MAX_INLINE_DEPTH 20 // Methods at more than this level deep will not be inlined -#define DEFAULT_INLINE_BUDGET 20 // Maximum estimated compile time increase via inlining +#define DEFAULT_INLINE_BUDGET 22 // Maximum estimated compile time increase via inlining #define DEFAULT_MAX_FORCE_INLINE_DEPTH 1 // Methods at more than this level deep will not be force inlined diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 0f9b1de014ad49..49472de89254f4 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/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; @@ -1752,9 +1750,8 @@ inline GenTreeIndir* Compiler::gtNewIndexIndir(GenTreeIndexAddr* indexAddr) // // Arguments: // arrLen - The new GT_ARR_LENGTH or GT_MDARR_LENGTH node -// block - Basic block that will contain the new length node // -inline void Compiler::gtAnnotateNewArrLen(GenTree* arrLen, BasicBlock* block) +inline void Compiler::gtAnnotateNewArrLen(GenTree* arrLen) { assert(arrLen->OperIs(GT_ARR_LENGTH, GT_MDARR_LENGTH)); static_assert_no_msg(GTF_ARRLEN_NONFAULTING == GTF_IND_NONFAULTING); @@ -1769,19 +1766,14 @@ inline void Compiler::gtAnnotateNewArrLen(GenTree* arrLen, BasicBlock* block) // typ - Type of the node // arrayOp - Array node // lenOffset - Offset of the length field -// block - Basic block that will contain the result // // Return Value: // New GT_ARR_LENGTH node // -inline GenTreeArrLen* Compiler::gtNewArrLen(var_types typ, GenTree* arrayOp, int lenOffset, BasicBlock* block) +inline GenTreeArrLen* Compiler::gtNewArrLen(var_types typ, GenTree* arrayOp, int lenOffset) { GenTreeArrLen* arrLen = new (this, GT_ARR_LENGTH) GenTreeArrLen(typ, arrayOp, lenOffset); - gtAnnotateNewArrLen(arrLen, block); - if (block != nullptr) - { - block->SetFlags(BBF_HAS_IDX_LEN); - } + gtAnnotateNewArrLen(arrLen); optMethodFlags |= OMF_HAS_ARRAYREF; return arrLen; } @@ -1793,19 +1785,14 @@ inline GenTreeArrLen* Compiler::gtNewArrLen(var_types typ, GenTree* arrayOp, int // arrayOp - Array node // dim - MD array dimension of interest // rank - MD array rank -// block - Basic block that will contain the result // // Return Value: // New GT_MDARR_LENGTH node // -inline GenTreeMDArr* Compiler::gtNewMDArrLen(GenTree* arrayOp, unsigned dim, unsigned rank, BasicBlock* block) +inline GenTreeMDArr* Compiler::gtNewMDArrLen(GenTree* arrayOp, unsigned dim, unsigned rank) { GenTreeMDArr* arrLen = new (this, GT_MDARR_LENGTH) GenTreeMDArr(GT_MDARR_LENGTH, arrayOp, dim, rank); - gtAnnotateNewArrLen(arrLen, block); - if (block != nullptr) - { - block->SetFlags(BBF_HAS_MD_IDX_LEN); - } + gtAnnotateNewArrLen(arrLen); assert((optMethodFlags & OMF_HAS_MDARRAYREF) != 0); // Should have been set in the importer. return arrLen; } @@ -1817,21 +1804,16 @@ inline GenTreeMDArr* Compiler::gtNewMDArrLen(GenTree* arrayOp, unsigned dim, uns // arrayOp - Array node // dim - MD array dimension of interest // rank - MD array rank -// block - Basic block that will contain the result // // Return Value: // New GT_MDARR_LOWER_BOUND node // -inline GenTreeMDArr* Compiler::gtNewMDArrLowerBound(GenTree* arrayOp, unsigned dim, unsigned rank, BasicBlock* block) +inline GenTreeMDArr* Compiler::gtNewMDArrLowerBound(GenTree* arrayOp, unsigned dim, unsigned rank) { GenTreeMDArr* arrOp = new (this, GT_MDARR_LOWER_BOUND) GenTreeMDArr(GT_MDARR_LOWER_BOUND, arrayOp, dim, rank); static_assert_no_msg(GTF_MDARRLOWERBOUND_NONFAULTING == GTF_IND_NONFAULTING); arrOp->SetIndirExceptionFlags(this); - if (block != nullptr) - { - block->SetFlags(BBF_HAS_MD_IDX_LEN); - } assert((optMethodFlags & OMF_HAS_MDARRAYREF) != 0); // Should have been set in the importer. return arrOp; } @@ -1841,17 +1823,15 @@ inline GenTreeMDArr* Compiler::gtNewMDArrLowerBound(GenTree* arrayOp, unsigned d // // Arguments: // addr - Address to null check -// basicBlock - Basic block of the node // // Return Value: // New GT_NULLCHECK node -inline GenTree* Compiler::gtNewNullCheck(GenTree* addr, BasicBlock* basicBlock) +inline GenTree* Compiler::gtNewNullCheck(GenTree* addr) { assert(fgAddrCouldBeNull(addr)); GenTree* nullCheck = gtNewOperNode(GT_NULLCHECK, TYP_BYTE, addr); nullCheck->gtFlags |= GTF_EXCEPT; - basicBlock->SetFlags(BBF_HAS_NULLCHECK); optMethodFlags |= OMF_HAS_NULLCHECK; return nullCheck; } @@ -1955,8 +1935,9 @@ inline GenTreeCast* Compiler::gtNewCastNodeL(var_types typ, GenTree* op1, bool f inline GenTreeIndir* Compiler::gtNewMethodTableLookup(GenTree* object, bool onStack) { + static_assert_no_msg(VPTR_OFFS == 0); assert(onStack || object->TypeIs(TYP_REF)); - GenTreeIndir* result = gtNewIndir(TYP_I_IMPL, object, GTF_IND_INVARIANT); + GenTreeIndir* result = gtNewIndir(TYP_I_IMPL, object, GTF_IND_INVARIANT | GTF_IND_NONNULL); return result; } @@ -4703,6 +4684,129 @@ GenTree::VisitResult GenTree::VisitOperands(TVisitor visitor) } } +//------------------------------------------------------------------------ +// VisitLocalDefs: Visit locals being defined by this node. +// +// Arguments: +// comp - the compiler instance +// visitor - Functor of type GenTree::VisitResult(LocalDef) +// +// Return Value: +// VisitResult::Abort if the functor aborted; otherwise VisitResult::Continue. +// +// Notes: +// This function is contractually bound to recognize a superset of stores +// that "LocalAddressVisitor" recognizes and transforms, as it is used to +// detect which trees can define tracked locals. +// +template +GenTree::VisitResult GenTree::VisitLocalDefs(Compiler* comp, TVisitor visitor) +{ + if (OperIs(GT_STORE_LCL_VAR)) + { + unsigned size = comp->lvaLclExactSize(AsLclVarCommon()->GetLclNum()); + return visitor(LocalDef(AsLclVarCommon(), /* isEntire */ true, 0, size)); + } + if (OperIs(GT_STORE_LCL_FLD)) + { + GenTreeLclFld* fld = AsLclFld(); + return visitor(LocalDef(fld, !fld->IsPartialLclFld(comp), fld->GetLclOffs(), fld->GetSize())); + } + if (OperIs(GT_CALL)) + { + GenTreeCall* call = AsCall(); + if (call->IsAsync()) + { + GenTreeLclVarCommon* suspendedArg = comp->gtCallGetDefinedAsyncSuspendedIndicatorLclAddr(call); + if (suspendedArg != nullptr) + { + bool isEntire = comp->lvaLclExactSize(suspendedArg->GetLclNum()) == 1; + if (visitor(LocalDef(suspendedArg, isEntire, suspendedArg->GetLclOffs(), 1)) == VisitResult::Abort) + { + return VisitResult::Abort; + } + } + } + + GenTreeLclVarCommon* lclAddr = comp->gtCallGetDefinedRetBufLclAddr(call); + if (lclAddr != nullptr) + { + unsigned storeSize = comp->typGetObjLayout(AsCall()->gtRetClsHnd)->GetSize(); + + bool isEntire = storeSize == comp->lvaLclExactSize(lclAddr->GetLclNum()); + + return visitor(LocalDef(lclAddr, isEntire, lclAddr->GetLclOffs(), storeSize)); + } + } + + return VisitResult::Continue; +} + +//------------------------------------------------------------------------ +// VisitLocalDefNodes: Visit GenTreeLclVarCommon nodes representing definitions in the specified node. +// +// Arguments: +// comp - the compiler instance +// visitor - Functor of type GenTree::VisitResult(GenTreeLclVarCommon*) +// +// Return Value: +// VisitResult::Abort if the functor aborted; otherwise VisitResult::Continue. +// +// Notes: +// This function is contractually bound to recognize a superset of stores +// that "LocalAddressVisitor" recognizes and transforms, as it is used to +// detect which trees can define tracked locals. +// +template +GenTree::VisitResult GenTree::VisitLocalDefNodes(Compiler* comp, TVisitor visitor) +{ + if (OperIs(GT_STORE_LCL_VAR)) + { + return visitor(AsLclVarCommon()); + } + if (OperIs(GT_STORE_LCL_FLD)) + { + return visitor(AsLclFld()); + } + if (OperIs(GT_CALL)) + { + GenTreeCall* call = AsCall(); + if (call->IsAsync()) + { + GenTreeLclVarCommon* suspendedArg = comp->gtCallGetDefinedAsyncSuspendedIndicatorLclAddr(call); + if ((suspendedArg != nullptr) && (visitor(suspendedArg) == VisitResult::Abort)) + { + return VisitResult::Abort; + } + } + + GenTreeLclVarCommon* lclAddr = comp->gtCallGetDefinedRetBufLclAddr(call); + if (lclAddr != nullptr) + { + return visitor(lclAddr); + } + } + + return VisitResult::Continue; +} + +//------------------------------------------------------------------------ +// HasAnyLocalDefs: +// Check if a tree is considered as defining any locals. +// +// Arguments: +// comp - the compiler instance +// +// Return Value: +// True if it is. +// +inline bool GenTree::HasAnyLocalDefs(Compiler* comp) +{ + return VisitLocalDefNodes(comp, [](GenTreeLclVarCommon* lcl) { + return GenTree::VisitResult::Abort; + }) == GenTree::VisitResult::Abort; +} + /***************************************************************************** * operator new * @@ -5308,6 +5412,171 @@ BasicBlockVisit FlowGraphNaturalLoop::VisitRegularExitBlocks(TFunc func) return BasicBlockVisit::Continue; } +//----------------------------------------------------------- +// gtComplexityExceeds: Check if a tree exceeds a specified complexity limit. +// +// Type parameters: +// TFunc - Callback functor type + +// Arguments: +// tree - The tree to check +// limit - complexity limit +// getTreeComplexity - Callback functor that takes a GenTree* and returns its complexity +// +// Return Value: +// True if 'tree' exceeds the complexity limit, otherwise false. +// +template +bool Compiler::gtComplexityExceeds(GenTree* tree, unsigned limit, TFunc getComplexity) +{ + struct ComplexityVisitor : GenTreeVisitor + { + enum + { + DoPreOrder = true, + }; + + ComplexityVisitor(Compiler* comp, unsigned limit, TFunc getComplexity) + : GenTreeVisitor(comp) + , m_complexity(0) + , m_limit(limit) + , m_getComplexity(getComplexity) + { + } + + fgWalkResult PreOrderVisit(GenTree** use, GenTree* user) + { + m_complexity += m_getComplexity(*use); + return (m_complexity > m_limit) ? WALK_ABORT : WALK_CONTINUE; + } + + private: + unsigned m_complexity; + const unsigned m_limit; + TFunc m_getComplexity; + }; + + assert(tree != nullptr); + + ComplexityVisitor visitor(this, limit, getComplexity); + + fgWalkResult result = visitor.WalkTree(&tree, nullptr); + + return (result == WALK_ABORT); +} + +//------------------------------------------------------------------------ +// ComplexityExceeds: Check if the trees in a block exceed a specified complexity limit. +// +// Type parameters: +// TFunc - Callback functor type +// +// Arguments: +// comp - compiler instance +// limit - complexity limit +// getTreeComplexity - Callback functor that takes a GenTree* and returns its complexity +// +// Returns: +// True if the trees in the block exceed the complexity limit, otherwise false. +// +template +bool BasicBlock::ComplexityExceeds(Compiler* comp, unsigned limit, TFunc getTreeComplexity) +{ + assert(comp != nullptr); + + unsigned localCount = 0; + auto getComplexity = [&](GenTree* tree) -> unsigned { + const unsigned treeComplexity = getTreeComplexity(tree); + localCount += treeComplexity; + return treeComplexity; + }; + + for (Statement* const stmt : Statements()) + { + const unsigned slack = limit - localCount; + if (comp->gtComplexityExceeds(stmt->GetRootNode(), slack, getComplexity)) + { + return true; + } + } + + return false; +} + +//------------------------------------------------------------------------ +// ComplexityExceeds: Check if the trees in a range of blocks exceed a specified complexity limit. +// +// Type parameters: +// TFunc - Callback functor type +// +// Arguments: +// comp - compiler instance +// limit - complexity limit +// getTreeComplexity - Callback functor that takes a GenTree* and returns its complexity +// +// Returns: +// True if the trees in the block range exceed the complexity limit, otherwise false. +// +template +bool BasicBlockRangeList::ComplexityExceeds(Compiler* comp, unsigned limit, TFunc getTreeComplexity) +{ + assert(comp != nullptr); + + unsigned localCount = 0; + auto getComplexity = [&](GenTree* tree) -> unsigned { + const unsigned treeComplexity = getTreeComplexity(tree); + localCount += treeComplexity; + return treeComplexity; + }; + + for (BasicBlock* const block : *this) + { + const unsigned slack = limit - localCount; + if (block->ComplexityExceeds(comp, slack, getComplexity)) + { + return true; + } + } + + return false; +} + +//------------------------------------------------------------------------ +// optLoopComplexityExceeds: Check if the trees in a loop exceed a specified complexity limit. +// +// Type parameters: +// TFunc - Callback functor type +// +// Arguments: +// comp - compiler instance +// limit - complexity limit +// getTreeComplexity - Callback functor that takes a GenTree* and returns its complexity +// +// Returns: +// True if the trees in 'loop' exceed the complexity limit, otherwise false. +// +template +bool Compiler::optLoopComplexityExceeds(FlowGraphNaturalLoop* loop, unsigned limit, TFunc getTreeComplexity) +{ + assert(loop != nullptr); + + unsigned loopComplexity = 0; + auto getComplexity = [&](GenTree* tree) -> unsigned { + const unsigned treeComplexity = getTreeComplexity(tree); + loopComplexity += treeComplexity; + return treeComplexity; + }; + + BasicBlockVisit const result = loop->VisitLoopBlocks([&](BasicBlock* block) { + assert(limit >= loopComplexity); + const unsigned slack = limit - loopComplexity; + return block->ComplexityExceeds(this, slack, getComplexity) ? BasicBlockVisit::Abort + : BasicBlockVisit::Continue; + }); + + return (result == BasicBlockVisit::Abort); +} + /*****************************************************************************/ #endif //_COMPILER_HPP_ /*****************************************************************************/ diff --git a/src/coreclr/jit/copyprop.cpp b/src/coreclr/jit/copyprop.cpp index 93ff8bd2676127..22ebf6a8791346 100644 --- a/src/coreclr/jit/copyprop.cpp +++ b/src/coreclr/jit/copyprop.cpp @@ -46,24 +46,31 @@ void Compiler::optBlockCopyPropPopStacks(BasicBlock* block, LclNumToLiveDefsMap* { for (GenTree* const tree : stmt->TreeList()) { - GenTreeLclVarCommon* lclDefNode = nullptr; - if (tree->OperIsSsaDef() && tree->DefinesLocal(this, &lclDefNode)) + if (!tree->OperIsSsaDef()) { - if (lclDefNode->HasCompositeSsaName()) + continue; + } + + auto visitDef = [=](GenTreeLclVarCommon* lcl) { + if (lcl->HasCompositeSsaName()) { - LclVarDsc* varDsc = lvaGetDesc(lclDefNode); + LclVarDsc* varDsc = lvaGetDesc(lcl); assert(varDsc->lvPromoted); for (unsigned index = 0; index < varDsc->lvFieldCnt; index++) { - popDef(varDsc->lvFieldLclStart + index, lclDefNode->GetSsaNum(this, index)); + popDef(varDsc->lvFieldLclStart + index, lcl->GetSsaNum(this, index)); } } else { - popDef(lclDefNode->GetLclNum(), lclDefNode->GetSsaNum()); + popDef(lcl->GetLclNum(), lcl->GetSsaNum()); } - } + + return GenTree::VisitResult::Continue; + }; + + tree->VisitLocalDefNodes(this, visitDef); } } } @@ -304,11 +311,10 @@ bool Compiler::optCopyProp( // optCopyPropPushDef: Push the new live SSA def on the stack for "lclNode". // // Arguments: -// defNode - The definition node for this def (store/GT_CALL) (will be "nullptr" for "use" defs) // lclNode - The local tree representing "the def" // curSsaName - The map of local numbers to stacks of their defs // -void Compiler::optCopyPropPushDef(GenTree* defNode, GenTreeLclVarCommon* lclNode, LclNumToLiveDefsMap* curSsaName) +void Compiler::optCopyPropPushDef(GenTreeLclVarCommon* lclNode, LclNumToLiveDefsMap* curSsaName) { unsigned lclNum = lclNode->GetLclNum(); @@ -400,10 +406,14 @@ bool Compiler::optBlockCopyProp(BasicBlock* block, LclNumToLiveDefsMap* curSsaNa { treeLifeUpdater.UpdateLife(tree); - GenTreeLclVarCommon* lclDefNode = nullptr; - if (tree->OperIsSsaDef() && tree->DefinesLocal(this, &lclDefNode)) + if (tree->OperIsSsaDef()) { - optCopyPropPushDef(tree, lclDefNode, curSsaName); + auto visitDef = [=](GenTreeLclVarCommon* lcl) { + optCopyPropPushDef(lcl, curSsaName); + return GenTree::VisitResult::Continue; + }; + + tree->VisitLocalDefNodes(this, visitDef); } else if (tree->OperIs(GT_LCL_VAR, GT_LCL_FLD) && tree->AsLclVarCommon()->HasSsaName()) { @@ -413,7 +423,7 @@ bool Compiler::optBlockCopyProp(BasicBlock* block, LclNumToLiveDefsMap* curSsaNa // live definition. Since they are always live, we'll do it only once. if ((lvaGetDesc(lclNum)->lvIsParam || (lclNum == info.compThisArg)) && !curSsaName->Lookup(lclNum)) { - optCopyPropPushDef(nullptr, tree->AsLclVarCommon(), curSsaName); + optCopyPropPushDef(tree->AsLclVarCommon(), curSsaName); } // TODO-Review: EH successor/predecessor iteration seems broken. diff --git a/src/coreclr/jit/decomposelongs.cpp b/src/coreclr/jit/decomposelongs.cpp index a223d49a45426a..c67c62e6d38f03 100644 --- a/src/coreclr/jit/decomposelongs.cpp +++ b/src/coreclr/jit/decomposelongs.cpp @@ -178,7 +178,7 @@ GenTree* DecomposeLongs::DecomposeNode(GenTree* tree) return tree->gtNext; } } - else if (user->OperIs(GT_STOREIND) && tree->OperIsHWIntrinsic() && m_compiler->opts.OptimizationEnabled()) + else if (user->OperIs(GT_STOREIND) && tree->OperIsHWIntrinsic() && m_compiler->opts.Tier0OptimizationEnabled()) { NamedIntrinsic intrinsicId = tree->AsHWIntrinsic()->GetHWIntrinsicId(); if (HWIntrinsicInfo::IsVectorToScalar(intrinsicId) && m_lowering->IsSafeToContainMem(user, tree)) diff --git a/src/coreclr/jit/earlyprop.cpp b/src/coreclr/jit/earlyprop.cpp index c35feaabd3342f..b606e66399d894 100644 --- a/src/coreclr/jit/earlyprop.cpp +++ b/src/coreclr/jit/earlyprop.cpp @@ -18,55 +18,11 @@ bool Compiler::optDoEarlyPropForFunc() { // TODO-MDArray: bool propMDArrayLen = (optMethodFlags & OMF_HAS_MDNEWARRAY) && (optMethodFlags & // OMF_HAS_MDARRAYREF); - bool propArrayLen = (optMethodFlags & OMF_HAS_NEWARRAY) && (optMethodFlags & OMF_HAS_ARRAYREF); + bool propArrayLen = (optMethodFlags & OMF_HAS_ARRAYREF) != 0; bool propNullCheck = (optMethodFlags & OMF_HAS_NULLCHECK) != 0; return propArrayLen || propNullCheck; } -bool Compiler::optDoEarlyPropForBlock(BasicBlock* block) -{ - // TODO-MDArray: bool bbHasMDArrayRef = block->HasFlag(BBF_HAS_MID_IDX_LEN); - bool bbHasArrayRef = block->HasFlag(BBF_HAS_IDX_LEN); - bool bbHasNullCheck = block->HasFlag(BBF_HAS_NULLCHECK); - return bbHasArrayRef || bbHasNullCheck; -} - -#ifdef DEBUG -//----------------------------------------------------------------------------- -// optCheckFlagsAreSet: Check that the method flag and the basic block flag are set. -// -// Arguments: -// methodFlag - The method flag to check. -// methodFlagStr - String representation of the method flag. -// bbFlag - The basic block flag to check. -// bbFlagStr - String representation of the basic block flag. -// tree - Tree that makes the flags required. -// basicBlock - The basic block to check the flag on. - -void Compiler::optCheckFlagsAreSet(unsigned methodFlag, - const char* methodFlagStr, - unsigned bbFlag, - const char* bbFlagStr, - GenTree* tree, - BasicBlock* basicBlock) -{ - if ((optMethodFlags & methodFlag) == 0) - { - printf("%s is not set on optMethodFlags but is required because of the following tree\n", methodFlagStr); - gtDispTree(tree); - assert(false); - } - - if (!basicBlock->HasFlag((BasicBlockFlags)bbFlag)) - { - printf("%s is not set on " FMT_BB " but is required because of the following tree \n", bbFlagStr, - basicBlock->bbNum); - gtDispTree(tree); - assert(false); - } -} -#endif - //------------------------------------------------------------------------------------------ // optEarlyProp: The entry point of the early value propagation. // @@ -97,13 +53,6 @@ PhaseStatus Compiler::optEarlyProp() for (BasicBlock* const block : Blocks()) { -#ifndef DEBUG - if (!optDoEarlyPropForBlock(block)) - { - continue; - } -#endif - compCurBB = block; CompAllocator allocator(getAllocator(CMK_EarlyProp)); @@ -114,6 +63,12 @@ PhaseStatus Compiler::optEarlyProp() // Preserve the next link before the propagation and morph. Statement* next = stmt->GetNextStmt(); + if (stmt->GetRootNode() == nullptr || ((stmt->GetRootNode()->gtFlags & GTF_ALL_EFFECT) == 0)) + { + stmt = next; + continue; + } + compCurStmt = stmt; // Walk the stmt tree in linear order to rewrite any array length reference with a @@ -134,7 +89,6 @@ PhaseStatus Compiler::optEarlyProp() if (isRewritten) { // Make sure the transformation happens in debug, check, and release build. - assert(optDoEarlyPropForFunc() && optDoEarlyPropForBlock(block)); gtSetStmtInfo(stmt); fgSetStmtSeq(stmt); numChanges++; @@ -189,16 +143,6 @@ GenTree* Compiler::optEarlyPropRewriteTree(GenTree* tree, LocalNumberToNullCheck { return folded ? tree : nullptr; } -#ifdef DEBUG - else - { - if (propKind == optPropKind::OPK_ARRAYLEN) - { - optCheckFlagsAreSet(OMF_HAS_ARRAYREF, "OMF_HAS_ARRAYREF", BBF_HAS_IDX_LEN, "BBF_HAS_IDX_LEN", tree, - compCurBB); - } - } -#endif unsigned lclNum = objectRefPtr->AsLclVarCommon()->GetLclNum(); unsigned ssaNum = objectRefPtr->AsLclVarCommon()->GetSsaNum(); @@ -372,19 +316,6 @@ GenTree* Compiler::optPropGetValueRec(unsigned lclNum, unsigned ssaNum, optPropK bool Compiler::optFoldNullCheck(GenTree* tree, LocalNumberToNullCheckTreeMap* nullCheckMap) { -#ifdef DEBUG - if (tree->OperIs(GT_NULLCHECK)) - { - optCheckFlagsAreSet(OMF_HAS_NULLCHECK, "OMF_HAS_NULLCHECK", BBF_HAS_NULLCHECK, "BBF_HAS_NULLCHECK", tree, - compCurBB); - } -#else - if (!compCurBB->HasFlag(BBF_HAS_NULLCHECK)) - { - return false; - } -#endif - GenTree* nullCheckTree = optFindNullCheckToFold(tree, nullCheckMap); GenTree* nullCheckParent = nullptr; Statement* nullCheckStmt = nullptr; @@ -392,7 +323,6 @@ bool Compiler::optFoldNullCheck(GenTree* tree, LocalNumberToNullCheckTreeMap* nu if ((nullCheckTree != nullptr) && optIsNullCheckFoldingLegal(tree, nullCheckTree, &nullCheckParent, &nullCheckStmt)) { // Make sure the transformation happens in debug, check, and release build. - assert(optDoEarlyPropForFunc() && optDoEarlyPropForBlock(compCurBB) && compCurBB->HasFlag(BBF_HAS_NULLCHECK)); JITDUMP("optEarlyProp Marking a null check for removal\n"); DISPTREE(nullCheckTree); JITDUMP("\n"); diff --git a/src/coreclr/jit/eeinterface.cpp b/src/coreclr/jit/eeinterface.cpp index a0cd59ed218680..50ca1eab333993 100644 --- a/src/coreclr/jit/eeinterface.cpp +++ b/src/coreclr/jit/eeinterface.cpp @@ -692,3 +692,35 @@ void Compiler::eePrintObjectDescription(const char* prefix, CORINFO_OBJECT_HANDL printf("%s '%s'", prefix, str); } + +#ifdef DEBUG +//------------------------------------------------------------------------ +// eePrintStringLiteral: +// Print a string literal. If missing information (in SPMI), +// then print a placeholder string. +// +// Arguments: +// module - The literal's scope handle +// token - The literal's token +// +void Compiler::eePrintStringLiteral(CORINFO_MODULE_HANDLE module, unsigned token) +{ + const int MAX_LITERAL_LENGTH = 256; + char16_t str[MAX_LITERAL_LENGTH] = {}; + int length = -1; + eeRunFunctorWithSPMIErrorTrap([&]() { + length = info.compCompHnd->getStringLiteral(module, token, str, MAX_LITERAL_LENGTH); + }); + + if (length < 0) + { + printf(""); + } + else + { + char dst[MAX_LITERAL_LENGTH]; + convertUtf16ToUtf8ForPrinting(str, length, dst, MAX_LITERAL_LENGTH); + printf("\"%.50s%s\"", dst, length > 50 ? "..." : ""); + } +} +#endif // DEBUG diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 198830d9ddac5a..416b3e978345ef 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -4502,6 +4502,7 @@ void emitter::emitRecomputeIGoffsets() ig->igOffs = offs; assert(IsCodeAligned(ig->igOffs)); offs += ig->igSize; + assert(offs >= ig->igOffs); // must not overflow } /* Set the total code size */ diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 9efc99b9210c9e..ec7fffec071bba 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -844,10 +844,10 @@ class emitter unsigned _idCustom5 : 1; unsigned _idCustom6 : 1; -#define _idEvexbContext \ - (_idCustom6 << 1) | _idCustom5 /* Evex.b: embedded broadcast, embedded rounding, embedded SAE \ - */ +#define _idEvexbContext (_idCustom6 << 1) | _idCustom5 /* Evex.b: embedded broadcast, rounding, SAE */ #define _idEvexNdContext _idCustom5 /* bits used for the APX-EVEX.nd context for promoted legacy instructions */ +#define _idEvexZuContext _idCustom5 /* bits used for the APX-EVEX.zu context for promoted legacy instructions */ + #define _idEvexNfContext _idCustom6 /* bits used for the APX-EVEX.nf context for promoted legacy/vex instructions */ // We repurpose 4 bits for the default flag value bits for ccmp instructions. @@ -1734,10 +1734,21 @@ class emitter return idGetEvexbContext() != 0; } + void idSetEvexBroadcastBit() + { + assert(!idIsEvexbContextSet()); + _idCustom5 = 1; + } + + void idSetEvexCompressedDisplacementBit() + { + assert(_idCustom6 == 0); + _idCustom6 = 1; + } + void idSetEvexbContext(insOpts instOptions) { assert(!idIsEvexbContextSet()); - assert(idGetEvexbContext() == 0); unsigned value = static_cast(instOptions & INS_OPTS_EVEX_b_MASK); _idCustom5 = ((value >> 0) & 1); @@ -1784,15 +1795,28 @@ class emitter bool idIsEvexNdContextSet() const { + assert(IsApxNddCompatibleInstruction(_idIns)); return _idEvexNdContext != 0; } + bool idIsEvexZuContextSet() const + { + assert(IsApxZuCompatibleInstruction(_idIns)); + return (_idEvexZuContext != 0); + } + void idSetEvexNdContext() { assert(!idIsEvexNdContextSet()); _idEvexNdContext = 1; } + void idSetEvexZuContext() + { + assert(!idIsEvexZuContextSet()); + _idEvexZuContext = 1; + } + bool idIsEvexNfContextSet() const { return _idEvexNfContext != 0; @@ -2388,7 +2412,7 @@ class emitter ssize_t emitGetInsCIdisp(instrDesc* id) const; unsigned emitGetInsCIargs(instrDesc* id) const; - inline emitAttr emitGetMemOpSize(instrDesc* id, bool ignoreEmbeddedBroadcast = false) const; + inline emitAttr emitGetMemOpSize(instrDesc* id, bool ignoreEmbeddedBroadcast) const; // Return the argument count for a direct call "id". int emitGetInsCDinfo(instrDesc* id); @@ -4164,7 +4188,7 @@ emitAttr emitter::emitGetMemOpSize(instrDesc* id, bool ignoreEmbeddedBroadcast) else if (tupleType == INS_TT_FULL) { // Embedded broadcast supported, so either loading scalar or full vector - if (id->idIsEvexbContextSet() && !ignoreEmbeddedBroadcast) + if (!ignoreEmbeddedBroadcast && HasEmbeddedBroadcast(id)) { memSize = GetInputSizeInBytes(id); } @@ -4183,7 +4207,7 @@ emitAttr emitter::emitGetMemOpSize(instrDesc* id, bool ignoreEmbeddedBroadcast) { memSize = 16; } - else if (id->idIsEvexbContextSet() && !ignoreEmbeddedBroadcast) + else if (!ignoreEmbeddedBroadcast && HasEmbeddedBroadcast(id)) { memSize = GetInputSizeInBytes(id); } @@ -4195,7 +4219,7 @@ emitAttr emitter::emitGetMemOpSize(instrDesc* id, bool ignoreEmbeddedBroadcast) else if (tupleType == INS_TT_HALF) { // Embedded broadcast supported, so either loading scalar or half vector - if (id->idIsEvexbContextSet() && !ignoreEmbeddedBroadcast) + if (!ignoreEmbeddedBroadcast && HasEmbeddedBroadcast(id)) { memSize = GetInputSizeInBytes(id); } diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index b72eda2a585079..54c50a3f0cfeda 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -555,7 +555,7 @@ static code_t insEncodeReg3Scale(bool isScaled); // Returns the encoding to select the 1/2/4/8 byte elemsize for an Arm64 SVE vector instruction static code_t insEncodeSveElemsize(emitAttr size); -// Returns the encoding to select the 1/2/4/8 byte elemsize for an Arm64 Sve vector instruction +// Returns the encoding to select the 1/2/4 byte elemsize for an Arm64 Sve narrowing vector instruction static code_t insEncodeNarrowingSveElemsize(emitAttr size); // Returns the encoding to select the 1/2/4/8 byte elemsize for an Arm64 Sve vector instruction diff --git a/src/coreclr/jit/emitarm64sve.cpp b/src/coreclr/jit/emitarm64sve.cpp index 0cae23420fc080..83e367392ac9c7 100644 --- a/src/coreclr/jit/emitarm64sve.cpp +++ b/src/coreclr/jit/emitarm64sve.cpp @@ -2645,9 +2645,9 @@ void emitter::emitInsSve_R_R_I(instruction ins, assert(isVectorRegister(reg1)); // ddddd assert(isVectorRegister(reg2)); // nnnnn assert(isValidVectorElemsize(optGetSveElemsize(opt))); // xx + assert(isValidRot(emitDecodeRotationImm90_or_270(imm))); // Convert rot to bitwise representation: 0 if 90, 1 if 270 - imm = emitEncodeRotationImm90_or_270(imm); // r fmt = IF_SVE_FV_2A; break; @@ -4560,14 +4560,13 @@ void emitter::emitInsSve_R_R_R_I(instruction ins, case INS_sve_cdot: assert(insScalableOptsNone(sopt)); assert(insOptsScalableWords(opt)); - assert(isVectorRegister(reg1)); // ddddd - assert(isVectorRegister(reg2)); // nnnnn - assert(isVectorRegister(reg3)); // mmmmm - assert(isValidRot(imm)); // rr - assert(isValidVectorElemsize(optGetSveElemsize(opt))); // xx + assert(isVectorRegister(reg1)); // ddddd + assert(isVectorRegister(reg2)); // nnnnn + assert(isVectorRegister(reg3)); // mmmmm + assert(isValidRot(emitDecodeRotationImm0_to_270(imm))); // rr + assert(isValidVectorElemsize(optGetSveElemsize(opt))); // xx // Convert rot to bitwise representation - imm = emitEncodeRotationImm0_to_270(imm); fmt = IF_SVE_EJ_3A; break; @@ -4575,14 +4574,13 @@ void emitter::emitInsSve_R_R_R_I(instruction ins, case INS_sve_sqrdcmlah: assert(insScalableOptsNone(sopt)); assert(insOptsScalableStandard(opt)); - assert(isVectorRegister(reg1)); // ddddd - assert(isVectorRegister(reg2)); // nnnnn - assert(isVectorRegister(reg3)); // mmmmm - assert(isValidRot(imm)); // rr - assert(isValidVectorElemsize(optGetSveElemsize(opt))); // xx + assert(isVectorRegister(reg1)); // ddddd + assert(isVectorRegister(reg2)); // nnnnn + assert(isVectorRegister(reg3)); // mmmmm + assert(isValidRot(emitDecodeRotationImm0_to_270(imm))); // rr + assert(isValidVectorElemsize(optGetSveElemsize(opt))); // xx // Convert rot to bitwise representation - imm = emitEncodeRotationImm0_to_270(imm); fmt = IF_SVE_EK_3A; break; @@ -5436,7 +5434,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 +5442,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 +5461,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 +5469,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; } @@ -5484,7 +5482,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 @@ -5492,7 +5490,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_FH_3B; } @@ -5534,7 +5532,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 @@ -5542,7 +5540,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)); // ii fmt = IF_SVE_FJ_3B; } @@ -5764,12 +5762,12 @@ void emitter::emitInsSve_R_R_R_I_I(instruction ins, switch (ins) { case INS_sve_cdot: - assert(isVectorRegister(reg1)); // ddddd - assert(isVectorRegister(reg2)); // nnnnn - assert(isLowVectorRegister(reg3)); // mmmm - assert(isValidRot(imm2)); // rr - // Convert imm2 from rotation value (0-270) to bitwise representation (0-3) - imm = (imm1 << 2) | emitEncodeRotationImm0_to_270(imm2); + assert(isVectorRegister(reg1)); // ddddd + assert(isVectorRegister(reg2)); // nnnnn + assert(isLowVectorRegister(reg3)); // mmmm + assert(isValidRot(emitDecodeRotationImm0_to_270(imm2))); // rr + + imm = (imm1 << 2) | imm2; if (opt == INS_OPTS_SCALABLE_B) { @@ -5786,12 +5784,12 @@ void emitter::emitInsSve_R_R_R_I_I(instruction ins, break; case INS_sve_cmla: - assert(isVectorRegister(reg1)); // ddddd - assert(isVectorRegister(reg2)); // nnnnn - assert(isLowVectorRegister(reg3)); // mmmm - assert(isValidRot(imm2)); // rr + assert(isVectorRegister(reg1)); // ddddd + assert(isVectorRegister(reg2)); // nnnnn + assert(isLowVectorRegister(reg3)); // mmmm + assert(isValidRot(emitDecodeRotationImm0_to_270(imm2))); // rr // Convert imm2 from rotation value (0-270) to bitwise representation (0-3) - imm = (imm1 << 2) | emitEncodeRotationImm0_to_270(imm2); + imm = (imm1 << 2) | imm2; if (opt == INS_OPTS_SCALABLE_H) { @@ -5808,13 +5806,12 @@ void emitter::emitInsSve_R_R_R_I_I(instruction ins, break; case INS_sve_sqrdcmlah: - assert(isVectorRegister(reg1)); // ddddd - assert(isVectorRegister(reg2)); // nnnnn - assert(isLowVectorRegister(reg3)); // mmmm - assert(isValidRot(imm2)); // rr - // Convert imm2 from rotation value (0-270) to bitwise representation (0-3) - imm = (imm1 << 2) | emitEncodeRotationImm0_to_270(imm2); + assert(isVectorRegister(reg1)); // ddddd + assert(isVectorRegister(reg2)); // nnnnn + assert(isLowVectorRegister(reg3)); // mmmm + assert(isValidRot(emitDecodeRotationImm0_to_270(imm2))); // rr + imm = (imm1 << 2) | imm2; if (opt == INS_OPTS_SCALABLE_H) { assert(isValidUimm<2>(imm1)); // ii @@ -7441,7 +7438,7 @@ void emitter::emitIns_PRFOP_R_R_I(instruction ins, /***************************************************************************** * - * Returns the encoding to select the 1/2/4/8 byte elemsize for an Arm64 Sve vector instruction + * Returns the encoding to select the 1/2/4 byte elemsize for an Arm64 Sve narrowing vector instruction */ /*static*/ emitter::code_t emitter::insEncodeNarrowingSveElemsize(emitAttr size) @@ -12999,7 +12996,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/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 6f772120f480e8..c0c80413a33333 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -591,7 +591,7 @@ void emitter::emitIns_Mov( { assert(isGeneralRegisterOrR0(srcReg)); assert(isGeneralRegisterOrR0(dstReg)); - emitIns_R_R_I(INS_addiw, attr, dstReg, srcReg, 0); + emitIns_R_R(INS_sext_w, attr, dstReg, srcReg); } else if (INS_fsgnj_s == ins || INS_fsgnj_d == ins) { @@ -607,7 +607,7 @@ void emitter::emitIns_Mov( { assert(isGeneralRegisterOrR0(srcReg)); assert(isGeneralRegisterOrR0(dstReg)); - emitIns_R_R_I(INS_addi, attr, dstReg, srcReg, 0); + emitIns_R_R(INS_mov, attr, dstReg, srcReg); } } } @@ -619,7 +619,7 @@ void emitter::emitIns_Mov(emitAttr attr, regNumber dstReg, regNumber srcReg, boo assert(attr == EA_4BYTE || attr == EA_PTRSIZE); if (isGeneralRegisterOrR0(dstReg) && isGeneralRegisterOrR0(srcReg)) { - emitIns_R_R_I(attr == EA_4BYTE ? INS_addiw : INS_addi, attr, dstReg, srcReg, 0); + emitIns_R_R(attr == EA_4BYTE ? INS_sext_w : INS_mov, attr, dstReg, srcReg); } else if (isGeneralRegisterOrR0(dstReg) && genIsValidFloatReg(srcReg)) { @@ -650,7 +650,7 @@ void emitter::emitIns_R_R( { code_t code = emitInsCode(ins); - if (INS_mov == ins || INS_sext_w == ins || (INS_clz <= ins && ins <= INS_rev8)) + if (INS_mov == ins || INS_sext_w == ins || INS_not == ins || (INS_clz <= ins && ins <= INS_rev8)) { assert(isGeneralRegisterOrR0(reg1)); assert(isGeneralRegisterOrR0(reg2)); @@ -1023,31 +1023,14 @@ void emitter::emitIns_R_R_R_R( * */ void emitter::emitIns_R_C( - instruction ins, emitAttr attr, regNumber reg, regNumber addrReg, CORINFO_FIELD_HANDLE fldHnd, int offs) + instruction ins, emitAttr attr, regNumber destReg, regNumber addrReg, CORINFO_FIELD_HANDLE fldHnd) { - assert(offs >= 0); - assert(instrDesc::fitsInSmallCns(offs)); // can optimize. instrDesc* id = emitNewInstr(attr); - id->idIns(ins); - assert(reg != REG_R0); // for special. reg Must not be R0. - id->idReg1(reg); // destination register that will get the constant value. - - id->idSmallCns(offs); // usually is 0. + assert(destReg != REG_R0); // for special. reg Must not be R0. + id->idReg1(destReg); id->idInsOpt(INS_OPTS_RC); - - if (emitComp->fgIsBlockCold(emitComp->compCurBB)) - { - // Loading constant from cold section might be arbitrarily far, - // use emitOutputInstr_OptsRcNoPcRel - id->idCodeSize(24); - } - else - { - // Loading constant from hot section can use auipc, - // use emitOutputInstr_OptsRcPcRel - id->idCodeSize(8); - } + id->idCodeSize(2 * sizeof(code_t)); // auipc + load/addi if (EA_IS_GCREF(attr)) { @@ -1087,7 +1070,6 @@ void emitter::emitIns_R_AI(instruction ins, assert(EA_IS_RELOC(attr)); // EA_PTR_DSP_RELOC assert(ins == INS_jal); // for special. assert(isGeneralRegister(reg)); - // INS_OPTS_RELOC: placeholders. 2-ins: // case:EA_HANDLE_CNS_RELOC // auipc reg, off-hi-20bits @@ -1143,16 +1125,9 @@ void emitter::emitIns_R_L(instruction ins, emitAttr attr, BasicBlock* dst, regNu { assert(dst->HasFlag(BBF_HAS_LABEL)); - // if for reloc! 4-ins: + // 2-ins: // auipc reg, offset-hi20 // addi reg, reg, offset-lo12 - // - // else: 5-ins: - // lui tmp, dst-lo-20bits - // addi tmp, tmp, dst-lo-12bits - // lui reg, dst-hi-15bits - // slli reg, reg, 20 - // add reg, tmp, reg instrDesc* id = emitNewInstr(attr); @@ -1161,13 +1136,9 @@ void emitter::emitIns_R_L(instruction ins, emitAttr attr, BasicBlock* dst, regNu id->idAddr()->iiaBBlabel = dst; if (emitComp->opts.compReloc) - { id->idSetIsDspReloc(); - id->idCodeSize(8); - } - else - id->idCodeSize(20); + id->idCodeSize(2 * sizeof(code_t)); id->idReg1(reg); if (EA_IS_GCREF(attr)) @@ -1596,7 +1567,7 @@ void emitter::emitLoadImmediate(emitAttr size, regNumber reg, ssize_t imm) { assert(!emitComp->compGeneratingProlog && !emitComp->compGeneratingEpilog); auto constAddr = emitDataConst(&originalImm, sizeof(long), sizeof(long), TYP_LONG); - emitIns_R_C(INS_ld, EA_PTRSIZE, reg, REG_NA, emitComp->eeFindJitDataOffs(constAddr), 0); + emitIns_R_C(INS_ld, EA_PTRSIZE, reg, REG_NA, emitComp->eeFindJitDataOffs(constAddr)); } else { @@ -1725,28 +1696,15 @@ void emitter::emitIns_Call(const EmitCallParams& params) id->idSetIsNoGC(params.isJump || params.noSafePoint || emitNoGChelper(params.methHnd)); /* Set the instruction - special case jumping a function */ - instruction ins; - - ins = INS_jalr; // jalr - id->idIns(ins); + id->idIns(INS_jalr); id->idInsOpt(INS_OPTS_C); - // TODO-RISCV64: maybe optimize. - - // INS_OPTS_C: placeholders. 1/2/4-ins: + // INS_OPTS_C: placeholders. 1/2-ins: // if (callType == EC_INDIR_R) - // jalr REG_R0/REG_RA, ireg, offset <---- 1-ins + // jalr zero/ra, ireg, offset // else if (callType == EC_FUNC_TOKEN || callType == EC_FUNC_ADDR) - // if reloc: - // //pc + offset_38bits # only when reloc. - // auipc t2, addr-hi20 - // jalr r0/1, t2, addr-lo12 - // - // else: - // lui t2, dst_offset_lo32-hi - // ori t2, t2, dst_offset_lo32-lo - // lui t2, dst_offset_hi32-lo - // jalr REG_R0/REG_RA, t2, 0 + // auipc t2/ra, offset-hi20 + // jalr zero/ra, t2/ra, offset-lo12 /* Record the address: method, indirection, or funcptr */ if (params.callType == EC_INDIR_R) @@ -1779,16 +1737,8 @@ void emitter::emitIns_Call(const EmitCallParams& params) void* addr = (void*)(((size_t)params.addr) + (params.isJump ? 0 : 1)); // NOTE: low-bit0 is used for jalr ra/r0,rd,0 id->idAddr()->iiaAddr = (BYTE*)addr; - - if (emitComp->opts.compReloc) - { - id->idSetIsDspReloc(); - id->idCodeSize(8); - } - else - { - id->idCodeSize(32); - } + id->idCodeSize(2 * sizeof(code_t)); + id->idSetIsDspReloc(); } #ifdef DEBUG @@ -1823,11 +1773,10 @@ void emitter::emitIns_Call(const EmitCallParams& params) * Output a call instruction. */ -unsigned emitter::emitOutputCall(const insGroup* ig, BYTE* dst, instrDesc* id, code_t code) +unsigned emitter::emitOutputCall(const insGroup* ig, BYTE* dst, instrDesc* id) { - unsigned char callInstrSize = sizeof(code_t); // 4 bytes - regMaskTP gcrefRegs; - regMaskTP byrefRegs; + regMaskTP gcrefRegs; + regMaskTP byrefRegs; VARSET_TP GCvars(VarSetOps::UninitVal()); @@ -1866,130 +1815,29 @@ unsigned emitter::emitOutputCall(const insGroup* ig, BYTE* dst, instrDesc* id, c #endif // DEBUG assert(id->idIns() == INS_jalr); + BYTE* origDst = dst; if (id->idIsCallRegPtr()) { // EC_INDIR_R ssize_t offset = id->idSmallCns(); - assert(isValidSimm12(offset)); - code = emitInsCode(id->idIns()); - code |= (code_t)id->idReg4() << 7; - code |= (code_t)id->idReg3() << 15; - code |= (code_t)offset << 20; - emitOutput_Instr(dst, code); + dst += emitOutput_ITypeInstr(dst, INS_jalr, id->idReg4(), id->idReg3(), TrimSignedToImm12(offset)); } - else if (id->idIsReloc()) + else { - // pc + offset_32bits - // - // auipc t2, addr-hi20 - // jalr r0/1,t2,addr-lo12 - - emitOutput_Instr(dst, 0x00000397); - size_t addr = (size_t)(id->idAddr()->iiaAddr); // get addr. - int reg2 = (int)(addr & 1); - addr -= reg2; - - if (!emitComp->opts.compReloc) - { - assert(isValidSimm32(addr - (ssize_t)dst)); - } - + regNumber linkReg = (regNumber)(addr & 1); + assert(linkReg == REG_ZERO || linkReg == REG_RA); + addr -= linkReg; assert((addr & 1) == 0); + regNumber tempReg = (linkReg == REG_ZERO) ? REG_DEFAULT_HELPER_CALL_TARGET : REG_RA; - dst += 4; - emitGCregDeadUpd(REG_DEFAULT_HELPER_CALL_TARGET, dst); - -#ifdef DEBUG - code = emitInsCode(INS_auipc); - assert((code | (REG_DEFAULT_HELPER_CALL_TARGET << 7)) == 0x00000397); - assert((int)REG_DEFAULT_HELPER_CALL_TARGET == 7); - code = emitInsCode(INS_jalr); - assert(code == 0x00000067); -#endif - emitOutput_Instr(dst, 0x00000067 | (REG_DEFAULT_HELPER_CALL_TARGET << 15) | reg2 << 7); + dst += emitOutput_UTypeInstr(dst, INS_auipc, tempReg, 0); + emitGCregDeadUpd(tempReg, dst); + dst += emitOutput_ITypeInstr(dst, INS_jalr, linkReg, tempReg, 0); - emitRecordRelocation(dst - 4, (BYTE*)addr, IMAGE_REL_RISCV64_PC); + assert(id->idIsDspReloc()); + emitRecordRelocation(origDst, (BYTE*)addr, IMAGE_REL_RISCV64_PC); } - else - { - // lui t2, dst_offset_hi32-hi - // addi t2, t2, dst_offset_hi32-lo - // slli t2, t2, 11 - // addi t2, t2, dst_offset_low32-hi - // slli t2, t2, 11 - // addi t2, t2, dst_offset_low32-md - // slli t2, t2, 10 - // jalr t2 - - ssize_t imm = (ssize_t)(id->idAddr()->iiaAddr); - assert((uint64_t)(imm >> 32) <= 0x7fff); // RISC-V Linux Kernel SV48 - - int reg2 = (int)(imm & 1); - imm -= reg2; - - UINT32 high = imm >> 32; - code = emitInsCode(INS_lui); - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 7; - code |= ((code_t)((high + 0x800) >> 12) & 0xfffff) << 12; - emitOutput_Instr(dst, code); - dst += 4; - - emitGCregDeadUpd(REG_DEFAULT_HELPER_CALL_TARGET, dst); - - code = emitInsCode(INS_addi); - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 7; - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 15; - code |= (code_t)(high & 0xfff) << 20; - emitOutput_Instr(dst, code); - dst += 4; - - code = emitInsCode(INS_slli); - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 7; - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 15; - code |= (code_t)(11 << 20); - emitOutput_Instr(dst, code); - dst += 4; - - UINT32 low = imm & 0xffffffff; - - code = emitInsCode(INS_addi); - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 7; - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 15; - code |= ((low >> 21) & 0x7ff) << 20; - emitOutput_Instr(dst, code); - dst += 4; - - code = emitInsCode(INS_slli); - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 7; - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 15; - code |= (code_t)(11 << 20); - emitOutput_Instr(dst, code); - dst += 4; - - code = emitInsCode(INS_addi); - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 7; - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 15; - code |= ((low >> 10) & 0x7ff) << 20; - emitOutput_Instr(dst, code); - dst += 4; - - code = emitInsCode(INS_slli); - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 7; - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 15; - code |= (code_t)(10 << 20); - emitOutput_Instr(dst, code); - dst += 4; - - code = emitInsCode(INS_jalr); - code |= (code_t)reg2 << 7; - code |= (code_t)REG_DEFAULT_HELPER_CALL_TARGET << 15; - code |= (low & 0x3ff) << 20; - // the offset default is 0; - emitOutput_Instr(dst, code); - } - - dst += 4; // If the method returns a GC ref, mark INTRET (A0) appropriately. if (id->idGCref() == GCT_GCREF) @@ -2037,25 +1885,19 @@ unsigned emitter::emitOutputCall(const insGroup* ig, BYTE* dst, instrDesc* id, c // So we're not really doing a "stack pop" here (note that "args" is 0), but we use this mechanism // to record the call for GC info purposes. (It might be best to use an alternate call, // and protect "emitStackPop" under the EMIT_TRACK_STACK_DEPTH preprocessor variable.) - emitStackPop(dst, /*isCall*/ true, callInstrSize, /*args*/ 0); + emitStackPop(dst, /*isCall*/ true, sizeof(code_t), /*args*/ 0); // Do we need to record a call location for GC purposes? // if (!emitFullGCinfo) { - emitRecordGCcall(dst, callInstrSize); + emitRecordGCcall(dst, sizeof(code_t)); } } - if (id->idIsCallRegPtr()) - { - callInstrSize = 1 << 2; - } - else - { - callInstrSize = id->idIsReloc() ? (2 << 2) : (8 << 2); // INS_OPTS_C: 2/9-ins. - } - return callInstrSize; + assert(dst > origDst); + assert((dst - origDst) <= UINT_MAX); + return (unsigned)(dst - origDst); } void emitter::emitJumpDistBind() @@ -2279,159 +2121,82 @@ void emitter::emitJumpDistBind() srcEncodingOffs = srcInstrOffs + ssz; // Encoding offset of relative offset for small branch + const char* direction = nullptr; if (jmpIG->igNum < tgtIG->igNum) { /* Forward jump */ + direction = "fwd"; /* Adjust the target offset by the current delta. This is a worst-case estimate, as jumps between here and the target could be shortened, causing the actual distance to shrink. */ - dstOffs += adjIG; /* Compute the distance estimate */ - jmpDist = dstOffs - srcEncodingOffs; /* How much beyond the max. short distance does the jump go? */ - extra = jmpDist - psd; - -#if DEBUG_EMIT - printJmpInfo(jmp, jmpIG, extra, srcInstrOffs, srcEncodingOffs, dstOffs, jmpDist, "fwd"); -#endif // DEBUG_EMIT - - assert(jmpDist >= 0); // Forward jump - assert(!(jmpDist & 0x3)); - - if (!(isLinkingEnd & 0x2) && (extra > 0) && - (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) - { - // transform forward INS_OPTS_J/INS_OPTS_J_cond jump when jmpDist exceed the maximum short distance - instruction ins = jmp->idIns(); - assert((INS_jal <= ins) && (ins <= INS_bgeu)); - - if (ins > INS_jalr || (ins < INS_jalr && ins > INS_j)) // jal < beqz < bnez < jalr < - // beq/bne/blt/bltu/bge/bgeu - { - if (isValidSimm13(jmpDist + maxPlaceholderSize)) - { - continue; - } - else if (isValidSimm21(jmpDist + maxPlaceholderSize)) - { - // convert to opposite branch and jal - extra = 4; - } - else - { - // convert to opposite branch and jalr - extra = 4 * 6; - } - } - else if (ins == INS_jal || ins == INS_j) - { - if (isValidSimm21(jmpDist + maxPlaceholderSize)) - { - continue; - } - else - { - // convert to jalr - extra = 4 * 5; - } - } - else - { - assert(ins == INS_jalr); - assert((jmpDist + maxPlaceholderSize) < 0x800); - continue; - } - - jmp->idInsOpt(INS_OPTS_JALR); - jmp->idCodeSize(jmp->idCodeSize() + extra); - jmpIG->igSize += (unsigned short)extra; // the placeholder sizeof(INS_OPTS_JALR) - sizeof(INS_OPTS_J). - adjSJ += (UNATIVE_OFFSET)extra; - adjIG += (UNATIVE_OFFSET)extra; - emitTotalCodeSize += (UNATIVE_OFFSET)extra; - jmpIG->igFlags |= IGF_UPD_ISZ; - isLinkingEnd |= 0x1; - } - continue; } else { /* Backward jump */ + direction = "bwd"; /* Compute the distance estimate */ - jmpDist = srcEncodingOffs - dstOffs; /* How much beyond the max. short distance does the jump go? */ - extra = jmpDist + nsd; + } #if DEBUG_EMIT - printJmpInfo(jmp, jmpIG, extra, srcInstrOffs, srcEncodingOffs, dstOffs, jmpDist, "bwd"); + printJmpInfo(jmp, jmpIG, extra, srcInstrOffs, srcEncodingOffs, dstOffs, jmpDist, direction); #endif // DEBUG_EMIT - assert(jmpDist >= 0); // Backward jump - assert(!(jmpDist & 0x3)); + assert(jmpDist >= 0); + assert(!(jmpDist & 0x3)); - if (!(isLinkingEnd & 0x2) && (extra > 0) && - (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) - { - // transform backward INS_OPTS_J/INS_OPTS_J_cond jump when jmpDist exceed the maximum short distance - instruction ins = jmp->idIns(); - assert((INS_jal <= ins) && (ins <= INS_bgeu)); + if (!(isLinkingEnd & 0x2) && (extra > 0) && + (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) + { + // transform INS_OPTS_J/INS_OPTS_J_cond jump when jmpDist exceed the maximum short distance + instruction ins = jmp->idIns(); + assert((INS_jal <= ins) && (ins <= INS_bgeu)); - if (ins > INS_jalr || (ins < INS_jalr && ins > INS_j)) // jal < beqz < bnez < jalr < - // beq/bne/blt/bltu/bge/bgeu - { - if (isValidSimm13(jmpDist + maxPlaceholderSize)) - { - continue; - } - else if (isValidSimm21(jmpDist + maxPlaceholderSize)) - { - // convert to opposite branch and jal - extra = 4; - } - else - { - // convert to opposite branch and jalr - extra = 4 * 6; - } - } - else if (ins == INS_jal || ins == INS_j) + if (ins > INS_jalr || (ins < INS_jalr && ins > INS_j)) // jal < beqz < bnez < jalr < + // beq/bne/blt/bltu/bge/bgeu + { + if (isValidSimm13(jmpDist + maxPlaceholderSize)) { - if (isValidSimm21(jmpDist + maxPlaceholderSize)) - { - continue; - } - else - { - // convert to jalr - extra = 4 * 5; - } + continue; } - else + // convert branch to opposite branch and jump + int insCount = isValidSimm21(jmpDist + maxPlaceholderSize) ? 1 /*jal*/ : 2 /*auipc+jalr*/; + extra = insCount * sizeof(code_t); + } + else if (ins == INS_jal || ins == INS_j) + { + if (isValidSimm21(jmpDist + maxPlaceholderSize)) { - assert(ins == INS_jalr); - assert((jmpDist + maxPlaceholderSize) < 0x800); continue; } - - jmp->idInsOpt(INS_OPTS_JALR); - jmp->idCodeSize(jmp->idCodeSize() + extra); - jmpIG->igSize += (unsigned short)extra; // the placeholder sizeof(INS_OPTS_JALR) - sizeof(INS_OPTS_J). - adjSJ += (UNATIVE_OFFSET)extra; - adjIG += (UNATIVE_OFFSET)extra; - emitTotalCodeSize += (UNATIVE_OFFSET)extra; - jmpIG->igFlags |= IGF_UPD_ISZ; - isLinkingEnd |= 0x1; + // convert jal to auipc+jalr + extra = sizeof(code_t); } - continue; + else + { + unreached(); + } + + jmp->idInsOpt(INS_OPTS_JALR); + jmp->idCodeSize(jmp->idCodeSize() + extra); + jmpIG->igSize += (unsigned short)extra; // the placeholder sizeof(INS_OPTS_JALR) - sizeof(INS_OPTS_J). + adjSJ += (UNATIVE_OFFSET)extra; + adjIG += (UNATIVE_OFFSET)extra; + emitTotalCodeSize += (UNATIVE_OFFSET)extra; + jmpIG->igFlags |= IGF_UPD_ISZ; + isLinkingEnd |= 0x1; } } // end for each jump @@ -3235,58 +3000,21 @@ BYTE* emitter::emitOutputInstr_OptsRc(BYTE* dst, const instrDesc* id, instructio assert(id->idAddr()->iiaIsJitDataOffset()); assert(id->idGCref() == GCT_NONE); - const int dataOffs = id->idAddr()->iiaGetJitDataOffset(); - assert(dataOffs >= 0); - - const ssize_t immediate = emitGetInsSC(id); - assert((immediate >= 0) && (immediate < 0x4000)); // 0x4000 is arbitrary, currently 'imm' is always 0. - - const unsigned offset = static_cast(dataOffs + immediate); - assert(offset < emitDataSize()); + const int offset = id->idAddr()->iiaGetJitDataOffset(); + assert(offset >= 0); + assert((UNATIVE_OFFSET)offset < emitDataSize()); *ins = id->idIns(); const regNumber reg1 = id->idReg1(); - - if (id->idCodeSize() == 8) - { - return emitOutputInstr_OptsRcPcRel(dst, ins, offset, reg1); - } - return emitOutputInstr_OptsRcNoPcRel(dst, ins, offset, reg1); -} - -BYTE* emitter::emitOutputInstr_OptsRcPcRel(BYTE* dst, instruction* ins, unsigned offset, regNumber reg1) -{ + assert(reg1 != REG_ZERO); + assert(id->idCodeSize() == 2 * sizeof(code_t)); const ssize_t immediate = (emitConsBlock - dst) + offset; assert((immediate > 0) && ((immediate & 0x03) == 0)); + assert(isValidSimm32(immediate)); - const regNumber rsvdReg = codeGen->rsGetRsvdReg(); - dst += emitOutput_UTypeInstr(dst, INS_auipc, rsvdReg, UpperNBitsOfWordSignExtend<20>(immediate)); - - instruction lastIns = *ins; - - if (*ins == INS_jal) - { - *ins = lastIns = INS_addi; - } - dst += emitOutput_ITypeInstr(dst, lastIns, reg1, rsvdReg, LowerNBitsOfWord<12>(immediate)); - return dst; -} - -BYTE* emitter::emitOutputInstr_OptsRcNoPcRel(BYTE* dst, instruction* ins, unsigned offset, regNumber reg1) -{ - const ssize_t immediate = reinterpret_cast(emitConsBlock) + offset; - assertCodeLength(static_cast(immediate), 48); // RISC-V Linux Kernel SV48 - const regNumber rsvdReg = codeGen->rsGetRsvdReg(); - - const instruction lastIns = (*ins == INS_jal) ? (*ins = INS_addi) : *ins; - const ssize_t high = immediate >> 16; - - dst += emitOutput_UTypeInstr(dst, INS_lui, rsvdReg, UpperNBitsOfWordSignExtend<20>(high)); - dst += emitOutput_ITypeInstr(dst, INS_addi, rsvdReg, rsvdReg, LowerNBitsOfWord<12>(high)); - dst += emitOutput_ITypeInstr(dst, INS_slli, rsvdReg, rsvdReg, 5); - dst += emitOutput_ITypeInstr(dst, INS_addi, rsvdReg, rsvdReg, LowerNBitsOfWord<5>(immediate >> 11)); - dst += emitOutput_ITypeInstr(dst, INS_slli, rsvdReg, rsvdReg, 11); - dst += emitOutput_ITypeInstr(dst, lastIns, reg1, rsvdReg, LowerNBitsOfWord<11>(immediate)); + const regNumber tempReg = isFloatReg(reg1) ? codeGen->rsGetRsvdReg() : reg1; + dst += emitOutput_UTypeInstr(dst, INS_auipc, tempReg, UpperNBitsOfWordSignExtend<20>(immediate)); + dst += emitOutput_ITypeInstr(dst, *ins, reg1, tempReg, LowerNBitsOfWord<12>(immediate)); return dst; } @@ -3298,102 +3026,49 @@ BYTE* emitter::emitOutputInstr_OptsRl(BYTE* dst, instrDesc* id, instruction* ins const regNumber reg1 = id->idReg1(); const ssize_t igOffs = targetInsGroup->igOffs; - if (id->idIsReloc()) - { - *ins = INS_addi; - return emitOutputInstr_OptsRlReloc(dst, igOffs, reg1); - } - *ins = INS_add; - return emitOutputInstr_OptsRlNoReloc(dst, igOffs, reg1); -} + *ins = INS_auipc; -BYTE* emitter::emitOutputInstr_OptsRlReloc(BYTE* dst, ssize_t igOffs, regNumber reg1) -{ const ssize_t immediate = (emitCodeBlock - dst) + igOffs; assert((immediate & 0x03) == 0); - + assert(isValidSimm32(immediate)); dst += emitOutput_UTypeInstr(dst, INS_auipc, reg1, UpperNBitsOfWordSignExtend<20>(immediate)); dst += emitOutput_ITypeInstr(dst, INS_addi, reg1, reg1, LowerNBitsOfWord<12>(immediate)); return dst; } -BYTE* emitter::emitOutputInstr_OptsRlNoReloc(BYTE* dst, ssize_t igOffs, regNumber reg1) -{ - const ssize_t immediate = reinterpret_cast(emitCodeBlock) + igOffs; - assertCodeLength(static_cast(immediate), 48); // RISC-V Linux Kernel SV48 - - const regNumber rsvdReg = codeGen->rsGetRsvdReg(); - const ssize_t upperSignExt = UpperWordOfDoubleWordDoubleSignExtend<32, 52>(immediate); - - dst += emitOutput_UTypeInstr(dst, INS_lui, rsvdReg, UpperNBitsOfWordSignExtend<20>(immediate)); - dst += emitOutput_ITypeInstr(dst, INS_addi, rsvdReg, rsvdReg, LowerNBitsOfWord<12>(immediate)); - dst += emitOutput_UTypeInstr(dst, INS_lui, reg1, LowerNBitsOfWord<16>(upperSignExt)); - dst += emitOutput_ITypeInstr(dst, INS_slli, reg1, reg1, 20); - dst += emitOutput_RTypeInstr(dst, INS_add, reg1, reg1, rsvdReg); - return dst; -} - BYTE* emitter::emitOutputInstr_OptsJalr(BYTE* dst, instrDescJmp* jmp, const insGroup* ig, instruction* ins) { const ssize_t immediate = emitOutputInstrJumpDistance(dst, ig, jmp) - 4; assert((immediate & 0x03) == 0); *ins = jmp->idIns(); - switch (jmp->idCodeSize()) - { - case 8: - return emitOutputInstr_OptsJalr8(dst, jmp, immediate); - case 24: - assert(jmp->idInsIs(INS_jal, INS_j)); - return emitOutputInstr_OptsJalr24(dst, immediate); - case 28: - return emitOutputInstr_OptsJalr28(dst, jmp, immediate); - default: - // case 0 - 4: The original INS_OPTS_JALR: not used by now!!! - break; + if (jmp->idInsIs(INS_jal, INS_j)) // far jump + { + assert(jmp->idCodeSize() == 2 * sizeof(code_t)); + assert(isValidSimm32(immediate)); + dst += emitOutput_UTypeInstr(dst, INS_auipc, REG_RA, UpperNBitsOfWordSignExtend<20>(immediate)); + dst += emitOutput_ITypeInstr(dst, INS_jalr, REG_RA, REG_RA, LowerNBitsOfWord<12>(immediate)); + } + else // opposite branch + jump + { + assert(jmp->idInsIs(INS_beqz, INS_bnez, INS_beq, INS_bne, INS_blt, INS_bltu, INS_bge, INS_bgeu)); + regNumber reg2 = jmp->idInsIs(INS_beqz, INS_bnez) ? REG_R0 : jmp->idReg2(); + dst += emitOutput_BTypeInstr_InvertComparation(dst, jmp->idIns(), jmp->idReg1(), reg2, jmp->idCodeSize()); + if (jmp->idCodeSize() == 2 * sizeof(code_t)) + { + dst += emitOutput_JTypeInstr(dst, INS_jal, REG_ZERO, TrimSignedToImm21(immediate)); + } + else + { + assert(jmp->idCodeSize() == 3 * sizeof(code_t)); + assert(isValidSimm32(immediate)); + dst += emitOutput_UTypeInstr(dst, INS_auipc, REG_RA, UpperNBitsOfWordSignExtend<20>(immediate)); + dst += emitOutput_ITypeInstr(dst, INS_jalr, REG_ZERO, REG_RA, LowerNBitsOfWord<12>(immediate)); + } } - unreached(); - return nullptr; -} - -BYTE* emitter::emitOutputInstr_OptsJalr8(BYTE* dst, const instrDescJmp* jmp, ssize_t immediate) -{ - const regNumber reg2 = jmp->idInsIs(INS_beqz, INS_bnez) ? REG_R0 : jmp->idReg2(); - - dst += emitOutput_BTypeInstr_InvertComparation(dst, jmp->idIns(), jmp->idReg1(), reg2, 0x8); - dst += emitOutput_JTypeInstr(dst, INS_jal, REG_ZERO, TrimSignedToImm21(immediate)); - return dst; -} - -BYTE* emitter::emitOutputInstr_OptsJalr24(BYTE* dst, ssize_t immediate) -{ - // Make target address with offset, then jump (JALR) with the target address - immediate -= 2 * 4; - const ssize_t high = UpperWordOfDoubleWordSingleSignExtend<0>(immediate); - - dst += emitOutput_UTypeInstr(dst, INS_lui, REG_RA, UpperNBitsOfWordSignExtend<20>(high)); - dst += emitOutput_ITypeInstr(dst, INS_addi, REG_RA, REG_RA, LowerNBitsOfWord<12>(high)); - dst += emitOutput_ITypeInstr(dst, INS_slli, REG_RA, REG_RA, 32); - - const regNumber rsvdReg = codeGen->rsGetRsvdReg(); - const ssize_t low = LowerWordOfDoubleWord(immediate); - - dst += emitOutput_UTypeInstr(dst, INS_auipc, rsvdReg, UpperNBitsOfWordSignExtend<20>(low)); - dst += emitOutput_RTypeInstr(dst, INS_add, rsvdReg, REG_RA, rsvdReg); - dst += emitOutput_ITypeInstr(dst, INS_jalr, REG_RA, rsvdReg, LowerNBitsOfWord<12>(low)); - return dst; } -BYTE* emitter::emitOutputInstr_OptsJalr28(BYTE* dst, const instrDescJmp* jmp, ssize_t immediate) -{ - regNumber reg2 = jmp->idInsIs(INS_beqz, INS_bnez) ? REG_R0 : jmp->idReg2(); - - dst += emitOutput_BTypeInstr_InvertComparation(dst, jmp->idIns(), jmp->idReg1(), reg2, 0x1c); - - return emitOutputInstr_OptsJalr24(dst, immediate); -} - BYTE* emitter::emitOutputInstr_OptsJCond(BYTE* dst, instrDesc* id, const insGroup* ig, instruction* ins) { const ssize_t immediate = emitOutputInstrJumpDistance(dst, ig, static_cast(id)); @@ -3453,7 +3128,7 @@ BYTE* emitter::emitOutputInstr_OptsC(BYTE* dst, instrDesc* id, const insGroup* i assert(!id->idIsLargeCns()); *size = sizeof(instrDesc); } - dst += emitOutputCall(ig, dst, id, 0); + dst += emitOutputCall(ig, dst, id); return dst; } diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index cbb2b11ec96747..c02a43087024f5 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -123,15 +123,8 @@ unsigned emitOutput_JTypeInstr(BYTE* dst, instruction ins, regNumber rd, unsigne BYTE* emitOutputInstr_OptsReloc(BYTE* dst, const instrDesc* id, instruction* ins); BYTE* emitOutputInstr_OptsRc(BYTE* dst, const instrDesc* id, instruction* ins); -BYTE* emitOutputInstr_OptsRcPcRel(BYTE* dst, instruction* ins, unsigned offset, regNumber reg1); -BYTE* emitOutputInstr_OptsRcNoPcRel(BYTE* dst, instruction* ins, unsigned offset, regNumber reg1); BYTE* emitOutputInstr_OptsRl(BYTE* dst, instrDesc* id, instruction* ins); -BYTE* emitOutputInstr_OptsRlReloc(BYTE* dst, ssize_t igOffs, regNumber reg1); -BYTE* emitOutputInstr_OptsRlNoReloc(BYTE* dst, ssize_t igOffs, regNumber reg1); BYTE* emitOutputInstr_OptsJalr(BYTE* dst, instrDescJmp* jmp, const insGroup* ig, instruction* ins); -BYTE* emitOutputInstr_OptsJalr8(BYTE* dst, const instrDescJmp* jmp, ssize_t immediate); -BYTE* emitOutputInstr_OptsJalr24(BYTE* dst, ssize_t immediate); -BYTE* emitOutputInstr_OptsJalr28(BYTE* dst, const instrDescJmp* jmp, ssize_t immediate); BYTE* emitOutputInstr_OptsJCond(BYTE* dst, instrDesc* id, const insGroup* ig, instruction* ins); BYTE* emitOutputInstr_OptsJ(BYTE* dst, instrDesc* id, const insGroup* ig, instruction* ins); BYTE* emitOutputInstr_OptsC(BYTE* dst, instrDesc* id, const insGroup* ig, size_t* size); @@ -325,8 +318,7 @@ void emitIns_R_R_I_I( void emitIns_R_R_R_R(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber reg3, regNumber reg4); -void emitIns_R_C( - instruction ins, emitAttr attr, regNumber reg, regNumber tmpReg, CORINFO_FIELD_HANDLE fldHnd, int offs); +void emitIns_R_C(instruction ins, emitAttr attr, regNumber destReg, regNumber addrReg, CORINFO_FIELD_HANDLE fldHnd); void emitIns_R_L(instruction ins, emitAttr attr, BasicBlock* dst, regNumber reg); @@ -339,7 +331,7 @@ void emitIns_R_AI(instruction ins, regNumber reg, ssize_t disp DEBUGARG(size_t targetHandle = 0) DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); -unsigned emitOutputCall(const insGroup* ig, BYTE* dst, instrDesc* id, code_t code); +unsigned emitOutputCall(const insGroup* ig, BYTE* dst, instrDesc* id); unsigned get_curTotalCodeSize(); // bytes of code diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index b0a65624163f0e..30b5ea482838b8 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -87,7 +87,10 @@ bool emitter::IsAvx512OnlyInstruction(instruction ins) bool emitter::IsApxOnlyInstruction(instruction ins) { +#ifdef TARGET_AMD64 return (ins >= FIRST_APX_INSTRUCTION) && (ins <= LAST_APX_INSTRUCTION); +#endif // TARGET_AMD64 + return false; } bool emitter::IsAVXVNNIFamilyInstruction(instruction ins) @@ -255,18 +258,55 @@ bool emitter::HasRex2Encoding(instruction ins) return (flags & Encoding_REX2) != 0; } -bool emitter::HasApxNdd(instruction ins) +//------------------------------------------------------------------------ +// IsApxNddCompatibleInstruction: Is this a APX-EVEX.ND compatible instruction? +// +// Arguments: +// ins - The instruction to check. +// +// Returns: +// `true` if it is a APX-EVEX.ND compatible instruction. +// +bool emitter::IsApxNddCompatibleInstruction(instruction ins) { insFlags flags = CodeGenInterface::instInfo[ins]; return (flags & INS_Flags_Has_NDD) != 0; } -bool emitter::HasApxNf(instruction ins) +//------------------------------------------------------------------------ +// IsApxNfCompatibleInstruction: Is this a APX-EVEX.NF compatible instruction? +// +// Arguments: +// ins - The instruction to check. +// +// Returns: +// `true` if it is a APX-EVEX.NF compatible instruction. +// +bool emitter::IsApxNfCompatibleInstruction(instruction ins) { insFlags flags = CodeGenInterface::instInfo[ins]; return (flags & INS_Flags_Has_NF) != 0; } +//------------------------------------------------------------------------ +// IsApxZuCompatibleInstruction: Is this a APX-EVEX.ZU compatible instruction? +// +// Arguments: +// ins - The instruction to check. +// +// Returns: +// `true` if it is a APX-EVEX.ZU compatible instruction. +// +bool emitter::IsApxZuCompatibleInstruction(instruction ins) +{ +#ifdef TARGET_AMD64 + // For now, we only have SETZUcc enabled for EVEX.ZU. + return ((ins >= INS_seto_apx) && (ins <= INS_setg_apx)); +#else + return false; +#endif +} + bool emitter::IsVexEncodableInstruction(instruction ins) const { if (!UseVEXEncoding()) @@ -341,6 +381,11 @@ bool emitter::IsEvexEncodableInstruction(instruction ins) const // some NAOT scenarios and it will already have been recorded // for appropriate usage. + if (IsBMIInstruction(ins) || IsKMOVInstruction(ins)) + { + return UsePromotedEVEXEncoding(); + } + switch (ins) { #if defined(FEATURE_HW_INTRINSICS) @@ -412,7 +457,7 @@ bool emitter::IsRex2EncodableInstruction(instruction ins) const } //------------------------------------------------------------------------ -// IsApxNDDEncodableInstruction: Answer the question- does this instruction have apx ndd form. +// IsApxNddEncodableInstruction: Answer the question- does this instruction have apx ndd form. // // Arguments: // ins - The instruction to check. @@ -420,18 +465,18 @@ bool emitter::IsRex2EncodableInstruction(instruction ins) const // Returns: // `true` if ins has apx ndd form. // -bool emitter::IsApxNDDEncodableInstruction(instruction ins) const +bool emitter::IsApxNddEncodableInstruction(instruction ins) const { if (!UsePromotedEVEXEncoding()) { return false; } - return HasApxNdd(ins); + return IsApxNddCompatibleInstruction(ins); } //------------------------------------------------------------------------ -// IsApxNFEncodableInstruction: Answer the question - does this instruction have Evex.nf supported +// IsApxNfEncodableInstruction: Answer the question - does this instruction have Evex.nf supported // // Arguments: // ins - The instruction to check. @@ -439,14 +484,14 @@ bool emitter::IsApxNDDEncodableInstruction(instruction ins) const // Returns: // `true` if ins is Evex.nf supported. // -bool emitter::IsApxNFEncodableInstruction(instruction ins) const +bool emitter::IsApxNfEncodableInstruction(instruction ins) const { if (!UsePromotedEVEXEncoding()) { return false; } - return HasApxNf(ins); + return IsApxNfCompatibleInstruction(ins); } //------------------------------------------------------------------------ @@ -466,14 +511,13 @@ bool emitter::IsApxExtendedEvexInstruction(instruction ins) const return false; } - if (HasApxNdd(ins) || HasApxNf(ins)) + if (IsApxNddCompatibleInstruction(ins)) { return true; } - if (ins == INS_crc32_apx || ins == INS_movbe_apx) + if (IsApxNfCompatibleInstruction(ins)) { - // With the new opcode, CRC32 is promoted to EVEX with APX. return true; } @@ -893,7 +937,7 @@ bool emitter::DoJitUseApxNDD(instruction ins) const #if !defined(TARGET_AMD64) return false; #else - return JitConfig.EnableApxNDD() && IsApxNDDEncodableInstruction(ins); + return JitConfig.EnableApxNDD() && IsApxNddEncodableInstruction(ins); #endif } @@ -1572,7 +1616,7 @@ insOpts emitter::GetEmbRoundingMode(uint8_t mode) const switch (mode) { case 1: - return INS_OPTS_EVEX_eb_er_rd; + return INS_OPTS_EVEX_er_rd; case 2: return INS_OPTS_EVEX_er_ru; case 3: @@ -1842,7 +1886,7 @@ bool emitter::TakesEvexPrefix(const instrDesc* id) const return true; } - if (HasEmbeddedBroadcast(id) || HasEmbeddedMask(id)) + if (id->idIsEvexbContextSet() || HasEmbeddedMask(id)) { // Requires the EVEX encoding due to embedded functionality return true; @@ -1866,59 +1910,30 @@ bool emitter::TakesEvexPrefix(const instrDesc* id) const #if defined(DEBUG) if (emitComp->DoJitStressEvexEncoding()) { - if (IsBMIInstruction(ins)) - { - // The Encoding_EVEX on some BMI instructions is tagged due to APX, - // they cannot be stressed with JitStressEvexEncoding. - return false; - } - - if (IsKMOVInstruction(ins)) - { - // KMOV should not be encoded in EVEX when stressing EVEX, as they are supposed to encded in EVEX only - // when APX is available, only stressing EVEX is not enough making the encoding valid. - return false; - } - - // Requires the EVEX encoding due to STRESS mode and no change in semantics - // - // Some instructions, like VCMPEQW return the value in a SIMD register for - // VEX but in a MASK register for EVEX. Such instructions will have already - // returned TRUE if they should have used EVEX due to the HasMaskReg(id) - // check above so we need to still return false here to preserve semantics. - return !HasKMaskRegisterDest(ins); + // Requires the EVEX encoding due to STRESS mode + return true; } +#endif // DEBUG - if (IsApxExtendedEvexInstruction(ins) && emitComp->DoJitStressPromotedEvexEncoding()) + if (id->idHasMem()) { - // This path will be hit when we stress APX-EVEX and encode VEX with Extended EVEX. - if (IsKMOVInstruction(ins)) + if ((ins == INS_pslldq) || (ins == INS_psrldq)) { + // The memory operand can only be encoded using the EVEX encoding return true; } - if (IsBMIInstruction(ins)) + if ((insTupleTypeInfo(ins) & INS_TT_MEM128) != 0) { - return HasApxNf(ins); - } - - return false; - } -#endif // DEBUG - - if ((ins == INS_pslldq) || (ins == INS_psrldq)) - { - // The memory operand can only be encoded using the EVEX encoding - return id->idHasMem(); - } - - if ((insTupleTypeInfo(ins) & INS_TT_MEM128) != 0) - { - assert((ins == INS_pslld) || (ins == INS_psllq) || (ins == INS_psllw) || (ins == INS_psrad) || - (ins == INS_psraw) || (ins == INS_psrld) || (ins == INS_psrlq) || (ins == INS_psrlw)); + assert((ins == INS_pslld) || (ins == INS_psllq) || (ins == INS_psllw) || (ins == INS_psrad) || + (ins == INS_psraw) || (ins == INS_psrld) || (ins == INS_psrlq) || (ins == INS_psrlw)); - // Memory operand with immediate can only be encoded using EVEX - return id->idHasMemAndCns(); + if (id->idHasMemAndCns()) + { + // Memory operand with immediate can only be encoded using EVEX + return true; + } + } } return false; @@ -2012,18 +2027,15 @@ bool emitter::TakesApxExtendedEvexPrefix(const instrDesc* id) const return false; } - if (id->idIsEvexNdContextSet()) - { - return true; - } - - if (id->idIsEvexNfContextSet()) + if (IsApxNddCompatibleInstruction(ins) && id->idIsEvexNdContextSet()) { + // The instruction uses APX-ND hint, and it requires EVEX. return true; } - if (ins == INS_crc32_apx || ins == INS_movbe_apx) + if (IsApxNfCompatibleInstruction(ins) && id->idIsEvexNfContextSet()) { + // The instruction uses APX-NF hint, and it requires EVEX. return true; } @@ -2130,12 +2142,18 @@ emitter::code_t emitter::AddEvexPrefix(const instrDesc* id, code_t code, emitAtt // TODO-XArch-APX: // verify if it is actually safe to reuse the EVEX.ND with EVEX.B on instrDesc. - if (id->idIsEvexNdContextSet()) + if (IsApxNddCompatibleInstruction(ins) && id->idIsEvexNdContextSet()) { code |= ND_BIT_IN_BYTE_EVEX_PREFIX; } - if (id->idIsEvexNfContextSet()) + if (IsApxZuCompatibleInstruction(ins) && id->idIsEvexZuContextSet()) + { + // EVEX.ZU reuses the EVEX.ND bit for SETcc and IMUL. + code |= ND_BIT_IN_BYTE_EVEX_PREFIX; + } + + if (IsApxNfCompatibleInstruction(ins) && id->idIsEvexNfContextSet()) { code |= NF_BIT_IN_BYTE_EVEX_PREFIX; } @@ -2148,11 +2166,6 @@ emitter::code_t emitter::AddEvexPrefix(const instrDesc* id, code_t code, emitAtt if (instrIsExtendedReg3opImul(ins)) { // EVEX.R3 - // TODO-XArch-APX: - // A few side notes: based on how JIT defined IMUL, we may need to extend - // the definition to `IMUL_31` to cover EGPRs. And it can be defined in a - // similar way that opcodes comes with built-in REX2 prefix, and convert - // it to EVEX when needed with some helper functions. code &= 0xFF7FFFFFFFFFFFFFULL; } #ifdef TARGET_AMD64 @@ -2183,11 +2196,13 @@ emitter::code_t emitter::AddEvexPrefix(const instrDesc* id, code_t code, emitAtt if (id->idIsEvexbContextSet()) { - code |= BBIT_IN_BYTE_EVEX_PREFIX; - if (!id->idHasMem()) { + // For non-memory operations, this holds the EVEX.RC bits + // that indicate the rounding mode to use, EVEX.b is implied + unsigned roundingMode = id->idGetEvexbContext(); + if (roundingMode == 1) { // {rd-sae} @@ -2210,10 +2225,16 @@ emitter::code_t emitter::AddEvexPrefix(const instrDesc* id, code_t code, emitAtt { unreached(); } + + code |= BBIT_IN_BYTE_EVEX_PREFIX; } - else + else if (HasEmbeddedBroadcast(id)) { - assert(id->idGetEvexbContext() == 1); + // For memory operations, the low bit being set indicates + // we are using embedded broadcast, while the upper bit + // being set indicates we are using compressed displacement + + code |= BBIT_IN_BYTE_EVEX_PREFIX; } } @@ -2984,7 +3005,7 @@ emitter::code_t emitter::emitExtractEvexPrefix(instruction ins, code_t& code) co // // 00 - None (0F - packed float) // 01 - 66 (66 0F - packed double) - // 10 - F3 (F3 0F - scalar float + // 10 - F3 (F3 0F - scalar float) // 11 - F2 (F2 0F - scalar double) switch (sizePrefix) { @@ -3056,8 +3077,9 @@ emitter::code_t emitter::emitExtractEvexPrefix(instruction ins, code_t& code) co // 1. An escape byte 0F (For isa before AVX10.2) // 2. A map number from 0 to 7 (For AVX10.2 and above) leadingBytes = check; - assert(leadingBytes == 0x0F || (emitComp->compIsaSupportedDebugOnly(InstructionSet_AVX10v2) && - leadingBytes >= 0x00 && leadingBytes <= 0x07)); + assert((leadingBytes == 0x0F) || ((emitComp->compIsaSupportedDebugOnly(InstructionSet_AVX10v2) || + (emitComp->compIsaSupportedDebugOnly(InstructionSet_APX))) && + (leadingBytes >= 0x00) && (leadingBytes <= 0x07))); // Get rid of both sizePrefix and escape byte code &= 0x0000FFFFLL; @@ -3128,6 +3150,13 @@ emitter::code_t emitter::emitExtractEvexPrefix(instruction ins, code_t& code) co break; } + case 0x04: + { + assert(emitComp->compIsaSupportedDebugOnly(InstructionSet_APX)); + evexPrefix |= (0x04 << 16); + break; + } + case 0x05: { assert(emitComp->compIsaSupportedDebugOnly(InstructionSet_AVX10v2)); @@ -3138,7 +3167,6 @@ emitter::code_t emitter::emitExtractEvexPrefix(instruction ins, code_t& code) co case 0x01: case 0x02: case 0x03: - case 0x04: case 0x06: case 0x07: default: @@ -3912,7 +3940,7 @@ inline emitter::insFormat emitter::emitInsModeFormat(instruction ins, insFormat #ifdef TARGET_AMD64 if (useNDD) { - assert(IsApxNDDEncodableInstruction(ins)); + assert(IsApxNddEncodableInstruction(ins)); if (ins == INS_rcl_N || ins == INS_rcr_N || ins == INS_rol_N || ins == INS_ror_N || ins == INS_shl_N || ins == INS_shr_N || ins == INS_sar_N) { @@ -5123,175 +5151,85 @@ inline UNATIVE_OFFSET emitter::emitInsSizeRR(instrDesc* id) // inline UNATIVE_OFFSET emitter::emitInsSizeSVCalcDisp(instrDesc* id, code_t code, int var, int dsp) { + instruction ins = id->idIns(); UNATIVE_OFFSET size = emitInsSize(id, code, /* includeRexPrefixSize */ true); - UNATIVE_OFFSET offs; - bool offsIsUpperBound = true; - bool EBPbased = true; - /* Is this a temporary? */ + int adr; + bool EBPbased; + bool dspInByte; + bool dspIsZero; - if (var < 0) - { - /* An address off of ESP takes an extra byte */ + adr = emitComp->lvaFrameAddress(var, &EBPbased); + dsp = adr + id->idAddr()->iiaLclVar.lvaOffset(); - if (!emitHasFramePtr) - { - size++; - } + dspIsZero = (dsp == 0); - // The offset is already assigned. Find the temp. - TempDsc* tmp = codeGen->regSet.tmpFindNum(var, RegSet::TEMP_USAGE_USED); - if (tmp == nullptr) - { - // It might be in the free lists, if we're working on zero initializing the temps. - tmp = codeGen->regSet.tmpFindNum(var, RegSet::TEMP_USAGE_FREE); - } - assert(tmp != nullptr); - offs = tmp->tdTempOffs(); + bool tryCompress = true; - // We only care about the magnitude of the offset here, to determine instruction size. - if (emitComp->isFramePointerUsed()) - { - if ((int)offs < 0) - { - offs = -(int)offs; - } - } - else - { - // SP-based offsets must already be positive. - assert((int)offs >= 0); - } + if (EBPbased) + { + // EBP always requires a displacement + dspIsZero = false; } else { + // An address off of ESP takes an extra byte + size++; - /* Get the frame offset of the (non-temp) variable */ - - offs = dsp + emitComp->lvaFrameAddress(var, &EBPbased); - - /* An address off of ESP takes an extra byte */ - - if (!EBPbased) - { - ++size; - } +#if !FEATURE_FIXED_OUT_ARGS + // Adjust the offset by the amount currently pushed on the CPU stack + dsp += emitCurStackLvl; - /* Is this a stack parameter reference? */ + // At this point, the amount pushed onto the stack is an estimate and + // so we cannot reliably predict if it will be zero or if compression + // can occur. So we'll pessimize to not compressing and not using zero + // displacement here, potentially resulting in over-allocation of bytes + tryCompress = false; + dspIsZero = false; +#endif // !FEATURE_FIXED_OUT_ARGS + } - if ((emitComp->lvaIsParameter(var) && !emitComp->lvaParamHasLocalStackSpace(var)) || - (static_cast(var) == emitComp->lvaRetAddrVar)) + if (IsEvexEncodableInstruction(ins) || IsApxExtendedEvexInstruction(ins)) + { + if (tryCompress) { - /* If no EBP frame, arguments and ret addr are off of ESP, above temps */ + ssize_t compressedDsp; - if (!EBPbased) + // Only the scaling factor of the original EVEX instructions can be changed by embedded broadcast. + // If the instruction does not have tuple type info, say extended EVEX from APX, the scaling factor is + // constantly 1, then this optimization cannot be performed, and whether disp8 or disp32 should be applied + // only depends dspInByte. + if (TryEvexCompressDisp8Byte(id, dsp, &compressedDsp, &dspInByte) && hasTupleTypeInfo(ins)) { - assert((int)offs >= 0); + SetEvexCompressedDisplacement(id); } } + else if (TakesEvexPrefix(id)) + { + // EVEX requires compressed displacement to fit in a byte + dspInByte = false; + } else { - /* Locals off of EBP are at negative offsets */ - - if (EBPbased) - { -#if defined(TARGET_AMD64) && !defined(UNIX_AMD64_ABI) - // If localloc is not used, then ebp chaining is done and hence - // offset of locals will be at negative offsets, Otherwise offsets - // will be positive. In future, when RBP gets positioned in the - // middle of the frame so as to optimize instruction encoding size, - // the below asserts needs to be modified appropriately. - // However, for Unix platforms, we always do frame pointer chaining, - // so offsets from the frame pointer will always be negative. - if (emitComp->compLocallocUsed || emitComp->opts.compDbgEnC) - { - noway_assert((int)offs >= 0); - } - else -#endif - { - // Dev10 804810 - failing this assert can lead to bad codegen and runtime crashes - -#ifdef UNIX_AMD64_ABI - const LclVarDsc* varDsc = emitComp->lvaGetDesc(var); - bool isRegPassedArg = varDsc->lvIsParam && varDsc->lvIsRegArg; - // Register passed args could have a stack offset of 0. - noway_assert((int)offs < 0 || isRegPassedArg || emitComp->opts.IsOSR()); -#else // !UNIX_AMD64_ABI - - // OSR transitioning to RBP frame currently can have mid-frame FP - noway_assert(((int)offs < 0) || emitComp->opts.IsOSR()); -#endif // !UNIX_AMD64_ABI - } - - assert(emitComp->lvaTempsHaveLargerOffsetThanVars()); - - // Check whether we can use compressed displacement if EVEX. - if (TakesEvexPrefix(id) || TakesApxExtendedEvexPrefix(id)) - { - bool compressedFitsInByte = false; - TryEvexCompressDisp8Byte(id, ssize_t(offs), &compressedFitsInByte); - return size + (compressedFitsInByte ? sizeof(char) : sizeof(int)); - } - - if ((int)offs < 0) - { - // offset is negative - return size + ((int(offs) >= SCHAR_MIN) ? sizeof(char) : sizeof(int)); - } -#ifdef TARGET_AMD64 - // This case arises for localloc frames - else - { - return size + ((offs <= SCHAR_MAX) ? sizeof(char) : sizeof(int)); - } -#endif - } + dspInByte = ((signed char)dsp == (ssize_t)dsp); } } - - assert((int)offs >= 0); - -#if !FEATURE_FIXED_OUT_ARGS - - /* Are we addressing off of ESP? */ - - if (!emitHasFramePtr) - { - /* Adjust the effective offset if necessary */ - - if (emitCntStackDepth) - offs += emitCurStackLvl; - - // we could (and used to) check for the special case [sp] here but the stack offset - // estimator was off, and there is very little harm in overestimating for such a - // rare case. - } - -#endif // !FEATURE_FIXED_OUT_ARGS - - bool useSmallEncoding = false; - if (TakesEvexPrefix(id) || TakesApxExtendedEvexPrefix(id)) - { - TryEvexCompressDisp8Byte(id, ssize_t(offs), &useSmallEncoding); - } else { -#ifdef TARGET_AMD64 - useSmallEncoding = (SCHAR_MIN <= (int)offs) && ((int)offs <= SCHAR_MAX); -#else - useSmallEncoding = (offs <= size_t(SCHAR_MAX)); -#endif + dspInByte = ((signed char)dsp == (ssize_t)dsp); } - // If it is ESP based, and the offset is zero, we will not encode the disp part. - if (!EBPbased && offs == 0) + if (dspIsZero) { return size; } + else if (dspInByte) + { + return size + sizeof(char); + } else { - return size + (useSmallEncoding ? sizeof(char) : sizeof(int)); + return size + sizeof(int); } } @@ -5300,24 +5238,24 @@ inline UNATIVE_OFFSET emitter::emitInsSizeSV(instrDesc* id, code_t code, int var assert(id->idIns() != INS_invalid); instruction ins = id->idIns(); emitAttr attrSize = id->idOpSize(); - UNATIVE_OFFSET prefix = emitGetAdjustedSize(id, code); + UNATIVE_OFFSET size = emitInsSizeSVCalcDisp(id, code, var, dsp); + + size += emitGetAdjustedSize(id, code); // REX prefix if (TakesRexWPrefix(id) || IsExtendedReg(id->idReg1(), attrSize) || IsExtendedReg(id->idReg2(), attrSize)) { - prefix += emitGetRexPrefixSize(id, ins); + size += emitGetRexPrefixSize(id, ins); } - return prefix + emitInsSizeSVCalcDisp(id, code, var, dsp); + return size; } inline UNATIVE_OFFSET emitter::emitInsSizeSV(instrDesc* id, code_t code, int var, int dsp, int val) { assert(id->idIns() != INS_invalid); instruction ins = id->idIns(); - emitAttr attrSize = id->idOpSize(); - UNATIVE_OFFSET valSize = EA_SIZE_IN_BYTES(attrSize); - UNATIVE_OFFSET prefix = emitGetAdjustedSize(id, code); + UNATIVE_OFFSET valSize = EA_SIZE_IN_BYTES(id->idOpSize()); bool valInByte = ((signed char)val == val) && (ins != INS_mov) && (ins != INS_test); #ifdef TARGET_AMD64 @@ -5346,13 +5284,7 @@ inline UNATIVE_OFFSET emitter::emitInsSizeSV(instrDesc* id, code_t code, int var assert(!IsSSEOrAVXInstruction(ins)); } - // 64-bit operand instructions will need a REX.W prefix - if (TakesRexWPrefix(id) || IsExtendedReg(id->idReg1(), attrSize) || IsExtendedReg(id->idReg2(), attrSize)) - { - prefix += emitGetRexPrefixSize(id, ins); - } - - return prefix + valSize + emitInsSizeSVCalcDisp(id, code, var, dsp); + return valSize + emitInsSizeSV(id, code, var, dsp); } /*****************************************************************************/ @@ -5436,11 +5368,13 @@ UNATIVE_OFFSET emitter::emitInsSizeAM(instrDesc* id, code_t code) dspInByte = false; // relocs can't be placed in a byte dspIsZero = false; // relocs won't always be zero } - else + else if (IsEvexEncodableInstruction(ins) || IsApxExtendedEvexInstruction(ins)) { - if (TakesEvexPrefix(id) || TakesApxExtendedEvexPrefix(id)) + ssize_t compressedDsp; + + if (TryEvexCompressDisp8Byte(id, dsp, &compressedDsp, &dspInByte) && hasTupleTypeInfo(ins)) { - dsp = TryEvexCompressDisp8Byte(id, dsp, &dspInByte); + SetEvexCompressedDisplacement(id); } } @@ -6420,7 +6354,7 @@ regNumber emitter::emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, G #else if (useNDD) { - assert(IsApxNDDEncodableInstruction(ins)); + assert(IsApxNddEncodableInstruction(ins)); // targetReg has to be an actual register if using NDD. assert(targetReg < REG_STK); // make sure target register is not either of the src registers. @@ -7032,6 +6966,7 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg, insOpts i } SetEvexNfIfNeeded(id, instOptions); + SetEvexZuIfNeeded(id, instOptions); // Vex bytes sz += emitGetAdjustedSize(id, insEncodeMRreg(id, reg, attr, insCodeMR(ins))); @@ -8050,7 +7985,7 @@ void emitter::emitIns_R_R(instruction ins, emitAttr attr, regNumber reg1, regNum } // Checking EVEX.ND and NDD compatibility together in case the ND slot is overridden by other features. - bool useNDD = ((instOptions & INS_OPTS_EVEX_nd_MASK) != 0) && IsApxNDDEncodableInstruction(ins); + bool useNDD = ((instOptions & INS_OPTS_EVEX_nd_MASK) != 0) && IsApxNddEncodableInstruction(ins); emitAttr size = EA_SIZE(attr); @@ -8070,13 +8005,7 @@ void emitter::emitIns_R_R(instruction ins, emitAttr attr, regNumber reg1, regNum SetEvexNfIfNeeded(id, instOptions); SetEvexDFVIfNeeded(id, instOptions); SetApxPpxIfNeeded(id, instOptions); - - if ((instOptions & INS_OPTS_EVEX_b_MASK) != INS_OPTS_NONE) - { - // if EVEX.b needs to be set in this path, then it should be embedded rounding. - assert(UseEvexEncoding()); - id->idSetEvexbContext(instOptions); - } + SetEvexEmbRoundIfNeeded(id, instOptions); SetEvexEmbMaskIfNeeded(id, instOptions); UNATIVE_OFFSET sz = emitInsSizeRR(id); @@ -8103,7 +8032,7 @@ void emitter::emitIns_R_R_I( instrDesc* id = emitNewInstrSC(attr, ival); // Checking EVEX.ND and NDD compatibility together in case the ND slot is overridden by other features. - bool useNDD = ((instOptions & INS_OPTS_EVEX_nd_MASK) != 0) && IsApxNDDEncodableInstruction(ins); + bool useNDD = ((instOptions & INS_OPTS_EVEX_nd_MASK) != 0) && IsApxNddEncodableInstruction(ins); id->idIns(ins); id->idInsFmt(emitInsModeFormat(ins, IF_RRD_RRD_CNS, useNDD)); @@ -8352,11 +8281,11 @@ void emitter::emitIns_R_R_A( id->idReg1(reg1); id->idReg2(reg2); + emitHandleMemOp(indir, id, (ins == INS_mulx) ? IF_RWR_RWR_ARD : emitInsModeFormat(ins, IF_RRD_RRD_ARD), ins); + SetEvexBroadcastIfNeeded(id, instOptions); SetEvexEmbMaskIfNeeded(id, instOptions); - emitHandleMemOp(indir, id, (ins == INS_mulx) ? IF_RWR_RWR_ARD : emitInsModeFormat(ins, IF_RRD_RRD_ARD), ins); - UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins)); id->idCodeSize(sz); @@ -8501,7 +8430,7 @@ void emitter::emitIns_R_R_R( assert(IsThreeOperandAVXInstruction(ins) || IsKInstruction(ins) || IsApxExtendedEvexInstruction(ins)); // Checking EVEX.ND and NDD compatibility together in case the ND slot is overridden by other features. - bool useNDD = ((instOptions & INS_OPTS_EVEX_nd_MASK) != 0) && IsApxNDDEncodableInstruction(ins); + bool useNDD = ((instOptions & INS_OPTS_EVEX_nd_MASK) != 0) && IsApxNddEncodableInstruction(ins); instrDesc* id = emitNewInstr(attr); id->idIns(ins); @@ -8510,12 +8439,7 @@ void emitter::emitIns_R_R_R( id->idReg2(reg1); id->idReg3(reg2); - if ((instOptions & INS_OPTS_EVEX_b_MASK) != 0) - { - // if EVEX.b needs to be set in this path, then it should be embedded rounding. - assert(UseEvexEncoding()); - id->idSetEvexbContext(instOptions); - } + SetEvexEmbRoundIfNeeded(id, instOptions); SetEvexEmbMaskIfNeeded(id, instOptions); SetEvexNdIfNeeded(id, instOptions); SetEvexNfIfNeeded(id, instOptions); @@ -8536,7 +8460,7 @@ void emitter::emitIns_R_R_S( instrDesc* id = emitNewInstr(attr); // Checking EVEX.ND and NDD compatibility together in case the ND slot is overridden by other features. - bool useNDD = ((instOptions & INS_OPTS_EVEX_nd_MASK) != 0) && IsApxNDDEncodableInstruction(ins); + bool useNDD = ((instOptions & INS_OPTS_EVEX_nd_MASK) != 0) && IsApxNddEncodableInstruction(ins); id->idIns(ins); id->idInsFmt((ins == INS_mulx) ? IF_RWR_RWR_SRD : emitInsModeFormat(ins, IF_RRD_RRD_SRD, useNDD)); @@ -12560,7 +12484,7 @@ void emitter::emitDispInsHex(instrDesc* id, BYTE* code, size_t sz) // void emitter::emitDispEmbBroadcastCount(instrDesc* id) const { - if (!IsEvexEncodableInstruction(id->idIns()) || !id->idIsEvexbContextSet()) + if (!IsEvexEncodableInstruction(id->idIns()) || !HasEmbeddedBroadcast(id)) { return; } @@ -12587,8 +12511,10 @@ void emitter::emitDispEmbRounding(instrDesc* id) const // for ndd case, we don't need to display any thing special. return; } + assert(!id->idHasMem()); unsigned roundingMode = id->idGetEvexbContext(); + if (roundingMode == 1) { printf(" {rd-sae}"); @@ -12874,7 +12800,7 @@ void emitter::emitDispIns( /* Display the instruction name */ #ifdef TARGET_AMD64 - if (IsApxNFEncodableInstruction(id->idIns()) && id->idIsEvexNfContextSet()) + if (IsApxNfEncodableInstruction(id->idIns()) && id->idIsEvexNfContextSet()) { // print the EVEX.NF indication in psudeo prefix style. printf("{nf} "); @@ -12934,7 +12860,7 @@ void emitter::emitDispIns( else { attr = id->idOpSize(); - sstr = codeGen->genSizeStr(emitGetMemOpSize(id)); + sstr = codeGen->genSizeStr(emitGetMemOpSize(id, !id->idHasMem())); if (ins == INS_lea) { @@ -14735,22 +14661,39 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) GOT_DSP: - dspIsZero = (dsp == 0); - if (id->idIsDspReloc()) { dspInByte = false; // relocs can't be placed in a byte + dspIsZero = false; // relocs won't always be zero } - else + else if (IsEvexEncodableInstruction(ins) || IsApxExtendedEvexInstruction(ins)) { - if (TakesEvexPrefix(id) || TakesApxExtendedEvexPrefix(id)) + ssize_t compressedDsp; + + if (HasCompressedDisplacement(id)) + { + bool isCompressed = TryEvexCompressDisp8Byte(id, dsp, &compressedDsp, &dspInByte); + assert(isCompressed && dspInByte); + dsp = compressedDsp; + } + else if (TakesEvexPrefix(id) && !IsBMIInstruction(ins)) { - dsp = TryEvexCompressDisp8Byte(id, dsp, &dspInByte); + assert(!(TryEvexCompressDisp8Byte(id, dsp, &compressedDsp, &dspInByte) && hasTupleTypeInfo(ins))); + dspInByte = false; } else { + // TODO-XArch-APX: for now, Extended Evex instruction will not have compressed displacement, or more + // accurately, extended evex may not have compressed displacement optimization as the scaling factor is + // constantly 1. dspInByte = ((signed char)dsp == (ssize_t)dsp); } + dspIsZero = (dsp == 0); + } + else + { + dspInByte = ((signed char)dsp == (ssize_t)dsp); + dspIsZero = (dsp == 0); } if (isMoffset) @@ -14884,14 +14827,15 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) { if (EncodedBySSE38orSSE3A(ins) || (ins == INS_crc32)) { - // Does the offset fit in a byte? if (dspInByte) { + // This is "[rbp + dsp8]" dst += emitOutputByte(dst, code | 0x45); dst += emitOutputByte(dst, dsp); } else { + // This is "[rbp + dsp32]" dst += emitOutputByte(dst, code | 0x85); dst += emitOutputLong(dst, dsp); @@ -14901,23 +14845,21 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) } } } + else if (dspInByte) + { + // This is "[rbp + dsp8]" + dst += emitOutputWord(dst, code | 0x4500); + dst += emitOutputByte(dst, dsp); + } else { - // Does the offset fit in a byte? - if (dspInByte) - { - dst += emitOutputWord(dst, code | 0x4500); - dst += emitOutputByte(dst, dsp); - } - else - { - dst += emitOutputWord(dst, code | 0x8500); - dst += emitOutputLong(dst, dsp); + // This is "[rbp + dsp32]" + dst += emitOutputWord(dst, code | 0x8500); + dst += emitOutputLong(dst, dsp); - if (id->idIsDspReloc()) - { - emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); - } + if (id->idIsDspReloc()) + { + emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); } } break; @@ -14927,52 +14869,55 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) { if (EncodedBySSE38orSSE3A(ins) || (ins == INS_crc32)) { - // Is the offset 0 or does it at least fit in a byte? if (dspIsZero) { + // This is simply "[rsp]" dst += emitOutputByte(dst, code | 0x04); dst += emitOutputByte(dst, 0x24); } else if (dspInByte) { + // This is "[rsp + dsp8]" dst += emitOutputByte(dst, code | 0x44); dst += emitOutputByte(dst, 0x24); dst += emitOutputByte(dst, dsp); } else { + // This is "[rsp + dsp32]" dst += emitOutputByte(dst, code | 0x84); dst += emitOutputByte(dst, 0x24); dst += emitOutputLong(dst, dsp); + if (id->idIsDspReloc()) { emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); } } } + else if (dspIsZero) + { + // This is simply "[rsp]" + dst += emitOutputWord(dst, code | 0x0400); + dst += emitOutputByte(dst, 0x24); + } + else if (dspInByte) + { + // This is "[rsp + dsp8]" + dst += emitOutputWord(dst, code | 0x4400); + dst += emitOutputByte(dst, 0x24); + dst += emitOutputByte(dst, dsp); + } else { - // Is the offset 0 or does it at least fit in a byte? - if (dspIsZero) - { - dst += emitOutputWord(dst, code | 0x0400); - dst += emitOutputByte(dst, 0x24); - } - else if (dspInByte) - { - dst += emitOutputWord(dst, code | 0x4400); - dst += emitOutputByte(dst, 0x24); - dst += emitOutputByte(dst, dsp); - } - else + // This is "[rsp + dsp32]" + dst += emitOutputWord(dst, code | 0x8400); + dst += emitOutputByte(dst, 0x24); + dst += emitOutputLong(dst, dsp); + + if (id->idIsDspReloc()) { - dst += emitOutputWord(dst, code | 0x8400); - dst += emitOutputByte(dst, 0x24); - dst += emitOutputLong(dst, dsp); - if (id->idIsDspReloc()) - { - emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); - } + emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); } } break; @@ -14985,28 +14930,26 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) // Put the register in the opcode code |= insEncodeReg012(id, reg, EA_PTRSIZE, nullptr); - // Is there a displacement? if (dspIsZero) { // This is simply "[reg]" dst += emitOutputByte(dst, code); } + else if (dspInByte) + { + // This is "[reg + dsp8]" + dst += emitOutputByte(dst, code | 0x40); + dst += emitOutputByte(dst, dsp); + } else { - // This is [reg + dsp]" -- does the offset fit in a byte? - if (dspInByte) - { - dst += emitOutputByte(dst, code | 0x40); - dst += emitOutputByte(dst, dsp); - } - else + // This is "[reg + dsp32]" + dst += emitOutputByte(dst, code | 0x80); + dst += emitOutputLong(dst, dsp); + + if (id->idIsDspReloc()) { - dst += emitOutputByte(dst, code | 0x80); - dst += emitOutputLong(dst, dsp); - if (id->idIsDspReloc()) - { - emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); - } + emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); } } } @@ -15021,22 +14964,21 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) // This is simply "[reg]" dst += emitOutputWord(dst, code); } + else if (dspInByte) + { + // This is "[reg + dsp8]" + dst += emitOutputWord(dst, code | 0x4000); + dst += emitOutputByte(dst, dsp); + } else { - // This is [reg + dsp]" -- does the offset fit in a byte? - if (dspInByte) - { - dst += emitOutputWord(dst, code | 0x4000); - dst += emitOutputByte(dst, dsp); - } - else + // This is "[reg + dsp32]" + dst += emitOutputWord(dst, code | 0x8000); + dst += emitOutputLong(dst, dsp); + + if (id->idIsDspReloc()) { - dst += emitOutputWord(dst, code | 0x8000); - dst += emitOutputLong(dst, dsp); - if (id->idIsDspReloc()) - { - emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); - } + emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); } } } @@ -15064,62 +15006,55 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) if (EncodedBySSE38orSSE3A(ins) || (ins == INS_crc32)) { - // Emit [ebp + {2/4/8} * rgz] as [ebp + {2/4/8} * rgx + 0] - if (dspIsZero && reg != REG_EBP) + if (dspIsZero && (reg != REG_EBP)) { // The address is "[reg + {2/4/8} * rgx]" dst += emitOutputByte(dst, code | 0x04); dst += emitOutputByte(dst, regByte); } + else if (dspInByte) + { + // The address is "[reg + {2/4/8} * rgx + dsp8]" + dst += emitOutputByte(dst, code | 0x44); + dst += emitOutputByte(dst, regByte); + dst += emitOutputByte(dst, dsp); + } else { - // The address is "[reg + {2/4/8} * rgx + disp]" - if (dspInByte) - { - dst += emitOutputByte(dst, code | 0x44); - dst += emitOutputByte(dst, regByte); - dst += emitOutputByte(dst, dsp); - } - else + // The address is "[reg + {2/4/8} * rgx + dsp32]" + dst += emitOutputByte(dst, code | 0x84); + dst += emitOutputByte(dst, regByte); + dst += emitOutputLong(dst, dsp); + + if (id->idIsDspReloc()) { - dst += emitOutputByte(dst, code | 0x84); - dst += emitOutputByte(dst, regByte); - dst += emitOutputLong(dst, dsp); - if (id->idIsDspReloc()) - { - emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); - } + emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); } } } + else if (dspIsZero && (reg != REG_EBP)) + { + // The address is "[reg + {2/4/8} * rgx]" + dst += emitOutputWord(dst, code | 0x0400); + dst += emitOutputByte(dst, regByte); + } + else if (dspInByte) + { + // The address is "[reg + {2/4/8} * rgx + dsp8]" + dst += emitOutputWord(dst, code | 0x4400); + dst += emitOutputByte(dst, regByte); + dst += emitOutputByte(dst, dsp); + } else { - // Emit [ebp + {2/4/8} * rgz] as [ebp + {2/4/8} * rgx + 0] - if (dspIsZero && reg != REG_EBP) - { - // The address is "[reg + {2/4/8} * rgx]" - dst += emitOutputWord(dst, code | 0x0400); - dst += emitOutputByte(dst, regByte); - } - else + // The address is "[reg + {2/4/8} * rgx + dsp32]" + dst += emitOutputWord(dst, code | 0x8400); + dst += emitOutputByte(dst, regByte); + dst += emitOutputLong(dst, dsp); + + if (id->idIsDspReloc()) { - // The address is "[reg + {2/4/8} * rgx + disp]" - if (dspInByte) - { - dst += emitOutputWord(dst, code | 0x4400); - dst += emitOutputByte(dst, regByte); - dst += emitOutputByte(dst, dsp); - } - else - { - dst += emitOutputWord(dst, code | 0x8400); - dst += emitOutputByte(dst, regByte); - dst += emitOutputLong(dst, dsp); - if (id->idIsDspReloc()) - { - emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); - } - } + emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); } } } @@ -15160,60 +15095,55 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) if (EncodedBySSE38orSSE3A(ins) || (ins == INS_crc32)) { - if (dspIsZero && reg != REG_EBP) + if (dspIsZero && (reg != REG_EBP)) { // This is [reg+rgx]" dst += emitOutputByte(dst, code | 0x04); dst += emitOutputByte(dst, regByte); } + else if (dspInByte) + { + // This is [reg+rgx+dsp8]" + dst += emitOutputByte(dst, code | 0x44); + dst += emitOutputByte(dst, regByte); + dst += emitOutputByte(dst, dsp); + } else { - // This is [reg+rgx+dsp]" -- does the offset fit in a byte? - if (dspInByte) + // This is [reg+rgx+dsp32]" + dst += emitOutputByte(dst, code | 0x84); + dst += emitOutputByte(dst, regByte); + dst += emitOutputLong(dst, dsp); + + if (id->idIsDspReloc()) { - dst += emitOutputByte(dst, code | 0x44); - dst += emitOutputByte(dst, regByte); - dst += emitOutputByte(dst, dsp); - } - else - { - dst += emitOutputByte(dst, code | 0x84); - dst += emitOutputByte(dst, regByte); - dst += emitOutputLong(dst, dsp); - if (id->idIsDspReloc()) - { - emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); - } + emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); } } } + else if (dspIsZero && (reg != REG_EBP)) + { + // This is [reg+rgx]" + dst += emitOutputWord(dst, code | 0x0400); + dst += emitOutputByte(dst, regByte); + } + else if (dspInByte) + { + // This is [reg+rgx+dsp8]" + dst += emitOutputWord(dst, code | 0x4400); + dst += emitOutputByte(dst, regByte); + dst += emitOutputByte(dst, dsp); + } else { - if (dspIsZero && reg != REG_EBP) - { - // This is [reg+rgx]" - dst += emitOutputWord(dst, code | 0x0400); - dst += emitOutputByte(dst, regByte); - } - else + // This is [reg+rgx+dsp32]" + dst += emitOutputWord(dst, code | 0x8400); + dst += emitOutputByte(dst, regByte); + dst += emitOutputLong(dst, dsp); + + if (id->idIsDspReloc()) { - // This is [reg+rgx+dsp]" -- does the offset fit in a byte? - if (dspInByte) - { - dst += emitOutputWord(dst, code | 0x4400); - dst += emitOutputByte(dst, regByte); - dst += emitOutputByte(dst, dsp); - } - else - { - dst += emitOutputWord(dst, code | 0x8400); - dst += emitOutputByte(dst, regByte); - dst += emitOutputLong(dst, dsp); - if (id->idIsDspReloc()) - { - emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); - } - } + emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW); } } } @@ -15623,13 +15553,31 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) adr = emitComp->lvaFrameAddress(varNum, &EBPbased); dsp = adr + id->idAddr()->iiaLclVar.lvaOffset(); - // TODO-XARCH-AVX512 : working to wrap up all adjusted disp8 compression logic into the following - // function, to which the remainder of the emitter logic should handle properly. - // TODO-XARCH-AVX512 : embedded broadcast might change this - int dspAsByte = dsp; - if (TakesEvexPrefix(id) || TakesApxExtendedEvexPrefix(id)) + if (IsEvexEncodableInstruction(ins) || IsApxExtendedEvexInstruction(ins)) { - dspAsByte = int(TryEvexCompressDisp8Byte(id, ssize_t(dsp), &dspInByte)); + ssize_t compressedDsp; + + if (HasCompressedDisplacement(id)) + { + bool isCompressed = TryEvexCompressDisp8Byte(id, dsp, &compressedDsp, &dspInByte); + assert(isCompressed && dspInByte); + dsp = (int)compressedDsp; + } + else if (TakesEvexPrefix(id) && !IsBMIInstruction(ins)) + { +#if FEATURE_FIXED_OUT_ARGS + // TODO-AMD64-CQ: We should be able to accurately predict this when FEATURE_FIXED_OUT_ARGS + // is available. However, there's some nuance in how emitInsSizeSVCalcDisp does things + // compared to emitOutputSV here, so we will miss a few cases today. + // + // assert(!TryEvexCompressDisp8Byte(id, dsp, &compressedDsp, &dspInByte)); +#endif + dspInByte = false; + } + else + { + dspInByte = ((signed char)dsp == (ssize_t)dsp); + } } else { @@ -15648,7 +15596,7 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) if (dspInByte) { dst += emitOutputByte(dst, code | 0x45); - dst += emitOutputByte(dst, dspAsByte); + dst += emitOutputByte(dst, dsp); } else { @@ -15656,61 +15604,56 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) dst += emitOutputLong(dst, dsp); } } + else if (dspInByte) + { + dst += emitOutputWord(dst, code | 0x4500); + dst += emitOutputByte(dst, dsp); + } else { - if (dspInByte) - { - dst += emitOutputWord(dst, code | 0x4500); - dst += emitOutputByte(dst, dspAsByte); - } - else - { - dst += emitOutputWord(dst, code | 0x8500); - dst += emitOutputLong(dst, dsp); - } + dst += emitOutputWord(dst, code | 0x8500); + dst += emitOutputLong(dst, dsp); } } else { - #if !FEATURE_FIXED_OUT_ARGS // Adjust the offset by the amount currently pushed on the CPU stack dsp += emitCurStackLvl; -#endif - // TODO-XARCH-AVX512 : working to wrap up all adjusted disp8 compression logic into the following - // function, to which the remainder of the emitter logic should handle properly. - // TODO-XARCH-AVX512 : embedded broadcast might change this - if (TakesEvexPrefix(id) || TakesApxExtendedEvexPrefix(id)) + if (IsEvexEncodableInstruction(ins) || IsApxExtendedEvexInstruction(ins)) { - dspAsByte = int(TryEvexCompressDisp8Byte(id, ssize_t(dsp), &dspInByte)); + // We cannot reliably predict the encoding size up front so we shouldn't + // have encountered a scenario marked with compressed displacement. We + // did predict cases that could use the small encoding for VEX scenarios + + assert(!HasCompressedDisplacement(id)); + + if (!TakesEvexPrefix(id)) + { + dspInByte = ((signed char)dsp == (ssize_t)dsp); + } } else { dspInByte = ((signed char)dsp == (ssize_t)dsp); - if (dspInByte) - { - dspAsByte = dsp; - } } dspIsZero = (dsp == 0); +#endif // !FEATURE_FIXED_OUT_ARGS // Does the offset fit in a byte? if (EncodedBySSE38orSSE3A(ins) || (ins == INS_crc32)) { - if (dspInByte) + if (dspIsZero) { - if (dspIsZero) - { - dst += emitOutputByte(dst, code | 0x04); - dst += emitOutputByte(dst, 0x24); - } - else - { - dst += emitOutputByte(dst, code | 0x44); - dst += emitOutputByte(dst, 0x24); - dst += emitOutputByte(dst, dspAsByte); - } + dst += emitOutputByte(dst, code | 0x04); + dst += emitOutputByte(dst, 0x24); + } + else if (dspInByte) + { + dst += emitOutputByte(dst, code | 0x44); + dst += emitOutputByte(dst, 0x24); + dst += emitOutputByte(dst, dsp); } else { @@ -15719,28 +15662,22 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) dst += emitOutputLong(dst, dsp); } } + else if (dspIsZero) + { + dst += emitOutputWord(dst, code | 0x0400); + dst += emitOutputByte(dst, 0x24); + } + else if (dspInByte) + { + dst += emitOutputWord(dst, code | 0x4400); + dst += emitOutputByte(dst, 0x24); + dst += emitOutputByte(dst, dsp); + } else { - if (dspInByte) - { - if (dspIsZero) - { - dst += emitOutputWord(dst, code | 0x0400); - dst += emitOutputByte(dst, 0x24); - } - else - { - dst += emitOutputWord(dst, code | 0x4400); - dst += emitOutputByte(dst, 0x24); - dst += emitOutputByte(dst, dspAsByte); - } - } - else - { - dst += emitOutputWord(dst, code | 0x8400); - dst += emitOutputByte(dst, 0x24); - dst += emitOutputLong(dst, dsp); - } + dst += emitOutputWord(dst, code | 0x8400); + dst += emitOutputByte(dst, 0x24); + dst += emitOutputLong(dst, dsp); } } @@ -16152,7 +16089,7 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) addr = emitConsBlock + doff; #ifdef DEBUG - int byteSize = EA_SIZE_IN_BYTES(emitGetMemOpSize(id)); + int byteSize = EA_SIZE_IN_BYTES(emitGetMemOpSize(id, /*ignoreEmbeddedBroadcast*/ false)); // Check that the offset is properly aligned (i.e. the ddd in [ddd]) // When SMALL_CODE is set, we only expect 4-byte alignment, otherwise @@ -16540,20 +16477,22 @@ BYTE* emitter::emitOutputR(BYTE* dst, instrDesc* id) case INS_setge: case INS_setle: case INS_setg: - + { assert(id->idGCref() == GCT_NONE); assert(size == EA_1BYTE); - code = insEncodeMRreg(id, reg, EA_1BYTE, insCodeMR(ins)); + code = insCodeMR(ins); if (TakesRex2Prefix(id)) { code = AddRex2Prefix(ins, code); + code = insEncodeMRreg(id, reg, EA_1BYTE, code); dst += emitOutputRexOrSimdPrefixIfNeeded(ins, dst, code); dst += emitOutputWord(dst, code & 0x0000FFFF); } else { + code = insEncodeMRreg(id, reg, EA_1BYTE, code); // Output the REX prefix dst += emitOutputRexOrSimdPrefixIfNeeded(ins, dst, code); // We expect this to always be a 'big' opcode @@ -16563,6 +16502,37 @@ BYTE* emitter::emitOutputR(BYTE* dst, instrDesc* id) dst += emitOutputWord(dst, code & 0x0000FFFF); } break; + } + +#ifdef TARGET_AMD64 + case INS_seto_apx: + case INS_setno_apx: + case INS_setb_apx: + case INS_setae_apx: + case INS_sete_apx: + case INS_setne_apx: + case INS_setbe_apx: + case INS_seta_apx: + case INS_sets_apx: + case INS_setns_apx: + case INS_setp_apx: + case INS_setnp_apx: + case INS_setl_apx: + case INS_setge_apx: + case INS_setle_apx: + case INS_setg_apx: + { + assert(TakesApxExtendedEvexPrefix(id)); + assert(size == EA_1BYTE); + + code = insCodeMR(ins); + code = AddEvexPrefix(id, code, size); + code = insEncodeMRreg(id, reg, EA_1BYTE, code); + dst += emitOutputRexOrSimdPrefixIfNeeded(ins, dst, code); + dst += emitOutputWord(dst, code & 0x0000FFFF); + break; + } +#endif case INS_mulEAX: case INS_imulEAX: @@ -16914,7 +16884,7 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id) } unsigned regCode; - if (!id->idIsEvexNdContextSet() || !IsApxNDDEncodableInstruction(ins)) + if (!IsApxNddEncodableInstruction(ins) || !id->idIsEvexNdContextSet()) { regCode = insEncodeReg345(id, regFor345Bits, size, &code); regCode |= insEncodeReg012(id, regFor012Bits, size, &code); @@ -16986,7 +16956,7 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id) dst += emitOutputByte(dst, (code >> 8) & 0xFF); dst += emitOutputByte(dst, (0xC0 | regCode)); } - else if (IsApxNDDEncodableInstruction(ins) && id->idIsEvexNdContextSet()) + else if (IsApxNddEncodableInstruction(ins) && id->idIsEvexNdContextSet()) { dst += emitOutputByte(dst, (code & 0xFF)); dst += emitOutputByte(dst, (0xC0 | regCode | (code >> 8))); @@ -17941,6 +17911,7 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i) idAmd->idCodeSize(sz); code = insCodeRM(ins); + code = AddX86PrefixIfNeeded(id, code, id->idOpSize()); code |= (insEncodeReg345(id, id->idReg1(), EA_PTRSIZE, &code) << 8); dst = emitOutputAM(dst, idAmd, code, nullptr); @@ -18026,7 +17997,7 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i) // Return Value: // size in bytes. // -ssize_t emitter::GetInputSizeInBytes(instrDesc* id) const +ssize_t emitter::GetInputSizeInBytes(const instrDesc* id) const { assert((unsigned)id->idIns() < ArrLen(CodeGenInterface::instInfo)); insFlags inputSize = static_cast((CodeGenInterface::instInfo[id->idIns()] & Input_Mask)); @@ -18052,53 +18023,73 @@ ssize_t emitter::GetInputSizeInBytes(instrDesc* id) const // TryEvexCompressDisp8Byte: Do we do compressed displacement encoding for EVEX. // // Arguments: -// id -- Instruction descriptor. -// dsp -- Displacemnt. -// dspInByte[out] - `true` if compressed displacement +// id -- Instruction descriptor. +// dsp -- displacement to try and compress +// compressedDsp -- [out] the compressed displacement on success; otherwise, dsp +// fitsInByte -- [out] true if the displacement fits in a byte; otherwise, false // // Return Value: -// compressed displacement value if dspInByte === TRUE. -// Original dsp otherwise. +// True if the displacement was compressed; otherwise, false // -ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspInByte) +bool emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, ssize_t* compressedDsp, bool* fitsInByte) const { - assert(TakesEvexPrefix(id) || TakesApxExtendedEvexPrefix(id)); + instruction ins = id->idIns(); - if (!hasTupleTypeInfo(id->idIns())) + assert(IsEvexEncodableInstruction(ins) || IsApxExtendedEvexInstruction(ins)); + assert(id->idHasMem() && !id->idHasMemGen()); + assert(!id->idIsDspReloc()); + assert(compressedDsp != nullptr); + assert(fitsInByte != nullptr); + + *compressedDsp = dsp; + *fitsInByte = (static_cast(dsp) == dsp); + + if (!hasTupleTypeInfo(ins)) { // After APX, some instructions with APX features will be promoted // to APX-EVEX, we will re-use the existing displacement emitting // path, but for those instructions with no tuple information, // APX-EVEX treat the scaling factor to be 1 constantly. - instruction ins = id->idIns(); - assert(IsApxExtendedEvexInstruction(ins) || IsBMIInstruction(ins)); - *dspInByte = ((signed char)dsp == (ssize_t)dsp); - return dsp; - } - insTupleType tt = insTupleTypeInfo(id->idIns()); - assert(hasTupleTypeInfo(id->idIns())); + assert(IsApxExtendedEvexInstruction(ins) || IsBMIInstruction(ins) || IsKMOVInstruction(ins)); + assert(*compressedDsp == dsp); + + return *fitsInByte; + } - // if dsp is 0, no need for all of this - if (dsp == 0) + if (*fitsInByte) { - *dspInByte = true; - return dsp; + if (!TakesEvexPrefix(id)) + { + // We already fit into a byte and do not otherwise require the EVEX prefix + // which means we can use the VEX encoding instead and be even smaller. + + assert(*compressedDsp == dsp); + return false; + } } + else + { + ssize_t compressedTest = dsp / 64; - // Only handling non-broadcast forms right now - ssize_t vectorLength = EA_SIZE_IN_BYTES(id->idOpSize()); + if (static_cast(compressedTest) != compressedTest) + { + // We are larger than the maximum possible compressed displacement + assert(*compressedDsp == dsp); + return false; + } + } - ssize_t inputSize = GetInputSizeInBytes(id); + insTupleType tt = insTupleTypeInfo(ins); + ssize_t vectorLength = EA_SIZE_IN_BYTES(id->idOpSize()); + ssize_t inputSize = GetInputSizeInBytes(id); ssize_t disp8Compression = 1; if ((tt & INS_TT_MEM128) != 0) { // These instructions can be one of two tuple types, so we need to find the right one - - instruction ins = id->idIns(); - insFormat insFmt = id->idInsFmt(); + insFormat insFmt = id->idInsFmt(); if ((tt & INS_TT_FULL) != 0) { @@ -18137,13 +18128,13 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI } } + bool isEmbBroadcast = HasEmbeddedBroadcast(id); + switch (tt) { case INS_TT_FULL: { - instruction ins = id->idIns(); - assert((inputSize == 4 || inputSize == 8) || IsAVXVNNIINTInstruction(ins)); - if (HasEmbeddedBroadcast(id)) + if (isEmbBroadcast) { // N = input size in bytes disp8Compression = inputSize; @@ -18159,7 +18150,7 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI case INS_TT_HALF: { assert(inputSize == 4); - if (HasEmbeddedBroadcast(id)) + if (isEmbBroadcast) { // N = input size in bytes disp8Compression = inputSize; @@ -18175,12 +18166,14 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI case INS_TT_FULL_MEM: { // N = vector length in bytes + assert(!isEmbBroadcast); disp8Compression = vectorLength; break; } case INS_TT_TUPLE1_SCALAR: { + assert(!isEmbBroadcast); disp8Compression = inputSize; break; } @@ -18188,7 +18181,8 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI case INS_TT_TUPLE1_FIXED: { // N = input size in bytes, 32bit and 64bit only - assert(inputSize == 4 || inputSize == 8); + assert(!isEmbBroadcast); + assert((inputSize == 4) || (inputSize == 8)); disp8Compression = inputSize; break; } @@ -18196,7 +18190,8 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI case INS_TT_TUPLE2: { // N = input size in bytes * 2, 32bit and 64bit for 256 bit and 512 bit only - assert((inputSize == 4) || (inputSize == 8 && vectorLength >= 32)); + assert(!isEmbBroadcast); + assert((inputSize == 4) || ((inputSize == 8) && (vectorLength >= 32))); disp8Compression = inputSize * 2; break; } @@ -18204,7 +18199,8 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI case INS_TT_TUPLE4: { // N = input size in bytes * 4, 32bit for 256 bit and 512 bit, 64bit for 512 bit - assert((inputSize == 4 && vectorLength >= 32) || (inputSize == 8 && vectorLength >= 64)); + assert(!isEmbBroadcast); + assert(((inputSize == 4) && (vectorLength >= 32)) || ((inputSize == 8) && (vectorLength >= 64))); disp8Compression = inputSize * 4; break; } @@ -18212,7 +18208,8 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI case INS_TT_TUPLE8: { // N = input size in bytes * 8, 32bit for 512 only - assert((inputSize == 4 && vectorLength >= 64)); + assert(!isEmbBroadcast); + assert((inputSize == 4) && (vectorLength >= 64)); disp8Compression = inputSize * 8; break; } @@ -18220,6 +18217,7 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI case INS_TT_HALF_MEM: { // N = vector length in bytes / 2 + assert(!isEmbBroadcast); disp8Compression = vectorLength / 2; break; } @@ -18227,6 +18225,7 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI case INS_TT_QUARTER_MEM: { // N = vector length in bytes / 4 + assert(!isEmbBroadcast); disp8Compression = vectorLength / 4; break; } @@ -18234,6 +18233,7 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI case INS_TT_EIGHTH_MEM: { // N = vector length in bytes / 8 + assert(!isEmbBroadcast); disp8Compression = vectorLength / 8; break; } @@ -18241,6 +18241,7 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI case INS_TT_MEM128: { // N = 16 + assert(!isEmbBroadcast); disp8Compression = 16; break; } @@ -18248,6 +18249,7 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI case INS_TT_MOVDDUP: { // N = vector length in bytes / 2 + assert(!isEmbBroadcast); disp8Compression = (vectorLength == 16) ? (vectorLength / 2) : vectorLength; break; } @@ -18259,23 +18261,26 @@ ssize_t emitter::TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspI } // If we can evenly divide dsp by the disp8Compression, we can attempt to use it in a disp8 byte form - if (dsp % disp8Compression != 0) + if ((dsp % disp8Compression) != 0) { - *dspInByte = false; - return dsp; + assert(*compressedDsp == dsp); + *fitsInByte = false; + return false; } - ssize_t compressedDsp = dsp / disp8Compression; + ssize_t compressedDisp = dsp / disp8Compression; - *dspInByte = ((signed char)compressedDsp == (ssize_t)compressedDsp); - if (*dspInByte) - { - return compressedDsp; - } - else + if (static_cast(compressedDisp) != compressedDisp) { - return dsp; + assert(*compressedDsp == dsp); + *fitsInByte = false; + return false; } + + *compressedDsp = compressedDisp; + *fitsInByte = true; + + return true; } /***************************************************************************** @@ -19183,7 +19188,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { code = insCodeRM(ins); - if (id->idIsEvexNdContextSet() && TakesApxExtendedEvexPrefix(id)) + if (IsApxNddCompatibleInstruction(ins) && id->idIsEvexNdContextSet()) { // TODO-XArch-APX: // I'm not sure why instructions on this path can be with instruction @@ -19469,7 +19474,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { assert(IsVexOrEvexEncodableInstruction(ins) || IsApxExtendedEvexInstruction(ins)); - if (id->idIsEvexNdContextSet() && IsApxNDDEncodableInstruction(ins)) + if (IsApxNddEncodableInstruction(ins) && id->idIsEvexNdContextSet()) { // EVEX.vvvv has different semantic for APX-EVEX NDD instructions. code = insCodeRM(ins); @@ -20738,6 +20743,24 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_setge: case INS_setle: case INS_setg: +#ifdef TARGET_AMD64 + case INS_seto_apx: + case INS_setno_apx: + case INS_setb_apx: + case INS_setae_apx: + case INS_sete_apx: + case INS_setne_apx: + case INS_setbe_apx: + case INS_seta_apx: + case INS_sets_apx: + case INS_setns_apx: + case INS_setp_apx: + case INS_setnp_apx: + case INS_setl_apx: + case INS_setge_apx: + case INS_setle_apx: + case INS_setg_apx: +#endif { result.insLatency += PERFSCORE_LATENCY_1C; if (insFmt == IF_RRD) diff --git a/src/coreclr/jit/emitxarch.h b/src/coreclr/jit/emitxarch.h index 2074cb5da3ff70..126d1a67a3593b 100644 --- a/src/coreclr/jit/emitxarch.h +++ b/src/coreclr/jit/emitxarch.h @@ -132,13 +132,14 @@ static bool IsApxOnlyInstruction(instruction ins); static regNumber getBmiRegNumber(instruction ins); static regNumber getSseShiftRegNumber(instruction ins); static bool HasRex2Encoding(instruction ins); -static bool HasApxNdd(instruction ins); -static bool HasApxNf(instruction ins); +static bool IsApxNddCompatibleInstruction(instruction ins); +static bool IsApxNfCompatibleInstruction(instruction ins); +static bool IsApxZuCompatibleInstruction(instruction ins); bool IsVexEncodableInstruction(instruction ins) const; bool IsEvexEncodableInstruction(instruction ins) const; bool IsRex2EncodableInstruction(instruction ins) const; -bool IsApxNDDEncodableInstruction(instruction ins) const; -bool IsApxNFEncodableInstruction(instruction ins) const; +bool IsApxNddEncodableInstruction(instruction ins) const; +bool IsApxNfEncodableInstruction(instruction ins) const; bool IsApxExtendedEvexInstruction(instruction ins) const; bool IsShiftInstruction(instruction ins) const; bool IsLegacyMap1(code_t code) const; @@ -266,7 +267,7 @@ bool IsExtendedGPReg(regNumber reg) const; // ins - The instruction to check. // // Returns: -// `true` if Evex encoding requires KMAsk support. +// `true` if Evex encoding requires KMask support. // bool HasKMaskRegisterDest(instruction ins) const { @@ -497,17 +498,28 @@ code_t AddX86PrefixIfNeededAndNotPresent(const instrDesc* id, code_t code, emitA // instOptions - emit options void SetEvexBroadcastIfNeeded(instrDesc* id, insOpts instOptions) { - if ((instOptions & INS_OPTS_EVEX_b_MASK) == INS_OPTS_EVEX_eb_er_rd) + assert(id->idHasMem()); + + if ((instOptions & INS_OPTS_EVEX_eb) != INS_OPTS_NONE) { assert(UseEvexEncoding()); - id->idSetEvexbContext(instOptions); - } - else - { - assert((instOptions & INS_OPTS_EVEX_b_MASK) == 0); + id->idSetEvexBroadcastBit(); } } +//------------------------------------------------------------------------ +// SetEvexCompressedDisplacement: set compressed displacement +// +// Arguments: +// id - instruction descriptor +void SetEvexCompressedDisplacement(instrDesc* id) +{ + assert(id->idHasMem()); + + assert(UseEvexEncoding()); + id->idSetEvexCompressedDisplacementBit(); +} + //------------------------------------------------------------------------ // SetEvexEmbMaskIfNeeded: set embedded mask if needed. // @@ -530,6 +542,25 @@ void SetEvexEmbMaskIfNeeded(instrDesc* id, insOpts instOptions) } } +//------------------------------------------------------------------------ +// SetEvexEmbRoundIfNeeded: set embedded round if needed. +// +// Arguments: +// id - instruction descriptor +// instOptions - emit options +// +void SetEvexEmbRoundIfNeeded(instrDesc* id, insOpts instOptions) +{ + assert(!id->idHasMem()); + + if ((instOptions & INS_OPTS_EVEX_b_MASK) != INS_OPTS_NONE) + { + // if EVEX.b needs to be set in this path, then it should be embedded rounding. + assert(UseEvexEncoding()); + id->idSetEvexbContext(instOptions); + } +} + //------------------------------------------------------------------------ // SetEvexNdIfNeeded: set NDD form - new data destination if needed. // @@ -542,7 +573,7 @@ void SetEvexNdIfNeeded(instrDesc* id, insOpts instOptions) if ((instOptions & INS_OPTS_EVEX_nd_MASK) != 0) { assert(UsePromotedEVEXEncoding()); - assert(IsApxNDDEncodableInstruction(id->idIns())); + assert(IsApxNddEncodableInstruction(id->idIns())); id->idSetEvexNdContext(); } else @@ -563,7 +594,7 @@ void SetEvexNfIfNeeded(instrDesc* id, insOpts instOptions) if ((instOptions & INS_OPTS_EVEX_nf_MASK) != 0) { assert(UsePromotedEVEXEncoding()); - assert(IsApxNFEncodableInstruction(id->idIns())); + assert(IsApxNfEncodableInstruction(id->idIns())); id->idSetEvexNfContext(); } else @@ -572,6 +603,33 @@ void SetEvexNfIfNeeded(instrDesc* id, insOpts instOptions) } } +//------------------------------------------------------------------------ +// SetEvexZuIfNeeded: set Evex.zu on instrDesc +// +// Arguments: +// id - instruction descriptor +// instOptions - emit options +// +void SetEvexZuIfNeeded(instrDesc* id, insOpts instOptions) +{ + if ((instOptions & INS_OPTS_EVEX_zu_MASK) != 0) + { + assert(UsePromotedEVEXEncoding()); + instruction ins = id->idIns(); +#ifdef TARGET_AMD64 + assert(IsApxZuCompatibleInstruction(ins)); +#else + // This method is not expected to be used on 32-bit systems. + unreached(); +#endif + id->idSetEvexZuContext(); + } + else + { + assert((instOptions & INS_OPTS_EVEX_zu_MASK) == 0); + } +} + //------------------------------------------------------------------------ // SetApxPpxIfNeeded: set APX.ppx on instrDesc // @@ -654,7 +712,7 @@ bool hasVexOrEvexPrefix(code_t code) return (hasVexPrefix(code) || hasEvexPrefix(code)); } -ssize_t TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, bool* dspInByte); +bool TryEvexCompressDisp8Byte(instrDesc* id, ssize_t dsp, ssize_t* compressedDsp, bool* fitsInByte) const; //------------------------------------------------------------------------ // codeEvexMigrationCheck: Temporary check to use when adding EVEX codepaths @@ -672,7 +730,7 @@ bool codeEvexMigrationCheck(code_t code) return hasEvexPrefix(code); } -ssize_t GetInputSizeInBytes(instrDesc* id) const; +ssize_t GetInputSizeInBytes(const instrDesc* id) const; bool containsAVXInstruction = false; bool ContainsAVX() @@ -1289,23 +1347,39 @@ inline bool emitIsUncondJump(instrDesc* jmp) // inline bool HasEmbeddedBroadcast(const instrDesc* id) const { - return id->idIsEvexbContextSet(); + assert(id->idHasMem()); + return (id->idGetEvexbContext() & INS_OPTS_EVEX_eb) != 0; } //------------------------------------------------------------------------ -// HasEmbeddedBroadcast: Do we consider embedded broadcast while encoding. +// HasEmbeddedMask: Do we consider embedded masking while encoding. // // Arguments: // id - Instruction descriptor. // // Returns: -// `true` if the instruction does embedded broadcast. +// `true` if the instruction does embedded masking. // inline bool HasEmbeddedMask(const instrDesc* id) const { return id->idIsEvexAaaContextSet() || id->idIsEvexZContextSet(); } +//------------------------------------------------------------------------ +// HasCompressedDisplacement: Do we consider compressed displacement while encoding. +// +// Arguments: +// id - Instruction descriptor. +// +// Returns: +// `true` if the instruction does compressed displacement. +// +inline bool HasCompressedDisplacement(const instrDesc* id) const +{ + assert(id->idHasMem()); + return (id->idGetEvexbContext() & INS_OPTS_EVEX_cd) != 0; +} + inline bool HasHighSIMDReg(const instrDesc* id) const; inline bool HasExtendedGPReg(const instrDesc* id) const; diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index 4fa17a9c6c8207..1b58b09a5d1b76 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -162,7 +162,7 @@ void Compiler::fgConvertBBToThrowBB(BasicBlock* block) // Scrub this block from the pred lists of any successors bool profileInconsistent = false; - for (BasicBlock* const succBlock : block->Succs(this)) + for (BasicBlock* const succBlock : block->Succs()) { FlowEdge* const succEdge = fgRemoveAllRefPreds(succBlock, block); @@ -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++) - { - FlowEdge* succEdge = swtDesc->bbsDstTab[i]; - assert(succEdge != nullptr); - - 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) + for (unsigned i = 0; i < swtDesc->GetSuccCount(); i++) { - SwitchUniqueSuccSet uniqueSuccSet; + FlowEdge* succEdge = swtDesc->GetSucc(i); + assert(succEdge->getSourceBlock() == oldSwitchBlock); - // 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, @@ -1301,7 +1245,9 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed case NI_SRCS_UNSAFE_AreSame: case NI_SRCS_UNSAFE_ByteOffset: case NI_SRCS_UNSAFE_IsAddressGreaterThan: + case NI_SRCS_UNSAFE_IsAddressGreaterThanOrEqualTo: case NI_SRCS_UNSAFE_IsAddressLessThan: + case NI_SRCS_UNSAFE_IsAddressLessThanOrEqualTo: case NI_SRCS_UNSAFE_IsNullRef: case NI_SRCS_UNSAFE_Subtract: case NI_SRCS_UNSAFE_SubtractByteOffset: @@ -1316,7 +1262,9 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed { case NI_SRCS_UNSAFE_AreSame: case NI_SRCS_UNSAFE_IsAddressGreaterThan: + case NI_SRCS_UNSAFE_IsAddressGreaterThanOrEqualTo: case NI_SRCS_UNSAFE_IsAddressLessThan: + case NI_SRCS_UNSAFE_IsAddressLessThanOrEqualTo: case NI_SRCS_UNSAFE_IsNullRef: { fgObserveInlineConstants(opcode, pushedStack, isInlining); @@ -2310,11 +2258,10 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed // generate for this ldfld, and we require that we // won't need the address of this local at all - const bool notStruct = !varTypeIsStruct(lvaGetDesc(varNum)); const bool notLastInstr = (codeAddr < codeEndp - sz); const bool notDebugCode = !opts.compDbgCode; - if (notStruct && notLastInstr && notDebugCode && impILConsumesAddr(codeAddr + sz)) + if (notLastInstr && notDebugCode && impILConsumesAddr(codeAddr + sz, codeEndp)) { // We can skip the addrtaken, as next IL instruction consumes // the address. @@ -2877,26 +2824,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); + } + + curBBdesc->GetSwitchTargets()->SetSuccs(succs, numUnique); - /* Default case of CEE_SWITCH (next block), is at end of jumpTab[] */ + /* Default case of CEE_SWITCH (next block), is at end of cases[] */ - noway_assert(curBBdesc->NextIs((*(jumpPtr - 1))->getDestinationBlock())); + noway_assert(curBBdesc->NextIs(cases[numCases - 1]->getDestinationBlock())); break; } @@ -3055,56 +3010,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 */ @@ -3171,6 +3112,7 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed case CEE_CALLVIRT: case CEE_CALLI: { + opts.callInstrCount++; if (compIsForInlining() || // Ignore tail call in the inlinee. Period. (!tailCall && !compTailCallStress()) // A new BB with BBJ_RETURN would have been created @@ -3289,6 +3231,7 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed // These ctrl-flow opcodes don't need any special handling case CEE_NEWOBJ: // CTRL_CALL + opts.callInstrCount++; break; // what's left are forgotten instructions @@ -3420,7 +3363,7 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed fgLastBB = curBBdesc; - DBEXEC(verbose, curBBdesc->dspBlockHeader(this, false, false, false)); + DBEXEC(verbose, curBBdesc->dspBlockHeader(false, false, false)); /* Remember where the next BB will start */ @@ -3798,24 +3741,22 @@ void Compiler::fgFindBasicBlocks() } else { - HBtab->ebdTyp = clause.ClassToken; - - /* Set bbCatchTyp as appropriate */ - + // Set ebdTyp and bbCatchTyp as appropriate + // if (clause.Flags & CORINFO_EH_CLAUSE_FINALLY) { hndBegBB->bbCatchTyp = BBCT_FINALLY; + HBtab->ebdTyp = 0; } else { if (clause.Flags & CORINFO_EH_CLAUSE_FAULT) { hndBegBB->bbCatchTyp = BBCT_FAULT; + HBtab->ebdTyp = 0; } else { - hndBegBB->bbCatchTyp = clause.ClassToken; - // These values should be non-zero value that will // not collide with real tokens for bbCatchTyp if (clause.ClassToken == 0) @@ -3823,6 +3764,9 @@ void Compiler::fgFindBasicBlocks() BADCODE("Exception catch type is Null"); } + hndBegBB->bbCatchTyp = clause.ClassToken; + HBtab->ebdTyp = clause.ClassToken; + noway_assert(clause.ClassToken != BBCT_FAULT); noway_assert(clause.ClassToken != BBCT_FINALLY); noway_assert(clause.ClassToken != BBCT_FILTER); @@ -4239,7 +4183,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); } @@ -5275,51 +5219,6 @@ void Compiler::fgPrepareCallFinallyRetForRemoval(BasicBlock* block) block->SetKind(BBJ_ALWAYS); } -/***************************************************************************** - * - * Is the BasicBlock bJump a forward branch? - * Optionally bSrc can be supplied to indicate that - * bJump must be forward with respect to bSrc - */ -bool Compiler::fgIsForwardBranch(BasicBlock* bJump, BasicBlock* bDest, BasicBlock* bSrc /* = NULL */) -{ - assert((bJump->KindIs(BBJ_ALWAYS, BBJ_CALLFINALLYRET) && bJump->TargetIs(bDest)) || - (bJump->KindIs(BBJ_COND) && bJump->TrueTargetIs(bDest))); - - bool result = false; - BasicBlock* bTemp = (bSrc == nullptr) ? bJump : bSrc; - - while (true) - { - bTemp = bTemp->Next(); - - if (bTemp == nullptr) - { - break; - } - - if (bTemp == bDest) - { - result = true; - break; - } - } - - return result; -} - -/***************************************************************************** - * - * Returns true if it is allowable (based upon the EH regions) - * to place block bAfter immediately after bBefore. It is allowable - * if the 'bBefore' and 'bAfter' blocks are in the exact same EH region. - */ - -bool Compiler::fgEhAllowsMoveBlock(BasicBlock* bBefore, BasicBlock* bAfter) -{ - return BasicBlock::sameEHRegion(bBefore, bAfter); -} - /***************************************************************************** * * Function called to move the range of blocks [bStart .. bEnd]. diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp index 50145f04b32b81..ca6a2a7eb223cb 100644 --- a/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/coreclr/jit/fgdiagnostic.cpp @@ -828,7 +828,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase, PhasePosition pos) const bool isTryEntryBlock = bbIsTryBeg(block); const bool isFuncletEntryBlock = fgFuncletsCreated && bbIsFuncletBeg(block); - if (isTryEntryBlock || isFuncletEntryBlock || block->HasAnyFlag(BBF_RUN_RARELY | BBF_LOOP_ALIGN)) + if (isTryEntryBlock || isFuncletEntryBlock || block->HasFlag(BBF_LOOP_ALIGN)) { // Display a very few, useful, block flags fprintf(fgxFile, " ["); @@ -840,10 +840,6 @@ bool Compiler::fgDumpFlowGraph(Phases phase, PhasePosition pos) { fprintf(fgxFile, "F"); } - if (block->HasFlag(BBF_RUN_RARELY)) - { - fprintf(fgxFile, "R"); - } if (block->HasFlag(BBF_LOOP_ALIGN)) { fprintf(fgxFile, "A"); @@ -1068,7 +1064,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 +1974,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 +1984,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 +2033,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]"); @@ -2417,7 +2410,7 @@ void Compiler::fgDumpStmtTree(const BasicBlock* block, Statement* stmt) void Compiler::fgDumpBlock(BasicBlock* block) { printf("\n------------ "); - block->dspBlockHeader(this); + block->dspBlockHeader(); if (fgSsaValid) { @@ -2786,7 +2779,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 +2963,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)) - { - 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 + // Check that all the successors have the current traversal stamp. + for (BasicBlock* const succBlock : block->Succs()) { - 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 @@ -3164,16 +3129,6 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */, bool checkBBRef } } } - - /* Check if BBF_RUN_RARELY is set that we have bbWeight of zero */ - if (block->isRunRarely()) - { - assert(block->bbWeight == BB_ZERO_WEIGHT); - } - else - { - assert(block->bbWeight > BB_ZERO_WEIGHT); - } } assert(fgBBcount == numBlocks); @@ -3971,31 +3926,30 @@ 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)) + // Switch blocks with dominant cases must have profile-derived weights. + if (block->GetSwitchTargets()->HasDominantCase()) { - // 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)); - } + assert(block->hasProfileWeight()); + } + + // 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++) + { + 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)); } } } @@ -4326,61 +4280,58 @@ class SsaCheckVisitor : public GenTreeVisitor void ProcessDefs(GenTree* tree) { - GenTreeLclVarCommon* lclNode; - bool isFullDef = false; - ssize_t offset = 0; - unsigned storeSize = 0; - bool definesLocal = tree->DefinesLocal(m_compiler, &lclNode, &isFullDef, &offset, &storeSize); - - if (!definesLocal) - { - return; - } - - const bool isUse = (lclNode->gtFlags & GTF_VAR_USEASG) != 0; - unsigned const lclNum = lclNode->GetLclNum(); - LclVarDsc* const varDsc = m_compiler->lvaGetDesc(lclNum); + auto visitDef = [=](const LocalDef& def) { + const bool isUse = (def.Def->gtFlags & GTF_VAR_USEASG) != 0; + unsigned const lclNum = def.Def->GetLclNum(); + LclVarDsc* const varDsc = m_compiler->lvaGetDesc(lclNum); - assert(!(isFullDef && isUse)); + assert(!(def.IsEntire && isUse)); - if (lclNode->HasCompositeSsaName()) - { - for (unsigned index = 0; index < varDsc->lvFieldCnt; index++) + if (def.Def->HasCompositeSsaName()) { - unsigned const fieldLclNum = varDsc->lvFieldLclStart + index; - LclVarDsc* const fieldVarDsc = m_compiler->lvaGetDesc(fieldLclNum); - unsigned const fieldSsaNum = lclNode->GetSsaNum(m_compiler, index); - - ssize_t fieldStoreOffset; - unsigned fieldStoreSize; - if (m_compiler->gtStoreDefinesField(fieldVarDsc, offset, storeSize, &fieldStoreOffset, &fieldStoreSize)) + for (unsigned index = 0; index < varDsc->lvFieldCnt; index++) { - ProcessDef(lclNode, fieldLclNum, fieldSsaNum); - - if (!ValueNumStore::LoadStoreIsEntire(genTypeSize(fieldVarDsc), fieldStoreOffset, fieldStoreSize)) + unsigned const fieldLclNum = varDsc->lvFieldLclStart + index; + LclVarDsc* const fieldVarDsc = m_compiler->lvaGetDesc(fieldLclNum); + unsigned const fieldSsaNum = def.Def->GetSsaNum(m_compiler, index); + + ssize_t fieldStoreOffset; + unsigned fieldStoreSize; + if (m_compiler->gtStoreDefinesField(fieldVarDsc, def.Offset, def.Size, &fieldStoreOffset, + &fieldStoreSize)) { - assert(isUse); - unsigned const fieldUseSsaNum = fieldVarDsc->GetPerSsaData(fieldSsaNum)->GetUseDefSsaNum(); - ProcessUse(lclNode, fieldLclNum, fieldUseSsaNum); + ProcessDef(def.Def, fieldLclNum, fieldSsaNum); + + if (!ValueNumStore::LoadStoreIsEntire(genTypeSize(fieldVarDsc), fieldStoreOffset, + fieldStoreSize)) + { + assert(isUse); + unsigned const fieldUseSsaNum = fieldVarDsc->GetPerSsaData(fieldSsaNum)->GetUseDefSsaNum(); + ProcessUse(def.Def, fieldLclNum, fieldUseSsaNum); + } } } } - } - else - { - unsigned const ssaNum = lclNode->GetSsaNum(); - ProcessDef(lclNode, lclNum, ssaNum); - - if (isUse) + else { - unsigned useSsaNum = SsaConfig::RESERVED_SSA_NUM; - if (ssaNum != SsaConfig::RESERVED_SSA_NUM) + unsigned const ssaNum = def.Def->GetSsaNum(); + ProcessDef(def.Def, lclNum, ssaNum); + + if (isUse) { - useSsaNum = varDsc->GetPerSsaData(ssaNum)->GetUseDefSsaNum(); + unsigned useSsaNum = SsaConfig::RESERVED_SSA_NUM; + if (ssaNum != SsaConfig::RESERVED_SSA_NUM) + { + useSsaNum = varDsc->GetPerSsaData(ssaNum)->GetUseDefSsaNum(); + } + ProcessUse(def.Def, lclNum, useSsaNum); } - ProcessUse(lclNode, lclNum, useSsaNum); } - } + + return GenTree::VisitResult::Continue; + }; + + tree->VisitLocalDefs(m_compiler, visitDef); } void ProcessUse(GenTreeLclVarCommon* tree, unsigned lclNum, unsigned ssaNum) diff --git a/src/coreclr/jit/fgehopt.cpp b/src/coreclr/jit/fgehopt.cpp index 084afc5846813d..dfd8fa5e973570 100644 --- a/src/coreclr/jit/fgehopt.cpp +++ b/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); } } @@ -2505,7 +2505,7 @@ BasicBlock* Compiler::fgCloneTryRegion(BasicBlock* tryEntry, CloneTryInfo& info, // // We need to clone to the entire try region plus any // enclosed regions and any enclosing mutual protect regions, - // plus all the the associated handlers and filters and any + // plus all the associated handlers and filters and any // regions they enclose, plus any callfinallies that follow. // // This is necessary because try regions can't have multiple entries, or diff --git a/src/coreclr/jit/fgflow.cpp b/src/coreclr/jit/fgflow.cpp index f7a055f4a76e57..c22bde11ea5955 100644 --- a/src/coreclr/jit/fgflow.cpp +++ b/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/coreclr/jit/fginline.cpp b/src/coreclr/jit/fginline.cpp index eb973be0434e9b..8a58dcbe813169 100644 --- a/src/coreclr/jit/fginline.cpp +++ b/src/coreclr/jit/fginline.cpp @@ -1100,7 +1100,7 @@ void Compiler::fgMorphCallInlineHelper(GenTreeCall* call, InlineResult* result, } #endif // defined(DEBUG) - if (lvaCount >= MAX_LV_NUM_COUNT_FOR_INLINING) + if (lvaHaveManyLocals(0.9f)) { // For now, attributing this to call site, though it's really // more of a budget issue (lvaCount currently includes all @@ -1591,8 +1591,8 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo) noway_assert((inlineeBlockFlags & BBF_HAS_JMP) == 0); noway_assert((inlineeBlockFlags & BBF_KEEP_BBJ_ALWAYS) == 0); - // Todo: we may want to exclude other flags here. - iciBlock->SetFlags(inlineeBlockFlags & ~BBF_RUN_RARELY); + // Todo: we may want to exclude some flags here. + iciBlock->SetFlags(inlineeBlockFlags); #ifdef DEBUG if (verbose) @@ -2266,7 +2266,7 @@ Statement* Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo) GenTree* thisOp = impInlineFetchArg(inlArgInfo[0], lclVarInfo[0]); if (fgAddrCouldBeNull(thisOp)) { - nullcheck = gtNewNullCheck(thisOp, block); + nullcheck = gtNewNullCheck(thisOp); // The NULL-check statement will be inserted to the statement list after those statements // that assign arguments to temps and before the actual body of the inlinee method. } diff --git a/src/coreclr/jit/fgopt.cpp b/src/coreclr/jit/fgopt.cpp index 9b63fb63cfd5ee..9120da5926735e 100644 --- a/src/coreclr/jit/fgopt.cpp +++ b/src/coreclr/jit/fgopt.cpp @@ -353,7 +353,7 @@ PhaseStatus Compiler::fgPostImportationCleanup() // When we alter flow in the importer branch opts, we should be able to make // suitable updates there for blocks that we plan to keep. // - for (BasicBlock* succ : cur->Succs(this)) + for (BasicBlock* succ : cur->Succs()) { fgRemoveAllRefPreds(succ, cur); } @@ -491,9 +491,6 @@ PhaseStatus Compiler::fgPostImportationCleanup() // this would be problematic as we don't have enough context to redirect // all the incoming edges, but we know oldTryEntry is unreachable. // So there are no incoming edges to worry about. - // - assert(!tryEntryPrev->bbFallsThrough()); - // What follows is similar to fgNewBBInRegion, but we can't call that // here as the oldTryEntry is no longer in the main bb list. newTryEntry = BasicBlock::New(this); @@ -1251,7 +1248,7 @@ void Compiler::fgUnreachableBlock(BasicBlock* block) // Update bbRefs and bbPreds for this block's successors bool profileInconsistent = false; - for (BasicBlock* const succBlock : block->Succs(this)) + for (BasicBlock* const succBlock : block->Succs()) { FlowEdge* const succEdge = fgRemoveAllRefPreds(succBlock, block); @@ -1588,17 +1585,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 +1609,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 +1621,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 +1629,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 +1666,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 +1744,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 +1772,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 +1795,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"); @@ -2567,11 +2538,11 @@ bool Compiler::fgOptimizeBranch(BasicBlock* bJump) if (fgIsUsingProfileWeights()) { // Only rely upon the profile weight when all three of these blocks - // have either good profile weights or are rarelyRun + // have either good profile weights or are rarely run // - if (bJump->HasAnyFlag(BBF_PROF_WEIGHT | BBF_RUN_RARELY) && - bDest->HasAnyFlag(BBF_PROF_WEIGHT | BBF_RUN_RARELY) && - trueTarget->HasAnyFlag(BBF_PROF_WEIGHT | BBF_RUN_RARELY)) + if ((bJump->hasProfileWeight() || bJump->isRunRarely()) && + (bDest->hasProfileWeight() || bDest->isRunRarely()) && + (trueTarget->hasProfileWeight() || trueTarget->isRunRarely())) { haveProfileWeights = true; @@ -2778,7 +2749,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 +2761,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 +2827,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 +2842,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) { @@ -3162,7 +3132,6 @@ bool Compiler::fgExpandRarelyRunBlocks() // Set the BBJ_CALLFINALLY block to the same weight as the BBJ_CALLFINALLYRET block and // mark it rarely run. bPrev->bbWeight = block->bbWeight; - bPrev->SetFlags(BBF_RUN_RARELY); #ifdef DEBUG if (verbose) { @@ -3177,7 +3146,6 @@ bool Compiler::fgExpandRarelyRunBlocks() // Set the BBJ_CALLFINALLYRET block to the same weight as the BBJ_CALLFINALLY block and // mark it rarely run. block->bbWeight = bPrev->bbWeight; - block->SetFlags(BBF_RUN_RARELY); #ifdef DEBUG if (verbose) { @@ -3529,7 +3497,7 @@ void Compiler::ThreeOptLayout::AddNonFallthroughSuccs(unsigned blockPos) BasicBlock* const block = blockOrder[blockPos]; BasicBlock* const next = ((blockPos + 1) >= numCandidateBlocks) ? nullptr : blockOrder[blockPos + 1]; - for (FlowEdge* const succEdge : block->SuccEdges(compiler)) + for (FlowEdge* const succEdge : block->SuccEdges()) { if (succEdge->getDestinationBlock() != next) { @@ -4517,8 +4485,10 @@ bool Compiler::fgUpdateFlowGraph(bool doTailDuplication /* = false */, bool isPh { // In the join free case, we also need to move bDest right after bNext // to create same flow as in the isJumpAroundEmpty case. + // However, we cannot move bDest if it will break EH invariants. // - if (!fgEhAllowsMoveBlock(bNext, bDest) || bDest->isBBCallFinallyPair()) + if (!BasicBlock::sameEHRegion(bNext, bDest) || bbIsTryBeg(bDest) || bbIsHandlerBeg(bDest) || + bDest->isBBCallFinallyPair()) { optimizeJump = false; } diff --git a/src/coreclr/jit/fgprofile.cpp b/src/coreclr/jit/fgprofile.cpp index d3a43675162298..7786ff73ee2dd2 100644 --- a/src/coreclr/jit/fgprofile.cpp +++ b/src/coreclr/jit/fgprofile.cpp @@ -763,7 +763,7 @@ GenTree* BlockCountInstrumentor::CreateCounterIncrement(Compiler* comp, uint8_t* // Read Basic-Block count value GenTree* valueNode = - comp->gtNewIndOfIconHandleNode(countType, reinterpret_cast(counterAddr), GTF_ICON_BBC_PTR, false); + comp->gtNewIndOfIconHandleNode(countType, reinterpret_cast(counterAddr), GTF_ICON_BBC_PTR); // Increment value by 1 GenTree* incValueNode = comp->gtNewOperNode(GT_ADD, countType, valueNode, comp->gtNewIconNode(1, countType)); @@ -1020,13 +1020,13 @@ void Compiler::WalkSpanningTree(SpanningTreeVisitor* visitor) // things will just work for switches either way, but it // might work a bit better using the root compiler. // - const unsigned numSucc = block->NumSucc(this); + const unsigned numSucc = block->NumSucc(); if (numSucc == 1) { // Not a fork. Just visit the sole successor. // - BasicBlock* const target = block->GetSucc(0, this); + BasicBlock* const target = block->GetSucc(0); if (BitVecOps::IsMember(&traits, marked, target->bbID)) { // We can't instrument in the call finally pair tail block @@ -1061,7 +1061,7 @@ void Compiler::WalkSpanningTree(SpanningTreeVisitor* visitor) for (unsigned i = 0; i < numSucc; i++) { - BasicBlock* const succ = block->GetSucc(i, this); + BasicBlock* const succ = block->GetSucc(i); scratch.Push(succ); } @@ -1483,7 +1483,7 @@ void EfficientEdgeCountInstrumentor::SplitCriticalEdges() // See if the edge still exists. // bool found = false; - for (BasicBlock* const succ : block->Succs(m_comp)) + for (BasicBlock* const succ : block->Succs()) { if (target == succ) { @@ -3782,7 +3782,7 @@ void EfficientEdgeCountReconstructor::Propagate() assert(info->m_weightKnown); block->setBBProfileWeight(info->m_weight); - const unsigned nSucc = block->NumSucc(m_comp); + const unsigned nSucc = block->NumSucc(); if (nSucc == 0) { // No edges to worry about. @@ -3983,7 +3983,7 @@ void EfficientEdgeCountReconstructor::PropagateEdges(BasicBlock* block, BlockInf weight_t equalLikelihood = 1.0 / nSucc; - for (FlowEdge* const succEdge : block->SuccEdges(m_comp)) + for (FlowEdge* const succEdge : block->SuccEdges()) { BasicBlock* const succBlock = succEdge->getDestinationBlock(); JITDUMP("Setting likelihood of " FMT_BB " -> " FMT_BB " to " FMT_WT " (heur)\n", block->bbNum, @@ -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); } //------------------------------------------------------------------------ @@ -4346,14 +4345,6 @@ bool Compiler::fgComputeMissingBlockWeights() changed = true; modified = true; bDst->bbWeight = newWeight; - if (newWeight == BB_ZERO_WEIGHT) - { - bDst->SetFlags(BBF_RUN_RARELY); - } - else - { - bDst->RemoveFlags(BBF_RUN_RARELY); - } } } else if (!bDst->hasProfileWeight() && bbIsHandlerBeg(bDst) && !bDst->isRunRarely()) @@ -4872,7 +4863,7 @@ bool Compiler::fgDebugCheckOutgoingProfileData(BasicBlock* block, ProfileChecks // We want switch targets unified, but not EH edges. // - const unsigned numSuccs = block->NumSucc(this); + const unsigned numSuccs = block->NumSucc(); if ((numSuccs > 0) && !block->KindIs(BBJ_EHFAULTRET, BBJ_EHFILTERRET)) { @@ -4884,7 +4875,7 @@ bool Compiler::fgDebugCheckOutgoingProfileData(BasicBlock* block, ProfileChecks unsigned missingEdges = 0; unsigned missingLikelihood = 0; - for (FlowEdge* succEdge : block->SuccEdges(this)) + for (FlowEdge* succEdge : block->SuccEdges()) { assert(succEdge != nullptr); BasicBlock* succBlock = succEdge->getDestinationBlock(); @@ -4936,7 +4927,7 @@ bool Compiler::fgDebugCheckOutgoingProfileData(BasicBlock* block, ProfileChecks #ifdef DEBUG if (verbose) { - for (const FlowEdge* succEdge : block->SuccEdges(this)) + for (const FlowEdge* succEdge : block->SuccEdges()) { const BasicBlock* succBlock = succEdge->getDestinationBlock(); if (succEdge->hasLikelihood()) @@ -5019,7 +5010,7 @@ void Compiler::fgRepairProfileCondToUncond(BasicBlock* block, // weight_t const weight = removedEdge->getLikelyWeight(); - if (weight == 0.0) + if (weight == BB_ZERO_WEIGHT) { return; } @@ -5056,30 +5047,28 @@ void Compiler::fgRepairProfileCondToUncond(BasicBlock* block, if (alternate->hasProfileWeight()) { - weight_t const alternateNewWeight = alternate->bbWeight - weight; - - // If profile weights are consistent, expect at worst a slight underflow. - // - const bool checkProfileConsistency = hasFlag(activePhaseChecks, PhaseChecks::CHECK_PROFILE); - if (checkProfileConsistency && fgPgoConsistent && (alternateNewWeight < 0.0)) - { - assert(fgProfileWeightsEqual(alternateNewWeight, 0.0)); - } - alternate->setBBProfileWeight(max(0.0, alternateNewWeight)); + alternate->decreaseBBProfileWeight(weight); } else { missingProfileData = true; } - // Check for the special case where the block's postdominator - // is target's target (simple if/then/else/join). + // Check for the special cases where both successors are leaves, + // or the block's postdominator is target's target (simple if/then/else/join). // // TODO: try a bit harder to find a postdominator, if it's "nearby" // - if (!missingProfileData && target->KindIs(BBJ_ALWAYS)) + if (!missingProfileData) { - repairWasComplete = alternate->KindIs(BBJ_ALWAYS) && (alternate->GetTarget() == target->GetTarget()); + if ((target->NumSucc() == 0) && (alternate->NumSucc() == 0)) + { + repairWasComplete = true; + } + else if (target->KindIs(BBJ_ALWAYS)) + { + repairWasComplete = target->TargetIs(alternate->GetUniqueSucc()); + } } if (missingProfileData) diff --git a/src/coreclr/jit/fgprofilesynthesis.cpp b/src/coreclr/jit/fgprofilesynthesis.cpp index 1e90c43c81b824..d87415f4cc87e0 100644 --- a/src/coreclr/jit/fgprofilesynthesis.cpp +++ b/src/coreclr/jit/fgprofilesynthesis.cpp @@ -70,7 +70,7 @@ bool anyPathThrows = false; bool allPathsThrow = true; - for (BasicBlock* const succBlock : block->Succs(compiler)) + for (BasicBlock* const succBlock : block->Succs()) { if (BitVecOps::IsMember(&traits, willThrow, succBlock->bbPostorderNum)) { @@ -249,14 +249,23 @@ void ProfileSynthesis::Run(ProfileSynthesisOption option) m_comp->fgPgoSynthesized = true; m_comp->fgPgoConsistent = !m_approximate; - // A simple check whether the current method has more than one edge. - m_comp->fgPgoSingleEdge = true; - for (BasicBlock* const block : m_comp->Blocks()) + // If a method has just one edge, we simulate having PGO data for it since we typically + // don't instrument such methods. To avoid giving excessive inlining boost to large and/or + // infrequently executed methods, we apply the following heuristics to exclude: + // + const bool preferSize = m_comp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_SIZE_OPT); + const bool isCctor = (m_comp->info.compFlags & FLG_CCTOR) == FLG_CCTOR; + m_comp->fgPgoSingleEdge = !isCctor && !preferSize && (m_comp->opts.callInstrCount < 10); + + if (m_comp->fgPgoSingleEdge) { - if (block->NumSucc() > 1) + for (BasicBlock* const block : m_comp->Blocks()) { - m_comp->fgPgoSingleEdge = false; - break; + if (block->NumSucc() > 1) + { + m_comp->fgPgoSingleEdge = false; + break; + } } } @@ -516,7 +525,7 @@ void ProfileSynthesis::AssignLikelihoodSwitch(BasicBlock* block) { // Assume each switch case is equally probable // - const unsigned n = block->NumSucc(); + const unsigned n = block->GetSwitchTargets()->GetCaseCount(); assert(n != 0); // Check for divide by zero to avoid compiler warnings for Release builds (above assert is removed) @@ -524,7 +533,7 @@ void ProfileSynthesis::AssignLikelihoodSwitch(BasicBlock* block) // Each unique edge gets some multiple of that basic probability // - for (FlowEdge* const succEdge : block->SuccEdges(m_comp)) + for (FlowEdge* const succEdge : block->SuccEdges()) { succEdge->setLikelihood(p * succEdge->getDupCount()); } @@ -549,7 +558,7 @@ weight_t ProfileSynthesis::SumOutgoingLikelihoods(BasicBlock* block, WeightVecto likelihoods->clear(); } - for (FlowEdge* const succEdge : block->SuccEdges(m_comp)) + for (FlowEdge* const succEdge : block->SuccEdges()) { weight_t likelihood = succEdge->getLikelihood(); if (likelihoods != nullptr) @@ -730,7 +739,7 @@ void ProfileSynthesis::BlendLikelihoods() JITDUMP("Blending likelihoods in " FMT_BB " with blend factor " FMT_WT " \n", block->bbNum, m_blendFactor); iter = likelihoods.begin(); - for (FlowEdge* const succEdge : block->SuccEdges(m_comp)) + for (FlowEdge* const succEdge : block->SuccEdges()) { weight_t newLikelihood = succEdge->getLikelihood(); weight_t oldLikelihood = *iter; @@ -758,7 +767,7 @@ void ProfileSynthesis::ClearLikelihoods() { for (BasicBlock* const block : m_comp->Blocks()) { - for (FlowEdge* const succEdge : block->SuccEdges(m_comp)) + for (FlowEdge* const succEdge : block->SuccEdges()) { succEdge->clearLikelihood(); } @@ -776,7 +785,7 @@ void ProfileSynthesis::ReverseLikelihoods() WeightVector likelihoods(m_comp->getAllocator(CMK_Pgo)); for (BasicBlock* const block : m_comp->Blocks()) { - for (BasicBlock* const succ : block->Succs(m_comp)) + for (BasicBlock* const succ : block->Succs()) { weight_t sum = SumOutgoingLikelihoods(block, &likelihoods); @@ -816,7 +825,7 @@ void ProfileSynthesis::RandomizeLikelihoods() for (BasicBlock* const block : m_comp->Blocks()) { - unsigned const N = block->NumSucc(m_comp); + unsigned const N = block->NumSucc(); likelihoods.clear(); likelihoods.reserve(N); @@ -833,7 +842,7 @@ void ProfileSynthesis::RandomizeLikelihoods() } i = 0; - for (FlowEdge* const succEdge : block->SuccEdges(m_comp)) + for (FlowEdge* const succEdge : block->SuccEdges()) { succEdge->setLikelihood(likelihoods[i++] / sum); } diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index 4db0f7b1ccbce1..1bff7f951db56e 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -322,13 +322,13 @@ BasicBlock* Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block) { // Use a double indirection GenTree* addr = - gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pAddrOfCaptureThreadGlobal, GTF_ICON_CONST_PTR, true); + gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pAddrOfCaptureThreadGlobal, GTF_ICON_CONST_PTR); value = gtNewIndir(TYP_INT, addr, GTF_IND_NONFAULTING); } else { // Use a single indirection - value = gtNewIndOfIconHandleNode(TYP_INT, (size_t)addrTrap, GTF_ICON_GLOBAL_PTR, false); + value = gtNewIndOfIconHandleNode(TYP_INT, (size_t)addrTrap, GTF_ICON_GLOBAL_PTR); } // NOTE: in c++ an equivalent load is done via LoadWithoutBarrier() to ensure that the @@ -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); @@ -1440,7 +1436,6 @@ void Compiler::fgAddSyncMethodEnterExit() // Create a block for the fault. // It gets an artificial ref count. - assert(!tryLastBB->bbFallsThrough()); BasicBlock* faultBB = fgNewBBafter(BBJ_EHFAULTRET, tryLastBB, false); assert(tryLastBB->NextIs(faultBB)); @@ -5391,11 +5386,13 @@ bool FlowGraphNaturalLoop::VisitDefs(TFunc func) return Compiler::WALK_SKIP_SUBTREES; } - GenTreeLclVarCommon* lclDef; - if (tree->DefinesLocal(m_compiler, &lclDef)) + auto visitDef = [=](GenTreeLclVarCommon* lcl) { + return m_func(lcl) ? GenTree::VisitResult::Continue : GenTree::VisitResult::Abort; + }; + + if (tree->VisitLocalDefNodes(m_compiler, visitDef) == GenTree::VisitResult::Abort) { - if (!m_func(lclDef)) - return Compiler::WALK_ABORT; + return Compiler::WALK_ABORT; } return Compiler::WALK_CONTINUE; diff --git a/src/coreclr/jit/forwardsub.cpp b/src/coreclr/jit/forwardsub.cpp index 8bfa7af4f245c0..e67959aa7c981f 100644 --- a/src/coreclr/jit/forwardsub.cpp +++ b/src/coreclr/jit/forwardsub.cpp @@ -569,8 +569,11 @@ bool Compiler::fgForwardSubStatement(Statement* stmt) // Consider instead using the height of the fwdSubNode. // unsigned const nodeLimit = 16; + auto countNode = [](GenTree* tree) -> unsigned { + return 1; + }; - if (gtComplexityExceeds(fwdSubNode, nodeLimit)) + if (gtComplexityExceeds(fwdSubNode, nodeLimit, countNode)) { JITDUMP(" tree to sub has more than %u nodes\n", nodeLimit); return false; @@ -633,7 +636,7 @@ bool Compiler::fgForwardSubStatement(Statement* stmt) // height of the fwdSubNode. // unsigned const nextTreeLimit = 200; - if ((fsv.GetComplexity() > nextTreeLimit) && gtComplexityExceeds(fwdSubNode, 1)) + if ((fsv.GetComplexity() > nextTreeLimit) && gtComplexityExceeds(fwdSubNode, 1, countNode)) { JITDUMP(" next stmt tree is too large (%u)\n", fsv.GetComplexity()); return false; diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 78ed00c13041cf..2ae5c17f1132f7 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -1829,6 +1829,46 @@ void CallArgs::Remove(CallArg* arg) assert(!"Did not find arg to remove in CallArgs::Remove"); } +//--------------------------------------------------------------- +// RemoveUnsafe: Remove an argument from the argument list, without validation. +// +// Parameters: +// arg - The arg to remove. +// +// Remarks: +// This function will break ABI information of other arguments. The caller +// needs to know what they are doing. +// +void CallArgs::RemoveUnsafe(CallArg* arg) +{ + CallArg** slot = &m_lateHead; + while (*slot != nullptr) + { + if (*slot == arg) + { + *slot = arg->GetLateNext(); + break; + } + + slot = &(*slot)->LateNextRef(); + } + + slot = &m_head; + while (*slot != nullptr) + { + if (*slot == arg) + { + *slot = arg->GetNext(); + RemovedWellKnownArg(arg->GetWellKnownArg()); + return; + } + + slot = &(*slot)->NextRef(); + } + + assert(!"Did not find arg to remove in CallArgs::Remove"); +} + #ifdef TARGET_XARCH //--------------------------------------------------------------- // NeedsVzeroupper: Determines if the call needs a vzeroupper emitted before it is invoked @@ -7687,10 +7727,9 @@ GenTreeFlags Compiler::gtTokenToIconFlags(unsigned token) // gtNewIndOfIconHandleNode: Creates an indirection GenTree node of a constant handle // // Arguments: -// indType - The type returned by the indirection node -// addr - The constant address to read from -// iconFlags - The GTF_ICON flag value that specifies the kind of handle that we have -// isInvariant - The indNode should also be marked as invariant +// indType - The type returned by the indirection node +// addr - The constant address to read from +// iconFlags - The GTF_ICON flag value that specifies the kind of handle that we have // // Return Value: // Returns a GT_IND node representing value at the address provided by 'addr' @@ -7699,21 +7738,17 @@ GenTreeFlags Compiler::gtTokenToIconFlags(unsigned token) // The GT_IND node is marked as non-faulting. // If the indirection is not invariant, we also mark the indNode as GTF_GLOB_REF. // -GenTree* Compiler::gtNewIndOfIconHandleNode(var_types indType, size_t addr, GenTreeFlags iconFlags, bool isInvariant) +GenTree* Compiler::gtNewIndOfIconHandleNode(var_types indType, size_t addr, GenTreeFlags iconFlags) { GenTree* addrNode = gtNewIconHandleNode(addr, iconFlags); GenTreeFlags indirFlags = GTF_IND_NONFAULTING; // This indirection won't cause an exception. - - if (isInvariant) + if (GenTree::HandleKindDataIsInvariant(iconFlags)) { - // This indirection also is invariant. indirFlags |= GTF_IND_INVARIANT; - - if (iconFlags == GTF_ICON_STR_HDL) - { - // String literals are never null - indirFlags |= GTF_IND_NONNULL; - } + } + if (GenTree::HandleKindDataIsNotNull(iconFlags)) + { + indirFlags |= GTF_IND_NONNULL; } GenTree* indNode = gtNewIndir(indType, addrNode, indirFlags); @@ -7783,13 +7818,13 @@ GenTree* Compiler::gtNewStringLiteralNode(InfoAccessType iat, void* pValue) case IAT_PVALUE: // The value needs to be accessed via an indirection // Create an indirection - tree = gtNewIndOfIconHandleNode(TYP_REF, (size_t)pValue, GTF_ICON_STR_HDL, true); + tree = gtNewIndOfIconHandleNode(TYP_REF, (size_t)pValue, GTF_ICON_STR_HDL); INDEBUG(tree->gtGetOp1()->AsIntCon()->gtTargetHandle = (size_t)pValue); break; case IAT_PPVALUE: // The value needs to be accessed via a double indirection // Create the first indirection. - tree = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pValue, GTF_ICON_CONST_PTR, true); + tree = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pValue, GTF_ICON_CONST_PTR); INDEBUG(tree->gtGetOp1()->AsIntCon()->gtTargetHandle = (size_t)pValue); // Create the second indirection. tree = gtNewIndir(TYP_REF, tree, GTF_IND_NONFAULTING | GTF_IND_INVARIANT | GTF_IND_NONNULL); @@ -9596,18 +9631,15 @@ GenTree* Compiler::gtCloneExpr(GenTree* tree) break; case GT_ARR_LENGTH: - copy = - gtNewArrLen(tree->TypeGet(), tree->AsArrLen()->ArrRef(), tree->AsArrLen()->ArrLenOffset(), nullptr); + copy = gtNewArrLen(tree->TypeGet(), tree->AsArrLen()->ArrRef(), tree->AsArrLen()->ArrLenOffset()); break; case GT_MDARR_LENGTH: - copy = - gtNewMDArrLen(tree->AsMDArr()->ArrRef(), tree->AsMDArr()->Dim(), tree->AsMDArr()->Rank(), nullptr); + copy = gtNewMDArrLen(tree->AsMDArr()->ArrRef(), tree->AsMDArr()->Dim(), tree->AsMDArr()->Rank()); break; case GT_MDARR_LOWER_BOUND: - copy = gtNewMDArrLowerBound(tree->AsMDArr()->ArrRef(), tree->AsMDArr()->Dim(), tree->AsMDArr()->Rank(), - nullptr); + copy = gtNewMDArrLowerBound(tree->AsMDArr()->ArrRef(), tree->AsMDArr()->Dim(), tree->AsMDArr()->Rank()); break; case GT_QMARK: @@ -9911,7 +9943,7 @@ GenTreeCall* Compiler::gtCloneExprCallHelper(GenTreeCall* tree) } else if (tree->IsAsync()) { - copy->asyncInfo = tree->asyncInfo; + copy->asyncInfo = new (this, CMK_Async) AsyncCallInfo(*tree->asyncInfo); } else if (tree->IsTailPrefixedCall()) { @@ -10798,45 +10830,35 @@ void GenTree::SetIndirExceptionFlags(Compiler* comp) } } +static const uint8_t g_handleKindsFlags[] = { +#define HANDLE_KIND(name, description, flags) flags, +#include "handlekinds.h" +}; + //------------------------------------------------------------------------------ -// HandleKindDataIsInvariant: Returns true if the data referred to by a handle +// HandleKindDataIsInvariant: Returns true if the data pointed to by a handle // address is guaranteed to be invariant. // // Arguments: -// flags - GenTree flags for handle. +// flags - the handle kind // -/* static */ bool GenTree::HandleKindDataIsInvariant(GenTreeFlags flags) { - GenTreeFlags handleKind = flags & GTF_ICON_HDL_MASK; - assert(handleKind != GTF_EMPTY); + unsigned handleKindIndex = HandleKindToHandleKindIndex(flags); + return (g_handleKindsFlags[handleKindIndex] & HKF_INVARIANT) != 0; +} - switch (handleKind) - { - case GTF_ICON_SCOPE_HDL: - case GTF_ICON_CLASS_HDL: - case GTF_ICON_METHOD_HDL: - case GTF_ICON_FIELD_HDL: - case GTF_ICON_STR_HDL: - case GTF_ICON_CONST_PTR: - case GTF_ICON_VARG_HDL: - case GTF_ICON_PINVKI_HDL: - case GTF_ICON_TOKEN_HDL: - case GTF_ICON_TLS_HDL: - case GTF_ICON_CIDMID_HDL: - case GTF_ICON_FIELD_SEQ: - case GTF_ICON_STATIC_ADDR_PTR: - case GTF_ICON_SECREL_OFFSET: - case GTF_ICON_TLSGD_OFFSET: - return true; - case GTF_ICON_FTN_ADDR: - case GTF_ICON_GLOBAL_PTR: - case GTF_ICON_STATIC_HDL: - case GTF_ICON_BBC_PTR: - case GTF_ICON_STATIC_BOX_PTR: - default: - return false; - } +//------------------------------------------------------------------------------ +// HandleKindDataIsNotNull: Returns true if the data pointed to by a handle +// address is guaranteed to be non-null if interpreted as a pointer. +// +// Arguments: +// flags - the handle kind +// +bool GenTree::HandleKindDataIsNotNull(GenTreeFlags flags) +{ + unsigned handleKindIndex = HandleKindToHandleKindIndex(flags); + return (g_handleKindsFlags[handleKindIndex] & HKF_NONNULL) != 0; } #ifdef DEBUG @@ -10877,48 +10899,10 @@ const char* GenTree::gtGetHandleKindString(GenTreeFlags flags) { case 0: return ""; - case GTF_ICON_SCOPE_HDL: - return "GTF_ICON_SCOPE_HDL"; - case GTF_ICON_CLASS_HDL: - return "GTF_ICON_CLASS_HDL"; - case GTF_ICON_METHOD_HDL: - return "GTF_ICON_METHOD_HDL"; - case GTF_ICON_FIELD_HDL: - return "GTF_ICON_FIELD_HDL"; - case GTF_ICON_STATIC_HDL: - return "GTF_ICON_STATIC_HDL"; - case GTF_ICON_STR_HDL: - return "GTF_ICON_STR_HDL"; - case GTF_ICON_OBJ_HDL: - return "GTF_ICON_OBJ_HDL"; - case GTF_ICON_CONST_PTR: - return "GTF_ICON_CONST_PTR"; - case GTF_ICON_GLOBAL_PTR: - return "GTF_ICON_GLOBAL_PTR"; - case GTF_ICON_VARG_HDL: - return "GTF_ICON_VARG_HDL"; - case GTF_ICON_PINVKI_HDL: - return "GTF_ICON_PINVKI_HDL"; - case GTF_ICON_TOKEN_HDL: - return "GTF_ICON_TOKEN_HDL"; - case GTF_ICON_TLS_HDL: - return "GTF_ICON_TLS_HDL"; - case GTF_ICON_FTN_ADDR: - return "GTF_ICON_FTN_ADDR"; - case GTF_ICON_CIDMID_HDL: - return "GTF_ICON_CIDMID_HDL"; - case GTF_ICON_BBC_PTR: - return "GTF_ICON_BBC_PTR"; - case GTF_ICON_STATIC_BOX_PTR: - return "GTF_ICON_STATIC_BOX_PTR"; - case GTF_ICON_FIELD_SEQ: - return "GTF_ICON_FIELD_SEQ"; - case GTF_ICON_STATIC_ADDR_PTR: - return "GTF_ICON_STATIC_ADDR_PTR"; - case GTF_ICON_SECREL_OFFSET: - return "GTF_ICON_SECREL_OFFSET"; - case GTF_ICON_TLSGD_OFFSET: - return "GTF_ICON_TLSGD_OFFSET"; +#define HANDLE_KIND(name, description, flags) \ + case name: \ + return #name; +#include "handlekinds.h" default: return "ILLEGAL!"; } @@ -11574,9 +11558,9 @@ void Compiler::gtDispNode(GenTree* tree, IndentStack* indentStack, _In_ _In_opt_ { printf("(AX)"); // Variable has address exposed. } - if (varDsc->IsHiddenBufferStructArg()) + if (varDsc->IsDefinedViaAddress()) { - printf("(RB)"); // Variable is hidden return buffer + printf("(DA)"); // Variable is defined via address } if (varDsc->lvUnusedStruct) { @@ -12051,7 +12035,7 @@ void Compiler::gtDispConst(GenTree* tree) } else if (tree->IsIconHandle(GTF_ICON_OBJ_HDL)) { - eePrintObjectDescription(" ", (CORINFO_OBJECT_HANDLE)tree->AsIntCon()->gtIconVal); + eePrintObjectDescription(" ", CORINFO_OBJECT_HANDLE(tree->AsIntCon()->IconValue())); } else { @@ -12098,93 +12082,43 @@ void Compiler::gtDispConst(GenTree* tree) } } - if (tree->IsIconHandle()) + switch (tree->GetIconHandleFlag()) { - switch (tree->GetIconHandleFlag()) - { - case GTF_ICON_SCOPE_HDL: - printf(" scope"); - break; - case GTF_ICON_CLASS_HDL: - if (IsAot()) - { - printf(" class"); - } - else - { - printf(" class %s", eeGetClassName((CORINFO_CLASS_HANDLE)iconVal)); - } - break; - case GTF_ICON_METHOD_HDL: - if (IsAot()) - { - printf(" method"); - } - else - { - printf(" method %s", eeGetMethodFullName((CORINFO_METHOD_HANDLE)iconVal)); - } - break; - case GTF_ICON_FIELD_HDL: - if (IsAot()) - { - printf(" field"); - } - else - { - printf(" field %s", eeGetFieldName((CORINFO_FIELD_HANDLE)iconVal, true)); - } - break; - case GTF_ICON_STATIC_HDL: - printf(" static"); - break; - case GTF_ICON_OBJ_HDL: - case GTF_ICON_STR_HDL: - unreached(); // These cases are handled above - break; - case GTF_ICON_CONST_PTR: - printf(" const ptr"); - break; - case GTF_ICON_GLOBAL_PTR: - printf(" global ptr"); - break; - case GTF_ICON_VARG_HDL: - printf(" vararg"); - break; - case GTF_ICON_PINVKI_HDL: - printf(" pinvoke"); - break; - case GTF_ICON_TOKEN_HDL: - printf(" token"); - break; - case GTF_ICON_TLS_HDL: - printf(" tls"); - break; - case GTF_ICON_FTN_ADDR: - printf(" ftn"); - break; - case GTF_ICON_CIDMID_HDL: - printf(" cid/mid"); - break; - case GTF_ICON_BBC_PTR: - printf(" bbc"); - break; - case GTF_ICON_STATIC_BOX_PTR: - printf(" static box ptr"); - break; - case GTF_ICON_STATIC_ADDR_PTR: - printf(" static base addr cell"); - break; - case GTF_ICON_SECREL_OFFSET: - printf(" relative offset in section"); - break; - case GTF_ICON_TLSGD_OFFSET: - printf(" tls global dynamic offset"); - break; - default: - printf(" UNKNOWN"); - break; - } + case GTF_EMPTY: + break; +#define HANDLE_KIND(name, description, flags) \ + case name: \ + printf(" %s", description); \ + break; +#include "handlekinds.h" + default: + printf(" ILLEGAL"); + break; + } + + // Print additional details for some handles. + switch (tree->GetIconHandleFlag()) + { + case GTF_ICON_CLASS_HDL: + if (!IsAot()) + { + printf(" %s", eeGetClassName((CORINFO_CLASS_HANDLE)iconVal)); + } + break; + case GTF_ICON_METHOD_HDL: + if (!IsAot()) + { + printf(" %s", eeGetMethodFullName((CORINFO_METHOD_HANDLE)iconVal)); + } + break; + case GTF_ICON_FIELD_HDL: + if (!IsAot()) + { + printf(" %s", eeGetFieldName((CORINFO_FIELD_HANDLE)iconVal, true)); + } + break; + default: + break; } #ifdef FEATURE_SIMD @@ -12233,8 +12167,18 @@ void Compiler::gtDispConst(GenTree* tree) } case GT_CNS_STR: - printf(""); - break; + { + GenTreeStrCon* cnsStr = tree->AsStrCon(); + if (cnsStr->IsStringEmptyField()) + { + // Special case: do not call getStringLiteral for the empty string field + printf("\"\""); + break; + } + + eePrintStringLiteral(cnsStr->gtScpHnd, cnsStr->gtSconCPX); + } + break; #if defined(FEATURE_SIMD) case GT_CNS_VEC: @@ -13180,6 +13124,8 @@ const char* Compiler::gtGetWellKnownArgNameForArgMsg(WellKnownArg arg) return "&lcl arr"; case WellKnownArg::RuntimeMethodHandle: return "meth hnd"; + case WellKnownArg::AsyncSuspendedIndicator: + return "async susp"; default: return nullptr; } @@ -14218,7 +14164,7 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree) { // we still have to emit a null-check // obj.GetType == typeof() -> (nullcheck) true/false - GenTree* nullcheck = gtNewNullCheck(objOp, compCurBB); + GenTree* nullcheck = gtNewNullCheck(objOp); return gtNewOperNode(GT_COMMA, tree->TypeGet(), nullcheck, compareResult); } else if (objOp->gtFlags & GTF_ALL_EFFECT) @@ -17373,7 +17319,7 @@ void Compiler::gtExtractSideEffList(GenTree* expr, if (node->OperIsBlk() && !node->OperIsStoreBlk()) { JITDUMP("Replace an unused BLK node [%06d] with a NULLCHECK\n", dspTreeID(node)); - m_compiler->gtChangeOperToNullCheck(node, m_compiler->compCurBB); + m_compiler->gtChangeOperToNullCheck(node); } Append(node); @@ -17806,65 +17752,6 @@ ExceptionSetFlags Compiler::gtCollectExceptions(GenTree* tree) return walker.GetFlags(); } -//----------------------------------------------------------- -// gtComplexityExceeds: Check if a tree exceeds a specified complexity in terms -// of number of sub nodes. -// -// Arguments: -// tree - The tree to check -// limit - The limit in terms of number of nodes -// complexity - [out, optional] the actual node count (if not greater than limit) -// -// Return Value: -// True if there are more than limit nodes in tree; otherwise false. -// -bool Compiler::gtComplexityExceeds(GenTree* tree, unsigned limit, unsigned* complexity) -{ - struct ComplexityVisitor : GenTreeVisitor - { - enum - { - DoPreOrder = true, - }; - - ComplexityVisitor(Compiler* comp, unsigned limit) - : GenTreeVisitor(comp) - , m_limit(limit) - { - } - - fgWalkResult PreOrderVisit(GenTree** use, GenTree* user) - { - if (++m_numNodes > m_limit) - { - return WALK_ABORT; - } - - return WALK_CONTINUE; - } - - unsigned NumNodes() - { - return m_numNodes; - } - - private: - unsigned m_limit; - unsigned m_numNodes = 0; - }; - - ComplexityVisitor visitor(this, limit); - - fgWalkResult result = visitor.WalkTree(&tree, nullptr); - - if (complexity != nullptr) - { - *complexity = visitor.NumNodes(); - } - - return (result == WALK_ABORT); -} - bool GenTree::IsPhiNode() { return (OperGet() == GT_PHI_ARG) || (OperGet() == GT_PHI) || IsPhiDefn(); @@ -17895,105 +17782,6 @@ bool GenTree::IsPartialLclFld(Compiler* comp) (comp->lvaGetDesc(AsLclFld())->lvExactSize() != AsLclFld()->GetSize()); } -//------------------------------------------------------------------------ -// DefinesLocal: Does "this" define a local? -// -// Arguments: -// comp - the compiler instance -// pLclVarTree - [out] parameter for the local representing the definition -// pIsEntire - optional [out] parameter for whether the store represents -// a "full" definition (overwrites the entire variable) -// pOffset - optional [out] parameter for the offset, relative to the -// local, at which the store is performed -// pSize - optional [out] parameter for the amount of bytes affected -// by the store -// -// Return Value: -// Whether "this" represents a store to a possibly tracked local variable -// before rationalization. -// -// Notes: -// This function is contractually bound to recognize a superset of stores -// that "LocalAddressVisitor" recognizes and transforms, as it is used to -// detect which trees can define tracked locals. -// -bool GenTree::DefinesLocal( - Compiler* comp, GenTreeLclVarCommon** pLclVarTree, bool* pIsEntire, ssize_t* pOffset, unsigned* pSize) -{ - assert((pOffset == nullptr) || (*pOffset == 0)); - - if (OperIs(GT_STORE_LCL_VAR)) - { - *pLclVarTree = AsLclVarCommon(); - if (pIsEntire != nullptr) - { - *pIsEntire = true; - } - if (pOffset != nullptr) - { - *pOffset = 0; - } - if (pSize != nullptr) - { - *pSize = comp->lvaLclExactSize(AsLclVarCommon()->GetLclNum()); - } - - return true; - } - if (OperIs(GT_STORE_LCL_FLD)) - { - *pLclVarTree = AsLclVarCommon(); - if (pIsEntire != nullptr) - { - *pIsEntire = !AsLclFld()->IsPartialLclFld(comp); - } - if (pOffset != nullptr) - { - *pOffset = AsLclFld()->GetLclOffs(); - } - if (pSize != nullptr) - { - *pSize = AsLclFld()->GetSize(); - } - - return true; - } - if (OperIs(GT_CALL)) - { - GenTreeLclVarCommon* lclAddr = comp->gtCallGetDefinedRetBufLclAddr(AsCall()); - if (lclAddr == nullptr) - { - return false; - } - - *pLclVarTree = lclAddr; - - if ((pIsEntire != nullptr) || (pSize != nullptr)) - { - unsigned storeSize = comp->typGetObjLayout(AsCall()->gtRetClsHnd)->GetSize(); - - if (pIsEntire != nullptr) - { - *pIsEntire = storeSize == comp->lvaLclExactSize(lclAddr->GetLclNum()); - } - - if (pSize != nullptr) - { - *pSize = storeSize; - } - } - - if (pOffset != nullptr) - { - *pOffset = lclAddr->GetLclOffs(); - } - - return true; - } - - return false; -} - //------------------------------------------------------------------------ // IsImplicitByrefParameterValuePreMorph: // Determine if this tree represents the value of an implicit byref @@ -18151,9 +17939,9 @@ bool GenTree::canBeContained() const { return false; } - else if (OperIsHWIntrinsic() && !isContainableHWIntrinsic()) + else if (OperIsHWIntrinsic()) { - return isEmbeddedMaskingCompatibleHWIntrinsic(); + return isContainableHWIntrinsic(); } return true; @@ -19657,7 +19445,33 @@ GenTreeLclVarCommon* Compiler::gtCallGetDefinedRetBufLclAddr(GenTreeCall* call) // This may be called very late to check validity of LIR. node = node->gtSkipReloadOrCopy(); - assert(node->OperIs(GT_LCL_ADDR) && lvaGetDesc(node->AsLclVarCommon())->IsHiddenBufferStructArg()); + assert(node->OperIs(GT_LCL_ADDR) && lvaGetDesc(node->AsLclVarCommon())->IsDefinedViaAddress()); + + return node->AsLclVarCommon(); +} + +//------------------------------------------------------------------------ +// gtCallGetDefinedAsyncSuspendedIndicatorLclAddr: +// Get the tree corresponding to the address of the indicator local that this call defines. +// +// Parameters: +// call - the Call node +// +// Returns: +// A tree representing the address of a local. +// +GenTreeLclVarCommon* Compiler::gtCallGetDefinedAsyncSuspendedIndicatorLclAddr(GenTreeCall* call) +{ + if (!call->IsAsync() || !call->GetAsyncInfo().HasSuspensionIndicatorDef) + { + return nullptr; + } + + CallArg* asyncSuspensionIndicatorArg = call->gtArgs.FindWellKnownArg(WellKnownArg::AsyncSuspendedIndicator); + assert(asyncSuspensionIndicatorArg != nullptr); + GenTree* node = asyncSuspensionIndicatorArg->GetNode(); + + assert(node->OperIs(GT_LCL_ADDR) && lvaGetDesc(node->AsLclVarCommon())->IsDefinedViaAddress()); return node->AsLclVarCommon(); } @@ -19994,7 +19808,13 @@ bool GenTree::IsArrayAddr(GenTreeArrAddr** pArrAddr) bool GenTree::SupportsSettingZeroFlag() { #if defined(TARGET_XARCH) - if (OperIs(GT_AND, GT_OR, GT_XOR, GT_ADD, GT_SUB, GT_NEG, GT_LSH, GT_RSH, GT_RSZ, GT_ROL, GT_ROR)) + if (OperIs(GT_LSH, GT_RSH, GT_RSZ, GT_ROL, GT_ROR)) + { + // Shift/Rotate instructions do not update the flags in case of count being zero. + return gtGetOp2()->IsNeverZero(); + } + + if (OperIs(GT_AND, GT_OR, GT_XOR, GT_ADD, GT_SUB, GT_NEG)) { return true; } @@ -20334,10 +20154,11 @@ bool GenTree::isCommutativeHWIntrinsic() const bool GenTree::isContainableHWIntrinsic() const { - assert(OperIs(GT_HWINTRINSIC)); + const GenTreeHWIntrinsic* node = AsHWIntrinsic(); + NamedIntrinsic intrinsic = node->GetHWIntrinsicId(); #ifdef TARGET_XARCH - switch (AsHWIntrinsic()->GetHWIntrinsicId()) + switch (intrinsic) { case NI_X86Base_LoadAlignedVector128: case NI_X86Base_LoadScalarVector128: @@ -20353,7 +20174,7 @@ bool GenTree::isContainableHWIntrinsic() const case NI_AVX512_ConvertToVector256Int32: case NI_AVX512_ConvertToVector256UInt32: { - if (varTypeIsFloating(AsHWIntrinsic()->GetSimdBaseType())) + if (varTypeIsFloating(node->GetSimdBaseType())) { return false; } @@ -20428,24 +20249,24 @@ bool GenTree::isContainableHWIntrinsic() const default: { - return false; + return isEmbeddedMaskingCompatible(); } } #elif defined(TARGET_ARM64) - return (AsHWIntrinsic()->GetHWIntrinsicId() == NI_Sve_ConditionalSelect); + return (intrinsic == NI_Sve_ConditionalSelect) || isEmbeddedMaskingCompatible(); #else return false; #endif // TARGET_XARCH } -bool GenTree::isRMWHWIntrinsic(Compiler* comp) +bool GenTree::isRMWHWIntrinsic(Compiler* comp) const { assert(OperIs(GT_HWINTRINSIC)); assert(comp != nullptr); #if defined(TARGET_XARCH) - GenTreeHWIntrinsic* hwintrinsic = AsHWIntrinsic(); - NamedIntrinsic intrinsicId = hwintrinsic->GetHWIntrinsicId(); + const GenTreeHWIntrinsic* hwintrinsic = AsHWIntrinsic(); + NamedIntrinsic intrinsicId = hwintrinsic->GetHWIntrinsicId(); if (!comp->canUseVexEncoding()) { @@ -20618,7 +20439,7 @@ bool GenTree::isEmbeddedBroadcastCompatibleHWIntrinsic(Compiler* comp) const { NamedIntrinsic intrinsicId = AsHWIntrinsic()->GetHWIntrinsicId(); var_types simdBaseType = AsHWIntrinsic()->GetSimdBaseType(); - instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, simdBaseType, nullptr); + instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, simdBaseType, comp); if (comp->codeGen->instIsEmbeddedBroadcastCompatible(ins)) { @@ -20638,19 +20459,21 @@ bool GenTree::isEmbeddedBroadcastCompatibleHWIntrinsic(Compiler* comp) const #endif // TARGET_XARCH //------------------------------------------------------------------------ -// isEmbeddedMaskingCompatibleHWIntrinsic : Checks if the intrinsic is compatible +// isEmbeddedMaskingCompatible: Checks if the node is a hwintrinsic compatible // with the EVEX embedded masking form for its intended lowering instruction. // // Return Value: -// true if the intrinsic node lowering instruction has a EVEX embedded masking support +// true if the node lowering instruction has a EVEX embedded masking support // -bool GenTree::isEmbeddedMaskingCompatibleHWIntrinsic() const +bool GenTree::isEmbeddedMaskingCompatible() const { if (OperIsHWIntrinsic()) { - NamedIntrinsic intrinsicId = AsHWIntrinsic()->GetHWIntrinsicId(); + const GenTreeHWIntrinsic* node = AsHWIntrinsic(); + NamedIntrinsic intrinsic = node->GetHWIntrinsicId(); + #if defined(TARGET_XARCH) - var_types simdBaseType = AsHWIntrinsic()->GetSimdBaseType(); + var_types simdBaseType = node->GetSimdBaseType(); if (simdBaseType == TYP_UNKNOWN) { @@ -20658,32 +20481,234 @@ bool GenTree::isEmbeddedMaskingCompatibleHWIntrinsic() const return false; } - if (AsHWIntrinsic()->OperIsMemoryLoadOrStore()) + HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsic); + + if (!HWIntrinsicInfo::genIsTableDrivenHWIntrinsic(intrinsic, category)) + { + // TODO-AVX512-CQ: Codegen is currently limited to only handling embedded + // masking for table driven intrinsics. This can be relaxed once that is fixed. + return false; + } + + if (node->OperIsMemoryLoadOrStore()) { // Direct loads and stores cannot be embedded masking compatible // as they may suppress faults that should otherwise be raised return false; } - instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, simdBaseType, nullptr); + instruction ins = HWIntrinsicInfo::lookupIns(intrinsic, simdBaseType, nullptr); return CodeGenInterface::instIsEmbeddedMaskingCompatible(ins); #elif defined(TARGET_ARM64) - return HWIntrinsicInfo::IsEmbeddedMaskedOperation(intrinsicId) || - HWIntrinsicInfo::IsOptionalEmbeddedMaskedOperation(intrinsicId); + return HWIntrinsicInfo::IsEmbeddedMaskedOperation(intrinsic) || + HWIntrinsicInfo::IsOptionalEmbeddedMaskedOperation(intrinsic); #endif } return false; } -GenTreeHWIntrinsic* Compiler::gtNewSimdHWIntrinsicNode(var_types type, - NamedIntrinsic hwIntrinsicID, - CorInfoType simdBaseJitType, - unsigned simdSize) -{ - return new (this, GT_HWINTRINSIC) - GenTreeHWIntrinsic(type, getAllocator(CMK_ASTNode), hwIntrinsicID, simdBaseJitType, simdSize); -} - +#if defined(TARGET_XARCH) +//------------------------------------------------------------------------ +// isEmbeddedMaskingCompatible : Checks if the node is a hwintrinsic compatible +// with the EVEX embedded masking form for its intended lowering instruction. +// +// Arguments: +// comp - The compiler +// tgtMaskSize - The mask size to check compatibility against +// tgtSimdBaseJitType - The target simd base jit type to use if supported +// +// Return Value: +// true if the node lowering instruction has a EVEX embedded masking support +// +bool GenTree::isEmbeddedMaskingCompatible(Compiler* comp, unsigned tgtMaskSize, CorInfoType& tgtSimdBaseJitType) const +{ + if (!isEmbeddedMaskingCompatible()) + { + return false; + } + + if (!comp->opts.Tier0OptimizationEnabled()) + { + return false; + } + + if (!comp->canUseEmbeddedMasking()) + { + return false; + } + + if (isRMWHWIntrinsic(comp)) + { + // TODO-AVX512-CQ: Ensure we can support embedded operations on RMW intrinsics + return false; + } + + const GenTreeHWIntrinsic* node = AsHWIntrinsic(); + NamedIntrinsic intrinsic = node->GetHWIntrinsicId(); + CorInfoType simdBaseJitType = node->GetSimdBaseJitType(); + var_types simdBaseType = node->GetSimdBaseType(); + var_types simdType = node->TypeGet(); + + instruction ins = HWIntrinsicInfo::lookupIns(intrinsic, simdBaseType, comp); + unsigned maskBaseSize = CodeGenInterface::instKMaskBaseSize(ins); + unsigned tgtMaskBaseSize = tgtMaskSize / (genTypeSize(simdType) / 16); + + tgtSimdBaseJitType = CORINFO_TYPE_UNDEF; + + if (maskBaseSize != tgtMaskBaseSize) + { + // Some intrinsics are effectively bitwise operations and so we + // can freely update them to match the size of the actual mask + + bool supportsMaskBaseSize2Or4 = false; + + switch (ins) + { + case INS_andpd: + case INS_andps: + case INS_andnpd: + case INS_andnps: + case INS_orpd: + case INS_orps: + case INS_pandd: + case INS_pandnd: + case INS_pord: + case INS_pxord: + case INS_vpandq: + case INS_vpandnq: + case INS_vporq: + case INS_vpxorq: + case INS_vshuff32x4: + case INS_vshuff64x2: + case INS_vshufi32x4: + case INS_vshufi64x2: + case INS_xorpd: + case INS_xorps: + { + // 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 + supportsMaskBaseSize2Or4 = true; + } + break; + } + + case INS_vpternlogd: + case INS_vpternlogq: + { + // 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 + supportsMaskBaseSize2Or4 = true; + } + break; + } + + case INS_vbroadcastf32x4: + case INS_vbroadcastf32x8: + case INS_vbroadcastf64x2: + case INS_vbroadcastf64x4: + case INS_vbroadcasti32x4: + case INS_vbroadcasti32x8: + case INS_vbroadcasti64x2: + case INS_vbroadcasti64x4: + case INS_vextractf32x4: + case INS_vextractf32x8: + case INS_vextractf64x2: + case INS_vextractf64x4: + case INS_vextracti32x4: + case INS_vextracti32x8: + case INS_vextracti64x2: + case INS_vextracti64x4: + case INS_vinsertf32x4: + case INS_vinsertf32x8: + case INS_vinsertf64x2: + case INS_vinsertf64x4: + case INS_vinserti32x4: + case INS_vinserti32x8: + case INS_vinserti64x2: + case INS_vinserti64x4: + { + // These intrinsics don't support embedded broadcast and have masking support for 2 or 4 + assert((maskBaseSize == 2) || (maskBaseSize == 4)); + supportsMaskBaseSize2Or4 = true; + break; + } + + default: + { + break; + } + } + + if (supportsMaskBaseSize2Or4) + { + if (tgtMaskBaseSize == 2) + { + if (varTypeIsFloating(simdBaseType)) + { + tgtSimdBaseJitType = CORINFO_TYPE_DOUBLE; + } + else if (varTypeIsSigned(simdBaseType)) + { + tgtSimdBaseJitType = CORINFO_TYPE_LONG; + } + else + { + tgtSimdBaseJitType = CORINFO_TYPE_ULONG; + } + } + else if (tgtMaskBaseSize == 4) + { + if (varTypeIsFloating(simdBaseType)) + { + tgtSimdBaseJitType = CORINFO_TYPE_FLOAT; + } + else if (varTypeIsSigned(simdBaseType)) + { + tgtSimdBaseJitType = CORINFO_TYPE_INT; + } + else + { + tgtSimdBaseJitType = CORINFO_TYPE_UINT; + } + } + } + } + + if (tgtSimdBaseJitType != CORINFO_TYPE_UNDEF) + { + var_types tgtSimdBaseType = JitType2PreciseVarType(tgtSimdBaseJitType); + + instruction tgtIns = HWIntrinsicInfo::lookupIns(intrinsic, tgtSimdBaseType, comp); + assert(ins != tgtIns); + + ins = tgtIns; + maskBaseSize = CodeGenInterface::instKMaskBaseSize(ins); + } + + unsigned maskSize = maskBaseSize * (genTypeSize(simdType) / 16); + assert(maskSize != 0); + + return maskSize == tgtMaskSize; +} +#endif // TARGET_XARCH + +GenTreeHWIntrinsic* Compiler::gtNewSimdHWIntrinsicNode(var_types type, + NamedIntrinsic hwIntrinsicID, + CorInfoType simdBaseJitType, + unsigned simdSize) +{ + return new (this, GT_HWINTRINSIC) + GenTreeHWIntrinsic(type, getAllocator(CMK_ASTNode), hwIntrinsicID, simdBaseJitType, simdSize); +} + GenTreeHWIntrinsic* Compiler::gtNewSimdHWIntrinsicNode( var_types type, GenTree* op1, NamedIntrinsic hwIntrinsicID, CorInfoType simdBaseJitType, unsigned simdSize) { @@ -28321,22 +28346,6 @@ bool GenTree::OperIsConvertVectorToMask() const return false; } -//------------------------------------------------------------------------ -// OperIsVectorConditionalSelect: Is this a vector ConditionalSelect hwintrinsic -// -// Return Value: -// true if the node is a vector ConditionalSelect hwintrinsic -// otherwise; false -// -bool GenTree::OperIsVectorConditionalSelect() const -{ - if (OperIsHWIntrinsic()) - { - return AsHWIntrinsic()->OperIsVectorConditionalSelect(); - } - return false; -} - //------------------------------------------------------------------------ // OperIsVectorFusedMultiplyOp: Is this a vector FusedMultiplyOp hwintrinsic // @@ -28454,6 +28463,31 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad(GenTree** pAddr) const case NI_Sve_Load2xVectorAndUnzip: case NI_Sve_Load3xVectorAndUnzip: case NI_Sve_Load4xVectorAndUnzip: + case NI_Sve_LoadVectorByteNonFaultingZeroExtendToInt16: + case NI_Sve_LoadVectorByteNonFaultingZeroExtendToInt32: + case NI_Sve_LoadVectorByteNonFaultingZeroExtendToInt64: + case NI_Sve_LoadVectorByteNonFaultingZeroExtendToUInt16: + case NI_Sve_LoadVectorByteNonFaultingZeroExtendToUInt32: + case NI_Sve_LoadVectorByteNonFaultingZeroExtendToUInt64: + case NI_Sve_LoadVectorInt16NonFaultingSignExtendToInt32: + case NI_Sve_LoadVectorInt16NonFaultingSignExtendToInt64: + case NI_Sve_LoadVectorInt16NonFaultingSignExtendToUInt32: + case NI_Sve_LoadVectorInt16NonFaultingSignExtendToUInt64: + case NI_Sve_LoadVectorInt32NonFaultingSignExtendToInt64: + case NI_Sve_LoadVectorInt32NonFaultingSignExtendToUInt64: + case NI_Sve_LoadVectorNonFaulting: + case NI_Sve_LoadVectorSByteNonFaultingSignExtendToInt16: + case NI_Sve_LoadVectorSByteNonFaultingSignExtendToInt32: + case NI_Sve_LoadVectorSByteNonFaultingSignExtendToInt64: + case NI_Sve_LoadVectorSByteNonFaultingSignExtendToUInt16: + case NI_Sve_LoadVectorSByteNonFaultingSignExtendToUInt32: + case NI_Sve_LoadVectorSByteNonFaultingSignExtendToUInt64: + case NI_Sve_LoadVectorUInt16NonFaultingZeroExtendToInt32: + case NI_Sve_LoadVectorUInt16NonFaultingZeroExtendToInt64: + case NI_Sve_LoadVectorUInt16NonFaultingZeroExtendToUInt32: + case NI_Sve_LoadVectorUInt16NonFaultingZeroExtendToUInt64: + case NI_Sve_LoadVectorUInt32NonFaultingZeroExtendToInt64: + case NI_Sve_LoadVectorUInt32NonFaultingZeroExtendToUInt64: addr = Op(2); break; @@ -28602,6 +28636,7 @@ bool GenTreeHWIntrinsic::OperIsMemoryStore(GenTree** pAddr) const case NI_Sve_Scatter32BitWithByteOffsetsNarrowing: case NI_Sve_Scatter8BitNarrowing: case NI_Sve_Scatter8BitWithByteOffsetsNarrowing: + case NI_Sve_ScatterWithByteOffsets: addr = Op(2); break; #endif // TARGET_ARM64 @@ -30872,47 +30907,9 @@ var_types GenTreeHWIntrinsic::GetLookupTypeForCmpOp( var_types lookupType = type; #if defined(TARGET_XARCH) - if (reverseCond) - { - oper = ReverseRelop(oper); - } - - switch (oper) + if ((simdSize == 64) || comp->canUseEvexEncoding()) { - case GT_EQ: - { - if (simdSize == 64) - { - lookupType = TYP_MASK; - } - break; - } - - case GT_GE: - case GT_LE: - case GT_NE: - { - if ((simdSize == 64) || (varTypeIsIntegral(simdBaseType) && comp->canUseEvexEncoding())) - { - lookupType = TYP_MASK; - } - break; - } - - case GT_GT: - case GT_LT: - { - if ((simdSize == 64) || (varTypeIsUnsigned(simdBaseType) && comp->canUseEvexEncoding())) - { - lookupType = TYP_MASK; - } - break; - } - - default: - { - unreached(); - } + lookupType = TYP_MASK; } #endif // TARGET_XARCH @@ -32109,6 +32106,15 @@ bool GenTree::CanDivOrModPossiblyOverflow(Compiler* comp) const return true; } +//------------------------------------------------------------------------ +// gtFoldExprHWIntrinsic: Attempt to fold a HWIntrinsic +// +// Arguments: +// tree - HWIntrinsic to fold +// +// Return Value: +// folded expression if it could be folded, else the original tree +// #if defined(FEATURE_HW_INTRINSICS) GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) { @@ -32252,7 +32258,8 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) // We shouldn't find AND_NOT nodes since it should only be produced in lowering assert(oper != GT_AND_NOT); -#if defined(FEATURE_MASKED_HW_INTRINSICS) && defined(TARGET_XARCH) +#ifdef FEATURE_MASKED_HW_INTRINSICS +#ifdef TARGET_XARCH if (GenTreeHWIntrinsic::OperIsBitwiseHWIntrinsic(oper)) { // Comparisons that produce masks lead to more verbose trees than @@ -32262,20 +32269,15 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) // fold the unnecessary back and forth conversions away where possible. genTreeOps effectiveOper = oper; - GenTree* actualOp2 = op2; - - if (oper == GT_NOT) - { - assert(op2 == nullptr); - op2 = op1; - } // We need both operands to be ConvertMaskToVector in // order to optimize this to a direct mask operation if (op1->OperIsConvertMaskToVector()) { - if (!op2->OperIsHWIntrinsic()) + assert((oper == GT_NOT) == (op2 == nullptr)); + + if ((op2 != nullptr) && !op2->OperIsHWIntrinsic()) { if ((oper == GT_XOR) && op2->IsVectorAllBitsSet()) { @@ -32283,19 +32285,18 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) // some platforms don't have direct support for ~op1 effectiveOper = GT_NOT; - op2 = op1; } } - if (op2->OperIsConvertMaskToVector()) + if ((effectiveOper == GT_NOT) || op2->OperIsConvertMaskToVector()) { GenTreeHWIntrinsic* cvtOp1 = op1->AsHWIntrinsic(); - GenTreeHWIntrinsic* cvtOp2 = op2->AsHWIntrinsic(); + GenTreeHWIntrinsic* cvtOp2 = (effectiveOper == GT_NOT) ? cvtOp1 : op2->AsHWIntrinsic(); - unsigned simdBaseTypeSize = genTypeSize(simdBaseType); + var_types op1SimdBaseType = cvtOp1->GetSimdBaseType(); + var_types op2SimdBaseType = cvtOp2->GetSimdBaseType(); - if ((genTypeSize(cvtOp1->GetSimdBaseType()) == simdBaseTypeSize) && - (genTypeSize(cvtOp2->GetSimdBaseType()) == simdBaseTypeSize)) + if (genTypeSize(op1SimdBaseType) == genTypeSize(op2SimdBaseType)) { // We need both operands to be the same kind of mask; otherwise // the bitwise operation can differ in how it performs @@ -32348,6 +32349,12 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) tree->gtFlags &= ~GTF_REVERSE_OPS; } + // The bitwise operation is likely normalized to int or uint, while + // the underlying convert ops may be a small type. We need to preserve + // such a small type since that indicates how many elements are in the mask. + simdBaseJitType = cvtOp1->GetSimdBaseJitType(); + tree->SetSimdBaseJitType(simdBaseJitType); + tree->gtType = TYP_MASK; DEBUG_DESTROY_NODE(op1); @@ -32356,9 +32363,9 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) tree->Op(2) = cvtOp2->Op(1); } - if (actualOp2 != nullptr) + if (op2 != nullptr) { - DEBUG_DESTROY_NODE(actualOp2); + DEBUG_DESTROY_NODE(op2); } tree->SetMorphed(this); @@ -32370,46 +32377,75 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) } } } -#endif // FEATURE_MASKED_HW_INTRINSICS && TARGET_XARCH - - switch (ni) +#elif defined(TARGET_ARM64) + // Check if the tree can be folded into a mask variant + if (HWIntrinsicInfo::HasAllMaskVariant(tree->GetHWIntrinsicId())) { - // There's certain IR simplifications that are possible and which - // unblock other constant folding, so do those early here. + NamedIntrinsic maskVariant = HWIntrinsicInfo::GetMaskVariant(tree->GetHWIntrinsicId()); -#if defined(TARGET_XARCH) - case NI_AVX_Compare: - case NI_AVX512_Compare: - case NI_AVX_CompareScalar: - { - assert(tree->GetOperandCount() == 3); + assert(opCount == (size_t)HWIntrinsicInfo::lookupNumArgs(maskVariant)); - if (!op3->IsCnsIntOrI()) + // Check all operands are valid + bool canFold = true; + if (ni == NI_Sve_ConditionalSelect) + { + assert(varTypeIsMask(op1)); + canFold = (op2->OperIsConvertMaskToVector() && op3->OperIsConvertMaskToVector()); + } + else + { + for (size_t i = 1; i <= opCount && canFold; i++) { - break; + canFold &= tree->Op(i)->OperIsConvertMaskToVector(); } + } - FloatComparisonMode mode = static_cast(op3->AsIntConCommon()->IntegralValue()); - NamedIntrinsic id = HWIntrinsicInfo::lookupIdForFloatComparisonMode(ni, mode, simdBaseType, simdSize); - - if (id == ni) + if (canFold) + { + // Convert all the operands to masks + for (size_t i = 1; i <= opCount; i++) { - break; + if (tree->Op(i)->OperIsConvertMaskToVector()) + { + // Replace with op1. + tree->Op(i) = tree->Op(i)->AsHWIntrinsic()->Op(1); + } + else if (tree->Op(i)->IsVectorZero()) + { + // Replace the vector of zeroes with a mask of zeroes. + tree->Op(i) = gtNewSimdFalseMaskByteNode(); + tree->Op(i)->SetMorphed(this); + } + assert(varTypeIsMask(tree->Op(i))); } - tree->ResetHWIntrinsicId(id, op1, op2); - DEBUG_DESTROY_NODE(op3); + // Switch to the mask variant + switch (opCount) + { + case 1: + tree->ResetHWIntrinsicId(maskVariant, tree->Op(1)); + break; + case 2: + tree->ResetHWIntrinsicId(maskVariant, tree->Op(1), tree->Op(2)); + break; + case 3: + tree->ResetHWIntrinsicId(maskVariant, this, tree->Op(1), tree->Op(2), tree->Op(3)); + break; + default: + unreached(); + } + tree->gtType = TYP_MASK; tree->SetMorphed(this); - return gtFoldExprHWIntrinsic(tree); - } -#endif // TARGET_XARCH - - default: - { - break; + tree = gtNewSimdCvtMaskToVectorNode(retType, tree, simdBaseJitType, simdSize)->AsHWIntrinsic(); + tree->SetMorphed(this); + op1 = tree->Op(1); + op2 = nullptr; + op3 = nullptr; } } +#endif // TARGET_ARM64 +#endif // FEATURE_MASKED_HW_INTRINSICS GenTree* cnsNode = nullptr; GenTree* otherNode = nullptr; @@ -32419,12 +32455,23 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) cnsNode = op1; otherNode = op2; } - else if ((op2 != nullptr) && op2->OperIsConst()) + else if (op2 != nullptr) { - cnsNode = op2; - otherNode = op1; + if (op2->OperIsConst()) + { + cnsNode = op2; + otherNode = op1; + } + else if (op3 != nullptr) + { + if (op3->OperIsConst()) + { + cnsNode = op3; + } + } } - else + + if (cnsNode == nullptr) { // No constants, so nothing to fold return tree; @@ -32432,11 +32479,8 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) GenTree* resultNode = tree; - if (otherNode == nullptr) + if (opCount == 1) { - assert(op2 == nullptr); - assert(op3 == nullptr); - if (oper != GT_NONE) { if (varTypeIsMask(retType)) @@ -32470,6 +32514,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 @@ -32652,654 +32768,826 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) break; } - default: +#ifdef TARGET_ARM64 + case NI_ArmBase_ReverseElementBits: { - break; - } - } - } - } - else if (otherNode->OperIsConst()) - { - if (oper != GT_NONE) - { - assert(op3 == nullptr); + assert(!varTypeIsSmall(retType) && !varTypeIsLong(retType)); - if (varTypeIsMask(retType)) - { - if (varTypeIsMask(cnsNode)) + int32_t value = static_cast(cnsNode->AsIntConCommon()->IconValue()); + uint32_t result = BitOperations::ReverseBits(static_cast(value)); + + cnsNode->AsIntConCommon()->SetIconValue(static_cast(result)); + resultNode = cnsNode; + break; + } + + case NI_ArmBase_Arm64_ReverseElementBits: { - cnsNode->AsMskCon()->EvaluateBinaryInPlace(oper, isScalar, simdBaseType, simdSize, - otherNode->AsMskCon()); + assert(varTypeIsLong(retType)); + + int64_t value = cnsNode->AsIntConCommon()->IntegralValue(); + uint64_t result = BitOperations::ReverseBits(static_cast(value)); + + cnsNode->AsIntConCommon()->SetIntegralValue(static_cast(result)); + resultNode = cnsNode; + break; } - else +#endif // TARGET_ARM64 + +#ifdef TARGET_XARCH + case NI_AVX2_TrailingZeroCount: { - cnsNode->AsVecCon()->EvaluateBinaryInPlace(oper, isScalar, simdBaseType, otherNode->AsVecCon()); + assert(!varTypeIsSmall(retType) && !varTypeIsLong(retType)); + + int32_t value = static_cast(cnsNode->AsIntConCommon()->IconValue()); + uint32_t result = BitOperations::TrailingZeroCount(static_cast(value)); + + cnsNode->AsIntConCommon()->SetIconValue(static_cast(result)); + resultNode = cnsNode; + break; } - } - else - { -#if defined(TARGET_XARCH) - if ((oper == GT_LSH) || (oper == GT_RSH) || (oper == GT_RSZ)) + + case NI_AVX2_X64_TrailingZeroCount: { - if (otherNode->TypeIs(TYP_SIMD16)) - { - if (!HWIntrinsicInfo::IsVariableShift(ni)) - { - // The xarch shift instructions support taking the shift amount as - // a simd16, in which case they take the shift amount from the lower - // 64-bits. + assert(varTypeIsLong(retType)); - int64_t shiftAmount = otherNode->AsVecCon()->GetElementIntegral(TYP_LONG, 0); + int64_t value = cnsNode->AsIntConCommon()->IntegralValue(); + uint32_t result = BitOperations::TrailingZeroCount(static_cast(value)); - if (static_cast(shiftAmount) >= - (static_cast(genTypeSize(simdBaseType)) * BITS_PER_BYTE)) - { - // Set to -1 to indicate an explicit overshift - shiftAmount = -1; - } + cnsNode->AsIntConCommon()->SetIntegralValue(static_cast(result)); + resultNode = cnsNode; + break; + } - // Ensure we broadcast to the right vector size - otherNode->gtType = retType; + case NI_SSE42_PopCount: + { + assert(!varTypeIsSmall(retType) && !varTypeIsLong(retType)); - otherNode->AsVecCon()->EvaluateBroadcastInPlace(simdBaseType, shiftAmount); - } - } + int32_t value = static_cast(cnsNode->AsIntConCommon()->IconValue()); + uint32_t result = BitOperations::PopCount(static_cast(value)); + + cnsNode->AsIntConCommon()->SetIconValue(static_cast(result)); + resultNode = cnsNode; + break; } -#endif // TARGET_XARCH - if (otherNode->IsIntegralConst()) + case NI_SSE42_X64_PopCount: { - int64_t scalar = otherNode->AsIntConCommon()->IntegralValue(); + assert(varTypeIsLong(retType)); - otherNode = gtNewVconNode(retType); - otherNode->AsVecCon()->EvaluateBroadcastInPlace(simdBaseType, scalar); + int64_t value = cnsNode->AsIntConCommon()->IntegralValue(); + uint32_t result = BitOperations::PopCount(static_cast(value)); + + cnsNode->AsIntConCommon()->SetIntegralValue(static_cast(result)); + resultNode = cnsNode; + break; } - cnsNode->AsVecCon()->EvaluateBinaryInPlace(oper, isScalar, simdBaseType, otherNode->AsVecCon()); - } - resultNode = cnsNode; - } - else - { - switch (ni) - { - case NI_Vector128_GetElement: -#ifdef TARGET_ARM64 - case NI_Vector64_GetElement: -#else - case NI_Vector256_GetElement: - case NI_Vector512_GetElement: -#endif + case NI_X86Base_BitScanForward: { - assert(op3 == nullptr); - uint32_t index = static_cast(otherNode->AsIntConCommon()->IconValue()); + assert(!varTypeIsSmall(retType) && !varTypeIsLong(retType)); + + int32_t value = static_cast(cnsNode->AsIntConCommon()->IconValue()); - if (index >= GenTreeVecCon::ElementCount(simdSize, simdBaseType)) + if (value == 0) { - // Nothing to fold for out of range indexes + // bsf is undefined for 0 break; } + uint32_t result = BitOperations::BitScanForward(static_cast(value)); - var_types simdType = getSIMDTypeForSize(simdSize); + cnsNode->AsIntConCommon()->SetIconValue(static_cast(result)); + resultNode = cnsNode; + break; + } - if (varTypeIsFloating(retType)) - { - double result = cnsNode->AsVecCon()->GetElementFloating(simdBaseType, index); + case NI_X86Base_X64_BitScanForward: + { + assert(varTypeIsLong(retType)); - resultNode = gtNewDconNode(result, retType); - } - else - { - assert(varTypeIsIntegral(retType)); - int64_t result = cnsNode->AsVecCon()->GetElementIntegral(simdBaseType, index); + int64_t value = cnsNode->AsIntConCommon()->IntegralValue(); - if (varTypeIsLong(retType)) - { - resultNode = gtNewLconNode(result); - } - else - { - resultNode = gtNewIconNode(static_cast(result), retType); - } + if (value == 0) + { + // bsf is undefined for 0 + break; } + uint32_t result = BitOperations::BitScanForward(static_cast(value)); + + cnsNode->AsIntConCommon()->SetIntegralValue(static_cast(result)); + resultNode = cnsNode; break; } -#ifdef TARGET_ARM64 - case NI_AdvSimd_MultiplyByScalar: - case NI_AdvSimd_Arm64_MultiplyByScalar: + case NI_X86Base_BitScanReverse: { - assert(op3 == nullptr); - - // MultiplyByScalar takes a vector as the second operand but only utilizes element 0 - // We need to extract it and then functionally broadcast it up for the evaluation to - // work as expected. Ensuring we broadcast up to the target vector size. + assert(!varTypeIsSmall(retType) && !varTypeIsLong(retType)); - otherNode->gtType = retType; + int32_t value = static_cast(cnsNode->AsIntConCommon()->IconValue()); - if (varTypeIsFloating(simdBaseType)) + if (value == 0) { - double scalar = otherNode->AsVecCon()->ToScalarFloating(simdBaseType); - otherNode->AsVecCon()->EvaluateBroadcastInPlace(simdBaseType, scalar); - } - else - { - assert(varTypeIsIntegral(simdBaseType)); - int64_t scalar = otherNode->AsVecCon()->ToScalarIntegral(simdBaseType); - otherNode->AsVecCon()->EvaluateBroadcastInPlace(simdBaseType, scalar); + // bsr is undefined for 0 + break; } + uint32_t result = BitOperations::BitScanReverse(static_cast(value)); - cnsNode->AsVecCon()->EvaluateBinaryInPlace(GT_MUL, isScalar, simdBaseType, otherNode->AsVecCon()); + cnsNode->AsIntConCommon()->SetIconValue(static_cast(result)); resultNode = cnsNode; break; } -#endif - case NI_Vector128_WithElement: -#ifdef TARGET_ARM64 - case NI_Vector64_WithElement: -#else - case NI_Vector256_WithElement: - case NI_Vector512_WithElement: -#endif + case NI_X86Base_X64_BitScanReverse: { - if (!op3->OperIsConst()) + assert(varTypeIsLong(retType)); + + int64_t value = cnsNode->AsIntConCommon()->IntegralValue(); + + if (value == 0) { + // bsr is undefined for 0 break; } + uint32_t result = BitOperations::BitScanReverse(static_cast(value)); - uint32_t index = static_cast(op2->AsIntConCommon()->IconValue()); + cnsNode->AsIntConCommon()->SetIntegralValue(static_cast(result)); + resultNode = cnsNode; + break; + } +#endif // TARGET_XARCH - if (index >= GenTreeVecCon::ElementCount(simdSize, simdBaseType)) + default: + { + break; + } + } + } + } + else if (opCount == 2) + { + if (otherNode->OperIsConst()) + { + if (oper != GT_NONE) + { + if (varTypeIsMask(retType)) + { + if (varTypeIsMask(cnsNode)) { - // Nothing to fold for out of range indexes - break; + cnsNode->AsMskCon()->EvaluateBinaryInPlace(oper, isScalar, simdBaseType, simdSize, + otherNode->AsMskCon()); } + else + { + cnsNode->AsVecCon()->EvaluateBinaryInPlace(oper, isScalar, simdBaseType, otherNode->AsVecCon()); + } + } + else + { +#if defined(TARGET_XARCH) + if ((oper == GT_LSH) || (oper == GT_RSH) || (oper == GT_RSZ)) + { + if (otherNode->TypeIs(TYP_SIMD16)) + { + if (!HWIntrinsicInfo::IsVariableShift(ni)) + { + // The xarch shift instructions support taking the shift amount as + // a simd16, in which case they take the shift amount from the lower + // 64-bits. - var_types simdType = getSIMDTypeForSize(simdSize); + int64_t shiftAmount = otherNode->AsVecCon()->GetElementIntegral(TYP_LONG, 0); - if (varTypeIsFloating(simdBaseType)) + if (static_cast(shiftAmount) >= + (static_cast(genTypeSize(simdBaseType)) * BITS_PER_BYTE)) + { + // Set to -1 to indicate an explicit overshift + shiftAmount = -1; + } + + // Ensure we broadcast to the right vector size + otherNode->gtType = retType; + + otherNode->AsVecCon()->EvaluateBroadcastInPlace(simdBaseType, shiftAmount); + } + } + } +#endif // TARGET_XARCH + + if (otherNode->IsIntegralConst()) { - double value = op3->AsDblCon()->DconValue(); - cnsNode->AsVecCon()->SetElementFloating(simdBaseType, index, value); - resultNode = cnsNode; + int64_t scalar = otherNode->AsIntConCommon()->IntegralValue(); + + otherNode = gtNewVconNode(retType); + otherNode->AsVecCon()->EvaluateBroadcastInPlace(simdBaseType, scalar); } - else + + cnsNode->AsVecCon()->EvaluateBinaryInPlace(oper, isScalar, simdBaseType, otherNode->AsVecCon()); + } + resultNode = cnsNode; + } + else + { + switch (ni) + { + case NI_Vector128_GetElement: +#ifdef TARGET_ARM64 + case NI_Vector64_GetElement: +#else + case NI_Vector256_GetElement: + case NI_Vector512_GetElement: +#endif + { + uint32_t index = static_cast(otherNode->AsIntConCommon()->IconValue()); + + if (index >= GenTreeVecCon::ElementCount(simdSize, simdBaseType)) + { + // Nothing to fold for out of range indexes + break; + } + + var_types simdType = getSIMDTypeForSize(simdSize); + + if (varTypeIsFloating(retType)) + { + double result = cnsNode->AsVecCon()->GetElementFloating(simdBaseType, index); + + resultNode = gtNewDconNode(result, retType); + } + else + { + assert(varTypeIsIntegral(retType)); + int64_t result = cnsNode->AsVecCon()->GetElementIntegral(simdBaseType, index); + + if (varTypeIsLong(retType)) + { + resultNode = gtNewLconNode(result); + } + else + { + resultNode = gtNewIconNode(static_cast(result), retType); + } + } + break; + } + +#ifdef TARGET_ARM64 + case NI_AdvSimd_MultiplyByScalar: + case NI_AdvSimd_Arm64_MultiplyByScalar: { - assert(varTypeIsIntegral(simdBaseType)); - int64_t value = op3->AsIntConCommon()->IntegralValue(); - cnsNode->AsVecCon()->SetElementIntegral(simdBaseType, index, value); + // MultiplyByScalar takes a vector as the second operand but only utilizes element 0 + // We need to extract it and then functionally broadcast it up for the evaluation to + // work as expected. Ensuring we broadcast up to the target vector size. + + otherNode->gtType = retType; + + if (varTypeIsFloating(simdBaseType)) + { + double scalar = otherNode->AsVecCon()->ToScalarFloating(simdBaseType); + otherNode->AsVecCon()->EvaluateBroadcastInPlace(simdBaseType, scalar); + } + else + { + assert(varTypeIsIntegral(simdBaseType)); + int64_t scalar = otherNode->AsVecCon()->ToScalarIntegral(simdBaseType); + otherNode->AsVecCon()->EvaluateBroadcastInPlace(simdBaseType, scalar); + } + + cnsNode->AsVecCon()->EvaluateBinaryInPlace(GT_MUL, isScalar, simdBaseType, + otherNode->AsVecCon()); resultNode = cnsNode; + break; } - break; - } +#endif #ifdef TARGET_ARM64 - case NI_Vector128_WithLower: - { - assert(retType == TYP_SIMD16); - assert(cnsNode->TypeIs(TYP_SIMD16)); - assert(otherNode->TypeIs(TYP_SIMD8)); - cnsNode->AsVecCon()->gtSimd16Val.v64[0] = otherNode->AsVecCon()->gtSimd8Val; + case NI_Vector128_WithLower: + { + assert(retType == TYP_SIMD16); + assert(cnsNode->TypeIs(TYP_SIMD16)); + assert(otherNode->TypeIs(TYP_SIMD8)); + cnsNode->AsVecCon()->gtSimd16Val.v64[0] = otherNode->AsVecCon()->gtSimd8Val; - resultNode = cnsNode; - break; - } + resultNode = cnsNode; + break; + } #else - case NI_Vector256_WithLower: - { - assert(retType == TYP_SIMD32); - assert(cnsNode->TypeIs(TYP_SIMD32)); - assert(otherNode->TypeIs(TYP_SIMD16)); - cnsNode->AsVecCon()->gtSimd32Val.v128[0] = otherNode->AsVecCon()->gtSimd16Val; + case NI_Vector256_WithLower: + { + assert(retType == TYP_SIMD32); + assert(cnsNode->TypeIs(TYP_SIMD32)); + assert(otherNode->TypeIs(TYP_SIMD16)); + cnsNode->AsVecCon()->gtSimd32Val.v128[0] = otherNode->AsVecCon()->gtSimd16Val; - resultNode = cnsNode; - break; - } + resultNode = cnsNode; + break; + } - case NI_Vector512_WithLower: - { - assert(retType == TYP_SIMD64); - assert(cnsNode->TypeIs(TYP_SIMD64)); - assert(otherNode->TypeIs(TYP_SIMD32)); - cnsNode->AsVecCon()->gtSimd64Val.v256[0] = otherNode->AsVecCon()->gtSimd32Val; + case NI_Vector512_WithLower: + { + assert(retType == TYP_SIMD64); + assert(cnsNode->TypeIs(TYP_SIMD64)); + assert(otherNode->TypeIs(TYP_SIMD32)); + cnsNode->AsVecCon()->gtSimd64Val.v256[0] = otherNode->AsVecCon()->gtSimd32Val; - resultNode = cnsNode; - break; - } + resultNode = cnsNode; + break; + } #endif #ifdef TARGET_ARM64 - case NI_Vector128_WithUpper: - { - assert(retType == TYP_SIMD16); - assert(cnsNode->TypeIs(TYP_SIMD16)); - assert(otherNode->TypeIs(TYP_SIMD8)); - cnsNode->AsVecCon()->gtSimd16Val.v64[1] = otherNode->AsVecCon()->gtSimd8Val; + case NI_Vector128_WithUpper: + { + assert(retType == TYP_SIMD16); + assert(cnsNode->TypeIs(TYP_SIMD16)); + assert(otherNode->TypeIs(TYP_SIMD8)); + cnsNode->AsVecCon()->gtSimd16Val.v64[1] = otherNode->AsVecCon()->gtSimd8Val; - resultNode = cnsNode; - break; - } + resultNode = cnsNode; + break; + } #else - case NI_Vector256_WithUpper: - { - assert(retType == TYP_SIMD32); - assert(cnsNode->TypeIs(TYP_SIMD32)); - assert(otherNode->TypeIs(TYP_SIMD16)); - cnsNode->AsVecCon()->gtSimd32Val.v128[1] = otherNode->AsVecCon()->gtSimd16Val; + case NI_Vector256_WithUpper: + { + assert(retType == TYP_SIMD32); + assert(cnsNode->TypeIs(TYP_SIMD32)); + assert(otherNode->TypeIs(TYP_SIMD16)); + cnsNode->AsVecCon()->gtSimd32Val.v128[1] = otherNode->AsVecCon()->gtSimd16Val; - resultNode = cnsNode; - break; - } + resultNode = cnsNode; + break; + } - case NI_Vector512_WithUpper: - { - assert(retType == TYP_SIMD64); - assert(cnsNode->TypeIs(TYP_SIMD64)); - assert(otherNode->TypeIs(TYP_SIMD32)); - cnsNode->AsVecCon()->gtSimd64Val.v256[1] = otherNode->AsVecCon()->gtSimd32Val; + case NI_Vector512_WithUpper: + { + assert(retType == TYP_SIMD64); + assert(cnsNode->TypeIs(TYP_SIMD64)); + assert(otherNode->TypeIs(TYP_SIMD32)); + cnsNode->AsVecCon()->gtSimd64Val.v256[1] = otherNode->AsVecCon()->gtSimd32Val; - resultNode = cnsNode; - break; - } + resultNode = cnsNode; + break; + } #endif - case NI_Vector128_op_Equality: + case NI_Vector128_op_Equality: #if defined(TARGET_ARM64) - case NI_Vector64_op_Equality: + case NI_Vector64_op_Equality: #elif defined(TARGET_XARCH) - case NI_Vector256_op_Equality: - case NI_Vector512_op_Equality: + case NI_Vector256_op_Equality: + case NI_Vector512_op_Equality: #endif // !TARGET_ARM64 && !TARGET_XARCH - { - cnsNode->AsVecCon()->EvaluateBinaryInPlace(GT_EQ, isScalar, simdBaseType, otherNode->AsVecCon()); - resultNode = gtNewIconNode(cnsNode->AsVecCon()->IsAllBitsSet() ? 1 : 0, retType); - break; - } + { + cnsNode->AsVecCon()->EvaluateBinaryInPlace(GT_EQ, isScalar, simdBaseType, + otherNode->AsVecCon()); + resultNode = gtNewIconNode(cnsNode->AsVecCon()->IsAllBitsSet() ? 1 : 0, retType); + break; + } - case NI_Vector128_op_Inequality: + case NI_Vector128_op_Inequality: #if defined(TARGET_ARM64) - case NI_Vector64_op_Inequality: + case NI_Vector64_op_Inequality: #elif defined(TARGET_XARCH) - case NI_Vector256_op_Inequality: - case NI_Vector512_op_Inequality: + case NI_Vector256_op_Inequality: + case NI_Vector512_op_Inequality: #endif // !TARGET_ARM64 && !TARGET_XARCH - { - cnsNode->AsVecCon()->EvaluateBinaryInPlace(GT_NE, isScalar, simdBaseType, otherNode->AsVecCon()); - resultNode = gtNewIconNode(cnsNode->AsVecCon()->IsZero() ? 0 : 1, retType); - break; - } + { + cnsNode->AsVecCon()->EvaluateBinaryInPlace(GT_NE, isScalar, simdBaseType, + otherNode->AsVecCon()); + resultNode = gtNewIconNode(cnsNode->AsVecCon()->IsZero() ? 0 : 1, retType); + break; + } - default: - { - break; + default: + { + break; + } } } } - } - else if (op3 == nullptr) - { - if (isScalar) + else { - // We don't support folding for scalars when only one input is constant - // because it means one value is computed and the remaining values are - // either zeroed or preserved based on the underlying target architecture - oper = GT_NONE; - } + if (isScalar) + { + // We don't support folding for scalars when only one input is constant + // because it means one value is computed and the remaining values are + // either zeroed or preserved based on the underlying target architecture + oper = GT_NONE; + } + + // For mask nodes in particular, the foldings below are done under the presumption + // that we only produce something like `AddMask(op1, op2)` if op1 and op2 are compatible + // masks. On xarch, for example, this means that it'd be adding 8, 16, 32, or 64-bits + // together with the same size. We wouldn't ever encounter something like an 8 and 16 bit + // masks being added. This ensures that we don't end up with a case where folding would + // cause a different result to be produced, such as because the remaining upper bits are + // no longer zeroed. - // For mask nodes in particular, the foldings below are done under the presumption - // that we only produce something like `AddMask(op1, op2)` if op1 and op2 are compatible - // masks. On xarch, for example, this means that it'd be adding 8, 16, 32, or 64-bits - // together with the same size. We wouldn't ever encounter something like an 8 and 16 bit - // masks being added. This ensures that we don't end up with a case where folding would - // cause a different result to be produced, such as because the remaining upper bits are - // no longer zeroed. + switch (oper) + { + case GT_ADD: + { + if (varTypeIsMask(retType)) + { + // Handle `x + 0 == x` and `0 + x == x` + if (cnsNode->IsMaskZero()) + { + resultNode = otherNode; + } + break; + } + + if (varTypeIsFloating(simdBaseType)) + { + // Handle `x + NaN == NaN` and `NaN + x == NaN` + // This is safe for all floats since we do not fault for sNaN + + if (cnsNode->IsVectorNaN(simdBaseType)) + { + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } + + // Handle `x + -0 == x` and `-0 + x == x` + + if (cnsNode->IsVectorNegativeZero(simdBaseType)) + { + resultNode = otherNode; + break; + } + + // We cannot handle `x + 0 == x` or `0 + x == x` since `-0 + 0 == 0` + break; + } - switch (oper) - { - case GT_ADD: - { - if (varTypeIsMask(retType)) - { // Handle `x + 0 == x` and `0 + x == x` - if (cnsNode->IsMaskZero()) + if (cnsNode->IsVectorZero()) { resultNode = otherNode; } break; } - if (varTypeIsFloating(simdBaseType)) + case GT_AND: { - // Handle `x + NaN == NaN` and `NaN + x == NaN` - // This is safe for all floats since we do not fault for sNaN - - if (cnsNode->IsVectorNaN(simdBaseType)) + if (varTypeIsMask(retType)) { - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; - } - - // Handle `x + -0 == x` and `-0 + x == x` + // Handle `x & 0 == 0` and `0 & x == 0` + if (cnsNode->IsMaskZero()) + { + resultNode = otherNode; + break; + } - if (cnsNode->IsVectorNegativeZero(simdBaseType)) - { - resultNode = otherNode; + // Handle `x & AllBitsSet == x` and `AllBitsSet & x == x` + if (cnsNode->IsMaskAllBitsSet()) + { + resultNode = otherNode; + } break; } - // We cannot handle `x + 0 == x` or `0 + x == x` since `-0 + 0 == 0` - break; - } - - // Handle `x + 0 == x` and `0 + x == x` - if (cnsNode->IsVectorZero()) - { - resultNode = otherNode; - } - break; - } - - case GT_AND: - { - if (varTypeIsMask(retType)) - { // Handle `x & 0 == 0` and `0 & x == 0` - if (cnsNode->IsMaskZero()) + if (cnsNode->IsVectorZero()) { - resultNode = otherNode; + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); break; } // Handle `x & AllBitsSet == x` and `AllBitsSet & x == x` - if (cnsNode->IsMaskAllBitsSet()) + if (cnsNode->IsVectorAllBitsSet()) { resultNode = otherNode; } break; } - // Handle `x & 0 == 0` and `0 & x == 0` - if (cnsNode->IsVectorZero()) + case GT_DIV: { - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; - } + assert(!varTypeIsMask(retType)); - // Handle `x & AllBitsSet == x` and `AllBitsSet & x == x` - if (cnsNode->IsVectorAllBitsSet()) - { - resultNode = otherNode; - } - break; - } + if (varTypeIsFloating(simdBaseType)) + { + // Handle `x / NaN == NaN` and `NaN / x == NaN` + // This is safe for all floats since we do not fault for sNaN - case GT_DIV: - { - if (varTypeIsFloating(simdBaseType)) - { - // Handle `x / NaN == NaN` and `NaN / x == NaN` + if (cnsNode->IsVectorNaN(simdBaseType)) + { + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } + } + + // Handle `x / 1 == x`. // This is safe for all floats since we do not fault for sNaN - if (cnsNode->IsVectorNaN(simdBaseType)) + if (cnsNode != op2) { - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); break; } - } - // Handle `x / 1 == x`. - // This is safe for all floats since we do not fault for sNaN + if (!cnsNode->IsVectorBroadcast(simdBaseType)) + { + break; + } - if (cnsNode != op2) - { + if (cnsNode->AsVecCon()->IsScalarOne(simdBaseType)) + { + resultNode = otherNode; + } break; } - if (!cnsNode->IsVectorBroadcast(simdBaseType)) + case GT_EQ: { - break; - } + if (varTypeIsFloating(simdBaseType)) + { + // Handle `(x == NaN) == false` and `(NaN == x) == false` for floating-point types + if (cnsNode->IsVectorNaN(simdBaseType)) + { + int64_t zero = 0; + cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } + } + else if (otherNode->OperIsHWIntrinsic()) + { + GenTreeHWIntrinsic* otherIntrinsic = otherNode->AsHWIntrinsic(); + NamedIntrinsic otherIntrinsicId = otherIntrinsic->GetHWIntrinsicId(); - if (cnsNode->AsVecCon()->IsScalarOne(simdBaseType)) - { - resultNode = otherNode; - } - break; - } + if (HWIntrinsicInfo::ReturnsPerElementMask(otherIntrinsicId) && + (genTypeSize(simdBaseType) == genTypeSize(otherIntrinsic->GetSimdBaseType()))) + { + // This optimization is only safe if we know the other node produces + // AllBitsSet or Zero per element and if the outer comparison is the + // same size as what the other node produces for its mask - case GT_EQ: - { - if (varTypeIsFloating(simdBaseType)) - { - // Handle `(x == NaN) == false` and `(NaN == x) == false` for floating-point types - if (cnsNode->IsVectorNaN(simdBaseType)) - { - int64_t zero = 0; - cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; + // Handle `(Mask == AllBitsSet) == Mask` and `(AllBitsSet == Mask) == Mask` for integrals + if (cnsNode->IsVectorAllBitsSet()) + { + resultNode = otherNode; + break; + } + } } + break; } - break; - } - case GT_GT: - { - if (varTypeIsUnsigned(simdBaseType)) + case GT_GT: { - // Handle `(0 > x) == false` for unsigned types. - if ((cnsNode == op1) && cnsNode->IsVectorZero()) + if (varTypeIsUnsigned(simdBaseType)) { - int64_t zero = 0; - cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; + // Handle `(0 > x) == false` for unsigned types. + if ((cnsNode == op1) && cnsNode->IsVectorZero()) + { + int64_t zero = 0; + cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } } - } - else if (varTypeIsFloating(simdBaseType)) - { - // Handle `(x > NaN) == false` and `(NaN > x) == false` for floating-point types - if (cnsNode->IsVectorNaN(simdBaseType)) + else if (varTypeIsFloating(simdBaseType)) { - int64_t zero = 0; - cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; + // Handle `(x > NaN) == false` and `(NaN > x) == false` for floating-point types + if (cnsNode->IsVectorNaN(simdBaseType)) + { + int64_t zero = 0; + cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } } + break; } - break; - } - case GT_GE: - { - if (varTypeIsUnsigned(simdBaseType)) + case GT_GE: { - // Handle `x >= 0 == true` for unsigned types. - if ((cnsNode == op2) && cnsNode->IsVectorZero()) + if (varTypeIsUnsigned(simdBaseType)) { - int64_t allBitsSet = -1; - cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, allBitsSet); - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; + // Handle `x >= 0 == true` for unsigned types. + if ((cnsNode == op2) && cnsNode->IsVectorZero()) + { + int64_t allBitsSet = -1; + cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, allBitsSet); + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } } - } - else if (varTypeIsFloating(simdBaseType)) - { - // Handle `(x >= NaN) == false` and `(NaN >= x) == false` for floating-point types - if (cnsNode->IsVectorNaN(simdBaseType)) + else if (varTypeIsFloating(simdBaseType)) { - int64_t zero = 0; - cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; + // Handle `(x >= NaN) == false` and `(NaN >= x) == false` for floating-point types + if (cnsNode->IsVectorNaN(simdBaseType)) + { + int64_t zero = 0; + cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } } + break; } - break; - } - case GT_LT: - { - if (varTypeIsUnsigned(simdBaseType)) + case GT_LT: { - // Handle `x < 0 == false` for unsigned types. - if ((cnsNode == op2) && cnsNode->IsVectorZero()) + if (varTypeIsUnsigned(simdBaseType)) { - int64_t zero = 0; - cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; + // Handle `x < 0 == false` for unsigned types. + if ((cnsNode == op2) && cnsNode->IsVectorZero()) + { + int64_t zero = 0; + cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } } - } - else if (varTypeIsFloating(simdBaseType)) - { - // Handle `(x < NaN) == false` and `(NaN < x) == false` for floating-point types - if (cnsNode->IsVectorNaN(simdBaseType)) + else if (varTypeIsFloating(simdBaseType)) { - int64_t zero = 0; - cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; + // Handle `(x < NaN) == false` and `(NaN < x) == false` for floating-point types + if (cnsNode->IsVectorNaN(simdBaseType)) + { + int64_t zero = 0; + cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } } + break; } - break; - } - case GT_LE: - { - if (varTypeIsUnsigned(simdBaseType)) + case GT_LE: { - // Handle `0 <= x == true` for unsigned types. - if ((cnsNode == op1) && cnsNode->IsVectorZero()) + if (varTypeIsUnsigned(simdBaseType)) { - int64_t allBitsSet = -1; - cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, allBitsSet); - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; + // Handle `0 <= x == true` for unsigned types. + if ((cnsNode == op1) && cnsNode->IsVectorZero()) + { + int64_t allBitsSet = -1; + cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, allBitsSet); + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } } - } - else if (varTypeIsFloating(simdBaseType)) - { - // Handle `(x <= NaN) == false` and `(NaN <= x) == false` for floating-point types - if (cnsNode->IsVectorNaN(simdBaseType)) + else if (varTypeIsFloating(simdBaseType)) { - int64_t zero = 0; - cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; + // Handle `(x <= NaN) == false` and `(NaN <= x) == false` for floating-point types + if (cnsNode->IsVectorNaN(simdBaseType)) + { + int64_t zero = 0; + cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, zero); + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } } + break; } - break; - } - case GT_MUL: - { - if (!varTypeIsFloating(simdBaseType)) + case GT_MUL: { - // Handle `x * 0 == 0` and `0 * x == 0` - // Not safe for floating-point when x == -0.0, NaN, +Inf, -Inf - if (cnsNode->IsVectorZero()) + assert(!varTypeIsMask(retType)); + + if (!varTypeIsFloating(simdBaseType)) { - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; + // Handle `x * 0 == 0` and `0 * x == 0` + // Not safe for floating-point when x == -0.0, NaN, +Inf, -Inf + if (cnsNode->IsVectorZero()) + { + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } } - } - else - { - // Handle `x * NaN == NaN` and `NaN * x == NaN` + else + { + // Handle `x * NaN == NaN` and `NaN * x == NaN` + // This is safe for all floats since we do not fault for sNaN + + if (cnsNode->IsVectorNaN(simdBaseType)) + { + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } + + // We cannot handle `x * 0 == 0` or ` 0 * x == 0` since `-0 * 0 == -0` + // We cannot handle `x * -0 == -0` or `-0 * x == -0` since `-0 * -0 == 0` + } + + // Handle `x * 1 == x` and `1 * x == x` // This is safe for all floats since we do not fault for sNaN - if (cnsNode->IsVectorNaN(simdBaseType)) + if (!cnsNode->IsVectorBroadcast(simdBaseType)) { - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); break; } - // We cannot handle `x * 0 == 0` or ` 0 * x == 0` since `-0 * 0 == -0` - // We cannot handle `x * -0 == -0` or `-0 * x == -0` since `-0 * -0 == 0` - } - - // Handle `x * 1 == x` and `1 * x == x` - // This is safe for all floats since we do not fault for sNaN - - if (!cnsNode->IsVectorBroadcast(simdBaseType)) - { + if (cnsNode->AsVecCon()->IsScalarOne(simdBaseType)) + { + resultNode = otherNode; + } break; } - if (cnsNode->AsVecCon()->IsScalarOne(simdBaseType)) + case GT_NE: { - resultNode = otherNode; + if (varTypeIsFloating(simdBaseType)) + { + // Handle `(x != NaN) == true` and `(NaN != x) == true` for floating-point types + if (cnsNode->IsVectorNaN(simdBaseType)) + { + int64_t allBitsSet = -1; + cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, allBitsSet); + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } + } + else if (otherNode->OperIsHWIntrinsic()) + { + GenTreeHWIntrinsic* otherIntrinsic = otherNode->AsHWIntrinsic(); + NamedIntrinsic otherIntrinsicId = otherIntrinsic->GetHWIntrinsicId(); + + if (HWIntrinsicInfo::ReturnsPerElementMask(otherIntrinsicId) && + (genTypeSize(simdBaseType) == genTypeSize(otherIntrinsic->GetSimdBaseType()))) + { + // This optimization is only safe if we know the other node produces + // AllBitsSet or Zero per element and if the outer comparison is the + // same size as what the other node produces for its mask + + // Handle `(Mask != Zero) == Mask` and `(Zero != Mask) == Mask` for integral types + if (cnsNode->IsVectorZero()) + { + resultNode = otherNode; + break; + } + } + } + break; } - break; - } - case GT_NE: - { - if (varTypeIsFloating(simdBaseType)) + case GT_OR: { - // Handle `(x != NaN) == true` and `(NaN != x) == true` for floating-point types - if (cnsNode->IsVectorNaN(simdBaseType)) + if (varTypeIsMask(retType)) { - int64_t allBitsSet = -1; - cnsNode->AsVecCon()->EvaluateBroadcastInPlace(TYP_LONG, allBitsSet); - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + // Handle `x | 0 == x` and `0 | x == x` + if (cnsNode->IsMaskZero()) + { + resultNode = otherNode; + break; + } + + // Handle `x | AllBitsSet == AllBitsSet` and `AllBitsSet | x == AllBitsSet` + if (cnsNode->IsMaskAllBitsSet()) + { + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + } break; - } - } - break; - } + } - case GT_OR: - { - if (varTypeIsMask(retType)) - { // Handle `x | 0 == x` and `0 | x == x` - if (cnsNode->IsMaskZero()) + if (cnsNode->IsVectorZero()) { resultNode = otherNode; break; } // Handle `x | AllBitsSet == AllBitsSet` and `AllBitsSet | x == AllBitsSet` - if (cnsNode->IsMaskAllBitsSet()) + if (cnsNode->IsVectorAllBitsSet()) { resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); } break; } - // Handle `x | 0 == x` and `0 | x == x` - if (cnsNode->IsVectorZero()) - { - resultNode = otherNode; - break; - } - - // Handle `x | AllBitsSet == AllBitsSet` and `AllBitsSet | x == AllBitsSet` - if (cnsNode->IsVectorAllBitsSet()) + case GT_ROL: + case GT_ROR: + case GT_LSH: + case GT_RSH: + case GT_RSZ: { - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - } - break; - } + // Handle `x rol 0 == x` and `0 rol x == 0` + // Handle `x ror 0 == x` and `0 ror x == 0` + // Handle `x << 0 == x` and `0 << x == 0` + // Handle `x >> 0 == x` and `0 >> x == 0` + // Handle `x >>> 0 == x` and `0 >>> x == 0` - case GT_ROL: - case GT_ROR: - case GT_LSH: - case GT_RSH: - case GT_RSZ: - { - // Handle `x rol 0 == x` and `0 rol x == 0` - // Handle `x ror 0 == x` and `0 ror x == 0` - // Handle `x << 0 == x` and `0 << x == 0` - // Handle `x >> 0 == x` and `0 >> x == 0` - // Handle `x >>> 0 == x` and `0 >>> x == 0` + if (varTypeIsMask(retType)) + { + if (cnsNode->IsMaskZero()) + { + if (cnsNode == op2) + { + resultNode = otherNode; + } + else + { + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + } + } + else if (cnsNode->IsIntegralConst(0)) + { + assert(cnsNode == op2); + resultNode = otherNode; + } + break; + } - if (varTypeIsMask(retType)) - { - if (cnsNode->IsMaskZero()) + if (cnsNode->IsVectorZero()) { if (cnsNode == op2) { @@ -33318,205 +33606,190 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) break; } - if (cnsNode->IsVectorZero()) + case GT_SUB: { - if (cnsNode == op2) + assert(!varTypeIsMask(retType)); + + if (varTypeIsFloating(simdBaseType)) { - resultNode = otherNode; + // Handle `x - NaN == NaN` and `NaN - x == NaN` + // This is safe for all floats since we do not fault for sNaN + + if (cnsNode->IsVectorNaN(simdBaseType)) + { + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } + + // We cannot handle `x - -0 == x` since `-0 - -0 == 0` } - else + + // Handle `x - 0 == x` + if ((op2 == cnsNode) && cnsNode->IsVectorZero()) { - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + resultNode = otherNode; } + break; } - else if (cnsNode->IsIntegralConst(0)) - { - assert(cnsNode == op2); - resultNode = otherNode; - } - break; - } - case GT_SUB: - { - if (varTypeIsFloating(simdBaseType)) + case GT_XOR: { - // Handle `x - NaN == NaN` and `NaN - x == NaN` - // This is safe for all floats since we do not fault for sNaN - - if (cnsNode->IsVectorNaN(simdBaseType)) + if (varTypeIsMask(retType)) { - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + // Handle `x ^ 0 == x` and `0 ^ x == x` + if (cnsNode->IsMaskZero()) + { + resultNode = otherNode; + } break; } - // We cannot handle `x - -0 == x` since `-0 - -0 == 0` - } - - // Handle `x - 0 == x` - if ((op2 == cnsNode) && cnsNode->IsVectorZero()) - { - resultNode = otherNode; - } - break; - } - - case GT_XOR: - { - if (varTypeIsMask(retType)) - { // Handle `x ^ 0 == x` and `0 ^ x == x` - if (cnsNode->IsMaskZero()) + if (cnsNode->IsVectorZero()) { resultNode = otherNode; } break; } - // Handle `x ^ 0 == x` and `0 ^ x == x` - if (cnsNode->IsVectorZero()) + default: { - resultNode = otherNode; + break; } - break; } - default: + switch (ni) { - break; - } - } - - switch (ni) - { #ifdef TARGET_ARM64 - case NI_Sve_ConvertVectorToMask: - resultNode = gtFoldExprConvertVecCnsToMask(tree, cnsNode->AsVecCon()); - break; + case NI_Sve_ConvertVectorToMask: + resultNode = gtFoldExprConvertVecCnsToMask(tree, cnsNode->AsVecCon()); + break; - case NI_AdvSimd_MultiplyByScalar: - case NI_AdvSimd_Arm64_MultiplyByScalar: - { - if (!varTypeIsFloating(simdBaseType)) + case NI_AdvSimd_MultiplyByScalar: + case NI_AdvSimd_Arm64_MultiplyByScalar: { - // Handle `x * 0 == 0` and `0 * x == 0` - // Not safe for floating-point when x == -0.0, NaN, +Inf, -Inf - if (cnsNode == op1) + if (!varTypeIsFloating(simdBaseType)) { - if (cnsNode->IsVectorZero()) + // Handle `x * 0 == 0` and `0 * x == 0` + // Not safe for floating-point when x == -0.0, NaN, +Inf, -Inf + if (cnsNode == op1) { - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; + if (cnsNode->IsVectorZero()) + { + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } } - } - else - { - assert(cnsNode == op2); - - if (cnsNode->AsVecCon()->IsScalarZero(simdBaseType)) + else { - int64_t val = 0; + assert(cnsNode == op2); - cnsNode->gtType = retType; - cnsNode->AsVecCon()->EvaluateBroadcastInPlace(simdBaseType, val); + if (cnsNode->AsVecCon()->IsScalarZero(simdBaseType)) + { + int64_t val = 0; - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; - } - } - } - else - { - // Handle `x * NaN == NaN` and `NaN * x == NaN` - // This is safe for all floats since we do not fault for sNaN + cnsNode->gtType = retType; + cnsNode->AsVecCon()->EvaluateBroadcastInPlace(simdBaseType, val); - if (cnsNode == op1) - { - if (cnsNode->IsVectorNaN(simdBaseType)) - { - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } } } else { - assert(cnsNode == op2); - double val = cnsNode->AsVecCon()->GetElementFloating(simdBaseType, 0); + // Handle `x * NaN == NaN` and `NaN * x == NaN` + // This is safe for all floats since we do not fault for sNaN - if (FloatingPointUtils::isNaN(val)) + if (cnsNode == op1) + { + if (cnsNode->IsVectorNaN(simdBaseType)) + { + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } + } + else { - cnsNode->gtType = retType; - cnsNode->AsVecCon()->EvaluateBroadcastInPlace(simdBaseType, val); + assert(cnsNode == op2); + double val = cnsNode->AsVecCon()->GetElementFloating(simdBaseType, 0); - resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); - break; + if (FloatingPointUtils::isNaN(val)) + { + cnsNode->gtType = retType; + cnsNode->AsVecCon()->EvaluateBroadcastInPlace(simdBaseType, val); + + resultNode = gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT); + break; + } } - } - // We cannot handle `x * 0 == 0` or ` 0 * x == 0` since `-0 * 0 == -0` - // We cannot handle `x * -0 == -0` or `-0 * x == -0` since `-0 * -0 == 0` - } + // We cannot handle `x * 0 == 0` or ` 0 * x == 0` since `-0 * 0 == -0` + // We cannot handle `x * -0 == -0` or `-0 * x == -0` since `-0 * -0 == 0` + } - // Handle x * 1 => x, but only if the scalar RHS is <1, ...>. - if ((cnsNode == op2) && cnsNode->AsVecCon()->IsScalarOne(simdBaseType)) - { - resultNode = otherNode; + // Handle x * 1 => x, but only if the scalar RHS is <1, ...>. + if ((cnsNode == op2) && cnsNode->AsVecCon()->IsScalarOne(simdBaseType)) + { + resultNode = otherNode; + } + break; } - break; - } #endif - case NI_Vector128_op_Equality: + case NI_Vector128_op_Equality: #if defined(TARGET_ARM64) - case NI_Vector64_op_Equality: + case NI_Vector64_op_Equality: #elif defined(TARGET_XARCH) - case NI_Vector256_op_Equality: - case NI_Vector512_op_Equality: + case NI_Vector256_op_Equality: + case NI_Vector512_op_Equality: #endif // !TARGET_ARM64 && !TARGET_XARCH - { - if (varTypeIsFloating(simdBaseType)) { - // Handle `(x == NaN) == false` and `(NaN == x) == false` for floating-point types - if (cnsNode->IsVectorNaN(simdBaseType)) + if (varTypeIsFloating(simdBaseType)) { - resultNode = gtNewIconNode(0, retType); - resultNode = gtWrapWithSideEffects(resultNode, otherNode, GTF_ALL_EFFECT); - break; + // Handle `(x == NaN) == false` and `(NaN == x) == false` for floating-point types + if (cnsNode->IsVectorNaN(simdBaseType)) + { + resultNode = gtNewIconNode(0, retType); + resultNode = gtWrapWithSideEffects(resultNode, otherNode, GTF_ALL_EFFECT); + break; + } } + break; } - break; - } - case NI_Vector128_op_Inequality: + case NI_Vector128_op_Inequality: #if defined(TARGET_ARM64) - case NI_Vector64_op_Inequality: + case NI_Vector64_op_Inequality: #elif defined(TARGET_XARCH) - case NI_Vector256_op_Inequality: - case NI_Vector512_op_Inequality: + case NI_Vector256_op_Inequality: + case NI_Vector512_op_Inequality: #endif // !TARGET_ARM64 && !TARGET_XARCH - { - if (varTypeIsFloating(simdBaseType)) { - // Handle `(x != NaN) == true` and `(NaN != x) == true` for floating-point types - if (cnsNode->IsVectorNaN(simdBaseType)) + if (varTypeIsFloating(simdBaseType)) { - resultNode = gtNewIconNode(1, retType); - resultNode = gtWrapWithSideEffects(resultNode, otherNode, GTF_ALL_EFFECT); - break; + // Handle `(x != NaN) == true` and `(NaN != x) == true` for floating-point types + if (cnsNode->IsVectorNaN(simdBaseType)) + { + resultNode = gtNewIconNode(1, retType); + resultNode = gtWrapWithSideEffects(resultNode, otherNode, GTF_ALL_EFFECT); + break; + } } + break; } - break; - } - default: - { - break; + default: + { + break; + } } } } - - if (op3 != nullptr) + else { + assert(opCount == 3); + switch (ni) { #if defined(TARGET_XARCH) @@ -33559,7 +33832,7 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) // op2 = op2 & op1 op2->AsVecCon()->EvaluateBinaryInPlace(GT_AND, false, simdBaseType, op1->AsVecCon()); - // op3 = op2 & ~op1 + // op3 = op3 & ~op1 op3->AsVecCon()->EvaluateBinaryInPlace(GT_AND_NOT, false, simdBaseType, op1->AsVecCon()); // op2 = op2 | op3 @@ -33572,8 +33845,8 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) #if defined(TARGET_ARM64) case NI_Sve_ConditionalSelect: + case NI_Sve_ConditionalSelect_Predicates: { - assert(!varTypeIsMask(retType)); assert(varTypeIsMask(op1)); if (cnsNode != op1) @@ -33602,10 +33875,11 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) if (op2->IsCnsVec() && op3->IsCnsVec()) { + assert(ni == NI_Sve_ConditionalSelect); assert(op2->gtType == TYP_SIMD16); assert(op3->gtType == TYP_SIMD16); - simd16_t op1SimdVal; + simd16_t op1SimdVal = {}; EvaluateSimdCvtMaskToVector(simdBaseType, &op1SimdVal, op1->AsMskCon()->gtSimdMaskVal); // op2 = op2 & op1 @@ -33614,7 +33888,7 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) op1SimdVal); op2->AsVecCon()->gtSimd16Val = result; - // op3 = op2 & ~op1 + // op3 = op3 & ~op1 result = {}; EvaluateBinarySimd(GT_AND_NOT, false, simdBaseType, &result, op3->AsVecCon()->gtSimd16Val, op1SimdVal); @@ -33625,10 +33899,124 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) resultNode = op2; } + else if (op2->IsCnsMsk() && op3->IsCnsMsk()) + { + assert(ni == NI_Sve_ConditionalSelect_Predicates); + + // op2 = op2 & op1 + simdmask_t result = {}; + EvaluateBinaryMask(GT_AND, false, simdBaseType, &result, op2->AsMskCon()->gtSimdMaskVal, + op1->AsMskCon()->gtSimdMaskVal); + op2->AsMskCon()->gtSimdMaskVal = result; + + // op3 = op3 & ~op1 + result = {}; + EvaluateBinaryMask(GT_AND_NOT, false, simdBaseType, &result, + op3->AsMskCon()->gtSimdMaskVal, op1->AsMskCon()->gtSimdMaskVal); + op3->AsMskCon()->gtSimdMaskVal = result; + + // op2 = op2 | op3 + result = {}; + EvaluateBinaryMask(GT_OR, false, simdBaseType, &result, op2->AsMskCon()->gtSimdMaskVal, + op3->AsMskCon()->gtSimdMaskVal); + op2->AsMskCon()->gtSimdMaskVal = result; + + resultNode = op2; + } break; } #endif // TARGET_ARM64 + case NI_Vector128_WithElement: +#ifdef TARGET_ARM64 + case NI_Vector64_WithElement: +#else + case NI_Vector256_WithElement: + case NI_Vector512_WithElement: +#endif + { + if ((cnsNode != op1) || !op3->OperIsConst()) + { + break; + } + + uint32_t index = static_cast(op2->AsIntConCommon()->IconValue()); + + if (index >= GenTreeVecCon::ElementCount(simdSize, simdBaseType)) + { + // Nothing to fold for out of range indexes + break; + } + + var_types simdType = getSIMDTypeForSize(simdSize); + + if (varTypeIsFloating(simdBaseType)) + { + double value = op3->AsDblCon()->DconValue(); + cnsNode->AsVecCon()->SetElementFloating(simdBaseType, index, value); + resultNode = cnsNode; + } + else + { + assert(varTypeIsIntegral(simdBaseType)); + int64_t value = op3->AsIntConCommon()->IntegralValue(); + cnsNode->AsVecCon()->SetElementIntegral(simdBaseType, index, value); + resultNode = cnsNode; + } + break; + } + +#if defined(TARGET_XARCH) + case NI_AVX_Compare: + case NI_AVX_CompareScalar: + case NI_AVX512_CompareMask: + { + if (!op3->IsCnsIntOrI()) + { + break; + } + + FloatComparisonMode mode = static_cast(op3->AsIntConCommon()->IntegralValue()); + NamedIntrinsic id = ni; + + switch (mode) + { + case FloatComparisonMode::OrderedFalseNonSignaling: + case FloatComparisonMode::OrderedFalseSignaling: + { + resultNode = gtNewZeroConNode(retType); + resultNode = gtWrapWithSideEffects(resultNode, tree, GTF_ALL_EFFECT); + break; + } + + case FloatComparisonMode::UnorderedTrueNonSignaling: + case FloatComparisonMode::UnorderedTrueSignaling: + { + resultNode = gtNewAllBitsSetConNode(retType); + resultNode = gtWrapWithSideEffects(resultNode, tree, GTF_ALL_EFFECT); + break; + } + + default: + { + id = HWIntrinsicInfo::lookupIdForFloatComparisonMode(ni, mode, simdBaseType, simdSize); + break; + } + } + + if (id == ni) + { + break; + } + + tree->ResetHWIntrinsicId(id, op1, op2); + DEBUG_DESTROY_NODE(op3); + + tree->SetMorphed(this); + return gtFoldExprHWIntrinsic(tree); + } +#endif // TARGET_XARCH + default: { break; diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 0532f8df795345..4f90e06914070b 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -333,7 +333,18 @@ class GenTreeOperandIterator; struct Statement; -/*****************************************************************************/ +enum HandleKindFlag +{ + HKF_INVARIANT = 1, // Points to invariant data. + HKF_NONNULL = 2, // Points to non-null data. +}; + +enum class HandleKindIndex : unsigned +{ +#define HANDLE_KIND(name, description, flags) name, +#include "handlekinds.h" + COUNT +}; // Forward declarations of the subtypes #define GTSTRUCT_0(fn, en) struct GenTree##fn; @@ -354,7 +365,7 @@ struct Statement; //------------------------------------------------------------------------ // GenTreeFlags: a bitmask of flags for GenTree stored in gtFlags // -enum GenTreeFlags : unsigned int +enum GenTreeFlags : unsigned { GTF_EMPTY = 0, @@ -507,28 +518,10 @@ enum GenTreeFlags : unsigned int GTF_ARR_ADDR_NONNULL = 0x80000000, // GT_ARR_ADDR -- this array's address is not null - GTF_ICON_HDL_MASK = 0xFF000000, // Bits used by handle types below - GTF_ICON_SCOPE_HDL = 0x01000000, // GT_CNS_INT -- constant is a scope handle - GTF_ICON_CLASS_HDL = 0x02000000, // GT_CNS_INT -- constant is a class handle - GTF_ICON_METHOD_HDL = 0x03000000, // GT_CNS_INT -- constant is a method handle - GTF_ICON_FIELD_HDL = 0x04000000, // GT_CNS_INT -- constant is a field handle - GTF_ICON_STATIC_HDL = 0x05000000, // GT_CNS_INT -- constant is a handle to static data - GTF_ICON_STR_HDL = 0x06000000, // GT_CNS_INT -- constant is a pinned handle pointing to a string object - GTF_ICON_OBJ_HDL = 0x07000000, // GT_CNS_INT -- constant is an object handle (e.g. frozen string or Type object) - GTF_ICON_CONST_PTR = 0x08000000, // GT_CNS_INT -- constant is a pointer to immutable data, (e.g. IAT_PPVALUE) - GTF_ICON_GLOBAL_PTR = 0x09000000, // GT_CNS_INT -- constant is a pointer to mutable data (e.g. from the VM state) - GTF_ICON_VARG_HDL = 0x0A000000, // GT_CNS_INT -- constant is a var arg cookie handle - GTF_ICON_PINVKI_HDL = 0x0B000000, // GT_CNS_INT -- constant is a pinvoke calli handle - GTF_ICON_TOKEN_HDL = 0x0C000000, // GT_CNS_INT -- constant is a token handle (other than class, method or field) - GTF_ICON_TLS_HDL = 0x0D000000, // GT_CNS_INT -- constant is a TLS ref with offset - GTF_ICON_FTN_ADDR = 0x0E000000, // GT_CNS_INT -- constant is a function address - GTF_ICON_CIDMID_HDL = 0x0F000000, // GT_CNS_INT -- constant is a class ID or a module ID - GTF_ICON_BBC_PTR = 0x10000000, // GT_CNS_INT -- constant is a basic block count pointer - GTF_ICON_STATIC_BOX_PTR = 0x11000000, // GT_CNS_INT -- constant is an address of the box for a STATIC_IN_HEAP field - GTF_ICON_FIELD_SEQ = 0x12000000, // <--------> -- constant is a FieldSeq* (used only as VNHandle) - GTF_ICON_STATIC_ADDR_PTR = 0x13000000, // GT_CNS_INT -- constant is a pointer to a static base address - GTF_ICON_SECREL_OFFSET = 0x14000000, // GT_CNS_INT -- constant is an offset in a certain section. - GTF_ICON_TLSGD_OFFSET = 0x15000000, // GT_CNS_INT -- constant is an argument to tls_get_addr. +#define HANDLE_KIND_INDEX_SHIFT 24 + GTF_ICON_HDL_MASK = (~0u) << HANDLE_KIND_INDEX_SHIFT, // 0xFF000000, bits used by the handle types. +#define HANDLE_KIND(name, description, flags) name = (static_cast(HandleKindIndex::name) + 1) << HANDLE_KIND_INDEX_SHIFT, +#include "handlekinds.h" // GTF_ICON_REUSE_REG_VAL = 0x00800000 // GT_CNS_INT -- GTF_REUSE_REG_VAL, defined above GTF_ICON_SIMD_COUNT = 0x00200000, // GT_CNS_INT -- constant is Vector.Count @@ -597,6 +590,14 @@ inline GenTreeFlags& operator ^=(GenTreeFlags& a, GenTreeFlags b) #define GTF_GLOBALLY_VISIBLE_SIDE_EFFECTS(flags) \ (((flags) & (GTF_CALL | GTF_EXCEPT)) || (((flags) & (GTF_ASG | GTF_GLOB_REF)) == (GTF_ASG | GTF_GLOB_REF))) +inline unsigned HandleKindToHandleKindIndex(GenTreeFlags kind) +{ + assert((kind & GTF_ICON_HDL_MASK) != 0); + unsigned index = (kind >> HANDLE_KIND_INDEX_SHIFT) - 1; + assert(index < static_cast(HandleKindIndex::COUNT)); + return index; +} + #if defined(DEBUG) //------------------------------------------------------------------------ @@ -648,6 +649,22 @@ inline GenTreeDebugFlags& operator &=(GenTreeDebugFlags& a, GenTreeDebugFlags b) // clang-format on +struct LocalDef +{ + GenTreeLclVarCommon* Def; + bool IsEntire; + ssize_t Offset; + unsigned Size; + + LocalDef(GenTreeLclVarCommon* def, bool isEntire, ssize_t offset, unsigned size) + : Def(def) + , IsEntire(isEntire) + , Offset(offset) + , Size(size) + { + } +}; + #ifndef HOST_64BIT #include #endif @@ -696,6 +713,12 @@ struct GenTree #include "gtstructs.h" + enum class VisitResult + { + Abort = false, + Continue = true + }; + genTreeOps gtOper; // enum subtype BYTE var_types gtType; // enum subtype BYTE @@ -1494,12 +1517,13 @@ struct GenTree #ifdef FEATURE_HW_INTRINSICS bool isCommutativeHWIntrinsic() const; bool isContainableHWIntrinsic() const; - bool isRMWHWIntrinsic(Compiler* comp); + bool isRMWHWIntrinsic(Compiler* comp) const; #if defined(TARGET_XARCH) bool isEvexCompatibleHWIntrinsic(Compiler* comp) const; bool isEmbeddedBroadcastCompatibleHWIntrinsic(Compiler* comp) const; + bool isEmbeddedMaskingCompatible(Compiler* comp, unsigned tgtMaskSize, CorInfoType& tgtSimdBaseJitType) const; #endif // TARGET_XARCH - bool isEmbeddedMaskingCompatibleHWIntrinsic() const; + bool isEmbeddedMaskingCompatible() const; #else bool isCommutativeHWIntrinsic() const { @@ -1511,7 +1535,7 @@ struct GenTree return false; } - bool isRMWHWIntrinsic(Compiler* comp) + bool isRMWHWIntrinsic(Compiler* comp) const { return false; } @@ -1528,7 +1552,7 @@ struct GenTree } #endif // TARGET_XARCH - bool isEmbeddedMaskingCompatibleHWIntrinsic() const + bool isEmbeddedMaskingCompatible() const { return false; } @@ -1692,7 +1716,6 @@ struct GenTree bool OperIsHWIntrinsic(NamedIntrinsic intrinsicId) const; bool OperIsConvertMaskToVector() const; bool OperIsConvertVectorToMask() const; - bool OperIsVectorConditionalSelect() const; bool OperIsVectorFusedMultiplyOp() const; // This is here for cleaner GT_LONG #ifdefs. @@ -2022,11 +2045,13 @@ struct GenTree // is not the same size as the type of the GT_LCL_VAR. bool IsPartialLclFld(Compiler* comp); - bool DefinesLocal(Compiler* comp, - GenTreeLclVarCommon** pLclVarTree, - bool* pIsEntire = nullptr, - ssize_t* pOffset = nullptr, - unsigned* pSize = nullptr); + template + VisitResult VisitLocalDefs(Compiler* comp, TVisitor visitor); + + template + VisitResult VisitLocalDefNodes(Compiler* comp, TVisitor visitor); + + bool HasAnyLocalDefs(Compiler* comp); GenTreeLclVarCommon* IsImplicitByrefParameterValuePreMorph(Compiler* compiler); GenTreeLclVar* IsImplicitByrefParameterValuePostMorph(Compiler* compiler, GenTree** addr, target_ssize_t* offset); @@ -2299,6 +2324,7 @@ struct GenTree #endif // FEATURE_HW_INTRINSICS static bool HandleKindDataIsInvariant(GenTreeFlags flags); + static bool HandleKindDataIsNotNull(GenTreeFlags flags); bool IsCall() const { @@ -2349,12 +2375,6 @@ struct GenTree // Returns a range that will produce the operands of this node in execution order. IteratorPair Operands(); - enum class VisitResult - { - Abort = false, - Continue = true - }; - // Visits each operand of this node. The operand must be either a lambda, function, or functor with the signature // `GenTree::VisitResult VisitorFunction(GenTree* operand)`. Here is a simple example: // @@ -4327,10 +4347,55 @@ enum class ExecutionContextHandling AsyncSaveAndRestore, }; +enum class ContinuationContextHandling +{ + // No special handling of SynchronizationContext/TaskScheduler is required. + None, + // Continue on SynchronizationContext/TaskScheduler + ContinueOnCapturedContext, + // Continue on thread pool thread + ContinueOnThreadPool, +}; + // Additional async call info. struct AsyncCallInfo { - ExecutionContextHandling ExecutionContextHandling = ExecutionContextHandling::None; + // The following information is used to implement the proper observable handling of `ExecutionContext`, + // `SynchronizationContext` and `TaskScheduler` in async methods. + // + // The breakdown of the handling is as follows: + // + // - For custom awaitables there is no special handling of `SynchronizationContext` or `TaskScheduler`. All the + // handling that exists is custom implemented by the user. In this case "ContinuationContextHandling == None" and + // "SaveAndRestoreSynchronizationContextField == false". + // + // - For custom awaitables there _is_ special handling of `ExecutionContext`: when the custom awaitable suspends, + // the JIT ensures that the `ExecutionContext` will be captured on suspension and restored when the continuation is + // running. This is represented by "ExecutionContextHandling == AsyncSaveAndRestore". + // + // - For task awaits there is special handling of `SynchronizationContext` and `TaskScheduler` in multiple ways: + // + // * The JIT ensures that `Thread.CurrentThread._synchronizationContext` is saved and restored around + // synchronously finishing calls. This is represented by "SaveAndRestoreSynchronizationContextField == true". + // + // * The JIT/runtime/BCL ensure that when the callee suspends, the caller will eventually be resumed on the + // `SynchronizationContext`/`TaskScheduler` present before the call started, depending on the configuration of the + // task await by the user. This resumption can be inlined if the `SynchronizationContext` is current when the + // continuation is about to run, and otherwise will be posted to it. This is represented by + // "ContinuationContextHandling == ContinueOnCapturedContext/ContinueOnThreadPool". + // + // * When the callee suspends restoration of `Thread.CurrentThread._synchronizationContext` is left up to the + // custom implementation of the `SynchronizationContext`, it must not be done by the JIT. + // + // - For task awaits the runtime/BCL ensure that `Thread.CurrentThread._executionContext` is captured before the + // call and restored after it. This happens consistently regardless of whether the callee finishes synchronously or + // not. This is represented by "ExecutionContextHandling == SaveAndRestore". + // + ExecutionContextHandling ExecutionContextHandling = ExecutionContextHandling::None; + ContinuationContextHandling ContinuationContextHandling = ContinuationContextHandling::None; + bool SaveAndRestoreSynchronizationContextField = false; + bool HasSuspensionIndicatorDef = false; + unsigned SynchronizationContextLclNum = BAD_VAR_NUM; }; // Return type descriptor of a GT_CALL node. @@ -4603,6 +4668,7 @@ enum class WellKnownArg : unsigned X86TailCallSpecialArg, StackArrayLocal, RuntimeMethodHandle, + AsyncSuspendedIndicator, }; #ifdef DEBUG @@ -4817,6 +4883,7 @@ class CallArgs CallArg* InsertAfterThisOrFirst(Compiler* comp, const NewCallArg& arg); void PushLateBack(CallArg* arg); void Remove(CallArg* arg); + void RemoveUnsafe(CallArg* arg); template void InternalCopyFrom(Compiler* comp, CallArgs* other, CopyNodeFunc copyFunc); @@ -4990,7 +5057,7 @@ struct GenTreeCall final : public GenTree // Only used for unmanaged calls, which cannot be tail-called CorInfoCallConvExtension unmgdCallConv; // Used for async calls - const AsyncCallInfo* asyncInfo; + AsyncCallInfo* asyncInfo; }; #if FEATURE_MULTIREG_RET @@ -5048,7 +5115,7 @@ struct GenTreeCall final : public GenTree #endif } - void SetIsAsync(const AsyncCallInfo* info) + void SetIsAsync(AsyncCallInfo* info) { assert(info != nullptr); gtCallMoreFlags |= GTF_CALL_M_ASYNC; @@ -6510,34 +6577,6 @@ struct GenTreeHWIntrinsic : public GenTreeJitIntrinsic #endif } - bool OperIsVectorConditionalSelect() const - { - switch (GetHWIntrinsicId()) - { -#if defined(TARGET_XARCH) - case NI_Vector128_ConditionalSelect: - case NI_Vector256_ConditionalSelect: - case NI_Vector512_ConditionalSelect: - { - return true; - } -#endif // TARGET_XARCH - -#if defined(TARGET_ARM64) - case NI_AdvSimd_BitwiseSelect: - case NI_Sve_ConditionalSelect: - { - return true; - } -#endif // TARGET_ARM64 - - default: - { - return false; - } - } - } - bool OperIsVectorFusedMultiplyOp() const { switch (GetHWIntrinsicId()) diff --git a/src/coreclr/jit/gschecks.cpp b/src/coreclr/jit/gschecks.cpp index 75d5a365a5871f..4d7a54fcdcc2ff 100644 --- a/src/coreclr/jit/gschecks.cpp +++ b/src/coreclr/jit/gschecks.cpp @@ -410,7 +410,7 @@ void Compiler::gsParamsToShadows() shadowVarDsc->lvDoNotEnregister = varDsc->lvDoNotEnregister; #ifdef DEBUG shadowVarDsc->SetDoNotEnregReason(varDsc->GetDoNotEnregReason()); - shadowVarDsc->SetHiddenBufferStructArg(varDsc->IsHiddenBufferStructArg()); + shadowVarDsc->SetDefinedViaAddress(varDsc->IsDefinedViaAddress()); #endif if (varTypeIsStruct(type)) diff --git a/src/coreclr/jit/gtlist.h b/src/coreclr/jit/gtlist.h index 0ec112781c050e..93fb4dfd358b37 100644 --- a/src/coreclr/jit/gtlist.h +++ b/src/coreclr/jit/gtlist.h @@ -280,19 +280,19 @@ GTNODE(SELECT_NEGCC , GenTreeOpCC ,0,0,GTK_BINOP|DBK_NOTHIR) #ifdef TARGET_RISCV64 // Maps to riscv64 sh1add instruction. Computes result = op2 + (op1 << 1). GTNODE(SH1ADD , GenTreeOp ,0,0,GTK_BINOP|DBK_NOTHIR) -// Maps to riscv64 sh1add.uw instruction. Computes result = op2 + zext(op1[31..0] << 1). +// Maps to riscv64 sh1add.uw instruction. Computes result = op2 + (zext(op1[31..0]) << 1). GTNODE(SH1ADD_UW , GenTreeOp ,0,0,GTK_BINOP|DBK_NOTHIR) // Maps to riscv64 sh2add instruction. Computes result = op2 + (op1 << 2). GTNODE(SH2ADD , GenTreeOp ,0,0,GTK_BINOP|DBK_NOTHIR) -// Maps to riscv64 sh2add.uw instruction. Computes result = op2 + zext(op1[31..0] << 2). +// Maps to riscv64 sh2add.uw instruction. Computes result = op2 + (zext(op1[31..0]) << 2). GTNODE(SH2ADD_UW , GenTreeOp ,0,0,GTK_BINOP|DBK_NOTHIR) // Maps to riscv64 sh3add instruction. Computes result = op2 + (op1 << 3). GTNODE(SH3ADD , GenTreeOp ,0,0,GTK_BINOP|DBK_NOTHIR) -// Maps to riscv64 sh3add.uw instruction. Computes result = op2 + zext(op1[31..0] << 3). +// Maps to riscv64 sh3add.uw instruction. Computes result = op2 + (zext(op1[31..0]) << 3). GTNODE(SH3ADD_UW , GenTreeOp ,0,0,GTK_BINOP|DBK_NOTHIR) // Maps to riscv64 add.uw instruction. Computes result = op2 + zext(op1[31..0]). GTNODE(ADD_UW , GenTreeOp ,0,0,GTK_BINOP|DBK_NOTHIR) -// Maps to riscv64 slli.uw instruction. Computes result = zext(op1[31..0] << imm). +// Maps to riscv64 slli.uw instruction. Computes result = zext(op1[31..0]) << imm. GTNODE(SLLI_UW , GenTreeOp ,0,0,GTK_BINOP|DBK_NOTHIR) #endif diff --git a/src/coreclr/jit/handlekinds.h b/src/coreclr/jit/handlekinds.h new file mode 100644 index 00000000000000..9516c5193c8baf --- /dev/null +++ b/src/coreclr/jit/handlekinds.h @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// clang-format off +#ifndef HANDLE_KIND +#error Define HANDLE_KIND before including this file. +#endif + +HANDLE_KIND(GTF_ICON_SCOPE_HDL , "scope" , HKF_INVARIANT) // scope handle +HANDLE_KIND(GTF_ICON_CLASS_HDL , "class" , HKF_INVARIANT) // class handle +HANDLE_KIND(GTF_ICON_METHOD_HDL , "method" , HKF_INVARIANT) // method handle +HANDLE_KIND(GTF_ICON_FIELD_HDL , "field" , HKF_INVARIANT) // field handle +HANDLE_KIND(GTF_ICON_STATIC_HDL , "static" , 0) // handle to static data +HANDLE_KIND(GTF_ICON_STR_HDL , "string" , HKF_INVARIANT | HKF_NONNULL) // pinned handle pointing to a string object +HANDLE_KIND(GTF_ICON_OBJ_HDL , "object" , 0) // object handle (e.g. frozen string or Type object) +HANDLE_KIND(GTF_ICON_CONST_PTR , "const ptr" , HKF_INVARIANT) // pointer to immutable data, (e.g. IAT_PPVALUE) +HANDLE_KIND(GTF_ICON_GLOBAL_PTR , "global ptr" , 0) // pointer to mutable data (e.g. from the VM state) +HANDLE_KIND(GTF_ICON_VARG_HDL , "vararg" , HKF_INVARIANT) // var arg cookie handle +HANDLE_KIND(GTF_ICON_PINVKI_HDL , "pinvoke" , 0) // pinvoke calli handle +HANDLE_KIND(GTF_ICON_TOKEN_HDL , "token" , HKF_INVARIANT) // token handle (other than class, method or field) +HANDLE_KIND(GTF_ICON_TLS_HDL , "tls" , HKF_INVARIANT) // TLS ref with offset +HANDLE_KIND(GTF_ICON_FTN_ADDR , "ftn" , 0) // function address +HANDLE_KIND(GTF_ICON_CIDMID_HDL , "cid/mid" , HKF_INVARIANT) // class ID or a module ID +HANDLE_KIND(GTF_ICON_BBC_PTR , "bbc" , 0) // basic block count pointer +HANDLE_KIND(GTF_ICON_STATIC_BOX_PTR , "static box ptr" , 0) // address of the box for a STATIC_IN_HEAP field +HANDLE_KIND(GTF_ICON_FIELD_SEQ , "field seq" , 0) // FieldSeq* (used only as VNHandle) +HANDLE_KIND(GTF_ICON_STATIC_ADDR_PTR , "static base addr cell" , HKF_INVARIANT | HKF_NONNULL) // pointer to a static base address +HANDLE_KIND(GTF_ICON_SECREL_OFFSET , "relative offset in section" , HKF_INVARIANT) // offset in a certain section. +HANDLE_KIND(GTF_ICON_TLSGD_OFFSET , "tls global dynamic offset" , HKF_INVARIANT) // argument to tls_get_addr. + +#undef HANDLE_KIND +// clang-format on diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 1e18c82f589536..8bb9f8feb2a147 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -18,6 +18,16 @@ static GenTree* SpillExpression(Compiler* comp, GenTree* expr, BasicBlock* exprB return comp->gtNewLclVarNode(tmpNum); }; +static void InheritFlags(BasicBlock* dst, const BasicBlock* flagSrc) +{ + // Currently, all of our "new block" helpers set BBF_INTERNAL flag by default. + if (!flagSrc->HasFlag(BBF_INTERNAL)) + { + dst->RemoveFlags(BBF_INTERNAL); + dst->SetFlags(BBF_IMPORTED); + } +} + //------------------------------------------------------------------------------ // SplitAtTreeAndReplaceItWithLocal : Split block at the given tree and replace it with a local // See comments in gtSplitTree and fgSplitBlockBeforeTree @@ -242,7 +252,6 @@ bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock** pBlock, Statement* stm } GenTree* ctxTree = call->gtArgs.GetArgByIndex(0)->GetNode(); - GenTree* sigNode = call->gtArgs.GetArgByIndex(1)->GetNode(); // Prepare slotPtr tree (TODO: consider sharing this part with impRuntimeLookup) GenTree* slotPtrTree = gtCloneExpr(ctxTree); @@ -442,6 +451,19 @@ bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock** pBlock, Statement* stm fallbackBb->inheritWeightPercentage(nullcheckBb, 20); } + // + // Update flags in all new blocks + // + + InheritFlags(nullcheckBb, prevBb); + InheritFlags(fastPathBb, prevBb); + InheritFlags(fallbackBb, prevBb); + InheritFlags(block, prevBb); + if (needsSizeCheck) + { + InheritFlags(sizeCheckBb, prevBb); + } + // All blocks are expected to be in the same EH region assert(BasicBlock::sameEHRegion(prevBb, block)); assert(BasicBlock::sameEHRegion(prevBb, nullcheckBb)); @@ -1441,7 +1463,7 @@ bool Compiler::fgExpandStaticInitForCall(BasicBlock** pBlock, Statement* stmt, G { assert(isInitOffset == 0); - isInitedActualValueNode = gtNewIndOfIconHandleNode(TYP_INT, (size_t)flagAddr.addr, GTF_ICON_GLOBAL_PTR, false); + isInitedActualValueNode = gtNewIndOfIconHandleNode(TYP_INT, (size_t)flagAddr.addr, GTF_ICON_GLOBAL_PTR); isInitedActualValueNode->gtFlags |= GTF_IND_VOLATILE; isInitedActualValueNode->SetHasOrderingSideEffect(); @@ -1479,8 +1501,7 @@ bool Compiler::fgExpandStaticInitForCall(BasicBlock** pBlock, Statement* stmt, G else { assert(staticBaseAddr.accessType == IAT_PVALUE); - replacementNode = - gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)staticBaseAddr.addr, GTF_ICON_GLOBAL_PTR, false); + replacementNode = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)staticBaseAddr.addr, GTF_ICON_GLOBAL_PTR); } } @@ -1546,6 +1567,14 @@ bool Compiler::fgExpandStaticInitForCall(BasicBlock** pBlock, Statement* stmt, G isInitedBb->inheritWeight(prevBb); helperCallBb->inheritWeightPercentage(isInitedBb, 0); + // + // Update flags in all new blocks + // + + InheritFlags(block, prevBb); + InheritFlags(isInitedBb, prevBb); + InheritFlags(helperCallBb, prevBb); + // All blocks are expected to be in the same EH region assert(BasicBlock::sameEHRegion(prevBb, block)); assert(BasicBlock::sameEHRegion(prevBb, isInitedBb)); diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index d7be0beb08da26..588396c4a7253c 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -87,108 +87,147 @@ instruction HWIntrinsicInfo::lookupIns(NamedIntrinsic id, var_types type, Compil #endif // TARGET_X86 #if defined(TARGET_XARCH) - instruction evexIns = ins; - - switch (ins) + if (comp != nullptr) { - case INS_movdqa32: + instruction evexIns = ins; + + switch (ins) { - if (varTypeIsLong(type)) + case INS_movdqa32: { - evexIns = INS_vmovdqa64; + if (varTypeIsLong(type)) + { + evexIns = INS_vmovdqa64; + } + break; } - break; - } - case INS_movdqu32: - { - if (varTypeIsLong(type)) + case INS_movdqu32: { - evexIns = INS_vmovdqu64; + if (varTypeIsLong(type)) + { + evexIns = INS_vmovdqu64; + } + break; } - break; - } - case INS_vbroadcastf32x4: - { - if (type == TYP_DOUBLE) + case INS_pandd: { - evexIns = INS_vbroadcastf64x2; + if (varTypeIsLong(type)) + { + evexIns = INS_vpandq; + } + break; } - break; - } - case INS_vbroadcasti32x4: - { - if (varTypeIsLong(type)) + case INS_pandnd: { - evexIns = INS_vbroadcasti64x2; + if (varTypeIsLong(type)) + { + evexIns = INS_vpandnq; + } + break; } - break; - } - case INS_vextractf32x4: - { - if (type == TYP_DOUBLE) + case INS_pord: { - evexIns = INS_vextractf64x2; + if (varTypeIsLong(type)) + { + evexIns = INS_vporq; + } + break; } - else if (varTypeIsInt(type)) + + case INS_pxord: { - evexIns = INS_vextracti32x4; + if (varTypeIsLong(type)) + { + evexIns = INS_vpxorq; + } + break; } - else if (varTypeIsLong(type)) + + case INS_vbroadcastf32x4: { - evexIns = INS_vextracti64x2; + if (type == TYP_DOUBLE) + { + evexIns = INS_vbroadcastf64x2; + } + break; } - break; - } - case INS_vextracti32x4: - { - if (varTypeIsLong(type)) + case INS_vbroadcasti32x4: { - evexIns = INS_vextracti64x2; + if (varTypeIsLong(type)) + { + evexIns = INS_vbroadcasti64x2; + } + break; } - break; - } - case INS_vinsertf32x4: - { - if (type == TYP_DOUBLE) + case INS_vextractf32x4: { - evexIns = INS_vinsertf64x2; + if (type == TYP_DOUBLE) + { + evexIns = INS_vextractf64x2; + } + else if (varTypeIsInt(type)) + { + evexIns = INS_vextracti32x4; + } + else if (varTypeIsLong(type)) + { + evexIns = INS_vextracti64x2; + } + break; } - else if (varTypeIsInt(type)) + + case INS_vextracti32x4: { - evexIns = INS_vinserti32x4; + if (varTypeIsLong(type)) + { + evexIns = INS_vextracti64x2; + } + break; } - else if (varTypeIsLong(type)) + + case INS_vinsertf32x4: { - evexIns = INS_vinserti64x2; + if (type == TYP_DOUBLE) + { + evexIns = INS_vinsertf64x2; + } + else if (varTypeIsInt(type)) + { + evexIns = INS_vinserti32x4; + } + else if (varTypeIsLong(type)) + { + evexIns = INS_vinserti64x2; + } + break; } - break; - } - case INS_vinserti32x4: - { - if (varTypeIsLong(type)) + case INS_vinserti32x4: { - evexIns = INS_vinserti64x2; + if (varTypeIsLong(type)) + { + evexIns = INS_vinserti64x2; + } + break; + } + + default: + { + break; } - break; } - default: + if ((evexIns != ins) && comp->canUseEvexEncoding()) { - break; + ins = evexIns; } } - - if ((evexIns != ins) && (comp != nullptr) && comp->canUseEvexEncoding()) - { - ins = evexIns; - } #endif // TARGET_XARCH return ins; @@ -2015,9 +2054,6 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, // If so, skip the lookup. simdSize = (simdSize == 0) ? HWIntrinsicInfo::lookupSimdSize(this, intrinsic, sig) : simdSize; - HWIntrinsicSignatureReader sigReader; - sigReader.Read(info.compCompHnd, sig); - GenTree* immOp1 = nullptr; GenTree* immOp2 = nullptr; int immLowerBound = 0; @@ -2034,8 +2070,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, { unsigned immSimdSize = simdSize; var_types immSimdBaseType = simdBaseType; - getHWIntrinsicImmTypes(intrinsic, sig, 2, simdBaseType, simdBaseJitType, sigReader.op1ClsHnd, - sigReader.op2ClsHnd, sigReader.op3ClsHnd, &immSimdSize, &immSimdBaseType); + getHWIntrinsicImmTypes(intrinsic, sig, 2, &immSimdSize, &immSimdBaseType); HWIntrinsicInfo::lookupImmBounds(intrinsic, immSimdSize, immSimdBaseType, 2, &immLowerBound, &immUpperBound); if (!CheckHWIntrinsicImmRange(intrinsic, simdBaseJitType, immOp2, mustExpand, immLowerBound, immUpperBound, @@ -2082,8 +2117,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, #ifdef TARGET_ARM64 unsigned immSimdSize = simdSize; var_types immSimdBaseType = simdBaseType; - getHWIntrinsicImmTypes(intrinsic, sig, 1, simdBaseType, simdBaseJitType, sigReader.op1ClsHnd, - sigReader.op2ClsHnd, sigReader.op3ClsHnd, &immSimdSize, &immSimdBaseType); + getHWIntrinsicImmTypes(intrinsic, sig, 1, &immSimdSize, &immSimdBaseType); HWIntrinsicInfo::lookupImmBounds(intrinsic, immSimdSize, immSimdBaseType, 1, &immLowerBound, &immUpperBound); #else immUpperBound = HWIntrinsicInfo::lookupImmUpperBound(intrinsic); @@ -2167,10 +2201,12 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, } } - GenTree* op1 = nullptr; - GenTree* op2 = nullptr; - GenTree* op3 = nullptr; - GenTree* op4 = nullptr; + GenTree* op1 = nullptr; + GenTree* op2 = nullptr; + GenTree* op3 = nullptr; + GenTree* op4 = nullptr; + HWIntrinsicSignatureReader sigReader; + sigReader.Read(info.compCompHnd, sig); switch (numArgs) { diff --git a/src/coreclr/jit/hwintrinsic.h b/src/coreclr/jit/hwintrinsic.h index 6cacd4a1ae17f1..5267d426237a79 100644 --- a/src/coreclr/jit/hwintrinsic.h +++ b/src/coreclr/jit/hwintrinsic.h @@ -1275,6 +1275,9 @@ struct HWIntrinsicInfo } case NI_Sve_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar: + case NI_Sve2_DotProductRotateComplexBySelectedIndex: { assert(sig->numArgs == 5); *imm1Pos = 0; diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index efa6c434d0e6e2..650919f3934e23 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -234,80 +234,51 @@ void Compiler::getHWIntrinsicImmOps(NamedIntrinsic intrinsic, // intrinsic -- NamedIntrinsic associated with the HWIntrinsic to lookup // sig -- signature of the intrinsic call. // immNumber -- Which immediate to use (1 for most intrinsics) -// simdBaseType -- base type of the intrinsic -// simdType -- vector size of the intrinsic -// op1ClsHnd -- cls handler for op1 -// op2ClsHnd -- cls handler for op2 -// op2ClsHnd -- cls handler for op3 // immSimdSize [IN/OUT] -- Size of the immediate to override // immSimdBaseType [IN/OUT] -- Base type of the immediate to override // -void Compiler::getHWIntrinsicImmTypes(NamedIntrinsic intrinsic, - CORINFO_SIG_INFO* sig, - unsigned immNumber, - var_types simdBaseType, - CorInfoType simdBaseJitType, - CORINFO_CLASS_HANDLE op1ClsHnd, - CORINFO_CLASS_HANDLE op2ClsHnd, - CORINFO_CLASS_HANDLE op3ClsHnd, - unsigned* immSimdSize, - var_types* immSimdBaseType) +void Compiler::getHWIntrinsicImmTypes(NamedIntrinsic intrinsic, + CORINFO_SIG_INFO* sig, + unsigned immNumber, + unsigned* immSimdSize, + var_types* immSimdBaseType) { HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsic); if (category == HW_Category_SIMDByIndexedElement) { assert(immNumber == 1); + *immSimdSize = 0; + CORINFO_ARG_LIST_HANDLE immArg = sig->args; - CorInfoType indexedElementBaseJitType; - var_types indexedElementBaseType; - *immSimdSize = 0; - - if (sig->numArgs == 2) - { - indexedElementBaseJitType = getBaseJitTypeAndSizeOfSIMDType(op1ClsHnd, immSimdSize); - indexedElementBaseType = JitType2PreciseVarType(indexedElementBaseJitType); - } - else if (sig->numArgs == 3) - { - indexedElementBaseJitType = getBaseJitTypeAndSizeOfSIMDType(op2ClsHnd, immSimdSize); - indexedElementBaseType = JitType2PreciseVarType(indexedElementBaseJitType); - } - else + switch (sig->numArgs) { - assert(sig->numArgs == 4); - indexedElementBaseJitType = getBaseJitTypeAndSizeOfSIMDType(op3ClsHnd, immSimdSize); - indexedElementBaseType = JitType2PreciseVarType(indexedElementBaseJitType); - - if (intrinsic == NI_Dp_DotProductBySelectedQuadruplet) - { - assert(((simdBaseType == TYP_INT) && (indexedElementBaseType == TYP_BYTE)) || - ((simdBaseType == TYP_UINT) && (indexedElementBaseType == TYP_UBYTE))); - // The second source operand of sdot, udot instructions is an indexed 32-bit element. - indexedElementBaseType = simdBaseType; - } - - if (intrinsic == NI_Sve_DotProductBySelectedScalar) + case 4: + immArg = info.compCompHnd->getArgNext(immArg); + FALLTHROUGH; + case 3: + immArg = info.compCompHnd->getArgNext(immArg); + FALLTHROUGH; + case 2: { - assert(((simdBaseType == TYP_INT) && (indexedElementBaseType == TYP_BYTE)) || - ((simdBaseType == TYP_UINT) && (indexedElementBaseType == TYP_UBYTE)) || - ((simdBaseType == TYP_LONG) && (indexedElementBaseType == TYP_SHORT)) || - ((simdBaseType == TYP_ULONG) && (indexedElementBaseType == TYP_USHORT))); - - // The second source operand of sdot, udot instructions is an indexed 32-bit element. - indexedElementBaseType = simdBaseType; + CORINFO_CLASS_HANDLE typeHnd = info.compCompHnd->getArgClass(sig, immArg); + getBaseJitTypeAndSizeOfSIMDType(typeHnd, immSimdSize); + break; } + default: + unreached(); } - - assert(indexedElementBaseType == simdBaseType); } else if (intrinsic == NI_AdvSimd_Arm64_InsertSelectedScalar) { if (immNumber == 2) { - CorInfoType otherBaseJitType = getBaseJitTypeAndSizeOfSIMDType(op3ClsHnd, immSimdSize); - *immSimdBaseType = JitType2PreciseVarType(otherBaseJitType); - assert(otherBaseJitType == simdBaseJitType); + CORINFO_ARG_LIST_HANDLE immArg = sig->args; + immArg = info.compCompHnd->getArgNext(immArg); + immArg = info.compCompHnd->getArgNext(immArg); + CORINFO_CLASS_HANDLE typeHnd = info.compCompHnd->getArgClass(sig, immArg); + CorInfoType otherBaseJitType = getBaseJitTypeAndSizeOfSIMDType(typeHnd, immSimdSize); + *immSimdBaseType = JitType2PreciseVarType(otherBaseJitType); } // For imm1 use default simd sizes. } @@ -362,14 +333,30 @@ 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: + case NI_Sve2_MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven: + case NI_Sve2_MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd: + case NI_Sve2_MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven: + case NI_Sve2_MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd: + case NI_Sve2_MultiplyDoublingWideningSaturateEvenBySelectedScalar: + case NI_Sve2_MultiplyDoublingWideningSaturateOddBySelectedScalar: + // 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 @@ -458,11 +445,16 @@ void HWIntrinsicInfo::lookupImmBounds( break; case NI_Sve_AddRotateComplex: + case NI_Sve2_AddRotateComplex: + case NI_Sve2_AddSaturateRotateComplex: immLowerBound = 0; immUpperBound = 1; break; case NI_Sve_MultiplyAddRotateComplex: + case NI_Sve2_MultiplyAddRotateComplex: + case NI_Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex: + case NI_Sve2_DotProductRotateComplex: immLowerBound = 0; immUpperBound = 3; break; @@ -488,6 +480,58 @@ void HWIntrinsicInfo::lookupImmBounds( } break; + case NI_Sve2_DotProductRotateComplexBySelectedIndex: + if (immNumber == 1) + { + // Bounds for rotation + immLowerBound = 0; + immUpperBound = 3; + } + else + { + // Bounds for index + assert(immNumber == 2); + assert(baseType == TYP_BYTE || baseType == TYP_SHORT); + immLowerBound = 0; + immUpperBound = (baseType == TYP_BYTE) ? 3 : 1; + } + break; + + case NI_Sve2_MultiplyAddRotateComplexBySelectedScalar: + if (immNumber == 1) + { + // Bounds for rotation + immLowerBound = 0; + immUpperBound = 3; + } + else + { + // Bounds for index + assert(immNumber == 2); + assert(baseType == TYP_USHORT || baseType == TYP_SHORT || baseType == TYP_INT || + baseType == TYP_UINT); + immLowerBound = 0; + immUpperBound = (baseType == TYP_USHORT || baseType == TYP_SHORT) ? 3 : 1; + } + break; + + case NI_Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar: + if (immNumber == 1) + { + // Bounds for rotation + immLowerBound = 0; + immUpperBound = 3; + } + else + { + // Bounds for index + assert(immNumber == 2); + assert(baseType == TYP_INT || baseType == TYP_SHORT); + immLowerBound = 0; + immUpperBound = (baseType == TYP_SHORT) ? 3 : 1; + } + break; + case NI_Sve_TrigonometricMultiplyAddCoefficient: immLowerBound = 0; immUpperBound = 7; @@ -1346,166 +1390,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; } @@ -3333,6 +3219,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, } case NI_Sve_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar: + case NI_Sve2_DotProductRotateComplexBySelectedIndex: { assert(sig->numArgs == 5); assert(!isScalar); @@ -3405,6 +3294,29 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_Sve2_AddWideningEven: + case NI_Sve2_AddWideningOdd: + case NI_Sve2_SubtractWideningEven: + case NI_Sve2_SubtractWideningOdd: + { + assert(sig->numArgs == 2); + + CORINFO_ARG_LIST_HANDLE arg1 = sig->args; + CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(arg1); + CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE; + + JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass))); + JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg1, &argClass))); + op2 = impPopStack().val; + op1 = impPopStack().val; + + CorInfoType op1BaseJitType = getBaseJitTypeOfSIMDType(argClass); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); + retNode->AsHWIntrinsic()->SetSimdBaseJitType(simdBaseJitType); + retNode->AsHWIntrinsic()->SetAuxiliaryJitType(op1BaseJitType); + break; + } + default: { return nullptr; diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 9b80d48f3711fa..13c7163c4fcbb1 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -368,8 +368,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { if (isRMW) { - assert((targetReg == op1Reg) || (targetReg != op2Reg)); - assert((targetReg == op1Reg) || (targetReg != op3Reg)); + assert((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar(intrin.op1, intrin.op2)); + assert((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar(intrin.op1, intrin.op3)); GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); HWIntrinsicImmOpHelper helper(this, intrin.op4, node); @@ -412,8 +412,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { if (isRMW) { - assert((targetReg == op1Reg) || (targetReg != op2Reg)); - assert((targetReg == op1Reg) || (targetReg != op3Reg)); + assert((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar(intrin.op1, intrin.op2)); + assert((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar(intrin.op1, intrin.op3)); GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); GetEmitter()->emitIns_R_R_R_I(ins, emitSize, targetReg, op2Reg, op3Reg, 0, opt); } @@ -511,7 +511,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) // If `falseReg` is zero, then move the first operand of `intrinEmbMask` in the // destination using /Z. - assert((targetReg != embMaskOp2Reg) || (embMaskOp1Reg == embMaskOp2Reg)); + assert((targetReg != embMaskOp2Reg) || (embMaskOp1Reg == embMaskOp2Reg) || + genIsSameLocalVar(intrinEmbMask.op1, intrinEmbMask.op2)); assert(intrin.op3->isContained() || !intrin.op1->IsTrueMask(node->GetSimdBaseType())); GetEmitter()->emitInsSve_R_R_R(INS_sve_movprfx, emitSize, targetReg, maskReg, embMaskOp1Reg, opt); } @@ -582,6 +583,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_ConvertToInt32: case NI_Sve_ConvertToUInt32: case NI_Sve_ConvertToSingle: + case NI_Sve2_ConvertToSingleEvenRoundToOdd: { embOpt = emitTypeSize(intrinEmbMask.baseType) == EA_8BYTE ? INS_OPTS_D_TO_S : INS_OPTS_SCALABLE_S; @@ -591,6 +593,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_ConvertToInt64: case NI_Sve_ConvertToUInt64: case NI_Sve_ConvertToDouble: + case NI_Sve2_ConvertToDoubleOdd: { embOpt = emitTypeSize(intrinEmbMask.baseType) == EA_4BYTE ? INS_OPTS_S_TO_D : INS_OPTS_SCALABLE_D; @@ -670,38 +673,6 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) // Perform the actual "predicated" operation so that `embMaskOp1Reg` is the first operand.. switch (intrinEmbMask.id) { - case NI_Sve_LoadVectorByteNonFaultingZeroExtendToInt16: - case NI_Sve_LoadVectorByteNonFaultingZeroExtendToInt32: - case NI_Sve_LoadVectorByteNonFaultingZeroExtendToInt64: - case NI_Sve_LoadVectorByteNonFaultingZeroExtendToUInt16: - case NI_Sve_LoadVectorByteNonFaultingZeroExtendToUInt32: - case NI_Sve_LoadVectorByteNonFaultingZeroExtendToUInt64: - case NI_Sve_LoadVectorInt16NonFaultingSignExtendToInt32: - case NI_Sve_LoadVectorInt16NonFaultingSignExtendToInt64: - case NI_Sve_LoadVectorInt16NonFaultingSignExtendToUInt32: - case NI_Sve_LoadVectorInt16NonFaultingSignExtendToUInt64: - case NI_Sve_LoadVectorInt32NonFaultingSignExtendToInt64: - case NI_Sve_LoadVectorInt32NonFaultingSignExtendToUInt64: - case NI_Sve_LoadVectorNonFaulting: - case NI_Sve_LoadVectorSByteNonFaultingSignExtendToInt16: - case NI_Sve_LoadVectorSByteNonFaultingSignExtendToInt32: - case NI_Sve_LoadVectorSByteNonFaultingSignExtendToInt64: - case NI_Sve_LoadVectorSByteNonFaultingSignExtendToUInt16: - case NI_Sve_LoadVectorSByteNonFaultingSignExtendToUInt32: - case NI_Sve_LoadVectorSByteNonFaultingSignExtendToUInt64: - case NI_Sve_LoadVectorUInt16NonFaultingZeroExtendToInt32: - case NI_Sve_LoadVectorUInt16NonFaultingZeroExtendToInt64: - case NI_Sve_LoadVectorUInt16NonFaultingZeroExtendToUInt32: - case NI_Sve_LoadVectorUInt16NonFaultingZeroExtendToUInt64: - case NI_Sve_LoadVectorUInt32NonFaultingZeroExtendToInt64: - case NI_Sve_LoadVectorUInt32NonFaultingZeroExtendToUInt64: - { - - GetEmitter()->emitIns_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp1Reg, - opt); - break; - } - case NI_Sve_And_Predicates: case NI_Sve_BitwiseClear_Predicates: case NI_Sve_Or_Predicates: @@ -797,14 +768,16 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) switch (intrinEmbMask.id) { case NI_Sve_CreateBreakPropagateMask: - assert((targetReg == embMaskOp2Reg) || (targetReg != embMaskOp1Reg)); + assert((targetReg == embMaskOp2Reg) || (targetReg != embMaskOp1Reg) || + genIsSameLocalVar(intrinEmbMask.op1, intrinEmbMask.op2)); GetEmitter()->emitIns_Mov(INS_sve_mov, emitSize, targetReg, embMaskOp2Reg, /* canSkip */ true); emitInsHelper(targetReg, maskReg, embMaskOp1Reg); break; case NI_Sve_AddSequentialAcross: - assert((targetReg == op1Reg) || (targetReg != embMaskOp2Reg)); + assert((targetReg == op1Reg) || (targetReg != embMaskOp2Reg) || + genIsSameLocalVar(intrinEmbMask.op1, intrinEmbMask.op2)); GetEmitter()->emitIns_Mov(INS_fmov, GetEmitter()->optGetSveElemsize(embOpt), targetReg, embMaskOp1Reg, /* canSkip */ true); emitInsHelper(targetReg, maskReg, embMaskOp2Reg); @@ -1093,7 +1066,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { if (isRMW) { - assert((targetReg == op2Reg) || (targetReg != op1Reg)); + assert((targetReg == op2Reg) || (targetReg != op1Reg) || + genIsSameLocalVar(intrin.op1, intrin.op2)); GetEmitter()->emitIns_Mov(ins_Move_Extend(intrin.op2->TypeGet(), false), emitTypeSize(node), targetReg, op2Reg, /* canSkip */ true); @@ -1113,7 +1087,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) } else if (isRMW) { - assert((targetReg == op1Reg) || (targetReg != op2Reg)); + assert((targetReg == op1Reg) || (targetReg != op2Reg) || + genIsSameLocalVar(intrin.op1, intrin.op2)); GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op2Reg, opt); @@ -1131,7 +1106,10 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { if (HWIntrinsicInfo::IsExplicitMaskedOperation(intrin.id)) { - assert((targetReg == op2Reg) || ((targetReg != op1Reg) && (targetReg != op3Reg))); + assert((targetReg == op2Reg) || (targetReg != op1Reg) || + genIsSameLocalVar(intrin.op2, intrin.op1)); + assert((targetReg == op2Reg) || (targetReg != op3Reg) || + genIsSameLocalVar(intrin.op2, intrin.op3)); GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op2Reg, /* canSkip */ true); @@ -1139,7 +1117,10 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) } else { - assert((targetReg == op1Reg) || ((targetReg != op2Reg) && (targetReg != op3Reg))); + assert((targetReg == op1Reg) || (targetReg != op2Reg) || + genIsSameLocalVar(intrin.op1, intrin.op2)); + assert((targetReg == op1Reg) || (targetReg != op3Reg) || + genIsSameLocalVar(intrin.op1, intrin.op3)); GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); @@ -1390,7 +1371,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AdvSimd_InsertScalar: { assert(isRMW); - assert((targetReg == op1Reg) || (targetReg != op3Reg)); + assert((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar(intrin.op1, intrin.op3)); GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); HWIntrinsicImmOpHelper helper(this, intrin.op2, node); @@ -1407,7 +1388,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AdvSimd_Arm64_InsertSelectedScalar: { assert(isRMW); - assert((targetReg == op1Reg) || (targetReg != op3Reg)); + assert((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar(intrin.op1, intrin.op3)); GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); const int resultIndex = (int)intrin.op2->AsIntCon()->gtIconVal; @@ -1419,7 +1400,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AdvSimd_LoadAndInsertScalar: { assert(isRMW); - assert((targetReg == op1Reg) || (targetReg != op3Reg)); + assert((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar(intrin.op1, intrin.op3)); GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); HWIntrinsicImmOpHelper helper(this, intrin.op2, node); @@ -2015,7 +1996,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) break; } - assert((targetReg == op1Reg) || (targetReg != op3Reg)); + assert((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar(intrin.op1, intrin.op3)); GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op2Reg, op3Reg, opt); break; @@ -2175,14 +2156,14 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_LoadVectorUInt32NonFaultingZeroExtendToInt64: case NI_Sve_LoadVectorUInt32NonFaultingZeroExtendToUInt64: { - if (intrin.numOperands == 2) + if (intrin.numOperands == 3) { - // We have extra argument which means there is a "use" of FFR here. Restore it back in FFR - // register. - assert(op2Reg != REG_NA); - GetEmitter()->emitIns_R(INS_sve_wrffr, emitSize, op2Reg, opt); + // We have extra argument which means there is a "use" of FFR here. Restore it back in FFR register. + assert(op3Reg != REG_NA); + GetEmitter()->emitIns_R(INS_sve_wrffr, emitSize, op3Reg, opt); } - GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg); + + GetEmitter()->emitIns_R_R_R_I(ins, emitSize, targetReg, op1Reg, op2Reg, 0, opt); break; } @@ -2309,6 +2290,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_Scatter32BitWithByteOffsetsNarrowing: case NI_Sve_Scatter8BitNarrowing: case NI_Sve_Scatter8BitWithByteOffsetsNarrowing: + case NI_Sve_ScatterWithByteOffsets: { if (!varTypeIsSIMD(intrin.op2->gtType)) { @@ -2379,8 +2361,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_SaturatingIncrementBy8BitElementCount: { assert(isRMW); - assert((targetReg == op1Reg) || (targetReg != op2Reg)); - assert((targetReg == op1Reg) || (targetReg != op3Reg)); + assert((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar(intrin.op1, intrin.op2)); + assert((targetReg == op1Reg) || (targetReg != op3Reg) || genIsSameLocalVar(intrin.op1, intrin.op3)); GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); if (intrin.op2->IsCnsIntOrI() && intrin.op3->IsCnsIntOrI()) @@ -2433,7 +2415,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_SaturatingIncrementByActiveElementCount: { // RMW semantics - assert((targetReg == op1Reg) || (targetReg != op2Reg)); + assert((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar(intrin.op1, intrin.op2)); GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); // Switch instruction if arg1 is unsigned. @@ -2473,7 +2455,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_ExtractVector: { assert(isRMW); - assert((targetReg == op1Reg) || (targetReg != op2Reg)); + assert((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar(intrin.op1, intrin.op2)); GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); HWIntrinsicImmOpHelper helper(this, intrin.op3, node); @@ -2492,7 +2474,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { assert(isRMW); assert(emitter::isFloatReg(op2Reg) == varTypeIsFloating(intrin.baseType)); - assert((targetReg == op1Reg) || (targetReg != op2Reg)); + assert((targetReg == op1Reg) || (targetReg != op2Reg) || genIsSameLocalVar(intrin.op1, intrin.op2)); GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); GetEmitter()->emitInsSve_R_R(ins, emitSize, targetReg, op2Reg, opt); @@ -2518,7 +2500,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { assert(isRMW); assert(HWIntrinsicInfo::IsExplicitMaskedOperation(intrin.id)); - assert((targetReg == op2Reg) || (targetReg != op1Reg)); + assert((targetReg == op2Reg) || (targetReg != op1Reg) || genIsSameLocalVar(intrin.op2, intrin.op1)); GetEmitter()->emitIns_Mov(INS_sve_mov, emitTypeSize(node), targetReg, op2Reg, /* canSkip */ true); GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg, INS_OPTS_SCALABLE_B); break; @@ -2590,8 +2572,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { assert(emitter::isFloatReg(targetReg)); assert(varTypeIsFloating(node->gtType) || varTypeIsSIMD(node->gtType)); - assert((targetReg == op2Reg) || (targetReg != op1Reg)); - assert((targetReg == op2Reg) || (targetReg != op3Reg)); + assert((targetReg == op2Reg) || (targetReg != op1Reg) || genIsSameLocalVar(intrin.op2, intrin.op1)); + assert((targetReg == op2Reg) || (targetReg != op3Reg) || genIsSameLocalVar(intrin.op2, intrin.op3)); GetEmitter()->emitIns_Mov(INS_sve_mov, EA_SCALABLE, targetReg, op2Reg, /* canSkip */ true, opt); GetEmitter()->emitInsSve_R_R_R(ins, EA_SCALABLE, targetReg, op1Reg, op3Reg, opt, @@ -2629,6 +2611,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) } case NI_Sve_TrigonometricMultiplyAddCoefficient: + case NI_Sve2_AddRotateComplex: + case NI_Sve2_AddSaturateRotateComplex: { assert(isRMW); @@ -2649,6 +2633,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) } case NI_Sve_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar: { assert(isRMW); assert(hasImmediateOperand); @@ -2671,19 +2657,22 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) else { // Use the helper to generate a table. The table can only use a single lookup value, therefore - // the two immediates index (0 to 1, in op4Reg) and rotation (0 to 3, in op5Reg) must be - // combined to a single value (0 to 7) + // the two immediates index and rotation must be combined to a single value assert(!intrin.op4->isContainedIntOrIImmed() && !intrin.op5->isContainedIntOrIImmed()); emitAttr scalarSize = emitActualTypeSize(node->GetSimdBaseType()); - // Combine the two immediates into op4Reg - // Shift rotation left to be out of range of index - GetEmitter()->emitIns_R_R_I(INS_lsl, scalarSize, op5Reg, op5Reg, 1); - // Combine the two values by ORing + var_types baseType = node->GetSimdBaseType(); + + const unsigned rotMask = 0b11; + const unsigned indexMask = (baseType == TYP_SHORT || baseType == TYP_USHORT) ? 0b11 : 0b1; + const unsigned numIndexBits = genCountBits(indexMask); + + GetEmitter()->emitIns_R_R_I(INS_lsl, scalarSize, op5Reg, op5Reg, numIndexBits); GetEmitter()->emitIns_R_R_R(INS_orr, scalarSize, op4Reg, op4Reg, op5Reg); - // Generate the table using the combined immediate - HWIntrinsicImmOpHelper helper(this, op4Reg, 0, 7, node, (targetReg != op1Reg) ? 2 : 1); + const unsigned upperBound = (rotMask << numIndexBits) | indexMask; + HWIntrinsicImmOpHelper helper(this, op4Reg, 0, upperBound, node, (targetReg != op1Reg) ? 2 : 1); + for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) { if (targetReg != op1Reg) @@ -2693,17 +2682,15 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GetEmitter()->emitInsSve_R_R(INS_sve_movprfx, EA_SCALABLE, targetReg, op1Reg); } - // Extract index and rotation from the immediate const int value = helper.ImmValue(); - const ssize_t index = value & 1; - const ssize_t rotation = value >> 1; + const ssize_t index = value & indexMask; + const ssize_t rotation = value >> numIndexBits; GetEmitter()->emitInsSve_R_R_R_I_I(ins, emitSize, targetReg, op2Reg, op3Reg, index, rotation, opt); } - // Restore the original values in op4Reg and op5Reg - GetEmitter()->emitIns_R_R_I(INS_and, scalarSize, op4Reg, op4Reg, 1); - GetEmitter()->emitIns_R_R_I(INS_lsr, scalarSize, op5Reg, op5Reg, 1); + GetEmitter()->emitIns_R_R_I(INS_and, scalarSize, op4Reg, op4Reg, indexMask); + GetEmitter()->emitIns_R_R_I(INS_lsr, scalarSize, op5Reg, op5Reg, numIndexBits); } break; @@ -2718,6 +2705,31 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GetEmitter()->emitInsSve_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); break; + case NI_Sve2_AddWideningEven: + { + var_types returnType = node->AsHWIntrinsic()->GetSimdBaseType(); + var_types op1Type = node->AsHWIntrinsic()->GetAuxiliaryType(); + if (returnType != op1Type) + { + ins = varTypeIsUnsigned(intrin.baseType) ? INS_sve_uaddlb : INS_sve_saddlb; + } + + GetEmitter()->emitInsSve_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); + break; + } + + case NI_Sve2_AddWideningOdd: + { + var_types returnType = node->AsHWIntrinsic()->GetSimdBaseType(); + var_types op1Type = node->AsHWIntrinsic()->GetAuxiliaryType(); + if (returnType != op1Type) + { + ins = varTypeIsUnsigned(intrin.baseType) ? INS_sve_uaddlt : INS_sve_saddlt; + } + GetEmitter()->emitInsSve_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); + break; + } + case NI_Sve2_BitwiseClearXor: case NI_Sve2_Xor: if (targetReg != op1Reg) @@ -2743,6 +2755,115 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GetEmitter()->emitInsSve_R_R_R(ins, emitSize, targetReg, op3Reg, op1Reg, INS_OPTS_SCALABLE_D); break; + case NI_Sve2_MultiplyAddRotateComplex: + case NI_Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex: + case NI_Sve2_DotProductRotateComplex: + { + assert(isRMW); + assert(hasImmediateOperand); + + HWIntrinsicImmOpHelper helper(this, intrin.op4, node, (targetReg != op1Reg) ? 2 : 1); + + for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) + { + if (targetReg != op1Reg) + { + assert(targetReg != op2Reg); + + GetEmitter()->emitInsSve_R_R(INS_sve_movprfx, EA_SCALABLE, targetReg, op1Reg); + } + + GetEmitter()->emitInsSve_R_R_R_I(ins, emitSize, targetReg, op2Reg, op3Reg, helper.ImmValue(), opt); + } + break; + } + + case NI_Sve2_DotProductRotateComplexBySelectedIndex: + { + assert(isRMW); + assert(hasImmediateOperand); + + // If both immediates are constant, we don't need a jump table + if (intrin.op4->IsCnsIntOrI() && intrin.op5->IsCnsIntOrI()) + { + if (targetReg != op1Reg) + { + assert(targetReg != op2Reg); + assert(targetReg != op3Reg); + GetEmitter()->emitInsSve_R_R(INS_sve_movprfx, EA_SCALABLE, targetReg, op1Reg); + } + + assert(intrin.op4->isContainedIntOrIImmed() && intrin.op5->isContainedIntOrIImmed()); + GetEmitter()->emitInsSve_R_R_R_I_I(ins, emitSize, targetReg, op2Reg, op3Reg, + intrin.op4->AsIntCon()->gtIconVal, + intrin.op5->AsIntCon()->gtIconVal, opt); + } + else + { + // Use the helper to generate a table. The table can only use a single lookup value, therefore + // the two immediates index and rotation must be combined to a single value + assert(!intrin.op4->isContainedIntOrIImmed() && !intrin.op5->isContainedIntOrIImmed()); + emitAttr scalarSize = emitActualTypeSize(node->GetSimdBaseType()); + + var_types baseType = node->GetSimdBaseType(); + + const unsigned rotMask = 0b11; + const unsigned indexMask = (baseType == TYP_BYTE) ? 0b11 : 0b1; + const unsigned numIndexBits = genCountBits(indexMask); + + GetEmitter()->emitIns_R_R_I(INS_lsl, scalarSize, op5Reg, op5Reg, numIndexBits); + GetEmitter()->emitIns_R_R_R(INS_orr, scalarSize, op4Reg, op4Reg, op5Reg); + + const unsigned upperBound = (rotMask << numIndexBits) | indexMask; + HWIntrinsicImmOpHelper helper(this, op4Reg, 0, upperBound, node, (targetReg != op1Reg) ? 2 : 1); + + for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) + { + if (targetReg != op1Reg) + { + assert(targetReg != op2Reg); + assert(targetReg != op3Reg); + GetEmitter()->emitInsSve_R_R(INS_sve_movprfx, EA_SCALABLE, targetReg, op1Reg); + } + + const int value = helper.ImmValue(); + const ssize_t index = value & indexMask; + const ssize_t rotation = value >> numIndexBits; + GetEmitter()->emitInsSve_R_R_R_I_I(ins, emitSize, targetReg, op2Reg, op3Reg, index, rotation, + opt); + } + + GetEmitter()->emitIns_R_R_I(INS_and, scalarSize, op4Reg, op4Reg, indexMask); + GetEmitter()->emitIns_R_R_I(INS_lsr, scalarSize, op5Reg, op5Reg, numIndexBits); + } + + break; + } + + case NI_Sve2_SubtractWideningEven: + { + var_types returnType = node->AsHWIntrinsic()->GetSimdBaseType(); + var_types op1Type = node->AsHWIntrinsic()->GetAuxiliaryType(); + if (returnType != op1Type) + { + ins = varTypeIsUnsigned(intrin.baseType) ? INS_sve_usublb : INS_sve_ssublb; + } + GetEmitter()->emitInsSve_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); + break; + } + + case NI_Sve2_SubtractWideningOdd: + { + var_types returnType = node->AsHWIntrinsic()->GetSimdBaseType(); + var_types op1Type = node->AsHWIntrinsic()->GetAuxiliaryType(); + if (returnType != op1Type) + { + ins = varTypeIsUnsigned(intrin.baseType) ? INS_sve_usublt : INS_sve_ssublt; + } + GetEmitter()->emitInsSve_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); + break; + } + default: unreached(); } diff --git a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp index 6d255a1295315c..9dc8a978174c9d 100644 --- a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp @@ -95,7 +95,7 @@ static insOpts AddEmbRoundingMode(insOpts instOptions, int8_t mode) { case 0x01: { - result |= INS_OPTS_EVEX_eb_er_rd; + result |= INS_OPTS_EVEX_er_rd; break; } @@ -1059,6 +1059,44 @@ void CodeGen::genHWIntrinsic_R_RM( { instOptions = AddEmbBroadcastMode(instOptions); } + else if ((instOptions == INS_OPTS_NONE) && !GetEmitter()->IsVexEncodableInstruction(ins)) + { + // We may have opportunistically selected an EVEX only instruction + // that isn't actually required, so fallback to the VEX compatible + // encoding to potentially save on the number of bytes emitted. + + switch (ins) + { + case INS_vbroadcastf64x2: + { + ins = INS_vbroadcastf32x4; + break; + } + + case INS_vbroadcasti64x2: + { + ins = INS_vbroadcasti32x4; + break; + } + + case INS_vmovdqa64: + { + ins = INS_movdqa32; + break; + } + + case INS_vmovdqu64: + { + ins = INS_movdqu32; + break; + } + + default: + { + break; + } + } + } OperandDesc rmOpDesc = genOperandDesc(ins, rmOp); @@ -1976,8 +2014,8 @@ void CodeGen::genBaseIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions) unsigned simdInitTempVarNum = compiler->lvaSIMDInitTempVarNum; noway_assert(simdInitTempVarNum != BAD_VAR_NUM); - bool isEBPbased; - unsigned offs = compiler->lvaFrameAddress(simdInitTempVarNum, &isEBPbased); + bool isEBPbased; + int offs = compiler->lvaFrameAddress(simdInitTempVarNum, &isEBPbased); #if !FEATURE_FIXED_OUT_ARGS if (!isEBPbased) @@ -2056,6 +2094,14 @@ void CodeGen::genBaseIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions) } baseReg = (isEBPbased) ? REG_EBP : REG_ESP; } + else if (op1->IsCnsVec()) + { + CORINFO_FIELD_HANDLE hnd = + GetEmitter()->emitSimdConst(&op1->AsVecCon()->gtSimdVal, emitTypeSize(op1)); + + baseReg = internalRegisters.GetSingle(node); + GetEmitter()->emitIns_R_C(INS_lea, emitTypeSize(TYP_I_IMPL), baseReg, hnd, 0, INS_OPTS_NONE); + } else { // Require GT_IND addr to be not contained. @@ -2137,8 +2183,8 @@ void CodeGen::genBaseIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions) unsigned simdInitTempVarNum = compiler->lvaSIMDInitTempVarNum; noway_assert(simdInitTempVarNum != BAD_VAR_NUM); - bool isEBPbased; - unsigned offs = compiler->lvaFrameAddress(simdInitTempVarNum, &isEBPbased); + bool isEBPbased; + int offs = compiler->lvaFrameAddress(simdInitTempVarNum, &isEBPbased); #if !FEATURE_FIXED_OUT_ARGS if (!isEBPbased) @@ -2577,7 +2623,8 @@ void CodeGen::genSse42Intrinsic(GenTreeHWIntrinsic* node, insOpts instOptions) regNumber op1Reg = op1->GetRegNum(); GenTree* op2 = node->Op(2); - assert(!op2->isUsedFromReg() || (op2->GetRegNum() != targetReg) || (op1Reg == targetReg)); + assert(!op2->isUsedFromReg() || (op2->GetRegNum() != targetReg) || (op1Reg == targetReg) || + genIsSameLocalVar(op1, op2)); emit->emitIns_Mov(INS_mov, emitTypeSize(targetType), targetReg, op1Reg, /* canSkip */ true); #ifdef TARGET_AMD64 diff --git a/src/coreclr/jit/hwintrinsiclistarm64.h b/src/coreclr/jit/hwintrinsiclistarm64.h index 25433249351660..ec721f567c50f3 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64.h +++ b/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/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index 9da8e45324b0ce..56cc4d3c2d9e3e 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -154,12 +154,12 @@ HARDWARE_INTRINSIC(Sve, Load3xVectorAndUnzip, HARDWARE_INTRINSIC(Sve, Load4xVectorAndUnzip, -1, 2, {INS_sve_ld4b, INS_sve_ld4b, INS_sve_ld4h, INS_sve_ld4h, INS_sve_ld4w, INS_sve_ld4w, INS_sve_ld4d, INS_sve_ld4d, INS_sve_ld4w, INS_sve_ld4d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_MultiReg|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_NeedsConsecutiveRegisters|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Sve, LoadVector, -1, 2, {INS_sve_ld1b, INS_sve_ld1b, INS_sve_ld1h, INS_sve_ld1h, INS_sve_ld1w, INS_sve_ld1w, INS_sve_ld1d, INS_sve_ld1d, INS_sve_ld1w, INS_sve_ld1d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVector128AndReplicateToVector, -1, 2, {INS_sve_ld1rqb, INS_sve_ld1rqb, INS_sve_ld1rqh, INS_sve_ld1rqh, INS_sve_ld1rqw, INS_sve_ld1rqw, INS_sve_ld1rqd, INS_sve_ld1rqd, INS_sve_ld1rqw, INS_sve_ld1rqd}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) -HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToInt16, -1, -1, {INS_invalid, INS_invalid, INS_sve_ldnf1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1b, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToUInt16, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToUInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToUInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1b, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToInt16, -1, -1, {INS_invalid, INS_invalid, INS_sve_ldnf1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1b, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToUInt16, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToUInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorByteNonFaultingZeroExtendToUInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1b, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendFirstFaulting, -1, -1, {INS_invalid, INS_invalid, INS_sve_ldff1b, INS_sve_ldff1b, INS_sve_ldff1b, INS_sve_ldff1b, INS_sve_ldff1b, INS_sve_ldff1b, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialCodeGen|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToInt16, -1, 2, {INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToInt32, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) @@ -168,28 +168,28 @@ HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToUInt16, HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToUInt32, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToUInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorFirstFaulting, -1, -1, {INS_sve_ldff1b, INS_sve_ldff1b, INS_sve_ldff1h, INS_sve_ldff1h, INS_sve_ldff1w, INS_sve_ldff1w, INS_sve_ldff1d, INS_sve_ldff1d, INS_sve_ldff1w, INS_sve_ldff1d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffect_Other) -HARDWARE_INTRINSIC(Sve, LoadVectorInt16NonFaultingSignExtendToInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sh, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorInt16NonFaultingSignExtendToInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sh, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorInt16NonFaultingSignExtendToUInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sh, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorInt16NonFaultingSignExtendToUInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sh, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorInt16NonFaultingSignExtendToInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sh, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorInt16NonFaultingSignExtendToInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sh, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorInt16NonFaultingSignExtendToUInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sh, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorInt16NonFaultingSignExtendToUInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sh, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, LoadVectorInt16SignExtendFirstFaulting, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldff1sh, INS_sve_ldff1sh, INS_sve_ldff1sh, INS_sve_ldff1sh, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialCodeGen|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, LoadVectorInt16SignExtendToInt32, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sh, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorInt16SignExtendToInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sh, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorInt16SignExtendToUInt32, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sh, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorInt16SignExtendToUInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sh, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) -HARDWARE_INTRINSIC(Sve, LoadVectorInt32NonFaultingSignExtendToInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorInt32NonFaultingSignExtendToUInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sw, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorInt32NonFaultingSignExtendToInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorInt32NonFaultingSignExtendToUInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sw, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, LoadVectorInt32SignExtendFirstFaulting, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldff1sw, INS_sve_ldff1sw, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialCodeGen|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, LoadVectorInt32SignExtendToInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorInt32SignExtendToUInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sw, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) -HARDWARE_INTRINSIC(Sve, LoadVectorNonFaulting, -1, -1, {INS_sve_ldnf1b, INS_sve_ldnf1b, INS_sve_ldnf1h, INS_sve_ldnf1h, INS_sve_ldnf1w, INS_sve_ldnf1w, INS_sve_ldnf1d, INS_sve_ldnf1d, INS_sve_ldnf1w, INS_sve_ldnf1d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorNonFaulting, -1, -1, {INS_sve_ldnf1b, INS_sve_ldnf1b, INS_sve_ldnf1h, INS_sve_ldnf1h, INS_sve_ldnf1w, INS_sve_ldnf1w, INS_sve_ldnf1d, INS_sve_ldnf1d, INS_sve_ldnf1w, INS_sve_ldnf1d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, LoadVectorNonTemporal, -1, 2, {INS_sve_ldnt1b, INS_sve_ldnt1b, INS_sve_ldnt1h, INS_sve_ldnt1h, INS_sve_ldnt1w, INS_sve_ldnt1w, INS_sve_ldnt1d, INS_sve_ldnt1d, INS_sve_ldnt1w, INS_sve_ldnt1d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) -HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToInt16, -1, -1, {INS_invalid, INS_invalid, INS_sve_ldnf1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToUInt16, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToUInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToUInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sb, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToInt16, -1, -1, {INS_invalid, INS_invalid, INS_sve_ldnf1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToUInt16, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToUInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorSByteNonFaultingSignExtendToUInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1sb, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendFirstFaulting, -1, -1, {INS_invalid, INS_invalid, INS_sve_ldff1sb, INS_sve_ldff1sb, INS_sve_ldff1sb, INS_sve_ldff1sb, INS_sve_ldff1sb, INS_sve_ldff1sb, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialCodeGen|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToInt16, -1, 2, {INS_invalid, INS_invalid, INS_sve_ld1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToInt32, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) @@ -197,17 +197,17 @@ HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToInt64, HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToUInt16, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToUInt32, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToUInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sb, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) -HARDWARE_INTRINSIC(Sve, LoadVectorUInt16NonFaultingZeroExtendToInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1h, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorUInt16NonFaultingZeroExtendToInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1h, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorUInt16NonFaultingZeroExtendToUInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1h, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorUInt16NonFaultingZeroExtendToUInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1h, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorUInt16NonFaultingZeroExtendToInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1h, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorUInt16NonFaultingZeroExtendToInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1h, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorUInt16NonFaultingZeroExtendToUInt32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1h, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorUInt16NonFaultingZeroExtendToUInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1h, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendFirstFaulting, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldff1h, INS_sve_ldff1h, INS_sve_ldff1h, INS_sve_ldff1h, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialCodeGen|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendToInt32, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1h, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendToInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1h, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendToUInt32, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1h, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendToUInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1h, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) -HARDWARE_INTRINSIC(Sve, LoadVectorUInt32NonFaultingZeroExtendToInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1w, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) -HARDWARE_INTRINSIC(Sve, LoadVectorUInt32NonFaultingZeroExtendToUInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1w, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorUInt32NonFaultingZeroExtendToInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1w, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) +HARDWARE_INTRINSIC(Sve, LoadVectorUInt32NonFaultingZeroExtendToUInt64, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldnf1w, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendFirstFaulting, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ldff1w, INS_sve_ldff1w, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation|HW_Flag_SpecialCodeGen|HW_Flag_SpecialSideEffectMask) HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToUInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) @@ -268,6 +268,7 @@ HARDWARE_INTRINSIC(Sve, Scatter32BitNarrowing, HARDWARE_INTRINSIC(Sve, Scatter32BitWithByteOffsetsNarrowing, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_st1w, INS_sve_st1w, INS_invalid, INS_invalid}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Scatter8BitNarrowing, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_st1b, INS_sve_st1b, INS_sve_st1b, INS_sve_st1b, INS_invalid, INS_invalid}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Scatter8BitWithByteOffsetsNarrowing, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_st1b, INS_sve_st1b, INS_sve_st1b, INS_sve_st1b, INS_invalid, INS_invalid}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, ScatterWithByteOffsets, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_st1w, INS_sve_st1w, INS_sve_st1d, INS_sve_st1d, INS_sve_st1w, INS_sve_st1d}, HW_Category_MemoryStore, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, SetFfr, -1, 1, {INS_sve_wrffr, INS_sve_wrffr, INS_sve_wrffr, INS_sve_wrffr, INS_sve_wrffr, INS_sve_wrffr, INS_sve_wrffr, INS_sve_wrffr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialSideEffect_Other|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, ShiftLeftLogical, -1, -1, {INS_sve_lsl, INS_sve_lsl, INS_sve_lsl, INS_sve_lsl, INS_sve_lsl, INS_sve_lsl, INS_sve_lsl, INS_sve_lsl, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve, ShiftRightArithmetic, -1, -1, {INS_sve_asr, INS_invalid, INS_sve_asr, INS_invalid, INS_sve_asr, INS_invalid, INS_sve_asr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics) @@ -312,7 +313,8 @@ HARDWARE_INTRINSIC(Sve, ZipLow, // {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // SVE2 Intrinsics -#define FIRST_NI_Sve2 NI_Sve2_AbsoluteDifferenceAdd +#define FIRST_NI_Sve2 NI_Sve2_AbsSaturate +HARDWARE_INTRINSIC(Sve2, AbsSaturate, -1, -1, {INS_sve_sqabs, INS_invalid, INS_sve_sqabs, INS_invalid, INS_sve_sqabs, INS_invalid, INS_sve_sqabs, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceAdd, -1, 3, {INS_sve_saba, INS_sve_uaba, INS_sve_saba, INS_sve_uaba, INS_sve_saba, INS_sve_uaba, INS_sve_saba, INS_sve_uaba, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceWideningEven, -1, 2, {INS_invalid, INS_invalid, INS_sve_sabdlb, INS_sve_uabdlb, INS_sve_sabdlb, INS_sve_uabdlb, INS_sve_sabdlb, INS_sve_uabdlb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceWideningLowerAndAddEven, -1, 3, {INS_invalid, INS_invalid, INS_sve_sabalb, INS_sve_uabalb, INS_sve_sabalb, INS_sve_uabalb, INS_sve_sabalb, INS_sve_uabalb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasRMWSemantics) @@ -323,21 +325,82 @@ HARDWARE_INTRINSIC(Sve2, AddCarryWideningOdd, HARDWARE_INTRINSIC(Sve2, AddHighNarrowingEven, -1, 2, {INS_sve_addhnb, INS_sve_addhnb, INS_sve_addhnb, INS_sve_addhnb, INS_sve_addhnb, INS_sve_addhnb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) 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, AddPairwiseWidening, -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, 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, AddRotateComplex, -1, 3, {INS_sve_cadd, INS_sve_cadd, INS_sve_cadd, INS_sve_cadd, INS_sve_cadd, INS_sve_cadd, INS_sve_cadd, INS_sve_cadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_SpecialCodeGen) +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, AddSaturateRotateComplex, -1, 3, {INS_sve_sqcadd, INS_invalid, INS_sve_sqcadd, INS_invalid, INS_sve_sqcadd, INS_invalid, INS_sve_sqcadd, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_SpecialCodeGen) 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) -HARDWARE_INTRINSIC(Sve2, AddWideLower, -1, 2, {INS_invalid, INS_invalid, INS_sve_saddwb, INS_sve_uaddwb, INS_sve_saddwb, INS_sve_uaddwb, INS_sve_saddwb, INS_sve_uaddwb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Sve2, AddWideUpper, -1, 2, {INS_invalid, INS_invalid, INS_sve_saddwt, INS_sve_uaddwt, INS_sve_saddwt, INS_sve_uaddwt, INS_sve_saddwt, INS_sve_uaddwt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Sve2, AddWideningLower, -1, 2, {INS_invalid, INS_invalid, INS_sve_saddlb, INS_sve_uaddlb, INS_sve_saddlb, INS_sve_uaddlb, INS_sve_saddlb, INS_sve_uaddlb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) -HARDWARE_INTRINSIC(Sve2, AddWideningLowerUpper, -1, 2, {INS_invalid, INS_invalid, INS_sve_saddlbt, INS_invalid, INS_sve_saddlbt, INS_invalid, INS_sve_saddlbt, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) -HARDWARE_INTRINSIC(Sve2, AddWideningUpper, -1, 2, {INS_invalid, INS_invalid, INS_sve_saddlt, INS_sve_uaddlt, INS_sve_saddlt, INS_sve_uaddlt, INS_sve_saddlt, INS_sve_uaddlt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, AddWideningEven, -1, 2, {INS_invalid, INS_invalid, INS_sve_saddwb, INS_sve_uaddwb, INS_sve_saddwb, INS_sve_uaddwb, INS_sve_saddwb, INS_sve_uaddwb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Sve2, AddWideningEvenOdd, -1, 2, {INS_invalid, INS_invalid, INS_sve_saddlbt, INS_invalid, INS_sve_saddlbt, INS_invalid, INS_sve_saddlbt, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, AddWideningOdd, -1, 2, {INS_invalid, INS_invalid, INS_sve_saddwt, INS_sve_uaddwt, INS_sve_saddwt, INS_sve_uaddwt, INS_sve_saddwt, INS_sve_uaddwt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve2, BitwiseClearXor, -1, 3, {INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, BitwiseSelect, -1, 3, {INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) 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, ConvertToDoubleOdd, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcvtlt, INS_sve_fcvtlt}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve2, ConvertToSingleEvenRoundToOdd, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcvtx, INS_sve_fcvtx}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve2, DotProductRotateComplex, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cdot, INS_invalid, INS_sve_cdot, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_SpecialCodeGen|HW_Flag_HasImmediateOperand) +HARDWARE_INTRINSIC(Sve2, DotProductRotateComplexBySelectedIndex, -1, 5, {INS_sve_cdot, INS_invalid, INS_sve_cdot, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_SpecialCodeGen|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation|HW_Flag_SpecialImport|HW_Flag_BaseTypeFromSecondArg) +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, Log2, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_flogb, INS_invalid, INS_sve_flogb, INS_invalid, INS_sve_flogb, INS_sve_flogb}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve2, MaxNumberPairwise, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmaxnmp, INS_sve_fmaxnmp}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MaxPairwise, -1, -1, {INS_sve_smaxp, INS_sve_umaxp, INS_sve_smaxp, INS_sve_umaxp, INS_sve_smaxp, INS_sve_umaxp, INS_sve_smaxp, INS_sve_umaxp, INS_sve_fmaxp, INS_sve_fmaxp}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_ReduceOperation) +HARDWARE_INTRINSIC(Sve2, MinNumberPairwise, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fminnmp, INS_sve_fminnmp}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MinPairwise, -1, -1, {INS_sve_sminp, INS_sve_uminp, INS_sve_sminp, INS_sve_uminp, INS_sve_sminp, INS_sve_uminp, INS_sve_sminp, INS_sve_uminp, INS_sve_fminp, INS_sve_fminp}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_ReduceOperation) +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, MultiplyAddRotateComplex, -1, 4, {INS_sve_cmla, INS_sve_cmla, INS_sve_cmla, INS_sve_cmla, INS_sve_cmla, INS_sve_cmla, INS_sve_cmla, INS_sve_cmla, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_SpecialCodeGen|HW_Flag_HasImmediateOperand) +HARDWARE_INTRINSIC(Sve2, MultiplyAddRotateComplexBySelectedScalar, -1, 5, {INS_invalid, INS_invalid, INS_sve_cmla, INS_sve_cmla, INS_sve_cmla, INS_sve_cmla, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation|HW_Flag_HasRMWSemantics|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(Sve2, MultiplyAddRoundedDoublingSaturateHighRotateComplex, -1, 4, {INS_sve_sqrdcmlah, INS_invalid, INS_sve_sqrdcmlah, INS_invalid, INS_sve_sqrdcmlah, INS_invalid, INS_sve_sqrdcmlah, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_SpecialCodeGen|HW_Flag_HasImmediateOperand) +HARDWARE_INTRINSIC(Sve2, MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar, -1, 5, {INS_invalid, INS_invalid, INS_sve_sqrdcmlah, INS_invalid, INS_sve_sqrdcmlah, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation|HW_Flag_HasRMWSemantics|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport) +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, MultiplyDoublingBySelectedScalarSaturateHigh, -1, 3, {INS_invalid, INS_invalid, INS_sve_sqdmulh, INS_invalid, INS_sve_sqdmulh, INS_invalid, INS_sve_sqdmulh, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingSaturateHigh, -1, 2, {INS_sve_sqdmulh, INS_invalid, INS_sve_sqdmulh, INS_invalid, INS_sve_sqdmulh, INS_invalid, INS_sve_sqdmulh, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningAndAddSaturateEven, -1, 3, {INS_invalid, INS_invalid, INS_sve_sqdmlalb, INS_invalid, INS_sve_sqdmlalb, INS_invalid, INS_sve_sqdmlalb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningAndAddSaturateEvenOdd, -1, 3, {INS_invalid, INS_invalid, INS_sve_sqdmlalbt, INS_invalid, INS_sve_sqdmlalbt, INS_invalid, INS_sve_sqdmlalbt, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningAndAddSaturateOdd, -1, 3, {INS_invalid, INS_invalid, INS_sve_sqdmlalt, INS_invalid, INS_sve_sqdmlalt, INS_invalid, INS_sve_sqdmlalt, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningAndSubtractSaturateEven, -1, 3, {INS_invalid, INS_invalid, INS_sve_sqdmlslb, INS_invalid, INS_sve_sqdmlslb, INS_invalid, INS_sve_sqdmlslb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningAndSubtractSaturateEvenOdd, -1, 3, {INS_invalid, INS_invalid, INS_sve_sqdmlslbt, INS_invalid, INS_sve_sqdmlslbt, INS_invalid, INS_sve_sqdmlslbt, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningAndSubtractSaturateOdd, -1, 3, {INS_invalid, INS_invalid, INS_sve_sqdmlslt, INS_invalid, INS_sve_sqdmlslt, INS_invalid, INS_sve_sqdmlslt, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqdmlalb, INS_invalid, INS_sve_sqdmlalb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqdmlalt, INS_invalid, INS_sve_sqdmlalt, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqdmlslb, INS_invalid, INS_sve_sqdmlslb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqdmlslt, INS_invalid, INS_sve_sqdmlslt, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningSaturateEven, -1, 2, {INS_invalid, INS_invalid, INS_sve_sqdmullb, INS_invalid, INS_sve_sqdmullb, INS_invalid, INS_sve_sqdmullb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningSaturateEvenBySelectedScalar, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqdmullb, INS_invalid, INS_sve_sqdmullb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningSaturateOdd, -1, 2, {INS_invalid, INS_invalid, INS_sve_sqdmullt, INS_invalid, INS_sve_sqdmullt, INS_invalid, INS_sve_sqdmullt, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, MultiplyDoublingWideningSaturateOddBySelectedScalar, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sqdmullt, INS_invalid, INS_sve_sqdmullt, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyRoundedDoublingBySelectedScalarSaturateHigh, -1, 3, {INS_invalid, INS_invalid, INS_sve_sqrdmulh, INS_invalid, INS_sve_sqrdmulh, INS_invalid, INS_sve_sqrdmulh, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyRoundedDoublingSaturateAndAddHigh, -1, 3, {INS_sve_sqrdmlah, INS_invalid, INS_sve_sqrdmlah, INS_invalid, INS_sve_sqrdmlah, INS_invalid, INS_sve_sqrdmlah, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyRoundedDoublingSaturateAndSubtractHigh, -1, 3, {INS_sve_sqrdmlsh, INS_invalid, INS_sve_sqrdmlsh, INS_invalid, INS_sve_sqrdmlsh, INS_invalid, INS_sve_sqrdmlsh, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh, -1, 4, {INS_invalid, INS_invalid, INS_sve_sqrdmlah, INS_invalid, INS_sve_sqrdmlah, INS_invalid, INS_sve_sqrdmlah, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh, -1, 4, {INS_invalid, INS_invalid, INS_sve_sqrdmlsh, INS_invalid, INS_sve_sqrdmlsh, INS_invalid, INS_sve_sqrdmlsh, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyRoundedDoublingSaturateHigh, -1, 2, {INS_sve_sqrdmulh, INS_invalid, INS_sve_sqrdmulh, INS_invalid, INS_sve_sqrdmulh, INS_invalid, INS_sve_sqrdmulh, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +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, NegateSaturate, -1, -1, {INS_sve_sqneg, INS_invalid, INS_sve_sqneg, INS_invalid, INS_sve_sqneg, INS_invalid, INS_sve_sqneg, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +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, ReciprocalEstimate, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_urecpe, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve2, ReciprocalSqrtEstimate, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ursqrte, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) 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) @@ -350,8 +413,8 @@ HARDWARE_INTRINSIC(Sve2, ShiftLogicalRounded, HARDWARE_INTRINSIC(Sve2, ShiftLogicalRoundedSaturate, -1, -1, {INS_invalid, INS_sve_uqrshl, INS_invalid, INS_sve_uqrshl, INS_invalid, INS_sve_uqrshl, INS_invalid, INS_sve_uqrshl, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, ShiftRightAndInsert, -1, 3, {INS_sve_sri, INS_sve_sri, INS_sve_sri, INS_sve_sri, INS_sve_sri, INS_sve_sri, INS_sve_sri, INS_sve_sri, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, ShiftRightArithmeticAdd, -1, 3, {INS_sve_ssra, INS_invalid, INS_sve_ssra, INS_invalid, INS_sve_ssra, INS_invalid, INS_sve_ssra, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sve2, ShiftRightArithmeticNarrowingSaturateEven, -1, 2, {INS_sve_sqshrnb, INS_sve_uqshrnb, INS_sve_sqshrnb, INS_sve_uqshrnb, INS_sve_sqshrnb, INS_sve_uqshrnb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand) -HARDWARE_INTRINSIC(Sve2, ShiftRightArithmeticNarrowingSaturateOdd, -1, 3, {INS_sve_sqshrnt, INS_sve_uqshrnt, INS_sve_sqshrnt, INS_sve_uqshrnt, INS_sve_sqshrnt, INS_sve_uqshrnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, ShiftRightArithmeticNarrowingSaturateEven, -1, 2, {INS_sve_sqshrnb, INS_invalid, INS_sve_sqshrnb, INS_invalid, INS_sve_sqshrnb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand) +HARDWARE_INTRINSIC(Sve2, ShiftRightArithmeticNarrowingSaturateOdd, -1, 3, {INS_sve_sqshrnt, INS_invalid, INS_sve_sqshrnt, INS_invalid, INS_sve_sqshrnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, ShiftRightArithmeticNarrowingSaturateUnsignedEven, -1, 2, {INS_invalid, INS_sve_sqshrunb, INS_invalid, INS_sve_sqshrunb, INS_invalid, INS_sve_sqshrunb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand) HARDWARE_INTRINSIC(Sve2, ShiftRightArithmeticNarrowingSaturateUnsignedOdd, -1, 3, {INS_invalid, INS_sve_sqshrunt, INS_invalid, INS_sve_sqshrunt, INS_invalid, INS_sve_sqshrunt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, ShiftRightArithmeticRounded, -1, -1, {INS_sve_srshr, INS_invalid, INS_sve_srshr, INS_invalid, INS_sve_srshr, INS_invalid, INS_sve_srshr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand) @@ -369,8 +432,19 @@ 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, 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, 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, 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, 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) HARDWARE_INTRINSIC(Sve2, XorRotateRight, -1, 3, {INS_sve_xar, INS_sve_xar, INS_sve_xar, INS_sve_xar, INS_sve_xar, INS_sve_xar, INS_sve_xar, INS_sve_xar, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand) #define LAST_NI_Sve2 NI_Sve2_XorRotateRight diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h index bcde3fb59fad2e..be680becff0b52 100644 --- a/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/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) @@ -429,17 +429,17 @@ HARDWARE_INTRINSIC(X86Base, AndNot, HARDWARE_INTRINSIC(X86Base, Average, 16, 2, {INS_invalid, INS_pavgb, INS_invalid, INS_pavgw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(X86Base, BitScanForward, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_bsf, INS_bsf, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(X86Base, BitScanReverse, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_bsr, INS_bsr, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_NoRMWSemantics) -HARDWARE_INTRINSIC(X86Base, CompareEqual, 16, 2, {INS_pcmpeqb, INS_pcmpeqb, INS_pcmpeqw, INS_pcmpeqw, INS_pcmpeqd, INS_pcmpeqd, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(X86Base, CompareGreaterThan, 16, 2, {INS_pcmpgtb, INS_invalid, INS_pcmpgtw, INS_invalid, INS_pcmpgtd, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(X86Base, CompareGreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(X86Base, CompareLessThan, 16, 2, {INS_pcmpgtb, INS_invalid, INS_pcmpgtw, INS_invalid, INS_pcmpgtd, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(X86Base, CompareLessThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(X86Base, CompareNotEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(X86Base, CompareNotGreaterThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(X86Base, CompareNotGreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(X86Base, CompareNotLessThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(X86Base, CompareNotLessThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(X86Base, CompareOrdered, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) +HARDWARE_INTRINSIC(X86Base, CompareEqual, 16, 2, {INS_pcmpeqb, INS_pcmpeqb, INS_pcmpeqw, INS_pcmpeqw, INS_pcmpeqd, INS_pcmpeqd, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(X86Base, CompareGreaterThan, 16, 2, {INS_pcmpgtb, INS_invalid, INS_pcmpgtw, INS_invalid, INS_pcmpgtd, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(X86Base, CompareGreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(X86Base, CompareLessThan, 16, 2, {INS_pcmpgtb, INS_invalid, INS_pcmpgtw, INS_invalid, INS_pcmpgtd, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(X86Base, CompareLessThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(X86Base, CompareNotEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(X86Base, CompareNotGreaterThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(X86Base, CompareNotGreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(X86Base, CompareNotLessThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(X86Base, CompareNotLessThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(X86Base, CompareOrdered, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(X86Base, CompareScalarEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpss, INS_cmpsd}, HW_Category_SIMDScalar, HW_Flag_CopyUpperBits|HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(X86Base, CompareScalarGreaterThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpss, INS_cmpsd}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_CopyUpperBits|HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(X86Base, CompareScalarGreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpss, INS_cmpsd}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_CopyUpperBits|HW_Flag_NoEvexSemantics) @@ -464,7 +464,7 @@ HARDWARE_INTRINSIC(X86Base, CompareScalarUnorderedGreaterThanOrEqual, HARDWARE_INTRINSIC(X86Base, CompareScalarUnorderedLessThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ucomiss, INS_ucomisd}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(X86Base, CompareScalarUnorderedLessThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ucomiss, INS_ucomisd}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(X86Base, CompareScalarUnorderedNotEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ucomiss, INS_ucomisd}, HW_Category_SIMDScalar, HW_Flag_Commutative|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) -HARDWARE_INTRINSIC(X86Base, CompareUnordered, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) +HARDWARE_INTRINSIC(X86Base, CompareUnordered, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(X86Base, ConvertScalarToVector128Double, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtsi2sd32, INS_invalid, INS_invalid, INS_invalid, INS_cvtss2sd, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromSecondArg) HARDWARE_INTRINSIC(X86Base, ConvertScalarToVector128Int32, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movd32, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(X86Base, ConvertScalarToVector128Single, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtsi2ss32, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtsd2ss}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromSecondArg|HW_Flag_CopyUpperBits) @@ -570,12 +570,12 @@ HARDWARE_INTRINSIC(SSE42, Abs, HARDWARE_INTRINSIC(SSE42, AddSubtract, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_addsubps, INS_addsubpd}, HW_Category_SimpleSIMD, HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(SSE42, AlignRight, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_palignr, INS_palignr, INS_palignr, INS_palignr, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_NormalizeSmallTypeToInt) HARDWARE_INTRINSIC(SSE42, Blend, 16, 3, {INS_invalid, INS_invalid, INS_pblendw, INS_pblendw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_blendps, INS_blendpd}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(SSE42, BlendVariable, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pblendvb, INS_pblendvb, INS_pblendvb, INS_pblendvb, INS_blendvps, INS_blendvpd}, HW_Category_SimpleSIMD, HW_Flag_NoEvexSemantics|HW_Flag_NormalizeSmallTypeToInt) +HARDWARE_INTRINSIC(SSE42, BlendVariable, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pblendvb, INS_pblendvb, INS_pblendvb, INS_pblendvb, INS_blendvps, INS_blendvpd}, HW_Category_SimpleSIMD, HW_Flag_NoEvexSemantics|HW_Flag_NormalizeSmallTypeToInt|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(SSE42, Ceiling, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_roundps, INS_roundpd}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(SSE42, CeilingScalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_roundss, INS_roundsd}, HW_Category_SIMDScalar, HW_Flag_CopyUpperBits) -HARDWARE_INTRINSIC(SSE42, CompareEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pcmpeqq, INS_pcmpeqq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(SSE42, CompareGreaterThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pcmpgtq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(SSE42, CompareLessThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pcmpgtq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) +HARDWARE_INTRINSIC(SSE42, CompareEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pcmpeqq, INS_pcmpeqq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(SSE42, CompareGreaterThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pcmpgtq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(SSE42, CompareLessThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pcmpgtq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(SSE42, ConvertToVector128Int16, 16, 1, {INS_pmovsxbw, INS_pmovzxbw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics|HW_Flag_MaybeMemoryLoad) HARDWARE_INTRINSIC(SSE42, ConvertToVector128Int32, 16, 1, {INS_pmovsxbd, INS_pmovzxbd, INS_pmovsxwd, INS_pmovzxwd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics|HW_Flag_MaybeMemoryLoad) HARDWARE_INTRINSIC(SSE42, ConvertToVector128Int64, 16, 1, {INS_pmovsxbq, INS_pmovzxbq, INS_pmovsxwq, INS_pmovzxwq, INS_pmovsxdq, INS_pmovzxdq, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics|HW_Flag_MaybeMemoryLoad) @@ -645,25 +645,25 @@ HARDWARE_INTRINSIC(AVX, AddSubtract, HARDWARE_INTRINSIC(AVX, And, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_andps, INS_andpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AVX, AndNot, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_andnps, INS_andnpd}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport) HARDWARE_INTRINSIC(AVX, Blend, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_blendps, INS_blendpd}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, BlendVariable, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vblendvps, INS_vblendvpd}, HW_Category_SimpleSIMD, HW_Flag_NoEvexSemantics) +HARDWARE_INTRINSIC(AVX, BlendVariable, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vblendvps, INS_vblendvpd}, HW_Category_SimpleSIMD, HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(AVX, BroadcastScalarToVector128, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcastss, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX, BroadcastScalarToVector256, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcastss, INS_vbroadcastsd}, HW_Category_MemoryLoad, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX, BroadcastVector128ToVector256, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcastf32x4, INS_vbroadcastf32x4}, HW_Category_MemoryLoad, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX, Ceiling, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_roundps, INS_roundpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX, Compare, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_IMM, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) -HARDWARE_INTRINSIC(AVX, CompareEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, CompareGreaterThan, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, CompareGreaterThanOrEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, CompareLessThan, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, CompareLessThanOrEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, CompareNotEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, CompareNotGreaterThan, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, CompareNotGreaterThanOrEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, CompareNotLessThan, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, CompareNotLessThanOrEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX, CompareOrdered, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) +HARDWARE_INTRINSIC(AVX, CompareEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX, CompareGreaterThan, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX, CompareGreaterThanOrEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX, CompareLessThan, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX, CompareLessThanOrEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX, CompareNotEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX, CompareNotGreaterThan, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX, CompareNotGreaterThanOrEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX, CompareNotLessThan, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX, CompareNotLessThanOrEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX, CompareOrdered, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(AVX, CompareScalar, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpss, INS_cmpsd}, HW_Category_IMM, HW_Flag_CopyUpperBits|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) -HARDWARE_INTRINSIC(AVX, CompareUnordered, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) +HARDWARE_INTRINSIC(AVX, CompareUnordered, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmpps, INS_cmppd}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(AVX, ConvertToVector128Int32, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtpd2dq, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtpd2dq}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX, ConvertToVector128Int32WithTruncation, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvttpd2dq, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX, ConvertToVector128Single, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtpd2ps}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) @@ -729,13 +729,13 @@ HARDWARE_INTRINSIC(AVX2, AndNot, HARDWARE_INTRINSIC(AVX2, Average, 32, 2, {INS_invalid, INS_pavgb, INS_invalid, INS_pavgw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AVX2, BitFieldExtract, 0, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_bextr, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFloatingPointUsed|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_NoEvexSemantics) HARDWARE_INTRINSIC(AVX2, Blend, -1, 3, {INS_invalid, INS_invalid, INS_pblendw, INS_pblendw, INS_vpblendd, INS_vpblendd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX2, BlendVariable, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpblendvb, INS_vpblendvb, INS_vpblendvb, INS_vpblendvb, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoEvexSemantics|HW_Flag_NormalizeSmallTypeToInt) +HARDWARE_INTRINSIC(AVX2, BlendVariable, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpblendvb, INS_vpblendvb, INS_vpblendvb, INS_vpblendvb, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoEvexSemantics|HW_Flag_NormalizeSmallTypeToInt|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(AVX2, BroadcastScalarToVector128, 16, 1, {INS_vpbroadcastb, INS_vpbroadcastb, INS_vpbroadcastw, INS_vpbroadcastw, INS_vpbroadcastd, INS_vpbroadcastd, INS_vpbroadcastq, INS_vpbroadcastq, INS_vbroadcastss, INS_movddup}, HW_Category_SIMDScalar, HW_Flag_MaybeMemoryLoad) HARDWARE_INTRINSIC(AVX2, BroadcastScalarToVector256, 32, 1, {INS_vpbroadcastb, INS_vpbroadcastb, INS_vpbroadcastw, INS_vpbroadcastw, INS_vpbroadcastd, INS_vpbroadcastd, INS_vpbroadcastq, INS_vpbroadcastq, INS_vbroadcastss, INS_vbroadcastsd}, HW_Category_SIMDScalar, HW_Flag_MaybeMemoryLoad) HARDWARE_INTRINSIC(AVX2, BroadcastVector128ToVector256, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcasti32x4, INS_vbroadcasti32x4, INS_vbroadcasti32x4, INS_vbroadcasti32x4, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NormalizeSmallTypeToInt) -HARDWARE_INTRINSIC(AVX2, CompareEqual, 32, 2, {INS_pcmpeqb, INS_pcmpeqb, INS_pcmpeqw, INS_pcmpeqw, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqq, INS_pcmpeqq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX2, CompareGreaterThan, 32, 2, {INS_pcmpgtb, INS_invalid, INS_pcmpgtw, INS_invalid, INS_pcmpgtd, INS_invalid, INS_pcmpgtq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) -HARDWARE_INTRINSIC(AVX2, CompareLessThan, 32, 2, {INS_pcmpgtb, INS_invalid, INS_pcmpgtw, INS_invalid, INS_pcmpgtd, INS_invalid, INS_pcmpgtq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics) +HARDWARE_INTRINSIC(AVX2, CompareEqual, 32, 2, {INS_pcmpeqb, INS_pcmpeqb, INS_pcmpeqw, INS_pcmpeqw, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqq, INS_pcmpeqq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX2, CompareGreaterThan, 32, 2, {INS_pcmpgtb, INS_invalid, INS_pcmpgtw, INS_invalid, INS_pcmpgtd, INS_invalid, INS_pcmpgtq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(AVX2, CompareLessThan, 32, 2, {INS_pcmpgtb, INS_invalid, INS_pcmpgtw, INS_invalid, INS_pcmpgtd, INS_invalid, INS_pcmpgtq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_ReturnsPerElementMask|HW_Flag_NoEvexSemantics|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(AVX2, ConvertToInt32, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movd32, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AVX2, ConvertToUInt32, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movd32, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AVX2, ConvertToVector256Int16, 32, 1, {INS_pmovsxbw, INS_pmovzxbw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_MaybeMemoryLoad) @@ -843,7 +843,7 @@ HARDWARE_INTRINSIC(AVX512, AlignRight64, HARDWARE_INTRINSIC(AVX512, And, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pandd, INS_pandd, INS_vpandq, INS_vpandq, INS_andps, INS_andpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_NormalizeSmallTypeToInt) HARDWARE_INTRINSIC(AVX512, AndNot, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pandnd, INS_pandnd, INS_vpandnq, INS_vpandnq, INS_andnps, INS_andnpd}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_NormalizeSmallTypeToInt) HARDWARE_INTRINSIC(AVX512, Average, 64, 2, {INS_invalid, INS_pavgb, INS_invalid, INS_pavgw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AVX512, BlendVariable, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(AVX512, BlendVariable, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(AVX512, BroadcastPairScalarToVector128, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcasti32x2, INS_vbroadcasti32x2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512, BroadcastPairScalarToVector256, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcasti32x2, INS_vbroadcasti32x2, INS_invalid, INS_invalid, INS_vbroadcastf32x2, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512, BroadcastPairScalarToVector512, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcasti32x2, INS_vbroadcasti32x2, INS_invalid, INS_invalid, INS_vbroadcastf32x2, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) @@ -852,19 +852,19 @@ HARDWARE_INTRINSIC(AVX512, BroadcastVector128ToVector512, HARDWARE_INTRINSIC(AVX512, BroadcastVector256ToVector512, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vbroadcasti32x8, INS_vbroadcasti32x8, INS_vbroadcasti64x4, INS_vbroadcasti64x4, INS_vbroadcastf32x8, INS_vbroadcastf64x4}, HW_Category_MemoryLoad, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512, Classify, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_InvalidNodeId|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512, ClassifyScalar, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_InvalidNodeId|HW_Flag_FullRangeIMM) -HARDWARE_INTRINSIC(AVX512, Compare, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_InvalidNodeId) -HARDWARE_INTRINSIC(AVX512, CompareEqual, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(AVX512, Compare, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(AVX512, CompareEqual, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(AVX512, CompareGreaterThan, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(AVX512, CompareGreaterThanOrEqual, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(AVX512, CompareLessThan, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(AVX512, CompareLessThanOrEqual, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(AVX512, CompareNotEqual, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) -HARDWARE_INTRINSIC(AVX512, CompareNotGreaterThan, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) -HARDWARE_INTRINSIC(AVX512, CompareNotGreaterThanOrEqual, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) -HARDWARE_INTRINSIC(AVX512, CompareNotLessThan, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) -HARDWARE_INTRINSIC(AVX512, CompareNotLessThanOrEqual, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) -HARDWARE_INTRINSIC(AVX512, CompareOrdered, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) -HARDWARE_INTRINSIC(AVX512, CompareUnordered, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(AVX512, CompareNotGreaterThan, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(AVX512, CompareNotGreaterThanOrEqual, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(AVX512, CompareNotLessThan, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(AVX512, CompareNotLessThanOrEqual, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(AVX512, CompareOrdered, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) +HARDWARE_INTRINSIC(AVX512, CompareUnordered, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(AVX512, Compress, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_InvalidNodeId) HARDWARE_INTRINSIC(AVX512, CompressStore, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryStore, HW_Flag_InvalidNodeId|HW_Flag_BaseTypeFromSecondArg) HARDWARE_INTRINSIC(AVX512, ConvertScalarToVector128Double, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cvtsi2sd32, INS_vcvtusi2sd32, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromSecondArg|HW_Flag_CopyUpperBits) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 7d4d4abd207b5f..c614918b2074d5 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -2397,7 +2397,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { assert(sig->numArgs == 1); - if ((simdSize == 64) || (varTypeIsShort(simdBaseType) && canUseEvexEncoding())) + if ((simdSize == 64) || canUseEvexEncoding()) { intrinsic = NI_AVX512_MoveMask; } @@ -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; } @@ -4962,6 +4914,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_SSE42_BlendVariable: + case NI_AVX_BlendVariable: + case NI_AVX2_BlendVariable: case NI_AVX512_BlendVariable: { assert(sig->numArgs == 3); @@ -4970,9 +4925,29 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - op3 = gtNewSimdCvtVectorToMaskNode(TYP_MASK, op3, simdBaseJitType, simdSize); - retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, NI_AVX512_BlendVariableMask, simdBaseJitType, - simdSize); + if ((simdSize == 64) || canUseEvexEncoding()) + { + if ((intrinsic != NI_AVX512_BlendVariable) && varTypeIsIntegral(simdBaseType)) + { + // The pre-EVEX intrinsics for integers all emitted pblendvb and so we need + // to preserve that behavior when using the EVEX variant as otherwise we'll + // get slightly different results for certain masks. + + if (varTypeIsSigned(simdBaseType)) + { + simdBaseJitType = CORINFO_TYPE_BYTE; + simdBaseType = TYP_BYTE; + } + else + { + simdBaseJitType = CORINFO_TYPE_UBYTE; + simdBaseType = TYP_UBYTE; + } + } + intrinsic = NI_AVX512_BlendVariableMask; + op3 = gtFoldExpr(gtNewSimdCvtVectorToMaskNode(TYP_MASK, op3, simdBaseJitType, simdSize)); + } + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, intrinsic, simdBaseJitType, simdSize); break; } @@ -4989,26 +4964,29 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { intrinsic = NI_AVX512_ClassifyScalarMask; } + retType = TYP_MASK; op2 = impPopStack().val; op1 = impSIMDPopStack(); - retNode = gtNewSimdHWIntrinsicNode(TYP_MASK, op1, op2, intrinsic, simdBaseJitType, simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); break; } case NI_AVX_Compare: - case NI_AVX_CompareScalar: case NI_AVX512_Compare: { - assert(sig->numArgs == 3); - - if (intrinsic == NI_AVX512_Compare) + if ((simdSize == 64) || canUseEvexEncoding()) { intrinsic = NI_AVX512_CompareMask; retType = TYP_MASK; } + FALLTHROUGH; + } + + case NI_AVX_CompareScalar: + { + assert(sig->numArgs == 3); int immLowerBound = 0; int immUpperBound = HWIntrinsicInfo::lookupImmUpperBound(intrinsic); @@ -5039,168 +5017,240 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, intrinsic, simdBaseJitType, simdSize); } - - if (retType == TYP_MASK) - { - retType = getSIMDTypeForSize(simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); - } break; } + case NI_X86Base_CompareEqual: + case NI_SSE42_CompareEqual: + case NI_AVX_CompareEqual: + case NI_AVX2_CompareEqual: case NI_AVX512_CompareEqual: { assert(sig->numArgs == 2); + if ((simdSize == 64) || canUseEvexEncoding()) + { + intrinsic = NI_AVX512_CompareEqualMask; + retType = TYP_MASK; + } + op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - retNode = - gtNewSimdHWIntrinsicNode(TYP_MASK, op1, op2, NI_AVX512_CompareEqualMask, simdBaseJitType, simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); break; } + case NI_X86Base_CompareGreaterThan: + case NI_SSE42_CompareGreaterThan: + case NI_AVX_CompareGreaterThan: + case NI_AVX2_CompareGreaterThan: case NI_AVX512_CompareGreaterThan: { assert(sig->numArgs == 2); + if ((simdSize == 64) || canUseEvexEncoding()) + { + intrinsic = NI_AVX512_CompareGreaterThanMask; + retType = TYP_MASK; + } + op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - retNode = gtNewSimdHWIntrinsicNode(TYP_MASK, op1, op2, NI_AVX512_CompareGreaterThanMask, simdBaseJitType, - simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); break; } + case NI_X86Base_CompareGreaterThanOrEqual: + case NI_AVX_CompareGreaterThanOrEqual: case NI_AVX512_CompareGreaterThanOrEqual: { assert(sig->numArgs == 2); + if ((simdSize == 64) || canUseEvexEncoding()) + { + intrinsic = NI_AVX512_CompareGreaterThanOrEqualMask; + retType = TYP_MASK; + } + op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - retNode = gtNewSimdHWIntrinsicNode(TYP_MASK, op1, op2, NI_AVX512_CompareGreaterThanOrEqualMask, - simdBaseJitType, simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); break; } + case NI_X86Base_CompareLessThan: + case NI_SSE42_CompareLessThan: + case NI_AVX_CompareLessThan: + case NI_AVX2_CompareLessThan: case NI_AVX512_CompareLessThan: { assert(sig->numArgs == 2); + if ((simdSize == 64) || canUseEvexEncoding()) + { + intrinsic = NI_AVX512_CompareLessThanMask; + retType = TYP_MASK; + } + op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - retNode = - gtNewSimdHWIntrinsicNode(TYP_MASK, op1, op2, NI_AVX512_CompareLessThanMask, simdBaseJitType, simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); break; } + case NI_X86Base_CompareLessThanOrEqual: + case NI_AVX_CompareLessThanOrEqual: case NI_AVX512_CompareLessThanOrEqual: { assert(sig->numArgs == 2); + if ((simdSize == 64) || canUseEvexEncoding()) + { + intrinsic = NI_AVX512_CompareLessThanOrEqualMask; + retType = TYP_MASK; + } + op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - retNode = gtNewSimdHWIntrinsicNode(TYP_MASK, op1, op2, NI_AVX512_CompareLessThanOrEqualMask, - simdBaseJitType, simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); break; } + case NI_X86Base_CompareNotEqual: + case NI_AVX_CompareNotEqual: case NI_AVX512_CompareNotEqual: { assert(sig->numArgs == 2); + if ((simdSize == 64) || canUseEvexEncoding()) + { + intrinsic = NI_AVX512_CompareNotEqualMask; + retType = TYP_MASK; + } + op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - retNode = - gtNewSimdHWIntrinsicNode(TYP_MASK, op1, op2, NI_AVX512_CompareNotEqualMask, simdBaseJitType, simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); break; } + case NI_X86Base_CompareNotGreaterThan: + case NI_AVX_CompareNotGreaterThan: case NI_AVX512_CompareNotGreaterThan: { assert(sig->numArgs == 2); + if ((simdSize == 64) || canUseEvexEncoding()) + { + intrinsic = NI_AVX512_CompareNotGreaterThanMask; + retType = TYP_MASK; + } + op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - retNode = gtNewSimdHWIntrinsicNode(TYP_MASK, op1, op2, NI_AVX512_CompareNotGreaterThanMask, simdBaseJitType, - simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); break; } + case NI_X86Base_CompareNotGreaterThanOrEqual: + case NI_AVX_CompareNotGreaterThanOrEqual: case NI_AVX512_CompareNotGreaterThanOrEqual: { assert(sig->numArgs == 2); + if ((simdSize == 64) || canUseEvexEncoding()) + { + intrinsic = NI_AVX512_CompareNotGreaterThanOrEqualMask; + retType = TYP_MASK; + } + op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - retNode = gtNewSimdHWIntrinsicNode(TYP_MASK, op1, op2, NI_AVX512_CompareNotGreaterThanOrEqualMask, - simdBaseJitType, simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); break; } + case NI_X86Base_CompareNotLessThan: + case NI_AVX_CompareNotLessThan: case NI_AVX512_CompareNotLessThan: { assert(sig->numArgs == 2); + if ((simdSize == 64) || canUseEvexEncoding()) + { + intrinsic = NI_AVX512_CompareNotLessThanMask; + retType = TYP_MASK; + } + op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - retNode = gtNewSimdHWIntrinsicNode(TYP_MASK, op1, op2, NI_AVX512_CompareNotLessThanMask, simdBaseJitType, - simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); break; } + case NI_X86Base_CompareNotLessThanOrEqual: + case NI_AVX_CompareNotLessThanOrEqual: case NI_AVX512_CompareNotLessThanOrEqual: { assert(sig->numArgs == 2); + if ((simdSize == 64) || canUseEvexEncoding()) + { + intrinsic = NI_AVX512_CompareNotLessThanOrEqualMask; + retType = TYP_MASK; + } + op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - retNode = gtNewSimdHWIntrinsicNode(TYP_MASK, op1, op2, NI_AVX512_CompareNotLessThanOrEqualMask, - simdBaseJitType, simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); break; } + case NI_X86Base_CompareOrdered: + case NI_AVX_CompareOrdered: case NI_AVX512_CompareOrdered: { assert(sig->numArgs == 2); + if ((simdSize == 64) || canUseEvexEncoding()) + { + intrinsic = NI_AVX512_CompareOrderedMask; + retType = TYP_MASK; + } + op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - retNode = - gtNewSimdHWIntrinsicNode(TYP_MASK, op1, op2, NI_AVX512_CompareOrderedMask, simdBaseJitType, simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); break; } + case NI_X86Base_CompareUnordered: + case NI_AVX_CompareUnordered: case NI_AVX512_CompareUnordered: { assert(sig->numArgs == 2); + if ((simdSize == 64) || canUseEvexEncoding()) + { + intrinsic = NI_AVX512_CompareUnorderedMask; + retType = TYP_MASK; + } + op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - retNode = - gtNewSimdHWIntrinsicNode(TYP_MASK, op1, op2, NI_AVX512_CompareUnorderedMask, simdBaseJitType, simdSize); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, simdBaseJitType, simdSize); break; } @@ -5429,7 +5479,13 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, } } - if (isMinMaxIntrinsic) + if (retType == TYP_MASK) + { + retType = getSIMDTypeForSize(simdSize); + assert(retType == getSIMDTypeForSize(getSIMDTypeSizeInBytes(sig->retTypeSigClass))); + retNode = gtNewSimdCvtMaskToVectorNode(retType, gtFoldExpr(retNode), simdBaseJitType, simdSize); + } + else if (isMinMaxIntrinsic) { assert(sig->numArgs == 2); assert(retNode == nullptr); diff --git a/src/coreclr/jit/ifconversion.cpp b/src/coreclr/jit/ifconversion.cpp index ef81c2580a1928..abf7f53a6b0250 100644 --- a/src/coreclr/jit/ifconversion.cpp +++ b/src/coreclr/jit/ifconversion.cpp @@ -57,6 +57,9 @@ class OptIfConversionDsc bool IfConvertCheckStmts(BasicBlock* fromBlock, IfConvertOperation* foundOperation); void IfConvertJoinStmts(BasicBlock* fromBlock); + GenTree* TryTransformSelectOperOrLocal(GenTree* oper, GenTree* lcl); + GenTree* TryTransformSelectOperOrZero(GenTree* oper, GenTree* lcl); + GenTree* TryTransformSelectToOrdinaryOps(GenTree* trueInput, GenTree* falseInput); #ifdef DEBUG void IfConvertDump(); #endif @@ -678,17 +681,8 @@ bool OptIfConversionDsc::optIfConvert() GenTree* selectFalseInput; if (m_mainOper == GT_STORE_LCL_VAR) { - if (m_doElseConversion) - { - selectTrueInput = m_elseOperation.node->AsLclVar()->Data(); - selectFalseInput = m_thenOperation.node->AsLclVar()->Data(); - } - else // Duplicate the destination of the Then store. - { - GenTreeLclVar* store = m_thenOperation.node->AsLclVar(); - selectTrueInput = m_comp->gtNewLclVarNode(store->GetLclNum(), store->TypeGet()); - selectFalseInput = m_thenOperation.node->AsLclVar()->Data(); - } + selectFalseInput = m_thenOperation.node->AsLclVar()->Data(); + selectTrueInput = m_doElseConversion ? m_elseOperation.node->AsLclVar()->Data() : nullptr; // Pick the type as the type of the local, which should always be compatible even for implicit coercions. selectType = genActualType(m_thenOperation.node); @@ -704,23 +698,20 @@ bool OptIfConversionDsc::optIfConvert() selectType = genActualType(m_thenOperation.node); } - GenTree* select = nullptr; - if (selectTrueInput->TypeIs(TYP_INT) && selectFalseInput->TypeIs(TYP_INT)) + GenTree* select = TryTransformSelectToOrdinaryOps(selectTrueInput, selectFalseInput); + if (select == nullptr) { - if (selectTrueInput->IsIntegralConst(1) && selectFalseInput->IsIntegralConst(0)) - { - // compare ? true : false --> compare - select = m_cond; - } - else if (selectTrueInput->IsIntegralConst(0) && selectFalseInput->IsIntegralConst(1)) +#ifdef TARGET_RISCV64 + JITDUMP("Skipping if-conversion that cannot be transformed to ordinary operations\n"); + return false; +#endif + if (selectTrueInput == nullptr) { - // compare ? false : true --> reversed_compare - select = m_comp->gtReverseCond(m_cond); + // Duplicate the destination of the Then store. + assert(m_mainOper == GT_STORE_LCL_VAR && !m_doElseConversion); + GenTreeLclVar* store = m_thenOperation.node->AsLclVar(); + selectTrueInput = m_comp->gtNewLclVarNode(store->GetLclNum(), store->TypeGet()); } - } - - if (select == nullptr) - { // Create a select node select = m_comp->gtNewConditionalNode(GT_SELECT, m_cond, selectTrueInput, selectFalseInput, selectType); } @@ -774,6 +765,235 @@ bool OptIfConversionDsc::optIfConvert() return true; } +struct IntConstSelectOper +{ + genTreeOps oper; + var_types type; + unsigned bitIndex; + + bool isMatched() const + { + return oper != GT_NONE; + } +}; + +//----------------------------------------------------------------------------- +// MatchIntConstSelectValues: Matches an operation so that `trueVal` can be calculated as: +// oper(type, falseVal, condition) +// +// Notes: +// A non-zero bitIndex (log2(trueVal)) differentiates (condition << bitIndex) from (falseVal << condition). +// +// Return Value: +// The matched operation (if any). +// +static IntConstSelectOper MatchIntConstSelectValues(int64_t trueVal, int64_t falseVal) +{ + if (trueVal == falseVal + 1) + return {GT_ADD, TYP_LONG}; + + if (trueVal == int64_t(int32_t(falseVal) + 1)) + return {GT_ADD, TYP_INT}; + + if (falseVal == 0) + { + unsigned bitIndex = BitOperations::Log2((uint64_t)trueVal); + assert(bitIndex > 0); + if (trueVal == (int64_t(1) << bitIndex)) + return {GT_LSH, TYP_LONG, bitIndex}; + + bitIndex = BitOperations::Log2((uint32_t)trueVal); + assert(bitIndex > 0); + if (trueVal == int64_t(int32_t(int32_t(1) << bitIndex))) + return {GT_LSH, TYP_INT, bitIndex}; + } + + if (trueVal == falseVal << 1) + return {GT_LSH, TYP_LONG}; + + if (trueVal == int64_t(int32_t(falseVal) << 1)) + return {GT_LSH, TYP_INT}; + + if (trueVal == falseVal >> 1) + return {GT_RSH, TYP_LONG}; + + if (trueVal == int64_t(int32_t(falseVal) >> 1)) + return {GT_RSH, TYP_INT}; + + if (trueVal == int64_t(uint64_t(falseVal) >> 1)) + return {GT_RSZ, TYP_LONG}; + + if (trueVal == int64_t(uint32_t(falseVal) >> 1)) + return {GT_RSZ, TYP_INT}; + + return {GT_NONE}; +} + +//----------------------------------------------------------------------------- +// TryTransformSelectOperOrLocal: Try to trasform "cond ? oper(lcl, (-)1) : lcl" into "oper(')(lcl, cond)" +// +// Arguments: +// trueInput - expression to be evaluated when m_cond is true +// falseInput - expression to be evaluated when m_cond is false +// +// Return Value: +// The transformed expression, or null if no transformation took place +// +GenTree* OptIfConversionDsc::TryTransformSelectOperOrLocal(GenTree* trueInput, GenTree* falseInput) +{ + GenTree* oper = trueInput; + GenTree* lcl = falseInput; + + bool isCondReversed = !lcl->OperIsAnyLocal(); + if (isCondReversed) + std::swap(oper, lcl); + + if (lcl->OperIsAnyLocal() && (oper->OperIs(GT_ADD, GT_OR, GT_XOR) || oper->OperIsShift())) + { + GenTree* lcl2 = oper->gtGetOp1(); + GenTree* one = oper->gtGetOp2(); + if (oper->OperIsCommutative() && !one->IsIntegralConst()) + std::swap(lcl2, one); + + bool isDecrement = oper->OperIs(GT_ADD) && one->IsIntegralConst(-1); + if (one->IsIntegralConst(1) || isDecrement) + { + unsigned lclNum = lcl->AsLclVarCommon()->GetLclNum(); + if (lcl2->OperIs(GT_LCL_VAR) && (lcl2->AsLclVar()->GetLclNum() == lclNum)) + { + oper->AsOp()->gtOp1 = lcl2; + oper->AsOp()->gtOp2 = isCondReversed ? m_comp->gtReverseCond(m_cond) : m_cond; + if (isDecrement) + oper->ChangeOper(GT_SUB); + + oper->gtFlags |= m_cond->gtFlags & GTF_ALL_EFFECT; + return oper; + } + } + } + return nullptr; +} + +//----------------------------------------------------------------------------- +// TryTransformSelectOperOrZero: Try to trasform "cond ? oper(1, expr) : 0" into "oper(cond, expr)" +// +// Arguments: +// trueInput - expression to be evaluated when m_cond is true +// falseInput - expression to be evaluated when m_cond is false +// +// Return Value: +// The transformed expression, or null if no transformation took place +// +GenTree* OptIfConversionDsc::TryTransformSelectOperOrZero(GenTree* trueInput, GenTree* falseInput) +{ + GenTree* oper = trueInput; + GenTree* zero = falseInput; + + bool isCondReversed = !zero->IsIntegralConst(); + if (isCondReversed) + std::swap(oper, zero); + + if (zero->IsIntegralConst(0) && oper->OperIs(GT_AND, GT_LSH)) + { + GenTree* one = oper->gtGetOp1(); + GenTree* expr = oper->gtGetOp2(); + if (oper->OperIsCommutative() && !one->IsIntegralConst()) + std::swap(one, expr); + + if (one->IsIntegralConst(1)) + { + oper->AsOp()->gtOp1 = isCondReversed ? m_comp->gtReverseCond(m_cond) : m_cond; + oper->AsOp()->gtOp2 = expr; + + oper->gtFlags |= m_cond->gtFlags & GTF_ALL_EFFECT; + return oper; + } + } + return nullptr; +} + +//----------------------------------------------------------------------------- +// TryTransformSelectToOrdinaryOps: Try transforming the identified if-else expressions to a single expression +// +// This is meant mostly for RISC-V where the condition (1 or 0) is stored in a regular general-purpose register +// which can be fed as an argument to standard operations, e.g. +// * (cond ? 6 : 5) becomes (5 + cond) +// * (cond ? -25 : -13) becomes (-25 >> cond) +// * if (cond) a++; becomes (a + cond) +// * (cond ? 1 << a : 0) becomes (cond << a) +// +// Arguments: +// trueInput - expression to be evaluated when m_cond is true, or null if there is no else expression +// falseInput - expression to be evaluated when m_cond is false +// +// Return Value: +// The transformed single expression equivalent to the if-else expressions, or null if no transformation took place +// +GenTree* OptIfConversionDsc::TryTransformSelectToOrdinaryOps(GenTree* trueInput, GenTree* falseInput) +{ + assert(falseInput != nullptr); + + if ((trueInput != nullptr && trueInput->IsIntegralConst()) && falseInput->IsIntegralConst()) + { + int64_t trueVal = trueInput->AsIntConCommon()->IntegralValue(); + int64_t falseVal = falseInput->AsIntConCommon()->IntegralValue(); + if (trueInput->TypeIs(TYP_INT) && falseInput->TypeIs(TYP_INT)) + { + if (trueVal == 1 && falseVal == 0) + { + // compare ? true : false --> compare + return m_cond; + } + else if (trueVal == 0 && falseVal == 1) + { + // compare ? false : true --> reversed_compare + return m_comp->gtReverseCond(m_cond); + } + } +#ifdef TARGET_RISCV64 + bool isCondReversed = false; + IntConstSelectOper selectOper = MatchIntConstSelectValues(trueVal, falseVal); + if (!selectOper.isMatched()) + { + isCondReversed = true; + selectOper = MatchIntConstSelectValues(falseVal, trueVal); + } + if (selectOper.isMatched()) + { + GenTree* left = isCondReversed ? trueInput : falseInput; + GenTree* right = isCondReversed ? m_comp->gtReverseCond(m_cond) : m_cond; + if (selectOper.bitIndex > 0) + { + assert(selectOper.oper == GT_LSH); + left->AsIntConCommon()->SetIntegralValue(selectOper.bitIndex); + std::swap(left, right); + } + return m_comp->gtNewOperNode(selectOper.oper, selectOper.type, left, right); + } + return nullptr; +#endif // TARGET_RISCV64 + } +#ifdef TARGET_RISCV64 + else + { + if (trueInput == nullptr) + { + assert(m_mainOper == GT_STORE_LCL_VAR && !m_doElseConversion); + trueInput = m_thenOperation.node; + } + + GenTree* transformed = TryTransformSelectOperOrLocal(trueInput, falseInput); + if (transformed != nullptr) + return transformed; + + transformed = TryTransformSelectOperOrZero(trueInput, falseInput); + if (transformed != nullptr) + return transformed; + } +#endif // TARGET_RISCV64 + return nullptr; +} + //----------------------------------------------------------------------------- // optIfConversion: If conversion // @@ -800,7 +1020,7 @@ PhaseStatus Compiler::optIfConversion() assert(!fgSsaValid); optReachableBitVecTraits = nullptr; -#if defined(TARGET_ARM64) || defined(TARGET_XARCH) +#if defined(TARGET_ARM64) || defined(TARGET_XARCH) || defined(TARGET_RISCV64) // Reverse iterate through the blocks. BasicBlock* block = fgLastBB; while (block != nullptr) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 21f12c21e0dc59..27550eac30073a 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -50,51 +50,16 @@ void Compiler::impPushOnStack(GenTree* tree, typeInfo ti) // helper function that will tell us if the IL instruction at the addr passed // by param consumes an address at the top of the stack. We use it to save // us lvAddrTaken -bool Compiler::impILConsumesAddr(const BYTE* codeAddr) +bool Compiler::impILConsumesAddr(const BYTE* codeAddr, const BYTE* codeEndp) { - assert(!compIsForInlining()); - - OPCODE opcode; - - opcode = (OPCODE)getU1LittleEndian(codeAddr); - + OPCODE opcode = impGetNonPrefixOpcode(codeAddr, codeEndp); switch (opcode) { - // case CEE_LDFLDA: We're taking this one out as if you have a sequence - // like - // - // ldloca.0 - // ldflda whatever - // - // of a primitivelike struct, you end up after morphing with addr of a local - // that's not marked as addrtaken, which is wrong. Also ldflda is usually used - // for structs that contain other structs, which isnt a case we handle very - // well now for other reasons. - case CEE_LDFLD: { - // We won't collapse small fields. This is probably not the right place to have this - // check, but we're only using the function for this purpose, and is easy to factor - // out if we need to do so. - - CORINFO_RESOLVED_TOKEN resolvedToken; - impResolveToken(codeAddr + sizeof(int8_t), &resolvedToken, CORINFO_TOKENKIND_Field); - - var_types lclTyp = JITtype2varType(info.compCompHnd->getFieldType(resolvedToken.hField)); - - // Preserve 'small' int types - if (!varTypeIsSmall(lclTyp)) - { - lclTyp = genActualType(lclTyp); - } - - if (varTypeIsSmall(lclTyp)) - { - return false; - } - return true; } + default: break; } @@ -4199,7 +4164,7 @@ GenTree* Compiler::impImportStaticFieldAddress(CORINFO_RESOLVED_TOKEN* pResolved else { assert(pFieldInfo->fieldLookup.accessType == IAT_PVALUE); - op1 = gtNewIndOfIconHandleNode(TYP_I_IMPL, fldAddr, GTF_ICON_STATIC_ADDR_PTR, true); + op1 = gtNewIndOfIconHandleNode(TYP_I_IMPL, fldAddr, GTF_ICON_STATIC_ADDR_PTR); } GenTree* offset = gtNewIconNode(pFieldInfo->offset, innerFldSeq); isHoistable = true; @@ -5113,7 +5078,6 @@ void Compiler::impImportLeave(BasicBlock* block) } step2->inheritWeight(block); - step2->CopyFlags(block, BBF_RUN_RARELY); step2->SetFlags(BBF_IMPORTED); #ifdef DEBUG @@ -5396,10 +5360,9 @@ void Compiler::impResetLeaveBlock(BasicBlock* block, unsigned jmpAddr) // b) weight zero // c) prevent from being imported // d) as internal - // e) as rarely run - dupBlock->bbRefs = 0; - dupBlock->bbWeight = BB_ZERO_WEIGHT; - dupBlock->SetFlags(BBF_IMPORTED | BBF_INTERNAL | BBF_RUN_RARELY); + dupBlock->bbRefs = 0; + dupBlock->bbSetRunRarely(); + dupBlock->SetFlags(BBF_IMPORTED | BBF_INTERNAL); // Insert the block right after the block which is getting reset so that BBJ_CALLFINALLY and BBJ_ALWAYS // will be next to each other. @@ -6217,7 +6180,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) // if (!mustUseTargetPatchpoint) { - for (BasicBlock* const succBlock : block->Succs(this)) + for (BasicBlock* const succBlock : block->Succs()) { if ((succBlock->bbNum <= block->bbNum) && (succBlock->bbRefs > 1)) { @@ -6238,7 +6201,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) // We wanted a source patchpoint, but could not have one. // So, add patchpoints to the backedge targets. // - for (BasicBlock* const succBlock : block->Succs(this)) + for (BasicBlock* const succBlock : block->Succs()) { if (succBlock->bbNum <= block->bbNum) { @@ -6390,7 +6353,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) // Block will no longer flow to any of its successors. // - for (BasicBlock* const succ : block->Succs(this)) + for (BasicBlock* const succ : block->Succs()) { // We may have degenerate flow, make sure to fully remove fgRemoveAllRefPreds(succ, block); @@ -7062,9 +7025,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) return; } - op1->ChangeType(TYP_BYREF); - op1->SetOper(GT_LCL_ADDR); - op1->AsLclFld()->SetLclOffs(0); + op1 = gtNewLclAddrNode(op1->AsLclVar()->GetLclNum(), 0, TYP_BYREF); goto _PUSH_ADRVAR; } @@ -7347,7 +7308,6 @@ void Compiler::impImportBlockCode(BasicBlock* block) if (op1->OperIs(GT_LCL_VAR) && op2->OperIs(GT_LCL_VAR, GT_CNS_INT, GT_ADD)) { - block->SetFlags(BBF_HAS_IDX_LEN); optMethodFlags |= OMF_HAS_ARRAYREF; } @@ -7453,7 +7413,6 @@ void Compiler::impImportBlockCode(BasicBlock* block) // Mark the block as containing an index expression if (op3->OperIs(GT_LCL_VAR) && op1->OperIs(GT_LCL_VAR, GT_CNS_INT, GT_ADD)) { - block->SetFlags(BBF_HAS_IDX_LEN); optMethodFlags |= OMF_HAS_ARRAYREF; } @@ -8095,8 +8054,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++; @@ -8123,15 +8082,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. @@ -8454,7 +8409,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) // via an underlying address, just null check the address. if (op1->OperIs(GT_IND, GT_BLK)) { - gtChangeOperToNullCheck(op1, block); + gtChangeOperToNullCheck(op1); } else { @@ -9131,17 +9086,22 @@ void Compiler::impImportBlockCode(BasicBlock* block) // many other places. We unfortunately embed that knowledge here. if (opcode != CEE_CALLI) { - bool isAwait = false; - // TODO: The configVal should be wired to the actual implementation - // that control the flow of sync context. - // We do not have that yet. - int configVal = -1; // -1 not configured, 0/1 configured to false/true + bool isAwait = false; + int configVal = -1; // -1 not configured, 0/1 configured to false/true +#ifdef DEBUG if (compIsAsync() && JitConfig.JitOptimizeAwait()) +#else + if (compIsAsync()) +#endif { if (impMatchTaskAwaitPattern(codeAddr, codeEndp, &configVal)) { isAwait = true; prefixFlags |= PREFIX_IS_TASK_AWAIT; + if (configVal != 0) + { + prefixFlags |= PREFIX_TASK_AWAIT_CONTINUE_ON_CAPTURED_CONTEXT; + } } } @@ -10418,7 +10378,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) GenTree* boxPayloadOffset = gtNewIconNode(TARGET_POINTER_SIZE, TYP_I_IMPL); GenTree* boxPayloadAddress = gtNewOperNode(GT_ADD, TYP_BYREF, cloneOperand, boxPayloadOffset); - GenTree* nullcheck = gtNewNullCheck(op1, block); + GenTree* nullcheck = gtNewNullCheck(op1); // Add an ordering dependency between the null // check and forming the byref; the JIT assumes // in many places that the only legal null @@ -11000,7 +10960,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) if (opts.OptimizationEnabled()) { /* Use GT_ARR_LENGTH operator so rng check opts see this */ - GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, op1, OFFSETOF__CORINFO_Array__length, block); + GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, op1, OFFSETOF__CORINFO_Array__length); op1 = arrLen; } @@ -11478,8 +11438,7 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode) } // If gtSubstExpr is an arbitrary tree then we may need to - // propagate mandatory "IR presence" flags (e.g. BBF_HAS_IDX_LEN) - // to the BB it ends up in. + // propagate mandatory "IR presence" flags to the BB it ends up in. inlRetExpr->gtSubstBB = fgNeedReturnSpillTemp() ? nullptr : compCurBB; } } @@ -11876,7 +11835,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; @@ -12793,19 +12752,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. @@ -12834,8 +12787,7 @@ void Compiler::impFixPredLists() newEdge->setLikelihood(1.0 / predCount); } - jumpEhf->bbeSuccs[predNum] = newEdge; - ++predNum; + succTab[predNum++] = newEdge; if (!added) { @@ -12843,7 +12795,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); @@ -13431,7 +13393,7 @@ void Compiler::impInlineRecordArgInfo(InlineInfo* pInlineInfo, // The method may make observations that lead to marking this candidate as // a failed inline. If this happens the initialization is abandoned immediately // to try and reduce the jit time cost for a failed inline. - +// void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) { assert(!compIsForInlining()); diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index cbdb15e9a63d9d..f69407f58bb049 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -384,8 +384,18 @@ var_types Compiler::impImportCall(OPCODE opcode, // take the call now.... call = gtNewIndCallNode(nullptr, callRetTyp, di); + if (sig->isAsyncCall()) + { + impSetupAndSpillForAsyncCall(call->AsCall(), opcode, prefixFlags); + } + impPopCallArgs(sig, call->AsCall()); + if (call->AsCall()->IsAsync()) + { + impInsertAsyncContinuationForLdvirtftnCall(call->AsCall()); + } + GenTree* thisPtr = impPopStack().val; thisPtr = impTransformThis(thisPtr, pConstrainedResolvedToken, callInfo->thisTransform); assert(thisPtr != nullptr); @@ -618,7 +628,7 @@ var_types Compiler::impImportCall(OPCODE opcode, * to the arg list next after we pop them */ } - //--------------------------- Inline NDirect ------------------------------ + //--------------------------- Inline PInvoke ------------------------------ // If this is a call to a PInvoke method, we may be able to inline the invocation frame. // impCheckForPInvokeCall(call->AsCall(), methHnd, sig, mflags, compCurBB); @@ -652,24 +662,6 @@ var_types Compiler::impImportCall(OPCODE opcode, else if ((opcode == CEE_CALLI) && ((sig->callConv & CORINFO_CALLCONV_MASK) != CORINFO_CALLCONV_DEFAULT) && ((sig->callConv & CORINFO_CALLCONV_MASK) != CORINFO_CALLCONV_VARARG)) { - if (!info.compCompHnd->canGetCookieForPInvokeCalliSig(sig)) - { - // Normally this only happens with inlining. - // However, a generic method (or type) being NGENd into another module - // can run into this issue as well. There's not an easy fall-back for AOT - // so instead we fallback to JIT. - if (compIsForInlining()) - { - compInlineResult->NoteFatal(InlineObservation::CALLSITE_CANT_EMBED_PINVOKE_COOKIE); - } - else - { - IMPL_LIMITATION("Can't get PInvoke cookie (cross module generics)"); - } - - return TYP_UNDEF; - } - GenTree* cookie = eeGetPInvokeCookie(sig); // This cookie is required to be either a simple GT_CNS_INT or @@ -699,51 +691,7 @@ var_types Compiler::impImportCall(OPCODE opcode, if (sig->isAsyncCall()) { - AsyncCallInfo asyncInfo; - - JITDUMP("Call is an async "); - - if ((prefixFlags & PREFIX_IS_TASK_AWAIT) != 0) - { - JITDUMP("task await\n"); - - asyncInfo.ExecutionContextHandling = ExecutionContextHandling::SaveAndRestore; - } - else - { - JITDUMP("non-task await\n"); - // Only expected non-task await to see in IL is one of the AsyncHelpers.AwaitAwaiter variants. - // These are awaits of custom awaitables, and they come with the behavior that the execution context - // is captured and restored on suspension/resumption. - // We could perhaps skip this for AwaitAwaiter (but not for UnsafeAwaitAwaiter) since it is expected - // that the safe INotifyCompletion will take care of flowing ExecutionContext. - asyncInfo.ExecutionContextHandling = ExecutionContextHandling::AsyncSaveAndRestore; - } - - // For tailcalls the context does not need saving/restoring: it will be - // overwritten by the caller anyway. - // - // More specifically, if we can show that - // Thread.CurrentThread._executionContext is not accessed between the - // call and returning then we can omit save/restore of the execution - // context. We do not do that optimization yet. - if (tailCallFlags != 0) - { - asyncInfo.ExecutionContextHandling = ExecutionContextHandling::None; - } - - call->AsCall()->SetIsAsync(new (this, CMK_Async) AsyncCallInfo(asyncInfo)); - - if (asyncInfo.ExecutionContextHandling == ExecutionContextHandling::SaveAndRestore) - { - compMustSaveAsyncContexts = true; - - // In this case we will need to save the context after the arguments are evaluated. - // Spill the arguments to accomplish that. - // (We could do this via splitting in SaveAsyncContexts, but since we need to - // handle inline candidates we won't gain much.) - impSpillSideEffects(true, CHECK_SPILL_ALL DEBUGARG("Async await with execution context save and restore")); - } + impSetupAndSpillForAsyncCall(call->AsCall(), opcode, prefixFlags); } // Now create the argument list. @@ -754,13 +702,7 @@ var_types Compiler::impImportCall(OPCODE opcode, if ((sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_VARARG) { void *varCookie, *pVarCookie; - if (!info.compCompHnd->canGetVarArgsHandle(sig)) - { - compInlineResult->NoteFatal(InlineObservation::CALLSITE_CANT_EMBED_VARARGS_COOKIE); - return TYP_UNDEF; - } - - varCookie = info.compCompHnd->getVarArgsHandle(sig, &pVarCookie); + varCookie = info.compCompHnd->getVarArgsHandle(sig, methHnd, &pVarCookie); assert((!varCookie) != (!pVarCookie)); varArgsCookie = gtNewIconEmbHndNode(varCookie, pVarCookie, GTF_ICON_VARG_HDL, sig); } @@ -929,7 +871,9 @@ var_types Compiler::impImportCall(OPCODE opcode, .WellKnown(WellKnownArg::VarArgsCookie)); } - if (call->AsCall()->IsAsync()) + // Add async continuation arg. For calli these are used for IL + // stubs and the VM inserts the arg itself. + if (call->AsCall()->IsAsync() && (opcode != CEE_CALLI)) { call->AsCall()->gtArgs.PushFront(this, NewCallArg::Primitive(gtNewNull(), TYP_REF) .WellKnown(WellKnownArg::AsyncContinuation)); @@ -943,16 +887,18 @@ var_types Compiler::impImportCall(OPCODE opcode, } else { - if (instParam != nullptr) + // Add async continuation arg. For calli these are used for IL + // stubs and the VM inserts the arg itself. + if (call->AsCall()->IsAsync() && (opcode != CEE_CALLI)) { - call->AsCall()->gtArgs.PushBack(this, - NewCallArg::Primitive(instParam).WellKnown(WellKnownArg::InstParam)); + call->AsCall()->gtArgs.PushBack(this, NewCallArg::Primitive(gtNewNull(), TYP_REF) + .WellKnown(WellKnownArg::AsyncContinuation)); } - if (call->AsCall()->IsAsync()) + if (instParam != nullptr) { - call->AsCall()->gtArgs.PushBack(this, NewCallArg::Primitive(gtNewNull(), TYP_REF) - .WellKnown(WellKnownArg::AsyncContinuation)); + call->AsCall()->gtArgs.PushBack(this, + NewCallArg::Primitive(instParam).WellKnown(WellKnownArg::InstParam)); } if (varArgsCookie != nullptr) @@ -3626,7 +3572,7 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd, break; } } - GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, op1, OFFSETOF__CORINFO_String__stringLen, compCurBB); + GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, op1, OFFSETOF__CORINFO_String__stringLen); op1 = arrLen; // Getting the length of a null string should throw @@ -3654,14 +3600,14 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd, if (op1->OperIsConst() || gtIsTypeof(op1)) { // op1 is a known constant, replace with 'true'. - retNode = gtNewIconNode(1); + retNode = gtNewTrue(); JITDUMP("\nExpanding RuntimeHelpers.IsKnownConstant to true early\n"); // We can also consider FTN_ADDR here } else if (opts.OptimizationDisabled()) { // It doesn't make sense to carry it as GT_INTRINSIC till Morph in Tier0 - retNode = gtNewIconNode(0); + retNode = gtNewFalse(); JITDUMP("\nExpanding RuntimeHelpers.IsKnownConstant to false early\n"); } else @@ -3728,7 +3674,7 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd, array = impCloneExpr(array, &arrayClone, CHECK_SPILL_ALL, nullptr DEBUGARG("MemoryMarshal.GetArrayDataReference array")); - impAppendTree(gtNewNullCheck(array, compCurBB), CHECK_SPILL_ALL, impCurStmtDI); + impAppendTree(gtNewNullCheck(array), CHECK_SPILL_ALL, impCurStmtDI); array = arrayClone; } @@ -5491,6 +5437,25 @@ GenTree* Compiler::impSRCSUnsafeIntrinsic(NamedIntrinsic intrinsic, return gtFoldExpr(tmp); } + case NI_SRCS_UNSAFE_IsAddressGreaterThanOrEqualTo: + { + assert(sig->sigInst.methInstCount == 1); + + // ldarg.0 + // ldarg.1 + // clt.un + // ldc.i4.0 + // ceq + // ret + + GenTree* op2 = impPopStack().val; + GenTree* op1 = impPopStack().val; + + GenTree* tmp = gtNewOperNode(GT_GE, TYP_INT, op1, op2); + tmp->gtFlags |= GTF_UNSIGNED; + return gtFoldExpr(tmp); + } + case NI_SRCS_UNSAFE_IsAddressLessThan: { assert(sig->sigInst.methInstCount == 1); @@ -5508,6 +5473,25 @@ GenTree* Compiler::impSRCSUnsafeIntrinsic(NamedIntrinsic intrinsic, return gtFoldExpr(tmp); } + case NI_SRCS_UNSAFE_IsAddressLessThanOrEqualTo: + { + assert(sig->sigInst.methInstCount == 1); + + // ldarg.0 + // ldarg.1 + // cgt.un + // ldc.i4.0 + // ceq + // ret + + GenTree* op2 = impPopStack().val; + GenTree* op1 = impPopStack().val; + + GenTree* tmp = gtNewOperNode(GT_LE, TYP_INT, op1, op2); + tmp->gtFlags |= GTF_UNSIGNED; + return gtFoldExpr(tmp); + } + case NI_SRCS_UNSAFE_IsNullRef: { assert(sig->sigInst.methInstCount == 1); @@ -6694,7 +6678,7 @@ bool Compiler::impCanPInvokeInlineCallSite(BasicBlock* block) // call passes a combination of legality and profitability checks. // // If GTF_CALL_UNMANAGED is set, increments info.compUnmanagedCallCountWithGCTransition - +// void Compiler::impCheckForPInvokeCall( GenTreeCall* call, CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* sig, unsigned mflags, BasicBlock* block) { @@ -6799,7 +6783,7 @@ void Compiler::impCheckForPInvokeCall( } } - JITLOG((LL_INFO1000000, "\nInline a CALLI PINVOKE call from method %s\n", info.compFullName)); + JITLOG((LL_INFO1000000, "\nInline a PINVOKE call from method %s\n", info.compFullName)); call->gtFlags |= GTF_CALL_UNMANAGED; call->unmgdCallConv = unmanagedCallConv; @@ -6808,7 +6792,6 @@ void Compiler::impCheckForPInvokeCall( info.compUnmanagedCallCountWithGCTransition++; } - // AMD64 convention is same for native and managed if (unmanagedCallConv == CorInfoCallConvExtension::C || unmanagedCallConv == CorInfoCallConvExtension::CMemberFunction) { @@ -6816,6 +6799,110 @@ void Compiler::impCheckForPInvokeCall( } } +//------------------------------------------------------------------------ +// impSetupAndSpillForAsyncCall: +// Register a call as being async and set up context handling information depending on the IL. +// Also spill IL arguments if necessary. +// +// Arguments: +// call - The call +// opcode - The IL opcode for the call +// prefixFlags - Flags containing context handling information from IL +// +void Compiler::impSetupAndSpillForAsyncCall(GenTreeCall* call, OPCODE opcode, unsigned prefixFlags) +{ + AsyncCallInfo asyncInfo; + + if ((prefixFlags & PREFIX_IS_TASK_AWAIT) != 0) + { + JITDUMP("Call is an async task await\n"); + + asyncInfo.ExecutionContextHandling = ExecutionContextHandling::SaveAndRestore; + asyncInfo.SaveAndRestoreSynchronizationContextField = true; + + if ((prefixFlags & PREFIX_TASK_AWAIT_CONTINUE_ON_CAPTURED_CONTEXT) != 0) + { + asyncInfo.ContinuationContextHandling = ContinuationContextHandling::ContinueOnCapturedContext; + JITDUMP(" Continuation continues on captured context\n"); + } + else + { + asyncInfo.ContinuationContextHandling = ContinuationContextHandling::ContinueOnThreadPool; + JITDUMP(" Continuation continues on thread pool\n"); + } + } + else if (opcode == CEE_CALLI) + { + // Used for unboxing/instantiating stubs + JITDUMP("Call is an async calli\n"); + } + else + { + JITDUMP("Call is an async non-task await\n"); + // Only expected non-task await to see in IL is one of the AsyncHelpers.AwaitAwaiter variants. + // These are awaits of custom awaitables, and they come with the behavior that the execution context + // is captured and restored on suspension/resumption. + // We could perhaps skip this for AwaitAwaiter (but not for UnsafeAwaitAwaiter) since it is expected + // that the safe INotifyCompletion will take care of flowing ExecutionContext. + asyncInfo.ExecutionContextHandling = ExecutionContextHandling::AsyncSaveAndRestore; + } + + // For tailcalls the contexts does not need saving/restoring: they will be + // overwritten by the caller anyway. + // + // More specifically, if we can show that + // Thread.CurrentThread._executionContext is not accessed between the + // call and returning then we can omit save/restore of the execution + // context. We do not do that optimization yet. + if ((prefixFlags & PREFIX_TAILCALL) != 0) + { + asyncInfo.ExecutionContextHandling = ExecutionContextHandling::None; + asyncInfo.ContinuationContextHandling = ContinuationContextHandling::None; + asyncInfo.SaveAndRestoreSynchronizationContextField = false; + } + + call->AsCall()->SetIsAsync(new (this, CMK_Async) AsyncCallInfo(asyncInfo)); + + if (asyncInfo.ExecutionContextHandling == ExecutionContextHandling::SaveAndRestore) + { + compMustSaveAsyncContexts = true; + + // In this case we will need to save the context after the arguments are evaluated. + // Spill the arguments to accomplish that. + // (We could do this via splitting in SaveAsyncContexts, but since we need to + // handle inline candidates we won't gain much.) + impSpillSideEffects(true, CHECK_SPILL_ALL DEBUGARG("Async await with execution context save and restore")); + } +} + +//------------------------------------------------------------------------ +// impInsertAsyncContinuationForLdvirtftnCall: +// Insert the async continuation argument for a call the EE asked to be +// performed via ldvirtftn. +// +// Arguments: +// call - The call +// +// Remarks: +// Should be called before the 'this' arg is inserted, but after other IL args +// have been inserted. +// +void Compiler::impInsertAsyncContinuationForLdvirtftnCall(GenTreeCall* call) +{ + assert(call->AsCall()->IsAsync()); + + if (Target::g_tgtArgOrder == Target::ARG_ORDER_R2L) + { + call->AsCall()->gtArgs.PushFront(this, NewCallArg::Primitive(gtNewNull(), TYP_REF) + .WellKnown(WellKnownArg::AsyncContinuation)); + } + else + { + call->AsCall()->gtArgs.PushBack(this, NewCallArg::Primitive(gtNewNull(), TYP_REF) + .WellKnown(WellKnownArg::AsyncContinuation)); + } +} + //------------------------------------------------------------------------ // SpillRetExprHelper: iterate through arguments tree and spill ret_expr to local variables. // @@ -6937,6 +7024,7 @@ void Compiler::pickGDV(GenTreeCall* call, const int maxLikelyMethods = MAX_GDV_TYPE_CHECKS; LikelyClassMethodRecord likelyMethods[maxLikelyMethods]; unsigned numberOfMethods = 0; + bool isInferredGDV = false; // TODO-GDV: R2R support requires additional work to reacquire the // entrypoint, similar to what happens at the end of impDevirtualizeCall. @@ -6951,6 +7039,39 @@ void Compiler::pickGDV(GenTreeCall* call, pgoInfo.PgoData, ilOffset); } + if ((numberOfClasses < 1) && (numberOfMethods < 1) && hasEnumeratorLikelyTypeMap()) + { + // See if we can infer a GDV here for enumerator var uses + // + CallArg* const thisArg = call->gtArgs.FindWellKnownArg(WellKnownArg::ThisPointer); + + if (thisArg != nullptr) + { + GenTree* const thisNode = thisArg->GetEarlyNode(); + if (thisNode->OperIs(GT_LCL_VAR)) + { + GenTreeLclVarCommon* thisLclNode = thisNode->AsLclVarCommon(); + LclVarDsc* const thisVarDsc = lvaGetDesc(thisLclNode); + unsigned const thisLclNum = thisLclNode->GetLclNum(); + + if (thisVarDsc->lvIsEnumerator) + { + VarToLikelyClassMap* const map = getImpEnumeratorLikelyTypeMap(); + InferredGdvEntry e; + if (map->Lookup(thisLclNum, &e)) + { + JITDUMP("Recalling that V%02u has %u%% likely class %s\n", thisLclNum, e.m_likelihood, + eeGetClassName(e.m_classHandle)); + numberOfClasses = 1; + likelyClasses[0].handle = (INT_PTR)e.m_classHandle; + likelyClasses[0].likelihood = e.m_likelihood; + isInferredGDV = true; + } + } + } + } + } + if ((numberOfClasses < 1) && (numberOfMethods < 1)) { if (verboseLogging) @@ -7137,6 +7258,58 @@ void Compiler::pickGDV(GenTreeCall* call, JITDUMP("Accepting type %s with likelihood %u as a candidate\n", eeGetClassName(classGuesses[guessIdx]), likelihoods[guessIdx]) } + + // If the 'this' arg to the call is an enumerator var, record any + // dominant likely class so we can possibly infer a GDV at places where we + // never observed the var's value. (eg an unreached Dispose call if + // control is hijacked out of Tier0+i by OSR). + // + // Note enumerator vars are special as they are generally not redefined + // and we want to ensure all methods called on them get inlined to enable + // escape analysis to kick in, if possible. + // + const unsigned dominantLikelihood = 50; + + if (!isInferredGDV && (likelihoods[guessIdx] >= dominantLikelihood)) + { + CallArg* const thisArg = call->gtArgs.FindWellKnownArg(WellKnownArg::ThisPointer); + + if (thisArg != nullptr) + { + GenTree* const thisNode = thisArg->GetEarlyNode(); + if (thisNode->OperIs(GT_LCL_VAR)) + { + GenTreeLclVarCommon* thisLclNode = thisNode->AsLclVarCommon(); + LclVarDsc* const thisVarDsc = lvaGetDesc(thisLclNode); + unsigned const thisLclNum = thisLclNode->GetLclNum(); + + if (thisVarDsc->lvIsEnumerator) + { + VarToLikelyClassMap* const map = getImpEnumeratorLikelyTypeMap(); + + // If we have multiple type observations, we just use the first. + // + // Note importation order is somewhat reverse-post-orderish; + // a block is only imported if one of its imported preds is imported. + // + // Enumerator vars tend to have a dominating MoveNext call that will + // be the one subsequent uses will see, if they lack their own + // type observations. + // + if (!map->Lookup(thisLclNum)) + { + InferredGdvEntry e; + e.m_classHandle = classGuesses[guessIdx]; + e.m_likelihood = likelihoods[guessIdx]; + + JITDUMP("Remembering that V%02u has %u%% likely class %s\n", thisLclNum, + e.m_likelihood, eeGetClassName(e.m_classHandle)); + map->Set(thisLclNum, e); + } + } + } + } + } } else { @@ -7194,6 +7367,38 @@ bool Compiler::isCompatibleMethodGDV(GenTreeCall* call, CORINFO_METHOD_HANDLE gd CORINFO_ARG_LIST_HANDLE sigParam = sig.args; unsigned numParams = sig.numArgs; unsigned numArgs = 0; + + var_types gdvType = JITtype2varType(sig.retType); + var_types callType = call->gtReturnType; + + const bool sameRetTypes = + (genActualType(callType) == genActualType(gdvType)) || (varTypeIsStruct(callType) && varTypeIsStruct(gdvType)); + if (!sameRetTypes) + { + JITDUMP("Incompatible method GDV: Return types do not match - bail out.\n"); + return false; + } + + if (varTypeIsStruct(gdvType)) + { + assert(varTypeIsStruct(callType)); + + CORINFO_SIG_INFO callSig; + info.compCompHnd->getMethodSig(call->gtCallMethHnd, &callSig); + + structPassingKind callRetKind; + structPassingKind gdvRetKind; + getReturnTypeForStruct(callSig.retTypeClass, call->GetUnmanagedCallConv(), &callRetKind); + getReturnTypeForStruct(sig.retTypeClass, call->GetUnmanagedCallConv(), &gdvRetKind); + + if ((callRetKind != gdvRetKind) || + !ClassLayout::AreCompatible(typGetObjLayout(callSig.retTypeClass), typGetObjLayout(sig.retTypeClass))) + { + JITDUMP("Incompatible method GDV: Return struct types do not match - bail out.\n"); + return false; + } + } + for (CallArg& arg : call->gtArgs.Args()) { switch (arg.GetWellKnownArg()) @@ -7884,6 +8089,14 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call, return; } + if (call->IsAsync() && (call->GetAsyncInfo().ContinuationContextHandling != ContinuationContextHandling::None)) + { + // Cannot currently handle moving to captured context/thread pool when logically returning from inlinee. + // + inlineResult->NoteFatal(InlineObservation::CALLSITE_CONTINUATION_HANDLING); + return; + } + // Ignore indirect calls, unless they are indirect virtual stub calls with profile info. // if (call->gtCallType == CT_INDIRECT) @@ -10703,10 +10916,18 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { result = NI_SRCS_UNSAFE_IsAddressGreaterThan; } + else if (strcmp(methodName, "IsAddressGreaterThanOrEqualTo") == 0) + { + result = NI_SRCS_UNSAFE_IsAddressGreaterThanOrEqualTo; + } else if (strcmp(methodName, "IsAddressLessThan") == 0) { result = NI_SRCS_UNSAFE_IsAddressLessThan; } + else if (strcmp(methodName, "IsAddressLessThanOrEqualTo") == 0) + { + result = NI_SRCS_UNSAFE_IsAddressLessThanOrEqualTo; + } else if (strcmp(methodName, "IsNullRef") == 0) { result = NI_SRCS_UNSAFE_IsNullRef; diff --git a/src/coreclr/jit/importervectorization.cpp b/src/coreclr/jit/importervectorization.cpp index 0f9ac5643e9a92..7fc5226b2eb923 100644 --- a/src/coreclr/jit/importervectorization.cpp +++ b/src/coreclr/jit/importervectorization.cpp @@ -500,13 +500,23 @@ GenTree* Compiler::impUtf16StringComparison(StringComparisonKind kind, CORINFO_S // Create a tree representing string's Length: int strLenOffset = OFFSETOF__CORINFO_String__stringLen; - GenTree* lenNode = gtNewArrLen(TYP_INT, varStrLcl, strLenOffset, compCurBB); + GenTree* lenNode = gtNewArrLen(TYP_INT, varStrLcl, strLenOffset); varStrLcl = gtClone(varStrLcl)->AsLclVar(); GenTree* unrolled = impExpandHalfConstEquals(varStrLcl, lenNode, needsNullcheck, kind, (WCHAR*)str, cnsLength, strLenOffset + sizeof(int), cmpMode); if (unrolled != nullptr) { + // Wrap with the reference equality check for Equals. + // We believe it's less likely to be useful for StartsWith/EndsWith. + if (kind == StringComparisonKind::Equals) + { + GenTreeColon* refEqualityColon = gtNewColonNode(TYP_INT, gtNewTrue(), unrolled); + unrolled = + gtNewQmarkNode(TYP_INT, gtNewOperNode(GT_EQ, TYP_INT, gtCloneExpr(varStrLcl), gtCloneExpr(cnsStr)), + refEqualityColon); + } + impStoreToTemp(varStrTmp, varStr, CHECK_SPILL_NONE); if (unrolled->OperIs(GT_QMARK)) { @@ -647,8 +657,13 @@ GenTree* Compiler::impUtf16SpanComparison(StringComparisonKind kind, CORINFO_SIG return nullptr; } - JITDUMP("Trying to unroll MemoryExtensions.Equals|SequenceEqual|StartsWith(op1, \"%s\")...\n", - convertUtf16ToUtf8ForPrinting((WCHAR*)str)); +#if DEBUG + constexpr int maxLiteralLength = 256; + char dst[maxLiteralLength]; + convertUtf16ToUtf8ForPrinting(str, cnsLength, dst, maxLiteralLength); + JITDUMP("Trying to unroll MemoryExtensions.Equals|SequenceEqual|StartsWith(op1, \"%.50s%s\")...\n", dst, + cnsLength > 50 ? "..." : ""); +#endif } unsigned spanLclNum; @@ -673,6 +688,16 @@ GenTree* Compiler::impUtf16SpanComparison(StringComparisonKind kind, CORINFO_SIG if (unrolled != nullptr) { + // Wrap with the reference equality check for Equals. + // We believe it's less likely to be useful for StartsWith/EndsWith. + if (kind == StringComparisonKind::Equals) + { + GenTreeColon* refEqualityColon = gtNewColonNode(TYP_INT, gtNewTrue(), unrolled); + unrolled = gtNewQmarkNode(TYP_INT, + gtNewOperNode(GT_EQ, TYP_INT, gtCloneExpr(spanReferenceFld), gtCloneExpr(cnsStr)), + refEqualityColon); + } + if (!spanObj->OperIs(GT_LCL_VAR)) { impStoreToTemp(spanLclNum, spanObj, CHECK_SPILL_NONE); diff --git a/src/coreclr/jit/indirectcalltransformer.cpp b/src/coreclr/jit/indirectcalltransformer.cpp index feece42bb461b3..fd4ee8c5777908 100644 --- a/src/coreclr/jit/indirectcalltransformer.cpp +++ b/src/coreclr/jit/indirectcalltransformer.cpp @@ -415,9 +415,10 @@ class IndirectCallTransformer { elseBlock = CreateAndInsertBasicBlock(BBJ_ALWAYS, thenBlock, currBlock); - GenTree* fixedFptrAddress = GetFixedFptrAddress(); - GenTree* actualCallAddress = compiler->gtNewIndir(pointerType, fixedFptrAddress); - GenTree* hiddenArgument = GetHiddenArgument(fixedFptrAddress); + GenTree* fixedFptrAddress = GetFixedFptrAddress(); + GenTree* actualCallAddress = + compiler->gtNewIndir(pointerType, fixedFptrAddress, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); + GenTree* hiddenArgument = GetHiddenArgument(fixedFptrAddress); Statement* fatStmt = CreateFatCallStmt(actualCallAddress, hiddenArgument); compiler->fgInsertStmtAtEnd(elseBlock, fatStmt); @@ -448,7 +449,8 @@ class IndirectCallTransformer GenTree* fixedFptrAddressCopy = compiler->gtCloneExpr(fixedFptrAddress); GenTree* wordSize = new (compiler, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, genTypeSize(TYP_I_IMPL)); GenTree* hiddenArgumentPtr = compiler->gtNewOperNode(GT_ADD, pointerType, fixedFptrAddressCopy, wordSize); - return compiler->gtNewIndir(fixedFptrAddressCopy->TypeGet(), hiddenArgumentPtr); + return compiler->gtNewIndir(fixedFptrAddressCopy->TypeGet(), hiddenArgumentPtr, + GTF_IND_NONFAULTING | GTF_IND_INVARIANT); } //------------------------------------------------------------------------ diff --git a/src/coreclr/jit/inline.cpp b/src/coreclr/jit/inline.cpp index 33474bbbfda689..8f662c78450eaa 100644 --- a/src/coreclr/jit/inline.cpp +++ b/src/coreclr/jit/inline.cpp @@ -786,7 +786,7 @@ void InlineResult::Report() // Was the result NEVER? If so we might want to propagate this to // the runtime. - if (IsNever() && m_Policy->PropagateNeverToRuntime()) + if (IsNever() && m_Policy->PropagateNeverToRuntime() && (m_Callee != nullptr)) { // If we know the callee, and if the observation that got us // to this Never inline state is something *other* than @@ -795,36 +795,16 @@ void InlineResult::Report() // so that future inline attempts for this callee fail faster. // InlineObservation obs = m_Policy->GetObservation(); - - bool report = (m_Callee != nullptr); - bool suppress = (obs == InlineObservation::CALLEE_IS_NOINLINE); - bool dynamicPgo = m_RootCompiler->fgPgoDynamic; - - // If dynamic pgo is active, only propagate noinline back to metadata - // when there is a CALLEE FATAL observation. We want to make sure - // not to block future inlines based on performance or throughput considerations. - // - // Note fgPgoDynamic (and hence dynamicPgo) is true iff TieredPGO is enabled globally. - // In particular this value does not depend on the root method having PGO data. - // - if (dynamicPgo) - { - InlineTarget target = InlGetTarget(obs); - InlineImpact impact = InlGetImpact(obs); - suppress = (target != InlineTarget::CALLEE) || (impact != InlineImpact::FATAL); - } - - if (report && !suppress) + if (obs != InlineObservation::CALLEE_IS_NOINLINE) { JITDUMP("\nINLINER: Marking %s as NOINLINE (observation %s)\n", callee, InlGetObservationString(obs)); COMP_HANDLE comp = m_RootCompiler->info.compCompHnd; comp->setMethodAttribs(m_Callee, CORINFO_FLG_BAD_INLINEE); } - else if (suppress) + else { - JITDUMP("\nINLINER: Not marking %s NOINLINE; %s (observation %s)\n", callee, - dynamicPgo ? "pgo active" : "already known", InlGetObservationString(obs)); + JITDUMP("\nINLINER: Not marking %s NOINLINE because it's already marked as such\n", callee); } } diff --git a/src/coreclr/jit/inline.def b/src/coreclr/jit/inline.def index b8bc674bce09a3..bb6d2226cea21a 100644 --- a/src/coreclr/jit/inline.def +++ b/src/coreclr/jit/inline.def @@ -128,8 +128,6 @@ INLINE_OBSERVATION(ARG_HAS_NULL_THIS, bool, "this pointer argument is INLINE_OBSERVATION(ARG_NO_BASH_TO_INT, bool, "argument can't bash to int", FATAL, CALLSITE) INLINE_OBSERVATION(ARG_NO_BASH_TO_REF, bool, "argument can't bash to ref", FATAL, CALLSITE) INLINE_OBSERVATION(ARG_TYPES_INCOMPATIBLE, bool, "argument types incompatible", FATAL, CALLSITE) -INLINE_OBSERVATION(CANT_EMBED_PINVOKE_COOKIE, bool, "can't embed pinvoke cookie", FATAL, CALLSITE) -INLINE_OBSERVATION(CANT_EMBED_VARARGS_COOKIE, bool, "can't embed varargs cookie", FATAL, CALLSITE) INLINE_OBSERVATION(CANT_CLASS_INIT, bool, "can't class init", FATAL, CALLSITE) INLINE_OBSERVATION(COMPILATION_ERROR, bool, "compilation error", FATAL, CALLSITE) INLINE_OBSERVATION(COMPILATION_FAILURE, bool, "failed to compile", FATAL, CALLSITE) @@ -163,6 +161,7 @@ INLINE_OBSERVATION(RETURN_TYPE_MISMATCH, bool, "return type mismatch", INLINE_OBSERVATION(STFLD_NEEDS_HELPER, bool, "stfld needs helper", FATAL, CALLSITE) INLINE_OBSERVATION(TOO_MANY_LOCALS, bool, "too many locals", FATAL, CALLSITE) INLINE_OBSERVATION(PINVOKE_EH, bool, "PInvoke call site with EH", FATAL, CALLSITE) +INLINE_OBSERVATION(CONTINUATION_HANDLING, bool, "Callsite needs continuation handling", FATAL, CALLSITE) // ------ Call Site Performance ------- diff --git a/src/coreclr/jit/inlinepolicy.cpp b/src/coreclr/jit/inlinepolicy.cpp index 6ddd8c6278fe02..dd1e6cc23f8297 100644 --- a/src/coreclr/jit/inlinepolicy.cpp +++ b/src/coreclr/jit/inlinepolicy.cpp @@ -1036,18 +1036,48 @@ void DefaultPolicy::OnDumpXml(FILE* file, unsigned indent) const bool DefaultPolicy::PropagateNeverToRuntime() const { - // - // Do not propagate the "no return" observation. If we do this then future inlining - // attempts will fail immediately without marking the call node as "no return". - // This can have an adverse impact on caller's code quality as it may have to preserve - // registers across the call. - // TODO-Throughput: We should persist the "no return" information in the runtime - // so we don't need to re-analyze the inlinee all the time. - // + if (m_Observation == InlineObservation::CALLEE_DOES_NOT_RETURN) + { + // Do not propagate the "no return" observation. If we do this then future inlining + // attempts will fail immediately without marking the call node as "no return". + // This can have an adverse impact on caller's code quality as it may have to preserve + // registers across the call. + // TODO-Throughput: We should persist the "no return" information in the runtime + // so we don't need to re-analyze the inlinee all the time. + // + return false; + } + + InlineTarget target = InlGetTarget(GetObservation()); + InlineImpact impact = InlGetImpact(GetObservation()); + + if ((target == InlineTarget::CALLEE) && (impact == InlineImpact::FATAL)) + { + // This callee will never inline. + // + return true; + } + + if (m_InsideThrowBlock) + { + // We inline only trivial methods inside BBJ_THROW call-sites - no need to record that. + // + return false; + } - bool propagate = (m_Observation != InlineObservation::CALLEE_DOES_NOT_RETURN); + if (m_RootCompiler->fgPgoDynamic) + { + // If dynamic pgo is active, only propagate noinline back to metadata + // when there is a CALLEE FATAL observation. We want to make sure + // not to block future inlines based on performance or throughput considerations. + // + // Note fgPgoDynamic (and hence dynamicPgo) is true iff TieredPGO is enabled globally. + // In particular this value does not depend on the root method having PGO data. + // + return false; + } - return propagate; + return true; } #if defined(DEBUG) @@ -1377,8 +1407,22 @@ void ExtendedDefaultPolicy::NoteInt(InlineObservation obs, int value) } else if (m_RootCompiler->fgHaveSufficientProfileWeights()) { - JITDUMP("Root has sufficient profile\n"); - maxCodeSize = static_cast(JitConfig.JitExtDefaultPolicyMaxILRoot()); + // For now we want to inline somewhat less aggressively in Tier1+Instr and OSR. We can reconsider + // when we have inlinee instrumentation. Otherwise we may lose profile data for key inlinees. + // + const bool isTier1Instr = m_RootCompiler->opts.IsInstrumentedAndOptimized(); + const bool isOSR = m_RootCompiler->opts.IsOSR(); + + if (isTier1Instr || isOSR) + { + JITDUMP("Root has sufficient profile. Leaving max IL size at %u for Tier1+Instr or OSR\n", + maxCodeSize); + } + else + { + maxCodeSize = static_cast(JitConfig.JitExtDefaultPolicyMaxILRoot()); + JITDUMP("Root has sufficient profile. Boosting max IL size to %u\n", maxCodeSize); + } } else { diff --git a/src/coreclr/jit/instr.cpp b/src/coreclr/jit/instr.cpp index c336b1c521d03a..844a621b5cb563 100644 --- a/src/coreclr/jit/instr.cpp +++ b/src/coreclr/jit/instr.cpp @@ -612,13 +612,12 @@ bool CodeGenInterface::instHasPseudoName(instruction ins) * Generate a set instruction. */ -void CodeGen::inst_SET(emitJumpKind condition, regNumber reg) +void CodeGen::inst_SET(emitJumpKind condition, regNumber reg, insOpts instOptions) { #ifdef TARGET_XARCH instruction ins; /* Convert the condition to an instruction opcode */ - switch (condition) { case EJ_js: @@ -672,10 +671,35 @@ void CodeGen::inst_SET(emitJumpKind condition, regNumber reg) return; } +#ifdef TARGET_AMD64 + // If using ZU feature, we need to promote the SETcc to the new instruction. + if ((instOptions & INS_OPTS_EVEX_zu_MASK) != 0) + { + const int offset = (INS_seto - INS_seto_apx); + assert(INS_seto == (INS_seto_apx + offset)); + assert(INS_setno == (INS_setno_apx + offset)); + assert(INS_setb == (INS_setb_apx + offset)); + assert(INS_setae == (INS_setae_apx + offset)); + assert(INS_sete == (INS_sete_apx + offset)); + assert(INS_setne == (INS_setne_apx + offset)); + assert(INS_setbe == (INS_setbe_apx + offset)); + assert(INS_seta == (INS_seta_apx + offset)); + assert(INS_sets == (INS_sets_apx + offset)); + assert(INS_setns == (INS_setns_apx + offset)); + assert(INS_setp == (INS_setp_apx + offset)); + assert(INS_setnp == (INS_setnp_apx + offset)); + assert(INS_setl == (INS_setl_apx + offset)); + assert(INS_setge == (INS_setge_apx + offset)); + assert(INS_setle == (INS_setle_apx + offset)); + assert(INS_setg == (INS_setg_apx + offset)); + ins = (instruction)(ins - offset); + } +#endif + assert(genRegMask(reg) & RBM_BYTE_REGS); // These instructions only write the low byte of 'reg' - GetEmitter()->emitIns_R(ins, EA_1BYTE, reg); + GetEmitter()->emitIns_R(ins, EA_1BYTE, reg, instOptions); #elif defined(TARGET_ARM64) GetEmitter()->emitIns_R_COND(INS_cset, EA_8BYTE, reg, JumpKindToInsCond(condition)); @@ -1386,6 +1410,32 @@ void CodeGen::inst_RV_TT_IV( { instOptions = AddEmbBroadcastMode(instOptions); } + else if ((instOptions == INS_OPTS_NONE) && !GetEmitter()->IsVexEncodableInstruction(ins)) + { + // We may have opportunistically selected an EVEX only instruction + // that isn't actually required, so fallback to the VEX compatible + // encoding to potentially save on the number of bytes emitted. + + switch (ins) + { + case INS_vextractf64x2: + { + ins = INS_vextractf32x4; + break; + } + + case INS_vextracti64x2: + { + ins = INS_vextracti32x4; + break; + } + + default: + { + break; + } + } + } #endif // TARGET_XARCH && FEATURE_HW_INTRINSICS OperandDesc rmOpDesc = genOperandDesc(ins, rmOp); @@ -1465,7 +1515,7 @@ insOpts CodeGen::AddEmbBroadcastMode(insOpts instOptions) { assert((instOptions & INS_OPTS_EVEX_b_MASK) == 0); unsigned result = static_cast(instOptions); - return static_cast(result | INS_OPTS_EVEX_eb_er_rd); + return static_cast(result | INS_OPTS_EVEX_eb); } #endif // TARGET_XARCH && FEATURE_HW_INTRINSICS @@ -1500,29 +1550,42 @@ void CodeGen::inst_RV_RV_TT(instruction ins, if (CodeGenInterface::IsEmbeddedBroadcastEnabled(ins, op2)) { instOptions = AddEmbBroadcastMode(instOptions); + } + else if ((instOptions == INS_OPTS_NONE) && !GetEmitter()->IsVexEncodableInstruction(ins)) + { + // We may have opportunistically selected an EVEX only instruction + // that isn't actually required, so fallback to the VEX compatible + // encoding to potentially save on the number of bytes emitted. - if (emitter::IsBitwiseInstruction(ins) && varTypeIsLong(op2->AsHWIntrinsic()->GetSimdBaseType())) + switch (ins) { - switch (ins) + case INS_vpandq: { - case INS_pandd: - ins = INS_vpandq; - break; + ins = INS_pandd; + break; + } - case INS_pandnd: - ins = INS_vpandnq; - break; + case INS_vpandnq: + { + ins = INS_pandnd; + break; + } - case INS_pord: - ins = INS_vporq; - break; + case INS_vporq: + { + ins = INS_pord; + break; + } - case INS_pxord: - ins = INS_vpxorq; - break; + case INS_vpxorq: + { + ins = INS_pxord; + break; + } - default: - unreached(); + default: + { + break; } } } @@ -1613,6 +1676,32 @@ void CodeGen::inst_RV_RV_TT_IV(instruction ins, { instOptions = AddEmbBroadcastMode(instOptions); } + else if ((instOptions == INS_OPTS_NONE) && !GetEmitter()->IsVexEncodableInstruction(ins)) + { + // We may have opportunistically selected an EVEX only instruction + // that isn't actually required, so fallback to the VEX compatible + // encoding to potentially save on the number of bytes emitted. + + switch (ins) + { + case INS_vinsertf64x2: + { + ins = INS_vinsertf32x4; + break; + } + + case INS_vinserti64x2: + { + ins = INS_vinserti32x4; + break; + } + + default: + { + break; + } + } + } #endif // TARGET_XARCH && FEATURE_HW_INTRINSICS OperandDesc op2Desc = genOperandDesc(ins, op2); diff --git a/src/coreclr/jit/instr.h b/src/coreclr/jit/instr.h index d3a5b5385a3e9d..15de2fd08f77bd 100644 --- a/src/coreclr/jit/instr.h +++ b/src/coreclr/jit/instr.h @@ -248,13 +248,17 @@ enum insOpts: unsigned INS_OPTS_NONE = 0, // Two-bits: 0b0000_0011 - INS_OPTS_EVEX_b_MASK = 0x03, // mask for EVEX.b related features. + INS_OPTS_EVEX_b_MASK = 0x03, // mask for EVEX.b related features. - INS_OPTS_EVEX_eb_er_rd = 1, // Embedded Broadcast or Round down + INS_OPTS_EVEX_eb = 1, // Embedded broadcast - INS_OPTS_EVEX_er_ru = 2, // Round up + INS_OPTS_EVEX_cd = 2, // Compressed displacement - INS_OPTS_EVEX_er_rz = 3, // Round towards zero + INS_OPTS_EVEX_er_rd = 1, // Embedded round down + + INS_OPTS_EVEX_er_ru = 2, // Embedded round up + + INS_OPTS_EVEX_er_rz = 3, // Embedded round towards zero // Three-bits: 0b0001_1100 INS_OPTS_EVEX_aaa_MASK = 0x1C, // mask for EVEX.aaa related features @@ -302,6 +306,10 @@ enum insOpts: unsigned // One-bit: 0b10_0000_0000_0000 INS_OPTS_APX_ppx_MASK = 0x2000, // mask for APX-EVEX.ppx feature. + INS_OPTS_EVEX_zu = 1 << 14, // Zero Upper for APX-EVEX + // One-bit: 0b100_0000_0000_0000 + INS_OPTS_EVEX_zu_MASK = 0x4000, // mask for APX-EVEX.zu feature. + }; #elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) diff --git a/src/coreclr/jit/instrsriscv64.h b/src/coreclr/jit/instrsriscv64.h index 62169e5831beff..293b6df097b6e7 100644 --- a/src/coreclr/jit/instrsriscv64.h +++ b/src/coreclr/jit/instrsriscv64.h @@ -37,6 +37,7 @@ INST(nop, "nop", 0, 0x00000013) //// R_R INST(mov, "mv", 0, 0x00000013) INST(sext_w, "sext.w", 0, 0x0000001b) +INST(not, "not", 0, 0xFFF04013) ////R_I INST(lui, "lui", 0, 0x00000037) diff --git a/src/coreclr/jit/instrsxarch.h b/src/coreclr/jit/instrsxarch.h index d395369ffc1b07..9e833eb52d6356 100644 --- a/src/coreclr/jit/instrsxarch.h +++ b/src/coreclr/jit/instrsxarch.h @@ -226,10 +226,10 @@ INST3(andnpd, "vandnpd", IUM_WR, BAD_CODE, BAD_CODE, INST3(andnps, "vandnps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x55), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // And-Not packed singles INST3(andpd, "vandpd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x54), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // AND packed doubles INST3(andps, "vandps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x54), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // AND packed singles -INST3(cmppd, "vcmppd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xC2), 4C, 2X, INS_TT_FULL, REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare packed doubles -INST3(cmpps, "vcmpps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0xC2), 4C, 2X, INS_TT_FULL, REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare packed singles -INST3(cmpsd, "vcmpsd", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0xC2), 4C, 2X, INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare scalar doubles -INST3(cmpss, "vcmpss", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xC2), 4C, 2X, INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare scalar singles +INST3(cmppd, "vcmppd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xC2), 4C, 2X, INS_TT_FULL, REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // compare packed doubles +INST3(cmpps, "vcmpps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0xC2), 4C, 2X, INS_TT_FULL, REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // compare packed singles +INST3(cmpsd, "vcmpsd", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0xC2), 4C, 2X, INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // compare scalar doubles +INST3(cmpss, "vcmpss", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xC2), 4C, 2X, INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // compare scalar singles INST3(comisd, "vcomisd", IUM_RD, BAD_CODE, BAD_CODE, PCKDBL(0x2F), 3C, 1C, INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Writes_PF | Writes_CF) // ordered compare doubles INST3(comiss, "vcomiss", IUM_RD, BAD_CODE, BAD_CODE, PCKFLT(0x2F), 3C, 1C, INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Writes_PF | Writes_CF) // ordered compare singles INST3(cvtdq2pd, "vcvtdq2pd", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xE6), ILLEGAL, ILLEGAL, INS_TT_HALF, Input_32Bit | KMask_Base2 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX) // cvt packed DWORDs to doubles @@ -273,8 +273,8 @@ INST3(movapd, "vmovapd", IUM_WR, PCKDBL(0x29), BAD_CODE, INST3(movaps, "vmovaps", IUM_WR, PCKFLT(0x29), BAD_CODE, PCKFLT(0x28), ILLEGAL, ILLEGAL, INS_TT_FULL_MEM, REX_W0_EVEX | Encoding_VEX | Encoding_EVEX) INST3(movd32, "vmovd", IUM_WR, PCKDBL(0x7E), BAD_CODE, PCKDBL(0x6E), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | Encoding_EVEX | Encoding_REX2) // Move DWORD between xmm regs <-> memory/r32 regs INST3(movd64, "vmovq", IUM_WR, PCKDBL(0x7E), BAD_CODE, PCKDBL(0x6E), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | Encoding_EVEX | Encoding_REX2) // Move QWORD between xmm regs <-> memory/r64 regs -INST3(movdqa32, "vmovdqa", IUM_WR, PCKDBL(0x7F), BAD_CODE, PCKDBL(0x6F), ILLEGAL, ILLEGAL, INS_TT_FULL_MEM, REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | Encoding_REX2) -INST3(movdqu32, "vmovdqu", IUM_WR, SSEFLT(0x7F), BAD_CODE, SSEFLT(0x6F), ILLEGAL, ILLEGAL, INS_TT_FULL_MEM, REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | Encoding_REX2) +INST3(movdqa32, "vmovdqa", IUM_WR, PCKDBL(0x7F), BAD_CODE, PCKDBL(0x6F), ILLEGAL, ILLEGAL, INS_TT_FULL_MEM, REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | Encoding_REX2 | INS_FLAGS_HasPseudoName) +INST3(movdqu32, "vmovdqu", IUM_WR, SSEFLT(0x7F), BAD_CODE, SSEFLT(0x6F), ILLEGAL, ILLEGAL, INS_TT_FULL_MEM, REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | Encoding_REX2 | INS_FLAGS_HasPseudoName) INST3(movhlps, "vmovhlps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x12), 1C, 1C, INS_TT_NONE, REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) INST3(movhpd, "vmovhpd", IUM_WR, PCKDBL(0x17), BAD_CODE, PCKDBL(0x16), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) INST3(movhps, "vmovhps", IUM_WR, PCKFLT(0x17), BAD_CODE, PCKFLT(0x16), ILLEGAL, ILLEGAL, INS_TT_TUPLE2, Input_32Bit | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) @@ -310,8 +310,8 @@ INST3(paddsw, "vpaddsw", IUM_WR, BAD_CODE, BAD_CODE, INST3(paddusb, "vpaddusb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xDC), ILLEGAL, ILLEGAL, INS_TT_FULL_MEM, KMask_Base16 | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Add packed unsigned byte integers and saturate the results INST3(paddusw, "vpaddusw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xDD), ILLEGAL, ILLEGAL, INS_TT_FULL_MEM, KMask_Base8 | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Add packed unsigned word integers and saturate the results INST3(paddw, "vpaddw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xFD), ILLEGAL, ILLEGAL, INS_TT_FULL_MEM, KMask_Base8 | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Add packed word (16-bit) integers -INST3(pandd, "vpand", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xDB), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise AND of two xmm regs -INST3(pandnd, "vpandn", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xDF), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise AND NOT of two xmm regs +INST3(pandd, "vpand", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xDB), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // Packed bit-wise AND of two xmm regs +INST3(pandnd, "vpandn", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xDF), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // Packed bit-wise AND NOT of two xmm regs INST3(pavgb, "vpavgb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xE0), 1C, 2X, INS_TT_FULL_MEM, KMask_Base16 | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Average of packed byte integers INST3(pavgw, "vpavgw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xE3), 1C, 2X, INS_TT_FULL_MEM, KMask_Base8 | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Average of packed word integers INST3(pcmpeqb, "vpcmpeqb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x74), 1C, 2X, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 8-bit integers for equality @@ -332,7 +332,7 @@ INST3(pmulhuw, "vpmulhuw", IUM_WR, BAD_CODE, BAD_CODE, INST3(pmulhw, "vpmulhw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xE5), 5C, 2X, INS_TT_FULL_MEM, KMask_Base8 | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Multiply high the packed 16-bit signed integers INST3(pmullw, "vpmullw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xD5), 5C, 2X, INS_TT_FULL_MEM, KMask_Base8 | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed multiply 16 bit unsigned integers and store lower 16 bits of each result INST3(pmuludq, "vpmuludq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xF4), 5C, 2X, INS_TT_FULL, Input_32Bit | KMask_Base2 | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // packed multiply 32-bit unsigned integers and store 64-bit result -INST3(pord, "vpor", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xEB), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise OR of two xmm regs +INST3(pord, "vpor", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xEB), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // Packed bit-wise OR of two xmm regs INST3(prefetchnta, "prefetchnta", IUM_RD, 0x000F0018, BAD_CODE, BAD_CODE, ZERO, 2X, INS_TT_TUPLE1_FIXED, Input_8Bit | REX_WIG | Encoding_REX2) INST3(prefetcht0, "prefetcht0", IUM_RD, 0x000F0818, BAD_CODE, BAD_CODE, ZERO, 2X, INS_TT_TUPLE1_FIXED, Input_8Bit | REX_WIG | Encoding_REX2) INST3(prefetcht1, "prefetcht1", IUM_RD, 0x000F1018, BAD_CODE, BAD_CODE, ZERO, 2X, INS_TT_TUPLE1_FIXED, Input_8Bit | REX_WIG | Encoding_REX2) @@ -367,7 +367,7 @@ INST3(punpcklbw, "vpunpcklbw", IUM_WR, BAD_CODE, BAD_CODE, INST3(punpckldq, "vpunpckldq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x62), 1C, 1C, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) INST3(punpcklqdq, "vpunpcklqdq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x6C), 1C, 1C, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed logical (unsigned) widen uint to ulong (lo) INST3(punpcklwd, "vpunpcklwd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x61), 1C, 1C, INS_TT_FULL_MEM, KMask_Base8 | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed logical (unsigned) widen ushort to uint (lo) -INST3(pxord, "vpxor", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xEF), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise XOR of two xmm regs +INST3(pxord, "vpxor", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xEF), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // Packed bit-wise XOR of two xmm regs INST3(rcpps, "vrcpps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x53), 4C, 1C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX) // Reciprocal of packed singles INST3(rcpss, "vrcpss", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0x53), 4C, 1C, INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_WIG | Encoding_VEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Reciprocal of scalar single INST3(rsqrtps, "vrsqrtps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x52), 4C, 1C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX) // Reciprocal Sqrt of packed singles @@ -465,19 +465,19 @@ INST3(psignb, "vpsignb", IUM_WR, BAD_CODE, BAD_CODE, INST3(psignd, "vpsignd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x0A), 1C, 2X, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed SIGN INST3(psignw, "vpsignw", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x09), 1C, 2X, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed SIGN INST3(ptest, "vptest", IUM_RD, BAD_CODE, BAD_CODE, SSE38(0x17), ILLEGAL, ILLEGAL, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF) // Packed logical compare -INST3(roundpd, "vroundpd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x09), 8C, 1C, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX) // Round packed double precision floating-point values -INST3(roundps, "vroundps", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x08), 8C, 1C, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX) // Round packed single precision floating-point values -INST3(roundsd, "vroundsd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x0B), 8C, 1C, INS_TT_TUPLE1_SCALAR, Input_64Bit | KMask_Base2 | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Round scalar double precision floating-point values -INST3(roundss, "vroundss", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x0A), 8C, 1C, INS_TT_TUPLE1_SCALAR, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction) // Round scalar single precision floating-point values +INST3(roundpd, "vroundpd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x09), 8C, 1C, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_FLAGS_HasPseudoName) // Round packed double precision floating-point values +INST3(roundps, "vroundps", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x08), 8C, 1C, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_FLAGS_HasPseudoName) // Round packed single precision floating-point values +INST3(roundsd, "vroundsd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x0B), 8C, 1C, INS_TT_TUPLE1_SCALAR, Input_64Bit | KMask_Base2 | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction | INS_FLAGS_HasPseudoName) // Round scalar double precision floating-point values +INST3(roundss, "vroundss", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x0A), 8C, 1C, INS_TT_TUPLE1_SCALAR, Input_32Bit | KMask_Base4 | REX_W0_EVEX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstSrcSrcAVXInstruction | INS_FLAGS_HasPseudoName) // Round scalar single precision floating-point values // Instructions for AESNI, PCLMULQDQ -INST3(aesdec, "vaesdec", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xDE), 4C, 1C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Perform one round of an AES decryption flow -INST3(aesdeclast, "vaesdeclast", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xDF), 4C, 1C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Perform last round of an AES decryption flow -INST3(aesenc, "vaesenc", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xDC), 4C, 1C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Perform one round of an AES encryption flow -INST3(aesenclast, "vaesenclast", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xDD), 4C, 1C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Perform last round of an AES encryption flow +INST3(aesdec, "vaesdec", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xDE), 4C, 1C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Perform one round of an AES decryption flow +INST3(aesdeclast, "vaesdeclast", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xDF), 4C, 1C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Perform last round of an AES decryption flow +INST3(aesenc, "vaesenc", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xDC), 4C, 1C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Perform one round of an AES encryption flow +INST3(aesenclast, "vaesenclast", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xDD), 4C, 1C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Perform last round of an AES encryption flow INST3(aesimc, "vaesimc", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xDB), 8C, 2C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX) // Perform the AES InvMixColumn Transformation INST3(aeskeygenassist, "vaeskeygenassist", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0xDF), 7C, 13C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX) // AES Round Key Generation Assist -INST3(pclmulqdq, "vpclmulqdq", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x44), 7C, 1C, INS_TT_FULL_MEM, KMask_Base1 | REX_WIG | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Perform a carry-less multiplication of two quadwords +INST3(pclmulqdq, "vpclmulqdq", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x44), 7C, 1C, INS_TT_FULL_MEM, KMask_Base1 | REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // Perform a carry-less multiplication of two quadwords // Instructions for SHA INST3(sha1msg1, "sha1msg1", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xC9), ILLEGAL, ILLEGAL, INS_TT_FULL, REX_WIG) // Perform an Intermediate Calculation for the Next Four SHA1 Message Dwords @@ -498,11 +498,11 @@ INST3(gf2p8mulb, "vgf2p8mulb", IUM_WR, BAD_CODE, BAD_CODE, // Instructions for AVX INST3(vblendvpd, "vblendvpd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x4B), 2C, 1C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Variable Blend Packed Doubles INST3(vblendvps, "vblendvps", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x4A), 2C, 1C, INS_TT_FULL_MEM, REX_WIG | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Variable Blend Packed Singles -INST3(vbroadcastf32x4, "vbroadcastf128", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x1A), ILLEGAL, ILLEGAL, INS_TT_TUPLE4, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX) // Broadcast packed float values read from memory to entire ymm register +INST3(vbroadcastf32x4, "vbroadcastf128", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x1A), ILLEGAL, ILLEGAL, INS_TT_TUPLE4, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_FLAGS_HasPseudoName) // Broadcast packed float values read from memory to entire ymm register INST3(vbroadcastsd, "vbroadcastsd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x19), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_64Bit | KMask_Base2 | REX_W1_EVEX | Encoding_VEX | Encoding_EVEX) // Broadcast float value read from memory to entire ymm register INST3(vbroadcastss, "vbroadcastss", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x18), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX) // Broadcast float value read from memory to entire ymm register -INST3(vextractf32x4, "vextractf128", IUM_WR, SSE3A(0x19), BAD_CODE, BAD_CODE, 3C, 1C, INS_TT_TUPLE4, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX) // Extract 128-bit packed floating point values -INST3(vinsertf32x4, "vinsertf128", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x18), 3C, 1C, INS_TT_TUPLE4, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Insert 128-bit packed floating point values +INST3(vextractf32x4, "vextractf128", IUM_WR, SSE3A(0x19), BAD_CODE, BAD_CODE, 3C, 1C, INS_TT_TUPLE4, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_FLAGS_HasPseudoName) // Extract 128-bit packed floating point values +INST3(vinsertf32x4, "vinsertf128", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x18), 3C, 1C, INS_TT_TUPLE4, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // Insert 128-bit packed floating point values INST3(vmaskmovpd, "vmaskmovpd", IUM_WR, SSE38(0x2F), BAD_CODE, SSE38(0x2D), ILLEGAL, ILLEGAL, INS_TT_FULL_MEM, REX_W0 | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Conditional SIMD Packed Double-Precision Floating-Point Loads and Stores INST3(vmaskmovps, "vmaskmovps", IUM_WR, SSE38(0x2E), BAD_CODE, SSE38(0x2C), ILLEGAL, ILLEGAL, INS_TT_FULL_MEM, REX_W0 | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Conditional SIMD Packed Single-Precision Floating-Point Loads and Stores INST3(vpblendvb, "vpblendvb", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x4C), 2C, 1C, INS_TT_FULL_MEM, REX_W0 | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Variable Blend Packed Bytes @@ -516,15 +516,15 @@ INST3(vtestps, "vtestps", IUM_RD, BAD_CODE, BAD_CODE, INST3(vzeroupper, "vzeroupper", IUM_WR, 0xC577F8, BAD_CODE, BAD_CODE, ZERO, 1C, INS_TT_NONE, REX_WIG | Encoding_VEX) // Zero upper 128-bits of all YMM regs (includes 2-byte fixed VEX prefix) // Instructions for AVX2, BMI1, BMI2, F16C, LZCNT, MOVBE -INST3(vbroadcasti32x4, "vbroadcasti128", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x5A), ILLEGAL, ILLEGAL, INS_TT_TUPLE4, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX) // Broadcast packed integer values read from memory to entire ymm register +INST3(vbroadcasti32x4, "vbroadcasti128", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x5A), ILLEGAL, ILLEGAL, INS_TT_TUPLE4, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_FLAGS_HasPseudoName) // Broadcast packed integer values read from memory to entire ymm register INST3(vcvtph2ps, "vcvtph2ps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x13), ILLEGAL, ILLEGAL, INS_TT_HALF_MEM, Input_16Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX) // Convert Packed FP16 Values to Single Precision Floating-Point Values INST3(vcvtps2ph, "vcvtps2ph", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1D), ILLEGAL, ILLEGAL, INS_TT_HALF_MEM, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX) // Convert Single Precision FP Value to 16-bit FP Value -INST3(vextracti32x4, "vextracti128", IUM_WR, SSE3A(0x39), BAD_CODE, BAD_CODE, 3C, 1C, INS_TT_TUPLE4, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX) // Extract 128-bit packed integer values +INST3(vextracti32x4, "vextracti128", IUM_WR, SSE3A(0x39), BAD_CODE, BAD_CODE, 3C, 1C, INS_TT_TUPLE4, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_FLAGS_HasPseudoName) // Extract 128-bit packed integer values INST3(vgatherdpd, "vgatherdpd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x92), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Gather Packed DP FP Values Using Signed Dword Indices INST3(vgatherdps, "vgatherdps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x92), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Gather Packed SP FP values Using Signed Dword Indices INST3(vgatherqpd, "vgatherqpd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x93), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_64Bit | REX_W1 | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Gather Packed DP FP Values Using Signed Qword Indices INST3(vgatherqps, "vgatherqps", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x93), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_32Bit | REX_W0 | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Gather Packed SP FP values Using Signed Qword Indices -INST3(vinserti32x4, "vinserti128", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x38), 3C, 1C, INS_TT_TUPLE4, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Insert 128-bit packed integer values +INST3(vinserti32x4, "vinserti128", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x38), 3C, 1C, INS_TT_TUPLE4, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // Insert 128-bit packed integer values INST3(vpblendd, "vpblendd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x02), ILLEGAL, ILLEGAL, INS_TT_FULL_MEM, REX_W0 | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Blend Packed DWORDs INST3(vpbroadcastb, "vpbroadcastb", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x78), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_8Bit | KMask_Base16 | REX_W0 | Encoding_VEX | Encoding_EVEX) // Broadcast int8 value from reg/memory to entire ymm register INST3(vpbroadcastd, "vpbroadcastd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x58), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX) // Broadcast int32 value from reg/memory to entire ymm register @@ -613,27 +613,27 @@ INST3(vfnmsub231ss, "vfnmsub231ss", IUM_RW, BAD_CODE, BAD_CODE, #define FIRST_BMI_INSTRUCTION INS_andn // Instructions for BMI1, BMI2 -INST3(andn, "andn", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF2), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Resets_CF | INS_Flags_Has_NF) // Logical AND NOT -INST3(bextr, "bextr", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF7), 2C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | Resets_OF | Undefined_SF | Writes_ZF | Undefined_AF | Undefined_PF | Resets_CF | INS_Flags_Has_NF) // Bit Field Extract -INST3(blsi, "blsi", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_Flags_Has_NF) // Extract Lowest Set Isolated Bit -INST3(blsmsk, "blsmsk", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | Resets_OF | Writes_SF | Resets_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_Flags_Has_NF) // Get Mask Up to Lowest Set Bit -INST3(blsr, "blsr", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_Flags_Has_NF) // Reset Lowest Set Bit -INST3(bzhi, "bzhi", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF5), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Writes_CF) // Zero High Bits Starting with Specified Bit Position -INST3(mulx, "mulx", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF6), 4C, 1C, INS_TT_NONE, REX_WX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Unsigned Multiply Without Affecting Flags -INST3(pdep, "pdep", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF5), 3C, 1C, INS_TT_NONE, REX_WX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Parallel Bits Deposit -INST3(pext, "pext", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF5), 3C, 1C, INS_TT_NONE, REX_WX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Parallel Bits Extract -INST3(rorx, "rorx", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0xF0), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | Encoding_EVEX) -INST3(sarx, "sarx", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0xF7), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Shift Arithmetic Right Without Affecting Flags -INST3(shlx, "shlx", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF7), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Shift Logical Left Without Affecting Flags -INST3(shrx, "shrx", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF2, 0xF7), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Shift Logical Right Without Affecting Flags +INST3(andn, "andn", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF2), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction | Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Resets_CF | INS_Flags_Has_NF) // Logical AND NOT +INST3(bextr, "bextr", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF7), 2C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction | Resets_OF | Undefined_SF | Writes_ZF | Undefined_AF | Undefined_PF | Resets_CF | INS_Flags_Has_NF) // Bit Field Extract +INST3(blsi, "blsi", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction | Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_Flags_Has_NF) // Extract Lowest Set Isolated Bit +INST3(blsmsk, "blsmsk", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction | Resets_OF | Writes_SF | Resets_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_Flags_Has_NF) // Get Mask Up to Lowest Set Bit +INST3(blsr, "blsr", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction | Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_Flags_Has_NF) // Reset Lowest Set Bit +INST3(bzhi, "bzhi", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF5), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction | Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Writes_CF) // Zero High Bits Starting with Specified Bit Position +INST3(mulx, "mulx", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF6), 4C, 1C, INS_TT_NONE, REX_WX | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Unsigned Multiply Without Affecting Flags +INST3(pdep, "pdep", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF5), 3C, 1C, INS_TT_NONE, REX_WX | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Parallel Bits Deposit +INST3(pext, "pext", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF5), 3C, 1C, INS_TT_NONE, REX_WX | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Parallel Bits Extract +INST3(rorx, "rorx", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0xF0), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX) +INST3(sarx, "sarx", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF3, 0xF7), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Shift Arithmetic Right Without Affecting Flags +INST3(shlx, "shlx", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF7), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Shift Logical Left Without Affecting Flags +INST3(shrx, "shrx", IUM_WR, BAD_CODE, BAD_CODE, PSSE38(0xF2, 0xF7), 1C, 2X, INS_TT_NONE, REX_WX | Encoding_VEX | INS_Flags_IsDstDstSrcAVXInstruction) // Shift Logical Right Without Affecting Flags #define LAST_BMI_INSTRUCTION INS_shrx #define FIRST_AVXVNNI_INSTRUCTION INS_vpdpbusd // Instructions for AVXVNNI -INST3(vpdpbusd, "vpdpbusd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x50), 5C, 2X, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Multiply and Add Unsigned and Signed Bytes -INST3(vpdpbusds, "vpdpbusds", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x51), 5C, 2X, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Multiply and Add Unsigned and Signed Bytes with Saturation -INST3(vpdpwssd, "vpdpwssd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x52), 5C, 2X, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Multiply and Add Signed Word Integers -INST3(vpdpwssds, "vpdpwssds", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x53), 5C, 2X, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Multiply and Add Signed Word Integers with Saturation +INST3(vpdpbusd, "vpdpbusd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x50), 5C, 2X, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | INS_Flags_IsDstDstSrcAVXInstruction) // Multiply and Add Unsigned and Signed Bytes +INST3(vpdpbusds, "vpdpbusds", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x51), 5C, 2X, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | INS_Flags_IsDstDstSrcAVXInstruction) // Multiply and Add Unsigned and Signed Bytes with Saturation +INST3(vpdpwssd, "vpdpwssd", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x52), 5C, 2X, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | INS_Flags_IsDstDstSrcAVXInstruction) // Multiply and Add Signed Word Integers +INST3(vpdpwssds, "vpdpwssds", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0x53), 5C, 2X, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | INS_Flags_IsDstDstSrcAVXInstruction) // Multiply and Add Signed Word Integers with Saturation #define LAST_AVXVNNI_INSTRUCTION INS_vpdpwssds #define FIRST_AVXVNNIINT8_INSTRUCTION INS_vpdpwsud @@ -656,8 +656,8 @@ INST3(vpdpbuuds, "vpdpbuuds", IUM_WR, BAD_CODE, BAD_ #define FIRST_AVXIFMA_INSTRUCTION INS_vpmadd52huq // Instructions for AVXIFMA -INST3(vpmadd52huq, "vpmadd52huq", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xB5), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed Multiply of Unsigned 52-Bit Unsigned Integers and Add High 52-Bit Products to 64-Bit Accumulators -INST3(vpmadd52luq, "vpmadd52luq", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xB4), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_VEX | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed Multiply of Unsigned 52-Bit Integers and Add the Low 52-Bit Products to Qword Accumulators +INST3(vpmadd52huq, "vpmadd52huq", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xB5), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1 | INS_Flags_IsDstDstSrcAVXInstruction) // Packed Multiply of Unsigned 52-Bit Unsigned Integers and Add High 52-Bit Products to 64-Bit Accumulators +INST3(vpmadd52luq, "vpmadd52luq", IUM_RW, BAD_CODE, BAD_CODE, SSE38(0xB4), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1 | INS_Flags_IsDstDstSrcAVXInstruction) // Packed Multiply of Unsigned 52-Bit Integers and Add the Low 52-Bit Products to Qword Accumulators #define LAST_AVXIFMA_INSTRUCTION INS_vpmadd52luq #define LAST_AVX_INSTRUCTION INS_vpmadd52luq @@ -730,10 +730,10 @@ INST3(vbroadcasti32x2, "vbroadcasti32x2", IUM_WR, BAD_CODE, BAD_ INST3(vbroadcasti32x8, "vbroadcasti32x8", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x5B), ILLEGAL, ILLEGAL, INS_TT_TUPLE8, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_EVEX) // Broadcast packed integer values read from memory to entire register INST3(vbroadcasti64x2, "vbroadcasti64x2", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x5A), ILLEGAL, ILLEGAL, INS_TT_TUPLE2, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_EVEX) // Broadcast packed integer values read from memory to entire register INST3(vbroadcasti64x4, "vbroadcasti64x4", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x5B), ILLEGAL, ILLEGAL, INS_TT_TUPLE2, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_EVEX) // Broadcast packed integer values read from memory to entire register -INST3(vcmppd, "vcmppd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xC2), 4C, 2X, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare packed doubles -INST3(vcmpps, "vcmpps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0xC2), 4C, 2X, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare packed singles -INST3(vcmpsd, "vcmpsd", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0xC2), 4C, 2X, INS_TT_TUPLE1_SCALAR, Input_64Bit | KMask_Base1 | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare scalar doubles -INST3(vcmpss, "vcmpss", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xC2), 4C, 2X, INS_TT_TUPLE1_SCALAR, Input_32Bit | KMask_Base1 | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // compare scalar singles +INST3(vcmppd, "vcmppd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xC2), 4C, 2X, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // compare packed doubles +INST3(vcmpps, "vcmpps", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0xC2), 4C, 2X, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // compare packed singles +INST3(vcmpsd, "vcmpsd", IUM_WR, BAD_CODE, BAD_CODE, SSEDBL(0xC2), 4C, 2X, INS_TT_TUPLE1_SCALAR, Input_64Bit | KMask_Base1 | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // compare scalar doubles +INST3(vcmpss, "vcmpss", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xC2), 4C, 2X, INS_TT_TUPLE1_SCALAR, Input_32Bit | KMask_Base1 | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) // compare scalar singles INST3(vcompresspd, "vcompresspd", IUM_WR, SSE38(0x8A), BAD_CODE, BAD_CODE, 6C, 2C, INS_TT_FULL_MEM, Input_64Bit | REX_W1 | Encoding_EVEX) // Store sparse packed doubles into dense memory INST3(vcompressps, "vcompressps", IUM_WR, SSE38(0x8A), BAD_CODE, BAD_CODE, 6C, 2C, INS_TT_FULL_MEM, Input_32Bit | REX_W0 | Encoding_EVEX) // Store sparse packed singles into dense memory INST3(vcvtpd2qq, "vcvtpd2qq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x7B), 4C, 2X, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_EVEX) // cvt packed doubles to signed QWORDs @@ -816,22 +816,22 @@ INST3(vpbroadcastb_gpr, "vpbroadcastb", IUM_WR, BAD_CODE, BAD_ INST3(vpbroadcastd_gpr, "vpbroadcastd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x7C), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_EVEX) // Broadcast int32 value from gpr to entire register INST3(vpbroadcastq_gpr, "vpbroadcastq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x7C), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_EVEX) // Broadcast int64 value from gpr to entire register INST3(vpbroadcastw_gpr, "vpbroadcastw", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x7B), ILLEGAL, ILLEGAL, INS_TT_TUPLE1_SCALAR, Input_16Bit | KMask_Base8 | REX_W0 | Encoding_EVEX) // Broadcast int16 value from gpr to entire register -INST3(vpcmpb, "vpcmpb", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3F), 4C, 1C, INS_TT_FULL_MEM, KMask_Base16 | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) -INST3(vpcmpd, "vpcmpd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1F), 4C, 1C, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask) -INST3(vpcmpeqb, "vpcmpeqb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x74), 1C, 2X, INS_TT_FULL_MEM, KMask_Base16 | REX_WIG | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 8-bit integers for equality +INST3(vpcmpb, "vpcmpb", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3F), 4C, 1C, INS_TT_FULL_MEM, KMask_Base16 | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) +INST3(vpcmpd, "vpcmpd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1F), 4C, 1C, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask | INS_FLAGS_HasPseudoName) +INST3(vpcmpeqb, "vpcmpeqb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x74), 1C, 2X, INS_TT_FULL_MEM, KMask_Base16 | REX_WIG | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 8-bit integers for equality INST3(vpcmpeqd, "vpcmpeqd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x76), 1C, 2X, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 32-bit integers for equality INST3(vpcmpeqq, "vpcmpeqq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x29), 1C, 2X, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 64-bit integers for equality -INST3(vpcmpeqw, "vpcmpeqw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x75), 1C, 2X, INS_TT_FULL_MEM, KMask_Base8 | REX_WIG | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 16-bit integers for equality -INST3(vpcmpgtb, "vpcmpgtb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x64), 1C, 2X, INS_TT_FULL_MEM, KMask_Base16 | REX_WIG | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 8-bit signed integers for greater than +INST3(vpcmpeqw, "vpcmpeqw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x75), 1C, 2X, INS_TT_FULL_MEM, KMask_Base8 | REX_WIG | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 16-bit integers for equality +INST3(vpcmpgtb, "vpcmpgtb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x64), 1C, 2X, INS_TT_FULL_MEM, KMask_Base16 | REX_WIG | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 8-bit signed integers for greater than INST3(vpcmpgtd, "vpcmpgtd", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x66), 1C, 2X, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 32-bit signed integers for greater than INST3(vpcmpgtq, "vpcmpgtq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x37), 3C, 1C, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 64-bit integers for equality -INST3(vpcmpgtw, "vpcmpgtw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x65), 1C, 2X, INS_TT_FULL_MEM, KMask_Base8 | REX_WIG | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 16-bit signed integers for greater than -INST3(vpcmpq, "vpcmpq", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1F), 4C, 1C, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask) -INST3(vpcmpub, "vpcmpub", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3E), 4C, 1C, INS_TT_FULL_MEM, KMask_Base16 | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) -INST3(vpcmpud, "vpcmpud", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1E), 4C, 1C, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask) -INST3(vpcmpuq, "vpcmpuq", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1E), 4C, 1C, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask) -INST3(vpcmpuw, "vpcmpuw", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3E), 4C, 1C, INS_TT_FULL_MEM, KMask_Base8 | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) -INST3(vpcmpw, "vpcmpw", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3F), 4C, 1C, INS_TT_FULL_MEM, KMask_Base8 | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) +INST3(vpcmpgtw, "vpcmpgtw", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x65), 1C, 2X, INS_TT_FULL_MEM, KMask_Base8 | REX_WIG | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed compare 16-bit signed integers for greater than +INST3(vpcmpq, "vpcmpq", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1F), 4C, 1C, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask | INS_FLAGS_HasPseudoName) +INST3(vpcmpub, "vpcmpub", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3E), 4C, 1C, INS_TT_FULL_MEM, KMask_Base16 | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) +INST3(vpcmpud, "vpcmpud", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1E), 4C, 1C, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask | INS_FLAGS_HasPseudoName) +INST3(vpcmpuq, "vpcmpuq", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x1E), 4C, 1C, INS_TT_FULL, Input_64Bit | KMask_Base2 | REX_W1 | Encoding_EVEX | INS_Flags_Is3OperandInstructionMask | INS_FLAGS_HasPseudoName) +INST3(vpcmpuw, "vpcmpuw", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3E), 4C, 1C, INS_TT_FULL_MEM, KMask_Base8 | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) +INST3(vpcmpw, "vpcmpw", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x3F), 4C, 1C, INS_TT_FULL_MEM, KMask_Base8 | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction | INS_FLAGS_HasPseudoName) INST3(vpcompressd, "vpcompressd", IUM_WR, SSE38(0x8B), BAD_CODE, BAD_CODE, 6C, 2C, INS_TT_FULL_MEM, Input_32Bit | REX_W0 | Encoding_EVEX) // Store sparse packed doublewords into dense memory INST3(vpcompressq, "vpcompressq", IUM_WR, SSE38(0x8B), BAD_CODE, BAD_CODE, 6C, 2C, INS_TT_FULL_MEM, Input_64Bit | REX_W1 | Encoding_EVEX) // Store sparse packed quadwords into dense memory INST3(vpconflictd, "vpconflictd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xC4), ILLEGAL, ILLEGAL, INS_TT_FULL, Input_32Bit | KMask_Base4 | REX_W0 | Encoding_EVEX) // Detect conflicts within a vector of packed dword values into dense memory/register @@ -1154,13 +1154,29 @@ INST3(ccmpge, "ccmpge", IUM_RD, 0x000038, 0x0003880, 0x INST3(ccmple, "ccmple", IUM_RD, 0x000038, 0x0003880, 0x00003A, ILLEGAL, ILLEGAL, INS_TT_NONE, Writes_OF | Writes_SF | Writes_ZF | Writes_CF | INS_FLAGS_Has_Sbit) INST3(ccmpg, "ccmpg", IUM_RD, 0x000038, 0x0003880, 0x00003A, ILLEGAL, ILLEGAL, INS_TT_NONE, Writes_OF | Writes_SF | Writes_ZF | Writes_CF | INS_FLAGS_Has_Sbit) #define LAST_CCMP_INSTRUCTION INS_ccmpg -#define LAST_APX_INSTRUCTION INS_ccmpg +INST3(crc32_apx, "crc32", IUM_RW, BAD_CODE, BAD_CODE, 0x0000F0, 3C, 1C, INS_TT_NONE, INS_FLAGS_None) +INST3(movbe_apx, "movbe", IUM_WR, 0x000061, BAD_CODE, 0x000060, ILLEGAL, ILLEGAL, INS_TT_NONE, INS_FLAGS_None) + +INST3(seto_apx, "setzuo", IUM_WR, SSEDBLMAP(4, 0x40), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_OF) +INST3(setno_apx, "setzuno", IUM_WR, SSEDBLMAP(4, 0x41), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_OF) +INST3(setb_apx, "setzub", IUM_WR, SSEDBLMAP(4, 0x42), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_CF) +INST3(setae_apx, "setzuae", IUM_WR, SSEDBLMAP(4, 0x43), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_CF) +INST3(sete_apx, "setzue", IUM_WR, SSEDBLMAP(4, 0x44), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_ZF) +INST3(setne_apx, "setzune", IUM_WR, SSEDBLMAP(4, 0x45), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_ZF) +INST3(setbe_apx, "setzube", IUM_WR, SSEDBLMAP(4, 0x46), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_ZF | Reads_CF) +INST3(seta_apx, "setzua", IUM_WR, SSEDBLMAP(4, 0x47), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_ZF | Reads_CF) +INST3(sets_apx, "setzus", IUM_WR, SSEDBLMAP(4, 0x48), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_SF) +INST3(setns_apx, "setzuns", IUM_WR, SSEDBLMAP(4, 0x49), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_SF) +INST3(setp_apx, "setzup", IUM_WR, SSEDBLMAP(4, 0x4A), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_PF) +INST3(setnp_apx, "setzunp", IUM_WR, SSEDBLMAP(4, 0x4B), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_PF) +INST3(setl_apx, "setzul", IUM_WR, SSEDBLMAP(4, 0x4C), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_OF | Reads_SF) +INST3(setge_apx, "setzuge", IUM_WR, SSEDBLMAP(4, 0x4D), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_OF | Reads_SF) +INST3(setle_apx, "setzule", IUM_WR, SSEDBLMAP(4, 0x4E), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_OF | Reads_SF | Reads_ZF) +INST3(setg_apx, "setzug", IUM_WR, SSEDBLMAP(4, 0x4F), BAD_CODE, BAD_CODE, ILLEGAL, ILLEGAL, INS_TT_NONE, Reads_OF | Reads_SF | Reads_ZF) +#define LAST_APX_INSTRUCTION INS_setg_apx // Scalar instructions in SSE4.2 INST3(crc32, "crc32", IUM_RW, BAD_CODE, BAD_CODE, PSSE38(0xF2, 0xF0), 3C, 1C, INS_TT_NONE, INS_FLAGS_None) -#ifdef TARGET_AMD64 -INST3(crc32_apx, "crc32", IUM_RW, BAD_CODE, BAD_CODE, 0x0000F0, 3C, 1C, INS_TT_NONE, INS_FLAGS_None) -#endif // BMI1 INST3(tzcnt, "tzcnt", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xBC), 3C, 1C, INS_TT_NONE, Undefined_OF | Undefined_SF | Writes_ZF | Undefined_AF | Undefined_PF | Writes_CF | Encoding_REX2) // Count the Number of Trailing Zero Bits @@ -1176,9 +1192,6 @@ INST3(lzcnt_apx, "lzcnt", IUM_WR, BAD_CODE, BAD_CODE, // MOVBE INST3(movbe, "movbe", IUM_WR, PCKMVB(0xF1), BAD_CODE, PCKMVB(0xF0), ILLEGAL, ILLEGAL, INS_TT_NONE, INS_FLAGS_None) -#ifdef TARGET_AMD64 -INST3(movbe_apx, "movbe", IUM_WR, 0x000061, BAD_CODE, 0x000060, ILLEGAL, ILLEGAL, INS_TT_NONE, INS_FLAGS_None) -#endif // POPCNT INST3(popcnt, "popcnt", IUM_WR, BAD_CODE, BAD_CODE, SSEFLT(0xB8), 3C, 1C, INS_TT_NONE, Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Resets_CF | Encoding_REX2) @@ -1253,8 +1266,8 @@ INST1(leave, "leave", IUM_RD, 0x0000C9, INST1(serialize, "serialize", IUM_RD, 0x0fe801, 105C, 50C, INS_TT_NONE, INS_FLAGS_None) -INST1(cwde, "cwde", IUM_RD, 0x000098, ILLEGAL, ILLEGAL, INS_TT_NONE, INS_FLAGS_None) -INST1(cdq, "cdq", IUM_RD, 0x000099, 1C, 2X, INS_TT_NONE, INS_FLAGS_None) +INST1(cwde, "cwde", IUM_RD, 0x000098, ILLEGAL, ILLEGAL, INS_TT_NONE, INS_FLAGS_HasPseudoName) +INST1(cdq, "cdq", IUM_RD, 0x000099, 1C, 2X, INS_TT_NONE, INS_FLAGS_HasPseudoName) INST1(idiv, "idiv", IUM_RD, 0x0038F6, ILLEGAL, ILLEGAL, INS_TT_NONE, Undefined_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Undefined_CF | INS_FLAGS_Has_Wbit | Encoding_REX2 | INS_Flags_Has_NF) INST1(imulEAX, "imul", IUM_RD, 0x0028F6, 4C, 1C, INS_TT_NONE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Wbit | Encoding_REX2 | INS_Flags_Has_NF) INST1(div, "div", IUM_RD, 0x0030F6, ILLEGAL, ILLEGAL, INS_TT_NONE, Undefined_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Undefined_CF | INS_FLAGS_Has_Wbit | Encoding_REX2 | INS_Flags_Has_NF) diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index 3a3b85ba1d4863..d1e69950efc631 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -738,16 +738,9 @@ inline size_t unsigned_abs(int64_t x) #define FEATURE_TAILCALL_OPT_SHARED_RETURN 0 #endif // !FEATURE_TAILCALL_OPT -#define CLFLG_CODESIZE 0x00001 -#define CLFLG_CODESPEED 0x00002 -#define CLFLG_CSE 0x00004 -#define CLFLG_REGVAR 0x00008 -#define CLFLG_RNGCHKOPT 0x00010 -#define CLFLG_DEADSTORE 0x00020 -#define CLFLG_CODEMOTION 0x00040 -#define CLFLG_QMARK 0x00080 -#define CLFLG_TREETRANS 0x00100 -#define CLFLG_INLINING 0x00200 +#define CLFLG_REGVAR 0x00008 +#define CLFLG_TREETRANS 0x00100 +#define CLFLG_INLINING 0x00200 #if FEATURE_STRUCTPROMOTE #define CLFLG_STRUCTPROMOTE 0x00400 @@ -761,10 +754,7 @@ inline size_t unsigned_abs(int64_t x) #define FEATURE_LOOP_ALIGN 0 #endif -#define CLFLG_MAXOPT \ - (CLFLG_CSE | CLFLG_REGVAR | CLFLG_RNGCHKOPT | CLFLG_DEADSTORE | CLFLG_CODEMOTION | CLFLG_QMARK | CLFLG_TREETRANS | \ - CLFLG_INLINING | CLFLG_STRUCTPROMOTE) - +#define CLFLG_MAXOPT (CLFLG_REGVAR | CLFLG_TREETRANS | CLFLG_INLINING | CLFLG_STRUCTPROMOTE) #define CLFLG_MINOPT (CLFLG_TREETRANS) /*****************************************************************************/ diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index 3c2f9c67c0f78f..f5d05b2a95aa66 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -436,6 +436,7 @@ RELEASE_CONFIG_INTEGER(EnableEmbeddedMasking, "EnableEmbeddedMasking", RELEASE_CONFIG_INTEGER(EnableApxNDD, "EnableApxNDD", 0) // Allows APX NDD feature to be disabled RELEASE_CONFIG_INTEGER(EnableApxConditionalChaining, "EnableApxConditionalChaining", 0) // Allows APX conditional compare chaining RELEASE_CONFIG_INTEGER(EnableApxPPX, "EnableApxPPX", 0) // Allows APX PPX feature to be disabled +RELEASE_CONFIG_INTEGER(EnableApxZU, "EnableApxZU", 0) // Allows APX ZU feature to be disabled // clang-format on @@ -584,7 +585,7 @@ OPT_CONFIG_INTEGER(JitDoIfConversion, "JitDoIfConversion", 1) OPT_CONFIG_INTEGER(JitDoOptimizeMaskConversions, "JitDoOptimizeMaskConversions", 1) // Perform optimization of mask // conversions -RELEASE_CONFIG_INTEGER(JitOptimizeAwait, "JitOptimizeAwait", 1) // Perform optimization of Await intrinsics +OPT_CONFIG_INTEGER(JitOptimizeAwait, "JitOptimizeAwait", 1) // Perform optimization of Await intrinsics RELEASE_CONFIG_INTEGER(JitEnableOptRepeat, "JitEnableOptRepeat", 1) // If zero, do not allow JitOptRepeat RELEASE_CONFIG_METHODSET(JitOptRepeat, "JitOptRepeat") // Runs optimizer multiple times on specified methods diff --git a/src/coreclr/jit/jiteh.cpp b/src/coreclr/jit/jiteh.cpp index bf7ba8cb03bc9a..287cd28393d388 100644 --- a/src/coreclr/jit/jiteh.cpp +++ b/src/coreclr/jit/jiteh.cpp @@ -1522,6 +1522,8 @@ void Compiler::fgAllocEHTable() compHndBBtab = new (this, CMK_BasicBlock) EHblkDsc[compHndBBtabAllocCount]; + memset(compHndBBtab, 0, compHndBBtabAllocCount * sizeof(*compHndBBtab)); + compHndBBtabCount = info.compXcptnsCount; } @@ -1883,6 +1885,10 @@ EHblkDsc* Compiler::fgTryAddEHTableEntries(unsigned XTnum, unsigned count, bool EHblkDsc* newTable = new (this, CMK_BasicBlock) EHblkDsc[compHndBBtabAllocCount]; + // Zero the storage + + memset(newTable, 0, compHndBBtabAllocCount * sizeof(*compHndBBtab)); + // Move over the stuff before the new entries memcpy_s(newTable, compHndBBtabAllocCount * sizeof(*compHndBBtab), compHndBBtab, XTnum * sizeof(*compHndBBtab)); diff --git a/src/coreclr/jit/lclmorph.cpp b/src/coreclr/jit/lclmorph.cpp index 7366dfe9bce1fd..cd464797e79890 100644 --- a/src/coreclr/jit/lclmorph.cpp +++ b/src/coreclr/jit/lclmorph.cpp @@ -1240,6 +1240,22 @@ class LocalAddressVisitor final : public GenTreeVisitor PopValue(); break; + case GT_CAST: + { + assert(TopValue(1).Node() == node); + assert(TopValue(0).Node() == node->AsCast()->CastOp()); + + var_types castToType = node->CastToType(); + bool isPtrCast = (castToType == TYP_I_IMPL) || (castToType == TYP_U_IMPL) || (castToType == TYP_BYREF); + if (!isPtrCast || node->gtOverflow() || !TopValue(0).IsAddress() || + !TopValue(1).AddOffset(TopValue(0), 0)) + { + EscapeValue(TopValue(0), node); + } + + PopValue(); + break; + } case GT_CALL: while (TopValue(0).Node() != node) { @@ -1462,9 +1478,9 @@ class LocalAddressVisitor final : public GenTreeVisitor unsigned lclNum = val.LclNum(); LclVarDsc* varDsc = m_compiler->lvaGetDesc(lclNum); - GenTreeFlags defFlag = GTF_EMPTY; - GenTreeCall* callUser = (user != nullptr) && user->IsCall() ? user->AsCall() : nullptr; - bool hasHiddenStructArg = false; + GenTreeFlags defFlag = GTF_EMPTY; + GenTreeCall* callUser = (user != nullptr) && user->IsCall() ? user->AsCall() : nullptr; + bool escapeAddr = true; if (m_compiler->opts.compJitOptimizeStructHiddenBuffer && (callUser != nullptr) && m_compiler->IsValidLclAddr(lclNum, val.Offset())) { @@ -1484,7 +1500,7 @@ class LocalAddressVisitor final : public GenTreeVisitor (val.Node() == callUser->gtArgs.GetRetBufferArg()->GetNode())) { m_compiler->lvaSetHiddenBufferStructArg(lclNum); - hasHiddenStructArg = true; + escapeAddr = false; callUser->gtCallMoreFlags |= GTF_CALL_M_RETBUFFARG_LCLOPT; defFlag = GTF_VAR_DEF; @@ -1496,7 +1512,25 @@ class LocalAddressVisitor final : public GenTreeVisitor } } - if (!hasHiddenStructArg) + if ((callUser != nullptr) && callUser->IsAsync() && m_compiler->IsValidLclAddr(lclNum, val.Offset())) + { + CallArg* suspendedArg = callUser->gtArgs.FindWellKnownArg(WellKnownArg::AsyncSuspendedIndicator); + if ((suspendedArg != nullptr) && (val.Node() == suspendedArg->GetNode())) + { + INDEBUG(varDsc->SetDefinedViaAddress(true)); + escapeAddr = false; + defFlag = GTF_VAR_DEF; + + if ((val.Offset() != 0) || (varDsc->lvExactSize() != 1)) + { + defFlag |= GTF_VAR_USEASG; + } + + callUser->asyncInfo->HasSuspensionIndicatorDef = true; + } + } + + if (escapeAddr) { unsigned exposedLclNum = varDsc->lvIsStructField ? varDsc->lvParentLcl : lclNum; @@ -1516,7 +1550,8 @@ class LocalAddressVisitor final : public GenTreeVisitor // a ByRef to an INT32 when they actually write a SIZE_T or INT64. There are cases where // overwriting these extra 4 bytes corrupts some data (such as a saved register) that leads // to A/V. Whereas previously the JIT64 codegen did not lead to an A/V. - if ((callUser != nullptr) && !varDsc->lvIsParam && !varDsc->lvIsStructField && genActualTypeIsInt(varDsc)) + if ((callUser != nullptr) && !varDsc->lvIsParam && !varDsc->lvIsStructField && genActualTypeIsInt(varDsc) && + escapeAddr) { varDsc->lvQuirkToLong = true; JITDUMP("Adding a quirk for the storage size of V%02u of type %s\n", val.LclNum(), @@ -1618,7 +1653,7 @@ class LocalAddressVisitor final : public GenTreeVisitor assert(addr->TypeIs(TYP_BYREF, TYP_I_IMPL)); assert(m_compiler->lvaVarAddrExposed(lclNum) || ((m_lclAddrAssertions != nullptr) && m_lclAddrAssertions->IsMarkedForExposure(lclNum)) || - m_compiler->lvaGetDesc(lclNum)->IsHiddenBufferStructArg()); + m_compiler->lvaGetDesc(lclNum)->IsDefinedViaAddress()); if (m_compiler->IsValidLclAddr(lclNum, offset)) { diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 246cccee168018..f96943f2069bbe 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -387,12 +387,12 @@ void Compiler::lvaInitArgs(bool hasRetBuffArg) //------------------------------------------------------------------------- lvaInitUserArgs(&varNum, numUserArgsToSkip, numUserArgs); #if !USER_ARGS_COME_LAST + lvaInitAsyncContinuation(&varNum); + //@GENERICS: final instantiation-info argument for shared generic methods // and shared generic struct instance methods lvaInitGenericsCtxt(&varNum); - lvaInitAsyncContinuation(&varNum); - /* If the method is varargs, process the varargs cookie */ lvaInitVarArgsHandle(&varNum); #endif @@ -2089,7 +2089,7 @@ void Compiler::lvaSetHiddenBufferStructArg(unsigned varNum) LclVarDsc* varDsc = lvaGetDesc(varNum); #ifdef DEBUG - varDsc->SetHiddenBufferStructArg(true); + varDsc->SetDefinedViaAddress(true); #endif if (varDsc->lvPromoted) @@ -2100,7 +2100,7 @@ void Compiler::lvaSetHiddenBufferStructArg(unsigned varNum) { noway_assert(lvaTable[i].lvIsStructField); #ifdef DEBUG - lvaTable[i].SetHiddenBufferStructArg(true); + lvaTable[i].SetDefinedViaAddress(true); #endif lvaSetVarDoNotEnregister(i DEBUGARG(DoNotEnregisterReason::HiddenBufferStructArg)); @@ -3435,7 +3435,7 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt, if (tree->OperIs(GT_LCL_ADDR)) { LclVarDsc* varDsc = lvaGetDesc(tree->AsLclVarCommon()); - assert(varDsc->IsAddressExposed() || varDsc->IsHiddenBufferStructArg()); + assert(varDsc->IsAddressExposed() || varDsc->IsDefinedViaAddress()); varDsc->incRefCnts(weight, this); return; } @@ -6365,9 +6365,9 @@ void Compiler::lvaDumpEntry(unsigned lclNum, FrameLayoutState curState, size_t r { printf("X"); } - if (varDsc->IsHiddenBufferStructArg()) + if (varDsc->IsDefinedViaAddress()) { - printf("H"); + printf("DA"); } if (varTypeIsStruct(varDsc)) { @@ -6428,9 +6428,9 @@ void Compiler::lvaDumpEntry(unsigned lclNum, FrameLayoutState curState, size_t r { printf(" addr-exposed"); } - if (varDsc->IsHiddenBufferStructArg()) + if (varDsc->IsDefinedViaAddress()) { - printf(" hidden-struct-arg"); + printf(" defined-via-address"); } if (varDsc->lvHasLdAddrOp) { diff --git a/src/coreclr/jit/liveness.cpp b/src/coreclr/jit/liveness.cpp index d51746731b6c8e..05786eb1a9045e 100644 --- a/src/coreclr/jit/liveness.cpp +++ b/src/coreclr/jit/liveness.cpp @@ -66,9 +66,10 @@ void Compiler::fgMarkUseDef(GenTreeLclVarCommon* tree) if (compRationalIRForm && (varDsc->lvType != TYP_STRUCT) && !varTypeIsMultiReg(varDsc)) { - // If this is an enregisterable variable that is not marked doNotEnregister, + // If this is an enregisterable variable that is not marked doNotEnregister and not defined via address, // we should only see direct references (not ADDRs). - assert(varDsc->lvDoNotEnregister || tree->OperIs(GT_LCL_VAR, GT_STORE_LCL_VAR)); + assert(varDsc->lvDoNotEnregister || varDsc->lvDefinedViaAddress || + tree->OperIs(GT_LCL_VAR, GT_STORE_LCL_VAR)); } if (isUse && !VarSetOps::IsMember(this, fgCurDefSet, varDsc->lvVarIndex)) @@ -342,11 +343,11 @@ void Compiler::fgPerNodeLocalVarLiveness(GenTree* tree) } } - GenTreeLclVarCommon* definedLcl = gtCallGetDefinedRetBufLclAddr(call); - if (definedLcl != nullptr) - { - fgMarkUseDef(definedLcl); - } + auto visitDef = [=](GenTreeLclVarCommon* lcl) { + fgMarkUseDef(lcl); + return GenTree::VisitResult::Continue; + }; + call->VisitLocalDefNodes(this, visitDef); break; } @@ -796,13 +797,11 @@ void Compiler::fgLiveVarAnalysis() // call - The call node in question. // // Returns: -// local defined by the call, if any (eg retbuf) +// partially defined local by the call, if any (eg retbuf) // GenTreeLclVarCommon* Compiler::fgComputeLifeCall(VARSET_TP& life, VARSET_VALARG_TP keepAliveVars, GenTreeCall* call) { assert(call != nullptr); - GenTreeLclVarCommon* definedLcl = nullptr; - // If this is a tail-call via helper, and we have any unmanaged p/invoke calls in // the method, then we're going to run the p/invoke epilog // So we mark the FrameRoot as used by this instruction. @@ -824,7 +823,7 @@ GenTreeLclVarCommon* Compiler::fgComputeLifeCall(VARSET_TP& life, VARSET_VALARG_ } // TODO: we should generate the code for saving to/restoring - // from the inlined N/Direct frame instead. + // from the inlined PInvoke frame instead. /* Is this call to unmanaged code? */ if (call->IsUnmanaged() && compMethodRequiresPInvokeFrame()) @@ -861,13 +860,22 @@ GenTreeLclVarCommon* Compiler::fgComputeLifeCall(VARSET_TP& life, VARSET_VALARG_ } } - definedLcl = gtCallGetDefinedRetBufLclAddr(call); - if (definedLcl != nullptr) - { - fgComputeLifeLocal(life, keepAliveVars, definedLcl); - } + GenTreeLclVarCommon* partialDef = nullptr; + + auto visitDef = [&](const LocalDef& def) { + if (!def.IsEntire) + { + assert(partialDef == nullptr); + partialDef = def.Def; + } + + fgComputeLifeLocal(life, keepAliveVars, def.Def); + return GenTree::VisitResult::Continue; + }; + + call->VisitLocalDefs(this, visitDef); - return definedLcl; + return partialDef; } //------------------------------------------------------------------------ @@ -1207,11 +1215,12 @@ void Compiler::fgComputeLife(VARSET_TP& life, if (tree->IsCall()) { - GenTreeLclVarCommon* const definedLcl = fgComputeLifeCall(life, keepAliveVars, tree->AsCall()); - if (definedLcl != nullptr) + GenTreeLclVarCommon* const partialDef = fgComputeLifeCall(life, keepAliveVars, tree->AsCall()); + if (partialDef != nullptr) { - isUse = (definedLcl->gtFlags & GTF_VAR_USEASG) != 0; - varDsc = lvaGetDesc(definedLcl); + assert((partialDef->gtFlags & GTF_VAR_USEASG) != 0); + isUse = true; + varDsc = lvaGetDesc(partialDef); } } else if (tree->OperIsNonPhiLocal()) diff --git a/src/coreclr/jit/loopcloning.cpp b/src/coreclr/jit/loopcloning.cpp index 4703704553408a..b77fdf7f99d8c4 100644 --- a/src/coreclr/jit/loopcloning.cpp +++ b/src/coreclr/jit/loopcloning.cpp @@ -104,7 +104,7 @@ GenTree* LC_Array::ToGenTree(Compiler* comp, BasicBlock* bb) // If asked for arrlen invoke arr length operator. if (oper == ArrLen) { - GenTree* arrLen = comp->gtNewArrLen(TYP_INT, arr, OFFSETOF__CORINFO_Array__length, bb); + GenTree* arrLen = comp->gtNewArrLen(TYP_INT, arr, OFFSETOF__CORINFO_Array__length); // We already guaranteed (by a sequence of preceding checks) that the array length operator will not // throw an exception because we null checked the base array. @@ -177,12 +177,13 @@ GenTree* LC_Ident::ToGenTree(Compiler* comp, BasicBlock* bb) case IndirOfLocal: { GenTree* addr = comp->gtNewLclvNode(lclNum, TYP_REF); - if (indirOffs != 0) + if (indirOffs == 0) { - addr = comp->gtNewOperNode(GT_ADD, TYP_BYREF, addr, - comp->gtNewIconNode(static_cast(indirOffs), TYP_I_IMPL)); + return comp->gtNewMethodTableLookup(addr); } + addr = comp->gtNewOperNode(GT_ADD, TYP_BYREF, addr, + comp->gtNewIconNode(static_cast(indirOffs), TYP_I_IMPL)); GenTree* const indir = comp->gtNewIndir(TYP_I_IMPL, addr, GTF_IND_INVARIANT); return indir; } @@ -3080,6 +3081,10 @@ PhaseStatus Compiler::optCloneLoops() bool allTrue = false; bool anyFalse = false; const int sizeLimit = JitConfig.JitCloneLoopsSizeLimit(); + auto countNode = [](GenTree* tree) -> unsigned { + return 1; + }; + context.EvaluateConditions(loop->GetIndex(), &allTrue, &anyFalse DEBUGARG(verbose)); if (anyFalse) { @@ -3102,8 +3107,9 @@ PhaseStatus Compiler::optCloneLoops() // tree nodes in all statements in all blocks in the loop. // This value is compared to a hard-coded threshold, and if bigger, // then the method returns false. - else if ((sizeLimit >= 0) && optLoopComplexityExceeds(loop, (unsigned)sizeLimit)) + else if ((sizeLimit >= 0) && optLoopComplexityExceeds(loop, (unsigned)sizeLimit, countNode)) { + JITDUMP(FMT_LP " exceeds cloning size limit %d\n", loop->GetIndex(), sizeLimit); context.CancelLoopOptInfo(loop->GetIndex()); } } diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 8fe43d05484567..9b1889e1673b8e 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -150,34 +150,7 @@ bool Lowering::CheckImmedAndMakeContained(GenTree* parentNode, GenTree* childNod // bool Lowering::IsInvariantInRange(GenTree* node, GenTree* endExclusive) const { - assert((node != nullptr) && (endExclusive != nullptr)); - - // Quick early-out for unary cases - // - if (node->gtNext == endExclusive) - { - return true; - } - - if (node->OperConsumesFlags()) - { - return false; - } - - m_scratchSideEffects.Clear(); - m_scratchSideEffects.AddNode(comp, node); - - for (GenTree* cur = node->gtNext; cur != endExclusive; cur = cur->gtNext) - { - assert((cur != nullptr) && "Expected first node to precede end node"); - const bool strict = true; - if (m_scratchSideEffects.InterferesWith(comp, cur, strict)) - { - return false; - } - } - - return true; + return m_scratchSideEffects.IsLirInvariantInRange(comp, node, endExclusive); } //------------------------------------------------------------------------ @@ -196,42 +169,7 @@ bool Lowering::IsInvariantInRange(GenTree* node, GenTree* endExclusive) const // bool Lowering::IsInvariantInRange(GenTree* node, GenTree* endExclusive, GenTree* ignoreNode) const { - assert((node != nullptr) && (endExclusive != nullptr)); - - if (ignoreNode == nullptr) - { - return IsInvariantInRange(node, endExclusive); - } - - if ((node->gtNext == endExclusive) || ((node->gtNext == ignoreNode) && (node->gtNext->gtNext == endExclusive))) - { - return true; - } - - if (node->OperConsumesFlags()) - { - return false; - } - - m_scratchSideEffects.Clear(); - m_scratchSideEffects.AddNode(comp, node); - - for (GenTree* cur = node->gtNext; cur != endExclusive; cur = cur->gtNext) - { - assert((cur != nullptr) && "Expected first node to precede end node"); - if (cur == ignoreNode) - { - continue; - } - - const bool strict = true; - if (m_scratchSideEffects.InterferesWith(comp, cur, strict)) - { - return false; - } - } - - return true; + return m_scratchSideEffects.IsLirInvariantInRange(comp, node, endExclusive, ignoreNode); } //------------------------------------------------------------------------ @@ -258,50 +196,7 @@ bool Lowering::IsRangeInvariantInRange(GenTree* rangeStart, GenTree* endExclusive, GenTree* ignoreNode) const { - assert((rangeStart != nullptr) && (rangeEnd != nullptr)); - - if ((rangeEnd->gtNext == endExclusive) || - ((ignoreNode != nullptr) && (rangeEnd->gtNext == ignoreNode) && (rangeEnd->gtNext->gtNext == endExclusive))) - { - return true; - } - - if (rangeStart->OperConsumesFlags()) - { - return false; - } - - m_scratchSideEffects.Clear(); - GenTree* cur = rangeStart; - while (true) - { - m_scratchSideEffects.AddNode(comp, cur); - - if (cur == rangeEnd) - { - break; - } - - cur = cur->gtNext; - assert((cur != nullptr) && "Expected rangeStart to precede rangeEnd"); - } - - for (GenTree* cur = rangeEnd->gtNext; cur != endExclusive; cur = cur->gtNext) - { - assert((cur != nullptr) && "Expected first node to precede end node"); - if (cur == ignoreNode) - { - continue; - } - - const bool strict = true; - if (m_scratchSideEffects.InterferesWith(comp, cur, strict)) - { - return false; - } - } - - return true; + return m_scratchSideEffects.IsLirRangeInvariantInRange(comp, rangeStart, rangeEnd, endExclusive, ignoreNode); } //------------------------------------------------------------------------ @@ -949,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 @@ -973,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. @@ -1058,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). @@ -1102,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) + if ((targetCnt == 2) && (defaultEdge->getDupCount() == 0)) { - 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 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 @@ -1314,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); } @@ -1346,7 +1222,8 @@ GenTree* Lowering::LowerSwitch(GenTree* node) JITDUMP("Lowering switch " FMT_BB ": using jump table expansion\n", originalSwitchBB->bbNum); #ifdef TARGET_64BIT - if (tempLclType != TYP_I_IMPL) + if (RISCV64_ONLY(!comp->compOpportunisticallyDependsOn(InstructionSet_Zba)&&) // shXadd.uw 0-extends index + tempLclType != TYP_I_IMPL) { // SWITCH_TABLE expects the switch value (the index into the jump table) to be TYP_I_IMPL. // Note that the switch value is unsigned so the cast should be unsigned as well. @@ -1360,24 +1237,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", @@ -1385,9 +1267,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(); @@ -1412,9 +1294,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) @@ -1427,11 +1309,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; @@ -4432,6 +4309,7 @@ GenTree* Lowering::OptimizeConstCompare(GenTree* cmp) // Transform EQ|NE(AND(x, y), y) into EQ|NE(AND(NOT(x), y), 0) when y is a constant. // + andOp1->ClearContained(); GenTree* notNode = comp->gtNewOperNode(GT_NOT, andOp1->TypeGet(), andOp1); cmp->gtGetOp1()->AsOp()->gtOp1 = notNode; BlockRange().InsertAfter(andOp1, notNode); @@ -5110,7 +4988,7 @@ void Lowering::LowerRetFieldList(GenTreeOp* ret, GenTreeFieldList* fieldList) auto getRegInfo = [=, &retDesc](unsigned regIndex) { unsigned offset = retDesc.GetReturnFieldOffset(regIndex); - var_types regType = genActualType(retDesc.GetReturnRegType(regIndex)); + var_types regType = retDesc.GetReturnRegType(regIndex); return LowerFieldListRegisterInfo(offset, regType); }; @@ -5432,6 +5310,27 @@ void Lowering::LowerFieldListToFieldListOfRegisters(GenTreeFieldList* fieldLis regEntry->SetNode(bitCast); } + // If this is the last entry then try to optimize out unnecessary + // normalizing casts, similar to how LowerRetSingleRegStructLclVar + // avoids inserting them. + if ((i == numRegs - 1) && varTypeUsesIntReg(regType)) + { + GenTree* node = regEntry->GetNode(); + // If this is a truncation that affects only bits after the return + // size then it can be removed. Those bits are undefined in all our + // ABIs for structs. + while (node->OperIs(GT_CAST) && !node->gtOverflow() && (genActualType(node->CastFromType()) == TYP_INT) && + (genActualType(node->CastToType()) == TYP_INT) && + (genTypeSize(regType) <= genTypeSize(node->CastToType()))) + { + GenTree* op = node->AsCast()->CastOp(); + regEntry->SetNode(op); + op->ClearContained(); + node->gtBashToNOP(); + node = op; + } + } + if (fieldListPrev->gtNext != fieldList) { LowerRange(fieldListPrev->gtNext, fieldList->gtPrev); @@ -8741,15 +8640,16 @@ void Lowering::FindInducedParameterRegisterLocals() { hasRegisterKill |= node->IsCall(); - GenTreeLclVarCommon* storeLcl; - if (node->DefinesLocal(comp, &storeLcl)) - { - storedToLocals.Emplace(storeLcl->GetLclNum(), true); - continue; - } + auto visitDefs = [&](GenTreeLclVarCommon* lcl) { + storedToLocals.Emplace(lcl->GetLclNum(), true); + return GenTree::VisitResult::Continue; + }; + + node->VisitLocalDefNodes(comp, visitDefs); if (node->OperIs(GT_LCL_ADDR)) { + // Model these as stored to, since we cannot reason about them in the same way. storedToLocals.Emplace(node->AsLclVarCommon()->GetLclNum(), true); continue; } @@ -9809,7 +9709,7 @@ bool Lowering::TryLowerBlockStoreAsGcBulkCopyCall(GenTreeBlk* blk) LIR::Use nodeUse; BlockRange().TryGetUse(node, &nodeUse); GenTree* nodeClone = comp->gtNewLclvNode(nodeUse.ReplaceWithLclVar(comp), genActualType(node)); - GenTree* nullcheck = comp->gtNewNullCheck(nodeClone, comp->compCurBB); + GenTree* nullcheck = comp->gtNewNullCheck(nodeClone); BlockRange().InsertAfter(nodeUse.Def(), nodeClone, nullcheck); LowerNode(nullcheck); } @@ -11262,7 +11162,7 @@ void Lowering::TransformUnusedIndirection(GenTreeIndir* ind, Compiler* comp, Bas if (useNullCheck && !ind->OperIs(GT_NULLCHECK)) { - comp->gtChangeOperToNullCheck(ind, block); + comp->gtChangeOperToNullCheck(ind); ind->ClearUnusedValue(); } else if (!useNullCheck && !ind->OperIs(GT_IND)) @@ -11600,6 +11500,22 @@ bool Lowering::TryLowerAndNegativeOne(GenTreeOp* node, GenTree** nextNode) } #if defined(TARGET_AMD64) || defined(TARGET_ARM64) +//------------------------------------------------------------------------ +// CanConvertOpToCCMP : Checks whether operand can be converted to CCMP +// +// Arguments: +// operand - operand to check for CCMP conversion +// tree - parent of the operand +// +// Return Value: +// true if operand can be converted to CCMP +// +bool Lowering::CanConvertOpToCCMP(GenTree* operand, GenTree* tree) +{ + return operand->OperIsCmpCompare() && varTypeIsIntegralOrI(operand->gtGetOp1()) && + IsInvariantInRange(operand, tree); +} + //------------------------------------------------------------------------ // TryLowerAndOrToCCMP : Lower AND/OR of two conditions into test + CCMP + SETCC nodes. // @@ -11641,16 +11557,22 @@ bool Lowering::TryLowerAndOrToCCMP(GenTreeOp* tree, GenTree** next) // by TryLowerConditionToFlagsNode. // GenCondition cond1; - if (op2->OperIsCmpCompare() && varTypeIsIntegralOrI(op2->gtGetOp1()) && IsInvariantInRange(op2, tree) && - (op2->gtGetOp1()->IsIntegralConst() || !op2->gtGetOp1()->isContained()) && - (op2->gtGetOp2() == nullptr || op2->gtGetOp2()->IsIntegralConst() || !op2->gtGetOp2()->isContained()) && + bool canConvertOp2ToCCMP = CanConvertOpToCCMP(op2, tree); + bool canConvertOp1ToCCMP = CanConvertOpToCCMP(op1, tree); + + if (canConvertOp2ToCCMP && + (!canConvertOp1ToCCMP || + ((op2->gtGetOp1()->IsIntegralConst() || !op2->gtGetOp1()->isContained()) && + (op2->gtGetOp2() == nullptr || op2->gtGetOp2()->IsIntegralConst() || !op2->gtGetOp2()->isContained()))) && TryLowerConditionToFlagsNode(tree, op1, &cond1, false)) { // Fall through, converting op2 to the CCMP } - else if (op1->OperIsCmpCompare() && varTypeIsIntegralOrI(op1->gtGetOp1()) && IsInvariantInRange(op1, tree) && - (op1->gtGetOp1()->IsIntegralConst() || !op1->gtGetOp1()->isContained()) && - (op1->gtGetOp2() == nullptr || op1->gtGetOp2()->IsIntegralConst() || !op1->gtGetOp2()->isContained()) && + else if (canConvertOp1ToCCMP && + (!op1->gtGetOp1()->isContained() || op1->gtGetOp1()->IsIntegralConst() || + IsContainableMemoryOp(op1->gtGetOp1())) && + (op1->gtGetOp2() == nullptr || !op1->gtGetOp2()->isContained() || op1->gtGetOp2()->IsIntegralConst() || + IsContainableMemoryOp(op1->gtGetOp2())) && TryLowerConditionToFlagsNode(tree, op2, &cond1, false)) { std::swap(op1, op2); diff --git a/src/coreclr/jit/lower.h b/src/coreclr/jit/lower.h index 49d74503e0593b..b3afd8cceaeb28 100644 --- a/src/coreclr/jit/lower.h +++ b/src/coreclr/jit/lower.h @@ -84,6 +84,7 @@ class Lowering final : public Phase void ContainCheckLclHeap(GenTreeOp* node); void ContainCheckRet(GenTreeUnOp* ret); #if defined(TARGET_ARM64) || defined(TARGET_AMD64) + bool CanConvertOpToCCMP(GenTree* operand, GenTree* tree); bool TryLowerAndOrToCCMP(GenTreeOp* tree, GenTree** next); insCflags TruthifyingFlags(GenCondition cond); void ContainCheckConditionalCompare(GenTreeCCMP* ccmp); diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 7a3d1eeb57e12d..5fd53c25fbb137 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -384,7 +384,7 @@ bool Lowering::IsContainableUnaryOrBinaryOp(GenTree* parentNode, GenTree* childN if (childNode->OperIs(GT_NEG)) { // If we have a contained LSH, RSH or RSZ, we can still contain NEG if the parent is a EQ or NE. - if (childNode->gtGetOp1()->isContained() && !childNode->gtGetOp1()->OperIs(GT_LSH, GT_RSH, GT_RSZ, GT_CAST)) + if (childNode->gtGetOp1()->isContained() && !childNode->gtGetOp1()->OperIs(GT_LSH, GT_RSH, GT_RSZ)) { // Cannot contain if the childs op1 is already contained return false; @@ -403,31 +403,6 @@ bool Lowering::IsContainableUnaryOrBinaryOp(GenTree* parentNode, GenTree* childN { return false; } - - if (childNode->gtGetOp1()->OperIs(GT_CAST)) - { - // Grab the cast as well, we can contain this with cmn (extended-register). - GenTreeCast* cast = childNode->gtGetOp1()->AsCast(); - GenTree* castOp = cast->CastOp(); - - // Cannot contain the cast from floating point. - if (!varTypeIsIntegral(castOp)) - { - return false; - } - - // Cannot contain the cast if it already contains it's CastOp. - if (castOp->isContained()) - { - return false; - } - - assert(!cast->gtOverflow()); - assert(varTypeIsIntegral(cast) && varTypeIsIntegral(cast->CastToType())); - - MakeSrcContained(childNode, cast); - } - return true; } @@ -1984,17 +1959,12 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) if (node->GetOperandCount() == 3) { - assert(node->GetAuxiliaryType() != TYP_UNKNOWN); node->ResetHWIntrinsicId(intrinsicId, comp, node->Op(1), node->Op(2), node->Op(3), lclVar); } - else if (node->GetOperandCount() == 2) - { - node->ResetHWIntrinsicId(intrinsicId, comp, node->Op(1), node->Op(2), lclVar); - } else { - assert(node->GetOperandCount() == 1); - node->ResetHWIntrinsicId(intrinsicId, comp, node->Op(1), lclVar); + assert(node->GetOperandCount() == 2); + node->ResetHWIntrinsicId(intrinsicId, comp, node->Op(1), node->Op(2), lclVar); } } @@ -3892,6 +3862,8 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_AddRotateComplex: case NI_Sve_TrigonometricMultiplyAddCoefficient: case NI_Sve2_ShiftLeftAndInsert: + case NI_Sve2_AddRotateComplex: + case NI_Sve2_AddSaturateRotateComplex: assert(hasImmediateOperand); assert(varTypeIsIntegral(intrin.op3)); if (intrin.op3->IsCnsIntOrI()) @@ -4026,7 +3998,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) { const GenTreeHWIntrinsic* embOp = op2->AsHWIntrinsic(); - if (IsInvariantInRange(op2, node) && op2->isEmbeddedMaskingCompatibleHWIntrinsic()) + if (IsInvariantInRange(op2, node) && op2->isEmbeddedMaskingCompatible()) { bool contain = false; uint32_t maskSize = genTypeSize(node->GetSimdBaseType()); @@ -4096,6 +4068,9 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_FusedMultiplyAddBySelectedScalar: case NI_Sve_FusedMultiplySubtractBySelectedScalar: case NI_Sve_MultiplyAddRotateComplex: + case NI_Sve2_MultiplyAddRotateComplex: + case NI_Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex: + case NI_Sve2_DotProductRotateComplex: assert(hasImmediateOperand); assert(varTypeIsIntegral(intrin.op4)); if (intrin.op4->IsCnsIntOrI()) @@ -4153,6 +4128,9 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) break; case NI_Sve_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar: + case NI_Sve2_DotProductRotateComplexBySelectedIndex: assert(hasImmediateOperand); assert(varTypeIsIntegral(intrin.op4)); assert(varTypeIsIntegral(intrin.op5)); diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 8a1ca074322921..db9c8db0ba9f33 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -3017,8 +3017,8 @@ GenTree* Lowering::LowerHWIntrinsicCmpOp(GenTreeHWIntrinsic* node, genTreeOps cm switch (mskIntrinsic) { case NI_AVX_Compare: - case NI_AVX512_Compare: case NI_AVX_CompareScalar: + case NI_AVX512_CompareMask: { assert(mskIntrin->GetOperandCount() == 3); @@ -5212,7 +5212,7 @@ GenTree* Lowering::LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node) if (indir->OperMayThrow(comp)) { GenTree* addrClone = comp->gtCloneExpr(addr); - GenTree* nullcheck = comp->gtNewNullCheck(addrClone, comp->compCurBB); + GenTree* nullcheck = comp->gtNewNullCheck(addrClone); BlockRange().InsertBefore(indir, addrClone, nullcheck); LowerNode(nullcheck); @@ -7773,7 +7773,7 @@ void Lowering::ContainCheckStoreIndir(GenTreeStoreInd* node) } // If the source is a BSWAP, contain it on supported hardware to generate a MOVBE. - if (comp->opts.OptimizationEnabled()) + if (comp->opts.Tier0OptimizationEnabled()) { if (src->OperIs(GT_BSWAP, GT_BSWAP16) && comp->compOpportunisticallyDependsOn(InstructionSet_AVX2)) { @@ -8370,7 +8370,7 @@ void Lowering::ContainCheckCast(GenTreeCast* node) srcIsContainable = !varTypeIsSmall(srcType) && ((srcType != TYP_ULONG) || comp->canUseEvexEncoding()); } } - else if (comp->opts.OptimizationEnabled() && varTypeIsIntegral(castOp) && varTypeIsIntegral(castToType)) + else if (comp->opts.Tier0OptimizationEnabled() && varTypeIsIntegral(castOp) && varTypeIsIntegral(castToType)) { // Most integral casts can be re-expressed as loads, except those that would be changing the sign. if (!varTypeIsSmall(castOp) || (varTypeIsUnsigned(castOp) == node->IsZeroExtending())) @@ -9255,15 +9255,15 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_AVX_LoadAlignedVector256: case NI_AVX512_LoadAlignedVector512: { - // In minOpts, we need to ensure that an unaligned address will fault when an explicit LoadAligned is used. - // Non-VEX encoded instructions will fault if an unaligned SIMD16 load is contained but will not for scalar - // loads, and VEX-encoded instructions will not fault for unaligned loads in any case. + // For debug code, we need to ensure that an unaligned address will fault when an explicit LoadAligned is + // used. Non-VEX encoded instructions will fault if an unaligned SIMD16 load is contained but will not for + // scalar loads, and VEX-encoded instructions will not fault for unaligned loads in any case. // // When optimizations are enabled, we want to contain any aligned load that is large enough for the parent's // requirement. - return (supportsSIMDLoad && - ((!comp->canUseVexEncoding() && expectedSize == genTypeSize(TYP_SIMD16)) || !comp->opts.MinOpts())); + return (supportsSIMDLoad && (comp->opts.OptimizationEnabled() || + (!comp->canUseVexEncoding() && expectedSize == genTypeSize(TYP_SIMD16)))); } case NI_X86Base_LoadScalarVector128: @@ -9279,7 +9279,7 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_AVX2_BroadcastScalarToVector256: case NI_AVX512_BroadcastScalarToVector512: { - if (comp->opts.MinOpts() || !comp->canUseEmbeddedBroadcast()) + if (!comp->opts.Tier0OptimizationEnabled() || !comp->canUseEmbeddedBroadcast()) { return false; } @@ -9781,14 +9781,16 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) for (GenTree* longOp : op1->Operands()) { - if (!varTypeIsSmall(longOp) && IsContainableMemoryOp(longOp) && - IsSafeToContainMem(node, longOp)) + if (!varTypeIsSmall(longOp)) { - MakeSrcContained(node, longOp); - } - else if (IsSafeToMarkRegOptional(node, longOp)) - { - MakeSrcRegOptional(node, longOp); + if (IsContainableMemoryOp(longOp) && IsSafeToContainMem(node, longOp)) + { + MakeSrcContained(node, longOp); + } + else if (IsSafeToMarkRegOptional(node, longOp)) + { + MakeSrcRegOptional(node, longOp); + } } } @@ -9904,15 +9906,35 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) // because it will prevent other transforms that will be better for codegen. LIR::Use use; - - if ((oper == GT_XOR) && isEmbeddedBroadcastCompatible && BlockRange().TryGetUse(node, &use) && - use.User()->OperIsVectorFusedMultiplyOp()) + if (isEmbeddedBroadcastCompatible && BlockRange().TryGetUse(node, &use)) { - // xor is bitwise and the actual xor node might be a different base type - // from the FMA node, so we check if its negative zero using the FMA base - // type since that's what the end negation would end up using - var_types fmaSimdBaseType = use.User()->AsHWIntrinsic()->GetSimdBaseType(); - isEmbeddedBroadcastCompatible = !containedOperand->IsVectorNegativeZero(fmaSimdBaseType); + if ((oper == GT_XOR) && use.User()->OperIsVectorFusedMultiplyOp()) + { + // xor is bitwise and the actual xor node might be a different base type + // from the FMA node, so we check if its negative zero using the FMA base + // type since that's what the end negation would end up using + var_types fmaSimdBaseType = use.User()->AsHWIntrinsic()->GetSimdBaseType(); + isEmbeddedBroadcastCompatible = + !containedOperand->IsVectorNegativeZero(fmaSimdBaseType); + } + else if (((oper == GT_AND) || (oper == GT_AND_NOT)) && use.User()->OperIsHWIntrinsic()) + { + // For EQ/NE(AND(X, CnsVec), ZeroVector) we don't need to fold CnsVec into a contained + // broadcast operand - AND will be folded into TestZ anyway. + GenTreeHWIntrinsic* userHw = use.User()->AsHWIntrinsic(); + NamedIntrinsic userId = userHw->GetHWIntrinsicId(); + + bool isEQ = (userId == NI_Vector128_op_Equality) || + (userId == NI_Vector256_op_Equality) || + (userId == NI_Vector512_op_Equality); + bool isNE = (userId == NI_Vector128_op_Inequality) || + (userId == NI_Vector256_op_Inequality) || + (userId == NI_Vector512_op_Inequality); + if ((isEQ || isNE) && (userHw->Op(1)->IsVectorZero() || userHw->Op(2)->IsVectorZero())) + { + isEmbeddedBroadcastCompatible = false; + } + } } if (isEmbeddedBroadcastCompatible) @@ -10121,7 +10143,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) MakeSrcContained(node, op2); } - if (IsContainableMemoryOp(op1) && IsSafeToContainMem(node, op1)) + if (op1->IsCnsVec() || (IsContainableMemoryOp(op1) && IsSafeToContainMem(node, op1))) { MakeSrcContained(node, op1); } @@ -10514,222 +10536,18 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) MakeSrcContained(node, op1); } - if (op2->isEmbeddedMaskingCompatibleHWIntrinsic()) + if (IsInvariantInRange(op2, node)) { - bool isEmbeddedMask = !comp->opts.MinOpts() && comp->canUseEmbeddedMasking(); - - if (op2->isRMWHWIntrinsic(comp)) - { - // TODO-AVX512-CQ: Ensure we can support embedded operations on RMW intrinsics - isEmbeddedMask = false; - } - - GenTreeHWIntrinsic* op2Intrinsic = op2->AsHWIntrinsic(); - NamedIntrinsic op2IntrinsicId = NI_Illegal; - HWIntrinsicCategory category = HW_Category_Special; + unsigned tgtMaskSize = simdSize / genTypeSize(simdBaseType); + CorInfoType tgtSimdBaseJitType = CORINFO_TYPE_UNDEF; - if (isEmbeddedMask) + if (op2->isEmbeddedMaskingCompatible(comp, tgtMaskSize, tgtSimdBaseJitType)) { - // TODO-AVX512-CQ: Codegen is currently limited to only handling embedded - // masking for table driven intrinsics. This can be relaxed once that is fixed. - - op2IntrinsicId = op2Intrinsic->GetHWIntrinsicId(); - category = HWIntrinsicInfo::lookupCategory(op2IntrinsicId); - isEmbeddedMask = - HWIntrinsicInfo::genIsTableDrivenHWIntrinsic(op2IntrinsicId, category); - - size_t numArgs = node->GetOperandCount(); - - if (numArgs == 1) - { - if (op2Intrinsic->OperIsMemoryLoad()) - { - isEmbeddedMask = false; - } - } - else if (numArgs == 2) + if (tgtSimdBaseJitType != CORINFO_TYPE_UNDEF) { - if (category == HW_Category_MemoryStore) - { - isEmbeddedMask = false; - } + op2->AsHWIntrinsic()->SetSimdBaseJitType(tgtSimdBaseJitType); } - } - - if (isEmbeddedMask) - { - var_types op2SimdBaseType = op2Intrinsic->GetSimdBaseType(); - - instruction ins = - HWIntrinsicInfo::lookupIns(op2IntrinsicId, op2SimdBaseType, comp); - - unsigned expectedMaskBaseSize = CodeGenInterface::instKMaskBaseSize(ins); - - // It's safe to use the return and base type of the BlendVariableMask node - // since anything which lowered to it will have validated compatibility itself - unsigned actualMaskSize = - genTypeSize(node->TypeGet()) / genTypeSize(simdBaseType); - unsigned actualMaskBaseSize = - actualMaskSize / (genTypeSize(node->TypeGet()) / 16); - CorInfoType op2AdjustedSimdBaseJitType = CORINFO_TYPE_UNDEF; - - if (actualMaskBaseSize != expectedMaskBaseSize) - { - // Some intrinsics are effectively bitwise operations and so we - // can freely update them to match the size of the actual mask - - bool supportsMaskBaseSize4Or8 = false; - - switch (ins) - { - case INS_andpd: - case INS_andps: - case INS_andnpd: - case INS_andnps: - case INS_orpd: - case INS_orps: - case INS_pandd: - case INS_pandnd: - case INS_pord: - case INS_pxord: - case INS_vpandq: - case INS_vpandnq: - case INS_vporq: - case INS_vpxorq: - case INS_vshuff32x4: - case INS_vshuff64x2: - case INS_vshufi32x4: - case INS_vshufi64x2: - case INS_xorpd: - case INS_xorps: - { - // These intrinsics support embedded broadcast and have masking - // support for 4 or 8 - assert((expectedMaskBaseSize == 4) || (expectedMaskBaseSize == 8)); - - if (!comp->codeGen->IsEmbeddedBroadcastEnabled(ins, - op2Intrinsic->Op(2))) - { - // We cannot change the base type if we've already contained a - // broadcast - supportsMaskBaseSize4Or8 = true; - } - break; - } - - case INS_vpternlogd: - case INS_vpternlogq: - { - // These intrinsics support embedded broadcast and have masking - // support for 4 or 8 - assert((expectedMaskBaseSize == 4) || (expectedMaskBaseSize == 8)); - - if (!comp->codeGen->IsEmbeddedBroadcastEnabled(ins, - op2Intrinsic->Op(3))) - { - // We cannot change the base type if we've already contained a - // broadcast - supportsMaskBaseSize4Or8 = true; - } - break; - } - - case INS_vbroadcastf32x4: - case INS_vbroadcastf32x8: - case INS_vbroadcastf64x2: - case INS_vbroadcastf64x4: - case INS_vbroadcasti32x4: - case INS_vbroadcasti32x8: - case INS_vbroadcasti64x2: - case INS_vbroadcasti64x4: - case INS_vextractf32x4: - case INS_vextractf32x8: - case INS_vextractf64x2: - case INS_vextractf64x4: - case INS_vextracti32x4: - case INS_vextracti32x8: - case INS_vextracti64x2: - case INS_vextracti64x4: - case INS_vinsertf32x4: - case INS_vinsertf32x8: - case INS_vinsertf64x2: - case INS_vinsertf64x4: - case INS_vinserti32x4: - case INS_vinserti32x8: - case INS_vinserti64x2: - case INS_vinserti64x4: - { - // These intrinsics don't support embedded broadcast and have - // masking support for 4 or 8 - assert((expectedMaskBaseSize == 4) || (expectedMaskBaseSize == 8)); - supportsMaskBaseSize4Or8 = true; - break; - } - - default: - { - break; - } - } - - if (supportsMaskBaseSize4Or8) - { - if (actualMaskBaseSize == 8) - { - if (varTypeIsFloating(op2SimdBaseType)) - { - op2AdjustedSimdBaseJitType = CORINFO_TYPE_DOUBLE; - } - else if (varTypeIsSigned(op2SimdBaseType)) - { - op2AdjustedSimdBaseJitType = CORINFO_TYPE_LONG; - } - else - { - op2AdjustedSimdBaseJitType = CORINFO_TYPE_ULONG; - } - } - else if (actualMaskBaseSize == 4) - { - if (varTypeIsFloating(op2SimdBaseType)) - { - op2AdjustedSimdBaseJitType = CORINFO_TYPE_FLOAT; - } - else if (varTypeIsSigned(op2SimdBaseType)) - { - op2AdjustedSimdBaseJitType = CORINFO_TYPE_INT; - } - else - { - op2AdjustedSimdBaseJitType = CORINFO_TYPE_UINT; - } - } - } - } - - if (op2AdjustedSimdBaseJitType != CORINFO_TYPE_UNDEF) - { - ins = HWIntrinsicInfo::lookupIns(op2IntrinsicId, op2SimdBaseType, comp); - expectedMaskBaseSize = CodeGenInterface::instKMaskBaseSize(ins); - } - - unsigned expectedMaskSize = - expectedMaskBaseSize * (genTypeSize(op2->TypeGet()) / 16); - assert(expectedMaskSize != 0); - - if (actualMaskSize != expectedMaskSize) - { - isEmbeddedMask = false; - } - else if (op2AdjustedSimdBaseJitType != CORINFO_TYPE_UNDEF) - { - op2Intrinsic->SetSimdBaseJitType(op2AdjustedSimdBaseJitType); - } - } - - if (isEmbeddedMask && IsInvariantInRange(op2, node)) - { MakeSrcContained(node, op2); op2->MakeEmbMaskOp(); break; diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 915019445fe619..9370e2f6501679 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -498,6 +498,35 @@ RegRecord* LinearScan::getRegisterRecord(regNumber regNum) return &physRegs[regNum]; } +//------------------------------------------------------------------------ +// getAvailableGPRsForType: Returns available general-purpose registers for the given type, +// with platform-specific restrictions applied. +// +// Arguments: +// candidates - The candidate register mask to be filtered +// regType - The register type for which we need available registers +// +// Return Value: +// A filtered register mask with platform-specific restrictions applied. +// For AMD64: GC types and long types are restricted to low GPRs only. +// For other platforms: Returns the original candidates unchanged. +// +// Notes: +// On AMD64, we don't use extended GPRs (R16-R31) for GC types to ensure +// proper GC tracking and code generation compatibility. +// +SingleTypeRegSet LinearScan::getAvailableGPRsForType(SingleTypeRegSet candidates, var_types regType) +{ +#ifdef TARGET_AMD64 + if (varTypeIsGC(regType) || varTypeIsLong(regType)) + { + // For AMD64, we don't use eGPR for GC types. + candidates &= (SingleTypeRegSet)RBM_LOWINT.getLow(); + } +#endif // TARGET_AMD64 + return candidates; +} + #ifdef DEBUG //---------------------------------------------------------------------------- @@ -1101,7 +1130,7 @@ void LinearScan::setBlockSequence() { if (!hasUniquePred) { - if (predBlock->NumSucc(compiler) > 1) + if (predBlock->NumSucc() > 1) { blockInfo[block->bbNum].hasCriticalInEdge = true; hasCriticalEdges = true; @@ -1131,14 +1160,14 @@ void LinearScan::setBlockSequence() // First, update the NORMAL successors of the current block, adding them to the worklist // according to the desired order. We will handle the EH successors below. - const unsigned numSuccs = block->NumSucc(compiler); + const unsigned numSuccs = block->NumSucc(); bool checkForCriticalOutEdge = (numSuccs > 1); if (!checkForCriticalOutEdge && block->KindIs(BBJ_SWITCH)) { assert(!"Switch with single successor"); } - for (BasicBlock* const succ : block->Succs(compiler)) + for (BasicBlock* const succ : block->Succs()) { if (checkForCriticalOutEdge && (succ->GetUniquePred(compiler) == nullptr)) { @@ -7636,25 +7665,18 @@ void LinearScan::insertUpperVectorRestore(GenTree* tree, if (tree != nullptr) { LIR::Use treeUse; - GenTree* useNode = nullptr; - bool foundUse = blockRange.TryGetUse(tree, &treeUse); - useNode = treeUse.User(); + bool foundUse; + GenTree* useNode = tree; -#ifdef TARGET_ARM64 - if (refPosition->needsConsecutive && useNode->OperIs(GT_FIELD_LIST)) - { - // The tree node requiring consecutive registers are represented as GT_FIELD_LIST. - // When restoring the upper vector, make sure to restore it at the point where - // GT_FIELD_LIST is consumed instead where the individual field is consumed, which - // will always be at GT_FIELD_LIST creation time. That way, we will restore the - // upper vector just before the use of them in the intrinsic. - LIR::Use fieldListUse; - foundUse = blockRange.TryGetUse(useNode, &fieldListUse); - treeUse = fieldListUse; + // Get the use of the node. If the node is contained then the actual use is the containing node + // (which may be much later in the LIR). Repeatedly check until there is no contained node. + do + { + foundUse = blockRange.TryGetUse(useNode, &treeUse); useNode = treeUse.User(); - } -#endif - assert(foundUse); + assert(foundUse); + } while (useNode->isContained()); + JITDUMP("before %d.%s:\n", useNode->gtTreeID, GenTree::OpName(useNode->gtOper)); // We need to insert the restore prior to the use, not (necessarily) immediately after the lclVar. @@ -8694,6 +8716,9 @@ regNumber LinearScan::getTempRegForResolution(BasicBlock* fromBlock, } #else // !TARGET_ARM SingleTypeRegSet freeRegs = allRegs(type); + // We call getTempRegForResolution() with only either TYP_INT or TYP_FLOAT. + // We are being conservative with eGPR usage when type is TYP_INT since it could be a reference type. + freeRegs = getAvailableGPRsForType(freeRegs, (type == TYP_INT) ? TYP_REF : type); #endif // !TARGET_ARM #ifdef DEBUG @@ -8953,7 +8978,7 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block) // Get the outVarToRegMap for this block VarToRegMap outVarToRegMap = getOutVarToRegMap(block->bbNum); - unsigned succCount = block->NumSucc(compiler); + unsigned succCount = block->NumSucc(); assert(succCount > 1); // First, determine the live regs at the end of this block so that we know what regs are @@ -9096,7 +9121,7 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block) regNumber sameToReg = REG_NA; for (unsigned succIndex = 0; succIndex < succCount; succIndex++) { - BasicBlock* succBlock = block->GetSucc(succIndex, compiler); + BasicBlock* succBlock = block->GetSucc(succIndex); if (!VarSetOps::IsMember(compiler, succBlock->bbLiveIn, outResolutionSetVarIndex)) { maybeSameLivePaths = true; @@ -9215,7 +9240,7 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block) { for (unsigned succIndex = 0; succIndex < succCount; succIndex++) { - BasicBlock* succBlock = block->GetSucc(succIndex, compiler); + BasicBlock* succBlock = block->GetSucc(succIndex); // Any "diffResolutionSet" resolution for a block with no other predecessors will be handled later // as split resolution. @@ -9333,7 +9358,7 @@ void LinearScan::resolveEdges() continue; } - unsigned succCount = block->NumSucc(compiler); + unsigned succCount = block->NumSucc(); BasicBlock* uniquePredBlock = block->GetUniquePred(compiler); // First, if this block has a single predecessor, @@ -9366,7 +9391,7 @@ void LinearScan::resolveEdges() if (succCount == 1) { - BasicBlock* succBlock = block->GetSucc(0, compiler); + BasicBlock* succBlock = block->GetSucc(0); if (succBlock->GetUniquePred(compiler) == nullptr) { VARSET_TP outResolutionSet( @@ -10958,7 +10983,7 @@ void LinearScan::TupleStyleDump(LsraTupleDumpMode mode) continueLoop = false; break; } - block->dspBlockHeader(compiler); + block->dspBlockHeader(); printedBlockHeader = true; printf("=====\n"); break; @@ -10975,7 +11000,7 @@ void LinearScan::TupleStyleDump(LsraTupleDumpMode mode) } else { - block->dspBlockHeader(compiler); + block->dspBlockHeader(); printf("=====\n"); } if (enregisterLocalVars && mode == LSRA_DUMP_POST && block != compiler->fgFirstBB && @@ -13466,7 +13491,7 @@ SingleTypeRegSet LinearScan::RegisterSelection::select(Interval* { preferences = candidates; } - + candidates = linearScan->getAvailableGPRsForType(candidates, regType); #ifdef DEBUG candidates = linearScan->stressLimitRegs(refPosition, regType, candidates); #endif @@ -13934,7 +13959,7 @@ SingleTypeRegSet LinearScan::RegisterSelection::selectMinimal( } } } - + candidates = linearScan->getAvailableGPRsForType(candidates, regType); #ifdef DEBUG candidates = linearScan->stressLimitRegs(refPosition, regType, candidates); #endif diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index e8484bed8e3d6a..7d00e272ed6377 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1142,7 +1142,8 @@ class LinearScan : public LinearScanInterface return getIntervalForLocalVar(varDsc->lvVarIndex); } - RegRecord* getRegisterRecord(regNumber regNum); + RegRecord* getRegisterRecord(regNumber regNum); + SingleTypeRegSet getAvailableGPRsForType(SingleTypeRegSet candidates, var_types regType); RefPosition* newRefPositionRaw(LsraLocation nodeLocation, GenTree* treeNode, RefType refType); diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index 15f658c656e853..d9712b31506bab 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -1710,6 +1710,9 @@ void LinearScan::BuildHWIntrinsicImmediate(GenTreeHWIntrinsic* intrinsicTree, co break; case NI_Sve_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar: + case NI_Sve2_DotProductRotateComplexBySelectedIndex: // This API has two immediates, one of which is used to index pairs of floats in a vector. // For a vector width of 128 bits, this means the index's range is [0, 1], // which means we will skip the above jump table register check, @@ -1734,6 +1737,9 @@ void LinearScan::BuildHWIntrinsicImmediate(GenTreeHWIntrinsic* intrinsicTree, co break; case NI_Sve_MultiplyAddRotateComplex: + case NI_Sve2_MultiplyAddRotateComplex: + case NI_Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex: + case NI_Sve2_DotProductRotateComplex: needBranchTargetReg = !intrin.op4->isContainedIntOrIImmed(); break; @@ -2164,9 +2170,31 @@ SingleTypeRegSet LinearScan::getOperandCandidates(GenTreeHWIntrinsic* intrinsicT case NI_Sve_FusedMultiplyAddBySelectedScalar: case NI_Sve_FusedMultiplySubtractBySelectedScalar: case NI_Sve_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_DotProductRotateComplexBySelectedIndex: + case NI_Sve2_MultiplyAddBySelectedScalar: + case NI_Sve2_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_MultiplyBySelectedScalarWideningEvenAndAdd: + case NI_Sve2_MultiplyBySelectedScalarWideningOddAndAdd: + case NI_Sve2_MultiplySubtractBySelectedScalar: + case NI_Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract: + case NI_Sve2_MultiplyBySelectedScalarWideningOddAndSubtract: + case NI_Sve2_MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven: + case NI_Sve2_MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd: + case NI_Sve2_MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven: + case NI_Sve2_MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd: + case NI_Sve2_MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh: + case NI_Sve2_MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh: + case NI_Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar: isLowVectorOpNum = (opNum == 3); break; case NI_Sve_MultiplyBySelectedScalar: + case NI_Sve2_MultiplyBySelectedScalar: + case NI_Sve2_MultiplyBySelectedScalarWideningEven: + case NI_Sve2_MultiplyBySelectedScalarWideningOdd: + case NI_Sve2_MultiplyDoublingBySelectedScalarSaturateHigh: + case NI_Sve2_MultiplyDoublingWideningSaturateEvenBySelectedScalar: + case NI_Sve2_MultiplyDoublingWideningSaturateOddBySelectedScalar: + case NI_Sve2_MultiplyRoundedDoublingBySelectedScalarSaturateHigh: isLowVectorOpNum = (opNum == 2); break; default: @@ -2176,6 +2204,10 @@ SingleTypeRegSet LinearScan::getOperandCandidates(GenTreeHWIntrinsic* intrinsicT if (isLowVectorOpNum) { unsigned baseElementSize = genTypeSize(intrin.baseType); + if (intrin.id == NI_Sve2_DotProductRotateComplexBySelectedIndex) + { + baseElementSize = intrin.baseType == TYP_BYTE ? 4 : 8; + } if (baseElementSize == 8) { @@ -2183,7 +2215,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/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 92b08b89a946b5..4ee0389a57a470 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -2771,7 +2771,7 @@ void LinearScan::buildIntervals() // If the last block has successors, create a RefTypeBB to record // what's live - if (prevBlock->NumSucc(compiler) > 0) + if (prevBlock->NumSucc() > 0) { RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeBB, nullptr, RBM_NONE); } diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index 8fb7ae7cfb6016..a947e5546e58c3 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -1157,12 +1157,12 @@ int LinearScan::BuildShiftRotate(GenTree* tree) #endif if (!source->isContained()) { - tgtPrefUse = BuildUse(source, srcCandidates); + tgtPrefUse = BuildUse(source, ForceLowGprForApxIfNeeded(source, srcCandidates, getEvexIsSupported())); srcCount++; } else { - srcCount += BuildOperandUses(source, srcCandidates); + srcCount += BuildOperandUses(source, ForceLowGprForApxIfNeeded(source, srcCandidates, getEvexIsSupported())); } if (!tree->isContained()) @@ -1172,6 +1172,9 @@ int LinearScan::BuildShiftRotate(GenTree* tree) srcCount += BuildDelayFreeUses(shiftBy, source, SRBM_RCX); buildKillPositionsForNode(tree, currentLoc + 1, SRBM_RCX); } + dstCandidates = (tree->GetRegNum() == REG_NA) + ? ForceLowGprForApxIfNeeded(tree, dstCandidates, getEvexIsSupported()) + : dstCandidates; BuildDef(tree, dstCandidates); } else @@ -2304,12 +2307,17 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou if (!op2->OperIsConst() && !op1->isContained()) { - // If the index is not a constant or op1 is in register, + // If the index is not a constant and op1 is in register, // we will use the SIMD temp location to store the vector. var_types requiredSimdTempType = Compiler::getSIMDTypeForSize(intrinsicTree->GetSimdSize()); compiler->getSIMDInitTempVarNum(requiredSimdTempType); } + else if (op1->IsCnsVec()) + { + // We need an int reg to load the address of the CnsVec data. + buildInternalIntRegisterDefForNode(intrinsicTree); + } break; } @@ -3275,8 +3283,8 @@ int LinearScan::BuildMul(GenTree* tree) srcCandidates1 = SRBM_RDX; } - srcCount = BuildOperandUses(op1, srcCandidates1); - srcCount += BuildOperandUses(op2, srcCandidates2); + srcCount = BuildOperandUses(op1, ForceLowGprForApxIfNeeded(op1, srcCandidates1, getEvexIsSupported())); + srcCount += BuildOperandUses(op2, ForceLowGprForApxIfNeeded(op2, srcCandidates2, getEvexIsSupported())); #if defined(TARGET_X86) if (tree->OperIs(GT_MUL_LONG)) diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 81e465ce46c1e0..a4f09b64f6213a 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -359,6 +359,22 @@ GenTree* Compiler::fgMorphExpandCast(GenTreeCast* tree) } } } + + // If we have a double->float cast, and the double node is itself a cast, + // look through it and see if we can cast directly to float. This is valid + // only if the cast to double would have been lossless. + // + // This pattern most often appears as CAST(float <- CAST(double <- float)), + // which is reduced to CAST(float <- float) and handled in codegen as an optional mov. + else if ((srcType == TYP_DOUBLE) && (dstType == TYP_FLOAT) && oper->OperIs(GT_CAST) && + !varTypeIsLong(oper->AsCast()->CastOp())) + { + oper->gtType = TYP_FLOAT; + oper->CastToType() = TYP_FLOAT; + + return fgMorphTree(oper); + } + #ifndef TARGET_64BIT // The code generation phase (for x86 & ARM32) does not handle casts // directly from [u]long to anything other than [u]int. Insert an @@ -372,36 +388,6 @@ GenTree* Compiler::fgMorphExpandCast(GenTreeCast* tree) } #endif //! TARGET_64BIT -#if defined(TARGET_ARMARCH) || defined(TARGET_XARCH) - // Because there is no IL instruction conv.r4.un, uint/ulong -> float - // casts are always imported as CAST(float <- CAST(double <- uint/ulong)). - // We can usually eliminate the redundant intermediate cast as an optimization. - // - // AArch and xarch+EVEX have instructions that can cast directly from - // all integers (except for longs on ARM32) to floats. - // On x64, we also have the option of widening uint -> long and - // using the signed conversion instructions, and ulong -> float/double - // is handled directly in codegen, so we can allow all casts. - // - // This logic will also catch CAST(float <- CAST(double <- float)) - // and reduce it to CAST(float <- float), which is handled in codegen as - // an optional mov. - else if ((dstType == TYP_FLOAT) && (srcType == TYP_DOUBLE) && oper->OperIs(GT_CAST) -#ifndef TARGET_64BIT - && !varTypeIsLong(oper->AsCast()->CastOp()) -#endif // !TARGET_64BIT -#ifdef TARGET_X86 - && canUseEvexEncoding() -#endif // TARGET_X86 - ) - { - oper->gtType = TYP_FLOAT; - oper->CastToType() = TYP_FLOAT; - - return fgMorphTree(oper); - } -#endif // TARGET_ARMARCH || TARGET_XARCH - #ifdef TARGET_ARM // converts long/ulong --> float/double casts into helper calls. else if (varTypeIsFloating(dstType) && varTypeIsLong(srcType)) @@ -692,6 +678,8 @@ const char* getWellKnownArgName(WellKnownArg arg) return "StackArrayLocal"; case WellKnownArg::RuntimeMethodHandle: return "RuntimeMethodHandle"; + case WellKnownArg::AsyncSuspendedIndicator: + return "AsyncSuspendedIndicator"; } return "N/A"; @@ -1856,8 +1844,6 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call const CORINFO_CLASS_HANDLE argSigClass = arg.GetSignatureClassHandle(); ClassLayout* argLayout = argSigClass == NO_CLASS_HANDLE ? nullptr : comp->typGetObjLayout(argSigClass); - ABIPassingInformation abiInfo; - // Some well known args have custom register assignment. // These should not affect the placement of any other args or stack space required. // Example: on AMD64 R10 and R11 are used for indirect VSD (generic interface) and cookie calls. @@ -1866,20 +1852,26 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call if (nonStdRegNum == REG_NA) { - abiInfo = classifier.Classify(comp, argSigType, argLayout, arg.GetWellKnownArg()); + if (arg.GetWellKnownArg() == WellKnownArg::AsyncSuspendedIndicator) + { + // Represents definition of a local. Expanded out by async transformation. + arg.AbiInfo = ABIPassingInformation(comp, 0); + } + else + { + arg.AbiInfo = classifier.Classify(comp, argSigType, argLayout, arg.GetWellKnownArg()); + } } else { ABIPassingSegment segment = ABIPassingSegment::InRegister(nonStdRegNum, 0, TARGET_POINTER_SIZE); - abiInfo = ABIPassingInformation::FromSegmentByValue(comp, segment); + arg.AbiInfo = ABIPassingInformation::FromSegmentByValue(comp, segment); } JITDUMP("Argument %u ABI info: ", GetIndex(&arg)); - DBEXEC(VERBOSE, abiInfo.Dump()); - - arg.AbiInfo = abiInfo; + DBEXEC(VERBOSE, arg.AbiInfo.Dump()); - for (const ABIPassingSegment& segment : abiInfo.Segments()) + for (const ABIPassingSegment& segment : arg.AbiInfo.Segments()) { if (segment.IsPassedOnStack()) { @@ -1933,6 +1925,13 @@ void CallArgs::DetermineABIInfo(Compiler* comp, GenTreeCall* call) for (CallArg& arg : Args()) { + if (arg.GetWellKnownArg() == WellKnownArg::AsyncSuspendedIndicator) + { + // Represents definition of a local. Expanded out by async transformation. + arg.AbiInfo = ABIPassingInformation(comp, 0); + continue; + } + const var_types argSigType = arg.GetSignatureType(); const CORINFO_CLASS_HANDLE argSigClass = arg.GetSignatureClassHandle(); ClassLayout* argLayout = argSigClass == NO_CLASS_HANDLE ? nullptr : comp->typGetObjLayout(argSigClass); @@ -2988,8 +2987,11 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) // If we're doing range checking, introduce a GT_BOUNDS_CHECK node for the address. if (indexAddr->IsBoundsChecked()) { - GenTree* arrRef2 = nullptr; // The second copy will be used in array address expression - GenTree* index2 = nullptr; + GenTree* arrRef2 = nullptr; // The second copy will be used in array address expression + GenTree* index2 = nullptr; + auto countNode = [](GenTree* node) -> unsigned { + return 1; + }; // If the arrRef or index expressions involves a store, a call, or reads from global memory, // then we *must* allocate a temporary in which to "localize" those values, to ensure that the @@ -3001,7 +3003,7 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) // TODO-Bug: GLOB_REF is not yet set for all trees in pre-order morph. // if (((arrRef->gtFlags & (GTF_ASG | GTF_CALL | GTF_GLOB_REF)) != 0) || - gtComplexityExceeds(arrRef, MAX_ARR_COMPLEXITY) || arrRef->OperIs(GT_LCL_FLD) || + gtComplexityExceeds(arrRef, MAX_ARR_COMPLEXITY, countNode) || arrRef->OperIs(GT_LCL_FLD) || (arrRef->OperIs(GT_LCL_VAR) && lvaIsLocalImplicitlyAccessedByRef(arrRef->AsLclVar()->GetLclNum()))) { unsigned arrRefTmpNum = lvaGrabTemp(true DEBUGARG("arr expr")); @@ -3016,7 +3018,7 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) } if (((index->gtFlags & (GTF_ASG | GTF_CALL | GTF_GLOB_REF)) != 0) || - gtComplexityExceeds(index, MAX_INDEX_COMPLEXITY) || index->OperIs(GT_LCL_FLD) || + gtComplexityExceeds(index, MAX_INDEX_COMPLEXITY, countNode) || index->OperIs(GT_LCL_FLD) || (index->OperIs(GT_LCL_VAR) && lvaIsLocalImplicitlyAccessedByRef(index->AsLclVar()->GetLclNum()))) { unsigned indexTmpNum = lvaGrabTemp(true DEBUGARG("index expr")); @@ -3043,7 +3045,7 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) } #endif // TARGET_64BIT - GenTree* arrLen = gtNewArrLen(TYP_INT, arrRef, (int)indexAddr->gtLenOffset, compCurBB); + GenTree* arrLen = gtNewArrLen(TYP_INT, arrRef, (int)indexAddr->gtLenOffset); if (bndsChkType != TYP_INT) { @@ -3757,7 +3759,7 @@ GenTree* Compiler::fgMorphExpandInstanceField(GenTree* tree, MorphAddrContext* m } GenTree* lclVar = gtNewLclvNode(lclNum, objRefType); - GenTree* nullchk = gtNewNullCheck(lclVar, compCurBB); + GenTree* nullchk = gtNewNullCheck(lclVar); nullchk->SetHasOrderingSideEffect(); @@ -3785,7 +3787,7 @@ GenTree* Compiler::fgMorphExpandInstanceField(GenTree* tree, MorphAddrContext* m if (tree->AsFieldAddr()->gtFieldLookup.accessType == IAT_PVALUE) { offsetNode = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)tree->AsFieldAddr()->gtFieldLookup.addr, - GTF_ICON_CONST_PTR, true); + GTF_ICON_CONST_PTR); #ifdef DEBUG offsetNode->gtGetOp1()->AsIntCon()->gtTargetHandle = (size_t)fieldHandle; #endif @@ -3907,7 +3909,7 @@ GenTree* Compiler::fgMorphExpandTlsFieldAddr(GenTree* tree) } else { - dllRef = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pIdAddr, GTF_ICON_CONST_PTR, true); + dllRef = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pIdAddr, GTF_ICON_CONST_PTR); // Next we multiply by 4 dllRef = gtNewOperNode(GT_MUL, TYP_I_IMPL, dllRef, gtNewIconNode(4, TYP_I_IMPL)); @@ -5273,7 +5275,7 @@ GenTree* Compiler::fgMorphTailCallViaHelpers(GenTreeCall* call, CORINFO_TAILCALL { // COMMA(tmp = "this", deref(tmp)) GenTree* tmp = gtNewLclvNode(lclNum, objp->TypeGet()); - GenTree* nullcheck = gtNewNullCheck(tmp, compCurBB); + GenTree* nullcheck = gtNewNullCheck(tmp); doBeforeStoreArgsStub = gtNewOperNode(GT_COMMA, TYP_VOID, doBeforeStoreArgsStub, nullcheck); } @@ -5289,7 +5291,7 @@ GenTree* Compiler::fgMorphTailCallViaHelpers(GenTreeCall* call, CORINFO_TAILCALL if (callNeedsNullCheck) { // deref("this") - doBeforeStoreArgsStub = gtNewNullCheck(objp, compCurBB); + doBeforeStoreArgsStub = gtNewNullCheck(objp); if (stubNeedsThisPtr) { @@ -5829,7 +5831,7 @@ void Compiler::fgMorphTailCallViaJitHelper(GenTreeCall* call) // COMMA(tmp = "this", deref(tmp)) GenTree* tmp = gtNewLclvNode(lclNum, vt); - GenTree* nullcheck = gtNewNullCheck(tmp, compCurBB); + GenTree* nullcheck = gtNewNullCheck(tmp); store = gtNewOperNode(GT_COMMA, TYP_VOID, store, nullcheck); // COMMA(COMMA(tmp = "this", deref(tmp)), tmp) @@ -5838,7 +5840,7 @@ void Compiler::fgMorphTailCallViaJitHelper(GenTreeCall* call) else { // thisPtr = COMMA(deref("this"), "this") - GenTree* nullcheck = gtNewNullCheck(thisPtr, compCurBB); + GenTree* nullcheck = gtNewNullCheck(thisPtr); thisPtr = gtNewOperNode(GT_COMMA, vt, nullcheck, gtClone(objp, true)); } @@ -6358,7 +6360,7 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call) assert(call->gtArgs.CountArgs() >= 1); GenTree* objPtr = call->gtArgs.GetArgByIndex(0)->GetNode(); - GenTree* nullCheck = gtNewNullCheck(objPtr, compCurBB); + GenTree* nullCheck = gtNewNullCheck(objPtr); return fgMorphTree(nullCheck); } @@ -6606,8 +6608,7 @@ GenTree* Compiler::fgExpandVirtualVtableCallTarget(GenTreeCall* call) &isRelative); // Dereference the this pointer to obtain the method table, it is called vtab below - assert(VPTR_OFFS == 0); // We have to add this value to the thisPtr to get the methodTable - GenTree* vtab = gtNewIndir(TYP_I_IMPL, thisPtr, GTF_IND_INVARIANT); + GenTree* vtab = gtNewMethodTableLookup(thisPtr); if (fgGlobalMorph) { @@ -6802,14 +6803,14 @@ GenTree* Compiler::fgMorphLeaf(GenTree* tree) switch (addrInfo.accessType) { case IAT_PPVALUE: - indNode = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)addrInfo.handle, GTF_ICON_CONST_PTR, true); + indNode = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)addrInfo.handle, GTF_ICON_CONST_PTR); // Add the second indirection indNode = gtNewIndir(TYP_I_IMPL, indNode, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); break; case IAT_PVALUE: - indNode = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)addrInfo.handle, GTF_ICON_FTN_ADDR, true); + indNode = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)addrInfo.handle, GTF_ICON_FTN_ADDR); INDEBUG(indNode->gtGetOp1()->AsIntCon()->gtTargetHandle = reinterpret_cast(funcHandle)); break; @@ -6838,22 +6839,22 @@ GenTree* Compiler::fgMorphLeaf(GenTree* tree) void Compiler::fgAssignSetVarDef(GenTree* tree) { - GenTreeLclVarCommon* lclVarCmnTree; - bool isEntire = false; - if (tree->DefinesLocal(this, &lclVarCmnTree, &isEntire)) - { - if (isEntire) + auto visitDef = [=](const LocalDef& def) { + if (def.IsEntire) { - lclVarCmnTree->gtFlags |= GTF_VAR_DEF; + def.Def->gtFlags |= GTF_VAR_DEF; } else { // We consider partial definitions to be modeled as uses followed by definitions. // This captures the idea that precedings defs are not necessarily made redundant // by this definition. - lclVarCmnTree->gtFlags |= (GTF_VAR_DEF | GTF_VAR_USEASG); + def.Def->gtFlags |= (GTF_VAR_DEF | GTF_VAR_USEASG); } - } + return GenTree::VisitResult::Continue; + }; + + tree->VisitLocalDefs(this, visitDef); } #ifdef FEATURE_SIMD @@ -8418,12 +8419,14 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA // We're lucky to catch a constant here while importer was not JITDUMP("true\n"); DEBUG_DESTROY_NODE(tree, op1); - tree = gtNewIconNode(1); + tree = gtNewTrue(); } else { JITDUMP("false\n"); - tree = gtWrapWithSideEffects(gtNewIconNode(0), op1, GTF_ALL_EFFECT); + tree = gtNewFalse(); + tree->SetMorphed(this); + tree = gtWrapWithSideEffects(tree, op1, GTF_ALL_EFFECT); } tree->SetMorphed(this); return tree; @@ -9882,8 +9885,9 @@ GenTree* Compiler::fgOptimizeHWIntrinsic(GenTreeHWIntrinsic* node) const bool reverseCond = true; var_types lookupType = - GenTreeHWIntrinsic::GetLookupTypeForCmpOp(this, op1Oper, op1RetType, op1SimdBaseType, op1SimdSize, - reverseCond); + op1IsScalar ? op1RetType + : GenTreeHWIntrinsic::GetLookupTypeForCmpOp(this, op1Oper, op1RetType, op1SimdBaseType, + op1SimdSize, reverseCond); NamedIntrinsic newId = GenTreeHWIntrinsic::GetHWIntrinsicIdForCmpOp(this, op1Oper, lookupType, cmpOp1, cmpOp2, op1SimdBaseType, op1SimdSize, op1IsScalar, @@ -9920,8 +9924,8 @@ GenTree* Compiler::fgOptimizeHWIntrinsic(GenTreeHWIntrinsic* node) switch (op1Intrinsic) { case NI_AVX_Compare: - case NI_AVX512_Compare: case NI_AVX_CompareScalar: + case NI_AVX512_CompareMask: { assert(op1Intrin->GetOperandCount() == 3); @@ -11292,6 +11296,43 @@ GenTree* Compiler::fgMorphHWIntrinsic(GenTreeHWIntrinsic* tree) // Perform the required oper-specific postorder morphing // + // If the folded tree is a vector to mask conversion, or vice versa, + // then we want to morph the inner operand as we may have folded something + // like xor(masktovector(op1), AllBitsSet) into masktovector(not(op1)), which + // can unlock further optimizations over op1, like the ability to invert + // not(cmple(op1, op2)) into cmpgt(op1, op2) + + int opIndex = 0; + + if (tree->OperIsConvertVectorToMask() || tree->OperIsConvertMaskToVector()) + { + opIndex = 1; + } + +#if defined(TARGET_ARM64) + if (tree->OperIsConvertVectorToMask()) + { + opIndex = 2; + } +#endif // TARGET_ARM64 + + if (opIndex != 0) + { + GenTree* innerOp = tree->Op(opIndex); + + if (innerOp->OperIsHWIntrinsic()) + { + innerOp = fgMorphHWIntrinsicRequired(innerOp->AsHWIntrinsic()); + + if (innerOp->OperIsHWIntrinsic()) + { + innerOp = fgMorphHWIntrinsicOptional(innerOp->AsHWIntrinsic()); + } + + tree->Op(opIndex) = innerOp; + } + } + morphedTree = fgMorphHWIntrinsicRequired(tree); if (morphedTree->OperIsHWIntrinsic()) @@ -11334,12 +11375,105 @@ GenTree* Compiler::fgMorphHWIntrinsicRequired(GenTreeHWIntrinsic* tree) if (tree->isCommutativeHWIntrinsic()) { assert(tree->GetOperandCount() == 2); + GenTree*& op1 = tree->Op(1); + GenTree*& op2 = tree->Op(2); if (op1->OperIsConst()) { // Move constants from op1 to op2 for commutative operations - std::swap(op1, tree->Op(2)); + std::swap(op1, op2); + } + + if (((oper == GT_EQ) || (oper == GT_NE)) && op1->OperIsHWIntrinsic() && op2->IsCnsVec()) + { + GenTreeHWIntrinsic* op1Intrinsic = op1->AsHWIntrinsic(); + NamedIntrinsic op1IntrinsicId = op1Intrinsic->GetHWIntrinsicId(); + var_types op1Type = op1Intrinsic->TypeGet(); + + if (HWIntrinsicInfo::ReturnsPerElementMask(op1IntrinsicId) && + (genTypeSize(simdBaseType) == genTypeSize(op1Intrinsic->GetSimdBaseType()))) + { + // This optimization is only safe if we know the other node produces + // AllBitsSet or Zero per element and if the outer comparison is the + // same size as what the other node produces for its mask + + bool reverseCond = false; + + if (oper == GT_EQ) + { + // Handle `Mask == Zero` and `Zero == Mask` for integral types + if (op2->IsVectorZero()) + { + reverseCond = true; + } + } + else if (oper == GT_NE) + { + // Handle `Mask != AllBitsSet` and `AllBitsSet != Mask` for integral types + if (op2->IsVectorAllBitsSet()) + { + reverseCond = true; + } + } + + if (reverseCond) + { + GenTree* newNode = nullptr; + + if (op1Intrinsic->OperIsConvertVectorToMask()) + { +#if defined(TARGET_XARCH) + op1 = op1Intrinsic->Op(1); +#elif defined(TARGET_ARM64) + op1 = op1Intrinsic->Op(2); + DEBUG_DESTROY_NODE(op1Intrinsic->Op(1)); +#else +#error Unsupported platform +#endif // !TARGET_XARCH && !TARGET_ARM64 + + op1Type = op1->TypeGet(); + DEBUG_DESTROY_NODE(op1Intrinsic); + } + + if (op1Type == TYP_MASK) + { +#if defined(TARGET_XARCH) + newNode = gtNewSimdHWIntrinsicNode(op1Type, op1, NI_AVX512_NotMask, simdBaseJitType, simdSize); +#endif // TARGET_XARCH + } + else + { + newNode = gtNewSimdUnOpNode(GT_NOT, op1Type, op1, simdBaseJitType, simdSize); + +#if defined(TARGET_XARCH) + newNode->AsHWIntrinsic()->Op(2)->SetMorphed(this); +#endif // TARGET_XARCH + } + + if (newNode != nullptr) + { + DEBUG_DESTROY_NODE(op2); + DEBUG_DESTROY_NODE(tree); + + if (op1Type != retType) + { + newNode = fgMorphHWIntrinsicRequired(newNode->AsHWIntrinsic()); + + if (retType == TYP_MASK) + { + newNode = gtNewSimdCvtVectorToMaskNode(retType, newNode, simdBaseJitType, simdSize); + } + else + { + newNode = gtNewSimdCvtMaskToVectorNode(retType, newNode, simdBaseJitType, simdSize); + } + } + + return fgMorphHWIntrinsicRequired(newNode->AsHWIntrinsic()); + } + } + } } } else if (GenTree::OperIsCompare(oper)) @@ -11384,7 +11518,7 @@ GenTree* Compiler::fgMorphHWIntrinsicRequired(GenTreeHWIntrinsic* tree) switch (intrinsic) { case NI_AVX_Compare: - case NI_AVX512_Compare: + case NI_AVX512_CompareMask: { assert(tree->GetOperandCount() == 3); @@ -11397,20 +11531,15 @@ GenTree* Compiler::fgMorphHWIntrinsicRequired(GenTreeHWIntrinsic* tree) break; } - FloatComparisonMode mode = static_cast(op3->AsIntConCommon()->IntegralValue()); - + FloatComparisonMode mode = static_cast(op3->AsIntConCommon()->IntegralValue()); FloatComparisonMode newMode = mode; switch (mode) { case FloatComparisonMode::UnorderedEqualNonSignaling: - case FloatComparisonMode::OrderedFalseNonSignaling: case FloatComparisonMode::OrderedNotEqualNonSignaling: - case FloatComparisonMode::UnorderedTrueNonSignaling: case FloatComparisonMode::UnorderedEqualSignaling: - case FloatComparisonMode::OrderedFalseSignaling: case FloatComparisonMode::OrderedNotEqualSignaling: - case FloatComparisonMode::UnorderedTrueSignaling: { tree->Op(1) = op2; tree->Op(2) = op1; @@ -12648,10 +12777,14 @@ void Compiler::fgMorphTreeDone(GenTree* tree, bool optAssertionPropDone DEBUGARG // Kill active assertions // - GenTreeLclVarCommon* lclVarTree = nullptr; - if ((optAssertionCount > 0) && tree->DefinesLocal(this, &lclVarTree)) + if (optAssertionCount > 0) { - fgKillDependentAssertions(lclVarTree->GetLclNum() DEBUGARG(tree)); + auto visitDef = [=](GenTreeLclVarCommon* lcl) { + fgKillDependentAssertions(lcl->GetLclNum() DEBUGARG(tree)); + return GenTree::VisitResult::Continue; + }; + + tree->VisitLocalDefNodes(this, visitDef); } // Generate assertions @@ -12752,15 +12885,10 @@ Compiler::FoldResult Compiler::fgFoldConditional(BasicBlock* block) block->SetKindAndTargetEdge(BBJ_ALWAYS, retainedEdge); fgRepairProfileCondToUncond(block, retainedEdge, removedEdge); -#ifdef DEBUG - if (verbose) - { - printf("\nConditional 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("\nConditional 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"); } } else if (block->KindIs(BBJ_SWITCH)) @@ -12818,8 +12946,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; @@ -15433,13 +15561,13 @@ bool Compiler::fgMorphArrayOpsStmt(MorphMDArrayTempCache* pTempCache, BasicBlock assert((idx->gtFlags & GTF_ALL_EFFECT) == 0); // We should have taken care of side effects earlier. GenTreeMDArr* const mdArrLowerBound = - m_compiler->gtNewMDArrLowerBound(m_compiler->gtNewLclvNode(arrLcl, TYP_REF), i, rank, m_block); + m_compiler->gtNewMDArrLowerBound(m_compiler->gtNewLclvNode(arrLcl, TYP_REF), i, rank); // unsigned effIdxLcl = m_compiler->lvaGrabTemp(true DEBUGARG("MD array effective index")); unsigned effIdxLcl = m_pTempCache->GrabTemp(TYP_INT); GenTree* const effIndex = m_compiler->gtNewOperNode(GT_SUB, TYP_INT, idx, mdArrLowerBound); GenTree* const effIdxLclDef = m_compiler->gtNewTempStore(effIdxLcl, effIndex); GenTreeMDArr* const mdArrLength = - m_compiler->gtNewMDArrLen(m_compiler->gtNewLclvNode(arrLcl, TYP_REF), i, rank, m_block); + m_compiler->gtNewMDArrLen(m_compiler->gtNewLclvNode(arrLcl, TYP_REF), i, rank); GenTreeBoundsChk* const arrBndsChk = new (m_compiler, GT_BOUNDS_CHECK) GenTreeBoundsChk(m_compiler->gtNewLclvNode(effIdxLcl, TYP_INT), mdArrLength, SCK_RNGCHK_FAIL); GenTree* const boundsCheckComma = @@ -15453,7 +15581,7 @@ bool Compiler::fgMorphArrayOpsStmt(MorphMDArrayTempCache* pTempCache, BasicBlock assert(fullTree != nullptr); GenTreeMDArr* const mdArrLengthScale = - m_compiler->gtNewMDArrLen(m_compiler->gtNewLclvNode(arrLcl, TYP_REF), i, rank, m_block); + m_compiler->gtNewMDArrLen(m_compiler->gtNewLclvNode(arrLcl, TYP_REF), i, rank); GenTree* const scale = m_compiler->gtNewOperNode(GT_MUL, TYP_INT, fullTree, mdArrLengthScale); GenTree* const effIndex = m_compiler->gtNewOperNode(GT_ADD, TYP_INT, scale, idxComma); diff --git a/src/coreclr/jit/morphblock.cpp b/src/coreclr/jit/morphblock.cpp index ac234686a63614..452983ffc50597 100644 --- a/src/coreclr/jit/morphblock.cpp +++ b/src/coreclr/jit/morphblock.cpp @@ -1164,6 +1164,32 @@ GenTree* MorphCopyBlockHelper::CopyFieldByField() addrSpillStore->SetMorphed(m_comp); } + auto postOrderAssertionProp = [=](GenTree* tree) { + if (m_comp->fgGlobalMorph && m_comp->optLocalAssertionProp && (m_comp->optAssertionCount > 0)) + { + GenTree* optimizedTree = tree; + bool again = JitConfig.JitEnablePostorderLocalAssertionProp() > 0; + bool didOptimize = false; + + while (again) + { + tree = optimizedTree; + optimizedTree = m_comp->optAssertionProp(m_comp->apLocalPostorder, tree, nullptr, nullptr); + again = (optimizedTree != nullptr); + didOptimize |= again; + } + + assert(tree != nullptr); + + if (didOptimize) + { + m_comp->gtUpdateNodeSideEffects(tree); + } + } + + return tree; + }; + auto grabAddr = [=, &result](unsigned offs) { GenTree* addrClone = nullptr; // Need address of the source. @@ -1316,6 +1342,8 @@ GenTree* MorphCopyBlockHelper::CopyFieldByField() } } assert(srcFld != nullptr); + + srcFld = postOrderAssertionProp(srcFld); srcFld->SetMorphed(m_comp); GenTree* dstFldStore; @@ -1372,7 +1400,16 @@ GenTree* MorphCopyBlockHelper::CopyFieldByField() } } } - noway_assert(dstFldStore->TypeGet() == srcFld->TypeGet()); + + // Allow mismatched types only when srcFld is an integer constant + // + if (dstFldStore->TypeGet() != srcFld->TypeGet()) + { + noway_assert(genActualType(dstFldStore->TypeGet()) == genActualType(srcFld->TypeGet())); + assert(srcFld->IsIntegralConst()); + } + + dstFldStore = postOrderAssertionProp(dstFldStore); dstFldStore->SetMorphed(m_comp); if (m_comp->optLocalAssertionProp) diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index 71a7124e0974ac..aa56003f25acc1 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -221,7 +221,9 @@ enum NamedIntrinsic : unsigned short NI_SRCS_UNSAFE_InitBlock, NI_SRCS_UNSAFE_InitBlockUnaligned, NI_SRCS_UNSAFE_IsAddressGreaterThan, + NI_SRCS_UNSAFE_IsAddressGreaterThanOrEqualTo, NI_SRCS_UNSAFE_IsAddressLessThan, + NI_SRCS_UNSAFE_IsAddressLessThanOrEqualTo, NI_SRCS_UNSAFE_IsNullRef, NI_SRCS_UNSAFE_NullRef, NI_SRCS_UNSAFE_Read, diff --git a/src/coreclr/jit/objectalloc.cpp b/src/coreclr/jit/objectalloc.cpp index 0b5a62f3400a36..99fe06b8dd427a 100644 --- a/src/coreclr/jit/objectalloc.cpp +++ b/src/coreclr/jit/objectalloc.cpp @@ -1324,7 +1324,8 @@ void ObjectAllocator::MorphAllocObjNode(AllocationCandidate& candidate) else { assert(candidate.m_onHeapReason != nullptr); - JITDUMP("Allocating V%02u on the heap: %s\n", lclNum, candidate.m_onHeapReason); + JITDUMP("Allocating V%02u / [%06u] on the heap: %s\n", lclNum, comp->dspTreeID(candidate.m_tree), + candidate.m_onHeapReason); if ((candidate.m_allocType == OAT_NEWOBJ) || (candidate.m_allocType == OAT_NEWOBJ_HEAP)) { GenTree* const stmtExpr = candidate.m_tree; @@ -1367,6 +1368,58 @@ bool ObjectAllocator::MorphAllocObjNodeHelper(AllocationCandidate& candidate) return false; } + // If we have done any cloning for conditional escape, verify this allocation + // is not on one of the "slow paths" that are now forcibly making interface calls. + // + for (CloneInfo* const c : CloneMap::ValueIteration(&m_CloneMap)) + { + if (!c->m_willClone) + { + // We didn't clone so there is no check needed. + // + continue; + } + + if (c->m_guardBlock == nullptr) + { + // This clone wasn't guarded by a GDV, so we should + // only have a fast path. + continue; + } + + GenTree* const allocTree = candidate.m_tree->AsLclVar()->Data(); + + if (c->m_allocTree == allocTree) + { + // This is the conditionally escaping allocation, so it's + // on the fast path. + // + continue; + } + + if (!comp->m_dfsTree->Contains(candidate.m_block)) + { + // If the def block is not in the DFS tree then the allocation + // is not within the hammock, so it is not on the slow path. + // + continue; + } + + // This allocation candidate might be on the "slow path". Check. + // + // c->m_guardBlock and c->m_defBlock form a GDV hammock. + // + // So if an allocation site is dominated by c->m_guardBlock and + // not dominated by c->m_defBlock, it is within the hammock. + // + if (comp->m_domTree->Dominates(c->m_guardBlock, candidate.m_block) && + !comp->m_domTree->Dominates(c->m_defBlock, candidate.m_block)) + { + candidate.m_onHeapReason = "[on slow path of conditional escape clone]"; + return false; + } + } + switch (candidate.m_allocType) { case OAT_NEWARR: @@ -2374,11 +2427,30 @@ void ObjectAllocator::UpdateAncestorTypes( { assert(tree == parent->AsIndir()->Data()); - // If we are storing to a GC struct field, we may need to retype the store - // if (varTypeIsGC(parent->TypeGet())) { - parent->ChangeType(newType); + // We are storing a non-struct value, possibly to a struct field. + // + // See if we can figure out the field type from the address. + // It might be TYP_BYREF even if the value we are storing is TYP_I_IMPL. + // + StoreInfo* const info = m_StoreAddressToIndexMap.LookupPointer(parent); + bool wasRetyped = false; + + if (info != nullptr) + { + unsigned const addressIndex = info->m_index; + if ((addressIndex != BAD_VAR_NUM) && !DoesIndexPointToStack(addressIndex)) + { + parent->ChangeType(TYP_BYREF); + wasRetyped = true; + } + } + + if (!wasRetyped) + { + parent->ChangeType(newType); + } } else if (retypeFields && parent->OperIs(GT_STORE_BLK)) { @@ -3613,22 +3685,24 @@ bool ObjectAllocator::ShouldClone(CloneInfo* info) unsigned const sizeLimit = (sizeConfig >= 0) ? (unsigned)sizeConfig : UINT_MAX; unsigned size = 0; bool shouldClone = true; + auto countNode = [&size](GenTree* tree) -> unsigned { + size++; + return 1; + }; for (BasicBlock* const block : *info->m_blocksToClone) { // Note this overstates the size a bit since we'll resolve GDVs // in the clone and the original... // - unsigned const slack = sizeLimit - size; - unsigned blockSize = 0; - if (block->ComplexityExceeds(comp, slack, &blockSize)) + unsigned const slack = sizeLimit - size; + if (block->ComplexityExceeds(comp, slack, countNode)) { JITDUMP("Rejecting"); JITDUMPEXEC(DumpIndex(info->m_pseudoIndex)); JITDUMP(" cloning: exceeds size limit %u\n", sizeLimit); return false; } - size += blockSize; } // TODO: some kind of profile check... @@ -3770,6 +3844,8 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info) JITDUMP("V%02u has single def in " FMT_BB " at [%06u]\n", info->m_local, defBlock->bbNum, comp->dspTreeID(defStmt->GetRootNode())); + info->m_defBlock = defBlock; + // We expect to be able to follow all paths from alloc block to defBlock // without reaching "beyond" defBlock. // @@ -3859,6 +3935,35 @@ bool ObjectAllocator::CheckCanClone(CloneInfo* info) JITDUMP("Unexpected, alloc site " FMT_BB " dominates def block " FMT_BB ". We will clone anyways.\n", allocBlock->bbNum, defBlock->bbNum); } + else + { + // The allocation is conditional. See if we can find the GDV guard + // so we can check what other possible stack allocations might reach + // the def block. + // + BasicBlock* possibleGuardBlock = defBlock->bbIDom; + GuardInfo gi; + if (IsGuard(possibleGuardBlock, &gi)) + { + // Todo: validate guard is the right guard. + // + JITDUMP("Conditional allocation is guarded by a GDV\n"); + info->m_guardBlock = possibleGuardBlock; + } + else + { + // The allocation is conditional but the enumerator var def is + // not dominated by a GDV. Perhaps we resolved the GDV already. + // + // We want to allow cloning to proceed in this case as alternative + // enumerators might be non-allocating (say the static empty array + // enumerator). + // + // But consider adding more checking in this case. + // + JITDUMP("Conditional allocation is not guarded by a GDV\n"); + } + } // Classify the other local appearances // as Ts (allocTemps) or Us (useTemps), and look for guard appearances. diff --git a/src/coreclr/jit/objectalloc.h b/src/coreclr/jit/objectalloc.h index 6019c8a7c45c78..5c7a4b92ce2e41 100644 --- a/src/coreclr/jit/objectalloc.h +++ b/src/coreclr/jit/objectalloc.h @@ -89,6 +89,12 @@ struct CloneInfo : public GuardInfo unsigned m_appearanceCount = 0; jitstd::vector* m_allocTemps = nullptr; + // The initial GDV guard block, if any. + BasicBlock* m_guardBlock = nullptr; + + // The block where the enumerator var is assigned. + BasicBlock* m_defBlock = nullptr; + // Where the enumerator allocation happens GenTree* m_allocTree = nullptr; Statement* m_allocStmt = nullptr; diff --git a/src/coreclr/jit/optimizebools.cpp b/src/coreclr/jit/optimizebools.cpp index c390887b8fbe25..bcc797f1e1909c 100644 --- a/src/coreclr/jit/optimizebools.cpp +++ b/src/coreclr/jit/optimizebools.cpp @@ -1576,11 +1576,13 @@ PhaseStatus Compiler::optOptimizeBools() printf("*************** In optOptimizeBools()\n"); } #endif - bool change = false; - bool retry = false; - unsigned numCond = 0; - unsigned numPasses = 0; - unsigned stress = false; + bool change = false; + bool retry = false; + unsigned numCond = 0; + unsigned numPasses = 0; + unsigned stress = false; + BitVecTraits ccmpTraits(fgBBNumMax + 1, this); + BitVec ccmpVec = BitVecOps::MakeEmpty(&ccmpTraits); do { @@ -1656,7 +1658,7 @@ PhaseStatus Compiler::optOptimizeBools() // trigger or not // else if ((compOpportunisticallyDependsOn(InstructionSet_APX) || JitConfig.JitEnableApxIfConv()) && // optBoolsDsc.optOptimizeCompareChainCondBlock()) - else if (JitConfig.EnableApxConditionalChaining() && !optSwitchDetectAndConvert(b1, true) && + else if (JitConfig.EnableApxConditionalChaining() && !optSwitchDetectAndConvert(b1, true, &ccmpVec) && optBoolsDsc.optOptimizeCompareChainCondBlock()) { // The optimization will have merged b1 and b2. Retry the loop so that diff --git a/src/coreclr/jit/optimizemaskconversions.cpp b/src/coreclr/jit/optimizemaskconversions.cpp index b328e884637e79..7396469770acae 100644 --- a/src/coreclr/jit/optimizemaskconversions.cpp +++ b/src/coreclr/jit/optimizemaskconversions.cpp @@ -175,37 +175,11 @@ class MaskConversionsCheckVisitor final : public GenTreeVisitorOperIsHWIntrinsic()) + if ((user != nullptr) && user->OperIsConvertVectorToMask()) { - GenTreeHWIntrinsic* hwintrin = user->AsHWIntrinsic(); - NamedIntrinsic ni = hwintrin->GetHWIntrinsicId(); - - if (hwintrin->OperIsConvertVectorToMask()) - { - convertOp = user->AsHWIntrinsic(); - hasConversion = true; - } - else if (hwintrin->OperIsVectorConditionalSelect()) - { - // We don't actually have a convert here, but we do have a case where - // the mask is being used in a ConditionalSelect and therefore can be - // consumed directly as a mask. While the IR shows TYP_SIMD, it gets - // handled in lowering as part of the general embedded-mask support. - - // We notably don't check that op2 supported embedded masking directly - // because we can still consume the mask directly in such cases. We'll just - // emit `vblendmps zmm1 {k1}, zmm2, zmm3` instead of containing the CndSel - // as part of something like `vaddps zmm1 {k1}, zmm2, zmm3` - - if (hwintrin->Op(1) == lclOp) - { - convertOp = user->AsHWIntrinsic(); - hasConversion = true; - } - } + convertOp = user->AsHWIntrinsic(); + hasConversion = true; } break; } @@ -402,7 +376,6 @@ class MaskConversionsUpdateVisitor final : public GenTreeVisitorData() = lclOp->Data()->AsHWIntrinsic()->Op(1); } - else if (isLocalStore && addConversion) { // Convert @@ -416,7 +389,6 @@ class MaskConversionsUpdateVisitor final : public GenTreeVisitorData() = m_compiler->gtNewSimdCvtVectorToMaskNode(TYP_MASK, lclOp->Data(), weight->simdBaseJitType, weight->simdSize); } - else if (isLocalUse && removeConversion) { // Convert @@ -426,7 +398,6 @@ class MaskConversionsUpdateVisitor final : public GenTreeVisitorGetEhfTargets(); - 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); @@ -1899,86 +1901,95 @@ bool Compiler::optTryInvertWhileLoop(FlowGraphNaturalLoop* loop) JITDUMP("Condition in block " FMT_BB " of loop " FMT_LP " is a candidate for duplication to invert the loop\n", condBlock->bbNum, loop->GetIndex()); - // Check if loop is small enough to consider for inversion. - // Large loops are less likely to benefit from inversion. - const int sizeLimit = JitConfig.JitLoopInversionSizeLimit(); - if ((sizeLimit >= 0) && optLoopComplexityExceeds(loop, (unsigned)sizeLimit)) - { - return false; - } - - unsigned estDupCostSz = 0; + weight_t loopIterations = BB_LOOP_WEIGHT_SCALE; + const bool haveProfileWeights = fgIsUsingProfileWeights(); + const weight_t weightPreheader = preheader->bbWeight; + const weight_t weightCond = condBlock->bbWeight; + const weight_t weightStayInLoopSucc = stayInLoopSucc->bbWeight; - for (int i = 0; i < duplicatedBlocks.Height(); i++) + // If we have profile data then we calculate the number of times + // the loop will iterate into loopIterations + if (haveProfileWeights) { - BasicBlock* block = duplicatedBlocks.Bottom(i); - for (Statement* stmt : block->Statements()) + assert(preheader->hasProfileWeight()); + assert(condBlock->hasProfileWeight()); + assert(stayInLoopSucc->hasProfileWeight()); + + // If this while loop never iterates then don't bother transforming + // + if (weightStayInLoopSucc == BB_ZERO_WEIGHT) { - GenTree* tree = stmt->GetRootNode(); - gtPrepareCost(tree); - estDupCostSz += tree->GetCostSz(); + JITDUMP("No loop-inversion for " FMT_LP " since the in-loop successor " FMT_BB " has 0 weight\n", + loop->GetIndex(), preheader->bbNum); + return false; } + + // Determine average iteration count + // + // weightTop is the number of time this loop executes + // weightTest is the number of times that we consider entering or remaining in the loop + // loopIterations is the average number of times that this loop iterates + // + // If profile is inaccurate, use other data to provide a credible estimate. + // The value should at least be >= weightPreheader. + // + const weight_t loopEntries = max(weightPreheader, weightCond - weightStayInLoopSucc); + loopIterations = weightStayInLoopSucc / loopEntries; } - weight_t loopIterations = BB_LOOP_WEIGHT_SCALE; - bool haveProfileWeights = false; - weight_t const weightPreheader = preheader->bbWeight; - weight_t const weightCond = condBlock->bbWeight; - weight_t const weightStayInLoopSucc = stayInLoopSucc->bbWeight; + // Check if loop is small enough to consider for inversion. + // Large loops are less likely to benefit from inversion. + const int invertSizeLimit = JitConfig.JitLoopInversionSizeLimit(); + if (invertSizeLimit >= 0) + { + const int cloneSizeLimit = JitConfig.JitCloneLoopsSizeLimit(); + bool mightBenefitFromCloning = false; + unsigned loopSize = 0; + + // Loops with bounds checks can benefit from cloning, which depends on inversion running. + // Thus, we will try to proceed with inversion for slightly oversize loops if they show potential for cloning. + auto countNode = [&mightBenefitFromCloning, &loopSize](GenTree* tree) -> unsigned { + mightBenefitFromCloning |= tree->OperIs(GT_BOUNDS_CHECK); + loopSize++; + return 1; + }; - // If we have profile data then we calculate the number of times - // the loop will iterate into loopIterations - if (fgIsUsingProfileWeights()) - { - // Only rely upon the profile weight when all three of these blocks - // have good profile weights - if (preheader->hasProfileWeight() && condBlock->hasProfileWeight() && stayInLoopSucc->hasProfileWeight()) + optLoopComplexityExceeds(loop, (unsigned)max(invertSizeLimit, cloneSizeLimit), countNode); + if (loopSize > (unsigned)invertSizeLimit) { - // If this while loop never iterates then don't bother transforming - // - if (weightStayInLoopSucc == BB_ZERO_WEIGHT) + // Don't try to invert oversize loops if they don't show cloning potential, + // or if they're too big to be cloned anyway. + JITDUMP(FMT_LP " exceeds inversion size limit of %d\n", loop->GetIndex(), invertSizeLimit); + const bool tooBigToClone = (cloneSizeLimit >= 0) && (loopSize > (unsigned)cloneSizeLimit); + if (!mightBenefitFromCloning || tooBigToClone) { - JITDUMP("No loop-inversion for " FMT_LP " since the in-loop successor " FMT_BB " has 0 weight\n", - loop->GetIndex(), preheader->bbNum); + JITDUMP("No inversion for " FMT_LP ": %s\n", loop->GetIndex(), + tooBigToClone ? "too big to clone" : "unlikely to benefit from cloning"); return false; } - haveProfileWeights = true; - - // We generally expect weightCond > weightStayInLoopSucc - // - // Tolerate small inconsistencies... - // - if (!fgProfileWeightsConsistent(weightPreheader + weightStayInLoopSucc, weightCond)) + // If the loop shows cloning potential, tolerate some excess size. + const unsigned liberalInvertSizeLimit = (unsigned)(invertSizeLimit * 1.25); + if (loopSize > liberalInvertSizeLimit) { - JITDUMP("Profile weights locally inconsistent: preheader " FMT_WT ", stayInLoopSucc " FMT_WT - ", cond " FMT_WT "\n", - weightPreheader, weightStayInLoopSucc, weightCond); + JITDUMP(FMT_LP " might benefit from cloning, but is too large to invert.\n", loop->GetIndex()); + return false; } - else - { - // Determine average iteration count - // - // weightTop is the number of time this loop executes - // weightTest is the number of times that we consider entering or remaining in the loop - // loopIterations is the average number of times that this loop iterates - // - weight_t loopEntries = weightCond - weightStayInLoopSucc; - // If profile is inaccurate, try and use other data to provide a credible estimate. - // The value should at least be >= weightBlock. - // - if (loopEntries < weightPreheader) - { - loopEntries = weightPreheader; - } - - loopIterations = weightStayInLoopSucc / loopEntries; - } + JITDUMP(FMT_LP " might benefit from cloning. Continuing.\n", loop->GetIndex()); } - else + } + + unsigned estDupCostSz = 0; + + for (int i = 0; i < duplicatedBlocks.Height(); i++) + { + BasicBlock* block = duplicatedBlocks.Bottom(i); + for (Statement* stmt : block->Statements()) { - JITDUMP("Missing profile data for loop!\n"); + GenTree* tree = stmt->GetRootNode(); + gtPrepareCost(tree); + estDupCostSz += tree->GetCostSz(); } } @@ -2341,7 +2352,6 @@ void Compiler::optResetLoopInfo() if (!block->hasProfileWeight()) { block->bbWeight = BB_UNITY_WEIGHT; - block->RemoveFlags(BBF_RUN_RARELY); } } } @@ -2862,47 +2872,6 @@ bool Compiler::optCanonicalizeExit(FlowGraphNaturalLoop* loop, BasicBlock* exit) return true; } -//------------------------------------------------------------------------ -// optLoopComplexityExceeds: Check if the number of nodes in the loop exceeds some limit -// -// Arguments: -// loop - the loop to compute the number of nodes in -// limit - limit on the number of nodes -// -// Returns: -// true if the number of nodes exceeds the limit -// -bool Compiler::optLoopComplexityExceeds(FlowGraphNaturalLoop* loop, unsigned limit) -{ - assert(loop != nullptr); - - // See if loop size exceeds the limit. - // - unsigned size = 0; - - BasicBlockVisit const result = loop->VisitLoopBlocks([this, limit, &size](BasicBlock* block) { - assert(limit >= size); - unsigned const slack = limit - size; - unsigned blockSize = 0; - if (block->ComplexityExceeds(this, slack, &blockSize)) - { - return BasicBlockVisit::Abort; - } - - size += blockSize; - return BasicBlockVisit::Continue; - }); - - if (result == BasicBlockVisit::Abort) - { - JITDUMP("Loop " FMT_LP ": exceeds size limit %u\n", loop->GetIndex(), limit); - return true; - } - - JITDUMP("Loop " FMT_LP ": size %u does not exceed size limit %u\n", loop->GetIndex(), size, limit); - return false; -} - //----------------------------------------------------------------------------- // optSetWeightForPreheaderOrExit: Set the weight of a newly created preheader // or exit, after it has been added to the flowgraph. @@ -2932,15 +2901,6 @@ void Compiler::optSetWeightForPreheaderOrExit(FlowGraphNaturalLoop* loop, BasicB { block->RemoveFlags(BBF_PROF_WEIGHT); } - - if (newWeight == BB_ZERO_WEIGHT) - { - block->SetFlags(BBF_RUN_RARELY); - } - else - { - block->RemoveFlags(BBF_RUN_RARELY); - } } /***************************************************************************** @@ -3695,23 +3655,16 @@ bool Compiler::optHoistThisLoop(FlowGraphNaturalLoop* loop, LoopHoistContext* ho } #endif // FEATURE_MASKED_HW_INTRINSICS - // Find the set of definitely-executed blocks. + // Find the set of definitely-executed blocks. These will be given priority for hoisting. // Ideally, the definitely-executed blocks are the ones that post-dominate the entry block. // Until we have post-dominators, we'll special-case for single-exit blocks. // - // Todo: it is not clear if this is a correctness requirement or a profitability heuristic. - // It seems like the latter. Ideally there are enough safeguards to prevent hoisting exception - // or side-effect dependent things. Note that HoistVisitor uses `m_beforeSideEffect` to determine if it's - // ok to hoist a side-effect. It allows this only for the first block (the entry block), before any - // side-effect has been seen. After the first block, it assumes that there has been a side effect and - // no further side-effect can be hoisted. It is true that we don't analyze any program behavior in the - // flow graph between the entry block and the subsequent blocks, whether they be the next block dominating - // the exit block, or the pre-headers of nested loops. - // - // We really should consider hoisting from conditionally executed blocks, if they are frequently executed - // and it is safe to evaluate the tree early. + // TODO: We ought to consider hoisting more aggressively from conditionally executed blocks, + // if they are frequently executed and it is safe to evaluate the tree early. // - ArrayStack defExec(getAllocatorLoopHoist()); + assert(m_dfsTree != nullptr); + BitVecTraits traits(m_dfsTree->PostOrderTraits()); + BitVec defExec(BitVecOps::MakeEmpty(&traits)); // Add the pre-headers of any child loops to the list of blocks to consider for hoisting. // Note that these are not necessarily definitely executed. However, it is a heuristic that they will @@ -3769,7 +3722,7 @@ bool Compiler::optHoistThisLoop(FlowGraphNaturalLoop* loop, LoopHoistContext* ho } } JITDUMP(" -- " FMT_BB " (child loop pre-header)\n", childPreHead->bbNum); - defExec.Push(childPreHead); + BitVecOps::AddElemD(&traits, defExec, childPreHead->bbPostorderNum); } if (loop->ExitEdges().size() == 1) @@ -3794,7 +3747,7 @@ bool Compiler::optHoistThisLoop(FlowGraphNaturalLoop* loop, LoopHoistContext* ho while ((cur != nullptr) && (cur != loop->GetHeader()) && loop->ContainsBlock(cur)) { JITDUMP(" -- " FMT_BB " (dominate exit block)\n", cur->bbNum); - defExec.Push(cur); + BitVecOps::AddElemD(&traits, defExec, cur->bbPostorderNum); cur = cur->bbIDom; } @@ -3810,9 +3763,9 @@ bool Compiler::optHoistThisLoop(FlowGraphNaturalLoop* loop, LoopHoistContext* ho } JITDUMP(" -- " FMT_BB " (header block)\n", loop->GetHeader()->bbNum); - defExec.Push(loop->GetHeader()); + BitVecOps::AddElemD(&traits, defExec, loop->GetHeader()->bbPostorderNum); - optHoistLoopBlocks(loop, &defExec, hoistCtxt); + optHoistLoopBlocks(loop, &traits, defExec, hoistCtxt); unsigned numHoisted = hoistCtxt->m_hoistedFPExprCount + hoistCtxt->m_hoistedExprCount; #ifdef FEATURE_MASKED_HW_INTRINSICS @@ -3821,7 +3774,10 @@ bool Compiler::optHoistThisLoop(FlowGraphNaturalLoop* loop, LoopHoistContext* ho return numHoisted > 0; } -bool Compiler::optIsProfitableToHoistTree(GenTree* tree, FlowGraphNaturalLoop* loop, LoopHoistContext* hoistCtxt) +bool Compiler::optIsProfitableToHoistTree(GenTree* tree, + FlowGraphNaturalLoop* loop, + LoopHoistContext* hoistCtxt, + bool defExecuted) { bool loopContainsCall = m_loopSideEffects[loop->GetIndex()].ContainsCall; @@ -3892,6 +3848,14 @@ bool Compiler::optIsProfitableToHoistTree(GenTree* tree, FlowGraphNaturalLoop* l // always be a subset of the InOut variables for the loop assert(loopVarCount <= varInOutCount); + // If this tree isn't guaranteed to execute every loop iteration, + // consider hoisting it only if it is expensive. + // + if (!defExecuted && (tree->GetCostEx() < (IND_COST_EX * 16))) + { + return false; + } + // When loopVarCount >= availRegCount we believe that all of the // available registers will get used to hold LclVars inside the loop. // This pessimistically assumes that each loopVar has a conflicting @@ -4110,17 +4074,14 @@ void LoopSideEffects::AddModifiedElemType(Compiler* comp, CORINFO_CLASS_HANDLE s // // Arguments: // loop - The loop -// blocks - A stack of blocks belonging to the loop +// traits - Bit vector traits for 'defExecuted' +// defExecuted - Bit vector of definitely executed blocks in the loop // hoistContext - The loop hoist context // -// Assumptions: -// The `blocks` stack contains the definitely-executed blocks in -// the loop, in the execution order, starting with the loop entry -// block on top of the stack. -// -void Compiler::optHoistLoopBlocks(FlowGraphNaturalLoop* loop, - ArrayStack* blocks, - LoopHoistContext* hoistContext) +void Compiler::optHoistLoopBlocks(FlowGraphNaturalLoop* loop, + BitVecTraits* traits, + BitVec defExecuted, + LoopHoistContext* hoistContext) { class HoistVisitor : public GenTreeVisitor { @@ -4159,6 +4120,8 @@ void Compiler::optHoistLoopBlocks(FlowGraphNaturalLoop* loop, FlowGraphNaturalLoop* m_loop; LoopHoistContext* m_hoistContext; BasicBlock* m_currentBlock; + BitVecTraits* m_traits; + BitVec m_defExec; bool IsNodeHoistable(GenTree* node) { @@ -4281,13 +4244,19 @@ void Compiler::optHoistLoopBlocks(FlowGraphNaturalLoop* loop, UseExecutionOrder = true, }; - HoistVisitor(Compiler* compiler, FlowGraphNaturalLoop* loop, LoopHoistContext* hoistContext) + HoistVisitor(Compiler* compiler, + FlowGraphNaturalLoop* loop, + LoopHoistContext* hoistContext, + BitVecTraits* traits, + BitVec defExec) : GenTreeVisitor(compiler) , m_valueStack(compiler->getAllocator(CMK_LoopHoist)) , m_beforeSideEffect(true) , m_loop(loop) , m_hoistContext(hoistContext) , m_currentBlock(nullptr) + , m_traits(traits) + , m_defExec(defExec) { } @@ -4303,7 +4272,8 @@ void Compiler::optHoistLoopBlocks(FlowGraphNaturalLoop* loop, // hoist the top node? if (top.m_hoistable) { - m_compiler->optHoistCandidate(stmt->GetRootNode(), block, m_loop, m_hoistContext); + const bool defExecuted = BitVecOps::IsMember(m_traits, m_defExec, block->bbPostorderNum); + m_compiler->optHoistCandidate(stmt->GetRootNode(), block, m_loop, m_hoistContext, defExecuted); } else { @@ -4313,11 +4283,6 @@ void Compiler::optHoistLoopBlocks(FlowGraphNaturalLoop* loop, m_valueStack.Reset(); } - - // Only unconditionally executed blocks in the loop are visited (see optHoistThisLoop) - // so after we're done visiting the first block we need to assume the worst, that the - // blocks that are not visited have side effects. - m_beforeSideEffect = false; } fgWalkResult PreOrderVisit(GenTree** use, GenTree* user) @@ -4496,8 +4461,7 @@ void Compiler::optHoistLoopBlocks(FlowGraphNaturalLoop* loop, if (!m_beforeSideEffect) { // For now, we give up on an expression that might raise an exception if it is after the - // first possible global side effect (and we assume we're after that if we're not in the first - // block). + // first possible global side effect. // TODO-CQ: this is when we might do loop cloning. // if ((tree->gtFlags & GTF_EXCEPT) != 0) @@ -4653,7 +4617,10 @@ void Compiler::optHoistLoopBlocks(FlowGraphNaturalLoop* loop, if (IsHoistableOverExcepSibling(value.Node(), hasExcep)) { - m_compiler->optHoistCandidate(value.Node(), m_currentBlock, m_loop, m_hoistContext); + const bool defExecuted = + BitVecOps::IsMember(m_traits, m_defExec, m_currentBlock->bbPostorderNum); + m_compiler->optHoistCandidate(value.Node(), m_currentBlock, m_loop, m_hoistContext, + defExecuted); } // Don't hoist this tree again. @@ -4699,12 +4666,9 @@ void Compiler::optHoistLoopBlocks(FlowGraphNaturalLoop* loop, } }; - HoistVisitor visitor(this, loop, hoistContext); - - while (!blocks->Empty()) - { - BasicBlock* block = blocks->Pop(); - weight_t blockWeight = block->getBBWeight(this); + HoistVisitor visitor(this, loop, hoistContext, traits, defExecuted); + loop->VisitLoopBlocks([&](BasicBlock* block) -> BasicBlockVisit { + const weight_t blockWeight = block->getBBWeight(this); JITDUMP("\n optHoistLoopBlocks " FMT_BB " (weight=%6s) of loop " FMT_LP " (head: " FMT_BB ")\n", block->bbNum, refCntWtd2str(blockWeight, /* padForDecimalPlaces */ true), loop->GetIndex(), @@ -4713,22 +4677,23 @@ void Compiler::optHoistLoopBlocks(FlowGraphNaturalLoop* loop, if (blockWeight < (BB_UNITY_WEIGHT / 10)) { JITDUMP(" block weight is too small to perform hoisting.\n"); - continue; + } + else + { + visitor.HoistBlock(block); } - visitor.HoistBlock(block); - } + return BasicBlockVisit::Continue; + }); hoistContext->ResetHoistedInCurLoop(); } -void Compiler::optHoistCandidate(GenTree* tree, - BasicBlock* treeBb, - FlowGraphNaturalLoop* loop, - LoopHoistContext* hoistCtxt) +void Compiler::optHoistCandidate( + GenTree* tree, BasicBlock* treeBb, FlowGraphNaturalLoop* loop, LoopHoistContext* hoistCtxt, bool defExecuted) { // It must pass the hoistable profitability tests for this loop level - if (!optIsProfitableToHoistTree(tree, loop, hoistCtxt)) + if (!optIsProfitableToHoistTree(tree, loop, hoistCtxt, defExecuted)) { JITDUMP(" ... not profitable to hoist\n"); return; diff --git a/src/coreclr/jit/promotion.cpp b/src/coreclr/jit/promotion.cpp index b4e2e284d051e4..137013963eedc0 100644 --- a/src/coreclr/jit/promotion.cpp +++ b/src/coreclr/jit/promotion.cpp @@ -1126,7 +1126,7 @@ class LocalsUseVisitor : public GenTreeVisitor if (lcl->OperIs(GT_LCL_ADDR)) { - assert(user->OperIs(GT_CALL) && dsc->IsHiddenBufferStructArg() && + assert(user->OperIs(GT_CALL) && dsc->IsDefinedViaAddress() && (user->AsCall()->gtArgs.GetRetBufferArg()->GetNode() == lcl)); accessType = TYP_STRUCT; @@ -3013,7 +3013,7 @@ PhaseStatus Promotion::Run() Statement* firstStmt = replacer.StartBlock(bb); JITDUMP("\nReplacing in "); - DBEXEC(m_compiler->verbose, bb->dspBlockHeader(m_compiler)); + DBEXEC(m_compiler->verbose, bb->dspBlockHeader()); JITDUMP("\n"); for (Statement* stmt : StatementList(firstStmt)) diff --git a/src/coreclr/jit/rangecheckcloning.cpp b/src/coreclr/jit/rangecheckcloning.cpp index 82dc3a1bc300d2..15b864630f90f0 100644 --- a/src/coreclr/jit/rangecheckcloning.cpp +++ b/src/coreclr/jit/rangecheckcloning.cpp @@ -305,7 +305,7 @@ static BasicBlock* optRangeCheckCloning_DoClone(Compiler* comp, upperBndToFallbackEdge->setLikelihood(0.0f); lowerBndBb->SetFlags(BBF_INTERNAL); - upperBndBb->SetFlags(BBF_INTERNAL | BBF_HAS_IDX_LEN); + upperBndBb->SetFlags(BBF_INTERNAL); // Now drop the bounds check from the fast path while (!bndChkStack->Empty()) @@ -443,8 +443,13 @@ static bool DoesComplexityExceed(Compiler* comp, ArrayStack* bn GenTree* rootNode = currentStmt->GetRootNode(); if (rootNode != nullptr) { - unsigned actual = 0; - if (comp->gtComplexityExceeds(rootNode, budget, &actual)) + unsigned actual = 0; + auto countNode = [&actual](GenTree* tree) -> unsigned { + actual++; + return 1; + }; + + if (comp->gtComplexityExceeds(rootNode, budget, countNode)) { JITDUMP("\tExceeded budget!"); return true; diff --git a/src/coreclr/jit/rationalize.cpp b/src/coreclr/jit/rationalize.cpp index 7115c01cbe963a..6857379c8b65bf 100644 --- a/src/coreclr/jit/rationalize.cpp +++ b/src/coreclr/jit/rationalize.cpp @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. #include "jitpch.h" +#include "sideeffects.h" + #ifdef _MSC_VER #pragma hdrstop #endif @@ -21,7 +23,6 @@ // Return Value: // None. // - void Rationalizer::RewriteNodeAsCall(GenTree** use, CORINFO_SIG_INFO* sig, ArrayStack& parents, @@ -262,8 +263,8 @@ void Rationalizer::RewriteNodeAsCall(GenTree** use, // RewriteIntrinsicAsUserCall : Rewrite an intrinsic operator as a GT_CALL to the original method. // // Arguments: -// ppTree - A pointer-to-a-pointer for the intrinsic node -// fgWalkData - A pointer to tree walk data providing the context +// use - A pointer-to-a-pointer for the intrinsic node +// parents - A pointer to tree walk data providing the context // // Return Value: // None. @@ -272,7 +273,6 @@ void Rationalizer::RewriteNodeAsCall(GenTree** use, // The ones that are not being rewritten here must be handled in Codegen. // Conceptually, the lower is the right place to do the rewrite. Keeping it in rationalization is // mainly for throughput issue. - void Rationalizer::RewriteIntrinsicAsUserCall(GenTree** use, ArrayStack& parents) { GenTreeIntrinsic* intrinsic = (*use)->AsIntrinsic(); @@ -310,12 +310,15 @@ void Rationalizer::RewriteIntrinsicAsUserCall(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) @@ -447,30 +464,6 @@ void Rationalizer::RewriteHWIntrinsicAsUserCall(GenTree** use, ArrayStack 0) - { - CORINFO_ARG_LIST_HANDLE args = sigInfo.args; - comp->info.compCompHnd->getArgType(&sigInfo, args, &op1ClsHnd); - - if (argCount > 1) - { - args = comp->info.compCompHnd->getArgNext(args); - comp->info.compCompHnd->getArgType(&sigInfo, args, &op2ClsHnd); - - if (argCount > 2) - { - args = comp->info.compCompHnd->getArgNext(args); - comp->info.compCompHnd->getArgType(&sigInfo, args, &op3ClsHnd); - } - } - } - // Position of the immediates from top of stack int imm1Pos = -1; int imm2Pos = -1; @@ -494,8 +487,7 @@ void Rationalizer::RewriteHWIntrinsicAsUserCall(GenTree** use, ArrayStackgetHWIntrinsicImmTypes(intrinsicId, &sigInfo, 2, simdBaseType, simdBaseJitType, op1ClsHnd, - op2ClsHnd, op3ClsHnd, &immSimdSize, &immSimdBaseType); + comp->getHWIntrinsicImmTypes(intrinsicId, &sigInfo, 2, &immSimdSize, &immSimdBaseType); HWIntrinsicInfo::lookupImmBounds(intrinsicId, immSimdSize, immSimdBaseType, 2, &immLowerBound, &immUpperBound); @@ -510,8 +502,7 @@ void Rationalizer::RewriteHWIntrinsicAsUserCall(GenTree** use, ArrayStackgetHWIntrinsicImmTypes(intrinsicId, &sigInfo, 1, simdBaseType, simdBaseJitType, op1ClsHnd, op2ClsHnd, - op3ClsHnd, &immSimdSize, &immSimdBaseType); + comp->getHWIntrinsicImmTypes(intrinsicId, &sigInfo, 1, &immSimdSize, &immSimdBaseType); HWIntrinsicInfo::lookupImmBounds(intrinsicId, immSimdSize, immSimdBaseType, 1, &immLowerBound, &immUpperBound); #endif @@ -573,6 +564,1058 @@ void Rationalizer::RewriteHWIntrinsicAsUserCall(GenTree** use, ArrayStackAsHWIntrinsic(); + + // Intrinsics should have already been rewritten back into user calls. + assert(!node->IsUserCall()); + + NamedIntrinsic intrinsic = node->GetHWIntrinsicId(); + + switch (intrinsic) + { +#if defined(TARGET_XARCH) + case NI_AVX512_BlendVariableMask: + { + RewriteHWIntrinsicBlendv(use, parents); + break; + } + + case NI_AVX512_ConvertMaskToVector: + case NI_AVX512_MoveMask: + { + RewriteHWIntrinsicMaskOp(use, parents); + break; + } +#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; + } + } +} + +#if defined(TARGET_XARCH) +//---------------------------------------------------------------------------------------------- +// RewriteHWIntrinsicBlendv: Rewrites a hwintrinsic blendv operation +// +// Arguments: +// use - A pointer to the hwintrinsic node +// parents - A reference to tree walk data providing the context +// +void Rationalizer::RewriteHWIntrinsicBlendv(GenTree** use, Compiler::GenTreeStack& parents) +{ + GenTreeHWIntrinsic* node = (*use)->AsHWIntrinsic(); + + // We normalize all comparisons to be of TYP_MASK on import. However, if we + // get to rationalization and we cannot take advantage of embedded masking + // then we want to rewrite things to just directly produce TYP_SIMD instead. + + NamedIntrinsic intrinsic = node->GetHWIntrinsicId(); + var_types retType = node->TypeGet(); + CorInfoType simdBaseJitType = node->GetSimdBaseJitType(); + var_types simdBaseType = node->GetSimdBaseType(); + unsigned simdSize = node->GetSimdSize(); + + if (simdSize == 64) + { + return; + } + + GenTree* op2 = node->Op(2); + + // We're in the post-order visit and are traversing in execution order, so + // everything between op2 and node will have already been rewritten to LIR + // form and doing the IsInvariantInRange check is safe. This allows us to + // catch cases where something is embedded masking compatible but where we + // could never actually contain it and so we want to rewrite it to the non-mask + // variant + SideEffectSet scratchSideEffects; + + if (scratchSideEffects.IsLirInvariantInRange(comp, op2, node)) + { + unsigned tgtMaskSize = simdSize / genTypeSize(simdBaseType); + CorInfoType tgtSimdBaseJitType = CORINFO_TYPE_UNDEF; + + if (op2->isEmbeddedMaskingCompatible(comp, tgtMaskSize, tgtSimdBaseJitType)) + { + // We are going to utilize the embedded mask, so we don't need to rewrite. However, + // we want to fixup the simdBaseJitType here since it simplifies lowering and allows + // both embedded broadcast and the mask to be live simultaneously. + + if (tgtSimdBaseJitType != CORINFO_TYPE_UNDEF) + { + op2->AsHWIntrinsic()->SetSimdBaseJitType(tgtSimdBaseJitType); + } + return; + } + } + + GenTree*& op3 = node->Op(3); + + if (!ShouldRewriteToNonMaskHWIntrinsic(op3)) + { + return; + } + + parents.Push(op3); + RewriteHWIntrinsicToNonMask(&op3, parents); + (void)parents.Pop(); + + if (simdSize == 32) + { + if (varTypeIsIntegral(simdBaseType)) + { + intrinsic = NI_AVX2_BlendVariable; + } + else + { + intrinsic = NI_AVX_BlendVariable; + } + } + else + { + intrinsic = NI_SSE42_BlendVariable; + } + + if (HWIntrinsicInfo::NeedsNormalizeSmallTypeToInt(intrinsic) && varTypeIsSmall(simdBaseType)) + { + node->SetSimdBaseJitType(varTypeIsUnsigned(simdBaseType) ? CORINFO_TYPE_UINT : CORINFO_TYPE_INT); + } + node->ChangeHWIntrinsicId(intrinsic); +} + +//---------------------------------------------------------------------------------------------- +// RewriteHWIntrinsicMaskOp: Rewrites a hwintrinsic mask operation +// +// Arguments: +// use - A pointer to the hwintrinsic node +// parents - A reference to tree walk data providing the context +// +void Rationalizer::RewriteHWIntrinsicMaskOp(GenTree** use, Compiler::GenTreeStack& parents) +{ + GenTreeHWIntrinsic* node = (*use)->AsHWIntrinsic(); + + // We normalize all comparisons to be of TYP_MASK on import. However, if we + // get to rationalization and we're just converting that back to TYP_SIMD, + // then we want to rewrite things to just directly produce TYP_SIMD instead. + + NamedIntrinsic intrinsic = node->GetHWIntrinsicId(); + var_types retType = node->TypeGet(); + CorInfoType simdBaseJitType = node->GetSimdBaseJitType(); + var_types simdBaseType = node->GetSimdBaseType(); + unsigned simdSize = node->GetSimdSize(); + + if (simdSize == 64) + { + // we must always use the evex encoding + return; + } + + if ((intrinsic == NI_AVX512_MoveMask) && varTypeIsShort(simdBaseType)) + { + // we need to keep the evex form as it's more efficient + return; + } + + GenTree*& op1 = node->Op(1); + + if (!ShouldRewriteToNonMaskHWIntrinsic(op1)) + { + return; + } + + parents.Push(op1); + RewriteHWIntrinsicToNonMask(&op1, parents); + (void)parents.Pop(); + + if (intrinsic == NI_AVX512_ConvertMaskToVector) + { + if (parents.Height() > 1) + { + parents.Top(1)->ReplaceOperand(use, op1); + } + else + { + *use = op1; + } + BlockRange().Remove(node); + + // Adjust the parent stack + assert(parents.Top() == node); + (void)parents.Pop(); + parents.Push(op1); + } + else + { + assert(intrinsic == NI_AVX512_MoveMask); + + switch (simdBaseType) + { + case TYP_BYTE: + case TYP_UBYTE: + { + intrinsic = (simdSize == 32) ? NI_AVX2_MoveMask : NI_X86Base_MoveMask; + break; + } + + case TYP_INT: + case TYP_UINT: + case TYP_FLOAT: + { + simdBaseJitType = CORINFO_TYPE_FLOAT; + intrinsic = (simdSize == 32) ? NI_AVX_MoveMask : NI_X86Base_MoveMask; + break; + } + + case TYP_LONG: + case TYP_ULONG: + case TYP_DOUBLE: + { + simdBaseJitType = CORINFO_TYPE_DOUBLE; + intrinsic = (simdSize == 32) ? NI_AVX_MoveMask : NI_X86Base_MoveMask; + break; + } + + default: + { + unreached(); + } + } + + node->SetSimdBaseJitType(simdBaseJitType); + node->ChangeHWIntrinsicId(intrinsic); + } +} + +//---------------------------------------------------------------------------------------------- +// RewriteHWIntrinsicToNonMask: Rewrites a hwintrinsic to its non-mask form +// +// Arguments: +// use - A pointer to the hwintrinsic node +// parents - A reference to tree walk data providing the context +// +void Rationalizer::RewriteHWIntrinsicToNonMask(GenTree** use, Compiler::GenTreeStack& parents) +{ + GenTreeHWIntrinsic* node = (*use)->AsHWIntrinsic(); + + assert(node->TypeIs(TYP_MASK)); + assert(ShouldRewriteToNonMaskHWIntrinsic(node)); + + NamedIntrinsic intrinsic = node->GetHWIntrinsicId(); + + switch (intrinsic) + { + case NI_AVX512_AndMask: + { + RewriteHWIntrinsicBitwiseOpToNonMask(use, parents, GT_AND); + break; + } + + case NI_AVX512_AndNotMask: + { + RewriteHWIntrinsicBitwiseOpToNonMask(use, parents, GT_AND_NOT); + break; + } + + case NI_AVX512_NotMask: + { + RewriteHWIntrinsicBitwiseOpToNonMask(use, parents, GT_NOT); + break; + } + + case NI_AVX512_OrMask: + { + RewriteHWIntrinsicBitwiseOpToNonMask(use, parents, GT_OR); + break; + } + + case NI_AVX512_XorMask: + { + RewriteHWIntrinsicBitwiseOpToNonMask(use, parents, GT_XOR); + break; + } + + case NI_AVX512_XnorMask: + { + CorInfoType simdBaseJitType = node->GetSimdBaseJitType(); + unsigned simdSize = node->GetSimdSize(); + var_types simdType = Compiler::getSIMDTypeForSize(simdSize); + + GenTree* op1 = + comp->gtNewSimdBinOpNode(GT_XOR, simdType, node->Op(1), node->Op(2), simdBaseJitType, simdSize); + BlockRange().InsertBefore(node, op1); + node->Op(1) = op1; + + GenTree* op2 = comp->gtNewAllBitsSetConNode(simdType); + BlockRange().InsertBefore(node, op2); + node->Op(2) = op2; + + RewriteHWIntrinsicBitwiseOpToNonMask(use, parents, GT_XOR); + break; + } + + case NI_AVX512_CompareMask: + case NI_AVX512_CompareEqualMask: + case NI_AVX512_CompareGreaterThanMask: + case NI_AVX512_CompareGreaterThanOrEqualMask: + case NI_AVX512_CompareLessThanMask: + case NI_AVX512_CompareLessThanOrEqualMask: + case NI_AVX512_CompareNotEqualMask: + case NI_AVX512_CompareNotGreaterThanMask: + case NI_AVX512_CompareNotGreaterThanOrEqualMask: + case NI_AVX512_CompareNotLessThanMask: + case NI_AVX512_CompareNotLessThanOrEqualMask: + case NI_AVX512_CompareOrderedMask: + case NI_AVX512_CompareUnorderedMask: + { + var_types simdBaseType = node->GetSimdBaseType(); + unsigned simdSize = node->GetSimdSize(); + var_types simdType = Compiler::getSIMDTypeForSize(simdSize); + + switch (intrinsic) + { + case NI_AVX512_CompareMask: + { + intrinsic = NI_AVX_Compare; + break; + } + + case NI_AVX512_CompareEqualMask: + { + if (simdSize == 32) + { + if (varTypeIsIntegral(simdBaseType)) + { + intrinsic = NI_AVX2_CompareEqual; + } + else + { + intrinsic = NI_AVX_CompareEqual; + } + } + else if (varTypeIsLong(simdBaseType)) + { + intrinsic = NI_SSE42_CompareEqual; + } + else + { + intrinsic = NI_X86Base_CompareEqual; + } + break; + } + + case NI_AVX512_CompareGreaterThanMask: + { + if (simdSize == 32) + { + if (varTypeIsIntegral(simdBaseType)) + { + intrinsic = NI_AVX2_CompareGreaterThan; + } + else + { + intrinsic = NI_AVX_CompareGreaterThan; + } + } + else if (varTypeIsLong(simdBaseType)) + { + intrinsic = NI_SSE42_CompareGreaterThan; + } + else + { + intrinsic = NI_X86Base_CompareGreaterThan; + } + break; + } + + case NI_AVX512_CompareGreaterThanOrEqualMask: + { + if (simdSize == 32) + { + intrinsic = NI_AVX_CompareGreaterThanOrEqual; + } + else + { + intrinsic = NI_X86Base_CompareGreaterThanOrEqual; + } + break; + } + + case NI_AVX512_CompareLessThanMask: + { + if (simdSize == 32) + { + if (varTypeIsIntegral(simdBaseType)) + { + intrinsic = NI_AVX2_CompareLessThan; + } + else + { + intrinsic = NI_AVX_CompareLessThan; + } + } + else if (varTypeIsLong(simdBaseType)) + { + intrinsic = NI_SSE42_CompareLessThan; + } + else + { + intrinsic = NI_X86Base_CompareLessThan; + } + break; + } + + case NI_AVX512_CompareLessThanOrEqualMask: + { + if (simdSize == 32) + { + intrinsic = NI_AVX_CompareLessThanOrEqual; + } + else + { + intrinsic = NI_X86Base_CompareLessThanOrEqual; + } + break; + } + + case NI_AVX512_CompareNotEqualMask: + { + if (simdSize == 32) + { + intrinsic = NI_AVX_CompareNotEqual; + } + else + { + intrinsic = NI_X86Base_CompareNotEqual; + } + break; + } + + case NI_AVX512_CompareNotGreaterThanMask: + { + if (simdSize == 32) + { + intrinsic = NI_AVX_CompareNotGreaterThan; + } + else + { + intrinsic = NI_X86Base_CompareNotGreaterThan; + } + break; + } + + case NI_AVX512_CompareNotGreaterThanOrEqualMask: + { + if (simdSize == 32) + { + intrinsic = NI_AVX_CompareNotGreaterThanOrEqual; + } + else + { + intrinsic = NI_X86Base_CompareNotGreaterThanOrEqual; + } + break; + } + + case NI_AVX512_CompareNotLessThanMask: + { + if (simdSize == 32) + { + intrinsic = NI_AVX_CompareNotLessThan; + } + else + { + intrinsic = NI_X86Base_CompareNotLessThan; + } + break; + } + + case NI_AVX512_CompareNotLessThanOrEqualMask: + { + if (simdSize == 32) + { + intrinsic = NI_AVX_CompareNotLessThanOrEqual; + } + else + { + intrinsic = NI_X86Base_CompareNotLessThanOrEqual; + } + break; + } + + case NI_AVX512_CompareOrderedMask: + { + if (simdSize == 32) + { + intrinsic = NI_AVX_CompareOrdered; + } + else + { + intrinsic = NI_X86Base_CompareOrdered; + } + break; + } + + case NI_AVX512_CompareUnorderedMask: + { + if (simdSize == 32) + { + intrinsic = NI_AVX_CompareUnordered; + } + else + { + intrinsic = NI_X86Base_CompareUnordered; + } + break; + } + + default: + { + unreached(); + } + } + + node->gtType = simdType; + node->ChangeHWIntrinsicId(intrinsic); + + break; + } + + case NI_AVX512_ConvertVectorToMask: + { + GenTree* op1 = node->Op(1); + + if (parents.Height() > 1) + { + parents.Top(1)->ReplaceOperand(use, op1); + } + else + { + *use = op1; + } + BlockRange().Remove(node); + + // Adjust the parent stack + assert(parents.Top() == node); + (void)parents.Pop(); + parents.Push(op1); + + break; + } + + default: + { + unreached(); + } + } +} + +//---------------------------------------------------------------------------------------------- +// RewriteHWIntrinsicBitwiseOpToNonMask: Rewrites hwintrinsic bitwise operation to its non-mask form +// +// Arguments: +// use - A pointer to the hwintrinsic node +// parents - A reference to tree walk data providing the context +// oper - The operation represented by the hwintrinsic +// +void Rationalizer::RewriteHWIntrinsicBitwiseOpToNonMask(GenTree** use, Compiler::GenTreeStack& parents, genTreeOps oper) +{ + GenTreeHWIntrinsic* node = (*use)->AsHWIntrinsic(); + assert((node->GetOperandCount() == 1) || (node->GetOperandCount() == 2)); + + assert(node->TypeIs(TYP_MASK)); + assert(oper != GT_NONE); + + NamedIntrinsic intrinsic = NI_Illegal; + var_types simdBaseType = node->GetSimdBaseType(); + unsigned simdSize = node->GetSimdSize(); + var_types simdType = Compiler::getSIMDTypeForSize(simdSize); + const bool isScalar = false; + + GenTree*& op1 = node->Op(1); + + parents.Push(op1); + RewriteHWIntrinsicToNonMask(&op1, parents); + (void)parents.Pop(); + + if (node->GetOperandCount() == 1) + { + assert(oper == GT_NOT); + + GenTree* op2 = comp->gtNewAllBitsSetConNode(simdType); + BlockRange().InsertBefore(node, op2); + + intrinsic = + GenTreeHWIntrinsic::GetHWIntrinsicIdForBinOp(comp, GT_XOR, op1, op2, simdBaseType, simdSize, isScalar); + + node->gtType = simdType; + node->ResetHWIntrinsicId(intrinsic, comp, op1, op2); + } + else + { + GenTree*& op2 = node->Op(2); + + parents.Push(op2); + RewriteHWIntrinsicToNonMask(&op2, parents); + (void)parents.Pop(); + + intrinsic = + GenTreeHWIntrinsic::GetHWIntrinsicIdForBinOp(comp, oper, op1, op2, simdBaseType, simdSize, isScalar); + + node->gtType = simdType; + node->ChangeHWIntrinsicId(intrinsic); + } +} + +//---------------------------------------------------------------------------------------------- +// ShouldRewriteToNonMaskHWIntrinsic: Determines if a node is a hwintrinsic that should be rewritten +// to its non-mask form +// +// Arguments: +// node - The node to check +// +// Returns: +// true if node is a hardware intrinsic node and should be converted to its non-mask form; otherwise false +// +bool Rationalizer::ShouldRewriteToNonMaskHWIntrinsic(GenTree* node) +{ + assert(node->TypeIs(TYP_MASK)); + + if (!node->OperIsHWIntrinsic()) + { + // Nothing to optimize if we don't have a hwintrinsic + return false; + } + + GenTreeHWIntrinsic* hwNode = node->AsHWIntrinsic(); + NamedIntrinsic intrinsic = hwNode->GetHWIntrinsicId(); + + if (hwNode->GetSimdSize() == 64) + { + // TYP_SIMD64 comparisons always produce a TYP_MASK + return false; + } + + switch (intrinsic) + { + case NI_AVX512_AndMask: + case NI_AVX512_AndNotMask: + case NI_AVX512_OrMask: + case NI_AVX512_XorMask: + case NI_AVX512_XnorMask: + { + // binary bitwise operations should be optimized if both inputs can + assert(hwNode->GetOperandCount() == 2); + return ShouldRewriteToNonMaskHWIntrinsic(hwNode->Op(1)) && ShouldRewriteToNonMaskHWIntrinsic(hwNode->Op(2)); + } + + case NI_AVX512_NotMask: + { + // unary bitwise operations should be optimized if the input can + assert(hwNode->GetOperandCount() == 1); + return ShouldRewriteToNonMaskHWIntrinsic(hwNode->Op(1)); + } + + case NI_AVX512_CompareMask: + case NI_AVX512_CompareEqualMask: + case NI_AVX512_CompareGreaterThanMask: + case NI_AVX512_CompareGreaterThanOrEqualMask: + case NI_AVX512_CompareLessThanMask: + case NI_AVX512_CompareLessThanOrEqualMask: + case NI_AVX512_CompareNotEqualMask: + case NI_AVX512_CompareNotGreaterThanMask: + case NI_AVX512_CompareNotGreaterThanOrEqualMask: + case NI_AVX512_CompareNotLessThanMask: + case NI_AVX512_CompareNotLessThanOrEqualMask: + case NI_AVX512_CompareOrderedMask: + case NI_AVX512_CompareUnorderedMask: + { + assert((hwNode->GetOperandCount() == 2) || (hwNode->GetOperandCount() == 3)); + var_types simdBaseType = hwNode->GetSimdBaseType(); + + if (varTypeIsFloating(simdBaseType)) + { + // floating-point comparisons can always be optimized + return true; + } + + if (intrinsic == NI_AVX512_CompareEqualMask) + { + // equals comparisons can always be optimized + return true; + } + + if (varTypeIsUnsigned(simdBaseType)) + { + // unsigned integer relational comparisons cannot be optimized + return false; + } + + if (intrinsic == NI_AVX512_CompareGreaterThanMask) + { + // signed integer greater-than comparisons can always be optimized + return true; + } + + if (intrinsic == NI_AVX512_CompareLessThanMask) + { + // signed integer less-than comparisons can always be optimized + return true; + } + break; + } + + case NI_AVX512_ConvertVectorToMask: + { + return true; + } + + default: + { + break; + } + } + + // Other cases cannot be optimized + 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 // RewriteSubLshDiv: Possibly rewrite a SubLshDiv node into a Mod. // @@ -784,8 +1827,7 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, Compiler::Ge #if defined(FEATURE_HW_INTRINSICS) case GT_HWINTRINSIC: - // Intrinsics should have already been rewritten back into user calls. - assert(!node->AsHWIntrinsic()->IsUserCall()); + RewriteHWIntrinsic(useEdge, parentStack); break; #endif // FEATURE_HW_INTRINSICS diff --git a/src/coreclr/jit/rationalize.h b/src/coreclr/jit/rationalize.h index 923e10665cb002..a4d18f25f708d3 100644 --- a/src/coreclr/jit/rationalize.h +++ b/src/coreclr/jit/rationalize.h @@ -49,7 +49,22 @@ class Rationalizer final : public Phase void RewriteIntrinsicAsUserCall(GenTree** use, Compiler::GenTreeStack& parents); #if defined(FEATURE_HW_INTRINSICS) + // pre-order rewriting void RewriteHWIntrinsicAsUserCall(GenTree** use, Compiler::GenTreeStack& parents); + + // post-order rewriting + void RewriteHWIntrinsic(GenTree** use, Compiler::GenTreeStack& parents); + +#if defined(TARGET_XARCH) + void RewriteHWIntrinsicBlendv(GenTree** use, Compiler::GenTreeStack& parents); + void RewriteHWIntrinsicMaskOp(GenTree** use, Compiler::GenTreeStack& parents); + void RewriteHWIntrinsicToNonMask(GenTree** use, Compiler::GenTreeStack& parents); + void RewriteHWIntrinsicBitwiseOpToNonMask(GenTree** use, Compiler::GenTreeStack& parents, genTreeOps oper); + + 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/coreclr/jit/redundantbranchopts.cpp b/src/coreclr/jit/redundantbranchopts.cpp index d430abe5171cdc..9528ac3065f798 100644 --- a/src/coreclr/jit/redundantbranchopts.cpp +++ b/src/coreclr/jit/redundantbranchopts.cpp @@ -688,6 +688,15 @@ bool Compiler::optRelopTryInferWithOneEqualOperand(const VNFuncApp& domApp, if ((ifTrueStatus == RelopResult::Unknown) && (ifFalseStatus == RelopResult::Unknown)) { + JITDUMP("Can't infer from both true and false branches - bail out.\n") + return false; + } + + if ((ifTrueStatus == RelopResult::AlwaysTrue) && (ifFalseStatus == RelopResult::AlwaysTrue)) + { + // If it doesn't depend on the dominating relop - bail out, someone else will fold + // this always-true condition. + JITDUMP("Always true from both branches - bail out.\n") return false; } diff --git a/src/coreclr/jit/sideeffects.cpp b/src/coreclr/jit/sideeffects.cpp index 4a9b1899b24b84..5f90c8d90456c7 100644 --- a/src/coreclr/jit/sideeffects.cpp +++ b/src/coreclr/jit/sideeffects.cpp @@ -596,6 +596,186 @@ bool SideEffectSet::InterferesWith(Compiler* compiler, GenTree* node, bool stric return InterferesWith(node->OperEffects(compiler), AliasSet::NodeInfo(compiler, node), strict); } +//------------------------------------------------------------------------ +// SideEffectSet::IsLirInvariantInRange: Check if a node is invariant in the +// specified range. In other words, can 'node' be moved to right before +// 'endExclusive' without its computation changing values? +// +// Arguments: +// comp - The compiler +// node - The node. +// endExclusive - The exclusive end of the range to check invariance for. +// +// Returns: +// True if 'node' can be evaluated at any point between its current +// location and 'endExclusive' without giving a different result; otherwise +// false. +// +// Remarks: +// This presumes we are operating on nodes that are in LIR form +// +bool SideEffectSet::IsLirInvariantInRange(Compiler* comp, GenTree* node, GenTree* endExclusive) +{ + assert((node != nullptr) && (endExclusive != nullptr)); + + // Quick early-out for unary cases + // + if (node->gtNext == endExclusive) + { + return true; + } + + if (node->OperConsumesFlags()) + { + return false; + } + + Clear(); + AddNode(comp, node); + + for (GenTree* cur = node->gtNext; cur != endExclusive; cur = cur->gtNext) + { + assert((cur != nullptr) && "Expected first node to precede end node"); + const bool strict = true; + if (InterferesWith(comp, cur, strict)) + { + return false; + } + } + + return true; +} + +//------------------------------------------------------------------------ +// SideEffectSet::IsLirInvariantInRange: Check if a node is invariant in the +// specified range, ignoring conflicts with one particular node. +// +// Arguments: +// comp - The compiler +// node - The node. +// endExclusive - The exclusive end of the range to check invariance for. +// ignoreNode - A node to ignore interference checks with, for example +// because it will retain its relative order with 'node'. +// +// Returns: +// True if 'node' can be evaluated at any point between its current location +// and 'endExclusive' without giving a different result; otherwise false. +// +// Remarks: +// This presumes we are operating on nodes that are in LIR form +// +bool SideEffectSet::IsLirInvariantInRange(Compiler* comp, GenTree* node, GenTree* endExclusive, GenTree* ignoreNode) +{ + assert((node != nullptr) && (endExclusive != nullptr)); + + if (ignoreNode == nullptr) + { + return IsLirInvariantInRange(comp, node, endExclusive); + } + + if ((node->gtNext == endExclusive) || ((node->gtNext == ignoreNode) && (node->gtNext->gtNext == endExclusive))) + { + return true; + } + + if (node->OperConsumesFlags()) + { + return false; + } + + Clear(); + AddNode(comp, node); + + for (GenTree* cur = node->gtNext; cur != endExclusive; cur = cur->gtNext) + { + assert((cur != nullptr) && "Expected first node to precede end node"); + if (cur == ignoreNode) + { + continue; + } + + const bool strict = true; + if (InterferesWith(comp, cur, strict)) + { + return false; + } + } + + return true; +} + +//------------------------------------------------------------------------ +// SideEffectSet::IsLirRangeInvariantInRange: Check if a range of nodes are +// invariant in the specified range. +// +// Arguments: +// comp - The compiler +// rangeStart - The first node. +// rangeEnd - The last node. +// endExclusive - The exclusive end of the range to check invariance for. +// ignoreNode - A node to ignore interference checks with, for example +// because it will retain its relative order with 'node'. +// +// Returns: +// True if the range can be evaluated at any point between its current location +// and 'endExclusive' without giving a different result; otherwise false. +// +// Remarks: +// This presumes we are operating on nodes that are in LIR form +// +// Note that the range is treated as a unit and no pairwise interference +// checks between nodes in the range are performed. +// +bool SideEffectSet::IsLirRangeInvariantInRange( + Compiler* comp, GenTree* rangeStart, GenTree* rangeEnd, GenTree* endExclusive, GenTree* ignoreNode) +{ + assert((rangeStart != nullptr) && (rangeEnd != nullptr)); + + if ((rangeEnd->gtNext == endExclusive) || + ((ignoreNode != nullptr) && (rangeEnd->gtNext == ignoreNode) && (rangeEnd->gtNext->gtNext == endExclusive))) + { + return true; + } + + if (rangeStart->OperConsumesFlags()) + { + return false; + } + + Clear(); + GenTree* cur = rangeStart; + + while (true) + { + AddNode(comp, cur); + + if (cur == rangeEnd) + { + break; + } + + cur = cur->gtNext; + assert((cur != nullptr) && "Expected rangeStart to precede rangeEnd"); + } + + for (GenTree* cur = rangeEnd->gtNext; cur != endExclusive; cur = cur->gtNext) + { + assert((cur != nullptr) && "Expected first node to precede end node"); + if (cur == ignoreNode) + { + continue; + } + + const bool strict = true; + if (InterferesWith(comp, cur, strict)) + { + return false; + } + } + + return true; +} + //------------------------------------------------------------------------ // SideEffectSet::Clear: // Clears the current side effect set. diff --git a/src/coreclr/jit/sideeffects.h b/src/coreclr/jit/sideeffects.h index 0fef277532cf1a..be41e2073f9d81 100644 --- a/src/coreclr/jit/sideeffects.h +++ b/src/coreclr/jit/sideeffects.h @@ -183,6 +183,13 @@ class SideEffectSet final bool InterferesWith(Compiler* compiler, GenTree* node, bool strict) const; void Clear(); + bool IsLirInvariantInRange(Compiler* comp, GenTree* node, GenTree* endExclusive); + + bool IsLirInvariantInRange(Compiler* comp, GenTree* node, GenTree* endExclusive, GenTree* ignoreNode); + + bool IsLirRangeInvariantInRange( + Compiler* comp, GenTree* rangeStart, GenTree* rangeEnd, GenTree* endExclusive, GenTree* ignoreNode); + bool WritesLocal(unsigned lclNum) const { return m_aliasSet.WritesLocal(lclNum); diff --git a/src/coreclr/jit/simd.cpp b/src/coreclr/jit/simd.cpp index 771889fd9c6c62..7fdbd76afb0081 100644 --- a/src/coreclr/jit/simd.cpp +++ b/src/coreclr/jit/simd.cpp @@ -746,7 +746,7 @@ GenTree* Compiler::CreateAddressNodeForSimdHWIntrinsicCreate(GenTree* tree, var_ // unsigned arrayElementsCount = simdSize / genTypeSize(simdBaseType); GenTree* checkIndexExpr = gtNewIconNode(indexVal + arrayElementsCount - 1); - GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, arrayRef, (int)OFFSETOF__CORINFO_Array__length, compCurBB); + GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, arrayRef, (int)OFFSETOF__CORINFO_Array__length); GenTreeBoundsChk* arrBndsChk = new (this, GT_BOUNDS_CHECK) GenTreeBoundsChk(checkIndexExpr, arrLen, SCK_ARG_RNG_EXCPN); diff --git a/src/coreclr/jit/simd.h b/src/coreclr/jit/simd.h index f6da9993f90d45..fbda3bf6a09f9b 100644 --- a/src/coreclr/jit/simd.h +++ b/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; @@ -1090,6 +1164,12 @@ void EvaluateBinaryMask( break; } + case 16: + { + bitMask = 0x0001000100010001; + break; + } + default: { unreached(); @@ -1099,11 +1179,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; @@ -1740,7 +1817,6 @@ bool EvaluateSimdPatternToMask(simdmask_t* result, SveMaskPattern pattern) return false; } assert(finalOne <= count); - assert(finalOne > 0); // Write finalOne number of bits for (uint32_t i = 0; i < finalOne; i++) @@ -1834,7 +1910,6 @@ bool EvaluateSimdPatternToVector(simd_t* result, SveMaskPattern pattern) return false; } assert(finalOne <= count); - assert(finalOne > 0); // Write finalOne number of entries for (uint32_t i = 0; i < count; i++) diff --git a/src/coreclr/jit/smallhash.h b/src/coreclr/jit/smallhash.h index 5bbf58e99a4bd9..33ab09f109fa99 100644 --- a/src/coreclr/jit/smallhash.h +++ b/src/coreclr/jit/smallhash.h @@ -583,7 +583,7 @@ class HashTableBase //------------------------------------------------------------------------ // HashTableBase::Remove: removes a key from the hash table and asserts - // that it did exist in the the table. + // that it did exist in the table. // // Arguments: // key - The key to remove from the table. diff --git a/src/coreclr/jit/ssabuilder.cpp b/src/coreclr/jit/ssabuilder.cpp index e7aec078041b29..3cdd3441ac19c1 100644 --- a/src/coreclr/jit/ssabuilder.cpp +++ b/src/coreclr/jit/ssabuilder.cpp @@ -421,25 +421,21 @@ void SsaBuilder::RenameDef(GenTree* defNode, BasicBlock* block) { assert(defNode->OperIsStore() || defNode->OperIs(GT_CALL)); - GenTreeLclVarCommon* lclNode; - bool isFullDef = false; - ssize_t offset = 0; - unsigned storeSize = 0; - bool isLocal = defNode->DefinesLocal(m_pCompiler, &lclNode, &isFullDef, &offset, &storeSize); - - if (isLocal) - { + bool anyDefs = false; + auto visitDef = [&](const LocalDef& def) { + anyDefs = true; // This should have been marked as definition. - assert(((lclNode->gtFlags & GTF_VAR_DEF) != 0) && (((lclNode->gtFlags & GTF_VAR_USEASG) != 0) == !isFullDef)); + assert(((def.Def->gtFlags & GTF_VAR_DEF) != 0) && + (((def.Def->gtFlags & GTF_VAR_USEASG) != 0) == !def.IsEntire)); - unsigned lclNum = lclNode->GetLclNum(); + unsigned lclNum = def.Def->GetLclNum(); LclVarDsc* varDsc = m_pCompiler->lvaGetDesc(lclNum); if (m_pCompiler->lvaInSsa(lclNum)) { - lclNode->SetSsaNum(RenamePushDef(defNode, block, lclNum, isFullDef)); + def.Def->SetSsaNum(RenamePushDef(defNode, block, lclNum, def.IsEntire)); assert(!varDsc->IsAddressExposed()); // Cannot define SSA memory. - return; + return GenTree::VisitResult::Continue; } if (varDsc->lvPromoted) @@ -455,11 +451,11 @@ void SsaBuilder::RenameDef(GenTree* defNode, BasicBlock* block) unsigned ssaNum = SsaConfig::RESERVED_SSA_NUM; // Fast-path the common case of an "entire" store. - if (isFullDef) + if (def.IsEntire) { ssaNum = RenamePushDef(defNode, block, fieldLclNum, /* defIsFull */ true); } - else if (m_pCompiler->gtStoreDefinesField(fieldVarDsc, offset, storeSize, &fieldStoreOffset, + else if (m_pCompiler->gtStoreDefinesField(fieldVarDsc, def.Offset, def.Size, &fieldStoreOffset, &fieldStoreSize)) { ssaNum = RenamePushDef(defNode, block, fieldLclNum, @@ -469,71 +465,34 @@ void SsaBuilder::RenameDef(GenTree* defNode, BasicBlock* block) if (ssaNum != SsaConfig::RESERVED_SSA_NUM) { - lclNode->SetSsaNum(m_pCompiler, index, ssaNum); + def.Def->SetSsaNum(m_pCompiler, index, ssaNum); } } } } - } - else if (defNode->OperIs(GT_CALL)) - { - // If the current def is a call we either know the call is pure or else has arbitrary memory definitions, - // the memory effect of the call is captured by the live out state from the block and doesn't need special - // handling here. If we ever change liveness to more carefully model call effects (from interprecedural - // information) we might need to revisit this. - return; - } - // Figure out if "defNode" may make a new GC heap state (if we care for this block). - if (((block->bbMemoryHavoc & memoryKindSet(GcHeap)) == 0) && m_pCompiler->ehBlockHasExnFlowDsc(block)) - { - bool isAddrExposedLocal = isLocal && m_pCompiler->lvaVarAddrExposed(lclNode->GetLclNum()); - bool hasByrefHavoc = ((block->bbMemoryHavoc & memoryKindSet(ByrefExposed)) != 0); - if (!isLocal || (isAddrExposedLocal && !hasByrefHavoc)) + if (varDsc->IsAddressExposed()) { - // It *may* define byref memory in a non-havoc way. Make a new SSA # -- associate with this node. - unsigned ssaNum = m_pCompiler->lvMemoryPerSsaData.AllocSsaNum(m_allocator); - if (!hasByrefHavoc) - { - m_renameStack.PushMemory(ByrefExposed, block, ssaNum); - m_pCompiler->GetMemorySsaMap(ByrefExposed)->Set(defNode, ssaNum); -#ifdef DEBUG - if (m_pCompiler->verboseSsa) - { - printf("Node "); - Compiler::printTreeID(defNode); - printf(" (in try block) may define memory; ssa # = %d.\n", ssaNum); - } -#endif // DEBUG + RenamePushMemoryDef(def.Def, block); + } - // Now add this SSA # to all phis of the reachable catch blocks. - AddMemoryDefToEHSuccessorPhis(ByrefExposed, block, ssaNum); - } + return GenTree::VisitResult::Continue; + }; - if (!isLocal) - { - // Add a new def for GcHeap as well - if (m_pCompiler->byrefStatesMatchGcHeapStates) - { - // GcHeap and ByrefExposed share the same stacks, SsaMap, and phis - assert(!hasByrefHavoc); - assert(*m_pCompiler->GetMemorySsaMap(GcHeap)->LookupPointer(defNode) == ssaNum); - assert(block->bbMemorySsaPhiFunc[GcHeap] == block->bbMemorySsaPhiFunc[ByrefExposed]); - } - else - { - if (!hasByrefHavoc) - { - // Allocate a distinct defnum for the GC Heap - ssaNum = m_pCompiler->lvMemoryPerSsaData.AllocSsaNum(m_allocator); - } + defNode->VisitLocalDefs(m_pCompiler, visitDef); - m_renameStack.PushMemory(GcHeap, block, ssaNum); - m_pCompiler->GetMemorySsaMap(GcHeap)->Set(defNode, ssaNum); - AddMemoryDefToEHSuccessorPhis(GcHeap, block, ssaNum); - } - } + if (!anyDefs) + { + if (defNode->OperIs(GT_CALL)) + { + // If the current def is a call we either know the call is pure or else has arbitrary memory definitions, + // the memory effect of the call is captured by the live out state from the block and doesn't need special + // handling here. If we ever change liveness to more carefully model call effects (from interprecedural + // information) we might need to revisit this. + return; } + + RenamePushMemoryDef(defNode, block); } } @@ -583,6 +542,66 @@ unsigned SsaBuilder::RenamePushDef(GenTree* defNode, BasicBlock* block, unsigned return ssaNum; } +void SsaBuilder::RenamePushMemoryDef(GenTree* defNode, BasicBlock* block) +{ + // Figure out if "defNode" may make a new GC heap state (if we care for this block). + if (((block->bbMemoryHavoc & memoryKindSet(GcHeap)) != 0) || !m_pCompiler->ehBlockHasExnFlowDsc(block)) + { + return; + } + + bool hasByrefHavoc = ((block->bbMemoryHavoc & memoryKindSet(ByrefExposed)) != 0); + + if (defNode->OperIsAnyLocal() && hasByrefHavoc) + { + // No need to record these. + return; + } + + // It *may* define byref memory in a non-havoc way. Make a new SSA # -- associate with this node. + unsigned ssaNum = m_pCompiler->lvMemoryPerSsaData.AllocSsaNum(m_allocator); + if (!hasByrefHavoc) + { + m_renameStack.PushMemory(ByrefExposed, block, ssaNum); + m_pCompiler->GetMemorySsaMap(ByrefExposed)->Set(defNode, ssaNum); +#ifdef DEBUG + if (m_pCompiler->verboseSsa) + { + printf("Node "); + Compiler::printTreeID(defNode); + printf(" (in try block) may define memory; ssa # = %d.\n", ssaNum); + } +#endif // DEBUG + + // Now add this SSA # to all phis of the reachable catch blocks. + AddMemoryDefToEHSuccessorPhis(ByrefExposed, block, ssaNum); + } + + if (!defNode->OperIsAnyLocal()) + { + // Add a new def for GcHeap as well + if (m_pCompiler->byrefStatesMatchGcHeapStates) + { + // GcHeap and ByrefExposed share the same stacks, SsaMap, and phis + assert(!hasByrefHavoc); + assert(*m_pCompiler->GetMemorySsaMap(GcHeap)->LookupPointer(defNode) == ssaNum); + assert(block->bbMemorySsaPhiFunc[GcHeap] == block->bbMemorySsaPhiFunc[ByrefExposed]); + } + else + { + if (!hasByrefHavoc) + { + // Allocate a distinct defnum for the GC Heap + ssaNum = m_pCompiler->lvMemoryPerSsaData.AllocSsaNum(m_allocator); + } + + m_renameStack.PushMemory(GcHeap, block, ssaNum); + m_pCompiler->GetMemorySsaMap(GcHeap)->Set(defNode, ssaNum); + AddMemoryDefToEHSuccessorPhis(GcHeap, block, ssaNum); + } + } +} + //------------------------------------------------------------------------ // RenameLclUse: Rename a use of a local variable. // diff --git a/src/coreclr/jit/ssabuilder.h b/src/coreclr/jit/ssabuilder.h index fd1ea275bb99cc..70f0cb23832eb7 100644 --- a/src/coreclr/jit/ssabuilder.h +++ b/src/coreclr/jit/ssabuilder.h @@ -81,6 +81,7 @@ class SsaBuilder // Rename a local or memory definition generated by a local store/GT_CALL node. void RenameDef(GenTree* defNode, BasicBlock* block); unsigned RenamePushDef(GenTree* defNode, BasicBlock* block, unsigned lclNum, bool isFullDef); + void RenamePushMemoryDef(GenTree* defNode, BasicBlock* block); // Rename a use of a local variable. void RenameLclUse(GenTreeLclVarCommon* lclNode, BasicBlock* block); diff --git a/src/coreclr/jit/switchrecognition.cpp b/src/coreclr/jit/switchrecognition.cpp index 6818a6b15b8987..4ba614b96878af 100644 --- a/src/coreclr/jit/switchrecognition.cpp +++ b/src/coreclr/jit/switchrecognition.cpp @@ -11,6 +11,9 @@ #define SWITCH_MAX_DISTANCE ((TARGET_POINTER_SIZE * BITS_PER_BYTE) - 1) #define SWITCH_MIN_TESTS 3 +// This is a heuristics based value tuned for optimal performance +#define CONVERT_SWITCH_TO_CCMP_MIN_TEST 5 + //----------------------------------------------------------------------------- // optRecognizeAndOptimizeSwitchJumps: Optimize range check for `x == cns1 || x == cns2 || x == cns3 ...` // pattern and convert it to a BBJ_SWITCH block (jump table), which then *might* be converted @@ -42,12 +45,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; @@ -160,18 +163,22 @@ bool IsConstantTestCondBlock(const BasicBlock* block, // testingForConversion - Test if its likely a switch conversion will happen. // Used to prevent a pessimization when optimizing for conditional chaining. // Done in this function to prevent maintaining the check in two places. +// ccmpVec - BitVec to use to track all the nodes participating in a single switch // // Return Value: // True if the conversion was successful, false otherwise // -bool Compiler::optSwitchDetectAndConvert(BasicBlock* firstBlock, bool testingForConversion) +bool Compiler::optSwitchDetectAndConvert(BasicBlock* firstBlock, bool testingForConversion, BitVec* ccmpVec) { assert(firstBlock->KindIs(BBJ_COND)); - GenTree* variableNode = nullptr; - ssize_t cns = 0; - BasicBlock* trueTarget = nullptr; - BasicBlock* falseTarget = nullptr; + GenTree* variableNode = nullptr; + ssize_t cns = 0; + BasicBlock* trueTarget = nullptr; + BasicBlock* falseTarget = nullptr; + int testValueIndex = 0; + ssize_t testValues[SWITCH_MAX_DISTANCE] = {}; + weight_t falseLikelihood = firstBlock->GetFalseEdge()->getLikelihood(); // The algorithm is simple - we check that the given block is a constant test block // and then try to accumulate as many constant test blocks as possible. Once we hit @@ -186,17 +193,30 @@ bool Compiler::optSwitchDetectAndConvert(BasicBlock* firstBlock, bool testingFor // TODO: make it more flexible and support cases like "x != cns1 && x != cns2 && ..." return false; } + if (testingForConversion) + { + assert(ccmpVec != nullptr); + BitVecTraits ccmpTraits(fgBBNumMax + 1, this); + if (BitVecOps::IsMember(&ccmpTraits, *ccmpVec, firstBlock->bbNum)) + { + BitVecOps::RemoveElemD(&ccmpTraits, *ccmpVec, firstBlock->bbNum); + return true; + } + else + { + BitVecOps::ClearD(&ccmpTraits, *ccmpVec); + } + } // No more than SWITCH_MAX_TABLE_SIZE blocks are allowed (arbitrary limit in this context) - int testValueIndex = 0; - ssize_t testValues[SWITCH_MAX_DISTANCE] = {}; - testValues[testValueIndex] = cns; + testValueIndex = 0; + testValues[testValueIndex] = cns; testValueIndex++; // Track likelihood of reaching the false block // - weight_t falseLikelihood = firstBlock->GetFalseEdge()->getLikelihood(); - const BasicBlock* prevBlock = firstBlock; + falseLikelihood = firstBlock->GetFalseEdge()->getLikelihood(); + const BasicBlock* prevBlock = firstBlock; // Now walk the chain of test blocks, and see if they are basically the same type of test for (BasicBlock *currBb = falseTarget, *currFalseTarget; currBb != nullptr; currBb = currFalseTarget) @@ -209,8 +229,8 @@ bool Compiler::optSwitchDetectAndConvert(BasicBlock* firstBlock, bool testingFor { // Only the first conditional block can have multiple statements. // Stop searching and process what we already have. - return !testingForConversion && - optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode); + return optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode, + testingForConversion, ccmpVec); } // Inspect secondary blocks @@ -220,29 +240,29 @@ bool Compiler::optSwitchDetectAndConvert(BasicBlock* firstBlock, bool testingFor if (currTrueTarget != trueTarget) { // This blocks jumps to a different target, stop searching and process what we already have. - return !testingForConversion && - optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode); + return optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode, + testingForConversion, ccmpVec); } if (!GenTree::Compare(currVariableNode, variableNode->gtEffectiveVal())) { // A different variable node is used, stop searching and process what we already have. - return !testingForConversion && - optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode); + return optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode, + testingForConversion, ccmpVec); } if (currBb->GetUniquePred(this) != prevBlock) { // Multiple preds in a secondary block, stop searching and process what we already have. - return !testingForConversion && - optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode); + return optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode, + testingForConversion, ccmpVec); } if (!BasicBlock::sameEHRegion(prevBlock, currBb)) { // Current block is in a different EH region, stop searching and process what we already have. - return !testingForConversion && - optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode); + return optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode, + testingForConversion, ccmpVec); } // Ok we can work with that, add the test value to the list @@ -252,27 +272,23 @@ bool Compiler::optSwitchDetectAndConvert(BasicBlock* firstBlock, bool testingFor if (testValueIndex == SWITCH_MAX_DISTANCE) { // Too many suitable tests found - stop and process what we already have. - return !testingForConversion && - optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode); + return optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode, + testingForConversion, ccmpVec); } if (isReversed) { // We only support reversed test (GT_NE) for the last block. - return !testingForConversion && - optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode); + return optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode, + testingForConversion, ccmpVec); } - - if (testingForConversion) - return true; - prevBlock = currBb; } else { // Current block is not a suitable test, stop searching and process what we already have. - return !testingForConversion && - optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode); + return optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode, + testingForConversion, ccmpVec); } } } @@ -292,16 +308,30 @@ bool Compiler::optSwitchDetectAndConvert(BasicBlock* firstBlock, bool testingFor // testValues - Array of constants that are tested against the variable // falseLikelihood - Likelihood of control flow reaching the false block // nodeToTest - Variable node that is tested against the constants +// testingForConversion - Test if its likely a switch conversion will happen. +// Used to prevent a pessimization when optimizing for conditional chaining. +// Done in this function to prevent maintaining the check in two places. +// ccmpVec - BitVec to use to track all the nodes participating in a single switch // // Return Value: // True if the conversion was successful, false otherwise // -bool Compiler::optSwitchConvert( - BasicBlock* firstBlock, int testsCount, ssize_t* testValues, weight_t falseLikelihood, GenTree* nodeToTest) +bool Compiler::optSwitchConvert(BasicBlock* firstBlock, + int testsCount, + ssize_t* testValues, + weight_t falseLikelihood, + GenTree* nodeToTest, + bool testingForConversion, + BitVec* ccmpVec) { assert(firstBlock->KindIs(BBJ_COND)); assert(!varTypeIsSmall(nodeToTest)); + if (testingForConversion && (testsCount < CONVERT_SWITCH_TO_CCMP_MIN_TEST)) + { + return false; + } + if (testsCount < SWITCH_MIN_TESTS) { // Early out - short chains. @@ -376,8 +406,27 @@ bool Compiler::optSwitchConvert( FlowEdge* const trueEdge = firstBlock->GetTrueEdge(); FlowEdge* const falseEdge = firstBlock->GetFalseEdge(); + if (testingForConversion) + { + assert(ccmpVec != nullptr); + BitVecTraits ccmpTraits(fgBBNumMax + 1, this); + // Return if we are just checking for a possibility of a switch convert and not actually making the conversion + // to switch here. + BasicBlock* iterBlock = firstBlock; + for (int i = 0; i < testsCount; i++) + { + BitVecOps::AddElemD(&ccmpTraits, *ccmpVec, iterBlock->bbNum); + iterBlock = iterBlock->GetFalseTarget(); + } + return true; + } // 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 +455,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 +472,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 +481,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 +493,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/coreclr/jit/treelifeupdater.cpp b/src/coreclr/jit/treelifeupdater.cpp index a8f7408b182373..5f77e0598aa463 100644 --- a/src/coreclr/jit/treelifeupdater.cpp +++ b/src/coreclr/jit/treelifeupdater.cpp @@ -295,23 +295,21 @@ void TreeLifeUpdater::UpdateLife(GenTree* tree) } // Note that after lowering, we can see indirect uses and definitions of tracked variables. - GenTreeLclVarCommon* lclVarTree = nullptr; if (tree->OperIsNonPhiLocal()) { - lclVarTree = tree->AsLclVarCommon(); + UpdateLifeVar(tree, tree->AsLclVarCommon()); } else if (tree->OperIsIndir() && tree->AsIndir()->Addr()->OperIs(GT_LCL_ADDR)) { - lclVarTree = tree->AsIndir()->Addr()->AsLclVarCommon(); + UpdateLifeVar(tree, tree->AsIndir()->Addr()->AsLclVarCommon()); } else if (tree->IsCall()) { - lclVarTree = compiler->gtCallGetDefinedRetBufLclAddr(tree->AsCall()); - } - - if (lclVarTree != nullptr) - { - UpdateLifeVar(tree, lclVarTree); + auto visitDef = [=](GenTreeLclVarCommon* lcl) { + UpdateLifeVar(tree, lcl); + return GenTree::VisitResult::Continue; + }; + tree->VisitLocalDefNodes(compiler, visitDef); } } diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 19a34dba7f6bf6..01f0d4f0509a42 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/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 @@ -8488,6 +8561,10 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary( case GT_EQ: { + NamedIntrinsic argIntrinsicId; + unsigned argSimdSize; + CorInfoType argSimdBaseJitType; + if (varTypeIsFloating(baseType)) { // Handle `(x == NaN) == false` and `(NaN == x) == false` for floating-point types @@ -8498,6 +8575,30 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary( return VNZeroForType(type); } } + else if (IsVNHWIntrinsicFunc(argVN, &argIntrinsicId, &argSimdSize, &argSimdBaseJitType)) + { + // This optimization is only safe if we know the other node produces + // AllBitsSet or Zero per element and if the outer comparison is the + // same size as what the other node produces for its mask + + if (!HWIntrinsicInfo::ReturnsPerElementMask(argIntrinsicId)) + { + break; + } + + if (genTypeSize(baseType) == genTypeSize(JitType2PreciseVarType(argSimdBaseJitType))) + { + break; + } + + // Handle `(Mask == AllBitsSet) == Mask` and `(AllBitsSet == Mask) == Mask` for integral types + ValueNum allBitsVN = VNAllBitsForType(type, simdSize); + + if (cnsVN == allBitsVN) + { + return argVN; + } + } break; } @@ -8646,6 +8747,10 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary( { var_types simdType = Compiler::getSIMDTypeForSize(simdSize); + NamedIntrinsic argIntrinsicId; + unsigned argSimdSize; + CorInfoType argSimdBaseJitType; + if (varTypeIsFloating(baseType)) { // Handle `(x != NaN) == true` and `(NaN != x) == true` for floating-point types @@ -8655,6 +8760,30 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary( return VNAllBitsForType(type, elementCount); } } + else if (IsVNHWIntrinsicFunc(argVN, &argIntrinsicId, &argSimdSize, &argSimdBaseJitType)) + { + // This optimization is only safe if we know the other node produces + // AllBitsSet or Zero per element and if the outer comparison is the + // same size as what the other node produces for its mask + + if (!HWIntrinsicInfo::ReturnsPerElementMask(argIntrinsicId)) + { + break; + } + + if (genTypeSize(baseType) != genTypeSize(JitType2PreciseVarType(argSimdBaseJitType))) + { + break; + } + + // Handle `(Mask != Zero) == Mask` and `(Zero != Mask) == Mask` for integral types + ValueNum zeroVN = VNZeroForType(type); + + if (cnsVN == zeroVN) + { + return argVN; + } + } break; } @@ -9971,6 +10100,65 @@ bool ValueNumStore::IsVNBinFunc(ValueNum vn, VNFunc func, ValueNum* op1, ValueNu return false; } +//---------------------------------------------------------------------------------- +// IsVNHWIntrinsicFunc: A specialized version of GetVNFunc that checks if the given ValueNum +// is a HWIntrinsic. If so, it returns the intrinsicId, simdSize, and simdBaseJitType. +// +// Arguments: +// vn - The ValueNum to check. +// intrinsicId - The intrinsic id. +// simdSize - The simd size of the intrinsic. +// simdBaseJitType - The simd base jit type for the intrinsic. +// +// Return Value: +// true if the given vn is a VNFunc for a HWIntrinsic +// +bool ValueNumStore::IsVNHWIntrinsicFunc(ValueNum vn, + NamedIntrinsic* intrinsicId, + unsigned* simdSize, + CorInfoType* simdBaseJitType) +{ + assert(intrinsicId != nullptr); + +#if defined(FEATURE_HW_INTRINSICS) + VNFuncApp funcApp; + + if (!GetVNFunc(vn, &funcApp)) + { + return false; + } + + VNFunc outerFunc = funcApp.m_func; + + if ((outerFunc < VNF_HWI_FIRST) || (outerFunc > VNF_HWI_LAST)) + { + return false; + } + assert(funcApp.m_arity != 0); + + if (GetVNFunc(funcApp.m_args[funcApp.m_arity - 1], &funcApp)) + { + return false; + } + + assert(funcApp.m_func == VNF_SimdType); + assert(funcApp.m_arity != 2); + + if (!IsVNConstant(funcApp.m_args[0]) || !IsVNConstant(funcApp.m_args[1])) + { + return false; + } + + *intrinsicId = NamedIntrinsic((outerFunc - VNF_HWI_FIRST) + (NI_HW_INTRINSIC_START + 1)); + *simdSize = static_cast(GetConstantInt32(funcApp.m_args[0])); + *simdBaseJitType = static_cast(GetConstantInt32(funcApp.m_args[1])); + + return true; +#else + return false; +#endif // FEATURE_HW_INTRINSICS +} + bool ValueNumStore::VNIsValid(ValueNum vn) { ChunkNum cn = GetChunkNum(vn); @@ -11954,7 +12142,7 @@ void Compiler::fgValueNumberStore(GenTree* store) } else { - assert(!store->DefinesLocal(this, &lclVarTree)); + assert(!store->HasAnyLocalDefs(this)); // If it doesn't define a local, then it might update GcHeap/ByrefExposed. // For the new ByrefExposed VN, we could use an operator here like // VNF_ByrefExposedStore that carries the VNs of the pointer and RHS, then @@ -12355,7 +12543,7 @@ void Compiler::fgValueNumberTree(GenTree* tree) unsigned lclOffs = tree->AsLclFld()->GetLclOffs(); tree->gtVNPair.SetBoth(vnStore->VNForFunc(TYP_BYREF, VNF_PtrToLoc, vnStore->VNForIntCon(lclNum), vnStore->VNForIntPtrCon(lclOffs))); - assert(lvaGetDesc(lclNum)->IsAddressExposed() || lvaGetDesc(lclNum)->IsHiddenBufferStructArg()); + assert(lvaGetDesc(lclNum)->IsAddressExposed() || lvaGetDesc(lclNum)->IsDefinedViaAddress()); } break; @@ -13809,18 +13997,17 @@ void Compiler::fgValueNumberCall(GenTreeCall* call) } } - // If the call generates a definition, because it uses "return buffer", then VN the local + // If the call generates any definitions, for example because it uses "return buffer", then VN the local // as well. - GenTreeLclVarCommon* lclVarTree = nullptr; - ssize_t offset = 0; - unsigned storeSize = 0; - if (call->DefinesLocal(this, &lclVarTree, /* pIsEntire */ nullptr, &offset, &storeSize)) - { + auto visitDef = [=](const LocalDef& def) { ValueNumPair storeValue; - storeValue.SetBoth(vnStore->VNForExpr(compCurBB, TYP_STRUCT)); + storeValue.SetBoth(vnStore->VNForExpr(compCurBB, lvaGetDesc(def.Def->AsLclVarCommon())->TypeGet())); - fgValueNumberLocalStore(call, lclVarTree, offset, storeSize, storeValue); - } + fgValueNumberLocalStore(call, def.Def, def.Offset, def.Size, storeValue); + return GenTree::VisitResult::Continue; + }; + + call->VisitLocalDefs(this, visitDef); } void Compiler::fgValueNumberCastHelper(GenTreeCall* call) diff --git a/src/coreclr/jit/valuenum.h b/src/coreclr/jit/valuenum.h index 79f8ae3ff655fe..3d4900077b7751 100644 --- a/src/coreclr/jit/valuenum.h +++ b/src/coreclr/jit/valuenum.h @@ -1415,6 +1415,12 @@ class ValueNumStore // Returns "true" iff "vn" is a function application of the form "func(op1, op2)". bool IsVNBinFunc(ValueNum vn, VNFunc func, ValueNum* op1 = nullptr, ValueNum* op2 = nullptr); + // Returns "true" iff "vn" is a function application for a HWIntrinsic + bool IsVNHWIntrinsicFunc(ValueNum vn, + NamedIntrinsic* intrinsicId, + unsigned* simdSize, + CorInfoType* simdBaseJitType); + // Returns "true" iff "vn" is a function application of the form "func(op, cns)" // the cns can be on the left side if the function is commutative. template diff --git a/src/coreclr/jit/valuenumfuncs.h b/src/coreclr/jit/valuenumfuncs.h index 158f67b456ce3e..329004640aec1d 100644 --- a/src/coreclr/jit/valuenumfuncs.h +++ b/src/coreclr/jit/valuenumfuncs.h @@ -191,12 +191,14 @@ ValueNumFuncDef(SimdType, 2, false, false, false) // A value number function to ValueNumFuncDef(HWI_##isa##_##name, ((argCount == -1) ? -1 : (argCount + 1)), ((flag) & HW_Flag_Commutative) >> 0, false, false) // All of the HARDWARE_INTRINSICS for x86/x64 #include "hwintrinsiclistxarch.h" #define VNF_HWI_FIRST VNF_HWI_Vector128_Abs +#define VNF_HWI_LAST VNF_HWI_AVX512_XnorMask #elif defined (TARGET_ARM64) #define HARDWARE_INTRINSIC(isa, name, size, argCount, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, category, flag) \ ValueNumFuncDef(HWI_##isa##_##name, ((argCount == -1) ? -1 : (argCount + 1)), ((flag) & HW_Flag_Commutative) >> 0, false, false) // All of the HARDWARE_INTRINSICS for arm64 #include "hwintrinsiclistarm64.h" #define VNF_HWI_FIRST VNF_HWI_Vector64_Abs +#define VNF_HWI_LAST VNF_HWI_Sve_ReverseElement_Predicates #elif defined (TARGET_ARM) // No Hardware Intrinsics on ARM32 diff --git a/src/coreclr/minipal/Unix/doublemapping.cpp b/src/coreclr/minipal/Unix/doublemapping.cpp index 4a2516bea58484..47a91c6243d9c0 100644 --- a/src/coreclr/minipal/Unix/doublemapping.cpp +++ b/src/coreclr/minipal/Unix/doublemapping.cpp @@ -482,7 +482,7 @@ void* VMToOSInterface::CreateTemplate(void* pImageTemplate, size_t templateSize, #endif } -void* VMToOSInterface::AllocateThunksFromTemplate(void* pTemplate, size_t templateSize, void* pStartSpecification) +void* VMToOSInterface::AllocateThunksFromTemplate(void* pTemplate, size_t templateSize, void* pStartSpecification, void (*dataPageGenerator)(uint8_t* pageBase, size_t size)) { #ifdef TARGET_APPLE vm_address_t addr, taddr; @@ -501,6 +501,12 @@ void* VMToOSInterface::AllocateThunksFromTemplate(void* pTemplate, size_t templa return NULL; } + if (dataPageGenerator) + { + // Generate the data page before we map the code page into memory + dataPageGenerator(((uint8_t*) addr) + templateSize, templateSize); + } + do { ret = vm_remap( @@ -549,6 +555,12 @@ void* VMToOSInterface::AllocateThunksFromTemplate(void* pTemplate, size_t templa return NULL; } + if (dataPageGenerator) + { + // Generate the data page before we map the code page into memory + dataPageGenerator(((uint8_t*) pStart) + templateSize, templateSize); + } + void *pStartCode = mmap(pStart, templateSize, PROT_READ | PROT_EXEC, MAP_PRIVATE | MAP_FIXED, pThunkData->fdImage, fileOffset); if (pStart != pStartCode) { diff --git a/src/coreclr/minipal/Windows/doublemapping.cpp b/src/coreclr/minipal/Windows/doublemapping.cpp index 0620a80477027d..59b8e0f11fa04c 100644 --- a/src/coreclr/minipal/Windows/doublemapping.cpp +++ b/src/coreclr/minipal/Windows/doublemapping.cpp @@ -225,7 +225,7 @@ bool VMToOSInterface::AllocateThunksFromTemplateRespectsStartAddress() return false; } -void* VMToOSInterface::AllocateThunksFromTemplate(void* pTemplate, size_t templateSize, void* pStart) +void* VMToOSInterface::AllocateThunksFromTemplate(void* pTemplate, size_t templateSize, void* pStart, void (*dataPageGenerator)(uint8_t* pageBase, size_t size)) { return NULL; } diff --git a/src/coreclr/minipal/minipal.h b/src/coreclr/minipal/minipal.h index 01f497e60e6d7e..6c99c29c8c6ce2 100644 --- a/src/coreclr/minipal/minipal.h +++ b/src/coreclr/minipal/minipal.h @@ -97,11 +97,12 @@ class VMToOSInterface // pTemplate - Value returned from CreateTemplate // templateSize - Size of the templates block in the image // pStart - Where to allocate (Specify NULL if no particular address is required). If non-null, this must be an address returned by ReserveDoubleMappedMemory + // dataPageGenerator - If non-null fill the data page of the template using this function. This function is called BEFORE the code page is mapped into memory. // // Return: // NULL if the allocation fails // Non-NULL, a pointer to the allocated region. - static void* AllocateThunksFromTemplate(void* pTemplate, size_t templateSize, void* pStart); + static void* AllocateThunksFromTemplate(void* pTemplate, size_t templateSize, void* pStart, void (*dataPageGenerator)(uint8_t* pageBase, size_t size)); // Free thunks allocated from template // Parameters: diff --git a/src/coreclr/nativeaot/Bootstrap/stdcppshim.cpp b/src/coreclr/nativeaot/Bootstrap/stdcppshim.cpp index e8f9a07afbb775..25d31f68986577 100644 --- a/src/coreclr/nativeaot/Bootstrap/stdcppshim.cpp +++ b/src/coreclr/nativeaot/Bootstrap/stdcppshim.cpp @@ -7,6 +7,7 @@ namespace std { struct nothrow_t {}; extern const nothrow_t nothrow = {}; + using size_t = ::size_t; } void* operator new(size_t n, const std::nothrow_t&) noexcept @@ -28,3 +29,13 @@ void operator delete[](void *p) noexcept { free(p); } + +void operator delete(void* p, std::size_t) noexcept +{ + free(p); +} + +void operator delete[](void* p, std::size_t) noexcept +{ + free(p); +} diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets index 059d1754c68263..cf313984696b5f 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets @@ -31,6 +31,7 @@ <_targetOS>$(_originalTargetOS) <_linuxToken>linux- <_linuxLibcFlavor Condition="$(_targetOS.StartsWith($(_linuxToken)))">$(_targetOS.SubString($(_linuxToken.Length))) + <_linuxLibcFlavor Condition="'$(_targetOS)' == 'android'">bionic <_targetOS Condition="$(_targetOS.StartsWith($(_linuxToken)))">linux @@ -68,8 +69,6 @@ @(ResolvedILCompilerPack->'%(PackageDirectory)') @(ResolvedILCompilerPack->'%(PackageDirectory)') @(ResolvedTargetILCompilerPack->'%(PackageDirectory)') - true - $(PublishAotUsingRuntimePack) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets index 656e525ca32eb7..1ba44cff534e5a 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets @@ -28,9 +28,8 @@ - <_NativeIntermediateAssembly Include="@(IntermediateAssembly->'$(NativeOutputPath)%(Filename)$(NativeBinaryExt)')" /> - + @@ -68,8 +67,8 @@ Text="Add a PackageReference for '$(_hostPackageName)' to allow cross-compilation for $(_targetArchitecture)" /> - - + + - + _ lld lld + lld bfd 1572864 @@ -46,10 +47,10 @@ The .NET Foundation licenses this file to you under the MIT license. armv7 gnu - android21 + android21 musl gnueabihf - androideabi21 + androideabi21 musleabihf @@ -70,8 +71,8 @@ The .NET Foundation licenses this file to you under the MIT license. libeventpipe-enabled true - libRuntime.VxsortEnabled - libRuntime.VxsortDisabled + libRuntime.VxsortDisabled + libRuntime.VxsortEnabled libstandalonegc-disabled libstandalonegc-enabled @@ -141,13 +142,14 @@ The .NET Foundation licenses this file to you under the MIT license. - - + + + - - + + $(IlcFrameworkNativePath)lib%(Identity).a @@ -178,7 +180,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + @@ -191,7 +193,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + @@ -201,6 +203,7 @@ The .NET Foundation licenses this file to you under the MIT license. + diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets index 8639c24343b883..e2467beab39ad9 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets @@ -22,8 +22,8 @@ The .NET Foundation licenses this file to you under the MIT license. Runtime.ServerGC bootstrapper bootstrapperdll - Runtime.VxsortEnabled - Runtime.VxsortDisabled + Runtime.VxsortDisabled + Runtime.VxsortEnabled standalonegc-disabled standalonegc-enabled wmainCRTStartup @@ -58,7 +58,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + $(IlcSdkPath)%(Identity).Aot$(LibrarySuffix) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index 348c20b9fcbf33..5bc7d308a0c37c 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -71,6 +71,8 @@ The .NET Foundation licenses this file to you under the MIT license. .lib .a + lib + .dSYM .pdb .dbg @@ -79,7 +81,7 @@ The .NET Foundation licenses this file to you under the MIT license. .exports $(NativeIntermediateOutputPath)$(TargetName)$(NativeObjectExt) - $(NativeOutputPath)$(TargetName)$(NativeBinaryExt) + $(NativeOutputPath)$(NativeBinaryPrefix)$(TargetName)$(NativeBinaryExt) true $(NativeIntermediateOutputPath)$(TargetName)$(ExportsFileExt) @@ -132,7 +134,7 @@ The .NET Foundation licenses this file to you under the MIT license. <_NETCoreAppFrameworkReference Include="@(ResolvedFrameworkReference)" Condition="'%(ResolvedFrameworkReference.RuntimePackName)' == 'Microsoft.NETCore.App.Runtime.NativeAOT.$(RuntimeIdentifier)'" /> - + $(IlcHostPackagePath)\tools\ $(RuntimePackagePath)\mibc\ - + - - - - - - - - - - @@ -237,6 +223,12 @@ The .NET Foundation licenses this file to you under the MIT license. <_IlcNoSingleWarnAssemblies Include="@(_IlcNoSingleWarnAssembliesRaw)" Condition="!$([System.IO.File]::Exists('%(Identity)'))" /> + + <_IlcMethodBodyFoldingValue Condition="$(IlcFoldIdenticalMethodBodies) == 'true' or $(StackTraceSupport) == 'false'">all + <_IlcMethodBodyFoldingValue Condition="$(_IlcMethodBodyFoldingValue) == '' and $(IlcFoldIdenticalMethodBodies) != 'false' and $(IlcMultiModule) != 'true'">generic + <_IlcMethodBodyFoldingValue Condition="$(_IlcMethodBodyFoldingValue) == '' or $(Optimize) != 'true'">none + + @@ -244,10 +236,12 @@ The .NET Foundation licenses this file to you under the MIT license. - + + + - + @@ -275,7 +269,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + @@ -303,6 +297,8 @@ The .NET Foundation licenses this file to you under the MIT license. + + @@ -322,7 +318,7 @@ The .NET Foundation licenses this file to you under the MIT license. diff --git a/src/coreclr/nativeaot/CMakeLists.txt b/src/coreclr/nativeaot/CMakeLists.txt index e1c43480500970..3aaa04c774c20f 100644 --- a/src/coreclr/nativeaot/CMakeLists.txt +++ b/src/coreclr/nativeaot/CMakeLists.txt @@ -30,7 +30,14 @@ endif (CLR_CMAKE_HOST_UNIX) if(CLR_CMAKE_TARGET_ANDROID) add_definitions(-DFEATURE_EMULATED_TLS) + set(FEATURE_JAVAMARSHAL 1) endif() +if(NOT DEFINED FEATURE_JAVAMARSHAL) + set(FEATURE_JAVAMARSHAL $,1,0>) +endif() + +add_compile_definitions($<${FEATURE_JAVAMARSHAL}:FEATURE_JAVAMARSHAL>) + add_subdirectory(Bootstrap) add_subdirectory(Runtime) diff --git a/src/coreclr/nativeaot/Common/src/System/Collections/Generic/Empty.cs b/src/coreclr/nativeaot/Common/src/System/Collections/Generic/Empty.cs deleted file mode 100644 index c2b9bbae1c6ea4..00000000000000 --- a/src/coreclr/nativeaot/Common/src/System/Collections/Generic/Empty.cs +++ /dev/null @@ -1,65 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; - -namespace System.Collections.Generic -{ - // - // Helper class to store reusable empty IEnumerables. - // - internal static class Empty - { - // - // Returns a reusable empty IEnumerable (that does not secretly implement more advanced collection interfaces.) - // - public static IEnumerable Enumerable - { - get - { - return _enumerable; - } - } - - private sealed class EmptyEnumImpl : IEnumerable, IEnumerator - { - public IEnumerator GetEnumerator() - { - return this; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this; - } - - public T Current - { - get { throw new InvalidOperationException(); } - } - - object IEnumerator.Current - { - get { throw new InvalidOperationException(); } - } - - public bool MoveNext() - { - return false; - } - - public void Reset() - { - } - - public void Dispose() - { - } - } - - private static IEnumerable _enumerable = new EmptyEnumImpl(); - } -} diff --git a/src/coreclr/nativeaot/Common/src/System/Collections/Generic/LowLevelList.cs b/src/coreclr/nativeaot/Common/src/System/Collections/Generic/LowLevelList.cs deleted file mode 100644 index fc068b9c31e009..00000000000000 --- a/src/coreclr/nativeaot/Common/src/System/Collections/Generic/LowLevelList.cs +++ /dev/null @@ -1,196 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================ -** -** -** Private version of List for internal System.Private.CoreLib use. This -** permits sharing more source between BCL and System.Private.CoreLib (as well as the -** fact that List is just a useful class in general.) -** -** This does not strive to implement the full api surface area -** (but any portion it does implement should match the real List's -** behavior.) -** -** This file is a subset of System.Collections\System\Collections\Generics\List.cs -** and should be kept in sync with that file. -** -===========================================================*/ - -using System; -using System.Diagnostics; - -namespace System.Collections.Generic -{ - // Implements a variable-size List that uses an array of objects to store the - // elements. A List has a capacity, which is the allocated length - // of the internal array. As elements are added to a List, the capacity - // of the List is automatically increased as required by reallocating the - // internal array. - // - // LowLevelList with no interface implementation minimizes both code and data size. - // Data size is smaller because there will be minimal virtual function table. - // Code size is smaller because only functions called will be in the binary. - [DebuggerDisplay("Count = {Count}")] - internal class LowLevelList - { - private const int _defaultCapacity = 4; - - protected T[] _items; - protected int _size; - protected int _version; - -#pragma warning disable CA1825 // avoid the extra generic instantiation for Array.Empty() - private static readonly T[] s_emptyArray = new T[0]; -#pragma warning restore CA1825 - - // Constructs a List. The list is initially empty and has a capacity - // of zero. Upon adding the first element to the list the capacity is - // increased to 4, and then increased in multiples of two as required. - public LowLevelList() - { - _items = s_emptyArray; - } - - // Constructs a List with a given initial capacity. The list is - // initially empty, but will have room for the given number of elements - // before any reallocations are required. - // - public LowLevelList(int capacity) - { - ArgumentOutOfRangeException.ThrowIfNegative(capacity); - - if (capacity == 0) - _items = s_emptyArray; - else - _items = new T[capacity]; - } - - // Constructs a List, copying the contents of the given collection. The - // size and capacity of the new list will both be equal to the size of the - // given collection. - // - public LowLevelList(IEnumerable collection) - { - ArgumentNullException.ThrowIfNull(collection); - - ICollection? c = collection as ICollection; - if (c != null) - { - int count = c.Count; - if (count == 0) - { - _items = s_emptyArray; - } - else - { - _items = new T[count]; - c.CopyTo(_items, 0); - _size = count; - } - } - else - { - _size = 0; - _items = s_emptyArray; - // This enumerable could be empty. Let Add allocate a new array, if needed. - // Note it will also go to _defaultCapacity first, not 1, then 2, etc. - - using (IEnumerator en = collection.GetEnumerator()) - { - while (en.MoveNext()) - { - Add(en.Current); - } - } - } - } - - // Gets and sets the capacity of this list. The capacity is the size of - // the internal array used to hold items. When set, the internal - // array of the list is reallocated to the given capacity. - // - public int Capacity - { - get - { - return _items.Length; - } - set - { - ArgumentOutOfRangeException.ThrowIfLessThan(value, _size); - - if (value != _items.Length) - { - if (value > 0) - { - T[] newItems = new T[value]; - Array.Copy(_items, 0, newItems, 0, _size); - _items = newItems; - } - else - { - _items = s_emptyArray; - } - } - } - } - - // Read-only property describing how many elements are in the List. - public int Count - { - get - { - return _size; - } - } - - // Sets or Gets the element at the given index. - // - public T this[int index] - { - get - { - // Following trick can reduce the range check by one - ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)_size, nameof(index)); - return _items[index]; - } - - set - { - ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)_size, nameof(index)); - _items[index] = value; - _version++; - } - } - - - // Adds the given object to the end of this list. The size of the list is - // increased by one. If required, the capacity of the list is doubled - // before adding the new element. - // - public void Add(T item) - { - if (_size == _items.Length) EnsureCapacity(_size + 1); - _items[_size++] = item; - _version++; - } - - // Ensures that the capacity of this list is at least the given minimum - // value. If the current capacity of the list is less than min, the - // capacity is increased to twice the current capacity or to min, - // whichever is larger. - private void EnsureCapacity(int min) - { - if (_items.Length < min) - { - int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Length * 2; - // Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow. - // Note that this check works even when _items.Length overflowed thanks to the (uint) cast - //if ((uint)newCapacity > Array.MaxLength) newCapacity = Array.MaxLength; - if (newCapacity < min) newCapacity = min; - Capacity = newCapacity; - } - } - } -} diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs index 7a6f07a01c0e19..d8ae1363c73af2 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs @@ -29,17 +29,7 @@ private static IntPtr RhpCidResolve_Worker(object pObject, IntPtr pCell) IntPtr pTargetCode = RhResolveDispatchWorker(pObject, (void*)pCell, ref cellInfo); if (pTargetCode != IntPtr.Zero) { - // We don't update the dispatch cell cache if this is IDynamicInterfaceCastable because this - // scenario is by-design dynamic. There is no guarantee that another instance with the same MethodTable - // as the one we just resolved would do the resolution the same way. We will need to ask again. - if (!pObject.GetMethodTable()->IsIDynamicInterfaceCastable) - { - return InternalCalls.RhpUpdateDispatchCellCache(pCell, pTargetCode, pObject.GetMethodTable(), ref cellInfo); - } - else - { - return pTargetCode; - } + return InternalCalls.RhpUpdateDispatchCellCache(pCell, pTargetCode, pObject.GetMethodTable(), ref cellInfo); } // "Valid method implementation was not found." diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index c6a19f9b9bf023..61ed486a7989c8 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -20,6 +20,7 @@ set(COMMON_RUNTIME_SOURCES gcenv.ee.cpp GcStressControl.cpp HandleTableHelpers.cpp + interoplibinterface_java.cpp MathHelpers.cpp MiscHelpers.cpp TypeManager.cpp @@ -38,6 +39,7 @@ set(COMMON_RUNTIME_SOURCES yieldprocessornormalized.cpp ${GC_DIR}/gceventstatus.cpp + ${GC_DIR}/gcbridge.cpp ${GC_DIR}/gcload.cpp ${GC_DIR}/gcconfig.cpp ${GC_DIR}/gchandletable.cpp diff --git a/src/coreclr/nativeaot/Runtime/HandleTableHelpers.cpp b/src/coreclr/nativeaot/Runtime/HandleTableHelpers.cpp index 91750c078e4539..7cf154d29c0cb3 100644 --- a/src/coreclr/nativeaot/Runtime/HandleTableHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/HandleTableHelpers.cpp @@ -6,6 +6,7 @@ #include "objecthandle.h" #include "RestrictedCallouts.h" #include "gchandleutilities.h" +#include "interoplibinterface.h" FCIMPL2(OBJECTHANDLE, RhpHandleAlloc, Object *pObject, int type) @@ -64,6 +65,27 @@ FCIMPL2(void, RhUnregisterRefCountedHandleCallback, void * pCallout, MethodTable } FCIMPLEND +FCIMPL2(OBJECTHANDLE, RhpHandleAllocCrossReference, Object *pPrimary, void *pContext) +{ + return GCHandleUtilities::GetGCHandleManager()->GetGlobalHandleStore()->CreateHandleWithExtraInfo(pPrimary, HNDTYPE_CROSSREFERENCE, pContext); +} +FCIMPLEND + +FCIMPL2(FC_BOOL_RET, RhHandleTryGetCrossReferenceContext, OBJECTHANDLE handle, void **pContext) +{ + *pContext = nullptr; + + IGCHandleManager* gcHandleManager = GCHandleUtilities::GetGCHandleManager(); + if (gcHandleManager->HandleFetchType(handle) != HNDTYPE_CROSSREFERENCE) + { + FC_RETURN_BOOL(false); + } + + *pContext = gcHandleManager->GetExtraInfoFromHandle(handle); + FC_RETURN_BOOL(true); +} +FCIMPLEND + // This structure mirrors the managed type System.Runtime.InteropServices.ComWrappers.ManagedObjectWrapper. struct ManagedObjectWrapper { diff --git a/src/coreclr/nativeaot/Runtime/MiscHelpers.cpp b/src/coreclr/nativeaot/Runtime/MiscHelpers.cpp index 138c3917198ec4..b8d3b4f797839d 100644 --- a/src/coreclr/nativeaot/Runtime/MiscHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/MiscHelpers.cpp @@ -73,7 +73,7 @@ EXTERN_C void QCALLTYPE RhFlushProcessWriteBuffers() ASSERT_MSG(!ThreadStore::GetCurrentThread()->IsCurrentThreadInCooperativeMode(), "You must p/invoke to RhFlushProcessWriteBuffers"); - PalFlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); } // Get the list of currently loaded NativeAOT modules (as OS HMODULE handles). The caller provides a reference diff --git a/src/coreclr/nativeaot/Runtime/Pal.h b/src/coreclr/nativeaot/Runtime/Pal.h index 6a4c57ce7307a1..0a9f9c2ea45599 100644 --- a/src/coreclr/nativeaot/Runtime/Pal.h +++ b/src/coreclr/nativeaot/Runtime/Pal.h @@ -23,6 +23,7 @@ #include #endif +#include #include #include "CommonTypes.h" @@ -290,7 +291,6 @@ int32_t _stricmp(const char *string1, const char *string2); uint16_t PalCaptureStackBackTrace(uint32_t arg1, uint32_t arg2, void* arg3, uint32_t* arg4); UInt32_BOOL PalCloseHandle(HANDLE arg1); -void PalFlushProcessWriteBuffers(); uint32_t PalGetCurrentProcessId(); #ifdef UNICODE diff --git a/src/coreclr/nativeaot/Runtime/RhConfig.cpp b/src/coreclr/nativeaot/Runtime/RhConfig.cpp index 23d405822b513b..af6d130bd7dde9 100644 --- a/src/coreclr/nativeaot/Runtime/RhConfig.cpp +++ b/src/coreclr/nativeaot/Runtime/RhConfig.cpp @@ -195,4 +195,23 @@ bool RhConfig::GetEmbeddedVariable(Config* config, _In_z_ const char* configName return false; } +size_t GetDefaultStackSizeSetting() +{ + // Keep the same arbitrary minimum and maximum from the CoreCLR VM layer. + const size_t minStack = 0x10000; // 64K + const size_t maxStack = 0x80000000; // 2G + + uint64_t uiStacksize; + if (g_pRhConfig->ReadConfigValue("Thread_DefaultStackSize", &uiStacksize) + || g_pRhConfig->ReadKnobUInt64Value("System.Threading.DefaultStackSize", &uiStacksize)) + { + if (uiStacksize < maxStack && uiStacksize >= minStack) + { + return (size_t)uiStacksize; + } + } + + return 0; +} + #endif diff --git a/src/coreclr/nativeaot/Runtime/RhConfig.h b/src/coreclr/nativeaot/Runtime/RhConfig.h index 59d1d37fc15546..b452d68af65c7e 100644 --- a/src/coreclr/nativeaot/Runtime/RhConfig.h +++ b/src/coreclr/nativeaot/Runtime/RhConfig.h @@ -109,6 +109,8 @@ class RhConfig extern RhConfig * g_pRhConfig; +size_t GetDefaultStackSizeSetting(); + #endif //!DACCESS_COMPILE #endif // RHCONFIG_H diff --git a/src/coreclr/nativeaot/Runtime/disabledruntimeeventinternal.cpp b/src/coreclr/nativeaot/Runtime/disabledruntimeeventinternal.cpp index 728e572e9ff1fc..22206116098223 100644 --- a/src/coreclr/nativeaot/Runtime/disabledruntimeeventinternal.cpp +++ b/src/coreclr/nativeaot/Runtime/disabledruntimeeventinternal.cpp @@ -80,7 +80,7 @@ EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogThreadPoolIOPack(void * Nati { } -EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogExceptionThrown(const WCHAR* exceptionTypeName, const WCHAR* exceptionMessage, void* faultingIP, HRESULT hresult) +EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogExceptionThrown(const WCHAR* exceptionTypeName, const WCHAR* exceptionMessage, void* faultingIP, HRESULT hresult, uint16_t flags, uint16_t ClrInstanceID) { } diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp index 95d8c7feb96dab..5d5e539e0c1b90 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp @@ -331,6 +331,12 @@ ep_rt_aot_atomic_dec_int64_t (volatile int64_t *value) { return (currentValue - 1); } +int64_t +ep_rt_aot_atomic_compare_exchange_int64_t (volatile int64_t *target, int64_t expected, int64_t value) { + STATIC_CONTRACT_NOTHROW; + return static_cast(PalInterlockedCompareExchange64 ((volatile int64_t *)target, (int64_t)value, (int64_t)expected)); +} + size_t ep_rt_aot_atomic_compare_exchange_size_t (volatile size_t *target, size_t expected, size_t value) { STATIC_CONTRACT_NOTHROW; diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h index 92714f0bcf85d4..78d6578dce29c8 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.h @@ -224,6 +224,16 @@ ep_rt_atomic_dec_int64_t (volatile int64_t *value) return ep_rt_aot_atomic_dec_int64_t (value); } +static +inline +int64_t +ep_rt_atomic_compare_exchange_int64_t (volatile int64_t *target, int64_t expected, int64_t value) +{ + STATIC_CONTRACT_NOTHROW; + extern int64_t ep_rt_aot_atomic_compare_exchange_int64_t (volatile int64_t *target, int64_t expected, int64_t value); + return ep_rt_aot_atomic_compare_exchange_int64_t (target, expected, value); +} + static inline size_t diff --git a/src/coreclr/nativeaot/Runtime/gcenv.ee.cpp b/src/coreclr/nativeaot/Runtime/gcenv.ee.cpp index 9285e676354434..58d7ffc0bfc963 100644 --- a/src/coreclr/nativeaot/Runtime/gcenv.ee.cpp +++ b/src/coreclr/nativeaot/Runtime/gcenv.ee.cpp @@ -63,7 +63,7 @@ void GCToEEInterface::RestartEE(bool /*bFinishedGC*/) // This is needed to synchronize threads that were running in preemptive mode while // the runtime was suspended and that will return to cooperative mode after the runtime // is restarted. - PalFlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); #endif // !defined(TARGET_X86) && !defined(TARGET_AMD64) SyncClean::CleanUp(); @@ -404,7 +404,7 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args) { // If runtime is not suspended, force all threads to see the changed table before seeing updated heap boundaries. // See: http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/346765 - PalFlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); } #endif @@ -415,7 +415,7 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args) if (!is_runtime_suspended) { // If runtime is not suspended, force all threads to see the changed state before observing future allocations. - PalFlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); } #endif return; @@ -809,4 +809,11 @@ void GCToEEInterface::FreeStringConfigValue(const char* value) delete[] value; } +void GCToEEInterface::TriggerClientBridgeProcessing(MarkCrossReferencesArgs* args) +{ +#ifdef FEATURE_JAVAMARSHAL + JavaMarshalNative::TriggerClientBridgeProcessing(args); +#endif +} + #endif // !DACCESS_COMPILE diff --git a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h index b41d65af26f27c..59ea64bf324bb0 100644 --- a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h +++ b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h @@ -11,7 +11,7 @@ struct ReadyToRunHeaderConstants { static const uint32_t Signature = 0x00525452; // 'RTR' - static const uint32_t CurrentMajorVersion = 15; + static const uint32_t CurrentMajorVersion = 16; static const uint32_t CurrentMinorVersion = 0; }; diff --git a/src/coreclr/nativeaot/Runtime/inc/stressLog.h b/src/coreclr/nativeaot/Runtime/inc/stressLog.h index 952789228023fb..9cef3be2b8c23a 100644 --- a/src/coreclr/nativeaot/Runtime/inc/stressLog.h +++ b/src/coreclr/nativeaot/Runtime/inc/stressLog.h @@ -344,19 +344,26 @@ class StressLog { }; -template<> -void* StressLog::ConvertArgument(float arg) = delete; - #if TARGET_64BIT template<> inline void* StressLog::ConvertArgument(double arg) { return (void*)(size_t)(*((uint64_t*)&arg)); } + +// COMPAT: Convert 32-bit floats to 64-bit doubles. +template<> +inline void* StressLog::ConvertArgument(float arg) +{ + return StressLog::ConvertArgument((double)arg); +} #else template<> void* StressLog::ConvertArgument(double arg) = delete; +template<> +void* StressLog::ConvertArgument(float arg) = delete; + // COMPAT: Truncate 64-bit integer arguments to 32-bit template<> inline void* StressLog::ConvertArgument(uint64_t arg) diff --git a/src/coreclr/nativeaot/Runtime/interoplibinterface.h b/src/coreclr/nativeaot/Runtime/interoplibinterface.h index fce04b81f90249..c89281d152d8cc 100644 --- a/src/coreclr/nativeaot/Runtime/interoplibinterface.h +++ b/src/coreclr/nativeaot/Runtime/interoplibinterface.h @@ -22,3 +22,15 @@ class ObjCMarshalNative }; #endif // FEATURE_OBJCMARSHAL + +#ifdef FEATURE_JAVAMARSHAL + +struct MarkCrossReferencesArgs; + +class JavaMarshalNative +{ +public: + static void TriggerClientBridgeProcessing( + MarkCrossReferencesArgs* args); +}; +#endif // FEATURE_JAVAMARSHAL diff --git a/src/coreclr/nativeaot/Runtime/interoplibinterface_java.cpp b/src/coreclr/nativeaot/Runtime/interoplibinterface_java.cpp new file mode 100644 index 00000000000000..1fcda8be6089d8 --- /dev/null +++ b/src/coreclr/nativeaot/Runtime/interoplibinterface_java.cpp @@ -0,0 +1,174 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifdef FEATURE_JAVAMARSHAL + +// Runtime headers +#include "common.h" +#include "gcenv.h" +#include "gcenv.ee.h" +#include "gcheaputilities.h" +#include "gchandleutilities.h" +#include "thread.h" +#include "threadstore.h" +#include "threadstore.inl" +#include "event.h" +#include "thread.inl" + +#include "interoplibinterface.h" + +using CrossreferenceHandleCallback = void(__stdcall *)(MarkCrossReferencesArgs*); + +namespace +{ + volatile CrossreferenceHandleCallback g_MarkCrossReferences = NULL; + + Volatile g_GCBridgeActive = false; + CLREventStatic g_bridgeFinished; + + void ReleaseGCBridgeArgumentsWorker( + MarkCrossReferencesArgs* args) + { + _ASSERTE(args != NULL); + + // Memory was allocated for the collections by the GC. + // See callers of GCToEEInterface::TriggerGCBridge(). + + // Free memory in each of the SCCs + for (size_t i = 0; i < args->ComponentCount; i++) + { + delete[] args->Components[i].Contexts; + } + delete[] args->Components; + delete[] args->CrossReferences; + delete args; + } +} + +void JavaMarshalNative::TriggerClientBridgeProcessing( + _In_ MarkCrossReferencesArgs* args) +{ + _ASSERTE(GCHeapUtilities::IsGCInProgress()); + + if (g_GCBridgeActive) + { + // Release the memory allocated since the GCBridge + // is already running and we're not passing them to it. + ReleaseGCBridgeArgumentsWorker(args); + return; + } + + // Not initialized + if (g_MarkCrossReferences == NULL) + { + // Release the memory allocated since we + // don't have a GC bridge callback. + ReleaseGCBridgeArgumentsWorker(args); + return; + } + + g_MarkCrossReferences(args); + + // This runs during GC while the world is stopped, no synchronisation required + g_bridgeFinished.Reset(); + + // Mark the GCBridge as active. + g_GCBridgeActive = true; +} + +extern "C" BOOL QCALLTYPE JavaMarshal_Initialize( + void* markCrossReferences) +{ + _ASSERTE(markCrossReferences != NULL); + + BOOL success = FALSE; + + // Switch to Cooperative mode since we are setting callbacks that + // will be used during a GC and we want to ensure a GC isn't occurring + // while they are being set. + Thread* pThisThread = ThreadStore::GetCurrentThreadIfAvailable(); + pThisThread->DeferTransitionFrame(); + pThisThread->DisablePreemptiveMode(); + + if (PalInterlockedCompareExchangePointer((void* volatile*)&g_MarkCrossReferences, (void*)markCrossReferences, NULL) == NULL) + { + success = g_bridgeFinished.CreateManualEventNoThrow(false); + } + + pThisThread->EnablePreemptiveMode(); + + return success; +} + +extern "C" void QCALLTYPE JavaMarshal_FinishCrossReferenceProcessing( + MarkCrossReferencesArgs *crossReferences, + size_t length, + void* unreachableObjectHandles) +{ + _ASSERTE(crossReferences->ComponentCount >= 0); + + _ASSERTE(g_GCBridgeActive); + + // Mark the GCBridge as inactive. + // This must be synchronized with the GC so switch to cooperative mode. + { + Thread* pThisThread = ThreadStore::GetCurrentThreadIfAvailable(); + pThisThread->DeferTransitionFrame(); + pThisThread->DisablePreemptiveMode(); + + GCHeapUtilities::GetGCHeap()->NullBridgeObjectsWeakRefs(length, unreachableObjectHandles); + + IGCHandleManager* pHandleManager = GCHandleUtilities::GetGCHandleManager(); + OBJECTHANDLE* handles = (OBJECTHANDLE*)unreachableObjectHandles; + for (size_t i = 0; i < length; i++) + pHandleManager->DestroyHandleOfUnknownType(handles[i]); + + g_GCBridgeActive = false; + g_bridgeFinished.Set(); + + pThisThread->EnablePreemptiveMode(); + } + + ReleaseGCBridgeArgumentsWorker(crossReferences); +} + +FCIMPL2(FC_BOOL_RET, GCHandle_InternalTryGetBridgeWait, OBJECTHANDLE handle, OBJECTREF* pObjResult) +{ + if (g_GCBridgeActive) + { + FC_RETURN_BOOL(false); + } + + *pObjResult = ObjectFromHandle(handle); + FC_RETURN_BOOL(true); +} +FCIMPLEND + +extern "C" void QCALLTYPE GCHandle_InternalGetBridgeWait(OBJECTHANDLE handle, OBJECTREF* pObj) +{ + _ASSERTE(pObj != NULL); + + // Transition to cooperative mode to ensure that the GC is not in progress + Thread* pThisThread = ThreadStore::GetCurrentThreadIfAvailable(); + pThisThread->DeferTransitionFrame(); + pThisThread->DisablePreemptiveMode(); + + while (g_GCBridgeActive) + { + // This wait will transition to pre-emptive mode to wait for the bridge to finish. + g_bridgeFinished.Wait(INFINITE, false, false); + } + + // If we reach here, then the bridge has finished processing and we can be sure that + // it isn't currently active. + + // No GC can happen between the wait and obtaining of the reference, so the + // bridge processing status can't change, guaranteeing the nulling of weak refs + // took place in the bridge processing finish stage. + *pObj = ObjectFromHandle(handle); + + // Re-enable preemptive mode before we exit the QCall to ensure we're in the right GC state. + pThisThread->EnablePreemptiveMode(); +} + +#endif // FEATURE_JAVAMARSHAL diff --git a/src/coreclr/nativeaot/Runtime/portable.cpp b/src/coreclr/nativeaot/Runtime/portable.cpp index 2f30e42253d876..c6f83d09c1ff0d 100644 --- a/src/coreclr/nativeaot/Runtime/portable.cpp +++ b/src/coreclr/nativeaot/Runtime/portable.cpp @@ -127,7 +127,7 @@ FCIMPL2(Array *, RhpNewArrayFast, MethodTable * pArrayEEType, int numElements) } FCIMPLEND -FCIMPL2(String *, RhNewString, MethodTable * pArrayEEType, int numElements) +FCIMPL2(String *, RhNewString, MethodTable * pArrayEEType, intptr_t numElements) { // TODO: Implement. We tail call to RhpNewArrayFast for now since there's a bunch of TODOs in the places // that matter anyway. diff --git a/src/coreclr/nativeaot/Runtime/runtimeeventinternal.cpp b/src/coreclr/nativeaot/Runtime/runtimeeventinternal.cpp index 5de8fa373c781c..c1377780f2e55a 100644 --- a/src/coreclr/nativeaot/Runtime/runtimeeventinternal.cpp +++ b/src/coreclr/nativeaot/Runtime/runtimeeventinternal.cpp @@ -90,14 +90,14 @@ EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogThreadPoolIOPack(void * Nati FireEtwThreadPoolIOPack(NativeOverlapped, Overlapped, ClrInstanceID); } -EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogExceptionThrown(const WCHAR* exceptionTypeName, const WCHAR* exceptionMessage, void* faultingIP, HRESULT hresult) +EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogExceptionThrown(const WCHAR* exceptionTypeName, const WCHAR* exceptionMessage, void* faultingIP, HRESULT hresult, uint16_t flags, uint16_t ClrInstanceID) { FireEtwExceptionThrown_V1(exceptionTypeName, exceptionMessage, faultingIP, hresult, - 0, - GetClrInstanceId()); + flags, + ClrInstanceID); } EXTERN_C void QCALLTYPE NativeRuntimeEventSource_LogWaitHandleWaitStart(uint8_t WaitSource, intptr_t AssociatedObjectID, uint16_t ClrInstanceID) diff --git a/src/coreclr/nativeaot/Runtime/thread.cpp b/src/coreclr/nativeaot/Runtime/thread.cpp index fb9d64885e6d52..45b88d1cde2def 100644 --- a/src/coreclr/nativeaot/Runtime/thread.cpp +++ b/src/coreclr/nativeaot/Runtime/thread.cpp @@ -38,7 +38,7 @@ static Thread* g_RuntimeInitializingThread; ee_alloc_context::PerThreadRandom::PerThreadRandom() { - minipal_xoshiro128pp_init(&random_state, (uint32_t)minipal_lowres_ticks()); + minipal_xoshiro128pp_init(&random_state, (uint32_t)minipal_hires_ticks()); } thread_local ee_alloc_context::PerThreadRandom ee_alloc_context::t_random = PerThreadRandom(); @@ -1317,6 +1317,12 @@ FCIMPL0(uint64_t, RhCurrentOSThreadId) } FCIMPLEND +FCIMPL0(size_t, RhGetDefaultStackSize) +{ + return GetDefaultStackSizeSetting(); +} +FCIMPLEND + // Standard calling convention variant and actual implementation for RhpReversePInvokeAttachOrTrapThread EXTERN_C NOINLINE void FASTCALL RhpReversePInvokeAttachOrTrapThread2(ReversePInvokeFrame* pFrame) { diff --git a/src/coreclr/nativeaot/Runtime/threadstore.cpp b/src/coreclr/nativeaot/Runtime/threadstore.cpp index daf745ba0b65ef..fd0c221f0725b4 100644 --- a/src/coreclr/nativeaot/Runtime/threadstore.cpp +++ b/src/coreclr/nativeaot/Runtime/threadstore.cpp @@ -237,7 +237,7 @@ void ThreadStore::SuspendAllThreads(bool waitForGCEvent) // Our lock-free algorithm depends on flushing write buffers of all processors running RH code. The // reason for this is that we essentially implement Dekker's algorithm, which requires write ordering. - PalFlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); int prevRemaining = INT32_MAX; bool observeOnly = true; @@ -310,7 +310,7 @@ void ThreadStore::SuspendAllThreads(bool waitForGCEvent) // This is needed to synchronize threads that were running in preemptive mode thus were // left alone by suspension to flush their writes that they made before they switched to // preemptive mode. - PalFlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); #endif //TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64 } @@ -329,7 +329,7 @@ void ThreadStore::ResumeAllThreads(bool waitForGCEvent) // This is needed to synchronize threads that were running in preemptive mode while // the runtime was suspended and that will return to cooperative mode after the runtime // is restarted. - PalFlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); #endif //TARGET_ARM || TARGET_ARM64 || TARGET_LOONGARCH64 RhpTrapThreads &= ~(uint32_t)TrapThreadsFlags::TrapThreads; diff --git a/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp index b6045f6f74d5ac..be67447030e85a 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #ifdef TARGET_LINUX @@ -765,6 +766,13 @@ bool PalStartBackgroundWork(_In_ BackgroundCallback callback, _In_opt_ void* pCa int st = pthread_attr_init(&attrs); ASSERT(st == 0); + + size_t stacksize = GetDefaultStackSizeSetting(); + if (stacksize != 0) + { + st = pthread_attr_setstacksize(&attrs, stacksize); + ASSERT(st == 0); + } static const int NormalPriority = 0; static const int HighestPriority = -20; @@ -1226,11 +1234,6 @@ int32_t PalGetModuleFileName(_Out_ const TCHAR** pModuleNameOut, HANDLE moduleBa #endif // defined(HOST_WASM) } -void PalFlushProcessWriteBuffers() -{ - GCToOSInterface::FlushProcessWriteBuffers(); -} - static const int64_t SECS_BETWEEN_1601_AND_1970_EPOCHS = 11644473600LL; static const int64_t SECS_TO_100NS = 10000000; /* 10^7 */ diff --git a/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp b/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp index 0d5f1cdd52124c..07c6c2135feeff 100644 --- a/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp @@ -25,6 +25,15 @@ #endif #include +template +inline To unwindhelpers_bitcast(From from) +{ + static_assert(sizeof(From)==sizeof(To), "Sizes must match"); + + To to; + memcpy(&to, &from, sizeof(To)); + return to; +} #if defined(TARGET_AMD64) using libunwind::Registers_x86_64; @@ -340,7 +349,7 @@ struct Registers_REGDISPLAY : REGDISPLAY bool validRegister(int num) const; bool validFloatRegister(int num) const; - bool validVectorRegister(int num) const { return false; }; + bool validVectorRegister(int num) const { return false; } uint32_t getRegister(int num) const; void setRegister(int num, uint32_t value, uint32_t location); @@ -398,7 +407,7 @@ inline bool Registers_REGDISPLAY::validRegister(int num) const { } inline bool Registers_REGDISPLAY::validFloatRegister(int num) const { - return num >= UNW_ARM_D0 && num <= UNW_ARM_D31; + return num >= UNW_ARM_D8 && num <= UNW_ARM_D15; } inline uint32_t Registers_REGDISPLAY::getRegister(int regNum) const { @@ -509,20 +518,14 @@ void Registers_REGDISPLAY::setRegister(int num, uint32_t value, uint32_t locatio double Registers_REGDISPLAY::getFloatRegister(int num) const { - if (num >= UNW_ARM_D8 && num <= UNW_ARM_D15) - { - return D[num - UNW_ARM_D8]; - } - - PORTABILITY_ASSERT("unsupported arm register"); + assert(validFloatRegister(num)); + return unwindhelpers_bitcast(D[num - UNW_ARM_D8]); } void Registers_REGDISPLAY::setFloatRegister(int num, double value) { - if (num >= UNW_ARM_D8 && num <= UNW_ARM_D15) - { - D[num - UNW_ARM_D8] = value; - } + assert(validFloatRegister(num)); + D[num - UNW_ARM_D8] = unwindhelpers_bitcast(value); } #endif // TARGET_ARM @@ -536,17 +539,17 @@ struct Registers_REGDISPLAY : REGDISPLAY static constexpr int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; } bool validRegister(int num) const; - bool validFloatRegister(int num) { return false; }; - bool validVectorRegister(int num) const; + bool validFloatRegister(int num) const; + bool validVectorRegister(int num) const { return false; } uint64_t getRegister(int num) const; void setRegister(int num, uint64_t value, uint64_t location); - double getFloatRegister(int num) const { abort(); } - void setFloatRegister(int num, double value) { abort(); } + double getFloatRegister(int num) const; + void setFloatRegister(int num, double value); - libunwind::v128 getVectorRegister(int num) const; - void setVectorRegister(int num, libunwind::v128 value); + libunwind::v128 getVectorRegister(int num) const { abort(); } + void setVectorRegister(int num, libunwind::v128 value) { abort(); } uint64_t getSP() const { return SP; } void setSP(uint64_t value, uint64_t location) { SP = value; } @@ -575,12 +578,9 @@ inline bool Registers_REGDISPLAY::validRegister(int num) const { return false; } -bool Registers_REGDISPLAY::validVectorRegister(int num) const +bool Registers_REGDISPLAY::validFloatRegister(int num) const { - if (num >= UNW_ARM64_D8 && num <= UNW_ARM64_D15) - return true; - - return false; + return num >= UNW_ARM64_D8 && num <= UNW_ARM64_D15; } inline uint64_t Registers_REGDISPLAY::getRegister(int regNum) const { @@ -777,35 +777,16 @@ void Registers_REGDISPLAY::setRegister(int num, uint64_t value, uint64_t locatio } } -libunwind::v128 Registers_REGDISPLAY::getVectorRegister(int num) const +double Registers_REGDISPLAY::getFloatRegister(int num) const { - num -= UNW_ARM64_D8; - - if (num < 0 || (size_t)num >= sizeof(D) / sizeof(uint64_t)) - { - PORTABILITY_ASSERT("unsupported arm64 vector register"); - } - - libunwind::v128 result; - - result.vec[0] = 0; - result.vec[1] = 0; - result.vec[2] = D[num] >> 32; - result.vec[3] = D[num] & 0xFFFFFFFF; - - return result; + assert(validFloatRegister(num)); + return unwindhelpers_bitcast(D[num - UNW_ARM64_D8]); } -void Registers_REGDISPLAY::setVectorRegister(int num, libunwind::v128 value) +void Registers_REGDISPLAY::setFloatRegister(int num, double value) { - num -= UNW_ARM64_D8; - - if (num < 0 || (size_t)num >= sizeof(D) / sizeof(uint64_t)) - { - PORTABILITY_ASSERT("unsupported arm64 vector register"); - } - - D[num] = (uint64_t)value.vec[2] << 32 | (uint64_t)value.vec[3]; + assert(validFloatRegister(num)); + D[num - UNW_ARM64_D8] = unwindhelpers_bitcast(value); } #endif // TARGET_ARM64 @@ -820,7 +801,7 @@ struct Registers_REGDISPLAY : REGDISPLAY bool validRegister(int num) const; bool validFloatRegister(int num) const; - bool validVectorRegister(int num) const { return false; }; + bool validVectorRegister(int num) const { return false; } uint64_t getRegister(int num) const; void setRegister(int num, uint64_t value, uint64_t location); @@ -828,8 +809,8 @@ struct Registers_REGDISPLAY : REGDISPLAY double getFloatRegister(int num) const; void setFloatRegister(int num, double value); - libunwind::v128 getVectorRegister(int num) const { abort(); }; - void setVectorRegister(int num, libunwind::v128 value) { abort(); }; + libunwind::v128 getVectorRegister(int num) const { abort(); } + void setVectorRegister(int num, libunwind::v128 value) { abort(); } uint64_t getSP() const { return SP; } void setSP(uint64_t value, uint64_t location) { SP = value; } @@ -860,10 +841,7 @@ inline bool Registers_REGDISPLAY::validRegister(int num) const { bool Registers_REGDISPLAY::validFloatRegister(int num) const { - if (num >= UNW_LOONGARCH_F24 && num <= UNW_LOONGARCH_F31) - return true; - - return false; + return num >= UNW_LOONGARCH_F24 && num <= UNW_LOONGARCH_F31; } inline uint64_t Registers_REGDISPLAY::getRegister(int regNum) const { @@ -1062,20 +1040,14 @@ void Registers_REGDISPLAY::setRegister(int num, uint64_t value, uint64_t locatio double Registers_REGDISPLAY::getFloatRegister(int num) const { - if (num >= UNW_LOONGARCH_F24 && num <= UNW_LOONGARCH_F31) - { - return F[num - UNW_LOONGARCH_F24]; - } - - PORTABILITY_ASSERT("unsupported LA freg"); + assert(validFloatRegister(num)); + return unwindhelpers_bitcast(F[num - UNW_LOONGARCH_F24]); } void Registers_REGDISPLAY::setFloatRegister(int num, double value) { - if (num >= UNW_LOONGARCH_F24 && num <= UNW_LOONGARCH_F31) - { - F[num - UNW_LOONGARCH_F24] = value; - } + assert(validFloatRegister(num)); + F[num - UNW_LOONGARCH_F24] = unwindhelpers_bitcast(value); } #endif // TARGET_LOONGARCH64 @@ -1089,17 +1061,17 @@ struct Registers_REGDISPLAY : REGDISPLAY static constexpr int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; } bool validRegister(int num) const; - bool validFloatRegister(int num) { return false; }; - bool validVectorRegister(int num) const; + bool validFloatRegister(int num) const; + bool validVectorRegister(int num) const { return false; } uint64_t getRegister(int num) const; void setRegister(int num, uint64_t value, uint64_t location); - double getFloatRegister(int num) const { abort(); } - void setFloatRegister(int num, double value) { abort(); } + double getFloatRegister(int num) const; + void setFloatRegister(int num, double value); - libunwind::v128 getVectorRegister(int num) const; - void setVectorRegister(int num, libunwind::v128 value); + libunwind::v128 getVectorRegister(int num) const { abort(); } + void setVectorRegister(int num, libunwind::v128 value) { abort(); } uint64_t getSP() const { return SP; } void setSP(uint64_t value, uint64_t location) { SP = value; } @@ -1119,6 +1091,10 @@ inline bool Registers_REGDISPLAY::validRegister(int num) const { if (num >= UNW_RISCV_X0 && num <= UNW_RISCV_X31) return true; + return false; +} + +inline bool Registers_REGDISPLAY::validFloatRegister(int num) const { if (num == UNW_RISCV_F8 || num == UNW_RISCV_F9) return true; @@ -1128,12 +1104,6 @@ inline bool Registers_REGDISPLAY::validRegister(int num) const { return false; } -bool Registers_REGDISPLAY::validVectorRegister(int num) const -{ - // Vector registers currently unsupported - return false; -} - inline uint64_t Registers_REGDISPLAY::getRegister(int regNum) const { switch (regNum) { case UNW_REG_IP: @@ -1180,74 +1150,6 @@ inline uint64_t Registers_REGDISPLAY::getRegister(int regNum) const { case UNW_RISCV_X23: return *pS7; - case UNW_RISCV_F0: - return F[0]; - case UNW_RISCV_F1: - return F[1]; - case UNW_RISCV_F2: - return F[2]; - case UNW_RISCV_F3: - return F[3]; - case UNW_RISCV_F4: - return F[4]; - case UNW_RISCV_F5: - return F[5]; - case UNW_RISCV_F6: - return F[6]; - case UNW_RISCV_F7: - return F[7]; - case UNW_RISCV_F8: - return F[8]; - case UNW_RISCV_F9: - return F[9]; - case UNW_RISCV_F10: - return F[10]; - case UNW_RISCV_F11: - return F[11]; - case UNW_RISCV_F12: - return F[12]; - case UNW_RISCV_F13: - return F[13]; - case UNW_RISCV_F14: - return F[14]; - case UNW_RISCV_F15: - return F[15]; - case UNW_RISCV_F16: - return F[16]; - case UNW_RISCV_F17: - return F[17]; - case UNW_RISCV_F18: - return F[18]; - case UNW_RISCV_F19: - return F[19]; - case UNW_RISCV_F20: - return F[20]; - case UNW_RISCV_F21: - return F[21]; - case UNW_RISCV_F22: - return F[22]; - case UNW_RISCV_F23: - return F[23]; - case UNW_RISCV_F24: - return F[24]; - case UNW_RISCV_F25: - return F[25]; - case UNW_RISCV_F26: - return F[26]; - case UNW_RISCV_F27: - return F[27]; - case UNW_RISCV_F28: - return F[28]; - case UNW_RISCV_F29: - return F[29]; - case UNW_RISCV_F30: - return F[30]; - case UNW_RISCV_F31: - return F[31]; - - case UNW_RISCV_VLENB: - return 0; // VLENB not used in REGDISPLAY, adjust if needed - default: PORTABILITY_ASSERT("unsupported RISC-V register"); } @@ -1331,122 +1233,24 @@ void Registers_REGDISPLAY::setRegister(int regNum, uint64_t value, uint64_t loca pS11 = (PTR_uintptr_t)location; break; - // Add other general-purpose registers if needed - - case UNW_RISCV_F0: - F[0] = value; - break; - case UNW_RISCV_F1: - F[1] = value; - break; - case UNW_RISCV_F2: - F[2] = value; - break; - case UNW_RISCV_F3: - F[3] = value; - break; - case UNW_RISCV_F4: - F[4] = value; - break; - case UNW_RISCV_F5: - F[5] = value; - break; - case UNW_RISCV_F6: - F[6] = value; - break; - case UNW_RISCV_F7: - F[7] = value; - break; - case UNW_RISCV_F8: - F[8] = value; - break; - case UNW_RISCV_F9: - F[9] = value; - break; - case UNW_RISCV_F10: - F[10] = value; - break; - case UNW_RISCV_F11: - F[11] = value; - break; - case UNW_RISCV_F12: - F[12] = value; - break; - case UNW_RISCV_F13: - F[13] = value; - break; - case UNW_RISCV_F14: - F[14] = value; - break; - case UNW_RISCV_F15: - F[15] = value; - break; - case UNW_RISCV_F16: - F[16] = value; - break; - case UNW_RISCV_F17: - F[17] = value; - break; - case UNW_RISCV_F18: - F[18] = value; - break; - case UNW_RISCV_F19: - F[19] = value; - break; - case UNW_RISCV_F20: - F[20] = value; - break; - case UNW_RISCV_F21: - F[21] = value; - break; - case UNW_RISCV_F22: - F[22] = value; - break; - case UNW_RISCV_F23: - F[23] = value; - break; - case UNW_RISCV_F24: - F[24] = value; - break; - case UNW_RISCV_F25: - F[25] = value; - break; - case UNW_RISCV_F26: - F[26] = value; - break; - case UNW_RISCV_F27: - F[27] = value; - break; - case UNW_RISCV_F28: - F[28] = value; - break; - case UNW_RISCV_F29: - F[29] = value; - break; - case UNW_RISCV_F30: - F[30] = value; - break; - case UNW_RISCV_F31: - F[31] = value; - break; - - case UNW_RISCV_VLENB: - PORTABILITY_ASSERT("unsupported RISC-V VLENB register"); - break; default: PORTABILITY_ASSERT("unsupported RISC-V register"); } } -libunwind::v128 Registers_REGDISPLAY::getVectorRegister(int num) const +double Registers_REGDISPLAY::getFloatRegister(int num) const { - PORTABILITY_ASSERT("Vector registers currently unsupported on RISC-V"); + assert(validFloatRegister(num)); + int index = (num < UNW_RISCV_F18) ? (num - UNW_RISCV_F8) : (num - UNW_RISCV_F18 + 2); + return unwindhelpers_bitcast(F[index]); } -void Registers_REGDISPLAY::setVectorRegister(int num, libunwind::v128 value) +void Registers_REGDISPLAY::setFloatRegister(int num, double value) { - PORTABILITY_ASSERT("Vector registers currently unsupported on RISC-V"); + assert(validFloatRegister(num)); + int index = (num < UNW_RISCV_F18) ? (num - UNW_RISCV_F8) : (num - UNW_RISCV_F18 + 2); + F[index] = unwindhelpers_bitcast(value); } #endif // TARGET_RISCV64 diff --git a/src/coreclr/nativeaot/Runtime/windows/PalMinWin.cpp b/src/coreclr/nativeaot/Runtime/windows/PalMinWin.cpp index 2927e358535359..839e0943877a65 100644 --- a/src/coreclr/nativeaot/Runtime/windows/PalMinWin.cpp +++ b/src/coreclr/nativeaot/Runtime/windows/PalMinWin.cpp @@ -846,9 +846,11 @@ static pfnSetThreadDescription g_pfnSetThreadDescription = SET_THREAD_DESCRIPTIO bool PalStartBackgroundWork(_In_ BackgroundCallback callback, _In_opt_ void* pCallbackContext, BOOL highPriority) { + DWORD stacksize = (DWORD)GetDefaultStackSizeSetting(); + HANDLE hThread = CreateThread( NULL, - 0, + (DWORD)stacksize, (LPTHREAD_START_ROUTINE)callback, pCallbackContext, highPriority ? CREATE_SUSPENDED : 0, @@ -1037,11 +1039,6 @@ UInt32_BOOL PalCloseHandle(HANDLE arg1) return ::CloseHandle(arg1); } -void PalFlushProcessWriteBuffers() -{ - ::FlushProcessWriteBuffers(); -} - uint32_t PalGetCurrentProcessId() { return static_cast(::GetCurrentProcessId()); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/AssemblyBinder.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/AssemblyBinder.cs index cee8abb23ab324..b799c50aeac5f2 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/AssemblyBinder.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/AssemblyBinder.cs @@ -33,5 +33,6 @@ public abstract class AssemblyBinder public abstract bool Bind(RuntimeAssemblyName refName, bool cacheMissedLookups, out AssemblyBindResult result, out Exception exception); public abstract IList GetLoadedAssemblies(); + public abstract int GetLoadedAssembliesCount(); } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs index 8249b4c58a32d6..2e2e5ebdf95bd9 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs @@ -7,6 +7,7 @@ using System.Collections.ObjectModel; using System.Diagnostics; using System.Reflection; +using System.Reflection.Runtime.General; //================================================================================================================== // Dependency note: @@ -110,13 +111,15 @@ public virtual E GetParent(E e) // private IEnumerable GetMatchingCustomAttributesIterator(E element, Func passesFilter, bool inherit) { - LowLevelList immediateResults = new LowLevelList(); + ListBuilder immediateResults = default; foreach (CustomAttributeData cad in GetDeclaredCustomAttributes(element)) { if (passesFilter(cad.AttributeType)) { yield return cad; - immediateResults.Add(cad); + + if (inherit) + immediateResults.Add(cad); } } if (inherit) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs index c55d468a4d4c8e..f93c101788f5ea 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs @@ -547,6 +547,11 @@ public static unsafe IntPtr ResolveStaticDispatchOnType(RuntimeTypeHandle instan return result; } + public static unsafe IntPtr ResolveDispatchOnType(RuntimeTypeHandle instanceType, RuntimeTypeHandle interfaceType, int slot) + { + return RuntimeImports.RhResolveDispatchOnType(instanceType.ToMethodTable(), interfaceType.ToMethodTable(), checked((ushort)slot)); + } + public static bool IsUnmanagedPointerType(RuntimeTypeHandle typeHandle) { return typeHandle.ToMethodTable()->IsPointer; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/FunctionPointerOps.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/FunctionPointerOps.cs index c0bceb7963c8ad..e011a5fe6739d3 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/FunctionPointerOps.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/FunctionPointerOps.cs @@ -49,10 +49,7 @@ public override int GetHashCode() public IntPtr InstantiationArgument; } - private static uint s_genericFunctionPointerNextIndex; - private const uint c_genericDictionaryChunkSize = 1024; - private static LowLevelList s_genericFunctionPointerCollection = new LowLevelList(); - private static LowLevelDictionary s_genericFunctionPointerDictionary = new LowLevelDictionary(); + private static LowLevelDictionary s_genericFunctionPointerDictionary = new LowLevelDictionary(); public static unsafe IntPtr GetGenericMethodFunctionPointer(IntPtr canonFunctionPointer, IntPtr instantiationArgument) { @@ -69,38 +66,17 @@ public static unsafe IntPtr GetGenericMethodFunctionPointer(IntPtr canonFunction InstantiationArgument = instantiationArgument }; - uint index = 0; - if (!s_genericFunctionPointerDictionary.TryGetValue(key, out index)) + if (!s_genericFunctionPointerDictionary.TryGetValue(key, out IntPtr descriptor)) { - // Capture new index value - index = s_genericFunctionPointerNextIndex; + descriptor = (IntPtr)NativeMemory.Alloc((uint)sizeof(GenericMethodDescriptor)); - int newChunkIndex = (int)(index / c_genericDictionaryChunkSize); - uint newSubChunkIndex = index % c_genericDictionaryChunkSize; - - // Generate new chunk if existing chunks are insufficient - if (s_genericFunctionPointerCollection.Count <= newChunkIndex) - { - Debug.Assert(newSubChunkIndex == 0); - - // New generic descriptors are allocated on the native heap and not tracked in the GC. - IntPtr pNewMem = (IntPtr)NativeMemory.Alloc(c_genericDictionaryChunkSize, (nuint)sizeof(GenericMethodDescriptor)); - s_genericFunctionPointerCollection.Add(pNewMem); - } - - ((GenericMethodDescriptor*)s_genericFunctionPointerCollection[newChunkIndex])[newSubChunkIndex] = + *(GenericMethodDescriptor*)descriptor = new GenericMethodDescriptor(canonFunctionPointer, instantiationArgument); - s_genericFunctionPointerDictionary.LookupOrAdd(key, index); - - // Now that we can no longer have failed, update the next index. - s_genericFunctionPointerNextIndex++; + s_genericFunctionPointerDictionary.LookupOrAdd(key, descriptor); } - // Lookup within list - int chunkIndex = (int)(index / c_genericDictionaryChunkSize); - uint subChunkIndex = index % c_genericDictionaryChunkSize; - GenericMethodDescriptor* genericFunctionPointer = &((GenericMethodDescriptor*)s_genericFunctionPointerCollection[chunkIndex])[subChunkIndex]; + GenericMethodDescriptor* genericFunctionPointer = (GenericMethodDescriptor*)descriptor; Debug.Assert(canonFunctionPointer == genericFunctionPointer->MethodFunctionPointer); Debug.Assert(instantiationArgument == genericFunctionPointer->InstantiationArgument); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/MethodTable.Runtime.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/MethodTable.Runtime.cs index 899ac448d5f9d8..c0c196713aa846 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/MethodTable.Runtime.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/MethodTable.Runtime.cs @@ -37,7 +37,7 @@ internal bool IsEnum // Generic type definitions that return true for IsPrimitive are type definitions of generic enums. // Otherwise check the base type. - return IsPrimitive && (IsGenericTypeDefinition || NonArrayBaseType == MethodTable.Of()); + return IsPrimitive && (IsGenericTypeDefinition || NonArrayBaseType != MethodTable.Of()); } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/TypeLoaderExceptionHelper.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/TypeLoaderExceptionHelper.cs index 70d17bb96989d7..e837f7c6c96518 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/TypeLoaderExceptionHelper.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/TypeLoaderExceptionHelper.cs @@ -92,6 +92,8 @@ private static string GetFormatString(ExceptionStringID id) return SR.ClassLoad_InlineArrayLength; case ExceptionStringID.ClassLoadInlineArrayExplicit: return SR.ClassLoad_InlineArrayExplicit; + case ExceptionStringID.ClassLoadInlineArrayExplicitSize: + return SR.ClassLoad_InlineArrayExplicitSize; case ExceptionStringID.InvalidProgramDefault: return SR.InvalidProgram_Default; case ExceptionStringID.InvalidProgramSpecific: diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index f8f6e6374592c0..6db8c5a1c5bf98 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -159,6 +159,7 @@ + @@ -185,7 +186,7 @@ - + @@ -324,9 +325,6 @@ Utilities\TypeHashingAlgorithms.cs - - System\Collections\Generic\LowLevelList.cs - System\Collections\Generic\LowLevelDictionary.cs diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs index 92a029cbf9837c..532e84cad3138a 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Delegate.cs @@ -9,6 +9,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; +using System.Threading; using Internal.Reflection.Augments; using Internal.Runtime; @@ -465,7 +466,7 @@ private unsafe Delegate NewMulticastDelegate(Wrapper[] invocationList, int invoc private static bool TrySetSlot(Wrapper[] a, int index, Delegate o) { - if (a[index].Value == null && System.Threading.Interlocked.CompareExchange(ref a[index].Value, o, null) == null) + if (a[index].Value == null && Interlocked.CompareExchange(ref a[index].Value, o, null) == null) return true; // The slot may be already set because we have added and removed the same method before. diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Exception.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Exception.NativeAot.cs index 79ad2b0922da60..9fbfcc9302c562 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Exception.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Exception.NativeAot.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.Tracing; using System.Runtime; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -136,17 +137,13 @@ private static void AppendExceptionStackFrame(object exceptionObj, IntPtr IP, in ex.AppendStackIP(IP, isFirstRethrowFrame); #if FEATURE_PERFTRACING - if (isFirstFrame) + if (isFirstFrame && NativeRuntimeEventSource.Log.IsEnabled()) { string typeName = !fatalOutOfMemory ? ex.GetType().ToString() : "System.OutOfMemoryException"; string message = !fatalOutOfMemory ? ex.Message : "Insufficient memory to continue the execution of the program."; - unsafe - { - fixed (char* exceptionTypeName = typeName, exceptionMessage = message) - RuntimeImports.NativeRuntimeEventSource_LogExceptionThrown(exceptionTypeName, exceptionMessage, IP, ex.HResult); - } + NativeRuntimeEventSource.Log.ExceptionThrown_V1(typeName, message, IP, (uint)ex.HResult, 0); } #endif } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs index 6f6aec5df683aa..3f14becf5ee7cb 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs @@ -764,7 +764,7 @@ public static long GetTotalAllocatedBytes(bool precise = false) /// Gets garbage collection memory information. /// An object that contains information about the garbage collector's memory usage. - public static GCMemoryInfo GetGCMemoryInfo() => GetGCMemoryInfo(GCKind.Any); + public static GCMemoryInfo GetGCMemoryInfo() => GetGCMemoryInfoUnchecked(GCKind.Any); /// Gets garbage collection memory information. /// The kind of collection for which to retrieve memory information. @@ -780,6 +780,11 @@ public static GCMemoryInfo GetGCMemoryInfo(GCKind kind) GCKind.Background)); } + return GetGCMemoryInfoUnchecked(kind); + } + + private static GCMemoryInfo GetGCMemoryInfoUnchecked(GCKind kind) + { var data = new GCMemoryInfoData(); RuntimeImports.RhGetMemoryInfo(ref data.GetRawData(), kind); return new GCMemoryInfo(data); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Assembly.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Assembly.NativeAot.cs index 2e0ba72727f33d..86d20bf94b2edb 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Assembly.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Assembly.NativeAot.cs @@ -35,13 +35,9 @@ public static Assembly Load(string assemblyString) } // Performance metric to count the number of assemblies - // Caching since in NativeAOT, the number will be the same - private static uint s_assemblyCount; internal static uint GetAssemblyCount() { - if (s_assemblyCount == 0) - s_assemblyCount = (uint)Internal.Reflection.Core.Execution.ReflectionCoreExecution.ExecutionEnvironment.AssemblyBinder.GetLoadedAssemblies().Count; - return s_assemblyCount; + return (uint)Internal.Reflection.Core.Execution.ReflectionCoreExecution.ExecutionEnvironment.AssemblyBinder.GetLoadedAssembliesCount(); } [Obsolete("Assembly.LoadWithPartialName has been deprecated. Use Assembly.Load() instead.")] diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs index ff812387e04ddc..66043999644081 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs @@ -22,7 +22,7 @@ internal NamespaceChain(MetadataReader reader, NamespaceDefinitionHandle innerMo NamespaceDefinition currentNamespaceDefinition = innerMostNamespaceHandle.GetNamespaceDefinition(reader); ConstantStringValueHandle currentNameHandle = currentNamespaceDefinition.Name; Handle currentNamespaceHandle; - LowLevelList names = new LowLevelList(); + ListBuilder names = default; for (; ; ) { string name = currentNameHandle.GetStringOrNull(reader); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/AnalysisCharacteristicAttribute.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/AnalysisCharacteristicAttribute.cs new file mode 100644 index 00000000000000..5cebc9511e183b --- /dev/null +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/AnalysisCharacteristicAttribute.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.CompilerServices +{ + // When applied to an intrinsic method, the method will become a characteristic check. + // + // The method needs to return bool and have no parameters. + // + // The compiler will replace the body of the method with a constant true/false depending + // on whether the characteristic (tag) was added to the whole program view. + // The name of the characteristic is the name of the method. + // Compiler can add characteristics to the whole program view using the + // NodeFactory.AnalysisCharacteristic(string) method. + [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] + internal class AnalysisCharacteristicAttribute : Attribute + { + } +} diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs index be875ba1731c52..541f62969ab526 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs @@ -27,18 +27,6 @@ public static void InitializeArray(Array array, RuntimeFieldHandle fldHandle) throw new PlatformNotSupportedException(); } - private static unsafe ref byte GetSpanDataFrom( - RuntimeFieldHandle fldHandle, - RuntimeTypeHandle targetTypeHandle, - out int count) - { - // We only support this intrinsic when it occurs within a well-defined IL sequence. - // If a call to this method occurs within the recognized sequence, codegen must expand the IL sequence completely. - // For any other purpose, the API is currently unsupported. - // https://github.com/dotnet/corert/issues/364 - throw new PlatformNotSupportedException(); - } - [RequiresUnreferencedCode("Trimmer can't guarantee existence of class constructor")] public static void RunClassConstructor(RuntimeTypeHandle type) { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.NativeAot.cs index 7b66abd31635f0..551d50a98b2bbe 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.NativeAot.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.Runtime.CompilerServices; + namespace System.Runtime.InteropServices { public partial struct GCHandle @@ -14,11 +16,24 @@ public partial struct GCHandle internal static void InternalSet(IntPtr handle, object? value) => RuntimeImports.RhHandleSet(handle, value); #if FEATURE_JAVAMARSHAL - // FIXME implement waiting for bridge processing - internal static object? InternalGetBridgeWait(IntPtr handle) + internal static unsafe object? InternalGetBridgeWait(IntPtr handle) { - return InternalGet(handle); + object? target = null; + + if (InternalTryGetBridgeWait(handle, ref target)) + return target; + + InternalGetBridgeWait(handle, &target); + + return target; } + + [MethodImpl(MethodImplOptions.InternalCall)] + [RuntimeImport(RuntimeImports.RuntimeLibrary, "GCHandle_InternalTryGetBridgeWait")] + private static extern bool InternalTryGetBridgeWait(IntPtr handle, ref object? result); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "GCHandle_InternalGetBridgeWait")] + private static unsafe partial void InternalGetBridgeWait(IntPtr handle, object?* result); #endif } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Java/JavaMarshal.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Java/JavaMarshal.NativeAot.cs new file mode 100644 index 00000000000000..c253114be4602d --- /dev/null +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Java/JavaMarshal.NativeAot.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; + +namespace System.Runtime.InteropServices.Java +{ + [CLSCompliant(false)] + [SupportedOSPlatform("android")] + public static partial class JavaMarshal + { + public static unsafe void Initialize(delegate* unmanaged markCrossReferences) + { + ArgumentNullException.ThrowIfNull(markCrossReferences); + + if (!InitializeInternal((IntPtr)markCrossReferences)) + { + throw new InvalidOperationException(SR.InvalidOperation_ReinitializeJavaMarshal); + } + } + + public static unsafe GCHandle CreateReferenceTrackingHandle(object obj, void* context) + { + ArgumentNullException.ThrowIfNull(obj); + return GCHandle.FromIntPtr(RuntimeImports.RhHandleAllocCrossReference(obj, (IntPtr)context)); + } + + public static unsafe void* GetContext(GCHandle obj) + { + IntPtr handle = GCHandle.ToIntPtr(obj); + if (handle == IntPtr.Zero + || !RuntimeImports.RhHandleTryGetCrossReferenceContext(handle, out nint context)) + { + throw new InvalidOperationException(SR.InvalidOperation_IncorrectGCHandleType); + } + return (void*)context; + } + + public static unsafe void FinishCrossReferenceProcessing( + MarkCrossReferencesArgs* crossReferences, + ReadOnlySpan unreachableObjectHandles) + { + fixed (GCHandle* handlesPtr = unreachableObjectHandles) + { + FinishCrossReferenceProcessingBridge( + crossReferences, + (nuint)unreachableObjectHandles.Length, + handlesPtr); + } + } + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "JavaMarshal_Initialize")] + [return: MarshalAs(UnmanagedType.Bool)] + internal static unsafe partial bool InitializeInternal(IntPtr markCrossReferences); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "JavaMarshal_FinishCrossReferenceProcessing")] + internal static unsafe partial void FinishCrossReferenceProcessingBridge( + MarkCrossReferencesArgs* crossReferences, + nuint numHandles, + GCHandle* unreachableObjectHandles); + } +} diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs index 7adbb86c7fcd2d..72a238b0bddde2 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -294,6 +294,26 @@ internal static IntPtr RhHandleAllocDependent(object primary, object secondary) return h; } + [MethodImpl(MethodImplOptions.InternalCall)] + [RuntimeImport(RuntimeLibrary, "RhpHandleAllocCrossReference")] + private static extern IntPtr RhpHandleAllocCrossReference(object value, IntPtr context); + + internal static IntPtr RhHandleAllocCrossReference(object value, IntPtr context) + { + IntPtr h = RhpHandleAllocCrossReference(value, context); + if (h == IntPtr.Zero) + throw new OutOfMemoryException(); + return h; + } + + [MethodImpl(MethodImplOptions.InternalCall)] + [RuntimeImport(RuntimeLibrary, "RhHandleTryGetCrossReferenceContext")] + internal static extern bool RhHandleTryGetCrossReferenceContext(IntPtr handle, out IntPtr context); + + [MethodImpl(MethodImplOptions.InternalCall)] + [RuntimeImport(RuntimeLibrary, "RhIsGCBridgeActive")] + internal static extern bool RhIsGCBridgeActive(); + // Free handle. [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhHandleFree")] @@ -396,7 +416,7 @@ internal static IntPtr RhHandleAllocDependent(object primary, object secondary) [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewString")] - internal static extern unsafe string RhNewString(MethodTable* pEEType, int length); + internal static extern unsafe string RhNewString(MethodTable* pEEType, nint length); [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhUnbox")] @@ -583,6 +603,10 @@ internal static IntPtr RhGetModuleSection(TypeManagerHandle module, ReadyToRunSe [RuntimeImport(RuntimeLibrary, "RhCurrentOSThreadId")] internal static extern unsafe ulong RhCurrentOSThreadId(); + [MethodImplAttribute(MethodImplOptions.InternalCall)] + [RuntimeImport(RuntimeLibrary, "RhGetDefaultStackSize")] + internal static extern unsafe IntPtr RhGetDefaultStackSize(); + [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport("*", "RhGetCurrentThunkContext")] internal static extern IntPtr GetCurrentInteropThunkContext(); @@ -649,11 +673,6 @@ internal static IntPtr RhGetModuleSection(TypeManagerHandle module, ReadyToRunSe [RuntimeImport(RuntimeLibrary, "RhUnregisterForGCReporting")] internal static extern unsafe void RhUnregisterForGCReporting(GCFrameRegistration* pRegistration); -#if FEATURE_PERFTRACING - [LibraryImport(RuntimeLibrary)] - internal static unsafe partial void NativeRuntimeEventSource_LogExceptionThrown(char* exceptionTypeName, char* exceptionMessage, IntPtr faultingIP, int hresult); -#endif // FEATURE_PERFTRACING - // // Interlocked helpers // diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs index ad8ff25374de80..a139757b4b69e6 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs @@ -192,23 +192,49 @@ public struct ExceptionInformationArray } private static ulong s_crashingThreadId; + private static IntPtr s_triageBufferAddress; + private static int s_triageBufferSize; + private static volatile int s_crashInfoPresent; + + internal static void SerializeCrashInfo(RhFailFastReason reason, string? message, Exception? exception) + { + int previousState = Interlocked.CompareExchange(ref s_crashInfoPresent, -1, 0); + if (previousState == 0) + { + CrashInfo crashInfo = new(); + + crashInfo.Open(reason, Thread.CurrentOSThreadId, message ?? GetStringForFailFastReason(reason)); + if (exception != null) + { + crashInfo.WriteException(exception); + } + crashInfo.Close(); + s_triageBufferAddress = crashInfo.TriageBufferAddress; + s_triageBufferSize = crashInfo.TriageBufferSize; + + s_crashInfoPresent = 1; + } + else + { + while (s_crashInfoPresent != 1) + { + // Some other thread is generating the crash info + Thread.Sleep(1); + } + } + } [DoesNotReturn] internal static unsafe void FailFast(string? message = null, Exception? exception = null, string? errorSource = null, RhFailFastReason reason = RhFailFastReason.EnvironmentFailFast, IntPtr pExAddress = 0, IntPtr pExContext = 0) { - IntPtr triageBufferAddress = IntPtr.Zero; - int triageBufferSize = 0; int errorCode = 0; ulong currentThreadId = Thread.CurrentOSThreadId; ulong previousThreadId = Interlocked.CompareExchange(ref s_crashingThreadId, currentThreadId, 0); if (previousThreadId == 0) { - CrashInfo crashInfo = new(); - crashInfo.Open(reason, s_crashingThreadId, message ?? GetStringForFailFastReason(reason)); - bool minimalFailFast = (exception == PreallocatedOutOfMemoryException.Instance); if (!minimalFailFast) { @@ -264,17 +290,9 @@ internal static unsafe void FailFast(string? message = null, Exception? exceptio reporter.Report(); } #endif + } // !minimalFailFast - if (exception != null) - { - crashInfo.WriteException(exception); - } - } - - crashInfo.Close(); - - triageBufferAddress = crashInfo.TriageBufferAddress; - triageBufferSize = crashInfo.TriageBufferSize; + SerializeCrashInfo(reason, message, minimalFailFast ? null : exception); // Try to map the failure into a HRESULT that makes sense errorCode = exception != null ? exception.HResult : reason switch @@ -310,8 +328,8 @@ internal static unsafe void FailFast(string? message = null, Exception? exceptio exceptionRecord.NumberParameters = 4; exceptionRecord.ExceptionInformation[0] = FAST_FAIL_EXCEPTION_DOTNET_AOT; exceptionRecord.ExceptionInformation[1] = (uint)errorCode; - exceptionRecord.ExceptionInformation[2] = (nuint)triageBufferAddress; - exceptionRecord.ExceptionInformation[3] = (uint)triageBufferSize; + exceptionRecord.ExceptionInformation[2] = (nuint)s_triageBufferAddress; + exceptionRecord.ExceptionInformation[3] = (uint)s_triageBufferSize; #if TARGET_WINDOWS Interop.Kernel32.RaiseFailFastException(new IntPtr(&exceptionRecord), pExContext, pExAddress == IntPtr.Zero ? FAIL_FAST_GENERATE_EXCEPTION_ADDRESS : 0); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.NativeAot.cs similarity index 99% rename from src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.NativeAot.cs index 1854e6ddeb210d..c417aaad804bb0 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.NativeAot.cs @@ -213,7 +213,7 @@ public override RuntimeTypeHandle TypeHandle } } - internal new unsafe bool IsInterface + internal unsafe bool IsActualInterface { get { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/String.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/String.NativeAot.cs index a8efc76018a30d..2e951b445befe9 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/String.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/String.NativeAot.cs @@ -18,7 +18,7 @@ public partial class String [Intrinsic] public static readonly string Empty = ""; - internal static unsafe string FastAllocateString(int length) + internal static unsafe string FastAllocateString(nint length) { // We allocate one extra char as an interop convenience so that our strings are null- // terminated, however, we don't pass the extra +1 to the string allocation because the base diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Thread.NativeAot.Unix.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Thread.NativeAot.Unix.cs index f9e49db5323045..de77bc91b088e3 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Thread.NativeAot.Unix.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Thread.NativeAot.Unix.cs @@ -94,7 +94,14 @@ private unsafe bool CreateThread(GCHandle thisThreadHandle) // This also avoids OOM after creating the thread. _stopped = new ManualResetEvent(false); - if (!Interop.Sys.CreateThread((IntPtr)_startHelper!._maxStackSize, &ThreadEntryPoint, GCHandle.ToIntPtr(thisThreadHandle))) + nint stackSize = _startHelper!._maxStackSize; + + if (stackSize <= 0) + { + stackSize = RuntimeImports.RhGetDefaultStackSize(); + } + + if (!Interop.Sys.CreateThread(stackSize, &ThreadEntryPoint, GCHandle.ToIntPtr(thisThreadHandle))) { return false; } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Thread.NativeAot.Windows.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Thread.NativeAot.Windows.cs index c579f4b3a00e32..f01fe0f86f38f7 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Thread.NativeAot.Windows.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Thread.NativeAot.Windows.cs @@ -176,8 +176,13 @@ private bool JoinInternal(int millisecondsTimeout) private unsafe bool CreateThread(GCHandle thisThreadHandle) { const int AllocationGranularity = 0x10000; // 64 KiB - int stackSize = _startHelper._maxStackSize; + + if (stackSize <= 0) + { + stackSize = (int)RuntimeImports.RhGetDefaultStackSize(); + } + if ((0 < stackSize) && (stackSize < AllocationGranularity)) { // If StackSizeParamIsAReservation flag is set and the reserve size specified by CreateThread's @@ -284,7 +289,14 @@ private bool SetApartmentStateUnchecked(ApartmentState state, bool throwOnError) { if (throwOnError) { - string msg = SR.Format(SR.Thread_ApartmentState_ChangeFailed, retState); + // NOTE: We do the enum stringification manually to avoid introducing a dependency + // on enum stringification in small apps. We set apartment state in the startup path. + string msg = SR.Format(SR.Thread_ApartmentState_ChangeFailed, retState switch + { + ApartmentState.MTA => "MTA", + ApartmentState.STA => "STA", + _ => "Unknown" + }); throw new InvalidOperationException(msg); } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj index 86fb64fa51852c..823a6e0564f095 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj @@ -1,4 +1,4 @@ - + @@ -56,9 +56,6 @@ System\NotImplemented.cs - - System\Collections\Generic\LowLevelList.cs - System\Collections\Generic\LowLevelDictionary.cs @@ -74,8 +71,5 @@ System\Collections\HashHelpers.cs - - System\Collections\Generic\Empty.cs - diff --git a/src/coreclr/nativeaot/System.Private.StackTraceMetadata/src/Internal/StackTraceMetadata/StackTraceMetadata.cs b/src/coreclr/nativeaot/System.Private.StackTraceMetadata/src/Internal/StackTraceMetadata/StackTraceMetadata.cs index 008119ebd10cad..352568239c0d4e 100644 --- a/src/coreclr/nativeaot/System.Private.StackTraceMetadata/src/Internal/StackTraceMetadata/StackTraceMetadata.cs +++ b/src/coreclr/nativeaot/System.Private.StackTraceMetadata/src/Internal/StackTraceMetadata/StackTraceMetadata.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Reflection.Runtime.General; +using System.Runtime.CompilerServices; using Internal.Metadata.NativeFormat; using Internal.NativeFormat; @@ -41,6 +42,10 @@ internal static void Initialize() RuntimeAugments.InitializeStackTraceMetadataSupport(new StackTraceMetadataCallbacksImpl()); } + [Intrinsic] + [AnalysisCharacteristic] + internal static extern bool StackTraceHiddenMetadataPresent(); + /// /// Locate the containing module for a method and try to resolve its name based on start address. /// @@ -75,21 +80,24 @@ public static unsafe string GetMethodNameFromStartAddressIfAvailable(IntPtr meth out TypeDefinitionHandle typeHandle, out MethodHandle methodHandle)) { - foreach (CustomAttributeHandle cah in reader.GetTypeDefinition(typeHandle).CustomAttributes) + if (StackTraceHiddenMetadataPresent()) { - if (cah.IsCustomAttributeOfType(reader, ["System", "Diagnostics"], "StackTraceHiddenAttribute")) + foreach (CustomAttributeHandle cah in reader.GetTypeDefinition(typeHandle).CustomAttributes) { - isStackTraceHidden = true; - break; + if (cah.IsCustomAttributeOfType(reader, ["System", "Diagnostics"], "StackTraceHiddenAttribute")) + { + isStackTraceHidden = true; + break; + } } - } - foreach (CustomAttributeHandle cah in reader.GetMethod(methodHandle).CustomAttributes) - { - if (cah.IsCustomAttributeOfType(reader, ["System", "Diagnostics"], "StackTraceHiddenAttribute")) + foreach (CustomAttributeHandle cah in reader.GetMethod(methodHandle).CustomAttributes) { - isStackTraceHidden = true; - break; + if (cah.IsCustomAttributeOfType(reader, ["System", "Diagnostics"], "StackTraceHiddenAttribute")) + { + isStackTraceHidden = true; + break; + } } } diff --git a/src/coreclr/nativeaot/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.csproj b/src/coreclr/nativeaot/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.csproj index cd40e0ec8ba54d..1fe8f87c09d76e 100644 --- a/src/coreclr/nativeaot/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.csproj +++ b/src/coreclr/nativeaot/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.csproj @@ -23,5 +23,7 @@ Internal\Runtime\StackTraceData.cs + + diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Reflection/Execution/AssemblyBinderImplementation.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Reflection/Execution/AssemblyBinderImplementation.cs index fba014a2415992..43bda9d00fb01a 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Reflection/Execution/AssemblyBinderImplementation.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Reflection/Execution/AssemblyBinderImplementation.cs @@ -94,6 +94,11 @@ public sealed override IList GetLoadedAssemblies() return loadedAssemblies; } + public sealed override int GetLoadedAssembliesCount() + { + return ScopeGroups.Length; + } + // // Encapsulates the assembly ref->def matching policy. // diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/GenericDictionaryCell.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/GenericDictionaryCell.cs index eb911d4037afde..c630754b50bb5f 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/GenericDictionaryCell.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/GenericDictionaryCell.cs @@ -140,10 +140,41 @@ internal override IntPtr Create(TypeBuilder builder) } } + /// + /// Used for non-generic instance constrained Methods + /// + private class NonGenericInstanceConstrainedMethodCell : GenericDictionaryCell + { + internal TypeDesc ConstraintType; + internal TypeDesc ConstrainedMethodType; + internal int ConstrainedMethodSlot; + + internal override void Prepare(TypeBuilder builder) + { + if (ConstraintType.IsCanonicalSubtype(CanonicalFormKind.Any) || ConstrainedMethodType.IsCanonicalSubtype(CanonicalFormKind.Any)) + Environment.FailFast("Unable to compute call information for a canonical type/method."); + + builder.RegisterForPreparation(ConstraintType); + builder.RegisterForPreparation(ConstrainedMethodType); + } + + internal override IntPtr Create(TypeBuilder builder) + { + IntPtr result = RuntimeAugments.ResolveDispatchOnType( + builder.GetRuntimeTypeHandle(ConstraintType), + builder.GetRuntimeTypeHandle(ConstrainedMethodType), + ConstrainedMethodSlot); + + Debug.Assert(result != IntPtr.Zero); + + return result; + } + } + /// /// Used for generic static constrained Methods /// - private class GenericStaticConstrainedMethodCell : GenericDictionaryCell + private class GenericConstrainedMethodCell : GenericDictionaryCell { internal DefType ConstraintType; internal InstantiatedMethod ConstrainedMethod; @@ -512,29 +543,45 @@ internal static GenericDictionaryCell ParseAndCreateCell(NativeLayoutInfoLoadCon break; case FixupSignatureKind.NonGenericStaticConstrainedMethod: - { + case FixupSignatureKind.NonGenericInstanceConstrainedMethod: + { var constraintType = nativeLayoutInfoLoadContext.GetType(ref parser); var constrainedMethodType = nativeLayoutInfoLoadContext.GetType(ref parser); var constrainedMethodSlot = parser.GetUnsigned(); - TypeLoaderLogger.WriteLine("NonGenericStaticConstrainedMethod: " + constraintType.ToString() + " Method " + constrainedMethodType.ToString() + ", slot #" + constrainedMethodSlot.LowLevelToString()); - cell = new NonGenericStaticConstrainedMethodCell() + string kindString = kind == FixupSignatureKind.NonGenericStaticConstrainedMethod ? "NonGenericStaticConstrainedMethod: " : "NonGenericInstanceConstrainedMethod: "; + + TypeLoaderLogger.WriteLine(kindString + constraintType.ToString() + " Method " + constrainedMethodType.ToString() + ", slot #" + constrainedMethodSlot.LowLevelToString()); + + if (kind == FixupSignatureKind.NonGenericStaticConstrainedMethod) { - ConstraintType = constraintType, - ConstrainedMethodType = constrainedMethodType, - ConstrainedMethodSlot = (int)constrainedMethodSlot - }; + cell = new NonGenericStaticConstrainedMethodCell() + { + ConstraintType = constraintType, + ConstrainedMethodType = constrainedMethodType, + ConstrainedMethodSlot = (int)constrainedMethodSlot + }; + } + else + { + cell = new NonGenericInstanceConstrainedMethodCell() + { + ConstraintType = constraintType, + ConstrainedMethodType = constrainedMethodType, + ConstrainedMethodSlot = (int)constrainedMethodSlot + }; + } } break; - case FixupSignatureKind.GenericStaticConstrainedMethod: - { + case FixupSignatureKind.GenericConstrainedMethod: + { TypeDesc constraintType = nativeLayoutInfoLoadContext.GetType(ref parser); MethodDesc constrainedMethod = nativeLayoutInfoLoadContext.GetMethod(ref parser); - TypeLoaderLogger.WriteLine("GenericStaticConstrainedMethod: " + constraintType.ToString() + " Method " + constrainedMethod.ToString()); + TypeLoaderLogger.WriteLine("GenericConstrainedMethod: " + constraintType.ToString() + " Method " + constrainedMethod.ToString()); - cell = new GenericStaticConstrainedMethodCell() + cell = new GenericConstrainedMethodCell() { ConstraintType = (DefType)constraintType, ConstrainedMethod = (InstantiatedMethod)constrainedMethod, diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs index 6f8b02d93ead60..50b0491f6b734f 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs @@ -26,11 +26,11 @@ public TypeBuilder() /// public static unsafe int ClassConstructorOffset => -sizeof(System.Runtime.CompilerServices.StaticClassConstructionContext); - private LowLevelList _typesThatNeedTypeHandles = new LowLevelList(); + private ArrayBuilder _typesThatNeedTypeHandles; - private LowLevelList _methodsThatNeedDictionaries = new LowLevelList(); + private ArrayBuilder _methodsThatNeedDictionaries; - private LowLevelList _typesThatNeedPreparation; + private ArrayBuilder _typesThatNeedPreparation; #if DEBUG private bool _finalTypeBuilding; @@ -88,8 +88,6 @@ public void RegisterForPreparation(TypeDesc type) if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) return; - _typesThatNeedPreparation ??= new LowLevelList(); - _typesThatNeedPreparation.Add(type); } @@ -266,10 +264,10 @@ private void PrepareBaseTypeAndDictionaries(TypeDesc type) private void ProcessTypesNeedingPreparation() { // Process the pending types - while (_typesThatNeedPreparation != null) + while (_typesThatNeedPreparation.Count > 0) { var pendingTypes = _typesThatNeedPreparation; - _typesThatNeedPreparation = null; + _typesThatNeedPreparation = default; for (int i = 0; i < pendingTypes.Count; i++) PrepareType(pendingTypes[i]); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericMethodsLookup.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericMethodsLookup.cs index 4330ad08aea7e9..fe1c59215b9be0 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericMethodsLookup.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericMethodsLookup.cs @@ -146,28 +146,53 @@ internal override bool MatchParsedEntry(ref NativeParser entryParser, ref Extern TypeSystemContext context = _methodToLookup.Context; RuntimeTypeHandle parsedDeclaringTypeHandle = externalReferencesLookup.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); + TypeDesc parsedDeclaringType = context.ResolveRuntimeTypeHandle(parsedDeclaringTypeHandle); + if (_methodToLookup.OwningType != parsedDeclaringType) + return false; // Hash table names / sigs are indirected through to the native layout info MethodNameAndSignature nameAndSignature = TypeLoaderEnvironment.GetMethodNameAndSignatureFromToken(moduleHandle, entryParser.GetUnsigned()); + if (!_methodToLookup.NameAndSignature.Equals(nameAndSignature)) + return false; RuntimeTypeHandle[] parsedArgsHandles = GetTypeSequence(ref externalReferencesLookup, ref entryParser); + if (parsedArgsHandles.Length != _methodToLookup.Instantiation.Length) + return false; - DefType parsedDeclaringType = context.ResolveRuntimeTypeHandle(parsedDeclaringTypeHandle) as DefType; - Instantiation parsedArgs = context.ResolveRuntimeTypeHandles(parsedArgsHandles); - InstantiatedMethod parsedGenericMethod = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, parsedDeclaringType, nameAndSignature, parsedArgs); + for (int i = 0; i < _methodToLookup.Instantiation.Length; i++) + { + TypeDesc leftType = context.ResolveRuntimeTypeHandle(parsedArgsHandles[i]); + TypeDesc rightType = _methodToLookup.Instantiation[i]; + if (leftType != rightType) + return false; + } - return parsedGenericMethod == _methodToLookup; + return true; } internal override bool MatchGenericMethodEntry(GenericMethodEntry entry) { TypeSystemContext context = _methodToLookup.Context; - DefType parsedDeclaringType = context.ResolveRuntimeTypeHandle(entry._declaringTypeHandle) as DefType; - Instantiation parsedArgs = context.ResolveRuntimeTypeHandles(entry._genericMethodArgumentHandles); - InstantiatedMethod parsedGenericMethod = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, parsedDeclaringType, entry._methodNameAndSignature, parsedArgs); + TypeDesc parsedDeclaringType = context.ResolveRuntimeTypeHandle(entry._declaringTypeHandle); + if (_methodToLookup.OwningType != parsedDeclaringType) + return false; - return parsedGenericMethod == _methodToLookup; + if (!_methodToLookup.NameAndSignature.Equals(entry._methodNameAndSignature)) + return false; + + if (entry._genericMethodArgumentHandles.Length != _methodToLookup.Instantiation.Length) + return false; + + for (int i = 0; i < _methodToLookup.Instantiation.Length; i++) + { + TypeDesc leftType = context.ResolveRuntimeTypeHandle(entry._genericMethodArgumentHandles[i]); + TypeDesc rightType = _methodToLookup.Instantiation[i]; + if (leftType != rightType) + return false; + } + + return true; } } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.GVMResolution.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.GVMResolution.cs index 568a8a444c3975..1b6d16fa3ffd1c 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.GVMResolution.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.GVMResolution.cs @@ -330,7 +330,7 @@ private static InstantiatedMethod ResolveInterfaceGenericVirtualMethodSlot(DefTy RuntimeTypeHandle openTargetTypeHandle = targetType.GetTypeDefinition().RuntimeTypeHandle; #if GVM_RESOLUTION_TRACE - Debug.WriteLine("INTERFACE GVM call = " + GetTypeNameDebug(slotMethod.OwningType) + "." + slotMethod.NameAndSignature.Name); + Debug.WriteLine("INTERFACE GVM call = " + GetTypeNameDebug(slotMethod.OwningType) + "." + slotMethod.Name); #endif foreach (NativeFormatModuleInfo module in ModuleList.EnumerateModules(RuntimeAugments.GetModuleFromTypeHandle(openTargetTypeHandle))) @@ -459,7 +459,7 @@ private static InstantiatedMethod ResolveGenericVirtualMethodTarget(DefType targ hashCode = ((hashCode << 13) ^ hashCode) ^ openTargetTypeHandle.GetHashCode(); #if GVM_RESOLUTION_TRACE - Debug.WriteLine("GVM Target Resolution = " + GetTypeNameDebug(targetType) + "." + slotMethod.NameAndSignature.Name); + Debug.WriteLine("GVM Target Resolution = " + GetTypeNameDebug(targetType) + "." + slotMethod.Name); #endif foreach (NativeFormatModuleInfo module in ModuleList.EnumerateModules(RuntimeAugments.GetModuleFromTypeHandle(openTargetTypeHandle))) diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/WellKnownTypeExtensions.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/WellKnownTypeExtensions.cs deleted file mode 100644 index 4db542dcc1bbaa..00000000000000 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/WellKnownTypeExtensions.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; - -using Internal.TypeSystem; - -namespace Internal.Runtime.TypeLoader -{ - public static class WellKnownTypeExtensions - { - public static RuntimeTypeHandle GetRuntimeTypeHandle(this WellKnownType wkt) - { - switch (wkt) - { - case WellKnownType.Void: - return typeof(void).TypeHandle; - case WellKnownType.Boolean: - return typeof(bool).TypeHandle; - case WellKnownType.Char: - return typeof(char).TypeHandle; - case WellKnownType.SByte: - return typeof(sbyte).TypeHandle; - case WellKnownType.Byte: - return typeof(byte).TypeHandle; - case WellKnownType.Int16: - return typeof(short).TypeHandle; - case WellKnownType.UInt16: - return typeof(ushort).TypeHandle; - case WellKnownType.Int32: - return typeof(int).TypeHandle; - case WellKnownType.UInt32: - return typeof(uint).TypeHandle; - case WellKnownType.Int64: - return typeof(long).TypeHandle; - case WellKnownType.UInt64: - return typeof(ulong).TypeHandle; - case WellKnownType.IntPtr: - return typeof(IntPtr).TypeHandle; - case WellKnownType.UIntPtr: - return typeof(UIntPtr).TypeHandle; - case WellKnownType.Single: - return typeof(float).TypeHandle; - case WellKnownType.Double: - return typeof(double).TypeHandle; - case WellKnownType.String: - return typeof(string).TypeHandle; - default: - Debug.Assert(false); - return default(RuntimeTypeHandle); - } - } - } -} diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/AssemblyNameInfo.Dummy.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/AssemblyNameInfo.Dummy.cs index 51d07ba6a15add..01e8b49989759a 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/AssemblyNameInfo.Dummy.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/AssemblyNameInfo.Dummy.cs @@ -6,6 +6,6 @@ namespace Internal.TypeSystem // Dummy implementation of AssemlyNameInfo for runtime type system public abstract class AssemblyNameInfo { - public abstract string FullName { get; } + public abstract string Name { get; } } } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs index 6391cf78abaa65..2cc527b21f4d31 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs @@ -511,7 +511,7 @@ public virtual int LoadFactor } } - private LowLevelList _typesToFlushTypeSystemStateFrom; + private ArrayBuilder _typesToFlushTypeSystemStateFrom; /// /// Register the types that will get their attached TypeSystemState flushed if the @@ -519,7 +519,6 @@ public virtual int LoadFactor /// internal void RegisterTypeForTypeSystemStateFlushing(TypeDesc type) { - _typesToFlushTypeSystemStateFrom ??= new LowLevelList(); _typesToFlushTypeSystemStateFrom.Add(type); } @@ -529,14 +528,11 @@ internal void RegisterTypeForTypeSystemStateFlushing(TypeDesc type) /// internal void FlushTypeBuilderStates() { - if (_typesToFlushTypeSystemStateFrom != null) + for (int i = 0; i < _typesToFlushTypeSystemStateFrom.Count; i++) { - for (int i = 0; i < _typesToFlushTypeSystemStateFrom.Count; i++) - { - _typesToFlushTypeSystemStateFrom[i].TypeBuilderState = null; - } + _typesToFlushTypeSystemStateFrom[i].TypeBuilderState = null; } - _typesToFlushTypeSystemStateFrom = null; + _typesToFlushTypeSystemStateFrom = default; } } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj b/src/coreclr/nativeaot/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj index 367dd4750479e5..b14c69d765daf6 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj @@ -1,4 +1,4 @@ - + disable TYPE_LOADER_IMPLEMENTATION;$(DefineConstants) @@ -35,9 +35,6 @@ TransitionBlock.cs - - LowLevelList.cs - MetadataBlob.cs @@ -244,7 +241,6 @@ - diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs index 026f0b8d109cc6..7703d63dee84a0 100644 --- a/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -82,7 +82,7 @@ internal static IntPtr RhGetModuleSection(TypeManagerHandle module, ReadyToRunSe [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewString")] - internal static extern unsafe string RhNewString(MethodTable* pEEType, int length); + internal static extern unsafe string RhNewString(MethodTable* pEEType, nint length); [DllImport(RuntimeLibrary)] internal static extern unsafe void RhAllocateNewArray(MethodTable* pArrayEEType, uint numElements, uint flags, void* pResult); diff --git a/src/coreclr/nativeaot/docs/README.md b/src/coreclr/nativeaot/docs/README.md index 74002dda6065d5..ffa0d580698617 100644 --- a/src/coreclr/nativeaot/docs/README.md +++ b/src/coreclr/nativeaot/docs/README.md @@ -1,9 +1,9 @@ # Using Native AOT -- [Limitations](limitations.md) -- [Compiling applications](compiling.md) -- [Building native AOT apps in containers](containers.md) -- [Debugging applications](debugging.md) +See the official documentation at https://learn.microsoft.com/dotnet/core/deploying/native-aot/. + +- [Compiling with Native AOT (advanced topics)](compiling.md) +- [Building Native AOT apps in containers](containers.md) - [Optimizing applications](optimizing.md) - [Troubleshooting](troubleshooting.md) - [RD.xml Documentation](rd-xml-format.md) diff --git a/src/coreclr/nativeaot/docs/debugging.md b/src/coreclr/nativeaot/docs/debugging.md deleted file mode 100644 index 8b9fed76668aa2..00000000000000 --- a/src/coreclr/nativeaot/docs/debugging.md +++ /dev/null @@ -1,15 +0,0 @@ -# Debugging NativeAOT programs - -The NativeAOT ahead of time compiler generates fully native executable files that can be debugged by native debuggers on your platform of choice (e.g. WinDbg or Visual Studio on Windows, and gdb or lldb on Unix-like systems). - -The NativeAOT compiler generates information about line numbers, types, locals and parameters. The native debugger will let you inspect stack trace and variables, step into/over source lines, or set line breakpoints. - -To debug managed exceptions, set a breakpoint on the `RhThrowEx` method - this method is called whenever a managed exception is thrown. - -## Visual Studio-specific notes - -You can launch a NativeAOT-compiled executable under the VS debugger by opening it in the Visual Studio IDE. In the `File` menu, choose `Open Project/Solution...` and navigate to the native executable. You can set breakpoints as needed. To start debugging the EXE, choose the `Start Debugging` option from the `Debug` menu. - -To set a breakpoint that breaks whenever an exception is thrown, choose the `Breakpoints` option from the `Debug` -> `Windows` menu. In the new window, select `New` -> `Function breakpoint`. Specify `RhThrowEx` as the Function Name and leave the Language option at "All Languages" (do not select C#). - -To see what exception was thrown, start debugging (`Debug` -> `Start Debugging` or `F5`), open the Watches window (`Debug` -> `Windows` -> `Watch`) and add following expression as one of the watches: `(S_P_CoreLib_System_Exception*)@rcx`. This leverages the fact that at the time `RhThrowEx` is called, the x64 CPU register RCX contains the thrown exception. You can also paste the expression into the `Immediate Window`; the syntax is the same as for watches. diff --git a/src/coreclr/nativeaot/docs/limitations.md b/src/coreclr/nativeaot/docs/limitations.md deleted file mode 100644 index 0a7a9bced6685a..00000000000000 --- a/src/coreclr/nativeaot/docs/limitations.md +++ /dev/null @@ -1,12 +0,0 @@ -# Limitations of Native AOT Runtime - -The native AOT .NET runtime form factor comes with a number of fundamental limitations and compatibility issues. The reasons -behind them are discussed in length in -the [.NET Runtime Form Factors](https://github.com/dotnet/designs/blob/main/accepted/2020/form-factors.md) roadmap. - -The key limitations include: - -- No dynamic loading (e.g. `Assembly.LoadFile`) -- No runtime code generation (e.g. `System.Reflection.Emit`) -- No C++/CLI, no built-in COM and WinRT interop support -- No [unconstrained reflection](reflection-in-aot-mode.md) diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 8da66ba362488a..d9f338c40e7e5c 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -1896,6 +1896,9 @@ typedef union IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA { #define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS) +#define CONTEXT_LSX 0x10 +#define CONTEXT_LASX 0x20 + #define CONTEXT_EXCEPTION_ACTIVE 0x8000000 #define CONTEXT_SERVICE_ACTIVE 0x10000000 #define CONTEXT_EXCEPTION_REQUEST 0x40000000 @@ -3574,11 +3577,6 @@ RtlCaptureContext( OUT PCONTEXT ContextRecord ); -PALIMPORT -VOID -PALAPI -FlushProcessWriteBuffers(); - typedef void (*PAL_ActivationFunction)(CONTEXT *context); typedef BOOL (*PAL_SafeActivationCheckFunction)(SIZE_T ip); @@ -4334,4 +4332,10 @@ class NativeExceptionHolderFactory } #endif +#ifndef TARGET_WASM +#define _ReturnAddress() __builtin_return_address(0) +#else +#define _ReturnAddress() 0 +#endif + #endif // __PAL_H__ diff --git a/src/coreclr/pal/inc/rt/palrt.h b/src/coreclr/pal/inc/rt/palrt.h index 215290ce093439..45ed97d670f7ee 100644 --- a/src/coreclr/pal/inc/rt/palrt.h +++ b/src/coreclr/pal/inc/rt/palrt.h @@ -751,8 +751,6 @@ typedef struct _LIST_ENTRY { #define RUNTIME_FUNCTION_INDIRECT 0x1 #endif -#define _ReturnAddress() __builtin_return_address(0) - #define DIRECTORY_SEPARATOR_CHAR_A '/' #define DIRECTORY_SEPARATOR_CHAR_W W('/') #define DIRECTORY_SEPARATOR_STR_A "/" @@ -1006,9 +1004,9 @@ typedef struct _DISPATCHER_CONTEXT { #elif defined(HOST_WASM) typedef struct _DISPATCHER_CONTEXT { - // WASM does not build the VM or JIT at this point, - // so we only provide a dummy definition. - DWORD Reserved; + // WASM does not build the JIT at this point, + // so we only add necessary fields. + UINT32 ControlPc; } DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT; #else diff --git a/src/coreclr/pal/inc/unixasmmacrosarm64.inc b/src/coreclr/pal/inc/unixasmmacrosarm64.inc index 6dd2b20d58acb6..ae5854a995c947 100644 --- a/src/coreclr/pal/inc/unixasmmacrosarm64.inc +++ b/src/coreclr/pal/inc/unixasmmacrosarm64.inc @@ -204,9 +204,9 @@ C_FUNC(\Name\()_End): __PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters - .if (__PWTB_SaveFPArgs == 1) - __PWTB_TransitionBlock = __PWTB_TransitionBlock + SIZEOF__FloatArgumentRegisters - .endif + // Always reserve space for the FP arg regs, even if they are not saved in the PROLOG_WITH_TRANSITION_BLOCK + // Some code using this macro saves them optionally + __PWTB_TransitionBlock = __PWTB_TransitionBlock + SIZEOF__FloatArgumentRegisters __PWTB_StackAlloc = __PWTB_TransitionBlock __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 104 diff --git a/src/coreclr/pal/inc/unixasmmacrosloongarch64.inc b/src/coreclr/pal/inc/unixasmmacrosloongarch64.inc index e44f07ddf4fd40..66ebdd147535e9 100644 --- a/src/coreclr/pal/inc/unixasmmacrosloongarch64.inc +++ b/src/coreclr/pal/inc/unixasmmacrosloongarch64.inc @@ -82,14 +82,8 @@ C_FUNC(\Name\()_End): ////NOTE: reg1 and reg2 must be the number and GPR type !!! .macro PROLOG_SAVE_REG_PAIR reg1, reg2, ofs, __def_cfa_save=0 -//#ifdef FEATURE_LOONGSONISA -// //NOTE:The offset of gssq/gslq must be 16-bytes aligned. -// // here ofs must be 16-bytes aligned. -// gssq \reg2, \reg1, \ofs(sp) -//#else st.d $r\reg1, $sp, \ofs st.d $r\reg2, $sp, \ofs+8 -//#endif .cfi_rel_offset \reg1, \ofs .cfi_rel_offset \reg2, \ofs + 8 @@ -123,23 +117,15 @@ C_FUNC(\Name\()_End): .endm .macro EPILOG_RESTORE_REG_PAIR reg1, reg2, ofs -//#ifdef FEATURE_LOONGSONISA -// gslq \reg2, \reg1, \ofs(sp) -//#else ld.d $r\reg2, $sp, \ofs+8 ld.d $r\reg1, $sp, \ofs -//#endif .cfi_restore \reg2 .cfi_restore \reg1 .endm .macro EPILOG_RESTORE_REG_PAIR_INDEXED reg1, reg2, ssize -//#ifdef FEATURE_LOONGSONISA -// gslq \reg2, \reg1, 0(sp) -//#else ld.d $r\reg2, $sp, 8 ld.d $r\reg1, $sp, 0 -//#endif .cfi_restore \reg2 .cfi_restore \reg1 @@ -183,14 +169,6 @@ C_FUNC(\Name\()_End): // Reserve 64 bytes of memory before calling SAVE_ARGUMENT_REGISTERS .macro SAVE_ARGUMENT_REGISTERS reg, ofs -//#ifdef FEATURE_LOONGSONISA -// //NOTE:The offset of gssq/gslq must be 16-bytes aligned. -// // here ofs must be 16-bytes aligned. -// gssq a1, a0, \ofs(\reg) -// gssq a3, a2, \ofs+16(\reg) -// gssq a5, a4, \ofs+32(\reg) -// gssq a7, a6, \ofs+48(\reg) -//#else st.d $a0, \reg, \ofs st.d $a1, \reg, \ofs+8 st.d $a2, \reg, \ofs+16 @@ -199,21 +177,12 @@ C_FUNC(\Name\()_End): st.d $a5, \reg, \ofs+40 st.d $a6, \reg, \ofs+48 st.d $a7, \reg, \ofs+56 -//#endif .endm // Reserve 64 bytes of memory before calling SAVE_FLOAT_ARGUMENT_REGISTERS .macro SAVE_FLOAT_ARGUMENT_REGISTERS reg, ofs -//#ifdef FEATURE_LOONGSONISA -// //NOTE:The offset of gssqc1/gslqc1 must be 16-bytes aligned. -// // here ofs must be 16-bytes aligned. -// gssqc1 $f13, $f12, \ofs(\reg) -// gssqc1 $f15, $f14, \ofs+16(\reg) -// gssqc1 $f17, $f16, \ofs+32(\reg) -// gssqc1 $f19, $f18, \ofs+48(\reg) -//#else fst.d $f0, \reg, \ofs fst.d $f1, \reg, \ofs+8 fst.d $f2, \reg, \ofs+16 @@ -222,21 +191,12 @@ C_FUNC(\Name\()_End): fst.d $f5, \reg, \ofs+40 fst.d $f6, \reg, \ofs+48 fst.d $f7, \reg, \ofs+56 -//#endif .endm // Reserve 64 bytes of memory before calling SAVE_FLOAT_CALLEESAVED_REGISTERS .macro SAVE_FLOAT_CALLEESAVED_REGISTERS reg, ofs -//#ifdef FEATURE_LOONGSONISA -// //NOTE:The offset of gssqc1/gslqc1 must be 16-bytes aligned. -// // here ofs must be 16-bytes aligned. -// gssqc1 $f25, $f24, \ofs(\reg) -// gssqc1 $f27, $f26, \ofs+16(\reg) -// gssqc1 $f29, $f28, \ofs+32(\reg) -// gssqc1 $f31, $f30, \ofs+48(\reg) -//#else fst.d $f24, \reg, \ofs fst.d $f25, \reg, \ofs+8 fst.d $f26, \reg, \ofs+16 @@ -245,7 +205,6 @@ C_FUNC(\Name\()_End): fst.d $f29, \reg, \ofs+40 fst.d $f30, \reg, \ofs+48 fst.d $f31, \reg, \ofs+56 -//#endif .endm @@ -260,14 +219,6 @@ C_FUNC(\Name\()_End): .macro RESTORE_ARGUMENT_REGISTERS reg, ofs -//#ifdef FEATURE_LOONGSONISA -// //NOTE:The offset of gssq/gslq must be 16-bytes aligned. -// // here ofs must be 16-bytes aligned. -// gslq a7, a6, \ofs+48(\reg) -// gslq a5, a4, \ofs+32(\reg) -// gslq a3, a2, \ofs+16(\reg) -// gslq a1, a0, \ofs(\reg) -//#else ld.d $a7, \reg, \ofs+56 ld.d $a6, \reg, \ofs+48 ld.d $a5, \reg, \ofs+40 @@ -276,18 +227,11 @@ C_FUNC(\Name\()_End): ld.d $a2, \reg, \ofs+16 ld.d $a1, \reg, \ofs+8 ld.d $a0, \reg, \ofs -//#endif .endm .macro RESTORE_FLOAT_ARGUMENT_REGISTERS reg, ofs -//#ifdef FEATURE_LOONGSONISA -// gslqc1 $f19, $f18, \ofs+48(\reg) -// gslqc1 $f17, $f16, \ofs+32(\reg) -// gslqc1 $f15, $f14, \ofs+16(\reg) -// gslqc1 $f13, $f12, \ofs(\reg) -//#else fld.d $f7, \reg, \ofs+56 fld.d $f6, \reg, \ofs+48 fld.d $f5, \reg, \ofs+40 @@ -296,20 +240,11 @@ C_FUNC(\Name\()_End): fld.d $f2, \reg, \ofs+16 fld.d $f1, \reg, \ofs+8 fld.d $f0, \reg, \ofs -//#endif .endm .macro RESTORE_FLOAT_CALLEESAVED_REGISTERS reg, ofs -//#ifdef FEATURE_LOONGSONISA -// //NOTE:The offset of gssqc1/gslqc1 must be 16-bytes aligned. -// // here ofs must be 16-bytes aligned. -// gslqc1 $f25, $f24, \ofs(\reg) -// gslqc1 $f27, $f26, \ofs+16(\reg) -// gslqc1 $f29, $f28, \ofs+32(\reg) -// gslqc1 $f31, $f30, \ofs+48(\reg) -//#else fld.d $f24, $r\reg, \ofs fld.d $f25, $r\reg, \ofs+8 fld.d $f26, $r\reg, \ofs+16 @@ -318,7 +253,6 @@ C_FUNC(\Name\()_End): fld.d $f29, $r\reg, \ofs+40 fld.d $f30, $r\reg, \ofs+48 fld.d $f31, $r\reg, \ofs+56 -//#endif .endm diff --git a/src/coreclr/pal/prebuilt/idl/corpub_i.cpp b/src/coreclr/pal/prebuilt/idl/corpub_i.cpp deleted file mode 100644 index 8aa67f88876171..00000000000000 --- a/src/coreclr/pal/prebuilt/idl/corpub_i.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - - -/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ - -/* link this file in with the server and any clients */ - - - /* File created by MIDL compiler version 8.00.0603 */ -/* @@MIDL_FILE_HEADING( ) */ - -#pragma warning( disable: 4049 ) /* more than 64k source lines */ - - -#ifdef __cplusplus -extern "C"{ -#endif - - -#include -#include - -#ifdef _MIDL_USE_GUIDDEF_ - -#ifndef INITGUID -#define INITGUID -#include -#undef INITGUID -#else -#include -#endif - -#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ - DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) - -#else // !_MIDL_USE_GUIDDEF_ - -#ifndef __IID_DEFINED__ -#define __IID_DEFINED__ - -typedef struct _IID -{ - unsigned long x; - unsigned short s1; - unsigned short s2; - unsigned char c[8]; -} IID; - -#endif // __IID_DEFINED__ - -#ifndef CLSID_DEFINED -#define CLSID_DEFINED -typedef IID CLSID; -#endif // CLSID_DEFINED - -#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ - EXTERN_C __declspec(selectany) const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} - -#endif // !_MIDL_USE_GUIDDEF_ - -MIDL_DEFINE_GUID(IID, LIBID_CorpubProcessLib,0xe97ca460,0x657d,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef); - - -MIDL_DEFINE_GUID(CLSID, CLSID_CorpubPublish,0x047a9a40,0x657e,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef); - - -MIDL_DEFINE_GUID(IID, IID_ICorPublish,0x9613A0E7,0x5A68,0x11d3,0x8F,0x84,0x00,0xA0,0xC9,0xB4,0xD5,0x0C); - - -MIDL_DEFINE_GUID(IID, IID_ICorPublishEnum,0xC0B22967,0x5A69,0x11d3,0x8F,0x84,0x00,0xA0,0xC9,0xB4,0xD5,0x0C); - - -MIDL_DEFINE_GUID(IID, IID_ICorPublishProcess,0x18D87AF1,0x5A6A,0x11d3,0x8F,0x84,0x00,0xA0,0xC9,0xB4,0xD5,0x0C); - - -MIDL_DEFINE_GUID(IID, IID_ICorPublishAppDomain,0xD6315C8F,0x5A6A,0x11d3,0x8F,0x84,0x00,0xA0,0xC9,0xB4,0xD5,0x0C); - - -MIDL_DEFINE_GUID(IID, IID_ICorPublishProcessEnum,0xA37FBD41,0x5A69,0x11d3,0x8F,0x84,0x00,0xA0,0xC9,0xB4,0xD5,0x0C); - - -MIDL_DEFINE_GUID(IID, IID_ICorPublishAppDomainEnum,0x9F0C98F5,0x5A6A,0x11d3,0x8F,0x84,0x00,0xA0,0xC9,0xB4,0xD5,0x0C); - -#undef MIDL_DEFINE_GUID - -#ifdef __cplusplus -} -#endif - - - diff --git a/src/coreclr/pal/prebuilt/inc/corpub.h b/src/coreclr/pal/prebuilt/inc/corpub.h deleted file mode 100644 index bc1ef7630802ec..00000000000000 --- a/src/coreclr/pal/prebuilt/inc/corpub.h +++ /dev/null @@ -1,820 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - - -/* this ALWAYS GENERATED file contains the definitions for the interfaces */ - - - /* File created by MIDL compiler version 8.00.0603 */ -/* @@MIDL_FILE_HEADING( ) */ - -#pragma warning( disable: 4049 ) /* more than 64k source lines */ - - -/* verify that the version is high enough to compile this file*/ -#ifndef __REQUIRED_RPCNDR_H_VERSION__ -#define __REQUIRED_RPCNDR_H_VERSION__ 475 -#endif - -#include "rpc.h" -#include "rpcndr.h" - -#ifndef __RPCNDR_H_VERSION__ -#error this stub requires an updated version of -#endif // __RPCNDR_H_VERSION__ - -#ifndef COM_NO_WINDOWS_H -#include "windows.h" -#include "ole2.h" -#endif /*COM_NO_WINDOWS_H*/ - -#ifndef __corpub_h__ -#define __corpub_h__ - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -#pragma once -#endif - -/* Forward Declarations */ - -#ifndef __CorpubPublish_FWD_DEFINED__ -#define __CorpubPublish_FWD_DEFINED__ - -#ifdef __cplusplus -typedef class CorpubPublish CorpubPublish; -#else -typedef struct CorpubPublish CorpubPublish; -#endif /* __cplusplus */ - -#endif /* __CorpubPublish_FWD_DEFINED__ */ - - -#ifndef __ICorPublish_FWD_DEFINED__ -#define __ICorPublish_FWD_DEFINED__ -typedef interface ICorPublish ICorPublish; - -#endif /* __ICorPublish_FWD_DEFINED__ */ - - -#ifndef __ICorPublishEnum_FWD_DEFINED__ -#define __ICorPublishEnum_FWD_DEFINED__ -typedef interface ICorPublishEnum ICorPublishEnum; - -#endif /* __ICorPublishEnum_FWD_DEFINED__ */ - - -#ifndef __ICorPublishProcess_FWD_DEFINED__ -#define __ICorPublishProcess_FWD_DEFINED__ -typedef interface ICorPublishProcess ICorPublishProcess; - -#endif /* __ICorPublishProcess_FWD_DEFINED__ */ - - -#ifndef __ICorPublishAppDomain_FWD_DEFINED__ -#define __ICorPublishAppDomain_FWD_DEFINED__ -typedef interface ICorPublishAppDomain ICorPublishAppDomain; - -#endif /* __ICorPublishAppDomain_FWD_DEFINED__ */ - - -#ifndef __ICorPublishProcessEnum_FWD_DEFINED__ -#define __ICorPublishProcessEnum_FWD_DEFINED__ -typedef interface ICorPublishProcessEnum ICorPublishProcessEnum; - -#endif /* __ICorPublishProcessEnum_FWD_DEFINED__ */ - - -#ifndef __ICorPublishAppDomainEnum_FWD_DEFINED__ -#define __ICorPublishAppDomainEnum_FWD_DEFINED__ -typedef interface ICorPublishAppDomainEnum ICorPublishAppDomainEnum; - -#endif /* __ICorPublishAppDomainEnum_FWD_DEFINED__ */ - - -/* header files for imported files */ -#include "unknwn.h" - -#ifdef __cplusplus -extern "C"{ -#endif - - -/* interface __MIDL_itf_corpub_0000_0000 */ -/* [local] */ - -#if 0 -#endif -typedef /* [public][public] */ -enum __MIDL___MIDL_itf_corpub_0000_0000_0001 - { - COR_PUB_MANAGEDONLY = 0x1 - } COR_PUB_ENUMPROCESS; - -#pragma warning(push) -#pragma warning(disable:28718) - - - - - -#pragma warning(pop) - - -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0000_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0000_v0_0_s_ifspec; - - -#ifndef __CorpubProcessLib_LIBRARY_DEFINED__ -#define __CorpubProcessLib_LIBRARY_DEFINED__ - -/* library CorpubProcessLib */ -/* [helpstring][version][uuid] */ - - -EXTERN_C const IID LIBID_CorpubProcessLib; - -EXTERN_C const CLSID CLSID_CorpubPublish; - -#ifdef __cplusplus - -class DECLSPEC_UUID("047a9a40-657e-11d3-8d5b-00104b35e7ef") -CorpubPublish; -#endif -#endif /* __CorpubProcessLib_LIBRARY_DEFINED__ */ - -#ifndef __ICorPublish_INTERFACE_DEFINED__ -#define __ICorPublish_INTERFACE_DEFINED__ - -/* interface ICorPublish */ -/* [local][unique][uuid][object] */ - - -EXTERN_C const IID IID_ICorPublish; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("9613A0E7-5A68-11d3-8F84-00A0C9B4D50C") - ICorPublish : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE EnumProcesses( - /* [in] */ COR_PUB_ENUMPROCESS Type, - /* [out] */ ICorPublishProcessEnum **ppIEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetProcess( - /* [in] */ unsigned int pid, - /* [out] */ ICorPublishProcess **ppProcess) = 0; - - }; - - -#else /* C style interface */ - - typedef struct ICorPublishVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICorPublish * This, - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICorPublish * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICorPublish * This); - - HRESULT ( STDMETHODCALLTYPE *EnumProcesses )( - ICorPublish * This, - /* [in] */ COR_PUB_ENUMPROCESS Type, - /* [out] */ ICorPublishProcessEnum **ppIEnum); - - HRESULT ( STDMETHODCALLTYPE *GetProcess )( - ICorPublish * This, - /* [in] */ unsigned int pid, - /* [out] */ ICorPublishProcess **ppProcess); - - END_INTERFACE - } ICorPublishVtbl; - - interface ICorPublish - { - CONST_VTBL struct ICorPublishVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICorPublish_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define ICorPublish_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define ICorPublish_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define ICorPublish_EnumProcesses(This,Type,ppIEnum) \ - ( (This)->lpVtbl -> EnumProcesses(This,Type,ppIEnum) ) - -#define ICorPublish_GetProcess(This,pid,ppProcess) \ - ( (This)->lpVtbl -> GetProcess(This,pid,ppProcess) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __ICorPublish_INTERFACE_DEFINED__ */ - - -#ifndef __ICorPublishEnum_INTERFACE_DEFINED__ -#define __ICorPublishEnum_INTERFACE_DEFINED__ - -/* interface ICorPublishEnum */ -/* [local][unique][uuid][object] */ - - -EXTERN_C const IID IID_ICorPublishEnum; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("C0B22967-5A69-11d3-8F84-00A0C9B4D50C") - ICorPublishEnum : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE Skip( - /* [in] */ ULONG celt) = 0; - - virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE Clone( - /* [out] */ ICorPublishEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCount( - /* [out] */ ULONG *pcelt) = 0; - - }; - - -#else /* C style interface */ - - typedef struct ICorPublishEnumVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICorPublishEnum * This, - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICorPublishEnum * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICorPublishEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Skip )( - ICorPublishEnum * This, - /* [in] */ ULONG celt); - - HRESULT ( STDMETHODCALLTYPE *Reset )( - ICorPublishEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Clone )( - ICorPublishEnum * This, - /* [out] */ ICorPublishEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetCount )( - ICorPublishEnum * This, - /* [out] */ ULONG *pcelt); - - END_INTERFACE - } ICorPublishEnumVtbl; - - interface ICorPublishEnum - { - CONST_VTBL struct ICorPublishEnumVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICorPublishEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define ICorPublishEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define ICorPublishEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define ICorPublishEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) - -#define ICorPublishEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) - -#define ICorPublishEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) - -#define ICorPublishEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __ICorPublishEnum_INTERFACE_DEFINED__ */ - - -/* interface __MIDL_itf_corpub_0000_0003 */ -/* [local] */ - -#pragma warning(push) -#pragma warning(disable:28718) - - -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0003_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0003_v0_0_s_ifspec; - -#ifndef __ICorPublishProcess_INTERFACE_DEFINED__ -#define __ICorPublishProcess_INTERFACE_DEFINED__ - -/* interface ICorPublishProcess */ -/* [local][unique][uuid][object] */ - - -EXTERN_C const IID IID_ICorPublishProcess; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("18D87AF1-5A6A-11d3-8F84-00A0C9B4D50C") - ICorPublishProcess : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE IsManaged( - /* [out] */ BOOL *pbManaged) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumAppDomains( - /* [out] */ ICorPublishAppDomainEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetProcessID( - /* [out] */ unsigned int *pid) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetDisplayName( - /* [in] */ ULONG32 cchName, - /* [out] */ ULONG32 *pcchName, - /* [length_is][size_is][out] */ WCHAR *szName) = 0; - - }; - - -#else /* C style interface */ - - typedef struct ICorPublishProcessVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICorPublishProcess * This, - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICorPublishProcess * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICorPublishProcess * This); - - HRESULT ( STDMETHODCALLTYPE *IsManaged )( - ICorPublishProcess * This, - /* [out] */ BOOL *pbManaged); - - HRESULT ( STDMETHODCALLTYPE *EnumAppDomains )( - ICorPublishProcess * This, - /* [out] */ ICorPublishAppDomainEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetProcessID )( - ICorPublishProcess * This, - /* [out] */ unsigned int *pid); - - HRESULT ( STDMETHODCALLTYPE *GetDisplayName )( - ICorPublishProcess * This, - /* [in] */ ULONG32 cchName, - /* [out] */ ULONG32 *pcchName, - /* [length_is][size_is][out] */ WCHAR *szName); - - END_INTERFACE - } ICorPublishProcessVtbl; - - interface ICorPublishProcess - { - CONST_VTBL struct ICorPublishProcessVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICorPublishProcess_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define ICorPublishProcess_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define ICorPublishProcess_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define ICorPublishProcess_IsManaged(This,pbManaged) \ - ( (This)->lpVtbl -> IsManaged(This,pbManaged) ) - -#define ICorPublishProcess_EnumAppDomains(This,ppEnum) \ - ( (This)->lpVtbl -> EnumAppDomains(This,ppEnum) ) - -#define ICorPublishProcess_GetProcessID(This,pid) \ - ( (This)->lpVtbl -> GetProcessID(This,pid) ) - -#define ICorPublishProcess_GetDisplayName(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetDisplayName(This,cchName,pcchName,szName) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __ICorPublishProcess_INTERFACE_DEFINED__ */ - - -/* interface __MIDL_itf_corpub_0000_0004 */ -/* [local] */ - -#pragma warning(pop) -#pragma warning(push) -#pragma warning(disable:28718) - - -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0004_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0004_v0_0_s_ifspec; - -#ifndef __ICorPublishAppDomain_INTERFACE_DEFINED__ -#define __ICorPublishAppDomain_INTERFACE_DEFINED__ - -/* interface ICorPublishAppDomain */ -/* [local][unique][uuid][object] */ - - -EXTERN_C const IID IID_ICorPublishAppDomain; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("D6315C8F-5A6A-11d3-8F84-00A0C9B4D50C") - ICorPublishAppDomain : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE GetID( - /* [out] */ ULONG32 *puId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetName( - /* [in] */ ULONG32 cchName, - /* [out] */ ULONG32 *pcchName, - /* [length_is][size_is][out] */ WCHAR *szName) = 0; - - }; - - -#else /* C style interface */ - - typedef struct ICorPublishAppDomainVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICorPublishAppDomain * This, - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICorPublishAppDomain * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICorPublishAppDomain * This); - - HRESULT ( STDMETHODCALLTYPE *GetID )( - ICorPublishAppDomain * This, - /* [out] */ ULONG32 *puId); - - HRESULT ( STDMETHODCALLTYPE *GetName )( - ICorPublishAppDomain * This, - /* [in] */ ULONG32 cchName, - /* [out] */ ULONG32 *pcchName, - /* [length_is][size_is][out] */ WCHAR *szName); - - END_INTERFACE - } ICorPublishAppDomainVtbl; - - interface ICorPublishAppDomain - { - CONST_VTBL struct ICorPublishAppDomainVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICorPublishAppDomain_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define ICorPublishAppDomain_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define ICorPublishAppDomain_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define ICorPublishAppDomain_GetID(This,puId) \ - ( (This)->lpVtbl -> GetID(This,puId) ) - -#define ICorPublishAppDomain_GetName(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __ICorPublishAppDomain_INTERFACE_DEFINED__ */ - - -/* interface __MIDL_itf_corpub_0000_0005 */ -/* [local] */ - -#pragma warning(pop) - - -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0005_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_corpub_0000_0005_v0_0_s_ifspec; - -#ifndef __ICorPublishProcessEnum_INTERFACE_DEFINED__ -#define __ICorPublishProcessEnum_INTERFACE_DEFINED__ - -/* interface ICorPublishProcessEnum */ -/* [local][unique][uuid][object] */ - - -EXTERN_C const IID IID_ICorPublishProcessEnum; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("A37FBD41-5A69-11d3-8F84-00A0C9B4D50C") - ICorPublishProcessEnum : public ICorPublishEnum - { - public: - virtual HRESULT STDMETHODCALLTYPE Next( - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ ICorPublishProcess **objects, - /* [out] */ ULONG *pceltFetched) = 0; - - }; - - -#else /* C style interface */ - - typedef struct ICorPublishProcessEnumVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICorPublishProcessEnum * This, - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICorPublishProcessEnum * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICorPublishProcessEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Skip )( - ICorPublishProcessEnum * This, - /* [in] */ ULONG celt); - - HRESULT ( STDMETHODCALLTYPE *Reset )( - ICorPublishProcessEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Clone )( - ICorPublishProcessEnum * This, - /* [out] */ ICorPublishEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetCount )( - ICorPublishProcessEnum * This, - /* [out] */ ULONG *pcelt); - - HRESULT ( STDMETHODCALLTYPE *Next )( - ICorPublishProcessEnum * This, - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ ICorPublishProcess **objects, - /* [out] */ ULONG *pceltFetched); - - END_INTERFACE - } ICorPublishProcessEnumVtbl; - - interface ICorPublishProcessEnum - { - CONST_VTBL struct ICorPublishProcessEnumVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICorPublishProcessEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define ICorPublishProcessEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define ICorPublishProcessEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define ICorPublishProcessEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) - -#define ICorPublishProcessEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) - -#define ICorPublishProcessEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) - -#define ICorPublishProcessEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) - - -#define ICorPublishProcessEnum_Next(This,celt,objects,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,objects,pceltFetched) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __ICorPublishProcessEnum_INTERFACE_DEFINED__ */ - - -#ifndef __ICorPublishAppDomainEnum_INTERFACE_DEFINED__ -#define __ICorPublishAppDomainEnum_INTERFACE_DEFINED__ - -/* interface ICorPublishAppDomainEnum */ -/* [local][unique][uuid][object] */ - - -EXTERN_C const IID IID_ICorPublishAppDomainEnum; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("9F0C98F5-5A6A-11d3-8F84-00A0C9B4D50C") - ICorPublishAppDomainEnum : public ICorPublishEnum - { - public: - virtual HRESULT STDMETHODCALLTYPE Next( - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ ICorPublishAppDomain **objects, - /* [out] */ ULONG *pceltFetched) = 0; - - }; - - -#else /* C style interface */ - - typedef struct ICorPublishAppDomainEnumVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICorPublishAppDomainEnum * This, - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICorPublishAppDomainEnum * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICorPublishAppDomainEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Skip )( - ICorPublishAppDomainEnum * This, - /* [in] */ ULONG celt); - - HRESULT ( STDMETHODCALLTYPE *Reset )( - ICorPublishAppDomainEnum * This); - - HRESULT ( STDMETHODCALLTYPE *Clone )( - ICorPublishAppDomainEnum * This, - /* [out] */ ICorPublishEnum **ppEnum); - - HRESULT ( STDMETHODCALLTYPE *GetCount )( - ICorPublishAppDomainEnum * This, - /* [out] */ ULONG *pcelt); - - HRESULT ( STDMETHODCALLTYPE *Next )( - ICorPublishAppDomainEnum * This, - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ ICorPublishAppDomain **objects, - /* [out] */ ULONG *pceltFetched); - - END_INTERFACE - } ICorPublishAppDomainEnumVtbl; - - interface ICorPublishAppDomainEnum - { - CONST_VTBL struct ICorPublishAppDomainEnumVtbl *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICorPublishAppDomainEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) - -#define ICorPublishAppDomainEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) - -#define ICorPublishAppDomainEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) - - -#define ICorPublishAppDomainEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) - -#define ICorPublishAppDomainEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) - -#define ICorPublishAppDomainEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) - -#define ICorPublishAppDomainEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) - - -#define ICorPublishAppDomainEnum_Next(This,celt,objects,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,objects,pceltFetched) ) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - - -#endif /* __ICorPublishAppDomainEnum_INTERFACE_DEFINED__ */ - - -/* Additional Prototypes for ALL interfaces */ - -/* end of Additional Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif - - diff --git a/src/coreclr/pal/src/arch/loongarch64/asmconstants.h b/src/coreclr/pal/src/arch/loongarch64/asmconstants.h index 3676b16fcc67ee..3af79d45ce1e5a 100644 --- a/src/coreclr/pal/src/arch/loongarch64/asmconstants.h +++ b/src/coreclr/pal/src/arch/loongarch64/asmconstants.h @@ -19,6 +19,11 @@ #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT) +#define CONTEXT_LSX_BIT (4) +#define CONTEXT_LASX_BIT (5) +#define CONTEXT_LSX (1 << CONTEXT_LSX_BIT) +#define CONTEXT_LASX (1 << CONTEXT_LASX_BIT) + #define SIZEOF_LOONGARCH_GPR 8 #define SIZEOF_LOONGARCH_FPR 8 diff --git a/src/coreclr/pal/src/arch/loongarch64/context2.S b/src/coreclr/pal/src/arch/loongarch64/context2.S index 31edbcfa851706..8a7f7b8e8deb55 100644 --- a/src/coreclr/pal/src/arch/loongarch64/context2.S +++ b/src/coreclr/pal/src/arch/loongarch64/context2.S @@ -16,12 +16,12 @@ LEAF_ENTRY RtlRestoreContext, _TEXT #ifdef HAS_ADDRESS_SANITIZER ld.w $r21, $a0, CONTEXT_ContextFlags - andi $r21, $r21, (1 << CONTEXT_CONTROL_BIT) - beq $r21, $r0, LOCAL_LABEL(Restore_CONTEXT_FLOATING_POINT) + andi $r21, $r21, (1 << CONTEXT_CONTROL_BIT) + beqz $r21, LOCAL_LABEL(Restore_CONTEXT_FLOATING_POINT) addi.d $sp, $sp, -16 - st.d a0, $sp, 0 - st.d a1, $sp, 8 + st.d $a0, $sp, 0 + st.d $a1, $sp, 8 bl __asan_handle_no_return @@ -37,17 +37,94 @@ LOCAL_LABEL(Restore_CONTEXT_FLOATING_POINT): andi $t1, $r21, (1 << CONTEXT_FLOATING_POINT_BIT) beqz $t1, LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT) + andi $t1, $r21, CONTEXT_LASX + bnez $t1, LOCAL_LABEL(Restore_CONTEXT_LASX) + andi $t1, $r21, CONTEXT_LSX + bnez $t1, LOCAL_LABEL(Restore_CONTEXT_LSX) + + // Neither LSX or LASX is supported. + fld.d $f0 , $a0, CONTEXT_FPU_OFFSET + fld.d $f1 , $a0, CONTEXT_FPU_OFFSET + 8*1 + fld.d $f2 , $a0, CONTEXT_FPU_OFFSET + 8*2 + fld.d $f3 , $a0, CONTEXT_FPU_OFFSET + 8*3 + fld.d $f4 , $a0, CONTEXT_FPU_OFFSET + 8*4 + fld.d $f5 , $a0, CONTEXT_FPU_OFFSET + 8*5 + fld.d $f6 , $a0, CONTEXT_FPU_OFFSET + 8*6 + fld.d $f7 , $a0, CONTEXT_FPU_OFFSET + 8*7 + fld.d $f8 , $a0, CONTEXT_FPU_OFFSET + 8*8 + fld.d $f9 , $a0, CONTEXT_FPU_OFFSET + 8*9 + fld.d $f10, $a0, CONTEXT_FPU_OFFSET + 8*10 + fld.d $f11, $a0, CONTEXT_FPU_OFFSET + 8*11 + fld.d $f12, $a0, CONTEXT_FPU_OFFSET + 8*12 + fld.d $f13, $a0, CONTEXT_FPU_OFFSET + 8*13 + fld.d $f14, $a0, CONTEXT_FPU_OFFSET + 8*14 + fld.d $f15, $a0, CONTEXT_FPU_OFFSET + 8*15 + fld.d $f16, $a0, CONTEXT_FPU_OFFSET + 8*16 + fld.d $f17, $a0, CONTEXT_FPU_OFFSET + 8*17 + fld.d $f18, $a0, CONTEXT_FPU_OFFSET + 8*18 + fld.d $f19, $a0, CONTEXT_FPU_OFFSET + 8*19 + fld.d $f20, $a0, CONTEXT_FPU_OFFSET + 8*20 + fld.d $f21, $a0, CONTEXT_FPU_OFFSET + 8*21 + fld.d $f22, $a0, CONTEXT_FPU_OFFSET + 8*22 + fld.d $f23, $a0, CONTEXT_FPU_OFFSET + 8*23 + fld.d $f24, $a0, CONTEXT_FPU_OFFSET + 8*24 + fld.d $f25, $a0, CONTEXT_FPU_OFFSET + 8*25 + fld.d $f26, $a0, CONTEXT_FPU_OFFSET + 8*26 + fld.d $f27, $a0, CONTEXT_FPU_OFFSET + 8*27 + fld.d $f28, $a0, CONTEXT_FPU_OFFSET + 8*28 + fld.d $f29, $a0, CONTEXT_FPU_OFFSET + 8*29 + fld.d $f30, $a0, CONTEXT_FPU_OFFSET + 8*30 + fld.d $f31, $a0, CONTEXT_FPU_OFFSET + 8*31 + b LOCAL_LABEL(Restore_CONTEXT_FLOATING_CONTROL) + +LOCAL_LABEL(Restore_CONTEXT_LSX): + // 128-bits SIMD:LSX. + vld $vr0 , $a0, CONTEXT_FPU_OFFSET + vld $vr1 , $a0, CONTEXT_FPU_OFFSET + 16*1 + vld $vr2 , $a0, CONTEXT_FPU_OFFSET + 16*2 + vld $vr3 , $a0, CONTEXT_FPU_OFFSET + 16*3 + vld $vr4 , $a0, CONTEXT_FPU_OFFSET + 16*4 + vld $vr5 , $a0, CONTEXT_FPU_OFFSET + 16*5 + vld $vr6 , $a0, CONTEXT_FPU_OFFSET + 16*6 + vld $vr7 , $a0, CONTEXT_FPU_OFFSET + 16*7 + vld $vr8 , $a0, CONTEXT_FPU_OFFSET + 16*8 + vld $vr9 , $a0, CONTEXT_FPU_OFFSET + 16*9 + vld $vr10, $a0, CONTEXT_FPU_OFFSET + 16*10 + vld $vr11, $a0, CONTEXT_FPU_OFFSET + 16*11 + vld $vr12, $a0, CONTEXT_FPU_OFFSET + 16*12 + vld $vr13, $a0, CONTEXT_FPU_OFFSET + 16*13 + vld $vr14, $a0, CONTEXT_FPU_OFFSET + 16*14 + vld $vr15, $a0, CONTEXT_FPU_OFFSET + 16*15 + vld $vr16, $a0, CONTEXT_FPU_OFFSET + 16*16 + vld $vr17, $a0, CONTEXT_FPU_OFFSET + 16*17 + vld $vr18, $a0, CONTEXT_FPU_OFFSET + 16*18 + vld $vr19, $a0, CONTEXT_FPU_OFFSET + 16*19 + vld $vr20, $a0, CONTEXT_FPU_OFFSET + 16*20 + vld $vr21, $a0, CONTEXT_FPU_OFFSET + 16*21 + vld $vr22, $a0, CONTEXT_FPU_OFFSET + 16*22 + vld $vr23, $a0, CONTEXT_FPU_OFFSET + 16*23 + vld $vr24, $a0, CONTEXT_FPU_OFFSET + 16*24 + vld $vr25, $a0, CONTEXT_FPU_OFFSET + 16*25 + vld $vr26, $a0, CONTEXT_FPU_OFFSET + 16*26 + vld $vr27, $a0, CONTEXT_FPU_OFFSET + 16*27 + vld $vr28, $a0, CONTEXT_FPU_OFFSET + 16*28 + vld $vr29, $a0, CONTEXT_FPU_OFFSET + 16*29 + vld $vr30, $a0, CONTEXT_FPU_OFFSET + 16*30 + vld $vr31, $a0, CONTEXT_FPU_OFFSET + 16*31 + b LOCAL_LABEL(Restore_CONTEXT_FLOATING_CONTROL) + +LOCAL_LABEL(Restore_CONTEXT_LASX): // 256-bits SIMD:LASX. - xvld $xr0, $a0, CONTEXT_FPU_OFFSET + 0 - xvld $xr1, $a0, CONTEXT_FPU_OFFSET + 32*1 - xvld $xr2, $a0, CONTEXT_FPU_OFFSET + 32*2 - xvld $xr3, $a0, CONTEXT_FPU_OFFSET + 32*3 - xvld $xr4, $a0, CONTEXT_FPU_OFFSET + 32*4 - xvld $xr5, $a0, CONTEXT_FPU_OFFSET + 32*5 - xvld $xr6, $a0, CONTEXT_FPU_OFFSET + 32*6 - xvld $xr7, $a0, CONTEXT_FPU_OFFSET + 32*7 - xvld $xr8, $a0, CONTEXT_FPU_OFFSET + 32*8 - xvld $xr9, $a0, CONTEXT_FPU_OFFSET + 32*9 + xvld $xr0 , $a0, CONTEXT_FPU_OFFSET + xvld $xr1 , $a0, CONTEXT_FPU_OFFSET + 32*1 + xvld $xr2 , $a0, CONTEXT_FPU_OFFSET + 32*2 + xvld $xr3 , $a0, CONTEXT_FPU_OFFSET + 32*3 + xvld $xr4 , $a0, CONTEXT_FPU_OFFSET + 32*4 + xvld $xr5 , $a0, CONTEXT_FPU_OFFSET + 32*5 + xvld $xr6 , $a0, CONTEXT_FPU_OFFSET + 32*6 + xvld $xr7 , $a0, CONTEXT_FPU_OFFSET + 32*7 + xvld $xr8 , $a0, CONTEXT_FPU_OFFSET + 32*8 + xvld $xr9 , $a0, CONTEXT_FPU_OFFSET + 32*9 xvld $xr10, $a0, CONTEXT_FPU_OFFSET + 32*10 xvld $xr11, $a0, CONTEXT_FPU_OFFSET + 32*11 xvld $xr12, $a0, CONTEXT_FPU_OFFSET + 32*12 @@ -71,6 +148,7 @@ LOCAL_LABEL(Restore_CONTEXT_FLOATING_POINT): xvld $xr30, $a0, CONTEXT_FPU_OFFSET + 32*30 xvld $xr31, $a0, CONTEXT_FPU_OFFSET + 32*31 +LOCAL_LABEL(Restore_CONTEXT_FLOATING_CONTROL): ld.d $t1, $a0, CONTEXT_FLOAT_CONTROL_OFFSET movgr2cf $fcc0, $t1 srli.d $t1, $t1, 8 @@ -127,7 +205,7 @@ LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT): LOCAL_LABEL(No_Restore_CONTEXT_INTEGER): andi $r21, $r21, (1 << CONTEXT_CONTROL_BIT) - beq $r21, $r0, LOCAL_LABEL(No_Restore_CONTEXT_CONTROL) + beqz $r21, LOCAL_LABEL(No_Restore_CONTEXT_CONTROL) ld.d $ra, $t4, CONTEXT_Ra ld.d $fp, $t4, CONTEXT_Fp @@ -145,7 +223,6 @@ LEAF_END RtlRestoreContext, _TEXT // Incoming: // a0: Context* - LEAF_ENTRY RtlCaptureContext, _TEXT PROLOG_STACK_ALLOC 16 st.d $r21, $sp, 0 @@ -218,8 +295,85 @@ LOCAL_LABEL(Done_CONTEXT_INTEGER): andi $t3, $t1, (1 << CONTEXT_FLOATING_POINT_BIT) beqz $t3, LOCAL_LABEL(Done_CONTEXT_FLOATING_POINT) + andi $t3, $t1, CONTEXT_LASX + bnez $t3, LOCAL_LABEL(Store_CONTEXT_LASX) + andi $t3, $t1, CONTEXT_LSX + bnez $t3, LOCAL_LABEL(Store_CONTEXT_LSX) + + // Neither LSX or LASX is supported. + fst.d $f0 , $a0, CONTEXT_FPU_OFFSET + fst.d $f1 , $a0, CONTEXT_FPU_OFFSET + 8*1 + fst.d $f2 , $a0, CONTEXT_FPU_OFFSET + 8*2 + fst.d $f3 , $a0, CONTEXT_FPU_OFFSET + 8*3 + fst.d $f4 , $a0, CONTEXT_FPU_OFFSET + 8*4 + fst.d $f5 , $a0, CONTEXT_FPU_OFFSET + 8*5 + fst.d $f6 , $a0, CONTEXT_FPU_OFFSET + 8*6 + fst.d $f7 , $a0, CONTEXT_FPU_OFFSET + 8*7 + fst.d $f8 , $a0, CONTEXT_FPU_OFFSET + 8*8 + fst.d $f9 , $a0, CONTEXT_FPU_OFFSET + 8*9 + fst.d $f10, $a0, CONTEXT_FPU_OFFSET + 8*10 + fst.d $f11, $a0, CONTEXT_FPU_OFFSET + 8*11 + fst.d $f12, $a0, CONTEXT_FPU_OFFSET + 8*12 + fst.d $f13, $a0, CONTEXT_FPU_OFFSET + 8*13 + fst.d $f14, $a0, CONTEXT_FPU_OFFSET + 8*14 + fst.d $f15, $a0, CONTEXT_FPU_OFFSET + 8*15 + fst.d $f16, $a0, CONTEXT_FPU_OFFSET + 8*16 + fst.d $f17, $a0, CONTEXT_FPU_OFFSET + 8*17 + fst.d $f18, $a0, CONTEXT_FPU_OFFSET + 8*18 + fst.d $f19, $a0, CONTEXT_FPU_OFFSET + 8*19 + fst.d $f20, $a0, CONTEXT_FPU_OFFSET + 8*20 + fst.d $f21, $a0, CONTEXT_FPU_OFFSET + 8*21 + fst.d $f22, $a0, CONTEXT_FPU_OFFSET + 8*22 + fst.d $f23, $a0, CONTEXT_FPU_OFFSET + 8*23 + fst.d $f24, $a0, CONTEXT_FPU_OFFSET + 8*24 + fst.d $f25, $a0, CONTEXT_FPU_OFFSET + 8*25 + fst.d $f26, $a0, CONTEXT_FPU_OFFSET + 8*26 + fst.d $f27, $a0, CONTEXT_FPU_OFFSET + 8*27 + fst.d $f28, $a0, CONTEXT_FPU_OFFSET + 8*28 + fst.d $f29, $a0, CONTEXT_FPU_OFFSET + 8*29 + fst.d $f30, $a0, CONTEXT_FPU_OFFSET + 8*30 + fst.d $f31, $a0, CONTEXT_FPU_OFFSET + 8*31 + b LOCAL_LABEL(Store_CONTEXT_FLOAT_CONTROL) + +LOCAL_LABEL(Store_CONTEXT_LSX): + // 128-bits SIMD:LSX. + vst $vr0 , $a0, CONTEXT_FPU_OFFSET + vst $vr1 , $a0, CONTEXT_FPU_OFFSET + 16*1 + vst $vr2 , $a0, CONTEXT_FPU_OFFSET + 16*2 + vst $vr3 , $a0, CONTEXT_FPU_OFFSET + 16*3 + vst $vr4 , $a0, CONTEXT_FPU_OFFSET + 16*4 + vst $vr5 , $a0, CONTEXT_FPU_OFFSET + 16*5 + vst $vr6 , $a0, CONTEXT_FPU_OFFSET + 16*6 + vst $vr7 , $a0, CONTEXT_FPU_OFFSET + 16*7 + vst $vr8 , $a0, CONTEXT_FPU_OFFSET + 16*8 + vst $vr9 , $a0, CONTEXT_FPU_OFFSET + 16*9 + vst $vr10, $a0, CONTEXT_FPU_OFFSET + 16*10 + vst $vr11, $a0, CONTEXT_FPU_OFFSET + 16*11 + vst $vr12, $a0, CONTEXT_FPU_OFFSET + 16*12 + vst $vr13, $a0, CONTEXT_FPU_OFFSET + 16*13 + vst $vr14, $a0, CONTEXT_FPU_OFFSET + 16*14 + vst $vr15, $a0, CONTEXT_FPU_OFFSET + 16*15 + vst $vr16, $a0, CONTEXT_FPU_OFFSET + 16*16 + vst $vr17, $a0, CONTEXT_FPU_OFFSET + 16*17 + vst $vr18, $a0, CONTEXT_FPU_OFFSET + 16*18 + vst $vr19, $a0, CONTEXT_FPU_OFFSET + 16*19 + vst $vr20, $a0, CONTEXT_FPU_OFFSET + 16*20 + vst $vr21, $a0, CONTEXT_FPU_OFFSET + 16*21 + vst $vr22, $a0, CONTEXT_FPU_OFFSET + 16*22 + vst $vr23, $a0, CONTEXT_FPU_OFFSET + 16*23 + vst $vr24, $a0, CONTEXT_FPU_OFFSET + 16*24 + vst $vr25, $a0, CONTEXT_FPU_OFFSET + 16*25 + vst $vr26, $a0, CONTEXT_FPU_OFFSET + 16*26 + vst $vr27, $a0, CONTEXT_FPU_OFFSET + 16*27 + vst $vr28, $a0, CONTEXT_FPU_OFFSET + 16*28 + vst $vr29, $a0, CONTEXT_FPU_OFFSET + 16*29 + vst $vr30, $a0, CONTEXT_FPU_OFFSET + 16*30 + vst $vr31, $a0, CONTEXT_FPU_OFFSET + 16*31 + b LOCAL_LABEL(Store_CONTEXT_FLOAT_CONTROL) + +LOCAL_LABEL(Store_CONTEXT_LASX): // 256-bits SIMD:LASX. - xvst $xr0 , $a0, CONTEXT_FPU_OFFSET + 32*0 + xvst $xr0 , $a0, CONTEXT_FPU_OFFSET xvst $xr1 , $a0, CONTEXT_FPU_OFFSET + 32*1 xvst $xr2 , $a0, CONTEXT_FPU_OFFSET + 32*2 xvst $xr3 , $a0, CONTEXT_FPU_OFFSET + 32*3 @@ -252,6 +406,7 @@ LOCAL_LABEL(Done_CONTEXT_INTEGER): xvst $xr30, $a0, CONTEXT_FPU_OFFSET + 32*30 xvst $xr31, $a0, CONTEXT_FPU_OFFSET + 32*31 +LOCAL_LABEL(Store_CONTEXT_FLOAT_CONTROL): ori $t0, $r0, 0 movcf2gr $t0, $fcc0 st.b $t0, $a0, CONTEXT_FLOAT_CONTROL_OFFSET diff --git a/src/coreclr/pal/src/debug/debug.cpp b/src/coreclr/pal/src/debug/debug.cpp index b248de3533d7a9..64dd8b7e0caadd 100644 --- a/src/coreclr/pal/src/debug/debug.cpp +++ b/src/coreclr/pal/src/debug/debug.cpp @@ -425,7 +425,7 @@ DebugBreak( BOOL IsInDebugBreak(void *addr) { -#if defined (__wasm__) +#ifdef TARGET_WASM _ASSERT("IsInDebugBreak not implemented on wasm"); return false; #else diff --git a/src/coreclr/pal/src/exception/seh.cpp b/src/coreclr/pal/src/exception/seh.cpp index c2f28cff936c96..26c963ff3b1110 100644 --- a/src/coreclr/pal/src/exception/seh.cpp +++ b/src/coreclr/pal/src/exception/seh.cpp @@ -248,7 +248,7 @@ Return value: BOOL SEHProcessException(PAL_SEHException* exception) { - g_SEHProcessExceptionReturnAddress = __builtin_return_address(0); + g_SEHProcessExceptionReturnAddress = _ReturnAddress(); CONTEXT* contextRecord = exception->GetContextRecord(); EXCEPTION_RECORD* exceptionRecord = exception->GetExceptionRecord(); diff --git a/src/coreclr/pal/src/exception/signal.cpp b/src/coreclr/pal/src/exception/signal.cpp index 444bad7e5c072c..732d1d5db05933 100644 --- a/src/coreclr/pal/src/exception/signal.cpp +++ b/src/coreclr/pal/src/exception/signal.cpp @@ -219,6 +219,7 @@ BOOL SEHInitializeSignals(CorUnix::CPalThread *pthrCurrent, DWORD flags) return FALSE; } +#ifndef TARGET_WASM // create a guard page for the alternate stack int st = mprotect((void*)g_stackOverflowHandlerStack, GetVirtualPageSize(), PROT_NONE); if (st != 0) @@ -226,6 +227,7 @@ BOOL SEHInitializeSignals(CorUnix::CPalThread *pthrCurrent, DWORD flags) munmap((void*)g_stackOverflowHandlerStack, stackOverflowStackSize); return FALSE; } +#endif // TARGET_WASM g_stackOverflowHandlerStack = (void*)((size_t)g_stackOverflowHandlerStack + stackOverflowStackSize); #endif // HAVE_MACH_EXCEPTIONS @@ -876,7 +878,7 @@ Parameters : __attribute__((noinline)) static void InvokeActivationHandler(CONTEXT *pWinContext) { - g_InvokeActivationHandlerReturnAddress = __builtin_return_address(0); + g_InvokeActivationHandlerReturnAddress = _ReturnAddress(); g_activationFunction(pWinContext); } diff --git a/src/coreclr/pal/src/handlemgr/handleapi.cpp b/src/coreclr/pal/src/handlemgr/handleapi.cpp index 90683bc2c30889..5f08f2fae51423 100644 --- a/src/coreclr/pal/src/handlemgr/handleapi.cpp +++ b/src/coreclr/pal/src/handlemgr/handleapi.cpp @@ -169,14 +169,8 @@ CorUnix::InternalDuplicateHandle( goto InternalDuplicateHandleExit; } - /* Since handles can be remoted to others processes using PAL_LocalHsndleToRemote - and PAL_RemoteHandleToLocal, DuplicateHandle needs some special handling - when this scenario occurs. - - if hSourceProcessHandle is from another process OR - hTargetProcessHandle is from another process but both aren't - ( handled above ) return hSourceHandle. - */ + // Handles can't be remoted cross-process. + // Just return the same handle. if (source_process_id != cur_process_id || target_process_id != cur_process_id) { diff --git a/src/coreclr/pal/src/include/pal/list.h b/src/coreclr/pal/src/include/pal/list.h index 8f4d734ba3fcee..78c840969021cf 100644 --- a/src/coreclr/pal/src/include/pal/list.h +++ b/src/coreclr/pal/src/include/pal/list.h @@ -22,12 +22,13 @@ Revision History: #ifndef _LIST_H_INCLUDED #define _LIST_H_INCLUDED +#include + #ifdef __cplusplus extern "C" { #endif // __cplusplus -#include typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; diff --git a/src/coreclr/pal/src/include/pal/process.h b/src/coreclr/pal/src/include/pal/process.h index 1c48093af219da..45ef76577ad197 100644 --- a/src/coreclr/pal/src/include/pal/process.h +++ b/src/coreclr/pal/src/include/pal/process.h @@ -188,17 +188,6 @@ VOID PROCNotifyProcessShutdown(bool isExecutingOnAltStack = false); --*/ VOID PROCCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, bool serialize); -/*++ -Function: - InitializeFlushProcessWriteBuffers - -Abstract - This function initializes data structures needed for the FlushProcessWriteBuffers -Return - TRUE if it succeeded, FALSE otherwise ---*/ -BOOL InitializeFlushProcessWriteBuffers(); - #ifdef __cplusplus } #endif // __cplusplus diff --git a/src/coreclr/pal/src/init/pal.cpp b/src/coreclr/pal/src/init/pal.cpp index 6811690132daed..4d02460f16d51a 100644 --- a/src/coreclr/pal/src/init/pal.cpp +++ b/src/coreclr/pal/src/init/pal.cpp @@ -36,6 +36,7 @@ SET_DEFAULT_DEBUG_CHANNEL(PAL); // some headers have code with asserts, so do th #include "pal/stackstring.hpp" #include "pal/cgroup.h" #include +#include #if HAVE_MACH_EXCEPTIONS #include "../exception/machexception.h" @@ -248,7 +249,7 @@ EnsureStackSize(SIZE_T stackSize) void InitializeDefaultStackSize() { - CLRConfigNoCache defStackSize = CLRConfigNoCache::Get("DefaultStackSize", /*noprefix*/ false, &getenv); + CLRConfigNoCache defStackSize = CLRConfigNoCache::Get("Thread_DefaultStackSize", /*noprefix*/ false, &getenv); if (defStackSize.IsSet()) { DWORD size; @@ -580,7 +581,7 @@ Initialize( if (flags & PAL_INITIALIZE_FLUSH_PROCESS_WRITE_BUFFERS) { // Initialize before first thread is created for faster load on Linux - if (!InitializeFlushProcessWriteBuffers()) + if (!minipal_initialize_memory_barrier_process_wide()) { ERROR("Unable to initialize flush process write buffers\n"); palError = ERROR_PALINIT_INITIALIZE_FLUSH_PROCESS_WRITE_BUFFERS; @@ -588,7 +589,7 @@ Initialize( } } -#ifndef __wasm__ +#ifndef TARGET_WASM if (flags & PAL_INITIALIZE_SYNC_THREAD) { // @@ -601,7 +602,7 @@ Initialize( goto CLEANUP13; } } -#endif +#endif // !TARGET_WASM /* initialize structured exception handling stuff (signals, etc) */ if (FALSE == SEHInitialize(pThread, flags)) { @@ -719,6 +720,7 @@ PAL_InitializeCoreCLR(const char *szExePath, BOOL runningInExe) return ERROR_SUCCESS; } +#ifndef TARGET_WASM // we don't use shared libraries on wasm // Now that the PAL is initialized it's safe to call the initialization methods for the code that used to // be dynamically loaded libraries but is now statically linked into CoreCLR just like the PAL, i.e. the // PAL RT and mscorwks. @@ -726,6 +728,7 @@ PAL_InitializeCoreCLR(const char *szExePath, BOOL runningInExe) { return ERROR_DLL_INIT_FAILED; } +#endif // !TARGET_WASM if (!PROCAbortInitialize()) { @@ -916,7 +919,7 @@ Return value: --*/ static BOOL INIT_IncreaseDescriptorLimit(void) { -#ifdef __wasm__ +#ifdef TARGET_WASM // WebAssembly cannot set limits return TRUE; #endif diff --git a/src/coreclr/pal/src/loader/module.cpp b/src/coreclr/pal/src/loader/module.cpp index d7cff970a0b02e..76fdb966afb6ac 100644 --- a/src/coreclr/pal/src/loader/module.cpp +++ b/src/coreclr/pal/src/loader/module.cpp @@ -926,6 +926,16 @@ PAL_CopyModuleData(PVOID moduleBase, PVOID destinationBufferStart, PVOID destina } return param.result; } +#elif defined(TARGET_WASM) +// WASM-TODO: get rid of whole module loading on wasm +PALIMPORT +int +PALAPI +PAL_CopyModuleData(PVOID moduleBase, PVOID destinationBufferStart, PVOID destinationBufferEnd) +{ + _ASSERTE(!"PAL_CopyModuleData not implemented for wasm"); + return 0; +} #else static int CopyModuleDataCallback(struct dl_phdr_info *info, size_t size, void *data) { @@ -1016,7 +1026,7 @@ BOOL LOADInitializeModules() exe_module.self = (HMODULE)&exe_module; exe_module.dl_handle = dlopen(nullptr, RTLD_LAZY); -#if not defined(__wasm__) // wasm does not support shared libraries +#ifndef TARGET_WASM // wasm does not support shared libraries if (exe_module.dl_handle == nullptr) { ERROR("Executable module will be broken : dlopen(nullptr) failed\n"); diff --git a/src/coreclr/pal/src/map/virtual.cpp b/src/coreclr/pal/src/map/virtual.cpp index dcf3fd5c51c852..9143917af4c2bb 100644 --- a/src/coreclr/pal/src/map/virtual.cpp +++ b/src/coreclr/pal/src/map/virtual.cpp @@ -641,7 +641,7 @@ static LPVOID ReserveVirtualMemory( } #endif // MMAP_ANON_IGNORES_PROTECTION -#ifdef MADV_DONTDUMP +#if defined(MADV_DONTDUMP) && !defined(TARGET_WASM) // Do not include reserved uncommitted memory in coredump. if (!(fAllocationType & MEM_COMMIT)) { @@ -730,14 +730,16 @@ VIRTUALCommitMemory( nProtect = W32toUnixAccessControl(flProtect); +#ifndef TARGET_WASM // Commit the pages if (mprotect((void *) StartBoundary, MemSize, nProtect) != 0) { ERROR("mprotect() failed! Error(%d)=%s\n", errno, strerror(errno)); goto error; } +#endif -#ifdef MADV_DODUMP +#if defined(MADV_DONTDUMP) && !defined(TARGET_WASM) // Include committed memory in coredump. Any newly allocated memory included by default. if (!IsNewMemory) { @@ -748,7 +750,9 @@ VIRTUALCommitMemory( pRetVal = (void *) StartBoundary; goto done; +#ifndef TARGET_WASM error: +#endif if ( flAllocationType & MEM_RESERVE || IsLocallyReserved ) { munmap( pRetVal, MemSize ); @@ -1055,7 +1059,7 @@ VirtualFree( // mmap support on emscripten/wasm is very limited and doesn't support location hints // (when address is not null) -#ifndef __wasm__ +#ifndef TARGET_WASM // Explicitly calling mmap instead of mprotect here makes it // that much more clear to the operating system that we no // longer need these pages. @@ -1073,7 +1077,7 @@ VirtualFree( } #endif // MMAP_ANON_IGNORES_PROTECTION -#ifdef MADV_DONTDUMP +#if defined(MADV_DONTDUMP) && !defined(TARGET_WASM) // Do not include freed memory in coredump. madvise((LPVOID) StartBoundary, MemSize, MADV_DONTDUMP); #endif @@ -1086,13 +1090,13 @@ VirtualFree( pthrCurrent->SetLastError( ERROR_INTERNAL_ERROR ); goto VirtualFreeExit; } -#else // __wasm__ +#else // TARGET_WASM // We can't decommit the mapping (MAP_FIXED doesn't work in emscripten), and we can't // MADV_DONTNEED it (madvise doesn't work in emscripten), but we can at least zero // the memory so that if an attempt is made to reuse it later, the memory will be // empty as PAL tests expect it to be. ZeroMemory((LPVOID) StartBoundary, MemSize); -#endif // __wasm__ +#endif // TARGET_WASM } if ( dwFreeType & MEM_RELEASE ) @@ -1207,9 +1211,11 @@ VirtualProtect( } pEntry = VIRTUALFindRegionInformation( StartBoundary ); +#ifndef TARGET_WASM if ( 0 == mprotect( (LPVOID)StartBoundary, MemSize, W32toUnixAccessControl( flNewProtect ) ) ) { +#endif // !TARGET_WASM /* Reset the access protection. */ TRACE( "Number of pages to change %d, starting page %d \n", NumberOfPagesToChange, OffSet ); @@ -1220,13 +1226,14 @@ VirtualProtect( */ *lpflOldProtect = PAGE_EXECUTE_READWRITE; -#ifdef MADV_DONTDUMP +#if defined(MADV_DONTDUMP) && !defined(TARGET_WASM) // Include or exclude memory from coredump based on the protection. int advise = flNewProtect == PAGE_NOACCESS ? MADV_DONTDUMP : MADV_DODUMP; madvise((LPVOID)StartBoundary, MemSize, advise); #endif bRetVal = TRUE; +#ifndef TARGET_WASM } else { @@ -1240,6 +1247,7 @@ VirtualProtect( SetLastError( ERROR_INVALID_ACCESS ); } } +#endif // !TARGET_WASM ExitVirtualProtect: minipal_mutex_leave(&virtual_critsec); diff --git a/src/coreclr/pal/src/misc/perfjitdump.cpp b/src/coreclr/pal/src/misc/perfjitdump.cpp index b9afb95a574052..84680cc2b4ffed 100644 --- a/src/coreclr/pal/src/misc/perfjitdump.cpp +++ b/src/coreclr/pal/src/misc/perfjitdump.cpp @@ -14,6 +14,7 @@ #ifdef JITDUMP_SUPPORTED #include +#include #include #include #include @@ -355,7 +356,7 @@ struct PerfJitDumpState result = close(fd); - if (result == -1) + if (result == -1 && errno != EINTR) return FatalError(); fd = -1; diff --git a/src/coreclr/pal/src/sharedmemory/sharedmemory.cpp b/src/coreclr/pal/src/sharedmemory/sharedmemory.cpp index 5d12b850f9b9bc..1ec85658594d5f 100644 --- a/src/coreclr/pal/src/sharedmemory/sharedmemory.cpp +++ b/src/coreclr/pal/src/sharedmemory/sharedmemory.cpp @@ -582,12 +582,7 @@ int SharedMemoryHelpers::CreateOrOpenFile( void SharedMemoryHelpers::CloseFile(int fileDescriptor) { _ASSERTE(fileDescriptor != -1); - - int closeResult; - do - { - closeResult = close(fileDescriptor); - } while (closeResult != 0 && errno == EINTR); + close(fileDescriptor); } int SharedMemoryHelpers::ChangeMode(LPCSTR path, mode_t mode) diff --git a/src/coreclr/pal/src/thread/context.cpp b/src/coreclr/pal/src/thread/context.cpp index de8d063ea39eee..cfd5000d59f330 100644 --- a/src/coreclr/pal/src/thread/context.cpp +++ b/src/coreclr/pal/src/thread/context.cpp @@ -1183,6 +1183,7 @@ void CONTEXTFromNativeContext(const native_context_t *native, LPCONTEXT lpContex lpContext->Fcsr = fpr->fcsr; lpContext->Fcc = fpr->fcc; memcpy(lpContext->F, fpr->regs, sizeof(fpr->regs)); + lpContext->ContextFlags |= CONTEXT_LSX; } else if (LASX_CTX_MAGIC == info->magic) { @@ -1190,6 +1191,7 @@ void CONTEXTFromNativeContext(const native_context_t *native, LPCONTEXT lpContex lpContext->Fcsr = fpr->fcsr; lpContext->Fcc = fpr->fcc; memcpy(lpContext->F, fpr->regs, sizeof(fpr->regs)); + lpContext->ContextFlags |= CONTEXT_LASX; } else { diff --git a/src/coreclr/pal/src/thread/process.cpp b/src/coreclr/pal/src/thread/process.cpp index c56cc0637dcd2f..206a9629189b5b 100644 --- a/src/coreclr/pal/src/thread/process.cpp +++ b/src/coreclr/pal/src/thread/process.cpp @@ -93,6 +93,9 @@ extern "C" } \ } while (false) +// On macOS 26, sem_open fails if debugger and debugee are signed with different team ids. +// Use fifos instead of semaphores to avoid this issue, https://github.com/dotnet/runtime/issues/116545 +#define ENABLE_RUNTIME_EVENTS_OVER_PIPES #endif // __APPLE__ #ifdef __NetBSD__ @@ -131,21 +134,6 @@ CObjectType CorUnix::otProcess( CObjectType::NoOwner ); -// -// Tracks if the OS supports FlushProcessWriteBuffers using membarrier -// -static int s_flushUsingMemBarrier = 0; - -// -// Helper memory page used by the FlushProcessWriteBuffers -// -static int* s_helperPage = 0; - -// -// Mutex to make the FlushProcessWriteBuffersMutex thread safe -// -pthread_mutex_t flushProcessWriteBuffersMutex; - CAllowedObjectTypes aotProcess(otiProcess); // @@ -1401,21 +1389,217 @@ static uint64_t HashSemaphoreName(uint64_t a, uint64_t b) static const char *const TwoWayNamedPipePrefix = "clr-debug-pipe"; static const char* IpcNameFormat = "%s-%d-%llu-%s"; -/*++ - PAL_NotifyRuntimeStarted +#ifdef ENABLE_RUNTIME_EVENTS_OVER_PIPES +static const char* RuntimeStartupPipeName = "st"; +static const char* RuntimeContinuePipeName = "co"; - Signals the debugger waiting for runtime startup notification to continue and - waits until the debugger signals us to continue. +#define PIPE_OPEN_RETRY_DELAY_NS 500000000 // 500 ms -Parameters: - None +typedef enum +{ + RuntimeEventsOverPipes_Disabled = 0, + RuntimeEventsOverPipes_Succeeded = 1, + RuntimeEventsOverPipes_Failed = 2, +} RuntimeEventsOverPipes; -Return value: - TRUE - successfully launched by debugger, FALSE - not launched or some failure in the handshake ---*/ +typedef enum +{ + RuntimeEvent_Unknown = 0, + RuntimeEvent_Started = 1, + RuntimeEvent_Continue = 2, +} RuntimeEvent; + +static +int +OpenPipe(const char* name, int mode) +{ + int fd = -1; + int flags = mode | O_NONBLOCK; + +#if defined(FD_CLOEXEC) + flags |= O_CLOEXEC; +#endif + + while (fd == -1) + { + fd = open(name, flags); + if (fd == -1) + { + if (mode == O_WRONLY && errno == ENXIO) + { + PAL_nanosleep(PIPE_OPEN_RETRY_DELAY_NS); + continue; + } + else if (errno == EINTR) + { + continue; + } + else + { + break; + } + } + } + + if (fd != -1) + { + flags = fcntl(fd, F_GETFL); + if (flags != -1) + { + flags &= ~O_NONBLOCK; + if (fcntl(fd, F_SETFL, flags) == -1) + { + close(fd); + fd = -1; + } + } + else + { + close(fd); + fd = -1; + } + } + + return fd; +} + +static +void +ClosePipe(int fd) +{ + if (fd != -1) + { + while (close(fd) < 0 && errno == EINTR); + } +} + +static +RuntimeEventsOverPipes +NotifyRuntimeUsingPipes() +{ + RuntimeEventsOverPipes result = RuntimeEventsOverPipes_Disabled; + char startupPipeName[MAX_DEBUGGER_TRANSPORT_PIPE_NAME_LENGTH]; + char continuePipeName[MAX_DEBUGGER_TRANSPORT_PIPE_NAME_LENGTH]; + int startupPipeFd = -1; + int continuePipeFd = -1; + size_t offset = 0; + + LPCSTR applicationGroupId = PAL_GetApplicationGroupId(); + + PAL_GetTransportPipeName(continuePipeName, gPID, applicationGroupId, RuntimeContinuePipeName); + TRACE("NotifyRuntimeUsingPipes: opening continue '%s' pipe\n", continuePipeName); + + continuePipeFd = OpenPipe(continuePipeName, O_RDONLY); + if (continuePipeFd == -1) + { + if (errno == ENOENT || errno == EACCES) + { + TRACE("NotifyRuntimeUsingPipes: pipe %s not found/accessible, runtime events over pipes disabled\n", continuePipeName); + } + else + { + TRACE("NotifyRuntimeUsingPipes: open(%s) failed: %d (%s)\n", continuePipeName, errno, strerror(errno)); + result = RuntimeEventsOverPipes_Failed; + } + + goto exit; + } + + PAL_GetTransportPipeName(startupPipeName, gPID, applicationGroupId, RuntimeStartupPipeName); + TRACE("NotifyRuntimeUsingPipes: opening startup '%s' pipe\n", startupPipeName); + + startupPipeFd = OpenPipe(startupPipeName, O_WRONLY); + if (startupPipeFd == -1) + { + if (errno == ENOENT || errno == EACCES) + { + TRACE("NotifyRuntimeUsingPipes: pipe %s not found/accessible, runtime events over pipes disabled\n", startupPipeName); + } + else + { + TRACE("NotifyRuntimeUsingPipes: open(%s) failed: %d (%s)\n", startupPipeName, errno, strerror(errno)); + result = RuntimeEventsOverPipes_Failed; + } + + goto exit; + } + + TRACE("NotifyRuntimeUsingPipes: sending started event\n"); + + { + unsigned char event = (unsigned char)RuntimeEvent_Started; + unsigned char *buffer = &event; + int bytesToWrite = sizeof(event); + int bytesWritten = 0; + + do + { + bytesWritten = write(startupPipeFd, buffer + offset, bytesToWrite - offset); + if (bytesWritten > 0) + { + offset += bytesWritten; + } + } + while ((bytesWritten > 0 && offset < bytesToWrite) || (bytesWritten == -1 && errno == EINTR)); + + if (offset != bytesToWrite) + { + TRACE("NotifyRuntimeUsingPipes: write(%s) failed: %d (%s)\n", startupPipeName, errno, strerror(errno)); + goto exit; + } + } + + TRACE("NotifyRuntimeUsingPipes: waiting on continue event\n"); + + { + unsigned char event = (unsigned char)RuntimeEvent_Unknown; + unsigned char *buffer = &event; + int bytesToRead = sizeof(event); + int bytesRead = 0; + + offset = 0; + do + { + bytesRead = read(continuePipeFd, buffer + offset, bytesToRead - offset); + if (bytesRead > 0) + { + offset += bytesRead; + } + } + while ((bytesRead > 0 && offset < bytesToRead) || (bytesRead == -1 && errno == EINTR)); + + if (offset == bytesToRead && event == (unsigned char)RuntimeEvent_Continue) + { + TRACE("NotifyRuntimeUsingPipes: received continue event\n"); + } + else + { + TRACE("NotifyRuntimeUsingPipes: received invalid event\n"); + goto exit; + } + } + + result = RuntimeEventsOverPipes_Succeeded; + +exit: + + if (startupPipeFd != -1) + { + ClosePipe(startupPipeFd); + } + + if (continuePipeFd != -1) + { + ClosePipe(continuePipeFd); + } + + return result; +} +#endif // ENABLE_RUNTIME_EVENTS_OVER_PIPES + +static BOOL -PALAPI -PAL_NotifyRuntimeStarted() +NotifyRuntimeUsingSemaphores() { char startupSemName[CLR_SEM_MAX_NAMELEN]; char continueSemName[CLR_SEM_MAX_NAMELEN]; @@ -1436,13 +1620,13 @@ PAL_NotifyRuntimeStarted() CreateSemaphoreName(startupSemName, RuntimeStartupSemaphoreName, unambiguousProcessDescriptor, applicationGroupId); CreateSemaphoreName(continueSemName, RuntimeContinueSemaphoreName, unambiguousProcessDescriptor, applicationGroupId); - TRACE("PAL_NotifyRuntimeStarted opening continue '%s' startup '%s'\n", continueSemName, startupSemName); + TRACE("NotifyRuntimeUsingSemaphores: opening continue '%s' startup '%s'\n", continueSemName, startupSemName); // Open the debugger startup semaphore. If it doesn't exists, then we do nothing and return startupSem = sem_open(startupSemName, 0); if (startupSem == SEM_FAILED) { - TRACE("sem_open(%s) failed: %d (%s)\n", startupSemName, errno, strerror(errno)); + TRACE("NotifyRuntimeUsingSemaphores: sem_open(%s) failed: %d (%s)\n", startupSemName, errno, strerror(errno)); goto exit; } @@ -1465,7 +1649,7 @@ PAL_NotifyRuntimeStarted() { if (EINTR == errno) { - TRACE("sem_wait() failed with EINTR; re-waiting"); + TRACE("NotifyRuntimeUsingSemaphores: sem_wait() failed with EINTR; re-waiting"); continue; } ASSERT("sem_wait(continueSem) failed: errno is %d (%s)\n", errno, strerror(errno)); @@ -1487,6 +1671,45 @@ PAL_NotifyRuntimeStarted() return launched; } +/*++ + PAL_NotifyRuntimeStarted + + Signals the debugger waiting for runtime startup notification to continue and + waits until the debugger signals us to continue. + +Parameters: + None + +Return value: + TRUE - successfully launched by debugger, FALSE - not launched or some failure in the handshake +--*/ +BOOL +PALAPI +PAL_NotifyRuntimeStarted() +{ +#ifdef ENABLE_RUNTIME_EVENTS_OVER_PIPES + // Test pipes as runtime event transport. + RuntimeEventsOverPipes result = NotifyRuntimeUsingPipes(); + switch (result) + { + case RuntimeEventsOverPipes_Disabled: + TRACE("PAL_NotifyRuntimeStarted: pipe handshake disabled, try semaphores\n"); + return NotifyRuntimeUsingSemaphores(); + case RuntimeEventsOverPipes_Failed: + TRACE("PAL_NotifyRuntimeStarted: pipe handshake failed\n"); + return FALSE; + case RuntimeEventsOverPipes_Succeeded: + TRACE("PAL_NotifyRuntimeStarted: pipe handshake succeeded\n"); + return TRUE; + default: + // Unexpected result. + return FALSE; + } +#else + return NotifyRuntimeUsingSemaphores(); +#endif // ENABLE_RUNTIME_EVENTS_OVER_PIPES +} + LPCSTR PALAPI PAL_GetApplicationGroupId() @@ -2239,6 +2462,7 @@ PROCCreateCrashDump( else if (childpid == 0) { // Close the read end of the pipe, the child doesn't need it + int callbackResult = 0; close(parent_pipe); // Only dup the child's stderr if there is error buffer @@ -2252,7 +2476,12 @@ PROCCreateCrashDump( SEHCleanupSignals(true /* isChildProcess */); // Call the statically linked createdump code - g_createdumpCallback(argv.size(), argv.data()); + callbackResult = g_createdumpCallback(argv.size(), argv.data()); + // Set the shutdown callback to nullptr and exit + // If we don't exit, the child's execution will continue into the diagnostic server behavior + // which causes all sorts of problems. + g_shutdownCallback = nullptr; + exit(callbackResult); } else { @@ -2566,70 +2795,6 @@ PROCAbort(int signal, siginfo_t* siginfo) abort(); } -/*++ -Function: - InitializeFlushProcessWriteBuffers - -Abstract - This function initializes data structures needed for the FlushProcessWriteBuffers -Return - TRUE if it succeeded, FALSE otherwise ---*/ -BOOL -InitializeFlushProcessWriteBuffers() -{ - _ASSERTE(s_helperPage == 0); - _ASSERTE(s_flushUsingMemBarrier == 0); - -#if defined(__linux__) || HAVE_SYS_MEMBARRIER_H - // Starting with Linux kernel 4.14, process memory barriers can be generated - // using MEMBARRIER_CMD_PRIVATE_EXPEDITED. - int mask = membarrier(MEMBARRIER_CMD_QUERY, 0, 0); - if (mask >= 0 && - mask & MEMBARRIER_CMD_PRIVATE_EXPEDITED) - { - // Register intent to use the private expedited command. - if (membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0, 0) == 0) - { - s_flushUsingMemBarrier = TRUE; - return TRUE; - } - } -#endif - -#ifdef TARGET_APPLE - return TRUE; -#else - s_helperPage = static_cast(mmap(0, GetVirtualPageSize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); - - if(s_helperPage == MAP_FAILED) - { - return FALSE; - } - - // Verify that the s_helperPage is really aligned to the GetVirtualPageSize() - _ASSERTE((((SIZE_T)s_helperPage) & (GetVirtualPageSize() - 1)) == 0); - - // Locking the page ensures that it stays in memory during the two mprotect - // calls in the FlushProcessWriteBuffers below. If the page was unmapped between - // those calls, they would not have the expected effect of generating IPI. - int status = mlock(s_helperPage, GetVirtualPageSize()); - - if (status != 0) - { - return FALSE; - } - - status = pthread_mutex_init(&flushProcessWriteBuffersMutex, NULL); - if (status != 0) - { - munlock(s_helperPage, GetVirtualPageSize()); - } - - return status == 0; -#endif // TARGET_APPLE -} - #define FATAL_ASSERT(e, msg) \ do \ { \ @@ -2641,77 +2806,6 @@ InitializeFlushProcessWriteBuffers() } \ while(0) -/*++ -Function: - FlushProcessWriteBuffers - -See MSDN doc. ---*/ -VOID -PALAPI -FlushProcessWriteBuffers() -{ -#if defined(__linux__) || HAVE_SYS_MEMBARRIER_H - if (s_flushUsingMemBarrier) - { - int status = membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0, 0); - FATAL_ASSERT(status == 0, "Failed to flush using membarrier"); - } - else -#endif - if (s_helperPage != 0) - { - int status = pthread_mutex_lock(&flushProcessWriteBuffersMutex); - FATAL_ASSERT(status == 0, "Failed to lock the flushProcessWriteBuffersMutex lock"); - - // Changing a helper memory page protection from read / write to no access - // causes the OS to issue IPI to flush TLBs on all processors. This also - // results in flushing the processor buffers. - status = mprotect(s_helperPage, GetVirtualPageSize(), PROT_READ | PROT_WRITE); - FATAL_ASSERT(status == 0, "Failed to change helper page protection to read / write"); - - // Ensure that the page is dirty before we change the protection so that - // we prevent the OS from skipping the global TLB flush. - InterlockedIncrement(s_helperPage); - - status = mprotect(s_helperPage, GetVirtualPageSize(), PROT_NONE); - FATAL_ASSERT(status == 0, "Failed to change helper page protection to no access"); - - status = pthread_mutex_unlock(&flushProcessWriteBuffersMutex); - FATAL_ASSERT(status == 0, "Failed to unlock the flushProcessWriteBuffersMutex lock"); - } -#ifdef TARGET_APPLE - else - { - mach_msg_type_number_t cThreads; - thread_act_t *pThreads; - kern_return_t machret = task_threads(mach_task_self(), &pThreads, &cThreads); - CHECK_MACH("task_threads()", machret); - - uintptr_t sp; - uintptr_t registerValues[128]; - - // Iterate through each of the threads in the list. - for (mach_msg_type_number_t i = 0; i < cThreads; i++) - { - // Request the threads pointer values to force the thread to emit a memory barrier - size_t registers = 128; - machret = thread_get_register_pointer_values(pThreads[i], &sp, ®isters, registerValues); - if (machret == KERN_INSUFFICIENT_BUFFER_SIZE) - { - CHECK_MACH("thread_get_register_pointer_values()", machret); - } - - machret = mach_port_deallocate(mach_task_self(), pThreads[i]); - CHECK_MACH("mach_port_deallocate()", machret); - } - // Deallocate the thread list now we're done with it. - machret = vm_deallocate(mach_task_self(), (vm_address_t)pThreads, cThreads * sizeof(thread_act_t)); - CHECK_MACH("vm_deallocate()", machret); - } -#endif // TARGET_APPLE -} - /*++ Function: PROCGetProcessIDFromHandle diff --git a/src/coreclr/pal/src/thread/thread.cpp b/src/coreclr/pal/src/thread/thread.cpp index fe48f04dfe639b..ec6920f922cade 100644 --- a/src/coreclr/pal/src/thread/thread.cpp +++ b/src/coreclr/pal/src/thread/thread.cpp @@ -42,6 +42,10 @@ SET_DEFAULT_DEBUG_CHANNEL(THREAD); // some headers have code with asserts, so do #include #endif +#if defined(TARGET_BROWSER) +#include +#endif + #include #include #if HAVE_PTHREAD_NP_H @@ -1330,10 +1334,9 @@ CorUnix::GetThreadTimesInternal( CPalThread *pThread; CPalThread *pTargetThread; IPalObject *pobjThread = NULL; + clockid_t cid; #ifdef __sun int fd; -#else // __sun - clockid_t cid; #endif // __sun pThread = InternalGetCurrentThread(); @@ -2281,6 +2284,10 @@ Return : BOOL CPalThread::EnsureSignalAlternateStack() { +#ifdef TARGET_WASM + // WebAssembly does not support alternate signal stacks. + return TRUE; +#else // !TARGET_WASM int st = 0; if (g_registered_signal_handlers) @@ -2334,6 +2341,7 @@ CPalThread::EnsureSignalAlternateStack() } return (st == 0); +#endif // !TARGET_WASM } /*++ @@ -2351,6 +2359,7 @@ Return : void CPalThread::FreeSignalAlternateStack() { +#ifndef TARGET_WASM // WebAssembly does not support alternate signal stacks. void *altstack = m_alternateStack; m_alternateStack = nullptr; @@ -2374,6 +2383,7 @@ CPalThread::FreeSignalAlternateStack() } } } +#endif // !TARGET_WASM } #endif // !HAVE_MACH_EXCEPTIONS @@ -2444,6 +2454,7 @@ CPalThread::GetStackBase() status = pthread_attr_init(&attr); _ASSERT_MSG(status == 0, "pthread_attr_init call failed"); +#ifndef TARGET_BROWSER #if HAVE_PTHREAD_ATTR_GET_NP status = pthread_attr_get_np(thread, &attr); #elif HAVE_PTHREAD_GETATTR_NP @@ -2460,7 +2471,10 @@ CPalThread::GetStackBase() _ASSERT_MSG(status == 0, "pthread_attr_destroy call failed"); stackBase = (void*)((size_t)stackAddr + stackSize); -#endif +#else // TARGET_BROWSER + stackBase = (void*)emscripten_stack_get_base(); +#endif // TARGET_BROWSER +#endif // !TARGET_APPLE return stackBase; } @@ -2484,6 +2498,7 @@ CPalThread::GetStackLimit() status = pthread_attr_init(&attr); _ASSERT_MSG(status == 0, "pthread_attr_init call failed"); +#ifndef TARGET_BROWSER #if HAVE_PTHREAD_ATTR_GET_NP status = pthread_attr_get_np(thread, &attr); #elif HAVE_PTHREAD_GETATTR_NP @@ -2498,7 +2513,10 @@ CPalThread::GetStackLimit() status = pthread_attr_destroy(&attr); _ASSERT_MSG(status == 0, "pthread_attr_destroy call failed"); -#endif +#else // TARGET_BROWSER + stackLimit = (void*)emscripten_stack_get_end(); +#endif // TARGET_BROWSER +#endif // !TARGET_APPLE return stackLimit; } diff --git a/src/coreclr/runtime.proj b/src/coreclr/runtime.proj index 58bb7df9dde4cf..efe3c5bf21cb4a 100644 --- a/src/coreclr/runtime.proj +++ b/src/coreclr/runtime.proj @@ -108,13 +108,14 @@ <_CoreClrBuildScript Condition="$([MSBuild]::IsOsPlatform(Windows))">build-runtime.cmd <_CoreClrBuildScript Condition="!$([MSBuild]::IsOsPlatform(Windows))">build-runtime.sh - <_CoreClrBuildPreSource Condition="'$(TargetsBrowser)' == 'true' and $([MSBuild]::IsOsPlatform(Windows))">"$([MSBuild]::NormalizePath('$(RepoRoot)src/mono/browser/emsdk', 'emsdk_env.cmd'))" && - <_CoreClrBuildPreSource Condition="'$(TargetsBrowser)' == 'true' and !$([MSBuild]::IsOsPlatform(Windows))">source "$(RepoRoot)src/mono/browser/emsdk/emsdk_env.sh" && + <_CoreClrBuildCommand>"$(MSBuildThisFileDirectory)$(_CoreClrBuildScript)" @(_CoreClrBuildArg, ' ') + <_CoreClrBuildCommand Condition="'$(TargetsBrowser)' == 'true' and $([MSBuild]::IsOsPlatform(Windows))">call "$([MSBuild]::NormalizePath('$(RepoRoot)src/mono/browser/emsdk', 'emsdk_env.cmd'))" && $(_CoreClrBuildCommand) + <_CoreClrBuildCommand Condition="'$(TargetsBrowser)' == 'true' and !$([MSBuild]::IsOsPlatform(Windows))">bash -c 'source "$(RepoRoot)src/mono/browser/emsdk/emsdk_env.sh" && $(_CoreClrBuildCommand)' - - + diff --git a/src/coreclr/runtime/amd64/AllocFast.S b/src/coreclr/runtime/amd64/AllocFast.S index d5b366b876dad6..02091bea31083e 100644 --- a/src/coreclr/runtime/amd64/AllocFast.S +++ b/src/coreclr/runtime/amd64/AllocFast.S @@ -173,7 +173,7 @@ NESTED_END RhpNewObject, _TEXT // Allocate a string. // RDI == MethodTable -// ESI == character/element count +// RSI == character/element count LEAF_ENTRY RhNewString, _TEXT // we want to limit the element count to the non-negative 32-bit int range @@ -233,8 +233,11 @@ LEAF_END RhpNewArrayFast, _TEXT LEAF_ENTRY RhpNewPtrArrayFast, _TEXT // Delegate overflow handling to the generic helper conservatively + // The constant 0x8000000 is (0x40000000 / sizeof(void*)) + // Some assemblers don't like an expression here, so the + // constant expression is reduced to it's simple form. - cmp rsi, (0x40000000 / 8) // sizeof(void*) + cmp rsi, 0x8000000 // (0x40000000 / 8) jae C_FUNC(RhpNewArrayFast) // In this case we know the element size is sizeof(void *), or 8 for x64 diff --git a/src/coreclr/runtime/amd64/AllocFast.asm b/src/coreclr/runtime/amd64/AllocFast.asm index c099cb829b2c83..cda88f3bf8f1ec 100644 --- a/src/coreclr/runtime/amd64/AllocFast.asm +++ b/src/coreclr/runtime/amd64/AllocFast.asm @@ -128,7 +128,7 @@ ENDM ; NEW_ARRAY_FAST ;; Allocate a string. ;; RCX == MethodTable -;; EDX == character/element count +;; RDX == character/element count LEAF_ENTRY RhNewString, _TEXT ; we want to limit the element count to the non-negative 32-bit int range diff --git a/src/coreclr/tools/Common/Compiler/Dataflow/MethodProxy.cs b/src/coreclr/tools/Common/Compiler/Dataflow/MethodProxy.cs index cfb4bb12902958..e0883f5eca8efc 100644 --- a/src/coreclr/tools/Common/Compiler/Dataflow/MethodProxy.cs +++ b/src/coreclr/tools/Common/Compiler/Dataflow/MethodProxy.cs @@ -48,7 +48,7 @@ internal partial ParameterProxy GetParameter(ParameterIndex index) internal partial bool HasGenericParameters() => Method.HasInstantiation; - internal partial bool HasGenericParametersCount(int genericParameterCount) => Method.Instantiation.Length == genericParameterCount; + internal partial bool HasGenericArgumentsCount(int genericArgumentCount) => Method.Instantiation.Length == genericArgumentCount; internal partial ImmutableArray GetGenericParameters() { diff --git a/src/coreclr/tools/Common/Compiler/DevirtualizationManager.cs b/src/coreclr/tools/Common/Compiler/DevirtualizationManager.cs index ceb7b6b71141b3..f704807c0c0841 100644 --- a/src/coreclr/tools/Common/Compiler/DevirtualizationManager.cs +++ b/src/coreclr/tools/Common/Compiler/DevirtualizationManager.cs @@ -210,6 +210,12 @@ protected virtual MethodDesc ResolveVirtualMethod(MethodDesc declMethod, DefType /// public virtual bool CanReferenceConstructedMethodTable(TypeDesc type) => true; + /// + /// Gets a value indicating whether it might be possible to obtain a metadata type data structure for the given type + /// in this compilation (i.e. is it possible to reference a metadata MethodTable symbol for this). + /// + public virtual bool CanReferenceMetadataMethodTable(TypeDesc type) => true; + /// /// Gets a value indicating whether a (potentially canonically-equlivalent) constructed MethodTable could /// exist. This is similar to , but will return true diff --git a/src/coreclr/tools/Common/Compiler/TypeExtensions.cs b/src/coreclr/tools/Common/Compiler/TypeExtensions.cs index ac69f6872a6b75..9b655d00578dcd 100644 --- a/src/coreclr/tools/Common/Compiler/TypeExtensions.cs +++ b/src/coreclr/tools/Common/Compiler/TypeExtensions.cs @@ -469,7 +469,9 @@ public static MethodDesc TryResolveConstraintMethodApprox(this TypeDesc constrai potentialInterfaceMethod.GetTypicalMethodDefinition(), (InstantiatedType)potentialInterfaceType); } - method = canonType.ResolveInterfaceMethodToVirtualMethodOnType(potentialInterfaceMethod); + method = canonType.ResolveInterfaceMethodToVirtualMethodOnType(potentialInterfaceMethod) + // Do not lose track of `method` if we were able to resolve it previously + ?? method; // See code:#TryResolveConstraintMethodApprox_DoNotReturnParentMethod if (method != null && !method.OwningType.IsValueType) diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/ReaderGen.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/ReaderGen.cs index 04f962ebb1c48d..88f1e8ecfefe36 100644 --- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/ReaderGen.cs +++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/ReaderGen.cs @@ -173,7 +173,9 @@ private void EmitHandle(RecordDef record) CloseScope("_Validate"); WriteLineIfNeeded(); + WriteLine("#if DEBUG"); WriteLine("public override string ToString() => string.Format(\"{0:X8}\", _value);"); + WriteLine("#endif"); CloseScope(handleName); } diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs index b2fdce3f0c0cb1..88192d6a03463c 100644 --- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs +++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs @@ -109,7 +109,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ArraySignatureHandle #if SYSTEM_PRIVATE_CORELIB @@ -188,7 +190,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ByReferenceSignatureHandle #if SYSTEM_PRIVATE_CORELIB @@ -266,7 +270,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantBooleanArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -344,7 +350,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantBooleanValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -422,7 +430,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantByteArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -500,7 +510,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantByteValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -578,7 +590,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantCharArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -656,7 +670,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantCharValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -734,7 +750,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantDoubleArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -812,7 +830,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantDoubleValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -894,7 +914,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantEnumArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -976,7 +998,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantEnumValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -1054,7 +1078,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantHandleArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -1132,7 +1158,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantInt16ArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -1210,7 +1238,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantInt16ValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -1288,7 +1318,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantInt32ArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -1366,7 +1398,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantInt32ValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -1444,7 +1478,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantInt64ArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -1522,7 +1558,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantInt64ValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -1596,7 +1634,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantReferenceValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -1674,7 +1714,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantSByteArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -1752,7 +1794,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantSByteValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -1830,7 +1874,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantSingleArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -1908,7 +1954,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantSingleValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -1987,7 +2035,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantStringArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -2067,7 +2117,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantStringValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -2145,7 +2197,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantUInt16ArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -2223,7 +2277,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantUInt16ValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -2301,7 +2357,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantUInt32ArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -2379,7 +2437,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantUInt32ValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -2457,7 +2517,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantUInt64ArrayHandle #if SYSTEM_PRIVATE_CORELIB @@ -2535,7 +2597,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ConstantUInt64ValueHandle #if SYSTEM_PRIVATE_CORELIB @@ -2623,7 +2687,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // CustomAttributeHandle #if SYSTEM_PRIVATE_CORELIB @@ -2718,7 +2784,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // EventHandle #if SYSTEM_PRIVATE_CORELIB @@ -2817,7 +2885,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // FieldHandle #if SYSTEM_PRIVATE_CORELIB @@ -2896,7 +2966,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // FieldSignatureHandle #if SYSTEM_PRIVATE_CORELIB @@ -2974,7 +3046,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // FunctionPointerSignatureHandle #if SYSTEM_PRIVATE_CORELIB @@ -3073,7 +3147,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // GenericParameterHandle #if SYSTEM_PRIVATE_CORELIB @@ -3161,7 +3237,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // MemberReferenceHandle #if SYSTEM_PRIVATE_CORELIB @@ -3263,7 +3341,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // MethodHandle #if SYSTEM_PRIVATE_CORELIB @@ -3347,7 +3427,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // MethodInstantiationHandle #if SYSTEM_PRIVATE_CORELIB @@ -3429,7 +3511,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // MethodSemanticsHandle #if SYSTEM_PRIVATE_CORELIB @@ -3526,7 +3610,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // MethodSignatureHandle #if SYSTEM_PRIVATE_CORELIB @@ -3604,7 +3690,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // MethodTypeVariableSignatureHandle #if SYSTEM_PRIVATE_CORELIB @@ -3692,7 +3780,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ModifiedTypeHandle #if SYSTEM_PRIVATE_CORELIB @@ -3784,7 +3874,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // NamedArgumentHandle #if SYSTEM_PRIVATE_CORELIB @@ -3879,7 +3971,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // NamespaceDefinitionHandle #if SYSTEM_PRIVATE_CORELIB @@ -3962,7 +4056,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // NamespaceReferenceHandle #if SYSTEM_PRIVATE_CORELIB @@ -4057,7 +4153,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ParameterHandle #if SYSTEM_PRIVATE_CORELIB @@ -4136,7 +4234,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // PointerSignatureHandle #if SYSTEM_PRIVATE_CORELIB @@ -4235,7 +4335,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // PropertyHandle #if SYSTEM_PRIVATE_CORELIB @@ -4323,7 +4425,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // PropertySignatureHandle #if SYSTEM_PRIVATE_CORELIB @@ -4405,7 +4509,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // QualifiedFieldHandle #if SYSTEM_PRIVATE_CORELIB @@ -4487,7 +4593,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // QualifiedMethodHandle #if SYSTEM_PRIVATE_CORELIB @@ -4566,7 +4674,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // SZArraySignatureHandle #if SYSTEM_PRIVATE_CORELIB @@ -4704,7 +4814,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ScopeDefinitionHandle #if SYSTEM_PRIVATE_CORELIB @@ -4810,7 +4922,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // ScopeReferenceHandle #if SYSTEM_PRIVATE_CORELIB @@ -4946,7 +5060,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // TypeDefinitionHandle #if SYSTEM_PRIVATE_CORELIB @@ -5032,7 +5148,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // TypeForwarderHandle #if SYSTEM_PRIVATE_CORELIB @@ -5116,7 +5234,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // TypeInstantiationSignatureHandle #if SYSTEM_PRIVATE_CORELIB @@ -5199,7 +5319,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // TypeReferenceHandle #if SYSTEM_PRIVATE_CORELIB @@ -5278,7 +5400,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // TypeSpecificationHandle #if SYSTEM_PRIVATE_CORELIB @@ -5356,7 +5480,9 @@ internal void _Validate() throw new ArgumentException(); } // _Validate + #if DEBUG public override string ToString() => string.Format("{0:X8}", _value); + #endif } // TypeVariableSignatureHandle #if SYSTEM_PRIVATE_CORELIB diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeMetadataReader.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeMetadataReader.cs index 2379832cb73c9a..53bb71d1c7d5d6 100644 --- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeMetadataReader.cs +++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeMetadataReader.cs @@ -234,9 +234,6 @@ internal ReadOnlySpan ReadStringAsBytes(ConstantStringValueHandle handle) internal sealed partial class MetadataHeader { - /// - /// Signature should be updated every time the metadata schema changes. - /// public const uint Signature = 0xDEADDFFD; /// diff --git a/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormat.cs b/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormat.cs index dbe629602172b5..7962ee0a15d29a 100644 --- a/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormat.cs +++ b/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormat.cs @@ -98,9 +98,9 @@ enum FixupSignatureKind : uint // unused = 0x17, // unused = 0x18, // unused = 0x19, - // unused = 0x20, + NonGenericInstanceConstrainedMethod = 0x20, NonGenericStaticConstrainedMethod = 0x21, - GenericStaticConstrainedMethod = 0x22, + GenericConstrainedMethod = 0x22, NotYetSupported = 0xee, } diff --git a/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormatReader.String.cs b/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormatReader.String.cs index a6fdf456cc643c..98a72da96913df 100644 --- a/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormatReader.String.cs +++ b/src/coreclr/tools/Common/Internal/NativeFormat/NativeFormatReader.String.cs @@ -73,15 +73,7 @@ public unsafe uint DecodeString(uint offset, out string value) if (endOffset < numBytes || endOffset > _size) ThrowBadImageFormatException(); -#if NETFX_45 - byte[] bytes = new byte[numBytes]; - for (int i = 0; i < bytes.Length; i++) - bytes[i] = *(_base + offset + i); - - value = Encoding.UTF8.GetString(bytes, 0, bytes.Length); -#else value = Encoding.UTF8.GetString(_base + offset, (int)numBytes); -#endif return endOffset; } diff --git a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs index c624469449c421..1ea99252052d90 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs @@ -15,7 +15,7 @@ internal struct ReadyToRunHeaderConstants { public const uint Signature = 0x00525452; // 'RTR' - public const ushort CurrentMajorVersion = 15; + public const ushort CurrentMajorVersion = 16; public const ushort CurrentMinorVersion = 0; } #if READYTORUN diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 06b34f71550601..e6fd0d4f7f80e0 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -3638,7 +3638,13 @@ private void getLocationOfThisType(CORINFO_METHOD_STRUCT_* context, ref CORINFO_ { throw new NotImplementedException("GetCookieForInterpreterCalliSig"); } private void* GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, ref void* ppIndirection) - { throw new NotImplementedException("GetCookieForPInvokeCalliSig"); } + { +#if READYTORUN + throw new RequiresRuntimeJitException($"{MethodBeingCompiled} -> {nameof(GetCookieForPInvokeCalliSig)}"); +#else + throw new NotImplementedException(nameof(GetCookieForPInvokeCalliSig)); +#endif + } #pragma warning disable CA1822 // Mark members as static private CORINFO_JUST_MY_CODE_HANDLE_* getJustMyCodeHandle(CORINFO_METHOD_STRUCT_* method, ref CORINFO_JUST_MY_CODE_HANDLE_* ppIndirection) #pragma warning restore CA1822 // Mark members as static @@ -3668,10 +3674,8 @@ private CORINFO_CONST_LOOKUP CreateConstLookupToSymbol(ISymbolNode symbol) return null; } - private IntPtr getVarArgsHandle(CORINFO_SIG_INFO* pSig, ref void* ppIndirection) + private IntPtr getVarArgsHandle(CORINFO_SIG_INFO* pSig, CORINFO_METHOD_STRUCT_* methHnd, ref void* ppIndirection) { throw new NotImplementedException("getVarArgsHandle"); } - private bool canGetVarArgsHandle(CORINFO_SIG_INFO* pSig) - { throw new NotImplementedException("canGetVarArgsHandle"); } private InfoAccessType emptyStringLiteral(ref void* ppValue) { diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 6be49af5d42404..8d0c83046277dd 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/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) { @@ -2120,21 +2105,6 @@ private static void _getAddressOfPInvokeTarget(IntPtr thisHandle, IntPtr* ppExce } } - [UnmanagedCallersOnly] - private static byte _canGetCookieForPInvokeCalliSig(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* szMetaSig) - { - var _this = GetThis(thisHandle); - try - { - return _this.canGetCookieForPInvokeCalliSig(szMetaSig) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - [UnmanagedCallersOnly] private static CORINFO_JUST_MY_CODE_HANDLE_* _getJustMyCodeHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, CORINFO_JUST_MY_CODE_HANDLE_** ppIndirection) { @@ -2224,27 +2194,12 @@ private static byte _getObjectContent(IntPtr thisHandle, IntPtr* ppException, CO } [UnmanagedCallersOnly] - private static IntPtr _getVarArgsHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* pSig, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getVarArgsHandle(pSig, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _canGetVarArgsHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* pSig) + private static IntPtr _getVarArgsHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* pSig, CORINFO_METHOD_STRUCT_* methHnd, void** ppIndirection) { var _this = GetThis(thisHandle); try { - return _this.canGetVarArgsHandle(pSig) ? (byte)1 : (byte)0; + return _this.getVarArgsHandle(pSig, methHnd, ref *ppIndirection); } catch (Exception ex) { @@ -2651,7 +2606,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) * 176); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_notifyMethodInfoUsage; @@ -2785,53 +2740,50 @@ 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)&_getJustMyCodeHandle; + callbacks[143] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[144] = (delegate* unmanaged)&_getCallInfo; + callbacks[145] = (delegate* unmanaged)&_getStaticFieldContent; + callbacks[146] = (delegate* unmanaged)&_getObjectContent; + callbacks[147] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[148] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[149] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[150] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[151] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[152] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[153] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[154] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[155] = (delegate* unmanaged)&_getAsyncResumptionStub; + callbacks[156] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[157] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[158] = (delegate* unmanaged)&_updateEntryPointForTailCall; + callbacks[159] = (delegate* unmanaged)&_allocMem; + callbacks[160] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[161] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[162] = (delegate* unmanaged)&_allocGCInfo; + callbacks[163] = (delegate* unmanaged)&_setEHcount; + callbacks[164] = (delegate* unmanaged)&_setEHinfo; + callbacks[165] = (delegate* unmanaged)&_logMsg; + callbacks[166] = (delegate* unmanaged)&_doAssert; + callbacks[167] = (delegate* unmanaged)&_reportFatalError; + callbacks[168] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[169] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; + callbacks[170] = (delegate* unmanaged)&_recordCallSite; + callbacks[171] = (delegate* unmanaged)&_recordRelocation; + callbacks[172] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[173] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[174] = (delegate* unmanaged)&_getJitFlags; + callbacks[175] = (delegate* unmanaged)&_getSpecialCopyHelper; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 7b5f8a7d79f292..4c4945475399c1 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/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); @@ -309,15 +308,13 @@ FUNCTIONS void getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, REF_CORINFO_CONST_LOOKUP pLookup); void* GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void ** ppIndirection); void* GetCookieForInterpreterCalliSig(CORINFO_SIG_INFO* szMetaSig); - bool canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig); CORINFO_JUST_MY_CODE_HANDLE getJustMyCodeHandle(CORINFO_METHOD_HANDLE method, CORINFO_JUST_MY_CODE_HANDLE**ppIndirection); void GetProfilingHandle(bool* pbHookFunction, void **pProfilerHandle, bool* pbIndirectedHandles); void getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN_PTR pConstrainedResolvedToken, CORINFO_METHOD_HANDLE callerHandle, CORINFO_CALLINFO_FLAGS flags, CORINFO_CALL_INFO *pResult); bool getStaticFieldContent(CORINFO_FIELD_HANDLE field, uint8_t *buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects); bool getObjectContent(CORINFO_OBJECT_HANDLE obj, uint8_t *buffer, int bufferSize, int valueOffset); CORINFO_CLASS_HANDLE getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, BoolStar pIsSpeculative); - CORINFO_VARARGS_HANDLE getVarArgsHandle(CORINFO_SIG_INFO *pSig, void **ppIndirection); - bool canGetVarArgsHandle(CORINFO_SIG_INFO *pSig); + CORINFO_VARARGS_HANDLE getVarArgsHandle(CORINFO_SIG_INFO *pSig, CORINFO_METHOD_HANDLE methHnd, void **ppIndirection); InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE module, mdToken metaTok, void **ppValue); InfoAccessType emptyStringLiteral(void **ppValue); uint32_t getFieldThreadLocalStoreID (CORINFO_FIELD_HANDLE field, void **ppIndirection); diff --git a/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs b/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs index 923ec0da4316fb..97363c783f8a3e 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs @@ -19,6 +19,7 @@ public enum ExceptionStringID ClassLoadInlineArrayFieldCount, ClassLoadInlineArrayLength, ClassLoadInlineArrayExplicit, + ClassLoadInlineArrayExplicitSize, // MissingMethodException MissingMethod, diff --git a/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs b/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs index 107d8dbffb87c4..604f76cd09442f 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs @@ -510,6 +510,12 @@ private static void AdjustForInlineArray( ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadInlineArrayFieldCount, type); } + var layoutMetadata = type.GetClassLayout(); + if (layoutMetadata.Size != 0) + { + ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadInlineArrayExplicitSize, type); + } + if (!instanceByteSizeAndAlignment.Size.IsIndeterminate) { long size = instanceByteSizeAndAlignment.Size.AsInt; diff --git a/src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs b/src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs index 5f05fdeb9f4703..f0eae5441d0c28 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs @@ -936,8 +936,6 @@ public override DefaultInterfaceMethodResolution ResolveVariantInterfaceMethodTo public static DefaultInterfaceMethodResolution ResolveVariantInterfaceMethodToDefaultImplementationOnType(MethodDesc interfaceMethod, MetadataType currentType, out MethodDesc impl) { - Debug.Assert(interfaceMethod.Signature.IsStatic); - MetadataType interfaceType = (MetadataType)interfaceMethod.OwningType; bool foundInterface = IsInterfaceImplementedOnType(currentType, interfaceType); diff --git a/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx b/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx index 6a2f012e012586..1ce5dcbd5e3333 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx +++ b/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx @@ -138,6 +138,9 @@ InlineArrayAttribute cannot be applied to a type with explicit layout. Type: '{0}'. Assembly: '{1}'.' + + InlineArrayAttribute cannot be applied to a type with explicit size. Type: '{0}'. Assembly: '{1}'.' + Array of type '{0}' from assembly '{1}' cannot be created because base value type is too large diff --git a/src/coreclr/tools/Common/TypeSystem/Common/ThrowHelper.Common.cs b/src/coreclr/tools/Common/TypeSystem/Common/ThrowHelper.Common.cs index 58114db36dfc86..62a6382bb592ec 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/ThrowHelper.Common.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/ThrowHelper.Common.cs @@ -65,7 +65,7 @@ public static string Module(ModuleDesc module) IAssemblyDesc assembly = module as IAssemblyDesc; if (assembly != null) { - return assembly.GetName().FullName; + return assembly.GetName().Name; } else { diff --git a/src/coreclr/tools/ILVerify/Program.cs b/src/coreclr/tools/ILVerify/Program.cs index eae57d8bfd752d..c5129006e4fa0e 100644 --- a/src/coreclr/tools/ILVerify/Program.cs +++ b/src/coreclr/tools/ILVerify/Program.cs @@ -362,7 +362,7 @@ private string GetFullClassName(MetadataReader metadataReader, TypeDefinitionHan fullName.Append(GetFullClassName(metadataReader, declaringType)); fullName.Append('+'); } - + var namespaceName = metadataReader.GetString(typeDef.Namespace); if (!string.IsNullOrEmpty(namespaceName)) { @@ -372,7 +372,7 @@ private string GetFullClassName(MetadataReader metadataReader, TypeDefinitionHan var typeName = metadataReader.GetString(typeDef.Name); fullName.Append(typeName); - + return fullName.ToString(); } @@ -479,10 +479,14 @@ public PEReader Resolve(string simpleName) private T Get(Argument argument) => _command.Result.GetValue(argument); private static int Main(string[] args) => - new CommandLineConfiguration(new ILVerifyRootCommand().UseVersion()) + new ILVerifyRootCommand().UseVersion() + .Parse(args, new() { ResponseFileTokenReplacer = Helpers.TryReadResponseFile, - EnableDefaultExceptionHandler = false, - }.Invoke(args); + }) + .Invoke(new() + { + EnableDefaultExceptionHandler = false + }); } } diff --git a/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs b/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs index e4c5332acaa21a..256ef76f9ed885 100644 --- a/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs +++ b/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs @@ -130,7 +130,9 @@ public override bool Execute() continue; } - if (isFromRuntimePack && taskItem.GetMetadata("AssetType")?.Equals("native", StringComparison.OrdinalIgnoreCase) == true) + if (isFromRuntimePack && taskItem.GetMetadata("AssetType")?.Equals("native", StringComparison.OrdinalIgnoreCase) == true + && !assemblyFileName.EndsWith(".jar", StringComparison.OrdinalIgnoreCase) + && !assemblyFileName.EndsWith(".dex", StringComparison.OrdinalIgnoreCase)) { // Skip the native components of the runtime pack, we don't need them for NativeAOT. assembliesToSkipPublish.Add(taskItem); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler.Tests/DependencyGraphTests.cs b/src/coreclr/tools/aot/ILCompiler.Compiler.Tests/DependencyGraphTests.cs index c20912efd6a5fb..d55ac1c07b1474 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler.Tests/DependencyGraphTests.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler.Tests/DependencyGraphTests.cs @@ -67,7 +67,7 @@ public void TestDependencyGraphInvariants(EcmaMethod method) CompilationModuleGroup compilationGroup = new SingleFileCompilationModuleGroup(); NativeAotILProvider ilProvider = new NativeAotILProvider(); - CompilerGeneratedState compilerGeneratedState = new CompilerGeneratedState(ilProvider, Logger.Null); + CompilerGeneratedState compilerGeneratedState = new CompilerGeneratedState(ilProvider, Logger.Null, disableGeneratedCodeHeuristics: true); UsageBasedMetadataManager metadataManager = new UsageBasedMetadataManager(compilationGroup, context, new FullyBlockedMetadataBlockingPolicy(), new FullyBlockedManifestResourceBlockingPolicy(), diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/AssemblyExtensions.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/AssemblyExtensions.cs new file mode 100644 index 00000000000000..24ca1923b90c3a --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/AssemblyExtensions.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics; +using System.Reflection.Metadata; +using Internal.TypeSystem; +using Internal.TypeSystem.Ecma; + +#nullable enable + +namespace ILCompiler +{ + public static class AssemblyExtensions + { + public static Version? GetTargetFrameworkVersion(this EcmaAssembly assembly) + { + // Get the custom attributes from the assembly's metadata + MetadataReader reader = assembly.MetadataReader; + CustomAttributeHandle attrHandle = reader.GetCustomAttributeHandle(assembly.AssemblyDefinition.GetCustomAttributes(), + "System.Runtime.Versioning", "TargetFrameworkAttribute"); + if (!attrHandle.IsNil) + { + CustomAttribute attr = reader.GetCustomAttribute(attrHandle); + CustomAttributeValue decoded = attr.DecodeValue(new CustomAttributeTypeProvider(assembly)); + if (decoded.FixedArguments.Length == 1 && decoded.FixedArguments[0].Value is string tfm && !string.IsNullOrEmpty(tfm)) + { + var versionPrefix = "Version=v"; + var idx = tfm.IndexOf(versionPrefix); + if (idx >= 0) + { + var versionStr = tfm.Substring(idx + versionPrefix.Length); + if (Version.TryParse(versionStr, out var version)) + return version; + } + } + } + return null; + } + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs index c32e6215bd5049..1d46b96d22ea7c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs @@ -183,7 +183,7 @@ public MethodDesc ExpandIntrinsicForCallsite(MethodDesc intrinsicMethod, MethodD if (callsiteModule != null) { Debug.Assert(callsiteModule is IAssemblyDesc, "Multi-module assemblies"); - return _typeGetTypeMethodThunks.GetHelper(intrinsicMethod, ((IAssemblyDesc)callsiteModule).GetName().FullName); + return _typeGetTypeMethodThunks.GetHelper(intrinsicMethod, ((IAssemblyDesc)callsiteModule).GetName().Name); } } } @@ -241,6 +241,7 @@ public bool NeedsRuntimeLookup(ReadyToRunHelperId lookupKind, object targetOfLoo { case ReadyToRunHelperId.TypeHandle: case ReadyToRunHelperId.NecessaryTypeHandle: + case ReadyToRunHelperId.MetadataTypeHandle: case ReadyToRunHelperId.DefaultConstructor: case ReadyToRunHelperId.TypeHandleForCasting: case ReadyToRunHelperId.ObjectAllocator: @@ -266,13 +267,22 @@ public bool NeedsRuntimeLookup(ReadyToRunHelperId lookupKind, object targetOfLoo public ReadyToRunHelperId GetLdTokenHelperForType(TypeDesc type) { - bool canPotentiallyConstruct = ConstructedEETypeNode.CreationAllowed(type) - && NodeFactory.DevirtualizationManager.CanReferenceConstructedMethodTable(type.NormalizeInstantiation()); - if (canPotentiallyConstruct) - return ReadyToRunHelperId.TypeHandle; + // This will not correctly answer questions for canonical forms because the answer would + // be about whether a type loader template for the type exists. + // We need to make a small exception for canonical definitions because of RuntimeAugments.GetCanonType + Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Any) || type.IsCanonicalDefinitionType(CanonicalFormKind.Any)); if (type.IsGenericDefinition && NodeFactory.DevirtualizationManager.IsGenericDefinitionMethodTableReflectionVisible(type)) - return ReadyToRunHelperId.TypeHandle; + return ReadyToRunHelperId.MetadataTypeHandle; + + if (ConstructedEETypeNode.CreationAllowed(type)) + { + if (NodeFactory.DevirtualizationManager.CanReferenceConstructedMethodTable(type.NormalizeInstantiation())) + return ReadyToRunHelperId.TypeHandle; + + if (NodeFactory.DevirtualizationManager.CanReferenceMetadataMethodTable(type.NormalizeInstantiation())) + return ReadyToRunHelperId.MetadataTypeHandle; + } return ReadyToRunHelperId.NecessaryTypeHandle; } @@ -302,6 +312,8 @@ public ISymbolNode ComputeConstantLookup(ReadyToRunHelperId lookupKind, object t { case ReadyToRunHelperId.TypeHandle: return NodeFactory.ConstructedTypeSymbol((TypeDesc)targetOfLookup); + case ReadyToRunHelperId.MetadataTypeHandle: + return NodeFactory.MetadataTypeSymbol((TypeDesc)targetOfLookup); case ReadyToRunHelperId.NecessaryTypeHandle: return NecessaryTypeSymbolIfPossible((TypeDesc)targetOfLookup); case ReadyToRunHelperId.TypeHandleForCasting: @@ -344,7 +356,7 @@ public ISymbolNode ComputeConstantLookup(ReadyToRunHelperId lookupKind, object t case ReadyToRunHelperId.ObjectAllocator: { var type = (TypeDesc)targetOfLookup; - return NodeFactory.ExternSymbol(JitHelper.GetNewObjectHelperForType(type)); + return NodeFactory.ExternFunctionSymbol(JitHelper.GetNewObjectHelperForType(type)); } default: @@ -393,12 +405,6 @@ public GenericDictionaryLookup ComputeGenericLookup(MethodDesc contextMethod, Re } } - // We don't have separate entries for necessary type handles to avoid possible duplication - if (lookupKind == ReadyToRunHelperId.NecessaryTypeHandle) - { - lookupKind = ReadyToRunHelperId.TypeHandle; - } - DictionaryLayoutNode dictionaryLayout; if (contextSource == GenericContextSource.MethodParameter) dictionaryLayout = _nodeFactory.GenericDictionaryLayout(contextMethod); @@ -650,7 +656,7 @@ public IEnumerable ConstructedEETypes { foreach (var node in MarkedNodes) { - if (node is ConstructedEETypeNode || node is CanonicalEETypeNode) + if (node is ConstructedEETypeNode) yield return ((IEETypeNode)node).Type; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs index 5eb049c74e442b..03818be44eb2a3 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs @@ -21,7 +21,7 @@ public partial class CompilationBuilder protected MethodImportationErrorProvider _methodImportationErrorProvider = new MethodImportationErrorProvider(); protected ReadOnlyFieldPolicy _readOnlyFieldPolicy = new ReadOnlyFieldPolicy(); protected IInliningPolicy _inliningPolicy; - protected bool _methodBodyFolding; + protected MethodBodyFoldingMode _methodBodyFolding; protected InstructionSetSupport _instructionSetSupport; protected SecurityMitigationOptions _mitigationOptions; protected bool _dehydrate; @@ -94,9 +94,9 @@ public CompilationBuilder UseDehydration(bool dehydrate) return this; } - public CompilationBuilder UseMethodBodyFolding(bool enable) + public CompilationBuilder UseMethodBodyFolding(MethodBodyFoldingMode mode) { - _methodBodyFolding = enable; + _methodBodyFolding = mode; return this; } @@ -154,4 +154,11 @@ public enum SecurityMitigationOptions { ControlFlowGuardAnnotations = 0x0001, } + + public enum MethodBodyFoldingMode + { + None, + Generic, + All, + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilerTypeSystemContext.Aot.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilerTypeSystemContext.Aot.cs index 699d8d16577e51..beb5658718cf9c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilerTypeSystemContext.Aot.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilerTypeSystemContext.Aot.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Diagnostics; using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -39,8 +40,10 @@ public SharedGenericsConfiguration GenericsConfig private readonly TypeWithRepeatedFieldsFieldLayoutAlgorithm _typeWithRepeatedFieldsFieldLayoutAlgorithm; private TypeDesc[] _arrayOfTInterfaces; + private TypeDesc[] _arrayEnumeratorOfTInterfaces; private ArrayOfTRuntimeInterfacesAlgorithm _arrayOfTRuntimeInterfacesAlgorithm; private MetadataType _arrayOfTType; + private MetadataType _arrayOfTEnumeratorType; private MetadataType _attributeType; public CompilerTypeSystemContext(TargetDetails details, SharedGenericsMode genericsMode, DelegateFeature delegateFeatures, @@ -62,6 +65,38 @@ public CompilerTypeSystemContext(TargetDetails details, SharedGenericsMode gener GenericsConfig = new SharedGenericsConfiguration(); } + public MetadataType ArrayOfTEnumeratorType + { + get + { + // This type is optional, but it's fine for this cache to be ineffective if that happens. + // Those scenarios are rare and typically deal with small compilations. + return _arrayOfTEnumeratorType ??= SystemModule.GetType("System", "SZGenericArrayEnumerator`1", throwIfNotFound: false); + } + } + + public bool IsArrayVariantCastable(TypeDesc type) + { + // Arrays and array enumerators have weird casting rules due to array covariance + // (string[] castable to object[], or int[] castable to uint[], or int[] castable + // to IList). + + if (type.IsSzArray + || type.GetTypeDefinition() == ArrayOfTEnumeratorType + || IsGenericArrayInterfaceType(type) + || IsGenericArrayEnumeratorInterfaceType(type)) + { + TypeDesc elementType = type.IsSzArray ? ((ArrayType)type).ElementType : type.Instantiation[0]; + if (CastingHelper.IsArrayElementTypeCastableBySize(elementType) || + (elementType.IsDefType && !elementType.IsValueType)) + { + return true; + } + } + + return false; + } + protected override RuntimeInterfacesAlgorithm GetRuntimeInterfacesAlgorithmForNonPointerArrayType(ArrayType type) { _arrayOfTRuntimeInterfacesAlgorithm ??= new ArrayOfTRuntimeInterfacesAlgorithm(SystemModule.GetKnownType("System", "Array`1")); @@ -126,6 +161,33 @@ public bool IsGenericArrayInterfaceType(TypeDesc type) return false; } + public bool IsGenericArrayEnumeratorInterfaceType(TypeDesc type) + { + // Hardcode the fact that all generic interfaces on array enumerator have arity 1 + if (!type.IsInterface || type.Instantiation.Length != 1) + return false; + + if (_arrayEnumeratorOfTInterfaces == null) + { + DefType[] implementedInterfaces = ArrayOfTEnumeratorType?.ExplicitlyImplementedInterfaces; + + ArrayBuilder definitions = default; + if (implementedInterfaces != null) + { + foreach (DefType interfaceType in implementedInterfaces) + { + if (interfaceType.HasInstantiation) + definitions.Add(interfaceType.GetTypeDefinition()); + } + } + + Interlocked.CompareExchange(ref _arrayEnumeratorOfTInterfaces, definitions.ToArray(), null); + } + + TypeDesc interfaceDefinition = type.GetTypeDefinition(); + return Array.IndexOf(_arrayEnumeratorOfTInterfaces, interfaceDefinition) >= 0; + } + protected override IEnumerable GetAllMethods(TypeDesc type) { return GetAllMethods(type, virtualOnly: false); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ArrayValue.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ArrayValue.cs index beb0d60d4799af..cab9d351cf6bb2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ArrayValue.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ArrayValue.cs @@ -19,7 +19,7 @@ internal partial record ArrayValue public static MultiValue Create(MultiValue size, TypeDesc elementType) { MultiValue result = MultiValueLattice.Top; - foreach (var sizeValue in size.AsEnumerable ()) + foreach (var sizeValue in size.AsEnumerable()) { result = MultiValueLattice.Meet(result, new MultiValue(new ArrayValue(sizeValue, elementType))); } @@ -92,7 +92,7 @@ public override SingleValue DeepCopy() // Since it's possible to store a reference to array as one of its own elements // simple deep copy could lead to endless recursion. // So instead we simply disallow arrays as element values completely - and treat that case as "too complex to analyze". - foreach (SingleValue v in kvp.Value.Value.AsEnumerable ()) + foreach (SingleValue v in kvp.Value.Value.AsEnumerable()) { System.Diagnostics.Debug.Assert(v is not ArrayValue); } @@ -123,7 +123,7 @@ public override string ToString() result.Append(element.Key); result.Append(",("); bool firstValue = true; - foreach (var v in element.Value.Value.AsEnumerable ()) + foreach (var v in element.Value.Value.AsEnumerable()) { if (firstValue) { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedState.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedState.cs index 24707c75f8c293..a4360d9a33a52e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedState.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedState.cs @@ -24,17 +24,20 @@ public class CompilerGeneratedState private readonly record struct TypeArgumentInfo( /// The method which calls the ctor for the given type MethodDesc CreatingMethod, - /// Attributes for the type, pulled from the creators type arguments + /// Generic parameters of the creator used as type arguments for the type IReadOnlyList? OriginalAttributes); private readonly TypeCacheHashtable _typeCacheHashtable; private readonly Logger _logger; - public CompilerGeneratedState(ILProvider ilProvider, Logger logger) + private readonly bool _disableGeneratedCodeHeuristics; + + public CompilerGeneratedState(ILProvider ilProvider, Logger logger, bool disableGeneratedCodeHeuristics) { _typeCacheHashtable = new TypeCacheHashtable(ilProvider); _logger = logger; + _disableGeneratedCodeHeuristics = disableGeneratedCodeHeuristics; } private sealed class TypeCacheHashtable : LockFreeReaderHashtable @@ -172,8 +175,8 @@ void ProcessMethod(MethodDesc method) // Find calls to state machine constructors that occur outside the type if (referencedMethod.IsConstructor && referencedMethod.OwningType is MetadataType generatedType && - // Don't consider calls in the same type, like inside a static constructor - method.OwningType != generatedType && + // Don't consider calls in the same/nested type, like inside a static constructor + !IsSameOrNestedType(method.OwningType, generatedType) && CompilerGeneratedNames.IsLambdaDisplayClass(generatedType.Name)) { Debug.Assert(generatedType.IsTypeDefinition); @@ -213,8 +216,8 @@ referencedMethod.OwningType is MetadataType generatedType && field = field.GetTypicalFieldDefinition(); if (field.OwningType is MetadataType generatedType && - // Don't consider field accesses in the same type, like inside a static constructor - method.OwningType != generatedType && + // Don't consider field accesses in the same/nested type, like inside a static constructor + !IsSameOrNestedType(method.OwningType, generatedType) && CompilerGeneratedNames.IsLambdaDisplayClass(generatedType.Name)) { Debug.Assert(generatedType.IsTypeDefinition); @@ -256,6 +259,22 @@ referencedMethod.OwningType is MetadataType generatedType && // Fill in null for argument providers now, the real providers will be filled in later generatedTypeToTypeArgs[stateMachineType] = new TypeArgumentInfo(method, null); } + + static bool IsSameOrNestedType(TypeDesc type, TypeDesc potentialOuterType) + { + do + { + if (type == potentialOuterType) + return true; + + if (type is not EcmaType ecmaType) + return false; + + type = ecmaType.ContainingType; + } while (type != null); + + return false; + } } // Look for state machine methods, and methods which call local functions. @@ -346,15 +365,15 @@ referencedMethod.OwningType is MetadataType generatedType && /// Attempts to reverse the process of the compiler's alpha renaming. So if the original code was /// something like this: /// - /// void M<T> () { - /// Action a = () => { Console.WriteLine (typeof (T)); }; + /// void M<T>() { + /// Action a = () => { Console.WriteLine(typeof(T)); }; /// } /// /// The compiler will generate a nested class like this: /// /// class <>c__DisplayClass0<T> { - /// public void <M>b__0 () { - /// Console.WriteLine (typeof (T)); + /// public void <M>b__0() { + /// Console.WriteLine(typeof(T)); /// } /// } /// @@ -659,6 +678,16 @@ public bool TryGetCompilerGeneratedCalleesForUserMethod(MethodDesc method, [NotN MetadataType generatedType = (MetadataType)type.GetTypeDefinition(); Debug.Assert(CompilerGeneratedNames.IsStateMachineOrDisplayClass(generatedType.Name)); + // Avoid the heuristics for .NET10+, where DynamicallyAccessedMembers flows to generated code + // because it is annotated with CompilerLoweringPreserveAttribute. + if (_disableGeneratedCodeHeuristics && + generatedType.Module.Assembly is EcmaAssembly asm && asm.GetTargetFrameworkVersion() >= new Version(10, 0)) + { + // Still run the logic for coverage to help us find bugs, but don't use the result. + GetCompilerGeneratedStateForType(generatedType); + return null; + } + var typeCache = GetCompilerGeneratedStateForType(generatedType); if (typeCache is null) return null; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/DiagnosticUtilities.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/DiagnosticUtilities.cs index 9f5bb5b0bd4a5f..cc3cde0f26112f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/DiagnosticUtilities.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/DiagnosticUtilities.cs @@ -101,7 +101,13 @@ internal static bool IsInRequiresScope(this MethodDesc method, string requiresAt return true; if (method.OwningType is TypeDesc type && TryGetRequiresAttribute(type, requiresAttribute, out attribute)) - return true; + { + if (!ExcludeStatics(attribute.Value)) + return true; + + if (!method.Signature.IsStatic) + return true; + } if (method.GetPropertyForAccessor() is PropertyPseudoDesc property && TryGetRequiresAttribute(property, requiresAttribute, out attribute)) return true; @@ -123,7 +129,13 @@ internal static bool DoesMethodRequire(this MethodDesc method, string requiresAt if ((method.Signature.IsStatic || method.IsConstructor) && method.OwningType is TypeDesc owningType && !owningType.IsArray && TryGetRequiresAttribute(owningType, requiresAttribute, out attribute)) - return true; + { + if (!ExcludeStatics(attribute.Value)) + return true; + + if (method.IsConstructor) + return true; + } if (method.GetPropertyForAccessor() is PropertyPseudoDesc @property && TryGetRequiresAttribute(@property, requiresAttribute, out attribute)) @@ -144,7 +156,7 @@ internal static bool DoesFieldRequire(this FieldDesc field, string requiresAttri return false; } - return TryGetRequiresAttribute(field.OwningType, requiresAttribute, out attribute); + return TryGetRequiresAttribute(field.OwningType, requiresAttribute, out attribute) && !ExcludeStatics(attribute.Value); } internal static bool DoesPropertyRequire(this PropertyPseudoDesc property, string requiresAttribute, [NotNullWhen(returnValue: true)] out CustomAttributeValue? attribute) => @@ -174,6 +186,20 @@ internal static bool DoesMemberRequire(this TypeSystemEntity member, string requ }; } + private static bool ExcludeStatics(CustomAttributeValue attribute) + { + foreach (var namedArgument in attribute.NamedArguments) + { + if (namedArgument.Name == "ExcludeStatics" && + namedArgument.Value is bool excludeStatics && + excludeStatics) + { + return true; + } + } + return false; + } + internal const string RequiresUnreferencedCodeAttribute = nameof(RequiresUnreferencedCodeAttribute); internal const string RequiresDynamicCodeAttribute = nameof(RequiresDynamicCodeAttribute); internal const string RequiresAssemblyFilesAttribute = nameof(RequiresAssemblyFilesAttribute); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs index 870a969c7e2b90..6f67e769dd3a1d 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs @@ -48,7 +48,7 @@ public HandleCallAction( _requireDynamicallyAccessedMembersAction = new(reflectionMarker, diagnosticContext, reason); } - private partial bool TryHandleIntrinsic ( + private partial bool TryHandleIntrinsic( MethodProxy calledMethod, MultiValue instanceValue, IReadOnlyList argumentValues, @@ -90,15 +90,24 @@ private partial bool TryHandleIntrinsic ( } } } - else if (typeInstantiated.Instantiation.IsConstrainedToBeReferenceTypes()) - { - // This will always succeed thanks to the runtime type loader - } else { - triggersWarning = true; - } + if (typeInstantiated.Instantiation.IsConstrainedToBeReferenceTypes()) + { + // This will always succeed thanks to the runtime type loader + } + else + { + triggersWarning = true; + } + // This should technically be in the IsConstrainedToBeReferenceTypes branch above + // but we have trim warning suppressions in dotnet/runtime and elsewhere that rely on the implementation + // detail that reference type instantiations will work, even if the generic is not + // constrained to be a reference type. + // MarkType will try to come up with a reference type type loader template. + _reflectionMarker.MarkType(_diagnosticContext.Origin, typeInstantiated, "MakeGenericType"); + } } else if (value == NullValue.Instance) { @@ -221,7 +230,7 @@ private partial bool TryHandleIntrinsic ( // // System.Array // - // CreateInstance (Type, Int32) + // CreateInstance(Type, Int32) // case IntrinsicId.Array_CreateInstance: { @@ -234,7 +243,7 @@ private partial bool TryHandleIntrinsic ( // // System.Enum // - // static GetValues (Type) + // static GetValues(Type) // case IntrinsicId.Enum_GetValues: { @@ -243,7 +252,7 @@ private partial bool TryHandleIntrinsic ( // type instead). // // At least until we have shared enum code, this needs extra handling to get it right. - foreach (var value in argumentValues[0].AsEnumerable ()) + foreach (var value in argumentValues[0].AsEnumerable()) { if (value is SystemTypeValue systemTypeValue && !systemTypeValue.RepresentedType.Type.IsGenericDefinition @@ -263,10 +272,10 @@ private partial bool TryHandleIntrinsic ( // // System.Runtime.InteropServices.Marshal // - // static SizeOf (Type) - // static PtrToStructure (IntPtr, Type) - // static DestroyStructure (IntPtr, Type) - // static OffsetOf (Type, string) + // static SizeOf(Type) + // static PtrToStructure(IntPtr, Type) + // static DestroyStructure(IntPtr, Type) + // static OffsetOf(Type, string) // case IntrinsicId.Marshal_SizeOf: case IntrinsicId.Marshal_PtrToStructure: @@ -278,7 +287,7 @@ private partial bool TryHandleIntrinsic ( ? 0 : 1; // We need the data to do struct marshalling. - foreach (var value in argumentValues[paramIndex].AsEnumerable ()) + foreach (var value in argumentValues[paramIndex].AsEnumerable()) { if (value is SystemTypeValue systemTypeValue && !systemTypeValue.RepresentedType.Type.IsGenericDefinition @@ -304,12 +313,12 @@ private partial bool TryHandleIntrinsic ( // // System.Runtime.InteropServices.Marshal // - // static GetDelegateForFunctionPointer (IntPtr, Type) + // static GetDelegateForFunctionPointer(IntPtr, Type) // case IntrinsicId.Marshal_GetDelegateForFunctionPointer: { // We need the data to do delegate marshalling. - foreach (var value in argumentValues[1].AsEnumerable ()) + foreach (var value in argumentValues[1].AsEnumerable()) { if (value is SystemTypeValue systemTypeValue && !systemTypeValue.RepresentedType.Type.IsGenericDefinition @@ -329,11 +338,11 @@ private partial bool TryHandleIntrinsic ( // // System.Delegate // - // get_Method () + // get_Method() // // System.Reflection.RuntimeReflectionExtensions // - // GetMethodInfo (System.Delegate) + // GetMethodInfo(System.Delegate) // case IntrinsicId.RuntimeReflectionExtensions_GetMethodInfo: case IntrinsicId.Delegate_get_Method: @@ -373,12 +382,12 @@ private partial bool TryHandleIntrinsic ( // case IntrinsicId.Object_GetType: { - if (instanceValue.IsEmpty ()) { - AddReturnValue (MultiValueLattice.Top); + if (instanceValue.IsEmpty()) { + AddReturnValue(MultiValueLattice.Top); break; } - foreach (var valueNode in instanceValue.AsEnumerable ()) + foreach (var valueNode in instanceValue.AsEnumerable()) { // Note that valueNode can be statically typed in IL as some generic argument type. // For example: diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HoistedLocalKey.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HoistedLocalKey.cs index 76b3fd499086cb..908381d9a7600e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HoistedLocalKey.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HoistedLocalKey.cs @@ -29,7 +29,7 @@ public HoistedLocalKey(FieldDesc field) public override int GetHashCode() => Field.GetHashCode(); - public static bool operator ==(HoistedLocalKey left, HoistedLocalKey right) => left.Equals (right); + public static bool operator ==(HoistedLocalKey left, HoistedLocalKey right) => left.Equals(right); public static bool operator !=(HoistedLocalKey left, HoistedLocalKey right) => !(left == right); } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/InterproceduralState.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/InterproceduralState.cs index 7627312e81550a..71e3518a42bd81 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/InterproceduralState.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/InterproceduralState.cs @@ -67,8 +67,8 @@ public void TrackMethod(MethodIL methodBody) methodBody = GetInstantiatedMethodIL(methodBody); // Work around the fact that ValueSet is readonly - Debug.Assert (!MethodBodies.IsUnknown ()); - var methodsList = new List(MethodBodies.GetKnownValues ()); + Debug.Assert(!MethodBodies.IsUnknown()); + var methodsList = new List(MethodBodies.GetKnownValues()); methodsList.Add(new MethodBodyValue(methodBody)); // For state machine methods, also scan the state machine members. diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs index eef3878c24461b..777db4bcf561c5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs @@ -78,9 +78,9 @@ private static void PushUnknown(Stack stack) stack.Push(new StackSlot()); } - private void PushUnknownAndWarnAboutInvalidIL(Stack stack, MethodIL methodBody, int offset) + private void PushUnknownAndWarnAboutInvalidIL(Stack stack, MethodIL methodIL, int offset) { - WarnAboutInvalidILInMethod(methodBody, offset); + WarnAboutInvalidILInMethod(methodIL, offset); PushUnknown(stack); } @@ -160,14 +160,14 @@ private struct BasicBlockIterator private readonly HashSet _methodBranchTargets; private int _currentBlockIndex; private bool _foundEndOfPrevBlock; - private MethodIL _methodBody; + private MethodIL _methodIL; - public BasicBlockIterator(MethodIL methodBody) + public BasicBlockIterator(MethodIL methodIL) { - _methodBranchTargets = methodBody.ComputeBranchTargets(); + _methodBranchTargets = methodIL.ComputeBranchTargets(); _currentBlockIndex = -1; _foundEndOfPrevBlock = true; - _methodBody = methodBody; + _methodIL = methodIL; } public int CurrentBlockIndex @@ -186,7 +186,7 @@ public int MoveNext(int offset) _foundEndOfPrevBlock = false; } - var reader = new ILReader(_methodBody.GetILBytes(), offset); + var reader = new ILReader(_methodIL.GetILBytes(), offset); ILOpcode opcode = reader.ReadILOpcode(); if (opcode.IsControlFlowInstruction()) { @@ -207,7 +207,7 @@ private static void ValidateNoReferenceToReference(ValueBasicBlockPair?[] locals continue; MultiValue localValue = localVariable.Value.Value; - foreach (var val in localValue.AsEnumerable ()) + foreach (var val in localValue.AsEnumerable()) { if (val is LocalVariableReferenceValue localReference && localReference.ReferencedType.IsByRefOrPointer()) { @@ -306,8 +306,8 @@ public virtual void InterproceduralScan(MethodIL startingMethodBody) // Flow state through all methods encountered so far, as long as there // are changes discovered in the hoisted local state on entry to any method. - Debug.Assert (!oldInterproceduralState.MethodBodies.IsUnknown ()); - foreach (var methodBodyValue in oldInterproceduralState.MethodBodies.GetKnownValues ()) + Debug.Assert(!oldInterproceduralState.MethodBodies.IsUnknown()); + foreach (var methodBodyValue in oldInterproceduralState.MethodBodies.GetKnownValues()) Scan(methodBodyValue.MethodBody, ref interproceduralState); } @@ -319,14 +319,14 @@ public virtual void InterproceduralScan(MethodIL startingMethodBody) var calleeMethods = compilerGeneratedCallees.OfType(); // https://github.com/dotnet/linker/issues/2845 // Disabled asserts due to a bug - // Debug.Assert (interproceduralState.Count == 1 + calleeMethods.Count ()); + // Debug.Assert(interproceduralState.Count == 1 + calleeMethods.Count()); // foreach (var method in calleeMethods) - // Debug.Assert (interproceduralState.Any (kvp => kvp.Key.Method == method)); + // Debug.Assert(interproceduralState.Any(kvp => kvp.Key.Method == method)); } else { - Debug.Assert (!interproceduralState.MethodBodies.IsUnknown ()); - Debug.Assert(interproceduralState.MethodBodies.GetKnownValues ().Count() == 1); + Debug.Assert(!interproceduralState.MethodBodies.IsUnknown()); + Debug.Assert(interproceduralState.MethodBodies.GetKnownValues().Count() == 1); } #endif } @@ -341,23 +341,23 @@ private static void TrackNestedFunctionReference(MethodDesc referencedMethod, re interproceduralState.TrackMethod(method); } - protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interproceduralState) + protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interproceduralState) { - MethodDesc thisMethod = methodBody.OwningMethod; + MethodDesc thisMethod = methodIL.OwningMethod; - ValueBasicBlockPair?[] locals = new ValueBasicBlockPair?[methodBody.GetLocals().Length]; + ValueBasicBlockPair?[] locals = new ValueBasicBlockPair?[methodIL.GetLocals().Length]; Dictionary> knownStacks = new Dictionary>(); - Stack? currentStack = new Stack(methodBody.MaxStack); + Stack? currentStack = new Stack(methodIL.MaxStack); - ScanExceptionInformation(knownStacks, methodBody); + ScanExceptionInformation(knownStacks, methodIL); - BasicBlockIterator blockIterator = new BasicBlockIterator(methodBody); + BasicBlockIterator blockIterator = new BasicBlockIterator(methodIL); - ILReader reader = new ILReader(methodBody.GetILBytes()); + ILReader reader = new ILReader(methodIL.GetILBytes()); while (reader.HasNext) { - ValidateNoReferenceToReference(locals, methodBody, reader.Offset); + ValidateNoReferenceToReference(locals, methodIL, reader.Offset); int curBasicBlock = blockIterator.MoveNext(reader.Offset); if (knownStacks.TryGetValue(reader.Offset, out var knownStack)) @@ -373,7 +373,7 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp } } - currentStack ??= new Stack(methodBody.MaxStack); + currentStack ??= new Stack(methodIL.MaxStack); int offset = reader.Offset; ILOpcode opcode = reader.ReadILOpcode(); @@ -404,7 +404,7 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.shr: case ILOpcode.shr_un: case ILOpcode.ceq: - PopUnknown(currentStack, 2, methodBody, offset); + PopUnknown(currentStack, 2, methodIL, offset); PushUnknown(currentStack); reader.Skip(opcode); break; @@ -472,9 +472,9 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.ldftn: { - if (methodBody.GetObject(reader.ReadILToken()) is MethodDesc methodOperand) + if (methodIL.GetObject(reader.ReadILToken()) is MethodDesc methodOperand) { - HandleMethodTokenAccess(methodBody, offset, methodOperand); + HandleMethodTokenAccess(methodIL, offset, methodOperand); TrackNestedFunctionReference(methodOperand, ref interproceduralState); } @@ -508,7 +508,7 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.ldloc_s: case ILOpcode.ldloca: case ILOpcode.ldloca_s: - ScanLdloc(methodBody, opcode, opcode switch + ScanLdloc(methodIL, opcode, opcode switch { ILOpcode.ldloc => reader.ReadILUInt16(), ILOpcode.ldloca => reader.ReadILUInt16(), @@ -516,29 +516,29 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp ILOpcode.ldloca_s => reader.ReadILByte(), _ => opcode - ILOpcode.ldloc_0 }, currentStack, locals); - ValidateNoReferenceToReference(locals, methodBody, offset); + ValidateNoReferenceToReference(locals, methodIL, offset); break; case ILOpcode.ldstr: { - StackSlot slot = new StackSlot(new KnownStringValue((string)methodBody.GetObject(reader.ReadILToken()))); + StackSlot slot = new StackSlot(new KnownStringValue((string)methodIL.GetObject(reader.ReadILToken()))); currentStack.Push(slot); } break; case ILOpcode.ldtoken: - object obj = methodBody.GetObject(reader.ReadILToken()); - ScanLdtoken(methodBody, offset, obj, currentStack); + object obj = methodIL.GetObject(reader.ReadILToken()); + ScanLdtoken(methodIL, offset, obj, currentStack); break; case ILOpcode.ldvirtftn: { - if (methodBody.GetObject(reader.ReadILToken()) is MethodDesc methodOperand) + if (methodIL.GetObject(reader.ReadILToken()) is MethodDesc methodOperand) { - HandleMethodTokenAccess(methodBody, offset, methodOperand); + HandleMethodTokenAccess(methodIL, offset, methodOperand); } - PopUnknown(currentStack, 1, methodBody, offset); + PopUnknown(currentStack, 1, methodIL, offset); PushUnknown(currentStack); } break; @@ -592,17 +592,22 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.conv_r8: case ILOpcode.ldind_ref: case ILOpcode.ldobj: - case ILOpcode.mkrefany: case ILOpcode.unbox: case ILOpcode.unbox_any: - case ILOpcode.box: case ILOpcode.neg: case ILOpcode.not: - PopUnknown(currentStack, 1, methodBody, offset); + PopUnknown(currentStack, 1, methodIL, offset); PushUnknown(currentStack); reader.Skip(opcode); break; + case ILOpcode.box: + case ILOpcode.mkrefany: + HandleTypeTokenAccess(methodIL, offset, (TypeDesc)methodIL.GetObject(reader.ReadILToken())); + PopUnknown(currentStack, 1, methodIL, offset); + PushUnknown(currentStack); + break; + case ILOpcode.isinst: case ILOpcode.castclass: // We can consider a NOP because the value doesn't change. @@ -615,13 +620,14 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.ldsfld: case ILOpcode.ldflda: case ILOpcode.ldsflda: - ScanLdfld(methodBody, offset, opcode, (FieldDesc)methodBody.GetObject(reader.ReadILToken()), currentStack, ref interproceduralState); + ScanLdfld(methodIL, offset, opcode, (FieldDesc)methodIL.GetObject(reader.ReadILToken()), currentStack, ref interproceduralState); break; case ILOpcode.newarr: { - StackSlot count = PopUnknown(currentStack, 1, methodBody, offset); - var arrayElement = (TypeDesc)methodBody.GetObject(reader.ReadILToken()); + StackSlot count = PopUnknown(currentStack, 1, methodIL, offset); + var arrayElement = (TypeDesc)methodIL.GetObject(reader.ReadILToken()); + HandleTypeTokenAccess(methodIL, offset, arrayElement); currentStack.Push(new StackSlot(ArrayValue.Create(count.Value, arrayElement))); } break; @@ -635,7 +641,7 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.stelem_r8: case ILOpcode.stelem: case ILOpcode.stelem_ref: - ScanStelem(offset, currentStack, methodBody, curBasicBlock); + ScanStelem(offset, currentStack, methodIL, curBasicBlock); reader.Skip(opcode); break; @@ -652,23 +658,23 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.ldelem: case ILOpcode.ldelem_ref: case ILOpcode.ldelema: - ScanLdelem(opcode, offset, currentStack, methodBody, curBasicBlock); + ScanLdelem(opcode, offset, currentStack, methodIL, curBasicBlock); reader.Skip(opcode); break; case ILOpcode.cpblk: case ILOpcode.initblk: - PopUnknown(currentStack, 3, methodBody, offset); + PopUnknown(currentStack, 3, methodIL, offset); reader.Skip(opcode); break; case ILOpcode.stfld: case ILOpcode.stsfld: - ScanStfld(methodBody, offset, opcode, (FieldDesc)methodBody.GetObject(reader.ReadILToken()), currentStack, locals, ref interproceduralState); + ScanStfld(methodIL, offset, opcode, (FieldDesc)methodIL.GetObject(reader.ReadILToken()), currentStack, locals, ref interproceduralState); break; case ILOpcode.cpobj: - PopUnknown(currentStack, 2, methodBody, offset); + PopUnknown(currentStack, 2, methodIL, offset); reader.Skip(opcode); break; @@ -681,20 +687,20 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.stind_r8: case ILOpcode.stind_ref: case ILOpcode.stobj: - ScanIndirectStore(methodBody, offset, currentStack, locals, curBasicBlock, ref interproceduralState); - ValidateNoReferenceToReference(locals, methodBody, offset); + ScanIndirectStore(methodIL, offset, currentStack, locals, curBasicBlock, ref interproceduralState); + ValidateNoReferenceToReference(locals, methodIL, offset); reader.Skip(opcode); break; case ILOpcode.initobj: case ILOpcode.pop: - PopUnknown(currentStack, 1, methodBody, offset); + PopUnknown(currentStack, 1, methodIL, offset); reader.Skip(opcode); break; case ILOpcode.starg: case ILOpcode.starg_s: - ScanStarg(methodBody, offset, opcode == ILOpcode.starg ? reader.ReadILUInt16() : reader.ReadILByte(), currentStack); + ScanStarg(methodIL, offset, opcode == ILOpcode.starg ? reader.ReadILUInt16() : reader.ReadILByte(), currentStack); break; case ILOpcode.stloc: @@ -703,13 +709,13 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.stloc_1: case ILOpcode.stloc_2: case ILOpcode.stloc_3: - ScanStloc(methodBody, offset, opcode switch + ScanStloc(methodIL, offset, opcode switch { ILOpcode.stloc => reader.ReadILUInt16(), ILOpcode.stloc_s => reader.ReadILByte(), _ => opcode - ILOpcode.stloc_0, }, currentStack, locals, curBasicBlock); - ValidateNoReferenceToReference(locals, methodBody, offset); + ValidateNoReferenceToReference(locals, methodIL, offset); break; case ILOpcode.constrained: @@ -725,24 +731,24 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.brfalse_s: case ILOpcode.brtrue: case ILOpcode.brtrue_s: - PopUnknown(currentStack, 1, methodBody, offset); + PopUnknown(currentStack, 1, methodIL, offset); NewKnownStack(knownStacks, reader.ReadBranchDestination(opcode), currentStack); break; case ILOpcode.calli: { - var signature = (MethodSignature)methodBody.GetObject(reader.ReadILToken()); + var signature = (MethodSignature)methodIL.GetObject(reader.ReadILToken()); if (!signature.IsStatic) { - PopUnknown(currentStack, 1, methodBody, offset); + PopUnknown(currentStack, 1, methodIL, offset); } // Pop arguments if (signature.Length > 0) - PopUnknown(currentStack, signature.Length, methodBody, offset); + PopUnknown(currentStack, signature.Length, methodIL, offset); // Pop function pointer - PopUnknown(currentStack, 1, methodBody, offset); + PopUnknown(currentStack, 1, methodIL, offset); // Push return value if (!signature.ReturnType.IsVoid) @@ -754,10 +760,10 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.callvirt: case ILOpcode.newobj: { - MethodDesc methodOperand = (MethodDesc)methodBody.GetObject(reader.ReadILToken()); + MethodDesc methodOperand = (MethodDesc)methodIL.GetObject(reader.ReadILToken()); TrackNestedFunctionReference(methodOperand, ref interproceduralState); - HandleCall(methodBody, opcode, offset, methodOperand, currentStack, locals, ref interproceduralState, curBasicBlock); - ValidateNoReferenceToReference(locals, methodBody, offset); + HandleCall(methodIL, opcode, offset, methodOperand, currentStack, locals, ref interproceduralState, curBasicBlock); + ValidateNoReferenceToReference(locals, methodIL, offset); } break; @@ -775,7 +781,7 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.leave: case ILOpcode.leave_s: ClearStack(ref currentStack); - NewKnownStack(knownStacks, reader.ReadBranchDestination(opcode), new Stack(methodBody.MaxStack)); + NewKnownStack(knownStacks, reader.ReadBranchDestination(opcode), new Stack(methodIL.MaxStack)); break; case ILOpcode.endfilter: @@ -787,20 +793,20 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.ret: { - bool hasReturnValue = !methodBody.OwningMethod.Signature.ReturnType.IsVoid; + bool hasReturnValue = !methodIL.OwningMethod.Signature.ReturnType.IsVoid; if (currentStack.Count != (hasReturnValue ? 1 : 0)) { - WarnAboutInvalidILInMethod(methodBody, offset); + WarnAboutInvalidILInMethod(methodIL, offset); } if (hasReturnValue) { - StackSlot retStackSlot = PopUnknown(currentStack, 1, methodBody, offset); + StackSlot retStackSlot = PopUnknown(currentStack, 1, methodIL, offset); // If the return value is a reference, treat it as the value itself for now // We can handle ref return values better later - MultiValue retValue = DereferenceValue(methodBody, offset, retStackSlot.Value, locals, ref interproceduralState); - var methodReturnValue = GetReturnValue(methodBody); - HandleReturnValue(methodBody, offset, methodReturnValue, retValue); - ValidateNoReferenceToReference(locals, methodBody, offset); + MultiValue retValue = DereferenceValue(methodIL, offset, retStackSlot.Value, locals, ref interproceduralState); + var methodReturnValue = GetReturnValue(methodIL); + HandleReturnValue(methodIL, offset, methodReturnValue, retValue); + ValidateNoReferenceToReference(locals, methodIL, offset); } ClearStack(ref currentStack); break; @@ -808,7 +814,7 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.switch_: { - PopUnknown(currentStack, 1, methodBody, offset); + PopUnknown(currentStack, 1, methodIL, offset); uint count = reader.ReadILUInt32(); int jmpBase = reader.Offset + (int)(4 * count); @@ -839,7 +845,7 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp case ILOpcode.blt_s: case ILOpcode.blt_un: case ILOpcode.blt_un_s: - PopUnknown(currentStack, 2, methodBody, offset); + PopUnknown(currentStack, 2, methodIL, offset); NewKnownStack(knownStacks, reader.ReadBranchDestination(opcode), currentStack); break; default: @@ -849,9 +855,9 @@ protected virtual void Scan(MethodIL methodBody, ref InterproceduralState interp } } - private static void ScanExceptionInformation(Dictionary> knownStacks, MethodIL methodBody) + private static void ScanExceptionInformation(Dictionary> knownStacks, MethodIL methodIL) { - foreach (ILExceptionRegion exceptionClause in methodBody.GetExceptionRegions()) + foreach (ILExceptionRegion exceptionClause in methodIL.GetExceptionRegions()) { Stack catchStack = new Stack(1); catchStack.Push(new StackSlot()); @@ -890,24 +896,24 @@ private void ScanLdarg(ILOpcode opcode, int parameterIndex, Stack cur } private void ScanStarg( - MethodIL methodBody, + MethodIL methodIL, int offset, int index, Stack currentStack ) { - var valueToStore = PopUnknown(currentStack, 1, methodBody, offset); + var valueToStore = PopUnknown(currentStack, 1, methodIL, offset); ParameterIndex paramNum = (ParameterIndex)index; - ParameterProxy param = new(methodBody.OwningMethod, paramNum); + ParameterProxy param = new(methodIL.OwningMethod, paramNum); var targetValue = GetMethodParameterValue(param); if (targetValue is MethodParameterValue targetParameterValue) - HandleStoreParameter(methodBody, offset, targetParameterValue, valueToStore.Value, null); + HandleStoreParameter(methodIL, offset, targetParameterValue, valueToStore.Value, null); // If the targetValue is MethodThisValue do nothing - it should never happen really, and if it does, there's nothing we can track there } private static void ScanLdloc( - MethodIL methodBody, + MethodIL methodIL, ILOpcode operation, int index, Stack currentStack, @@ -919,7 +925,7 @@ private static void ScanLdloc( StackSlot newSlot; if (isByRef) { - newSlot = new StackSlot(new LocalVariableReferenceValue(index, methodBody.GetLocals()[index].Type)); + newSlot = new StackSlot(new LocalVariableReferenceValue(index, methodIL.GetLocals()[index].Type)); } else if (localValue.HasValue) newSlot = new StackSlot(localValue.Value.Value); @@ -928,7 +934,7 @@ private static void ScanLdloc( currentStack.Push(newSlot); } - private void ScanLdtoken(MethodIL methodBody, int offset, object operand, Stack currentStack) + private void ScanLdtoken(MethodIL methodIL, int offset, object operand, Stack currentStack) { if (operand is TypeDesc type) { @@ -965,14 +971,14 @@ private void ScanLdtoken(MethodIL methodBody, int offset, object operand, Stack< } } - HandleTypeTokenAccess(methodBody, offset, type); + HandleTypeTokenAccess(methodIL, offset, type); } else if (operand is MethodDesc method) { StackSlot slot = new StackSlot(new RuntimeMethodHandleValue(method)); currentStack.Push(slot); - HandleMethodTokenAccess(methodBody, offset, method); + HandleMethodTokenAccess(methodIL, offset, method); } else { @@ -980,34 +986,34 @@ private void ScanLdtoken(MethodIL methodBody, int offset, object operand, Stack< PushUnknown(currentStack); - HandleFieldTokenAccess(methodBody, offset, (FieldDesc)operand); + HandleFieldTokenAccess(methodIL, offset, (FieldDesc)operand); } } private void ScanStloc( - MethodIL methodBody, + MethodIL methodIL, int offset, int index, Stack currentStack, ValueBasicBlockPair?[] locals, int curBasicBlock) { - StackSlot valueToStore = PopUnknown(currentStack, 1, methodBody, offset); + StackSlot valueToStore = PopUnknown(currentStack, 1, methodIL, offset); StoreMethodLocalValue(locals, valueToStore.Value, index, curBasicBlock); } private void ScanIndirectStore( - MethodIL methodBody, + MethodIL methodIL, int offset, Stack currentStack, ValueBasicBlockPair?[] locals, int curBasicBlock, ref InterproceduralState ipState) { - StackSlot valueToStore = PopUnknown(currentStack, 1, methodBody, offset); - StackSlot destination = PopUnknown(currentStack, 1, methodBody, offset); + StackSlot valueToStore = PopUnknown(currentStack, 1, methodIL, offset); + StackSlot destination = PopUnknown(currentStack, 1, methodIL, offset); - StoreInReference(destination.Value, valueToStore.Value, methodBody, offset, locals, curBasicBlock, ref ipState, null); + StoreInReference(destination.Value, valueToStore.Value, methodIL, offset, locals, curBasicBlock, ref ipState, null); } /// @@ -1015,12 +1021,12 @@ private void ScanIndirectStore( /// /// A set of that a value is being stored into /// The value to store - /// The method body that contains the operation causing the store + /// The method body that contains the operation causing the store /// The instruction offset causing the store /// Throws if is not a valid target for an indirect store. - protected void StoreInReference(MultiValue target, MultiValue source, MethodIL method, int offset, ValueBasicBlockPair?[] locals, int curBasicBlock, ref InterproceduralState ipState, int? parameterIndex) + protected void StoreInReference(MultiValue target, MultiValue source, MethodIL methodIL, int offset, ValueBasicBlockPair?[] locals, int curBasicBlock, ref InterproceduralState ipState, int? parameterIndex) { - foreach (var value in target.AsEnumerable ()) + foreach (var value in target.AsEnumerable()) { switch (value) { @@ -1028,26 +1034,26 @@ protected void StoreInReference(MultiValue target, MultiValue source, MethodIL m StoreMethodLocalValue(locals, source, localReference.LocalIndex, curBasicBlock); break; case FieldReferenceValue fieldReference - when HandleGetField(method, offset, fieldReference.FieldDefinition).AsSingleValue() is FieldValue fieldValue: - HandleStoreField(method, offset, fieldValue, source, parameterIndex); + when HandleGetField(methodIL, offset, fieldReference.FieldDefinition).AsSingleValue() is FieldValue fieldValue: + HandleStoreField(methodIL, offset, fieldValue, source, parameterIndex); break; case ParameterReferenceValue parameterReference when GetMethodParameterValue(parameterReference.Parameter) is MethodParameterValue parameterValue: - HandleStoreParameter(method, offset, parameterValue, source, parameterIndex); + HandleStoreParameter(methodIL, offset, parameterValue, source, parameterIndex); break; case MethodReturnValue methodReturnValue: // Ref returns don't have special ReferenceValue values, so assume if the target here is a MethodReturnValue then it must be a ref return value - HandleReturnValue(method, offset, methodReturnValue, source); + HandleReturnValue(methodIL, offset, methodReturnValue, source); break; case FieldValue fieldValue: - HandleStoreField(method, offset, fieldValue, DereferenceValue(method, offset, source, locals, ref ipState), parameterIndex); + HandleStoreField(methodIL, offset, fieldValue, DereferenceValue(methodIL, offset, source, locals, ref ipState), parameterIndex); break; case IValueWithStaticType valueWithStaticType: if (valueWithStaticType.StaticType is not null && FlowAnnotations.IsTypeInterestingForDataflow(valueWithStaticType.StaticType.Value.Type)) throw new InvalidOperationException(MessageContainer.CreateErrorMessage( $"Unhandled StoreReference call. Unhandled attempt to store a value in {value} of type {value.GetType()}.", (int)DiagnosticId.LinkerUnexpectedError, - origin: new MessageOrigin(method, offset)).ToMSBuildString()); + origin: new MessageOrigin(methodIL, offset)).ToMSBuildString()); // This should only happen for pointer derefs, which can't point to interesting types break; default: @@ -1077,10 +1083,10 @@ when GetMethodParameterValue(parameterReference.Parameter) is MethodParameterVal /// need to track those. It makes the design a bit cleaner because hoisted locals are purely handled in here /// and don't leak over to the reflection handling code in any way. /// - protected abstract MultiValue HandleGetField(MethodIL methodBody, int offset, FieldDesc field); + protected abstract MultiValue HandleGetField(MethodIL methodIL, int offset, FieldDesc field); private void ScanLdfld( - MethodIL methodBody, + MethodIL methodIL, int offset, ILOpcode opcode, FieldDesc field, @@ -1088,7 +1094,7 @@ private void ScanLdfld( ref InterproceduralState interproceduralState) { if (opcode == ILOpcode.ldfld || opcode == ILOpcode.ldflda) - PopUnknown(currentStack, 1, methodBody, offset); + PopUnknown(currentStack, 1, methodIL, offset); bool isByRef = opcode == ILOpcode.ldflda || opcode == ILOpcode.ldsflda; @@ -1103,7 +1109,7 @@ private void ScanLdfld( } else { - value = HandleGetField(methodBody, offset, field); + value = HandleGetField(methodIL, offset, field); } currentStack.Push(new StackSlot(value)); } @@ -1121,7 +1127,7 @@ protected virtual void HandleReturnValue(MethodIL method, int offset, MethodRetu } private void ScanStfld( - MethodIL methodBody, + MethodIL methodIL, int offset, ILOpcode opcode, FieldDesc field, @@ -1129,9 +1135,9 @@ private void ScanStfld( ValueBasicBlockPair?[] locals, ref InterproceduralState interproceduralState) { - StackSlot valueToStoreSlot = PopUnknown(currentStack, 1, methodBody, offset); + StackSlot valueToStoreSlot = PopUnknown(currentStack, 1, methodIL, offset); if (opcode == ILOpcode.stfld) - PopUnknown(currentStack, 1, methodBody, offset); + PopUnknown(currentStack, 1, methodIL, offset); if (CompilerGeneratedState.IsHoistedLocal(field)) { @@ -1139,7 +1145,7 @@ private void ScanStfld( return; } - foreach (var value in HandleGetField(methodBody, offset, field).AsEnumerable ()) + foreach (var value in HandleGetField(methodIL, offset, field).AsEnumerable()) { // GetFieldValue may return different node types, in which case they can't be stored to. // At least not yet. @@ -1147,16 +1153,16 @@ private void ScanStfld( continue; // Incomplete handling of ref fields -- if we're storing a reference to a value, pretend it's just the value - MultiValue valueToStore = DereferenceValue(methodBody, offset, valueToStoreSlot.Value, locals, ref interproceduralState); + MultiValue valueToStore = DereferenceValue(methodIL, offset, valueToStoreSlot.Value, locals, ref interproceduralState); - HandleStoreField(methodBody, offset, fieldValue, valueToStore, null); + HandleStoreField(methodIL, offset, fieldValue, valueToStore, null); } } private ValueNodeList PopCallArguments( Stack currentStack, MethodDesc methodCalled, - MethodIL containingMethodBody, + MethodIL containingMethodIL, bool isNewObj, int ilOffset) { int countToPop = 0; @@ -1167,7 +1173,7 @@ private ValueNodeList PopCallArguments( ValueNodeList methodParams = new ValueNodeList(countToPop); for (int iParam = 0; iParam < countToPop; ++iParam) { - StackSlot slot = PopUnknown(currentStack, 1, containingMethodBody, ilOffset); + StackSlot slot = PopUnknown(currentStack, 1, containingMethodIL, ilOffset); methodParams.Add(slot.Value); } @@ -1180,14 +1186,14 @@ private ValueNodeList PopCallArguments( } internal MultiValue DereferenceValue( - MethodIL methodBody, + MethodIL methodIL, int offset, MultiValue maybeReferenceValue, ValueBasicBlockPair?[] locals, ref InterproceduralState interproceduralState) { MultiValue dereferencedValue = MultiValueLattice.Top; - foreach (var value in maybeReferenceValue.AsEnumerable ()) + foreach (var value in maybeReferenceValue.AsEnumerable()) { switch (value) { @@ -1196,7 +1202,7 @@ internal MultiValue DereferenceValue( dereferencedValue, CompilerGeneratedState.IsHoistedLocal(fieldReferenceValue.FieldDefinition) ? interproceduralState.GetHoistedLocal(new HoistedLocalKey(fieldReferenceValue.FieldDefinition)) - : HandleGetField(methodBody, offset, fieldReferenceValue.FieldDefinition)); + : HandleGetField(methodIL, offset, fieldReferenceValue.FieldDefinition)); break; case ParameterReferenceValue parameterReferenceValue: dereferencedValue = MultiValue.Union( @@ -1228,7 +1234,7 @@ internal MultiValue DereferenceValue( /// Assigns a MethodParameterValue to the location of each parameter passed by reference. (i.e. assigns the value to x when passing `ref x` as a parameter) /// protected void AssignRefAndOutParameters( - MethodIL callingMethodBody, + MethodIL callingMethodIL, MethodDesc calledMethod, ValueNodeList methodArguments, int offset, @@ -1241,27 +1247,27 @@ protected void AssignRefAndOutParameters( if (parameter.GetReferenceKind() is not (ReferenceKind.Ref or ReferenceKind.Out)) continue; var newByRefValue = _annotations.GetMethodParameterValue(parameter); - StoreInReference(methodArguments[(int)parameter.Index], newByRefValue, callingMethodBody, offset, locals, curBasicBlock, ref ipState, parameter.Index.Index); + StoreInReference(methodArguments[(int)parameter.Index], newByRefValue, callingMethodIL, offset, locals, curBasicBlock, ref ipState, parameter.Index.Index); } } /// /// Called when type is accessed directly by its token (so creating a RuntimeHandle) /// - protected abstract void HandleTypeTokenAccess(MethodIL methodBody, int offset, TypeDesc accessedType); + protected abstract void HandleTypeTokenAccess(MethodIL methodIL, int offset, TypeDesc accessedType); /// /// Called to handle access to a method by its token (so creating a RuntimeHandle) /// - protected abstract void HandleMethodTokenAccess(MethodIL methodBody, int offset, MethodDesc accessedMethod); + protected abstract void HandleMethodTokenAccess(MethodIL methodIL, int offset, MethodDesc accessedMethod); /// /// Called to handle access to a field by its token (so creating a RuntimeHandle) /// - protected abstract void HandleFieldTokenAccess(MethodIL methodBody, int offset, FieldDesc accessedField); + protected abstract void HandleFieldTokenAccess(MethodIL methodIL, int offset, FieldDesc accessedField); private void HandleCall( - MethodIL callingMethodBody, + MethodIL callingMethodIL, ILOpcode opcode, int offset, MethodDesc calledMethod, @@ -1272,7 +1278,7 @@ private void HandleCall( { bool isNewObj = opcode == ILOpcode.newobj; - ValueNodeList methodArguments = PopCallArguments(currentStack, calledMethod, callingMethodBody, isNewObj, offset); + ValueNodeList methodArguments = PopCallArguments(currentStack, calledMethod, callingMethodIL, isNewObj, offset); // Multi-dimensional array access is represented as a call to a special Get method on the array (runtime provided method) // We don't track multi-dimensional arrays in any way, so return unknown value. @@ -1284,9 +1290,9 @@ private void HandleCall( var dereferencedMethodParams = new List(); foreach (var argument in methodArguments) - dereferencedMethodParams.Add(DereferenceValue(callingMethodBody, offset, argument, locals, ref interproceduralState)); + dereferencedMethodParams.Add(DereferenceValue(callingMethodIL, offset, argument, locals, ref interproceduralState)); MultiValue methodReturnValue = HandleCall( - callingMethodBody, + callingMethodIL, calledMethod, opcode, offset, @@ -1295,11 +1301,11 @@ private void HandleCall( if (isNewObj || !calledMethod.Signature.ReturnType.IsVoid) currentStack.Push(new StackSlot(methodReturnValue)); - AssignRefAndOutParameters(callingMethodBody, calledMethod, methodArguments, offset, locals, curBasicBlock, ref interproceduralState); + AssignRefAndOutParameters(callingMethodIL, calledMethod, methodArguments, offset, locals, curBasicBlock, ref interproceduralState); foreach (var param in methodArguments) { - foreach (var v in param.AsEnumerable ()) + foreach (var v in param.AsEnumerable()) { if (v is ArrayValue arr) { @@ -1314,7 +1320,7 @@ private void HandleCall( } public abstract MultiValue HandleCall( - MethodIL callingMethodBody, + MethodIL callingMethodIL, MethodDesc calledMethod, ILOpcode operation, int offset, @@ -1337,14 +1343,14 @@ private static void MarkArrayValuesAsUnknown(ArrayValue arrValue, int curBasicBl private void ScanStelem( int offset, Stack currentStack, - MethodIL methodBody, + MethodIL methodIL, int curBasicBlock) { - StackSlot valueToStore = PopUnknown(currentStack, 1, methodBody, offset); - StackSlot indexToStoreAt = PopUnknown(currentStack, 1, methodBody, offset); - StackSlot arrayToStoreIn = PopUnknown(currentStack, 1, methodBody, offset); + StackSlot valueToStore = PopUnknown(currentStack, 1, methodIL, offset); + StackSlot indexToStoreAt = PopUnknown(currentStack, 1, methodIL, offset); + StackSlot arrayToStoreIn = PopUnknown(currentStack, 1, methodIL, offset); int? indexToStoreAtInt = indexToStoreAt.Value.AsConstInt(); - foreach (var array in arrayToStoreIn.Value.AsEnumerable ()) + foreach (var array in arrayToStoreIn.Value.AsEnumerable()) { if (array is ArrayValue arrValue) { @@ -1369,11 +1375,11 @@ private void ScanLdelem( ILOpcode opcode, int offset, Stack currentStack, - MethodIL methodBody, + MethodIL methodIL, int curBasicBlock) { - StackSlot indexToLoadFrom = PopUnknown(currentStack, 1, methodBody, offset); - StackSlot arrayToLoadFrom = PopUnknown(currentStack, 1, methodBody, offset); + StackSlot indexToLoadFrom = PopUnknown(currentStack, 1, methodIL, offset); + StackSlot arrayToLoadFrom = PopUnknown(currentStack, 1, methodIL, offset); bool isByRef = opcode == ILOpcode.ldelema; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs index 4738e0755bf08b..11655bc4ad7b17 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs @@ -60,6 +60,14 @@ public static bool RequiresReflectionMethodBodyScannerForAccess(FlowAnnotations field.DoesFieldRequire(DiagnosticUtilities.RequiresDynamicCodeAttribute, out _); } + public static bool RequiresReflectionMethodBodyScannerForAccess(FlowAnnotations flowAnnotations, TypeDesc type) + { + return GenericArgumentDataFlow.RequiresGenericArgumentDataFlow(flowAnnotations, type) || + type.DoesTypeRequire(DiagnosticUtilities.RequiresUnreferencedCodeAttribute, out _) || + type.DoesTypeRequire(DiagnosticUtilities.RequiresAssemblyFilesAttribute, out _) || + type.DoesTypeRequire(DiagnosticUtilities.RequiresDynamicCodeAttribute, out _); + } + internal static void CheckAndReportAllRequires(in DiagnosticContext diagnosticContext, TypeSystemEntity calledMember) { CheckAndReportRequires(diagnosticContext, calledMember, DiagnosticUtilities.RequiresUnreferencedCodeAttribute); @@ -101,26 +109,26 @@ private ReflectionMethodBodyScanner(NodeFactory factory, FlowAnnotations annotat TrimAnalysisPatterns = new TrimAnalysisPatternStore(MultiValueLattice, logger); } - public override void InterproceduralScan(MethodIL methodBody) + public override void InterproceduralScan(MethodIL methodIL) { - base.InterproceduralScan(methodBody); + base.InterproceduralScan(methodIL); // Replace the reflection marker with one which actually marks _reflectionMarker = new ReflectionMarker(_logger, _factory, _annotations, typeHierarchyDataFlowOrigin: null, enabled: true); TrimAnalysisPatterns.MarkAndProduceDiagnostics(_reflectionMarker); } - protected override void Scan(MethodIL methodBody, ref InterproceduralState interproceduralState) + protected override void Scan(MethodIL methodIL, ref InterproceduralState interproceduralState) { - _origin = new MessageOrigin(methodBody.OwningMethod); - base.Scan(methodBody, ref interproceduralState); + _origin = new MessageOrigin(methodIL.OwningMethod); + base.Scan(methodIL, ref interproceduralState); } - public static DependencyList ScanAndProcessReturnValue(NodeFactory factory, FlowAnnotations annotations, Logger logger, MethodIL methodBody, out List runtimeDependencies) + public static DependencyList ScanAndProcessReturnValue(NodeFactory factory, FlowAnnotations annotations, Logger logger, MethodIL methodIL, out List runtimeDependencies) { - var scanner = new ReflectionMethodBodyScanner(factory, annotations, logger, new MessageOrigin(methodBody.OwningMethod)); + var scanner = new ReflectionMethodBodyScanner(factory, annotations, logger, new MessageOrigin(methodIL.OwningMethod)); - scanner.InterproceduralScan(methodBody); + scanner.InterproceduralScan(methodIL); runtimeDependencies = scanner._reflectionMarker.RuntimeDeterminedDependencies; return scanner._reflectionMarker.Dependencies; @@ -213,9 +221,9 @@ private MethodParameterValue GetMethodParameterValue(ParameterProxy parameter, D /// either as a source or target. It is not called when just a reference to field is created, /// But if such reference is dereferenced then it will get called. /// - protected override MultiValue HandleGetField(MethodIL methodBody, int offset, FieldDesc field) + protected override MultiValue HandleGetField(MethodIL methodIL, int offset, FieldDesc field) { - _origin = _origin.WithInstructionOffset(methodBody, offset); + _origin = _origin.WithInstructionOffset(methodIL, offset); if (field.DoesFieldRequire(DiagnosticUtilities.RequiresUnreferencedCodeAttribute, out _) || field.DoesFieldRequire(DiagnosticUtilities.RequiresDynamicCodeAttribute, out _) || @@ -227,58 +235,58 @@ protected override MultiValue HandleGetField(MethodIL methodBody, int offset, Fi return _annotations.GetFieldValue(field); } - private void HandleStoreValueWithDynamicallyAccessedMembers(MethodIL methodBody, int offset, ValueWithDynamicallyAccessedMembers targetValue, MultiValue sourceValue, int? parameterIndex, string reason) + private void HandleStoreValueWithDynamicallyAccessedMembers(MethodIL methodIL, int offset, ValueWithDynamicallyAccessedMembers targetValue, MultiValue sourceValue, int? parameterIndex, string reason) { if (targetValue.DynamicallyAccessedMemberTypes != 0) { - _origin = _origin.WithInstructionOffset(methodBody, offset); + _origin = _origin.WithInstructionOffset(methodIL, offset); TrimAnalysisPatterns.Add(new TrimAnalysisAssignmentPattern(sourceValue, targetValue, _origin, parameterIndex, reason)); } } - protected override void HandleStoreField(MethodIL methodBody, int offset, FieldValue field, MultiValue valueToStore, int? parameterIndex) - => HandleStoreValueWithDynamicallyAccessedMembers(methodBody, offset, field, valueToStore, parameterIndex, field.Field.GetDisplayName()); + protected override void HandleStoreField(MethodIL methodIL, int offset, FieldValue field, MultiValue valueToStore, int? parameterIndex) + => HandleStoreValueWithDynamicallyAccessedMembers(methodIL, offset, field, valueToStore, parameterIndex, field.Field.GetDisplayName()); - protected override void HandleStoreParameter(MethodIL methodBody, int offset, MethodParameterValue parameter, MultiValue valueToStore, int? parameterIndex) - => HandleStoreValueWithDynamicallyAccessedMembers(methodBody, offset, parameter, valueToStore, parameterIndex, parameter.Parameter.Method.GetDisplayName()); + protected override void HandleStoreParameter(MethodIL methodIL, int offset, MethodParameterValue parameter, MultiValue valueToStore, int? parameterIndex) + => HandleStoreValueWithDynamicallyAccessedMembers(methodIL, offset, parameter, valueToStore, parameterIndex, parameter.Parameter.Method.GetDisplayName()); - protected override void HandleReturnValue(MethodIL methodBody, int offset, MethodReturnValue returnValue, MultiValue valueToStore) - => HandleStoreValueWithDynamicallyAccessedMembers(methodBody, offset, returnValue, valueToStore, null, returnValue.Method.GetDisplayName()); + protected override void HandleReturnValue(MethodIL methodIL, int offset, MethodReturnValue returnValue, MultiValue valueToStore) + => HandleStoreValueWithDynamicallyAccessedMembers(methodIL, offset, returnValue, valueToStore, null, returnValue.Method.GetDisplayName()); - protected override void HandleTypeTokenAccess(MethodIL methodBody, int offset, TypeDesc accessedType) + protected override void HandleTypeTokenAccess(MethodIL methodIL, int offset, TypeDesc accessedType) { // Note that ldtoken alone is technically a reflection access to the type // it doesn't lead to full reflection marking of the type // since we implement full dataflow for type values and accesses to them. - _origin = _origin.WithInstructionOffset(methodBody, offset); + _origin = _origin.WithInstructionOffset(methodIL, offset); // Only check for generic instantiations. ProcessGenericArgumentDataFlow(accessedType); } - protected override void HandleMethodTokenAccess(MethodIL methodBody, int offset, MethodDesc accessedMethod) + protected override void HandleMethodTokenAccess(MethodIL methodIL, int offset, MethodDesc accessedMethod) { - _origin = _origin.WithInstructionOffset(methodBody, offset); + _origin = _origin.WithInstructionOffset(methodIL, offset); TrimAnalysisPatterns.Add(new TrimAnalysisTokenAccessPattern(accessedMethod, _origin)); ProcessGenericArgumentDataFlow(accessedMethod); } - protected override void HandleFieldTokenAccess(MethodIL methodBody, int offset, FieldDesc accessedField) + protected override void HandleFieldTokenAccess(MethodIL methodIL, int offset, FieldDesc accessedField) { - _origin = _origin.WithInstructionOffset(methodBody, offset); + _origin = _origin.WithInstructionOffset(methodIL, offset); TrimAnalysisPatterns.Add(new TrimAnalysisTokenAccessPattern(accessedField, _origin)); ProcessGenericArgumentDataFlow(accessedField); } - public override MultiValue HandleCall(MethodIL callingMethodBody, MethodDesc calledMethod, ILOpcode operation, int offset, ValueNodeList methodParams) + public override MultiValue HandleCall(MethodIL callingMethodIL, MethodDesc calledMethod, ILOpcode operation, int offset, ValueNodeList methodParams) { - Debug.Assert(callingMethodBody.OwningMethod == _origin.MemberDefinition); + Debug.Assert(callingMethodIL.OwningMethod == _origin.MemberDefinition); - _origin = _origin.WithInstructionOffset(callingMethodBody, offset); + _origin = _origin.WithInstructionOffset(callingMethodIL, offset); MultiValue instanceValue; ImmutableArray arguments; @@ -294,7 +302,7 @@ public override MultiValue HandleCall(MethodIL callingMethodBody, MethodDesc cal } TrimAnalysisPatterns.Add(new TrimAnalysisMethodCallPattern( - callingMethodBody, + callingMethodIL, operation, offset, calledMethod, @@ -307,7 +315,7 @@ public override MultiValue HandleCall(MethodIL callingMethodBody, MethodDesc cal var diagnosticContext = new DiagnosticContext(_origin, diagnosticsEnabled: false, _logger); return HandleCall( - callingMethodBody, + callingMethodIL, calledMethod, operation, instanceValue, @@ -429,10 +437,10 @@ private static bool IsComInterop(MarshalAsDescriptor? marshalInfoProvider, TypeD private void ProcessGenericArgumentDataFlow(MethodDesc method) { - // We only need to validate static methods and then all generic methods - // Instance non-generic methods don't need validation because the creation of the instance - // is the place where the validation will happen. - if (!method.Signature.IsStatic && !method.HasInstantiation && !method.IsConstructor) + // We mostly need to validate static methods and generic methods + // Instance non-generic methods on reference types don't need validation + // because the creation of the instance is the place where the validation will happen. + if (!method.Signature.IsStatic && !method.HasInstantiation && !method.IsConstructor && !method.OwningType.IsValueType) return; if (GenericArgumentDataFlow.RequiresGenericArgumentDataFlow(_annotations, method)) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisAssignmentPattern.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisAssignmentPattern.cs index 2f44acb76c90b6..89cebd2e73586b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisAssignmentPattern.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisAssignmentPattern.cs @@ -55,9 +55,9 @@ public void MarkAndProduceDiagnostics(ReflectionMarker reflectionMarker, Logger logger.ShouldSuppressAnalysisWarningsForRequires(Origin.MemberDefinition, DiagnosticUtilities.RequiresAssemblyFilesAttribute), logger); - foreach (var sourceValue in Source.AsEnumerable ()) + foreach (var sourceValue in Source.AsEnumerable()) { - foreach (var targetValue in Target.AsEnumerable ()) + foreach (var targetValue in Target.AsEnumerable()) { if (targetValue is not ValueWithDynamicallyAccessedMembers targetWithDynamicallyAccessedMembers) throw new NotImplementedException(); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/AnalysisCharacteristicNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/AnalysisCharacteristicNode.cs new file mode 100644 index 00000000000000..1d667fd833d72c --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/AnalysisCharacteristicNode.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; + +using ILCompiler.DependencyAnalysisFramework; + +namespace ILCompiler.DependencyAnalysis +{ + public class AnalysisCharacteristicNode : DependencyNodeCore + { + public AnalysisCharacteristicNode(string characteristic) + => Characteristic = characteristic; + + public string Characteristic { get; } + + public override bool InterestingForDynamicDependencyAnalysis => false; + public override bool HasDynamicDependencies => false; + public override bool HasConditionalStaticDependencies => false; + public override bool StaticDependenciesAreComputed => true; + public override IEnumerable GetConditionalStaticDependencies(NodeFactory context) => null; + public override IEnumerable GetStaticDependencies(NodeFactory context) => null; + public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory context) => null; + protected override string GetName(NodeFactory context) => $"Analysis characteristic: {Characteristic}"; + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/AnalyzedExternalTypeMapNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/AnalyzedExternalTypeMapNode.cs index b62b3da716dc28..a0c397a6180afe 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/AnalyzedExternalTypeMapNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/AnalyzedExternalTypeMapNode.cs @@ -21,7 +21,7 @@ public Vertex CreateTypeMap(NodeFactory factory, NativeWriter writer, Section se foreach ((string key, TypeDesc type) in entries) { Vertex keyVertex = writer.GetStringConstant(key); - Vertex valueVertex = writer.GetUnsignedConstant(externalReferences.GetIndex(factory.MaximallyConstructableType(type))); + Vertex valueVertex = writer.GetUnsignedConstant(externalReferences.GetIndex(factory.MetadataTypeSymbol(type))); Vertex entry = writer.GetTuple(keyVertex, valueVertex); typeMapHashTable.Append((uint)TypeHashingAlgorithms.ComputeNameHashCode(key), section.Place(entry)); } @@ -37,7 +37,7 @@ public override IEnumerable GetStaticDependencies(NodeFacto { foreach (TypeDesc targetType in entries.Values) { - yield return new DependencyListEntry(context.MaximallyConstructableType(targetType), "Analyzed external type map entry target type"); + yield return new DependencyListEntry(context.MetadataTypeSymbol(targetType), "Analyzed external type map entry target type"); } } public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory context) => []; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/AnalyzedProxyTypeMapNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/AnalyzedProxyTypeMapNode.cs index 7d19848d23ebb0..1689bc15716e59 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/AnalyzedProxyTypeMapNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/AnalyzedProxyTypeMapNode.cs @@ -21,7 +21,7 @@ public Vertex CreateTypeMap(NodeFactory factory, NativeWriter writer, Section se foreach ((TypeDesc key, TypeDesc type) in entries) { Vertex keyVertex = writer.GetUnsignedConstant(externalReferences.GetIndex(factory.MaximallyConstructableType(key))); - Vertex valueVertex = writer.GetUnsignedConstant(externalReferences.GetIndex(factory.MaximallyConstructableType(type))); + Vertex valueVertex = writer.GetUnsignedConstant(externalReferences.GetIndex(factory.MetadataTypeSymbol(type))); Vertex entry = writer.GetTuple(keyVertex, valueVertex); typeMapHashTable.Append((uint)key.GetHashCode(), section.Place(entry)); } @@ -38,7 +38,7 @@ public override IEnumerable GetStaticDependencies(NodeFacto foreach (var (sourceType, proxyType) in entries) { yield return new DependencyListEntry(context.MaximallyConstructableType(sourceType), "Analyzed proxy type map entry source type"); - yield return new DependencyListEntry(context.MaximallyConstructableType(proxyType), "Analyzed proxy type map entry proxy type"); + yield return new DependencyListEntry(context.MetadataTypeSymbol(proxyType), "Analyzed proxy type map entry proxy type"); } } public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory context) => []; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ArrayOfFrozenObjectsNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ArrayOfFrozenObjectsNode.cs index 8f616d98265a41..cecf9bd572f17e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ArrayOfFrozenObjectsNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ArrayOfFrozenObjectsNode.cs @@ -32,6 +32,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo return new ObjectData(Array.Empty(), Array.Empty(), 1, Array.Empty()); var builder = new ObjectDataBuilder(factory, relocsOnly); + builder.RequireInitialAlignment(factory.Target.PointerSize); builder.AddSymbol(this); foreach (FrozenObjectNode node in factory.MetadataManager.GetFrozenObjects()) { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs deleted file mode 100644 index 4336a5bd88b720..00000000000000 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs +++ /dev/null @@ -1,97 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; - -using Internal.TypeSystem; -using Internal.Runtime; - -namespace ILCompiler.DependencyAnalysis -{ - /// - /// Canonical type instantiations are emitted, not because they are used directly by the user code, but because - /// they are used by the dynamic type loader when dynamically instantiating types at runtime. - /// The data that we emit on canonical type instantiations should just be the minimum that is needed by the template - /// type loader. - /// Similarly, the dependencies that we track for canonical type instantiations are minimal, and are just the ones used - /// by the dynamic type loader - /// - public sealed class CanonicalEETypeNode : EETypeNode - { - public CanonicalEETypeNode(NodeFactory factory, TypeDesc type) : base(factory, type) - { - Debug.Assert(!type.IsCanonicalDefinitionType(CanonicalFormKind.Any)); - Debug.Assert(type.IsCanonicalSubtype(CanonicalFormKind.Any)); - Debug.Assert(type == type.ConvertToCanonForm(CanonicalFormKind.Specific)); - Debug.Assert(!type.IsMdArray); - } - - public override bool StaticDependenciesAreComputed => true; - public override bool IsShareable => IsTypeNodeShareable(_type); - protected override bool EmitVirtualSlots => true; - public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => false; - - protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) - { - DependencyList dependencyList = base.ComputeNonRelocationBasedDependencies(factory); - - // Ensure that we track the necessary type symbol if we are working with a constructed type symbol. - // The emitter will ensure we don't emit both, but this allows us assert that we only generate - // relocs to nodes we emit. - dependencyList.Add(factory.NecessaryTypeSymbol(_type), "Necessary type symbol related to CanonicalEETypeNode"); - - DefType closestDefType = _type.GetClosestDefType(); - - dependencyList.Add(factory.VTable(closestDefType), "VTable"); - - // Track generic virtual methods that will get added to the GVM tables - if ((_virtualMethodAnalysisFlags & VirtualMethodAnalysisFlags.NeedsGvmEntries) != 0) - { - dependencyList.Add(new DependencyListEntry(factory.TypeGVMEntries(_type.GetTypeDefinition()), "Type with generic virtual methods")); - } - - return dependencyList; - } - - protected override ISymbolNode GetBaseTypeNode(NodeFactory factory) - { - return _type.BaseType != null ? factory.NecessaryTypeSymbol(_type.BaseType.NormalizeInstantiation()) : null; - } - - protected override FrozenRuntimeTypeNode GetFrozenRuntimeTypeNode(NodeFactory factory) => throw new NotSupportedException(); - - protected override ISymbolNode GetNonNullableValueTypeArrayElementTypeNode(NodeFactory factory) - { - return factory.ConstructedTypeSymbol(((ArrayType)_type).ElementType); - } - - protected override int GCDescSize - { - get - { - return GCDescEncoder.GetGCDescSize(_type); - } - } - - protected override void OutputGCDesc(ref ObjectDataBuilder builder) - { - GCDescEncoder.EncodeGCDesc(ref builder, _type); - } - - protected override void OutputInterfaceMap(NodeFactory factory, ref ObjectDataBuilder objData) - { - foreach (DefType intface in _type.RuntimeInterfaces) - { - // If the interface was optimized away, skip it - if (!factory.InterfaceUse(intface.GetTypeDefinition()).Marked) - continue; - - // Interface omitted for canonical instantiations (constructed at runtime for dynamic types from the native layout info) - objData.EmitZeroPointer(); - } - } - - public override int ClassCode => -1798018602; - } -} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs index 162d2b9c5a1dc1..20a0a0ebd5a3f7 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs @@ -22,17 +22,16 @@ public ConstructedEETypeNode(NodeFactory factory, TypeDesc type) : base(factory, protected override bool EmitVirtualSlots => true; + protected override bool IsReflectionVisible => true; + protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencyList = base.ComputeNonRelocationBasedDependencies(factory); - // Ensure that we track the necessary type symbol if we are working with a constructed type symbol. + // Ensure that we track the metadata type symbol if we are working with a constructed type symbol. // The emitter will ensure we don't emit both, but this allows us assert that we only generate // relocs to nodes we emit. - dependencyList.Add(factory.NecessaryTypeSymbol(_type), "NecessaryType for constructed type"); - - if (_type is MetadataType mdType) - ModuleUseBasedDependencyAlgorithm.AddDependenciesDueToModuleUse(ref dependencyList, factory, mdType.Module); + dependencyList.Add(factory.MetadataTypeSymbol(_type), "MetadataType for constructed type"); DefType closestDefType = _type.GetClosestDefType(); @@ -53,22 +52,23 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact dependencyList.Add(factory.VTable(closestDefType), "VTable"); - // Ask the metadata manager if we have any dependencies due to the presence of the EEType. - factory.MetadataManager.GetDependenciesDueToEETypePresence(ref dependencyList, factory, _type); - - factory.InteropStubManager.AddInterestingInteropConstructedTypeDependencies(ref dependencyList, factory, _type); + if (!_type.IsCanonicalSubtype(CanonicalFormKind.Any)) + { + factory.InteropStubManager.AddInterestingInteropConstructedTypeDependencies(ref dependencyList, factory, _type); + } return dependencyList; } protected override ISymbolNode GetBaseTypeNode(NodeFactory factory) { - return _type.BaseType != null ? factory.ConstructedTypeSymbol(_type.BaseType) : null; + return _type.BaseType != null ? factory.ConstructedTypeSymbol(_type.BaseType.NormalizeInstantiation()) : null; } protected override FrozenRuntimeTypeNode GetFrozenRuntimeTypeNode(NodeFactory factory) { - return factory.SerializedConstructedRuntimeTypeObject(_type); + Debug.Assert(!_type.IsCanonicalSubtype(CanonicalFormKind.Any)); + return factory.SerializedMetadataRuntimeTypeObject(_type); } protected override ISymbolNode GetNonNullableValueTypeArrayElementTypeNode(NodeFactory factory) @@ -79,7 +79,7 @@ protected override ISymbolNode GetNonNullableValueTypeArrayElementTypeNode(NodeF protected override IEETypeNode GetInterfaceTypeNode(NodeFactory factory, TypeDesc interfaceType) { // The interface type will be visible to reflection and should be considered constructed. - return factory.ConstructedTypeSymbol(interfaceType); + return factory.ConstructedTypeSymbol(interfaceType.NormalizeInstantiation()); } protected override int GCDescSize => GCDescEncoder.GetGCDescSize(_type); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CustomAttributeBasedDependencyAlgorithm.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CustomAttributeBasedDependencyAlgorithm.cs index 936f900bb0002a..a83ad7506418b8 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CustomAttributeBasedDependencyAlgorithm.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CustomAttributeBasedDependencyAlgorithm.cs @@ -10,6 +10,9 @@ using Internal.TypeSystem.Ecma; using DependencyList = ILCompiler.DependencyAnalysisFramework.DependencyNodeCore.DependencyList; +using DependencyListEntry = ILCompiler.DependencyAnalysisFramework.DependencyNodeCore.DependencyListEntry; +using CombinedDependencyList = System.Collections.Generic.List.CombinedDependencyListEntry>; +using CombinedDependencyListEntry = ILCompiler.DependencyAnalysisFramework.DependencyNodeCore.CombinedDependencyListEntry; using MethodAttributes = System.Reflection.MethodAttributes; namespace ILCompiler.DependencyAnalysis @@ -20,27 +23,35 @@ namespace ILCompiler.DependencyAnalysis /// internal static class CustomAttributeBasedDependencyAlgorithm { - public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaMethod method) + private static IMethodNode GetMetadataApiDependency(NodeFactory factory, string entityName, string propertyName) + => factory.MethodEntrypoint(factory.TypeSystemContext.SystemModule.GetType("Internal.Metadata.NativeFormat", entityName).GetMethod(propertyName, null)); + + private static IMethodNode GetMetadataApiDependency(NodeFactory factory, string entityName) + => GetMetadataApiDependency(factory, entityName, "get_CustomAttributes"); + + public static void AddDependenciesDueToCustomAttributes(ref CombinedDependencyList dependencies, NodeFactory factory, EcmaMethod method) { MetadataReader reader = method.MetadataReader; MethodDefinitionHandle methodHandle = method.Handle; MethodDefinition methodDef = reader.GetMethodDefinition(methodHandle); // Handle custom attributes on the method - AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, methodDef.GetCustomAttributes(), method); + AddDependenciesDueToCustomAttributes(ref dependencies, GetMetadataApiDependency(factory, "Method"), factory, method.Module, methodDef.GetCustomAttributes(), method); // Handle custom attributes on method parameters + object parameterCondition = GetMetadataApiDependency(factory, "Parameter"); foreach (ParameterHandle parameterHandle in methodDef.GetParameters()) { Parameter parameter = reader.GetParameter(parameterHandle); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes(), method); + AddDependenciesDueToCustomAttributes(ref dependencies, parameterCondition, factory, method.Module, parameter.GetCustomAttributes(), method); } // Handle custom attributes on generic method parameters + object genericParameterCondition = GetMetadataApiDependency(factory, "GenericParameter"); foreach (GenericParameterHandle genericParameterHandle in methodDef.GetGenericParameters()) { GenericParameter parameter = reader.GetGenericParameter(genericParameterHandle); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes(), method); + AddDependenciesDueToCustomAttributes(ref dependencies, genericParameterCondition, factory, method.Module, parameter.GetCustomAttributes(), method); } // We don't model properties and events as separate entities within the compiler, so ensuring @@ -50,6 +61,7 @@ public static void AddDependenciesDueToCustomAttributes(ref DependencyList depen // As a performance optimization, we look for associated events and properties only // if the method is SpecialName. This is required for CLS compliance and compilers we // care about emit accessors like this. + object propertyCondition = GetMetadataApiDependency(factory, "Property"); if ((methodDef.Attributes & MethodAttributes.SpecialName) != 0) { TypeDefinition declaringType = reader.GetTypeDefinition(methodDef.GetDeclaringType()); @@ -60,50 +72,52 @@ public static void AddDependenciesDueToCustomAttributes(ref DependencyList depen PropertyAccessors accessors = property.GetAccessors(); if (accessors.Getter == methodHandle || accessors.Setter == methodHandle) - AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, property.GetCustomAttributes(), new PropertyPseudoDesc((EcmaType)method.OwningType, propertyHandle)); + AddDependenciesDueToCustomAttributes(ref dependencies, propertyCondition, factory, method.Module, property.GetCustomAttributes(), new PropertyPseudoDesc((EcmaType)method.OwningType, propertyHandle)); } + object eventCondition = GetMetadataApiDependency(factory, "Event"); foreach (EventDefinitionHandle eventHandle in declaringType.GetEvents()) { EventDefinition @event = reader.GetEventDefinition(eventHandle); EventAccessors accessors = @event.GetAccessors(); if (accessors.Adder == methodHandle || accessors.Remover == methodHandle || accessors.Raiser == methodHandle) - AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, @event.GetCustomAttributes(), new EventPseudoDesc((EcmaType)method.OwningType, eventHandle)); + AddDependenciesDueToCustomAttributes(ref dependencies, eventCondition, factory, method.Module, @event.GetCustomAttributes(), new EventPseudoDesc((EcmaType)method.OwningType, eventHandle)); } } } - public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaType type) + public static void AddDependenciesDueToCustomAttributes(ref CombinedDependencyList dependencies, NodeFactory factory, EcmaType type) { MetadataReader reader = type.MetadataReader; TypeDefinition typeDef = reader.GetTypeDefinition(type.Handle); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, type.EcmaModule, typeDef.GetCustomAttributes(), type); + AddDependenciesDueToCustomAttributes(ref dependencies, GetMetadataApiDependency(factory, "TypeDefinition"), factory, type.EcmaModule, typeDef.GetCustomAttributes(), type); // Handle custom attributes on generic type parameters + object genericParameterCondition = GetMetadataApiDependency(factory, "GenericParameter"); foreach (GenericParameterHandle genericParameterHandle in typeDef.GetGenericParameters()) { GenericParameter parameter = reader.GetGenericParameter(genericParameterHandle); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, type.EcmaModule, parameter.GetCustomAttributes(), type); + AddDependenciesDueToCustomAttributes(ref dependencies, genericParameterCondition, factory, type.EcmaModule, parameter.GetCustomAttributes(), type); } } - public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaField field) + public static void AddDependenciesDueToCustomAttributes(ref CombinedDependencyList dependencies, NodeFactory factory, EcmaField field) { FieldDefinition fieldDef = field.MetadataReader.GetFieldDefinition(field.Handle); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, field.Module, fieldDef.GetCustomAttributes(), field); + AddDependenciesDueToCustomAttributes(ref dependencies, GetMetadataApiDependency(factory, "Field"), factory, field.Module, fieldDef.GetCustomAttributes(), field); } - public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaAssembly assembly) + public static void AddDependenciesDueToCustomAttributes(ref CombinedDependencyList dependencies, NodeFactory factory, EcmaAssembly assembly) { AssemblyDefinition asmDef = assembly.MetadataReader.GetAssemblyDefinition(); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, asmDef.GetCustomAttributes(), assembly); + AddDependenciesDueToCustomAttributes(ref dependencies, GetMetadataApiDependency(factory, "ScopeDefinition"), factory, assembly, asmDef.GetCustomAttributes(), assembly); ModuleDefinition moduleDef = assembly.MetadataReader.GetModuleDefinition(); - AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, moduleDef.GetCustomAttributes(), assembly); + AddDependenciesDueToCustomAttributes(ref dependencies, GetMetadataApiDependency(factory, "ScopeDefinition", "get_ModuleCustomAttributes"), factory, assembly, moduleDef.GetCustomAttributes(), assembly); } - private static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaModule module, CustomAttributeHandleCollection attributeHandles, TypeSystemEntity parent) + private static void AddDependenciesDueToCustomAttributes(ref CombinedDependencyList dependencies, object condition, NodeFactory factory, EcmaModule module, CustomAttributeHandleCollection attributeHandles, TypeSystemEntity parent) { MetadataReader reader = module.MetadataReader; var mdManager = (UsageBasedMetadataManager)factory.MetadataManager; @@ -118,9 +132,6 @@ private static void AddDependenciesDueToCustomAttributes(ref DependencyList depe { MethodDesc constructor = module.GetMethod(attribute.Constructor); - if (TypeMapManager.LookupTypeMapType(constructor.OwningType) != TypeMapManager.TypeMapAttributeKind.None) - continue; - if (!mdManager.GeneratesAttributeMetadata(constructor.OwningType)) continue; @@ -137,9 +148,14 @@ private static void AddDependenciesDueToCustomAttributes(ref DependencyList depe if (AddDependenciesFromCustomAttributeBlob(caDependencies, factory, constructor.OwningType, decodedValue)) { - dependencies ??= new DependencyList(); - dependencies.AddRange(caDependencies); - dependencies.Add(factory.CustomAttributeMetadata(new ReflectableCustomAttribute(module, caHandle)), "Attribute metadata"); + dependencies ??= new CombinedDependencyList(); + + foreach (DependencyListEntry caDependency in caDependencies) + { + dependencies.Add(new CombinedDependencyListEntry(caDependency.Node, condition, caDependency.Reason)); + } + + dependencies.Add(new CombinedDependencyListEntry(factory.CustomAttributeMetadata(new ReflectableCustomAttribute(module, caHandle)), condition, "Attribute metadata")); } } catch (TypeSystemException) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DataflowAnalyzedTypeDefinitionNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DataflowAnalyzedTypeDefinitionNode.cs index 2fb798452850f2..4b283cb22c3542 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DataflowAnalyzedTypeDefinitionNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DataflowAnalyzedTypeDefinitionNode.cs @@ -69,15 +69,6 @@ public override IEnumerable GetStaticDependencies(NodeFacto if (_typeDefinition.HasBaseType) { - if (_typeDefinition.BaseType.DoesTypeRequire(DiagnosticUtilities.RequiresUnreferencedCodeAttribute, out var requiresAttribute) && - !_typeDefinition.DoesTypeRequire(DiagnosticUtilities.RequiresUnreferencedCodeAttribute, out _)) - { - UsageBasedMetadataManager metadataManager = (UsageBasedMetadataManager)factory.MetadataManager; - string arg1 = MessageFormat.FormatRequiresAttributeMessageArg(DiagnosticUtilities.GetRequiresAttributeMessage(requiresAttribute.Value)); - string arg2 = MessageFormat.FormatRequiresAttributeUrlArg(DiagnosticUtilities.GetRequiresAttributeUrl(requiresAttribute.Value)); - metadataManager.Logger.LogWarning(new MessageOrigin(_typeDefinition), DiagnosticId.RequiresUnreferencedCodeOnBaseClass, _typeDefinition.GetDisplayName(), _typeDefinition.BaseType.GetDisplayName(), arg1, arg2); - } - GenericArgumentDataFlow.ProcessGenericArgumentDataFlow(ref dependencies, factory, new MessageOrigin(_typeDefinition), _typeDefinition.BaseType, _typeDefinition); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs index c3b7828e6beb93..cc3a9d6f120add 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs @@ -212,6 +212,30 @@ public override bool TryGetSlotForEntry(GenericLookupResult entry, out int slot) { slot = Array.IndexOf(_layout, entry); + + // If we're looking for a low type handle load level and it doesn't exist, check for a higher load level. + var necessaryLookup = entry as NecessaryTypeHandleGenericLookupResult; + var metadataLookup = entry as MetadataTypeHandleGenericLookupResult; + if (slot < 0 + && (necessaryLookup != null || metadataLookup != null)) + { + for (int i = 0; i < _layout.Length; i++) + { + if (_layout[i] is TypeHandleGenericLookupResult thOther + && (thOther.Type == necessaryLookup?.Type || thOther.Type == metadataLookup?.Type)) + { + slot = i; + return true; + } + if (_layout[i] is MetadataTypeHandleGenericLookupResult mdOther + && mdOther.Type == necessaryLookup?.Type) + { + slot = i; + return true; + } + } + } + // If this is a slot we should discard, respond false if (slot < 0 && Array.IndexOf(_discardedSlots, entry) >= 0) return false; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs index 4c066a175eaf91..d6ff866e7d0af5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs @@ -84,11 +84,8 @@ protected enum VirtualMethodAnalysisFlags public EETypeNode(NodeFactory factory, TypeDesc type) { - if (type.IsCanonicalDefinitionType(CanonicalFormKind.Any)) - Debug.Assert(this is CanonicalDefinitionEETypeNode); - else if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) - Debug.Assert((this is CanonicalEETypeNode) || (this is NecessaryCanonicalEETypeNode)); - + Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Any) || type == type.ConvertToCanonForm(CanonicalFormKind.Specific)); + Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Any) || !type.IsMdArray); // MDArray doesn't have type loader templates Debug.Assert(!type.IsGenericParameter); Debug.Assert(!type.IsRuntimeDeterminedSubtype); _type = type; @@ -203,11 +200,7 @@ protected bool MightHaveInterfaceDispatchMap(NodeFactory factory) public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) { - // If there is a constructed version of this node in the graph, emit that instead - if (ConstructedEETypeNode.CreationAllowed(_type)) - return factory.ConstructedTypeSymbol(_type).Marked; - - return false; + return factory.MetadataTypeSymbol(_type).Marked; } public virtual ISymbolNode NodeForLinkage(NodeFactory factory) @@ -229,6 +222,8 @@ protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory) protected virtual bool EmitVirtualSlots => false; + protected virtual bool IsReflectionVisible => false; + public override bool InterestingForDynamicDependencyAnalysis => (_virtualMethodAnalysisFlags & VirtualMethodAnalysisFlags.InterestingForDynamicDependencies) != 0; @@ -286,6 +281,9 @@ public override bool HasConditionalStaticDependencies if (_type.RuntimeInterfaces.Length > 0) return true; + if (IsReflectionVisible && _hasConditionalDependenciesFromMetadataManager) + return true; + if (!EmitVirtualSlots) return false; @@ -315,7 +313,7 @@ public override bool HasConditionalStaticDependencies currentType = currentType.BaseType; } - return _hasConditionalDependenciesFromMetadataManager; + return false; } } @@ -323,6 +321,23 @@ public override IEnumerable GetConditionalStaticDep { List result = new List(); + if (IsReflectionVisible) + { + factory.MetadataManager.GetConditionalDependenciesDueToEETypePresence(ref result, factory, _type, allocated: EmitVirtualSlots); + + if (!_type.IsCanonicalSubtype(CanonicalFormKind.Any)) + { + foreach (DefType iface in _type.RuntimeInterfaces) + { + var ifaceDefinition = (DefType)iface.GetTypeDefinition(); + result.Add(new CombinedDependencyListEntry( + GetInterfaceTypeNode(factory, iface), + factory.InterfaceUse(ifaceDefinition), + "Interface definition was visible")); + } + } + } + IEETypeNode maximallyConstructableType = factory.MaximallyConstructableType(_type); if (maximallyConstructableType != this) @@ -346,18 +361,6 @@ public override IEnumerable GetConditionalStaticDep "Information about static bases for type with template")); } - if (!_type.IsCanonicalSubtype(CanonicalFormKind.Any)) - { - foreach (DefType iface in _type.RuntimeInterfaces) - { - var ifaceDefinition = (DefType)iface.GetTypeDefinition(); - result.Add(new CombinedDependencyListEntry( - GetInterfaceTypeNode(factory, iface), - factory.InterfaceUse(ifaceDefinition), - "Interface definition was visible")); - } - } - if (!EmitVirtualSlots) return result; @@ -558,8 +561,6 @@ public override IEnumerable GetConditionalStaticDep } } - factory.MetadataManager.GetConditionalDependenciesDueToEETypePresence(ref result, factory, _type); - return result; } @@ -627,8 +628,6 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact // Generated type contains generic virtual methods that will get added to the GVM tables if ((_virtualMethodAnalysisFlags & VirtualMethodAnalysisFlags.NeedsGvmEntries) != 0) { - dependencies.Add(new DependencyListEntry(factory.TypeGVMEntries(_type.GetTypeDefinition()), "Type with generic virtual methods")); - TypeDesc canonicalType = _type.ConvertToCanonForm(CanonicalFormKind.Specific); if (canonicalType != _type) dependencies.Add(factory.ConstructedTypeSymbol(canonicalType), "Type with generic virtual methods"); @@ -758,7 +757,7 @@ private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData, boo { uint flags = EETypeBuilderHelpers.ComputeFlags(_type); - if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType) + if (_type.GetTypeDefinition() == factory.TypeSystemContext.ArrayOfTEnumeratorType) { // Generic array enumerators use special variance rules recognized by the runtime flags |= (uint)EETypeFlags.GenericVarianceFlag; @@ -823,11 +822,12 @@ protected virtual int BaseSize protected virtual ISymbolNode GetBaseTypeNode(NodeFactory factory) { - return _type.BaseType != null ? factory.NecessaryTypeSymbol(_type.BaseType) : null; + return _type.BaseType != null ? factory.NecessaryTypeSymbol(_type.BaseType.NormalizeInstantiation()) : null; } protected virtual FrozenRuntimeTypeNode GetFrozenRuntimeTypeNode(NodeFactory factory) { + Debug.Assert(!_type.IsCanonicalSubtype(CanonicalFormKind.Any)); return factory.SerializedNecessaryRuntimeTypeObject(_type); } @@ -1038,19 +1038,36 @@ private void OutputVirtualSlots(NodeFactory factory, ref ObjectDataBuilder objDa protected virtual IEETypeNode GetInterfaceTypeNode(NodeFactory factory, TypeDesc interfaceType) { - return factory.NecessaryTypeSymbol(interfaceType); + return factory.NecessaryTypeSymbol(interfaceType.NormalizeInstantiation()); } - protected virtual void OutputInterfaceMap(NodeFactory factory, ref ObjectDataBuilder objData) + private void OutputInterfaceMap(NodeFactory factory, ref ObjectDataBuilder objData) { - foreach (var itf in _type.RuntimeInterfaces) + if (_type.IsCanonicalSubtype(CanonicalFormKind.Any)) { - IEETypeNode interfaceTypeNode = GetInterfaceTypeNode(factory, itf); - - // Only emit interfaces that were not optimized away. - if (interfaceTypeNode.Marked) + // Canonical types (type loader templates) do not generate an interface list - we build + // one for the loaded type at runtime dynamically from template data. + foreach (DefType itf in _type.RuntimeInterfaces) { - objData.EmitPointerReloc(interfaceTypeNode); + // If the interface was optimized away, skip it + if (factory.InterfaceUse(itf.GetTypeDefinition()).Marked) + { + // Interface omitted for canonical instantiations (constructed at runtime for dynamic types from the native layout info) + objData.EmitZeroPointer(); + } + } + } + else + { + foreach (var itf in _type.RuntimeInterfaces) + { + IEETypeNode interfaceTypeNode = GetInterfaceTypeNode(factory, itf); + + // Only emit interfaces that were not optimized away. + if (interfaceTypeNode.Marked) + { + objData.EmitPointerReloc(interfaceTypeNode); + } } } } @@ -1117,8 +1134,8 @@ protected void OutputGenericInstantiationDetails(NodeFactory factory, ref Object { if (!_type.IsTypeDefinition) { - IEETypeNode typeDefNode = factory.MaximallyConstructableType(_type) == this ? - factory.ConstructedTypeSymbol(_type.GetTypeDefinition()) : factory.NecessaryTypeSymbol(_type.GetTypeDefinition()); + IEETypeNode typeDefNode = IsReflectionVisible ? + factory.MetadataTypeSymbol(_type.GetTypeDefinition()) : factory.NecessaryTypeSymbol(_type.GetTypeDefinition()); if (factory.Target.SupportsRelativePointers) objData.EmitReloc(typeDefNode, RelocType.IMAGE_REL_BASED_RELPTR32); else @@ -1126,7 +1143,7 @@ protected void OutputGenericInstantiationDetails(NodeFactory factory, ref Object ISymbolNode compositionNode; - if (this == factory.MaximallyConstructableType(_type) + if (IsReflectionVisible && factory.MetadataManager.IsTypeInstantiationReflectionVisible(_type)) { compositionNode = _type.Instantiation.Length > 1 @@ -1148,7 +1165,7 @@ protected void OutputGenericInstantiationDetails(NodeFactory factory, ref Object else { GenericVarianceDetails details; - if (_type == factory.ArrayOfTEnumeratorType) + if (_type == factory.TypeSystemContext.ArrayOfTEnumeratorType) { // Generic array enumerators use special variance rules recognized by the runtime details = new GenericVarianceDetails(new[] { GenericVariance.ArrayCovariant }); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternEETypeSymbolNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternEETypeSymbolNode.cs index 053642f6eff505..1292076f32bde7 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternEETypeSymbolNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternEETypeSymbolNode.cs @@ -9,7 +9,7 @@ namespace ILCompiler.DependencyAnalysis /// Represents a symbol that is defined externally but modelled as a type in the /// DependencyAnalysis infrastructure during compilation. /// - public sealed class ExternEETypeSymbolNode : ExternSymbolNode, IEETypeNode + public sealed class ExternEETypeSymbolNode : ExternDataSymbolNode, IEETypeNode { private TypeDesc _type; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternMethodSymbolNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternMethodSymbolNode.cs index 0abfc47f1bff82..d26a42b44192a2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternMethodSymbolNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternMethodSymbolNode.cs @@ -9,7 +9,7 @@ namespace ILCompiler.DependencyAnalysis /// Represents a symbol that is defined externally but modelled as a method /// in the DependencyAnalysis infrastructure during compilation /// - public sealed class ExternMethodSymbolNode : ExternSymbolNode, IMethodNode + public sealed class ExternMethodSymbolNode : ExternFunctionSymbolNode, IMethodNode { private MethodDesc _method; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternSymbolNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternSymbolNode.cs index 6685fde0831273..8c576421f74d90 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternSymbolNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternSymbolNode.cs @@ -11,13 +11,15 @@ namespace ILCompiler.DependencyAnalysis { /// /// Represents a symbol that is defined externally and statically linked to the output obj file. + /// When making a new node, do not derive from this class directly, derive from one of its subclasses + /// (ExternFunctionSymbolNode / ExternDataSymbolNode) instead. /// - public class ExternSymbolNode : SortableDependencyNode, ISortableSymbolNode + public abstract class ExternSymbolNode : SortableDependencyNode, ISortableSymbolNode { private readonly Utf8String _name; private readonly bool _isIndirection; - public ExternSymbolNode(Utf8String name, bool isIndirection = false) + protected ExternSymbolNode(Utf8String name, bool isIndirection = false) { _name = name; _isIndirection = isIndirection; @@ -29,6 +31,7 @@ public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { sb.Append(_name); } + public int Offset => 0; public virtual bool RepresentsIndirectionCell => _isIndirection; @@ -42,8 +45,6 @@ public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory factory) => null; #if !SUPPORT_JIT - public override int ClassCode => 1092559304; - public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) { return _name.CompareTo(((ExternSymbolNode)other)._name); @@ -56,11 +57,26 @@ public override string ToString() } } - public class AddressTakenExternSymbolNode : ExternSymbolNode + /// + /// Represents a function symbol that is defined externally and statically linked to the output obj file. + /// + public class ExternFunctionSymbolNode(Utf8String name, bool isIndirection = false) : ExternSymbolNode(name, isIndirection) { - public AddressTakenExternSymbolNode(Utf8String name) - : base(name) { } + public override int ClassCode => 1452455506; + } + public class AddressTakenExternFunctionSymbolNode(Utf8String name) : ExternFunctionSymbolNode(name) + { public override int ClassCode => -45645737; } + + /// + /// Represents a data symbol that is defined externally and statically linked to the output obj file. + /// + public class ExternDataSymbolNode(Utf8String name) : ExternSymbolNode(name) + { + public override int ClassCode => 1428609964; + + protected override string GetName(NodeFactory factory) => $"ExternDataSymbolNode {ToString()}"; + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternSymbolsImportedNodeProvider.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternSymbolsImportedNodeProvider.cs index b50d07c23b9e35..1a774c511071bd 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternSymbolsImportedNodeProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternSymbolsImportedNodeProvider.cs @@ -15,12 +15,12 @@ public override IEETypeNode ImportedEETypeNode(NodeFactory factory, TypeDesc typ public override ISortableSymbolNode ImportedGCStaticNode(NodeFactory factory, MetadataType type) { - return new ExternSymbolNode(GCStaticsNode.GetMangledName(type, factory.NameMangler)); + return new ExternDataSymbolNode(GCStaticsNode.GetMangledName(type, factory.NameMangler)); } public override ISortableSymbolNode ImportedNonGCStaticNode(NodeFactory factory, MetadataType type) { - return new ExternSymbolNode(NonGCStaticsNode.GetMangledName(type, factory.NameMangler)); + return new ExternDataSymbolNode(NonGCStaticsNode.GetMangledName(type, factory.NameMangler)); } public override ISortableSymbolNode ImportedMethodDictionaryNode(NodeFactory factory, MethodDesc method) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternalTypeMapNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternalTypeMapNode.cs index c17781ff8d3c47..2d23d46991f93f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternalTypeMapNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternalTypeMapNode.cs @@ -36,14 +36,29 @@ public override IEnumerable GetConditionalStaticDep foreach (var entry in _mapEntries) { var (targetType, trimmingTargetType) = entry.Value; - yield return new CombinedDependencyListEntry( - context.MaximallyConstructableType(targetType), - context.NecessaryTypeSymbol(trimmingTargetType), - "Type in external type map is cast target"); + if (trimmingTargetType is not null) + { + yield return new CombinedDependencyListEntry( + context.MetadataTypeSymbol(targetType), + context.NecessaryTypeSymbol(trimmingTargetType), + "Type in external type map is cast target"); + } } } - public override IEnumerable GetStaticDependencies(NodeFactory context) => []; + public override IEnumerable GetStaticDependencies(NodeFactory context) + { + foreach (var entry in _mapEntries) + { + var (targetType, trimmingTargetType) = entry.Value; + if (trimmingTargetType is null) + { + yield return new DependencyListEntry( + context.MetadataTypeSymbol(targetType), + "External type map entry target type"); + } + } + } public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory context) => Array.Empty(); protected override string GetName(NodeFactory context) => $"External type map: {TypeMapGroup}"; @@ -62,9 +77,10 @@ public int CompareToImpl(ISortableNode other, CompilerComparer comparer) { var (targetType, trimmingTargetType) = entry.Value; - if (factory.NecessaryTypeSymbol(trimmingTargetType).Marked) + if (trimmingTargetType is null + || factory.NecessaryTypeSymbol(trimmingTargetType).Marked) { - IEETypeNode targetNode = factory.MaximallyConstructableType(targetType); + IEETypeNode targetNode = factory.MetadataTypeSymbol(targetType); Debug.Assert(targetNode.Marked); yield return (entry.Key, targetNode); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs index 77fa28233c8268..68837a34384644 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs @@ -40,8 +40,6 @@ public override IEnumerable GetStaticDependencies(NodeFacto DependencyList dependencies = new DependencyList(); dependencies.Add(factory.TypeMetadata((MetadataType)_field.OwningType), "Owning type metadata"); - CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, ((EcmaField)_field)); - if (_field is EcmaField ecmaField) { DynamicDependencyAttributesOnEntityNode.AddDependenciesDueToDynamicDependencyAttribute(ref dependencies, factory, ecmaField); @@ -62,6 +60,14 @@ public override IEnumerable GetStaticDependencies(NodeFacto return dependencies; } + + public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) + { + var dependencies = new List(); + CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, (EcmaField)_field); + return dependencies; + } + protected override string GetName(NodeFactory factory) { return "Field metadata: " + _field.ToString(); @@ -75,9 +81,8 @@ protected override void OnMarked(NodeFactory factory) public override bool InterestingForDynamicDependencyAnalysis => false; public override bool HasDynamicDependencies => false; - public override bool HasConditionalStaticDependencies => false; + public override bool HasConditionalStaticDependencies => true; public override bool StaticDependenciesAreComputed => true; - public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) => null; public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory factory) => null; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenRuntimeTypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenRuntimeTypeNode.cs index df38758e7deeed..4ad226b7a99eb2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenRuntimeTypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenRuntimeTypeNode.cs @@ -12,13 +12,13 @@ namespace ILCompiler.DependencyAnalysis public sealed class FrozenRuntimeTypeNode : FrozenObjectNode { private readonly TypeDesc _type; - private readonly bool _constructed; + private readonly bool _withMetadata; - public FrozenRuntimeTypeNode(TypeDesc type, bool constructed) + public FrozenRuntimeTypeNode(TypeDesc type, bool withMetadata) { Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Any)); _type = type; - _constructed = constructed; + _withMetadata = withMetadata; } public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) @@ -30,8 +30,8 @@ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilde public override void EncodeContents(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly) { - IEETypeNode typeSymbol = _constructed - ? factory.ConstructedTypeSymbol(_type) + IEETypeNode typeSymbol = _withMetadata + ? factory.MetadataTypeSymbol(_type) : factory.NecessaryTypeSymbol(_type); dataBuilder.EmitPointerReloc(factory.ConstructedTypeSymbol(ObjectType)); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GVMDependenciesNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GVMDependenciesNode.cs index 7218bf0d7d9639..531cdefffd5b50 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GVMDependenciesNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GVMDependenciesNode.cs @@ -41,7 +41,14 @@ public GVMDependenciesNode(MethodDesc method) public override IEnumerable GetStaticDependencies(NodeFactory factory) { if (!_method.IsAbstract) + { yield return new DependencyListEntry(factory.GenericVirtualMethodImpl(_method), "Implementation of the generic virtual method"); + } + + if (!_method.OwningType.IsInterface) + { + yield return new DependencyListEntry(factory.TypeGVMEntries(_method.OwningType.GetTypeDefinition()), "Resolution metadata"); + } } public override IEnumerable GetConditionalStaticDependencies(NodeFactory context) => null; @@ -82,8 +89,6 @@ public override IEnumerable SearchDynamicDependenci // to walk the whole class hierarchy for the non matching nodes. if (entry is ConstructedEETypeNode constructedEETypeNode) entryAsEETypeNode = constructedEETypeNode; - else if (entry is CanonicalEETypeNode canonicalEETypeNode) - entryAsEETypeNode = canonicalEETypeNode; else continue; @@ -97,6 +102,8 @@ public override IEnumerable SearchDynamicDependenci potentialOverrideType.ConvertToCanonForm(CanonicalFormKind.Specific) != potentialOverrideType) continue; + bool foundImpl = false; + // If this is an interface gvm, look for types that implement the interface // and other instantantiations that have the same canonical form. // This ensure the various slot numbers remain equivalent across all types where there is an equivalence @@ -152,6 +159,8 @@ public override IEnumerable SearchDynamicDependenci TypeSystemEntity origin = (implementingMethodInstantiation.OwningType != potentialOverrideType) ? potentialOverrideType : null; factory.MetadataManager.NoteOverridingMethod(_method, implementingMethodInstantiation, origin); } + + foundImpl = true; } } } @@ -203,7 +212,20 @@ public override IEnumerable SearchDynamicDependenci factory.GenericVirtualMethodImpl(instantiatedTargetMethod), null, "DerivedMethodInstantiation")); factory.MetadataManager.NoteOverridingMethod(_method, instantiatedTargetMethod); + + foundImpl = true; + } + } + + if (foundImpl) + { + TypeDesc currentType = potentialOverrideType; + do + { + dynamicDependencies.Add(new CombinedDependencyListEntry(factory.TypeGVMEntries(currentType.GetTypeDefinition()), null, "Resolution metadata")); + currentType = currentType.BaseType; } + while (currentType != null); } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs index a87f87bdcb425f..53ef725e499951 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs @@ -38,7 +38,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo // Generic array enumerators use special variance rules recognized by the runtime // Runtime casting logic relies on all interface types implemented on arrays // to have the variant flag set. - if (_type == factory.ArrayOfTEnumeratorType || factory.TypeSystemContext.IsGenericArrayInterfaceType(_type)) + if (_type == factory.TypeSystemContext.ArrayOfTEnumeratorType || factory.TypeSystemContext.IsGenericArrayInterfaceType(_type)) flags |= (uint)EETypeFlags.GenericVarianceFlag; if (_type.IsByRefLike) @@ -69,7 +69,7 @@ public ReflectionInvisibleGenericDefinitionEETypeNode(NodeFactory factory, TypeD public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) { - return factory.ConstructedTypeSymbol(_type).Marked; + return factory.MetadataTypeSymbol(_type).Marked; } protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) @@ -93,7 +93,7 @@ public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) protected override FrozenRuntimeTypeNode GetFrozenRuntimeTypeNode(NodeFactory factory) { - return factory.SerializedConstructedRuntimeTypeObject(_type); + return factory.SerializedMetadataRuntimeTypeObject(_type); } protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler) + " reflection visible"; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericLookupResult.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericLookupResult.cs index 9f5be7ae142ce0..ea7849f02c3405 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericLookupResult.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericLookupResult.cs @@ -215,6 +215,113 @@ protected override bool EqualsImpl(GenericLookupResult obj) } } + /// + /// Generic lookup result that points to an MethodTable. + /// + public sealed class NecessaryTypeHandleGenericLookupResult : GenericLookupResult + { + private TypeDesc _type; + + protected override int ClassCode => -4882991; + + public NecessaryTypeHandleGenericLookupResult(TypeDesc type) + { + Debug.Assert(type.IsRuntimeDeterminedSubtype, "Concrete type in a generic dictionary?"); + _type = type; + } + + public override ISymbolNode GetTarget(NodeFactory factory, GenericLookupResultContext dictionary) + { + TypeDesc instantiatedType = _type.GetNonRuntimeDeterminedTypeFromRuntimeDeterminedSubtypeViaSubstitution(dictionary.TypeInstantiation, dictionary.MethodInstantiation); + + factory.TypeSystemContext.DetectGenericCycles(dictionary.Context, instantiatedType); + + return factory.NecessaryTypeSymbol(instantiatedType); + } + + public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) + { + sb.Append("NecessaryTypeHandle_"u8); + sb.Append(nameMangler.GetMangledTypeName(_type)); + } + + public TypeDesc Type => _type; + public override string ToString() => $"NecessaryTypeHandle: {_type}"; + + public override NativeLayoutVertexNode TemplateDictionaryNode(NodeFactory factory) + { + return factory.NativeLayout.TypeHandleDictionarySlot(_type); + } + + protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer) + { + return comparer.Compare(_type, ((NecessaryTypeHandleGenericLookupResult)other)._type); + } + + protected override int GetHashCodeImpl() + { + return _type.GetHashCode(); + } + + protected override bool EqualsImpl(GenericLookupResult obj) + { + return ((NecessaryTypeHandleGenericLookupResult)obj)._type == _type; + } + } + + /// + /// Generic lookup result that points to an MethodTable. + /// + public sealed class MetadataTypeHandleGenericLookupResult : GenericLookupResult + { + private TypeDesc _type; + + protected override int ClassCode => -4892308; + + public MetadataTypeHandleGenericLookupResult(TypeDesc type) + { + Debug.Assert(type.IsRuntimeDeterminedSubtype, "Concrete type in a generic dictionary?"); + _type = type; + } + + public override ISymbolNode GetTarget(NodeFactory factory, GenericLookupResultContext dictionary) + { + TypeDesc instantiatedType = _type.GetNonRuntimeDeterminedTypeFromRuntimeDeterminedSubtypeViaSubstitution(dictionary.TypeInstantiation, dictionary.MethodInstantiation); + + factory.TypeSystemContext.DetectGenericCycles(dictionary.Context, instantiatedType); + + return factory.MetadataTypeSymbol(instantiatedType); + } + + public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) + { + sb.Append("MetadataTypeHandle_"u8); + sb.Append(nameMangler.GetMangledTypeName(_type)); + } + + public TypeDesc Type => _type; + public override string ToString() => $"MetadataTypeHandle: {_type}"; + + public override NativeLayoutVertexNode TemplateDictionaryNode(NodeFactory factory) + { + return factory.NativeLayout.TypeHandleDictionarySlot(_type); + } + + protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer) + { + return comparer.Compare(_type, ((MetadataTypeHandleGenericLookupResult)other)._type); + } + + protected override int GetHashCodeImpl() + { + return _type.GetHashCode(); + } + + protected override bool EqualsImpl(GenericLookupResult obj) + { + return ((MetadataTypeHandleGenericLookupResult)obj)._type == _type; + } + } /// /// Generic lookup result that points to an MethodTable where if the type is Nullable<X> the MethodTable is X @@ -728,7 +835,7 @@ public ObjectAllocatorGenericLookupResult(TypeDesc type) public override ISymbolNode GetTarget(NodeFactory factory, GenericLookupResultContext dictionary) { TypeDesc instantiatedType = _type.GetNonRuntimeDeterminedTypeFromRuntimeDeterminedSubtypeViaSubstitution(dictionary.TypeInstantiation, dictionary.MethodInstantiation); - return factory.ExternSymbol(JitHelper.GetNewObjectHelperForType(instantiatedType)); + return factory.ExternFunctionSymbol(JitHelper.GetNewObjectHelperForType(instantiatedType)); } public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) @@ -848,30 +955,38 @@ public override ISymbolNode GetTarget(NodeFactory factory, GenericLookupResultCo TypeDesc instantiatedConstraintType = _constraintType.GetNonRuntimeDeterminedTypeFromRuntimeDeterminedSubtypeViaSubstitution(dictionary.TypeInstantiation, dictionary.MethodInstantiation); MethodDesc implMethod; + MethodDesc instantiatedConstrainedMethodDefinition = instantiatedConstrainedMethod.GetMethodDefinition(); + if (instantiatedConstrainedMethod.OwningType.IsInterface) { if (instantiatedConstrainedMethod.Signature.IsStatic) { - implMethod = instantiatedConstraintType.GetClosestDefType().ResolveVariantInterfaceMethodToStaticVirtualMethodOnType(instantiatedConstrainedMethod); - if (implMethod == null) - { - DefaultInterfaceMethodResolution resolution = - instantiatedConstraintType.GetClosestDefType().ResolveVariantInterfaceMethodToDefaultImplementationOnType(instantiatedConstrainedMethod, out implMethod); - if (resolution != DefaultInterfaceMethodResolution.DefaultImplementation) - { - // TODO: diamond/reabstraction - ThrowHelper.ThrowInvalidProgramException(); - } - } + implMethod = instantiatedConstraintType.GetClosestDefType().ResolveVariantInterfaceMethodToStaticVirtualMethodOnType(instantiatedConstrainedMethodDefinition); } else { - throw new NotImplementedException(); + implMethod = instantiatedConstraintType.GetClosestDefType().ResolveVariantInterfaceMethodToVirtualMethodOnType(instantiatedConstrainedMethodDefinition); + } + + if (implMethod == null) + { + DefaultInterfaceMethodResolution resolution = + instantiatedConstraintType.GetClosestDefType().ResolveVariantInterfaceMethodToDefaultImplementationOnType(instantiatedConstrainedMethodDefinition, out implMethod); + if (resolution != DefaultInterfaceMethodResolution.DefaultImplementation) + { + // TODO: diamond/reabstraction: https://github.com/dotnet/runtime/issues/72589 + ThrowHelper.ThrowInvalidProgramException(); + } } } else { - implMethod = instantiatedConstraintType.GetClosestDefType().FindVirtualFunctionTargetMethodOnObjectType(instantiatedConstrainedMethod); + implMethod = instantiatedConstraintType.GetClosestDefType().FindVirtualFunctionTargetMethodOnObjectType(instantiatedConstrainedMethodDefinition); + } + + if (instantiatedConstrainedMethod != instantiatedConstrainedMethodDefinition) + { + implMethod = implMethod.MakeInstantiatedMethod(instantiatedConstrainedMethod.Instantiation); } // AOT use of this generic lookup is restricted to finding methods on valuetypes (runtime usage of this slot in universal generics is more flexible) @@ -880,21 +995,10 @@ public override ISymbolNode GetTarget(NodeFactory factory, GenericLookupResultCo factory.MetadataManager.NoteOverridingMethod(_constrainedMethod, implMethod); // TODO-SIZE: this is address taken only in the delegate target case - if (implMethod.Signature.IsStatic) - { - if (implMethod.GetCanonMethodTarget(CanonicalFormKind.Specific).IsSharedByGenericInstantiations) - return factory.ExactCallableAddressTakenAddress(implMethod); - else - return factory.AddressTakenMethodEntrypoint(implMethod); - } - else if (implMethod.HasInstantiation) - { + if (implMethod.GetCanonMethodTarget(CanonicalFormKind.Specific).IsSharedByGenericInstantiations) return factory.ExactCallableAddressTakenAddress(implMethod); - } else - { - return factory.AddressTakenMethodEntrypoint(implMethod.GetCanonMethodTarget(CanonicalFormKind.Specific)); - } + return factory.AddressTakenMethodEntrypoint(implMethod); } public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericVirtualMethodTableNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericVirtualMethodTableNode.cs index 6a3affe4b74d8c..3df07d1581bca5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericVirtualMethodTableNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericVirtualMethodTableNode.cs @@ -54,7 +54,9 @@ public static void GetGenericVirtualMethodImplementationDependencies(ref Depende MethodDesc openImplementationMethod = implementationMethod.GetTypicalMethodDefinition(); factory.MetadataManager.GetNativeLayoutMetadataDependencies(ref dependencies, factory, openCallingMethod); + dependencies.Add(factory.NecessaryTypeSymbol(openCallingMethod.OwningType), "Owning type of GVM declaration"); factory.MetadataManager.GetNativeLayoutMetadataDependencies(ref dependencies, factory, openImplementationMethod); + dependencies.Add(factory.NecessaryTypeSymbol(openImplementationMethod.OwningType), "Owning type of GVM implementation"); } private void AddGenericVirtualMethodImplementation(MethodDesc callingMethod, MethodDesc implementationMethod) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/IObjectDumper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/IObjectDumper.cs index 0b30619bba9e08..9c3de2672d56b6 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/IObjectDumper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/IObjectDumper.cs @@ -8,5 +8,6 @@ namespace ILCompiler.DependencyAnalysis public interface IObjectDumper { void DumpObjectNode(NodeFactory factory, ObjectNode node, ObjectData objectData); + void ReportFoldedNode(NodeFactory factory, ObjectNode originalNode, ISymbolNode targetNode); } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MetadataEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MetadataEETypeNode.cs new file mode 100644 index 00000000000000..0cfd7e55a1b33c --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MetadataEETypeNode.cs @@ -0,0 +1,102 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; + +using Internal.Runtime; +using Internal.TypeSystem; + +namespace ILCompiler.DependencyAnalysis +{ + public sealed class MetadataEETypeNode : EETypeNode + { + public MetadataEETypeNode(NodeFactory factory, TypeDesc type) : base(factory, type) + { + Debug.Assert(!type.IsCanonicalDefinitionType(CanonicalFormKind.Any)); + } + + protected override bool IsReflectionVisible => true; + + protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler) + " with metadata"; + + public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) + { + // If there is a constructed version of this node in the graph, emit that instead + if (ConstructedEETypeNode.CreationAllowed(_type)) + return factory.ConstructedTypeSymbol(_type).Marked; + + return false; + } + + protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) + { + DependencyList dependencyList = base.ComputeNonRelocationBasedDependencies(factory); + + // Ensure that we track the necessary type symbol if we are working with a metadata type symbol. + // The emitter will ensure we don't emit both, but this allows us assert that we only generate + // relocs to nodes we emit. + dependencyList.Add(factory.NecessaryTypeSymbol(_type), "NecessaryType for metadata type"); + + if (_type is MetadataType mdType) + ModuleUseBasedDependencyAlgorithm.AddDependenciesDueToModuleUse(ref dependencyList, factory, mdType.Module); + + // Ask the metadata manager if we have any dependencies due to the presence of the EEType. + factory.MetadataManager.GetDependenciesDueToEETypePresence(ref dependencyList, factory, _type); + + // Reflection-visible valuetypes are considered constructed due to APIs like RuntimeHelpers.Box, + // or Enum.ToObject. + if (_type.IsValueType) + dependencyList.Add(factory.MaximallyConstructableType(_type), "Reflection visible valuetype"); + + // Delegates can be constructed through runtime magic APIs so consider constructed. + if (_type.IsDelegate) + dependencyList.Add(factory.MaximallyConstructableType(_type), "Reflection visible delegate"); + + // Arrays can be constructed through Array.CreateInstanceFromArrayType so consider constructed. + if (_type.IsArray) + dependencyList.Add(factory.MaximallyConstructableType(_type), "Reflection visible array"); + + // TODO-SIZE: We need to separate tracking the use of static and instance virtual methods + // Unconstructed MethodTables only need to track the static virtuals. + // For now, conservatively upgrade to constructed types when static virtuals are present + bool hasStaticVirtuals = false; + foreach (MetadataType intface in _type.RuntimeInterfaces) + { + foreach (MethodDesc intfaceMethod in intface.GetAllVirtualMethods()) + { + if (intfaceMethod.Signature.IsStatic) + { + hasStaticVirtuals = true; + break; + } + } + } + if (hasStaticVirtuals) + dependencyList.Add(factory.MaximallyConstructableType(_type), "Has static virtual methods"); + + return dependencyList; + } + + protected override ISymbolNode GetBaseTypeNode(NodeFactory factory) + { + return _type.BaseType != null ? factory.MetadataTypeSymbol(_type.BaseType.NormalizeInstantiation()) : null; + } + + protected override FrozenRuntimeTypeNode GetFrozenRuntimeTypeNode(NodeFactory factory) + { + return factory.SerializedMetadataRuntimeTypeObject(_type); + } + + protected override ISymbolNode GetNonNullableValueTypeArrayElementTypeNode(NodeFactory factory) + { + return factory.MetadataTypeSymbol(((ArrayType)_type).ElementType); + } + + protected override IEETypeNode GetInterfaceTypeNode(NodeFactory factory, TypeDesc interfaceType) + { + return factory.MetadataTypeSymbol(interfaceType); + } + + public override int ClassCode => 99298112; + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs index 8eaade82cc95f3..f145aa9504eaaa 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs @@ -40,12 +40,12 @@ public MethodMetadataNode(MethodDesc method, bool isMinimal) public override IEnumerable GetStaticDependencies(NodeFactory factory) { DependencyList dependencies = new DependencyList(); - dependencies.Add(factory.TypeMetadata((MetadataType)_method.OwningType), "Owning type metadata"); + + var owningType = (MetadataType)_method.OwningType; + dependencies.Add(factory.TypeMetadata(owningType), "Owning type metadata"); if (!_isMinimal) { - CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, _method); - foreach (var parameterHandle in _method.MetadataReader.GetMethodDefinition(_method.Handle).GetParameters()) { dependencies.Add(factory.MethodParameterMetadata(new ReflectableParameter(_method.Module, parameterHandle)), "Parameter is visible"); @@ -79,10 +79,24 @@ public override IEnumerable GetStaticDependencies(NodeFacto { GenericArgumentDataFlow.ProcessGenericArgumentDataFlow(ref dependencies, factory, new MessageOrigin(_method), parameterType, _method); } + + if (_method.HasCustomAttribute("System.Diagnostics", "StackTraceHiddenAttribute") + || owningType.HasCustomAttribute("System.Diagnostics", "StackTraceHiddenAttribute")) + { + dependencies.Add(factory.AnalysisCharacteristic("StackTraceHiddenMetadataPresent"), "Method is StackTraceHidden"); + } } return dependencies; } + + public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) + { + var dependencies = new List(); + CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, _method); + return dependencies; + } + protected override string GetName(NodeFactory factory) { return "Method metadata: " + _method.ToString(); @@ -96,9 +110,8 @@ protected override void OnMarked(NodeFactory factory) public override bool InterestingForDynamicDependencyAnalysis => false; public override bool HasDynamicDependencies => false; - public override bool HasConditionalStaticDependencies => false; + public override bool HasConditionalStaticDependencies => !_isMinimal; public override bool StaticDependenciesAreComputed => true; - public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) => null; public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory factory) => null; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ModuleMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ModuleMetadataNode.cs index ef1e8e9ab5b1ec..9e7aa3edba4db2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ModuleMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ModuleMetadataNode.cs @@ -46,8 +46,6 @@ public override IEnumerable GetStaticDependencies(NodeFacto EcmaAssembly ecmaAssembly = (EcmaAssembly)_module; - CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, ecmaAssembly); - foreach (EcmaModule satelliteModule in ((UsageBasedMetadataManager)factory.MetadataManager).GetSatelliteAssemblies(ecmaAssembly)) { dependencies.Add(factory.ModuleMetadata(satelliteModule), "Satellite assembly"); @@ -56,16 +54,22 @@ public override IEnumerable GetStaticDependencies(NodeFacto return dependencies; } + public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) + { + var dependencies = new List(); + CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, (EcmaAssembly)_module); + return dependencies; + } + protected override string GetName(NodeFactory factory) { - return "Reflectable module: " + ((IAssemblyDesc)_module).GetName().FullName; + return "Reflectable module: " + ((IAssemblyDesc)_module).GetName().Name; } public override bool InterestingForDynamicDependencyAnalysis => false; public override bool HasDynamicDependencies => false; - public override bool HasConditionalStaticDependencies => false; + public override bool HasConditionalStaticDependencies => true; public override bool StaticDependenciesAreComputed => true; - public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) => null; public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory factory) => null; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs index 60b9a82dd0f930..c57f8ad072c233 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs @@ -1414,7 +1414,6 @@ public NativeLayoutConstrainedMethodDictionarySlotNode(MethodDesc constrainedMet _directCall = directCall; Debug.Assert(_constrainedMethod.OwningType.IsInterface); Debug.Assert(!_constrainedMethod.HasInstantiation || !directCall); - Debug.Assert(_constrainedMethod.Signature.IsStatic); } protected sealed override string GetName(NodeFactory factory) => @@ -1428,10 +1427,12 @@ protected sealed override FixupSignatureKind SignatureKind { get { - if (_constrainedMethod.HasInstantiation) - return FixupSignatureKind.GenericStaticConstrainedMethod; - else - return FixupSignatureKind.NonGenericStaticConstrainedMethod; + return (_constrainedMethod.HasInstantiation, _constrainedMethod.Signature.IsStatic) switch + { + (true, _) => FixupSignatureKind.GenericConstrainedMethod, + (false, true) => FixupSignatureKind.NonGenericStaticConstrainedMethod, + (false, false) => FixupSignatureKind.NonGenericInstanceConstrainedMethod, + }; } } @@ -1477,13 +1478,13 @@ protected sealed override Vertex WriteSignatureVertex(NativeWriter writer, NodeF Vertex constraintType = factory.NativeLayout.TypeSignatureVertex(_constraintType).WriteVertex(factory); if (_constrainedMethod.HasInstantiation) { - Debug.Assert(SignatureKind is FixupSignatureKind.GenericStaticConstrainedMethod); + Debug.Assert(SignatureKind is FixupSignatureKind.GenericConstrainedMethod); Vertex constrainedMethodVertex = factory.NativeLayout.MethodEntry(_constrainedMethod).WriteVertex(factory); return writer.GetTuple(constraintType, constrainedMethodVertex); } else { - Debug.Assert(SignatureKind is FixupSignatureKind.NonGenericStaticConstrainedMethod); + Debug.Assert(SignatureKind is FixupSignatureKind.NonGenericStaticConstrainedMethod or FixupSignatureKind.NonGenericInstanceConstrainedMethod); Vertex methodType = factory.NativeLayout.TypeSignatureVertex(_constrainedMethod.OwningType).WriteVertex(factory); var canonConstrainedMethod = _constrainedMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); int interfaceSlot = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, canonConstrainedMethod, canonConstrainedMethod.OwningType); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NecessaryCanonicalEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NecessaryCanonicalEETypeNode.cs deleted file mode 100644 index 1746741ecdcc41..00000000000000 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NecessaryCanonicalEETypeNode.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; - -using Internal.TypeSystem; - -namespace ILCompiler.DependencyAnalysis -{ - /// - /// The node is used in ProjectX to represent a canonical type that does not have a vtable. - /// - public sealed class NecessaryCanonicalEETypeNode : EETypeNode - { - public NecessaryCanonicalEETypeNode(NodeFactory factory, TypeDesc type) : base(factory, type) - { - Debug.Assert(!type.IsCanonicalDefinitionType(CanonicalFormKind.Any)); - Debug.Assert(type.IsCanonicalSubtype(CanonicalFormKind.Any)); - Debug.Assert(type == type.ConvertToCanonForm(CanonicalFormKind.Specific)); - Debug.Assert(!type.IsMdArray); - } - - protected override void OutputInterfaceMap(NodeFactory factory, ref ObjectDataBuilder objData) - { - foreach (DefType intface in _type.RuntimeInterfaces) - { - // If the interface was optimized away, skip it - if (!factory.InterfaceUse(intface.GetTypeDefinition()).Marked) - continue; - - // Interface omitted for canonical instantiations (constructed at runtime for dynamic types from the native layout info) - objData.EmitZeroPointer(); - } - } - - protected override ISymbolNode GetBaseTypeNode(NodeFactory factory) - { - return _type.BaseType != null ? factory.NecessaryTypeSymbol(_type.BaseType.NormalizeInstantiation()) : null; - } - - protected override FrozenRuntimeTypeNode GetFrozenRuntimeTypeNode(NodeFactory factory) => throw new NotSupportedException(); - - public override int ClassCode => 1505000724; - } -} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.GenericLookups.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.GenericLookups.cs index 8bed90a325e214..8e6bbaef113d21 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.GenericLookups.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.GenericLookups.cs @@ -27,6 +27,16 @@ private void CreateNodeCaches() return new TypeHandleGenericLookupResult(type); }); + _necessaryTypeSymbols = new NodeCache(type => + { + return new NecessaryTypeHandleGenericLookupResult(type); + }); + + _metadataTypeSymbols = new NodeCache(type => + { + return new MetadataTypeHandleGenericLookupResult(type); + }); + _unwrapNullableSymbols = new NodeCache(type => { return new UnwrapNullableTypeHandleGenericLookupResult(type); @@ -95,6 +105,20 @@ public GenericLookupResult Type(TypeDesc type) return _typeSymbols.GetOrAdd(type); } + private NodeCache _necessaryTypeSymbols; + + public GenericLookupResult NecessaryType(TypeDesc type) + { + return _necessaryTypeSymbols.GetOrAdd(type); + } + + private NodeCache _metadataTypeSymbols; + + public GenericLookupResult MetadataType(TypeDesc type) + { + return _metadataTypeSymbols.GetOrAdd(type); + } + private NodeCache _unwrapNullableSymbols; public GenericLookupResult UnwrapNullableType(TypeDesc type) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs index a6add520521126..8afd930fb88383 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs @@ -46,7 +46,7 @@ public NodeFactory( { _target = context.Target; - InitialInterfaceDispatchStub = new AddressTakenExternSymbolNode("RhpInitialDynamicInterfaceDispatch"); + InitialInterfaceDispatchStub = new AddressTakenExternFunctionSymbolNode("RhpInitialDynamicInterfaceDispatch"); _context = context; _compilationModuleGroup = compilationModuleGroup; @@ -191,6 +191,8 @@ private void CreateNodeCaches() { _typeSymbols = new NecessaryTypeSymbolHashtable(this); + _metadataTypeSymbols = new MetadataTypeSymbolHashtable(this); + _constructedTypeSymbols = new ConstructedTypeSymbolHashtable(this); _importedTypeSymbols = new NodeCache((TypeDesc type) => @@ -263,13 +265,17 @@ private void CreateNodeCaches() return new FieldRvaDataNode(key); }); - _externSymbols = new NodeCache((string name) => + _externFunctionSymbols = new NodeCache((string name) => + { + return new ExternFunctionSymbolNode(name); + }); + _externIndirectFunctionSymbols = new NodeCache((string name) => { - return new ExternSymbolNode(name); + return new ExternFunctionSymbolNode(name, isIndirection: true); }); - _externIndirectSymbols = new NodeCache((string name) => + _externDataSymbols = new NodeCache((string name) => { - return new ExternSymbolNode(name, isIndirection: true); + return new ExternDataSymbolNode(name); }); _pInvokeModuleFixups = new NodeCache((PInvokeModuleData moduleData) => @@ -433,14 +439,14 @@ private void CreateNodeCaches() return new SerializedFrozenObjectNode(key.OwnerType, key.AllocationSiteId, key.SerializableObject); }); - _frozenConstructedRuntimeTypeNodes = new NodeCache(key => + _frozenMetadataRuntimeTypeNodes = new NodeCache(key => { - return new FrozenRuntimeTypeNode(key, constructed: true); + return new FrozenRuntimeTypeNode(key, withMetadata: true); }); _frozenNecessaryRuntimeTypeNodes = new NodeCache(key => { - return new FrozenRuntimeTypeNode(key, constructed: false); + return new FrozenRuntimeTypeNode(key, withMetadata: false); }); _interfaceDispatchCells = new NodeCache(callSiteCell => @@ -598,6 +604,11 @@ private void CreateNodeCaches() return new ProxyTypeMapRequestNode(type); }); + _analysisCharacteristics = new NodeCache(c => + { + return new AnalysisCharacteristicNode(c); + }); + NativeLayout = new NativeLayoutHelper(this); } @@ -624,10 +635,6 @@ private IEETypeNode CreateNecessaryTypeNode(TypeDesc type) { return new CanonicalDefinitionEETypeNode(this, type); } - else if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) - { - return new NecessaryCanonicalEETypeNode(this, type); - } else { return new EETypeNode(this, type); @@ -639,9 +646,9 @@ private IEETypeNode CreateNecessaryTypeNode(TypeDesc type) } } - private IEETypeNode CreateConstructedTypeNode(TypeDesc type) + private IEETypeNode CreateMetadataTypeNode(TypeDesc type) { - // Canonical definition types are *not* constructed types (call NecessaryTypeSymbol to get them) + // Canonical definition types are *not* metadata types (call NecessaryTypeSymbol to get them) Debug.Assert(!type.IsCanonicalDefinitionType(CanonicalFormKind.Any)); Debug.Assert(!_compilationModuleGroup.ShouldReferenceThroughImportTable(type)); @@ -651,13 +658,9 @@ private IEETypeNode CreateConstructedTypeNode(TypeDesc type) { return new ReflectionVisibleGenericDefinitionEETypeNode(this, type); } - else if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) - { - return new CanonicalEETypeNode(this, type); - } else { - return new ConstructedEETypeNode(this, type); + return new MetadataEETypeNode(this, type); } } else @@ -666,6 +669,23 @@ private IEETypeNode CreateConstructedTypeNode(TypeDesc type) } } + private IEETypeNode CreateConstructedTypeNode(TypeDesc type) + { + // Canonical definition types are *not* constructed types (call NecessaryTypeSymbol to get them) + Debug.Assert(!type.IsCanonicalDefinitionType(CanonicalFormKind.Any)); + Debug.Assert(!_compilationModuleGroup.ShouldReferenceThroughImportTable(type)); + Debug.Assert(!type.IsGenericDefinition); + + if (_compilationModuleGroup.ContainsType(type)) + { + return new ConstructedEETypeNode(this, type); + } + else + { + return new ExternEETypeSymbolNode(this, type); + } + } + protected abstract IMethodNode CreateMethodEntrypointNode(MethodDesc method); protected abstract IMethodNode CreateUnboxingStubNode(MethodDesc method); @@ -712,6 +732,31 @@ public IEETypeNode NecessaryTypeSymbol(TypeDesc type) return _typeSymbols.GetOrCreateValue(type); } + private sealed class MetadataTypeSymbolHashtable : TypeSymbolHashtable + { + public MetadataTypeSymbolHashtable(NodeFactory factory) : base(factory) { } + protected override IEETypeNode CreateValueFromKey(TypeDesc key) => _factory.CreateMetadataTypeNode(key); + } + + private MetadataTypeSymbolHashtable _metadataTypeSymbols; + + public IEETypeNode MetadataTypeSymbol(TypeDesc type) + { + if (_compilationModuleGroup.ShouldReferenceThroughImportTable(type)) + { + return ImportedEETypeSymbol(type); + } + + if (_compilationModuleGroup.ShouldPromoteToFullType(type)) + { + return ConstructedTypeSymbol(type); + } + + Debug.Assert(!TypeCannotHaveEEType(type)); + + return _metadataTypeSymbols.GetOrCreateValue(type); + } + private sealed class ConstructedTypeSymbolHashtable : TypeSymbolHashtable { public ConstructedTypeSymbolHashtable(NodeFactory factory) : base(factory) { } @@ -734,8 +779,10 @@ public IEETypeNode ConstructedTypeSymbol(TypeDesc type) public IEETypeNode MaximallyConstructableType(TypeDesc type) { - if (ConstructedEETypeNode.CreationAllowed(type) || type.IsGenericDefinition) + if (ConstructedEETypeNode.CreationAllowed(type)) return ConstructedTypeSymbol(type); + else if (type.IsGenericDefinition) + return MetadataTypeSymbol(type); else return NecessaryTypeSymbol(type); } @@ -793,7 +840,7 @@ public ISortableSymbolNode TypeThreadStaticIndex(MetadataType type) } else { - return ExternSymbol(NameMangler.NodeMangler.ThreadStaticsIndex(type)); + return ExternDataSymbol(NameMangler.NodeMangler.ThreadStaticsIndex(type)); } } @@ -903,24 +950,31 @@ internal ISymbolNode GenericVariance(GenericVarianceDetails details) return _genericVariances.GetOrAdd(details); } - private NodeCache _externSymbols; + private NodeCache _externFunctionSymbols; - public ISortableSymbolNode ExternSymbol(string name) + public ISortableSymbolNode ExternFunctionSymbol(string name) { - return _externSymbols.GetOrAdd(name); + return _externFunctionSymbols.GetOrAdd(name); } - public ISortableSymbolNode ExternVariable(string name) + private NodeCache _externIndirectFunctionSymbols; + + public ISortableSymbolNode ExternIndirectFunctionSymbol(string name) { - string mangledName = NameMangler.NodeMangler.ExternVariable(name); - return _externSymbols.GetOrAdd(mangledName); + return _externIndirectFunctionSymbols.GetOrAdd(name); } - private NodeCache _externIndirectSymbols; + private NodeCache _externDataSymbols; - public ISortableSymbolNode ExternIndirectSymbol(string name) + public ISortableSymbolNode ExternDataSymbol(string name) { - return _externIndirectSymbols.GetOrAdd(name); + return _externDataSymbols.GetOrAdd(name); + } + + public ISortableSymbolNode ExternVariable(string name) + { + string mangledName = NameMangler.NodeMangler.ExternVariable(name); + return _externDataSymbols.GetOrAdd(mangledName); } private NodeCache _pInvokeModuleFixups; @@ -1059,7 +1113,7 @@ public IMethodNode FatFunctionPointer(MethodDesc method, bool isUnboxingStub = f public IMethodNode FatAddressTakenFunctionPointer(MethodDesc method, bool isUnboxingStub = false) { - if (ObjectInterner.IsNull) + if (!ObjectInterner.CanFold(method)) return FatFunctionPointer(method, isUnboxingStub); return _fatAddressTakenFunctionPointers.GetOrAdd(new MethodKey(method, isUnboxingStub)); @@ -1125,7 +1179,7 @@ internal TypeGVMEntriesNode TypeGVMEntries(TypeDesc type) private NodeCache _addressTakenMethods; public IMethodNode AddressTakenMethodEntrypoint(MethodDesc method, bool unboxingStub = false) { - if (unboxingStub || ObjectInterner.IsNull) + if (unboxingStub || !ObjectInterner.CanFold(method)) return MethodEntrypoint(method, unboxingStub); return _addressTakenMethods.GetOrAdd(method); @@ -1257,17 +1311,6 @@ public MetadataType ArrayOfTClass } } - private TypeDesc _systemArrayOfTEnumeratorType; - public TypeDesc ArrayOfTEnumeratorType - { - get - { - // This type is optional, but it's fine for this cache to be ineffective if that happens. - // Those scenarios are rare and typically deal with small compilations. - return _systemArrayOfTEnumeratorType ??= _context.SystemModule.GetType("System", "SZGenericArrayEnumerator`1", throwIfNotFound: false); - } - } - private MethodDesc _instanceMethodRemovedHelper; public MethodDesc InstanceMethodRemovedHelper { @@ -1428,18 +1471,11 @@ public SerializedFrozenObjectNode SerializedFrozenObject(MetadataType owningType return _frozenObjectNodes.GetOrAdd(new SerializedFrozenObjectKey(owningType, allocationSiteId, data)); } - public FrozenRuntimeTypeNode SerializedMaximallyConstructableRuntimeTypeObject(TypeDesc type) - { - if (ConstructedEETypeNode.CreationAllowed(type) || type.IsGenericDefinition) - return SerializedConstructedRuntimeTypeObject(type); - return SerializedNecessaryRuntimeTypeObject(type); - } - - private NodeCache _frozenConstructedRuntimeTypeNodes; + private NodeCache _frozenMetadataRuntimeTypeNodes; - public FrozenRuntimeTypeNode SerializedConstructedRuntimeTypeObject(TypeDesc type) + public FrozenRuntimeTypeNode SerializedMetadataRuntimeTypeObject(TypeDesc type) { - return _frozenConstructedRuntimeTypeNodes.GetOrAdd(type); + return _frozenMetadataRuntimeTypeNodes.GetOrAdd(type); } private NodeCache _frozenNecessaryRuntimeTypeNodes; @@ -1495,6 +1531,12 @@ public ProxyTypeMapRequestNode ProxyTypeMapRequest(TypeDesc type) return _proxyTypeMapRequests.GetOrAdd(type); } + private NodeCache _analysisCharacteristics; + public AnalysisCharacteristicNode AnalysisCharacteristic(string ch) + { + return _analysisCharacteristics.GetOrAdd(ch); + } + /// /// Returns alternative symbol name that object writer should produce for given symbols /// in addition to the regular one. diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ProxyTypeMapNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ProxyTypeMapNode.cs index a131677a776be6..39ed1b885cff61 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ProxyTypeMapNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ProxyTypeMapNode.cs @@ -43,7 +43,7 @@ public override IEnumerable GetConditionalStaticDep foreach (var (key, value) in _mapEntries) { yield return new CombinedDependencyListEntry( - context.MaximallyConstructableType(value), + context.MetadataTypeSymbol(value), context.MaximallyConstructableType(key), "Proxy type map entry"); } @@ -60,7 +60,7 @@ public override IEnumerable GetConditionalStaticDep IEETypeNode keyNode = factory.MaximallyConstructableType(key); if (keyNode.Marked) { - IEETypeNode valueNode = factory.MaximallyConstructableType(value); + IEETypeNode valueNode = factory.MetadataTypeSymbol(value); Debug.Assert(valueNode.Marked); yield return (keyNode, valueNode); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs index a9b7e142b3b3c4..6bc7560b5d5371 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs @@ -51,13 +51,14 @@ public ReadyToRunGenericHelperNode(NodeFactory factory, ReadyToRunHelperId helpe public static GenericLookupResult GetLookupSignature(NodeFactory factory, ReadyToRunHelperId id, object target) { - // Necessary type handle is not something you can put in a dictionary - someone should have normalized to TypeHandle - Debug.Assert(id != ReadyToRunHelperId.NecessaryTypeHandle); - switch (id) { case ReadyToRunHelperId.TypeHandle: return factory.GenericLookup.Type((TypeDesc)target); + case ReadyToRunHelperId.NecessaryTypeHandle: + return factory.GenericLookup.NecessaryType((TypeDesc)target); + case ReadyToRunHelperId.MetadataTypeHandle: + return factory.GenericLookup.MetadataType((TypeDesc)target); case ReadyToRunHelperId.TypeHandleForCasting: // Check that we unwrapped the cases that could be unwrapped to prevent duplicate entries Debug.Assert(factory.GenericLookup.Type((TypeDesc)target) != factory.GenericLookup.UnwrapNullableType((TypeDesc)target)); @@ -304,6 +305,7 @@ public override int CompareToImpl(ISortableNode other, CompilerComparer comparer switch (_id) { case ReadyToRunHelperId.TypeHandle: + case ReadyToRunHelperId.NecessaryTypeHandle: case ReadyToRunHelperId.GetGCStaticBase: case ReadyToRunHelperId.GetNonGCStaticBase: case ReadyToRunHelperId.GetThreadStaticBase: diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReadyToRunHelperNode.cs index a9e29728ca6421..761a36e754bf55 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReadyToRunHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReadyToRunHelperNode.cs @@ -30,6 +30,7 @@ public enum ReadyToRunHelperId // The following helpers are used for generic lookups only TypeHandle, NecessaryTypeHandle, + MetadataTypeHandle, DeclaringTypeHandle, MethodHandle, FieldHandle, diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReflectionInvokeMapNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReflectionInvokeMapNode.cs index afc6188152a8a3..f74267f9c26be4 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReflectionInvokeMapNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReflectionInvokeMapNode.cs @@ -99,28 +99,15 @@ internal static void AddSignatureDependency(ref DependencyList dependencies, Nod { factory.TypeSystemContext.DetectGenericCycles(type, referent); - // If the user can legitimately get to a System.Type instance by inspecting the signature of the method, - // the user then might use these System.Type instances with APIs such as: - // - // * MethodInfo.CreateDelegate - // * RuntimeHelpers.Box - // * Array.CreateInstanceForArrayType - // - // All of these APIs are trim/AOT safe and allow creating new instances of the supplied Type. - // We need this to work. - // NOTE: We don't have to worry about RuntimeHelpers.GetUninitializedObject because that one is annotated - // as trim-unsafe. - bool isMaximallyConstructibleByPolicy = type.IsDelegate || type.IsValueType || type.IsSzArray; - // Reflection might need to create boxed instances of valuetypes as part of reflection invocation. // Non-valuetypes are only needed for the purposes of casting/type checks. // If this is a non-exact type, we need the type loader template to get the type handle. if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) GenericTypesTemplateMap.GetTemplateTypeDependencies(ref dependencies, factory, type.NormalizeInstantiation()); - else if ((isOut && !type.IsGCPointer) || isMaximallyConstructibleByPolicy) + else if (isOut && !type.IsGCPointer) dependencies.Add(factory.MaximallyConstructableType(type.NormalizeInstantiation()), reason); else - dependencies.Add(factory.NecessaryTypeSymbol(type.NormalizeInstantiation()), reason); + dependencies.Add(factory.MetadataTypeSymbol(type.NormalizeInstantiation()), reason); } catch (TypeSystemException) { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/RuntimeImportMethodNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/RuntimeImportMethodNode.cs index 6ccf0d25d43ad6..1d4d4b47c3c4b1 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/RuntimeImportMethodNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/RuntimeImportMethodNode.cs @@ -9,7 +9,7 @@ namespace ILCompiler.DependencyAnalysis /// /// Represents a method that is imported from the runtime library. /// - public class RuntimeImportMethodNode : ExternSymbolNode, IMethodNode, ISymbolDefinitionNode + public class RuntimeImportMethodNode : ExternFunctionSymbolNode, IMethodNode, ISymbolDefinitionNode { private MethodDesc _method; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunGenericHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunGenericHelperNode.cs index 1e60084ae74968..9a3a50d5f55612 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunGenericHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunGenericHelperNode.cs @@ -188,6 +188,8 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco // These are all simple: just get the thing from the dictionary and we're done case ReadyToRunHelperId.TypeHandle: + case ReadyToRunHelperId.NecessaryTypeHandle: + case ReadyToRunHelperId.MetadataTypeHandle: case ReadyToRunHelperId.MethodHandle: case ReadyToRunHelperId.FieldHandle: case ReadyToRunHelperId.MethodDictionary: diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs index 85a507d6a1dd90..b7db3ab474e48c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs @@ -128,7 +128,7 @@ protected override void EmitCode(NodeFactory factory, ref ARMEmitter encoder, bo if (targetMethod.OwningType.IsInterface) { encoder.EmitMOV(encoder.TargetRegister.Arg1, factory.InterfaceDispatchCell(targetMethod)); - encoder.EmitJMP(factory.ExternSymbol("RhpResolveInterfaceMethod")); + encoder.EmitJMP(factory.ExternFunctionSymbol("RhpResolveInterfaceMethod")); } else { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunGenericHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunGenericHelperNode.cs index 8a0cf4f8d12437..bee77707a3d380 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunGenericHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunGenericHelperNode.cs @@ -186,6 +186,8 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en // These are all simple: just get the thing from the dictionary and we're done case ReadyToRunHelperId.TypeHandle: + case ReadyToRunHelperId.NecessaryTypeHandle: + case ReadyToRunHelperId.MetadataTypeHandle: case ReadyToRunHelperId.MethodHandle: case ReadyToRunHelperId.FieldHandle: case ReadyToRunHelperId.MethodDictionary: diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs index 430fb07d960242..de94d044527b2f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs @@ -144,7 +144,7 @@ protected override void EmitCode(NodeFactory factory, ref ARM64Emitter encoder, if (targetMethod.OwningType.IsInterface) { encoder.EmitMOV(encoder.TargetRegister.Arg1, factory.InterfaceDispatchCell(targetMethod)); - encoder.EmitJMP(factory.ExternSymbol("RhpResolveInterfaceMethod")); + encoder.EmitJMP(factory.ExternFunctionSymbol("RhpResolveInterfaceMethod")); } else { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64ReadyToRunGenericHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64ReadyToRunGenericHelperNode.cs index a391b3d081d867..609ab259aeeebe 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64ReadyToRunGenericHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64ReadyToRunGenericHelperNode.cs @@ -188,6 +188,8 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit // These are all simple: just get the thing from the dictionary and we're done case ReadyToRunHelperId.TypeHandle: + case ReadyToRunHelperId.NecessaryTypeHandle: + case ReadyToRunHelperId.MetadataTypeHandle: case ReadyToRunHelperId.MethodHandle: case ReadyToRunHelperId.FieldHandle: case ReadyToRunHelperId.MethodDictionary: diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64ReadyToRunHelperNode.cs index 3339edb837a57c..98e433a5058c4d 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64ReadyToRunHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64ReadyToRunHelperNode.cs @@ -136,7 +136,7 @@ protected override void EmitCode(NodeFactory factory, ref LoongArch64Emitter enc if (targetMethod.OwningType.IsInterface) { encoder.EmitMOV(encoder.TargetRegister.Arg1, factory.InterfaceDispatchCell(targetMethod)); - encoder.EmitJMP(factory.ExternSymbol("RhpResolveInterfaceMethod")); + encoder.EmitJMP(factory.ExternFunctionSymbol("RhpResolveInterfaceMethod")); } else { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64ReadyToRunGenericHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64ReadyToRunGenericHelperNode.cs index c6e2364766fa64..397054c946422b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64ReadyToRunGenericHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64ReadyToRunGenericHelperNode.cs @@ -185,6 +185,8 @@ protected sealed override void EmitCode(NodeFactory factory, ref RiscV64Emitter // These are all simple: just get the thing from the dictionary and we're done case ReadyToRunHelperId.TypeHandle: + case ReadyToRunHelperId.NecessaryTypeHandle: + case ReadyToRunHelperId.MetadataTypeHandle: case ReadyToRunHelperId.MethodHandle: case ReadyToRunHelperId.FieldHandle: case ReadyToRunHelperId.MethodDictionary: diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64ReadyToRunHelperNode.cs index afe928b4f24be6..cb217b1e2bffb2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64ReadyToRunHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64ReadyToRunHelperNode.cs @@ -134,7 +134,7 @@ protected override void EmitCode(NodeFactory factory, ref RiscV64Emitter encoder if (targetMethod.OwningType.IsInterface) { encoder.EmitMOV(encoder.TargetRegister.Arg1, factory.InterfaceDispatchCell(targetMethod)); - encoder.EmitJMP(factory.ExternSymbol("RhpResolveInterfaceMethod")); + encoder.EmitJMP(factory.ExternFunctionSymbol("RhpResolveInterfaceMethod")); } else { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunGenericHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunGenericHelperNode.cs index 89e4247a44bff5..3bdb19a24ac5ac 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunGenericHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunGenericHelperNode.cs @@ -196,6 +196,8 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco // These are all simple: just get the thing from the dictionary and we're done case ReadyToRunHelperId.TypeHandle: + case ReadyToRunHelperId.NecessaryTypeHandle: + case ReadyToRunHelperId.MetadataTypeHandle: case ReadyToRunHelperId.MethodHandle: case ReadyToRunHelperId.FieldHandle: case ReadyToRunHelperId.MethodDictionary: diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs index a63deaf80c1dd3..c5f8cab13db3f7 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs @@ -149,7 +149,7 @@ protected override void EmitCode(NodeFactory factory, ref X64Emitter encoder, bo if (targetMethod.OwningType.IsInterface) { encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.InterfaceDispatchCell(targetMethod)); - encoder.EmitJMP(factory.ExternSymbol("RhpResolveInterfaceMethod")); + encoder.EmitJMP(factory.ExternFunctionSymbol("RhpResolveInterfaceMethod")); } else { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X86/X86ReadyToRunGenericHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X86/X86ReadyToRunGenericHelperNode.cs index e61f9c5b088cd2..022b87dd817fd7 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X86/X86ReadyToRunGenericHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X86/X86ReadyToRunGenericHelperNode.cs @@ -190,6 +190,8 @@ protected sealed override void EmitCode(NodeFactory factory, ref X86Emitter enco // These are all simple: just get the thing from the dictionary and we're done case ReadyToRunHelperId.TypeHandle: + case ReadyToRunHelperId.NecessaryTypeHandle: + case ReadyToRunHelperId.MetadataTypeHandle: case ReadyToRunHelperId.MethodHandle: case ReadyToRunHelperId.FieldHandle: case ReadyToRunHelperId.MethodDictionary: diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X86/X86ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X86/X86ReadyToRunHelperNode.cs index 472f628a353393..e2b8e6724aaf25 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X86/X86ReadyToRunHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X86/X86ReadyToRunHelperNode.cs @@ -159,7 +159,7 @@ protected override void EmitCode(NodeFactory factory, ref X86Emitter encoder, bo if (targetMethod.OwningType.IsInterface) { encoder.EmitMOV(encoder.TargetRegister.Arg1, factory.InterfaceDispatchCell(targetMethod)); - encoder.EmitJMP(factory.ExternSymbol("RhpResolveInterfaceMethod")); + encoder.EmitJMP(factory.ExternFunctionSymbol("RhpResolveInterfaceMethod")); } else { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs index 32c826adf5f21f..0d26a15756011c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs @@ -37,8 +37,6 @@ public override IEnumerable GetStaticDependencies(NodeFacto { DependencyList dependencies = new DependencyList(); - CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, ((EcmaType)_type)); - DefType containingType = _type.ContainingType; if (containingType != null) dependencies.Add(factory.TypeMetadata((MetadataType)containingType), "Containing type of a reflectable type"); @@ -102,6 +100,13 @@ public override IEnumerable GetStaticDependencies(NodeFacto return dependencies; } + public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) + { + var dependencies = new List(); + CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, ((EcmaType)_type)); + return dependencies; + } + /// /// Decomposes a constructed type into individual units that will be needed to /// express the constructed type in metadata. @@ -183,9 +188,8 @@ protected override void OnMarked(NodeFactory factory) public override bool InterestingForDynamicDependencyAnalysis => false; public override bool HasDynamicDependencies => false; - public override bool HasConditionalStaticDependencies => false; + public override bool HasConditionalStaticDependencies => true; public override bool StaticDependenciesAreComputed => true; - public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) => null; public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory factory) => null; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/VariantInterfaceMethodUseNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/VariantInterfaceMethodUseNode.cs index a81bffeb0b785b..91f851b8d5af75 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/VariantInterfaceMethodUseNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/VariantInterfaceMethodUseNode.cs @@ -76,7 +76,7 @@ public static bool IsVariantInterfaceImplementation(NodeFactory factory, TypeDes } if (!result && - (providingType.IsArray || providingType.GetTypeDefinition() == factory.ArrayOfTEnumeratorType) && + (providingType.IsArray || providingType.GetTypeDefinition() == factory.TypeSystemContext.ArrayOfTEnumeratorType) && implementedInterface.HasInstantiation) { // We need to also do this for generic interfaces on arrays because they have a weird casting rule diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs index bc3f6ef3945523..18fdd2f65550eb 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs @@ -200,7 +200,7 @@ protected override Helper CreateValueFromKey(ReadyToRunHelper key) ISymbolNode entryPoint; if (mangledName != null) - entryPoint = _compilation.NodeFactory.ExternSymbol(mangledName); + entryPoint = _compilation.NodeFactory.ExternFunctionSymbol(mangledName); else entryPoint = _compilation.NodeFactory.MethodEntrypoint(methodDesc); @@ -310,6 +310,15 @@ public TypeMapManager GetTypeMapManager() return new ScannedTypeMapManager(_factory); } + public IEnumerable GetAnalysisCharacteristics() + { + foreach (DependencyNodeCore n in MarkedNodes) + { + if (n is AnalysisCharacteristicNode acn) + yield return acn.Characteristic; + } + } + private sealed class ScannedVTableProvider : VTableSliceProvider { private readonly Dictionary _vtableSlices = new Dictionary(); @@ -393,6 +402,17 @@ private static GenericLookupResult[] OptimizeSlots(NodeFactory factory, IEnumera ArrayBuilder slotBuilder = default; ArrayBuilder discardedBuilder = default; + // Find all constructed and metadata type lookups. We'll use this for deduplication. + var constructedTypeLookups = new HashSet(); + var metadataTypeLookups = new HashSet(); + foreach (GenericLookupResult lookupResult in slots) + { + if (lookupResult is TypeHandleGenericLookupResult thLookup) + constructedTypeLookups.Add(thLookup.Type); + else if (lookupResult is MetadataTypeHandleGenericLookupResult mdthLookup) + metadataTypeLookups.Add(mdthLookup.Type); + } + // We go over all slots in the layout, looking for references to method dictionaries // that are going to be empty. // Set those slots aside so that we can avoid generating the references to such dictionaries. @@ -412,6 +432,16 @@ private static GenericLookupResult[] OptimizeSlots(NodeFactory factory, IEnumera continue; } } + else if (lookupResult is NecessaryTypeHandleGenericLookupResult thLookup) + { + if (constructedTypeLookups.Contains(thLookup.Type) || metadataTypeLookups.Contains(thLookup.Type)) + continue; + } + else if (lookupResult is MetadataTypeHandleGenericLookupResult mdthLookup) + { + if (constructedTypeLookups.Contains(mdthLookup.Type)) + continue; + } slotBuilder.Add(lookupResult); } @@ -470,7 +500,9 @@ public override DictionaryLayoutNode GetLayout(TypeSystemEntity methodOrType) private sealed class ScannedDevirtualizationManager : DevirtualizationManager { + private CompilerTypeSystemContext _context; private HashSet _constructedMethodTables = new HashSet(); + private HashSet _metadataMethodTables = new HashSet(); private HashSet _reflectionVisibleGenericDefinitionMethodTables = new HashSet(); private HashSet _canonConstructedMethodTables = new HashSet(); private HashSet _canonConstructedTypes = new HashSet(); @@ -483,6 +515,8 @@ private sealed class ScannedDevirtualizationManager : DevirtualizationManager public ScannedDevirtualizationManager(NodeFactory factory, ImmutableArray> markedNodes) { + _context = factory.TypeSystemContext; + var vtables = new Dictionary>(); var dynamicInterfaceCastableImplementationTargets = new HashSet(); @@ -499,12 +533,12 @@ public ScannedDevirtualizationManager(NodeFactory factory, ImmutableArray eetypeNode.Type, - CanonicalEETypeNode canoneetypeNode => canoneetypeNode.Type, - _ => null, - }; + _metadataMethodTables.Add(metadataMT.Type); + } + + TypeDesc type = (node as ConstructedEETypeNode)?.Type; if (type != null) { @@ -578,23 +612,6 @@ public ScannedDevirtualizationManager(NodeFactory factory, ImmutableArray, etc. - if (baseInterface.HasInstantiation) - _disqualifiedTypes.Add(baseInterface); - } - } - } TypeDesc canonType = type.ConvertToCanonForm(CanonicalFormKind.Specific); TypeDesc baseType; @@ -778,6 +795,13 @@ public override bool CanReferenceConstructedMethodTable(TypeDesc type) return _constructedMethodTables.Contains(type); } + public override bool CanReferenceMetadataMethodTable(TypeDesc type) + { + Debug.Assert(type.NormalizeInstantiation() == type); + Debug.Assert(ConstructedEETypeNode.CreationAllowed(type)); + return _metadataMethodTables.Contains(type); + } + public override bool CanReferenceConstructedTypeOrCanonicalFormOfType(TypeDesc type) { Debug.Assert(type.NormalizeInstantiation() == type); @@ -796,6 +820,9 @@ public override TypeDesc[] GetImplementingClasses(TypeDesc type) if (_disqualifiedTypes.Contains(type)) return null; + if (_context.IsArrayVariantCastable(type)) + return null; + if (_implementators.TryGetValue(type, out HashSet implementations)) { TypeDesc[] types; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Logger.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Logger.cs index 182d84900f57e8..12bd8b0e81aa12 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Logger.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Logger.cs @@ -37,7 +37,7 @@ public class Logger private readonly bool _treatWarningsAsErrors; private readonly Dictionary _warningsAsErrors; - public static Logger Null = new Logger(new TextLogWriter(TextWriter.Null), null, false); + public static Logger Null = new Logger(new TextLogWriter(TextWriter.Null), null, false, true); public bool IsVerbose { get; } @@ -51,7 +51,8 @@ public Logger( IEnumerable singleWarnDisabledModules, IEnumerable suppressedCategories, bool treatWarningsAsErrors, - IDictionary warningsAsErrors) + IDictionary warningsAsErrors, + bool disableGeneratedCodeHeuristics) { _logWriter = writer; IsVerbose = isVerbose; @@ -62,22 +63,22 @@ public Logger( _suppressedCategories = new HashSet(suppressedCategories, StringComparer.Ordinal); _treatWarningsAsErrors = treatWarningsAsErrors; _warningsAsErrors = new Dictionary(warningsAsErrors); - _compilerGeneratedState = ilProvider == null ? null : new CompilerGeneratedState(ilProvider, this); + _compilerGeneratedState = ilProvider == null ? null : new CompilerGeneratedState(ilProvider, this, disableGeneratedCodeHeuristics); _unconditionalSuppressMessageAttributeState = new UnconditionalSuppressMessageAttributeState(_compilerGeneratedState, this); } - public Logger(TextWriter writer, ILProvider ilProvider, bool isVerbose, IEnumerable suppressedWarnings, bool singleWarn, IEnumerable singleWarnEnabledModules, IEnumerable singleWarnDisabledModules, IEnumerable suppressedCategories, bool treatWarningsAsErrors, IDictionary warningsAsErrors) - : this(new TextLogWriter(writer), ilProvider, isVerbose, suppressedWarnings, singleWarn, singleWarnEnabledModules, singleWarnDisabledModules, suppressedCategories, treatWarningsAsErrors, warningsAsErrors) + public Logger(TextWriter writer, ILProvider ilProvider, bool isVerbose, IEnumerable suppressedWarnings, bool singleWarn, IEnumerable singleWarnEnabledModules, IEnumerable singleWarnDisabledModules, IEnumerable suppressedCategories, bool treatWarningsAsErrors, IDictionary warningsAsErrors, bool disableGeneratedCodeHeuristics) + : this(new TextLogWriter(writer), ilProvider, isVerbose, suppressedWarnings, singleWarn, singleWarnEnabledModules, singleWarnDisabledModules, suppressedCategories, treatWarningsAsErrors, warningsAsErrors, disableGeneratedCodeHeuristics) { } - public Logger(ILogWriter writer, ILProvider ilProvider, bool isVerbose) - : this(writer, ilProvider, isVerbose, Array.Empty(), singleWarn: false, Array.Empty(), Array.Empty(), Array.Empty(), false, new Dictionary()) + public Logger(ILogWriter writer, ILProvider ilProvider, bool isVerbose, bool disableGeneratedCodeHeuristics) + : this(writer, ilProvider, isVerbose, Array.Empty(), singleWarn: false, Array.Empty(), Array.Empty(), Array.Empty(), false, new Dictionary(), disableGeneratedCodeHeuristics) { } - public Logger(TextWriter writer, ILProvider ilProvider, bool isVerbose) - : this(new TextLogWriter(writer), ilProvider, isVerbose) + public Logger(TextWriter writer, ILProvider ilProvider, bool isVerbose, bool disableGeneratedCodeHeuristics) + : this(new TextLogWriter(writer), ilProvider, isVerbose, disableGeneratedCodeHeuristics) { } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs index 1476d46cbd10e0..93a2e79d9df627 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs @@ -233,7 +233,7 @@ protected virtual void Graph_NewMarkedNode(DependencyNodeCore obj) { _typesWithEETypesGenerated.Add(eetypeNode.Type); - if (eetypeNode is ConstructedEETypeNode || eetypeNode is CanonicalEETypeNode) + if (eetypeNode is ConstructedEETypeNode) { _typesWithConstructedEETypesGenerated.Add(eetypeNode.Type); } @@ -565,7 +565,7 @@ protected virtual void GetMetadataDependenciesDueToReflectability(ref Dependency // and property setters) } - public virtual void GetConditionalDependenciesDueToEETypePresence(ref CombinedDependencyList dependencies, NodeFactory factory, TypeDesc type) + public virtual void GetConditionalDependenciesDueToEETypePresence(ref CombinedDependencyList dependencies, NodeFactory factory, TypeDesc type, bool allocated) { // MetadataManagers can override this to provide additional dependencies caused by the presence of // an MethodTable. @@ -1240,6 +1240,10 @@ public bool CanGenerateMetadata(FieldDesc field) protected abstract MetadataCategory GetMetadataCategory(TypeDesc type); protected abstract MetadataCategory GetMetadataCategory(FieldDesc field); + public virtual void GetDependenciesDueToAccess(ref DependencyList dependencies, NodeFactory factory, MethodIL methodIL, TypeDesc accessedType) + { + } + public virtual void GetDependenciesDueToAccess(ref DependencyList dependencies, NodeFactory factory, MethodIL methodIL, MethodDesc calledMethod) { } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MstatObjectDumper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MstatObjectDumper.cs index 341be9932824bd..b210a7b33eafd0 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MstatObjectDumper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MstatObjectDumper.cs @@ -25,7 +25,7 @@ namespace ILCompiler public class MstatObjectDumper : ObjectDumper { private const int VersionMajor = 2; - private const int VersionMinor = 1; + private const int VersionMinor = 2; private readonly string _fileName; private readonly MstatEmitter _emitter; @@ -40,6 +40,7 @@ public class MstatObjectDumper : ObjectDumper private List<(MethodDesc Method, string MangledName, int Size, int GcInfoSize)> _methods = new(); private Dictionary _methodEhInfo = new(); private Dictionary _blobs = new(); + private Dictionary> _deduplicatedBodies = new(); public MstatObjectDumper(string fileName, TypeSystemContext context) { @@ -106,6 +107,17 @@ protected override void DumpObjectNode(NodeFactory factory, ObjectNode node, Obj } } + public override void ReportFoldedNode(NodeFactory factory, ObjectNode originalNode, ISymbolNode targetNode) + { + if (originalNode is IMethodBodyNode originalBody && targetNode is IMethodBodyNode targetBody) + { + if (!_deduplicatedBodies.TryGetValue(originalBody.Method, out List<(MethodDesc, int)> targetBodies)) + _deduplicatedBodies.Add(originalBody.Method, targetBodies = new List<(MethodDesc, int)>()); + + targetBodies.Add((targetBody.Method, AppendMangledName(targetBody.GetName(factory)))); + } + } + private void DumpFrozenRegion(NodeFactory factory) { Debug.Assert(_frozenObjects.Offset == 0); @@ -168,12 +180,27 @@ internal override void End() blobs.LoadConstantI4(b.Value); } + var deduplicatedMethods = new InstructionEncoder(new BlobBuilder()); + foreach (var d in _deduplicatedBodies) + { + deduplicatedMethods.OpCode(ILOpCode.Ldtoken); + deduplicatedMethods.Token(_emitter.EmitMetadataHandleForTypeSystemEntity(d.Key)); + deduplicatedMethods.LoadConstantI4(d.Value.Count); + foreach (var o in d.Value) + { + deduplicatedMethods.OpCode(ILOpCode.Ldtoken); + deduplicatedMethods.Token(_emitter.EmitMetadataHandleForTypeSystemEntity(o.Method)); + deduplicatedMethods.LoadConstantI4(o.MangledName); + } + } + _emitter.AddGlobalMethod("Methods", methods, 0); _emitter.AddGlobalMethod("Types", _types, 0); _emitter.AddGlobalMethod("Blobs", blobs, 0); _emitter.AddGlobalMethod("RvaFields", _fieldRvas, 0); _emitter.AddGlobalMethod("FrozenObjects", _frozenObjects, 0); _emitter.AddGlobalMethod("ManifestResources", _manifestResources, 0); + _emitter.AddGlobalMethod("DeduplicatedMethods", deduplicatedMethods, 0); _emitter.AddPESection(".names", _mangledNames); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MultiFileCompilationModuleGroup.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MultiFileCompilationModuleGroup.cs index 4e0cc67c824a42..031508b7cc5f26 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MultiFileCompilationModuleGroup.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MultiFileCompilationModuleGroup.cs @@ -97,7 +97,7 @@ public override bool ShouldProduceFullVTable(TypeDesc type) public override bool ShouldPromoteToFullType(TypeDesc type) { - return ShouldProduceFullVTable(type) || type.IsGenericDefinition; + return ShouldProduceFullVTable(type); } public override bool PresenceOfEETypeImpliesAllMethodsOnType(TypeDesc type) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectDataInterner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectDataInterner.cs index bbaf09e2c8cdc6..f54d68cf0fc154 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectDataInterner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectDataInterner.cs @@ -6,17 +6,29 @@ using ILCompiler.DependencyAnalysis; +using Internal.TypeSystem; + using Debug = System.Diagnostics.Debug; namespace ILCompiler { public sealed class ObjectDataInterner { + private readonly bool _genericsOnly; private Dictionary _symbolRemapping; - public static ObjectDataInterner Null { get; } = new ObjectDataInterner() { _symbolRemapping = new() }; + public static ObjectDataInterner Null { get; } = new ObjectDataInterner(genericsOnly: false) { _symbolRemapping = new() }; - public bool IsNull => _symbolRemapping != null && _symbolRemapping.Count == 0; + public ObjectDataInterner(bool genericsOnly) + { + _genericsOnly = genericsOnly; + } + + public bool CanFold(MethodDesc method) + { + return this != Null + && (!_genericsOnly || method.HasInstantiation || method.OwningType.HasInstantiation); + } private void EnsureMap(NodeFactory factory) { @@ -34,11 +46,14 @@ private void EnsureMap(NodeFactory factory) { previousMethodHash = methodHash; previousSymbolRemapping = symbolRemapping; - methodHash = new HashSet(previousMethodHash?.Count ?? 0, new MethodInternComparer(factory, previousSymbolRemapping)); + methodHash = new HashSet(previousMethodHash?.Count ?? 0, new MethodInternComparer(factory, previousSymbolRemapping, _genericsOnly)); symbolRemapping = new Dictionary((int)(1.05 * (previousSymbolRemapping?.Count ?? 0))); foreach (IMethodBodyNode body in factory.MetadataManager.GetCompiledMethodBodies()) { + if (!CanFold(body.Method)) + continue; + // We don't track special unboxing thunks as virtual method use related so ignore them if (body is ISpecialUnboxThunkNode unboxThunk && unboxThunk.IsSpecialUnboxingThunk) continue; @@ -107,9 +122,10 @@ private sealed class MethodInternComparer : IEqualityComparer { private readonly NodeFactory _factory; private readonly Dictionary _interner; + private readonly bool _genericsOnly; - public MethodInternComparer(NodeFactory factory, Dictionary interner) - => (_factory, _interner) = (factory, interner); + public MethodInternComparer(NodeFactory factory, Dictionary interner, bool genericsOnly) + => (_factory, _interner, _genericsOnly) = (factory, interner, genericsOnly); public int GetHashCode(MethodInternKey key) => key.HashCode; @@ -161,6 +177,10 @@ public bool Equals(MethodInternKey a, MethodInternKey b) if (a.HashCode != b.HashCode) return false; + if (_genericsOnly + && a.Method.Method.GetTypicalMethodDefinition() != b.Method.Method.GetTypicalMethodDefinition()) + return false; + ObjectNode.ObjectData o1data = ((ObjectNode)a.Method).GetData(_factory, relocsOnly: false); ObjectNode.ObjectData o2data = ((ObjectNode)b.Method).GetData(_factory, relocsOnly: false); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectDumper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectDumper.cs index 85cd7f790c2c45..a6a2d4c14bf2e9 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectDumper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectDumper.cs @@ -16,6 +16,8 @@ public abstract class ObjectDumper : IObjectDumper void IObjectDumper.DumpObjectNode(NodeFactory factory, ObjectNode node, ObjectData objectData) => DumpObjectNode(factory, node, objectData); protected abstract void DumpObjectNode(NodeFactory factory, ObjectNode node, ObjectData objectData); + public virtual void ReportFoldedNode(NodeFactory factory, ObjectNode originalNode, ISymbolNode targetNode) { } + protected static string GetObjectNodeName(ObjectNode node) { string name = node.GetType().Name; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ObjectWriter.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ObjectWriter.cs index 542f150cb1f315..6db2bc20b01b25 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ObjectWriter.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ObjectWriter.cs @@ -385,8 +385,12 @@ private void EmitObject(string objectFilePath, IReadOnlyCollection.StaticDependenciesAreComputed => true; bool IDependencyNode.Marked => true; + string IDependencyNode.GetName(NodeFactory context) => _name; void ISymbolNode.AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) => sb.Append(_name); IEnumerable IDependencyNode.GetConditionalStaticDependencies(NodeFactory context) => throw new NotImplementedException(); IEnumerable IDependencyNode.GetStaticDependencies(NodeFactory context) => null; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs index b7805815887b56..d455183bb0b5ae 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs @@ -10,6 +10,7 @@ using ILCompiler.DependencyAnalysis; using Internal.IL; +using Internal.IL.Stubs; using Internal.TypeSystem; using Internal.TypeSystem.Ecma; @@ -24,13 +25,15 @@ public class SubstitutedILProvider : ILProvider private readonly SubstitutionProvider _substitutionProvider; private readonly DevirtualizationManager _devirtualizationManager; private readonly MetadataManager _metadataManager; + private readonly HashSet _characteristics; - public SubstitutedILProvider(ILProvider nestedILProvider, SubstitutionProvider substitutionProvider, DevirtualizationManager devirtualizationManager, MetadataManager metadataManager = null) + public SubstitutedILProvider(ILProvider nestedILProvider, SubstitutionProvider substitutionProvider, DevirtualizationManager devirtualizationManager, MetadataManager metadataManager = null, IEnumerable characteristics = null) { _nestedILProvider = nestedILProvider; _substitutionProvider = substitutionProvider; _devirtualizationManager = devirtualizationManager; _metadataManager = metadataManager; + _characteristics = characteristics != null ? new HashSet(characteristics) : null; } public override MethodIL GetMethodIL(MethodDesc method) @@ -41,6 +44,13 @@ public override MethodIL GetMethodIL(MethodDesc method) return substitution.EmitIL(method); } + if (TryGetCharacteristicValue(method, out bool characteristicEnabled)) + { + return new ILStubMethodIL(method, + [characteristicEnabled ? (byte)ILOpCode.Ldc_i4_1 : (byte)ILOpCode.Ldc_i4_0, (byte)ILOpCode.Ret], + [], []); + } + // BEGIN TEMPORARY WORKAROUND // // The following lines should just be: @@ -819,6 +829,11 @@ private bool TryGetConstantArgument(MethodIL methodIL, byte[] body, OpcodeFlags[ { return true; } + else if (TryGetCharacteristicValue(method, out bool characteristic)) + { + constant = characteristic ? 1 : 0; + return true; + } else { constant = 0; @@ -1087,6 +1102,10 @@ private bool TryExpandIsInst(in IsInstCheckPatternAnalyzer analyzer, MethodIL me if (_devirtualizationManager.CanReferenceConstructedTypeOrCanonicalFormOfType(type.NormalizeInstantiation())) return false; + // Above check took care of most variant scenarios but we still need to worry about array variance + if (((CompilerTypeSystemContext)type.Context).IsArrayVariantCastable(type)) + return false; + constant = 0; return true; @@ -1123,6 +1142,19 @@ private static bool ReadGetTypeFromHandle(ref ILReader reader, MethodIL methodIL return true; } + private bool TryGetCharacteristicValue(MethodDesc maybeCharacteristicMethod, out bool value) + { + if (maybeCharacteristicMethod.IsIntrinsic + && maybeCharacteristicMethod.HasCustomAttribute("System.Runtime.CompilerServices", "AnalysisCharacteristicAttribute")) + { + value = _characteristics == null || _characteristics.Contains(maybeCharacteristicMethod.Name); + return true; + } + + value = false; + return false; + } + private sealed class SubstitutedMethodIL : MethodIL { private readonly byte[] _body; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypeMapMetadata.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypeMapMetadata.cs index cea9f66e4bb5e0..5a84855650f394 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypeMapMetadata.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypeMapMetadata.cs @@ -248,7 +248,7 @@ void ProcessTypeMapAttribute(CustomAttributeValue attrValue, TypeDesc { typeMapStates[typeMapGroup] = typeMapState = new Map(typeMapGroup); } - typeMapState.AddExternalTypeMapEntry(typeName, targetType, targetType); + typeMapState.AddExternalTypeMapEntry(typeName, targetType, null); break; } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs index 2a58d119798695..3871f3b059e7bd 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs @@ -2868,7 +2868,7 @@ public RuntimeTypeValue(TypeDesc type) public override bool GetRawData(NodeFactory factory, out object data) { - data = factory.SerializedMaximallyConstructableRuntimeTypeObject(TypeRepresented); + data = factory.SerializedMetadataRuntimeTypeObject(TypeRepresented); return true; } @@ -2882,7 +2882,7 @@ public override ReferenceTypeValue ToForeignInstance(int baseInstructionCounter, } public override void WriteFieldData(ref ObjectDataBuilder builder, NodeFactory factory) { - builder.EmitPointerReloc(factory.SerializedMaximallyConstructableRuntimeTypeObject(TypeRepresented)); + builder.EmitPointerReloc(factory.SerializedMetadataRuntimeTypeObject(TypeRepresented)); } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs index 18fe157a668b3e..5b233fe12e627f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs @@ -405,13 +405,13 @@ public override bool HasConditionalDependenciesDueToEETypePresence(TypeDesc type return false; } - public override void GetConditionalDependenciesDueToEETypePresence(ref CombinedDependencyList dependencies, NodeFactory factory, TypeDesc type) + public override void GetConditionalDependenciesDueToEETypePresence(ref CombinedDependencyList dependencies, NodeFactory factory, TypeDesc type, bool allocated) { // Check to see if we have any dataflow annotations on the type. // The check below also covers flow annotations inherited through base classes and implemented interfaces. - bool hasFlowAnnotations = type.IsDefType && FlowAnnotations.GetTypeAnnotation(type) != default; + bool allocatedWithFlowAnnotations = allocated && type.IsDefType && FlowAnnotations.GetTypeAnnotation(type) != default; - if (hasFlowAnnotations) + if (allocatedWithFlowAnnotations) { dependencies ??= new CombinedDependencyList(); dependencies.Add(new DependencyNodeCore.CombinedDependencyListEntry( @@ -420,7 +420,7 @@ public override void GetConditionalDependenciesDueToEETypePresence(ref CombinedD "Type exists and GetType called on it")); } - if (hasFlowAnnotations + if (allocatedWithFlowAnnotations && !type.IsInterface /* "IFoo x; x.GetType();" -> this doesn't actually return an interface type */) { // We have some flow annotations on this type. @@ -718,25 +718,6 @@ public override IEnumerable GetCompilationModulesWithMetadata() return _modulesWithMetadata; } - private IEnumerable GetTypesWithRuntimeMapping() - { - // All constructed types that are not blocked get runtime mapping - foreach (var constructedType in GetTypesWithConstructedEETypes()) - { - if (!IsReflectionBlocked(constructedType)) - yield return constructedType; - } - - // All necessary types for which this is the highest load level that are not blocked - // get runtime mapping. - foreach (var necessaryType in GetTypesWithEETypes()) - { - if (!ConstructedEETypeNode.CreationAllowed(necessaryType) && - !IsReflectionBlocked(necessaryType)) - yield return necessaryType; - } - } - public override void GetDependenciesDueToAccess(ref DependencyList dependencies, NodeFactory factory, MethodIL methodIL, FieldDesc writtenField) { bool scanReflection = (_generationOptions & UsageBasedMetadataGenerationOptions.ReflectionILScanning) != 0; @@ -773,6 +754,15 @@ public override void GetDependenciesDueToAccess(ref DependencyList dependencies, } } + public override void GetDependenciesDueToAccess(ref DependencyList dependencies, NodeFactory factory, MethodIL methodIL, TypeDesc accessedType) + { + bool scanReflection = (_generationOptions & UsageBasedMetadataGenerationOptions.ReflectionILScanning) != 0; + if (scanReflection && Dataflow.ReflectionMethodBodyScanner.RequiresReflectionMethodBodyScannerForAccess(FlowAnnotations, accessedType)) + { + AddDataflowDependency(ref dependencies, factory, methodIL, "Access to interesting type"); + } + } + public override void GetDependenciesDueToAccess(ref DependencyList dependencies, NodeFactory factory, MethodIL methodIL, MethodDesc calledMethod) { bool scanReflection = (_generationOptions & UsageBasedMetadataGenerationOptions.ReflectionILScanning) != 0; @@ -857,8 +847,11 @@ public MetadataManager ToAnalysisBasedMetadataManager() reflectableTypes[typeWithMetadata] = MetadataCategory.Description; } - foreach (var constructedType in GetTypesWithRuntimeMapping()) + foreach (var constructedType in GetTypesWithEETypes()) { + if (IsReflectionBlocked(constructedType)) + continue; + reflectableTypes[constructedType] |= MetadataCategory.RuntimeMapping; // Also set the description bit if the definition is getting metadata. diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs index 00a0d56d48150f..799a17899a6779 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs @@ -61,6 +61,8 @@ public enum ImportState : byte private bool _isReadOnly; private TypeDesc _constrained; + private int _currentInstructionOffset; + private int _previousInstructionOffset; private DependencyList _dependencies; private BasicBlock _lateBasicBlocks; @@ -258,6 +260,13 @@ private void StartImportingBasicBlock(BasicBlock basicBlock) _typeEqualityPatternAnalyzer = default; _isInstCheckPatternAnalyzer = default; + _currentInstructionOffset = 0; + _previousInstructionOffset = -1; + } + + private void StartImportingInstruction() + { + _currentInstructionOffset = _currentOffset; } partial void StartImportingInstruction(ILOpcode opcode) @@ -271,6 +280,8 @@ private void EndImportingInstruction() // The instruction should have consumed any prefixes. _constrained = null; _isReadOnly = false; + + _previousInstructionOffset = _currentInstructionOffset; } private void ImportCasting(ILOpcode opcode, int token) @@ -550,42 +561,39 @@ private void ImportCall(ILOpcode opcode, int token) bool allowInstParam = opcode != ILOpcode.ldvirtftn && opcode != ILOpcode.ldftn; - if (directCall && resolvedConstraint && exactContextNeedsRuntimeLookup) + if (directCall && resolvedConstraint && (exactContextNeedsRuntimeLookup || forceUseRuntimeLookup)) { // We want to do a direct call to a shared method on a valuetype. We need to provide // a generic context, but the JitInterface doesn't provide a way for us to do it from here. // So we do the next best thing and ask RyuJIT to look up a fat pointer. - // - // We have the canonical version of the method - find the runtime determined version. - // This is simplified because we know the method is on a valuetype. - Debug.Assert(targetMethod.OwningType.IsValueType); if (forceUseRuntimeLookup) { - // The below logic would incorrectly resolve the lookup into the first match we found, - // but there was a compile-time ambiguity due to shared code. The correct fix should - // use the ConstrainedMethodUseLookupResult dictionary entry so that the exact - // dispatch can be computed with the help of the generic dictionary. - // We fail the compilation here to avoid bad codegen. This is not actually an invalid program. - // https://github.com/dotnet/runtimelab/issues/1431 - ThrowHelper.ThrowInvalidProgramException(); + var constrainedCallInfo = new ConstrainedCallInfo(_constrained, runtimeDeterminedMethod); + _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.ConstrainedDirectCall, constrainedCallInfo), reason); } - - MethodDesc targetOfLookup; - if (_constrained.IsRuntimeDeterminedType) - targetOfLookup = _compilation.TypeSystemContext.GetMethodForRuntimeDeterminedType(targetMethod.GetTypicalMethodDefinition(), (RuntimeDeterminedType)_constrained); - else if (_constrained.HasInstantiation) - targetOfLookup = _compilation.TypeSystemContext.GetMethodForInstantiatedType(targetMethod.GetTypicalMethodDefinition(), (InstantiatedType)_constrained); else - targetOfLookup = targetMethod.GetMethodDefinition(); - if (targetOfLookup.HasInstantiation) { - targetOfLookup = targetOfLookup.MakeInstantiatedMethod(runtimeDeterminedMethod.Instantiation); - } - Debug.Assert(targetOfLookup.GetCanonMethodTarget(CanonicalFormKind.Specific) == targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific)); - _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.MethodEntry, targetOfLookup), reason); + // We have the canonical version of the method - find the runtime determined version. + // This is simplified because we know the method is on a valuetype. + Debug.Assert(targetMethod.OwningType.IsValueType); + + MethodDesc targetOfLookup; + if (_constrained.IsRuntimeDeterminedType) + targetOfLookup = _compilation.TypeSystemContext.GetMethodForRuntimeDeterminedType(targetMethod.GetTypicalMethodDefinition(), (RuntimeDeterminedType)_constrained); + else if (_constrained.HasInstantiation) + targetOfLookup = _compilation.TypeSystemContext.GetMethodForInstantiatedType(targetMethod.GetTypicalMethodDefinition(), (InstantiatedType)_constrained); + else + targetOfLookup = targetMethod.GetMethodDefinition(); + if (targetOfLookup.HasInstantiation) + { + targetOfLookup = targetOfLookup.MakeInstantiatedMethod(runtimeDeterminedMethod.Instantiation); + } + Debug.Assert(targetOfLookup.GetCanonMethodTarget(CanonicalFormKind.Specific) == targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific)); + _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.MethodEntry, targetOfLookup), reason); - targetForDelegate = targetOfLookup; + targetForDelegate = targetOfLookup; + } } else if (directCall && !allowInstParam && targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific).RequiresInstArg()) { @@ -700,6 +708,7 @@ private void ImportCall(ILOpcode opcode, int token) { Debug.Assert(targetMethod.OwningType.IsInterface && targetMethod.IsVirtual && _constrained != null); + // TODO: https://github.com/dotnet/runtime/issues/72589 ThrowHelper.ThrowBadImageFormatException(); } else if (method.Signature.IsStatic) @@ -846,12 +855,26 @@ private void ImportBranch(ILOpcode opcode, BasicBlock target, BasicBlock fallthr { TypeDesc isinstCheckType = (TypeDesc)_canonMethodIL.GetObject(_isInstCheckPatternAnalyzer.Token); if (ConstructedEETypeNode.CreationAllowed(isinstCheckType) - && !isinstCheckType.ConvertToCanonForm(CanonicalFormKind.Specific).IsCanonicalSubtype(CanonicalFormKind.Any)) + // Below makes sure we don't need to worry about variance + && !isinstCheckType.ConvertToCanonForm(CanonicalFormKind.Specific).IsCanonicalSubtype(CanonicalFormKind.Any) + // However, we still need to worry about variant-by-size casting with arrays + && !_factory.TypeSystemContext.IsArrayVariantCastable(isinstCheckType)) { condition = _factory.MaximallyConstructableType(isinstCheckType); } } + if (opcode == ILOpcode.brfalse && _previousInstructionOffset >= 0) + { + var reader = new ILReader(_ilBytes, _previousInstructionOffset); + if (reader.ReadILOpcode() == ILOpcode.call + && _methodIL.GetObject(reader.ReadILToken()) is MethodDesc { IsIntrinsic: true } intrinsicMethod + && intrinsicMethod.HasCustomAttribute("System.Runtime.CompilerServices", "AnalysisCharacteristicAttribute")) + { + condition = _factory.AnalysisCharacteristic(intrinsicMethod.Name); + } + } + ImportFallthrough(target); if (fallthrough != null) @@ -886,7 +909,7 @@ private void ImportUnbox(int token, ILOpcode opCode) if (type.IsRuntimeDeterminedSubtype) { - _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, type), "Unbox"); + _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.NecessaryTypeHandle, type), "Unbox"); } else { @@ -918,6 +941,7 @@ private void ImportMkRefAny(int token) { _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.TypeHandleToRuntimeType), "mkrefany"); _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.TypeHandleToRuntimeTypeHandle), "mkrefany"); + _factory.MetadataManager.GetDependenciesDueToAccess(ref _dependencies, _factory, _methodIL, (TypeDesc)_canonMethodIL.GetObject(token)); ImportTypedRefOperationDependencies(token, "mkrefany"); } @@ -941,7 +965,7 @@ private void ImportLdToken(int token) if (obj is TypeDesc type) { // We might also be able to optimize this a little if this is a ldtoken/GetTypeFromHandle/Equals sequence. - bool isTypeEquals = false; + var helperId = ReadyToRunHelperId.MetadataTypeHandle; TypeEqualityPatternAnalyzer analyzer = _typeEqualityPatternAnalyzer; ILReader reader = new ILReader(_ilBytes, _currentOffset); while (!analyzer.IsDefault) @@ -952,23 +976,30 @@ private void ImportLdToken(int token) if (analyzer.IsTypeEqualityCheck) { - isTypeEquals = true; + helperId = ReadyToRunHelperId.NecessaryTypeHandle; break; } } + _factory.MetadataManager.GetDependenciesDueToAccess(ref _dependencies, _factory, _methodIL, (TypeDesc)_canonMethodIL.GetObject(token)); + _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.GetRuntimeTypeHandle), "ldtoken"); _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.GetRuntimeType), "ldtoken"); ISymbolNode reference; if (type.IsRuntimeDeterminedSubtype) { - reference = GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, type); + reference = GetGenericLookupHelper(helperId, type); } else { - reference = _compilation.ComputeConstantLookup( - isTypeEquals ? ReadyToRunHelperId.NecessaryTypeHandle : _compilation.GetLdTokenHelperForType(type), type); + if (type.IsCanonicalDefinitionType(CanonicalFormKind.Any)) + { + Debug.Assert(_methodIL.OwningMethod.Name == "GetCanonType"); + helperId = ReadyToRunHelperId.NecessaryTypeHandle; + } + + reference = _compilation.ComputeConstantLookup(helperId, type); } _dependencies.Add(reference, "ldtoken"); } @@ -1186,6 +1217,9 @@ private void AddBoxingDependencies(TypeDesc type, string reason) if (!type.IsValueType) return; + TypeDesc typeForAccessCheck = type.IsRuntimeDeterminedSubtype ? type.ConvertToCanonForm(CanonicalFormKind.Specific) : type; + _factory.MetadataManager.GetDependenciesDueToAccess(ref _dependencies, _factory, _methodIL, typeForAccessCheck); + if (type.IsRuntimeDeterminedSubtype) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, type), reason); @@ -1213,6 +1247,7 @@ private void ImportLeave(BasicBlock target) private void ImportNewArray(int token) { var elementType = (TypeDesc)_methodIL.GetObject(token); + _factory.MetadataManager.GetDependenciesDueToAccess(ref _dependencies, _factory, _methodIL, (TypeDesc)_canonMethodIL.GetObject(token)); if (elementType.IsRuntimeDeterminedSubtype) { _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, elementType.MakeArrayType()), "newarr"); @@ -1257,7 +1292,7 @@ private void ImportAddressOfElement(int token) if (elementType.IsGCPointer && !_isReadOnly) { if (elementType.IsRuntimeDeterminedSubtype) - _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, elementType), "ldelema"); + _dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.NecessaryTypeHandle, elementType), "ldelema"); else _dependencies.Add(_factory.NecessaryTypeSymbol(elementType), "ldelema"); @@ -1518,7 +1553,6 @@ private DefType GetWellKnownType(WellKnownType wellKnownType) return _compilation.TypeSystemContext.GetWellKnownType(wellKnownType); } - private static void StartImportingInstruction() { } private static void ImportNop() { } private static void ImportBreak() { } private static void ImportLoadVar(int index, bool argument) { } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj index 8f0bb038d21fe1..862404c49d4eb6 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj @@ -343,9 +343,11 @@ + + @@ -547,6 +549,7 @@ + @@ -556,8 +559,6 @@ - - diff --git a/src/coreclr/tools/aot/ILCompiler.DependencyAnalysisFramework/DependencyNodeCore.cs b/src/coreclr/tools/aot/ILCompiler.DependencyAnalysisFramework/DependencyNodeCore.cs index 0f8ed436ed4ffe..8c8e37893cc333 100644 --- a/src/coreclr/tools/aot/ILCompiler.DependencyAnalysisFramework/DependencyNodeCore.cs +++ b/src/coreclr/tools/aot/ILCompiler.DependencyAnalysisFramework/DependencyNodeCore.cs @@ -147,6 +147,8 @@ protected virtual void OnMarked(DependencyContextType context) // Force all non-abstract nodes to provide a name protected abstract string GetName(DependencyContextType context); + string IDependencyNode.GetName(DependencyContextType context) => GetName(context); + // We would prefer GetName to be "protected internal", but that will break people who want to source // include the dependency analysis framework. When nobody does that, maybe we can get rid of this method. internal string GetNameInternal(DependencyContextType context) diff --git a/src/coreclr/tools/aot/ILCompiler.DependencyAnalysisFramework/IDependencyNode.cs b/src/coreclr/tools/aot/ILCompiler.DependencyAnalysisFramework/IDependencyNode.cs index 76365d9c68bc59..fb0b622d59f4d4 100644 --- a/src/coreclr/tools/aot/ILCompiler.DependencyAnalysisFramework/IDependencyNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.DependencyAnalysisFramework/IDependencyNode.cs @@ -40,5 +40,7 @@ bool StaticDependenciesAreComputed IEnumerable.CombinedDependencyListEntry> GetConditionalStaticDependencies(DependencyContextType context); IEnumerable.CombinedDependencyListEntry> SearchDynamicDependencies(List> markedNodes, int firstNode, DependencyContextType context); + + string GetName(DependencyContextType context); } } diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler.MetadataTransform.csproj b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler.MetadataTransform.csproj index 181fa286aba3e3..304e1621f64e3f 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler.MetadataTransform.csproj +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler.MetadataTransform.csproj @@ -4,7 +4,7 @@ ILCompiler.MetadataTransform $(NetCoreAppToolCurrent) true - $(DefineConstants);NATIVEFORMAT_PUBLICWRITER;NETFX_45 + $(DefineConstants);NATIVEFORMAT_PUBLICWRITER false x64;x86 AnyCPU diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugInfoTableNode.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugInfoTableNode.cs index 6b4231b16c99f5..b809ef074b9af0 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugInfoTableNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugInfoTableNode.cs @@ -132,20 +132,103 @@ public static byte[] CreateBoundsBlobForMethod(OffsetMapping[] offsetMapping) if (offsetMapping == null || offsetMapping.Length == 0) return null; - NibbleWriter writer = new NibbleWriter(); - writer.WriteUInt((uint)offsetMapping.Length); - uint previousNativeOffset = 0; + uint maxNativeDelta = 0; + uint maxILValue = 0; foreach (var locInfo in offsetMapping) { - writer.WriteUInt(locInfo.nativeOffset - previousNativeOffset); - writer.WriteUInt(locInfo.ilOffset + 3); // Count of items in Internal.JitInterface.MappingTypes to adjust the IL offset by - writer.WriteUInt((uint)locInfo.source); - + maxNativeDelta = Math.Max(maxNativeDelta, locInfo.nativeOffset - previousNativeOffset); + maxILValue = Math.Max(maxILValue, locInfo.ilOffset + 3); previousNativeOffset = locInfo.nativeOffset; } - return writer.ToArray(); + int bitWidthForNativeDelta = Math.Max(1, 32 - System.Numerics.BitOperations.LeadingZeroCount(maxNativeDelta)); + int bitWidthForILOffset = Math.Max(1, 32 - System.Numerics.BitOperations.LeadingZeroCount(maxILValue)); + + int bitWidthReportForNativeDelta = bitWidthForNativeDelta - 1; + int bitWidthReportForILOffset = bitWidthForILOffset - 1; + NibbleWriter writer2 = new NibbleWriter(); + writer2.WriteUInt((uint)offsetMapping.Length); // We need the total count + writer2.WriteUInt((uint)bitWidthReportForNativeDelta); // Number of bits needed for native deltas + writer2.WriteUInt((uint)bitWidthReportForILOffset); // How many bits needed for IL offsets + int bitWidth = bitWidthForNativeDelta + + bitWidthForILOffset + + 2; // for the source data + int totalBits = bitWidth * offsetMapping.Length; + int bytesNeededForArray = (totalBits + 7) / 8; + + byte bitsInProgress = 0; + byte bitsInProgressCount = 0; + + List boundsBlob = new List(writer2.ToArray()); + + for (uint i = 0; i < offsetMapping.Length; i++) + { + var bound = offsetMapping[i]; + + uint prevNativeOffset = 0; + if (i > 0) + { + prevNativeOffset = offsetMapping[i - 1].nativeOffset; + } + uint nativeOffsetDelta = bound.nativeOffset - prevNativeOffset; + + uint sourceBits = 0; + switch ((int)bound.source) + { + case (int)Internal.JitInterface.SourceTypes.SOURCE_TYPE_INVALID: + sourceBits = 0; + break; + case (int)Internal.JitInterface.SourceTypes.CALL_INSTRUCTION: + sourceBits = 1; + break; + case (int)Internal.JitInterface.SourceTypes.STACK_EMPTY: + sourceBits = 2; + break; + case (int)(Internal.JitInterface.SourceTypes.CALL_INSTRUCTION | Internal.JitInterface.SourceTypes.STACK_EMPTY): + sourceBits = 3; + break; + default: + throw new InternalCompilerErrorException("Unknown source type"); + } + + + ulong mappingDataEncoded = (ulong)sourceBits | + ((ulong)nativeOffsetDelta << 2) | + ((ulong)((int)bound.ilOffset - (int)MappingTypes.EPILOG) << (2 + bitWidthForNativeDelta)); + + for (byte bitsToWrite = (byte)bitWidth; bitsToWrite > 0;) + { + // Figure out next bits to write if we need to combine with a previous byte. + if (bitsInProgressCount > 0) + { + byte bitsToAddFromNewEncoding = (byte)(8 - bitsInProgressCount); + byte bitsToAddOnToInProgress = (byte)((mappingDataEncoded & ((((uint)1) << bitsToAddFromNewEncoding) - 1)) << bitsInProgressCount); + boundsBlob.Add((byte)(bitsToAddOnToInProgress | bitsInProgress)); + mappingDataEncoded >>= bitsToAddFromNewEncoding; + bitsToWrite -= bitsToAddFromNewEncoding; + bitsInProgressCount = 0; + } + else if (bitsToWrite >= 8) + { + boundsBlob.Add((byte)mappingDataEncoded); + mappingDataEncoded >>= 8; + bitsToWrite -= 8; + } + else + { + bitsInProgress = (byte)mappingDataEncoded; + bitsInProgressCount = bitsToWrite; + bitsToWrite = 0; + } + } + } + if (bitsInProgressCount > 0) + { + Debug.Assert(bitsInProgressCount < 8); + boundsBlob.Add(bitsInProgress); + } + return boundsBlob.ToArray(); } public static byte[] CreateVarBlobForMethod(NativeVarInfo[] varInfos, TargetDetails target) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GCRefMapNode.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GCRefMapNode.cs index 7cab71737766d9..476049f45ca652 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GCRefMapNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GCRefMapNode.cs @@ -34,6 +34,8 @@ public GCRefMapNode(ImportSectionNode importSection) public int Offset => 0; + public bool IsEmpty => _methods.Count == 0; + public void AddImport(Import import) { lock (_methods) @@ -53,9 +55,9 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) if (_methods.Count == 0 || relocsOnly) { return new ObjectData( - data: Array.Empty(), - relocs: Array.Empty(), - alignment: 1, + data: Array.Empty(), + relocs: Array.Empty(), + alignment: 1, definedSymbols: new ISymbolDefinitionNode[] { this }); } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportSectionNode.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportSectionNode.cs index e2356ea2816f84..6fb78cf67757f3 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportSectionNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportSectionNode.cs @@ -41,7 +41,6 @@ protected override int GetAlignmentRequirement(NodeFactory factory) private readonly byte _entrySize; private readonly string _name; private readonly bool _emitPrecode; - private readonly bool _emitGCRefMap; private bool _materializedSignature; @@ -52,12 +51,11 @@ public ImportSectionNode(string name, ReadyToRunImportSectionType importType, Re _flags = flags; _entrySize = entrySize; _emitPrecode = emitPrecode; - _emitGCRefMap = emitGCRefMap; _imports = new ImportTable(_name + "_ImportBegin", entrySize); _signatures = new ArrayOfEmbeddedPointersNode(_name + "_SigBegin", new EmbeddedObjectNodeComparer(CompilerComparer.Instance)); _signatureList = new List(); - _gcRefMap = _emitGCRefMap ? new GCRefMapNode(this) : null; + _gcRefMap = emitGCRefMap ? new GCRefMapNode(this) : null; } public void MaterializeSignature(NodeFactory r2rFactory) @@ -89,10 +87,7 @@ public void AddImport(NodeFactory factory, Import import) _signatureList.Add(import.ImportSignature.Target); } - if (_emitGCRefMap) - { - _gcRefMap.AddImport(import); - } + _gcRefMap?.AddImport(import); } public string Name => _name; @@ -135,8 +130,10 @@ public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory f dataBuilder.EmitUInt(0); } - if (_emitGCRefMap) + // If we emit an Rva for an empty gcrefmap, it will have no size header and be impossible for r2rdump to read correctly + if (_gcRefMap?.IsEmpty == false) { + // This indirectly generates the AuxiliaryDataRva by emitting a placeholder 0 which will be replaced later dataBuilder.EmitReloc(_gcRefMap, RelocType.IMAGE_REL_BASED_ADDR32NB, 0); } else @@ -149,7 +146,7 @@ public override IEnumerable GetStaticDependencies(NodeFacto { yield return new DependencyListEntry(_imports, "Import section fixup data"); yield return new DependencyListEntry(_signatures, "Import section signatures"); - if (_emitGCRefMap) + if (_gcRefMap != null) { yield return new DependencyListEntry(_gcRefMap, "GC ref map"); } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/FileLayoutOptimizer.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/FileLayoutOptimizer.cs index 86a6a000505e60..e46de02cbf8b77 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/FileLayoutOptimizer.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/FileLayoutOptimizer.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using Internal.TypeSystem; @@ -36,6 +37,7 @@ public enum MethodLayoutAlgorithm #endif PettisHansen, Random, + Explicit, } public enum FileLayoutAlgorithm @@ -50,13 +52,15 @@ public FileLayoutOptimizer (Logger logger, MethodLayoutAlgorithm methodAlgorithm, FileLayoutAlgorithm fileAlgorithm, ProfileDataManager profileData, - NodeFactory nodeFactory) + NodeFactory nodeFactory, + string orderFile = null) { _logger = logger; _methodLayoutAlgorithm = methodAlgorithm; _fileLayoutAlgorithm = fileAlgorithm; _profileData = profileData; _nodeFactory = nodeFactory; + _orderFile = orderFile; } private Logger _logger; @@ -64,6 +68,7 @@ public FileLayoutOptimizer (Logger logger, private FileLayoutAlgorithm _fileLayoutAlgorithm = FileLayoutAlgorithm.DefaultSort; private ProfileDataManager _profileData; private NodeFactory _nodeFactory; + private string _orderFile; public ImmutableArray> ApplyProfilerGuidedMethodSort(ImmutableArray> nodes) { @@ -200,6 +205,33 @@ int ComputeHotWarmColdRegion(MethodWithGCInfo method) } break; + case MethodLayoutAlgorithm.Explicit: + var nameMap = new Dictionary(methods.Count); + var order = new Dictionary(methods.Count); + + for (int i = 0; i < methods.Count; i++) + { + nameMap[methods[i].GetMangledName(_nodeFactory.NameMangler)] = methods[i]; + order[methods[i]] = int.MaxValue; + } + + using (StreamReader sr = new StreamReader(_orderFile)) + { + int line = 0; + while (!sr.EndOfStream) + { + string symbolName = sr.ReadLine(); + if (string.IsNullOrEmpty(symbolName) + || !nameMap.TryGetValue(symbolName, out MethodWithGCInfo m)) + continue; + + order[m] = line++; + } + } + + methods.MergeSortAllowDuplicates((MethodWithGCInfo left, MethodWithGCInfo right) => order[left].CompareTo(order[right])); + break; + default: throw new NotImplementedException(_methodLayoutAlgorithm.ToString()); } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 3e3c1762f1823e..a1dc79692155f5 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/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) @@ -3103,13 +3098,6 @@ private bool convertPInvokeCalliToCall(ref CORINFO_RESOLVED_TOKEN pResolvedToken throw new NotImplementedException(); } - private bool canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig) - { - // If we answer "true" here, RyuJIT is going to ask for the cookie and for the CORINFO_HELP_PINVOKE_CALLI - // helper. The helper doesn't exist in ReadyToRun, so let's just throw right here. - throw new RequiresRuntimeJitException($"{MethodBeingCompiled} -> {nameof(canGetCookieForPInvokeCalliSig)}"); - } - private int SizeOfPInvokeTransitionFrame => ReadyToRunRuntimeConstants.READYTORUN_PInvokeTransitionFrameSizeInPointerUnits * PointerSize; private int SizeOfReversePInvokeTransitionFrame { @@ -3129,8 +3117,8 @@ private void setEHcount(uint cEH) private void setEHinfo(uint EHnumber, ref CORINFO_EH_CLAUSE clause) { - // Filters don't have class token in the clause.ClassTokenOrOffset - if ((clause.Flags & CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FILTER) == 0) + // Filters, finallys, and faults don't have class token in the clause.ClassTokenOrOffset + if ((clause.Flags & (CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FILTER | CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FINALLY | CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FAULT)) == 0) { if (clause.ClassTokenOrOffset != 0) { diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs index 3170dadd9dcafd..e162ae0569e02f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs @@ -87,7 +87,7 @@ public GcInfo() { } /// /// based on GcInfoDecoder::GcInfoDecoder /// - public GcInfo(byte[] image, int offset, Machine machine, ushort majorVersion, ushort minorVersion) + public GcInfo(NativeReader imageReader, int offset, Machine machine, ushort majorVersion, ushort minorVersion) { Offset = offset; Version = ReadyToRunVersionToGcInfoVersion(majorVersion, minorVersion); @@ -106,98 +106,98 @@ public GcInfo(byte[] image, int offset, Machine machine, ushort majorVersion, us int bitOffset = offset * 8; - ParseHeaderFlags(image, ref bitOffset); + ParseHeaderFlags(imageReader, ref bitOffset); if (Version >= MIN_GCINFO_VERSION_WITH_RETURN_KIND && Version <= MAX_GCINFO_VERSION_WITH_RETURN_KIND) // IsReturnKindAvailable { int returnKindBits = (_slimHeader) ? _gcInfoTypes.SIZE_OF_RETURN_KIND_SLIM : _gcInfoTypes.SIZE_OF_RETURN_KIND_FAT; - ReturnKind = (ReturnKinds)NativeReader.ReadBits(image, returnKindBits, ref bitOffset); + ReturnKind = (ReturnKinds)imageReader.ReadBits(returnKindBits, ref bitOffset); } - CodeLength = _gcInfoTypes.DenormalizeCodeLength((int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.CODE_LENGTH_ENCBASE, ref bitOffset)); + CodeLength = _gcInfoTypes.DenormalizeCodeLength((int)imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.CODE_LENGTH_ENCBASE, ref bitOffset)); if (_hasGSCookie) { - uint normPrologSize = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NORM_PROLOG_SIZE_ENCBASE, ref bitOffset) + 1; - uint normEpilogSize = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NORM_EPILOG_SIZE_ENCBASE, ref bitOffset); + uint normPrologSize = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.NORM_PROLOG_SIZE_ENCBASE, ref bitOffset) + 1; + uint normEpilogSize = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.NORM_EPILOG_SIZE_ENCBASE, ref bitOffset); ValidRangeStart = _gcInfoTypes.DenormalizeCodeOffset(normPrologSize); ValidRangeEnd = (uint)CodeLength - _gcInfoTypes.DenormalizeCodeOffset(normEpilogSize); } else if (_hasSecurityObject || _hasGenericsInstContext) { - uint normValidRangeStart = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NORM_PROLOG_SIZE_ENCBASE, ref bitOffset) + 1; + uint normValidRangeStart = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.NORM_PROLOG_SIZE_ENCBASE, ref bitOffset) + 1; ValidRangeStart = _gcInfoTypes.DenormalizeCodeOffset(normValidRangeStart); ValidRangeEnd = ValidRangeStart + 1; } if (_hasSecurityObject) { - SecurityObjectStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.SECURITY_OBJECT_STACK_SLOT_ENCBASE, ref bitOffset)); + SecurityObjectStackSlot = _gcInfoTypes.DenormalizeStackSlot(imageReader.DecodeVarLengthSigned(_gcInfoTypes.SECURITY_OBJECT_STACK_SLOT_ENCBASE, ref bitOffset)); } if (_hasGSCookie) { - GSCookieStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.GS_COOKIE_STACK_SLOT_ENCBASE, ref bitOffset)); + GSCookieStackSlot = _gcInfoTypes.DenormalizeStackSlot(imageReader.DecodeVarLengthSigned(_gcInfoTypes.GS_COOKIE_STACK_SLOT_ENCBASE, ref bitOffset)); } if (_hasPSPSym) { - PSPSymStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.PSP_SYM_STACK_SLOT_ENCBASE, ref bitOffset)); + PSPSymStackSlot = _gcInfoTypes.DenormalizeStackSlot(imageReader.DecodeVarLengthSigned(_gcInfoTypes.PSP_SYM_STACK_SLOT_ENCBASE, ref bitOffset)); } if (_hasGenericsInstContext) { - GenericsInstContextStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.GENERICS_INST_CONTEXT_STACK_SLOT_ENCBASE, ref bitOffset)); + GenericsInstContextStackSlot = _gcInfoTypes.DenormalizeStackSlot(imageReader.DecodeVarLengthSigned(_gcInfoTypes.GENERICS_INST_CONTEXT_STACK_SLOT_ENCBASE, ref bitOffset)); } if (_hasStackBaseRegister && !_slimHeader) { - StackBaseRegister = _gcInfoTypes.DenormalizeStackBaseRegister(NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.STACK_BASE_REGISTER_ENCBASE, ref bitOffset)); + StackBaseRegister = _gcInfoTypes.DenormalizeStackBaseRegister(imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.STACK_BASE_REGISTER_ENCBASE, ref bitOffset)); } if (_hasSizeOfEditAndContinuePreservedArea) { - SizeOfEditAndContinuePreservedArea = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE, ref bitOffset); + SizeOfEditAndContinuePreservedArea = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE, ref bitOffset); } if (_hasReversePInvokeFrame) { - ReversePInvokeFrameStackSlot = NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.REVERSE_PINVOKE_FRAME_ENCBASE, ref bitOffset); + ReversePInvokeFrameStackSlot = imageReader.DecodeVarLengthSigned(_gcInfoTypes.REVERSE_PINVOKE_FRAME_ENCBASE, ref bitOffset); } // FIXED_STACK_PARAMETER_SCRATCH_AREA (this macro is always defined in _gcInfoTypes.h) if (!_slimHeader) { - SizeOfStackOutgoingAndScratchArea = _gcInfoTypes.DenormalizeSizeOfStackArea(NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.SIZE_OF_STACK_AREA_ENCBASE, ref bitOffset)); + SizeOfStackOutgoingAndScratchArea = _gcInfoTypes.DenormalizeSizeOfStackArea(imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.SIZE_OF_STACK_AREA_ENCBASE, ref bitOffset)); } // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED (this macro is always defined in _gcInfoTypes.h) - NumSafePoints = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NUM_SAFE_POINTS_ENCBASE, ref bitOffset); + NumSafePoints = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.NUM_SAFE_POINTS_ENCBASE, ref bitOffset); if (!_slimHeader) { - NumInterruptibleRanges = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NUM_INTERRUPTIBLE_RANGES_ENCBASE, ref bitOffset); + NumInterruptibleRanges = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.NUM_INTERRUPTIBLE_RANGES_ENCBASE, ref bitOffset); } // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED (this macro is always defined in _gcInfoTypes.h) - SafePointOffsets = EnumerateSafePoints(image, ref bitOffset); + SafePointOffsets = EnumerateSafePoints(imageReader, ref bitOffset); - InterruptibleRanges = EnumerateInterruptibleRanges(image, _gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA1_ENCBASE, _gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA2_ENCBASE, ref bitOffset); + InterruptibleRanges = EnumerateInterruptibleRanges(imageReader, _gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA1_ENCBASE, _gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA2_ENCBASE, ref bitOffset); - SlotTable = new GcSlotTable(image, machine, _gcInfoTypes, ref bitOffset); + SlotTable = new GcSlotTable(imageReader, machine, _gcInfoTypes, ref bitOffset); if (SlotTable.NumSlots > 0) { if (NumSafePoints > 0) { // Partially interruptible code - LiveSlotsAtSafepoints = GetLiveSlotsAtSafepoints(image, ref bitOffset); + LiveSlotsAtSafepoints = GetLiveSlotsAtSafepoints(imageReader, ref bitOffset); } else { // Fully interruptible code - Transitions = GetTransitions(image, ref bitOffset); + Transitions = GetTransitions(imageReader, ref bitOffset); } } @@ -326,18 +326,18 @@ public override string ToString() /// /// based on GcInfoDecoder::GcInfoDecoder /// - private void ParseHeaderFlags(byte[] image, ref int bitOffset) + private void ParseHeaderFlags(NativeReader imageReader, ref int bitOffset) { GcInfoHeaderFlags headerFlags; - _slimHeader = (NativeReader.ReadBits(image, 1, ref bitOffset) == 0); + _slimHeader = (imageReader.ReadBits(1, ref bitOffset) == 0); if (_slimHeader) { - headerFlags = NativeReader.ReadBits(image, 1, ref bitOffset) == 1 ? GcInfoHeaderFlags.GC_INFO_HAS_STACK_BASE_REGISTER : 0; + headerFlags = imageReader.ReadBits(1, ref bitOffset) == 1 ? GcInfoHeaderFlags.GC_INFO_HAS_STACK_BASE_REGISTER : 0; } else { int numFlagBits = (int)((Version == 1) ? GcInfoHeaderFlags.GC_INFO_FLAGS_BIT_SIZE_VERSION_1 : GcInfoHeaderFlags.GC_INFO_FLAGS_BIT_SIZE); - headerFlags = (GcInfoHeaderFlags)NativeReader.ReadBits(image, numFlagBits, ref bitOffset); + headerFlags = (GcInfoHeaderFlags)imageReader.ReadBits(numFlagBits, ref bitOffset); } _hasSecurityObject = (headerFlags & GcInfoHeaderFlags.GC_INFO_HAS_SECURITY_OBJECT) != 0; @@ -353,13 +353,13 @@ private void ParseHeaderFlags(byte[] image, ref int bitOffset) _wantsReportOnlyLeaf = ((headerFlags & GcInfoHeaderFlags.GC_INFO_WANTS_REPORT_ONLY_LEAF) != 0); } - private List EnumerateSafePoints(byte[] image, ref int bitOffset) + private List EnumerateSafePoints(NativeReader imageReader, ref int bitOffset) { List safePoints = new List(); uint numBitsPerOffset = GcInfoTypes.CeilOfLog2((int)_gcInfoTypes.NormalizeCodeOffset((uint)CodeLength)); for (int i = 0; i < NumSafePoints; i++) { - uint normOffset = (uint)NativeReader.ReadBits(image, (int)numBitsPerOffset, ref bitOffset); + uint normOffset = (uint)imageReader.ReadBits((int)numBitsPerOffset, ref bitOffset); safePoints.Add(new SafePointOffset(i, _gcInfoTypes.DenormalizeCodeOffset(normOffset))); } return safePoints; @@ -368,15 +368,15 @@ private List EnumerateSafePoints(byte[] image, ref int bitOffse /// /// based on beginning of GcInfoDecoder::EnumerateLiveSlots /// - private List EnumerateInterruptibleRanges(byte[] image, int interruptibleRangeDelta1EncBase, int interruptibleRangeDelta2EncBase, ref int bitOffset) + private List EnumerateInterruptibleRanges(NativeReader imageReader, int interruptibleRangeDelta1EncBase, int interruptibleRangeDelta2EncBase, ref int bitOffset) { List ranges = new List(); uint normLastinterruptibleRangeStopOffset = 0; for (uint i = 0; i < NumInterruptibleRanges; i++) { - uint normStartDelta = NativeReader.DecodeVarLengthUnsigned(image, interruptibleRangeDelta1EncBase, ref bitOffset); - uint normStopDelta = NativeReader.DecodeVarLengthUnsigned(image, interruptibleRangeDelta2EncBase, ref bitOffset) + 1; + uint normStartDelta = imageReader.DecodeVarLengthUnsigned(interruptibleRangeDelta1EncBase, ref bitOffset); + uint normStopDelta = imageReader.DecodeVarLengthUnsigned(interruptibleRangeDelta2EncBase, ref bitOffset) + 1; uint normRangeStartOffset = normLastinterruptibleRangeStopOffset + normStartDelta; uint normRangeStopOffset = normRangeStartOffset + normStopDelta; @@ -411,7 +411,7 @@ private int ReadyToRunVersionToGcInfoVersion(int readyToRunMajorVersion, int rea return 4; } - private List> GetLiveSlotsAtSafepoints(byte[] image, ref int bitOffset) + private List> GetLiveSlotsAtSafepoints(NativeReader imageReader, ref int bitOffset) { // For each safe point, enumerates a list of GC slots that are alive at that point var result = new List>(); @@ -423,9 +423,9 @@ private List> GetLiveSlotsAtSafepoints(byte[] image, ref int bi uint numBitsPerOffset = 0; // Duplicate the encoder's heuristic to determine if we have indirect live // slot table (similar to the chunk pointers) - if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + if (imageReader.ReadBits(1, ref bitOffset) != 0) { - numBitsPerOffset = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.POINTER_SIZE_ENCBASE, ref bitOffset) + 1; + numBitsPerOffset = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.POINTER_SIZE_ENCBASE, ref bitOffset) + 1; Debug.Assert(numBitsPerOffset != 0); } @@ -441,20 +441,20 @@ private List> GetLiveSlotsAtSafepoints(byte[] image, ref int bi { bitOffset += (int)(numBitsPerOffset * safePointIndex); - uint liveStatesOffset = (uint)NativeReader.ReadBits(image, (int)numBitsPerOffset, ref bitOffset); + uint liveStatesOffset = (uint)imageReader.ReadBits((int)numBitsPerOffset, ref bitOffset); uint liveStatesStart = (uint)((offsetTablePos + NumSafePoints * numBitsPerOffset + 7) & (~7)); bitOffset = (int)(liveStatesStart + liveStatesOffset); - if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + if (imageReader.ReadBits(1, ref bitOffset) != 0) { // RLE encoded - bool skip = NativeReader.ReadBits(image, 1, ref bitOffset) == 0; + bool skip = imageReader.ReadBits(1, ref bitOffset) == 0; bool report = true; - uint readSlots = NativeReader.DecodeVarLengthUnsigned(image, + uint readSlots = imageReader.DecodeVarLengthUnsigned( skip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset); skip = !skip; while (readSlots < numSlots) { - uint cnt = NativeReader.DecodeVarLengthUnsigned(image, + uint cnt = imageReader.DecodeVarLengthUnsigned( skip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset) + 1; if (report) { @@ -492,7 +492,7 @@ private List> GetLiveSlotsAtSafepoints(byte[] image, ref int bi for (uint slotIndex = 0; slotIndex < numSlots; slotIndex++) { - bool isLive = NativeReader.ReadBits(image, 1, ref bitOffset) != 0; + bool isLive = imageReader.ReadBits(1, ref bitOffset) != 0; if (isLive) { int trackedSlotIndex = 0; @@ -520,7 +520,7 @@ private List> GetLiveSlotsAtSafepoints(byte[] image, ref int bi /// /// based on end of GcInfoDecoder::EnumerateLiveSlots and GcInfoEncoder::Build /// - private Dictionary> GetTransitions(byte[] image, ref int bitOffset) + private Dictionary> GetTransitions(NativeReader imageReader, ref int bitOffset) { int totalInterruptibleLength = 0; if (NumInterruptibleRanges == 0) @@ -532,7 +532,7 @@ private Dictionary> GetTransitions(byte[] image, ref foreach (InterruptibleRange range in InterruptibleRanges) { uint normStart = _gcInfoTypes.NormalizeCodeOffset(range.StartOffset); - uint normStop = _gcInfoTypes.NormalizeCodeOffset(range.StopOffset); + uint normStop = _gcInfoTypes.NormalizeCodeOffset(range.StopOffset); totalInterruptibleLength += (int)(normStop - normStart); } } @@ -541,7 +541,7 @@ private Dictionary> GetTransitions(byte[] image, ref return new Dictionary>(); int numChunks = (totalInterruptibleLength + _gcInfoTypes.NUM_NORM_CODE_OFFSETS_PER_CHUNK - 1) / _gcInfoTypes.NUM_NORM_CODE_OFFSETS_PER_CHUNK; - int numBitsPerPointer = (int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.POINTER_SIZE_ENCBASE, ref bitOffset); + int numBitsPerPointer = (int)imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.POINTER_SIZE_ENCBASE, ref bitOffset); if (numBitsPerPointer == 0) { return new Dictionary>(); @@ -551,7 +551,7 @@ private Dictionary> GetTransitions(byte[] image, ref int[] chunkPointers = new int[numChunks]; for (int i = 0; i < numChunks; i++) { - chunkPointers[i] = NativeReader.ReadBits(image, numBitsPerPointer, ref bitOffset); + chunkPointers[i] = imageReader.ReadBits(numBitsPerPointer, ref bitOffset); } // Offset to m_Info2 containing all the info on register liveness, which starts at the next byte @@ -572,16 +572,16 @@ private Dictionary> GetTransitions(byte[] image, ref int couldBeLiveOffset = bitOffset; // points to the couldBeLive bit array (array of bits indicating the slot changed state in the chunk) int slotId = 0; - bool fSimple = (NativeReader.ReadBits(image, 1, ref couldBeLiveOffset) == 0); + bool fSimple = (imageReader.ReadBits(1, ref couldBeLiveOffset) == 0); bool fSkipFirst = false; int couldBeLiveCnt = 0; if (!fSimple) { - fSkipFirst = (NativeReader.ReadBits(image, 1, ref couldBeLiveOffset) == 0); + fSkipFirst = (imageReader.ReadBits(1, ref couldBeLiveOffset) == 0); slotId = -1; } - uint numCouldBeLiveSlots = GetNumCouldBeLiveSlots(image, ref bitOffset); // count the number of set bits in the couldBeLive array + uint numCouldBeLiveSlots = GetNumCouldBeLiveSlots(imageReader, ref bitOffset); // count the number of set bits in the couldBeLive array int finalStateOffset = bitOffset; // points to the finalState bit array (array of bits indicating if the slot is live at the end of the chunk) bitOffset += (int)numCouldBeLiveSlots; // points to the array of code offsets @@ -590,16 +590,16 @@ private Dictionary> GetTransitions(byte[] image, ref for (int i = 0; i < numCouldBeLiveSlots; i++) { // get the index of the next couldBeLive slot - slotId = GetNextSlotId(image, fSimple, fSkipFirst, slotId, ref couldBeLiveCnt, ref couldBeLiveOffset); + slotId = GetNextSlotId(imageReader, fSimple, fSkipFirst, slotId, ref couldBeLiveCnt, ref couldBeLiveOffset); // set the liveAtEnd for the slot at slotId bool isLive = !liveAtEnd[slotId]; - liveAtEnd[slotId] = (NativeReader.ReadBits(image, 1, ref finalStateOffset) != 0); + liveAtEnd[slotId] = (imageReader.ReadBits(1, ref finalStateOffset) != 0); // Read all the code offsets where the slot at slotId changed state - while (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + while (imageReader.ReadBits(1, ref bitOffset) != 0) { - int transitionOffset = NativeReader.ReadBits(image, _gcInfoTypes.NUM_NORM_CODE_OFFSETS_PER_CHUNK_LOG2, ref bitOffset) + normChunkBaseCodeOffset; + int transitionOffset = imageReader.ReadBits(_gcInfoTypes.NUM_NORM_CODE_OFFSETS_PER_CHUNK_LOG2, ref bitOffset) + normChunkBaseCodeOffset; transitions.Add(new GcTransition(transitionOffset, slotId, isLive, currentChunk, SlotTable, _machine)); isLive = !isLive; } @@ -612,20 +612,20 @@ private Dictionary> GetTransitions(byte[] image, ref return UpdateTransitionCodeOffset(transitions); } - private uint GetNumCouldBeLiveSlots(byte[] image, ref int bitOffset) + private uint GetNumCouldBeLiveSlots(NativeReader imageReader, ref int bitOffset) { uint numCouldBeLiveSlots = 0; uint numTracked = SlotTable.NumTracked; - if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + if (imageReader.ReadBits(1, ref bitOffset) != 0) { // RLE encoded - bool fSkip = (NativeReader.ReadBits(image, 1, ref bitOffset) == 0); + bool fSkip = (imageReader.ReadBits(1, ref bitOffset) == 0); bool fReport = true; - uint readSlots = NativeReader.DecodeVarLengthUnsigned(image, fSkip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset); + uint readSlots = imageReader.DecodeVarLengthUnsigned(fSkip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset); fSkip = !fSkip; while (readSlots < numTracked) { - uint cnt = NativeReader.DecodeVarLengthUnsigned(image, fSkip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset) + 1; + uint cnt = imageReader.DecodeVarLengthUnsigned(fSkip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset) + 1; if (fReport) { numCouldBeLiveSlots += cnt; @@ -644,7 +644,7 @@ private uint GetNumCouldBeLiveSlots(byte[] image, ref int bitOffset) if ((slot.Flags & GcSlotFlags.GC_SLOT_UNTRACKED) != 0) break; - if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + if (imageReader.ReadBits(1, ref bitOffset) != 0) numCouldBeLiveSlots++; } } @@ -652,12 +652,12 @@ private uint GetNumCouldBeLiveSlots(byte[] image, ref int bitOffset) return numCouldBeLiveSlots; } - private int GetNextSlotId(byte[] image, bool fSimple, bool fSkipFirst, int slotId, ref int couldBeLiveCnt, ref int couldBeLiveOffset) + private int GetNextSlotId(NativeReader imageReader, bool fSimple, bool fSkipFirst, int slotId, ref int couldBeLiveCnt, ref int couldBeLiveOffset) { if (fSimple) { // Get the slotId by iterating through the couldBeLive bit array. The slotId is the index of the next set bit - while (NativeReader.ReadBits(image, 1, ref couldBeLiveOffset) == 0) + while (imageReader.ReadBits(1, ref couldBeLiveOffset) == 0) slotId++; } else if (couldBeLiveCnt > 0) @@ -668,15 +668,15 @@ private int GetNextSlotId(byte[] image, bool fSimple, bool fSkipFirst, int slotI // We need to find a new run else if (fSkipFirst) { - int tmp = (int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE, ref couldBeLiveOffset) + 1; + int tmp = (int)imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE, ref couldBeLiveOffset) + 1; slotId += tmp; - couldBeLiveCnt = (int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref couldBeLiveOffset); + couldBeLiveCnt = (int)imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref couldBeLiveOffset); } else { - int tmp = (int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref couldBeLiveOffset) + 1; + int tmp = (int)imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref couldBeLiveOffset) + 1; slotId += tmp; - couldBeLiveCnt = (int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE, ref couldBeLiveOffset); + couldBeLiveCnt = (int)imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE, ref couldBeLiveOffset); } return slotId; } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs index d5ac7048589c29..bd633fbbc9e406 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs @@ -104,33 +104,33 @@ public GcSlotTable() { } /// /// based on GcSlotDecoder::DecodeSlotTable /// - public GcSlotTable(byte[] image, Machine machine, GcInfoTypes gcInfoTypes, ref int bitOffset) + public GcSlotTable(NativeReader imageReader, Machine machine, GcInfoTypes gcInfoTypes, ref int bitOffset) { _machine = machine; - if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + if (imageReader.ReadBits(1, ref bitOffset) != 0) { - NumRegisters = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.NUM_REGISTERS_ENCBASE, ref bitOffset); + NumRegisters = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.NUM_REGISTERS_ENCBASE, ref bitOffset); } - if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + if (imageReader.ReadBits(1, ref bitOffset) != 0) { - NumStackSlots = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.NUM_STACK_SLOTS_ENCBASE, ref bitOffset); - NumUntracked = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.NUM_UNTRACKED_SLOTS_ENCBASE, ref bitOffset); + NumStackSlots = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.NUM_STACK_SLOTS_ENCBASE, ref bitOffset); + NumUntracked = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.NUM_UNTRACKED_SLOTS_ENCBASE, ref bitOffset); } NumSlots = NumRegisters + NumStackSlots + NumUntracked; GcSlots = new List(); if (NumRegisters > 0) { - DecodeRegisters(image, gcInfoTypes, ref bitOffset); + DecodeRegisters(imageReader, gcInfoTypes, ref bitOffset); } if (NumStackSlots > 0) { - DecodeStackSlots(image, machine, gcInfoTypes, NumStackSlots, false, ref bitOffset); + DecodeStackSlots(imageReader, machine, gcInfoTypes, NumStackSlots, false, ref bitOffset); } if (NumUntracked > 0) { - DecodeStackSlots(image, machine, gcInfoTypes, NumUntracked, true, ref bitOffset); + DecodeStackSlots(imageReader, machine, gcInfoTypes, NumUntracked, true, ref bitOffset); } } @@ -150,50 +150,50 @@ public override string ToString() return sb.ToString(); } - private void DecodeRegisters(byte[] image, GcInfoTypes gcInfoTypes, ref int bitOffset) + private void DecodeRegisters(NativeReader imageReader, GcInfoTypes gcInfoTypes, ref int bitOffset) { // We certainly predecode the first register - uint regNum = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.REGISTER_ENCBASE, ref bitOffset); - GcSlotFlags flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset); + uint regNum = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.REGISTER_ENCBASE, ref bitOffset); + GcSlotFlags flags = (GcSlotFlags)imageReader.ReadBits(2, ref bitOffset); GcSlots.Add(new GcSlot(GcSlots.Count, (int)regNum, null, flags)); for (int i = 1; i < NumRegisters; i++) { if ((uint)flags != 0) { - regNum = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.REGISTER_ENCBASE, ref bitOffset); - flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset); + regNum = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.REGISTER_ENCBASE, ref bitOffset); + flags = (GcSlotFlags)imageReader.ReadBits(2, ref bitOffset); } else { - uint regDelta = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.REGISTER_DELTA_ENCBASE, ref bitOffset) + 1; + uint regDelta = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.REGISTER_DELTA_ENCBASE, ref bitOffset) + 1; regNum += regDelta; } GcSlots.Add(new GcSlot(GcSlots.Count, (int)regNum, null, flags)); } } - private void DecodeStackSlots(byte[] image, Machine machine, GcInfoTypes gcInfoTypes, uint nSlots, bool isUntracked, ref int bitOffset) + private void DecodeStackSlots(NativeReader imageReader, Machine machine, GcInfoTypes gcInfoTypes, uint nSlots, bool isUntracked, ref int bitOffset) { // We have stack slots left and more room to predecode - GcStackSlotBase spBase = (GcStackSlotBase)NativeReader.ReadBits(image, 2, ref bitOffset); - int normSpOffset = NativeReader.DecodeVarLengthSigned(image, gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset); + GcStackSlotBase spBase = (GcStackSlotBase)imageReader.ReadBits(2, ref bitOffset); + int normSpOffset = imageReader.DecodeVarLengthSigned(gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset); int spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset); - GcSlotFlags flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset); + GcSlotFlags flags = (GcSlotFlags)imageReader.ReadBits(2, ref bitOffset); GcSlots.Add(new GcSlot(GcSlots.Count, -1, new GcStackSlot(spOffset, spBase), flags, isUntracked)); for (int i = 1; i < nSlots; i++) { - spBase = (GcStackSlotBase)NativeReader.ReadBits(image, 2, ref bitOffset); + spBase = (GcStackSlotBase)imageReader.ReadBits(2, ref bitOffset); if ((uint)flags != 0) { - normSpOffset = NativeReader.DecodeVarLengthSigned(image, gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset); + normSpOffset = imageReader.DecodeVarLengthSigned(gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset); spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset); - flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset); + flags = (GcSlotFlags)imageReader.ReadBits(2, ref bitOffset); } else { - int normSpOffsetDelta = NativeReader.DecodeVarLengthSigned(image, gcInfoTypes.STACK_SLOT_DELTA_ENCBASE, ref bitOffset); + int normSpOffsetDelta = imageReader.DecodeVarLengthSigned(gcInfoTypes.STACK_SLOT_DELTA_ENCBASE, ref bitOffset); normSpOffset += normSpOffsetDelta; spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset); } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs index 8cc66d025abbdf..9b89b3b5755d55 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs @@ -61,10 +61,10 @@ public UnwindCode() { } /// /// Unwind code parsing is based on src\jit\unwindamd64.cpp DumpUnwindInfo /// - public UnwindCode(byte[] image, ref int frameOffset, ref int offset) + public UnwindCode(NativeReader imageReader, ref int frameOffset, ref int offset) { - CodeOffset = NativeReader.ReadByte(image, ref offset); - byte op = NativeReader.ReadByte(image, ref offset); + CodeOffset = imageReader.ReadByte(ref offset); + byte op = imageReader.ReadByte(ref offset); UnwindOp = (UnwindOpCodes)(op & 15); OpInfo = (byte)(op >> 4); @@ -83,13 +83,13 @@ public UnwindCode(byte[] image, ref int frameOffset, ref int offset) if (OpInfo == 0) { OpInfoStr += "Scaled small"; - NextFrameOffset = 8 * NativeReader.ReadUInt16(image, ref offset); + NextFrameOffset = 8 * imageReader.ReadUInt16(ref offset); } else if (OpInfo == 1) { OpInfoStr += "Unscaled large"; - uint nextOffset = NativeReader.ReadUInt16(image, ref offset); - NextFrameOffset = (int)((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset); + uint nextOffset = imageReader.ReadUInt16(ref offset); + NextFrameOffset = (int)((uint)(imageReader.ReadUInt16(ref offset) << 16) | nextOffset); } else { @@ -104,43 +104,43 @@ public UnwindCode(byte[] image, ref int frameOffset, ref int offset) OpInfoStr = $"Unused({OpInfo})"; break; case UnwindOpCodes.UWOP_SET_FPREG_LARGE: + { + OpInfoStr = $"Unused({OpInfo})"; + uint nextOffset = imageReader.ReadUInt16(ref offset); + nextOffset = ((uint)(imageReader.ReadUInt16(ref offset) << 16) | nextOffset); + NextFrameOffset = (int)nextOffset * 16; + if ((NextFrameOffset & 0xF0000000) != 0) { - OpInfoStr = $"Unused({OpInfo})"; - uint nextOffset = NativeReader.ReadUInt16(image, ref offset); - nextOffset = ((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset); - NextFrameOffset = (int)nextOffset * 16; - if ((NextFrameOffset & 0xF0000000) != 0) - { - throw new BadImageFormatException("Warning: Illegal unwindInfo unscaled offset: too large"); - } + throw new BadImageFormatException("Warning: Illegal unwindInfo unscaled offset: too large"); } - break; + } + break; case UnwindOpCodes.UWOP_SAVE_NONVOL: - { - OpInfoStr = $"{(Registers)OpInfo}({OpInfo})"; - NextFrameOffset = NativeReader.ReadUInt16(image, ref offset) * 8; - } - break; + { + OpInfoStr = $"{(Registers)OpInfo}({OpInfo})"; + NextFrameOffset = imageReader.ReadUInt16(ref offset) * 8; + } + break; case UnwindOpCodes.UWOP_SAVE_NONVOL_FAR: - { - OpInfoStr = $"{(Registers)OpInfo}({OpInfo})"; - uint nextOffset = NativeReader.ReadUInt16(image, ref offset); - NextFrameOffset = (int)((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset); - } - break; + { + OpInfoStr = $"{(Registers)OpInfo}({OpInfo})"; + uint nextOffset = imageReader.ReadUInt16(ref offset); + NextFrameOffset = (int)((uint)(imageReader.ReadUInt16(ref offset) << 16) | nextOffset); + } + break; case UnwindOpCodes.UWOP_SAVE_XMM128: - { - OpInfoStr = $"XMM{OpInfo}({OpInfo})"; - NextFrameOffset = (int)NativeReader.ReadUInt16(image, ref offset) * 16; - } - break; + { + OpInfoStr = $"XMM{OpInfo}({OpInfo})"; + NextFrameOffset = (int)imageReader.ReadUInt16(ref offset) * 16; + } + break; case UnwindOpCodes.UWOP_SAVE_XMM128_FAR: - { - OpInfoStr = $"XMM{OpInfo}({OpInfo})"; - uint nextOffset = NativeReader.ReadUInt16(image, ref offset); - NextFrameOffset = (int)((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset); - } - break; + { + OpInfoStr = $"XMM{OpInfo}({OpInfo})"; + uint nextOffset = imageReader.ReadUInt16(ref offset); + NextFrameOffset = (int)((uint)(imageReader.ReadUInt16(ref offset) << 16) | nextOffset); + } + break; default: throw new NotImplementedException(UnwindOp.ToString()); } @@ -172,14 +172,14 @@ public UnwindInfo() { } /// /// based on ZapUnwindData::Save /// - public UnwindInfo(byte[] image, int offset) + public UnwindInfo(NativeReader imageReader, int offset) { - byte versionAndFlags = NativeReader.ReadByte(image, ref offset); + byte versionAndFlags = imageReader.ReadByte(ref offset); Version = (byte)(versionAndFlags & 7); Flags = (byte)(versionAndFlags >> 3); - SizeOfProlog = NativeReader.ReadByte(image, ref offset); - CountOfUnwindCodes = NativeReader.ReadByte(image, ref offset); - byte frameRegisterAndOffset = NativeReader.ReadByte(image, ref offset); + SizeOfProlog = imageReader.ReadByte(ref offset); + CountOfUnwindCodes = imageReader.ReadByte(ref offset); + byte frameRegisterAndOffset = imageReader.ReadByte(ref offset); FrameRegister = (Registers)(frameRegisterAndOffset & 15); FrameOffset = (byte)(frameRegisterAndOffset >> 4); @@ -190,7 +190,7 @@ public UnwindInfo(byte[] image, int offset) int endOffset = offset + sizeOfUnwindCodes; while (offset < endOffset) { - UnwindCode unwindCode = new UnwindCode(image, ref frameOffset, ref offset); + UnwindCode unwindCode = new UnwindCode(imageReader, ref frameOffset, ref offset); CodeOffsetToUnwindCodeIndex.Add(unwindCode.CodeOffset, UnwindCodes.Count); UnwindCodes.Add(unwindCode); } @@ -201,7 +201,7 @@ public UnwindInfo(byte[] image, int offset) // Personality routine RVA must be at 4-aligned address offset += alignmentPad; - PersonalityRoutineRVA = NativeReader.ReadUInt32(image, ref offset); + PersonalityRoutineRVA = imageReader.ReadUInt32(ref offset); } public override string ToString() diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm/UnwindInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm/UnwindInfo.cs index 5a7d919910fe7b..4e6d81167f206b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm/UnwindInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm/UnwindInfo.cs @@ -75,11 +75,11 @@ public class UnwindInfo : BaseUnwindInfo public UnwindInfo() { } - public UnwindInfo(byte[] image, int offset) + public UnwindInfo(NativeReader imageReader, int offset) { uint startOffset = (uint)offset; - int dw = NativeReader.ReadInt32(image, ref offset); + int dw = imageReader.ReadInt32(ref offset); CodeWords = ExtractBits(dw, 28, 4); EpilogCount = ExtractBits(dw, 23, 5); FBit = ExtractBits(dw, 22, 1); @@ -92,7 +92,7 @@ public UnwindInfo(byte[] image, int offset) { // We have an extension word specifying a larger number of Code Words or Epilog Counts // than can be specified in the header word. - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); ExtendedCodeWords = ExtractBits(dw, 16, 8); ExtendedEpilogCount = ExtractBits(dw, 0, 16); } @@ -106,7 +106,7 @@ public UnwindInfo(byte[] image, int offset) { for (int scope = 0; scope < EpilogCount; scope++) { - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); Epilogs[scope] = new Epilog(scope, dw, startOffset); epilogStartAt[Epilogs[scope].EpilogStartIndex] = true; // an epilog starts at this offset in the unwind codes } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm64/UnwindInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm64/UnwindInfo.cs index c44e7c80833531..5809959d13aca8 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm64/UnwindInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm64/UnwindInfo.cs @@ -75,11 +75,11 @@ public class UnwindInfo : BaseUnwindInfo public UnwindInfo() { } - public UnwindInfo(byte[] image, int offset) + public UnwindInfo(NativeReader imageReader, int offset) { uint startOffset = (uint)offset; - int dw = NativeReader.ReadInt32(image, ref offset); + int dw = imageReader.ReadInt32(ref offset); CodeWords = ExtractBits(dw, 27, 5); EpilogCount = ExtractBits(dw, 22, 5); EBit = ExtractBits(dw, 21, 1); @@ -91,7 +91,7 @@ public UnwindInfo(byte[] image, int offset) { // We have an extension word specifying a larger number of Code Words or Epilog Counts // than can be specified in the header word. - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); ExtendedCodeWords = ExtractBits(dw, 16, 8); ExtendedEpilogCount = ExtractBits(dw, 0, 16); } @@ -105,7 +105,7 @@ public UnwindInfo(byte[] image, int offset) { for (int scope = 0; scope < EpilogCount; scope++) { - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); Epilogs[scope] = new Epilog(scope, dw, startOffset); epilogStartAt[Epilogs[scope].EpilogStartIndex] = true; // an epilog starts at this offset in the unwind codes } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs index f570dffdca505b..019b74c714b3a9 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs @@ -20,6 +20,7 @@ public class DebugInfo private readonly RuntimeFunction _runtimeFunction; private readonly int _offset; private List _boundsList; + private byte[] _boundsBytes; private List _variablesList; private Machine _machine; @@ -38,6 +39,15 @@ public List BoundsList } } + public byte[] BoundsBytes + { + get + { + EnsureInitialized(); + return _boundsBytes; + } + } + public List VariablesList { get @@ -92,12 +102,12 @@ private void EnsureInitialized() _boundsList = new List(); _variablesList = new List(); Machine machine = _readyToRunReader.Machine; - byte[] image = _readyToRunReader.Image; + NativeReader imageReader = _readyToRunReader.ImageReader; _machine = machine; // Get the id of the runtime function from the NativeArray uint lookback = 0; - uint debugInfoOffset = NativeReader.DecodeUnsigned(image, (uint)offset, ref lookback); + uint debugInfoOffset = imageReader.DecodeUnsigned((uint)offset, ref lookback); if (lookback != 0) { @@ -105,54 +115,118 @@ private void EnsureInitialized() debugInfoOffset = (uint)offset - lookback; } - NibbleReader reader = new NibbleReader(image, (int)debugInfoOffset); + NibbleReader reader = new NibbleReader(imageReader, (int)debugInfoOffset); uint boundsByteCount = reader.ReadUInt(); uint variablesByteCount = reader.ReadUInt(); int boundsOffset = reader.GetNextByteOffset(); int variablesOffset = (int)(boundsOffset + boundsByteCount); + _boundsBytes = new byte[boundsByteCount]; + int boundsOffsetMutable = boundsOffset; + imageReader.ReadSpanAt(ref boundsOffsetMutable, _boundsBytes.AsSpan()); + if (boundsByteCount > 0) { - ParseBounds(image, boundsOffset); + ParseBounds(imageReader, boundsOffset); } if (variablesByteCount > 0) { - ParseNativeVarInfo(image, variablesOffset); + ParseNativeVarInfo(imageReader, variablesOffset); } } - private void ParseBounds(byte[] image, int offset) + private void ParseBounds(NativeReader imageReader, int offset) { // Bounds info contains (Native Offset, IL Offset, flags) // - Sorted by native offset (so use a delta encoding for that). - // - IL offsets aren't sorted, but they should be close to each other (so a signed delta encoding) + // - IL offsets aren't sorted // They may also include a sentinel value from MappingTypes. // - flags is 3 independent bits. - NibbleReader reader = new NibbleReader(image, offset); - uint boundsEntryCount = reader.ReadUInt(); - Debug.Assert(boundsEntryCount > 0); + if (_runtimeFunction.ReadyToRunReader.ReadyToRunHeader.MajorVersion >= 16) + { + NibbleReader reader = new NibbleReader(imageReader, offset); + uint boundsEntryCount = reader.ReadUInt(); + Debug.Assert(boundsEntryCount > 0); + uint bitsForNativeDelta = reader.ReadUInt() + 1; // Number of bits needed for native deltas + uint bitsForILOffsets = reader.ReadUInt() + 1; // Number of bits needed for IL offsets + + uint bitsPerEntry = bitsForNativeDelta + bitsForILOffsets + 2; // 2 bits for source type + ulong bitsMeaningfulMask = (1UL << ((int)bitsPerEntry)) - 1; + int offsetOfActualBoundsData = reader.GetNextByteOffset(); + + uint bitsCollected = 0; + ulong bitTemp = 0; + uint curBoundsProcessed = 0; - uint previousNativeOffset = 0; - for (int i = 0; i < boundsEntryCount; ++i) + uint previousNativeOffset = 0; + + while (curBoundsProcessed < boundsEntryCount) + { + bitTemp |= ((uint)imageReader[offsetOfActualBoundsData++]) << (int)bitsCollected; + bitsCollected += 8; + while (bitsCollected >= bitsPerEntry) + { + ulong mappingDataEncoded = bitsMeaningfulMask & bitTemp; + bitTemp >>= (int)bitsPerEntry; + bitsCollected -= bitsPerEntry; + + var entry = new DebugInfoBoundsEntry(); + switch (mappingDataEncoded & 0x3) + { + case 0: + entry.SourceTypes = SourceTypes.SourceTypeInvalid; + break; + case 1: + entry.SourceTypes = SourceTypes.CallInstruction; + break; + case 2: + entry.SourceTypes = SourceTypes.StackEmpty; + break; + case 3: + entry.SourceTypes = SourceTypes.StackEmpty | SourceTypes.CallInstruction; + break; + } + mappingDataEncoded >>= 2; + uint nativeOffsetDelta = (uint)(mappingDataEncoded & ((1UL << (int)bitsForNativeDelta) - 1)); + previousNativeOffset += nativeOffsetDelta; + entry.NativeOffset = previousNativeOffset; + + mappingDataEncoded >>= (int)bitsForNativeDelta; + entry.ILOffset = (uint)(mappingDataEncoded) + (uint)DebugInfoBoundsType.MaxMappingValue; + + _boundsList.Add(entry); + curBoundsProcessed++; + } + } + } + else { - var entry = new DebugInfoBoundsEntry(); - previousNativeOffset += reader.ReadUInt(); - entry.NativeOffset = previousNativeOffset; - entry.ILOffset = reader.ReadUInt() + (uint)DebugInfoBoundsType.MaxMappingValue; - entry.SourceTypes = (SourceTypes)reader.ReadUInt(); - _boundsList.Add(entry); + NibbleReader reader = new NibbleReader(imageReader, offset); + uint boundsEntryCount = reader.ReadUInt(); + Debug.Assert(boundsEntryCount > 0); + + uint previousNativeOffset = 0; + for (int i = 0; i < boundsEntryCount; ++i) + { + var entry = new DebugInfoBoundsEntry(); + previousNativeOffset += reader.ReadUInt(); + entry.NativeOffset = previousNativeOffset; + entry.ILOffset = reader.ReadUInt() + (uint)DebugInfoBoundsType.MaxMappingValue; + entry.SourceTypes = (SourceTypes)reader.ReadUInt(); + _boundsList.Add(entry); + } } } - private void ParseNativeVarInfo(byte[] image, int offset) + private void ParseNativeVarInfo(NativeReader imageReader, int offset) { // Each Varinfo has a: // - native start +End offset. We can use a delta for the end offset. // - Il variable number. These are usually small. // - VarLoc information. This is a tagged variant. // The entries aren't sorted in any particular order. - NibbleReader reader = new NibbleReader(image, offset); + NibbleReader reader = new NibbleReader(imageReader, offset); uint nativeVarCount = reader.ReadUInt(); for (int i = 0; i < nativeVarCount; ++i) diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj index f60794a8abf0be..71981555136054 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj @@ -7,8 +7,7 @@ AnyCPU Open true - - netstandard2.0 + $(NetCoreAppMinimum) false $(NoWarn);8002;NU1701 win-x64;win-x86 @@ -16,11 +15,6 @@ AnyCPU;x64 AnyCPU false - - false diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection.cs index c67582623af7fc..4d3a6ea4fc8ad6 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection.cs @@ -24,14 +24,14 @@ public override string ToString() StringBuilder sb = new StringBuilder(); int iiOffset = _startOffset; - int sizeOfInlineIndex = NativeReader.ReadInt32(_r2r.Image, ref iiOffset); + int sizeOfInlineIndex = _r2r.ImageReader.ReadInt32(ref iiOffset); int inlineIndexEndOffset = iiOffset + sizeOfInlineIndex; while (iiOffset < inlineIndexEndOffset) { - int inlineeRid = NativeReader.ReadInt32(_r2r.Image, ref iiOffset); - int inlinersOffset = NativeReader.ReadInt32(_r2r.Image, ref iiOffset); + int inlineeRid = _r2r.ImageReader.ReadInt32(ref iiOffset); + int inlinersOffset = _r2r.ImageReader.ReadInt32(ref iiOffset); sb.AppendLine($"Inliners for inlinee {RidToMethodDef(inlineeRid):X8}:"); - var inlinersReader = new NibbleReader(_r2r.Image, inlineIndexEndOffset + inlinersOffset); + var inlinersReader = new NibbleReader(_r2r.ImageReader, inlineIndexEndOffset + inlinersOffset); uint sameModuleCount = inlinersReader.ReadUInt(); int baseRid = 0; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection2.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection2.cs index 46399743450124..036c771e1bb215 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection2.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection2.cs @@ -23,8 +23,8 @@ public override string ToString() { StringBuilder sb = new StringBuilder(); - NativeParser parser = new NativeParser(_r2r.Image, (uint)_startOffset); - NativeHashtable hashtable = new NativeHashtable(_r2r.Image, parser, (uint)_endOffset); + NativeParser parser = new NativeParser(_r2r.ImageReader, (uint)_startOffset); + NativeHashtable hashtable = new NativeHashtable(_r2r.ImageReader, parser, (uint)_endOffset); var enumerator = hashtable.EnumerateAllEntries(); diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/LoongArch64/UnwindInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/LoongArch64/UnwindInfo.cs index 98fe6cbfdde3e1..803c565092d12e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/LoongArch64/UnwindInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/LoongArch64/UnwindInfo.cs @@ -75,11 +75,11 @@ public class UnwindInfo : BaseUnwindInfo public UnwindInfo() { } - public UnwindInfo(byte[] image, int offset) + public UnwindInfo(NativeReader imageReader, int offset) { uint startOffset = (uint)offset; - int dw = NativeReader.ReadInt32(image, ref offset); + int dw = imageReader.ReadInt32(ref offset); CodeWords = ExtractBits(dw, 27, 5); EpilogCount = ExtractBits(dw, 22, 5); EBit = ExtractBits(dw, 21, 1); @@ -91,7 +91,7 @@ public UnwindInfo(byte[] image, int offset) { // We have an extension word specifying a larger number of Code Words or Epilog Counts // than can be specified in the header word. - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); ExtendedCodeWords = ExtractBits(dw, 16, 8); ExtendedEpilogCount = ExtractBits(dw, 0, 16); } @@ -105,7 +105,7 @@ public UnwindInfo(byte[] image, int offset) { for (int scope = 0; scope < EpilogCount; scope++) { - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); Epilogs[scope] = new Epilog(scope, dw, startOffset); epilogStartAt[Epilogs[scope].EpilogStartIndex] = true; // an epilog starts at this offset in the unwind codes } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeArray.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeArray.cs index 7a9008100a23b5..c8810a66476500 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeArray.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeArray.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.IO; using System.Text; namespace ILCompiler.Reflection.ReadyToRun @@ -10,20 +11,21 @@ namespace ILCompiler.Reflection.ReadyToRun /// public class NativeArray { - // TODO (refactoring) - all these Native* class should be private private const int _blockSize = 16; + + private NativeReader _reader; private uint _baseOffset; private uint _nElements; private byte _entryIndexSize; - private byte[] _image; - public NativeArray(byte[] image, uint offset) + public NativeArray(NativeReader reader, uint offset) { + _reader = reader; + uint val = 0; - _baseOffset = NativeReader.DecodeUnsigned(image, offset, ref val); + _baseOffset = _reader.DecodeUnsigned(offset, ref val); _nElements = (val >> 2); _entryIndexSize = (byte)(val & 3); - _image = image; } public uint GetCount() @@ -40,7 +42,7 @@ public override string ToString() for (uint i = 0; i < _nElements; i++) { int val = 0; - if (TryGetAt(_image, i, ref val)) + if (TryGetAt(i, ref val)) { sb.AppendLine($"{i}: {val}"); } @@ -49,38 +51,38 @@ public override string ToString() return sb.ToString(); } - public bool TryGetAt(byte[] image, uint index, ref int pOffset) + public bool TryGetAt(uint index, ref int pOffset) { if (index >= _nElements) return false; - uint offset = 0; + uint offset; if (_entryIndexSize == 0) { int i = (int)(_baseOffset + (index / _blockSize)); - offset = NativeReader.ReadByte(image, ref i); + offset = _reader.ReadByte(ref i); } else if (_entryIndexSize == 1) { int i = (int)(_baseOffset + 2 * (index / _blockSize)); - offset = NativeReader.ReadUInt16(image, ref i); + offset = _reader.ReadUInt16(ref i); } else { int i = (int)(_baseOffset + 4 * (index / _blockSize)); - offset = NativeReader.ReadUInt32(image, ref i); + offset = _reader.ReadUInt32(ref i); } offset += _baseOffset; for (uint bit = _blockSize >> 1; bit > 0; bit >>= 1) { uint val = 0; - uint offset2 = NativeReader.DecodeUnsigned(image, offset, ref val); + uint offset2 = _reader.DecodeUnsigned(offset, ref val); if ((index & bit) != 0) { if ((val & 2) != 0) { - offset = offset + (val >> 2); + offset += val >> 2; continue; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeHashtable.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeHashtable.cs index efeeaf18584087..846a60e22d965c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeHashtable.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeHashtable.cs @@ -18,18 +18,18 @@ public struct NativeParser public uint Offset { get; set; } public byte LowHashcode { get; } - byte[] _image; + NativeReader _imageReader; - public NativeParser(byte[] image, uint offset, byte lowHashcode = 0) + public NativeParser(NativeReader imageReader, uint offset, byte lowHashcode = 0) { Offset = offset; LowHashcode = lowHashcode; - _image = image; + _imageReader = imageReader; } public bool IsNull() { - return _image == null; + return _imageReader == null; } public uint GetRelativeOffset() @@ -37,7 +37,7 @@ public uint GetRelativeOffset() uint pos = Offset; int delta = 0; - Offset = NativeReader.DecodeSigned(_image, Offset, ref delta); + Offset = _imageReader.DecodeSigned(Offset, ref delta); return pos + (uint)delta; } @@ -45,13 +45,13 @@ public uint GetRelativeOffset() public NativeParser GetParserFromRelativeOffset() { byte lowHashcode = GetByte(); - return new NativeParser(_image, GetRelativeOffset(), lowHashcode); + return new NativeParser(_imageReader, GetRelativeOffset(), lowHashcode); } public byte GetByte() { int off = (int)Offset; - byte val = NativeReader.ReadByte(_image, ref off); + byte val = _imageReader.ReadByte(ref off); Offset += 1; return val; } @@ -59,7 +59,7 @@ public byte GetByte() public uint GetCompressedData() { int off = (int)Offset; - uint val = NativeReader.ReadCompressedData(_image, ref off); + uint val = _imageReader.ReadCompressedData(ref off); Offset = (uint)off; return val; } @@ -67,14 +67,14 @@ public uint GetCompressedData() public uint GetUnsigned() { uint value = 0; - Offset = NativeReader.DecodeUnsigned(_image, Offset, ref value); + Offset = _imageReader.DecodeUnsigned(Offset, ref value); return value; } public int GetSigned() { int value = 0; - Offset = NativeReader.DecodeSigned(_image, Offset, ref value); + Offset = _imageReader.DecodeSigned(Offset, ref value); return value; } } @@ -85,17 +85,17 @@ public int GetSigned() public struct NativeHashtable { // TODO (refactoring) - all these Native* class should be private - private byte[] _image; + private NativeReader _imageReader; private uint _baseOffset; private uint _bucketMask; private byte _entryIndexSize; private uint _endOffset; - public NativeHashtable(byte[] image, NativeParser parser, uint endOffset) + public NativeHashtable(NativeReader imageReader, NativeParser parser, uint endOffset) { uint header = parser.GetByte(); _baseOffset = parser.Offset; - _image = image; + _imageReader = imageReader; int numberOfBucketsShift = (int)(header >> 2); if (numberOfBucketsShift > 31) @@ -134,7 +134,7 @@ public override string ToString() { for (int i = curOffset; i < nextOffset; i++) { - sb.Append($"{_image[i]:X2} "); + sb.Append($"{_imageReader[i]:X2} "); } sb.AppendLine(); } @@ -205,24 +205,24 @@ private NativeParser GetParserForBucket(uint bucket, out uint endOffset) if (_entryIndexSize == 0) { int bucketOffset = (int)(_baseOffset + bucket); - start = NativeReader.ReadByte(_image, ref bucketOffset); - end = NativeReader.ReadByte(_image, ref bucketOffset); + start = _imageReader.ReadByte(ref bucketOffset); + end = _imageReader.ReadByte(ref bucketOffset); } else if (_entryIndexSize == 1) { int bucketOffset = (int)(_baseOffset + 2 * bucket); - start = NativeReader.ReadUInt16(_image, ref bucketOffset); - end = NativeReader.ReadUInt16(_image, ref bucketOffset); + start = _imageReader.ReadUInt16(ref bucketOffset); + end = _imageReader.ReadUInt16(ref bucketOffset); } else { int bucketOffset = (int)(_baseOffset + 4 * bucket); - start = NativeReader.ReadUInt32(_image, ref bucketOffset); - end = NativeReader.ReadUInt32(_image, ref bucketOffset); + start = _imageReader.ReadUInt32(ref bucketOffset); + end = _imageReader.ReadUInt32(ref bucketOffset); } endOffset = end + _baseOffset; - return new NativeParser(_image, _baseOffset + start); + return new NativeParser(_imageReader, _baseOffset + start); } public Enumerator Lookup(int hashcode) @@ -246,13 +246,13 @@ public AllEntriesEnumerator EnumerateAllEntries() public struct NativeCuckooFilter { // TODO (refactoring) - all these Native* class should be private - private byte[] _image; + private NativeReader _imageReader; private int _filterStartOffset; private int _filterEndOffset; - public NativeCuckooFilter(byte[] image, int filterStartOffset, int filterEndOffset) + public NativeCuckooFilter(NativeReader imageReader, int filterStartOffset, int filterEndOffset) { - _image = image; + _imageReader = imageReader; _filterStartOffset = filterStartOffset; _filterEndOffset = filterEndOffset; @@ -271,7 +271,7 @@ private IEnumerable GetBuckets() ushort[] bucket = new ushort[8]; for (int i = 0; i < bucket.Length; i++) { - bucket[i] = NativeReader.ReadUInt16(_image, ref offset); + bucket[i] = _imageReader.ReadUInt16(ref offset); } yield return bucket; } @@ -283,7 +283,7 @@ public override string ToString() sb.AppendLine($"NativeCuckooFilter Size: {(_filterEndOffset - _filterStartOffset) / 16}"); int bucket = 0; - foreach (ushort [] bucketContents in GetBuckets()) + foreach (ushort[] bucketContents in GetBuckets()) { sb.Append($"Bucket: {bucket} ["); for (int i = 0; i < 8; i++) diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeReader.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeReader.cs index 2805a24d139ab0..b26a75790eeb89 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeReader.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeReader.cs @@ -2,122 +2,137 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Buffers.Binary; using System.Collections.Generic; +using System.IO; using System.Text; namespace ILCompiler.Reflection.ReadyToRun { - public class NativeReader + public class NativeReader(Stream backingStream, bool littleEndian = true) { - // TODO (refactoring) - all these Native* class should be private private const int BITS_PER_BYTE = 8; private const int BITS_PER_SIZE_T = 32; + private readonly Stream _backingStream = backingStream; + private readonly bool _littleEndian = littleEndian; + + /// + /// Reads a byte from the image at the specified index + /// + public int this[int index] + { + get => ReadByte(ref index); + } + + /// + /// Reads a span of bytes from the image at the specified start index + /// + /// Starting index of the value + /// Span to be filled with the read bytes + /// + /// The gets incremented by the size of the buffer + /// + public void ReadSpanAt(ref int start, Span buffer) + { + if (start < 0 || start + buffer.Length > _backingStream.Length) + throw new ArgumentOutOfRangeException(nameof(start), "Start index is out of bounds"); + + _backingStream.Seek(start, SeekOrigin.Begin); + _backingStream.ReadExactly(buffer); + start += buffer.Length; + } + /// /// Extracts a 64bit value from the image byte array /// - /// PE image /// Starting index of the value /// /// The gets incremented by the size of the value /// - public static long ReadInt64(byte[] image, ref int start) + public long ReadInt64(ref int start) { - int size = sizeof(long); - byte[] bytes = new byte[size]; - Array.Copy(image, start, bytes, 0, size); - start += size; - return BitConverter.ToInt64(bytes, 0); + Span bytes = stackalloc byte[sizeof(long)]; + ReadSpanAt(ref start, bytes); + return _littleEndian ? BinaryPrimitives.ReadInt64LittleEndian(bytes) : BinaryPrimitives.ReadInt64BigEndian(bytes); } // /// Extracts a 32bit value from the image byte array /// - /// PE image /// Starting index of the value /// /// The gets incremented by the size of the value /// - public static int ReadInt32(byte[] image, ref int start) + public int ReadInt32(ref int start) { - int size = sizeof(int); - byte[] bytes = new byte[size]; - Array.Copy(image, start, bytes, 0, size); - start += size; - return BitConverter.ToInt32(bytes, 0); + Span bytes = stackalloc byte[sizeof(int)]; + ReadSpanAt(ref start, bytes); + return _littleEndian ? BinaryPrimitives.ReadInt32LittleEndian(bytes) : BinaryPrimitives.ReadInt32BigEndian(bytes); } // /// Extracts an unsigned 32bit value from the image byte array /// - /// PE image /// Starting index of the value /// /// The gets incremented by the size of the value /// - public static uint ReadUInt32(byte[] image, ref int start) + public uint ReadUInt32(ref int start) { - int size = sizeof(int); - byte[] bytes = new byte[size]; - Array.Copy(image, start, bytes, 0, size); - start += size; - return (uint)BitConverter.ToInt32(bytes, 0); + Span bytes = stackalloc byte[sizeof(uint)]; + ReadSpanAt(ref start, bytes); + return _littleEndian ? BinaryPrimitives.ReadUInt32LittleEndian(bytes) : BinaryPrimitives.ReadUInt32BigEndian(bytes); } // /// Extracts an unsigned 16bit value from the image byte array /// - /// PE image /// Starting index of the value /// /// The gets incremented by the size of the value /// - public static ushort ReadUInt16(byte[] image, ref int start) + public ushort ReadUInt16(ref int start) { - int size = sizeof(short); - byte[] bytes = new byte[size]; - Array.Copy(image, start, bytes, 0, size); - start += size; - return (ushort)BitConverter.ToInt16(bytes, 0); + Span bytes = stackalloc byte[sizeof(ushort)]; + ReadSpanAt(ref start, bytes); + return _littleEndian ? BinaryPrimitives.ReadUInt16LittleEndian(bytes) : BinaryPrimitives.ReadUInt16BigEndian(bytes); } // /// Extracts byte from the image byte array /// - /// PE image /// Start index of the value /// /// The gets incremented by the size of the value /// - public static byte ReadByte(byte[] image, ref int start) + public byte ReadByte(ref int start) { - byte val = image[start]; - start += sizeof(byte); - return val; + Span bytes = stackalloc byte[sizeof(byte)]; + ReadSpanAt(ref start, bytes); + return bytes[0]; } // /// Extracts bits from the image byte array /// - /// PE image /// Number of bits to read /// Start bit of the value /// /// The gets incremented by /// - public static int ReadBits(byte[] image, int numBits, ref int bitOffset) + public int ReadBits(int numBits, ref int bitOffset) { int start = bitOffset / BITS_PER_BYTE; int bits = bitOffset % BITS_PER_BYTE; - int val = image[start] >> bits; + int val = ReadByte(ref start) >> bits; bits += numBits; while (bits > BITS_PER_BYTE) { - start++; bits -= BITS_PER_BYTE; if (bits > 0) { - int extraBits = image[start] << (numBits - bits); + int extraBits = ReadByte(ref start) << (numBits - bits); val ^= extraBits; } } @@ -130,19 +145,18 @@ public static int ReadBits(byte[] image, int numBits, ref int bitOffset) /// Decode variable length numbers /// based on src\inc\gcinfodecoder.h DecodeVarLengthUnsigned /// - /// PE image /// Number of bits to read /// Start bit of the value /// /// The gets incremented by the size of the value /// - public static uint DecodeVarLengthUnsigned(byte[] image, int len, ref int bitOffset) + public uint DecodeVarLengthUnsigned(int len, ref int bitOffset) { uint numEncodings = (uint)(1 << len); uint result = 0; for (int shift = 0; ; shift += len) { - uint currentChunk = (uint)ReadBits(image, len + 1, ref bitOffset); + uint currentChunk = (uint)ReadBits(len + 1, ref bitOffset); result |= (currentChunk & (numEncodings - 1)) << shift; if ((currentChunk & numEncodings) == 0) { @@ -155,13 +169,13 @@ public static uint DecodeVarLengthUnsigned(byte[] image, int len, ref int bitOff // /// based on src\inc\gcinfodecoder.h DecodeVarLengthSigned /// - public static int DecodeVarLengthSigned(byte[] image, int len, ref int bitOffset) + public int DecodeVarLengthSigned(int len, ref int bitOffset) { int numEncodings = (1 << len); int result = 0; for (int shift = 0; ; shift += len) { - int currentChunk = ReadBits(image, len + 1, ref bitOffset); + int currentChunk = ReadBits(len + 1, ref bitOffset); result |= (currentChunk & (numEncodings - 1)) << shift; if ((currentChunk & numEncodings) == 0) { @@ -177,13 +191,13 @@ public static int DecodeVarLengthSigned(byte[] image, int len, ref int bitOffset // /// based on src\vm\nativeformatreader.h DecodeUnsigned /// - public static uint DecodeUnsigned(byte[] image, uint offset, ref uint pValue) + public uint DecodeUnsigned(uint offset, ref uint pValue) { - if (offset >= image.Length) + if (offset >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); int off = (int)offset; - uint val = ReadByte(image, ref off); + uint val = ReadByte(ref off); if ((val & 1) == 0) { @@ -192,37 +206,37 @@ public static uint DecodeUnsigned(byte[] image, uint offset, ref uint pValue) } else if ((val & 2) == 0) { - if (offset + 1 >= image.Length) + if (offset + 1 >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); pValue = (val >> 2) | - ((uint)ReadByte(image, ref off) << 6); + ((uint)ReadByte(ref off) << 6); offset += 2; } else if ((val & 4) == 0) { - if (offset + 2 >= image.Length) + if (offset + 2 >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); pValue = (val >> 3) | - ((uint)ReadByte(image, ref off) << 5) | - ((uint)ReadByte(image, ref off) << 13); + ((uint)ReadByte(ref off) << 5) | + ((uint)ReadByte(ref off) << 13); offset += 3; } else if ((val & 8) == 0) { - if (offset + 3 >= image.Length) + if (offset + 3 >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); pValue = (val >> 4) | - ((uint)ReadByte(image, ref off) << 4) | - ((uint)ReadByte(image, ref off) << 12) | - ((uint)ReadByte(image, ref off) << 20); + ((uint)ReadByte(ref off) << 4) | + ((uint)ReadByte(ref off) << 12) | + ((uint)ReadByte(ref off) << 20); offset += 4; } else if ((val & 16) == 0) { - pValue = ReadUInt32(image, ref off); + pValue = ReadUInt32(ref off); offset += 5; } else @@ -236,13 +250,13 @@ public static uint DecodeUnsigned(byte[] image, uint offset, ref uint pValue) // /// based on src\vm\nativeformatreader.h DecodeSigned /// - public static uint DecodeSigned(byte[] image, uint offset, ref int pValue) + public uint DecodeSigned(uint offset, ref int pValue) { - if (offset >= image.Length) + if (offset >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); int off = (int)offset; - int val = ReadByte(image, ref off); + int val = ReadByte(ref off); if ((val & 1) == 0) { @@ -251,37 +265,37 @@ public static uint DecodeSigned(byte[] image, uint offset, ref int pValue) } else if ((val & 2) == 0) { - if (offset + 1 >= image.Length) + if (offset + 1 >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); pValue = (val >> 2) | - (ReadByte(image, ref off) << 6); + (ReadByte(ref off) << 6); offset += 2; } else if ((val & 4) == 0) { - if (offset + 2 >= image.Length) + if (offset + 2 >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); pValue = (val >> 3) | - (ReadByte(image, ref off) << 5) | - (ReadByte(image, ref off) << 13); + (ReadByte(ref off) << 5) | + (ReadByte(ref off) << 13); offset += 3; } else if ((val & 8) == 0) { - if (offset + 3 >= image.Length) + if (offset + 3 >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); pValue = (val >> 4) | - (ReadByte(image, ref off) << 4) | - (ReadByte(image, ref off) << 12) | - (ReadByte(image, ref off) << 20); + (ReadByte(ref off) << 4) | + (ReadByte(ref off) << 12) | + (ReadByte(ref off) << 20); offset += 4; } else if ((val & 16) == 0) { - pValue = ReadInt32(image, ref off); + pValue = ReadInt32(ref off); offset += 5; } else @@ -295,10 +309,10 @@ public static uint DecodeSigned(byte[] image, uint offset, ref int pValue) // /// based on src\debug\daccess\nidump.cpp DacSigUncompressData and DacSigUncompressBigData /// - public static uint ReadCompressedData(byte[] image, ref int start) + public uint ReadCompressedData(ref int start) { int off = start; - uint data = ReadUInt32(image, ref off); + uint data = ReadUInt32(ref off); if ((data & 0x80) == 0x00) { start++; @@ -306,15 +320,15 @@ public static uint ReadCompressedData(byte[] image, ref int start) } if ((data & 0xC0) == 0x80) // 10?? ???? { - data = (uint)((ReadByte(image, ref start) & 0x3f) << 8); - data |= ReadByte(image, ref start); + data = (uint)((ReadByte(ref start) & 0x3f) << 8); + data |= ReadByte(ref start); } else // 110? ???? { - data = (uint)(ReadByte(image, ref start) & 0x1f) << 24; - data |= (uint)ReadByte(image, ref start) << 16; - data |= (uint)ReadByte(image, ref start) << 8; - data |= ReadByte(image, ref start); + data = (uint)(ReadByte(ref start) & 0x1f) << 24; + data |= (uint)ReadByte(ref start) << 16; + data |= (uint)ReadByte(ref start) << 8; + data |= ReadByte(ref start); } return data; } @@ -322,15 +336,15 @@ public static uint ReadCompressedData(byte[] image, ref int start) /// /// based on src\inc\gcdecoder.cpp decodeUnsigned /// - public static uint DecodeUnsignedGc(byte[] image, ref int start) + public uint DecodeUnsignedGc(ref int start) { int size = 1; - byte data = image[start++]; + byte data = ReadByte(ref start); uint value = (uint)data & 0x7f; while ((data & 0x80) != 0) { size++; - data = image[start++]; + data = ReadByte(ref start); value <<= 7; value += (uint)data & 0x7f; } @@ -340,16 +354,16 @@ public static uint DecodeUnsignedGc(byte[] image, ref int start) /// /// based on src\inc\gcdecoder.cpp decodeSigned /// - public static int DecodeSignedGc(byte[] image, ref int start) + public int DecodeSignedGc(ref int start) { int size = 1; - byte data = image[start++]; + byte data = ReadByte(ref start); byte first = data; int value = data & 0x3f; while ((data & 0x80) != 0) { size++; - data = image[start++]; + data = ReadByte(ref start); value <<= 7; value += data & 0x7f; } @@ -362,9 +376,9 @@ public static int DecodeSignedGc(byte[] image, ref int start) /// /// based on src\inc\gcdecoder.cpp decodeUDelta /// - public static uint DecodeUDelta(byte[] image, ref int start, uint lastValue) + public uint DecodeUDelta(ref int start, uint lastValue) { - uint delta = DecodeUnsignedGc(image, ref start); + uint delta = DecodeUnsignedGc(ref start); return lastValue + delta; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NibbleReader.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NibbleReader.cs index 7a024ed33445b5..90ad9b5f58dfa5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NibbleReader.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NibbleReader.cs @@ -7,7 +7,7 @@ namespace ILCompiler.Reflection.ReadyToRun /// Helper to read memory by 4-bit (half-byte) nibbles as is used for encoding /// method fixups. More or less ported over from CoreCLR src\inc\nibblestream.h. /// - class NibbleReader + internal class NibbleReader { /// /// Special value in _nextNibble saying there's no next nibble and the next byte @@ -16,9 +16,9 @@ class NibbleReader private const byte NoNextNibble = 0xFF; /// - /// Byte array representing the PE file. + /// NativeReader representing the PE file. /// - private byte[] _image; + private NativeReader _imageReader; /// /// Offset within the image. @@ -30,9 +30,9 @@ class NibbleReader /// private byte _nextNibble; - public NibbleReader(byte[] image, int offset) + public NibbleReader(NativeReader imageReader, int offset) { - _image = image; + _imageReader = imageReader; _offset = offset; _nextNibble = NoNextNibble; } @@ -47,7 +47,7 @@ public byte ReadNibble() } else { - _nextNibble = _image[_offset++]; + _nextNibble = _imageReader.ReadByte(ref _offset); result = (byte)(_nextNibble & 0x0F); _nextNibble >>= 4; } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PEReaderExtensions.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PEReaderExtensions.cs index 9f2cc6ad22987f..0fd43e06c81e29 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PEReaderExtensions.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PEReaderExtensions.cs @@ -16,6 +16,9 @@ namespace ILCompiler.Reflection.ReadyToRun { public class PEExportTable { + public readonly bool HasExportTable; + public readonly int ExportTableHeaderLength; + private readonly Dictionary _namedExportRva; private readonly Dictionary _ordinalRva; @@ -28,6 +31,8 @@ private PEExportTable(PEReader peReader) if ((exportTable.Size == 0) || (exportTable.RelativeVirtualAddress == 0)) return; + HasExportTable = true; + PEMemoryBlock peImage = peReader.GetEntireImage(); BlobReader exportTableHeader = peImage.GetReader(peReader.GetOffset(exportTable.RelativeVirtualAddress), exportTable.Size); if (exportTableHeader.Length == 0) @@ -35,6 +40,8 @@ private PEExportTable(PEReader peReader) return; } + ExportTableHeaderLength = exportTableHeader.Length; + // +0x00: reserved exportTableHeader.ReadUInt32(); // +0x04: TODO: time/date stamp @@ -89,6 +96,10 @@ private PEExportTable(PEReader peReader) } _namedExportRva.Add(nameBuilder.ToString(), addressTable[ordinalTable[entryIndex]]); } + else + { + Console.Error.WriteLine($"Found a zero RVA when reading name pointers for entry #{entryIndex}/{namePointerCount}"); + } } } @@ -97,6 +108,23 @@ public static PEExportTable Parse(PEReader peReader) return new PEExportTable(peReader); } + public void DumpToConsoleError() + { + Console.Error.WriteLine($"HasExportTable: {HasExportTable}"); + Console.Error.WriteLine($"ExportTableHeaderLength: {ExportTableHeaderLength}"); + Console.Error.WriteLine($"_namedExportRva: {_namedExportRva.Count} item(s)"); + int i = 0; + foreach (var kvp in _namedExportRva) + { + Console.Error.WriteLine($" '{kvp.Key}': {kvp.Value}"); + if (i++ > 64) + { + Console.Error.WriteLine(" ... stopped dumping named exports because there are too many."); + break; + } + } + } + public bool TryGetValue(string exportName, out int rva) => _namedExportRva.TryGetValue(exportName, out rva); public bool TryGetValue(int ordinal, out int rva) => _ordinalRva.TryGetValue(ordinal, out rva); } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunHeader.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunHeader.cs index 173ece1227ef29..dcecc214111bdf 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunHeader.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunHeader.cs @@ -22,16 +22,12 @@ public class ComponentAssembly public readonly int AssemblyHeaderRVA; public readonly int AssemblyHeaderSize; - public ComponentAssembly(byte[] image, ref int curOffset) + public ComponentAssembly(NativeReader imageReader, ref int curOffset) { - CorHeaderRVA = BitConverter.ToInt32(image, curOffset); - curOffset += sizeof(int); - CorHeaderSize = BitConverter.ToInt32(image, curOffset); - curOffset += sizeof(int); - AssemblyHeaderRVA = BitConverter.ToInt32(image, curOffset); - curOffset += sizeof(int); - AssemblyHeaderSize = BitConverter.ToInt32(image, curOffset); - curOffset += sizeof(int); + CorHeaderRVA = imageReader.ReadInt32(ref curOffset); + CorHeaderSize = imageReader.ReadInt32(ref curOffset); + AssemblyHeaderRVA = imageReader.ReadInt32(ref curOffset); + AssemblyHeaderSize = imageReader.ReadInt32(ref curOffset); } } @@ -55,32 +51,32 @@ public ReadyToRunCoreHeader() { } - public ReadyToRunCoreHeader(byte[] image, ref int curOffset) + public ReadyToRunCoreHeader(NativeReader imageReader, ref int curOffset) { - ParseCoreHeader(image, ref curOffset); + ParseCoreHeader(imageReader, ref curOffset); } /// /// Parse core header fields common to global R2R file header and per assembly headers in composite R2R images. /// - /// PE image + /// PE Image reader /// Index in the image byte array to the start of the ReadyToRun core header - public void ParseCoreHeader(byte[] image, ref int curOffset) + public void ParseCoreHeader(NativeReader imageReader, ref int curOffset) { - Flags = NativeReader.ReadUInt32(image, ref curOffset); - int nSections = NativeReader.ReadInt32(image, ref curOffset); + Flags = imageReader.ReadUInt32(ref curOffset); + int nSections = imageReader.ReadInt32(ref curOffset); Sections = new Dictionary(); for (int i = 0; i < nSections; i++) { - int type = NativeReader.ReadInt32(image, ref curOffset); + int type = imageReader.ReadInt32(ref curOffset); var sectionType = (ReadyToRunSectionType)type; if (!Enum.IsDefined(typeof(ReadyToRunSectionType), type)) { throw new BadImageFormatException("Warning: Invalid ReadyToRun section type"); } - int sectionStartRva = NativeReader.ReadInt32(image, ref curOffset); - int sectionLength = NativeReader.ReadInt32(image, ref curOffset); + int sectionStartRva = imageReader.ReadInt32(ref curOffset); + int sectionLength = imageReader.ReadInt32(ref curOffset); Sections[sectionType] = new ReadyToRunSection(sectionType, sectionStartRva, sectionLength); } } @@ -124,28 +120,29 @@ public ReadyToRunHeader() { } /// /// Initializes the fields of the R2RHeader /// - /// PE image + /// PE Image reader /// Relative virtual address of the ReadyToRun header /// Index in the image byte array to the start of the ReadyToRun header /// The signature must be 0x00525452 - public ReadyToRunHeader(byte[] image, int rva, int curOffset) + public ReadyToRunHeader(NativeReader imageReader, int rva, int curOffset) { RelativeVirtualAddress = rva; int startOffset = curOffset; byte[] signature = new byte[sizeof(uint) - 1]; // -1 removes the null character at the end of the cstring - Array.Copy(image, curOffset, signature, 0, sizeof(uint) - 1); + imageReader.ReadSpanAt(ref curOffset, signature); + curOffset = startOffset; SignatureString = Encoding.UTF8.GetString(signature); - Signature = NativeReader.ReadUInt32(image, ref curOffset); + Signature = imageReader.ReadUInt32(ref curOffset); if (Signature != READYTORUN_SIGNATURE) { throw new System.BadImageFormatException("Incorrect R2R header signature: " + SignatureString); } - MajorVersion = NativeReader.ReadUInt16(image, ref curOffset); - MinorVersion = NativeReader.ReadUInt16(image, ref curOffset); + MajorVersion = imageReader.ReadUInt16(ref curOffset); + MinorVersion = imageReader.ReadUInt16(ref curOffset); - ParseCoreHeader(image, ref curOffset); + ParseCoreHeader(imageReader, ref curOffset); Size = curOffset - startOffset; } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs index 67f581e8d8dfe6..10ab13a6e9eaad 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs @@ -399,32 +399,32 @@ public ReadyToRunMethod( switch (MethodHandle.Kind) { case HandleKind.MethodDefinition: + { + MethodDefinition methodDef = ComponentReader.MetadataReader.GetMethodDefinition((MethodDefinitionHandle)MethodHandle); + if (methodDef.RelativeVirtualAddress != 0) { - MethodDefinition methodDef = ComponentReader.MetadataReader.GetMethodDefinition((MethodDefinitionHandle)MethodHandle); - if (methodDef.RelativeVirtualAddress != 0) + MethodBodyBlock mbb = ComponentReader.ImageReader.GetMethodBody(methodDef.RelativeVirtualAddress); + if (!mbb.LocalSignature.IsNil) { - MethodBodyBlock mbb = ComponentReader.ImageReader.GetMethodBody(methodDef.RelativeVirtualAddress); - if (!mbb.LocalSignature.IsNil) - { - StandaloneSignature ss = ComponentReader.MetadataReader.GetStandaloneSignature(mbb.LocalSignature); - LocalSignature = ss.DecodeLocalSignature(typeProvider, genericContext); - } + StandaloneSignature ss = ComponentReader.MetadataReader.GetStandaloneSignature(mbb.LocalSignature); + LocalSignature = ss.DecodeLocalSignature(typeProvider, genericContext); } - Name = ComponentReader.MetadataReader.GetString(methodDef.Name); - Signature = methodDef.DecodeSignature(typeProvider, genericContext); - owningTypeHandle = methodDef.GetDeclaringType(); - genericParams = methodDef.GetGenericParameters(); } - break; + Name = ComponentReader.MetadataReader.GetString(methodDef.Name); + Signature = methodDef.DecodeSignature(typeProvider, genericContext); + owningTypeHandle = methodDef.GetDeclaringType(); + genericParams = methodDef.GetGenericParameters(); + } + break; case HandleKind.MemberReference: - { - MemberReference memberRef = ComponentReader.MetadataReader.GetMemberReference((MemberReferenceHandle)MethodHandle); - Name = ComponentReader.MetadataReader.GetString(memberRef.Name); - Signature = memberRef.DecodeMethodSignature(typeProvider, genericContext); - owningTypeHandle = memberRef.Parent; - } - break; + { + MemberReference memberRef = ComponentReader.MetadataReader.GetMemberReference((MemberReferenceHandle)MethodHandle); + Name = ComponentReader.MetadataReader.GetString(memberRef.Name); + Signature = memberRef.DecodeMethodSignature(typeProvider, genericContext); + owningTypeHandle = memberRef.Parent; + } + break; default: throw new NotImplementedException(); @@ -492,13 +492,13 @@ private void EnsureInitialized() int gcInfoOffset = _readyToRunReader.CompositeReader.GetOffset(GcInfoRva); if (_readyToRunReader.Machine == Machine.I386) { - _gcInfo = new x86.GcInfo(_readyToRunReader.Image, gcInfoOffset); + _gcInfo = new x86.GcInfo(_readyToRunReader.ImageReader, gcInfoOffset); } else { // Arm, Arm64, LoongArch64 and RISCV64 use the same GcInfo format as Amd64 _gcInfo = new Amd64.GcInfo( - _readyToRunReader.Image, + _readyToRunReader.ImageReader, gcInfoOffset, _readyToRunReader.Machine, _readyToRunReader.ReadyToRunHeader.MajorVersion, @@ -527,7 +527,7 @@ private void EnsureFixupCells() return; } _fixupCells = new List(); - NibbleReader reader = new NibbleReader(_readyToRunReader.Image, _fixupOffset.Value); + NibbleReader reader = new NibbleReader(_readyToRunReader.ImageReader, _fixupOffset.Value); // The following algorithm has been loosely ported from CoreCLR, // src\vm\ceeload.inl, BOOL Module::FixupDelayListAux @@ -585,7 +585,7 @@ private void ParseRuntimeFunctions(bool partial) curOffset = coldOffset; runtimeFunctionId = coldRuntimeFunctionId; } - int startRva = NativeReader.ReadInt32(_readyToRunReader.Image, ref curOffset); + int startRva = _readyToRunReader.ImageReader.ReadInt32(ref curOffset); if (_readyToRunReader.Machine == Machine.ArmThumb2) { // The low bit of this address is set since the function contains thumb code. @@ -595,35 +595,35 @@ private void ParseRuntimeFunctions(bool partial) int endRva = -1; if (_readyToRunReader.Machine == Machine.Amd64) { - endRva = NativeReader.ReadInt32(_readyToRunReader.Image, ref curOffset); + endRva = _readyToRunReader.ImageReader.ReadInt32(ref curOffset); } - int unwindRva = NativeReader.ReadInt32(_readyToRunReader.Image, ref curOffset); + int unwindRva = _readyToRunReader.ImageReader.ReadInt32(ref curOffset); int unwindOffset = _readyToRunReader.CompositeReader.GetOffset(unwindRva); BaseUnwindInfo unwindInfo = null; if (_readyToRunReader.Machine == Machine.I386) { - unwindInfo = new x86.UnwindInfo(_readyToRunReader.Image, unwindOffset); + unwindInfo = new x86.UnwindInfo(_readyToRunReader.ImageReader, unwindOffset); } else if (_readyToRunReader.Machine == Machine.Amd64) { - unwindInfo = new Amd64.UnwindInfo(_readyToRunReader.Image, unwindOffset); + unwindInfo = new Amd64.UnwindInfo(_readyToRunReader.ImageReader, unwindOffset); } else if (_readyToRunReader.Machine == Machine.ArmThumb2) { - unwindInfo = new Arm.UnwindInfo(_readyToRunReader.Image, unwindOffset); + unwindInfo = new Arm.UnwindInfo(_readyToRunReader.ImageReader, unwindOffset); } else if (_readyToRunReader.Machine == Machine.Arm64) { - unwindInfo = new Arm64.UnwindInfo(_readyToRunReader.Image, unwindOffset); + unwindInfo = new Arm64.UnwindInfo(_readyToRunReader.ImageReader, unwindOffset); } else if (_readyToRunReader.Machine == Machine.LoongArch64) { - unwindInfo = new LoongArch64.UnwindInfo(_readyToRunReader.Image, unwindOffset); + unwindInfo = new LoongArch64.UnwindInfo(_readyToRunReader.ImageReader, unwindOffset); } else if (_readyToRunReader.Machine == Machine.RiscV64) { - unwindInfo = new RiscV64.UnwindInfo(_readyToRunReader.Image, unwindOffset); + unwindInfo = new RiscV64.UnwindInfo(_readyToRunReader.ImageReader, unwindOffset); } if (i == 0 && unwindInfo != null) diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index 3dc6cbb9aae659..3e5341c03f83bc 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -141,8 +141,14 @@ public sealed class ReadyToRunReader /// Byte array containing the ReadyToRun image /// public byte[] Image { get; private set; } + private PinningReference ImagePin; + /// + /// NativeReader to read the image contents + /// + public NativeReader ImageReader { get; private set; } + /// /// Name of the image file /// @@ -407,6 +413,7 @@ public ReadyToRunReader(IAssemblyResolver assemblyResolver, IAssemblyMetadata me CompositeReader = peReader; Filename = filename; Image = ConvertToArray(content); + ImageReader = new NativeReader(new MemoryStream(Image)); Initialize(metadata); } @@ -433,6 +440,7 @@ public unsafe ReadyToRunReader(IAssemblyResolver assemblyResolver, string filena _assemblyResolver = assemblyResolver; Filename = filename; Image = ConvertToArray(content); + ImageReader = new NativeReader(new MemoryStream(Image)); Initialize(metadata: null); } @@ -479,49 +487,97 @@ public PinningReference(object o) } private unsafe void Initialize(IAssemblyMetadata metadata) { - _assemblyCache = new List(); - - if (CompositeReader == null) + try { - Image ??= File.ReadAllBytes(Filename); - byte[] image = Image; - ImagePin = new PinningReference(image); - CompositeReader = new PEReader(Unsafe.As>(ref image)); + _assemblyCache = new List(); + + if (CompositeReader == null) + { + Image ??= File.ReadAllBytes(Filename); + ImageReader = new NativeReader(new MemoryStream(Image)); + byte[] image = Image; + ImagePin = new PinningReference(image); + CompositeReader = new PEReader(Unsafe.As>(ref image)); + } + else + { + ImmutableArray content = CompositeReader.GetEntireImage().GetContent(); + Image = Unsafe.As, byte[]>(ref content); + ImageReader = new NativeReader(new MemoryStream(Image)); + ImagePin = new PinningReference(Image); + } + + if (metadata == null && CompositeReader.HasMetadata) + { + metadata = new StandaloneAssemblyMetadata(CompositeReader); + } + + if (metadata != null) + { + if ((CompositeReader.PEHeaders.CorHeader.Flags & CorFlags.ILLibrary) == 0) + { + if (!TryLocateNativeReadyToRunHeader()) + { + DumpImageInformation(); + + throw new BadImageFormatException("The file is not a ReadyToRun image"); + } + + Debug.Assert(Composite); + } + else + { + _assemblyCache.Add(metadata); + + DirectoryEntry r2rHeaderDirectory = CompositeReader.PEHeaders.CorHeader.ManagedNativeHeaderDirectory; + _readyToRunHeaderRVA = r2rHeaderDirectory.RelativeVirtualAddress; + Debug.Assert(!Composite); + } + + } + else if (!TryLocateNativeReadyToRunHeader()) + { + throw new BadImageFormatException($"ECMA metadata / RTR_HEADER not found in file '{Filename}'"); + } } - else + catch (BadImageFormatException) { - ImmutableArray content = CompositeReader.GetEntireImage().GetContent(); - Image = Unsafe.As, byte[]>(ref content); - ImagePin = new PinningReference(Image); + if (CompositeReader != null) + DumpImageInformation(); + throw; } + } - if (metadata == null && CompositeReader.HasMetadata) + internal void DumpImageInformation() + { + try { - metadata = new StandaloneAssemblyMetadata(CompositeReader); - } + Console.Error.WriteLine($"Image file '{Filename}' information:"); + Console.Error.WriteLine($"Size: {Image.Length} byte(s)"); + Console.Error.WriteLine($"MetadataSize: {CompositeReader.PEHeaders.MetadataSize} byte(s)"); - if (metadata != null) - { - if ((CompositeReader.PEHeaders.CorHeader.Flags & CorFlags.ILLibrary) == 0) + if (CompositeReader.PEHeaders.PEHeader is PEHeader header) { - if (!TryLocateNativeReadyToRunHeader()) - throw new BadImageFormatException("The file is not a ReadyToRun image"); - - Debug.Assert(Composite); + Console.Error.WriteLine($"SizeOfImage: {header.SizeOfImage} byte(s)"); + Console.Error.WriteLine($"ImageBase: 0x{header.ImageBase:X}"); + Console.Error.WriteLine($"FileAlignment: 0x{header.FileAlignment:X}"); + Console.Error.WriteLine($"SectionAlignment: 0x{header.SectionAlignment:X}"); } else - { - _assemblyCache.Add(metadata); + Console.Error.WriteLine("No PEHeader"); - DirectoryEntry r2rHeaderDirectory = CompositeReader.PEHeaders.CorHeader.ManagedNativeHeaderDirectory; - _readyToRunHeaderRVA = r2rHeaderDirectory.RelativeVirtualAddress; - Debug.Assert(!Composite); - } + Console.Error.WriteLine($"CorHeader.Flags: {CompositeReader.PEHeaders.CorHeader?.Flags}"); + + Console.Error.WriteLine("Sections:"); + foreach (var section in CompositeReader.PEHeaders.SectionHeaders) + Console.Error.WriteLine($" {section.Name} {section.VirtualAddress} - {(section.VirtualAddress + section.VirtualSize)}"); + var exportTable = CompositeReader.GetExportTable(); + exportTable.DumpToConsoleError(); } - else if (!TryLocateNativeReadyToRunHeader()) + catch (Exception exc) { - throw new BadImageFormatException($"ECMA metadata / RTR_HEADER not found in file '{Filename}'"); + Console.Error.WriteLine($"Unhandled exception while dumping image information: {exc}"); } } @@ -560,7 +616,7 @@ internal void EnsureMethods() for (int i = 0; i < count; i++) { - mHotColdMap.Add(new List { NativeReader.ReadInt32(Image, ref hotColdMapOffset), NativeReader.ReadInt32(Image, ref hotColdMapOffset) }); + mHotColdMap.Add(new List { ImageReader.ReadInt32(ref hotColdMapOffset), ImageReader.ReadInt32(ref hotColdMapOffset) }); } for (int i = 0; i < count - 1; i++) @@ -687,7 +743,7 @@ private unsafe void EnsureHeader() // Initialize R2RHeader Debug.Assert(_readyToRunHeaderRVA != 0); int r2rHeaderOffset = GetOffset(_readyToRunHeaderRVA); - _readyToRunHeader = new ReadyToRunHeader(Image, _readyToRunHeaderRVA, r2rHeaderOffset); + _readyToRunHeader = new ReadyToRunHeader(ImageReader, _readyToRunHeaderRVA, r2rHeaderOffset); FindOwnerCompositeExecutable(); @@ -716,11 +772,11 @@ private void EnsureDebugInfo() int debugInfoSectionOffset = GetOffset(debugInfoSection.RelativeVirtualAddress); - NativeArray debugInfoArray = new NativeArray(Image, (uint)debugInfoSectionOffset); + NativeArray debugInfoArray = new NativeArray(ImageReader, (uint)debugInfoSectionOffset); for (uint i = 0; i < debugInfoArray.GetCount(); ++i) { int offset = 0; - if (!debugInfoArray.TryGetAt(Image, i, ref offset)) + if (!debugInfoArray.TryGetAt(i, ref offset)) { continue; } @@ -837,13 +893,13 @@ private void ParseMethodDefEntrypointsSection(ReadyToRunSection section, IAssemb { int assemblyIndex = GetAssemblyIndex(section); int methodDefEntryPointsOffset = GetOffset(section.RelativeVirtualAddress); - NativeArray methodEntryPoints = new NativeArray(Image, (uint)methodDefEntryPointsOffset); + NativeArray methodEntryPoints = new NativeArray(ImageReader, (uint)methodDefEntryPointsOffset); uint nMethodEntryPoints = methodEntryPoints.GetCount(); for (uint rid = 1; rid <= nMethodEntryPoints; rid++) { int offset = 0; - if (methodEntryPoints.TryGetAt(Image, rid - 1, ref offset)) + if (methodEntryPoints.TryGetAt(rid - 1, ref offset)) { EntityHandle methodHandle = MetadataTokens.MethodDefinitionHandle((int)rid); int runtimeFunctionId; @@ -870,13 +926,13 @@ private void ParseMethodDefEntrypointsSection(ReadyToRunSection section, IAssemb private void ParseMethodDefEntrypointsSectionCustom(IR2RSignatureTypeProvider provider, Dictionary foundMethods, ReadyToRunSection section, IAssemblyMetadata metadataReader) { int methodDefEntryPointsOffset = GetOffset(section.RelativeVirtualAddress); - NativeArray methodEntryPoints = new NativeArray(Image, (uint)methodDefEntryPointsOffset); + NativeArray methodEntryPoints = new NativeArray(ImageReader, (uint)methodDefEntryPointsOffset); uint nMethodEntryPoints = methodEntryPoints.GetCount(); for (uint rid = 1; rid <= nMethodEntryPoints; rid++) { int offset = 0; - if (methodEntryPoints.TryGetAt(Image, rid - 1, ref offset)) + if (methodEntryPoints.TryGetAt(rid - 1, ref offset)) { EntityHandle methodHandle = MetadataTokens.MethodDefinitionHandle((int)rid); int runtimeFunctionId; @@ -901,8 +957,8 @@ private void ParseInstanceMethodEntrypointsCustom(); int availableTypesOffset = GetOffset(availableTypesSection.RelativeVirtualAddress); - NativeParser parser = new NativeParser(Image, (uint)availableTypesOffset); - NativeHashtable availableTypes = new NativeHashtable(Image, parser, (uint)(availableTypesOffset + availableTypesSection.Size)); + NativeParser parser = new NativeParser(ImageReader, (uint)availableTypesOffset); + NativeHashtable availableTypes = new NativeHashtable(ImageReader, parser, (uint)(availableTypesOffset + availableTypesSection.Size)); NativeHashtable.AllEntriesEnumerator allEntriesEnum = availableTypes.EnumerateAllEntries(); NativeParser curParser = allEntriesEnum.GetNext(); while (!curParser.IsNull()) @@ -1396,10 +1452,10 @@ private void ParseComponentAssemblies() for (int assemblyIndex = 0; assemblyIndex < numberOfAssemblyHeaderRVAs; assemblyIndex++) { - ComponentAssembly assembly = new ComponentAssembly(Image, ref offset); + ComponentAssembly assembly = new ComponentAssembly(ImageReader, ref offset); int headerOffset = GetOffset(assembly.AssemblyHeaderRVA); - ReadyToRunCoreHeader assemblyHeader = new ReadyToRunCoreHeader(Image, ref headerOffset); + ReadyToRunCoreHeader assemblyHeader = new ReadyToRunCoreHeader(ImageReader, ref headerOffset); _readyToRunAssemblyHeaders.Add(assemblyHeader); _readyToRunAssemblies.Add(new ReadyToRunAssembly(this)); } @@ -1420,10 +1476,23 @@ private void FindOwnerCompositeExecutable() } } + private void EnsureImportSections() + { + try + { + EnsureImportSectionsImpl(); + } + catch (BadImageFormatException) + { + DumpImageInformation(); + throw; + } + } + /// /// based on ZapImportSectionsTable::Save /// - private void EnsureImportSections() + private void EnsureImportSectionsImpl() { if (_importSections != null) { @@ -1439,13 +1508,13 @@ private void EnsureImportSections() int endOffset = offset + importSectionsSection.Size; while (offset < endOffset) { - int rva = NativeReader.ReadInt32(Image, ref offset); + int rva = ImageReader.ReadInt32(ref offset); int sectionOffset = GetOffset(rva); int startOffset = sectionOffset; - int size = NativeReader.ReadInt32(Image, ref offset); - ReadyToRunImportSectionFlags flags = (ReadyToRunImportSectionFlags)NativeReader.ReadUInt16(Image, ref offset); - ReadyToRunImportSectionType type = (ReadyToRunImportSectionType)NativeReader.ReadByte(Image, ref offset); - byte entrySize = NativeReader.ReadByte(Image, ref offset); + int size = ImageReader.ReadInt32(ref offset); + ReadyToRunImportSectionFlags flags = (ReadyToRunImportSectionFlags)ImageReader.ReadUInt16(ref offset); + ReadyToRunImportSectionType type = (ReadyToRunImportSectionType)ImageReader.ReadByte(ref offset); + byte entrySize = ImageReader.ReadByte(ref offset); if (entrySize == 0) { switch (Machine) @@ -1471,7 +1540,7 @@ private void EnsureImportSections() { entryCount = size / entrySize; } - int signatureRVA = NativeReader.ReadInt32(Image, ref offset); + int signatureRVA = ImageReader.ReadInt32(ref offset); int signatureOffset = 0; if (signatureRVA != 0) @@ -1482,15 +1551,15 @@ private void EnsureImportSections() for (int i = 0; i < entryCount; i++) { int entryOffset = sectionOffset - startOffset; - long section = NativeReader.ReadInt64(Image, ref sectionOffset); - uint sigRva = NativeReader.ReadUInt32(Image, ref signatureOffset); + long section = ImageReader.ReadInt64(ref sectionOffset); + uint sigRva = ImageReader.ReadUInt32(ref signatureOffset); int sigOffset = GetOffset((int)sigRva); ReadyToRunSignature signature = MetadataNameFormatter.FormatSignature(_assemblyResolver, this, sigOffset); entries.Add(new ReadyToRunImportSection.ImportSectionEntry(entries.Count, entryOffset, entryOffset + rva, section, sigRva, signature)); _importSignatures.Add(rva + entrySize * i, signature); } - int auxDataRVA = NativeReader.ReadInt32(Image, ref offset); + int auxDataRVA = ImageReader.ReadInt32(ref offset); int auxDataOffset = 0; if (auxDataRVA != 0) { @@ -1539,13 +1608,13 @@ private void GetRuntimeFunctionIndexFromOffset(int offset, out int runtimeFuncti // get the id of the entry point runtime function from the MethodEntryPoints NativeArray uint id = 0; // the RUNTIME_FUNCTIONS index - offset = (int)NativeReader.DecodeUnsigned(Image, (uint)offset, ref id); + offset = (int)ImageReader.DecodeUnsigned((uint)offset, ref id); if ((id & 1) != 0) { if ((id & 2) != 0) { uint val = 0; - NativeReader.DecodeUnsigned(Image, (uint)offset, ref val); + ImageReader.DecodeUnsigned((uint)offset, ref val); offset -= (int)val; } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/RiscV64/UnwindInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/RiscV64/UnwindInfo.cs index 34411efe8e2ca7..34d14ca6ae04a1 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/RiscV64/UnwindInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/RiscV64/UnwindInfo.cs @@ -75,11 +75,11 @@ public class UnwindInfo : BaseUnwindInfo public UnwindInfo() { } - public UnwindInfo(byte[] image, int offset) + public UnwindInfo(NativeReader imageReader, int offset) { uint startOffset = (uint)offset; - int dw = NativeReader.ReadInt32(image, ref offset); + int dw = imageReader.ReadInt32(ref offset); CodeWords = ExtractBits(dw, 27, 5); EpilogCount = ExtractBits(dw, 22, 5); EBit = ExtractBits(dw, 21, 1); @@ -91,7 +91,7 @@ public UnwindInfo(byte[] image, int offset) { // We have an extension word specifying a larger number of Code Words or Epilog Counts // than can be specified in the header word. - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); ExtendedCodeWords = ExtractBits(dw, 16, 8); ExtendedEpilogCount = ExtractBits(dw, 0, 16); } @@ -105,7 +105,7 @@ public UnwindInfo(byte[] image, int offset) { for (int scope = 0; scope < EpilogCount; scope++) { - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); Epilogs[scope] = new Epilog(scope, dw, startOffset); epilogStartAt[Epilogs[scope].EpilogStartIndex] = true; // an epilog starts at this offset in the unwind codes } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcInfo.cs index 7b6f466c2f1a3b..d7e6f5a9cd7bd1 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcInfo.cs @@ -21,30 +21,30 @@ public GcInfo() { } /// /// based on GCDump::DumpGCTable /// - public GcInfo(byte[] image, int offset) + public GcInfo(NativeReader imageReader, int offset) { Offset = offset; - CodeLength = (int)NativeReader.DecodeUnsignedGc(image, ref offset); + CodeLength = (int)imageReader.DecodeUnsignedGc(ref offset); - Header = InfoHdrDecoder.DecodeHeader(image, ref offset, CodeLength); + Header = InfoHdrDecoder.DecodeHeader(imageReader, ref offset, CodeLength); - NoGCRegions = new NoGcRegionTable(image, Header, ref offset); + NoGCRegions = new NoGcRegionTable(imageReader, Header, ref offset); - SlotTable = new GcSlotTable(image, Header, ref offset); + SlotTable = new GcSlotTable(imageReader, Header, ref offset); Transitions = new Dictionary>(); if (Header.Interruptible) { - GetTransitionsFullyInterruptible(image, ref offset); + GetTransitionsFullyInterruptible(imageReader, ref offset); } else if (Header.EbpFrame) { - GetTransitionsEbpFrame(image, ref offset); + GetTransitionsEbpFrame(imageReader, ref offset); } else { - GetTransitionsNoEbp(image, ref offset); + GetTransitionsNoEbp(imageReader, ref offset); } Size = offset - Offset; @@ -79,7 +79,7 @@ private void AddNewTransition(BaseGcTransition transition) Transitions[transition.CodeOffset].Add(transition); } - private void ArgEncoding(byte[] image, ref uint isPop, ref uint argOffs, ref uint argCnt, ref uint curOffs, ref bool isThis, ref bool iptr) + private void ArgEncoding(NativeReader imageReader, ref uint isPop, ref uint argOffs, ref uint argCnt, ref uint curOffs, ref bool isThis, ref bool iptr) { if (isPop != 0) { @@ -101,7 +101,7 @@ private void ArgEncoding(byte[] image, ref uint isPop, ref uint argOffs, ref uin /// /// based on GCDump::DumpGCTable /// - private void GetTransitionsFullyInterruptible(byte[] image, ref int offset) + private void GetTransitionsFullyInterruptible(NativeReader imageReader, ref int offset) { uint argCnt = 0; bool isThis = false; @@ -112,7 +112,7 @@ private void GetTransitionsFullyInterruptible(byte[] image, ref int offset) { uint isPop; uint argOffs; - uint val = image[offset++]; + uint val = imageReader.ReadByte(ref offset); if ((val & 0x80) == 0) { @@ -143,7 +143,7 @@ private void GetTransitionsFullyInterruptible(byte[] image, ref int offset) curOffs += (val & 0x07); isPop = (val & 0x40); - ArgEncoding(image, ref isPop, ref argOffs, ref argCnt, ref curOffs, ref isThis, ref iptr); + ArgEncoding(imageReader, ref isPop, ref argOffs, ref argCnt, ref curOffs, ref isThis, ref iptr); continue; } @@ -177,21 +177,21 @@ private void GetTransitionsFullyInterruptible(byte[] image, ref int offset) iptr = true; break; case 0xB8: - val = NativeReader.DecodeUnsignedGc(image, ref offset); + val = imageReader.DecodeUnsignedGc(ref offset); curOffs += val; break; case 0xF8: case 0xFC: isPop = val & 0x04; - argOffs = NativeReader.DecodeUnsignedGc(image, ref offset); - ArgEncoding(image, ref isPop, ref argOffs, ref argCnt, ref curOffs, ref isThis, ref iptr); + argOffs = imageReader.DecodeUnsignedGc(ref offset); + ArgEncoding(imageReader, ref isPop, ref argOffs, ref argCnt, ref curOffs, ref isThis, ref iptr); break; case 0xFD: - argOffs = NativeReader.DecodeUnsignedGc(image, ref offset); + argOffs = imageReader.DecodeUnsignedGc(ref offset); AddNewTransition(new GcTransitionPointer((int)curOffs, argOffs, argCnt, Action.KILL, Header.EbpFrame)); break; case 0xF9: - argOffs = NativeReader.DecodeUnsignedGc(image, ref offset); + argOffs = imageReader.DecodeUnsignedGc(ref offset); argCnt += argOffs; break; default: @@ -203,7 +203,7 @@ private void GetTransitionsFullyInterruptible(byte[] image, ref int offset) /// /// based on GCDump::DumpGCTable /// - private void GetTransitionsEbpFrame(byte[] image, ref int offset) + private void GetTransitionsEbpFrame(NativeReader imageReader, ref int offset) { while (true) { @@ -218,7 +218,7 @@ private void GetTransitionsEbpFrame(byte[] image, ref int offset) uint curOffs = 0; // Get the next byte and check for a 'special' entry - uint encType = image[offset++]; + uint encType = imageReader.ReadByte(ref offset); GcTransitionCall transition = null; switch (encType) @@ -259,50 +259,50 @@ private void GetTransitionsEbpFrame(byte[] image, ref int offset) { // A small call entry curOffs += (val & 0x7F); - val = image[offset++]; + val = imageReader.ReadByte(ref offset); regMask = val >> 5; argMask = val & 0x1F; } break; case 0xFD: // medium encoding - argMask = image[offset++]; - val = image[offset++]; + argMask = imageReader.ReadByte(ref offset); + val = imageReader.ReadByte(ref offset); argMask |= (val & 0xF0) << 4; - nxt = image[offset++]; + nxt = imageReader.ReadByte(ref offset); curOffs += (val & 0x0F) + ((nxt & 0x1F) << 4); regMask = nxt >> 5; // EBX,ESI,EDI break; case 0xF9: // medium encoding with byrefs - curOffs += image[offset++]; - val = image[offset++]; + curOffs += imageReader.ReadByte(ref offset); + val = imageReader.ReadByte(ref offset); argMask = val & 0x1F; regMask = val >> 5; - val = image[offset++]; + val = imageReader.ReadByte(ref offset); byrefArgMask = val & 0x1F; byrefRegMask = val >> 5; break; case 0xFE: // large encoding case 0xFA: // large encoding with byrefs - val = image[offset++]; + val = imageReader.ReadByte(ref offset); regMask = val & 0x7; byrefRegMask = val >> 4; - curOffs += NativeReader.ReadUInt32(image, ref offset); - argMask = NativeReader.ReadUInt32(image, ref offset); + curOffs += imageReader.ReadUInt32(ref offset); + argMask = imageReader.ReadUInt32(ref offset); if (encType == 0xFA) // read byrefArgMask { - byrefArgMask = NativeReader.ReadUInt32(image, ref offset); + byrefArgMask = imageReader.ReadUInt32(ref offset); } break; case 0xFB: // huge encoding - val = image[offset++]; + val = imageReader.ReadByte(ref offset); regMask = val & 0x7; byrefRegMask = val >> 4; - curOffs = NativeReader.ReadUInt32(image, ref offset); - argCnt = NativeReader.ReadUInt32(image, ref offset); - argTabSize = NativeReader.ReadUInt32(image, ref offset); + curOffs = imageReader.ReadUInt32(ref offset); + argCnt = imageReader.ReadUInt32(ref offset); + argTabSize = imageReader.ReadUInt32(ref offset); argOffset = offset; offset += (int)argTabSize; break; @@ -326,7 +326,7 @@ argMask ... bitmask of pushed pointer arguments { do { - val = NativeReader.DecodeUnsignedGc(image, ref argOffset); + val = imageReader.DecodeUnsignedGc(ref argOffset); uint stkOffs = val & ~byref_OFFSET_FLAG; uint lowBit = val & byref_OFFSET_FLAG; @@ -346,7 +346,7 @@ argMask ... bitmask of pushed pointer arguments /// /// based on GCDump::DumpGCTable /// - private void SaveCallTransition(byte[] image, ref int offset, uint val, uint curOffs, uint callRegMask, bool callPndTab, uint callPndTabCnt, uint callPndMask, uint lastSkip, ref uint imask) + private void SaveCallTransition(NativeReader imageReader, ref int offset, uint val, uint curOffs, uint callRegMask, bool callPndTab, uint callPndTabCnt, uint callPndMask, uint lastSkip, ref uint imask) { uint iregMask, iargMask; iregMask = imask & 0xF; @@ -359,7 +359,7 @@ private void SaveCallTransition(byte[] image, ref int offset, uint val, uint cur { for (int i = 0; i < callPndTabCnt; i++) { - uint pndOffs = NativeReader.DecodeUnsignedGc(image, ref offset); + uint pndOffs = imageReader.DecodeUnsignedGc(ref offset); uint stkOffs = val & ~byref_OFFSET_FLAG; uint lowBit = val & byref_OFFSET_FLAG; @@ -377,7 +377,7 @@ private void SaveCallTransition(byte[] image, ref int offset, uint val, uint cur imask = lastSkip = 0; } - private void GetTransitionsNoEbp(byte[] image, ref int offset) + private void GetTransitionsNoEbp(NativeReader imageReader, ref int offset) { uint curOffs = 0; uint lastSkip = 0; @@ -385,7 +385,7 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) for (; ; ) { - uint val = image[offset++]; + uint val = imageReader.ReadByte(ref offset); if ((val & 0x80) == 0) { @@ -400,7 +400,7 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) else { // push 00100000 [pushCount] ESP push multiple items - uint pushCount = NativeReader.DecodeUnsignedGc(image, ref offset); + uint pushCount = imageReader.DecodeUnsignedGc(ref offset); AddNewTransition(new GcTransitionRegister((int)curOffs, Registers.ESP, Action.PUSH, false, false, (int)pushCount)); } } @@ -414,7 +414,7 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) // // skip 01000000 [Delta] Skip arbitrary sized delta // - skip = NativeReader.DecodeUnsignedGc(image, ref offset); + skip = imageReader.DecodeUnsignedGc(ref offset); curOffs += skip; lastSkip = skip; } @@ -450,7 +450,7 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) // CallPattern.DecodeCallPattern((val & 0x7f), out callArgCnt, out callRegMask, out callPndMask, out lastSkip); curOffs += lastSkip; - SaveCallTransition(image, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); + SaveCallTransition(imageReader, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); break; case 5: @@ -459,12 +459,12 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) // ArgMask=MMM Delta=commonDelta[DD] // callRegMask = val & 0xf; // EBP,EBX,ESI,EDI - val = image[offset++]; + val = imageReader.ReadByte(ref offset); callPndMask = (val & 0x7); callArgCnt = (val >> 3) & 0x7; lastSkip = CallPattern.callCommonDelta[val >> 6]; curOffs += lastSkip; - SaveCallTransition(image, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); + SaveCallTransition(imageReader, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); break; case 6: // @@ -472,16 +472,16 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) // Call ArgCnt,RegMask=RRR,ArgMask // callRegMask = val & 0xf; // EBP,EBX,ESI,EDI - callArgCnt = NativeReader.DecodeUnsignedGc(image, ref offset); - callPndMask = NativeReader.DecodeUnsignedGc(image, ref offset); - SaveCallTransition(image, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); + callArgCnt = imageReader.DecodeUnsignedGc(ref offset); + callPndMask = imageReader.DecodeUnsignedGc(ref offset); + SaveCallTransition(imageReader, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); break; case 7: switch (val & 0x0C) { case 0x00: // iptr 11110000 [IPtrMask] Arbitrary Interior Pointer Mask - imask = NativeReader.DecodeUnsignedGc(image, ref offset); + imask = imageReader.DecodeUnsignedGc(ref offset); AddNewTransition(new IPtrMask((int)curOffs, imask)); break; @@ -490,16 +490,16 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) break; case 0x08: - val = image[offset++]; + val = imageReader.ReadByte(ref offset); callRegMask = val & 0xF; imask = val >> 4; - lastSkip = NativeReader.ReadUInt32(image, ref offset); + lastSkip = imageReader.ReadUInt32(ref offset); curOffs += lastSkip; - callArgCnt = NativeReader.ReadUInt32(image, ref offset); - callPndTabCnt = NativeReader.ReadUInt32(image, ref offset); - callPndTabSize = NativeReader.ReadUInt32(image, ref offset); + callArgCnt = imageReader.ReadUInt32(ref offset); + callPndTabCnt = imageReader.ReadUInt32(ref offset); + callPndTabSize = imageReader.ReadUInt32(ref offset); callPndTab = true; - SaveCallTransition(image, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); + SaveCallTransition(imageReader, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); break; case 0x0C: return; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcSlotTable.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcSlotTable.cs index 534780b671834f..b4cf2795031d57 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcSlotTable.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcSlotTable.cs @@ -98,12 +98,12 @@ public override string ToString() public GcSlotTable() { } - public GcSlotTable(byte[] image, InfoHdrSmall header, ref int offset) + public GcSlotTable(NativeReader imageReader, InfoHdrSmall header, ref int offset) { GcSlots = new List(); - DecodeUntracked(image, header, ref offset); - DecodeFrameVariableLifetimeTable(image, header, ref offset); + DecodeUntracked(imageReader, header, ref offset); + DecodeFrameVariableLifetimeTable(imageReader, header, ref offset); } public override string ToString() @@ -124,7 +124,7 @@ public override string ToString() /// /// based on GCDump::DumpGCTable /// - private void DecodeUntracked(byte[] image, InfoHdrSmall header, ref int offset) + private void DecodeUntracked(NativeReader imageReader, InfoHdrSmall header, ref int offset) { uint calleeSavedRegs = 0; if (header.DoubleAlign) @@ -144,7 +144,7 @@ private void DecodeUntracked(byte[] image, InfoHdrSmall header, ref int offset) char reg = header.EbpFrame ? 'B' : 'S'; - stkOffsDelta = NativeReader.DecodeSignedGc(image, ref offset); + stkOffsDelta = imageReader.DecodeSignedGc(ref offset); int stkOffs = lastStkOffs - stkOffsDelta; lastStkOffs = stkOffs; @@ -165,15 +165,15 @@ private void DecodeUntracked(byte[] image, InfoHdrSmall header, ref int offset) /// /// based on GCDump::DumpGCTable /// - private void DecodeFrameVariableLifetimeTable(byte[] image, InfoHdrSmall header, ref int offset) + private void DecodeFrameVariableLifetimeTable(NativeReader imageReader, InfoHdrSmall header, ref int offset) { uint count = header.VarPtrTableSize; uint curOffs = 0; while (count-- > 0) { - uint varOffs = NativeReader.DecodeUnsignedGc(image, ref offset); - uint begOffs = NativeReader.DecodeUDelta(image, ref offset, curOffs); - uint endOffs = NativeReader.DecodeUDelta(image, ref offset, begOffs); + uint varOffs = imageReader.DecodeUnsignedGc(ref offset); + uint begOffs = imageReader.DecodeUDelta(ref offset, curOffs); + uint endOffs = imageReader.DecodeUDelta(ref offset, begOffs); uint lowBits = varOffs & 0x3; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/InfoHdr.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/InfoHdr.cs index b18706b7661dc2..7f2a22465f4a0d 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/InfoHdr.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/InfoHdr.cs @@ -158,7 +158,8 @@ public override string ToString() } }; - public class InfoHdrDecoder { + public class InfoHdrDecoder + { private const uint HAS_VARPTR = 0xFFFFFFFF; private const uint HAS_UNTRACKED = 0xFFFFFFFF; @@ -181,14 +182,14 @@ public static InfoHdrSmall GetInfoHdr(byte encoding) /// Initialize the GcInfo header /// based on src\inc\gcdecoder.cpp DecodeHeader and GCDump::DumpInfoHdr /// - public static InfoHdrSmall DecodeHeader(byte[] image, ref int offset, int codeLength) + public static InfoHdrSmall DecodeHeader(NativeReader imageReader, ref int offset, int codeLength) { - byte nextByte = image[offset++]; + byte nextByte = imageReader.ReadByte(ref offset); byte encoding = (byte)(nextByte & 0x7f); InfoHdrSmall header = GetInfoHdr(encoding); while ((nextByte & (uint)InfoHdrAdjustConstants.MORE_BYTES_TO_FOLLOW) != 0) { - nextByte = image[offset++]; + nextByte = imageReader.ReadByte(ref offset); encoding = (byte)(nextByte & (uint)InfoHdrAdjustConstants.ADJ_ENCODING_MAX); if (encoding < (uint)InfoHdrAdjust.NEXT_FOUR_START) @@ -284,7 +285,7 @@ public static InfoHdrSmall DecodeHeader(byte[] image, ref int offset, int codeLe break; case (byte)InfoHdrAdjust.NEXT_OPCODE: - nextByte = image[offset++]; + nextByte = imageReader.ReadByte(ref offset); encoding = (byte)(nextByte & (int)InfoHdrAdjustConstants.ADJ_ENCODING_MAX); // encoding here always corresponds to codes in InfoHdrAdjust2 set if (encoding <= (int)InfoHdrAdjustConstants.SET_RET_KIND_MAX) @@ -347,29 +348,29 @@ public static InfoHdrSmall DecodeHeader(byte[] image, ref int offset, int codeLe if (header.UntrackedCnt == HAS_UNTRACKED) { header.HasArgTabOffset = true; - header.UntrackedCnt = NativeReader.DecodeUnsignedGc(image, ref offset); + header.UntrackedCnt = imageReader.DecodeUnsignedGc(ref offset); } if (header.VarPtrTableSize == HAS_VARPTR) { header.HasArgTabOffset = true; - header.VarPtrTableSize = NativeReader.DecodeUnsignedGc(image, ref offset); + header.VarPtrTableSize = imageReader.DecodeUnsignedGc(ref offset); } if (header.GsCookieOffset == HAS_GS_COOKIE_OFFSET) { - header.GsCookieOffset = NativeReader.DecodeUnsignedGc(image, ref offset); + header.GsCookieOffset = imageReader.DecodeUnsignedGc(ref offset); } if (header.SyncStartOffset == HAS_SYNC_OFFSET) { - header.SyncStartOffset = NativeReader.DecodeUnsignedGc(image, ref offset); - header.SyncEndOffset = NativeReader.DecodeUnsignedGc(image, ref offset); + header.SyncStartOffset = imageReader.DecodeUnsignedGc(ref offset); + header.SyncEndOffset = imageReader.DecodeUnsignedGc(ref offset); } if (header.RevPInvokeOffset == HAS_REV_PINVOKE_FRAME_OFFSET) { - header.RevPInvokeOffset = NativeReader.DecodeUnsignedGc(image, ref offset); + header.RevPInvokeOffset = imageReader.DecodeUnsignedGc(ref offset); } if (header.NoGCRegionCnt == HAS_NOGCREGIONS) { - header.NoGCRegionCnt = NativeReader.DecodeUnsignedGc(image, ref offset); + header.NoGCRegionCnt = imageReader.DecodeUnsignedGc(ref offset); } header.Epilogs = new List(); @@ -379,7 +380,7 @@ public static InfoHdrSmall DecodeHeader(byte[] image, ref int offset, int codeLe for (int i = 0; i < header.EpilogCount; i++) { - offs = NativeReader.DecodeUDelta(image, ref offset, offs); + offs = imageReader.DecodeUDelta(ref offset, offs); header.Epilogs.Add((int)offs); } } @@ -391,7 +392,7 @@ public static InfoHdrSmall DecodeHeader(byte[] image, ref int offset, int codeLe if (header.HasArgTabOffset) { - header.ArgTabOffset = NativeReader.DecodeUnsignedGc(image, ref offset); + header.ArgTabOffset = imageReader.DecodeUnsignedGc(ref offset); } return header; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/NoGcRegionTable.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/NoGcRegionTable.cs index 4dcc332cb7ce73..96123c94a69d39 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/NoGcRegionTable.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/NoGcRegionTable.cs @@ -23,7 +23,7 @@ public NoGcRegion(uint offset, uint size) public override string ToString() { - return $" [{Offset:04X}-{Offset+Size:04X})\n"; + return $" [{Offset:04X}-{Offset + Size:04X})\n"; } } @@ -31,15 +31,15 @@ public override string ToString() public NoGcRegionTable() { } - public NoGcRegionTable(byte[] image, InfoHdrSmall header, ref int offset) + public NoGcRegionTable(NativeReader imageReader, InfoHdrSmall header, ref int offset) { Regions = new List((int)header.NoGCRegionCnt); uint count = header.NoGCRegionCnt; while (count-- > 0) { - uint regionOffset = NativeReader.DecodeUnsignedGc(image, ref offset); - uint regionSize = NativeReader.DecodeUnsignedGc(image, ref offset); + uint regionOffset = imageReader.DecodeUnsignedGc(ref offset); + uint regionSize = imageReader.DecodeUnsignedGc(ref offset); Regions.Add(new NoGcRegion(regionOffset, regionSize)); } } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/UnwindInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/UnwindInfo.cs index 6c699eec54bc14..8f5d1245026796 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/UnwindInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/UnwindInfo.cs @@ -14,10 +14,10 @@ public class UnwindInfo : BaseUnwindInfo public UnwindInfo() { } - public UnwindInfo(byte[] image, int offset) + public UnwindInfo(NativeReader imageReader, int offset) { int startOffset = offset; - FunctionLength = NativeReader.DecodeUnsignedGc(image, ref offset); + FunctionLength = imageReader.DecodeUnsignedGc(ref offset); Size = offset - startOffset; } diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs index 67266d36203b40..98b214e2b4785a 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs @@ -47,7 +47,8 @@ internal RyuJitCompilation( RyuJitCompilationOptions options, MethodLayoutAlgorithm methodLayoutAlgorithm, FileLayoutAlgorithm fileLayoutAlgorithm, - int parallelism) + int parallelism, + string orderFile) : base(dependencyGraph, nodeFactory, roots, ilProvider, debugInformationProvider, inliningPolicy, logger) { _compilationOptions = options; @@ -61,7 +62,7 @@ internal RyuJitCompilation( _parallelism = parallelism; - _fileLayoutOptimizer = new FileLayoutOptimizer(logger, methodLayoutAlgorithm, fileLayoutAlgorithm, profileDataManager, nodeFactory); + _fileLayoutOptimizer = new FileLayoutOptimizer(logger, methodLayoutAlgorithm, fileLayoutAlgorithm, profileDataManager, nodeFactory, orderFile); } public ProfileDataManager ProfileData => _profileDataManager; @@ -77,16 +78,23 @@ public override IEETypeNode NecessaryTypeSymbolIfPossible(TypeDesc type) // information proving that it isn't, give RyuJIT the constructed symbol even // though we just need the unconstructed one. // https://github.com/dotnet/runtimelab/issues/1128 - return GetLdTokenHelperForType(type) == ReadyToRunHelperId.TypeHandle - ? _nodeFactory.ConstructedTypeSymbol(type) - : _nodeFactory.NecessaryTypeSymbol(type); + return GetLdTokenHelperForType(type) switch + { + ReadyToRunHelperId.MetadataTypeHandle => _nodeFactory.MetadataTypeSymbol(type), + ReadyToRunHelperId.TypeHandle => _nodeFactory.MaximallyConstructableType(type), + ReadyToRunHelperId.NecessaryTypeHandle => _nodeFactory.NecessaryTypeSymbol(type), + _ => throw new UnreachableException() + }; } public FrozenRuntimeTypeNode NecessaryRuntimeTypeIfPossible(TypeDesc type) { - return GetLdTokenHelperForType(type) == ReadyToRunHelperId.TypeHandle - ? _nodeFactory.SerializedConstructedRuntimeTypeObject(type) - : _nodeFactory.SerializedNecessaryRuntimeTypeObject(type); + return GetLdTokenHelperForType(type) switch + { + ReadyToRunHelperId.TypeHandle or ReadyToRunHelperId.MetadataTypeHandle => _nodeFactory.SerializedMetadataRuntimeTypeObject(type), + ReadyToRunHelperId.NecessaryTypeHandle => _nodeFactory.SerializedNecessaryRuntimeTypeObject(type), + _ => throw new UnreachableException() + }; } protected override void CompileInternal(string outputFile, ObjectDumper dumper) diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs index b1291ac837dce8..d4c69d52a3aa93 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs @@ -21,6 +21,7 @@ public sealed class RyuJitCompilationBuilder : CompilationBuilder private FileLayoutAlgorithm _fileLayoutAlgorithm; private ILProvider _ilProvider = new NativeAotILProvider(); private ProfileDataManager _profileDataManager; + private string _orderFile; private string _jitPath; public RyuJitCompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup group) @@ -35,6 +36,12 @@ public RyuJitCompilationBuilder UseProfileData(IEnumerable mibcFiles) return this; } + public RyuJitCompilationBuilder UseSymbolOrder(string filePath) + { + _orderFile = filePath; + return this; + } + public RyuJitCompilationBuilder UseJitPath(string jitPath) { _jitPath = jitPath; @@ -129,7 +136,12 @@ public override ICompilation ToCompilation() if (_resilient) options |= RyuJitCompilationOptions.UseResilience; - ObjectDataInterner interner = _methodBodyFolding ? new ObjectDataInterner() : ObjectDataInterner.Null; + ObjectDataInterner interner = _methodBodyFolding switch + { + MethodBodyFoldingMode.Generic => new ObjectDataInterner(genericsOnly: true), + MethodBodyFoldingMode.All => new ObjectDataInterner(genericsOnly: false), + _ => ObjectDataInterner.Null, + }; var factory = new RyuJitNodeFactory(_context, _compilationGroup, _metadataManager, _interopStubManager, _nameMangler, _vtableSliceProvider, _dictionaryLayoutProvider, _inlinedThreadStatics, GetPreinitializationManager(), _devirtualizationManager, interner, _typeMapManager); @@ -149,7 +161,8 @@ public override ICompilation ToCompilation() options, _methodLayoutAlgorithm, _fileLayoutAlgorithm, - _parallelism); + _parallelism, + _orderFile); } } } diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index c727d22513ade5..d3882b864d4f3b 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -75,8 +75,11 @@ public void CompileMethod(MethodCodeNode methodCodeNodeNeedingCode, MethodIL met // https://github.com/dotnet/runtimelab/issues/1128 for (int i = 0; i < _codeRelocs.Count; i++) { - Debug.Assert(_codeRelocs[i].Target.GetType() != typeof(EETypeNode) - || _compilation.NecessaryTypeSymbolIfPossible(((EETypeNode)_codeRelocs[i].Target).Type) == _codeRelocs[i].Target); + if (_codeRelocs[i].Target is EETypeNode eetype) + { + IEETypeNode expectedeetype = _compilation.NecessaryTypeSymbolIfPossible(eetype.Type); + Debug.Assert(expectedeetype == eetype); + } } #endif @@ -420,7 +423,7 @@ private void getReadyToRunDelegateCtorHelper(ref CORINFO_RESOLVED_TOKEN pTargetM } else if (staticResolution is DefaultInterfaceMethodResolution.Diamond or DefaultInterfaceMethodResolution.Reabstraction) { - // TODO + // TODO: https://github.com/dotnet/runtime/issues/72589 ThrowHelper.ThrowInvalidProgramException(); } } @@ -602,30 +605,30 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) id = ReadyToRunHelper.NewObject; break; case CorInfoHelpFunc.CORINFO_HELP_NEWSFAST: - return _compilation.NodeFactory.ExternSymbol("RhpNewFast"); + return _compilation.NodeFactory.ExternFunctionSymbol("RhpNewFast"); case CorInfoHelpFunc.CORINFO_HELP_NEWSFAST_FINALIZE: - return _compilation.NodeFactory.ExternSymbol("RhpNewFinalizable"); + return _compilation.NodeFactory.ExternFunctionSymbol("RhpNewFinalizable"); case CorInfoHelpFunc.CORINFO_HELP_NEWSFAST_ALIGN8: - return _compilation.NodeFactory.ExternSymbol("RhpNewFastAlign8"); + return _compilation.NodeFactory.ExternFunctionSymbol("RhpNewFastAlign8"); case CorInfoHelpFunc.CORINFO_HELP_NEWSFAST_ALIGN8_FINALIZE: - return _compilation.NodeFactory.ExternSymbol("RhpNewFinalizableAlign8"); + return _compilation.NodeFactory.ExternFunctionSymbol("RhpNewFinalizableAlign8"); case CorInfoHelpFunc.CORINFO_HELP_NEWSFAST_ALIGN8_VC: - return _compilation.NodeFactory.ExternSymbol("RhpNewFastMisalign"); + return _compilation.NodeFactory.ExternFunctionSymbol("RhpNewFastMisalign"); case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_DIRECT: id = ReadyToRunHelper.NewArray; break; case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_PTR: - return _compilation.NodeFactory.ExternSymbol("RhpNewPtrArrayFast"); + return _compilation.NodeFactory.ExternFunctionSymbol("RhpNewPtrArrayFast"); case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_ALIGN8: - return _compilation.NodeFactory.ExternSymbol("RhpNewArrayFastAlign8"); + return _compilation.NodeFactory.ExternFunctionSymbol("RhpNewArrayFastAlign8"); case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_VC: - return _compilation.NodeFactory.ExternSymbol("RhpNewArrayFast"); + return _compilation.NodeFactory.ExternFunctionSymbol("RhpNewArrayFast"); case CorInfoHelpFunc.CORINFO_HELP_STACK_PROBE: - return _compilation.NodeFactory.ExternSymbol("RhpStackProbe"); + return _compilation.NodeFactory.ExternFunctionSymbol("RhpStackProbe"); case CorInfoHelpFunc.CORINFO_HELP_POLL_GC: - return _compilation.NodeFactory.ExternSymbol("RhpGcPoll"); + return _compilation.NodeFactory.ExternFunctionSymbol("RhpGcPoll"); case CorInfoHelpFunc.CORINFO_HELP_LMUL: id = ReadyToRunHelper.LMul; @@ -779,9 +782,9 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) break; case CorInfoHelpFunc.CORINFO_HELP_VALIDATE_INDIRECT_CALL: - return _compilation.NodeFactory.ExternIndirectSymbol("__guard_check_icall_fptr"); + return _compilation.NodeFactory.ExternIndirectFunctionSymbol("__guard_check_icall_fptr"); case CorInfoHelpFunc.CORINFO_HELP_DISPATCH_INDIRECT_CALL: - return _compilation.NodeFactory.ExternIndirectSymbol("__guard_dispatch_icall_fptr"); + return _compilation.NodeFactory.ExternIndirectFunctionSymbol("__guard_dispatch_icall_fptr"); default: throw new NotImplementedException(ftnNum.ToString()); @@ -794,7 +797,7 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) ISymbolNode entryPoint; if (mangledName != null) - entryPoint = _compilation.NodeFactory.ExternSymbol(mangledName); + entryPoint = _compilation.NodeFactory.ExternFunctionSymbol(mangledName); else entryPoint = _compilation.NodeFactory.MethodEntrypoint(methodDesc); @@ -1377,7 +1380,7 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO ThrowHelper.ThrowBadImageFormatException(); } - if (directCall && resolvedConstraint && pResult->exactContextNeedsRuntimeLookup) + if (directCall && resolvedConstraint && (pResult->exactContextNeedsRuntimeLookup || forceUseRuntimeLookup)) { // We want to do a direct call to a shared method on a type. We need to provide // a generic context, but the JitInterface doesn't provide a way for us to do it from here. @@ -1387,39 +1390,43 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO pResult->codePointerOrStubLookup.constLookup.accessType = InfoAccessType.IAT_VALUE; pResult->nullInstanceCheck = !targetMethod.Signature.IsStatic; - // We have the canonical version of the method - find the runtime determined version. - // For now simplify it by assuming the resolved method is on the same type as the constraint. - Debug.Assert(targetMethod.OwningType.GetTypeDefinition() == constrainedType.GetTypeDefinition()); TypeDesc runtimeDeterminedConstrainedType = (TypeDesc)GetRuntimeDeterminedObjectForToken(ref *pConstrainedResolvedToken); + object targetOfLookup; + ReadyToRunHelperId lookupHelper; if (forceUseRuntimeLookup) { - // The below logic would incorrectly resolve the lookup into the first match we found, - // but there was a compile-time ambiguity due to shared code. The correct fix should - // use the ConstrainedMethodUseLookupResult dictionary entry so that the exact - // dispatch can be computed with the help of the generic dictionary. - // We fail the compilation here to avoid bad codegen. This is not actually an invalid program. - // https://github.com/dotnet/runtimelab/issues/1431 - ThrowHelper.ThrowInvalidProgramException(); + MethodDesc runtimeDeterminedInterfaceMethod = (MethodDesc)GetRuntimeDeterminedObjectForToken(ref pResolvedToken); + targetOfLookup = new ConstrainedCallInfo(runtimeDeterminedConstrainedType, runtimeDeterminedInterfaceMethod); + lookupHelper = ReadyToRunHelperId.ConstrainedDirectCall; } - - MethodDesc targetOfLookup; - if (runtimeDeterminedConstrainedType.IsRuntimeDeterminedType) - targetOfLookup = _compilation.TypeSystemContext.GetMethodForRuntimeDeterminedType(targetMethod.GetTypicalMethodDefinition(), (RuntimeDeterminedType)runtimeDeterminedConstrainedType); - else if (runtimeDeterminedConstrainedType.HasInstantiation) - targetOfLookup = _compilation.TypeSystemContext.GetMethodForInstantiatedType(targetMethod.GetTypicalMethodDefinition(), (InstantiatedType)runtimeDeterminedConstrainedType); else - targetOfLookup = targetMethod.GetMethodDefinition(); - if (targetOfLookup.HasInstantiation) { - var methodToGetInstantiation = (MethodDesc)GetRuntimeDeterminedObjectForToken(ref pResolvedToken); - targetOfLookup = targetOfLookup.MakeInstantiatedMethod(methodToGetInstantiation.Instantiation); + // We have the canonical version of the method - find the runtime determined version. + // For now simplify it by assuming the resolved method is on the same type as the constraint. + Debug.Assert(targetMethod.OwningType.GetTypeDefinition() == constrainedType.GetTypeDefinition()); + + MethodDesc lookupMethod; + if (runtimeDeterminedConstrainedType.IsRuntimeDeterminedType) + lookupMethod = _compilation.TypeSystemContext.GetMethodForRuntimeDeterminedType(targetMethod.GetTypicalMethodDefinition(), (RuntimeDeterminedType)runtimeDeterminedConstrainedType); + else if (runtimeDeterminedConstrainedType.HasInstantiation) + lookupMethod = _compilation.TypeSystemContext.GetMethodForInstantiatedType(targetMethod.GetTypicalMethodDefinition(), (InstantiatedType)runtimeDeterminedConstrainedType); + else + lookupMethod = targetMethod.GetMethodDefinition(); + if (lookupMethod.HasInstantiation) + { + var methodToGetInstantiation = (MethodDesc)GetRuntimeDeterminedObjectForToken(ref pResolvedToken); + lookupMethod = lookupMethod.MakeInstantiatedMethod(methodToGetInstantiation.Instantiation); + } + Debug.Assert(lookupMethod.GetCanonMethodTarget(CanonicalFormKind.Specific) == targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific)); + + targetOfLookup = lookupMethod; + lookupHelper = ReadyToRunHelperId.MethodEntry; } - Debug.Assert(targetOfLookup.GetCanonMethodTarget(CanonicalFormKind.Specific) == targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific)); ComputeLookup(ref pResolvedToken, targetOfLookup, - ReadyToRunHelperId.MethodEntry, + lookupHelper, HandleToObject(callerHandle), ref pResult->codePointerOrStubLookup); @@ -1641,7 +1648,7 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO // If this is LDVIRTFTN of an interface method that is part of a verifiable delegate creation sequence, // RyuJIT is not going to use this value. pResult->exactContextNeedsRuntimeLookup = false; - pResult->codePointerOrStubLookup.constLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.ExternSymbol("NYI_LDVIRTFTN")); + pResult->codePointerOrStubLookup.constLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.ExternFunctionSymbol("NYI_LDVIRTFTN")); } else { @@ -1773,7 +1780,8 @@ private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool if (pResolvedToken.tokenType == CorInfoTokenKind.CORINFO_TOKENKIND_NewObj || pResolvedToken.tokenType == CorInfoTokenKind.CORINFO_TOKENKIND_Newarr || pResolvedToken.tokenType == CorInfoTokenKind.CORINFO_TOKENKIND_Box - || pResolvedToken.tokenType == CorInfoTokenKind.CORINFO_TOKENKIND_Constrained) + || pResolvedToken.tokenType == CorInfoTokenKind.CORINFO_TOKENKIND_Constrained + || pResolvedToken.tokenType == CorInfoTokenKind.CORINFO_TOKENKIND_Method) { helperId = ReadyToRunHelperId.TypeHandle; } @@ -1783,7 +1791,26 @@ private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool } else if (pResolvedToken.tokenType == CorInfoTokenKind.CORINFO_TOKENKIND_Ldtoken) { - helperId = _compilation.GetLdTokenHelperForType(td); + if (((TypeDesc)target).IsRuntimeDeterminedSubtype) + { + // If we're in a generic context and the type is canonical, Compilation cannot give + // us a good answer on what handle kind to use because we don't track canonical forms. + // If we already have a fixed generic dictionary layout (a build with a scanner pass), + // ask for NecessaryTypeSymbol - it will get upgraded as needed. + // If we don't have a fixed dictionary layout, ask for a full type symbol because that's + // always correct. + MethodDesc callerContextMethod = HandleToObject(callerHandle); + DictionaryLayoutNode contextLayout = _compilation.NodeFactory.GenericDictionaryLayout( + callerContextMethod.RequiresInstMethodDescArg() ? callerContextMethod : callerContextMethod.OwningType); + if (contextLayout.HasFixedSlots) + helperId = ReadyToRunHelperId.NecessaryTypeHandle; + else + helperId = ReadyToRunHelperId.TypeHandle; + } + else + { + helperId = _compilation.GetLdTokenHelperForType(td); + } } else { @@ -1874,26 +1901,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"); @@ -1913,7 +1920,7 @@ private void getAddressOfPInvokeTarget(CORINFO_METHOD_STRUCT_* method, ref CORIN string externName = _compilation.PInvokeILProvider.GetDirectCallExternName(md); externName = _compilation.NodeFactory.NameMangler.NodeMangler.ExternMethod(externName, md); - pLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.ExternSymbol(externName)); + pLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.ExternFunctionSymbol(externName)); } private void getGSCookie(IntPtr* pCookieVal, IntPtr** ppCookieVal) @@ -2019,9 +2026,6 @@ private int SizeOfPInvokeTransitionFrame } } - private bool canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig) - { throw new NotImplementedException("canGetCookieForPInvokeCalliSig"); } - #pragma warning disable CA1822 // Mark members as static private void classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_STRUCT_* cls) #pragma warning restore CA1822 // Mark members as static @@ -2251,6 +2255,10 @@ private bool CanNeverHaveInstanceOfSubclassOf(TypeDesc type) if (!ConstructedEETypeNode.CreationAllowed(type)) return false; + // We don't track information that would allow us to deal with array variance + if (_compilation.TypeSystemContext.IsArrayVariantCastable(type)) + return false; + TypeDesc canonType = type.ConvertToCanonForm(CanonicalFormKind.Specific); // If we don't have a constructed MethodTable for the exact type or for its template, @@ -2468,10 +2476,10 @@ private bool getStaticBaseAddress(CORINFO_CLASS_STRUCT_* cls, bool isGc, ref COR private void getThreadLocalStaticInfo_NativeAOT(CORINFO_THREAD_STATIC_INFO_NATIVEAOT* pInfo) { pInfo->offsetOfThreadLocalStoragePointer = (uint)(11 * PointerSize); // Offset of ThreadLocalStoragePointer in the TEB - pInfo->tlsIndexObject = CreateConstLookupToSymbol(_compilation.NodeFactory.ExternSymbol("_tls_index")); + pInfo->tlsIndexObject = CreateConstLookupToSymbol(_compilation.NodeFactory.ExternDataSymbol("_tls_index")); pInfo->tlsRootObject = CreateConstLookupToSymbol(_compilation.NodeFactory.TlsRoot); pInfo->threadStaticBaseSlow = CreateConstLookupToSymbol(_compilation.NodeFactory.HelperEntrypoint(HelperEntrypoint.GetInlinedThreadStaticBaseSlow)); - pInfo->tlsGetAddrFtnPtr = CreateConstLookupToSymbol(_compilation.NodeFactory.ExternSymbol("__tls_get_addr")); + pInfo->tlsGetAddrFtnPtr = CreateConstLookupToSymbol(_compilation.NodeFactory.ExternFunctionSymbol("__tls_get_addr")); } #pragma warning disable CA1822 // Mark members as static diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/Extensions/CecilExtensions.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/Extensions/CecilExtensions.cs index 5e4dc5ffa1e137..5afa83d0a8957f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/Extensions/CecilExtensions.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/Extensions/CecilExtensions.cs @@ -10,355 +10,376 @@ namespace Mono.Linker.Tests.Extensions { - public static class CecilExtensions - { - public static IEnumerable AllDefinedTypes (this AssemblyDefinition assemblyDefinition) - { - return assemblyDefinition.Modules.SelectMany (m => m.AllDefinedTypes ()); - } - - public static IEnumerable AllDefinedTypes (this ModuleDefinition moduleDefinition) - { - foreach (var typeDefinition in moduleDefinition.Types) { - yield return typeDefinition; - - foreach (var definition in typeDefinition.AllDefinedTypes ()) - yield return definition; - } - } - - public static IEnumerable AllDefinedTypes (this TypeDefinition typeDefinition) - { - foreach (var nestedType in typeDefinition.NestedTypes) { - yield return nestedType; - - foreach (var definition in nestedType.AllDefinedTypes ()) - yield return definition; - } - } - - public static IEnumerable AllMembers (this ModuleDefinition module) - { - foreach (var type in module.AllDefinedTypes ()) { - yield return type; - - foreach (var member in type.AllMembers ()) - yield return member; - } - } - - public static IEnumerable AllMembers (this TypeDefinition type) - { - foreach (var field in type.Fields) - yield return field; - - foreach (var prop in type.Properties) - yield return prop; - - foreach (var method in type.Methods) - yield return method; - - foreach (var @event in type.Events) - yield return @event; - } - - public static IEnumerable AllMethods (this TypeDefinition type) - { - foreach (var m in type.AllMembers ()) { - switch (m) { - case MethodDefinition method: - yield return method; - break; - case PropertyDefinition @property: - if (@property.GetMethod != null) - yield return @property.GetMethod; - - if (@property.SetMethod != null) - yield return @property.SetMethod; - - break; - case EventDefinition @event: - if (@event.AddMethod != null) - yield return @event.AddMethod; - - if (@event.RemoveMethod != null) - yield return @event.RemoveMethod; - - break; - - default: - break; - } - } - } - - public static bool HasAttribute (this ICustomAttributeProvider provider, string name) - { - return provider.CustomAttributes.Any (ca => ca.AttributeType.Name == name); - } - - public static bool HasAttributeDerivedFrom (this ICustomAttributeProvider provider, string name) - { - return provider.CustomAttributes.Any (ca => ca.AttributeType.Resolve ().DerivesFrom (name)); - } - - public static bool DerivesFrom (this TypeDefinition type, string baseTypeName) - { - if (type.Name == baseTypeName) - return true; - - if (type.BaseType == null) - return false; - - if (type.BaseType.Name == baseTypeName) - return true; - - return type.BaseType.Resolve ()?.DerivesFrom (baseTypeName) ?? false; - } - - public static PropertyDefinition GetPropertyDefinition (this MethodDefinition method) - { - if (!method.IsSetter && !method.IsGetter) + public static class CecilExtensions + { + public static IEnumerable AllDefinedTypes(this AssemblyDefinition assemblyDefinition) + { + return assemblyDefinition.Modules.SelectMany(m => m.AllDefinedTypes()); + } + + public static IEnumerable AllDefinedTypes(this ModuleDefinition moduleDefinition) + { + foreach (var typeDefinition in moduleDefinition.Types) + { + yield return typeDefinition; + + foreach (var definition in typeDefinition.AllDefinedTypes()) + yield return definition; + } + } + + public static IEnumerable AllDefinedTypes(this TypeDefinition typeDefinition) + { + foreach (var nestedType in typeDefinition.NestedTypes) + { + yield return nestedType; + + foreach (var definition in nestedType.AllDefinedTypes()) + yield return definition; + } + } + + public static IEnumerable AllMembers(this ModuleDefinition module) + { + foreach (var type in module.AllDefinedTypes()) + { + yield return type; + + foreach (var member in type.AllMembers()) + yield return member; + } + } + + public static IEnumerable AllMembers(this TypeDefinition type) + { + foreach (var field in type.Fields) + yield return field; + + foreach (var prop in type.Properties) + yield return prop; + + foreach (var method in type.Methods) + yield return method; + + foreach (var @event in type.Events) + yield return @event; + } + + public static IEnumerable AllMethods(this TypeDefinition type) + { + foreach (var m in type.AllMembers()) + { + switch (m) + { + case MethodDefinition method: + yield return method; + break; + case PropertyDefinition @property: + if (@property.GetMethod != null) + yield return @property.GetMethod; + + if (@property.SetMethod != null) + yield return @property.SetMethod; + + break; + case EventDefinition @event: + if (@event.AddMethod != null) + yield return @event.AddMethod; + + if (@event.RemoveMethod != null) + yield return @event.RemoveMethod; + + break; + + default: + break; + } + } + } + + public static bool HasAttribute(this ICustomAttributeProvider provider, string name) + { + return provider.CustomAttributes.Any(ca => ca.AttributeType.Name == name); + } + + public static bool HasAttributeDerivedFrom(this ICustomAttributeProvider provider, string name) + { + return provider.CustomAttributes.Any(ca => ca.AttributeType.Resolve().DerivesFrom(name)); + } + + public static bool DerivesFrom(this TypeDefinition type, string baseTypeName) + { + if (type.Name == baseTypeName) + return true; + + if (type.BaseType == null) + return false; + + if (type.BaseType.Name == baseTypeName) + return true; + + return type.BaseType.Resolve()?.DerivesFrom(baseTypeName) ?? false; + } + + public static PropertyDefinition GetPropertyDefinition(this MethodDefinition method) + { + if (!method.IsSetter && !method.IsGetter) #pragma warning disable CA2208 // Instantiate argument exceptions correctly - throw new ArgumentException (); + throw new ArgumentException(); #pragma warning restore CA2208 // Instantiate argument exceptions correctly - var propertyName = method.Name.Substring (4); - return method.DeclaringType.Properties.First (p => p.Name == propertyName); - } - - public static string GetSignature (this MethodDefinition method) - { - var builder = new StringBuilder (); - builder.Append (method.Name); - if (method.HasGenericParameters) { - builder.Append ($"<#{method.GenericParameters.Count}>"); - } - - builder.Append ('('); - - if (method.HasParameters) { - for (int i = 0; i < method.Parameters.Count - 1; i++) { - // TODO: modifiers - // TODO: default values - builder.Append ($"{method.Parameters[i].ParameterType},"); - } - - builder.Append (method.Parameters[method.Parameters.Count - 1].ParameterType); - } - - builder.Append (')'); - - return builder.ToString (); - } - - public static object GetConstructorArgumentValue (this CustomAttribute attr, int argumentIndex) - { - return attr.ConstructorArguments[argumentIndex].Value; - } - - public static object? GetPropertyValue (this CustomAttribute attr, string propertyName) - { - foreach (var prop in attr.Properties) - if (prop.Name == propertyName) - return prop.Argument.Value; - - return null; - } - - public static bool IsEventMethod (this MethodDefinition md) - { - return (md.SemanticsAttributes & MethodSemanticsAttributes.AddOn) != 0 || - (md.SemanticsAttributes & MethodSemanticsAttributes.Fire) != 0 || - (md.SemanticsAttributes & MethodSemanticsAttributes.RemoveOn) != 0; - } - - public static string GetDisplayName (this MethodReference method) - { - var sb = new System.Text.StringBuilder (); - - // Match C# syntaxis name if setter or getter - var methodDefinition = method.Resolve (); - if (methodDefinition != null && (methodDefinition.IsSetter || methodDefinition.IsGetter)) { - // Append property name - string name = GetPropertyNameFromAccessorName (methodDefinition.Name, methodDefinition.IsSetter); - sb.Append (name); - // Insert declaring type name and namespace - sb.Insert (0, '.').Insert (0, method.DeclaringType?.GetDisplayName ()); - return sb.ToString (); - } - - if (methodDefinition != null && methodDefinition.IsEventMethod ()) { - // Append event name - string name = methodDefinition.SemanticsAttributes switch { - MethodSemanticsAttributes.AddOn => string.Concat (methodDefinition.Name.AsSpan (4), ".add"), - MethodSemanticsAttributes.RemoveOn => string.Concat (methodDefinition.Name.AsSpan (7), ".remove"), - MethodSemanticsAttributes.Fire => string.Concat (methodDefinition.Name.AsSpan (6), ".raise"), - _ => throw new NotSupportedException (), - }; - sb.Append (name); - // Insert declaring type name and namespace - sb.Insert (0, '.').Insert (0, method.DeclaringType.GetDisplayName ()); - return sb.ToString (); - } - - // Append parameters - sb.Append ('('); - if (method.HasParameters) { - for (int i = 0; i < method.Parameters.Count - 1; i++) - sb.Append (method.Parameters[i].ParameterType.GetDisplayNameWithoutNamespace ()).Append (", "); - - sb.Append (method.Parameters[method.Parameters.Count - 1].ParameterType.GetDisplayNameWithoutNamespace ()); - } - - sb.Append (')'); - - // Insert generic parameters - if (method.HasGenericParameters) { - PrependGenericParameters (method.GenericParameters, sb); - } - - // Insert method name - if (method.Name == ".ctor") - sb.Insert (0, method.DeclaringType.Name); - else - sb.Insert (0, method.Name); - - // Insert declaring type name and namespace - if (method.DeclaringType != null) - sb.Insert (0, '.').Insert (0, method.DeclaringType.GetDisplayName ()); - - return sb.ToString (); - } - - private static string GetPropertyNameFromAccessorName (string methodName, bool isSetter) => - isSetter ? - string.Concat (methodName.StartsWith ("set_") ? methodName.AsSpan (4) : methodName.Replace (".set_", "."), ".set") : - string.Concat (methodName.StartsWith ("get_") ? methodName.AsSpan (4) : methodName.Replace (".get_", "."), ".get"); - - public static string GetDisplayName (this TypeReference type) - { - var builder = GetDisplayNameWithoutNamespace (type); - var namespaceDisplayName = type.GetNamespaceDisplayName (); - if (!string.IsNullOrEmpty (namespaceDisplayName)) { - builder.Insert (0, "."); - builder.Insert (0, namespaceDisplayName); - } - - return builder.ToString (); - } - - public static string GetDisplayName (this FieldReference field) - { - var builder = new StringBuilder (); - if (field.DeclaringType != null) { - builder.Append (field.DeclaringType.GetDisplayName ()); - builder.Append ('.'); - } - - builder.Append (field.Name); - - return builder.ToString (); - } - - public static string GetNamespaceDisplayName (this MemberReference member) - { - var type = member is TypeReference typeReference ? typeReference : member.DeclaringType; - while (type.DeclaringType != null) - type = type.DeclaringType; - - return type.Namespace; - } - - public static StringBuilder GetDisplayNameWithoutNamespace (this TypeReference type) - { - var sb = new StringBuilder (); - if (type == null) - return sb; - - Stack? genericArguments = null; - while (true) { - switch (type) { - case ArrayType arrayType: - AppendArrayType (arrayType, sb); - break; - case GenericInstanceType genericInstanceType: - genericArguments = new Stack (genericInstanceType.GenericArguments); - type = genericInstanceType.ElementType; - continue; - default: - if (type.HasGenericParameters) { - int genericParametersCount = type.GenericParameters.Count; - int declaringTypeGenericParametersCount = type.DeclaringType?.GenericParameters?.Count ?? 0; - - string simpleName; - if (genericParametersCount > declaringTypeGenericParametersCount) { - if (genericArguments?.Count > 0) - PrependGenericArguments (genericArguments, genericParametersCount - declaringTypeGenericParametersCount, sb); - else - PrependGenericParameters (type.GenericParameters.Skip (declaringTypeGenericParametersCount).ToList (), sb); - - int explicitArityIndex = type.Name.IndexOf ('`'); - simpleName = explicitArityIndex != -1 ? type.Name.Substring (0, explicitArityIndex) : type.Name; - } else - simpleName = type.Name; - - sb.Insert (0, simpleName); - break; - } - - sb.Insert (0, type.Name); - break; - } - - type = type.GetElementType (); - if (type.DeclaringType is not TypeReference declaringType) - break; - - type = declaringType; - - sb.Insert (0, '.'); - } - - return sb; - } - - public static void PrependGenericParameters (IList genericParameters, StringBuilder sb) - { - sb.Insert (0, '>').Insert (0, genericParameters[genericParameters.Count - 1]); - for (int i = genericParameters.Count - 2; i >= 0; i--) - sb.Insert (0, ',').Insert (0, genericParameters[i]); - - sb.Insert (0, '<'); - } - - private static void PrependGenericArguments (Stack genericArguments, int argumentsToTake, StringBuilder sb) - { - sb.Insert (0, '>').Insert (0, genericArguments.Pop ().GetDisplayNameWithoutNamespace ().ToString ()); - while (--argumentsToTake > 0) - sb.Insert (0, ',').Insert (0, genericArguments.Pop ().GetDisplayNameWithoutNamespace ().ToString ()); - - sb.Insert (0, '<'); - } - - private static void AppendArrayType (ArrayType arrayType, StringBuilder sb) - { - void parseArrayDimensions (ArrayType at) - { - sb.Append ('['); - for (int i = 0; i < at.Dimensions.Count - 1; i++) - sb.Append (','); - - sb.Append (']'); - } - - sb.Append (arrayType.Name.AsSpan (0, arrayType.Name.IndexOf ('['))); - parseArrayDimensions (arrayType); - var element = arrayType.ElementType as ArrayType; - while (element != null) { - parseArrayDimensions (element); - element = element.ElementType as ArrayType; - } - } - } + var propertyName = method.Name.Substring(4); + return method.DeclaringType.Properties.First(p => p.Name == propertyName); + } + + public static string GetSignature(this MethodDefinition method) + { + var builder = new StringBuilder(); + builder.Append(method.Name); + if (method.HasGenericParameters) + { + builder.Append($"<#{method.GenericParameters.Count}>"); + } + + builder.Append('('); + + if (method.HasParameters) + { + for (int i = 0; i < method.Parameters.Count - 1; i++) + { + // TODO: modifiers + // TODO: default values + builder.Append($"{method.Parameters[i].ParameterType},"); + } + + builder.Append(method.Parameters[method.Parameters.Count - 1].ParameterType); + } + + builder.Append(')'); + + return builder.ToString(); + } + + public static object GetConstructorArgumentValue(this CustomAttribute attr, int argumentIndex) + { + return attr.ConstructorArguments[argumentIndex].Value; + } + + public static object? GetPropertyValue(this CustomAttribute attr, string propertyName) + { + foreach (var prop in attr.Properties) + if (prop.Name == propertyName) + return prop.Argument.Value; + + return null; + } + + public static bool IsEventMethod(this MethodDefinition md) + { + return (md.SemanticsAttributes & MethodSemanticsAttributes.AddOn) != 0 || + (md.SemanticsAttributes & MethodSemanticsAttributes.Fire) != 0 || + (md.SemanticsAttributes & MethodSemanticsAttributes.RemoveOn) != 0; + } + + public static string GetDisplayName(this MethodReference method) + { + var sb = new System.Text.StringBuilder(); + + // Match C# syntaxis name if setter or getter + var methodDefinition = method.Resolve(); + if (methodDefinition != null && (methodDefinition.IsSetter || methodDefinition.IsGetter)) + { + // Append property name + string name = GetPropertyNameFromAccessorName(methodDefinition.Name, methodDefinition.IsSetter); + sb.Append(name); + // Insert declaring type name and namespace + sb.Insert(0, '.').Insert(0, method.DeclaringType?.GetDisplayName()); + return sb.ToString(); + } + + if (methodDefinition != null && methodDefinition.IsEventMethod()) + { + // Append event name + string name = methodDefinition.SemanticsAttributes switch + { + MethodSemanticsAttributes.AddOn => string.Concat(methodDefinition.Name.AsSpan(4), ".add"), + MethodSemanticsAttributes.RemoveOn => string.Concat(methodDefinition.Name.AsSpan(7), ".remove"), + MethodSemanticsAttributes.Fire => string.Concat(methodDefinition.Name.AsSpan(6), ".raise"), + _ => throw new NotSupportedException(), + }; + sb.Append(name); + // Insert declaring type name and namespace + sb.Insert(0, '.').Insert(0, method.DeclaringType.GetDisplayName()); + return sb.ToString(); + } + + // Append parameters + sb.Append('('); + if (method.HasParameters) + { + for (int i = 0; i < method.Parameters.Count - 1; i++) + sb.Append(method.Parameters[i].ParameterType.GetDisplayNameWithoutNamespace()).Append(", "); + + sb.Append(method.Parameters[method.Parameters.Count - 1].ParameterType.GetDisplayNameWithoutNamespace()); + } + + sb.Append(')'); + + // Insert generic parameters + if (method.HasGenericParameters) + { + PrependGenericParameters(method.GenericParameters, sb); + } + + // Insert method name + if (method.Name == ".ctor") + sb.Insert(0, method.DeclaringType.Name); + else + sb.Insert(0, method.Name); + + // Insert declaring type name and namespace + if (method.DeclaringType != null) + sb.Insert(0, '.').Insert(0, method.DeclaringType.GetDisplayName()); + + return sb.ToString(); + } + + private static string GetPropertyNameFromAccessorName(string methodName, bool isSetter) => + isSetter ? + string.Concat(methodName.StartsWith("set_") ? methodName.AsSpan(4) : methodName.Replace(".set_", "."), ".set") : + string.Concat(methodName.StartsWith("get_") ? methodName.AsSpan(4) : methodName.Replace(".get_", "."), ".get"); + + public static string GetDisplayName(this TypeReference type) + { + var builder = GetDisplayNameWithoutNamespace(type); + var namespaceDisplayName = type.GetNamespaceDisplayName(); + if (!string.IsNullOrEmpty(namespaceDisplayName)) + { + builder.Insert(0, "."); + builder.Insert(0, namespaceDisplayName); + } + + return builder.ToString(); + } + + public static string GetDisplayName(this FieldReference field) + { + var builder = new StringBuilder(); + if (field.DeclaringType != null) + { + builder.Append(field.DeclaringType.GetDisplayName()); + builder.Append('.'); + } + + builder.Append(field.Name); + + return builder.ToString(); + } + + public static string GetNamespaceDisplayName(this MemberReference member) + { + var type = member is TypeReference typeReference ? typeReference : member.DeclaringType; + while (type.DeclaringType != null) + type = type.DeclaringType; + + return type.Namespace; + } + + public static StringBuilder GetDisplayNameWithoutNamespace(this TypeReference type) + { + var sb = new StringBuilder(); + if (type == null) + return sb; + + Stack? genericArguments = null; + while (true) + { + switch (type) + { + case ArrayType arrayType: + AppendArrayType(arrayType, sb); + break; + case GenericInstanceType genericInstanceType: + genericArguments = new Stack(genericInstanceType.GenericArguments); + type = genericInstanceType.ElementType; + continue; + default: + if (type.HasGenericParameters) + { + int genericParametersCount = type.GenericParameters.Count; + int declaringTypeGenericParametersCount = type.DeclaringType?.GenericParameters?.Count ?? 0; + + string simpleName; + if (genericParametersCount > declaringTypeGenericParametersCount) + { + if (genericArguments?.Count > 0) + PrependGenericArguments(genericArguments, genericParametersCount - declaringTypeGenericParametersCount, sb); + else + PrependGenericParameters(type.GenericParameters.Skip(declaringTypeGenericParametersCount).ToList(), sb); + + int explicitArityIndex = type.Name.IndexOf('`'); + simpleName = explicitArityIndex != -1 ? type.Name.Substring(0, explicitArityIndex) : type.Name; + } + else + simpleName = type.Name; + + sb.Insert(0, simpleName); + break; + } + + sb.Insert(0, type.Name); + break; + } + + type = type.GetElementType(); + if (type.DeclaringType is not TypeReference declaringType) + break; + + type = declaringType; + + sb.Insert(0, '.'); + } + + return sb; + } + + public static void PrependGenericParameters(IList genericParameters, StringBuilder sb) + { + sb.Insert(0, '>').Insert(0, genericParameters[genericParameters.Count - 1]); + for (int i = genericParameters.Count - 2; i >= 0; i--) + sb.Insert(0, ',').Insert(0, genericParameters[i]); + + sb.Insert(0, '<'); + } + + private static void PrependGenericArguments(Stack genericArguments, int argumentsToTake, StringBuilder sb) + { + sb.Insert(0, '>').Insert(0, genericArguments.Pop().GetDisplayNameWithoutNamespace().ToString()); + while (--argumentsToTake > 0) + sb.Insert(0, ',').Insert(0, genericArguments.Pop().GetDisplayNameWithoutNamespace().ToString()); + + sb.Insert(0, '<'); + } + + private static void AppendArrayType(ArrayType arrayType, StringBuilder sb) + { + void parseArrayDimensions(ArrayType at) + { + sb.Append('['); + for (int i = 0; i < at.Dimensions.Count - 1; i++) + sb.Append(','); + + sb.Append(']'); + } + + sb.Append(arrayType.Name.AsSpan(0, arrayType.Name.IndexOf('['))); + parseArrayDimensions(arrayType); + var element = arrayType.ElementType as ArrayType; + while (element != null) + { + parseArrayDimensions(element); + element = element.ElementType as ArrayType; + } + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/Extensions/NiceIO.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/Extensions/NiceIO.cs index 791d6b4d408539..30e04ade65b183 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/Extensions/NiceIO.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/Extensions/NiceIO.cs @@ -35,829 +35,877 @@ namespace Mono.Linker.Tests.Extensions { - public class NPath : IEquatable, IComparable - { - private static readonly StringComparison PathStringComparison = IsLinux () ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; - - private readonly string[] _elements; - private readonly bool _isRelative; - private readonly string? _driveLetter; - - #region construction - - public NPath (string path) - { - ArgumentNullException.ThrowIfNull (path); - - path = ParseDriveLetter (path, out _driveLetter); - - if (path == "/") { - _isRelative = false; - _elements = Array.Empty (); - } else { - var split = path.Split ('/', '\\'); - - _isRelative = _driveLetter == null && IsRelativeFromSplitString (split); - - _elements = ParseSplitStringIntoElements (split.Where (s => s.Length > 0).ToArray ()); - } - } - - private NPath (string[] elements, bool isRelative, string? driveLetter) - { - _elements = elements; - _isRelative = isRelative; - _driveLetter = driveLetter; - } - - private string[] ParseSplitStringIntoElements (IEnumerable inputs) - { - var stack = new List (); - - foreach (var input in inputs.Where (input => input.Length != 0)) { - if (input == ".") { - if ((stack.Count > 0) && (stack.Last () != ".")) - continue; - } else if (input == "..") { - if (HasNonDotDotLastElement (stack)) { - stack.RemoveAt (stack.Count - 1); - continue; - } - if (!_isRelative) - throw new ArgumentException ("You cannot create a path that tries to .. past the root"); - } - stack.Add (input); - } - return stack.ToArray (); - } - - private static bool HasNonDotDotLastElement (List stack) - { - return stack.Count > 0 && stack[stack.Count - 1] != ".."; - } - - private static string ParseDriveLetter (string path, out string? driveLetter) - { - if (path.Length >= 2 && path[1] == ':') { - driveLetter = path[0].ToString (); - return path.Substring (2); - } - - driveLetter = null; - return path; - } - - private static bool IsRelativeFromSplitString (string[] split) - { - if (split.Length < 2) - return true; - - return split[0].Length != 0 || !split.Any (s => s.Length > 0); - } - - public NPath Combine (params string[] append) - { - return Combine (append.Select (a => new NPath (a)).ToArray ()); - } - - public NPath Combine (params NPath[] append) - { - if (!append.All (p => p.IsRelative)) - throw new ArgumentException ("You cannot .Combine a non-relative path"); - - return new NPath (ParseSplitStringIntoElements (_elements.Concat (append.SelectMany (p => p._elements))), _isRelative, _driveLetter); - } - - public NPath Parent { - get { - if (_elements.Length == 0) - throw new InvalidOperationException ("Parent is called on an empty path"); - - var newElements = _elements.Take (_elements.Length - 1).ToArray (); - - return new NPath (newElements, _isRelative, _driveLetter); - } - } - - public NPath RelativeTo (NPath path) - { - if (!IsChildOf (path)) { - if (!IsRelative && !path.IsRelative && _driveLetter != path._driveLetter) - throw new ArgumentException ("Path.RelativeTo() was invoked with two paths that are on different volumes. invoked on: " + ToString () + " asked to be made relative to: " + path); - - NPath? commonParent = null; - foreach (var parent in RecursiveParents) { - commonParent = path.RecursiveParents.FirstOrDefault (otherParent => otherParent == parent); - - if (commonParent != null) - break; - } - - if (commonParent == null) - throw new ArgumentException ("Path.RelativeTo() was unable to find a common parent between " + ToString () + " and " + path); - - if (IsRelative && path.IsRelative && commonParent.IsEmpty ()) - throw new ArgumentException ("Path.RelativeTo() was invoked with two relative paths that do not share a common parent. Invoked on: " + ToString () + " asked to be made relative to: " + path); - - var depthDiff = path.Depth - commonParent.Depth; - return new NPath (Enumerable.Repeat ("..", depthDiff).Concat (_elements.Skip (commonParent.Depth)).ToArray (), true, null); - } - - return new NPath (_elements.Skip (path._elements.Length).ToArray (), true, null); - } - - public NPath ChangeExtension (string extension) - { - ThrowIfRoot (); - - var newElements = (string[]) _elements.Clone (); - newElements[newElements.Length - 1] = Path.ChangeExtension (_elements[_elements.Length - 1], WithDot (extension)); - if (extension == string.Empty) - newElements[newElements.Length - 1] = newElements[newElements.Length - 1].TrimEnd ('.'); - return new NPath (newElements, _isRelative, _driveLetter); - } - #endregion construction - - #region inspection - - public bool IsRelative { - get { return _isRelative; } - } - - public string FileName { - get { - ThrowIfRoot (); - - return _elements.Last (); - } - } - - public string FileNameWithoutExtension { - get { return Path.GetFileNameWithoutExtension (FileName); } - } - - public IEnumerable Elements { - get { return _elements; } - } - - public int Depth { - get { return _elements.Length; } - } - - public bool Exists (string append = "") - { - return Exists (new NPath (append)); - } - - public bool Exists (NPath append) - { - return FileExists (append) || DirectoryExists (append); - } - - public bool DirectoryExists (string append = "") - { - return DirectoryExists (new NPath (append)); - } - - public bool DirectoryExists (NPath append) - { - return Directory.Exists (Combine (append).ToString ()); - } - - public bool FileExists (string append = "") - { - return FileExists (new NPath (append)); - } - - public bool FileExists (NPath append) - { - return File.Exists (Combine (append).ToString ()); - } - - public string ExtensionWithDot { - get { - if (IsRoot) - throw new ArgumentException ("A root directory does not have an extension"); - - var last = _elements.Last (); - var index = last.LastIndexOf ("."); - if (index < 0) return string.Empty; - return last.Substring (index); - } - } - - public string InQuotes () - { - return "\"" + ToString () + "\""; - } - - public string InQuotes (SlashMode slashMode) - { - return "\"" + ToString (slashMode) + "\""; - } - - public override string ToString () - { - return ToString (SlashMode.Native); - } - - public string ToString (SlashMode slashMode) - { - // Check if it's linux root / - if (IsRoot && string.IsNullOrEmpty (_driveLetter)) - return Slash (slashMode).ToString (); - - if (_isRelative && _elements.Length == 0) - return "."; - - var sb = new StringBuilder (); - if (_driveLetter != null) { - sb.Append (_driveLetter); - sb.Append (':'); - } - if (!_isRelative) - sb.Append (Slash (slashMode)); - var first = true; - foreach (var element in _elements) { - if (!first) - sb.Append (Slash (slashMode)); - - sb.Append (element); - first = false; - } - return sb.ToString (); - } - - public static implicit operator string (NPath path) - { - return path.ToString (); - } - - private static char Slash (SlashMode slashMode) - { - return slashMode switch { - SlashMode.Backward => '\\', - SlashMode.Forward => '/', - _ => Path.DirectorySeparatorChar, - }; - } - - public override bool Equals (object? obj) - { - if (obj == null) - return false; - - // If parameter cannot be cast to Point return false. - if (!(obj is NPath p)) - return false; - - return Equals (p); - } - - public bool Equals (NPath? p) - { - if (p == null) - return false; - - if (p._isRelative != _isRelative) - return false; - - if (!string.Equals (p._driveLetter, _driveLetter, PathStringComparison)) - return false; - - if (p._elements.Length != _elements.Length) - return false; - - for (var i = 0; i < _elements.Length; i++) - if (!string.Equals (p._elements[i], _elements[i], PathStringComparison)) - return false; - - return true; - } - - public static bool operator == (NPath? a, NPath? b) - { - // If both are null, or both are same instance, return true. - if (ReferenceEquals (a, b)) - return true; - - // If one is null, but not both, return false. - if ((a is null) || (b is null)) - return false; - - // Return true if the fields match: - return a.Equals (b); - } - - public override int GetHashCode () - { - unchecked { - int hash = 17; - // Suitable nullity checks etc, of course :) - hash = hash * 23 + _isRelative.GetHashCode (); - foreach (var element in _elements) - hash = hash * 23 + element.GetHashCode (); - if (_driveLetter != null) - hash = hash * 23 + _driveLetter.GetHashCode (); - return hash; - } - } - - public int CompareTo (object? obj) - { - if (obj == null) - return -1; - - return this.ToString ().CompareTo (((NPath) obj).ToString ()); - } - - public static bool operator != (NPath? a, NPath? b) - { - return !(a == b); - } - - public bool HasExtension (params string[] extensions) - { - var extensionWithDotLower = ExtensionWithDot.ToLowerInvariant (); - return extensions.Any (e => WithDot (e).ToLowerInvariant () == extensionWithDotLower); - } - - private static string WithDot (string extension) - { - return extension.StartsWith (".") ? extension : "." + extension; - } - - private bool IsEmpty () - { - return _elements.Length == 0; - } - - public bool IsRoot { - get { return _elements.Length == 0 && !_isRelative; } - } - - #endregion inspection - - #region directory enumeration - - public IEnumerable Files (string filter, bool recurse = false) - { - return Directory.GetFiles (ToString (), filter, recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).Select (s => new NPath (s)); - } - - public IEnumerable Files (bool recurse = false) - { - return Files ("*", recurse); - } - - public IEnumerable Contents (string filter, bool recurse = false) - { - return Files (filter, recurse).Concat (Directories (filter, recurse)); - } - - public IEnumerable Contents (bool recurse = false) - { - return Contents ("*", recurse); - } - - public IEnumerable Directories (string filter, bool recurse = false) - { - return Directory.GetDirectories (ToString (), filter, recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).Select (s => new NPath (s)); - } - - public IEnumerable Directories (bool recurse = false) - { - return Directories ("*", recurse); - } - - #endregion - - #region filesystem writing operations - public NPath CreateFile () - { - ThrowIfRelative (); - ThrowIfRoot (); - EnsureParentDirectoryExists (); - File.WriteAllBytes (ToString (), Array.Empty ()); - return this; - } - - public NPath CreateFile (string file) - { - return CreateFile (new NPath (file)); - } - - public NPath CreateFile (NPath file) - { - if (!file.IsRelative) - throw new ArgumentException ("You cannot call CreateFile() on an existing path with a non relative argument"); - return Combine (file).CreateFile (); - } - - public NPath CreateDirectory () - { - ThrowIfRelative (); - - if (IsRoot) - throw new NotSupportedException ("CreateDirectory is not supported on a root level directory because it would be dangerous:" + ToString ()); - - Directory.CreateDirectory (ToString ()); - return this; - } - - public NPath CreateDirectory (string directory) - { - return CreateDirectory (new NPath (directory)); - } - - public NPath CreateDirectory (NPath directory) - { - if (!directory.IsRelative) - throw new ArgumentException ("Cannot call CreateDirectory with an absolute argument"); - - return Combine (directory).CreateDirectory (); - } - - public NPath? Copy (string dest) - { - return Copy (new NPath (dest)); - } - - public NPath? Copy (string dest, Func fileFilter) - { - return Copy (new NPath (dest), fileFilter); - } - - public NPath? Copy (NPath dest) - { - return Copy (dest, p => true); - } - - public NPath? Copy (NPath dest, Func fileFilter) - { - ThrowIfRelative (); - if (dest.IsRelative) - dest = Parent.Combine (dest); - - if (dest.DirectoryExists ()) - return CopyWithDeterminedDestination (dest.Combine (FileName), fileFilter); - - return CopyWithDeterminedDestination (dest, fileFilter); - } - - public NPath MakeAbsolute () - { - if (!IsRelative) - return this; - - return CurrentDirectory.Combine (this); - } - - private NPath? CopyWithDeterminedDestination (NPath absoluteDestination, Func fileFilter) - { - if (absoluteDestination.IsRelative) - throw new ArgumentException ("absoluteDestination must be absolute"); - - if (FileExists ()) { - if (!fileFilter (absoluteDestination)) - return null; - - absoluteDestination.EnsureParentDirectoryExists (); - - File.Copy (ToString (), absoluteDestination.ToString (), true); - return absoluteDestination; - } - - if (DirectoryExists ()) { - absoluteDestination.EnsureDirectoryExists (); - foreach (var thing in Contents ()) - thing.CopyWithDeterminedDestination (absoluteDestination.Combine (thing.RelativeTo (this)), fileFilter); - return absoluteDestination; - } - - throw new ArgumentException ("Copy() called on path that doesnt exist: " + ToString ()); - } - - public void Delete (DeleteMode deleteMode = DeleteMode.Normal) - { - ThrowIfRelative (); - - if (IsRoot) - throw new NotSupportedException ("Delete is not supported on a root level directory because it would be dangerous:" + ToString ()); - - if (FileExists ()) - File.Delete (ToString ()); - else if (DirectoryExists ()) - try { - Directory.Delete (ToString (), true); - } catch (IOException) { - if (deleteMode == DeleteMode.Normal) - throw; - } - else - throw new InvalidOperationException ("Trying to delete a path that does not exist: " + ToString ()); - } - - public void DeleteIfExists (DeleteMode deleteMode = DeleteMode.Normal) - { - ThrowIfRelative (); - - if (FileExists () || DirectoryExists ()) - Delete (deleteMode); - } - - public NPath DeleteContents () - { - ThrowIfRelative (); - - if (IsRoot) - throw new NotSupportedException ("DeleteContents is not supported on a root level directory because it would be dangerous:" + ToString ()); - - if (FileExists ()) - throw new InvalidOperationException ("It is not valid to perform this operation on a file"); - - if (DirectoryExists ()) { - try { - Files ().Delete (); - Directories ().Delete (); - } catch (IOException) { - if (Files (true).Any ()) - throw; - } - - return this; - } - - return EnsureDirectoryExists (); - } - - public static NPath CreateTempDirectory (string myprefix) - { - var random = new Random (); - while (true) { - var candidate = new NPath (Path.GetTempPath () + "/" + myprefix + "_" + random.Next ()); - if (!candidate.Exists ()) - return candidate.CreateDirectory (); - } - } - - public NPath Move (string dest) - { - return Move (new NPath (dest)); - } - - public NPath Move (NPath dest) - { - ThrowIfRelative (); - - if (IsRoot) - throw new NotSupportedException ("Move is not supported on a root level directory because it would be dangerous:" + ToString ()); - - if (dest.IsRelative) - return Move (Parent.Combine (dest)); - - if (dest.DirectoryExists ()) - return Move (dest.Combine (FileName)); - - if (FileExists ()) { - dest.EnsureParentDirectoryExists (); - File.Move (ToString (), dest.ToString ()); - return dest; - } - - if (DirectoryExists ()) { - Directory.Move (ToString (), dest.ToString ()); - return dest; - } - - throw new ArgumentException ("Move() called on a path that doesn't exist: " + ToString ()); - } - - #endregion - - #region special paths - - public static NPath CurrentDirectory { - get { - return new NPath (Directory.GetCurrentDirectory ()); - } - } - - public static NPath HomeDirectory { - get { - if (Path.DirectorySeparatorChar == '\\') - return new NPath (Environment.GetEnvironmentVariable ("USERPROFILE")!); - return new NPath (Environment.GetEnvironmentVariable ("HOME")!); - } - } - - public static NPath SystemTemp { - get { - return new NPath (Path.GetTempPath ()); - } - } - - #endregion - - private void ThrowIfRelative () - { - if (_isRelative) - throw new ArgumentException ("You are attempting an operation on a Path that requires an absolute path, but the path is relative"); - } - - private void ThrowIfRoot () - { - if (IsRoot) - throw new ArgumentException ("You are attempting an operation that is not valid on a root level directory"); - } - - public NPath EnsureDirectoryExists (string append = "") - { - return EnsureDirectoryExists (new NPath (append)); - } - - public NPath EnsureDirectoryExists (NPath append) - { - var combined = Combine (append); - if (combined.DirectoryExists ()) - return combined; - combined.EnsureParentDirectoryExists (); - combined.CreateDirectory (); - return combined; - } - - public NPath EnsureParentDirectoryExists () - { - var parent = Parent; - parent.EnsureDirectoryExists (); - return parent; - } - - public NPath FileMustExist () - { - if (!FileExists ()) - throw new FileNotFoundException ("File was expected to exist : " + ToString ()); - - return this; - } - - public NPath DirectoryMustExist () - { - if (!DirectoryExists ()) - throw new DirectoryNotFoundException ("Expected directory to exist : " + ToString ()); - - return this; - } - - public bool IsChildOf (string potentialBasePath) - { - return IsChildOf (new NPath (potentialBasePath)); - } - - public bool IsChildOf (NPath potentialBasePath) - { - if ((IsRelative && !potentialBasePath.IsRelative) || !IsRelative && potentialBasePath.IsRelative) - throw new ArgumentException ("You can only call IsChildOf with two relative paths, or with two absolute paths"); - - // If the other path is the root directory, then anything is a child of it as long as it's not a Windows path - if (potentialBasePath.IsRoot) { - if (_driveLetter != potentialBasePath._driveLetter) - return false; - return true; - } - - if (IsEmpty ()) - return false; - - if (Equals (potentialBasePath)) - return true; - - return Parent.IsChildOf (potentialBasePath); - } - - public IEnumerable RecursiveParents { - get { - var candidate = this; - while (true) { - if (candidate.IsEmpty ()) - yield break; - - candidate = candidate.Parent; - yield return candidate; - } - } - } - - public NPath WriteAllText (string contents) - { - ThrowIfRelative (); - EnsureParentDirectoryExists (); - File.WriteAllText (ToString (), contents); - return this; - } - - public string ReadAllText () - { - ThrowIfRelative (); - return File.ReadAllText (ToString ()); - } - - public NPath WriteAllLines (string[] contents) - { - ThrowIfRelative (); - EnsureParentDirectoryExists (); - File.WriteAllLines (ToString (), contents); - return this; - } - - public string[] ReadAllLines () - { - ThrowIfRelative (); - return File.ReadAllLines (ToString ()); - } - - public IEnumerable CopyFiles (NPath destination, bool recurse, Func? fileFilter = null) - { - destination.EnsureDirectoryExists (); - return Files (recurse).Where (fileFilter ?? AlwaysTrue).Select (file => file.Copy (destination.Combine (file.RelativeTo (this)))).ToArray (); - } - - public IEnumerable MoveFiles (NPath destination, bool recurse, Func? fileFilter = null) - { - if (IsRoot) - throw new NotSupportedException ("MoveFiles is not supported on this directory because it would be dangerous:" + ToString ()); - - destination.EnsureDirectoryExists (); - return Files (recurse).Where (fileFilter ?? AlwaysTrue).Select (file => file.Move (destination.Combine (file.RelativeTo (this)))).ToArray (); - } - - private static bool AlwaysTrue (NPath p) - { - return true; - } - - private static bool IsLinux () - { - return Directory.Exists ("/proc"); - } - } - - public static class Extensions - { - public static IEnumerable Copy (this IEnumerable self, string dest) - { - return Copy (self, new NPath (dest)); - } - - public static IEnumerable Copy (this IEnumerable self, NPath dest) - { - if (dest.IsRelative) - throw new ArgumentException ("When copying multiple files, the destination cannot be a relative path"); - dest.EnsureDirectoryExists (); - return self.Select (p => p.Copy (dest.Combine (p.FileName))).ToArray (); - } - - public static IEnumerable Move (this IEnumerable self, string dest) - { - return Move (self, new NPath (dest)); - } - - public static IEnumerable Move (this IEnumerable self, NPath dest) - { - if (dest.IsRelative) - throw new ArgumentException ("When moving multiple files, the destination cannot be a relative path"); - dest.EnsureDirectoryExists (); - return self.Select (p => p.Move (dest.Combine (p.FileName))).ToArray (); - } - - public static IEnumerable Delete (this IEnumerable self) - { - foreach (var p in self) - p.Delete (); - return self; - } - - public static IEnumerable InQuotes (this IEnumerable self, SlashMode forward = SlashMode.Native) - { - return self.Select (p => p.InQuotes (forward)); - } - - public static NPath ToNPath (this string path) - { - return new NPath (path); - } - } - - public enum SlashMode - { - Native, - Forward, - Backward - } - - public enum DeleteMode - { - Normal, - Soft - } + public class NPath : IEquatable, IComparable + { + private static readonly StringComparison PathStringComparison = IsLinux() ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; + + private readonly string[] _elements; + private readonly bool _isRelative; + private readonly string? _driveLetter; + + #region construction + + public NPath(string path) + { + ArgumentNullException.ThrowIfNull(path); + + path = ParseDriveLetter(path, out _driveLetter); + + if (path == "/") + { + _isRelative = false; + _elements = Array.Empty(); + } + else + { + var split = path.Split('/', '\\'); + + _isRelative = _driveLetter == null && IsRelativeFromSplitString(split); + + _elements = ParseSplitStringIntoElements(split.Where(s => s.Length > 0).ToArray()); + } + } + + private NPath(string[] elements, bool isRelative, string? driveLetter) + { + _elements = elements; + _isRelative = isRelative; + _driveLetter = driveLetter; + } + + private string[] ParseSplitStringIntoElements(IEnumerable inputs) + { + var stack = new List(); + + foreach (var input in inputs.Where(input => input.Length != 0)) + { + if (input == ".") + { + if ((stack.Count > 0) && (stack.Last() != ".")) + continue; + } + else if (input == "..") + { + if (HasNonDotDotLastElement(stack)) + { + stack.RemoveAt(stack.Count - 1); + continue; + } + if (!_isRelative) + throw new ArgumentException("You cannot create a path that tries to .. past the root"); + } + stack.Add(input); + } + return stack.ToArray(); + } + + private static bool HasNonDotDotLastElement(List stack) + { + return stack.Count > 0 && stack[stack.Count - 1] != ".."; + } + + private static string ParseDriveLetter(string path, out string? driveLetter) + { + if (path.Length >= 2 && path[1] == ':') + { + driveLetter = path[0].ToString(); + return path.Substring(2); + } + + driveLetter = null; + return path; + } + + private static bool IsRelativeFromSplitString(string[] split) + { + if (split.Length < 2) + return true; + + return split[0].Length != 0 || !split.Any(s => s.Length > 0); + } + + public NPath Combine(params string[] append) + { + return Combine(append.Select(a => new NPath(a)).ToArray()); + } + + public NPath Combine(params NPath[] append) + { + if (!append.All(p => p.IsRelative)) + throw new ArgumentException("You cannot .Combine a non-relative path"); + + return new NPath(ParseSplitStringIntoElements(_elements.Concat(append.SelectMany(p => p._elements))), _isRelative, _driveLetter); + } + + public NPath Parent + { + get + { + if (_elements.Length == 0) + throw new InvalidOperationException("Parent is called on an empty path"); + + var newElements = _elements.Take(_elements.Length - 1).ToArray(); + + return new NPath(newElements, _isRelative, _driveLetter); + } + } + + public NPath RelativeTo(NPath path) + { + if (!IsChildOf(path)) + { + if (!IsRelative && !path.IsRelative && _driveLetter != path._driveLetter) + throw new ArgumentException("Path.RelativeTo() was invoked with two paths that are on different volumes. invoked on: " + ToString() + " asked to be made relative to: " + path); + + NPath? commonParent = null; + foreach (var parent in RecursiveParents) + { + commonParent = path.RecursiveParents.FirstOrDefault(otherParent => otherParent == parent); + + if (commonParent != null) + break; + } + + if (commonParent == null) + throw new ArgumentException("Path.RelativeTo() was unable to find a common parent between " + ToString() + " and " + path); + + if (IsRelative && path.IsRelative && commonParent.IsEmpty()) + throw new ArgumentException("Path.RelativeTo() was invoked with two relative paths that do not share a common parent. Invoked on: " + ToString() + " asked to be made relative to: " + path); + + var depthDiff = path.Depth - commonParent.Depth; + return new NPath(Enumerable.Repeat("..", depthDiff).Concat(_elements.Skip(commonParent.Depth)).ToArray(), true, null); + } + + return new NPath(_elements.Skip(path._elements.Length).ToArray(), true, null); + } + + public NPath ChangeExtension(string extension) + { + ThrowIfRoot(); + + var newElements = (string[])_elements.Clone(); + newElements[newElements.Length - 1] = Path.ChangeExtension(_elements[_elements.Length - 1], WithDot(extension)); + if (extension == string.Empty) + newElements[newElements.Length - 1] = newElements[newElements.Length - 1].TrimEnd('.'); + return new NPath(newElements, _isRelative, _driveLetter); + } + #endregion construction + + #region inspection + + public bool IsRelative + { + get { return _isRelative; } + } + + public string FileName + { + get + { + ThrowIfRoot(); + + return _elements.Last(); + } + } + + public string FileNameWithoutExtension + { + get { return Path.GetFileNameWithoutExtension(FileName); } + } + + public IEnumerable Elements + { + get { return _elements; } + } + + public int Depth + { + get { return _elements.Length; } + } + + public bool Exists(string append = "") + { + return Exists(new NPath(append)); + } + + public bool Exists(NPath append) + { + return FileExists(append) || DirectoryExists(append); + } + + public bool DirectoryExists(string append = "") + { + return DirectoryExists(new NPath(append)); + } + + public bool DirectoryExists(NPath append) + { + return Directory.Exists(Combine(append).ToString()); + } + + public bool FileExists(string append = "") + { + return FileExists(new NPath(append)); + } + + public bool FileExists(NPath append) + { + return File.Exists(Combine(append).ToString()); + } + + public string ExtensionWithDot + { + get + { + if (IsRoot) + throw new ArgumentException("A root directory does not have an extension"); + + var last = _elements.Last(); + var index = last.LastIndexOf("."); + if (index < 0) return string.Empty; + return last.Substring(index); + } + } + + public string InQuotes() + { + return "\"" + ToString() + "\""; + } + + public string InQuotes(SlashMode slashMode) + { + return "\"" + ToString(slashMode) + "\""; + } + + public override string ToString() + { + return ToString(SlashMode.Native); + } + + public string ToString(SlashMode slashMode) + { + // Check if it's linux root / + if (IsRoot && string.IsNullOrEmpty(_driveLetter)) + return Slash(slashMode).ToString(); + + if (_isRelative && _elements.Length == 0) + return "."; + + var sb = new StringBuilder(); + if (_driveLetter != null) + { + sb.Append(_driveLetter); + sb.Append(':'); + } + if (!_isRelative) + sb.Append(Slash(slashMode)); + var first = true; + foreach (var element in _elements) + { + if (!first) + sb.Append(Slash(slashMode)); + + sb.Append(element); + first = false; + } + return sb.ToString(); + } + + public static implicit operator string(NPath path) + { + return path.ToString(); + } + + private static char Slash(SlashMode slashMode) + { + return slashMode switch + { + SlashMode.Backward => '\\', + SlashMode.Forward => '/', + _ => Path.DirectorySeparatorChar, + }; + } + + public override bool Equals(object? obj) + { + if (obj == null) + return false; + + // If parameter cannot be cast to Point return false. + if (!(obj is NPath p)) + return false; + + return Equals(p); + } + + public bool Equals(NPath? p) + { + if (p == null) + return false; + + if (p._isRelative != _isRelative) + return false; + + if (!string.Equals(p._driveLetter, _driveLetter, PathStringComparison)) + return false; + + if (p._elements.Length != _elements.Length) + return false; + + for (var i = 0; i < _elements.Length; i++) + if (!string.Equals(p._elements[i], _elements[i], PathStringComparison)) + return false; + + return true; + } + + public static bool operator ==(NPath? a, NPath? b) + { + // If both are null, or both are same instance, return true. + if (ReferenceEquals(a, b)) + return true; + + // If one is null, but not both, return false. + if ((a is null) || (b is null)) + return false; + + // Return true if the fields match: + return a.Equals(b); + } + + public override int GetHashCode() + { + unchecked + { + int hash = 17; + // Suitable nullity checks etc, of course :) + hash = hash * 23 + _isRelative.GetHashCode(); + foreach (var element in _elements) + hash = hash * 23 + element.GetHashCode(); + if (_driveLetter != null) + hash = hash * 23 + _driveLetter.GetHashCode(); + return hash; + } + } + + public int CompareTo(object? obj) + { + if (obj == null) + return -1; + + return this.ToString().CompareTo(((NPath)obj).ToString()); + } + + public static bool operator !=(NPath? a, NPath? b) + { + return !(a == b); + } + + public bool HasExtension(params string[] extensions) + { + var extensionWithDotLower = ExtensionWithDot.ToLowerInvariant(); + return extensions.Any(e => WithDot(e).ToLowerInvariant() == extensionWithDotLower); + } + + private static string WithDot(string extension) + { + return extension.StartsWith(".") ? extension : "." + extension; + } + + private bool IsEmpty() + { + return _elements.Length == 0; + } + + public bool IsRoot + { + get { return _elements.Length == 0 && !_isRelative; } + } + + #endregion inspection + + #region directory enumeration + + public IEnumerable Files(string filter, bool recurse = false) + { + return Directory.GetFiles(ToString(), filter, recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).Select(s => new NPath(s)); + } + + public IEnumerable Files(bool recurse = false) + { + return Files("*", recurse); + } + + public IEnumerable Contents(string filter, bool recurse = false) + { + return Files(filter, recurse).Concat(Directories(filter, recurse)); + } + + public IEnumerable Contents(bool recurse = false) + { + return Contents("*", recurse); + } + + public IEnumerable Directories(string filter, bool recurse = false) + { + return Directory.GetDirectories(ToString(), filter, recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).Select(s => new NPath(s)); + } + + public IEnumerable Directories(bool recurse = false) + { + return Directories("*", recurse); + } + + #endregion + + #region filesystem writing operations + public NPath CreateFile() + { + ThrowIfRelative(); + ThrowIfRoot(); + EnsureParentDirectoryExists(); + File.WriteAllBytes(ToString(), Array.Empty()); + return this; + } + + public NPath CreateFile(string file) + { + return CreateFile(new NPath(file)); + } + + public NPath CreateFile(NPath file) + { + if (!file.IsRelative) + throw new ArgumentException("You cannot call CreateFile() on an existing path with a non relative argument"); + return Combine(file).CreateFile(); + } + + public NPath CreateDirectory() + { + ThrowIfRelative(); + + if (IsRoot) + throw new NotSupportedException("CreateDirectory is not supported on a root level directory because it would be dangerous:" + ToString()); + + Directory.CreateDirectory(ToString()); + return this; + } + + public NPath CreateDirectory(string directory) + { + return CreateDirectory(new NPath(directory)); + } + + public NPath CreateDirectory(NPath directory) + { + if (!directory.IsRelative) + throw new ArgumentException("Cannot call CreateDirectory with an absolute argument"); + + return Combine(directory).CreateDirectory(); + } + + public NPath? Copy(string dest) + { + return Copy(new NPath(dest)); + } + + public NPath? Copy(string dest, Func fileFilter) + { + return Copy(new NPath(dest), fileFilter); + } + + public NPath? Copy(NPath dest) + { + return Copy(dest, p => true); + } + + public NPath? Copy(NPath dest, Func fileFilter) + { + ThrowIfRelative(); + if (dest.IsRelative) + dest = Parent.Combine(dest); + + if (dest.DirectoryExists()) + return CopyWithDeterminedDestination(dest.Combine(FileName), fileFilter); + + return CopyWithDeterminedDestination(dest, fileFilter); + } + + public NPath MakeAbsolute() + { + if (!IsRelative) + return this; + + return CurrentDirectory.Combine(this); + } + + private NPath? CopyWithDeterminedDestination(NPath absoluteDestination, Func fileFilter) + { + if (absoluteDestination.IsRelative) + throw new ArgumentException("absoluteDestination must be absolute"); + + if (FileExists()) + { + if (!fileFilter(absoluteDestination)) + return null; + + absoluteDestination.EnsureParentDirectoryExists(); + + File.Copy(ToString(), absoluteDestination.ToString(), true); + return absoluteDestination; + } + + if (DirectoryExists()) + { + absoluteDestination.EnsureDirectoryExists(); + foreach (var thing in Contents()) + thing.CopyWithDeterminedDestination(absoluteDestination.Combine(thing.RelativeTo(this)), fileFilter); + return absoluteDestination; + } + + throw new ArgumentException("Copy() called on path that doesnt exist: " + ToString()); + } + + public void Delete(DeleteMode deleteMode = DeleteMode.Normal) + { + ThrowIfRelative(); + + if (IsRoot) + throw new NotSupportedException("Delete is not supported on a root level directory because it would be dangerous:" + ToString()); + + if (FileExists()) + File.Delete(ToString()); + else if (DirectoryExists()) + try + { + Directory.Delete(ToString(), true); + } + catch (IOException) + { + if (deleteMode == DeleteMode.Normal) + throw; + } + else + throw new InvalidOperationException("Trying to delete a path that does not exist: " + ToString()); + } + + public void DeleteIfExists(DeleteMode deleteMode = DeleteMode.Normal) + { + ThrowIfRelative(); + + if (FileExists() || DirectoryExists()) + Delete(deleteMode); + } + + public NPath DeleteContents() + { + ThrowIfRelative(); + + if (IsRoot) + throw new NotSupportedException("DeleteContents is not supported on a root level directory because it would be dangerous:" + ToString()); + + if (FileExists()) + throw new InvalidOperationException("It is not valid to perform this operation on a file"); + + if (DirectoryExists()) + { + try + { + Files().Delete(); + Directories().Delete(); + } + catch (IOException) + { + if (Files(true).Any()) + throw; + } + + return this; + } + + return EnsureDirectoryExists(); + } + + public static NPath CreateTempDirectory(string myprefix) + { + var random = new Random(); + while (true) + { + var candidate = new NPath(Path.GetTempPath() + "/" + myprefix + "_" + random.Next()); + if (!candidate.Exists()) + return candidate.CreateDirectory(); + } + } + + public NPath Move(string dest) + { + return Move(new NPath(dest)); + } + + public NPath Move(NPath dest) + { + ThrowIfRelative(); + + if (IsRoot) + throw new NotSupportedException("Move is not supported on a root level directory because it would be dangerous:" + ToString()); + + if (dest.IsRelative) + return Move(Parent.Combine(dest)); + + if (dest.DirectoryExists()) + return Move(dest.Combine(FileName)); + + if (FileExists()) + { + dest.EnsureParentDirectoryExists(); + File.Move(ToString(), dest.ToString()); + return dest; + } + + if (DirectoryExists()) + { + Directory.Move(ToString(), dest.ToString()); + return dest; + } + + throw new ArgumentException("Move() called on a path that doesn't exist: " + ToString()); + } + + #endregion + + #region special paths + + public static NPath CurrentDirectory + { + get + { + return new NPath(Directory.GetCurrentDirectory()); + } + } + + public static NPath HomeDirectory + { + get + { + if (Path.DirectorySeparatorChar == '\\') + return new NPath(Environment.GetEnvironmentVariable("USERPROFILE")!); + return new NPath(Environment.GetEnvironmentVariable("HOME")!); + } + } + + public static NPath SystemTemp + { + get + { + return new NPath(Path.GetTempPath()); + } + } + + #endregion + + private void ThrowIfRelative() + { + if (_isRelative) + throw new ArgumentException("You are attempting an operation on a Path that requires an absolute path, but the path is relative"); + } + + private void ThrowIfRoot() + { + if (IsRoot) + throw new ArgumentException("You are attempting an operation that is not valid on a root level directory"); + } + + public NPath EnsureDirectoryExists(string append = "") + { + return EnsureDirectoryExists(new NPath(append)); + } + + public NPath EnsureDirectoryExists(NPath append) + { + var combined = Combine(append); + if (combined.DirectoryExists()) + return combined; + combined.EnsureParentDirectoryExists(); + combined.CreateDirectory(); + return combined; + } + + public NPath EnsureParentDirectoryExists() + { + var parent = Parent; + parent.EnsureDirectoryExists(); + return parent; + } + + public NPath FileMustExist() + { + if (!FileExists()) + throw new FileNotFoundException("File was expected to exist : " + ToString()); + + return this; + } + + public NPath DirectoryMustExist() + { + if (!DirectoryExists()) + throw new DirectoryNotFoundException("Expected directory to exist : " + ToString()); + + return this; + } + + public bool IsChildOf(string potentialBasePath) + { + return IsChildOf(new NPath(potentialBasePath)); + } + + public bool IsChildOf(NPath potentialBasePath) + { + if ((IsRelative && !potentialBasePath.IsRelative) || !IsRelative && potentialBasePath.IsRelative) + throw new ArgumentException("You can only call IsChildOf with two relative paths, or with two absolute paths"); + + // If the other path is the root directory, then anything is a child of it as long as it's not a Windows path + if (potentialBasePath.IsRoot) + { + if (_driveLetter != potentialBasePath._driveLetter) + return false; + return true; + } + + if (IsEmpty()) + return false; + + if (Equals(potentialBasePath)) + return true; + + return Parent.IsChildOf(potentialBasePath); + } + + public IEnumerable RecursiveParents + { + get + { + var candidate = this; + while (true) + { + if (candidate.IsEmpty()) + yield break; + + candidate = candidate.Parent; + yield return candidate; + } + } + } + + public NPath WriteAllText(string contents) + { + ThrowIfRelative(); + EnsureParentDirectoryExists(); + File.WriteAllText(ToString(), contents); + return this; + } + + public string ReadAllText() + { + ThrowIfRelative(); + return File.ReadAllText(ToString()); + } + + public NPath WriteAllLines(string[] contents) + { + ThrowIfRelative(); + EnsureParentDirectoryExists(); + File.WriteAllLines(ToString(), contents); + return this; + } + + public string[] ReadAllLines() + { + ThrowIfRelative(); + return File.ReadAllLines(ToString()); + } + + public IEnumerable CopyFiles(NPath destination, bool recurse, Func? fileFilter = null) + { + destination.EnsureDirectoryExists(); + return Files(recurse).Where(fileFilter ?? AlwaysTrue).Select(file => file.Copy(destination.Combine(file.RelativeTo(this)))).ToArray(); + } + + public IEnumerable MoveFiles(NPath destination, bool recurse, Func? fileFilter = null) + { + if (IsRoot) + throw new NotSupportedException("MoveFiles is not supported on this directory because it would be dangerous:" + ToString()); + + destination.EnsureDirectoryExists(); + return Files(recurse).Where(fileFilter ?? AlwaysTrue).Select(file => file.Move(destination.Combine(file.RelativeTo(this)))).ToArray(); + } + + private static bool AlwaysTrue(NPath p) + { + return true; + } + + private static bool IsLinux() + { + return Directory.Exists("/proc"); + } + } + + public static class Extensions + { + public static IEnumerable Copy(this IEnumerable self, string dest) + { + return Copy(self, new NPath(dest)); + } + + public static IEnumerable Copy(this IEnumerable self, NPath dest) + { + if (dest.IsRelative) + throw new ArgumentException("When copying multiple files, the destination cannot be a relative path"); + dest.EnsureDirectoryExists(); + return self.Select(p => p.Copy(dest.Combine(p.FileName))).ToArray(); + } + + public static IEnumerable Move(this IEnumerable self, string dest) + { + return Move(self, new NPath(dest)); + } + + public static IEnumerable Move(this IEnumerable self, NPath dest) + { + if (dest.IsRelative) + throw new ArgumentException("When moving multiple files, the destination cannot be a relative path"); + dest.EnsureDirectoryExists(); + return self.Select(p => p.Move(dest.Combine(p.FileName))).ToArray(); + } + + public static IEnumerable Delete(this IEnumerable self) + { + foreach (var p in self) + p.Delete(); + return self; + } + + public static IEnumerable InQuotes(this IEnumerable self, SlashMode forward = SlashMode.Native) + { + return self.Select(p => p.InQuotes(forward)); + } + + public static NPath ToNPath(this string path) + { + return new NPath(path); + } + } + + public enum SlashMode + { + Native, + Forward, + Backward + } + + public enum DeleteMode + { + Normal, + Soft + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/ILCompiler.Trimming.Tests.csproj b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/ILCompiler.Trimming.Tests.csproj index f2d5356f5dc9ab..e8cef2b9014c91 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/ILCompiler.Trimming.Tests.csproj +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/ILCompiler.Trimming.Tests.csproj @@ -50,6 +50,12 @@ $(TargetFramework) + + $(TargetFrameworkMoniker) + + + $(TargetFrameworkMonikerDisplayName) + $(ToolsProjectRoot)illink/test/ diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestCase.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestCase.cs index be690ac7a60df9..09965c24c30dda 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestCase.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestCase.cs @@ -9,98 +9,103 @@ namespace Mono.Linker.Tests.TestCases { - public class TestCase - { - public TestCase (NPath sourceFile, NPath rootCasesDirectory, NPath originalTestCaseAssemblyPath) - { - SourceFile = sourceFile; - RootCasesDirectory = rootCasesDirectory; - OriginalTestCaseAssemblyPath = originalTestCaseAssemblyPath; - Name = sourceFile.FileNameWithoutExtension; - var fullyRelative = sourceFile.RelativeTo (rootCasesDirectory); - var displayNameRelative = fullyRelative.RelativeTo (new NPath (fullyRelative.Elements.First ())); - string displayNameBase = displayNameRelative.Depth == 1 ? "" : displayNameRelative.Parent.ToString (SlashMode.Forward).Replace ('/', '.'); - DisplayName = sourceFile.FileNameWithoutExtension == "Program" && sourceFile.Parent.FileName == originalTestCaseAssemblyPath.FileNameWithoutExtension - ? displayNameBase - : $"{displayNameBase}.{sourceFile.FileNameWithoutExtension}"; - if (DisplayName.StartsWith(".")) - DisplayName = DisplayName.Substring(1); - - // A little hacky, but good enough for name. No reason why namespace & type names - // should not follow the directory structure - //ReconstructedFullTypeName = $"{sourceFile.Parent.RelativeTo (rootCasesDirectory.Parent).ToString (SlashMode.Forward).Replace ('/', '.')}.{sourceFile.FileNameWithoutExtension}"; - reconstructedFullTypeName = $"Mono.Linker.Tests.Cases.{fullyRelative.Parent.ToString (SlashMode.Forward).Replace ('/', '.')}.{sourceFile.FileNameWithoutExtension}"; - - var firstParentRelativeToRoot = SourceFile.RelativeTo (rootCasesDirectory).Elements.First (); - TestSuiteDirectory = rootCasesDirectory.Combine (firstParentRelativeToRoot); - } - - public NPath RootCasesDirectory { get; } - - public string Name { get; } - - public string DisplayName { get; } - - public NPath SourceFile { get; } - - public NPath OriginalTestCaseAssemblyPath { get; } - - private string reconstructedFullTypeName; - - public bool HasLinkXmlFile { - get { return SourceFile.ChangeExtension ("xml").FileExists (); } - } - - public NPath LinkXmlFile { - get { - if (!HasLinkXmlFile) - throw new InvalidOperationException ("This test case does not have a link xml file"); - - return SourceFile.ChangeExtension ("xml"); - } - } - - public NPath TestSuiteDirectory { get; } - - public TypeDefinition FindTypeDefinition (AssemblyDefinition assemblyDefinition) - => TryFindTypeDefinition (assemblyDefinition) is TypeDefinition typeDefinition - ? typeDefinition - : throw new InvalidOperationException ($"Could not find the type definition for {Name} in {assemblyDefinition.Name}"); - - public TypeDefinition? TryFindTypeDefinition (AssemblyDefinition caseAssemblyDefinition) - { - var typeDefinition = caseAssemblyDefinition.MainModule.GetType (reconstructedFullTypeName); - - // For all of the Test Cases, the full type name we constructed from the directory structure will be correct and we can successfully find - // the type from GetType. - if (typeDefinition != null) - return typeDefinition; - - // However, some of types are supporting types rather than test cases and may not follow the standardized naming scheme of the test cases. - // We still need to be able to locate these type defs so that we can parse some of the metadata on them. - // One example, Unity run's into this with its tests that require a type UnityEngine.MonoBehaviours to exist. This type is defined in its own - // file and it cannot follow our standardized naming directory & namespace naming scheme since the namespace must be UnityEngine. - // Also look for compiler-generated Program type for top-level statements. - foreach (var type in caseAssemblyDefinition.MainModule.Types) { - if (type.Name == "Program" && - type.CustomAttributes.Any (attr => attr.AttributeType.Name == nameof (CompilerGeneratedAttribute))) - return type; - - // Let's assume we should never have to search for a test case that has no namespace. If we don't find the type from GetType, then o well, that's not a test case. - if (string.IsNullOrEmpty (type.Namespace)) - continue; - - if (type.Name == Name) { - // This isn't foolproof, but let's do a little extra vetting to make sure the type we found corresponds to the source file we are - // processing. - if (!SourceFile.ReadAllText ().Contains ($"namespace {type.Namespace}")) - continue; - - return type; - } - } - - return null; - } - } + public class TestCase + { + public TestCase(NPath sourceFile, NPath rootCasesDirectory, NPath originalTestCaseAssemblyPath) + { + SourceFile = sourceFile; + RootCasesDirectory = rootCasesDirectory; + OriginalTestCaseAssemblyPath = originalTestCaseAssemblyPath; + Name = sourceFile.FileNameWithoutExtension; + var fullyRelative = sourceFile.RelativeTo(rootCasesDirectory); + var displayNameRelative = fullyRelative.RelativeTo(new NPath(fullyRelative.Elements.First())); + string displayNameBase = displayNameRelative.Depth == 1 ? "" : displayNameRelative.Parent.ToString(SlashMode.Forward).Replace('/', '.'); + DisplayName = sourceFile.FileNameWithoutExtension == "Program" && sourceFile.Parent.FileName == originalTestCaseAssemblyPath.FileNameWithoutExtension + ? displayNameBase + : $"{displayNameBase}.{sourceFile.FileNameWithoutExtension}"; + if (DisplayName.StartsWith(".")) + DisplayName = DisplayName.Substring(1); + + // A little hacky, but good enough for name. No reason why namespace & type names + // should not follow the directory structure + // ReconstructedFullTypeName = $"{sourceFile.Parent.RelativeTo(rootCasesDirectory.Parent).ToString(SlashMode.Forward).Replace('/', '.')}.{sourceFile.FileNameWithoutExtension}"; + reconstructedFullTypeName = $"Mono.Linker.Tests.Cases.{fullyRelative.Parent.ToString(SlashMode.Forward).Replace('/', '.')}.{sourceFile.FileNameWithoutExtension}"; + + var firstParentRelativeToRoot = SourceFile.RelativeTo(rootCasesDirectory).Elements.First(); + TestSuiteDirectory = rootCasesDirectory.Combine(firstParentRelativeToRoot); + } + + public NPath RootCasesDirectory { get; } + + public string Name { get; } + + public string DisplayName { get; } + + public NPath SourceFile { get; } + + public NPath OriginalTestCaseAssemblyPath { get; } + + private string reconstructedFullTypeName; + + public bool HasLinkXmlFile + { + get { return SourceFile.ChangeExtension("xml").FileExists(); } + } + + public NPath LinkXmlFile + { + get + { + if (!HasLinkXmlFile) + throw new InvalidOperationException("This test case does not have a link xml file"); + + return SourceFile.ChangeExtension("xml"); + } + } + + public NPath TestSuiteDirectory { get; } + + public TypeDefinition FindTypeDefinition(AssemblyDefinition assemblyDefinition) + => TryFindTypeDefinition(assemblyDefinition) is TypeDefinition typeDefinition + ? typeDefinition + : throw new InvalidOperationException($"Could not find the type definition for {Name} in {assemblyDefinition.Name}"); + + public TypeDefinition? TryFindTypeDefinition(AssemblyDefinition caseAssemblyDefinition) + { + var typeDefinition = caseAssemblyDefinition.MainModule.GetType(reconstructedFullTypeName); + + // For all of the Test Cases, the full type name we constructed from the directory structure will be correct and we can successfully find + // the type from GetType. + if (typeDefinition != null) + return typeDefinition; + + // However, some of types are supporting types rather than test cases and may not follow the standardized naming scheme of the test cases. + // We still need to be able to locate these type defs so that we can parse some of the metadata on them. + // One example, Unity run's into this with its tests that require a type UnityEngine.MonoBehaviours to exist. This type is defined in its own + // file and it cannot follow our standardized naming directory & namespace naming scheme since the namespace must be UnityEngine. + // Also look for compiler-generated Program type for top-level statements. + foreach (var type in caseAssemblyDefinition.MainModule.Types) + { + if (type.Name == "Program" && + type.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(CompilerGeneratedAttribute))) + return type; + + // Let's assume we should never have to search for a test case that has no namespace. If we don't find the type from GetType, then o well, that's not a test case. + if (string.IsNullOrEmpty(type.Namespace)) + continue; + + if (type.Name == Name) + { + // This isn't foolproof, but let's do a little extra vetting to make sure the type we found corresponds to the source file we are + // processing. + if (!SourceFile.ReadAllText().Contains($"namespace {type.Namespace}")) + continue; + + return type; + } + } + + return null; + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestDatabase.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestDatabase.cs index f742d409d9b75a..8f5b20deef2c96 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestDatabase.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestDatabase.cs @@ -10,29 +10,29 @@ namespace Mono.Linker.Tests.TestCases { - public static class TestDatabase - { - private static TestCase[]? _cachedAllCases; - - public static IEnumerable DataFlow () - { - return TestNamesBySuiteName (); - } - - public static IEnumerable DynamicDependencies () - { - return TestNamesBySuiteName (); - } - - public static IEnumerable Generics () - { - return TestNamesBySuiteName (); - } - - public static IEnumerable InlineArrays () - { - return TestNamesBySuiteName(); - } + public static class TestDatabase + { + private static TestCase[]? _cachedAllCases; + + public static IEnumerable DataFlow() + { + return TestNamesBySuiteName(); + } + + public static IEnumerable DynamicDependencies() + { + return TestNamesBySuiteName(); + } + + public static IEnumerable Generics() + { + return TestNamesBySuiteName(); + } + + public static IEnumerable InlineArrays() + { + return TestNamesBySuiteName(); + } public static IEnumerable Inheritance_Interaces() { @@ -45,91 +45,93 @@ public static IEnumerable Libraries() } public static IEnumerable LinkXml() - { - return TestNamesBySuiteName(); - } - - public static IEnumerable Reflection () - { - return TestNamesBySuiteName (); - } - - public static IEnumerable Repro () - { - return TestNamesBySuiteName (); - } - - public static IEnumerable RequiresCapability () - { - return TestNamesBySuiteName (); - } - - public static IEnumerable SingleFile () - { - return TestNamesBySuiteName (); - } - - public static IEnumerable Substitutions () - { - return TestNamesBySuiteName (); - } - - public static IEnumerable TopLevelStatements () - { - return TestNamesBySuiteName (); - } - - public static IEnumerable UnreachableBlock () - { - return TestNamesBySuiteName (); - } - - public static IEnumerable Warnings () - { - return TestNamesBySuiteName (); - } - - public static TestCaseCollector CreateCollector () - { - GetDirectoryPaths (out string rootSourceDirectory, out string testCaseAssemblyRoot); - return new TestCaseCollector (rootSourceDirectory, testCaseAssemblyRoot); - } - - public static NPath TestCasesRootDirectory { - get { - GetDirectoryPaths (out string rootSourceDirectory, out string _); - return rootSourceDirectory.ToNPath (); - } - } - - private static IEnumerable AllCases () - { - _cachedAllCases ??= CreateCollector () - .Collect () - .OrderBy (c => c.DisplayName) - .ToArray (); - - return _cachedAllCases; - } - - public static TestCase? GetTestCaseFromName (string name) - { - return AllCases ().FirstOrDefault (c => c.DisplayName == name); - } - - private static IEnumerable TestNamesBySuiteName ([CallerMemberName] string suiteName = "") - { - return AllCases () - .Where (c => c.TestSuiteDirectory.FileName == suiteName) - .Select (c => c.DisplayName) - .OrderBy (c => c) - .Select (c => new object[] { c }); - } - - private static void GetDirectoryPaths (out string rootSourceDirectory, out string testCaseAssemblyRoot) - { - rootSourceDirectory = Path.GetFullPath (Path.Combine (PathUtilities.GetTestsSourceRootDirectory (), "Mono.Linker.Tests.Cases")); - testCaseAssemblyRoot = PathUtilities.GetTestAssemblyRoot ("Mono.Linker.Tests.Cases"); - } - } + { + return TestNamesBySuiteName(); + } + + public static IEnumerable Reflection() + { + return TestNamesBySuiteName(); + } + + public static IEnumerable Repro() + { + return TestNamesBySuiteName(); + } + + public static IEnumerable RequiresCapability() + { + return TestNamesBySuiteName(); + } + + public static IEnumerable SingleFile() + { + return TestNamesBySuiteName(); + } + + public static IEnumerable Substitutions() + { + return TestNamesBySuiteName(); + } + + public static IEnumerable TopLevelStatements() + { + return TestNamesBySuiteName(); + } + + public static IEnumerable UnreachableBlock() + { + return TestNamesBySuiteName(); + } + + public static IEnumerable Warnings() + { + return TestNamesBySuiteName(); + } + + public static TestCaseCollector CreateCollector() + { + GetDirectoryPaths(out string rootSourceDirectory, out string testCaseAssemblyRoot); + return new TestCaseCollector(rootSourceDirectory, testCaseAssemblyRoot); + } + + public static NPath TestCasesRootDirectory + { + get + { + GetDirectoryPaths(out string rootSourceDirectory, out string _); + return rootSourceDirectory.ToNPath(); + } + } + + private static IEnumerable AllCases() + { + _cachedAllCases ??= CreateCollector() + .Collect() + .OrderBy(c => c.DisplayName) + .ToArray(); + + return _cachedAllCases; + } + + public static TestCase? GetTestCaseFromName(string name) + { + return AllCases().FirstOrDefault(c => c.DisplayName == name); + } + + private static IEnumerable TestNamesBySuiteName([CallerMemberName] string suiteName = "") + { + return AllCases() + .Where(c => c.TestSuiteDirectory.FileName == suiteName) + .Select(c => c.DisplayName) + .OrderBy(c => c) + .Select(c => new object[] { c }); + } + + private static void GetDirectoryPaths(out string rootSourceDirectory, out string testCaseAssemblyRoot) + { + rootSourceDirectory = Path.GetFullPath(Path.Combine(PathUtilities.GetTestsSourceRootDirectory(), "Mono.Linker.Tests.Cases")); + testCaseAssemblyRoot = PathUtilities.GetTestAssemblyRoot("Mono.Linker.Tests.Cases"); + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestSuites.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestSuites.cs index 87d8fc21ce8798..86d94be1f14c7c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestSuites.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestSuites.cs @@ -7,152 +7,155 @@ namespace Mono.Linker.Tests.TestCases { - public class All - { - [Theory] - [MemberData(nameof(TestDatabase.DataFlow), MemberType = typeof(TestDatabase))] - public void DataFlow(string t) - { - Run(t); - } - - [Theory] - [MemberData (nameof (TestDatabase.DynamicDependencies), MemberType = typeof (TestDatabase))] - public void DynamicDependencies (string t) - { - Run (t); - } - - [Theory] - [MemberData (nameof (TestDatabase.Generics), MemberType = typeof (TestDatabase))] - public void Generics (string t) - { - Run (t); - } - - [Theory] - [MemberData(nameof(TestDatabase.InlineArrays), MemberType = typeof(TestDatabase))] - public void InlineArrays(string t) - { - Run(t); - } - - [Theory] - [MemberData(nameof(TestDatabase.Inheritance_Interaces), MemberType = typeof(TestDatabase))] - public void Inheritance_Interfaces(string t) - { - switch (t) { - case ".InterfaceWithoutNewSlot": - Run (t); - break; - default: - // Skip the rest for now - break; - } - } - - [Theory] - [MemberData(nameof(TestDatabase.Libraries), MemberType = typeof(TestDatabase))] - public void Libraries(string t) - { - Run(t); - } - - [Theory] - [MemberData (nameof (TestDatabase.LinkXml), MemberType = typeof (TestDatabase))] - public void LinkXml (string t) - { - Run (t); - } - - [Theory] - [MemberData (nameof (TestDatabase.Reflection), MemberType = typeof (TestDatabase))] - public void Reflection (string t) - { - switch (t) - { - case "ObjectGetTypeLibraryMode": - case "TypeHierarchyLibraryModeSuppressions": - // No Library mode - break; - default: - Run (t); - break; - } - } - - [Theory] - [MemberData (nameof (TestDatabase.Repro), MemberType = typeof (TestDatabase))] - public void Repro (string t) - { - Run (t); - } - - [Theory] - [MemberData(nameof(TestDatabase.RequiresCapability), MemberType = typeof(TestDatabase))] - public void RequiresCapability(string t) - { - Run(t); - } - - [Theory] - [MemberData (nameof (TestDatabase.SingleFile), MemberType = typeof (TestDatabase))] - public void SingleFile (string t) - { - Run (t); - } - - [Theory] - [MemberData (nameof (TestDatabase.Substitutions), MemberType = typeof (TestDatabase))] - public void Substitutions (string t) - { - switch (t) { - case "FeatureGuardSubstitutions": - Run (t); - break; - default: - // Skip the rest for now - break; - } - } - - [Theory] - [MemberData (nameof (TestDatabase.TopLevelStatements), MemberType = typeof (TestDatabase))] - public void TopLevelStatements (string t) - { - Run (t); - } - - [Theory] - [MemberData (nameof (TestDatabase.UnreachableBlock), MemberType = typeof (TestDatabase))] - public void UnreachableBlock (string t) - { - switch (t) { - case "TryCatchBlocks": - Run (t); - break; - default: - // Skip the rest for now - break; - } - } - - [Theory] - [MemberData (nameof (TestDatabase.Warnings), MemberType = typeof (TestDatabase))] - public void Warnings (string t) - { - Run (t); - } - - protected virtual void Run(string testName) - { - TestCase testCase = TestDatabase.GetTestCaseFromName(testName) ?? throw new InvalidOperationException($"Unknown test {testName}"); - var runner = new TestRunner(new ObjectFactory()); - var linkedResult = runner.Run(testCase); - if (linkedResult != null) - { - new ResultChecker().Check(linkedResult); - } - } - } + public class All + { + [Theory] + [MemberData(nameof(TestDatabase.DataFlow), MemberType = typeof(TestDatabase))] + public void DataFlow(string t) + { + Run(t); + } + + [Theory] + [MemberData(nameof(TestDatabase.DynamicDependencies), MemberType = typeof(TestDatabase))] + public void DynamicDependencies(string t) + { + Run(t); + } + + [Theory] + [MemberData(nameof(TestDatabase.Generics), MemberType = typeof(TestDatabase))] + public void Generics(string t) + { + Run(t); + } + + [Theory] + [MemberData(nameof(TestDatabase.InlineArrays), MemberType = typeof(TestDatabase))] + public void InlineArrays(string t) + { + Run(t); + } + + [Theory] + [MemberData(nameof(TestDatabase.Inheritance_Interaces), MemberType = typeof(TestDatabase))] + public void Inheritance_Interfaces(string t) + { + switch (t) + { + case ".InterfaceWithoutNewSlot": + Run(t); + break; + default: + // Skip the rest for now + break; + } + } + + [Theory] + [MemberData(nameof(TestDatabase.Libraries), MemberType = typeof(TestDatabase))] + public void Libraries(string t) + { + Run(t); + } + + [Theory] + [MemberData(nameof(TestDatabase.LinkXml), MemberType = typeof(TestDatabase))] + public void LinkXml(string t) + { + Run(t); + } + + [Theory] + [MemberData(nameof(TestDatabase.Reflection), MemberType = typeof(TestDatabase))] + public void Reflection(string t) + { + switch (t) + { + case "ObjectGetTypeLibraryMode": + case "TypeHierarchyLibraryModeSuppressions": + // No Library mode + break; + default: + Run(t); + break; + } + } + + [Theory] + [MemberData(nameof(TestDatabase.Repro), MemberType = typeof(TestDatabase))] + public void Repro(string t) + { + Run(t); + } + + [Theory] + [MemberData(nameof(TestDatabase.RequiresCapability), MemberType = typeof(TestDatabase))] + public void RequiresCapability(string t) + { + Run(t); + } + + [Theory] + [MemberData(nameof(TestDatabase.SingleFile), MemberType = typeof(TestDatabase))] + public void SingleFile(string t) + { + Run(t); + } + + [Theory] + [MemberData(nameof(TestDatabase.Substitutions), MemberType = typeof(TestDatabase))] + public void Substitutions(string t) + { + switch (t) + { + case "FeatureGuardSubstitutions": + Run(t); + break; + default: + // Skip the rest for now + break; + } + } + + [Theory] + [MemberData(nameof(TestDatabase.TopLevelStatements), MemberType = typeof(TestDatabase))] + public void TopLevelStatements(string t) + { + Run(t); + } + + [Theory] + [MemberData(nameof(TestDatabase.UnreachableBlock), MemberType = typeof(TestDatabase))] + public void UnreachableBlock(string t) + { + switch (t) + { + case "TryCatchBlocks": + Run(t); + break; + default: + // Skip the rest for now + break; + } + } + + [Theory] + [MemberData(nameof(TestDatabase.Warnings), MemberType = typeof(TestDatabase))] + public void Warnings(string t) + { + Run(t); + } + + protected virtual void Run(string testName) + { + TestCase testCase = TestDatabase.GetTestCaseFromName(testName) ?? throw new InvalidOperationException($"Unknown test {testName}"); + var runner = new TestRunner(new ObjectFactory()); + var linkedResult = runner.Run(testCase); + if (linkedResult != null) + { + new ResultChecker().Check(linkedResult); + } + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/AssemblyChecker.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/AssemblyChecker.cs index 2f89b128c32ebe..b5de71ed3bb079 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/AssemblyChecker.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/AssemblyChecker.cs @@ -19,2035 +19,2165 @@ namespace Mono.Linker.Tests.TestCasesRunner { - partial class AssemblyChecker - { - class LinkedEntity - { - public TypeSystemEntity Entity { get; init; } - - public LinkedEntity(TypeSystemEntity entity) => Entity = entity; - } - - class LinkedMethodEntity : LinkedEntity - { - public bool IsReflected { get; init; } - - public MethodDesc Method { get => (MethodDesc) Entity; } - - public LinkedMethodEntity (MethodDesc method, bool isReflected) : base (method) => IsReflected = isReflected; - } - - private readonly BaseAssemblyResolver originalsResolver; - private readonly TypeNameResolver originalsTypeNameResolver; - private readonly ReaderParameters originalReaderParameters; - private readonly AssemblyDefinition originalAssembly; - private readonly TrimmedTestCaseResult testResult; - - private readonly Dictionary linkedMembers; - private readonly HashSet verifiedGeneratedFields = new HashSet (); - private readonly HashSet verifiedEventMethods = new HashSet (); - private readonly HashSet verifiedGeneratedTypes = new HashSet (); - private bool checkNames; - - // Note: It's enough to exclude the type name, all of its members will also be excluded then - private static readonly HashSet ExcludeDisplayNames = new () { - // Ignore compiler injected attributes to describe language version - "Microsoft.CodeAnalysis.EmbeddedAttribute", - "System.Runtime.CompilerServices.RefSafetyRulesAttribute", - - // Ignore NativeAOT injected members - ".StartupCodeMain(Int32,IntPtr)", - ".MainMethodWrapper()", - ".MainMethodWrapper(String[])", - - // Ignore compiler generated code which can't be reasonably matched to the source method - "", - }; - - public AssemblyChecker ( - BaseAssemblyResolver originalsResolver, - ReaderParameters originalReaderParameters, - AssemblyDefinition original, - TrimmedTestCaseResult testResult) - { - this.originalsResolver = originalsResolver; - this.originalsTypeNameResolver = new TypeNameResolver (new TestResolver (), new TestAssemblyNameResolver (originalsResolver)); - this.originalReaderParameters = originalReaderParameters; - this.originalAssembly = original; - this.testResult = testResult; - this.linkedMembers = new (); - - checkNames = original.MainModule.GetTypeReferences ().Any (attr => - attr.Name == nameof (RemovedNameValueAttribute)); - } - - public void Verify () - { - var errors = VerifyImpl().ToList(); - if (errors.Any()) - { - Assert.Fail(string.Join(Environment.NewLine, errors)); - } - - } - - IEnumerable VerifyImpl() - { - // There are no type forwarders left after compilation in Native AOT - // VerifyExportedTypes (originalAssembly, linkedAssembly); - - // TODO - // VerifyCustomAttributes (originalAssembly, linkedAssembly); - // VerifySecurityAttributes (originalAssembly, linkedAssembly); - - // TODO - this is mostly attribute verification - // foreach (var originalModule in originalAssembly.Modules) - // VerifyModule (originalModule, linkedAssembly.Modules.FirstOrDefault (m => m.Name == originalModule.Name)); - - // TODO - // VerifyResources (originalAssembly, linkedAssembly); - - // There are no assembly reference in Native AOT - // VerifyReferences (originalAssembly, linkedAssembly); - - PopulateLinkedMembers (); - - var membersToAssert = originalAssembly.MainModule.Types; - foreach (var originalMember in membersToAssert) { - if (originalMember is TypeDefinition td) { - AssemblyQualifiedToken token = new (td); - - if (td.Name == "") { - linkedMembers.Remove (token); - continue; - } - - linkedMembers.TryGetValue ( - token, - out LinkedEntity? linkedMember); - - foreach(var err in VerifyTypeDefinition (td, linkedMember)) - yield return err; - linkedMembers.Remove (token); - - continue; - } - - throw new NotImplementedException ($"Don't know how to check member of type {originalMember.GetType ()}"); - } - - // Verify anything not in the main assembly - foreach(var err in VerifyLinkingOfOtherAssemblies(this.originalAssembly)) - yield return err; - - // Filter out all members which are not from the main assembly - // The Kept attributes are "optional" for non-main assemblies - string mainModuleName = originalAssembly.Name.Name; - List externalMembers = linkedMembers.Where (m => GetModuleName (m.Value.Entity) != mainModuleName).Select (m => m.Key).ToList (); - foreach (var externalMember in externalMembers) { - linkedMembers.Remove (externalMember); - } - - if (linkedMembers.Count != 0) - yield return "Linked output includes unexpected member:\n " + - string.Join ("\n ", linkedMembers.Values.Select (e => e.Entity.GetDisplayName ())); - } - - private void PopulateLinkedMembers () - { - foreach (TypeDesc type in testResult.TrimmingResults.AllEETypes) { - AddType (type); - } - - foreach (MethodDesc method in testResult.TrimmingResults.CompiledMethodBodies) { - AddMethod (method); - } - - foreach (MethodDesc method in testResult.TrimmingResults.ReflectedMethods) { - AddMethod (method, isReflected: true); - } - - void AddMethod (MethodDesc method, bool isReflected = false) - { - MethodDesc methodDef = method.GetTypicalMethodDefinition (); - - if (!ShouldIncludeMethod (methodDef)) - return; - - TypeDesc owningType = methodDef.OwningType; - - // Skip any methods on a delegate - we handle those in the AddType - // (AOT generates different methods for delegates compared to IL/metadata shapes) - if (owningType?.IsDelegate == true) - return; - - if (!AddTrimmedMethod (methodDef, isReflected)) - return; - - if (owningType is not null) { - AddType (owningType); - } - - if (methodDef.GetPropertyForAccessor () is { } property) - AddProperty (property); - - if (methodDef.GetEventForAccessor () is { } @event) - AddEvent (@event); - } - - void AddType (TypeDesc type) - { - TypeDesc typeDef = type.GetTypeDefinition (); - - if (!ShouldIncludeType (typeDef)) - return; - - if (!AddMember (typeDef)) - return; - - if (typeDef is MetadataType { ContainingType: { } containingType }) { - AddType (containingType); - } - - if (typeDef.IsDelegate) { - // AOT's handling of delegates is very different from the IL/metadata picture - // So to simplify this, we're going to automatically "mark" all of the delegate's methods - foreach (MethodDesc m in typeDef.GetMethods ()) { - if (ShouldIncludeEntityByDisplayName (m)) { - AddTrimmedMethod (m, isReflected: false); - } - } - } - } - - void AddProperty (PropertyPseudoDesc property) - { - // Note that this is currently called from AddMethod which will exit if the owning type is excluded - // and also add the owning type if necessary - if (!ShouldIncludeEntityByDisplayName (property)) - return; - - AddMember (property); - } - - void AddEvent (EventPseudoDesc @event) - { - // Note that this is currently called from AddMethod which will exit if the owning type is excluded - // and also add the owning type if necessary - if (!ShouldIncludeEntityByDisplayName (@event)) - return; - - AddMember (@event); - } - - bool AddMember (TypeSystemEntity entity) - { - Assert.False (entity is MethodDesc, "Use AddTrimmedMethod for all methods instead"); - return linkedMembers.TryAdd (new AssemblyQualifiedToken (entity), new LinkedEntity(entity)); - } - - bool AddTrimmedMethod (MethodDesc method, bool isReflected = false) - { - var token = new AssemblyQualifiedToken (method); - bool addedNew = true; - if (linkedMembers.TryGetValue(token, out var existingValue)) { - addedNew = false; - LinkedMethodEntity existingMethod = (LinkedMethodEntity) existingValue; - if (existingMethod.IsReflected || !isReflected) - return addedNew; - - linkedMembers.Remove (token); - } - - linkedMembers.Add (token, new LinkedMethodEntity (method, isReflected)); - return addedNew; - } - - static bool ShouldIncludeEntityByDisplayName (TypeSystemEntity entity) => !ExcludeDisplayNames.Contains (entity.GetDisplayName ()); - - static bool ShouldIncludeType (TypeDesc type) - { - if (type is MetadataType metadataType) { - if (metadataType.ContainingType is { } containingType) { - if (!ShouldIncludeType (containingType)) - return false; - } - - if (metadataType.Namespace.StartsWith ("Internal")) - return false; - - // Simple way to filter out system assemblies - the best way would be to get a list - // of input/reference assemblies and filter on that, but it's tricky and this should work for basically everything - if (metadataType.Namespace.StartsWith ("System")) - return false; - - - return ShouldIncludeEntityByDisplayName (type); - } - - return false; - } - - static bool ShouldIncludeMethod (MethodDesc method) => ShouldIncludeType (method.OwningType) && ShouldIncludeEntityByDisplayName (method); - } - - private static MetadataType? GetOwningType (TypeSystemEntity? entity) - { - return entity switch - { - MetadataType type => type.ContainingType as MetadataType, - MethodDesc method => method.OwningType as MetadataType, - PropertyPseudoDesc prop => prop.OwningType, - EventPseudoDesc e => e.OwningType, - _ => null - }; - } - - private static string? GetModuleName (TypeSystemEntity entity) - { - return entity switch { - MetadataType type => type.Module.ToString (), - _ => GetOwningType(entity)?.Module.ToString() - }; - } - - protected virtual IEnumerable VerifyModule (ModuleDefinition original, ModuleDefinition? linked) - { - // We never link away a module today so let's make sure the linked one isn't null - if (linked == null) { - yield return $"Linked assembly `{original.Assembly.Name.Name}` is missing module `{original.Name}`"; - yield break; - } - - var expected = original.Assembly.MainModule.AllDefinedTypes () - .SelectMany (t => GetCustomAttributeCtorValues (t, nameof (KeptModuleReferenceAttribute))) - .ToArray (); - - var actual = linked.ModuleReferences - .Select (name => name.Name) - .ToArray (); - - if (!expected.Equals(actual)) - yield return "Module references do not match"; - - foreach(var err in VerifyCustomAttributes (original, linked)) - yield return err; - } - - IEnumerable VerifyTypeDefinition (TypeDefinition original, LinkedEntity? linkedEntity) - { - TypeDesc? linked = linkedEntity?.Entity as TypeDesc; - if (linked != null && NameUtils.GetActualOriginDisplayName (linked) is string linkedDisplayName && verifiedGeneratedTypes.Contains (linkedDisplayName)) - yield break; - - EcmaModule? linkedModule = (linked as MetadataType)?.Module as EcmaModule; - - // - // Little bit complex check to allow easier test writing to match - // - It has [Kept] attribute or any variation of it - // - It contains Main method - // - It contains at least one member which has [Kept] attribute (not recursive) - // - bool expectedKept = - HasActiveKeptDerivedAttribute (original) || - (linked != null && linkedModule?.EntryPoint?.OwningType == linked) || - original.AllMembers ().Any (HasActiveKeptDerivedAttribute); - - if (!expectedKept) { - if (linked == null) - yield break; - - // Compiler generated members can't be annotated with `Kept` attributes directly - // For some of them we have special attributes (backing fields for example), but it's impractical to define - // special attributes for all types of compiler generated members (there are quite a few of them and they're - // going to change/increase over time). - // So we're effectively disabling Kept validation on compiler generated members - // Note that we still want to go "inside" each such member, as it might have additional attributes - // we do want to validate. There's no specific use case right now, but I can easily imagine one - // for more detailed testing of for example custom attributes on local functions, or similar. - if (!IsCompilerGeneratedMember (original)) - yield return $"Type `{original}' should have been removed"; - } - - bool prev = checkNames; - checkNames |= original.HasAttribute (nameof (VerifyMetadataNamesAttribute)); - - foreach(var err in VerifyTypeDefinitionKept (original, linked)) - yield return err; - - checkNames = prev; - - if (original.HasAttribute (nameof (CreatedMemberAttribute))) { - // For now always fail on this attribute since we don't know how to validate it - throw new NotSupportedException ("CreatedMemberAttribute is not yet supported by the test infra"); + partial class AssemblyChecker + { + class LinkedEntity + { + public TypeSystemEntity Entity { get; init; } + + public LinkedEntity(TypeSystemEntity entity) => Entity = entity; + } + + class LinkedMethodEntity : LinkedEntity + { + public bool IsReflected { get; init; } + + public MethodDesc Method { get => (MethodDesc)Entity; } + + public LinkedMethodEntity(MethodDesc method, bool isReflected) : base(method) => IsReflected = isReflected; + } + + private readonly BaseAssemblyResolver originalsResolver; + private readonly TypeNameResolver originalsTypeNameResolver; + private readonly ReaderParameters originalReaderParameters; + private readonly AssemblyDefinition originalAssembly; + private readonly TrimmedTestCaseResult testResult; + + private readonly Dictionary linkedMembers; + private readonly HashSet verifiedGeneratedFields = new HashSet(); + private readonly HashSet verifiedEventMethods = new HashSet(); + private readonly HashSet verifiedGeneratedTypes = new HashSet(); + private bool checkNames; + + // Note: It's enough to exclude the type name, all of its members will also be excluded then + private static readonly HashSet ExcludeDisplayNames = new() { + // Ignore compiler injected attributes to describe language version + "Microsoft.CodeAnalysis.EmbeddedAttribute", + "System.Runtime.CompilerServices.RefSafetyRulesAttribute", + + // Ignore NativeAOT injected members + ".StartupCodeMain(Int32,IntPtr)", + ".MainMethodWrapper()", + ".MainMethodWrapper(String[])", + "System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute.__GetFieldHelper(Int32,MethodTable*&)", + "System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute.__GetFieldHelper(Int32,MethodTable*&)", + "System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute.__GetFieldHelper(Int32,MethodTable*&)", + "System.Runtime.InteropServices.TypeMapping", + "System.Runtime.InteropServices.TypeMapping.GetOrCreateExternalTypeMapping()", + "System.Runtime.InteropServices.TypeMapping.GetOrCreateProxyTypeMapping()", + + // Ignore compiler generated code which can't be reasonably matched to the source method + "", + }; + + public AssemblyChecker( + BaseAssemblyResolver originalsResolver, + ReaderParameters originalReaderParameters, + AssemblyDefinition original, + TrimmedTestCaseResult testResult) + { + this.originalsResolver = originalsResolver; + this.originalsTypeNameResolver = new TypeNameResolver(new TestResolver(), new TestAssemblyNameResolver(originalsResolver)); + this.originalReaderParameters = originalReaderParameters; + this.originalAssembly = original; + this.testResult = testResult; + this.linkedMembers = new(); + + checkNames = original.MainModule.GetTypeReferences().Any(attr => + attr.Name == nameof(RemovedNameValueAttribute)); + } + + public void Verify() + { + var errors = VerifyImpl().ToList(); + if (errors.Any()) + { + Assert.Fail(string.Join(Environment.NewLine, errors)); + } + + } + + IEnumerable VerifyImpl() + { + // There are no type forwarders left after compilation in Native AOT + // VerifyExportedTypes(originalAssembly, linkedAssembly); + + // TODO + // VerifyCustomAttributes(originalAssembly, linkedAssembly); + // VerifySecurityAttributes(originalAssembly, linkedAssembly); + + // TODO - this is mostly attribute verification + // foreach (var originalModule in originalAssembly.Modules) + // VerifyModule(originalModule, linkedAssembly.Modules.FirstOrDefault (m => m.Name == originalModule.Name)); + + // TODO + // VerifyResources(originalAssembly, linkedAssembly); + + // There are no assembly reference in Native AOT + // VerifyReferences(originalAssembly, linkedAssembly); + + PopulateLinkedMembers(); + + var membersToAssert = originalAssembly.MainModule.Types; + foreach (var originalMember in membersToAssert) + { + if (originalMember is TypeDefinition td) + { + AssemblyQualifiedToken token = new(td); + + if (td.Name == "") + { + linkedMembers.Remove(token); + continue; + } + + linkedMembers.TryGetValue( + token, + out LinkedEntity? linkedMember); + + foreach (var err in VerifyTypeDefinition(td, linkedMember)) + yield return err; + linkedMembers.Remove(token); + + continue; + } + + throw new NotImplementedException($"Don't know how to check member of type {originalMember.GetType()}"); + } + + // Verify anything not in the main assembly + foreach (var err in VerifyLinkingOfOtherAssemblies(this.originalAssembly)) + yield return err; + + // Filter out all members which are not from the main assembly + // The Kept attributes are "optional" for non-main assemblies + string mainModuleName = originalAssembly.Name.Name; + List externalMembers = linkedMembers.Where(m => GetModuleName(m.Value.Entity) != mainModuleName).Select(m => m.Key).ToList(); + foreach (var externalMember in externalMembers) + { + linkedMembers.Remove(externalMember); + } + + if (linkedMembers.Count != 0) + yield return "Linked output includes unexpected member:\n " + + string.Join("\n ", linkedMembers.Values.Select(e => e.Entity.GetDisplayName())); + } + + private void PopulateLinkedMembers() + { + foreach (TypeDesc type in testResult.TrimmingResults.AllEETypes) + { + AddType(type); + } + + foreach (MethodDesc method in testResult.TrimmingResults.CompiledMethodBodies) + { + AddMethod(method); + } + + foreach (MethodDesc method in testResult.TrimmingResults.ReflectedMethods) + { + AddMethod(method, isReflected: true); + } + + void AddMethod(MethodDesc method, bool isReflected = false) + { + MethodDesc methodDef = method.GetTypicalMethodDefinition(); + + if (!ShouldIncludeMethod(methodDef)) + return; + + TypeDesc owningType = methodDef.OwningType; + + // Skip any methods on a delegate - we handle those in the AddType + // (AOT generates different methods for delegates compared to IL/metadata shapes) + if (owningType?.IsDelegate == true) + return; + + if (!AddTrimmedMethod(methodDef, isReflected)) + return; + + if (owningType is not null) + { + AddType(owningType); + } + + if (methodDef.GetPropertyForAccessor() is { } property) + AddProperty(property); + + if (methodDef.GetEventForAccessor() is { } @event) + AddEvent(@event); + } + + void AddType(TypeDesc type) + { + TypeDesc typeDef = type.GetTypeDefinition(); + + if (!ShouldIncludeType(typeDef)) + return; + + if (!AddMember(typeDef)) + return; + + if (typeDef is MetadataType { ContainingType: { } containingType }) + { + AddType(containingType); + } + + if (typeDef.IsDelegate) + { + // AOT's handling of delegates is very different from the IL/metadata picture + // So to simplify this, we're going to automatically "mark" all of the delegate's methods + foreach (MethodDesc m in typeDef.GetMethods()) + { + if (ShouldIncludeEntityByDisplayName(m)) + { + AddTrimmedMethod(m, isReflected: false); + } + } + } + } + + void AddProperty(PropertyPseudoDesc property) + { + // Note that this is currently called from AddMethod which will exit if the owning type is excluded + // and also add the owning type if necessary + if (!ShouldIncludeEntityByDisplayName(property)) + return; + + AddMember(property); + } + + void AddEvent(EventPseudoDesc @event) + { + // Note that this is currently called from AddMethod which will exit if the owning type is excluded + // and also add the owning type if necessary + if (!ShouldIncludeEntityByDisplayName(@event)) + return; + + AddMember(@event); + } + + bool AddMember(TypeSystemEntity entity) + { + Assert.False(entity is MethodDesc, "Use AddTrimmedMethod for all methods instead"); + return linkedMembers.TryAdd(new AssemblyQualifiedToken(entity), new LinkedEntity(entity)); + } + + bool AddTrimmedMethod(MethodDesc method, bool isReflected = false) + { + var token = new AssemblyQualifiedToken(method); + bool addedNew = true; + if (linkedMembers.TryGetValue(token, out var existingValue)) + { + addedNew = false; + LinkedMethodEntity existingMethod = (LinkedMethodEntity)existingValue; + if (existingMethod.IsReflected || !isReflected) + return addedNew; + + linkedMembers.Remove(token); + } + + linkedMembers.Add(token, new LinkedMethodEntity(method, isReflected)); + return addedNew; + } + + static bool ShouldIncludeEntityByDisplayName(TypeSystemEntity entity) => !ExcludeDisplayNames.Contains(entity.GetDisplayName()); + + static bool ShouldIncludeType(TypeDesc type) + { + if (type is MetadataType metadataType) + { + if (metadataType.ContainingType is { } containingType) + { + if (!ShouldIncludeType(containingType)) + return false; + } + + if (metadataType.Namespace.StartsWith("Internal")) + return false; + + if (metadataType.Module.Assembly is EcmaAssembly asm && asm.Assembly.GetName().Name == "System.Private.CoreLib") + return false; + + return ShouldIncludeEntityByDisplayName(type); + } + + return false; + } + + static bool ShouldIncludeMethod(MethodDesc method) => ShouldIncludeType(method.OwningType) && ShouldIncludeEntityByDisplayName(method); + } + + private static MetadataType? GetOwningType(TypeSystemEntity? entity) + { + return entity switch + { + MetadataType type => type.ContainingType as MetadataType, + MethodDesc method => method.OwningType as MetadataType, + PropertyPseudoDesc prop => prop.OwningType, + EventPseudoDesc e => e.OwningType, + _ => null + }; + } + + private static string? GetModuleName(TypeSystemEntity entity) + { + return entity switch + { + MetadataType type => type.Module.ToString(), + _ => GetOwningType(entity)?.Module.ToString() + }; + } + + protected virtual IEnumerable VerifyModule(ModuleDefinition original, ModuleDefinition? linked) + { + // We never link away a module today so let's make sure the linked one isn't null + if (linked == null) + { + yield return $"Linked assembly `{original.Assembly.Name.Name}` is missing module `{original.Name}`"; + yield break; + } + + var expected = original.Assembly.MainModule.AllDefinedTypes() + .SelectMany(t => GetCustomAttributeCtorValues(t, nameof(KeptModuleReferenceAttribute))) + .ToArray(); + + var actual = linked.ModuleReferences + .Select(name => name.Name) + .ToArray(); + + if (!expected.Equals(actual)) + yield return "Module references do not match"; + + foreach (var err in VerifyCustomAttributes(original, linked)) + yield return err; + } + + IEnumerable VerifyTypeDefinition(TypeDefinition original, LinkedEntity? linkedEntity) + { + TypeDesc? linked = linkedEntity?.Entity as TypeDesc; + if (linked != null && NameUtils.GetActualOriginDisplayName(linked) is string linkedDisplayName && verifiedGeneratedTypes.Contains(linkedDisplayName)) + yield break; + + EcmaModule? linkedModule = (linked as MetadataType)?.Module as EcmaModule; + + // + // Little bit complex check to allow easier test writing to match + // - It has [Kept] attribute or any variation of it + // - It contains Main method + // - It contains at least one member which has [Kept] attribute (not recursive) + // + bool expectedKept = + HasActiveKeptDerivedAttribute(original) || + (linked != null && linkedModule?.EntryPoint?.OwningType == linked) || + original.AllMembers().Any(HasActiveKeptDerivedAttribute); + + if (!expectedKept) + { + if (linked == null) + yield break; + + // Note that we still want to go "inside" each skipped type, as it might have additional attributes + // we do want to validate. There's no specific use case right now, but I can easily imagine one + // for more detailed testing of for example custom attributes on local functions, or similar. + if (!SkipKeptItemsValidation(original)) + yield return $"Type `{original}' should have been removed"; + } + + bool prev = checkNames; + checkNames |= original.HasAttribute(nameof(VerifyMetadataNamesAttribute)); + + foreach (var err in VerifyTypeDefinitionKept(original, linked)) + yield return err; + + checkNames = prev; + + if (original.HasAttribute(nameof(CreatedMemberAttribute))) + { + // For now always fail on this attribute since we don't know how to validate it + throw new NotSupportedException("CreatedMemberAttribute is not yet supported by the test infra"); #if false - foreach (var attr in original.CustomAttributes.Where (l => l.AttributeType.Name == nameof (CreatedMemberAttribute))) { - var newName = original.FullName + "::" + attr.ConstructorArguments[0].Value.ToString (); + foreach (var attr in original.CustomAttributes.Where(l => l.AttributeType.Name == nameof(CreatedMemberAttribute))) + { + var newName = original.FullName + "::" + attr.ConstructorArguments[0].Value.ToString(); - var linkedMemberName = linkedMembers.Keys.FirstOrDefault (l => l.Contains (newName)); - if (linkedMemberName == null) - yield return $"Newly created member '{newName}' was not found"; + var linkedMemberName = linkedMembers.Keys.FirstOrDefault(l => l.Contains(newName)); + if (linkedMemberName == null) + yield return $"Newly created member '{newName}' was not found"; - linkedMembers.Remove (linkedMemberName); - } + linkedMembers.Remove(linkedMemberName); + } #endif - } - } - - protected virtual IEnumerable VerifyTypeDefinitionKept (TypeDefinition original, TypeDesc? linked) - { - // NativeAOT will not keep delegate backing field type information, it's compiled down to a set of static fields - // this infra currently doesn't track fields in any way. - // Same goes for private implementation detail type. - if (IsDelegateBackingFieldsType (original) || IsPrivateImplementationDetailsType(original)) - yield break; - - if (linked == null) { - yield return $"Type `{original}' should have been kept"; - yield break; - } + } + } + + protected virtual IEnumerable VerifyTypeDefinitionKept(TypeDefinition original, TypeDesc? linked) + { + // NativeAOT will not keep delegate backing field type information, it's compiled down to a set of static fields + // this infra currently doesn't track fields in any way. + // Same goes for private implementation detail type. + if (IsDelegateBackingFieldsType(original) || IsPrivateImplementationDetailsType(original)) + yield break; + + if (linked == null) + { + yield return $"Type `{original}' should have been kept"; + yield break; + } #if false - // Skip verification of type metadata for compiler generated types (we don't currently need it yet) - if (!IsCompilerGeneratedMember (original)) { - foreach(var err in VerifyKeptByAttributes (original, linked)) - yield return err; - if (!original.IsInterface) - { - foreach(var err in VerifyBaseType (original, linked)) - yield return err; - } - - foreach(var err in VerifyInterfaces (original, linked)) - yield return err; - foreach(var err in VerifyPseudoAttributes (original, linked)) - yield return err; - foreach(var err in VerifyGenericParameters (original, linked)) - yield return err; - foreach(var err in VerifyCustomAttributes (original, linked)) - yield return err; - foreach(var err in VerifySecurityAttributes (original, linked)) - yield return err; - - foreach(var err in VerifyFixedBufferFields (original, linked)) - yield return err; - } + if (!SkipKeptItemsValidation(original)) + { + foreach (var err in VerifyKeptByAttributes(original, linked)) + yield return err; + if (!original.IsInterface) + { + foreach (var err in VerifyBaseType(original, linked)) + yield return err; + } + + foreach (var err in VerifyInterfaces(original, linked)) + yield return err; + foreach (var err in VerifyPseudoAttributes(original, linked)) + yield return err; + foreach (var err in VerifyGenericParameters(original, linked, skipKeptItemsValidation: false)) + yield return err; + foreach (var err in VerifyCustomAttributes(original, linked)) + yield return err; + foreach (var err in VerifySecurityAttributes(original, linked)) + yield return err; + + foreach (var err in VerifyFixedBufferFields(original, linked)) + yield return err; + } #endif - foreach (var td in original.NestedTypes) { - AssemblyQualifiedToken token = new (td); - linkedMembers.TryGetValue ( - token, - out LinkedEntity? linkedMember); - - foreach(var err in VerifyTypeDefinition (td, linkedMember)) - yield return err; - linkedMembers.Remove (token); - } - - //// Need to check properties before fields so that the KeptBackingFieldAttribute is handled correctly - foreach (var p in original.Properties) { - AssemblyQualifiedToken token = new AssemblyQualifiedToken (p); - - linkedMembers.TryGetValue ( - token, - out LinkedEntity? linkedMember); - foreach(var err in VerifyProperty (p, linkedMember, linked)) - yield return err; - linkedMembers.Remove (token); - } - // Need to check events before fields so that the KeptBackingFieldAttribute is handled correctly - foreach (var e in original.Events) { - AssemblyQualifiedToken token = new AssemblyQualifiedToken (e); - - linkedMembers.TryGetValue ( - token, - out LinkedEntity? linkedMember); - foreach(var err in VerifyEvent (e, linkedMember, linked)) - yield return err; - linkedMembers.Remove (token); - } + foreach (var td in original.NestedTypes) + { + AssemblyQualifiedToken token = new(td); + linkedMembers.TryGetValue( + token, + out LinkedEntity? linkedMember); + + foreach (var err in VerifyTypeDefinition(td, linkedMember)) + yield return err; + linkedMembers.Remove(token); + } + + //// Need to check properties before fields so that the KeptBackingFieldAttribute is handled correctly + foreach (var p in original.Properties) + { + AssemblyQualifiedToken token = new AssemblyQualifiedToken(p); + + linkedMembers.TryGetValue( + token, + out LinkedEntity? linkedMember); + foreach (var err in VerifyProperty(p, linkedMember, linked)) + yield return err; + linkedMembers.Remove(token); + } + // Need to check events before fields so that the KeptBackingFieldAttribute is handled correctly + foreach (var e in original.Events) + { + AssemblyQualifiedToken token = new AssemblyQualifiedToken(e); + + linkedMembers.TryGetValue( + token, + out LinkedEntity? linkedMember); + foreach (var err in VerifyEvent(e, linkedMember, linked)) + yield return err; + linkedMembers.Remove(token); + } #if false - // Need to check delegate cache fields before the normal field check - VerifyDelegateBackingFields (original, linked); - - foreach (var f in original.Fields) { - if (verifiedGeneratedFields.Contains (f.FullName)) - continue; - VerifyField (f, linked.Fields.FirstOrDefault (l => f.Name == l.Name)); - linkedMembers.Remove (f.FullName); - } + // Need to check delegate cache fields before the normal field check + VerifyDelegateBackingFields(original, linked); + + foreach (var f in original.Fields) + { + if (verifiedGeneratedFields.Contains(f.FullName)) + continue; + VerifyField(f, linked.Fields.FirstOrDefault(l => f.Name == l.Name)); + linkedMembers.Remove(f.FullName); + } #endif - foreach (var m in original.Methods) { - if (verifiedEventMethods.Contains (m.FullName)) - continue; - - AssemblyQualifiedToken token = new (m); - linkedMembers.TryGetValue ( - token, - out LinkedEntity? linkedMember); - - foreach(var err in VerifyMethod (m, linkedMember)) - yield return err; - linkedMembers.Remove (token); - } - } - - private IEnumerable VerifyBaseType (TypeDefinition src, TypeDefinition linked) - { - string expectedBaseName; - var expectedBaseGenericAttr = src.CustomAttributes.FirstOrDefault (w => w.AttributeType.Name == nameof (KeptBaseTypeAttribute) && w.ConstructorArguments.Count > 1); - if (expectedBaseGenericAttr != null) { - expectedBaseName = FormatBaseOrInterfaceAttributeValue (expectedBaseGenericAttr); - } else { - var defaultBaseType = src.IsEnum ? "System.Enum" : src.IsValueType ? "System.ValueType" : "System.Object"; - expectedBaseName = GetCustomAttributeCtorValues (src, nameof (KeptBaseTypeAttribute)).FirstOrDefault ()?.ToString () ?? defaultBaseType; - } - - if (expectedBaseName != linked.BaseType?.FullName) { - yield return $"Incorrect base type on : {linked.Name}. Expected {expectedBaseName}, actual {linked.BaseType?.FullName}"; - } - } - - private IEnumerable VerifyInterfaces (TypeDefinition src, TypeDefinition linked) - { - var expectedInterfaces = new HashSet (src.CustomAttributes - .Where (w => w.AttributeType.Name == nameof (KeptInterfaceAttribute)) - .Select (FormatBaseOrInterfaceAttributeValue)); - if (expectedInterfaces.Count == 0) { - if (linked.HasInterfaces) - yield return $"Type `{src}' has unexpected interfaces"; - } else { - foreach (var iface in linked.Interfaces) { - if (!expectedInterfaces.Remove (iface.InterfaceType.FullName)) { - if (true != expectedInterfaces.Remove (iface.InterfaceType.Resolve ().FullName)) - yield return $"Type `{src}' interface `{iface.InterfaceType.Resolve ().FullName}' should have been removed"; - } - } - - if (expectedInterfaces.Count != 0) - yield return $"Expected interfaces were not found on {src}"; - } - } - - private static string FormatBaseOrInterfaceAttributeValue (CustomAttribute attr) - { - if (attr.ConstructorArguments.Count == 1) - return attr.ConstructorArguments[0].Value.ToString ()!; - - StringBuilder builder = new StringBuilder (); - builder.Append (attr.ConstructorArguments[0].Value); - builder.Append ('<'); - bool separator = false; - foreach (var caa in (CustomAttributeArgument[]) attr.ConstructorArguments[1].Value) { - if (separator) - builder.Append (','); - else - separator = true; - - var arg = (CustomAttributeArgument) caa.Value; - builder.Append (arg.Value); - } - - builder.Append ('>'); - return builder.ToString (); - } - - private IEnumerable VerifyField (FieldDefinition src, FieldDesc? linked) - { - bool compilerGenerated = IsCompilerGeneratedMember (src); - bool expectedKept = ShouldBeKept (src) | compilerGenerated; - - if (!expectedKept) { - if (linked != null) - yield return $"Field `{src}' should have been removed"; - - yield break; - } - - foreach(var err in VerifyFieldKept (src, linked, compilerGenerated)) - yield return err; - } - - private static IEnumerable VerifyFieldKept (FieldDefinition src, FieldDesc? linked, bool compilerGenerated) - { - if (linked == null) { - yield return $"Field `{src}' should have been kept"; - yield break; - } - - - if (src.HasConstant) - throw new NotImplementedException ("Constant value for a field is not yet supported by the test infra."); + foreach (var m in original.Methods) + { + if (verifiedEventMethods.Contains(m.FullName)) + continue; + + AssemblyQualifiedToken token = new(m); + linkedMembers.TryGetValue( + token, + out LinkedEntity? linkedMember); + + foreach (var err in VerifyMethod(m, linkedMember)) + yield return err; + linkedMembers.Remove(token); + } + } + + private IEnumerable VerifyBaseType(TypeDefinition src, TypeDefinition linked) + { + string expectedBaseName; + var expectedBaseGenericAttr = src.CustomAttributes.FirstOrDefault(w => w.AttributeType.Name == nameof(KeptBaseTypeAttribute) && w.ConstructorArguments.Count > 1); + if (expectedBaseGenericAttr != null) + { + expectedBaseName = FormatBaseOrInterfaceAttributeValue(expectedBaseGenericAttr); + } + else + { + var defaultBaseType = src.IsEnum ? "System.Enum" : src.IsValueType ? "System.ValueType" : "System.Object"; + expectedBaseName = GetCustomAttributeCtorValues(src, nameof(KeptBaseTypeAttribute)).FirstOrDefault()?.ToString() ?? defaultBaseType; + } + + if (expectedBaseName != linked.BaseType?.FullName) + { + yield return $"Incorrect base type on : {linked.Name}. Expected {expectedBaseName}, actual {linked.BaseType?.FullName}"; + } + } + + private IEnumerable VerifyInterfaces(TypeDefinition src, TypeDefinition linked) + { + var expectedInterfaces = new HashSet(src.CustomAttributes + .Where(w => w.AttributeType.Name == nameof(KeptInterfaceAttribute)) + .Select(FormatBaseOrInterfaceAttributeValue)); + if (expectedInterfaces.Count == 0) + { + if (linked.HasInterfaces) + yield return $"Type `{src}' has unexpected interfaces"; + } + else + { + foreach (var iface in linked.Interfaces) + { + if (!expectedInterfaces.Remove(iface.InterfaceType.FullName)) + { + if (true != expectedInterfaces.Remove(iface.InterfaceType.Resolve().FullName)) + yield return $"Type `{src}' interface `{iface.InterfaceType.Resolve().FullName}' should have been removed"; + } + } + + if (expectedInterfaces.Count != 0) + yield return $"Expected interfaces were not found on {src}"; + } + } + + private static string FormatBaseOrInterfaceAttributeValue(CustomAttribute attr) + { + if (attr.ConstructorArguments.Count == 1) + return attr.ConstructorArguments[0].Value.ToString()!; + + StringBuilder builder = new StringBuilder(); + builder.Append(attr.ConstructorArguments[0].Value); + builder.Append('<'); + bool separator = false; + foreach (var caa in (CustomAttributeArgument[])attr.ConstructorArguments[1].Value) + { + if (separator) + builder.Append(','); + else + separator = true; + + var arg = (CustomAttributeArgument)caa.Value; + builder.Append(arg.Value); + } + + builder.Append('>'); + return builder.ToString(); + } + + private IEnumerable VerifyField(FieldDefinition src, FieldDesc? linked) + { + bool skipKeptItemsValidation = SkipKeptItemsValidation(src); + bool expectedKept = ShouldBeKept(src); + + if (!expectedKept) + { + if (linked != null && !skipKeptItemsValidation) + yield return $"Field `{src}' should have been removed"; + + yield break; + } + + foreach (var err in VerifyFieldKept(src, linked, skipKeptItemsValidation)) + yield return err; + } + + private static IEnumerable VerifyFieldKept(FieldDefinition src, FieldDesc? linked, bool skipKeptItemsValidation) + { + if (linked == null) + { + yield return $"Field `{src}' should have been kept"; + yield break; + } + + + if (src.HasConstant) + throw new NotImplementedException("Constant value for a field is not yet supported by the test infra."); #if false - if (!Equals (src.Constant, linked.Constant)) { - yield return $"Field '{src}' value doesn's match. Expected {src.Constant}, actual {linked.Constant}"; - } + if (!Equals(src.Constant, linked.Constant)) { + yield return $"Field '{src}' value doesn's match. Expected {src.Constant}, actual {linked.Constant}"; + } #endif #if false - foreach(var err in VerifyPseudoAttributes (src, linked)) - yield return err; - if (!compilerGenerated) - foreach(var err in VerifyCustomAttributes (src, linked)) - yield return err; + foreach (var err in VerifyPseudoAttributes (src, linked)) + yield return err; + if (!skipKeptItemsValidation) + foreach (var err in VerifyCustomAttributes (src, linked)) + yield return err; #endif - } + } - private IEnumerable VerifyProperty (PropertyDefinition src, LinkedEntity? linkedEntity, TypeDesc linkedType) - { - PropertyPseudoDesc? linked = linkedEntity?.Entity as PropertyPseudoDesc; - VerifyMemberBackingField (src, linkedType); + private IEnumerable VerifyProperty(PropertyDefinition src, LinkedEntity? linkedEntity, TypeDesc linkedType) + { + PropertyPseudoDesc? linked = linkedEntity?.Entity as PropertyPseudoDesc; + VerifyMemberBackingField(src, linkedType); - bool compilerGenerated = IsCompilerGeneratedMember (src); - bool expectedKept = ShouldBeKept (src) || compilerGenerated; + bool skipKeptItemsValidation = SkipKeptItemsValidation(src); + bool expectedKept = ShouldBeKept(src); - if (!expectedKept) { - if (linked is not null) - yield return $"Property `{src}' should have been removed"; + if (!expectedKept) + { + if (linked is not null && !skipKeptItemsValidation) + yield return $"Property `{src}' should have been removed"; - yield break; - } + yield break; + } - if (linked is null) { - yield return $"Property `{src}' should have been kept"; - yield break; - } + if (linked is null) + { + yield return $"Property `{src}' should have been kept"; + yield break; + } - if (src.HasConstant) - throw new NotSupportedException ("Constant value for a property is not yet supported by the test infra."); + if (src.HasConstant) + throw new NotSupportedException("Constant value for a property is not yet supported by the test infra."); #if false - if (src.Constant != linked.Constant) { - yield return $"Property '{src}' value doesn's match. Expected {src.Constant}, actual {linked.Constant}"; - } + if (src.Constant != linked.Constant) + { + yield return $"Property '{src}' value doesn's match. Expected {src.Constant}, actual {linked.Constant}"; + } #endif #if false - foreach(var err in VerifyPseudoAttributes (src, linked)) - yield return err; - if (!compilerGenerated) - { - foreach(var err in VerifyCustomAttributes (src, linked)) - yield return err; - } + foreach (var err in VerifyPseudoAttributes(src, linked)) + yield return err; + if (!skipKeptItemsValidation) + { + foreach (var err in VerifyCustomAttributes(src, linked)) + yield return err; + } #endif - } - - private IEnumerable VerifyEvent (EventDefinition src, LinkedEntity? linkedEntity, TypeDesc linkedType) - { - EventPseudoDesc? linked = linkedEntity?.Entity as EventPseudoDesc; - foreach(var err in VerifyMemberBackingField (src, linkedType)) - yield return err; - - bool compilerGenerated = IsCompilerGeneratedMember (src); - bool expectedKept = ShouldBeKept (src) | compilerGenerated; - - if (!expectedKept) { - if (linked is not null) - yield return $"Event `{src}' should have been removed"; - - yield break; - } - - if (linked is null) { - yield return $"Event `{src}' should have been kept"; - yield break; - } - - if (src.CustomAttributes.Any (attr => attr.AttributeType.Name == nameof (KeptEventAddMethodAttribute))) { - // TODO: This is wrong - we can't validate that the method is present by looking at linked (as that is not actually linked) - // we need to look into linkedMembers to see if the method was actually preserved by the compiler (and has an entry point) - foreach(var err in VerifyMethodInternal (src.AddMethod, new LinkedMethodEntity(linked.AddMethod, false), true, compilerGenerated)) - yield return err; - verifiedEventMethods.Add (src.AddMethod.FullName); - linkedMembers.Remove (new AssemblyQualifiedToken (src.AddMethod)); - } - - if (src.CustomAttributes.Any (attr => attr.AttributeType.Name == nameof (KeptEventRemoveMethodAttribute))) { - // TODO: This is wrong - we can't validate that the method is present by looking at linked (as that is not actually linked) - // we need to look into linkedMembers to see if the method was actually preserved by the compiler (and has an entry point) - foreach(var err in VerifyMethodInternal (src.RemoveMethod, new LinkedMethodEntity(linked.RemoveMethod, false), true, compilerGenerated)) - yield return err; - verifiedEventMethods.Add (src.RemoveMethod.FullName); - linkedMembers.Remove (new AssemblyQualifiedToken (src.RemoveMethod)); - } + } + + private IEnumerable VerifyEvent(EventDefinition src, LinkedEntity? linkedEntity, TypeDesc linkedType) + { + EventPseudoDesc? linked = linkedEntity?.Entity as EventPseudoDesc; + foreach (var err in VerifyMemberBackingField(src, linkedType)) + yield return err; + + bool skipKeptItemsValidation = SkipKeptItemsValidation(src); + bool expectedKept = ShouldBeKept(src); + + if (!expectedKept) + { + if (linked is not null && !skipKeptItemsValidation) + yield return $"Event `{src}' should have been removed"; + + yield break; + } + + if (linked is null) + { + yield return $"Event `{src}' should have been kept"; + yield break; + } + + if (src.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(KeptEventAddMethodAttribute))) + { + // TODO: This is wrong - we can't validate that the method is present by looking at linked (as that is not actually linked) + // we need to look into linkedMembers to see if the method was actually preserved by the compiler (and has an entry point) + foreach (var err in VerifyMethodInternal(src.AddMethod, new LinkedMethodEntity(linked.AddMethod, false), true, skipKeptItemsValidation)) + yield return err; + verifiedEventMethods.Add(src.AddMethod.FullName); + linkedMembers.Remove(new AssemblyQualifiedToken(src.AddMethod)); + } + + if (src.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(KeptEventRemoveMethodAttribute))) + { + // TODO: This is wrong - we can't validate that the method is present by looking at linked (as that is not actually linked) + // we need to look into linkedMembers to see if the method was actually preserved by the compiler (and has an entry point) + foreach (var err in VerifyMethodInternal(src.RemoveMethod, new LinkedMethodEntity(linked.RemoveMethod, false), true, skipKeptItemsValidation)) + yield return err; + verifiedEventMethods.Add(src.RemoveMethod.FullName); + linkedMembers.Remove(new AssemblyQualifiedToken(src.RemoveMethod)); + } #if false - foreach(var err in VerifyPseudoAttributes (src, linked)) - yield return err; - if (!compilerGenerated) - { - foreach(var err in VerifyCustomAttributes (src, linned)) - yield return err; - } + foreach (var err in VerifyPseudoAttributes(src, linked)) + yield return err; + if (!skipKeptItemsValidation) + { + foreach (var err in VerifyCustomAttributes(src, linned)) + yield return err; + } #endif - } - - private IEnumerable VerifyMethod (MethodDefinition src, LinkedEntity? linkedEntity) - { - LinkedMethodEntity? linked = linkedEntity as LinkedMethodEntity; - bool compilerGenerated = IsCompilerGeneratedMember (src); - bool expectedKept = ShouldMethodBeKept (src); - foreach(var err in VerifyMethodInternal (src, linked, expectedKept, compilerGenerated)) - yield return err; - } - - private IEnumerable VerifyMethodInternal (MethodDefinition src, LinkedMethodEntity? linked, bool expectedKept, bool compilerGenerated) - { - if (!expectedKept) { - if (linked == null) - yield break; - - // Similar to comment on types, compiler-generated methods can't be annotated with Kept attribute directly - // so we're not going to validate kept/remove on them. Note that we're still going to go validate "into" them - // to check for other properties (like parameter name presence/removal for example) - if (!compilerGenerated) - yield return $"Method `{NameUtils.GetExpectedOriginDisplayName (src)}' should have been removed"; - } - - foreach(var err in VerifyMethodKept (src, linked, compilerGenerated)) - yield return err; - } - - private IEnumerable VerifyMemberBackingField (IMemberDefinition src, TypeDesc? linkedType) - { - var keptBackingFieldAttribute = src.CustomAttributes.FirstOrDefault (attr => attr.AttributeType.Name == nameof (KeptBackingFieldAttribute)); - if (keptBackingFieldAttribute == null) - yield break; - - var backingFieldName = src.MetadataToken.TokenType == TokenType.Property - ? $"<{src.Name}>k__BackingField" : src.Name; - var srcField = src.DeclaringType.Fields.FirstOrDefault (f => f.Name == backingFieldName); - - if (srcField == null) { - // Can add more here if necessary - backingFieldName = backingFieldName.Replace ("System.Int32", "int"); - backingFieldName = backingFieldName.Replace ("System.String", "string"); - backingFieldName = backingFieldName.Replace ("System.Char", "char"); - - srcField = src.DeclaringType.Fields.FirstOrDefault (f => f.Name == backingFieldName); - } - - if (srcField == null) { - yield return $"{src.MetadataToken.TokenType} `{src}', could not locate the expected backing field {backingFieldName}"; - yield break; - } - - foreach(var err in VerifyFieldKept (srcField, linkedType?.GetFields ()?.FirstOrDefault (l => srcField.Name == l.Name), compilerGenerated: true)) - yield return err; - verifiedGeneratedFields.Add (srcField.FullName); - linkedMembers.Remove (new AssemblyQualifiedToken (srcField)); - } - - IEnumerable VerifyMethodKept (MethodDefinition src, LinkedMethodEntity? linked, bool compilerGenerated) - { - if (linked == null) { - yield return $"Method `{NameUtils.GetExpectedOriginDisplayName (src)}' should have been kept"; - yield break; - } + } + + private IEnumerable VerifyMethod(MethodDefinition src, LinkedEntity? linkedEntity) + { + LinkedMethodEntity? linked = linkedEntity as LinkedMethodEntity; + bool skipKeptItemsValidation = SkipKeptItemsValidation(src); + bool expectedKept = ShouldMethodBeKept(src); + foreach (var err in VerifyMethodInternal(src, linked, expectedKept, skipKeptItemsValidation)) + yield return err; + } + + private IEnumerable VerifyMethodInternal(MethodDefinition src, LinkedMethodEntity? linked, bool expectedKept, bool skipKeptItemsValidation) + { + if (!expectedKept) + { + if (linked == null) + yield break; + + // Note that we're still going to go validate "into" skipped methods to check for other properties + // (like parameter name presence/removal for example) + if (!skipKeptItemsValidation) + yield return $"Method `{NameUtils.GetExpectedOriginDisplayName(src)}' should have been removed"; + } + + foreach (var err in VerifyMethodKept(src, linked, skipKeptItemsValidation)) + yield return err; + } + + private IEnumerable VerifyMemberBackingField(IMemberDefinition src, TypeDesc? linkedType) + { + var keptBackingFieldAttribute = src.CustomAttributes.FirstOrDefault(attr => attr.AttributeType.Name == nameof(KeptBackingFieldAttribute)); + if (keptBackingFieldAttribute == null) + yield break; + + var backingFieldName = src.MetadataToken.TokenType == TokenType.Property + ? $"<{src.Name}>k__BackingField" : src.Name; + var srcField = src.DeclaringType.Fields.FirstOrDefault(f => f.Name == backingFieldName); + + if (srcField == null) + { + // Can add more here if necessary + backingFieldName = backingFieldName.Replace("System.Int32", "int"); + backingFieldName = backingFieldName.Replace("System.String", "string"); + backingFieldName = backingFieldName.Replace("System.Char", "char"); + + srcField = src.DeclaringType.Fields.FirstOrDefault(f => f.Name == backingFieldName); + } + + if (srcField == null) + { + yield return $"{src.MetadataToken.TokenType} `{src}', could not locate the expected backing field {backingFieldName}"; + yield break; + } + + foreach (var err in VerifyFieldKept(srcField, linkedType?.GetFields()?.FirstOrDefault(l => srcField.Name == l.Name), skipKeptItemsValidation: true)) + yield return err; + verifiedGeneratedFields.Add(srcField.FullName); + linkedMembers.Remove(new AssemblyQualifiedToken(srcField)); + } + + IEnumerable VerifyMethodKept(MethodDefinition src, LinkedMethodEntity? linked, bool skipKeptItemsValidation) + { + if (linked == null) + { + yield return $"Method `{NameUtils.GetExpectedOriginDisplayName(src)}' should have been kept"; + yield break; + } #if false - foreach(var err in VerifyPseudoAttributes (src, linked)) - yield return err; - foreach(var err in VerifyGenericParameters (src, linked)) - yield return err; - if (!compilerGenerated) { - foreach(var err in VerifyCustomAttributes (src, linked)) - yield return err; - foreach(var err in VerifyCustomAttributes (src.MethodReturnType, linked.MethodReturnType)) - yield return err; - } + foreach (var err in VerifyPseudoAttributes(src, linked)) + yield return err; + foreach (var err in VerifyGenericParameters(src, linked, skipKeptItemsValidation)) + yield return err; + if (!skipKeptItemsValidation) + { + foreach (var err in VerifyCustomAttributes(src, linked)) + yield return err; + foreach (var err in VerifyCustomAttributes(src.MethodReturnType, linked.MethodReturnType)) + yield return err; + } #endif - foreach(var err in VerifyParameters (src, linked)) - yield return err; + foreach (var err in VerifyParameters(src, linked, skipKeptItemsValidation)) + yield return err; #if false - foreach(var err in VerifySecurityAttributes (src, linked)) - yield return err; - foreach(var err in VerifyArrayInitializers (src, linked)) - yield return err; - - // Method bodies are not very different in Native AOT - foreach(var err in VerifyMethodBody (src, linked)) - yield return err; - foreach(var err in VerifyKeptByAttributes (src, linked)) - yield return err; + foreach (var err in VerifySecurityAttributes(src, linked)) + yield return err; + foreach (var err in VerifyArrayInitializers(src, linked)) + yield return err; + + // Method bodies are not very different in Native AOT + foreach (var err in VerifyMethodBody (src, linked)) + yield return err; + foreach (var err in VerifyKeptByAttributes (src, linked)) + yield return err; #endif - } - - protected virtual IEnumerable VerifyMethodBody (MethodDefinition src, MethodDefinition linked) - { - if (!src.HasBody) - yield break; - - foreach(var err in VerifyInstructions (src, linked)) - yield return err; - foreach(var err in VerifyLocals (src, linked)) - yield return err; - } - - protected static IEnumerable VerifyInstructions (MethodDefinition src, MethodDefinition linked) - { - foreach (var err in VerifyBodyProperties ( - src, - linked, - nameof (ExpectedInstructionSequenceAttribute), - nameof (ExpectBodyModifiedAttribute), - "instructions", - m => FormatMethodBody (m.Body), - attr => GetStringArrayAttributeValue (attr)!.ToArray ())) - { - yield return err; - } - } - - public static string[] FormatMethodBody (MethodBody body) - { - List<(Instruction?, string)> result = new List<(Instruction?, string)> (body.Instructions.Count); - for (int index = 0; index < body.Instructions.Count; index++) { - var instruction = body.Instructions[index]; - result.Add ((instruction, FormatInstruction (instruction))); - } - - HashSet<(Instruction, Instruction)> existingTryBlocks = new HashSet<(Instruction, Instruction)> (); - foreach (var exHandler in body.ExceptionHandlers) { - if (existingTryBlocks.Add ((exHandler.TryStart, exHandler.TryEnd!))) { - InsertBeforeInstruction (exHandler.TryStart, ".try"); - if (exHandler.TryEnd != null) - InsertBeforeInstruction (exHandler.TryEnd, ".endtry"); - else - Append (".endtry"); - } - - if (exHandler.HandlerStart != null) - InsertBeforeInstruction (exHandler.HandlerStart, ".catch"); - - if (exHandler.HandlerEnd != null) - InsertBeforeInstruction (exHandler.HandlerEnd, ".endcatch"); - else - Append (".endcatch"); - - if (exHandler.FilterStart != null) - InsertBeforeInstruction (exHandler.FilterStart, ".filter"); - } - - return result.Select (i => i.Item2).ToArray (); - - void InsertBeforeInstruction (Instruction instruction, string text) => - result.Insert (result.FindIndex (i => i.Item1 == instruction), (null, text)); - - void Append (string text) => - result.Add ((null, text)); - } - - private static string FormatInstruction (Instruction instr) - { - switch (instr.OpCode.FlowControl) { - case FlowControl.Branch: - case FlowControl.Cond_Branch: - if (instr.Operand is Instruction target) - return $"{instr.OpCode} il_{target.Offset:x}"; - - break; - } - - switch (instr.OpCode.Code) { - case Code.Ldc_I4: - if (instr.Operand is int ivalue) - return $"{instr.OpCode} 0x{ivalue:x}"; - - throw new NotImplementedException (instr.Operand.GetType ().ToString ()); - case Code.Ldc_I4_S: - if (instr.Operand is sbyte bvalue) - return $"{instr.OpCode} 0x{bvalue:x}"; - - throw new NotImplementedException (instr.Operand.GetType ().ToString ()); - case Code.Ldc_I8: - if (instr.Operand is long lvalue) - return $"{instr.OpCode} 0x{lvalue:x}"; - - throw new NotImplementedException (instr.Operand.GetType ().ToString ()); - - case Code.Ldc_R4: - if (instr.Operand is float fvalue) - return $"{instr.OpCode} {fvalue}"; - - throw new NotImplementedException (instr.Operand.GetType ().ToString ()); - - case Code.Ldc_R8: - if (instr.Operand is double dvalue) - return $"{instr.OpCode} {dvalue}"; - - throw new NotImplementedException (instr.Operand.GetType ().ToString ()); - - case Code.Ldstr: - if (instr.Operand is string svalue) - return $"{instr.OpCode} '{svalue}'"; - - throw new NotImplementedException (instr.Operand.GetType ().ToString ()); - - default: { - string? operandString = null; - switch (instr.OpCode.OperandType) { - case OperandType.InlineField: - case OperandType.InlineMethod: - case OperandType.InlineType: - case OperandType.InlineTok: - operandString = instr.Operand switch { - FieldReference fieldRef => fieldRef.FullName, - MethodReference methodRef => methodRef.FullName, - TypeReference typeRef => typeRef.FullName, - _ => null - }; - break; - } - - if (operandString != null) - return $"{instr.OpCode} {operandString}"; - else - return instr.OpCode.ToString (); - } - } - } - - private static IEnumerable VerifyLocals (MethodDefinition src, MethodDefinition linked) - { - foreach(var err in VerifyBodyProperties ( - src, - linked, - nameof (ExpectedLocalsSequenceAttribute), - nameof (ExpectLocalsModifiedAttribute), - "locals", - m => m.Body.Variables.Select (v => v.VariableType.ToString ()).ToArray (), - attr => GetStringOrTypeArrayAttributeValue (attr).ToArray ())) - { - yield return err; - } - } - - public static IEnumerable VerifyBodyProperties (MethodDefinition src, MethodDefinition linked, string sequenceAttributeName, string expectModifiedAttributeName, - string propertyDescription, - Func valueCollector, - Func getExpectFromSequenceAttribute) - { - var expectedSequenceAttribute = src.CustomAttributes.FirstOrDefault (attr => attr.AttributeType.Name == sequenceAttributeName); - var linkedValues = valueCollector (linked); - var srcValues = valueCollector (src); - - if (src.CustomAttributes.Any (attr => attr.AttributeType.Name == expectModifiedAttributeName)) { - if (linkedValues.SequenceEqual(srcValues)) - { - yield return $"Expected method `{src} to have {propertyDescription} modified, however, the {propertyDescription} were the same as the original\n{FormattingUtils.FormatSequenceCompareFailureMessage (linkedValues, srcValues)}"; - } - } else if (expectedSequenceAttribute != null) { - var expected = getExpectFromSequenceAttribute (expectedSequenceAttribute).ToArray (); - if (!linkedValues.SequenceEqual(expected)) - { - yield return $"Expected method `{src} to have it's {propertyDescription} modified, however, the sequence of {propertyDescription} does not match the expected value\n{FormattingUtils.FormatSequenceCompareFailureMessage2 (linkedValues, expected, srcValues)}"; - } - } else { - if (!linkedValues.SequenceEqual(srcValues)) - { - yield return $"Expected method `{src} to have it's {propertyDescription} unchanged, however, the {propertyDescription} differ from the original\n{FormattingUtils.FormatSequenceCompareFailureMessage (linkedValues, srcValues)}"; - } - } - } - - private IEnumerable VerifyReferences (AssemblyDefinition original, AssemblyDefinition linked) - { - var expected = original.MainModule.AllDefinedTypes () - .SelectMany (t => GetCustomAttributeCtorValues (t, nameof (KeptReferenceAttribute))) - .Select (ReduceAssemblyFileNameOrNameToNameOnly) - .ToArray (); - - /* - - The test case will always need to have at least 1 reference. - - Forcing all tests to define their expected references seems tedious - - Given the above, let's assume that when no [KeptReference] attributes are present, - the test case does not want to make any assertions regarding references. - - Once 1 kept reference attribute is used, the test will need to define all of of it's expected references - */ - if (expected.Length == 0) - yield break; - - var actual = linked.MainModule.AssemblyReferences - .Select (name => name.Name) - .ToArray (); - - if (!actual!.SequenceEqual(expected)) - yield return $"Expected references do not match actual references:\n\tExpected: {string.Join(", ", expected)}\n\tActual: {string.Join(", ", actual)}"; - } - - private string? ReduceAssemblyFileNameOrNameToNameOnly (string? fileNameOrAssemblyName) - { - if (fileNameOrAssemblyName == null) - return null; - - if (fileNameOrAssemblyName.EndsWith (".dll") || fileNameOrAssemblyName.EndsWith (".exe") || fileNameOrAssemblyName.EndsWith (".winmd")) - return System.IO.Path.GetFileNameWithoutExtension (fileNameOrAssemblyName); - - // It must already be just the assembly name - return fileNameOrAssemblyName; - } - - private IEnumerable VerifyResources (AssemblyDefinition original, AssemblyDefinition linked) - { - List expectedResourceNames = original.MainModule.AllDefinedTypes () - .SelectMany (t => GetCustomAttributeCtorValues (t, nameof (KeptResourceAttribute))) - .ToList (); - - foreach (var resource in linked.MainModule.Resources) { - if (!expectedResourceNames.Remove (resource.Name)) - yield return $"Resource '{resource.Name}' should be removed."; - - EmbeddedResource embeddedResource = (EmbeddedResource) resource; - - var expectedResource = (EmbeddedResource) original.MainModule.Resources.First (r => r.Name == resource.Name); - - if (!embeddedResource.GetResourceData().SequenceEqual(expectedResource.GetResourceData())) - yield return $"Resource '{resource.Name}' data doesn't match."; - } - - if (expectedResourceNames.Count > 0) { - yield return $"Resource '{expectedResourceNames.First ()}' should be kept."; - } - } - - private IEnumerable VerifyExportedTypes (AssemblyDefinition original, AssemblyDefinition linked) - { - var expectedTypes = original.MainModule.AllDefinedTypes () - .SelectMany (t => GetCustomAttributeCtorValues (t, nameof (KeptExportedTypeAttribute)).Select (l => l?.FullName ?? "")).ToArray (); - - if (!linked.MainModule.ExportedTypes.Select (l => l.FullName).SequenceEqual(expectedTypes)) - yield return $"Exported types do not match expected values"; - } - - protected virtual IEnumerable VerifyPseudoAttributes (MethodDefinition src, MethodDefinition linked) - { - var expected = (MethodAttributes) GetExpectedPseudoAttributeValue (src, (uint) src.Attributes); - if (!linked.Attributes.Equals(expected)) - { - yield return $"Method `{src}' pseudo attributes did not match expected"; - } - } - - protected virtual IEnumerable VerifyPseudoAttributes (TypeDefinition src, TypeDefinition linked) - { - var expected = (TypeAttributes) GetExpectedPseudoAttributeValue (src, (uint) src.Attributes); - - if (!linked.Attributes.Equals(expected)) - { - yield return $"Type `{src}' pseudo attributes did not match expected"; - } - } - - protected virtual IEnumerable VerifyPseudoAttributes (FieldDefinition src, FieldDefinition linked) - { - var expected = (FieldAttributes) GetExpectedPseudoAttributeValue (src, (uint) src.Attributes); - if (!linked.Attributes.Equals(expected)) - { - yield return $"Field `{src}' pseudo attributes did not match expected"; - } - } - - protected virtual IEnumerable VerifyPseudoAttributes (PropertyDefinition src, PropertyDefinition linked) - { - var expected = (PropertyAttributes) GetExpectedPseudoAttributeValue (src, (uint) src.Attributes); - if (!linked.Attributes.Equals(expected)) - { - yield return $"Property `{src}' pseudo attributes did not match expected"; - } - - } - - protected virtual IEnumerable VerifyPseudoAttributes (EventDefinition src, EventDefinition linked) - { - var expected = (EventAttributes) GetExpectedPseudoAttributeValue (src, (uint) src.Attributes); - if (!linked.Attributes.Equals(expected)) - { - yield return $"Event `{src}' pseudo attributes did not match expected"; - } - } - - protected virtual IEnumerable VerifyCustomAttributes (ICustomAttributeProvider src, ICustomAttributeProvider linked) - { - var expectedAttrs = GetExpectedAttributes (src).ToList (); - var linkedAttrs = FilterLinkedAttributes (linked).ToList (); - - if (!linkedAttrs.SequenceEqual(expectedAttrs)) - { - yield return $"Custom attributes on `{src}' are not matching"; - } - } - - protected virtual IEnumerable VerifySecurityAttributes (ICustomAttributeProvider src, ISecurityDeclarationProvider linked) - { - var expectedAttrs = GetCustomAttributeCtorValues (src, nameof (KeptSecurityAttribute)) - .Select (attr => attr?.ToString () ?? "") - .ToList (); - - var linkedAttrs = FilterLinkedSecurityAttributes (linked).ToList (); - - if (!linkedAttrs.SequenceEqual(expectedAttrs)) - { - yield return $"Security attributes on `{src}' are not matching"; - } - } + } + + protected virtual IEnumerable VerifyMethodBody(MethodDefinition src, MethodDefinition linked) + { + if (!src.HasBody) + yield break; + + foreach (var err in VerifyInstructions(src, linked)) + yield return err; + foreach (var err in VerifyLocals(src, linked)) + yield return err; + } + + protected static IEnumerable VerifyInstructions(MethodDefinition src, MethodDefinition linked) + { + foreach (var err in VerifyBodyProperties( + src, + linked, + nameof(ExpectedInstructionSequenceAttribute), + nameof(ExpectBodyModifiedAttribute), + "instructions", + m => FormatMethodBody(m.Body), + attr => GetStringArrayAttributeValue(attr)!.ToArray())) + { + yield return err; + } + } + + public static string[] FormatMethodBody(MethodBody body) + { + List<(Instruction?, string)> result = new List<(Instruction?, string)>(body.Instructions.Count); + for (int index = 0; index < body.Instructions.Count; index++) + { + var instruction = body.Instructions[index]; + result.Add((instruction, FormatInstruction(instruction))); + } + + HashSet<(Instruction, Instruction)> existingTryBlocks = new HashSet<(Instruction, Instruction)>(); + foreach (var exHandler in body.ExceptionHandlers) + { + if (existingTryBlocks.Add((exHandler.TryStart, exHandler.TryEnd!))) + { + InsertBeforeInstruction(exHandler.TryStart, ".try"); + if (exHandler.TryEnd != null) + InsertBeforeInstruction(exHandler.TryEnd, ".endtry"); + else + Append(".endtry"); + } + + if (exHandler.HandlerStart != null) + InsertBeforeInstruction(exHandler.HandlerStart, ".catch"); + + if (exHandler.HandlerEnd != null) + InsertBeforeInstruction(exHandler.HandlerEnd, ".endcatch"); + else + Append(".endcatch"); + + if (exHandler.FilterStart != null) + InsertBeforeInstruction(exHandler.FilterStart, ".filter"); + } + + return result.Select(i => i.Item2).ToArray(); + + void InsertBeforeInstruction(Instruction instruction, string text) => + result.Insert(result.FindIndex(i => i.Item1 == instruction), (null, text)); + + void Append(string text) => + result.Add((null, text)); + } + + private static string FormatInstruction(Instruction instr) + { + switch (instr.OpCode.FlowControl) + { + case FlowControl.Branch: + case FlowControl.Cond_Branch: + if (instr.Operand is Instruction target) + return $"{instr.OpCode} il_{target.Offset:x}"; + + break; + } + + switch (instr.OpCode.Code) + { + case Code.Ldc_I4: + if (instr.Operand is int ivalue) + return $"{instr.OpCode} 0x{ivalue:x}"; + + throw new NotImplementedException(instr.Operand.GetType().ToString()); + case Code.Ldc_I4_S: + if (instr.Operand is sbyte bvalue) + return $"{instr.OpCode} 0x{bvalue:x}"; + + throw new NotImplementedException(instr.Operand.GetType().ToString()); + case Code.Ldc_I8: + if (instr.Operand is long lvalue) + return $"{instr.OpCode} 0x{lvalue:x}"; + + throw new NotImplementedException(instr.Operand.GetType().ToString()); + + case Code.Ldc_R4: + if (instr.Operand is float fvalue) + return $"{instr.OpCode} {fvalue}"; + + throw new NotImplementedException(instr.Operand.GetType().ToString()); + + case Code.Ldc_R8: + if (instr.Operand is double dvalue) + return $"{instr.OpCode} {dvalue}"; + + throw new NotImplementedException(instr.Operand.GetType().ToString()); + + case Code.Ldstr: + if (instr.Operand is string svalue) + return $"{instr.OpCode} '{svalue}'"; + + throw new NotImplementedException(instr.Operand.GetType().ToString()); + + default: + { + string? operandString = null; + switch (instr.OpCode.OperandType) + { + case OperandType.InlineField: + case OperandType.InlineMethod: + case OperandType.InlineType: + case OperandType.InlineTok: + operandString = instr.Operand switch + { + FieldReference fieldRef => fieldRef.FullName, + MethodReference methodRef => methodRef.FullName, + TypeReference typeRef => typeRef.FullName, + _ => null + }; + break; + } + + if (operandString != null) + return $"{instr.OpCode} {operandString}"; + else + return instr.OpCode.ToString(); + } + } + } + + private static IEnumerable VerifyLocals(MethodDefinition src, MethodDefinition linked) + { + foreach (var err in VerifyBodyProperties( + src, + linked, + nameof(ExpectedLocalsSequenceAttribute), + nameof(ExpectLocalsModifiedAttribute), + "locals", + m => m.Body.Variables.Select(v => v.VariableType.ToString()).ToArray(), + attr => GetStringOrTypeArrayAttributeValue(attr).ToArray())) + { + yield return err; + } + } + + public static IEnumerable VerifyBodyProperties(MethodDefinition src, MethodDefinition linked, string sequenceAttributeName, string expectModifiedAttributeName, + string propertyDescription, + Func valueCollector, + Func getExpectFromSequenceAttribute) + { + var expectedSequenceAttribute = src.CustomAttributes.FirstOrDefault(attr => attr.AttributeType.Name == sequenceAttributeName); + var linkedValues = valueCollector(linked); + var srcValues = valueCollector(src); + + if (src.CustomAttributes.Any(attr => attr.AttributeType.Name == expectModifiedAttributeName)) + { + if (linkedValues.SequenceEqual(srcValues)) + { + yield return $"Expected method `{src} to have {propertyDescription} modified, however, the {propertyDescription} were the same as the original\n{FormattingUtils.FormatSequenceCompareFailureMessage(linkedValues, srcValues)}"; + } + } + else if (expectedSequenceAttribute != null) + { + var expected = getExpectFromSequenceAttribute(expectedSequenceAttribute).ToArray(); + if (!linkedValues.SequenceEqual(expected)) + { + yield return $"Expected method `{src} to have it's {propertyDescription} modified, however, the sequence of {propertyDescription} does not match the expected value\n{FormattingUtils.FormatSequenceCompareFailureMessage2(linkedValues, expected, srcValues)}"; + } + } + else + { + if (!linkedValues.SequenceEqual(srcValues)) + { + yield return $"Expected method `{src} to have it's {propertyDescription} unchanged, however, the {propertyDescription} differ from the original\n{FormattingUtils.FormatSequenceCompareFailureMessage(linkedValues, srcValues)}"; + } + } + } + + private IEnumerable VerifyReferences(AssemblyDefinition original, AssemblyDefinition linked) + { + var expected = original.MainModule.AllDefinedTypes() + .SelectMany(t => GetCustomAttributeCtorValues(t, nameof(KeptReferenceAttribute))) + .Select(ReduceAssemblyFileNameOrNameToNameOnly) + .ToArray(); + + /* + - The test case will always need to have at least 1 reference. + - Forcing all tests to define their expected references seems tedious + + Given the above, let's assume that when no [KeptReference] attributes are present, + the test case does not want to make any assertions regarding references. + + Once 1 kept reference attribute is used, the test will need to define all of of it's expected references + */ + if (expected.Length == 0) + yield break; + + var actual = linked.MainModule.AssemblyReferences + .Select(name => name.Name) + .ToArray(); + + if (!actual!.SequenceEqual(expected)) + yield return $"Expected references do not match actual references:\n\tExpected: {string.Join(", ", expected)}\n\tActual: {string.Join(", ", actual)}"; + } + + private string? ReduceAssemblyFileNameOrNameToNameOnly(string? fileNameOrAssemblyName) + { + if (fileNameOrAssemblyName == null) + return null; + + if (fileNameOrAssemblyName.EndsWith(".dll") || fileNameOrAssemblyName.EndsWith(".exe") || fileNameOrAssemblyName.EndsWith(".winmd")) + return System.IO.Path.GetFileNameWithoutExtension(fileNameOrAssemblyName); + + // It must already be just the assembly name + return fileNameOrAssemblyName; + } + + private IEnumerable VerifyResources(AssemblyDefinition original, AssemblyDefinition linked) + { + List expectedResourceNames = original.MainModule.AllDefinedTypes() + .SelectMany(t => GetCustomAttributeCtorValues(t, nameof(KeptResourceAttribute))) + .ToList(); + + foreach (var resource in linked.MainModule.Resources) + { + if (!expectedResourceNames.Remove(resource.Name)) + yield return $"Resource '{resource.Name}' should be removed."; + + EmbeddedResource embeddedResource = (EmbeddedResource)resource; + + var expectedResource = (EmbeddedResource)original.MainModule.Resources.First(r => r.Name == resource.Name); + + if (!embeddedResource.GetResourceData().SequenceEqual(expectedResource.GetResourceData())) + yield return $"Resource '{resource.Name}' data doesn't match."; + } + + if (expectedResourceNames.Count > 0) + { + yield return $"Resource '{expectedResourceNames.First()}' should be kept."; + } + } + + private IEnumerable VerifyExportedTypes(AssemblyDefinition original, AssemblyDefinition linked) + { + var expectedTypes = original.MainModule.AllDefinedTypes() + .SelectMany(t => GetCustomAttributeCtorValues(t, nameof(KeptExportedTypeAttribute)).Select(l => l?.FullName ?? "")).ToArray(); + + if (!linked.MainModule.ExportedTypes.Select(l => l.FullName).SequenceEqual(expectedTypes)) + yield return $"Exported types do not match expected values"; + } + + protected virtual IEnumerable VerifyPseudoAttributes(MethodDefinition src, MethodDefinition linked) + { + var expected = (MethodAttributes)GetExpectedPseudoAttributeValue(src, (uint)src.Attributes); + if (!linked.Attributes.Equals(expected)) + { + yield return $"Method `{src}' pseudo attributes did not match expected"; + } + } + + protected virtual IEnumerable VerifyPseudoAttributes(TypeDefinition src, TypeDefinition linked) + { + var expected = (TypeAttributes)GetExpectedPseudoAttributeValue(src, (uint)src.Attributes); + + if (!linked.Attributes.Equals(expected)) + { + yield return $"Type `{src}' pseudo attributes did not match expected"; + } + } + + protected virtual IEnumerable VerifyPseudoAttributes(FieldDefinition src, FieldDefinition linked) + { + var expected = (FieldAttributes)GetExpectedPseudoAttributeValue(src, (uint)src.Attributes); + if (!linked.Attributes.Equals(expected)) + { + yield return $"Field `{src}' pseudo attributes did not match expected"; + } + } + + protected virtual IEnumerable VerifyPseudoAttributes(PropertyDefinition src, PropertyDefinition linked) + { + var expected = (PropertyAttributes)GetExpectedPseudoAttributeValue(src, (uint)src.Attributes); + if (!linked.Attributes.Equals(expected)) + { + yield return $"Property `{src}' pseudo attributes did not match expected"; + } + + } + + protected virtual IEnumerable VerifyPseudoAttributes(EventDefinition src, EventDefinition linked) + { + var expected = (EventAttributes)GetExpectedPseudoAttributeValue(src, (uint)src.Attributes); + if (!linked.Attributes.Equals(expected)) + { + yield return $"Event `{src}' pseudo attributes did not match expected"; + } + } + + protected virtual IEnumerable VerifyCustomAttributes(ICustomAttributeProvider src, ICustomAttributeProvider linked) + { + var expectedAttrs = GetExpectedAttributes(src).ToList(); + var linkedAttrs = FilterLinkedAttributes(linked).ToList(); + + if (!linkedAttrs.SequenceEqual(expectedAttrs)) + { + yield return $"Custom attributes on `{src}' are not matching"; + } + } + + protected virtual IEnumerable VerifySecurityAttributes(ICustomAttributeProvider src, ISecurityDeclarationProvider linked) + { + var expectedAttrs = GetCustomAttributeCtorValues(src, nameof(KeptSecurityAttribute)) + .Select(attr => attr?.ToString() ?? "") + .ToList(); + + var linkedAttrs = FilterLinkedSecurityAttributes(linked).ToList(); + + if (!linkedAttrs.SequenceEqual(expectedAttrs)) + { + yield return $"Security attributes on `{src}' are not matching"; + } + } #if false - protected virtual IEnumerable VerifyArrayInitializers (MethodDefinition src, MethodDefinition linked) - { - var expectedIndices = GetCustomAttributeCtorValues (src, nameof (KeptInitializerData)) - .Cast () - .ToArray (); - - var expectKeptAll = src.CustomAttributes.Any (attr => attr.AttributeType.Name == nameof (KeptInitializerData) && !attr.HasConstructorArguments); - - if (expectedIndices.Length == 0 && !expectKeptAll) - return; - - if (!src.HasBody) - yield return $"`{nameof (KeptInitializerData)}` cannot be used on methods that don't have bodies"; - - var srcImplementationDetails = src.Module.Types.FirstOrDefault (t => string.IsNullOrEmpty (t.Namespace) && t.Name.StartsWith ("")); - - if (srcImplementationDetails == null) { - yield return "Could not locate in the original assembly. Does your test use initializers?"; - return; - } - - var linkedImplementationDetails = linked.Module.Types.FirstOrDefault (t => string.IsNullOrEmpty (t.Namespace) && t.Name.StartsWith ("")); - - if (linkedImplementationDetails == null) { - yield return "Could not locate in the linked assembly"; - return; - } - - var possibleInitializerFields = src.Body.Instructions - .Where (ins => IsLdtokenOnPrivateImplementationDetails (srcImplementationDetails, ins)) - .Select (ins => ((FieldReference) ins.Operand).Resolve ()) - .ToArray (); - - if (possibleInitializerFields.Length == 0) - yield return $"`{src}` does not make use of any initializers"; - - if (expectKeptAll) { - foreach (var srcField in possibleInitializerFields) { - var linkedField = linkedImplementationDetails.Fields.FirstOrDefault (f => f.InitialValue.SequenceEqual (srcField.InitialValue)); - foreach(var err in VerifyInitializerField (srcField, linkedField)) - yield return err; - } - } else { - foreach (var index in expectedIndices) { - if (index < 0 || index > possibleInitializerFields.Length) - yield return $"Invalid expected index `{index}` in {src}. Value must be between 0 and {expectedIndices.Length}"; - - var srcField = possibleInitializerFields[index]; - var linkedField = linkedImplementationDetails.Fields.FirstOrDefault (f => f.InitialValue.SequenceEqual (srcField.InitialValue)); - - foreach(var err in VerifyInitializerField (srcField, linkedField)) - yield return err; - } - } - } - - private IEnumerable VerifyInitializerField (FieldDefinition src, FieldDefinition? linked) - { - foreach(var err in VerifyFieldKept (src, linked)) - yield return err; - verifiedGeneratedFields.Add (linked!.FullName); - linkedMembers.Remove (new (linked)); - // foreach(var err in VerifyTypeDefinitionKept (src.FieldType.Resolve (), linked.FieldType.Resolve ())) - // yield return err; - linkedMembers.Remove (new (linked.FieldType.Resolve ())); - linkedMembers.Remove (new (linked.DeclaringType.Resolve ())); - verifiedGeneratedTypes.Add (linked.DeclaringType.FullName); - } + protected virtual IEnumerable VerifyArrayInitializers(MethodDefinition src, MethodDefinition linked) + { + var expectedIndices = GetCustomAttributeCtorValues(src, nameof(KeptInitializerData)) + .Cast() + .ToArray(); + + var expectKeptAll = src.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(KeptInitializerData) && !attr.HasConstructorArguments); + + if (expectedIndices.Length == 0 && !expectKeptAll) + return; + + if (!src.HasBody) + yield return $"`{nameof(KeptInitializerData)}` cannot be used on methods that don't have bodies"; + + var srcImplementationDetails = src.Module.Types.FirstOrDefault(t => string.IsNullOrEmpty(t.Namespace) && t.Name.StartsWith("")); + + if (srcImplementationDetails == null) + { + yield return "Could not locate in the original assembly. Does your test use initializers?"; + return; + } + + var linkedImplementationDetails = linked.Module.Types.FirstOrDefault(t => string.IsNullOrEmpty(t.Namespace) && t.Name.StartsWith("")); + + if (linkedImplementationDetails == null) + { + yield return "Could not locate in the linked assembly"; + return; + } + + var possibleInitializerFields = src.Body.Instructions + .Where(ins => IsLdtokenOnPrivateImplementationDetails(srcImplementationDetails, ins)) + .Select(ins => ((FieldReference)ins.Operand).Resolve()) + .ToArray(); + + if (possibleInitializerFields.Length == 0) + yield return $"`{src}` does not make use of any initializers"; + + if (expectKeptAll) + { + foreach (var srcField in possibleInitializerFields) + { + var linkedField = linkedImplementationDetails.Fields.FirstOrDefault(f => f.InitialValue.SequenceEqual(srcField.InitialValue)); + foreach (var err in VerifyInitializerField(srcField, linkedField)) + yield return err; + } + } + else + { + foreach (var index in expectedIndices) + { + if (index < 0 || index > possibleInitializerFields.Length) + yield return $"Invalid expected index `{index}` in {src}. Value must be between 0 and {expectedIndices.Length}"; + + var srcField = possibleInitializerFields[index]; + var linkedField = linkedImplementationDetails.Fields.FirstOrDefault(f => f.InitialValue.SequenceEqual(srcField.InitialValue)); + + foreach (var err in VerifyInitializerField(srcField, linkedField)) + yield return err; + } + } + } + + private IEnumerable VerifyInitializerField(FieldDefinition src, FieldDefinition? linked) + { + foreach (var err in VerifyFieldKept(src, linked, skipKeptItemsValidation: true)) + yield return err; + verifiedGeneratedFields.Add(linked!.FullName); + linkedMembers.Remove(new(linked)); + // foreach (var err in VerifyTypeDefinitionKept(src.FieldType.Resolve(), linked.FieldType.Resolve())) + // yield return err; + linkedMembers.Remove(new(linked.FieldType.Resolve())); + linkedMembers.Remove(new(linked.DeclaringType.Reolve())); + verifiedGeneratedTypes.Add(linked.DeclaringType.FullName); + } #endif - private static bool IsLdtokenOnPrivateImplementationDetails (TypeDefinition privateImplementationDetails, Instruction instruction) - { - if (instruction.OpCode.Code == Code.Ldtoken && instruction.Operand is FieldReference field) { - return field.DeclaringType.Resolve () == privateImplementationDetails; - } - - return false; - } - - protected static IEnumerable GetExpectedAttributes (ICustomAttributeProvider original) - { - foreach (var expectedAttrs in GetCustomAttributeCtorValues (original, nameof (KeptAttributeAttribute))) - yield return expectedAttrs?.ToString (); - - // The name of the generated fixed buffer type is a little tricky. - // Some versions of csc name it `e__FixedBuffer0` - // while mcs and other versions of csc name it `__FixedBuffer0` - if (original is TypeDefinition srcDefinition && srcDefinition.Name.Contains ("__FixedBuffer")) { - var name = srcDefinition.Name.Substring (1, srcDefinition.Name.IndexOf ('>') - 1); - var fixedField = srcDefinition.DeclaringType.Fields.FirstOrDefault (f => f.Name == name); - if (fixedField == null) - Assert.Fail($"Could not locate original fixed field for {srcDefinition}"); - - foreach (var additionalExpectedAttributesFromFixedField in GetCustomAttributeCtorValues (fixedField!, nameof (KeptAttributeOnFixedBufferTypeAttribute))) - yield return additionalExpectedAttributesFromFixedField?.ToString (); - - } - } - - /// - /// Filters out some attributes that should not be taken into consideration when checking the linked result against the expected result - /// - /// - /// - protected virtual IEnumerable FilterLinkedAttributes (ICustomAttributeProvider linked) - { - foreach (var attr in linked.CustomAttributes) { - switch (attr.AttributeType.FullName) { - case "System.Runtime.CompilerServices.RuntimeCompatibilityAttribute": - case "System.Runtime.CompilerServices.CompilerGeneratedAttribute": - continue; - - // When mcs is used to compile the test cases, backing fields end up with this attribute on them - case "System.Diagnostics.DebuggerBrowsableAttribute": - continue; - - // When compiling with roslyn, assemblies get the DebuggableAttribute by default. - case "System.Diagnostics.DebuggableAttribute": - continue; - - case "System.Runtime.CompilerServices.CompilationRelaxationsAttribute": - if (linked is AssemblyDefinition) - continue; - break; - } - - yield return attr.AttributeType.FullName; - } - } - - protected virtual IEnumerable FilterLinkedSecurityAttributes (ISecurityDeclarationProvider linked) - { - return linked.SecurityDeclarations - .SelectMany (d => d.SecurityAttributes) - .Select (attr => attr.AttributeType.ToString ()); - } + private static bool IsLdtokenOnPrivateImplementationDetails(TypeDefinition privateImplementationDetails, Instruction instruction) + { + if (instruction.OpCode.Code == Code.Ldtoken && instruction.Operand is FieldReference field) + { + return field.DeclaringType.Resolve() == privateImplementationDetails; + } + + return false; + } + + protected static IEnumerable GetExpectedAttributes(ICustomAttributeProvider original) + { + foreach (var expectedAttrs in GetCustomAttributeCtorValues(original, nameof(KeptAttributeAttribute))) + yield return expectedAttrs?.ToString(); + + // The name of the generated fixed buffer type is a little tricky. + // Some versions of csc name it `e__FixedBuffer0` + // while mcs and other versions of csc name it `__FixedBuffer0` + if (original is TypeDefinition srcDefinition && srcDefinition.Name.Contains("__FixedBuffer")) + { + var name = srcDefinition.Name.Substring(1, srcDefinition.Name.IndexOf('>') - 1); + var fixedField = srcDefinition.DeclaringType.Fields.FirstOrDefault(f => f.Name == name); + if (fixedField == null) + Assert.Fail($"Could not locate original fixed field for {srcDefinition}"); + + foreach (var additionalExpectedAttributesFromFixedField in GetCustomAttributeCtorValues(fixedField!, nameof(KeptAttributeOnFixedBufferTypeAttribute))) + yield return additionalExpectedAttributesFromFixedField?.ToString(); + + } + } + + /// + /// Filters out some attributes that should not be taken into consideration when checking the linked result against the expected result + /// + /// + /// + protected virtual IEnumerable FilterLinkedAttributes(ICustomAttributeProvider linked) + { + foreach (var attr in linked.CustomAttributes) + { + switch (attr.AttributeType.FullName) + { + case "System.Runtime.CompilerServices.RuntimeCompatibilityAttribute": + case "System.Runtime.CompilerServices.CompilerGeneratedAttribute": + continue; + + // When mcs is used to compile the test cases, backing fields end up with this attribute on them + case "System.Diagnostics.DebuggerBrowsableAttribute": + continue; + + // When compiling with roslyn, assemblies get the DebuggableAttribute by default. + case "System.Diagnostics.DebuggableAttribute": + continue; + + case "System.Runtime.CompilerServices.CompilationRelaxationsAttribute": + if (linked is AssemblyDefinition) + continue; + break; + } + + yield return attr.AttributeType.FullName; + } + } + + protected virtual IEnumerable FilterLinkedSecurityAttributes(ISecurityDeclarationProvider linked) + { + return linked.SecurityDeclarations + .SelectMany(d => d.SecurityAttributes) + .Select(attr => attr.AttributeType.ToString()); + } #if false - private IEnumerable VerifyFixedBufferFields (TypeDefinition src, TypeDefinition linked) - { - var fields = src.Fields.Where (f => f.CustomAttributes.Any (attr => attr.AttributeType.Name == nameof (KeptFixedBufferAttribute))); - - foreach (var field in fields) { - // The name of the generated fixed buffer type is a little tricky. - // Some versions of csc name it `e__FixedBuffer0` - // while mcs and other versions of csc name it `__FixedBuffer0` - var originalCompilerGeneratedBufferType = src.NestedTypes.FirstOrDefault (t => t.FullName.Contains ($"<{field.Name}>") && t.FullName.Contains ("__FixedBuffer")); - if (originalCompilerGeneratedBufferType == null) { - yield return $"Could not locate original compiler generated fixed buffer type for field {field}"; - yield break; - } - - var linkedCompilerGeneratedBufferType = linked.NestedTypes.FirstOrDefault (t => t.Name == originalCompilerGeneratedBufferType.Name); - if (linkedCompilerGeneratedBufferType == null) { - yield return $"Missing expected type {originalCompilerGeneratedBufferType}"; - yield break; - } - - // Have to verify the field before the type - var originalElementField = originalCompilerGeneratedBufferType.Fields.FirstOrDefault (); - if (originalElementField == null) { - yield return $"Could not locate original compiler generated FixedElementField on {originalCompilerGeneratedBufferType}"; - yield break; - } - - var linkedField = linkedCompilerGeneratedBufferType?.Fields.FirstOrDefault (); - foreach(var err in VerifyFieldKept (originalElementField, linkedField)) - yield return err; - verifiedGeneratedFields.Add (originalElementField.FullName); - linkedMembers.Remove (new (linkedField!)); - - // foreach(var err in VerifyTypeDefinitionKept (originalCompilerGeneratedBufferType, linkedCompilerGeneratedBufferType)) - // yield return err; - verifiedGeneratedTypes.Add (originalCompilerGeneratedBufferType.FullName); - } - } - - private IEnumerable VerifyDelegateBackingFields (TypeDefinition src, TypeDefinition linked) - { - var expectedFieldNames = GetCustomAttributeCtorValues (src, nameof (KeptDelegateCacheFieldAttribute)) - .Select (unique => $"<>f__mg$cache{unique}") - .ToList (); - - if (expectedFieldNames.Count == 0) - yield break; - - foreach (var srcField in src.Fields) { - if (!expectedFieldNames.Contains (srcField.Name)) - continue; - - var linkedField = linked?.Fields.FirstOrDefault (l => l.Name == srcField.Name); - foreach(var err in VerifyFieldKept (srcField, linkedField)) - yield return err; - verifiedGeneratedFields.Add (srcField.FullName); - linkedMembers.Remove (new (srcField)); - } - } + private IEnumerable VerifyFixedBufferFields(TypeDefinition src, TypeDefinition linked) + { + var fields = src.Fields.Where(f => f.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(KeptFixedBufferAttribute))); + + foreach (var field in fields) + { + // The name of the generated fixed buffer type is a little tricky. + // Some versions of csc name it `e__FixedBuffer0` + // while mcs and other versions of csc name it `__FixedBuffer0` + var originalCompilerGeneratedBufferType = src.NestedTypes.FirstOrDefault(t => t.FullName.Contains($"<{field.Name}>") && t.FullName.Contains("__FixedBuffer")); + if (originalCompilerGeneratedBufferType == null) + { + yield return $"Could not locate original compiler generated fixed buffer type for field {field}"; + yield break; + } + + var linkedCompilerGeneratedBufferType = linked.NestedTypes.FirstOrDefault(t => t.Name == originalCompilerGeneratedBufferType.Name); + if (linkedCompilerGeneratedBufferType == null) + { + yield return $"Missing expected type {originalCompilerGeneratedBufferType}"; + yield break; + } + + // Have to verify the field before the type + var originalElementField = originalCompilerGeneratedBufferType.Fields.FirstOrDefault(); + if (originalElementField == null) + { + yield return $"Could not locate original compiler generated FixedElementField on {originalCompilerGeneratedBufferType}"; + yield break; + } + + var linkedField = linkedCompilerGeneratedBufferType?.Fields.FirstOrDefault(); + foreach (var err in VerifyFieldKept(originalElementField, linkedField, skipKeptItemsValidation: true)) + yield return err; + verifiedGeneratedFields.Add(originalElementField.FullName); + linkedMembers.Remove(new(linkedField!)); + + // foreach (var err in VerifyTypeDefinitionKept(originalCompilerGeneratedBufferType, linkedCompilerGeneratedBufferType)) + // yield return err; + verifiedGeneratedTypes.Add(originalCompilerGeneratedBufferType.FullName); + } + } + + private IEnumerable VerifyDelegateBackingFields(TypeDefinition src, TypeDefinition linked) + { + var expectedFieldNames = GetCustomAttributeCtorValues(src, nameof(KeptDelegateCacheFieldAttribute)) + .Select(unique => $"<>f__mg$cache{unique}") + .ToList(); + + if (expectedFieldNames.Count == 0) + yield break; + + foreach (var srcField in src.Fields) { + if (!expectedFieldNames.Contains(srcField.Name)) + continue; + + var linkedField = linked?.Fields.FirstOrDefault(l => l.Name == srcField.Name); + foreach (var err in VerifyFieldKept(srcField, linkedField, skipKeptItemsValidation: true)) + yield return err; + verifiedGeneratedFields.Add(srcField.FullName); + linkedMembers.Remove(new(srcField)); + } + } #endif - private IEnumerable VerifyGenericParameters (IGenericParameterProvider src, IGenericParameterProvider linked) - { - if (src.HasGenericParameters != linked.HasGenericParameters) - yield return $"Mismatch in having generic paramters. Expected {src.HasGenericParameters}, actual {linked.HasGenericParameters}"; - - if (src.HasGenericParameters) { - for (int i = 0; i < src.GenericParameters.Count; ++i) { - // TODO: Verify constraints - var srcp = src.GenericParameters[i]; - var lnkp = linked.GenericParameters[i]; - foreach(var err in VerifyCustomAttributes (srcp, lnkp)) - yield return err; - - if (checkNames) { - if (srcp.CustomAttributes.Any (attr => attr.AttributeType.Name == nameof (RemovedNameValueAttribute))) { - string name = (src.GenericParameterType == GenericParameterType.Method ? "!!" : "!") + srcp.Position; - if (lnkp.Name != name) - yield return "Expected empty generic parameter name"; - } else { - if (lnkp.Name != srcp.Name) - yield return "Mismatch in generic parameter name"; - } - } - } - } - } - - private IEnumerable VerifyParameters (IMethodSignature src, LinkedMethodEntity linked) - { - if (src.HasParameters != linked.Method.Signature.Length > 0) - yield return $"Mismatch in having parameters in {src as MethodDefinition}: Expected {src.HasParameters}, actual {linked.Method.Signature.Length > 0}"; - if (src.HasParameters) { - for (int i = 0; i < src.Parameters.Count; ++i) { - var srcp = src.Parameters[i]; - //var lnkp = linked.Parameters[i]; + private IEnumerable VerifyGenericParameters(IGenericParameterProvider src, IGenericParameterProvider linked, bool skipKeptItemsValidation) + { + if (src.HasGenericParameters != linked.HasGenericParameters) + yield return $"Mismatch in having generic paramters. Expected {src.HasGenericParameters}, actual {linked.HasGenericParameters}"; + + if (src.HasGenericParameters) + { + for (int i = 0; i < src.GenericParameters.Count; ++i) + { + // TODO: Verify constraints + var srcp = src.GenericParameters[i]; + var lnkp = linked.GenericParameters[i]; + + if (!skipKeptItemsValidation) + { + foreach (var err in VerifyCustomAttributes(srcp, lnkp)) + yield return err; + } + + if (checkNames) + { + if (srcp.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(RemovedNameValueAttribute))) + { + string name = (src.GenericParameterType == GenericParameterType.Method ? "!!" : "!") + srcp.Position; + if (lnkp.Name != name) + yield return "Expected empty generic parameter name"; + } + else + { + if (lnkp.Name != srcp.Name) + yield return "Mismatch in generic parameter name"; + } + } + } + } + } + + private IEnumerable VerifyParameters(IMethodSignature src, LinkedMethodEntity linked, bool skipKeptItemsValidation) + { + if (src.HasParameters != linked.Method.Signature.Length > 0) + yield return $"Mismatch in having parameters in {src as MethodDefinition}: Expected {src.HasParameters}, actual {linked.Method.Signature.Length > 0}"; + if (src.HasParameters) + { + for (int i = 0; i < src.Parameters.Count; ++i) + { + var srcp = src.Parameters[i]; + //var lnkp = linked.Parameters[i]; #if false - foreach(var err in VerifyCustomAttributes (srcp, lnkp)) - yield return err; + if (!skipKeptItemsValidation) + { + foreach (var err in VerifyCustomAttributes(srcp, lnkp)) + yield return err; + } #endif - if (checkNames) { - if (srcp.CustomAttributes.Any (attr => attr.AttributeType.Name == nameof (RemovedNameValueAttribute))) - { - if (linked.IsReflected != false) - yield return $"Expected no parameter name (non-reflectable). Parameter {i} of {src as MethodDefinition}"; - } - else - { - if (linked.IsReflected != true) - yield return $"Expected accessible parameter name (reflectable). Parameter {i} of {(src as MethodDefinition)}"; - } - } - } - } - } - - protected virtual bool ShouldMethodBeKept (MethodDefinition method) - { - var srcSignature = method.GetSignature (); - return ShouldBeKept (method, srcSignature) || method.DeclaringType.Module.EntryPoint == method; - } - - protected virtual bool ShouldBeKept (T member, string? signature = null) where T : MemberReference, ICustomAttributeProvider - { - if (HasActiveKeptAttribute (member)) - return true; - - ICustomAttributeProvider cap = (ICustomAttributeProvider) member.DeclaringType; - if (cap == null) - return false; - - return GetActiveKeptAttributes (cap, nameof (KeptMemberAttribute)).Any (ca => { - if (ca.Constructor.Parameters.Count != 1 || - ca.ConstructorArguments[0].Value is not string a) - return false; - - return a == (signature ?? member.Name); - }); - } - - protected static uint GetExpectedPseudoAttributeValue (ICustomAttributeProvider provider, uint sourceValue) - { - var removals = provider.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (RemovedPseudoAttributeAttribute)).ToArray (); - var adds = provider.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (AddedPseudoAttributeAttribute)).ToArray (); - - return removals.Aggregate (sourceValue, (accum, item) => accum & ~(uint) item.ConstructorArguments[0].Value) | - adds.Aggregate ((uint) 0, (acum, item) => acum | (uint) item.ConstructorArguments[0].Value); - } - - protected static IEnumerable GetCustomAttributeCtorValues (ICustomAttributeProvider provider, string attributeName) where T : class - { - return provider.CustomAttributes. - Where (w => w.AttributeType.Name == attributeName && w.Constructor.Parameters.Count == 1). - Select (l => l.ConstructorArguments[0].Value as T); - } - - protected static IEnumerable GetStringOrTypeArrayAttributeValue (CustomAttribute attribute) - { - foreach (var arg in (CustomAttributeArgument[]) attribute.ConstructorArguments[0].Value) { - if (arg.Value is TypeReference tRef) - yield return tRef.ToString (); - else - yield return (string) arg.Value; - } - } - - protected static IEnumerable? GetStringArrayAttributeValue (CustomAttribute attribute) - { - return ((CustomAttributeArgument[]) attribute.ConstructorArguments[0].Value)?.Select (arg => arg.Value.ToString ()!); - } - - private static IEnumerable GetActiveKeptAttributes (ICustomAttributeProvider provider, string attributeName) - { - return provider.CustomAttributes.Where (ca => { - if (ca.AttributeType.Name != attributeName) { - return false; - } - - object? keptBy = ca.GetPropertyValue (nameof (KeptAttribute.By)); - return keptBy is null ? true : ((Tool) keptBy).HasFlag (Tool.NativeAot); - }); - } - - private static bool HasActiveKeptAttribute (ICustomAttributeProvider provider) - { - return GetActiveKeptAttributes (provider, nameof (KeptAttribute)).Any (); - } - - private static IEnumerable GetActiveKeptDerivedAttributes (ICustomAttributeProvider provider) - { - return provider.CustomAttributes.Where (ca => { - if (!ca.AttributeType.Resolve ().DerivesFrom (nameof (KeptAttribute))) { - return false; - } - - object? keptBy = ca.GetPropertyValue (nameof (KeptAttribute.By)); - return keptBy is null ? true : ((Tool) keptBy).HasFlag (Tool.NativeAot); - }); - } - - - private static bool HasActiveKeptDerivedAttribute (ICustomAttributeProvider provider) - { - return GetActiveKeptDerivedAttributes (provider).Any (); - } - - internal IEnumerable VerifyLinkingOfOtherAssemblies (AssemblyDefinition original) - { - var checks = BuildOtherAssemblyCheckTable (original); - List errs = []; - - try { - foreach (var assemblyName in checks.Keys) { - var linkedMembersInAssembly = ResolveLinkedMembersForAssembly (assemblyName); - var originalTargetAssembly = ResolveOriginalsAssembly(assemblyName); - foreach (var checkAttrInAssembly in checks[assemblyName]) { - var attributeTypeName = checkAttrInAssembly.AttributeType.Name; - - switch (attributeTypeName) { - case nameof (KeptAllTypesAndMembersInAssemblyAttribute): - errs.AddRange(VerifyKeptAllTypesAndMembersInAssembly (assemblyName, linkedMembersInAssembly)); - continue; - case nameof (KeptAttributeInAssemblyAttribute): - // errs.AddRange(VerifyKeptAttributeInAssembly (checkAttrInAssembly, linkedAssembly)) - continue; - case nameof (RemovedAttributeInAssembly): - // errs.AddRange(VerifyRemovedAttributeInAssembly (checkAttrInAssembly, linkedAssembly)) - continue; - default: - break; - } - - var expectedTypeName = checkAttrInAssembly.ConstructorArguments[1].Value.ToString ()!; - if (!originalsTypeNameResolver.TryResolveTypeName (originalTargetAssembly, expectedTypeName, out TypeReference? expectedTypeRef, out _)) - Assert.Fail($"Could not resolve original type `{expectedTypeName}' in assembly {assemblyName}"); - TypeDefinition expectedType = expectedTypeRef.Resolve (); - linkedMembersInAssembly.TryGetValue(new AssemblyQualifiedToken(expectedType), out LinkedEntity? linkedTypeEntity); - MetadataType? linkedType = linkedTypeEntity?.Entity as MetadataType; + if (checkNames) + { + if (srcp.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(RemovedNameValueAttribute))) + { + if (linked.IsReflected != false) + yield return $"Expected no parameter name (non-reflectable). Parameter {i} of {src as MethodDefinition}"; + } + else + { + if (linked.IsReflected != true) + yield return $"Expected accessible parameter name (reflectable). Parameter {i} of {(src as MethodDefinition)}"; + } + } + } + } + } + + protected virtual bool ShouldMethodBeKept(MethodDefinition method) + { + var srcSignature = method.GetSignature(); + return ShouldBeKept(method, srcSignature) || method.DeclaringType.Module.EntryPoint == method; + } + + protected virtual bool ShouldBeKept(T member, string? signature = null) where T : MemberReference, ICustomAttributeProvider + { + if (HasActiveKeptAttribute(member)) + return true; + + ICustomAttributeProvider cap = (ICustomAttributeProvider)member.DeclaringType; + if (cap == null) + return false; + + return GetActiveKeptAttributes(cap, nameof(KeptMemberAttribute)).Any(ca => + { + if (ca.Constructor.Parameters.Count != 1 || + ca.ConstructorArguments[0].Value is not string a) + return false; + + return a == (signature ?? member.Name); + }); + } + + protected static uint GetExpectedPseudoAttributeValue(ICustomAttributeProvider provider, uint sourceValue) + { + var removals = provider.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(RemovedPseudoAttributeAttribute)).ToArray(); + var adds = provider.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(AddedPseudoAttributeAttribute)).ToArray(); + + return removals.Aggregate(sourceValue, (accum, item) => accum & ~(uint)item.ConstructorArguments[0].Value) | + adds.Aggregate((uint)0, (acum, item) => acum | (uint)item.ConstructorArguments[0].Value); + } + + protected static IEnumerable GetCustomAttributeCtorValues(ICustomAttributeProvider provider, string attributeName) where T : class + { + return provider.CustomAttributes. + Where(w => w.AttributeType.Name == attributeName && w.Constructor.Parameters.Count == 1). + Select(l => l.ConstructorArguments[0].Value as T); + } + + protected static IEnumerable GetStringOrTypeArrayAttributeValue(CustomAttribute attribute) + { + foreach (var arg in (CustomAttributeArgument[])attribute.ConstructorArguments[0].Value) + { + if (arg.Value is TypeReference tRef) + yield return tRef.ToString(); + else + yield return (string)arg.Value; + } + } + + protected static IEnumerable? GetStringArrayAttributeValue(CustomAttribute attribute) + { + return ((CustomAttributeArgument[])attribute.ConstructorArguments[0].Value)?.Select(arg => arg.Value.ToString()!); + } + + private static IEnumerable GetActiveKeptAttributes(ICustomAttributeProvider provider, string attributeName) + { + return provider.CustomAttributes.Where(ca => + { + if (ca.AttributeType.Name != attributeName) + { + return false; + } + + object? keptBy = ca.GetPropertyValue(nameof(KeptAttribute.By)); + return keptBy is null ? true : ((Tool)keptBy).HasFlag(Tool.NativeAot); + }); + } + + private static bool HasActiveKeptAttribute(ICustomAttributeProvider provider) + { + return GetActiveKeptAttributes(provider, nameof(KeptAttribute)).Any(); + } + + private static IEnumerable GetActiveKeptDerivedAttributes(ICustomAttributeProvider provider) + { + return provider.CustomAttributes.Where(ca => + { + if (!ca.AttributeType.Resolve().DerivesFrom(nameof(KeptAttribute))) + { + return false; + } + + object? keptBy = ca.GetPropertyValue(nameof(KeptAttribute.By)); + return keptBy is null ? true : ((Tool)keptBy).HasFlag(Tool.NativeAot); + }); + } + + + private static bool HasActiveKeptDerivedAttribute(ICustomAttributeProvider provider) + { + return GetActiveKeptDerivedAttributes(provider).Any(); + } + + internal IEnumerable VerifyLinkingOfOtherAssemblies(AssemblyDefinition original) + { + var checks = BuildOtherAssemblyCheckTable(original); + List errs = []; + + try + { + foreach (var assemblyName in checks.Keys) + { + var linkedMembersInAssembly = ResolveLinkedMembersForAssembly(assemblyName); + var originalTargetAssembly = ResolveOriginalsAssembly(assemblyName); + foreach (var checkAttrInAssembly in checks[assemblyName]) + { + var attributeTypeName = checkAttrInAssembly.AttributeType.Name; + + switch (attributeTypeName) + { + case nameof(KeptAllTypesAndMembersInAssemblyAttribute): + errs.AddRange(VerifyKeptAllTypesAndMembersInAssembly(assemblyName, linkedMembersInAssembly)); + continue; + case nameof(KeptAttributeInAssemblyAttribute): + // errs.AddRange(VerifyKeptAttributeInAssembly(checkAttrInAssembly, linkedAssembly)) + continue; + case nameof(RemovedAttributeInAssembly): + // errs.AddRange(VerifyRemovedAttributeInAssembly(checkAttrInAssembly, linkedAssembly)) + continue; + default: + break; + } + + var expectedTypeName = checkAttrInAssembly.ConstructorArguments[1].Value.ToString()!; + if (!originalsTypeNameResolver.TryResolveTypeName(originalTargetAssembly, expectedTypeName, out TypeReference? expectedTypeRef, out _)) + Assert.Fail($"Could not resolve original type `{expectedTypeName}' in assembly {assemblyName}"); + TypeDefinition expectedType = expectedTypeRef.Resolve(); + linkedMembersInAssembly.TryGetValue(new AssemblyQualifiedToken(expectedType), out LinkedEntity? linkedTypeEntity); + MetadataType? linkedType = linkedTypeEntity?.Entity as MetadataType; #if false - if (linkedType == null && linkedAssembly.MainModule.HasExportedTypes) { - ExportedType? exportedType = linkedAssembly.MainModule.ExportedTypes - .FirstOrDefault (exported => exported.FullName == expectedTypeName); - - // Note that copied assemblies could have dangling references. - if (exportedType != null && original.EntryPoint.DeclaringType.CustomAttributes.FirstOrDefault ( - ca => ca.AttributeType.Name == nameof (RemovedAssemblyAttribute) - && ca.ConstructorArguments[0].Value.ToString () == exportedType.Scope.Name + ".dll") != null) - continue; - - linkedType = exportedType?.Resolve (); - } + if (linkedType == null && linkedAssembly.MainModule.HasExportedTypes) { + ExportedType? exportedType = linkedAssembly.MainModule.ExportedTypes + .FirstOrDefault(exported => exported.FullName == expectedTypeName); + + // Note that copied assemblies could have dangling references. + if (exportedType != null && original.EntryPoint.DeclaringType.CustomAttributes.FirstOrDefault( + ca => ca.AttributeType.Name == nameof(RemovedAssemblyAttribute) + && ca.ConstructorArguments[0].Value.ToString() == exportedType.Scope.Name + ".dll") != null) + continue; + + linkedType = exportedType?.Resolve(); + } #endif - switch (attributeTypeName) { - case nameof (RemovedTypeInAssemblyAttribute): - if (linkedType != null) - errs.Add($"Type `{expectedTypeName}' should have been removed from assembly {assemblyName}"); - GetOriginalTypeFromInAssemblyAttribute (checkAttrInAssembly); - break; - case nameof (KeptTypeInAssemblyAttribute): - if (linkedType == null) - errs.Add($"Type `{expectedTypeName}' should have been kept in assembly {assemblyName}"); - break; + switch (attributeTypeName) + { + case nameof(RemovedTypeInAssemblyAttribute): + if (linkedType != null) + errs.Add($"Type `{expectedTypeName}' should have been removed from assembly {assemblyName}"); + GetOriginalTypeFromInAssemblyAttribute(checkAttrInAssembly); + break; + case nameof(KeptTypeInAssemblyAttribute): + if (linkedType == null) + errs.Add($"Type `{expectedTypeName}' should have been kept in assembly {assemblyName}"); + break; #if false - case nameof (RemovedInterfaceOnTypeInAssemblyAttribute): - if (linkedType == null) - { - errs.Add($"Type `{expectedTypeName}' should have been kept in assembly {assemblyName}"); - break; - } - errs.AddRange(VerifyRemovedInterfaceOnTypeInAssembly (checkAttrInAssembly, linkedType)); - break; - case nameof (KeptInterfaceOnTypeInAssemblyAttribute): - if (linkedType == null) - { - errs.Add($"Type `{expectedTypeName}' should have been kept in assembly {assemblyName}"); - break; - } - errs.AddRange(VerifyKeptInterfaceOnTypeInAssembly (checkAttrInAssembly, linkedType)); - break; - case nameof (RemovedMemberInAssemblyAttribute): - if (linkedType == null) - continue; - - errs.AddRange(VerifyRemovedMemberInAssembly (checkAttrInAssembly, linkedType)); - break; - case nameof (KeptBaseOnTypeInAssemblyAttribute): - if (linkedType == null) - { - errs.Add($"Type `{expectedTypeName}' should have been kept in assembly {assemblyName}"); - break; - } - errs.AddRange(VerifyKeptBaseOnTypeInAssembly (checkAttrInAssembly, linkedType)); - break; - case nameof (KeptMemberInAssemblyAttribute): - if (linkedType == null) - { - errs.Add($"Type `{expectedTypeName}' should have been kept in assembly {assemblyName}"); - break; - } - - errs.AddRange(VerifyKeptMemberInAssembly (checkAttrInAssembly, linkedType)); - break; - case nameof (RemovedForwarderAttribute): - if (linkedAssembly.MainModule.ExportedTypes.Any (l => l.Name == expectedTypeName)) - errs.Add($"Forwarder `{expectedTypeName}' should have been removed from assembly {assemblyName}"); - - break; - - case nameof (RemovedAssemblyReferenceAttribute): - if (linkedAssembly.MainModule.AssemblyReferences.Any (l => l.Name == expectedTypeName) != false) - errs.Add($"AssemblyRef '{expectedTypeName}' should have been removed from assembly {assemblyName}"); - break; - - case nameof (KeptResourceInAssemblyAttribute): - errs.AddRange(VerifyKeptResourceInAssembly (checkAttrInAssembly)); - break; - case nameof (RemovedResourceInAssemblyAttribute): - errs.AddRange(VerifyRemovedResourceInAssembly (checkAttrInAssembly)); - break; - case nameof (KeptReferencesInAssemblyAttribute): - errs.AddRange(VerifyKeptReferencesInAssembly (checkAttrInAssembly)) - break; - case nameof (ExpectedInstructionSequenceOnMemberInAssemblyAttribute): - if (linkedType == null) - { - errs.Add($"Type `{expectedTypeName}` should have been kept in assembly {assemblyName}"); - break; - } - errs.AddRange(VerifyExpectedInstructionSequenceOnMemberInAssembly (checkAttrInAssembly, linkedType)); - break; - default: - UnhandledOtherAssemblyAssertion (expectedTypeName, checkAttrInAssembly, linkedType); - break; + case nameof(RemovedInterfaceOnTypeInAssemblyAttribute): + if (linkedType == null) + { + errs.Add($"Type `{expectedTypeName}' should have been kept in assembly {assemblyName}"); + break; + } + errs.AddRange(VerifyRemovedInterfaceOnTypeInAssembly(checkAttrInAssembly, linkedType)); + break; + case nameof(KeptInterfaceOnTypeInAssemblyAttribute): + if (linkedType == null) + { + errs.Add($"Type `{expectedTypeName}' should have been kept in assembly {assemblyName}"); + break; + } + errs.AddRange(VerifyKeptInterfaceOnTypeInAssembly(checkAttrInAssembly, linkedType)); + break; + case nameof(RemovedMemberInAssemblyAttribute): + if (linkedType == null) + continue; + + errs.AddRange(VerifyRemovedMemberInAssembly(checkAttrInAssembly, linkedType)); + break; + case nameof(KeptBaseOnTypeInAssemblyAttribute): + if (linkedType == null) + { + errs.Add($"Type `{expectedTypeName}' should have been kept in assembly {assemblyName}"); + break; + } + errs.AddRange(VerifyKeptBaseOnTypeInAssembly(checkAttrInAssembly, linkedType)); + break; + case nameof(KeptMemberInAssemblyAttribute): + if (linkedType == null) + { + errs.Add($"Type `{expectedTypeName}' should have been kept in assembly {assemblyName}"); + break; + } + + errs.AddRange(VerifyKeptMemberInAssembly(checkAttrInAssembly, linkedType)); + break; + case nameof(RemovedForwarderAttribute): + if (linkedAssembly.MainModule.ExportedTypes.Any(l => l.Name == expectedTypeName)) + errs.Add($"Forwarder `{expectedTypeName}' should have been removed from assembly {assemblyName}"); + + break; + + case nameof(RemovedAssemblyReferenceAttribute): + if (linkedAssembly.MainModule.AssemblyReferences.Any(l => l.Name == expectedTypeName) != false) + errs.Add($"AssemblyRef '{expectedTypeName}' should have been removed from assembly {assemblyName}"); + break; + + case nameof(KeptResourceInAssemblyAttribute): + errs.AddRange(VerifyKeptResourceInAssembly(checkAttrInAssembly)); + break; + case nameof(RemovedResourceInAssemblyAttribute): + errs.AddRange(VerifyRemovedResourceInAssembly(checkAttrInAssembly)); + break; + case nameof(KeptReferencesInAssemblyAttribute): + errs.AddRange(VerifyKeptReferencesInAssembly(checkAttrInAssembly)) + break; + case nameof(ExpectedInstructionSequenceOnMemberInAssemblyAttribute): + if (linkedType == null) + { + errs.Add($"Type `{expectedTypeName}` should have been kept in assembly {assemblyName}"); + break; + } + errs.AddRange(VerifyExpectedInstructionSequenceOnMemberInAssembly checkAttrInAssembly, linkedType)); + break; + default: + UnhandledOtherAssemblyAssertion(expectedTypeName, checkAttrInAssembly, linkedType); + break; #else - default: - break; + default: + break; #endif - } - } - } - } catch (AssemblyResolutionException e) { - errs.Add($"Failed to resolve linked assembly `{e.AssemblyReference.Name}`. It must not exist in the output."); - } - return errs; - } - - private IEnumerable VerifyKeptAttributeInAssembly (CustomAttribute inAssemblyAttribute, AssemblyDefinition linkedAssembly) - { - return VerifyAttributeInAssembly (inAssemblyAttribute, linkedAssembly, VerifyCustomAttributeKept); - } - - private IEnumerable VerifyRemovedAttributeInAssembly (CustomAttribute inAssemblyAttribute, AssemblyDefinition linkedAssembly) - { - return VerifyAttributeInAssembly (inAssemblyAttribute, linkedAssembly, VerifyCustomAttributeRemoved); - } - - private IEnumerable VerifyAttributeInAssembly (CustomAttribute inAssemblyAttribute, AssemblyDefinition linkedAssembly, Func> assertExpectedAttribute) - { - var assemblyName = (string) inAssemblyAttribute.ConstructorArguments[0].Value!; - string expectedAttributeTypeName; - var attributeTypeOrTypeName = inAssemblyAttribute.ConstructorArguments[1].Value!; - if (attributeTypeOrTypeName is TypeReference typeReference) { - expectedAttributeTypeName = typeReference.FullName; - } else { - expectedAttributeTypeName = attributeTypeOrTypeName.ToString ()!; - } - - if (inAssemblyAttribute.ConstructorArguments.Count == 2) { - // Assembly - foreach(var err in assertExpectedAttribute (linkedAssembly, expectedAttributeTypeName)) - yield return err; - yield break; - } - - // We are asserting on type or member - var typeOrTypeName = inAssemblyAttribute.ConstructorArguments[2].Value; - var originalType = GetOriginalTypeFromInAssemblyAttribute (inAssemblyAttribute.ConstructorArguments[0].Value.ToString ()!, typeOrTypeName); - if (originalType == null) - { - yield return $"Invalid test assertion. The original `{assemblyName}` does not contain a type `{typeOrTypeName}`"; - yield break; - } - - var linkedType = linkedAssembly.MainModule.GetType (originalType.FullName); - if (linkedType == null) - { - yield return $"Missing expected type `{typeOrTypeName}` in `{assemblyName}`"; - yield break; - } - - if (inAssemblyAttribute.ConstructorArguments.Count == 3) { - assertExpectedAttribute (linkedType, expectedAttributeTypeName); - yield break; - } - - // we are asserting on a member - string memberName = (string) inAssemblyAttribute.ConstructorArguments[3].Value; - - // We will find the matching type from the original assembly first that way we can confirm - // that the name defined in the attribute corresponds to a member that actually existed - var originalFieldMember = originalType.Fields.FirstOrDefault (m => m.Name == memberName); - if (originalFieldMember != null) { - var linkedField = linkedType.Fields.FirstOrDefault (m => m.Name == memberName); - if (linkedField == null) - { - yield return $"Field `{memberName}` on Type `{originalType}` should have been kept"; - yield break; - } - - assertExpectedAttribute (linkedField, expectedAttributeTypeName); - yield break; - } - - var originalPropertyMember = originalType.Properties.FirstOrDefault (m => m.Name == memberName); - if (originalPropertyMember != null) { - var linkedProperty = linkedType.Properties.FirstOrDefault (m => m.Name == memberName); - if (linkedProperty == null) - { - yield return $"Property `{memberName}` on Type `{originalType}` should have been kept"; - yield break; - } - - foreach(var err in assertExpectedAttribute (linkedProperty, expectedAttributeTypeName)) - yield return err; - yield break; - } - - var originalMethodMember = originalType.Methods.FirstOrDefault (m => m.GetSignature () == memberName); - if (originalMethodMember != null) { - var linkedMethod = linkedType.Methods.FirstOrDefault (m => m.GetSignature () == memberName); - if (linkedMethod == null) - { - yield return $"Method `{memberName}` on Type `{originalType}` should have been kept"; - yield break; - } - - assertExpectedAttribute (linkedMethod, expectedAttributeTypeName); - yield break; - } - - yield return $"Invalid test assertion. No member named `{memberName}` exists on the original type `{originalType}`"; - } - - private static IEnumerable VerifyCopyAssemblyIsKeptUnmodified (NPath outputDirectory, string assemblyName) - { - string inputAssemblyPath = Path.Combine (Directory.GetParent (outputDirectory)!.ToString (), "input", assemblyName); - string outputAssemblyPath = Path.Combine (outputDirectory, assemblyName); - if (true != File.ReadAllBytes (inputAssemblyPath).SequenceEqual (File.ReadAllBytes (outputAssemblyPath))) - yield return $"Expected assemblies\n" + - $"\t{inputAssemblyPath}\n" + - $"\t{outputAssemblyPath}\n" + - $"binaries to be equal, since the input assembly has copy action."; - } - - private IEnumerable VerifyCustomAttributeKept (ICustomAttributeProvider provider, string expectedAttributeTypeName) - { - var match = provider.CustomAttributes.FirstOrDefault (attr => attr.AttributeType.FullName == expectedAttributeTypeName); - if (match == null) - yield return $"Expected `{provider}` to have an attribute of type `{expectedAttributeTypeName}`"; - } - - private IEnumerable VerifyCustomAttributeRemoved (ICustomAttributeProvider provider, string expectedAttributeTypeName) - { - var match = provider.CustomAttributes.FirstOrDefault (attr => attr.AttributeType.FullName == expectedAttributeTypeName); - if (match != null) - yield return $"Expected `{provider}` to no longer have an attribute of type `{expectedAttributeTypeName}`"; - } - - private IEnumerable VerifyRemovedInterfaceOnTypeInAssembly (CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) - { - var originalType = GetOriginalTypeFromInAssemblyAttribute (inAssemblyAttribute); - - var interfaceAssemblyName = inAssemblyAttribute.ConstructorArguments[2].Value.ToString ()!; - var interfaceType = inAssemblyAttribute.ConstructorArguments[3].Value; - - var originalInterface = GetOriginalTypeFromInAssemblyAttribute (interfaceAssemblyName, interfaceType); - if (!originalType.HasInterfaces) - yield return "Invalid assertion. Original type does not have any interfaces"; - - var originalInterfaceImpl = GetMatchingInterfaceImplementationOnType (originalType, originalInterface.FullName); - if (originalInterfaceImpl == null) - yield return $"Invalid assertion. Original type never had an interface of type `{originalInterface}`"; - - var linkedInterfaceImpl = GetMatchingInterfaceImplementationOnType (linkedType, originalInterface.FullName); - if (linkedInterfaceImpl != null) - yield return $"Expected `{linkedType}` to no longer have an interface of type {originalInterface.FullName}"; - } - - private IEnumerable VerifyKeptInterfaceOnTypeInAssembly (CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) - { - var originalType = GetOriginalTypeFromInAssemblyAttribute (inAssemblyAttribute); - - var interfaceAssemblyName = inAssemblyAttribute.ConstructorArguments[2].Value.ToString ()!; - var interfaceType = inAssemblyAttribute.ConstructorArguments[3].Value; - - var originalInterface = GetOriginalTypeFromInAssemblyAttribute (interfaceAssemblyName, interfaceType); - if (!originalType.HasInterfaces) - yield return "Invalid assertion. Original type does not have any interfaces"; - - var originalInterfaceImpl = GetMatchingInterfaceImplementationOnType (originalType, originalInterface.FullName); - if (originalInterfaceImpl == null) - yield return $"Invalid assertion. Original type never had an interface of type `{originalInterface}`"; - - var linkedInterfaceImpl = GetMatchingInterfaceImplementationOnType (linkedType, originalInterface.FullName); - if (linkedInterfaceImpl == null) - yield return $"Expected `{linkedType}` to have interface of type {originalInterface.FullName}"; - } - - private IEnumerable VerifyKeptBaseOnTypeInAssembly (CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) - { - var originalType = GetOriginalTypeFromInAssemblyAttribute (inAssemblyAttribute); - - var baseAssemblyName = inAssemblyAttribute.ConstructorArguments[2].Value.ToString ()!; - var baseType = inAssemblyAttribute.ConstructorArguments[3].Value; - - var originalBase = GetOriginalTypeFromInAssemblyAttribute (baseAssemblyName, baseType); - if (originalType.BaseType.Resolve () != originalBase) - yield return "Invalid assertion. Original type's base does not match the expected base"; - - if (originalBase.FullName != linkedType.BaseType.FullName) - yield return $"Incorrect base on `{linkedType.FullName}`. Expected `{originalBase.FullName}` but was `{linkedType.BaseType.FullName}`"; - } - - private static InterfaceImplementation? GetMatchingInterfaceImplementationOnType (TypeDefinition type, string expectedInterfaceTypeName) - { - return type.Interfaces.FirstOrDefault (impl => { - var resolvedImpl = impl.InterfaceType.Resolve (); - - if (resolvedImpl == null) - Assert.Fail ($"Failed to resolve interface : `{impl.InterfaceType}` on `{type}`"); - - return resolvedImpl.FullName == expectedInterfaceTypeName; - }); - } - - private IEnumerable VerifyRemovedMemberInAssembly (CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) - { - var originalType = GetOriginalTypeFromInAssemblyAttribute (inAssemblyAttribute); - foreach (var memberNameAttr in (CustomAttributeArgument[]) inAssemblyAttribute.ConstructorArguments[2].Value) { - string memberName = (string) memberNameAttr.Value; - - // We will find the matching type from the original assembly first that way we can confirm - // that the name defined in the attribute corresponds to a member that actually existed - var originalFieldMember = originalType.Fields.FirstOrDefault (m => m.Name == memberName); - if (originalFieldMember != null) { - var linkedField = linkedType.Fields.FirstOrDefault (m => m.Name == memberName); - if (linkedField != null) - yield return $"Field `{memberName}` on Type `{originalType}` should have been removed"; - - continue; - } - - var originalPropertyMember = originalType.Properties.FirstOrDefault (m => m.Name == memberName); - if (originalPropertyMember != null) { - var linkedProperty = linkedType.Properties.FirstOrDefault (m => m.Name == memberName); - if (linkedProperty != null) - yield return $"Property `{memberName}` on Type `{originalType}` should have been removed"; - - continue; - } - - var originalMethodMember = originalType.Methods.FirstOrDefault (m => m.GetSignature () == memberName); - if (originalMethodMember != null) { - var linkedMethod = linkedType.Methods.FirstOrDefault (m => m.GetSignature () == memberName); - if (linkedMethod != null) - yield return $"Method `{memberName}` on Type `{originalType}` should have been removed"; - - continue; - } - - yield return $"Invalid test assertion. No member named `{memberName}` exists on the original type `{originalType}`"; - } - } - - private IEnumerable VerifyKeptMemberInAssembly (CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) - { - var originalType = GetOriginalTypeFromInAssemblyAttribute (inAssemblyAttribute); - var memberNames = (CustomAttributeArgument[]) inAssemblyAttribute.ConstructorArguments[2].Value; - if (!(memberNames.Length > 0)) - yield return "Invalid KeptMemberInAssemblyAttribute. Expected member names."; - foreach (var memberNameAttr in memberNames) { - string memberName = (string) memberNameAttr.Value; - - // We will find the matching type from the original assembly first that way we can confirm - // that the name defined in the attribute corresponds to a member that actually existed - - if (TryVerifyKeptMemberInAssemblyAsField (memberName, originalType, linkedType)) - continue; - - if (TryVerifyKeptMemberInAssemblyAsProperty (memberName, originalType, linkedType)) - continue; - - if (TryVerifyKeptMemberInAssemblyAsMethod (memberName, originalType, linkedType)) - continue; - - yield return $"Invalid test assertion. No member named `{memberName}` exists on the original type `{originalType}`"; - } - } - - protected virtual bool TryVerifyKeptMemberInAssemblyAsField (string memberName, TypeDefinition originalType, TypeDefinition linkedType) - { - var originalFieldMember = originalType.Fields.FirstOrDefault (m => m.Name == memberName); - if (originalFieldMember != null) { - var linkedField = linkedType.Fields.FirstOrDefault (m => m.Name == memberName); - if (linkedField == null) - Assert.Fail ($"Field `{memberName}` on Type `{originalType}` should have been kept"); - - return true; - } - - return false; - } - - protected virtual bool TryVerifyKeptMemberInAssemblyAsProperty (string memberName, TypeDefinition originalType, TypeDefinition linkedType) - { - var originalPropertyMember = originalType.Properties.FirstOrDefault (m => m.Name == memberName); - if (originalPropertyMember != null) { - var linkedProperty = linkedType.Properties.FirstOrDefault (m => m.Name == memberName); - if (linkedProperty == null) - Assert.Fail ($"Property `{memberName}` on Type `{originalType}` should have been kept"); - - return true; - } - - return false; - } - - protected virtual bool TryVerifyKeptMemberInAssemblyAsMethod (string memberName, TypeDefinition originalType, TypeDefinition linkedType) - { - return TryVerifyKeptMemberInAssemblyAsMethod (memberName, originalType, linkedType, out _, out _); - } - - protected virtual bool TryVerifyKeptMemberInAssemblyAsMethod (string memberName, TypeDefinition originalType, TypeDefinition linkedType, out MethodDefinition? originalMethod, out MethodDefinition? linkedMethod) - { - originalMethod = originalType.Methods.FirstOrDefault (m => m.GetSignature () == memberName); - if (originalMethod != null) { - linkedMethod = linkedType.Methods.FirstOrDefault (m => m.GetSignature () == memberName); - if (linkedMethod == null) - Assert.Fail ($"Method `{memberName}` on Type `{originalType}` should have been kept"); - - return true; - } - - linkedMethod = null; - return false; - } - - private IEnumerable VerifyKeptReferencesInAssembly (CustomAttribute inAssemblyAttribute) - { + } + } + } + } + catch (AssemblyResolutionException e) + { + errs.Add($"Failed to resolve linked assembly `{e.AssemblyReference.Name}`. It must not exist in the output."); + } + return errs; + } + + private IEnumerable VerifyKeptAttributeInAssembly(CustomAttribute inAssemblyAttribute, AssemblyDefinition linkedAssembly) + { + return VerifyAttributeInAssembly(inAssemblyAttribute, linkedAssembly, VerifyCustomAttributeKept); + } + + private IEnumerable VerifyRemovedAttributeInAssembly(CustomAttribute inAssemblyAttribute, AssemblyDefinition linkedAssembly) + { + return VerifyAttributeInAssembly(inAssemblyAttribute, linkedAssembly, VerifyCustomAttributeRemoved); + } + + private IEnumerable VerifyAttributeInAssembly(CustomAttribute inAssemblyAttribute, AssemblyDefinition linkedAssembly, Func> assertExpectedAttribute) + { + var assemblyName = (string)inAssemblyAttribute.ConstructorArguments[0].Value!; + string expectedAttributeTypeName; + var attributeTypeOrTypeName = inAssemblyAttribute.ConstructorArguments[1].Value!; + if (attributeTypeOrTypeName is TypeReference typeReference) + { + expectedAttributeTypeName = typeReference.FullName; + } + else + { + expectedAttributeTypeName = attributeTypeOrTypeName.ToString()!; + } + + if (inAssemblyAttribute.ConstructorArguments.Count == 2) + { + // Assembly + foreach (var err in assertExpectedAttribute(linkedAssembly, expectedAttributeTypeName)) + yield return err; + yield break; + } + + // We are asserting on type or member + var typeOrTypeName = inAssemblyAttribute.ConstructorArguments[2].Value; + var originalType = GetOriginalTypeFromInAssemblyAttribute(inAssemblyAttribute.ConstructorArguments[0].Value.ToString()!, typeOrTypeName); + if (originalType == null) + { + yield return $"Invalid test assertion. The original `{assemblyName}` does not contain a type `{typeOrTypeName}`"; + yield break; + } + + var linkedType = linkedAssembly.MainModule.GetType(originalType.FullName); + if (linkedType == null) + { + yield return $"Missing expected type `{typeOrTypeName}` in `{assemblyName}`"; + yield break; + } + + if (inAssemblyAttribute.ConstructorArguments.Count == 3) + { + assertExpectedAttribute(linkedType, expectedAttributeTypeName); + yield break; + } + + // we are asserting on a member + string memberName = (string)inAssemblyAttribute.ConstructorArguments[3].Value; + + // We will find the matching type from the original assembly first that way we can confirm + // that the name defined in the attribute corresponds to a member that actually existed + var originalFieldMember = originalType.Fields.FirstOrDefault(m => m.Name == memberName); + if (originalFieldMember != null) + { + var linkedField = linkedType.Fields.FirstOrDefault(m => m.Name == memberName); + if (linkedField == null) + { + yield return $"Field `{memberName}` on Type `{originalType}` should have been kept"; + yield break; + } + + assertExpectedAttribute(linkedField, expectedAttributeTypeName); + yield break; + } + + var originalPropertyMember = originalType.Properties.FirstOrDefault(m => m.Name == memberName); + if (originalPropertyMember != null) + { + var linkedProperty = linkedType.Properties.FirstOrDefault(m => m.Name == memberName); + if (linkedProperty == null) + { + yield return $"Property `{memberName}` on Type `{originalType}` should have been kept"; + yield break; + } + + foreach (var err in assertExpectedAttribute(linkedProperty, expectedAttributeTypeName)) + yield return err; + yield break; + } + + var originalMethodMember = originalType.Methods.FirstOrDefault(m => m.GetSignature() == memberName); + if (originalMethodMember != null) + { + var linkedMethod = linkedType.Methods.FirstOrDefault(m => m.GetSignature() == memberName); + if (linkedMethod == null) + { + yield return $"Method `{memberName}` on Type `{originalType}` should have been kept"; + yield break; + } + + assertExpectedAttribute(linkedMethod, expectedAttributeTypeName); + yield break; + } + + yield return $"Invalid test assertion. No member named `{memberName}` exists on the original type `{originalType}`"; + } + + private static IEnumerable VerifyCopyAssemblyIsKeptUnmodified(NPath outputDirectory, string assemblyName) + { + string inputAssemblyPath = Path.Combine(Directory.GetParent(outputDirectory)!.ToString(), "input", assemblyName); + string outputAssemblyPath = Path.Combine(outputDirectory, assemblyName); + if (true != File.ReadAllBytes(inputAssemblyPath).SequenceEqual(File.ReadAllBytes(outputAssemblyPath))) + yield return $"Expected assemblies\n" + + $"\t{inputAssemblyPath}\n" + + $"\t{outputAssemblyPath}\n" + + $"binaries to be equal, since the input assembly has copy action."; + } + + private IEnumerable VerifyCustomAttributeKept(ICustomAttributeProvider provider, string expectedAttributeTypeName) + { + var match = provider.CustomAttributes.FirstOrDefault(attr => attr.AttributeType.FullName == expectedAttributeTypeName); + if (match == null) + yield return $"Expected `{provider}` to have an attribute of type `{expectedAttributeTypeName}`"; + } + + private IEnumerable VerifyCustomAttributeRemoved(ICustomAttributeProvider provider, string expectedAttributeTypeName) + { + var match = provider.CustomAttributes.FirstOrDefault(attr => attr.AttributeType.FullName == expectedAttributeTypeName); + if (match != null) + yield return $"Expected `{provider}` to no longer have an attribute of type `{expectedAttributeTypeName}`"; + } + + private IEnumerable VerifyRemovedInterfaceOnTypeInAssembly(CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) + { + var originalType = GetOriginalTypeFromInAssemblyAttribute(inAssemblyAttribute); + + var interfaceAssemblyName = inAssemblyAttribute.ConstructorArguments[2].Value.ToString()!; + var interfaceType = inAssemblyAttribute.ConstructorArguments[3].Value; + + var originalInterface = GetOriginalTypeFromInAssemblyAttribute(interfaceAssemblyName, interfaceType); + if (!originalType.HasInterfaces) + yield return "Invalid assertion. Original type does not have any interfaces"; + + var originalInterfaceImpl = GetMatchingInterfaceImplementationOnType(originalType, originalInterface.FullName); + if (originalInterfaceImpl == null) + yield return $"Invalid assertion. Original type never had an interface of type `{originalInterface}`"; + + var linkedInterfaceImpl = GetMatchingInterfaceImplementationOnType(linkedType, originalInterface.FullName); + if (linkedInterfaceImpl != null) + yield return $"Expected `{linkedType}` to no longer have an interface of type {originalInterface.FullName}"; + } + + private IEnumerable VerifyKeptInterfaceOnTypeInAssembly(CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) + { + var originalType = GetOriginalTypeFromInAssemblyAttribute(inAssemblyAttribute); + + var interfaceAssemblyName = inAssemblyAttribute.ConstructorArguments[2].Value.ToString()!; + var interfaceType = inAssemblyAttribute.ConstructorArguments[3].Value; + + var originalInterface = GetOriginalTypeFromInAssemblyAttribute(interfaceAssemblyName, interfaceType); + if (!originalType.HasInterfaces) + yield return "Invalid assertion. Original type does not have any interfaces"; + + var originalInterfaceImpl = GetMatchingInterfaceImplementationOnType(originalType, originalInterface.FullName); + if (originalInterfaceImpl == null) + yield return $"Invalid assertion. Original type never had an interface of type `{originalInterface}`"; + + var linkedInterfaceImpl = GetMatchingInterfaceImplementationOnType(linkedType, originalInterface.FullName); + if (linkedInterfaceImpl == null) + yield return $"Expected `{linkedType}` to have interface of type {originalInterface.FullName}"; + } + + private IEnumerable VerifyKeptBaseOnTypeInAssembly(CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) + { + var originalType = GetOriginalTypeFromInAssemblyAttribute(inAssemblyAttribute); + + var baseAssemblyName = inAssemblyAttribute.ConstructorArguments[2].Value.ToString()!; + var baseType = inAssemblyAttribute.ConstructorArguments[3].Value; + + var originalBase = GetOriginalTypeFromInAssemblyAttribute(baseAssemblyName, baseType); + if (originalType.BaseType.Resolve() != originalBase) + yield return "Invalid assertion. Original type's base does not match the expected base"; + + if (originalBase.FullName != linkedType.BaseType.FullName) + yield return $"Incorrect base on `{linkedType.FullName}`. Expected `{originalBase.FullName}` but was `{linkedType.BaseType.FullName}`"; + } + + private static InterfaceImplementation? GetMatchingInterfaceImplementationOnType(TypeDefinition type, string expectedInterfaceTypeName) + { + return type.Interfaces.FirstOrDefault(impl => + { + var resolvedImpl = impl.InterfaceType.Resolve(); + + if (resolvedImpl == null) + Assert.Fail($"Failed to resolve interface : `{impl.InterfaceType}` on `{type}`"); + + return resolvedImpl.FullName == expectedInterfaceTypeName; + }); + } + + private IEnumerable VerifyRemovedMemberInAssembly(CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) + { + var originalType = GetOriginalTypeFromInAssemblyAttribute(inAssemblyAttribute); + foreach (var memberNameAttr in (CustomAttributeArgument[])inAssemblyAttribute.ConstructorArguments[2].Value) + { + string memberName = (string)memberNameAttr.Value; + + // We will find the matching type from the original assembly first that way we can confirm + // that the name defined in the attribute corresponds to a member that actually existed + var originalFieldMember = originalType.Fields.FirstOrDefault(m => m.Name == memberName); + if (originalFieldMember != null) + { + var linkedField = linkedType.Fields.FirstOrDefault(m => m.Name == memberName); + if (linkedField != null) + yield return $"Field `{memberName}` on Type `{originalType}` should have been removed"; + + continue; + } + + var originalPropertyMember = originalType.Properties.FirstOrDefault(m => m.Name == memberName); + if (originalPropertyMember != null) + { + var linkedProperty = linkedType.Properties.FirstOrDefault(m => m.Name == memberName); + if (linkedProperty != null) + yield return $"Property `{memberName}` on Type `{originalType}` should have been removed"; + + continue; + } + + var originalMethodMember = originalType.Methods.FirstOrDefault(m => m.GetSignature() == memberName); + if (originalMethodMember != null) + { + var linkedMethod = linkedType.Methods.FirstOrDefault(m => m.GetSignature() == memberName); + if (linkedMethod != null) + yield return $"Method `{memberName}` on Type `{originalType}` should have been removed"; + + continue; + } + + yield return $"Invalid test assertion. No member named `{memberName}` exists on the original type `{originalType}`"; + } + } + + private IEnumerable VerifyKeptMemberInAssembly(CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) + { + var originalType = GetOriginalTypeFromInAssemblyAttribute(inAssemblyAttribute); + var memberNames = (CustomAttributeArgument[])inAssemblyAttribute.ConstructorArguments[2].Value; + if (!(memberNames.Length > 0)) + yield return "Invalid KeptMemberInAssemblyAttribute. Expected member names."; + foreach (var memberNameAttr in memberNames) + { + string memberName = (string)memberNameAttr.Value; + + // We will find the matching type from the original assembly first that way we can confirm + // that the name defined in the attribute corresponds to a member that actually existed + + if (TryVerifyKeptMemberInAssemblyAsField(memberName, originalType, linkedType)) + continue; + + if (TryVerifyKeptMemberInAssemblyAsProperty(memberName, originalType, linkedType)) + continue; + + if (TryVerifyKeptMemberInAssemblyAsMethod(memberName, originalType, linkedType)) + continue; + + yield return $"Invalid test assertion. No member named `{memberName}` exists on the original type `{originalType}`"; + } + } + + protected virtual bool TryVerifyKeptMemberInAssemblyAsField(string memberName, TypeDefinition originalType, TypeDefinition linkedType) + { + var originalFieldMember = originalType.Fields.FirstOrDefault(m => m.Name == memberName); + if (originalFieldMember != null) + { + var linkedField = linkedType.Fields.FirstOrDefault(m => m.Name == memberName); + if (linkedField == null) + Assert.Fail($"Field `{memberName}` on Type `{originalType}` should have been kept"); + + return true; + } + + return false; + } + + protected virtual bool TryVerifyKeptMemberInAssemblyAsProperty(string memberName, TypeDefinition originalType, TypeDefinition linkedType) + { + var originalPropertyMember = originalType.Properties.FirstOrDefault(m => m.Name == memberName); + if (originalPropertyMember != null) + { + var linkedProperty = linkedType.Properties.FirstOrDefault(m => m.Name == memberName); + if (linkedProperty == null) + Assert.Fail($"Property `{memberName}` on Type `{originalType}` should have been kept"); + + return true; + } + + return false; + } + + protected virtual bool TryVerifyKeptMemberInAssemblyAsMethod(string memberName, TypeDefinition originalType, TypeDefinition linkedType) + { + return TryVerifyKeptMemberInAssemblyAsMethod(memberName, originalType, linkedType, out _, out _); + } + + protected virtual bool TryVerifyKeptMemberInAssemblyAsMethod(string memberName, TypeDefinition originalType, TypeDefinition linkedType, out MethodDefinition? originalMethod, out MethodDefinition? linkedMethod) + { + originalMethod = originalType.Methods.FirstOrDefault(m => m.GetSignature() == memberName); + if (originalMethod != null) + { + linkedMethod = linkedType.Methods.FirstOrDefault(m => m.GetSignature() == memberName); + if (linkedMethod == null) + Assert.Fail($"Method `{memberName}` on Type `{originalType}` should have been kept"); + + return true; + } + + linkedMethod = null; + return false; + } + + private IEnumerable VerifyKeptReferencesInAssembly(CustomAttribute inAssemblyAttribute) + { #if false - var assembly = ResolveLinkedAssembly (inAssemblyAttribute.ConstructorArguments[0].Value.ToString ()!); - var expectedReferenceNames = ((CustomAttributeArgument[]) inAssemblyAttribute.ConstructorArguments[1].Value).Select (attr => (string) attr.Value).ToList (); - for (int i = 0; i < expectedReferenceNames.Count; i++) - if (expectedReferenceNames[i].EndsWith (".dll")) - expectedReferenceNames[i] = expectedReferenceNames[i].Substring (0, expectedReferenceNames[i].LastIndexOf (".")); + var assembly = ResolveLinkedAssembly(inAssemblyAttribute.ConstructorArguments[0].Value.ToString()!); + var expectedReferenceNames = ((CustomAttributeArgument[]) inAssemblyAttribute.ConstructorArguments[1].Value).Select(attr => (string) attr.Value).ToList(); + for (int i = 0; i < expectedReferenceNames.Count; i++) + if (expectedReferenceNames[i].EndsWith(".dll")) + expectedReferenceNames[i] = expectedReferenceNames[i].Substring(0, expectedReferenceNames[i].LastIndexOf(".")); - Assert.Equal (assembly.MainModule.AssemblyReferences.Select (asm => asm.Name), expectedReferenceNames); + Assert.Equal(assembly.MainModule.AssemblyReferences.Select(asm => asm.Name), expectedReferenceNames); #endif - yield break; - } + yield break; + } - private IEnumerable VerifyKeptResourceInAssembly (CustomAttribute inAssemblyAttribute) - { + private IEnumerable VerifyKeptResourceInAssembly(CustomAttribute inAssemblyAttribute) + { #if false - var assembly = ResolveLinkedAssembly (inAssemblyAttribute.ConstructorArguments[0].Value.ToString ()!); - var resourceName = inAssemblyAttribute.ConstructorArguments[1].Value.ToString (); + var assembly = ResolveLinkedAssembly(inAssemblyAttribute.ConstructorArguments[0].Value.ToString()!); + var resourceName = inAssemblyAttribute.ConstructorArguments[1].Value.ToString(); - Assert.Contains (resourceName, assembly.MainModule.Resources.Select (r => r.Name)); + Assert.Contains(resourceName, assembly.MainModule.Resources.Select(r => r.Name)); #endif - yield break; - } + yield break; + } - private IEnumerable VerifyRemovedResourceInAssembly (CustomAttribute inAssemblyAttribute) - { + private IEnumerable VerifyRemovedResourceInAssembly(CustomAttribute inAssemblyAttribute) + { #if false - var assembly = ResolveLinkedAssembly (inAssemblyAttribute.ConstructorArguments[0].Value.ToString ()!); - var resourceName = inAssemblyAttribute.ConstructorArguments[1].Value.ToString (); + var assembly = ResolveLinkedAssembly(inAssemblyAttribute.ConstructorArguments[0].Value.ToString()!); + var resourceName = inAssemblyAttribute.ConstructorArguments[1].Value.ToString(); - Assert.DoesNotContain (resourceName, assembly.MainModule.Resources.Select (r => r.Name)); + Assert.DoesNotContain(resourceName, assembly.MainModule.Resources.Select(r => r.Name)); #endif - yield break; - } - - private IEnumerable VerifyKeptAllTypesAndMembersInAssembly (string assemblyName, Dictionary linkedMembers) - { - var original = ResolveOriginalsAssembly (assemblyName); - - if (original == null) - { - yield return $"Failed to resolve original assembly {assemblyName}"; - yield break; - } - - var originalTypes = original.AllDefinedTypes ().ToDictionary (t => new AssemblyQualifiedToken(t)); - var linkedTypes = linkedMembers.Where(t => t.Value.Entity is TypeDesc).ToDictionary(); - - var missingInLinked = originalTypes.Keys.Except (linkedTypes.Keys); - - if (missingInLinked.Any ()) - yield return $"Expected all types to exist in the linked assembly {assemblyName}, but one or more were missing"; - - foreach (var originalKvp in originalTypes) { - var linkedType = linkedTypes[originalKvp.Key]; - TypeDesc linkedTypeDesc = (TypeDesc)linkedType.Entity; - - // NativeAOT field trimming is very different (it basically doesn't trim fields, not in the same way trimmer does) - var originalMembers = originalKvp.Value.AllMembers ().Where(m => m is not FieldDefinition).Select (m => new AssemblyQualifiedToken(m)); - var linkedMembersOnType = linkedMembers.Where(t => GetOwningType(t.Value.Entity) == linkedTypeDesc).Select(t => t.Key); - - var missingMembersInLinked = originalMembers.Except (linkedMembersOnType); - - if (missingMembersInLinked.Any ()) - yield return $"Expected all members of `{linkedTypeDesc.GetDisplayName()}`to exist in the linked assembly, but one or more were missing"; - } - } - - private TypeDefinition GetOriginalTypeFromInAssemblyAttribute (CustomAttribute inAssemblyAttribute) - { - string assemblyName; - if (inAssemblyAttribute.HasProperties && inAssemblyAttribute.Properties[0].Name == "ExpectationAssemblyName") - assemblyName = inAssemblyAttribute.Properties[0].Argument.Value.ToString ()!; - else - assemblyName = inAssemblyAttribute.ConstructorArguments[0].Value.ToString ()!; - - return GetOriginalTypeFromInAssemblyAttribute (assemblyName, inAssemblyAttribute.ConstructorArguments[1].Value); - } - - private TypeDefinition GetOriginalTypeFromInAssemblyAttribute (string assemblyName, object typeOrTypeName) - { - if (typeOrTypeName is TypeReference attributeValueAsTypeReference) - return attributeValueAsTypeReference.Resolve (); - - var assembly = ResolveOriginalsAssembly (assemblyName); - - var expectedTypeName = typeOrTypeName.ToString (); - var originalType = assembly.MainModule.GetType (expectedTypeName); - if (originalType == null) - Assert.Fail ($"Invalid test assertion. Unable to locate the original type `{expectedTypeName}.`"); - return originalType; - } - - private static Dictionary> BuildOtherAssemblyCheckTable (AssemblyDefinition original) - { - var checks = new Dictionary> (); - - foreach (var typeWithRemoveInAssembly in original.AllDefinedTypes ()) { - foreach (var attr in typeWithRemoveInAssembly.CustomAttributes.Where (IsTypeInOtherAssemblyAssertion)) { - var assemblyName = (string) attr.ConstructorArguments[0].Value; - - Tool? toolTarget = (Tool?)(int?)attr.GetPropertyValue("Tool"); - if (toolTarget is not null && !toolTarget.Value.HasFlag(Tool.NativeAot)) - continue; - - if (!checks.TryGetValue (assemblyName, out List? checksForAssembly)) - checks[assemblyName] = checksForAssembly = new List (); - - checksForAssembly.Add (attr); - } - } - - return checks; - } - - private Dictionary ResolveLinkedMembersForAssembly (string assemblyName) - { - var cleanAssemblyName = assemblyName; - if (assemblyName.EndsWith(".exe") || assemblyName.EndsWith(".dll")) - cleanAssemblyName = System.IO.Path.GetFileNameWithoutExtension(assemblyName); - - return this.linkedMembers.Where(e => GetModuleName(e.Value.Entity) == cleanAssemblyName).ToDictionary(); - } - - protected AssemblyDefinition ResolveOriginalsAssembly (string assemblyName) - { - var cleanAssemblyName = assemblyName; - if (assemblyName.EndsWith (".exe") || assemblyName.EndsWith (".dll")) - cleanAssemblyName = Path.GetFileNameWithoutExtension (assemblyName); - return originalsResolver.Resolve (new AssemblyNameReference (cleanAssemblyName, null), originalReaderParameters); - } - - private static bool IsTypeInOtherAssemblyAssertion (CustomAttribute attr) - { - return attr.AttributeType.Resolve ()?.DerivesFrom (nameof (BaseInAssemblyAttribute)) ?? false; - } - - private IEnumerable VerifyExpectedInstructionSequenceOnMemberInAssembly (CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) - { - var originalType = GetOriginalTypeFromInAssemblyAttribute (inAssemblyAttribute); - var memberName = (string) inAssemblyAttribute.ConstructorArguments[2].Value; - - if (TryVerifyKeptMemberInAssemblyAsMethod (memberName, originalType, linkedType, out MethodDefinition? originalMethod, out MethodDefinition? linkedMethod)) { - static string[] valueCollector (MethodDefinition m) => AssemblyChecker.FormatMethodBody (m.Body); - var linkedValues = valueCollector (linkedMethod!); - var srcValues = valueCollector (originalMethod!); - - var expected = ((CustomAttributeArgument[]) inAssemblyAttribute.ConstructorArguments[3].Value)?.Select (arg => arg.Value.ToString ()).ToArray (); - if (!linkedValues.Equals(expected)) - yield return "Expected instruction sequence does not match"; - - yield break; - } - - yield return $"Invalid test assertion. No method named `{memberName}` exists on the original type `{originalType}`"; - } - - protected virtual void UnhandledOtherAssemblyAssertion (string expectedTypeName, CustomAttribute checkAttrInAssembly, TypeDefinition? linkedType) - { - throw new NotImplementedException ($"Type {expectedTypeName}, has an unknown other assembly attribute of type {checkAttrInAssembly.AttributeType}"); - } - } + yield break; + } + + private IEnumerable VerifyKeptAllTypesAndMembersInAssembly(string assemblyName, Dictionary linkedMembers) + { + var original = ResolveOriginalsAssembly(assemblyName); + + if (original == null) + { + yield return $"Failed to resolve original assembly {assemblyName}"; + yield break; + } + + var originalTypes = original.AllDefinedTypes().ToDictionary(t => new AssemblyQualifiedToken(t)); + var linkedTypes = linkedMembers.Where(t => t.Value.Entity is TypeDesc).ToDictionary(); + + var missingInLinked = originalTypes.Keys.Except(linkedTypes.Keys); + + if (missingInLinked.Any()) + { + yield return $"Expected all types to exist in the linked assembly {assemblyName}, but one or more were missing"; + yield break; + } + + foreach (var originalKvp in originalTypes) + { + var linkedType = linkedTypes[originalKvp.Key]; + TypeDesc linkedTypeDesc = (TypeDesc)linkedType.Entity; + + // NativeAOT field trimming is very different (it basically doesn't trim fields, not in the same way trimmer does) + var originalMembers = originalKvp.Value.AllMembers().Where(m => m is not FieldDefinition).Select(m => new AssemblyQualifiedToken(m)); + var linkedMembersOnType = linkedMembers.Where(t => GetOwningType(t.Value.Entity) == linkedTypeDesc).Select(t => t.Key); + + var missingMembersInLinked = originalMembers.Except(linkedMembersOnType); + + if (missingMembersInLinked.Any()) + yield return $"Expected all members of `{linkedTypeDesc.GetDisplayName()}`to exist in the linked assembly, but one or more were missing"; + } + } + + private TypeDefinition GetOriginalTypeFromInAssemblyAttribute(CustomAttribute inAssemblyAttribute) + { + string assemblyName; + if (inAssemblyAttribute.HasProperties && inAssemblyAttribute.Properties[0].Name == "ExpectationAssemblyName") + assemblyName = inAssemblyAttribute.Properties[0].Argument.Value.ToString()!; + else + assemblyName = inAssemblyAttribute.ConstructorArguments[0].Value.ToString()!; + + return GetOriginalTypeFromInAssemblyAttribute(assemblyName, inAssemblyAttribute.ConstructorArguments[1].Value); + } + + private TypeDefinition GetOriginalTypeFromInAssemblyAttribute(string assemblyName, object typeOrTypeName) + { + if (typeOrTypeName is TypeReference attributeValueAsTypeReference) + return attributeValueAsTypeReference.Resolve(); + + var assembly = ResolveOriginalsAssembly(assemblyName); + + var expectedTypeName = typeOrTypeName.ToString(); + var originalType = assembly.MainModule.GetType(expectedTypeName); + if (originalType == null) + Assert.Fail($"Invalid test assertion. Unable to locate the original type `{expectedTypeName}.`"); + return originalType; + } + + private static Dictionary> BuildOtherAssemblyCheckTable(AssemblyDefinition original) + { + var checks = new Dictionary>(); + + foreach (var typeWithRemoveInAssembly in original.AllDefinedTypes()) + { + foreach (var attr in typeWithRemoveInAssembly.CustomAttributes.Where(IsTypeInOtherAssemblyAssertion)) + { + var assemblyName = (string)attr.ConstructorArguments[0].Value; + + Tool? toolTarget = (Tool?)(int?)attr.GetPropertyValue("Tool"); + if (toolTarget is not null && !toolTarget.Value.HasFlag(Tool.NativeAot)) + continue; + + if (!checks.TryGetValue(assemblyName, out List? checksForAssembly)) + checks[assemblyName] = checksForAssembly = new List(); + + checksForAssembly.Add(attr); + } + } + + return checks; + } + + private Dictionary ResolveLinkedMembersForAssembly(string assemblyName) + { + var cleanAssemblyName = assemblyName; + if (assemblyName.EndsWith(".exe") || assemblyName.EndsWith(".dll")) + cleanAssemblyName = System.IO.Path.GetFileNameWithoutExtension(assemblyName); + + return this.linkedMembers.Where(e => GetModuleName(e.Value.Entity) == cleanAssemblyName).ToDictionary(); + } + + protected AssemblyDefinition ResolveOriginalsAssembly(string assemblyName) + { + var cleanAssemblyName = assemblyName; + if (assemblyName.EndsWith(".exe") || assemblyName.EndsWith(".dll")) + cleanAssemblyName = Path.GetFileNameWithoutExtension(assemblyName); + return originalsResolver.Resolve(new AssemblyNameReference(cleanAssemblyName, null), originalReaderParameters); + } + + private static bool IsTypeInOtherAssemblyAssertion(CustomAttribute attr) + { + return attr.AttributeType.Resolve()?.DerivesFrom(nameof(BaseInAssemblyAttribute)) ?? false; + } + + private IEnumerable VerifyExpectedInstructionSequenceOnMemberInAssembly(CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) + { + var originalType = GetOriginalTypeFromInAssemblyAttribute(inAssemblyAttribute); + var memberName = (string)inAssemblyAttribute.ConstructorArguments[2].Value; + + if (TryVerifyKeptMemberInAssemblyAsMethod(memberName, originalType, linkedType, out MethodDefinition? originalMethod, out MethodDefinition? linkedMethod)) + { + static string[] valueCollector(MethodDefinition m) => AssemblyChecker.FormatMethodBody(m.Body); + var linkedValues = valueCollector(linkedMethod!); + var srcValues = valueCollector(originalMethod!); + + var expected = ((CustomAttributeArgument[])inAssemblyAttribute.ConstructorArguments[3].Value)?.Select(arg => arg.Value.ToString()).ToArray(); + if (!linkedValues.Equals(expected)) + yield return "Expected instruction sequence does not match"; + + yield break; + } + + yield return $"Invalid test assertion. No method named `{memberName}` exists on the original type `{originalType}`"; + } + + protected virtual void UnhandledOtherAssemblyAssertion(string expectedTypeName, CustomAttribute checkAttrInAssembly, TypeDefinition? linkedType) + { + throw new NotImplementedException($"Type {expectedTypeName}, has an unknown other assembly attribute of type {checkAttrInAssembly.AttributeType}"); + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/AssemblyQualifiedToken.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/AssemblyQualifiedToken.cs index 2e0ecaa9a5b7ac..01bf36d8e936d2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/AssemblyQualifiedToken.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/AssemblyQualifiedToken.cs @@ -6,51 +6,54 @@ using System.Reflection.Metadata.Ecma335; using ILCompiler; using Internal.IL.Stubs; -using Internal.TypeSystem.Ecma; using Internal.TypeSystem; +using Internal.TypeSystem.Ecma; using Mono.Cecil; using MetadataType = Internal.TypeSystem.MetadataType; namespace Mono.Linker.Tests.TestCasesRunner { - internal readonly struct AssemblyQualifiedToken : IEquatable - { - public string? AssemblyName { get; } - public int Token { get; } + internal readonly struct AssemblyQualifiedToken : IEquatable + { + public string? AssemblyName { get; } + public int Token { get; } - public AssemblyQualifiedToken (string? assemblyName, int token) => (AssemblyName, Token) = (assemblyName, token); + public AssemblyQualifiedToken(string? assemblyName, int token) => (AssemblyName, Token) = (assemblyName, token); - public AssemblyQualifiedToken (TypeSystemEntity entity) { - if (entity is MethodForInstantiatedType instantiatedMethod) - entity = instantiatedMethod.GetTypicalMethodDefinition (); - (AssemblyName, Token) = entity switch { - EcmaType type => (type.Module.Assembly.GetName ().Name, MetadataTokens.GetToken (type.Handle)), - EcmaMethod method => (method.Module.Assembly.GetName ().Name, MetadataTokens.GetToken (method.Handle)), - EcmaField field => (field.Module.Assembly.GetName ().Name, MetadataTokens.GetToken (field.Handle)), - PropertyPseudoDesc property => (((EcmaType) property.OwningType).Module.Assembly.GetName ().Name, MetadataTokens.GetToken (property.Handle)), - EventPseudoDesc @event => (((EcmaType) @event.OwningType).Module.Assembly.GetName ().Name, MetadataTokens.GetToken (@event.Handle)), - ILStubMethod => (null, 0), // Ignore compiler generated methods - MetadataType mt when mt.GetType().Name == "BoxedValueType" => (null, 0), - _ => throw new NotSupportedException ($"The infra doesn't support getting a token for {entity} yet.") - }; - } + public AssemblyQualifiedToken(TypeSystemEntity entity) + { + if (entity is MethodForInstantiatedType instantiatedMethod) + entity = instantiatedMethod.GetTypicalMethodDefinition(); + (AssemblyName, Token) = entity switch + { + EcmaType type => (type.Module.Assembly.GetName().Name, MetadataTokens.GetToken(type.Handle)), + EcmaMethod method => (method.Module.Assembly.GetName().Name, MetadataTokens.GetToken(method.Handle)), + EcmaField field => (field.Module.Assembly.GetName().Name, MetadataTokens.GetToken(field.Handle)), + PropertyPseudoDesc property => (((EcmaType)property.OwningType).Module.Assembly.GetName().Name, MetadataTokens.GetToken(property.Handle)), + EventPseudoDesc @event => (((EcmaType)@event.OwningType).Module.Assembly.GetName().Name, MetadataTokens.GetToken(@event.Handle)), + ILStubMethod => (null, 0), // Ignore compiler generated methods + MetadataType mt when mt.GetType().Name == "BoxedValueType" => (null, 0), + _ => throw new NotSupportedException($"The infra doesn't support getting a token for {entity} yet.") + }; + } - public AssemblyQualifiedToken (IMemberDefinition member) => - (AssemblyName, Token) = member switch { - TypeDefinition type => (type.Module.Assembly.Name.Name, type.MetadataToken.ToInt32 ()), - MethodDefinition method => (method.Module.Assembly.Name.Name, method.MetadataToken.ToInt32 ()), - PropertyDefinition property => (property.Module.Assembly.Name.Name, property.MetadataToken.ToInt32 ()), - EventDefinition @event => (@event.Module.Assembly.Name.Name, @event.MetadataToken.ToInt32 ()), - FieldDefinition field => (field.Module.Assembly.Name.Name, field.MetadataToken.ToInt32 ()), - _ => throw new NotSupportedException ($"The infra doesn't support getting a token for {member} yet.") - }; + public AssemblyQualifiedToken(IMemberDefinition member) => + (AssemblyName, Token) = member switch + { + TypeDefinition type => (type.Module.Assembly.Name.Name, type.MetadataToken.ToInt32()), + MethodDefinition method => (method.Module.Assembly.Name.Name, method.MetadataToken.ToInt32()), + PropertyDefinition property => (property.Module.Assembly.Name.Name, property.MetadataToken.ToInt32()), + EventDefinition @event => (@event.Module.Assembly.Name.Name, @event.MetadataToken.ToInt32()), + FieldDefinition field => (field.Module.Assembly.Name.Name, field.MetadataToken.ToInt32()), + _ => throw new NotSupportedException($"The infra doesn't support getting a token for {member} yet.") + }; - public override int GetHashCode () => AssemblyName == null ? 0 : AssemblyName.GetHashCode () ^ Token.GetHashCode (); - public override string ToString () => $"{AssemblyName}: {Token}"; - public bool Equals (AssemblyQualifiedToken other) => - string.CompareOrdinal (AssemblyName, other.AssemblyName) == 0 && Token == other.Token; - public override bool Equals ([NotNullWhen (true)] object? obj) => ((AssemblyQualifiedToken?) obj)?.Equals (this) == true; + public override int GetHashCode() => AssemblyName == null ? 0 : AssemblyName.GetHashCode() ^ Token.GetHashCode(); + public override string ToString() => $"{AssemblyName}: {Token}"; + public bool Equals(AssemblyQualifiedToken other) => + string.CompareOrdinal(AssemblyName, other.AssemblyName) == 0 && Token == other.Token; + public override bool Equals([NotNullWhen(true)] object? obj) => ((AssemblyQualifiedToken?)obj)?.Equals(this) == true; - public bool IsNil => AssemblyName == null; - } + public bool IsNil => AssemblyName == null; + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILCompilerOptions.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILCompilerOptions.cs index 926f3e593b8c70..b3a066627a6167 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILCompilerOptions.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILCompilerOptions.cs @@ -5,20 +5,21 @@ namespace Mono.Linker.Tests.TestCasesRunner { - public class ILCompilerOptions - { - public Dictionary InputFilePaths = new Dictionary (); - public Dictionary ReferenceFilePaths = new Dictionary (); - public List InitAssemblies = new List (); - public List TrimAssemblies = new List (); - public List AdditionalRootAssemblies = new List (); - public Dictionary FeatureSwitches = new Dictionary (); - public List Descriptors = new List (); - public bool FrameworkCompilation; - public bool SingleWarn; - public List SubstitutionFiles = new List (); - public bool TreatWarningsAsErrors; - public Dictionary WarningsAsErrors = new Dictionary (); - public List SuppressedWarningCategories = new List (); - } + public class ILCompilerOptions + { + public Dictionary InputFilePaths = new Dictionary(); + public Dictionary ReferenceFilePaths = new Dictionary(); + public List InitAssemblies = new List(); + public List TrimAssemblies = new List(); + public List AdditionalRootAssemblies = new List(); + public Dictionary FeatureSwitches = new Dictionary(); + public List Descriptors = new List(); + public bool FrameworkCompilation; + public bool SingleWarn; + public List SubstitutionFiles = new List(); + public bool TreatWarningsAsErrors; + public Dictionary WarningsAsErrors = new Dictionary(); + public List SuppressedWarningCategories = new List(); + public bool DisableGeneratedCodeHeuristics; + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILCompilerTestPInvokePolicy.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILCompilerTestPInvokePolicy.cs index 4d2aebdcd269c1..5719ee5677b888 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILCompilerTestPInvokePolicy.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILCompilerTestPInvokePolicy.cs @@ -6,12 +6,12 @@ namespace Mono.Linker.Tests.TestCasesRunner { - internal sealed class ILCompilerTestPInvokePolicy : PInvokeILEmitterConfiguration - { - public override bool GenerateDirectCall (MethodDesc method, out string? externName) - { - externName = method.Name; - return true; - } - } + internal sealed class ILCompilerTestPInvokePolicy : PInvokeILEmitterConfiguration + { + public override bool GenerateDirectCall(MethodDesc method, out string? externName) + { + externName = method.Name; + return true; + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILInputCompiler.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILInputCompiler.cs index 80a48c2da1695e..c9d00414694f0c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILInputCompiler.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILInputCompiler.cs @@ -13,80 +13,81 @@ namespace Mono.Linker.Tests.TestCasesRunner { - public class ILInputCompiler - { - public NPath Compile (CompilerOptions options) - { - var capturedOutput = new List (); - var process = new Process (); - SetupProcess (process, options); - process.StartInfo.RedirectStandardOutput = true; - process.OutputDataReceived += (sender, args) => capturedOutput.Add (args.Data!); - process.Start (); - process.BeginOutputReadLine (); - process.WaitForExit (); + public class ILInputCompiler + { + public NPath Compile(CompilerOptions options) + { + var capturedOutput = new List(); + var process = new Process(); + SetupProcess(process, options); + process.StartInfo.RedirectStandardOutput = true; + process.OutputDataReceived += (sender, args) => capturedOutput.Add(args.Data!); + process.Start(); + process.BeginOutputReadLine(); + process.WaitForExit(); - if (process.ExitCode != 0) { - Assert.Fail($"Failed to compile IL assembly : {options.OutputPath}\n{capturedOutput.Aggregate ((buff, s) => buff + Environment.NewLine + s)}"); - } + if (process.ExitCode != 0) + { + Assert.Fail($"Failed to compile IL assembly : {options.OutputPath}\n{capturedOutput.Aggregate((buff, s) => buff + Environment.NewLine + s)}"); + } - return options.OutputPath; - } + return options.OutputPath; + } - protected virtual void SetupProcess (Process process, CompilerOptions options) - { - process.StartInfo.FileName = LocateIlasm ().ToString (); - process.StartInfo.Arguments = BuildArguments (options); - process.StartInfo.UseShellExecute = false; - process.StartInfo.CreateNoWindow = true; - process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; - } + protected virtual void SetupProcess(Process process, CompilerOptions options) + { + process.StartInfo.FileName = LocateIlasm().ToString(); + process.StartInfo.Arguments = BuildArguments(options); + process.StartInfo.UseShellExecute = false; + process.StartInfo.CreateNoWindow = true; + process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + } - private static string BuildArguments (CompilerOptions options) - { - var args = new StringBuilder (); + private static string BuildArguments(CompilerOptions options) + { + var args = new StringBuilder(); #if NET - args.Append (options.OutputPath.ExtensionWithDot == ".dll" ? "-dll" : "-exe"); - args.Append ($" -out:{options.OutputPath.InQuotes ()}"); + args.Append(options.OutputPath.ExtensionWithDot == ".dll" ? "-dll" : "-exe"); + args.Append($" -out:{options.OutputPath.InQuotes()}"); #else - args.Append (options.OutputPath.ExtensionWithDot == ".dll" ? "/dll" : "/exe"); - args.Append ($" /out:{options.OutputPath.InQuotes ()}"); + args.Append(options.OutputPath.ExtensionWithDot == ".dll" ? "/dll" : "/exe"); + args.Append($" /out:{options.OutputPath.InQuotes()}"); #endif - args.Append ($" {options.SourceFiles.Aggregate (string.Empty, (buff, file) => $"{buff} {file.InQuotes ()}")}"); - return args.ToString (); - } + args.Append($" {options.SourceFiles.Aggregate(string.Empty, (buff, file) => $"{buff} {file.InQuotes()}")}"); + return args.ToString(); + } - protected virtual NPath LocateIlasm () - { + protected virtual NPath LocateIlasm() + { #if NET - var extension = RuntimeInformation.IsOSPlatform (OSPlatform.Windows) ? ".exe" : ""; + var extension = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : ""; - var toolsDir = (string) AppContext.GetData ("Mono.Linker.Tests.ILToolsDir")!; + var toolsDir = (string)AppContext.GetData("Mono.Linker.Tests.ILToolsDir")!; - var ilasmPath = Path.GetFullPath (Path.Combine (toolsDir, $"ilasm{extension}")).ToNPath (); - if (ilasmPath.FileExists ()) - return ilasmPath; + var ilasmPath = Path.GetFullPath(Path.Combine(toolsDir, $"ilasm{extension}")).ToNPath(); + if (ilasmPath.FileExists()) + return ilasmPath; - throw new InvalidOperationException ("ilasm not found at " + ilasmPath); + throw new InvalidOperationException("ilasm not found at " + ilasmPath); #else - return Environment.OSVersion.Platform == PlatformID.Win32NT ? LocateIlasmOnWindows () : "ilasm".ToNPath (); + return Environment.OSVersion.Platform == PlatformID.Win32NT ? LocateIlasmOnWindows() : "ilasm".ToNPath(); #endif - } + } - public static NPath LocateIlasmOnWindows () - { - if (Environment.OSVersion.Platform != PlatformID.Win32NT) - throw new InvalidOperationException ("This method should only be called on windows"); + public static NPath LocateIlasmOnWindows() + { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + throw new InvalidOperationException("This method should only be called on windows"); - var possiblePath = RuntimeEnvironment.GetRuntimeDirectory ().ToNPath ().Combine ("ilasm.exe"); - if (possiblePath.FileExists ()) - return possiblePath; + var possiblePath = RuntimeEnvironment.GetRuntimeDirectory().ToNPath().Combine("ilasm.exe"); + if (possiblePath.FileExists()) + return possiblePath; - possiblePath = Environment.CurrentDirectory.ToNPath ().Combine ("ilasm.exe"); - if (possiblePath.FileExists ()) - return possiblePath; + possiblePath = Environment.CurrentDirectory.ToNPath().Combine("ilasm.exe"); + if (possiblePath.FileExists()) + return possiblePath; - throw new InvalidOperationException ("Could not locate a ilasm.exe executable"); - } - } + throw new InvalidOperationException("Could not locate a ilasm.exe executable"); + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/MemberAssertionsCollector.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/MemberAssertionsCollector.cs index 6b7958c92c4d89..425ad3d1dbce5c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/MemberAssertionsCollector.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/MemberAssertionsCollector.cs @@ -16,181 +16,195 @@ namespace Mono.Linker.Tests.TestCasesRunner { - public class MemberAssertionsCollector : IEnumerable - { - public struct CustomAttribute - { - public MetadataType AttributeType; - public CustomAttributeValue Value; - - public override string ToString () => AttributeType.ToString (); - } - - public MemberAssertionsCollector(Type type) - { - this.type = type; - TypeSystemContext = CreateTypeSystemContext(); - } - - private CompilerTypeSystemContext TypeSystemContext; - private readonly Type type; - - private CompilerTypeSystemContext CreateTypeSystemContext () - { - TrimmingDriver.ComputeDefaultOptions (out var targetOS, out var targetArchitecture); - var targetDetails = new TargetDetails (targetArchitecture, targetOS, TargetAbi.NativeAot); - CompilerTypeSystemContext typeSystemContext = - new CompilerTypeSystemContext (targetDetails, SharedGenericsMode.CanonicalReferenceTypes, DelegateFeature.All); - typeSystemContext.InputFilePaths = new Dictionary () { - { type.Assembly.GetName().Name!, type.Assembly.Location } - }; - Dictionary references = new Dictionary (); - foreach (Assembly assembly in AssemblyLoadContext.Default.Assemblies) { - references.Add (assembly.GetName ().Name!, assembly.Location!); - } - typeSystemContext.ReferenceFilePaths = references; - typeSystemContext.SetSystemModule (typeSystemContext.GetModuleForSimpleName (TrimmingDriver.DefaultSystemModule)); - - return typeSystemContext; - } - - internal IEnumerable<(TypeSystemEntity member, CustomAttribute ca)> GetMemberAssertions (Type type) - { - var module = TypeSystemContext.GetModuleFromPath (type.Assembly.Location); - var t = module.GetType (type.Namespace, type.Name, throwIfNotFound: false); - if (t == null) - throw new InvalidOperationException ($"type {type} not found in {module}"); - var results = new List<(TypeSystemEntity, CustomAttribute)> (); - CollectMemberAssertions (t, results); - return results; - } - - public IEnumerable GetMemberAssertionsData () - { - return GetMemberAssertions (type).Select (v => new object[] { v.member, v.ca }); - } - - public IEnumerator GetEnumerator () => GetMemberAssertionsData ().GetEnumerator (); - IEnumerator IEnumerable.GetEnumerator () => throw new NotImplementedException (); - - private static bool IsMemberAssertion (MetadataType attributeType) - { - if (attributeType == null) - return false; - - if (attributeType.Namespace != "Mono.Linker.Tests.Cases.Expectations.Assertions") - return false; - - MetadataType t = attributeType; - while (t != null) { - if (t.Name == nameof (BaseMemberAssertionAttribute)) - return true; - - t = t.MetadataBaseType; - } - - return false; - } - - private static void CollectMemberAssertions (MetadataType metadataType, List<(TypeSystemEntity, CustomAttribute)> results) - { - if (metadataType is not EcmaType type) - return; - - foreach (var ca in GetCustomAttributes (type)) { - if (!IsMemberAssertion (ca.AttributeType)) - continue; - results.Add ((type, ca)); - } - - foreach (var md in type.GetMethods ()) { - if (md is not EcmaMethod m) - continue; - - foreach (var ca in GetCustomAttributes(m)) { - if (!IsMemberAssertion (ca.AttributeType)) - continue; - results.Add ((m, ca)); - } - } - - foreach (var fd in type.GetFields()) { - if (fd is not EcmaField f) - continue; - - foreach (var ca in GetCustomAttributes(f)) { - if (!IsMemberAssertion (ca.AttributeType)) - continue; - results.Add ((f, ca)); - } - } - - foreach (var propertyHandle in type.MetadataReader.GetTypeDefinition (type.Handle).GetProperties ()) { - var p = new PropertyPseudoDesc (type, propertyHandle); - foreach (var ca in GetCustomAttributes(type, p)) { - if (!IsMemberAssertion (ca.AttributeType)) - continue; - results.Add ((p, ca)); - } - } - - foreach (var eventHandle in type.MetadataReader.GetTypeDefinition (type.Handle).GetEvents ()) { - var e = new EventPseudoDesc (type, eventHandle); - foreach (var ca in GetCustomAttributes(type, e)) { - if (!IsMemberAssertion (ca.AttributeType)) - continue; - results.Add ((e, ca)); - } - } - - foreach (var nested in type.GetNestedTypes()) { - CollectMemberAssertions (nested, results); - } - } - - private static IEnumerable GetCustomAttributes (EcmaType type) - { - var metadataReader = type.MetadataReader; - return GetCustomAttributes (metadataReader.GetTypeDefinition (type.Handle).GetCustomAttributes (), metadataReader, type.EcmaModule); - } - - private static IEnumerable GetCustomAttributes (EcmaMethod method) - { - var metadataReader = method.MetadataReader; - return GetCustomAttributes (metadataReader.GetMethodDefinition (method.Handle).GetCustomAttributes (), metadataReader, method.Module); - } - - private static IEnumerable GetCustomAttributes (EcmaField field) - { - var metadataReader = field.MetadataReader; - return GetCustomAttributes (metadataReader.GetFieldDefinition (field.Handle).GetCustomAttributes (), metadataReader, field.Module); - } - - private static IEnumerable GetCustomAttributes (EcmaType type, PropertyPseudoDesc prop) - { - return GetCustomAttributes (prop.GetCustomAttributes, type.MetadataReader, type.EcmaModule); - } - - private static IEnumerable GetCustomAttributes (EcmaType type, EventPseudoDesc @event) - { - return GetCustomAttributes (@event.GetCustomAttributes, type.MetadataReader, type.EcmaModule); - } - - private static IEnumerable GetCustomAttributes(CustomAttributeHandleCollection attributeHandles, MetadataReader metadataReader, EcmaModule module) - { - foreach (var attributeHandle in attributeHandles) { - if (!metadataReader.GetAttributeTypeAndConstructor (attributeHandle, out var attributeType, out _)) - continue; - - if (module.GetType (attributeType) is not MetadataType attributeMetadataType) - continue; - - yield return - new CustomAttribute () { - AttributeType = attributeMetadataType, - Value = metadataReader.GetCustomAttribute (attributeHandle).DecodeValue (new CustomAttributeTypeProvider (module)) - }; - } - } - } + public class MemberAssertionsCollector : IEnumerable + { + public struct CustomAttribute + { + public MetadataType AttributeType; + public CustomAttributeValue Value; + + public override string ToString() => AttributeType.ToString(); + } + + public MemberAssertionsCollector(Type type) + { + this.type = type; + TypeSystemContext = CreateTypeSystemContext(); + } + + private CompilerTypeSystemContext TypeSystemContext; + private readonly Type type; + + private CompilerTypeSystemContext CreateTypeSystemContext() + { + TrimmingDriver.ComputeDefaultOptions(out var targetOS, out var targetArchitecture); + var targetDetails = new TargetDetails(targetArchitecture, targetOS, TargetAbi.NativeAot); + CompilerTypeSystemContext typeSystemContext = + new CompilerTypeSystemContext(targetDetails, SharedGenericsMode.CanonicalReferenceTypes, DelegateFeature.All); + typeSystemContext.InputFilePaths = new Dictionary() { + { type.Assembly.GetName().Name!, type.Assembly.Location } + }; + Dictionary references = new Dictionary(); + foreach (Assembly assembly in AssemblyLoadContext.Default.Assemblies) + { + references.Add(assembly.GetName().Name!, assembly.Location!); + } + typeSystemContext.ReferenceFilePaths = references; + typeSystemContext.SetSystemModule(typeSystemContext.GetModuleForSimpleName(TrimmingDriver.DefaultSystemModule)); + + return typeSystemContext; + } + + internal IEnumerable<(TypeSystemEntity member, CustomAttribute ca)> GetMemberAssertions(Type type) + { + var module = TypeSystemContext.GetModuleFromPath(type.Assembly.Location); + var t = module.GetType(type.Namespace, type.Name, throwIfNotFound: false); + if (t == null) + throw new InvalidOperationException($"type {type} not found in {module}"); + var results = new List<(TypeSystemEntity, CustomAttribute)>(); + CollectMemberAssertions(t, results); + return results; + } + + public IEnumerable GetMemberAssertionsData() + { + return GetMemberAssertions(type).Select(v => new object[] { v.member, v.ca }); + } + + public IEnumerator GetEnumerator() => GetMemberAssertionsData().GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); + + private static bool IsMemberAssertion(MetadataType attributeType) + { + if (attributeType == null) + return false; + + if (attributeType.Namespace != "Mono.Linker.Tests.Cases.Expectations.Assertions") + return false; + + MetadataType t = attributeType; + while (t != null) + { + if (t.Name == nameof(BaseMemberAssertionAttribute)) + return true; + + t = t.MetadataBaseType; + } + + return false; + } + + private static void CollectMemberAssertions(MetadataType metadataType, List<(TypeSystemEntity, CustomAttribute)> results) + { + if (metadataType is not EcmaType type) + return; + + foreach (var ca in GetCustomAttributes(type)) + { + if (!IsMemberAssertion(ca.AttributeType)) + continue; + results.Add((type, ca)); + } + + foreach (var md in type.GetMethods()) + { + if (md is not EcmaMethod m) + continue; + + foreach (var ca in GetCustomAttributes(m)) + { + if (!IsMemberAssertion(ca.AttributeType)) + continue; + results.Add((m, ca)); + } + } + + foreach (var fd in type.GetFields()) + { + if (fd is not EcmaField f) + continue; + + foreach (var ca in GetCustomAttributes(f)) + { + if (!IsMemberAssertion(ca.AttributeType)) + continue; + results.Add((f, ca)); + } + } + + foreach (var propertyHandle in type.MetadataReader.GetTypeDefinition(type.Handle).GetProperties()) + { + var p = new PropertyPseudoDesc(type, propertyHandle); + foreach (var ca in GetCustomAttributes(type, p)) + { + if (!IsMemberAssertion(ca.AttributeType)) + continue; + results.Add((p, ca)); + } + } + + foreach (var eventHandle in type.MetadataReader.GetTypeDefinition(type.Handle).GetEvents()) + { + var e = new EventPseudoDesc(type, eventHandle); + foreach (var ca in GetCustomAttributes(type, e)) + { + if (!IsMemberAssertion(ca.AttributeType)) + continue; + results.Add((e, ca)); + } + } + + foreach (var nested in type.GetNestedTypes()) + { + CollectMemberAssertions(nested, results); + } + } + + private static IEnumerable GetCustomAttributes(EcmaType type) + { + var metadataReader = type.MetadataReader; + return GetCustomAttributes(metadataReader.GetTypeDefinition(type.Handle).GetCustomAttributes(), metadataReader, type.EcmaModule); + } + + private static IEnumerable GetCustomAttributes(EcmaMethod method) + { + var metadataReader = method.MetadataReader; + return GetCustomAttributes(metadataReader.GetMethodDefinition(method.Handle).GetCustomAttributes(), metadataReader, method.Module); + } + + private static IEnumerable GetCustomAttributes(EcmaField field) + { + var metadataReader = field.MetadataReader; + return GetCustomAttributes(metadataReader.GetFieldDefinition(field.Handle).GetCustomAttributes(), metadataReader, field.Module); + } + + private static IEnumerable GetCustomAttributes(EcmaType type, PropertyPseudoDesc prop) + { + return GetCustomAttributes(prop.GetCustomAttributes, type.MetadataReader, type.EcmaModule); + } + + private static IEnumerable GetCustomAttributes(EcmaType type, EventPseudoDesc @event) + { + return GetCustomAttributes(@event.GetCustomAttributes, type.MetadataReader, type.EcmaModule); + } + + private static IEnumerable GetCustomAttributes(CustomAttributeHandleCollection attributeHandles, MetadataReader metadataReader, EcmaModule module) + { + foreach (var attributeHandle in attributeHandles) + { + if (!metadataReader.GetAttributeTypeAndConstructor(attributeHandle, out var attributeType, out _)) + continue; + + if (module.GetType(attributeType) is not MetadataType attributeMetadataType) + continue; + + yield return + new CustomAttribute() + { + AttributeType = attributeMetadataType, + Value = metadataReader.GetCustomAttribute(attributeHandle).DecodeValue(new CustomAttributeTypeProvider(module)) + }; + } + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/NameUtils.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/NameUtils.cs index 68c4006eb65303..53a13f821c8faa 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/NameUtils.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/NameUtils.cs @@ -11,74 +11,83 @@ namespace Mono.Linker.Tests.TestCasesRunner { - internal static class NameUtils - { - internal static string? GetActualOriginDisplayName (TypeSystemEntity? entity) => entity switch { - DefType defType => TrimAssemblyNamePrefix (defType.GetDisplayName ()), - MethodDesc method => TrimAssemblyNamePrefix (method.GetDisplayName ()), - FieldDesc field => TrimAssemblyNamePrefix (field.ToString ()), - ModuleDesc module => module.Assembly.GetName ().Name, - _ => null - }; + internal static class NameUtils + { + internal static string? GetActualOriginDisplayName(TypeSystemEntity? entity) => entity switch + { + DefType defType => TrimAssemblyNamePrefix(defType.GetDisplayName()), + MethodDesc method => TrimAssemblyNamePrefix(method.GetDisplayName()), + FieldDesc field => TrimAssemblyNamePrefix(field.ToString()), + ModuleDesc module => module.Assembly.GetName().Name, + _ => null + }; - private static string? TrimAssemblyNamePrefix (string? name) - { - if (name == null) - return null; + private static string? TrimAssemblyNamePrefix(string? name) + { + if (name == null) + return null; - if (name.StartsWith ('[')) { - int i = name.IndexOf (']'); - if (i > 0) { - return name.Substring (i + 1); - } - } + if (name.StartsWith('[')) + { + int i = name.IndexOf(']'); + if (i > 0) + { + return name.Substring(i + 1); + } + } - return name; - } + return name; + } - internal static string GetExpectedOriginDisplayName (ICustomAttributeProvider provider) => - ConvertSignatureToIlcFormat (provider switch { - MethodDefinition method => method.GetDisplayName (), - FieldDefinition field => field.GetDisplayName (), - TypeDefinition type => type.GetDisplayName (), - IMemberDefinition member => member.FullName, - AssemblyDefinition asm => asm.Name.Name, - _ => throw new NotImplementedException () - }); + internal static string GetExpectedOriginDisplayName(ICustomAttributeProvider provider) => + ConvertSignatureToIlcFormat(provider switch + { + MethodDefinition method => method.GetDisplayName(), + FieldDefinition field => field.GetDisplayName(), + TypeDefinition type => type.GetDisplayName(), + IMemberDefinition member => member.FullName, + AssemblyDefinition asm => asm.Name.Name, + _ => throw new NotImplementedException() + }); - internal static string ConvertSignatureToIlcFormat (string value) - { - if (value.Contains ('(') || value.Contains ('<')) { - value = value.Replace (", ", ","); - } + internal static string ConvertSignatureToIlcFormat(string value) + { + if (value.Contains('(') || value.Contains('<')) + { + value = value.Replace(", ", ","); + } - if (value.Contains ('/')) { - value = value.Replace ('/', '+'); - } + if (value.Contains('/')) + { + value = value.Replace('/', '+'); + } - // Split it into . separated parts and if one is ending with > rewrite it to `1 format - // ILC folows the reflection format which doesn't actually use generic instantiations on anything but the last type - // in nested hierarchy - it's difficult to replicate this with Cecil as it has different representation so just strip that info - var parts = value.Split ('.'); - StringBuilder sb = new StringBuilder (); - foreach (var part in parts) { - if (sb.Length > 0) - sb.Append ('.'); + // Split it into . separated parts and if one is ending with > rewrite it to `1 format + // ILC folows the reflection format which doesn't actually use generic instantiations on anything but the last type + // in nested hierarchy - it's difficult to replicate this with Cecil as it has different representation so just strip that info + var parts = value.Split('.'); + StringBuilder sb = new StringBuilder(); + foreach (var part in parts) + { + if (sb.Length > 0) + sb.Append('.'); - if (part.EndsWith ('>')) { - int i = part.LastIndexOf ('<'); - if (i >= 0) { - sb.Append (part.AsSpan (0, i)); - sb.Append ('`'); - sb.Append (part.Substring (i + 1).Where (c => c == ',').Count () + 1); - continue; - } - } + if (part.EndsWith('>')) + { + int i = part.LastIndexOf('<'); + if (i >= 0) + { + sb.Append(part.AsSpan(0, i)); + sb.Append('`'); + sb.Append(part.Substring(i + 1).Where(c => c == ',').Count() + 1); + continue; + } + } - sb.Append (part); - } + sb.Append(part); + } - return sb.ToString (); - } - } + return sb.ToString(); + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ResultChecker.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ResultChecker.cs index a6eb6007661f62..673df2e9a11500 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ResultChecker.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ResultChecker.cs @@ -18,485 +18,535 @@ namespace Mono.Linker.Tests.TestCasesRunner { - public class ResultChecker - { - private readonly BaseAssemblyResolver _originalsResolver; - private readonly ReaderParameters _originalReaderParameters; - private readonly ReaderParameters _linkedReaderParameters; - - public ResultChecker () - : this (new TestCaseAssemblyResolver (), - new ReaderParameters { - SymbolReaderProvider = new DefaultSymbolReaderProvider (false) - }, - new ReaderParameters { - SymbolReaderProvider = new DefaultSymbolReaderProvider (false) - }) - { - } - - public ResultChecker (BaseAssemblyResolver originalsResolver, - ReaderParameters originalReaderParameters, ReaderParameters linkedReaderParameters) - { - _originalsResolver = originalsResolver; - _originalReaderParameters = originalReaderParameters; - _linkedReaderParameters = linkedReaderParameters; - } - - public virtual void Check (TrimmedTestCaseResult testResult) - { - InitializeResolvers (testResult); - - try { - var original = ResolveOriginalsAssembly (testResult.ExpectationsAssemblyPath.FileNameWithoutExtension); - - if (!HasAttribute (original, nameof (NoLinkedOutputAttribute))) { - // TODO Validate presence of the main assembly - if it makes sense (reflection only somehow) - - // IL verification is impossible for NativeAOT since there's no IL output - // if (ShouldValidateIL (original)) - // VerifyIL (); - - InitialChecking (testResult, original); - - PerformOutputAssemblyChecks (original, testResult); - PerformOutputSymbolChecks (original, testResult); - - if (!HasActiveSkipKeptItemsValidationAttribute (testResult.TestCase.FindTypeDefinition (original))) { - CreateAssemblyChecker (original, testResult).Verify (); - } - } - - AdditionalChecking (testResult, original); - } finally { - _originalsResolver.Dispose (); - } - - bool HasActiveSkipKeptItemsValidationAttribute(ICustomAttributeProvider provider) - { - if (TryGetCustomAttribute(provider, nameof(SkipKeptItemsValidationAttribute), out var attribute)) { - object? by = attribute.GetPropertyValue (nameof (SkipKeptItemsValidationAttribute.By)); - return by is null ? true : ((Tool) by).HasFlag (Tool.NativeAot); - } - - return false; - } - } - - protected virtual AssemblyChecker CreateAssemblyChecker (AssemblyDefinition original, TrimmedTestCaseResult testResult) - { - return new AssemblyChecker (_originalsResolver, _originalReaderParameters, original, testResult); - } - - private void InitializeResolvers (TrimmedTestCaseResult linkedResult) - { - _originalsResolver.AddSearchDirectory (linkedResult.ExpectationsAssemblyPath.Parent.ToString ()); - } - - protected AssemblyDefinition ResolveOriginalsAssembly (string assemblyName) - { - var cleanAssemblyName = assemblyName; - if (assemblyName.EndsWith (".exe") || assemblyName.EndsWith (".dll")) - cleanAssemblyName = Path.GetFileNameWithoutExtension (assemblyName); - return _originalsResolver.Resolve (new AssemblyNameReference (cleanAssemblyName, null), _originalReaderParameters); - } - - private static void PerformOutputAssemblyChecks (AssemblyDefinition original, TrimmedTestCaseResult testResult) - { - var assembliesToCheck = original.MainModule.Types.SelectMany (t => t.CustomAttributes).Where (ExpectationsProvider.IsAssemblyAssertion); - var actionAssemblies = new HashSet (); - //bool trimModeIsCopy = false; - - foreach (var assemblyAttr in assembliesToCheck) { - var name = (string) assemblyAttr.ConstructorArguments.First ().Value; - name = Path.GetFileNameWithoutExtension (name); + public class ResultChecker + { + private readonly BaseAssemblyResolver _originalsResolver; + private readonly ReaderParameters _originalReaderParameters; + private readonly ReaderParameters _linkedReaderParameters; + + public ResultChecker() + : this(new TestCaseAssemblyResolver(), + new ReaderParameters + { + SymbolReaderProvider = new DefaultSymbolReaderProvider(false) + }, + new ReaderParameters + { + SymbolReaderProvider = new DefaultSymbolReaderProvider(false) + }) + { + } + + public ResultChecker(BaseAssemblyResolver originalsResolver, + ReaderParameters originalReaderParameters, ReaderParameters linkedReaderParameters) + { + _originalsResolver = originalsResolver; + _originalReaderParameters = originalReaderParameters; + _linkedReaderParameters = linkedReaderParameters; + } + + public virtual void Check(TrimmedTestCaseResult testResult) + { + InitializeResolvers(testResult); + + try + { + var original = ResolveOriginalsAssembly(testResult.ExpectationsAssemblyPath.FileNameWithoutExtension); + + if (!HasAttribute(original, nameof(NoLinkedOutputAttribute))) + { + // TODO Validate presence of the main assembly - if it makes sense (reflection only somehow) + + // IL verification is impossible for NativeAOT since there's no IL output + // if (ShouldValidateIL(original)) + // VerifyIL(); + + InitialChecking(testResult, original); + + PerformOutputAssemblyChecks(original, testResult); + PerformOutputSymbolChecks(original, testResult); + + if (!HasActiveSkipKeptItemsValidationAttribute(testResult.TestCase.FindTypeDefinition(original))) + { + CreateAssemblyChecker(original, testResult).Verify(); + } + } + + AdditionalChecking(testResult, original); + } + finally + { + _originalsResolver.Dispose(); + } + } + + internal static bool HasActiveSkipKeptItemsValidationAttribute(ICustomAttributeProvider provider) + { + if (TryGetCustomAttribute(provider, nameof(SkipKeptItemsValidationAttribute), out var attribute)) + { + object? by = attribute.GetPropertyValue(nameof(SkipKeptItemsValidationAttribute.By)); + return by is null ? true : ((Tool)by).HasFlag(Tool.NativeAot); + } + + return false; + } + + protected virtual AssemblyChecker CreateAssemblyChecker(AssemblyDefinition original, TrimmedTestCaseResult testResult) + { + return new AssemblyChecker(_originalsResolver, _originalReaderParameters, original, testResult); + } + + private void InitializeResolvers(TrimmedTestCaseResult linkedResult) + { + _originalsResolver.AddSearchDirectory(linkedResult.ExpectationsAssemblyPath.Parent.ToString()); + } + + protected AssemblyDefinition ResolveOriginalsAssembly(string assemblyName) + { + var cleanAssemblyName = assemblyName; + if (assemblyName.EndsWith(".exe") || assemblyName.EndsWith(".dll")) + cleanAssemblyName = Path.GetFileNameWithoutExtension(assemblyName); + return _originalsResolver.Resolve(new AssemblyNameReference(cleanAssemblyName, null), _originalReaderParameters); + } + + private static void PerformOutputAssemblyChecks(AssemblyDefinition original, TrimmedTestCaseResult testResult) + { + var assembliesToCheck = original.MainModule.Types.SelectMany(t => t.CustomAttributes).Where(ExpectationsProvider.IsAssemblyAssertion); + var actionAssemblies = new HashSet(); + //bool trimModeIsCopy = false; + + foreach (var assemblyAttr in assembliesToCheck) + { + var name = (string)assemblyAttr.ConstructorArguments.First().Value; + name = Path.GetFileNameWithoutExtension(name); #if false - if (assemblyAttr.AttributeType.Name == nameof (RemovedAssemblyAttribute)) - Assert.IsFalse (expectedPath.FileExists (), $"Expected the assembly {name} to not exist in {outputDirectory}, but it did"); - else if (assemblyAttr.AttributeType.Name == nameof (KeptAssemblyAttribute)) - Assert.IsTrue (expectedPath.FileExists (), $"Expected the assembly {name} to exist in {outputDirectory}, but it did not"); - else if (assemblyAttr.AttributeType.Name == nameof (SetupLinkerActionAttribute)) { - string assemblyName = (string) assemblyAttr.ConstructorArguments[1].Value; - if ((string) assemblyAttr.ConstructorArguments[0].Value == "copy") { - VerifyCopyAssemblyIsKeptUnmodified (outputDirectory, assemblyName + (assemblyName == "test" ? ".exe" : ".dll")); - } - - actionAssemblies.Add (assemblyName); - } else if (assemblyAttr.AttributeType.Name == nameof (SetupLinkerTrimModeAttribute)) { - // We delay checking that everything was copied after processing all assemblies - // with a specific action, since assembly action wins over trim mode. - if ((string) assemblyAttr.ConstructorArguments[0].Value == "copy") - trimModeIsCopy = true; - } else - throw new NotImplementedException ($"Unknown assembly assertion of type {assemblyAttr.AttributeType}"); + if (assemblyAttr.AttributeType.Name == nameof(RemovedAssemblyAttribute)) + Assert.IsFalse(expectedPath.FileExists(), $"Expected the assembly {name} to not exist in {outputDirectory}, but it did"); + else if (assemblyAttr.AttributeType.Name == nameof(KeptAssemblyAttribute)) + Assert.IsTrue(expectedPath.FileExists(), $"Expected the assembly {name} to exist in {outputDirectory}, but it did not"); + else if (assemblyAttr.AttributeType.Name == nameof(SetupLinkerActionAttribute)) { + string assemblyName = (string) assemblyAttr.ConstructorArguments[1].Value; + if ((string) assemblyAttr.ConstructorArguments[0].Value == "copy") { + VerifyCopyAssemblyIsKeptUnmodified(outputDirectory, assemblyName + (assemblyName == "test" ? ".exe" : ".dll")); + } + + actionAssemblies.Add(assemblyName); + } else if (assemblyAttr.AttributeType.Name == nameof(SetupLinkerTrimModeAttribute)) { + // We delay checking that everything was copied after processing all assemblies + // with a specific action, since assembly action wins over trim mode. + if ((string) assemblyAttr.ConstructorArguments[0].Value == "copy") + trimModeIsCopy = true; + } else + throw new NotImplementedException($"Unknown assembly assertion of type {assemblyAttr.AttributeType}"); #endif - } + } #if false - if (trimModeIsCopy) { - foreach (string assemblyName in Directory.GetFiles (Directory.GetParent (outputDirectory).ToString (), "input")) { - var fileInfo = new FileInfo (assemblyName); - if (fileInfo.Extension == ".dll" && !actionAssemblies.Contains (assemblyName)) - VerifyCopyAssemblyIsKeptUnmodified (outputDirectory, assemblyName + (assemblyName == "test" ? ".exe" : ".dll")); - } - } + if (trimModeIsCopy) + { + foreach (string assemblyName in Directory.GetFiles(Directory.GetParent(outputDirectory).ToString(), "input")) { + var fileInfo = new FileInfo(assemblyName); + if (fileInfo.Extension == ".dll" && !actionAssemblies.Contains(assemblyName)) + VerifyCopyAssemblyIsKeptUnmodified(outputDirectory, assemblyName + (assemblyName == "test" ? ".exe" : ".dll")); + } + } #endif - } + } #pragma warning disable IDE0060 // Remove unused parameter - private static void PerformOutputSymbolChecks (AssemblyDefinition original, TrimmedTestCaseResult testResult) + private static void PerformOutputSymbolChecks(AssemblyDefinition original, TrimmedTestCaseResult testResult) #pragma warning restore IDE0060 // Remove unused parameter - { - // While NativeAOT has symbols, verifying them is rather difficult - } - - protected virtual void AdditionalChecking (TrimmedTestCaseResult linkResult, AssemblyDefinition original) - { - bool checkRemainingErrors = !HasAttribute (linkResult.TestCase.FindTypeDefinition (original), nameof (SkipRemainingErrorsValidationAttribute)); - VerifyLoggedMessages (original, linkResult.Logger, checkRemainingErrors); - } - - private static bool IsProducedByNativeAOT (CustomAttribute attr) - { - if (attr.ConstructorArguments.Count > 2 && attr.ConstructorArguments[^2].Type.Name == "Tool") - return ((Tool)attr.ConstructorArguments[^2].Value).HasFlag(Tool.NativeAot); - var producedBy = attr.GetPropertyValue ("ProducedBy"); - return producedBy is null ? true : ((Tool) producedBy).HasFlag (Tool.NativeAot); - } - - private static IEnumerable GetAttributeProviders (AssemblyDefinition assembly) - { - foreach (var testType in assembly.AllDefinedTypes ()) { - foreach (var provider in testType.AllMembers ()) - yield return provider; - - yield return testType; - } - - foreach (var module in assembly.Modules) - yield return module; - - yield return assembly; - } - - protected virtual void InitialChecking (TrimmedTestCaseResult testResult, AssemblyDefinition original) - { - // PE verifier is done here in ILLinker, but that's not possible with NativeAOT - } - - private void VerifyLoggedMessages (AssemblyDefinition original, TrimmingTestLogger logger, bool checkRemainingErrors) - { - List loggedMessages = logger.GetLoggedMessages (); - List<(ICustomAttributeProvider, CustomAttribute)> expectedNoWarningsAttributes = new (); - foreach (var attrProvider in GetAttributeProviders (original)) { - foreach (var attr in attrProvider.CustomAttributes) { - if (!IsProducedByNativeAOT (attr)) - continue; - - switch (attr.AttributeType.Name) { - - case nameof (LogContainsAttribute): { - var expectedMessage = (string) attr.ConstructorArguments[0].Value; - - List matchedMessages; - if ((bool) attr.ConstructorArguments[1].Value) - matchedMessages = loggedMessages.Where (m => Regex.IsMatch (m.ToString (), expectedMessage)).ToList (); - else - matchedMessages = loggedMessages.Where (m => MessageTextContains (m.ToString (), expectedMessage)).ToList (); - Assert.True ( - matchedMessages.Count > 0, - $"Expected to find logged message matching `{expectedMessage}`, but no such message was found.{Environment.NewLine}Logged messages:{Environment.NewLine}{string.Join (Environment.NewLine, loggedMessages)}"); - - foreach (var matchedMessage in matchedMessages) - loggedMessages.Remove (matchedMessage); - } - break; - - case nameof (LogDoesNotContainAttribute): { - var unexpectedMessage = (string) attr.ConstructorArguments[0].Value; - foreach (var loggedMessage in loggedMessages) { - var isLogged = () => { - if ((bool) attr.ConstructorArguments[1].Value) - return !Regex.IsMatch (loggedMessage.ToString (), unexpectedMessage); - return !MessageTextContains (loggedMessage.ToString (), unexpectedMessage); - }; - - Assert.True ( - isLogged (), - $"Expected to not find logged message matching `{unexpectedMessage}`, but found:{Environment.NewLine}{loggedMessage}{Environment.NewLine}Logged messages:{Environment.NewLine}{string.Join (Environment.NewLine, loggedMessages)}"); - } - } - break; - - case nameof (ExpectedWarningAttribute) or nameof(UnexpectedWarningAttribute): { - var expectedWarningCode = (string) attr.GetConstructorArgumentValue (0); - if (!expectedWarningCode.StartsWith ("IL")) { - Assert.Fail ($"The warning code specified in {attr.AttributeType.Name} must start with the 'IL' prefix. Specified value: '{expectedWarningCode}'."); - } - IEnumerable expectedMessageContains = attr.Constructor.Parameters switch - { - // ExpectedWarningAttribute(string warningCode, params string[] expectedMessages) - // ExpectedWarningAttribute(string warningCode, string[] expectedMessages, Tool producedBy, string issueLink) - [_, { ParameterType.IsArray: true }, ..] - => ((CustomAttributeArgument[])attr.ConstructorArguments[1].Value) - .Select(caa => (string)caa.Value), - // ExpectedWarningAttribute(string warningCode, string expectedMessage1, string expectedMessage2, Tool producedBy, string issueLink) - [_, { ParameterType.Name: "String" }, { ParameterType.Name: "String" }, { ParameterType.Name: "Tool" }, _] - => [(string)attr.GetConstructorArgumentValue(1), (string)attr.GetConstructorArgumentValue(2)], - // ExpectedWarningAttribute(string warningCode, string expectedMessage, Tool producedBy, string issueLink) - [_, { ParameterType.Name: "String" }, { ParameterType.Name: "Tool" }, _] - => [(string)attr.GetConstructorArgumentValue(1)], - // ExpectedWarningAttribute(string warningCode, Tool producedBy, string issueLink) - [_, { ParameterType.Name: "Tool" }, _] - => [], - _ => throw new UnreachableException(), - }; - string fileName = (string) attr.GetPropertyValue ("FileName")!; - int? sourceLine = (int?) attr.GetPropertyValue ("SourceLine"); - int? sourceColumn = (int?) attr.GetPropertyValue ("SourceColumn"); - bool? isCompilerGeneratedCode = (bool?) attr.GetPropertyValue ("CompilerGeneratedCode"); - - int expectedWarningCodeNumber = int.Parse (expectedWarningCode.Substring (2)); - string? expectedOrigin = null; - bool expectedWarningFound = false; - - foreach (var loggedMessage in loggedMessages) { - if (loggedMessage.Category != MessageCategory.Warning || loggedMessage.Code != expectedWarningCodeNumber) - continue; - - bool messageNotFound = false; - foreach (var expectedMessage in expectedMessageContains) { - if (!MessageTextContains (loggedMessage.Text, expectedMessage)) { - messageNotFound = true; - break; - } - } - if (messageNotFound) - continue; - - if (fileName != null) { - if (loggedMessage.Origin == null) - continue; - - var actualOrigin = loggedMessage.Origin.Value; - if (actualOrigin.FileName != null) { - // Note: string.Compare(string, StringComparison) doesn't exist in .NET Framework API set - if (actualOrigin.FileName.IndexOf (fileName, StringComparison.OrdinalIgnoreCase) < 0) - continue; - - if (sourceLine != null && loggedMessage.Origin?.SourceLine != sourceLine.Value) - continue; - - if (sourceColumn != null && loggedMessage.Origin?.SourceColumn != sourceColumn.Value) - continue; - } else { - // The warning was logged with member/ILoffset, so it didn't have line/column info filled - // but it will be computed from PDBs, so instead compare it in a string representation - if (expectedOrigin == null) { - expectedOrigin = fileName; - if (sourceLine.HasValue) { - expectedOrigin += "(" + sourceLine.Value; - if (sourceColumn.HasValue) - expectedOrigin += "," + sourceColumn.Value; - expectedOrigin += ")"; - } - } - - string actualOriginString = actualOrigin.ToString () ?? ""; - if (!actualOriginString.EndsWith (expectedOrigin, StringComparison.OrdinalIgnoreCase)) - continue; - } - } else if (isCompilerGeneratedCode == true) { - if (loggedMessage.Origin?.MemberDefinition is not MethodDesc methodDesc) - continue; - - if (attrProvider is IMemberDefinition expectedMember) { - string? actualName = NameUtils.GetActualOriginDisplayName (methodDesc); - string expectedTypeName = NameUtils.GetExpectedOriginDisplayName (expectedMember.DeclaringType); - if (actualName?.Contains (expectedTypeName) == true && - actualName?.Contains ("<" + expectedMember.Name + ">") == true) { - expectedWarningFound = true; - loggedMessages.Remove (loggedMessage); - break; - } - if (actualName?.StartsWith (expectedTypeName) == true) { - if (actualName?.Contains (".cctor") == true && - (expectedMember is FieldDefinition || expectedMember is PropertyDefinition)) { - expectedWarningFound = true; - loggedMessages.Remove (loggedMessage); - break; - } - if (methodDesc.IsConstructor && - (expectedMember is FieldDefinition || expectedMember is PropertyDefinition || new AssemblyQualifiedToken (methodDesc.OwningType).Equals(new AssemblyQualifiedToken (expectedMember)))) { - expectedWarningFound = true; - loggedMessages.Remove (loggedMessage); - break; - } - } - } else if (attrProvider is AssemblyDefinition expectedAssembly) { - // Allow assembly-level attributes to match warnings from compiler-generated Main - if (NameUtils.GetActualOriginDisplayName (methodDesc) == "Program.
$(String[])") { - expectedWarningFound = true; - loggedMessages.Remove (loggedMessage); - break; - } - } - continue; - } else { - if (LogMessageHasSameOriginMember (loggedMessage, attrProvider)) { - expectedWarningFound = true; - loggedMessages.Remove (loggedMessage); - break; - } - continue; - } - - expectedWarningFound = true; - loggedMessages.Remove (loggedMessage); - break; - } - - var expectedOriginString = fileName == null - ? NameUtils.GetExpectedOriginDisplayName (attrProvider) + ": " - : ""; - - Assert.True (expectedWarningFound, - $"Expected to find warning: {(fileName != null ? fileName + (sourceLine != null ? $"({sourceLine},{sourceColumn})" : "") + ": " : "")}" + - $"warning {expectedWarningCode}: {expectedOriginString}" + - $"and message containing {string.Join (" ", expectedMessageContains.Select (m => "'" + m + "'"))}, " + - $"but no such message was found.{Environment.NewLine}Logged messages:{Environment.NewLine}{string.Join (Environment.NewLine, loggedMessages)}"); - } - break; - - case nameof (ExpectedNoWarningsAttribute): - // Postpone processing of negative checks, to make it possible to mark some warnings as expected (will be removed from the list above) - // and then do the negative check on the rest. - expectedNoWarningsAttributes.Add ((attrProvider, attr)); - break; - } - } - } - - foreach ((var attrProvider, var attr) in expectedNoWarningsAttributes) { - var unexpectedWarningCode = attr.ConstructorArguments.Count == 0 ? null : (string) attr.GetConstructorArgumentValue (0); - if (unexpectedWarningCode != null && !unexpectedWarningCode.StartsWith ("IL")) { - Assert.Fail ($"The warning code specified in ExpectedNoWarnings attribute must start with the 'IL' prefix. Specified value: '{unexpectedWarningCode}'."); - } - - int? unexpectedWarningCodeNumber = unexpectedWarningCode == null ? null : int.Parse (unexpectedWarningCode.Substring (2)); - - MessageContainer? unexpectedWarningMessage = null; - foreach (var mc in logger.GetLoggedMessages ()) { - if (mc.Category != MessageCategory.Warning) - continue; - - if (unexpectedWarningCodeNumber != null && unexpectedWarningCodeNumber.Value != mc.Code) - continue; - - // This is a hacky way to say anything in the "subtree" of the attrProvider - if (attrProvider is IMemberDefinition attrMember && (mc.Origin?.MemberDefinition is TypeSystemEntity member) && member.ToString ()?.Contains (attrMember.FullName) != true) - continue; - - unexpectedWarningMessage = mc; - break; - } - - Assert.False (unexpectedWarningMessage.HasValue, - $"Unexpected warning found: {unexpectedWarningMessage}"); - } - - if (checkRemainingErrors) { - var remainingErrors = loggedMessages.Where (m => Regex.IsMatch (m.ToString (), @".*(error | warning): \d{4}.*")); - Assert.False (remainingErrors.Any (), $"Found unexpected errors:{Environment.NewLine}{string.Join (Environment.NewLine, remainingErrors)}"); - } - - static bool LogMessageHasSameOriginMember (MessageContainer mc, ICustomAttributeProvider expectedOriginProvider) - { - var origin = mc.Origin; - Debug.Assert (origin != null); - if (origin?.MemberDefinition == null) - return false; - if (origin?.MemberDefinition is IAssemblyDesc asm) - return expectedOriginProvider is AssemblyDefinition expectedAsm && asm.GetName().Name == expectedAsm.Name.Name; - - if (expectedOriginProvider is not IMemberDefinition expectedOriginMember) - return false; - - var actualOriginToken = new AssemblyQualifiedToken (origin!.Value.MemberDefinition); - var expectedOriginToken = new AssemblyQualifiedToken (expectedOriginMember); - if (actualOriginToken.Equals (expectedOriginToken)) - return true; - - var actualMember = origin.Value.MemberDefinition; - // Compensate for cases where for some reason the OM doesn't preserve the declaring types - // on certain things after trimming. - if (actualMember != null && GetOwningType (actualMember) == null && - GetMemberName (actualMember) == (expectedOriginProvider as IMemberDefinition)?.Name) - return true; - - return false; - } - - static TypeDesc? GetOwningType (TypeSystemEntity entity) => entity switch { - DefType defType => defType.ContainingType, - MethodDesc method => method.OwningType, - FieldDesc field => field.OwningType, - _ => null - }; - - static string? GetMemberName (TypeSystemEntity? entity) => entity switch { - DefType defType => defType.Name, - MethodDesc method => method.Name, - FieldDesc field => field.Name, - _ => null - }; - - static bool MessageTextContains (string message, string value) - { - // This is a workaround for different formatting of methods between ilc and illink/analyzer - // Sometimes they're written with a space after comma and sometimes without - // Method(String,String) - ilc - // Method(String, String) - illink/analyzer - return message.Contains (value) || message.Contains (NameUtils.ConvertSignatureToIlcFormat (value)); - } - } - - private static bool HasAttribute (ICustomAttributeProvider caProvider, string attributeName) - { - return TryGetCustomAttribute (caProvider, attributeName, out var _); - } + { + // While NativeAOT has symbols, verifying them is rather difficult + } + + protected virtual void AdditionalChecking(TrimmedTestCaseResult linkResult, AssemblyDefinition original) + { + bool checkRemainingErrors = !HasAttribute(linkResult.TestCase.FindTypeDefinition(original), nameof(SkipRemainingErrorsValidationAttribute)); + VerifyLoggedMessages(original, linkResult.Logger, checkRemainingErrors); + } + + private static bool IsProducedByNativeAOT(CustomAttribute attr) + { + if (attr.ConstructorArguments.Count > 2 && attr.ConstructorArguments[^2].Type.Name == "Tool") + return ((Tool)attr.ConstructorArguments[^2].Value).HasFlag(Tool.NativeAot); + var producedBy = attr.GetPropertyValue("ProducedBy"); + return producedBy is null ? true : ((Tool)producedBy).HasFlag(Tool.NativeAot); + } + + private static IEnumerable GetAttributeProviders(AssemblyDefinition assembly) + { + foreach (var testType in assembly.AllDefinedTypes()) + { + foreach (var provider in testType.AllMembers()) + yield return provider; + + yield return testType; + } + + foreach (var module in assembly.Modules) + yield return module; + + yield return assembly; + } + + protected virtual void InitialChecking(TrimmedTestCaseResult testResult, AssemblyDefinition original) + { + // PE verifier is done here in ILLinker, but that's not possible with NativeAOT + } + + private void VerifyLoggedMessages(AssemblyDefinition original, TrimmingTestLogger logger, bool checkRemainingErrors) + { + List loggedMessages = logger.GetLoggedMessages(); + List<(ICustomAttributeProvider, CustomAttribute)> expectedNoWarningsAttributes = new(); + foreach (var attrProvider in GetAttributeProviders(original)) + { + foreach (var attr in attrProvider.CustomAttributes) + { + if (!IsProducedByNativeAOT(attr)) + continue; + + switch (attr.AttributeType.Name) + { + + case nameof(LogContainsAttribute): + { + var expectedMessage = (string)attr.ConstructorArguments[0].Value; + + List matchedMessages; + if ((bool)attr.ConstructorArguments[1].Value) + matchedMessages = loggedMessages.Where(m => Regex.IsMatch(m.ToString(), expectedMessage)).ToList(); + else + matchedMessages = loggedMessages.Where(m => MessageTextContains(m.ToString(), expectedMessage)).ToList(); + Assert.True( + matchedMessages.Count > 0, + $"Expected to find logged message matching `{expectedMessage}`, but no such message was found.{Environment.NewLine}Logged messages:{Environment.NewLine}{string.Join(Environment.NewLine, loggedMessages)}"); + + foreach (var matchedMessage in matchedMessages) + loggedMessages.Remove(matchedMessage); + } + break; + + case nameof(LogDoesNotContainAttribute): + { + var unexpectedMessage = (string)attr.ConstructorArguments[0].Value; + foreach (var loggedMessage in loggedMessages) + { + var isLogged = () => + { + if ((bool)attr.ConstructorArguments[1].Value) + return !Regex.IsMatch(loggedMessage.ToString(), unexpectedMessage); + return !MessageTextContains(loggedMessage.ToString(), unexpectedMessage); + }; + + Assert.True( + isLogged(), + $"Expected to not find logged message matching `{unexpectedMessage}`, but found:{Environment.NewLine}{loggedMessage}{Environment.NewLine}Logged messages:{Environment.NewLine}{string.Join(Environment.NewLine, loggedMessages)}"); + } + } + break; + + case nameof(ExpectedWarningAttribute) or nameof(UnexpectedWarningAttribute): + { + var expectedWarningCode = (string)attr.GetConstructorArgumentValue(0); + if (!expectedWarningCode.StartsWith("IL")) + { + Assert.Fail($"The warning code specified in {attr.AttributeType.Name} must start with the 'IL' prefix. Specified value: '{expectedWarningCode}'."); + } + IEnumerable expectedMessageContains = attr.Constructor.Parameters switch + { + // ExpectedWarningAttribute(string warningCode, params string[] expectedMessages) + // ExpectedWarningAttribute(string warningCode, string[] expectedMessages, Tool producedBy, string issueLink) + [_, { ParameterType.IsArray: true }, ..] + => ((CustomAttributeArgument[])attr.ConstructorArguments[1].Value) + .Select(caa => (string)caa.Value), + // ExpectedWarningAttribute(string warningCode, string expectedMessage1, string expectedMessage2, Tool producedBy, string issueLink) + [_, { ParameterType.Name: "String" }, { ParameterType.Name: "String" }, { ParameterType.Name: "Tool" }, _] + => [(string)attr.GetConstructorArgumentValue(1), (string)attr.GetConstructorArgumentValue(2)], + // ExpectedWarningAttribute(string warningCode, string expectedMessage, Tool producedBy, string issueLink) + [_, { ParameterType.Name: "String" }, { ParameterType.Name: "Tool" }, _] + => [(string)attr.GetConstructorArgumentValue(1)], + // ExpectedWarningAttribute(string warningCode, Tool producedBy, string issueLink) + [_, { ParameterType.Name: "Tool" }, _] + => [], + _ => throw new UnreachableException(), + }; + string fileName = (string)attr.GetPropertyValue("FileName")!; + int? sourceLine = (int?)attr.GetPropertyValue("SourceLine"); + int? sourceColumn = (int?)attr.GetPropertyValue("SourceColumn"); + bool? isCompilerGeneratedCode = (bool?)attr.GetPropertyValue("CompilerGeneratedCode"); + + int expectedWarningCodeNumber = int.Parse(expectedWarningCode.Substring(2)); + string? expectedOrigin = null; + bool expectedWarningFound = false; + + foreach (var loggedMessage in loggedMessages) + { + if (loggedMessage.Category != MessageCategory.Warning || loggedMessage.Code != expectedWarningCodeNumber) + continue; + + bool messageNotFound = false; + foreach (var expectedMessage in expectedMessageContains) + { + if (!MessageTextContains(loggedMessage.Text, expectedMessage)) + { + messageNotFound = true; + break; + } + } + if (messageNotFound) + continue; + + if (fileName != null) + { + if (loggedMessage.Origin == null) + continue; + + var actualOrigin = loggedMessage.Origin.Value; + if (actualOrigin.FileName != null) + { + // Note: string.Compare(string, StringComparison) doesn't exist in .NET Framework API set + if (actualOrigin.FileName.IndexOf(fileName, StringComparison.OrdinalIgnoreCase) < 0) + continue; + + if (sourceLine != null && loggedMessage.Origin?.SourceLine != sourceLine.Value) + continue; + + if (sourceColumn != null && loggedMessage.Origin?.SourceColumn != sourceColumn.Value) + continue; + } + else + { + // The warning was logged with member/ILoffset, so it didn't have line/column info filled + // but it will be computed from PDBs, so instead compare it in a string representation + if (expectedOrigin == null) + { + expectedOrigin = fileName; + if (sourceLine.HasValue) + { + expectedOrigin += "(" + sourceLine.Value; + if (sourceColumn.HasValue) + expectedOrigin += "," + sourceColumn.Value; + expectedOrigin += ")"; + } + } + + string actualOriginString = actualOrigin.ToString() ?? ""; + if (!actualOriginString.EndsWith(expectedOrigin, StringComparison.OrdinalIgnoreCase)) + continue; + } + } + else if (isCompilerGeneratedCode == true) + { + if (loggedMessage.Origin?.MemberDefinition is not MethodDesc methodDesc) + continue; + + if (attrProvider is IMemberDefinition expectedMember) + { + string? actualName = NameUtils.GetActualOriginDisplayName(methodDesc); + string expectedTypeName = NameUtils.GetExpectedOriginDisplayName(expectedMember.DeclaringType); + if (actualName?.Contains(expectedTypeName) == true && + actualName?.Contains("<" + expectedMember.Name + ">") == true) + { + expectedWarningFound = true; + loggedMessages.Remove(loggedMessage); + break; + } + if (actualName?.StartsWith(expectedTypeName) == true) + { + if (actualName?.Contains(".cctor") == true && + (expectedMember is FieldDefinition || expectedMember is PropertyDefinition)) + { + expectedWarningFound = true; + loggedMessages.Remove(loggedMessage); + break; + } + if (methodDesc.IsConstructor && + (expectedMember is FieldDefinition || expectedMember is PropertyDefinition || new AssemblyQualifiedToken(methodDesc.OwningType).Equals(new AssemblyQualifiedToken(expectedMember)))) + { + expectedWarningFound = true; + loggedMessages.Remove(loggedMessage); + break; + } + } + } + else if (attrProvider is AssemblyDefinition expectedAssembly) + { + // Allow assembly-level attributes to match warnings from compiler-generated Main + if (NameUtils.GetActualOriginDisplayName(methodDesc) == "Program.
$(String[])") + { + expectedWarningFound = true; + loggedMessages.Remove(loggedMessage); + break; + } + } + continue; + } + else + { + if (LogMessageHasSameOriginMember(loggedMessage, attrProvider)) + { + expectedWarningFound = true; + loggedMessages.Remove(loggedMessage); + break; + } + continue; + } + + expectedWarningFound = true; + loggedMessages.Remove(loggedMessage); + break; + } + + var expectedOriginString = fileName == null + ? NameUtils.GetExpectedOriginDisplayName(attrProvider) + ": " + : ""; + + Assert.True(expectedWarningFound, + $"Expected to find warning: {(fileName != null ? fileName + (sourceLine != null ? $"({sourceLine},{sourceColumn})" : "") + ": " : "")}" + + $"warning {expectedWarningCode}: {expectedOriginString}" + + $"and message containing {string.Join(" ", expectedMessageContains.Select(m => "'" + m + "'"))}, " + + $"but no such message was found.{Environment.NewLine}Logged messages:{Environment.NewLine}{string.Join(Environment.NewLine, loggedMessages)}"); + } + break; + + case nameof(ExpectedNoWarningsAttribute): + // Postpone processing of negative checks, to make it possible to mark some warnings as expected (will be removed from the list above) + // and then do the negative check on the rest. + expectedNoWarningsAttributes.Add((attrProvider, attr)); + break; + } + } + } + + foreach ((var attrProvider, var attr) in expectedNoWarningsAttributes) + { + var unexpectedWarningCode = attr.ConstructorArguments.Count == 0 ? null : (string)attr.GetConstructorArgumentValue(0); + if (unexpectedWarningCode != null && !unexpectedWarningCode.StartsWith("IL")) + { + Assert.Fail($"The warning code specified in ExpectedNoWarnings attribute must start with the 'IL' prefix. Specified value: '{unexpectedWarningCode}'."); + } + + int? unexpectedWarningCodeNumber = unexpectedWarningCode == null ? null : int.Parse(unexpectedWarningCode.Substring(2)); + + MessageContainer? unexpectedWarningMessage = null; + foreach (var mc in logger.GetLoggedMessages()) + { + if (mc.Category != MessageCategory.Warning) + continue; + + if (unexpectedWarningCodeNumber != null && unexpectedWarningCodeNumber.Value != mc.Code) + continue; + + // This is a hacky way to say anything in the "subtree" of the attrProvider + if (attrProvider is IMemberDefinition attrMember && (mc.Origin?.MemberDefinition is TypeSystemEntity member) && member.ToString()?.Contains(attrMember.FullName) != true) + continue; + + unexpectedWarningMessage = mc; + break; + } + + Assert.False(unexpectedWarningMessage.HasValue, + $"Unexpected warning found: {unexpectedWarningMessage}"); + } + + if (checkRemainingErrors) + { + var remainingErrors = loggedMessages.Where(m => Regex.IsMatch(m.ToString(), @".*(error | warning): \d{4}.*")); + Assert.False(remainingErrors.Any(), $"Found unexpected errors:{Environment.NewLine}{string.Join(Environment.NewLine, remainingErrors)}"); + } + + static bool LogMessageHasSameOriginMember(MessageContainer mc, ICustomAttributeProvider expectedOriginProvider) + { + var origin = mc.Origin; + Debug.Assert(origin != null); + if (origin?.MemberDefinition == null) + return false; + if (origin?.MemberDefinition is IAssemblyDesc asm) + return expectedOriginProvider is AssemblyDefinition expectedAsm && asm.GetName().Name == expectedAsm.Name.Name; + + if (expectedOriginProvider is not IMemberDefinition expectedOriginMember) + return false; + + var actualOriginToken = new AssemblyQualifiedToken(origin!.Value.MemberDefinition); + var expectedOriginToken = new AssemblyQualifiedToken(expectedOriginMember); + if (actualOriginToken.Equals(expectedOriginToken)) + return true; + + var actualMember = origin.Value.MemberDefinition; + // Compensate for cases where for some reason the OM doesn't preserve the declaring types + // on certain things after trimming. + if (actualMember != null && GetOwningType(actualMember) == null && + GetMemberName(actualMember) == (expectedOriginProvider as IMemberDefinition)?.Name) + return true; + + return false; + } + + static TypeDesc? GetOwningType(TypeSystemEntity entity) => entity switch + { + DefType defType => defType.ContainingType, + MethodDesc method => method.OwningType, + FieldDesc field => field.OwningType, + _ => null + }; + + static string? GetMemberName(TypeSystemEntity? entity) => entity switch + { + DefType defType => defType.Name, + MethodDesc method => method.Name, + FieldDesc field => field.Name, + _ => null + }; + + static bool MessageTextContains(string message, string value) + { + // This is a workaround for different formatting of methods between ilc and illink/analyzer + // Sometimes they're written with a space after comma and sometimes without + // Method(String,String) - ilc + // Method(String, String) - illink/analyzer + return message.Contains(value) || message.Contains(NameUtils.ConvertSignatureToIlcFormat(value)); + } + } + + private static bool HasAttribute(ICustomAttributeProvider caProvider, string attributeName) + { + return TryGetCustomAttribute(caProvider, attributeName, out var _); + } #nullable enable - private static bool TryGetCustomAttribute (ICustomAttributeProvider caProvider, string attributeName, [NotNullWhen (true)] out CustomAttribute? customAttribute) - { - if (caProvider is AssemblyDefinition assembly && assembly.EntryPoint != null) { - customAttribute = assembly.EntryPoint.DeclaringType.CustomAttributes - .FirstOrDefault (attr => attr!.AttributeType.Name == attributeName, null); - return customAttribute is not null; - } - - if (caProvider is TypeDefinition type) { - customAttribute = type.CustomAttributes - .FirstOrDefault (attr => attr!.AttributeType.Name == attributeName, null); - return customAttribute is not null; - } - customAttribute = null; - return false; - } - - private static IEnumerable GetCustomAttributes (ICustomAttributeProvider caProvider, string attributeName) - { - if (caProvider is AssemblyDefinition assembly && assembly.EntryPoint != null) - return assembly.EntryPoint.DeclaringType.CustomAttributes - .Where (attr => attr!.AttributeType.Name == attributeName); - - if (caProvider is TypeDefinition type) - return type.CustomAttributes - .Where (attr => attr!.AttributeType.Name == attributeName); - - return Enumerable.Empty (); - } + private static bool TryGetCustomAttribute(ICustomAttributeProvider caProvider, string attributeName, [NotNullWhen(true)] out CustomAttribute? customAttribute) + { + if (caProvider is AssemblyDefinition assembly && assembly.EntryPoint != null) + { + customAttribute = assembly.EntryPoint.DeclaringType.CustomAttributes + .FirstOrDefault(attr => attr!.AttributeType.Name == attributeName, null); + return customAttribute is not null; + } + + if (caProvider is TypeDefinition type) + { + customAttribute = type.CustomAttributes + .FirstOrDefault(attr => attr!.AttributeType.Name == attributeName, null); + return customAttribute is not null; + } + customAttribute = null; + return false; + } + + private static IEnumerable GetCustomAttributes(ICustomAttributeProvider caProvider, string attributeName) + { + if (caProvider is AssemblyDefinition assembly && assembly.EntryPoint != null) + return assembly.EntryPoint.DeclaringType.CustomAttributes + .Where(attr => attr!.AttributeType.Name == attributeName); + + if (caProvider is TypeDefinition type) + return type.CustomAttributes + .Where(attr => attr!.AttributeType.Name == attributeName); + + return Enumerable.Empty(); + } #nullable restore - } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCollector.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCollector.cs index 1a301af17577e8..42c7bf7a44a6c8 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCollector.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCollector.cs @@ -13,145 +13,155 @@ namespace Mono.Linker.Tests.TestCasesRunner { - public class TestCaseCollector - { - private readonly NPath _rootDirectory; - private readonly NPath _testCaseAssemblyRoot; - - public TestCaseCollector (string rootDirectory, string testCaseAssemblyPath) - : this (rootDirectory.ToNPath (), testCaseAssemblyPath.ToNPath ()) - { - } - - public TestCaseCollector (NPath rootDirectory, NPath testCaseAssemblyRoot) - { - _rootDirectory = rootDirectory; - _testCaseAssemblyRoot = testCaseAssemblyRoot; - } - - public IEnumerable Collect () - { - return Collect (AllSourceFiles ()); - } - - public TestCase? Collect (NPath sourceFile) - { - return Collect (new[] { sourceFile }).FirstOrDefault (); - } - - public IEnumerable Collect (IEnumerable sourceFiles) - { - _rootDirectory.DirectoryMustExist (); - _testCaseAssemblyRoot.DirectoryMustExist (); - - foreach (var file in sourceFiles) { - var testCaseAssemblyPath = FindTestCaseAssembly (file); - testCaseAssemblyPath.FileMustExist (); - if (CreateCase (testCaseAssemblyPath, file, out TestCase? testCase)) - yield return testCase; - } - } - - NPath FindTestCaseAssembly (NPath sourceFile) - { - if (!sourceFile.IsChildOf (_rootDirectory)) - throw new ArgumentException ($"{sourceFile} is not a child of {_rootDirectory}"); - - var current = sourceFile; - do { - if (current.Parent.Files ("*.csproj").FirstOrDefault () is NPath csproj) { - var relative = csproj.Parent.RelativeTo (_rootDirectory); - return _testCaseAssemblyRoot.Combine (relative).Combine (csproj.ChangeExtension ("dll").FileName); - } - - current = current.Parent; - } while (current != _rootDirectory); - - throw new InvalidOperationException ($"Could not find a .csproj file for {sourceFile}"); - } - - public IEnumerable AllSourceFiles () - { - _rootDirectory.DirectoryMustExist (); - - foreach (var file in _rootDirectory.Files ("*.cs")) { - yield return file; - } - - foreach (var subDir in _rootDirectory.Directories ()) { - if (subDir.FileName == "bin" || subDir.FileName == "obj" || subDir.FileName == "Properties") - continue; - - foreach (var file in subDir.Files ("*.cs", true)) { - - var relativeParents = file.RelativeTo (_rootDirectory); - // Magic : Anything in a directory named Dependencies is assumed to be a dependency to a test case - // and never a test itself - // This makes life a little easier when writing these supporting files as it removes some constraints you would previously have - // had to follow such as ensuring a class exists that matches the file name and putting [NotATestCase] on that class - if (relativeParents.RecursiveParents.Any (p => p.Elements.Any () && p.FileName == "Dependencies")) - continue; - - // Magic: Anything in a directory named Individual is expected to be ran by it's own [Test] rather than as part of [TestCaseSource] - if (relativeParents.RecursiveParents.Any (p => p.Elements.Any () && p.FileName == "Individual")) - continue; - - yield return file; - } - } - } - - public TestCase? CreateIndividualCase (Type testCaseType) - { - _rootDirectory.DirectoryMustExist (); - _testCaseAssemblyRoot.FileMustExist (); - - var pathRelativeToAssembly = $"{testCaseType.FullName?.Substring (testCaseType.Module.Name.Length - 3).Replace ('.', '/')}.cs"; - var fullSourcePath = _rootDirectory.Combine (pathRelativeToAssembly).FileMustExist (); - var testCaseAssemblyPath = FindTestCaseAssembly (fullSourcePath); - - if (!CreateCase (testCaseAssemblyPath, fullSourcePath, out TestCase? testCase)) - throw new ArgumentException ($"Could not create a test case for `{testCaseType}`. Ensure the namespace matches it's location on disk"); - - return testCase; - } - - private bool CreateCase (NPath caseAssemblyPath, NPath sourceFile, [NotNullWhen (true)] out TestCase? testCase) - { - using AssemblyDefinition caseAssemblyDefinition = AssemblyDefinition.ReadAssembly (caseAssemblyPath.ToString ()); - - var potentialCase = new TestCase (sourceFile, _rootDirectory, caseAssemblyPath); - var typeDefinition = potentialCase.TryFindTypeDefinition (caseAssemblyDefinition); - - testCase = null; - - if (typeDefinition == null) { - Console.WriteLine ($"Could not find the matching type for test case {sourceFile}. Ensure the file name and class name match"); - return false; - } - - if (typeDefinition.HasAttribute (nameof (NotATestCaseAttribute))) { - return false; - } - - // Verify the class as a static main method - var mainMethod = typeDefinition.Methods.FirstOrDefault (m => m.Name == - (typeDefinition.FullName == "Program" - ? "
$" // Compiler-generated Main for top-level statements - : "Main")); - - if (mainMethod == null) { - Console.WriteLine ($"{typeDefinition} in {sourceFile} is missing a Main() method"); - return false; - } - - if (!mainMethod.IsStatic) { - Console.WriteLine ($"The Main() method for {typeDefinition} in {sourceFile} should be static"); - return false; - } - - testCase = potentialCase; - return true; - } - } + public class TestCaseCollector + { + private readonly NPath _rootDirectory; + private readonly NPath _testCaseAssemblyRoot; + + public TestCaseCollector(string rootDirectory, string testCaseAssemblyPath) + : this(rootDirectory.ToNPath(), testCaseAssemblyPath.ToNPath()) + { + } + + public TestCaseCollector(NPath rootDirectory, NPath testCaseAssemblyRoot) + { + _rootDirectory = rootDirectory; + _testCaseAssemblyRoot = testCaseAssemblyRoot; + } + + public IEnumerable Collect() + { + return Collect(AllSourceFiles()); + } + + public TestCase? Collect(NPath sourceFile) + { + return Collect(new[] { sourceFile }).FirstOrDefault(); + } + + public IEnumerable Collect(IEnumerable sourceFiles) + { + _rootDirectory.DirectoryMustExist(); + _testCaseAssemblyRoot.DirectoryMustExist(); + + foreach (var file in sourceFiles) + { + var testCaseAssemblyPath = FindTestCaseAssembly(file); + testCaseAssemblyPath.FileMustExist(); + if (CreateCase(testCaseAssemblyPath, file, out TestCase? testCase)) + yield return testCase; + } + } + + NPath FindTestCaseAssembly(NPath sourceFile) + { + if (!sourceFile.IsChildOf(_rootDirectory)) + throw new ArgumentException($"{sourceFile} is not a child of {_rootDirectory}"); + + var current = sourceFile; + do + { + if (current.Parent.Files("*.csproj").FirstOrDefault() is NPath csproj) + { + var relative = csproj.Parent.RelativeTo(_rootDirectory); + return _testCaseAssemblyRoot.Combine(relative).Combine(csproj.ChangeExtension("dll").FileName); + } + + current = current.Parent; + } while (current != _rootDirectory); + + throw new InvalidOperationException($"Could not find a .csproj file for {sourceFile}"); + } + + public IEnumerable AllSourceFiles() + { + _rootDirectory.DirectoryMustExist(); + + foreach (var file in _rootDirectory.Files("*.cs")) + { + yield return file; + } + + foreach (var subDir in _rootDirectory.Directories()) + { + if (subDir.FileName == "bin" || subDir.FileName == "obj" || subDir.FileName == "Properties") + continue; + + foreach (var file in subDir.Files("*.cs", true)) + { + + var relativeParents = file.RelativeTo(_rootDirectory); + // Magic : Anything in a directory named Dependencies is assumed to be a dependency to a test case + // and never a test itself + // This makes life a little easier when writing these supporting files as it removes some constraints you would previously have + // had to follow such as ensuring a class exists that matches the file name and putting [NotATestCase] on that class + if (relativeParents.RecursiveParents.Any(p => p.Elements.Any() && p.FileName == "Dependencies")) + continue; + + // Magic: Anything in a directory named Individual is expected to be ran by it's own [Test] rather than as part of [TestCaseSource] + if (relativeParents.RecursiveParents.Any(p => p.Elements.Any() && p.FileName == "Individual")) + continue; + + yield return file; + } + } + } + + public TestCase? CreateIndividualCase(Type testCaseType) + { + _rootDirectory.DirectoryMustExist(); + _testCaseAssemblyRoot.FileMustExist(); + + var pathRelativeToAssembly = $"{testCaseType.FullName?.Substring(testCaseType.Module.Name.Length - 3).Replace('.', '/')}.cs"; + var fullSourcePath = _rootDirectory.Combine(pathRelativeToAssembly).FileMustExist(); + var testCaseAssemblyPath = FindTestCaseAssembly(fullSourcePath); + + if (!CreateCase(testCaseAssemblyPath, fullSourcePath, out TestCase? testCase)) + throw new ArgumentException($"Could not create a test case for `{testCaseType}`. Ensure the namespace matches it's location on disk"); + + return testCase; + } + + private bool CreateCase(NPath caseAssemblyPath, NPath sourceFile, [NotNullWhen(true)] out TestCase? testCase) + { + using AssemblyDefinition caseAssemblyDefinition = AssemblyDefinition.ReadAssembly(caseAssemblyPath.ToString()); + + var potentialCase = new TestCase(sourceFile, _rootDirectory, caseAssemblyPath); + var typeDefinition = potentialCase.TryFindTypeDefinition(caseAssemblyDefinition); + + testCase = null; + + if (typeDefinition == null) + { + Console.WriteLine($"Could not find the matching type for test case {sourceFile}. Ensure the file name and class name match"); + return false; + } + + if (typeDefinition.HasAttribute(nameof(NotATestCaseAttribute))) + { + return false; + } + + // Verify the class as a static main method + var mainMethod = typeDefinition.Methods.FirstOrDefault(m => m.Name == + (typeDefinition.FullName == "Program" + ? "
$" // Compiler-generated Main for top-level statements + : "Main")); + + if (mainMethod == null) + { + Console.WriteLine($"{typeDefinition} in {sourceFile} is missing a Main() method"); + return false; + } + + if (!mainMethod.IsStatic) + { + Console.WriteLine($"The Main() method for {typeDefinition} in {sourceFile} should be static"); + return false; + } + + testCase = potentialCase; + return true; + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs index 825663ac8bdae1..f8fe337cb5cd34 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs @@ -14,237 +14,285 @@ namespace Mono.Linker.Tests.TestCasesRunner { - public class TestCaseCompilationMetadataProvider : BaseMetadataProvider - { - - public TestCaseCompilationMetadataProvider (TestCase testCase, AssemblyDefinition fullTestCaseAssemblyDefinition) - : base (testCase, fullTestCaseAssemblyDefinition) - { - - } - - public virtual TestRunCharacteristics Characteristics => - TestRunCharacteristics.TargetingNetCore | TestRunCharacteristics.SupportsDefaultInterfaceMethods | TestRunCharacteristics.SupportsStaticInterfaceMethods; - - private static bool IsIgnoredByNativeAOT (CustomAttribute attr) - { - var ignoredBy = attr.GetPropertyValue ("IgnoredBy"); - return ignoredBy is null ? true : ((Tool) ignoredBy).HasFlag (Tool.NativeAot); - } - - public virtual bool IsIgnored ([NotNullWhen (true)] out string? reason) - { - var ignoreAttribute = _testCaseTypeDefinition.CustomAttributes.FirstOrDefault (attr => attr.AttributeType.Name == nameof (IgnoreTestCaseAttribute)); - if (ignoreAttribute != null && IsIgnoredByNativeAOT (ignoreAttribute)) { - if (ignoreAttribute.ConstructorArguments.Count == 1) { - reason = (string) ignoreAttribute.ConstructorArguments.First ().Value; - return true; - } else { - throw new ArgumentException ($"Unhandled {nameof (IgnoreTestCaseAttribute)} constructor with {ignoreAttribute.ConstructorArguments} arguments"); - } - } - - var requirementsAttribute = _testCaseTypeDefinition.CustomAttributes.FirstOrDefault (attr => attr.AttributeType.Name == nameof (TestCaseRequirementsAttribute)); - if (requirementsAttribute != null) { - if (requirementsAttribute.ConstructorArguments.Count == 2) { - var testCaseRequirements = (TestRunCharacteristics) requirementsAttribute.ConstructorArguments[0].Value; - - foreach (var value in Enum.GetValues (typeof (TestRunCharacteristics))) { - if (IsRequirementMissing ((TestRunCharacteristics) value, testCaseRequirements)) { - reason = (string) requirementsAttribute.ConstructorArguments[1].Value; - return true; - } - } - } else { - throw new ArgumentException ($"Unhandled {nameof (TestCaseRequirementsAttribute)} constructor with {requirementsAttribute.ConstructorArguments} arguments"); - } - } - - reason = null; - return false; - } - - private bool IsRequirementMissing (TestRunCharacteristics requirement, TestRunCharacteristics testCaseRequirements) - { - return testCaseRequirements.HasFlag (requirement) && !Characteristics.HasFlag (requirement); - } - - public virtual IEnumerable GetDefines () - { - // There are a few tests related to native pdbs where the assertions are different between windows and non-windows - // To enable test cases to define different expected behavior we set this special define - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - yield return "WIN32"; - - if (Characteristics.HasFlag (TestRunCharacteristics.TargetingNetCore)) - yield return "NET"; - - if (Characteristics.HasFlag (TestRunCharacteristics.SupportsDefaultInterfaceMethods)) - yield return "SUPPORTS_DEFAULT_INTERFACE_METHODS"; - - foreach (var attr in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (DefineAttribute))) - yield return (string) attr.ConstructorArguments.First ().Value; - } - - public virtual string GetAssemblyName () - { - var asLibraryAttribute = _testCaseTypeDefinition.CustomAttributes - .FirstOrDefault (attr => attr.AttributeType.Name == nameof (SetupCompileAsLibraryAttribute)); - var defaultName = asLibraryAttribute == null ? "test.exe" : "test.dll"; - return GetOptionAttributeValue (nameof (SetupCompileAssemblyNameAttribute), defaultName)!; - } - - public virtual string GetCSharpCompilerToUse () - { - return GetOptionAttributeValue (nameof (SetupCSharpCompilerToUseAttribute), string.Empty)!.ToLowerInvariant (); - } - - public virtual IEnumerable GetSetupCompilerArguments () - { - return _testCaseTypeDefinition.CustomAttributes - .Where (attr => attr.AttributeType.Name == nameof (SetupCompileArgumentAttribute)) - .Select (attr => (string) attr.ConstructorArguments.First ().Value); - } - - public virtual IEnumerable AdditionalFilesToSandbox () - { - return _testCaseTypeDefinition.CustomAttributes - .Where (attr => attr.AttributeType.Name == nameof (SandboxDependencyAttribute)) - .Select (GetSourceAndRelativeDestinationValue); - } - - private static string GetReferenceDir () - { - string runtimeDir = Path.GetDirectoryName (typeof (object).Assembly.Location)!; - string ncaVersion = Path.GetFileName (runtimeDir); - string dotnetDir = Path.GetDirectoryName (Path.GetDirectoryName (Path.GetDirectoryName (runtimeDir)))!; - return Path.Combine (dotnetDir, "packs", "Microsoft.NETCore.App.Ref", ncaVersion, "ref", PathUtilities.TFMDirectoryName); - } - - public virtual IEnumerable GetCommonReferencedAssemblies (NPath workingDirectory) - { - yield return workingDirectory.Combine ("Mono.Linker.Tests.Cases.Expectations.dll").ToString (); - if (Characteristics.HasFlag (TestRunCharacteristics.TargetingNetCore)) { - string referenceDir = GetReferenceDir (); - - yield return Path.Combine (referenceDir, "mscorlib.dll"); - yield return Path.Combine (referenceDir, "System.Collections.dll"); - yield return Path.Combine (referenceDir, "System.Collections.Immutable.dll"); - yield return Path.Combine (referenceDir, "System.ComponentModel.TypeConverter.dll"); - yield return Path.Combine (referenceDir, "System.Console.dll"); - yield return Path.Combine (referenceDir, "System.Linq.Expressions.dll"); - yield return Path.Combine (referenceDir, "System.Memory.dll"); - yield return Path.Combine (referenceDir, "System.ObjectModel.dll"); - yield return Path.Combine (referenceDir, "System.Runtime.dll"); - yield return Path.Combine (referenceDir, "System.Runtime.Extensions.dll"); - yield return Path.Combine (referenceDir, "System.Runtime.InteropServices.dll"); - } else { - yield return "mscorlib.dll"; - } - } - - public virtual IEnumerable GetReferencedAssemblies (NPath workingDirectory) - { - foreach (var fileName in GetReferenceValues ()) { - - if (fileName.StartsWith ("System.", StringComparison.Ordinal) || fileName.StartsWith ("Mono.", StringComparison.Ordinal) || fileName.StartsWith ("Microsoft.", StringComparison.Ordinal)) { - if (Characteristics.HasFlag (TestRunCharacteristics.TargetingNetCore)) { - var referenceDir = GetReferenceDir (); - var filePath = Path.Combine (referenceDir, fileName); - - if (File.Exists (filePath)) { - yield return filePath; - } else { - yield return fileName; - } - } else { - yield return fileName; - } - } else { - // Drop any relative path information. Sandboxing will have taken care of copying the reference to the directory - yield return workingDirectory.Combine (Path.GetFileName (fileName)); - } - } - } - - public virtual IEnumerable GetReferenceDependencies () - { - return _testCaseTypeDefinition.CustomAttributes - .Where (attr => attr.AttributeType.Name == nameof (ReferenceDependencyAttribute)) - .Select (attr => (string) attr.ConstructorArguments[0].Value); - } - - public virtual IEnumerable GetReferenceValues () - { - foreach (var referenceAttr in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (ReferenceAttribute))) - yield return (string) referenceAttr.ConstructorArguments.First ().Value; - } - - public virtual IEnumerable GetResources () - { - return _testCaseTypeDefinition.CustomAttributes - .Where (attr => attr.AttributeType.Name == nameof (SetupCompileResourceAttribute)) - .Select (GetSourceAndRelativeDestinationValue); - } - - public virtual IEnumerable GetSetupCompileAssembliesBefore () - { - return _testCaseTypeDefinition.CustomAttributes - .Where (attr => attr.AttributeType.Name == nameof (SetupCompileBeforeAttribute)) - .Select (CreateSetupCompileAssemblyInfo); - } - - public virtual IEnumerable GetSetupCompileAssembliesAfter () - { - return _testCaseTypeDefinition.CustomAttributes - .Where (attr => attr.AttributeType.Name == nameof (SetupCompileAfterAttribute)) - .Select (CreateSetupCompileAssemblyInfo); - } - - private SetupCompileInfo CreateSetupCompileAssemblyInfo (CustomAttribute attribute) - { - var ctorArguments = attribute.ConstructorArguments; - return new SetupCompileInfo { - OutputName = (string) ctorArguments[0].Value, - SourceFiles = SourceFilesForAttributeArgument (ctorArguments[1]), - References = ((CustomAttributeArgument[]) ctorArguments[2].Value)?.Select (arg => arg.Value.ToString ()).ToArray (), - Defines = ((CustomAttributeArgument[]) ctorArguments[3].Value)?.Select (arg => arg.Value.ToString ()).ToArray (), - Resources = ResourcesForAttributeArgument (ctorArguments[4]), - AdditionalArguments = ((CustomAttributeArgument[]) ctorArguments[5].Value)?.Select (arg => arg.Value.ToString ()).ToArray (), - CompilerToUse = (string) ctorArguments[6].Value, - AddAsReference = ctorArguments.Count >= 8 ? (bool) ctorArguments[7].Value : true, - RemoveFromLinkerInput = ctorArguments.Count >= 9 ? (bool) ctorArguments[8].Value : false, - OutputSubFolder = ctorArguments.Count >= 10 ? (string) ctorArguments[9].Value : null - }; - } - - protected NPath[] SourceFilesForAttributeArgument (CustomAttributeArgument attributeArgument) - { - return ((CustomAttributeArgument[]) attributeArgument.Value) - .Select (attributeArg => SourceFileForAttributeArgumentValue (attributeArg.Value)) - .Distinct () - .ToArray (); - } - - protected SourceAndDestinationPair[]? ResourcesForAttributeArgument (CustomAttributeArgument attributeArgument) - { - return ((CustomAttributeArgument[]) attributeArgument.Value) - ?.Select (arg => { - var referenceArg = (CustomAttributeArgument) arg.Value; - if (referenceArg.Value is string source) { - var fullSource = MakeSourceTreeFilePathAbsolute (source); - return new SourceAndDestinationPair { - Source = fullSource, - DestinationFileName = fullSource.FileName - }; - } - var sourceAndDestination = (CustomAttributeArgument[]) referenceArg.Value; - return new SourceAndDestinationPair { - Source = MakeSourceTreeFilePathAbsolute (sourceAndDestination[0].Value!.ToString ()!), - DestinationFileName = sourceAndDestination[1].Value!.ToString ()! - }; - }) - ?.ToArray (); - } - } + public class TestCaseCompilationMetadataProvider : BaseMetadataProvider + { + + public TestCaseCompilationMetadataProvider(TestCase testCase, AssemblyDefinition fullTestCaseAssemblyDefinition) + : base(testCase, fullTestCaseAssemblyDefinition) + { + + } + + public virtual TestRunCharacteristics Characteristics => + TestRunCharacteristics.TargetingNetCore | TestRunCharacteristics.SupportsDefaultInterfaceMethods | TestRunCharacteristics.SupportsStaticInterfaceMethods; + + private static bool IsIgnoredByNativeAOT(CustomAttribute attr) + { + var ignoredBy = attr.GetPropertyValue("IgnoredBy"); + return ignoredBy is null ? true : ((Tool)ignoredBy).HasFlag(Tool.NativeAot); + } + + public virtual bool IsIgnored([NotNullWhen(true)] out string? reason) + { + var ignoreAttribute = _testCaseTypeDefinition.CustomAttributes.FirstOrDefault(attr => attr.AttributeType.Name == nameof(IgnoreTestCaseAttribute)); + if (ignoreAttribute != null && IsIgnoredByNativeAOT(ignoreAttribute)) + { + if (ignoreAttribute.ConstructorArguments.Count == 1) + { + reason = (string)ignoreAttribute.ConstructorArguments.First().Value; + return true; + } + else + { + throw new ArgumentException($"Unhandled {nameof(IgnoreTestCaseAttribute)} constructor with {ignoreAttribute.ConstructorArguments} arguments"); + } + } + + var requirementsAttribute = _testCaseTypeDefinition.CustomAttributes.FirstOrDefault(attr => attr.AttributeType.Name == nameof(TestCaseRequirementsAttribute)); + if (requirementsAttribute != null) + { + if (requirementsAttribute.ConstructorArguments.Count == 2) + { + var testCaseRequirements = (TestRunCharacteristics)requirementsAttribute.ConstructorArguments[0].Value; + + foreach (var value in Enum.GetValues(typeof(TestRunCharacteristics))) + { + if (IsRequirementMissing((TestRunCharacteristics)value, testCaseRequirements)) + { + reason = (string)requirementsAttribute.ConstructorArguments[1].Value; + return true; + } + } + } + else + { + throw new ArgumentException($"Unhandled {nameof(TestCaseRequirementsAttribute)} constructor with {requirementsAttribute.ConstructorArguments} arguments"); + } + } + + reason = null; + return false; + } + + private bool IsRequirementMissing(TestRunCharacteristics requirement, TestRunCharacteristics testCaseRequirements) + { + return testCaseRequirements.HasFlag(requirement) && !Characteristics.HasFlag(requirement); + } + + public virtual IEnumerable GetDefines() + { + // There are a few tests related to native pdbs where the assertions are different between windows and non-windows + // To enable test cases to define different expected behavior we set this special define + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + yield return "WIN32"; + + if (Characteristics.HasFlag(TestRunCharacteristics.TargetingNetCore)) + yield return "NET"; + + if (Characteristics.HasFlag(TestRunCharacteristics.SupportsDefaultInterfaceMethods)) + yield return "SUPPORTS_DEFAULT_INTERFACE_METHODS"; + + foreach (var attr in _testCaseTypeDefinition.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(DefineAttribute))) + yield return (string)attr.ConstructorArguments.First().Value; + } + + public virtual string GetAssemblyName() + { + var asLibraryAttribute = _testCaseTypeDefinition.CustomAttributes + .FirstOrDefault(attr => attr.AttributeType.Name == nameof(SetupCompileAsLibraryAttribute)); + var defaultName = asLibraryAttribute == null ? "test.exe" : "test.dll"; + return GetOptionAttributeValue(nameof(SetupCompileAssemblyNameAttribute), defaultName)!; + } + + public virtual string GetCSharpCompilerToUse() + { + return GetOptionAttributeValue(nameof(SetupCSharpCompilerToUseAttribute), string.Empty)!.ToLowerInvariant(); + } + + public virtual IEnumerable GetSetupCompilerArguments() + { + return _testCaseTypeDefinition.CustomAttributes + .Where(attr => attr.AttributeType.Name == nameof(SetupCompileArgumentAttribute)) + .Select(attr => (string)attr.ConstructorArguments.First().Value); + } + + public virtual IEnumerable AdditionalFilesToSandbox() + { + return _testCaseTypeDefinition.CustomAttributes + .Where(attr => attr.AttributeType.Name == nameof(SandboxDependencyAttribute)) + .Select(GetSourceAndRelativeDestinationValue); + } + + private static string GetReferenceDir() + { + string runtimeDir = Path.GetDirectoryName(typeof(object).Assembly.Location)!; + string ncaVersion = Path.GetFileName(runtimeDir); + string dotnetDir = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(runtimeDir)))!; + return Path.Combine(dotnetDir, "packs", "Microsoft.NETCore.App.Ref", ncaVersion, "ref", PathUtilities.TargetFramework); + } + + public IEnumerable GetCommonSourceFiles() + { + var dam = _testCase.RootCasesDirectory.Parent + .Combine("Mono.Linker.Tests.Cases.Expectations") + .Combine("Support") + .Combine("DynamicallyAccessedMembersAttribute.cs"); + yield return dam; + + var sharedDir = _testCase.RootCasesDirectory.Parent.Parent + .Combine("src") + .Combine("ILLink.Shared"); + yield return sharedDir.Combine("RequiresDynamicCodeAttribute.cs"); + yield return sharedDir.Combine("RequiresUnreferencedCodeAttribute.cs"); + } + + public virtual IEnumerable GetCommonReferencedAssemblies(NPath workingDirectory) + { + yield return workingDirectory.Combine("Mono.Linker.Tests.Cases.Expectations.dll").ToString(); + if (Characteristics.HasFlag(TestRunCharacteristics.TargetingNetCore)) + { + string referenceDir = GetReferenceDir(); + + yield return Path.Combine(referenceDir, "mscorlib.dll"); + yield return Path.Combine(referenceDir, "System.Collections.dll"); + yield return Path.Combine(referenceDir, "System.Collections.Immutable.dll"); + yield return Path.Combine(referenceDir, "System.ComponentModel.TypeConverter.dll"); + yield return Path.Combine(referenceDir, "System.Console.dll"); + yield return Path.Combine(referenceDir, "System.Linq.Expressions.dll"); + yield return Path.Combine(referenceDir, "System.Memory.dll"); + yield return Path.Combine(referenceDir, "System.ObjectModel.dll"); + yield return Path.Combine(referenceDir, "System.Runtime.dll"); + yield return Path.Combine(referenceDir, "System.Runtime.Extensions.dll"); + yield return Path.Combine(referenceDir, "System.Runtime.InteropServices.dll"); + } + else + { + yield return "mscorlib.dll"; + } + } + + public virtual IEnumerable GetReferencedAssemblies(NPath workingDirectory) + { + foreach (var fileName in GetReferenceValues()) + { + + if (fileName.StartsWith("System.", StringComparison.Ordinal) || fileName.StartsWith("Mono.", StringComparison.Ordinal) || fileName.StartsWith("Microsoft.", StringComparison.Ordinal)) + { + if (Characteristics.HasFlag(TestRunCharacteristics.TargetingNetCore)) + { + var referenceDir = GetReferenceDir(); + var filePath = Path.Combine(referenceDir, fileName); + + if (File.Exists(filePath)) + { + yield return filePath; + } + else + { + yield return fileName; + } + } + else + { + yield return fileName; + } + } + else + { + // Drop any relative path information. Sandboxing will have taken care of copying the reference to the directory + yield return workingDirectory.Combine(Path.GetFileName(fileName)); + } + } + } + + public virtual IEnumerable GetReferenceDependencies() + { + return _testCaseTypeDefinition.CustomAttributes + .Where(attr => attr.AttributeType.Name == nameof(ReferenceDependencyAttribute)) + .Select(attr => (string)attr.ConstructorArguments[0].Value); + } + + public virtual IEnumerable GetReferenceValues() + { + foreach (var referenceAttr in _testCaseTypeDefinition.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(ReferenceAttribute))) + yield return (string)referenceAttr.ConstructorArguments.First().Value; + } + + public virtual IEnumerable GetResources() + { + return _testCaseTypeDefinition.CustomAttributes + .Where(attr => attr.AttributeType.Name == nameof(SetupCompileResourceAttribute)) + .Select(GetSourceAndRelativeDestinationValue); + } + + public virtual IEnumerable GetSetupCompileAssembliesBefore() + { + return _testCaseTypeDefinition.CustomAttributes + .Where(attr => attr.AttributeType.Name == nameof(SetupCompileBeforeAttribute)) + .Select(CreateSetupCompileAssemblyInfo); + } + + public virtual IEnumerable GetSetupCompileAssembliesAfter() + { + return _testCaseTypeDefinition.CustomAttributes + .Where(attr => attr.AttributeType.Name == nameof(SetupCompileAfterAttribute)) + .Select(CreateSetupCompileAssemblyInfo); + } + + public bool GetGenerateTargetFrameworkAttribute() + { + return GetOptionAttributeValue(nameof(GetGenerateTargetFrameworkAttribute), true); + } + + private SetupCompileInfo CreateSetupCompileAssemblyInfo(CustomAttribute attribute) + { + var ctorArguments = attribute.ConstructorArguments; + return new SetupCompileInfo + { + OutputName = (string)ctorArguments[0].Value, + SourceFiles = SourceFilesForAttributeArgument(ctorArguments[1]), + References = ((CustomAttributeArgument[])ctorArguments[2].Value)?.Select(arg => arg.Value.ToString()).ToArray(), + Defines = ((CustomAttributeArgument[])ctorArguments[3].Value)?.Select(arg => arg.Value.ToString()).ToArray(), + Resources = ResourcesForAttributeArgument(ctorArguments[4]), + AdditionalArguments = ((CustomAttributeArgument[])ctorArguments[5].Value)?.Select(arg => arg.Value.ToString()).ToArray(), + CompilerToUse = (string)ctorArguments[6].Value, + AddAsReference = ctorArguments.Count >= 8 ? (bool)ctorArguments[7].Value : true, + RemoveFromLinkerInput = ctorArguments.Count >= 9 ? (bool)ctorArguments[8].Value : false, + OutputSubFolder = ctorArguments.Count >= 10 ? (string)ctorArguments[9].Value : null + }; + } + + protected NPath[] SourceFilesForAttributeArgument(CustomAttributeArgument attributeArgument) + { + return ((CustomAttributeArgument[])attributeArgument.Value) + .Select(attributeArg => SourceFileForAttributeArgumentValue(attributeArg.Value)) + .Distinct() + .ToArray(); + } + + protected SourceAndDestinationPair[]? ResourcesForAttributeArgument(CustomAttributeArgument attributeArgument) + { + return ((CustomAttributeArgument[])attributeArgument.Value) + ?.Select(arg => + { + var referenceArg = (CustomAttributeArgument)arg.Value; + if (referenceArg.Value is string source) + { + var fullSource = MakeSourceTreeFilePathAbsolute(source); + return new SourceAndDestinationPair + { + Source = fullSource, + DestinationFileName = fullSource.FileName + }; + } + var sourceAndDestination = (CustomAttributeArgument[])referenceArg.Value; + return new SourceAndDestinationPair + { + Source = MakeSourceTreeFilePathAbsolute(sourceAndDestination[0].Value!.ToString()!), + DestinationFileName = sourceAndDestination[1].Value!.ToString()! + }; + }) + ?.ToArray(); + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompiler.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompiler.cs index b20c16631302c2..f043024e96a741 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompiler.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompiler.cs @@ -18,404 +18,456 @@ namespace Mono.Linker.Tests.TestCasesRunner { - public class TestCaseCompiler - { - protected readonly TestCaseCompilationMetadataProvider _metadataProvider; - protected readonly TestCaseSandbox _sandbox; - protected readonly ILInputCompiler _ilCompiler; - - public TestCaseCompiler (TestCaseSandbox sandbox, TestCaseCompilationMetadataProvider metadataProvider) - : this (sandbox, metadataProvider, new ILInputCompiler ()) - { - } - - public TestCaseCompiler (TestCaseSandbox sandbox, TestCaseCompilationMetadataProvider metadataProvider, ILInputCompiler ilCompiler) - { - _ilCompiler = ilCompiler; - _sandbox = sandbox; - _metadataProvider = metadataProvider; - } - - public NPath CompileTestIn (NPath outputDirectory, string outputName, IEnumerable sourceFiles, string[] commonReferences, string[] mainAssemblyReferences, IEnumerable? defines, NPath[] resources, string[] additionalArguments) - { - var originalCommonReferences = commonReferences.Select (r => r.ToNPath ()).ToArray (); - var originalDefines = defines?.ToArray () ?? Array.Empty (); - - Prepare (outputDirectory); - - var removeFromLinkerInputAssemblies = new List (); - var compiledReferences = CompileBeforeTestCaseAssemblies (outputDirectory, originalCommonReferences, originalDefines, removeFromLinkerInputAssemblies).ToArray (); - var allTestCaseReferences = originalCommonReferences - .Concat (compiledReferences) - .Concat (mainAssemblyReferences.Select (r => r.ToNPath ())) - .ToArray (); - - var options = CreateOptionsForTestCase ( - outputDirectory.Combine (outputName), - sourceFiles.Select (s => s.ToNPath ()).ToArray (), - allTestCaseReferences, - originalDefines, - resources, - additionalArguments); - var testAssembly = CompileAssembly (options); - - - // The compile after step is used by tests to mess around with the input to the illink tool. Generally speaking, it doesn't seem like we would ever want to mess with the - // expectations assemblies because this would undermine our ability to inspect them for expected results during ResultChecking. The UnityLinker UnresolvedHandling tests depend on this - // behavior of skipping the after test compile - if (outputDirectory != _sandbox.ExpectationsDirectory) { - CompileAfterTestCaseAssemblies (outputDirectory, originalCommonReferences, originalDefines, removeFromLinkerInputAssemblies); - - foreach (var assemblyToRemove in removeFromLinkerInputAssemblies) - assemblyToRemove.DeleteIfExists (); - } - - return testAssembly; - } - - protected virtual void Prepare (NPath outputDirectory) - { - } - - protected virtual CompilerOptions CreateOptionsForTestCase (NPath outputPath, NPath[] sourceFiles, NPath[] references, string[] defines, NPath[] resources, string[] additionalArguments) - { - return new CompilerOptions { - OutputPath = outputPath, - SourceFiles = sourceFiles, - References = references, - Defines = defines.Concat (_metadataProvider.GetDefines ()).ToArray (), - Resources = resources, - AdditionalArguments = additionalArguments, - CompilerToUse = _metadataProvider.GetCSharpCompilerToUse () - }; - } - - protected virtual CompilerOptions CreateOptionsForSupportingAssembly (SetupCompileInfo setupCompileInfo, NPath outputDirectory, NPath[] sourceFiles, NPath[] references, string[] defines, NPath[] resources) - { - var allDefines = defines.Concat (setupCompileInfo.Defines ?? Array.Empty ()).ToArray (); - var allReferences = references.Concat (setupCompileInfo.References?.Select (p => MakeSupportingAssemblyReferencePathAbsolute (outputDirectory, p)) ?? Array.Empty ()).ToArray (); - string[]? additionalArguments = setupCompileInfo.AdditionalArguments; - return new CompilerOptions { - OutputPath = outputDirectory.Combine (setupCompileInfo.OutputName), - SourceFiles = sourceFiles, - References = allReferences, - Defines = allDefines, - Resources = resources, - AdditionalArguments = additionalArguments, - CompilerToUse = setupCompileInfo.CompilerToUse?.ToLowerInvariant () - }; - } - - private IEnumerable CompileBeforeTestCaseAssemblies (NPath outputDirectory, NPath[] references, string[] defines, IList removeFromLinkerInputAssemblies) - { - foreach (var setupCompileInfo in _metadataProvider.GetSetupCompileAssembliesBefore ()) { - NPath outputFolder; - if (setupCompileInfo.OutputSubFolder == null) { - outputFolder = outputDirectory; - } else { - outputFolder = outputDirectory.Combine (setupCompileInfo.OutputSubFolder); - Directory.CreateDirectory (outputFolder.ToString ()); - } - - var options = CreateOptionsForSupportingAssembly ( - setupCompileInfo, - outputFolder, - CollectSetupBeforeSourcesFiles (setupCompileInfo), - references, - defines, - CollectSetupBeforeResourcesFiles (setupCompileInfo)); - var output = CompileAssembly (options); - - if (setupCompileInfo.RemoveFromLinkerInput) - removeFromLinkerInputAssemblies.Add (output); - - if (setupCompileInfo.AddAsReference) - yield return output; - } - } - - private void CompileAfterTestCaseAssemblies (NPath outputDirectory, NPath[] references, string[] defines, IList removeFromLinkerInputAssemblies) - { - foreach (var setupCompileInfo in _metadataProvider.GetSetupCompileAssembliesAfter ()) { - var options = CreateOptionsForSupportingAssembly ( - setupCompileInfo, - outputDirectory, - CollectSetupAfterSourcesFiles (setupCompileInfo), - references, - defines, - CollectSetupAfterResourcesFiles (setupCompileInfo)); - var output = CompileAssembly (options); - - if (setupCompileInfo.RemoveFromLinkerInput) - removeFromLinkerInputAssemblies.Add (output); - } - } - - private NPath[] CollectSetupBeforeSourcesFiles (SetupCompileInfo info) - { - return CollectSourceFilesFrom (_sandbox.BeforeReferenceSourceDirectoryFor (info.OutputName)); - } - - private NPath[] CollectSetupAfterSourcesFiles (SetupCompileInfo info) - { - return CollectSourceFilesFrom (_sandbox.AfterReferenceSourceDirectoryFor (info.OutputName)); - } - - private NPath[] CollectSetupBeforeResourcesFiles (SetupCompileInfo info) - { - return _sandbox.BeforeReferenceResourceDirectoryFor (info.OutputName).Files ().ToArray (); - } - - private NPath[] CollectSetupAfterResourcesFiles (SetupCompileInfo info) - { - return _sandbox.AfterReferenceResourceDirectoryFor (info.OutputName).Files ().ToArray (); - } - - private static NPath[] CollectSourceFilesFrom (NPath directory) - { - var sourceFiles = directory.Files ("*.cs").ToArray (); - if (sourceFiles.Length > 0) - return sourceFiles; - - sourceFiles = directory.Files ("*.il").ToArray (); - if (sourceFiles.Length > 0) - return sourceFiles; - - throw new FileNotFoundException ($"Didn't find any sources files in {directory}"); - } - - protected static NPath MakeSupportingAssemblyReferencePathAbsolute (NPath outputDirectory, string referenceFileName) - { - // Not a good idea to use a full path in a test, but maybe someone is trying to quickly test something locally - if (Path.IsPathRooted (referenceFileName)) - return referenceFileName.ToNPath (); + public class TestCaseCompiler + { + protected readonly TestCaseCompilationMetadataProvider _metadataProvider; + protected readonly TestCaseSandbox _sandbox; + protected readonly ILInputCompiler _ilCompiler; + + public TestCaseCompiler(TestCaseSandbox sandbox, TestCaseCompilationMetadataProvider metadataProvider) + : this(sandbox, metadataProvider, new ILInputCompiler()) + { + } + + public TestCaseCompiler(TestCaseSandbox sandbox, TestCaseCompilationMetadataProvider metadataProvider, ILInputCompiler ilCompiler) + { + _ilCompiler = ilCompiler; + _sandbox = sandbox; + _metadataProvider = metadataProvider; + } + + public NPath CompileTestIn(NPath outputDirectory, string outputName, IEnumerable sourceFiles, string[] commonReferences, string[] mainAssemblyReferences, IEnumerable? defines, NPath[] resources, bool generateTargetFrameworkAttribute, string[] additionalArguments) + { + var originalCommonReferences = commonReferences.Select(r => r.ToNPath()).ToArray(); + var originalDefines = defines?.ToArray() ?? Array.Empty(); + + Prepare(outputDirectory); + + var removeFromLinkerInputAssemblies = new List(); + var compiledReferences = CompileBeforeTestCaseAssemblies( + outputDirectory, + originalCommonReferences, + originalDefines, + removeFromLinkerInputAssemblies, + generateTargetFrameworkAttribute) + .ToArray(); + var allTestCaseReferences = originalCommonReferences + .Concat(compiledReferences) + .Concat(mainAssemblyReferences.Select(r => r.ToNPath())) + .ToArray(); + + var options = CreateOptionsForTestCase( + outputDirectory.Combine(outputName), + sourceFiles.Select(s => s.ToNPath()).ToArray(), + allTestCaseReferences, + originalDefines, + resources, + generateTargetFrameworkAttribute, + additionalArguments); + var testAssembly = CompileAssembly(options); + + + // The compile after step is used by tests to mess around with the input to the illink tool. Generally speaking, it doesn't seem like we would ever want to mess with the + // expectations assemblies because this would undermine our ability to inspect them for expected results during ResultChecking. The UnityLinker UnresolvedHandling tests depend on this + // behavior of skipping the after test compile + if (outputDirectory != _sandbox.ExpectationsDirectory) + { + CompileAfterTestCaseAssemblies( + outputDirectory, + originalCommonReferences, + originalDefines, + removeFromLinkerInputAssemblies, + generateTargetFrameworkAttribute); + + foreach (var assemblyToRemove in removeFromLinkerInputAssemblies) + assemblyToRemove.DeleteIfExists(); + } + + return testAssembly; + } + + protected virtual void Prepare(NPath outputDirectory) + { + } + + protected virtual CompilerOptions CreateOptionsForTestCase(NPath outputPath, NPath[] sourceFiles, NPath[] references, string[] defines, NPath[] resources, bool generateTargetFrameworkAttribute, string[] additionalArguments) + { + return new CompilerOptions + { + OutputPath = outputPath, + SourceFiles = sourceFiles, + References = references, + Defines = defines.Concat(_metadataProvider.GetDefines()).ToArray(), + Resources = resources, + AdditionalArguments = additionalArguments, + CompilerToUse = _metadataProvider.GetCSharpCompilerToUse(), + GenerateTargetFrameworkAttribute = generateTargetFrameworkAttribute + }; + } + + protected virtual CompilerOptions CreateOptionsForSupportingAssembly(SetupCompileInfo setupCompileInfo, NPath outputDirectory, NPath[] sourceFiles, NPath[] references, string[] defines, NPath[] resources, bool generateTargetFrameworkAttribute) + { + var allDefines = defines.Concat(setupCompileInfo.Defines ?? Array.Empty()).ToArray(); + var allReferences = references.Concat(setupCompileInfo.References?.Select(p => MakeSupportingAssemblyReferencePathAbsolute(outputDirectory, p)) ?? Array.Empty()).ToArray(); + string[]? additionalArguments = setupCompileInfo.AdditionalArguments; + return new CompilerOptions + { + OutputPath = outputDirectory.Combine(setupCompileInfo.OutputName), + SourceFiles = sourceFiles, + References = allReferences, + Defines = allDefines, + Resources = resources, + AdditionalArguments = additionalArguments, + CompilerToUse = setupCompileInfo.CompilerToUse?.ToLowerInvariant(), + GenerateTargetFrameworkAttribute = generateTargetFrameworkAttribute + }; + } + + private IEnumerable CompileBeforeTestCaseAssemblies(NPath outputDirectory, NPath[] references, string[] defines, IList removeFromLinkerInputAssemblies, bool generateTargetFrameworkAttribute) + { + foreach (var setupCompileInfo in _metadataProvider.GetSetupCompileAssembliesBefore()) + { + NPath outputFolder; + if (setupCompileInfo.OutputSubFolder == null) + { + outputFolder = outputDirectory; + } + else + { + outputFolder = outputDirectory.Combine(setupCompileInfo.OutputSubFolder); + Directory.CreateDirectory(outputFolder.ToString()); + } + + var options = CreateOptionsForSupportingAssembly( + setupCompileInfo, + outputFolder, + CollectSetupBeforeSourcesFiles(setupCompileInfo), + references, + defines, + CollectSetupBeforeResourcesFiles(setupCompileInfo), + generateTargetFrameworkAttribute); + var output = CompileAssembly(options); + + if (setupCompileInfo.RemoveFromLinkerInput) + removeFromLinkerInputAssemblies.Add(output); + + if (setupCompileInfo.AddAsReference) + yield return output; + } + } + + private void CompileAfterTestCaseAssemblies(NPath outputDirectory, NPath[] references, string[] defines, IList removeFromLinkerInputAssemblies, bool generateTargetFrameworkAttribute) + { + foreach (var setupCompileInfo in _metadataProvider.GetSetupCompileAssembliesAfter()) + { + var options = CreateOptionsForSupportingAssembly( + setupCompileInfo, + outputDirectory, + CollectSetupAfterSourcesFiles(setupCompileInfo), + references, + defines, + CollectSetupAfterResourcesFiles(setupCompileInfo), + generateTargetFrameworkAttribute); + var output = CompileAssembly(options); + + if (setupCompileInfo.RemoveFromLinkerInput) + removeFromLinkerInputAssemblies.Add(output); + } + } + + private NPath[] CollectSetupBeforeSourcesFiles(SetupCompileInfo info) + { + return CollectSourceFilesFrom(_sandbox.BeforeReferenceSourceDirectoryFor(info.OutputName)); + } + + private NPath[] CollectSetupAfterSourcesFiles(SetupCompileInfo info) + { + return CollectSourceFilesFrom(_sandbox.AfterReferenceSourceDirectoryFor(info.OutputName)); + } + + private NPath[] CollectSetupBeforeResourcesFiles(SetupCompileInfo info) + { + return _sandbox.BeforeReferenceResourceDirectoryFor(info.OutputName).Files().ToArray(); + } + + private NPath[] CollectSetupAfterResourcesFiles(SetupCompileInfo info) + { + return _sandbox.AfterReferenceResourceDirectoryFor(info.OutputName).Files().ToArray(); + } + + private NPath[] CollectSourceFilesFrom(NPath directory) + { + var sourceFiles = directory.Files("*.cs"); + if (sourceFiles.Any()) + return sourceFiles.Concat(_metadataProvider.GetCommonSourceFiles()).ToArray(); + + sourceFiles = directory.Files("*.il"); + if (sourceFiles.Any()) + return sourceFiles.ToArray(); + + throw new FileNotFoundException($"Didn't find any sources files in {directory}"); + } + + protected static NPath MakeSupportingAssemblyReferencePathAbsolute(NPath outputDirectory, string referenceFileName) + { + // Not a good idea to use a full path in a test, but maybe someone is trying to quickly test something locally + if (Path.IsPathRooted(referenceFileName)) + return referenceFileName.ToNPath(); #if NET - if (referenceFileName.StartsWith ("System.", StringComparison.Ordinal) || - referenceFileName.StartsWith ("Mono.", StringComparison.Ordinal) || - referenceFileName.StartsWith ("Microsoft.", StringComparison.Ordinal) || - referenceFileName == "netstandard.dll") { - - var frameworkDir = Path.GetFullPath (Path.GetDirectoryName (typeof (object).Assembly.Location)!); - var filePath = Path.Combine (frameworkDir, referenceFileName); - - if (File.Exists (filePath)) - return filePath.ToNPath (); - } + if (referenceFileName.StartsWith("System.", StringComparison.Ordinal) || + referenceFileName.StartsWith("Mono.", StringComparison.Ordinal) || + referenceFileName.StartsWith("Microsoft.", StringComparison.Ordinal) || + referenceFileName == "netstandard.dll") + { + + var frameworkDir = Path.GetFullPath(Path.GetDirectoryName(typeof(object).Assembly.Location)!); + var filePath = Path.Combine(frameworkDir, referenceFileName); + + if (File.Exists(filePath)) + return filePath.ToNPath(); + } #endif - var possiblePath = outputDirectory.Combine (referenceFileName); - if (possiblePath.FileExists ()) - return possiblePath; + var possiblePath = outputDirectory.Combine(referenceFileName); + if (possiblePath.FileExists()) + return possiblePath; - return referenceFileName.ToNPath (); - } + return referenceFileName.ToNPath(); + } - protected NPath CompileAssembly (CompilerOptions options) - { - if (options.SourceFiles.Any (path => path.ExtensionWithDot == ".cs")) - return CompileCSharpAssembly (options); + protected NPath CompileAssembly(CompilerOptions options) + { + if (options.SourceFiles.Any(path => path.ExtensionWithDot == ".cs")) + return CompileCSharpAssembly(options); - if (options.SourceFiles.Any (path => path.ExtensionWithDot == ".il")) - return CompileIlAssembly (options); + if (options.SourceFiles.Any(path => path.ExtensionWithDot == ".il")) + return CompileIlAssembly(options); - throw new NotSupportedException ($"Unable to compile sources files with extension `{options.SourceFiles.First ().ExtensionWithDot}`"); - } + throw new NotSupportedException($"Unable to compile sources files with extension `{options.SourceFiles.First().ExtensionWithDot}`"); + } - protected virtual NPath CompileCSharpAssemblyWithDefaultCompiler (CompilerOptions options) - { + protected virtual NPath CompileCSharpAssemblyWithDefaultCompiler(CompilerOptions options) + { #if NET - return CompileCSharpAssemblyWithRoslyn (options); + return CompileCSharpAssemblyWithRoslyn(options); #else - return CompileCSharpAssemblyWithCsc (options); + return CompileCSharpAssemblyWithCsc(options); #endif - } + } #if NET - protected virtual NPath CompileCSharpAssemblyWithRoslyn (CompilerOptions options) - { - var languageVersion = LanguageVersion.Default; - var compilationOptions = new CSharpCompilationOptions ( - outputKind: options.OutputPath.FileName.EndsWith (".exe") ? OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary, - assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default - ); - // Default debug info format for the current platform. - DebugInformationFormat debugType = RuntimeInformation.IsOSPlatform (OSPlatform.Windows) ? DebugInformationFormat.Pdb : DebugInformationFormat.PortablePdb; - bool emitPdb = false; - if (options.AdditionalArguments != null) { - foreach (var option in options.AdditionalArguments) { - switch (option) { - case "/unsafe": - compilationOptions = compilationOptions.WithAllowUnsafe (true); - break; - case "/optimize+": - compilationOptions = compilationOptions.WithOptimizationLevel (OptimizationLevel.Release); - break; - case "/optimize-": - compilationOptions = compilationOptions.WithOptimizationLevel (OptimizationLevel.Debug); - break; - case "/debug:full": - case "/debug:pdbonly": - // Use platform's default debug info. This behavior is the same as csc. - emitPdb = true; - break; - case "/debug:portable": - emitPdb = true; - debugType = DebugInformationFormat.PortablePdb; - break; - case "/debug:embedded": - emitPdb = true; - debugType = DebugInformationFormat.Embedded; - break; - case "/langversion:7.3": - languageVersion = LanguageVersion.CSharp7_3; - break; - default: - var splitIndex = option.IndexOf (":"); - if (splitIndex != -1 && option[..splitIndex] == "/main") { - var mainTypeName = option[(splitIndex + 1)..]; - compilationOptions = compilationOptions.WithMainTypeName (mainTypeName); - break; - } - throw new NotImplementedException (option); - } - } - } - var parseOptions = new CSharpParseOptions (preprocessorSymbols: options.Defines, languageVersion: languageVersion); - var emitOptions = new EmitOptions (debugInformationFormat: debugType); - var pdbPath = (!emitPdb || debugType == DebugInformationFormat.Embedded) ? null : options.OutputPath.ChangeExtension (".pdb").ToString (); - - var syntaxTrees = options.SourceFiles.Select (p => - CSharpSyntaxTree.ParseText ( - text: p.ReadAllText (), - options: parseOptions - ) - ); - - var compilation = CSharpCompilation.Create ( - assemblyName: options.OutputPath.FileNameWithoutExtension, - syntaxTrees: syntaxTrees, - references: options.References.Select (r => MetadataReference.CreateFromFile (r)), - options: compilationOptions - ); - - var manifestResources = options.Resources.Select (r => { - var fullPath = r.ToString (); - return new ResourceDescription ( - resourceName: Path.GetFileName (fullPath), - dataProvider: () => new FileStream (fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), - isPublic: true - ); - }); - - EmitResult result; - using (var outputStream = File.Create (options.OutputPath.ToString ())) - using (var pdbStream = pdbPath == null ? null : File.Create (pdbPath)) { - result = compilation.Emit ( - peStream: outputStream, - pdbStream: pdbStream, - manifestResources: manifestResources, - options: emitOptions - ); - } - - var errors = new StringBuilder (); - if (result.Success) - return options.OutputPath; - - foreach (var diagnostic in result.Diagnostics) - errors.AppendLine (diagnostic.ToString ()); - throw new Exception ("Roslyn compilation errors: " + errors); - } + protected virtual NPath CompileCSharpAssemblyWithRoslyn(CompilerOptions options) + { + var languageVersion = LanguageVersion.Default; + var compilationOptions = new CSharpCompilationOptions( + outputKind: options.OutputPath.FileName.EndsWith(".exe") ? OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary, + assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default + ); + // Default debug info format for the current platform. + DebugInformationFormat debugType = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? DebugInformationFormat.Pdb : DebugInformationFormat.PortablePdb; + bool emitPdb = false; + if (options.AdditionalArguments != null) + { + foreach (var option in options.AdditionalArguments) + { + switch (option) + { + case "/unsafe": + compilationOptions = compilationOptions.WithAllowUnsafe(true); + break; + case "/optimize+": + compilationOptions = compilationOptions.WithOptimizationLevel(OptimizationLevel.Release); + break; + case "/optimize-": + compilationOptions = compilationOptions.WithOptimizationLevel(OptimizationLevel.Debug); + break; + case "/debug:full": + case "/debug:pdbonly": + // Use platform's default debug info. This behavior is the same as csc. + emitPdb = true; + break; + case "/debug:portable": + emitPdb = true; + debugType = DebugInformationFormat.PortablePdb; + break; + case "/debug:embedded": + emitPdb = true; + debugType = DebugInformationFormat.Embedded; + break; + case "/langversion:7.3": + languageVersion = LanguageVersion.CSharp7_3; + break; + default: + var splitIndex = option.IndexOf(":"); + if (splitIndex != -1 && option[..splitIndex] == "/main") + { + var mainTypeName = option[(splitIndex + 1)..]; + compilationOptions = compilationOptions.WithMainTypeName(mainTypeName); + break; + } + throw new NotImplementedException(option); + } + } + } + var parseOptions = new CSharpParseOptions(preprocessorSymbols: options.Defines, languageVersion: languageVersion); + var emitOptions = new EmitOptions(debugInformationFormat: debugType); + var pdbPath = (!emitPdb || debugType == DebugInformationFormat.Embedded) ? null : options.OutputPath.ChangeExtension(".pdb").ToString(); + + var syntaxTrees = options.SourceFiles.Select(p => + CSharpSyntaxTree.ParseText( + text: p.ReadAllText(), + options: parseOptions, + path: p.ToString(), + Encoding.UTF8 + ) + ).ToList(); + + if (options.GenerateTargetFrameworkAttribute) + { + syntaxTrees.Add(CSharpSyntaxTree.ParseText( + text: GenerateTargetFrameworkAttributeSource(), + options: parseOptions, + path: "AssemblyInfo.g.cs", + Encoding.UTF8 + )); + } + + var compilation = CSharpCompilation.Create( + assemblyName: options.OutputPath.FileNameWithoutExtension, + syntaxTrees: syntaxTrees, + references: options.References.Select(r => MetadataReference.CreateFromFile(r)), + options: compilationOptions + ); + + var manifestResources = options.Resources.Select(r => + { + var fullPath = r.ToString(); + return new ResourceDescription( + resourceName: Path.GetFileName(fullPath), + dataProvider: () => new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), + isPublic: true + ); + }); + + EmitResult result; + using (var outputStream = File.Create(options.OutputPath.ToString())) + using (var pdbStream = pdbPath == null ? null : File.Create(pdbPath)) + { + result = compilation.Emit( + peStream: outputStream, + pdbStream: pdbStream, + manifestResources: manifestResources, + options: emitOptions + ); + } + + var errors = new StringBuilder(); + if (result.Success) + return options.OutputPath; + + foreach (var diagnostic in result.Diagnostics) + errors.AppendLine(diagnostic.ToString()); + throw new Exception("Roslyn compilation errors: " + errors); + } #endif - protected virtual NPath CompileCSharpAssemblyWithCsc (CompilerOptions options) - { + protected virtual NPath CompileCSharpAssemblyWithCsc(CompilerOptions options) + { #if NET - return CompileCSharpAssemblyWithRoslyn (options); + return CompileCSharpAssemblyWithRoslyn(options); #else - return CompileCSharpAssemblyWithExternalCompiler (LocateCscExecutable (), options, "/shared "); + return CompileCSharpAssemblyWithExternalCompiler(LocateCscExecutable(), options, "/shared "); #endif - } - - protected virtual NPath CompileCSharpAssemblyWithMcs (CompilerOptions options) - { - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - CompileCSharpAssemblyWithExternalCompiler (LocateMcsExecutable (), options, string.Empty); - - return CompileCSharpAssemblyWithDefaultCompiler (options); - } - - protected NPath CompileCSharpAssemblyWithExternalCompiler (string executable, CompilerOptions options, string compilerSpecificArguments) - { - var capturedOutput = new List (); - var process = new Process (); - process.StartInfo.FileName = executable; - process.StartInfo.Arguments = OptionsToCompilerCommandLineArguments (options, compilerSpecificArguments); - process.StartInfo.UseShellExecute = false; - process.StartInfo.CreateNoWindow = true; - process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; - process.StartInfo.RedirectStandardOutput = true; - process.OutputDataReceived += (sender, args) => capturedOutput.Add (args.Data!); - process.Start (); - process.BeginOutputReadLine (); - process.WaitForExit (); - - if (process.ExitCode != 0) - Assert.Fail($"Failed to compile assembly with csc: {options.OutputPath}\n{capturedOutput.Aggregate ((buff, s) => buff + Environment.NewLine + s)}"); - - return options.OutputPath; - } - - private static string LocateMcsExecutable () - { - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - throw new IgnoreTestException ("We don't have a universal way of locating mcs on Windows"); - - return "mcs"; - } - - protected string OptionsToCompilerCommandLineArguments (CompilerOptions options, string compilerSpecificArguments) - { - var builder = new StringBuilder (); - if (!string.IsNullOrEmpty (compilerSpecificArguments)) - builder.Append (compilerSpecificArguments); - builder.Append ($"/out:{options.OutputPath}"); - var target = options.OutputPath.ExtensionWithDot == ".exe" ? "exe" : "library"; - builder.Append ($" /target:{target}"); - if (options.Defines != null && options.Defines.Length > 0) - builder.Append (options.Defines.Aggregate (string.Empty, (buff, arg) => $"{buff} /define:{arg}")); - - builder.Append (options.References.Aggregate (string.Empty, (buff, arg) => $"{buff} /r:{arg}")); - - if (options.Resources != null && options.Resources.Length > 0) - builder.Append (options.Resources.Aggregate (string.Empty, (buff, arg) => $"{buff} /res:{arg}")); - - if (options.AdditionalArguments != null && options.AdditionalArguments.Length > 0) - builder.Append (options.AdditionalArguments.Aggregate (string.Empty, (buff, arg) => $"{buff} {arg}")); - - builder.Append (options.SourceFiles.Aggregate (string.Empty, (buff, arg) => $"{buff} {arg}")); - - return builder.ToString (); - } - - protected NPath CompileCSharpAssembly (CompilerOptions options) - { - if (string.IsNullOrEmpty (options.CompilerToUse)) - return CompileCSharpAssemblyWithDefaultCompiler (options); - - if (options.CompilerToUse == "csc") - return CompileCSharpAssemblyWithCsc (options); - - if (options.CompilerToUse == "mcs") - return CompileCSharpAssemblyWithMcs (options); - - throw new ArgumentException ($"Invalid compiler value `{options.CompilerToUse}`"); - } - - protected NPath CompileIlAssembly (CompilerOptions options) - { - return _ilCompiler.Compile (options); - } - } + } + + protected virtual NPath CompileCSharpAssemblyWithMcs(CompilerOptions options) + { + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + CompileCSharpAssemblyWithExternalCompiler(LocateMcsExecutable(), options, string.Empty); + + return CompileCSharpAssemblyWithDefaultCompiler(options); + } + + protected NPath CompileCSharpAssemblyWithExternalCompiler(string executable, CompilerOptions options, string compilerSpecificArguments) + { + var capturedOutput = new List(); + var process = new Process(); + process.StartInfo.FileName = executable; + process.StartInfo.Arguments = OptionsToCompilerCommandLineArguments(options, compilerSpecificArguments); + process.StartInfo.UseShellExecute = false; + process.StartInfo.CreateNoWindow = true; + process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + process.StartInfo.RedirectStandardOutput = true; + process.OutputDataReceived += (sender, args) => capturedOutput.Add(args.Data!); + process.Start(); + process.BeginOutputReadLine(); + process.WaitForExit(); + + if (process.ExitCode != 0) + Assert.Fail($"Failed to compile assembly with csc: {options.OutputPath}\n{capturedOutput.Aggregate((buff, s) => buff + Environment.NewLine + s)}"); + + return options.OutputPath; + } + + private static string LocateMcsExecutable() + { + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + throw new IgnoreTestException("We don't have a universal way of locating mcs on Windows"); + + return "mcs"; + } + + protected string OptionsToCompilerCommandLineArguments(CompilerOptions options, string compilerSpecificArguments) + { + var builder = new StringBuilder(); + if (!string.IsNullOrEmpty(compilerSpecificArguments)) + builder.Append(compilerSpecificArguments); + builder.Append($"/out:{options.OutputPath}"); + var target = options.OutputPath.ExtensionWithDot == ".exe" ? "exe" : "library"; + builder.Append($" /target:{target}"); + if (options.Defines != null && options.Defines.Length > 0) + builder.Append(options.Defines.Aggregate(string.Empty, (buff, arg) => $"{buff} /define:{arg}")); + + builder.Append(options.References.Aggregate(string.Empty, (buff, arg) => $"{buff} /r:{arg}")); + + if (options.Resources != null && options.Resources.Length > 0) + builder.Append(options.Resources.Aggregate(string.Empty, (buff, arg) => $"{buff} /res:{arg}")); + + if (options.AdditionalArguments != null && options.AdditionalArguments.Length > 0) + builder.Append(options.AdditionalArguments.Aggregate(string.Empty, (buff, arg) => $"{buff} {arg}")); + + builder.Append(options.SourceFiles.Aggregate(string.Empty, (buff, arg) => $"{buff} {arg}")); + + return builder.ToString(); + } + + protected NPath CompileCSharpAssembly(CompilerOptions options) + { + if (string.IsNullOrEmpty(options.CompilerToUse)) + return CompileCSharpAssemblyWithDefaultCompiler(options); + + if (options.CompilerToUse == "csc") + return CompileCSharpAssemblyWithCsc(options); + + if (options.CompilerToUse == "mcs") + return CompileCSharpAssemblyWithMcs(options); + + throw new ArgumentException($"Invalid compiler value `{options.CompilerToUse}`"); + } + + protected NPath CompileIlAssembly(CompilerOptions options) + { + return _ilCompiler.Compile(options); + } + + private string GenerateTargetFrameworkAttributeSource() + { + var tfm = PathUtilities.TargetFrameworkMoniker; + var tfmDisplayName = PathUtilities.TargetFrameworkMonikerDisplayName; + return $""" + [assembly: System.Runtime.Versioning.TargetFramework("{tfm}", FrameworkDisplayName = "{tfmDisplayName}")] + """; + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseLinkerOptions.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseLinkerOptions.cs index 29d34834129e5c..bfb43fb162fcde 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseLinkerOptions.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseLinkerOptions.cs @@ -7,32 +7,32 @@ namespace Mono.Linker.Tests.TestCasesRunner { - public class TestCaseLinkerOptions - { - public string TrimMode; - public string DefaultAssembliesAction; - public List<(string Action, string Assembly)> AssembliesAction = new(); - - public string Il8n; - public bool IgnoreDescriptors; - public bool IgnoreSubstitutions; - public bool IgnoreLinkAttributes; - public string KeepTypeForwarderOnlyAssemblies; - public string LinkSymbols; - public bool SkipUnresolved; - public bool StripDescriptors; - public bool StripSubstitutions; - public bool StripLinkAttributes; - public bool DumpDependencies; - - public bool IlcFrameworkCompilation; - - public List> AdditionalArguments = new List> (); - - public List Descriptors = new List (); - - public List Substitutions = new List (); - - public List LinkAttributes = new List (); - } + public class TestCaseLinkerOptions + { + public string TrimMode; + public string DefaultAssembliesAction; + public List<(string Action, string Assembly)> AssembliesAction = new(); + + public string Il8n; + public bool IgnoreDescriptors; + public bool IgnoreSubstitutions; + public bool IgnoreLinkAttributes; + public string KeepTypeForwarderOnlyAssemblies; + public string LinkSymbols; + public bool SkipUnresolved; + public bool StripDescriptors; + public bool StripSubstitutions; + public bool StripLinkAttributes; + public bool DumpDependencies; + + public bool IlcFrameworkCompilation; + + public List> AdditionalArguments = new List>(); + + public List Descriptors = new List(); + + public List Substitutions = new List(); + + public List LinkAttributes = new List(); + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseMetadataProvider.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseMetadataProvider.cs index a6c6a9543d6e13..15bbb2ac3d1f5a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseMetadataProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseMetadataProvider.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -8,141 +9,149 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; using Mono.Linker.Tests.Extensions; using Mono.Linker.Tests.TestCases; -using System; namespace Mono.Linker.Tests.TestCasesRunner { - public class TestCaseMetadataProvider : BaseMetadataProvider - { - public TestCaseMetadataProvider (TestCase testCase, AssemblyDefinition fullTestCaseAssemblyDefinition) - : base (testCase, fullTestCaseAssemblyDefinition) - { - } - - public virtual TestCaseLinkerOptions GetLinkerOptions (NPath inputPath) - { - var tclo = new TestCaseLinkerOptions { - Il8n = GetOptionAttributeValue (nameof (Il8nAttribute), "none"), - IgnoreDescriptors = GetOptionAttributeValue (nameof (IgnoreDescriptorsAttribute), true), - IgnoreSubstitutions = GetOptionAttributeValue (nameof (IgnoreSubstitutionsAttribute), true), - IgnoreLinkAttributes = GetOptionAttributeValue (nameof (IgnoreLinkAttributesAttribute), true), - KeepTypeForwarderOnlyAssemblies = GetOptionAttributeValue (nameof (KeepTypeForwarderOnlyAssembliesAttribute), string.Empty), - LinkSymbols = GetOptionAttributeValue (nameof (SetupLinkerLinkSymbolsAttribute), string.Empty), - TrimMode = GetOptionAttributeValue (nameof (SetupLinkerTrimModeAttribute), null), - DefaultAssembliesAction = GetOptionAttributeValue (nameof (SetupLinkerDefaultActionAttribute), null), - SkipUnresolved = GetOptionAttributeValue (nameof (SkipUnresolvedAttribute), false), - StripDescriptors = GetOptionAttributeValue (nameof (StripDescriptorsAttribute), true), - StripSubstitutions = GetOptionAttributeValue (nameof (StripSubstitutionsAttribute), true), - StripLinkAttributes = GetOptionAttributeValue (nameof (StripLinkAttributesAttribute), true), - DumpDependencies = GetOptionAttribute (nameof (DumpDependenciesAttribute)), - IlcFrameworkCompilation = _testCaseTypeDefinition.HasAttribute (nameof (SetupIlcWholeProgramAnalysisAttribute)), - }; - - foreach (var assemblyAction in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (SetupLinkerActionAttribute))) { - var ca = assemblyAction.ConstructorArguments; - tclo.AssembliesAction.Add (((string) ca[0].Value, (string) ca[1].Value)); - } - - foreach (var descFile in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (SetupLinkerDescriptorFile))) { - var ca = descFile.ConstructorArguments; - var file = (string) ca[0].Value; - tclo.Descriptors.Add (Path.Combine (inputPath, file)); - } - - foreach (var subsFile in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (SetupLinkerSubstitutionFileAttribute))) { - var ca = subsFile.ConstructorArguments; - var file = (string) ca[0].Value; - tclo.Substitutions.Add (Path.Combine (inputPath, file)); - } - - foreach (var linkAttrFile in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (SetupLinkAttributesFile))) { - var ca = linkAttrFile.ConstructorArguments; - var file = (string) ca[0].Value; - tclo.LinkAttributes.Add (Path.Combine (inputPath, file)); - } - - foreach (var additionalArgumentAttr in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (SetupLinkerArgumentAttribute))) { - var ca = additionalArgumentAttr.ConstructorArguments; - var values = ((CustomAttributeArgument[]) ca[1].Value)!.Select (arg => arg.Value.ToString ()!).ToArray (); - // Since custom attribute arguments need to be constant expressions, we need to add - // the path to the temp directory (where the custom assembly is located) here. - switch ((string) ca[0].Value) { - case "--custom-step": - int pos = values[0].IndexOf (","); - if (pos != -1) { - string custom_assembly_path = values[0].Substring (pos + 1); - if (!Path.IsPathRooted (custom_assembly_path)) - values[0] = string.Concat (values[0].AsSpan (0, pos + 1), Path.Combine (inputPath, custom_assembly_path)); - } - break; - case "-a": - if (!Path.IsPathRooted (values[0])) - values[0] = Path.Combine (inputPath, values[0]); - - break; - } - - tclo.AdditionalArguments.Add (new KeyValuePair ((string) ca[0].Value, values)); - } - - return tclo; - } - - public virtual IEnumerable GetResponseFiles () - { - return _testCaseTypeDefinition.CustomAttributes - .Where (attr => attr.AttributeType.Name == nameof (SetupLinkerResponseFileAttribute)) - .Select (GetSourceAndRelativeDestinationValue); - } - - public virtual IEnumerable GetDescriptorFiles () - { - return _testCaseTypeDefinition.CustomAttributes - .Where (attr => attr.AttributeType.Name == nameof (SetupLinkerDescriptorFile)) - .Select (GetSourceAndRelativeDestinationValue); - } - - public virtual IEnumerable GetSubstitutionFiles () - { - return _testCaseTypeDefinition.CustomAttributes - .Where (attr => attr.AttributeType.Name == nameof (SetupLinkerSubstitutionFileAttribute)) - .Select (GetSourceAndRelativeDestinationValue); - } - - public virtual IEnumerable GetLinkAttributesFiles () - { - return _testCaseTypeDefinition.CustomAttributes - .Where (attr => attr.AttributeType.Name == nameof (SetupLinkAttributesFile)) - .Select (GetSourceAndRelativeDestinationValue); - } - - public IEnumerable GetDeleteBefore () - { - return _testCaseTypeDefinition.CustomAttributes - .Where (attr => attr.AttributeType.Name == nameof (DeleteBeforeAttribute)) - .Select (attr => (string)attr.ConstructorArguments[0].Value); - } - - public virtual IEnumerable GetExtraLinkerReferences () - { - var netcoreappDir = Path.GetDirectoryName (typeof (object).Assembly.Location)!; - foreach (var assembly in Directory.EnumerateFiles (netcoreappDir)) { - if (Path.GetExtension (assembly) != ".dll") - continue; - var assemblyName = Path.GetFileNameWithoutExtension (assembly); - if (assemblyName.Contains ("Native")) - continue; - if (assemblyName.StartsWith ("Microsoft") || - assemblyName.StartsWith ("System") || - assemblyName == "mscorlib" || assemblyName == "netstandard") - yield return assembly.ToNPath (); - } - } - - public virtual bool LinkPublicAndFamily () - { - return _testCaseTypeDefinition.CustomAttributes - .FirstOrDefault (attr => attr.AttributeType.Name == nameof (SetupLinkerLinkPublicAndFamilyAttribute)) != null; - } - } + public class TestCaseMetadataProvider : BaseMetadataProvider + { + public TestCaseMetadataProvider(TestCase testCase, AssemblyDefinition fullTestCaseAssemblyDefinition) + : base(testCase, fullTestCaseAssemblyDefinition) + { + } + + public virtual TestCaseLinkerOptions GetLinkerOptions(NPath inputPath) + { + var tclo = new TestCaseLinkerOptions + { + Il8n = GetOptionAttributeValue(nameof(Il8nAttribute), "none"), + IgnoreDescriptors = GetOptionAttributeValue(nameof(IgnoreDescriptorsAttribute), true), + IgnoreSubstitutions = GetOptionAttributeValue(nameof(IgnoreSubstitutionsAttribute), true), + IgnoreLinkAttributes = GetOptionAttributeValue(nameof(IgnoreLinkAttributesAttribute), true), + KeepTypeForwarderOnlyAssemblies = GetOptionAttributeValue(nameof(KeepTypeForwarderOnlyAssembliesAttribute), string.Empty), + LinkSymbols = GetOptionAttributeValue(nameof(SetupLinkerLinkSymbolsAttribute), string.Empty), + TrimMode = GetOptionAttributeValue(nameof(SetupLinkerTrimModeAttribute), null), + DefaultAssembliesAction = GetOptionAttributeValue(nameof(SetupLinkerDefaultActionAttribute), null), + SkipUnresolved = GetOptionAttributeValue(nameof(SkipUnresolvedAttribute), false), + StripDescriptors = GetOptionAttributeValue(nameof(StripDescriptorsAttribute), true), + StripSubstitutions = GetOptionAttributeValue(nameof(StripSubstitutionsAttribute), true), + StripLinkAttributes = GetOptionAttributeValue(nameof(StripLinkAttributesAttribute), true), + DumpDependencies = GetOptionAttribute(nameof(DumpDependenciesAttribute)), + IlcFrameworkCompilation = _testCaseTypeDefinition.HasAttribute(nameof(SetupIlcWholeProgramAnalysisAttribute)), + }; + + foreach (var assemblyAction in _testCaseTypeDefinition.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(SetupLinkerActionAttribute))) + { + var ca = assemblyAction.ConstructorArguments; + tclo.AssembliesAction.Add(((string)ca[0].Value, (string)ca[1].Value)); + } + + foreach (var descFile in _testCaseTypeDefinition.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(SetupLinkerDescriptorFile))) + { + var ca = descFile.ConstructorArguments; + var file = (string)ca[0].Value; + tclo.Descriptors.Add(Path.Combine(inputPath, file)); + } + + foreach (var subsFile in _testCaseTypeDefinition.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(SetupLinkerSubstitutionFileAttribute))) + { + var ca = subsFile.ConstructorArguments; + var file = (string)ca[0].Value; + tclo.Substitutions.Add(Path.Combine(inputPath, file)); + } + + foreach (var linkAttrFile in _testCaseTypeDefinition.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(SetupLinkAttributesFile))) + { + var ca = linkAttrFile.ConstructorArguments; + var file = (string)ca[0].Value; + tclo.LinkAttributes.Add(Path.Combine(inputPath, file)); + } + + foreach (var additionalArgumentAttr in _testCaseTypeDefinition.CustomAttributes.Where(attr => attr.AttributeType.Name == nameof(SetupLinkerArgumentAttribute))) + { + var ca = additionalArgumentAttr.ConstructorArguments; + var values = ((CustomAttributeArgument[])ca[1].Value)!.Select(arg => arg.Value.ToString()!).ToArray(); + // Since custom attribute arguments need to be constant expressions, we need to add + // the path to the temp directory (where the custom assembly is located) here. + switch ((string)ca[0].Value) + { + case "--custom-step": + int pos = values[0].IndexOf(","); + if (pos != -1) + { + string custom_assembly_path = values[0].Substring(pos + 1); + if (!Path.IsPathRooted(custom_assembly_path)) + values[0] = string.Concat(values[0].AsSpan(0, pos + 1), Path.Combine(inputPath, custom_assembly_path)); + } + break; + case "-a": + if (!Path.IsPathRooted(values[0])) + values[0] = Path.Combine(inputPath, values[0]); + + break; + } + + tclo.AdditionalArguments.Add(new KeyValuePair((string)ca[0].Value, values)); + } + + return tclo; + } + + public virtual IEnumerable GetResponseFiles() + { + return _testCaseTypeDefinition.CustomAttributes + .Where(attr => attr.AttributeType.Name == nameof(SetupLinkerResponseFileAttribute)) + .Select(GetSourceAndRelativeDestinationValue); + } + + public virtual IEnumerable GetDescriptorFiles() + { + return _testCaseTypeDefinition.CustomAttributes + .Where(attr => attr.AttributeType.Name == nameof(SetupLinkerDescriptorFile)) + .Select(GetSourceAndRelativeDestinationValue); + } + + public virtual IEnumerable GetSubstitutionFiles() + { + return _testCaseTypeDefinition.CustomAttributes + .Where(attr => attr.AttributeType.Name == nameof(SetupLinkerSubstitutionFileAttribute)) + .Select(GetSourceAndRelativeDestinationValue); + } + + public virtual IEnumerable GetLinkAttributesFiles() + { + return _testCaseTypeDefinition.CustomAttributes + .Where(attr => attr.AttributeType.Name == nameof(SetupLinkAttributesFile)) + .Select(GetSourceAndRelativeDestinationValue); + } + + public IEnumerable GetDeleteBefore() + { + return _testCaseTypeDefinition.CustomAttributes + .Where(attr => attr.AttributeType.Name == nameof(DeleteBeforeAttribute)) + .Select(attr => (string)attr.ConstructorArguments[0].Value); + } + + public virtual IEnumerable GetExtraLinkerReferences() + { + var netcoreappDir = Path.GetDirectoryName(typeof(object).Assembly.Location)!; + foreach (var assembly in Directory.EnumerateFiles(netcoreappDir)) + { + if (Path.GetExtension(assembly) != ".dll") + continue; + var assemblyName = Path.GetFileNameWithoutExtension(assembly); + if (assemblyName.Contains("Native")) + continue; + if (assemblyName.StartsWith("Microsoft") || + assemblyName.StartsWith("System") || + assemblyName == "mscorlib" || assemblyName == "netstandard") + yield return assembly.ToNPath(); + } + } + + public virtual bool LinkPublicAndFamily() + { + return _testCaseTypeDefinition.CustomAttributes + .FirstOrDefault(attr => attr.AttributeType.Name == nameof(SetupLinkerLinkPublicAndFamilyAttribute)) != null; + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseSandbox.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseSandbox.cs index c3cd3fbcd3b3ae..49f8c79da90ee6 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseSandbox.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseSandbox.cs @@ -10,17 +10,17 @@ namespace Mono.Linker.Tests.TestCasesRunner { - partial class TestCaseSandbox - { - private const string _linkerAssemblyPath = "";//typeof (Trimmer).Assembly.Location; + partial class TestCaseSandbox + { + private const string _linkerAssemblyPath = ""; // typeof(Trimmer).Assembly.Location; - private static partial NPath GetArtifactsTestPath () - { - // Converts paths like /root-folder/runtime/artifacts/bin/Mono.Linker.Tests/x64/Debug/Mono.Linker.Tests.dll - // to /root-folder/runtime/artifacts/bin/ILLink.testcases/ - string artifacts = (string) AppContext.GetData ("Mono.Linker.Tests.ArtifactsBinDir")!; - string tests = Path.Combine (artifacts, "ILLink.testcases"); - return new NPath (tests); - } - } + private static partial NPath GetArtifactsTestPath() + { + // Converts paths like /root-folder/runtime/artifacts/bin/Mono.Linker.Tests/x64/Debug/Mono.Linker.Tests.dll + // to /root-folder/runtime/artifacts/bin/ILLink.testcases/ + string artifacts = (string)AppContext.GetData("Mono.Linker.Tests.ArtifactsBinDir")!; + string tests = Path.Combine(artifacts, "ILLink.testcases"); + return new NPath(tests); + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestInfraMultiFileCompilationModuleGroup.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestInfraMultiFileCompilationModuleGroup.cs index b8c44ab2b35568..33d76b172f8772 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestInfraMultiFileCompilationModuleGroup.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestInfraMultiFileCompilationModuleGroup.cs @@ -10,50 +10,51 @@ namespace Mono.Linker.Tests.TestCasesRunner { - /// - /// Represents a non-leaf multifile compilation group where types contained in the group are always fully expanded. - /// - public class TestInfraMultiFileSharedCompilationModuleGroup : MultiFileCompilationModuleGroup - { - public TestInfraMultiFileSharedCompilationModuleGroup (CompilerTypeSystemContext context, IEnumerable compilationModuleSet) - : base (context, compilationModuleSet) - { - } - - public override bool ShouldProduceFullVTable (TypeDesc type) - { - return false; - } - - public override bool ShouldPromoteToFullType (TypeDesc type) - { - return ShouldProduceFullVTable (type); - } - - public override bool PresenceOfEETypeImpliesAllMethodsOnType (TypeDesc type) - { - return (type.HasInstantiation || type.IsArray) && ShouldProduceFullVTable (type) && - type.ConvertToCanonForm (CanonicalFormKind.Specific).IsCanonicalSubtype (CanonicalFormKind.Any); - } - - public override bool AllowInstanceMethodOptimization (MethodDesc method) - { - // Both the instance methods and the owning type are homed in a single compilation group - // so if we're able to generate the body, we would also generate the owning type here - // and nowhere else. - if (ContainsMethodBody (method, unboxingStub: false)) { - TypeDesc owningType = method.OwningType; - return owningType.IsDefType && !owningType.HasInstantiation && !method.HasInstantiation; - } - return false; - } - - public override bool AllowVirtualMethodOnAbstractTypeOptimization (MethodDesc method) - { - // Not really safe to do this since we need to assume IgnoreAccessChecks - // and we wouldn't know all derived types when compiling methods on the type - // that introduces this method. - return false; - } - } + /// + /// Represents a non-leaf multifile compilation group where types contained in the group are always fully expanded. + /// + public class TestInfraMultiFileSharedCompilationModuleGroup : MultiFileCompilationModuleGroup + { + public TestInfraMultiFileSharedCompilationModuleGroup(CompilerTypeSystemContext context, IEnumerable compilationModuleSet) + : base(context, compilationModuleSet) + { + } + + public override bool ShouldProduceFullVTable(TypeDesc type) + { + return false; + } + + public override bool ShouldPromoteToFullType(TypeDesc type) + { + return ShouldProduceFullVTable(type); + } + + public override bool PresenceOfEETypeImpliesAllMethodsOnType(TypeDesc type) + { + return (type.HasInstantiation || type.IsArray) && ShouldProduceFullVTable(type) && + type.ConvertToCanonForm(CanonicalFormKind.Specific).IsCanonicalSubtype(CanonicalFormKind.Any); + } + + public override bool AllowInstanceMethodOptimization(MethodDesc method) + { + // Both the instance methods and the owning type are homed in a single compilation group + // so if we're able to generate the body, we would also generate the owning type here + // and nowhere else. + if (ContainsMethodBody(method, unboxingStub: false)) + { + TypeDesc owningType = method.OwningType; + return owningType.IsDefType && !owningType.HasInstantiation && !method.HasInstantiation; + } + return false; + } + + public override bool AllowVirtualMethodOnAbstractTypeOptimization(MethodDesc method) + { + // Not really safe to do this since we need to assume IgnoreAccessChecks + // and we wouldn't know all derived types when compiling methods on the type + // that introduces this method. + return false; + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestRunner.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestRunner.cs index 6be7c7ed5c0b0f..97bcdf2d79f735 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestRunner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestRunner.cs @@ -12,48 +12,52 @@ namespace Mono.Linker.Tests.TestCasesRunner { - public partial class TestRunner - { - partial void IgnoreTest (string reason) - { - throw new IgnoreTestException (reason); - } - - static IEnumerable additionalDefines = new string[] { "NATIVEAOT" }; - private partial IEnumerable? GetAdditionalDefines () => additionalDefines; - - private static T GetResultOfTaskThatMakesAssertions (Task task) - { - try { - return task.Result; - } catch (AggregateException e) { - if (e.InnerException != null) { - if (e.InnerException is XunitException) - throw e.InnerException; - } - - throw; - } - } - - protected partial TrimmingCustomizations? CustomizeTrimming (TrimmingDriver linker, TestCaseMetadataProvider metadataProvider) - => null; - - protected partial void AddDumpDependenciesOptions (TestCaseLinkerOptions caseDefinedOptions, ManagedCompilationResult compilationResult, TrimmingArgumentBuilder builder, TestCaseMetadataProvider metadataProvider) - { - } - - static partial void AddOutputDirectory (TestCaseSandbox sandbox, ManagedCompilationResult compilationResult, TrimmingArgumentBuilder builder) - { - builder.AddOutputDirectory (sandbox.OutputDirectory.Combine (compilationResult.InputAssemblyPath.FileNameWithoutExtension + ".obj")); - } - - static partial void AddInputReference (NPath inputReference, TrimmingArgumentBuilder builder) - { - // It's important to add all assemblies as "link" assemblies since the default configuration - // is to run the compiler in multi-file mode which will not process anything which is just in the reference set. - builder.AddLinkAssembly (inputReference); - builder.AddReference (inputReference); - } - } + public partial class TestRunner + { + partial void IgnoreTest(string reason) + { + throw new IgnoreTestException(reason); + } + + static IEnumerable additionalDefines = new string[] { "NATIVEAOT" }; + private partial IEnumerable? GetAdditionalDefines() => additionalDefines; + + private static T GetResultOfTaskThatMakesAssertions(Task task) + { + try + { + return task.Result; + } + catch (AggregateException e) + { + if (e.InnerException != null) + { + if (e.InnerException is XunitException) + throw e.InnerException; + } + + throw; + } + } + + protected partial TrimmingCustomizations? CustomizeTrimming(TrimmingDriver linker, TestCaseMetadataProvider metadataProvider) + => null; + + protected partial void AddDumpDependenciesOptions(TestCaseLinkerOptions caseDefinedOptions, ManagedCompilationResult compilationResult, TrimmingArgumentBuilder builder, TestCaseMetadataProvider metadataProvider) + { + } + + static partial void AddOutputDirectory(TestCaseSandbox sandbox, ManagedCompilationResult compilationResult, TrimmingArgumentBuilder builder) + { + builder.AddOutputDirectory(sandbox.OutputDirectory.Combine(compilationResult.InputAssemblyPath.FileNameWithoutExtension + ".obj")); + } + + static partial void AddInputReference(NPath inputReference, TrimmingArgumentBuilder builder) + { + // It's important to add all assemblies as "link" assemblies since the default configuration + // is to run the compiler in multi-file mode which will not process anything which is just in the reference set. + builder.AddLinkAssembly(inputReference); + builder.AddReference(inputReference); + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmedTestCaseResult.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmedTestCaseResult.cs index ed54092b7005b9..2a83391df3ec01 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmedTestCaseResult.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmedTestCaseResult.cs @@ -7,32 +7,32 @@ namespace Mono.Linker.Tests.TestCasesRunner { - partial class TrimmedTestCaseResult - { - public readonly ILScanResults TrimmingResults; + partial class TrimmedTestCaseResult + { + public readonly ILScanResults TrimmingResults; - public TrimmedTestCaseResult ( - TestCase testCase, - NPath inputAssemblyPath, - NPath outputAssemblyPath, - NPath expectationsAssemblyPath, - TestCaseSandbox sandbox, - TestCaseMetadataProvider metadataProvider, - ManagedCompilationResult compilationResult, - TrimmingTestLogger logger, - TrimmingCustomizations? customizations, - ILScanResults trimmingResults) - { - // Ignore outputAssemblyPath because ILCompiler trimming tests don't write output assemblies. - // Ignore TrimmingCustomizatoins which are not used by ILCompiler trimming tests. - TestCase = testCase; - InputAssemblyPath = inputAssemblyPath; - ExpectationsAssemblyPath = expectationsAssemblyPath; - Sandbox = sandbox; - MetadataProvider = metadataProvider; - CompilationResult = compilationResult; - Logger = logger; - TrimmingResults = trimmingResults; - } - } + public TrimmedTestCaseResult( + TestCase testCase, + NPath inputAssemblyPath, + NPath outputAssemblyPath, + NPath expectationsAssemblyPath, + TestCaseSandbox sandbox, + TestCaseMetadataProvider metadataProvider, + ManagedCompilationResult compilationResult, + TrimmingTestLogger logger, + TrimmingCustomizations? customizations, + ILScanResults trimmingResults) + { + // Ignore outputAssemblyPath because ILCompiler trimming tests don't write output assemblies. + // Ignore TrimmingCustomizatoins which are not used by ILCompiler trimming tests. + TestCase = testCase; + InputAssemblyPath = inputAssemblyPath; + ExpectationsAssemblyPath = expectationsAssemblyPath; + Sandbox = sandbox; + MetadataProvider = metadataProvider; + CompilationResult = compilationResult; + Logger = logger; + TrimmingResults = trimmingResults; + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs index e108cced4bde5a..2a06adb2875633 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs @@ -9,312 +9,327 @@ namespace Mono.Linker.Tests.TestCasesRunner { - public class TrimmingArgumentBuilder - { - private readonly TestCaseMetadataProvider _metadataProvider; - - private ILCompilerOptions? _options; - private ILCompilerOptions Options => _options ?? throw new InvalidOperationException ("Invalid state: Build() was already called"); - - public TrimmingArgumentBuilder (TestCaseMetadataProvider metadataProvider) - { - _options = new ILCompilerOptions (); - _metadataProvider = metadataProvider; - - string runtimeBinDir = (string) AppContext.GetData ("Mono.Linker.Tests.RuntimeBinDirectory")!; - AppendExpandedPaths (Options.ReferenceFilePaths, Path.Combine (runtimeBinDir, "aotsdk", "*.dll")); - - string runtimePackDir = (string) AppContext.GetData ("Mono.Linker.Tests.MicrosoftNetCoreAppRuntimePackDirectory")!; - if (!Directory.Exists (runtimePackDir) && runtimePackDir.Contains ("Debug")) { - // Frequently we'll have a Debug runtime and Release libraries, which actually produces a Release runtime pack - // but from within VS we're see Debug everything. So if the runtime pack directory doesn't exist - // try the Release path (simple string replace) - string candidate = runtimePackDir.Replace ("Debug", "Release"); - if (Directory.Exists (candidate)) - runtimePackDir = candidate; - } - AppendExpandedPaths (Options.ReferenceFilePaths, Path.Combine (runtimePackDir, "*.dll")); - - Options.InitAssemblies.Add ("System.Private.CoreLib"); - Options.InitAssemblies.Add ("System.Private.StackTraceMetadata"); - Options.InitAssemblies.Add ("System.Private.TypeLoader"); - Options.InitAssemblies.Add ("System.Private.Reflection.Execution"); - - Options.FeatureSwitches.Add ("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", false); - Options.FeatureSwitches.Add ("System.Resources.ResourceManager.AllowCustomResourceTypes", false); - Options.FeatureSwitches.Add ("System.Linq.Expressions.CanEmitObjectArrayDelegate", false); - Options.FeatureSwitches.Add ("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", false); - Options.FeatureSwitches.Add ("System.Diagnostics.Debugger.IsSupported", false); - Options.FeatureSwitches.Add ("System.Text.Encoding.EnableUnsafeUTF7Encoding", false); - Options.FeatureSwitches.Add ("System.Diagnostics.Tracing.EventSource.IsSupported", false); - Options.FeatureSwitches.Add ("System.Globalization.Invariant", true); - Options.FeatureSwitches.Add ("System.Resources.UseSystemResourceKeys", true); - - Options.FrameworkCompilation = false; - } - - public virtual void AddSearchDirectory (NPath directory) - { - } - - public virtual void AddReference (NPath path) - { - AppendExpandedPaths (Options.ReferenceFilePaths, path.ToString ()); - } - - public virtual void AddOutputDirectory (NPath directory) - { - } - - public virtual void AddLinkXmlFile (string file) - { - Options.Descriptors.Add (file); - } - - public virtual void AddResponseFile (NPath path) - { - } - - public virtual void AddTrimMode (string value) - { - } - - public virtual void AddDefaultAction (string value) - { - } - - public virtual void AddLinkAssembly (string fileName) - { - Options.TrimAssemblies.Add (Path.GetFileNameWithoutExtension(fileName)); - } - - public virtual void LinkFromAssembly (string fileName) - { - AppendExpandedPaths (Options.InputFilePaths, fileName); - } - - public virtual void LinkFromPublicAndFamily (string fileName) - { - } - - public virtual void IgnoreDescriptors (bool value) - { - } - - public virtual void IgnoreSubstitutions (bool value) - { - } - - public virtual void IgnoreLinkAttributes (bool value) - { - } - - public virtual void AddIl8n (string value) - { - } - - public virtual void AddKeepTypeForwarderOnlyAssemblies (string value) - { - } - - public virtual void AddLinkSymbols (string value) - { - } - - public virtual void AddAssemblyAction (string action, string assembly) - { - switch (action) { - case "copy": - Options.AdditionalRootAssemblies.Add (assembly); - break; - } - } - - public virtual void AddSkipUnresolved (bool skipUnresolved) - { - } - - public virtual void AddStripDescriptors (bool stripDescriptors) - { - } - - public virtual void AddStripSubstitutions (bool stripSubstitutions) - { - } - - public virtual void AddStripLinkAttributes (bool stripLinkAttributes) - { - } - - public virtual void AddSubstitutions (string file) - { - Options.SubstitutionFiles.Add (file); - } - - public virtual void AddLinkAttributes (string file) - { - } - - public virtual void AddAdditionalArgument (string flag, string[] values) - { - if (flag == "--feature") { - Options.FeatureSwitches.Add (values[0], bool.Parse (values[1])); - } - else if (flag == "--singlewarn") { - Options.SingleWarn = true; - } - else if (flag.StartsWith("--warnaserror")) - { - if (flag == "--warnaserror" || flag == "--warnaserror+") - { - if (values.Length == 0) - Options.TreatWarningsAsErrors = true; - else - { - foreach (int warning in ProcessWarningCodes(values)) - Options.WarningsAsErrors[warning] = true; - } - - } - else if (flag == "--warnaserror-") - { - if (values.Length == 0) - Options.TreatWarningsAsErrors = false; - else - { - foreach (int warning in ProcessWarningCodes(values)) - Options.WarningsAsErrors[warning] = false; - } - } - } - else if (flag == "--notrimwarn") { - Options.SuppressedWarningCategories.Add(MessageSubCategory.TrimAnalysis); - } - else if (flag == "--noaotwarn") { - Options.SuppressedWarningCategories.Add(MessageSubCategory.AotAnalysis); - } - } - - public virtual void ProcessTestInputAssembly (NPath inputAssemblyPath) - { - if (_metadataProvider.LinkPublicAndFamily ()) - LinkFromPublicAndFamily (inputAssemblyPath.ToString ()); - else - LinkFromAssembly (inputAssemblyPath.ToString ()); - } - - public virtual void ProcessOptions (TestCaseLinkerOptions options) - { - if (options.TrimMode != null) - AddTrimMode (options.TrimMode); - - if (options.DefaultAssembliesAction != null) - AddDefaultAction (options.DefaultAssembliesAction); - - if (options.AssembliesAction != null) { - foreach (var (action, assembly) in options.AssembliesAction) - AddAssemblyAction (action, assembly); - } - - // Honoring descriptors causes a ton of stuff to be preserved. That's good for normal use cases, but for - // our test cases that pollutes the results - IgnoreDescriptors (options.IgnoreDescriptors); - - IgnoreSubstitutions (options.IgnoreSubstitutions); - - IgnoreLinkAttributes (options.IgnoreLinkAttributes); + public class TrimmingArgumentBuilder + { + private readonly TestCaseMetadataProvider _metadataProvider; + + private ILCompilerOptions? _options; + private ILCompilerOptions Options => _options ?? throw new InvalidOperationException("Invalid state: Build() was already called"); + + public TrimmingArgumentBuilder(TestCaseMetadataProvider metadataProvider) + { + _options = new ILCompilerOptions(); + _metadataProvider = metadataProvider; + + string runtimeBinDir = (string)AppContext.GetData("Mono.Linker.Tests.RuntimeBinDirectory")!; + AppendExpandedPaths(Options.ReferenceFilePaths, Path.Combine(runtimeBinDir, "aotsdk", "*.dll")); + + string runtimePackDir = (string)AppContext.GetData("Mono.Linker.Tests.MicrosoftNetCoreAppRuntimePackDirectory")!; + if (!Directory.Exists(runtimePackDir) && runtimePackDir.Contains("Debug")) + { + // Frequently we'll have a Debug runtime and Release libraries, which actually produces a Release runtime pack + // but from within VS we're see Debug everything. So if the runtime pack directory doesn't exist + // try the Release path (simple string replace) + string candidate = runtimePackDir.Replace("Debug", "Release"); + if (Directory.Exists(candidate)) + runtimePackDir = candidate; + } + AppendExpandedPaths(Options.ReferenceFilePaths, Path.Combine(runtimePackDir, "*.dll")); + + Options.InitAssemblies.Add("System.Private.CoreLib"); + Options.InitAssemblies.Add("System.Private.StackTraceMetadata"); + Options.InitAssemblies.Add("System.Private.TypeLoader"); + Options.InitAssemblies.Add("System.Private.Reflection.Execution"); + + Options.FeatureSwitches.Add("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", false); + Options.FeatureSwitches.Add("System.Resources.ResourceManager.AllowCustomResourceTypes", false); + Options.FeatureSwitches.Add("System.Linq.Expressions.CanEmitObjectArrayDelegate", false); + Options.FeatureSwitches.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", false); + Options.FeatureSwitches.Add("System.Diagnostics.Debugger.IsSupported", false); + Options.FeatureSwitches.Add("System.Text.Encoding.EnableUnsafeUTF7Encoding", false); + Options.FeatureSwitches.Add("System.Diagnostics.Tracing.EventSource.IsSupported", false); + Options.FeatureSwitches.Add("System.Globalization.Invariant", true); + Options.FeatureSwitches.Add("System.Resources.UseSystemResourceKeys", true); + + Options.FrameworkCompilation = false; + } + + public virtual void AddSearchDirectory(NPath directory) + { + } + + public virtual void AddReference(NPath path) + { + AppendExpandedPaths(Options.ReferenceFilePaths, path.ToString()); + } + + public virtual void AddOutputDirectory(NPath directory) + { + } + + public virtual void AddLinkXmlFile(string file) + { + Options.Descriptors.Add(file); + } + + public virtual void AddResponseFile(NPath path) + { + } + + public virtual void AddTrimMode(string value) + { + } + + public virtual void AddDefaultAction(string value) + { + } + + public virtual void AddLinkAssembly(string fileName) + { + Options.TrimAssemblies.Add(Path.GetFileNameWithoutExtension(fileName)); + } + + public virtual void LinkFromAssembly(string fileName) + { + AppendExpandedPaths(Options.InputFilePaths, fileName); + } + + public virtual void LinkFromPublicAndFamily(string fileName) + { + } + + public virtual void IgnoreDescriptors(bool value) + { + } + + public virtual void IgnoreSubstitutions(bool value) + { + } + + public virtual void IgnoreLinkAttributes(bool value) + { + } + + public virtual void AddIl8n(string value) + { + } + + public virtual void AddKeepTypeForwarderOnlyAssemblies(string value) + { + } + + public virtual void AddLinkSymbols(string value) + { + } + + public virtual void AddAssemblyAction(string action, string assembly) + { + switch (action) + { + case "copy": + Options.AdditionalRootAssemblies.Add(assembly); + break; + } + } + + public virtual void AddSkipUnresolved(bool skipUnresolved) + { + } + + public virtual void AddStripDescriptors(bool stripDescriptors) + { + } + + public virtual void AddStripSubstitutions(bool stripSubstitutions) + { + } + + public virtual void AddStripLinkAttributes(bool stripLinkAttributes) + { + } + + public virtual void AddSubstitutions(string file) + { + Options.SubstitutionFiles.Add(file); + } + + public virtual void AddLinkAttributes(string file) + { + } + + public virtual void AddAdditionalArgument(string flag, string[] values) + { + if (flag == "--feature") + { + Options.FeatureSwitches.Add(values[0], bool.Parse(values[1])); + } + else if (flag == "--singlewarn") + { + Options.SingleWarn = true; + } + else if (flag.StartsWith("--warnaserror")) + { + if (flag == "--warnaserror" || flag == "--warnaserror+") + { + if (values.Length == 0) + Options.TreatWarningsAsErrors = true; + else + { + foreach (int warning in ProcessWarningCodes(values)) + Options.WarningsAsErrors[warning] = true; + } + + } + else if (flag == "--warnaserror-") + { + if (values.Length == 0) + Options.TreatWarningsAsErrors = false; + else + { + foreach (int warning in ProcessWarningCodes(values)) + Options.WarningsAsErrors[warning] = false; + } + } + } + else if (flag == "--notrimwarn") + { + Options.SuppressedWarningCategories.Add(MessageSubCategory.TrimAnalysis); + } + else if (flag == "--noaotwarn") + { + Options.SuppressedWarningCategories.Add(MessageSubCategory.AotAnalysis); + } + else if (flag == "--disable-generated-code-heuristics") + { + Options.DisableGeneratedCodeHeuristics = true; + } + } + + public virtual void ProcessTestInputAssembly(NPath inputAssemblyPath) + { + if (_metadataProvider.LinkPublicAndFamily()) + LinkFromPublicAndFamily(inputAssemblyPath.ToString()); + else + LinkFromAssembly(inputAssemblyPath.ToString()); + } + + public virtual void ProcessOptions(TestCaseLinkerOptions options) + { + if (options.TrimMode != null) + AddTrimMode(options.TrimMode); + + if (options.DefaultAssembliesAction != null) + AddDefaultAction(options.DefaultAssembliesAction); + + if (options.AssembliesAction != null) + { + foreach (var (action, assembly) in options.AssembliesAction) + AddAssemblyAction(action, assembly); + } + + // Honoring descriptors causes a ton of stuff to be preserved. That's good for normal use cases, but for + // our test cases that pollutes the results + IgnoreDescriptors(options.IgnoreDescriptors); + + IgnoreSubstitutions(options.IgnoreSubstitutions); + + IgnoreLinkAttributes(options.IgnoreLinkAttributes); #if !NET - if (!string.IsNullOrEmpty (options.Il8n)) - AddIl8n (options.Il8n); + if (!string.IsNullOrEmpty(options.Il8n)) + AddIl8n(options.Il8n); #endif - if (!string.IsNullOrEmpty (options.KeepTypeForwarderOnlyAssemblies)) - AddKeepTypeForwarderOnlyAssemblies (options.KeepTypeForwarderOnlyAssemblies); + if (!string.IsNullOrEmpty(options.KeepTypeForwarderOnlyAssemblies)) + AddKeepTypeForwarderOnlyAssemblies(options.KeepTypeForwarderOnlyAssemblies); - if (!string.IsNullOrEmpty (options.LinkSymbols)) - AddLinkSymbols (options.LinkSymbols); + if (!string.IsNullOrEmpty(options.LinkSymbols)) + AddLinkSymbols(options.LinkSymbols); - AddSkipUnresolved (options.SkipUnresolved); + AddSkipUnresolved(options.SkipUnresolved); - AddStripDescriptors (options.StripDescriptors); + AddStripDescriptors(options.StripDescriptors); - AddStripSubstitutions (options.StripSubstitutions); + AddStripSubstitutions(options.StripSubstitutions); - AddStripLinkAttributes (options.StripLinkAttributes); + AddStripLinkAttributes(options.StripLinkAttributes); - foreach (var descriptor in options.Descriptors) - AddLinkXmlFile (descriptor); + foreach (var descriptor in options.Descriptors) + AddLinkXmlFile(descriptor); - foreach (var substitutions in options.Substitutions) - AddSubstitutions (substitutions); + foreach (var substitutions in options.Substitutions) + AddSubstitutions(substitutions); - foreach (var attributeDefinition in options.LinkAttributes) - AddLinkAttributes (attributeDefinition); + foreach (var attributeDefinition in options.LinkAttributes) + AddLinkAttributes(attributeDefinition); - // A list of expensive optimizations which should not run by default - AddAdditionalArgument ("--disable-opt", new[] { "ipconstprop" }); + // A list of expensive optimizations which should not run by default + AddAdditionalArgument("--disable-opt", new[] { "ipconstprop" }); - // Unity uses different argument format and needs to be able to translate to their format. In order to make that easier - // we keep the information in flag + values format for as long as we can so that this information doesn't have to be parsed out of a single string - foreach (var additionalArgument in options.AdditionalArguments) - AddAdditionalArgument (additionalArgument.Key, additionalArgument.Value); + // Unity uses different argument format and needs to be able to translate to their format. In order to make that easier + // we keep the information in flag + values format for as long as we can so that this information doesn't have to be parsed out of a single string + foreach (var additionalArgument in options.AdditionalArguments) + AddAdditionalArgument(additionalArgument.Key, additionalArgument.Value); - if (options.IlcFrameworkCompilation) - Options.FrameworkCompilation = true; - } + if (options.IlcFrameworkCompilation) + Options.FrameworkCompilation = true; + } - private static void AppendExpandedPaths (Dictionary dictionary, string pattern) - { - bool empty = true; + private static void AppendExpandedPaths(Dictionary dictionary, string pattern) + { + bool empty = true; - string directoryName = Path.GetDirectoryName (pattern)!; - string searchPattern = Path.GetFileName (pattern); + string directoryName = Path.GetDirectoryName(pattern)!; + string searchPattern = Path.GetFileName(pattern); - if (directoryName == "") - directoryName = "."; + if (directoryName == "") + directoryName = "."; - if (Directory.Exists (directoryName)) { - foreach (string fileName in Directory.EnumerateFiles (directoryName, searchPattern)) { - string fullFileName = Path.GetFullPath (fileName); + if (Directory.Exists(directoryName)) + { + foreach (string fileName in Directory.EnumerateFiles(directoryName, searchPattern)) + { + string fullFileName = Path.GetFullPath(fileName); - string simpleName = Path.GetFileNameWithoutExtension (fileName); + string simpleName = Path.GetFileNameWithoutExtension(fileName); - if (!dictionary.ContainsKey (simpleName)) { - dictionary.Add (simpleName, fullFileName); - } + if (!dictionary.ContainsKey(simpleName)) + { + dictionary.Add(simpleName, fullFileName); + } - empty = false; - } - } + empty = false; + } + } - if (empty) { - throw new Exception ("No files matching " + pattern); - } - } + if (empty) + { + throw new Exception("No files matching " + pattern); + } + } - private static readonly char[] s_separator = new char[] { ',', ';', ' ' }; + private static readonly char[] s_separator = new char[] { ',', ';', ' ' }; - private static IEnumerable ProcessWarningCodes(IEnumerable warningCodes) - { - foreach (string value in warningCodes) - { - string[] values = value.Split(s_separator, StringSplitOptions.RemoveEmptyEntries); - foreach (string id in values) - { - if (!id.StartsWith("IL", StringComparison.Ordinal) || !ushort.TryParse(id.AsSpan(2), out ushort code)) - continue; + private static IEnumerable ProcessWarningCodes(IEnumerable warningCodes) + { + foreach (string value in warningCodes) + { + string[] values = value.Split(s_separator, StringSplitOptions.RemoveEmptyEntries); + foreach (string id in values) + { + if (!id.StartsWith("IL", StringComparison.Ordinal) || !ushort.TryParse(id.AsSpan(2), out ushort code)) + continue; - yield return code; - } - } - } + yield return code; + } + } + } - public ILCompilerOptions Build () - { - var options = Options; - _options = null; - return options; - } - } + public ILCompilerOptions Build() + { + var options = Options; + _options = null; + return options; + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingCustomizations.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingCustomizations.cs index f6ef0009a701f2..edb5b1030bbc7b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingCustomizations.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingCustomizations.cs @@ -5,7 +5,7 @@ namespace Mono.Linker.Tests.TestCasesRunner { - public class TrimmingCustomizations - { - } + public class TrimmingCustomizations + { + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingDriver.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingDriver.cs index a97f9638c5f8f0..97e3256eef782a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingDriver.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingDriver.cs @@ -18,194 +18,203 @@ namespace Mono.Linker.Tests.TestCasesRunner { - public class TrimmingDriver - { - internal const string DefaultSystemModule = "System.Private.CoreLib"; - - public ILScanResults Trim (ILCompilerOptions options, TrimmingCustomizations? customizations, ILogWriter logWriter) - { - ComputeDefaultOptions (out var targetOS, out var targetArchitecture); - var targetDetails = new TargetDetails (targetArchitecture, targetOS, TargetAbi.NativeAot); - CompilerTypeSystemContext typeSystemContext = - new CompilerTypeSystemContext (targetDetails, SharedGenericsMode.CanonicalReferenceTypes, DelegateFeature.All, genericCycleDepthCutoff: -1); - - typeSystemContext.InputFilePaths = options.InputFilePaths; - typeSystemContext.ReferenceFilePaths = options.ReferenceFilePaths; - typeSystemContext.SetSystemModule (typeSystemContext.GetModuleForSimpleName (DefaultSystemModule)); - - List inputModules = new List (); - foreach (var inputFile in typeSystemContext.InputFilePaths) { - EcmaModule module = typeSystemContext.GetModuleFromPath (inputFile.Value); - inputModules.Add (module); - } - - foreach (var trimAssembly in options.TrimAssemblies) { - EcmaModule module = typeSystemContext.GetModuleForSimpleName (trimAssembly); - inputModules.Add (module); - } - - CompilationModuleGroup compilationGroup; - if (options.FrameworkCompilation) - compilationGroup = new SingleFileCompilationModuleGroup (); - else - compilationGroup = new TestInfraMultiFileSharedCompilationModuleGroup (typeSystemContext, inputModules); - - List compilationRoots = new List (); - EcmaModule? entrypointModule = null; - foreach (var inputFile in typeSystemContext.InputFilePaths) { - EcmaModule module = typeSystemContext.GetModuleFromPath (inputFile.Value); - - if (module.PEReader.PEHeaders.IsExe) { - if (entrypointModule != null) - throw new Exception ("Multiple EXE modules"); - entrypointModule = module; - } - - compilationRoots.Add (new UnmanagedEntryPointsRootProvider (module)); - } - - compilationRoots.Add (new MainMethodRootProvider (entrypointModule, CreateInitializerList (typeSystemContext, options), generateLibraryAndModuleInitializers: true)); - - foreach (var rootedAssembly in options.AdditionalRootAssemblies) { - EcmaModule module = typeSystemContext.GetModuleForSimpleName (rootedAssembly); - - // We only root the module type. The rest will fall out because we treat rootedAssemblies - // same as conditionally rooted ones and here we're fulfilling the condition ("something is used"). - compilationRoots.Add ( - new GenericRootProvider (module, - (ModuleDesc module, IRootingServiceProvider rooter) => rooter.AddReflectionRoot (module.GetGlobalModuleType (), "Command line root"))); - } - - ILProvider ilProvider = new NativeAotILProvider (); - - Logger logger = new Logger ( - logWriter, - ilProvider, - isVerbose: true, - suppressedWarnings: Enumerable.Empty (), - options.SingleWarn, - singleWarnEnabledModules: Enumerable.Empty (), - singleWarnDisabledModules: Enumerable.Empty (), - suppressedCategories: options.SuppressedWarningCategories, - treatWarningsAsErrors: options.TreatWarningsAsErrors, - warningsAsErrors: options.WarningsAsErrors); - - foreach (var descriptor in options.Descriptors) { - if (!File.Exists (descriptor)) - throw new FileNotFoundException ($"'{descriptor}' doesn't exist"); - compilationRoots.Add (new ILCompiler.DependencyAnalysis.TrimmingDescriptorNode (descriptor)); - } - - var featureSwitches = options.FeatureSwitches; - BodyAndFieldSubstitutions substitutions = default; - IReadOnlyDictionary>? resourceBlocks = default; - foreach (string substitutionFilePath in options.SubstitutionFiles) - { - using FileStream fs = File.OpenRead(substitutionFilePath); - substitutions.AppendFrom(BodySubstitutionsParser.GetSubstitutions( - logger, typeSystemContext, XmlReader.Create(fs), substitutionFilePath, featureSwitches)); - - fs.Seek(0, SeekOrigin.Begin); - - resourceBlocks = ManifestResourceBlockingPolicy.UnionBlockings(resourceBlocks, - ManifestResourceBlockingPolicy.SubstitutionsReader.GetSubstitutions( - logger, typeSystemContext, XmlReader.Create(fs), substitutionFilePath, featureSwitches)); - } - - SubstitutionProvider substitutionProvider = new SubstitutionProvider(logger, featureSwitches, substitutions); - ilProvider = new SubstitutedILProvider(ilProvider, substitutionProvider, new DevirtualizationManager()); - - CompilerGeneratedState compilerGeneratedState = new CompilerGeneratedState (ilProvider, logger); - - UsageBasedMetadataManager metadataManager = new UsageBasedMetadataManager( - compilationGroup, - typeSystemContext, - new NoMetadataBlockingPolicy(), - new ManifestResourceBlockingPolicy(logger, options.FeatureSwitches, new Dictionary>()), - logFile: null, - stackTracePolicy: new NoStackTraceEmissionPolicy(), - invokeThunkGenerationPolicy: new DefaultDynamicInvokeThunkGenerationPolicy(), - flowAnnotations: new FlowAnnotations(logger, ilProvider, compilerGeneratedState), - generationOptions: UsageBasedMetadataGenerationOptions.ReflectionILScanning, - options: default, - logger: logger, - featureSwitchValues: options.FeatureSwitches, - rootEntireAssembliesModules: Array.Empty(), - additionalRootedAssemblies: options.AdditionalRootAssemblies.ToArray(), - trimmedAssemblies: options.TrimAssemblies.ToArray(), - satelliteAssemblyFilePaths: Array.Empty()); - - PInvokeILEmitterConfiguration pinvokePolicy = new ILCompilerTestPInvokePolicy (); - InteropStateManager interopStateManager = new InteropStateManager (typeSystemContext.GeneratedAssembly); - InteropStubManager interopStubManager = new UsageBasedInteropStubManager (interopStateManager, pinvokePolicy, logger); - - TypeMapManager typeMapManager = new UsageBasedTypeMapManager (TypeMapMetadata.Empty); - if (entrypointModule is { Assembly: EcmaAssembly entryAssembly }) - { - typeMapManager = new UsageBasedTypeMapManager (TypeMapMetadata.CreateFromAssembly(entryAssembly, typeSystemContext)); - } - - CompilationBuilder builder = new RyuJitCompilationBuilder (typeSystemContext, compilationGroup) - .UseILProvider (ilProvider) - .UseCompilationUnitPrefix(""); - - IILScanner scanner = builder.GetILScannerBuilder () - .UseCompilationRoots (compilationRoots) - .UseMetadataManager (metadataManager) - .UseParallelism (System.Diagnostics.Debugger.IsAttached ? 1 : -1) - .UseInteropStubManager (interopStubManager) - .UseTypeMapManager (typeMapManager) - .ToILScanner (); - - return scanner.Scan (); - } - - public static void ComputeDefaultOptions (out TargetOS os, out TargetArchitecture arch) - { - if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) - os = TargetOS.Windows; - else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) - os = TargetOS.Linux; - else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) - os = TargetOS.OSX; - else if (RuntimeInformation.IsOSPlatform (OSPlatform.FreeBSD)) - os = TargetOS.FreeBSD; - else - throw new NotImplementedException (); - - switch (RuntimeInformation.ProcessArchitecture) { - case Architecture.X86: - arch = TargetArchitecture.X86; - break; - case Architecture.X64: - arch = TargetArchitecture.X64; - break; - case Architecture.Arm: - arch = TargetArchitecture.ARM; - break; - case Architecture.Arm64: - arch = TargetArchitecture.ARM64; - break; - default: - throw new NotImplementedException (); - } - } - - private static IReadOnlyCollection CreateInitializerList (CompilerTypeSystemContext context, ILCompilerOptions options) - { - List assembliesWithInitalizers = new List (); - - // Build a list of assemblies that have an initializer that needs to run before - // any user code runs. - foreach (string initAssemblyName in options.InitAssemblies) { - ModuleDesc assembly = context.ResolveAssembly (new AssemblyNameInfo (initAssemblyName), throwIfNotFound: true); - assembliesWithInitalizers.Add (assembly); - } - - var libraryInitializers = new LibraryInitializers (context, assembliesWithInitalizers); - - List initializerList = new List (libraryInitializers.LibraryInitializerMethods); - return initializerList; - } - } + public class TrimmingDriver + { + internal const string DefaultSystemModule = "System.Private.CoreLib"; + + public ILScanResults Trim(ILCompilerOptions options, TrimmingCustomizations? customizations, ILogWriter logWriter) + { + ComputeDefaultOptions(out var targetOS, out var targetArchitecture); + var targetDetails = new TargetDetails(targetArchitecture, targetOS, TargetAbi.NativeAot); + CompilerTypeSystemContext typeSystemContext = + new CompilerTypeSystemContext(targetDetails, SharedGenericsMode.CanonicalReferenceTypes, DelegateFeature.All, genericCycleDepthCutoff: -1); + + typeSystemContext.InputFilePaths = options.InputFilePaths; + typeSystemContext.ReferenceFilePaths = options.ReferenceFilePaths; + typeSystemContext.SetSystemModule(typeSystemContext.GetModuleForSimpleName(DefaultSystemModule)); + + List inputModules = new List(); + foreach (var inputFile in typeSystemContext.InputFilePaths) + { + EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value); + inputModules.Add(module); + } + + foreach (var trimAssembly in options.TrimAssemblies) + { + EcmaModule module = typeSystemContext.GetModuleForSimpleName(trimAssembly); + inputModules.Add(module); + } + + CompilationModuleGroup compilationGroup; + if (options.FrameworkCompilation) + compilationGroup = new SingleFileCompilationModuleGroup(); + else + compilationGroup = new TestInfraMultiFileSharedCompilationModuleGroup(typeSystemContext, inputModules); + + List compilationRoots = new List(); + EcmaModule? entrypointModule = null; + foreach (var inputFile in typeSystemContext.InputFilePaths) + { + EcmaModule module = typeSystemContext.GetModuleFromPath(inputFile.Value); + + if (module.PEReader.PEHeaders.IsExe) + { + if (entrypointModule != null) + throw new Exception("Multiple EXE modules"); + entrypointModule = module; + } + + compilationRoots.Add(new UnmanagedEntryPointsRootProvider(module)); + } + + compilationRoots.Add(new MainMethodRootProvider(entrypointModule, CreateInitializerList(typeSystemContext, options), generateLibraryAndModuleInitializers: true)); + + foreach (var rootedAssembly in options.AdditionalRootAssemblies) + { + EcmaModule module = typeSystemContext.GetModuleForSimpleName(rootedAssembly); + + // We only root the module type. The rest will fall out because we treat rootedAssemblies + // same as conditionally rooted ones and here we're fulfilling the condition ("something is used"). + compilationRoots.Add( + new GenericRootProvider(module, + (ModuleDesc module, IRootingServiceProvider rooter) => rooter.AddReflectionRoot(module.GetGlobalModuleType(), "Command line root"))); + } + + ILProvider ilProvider = new NativeAotILProvider(); + + Logger logger = new Logger( + logWriter, + ilProvider, + isVerbose: true, + suppressedWarnings: Enumerable.Empty(), + options.SingleWarn, + singleWarnEnabledModules: Enumerable.Empty(), + singleWarnDisabledModules: Enumerable.Empty(), + suppressedCategories: options.SuppressedWarningCategories, + treatWarningsAsErrors: options.TreatWarningsAsErrors, + warningsAsErrors: options.WarningsAsErrors, + disableGeneratedCodeHeuristics: options.DisableGeneratedCodeHeuristics); + + foreach (var descriptor in options.Descriptors) + { + if (!File.Exists(descriptor)) + throw new FileNotFoundException($"'{descriptor}' doesn't exist"); + compilationRoots.Add(new ILCompiler.DependencyAnalysis.TrimmingDescriptorNode(descriptor)); + } + + var featureSwitches = options.FeatureSwitches; + BodyAndFieldSubstitutions substitutions = default; + IReadOnlyDictionary>? resourceBlocks = default; + foreach (string substitutionFilePath in options.SubstitutionFiles) + { + using FileStream fs = File.OpenRead(substitutionFilePath); + substitutions.AppendFrom(BodySubstitutionsParser.GetSubstitutions( + logger, typeSystemContext, XmlReader.Create(fs), substitutionFilePath, featureSwitches)); + + fs.Seek(0, SeekOrigin.Begin); + + resourceBlocks = ManifestResourceBlockingPolicy.UnionBlockings(resourceBlocks, + ManifestResourceBlockingPolicy.SubstitutionsReader.GetSubstitutions( + logger, typeSystemContext, XmlReader.Create(fs), substitutionFilePath, featureSwitches)); + } + + SubstitutionProvider substitutionProvider = new SubstitutionProvider(logger, featureSwitches, substitutions); + ilProvider = new SubstitutedILProvider(ilProvider, substitutionProvider, new DevirtualizationManager()); + + CompilerGeneratedState compilerGeneratedState = new CompilerGeneratedState(ilProvider, logger, options.DisableGeneratedCodeHeuristics); + + UsageBasedMetadataManager metadataManager = new UsageBasedMetadataManager( + compilationGroup, + typeSystemContext, + new NoMetadataBlockingPolicy(), + new ManifestResourceBlockingPolicy(logger, options.FeatureSwitches, new Dictionary>()), + logFile: null, + stackTracePolicy: new NoStackTraceEmissionPolicy(), + invokeThunkGenerationPolicy: new DefaultDynamicInvokeThunkGenerationPolicy(), + flowAnnotations: new FlowAnnotations(logger, ilProvider, compilerGeneratedState), + generationOptions: UsageBasedMetadataGenerationOptions.ReflectionILScanning, + options: default, + logger: logger, + featureSwitchValues: options.FeatureSwitches, + rootEntireAssembliesModules: Array.Empty(), + additionalRootedAssemblies: options.AdditionalRootAssemblies.ToArray(), + trimmedAssemblies: options.TrimAssemblies.ToArray(), + satelliteAssemblyFilePaths: Array.Empty()); + + PInvokeILEmitterConfiguration pinvokePolicy = new ILCompilerTestPInvokePolicy(); + InteropStateManager interopStateManager = new InteropStateManager(typeSystemContext.GeneratedAssembly); + InteropStubManager interopStubManager = new UsageBasedInteropStubManager(interopStateManager, pinvokePolicy, logger); + + TypeMapManager typeMapManager = new UsageBasedTypeMapManager(TypeMapMetadata.Empty); + if (entrypointModule is { Assembly: EcmaAssembly entryAssembly }) + { + typeMapManager = new UsageBasedTypeMapManager(TypeMapMetadata.CreateFromAssembly(entryAssembly, typeSystemContext)); + } + + CompilationBuilder builder = new RyuJitCompilationBuilder(typeSystemContext, compilationGroup) + .UseILProvider(ilProvider) + .UseCompilationUnitPrefix(""); + + IILScanner scanner = builder.GetILScannerBuilder() + .UseCompilationRoots(compilationRoots) + .UseMetadataManager(metadataManager) + .UseParallelism(System.Diagnostics.Debugger.IsAttached ? 1 : -1) + .UseInteropStubManager(interopStubManager) + .UseTypeMapManager(typeMapManager) + .ToILScanner(); + + return scanner.Scan(); + } + + public static void ComputeDefaultOptions(out TargetOS os, out TargetArchitecture arch) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + os = TargetOS.Windows; + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + os = TargetOS.Linux; + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + os = TargetOS.OSX; + else if (RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD)) + os = TargetOS.FreeBSD; + else + throw new NotImplementedException(); + + switch (RuntimeInformation.ProcessArchitecture) + { + case Architecture.X86: + arch = TargetArchitecture.X86; + break; + case Architecture.X64: + arch = TargetArchitecture.X64; + break; + case Architecture.Arm: + arch = TargetArchitecture.ARM; + break; + case Architecture.Arm64: + arch = TargetArchitecture.ARM64; + break; + default: + throw new NotImplementedException(); + } + } + + private static IReadOnlyCollection CreateInitializerList(CompilerTypeSystemContext context, ILCompilerOptions options) + { + List assembliesWithInitalizers = new List(); + + // Build a list of assemblies that have an initializer that needs to run before + // any user code runs. + foreach (string initAssemblyName in options.InitAssemblies) + { + ModuleDesc assembly = context.ResolveAssembly(new AssemblyNameInfo(initAssemblyName), throwIfNotFound: true); + assembliesWithInitalizers.Add(assembly); + } + + var libraryInitializers = new LibraryInitializers(context, assembliesWithInitalizers); + + List initializerList = new List(libraryInitializers.LibraryInitializerMethods); + return initializerList; + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingTestLogger.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingTestLogger.cs index 9e1bec7a057093..3bc19c3eef01a2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingTestLogger.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingTestLogger.cs @@ -8,46 +8,49 @@ namespace Mono.Linker.Tests.TestCasesRunner { - public class TrimmingTestLogger : ILogWriter - { - private readonly StringWriter _infoStringWriter; - private readonly TextWriter _infoWriter; - - private readonly List _messageContainers; - - public TrimmingTestLogger () - { - _infoStringWriter = new StringWriter (); - _infoWriter = TextWriter.Synchronized (_infoStringWriter); - _messageContainers = new List (); - } - - public TextWriter Writer => _infoWriter; - - public List GetLoggedMessages () - { - return _messageContainers; - } - - public void WriteError (MessageContainer error) - { - lock (_messageContainers) { - _messageContainers.Add (error); - } - } - - public void WriteMessage (MessageContainer message) - { - lock (_messageContainers) { - _messageContainers.Add (message); - } - } - - public void WriteWarning (MessageContainer warning) - { - lock (_messageContainers) { - _messageContainers.Add (warning); - } - } - } + public class TrimmingTestLogger : ILogWriter + { + private readonly StringWriter _infoStringWriter; + private readonly TextWriter _infoWriter; + + private readonly List _messageContainers; + + public TrimmingTestLogger() + { + _infoStringWriter = new StringWriter(); + _infoWriter = TextWriter.Synchronized(_infoStringWriter); + _messageContainers = new List(); + } + + public TextWriter Writer => _infoWriter; + + public List GetLoggedMessages() + { + return _messageContainers; + } + + public void WriteError(MessageContainer error) + { + lock (_messageContainers) + { + _messageContainers.Add(error); + } + } + + public void WriteMessage(MessageContainer message) + { + lock (_messageContainers) + { + _messageContainers.Add(message); + } + } + + public void WriteWarning(MessageContainer warning) + { + lock (_messageContainers) + { + _messageContainers.Add(warning); + } + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/Tests/DocumentationSignatureParserTests.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/Tests/DocumentationSignatureParserTests.cs index c8df47cc328556..14adc5da7a68e6 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/Tests/DocumentationSignatureParserTests.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/Tests/DocumentationSignatureParserTests.cs @@ -16,545 +16,553 @@ namespace Mono.Linker.Tests { - public class DocumentationSignatureParserTests - { - [Theory] - [ClassData (typeof (MemberAssertions))] - public void TestSignatureParsing (TypeSystemEntity member, MemberAssertionsCollector.CustomAttribute customAttribute) - { - var attributeString = (string) customAttribute.Value.FixedArguments[0].Value!; - switch (customAttribute.AttributeType.Name) { - case nameof (ExpectExactlyResolvedDocumentationSignatureAttribute): - CheckUniqueParsedString (member, attributeString); - break; - case nameof (ExpectGeneratedDocumentationSignatureAttribute): - // CheckGeneratedString (member, attributeString); - break; - case nameof (ExpectResolvedDocumentationSignatureAttribute): - CheckParsedString (member, attributeString); - break; - case nameof (ExpectUnresolvedDocumentationSignatureAttribute): - CheckUnresolvedDocumentationSignature (member, attributeString); - break; - default: - throw new NotImplementedException (); - } - } - - public class MemberAssertions : MemberAssertionsCollector - { - public MemberAssertions () : base (typeof (DocumentationSignatureParserTests)) - { } - } - - private static void CheckUniqueParsedString (TypeSystemEntity member, string input) - { - var module = GetModule (member); - Assert.NotNull (module); - var parseResults = DocumentationSignatureParser.GetMembersForDocumentationSignature (input, module); - Assert.Single (parseResults); - TypeSystemEntity result = parseResults.First (); - switch (member) { - case PropertyPseudoDesc p: - var actualProperty = Assert.IsType (result); - Assert.Equal (p.OwningType, actualProperty.OwningType); - Assert.Equal (p.Name, actualProperty.Name); - break; - case EventPseudoDesc e: - var actualEvent = Assert.IsType (result); - Assert.Equal (e.OwningType, actualEvent.OwningType); - Assert.Equal (e.Name, actualEvent.Name); - break; - default: - Assert.Equal (member, parseResults.First ()); - break; - } - } - - // Currently NativeAOT has only a partial implementation of the generator since it doesn't need it for anything - // other than signature parsing (which uses the generator for certain parts). + public class DocumentationSignatureParserTests + { + [Theory] + [ClassData(typeof(MemberAssertions))] + public void TestSignatureParsing(TypeSystemEntity member, MemberAssertionsCollector.CustomAttribute customAttribute) + { + var attributeString = (string)customAttribute.Value.FixedArguments[0].Value!; + switch (customAttribute.AttributeType.Name) + { + case nameof(ExpectExactlyResolvedDocumentationSignatureAttribute): + CheckUniqueParsedString(member, attributeString); + break; + case nameof(ExpectGeneratedDocumentationSignatureAttribute): + // CheckGeneratedString(member, attributeString); + break; + case nameof(ExpectResolvedDocumentationSignatureAttribute): + CheckParsedString(member, attributeString); + break; + case nameof(ExpectUnresolvedDocumentationSignatureAttribute): + CheckUnresolvedDocumentationSignature(member, attributeString); + break; + default: + throw new NotImplementedException(); + } + } + + public class MemberAssertions : MemberAssertionsCollector + { + public MemberAssertions() : base(typeof(DocumentationSignatureParserTests)) + { } + } + + private static void CheckUniqueParsedString(TypeSystemEntity member, string input) + { + var module = GetModule(member); + Assert.NotNull(module); + var parseResults = DocumentationSignatureParser.GetMembersForDocumentationSignature(input, module); + Assert.Single(parseResults); + TypeSystemEntity result = parseResults.First(); + switch (member) + { + case PropertyPseudoDesc p: + var actualProperty = Assert.IsType(result); + Assert.Equal(p.OwningType, actualProperty.OwningType); + Assert.Equal(p.Name, actualProperty.Name); + break; + case EventPseudoDesc e: + var actualEvent = Assert.IsType(result); + Assert.Equal(e.OwningType, actualEvent.OwningType); + Assert.Equal(e.Name, actualEvent.Name); + break; + default: + Assert.Equal(member, parseResults.First()); + break; + } + } + + // Currently NativeAOT has only a partial implementation of the generator since it doesn't need it for anything + // other than signature parsing (which uses the generator for certain parts). #if false - private static void CheckGeneratedString (TypeSystemEntity member, string expected) - { - var builder = new StringBuilder (); - DocumentationSignatureGenerator.PartVisitor.Instance.AppendName (builder, type); - Assert.Equal (expected, builder.ToString ()); - } + private static void CheckGeneratedString(TypeSystemEntity member, string expected) + { + var builder = new StringBuilder(); + DocumentationSignatureGenerator.PartVisitor.Instance.AppendName(builder, type); + Assert.Equal(expected, builder.ToString()); + } #endif - private static void CheckParsedString (TypeSystemEntity member, string input) - { - var module = GetModule (member); - Assert.NotNull (module); - var parseResults = DocumentationSignatureParser.GetMembersForDocumentationSignature (input, module); - Assert.Contains (member, parseResults); - } - - private static void CheckUnresolvedDocumentationSignature (TypeSystemEntity member, string input) - { - var module = GetModule (member); - Assert.NotNull (module); - var parseResults = DocumentationSignatureParser.GetMembersForDocumentationSignature (input, module); - Assert.DoesNotContain (member, parseResults); - } - - private static ModuleDesc? GetModule (TypeSystemEntity entity) - { - return entity switch { - MethodDesc method => (method.OwningType as MetadataType)?.Module, - FieldDesc field => (field.OwningType as MetadataType)?.Module, - MetadataType type => type.Module, - PropertyPseudoDesc property => property.OwningType.Module, - EventPseudoDesc @event => @event.OwningType.Module, - _ => throw new InvalidOperationException (), - }; - } - - // testcases - - [ExpectGeneratedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.A")] - [ExpectExactlyResolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.A")] - public class A - { - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.#ctor")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.#ctor")] - public A () - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.#ctor(System.Int32)")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.#ctor(System.Int32)")] - public A (int a) - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.#cctor")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.#cctor")] - static A () - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[])")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[])")] - public static void M (int[] a) - { - } - - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32,System.Int32,System.Int32)~System.Int32")] - public static int M (int a, int b, int c) - { - return 0; - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MRef(System.Int32@)")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MRef(System.Int32@)")] - public static void MRef (ref int a) - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MOut(System.Int32@)")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MOut(System.Int32@)")] - public static void MOut (out int a) - { - a = 5; - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MIn(System.Int32@)")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MIn(System.Int32@)")] - public static void MIn (in int a) - { - } - - private static int i; - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MRefReturn")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MRefReturn")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MRefReturn~System.Int32@")] - public static ref int MRefReturn () - { - return ref i; - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M")] - [ExpectResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M")] // binds to both. - [ExpectResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M()")] // binds to both. - public static void M () - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M()")] - [ExpectResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M")] - [ExpectResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M()")] - public static void M (__arglist) - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[][])")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[][])")] - public static void M (int[][] a) - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[][0:,0:,0:])")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[][0:,0:,0:])")] - public static void M (int[,,][] a) - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[0:,0:])")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[0:,0:])")] - public static void M (int[,] a) - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Object)")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Object)")] - public static void M (dynamic d) - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32*)")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32*)")] - public static unsafe void M (int* a) - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M``1(Mono.Linker.Tests.DocumentationSignatureParserTests.S{Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A,``0}}**[0:,0:,0:][][][0:,0:]@)")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M``1(Mono.Linker.Tests.DocumentationSignatureParserTests.S{Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A,``0}}**[0:,0:,0:][][][0:,0:]@)")] - public static unsafe void M (ref S>**[,][][][,,] a) - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Collections.Generic.List{System.Int32[]})")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Collections.Generic.List{System.Int32[]})")] - public static void M (List a) - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32,)")] - //[ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32,)")] - // there's no way to reference this, since the parsing logic doesn't like it. - public static void M (int abo, __arglist) - { - } - - [ExpectGeneratedDocumentationSignature ("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Prop")] - [ExpectExactlyResolvedDocumentationSignature ("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Prop")] - public int Prop { get; set; } - - [ExpectGeneratedDocumentationSignature ("F:Mono.Linker.Tests.DocumentationSignatureParserTests.A.field")] - [ExpectExactlyResolvedDocumentationSignature ("F:Mono.Linker.Tests.DocumentationSignatureParserTests.A.field")] - public int field; - - - [ExpectGeneratedDocumentationSignature ("E:Mono.Linker.Tests.DocumentationSignatureParserTests.A.OnEvent")] - [ExpectExactlyResolvedDocumentationSignature ("E:Mono.Linker.Tests.DocumentationSignatureParserTests.A.OnEvent")] - public event EventHandler? OnEvent; - - [ExpectGeneratedDocumentationSignature ("E:Mono.Linker.Tests.DocumentationSignatureParserTests.A.OnEventInt")] - [ExpectExactlyResolvedDocumentationSignature ("E:Mono.Linker.Tests.DocumentationSignatureParserTests.A.OnEventInt")] - public event Action? OnEventInt; - - [ExpectGeneratedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Del")] - [ExpectExactlyResolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Del")] - public delegate int Del (int a, int b); - - [ExpectGeneratedDocumentationSignature ("E:Mono.Linker.Tests.DocumentationSignatureParserTests.A.OnEventDel")] - [ExpectExactlyResolvedDocumentationSignature ("E:Mono.Linker.Tests.DocumentationSignatureParserTests.A.OnEventDel")] - public event Del? OnEventDel; - - // prevent warning about unused events - public void UseEvents () - { - OnEventDel?.Invoke (1, 2); - OnEventInt?.Invoke (1); - OnEvent?.Invoke (null, new EventArgs ()); - } - - [ExpectGeneratedDocumentationSignature ("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Item(System.Int32)")] - [ExpectExactlyResolvedDocumentationSignature ("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Item(System.Int32)")] - public int this[int i] { - get => 0; - set { } - } - - [ExpectGeneratedDocumentationSignature ("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Item(System.String,System.Int32)")] - [ExpectExactlyResolvedDocumentationSignature ("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Item(System.String,System.Int32)")] - public int this[string s, int i] { - get => 0; - set { } - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Implicit(Mono.Linker.Tests.DocumentationSignatureParserTests.A)~System.Boolean")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Implicit(Mono.Linker.Tests.DocumentationSignatureParserTests.A)~System.Boolean")] - public static implicit operator bool (A a) => false; - - // C# will not generate a return type for this method, but we will. - // [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Implicit(Mono.Linker.Tests.DocumentationSignatureParserTests.A)~System.Boolean")] - // [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Implicit(Mono.Linker.Tests.DocumentationSignatureParserTests.A)~System.Boolean")] - //public static int op_Implicit (A a) => 0; - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_UnaryPlus(Mono.Linker.Tests.DocumentationSignatureParserTests.A)")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_UnaryPlus(Mono.Linker.Tests.DocumentationSignatureParserTests.A)")] - public static A? operator + (A a) => null; - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Addition(Mono.Linker.Tests.DocumentationSignatureParserTests.A,Mono.Linker.Tests.DocumentationSignatureParserTests.A)")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Addition(Mono.Linker.Tests.DocumentationSignatureParserTests.A,Mono.Linker.Tests.DocumentationSignatureParserTests.A)")] - public static A? operator + (A left, A right) => null; - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MWithReturnType")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MWithReturnType~System.Boolean")] - public static bool MWithReturnType () => false; - } - - public struct S - { - } - - [ExpectGeneratedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.A`1")] - [ExpectExactlyResolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.A`1")] - public class A - { - [ExpectGeneratedDocumentationSignature ("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A`1.Item(`0)")] - [ExpectExactlyResolvedDocumentationSignature ("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A`1.Item(`0)")] - public int this[T t] { - get => 0; - set { } - } - } - - [ExpectExactlyResolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.B")] - [ExpectGeneratedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.B")] - public class B - { - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.B.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A{Mono.Linker.Tests.DocumentationSignatureParserTests.B},System.Collections.Generic.List{Mono.Linker.Tests.DocumentationSignatureParserTests.A}})")] - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.B.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A{Mono.Linker.Tests.DocumentationSignatureParserTests.B},System.Collections.Generic.List{Mono.Linker.Tests.DocumentationSignatureParserTests.A}})")] - public static void Method (G, List> l) - { - } - } - - [ExpectGeneratedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2")] - [ExpectExactlyResolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2")] - public class G - { - [ExpectGeneratedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1")] - [ExpectExactlyResolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1")] - public class NG - { - [ExpectGeneratedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1.NG2`1")] - [ExpectExactlyResolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1.NG2`1")] - public class NG2 - { - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1.NG2`1.Method``1(`0,`1,`2,`3,``0)")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1.NG2`1.Method``1(`0,`1,`2,`3,``0)")] - public void Method (T t, U u, V v, W w, X x) - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1.NG2`1.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{`0,`1}.NG{`2}.NG2{`3})")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1.NG2`1.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{`0,`1}.NG{`2}.NG2{`3})")] - public void Method (NG2 n) - { - } - } - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{`0,`1})")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{`0,`1})")] - public void Method (G g) - { - } - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method")] - public static void Method () - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method(System.Int32)")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method(System.Int32)")] - public static void Method (int i) - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.IntMethod")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.IntMethod")] - public static int IntMethod () => 0; - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A,Mono.Linker.Tests.DocumentationSignatureParserTests.A})")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A,Mono.Linker.Tests.DocumentationSignatureParserTests.A})")] - public static void Method (G g) - { - } - - [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A,Mono.Linker.Tests.DocumentationSignatureParserTests.A}.NG{Mono.Linker.Tests.DocumentationSignatureParserTests.A})")] - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A,Mono.Linker.Tests.DocumentationSignatureParserTests.A}.NG{Mono.Linker.Tests.DocumentationSignatureParserTests.A})")] - public static void Method (G.NG g) - { - } - - public class Invalid - { - [ExpectUnresolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoReturnType~")] - public static int NoReturnType () => 0; - - [ExpectUnresolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoParameters(,)")] - public static void NoParameters (int a, int b) - { - } - - [ExpectUnresolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoClosingParen(")] - public static void NoClosingParen () { } - - [ExpectUnresolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Whitespace ")] - [ExpectUnresolvedDocumentationSignature (" T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Whitespace")] - [ExpectUnresolvedDocumentationSignature ("T: Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Whitespace")] - [ExpectUnresolvedDocumentationSignature ("T :Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Whitespace")] - [ExpectUnresolvedDocumentationSignature ("")] - [ExpectUnresolvedDocumentationSignature (" ")] - public class Whitespace - { - [ExpectUnresolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Whitespace.Method(System.Int32, System.Int32)")] - public static void Method (int a, int b) - { - } - - [ExpectUnresolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Whitespace.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic{System.Int32, System.Int32})")] - public static void Method (Generic g) - { - } - } - - public class Generic - { - } - - [ExpectUnresolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic{`1}")] - [ExpectUnresolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic{T}")] - [ExpectUnresolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic")] - public class Generic - { - [ExpectUnresolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic``1.MethodSyntaxForTypeParameter(`0)")] - - public void MethodSyntaxForTypeParameter (T t) - { - } - - [ExpectUnresolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic`1.MethodSyntaxForTypeGenericArgument(Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic{``0})")] - public void MethodSyntaxForTypeGenericArgument (Generic g) - { - } - - [ExpectUnresolvedDocumentationSignature ("P:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic`1.Item(``0)")] - public bool this[T t] { - get => false; - set { } - } - } - - [ExpectUnresolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.MethodWithGenericInstantiation(Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic`1)")] - public static void MethodWithGenericInstantiation (Generic g) - { - } - - [ExpectUnresolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Method(System.Int32[:,:])")] - [ExpectUnresolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Method(System.Int32[0:,)")] - public static void Method (int[,] a) - { - } - - [ExpectUnresolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NonGenericMethod(``0)")] - public static void NonGenericMethod (int i) - { - } - - [ExpectUnresolvedDocumentationSignature ("P:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Item(`0)")] - [ExpectUnresolvedDocumentationSignature ("P:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Item(``0)")] - public int this[int i] { - get => 0; - set { } - } - - [ExpectUnresolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.MethodMissingArgumentTypeName(System.)")] - public static void MethodMissingArgumentTypeName (int i) - { - } - - [ExpectUnresolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.")] - public class NoType - { - [ExpectUnresolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid..Method")] - public static void Method () - { - } - } - - // prevent warning about unused events - public void UseEvents () - { - OnEvent?.Invoke (null, new EventArgs ()); - OnEventArgs?.Invoke (null, new EventArgs ()); - } - - [ExpectUnresolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoParameterType()")] - public static void NoParameterType (int i) - { - } - - [ExpectUnresolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoParameterType(Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic{})")] - public static void NoGenericParameterType (Generic g) - { - } - - [ExpectUnresolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.TypeWithMethodGenericParameters``1")] - public class TypeWithMethodGenericParameters - { - } - - public class GenericType - { - [ExpectUnresolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.GenericType`2.TypeWithMethodGenericParameters``1")] - public class TypeWithMethodGenericParameters - { - } - } - - // our parser won't match fields with `, unlike roslyn. - [ExpectUnresolvedDocumentationSignature ("F:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.field`gibberish")] - public int field; - - [ExpectUnresolvedDocumentationSignature ("E:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.OnEvent`gibberish")] - public event EventHandler? OnEvent; - - // the below work, but seem like they shouldn't. See https://github.com/dotnet/linker/issues/1214. - - [ExpectExactlyResolvedDocumentationSignature ("TMono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoColon")] - public class NoColon - { - } - - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoClosingParenWithParameters(System.Int32")] - public static void NoClosingParenWithParameters (int a) - { - } - - [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoClosingBrace(Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic{Mono.Linker.Tests.DocumentationSignatureParserTests.A)")] - public static void NoClosingBrace (Generic g) - { - } - - [ExpectExactlyResolvedDocumentationSignature ("F:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.fieldArgs(gibberish")] - public int fieldArgs; - - [ExpectExactlyResolvedDocumentationSignature ("E:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.OnEventArgs(gibberish")] - public event EventHandler? OnEventArgs; - - [ExpectExactlyResolvedDocumentationSignature ("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NestedType{")] - public class NestedType - { - } - } - } + private static void CheckParsedString(TypeSystemEntity member, string input) + { + var module = GetModule(member); + Assert.NotNull(module); + var parseResults = DocumentationSignatureParser.GetMembersForDocumentationSignature(input, module); + Assert.Contains(member, parseResults); + } + + private static void CheckUnresolvedDocumentationSignature(TypeSystemEntity member, string input) + { + var module = GetModule(member); + Assert.NotNull(module); + var parseResults = DocumentationSignatureParser.GetMembersForDocumentationSignature(input, module); + Assert.DoesNotContain(member, parseResults); + } + + private static ModuleDesc? GetModule(TypeSystemEntity entity) + { + return entity switch + { + MethodDesc method => (method.OwningType as MetadataType)?.Module, + FieldDesc field => (field.OwningType as MetadataType)?.Module, + MetadataType type => type.Module, + PropertyPseudoDesc property => property.OwningType.Module, + EventPseudoDesc @event => @event.OwningType.Module, + _ => throw new InvalidOperationException(), + }; + } + + // testcases + + [ExpectGeneratedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.A")] + [ExpectExactlyResolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.A")] + public class A + { + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.#ctor")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.#ctor")] + public A() + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.#ctor(System.Int32)")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.#ctor(System.Int32)")] + public A(int a) + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.#cctor")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.#cctor")] + static A() + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[])")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[])")] + public static void M(int[] a) + { + } + + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32,System.Int32,System.Int32)~System.Int32")] + public static int M(int a, int b, int c) + { + return 0; + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MRef(System.Int32@)")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MRef(System.Int32@)")] + public static void MRef(ref int a) + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MOut(System.Int32@)")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MOut(System.Int32@)")] + public static void MOut(out int a) + { + a = 5; + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MIn(System.Int32@)")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MIn(System.Int32@)")] + public static void MIn(in int a) + { + } + + private static int i; + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MRefReturn")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MRefReturn")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MRefReturn~System.Int32@")] + public static ref int MRefReturn() + { + return ref i; + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M")] + [ExpectResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M")] // binds to both. + [ExpectResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M()")] // binds to both. + public static void M() + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M()")] + [ExpectResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M")] + [ExpectResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M()")] + public static void M(__arglist) + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[][])")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[][])")] + public static void M(int[][] a) + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[][0:,0:,0:])")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[][0:,0:,0:])")] + public static void M(int[,,][] a) + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[0:,0:])")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32[0:,0:])")] + public static void M(int[,] a) + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Object)")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Object)")] + public static void M(dynamic d) + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32*)")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32*)")] + public static unsafe void M(int* a) + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M``1(Mono.Linker.Tests.DocumentationSignatureParserTests.S{Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A,``0}}**[0:,0:,0:][][][0:,0:]@)")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M``1(Mono.Linker.Tests.DocumentationSignatureParserTests.S{Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A,``0}}**[0:,0:,0:][][][0:,0:]@)")] + public static unsafe void M(ref S>**[,][][][,,] a) + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Collections.Generic.List{System.Int32[]})")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Collections.Generic.List{System.Int32[]})")] + public static void M(List a) + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32,)")] + //[ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32,)")] + // there's no way to reference this, since the parsing logic doesn't like it. + public static void M(int abo, __arglist) + { + } + + [ExpectGeneratedDocumentationSignature("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Prop")] + [ExpectExactlyResolvedDocumentationSignature("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Prop")] + public int Prop { get; set; } + + [ExpectGeneratedDocumentationSignature("F:Mono.Linker.Tests.DocumentationSignatureParserTests.A.field")] + [ExpectExactlyResolvedDocumentationSignature("F:Mono.Linker.Tests.DocumentationSignatureParserTests.A.field")] + public int field; + + + [ExpectGeneratedDocumentationSignature("E:Mono.Linker.Tests.DocumentationSignatureParserTests.A.OnEvent")] + [ExpectExactlyResolvedDocumentationSignature("E:Mono.Linker.Tests.DocumentationSignatureParserTests.A.OnEvent")] + public event EventHandler? OnEvent; + + [ExpectGeneratedDocumentationSignature("E:Mono.Linker.Tests.DocumentationSignatureParserTests.A.OnEventInt")] + [ExpectExactlyResolvedDocumentationSignature("E:Mono.Linker.Tests.DocumentationSignatureParserTests.A.OnEventInt")] + public event Action? OnEventInt; + + [ExpectGeneratedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Del")] + [ExpectExactlyResolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Del")] + public delegate int Del(int a, int b); + + [ExpectGeneratedDocumentationSignature("E:Mono.Linker.Tests.DocumentationSignatureParserTests.A.OnEventDel")] + [ExpectExactlyResolvedDocumentationSignature("E:Mono.Linker.Tests.DocumentationSignatureParserTests.A.OnEventDel")] + public event Del? OnEventDel; + + // prevent warning about unused events + public void UseEvents() + { + OnEventDel?.Invoke(1, 2); + OnEventInt?.Invoke(1); + OnEvent?.Invoke(null, new EventArgs()); + } + + [ExpectGeneratedDocumentationSignature("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Item(System.Int32)")] + [ExpectExactlyResolvedDocumentationSignature("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Item(System.Int32)")] + public int this[int i] + { + get => 0; + set { } + } + + [ExpectGeneratedDocumentationSignature("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Item(System.String,System.Int32)")] + [ExpectExactlyResolvedDocumentationSignature("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A.Item(System.String,System.Int32)")] + public int this[string s, int i] + { + get => 0; + set { } + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Implicit(Mono.Linker.Tests.DocumentationSignatureParserTests.A)~System.Boolean")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Implicit(Mono.Linker.Tests.DocumentationSignatureParserTests.A)~System.Boolean")] + public static implicit operator bool(A a) => false; + + // C# will not generate a return type for this method, but we will. + // [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Implicit(Mono.Linker.Tests.DocumentationSignatureParserTests.A)~System.Boolean")] + // [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Implicit(Mono.Linker.Tests.DocumentationSignatureParserTests.A)~System.Boolean")] + //public static int op_Implicit(A a) => 0; + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_UnaryPlus(Mono.Linker.Tests.DocumentationSignatureParserTests.A)")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_UnaryPlus(Mono.Linker.Tests.DocumentationSignatureParserTests.A)")] + public static A? operator +(A a) => null; + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Addition(Mono.Linker.Tests.DocumentationSignatureParserTests.A,Mono.Linker.Tests.DocumentationSignatureParserTests.A)")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Addition(Mono.Linker.Tests.DocumentationSignatureParserTests.A,Mono.Linker.Tests.DocumentationSignatureParserTests.A)")] + public static A? operator +(A left, A right) => null; + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MWithReturnType")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.MWithReturnType~System.Boolean")] + public static bool MWithReturnType() => false; + } + + public struct S + { + } + + [ExpectGeneratedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.A`1")] + [ExpectExactlyResolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.A`1")] + public class A + { + [ExpectGeneratedDocumentationSignature("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A`1.Item(`0)")] + [ExpectExactlyResolvedDocumentationSignature("P:Mono.Linker.Tests.DocumentationSignatureParserTests.A`1.Item(`0)")] + public int this[T t] + { + get => 0; + set { } + } + } + + [ExpectExactlyResolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.B")] + [ExpectGeneratedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.B")] + public class B + { + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.B.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A{Mono.Linker.Tests.DocumentationSignatureParserTests.B},System.Collections.Generic.List{Mono.Linker.Tests.DocumentationSignatureParserTests.A}})")] + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.B.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A{Mono.Linker.Tests.DocumentationSignatureParserTests.B},System.Collections.Generic.List{Mono.Linker.Tests.DocumentationSignatureParserTests.A}})")] + public static void Method(G, List> l) + { + } + } + + [ExpectGeneratedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2")] + [ExpectExactlyResolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2")] + public class G + { + [ExpectGeneratedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1")] + [ExpectExactlyResolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1")] + public class NG + { + [ExpectGeneratedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1.NG2`1")] + [ExpectExactlyResolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1.NG2`1")] + public class NG2 + { + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1.NG2`1.Method``1(`0,`1,`2,`3,``0)")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1.NG2`1.Method``1(`0,`1,`2,`3,``0)")] + public void Method(T t, U u, V v, W w, X x) + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1.NG2`1.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{`0,`1}.NG{`2}.NG2{`3})")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.NG`1.NG2`1.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{`0,`1}.NG{`2}.NG2{`3})")] + public void Method(NG2 n) + { + } + } + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{`0,`1})")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.G`2.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{`0,`1})")] + public void Method(G g) + { + } + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method")] + public static void Method() + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method(System.Int32)")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method(System.Int32)")] + public static void Method(int i) + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.IntMethod")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.IntMethod")] + public static int IntMethod() => 0; + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A,Mono.Linker.Tests.DocumentationSignatureParserTests.A})")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A,Mono.Linker.Tests.DocumentationSignatureParserTests.A})")] + public static void Method(G g) + { + } + + [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A,Mono.Linker.Tests.DocumentationSignatureParserTests.A}.NG{Mono.Linker.Tests.DocumentationSignatureParserTests.A})")] + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.G{Mono.Linker.Tests.DocumentationSignatureParserTests.A,Mono.Linker.Tests.DocumentationSignatureParserTests.A}.NG{Mono.Linker.Tests.DocumentationSignatureParserTests.A})")] + public static void Method(G.NG g) + { + } + + public class Invalid + { + [ExpectUnresolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoReturnType~")] + public static int NoReturnType() => 0; + + [ExpectUnresolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoParameters(,)")] + public static void NoParameters(int a, int b) + { + } + + [ExpectUnresolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoClosingParen(")] + public static void NoClosingParen() { } + + [ExpectUnresolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Whitespace ")] + [ExpectUnresolvedDocumentationSignature(" T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Whitespace")] + [ExpectUnresolvedDocumentationSignature("T: Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Whitespace")] + [ExpectUnresolvedDocumentationSignature("T :Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Whitespace")] + [ExpectUnresolvedDocumentationSignature("")] + [ExpectUnresolvedDocumentationSignature(" ")] + public class Whitespace + { + [ExpectUnresolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Whitespace.Method(System.Int32, System.Int32)")] + public static void Method(int a, int b) + { + } + + [ExpectUnresolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Whitespace.Method(Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic{System.Int32, System.Int32})")] + public static void Method(Generic g) + { + } + } + + public class Generic + { + } + + [ExpectUnresolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic{`1}")] + [ExpectUnresolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic{T}")] + [ExpectUnresolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic")] + public class Generic + { + [ExpectUnresolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic``1.MethodSyntaxForTypeParameter(`0)")] + + public void MethodSyntaxForTypeParameter(T t) + { + } + + [ExpectUnresolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic`1.MethodSyntaxForTypeGenericArgument(Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic{``0})")] + public void MethodSyntaxForTypeGenericArgument(Generic g) + { + } + + [ExpectUnresolvedDocumentationSignature("P:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic`1.Item(``0)")] + public bool this[T t] + { + get => false; + set { } + } + } + + [ExpectUnresolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.MethodWithGenericInstantiation(Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic`1)")] + public static void MethodWithGenericInstantiation(Generic g) + { + } + + [ExpectUnresolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Method(System.Int32[:,:])")] + [ExpectUnresolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Method(System.Int32[0:,)")] + public static void Method(int[,] a) + { + } + + [ExpectUnresolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NonGenericMethod(``0)")] + public static void NonGenericMethod(int i) + { + } + + [ExpectUnresolvedDocumentationSignature("P:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Item(`0)")] + [ExpectUnresolvedDocumentationSignature("P:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Item(``0)")] + public int this[int i] + { + get => 0; + set { } + } + + [ExpectUnresolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.MethodMissingArgumentTypeName(System.)")] + public static void MethodMissingArgumentTypeName(int i) + { + } + + [ExpectUnresolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.")] + public class NoType + { + [ExpectUnresolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid..Method")] + public static void Method() + { + } + } + + // prevent warning about unused events + public void UseEvents() + { + OnEvent?.Invoke(null, new EventArgs()); + OnEventArgs?.Invoke(null, new EventArgs()); + } + + [ExpectUnresolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoParameterType()")] + public static void NoParameterType(int i) + { + } + + [ExpectUnresolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoParameterType(Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic{})")] + public static void NoGenericParameterType(Generic g) + { + } + + [ExpectUnresolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.TypeWithMethodGenericParameters``1")] + public class TypeWithMethodGenericParameters + { + } + + public class GenericType + { + [ExpectUnresolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.GenericType`2.TypeWithMethodGenericParameters``1")] + public class TypeWithMethodGenericParameters + { + } + } + + // our parser won't match fields with `, unlike roslyn. + [ExpectUnresolvedDocumentationSignature("F:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.field`gibberish")] + public int field; + + [ExpectUnresolvedDocumentationSignature("E:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.OnEvent`gibberish")] + public event EventHandler? OnEvent; + + // the below work, but seem like they shouldn't. See https://github.com/dotnet/linker/issues/1214. + + [ExpectExactlyResolvedDocumentationSignature("TMono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoColon")] + public class NoColon + { + } + + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoClosingParenWithParameters(System.Int32")] + public static void NoClosingParenWithParameters(int a) + { + } + + [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NoClosingBrace(Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.Generic{Mono.Linker.Tests.DocumentationSignatureParserTests.A)")] + public static void NoClosingBrace(Generic g) + { + } + + [ExpectExactlyResolvedDocumentationSignature("F:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.fieldArgs(gibberish")] + public int fieldArgs; + + [ExpectExactlyResolvedDocumentationSignature("E:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.OnEventArgs(gibberish")] + public event EventHandler? OnEventArgs; + + [ExpectExactlyResolvedDocumentationSignature("T:Mono.Linker.Tests.DocumentationSignatureParserTests.Invalid.NestedType{")] + public class NestedType + { + } + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler/ConfigurablePInvokePolicy.cs b/src/coreclr/tools/aot/ILCompiler/ConfigurablePInvokePolicy.cs index 27d6108eb70e9e..ac6e0a66934ac7 100644 --- a/src/coreclr/tools/aot/ILCompiler/ConfigurablePInvokePolicy.cs +++ b/src/coreclr/tools/aot/ILCompiler/ConfigurablePInvokePolicy.cs @@ -92,9 +92,16 @@ private IEnumerable ModuleNameVariations(string name) else { string suffix = _target.IsApplePlatform ? ".dylib" : ".so"; + bool hasSharedLibraryExtension = name.EndsWith(suffix, StringComparison.Ordinal); + const string LibPrefix = "lib"; + bool hasLibPrefix = name.StartsWith(LibPrefix, StringComparison.Ordinal); - if (name.EndsWith(suffix, StringComparison.Ordinal)) + if (hasSharedLibraryExtension) yield return name.Substring(0, name.Length - suffix.Length); + if (hasLibPrefix) + yield return name.Substring(LibPrefix.Length); + if (hasLibPrefix && hasSharedLibraryExtension) + yield return name.Substring(LibPrefix.Length, name.Length - suffix.Length - LibPrefix.Length); } } diff --git a/src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs b/src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs index 55b670ee7213da..907176421f3c6d 100644 --- a/src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs +++ b/src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs @@ -31,6 +31,8 @@ internal sealed class ILCompilerRootCommand : RootCommand new("--method-layout") { CustomParser = MakeMethodLayoutAlgorithm, DefaultValueFactory = MakeMethodLayoutAlgorithm, Description = "Layout algorithm used by profile-driven optimization for arranging methods in a file.", HelpName = "arg" }; public Option FileLayout { get; } = new("--file-layout") { CustomParser = MakeFileLayoutAlgorithm, DefaultValueFactory = MakeFileLayoutAlgorithm, Description = "Layout algorithm used by profile-driven optimization for arranging non-method contents in a file.", HelpName = "arg" }; + public Option OrderFile { get; } = + new("--order") { Description = "File that specifies order of symbols within the generated object file" }; public Option SatelliteFilePaths { get; } = new("--satellite") { DefaultValueFactory = _ => Array.Empty(), Description = "Satellite assemblies associated with inputs/references" }; public Option EnableDebugInfo { get; } = @@ -99,8 +101,8 @@ internal sealed class ILCompilerRootCommand : RootCommand new("--noinlinetls") { Description = "Do not generate inline thread local statics" }; public Option EmitStackTraceData { get; } = new("--stacktracedata") { Description = "Emit data to support generating stack trace strings at runtime" }; - public Option MethodBodyFolding { get; } = - new("--methodbodyfolding") { Description = "Fold identical method bodies" }; + public Option MethodBodyFolding { get; } = + new("--methodbodyfolding") { Description = "Fold identical method bodies (one of: none, generic, all" }; public Option InitAssemblies { get; } = new("--initassembly") { DefaultValueFactory = _ => Array.Empty(), Description = "Assembly(ies) with a library initializer" }; public Option FeatureSwitches { get; } = @@ -177,6 +179,8 @@ internal sealed class ILCompilerRootCommand : RootCommand new("--make-repro-path") { Description = "Path where to place a repro package" }; public Option UnmanagedEntryPointsAssemblies { get; } = new("--generateunmanagedentrypoints") { DefaultValueFactory = _ => Array.Empty(), Description = "Generate unmanaged entrypoints for a given assembly" }; + public Option DisableGeneratedCodeHeuristics { get; } = + new("--disable-generated-code-heuristics") { Description = "Disable heuristics for detecting compiler-generated code" }; public OptimizationMode OptimizationMode { get; private set; } public ParseResult Result; @@ -193,6 +197,7 @@ public ILCompilerRootCommand(string[] args) : base(".NET Native IL Compiler") Options.Add(MibcFilePaths); Options.Add(MethodLayout); Options.Add(FileLayout); + Options.Add(OrderFile); Options.Add(SatelliteFilePaths); Options.Add(EnableDebugInfo); Options.Add(UseDwarf5); @@ -266,6 +271,7 @@ public ILCompilerRootCommand(string[] args) : base(".NET Native IL Compiler") Options.Add(SingleMethodGenericArgs); Options.Add(MakeReproPath); Options.Add(UnmanagedEntryPointsAssemblies); + Options.Add(DisableGeneratedCodeHeuristics); this.SetAction(result => { @@ -300,7 +306,7 @@ public ILCompilerRootCommand(string[] args) : base(".NET Native IL Compiler") #pragma warning disable CA1861 // Avoid constant arrays as arguments. Only executed once during the execution of the program. Helpers.MakeReproPackage(makeReproPath, result.GetValue(OutputFilePath), args, result, - inputOptions : new[] { "-r", "--reference", "-m", "--mibc", "--rdxml", "--directpinvokelist", "--descriptor", "--satellite" }, + inputOptions : new[] { "-r", "--reference", "-m", "--mibc", "--rdxml", "--directpinvokelist", "--descriptor", "--satellite", "--order" }, outputOptions : new[] { "-o", "--out", "--exportsfile", "--dgmllog", "--scandgmllog", "--mstat", "--sourcelink" }); #pragma warning restore CA1861 // Avoid constant arrays as arguments } @@ -424,6 +430,7 @@ private static MethodLayoutAlgorithm MakeMethodLayoutAlgorithm(ArgumentResult re "hotwarmcold" => MethodLayoutAlgorithm.HotWarmCold, "pettishansen" => MethodLayoutAlgorithm.PettisHansen, "random" => MethodLayoutAlgorithm.Random, + "explicit" => MethodLayoutAlgorithm.Explicit, _ => throw new CommandLineException(result.Tokens[0].Value) }; } diff --git a/src/coreclr/tools/aot/ILCompiler/Program.cs b/src/coreclr/tools/aot/ILCompiler/Program.cs index 0cf9f83308e207..04795875d6d071 100644 --- a/src/coreclr/tools/aot/ILCompiler/Program.cs +++ b/src/coreclr/tools/aot/ILCompiler/Program.cs @@ -94,7 +94,7 @@ public int Run() } var logger = new Logger(Console.Out, ilProvider, Get(_command.IsVerbose), ProcessWarningCodes(Get(_command.SuppressedWarnings)), Get(_command.SingleWarn), Get(_command.SingleWarnEnabledAssemblies), Get(_command.SingleWarnDisabledAssemblies), suppressedWarningCategories, - Get(_command.TreatWarningsAsErrors), warningsAsErrors); + Get(_command.TreatWarningsAsErrors), warningsAsErrors, Get(_command.DisableGeneratedCodeHeuristics)); // NativeAOT is full AOT and its pre-compiled methods can not be // thrown away at runtime if they mismatch in required ISAs or @@ -361,6 +361,7 @@ public int Run() string compilationUnitPrefix = multiFile ? Path.GetFileNameWithoutExtension(outputFilePath) : ""; var builder = new RyuJitCompilationBuilder(typeSystemContext, compilationGroup) .FileLayoutAlgorithms(Get(_command.MethodLayout), Get(_command.FileLayout)) + .UseSymbolOrder(Get(_command.OrderFile)) .UseCompilationUnitPrefix(compilationUnitPrefix); string[] mibcFilePaths = Get(_command.MibcFilePaths); @@ -399,7 +400,7 @@ public int Run() logger, typeSystemContext, XmlReader.Create(fs), substitutionFilePath, featureSwitches)); } - CompilerGeneratedState compilerGeneratedState = new CompilerGeneratedState(ilProvider, logger); + CompilerGeneratedState compilerGeneratedState = new CompilerGeneratedState(ilProvider, logger, Get(_command.DisableGeneratedCodeHeuristics)); if (Get(_command.UseReachability) is string reachabilityInstrumentationFileName) { @@ -533,7 +534,7 @@ void RunScanner() substitutionProvider = new SubstitutionProvider(logger, featureSwitches, substitutions); - ilProvider = new SubstitutedILProvider(unsubstitutedILProvider, substitutionProvider, devirtualizationManager, metadataManager); + ilProvider = new SubstitutedILProvider(unsubstitutedILProvider, substitutionProvider, devirtualizationManager, metadataManager, scanResults.GetAnalysisCharacteristics()); // Use a more precise IL provider that uses whole program analysis for dead branch elimination builder.UseILProvider(ilProvider); @@ -603,10 +604,14 @@ void RunScanner() compilationRoots.Add(metadataManager); compilationRoots.Add(interopStubManager); + MethodBodyFoldingMode foldingMode = string.IsNullOrEmpty(Get(_command.MethodBodyFolding)) + ? MethodBodyFoldingMode.None + : Enum.Parse(Get(_command.MethodBodyFolding), ignoreCase: true); + builder .UseInstructionSetSupport(instructionSetSupport) .UseBackendOptions(Get(_command.CodegenOptions)) - .UseMethodBodyFolding(enable: Get(_command.MethodBodyFolding)) + .UseMethodBodyFolding(foldingMode) .UseParallelism(parallelism) .UseMetadataManager(metadataManager) .UseInteropStubManager(interopStubManager) @@ -804,12 +809,16 @@ private static IEnumerable ProcessWarningCodes(IEnumerable warningC private T Get(Option option) => _command.Result.GetValue(option); private static int Main(string[] args) => - new CommandLineConfiguration(new ILCompilerRootCommand(args) + new ILCompilerRootCommand(args) .UseVersion() - .UseExtendedHelp(ILCompilerRootCommand.PrintExtendedHelp)) - { - ResponseFileTokenReplacer = Helpers.TryReadResponseFile, - EnableDefaultExceptionHandler = false, - }.Invoke(args); + .UseExtendedHelp(ILCompilerRootCommand.PrintExtendedHelp) + .Parse(args, new() + { + ResponseFileTokenReplacer = Helpers.TryReadResponseFile, + }) + .Invoke(new() + { + EnableDefaultExceptionHandler = false + }); } } diff --git a/src/coreclr/tools/aot/crossgen2/Program.cs b/src/coreclr/tools/aot/crossgen2/Program.cs index c38f577c5a3f45..53404bb9feb440 100644 --- a/src/coreclr/tools/aot/crossgen2/Program.cs +++ b/src/coreclr/tools/aot/crossgen2/Program.cs @@ -912,12 +912,16 @@ internal static bool IsValidPublicKey(byte[] blob) private T Get(Option option) => _command.Result.GetValue(option); private static int Main(string[] args) => - new CommandLineConfiguration(new Crossgen2RootCommand(args) + new Crossgen2RootCommand(args) .UseVersion() - .UseExtendedHelp(Crossgen2RootCommand.PrintExtendedHelp)) - { - ResponseFileTokenReplacer = Helpers.TryReadResponseFile, - EnableDefaultExceptionHandler = false, - }.Invoke(args); + .UseExtendedHelp(Crossgen2RootCommand.PrintExtendedHelp) + .Parse(args, new() + { + ResponseFileTokenReplacer = Helpers.TryReadResponseFile, + }) + .Invoke(new() + { + EnableDefaultExceptionHandler = false + }); } } diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index f72f9cdeef2ac4..4069f29308dadd 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/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); @@ -154,15 +153,13 @@ struct JitInterfaceCallbacks void (* getAddressOfPInvokeTarget)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP* pLookup); void* (* GetCookieForPInvokeCalliSig)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* szMetaSig, void** ppIndirection); void* (* GetCookieForInterpreterCalliSig)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* szMetaSig); - bool (* canGetCookieForPInvokeCalliSig)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* szMetaSig); CORINFO_JUST_MY_CODE_HANDLE (* getJustMyCodeHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE method, CORINFO_JUST_MY_CODE_HANDLE** ppIndirection); void (* GetProfilingHandle)(void * thisHandle, CorInfoExceptionClass** ppException, bool* pbHookFunction, void** pProfilerHandle, bool* pbIndirectedHandles); void (* getCallInfo)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, CORINFO_METHOD_HANDLE callerHandle, CORINFO_CALLINFO_FLAGS flags, CORINFO_CALL_INFO* pResult); bool (* getStaticFieldContent)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, int valueOffset, bool ignoreMovableObjects); bool (* getObjectContent)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_OBJECT_HANDLE obj, uint8_t* buffer, int bufferSize, int valueOffset); CORINFO_CLASS_HANDLE (* getStaticFieldCurrentClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, bool* pIsSpeculative); - CORINFO_VARARGS_HANDLE (* getVarArgsHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* pSig, void** ppIndirection); - bool (* canGetVarArgsHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* pSig); + CORINFO_VARARGS_HANDLE (* getVarArgsHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* pSig, CORINFO_METHOD_HANDLE methHnd, void** ppIndirection); InfoAccessType (* constructStringLiteral)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE module, unsigned int metaTok, void** ppValue); InfoAccessType (* emptyStringLiteral)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppValue); uint32_t (* getFieldThreadLocalStoreID)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, void** ppIndirection); @@ -1480,16 +1477,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) { @@ -1587,15 +1574,6 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual bool canGetCookieForPInvokeCalliSig( - CORINFO_SIG_INFO* szMetaSig) -{ - CorInfoExceptionClass* pException = nullptr; - bool temp = _callbacks->canGetCookieForPInvokeCalliSig(_thisHandle, &pException, szMetaSig); - if (pException != nullptr) throw pException; - return temp; -} - virtual CORINFO_JUST_MY_CODE_HANDLE getJustMyCodeHandle( CORINFO_METHOD_HANDLE method, CORINFO_JUST_MY_CODE_HANDLE** ppIndirection) @@ -1665,19 +1643,11 @@ class JitInterfaceWrapper : public ICorJitInfo virtual CORINFO_VARARGS_HANDLE getVarArgsHandle( CORINFO_SIG_INFO* pSig, + CORINFO_METHOD_HANDLE methHnd, void** ppIndirection) { CorInfoExceptionClass* pException = nullptr; - CORINFO_VARARGS_HANDLE temp = _callbacks->getVarArgsHandle(_thisHandle, &pException, pSig, ppIndirection); - if (pException != nullptr) throw pException; - return temp; -} - - virtual bool canGetVarArgsHandle( - CORINFO_SIG_INFO* pSig) -{ - CorInfoExceptionClass* pException = nullptr; - bool temp = _callbacks->canGetVarArgsHandle(_thisHandle, &pException, pSig); + CORINFO_VARARGS_HANDLE temp = _callbacks->getVarArgsHandle(_thisHandle, &pException, pSig, methHnd, ppIndirection); if (pException != nullptr) throw pException; return temp; } diff --git a/src/coreclr/tools/dotnet-pgo/Program.cs b/src/coreclr/tools/dotnet-pgo/Program.cs index 3ed5bd51efc4e8..a36fce10d09e1c 100644 --- a/src/coreclr/tools/dotnet-pgo/Program.cs +++ b/src/coreclr/tools/dotnet-pgo/Program.cs @@ -161,13 +161,17 @@ public Program(PgoRootCommand command) private bool IsSet(Option option) => _command.Result.GetResult(option) != null; private static int Main(string[] args) => - new CommandLineConfiguration(new PgoRootCommand(args) + new PgoRootCommand(args) .UseVersion() - .UseExtendedHelp(PgoRootCommand.PrintExtendedHelp)) - { - ResponseFileTokenReplacer = Helpers.TryReadResponseFile, - EnableDefaultExceptionHandler = false, - }.Invoke(args); + .UseExtendedHelp(PgoRootCommand.PrintExtendedHelp) + .Parse(args, new() + { + ResponseFileTokenReplacer = Helpers.TryReadResponseFile, + }) + .Invoke(new() + { + EnableDefaultExceptionHandler = false + }); public static void PrintWarning(string warning) { diff --git a/src/coreclr/tools/dotnet-pgo/dotnet-pgo.csproj b/src/coreclr/tools/dotnet-pgo/dotnet-pgo.csproj index ac3720d4f7e059..40a919e7b9ba90 100644 --- a/src/coreclr/tools/dotnet-pgo/dotnet-pgo.csproj +++ b/src/coreclr/tools/dotnet-pgo/dotnet-pgo.csproj @@ -9,11 +9,10 @@ $(RuntimeBinDir)/dotnet-pgo true false - linux-x64;linux-musl-x64;win-x64 true true dotnet-pgo - win-x64;win-x86;osx-x64 + win-x64;win-x86;osx-x64;linux-x64;linux-musl-x64 $(OutputPath) false .NET Performance Guided Optimization Tool diff --git a/src/coreclr/tools/metainfo/mdinfo.cpp b/src/coreclr/tools/metainfo/mdinfo.cpp index bac3b2158117aa..ced1b33e0903b7 100644 --- a/src/coreclr/tools/metainfo/mdinfo.cpp +++ b/src/coreclr/tools/metainfo/mdinfo.cpp @@ -2912,7 +2912,7 @@ HRESULT MDInfo::GetOneElementType(PCCOR_SIGNATURE pbSigBlob, ULONG ulSigBlob, UL return hr; } // HRESULT MDInfo::GetOneElementType() -// Display the fields of the N/Direct custom value structure. +// Display the fields of the PInvoke custom value structure. void MDInfo::DisplayCorNativeLink(COR_NATIVE_LINK *pCorNLnk, const char *preFix) { diff --git a/src/coreclr/tools/r2rdump/Extensions.cs b/src/coreclr/tools/r2rdump/Extensions.cs index 4f0e461cc03106..1f635883329097 100644 --- a/src/coreclr/tools/r2rdump/Extensions.cs +++ b/src/coreclr/tools/r2rdump/Extensions.cs @@ -21,6 +21,23 @@ public static void WriteTo(this DebugInfo theThis, TextWriter writer, DumpModel writer.WriteLine("Debug Info"); writer.WriteLine(" Bounds:"); + + byte[] boundsBytes = theThis.BoundsBytes; + for (int i = 0; i < boundsBytes.Length; i++) + { + if (i % 16 == 0) + { + writer.Write($"{i:X8}:"); + } + writer.Write($" {boundsBytes[i]:X2}"); + if (i % 16 == 15 && i != boundsBytes.Length - 1) + { + writer.WriteLine(""); + } + } + + writer.WriteLine(""); + for (int i = 0; i < theThis.BoundsList.Count; ++i) { writer.Write(" "); diff --git a/src/coreclr/tools/r2rdump/Program.cs b/src/coreclr/tools/r2rdump/Program.cs index 4755414bd66496..9bf71723a02f59 100644 --- a/src/coreclr/tools/r2rdump/Program.cs +++ b/src/coreclr/tools/r2rdump/Program.cs @@ -499,9 +499,12 @@ public int Run() private T Get(Option option) => _command.Result.GetValue(option); public static int Main(string[] args) => - new CommandLineConfiguration(new R2RDumpRootCommand().UseVersion()) - { - ResponseFileTokenReplacer = Helpers.TryReadResponseFile - }.Invoke(args); + new R2RDumpRootCommand().UseVersion() + .Parse(args, + new ParserConfiguration() + { + ResponseFileTokenReplacer = Helpers.TryReadResponseFile + }) + .Invoke(); } } diff --git a/src/coreclr/tools/r2rdump/TextDumper.cs b/src/coreclr/tools/r2rdump/TextDumper.cs index 9f2c462ddaa347..60cd0fb09ba35d 100644 --- a/src/coreclr/tools/r2rdump/TextDumper.cs +++ b/src/coreclr/tools/r2rdump/TextDumper.cs @@ -346,8 +346,8 @@ public override void DumpSectionContents(ReadyToRunSection section) if (!_model.Naked) { uint availableTypesSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress); - NativeParser availableTypesParser = new NativeParser(_r2r.Image, availableTypesSectionOffset); - NativeHashtable availableTypes = new NativeHashtable(_r2r.Image, availableTypesParser, (uint)(availableTypesSectionOffset + section.Size)); + NativeParser availableTypesParser = new NativeParser(_r2r.ImageReader, availableTypesSectionOffset); + NativeHashtable availableTypes = new NativeHashtable(_r2r.ImageReader, availableTypesParser, (uint)(availableTypesSectionOffset + section.Size)); _writer.WriteLine(availableTypes.ToString()); } @@ -364,7 +364,7 @@ public override void DumpSectionContents(ReadyToRunSection section) case ReadyToRunSectionType.MethodDefEntryPoints: if (!_model.Naked) { - NativeArray methodEntryPoints = new NativeArray(_r2r.Image, (uint)_r2r.GetOffset(section.RelativeVirtualAddress)); + NativeArray methodEntryPoints = new NativeArray(_r2r.ImageReader, (uint)_r2r.GetOffset(section.RelativeVirtualAddress)); _writer.Write(methodEntryPoints.ToString()); } @@ -382,8 +382,8 @@ public override void DumpSectionContents(ReadyToRunSection section) if (!_model.Naked) { uint instanceSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress); - NativeParser instanceParser = new NativeParser(_r2r.Image, instanceSectionOffset); - NativeHashtable instMethodEntryPoints = new NativeHashtable(_r2r.Image, instanceParser, (uint)(instanceSectionOffset + section.Size)); + NativeParser instanceParser = new NativeParser(_r2r.ImageReader, instanceSectionOffset); + NativeHashtable instMethodEntryPoints = new NativeHashtable(_r2r.ImageReader, instanceParser, (uint)(instanceSectionOffset + section.Size)); _writer.Write(instMethodEntryPoints.ToString()); _writer.WriteLine(); } @@ -400,13 +400,13 @@ public override void DumpSectionContents(ReadyToRunSection section) _writer.WriteLine("-----------------------------------------"); while (rtfOffset < rtfEndOffset) { - int startRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); + int startRva = _r2r.ImageReader.ReadInt32(ref rtfOffset); int endRva = -1; if (_r2r.Machine == Machine.Amd64) { - endRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); + endRva = _r2r.ImageReader.ReadInt32(ref rtfOffset); } - int unwindRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); + int unwindRva = _r2r.ImageReader.ReadInt32(ref rtfOffset); string endRvaText = (endRva != -1 ? endRva.ToString("x8") : " "); _writer.WriteLine($"{rtfIndex,7} | {startRva:X8} | {endRvaText} | {unwindRva:X8}"); rtfIndex++; @@ -488,7 +488,7 @@ public override void DumpSectionContents(ReadyToRunSection section) case ReadyToRunSectionType.AttributePresence: int attributesStartOffset = _r2r.GetOffset(section.RelativeVirtualAddress); int attributesEndOffset = attributesStartOffset + section.Size; - NativeCuckooFilter attributes = new NativeCuckooFilter(_r2r.Image, attributesStartOffset, attributesEndOffset); + NativeCuckooFilter attributes = new NativeCuckooFilter(_r2r.ImageReader, attributesStartOffset, attributesEndOffset); _writer.WriteLine("Attribute presence filter"); _writer.WriteLine(attributes.ToString()); break; @@ -524,80 +524,80 @@ public override void DumpSectionContents(ReadyToRunSection section) int hotColdMapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); for (int i = 0; i < count; i++) { - _writer.Write(NativeReader.ReadInt32(_r2r.Image, ref hotColdMapOffset)); + _writer.Write(_r2r.ImageReader.ReadInt32(ref hotColdMapOffset)); _writer.Write(","); - _writer.WriteLine(NativeReader.ReadInt32(_r2r.Image, ref hotColdMapOffset)); + _writer.WriteLine(_r2r.ImageReader.ReadInt32(ref hotColdMapOffset)); } break; case ReadyToRunSectionType.MethodIsGenericMap: + { + int mapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); + int mapDone = section.Size + mapOffset; + int countMethods = _r2r.ImageReader.ReadInt32(ref mapOffset); + int curMethod = 1; + while ((curMethod <= countMethods) && mapDone > mapOffset) { - int mapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); - int mapDone = section.Size + mapOffset; - int countMethods = NativeReader.ReadInt32(_r2r.Image, ref mapOffset); - int curMethod = 1; - while ((curMethod <= countMethods) && mapDone > mapOffset) - { - byte curByte = NativeReader.ReadByte(_r2r.Image, ref mapOffset); - for (int i = 0; i < 8 && (curMethod <= countMethods); i++) - { - bool isGeneric = (curByte & 0x80) == 0x80; - _writer.WriteLine($"{curMethod | 0x06000000:x8} : {isGeneric}"); - curByte <<= 1; - curMethod++; - } - } - if (curMethod != (countMethods + 1)) + byte curByte = _r2r.ImageReader.ReadByte(ref mapOffset); + for (int i = 0; i < 8 && (curMethod <= countMethods); i++) { - Program.WriteWarning("MethodIsGenericMap malformed"); - System.Diagnostics.Debug.Fail("MethodIsGenericMap malformed"); + bool isGeneric = (curByte & 0x80) == 0x80; + _writer.WriteLine($"{curMethod | 0x06000000:x8} : {isGeneric}"); + curByte <<= 1; + curMethod++; } - break; } + if (curMethod != (countMethods + 1)) + { + Program.WriteWarning("MethodIsGenericMap malformed"); + System.Diagnostics.Debug.Fail("MethodIsGenericMap malformed"); + } + break; + } case ReadyToRunSectionType.EnclosingTypeMap: + { + int mapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); + int mapDone = section.Size + mapOffset; + uint countTypes = checked((uint)((section.Size / 2 - 1))); // 2 bytes per nested type. This data structure is only used for IL images where there are <= 0xFFFE types. + if (countTypes != _r2r.ImageReader.ReadUInt16(ref mapOffset)) { - int mapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); - int mapDone = section.Size + mapOffset; - uint countTypes = checked((uint)((section.Size / 2 - 1))); // 2 bytes per nested type. This data structure is only used for IL images where there are <= 0xFFFE types. - if (countTypes != NativeReader.ReadUInt16(_r2r.Image, ref mapOffset)) - { - Program.WriteWarning("EnclosingTypeMap malformed"); - System.Diagnostics.Debug.Fail("EnclosingTypeMap malformed"); - } - int curType = 1; - while (curType <= (countTypes + 1)) - { - _writer.WriteLine($"{curType | 0x02000000:x8} : {NativeReader.ReadUInt16(_r2r.Image, ref mapOffset) | 0x02000000:x8}"); - curType++; - } - break; + Program.WriteWarning("EnclosingTypeMap malformed"); + System.Diagnostics.Debug.Fail("EnclosingTypeMap malformed"); } + int curType = 1; + while (curType <= (countTypes + 1)) + { + _writer.WriteLine($"{curType | 0x02000000:x8} : {_r2r.ImageReader.ReadUInt16(ref mapOffset) | 0x02000000:x8}"); + curType++; + } + break; + } case ReadyToRunSectionType.TypeGenericInfoMap: + { + int mapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); + int mapDone = section.Size + mapOffset; + int countTypes = _r2r.ImageReader.ReadInt32(ref mapOffset); + int curType = 1; + while ((curType <= countTypes) && mapDone > mapOffset) { - int mapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); - int mapDone = section.Size + mapOffset; - int countTypes = NativeReader.ReadInt32(_r2r.Image, ref mapOffset); - int curType = 1; - while ((curType <= countTypes) && mapDone > mapOffset) + byte curByte = _r2r.ImageReader.ReadByte(ref mapOffset); + for (int i = 0; i < 2 && (curType <= countTypes); i++) { - byte curByte = NativeReader.ReadByte(_r2r.Image, ref mapOffset); - for (int i = 0; i < 2 && (curType <= countTypes); i++) - { - var genericInfo = (ReadyToRunTypeGenericInfo)((curByte & 0xF0) >> 4); - bool hasConstraints = genericInfo.HasFlag(ReadyToRunTypeGenericInfo.HasConstraints); - bool hasVariance = genericInfo.HasFlag(ReadyToRunTypeGenericInfo.HasVariance); - var genericCount = (ReadyToRunGenericInfoGenericCount)(genericInfo & ReadyToRunTypeGenericInfo.GenericCountMask); - _writer.WriteLine($"{curType | 0x06000000:x8} : GenericArgumentCount: {genericCount} HasVariance {hasVariance} HasConstraints {hasConstraints}"); - curByte <<= 4; - curType++; - } - } - if (curType != (countTypes + 1)) - { - Program.WriteWarning("TypeGenericInfoMap malformed"); - System.Diagnostics.Debug.Fail("TypeGenericInfoMap malformed"); + var genericInfo = (ReadyToRunTypeGenericInfo)((curByte & 0xF0) >> 4); + bool hasConstraints = genericInfo.HasFlag(ReadyToRunTypeGenericInfo.HasConstraints); + bool hasVariance = genericInfo.HasFlag(ReadyToRunTypeGenericInfo.HasVariance); + var genericCount = (ReadyToRunGenericInfoGenericCount)(genericInfo & ReadyToRunTypeGenericInfo.GenericCountMask); + _writer.WriteLine($"{curType | 0x06000000:x8} : GenericArgumentCount: {genericCount} HasVariance {hasVariance} HasConstraints {hasConstraints}"); + curByte <<= 4; + curType++; } - break; } + if (curType != (countTypes + 1)) + { + Program.WriteWarning("TypeGenericInfoMap malformed"); + System.Diagnostics.Debug.Fail("TypeGenericInfoMap malformed"); + } + break; + } default: _writer.WriteLine("Unsupported section type {0}", section.Type); @@ -619,7 +619,8 @@ public override void DumpFixupStats() var sortedFixupCounts = _r2r.Methods.Where(m => m.Fixups != null) .SelectMany(m => m.Fixups) .GroupBy(f => f.Signature.FixupKind) - .Select(group => new { + .Select(group => new + { FixupKind = group.Key, Count = group.Count() }).OrderByDescending(x => x.Count); diff --git a/src/coreclr/tools/r2rtest/CommandLineOptions.cs b/src/coreclr/tools/r2rtest/CommandLineOptions.cs index c892030f1af94b..3966dbed6ebcc1 100644 --- a/src/coreclr/tools/r2rtest/CommandLineOptions.cs +++ b/src/coreclr/tools/r2rtest/CommandLineOptions.cs @@ -299,7 +299,7 @@ void CreateCommand(string name, string description, Option[] options, Func("--asp-net-path", "-asp") { Description = "Path to SERP's ASP.NET Core folder" }.AcceptExistingOnly(); private static int Main(string[] args) => - new CommandLineConfiguration(new R2RTestRootCommand().UseVersion()).Invoke(args); + new R2RTestRootCommand().UseVersion().Parse(args).Invoke(); } public partial class BuildOptions diff --git a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h index 1a04979bad37a5..01ec01427fa862 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h @@ -205,6 +205,9 @@ struct Agnostic_CORINFO_ASYNC_INFO DWORD continuationsNeedMethodHandle; DWORDLONG captureExecutionContextMethHnd; DWORDLONG restoreExecutionContextMethHnd; + DWORDLONG captureContinuationContextMethHnd; + DWORDLONG captureContextsMethHnd; + DWORDLONG restoreContextsMethHnd; }; struct Agnostic_GetOSRInfo @@ -705,12 +708,7 @@ struct GetVarArgsHandleValue DWORD pSig_Index; DWORDLONG scope; DWORD token; -}; - -struct CanGetVarArgsHandleValue -{ - DWORDLONG scope; - DWORD token; + DWORDLONG methHnd; }; struct GetCookieForPInvokeCalliSigValue @@ -729,12 +727,6 @@ struct GetCookieForInterpreterCalliSigValue DWORD token; }; -struct CanGetCookieForPInvokeCalliSigValue -{ - DWORDLONG scope; - DWORD token; -}; - struct GetReadyToRunHelper_TOKENin { Agnostic_CORINFO_RESOLVED_TOKEN ResolvedToken; diff --git a/src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp index 8c9252869fe243..e878cd59d82ff3 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp @@ -906,6 +906,31 @@ void CompileResult::applyRelocs(RelocContext* rc, unsigned char* block1, ULONG b } } + if (targetArch == SPMI_TARGET_ARCHITECTURE_RISCV64) + { + DWORDLONG fixupLocation = tmp.location; + DWORDLONG address = section_begin + (size_t)fixupLocation - (size_t)originalAddr; + + switch (relocType) + { + case IMAGE_REL_RISCV64_PC: + { + if ((section_begin <= address) && (address < section_end)) // A reloc for our section? + { + // Similar to x64's IMAGE_REL_BASED_REL32 handling we + // will handle this by also hardcoding the bottom bits + // of the target into the instruction. + PutRiscV64AuipcItype((UINT32*)address, (INT32)tmp.target); + } + wasRelocHandled = true; + } + break; + + default: + break; + } + } + if (IsSpmiTarget64Bit()) { if (!wasRelocHandled && (relocType == IMAGE_REL_BASED_DIR64)) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index b65429f3153bd4..cc0878ee3d7d66 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -21,8 +21,6 @@ LWM(GetPgoInstrumentationResults, DWORDLONG, Agnostic_GetPgoInstrumentationResul LWM(AsCorInfoType, DWORDLONG, DWORD) LWM(CanAccessClass, Agnostic_CanAccessClassIn, Agnostic_CanAccessClassOut) LWM(CanCast, DLDL, DWORD) -LWM(CanGetCookieForPInvokeCalliSig, CanGetCookieForPInvokeCalliSigValue, DWORD) -LWM(CanGetVarArgsHandle, CanGetVarArgsHandleValue, DWORD) LWM(CanInline, DLDL, Agnostic_CanInline) LWM(CanTailCall, Agnostic_CanTailCall, DWORD) LWM(CheckMethodModifier, Agnostic_CheckMethodModifier, DWORD) @@ -115,7 +113,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) @@ -138,7 +135,6 @@ LWM(GetSpecialCopyHelper, DWORDLONG, DWORDLONG) LWM(GetThreadTLSIndex, DWORD, DLD) LWM(GetTokenTypeAsHandle, GetTokenTypeAsHandleValue, DWORDLONG) LWM(GetTypeForBox, DWORDLONG, DWORDLONG) -LWM(GetTypeForBoxOnStack, DWORDLONG, DWORDLONG) LWM(GetTypeForPrimitiveValueClass, DWORDLONG, DWORD) LWM(GetTypeForPrimitiveNumericClass, DWORDLONG, DWORD) LWM(GetUnboxedEntry, DWORDLONG, DLD); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index bfdab057de446b..c2c5e7e0d5eae2 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -1915,30 +1915,6 @@ CORINFO_CLASS_HANDLE MethodContext::repGetTypeForBox(CORINFO_CLASS_HANDLE cls) return result; } -void MethodContext::recGetTypeForBoxOnStack(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result) -{ - if (GetTypeForBoxOnStack == nullptr) - GetTypeForBoxOnStack = new LightWeightMap(); - - DWORDLONG key = CastHandle(cls); - DWORDLONG value = CastHandle(result); - GetTypeForBoxOnStack->Add(key, value); - DEBUG_REC(dmpGetTypeForBoxOnStack(key, value)); -} -void MethodContext::dmpGetTypeForBoxOnStack(DWORDLONG key, DWORDLONG value) -{ - printf("GetTypeForBoxOnStack key cls-%016" PRIX64 ", value res-%016" PRIX64 "", key, value); -} - -CORINFO_CLASS_HANDLE MethodContext::repGetTypeForBoxOnStack(CORINFO_CLASS_HANDLE cls) -{ - DWORDLONG key = CastHandle(cls); - DWORDLONG value = LookupByKeyOrMiss(GetTypeForBoxOnStack, key, ": key %016" PRIX64 "", key); - DEBUG_REP(dmpGetTypeForBoxOnStack(key, value)); - CORINFO_CLASS_HANDLE result = (CORINFO_CLASS_HANDLE)value; - return result; -} - void MethodContext::recGetBoxHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc result) { if (GetBoxHelper == nullptr) @@ -2396,7 +2372,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); } @@ -4486,6 +4462,9 @@ void MethodContext::recGetAsyncInfo(const CORINFO_ASYNC_INFO* pAsyncInfo) value.continuationsNeedMethodHandle = pAsyncInfo->continuationsNeedMethodHandle ? 1 : 0; value.captureExecutionContextMethHnd = CastHandle(pAsyncInfo->captureExecutionContextMethHnd); value.restoreExecutionContextMethHnd = CastHandle(pAsyncInfo->restoreExecutionContextMethHnd); + value.captureContinuationContextMethHnd = CastHandle(pAsyncInfo->captureContinuationContextMethHnd); + value.captureContextsMethHnd = CastHandle(pAsyncInfo->captureContextsMethHnd); + value.restoreContextsMethHnd = CastHandle(pAsyncInfo->restoreContextsMethHnd); GetAsyncInfo->Add(0, value); DEBUG_REC(dmpGetAsyncInfo(0, value)); @@ -4511,6 +4490,9 @@ void MethodContext::repGetAsyncInfo(CORINFO_ASYNC_INFO* pAsyncInfoOut) pAsyncInfoOut->continuationsNeedMethodHandle = value.continuationsNeedMethodHandle != 0; pAsyncInfoOut->captureExecutionContextMethHnd = (CORINFO_METHOD_HANDLE)value.captureExecutionContextMethHnd; pAsyncInfoOut->restoreExecutionContextMethHnd = (CORINFO_METHOD_HANDLE)value.restoreExecutionContextMethHnd; + pAsyncInfoOut->captureContinuationContextMethHnd = (CORINFO_METHOD_HANDLE)value.captureContinuationContextMethHnd; + pAsyncInfoOut->captureContextsMethHnd = (CORINFO_METHOD_HANDLE)value.captureContextsMethHnd; + pAsyncInfoOut->restoreContextsMethHnd = (CORINFO_METHOD_HANDLE)value.restoreContextsMethHnd; DEBUG_REP(dmpGetAsyncInfo(0, value)); } @@ -5504,38 +5486,7 @@ 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) +void MethodContext::recGetVarArgsHandle(CORINFO_SIG_INFO* pSig, CORINFO_METHOD_HANDLE methHnd, void** ppIndirection, CORINFO_VARARGS_HANDLE result) { if (GetVarArgsHandle == nullptr) GetVarArgsHandle = new LightWeightMap(); @@ -5546,6 +5497,7 @@ void MethodContext::recGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirec key.pSig_Index = (DWORD)GetVarArgsHandle->AddBuffer((unsigned char*)pSig->pSig, pSig->cbSig); key.scope = CastHandle(pSig->scope); key.token = (DWORD)pSig->token; + key.methHnd = CastHandle(methHnd); DLDL value; if (ppIndirection != nullptr) @@ -5559,12 +5511,12 @@ void MethodContext::recGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirec } void MethodContext::dmpGetVarArgsHandle(const GetVarArgsHandleValue& key, DLDL value) { - printf("GetVarArgsHandle key sig-%s scope-%016" PRIX64 " token-%08X", + printf("GetVarArgsHandle key sig-%s scope-%016" PRIX64 " token-%08X methHnd-%016" PRIX64 "", SpmiDumpHelper::DumpPSig(key.pSig_Index, key.cbSig, GetVarArgsHandle).c_str(), - key.scope, key.token); + key.scope, key.token, key.methHnd); printf(", value ppIndirection-%016" PRIX64 " result-%016" PRIX64 "", value.A, value.B); } -CORINFO_VARARGS_HANDLE MethodContext::repGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection) +CORINFO_VARARGS_HANDLE MethodContext::repGetVarArgsHandle(CORINFO_SIG_INFO* pSig, CORINFO_METHOD_HANDLE methHnd, void** ppIndirection) { GetVarArgsHandleValue key; ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding @@ -5572,6 +5524,7 @@ CORINFO_VARARGS_HANDLE MethodContext::repGetVarArgsHandle(CORINFO_SIG_INFO* pSig key.pSig_Index = (DWORD)GetVarArgsHandle->Contains((unsigned char*)pSig->pSig, pSig->cbSig); key.scope = CastHandle(pSig->scope); key.token = (DWORD)pSig->token; + key.methHnd = CastHandle(methHnd); DLDL value = LookupByKeyOrMissNoMessage(GetVarArgsHandle, key); @@ -5582,37 +5535,6 @@ CORINFO_VARARGS_HANDLE MethodContext::repGetVarArgsHandle(CORINFO_SIG_INFO* pSig return (CORINFO_VARARGS_HANDLE)value.B; } -void MethodContext::recCanGetVarArgsHandle(CORINFO_SIG_INFO* pSig, bool result) -{ - if (CanGetVarArgsHandle == nullptr) - CanGetVarArgsHandle = new LightWeightMap(); - - CanGetVarArgsHandleValue key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.scope = CastHandle(pSig->scope); - key.token = (DWORD)pSig->token; - - DWORD value = result ? 1 : 0; - CanGetVarArgsHandle->Add(key, value); - DEBUG_REC(dmpCanGetVarArgsHandle(key, value)); -} -void MethodContext::dmpCanGetVarArgsHandle(const CanGetVarArgsHandleValue& key, DWORD value) -{ - printf("CanGetVarArgsHandle key scope-%016" PRIX64 " token-%08X, value result-%08X", key.scope, key.token, value); -} -bool MethodContext::repCanGetVarArgsHandle(CORINFO_SIG_INFO* pSig) -{ - CanGetVarArgsHandleValue key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.scope = CastHandle(pSig->scope); - key.token = (DWORD)pSig->token; - - DWORD value = LookupByKeyOrMiss(CanGetVarArgsHandle, key, ": key %016" PRIX64 " %08X", key.scope, key.token); - - DEBUG_REP(dmpCanGetVarArgsHandle(key, value)); - return value != 0; -} - void MethodContext::recGetFieldThreadLocalStoreID(CORINFO_FIELD_HANDLE field, void** ppIndirection, DWORD result) { if (GetFieldThreadLocalStoreID == nullptr) @@ -6166,6 +6088,8 @@ void MethodContext::dmpGetCookieForPInvokeCalliSig(const GetCookieForPInvokeCall } LPVOID MethodContext::repGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection) { + AssertMapExistsNoMessage(GetCookieForInterpreterCalliSig); + GetCookieForPInvokeCalliSigValue key; ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding key.cbSig = (DWORD)szMetaSig->cbSig; @@ -6221,38 +6145,6 @@ LPVOID MethodContext::repGetCookieForInterpreterCalliSig(CORINFO_SIG_INFO* szMet return (LPVOID)value.A; } -void MethodContext::recCanGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, bool result) -{ - if (CanGetCookieForPInvokeCalliSig == nullptr) - CanGetCookieForPInvokeCalliSig = new LightWeightMap(); - - CanGetCookieForPInvokeCalliSigValue key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.scope = CastHandle(szMetaSig->scope); - key.token = (DWORD)szMetaSig->token; - - DWORD value = result ? 1 : 0; - CanGetCookieForPInvokeCalliSig->Add(key, value); - DEBUG_REC(dmpCanGetCookieForPInvokeCalliSig(key, value)); -} -void MethodContext::dmpCanGetCookieForPInvokeCalliSig(const CanGetCookieForPInvokeCalliSigValue& key, DWORD value) -{ - printf("CanGetCookieForPInvokeCalliSig key scope-%016" PRIX64 " token-%08X, value result-%08X", key.scope, key.token, - value); -} -bool MethodContext::repCanGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig) -{ - CanGetCookieForPInvokeCalliSigValue key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.scope = CastHandle(szMetaSig->scope); - key.token = (DWORD)szMetaSig->token; - - DWORD value = LookupByKeyOrMissNoMessage(CanGetCookieForPInvokeCalliSig, key); - - DEBUG_REP(dmpCanGetCookieForPInvokeCalliSig(key, value)); - return value != 0; -} - void MethodContext::recErrorList(const char* error) { if (ErrorList == nullptr) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 06c1c1e33bd842..c86944897c4f4f 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -242,10 +242,6 @@ class MethodContext void dmpGetTypeForBox(DWORDLONG key, DWORDLONG value); CORINFO_CLASS_HANDLE repGetTypeForBox(CORINFO_CLASS_HANDLE cls); - void recGetTypeForBoxOnStack(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result); - void dmpGetTypeForBoxOnStack(DWORDLONG key, DWORDLONG value); - CORINFO_CLASS_HANDLE repGetTypeForBoxOnStack(CORINFO_CLASS_HANDLE cls); - void recGetBoxHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc result); void dmpGetBoxHelper(DWORDLONG key, DWORD value); CorInfoHelpFunc repGetBoxHelper(CORINFO_CLASS_HANDLE cls); @@ -460,13 +456,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,17 +709,9 @@ 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 recGetVarArgsHandle(CORINFO_SIG_INFO* pSig, CORINFO_METHOD_HANDLE methHnd, void** ppIndirection, CORINFO_VARARGS_HANDLE result); void dmpGetVarArgsHandle(const GetVarArgsHandleValue& key, DLDL value); - CORINFO_VARARGS_HANDLE repGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection); - - void recCanGetVarArgsHandle(CORINFO_SIG_INFO* pSig, bool result); - void dmpCanGetVarArgsHandle(const CanGetVarArgsHandleValue& key, DWORD value); - bool repCanGetVarArgsHandle(CORINFO_SIG_INFO* pSig); + CORINFO_VARARGS_HANDLE repGetVarArgsHandle(CORINFO_SIG_INFO* pSig, CORINFO_METHOD_HANDLE methHnd, void** ppIndirection); void recGetFieldThreadLocalStoreID(CORINFO_FIELD_HANDLE field, void** ppIndirection, DWORD result); void dmpGetFieldThreadLocalStoreID(DWORDLONG key, DLD value); @@ -766,10 +754,6 @@ class MethodContext void recGetCookieForInterpreterCalliSig(CORINFO_SIG_INFO* szMetaSig, LPVOID result); void dmpGetCookieForInterpreterCalliSig(const GetCookieForInterpreterCalliSigValue& key, DLDL value); - void recCanGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, bool result); - void dmpCanGetCookieForPInvokeCalliSig(const CanGetCookieForPInvokeCalliSigValue& key, DWORD value); - bool repCanGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig); - void recErrorList(const char* error); void dmpErrorList(DWORD key, DWORD value); @@ -1068,7 +1052,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, @@ -1211,7 +1195,7 @@ enum mcPackets Packet_GetClassStaticDynamicInfo = 218, Packet_GetClassThreadStaticDynamicInfo = 219, Packet_IsGenericType = 220, - Packet_GetTypeForBoxOnStack = 221, + //Packet_GetTypeForBoxOnStack = 221, Packet_GetTypeDefinition = 222, Packet_GetFpStructLowering = 223, Packet_GetSpecialCopyHelper = 224, diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp index 529d8260b675c2..3165ac8ab73436 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp +++ b/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/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h index df3ca7b31653f8..f5ef48009b8370 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h +++ b/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/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp index 9bba21b1bfd8e5..2b17d0ac8352ad 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp @@ -477,6 +477,54 @@ void PutArm32MovtConstant(UINT32* p, unsigned con) *((UINT16*)p + 1) = (UINT16)instr; } +//***************************************************************************** +// Extract the PC-Relative offset from auipc + I-type adder (addi/ld/jalr) +//***************************************************************************** +INT64 GetRiscV64AuipcItype(UINT32 * pCode) +{ + enum + { + OpcodeAuipc = 0x00000017, + OpcodeAddi = 0x00000013, + OpcodeLd = 0x00003003, + OpcodeJalr = 0x00000067, + OpcodeUTypeMask = 0x0000007F, + OpcodeITypeMask = 0x0000307F, + }; + + UINT32 auipc = pCode[0]; + _ASSERTE((auipc & OpcodeUTypeMask) == OpcodeAuipc); + int auipcRegDest = (auipc >> 7) & 0x1F; + _ASSERTE(auipcRegDest != 0); + + INT64 hi20 = (INT32(auipc) >> 12) << 12; + + UINT32 iType = pCode[1]; + UINT32 opcode = iType & OpcodeITypeMask; + _ASSERTE(opcode == OpcodeAddi || opcode == OpcodeLd || opcode == OpcodeJalr); + int iTypeRegSrc = (iType >> 15) & 0x1F; + _ASSERTE(auipcRegDest == iTypeRegSrc); + + INT64 lo12 = INT32(iType) >> 20; + + return hi20 + lo12; +} + +//***************************************************************************** +// Deposit the PC-Relative offset into auipc + I-type adder (addi/ld/jalr) +//***************************************************************************** +void PutRiscV64AuipcItype(UINT32 * pCode, INT64 offset) +{ + INT32 lo12 = (offset << (64 - 12)) >> (64 - 12); // low 12 bits, sign-extended + INT32 hi20 = INT32(offset - lo12); + _ASSERTE(INT64(hi20) + INT64(lo12) == offset); + + _ASSERTE(GetRiscV64AuipcItype(pCode) == 0); + pCode[0] |= hi20; + pCode[1] |= lo12 << 20; + _ASSERTE(GetRiscV64AuipcItype(pCode) == offset); +} + template static std::string getFromPrinter(TPrint print) { diff --git a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.h b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.h index 9ff49500321217..72e3b2b0f93a50 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.h @@ -97,6 +97,9 @@ bool Is32BitThumb2Instruction(UINT16* p); UINT32 ExtractArm32MovImm(UINT32 instr); void PutArm32MovtConstant(UINT32* p, unsigned con); +INT64 GetRiscV64AuipcItype(UINT32 * pCode); +void PutRiscV64AuipcItype(UINT32 * pCode, INT64 offset); + template inline constexpr unsigned ArrLen(T (&)[size]) { diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index eab692b4d37cab..0a6118d73ab862 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/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.) @@ -1617,17 +1608,6 @@ LPVOID interceptor_ICJI::GetCookieForInterpreterCalliSig(CORINFO_SIG_INFO* szMet return temp; } - -// returns true if a VM cookie can be generated for it (might be false due to cross-module -// inlining, in which case the inlining should be aborted) -bool interceptor_ICJI::canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig) -{ - mc->cr->AddCall("canGetCookieForPInvokeCalliSig"); - bool temp = original_ICorJitInfo->canGetCookieForPInvokeCalliSig(szMetaSig); - mc->recCanGetCookieForPInvokeCalliSig(szMetaSig, temp); - return temp; -} - // Gets a handle that is checked to see if the current method is // included in "JustMyCode" CORINFO_JUST_MY_CODE_HANDLE interceptor_ICJI::getJustMyCodeHandle(CORINFO_METHOD_HANDLE method, @@ -1718,21 +1698,11 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getStaticFieldCurrentClass(CORINFO_FIELD_ } // registers a vararg sig & returns a VM cookie for it (which can contain other stuff) -CORINFO_VARARGS_HANDLE interceptor_ICJI::getVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection) +CORINFO_VARARGS_HANDLE interceptor_ICJI::getVarArgsHandle(CORINFO_SIG_INFO* pSig, CORINFO_METHOD_HANDLE methHnd, void** ppIndirection) { mc->cr->AddCall("getVarArgsHandle"); - CORINFO_VARARGS_HANDLE temp = original_ICorJitInfo->getVarArgsHandle(pSig, ppIndirection); - mc->recGetVarArgsHandle(pSig, ppIndirection, temp); - return temp; -} - -// returns true if a VM cookie can be generated for it (might be false due to cross-module -// inlining, in which case the inlining should be aborted) -bool interceptor_ICJI::canGetVarArgsHandle(CORINFO_SIG_INFO* pSig) -{ - mc->cr->AddCall("canGetVarArgsHandle"); - bool temp = original_ICorJitInfo->canGetVarArgsHandle(pSig); - mc->recCanGetVarArgsHandle(pSig, temp); + CORINFO_VARARGS_HANDLE temp = original_ICorJitInfo->getVarArgsHandle(pSig, methHnd, ppIndirection); + mc->recGetVarArgsHandle(pSig, methHnd, ppIndirection, temp); return temp; } diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp index ffcf2dc749695c..ac148df7c4e295 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/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) { @@ -1157,13 +1149,6 @@ void* interceptor_ICJI::GetCookieForInterpreterCalliSig( return original_ICorJitInfo->GetCookieForInterpreterCalliSig(szMetaSig); } -bool interceptor_ICJI::canGetCookieForPInvokeCalliSig( - CORINFO_SIG_INFO* szMetaSig) -{ - mcs->AddCall("canGetCookieForPInvokeCalliSig"); - return original_ICorJitInfo->canGetCookieForPInvokeCalliSig(szMetaSig); -} - CORINFO_JUST_MY_CODE_HANDLE interceptor_ICJI::getJustMyCodeHandle( CORINFO_METHOD_HANDLE method, CORINFO_JUST_MY_CODE_HANDLE** ppIndirection) @@ -1223,17 +1208,11 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getStaticFieldCurrentClass( CORINFO_VARARGS_HANDLE interceptor_ICJI::getVarArgsHandle( CORINFO_SIG_INFO* pSig, + CORINFO_METHOD_HANDLE methHnd, void** ppIndirection) { mcs->AddCall("getVarArgsHandle"); - return original_ICorJitInfo->getVarArgsHandle(pSig, ppIndirection); -} - -bool interceptor_ICJI::canGetVarArgsHandle( - CORINFO_SIG_INFO* pSig) -{ - mcs->AddCall("canGetVarArgsHandle"); - return original_ICorJitInfo->canGetVarArgsHandle(pSig); + return original_ICorJitInfo->getVarArgsHandle(pSig, methHnd, ppIndirection); } InfoAccessType interceptor_ICJI::constructStringLiteral( diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp index 718959681da80a..1f47ea740c0c48 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/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) { @@ -1014,12 +1007,6 @@ void* interceptor_ICJI::GetCookieForInterpreterCalliSig( return original_ICorJitInfo->GetCookieForInterpreterCalliSig(szMetaSig); } -bool interceptor_ICJI::canGetCookieForPInvokeCalliSig( - CORINFO_SIG_INFO* szMetaSig) -{ - return original_ICorJitInfo->canGetCookieForPInvokeCalliSig(szMetaSig); -} - CORINFO_JUST_MY_CODE_HANDLE interceptor_ICJI::getJustMyCodeHandle( CORINFO_METHOD_HANDLE method, CORINFO_JUST_MY_CODE_HANDLE** ppIndirection) @@ -1073,15 +1060,10 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getStaticFieldCurrentClass( CORINFO_VARARGS_HANDLE interceptor_ICJI::getVarArgsHandle( CORINFO_SIG_INFO* pSig, + CORINFO_METHOD_HANDLE methHnd, void** ppIndirection) { - return original_ICorJitInfo->getVarArgsHandle(pSig, ppIndirection); -} - -bool interceptor_ICJI::canGetVarArgsHandle( - CORINFO_SIG_INFO* pSig) -{ - return original_ICorJitInfo->canGetVarArgsHandle(pSig); + return original_ICorJitInfo->getVarArgsHandle(pSig, methHnd, ppIndirection); } InfoAccessType interceptor_ICJI::constructStringLiteral( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index fafda8ea9fda18..a1b207c3de797e 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/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.) @@ -1385,14 +1378,6 @@ LPVOID MyICJI::GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** p return jitInstance->mc->repGetCookieForPInvokeCalliSig(szMetaSig, ppIndirection); } -// returns true if a VM cookie can be generated for it (might be false due to cross-module -// inlining, in which case the inlining should be aborted) -bool MyICJI::canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig) -{ - jitInstance->mc->cr->AddCall("canGetCookieForPInvokeCalliSig"); - return jitInstance->mc->repCanGetCookieForPInvokeCalliSig(szMetaSig); -} - // Generate a cookie based on the signature to pass to INTOP_CALLI LPVOID MyICJI::GetCookieForInterpreterCalliSig(CORINFO_SIG_INFO* szMetaSig) { @@ -1463,18 +1448,10 @@ CORINFO_CLASS_HANDLE MyICJI::getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE fie } // registers a vararg sig & returns a VM cookie for it (which can contain other stuff) -CORINFO_VARARGS_HANDLE MyICJI::getVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection) +CORINFO_VARARGS_HANDLE MyICJI::getVarArgsHandle(CORINFO_SIG_INFO* pSig, CORINFO_METHOD_HANDLE methHnd, void** ppIndirection) { jitInstance->mc->cr->AddCall("getVarArgsHandle"); - return jitInstance->mc->repGetVarArgsHandle(pSig, ppIndirection); -} - -// returns true if a VM cookie can be generated for it (might be false due to cross-module -// inlining, in which case the inlining should be aborted) -bool MyICJI::canGetVarArgsHandle(CORINFO_SIG_INFO* pSig) -{ - jitInstance->mc->cr->AddCall("canGetVarArgsHandle"); - return jitInstance->mc->repCanGetVarArgsHandle(pSig); + return jitInstance->mc->repGetVarArgsHandle(pSig, methHnd, ppIndirection); } // Allocate a string literal on the heap and return a handle to it diff --git a/src/coreclr/tools/superpmi/superpmi/neardiffer.cpp b/src/coreclr/tools/superpmi/superpmi/neardiffer.cpp index 5589e08133de92..ecacc20861323f 100644 --- a/src/coreclr/tools/superpmi/superpmi/neardiffer.cpp +++ b/src/coreclr/tools/superpmi/superpmi/neardiffer.cpp @@ -416,7 +416,7 @@ bool NearDiffer::mungeOffsets( // We might want to do something similar for mov/movk/movk/movk sequences on Arm64. The following code was // previously used, but currently is not active. // - // One difference is we might see a different number of movk on arm64 depending on the the data. Our "hack" + // One difference is we might see a different number of movk on arm64 depending on the data. Our "hack" // of zeroing out the constant so they compare equal doesn't work well. In this case, we really do want // a callback to the disassembler to skip the instructions. // diff --git a/src/coreclr/unwinder/CMakeLists.txt b/src/coreclr/unwinder/CMakeLists.txt index 01c7bca64a7888..1c82808f0366a4 100644 --- a/src/coreclr/unwinder/CMakeLists.txt +++ b/src/coreclr/unwinder/CMakeLists.txt @@ -1,18 +1,19 @@ -# helper to add set of include directories to unwinder targets -macro(add_unwinder_include_directories TARGET) - target_include_directories(${TARGET} BEFORE PRIVATE ${VM_DIR}) - target_include_directories(${TARGET} BEFORE PRIVATE ${VM_DIR}/${ARCH_SOURCES_DIR}) - target_include_directories(${TARGET} BEFORE PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) - target_include_directories(${TARGET} BEFORE PRIVATE ${CLR_DIR}/unwinder) - target_include_directories(${TARGET} PRIVATE ${CLR_DIR}/debug/ee) - target_include_directories(${TARGET} PRIVATE ${CLR_DIR}/gc) - target_include_directories(${TARGET} PRIVATE ${CLR_DIR}/gcdump) - target_include_directories(${TARGET} PRIVATE ${CLR_DIR}/debug/daccess) - target_include_directories(${TARGET} PRIVATE ${ARCH_SOURCES_DIR}) -endmacro() +include_directories(BEFORE ${VM_DIR}) +include_directories(BEFORE ${VM_DIR}/${ARCH_SOURCES_DIR}) +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(BEFORE ${CLR_DIR}/unwinder) +include_directories(${CLR_DIR}/debug/ee) +include_directories(${CLR_DIR}/gc) +include_directories(${CLR_DIR}/gcdump) +include_directories(${CLR_DIR}/debug/daccess) set(UNWINDER_SOURCES baseunwinder.cpp +) + +# Include platform specific unwinder for applicable (native and cross-target) builds. +include_directories(${ARCH_SOURCES_DIR}) +list(APPEND UNWINDER_SOURCES ${ARCH_SOURCES_DIR}/unwinder.cpp ) @@ -20,102 +21,10 @@ convert_to_absolute_path(UNWINDER_SOURCES ${UNWINDER_SOURCES}) if(CLR_CMAKE_HOST_UNIX) add_library_clr(unwinder_wks OBJECT ${UNWINDER_SOURCES}) - add_unwinder_include_directories(unwinder_wks) add_dependencies(unwinder_wks eventing_headers) endif(CLR_CMAKE_HOST_UNIX) add_library_clr(unwinder_dac ${UNWINDER_SOURCES}) -add_unwinder_include_directories(unwinder_dac) add_dependencies(unwinder_dac eventing_headers) set_target_properties(unwinder_dac PROPERTIES DAC_COMPONENT TRUE) target_compile_definitions(unwinder_dac PRIVATE FEATURE_NO_HOST) - -### cDAC Unwinders #### - -set(BASE_UNWINDER_SOURCES baseunwinder.cpp) -convert_to_absolute_path(BASE_UNWINDER_SOURCES ${BASE_UNWINDER_SOURCES}) -add_library_clr(unwinder_cdac_base STATIC ${BASE_UNWINDER_SOURCES}) - -target_include_directories(unwinder_cdac_base BEFORE PUBLIC ${VM_DIR}) -target_include_directories(unwinder_cdac_base BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_include_directories(unwinder_cdac_base BEFORE PUBLIC ${CLR_DIR}/unwinder) -target_include_directories(unwinder_cdac_base PUBLIC ${CLR_DIR}/debug/ee) -target_include_directories(unwinder_cdac_base PUBLIC ${CLR_DIR}/gc) -target_include_directories(unwinder_cdac_base PUBLIC ${CLR_DIR}/gcdump) -target_include_directories(unwinder_cdac_base PUBLIC ${CLR_DIR}/debug/daccess) -target_compile_definitions(unwinder_cdac_base PUBLIC FEATURE_NO_HOST FEATURE_CDAC_UNWINDER) - -if (CLR_CMAKE_TARGET_WIN32) - # cDAC unwinders are statically linked into the NativeAOT runtime which is built with - # release version of the statically linked CRT. Therefore we do the same here. - set_property(TARGET unwinder_cdac_base PROPERTY MSVC_RUNTIME_LIBRARY MultiThreaded) - - # _DEBUG is always passed as a parameter if the build is a debug build. - # This causes the debug CRT on MSVC to be used so we need to undefine it. - target_compile_options(unwinder_cdac_base PRIVATE -U_DEBUG) -endif() - -install_clr(TARGETS unwinder_cdac_base DESTINATIONS cdaclibs COMPONENT cdac) - -# Helper function for platform specific cDAC uwninder builds. -function(create_platform_unwinder) - set(oneValueArgs TARGET ARCH) - set(multiValueArgs DESTINATIONS) - cmake_parse_arguments(TARGETDETAILS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(TARGETDETAILS_ARCH STREQUAL "x64") - set(ARCH_SOURCES_DIR amd64) - elseif((TARGETDETAILS_ARCH STREQUAL "arm") OR (TARGETDETAILS_ARCH STREQUAL "armel")) - set(ARCH_SOURCES_DIR arm) - elseif(TARGETDETAILS_ARCH STREQUAL "x86") - set(ARCH_SOURCES_DIR i386) - elseif(TARGETDETAILS_ARCH STREQUAL "arm64") - set(ARCH_SOURCES_DIR arm64) - else() - clr_unknown_arch() - endif() - - set(UNWINDER_SOURCES ${ARCH_SOURCES_DIR}/unwinder.cpp) - convert_to_absolute_path(UNWINDER_SOURCES ${UNWINDER_SOURCES}) - add_library_clr(${TARGETDETAILS_TARGET} STATIC ${UNWINDER_SOURCES}) - - target_include_directories(${TARGETDETAILS_TARGET} BEFORE PRIVATE ${VM_DIR}/${ARCH_SOURCES_DIR}) - target_include_directories(${TARGETDETAILS_TARGET} PRIVATE ${ARCH_SOURCES_DIR}) - - target_link_libraries(${TARGETDETAILS_TARGET} PRIVATE unwinder_cdac_base) - if (CLR_CMAKE_TARGET_WIN32) - # cDAC unwinders are statically linked into the NativeAOT runtime which is built with - # release version of the statically linked CRT. Therefore we do the same here. - set_property(TARGET ${TARGETDETAILS_TARGET} PROPERTY MSVC_RUNTIME_LIBRARY MultiThreaded) - - # _DEBUG is always passed as a parameter if the build is a debug build. - # This causes the debug CRT on MSVC to be used so we need to undefine it. - target_compile_options(${TARGETDETAILS_TARGET} PRIVATE -U_DEBUG) - endif() - - # add the install targets - install_clr(TARGETS ${TARGETDETAILS_TARGET} DESTINATIONS ${TARGETDETAILS_DESTINATIONS} COMPONENT cdac) - - # Set the target to be built for the specified OS and ARCH - set_target_definitions_to_custom_os_and_arch(TARGET ${TARGETDETAILS_TARGET} OS win ARCH ${TARGETDETAILS_ARCH}) - - target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE FEATURE_NO_HOST FEATURE_CDAC_UNWINDER) -endfunction() - -if(CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_AMD64) - create_platform_unwinder(TARGET unwinder_cdac_amd64 ARCH x64 DESTINATIONS cdaclibs) - create_platform_unwinder(TARGET unwinder_cdac_arm64 ARCH arm64 DESTINATIONS cdaclibs) -endif(CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_AMD64) - -if(CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_ARM64) - create_platform_unwinder(TARGET unwinder_cdac_arm64 ARCH arm64 DESTINATIONS cdaclibs) -endif(CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_ARM64) - -if(NOT CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_AMD64) - create_platform_unwinder(TARGET unwinder_cdac_amd64 ARCH x64 DESTINATIONS cdaclibs) -endif(NOT CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_AMD64) - -if(NOT CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_ARM64) - create_platform_unwinder(TARGET unwinder_cdac_arm64 ARCH arm64 DESTINATIONS cdaclibs) -endif(NOT CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_ARM64) - diff --git a/src/coreclr/unwinder/amd64/unwinder.cpp b/src/coreclr/unwinder/amd64/unwinder.cpp index 57acbd30ab06e8..7fadcefd758aa7 100644 --- a/src/coreclr/unwinder/amd64/unwinder.cpp +++ b/src/coreclr/unwinder/amd64/unwinder.cpp @@ -8,7 +8,6 @@ typedef DPTR(M128A) PTR_M128A; -#ifndef FEATURE_CDAC_UNWINDER //--------------------------------------------------------------------------------------- // // Read 64 bit unsigned value from the specified address. When the unwinder is built @@ -52,29 +51,9 @@ static M128A MemoryRead128(PM128A addr) { return *dac_cast((TADDR)addr); } -#else -// Read 64 bit unsigned value from the specified addres when the unwinder is build -// for the cDAC. This triggers a callback to the cDAC host to read the memory from -// the target process. -static ULONG64 MemoryRead64(PULONG64 addr) -{ - ULONG64 value; - t_pCallbacks->readFromTarget((uint64_t)addr, &value, sizeof(value), t_pCallbacks->callbackContext); - return value; -} -// Read 128 bit value from the specified addres when the unwinder is build -// for the cDAC. This triggers a callback to the cDAC host to read the memory from -// the target process. -static M128A MemoryRead128(PM128A addr) -{ - M128A value; - t_pCallbacks->readFromTarget((uint64_t)addr, &value, sizeof(value), t_pCallbacks->callbackContext); - return value; -} -#endif // FEATURE_CDAC_UNWINDER +#ifdef DACCESS_COMPILE -#if defined(DACCESS_COMPILE) || defined(FEATURE_CDAC_UNWINDER) //--------------------------------------------------------------------------------------- // // The InstructionBuffer class abstracts accessing assembler instructions in the function @@ -89,19 +68,6 @@ class InstructionBuffer UCHAR m_buffer[32]; // Load the instructions from the target process being debugged -#ifdef FEATURE_CDAC_UNWINDER - HRESULT Load() - { - HRESULT hr = t_pCallbacks->readFromTarget(m_address, m_buffer, sizeof(m_buffer), t_pCallbacks->callbackContext); - if (SUCCEEDED(hr)) - { - // TODO: Implement breakpoint patching for cDAC - // https://github.com/dotnet/runtime/issues/112273#issue-2838620747 - } - - return hr; - } -#else // FEATURE_CDAC_UNWINDER HRESULT Load() { HRESULT hr = DacReadAll(TO_TADDR(m_address), m_buffer, sizeof(m_buffer), false); @@ -116,7 +82,6 @@ class InstructionBuffer return hr; } -#endif // FEATURE_CDAC_UNWINDER public: @@ -161,7 +126,7 @@ class InstructionBuffer } // Get the byte at the given index from the current position - // Assert that the index is within the buffer + // Invoke DacError if the index is out of the buffer UCHAR operator[](int index) { int realIndex = m_offset + index; @@ -169,9 +134,7 @@ class InstructionBuffer return m_buffer[realIndex]; } }; -#endif // DACCESS_COMPILE || FEATURE_CDAC_UNWINDER -#ifdef DACCESS_COMPILE //--------------------------------------------------------------------------------------- // // Given the target address of an UNWIND_INFO structure, this function retrieves all the memory used for @@ -251,57 +214,47 @@ BOOL DacUnwindStackFrame(CONTEXT * pContext, KNONVOLATILE_CONTEXT_POINTERS* pCon return res; } -#elif defined(FEATURE_CDAC_UNWINDER) - -BOOL amd64Unwind(void* pContext, ReadFromTarget readFromTarget, GetAllocatedBuffer getAllocatedBuffer, GetStackWalkInfo getStackWalkInfo, UnwinderFail unwinderFail, void* callbackContext) -{ - CDACCallbacks callbacks { readFromTarget, getAllocatedBuffer, getStackWalkInfo, unwinderFail, callbackContext }; - t_pCallbacks = &callbacks; - BOOL res = OOPStackUnwinderAMD64::Unwind((CONTEXT*) pContext); - t_pCallbacks = nullptr; - - return res; -} +//--------------------------------------------------------------------------------------- +// +// Unwind the given CONTEXT to the caller CONTEXT. The given CONTEXT will be overwritten. +// +// Arguments: +// pContext - in-out parameter storing the specified CONTEXT on entry and the unwound CONTEXT on exit +// +// Return Value: +// TRUE if the unwinding is successful +// -UNWIND_INFO * OOPStackUnwinderAMD64::GetUnwindInfo(TADDR taUnwindInfo) +BOOL OOPStackUnwinderAMD64::Unwind(CONTEXT * pContext) { - UNWIND_INFO unwindInfo; - if(t_pCallbacks->readFromTarget((uint64_t)taUnwindInfo, &unwindInfo, sizeof(unwindInfo), t_pCallbacks->callbackContext) != S_OK) - { - return NULL; - } + HRESULT hr = E_FAIL; - DWORD cbUnwindInfo = offsetof(UNWIND_INFO, UnwindCode) + - unwindInfo.CountOfUnwindCodes * sizeof(UNWIND_CODE); + ULONG64 uControlPC = (DWORD64)dac_cast(::GetIP(pContext)); - // Check if there is a chained unwind info. If so, it has an extra RUNTIME_FUNCTION tagged to the end. - if ((unwindInfo.Flags & UNW_FLAG_CHAININFO) != 0) + // get the module base + ULONG64 uImageBase; + hr = GetModuleBase(uControlPC, &uImageBase); + if (FAILED(hr)) { - // If there is an odd number of UNWIND_CODE, we need to adjust for alignment. - if ((unwindInfo.CountOfUnwindCodes & 1) != 0) - { - cbUnwindInfo += sizeof(UNWIND_CODE); - } - cbUnwindInfo += sizeof(T_RUNTIME_FUNCTION); + return FALSE; } - // Allocate a buffer for the unwind info from cDAC callback. - // This buffer will be freed by the cDAC host once unwinding is done. - UNWIND_INFO* pUnwindInfo; - if(t_pCallbacks->getAllocatedBuffer(cbUnwindInfo, (void**)&pUnwindInfo, t_pCallbacks->callbackContext) != S_OK) + // get the function entry + IMAGE_RUNTIME_FUNCTION_ENTRY functionEntry; + hr = GetFunctionEntry(uControlPC, &functionEntry, sizeof(functionEntry)); + if (FAILED(hr)) { - return NULL; + return FALSE; } - if(t_pCallbacks->readFromTarget(taUnwindInfo, pUnwindInfo, cbUnwindInfo, t_pCallbacks->callbackContext) != S_OK) - { - return NULL; - } + // call VirtualUnwind() to do the real work + ULONG64 EstablisherFrame; + hr = VirtualUnwind(0, uImageBase, uControlPC, &functionEntry, pContext, NULL, &EstablisherFrame, NULL, NULL); - return pUnwindInfo; + return (hr == S_OK); } -#else // !DACCESS_COMPILE && !FEATURE_CDAC_UNWINDER +#else // DACCESS_COMPILE // For unwinding of the jitted code on non-Windows platforms, the Instruction buffer is // just a plain pointer to the instruction data. @@ -385,57 +338,13 @@ PEXCEPTION_ROUTINE RtlVirtualUnwind_Unsafe( ContextPointers, &handlerRoutine); - UNWINDER_ASSERT(SUCCEEDED(res)); + _ASSERTE(SUCCEEDED(res)); return handlerRoutine; } -#endif // !DACCESS_COMPILE && !FEATURE_CDAC_UNWINDER - -//--------------------------------------------------------------------------------------- -// -// Unwind the given CONTEXT to the caller CONTEXT. The given CONTEXT will be overwritten. -// -// Arguments: -// pContext - in-out parameter storing the specified CONTEXT on entry and the unwound CONTEXT on exit -// -// Return Value: -// TRUE if the unwinding is successful -// - -BOOL OOPStackUnwinderAMD64::Unwind(CONTEXT * pContext) -{ - HRESULT hr = E_FAIL; - - ULONG64 uControlPC = -#ifndef FEATURE_CDAC_UNWINDER - (DWORD64)dac_cast(::GetIP(pContext)); -#else // FEATURE_CDAC_UNWINDER - pContext->Rip; -#endif // FEATURE_CDAC_UNWINDER - // get the module base - ULONG64 uImageBase; - hr = GetModuleBase(uControlPC, &uImageBase); - if (FAILED(hr)) - { - return FALSE; - } - - // get the function entry - IMAGE_RUNTIME_FUNCTION_ENTRY functionEntry; - hr = GetFunctionEntry(uControlPC, &functionEntry, sizeof(functionEntry)); - if (FAILED(hr)) - { - return FALSE; - } - - // call VirtualUnwind() to do the real work - ULONG64 EstablisherFrame; - hr = VirtualUnwind(0, uImageBase, uControlPC, &functionEntry, pContext, NULL, &EstablisherFrame, NULL, NULL); - - return (hr == S_OK); -} +#endif // DACCESS_COMPILE // // @@ -1936,4 +1845,3 @@ Return Value: return Slots; } - diff --git a/src/coreclr/unwinder/amd64/unwinder.h b/src/coreclr/unwinder/amd64/unwinder.h index 1e990168921402..1c714224f32eb5 100644 --- a/src/coreclr/unwinder/amd64/unwinder.h +++ b/src/coreclr/unwinder/amd64/unwinder.h @@ -8,14 +8,6 @@ #include "baseunwinder.h" -#ifdef FEATURE_CDAC_UNWINDER -EXTERN_C BOOL amd64Unwind(void* pContext, - ReadFromTarget readFromTarget, - GetAllocatedBuffer getAllocatedBuffer, - GetStackWalkInfo getStackWalkInfo, - UnwinderFail unwinderFail, - void* callbackContext); -#endif // FEATURE_CDAC_UNWINDER //--------------------------------------------------------------------------------------- // diff --git a/src/coreclr/unwinder/arm64/unwinder.cpp b/src/coreclr/unwinder/arm64/unwinder.cpp index ed4238c98a6bf6..f76a97c67f88ec 100644 --- a/src/coreclr/unwinder/arm64/unwinder.cpp +++ b/src/coreclr/unwinder/arm64/unwinder.cpp @@ -4,9 +4,7 @@ // #include "stdafx.h" -#ifndef FEATURE_CDAC_UNWINDER #include "utilcode.h" -#endif // FEATURE_CDAC_UNWINDER #include "crosscomp.h" #include "unwinder.h" @@ -166,25 +164,13 @@ typedef struct _ARM64_VFP_STATE // Macros for accessing memory. These can be overridden if other code // (in particular the debugger) needs to use them. -#if !defined(DEBUGGER_UNWIND) && !defined(FEATURE_CDAC_UNWINDER) +#if !defined(DEBUGGER_UNWIND) #define MEMORY_READ_BYTE(params, addr) (*dac_cast(addr)) -#define MEMORY_READ_WORD(params, addr) (*dac_cast(addr)) +#define MEMORY_READ_WORD(params, addr) (*dac_cast(addr)) #define MEMORY_READ_DWORD(params, addr) (*dac_cast(addr)) #define MEMORY_READ_QWORD(params, addr) (*dac_cast(addr)) -#elif defined(FEATURE_CDAC_UNWINDER) -template -T cdacRead(uint64_t addr) -{ - T t; - t_pCallbacks->readFromTarget(addr, &t, sizeof(t), t_pCallbacks->callbackContext); - return t; -} -#define MEMORY_READ_BYTE(params, addr) (cdacRead(addr)) -#define MEMORY_READ_WORD(params, addr) (cdacRead(addr)) -#define MEMORY_READ_DWORD(params, addr) (cdacRead(addr)) -#define MEMORY_READ_QWORD(params, addr) (cdacRead(addr)) #endif // @@ -1702,7 +1688,7 @@ Routine Description: returned. HandlerData - Supplies a pointer to a variable that receives a pointer - the the language handler data. + the language handler data. UnwindParams - Additional parameters shared with caller. @@ -2349,7 +2335,7 @@ Return Value: } // - // pac (11111100): function has pointer authentication + // pac (11111100): function has pointer authentication // else if (CurCode == 0xfc) { @@ -2550,7 +2536,7 @@ Routine Description: ContextRecord - Supplies the address of a context record. HandlerData - Supplies a pointer to a variable that receives a pointer - the the language handler data. + the language handler data. EstablisherFrame - Supplies a pointer to a variable that receives the the establisher frame pointer value. @@ -2773,7 +2759,6 @@ BOOL OOPStackUnwinderArm64::Unwind(T_CONTEXT * pContext) return TRUE; } -#ifdef DACCESS_COMPILE BOOL DacUnwindStackFrame(T_CONTEXT *pContext, T_KNONVOLATILE_CONTEXT_POINTERS* pContextPointers) { OOPStackUnwinderArm64 unwinder; @@ -2789,18 +2774,6 @@ BOOL DacUnwindStackFrame(T_CONTEXT *pContext, T_KNONVOLATILE_CONTEXT_POINTERS* p return res; } -#elif defined(FEATURE_CDAC_UNWINDER) -BOOL arm64Unwind(void* pContext, ReadFromTarget readFromTarget, GetAllocatedBuffer getAllocatedBuffer, GetStackWalkInfo getStackWalkInfo, UnwinderFail unwinderFail, void* callbackContext) -{ - CDACCallbacks callbacks { readFromTarget, getAllocatedBuffer, getStackWalkInfo, unwinderFail, callbackContext }; - t_pCallbacks = &callbacks; - OOPStackUnwinderArm64 unwinder; - BOOL res = unwinder.Unwind((T_CONTEXT*) pContext); - t_pCallbacks = nullptr; - - return res; -} -#endif // FEATURE_CDAC_UNWINDER #if defined(HOST_UNIX) diff --git a/src/coreclr/unwinder/arm64/unwinder.h b/src/coreclr/unwinder/arm64/unwinder.h index d85fdf6a09acc6..aa03c5a59fe9f1 100644 --- a/src/coreclr/unwinder/arm64/unwinder.h +++ b/src/coreclr/unwinder/arm64/unwinder.h @@ -8,13 +8,6 @@ #include "baseunwinder.h" -#ifdef FEATURE_CDAC_UNWINDER -EXTERN_C BOOL arm64Unwind(void* pContext, ReadFromTarget readFromTarget, - GetAllocatedBuffer getAllocatedBuffer, - GetStackWalkInfo getStackWalkInfo, - UnwinderFail unwinderFail, - void* callbackContext); -#endif // FEATURE_CDAC_UNWINDER //--------------------------------------------------------------------------------------- // diff --git a/src/coreclr/unwinder/baseunwinder.cpp b/src/coreclr/unwinder/baseunwinder.cpp index 2f2fecc7834045..b00c2aa114835e 100644 --- a/src/coreclr/unwinder/baseunwinder.cpp +++ b/src/coreclr/unwinder/baseunwinder.cpp @@ -6,15 +6,9 @@ #include "stdafx.h" #include "baseunwinder.h" -#ifndef FEATURE_CDAC_UNWINDER EXTERN_C void GetRuntimeStackWalkInfo(IN ULONG64 ControlPc, OUT UINT_PTR* pModuleBase, OUT UINT_PTR* pFuncEntry); -#endif // FEATURE_CDAC_UNWINDER - -#ifdef FEATURE_CDAC_UNWINDER -thread_local CDACCallbacks* t_pCallbacks; -#endif // FEATURE_CDAC_UNWINDER //--------------------------------------------------------------------------------------- // @@ -33,11 +27,7 @@ thread_local CDACCallbacks* t_pCallbacks; HRESULT OOPStackUnwinder::GetModuleBase( DWORD64 address, _Out_ PDWORD64 pdwBase) { -#ifndef FEATURE_CDAC_UNWINDER GetRuntimeStackWalkInfo(address, reinterpret_cast(pdwBase), NULL); -#else // FEATURE_CDAC_UNWINDER - t_pCallbacks->getStackWalkInfo(address, reinterpret_cast(pdwBase), NULL, t_pCallbacks->callbackContext); -#endif // FEATURE_CDAC_UNWINDER return ((*pdwBase == 0) ? E_FAIL : S_OK); } @@ -60,15 +50,12 @@ HRESULT OOPStackUnwinder::GetFunctionEntry( DWORD64 addres _Out_writes_(cbBuffer) PVOID pBuffer, DWORD cbBuffer) { -#ifndef FEATURE_CDAC_UNWINDER if (cbBuffer < sizeof(T_RUNTIME_FUNCTION)) { return E_INVALIDARG; } -#endif // FEATURE_CDAC_UNWINDER PVOID pFuncEntry = NULL; -#ifndef FEATURE_CDAC_UNWINDER GetRuntimeStackWalkInfo(address, NULL, reinterpret_cast(&pFuncEntry)); if (pFuncEntry == NULL) { @@ -77,17 +64,4 @@ HRESULT OOPStackUnwinder::GetFunctionEntry( DWORD64 addres memcpy(pBuffer, pFuncEntry, cbBuffer); return S_OK; -#else // FEATURE_CDAC_UNWINDER - t_pCallbacks->getStackWalkInfo(address, NULL, reinterpret_cast(&pFuncEntry), t_pCallbacks->callbackContext); - if (pFuncEntry == NULL) - { - return E_FAIL; - } - if (t_pCallbacks->readFromTarget((DWORD64)pFuncEntry, pBuffer, cbBuffer, t_pCallbacks->callbackContext) != S_OK) - { - return E_FAIL; - } - - return S_OK; -#endif } diff --git a/src/coreclr/unwinder/baseunwinder.h b/src/coreclr/unwinder/baseunwinder.h index f620bae944744b..d2ed5ac34ddda5 100644 --- a/src/coreclr/unwinder/baseunwinder.h +++ b/src/coreclr/unwinder/baseunwinder.h @@ -6,46 +6,12 @@ #ifndef __unwinder_h__ #define __unwinder_h__ -#ifdef FEATURE_CDAC_UNWINDER -using ReadFromTarget = LONG (*)(ULONG64 addr, PVOID pBuffer, LONG bufferSize, PVOID callbackContext); -using GetAllocatedBuffer = LONG (*)(LONG bufferSize, PVOID* ppBuffer, PVOID callbackContext); -using GetStackWalkInfo = VOID (*)(ULONG64 controlPC, UINT_PTR* pUnwindInfoBase, UINT_PTR* pFuncEntry, PVOID callbackContext); -using UnwinderFail = VOID (*)(); - -class CDACCallbacks -{ -public: - CDACCallbacks(ReadFromTarget readFromTarget, - GetAllocatedBuffer getAllocatedBuffer, - GetStackWalkInfo getStackWalkInfo, - UnwinderFail unwinderFail, - void* callbackContext) - : readFromTarget(readFromTarget), - getAllocatedBuffer(getAllocatedBuffer), - getStackWalkInfo(getStackWalkInfo), - unwinderFail(unwinderFail), - callbackContext(callbackContext) - { } - - ReadFromTarget readFromTarget; - GetAllocatedBuffer getAllocatedBuffer; - GetStackWalkInfo getStackWalkInfo; - UnwinderFail unwinderFail; - void* callbackContext; -}; - -// thread_local used to access cDAC callbacks outside of unwinder. -extern thread_local CDACCallbacks* t_pCallbacks; -#endif // FEATURE_CDAC_UNWINDER - // Report failure in the unwinder if the condition is FALSE -#if defined(FEATURE_CDAC_UNWINDER) -#define UNWINDER_ASSERT(Condition) if (!(Condition)) t_pCallbacks->unwinderFail() -#elif defined(DACCESS_COMPILE) +#ifdef DACCESS_COMPILE #define UNWINDER_ASSERT(Condition) if (!(Condition)) DacError(CORDBG_E_TARGET_INCONSISTENT) -#else // !DACCESS_COMPILE AND !FEATURE_CDAC_UNWINDER +#else // !DACCESS_COMPILE #define UNWINDER_ASSERT _ASSERTE -#endif +#endif // DACCESS_COMPILE //--------------------------------------------------------------------------------------- // diff --git a/src/coreclr/unwinder/stdafx.h b/src/coreclr/unwinder/stdafx.h index e0dc4fe44b3813..8decdc68562bd4 100644 --- a/src/coreclr/unwinder/stdafx.h +++ b/src/coreclr/unwinder/stdafx.h @@ -10,17 +10,10 @@ #define USE_COM_CONTEXT_DEF -#ifndef FEATURE_CDAC_UNWINDER #include + #include #include -#else // FEATURE_CDAC_UNWINDER -#include -#include -#include -#include -#endif // FEATURE_CDAC_UNWINDER - #ifdef DACCESS_COMPILE #include #include diff --git a/src/coreclr/utilcode/CMakeLists.txt b/src/coreclr/utilcode/CMakeLists.txt index 0f50b610d6552e..fd7b7d04399709 100644 --- a/src/coreclr/utilcode/CMakeLists.txt +++ b/src/coreclr/utilcode/CMakeLists.txt @@ -30,7 +30,6 @@ set(UTILCODE_COMMON_SOURCES interleavedloaderheap.cpp loaderheap_shared.cpp explicitcontrolloaderheap.cpp - allocmemtracker.cpp rangelist.cpp outstring.cpp ilformatter.cpp @@ -69,6 +68,7 @@ endif(CLR_CMAKE_TARGET_WIN32) set(UTILCODE_SOURCES ${UTILCODE_COMMON_SOURCES} + allocmemtracker.cpp executableallocator.cpp ) diff --git a/src/coreclr/utilcode/allocmemtracker.cpp b/src/coreclr/utilcode/allocmemtracker.cpp index 2ce0f3c2e021d1..522d6f92ebc65b 100644 --- a/src/coreclr/utilcode/allocmemtracker.cpp +++ b/src/coreclr/utilcode/allocmemtracker.cpp @@ -8,8 +8,6 @@ #define DONOT_DEFINE_ETW_CALLBACK #include "eventtracebase.h" -#ifndef DACCESS_COMPILE - AllocMemTracker::AllocMemTracker() { CONTRACTL @@ -169,5 +167,3 @@ void AllocMemTracker::SuppressRelease() m_fReleased = TRUE; } - -#endif //#ifndef DACCESS_COMPILE diff --git a/src/coreclr/utilcode/clrhost.cpp b/src/coreclr/utilcode/clrhost.cpp index a57b115fbfc780..2c6915c3fdfad5 100644 --- a/src/coreclr/utilcode/clrhost.cpp +++ b/src/coreclr/utilcode/clrhost.cpp @@ -62,7 +62,13 @@ DWORD GetClrModulePathName(SString& buffer) #ifdef HOST_WINDOWS return WszGetModuleFileName((HINSTANCE)GetClrModuleBase(), buffer); #else - return WszGetModuleFileName(PAL_GetPalHostModule(), buffer); +#ifndef HOST_WASM + HMODULE hModule = PAL_GetPalHostModule(); +#else + // on wasm the PAL library is statically linked + HMODULE hModule = nullptr; +#endif + return WszGetModuleFileName(hModule, buffer); #endif } diff --git a/src/coreclr/utilcode/executableallocator.cpp b/src/coreclr/utilcode/executableallocator.cpp index 0242377072238c..565ecfaba617b9 100644 --- a/src/coreclr/utilcode/executableallocator.cpp +++ b/src/coreclr/utilcode/executableallocator.cpp @@ -124,7 +124,7 @@ bool ExecutableAllocator::IsDoubleMappingEnabled() { LIMITED_METHOD_CONTRACT; -#if defined(HOST_APPLE) && defined(HOST_ARM64) +#if defined(HOST_APPLE) && defined(HOST_ARM64) || defined(HOST_WASM) return false; #else return g_isWXorXEnabled; @@ -978,7 +978,7 @@ void ExecutableAllocator::UnmapRW(void* pRW) } } -void* ExecutableAllocator::AllocateThunksFromTemplate(void *pTemplate, size_t templateSize) +void* ExecutableAllocator::AllocateThunksFromTemplate(void *pTemplate, size_t templateSize, void (*dataPageGenerator)(uint8_t* pageBase, size_t size)) { if (IsDoubleMappingEnabled() && VMToOSInterface::AllocateThunksFromTemplateRespectsStartAddress()) { @@ -1003,7 +1003,7 @@ void* ExecutableAllocator::AllocateThunksFromTemplate(void *pTemplate, size_t te BackoutBlock(block, isFreeBlock); } - void *pTemplateAddressAllocated = VMToOSInterface::AllocateThunksFromTemplate(pTemplate, templateSize, block->baseRX); + void *pTemplateAddressAllocated = VMToOSInterface::AllocateThunksFromTemplate(pTemplate, templateSize, block->baseRX, dataPageGenerator); if (pTemplateAddressAllocated == NULL) { @@ -1014,7 +1014,7 @@ void* ExecutableAllocator::AllocateThunksFromTemplate(void *pTemplate, size_t te } else { - return VMToOSInterface::AllocateThunksFromTemplate(pTemplate, templateSize, NULL); + return VMToOSInterface::AllocateThunksFromTemplate(pTemplate, templateSize, NULL, dataPageGenerator); } } diff --git a/src/coreclr/utilcode/explicitcontrolloaderheap.cpp b/src/coreclr/utilcode/explicitcontrolloaderheap.cpp index a6adb7da2c37fe..06a5e76d14cf2d 100644 --- a/src/coreclr/utilcode/explicitcontrolloaderheap.cpp +++ b/src/coreclr/utilcode/explicitcontrolloaderheap.cpp @@ -72,7 +72,6 @@ ExplicitControlLoaderHeap::ExplicitControlLoaderHeap(bool fMakeExecutable) : #endif } -// ~LoaderHeap is not synchronised (obviously) ExplicitControlLoaderHeap::~ExplicitControlLoaderHeap() { CONTRACTL diff --git a/src/coreclr/utilcode/interleavedloaderheap.cpp b/src/coreclr/utilcode/interleavedloaderheap.cpp index 082e337caebda1..8ce0a91e2f032c 100644 --- a/src/coreclr/utilcode/interleavedloaderheap.cpp +++ b/src/coreclr/utilcode/interleavedloaderheap.cpp @@ -52,7 +52,6 @@ UnlockedInterleavedLoaderHeap::UnlockedInterleavedLoaderHeap( _ASSERTE((GetStubCodePageSize() % GetOsPageSize()) == 0); // Stub code page size MUST be in increments of the page size. (Really it must be a power of 2 as well, but this is good enough) } -// ~LoaderHeap is not synchronised (obviously) UnlockedInterleavedLoaderHeap::~UnlockedInterleavedLoaderHeap() { CONTRACTL @@ -104,25 +103,32 @@ size_t UnlockedInterleavedLoaderHeap::GetBytesAvailReservedRegion() BOOL UnlockedInterleavedLoaderHeap::CommitPages(void* pData, size_t dwSizeToCommitPart) { _ASSERTE(m_pConfig->Template == NULL); // This path should only be used for LoaderHeaps which use the standard ExecutableAllocator functions - // Commit first set of pages, since it will contain the LoaderHeapBlock + { - void *pTemp = ExecutableAllocator::Instance()->Commit(pData, dwSizeToCommitPart, IsExecutable()); + void *pTemp = ExecutableAllocator::Instance()->Commit((BYTE*)pData + dwSizeToCommitPart, dwSizeToCommitPart, FALSE); if (pTemp == NULL) { return FALSE; } + // Fill in data pages with the initial state, do this before we map the executable pages in, so that + // the executable pages cannot speculate into the data page at any time before they are initialized. + if (m_pConfig->DataPageGenerator != NULL) + { + m_pConfig->DataPageGenerator((uint8_t*)pTemp, dwSizeToCommitPart); + } } - _ASSERTE(dwSizeToCommitPart == GetStubCodePageSize()); - + // Commit first set of pages, since it will contain the LoaderHeapBlock { - void *pTemp = ExecutableAllocator::Instance()->Commit((BYTE*)pData + dwSizeToCommitPart, dwSizeToCommitPart, FALSE); + void *pTemp = ExecutableAllocator::Instance()->Commit(pData, dwSizeToCommitPart, IsExecutable()); if (pTemp == NULL) { return FALSE; } } + _ASSERTE(dwSizeToCommitPart == GetStubCodePageSize()); + ExecutableWriterHolder codePageWriterHolder((BYTE*)pData, dwSizeToCommitPart, ExecutableAllocator::DoNotAddToCache); m_pConfig->CodePageGenerator(codePageWriterHolder.GetRW(), (BYTE*)pData, dwSizeToCommitPart); FlushInstructionCache(GetCurrentProcess(), pData, dwSizeToCommitPart); @@ -179,7 +185,7 @@ BOOL UnlockedInterleavedLoaderHeap::UnlockedReservePages(size_t dwSizeToCommit) size_t dwSizeToCommitPart = dwSizeToCommit; - // For interleaved heaps, we perform two commits, each being half of the requested size + // We perform two commits, each being half of the requested size dwSizeToCommitPart /= 2; if (!CommitPages(pData, dwSizeToCommitPart)) @@ -252,7 +258,7 @@ BOOL UnlockedInterleavedLoaderHeap::GetMoreCommittedPages(size_t dwMinSize) if (m_pConfig->Template != NULL) { - ThunkMemoryHolder newAllocatedThunks = (BYTE*)ExecutableAllocator::Instance()->AllocateThunksFromTemplate(m_pConfig->Template, GetStubCodePageSize()); + ThunkMemoryHolder newAllocatedThunks = (BYTE*)ExecutableAllocator::Instance()->AllocateThunksFromTemplate(m_pConfig->Template, GetStubCodePageSize(), m_pConfig->DataPageGenerator); if (newAllocatedThunks == NULL) { return FALSE; @@ -307,7 +313,7 @@ BOOL UnlockedInterleavedLoaderHeap::GetMoreCommittedPages(size_t dwMinSize) // This mode interleaves data and code pages 1:1. So the code size is required to be smaller than // or equal to the page size to ensure that the code range is consecutive. _ASSERTE(dwMinSize <= GetStubCodePageSize()); - // For interleaved heap, we always get two memory pages - one for code and one for data + // We always get two memory pages - one for code and one for data dwMinSize = 2 * GetStubCodePageSize(); // Does this fit in the reserved region? @@ -315,7 +321,7 @@ BOOL UnlockedInterleavedLoaderHeap::GetMoreCommittedPages(size_t dwMinSize) { SIZE_T dwSizeToCommit; - // For interleaved heaps, the allocation cannot cross page boundary since there are data and executable + // The allocation cannot cross page boundary since there are data and executable // pages interleaved in a 1:1 fashion. dwSizeToCommit = dwMinSize; @@ -323,12 +329,12 @@ BOOL UnlockedInterleavedLoaderHeap::GetMoreCommittedPages(size_t dwMinSize) PTR_BYTE pCommitBaseAddress = m_pPtrToEndOfCommittedRegion; - // The end of committed region for interleaved heaps points to the end of the executable + // The end of committed region points to the end of the executable // page and the data pages goes right after that. So we skip the data page here. pCommitBaseAddress += GetStubCodePageSize(); size_t dwSizeToCommitPart = dwSizeToCommit; - // For interleaved heaps, we perform two commits, each being half of the requested size + // We perform two commits, each being half of the requested size dwSizeToCommitPart /= 2; if (!CommitPages(pCommitBaseAddress, dwSizeToCommitPart)) @@ -338,7 +344,7 @@ BOOL UnlockedInterleavedLoaderHeap::GetMoreCommittedPages(size_t dwMinSize) INDEBUG(m_dwDebugWastedBytes += unusedRemainder;) - // For interleaved heaps, further allocations will start from the newly committed page as they cannot + // Further allocations will start from the newly committed page as they cannot // cross page boundary. m_pAllocPtr = (BYTE*)pCommitBaseAddress; @@ -490,11 +496,14 @@ void *UnlockedInterleavedLoaderHeap::UnlockedAllocStub_NoThrow( } #ifdef _DEBUG - // Check to ensure that the RW region of the allocated stub is zeroed out - BYTE *pAllocatedRWBytes = (BYTE*)pResult + GetStubCodePageSize(); - for (size_t i = 0; i < dwRequestedSize; i++) + // Check to ensure that the RW region of the allocated stub is zeroed out if there isn't a data page generator + if (m_pConfig->DataPageGenerator == NULL) { - _ASSERTE_MSG(pAllocatedRWBytes[i] == 0, "LoaderHeap must return zero-initialized memory"); + BYTE *pAllocatedRWBytes = (BYTE*)pResult + GetStubCodePageSize(); + for (size_t i = 0; i < dwRequestedSize; i++) + { + _ASSERTE_MSG(pAllocatedRWBytes[i] == 0, "LoaderHeap must return zero-initialized memory"); + } } if (m_dwDebugFlags & kCallTracing) @@ -539,11 +548,12 @@ void *UnlockedInterleavedLoaderHeap::UnlockedAllocStub( return pResult; } -void InitializeLoaderHeapConfig(InterleavedLoaderHeapConfig *pConfig, size_t stubSize, void* templateInImage, void (*codePageGenerator)(uint8_t* pageBase, uint8_t* pageBaseRX, size_t size)) +void InitializeLoaderHeapConfig(InterleavedLoaderHeapConfig *pConfig, size_t stubSize, void* templateInImage, void (*codePageGenerator)(uint8_t* pageBase, uint8_t* pageBaseRX, size_t size), void (*dataPageGenerator)(uint8_t* pageBase, size_t size)) { pConfig->StubSize = (uint32_t)stubSize; pConfig->Template = ExecutableAllocator::Instance()->CreateTemplate(templateInImage, GetStubCodePageSize(), codePageGenerator); pConfig->CodePageGenerator = codePageGenerator; + pConfig->DataPageGenerator = dataPageGenerator; } #endif // #ifndef DACCESS_COMPILE diff --git a/src/coreclr/utilcode/loaderheap.cpp b/src/coreclr/utilcode/loaderheap.cpp index a0bf9b5f242251..073b24ba56d7ce 100644 --- a/src/coreclr/utilcode/loaderheap.cpp +++ b/src/coreclr/utilcode/loaderheap.cpp @@ -70,7 +70,6 @@ UnlockedLoaderHeap::UnlockedLoaderHeap(DWORD dwReserveBlockSize, } } -// ~LoaderHeap is not synchronised (obviously) UnlockedLoaderHeap::~UnlockedLoaderHeap() { CONTRACTL @@ -1053,7 +1052,6 @@ size_t UnlockedLoaderHeap::AllocMem_TotalSize(size_t dwRequestedSize) size_t dwSize = dwRequestedSize; - // Interleaved heap cannot ad any extra to the requested size #ifdef _DEBUG dwSize += LOADER_HEAP_DEBUG_BOUNDARY; dwSize = ((dwSize + ALLOC_ALIGN_CONSTANT) & (~ALLOC_ALIGN_CONSTANT)); diff --git a/src/coreclr/utilcode/log.cpp b/src/coreclr/utilcode/log.cpp index e56255f83629af..296757812e6b23 100644 --- a/src/coreclr/utilcode/log.cpp +++ b/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/coreclr/utilcode/pedecoder.cpp b/src/coreclr/utilcode/pedecoder.cpp index 25fa70691906dc..338c0fc3e07e89 100644 --- a/src/coreclr/utilcode/pedecoder.cpp +++ b/src/coreclr/utilcode/pedecoder.cpp @@ -2574,11 +2574,11 @@ BOOL PEDecoder::ForceRelocForDLL(LPCWSTR lpFileName) #endif // _DEBUG // -// MethodSectionIterator class is used to iterate hot (or) cold method section in an ngen image. -// Also used to iterate over jitted methods in the code heap +// MethodSectionIterator class is used to iterate hot (or) cold method sections +// over jitted methods in the code heap // -MethodSectionIterator::MethodSectionIterator(const void *code, SIZE_T codeSize, - const void *codeTable, SIZE_T codeTableSize) +MethodSectionIterator::MethodSectionIterator(void *code, SIZE_T codeSize, + void *codeTable, SIZE_T codeTableSize) { using namespace NibbleMap; diff --git a/src/coreclr/utilcode/stresslog.cpp b/src/coreclr/utilcode/stresslog.cpp index e837e86712d789..3fd772c41e92b5 100644 --- a/src/coreclr/utilcode/stresslog.cpp +++ b/src/coreclr/utilcode/stresslog.cpp @@ -305,6 +305,9 @@ void StressLog::Initialize(unsigned facilities, unsigned level, unsigned maxByte void StressLog::AddModule(uint8_t* moduleBase) { +#ifdef TARGET_WASM + return; // no modules on wasm +#endif unsigned moduleIndex = 0; #ifdef MEMORY_MAPPED_STRESSLOG StressLogHeader* hdr = theLog.stressLogHeader; diff --git a/src/coreclr/utilcode/util.cpp b/src/coreclr/utilcode/util.cpp index dac90c2ad97925..e6c2bf271f46c3 100644 --- a/src/coreclr/utilcode/util.cpp +++ b/src/coreclr/utilcode/util.cpp @@ -2332,6 +2332,55 @@ void PutLoongArch64JIR(UINT32 * pCode, INT64 imm38) _ASSERTE(GetLoongArch64JIR(pCode) == imm38); } + +//***************************************************************************** +// Extract the PC-Relative offset from auipc + I-type adder (addi/ld/jalr) +//***************************************************************************** +INT64 GetRiscV64AuipcItype(UINT32 * pCode) +{ + enum + { + OpcodeAuipc = 0x00000017, + OpcodeAddi = 0x00000013, + OpcodeLd = 0x00003003, + OpcodeJalr = 0x00000067, + OpcodeUTypeMask = 0x0000007F, + OpcodeITypeMask = 0x0000307F, + }; + + UINT32 auipc = pCode[0]; + _ASSERTE((auipc & OpcodeUTypeMask) == OpcodeAuipc); + int auipcRegDest = (auipc >> 7) & 0x1F; + _ASSERTE(auipcRegDest != 0); + + INT64 hi20 = (INT32(auipc) >> 12) << 12; + + UINT32 iType = pCode[1]; + UINT32 opcode = iType & OpcodeITypeMask; + _ASSERTE(opcode == OpcodeAddi || opcode == OpcodeLd || opcode == OpcodeJalr); + int iTypeRegSrc = (iType >> 15) & 0x1F; + _ASSERTE(auipcRegDest == iTypeRegSrc); + + INT64 lo12 = INT32(iType) >> 20; + + return hi20 + lo12; +} + +//***************************************************************************** +// Deposit the PC-Relative offset into auipc + I-type adder (addi/ld/jalr) +//***************************************************************************** +void PutRiscV64AuipcItype(UINT32 * pCode, INT64 offset) +{ + INT32 lo12 = (offset << (64 - 12)) >> (64 - 12); // low 12 bits, sign-extended + INT32 hi20 = INT32(offset - lo12); + _ASSERTE(INT64(hi20) + INT64(lo12) == offset); + + _ASSERTE(GetRiscV64AuipcItype(pCode) == 0); + pCode[0] |= hi20; + pCode[1] |= lo12 << 20; + _ASSERTE(GetRiscV64AuipcItype(pCode) == offset); +} + //====================================================================== // This function returns true, if it can determine that the instruction pointer // refers to a code address that belongs in the range of the given image. diff --git a/src/coreclr/utilcode/utsem.cpp b/src/coreclr/utilcode/utsem.cpp index 0dcb7dc0794b49..1367a969e4f0b3 100644 --- a/src/coreclr/utilcode/utsem.cpp +++ b/src/coreclr/utilcode/utsem.cpp @@ -195,7 +195,7 @@ HRESULT UTSemReadWrite::LockRead() // holding this lock. IncCantStopCount(); - // First do some spinning - copied from file:..\VM\crst.cpp#CrstBase::SpinEnter + // First do some spinning for (DWORD iter = 0; iter < g_SpinConstants.dwRepetitions; iter++) { DWORD i = g_SpinConstants.dwInitialDuration; @@ -287,7 +287,7 @@ HRESULT UTSemReadWrite::LockWrite() // holding this lock. IncCantStopCount(); - // First do some spinning - copied from file:..\VM\crst.cpp#CrstBase::SpinEnter + // First do some spinning for (DWORD iter = 0; iter < g_SpinConstants.dwRepetitions; iter++) { DWORD i = g_SpinConstants.dwInitialDuration; diff --git a/src/coreclr/vm/CMakeLists.txt b/src/coreclr/vm/CMakeLists.txt index 0a37c998ba581f..37f1a76d4f73a3 100644 --- a/src/coreclr/vm/CMakeLists.txt +++ b/src/coreclr/vm/CMakeLists.txt @@ -47,10 +47,6 @@ endif(FEATURE_PERFTRACING) add_compile_definitions($<${FEATURE_CORECLR_CACHED_INTERFACE_DISPATCH}:FEATURE_CACHED_INTERFACE_DISPATCH>) add_compile_definitions($<${FEATURE_CORECLR_VIRTUAL_STUB_DISPATCH}:FEATURE_VIRTUAL_STUB_DISPATCH>) -if(CLR_CMAKE_TARGET_ARCH_WASM) - add_compile_definitions(FEATURE_STATICALLY_LINKED) -endif() - set(VM_SOURCES_DAC_AND_WKS_COMMON appdomain.cpp array.cpp @@ -914,6 +910,14 @@ elseif(CLR_CMAKE_TARGET_ARCH_RISCV64) ${ARCH_SOURCES_DIR}/singlestepper.cpp gcinfodecoder.cpp ) +elseif(CLR_CMAKE_TARGET_ARCH_WASM) + set(VM_SOURCES_WKS_ARCH + ${ARCH_SOURCES_DIR}/calldescrworkerwasm.cpp + ${ARCH_SOURCES_DIR}/profiler.cpp + ${ARCH_SOURCES_DIR}/helpers.cpp + exceptionhandling.cpp + gcinfodecoder.cpp + ) endif() set(VM_SOURCES_DAC_ARCH @@ -1009,3 +1013,5 @@ add_subdirectory(wks) if(FEATURE_PERFTRACING) add_subdirectory(eventing) endif(FEATURE_PERFTRACING) + +add_subdirectory(datadescriptor) diff --git a/src/coreclr/vm/ClrEtwAllMeta.lst b/src/coreclr/vm/ClrEtwAllMeta.lst index f5659cfa3ad047..1cbfc89755d526 100644 --- a/src/coreclr/vm/ClrEtwAllMeta.lst +++ b/src/coreclr/vm/ClrEtwAllMeta.lst @@ -650,6 +650,8 @@ nomac:CLRStackStress:::CLRStackWalkStress ################################# nostack:DebugIPCEvent:::DebugIPCEventStart nostack:DebugIPCEvent:::DebugIPCEventEnd +nostack:DebugExceptionProcessing:::DebugExceptionProcessingStart +nostack:DebugExceptionProcessing:::DebugExceptionProcessingEnd ################################# # Events from the Mono profiler provider diff --git a/src/coreclr/vm/amd64/AsmHelpers.asm b/src/coreclr/vm/amd64/AsmHelpers.asm index 8464102ef23730..178ffe4bddcbe0 100644 --- a/src/coreclr/vm/amd64/AsmHelpers.asm +++ b/src/coreclr/vm/amd64/AsmHelpers.asm @@ -4,7 +4,9 @@ include AsmMacros.inc include asmconstants.inc -extern NDirectImportWorker:proc +Thread_GetInterpThreadContext TEXTEQU + +extern PInvokeImportWorker:proc extern ThePreStub:proc extern ProfileEnter:proc extern ProfileLeave:proc @@ -13,6 +15,7 @@ extern OnHijackWorker:proc extern JIT_RareDisableHelperWorker:proc ifdef FEATURE_INTERPRETER extern ExecuteInterpretedMethod:proc +extern Thread_GetInterpThreadContext:proc endif extern g_pPollGC:QWORD @@ -20,15 +23,12 @@ extern g_TrapReturningThreads:DWORD ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; NDirectImportThunk +;; PInvokeImportThunk ;; -;; In addition to being called by the EE, this function can be called -;; directly from code generated by JIT64 for CRT optimized direct -;; P/Invoke calls. If it is modified, the JIT64 compiler's code -;; generation will need to altered accordingly. +;; The call in PInvokeImportPrecode points to this function. ;; -; EXTERN_C VOID __stdcall NDirectImportThunk(); -NESTED_ENTRY NDirectImportThunk, _TEXT +; EXTERN_C VOID __stdcall PInvokeImportThunk(); +NESTED_ENTRY PInvokeImportThunk, _TEXT ; ; Allocate space for XMM parameter registers and callee scratch area. @@ -52,10 +52,10 @@ NESTED_ENTRY NDirectImportThunk, _TEXT END_PROLOGUE ; - ; Call NDirectImportWorker w/ the NDirectMethodDesc* + ; Call PInvokeImportWorker w/ the PInvokeMethodDesc* ; mov rcx, METHODDESC_REGISTER - call NDirectImportWorker + call PInvokeImportWorker ; ; Restore parameter registers @@ -76,7 +76,7 @@ NESTED_ENTRY NDirectImportThunk, _TEXT add rsp, 68h TAILJMP_RAX -NESTED_END NDirectImportThunk, _TEXT +NESTED_END PInvokeImportThunk, _TEXT ;------------------------------------------------ @@ -565,12 +565,21 @@ NESTED_ENTRY InterpreterStub, _TEXT INLINE_GETTHREAD r10; thrashes rax and r11 + mov rax, qword ptr [r10 + OFFSETOF__Thread__m_pInterpThreadContext] + test rax, rax + jnz HaveInterpThreadContext + + mov rcx, r10 + call Thread_GetInterpThreadContext + RESTORE_ARGUMENT_REGISTERS __PWTB_ArgumentRegisters + RESTORE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters + +HaveInterpThreadContext: + mov r10, qword ptr [rax + OFFSETOF__InterpThreadContext__pStackPointer] ; Load the InterpMethod pointer from the IR bytecode mov rax, qword ptr [rbx] mov rax, qword ptr [rax + OFFSETOF__InterpMethod__pCallStub] lea r11, qword ptr [rax + OFFSETOF__CallStubHeader__Routines] - mov r10, qword ptr [r10 + OFFSETOF__Thread__m_pInterpThreadContext] - mov r10, qword ptr [r10 + OFFSETOF__InterpThreadContext__pStackPointer] lea rax, [rsp + __PWTB_TransitionBlock] ; Copy the arguments to the interpreter stack, invoke the InterpExecMethod and load the return value call qword ptr [r11] @@ -654,6 +663,33 @@ LEAF_ENTRY Store_Stack, _TEXT jmp qword ptr [r11] LEAF_END Store_Stack, _TEXT +LEAF_ENTRY Load_Stack_Ref, _TEXT + mov esi, dword ptr [r11 + 8] ; SP offset + mov edi, dword ptr [r11 + 12] ; size of the value type + add rsi, 8; return address + add rsi, rsp + mov qword ptr [rsi], r10 + add r10, rdi + lea r10, [r10 + 7] + and r10, 0fffffffffffffff8h + add r11, 16 + jmp qword ptr [r11] +LEAF_END Load_Stack_Ref, _TEXT + +LEAF_ENTRY Store_Stack_Ref, _TEXT + mov esi, dword ptr [r11 + 8] ; SP offset + mov ecx, dword ptr [r11 + 12] ; size of the value type + mov rsi, [rsp + rsi + 8 + __InterpreterStubArgumentRegistersOffset] + mov rdi, r10 + rep movsb + ; align rdi up to the stack slot size + lea rdi, [rdi + 7] + and rdi, 0fffffffffffffff8h + mov r10, rdi + add r11, 16 + jmp qword ptr [r11] +LEAF_END Store_Stack_Ref, _TEXT + ; Routines for passing value type arguments by reference in general purpose registers RCX, RDX, R8, R9 ; from native code to the interpreter diff --git a/src/coreclr/vm/amd64/PInvokeStubs.asm b/src/coreclr/vm/amd64/PInvokeStubs.asm index a18ed56b752d3c..9913dbd3c53f5b 100644 --- a/src/coreclr/vm/amd64/PInvokeStubs.asm +++ b/src/coreclr/vm/amd64/PInvokeStubs.asm @@ -23,7 +23,7 @@ LEAF_ENTRY GenericPInvokeCalliHelper, _TEXT ; ; check for existing IL stub ; - mov rax, [PINVOKE_CALLI_SIGTOKEN_REGISTER + OFFSETOF__VASigCookie__pNDirectILStub] + mov rax, [PINVOKE_CALLI_SIGTOKEN_REGISTER + OFFSETOF__VASigCookie__pPInvokeILStub] test rax, rax jz GenericPInvokeCalliGenILStub @@ -85,7 +85,7 @@ LEAF_ENTRY VarargPInvokeStubHelper, _TEXT ; ; check for existing IL stub ; - mov rax, [PINVOKE_CALLI_SIGTOKEN_REGISTER + OFFSETOF__VASigCookie__pNDirectILStub] + mov rax, [PINVOKE_CALLI_SIGTOKEN_REGISTER + OFFSETOF__VASigCookie__pPInvokeILStub] test rax, rax jz VarargPInvokeGenILStub diff --git a/src/coreclr/vm/amd64/asmconstants.h b/src/coreclr/vm/amd64/asmconstants.h index 96bb2f26d96239..1880ecbafdd340 100644 --- a/src/coreclr/vm/amd64/asmconstants.h +++ b/src/coreclr/vm/amd64/asmconstants.h @@ -248,9 +248,9 @@ ASMCONSTANTS_C_ASSERT(OFFSETOF__DynamicStaticsInfo__m_pNonGCStatics ASMCONSTANTS_C_ASSERT(OFFSETOF__DynamicStaticsInfo__m_pGCStatics == offsetof(DynamicStaticsInfo, m_pGCStatics)); -#define OFFSETOF__VASigCookie__pNDirectILStub 0x8 -ASMCONSTANTS_C_ASSERT(OFFSETOF__VASigCookie__pNDirectILStub - == offsetof(VASigCookie, pNDirectILStub)); +#define OFFSETOF__VASigCookie__pPInvokeILStub 0x8 +ASMCONSTANTS_C_ASSERT(OFFSETOF__VASigCookie__pPInvokeILStub + == offsetof(VASigCookie, pPInvokeILStub)); #if defined(UNIX_AMD64_ABI) && !defined(HOST_WINDOWS) // Expression is too complicated, is currently: diff --git a/src/coreclr/vm/amd64/asmhelpers.S b/src/coreclr/vm/amd64/asmhelpers.S index 79b6b520617b7a..fb90ce2b1034a6 100644 --- a/src/coreclr/vm/amd64/asmhelpers.S +++ b/src/coreclr/vm/amd64/asmhelpers.S @@ -444,6 +444,15 @@ NESTED_ENTRY InterpreterStub, _TEXT, NoHandler INLINE_GETTHREAD // result in rax, it can thrash all argument registers as it can call a helper mov r10, rax + mov rax, qword ptr [r10 + OFFSETOF__Thread__m_pInterpThreadContext] + test rax, rax + jnz LOCAL_LABEL(HaveInterpThreadContext) + + mov rcx, r10 + call C_FUNC(_ZN6Thread22GetInterpThreadContextEv) // Thread::GetInterpThreadContext + +LOCAL_LABEL(HaveInterpThreadContext): + mov r10, qword ptr [rax + OFFSETOF__InterpThreadContext__pStackPointer] // Load the InterpMethod pointer from the IR bytecode mov rax, qword ptr [rbx] mov rax, qword ptr [rax + OFFSETOF__InterpMethod__pCallStub] @@ -463,8 +472,6 @@ NESTED_ENTRY InterpreterStub, _TEXT, NoHandler movsd xmm6, real8 ptr [rsp + __PWTB_FloatArgumentRegisters + 0x60] movsd xmm7, real8 ptr [rsp + __PWTB_FloatArgumentRegisters + 0x70] lea r11, qword ptr [rax + OFFSETOF__CallStubHeader__Routines] - mov r10, qword ptr [r10 + OFFSETOF__Thread__m_pInterpThreadContext] - mov r10, qword ptr [r10 + OFFSETOF__InterpThreadContext__pStackPointer] lea rax, [rsp + __PWTB_TransitionBlock] // rbx contains IR bytecode address // Copy the arguments to the interpreter stack, invoke the InterpExecMethod and load the return value diff --git a/src/coreclr/vm/amd64/cgenamd64.cpp b/src/coreclr/vm/amd64/cgenamd64.cpp index 7fa9d44d1baa6b..af27637759473b 100644 --- a/src/coreclr/vm/amd64/cgenamd64.cpp +++ b/src/coreclr/vm/amd64/cgenamd64.cpp @@ -138,6 +138,14 @@ void InlinedCallFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateF SyncRegDisplayToCurrentContext(pRD); +#ifdef FEATURE_INTERPRETER + if ((m_Next != FRAME_TOP) && (m_Next->GetFrameIdentifier() == FrameIdentifier::InterpreterFrame)) + { + // If the next frame is an interpreter frame, we also need to set the first argument register to point to the interpreter frame. + SetFirstArgReg(pRD->pCurrentContext, dac_cast(m_Next)); + } +#endif // FEATURE_INTERPRETER + LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK InlinedCallFrame::UpdateRegDisplay_Impl(rip:%p, rsp:%p)\n", pRD->ControlPC, pRD->SP)); } @@ -380,14 +388,14 @@ void EncodeLoadAndJumpThunk (LPBYTE pBuffer, LPVOID pv, LPVOID pTarget) pBuffer[0] = 0x49; pBuffer[1] = 0xBA; - *((UINT64 UNALIGNED *)&pBuffer[2]) = (UINT64)pv; + SET_UNALIGNED_64(&pBuffer[2], pv); // mov rax, pTarget 48 b8 xx xx xx xx xx xx xx xx pBuffer[10] = 0x48; pBuffer[11] = 0xB8; - *((UINT64 UNALIGNED *)&pBuffer[12]) = (UINT64)pTarget; + SET_UNALIGNED_64(&pBuffer[12], pTarget); // jmp rax ff e0 @@ -419,7 +427,7 @@ void emitCOMStubCall (ComCallMethodDesc *pCOMMethodRX, ComCallMethodDesc *pCOMMe // nop 90 // call [$ - 10] ff 15 f0 ff ff ff - *((UINT64 *)&pBufferRW[COMMETHOD_CALL_PRESTUB_ADDRESS_OFFSET]) = (UINT64)target; + SET_UNALIGNED_64(&pBufferRW[COMMETHOD_CALL_PRESTUB_ADDRESS_OFFSET], target); pBufferRW[-2] = 0x90; pBufferRW[-1] = 0x90; @@ -451,7 +459,7 @@ void emitJump(LPBYTE pBufferRX, LPBYTE pBufferRW, LPVOID target) pBufferRW[0] = 0x48; pBufferRW[1] = 0xB8; - *((UINT64 UNALIGNED *)&pBufferRW[2]) = (UINT64)target; + SET_UNALIGNED_64(&pBufferRW[2], target); pBufferRW[10] = 0xFF; pBufferRW[11] = 0xE0; @@ -630,16 +638,16 @@ PCODE DynamicHelpers::CreateHelper(LoaderAllocator * pAllocator, TADDR arg, PCOD BEGIN_DYNAMIC_HELPER_EMIT(15); #ifdef UNIX_AMD64_ABI - *(UINT16 *)p = 0xBF48; // mov rdi, XXXXXX + SET_UNALIGNED_16(p, 0xBF48); // mov rdi, XXXXXX #else - *(UINT16 *)p = 0xB948; // mov rcx, XXXXXX + SET_UNALIGNED_16(p, 0xB948); // mov rcx, XXXXXX #endif p += 2; - *(TADDR *)p = arg; + SET_UNALIGNED_64(p, arg); p += 8; *p++ = X86_INSTR_JMP_REL32; // jmp rel32 - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), target, NULL, pAllocator); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), target, NULL, pAllocator)); p += 4; END_DYNAMIC_HELPER_EMIT(); @@ -657,16 +665,16 @@ void DynamicHelpers::EmitHelperWithArg(BYTE*& p, size_t rxOffset, LoaderAllocato // Move an argument into the second argument register and jump to a target function. #ifdef UNIX_AMD64_ABI - *(UINT16 *)p = 0xBE48; // mov rsi, XXXXXX + SET_UNALIGNED_16(p, 0xBE48); // mov rsi, XXXXXX #else - *(UINT16 *)p = 0xBA48; // mov rdx, XXXXXX + SET_UNALIGNED_16(p, 0xBA48); // mov rdx, XXXXXX #endif p += 2; - *(TADDR *)p = arg; + SET_UNALIGNED_64(p, arg); p += 8; *p++ = X86_INSTR_JMP_REL32; // jmp rel32 - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), target, NULL, pAllocator); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), target, NULL, pAllocator)); p += 4; } @@ -684,25 +692,25 @@ PCODE DynamicHelpers::CreateHelper(LoaderAllocator * pAllocator, TADDR arg, TADD BEGIN_DYNAMIC_HELPER_EMIT(25); #ifdef UNIX_AMD64_ABI - *(UINT16 *)p = 0xBF48; // mov rdi, XXXXXX + SET_UNALIGNED_16(p, 0xBF48); // mov rdi, XXXXXX #else - *(UINT16 *)p = 0xB948; // mov rcx, XXXXXX + SET_UNALIGNED_16(p, 0xB948); // mov rcx, XXXXXX #endif p += 2; - *(TADDR *)p = arg; + SET_UNALIGNED_64(p, arg); p += 8; #ifdef UNIX_AMD64_ABI - *(UINT16 *)p = 0xBE48; // mov rsi, XXXXXX + SET_UNALIGNED_16(p, 0xBE48); // mov rsi, XXXXXX #else - *(UINT16 *)p = 0xBA48; // mov rdx, XXXXXX + SET_UNALIGNED_16(p, 0xBA48); // mov rdx, XXXXXX #endif p += 2; - *(TADDR *)p = arg2; + SET_UNALIGNED_64(p, arg2); p += 8; *p++ = X86_INSTR_JMP_REL32; // jmp rel32 - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), target, NULL, pAllocator); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), target, NULL, pAllocator)); p += 4; END_DYNAMIC_HELPER_EMIT(); @@ -714,24 +722,24 @@ PCODE DynamicHelpers::CreateHelperArgMove(LoaderAllocator * pAllocator, TADDR ar #ifdef UNIX_AMD64_ABI *p++ = 0x48; // mov rsi, rdi - *(UINT16 *)p = 0xF78B; + SET_UNALIGNED_16(p, 0xF78B); #else *p++ = 0x48; // mov rdx, rcx - *(UINT16 *)p = 0xD18B; + SET_UNALIGNED_16(p, 0xD18B); #endif p += 2; #ifdef UNIX_AMD64_ABI - *(UINT16 *)p = 0xBF48; // mov rdi, XXXXXX + SET_UNALIGNED_16(p, 0xBF48); // mov rdi, XXXXXX #else - *(UINT16 *)p = 0xB948; // mov rcx, XXXXXX + SET_UNALIGNED_16(p, 0xB948); // mov rcx, XXXXXX #endif p += 2; - *(TADDR *)p = arg; + SET_UNALIGNED_64(p, arg); p += 8; *p++ = X86_INSTR_JMP_REL32; // jmp rel32 - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), target, NULL, pAllocator); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), target, NULL, pAllocator)); p += 4; END_DYNAMIC_HELPER_EMIT(); @@ -750,9 +758,9 @@ PCODE DynamicHelpers::CreateReturnConst(LoaderAllocator * pAllocator, TADDR arg) { BEGIN_DYNAMIC_HELPER_EMIT(11); - *(UINT16 *)p = 0xB848; // mov rax, XXXXXX + SET_UNALIGNED_16(p, 0xB848); // mov rax, XXXXXX p += 2; - *(TADDR *)p = arg; + SET_UNALIGNED_64(p, arg); p += 8; *p++ = 0xC3; // ret @@ -764,9 +772,9 @@ PCODE DynamicHelpers::CreateReturnIndirConst(LoaderAllocator * pAllocator, TADDR { BEGIN_DYNAMIC_HELPER_EMIT((offset != 0) ? 15 : 11); - *(UINT16 *)p = 0xA148; // mov rax, [XXXXXX] + SET_UNALIGNED_16(p, 0xA148); // mov rax, [XXXXXX] p += 2; - *(TADDR *)p = arg; + SET_UNALIGNED_64(p, arg); p += 8; if (offset != 0) @@ -788,16 +796,16 @@ PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADD BEGIN_DYNAMIC_HELPER_EMIT(15); #ifdef UNIX_AMD64_ABI - *(UINT16 *)p = 0xBA48; // mov rdx, XXXXXX + SET_UNALIGNED_16(p, 0xBA48); // mov rdx, XXXXXX #else - *(UINT16 *)p = 0xB849; // mov r8, XXXXXX + SET_UNALIGNED_16(p, 0xB849); // mov r8, XXXXXX #endif p += 2; - *(TADDR *)p = arg; + SET_UNALIGNED_64(p, arg); p += 8; *p++ = X86_INSTR_JMP_REL32; // jmp rel32 - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), target, NULL, pAllocator); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), target, NULL, pAllocator)); p += 4; END_DYNAMIC_HELPER_EMIT(); @@ -808,25 +816,25 @@ PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADD BEGIN_DYNAMIC_HELPER_EMIT(25); #ifdef UNIX_AMD64_ABI - *(UINT16 *)p = 0xBA48; // mov rdx, XXXXXX + SET_UNALIGNED_16(p, 0xBA48); // mov rdx, XXXXXX #else - *(UINT16 *)p = 0xB849; // mov r8, XXXXXX + SET_UNALIGNED_16(p, 0xB849); // mov r8, XXXXXX #endif p += 2; - *(TADDR *)p = arg; + SET_UNALIGNED_64(p, arg); p += 8; #ifdef UNIX_AMD64_ABI - *(UINT16 *)p = 0xB948; // mov rcx, XXXXXX + SET_UNALIGNED_16(p, 0xB948); // mov rcx, XXXXXX #else - *(UINT16 *)p = 0xB949; // mov r9, XXXXXX + SET_UNALIGNED_16(p, 0xB949); // mov r9, XXXXXX #endif p += 2; - *(TADDR *)p = arg2; + SET_UNALIGNED_64(p, arg2); p += 8; *p++ = X86_INSTR_JMP_REL32; // jmp rel32 - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), target, NULL, pAllocator); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), target, NULL, pAllocator)); p += 4; END_DYNAMIC_HELPER_EMIT(); @@ -877,9 +885,9 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator, _ASSERTE(pLookup->testForNull && i > 0); // cmp qword ptr[rax + sizeOffset],slotOffset - *(UINT32*)p = 0x00b88148; p += 3; - *(UINT32*)p = (UINT32)pLookup->sizeOffset; p += 4; - *(UINT32*)p = (UINT32)slotOffset; p += 4; + SET_UNALIGNED_32(p, 0x00b88148); p += 3; + SET_UNALIGNED_32(p, (UINT32)pLookup->sizeOffset); p += 4; + SET_UNALIGNED_32(p, (UINT32)slotOffset); p += 4; // jle 'HELPER CALL' *p++ = 0x7e; @@ -893,24 +901,24 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator, // mov rax,qword ptr [rdi+offset] if (pLookup->offsets[i] >= 0x80) { - *(UINT32*)p = 0x00878b48; p += 3; - *(UINT32*)p = (UINT32)pLookup->offsets[i]; p += 4; + SET_UNALIGNED_32(p, 0x00878b48); p += 3; + SET_UNALIGNED_32(p, (UINT32)pLookup->offsets[i]); p += 4; } else { - *(UINT32*)p = 0x00478b48; p += 3; + SET_UNALIGNED_32(p, 0x00478b48); p += 3; *p++ = (BYTE)pLookup->offsets[i]; } #else // mov rax,qword ptr [rcx+offset] if (pLookup->offsets[i] >= 0x80) { - *(UINT32*)p = 0x00818b48; p += 3; - *(UINT32*)p = (UINT32)pLookup->offsets[i]; p += 4; + SET_UNALIGNED_32(p, 0x00818b48); p += 3; + SET_UNALIGNED_32(p, (UINT32)pLookup->offsets[i]); p += 4; } else { - *(UINT32*)p = 0x00418b48; p += 3; + SET_UNALIGNED_32(p, 0x00418b48); p += 3; *p++ = (BYTE)pLookup->offsets[i]; } #endif @@ -920,12 +928,12 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator, // mov rax,qword ptr [rax+offset] if (pLookup->offsets[i] >= 0x80) { - *(UINT32*)p = 0x00808b48; p += 3; - *(UINT32*)p = (UINT32)pLookup->offsets[i]; p += 4; + SET_UNALIGNED_32(p, 0x00808b48); p += 3; + SET_UNALIGNED_32(p, (UINT32)pLookup->offsets[i]); p += 4; } else { - *(UINT32*)p = 0x00408b48; p += 3; + SET_UNALIGNED_32(p, 0x00408b48); p += 3; *p++ = (BYTE)pLookup->offsets[i]; } } @@ -945,10 +953,10 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator, _ASSERTE(pLookup->indirections != 0); - *(UINT32*)p = 0x00c08548; p += 3; // test rax,rax + SET_UNALIGNED_32(p, 0x00c08548); p += 3; // test rax,rax // je 'HELPER_CALL' (a jump of 1 byte) - *(UINT16*)p = 0x0174; p += 2; + SET_UNALIGNED_16(p, 0x0174); p += 2; *p++ = 0xC3; // ret diff --git a/src/coreclr/vm/amd64/cgencpu.h b/src/coreclr/vm/amd64/cgencpu.h index db9e1c717b53e2..bf50d7941adab4 100644 --- a/src/coreclr/vm/amd64/cgencpu.h +++ b/src/coreclr/vm/amd64/cgencpu.h @@ -43,7 +43,7 @@ class ComCallMethodDesc; #define SIZEOF_LOAD_AND_JUMP_THUNK 22 // # bytes to mov r10, X; jmp Z #define SIZEOF_LOAD2_AND_JUMP_THUNK 32 // # bytes to mov r10, X; mov r11, Y; jmp Z -#define HAS_NDIRECT_IMPORT_PRECODE 1 +#define HAS_PINVOKE_IMPORT_PRECODE 1 #define HAS_FIXUP_PRECODE 1 // ThisPtrRetBufPrecode one is necessary for closed delegates over static methods with return buffer diff --git a/src/coreclr/vm/amd64/pinvokestubs.S b/src/coreclr/vm/amd64/pinvokestubs.S index 3d33a63d8a0862..49bc602afee105 100644 --- a/src/coreclr/vm/amd64/pinvokestubs.S +++ b/src/coreclr/vm/amd64/pinvokestubs.S @@ -19,7 +19,7 @@ LEAF_ENTRY GenericPInvokeCalliHelper, _TEXT // // check for existing IL stub // - mov rax, [PINVOKE_CALLI_SIGTOKEN_REGISTER + OFFSETOF__VASigCookie__pNDirectILStub] + mov rax, [PINVOKE_CALLI_SIGTOKEN_REGISTER + OFFSETOF__VASigCookie__pPInvokeILStub] test rax, rax jz C_FUNC(GenericPInvokeCalliGenILStub) @@ -81,7 +81,7 @@ LEAF_ENTRY VarargPInvokeStubHelper, _TEXT // // check for existing IL stub // - mov rax, [PINVOKE_CALLI_SIGTOKEN_REGISTER + OFFSETOF__VASigCookie__pNDirectILStub] + mov rax, [PINVOKE_CALLI_SIGTOKEN_REGISTER + OFFSETOF__VASigCookie__pPInvokeILStub] test rax, rax jz C_FUNC(VarargPInvokeGenILStub) diff --git a/src/coreclr/vm/amd64/unixasmhelpers.S b/src/coreclr/vm/amd64/unixasmhelpers.S index cc864816bf03c8..53115def14a26b 100644 --- a/src/coreclr/vm/amd64/unixasmhelpers.S +++ b/src/coreclr/vm/amd64/unixasmhelpers.S @@ -7,15 +7,12 @@ ////////////////////////////////////////////////////////////////////////// // -// NDirectImportThunk +// PInvokeImportThunk // -// In addition to being called by the EE, this function can be called -// directly from code generated by JIT64 for CRT optimized direct -// P/Invoke calls. If it is modified, the JIT64 compiler's code -// generation will need to altered accordingly. +// The call in PInvokeImportPrecode points to this function // -// EXTERN_C VOID __stdcall NDirectImportThunk()// -NESTED_ENTRY NDirectImportThunk, _TEXT, NoHandler +// EXTERN_C VOID __stdcall PInvokeImportThunk()// +NESTED_ENTRY PInvokeImportThunk, _TEXT, NoHandler // // Save integer parameter registers. @@ -36,10 +33,10 @@ NESTED_ENTRY NDirectImportThunk, _TEXT, NoHandler END_PROLOGUE // - // Call NDirectImportWorker w/ the NDirectMethodDesc* + // Call PInvokeImportWorker w/ the PInvokeMethodDesc* // mov rdi, METHODDESC_REGISTER - call C_FUNC(NDirectImportWorker) + call C_FUNC(PInvokeImportWorker) mov r10, rax RESTORE_FLOAT_ARGUMENT_REGISTERS 0 @@ -58,7 +55,7 @@ NESTED_ENTRY NDirectImportThunk, _TEXT, NoHandler jmp r10 -NESTED_END NDirectImportThunk, _TEXT +NESTED_END PInvokeImportThunk, _TEXT //------------------------------------------------ // JIT_RareDisableHelper diff --git a/src/coreclr/vm/appdomain.cpp b/src/coreclr/vm/appdomain.cpp index 06d3adfe474d7c..7b247b2b8bfd02 100644 --- a/src/coreclr/vm/appdomain.cpp +++ b/src/coreclr/vm/appdomain.cpp @@ -762,7 +762,6 @@ void SystemDomain::DetachBegin() // Shut down the domain and its children (but don't deallocate anything just // yet). - // TODO: we should really not running managed DLLMain during process detach. if (GetThreadNULLOk() == NULL) { return; @@ -890,7 +889,7 @@ void SystemDomain::Init() { // We are about to start allocating objects, so we must be in cooperative mode. // However, many of the entrypoints to the system (DllGetClassObject and all - // N/Direct exports) get called multiple times. Sometimes they initialize the EE, + // PInvoke exports) get called multiple times. Sometimes they initialize the EE, // but generally they remain in preemptive mode. So we really want to push/pop // the state here: GCX_COOP(); @@ -953,29 +952,23 @@ void SystemDomain::LazyInitFrozenObjectsHeap() /*static*/ void SystemDomain::EnumAllStaticGCRefs(promote_func* fn, ScanContext* sc) { - CONTRACT_VOID + CONTRACTL { NOTHROW; GC_NOTRIGGER; MODE_COOPERATIVE; } - CONTRACT_END; + CONTRACTL_END; _ASSERTE(GCHeapUtilities::IsGCInProgress() && GCHeapUtilities::IsServerHeap() && IsGCSpecialThread()); - SystemDomain* sysDomain = SystemDomain::System(); - if (sysDomain) + AppDomain* pAppDomain = ::GetAppDomain(); + if (pAppDomain) { - AppDomain* pAppDomain = ::GetAppDomain(); - if (pAppDomain && pAppDomain->IsActive()) - { - pAppDomain->EnumStaticGCRefs(fn, sc); - } + pAppDomain->EnumStaticGCRefs(fn, sc); } - - RETURN; } extern "C" PCODE g_pGetGCStaticBase; @@ -1480,7 +1473,6 @@ void AppDomain::Create() NewHolder pDomain(new AppDomain()); pDomain->Init(); - pDomain->SetStage(AppDomain::STAGE_OPEN); pDomain->CreateDefaultBinder(); m_pTheAppDomain = pDomain.Extract(); @@ -1504,11 +1496,26 @@ void SystemDomain::PublishAppDomainAndInformDebugger (AppDomain *pDomain) LOG((LF_CORDB, LL_INFO100, "SD::PADAID: Adding 0x%x\n", pDomain)); - // Call the publisher API to add this appdomain entry to the list - // The publisher will handle failures, so we don't care if this succeeds or fails. - if (g_pDebugInterface != NULL) + // + // We need to synchronize this routine with the attach logic. The "normal" + // attach case uses the HelperThread and TrapAllRuntimeThreads to synchronize + // the runtime before sending any of the events (including AppDomainCreates) + // to the right-side. Thus, we can synchronize with this case by forcing us + // to go co-operative. If we were already co-op, then the helper thread will + // wait to start the attach until all co-op threads are paused. If we were + // pre-emptive, then going co-op will suspend us until the HelperThread finishes. + // + // The second case is under the IPC event for ATTACHING, which is where there are + // zero app domains, so it is considered an 'early attach' case. To synchronize + // with this we have to grab and hold the AppDomainDB lock. + // + + + // Send event to debugger if one is attached. + if (CORDebuggerAttached()) { - g_pDebugInterface->AddAppDomainToIPC(pDomain); + GCX_COOP(); + g_pDebugInterface->AppDomainCreated(pDomain); } } @@ -1613,7 +1620,6 @@ AppDomain::AppDomain() #ifdef FEATURE_COMWRAPPERS , m_pRCWRefCache{NULL} #endif // FEATURE_COMWRAPPERS - , m_Stage{STAGE_CREATING} , m_ForceTrivialWaitOperations{false} #ifdef FEATURE_TYPEEQUIVALENCE , m_pTypeEquivalenceTable{NULL} @@ -1660,12 +1666,7 @@ AppDomain::~AppDomain() //***************************************************************************** void AppDomain::Init() { - CONTRACTL - { - STANDARD_VM_CHECK; - PRECONDITION(m_Stage == STAGE_CREATING); - } - CONTRACTL_END; + STANDARD_VM_CONTRACT; // // The JIT lock and the CCtor locks are at the same level (and marked as @@ -1706,8 +1707,6 @@ void AppDomain::Init() m_ReflectionCrst.Init(CrstReflection, CRST_UNSAFE_ANYMODE); m_RefClassFactCrst.Init(CrstClassFactInfoHash); - SetStage(STAGE_READYFORMANAGEDCODE); - #ifdef FEATURE_TIERED_COMPILATION m_tieredCompilationManager.Init(); #endif @@ -1738,13 +1737,6 @@ void AppDomain::Stop() #ifdef DEBUGGING_SUPPORTED if (IsDebuggerAttached()) NotifyDebuggerUnload(); - - if (NULL != g_pDebugInterface) - { - // Call the publisher API to delete this appdomain entry from the list - CONTRACT_VIOLATION(ThrowsViolation); - g_pDebugInterface->RemoveAppDomainFromIPC (this); - } #endif // DEBUGGING_SUPPORTED } @@ -2811,13 +2803,9 @@ void AppDomain::SetFriendlyName(LPCWSTR pwzFriendlyName) if(g_pDebugInterface) { - // update the name in the IPC publishing block - if (SUCCEEDED(g_pDebugInterface->UpdateAppDomainEntryInIPC(this))) - { - // inform the attached debugger that the name of this appdomain has changed. - if (IsDebuggerAttached()) - g_pDebugInterface->NameChangeEvent(this, NULL); - } + // inform the attached debugger that the name of this appdomain has changed. + if (IsDebuggerAttached()) + g_pDebugInterface->NameChangeEvent(this, NULL); } } #endif // !DACCESS_COMPILE @@ -3430,7 +3418,7 @@ void AppDomain::RaiseExitProcessEvent() STATIC_CONTRACT_GC_TRIGGERS; // Only finalizer thread during shutdown can call this function. - _ASSERTE (g_fEEShutDown && (GetThread() == FinalizerThread::GetFinalizerThread())); + _ASSERTE (g_fEEShutDown && FinalizerThread::IsCurrentThreadFinalizer()); _ASSERTE (GetThread()->PreemptiveGCDisabled()); @@ -4096,7 +4084,7 @@ AppDomain::AssemblyIterator::Next_Unlocked( #if !defined(DACCESS_COMPILE) // Returns S_OK if the assembly was successfully loaded -HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToBindWithin, BINDER_SPACE::AssemblyName *pAssemblyName, DefaultAssemblyBinder *pDefaultBinder, AssemblyBinder *pBinder, BINDER_SPACE::Assembly **ppLoadedAssembly) +HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pAssemblyLoadContextToBindWithin, BINDER_SPACE::AssemblyName *pAssemblyName, DefaultAssemblyBinder *pDefaultBinder, AssemblyBinder *pBinder, BINDER_SPACE::Assembly **ppLoadedAssembly) { CONTRACTL { @@ -4126,7 +4114,7 @@ HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToB BINDER_SPACE::Assembly *pResolvedAssembly = NULL; bool fResolvedAssembly = false; - BinderTracing::ResolutionAttemptedOperation tracer{pAssemblyName, 0 /*binderID*/, pManagedAssemblyLoadContextToBindWithin, hr}; + BinderTracing::ResolutionAttemptedOperation tracer{pAssemblyName, 0 /*binderID*/, pAssemblyLoadContextToBindWithin, hr}; // Allocate an AssemblyName managed object _gcRefs.oRefAssemblyName = (ASSEMBLYNAMEREF) AllocateObject(CoreLibBinder::GetClass(CLASS__ASSEMBLY_NAME)); @@ -4150,7 +4138,7 @@ HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToB // Setup the arguments for the call ARG_SLOT args[2] = { - PtrToArgSlot(pManagedAssemblyLoadContextToBindWithin), // IntPtr for managed assembly load context instance + PtrToArgSlot(pAssemblyLoadContextToBindWithin), // IntPtr for managed assembly load context instance ObjToArgSlot(_gcRefs.oRefAssemblyName), // AssemblyName instance }; @@ -4197,7 +4185,7 @@ HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToB // Setup the arguments for the call ARG_SLOT args[2] = { - PtrToArgSlot(pManagedAssemblyLoadContextToBindWithin), // IntPtr for managed assembly load context instance + PtrToArgSlot(pAssemblyLoadContextToBindWithin), // IntPtr for managed assembly load context instance ObjToArgSlot(_gcRefs.oRefAssemblyName), // AssemblyName instance }; @@ -4226,7 +4214,7 @@ HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToB // Setup the arguments for the call ARG_SLOT args[2] = { - PtrToArgSlot(pManagedAssemblyLoadContextToBindWithin), // IntPtr for managed assembly load context instance + PtrToArgSlot(pAssemblyLoadContextToBindWithin), // IntPtr for managed assembly load context instance ObjToArgSlot(_gcRefs.oRefAssemblyName), // AssemblyName instance }; diff --git a/src/coreclr/vm/appdomain.hpp b/src/coreclr/vm/appdomain.hpp index a3098372ffd9ce..8a42c4d7cd213f 100644 --- a/src/coreclr/vm/appdomain.hpp +++ b/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, @@ -1231,26 +1230,6 @@ class AppDomain final static void ExceptionUnwind(Frame *pFrame); - BOOL IsActive() - { - LIMITED_METHOD_DAC_CONTRACT; - - return m_Stage >= STAGE_ACTIVE; - } - - BOOL IsValid() - { - LIMITED_METHOD_DAC_CONTRACT; - -#ifdef DACCESS_COMPILE - // We want to see all appdomains in SOS, even the about to be destructed ones. - // There is no risk of races under DAC, so we will pretend to be unconditionally valid. - return TRUE; -#else - return m_Stage > STAGE_CREATING; -#endif - } - static void RaiseExitProcessEvent(); Assembly* RaiseResourceResolveEvent(Assembly* pAssembly, LPCSTR szName); Assembly* RaiseTypeResolveEventThrowing(Assembly* pAssembly, LPCSTR szName, ASSEMBLYREF *pResultingAssemblyRef); @@ -1348,40 +1327,6 @@ class AppDomain final friend class Assembly; private: - enum Stage { - STAGE_CREATING, - STAGE_READYFORMANAGEDCODE, - STAGE_ACTIVE, - STAGE_OPEN, - // Don't delete the following *_DONOTUSE members and in case a new member needs to be added, - // add it at the end. The reason is that debugger stuff has its own copy of this enum and - // it can use the members that are marked as *_DONOTUSE here when debugging older version - // of the runtime. - STAGE_UNLOAD_REQUESTED_DONOTUSE, - STAGE_EXITING_DONOTUSE, - STAGE_EXITED_DONOTUSE, - STAGE_FINALIZING_DONOTUSE, - STAGE_FINALIZED_DONOTUSE, - STAGE_HANDLETABLE_NOACCESS_DONOTUSE, - STAGE_CLEARED_DONOTUSE, - STAGE_COLLECTED_DONOTUSE, - STAGE_CLOSED_DONOTUSE - }; - void SetStage(Stage stage) - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - STRESS_LOG1(LF_APPDOMAIN, LL_INFO100,"Updating AD stage, stage=%d\n",stage); - Stage lastStage=m_Stage; - while (lastStage !=stage) - lastStage = (Stage)InterlockedCompareExchange((LONG*)&m_Stage,stage,lastStage); - }; - // List of unloaded LoaderAllocators, protected by code:GetLoaderAllocatorReferencesLock (for now) LoaderAllocator * m_pDelayedLoaderAllocatorUnloadList; @@ -1441,8 +1386,6 @@ class AppDomain final RCWRefCache *m_pRCWRefCache; #endif // FEATURE_COMWRAPPERS - Volatile m_Stage; - ArrayList m_failedAssemblies; // @@ -1628,6 +1571,7 @@ struct cdac_data { static constexpr size_t RootAssembly = offsetof(AppDomain, m_pRootAssembly); static constexpr size_t DomainAssemblyList = offsetof(AppDomain, m_Assemblies) + offsetof(AppDomain::DomainAssemblyList, m_array); + static constexpr size_t FriendlyName = offsetof(AppDomain, m_friendlyName); }; typedef DPTR(class SystemDomain) PTR_SystemDomain; @@ -1937,7 +1881,8 @@ inline static BOOL IsUnderDomainLock() { LIMITED_METHOD_CONTRACT; return m_Syste template<> struct cdac_data { - static constexpr PTR_SystemDomain* SystemDomain = &SystemDomain::m_pSystemDomain; + static constexpr PTR_SystemDomain* SystemDomainPtr = &SystemDomain::m_pSystemDomain; + static constexpr size_t GlobalLoaderAllocator = offsetof(SystemDomain, m_GlobalAllocator); }; #endif // DACCESS_COMPILE diff --git a/src/coreclr/vm/arm/asmconstants.h b/src/coreclr/vm/arm/asmconstants.h index c19a2efbd8a68a..0f4840be10697a 100644 --- a/src/coreclr/vm/arm/asmconstants.h +++ b/src/coreclr/vm/arm/asmconstants.h @@ -123,8 +123,8 @@ ASMCONSTANTS_C_ASSERT(ASM__VTABLE_SLOTS_PER_CHUNK == VTABLE_SLOTS_PER_CHUNK) #define ASM__VTABLE_SLOTS_PER_CHUNK_LOG2 3 ASMCONSTANTS_C_ASSERT(ASM__VTABLE_SLOTS_PER_CHUNK_LOG2 == VTABLE_SLOTS_PER_CHUNK_LOG2) -#define VASigCookie__pNDirectILStub 0x4 -ASMCONSTANTS_C_ASSERT(VASigCookie__pNDirectILStub == offsetof(VASigCookie, pNDirectILStub)) +#define VASigCookie__pPInvokeILStub 0x4 +ASMCONSTANTS_C_ASSERT(VASigCookie__pPInvokeILStub == offsetof(VASigCookie, pPInvokeILStub)) #define CONTEXT_Pc 0x040 ASMCONSTANTS_C_ASSERT(CONTEXT_Pc == offsetof(T_CONTEXT,Pc)) diff --git a/src/coreclr/vm/arm/asmhelpers.S b/src/coreclr/vm/arm/asmhelpers.S index 231ea2fb156a69..1e485992c09ec9 100644 --- a/src/coreclr/vm/arm/asmhelpers.S +++ b/src/coreclr/vm/arm/asmhelpers.S @@ -187,8 +187,8 @@ ThePreStubPatchLabel: LEAF_END ThePreStubPatch, _TEXT // ------------------------------------------------------------------ -// The call in ndirect import precode points to this function. - NESTED_ENTRY NDirectImportThunk, _TEXT, NoHandler +// The call in PInvokeImportPrecode points to this function. + NESTED_ENTRY PInvokeImportThunk, _TEXT, NoHandler PROLOG_PUSH "{r0-r4,r7,r8,lr}" // Spill general argument registers, return address and PROLOG_STACK_SAVE_OFFSET r7, #20 @@ -198,17 +198,17 @@ ThePreStubPatchLabel: CHECK_STACK_ALIGNMENT mov r0, r12 - bl C_FUNC(NDirectImportWorker) + bl C_FUNC(PInvokeImportWorker) mov r12, r0 EPILOG_VPOP {d0-d7} EPILOG_POP "{r0-r4,r7,r8,lr}" - // If we got back from NDirectImportWorker, the MD has been successfully + // If we got back from PInvokeImportWorker, the MD has been successfully // linked. Proceed to execute the original DLL call. bx r12 - NESTED_END NDirectImportThunk, _TEXT + NESTED_END PInvokeImportThunk, _TEXT // ------------------------------------------------------------------ // void ResolveWorkerAsmStub(r0, r1, r2, r3, r4:IndirectionCellAndFlags, r12:DispatchToken) diff --git a/src/coreclr/vm/arm/cgencpu.h b/src/coreclr/vm/arm/cgencpu.h index 1d3c5c6a207123..1b019a0f2c5153 100644 --- a/src/coreclr/vm/arm/cgencpu.h +++ b/src/coreclr/vm/arm/cgencpu.h @@ -67,7 +67,7 @@ EXTERN_C void checkStack(void); #define JUMP_ALLOCATE_SIZE 8 // # bytes to allocate for a jump instruction #define BACK_TO_BACK_JUMP_ALLOCATE_SIZE 8 // # bytes to allocate for a back to back jump instruction -#define HAS_NDIRECT_IMPORT_PRECODE 1 +#define HAS_PINVOKE_IMPORT_PRECODE 1 EXTERN_C void getFPReturn(int fpSize, INT64 *pRetVal); EXTERN_C void setFPReturn(int fpSize, INT64 retVal); diff --git a/src/coreclr/vm/arm/pinvokestubs.S b/src/coreclr/vm/arm/pinvokestubs.S index b18d20f7d0c768..b102ae12d793e4 100644 --- a/src/coreclr/vm/arm/pinvokestubs.S +++ b/src/coreclr/vm/arm/pinvokestubs.S @@ -24,7 +24,7 @@ PROLOG_PUSH {\VASigCookieReg} // get the stub - ldr \VASigCookieReg, [\VASigCookieReg,#VASigCookie__pNDirectILStub] + ldr \VASigCookieReg, [\VASigCookieReg,#VASigCookie__pPInvokeILStub] // if null goto stub generation cbz \VASigCookieReg, \__PInvokeStubFuncName\()Label diff --git a/src/coreclr/vm/arm/thunktemplates.S b/src/coreclr/vm/arm/thunktemplates.S index b535090660a612..3e3e5987fd74a6 100644 --- a/src/coreclr/vm/arm/thunktemplates.S +++ b/src/coreclr/vm/arm/thunktemplates.S @@ -22,6 +22,7 @@ PAGE_SIZE = 4096 LEAF_ENTRY FixupPrecodeCode ldr pc, DATA_SLOT(FixupPrecode, Target) + dmb ldr r12, DATA_SLOT(FixupPrecode, MethodDesc) ldr pc, DATA_SLOT(FixupPrecode, PrecodeFixupThunk) LEAF_END_MARKED FixupPrecodeCode diff --git a/src/coreclr/vm/arm64/PInvokeStubs.asm b/src/coreclr/vm/arm64/PInvokeStubs.asm index 05e21ae22d16e4..180dca18de7f69 100644 --- a/src/coreclr/vm/arm64/PInvokeStubs.asm +++ b/src/coreclr/vm/arm64/PInvokeStubs.asm @@ -44,7 +44,7 @@ __PInvokeStubWorkerName SETS "$FuncPrefix":CC:"StubWorker" NESTED_ENTRY $__PInvokeStubFuncName ; get the stub - ldr x9, [$VASigCookieReg, #VASigCookie__pNDirectILStub] + ldr x9, [$VASigCookieReg, #VASigCookie__pPInvokeILStub] ; if null goto stub generation cbz x9, %0 diff --git a/src/coreclr/vm/arm64/asmconstants.h b/src/coreclr/vm/arm64/asmconstants.h index e8d32ab3b76dc9..b5b9de92ff4847 100644 --- a/src/coreclr/vm/arm64/asmconstants.h +++ b/src/coreclr/vm/arm64/asmconstants.h @@ -88,8 +88,8 @@ ASMCONSTANTS_C_ASSERT(CallDescrData__pTarget == offsetof(CallDescrD ASMCONSTANTS_C_ASSERT(CallDescrData__pRetBuffArg == offsetof(CallDescrData, pRetBuffArg)) ASMCONSTANTS_C_ASSERT(CallDescrData__returnValue == offsetof(CallDescrData, returnValue)) -#define VASigCookie__pNDirectILStub 0x8 -ASMCONSTANTS_C_ASSERT(VASigCookie__pNDirectILStub == offsetof(VASigCookie, pNDirectILStub)) +#define VASigCookie__pPInvokeILStub 0x8 +ASMCONSTANTS_C_ASSERT(VASigCookie__pPInvokeILStub == offsetof(VASigCookie, pPInvokeILStub)) #define SIZEOF__Frame 0x10 ASMCONSTANTS_C_ASSERT(SIZEOF__Frame == sizeof(Frame)); diff --git a/src/coreclr/vm/arm64/asmhelpers.S b/src/coreclr/vm/arm64/asmhelpers.S index 0d039e396321ed..801995254258d7 100644 --- a/src/coreclr/vm/arm64/asmhelpers.S +++ b/src/coreclr/vm/arm64/asmhelpers.S @@ -31,15 +31,15 @@ LEAF_END GetDataCacheZeroIDReg, _TEXT LEAF_END GetSveLengthFromOS, _TEXT // ------------------------------------------------------------------ -// The call in ndirect import precode points to this function. -NESTED_ENTRY NDirectImportThunk, _TEXT, NoHandler +// The call in PInvokeImportPrecode points to this function. +NESTED_ENTRY PInvokeImportThunk, _TEXT, NoHandler PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -224 SAVE_ARGUMENT_REGISTERS sp, 16 SAVE_FLOAT_ARGUMENT_REGISTERS sp, 96 mov x0, x12 - bl C_FUNC(NDirectImportWorker) + bl C_FUNC(PInvokeImportWorker) mov x12, x0 // pop the stack and restore original register state @@ -47,11 +47,11 @@ NESTED_ENTRY NDirectImportThunk, _TEXT, NoHandler RESTORE_ARGUMENT_REGISTERS sp, 16 EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 224 - // If we got back from NDirectImportWorker, the MD has been successfully + // If we got back from PInvokeImportWorker, the MD has been successfully // linked. Proceed to execute the original DLL call. EPILOG_BRANCH_REG x12 -NESTED_END NDirectImportThunk, _TEXT +NESTED_END PInvokeImportThunk, _TEXT // ------------------------------------------------------------------ @@ -695,27 +695,40 @@ NESTED_ENTRY InterpreterStub, _TEXT, NoHandler #endif INLINE_GETTHREAD x20 // thrashes x0 on Apple OSes (and possibly other arg registers on other Unixes) - // On Apple, the INLINE_GETTHREAD is guaranteed to not to thrash argument registers other than x0 - // On other Unixes, there is no such guarantee, so we need to always restore the argument registers + 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 + // 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 + SAVE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters + SAVE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters +#endif + + mov x0, x20 + bl C_FUNC(_ZN6Thread22GetInterpThreadContextEv) // Thread::GetInterpThreadContext + mov x11, x0 + #ifndef TARGET_APPLE - ldp x0, x1, [sp, #__PWTB_ArgumentRegisters + 8] - ldp x2, x3, [sp, #__PWTB_ArgumentRegisters + 0x18] - ldp x4, x5, [sp, #__PWTB_ArgumentRegisters + 0x28] - ldp x6, x7, [sp, #__PWTB_ArgumentRegisters + 0x38] - ldp q0, q1, [sp, #__PWTB_FloatArgumentRegisters] - ldp q2, q3, [sp, #__PWTB_FloatArgumentRegisters + 0x20] - ldp q4, q5, [sp, #__PWTB_FloatArgumentRegisters + 0x40] - ldp q6, q7, [sp, #__PWTB_FloatArgumentRegisters + 0x60] -#else // !TARGET_APPLE - // Restore the thrashed x0 +LOCAL_LABEL(HaveInterpThreadContext): +#endif + + RESTORE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters + RESTORE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters + +#ifdef TARGET_APPLE +LOCAL_LABEL(HaveInterpThreadContext): + // On Apple, the INLINE_GETTHREAD is guaranteed to not to thrash argument registers other than x0 + // So we restore just the x0 mov x0, x21 -#endif // !TARGET_APPLE +#endif // TARGET_APPLE ldr x9, [x19] // InterpMethod* ldr x9, [x9, #OFFSETOF__InterpMethod__pCallStub] add x10, x9, #OFFSETOF__CallStubHeader__Routines - ldr x9, [x20, #OFFSETOF__Thread__m_pInterpThreadContext] - ldr x9, [x9, #OFFSETOF__InterpThreadContext__pStackPointer] + ldr x9, [x11, #OFFSETOF__InterpThreadContext__pStackPointer] // x19 contains IR bytecode address // Copy the arguments to the interpreter stack, invoke the InterpExecMethod and load the return value ldr x11, [x10], #8 @@ -874,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. @@ -889,7 +926,62 @@ LOCAL_LABEL(StoreCopyLoop): bne LOCAL_LABEL(StoreCopyLoop) ldr x11, [x10], #8 EPILOG_BRANCH_REG x11 -LEAF_END Load_Stack +LEAF_END Store_Stack + +LEAF_ENTRY Load_Stack_Ref, _TEXT + ldr w11, [x10], #4 // SP offset + ldr w12, [x10], #4 // size of the value type + add x11, sp, x11 + str x9, [x11] + add x9, x9, x12 + // Align x9 to the stack slot size + add x9, x9, 7 + and x9, x9, 0xfffffffffffffff8 + ldr x11, [x10], #8 + EPILOG_BRANCH_REG x11 +LEAF_END Load_Stack_Ref, _TEXT + + +.macro Copy_Ref argReg + cmp x11, #16 + blt LOCAL_LABEL(CopyBy8\argReg) +LOCAL_LABEL(RefCopyLoop16\argReg): + ldp x13, x14, [\argReg], #16 + stp x13, x14, [x9], #16 + subs x11, x11, #16 + bgt LOCAL_LABEL(RefCopyLoop16\argReg) + beq LOCAL_LABEL(RefCopyDone\argReg) + add x11, x11, #16 +LOCAL_LABEL(CopyBy8\argReg): + cmp x11, #8 + blt LOCAL_LABEL(RefCopyLoop1\argReg) +LOCAL_LABEL(RefCopyLoop8\argReg): + ldr x13, [\argReg], #8 + str x13, [x9], #8 + subs x11, x11, #8 + bgt LOCAL_LABEL(RefCopyLoop8\argReg) + beq LOCAL_LABEL(RefCopyDone\argReg) + add x11, x11, #8 +LOCAL_LABEL(RefCopyLoop1\argReg): + ldrb w13, [\argReg], #1 + strb w13, [x9], #1 + subs x11, x11, #1 + bne LOCAL_LABEL(RefCopyLoop1\argReg) +LOCAL_LABEL(RefCopyDone\argReg): + // Align x9 to the stack slot size + add x9, x9, 7 + and x9, x9, 0xfffffffffffffff8 +.endm + +LEAF_ENTRY Store_Stack_Ref, _TEXT + ldr w12, [x10], #4 // SP offset + ldr w11, [x10], #4 // size of the value type + add x12, sp, x12 + ldr x12, [x12, #__PWTB_TransitionBlock + SIZEOF__TransitionBlock] + Copy_Ref x12 + ldr x11, [x10], #8 + EPILOG_BRANCH_REG x11 +LEAF_END Store_Stack_Ref, _TEXT #ifdef TARGET_APPLE @@ -932,34 +1024,7 @@ LEAF_END Store_Stack_4B LEAF_ENTRY Store_Ref_\argReg ldr x11, [x10], #8 // size of the value type - cmp x11, #16 - blt LOCAL_LABEL(CopyBy8\argReg) -LOCAL_LABEL(RefCopyLoop16\argReg): - ldp x13, x14, [\argReg], #16 - stp x13, x14, [x9], #16 - subs x11, x11, #16 - bgt LOCAL_LABEL(RefCopyLoop16\argReg) - beq LOCAL_LABEL(RefCopyDone\argReg) - add x11, x11, #16 -LOCAL_LABEL(CopyBy8\argReg): - cmp x11, #8 - blt LOCAL_LABEL(RefCopyLoop1\argReg) -LOCAL_LABEL(RefCopyLoop8\argReg): - ldr x13, [\argReg], #8 - str x13, [x9], #8 - subs x11, x11, #8 - bgt LOCAL_LABEL(RefCopyLoop8\argReg) - beq LOCAL_LABEL(RefCopyDone\argReg) - add x11, x11, #8 -LOCAL_LABEL(RefCopyLoop1\argReg): - ldrb w13, [\argReg], #1 - strb w13, [x9], #1 - subs x11, x11, #1 - bne LOCAL_LABEL(RefCopyLoop1\argReg) -LOCAL_LABEL(RefCopyDone\argReg): - // Align x9 to the stack slot size - add x9, x9, 7 - and x9, x9, 0xfffffffffffffff8 + Copy_Ref \argReg ldr x11, [x10], #8 EPILOG_BRANCH_REG x11 LEAF_END Store_Ref_\argReg @@ -1793,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/coreclr/vm/arm64/asmhelpers.asm b/src/coreclr/vm/arm64/asmhelpers.asm index edcd6d709ac032..72804cc6084350 100644 --- a/src/coreclr/vm/arm64/asmhelpers.asm +++ b/src/coreclr/vm/arm64/asmhelpers.asm @@ -7,7 +7,7 @@ IMPORT ExternalMethodFixupWorker IMPORT PreStubWorker - IMPORT NDirectImportWorker + IMPORT PInvokeImportWorker #ifdef FEATURE_VIRTUAL_STUB_DISPATCH IMPORT VSD_ResolveWorker #endif @@ -24,6 +24,8 @@ IMPORT HijackHandler IMPORT ThrowControlForThread #ifdef FEATURE_INTERPRETER + SETALIAS Thread_GetInterpThreadContext, ?GetInterpThreadContext@Thread@@QEAAPEAUInterpThreadContext@@XZ + IMPORT $Thread_GetInterpThreadContext IMPORT ExecuteInterpretedMethod #endif @@ -94,15 +96,15 @@ LEAF_END ; ------------------------------------------------------------------ -; The call in ndirect import precode points to this function. - NESTED_ENTRY NDirectImportThunk +; The call in PInvokeImportPrecode points to this function. + NESTED_ENTRY PInvokeImportThunk PROLOG_SAVE_REG_PAIR fp, lr, #-224! SAVE_ARGUMENT_REGISTERS sp, 16 SAVE_FLOAT_ARGUMENT_REGISTERS sp, 96 mov x0, x12 - bl NDirectImportWorker + bl PInvokeImportWorker mov x12, x0 ; pop the stack and restore original register state @@ -110,7 +112,7 @@ RESTORE_ARGUMENT_REGISTERS sp, 16 EPILOG_RESTORE_REG_PAIR fp, lr, #224! - ; If we got back from NDirectImportWorker, the MD has been successfully + ; If we got back from PInvokeImportWorker, the MD has been successfully ; linked. Proceed to execute the original DLL call. EPILOG_BRANCH_REG x12 @@ -1064,13 +1066,22 @@ JIT_PollGCRarePath INLINE_GETTHREAD x20, x19 + ldr x11, [x20, #OFFSETOF__Thread__m_pInterpThreadContext] + cbnz x11, HaveInterpThreadContext + + mov x0, x20 + bl $Thread_GetInterpThreadContext + mov x11, x0 + RESTORE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters + RESTORE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters + +HaveInterpThreadContext ; IR bytecode address mov x19, METHODDESC_REGISTER ldr x9, [METHODDESC_REGISTER] ldr x9, [x9, #OFFSETOF__InterpMethod__pCallStub] add x10, x9, #OFFSETOF__CallStubHeader__Routines - ldr x9, [x20, #OFFSETOF__Thread__m_pInterpThreadContext] - ldr x9, [x9, #OFFSETOF__InterpThreadContext__pStackPointer] + ldr x9, [x11, #OFFSETOF__InterpThreadContext__pStackPointer] ; x19 contains IR bytecode address ; Copy the arguments to the interpreter stack, invoke the InterpExecMethod and load the return value ldr x11, [x10], #8 @@ -1229,6 +1240,30 @@ JIT_PollGCRarePath 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 @@ -1247,13 +1282,23 @@ StoreCopyLoop bne StoreCopyLoop ldr x11, [x10], #8 EPILOG_BRANCH_REG x11 - LEAF_END Load_Stack - - MACRO - Store_Ref $argReg + LEAF_END Store_Stack - LEAF_ENTRY Store_Ref_$argReg - ldr x11, [x10], #8 ; size of the value type + LEAF_ENTRY Load_Stack_Ref + ldr w11, [x10], #4 ; SP offset + ldr w12, [x10], #4 ; size of the value type + add x11, sp, x11 + str x9, [x11] + add x9, x9, x12 + ; Align x9 to the stack slot size + add x9, x9, 7 + and x9, x9, 0xfffffffffffffff8 + ldr x11, [x10], #8 + EPILOG_BRANCH_REG x11 + LEAF_END Load_Stack_Ref + + MACRO + Copy_Ref $argReg cmp x11, #16 blt CopyBy8$argReg RefCopyLoop16$argReg @@ -1282,6 +1327,24 @@ RefCopyDone$argReg ; Align x9 to the stack slot size add x9, x9, 7 and x9, x9, 0xfffffffffffffff8 + MEND + + LEAF_ENTRY Store_Stack_Ref + ldr w12, [x10], #4 ; SP offset + ldr w11, [x10], #4 ; size of the value type + add x12, sp, x12 + ldr x12, [x12, #__PWTB_TransitionBlock + SIZEOF__TransitionBlock] + Copy_Ref x12 + ldr x11, [x10], #8 + EPILOG_BRANCH_REG x11 + LEAF_END Store_Stack_Ref + + MACRO + Store_Ref $argReg + + LEAF_ENTRY Store_Ref_$argReg + ldr x11, [x10], #8 ; size of the value type + Copy_Ref $argReg ldr x11, [x10], #8 EPILOG_BRANCH_REG x11 LEAF_END Store_Ref_$argReg @@ -2078,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/coreclr/vm/arm64/cgencpu.h b/src/coreclr/vm/arm64/cgencpu.h index 769c7ab31d702b..aa668e54a99a2a 100644 --- a/src/coreclr/vm/arm64/cgencpu.h +++ b/src/coreclr/vm/arm64/cgencpu.h @@ -60,7 +60,7 @@ extern PCODE GetPreStubEntryPoint(); #define JUMP_ALLOCATE_SIZE 16 // # bytes to allocate for a jump instruction #define BACK_TO_BACK_JUMP_ALLOCATE_SIZE 16 // # bytes to allocate for a back to back jump instruction -#define HAS_NDIRECT_IMPORT_PRECODE 1 +#define HAS_PINVOKE_IMPORT_PRECODE 1 #define HAS_FIXUP_PRECODE 1 diff --git a/src/coreclr/vm/arm64/pinvokestubs.S b/src/coreclr/vm/arm64/pinvokestubs.S index 84bb08bac1463a..de2a23cf06cb31 100644 --- a/src/coreclr/vm/arm64/pinvokestubs.S +++ b/src/coreclr/vm/arm64/pinvokestubs.S @@ -21,7 +21,7 @@ NESTED_ENTRY \__PInvokeStubFuncName, _TEXT, NoHandler // get the stub - ldr x9, [\VASigCookieReg, #VASigCookie__pNDirectILStub] + ldr x9, [\VASigCookieReg, #VASigCookie__pPInvokeILStub] // if null goto stub generation cbz x9, LOCAL_LABEL(\__PInvokeStubFuncName\()_0) diff --git a/src/coreclr/vm/arm64/stubs.cpp b/src/coreclr/vm/arm64/stubs.cpp index 8f01ee8ef5fca5..e26b8aac9ad5d0 100644 --- a/src/coreclr/vm/arm64/stubs.cpp +++ b/src/coreclr/vm/arm64/stubs.cpp @@ -318,6 +318,14 @@ void InlinedCallFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateF // Update the frame pointer in the current context. pRD->pCurrentContextPointers->Fp = (DWORD64 *)&m_pCalleeSavedFP; +#ifdef FEATURE_INTERPRETER + if ((m_Next != FRAME_TOP) && (m_Next->GetFrameIdentifier() == FrameIdentifier::InterpreterFrame)) + { + // If the next frame is an interpreter frame, we also need to set the first argument register to point to the interpreter frame. + SetFirstArgReg(pRD->pCurrentContext, dac_cast(m_Next)); + } +#endif // FEATURE_INTERPRETER + LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK InlinedCallFrame::UpdateRegDisplay_Impl(pc:%p, sp:%p)\n", pRD->ControlPC, pRD->SP)); RETURN; diff --git a/src/coreclr/vm/arm64/thunktemplates.S b/src/coreclr/vm/arm64/thunktemplates.S index bbbc490854721e..6320513b73e4c3 100644 --- a/src/coreclr/vm/arm64/thunktemplates.S +++ b/src/coreclr/vm/arm64/thunktemplates.S @@ -52,7 +52,7 @@ LEAF_END_MARKED StubPrecodeCodeTemplate, _TEXT // FixupPrecode // ---------- -#define FIXUP_PRECODE_CODESIZE 0x18 // 5 instructions, 4 bytes each (and we also have 4 bytes of padding) +#define FIXUP_PRECODE_CODESIZE 0x18 // 6 instructions, 4 bytes each #define FIXUP_PRECODE_DATASIZE 0x18 // 3 qwords .set FIXUP_PRECODE_NUM_THUNKS_PER_MAPPING,(THUNKS_MAP_SIZE / FIXUP_PRECODE_CODESIZE) @@ -62,10 +62,10 @@ LEAF_END_MARKED StubPrecodeCodeTemplate, _TEXT ldr x11, DATA_SLOT(FixupPrecode, Target, FIXUP_PRECODE_CODESIZE, FixupPrecodeCodeTemplate) br x11 + dmb ishld ldr x12, DATA_SLOT(FixupPrecode, MethodDesc, FIXUP_PRECODE_CODESIZE, FixupPrecodeCodeTemplate) ldr x11, DATA_SLOT(FixupPrecode, PrecodeFixupThunk, FIXUP_PRECODE_CODESIZE, FixupPrecodeCodeTemplate) br x11 - brk 0xf000 // Stubs need to be 24-byte in size to allow for the data to be 3 pointers IN_PAGE_INDEX = IN_PAGE_INDEX + 1 .endr @@ -81,7 +81,7 @@ LEAF_END_MARKED FixupPrecodeCodeTemplate, _TEXT // CallCountingStub // ---------- -#define CALLCOUNTING_CODESIZE 0x28 // 5 instructions, 4 bytes each (and we also have 4 bytes of padding) +#define CALLCOUNTING_CODESIZE 0x28 // 10 instructions, 4 bytes each #define CALLCOUNTING_DATASIZE 0x18 // 3 qwords .set CALLCOUNTING_NUM_THUNKS_PER_MAPPING, (THUNKS_MAP_SIZE / CALLCOUNTING_CODESIZE) @@ -99,7 +99,7 @@ LEAF_END_MARKED FixupPrecodeCodeTemplate, _TEXT 0: ldr x10, DATA_SLOT(CallCountingStub, TargetForThresholdReached, CALLCOUNTING_CODESIZE, CallCountingStubCodeTemplate) br x10 - brk 0xf000 // Stubs need to be 40-byte in size to allow for the data to be pointer aligned + brk 0xf000 // Stubs need to be aligned IN_PAGE_INDEX = IN_PAGE_INDEX + 1 .endr @@ -123,11 +123,15 @@ LEAF_END_MARKED CallCountingStubCodeTemplate, _TEXT ldr x10, DATA_SLOT(StubPrecode, Target) ldr x12, DATA_SLOT(StubPrecode, SecretParam) br x10 + brk 0xf000 // Stubs need to be 24-byte in size to allow for the data to be 3 pointers + brk 0xf000 // Stubs need to be 24-byte in size to allow for the data to be 3 pointers + brk 0xf000 // Stubs need to be 24-byte in size to allow for the data to be 3 pointers LEAF_END_MARKED StubPrecodeCode\STUB_PAGE_SIZE LEAF_ENTRY FixupPrecodeCode\STUB_PAGE_SIZE ldr x11, DATA_SLOT(FixupPrecode, Target) br x11 + dmb ishld ldr x12, DATA_SLOT(FixupPrecode, MethodDesc) ldr x11, DATA_SLOT(FixupPrecode, PrecodeFixupThunk) br x11 @@ -145,6 +149,7 @@ LOCAL_LABEL(StubStart\STUB_PAGE_SIZE): LOCAL_LABEL(CountReachedZero\STUB_PAGE_SIZE): ldr x10, DATA_SLOT(CallCountingStub, TargetForThresholdReached) br x10 + brk 0xf000 // Stubs need to be aligned in total size LEAF_END_MARKED CallCountingStubCode\STUB_PAGE_SIZE .endr diff --git a/src/coreclr/vm/array.cpp b/src/coreclr/vm/array.cpp index 5906f112756b44..ff13abd9422e96 100644 --- a/src/coreclr/vm/array.cpp +++ b/src/coreclr/vm/array.cpp @@ -900,7 +900,7 @@ Stub *GenerateArrayOpStub(ArrayMethodDesc* pMD) static const ILStubTypes stubTypes[3] = { ILSTUB_ARRAYOP_GET, ILSTUB_ARRAYOP_SET, ILSTUB_ARRAYOP_ADDRESS }; _ASSERTE(pMD->GetArrayFuncIndex() <= ARRAY_SIZE(stubTypes)); - NDirectStubFlags arrayOpStubFlag = (NDirectStubFlags)stubTypes[pMD->GetArrayFuncIndex()]; + PInvokeStubFlags arrayOpStubFlag = (PInvokeStubFlags)stubTypes[pMD->GetArrayFuncIndex()]; MethodDesc * pStubMD = ILStubCache::CreateAndLinkNewILStubMethodDesc(pMD->GetLoaderAllocator(), pMD->GetMethodTable(), diff --git a/src/coreclr/vm/assembly.cpp b/src/coreclr/vm/assembly.cpp index 95fd73a73ad64d..470bbfd1e23c2d 100644 --- a/src/coreclr/vm/assembly.cpp +++ b/src/coreclr/vm/assembly.cpp @@ -431,10 +431,7 @@ Assembly *Assembly::CreateDynamic(AssemblyBinder* pBinder, NativeAssemblyNamePar IfFailThrow(pAssemblyEmit->DefineAssembly(pAssemblyNameParts->_pPublicKeyOrToken, pAssemblyNameParts->_cbPublicKeyOrToken, hashAlgorithm, pAssemblyNameParts->_pName, &assemData, pAssemblyNameParts->_flags, &ma)); - pPEAssembly = PEAssembly::Create(pAssemblyEmit); - - // Set it as the fallback load context binder for the dynamic assembly being created - pPEAssembly->SetFallbackBinder(pBinder); + pPEAssembly = PEAssembly::Create(pAssemblyEmit, pBinder); } AppDomain* pDomain = ::GetAppDomain(); @@ -2365,7 +2362,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 @@ -2388,7 +2385,7 @@ DebuggerAssemblyControlFlags Assembly::ComputeDebuggingConfig() IfFailThrow(GetDebuggingCustomAttributes(&dacfFlags)); return (DebuggerAssemblyControlFlags)dacfFlags; #else // !DEBUGGING_SUPPORTED - return 0; + return DACF_NONE; #endif // DEBUGGING_SUPPORTED } @@ -2488,16 +2485,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/coreclr/vm/assemblybinder.cpp b/src/coreclr/vm/assemblybinder.cpp index e4c625046363e7..94b25361312754 100644 --- a/src/coreclr/vm/assemblybinder.cpp +++ b/src/coreclr/vm/assemblybinder.cpp @@ -168,7 +168,7 @@ void AssemblyBinder::AddLoadedAssembly(Assembly* loadedAssembly) void AssemblyBinder::GetNameForDiagnosticsFromManagedALC(INT_PTR managedALC, /* out */ SString& alcName) { - if (managedALC == GetAppDomain()->GetDefaultBinder()->GetManagedAssemblyLoadContext()) + if (managedALC == GetAppDomain()->GetDefaultBinder()->GetAssemblyLoadContext()) { alcName.Set(W("Default")); return; @@ -205,7 +205,7 @@ void AssemblyBinder::GetNameForDiagnostics(/*out*/ SString& alcName) } else { - GetNameForDiagnosticsFromManagedALC(GetManagedAssemblyLoadContext(), alcName); + GetNameForDiagnosticsFromManagedALC(GetAssemblyLoadContext(), alcName); } } diff --git a/src/coreclr/vm/assemblybinder.h b/src/coreclr/vm/assemblybinder.h index 8fa57302cfa401..640ef6c0a2f99d 100644 --- a/src/coreclr/vm/assemblybinder.h +++ b/src/coreclr/vm/assemblybinder.h @@ -37,14 +37,14 @@ class AssemblyBinder return &m_appContext; } - INT_PTR GetManagedAssemblyLoadContext() + INT_PTR GetAssemblyLoadContext() { - return m_ptrManagedAssemblyLoadContext; + return m_ptrAssemblyLoadContext; } - void SetManagedAssemblyLoadContext(INT_PTR ptrManagedDefaultBinderInstance) + void SetAssemblyLoadContext(INT_PTR ptrManagedDefaultBinderInstance) { - m_ptrManagedAssemblyLoadContext = ptrManagedDefaultBinderInstance; + m_ptrAssemblyLoadContext = ptrManagedDefaultBinderInstance; } NativeImage* LoadNativeImage(Module* componentModule, LPCUTF8 nativeImageName); @@ -125,9 +125,15 @@ class AssemblyBinder // A GC handle to the managed AssemblyLoadContext. // It is a long weak handle for collectible AssemblyLoadContexts and strong handle for non-collectible ones. - INT_PTR m_ptrManagedAssemblyLoadContext; + INT_PTR m_ptrAssemblyLoadContext; SArray m_loadedAssemblies; + friend struct cdac_data; }; +template<> +struct cdac_data +{ + static constexpr size_t AssemblyLoadContext = offsetof(AssemblyBinder, m_ptrAssemblyLoadContext); +}; #endif diff --git a/src/coreclr/vm/assemblynative.cpp b/src/coreclr/vm/assemblynative.cpp index fa3f45570e2fce..e9cfef6ea3d4ac 100644 --- a/src/coreclr/vm/assemblynative.cpp +++ b/src/coreclr/vm/assemblynative.cpp @@ -1168,7 +1168,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetImageRuntimeVersion(QCall::AssemblyH /*static*/ -extern "C" INT_PTR QCALLTYPE AssemblyNative_InitializeAssemblyLoadContext(INT_PTR ptrManagedAssemblyLoadContext, BOOL fRepresentsTPALoadContext, BOOL fIsCollectible) +extern "C" INT_PTR QCALLTYPE AssemblyNative_InitializeAssemblyLoadContext(INT_PTR ptrAssemblyLoadContext, BOOL fRepresentsTPALoadContext, BOOL fIsCollectible) { QCALL_CONTRACT; @@ -1220,17 +1220,17 @@ extern "C" INT_PTR QCALLTYPE AssemblyNative_InitializeAssemblyLoadContext(INT_PT loaderAllocator->ActivateManagedTracking(); } - IfFailThrow(CustomAssemblyBinder::SetupContext(pDefaultBinder, loaderAllocator, loaderAllocatorHandle, ptrManagedAssemblyLoadContext, &pCustomBinder)); + IfFailThrow(CustomAssemblyBinder::SetupContext(pDefaultBinder, loaderAllocator, loaderAllocatorHandle, ptrAssemblyLoadContext, &pCustomBinder)); ptrNativeAssemblyBinder = reinterpret_cast(pCustomBinder); } else { // We are initializing the managed instance of Assembly Load Context that would represent the TPA binder. // First, confirm we do not have an existing managed ALC attached to the TPA binder. - _ASSERTE(pDefaultBinder->GetManagedAssemblyLoadContext() == (INT_PTR)NULL); + _ASSERTE(pDefaultBinder->GetAssemblyLoadContext() == (INT_PTR)NULL); // Attach the managed TPA binding context with the native one. - pDefaultBinder->SetManagedAssemblyLoadContext(ptrManagedAssemblyLoadContext); + pDefaultBinder->SetAssemblyLoadContext(ptrAssemblyLoadContext); ptrNativeAssemblyBinder = reinterpret_cast(pDefaultBinder); } @@ -1262,7 +1262,7 @@ extern "C" INT_PTR QCALLTYPE AssemblyNative_GetLoadContextForAssembly(QCall::Ass { QCALL_CONTRACT; - INT_PTR ptrManagedAssemblyLoadContext = 0; + INT_PTR ptrAssemblyLoadContext = 0; BEGIN_QCALL; @@ -1273,13 +1273,13 @@ extern "C" INT_PTR QCALLTYPE AssemblyNative_GetLoadContextForAssembly(QCall::Ass if (!pAssemblyBinder->IsDefault()) { // Fetch the managed binder reference from the native binder instance - ptrManagedAssemblyLoadContext = pAssemblyBinder->GetManagedAssemblyLoadContext(); - _ASSERTE(ptrManagedAssemblyLoadContext != (INT_PTR)NULL); + ptrAssemblyLoadContext = pAssemblyBinder->GetAssemblyLoadContext(); + _ASSERTE(ptrAssemblyLoadContext != (INT_PTR)NULL); } END_QCALL; - return ptrManagedAssemblyLoadContext; + return ptrAssemblyLoadContext; } // static diff --git a/src/coreclr/vm/assemblynative.hpp b/src/coreclr/vm/assemblynative.hpp index 74a12cc25366de..4a5a930db6f2ab 100644 --- a/src/coreclr/vm/assemblynative.hpp +++ b/src/coreclr/vm/assemblynative.hpp @@ -110,7 +110,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetImageRuntimeVersion(QCall::AssemblyH extern "C" BOOL QCALLTYPE AssemblyNative_GetIsCollectible(QCall::AssemblyHandle pAssembly); -extern "C" INT_PTR QCALLTYPE AssemblyNative_InitializeAssemblyLoadContext(INT_PTR ptrManagedAssemblyLoadContext, BOOL fRepresentsTPALoadContext, BOOL fIsCollectible); +extern "C" INT_PTR QCALLTYPE AssemblyNative_InitializeAssemblyLoadContext(INT_PTR ptrAssemblyLoadContext, BOOL fRepresentsTPALoadContext, BOOL fIsCollectible); extern "C" void QCALLTYPE AssemblyNative_PrepareForAssemblyLoadContextRelease(INT_PTR ptrNativeAssemblyBinder, INT_PTR ptrManagedStrongAssemblyLoadContext); diff --git a/src/coreclr/vm/asyncthunks.cpp b/src/coreclr/vm/asyncthunks.cpp index a0ff27c49084e2..34777b22ad108e 100644 --- a/src/coreclr/vm/asyncthunks.cpp +++ b/src/coreclr/vm/asyncthunks.cpp @@ -18,7 +18,7 @@ bool MethodDesc::TryGenerateAsyncThunk(DynamicResolver** resolver, COR_ILMETHOD_ _ASSERTE(methodILDecoder != NULL); _ASSERTE(*resolver == NULL && *methodILDecoder == NULL); _ASSERTE(IsIL()); - _ASSERTE(GetRVA() == 0); + _ASSERTE(!HasILHeader()); if (!IsAsyncThunkMethod()) { @@ -448,13 +448,17 @@ void MethodDesc::EmitAsyncMethodThunk(MethodDesc* pAsyncOtherVariant, MetaSig& m MethodTable* pMTTaskOpen = CoreLibBinder::GetClass(CLASS__TASK_1); pMTTask = ClassLoader::LoadGenericInstantiationThrowing(pMTTaskOpen->GetModule(), pMTTaskOpen->GetCl(), Instantiation(&thLogicalRetType, 1)).GetMethodTable(); MethodTable* pMTTaskAwaiterOpen = CoreLibBinder::GetClass(CLASS__TASK_AWAITER_1); + thTaskAwaiter = ClassLoader::LoadGenericInstantiationThrowing(pMTTaskAwaiterOpen->GetModule(), pMTTaskAwaiterOpen->GetCl(), Instantiation(&thLogicalRetType, 1)); + mdGetAwaiter = CoreLibBinder::GetMethod(METHOD__TASK_1__GET_AWAITER); - mdGetAwaiter = pMTTask->GetParallelMethodDesc(mdGetAwaiter); + mdGetAwaiter = MethodDesc::FindOrCreateAssociatedMethodDesc(mdGetAwaiter, pMTTask, FALSE, Instantiation(), FALSE); + mdIsCompleted = CoreLibBinder::GetMethod(METHOD__TASK_AWAITER_1__GET_ISCOMPLETED); - mdIsCompleted = thTaskAwaiter.GetMethodTable()->GetParallelMethodDesc(mdIsCompleted); + mdIsCompleted = MethodDesc::FindOrCreateAssociatedMethodDesc(mdIsCompleted, thTaskAwaiter.GetMethodTable(), FALSE, Instantiation(), FALSE); + mdGetResult = CoreLibBinder::GetMethod(METHOD__TASK_AWAITER_1__GET_RESULT); - mdGetResult = thTaskAwaiter.GetMethodTable()->GetParallelMethodDesc(mdGetResult); + mdGetResult = MethodDesc::FindOrCreateAssociatedMethodDesc(mdGetResult, thTaskAwaiter.GetMethodTable(), FALSE, Instantiation(), FALSE); } DWORD localArg = 0; diff --git a/src/coreclr/vm/binder.cpp b/src/coreclr/vm/binder.cpp index b3ca67e5f24afd..6572465f15d621 100644 --- a/src/coreclr/vm/binder.cpp +++ b/src/coreclr/vm/binder.cpp @@ -1170,10 +1170,10 @@ void CoreLibBinder::CheckExtended() } } else - if (pMD->IsNDirect()) + if (pMD->IsPInvoke()) { - NDirectMethodDesc* pNMD = (NDirectMethodDesc*)pMD; - NDirect::PopulateNDirectMethodDesc(pNMD); + PInvokeMethodDesc* pNMD = (PInvokeMethodDesc*)pMD; + PInvoke::PopulatePInvokeMethodDesc(pNMD); if (pNMD->IsQCall() && QCallResolveDllImport(pNMD->GetEntrypointName()) == nullptr) { diff --git a/src/coreclr/vm/callcounting.cpp b/src/coreclr/vm/callcounting.cpp index dd2c912921b82d..dea3750dea0aef 100644 --- a/src/coreclr/vm/callcounting.cpp +++ b/src/coreclr/vm/callcounting.cpp @@ -7,6 +7,7 @@ #include "callcounting.h" #include "threadsuspend.h" +#include #ifndef DACCESS_COMPILE extern "C" void STDCALL OnCallCountThresholdReachedStub(); @@ -263,6 +264,8 @@ const CallCountingStub *CallCountingManager::CallCountingStubAllocator::Allocate allocationAddressHolder.SuppressRelease(); stub->Initialize(targetForMethod, remainingCallCountCell); + FlushCacheForDynamicMappedStub(stub, CallCountingStub::CodeSize); + return stub; } @@ -324,11 +327,13 @@ void CallCountingStub::StaticInitialize() // This should fail if the template is used on a platform which doesn't support the supported page size for templates ThrowHR(COR_E_EXECUTIONENGINE); } +#elif defined(TARGET_WASM) + // CallCountingStub is not implemented on WASM #else _ASSERTE((SIZE_T)((BYTE*)CallCountingStubCode_End - (BYTE*)CallCountingStubCode) <= CallCountingStub::CodeSize); #endif - InitializeLoaderHeapConfig(&s_callCountingHeapConfig, CallCountingStub::CodeSize, (void*)CallCountingStubCodeTemplate, CallCountingStub::GenerateCodePage); + InitializeLoaderHeapConfig(&s_callCountingHeapConfig, CallCountingStub::CodeSize, (void*)CallCountingStubCodeTemplate, CallCountingStub::GenerateCodePage, NULL); } #endif // DACCESS_COMPILE @@ -1021,7 +1026,7 @@ void CallCountingManager::StopAndDeleteAllCallCountingStubs() // will not be used after resuming the runtime. The following ensures that other threads will not use an old cached // entry point value that will not be valid. Do this here in case of exception later. MemoryBarrier(); // flush writes from this thread first to guarantee ordering - FlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); // At this point, allocated call counting stubs won't be used anymore. Call counting stubs and corresponding infos may // now be safely deleted. Note that call counting infos may not be deleted prior to this point because call counting diff --git a/src/coreclr/vm/callhelpers.cpp b/src/coreclr/vm/callhelpers.cpp index 00f7f1110d4756..4bf742d5078440 100644 --- a/src/coreclr/vm/callhelpers.cpp +++ b/src/coreclr/vm/callhelpers.cpp @@ -224,6 +224,10 @@ void * DispatchCallSimple( callDescrData.fpReturnSize = 0; callDescrData.pTarget = pTargetAddress; +#ifdef TARGET_WASM + PORTABILITY_ASSERT("wasm need to fill call description data"); +#endif + if ((dwDispatchCallSimpleFlags & DispatchCallSimple_CatchHandlerFoundNotification) != 0) { DispatchCallDebuggerWrapper( @@ -515,6 +519,9 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT * CallDescrData callDescrData; callDescrData.pSrc = pTransitionBlock + sizeof(TransitionBlock); +#ifdef TARGET_WASM + callDescrData.pTransitionBlock = (TransitionBlock*)pTransitionBlock; +#endif _ASSERTE((nStackBytes % TARGET_POINTER_SIZE) == 0); callDescrData.numStackSlots = nStackBytes / TARGET_POINTER_SIZE; #ifdef CALLDESCR_ARGREGS @@ -531,6 +538,10 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT * #endif callDescrData.fpReturnSize = fpReturnSize; callDescrData.pTarget = m_pCallTarget; +#ifdef TARGET_WASM + callDescrData.pMD = m_pMD; + callDescrData.nArgsSize = m_argIt.GetArgSize(); +#endif CallDescrWorkerWithHandler(&callDescrData); diff --git a/src/coreclr/vm/callhelpers.h b/src/coreclr/vm/callhelpers.h index 767ce238ac14fb..12b4a8da1af464 100644 --- a/src/coreclr/vm/callhelpers.h +++ b/src/coreclr/vm/callhelpers.h @@ -28,6 +28,13 @@ struct CallDescrData #endif UINT32 fpReturnSize; PCODE pTarget; +#ifdef TARGET_WASM + // method description is used to compile the method with the interpreter + MethodDesc* pMD; + // size of the arguments and the transition block are used to execute the method with the interpreter + size_t nArgsSize; + TransitionBlock* pTransitionBlock; +#endif #ifdef CALLDESCR_RETBUFFARGREG // Pointer to return buffer arg location diff --git a/src/coreclr/vm/callingconvention.h b/src/coreclr/vm/callingconvention.h index 98e6eee147fcd6..3d4abbee5358d4 100644 --- a/src/coreclr/vm/callingconvention.h +++ b/src/coreclr/vm/callingconvention.h @@ -641,6 +641,7 @@ class ArgIteratorTemplate : public ARGITERATOR_BASE int GetRetBuffArgOffset(); int GetVASigCookieOffset(); int GetParamTypeArgOffset(); + int GetAsyncContinuationArgOffset(); //------------------------------------------------------------ // Each time this is called, this returns a byte offset of the next @@ -675,6 +676,7 @@ class ArgIteratorTemplate : public ARGITERATOR_BASE // explicit arguments have been scanned is platform dependent. void GetThisLoc(ArgLocDesc * pLoc) { WRAPPER_NO_CONTRACT; GetSimpleLoc(GetThisOffset(), pLoc); } void GetParamTypeLoc(ArgLocDesc * pLoc) { WRAPPER_NO_CONTRACT; GetSimpleLoc(GetParamTypeArgOffset(), pLoc); } + void GetAsyncContinuationLoc(ArgLocDesc * pLoc) { WRAPPER_NO_CONTRACT; GetSimpleLoc(GetAsyncContinuationArgOffset(), pLoc); } void GetVASigCookieLoc(ArgLocDesc * pLoc) { WRAPPER_NO_CONTRACT; GetSimpleLoc(GetVASigCookieOffset(), pLoc); } #ifndef CALLDESCR_RETBUFFARGREG @@ -1000,21 +1002,26 @@ class ArgIteratorTemplate : public ARGITERATOR_BASE #endif enum { - ITERATION_STARTED = 0x0001, // Started iterating over arguments - SIZE_OF_ARG_STACK_COMPUTED = 0x0002, - RETURN_FLAGS_COMPUTED = 0x0004, - RETURN_HAS_RET_BUFFER = 0x0008, // Cached value of HasRetBuffArg + ITERATION_STARTED = 0x0001, // Started iterating over arguments + SIZE_OF_ARG_STACK_COMPUTED = 0x0002, + RETURN_FLAGS_COMPUTED = 0x0004, + RETURN_HAS_RET_BUFFER = 0x0008, // Cached value of HasRetBuffArg #ifdef TARGET_X86 - PARAM_TYPE_REGISTER_MASK = 0x0030, - PARAM_TYPE_REGISTER_STACK = 0x0010, - PARAM_TYPE_REGISTER_ECX = 0x0020, - PARAM_TYPE_REGISTER_EDX = 0x0030, + PARAM_TYPE_REGISTER_MASK = 0x0030, + PARAM_TYPE_REGISTER_STACK = 0x0010, + PARAM_TYPE_REGISTER_ECX = 0x0020, + PARAM_TYPE_REGISTER_EDX = 0x0030, + + ASYNC_CONTINUATION_REGISTER_MASK = 0x00C0, + ASYNC_CONTINUATION_REGISTER_STACK = 0x0040, + ASYNC_CONTINUATION_REGISTER_ECX = 0x0080, + ASYNC_CONTINUATION_REGISTER_EDX = 0x00C0, #endif - METHOD_INVOKE_NEEDS_ACTIVATION = 0x0040, // Flag used by ArgIteratorForMethodInvoke + METHOD_INVOKE_NEEDS_ACTIVATION = 0x0100, // Flag used by ArgIteratorForMethodInvoke - RETURN_FP_SIZE_SHIFT = 8, // The rest of the flags is cached value of GetFPReturnSize + RETURN_FP_SIZE_SHIFT = 10, // The rest of the flags is cached value of GetFPReturnSize }; void ComputeReturnFlags(); @@ -1158,6 +1165,68 @@ int ArgIteratorTemplate::GetParamTypeArgOffset() #endif } +template +int ArgIteratorTemplate::GetAsyncContinuationArgOffset() +{ + CONTRACTL + { + INSTANCE_CHECK; + if (FORBIDGC_LOADER_USE_ENABLED()) NOTHROW; else THROWS; + if (FORBIDGC_LOADER_USE_ENABLED()) GC_NOTRIGGER; else GC_TRIGGERS; + if (FORBIDGC_LOADER_USE_ENABLED()) FORBID_FAULT; else { INJECT_FAULT(COMPlusThrowOM()); } + MODE_ANY; + } + CONTRACTL_END + + _ASSERTE(this->HasAsyncContinuation()); + +#ifdef TARGET_X86 + // x86 is special as always + if (!(m_dwFlags & SIZE_OF_ARG_STACK_COMPUTED)) + ForceSigWalk(); + + switch (m_dwFlags & ASYNC_CONTINUATION_REGISTER_MASK) + { + case ASYNC_CONTINUATION_REGISTER_ECX: + return TransitionBlock::GetOffsetOfArgumentRegisters() + offsetof(ArgumentRegisters, ECX); + case ASYNC_CONTINUATION_REGISTER_EDX: + return TransitionBlock::GetOffsetOfArgumentRegisters() + offsetof(ArgumentRegisters, EDX); + default: + break; + } + + // If the async continuation is a stack arg, then it comes last unless + // there also is a param type arg on the stack, in which case it comes + // before it. + if (this->HasParamType() && (m_dwFlags & PARAM_TYPE_REGISTER_MASK) == PARAM_TYPE_REGISTER_STACK) + { + return sizeof(TransitionBlock) + sizeof(void*); + } + + return sizeof(TransitionBlock); +#else + // The hidden arg is after this, retbuf and param type arguments by default. + int ret = TransitionBlock::GetOffsetOfArgumentRegisters(); + + if (this->HasThis()) + { + ret += TARGET_POINTER_SIZE; + } + + if (this->HasRetBuffArg() && IsRetBuffPassedAsFirstArg()) + { + ret += TARGET_POINTER_SIZE; + } + + if (this->HasParamType()) + { + ret += TARGET_POINTER_SIZE; + } + + return ret; +#endif +} + // To avoid corner case bugs, limit maximum size of the arguments with sufficient margin #define MAX_ARG_SIZE 0xFFFFFF @@ -1190,6 +1259,11 @@ int ArgIteratorTemplate::GetNextOffset() { numRegistersUsed++; } + + if (this->HasAsyncContinuation()) + { + numRegistersUsed++; + } #endif #ifdef TARGET_X86 @@ -1223,6 +1297,10 @@ int ArgIteratorTemplate::GetNextOffset() m_idxGenReg = numRegistersUsed; m_ofsStack = 0; m_idxFPReg = 0; +#elif defined(TARGET_WASM) + // we put everything on the stack, we don't have registers + // WASM_TODO find out whether we can use implicit stack here + m_ofsStack = 0; #else PORTABILITY_ASSERT("ArgIteratorTemplate::GetNextOffset"); #endif @@ -1794,6 +1872,13 @@ int ArgIteratorTemplate::GetNextOffset() int argOfs = TransitionBlock::GetOffsetOfArgs() + m_ofsStack; m_ofsStack += ALIGN_UP(cbArg, TARGET_POINTER_SIZE); + return argOfs; +#elif defined(TARGET_WASM) + int cbArg = ALIGN_UP(StackElemSize(argSize), TARGET_POINTER_SIZE); + int argOfs = TransitionBlock::GetOffsetOfArgs() + m_ofsStack; + + m_ofsStack += cbArg; + return argOfs; #else PORTABILITY_ASSERT("ArgIteratorTemplate::GetNextOffset"); @@ -2002,6 +2087,23 @@ void ArgIteratorTemplate::ForceSigWalk() } } + if (this->HasAsyncContinuation()) + { + DWORD asyncContFlags = 0; + if (numRegistersUsed < NUM_ARGUMENT_REGISTERS) + { + numRegistersUsed++; + asyncContFlags = (numRegistersUsed == 1) ? + ASYNC_CONTINUATION_REGISTER_ECX : ASYNC_CONTINUATION_REGISTER_EDX; + } + else + { + nSizeOfArgStack += sizeof(void *); + asyncContFlags = ASYNC_CONTINUATION_REGISTER_STACK; + } + m_dwFlags |= asyncContFlags; + } + if (this->HasParamType()) { DWORD paramTypeFlags = 0; @@ -2139,25 +2241,19 @@ class ArgIteratorBase BOOL HasParamType() { LIMITED_METHOD_CONTRACT; - return m_pSig->GetCallingConventionInfo() & CORINFO_CALLCONV_PARAMTYPE; + return m_pSig->HasGenericContextArg(); } - BOOL IsVarArg() - { - LIMITED_METHOD_CONTRACT; - return m_pSig->IsVarArg() || m_pSig->IsTreatAsVarArg(); - } - - BOOL IsAsyncCall() + BOOL HasAsyncContinuation() { LIMITED_METHOD_CONTRACT; - return m_pSig->IsAsyncCall(); + return m_pSig->HasAsyncContinuation(); } - BOOL HasAsyncContinuation() + BOOL IsVarArg() { LIMITED_METHOD_CONTRACT; - return m_pSig->HasAsyncContinuation(); + return m_pSig->IsVarArg() || m_pSig->IsTreatAsVarArg(); } DWORD NumFixedArgs() diff --git a/src/coreclr/vm/callsiteinspect.cpp b/src/coreclr/vm/callsiteinspect.cpp index f4206d48a03ddb..5b8d502f9bb64a 100644 --- a/src/coreclr/vm/callsiteinspect.cpp +++ b/src/coreclr/vm/callsiteinspect.cpp @@ -200,7 +200,7 @@ namespace // return the object so it can be stored in the frame and // propagated to the root set - *(OBJECTREF*)&ret = (*src); + *(Object**)&ret = OBJECTREFToObject(*src); } } else if (CorTypeInfo::IsObjRef(typ)) @@ -211,7 +211,7 @@ namespace if (pvDest) SetObjectReference((OBJECTREF *)pvDest, *src); - *(OBJECTREF*)&ret = (*src); + *(Object**)&ret = OBJECTREFToObject(*src); } else { diff --git a/src/coreclr/vm/callstubgenerator.cpp b/src/coreclr/vm/callstubgenerator.cpp index 3cdfe7c68db14d..02f275d9b9506a 100644 --- a/src/coreclr/vm/callstubgenerator.cpp +++ b/src/coreclr/vm/callstubgenerator.cpp @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#ifdef FEATURE_INTERPRETER +#if defined(FEATURE_INTERPRETER) && !defined(TARGET_WASM) #include "callstubgenerator.h" #include "ecall.h" @@ -19,6 +19,11 @@ extern "C" void Store_Stack_2B(); extern "C" void Store_Stack_4B(); #endif // TARGET_APPLE && TARGET_ARM64 +#ifndef UNIX_AMD64_ABI +extern "C" void Load_Stack_Ref(); +extern "C" void Store_Stack_Ref(); +#endif // !UNIX_AMD64_ABI + #ifdef TARGET_AMD64 #ifdef TARGET_WINDOWS @@ -1029,6 +1034,14 @@ PCODE CallStubGenerator::GetGPRegRefRoutine(int r) return m_interpreterToNative ? GPRegsRefRoutines[r] : GPRegsRefStoreRoutines[r]; } +PCODE CallStubGenerator::GetStackRefRoutine() +{ +#if LOG_COMPUTE_CALL_STUB + printf("GetStackRefRoutine\n"); +#endif + return m_interpreterToNative ? (PCODE)Load_Stack_Ref : (PCODE)Store_Stack_Ref; +} + #endif // UNIX_AMD64_ABI PCODE CallStubGenerator::GetFPRegRangeRoutine(int x1, int x2) @@ -1077,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(); @@ -1085,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 @@ -1141,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"); @@ -1202,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"); @@ -1391,7 +1416,7 @@ void CallStubGenerator::ComputeCallStub(MetaSig &sig, PCODE *pRoutines) m_s1 = NoRange; // indicates that there is no active range of stack arguments m_s2 = 0; m_routineIndex = 0; - m_totalStackSize = 0; + m_totalStackSize = argIt.SizeOfArgStack(); #if LOG_COMPUTE_CALL_STUB printf("ComputeCallStub\n"); #endif @@ -1404,22 +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; - } - 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()) @@ -1516,7 +1527,6 @@ void CallStubGenerator::ComputeCallStub(MetaSig &sig, PCODE *pRoutines) } else if (m_s1 != NoRange) { - m_totalStackSize += m_s2 - m_s1 + 1; pRoutines[m_routineIndex++] = GetStackRoutine(); pRoutines[m_routineIndex++] = ((int64_t)(m_s2 - m_s1 + 1) << 32) | m_s1; } @@ -1560,7 +1570,6 @@ void CallStubGenerator::ProcessArgument(ArgIterator *pArgIt, ArgLocDesc& argLocD { // No stack argument is used to pass the current argument, but we already have a range of stack arguments, // store the routine for the range - m_totalStackSize += m_s2 - m_s1 + 1; pRoutines[m_routineIndex++] = GetStackRoutine(); pRoutines[m_routineIndex++] = ((int64_t)(m_s2 - m_s1 + 1) << 32) | m_s1; m_s1 = NoRange; @@ -1628,7 +1637,7 @@ void CallStubGenerator::ProcessArgument(ArgIterator *pArgIt, ArgLocDesc& argLocD m_s1 = argLocDesc.m_byteStackIndex; m_s2 = m_s1 + argLocDesc.m_byteStackSize - 1; } - else if ((argLocDesc.m_byteStackIndex == m_s2 + 1) && (argLocDesc.m_byteStackSize >= 8)) + else if ((argLocDesc.m_byteStackIndex == m_s2 + 1) && (argLocDesc.m_byteStackSize >= 8) && (!pArgIt || !pArgIt->IsArgPassedByRef())) { // Extend an existing range, but only if the argument is at least pointer size large. // The only case when this is not true is on Apple ARM64 OSes where primitive type smaller @@ -1639,7 +1648,6 @@ void CallStubGenerator::ProcessArgument(ArgIterator *pArgIt, ArgLocDesc& argLocD else { // Discontinuous range - store a routine for the current and start a new one - m_totalStackSize += m_s2 - m_s1 + 1; pRoutines[m_routineIndex++] = GetStackRoutine(); pRoutines[m_routineIndex++] = ((int64_t)(m_s2 - m_s1 + 1) << 32) | m_s1; m_s1 = argLocDesc.m_byteStackIndex; @@ -1677,10 +1685,19 @@ void CallStubGenerator::ProcessArgument(ArgIterator *pArgIt, ArgLocDesc& argLocD // we always process single argument passed by reference using single routine. if (pArgIt != NULL && pArgIt->IsArgPassedByRef()) { - _ASSERTE(argLocDesc.m_cGenReg == 1); - pRoutines[m_routineIndex++] = GetGPRegRefRoutine(argLocDesc.m_idxGenReg); - pRoutines[m_routineIndex++] = pArgIt->GetArgSize(); - m_r1 = NoRange; + if (argLocDesc.m_cGenReg == 1) + { + pRoutines[m_routineIndex++] = GetGPRegRefRoutine(argLocDesc.m_idxGenReg); + pRoutines[m_routineIndex++] = pArgIt->GetArgSize(); + m_r1 = NoRange; + } + else + { + _ASSERTE(argLocDesc.m_byteStackIndex != -1); + pRoutines[m_routineIndex++] = GetStackRefRoutine(); + pRoutines[m_routineIndex++] = ((int64_t)pArgIt->GetArgSize() << 32) | argLocDesc.m_byteStackIndex; + m_s1 = NoRange; + } } #endif // UNIX_AMD64_ABI } @@ -1700,7 +1717,7 @@ CallStubGenerator::ReturnType CallStubGenerator::GetReturnType(ArgIterator *pArg } #else return ReturnTypeBuff; -#endif +#endif } else { @@ -1818,8 +1835,28 @@ CallStubGenerator::ReturnType CallStubGenerator::GetReturnType(ArgIterator *pArg break; } break; + 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; default: - _ASSERTE(!"HFA types other than float and double are not supported yet"); + _ASSERTE(!"HFA type is not supported"); break; } } @@ -1854,4 +1891,4 @@ CallStubGenerator::ReturnType CallStubGenerator::GetReturnType(ArgIterator *pArg return ReturnTypeVoid; } -#endif // FEATURE_INTERPRETER +#endif // FEATURE_INTERPRETER && !TARGET_WASM diff --git a/src/coreclr/vm/callstubgenerator.h b/src/coreclr/vm/callstubgenerator.h index ee15fbcdbe4ca9..55ef6911480cdb 100644 --- a/src/coreclr/vm/callstubgenerator.h +++ b/src/coreclr/vm/callstubgenerator.h @@ -83,7 +83,9 @@ class CallStubGenerator ReturnTypeFloat, ReturnType2Float, ReturnType3Float, - ReturnType4Float + ReturnType4Float, + ReturnTypeVector64, + ReturnTypeVector128 #endif // TARGET_ARM64 }; @@ -109,6 +111,7 @@ class CallStubGenerator #ifndef UNIX_AMD64_ABI PCODE GetGPRegRefRoutine(int r); + PCODE GetStackRefRoutine(); #endif // !UNIX_AMD64_ABI PCODE GetStackRoutine(); #if defined(TARGET_APPLE) && defined(TARGET_ARM64) diff --git a/src/coreclr/vm/cdacplatformmetadata.cpp b/src/coreclr/vm/cdacplatformmetadata.cpp index 0c9c1233e94870..e616d10c82afde 100644 --- a/src/coreclr/vm/cdacplatformmetadata.cpp +++ b/src/coreclr/vm/cdacplatformmetadata.cpp @@ -3,20 +3,24 @@ #include "cdacplatformmetadata.hpp" -#ifndef DACCESS_COMPILE -CDacPlatformMetadata g_cdacPlatformMetadata; +GVAL_IMPL(CDacPlatformMetadata, g_cdacPlatformMetadata); +#ifndef DACCESS_COMPILE void CDacPlatformMetadata::Init() { - PrecodeMachineDescriptor::Init(&g_cdacPlatformMetadata.precode); #if defined(TARGET_ARM) - g_cdacPlatformMetadata.codePointerFlags = CDacCodePointerFlags::HasArm32ThumbBit; + (&g_cdacPlatformMetadata)->codePointerFlags = CDacCodePointerFlags::HasArm32ThumbBit; #elif defined(TARGET_ARM64) && defined(TARGET_APPLE) // TODO set HasArm64PtrAuth if arm64e - g_cdacPlatformMetadata.codePointerFlags = CDacCodePointerFlags::None; + (&g_cdacPlatformMetadata)->codePointerFlags = CDacCodePointerFlags::None; #else - g_cdacPlatformMetadata.codePointerFlags = CDacCodePointerFlags::None; + (&g_cdacPlatformMetadata)->codePointerFlags = CDacCodePointerFlags::None; #endif } +void CDacPlatformMetadata::InitPrecodes() +{ + PrecodeMachineDescriptor::Init(&(&g_cdacPlatformMetadata)->precode); +} + #endif // !DACCESS_COMPILE diff --git a/src/coreclr/vm/cdacplatformmetadata.hpp b/src/coreclr/vm/cdacplatformmetadata.hpp index 0ee94acab1a1ef..e89ccc540a3265 100644 --- a/src/coreclr/vm/cdacplatformmetadata.hpp +++ b/src/coreclr/vm/cdacplatformmetadata.hpp @@ -7,7 +7,6 @@ #include "precode.h" // Cross-cutting metadata for cDAC -#ifndef DACCESS_COMPILE enum class CDacCodePointerFlags : uint8_t { None = 0, @@ -24,10 +23,10 @@ struct CDacPlatformMetadata CDacPlatformMetadata(const CDacPlatformMetadata&) = delete; CDacPlatformMetadata& operator=(const CDacPlatformMetadata&) = delete; static void Init(); + static void InitPrecodes(); }; -extern CDacPlatformMetadata g_cdacPlatformMetadata; -#endif // DACCESS_COMPILE +GVAL_DECL(CDacPlatformMetadata, g_cdacPlatformMetadata); #endif// CDACPLATFORMMETADATA_HPP__ diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp index fe93cc357f34bf..adfe056bdbe20b 100644 --- a/src/coreclr/vm/ceeload.cpp +++ b/src/coreclr/vm/ceeload.cpp @@ -3355,11 +3355,11 @@ void Module::FixupVTables() iCurMethod++; #ifdef _DEBUG - if (pMD->IsNDirect()) + if (pMD->IsPInvoke()) { LOG((LF_INTEROP, LL_INFO10, "[0x%lx] <-- PINV thunk for \"%s\" (target = 0x%lx)\n", (size_t)&(pPointers[iMethod]), pMD->m_pszDebugMethodName, - (size_t)(((NDirectMethodDesc*)pMD)->GetNDirectTarget()))); + (size_t)(((PInvokeMethodDesc*)pMD)->GetPInvokeTarget()))); } #endif // _DEBUG @@ -3619,7 +3619,7 @@ void Module::RunEagerFixupsUnlocked() //----------------------------------------------------------------------------- -BOOL Module::FixupNativeEntry(READYTORUN_IMPORT_SECTION* pSection, SIZE_T fixupIndex, SIZE_T* fixupCell, BOOL mayUsePrecompiledNDirectMethods) +BOOL Module::FixupNativeEntry(READYTORUN_IMPORT_SECTION* pSection, SIZE_T fixupIndex, SIZE_T* fixupCell, BOOL mayUsePrecompiledPInvokeMethods) { CONTRACTL { @@ -3635,7 +3635,7 @@ BOOL Module::FixupNativeEntry(READYTORUN_IMPORT_SECTION* pSection, SIZE_T fixupI { PTR_DWORD pSignatures = dac_cast(GetReadyToRunImage()->GetRvaData(pSection->Signatures)); - if (!LoadDynamicInfoEntry(this, pSignatures[fixupIndex], fixupCell, mayUsePrecompiledNDirectMethods)) + if (!LoadDynamicInfoEntry(this, pSignatures[fixupIndex], fixupCell, mayUsePrecompiledPInvokeMethods)) return FALSE; _ASSERTE(*fixupCell != 0); @@ -3744,10 +3744,19 @@ void SaveManagedCommandLine(LPCWSTR pwzAssemblyPath, int argc, LPCWSTR *argv) #endif } +static bool g_fIJWLoaded = false; + void Module::SetIsIJWFixedUp() { LIMITED_METHOD_CONTRACT; InterlockedOr((LONG*)&m_dwTransientFlags, IS_IJW_FIXED_UP); + g_fIJWLoaded = true; +} + +bool Module::HasAnyIJWBeenLoaded() +{ + LIMITED_METHOD_CONTRACT; + return g_fIJWLoaded; } #endif // !DACCESS_COMPILE @@ -4348,7 +4357,7 @@ VASigCookie *Module::GetVASigCookieWorker(Module* pDefiningModule, Module* pLoad // Now, fill in the new cookie (assuming we had enough memory to create one.) pCookie->pModule = pDefiningModule; - pCookie->pNDirectILStub = 0; + pCookie->pPInvokeILStub = 0; pCookie->sizeOfArgs = sizeOfArgs; pCookie->signature = vaSignature; pCookie->pLoaderModule = pLoaderModule; @@ -4609,8 +4618,6 @@ void Module::EnumMemoryRegions(CLRDataEnumMemoryFlags flags, } } - ECall::EnumFCallMethods(); - #ifdef FEATURE_METADATA_UPDATER m_ClassList.EnumMemoryRegions(); diff --git a/src/coreclr/vm/ceeload.h b/src/coreclr/vm/ceeload.h index 32c1f1f04fcd50..3cea27da8fbcee 100644 --- a/src/coreclr/vm/ceeload.h +++ b/src/coreclr/vm/ceeload.h @@ -344,7 +344,7 @@ struct VASigCookie // The JIT wants knows that the size of the arguments comes first // so please keep this field first unsigned sizeOfArgs; // size of argument list - Volatile pNDirectILStub; // will be use if target is NDirect (tag == 0) + Volatile pPInvokeILStub; // will be use if target is PInvoke (tag == 0) PTR_Module pModule; PTR_Module pLoaderModule; Signature signature; @@ -1462,17 +1462,17 @@ class Module : public ModuleBase IMDInternalImport *GetNativeAssemblyImport(BOOL loadAllowed = TRUE); IMDInternalImport *GetNativeAssemblyImportIfLoaded(); - BOOL FixupNativeEntry(READYTORUN_IMPORT_SECTION * pSection, SIZE_T fixupIndex, SIZE_T *fixup, BOOL mayUsePrecompiledNDirectMethods = TRUE); + BOOL FixupNativeEntry(READYTORUN_IMPORT_SECTION * pSection, SIZE_T fixupIndex, SIZE_T *fixup, BOOL mayUsePrecompiledPInvokeMethods = TRUE); //this split exists to support new CLR Dump functionality in DAC. The //template removes any indirections. - BOOL FixupDelayList(TADDR pFixupList, BOOL mayUsePrecompiledNDirectMethods = TRUE); + BOOL FixupDelayList(TADDR pFixupList, BOOL mayUsePrecompiledPInvokeMethods = TRUE); template BOOL FixupDelayListAux(TADDR pFixupList, Ptr pThis, FixupNativeEntryCallback pfnCB, PTR_READYTORUN_IMPORT_SECTION pImportSections, COUNT_T nImportSections, - PEDecoder * pNativeImage, BOOL mayUsePrecompiledNDirectMethods = TRUE); + PEDecoder * pNativeImage, BOOL mayUsePrecompiledPInvokeMethods = TRUE); void RunEagerFixups(); void RunEagerFixupsUnlocked(); @@ -1513,6 +1513,8 @@ class Module : public ModuleBase BOOL IsIJWFixedUp() { return m_dwTransientFlags & IS_IJW_FIXED_UP; } void SetIsIJWFixedUp(); + static bool HasAnyIJWBeenLoaded(); + BOOL IsBeingUnloaded() { return m_dwTransientFlags & IS_BEING_UNLOADED; } void SetBeingUnloaded(); void StartUnload(); diff --git a/src/coreclr/vm/ceeload.inl b/src/coreclr/vm/ceeload.inl index 06a5001c23b22b..2067de38088fd9 100644 --- a/src/coreclr/vm/ceeload.inl +++ b/src/coreclr/vm/ceeload.inl @@ -338,21 +338,21 @@ inline mdAssemblyRef Module::FindAssemblyRef(Assembly *targetAssembly) #include "nibblestream.h" -FORCEINLINE BOOL Module::FixupDelayList(TADDR pFixupList, BOOL mayUsePrecompiledNDirectMethods) +FORCEINLINE BOOL Module::FixupDelayList(TADDR pFixupList, BOOL mayUsePrecompiledPInvokeMethods) { WRAPPER_NO_CONTRACT; COUNT_T nImportSections; PTR_READYTORUN_IMPORT_SECTION pImportSections = GetImportSections(&nImportSections); - return FixupDelayListAux(pFixupList, this, &Module::FixupNativeEntry, pImportSections, nImportSections, GetReadyToRunImage(), mayUsePrecompiledNDirectMethods); + return FixupDelayListAux(pFixupList, this, &Module::FixupNativeEntry, pImportSections, nImportSections, GetReadyToRunImage(), mayUsePrecompiledPInvokeMethods); } template BOOL Module::FixupDelayListAux(TADDR pFixupList, Ptr pThis, FixupNativeEntryCallback pfnCB, PTR_READYTORUN_IMPORT_SECTION pImportSections, COUNT_T nImportSections, - PEDecoder * pNativeImage, BOOL mayUsePrecompiledNDirectMethods) + PEDecoder * pNativeImage, BOOL mayUsePrecompiledPInvokeMethods) { CONTRACTL { @@ -442,7 +442,7 @@ BOOL Module::FixupDelayListAux(TADDR pFixupList, { CONSISTENCY_CHECK(fixupIndex * sizeof(TADDR) < cbData); - if (!(pThis->*pfnCB)(pImportSection, fixupIndex, dac_cast(pData + fixupIndex * sizeof(TADDR)), mayUsePrecompiledNDirectMethods)) + if (!(pThis->*pfnCB)(pImportSection, fixupIndex, dac_cast(pData + fixupIndex * sizeof(TADDR)), mayUsePrecompiledPInvokeMethods)) return FALSE; int delta = reader.ReadEncodedU32(); diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index 709b35510867c7..4be75dc9158969 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -663,7 +663,7 @@ void EEStartupHelper() Thread::StaticInitialize(); -#ifdef FEATURE_INTERPRETER +#if defined(FEATURE_INTERPRETER) && !defined(TARGET_WASM) InitCallStubGenerator(); #endif // FEATURE_INTERPRETER @@ -755,6 +755,8 @@ void EEStartupHelper() #endif // !TARGET_UNIX InitEventStore(); + UnwindInfoTable::Initialize(); + // Fire the runtime information ETW event ETW::InfoLog::RuntimeInformation(ETW::InfoLog::InfoStructs::Normal); @@ -804,6 +806,7 @@ void EEStartupHelper() StubLinkerCPU::Init(); StubPrecode::StaticInitialize(); FixupPrecode::StaticInitialize(); + CDacPlatformMetadata::InitPrecodes(); InitializeGarbageCollector(); @@ -822,9 +825,6 @@ void EEStartupHelper() // Static initialization SystemDomain::Attach(); - // Start up the EE initializing all the global variables - ECall::Init(); - COMDelegate::Init(); ExecutionManager::Init(); @@ -842,7 +842,9 @@ void EEStartupHelper() // Initialize the debugging services. This must be done before any // EE thread objects are created, and before any classes or // modules are loaded. +#ifndef TARGET_WASM InitializeDebugger(); // throws on error +#endif #endif // DEBUGGING_SUPPORTED #ifdef PROFILING_SUPPORTED @@ -920,7 +922,9 @@ void EEStartupHelper() } #endif -#ifndef TARGET_WINDOWS + // on wasm we need to run finalizers on main thread as we are single threaded + // active issue: https://github.com/dotnet/runtime/issues/114096 +#if !defined(TARGET_WINDOWS) && !defined(TARGET_WASM) // This isn't done as part of InitializeGarbageCollector() above because // debugger must be initialized before creating EE thread objects FinalizerThread::FinalizerThreadCreate(); @@ -1359,11 +1363,6 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading) { g_fEEShutDown |= ShutDown_Phase2; - // @TODO: This does things which shouldn't occur in part 2. Namely, - // calling managed dll main callbacks (AppDomain::SignalProcessDetach), and - // RemoveAppDomainFromIPC. - // - // (If we move those things to earlier, this can be called only if fShouldWeCleanup.) if (!g_fFastExitProcess) { SystemDomain::DetachBegin(); @@ -1703,7 +1702,17 @@ static void OsAttachThread(void* thread) if (t_flsState == FLS_STATE_INVOKED) { - _ASSERTE_ALL_BUILDS(!"Attempt to execute managed code after the .NET runtime thread state has been destroyed."); + // Managed C++ may run managed code in DllMain (e.g. during DLL_PROCESS_DETACH to run global destructors). This is + // not supported and unreliable. Historically, it happened to work most of the time. For backward compatibility, + // suppress this assert in release builds if we have encountered any mixed mode binaries. + if (Module::HasAnyIJWBeenLoaded()) + { + _ASSERTE(!"Attempt to execute managed code after the .NET runtime thread state has been destroyed."); + } + else + { + _ASSERTE_ALL_BUILDS(!"Attempt to execute managed code after the .NET runtime thread state has been destroyed."); + } } t_flsState = FLS_STATE_ARMED; diff --git a/src/coreclr/vm/class.cpp b/src/coreclr/vm/class.cpp index f29cafd3c5b055..71a03c6cf3d767 100644 --- a/src/coreclr/vm/class.cpp +++ b/src/coreclr/vm/class.cpp @@ -391,6 +391,8 @@ HRESULT EEClass::AddField(MethodTable* pMT, mdFieldDef fieldDef, FieldDesc** ppN LOG((LF_ENC, LL_INFO100, "EEClass::AddField Checking: %s mod:%p\n", pMod->GetDebugName(), pMod)); EETypeHashTable* paramTypes = pMod->GetAvailableParamTypes(); + CrstHolder ch(pMod->GetClassLoader()->GetAvailableTypesLock()); + EETypeHashTable::Iterator it(paramTypes); EETypeHashEntry* pEntry; while (paramTypes->FindNext(&it, &pEntry)) @@ -587,6 +589,8 @@ HRESULT EEClass::AddMethod(MethodTable* pMT, mdMethodDef methodDef, MethodDesc** LOG((LF_ENC, LL_INFO100, "EEClass::AddMethod Checking: %s mod:%p\n", pMod->GetDebugName(), pMod)); EETypeHashTable* paramTypes = pMod->GetAvailableParamTypes(); + CrstHolder ch(pMod->GetClassLoader()->GetAvailableTypesLock()); + EETypeHashTable::Iterator it(paramTypes); EETypeHashEntry* pEntry; while (paramTypes->FindNext(&it, &pEntry)) @@ -731,7 +735,7 @@ HRESULT EEClass::AddMethodDesc( dwImplFlags, dwMemberAttrs, TRUE, // fEnC - 0, // RVA - non-zero only for NDirect + 0, // RVA - non-zero only for PInvoke pImport, NULL, Signature(), @@ -1134,6 +1138,22 @@ void ClassLoader::LoadExactParents(MethodTable* pMT) EnsureLoaded(TypeHandle(pMT->GetCanonicalMethodTable()), CLASS_LOAD_EXACTPARENTS); } + if (pMT->GetClass()->HasRVAStaticFields()) + { + ApproxFieldDescIterator fdIterator(pMT, ApproxFieldDescIterator::STATIC_FIELDS); + FieldDesc* pFD = NULL; + while ((pFD = fdIterator.Next()) != NULL) + { + if (pFD->IsByValue() && pFD->IsRVA()) + { + if (pFD->GetApproxFieldTypeHandleThrowing().GetMethodTable()->GetClass()->HasFieldsWhichMustBeInited()) + { + ThrowHR(COR_E_BADIMAGEFORMAT); + } + } + } + } + LoadExactParentAndInterfacesTransitively(pMT); if (pMT->GetClass()->HasVTableMethodImpl()) @@ -1843,6 +1863,29 @@ EEClass::CheckForHFA() fieldHFAType = pFD->LookupApproxFieldTypeHandle().AsMethodTable()->GetHFAType(); #endif } + + int requiredAlignment; + switch (fieldHFAType) + { + case CORINFO_HFA_ELEM_FLOAT: + requiredAlignment = 4; + break; + case CORINFO_HFA_ELEM_VECTOR64: + case CORINFO_HFA_ELEM_DOUBLE: + requiredAlignment = 8; + break; + case CORINFO_HFA_ELEM_VECTOR128: + requiredAlignment = 16; + break; + default: + // VT without a valid HFA type inside of this struct means this struct is not an HFA + return false; + } + + if (requiredAlignment && (pFD->GetOffset() % requiredAlignment != 0)) // HFAs don't have unaligned fields. + { + return false; + } } break; @@ -2894,11 +2937,14 @@ WORD SparseVTableMap::GetNumVTableSlots() //******************************************************************************* void EEClass::AddChunk (MethodDescChunk* pNewChunk) { - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; - - _ASSERTE(pNewChunk->GetNextChunk() == NULL); + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + PRECONDITION(pNewChunk != NULL); + PRECONDITION(pNewChunk->GetNextChunk() == NULL); + } + CONTRACTL_END; MethodDescChunk* head = GetChunks(); @@ -2920,9 +2966,13 @@ void EEClass::AddChunk (MethodDescChunk* pNewChunk) //******************************************************************************* void EEClass::AddChunkIfItHasNotBeenAdded (MethodDescChunk* pNewChunk) { - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + PRECONDITION(pNewChunk != NULL); + } + CONTRACTL_END; // return if the chunk has been added if (pNewChunk->GetNextChunk() != NULL) diff --git a/src/coreclr/vm/class.h b/src/coreclr/vm/class.h index 2ea8c89349dd84..73f6c1a48520c7 100644 --- a/src/coreclr/vm/class.h +++ b/src/coreclr/vm/class.h @@ -1317,15 +1317,15 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! LIMITED_METHOD_CONTRACT; m_VMFlags |= (DWORD)VMFLAG_INLINE_ARRAY; } - DWORD HasNonPublicFields() + DWORD HasRVAStaticFields() { LIMITED_METHOD_CONTRACT; - return (m_VMFlags & VMFLAG_HASNONPUBLICFIELDS); + return (m_VMFlags & VMFLAG_HASRVASTATICFIELDS); } - void SetHasNonPublicFields() + void SetHasRVAStaticFields() { LIMITED_METHOD_CONTRACT; - m_VMFlags |= (DWORD)VMFLAG_HASNONPUBLICFIELDS; + m_VMFlags |= (DWORD)VMFLAG_HASRVASTATICFIELDS; } DWORD IsNotTightlyPacked() { @@ -1647,7 +1647,7 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! VMFLAG_INLINE_ARRAY = 0x00010000, VMFLAG_NO_GUID = 0x00020000, - VMFLAG_HASNONPUBLICFIELDS = 0x00040000, + VMFLAG_HASRVASTATICFIELDS = 0x00040000, VMFLAG_HAS_CUSTOM_FIELD_ALIGNMENT = 0x00080000, VMFLAG_CONTAINS_STACK_PTR = 0x00100000, VMFLAG_PREFER_ALIGN8 = 0x00200000, // Would like to have 8-byte alignment @@ -1799,9 +1799,13 @@ template<> struct cdac_data { static constexpr size_t InternalCorElementType = offsetof(EEClass, m_NormType); static constexpr size_t MethodTable = offsetof(EEClass, m_pMethodTable); + static constexpr size_t FieldDescList = offsetof(EEClass, m_pFieldDescList); static constexpr size_t MethodDescChunk = offsetof(EEClass, m_pChunks); static constexpr size_t NumMethods = offsetof(EEClass, m_NumMethods); static constexpr size_t CorTypeAttr = offsetof(EEClass, m_dwAttrClass); + static constexpr size_t NumInstanceFields = offsetof(EEClass, m_NumInstanceFields); + static constexpr size_t NumStaticFields = offsetof(EEClass, m_NumStaticFields); + static constexpr size_t NumThreadStaticFields = offsetof(EEClass, m_NumThreadStaticFields); static constexpr size_t NumNonVirtualSlots = offsetof(EEClass, m_NumNonVirtualSlots); }; @@ -2044,7 +2048,7 @@ inline PCODE GetPreStubEntryPoint() PCODE TheUMThunkPreStub(); -PCODE TheVarargNDirectStub(BOOL hasRetBuffArg); +PCODE TheVarargPInvokeStub(BOOL hasRetBuffArg); diff --git a/src/coreclr/vm/classcompat.cpp b/src/coreclr/vm/classcompat.cpp index 4f022ec115ec3d..82be81e0130308 100644 --- a/src/coreclr/vm/classcompat.cpp +++ b/src/coreclr/vm/classcompat.cpp @@ -2663,7 +2663,7 @@ VOID MethodTableBuilder::EnumerateClassMethods() if (IsReallyMdPinvokeImpl(dwMemberAttrs) || IsMiInternalCall(dwImplFlags)) { - hr = NDirect::HasNAT_LAttribute(pMDInternalImport, tok, dwMemberAttrs); + hr = PInvoke::HasNAT_LAttribute(pMDInternalImport, tok, dwMemberAttrs); // There was a problem querying for the attribute if (FAILED(hr)) @@ -2698,7 +2698,7 @@ VOID MethodTableBuilder::EnumerateClassMethods() else Classification = mcPInvoke; } - // The NAT_L attribute is present, marking this method as NDirect + // The NAT_L attribute is present, marking this method as PInvoke else { CONSISTENCY_CHECK(hr == S_OK); diff --git a/src/coreclr/vm/classlayoutinfo.cpp b/src/coreclr/vm/classlayoutinfo.cpp index db46373644622f..43b6781a74f07f 100644 --- a/src/coreclr/vm/classlayoutinfo.cpp +++ b/src/coreclr/vm/classlayoutinfo.cpp @@ -213,7 +213,7 @@ namespace LayoutRawFieldInfo* pfwalk = pFieldInfoArray; mdFieldDef fd; ULONG ulOffset; - UINT32 calcTotalSize = 0; + UINT32 calcTotalSize = parentSize; while (SUCCEEDED(hr = pInternalImport->GetClassLayoutNext( &classlayout, &fd, diff --git a/src/coreclr/vm/clrtocomcall.cpp b/src/coreclr/vm/clrtocomcall.cpp index c9e2ca3290cdd9..0e6add81fc3d87 100644 --- a/src/coreclr/vm/clrtocomcall.cpp +++ b/src/coreclr/vm/clrtocomcall.cpp @@ -35,7 +35,7 @@ // dllimport.cpp void CreateCLRToDispatchCOMStub( MethodDesc * pMD, - DWORD dwStubFlags // NDirectStubFlags + DWORD dwStubFlags // PInvokeStubFlags ); @@ -108,10 +108,10 @@ CLRToCOMCallInfo *CLRToCOMCall::PopulateCLRToCOMCallMethodDesc(MethodDesc* pMD, return pComInfo; // - // Compute NDirectStubFlags + // Compute PInvokeStubFlags // - DWORD dwStubFlags = NDIRECTSTUB_FL_COM; + DWORD dwStubFlags = PINVOKESTUB_FL_COM; // Determine if this is a special COM event call. BOOL fComEventCall = pItfMT->IsComEventItfType(); @@ -120,10 +120,10 @@ CLRToCOMCallInfo *CLRToCOMCall::PopulateCLRToCOMCallMethodDesc(MethodDesc* pMD, BOOL fLateBound = !fComEventCall && pItfMT->IsInterface() && pItfMT->GetComInterfaceType() == ifDispatch; if (fLateBound) - dwStubFlags |= NDIRECTSTUB_FL_COMLATEBOUND; + dwStubFlags |= PINVOKESTUB_FL_COMLATEBOUND; if (fComEventCall) - dwStubFlags |= NDIRECTSTUB_FL_COMEVENTCALL; + dwStubFlags |= PINVOKESTUB_FL_COMEVENTCALL; BOOL BestFit = TRUE; BOOL ThrowOnUnmappableChar = FALSE; @@ -131,10 +131,10 @@ CLRToCOMCallInfo *CLRToCOMCall::PopulateCLRToCOMCallMethodDesc(MethodDesc* pMD, ReadBestFitCustomAttribute(pMD, &BestFit, &ThrowOnUnmappableChar); if (BestFit) - dwStubFlags |= NDIRECTSTUB_FL_BESTFIT; + dwStubFlags |= PINVOKESTUB_FL_BESTFIT; if (ThrowOnUnmappableChar) - dwStubFlags |= NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR; + dwStubFlags |= PINVOKESTUB_FL_THROWONUNMAPPABLECHAR; // // fill in out param @@ -154,7 +154,7 @@ MethodDesc* CLRToCOMCall::GetILStubMethodDesc(MethodDesc* pMD, DWORD dwStubFlags // Get the call signature information StubSigDesc sigDesc(pMD); - return NDirect::CreateCLRToNativeILStub( + return PInvoke::CreateCLRToNativeILStub( &sigDesc, (CorNativeLinkType)0, (CorNativeLinkFlags)0, @@ -347,7 +347,7 @@ UINT32 CLRToCOMEventCallWorker(CLRToCOMMethodFrame* pFrame, CLRToCOMCallMethodDe MethodDescCallSite eventProvider(pEvProvMD, &gc.EventProviderObj); // Retrieve the event handler passed in. - OBJECTREF EventHandlerObj = *(OBJECTREF*)(pFrame->GetTransitionBlock() + ArgItr.GetNextOffset()); + OBJECTREF EventHandlerObj = ObjectToOBJECTREF(*(Object**)(pFrame->GetTransitionBlock() + ArgItr.GetNextOffset())); ARG_SLOT EventMethArgs[] = { diff --git a/src/coreclr/vm/clsload.cpp b/src/coreclr/vm/clsload.cpp index 09b9b44bbeaee5..72ca527baa01c4 100644 --- a/src/coreclr/vm/clsload.cpp +++ b/src/coreclr/vm/clsload.cpp @@ -1735,7 +1735,7 @@ VOID ClassLoader::Init(AllocMemTracker *pamTracker) // This lock is taken within the classloader whenever we have to insert a new param. type into the table. m_AvailableTypesLock.Init( CrstAvailableParamTypes, - CRST_DEBUGGER_THREAD); + CrstFlags(CRST_DEBUGGER_THREAD | CRST_GC_NOTRIGGER_WHEN_TAKEN | CRST_UNSAFE_ANYMODE)); #ifdef _DEBUG CorTypeInfo::CheckConsistency(); diff --git a/src/coreclr/vm/clsload.hpp b/src/coreclr/vm/clsload.hpp index ee7a8ca2f9dac6..c50dd4a5fc7987 100644 --- a/src/coreclr/vm/clsload.hpp +++ b/src/coreclr/vm/clsload.hpp @@ -533,6 +533,13 @@ class ClassLoader public: + + CrstBase *GetAvailableTypesLock() + { + LIMITED_METHOD_CONTRACT; + return &m_AvailableTypesLock; + } + //#LoaderModule // LoaderModule determines in which module an item gets placed. // For everything except parameterized types and methods the choice is easy. diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index d1a6a75e7d3efd..03aaed2aa9515f 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -77,7 +77,7 @@ unsigned ExecutionManager::m_LCG_JumpStubBlockFullCount; #endif // DACCESS_COMPILE -#if defined(TARGET_AMD64) && !defined(DACCESS_COMPILE) // We don't do this on ARM just amd64 +#if defined(TARGET_AMD64) && defined(TARGET_WINDOWS) && !defined(DACCESS_COMPILE) // Support for new style unwind information (to allow OS to stack crawl JIT compiled code). @@ -91,67 +91,42 @@ typedef VOID (WINAPI* RtlDeleteGrowableFunctionTableFnPtr) (PVOID DynamicTable); static RtlAddGrowableFunctionTableFnPtr pRtlAddGrowableFunctionTable; static RtlGrowFunctionTableFnPtr pRtlGrowFunctionTable; static RtlDeleteGrowableFunctionTableFnPtr pRtlDeleteGrowableFunctionTable; -static Volatile RtlUnwindFtnsInited; -// statics for UnwindInfoTable -Crst* UnwindInfoTable::s_pUnwindInfoTableLock = NULL; -Volatile UnwindInfoTable::s_publishingActive = false; - - -#if _DEBUG -// Fake functions on Win7 checked build to excercize the code paths, they are no-ops -NTSTATUS WINAPI FakeRtlAddGrowableFunctionTable ( - PVOID *DynamicTable, PT_RUNTIME_FUNCTION FunctionTable, ULONG EntryCount, - ULONG MaximumEntryCount, ULONG_PTR rangeStart, ULONG_PTR rangeEnd) { *DynamicTable = (PVOID) 1; return 0; } -VOID WINAPI FakeRtlGrowFunctionTable (PVOID DynamicTable, ULONG NewEntryCount) { } -VOID WINAPI FakeRtlDeleteGrowableFunctionTable (PVOID DynamicTable) {} -#endif +static bool s_publishingActive; // Publishing to ETW is turned on +static Crst* s_pUnwindInfoTableLock; // lock protects all public UnwindInfoTable functions /****************************************************************************/ // initialize the entry points for new win8 unwind info publishing functions. // return true if the initialize is successful (the functions exist) - bool InitUnwindFtns() { - CONTRACTL { + CONTRACTL + { NOTHROW; - } CONTRACTL_END; + GC_NOTRIGGER; + } + CONTRACTL_END; -#ifndef TARGET_UNIX - if (!RtlUnwindFtnsInited) + HINSTANCE hNtdll = GetModuleHandle(W("ntdll.dll")); + if (hNtdll != NULL) { - HINSTANCE hNtdll = GetModuleHandle(W("ntdll.dll")); - if (hNtdll != NULL) - { - void* growFunctionTable = GetProcAddress(hNtdll, "RtlGrowFunctionTable"); - void* deleteGrowableFunctionTable = GetProcAddress(hNtdll, "RtlDeleteGrowableFunctionTable"); - void* addGrowableFunctionTable = GetProcAddress(hNtdll, "RtlAddGrowableFunctionTable"); - - // All or nothing AddGroableFunctionTable is last (marker) - if (growFunctionTable != NULL && - deleteGrowableFunctionTable != NULL && - addGrowableFunctionTable != NULL) - { - pRtlGrowFunctionTable = (RtlGrowFunctionTableFnPtr) growFunctionTable; - pRtlDeleteGrowableFunctionTable = (RtlDeleteGrowableFunctionTableFnPtr) deleteGrowableFunctionTable; - pRtlAddGrowableFunctionTable = (RtlAddGrowableFunctionTableFnPtr) addGrowableFunctionTable; - } - // Don't call FreeLibrary(hNtdll) because GetModuleHandle did *NOT* increment the reference count! - } - else + void* growFunctionTable = GetProcAddress(hNtdll, "RtlGrowFunctionTable"); + void* deleteGrowableFunctionTable = GetProcAddress(hNtdll, "RtlDeleteGrowableFunctionTable"); + void* addGrowableFunctionTable = GetProcAddress(hNtdll, "RtlAddGrowableFunctionTable"); + + // All or nothing AddGroableFunctionTable is last (marker) + if (growFunctionTable != NULL && + deleteGrowableFunctionTable != NULL && + addGrowableFunctionTable != NULL) { -#if _DEBUG - pRtlGrowFunctionTable = FakeRtlGrowFunctionTable; - pRtlDeleteGrowableFunctionTable = FakeRtlDeleteGrowableFunctionTable; - pRtlAddGrowableFunctionTable = FakeRtlAddGrowableFunctionTable; -#endif + pRtlGrowFunctionTable = (RtlGrowFunctionTableFnPtr) growFunctionTable; + pRtlDeleteGrowableFunctionTable = (RtlDeleteGrowableFunctionTableFnPtr) deleteGrowableFunctionTable; + pRtlAddGrowableFunctionTable = (RtlAddGrowableFunctionTableFnPtr) addGrowableFunctionTable; } - RtlUnwindFtnsInited = true; + // Don't call FreeLibrary(hNtdll) because GetModuleHandle did *NOT* increment the reference count! } + return (pRtlAddGrowableFunctionTable != NULL); -#else // !TARGET_UNIX - return false; -#endif // !TARGET_UNIX } /****************************************************************************/ @@ -349,10 +324,12 @@ void UnwindInfoTable::AddToUnwindInfoTable(UnwindInfoTable** unwindInfoPtr, PT_R /*****************************************************************************/ /* static */ void UnwindInfoTable::RemoveFromUnwindInfoTable(UnwindInfoTable** unwindInfoPtr, TADDR baseAddress, TADDR entryPoint) { - CONTRACTL { + CONTRACTL + { NOTHROW; - GC_TRIGGERS; - } CONTRACTL_END; + GC_NOTRIGGER; + } + CONTRACTL_END; _ASSERTE(unwindInfoPtr != NULL); if (!s_publishingActive) @@ -405,10 +382,13 @@ void UnwindInfoTable::AddToUnwindInfoTable(UnwindInfoTable** unwindInfoPtr, PT_R /*****************************************************************************/ /* static */ void UnwindInfoTable::UnpublishUnwindInfoForMethod(TADDR entryPoint) { - CONTRACTL { + CONTRACTL + { NOTHROW; - GC_TRIGGERS; - } CONTRACTL_END; + GC_NOTRIGGER; + } + CONTRACTL_END; + if (!s_publishingActive) return; @@ -429,187 +409,153 @@ void UnwindInfoTable::AddToUnwindInfoTable(UnwindInfoTable** unwindInfoPtr, PT_R } /*****************************************************************************/ -// Publish all existing JIT compiled methods by iterating through the code heap -// Note that because we need to keep the entries in order we have to hold -// s_pUnwindInfoTableLock so that all entries get inserted in the correct order. -// (we rely on heapIterator walking the methods in a heap section in order). - -/* static */ void UnwindInfoTable::PublishUnwindInfoForExistingMethods() +// We only do this on Windows x64 (other platforms use frame-based stack crawling), +// We want good stack traces so we need to publish unwind information so ETW can +// walk the stack. +/* static */ void UnwindInfoTable::Initialize() { - STANDARD_VM_CONTRACT; + CONTRACTL { - // CodeHeapIterator holds the m_CodeHeapCritSec, which ensures code heaps don't get deallocated while being walked - EEJitManager::CodeHeapIterator heapIterator(NULL); - - // Currently m_CodeHeapCritSec is given the CRST_UNSAFE_ANYMODE flag which allows it to be taken in a GC_NOTRIGGER - // region but also disallows GC_TRIGGERS. We need GC_TRIGGERS because we take another lock. Ideally we would - // fix m_CodeHeapCritSec to not have the CRST_UNSAFE_ANYMODE flag, but I currently reached my threshold for fixing - // contracts. - CONTRACT_VIOLATION(GCViolation); - - while(heapIterator.Next()) - { - MethodDesc *pMD = heapIterator.GetMethod(); - if(pMD) - { - PCODE methodEntry =(PCODE) heapIterator.GetMethodCode(); - RangeSection * pRS = ExecutionManager::FindCodeRange(methodEntry, ExecutionManager::GetScanFlags()); - _ASSERTE(pRS != NULL); - _ASSERTE(pRS->_pjit->GetCodeType() == (miManaged | miIL)); - if (pRS != NULL && pRS->_pjit->GetCodeType() == (miManaged | miIL)) - { - // This cast is justified because only EEJitManager's have the code type above. - EEJitManager* pJitMgr = (EEJitManager*)(pRS->_pjit); - CodeHeader * pHeader = pJitMgr->GetCodeHeaderFromStartAddress(methodEntry); - int unwindInfoCount = pHeader->GetNumberOfUnwindInfos(); - for(int i = 0; i < unwindInfoCount; i++) - AddToUnwindInfoTable(&pRS->_pUnwindInfoTable, pHeader->GetUnwindInfo(i), pRS->_range.RangeStart(), pRS->_range.RangeEndOpen()); - } - } - } + THROWS; + GC_NOTRIGGER; } -} - -/*****************************************************************************/ -// turn on the publishing of unwind info. Called when the ETW rundown provider -// is turned on. - -/* static */ void UnwindInfoTable::PublishUnwindInfo(bool publishExisting) -{ - CONTRACTL { - NOTHROW; - GC_TRIGGERS; - } CONTRACTL_END; + CONTRACTL_END; - if (s_publishingActive) - return; + _ASSERTE(!s_publishingActive); // If we don't have the APIs we need, give up if (!InitUnwindFtns()) return; - EX_TRY - { - // Create the lock - Crst* newCrst = new Crst(CrstUnwindInfoTableLock); - if (InterlockedCompareExchangeT(&s_pUnwindInfoTableLock, newCrst, NULL) == NULL) - { - s_publishingActive = true; - if (publishExisting) - PublishUnwindInfoForExistingMethods(); - } - else - delete newCrst; // we were in a race and failed, throw away the Crst we made. - - } EX_CATCH { - STRESS_LOG1(LF_JIT, LL_ERROR, "Exception happened when doing unwind Info rundown. EIP of last AV = %p\n", g_LastAccessViolationEIP); - _ASSERTE(!"Exception thrown while publishing 'catchup' ETW unwind information"); - s_publishingActive = false; // Try to minimize damage. - } EX_END_CATCH + // Create the lock + s_pUnwindInfoTableLock = new Crst(CrstUnwindInfoTableLock); + s_publishingActive = true; } -#endif // defined(TARGET_AMD64) && !defined(DACCESS_COMPILE) - -/*----------------------------------------------------------------------------- - This is a listing of which methods uses which synchronization mechanism - in the EECodeGenManager. -//----------------------------------------------------------------------------- +#else +/* static */ void UnwindInfoTable::PublishUnwindInfoForMethod(TADDR baseAddress, T_RUNTIME_FUNCTION* unwindInfo, int unwindInfoCount) +{ + LIMITED_METHOD_CONTRACT; +} -Setters of EECodeGenManager::m_CodeHeapCritSec ------------------------------------------------ -allocCode -allocFromJitMetaHeap -allocJumpStubBlock -ResolveEHClause -RemoveJitData -Unload -ReleaseReferenceToHeap -JitCodeToMethodInfo - - -Need EECodeGenManager::m_CodeHeapCritSec to be set ------------------------------------------------ -NewCodeHeap -allocCodeRaw -GetCodeHeapList -RemoveCodeHeapFromDomainList -DeleteCodeHeap -AddRangeToJitHeapCache -DeleteJitHeapCache +/* static */ void UnwindInfoTable::UnpublishUnwindInfoForMethod(TADDR entryPoint) +{ + LIMITED_METHOD_CONTRACT; +} -*/ +/* static */ void UnwindInfoTable::Initialize() +{ + LIMITED_METHOD_CONTRACT; +} +#endif // defined(TARGET_AMD64) && defined(TARGET_WINDOWS) && !defined(DACCESS_COMPILE) #if !defined(DACCESS_COMPILE) -EEJitManager::CodeHeapIterator::CodeHeapIterator(LoaderAllocator *pLoaderAllocatorFilter) - : m_lockHolder(&(ExecutionManager::GetEEJitManager()->m_CodeHeapCritSec)), m_Iterator(NULL, 0, NULL, 0) +CodeHeapIterator::CodeHeapIterator(EECodeGenManager* manager, HeapList* heapList, LoaderAllocator* pLoaderAllocatorFilter) + : m_manager(manager) + , m_Iterator{} + , m_Heaps{} + , m_HeapsIndexNext{ 0 } + , m_pLoaderAllocatorFilter{ pLoaderAllocatorFilter } + , m_pCurrent{ NULL } { CONTRACTL { - NOTHROW; + THROWS; GC_NOTRIGGER; - MODE_ANY; + PRECONDITION(m_manager != NULL); } CONTRACTL_END; - m_pHeapList = NULL; - m_pLoaderAllocator = pLoaderAllocatorFilter; - m_pHeapList = ExecutionManager::GetEEJitManager()->GetCodeHeapList(); - if(m_pHeapList) - new (&m_Iterator) MethodSectionIterator((const void *)m_pHeapList->mapBase, (COUNT_T)m_pHeapList->maxCodeHeapSize, m_pHeapList->pHdrMap, (COUNT_T)HEAP2MAPSIZE(ROUND_UP_TO_PAGE(m_pHeapList->maxCodeHeapSize))); -}; + // Iterator through the heap list collecting the current state of the heaps. + HeapList* current = heapList; + while (current) + { + HeapListState* state = m_Heaps.AppendThrowing(); + state->Heap = current; + state->MapBase = (void*)current->mapBase; + state->HdrMap = current->pHdrMap; + state->MaxCodeHeapSize = current->maxCodeHeapSize; + + current = current->GetNext(); + } + + // Move to the first method section. + (void)NextMethodSectionIterator(); + + m_manager->AddRefIterator(); +} -EEJitManager::CodeHeapIterator::~CodeHeapIterator() +CodeHeapIterator::~CodeHeapIterator() { CONTRACTL { NOTHROW; GC_NOTRIGGER; - MODE_ANY; } CONTRACTL_END; + + m_manager->ReleaseIterator(); } -BOOL EEJitManager::CodeHeapIterator::Next() +bool CodeHeapIterator::Next() { CONTRACTL { NOTHROW; GC_NOTRIGGER; - MODE_ANY; } CONTRACTL_END; - if(!m_pHeapList) - return FALSE; - - while(1) + while (true) { - if(!m_Iterator.Next()) + if (!m_Iterator.Next()) { - m_pHeapList = m_pHeapList->GetNext(); - if(!m_pHeapList) - return FALSE; - new (&m_Iterator) MethodSectionIterator((const void *)m_pHeapList->mapBase, (COUNT_T)m_pHeapList->maxCodeHeapSize, m_pHeapList->pHdrMap, (COUNT_T)HEAP2MAPSIZE(ROUND_UP_TO_PAGE(m_pHeapList->maxCodeHeapSize))); + if (!NextMethodSectionIterator()) + return false; } else { - BYTE * code = m_Iterator.GetMethodCode(); - CodeHeader * pHdr = (CodeHeader *)(code - sizeof(CodeHeader)); + BYTE* code = m_Iterator.GetMethodCode(); + CodeHeader* pHdr = (CodeHeader*)(code - sizeof(CodeHeader)); m_pCurrent = !pHdr->IsStubCodeBlock() ? pHdr->GetMethodDesc() : NULL; // LoaderAllocator filter - if (m_pLoaderAllocator && m_pCurrent) + if (m_pLoaderAllocatorFilter && m_pCurrent) { LoaderAllocator *pCurrentLoaderAllocator = m_pCurrent->GetLoaderAllocator(); - if(pCurrentLoaderAllocator != m_pLoaderAllocator) + if (pCurrentLoaderAllocator != m_pLoaderAllocatorFilter) continue; } - return TRUE; + return true; } } } + +bool CodeHeapIterator::NextMethodSectionIterator() +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + } + CONTRACTL_END; + + if (m_HeapsIndexNext >= m_Heaps.Count()) + { + m_Iterator = {}; + return false; + } + + HeapListState& curr = m_Heaps.Table()[m_HeapsIndexNext++]; + m_Iterator = MethodSectionIterator{ + curr.MapBase, + (COUNT_T)curr.MaxCodeHeapSize, + curr.HdrMap, + (COUNT_T)HEAP2MAPSIZE(ROUND_UP_TO_PAGE(curr.MaxCodeHeapSize))}; + return true; +} #endif // !DACCESS_COMPILE #ifndef DACCESS_COMPILE @@ -1179,21 +1125,20 @@ PTR_VOID GetUnwindDataBlob(TADDR moduleBase, PTR_RUNTIME_FUNCTION pRuntimeFuncti //********************************************************************************** EECodeGenManager::EECodeGenManager() - : - m_pCodeHeap(NULL), - m_cleanupList(NULL), + : m_pAllCodeHeaps(NULL) + , m_cleanupList(NULL) // CRST_DEBUGGER_THREAD - We take this lock on debugger thread during EnC add method, among other things // CRST_TAKEN_DURING_SHUTDOWN - We take this lock during shutdown if ETW is on (to do rundown) - m_CodeHeapCritSec( CrstSingleUseLock, - CrstFlags(CRST_UNSAFE_ANYMODE|CRST_DEBUGGER_THREAD|CRST_TAKEN_DURING_SHUTDOWN)), - m_storeRichDebugInfo(false) + , m_CodeHeapLock( CrstSingleUseLock, + CrstFlags(CRST_UNSAFE_ANYMODE|CRST_DEBUGGER_THREAD|CRST_TAKEN_DURING_SHUTDOWN)) + , m_iteratorCount(0) + , m_storeRichDebugInfo(false) { } EEJitManager::EEJitManager() - : - m_CPUCompileFlags(), - m_JitLoadCritSec( CrstSingleUseLock ) + : m_CPUCompileFlags() + , m_JitLoadLock( CrstSingleUseLock ) { CONTRACTL { THROWS; @@ -1848,8 +1793,8 @@ BOOL EEJitManager::LoadJIT() if (IsJitLoaded()) return TRUE; - // Use m_JitLoadCritSec to ensure that the JIT is loaded on one thread only - CrstHolder chRead(&m_JitLoadCritSec); + // Use m_JitLoadLock to ensure that the JIT is loaded on one thread only + CrstHolder chRead(&m_JitLoadLock); // Did someone load the JIT before we got the lock? if (IsJitLoaded()) @@ -1979,7 +1924,7 @@ BOOL EEJitManager::LoadJIT() CodeFragmentHeap::CodeFragmentHeap(LoaderAllocator * pAllocator, StubCodeBlockKind kind) : m_pAllocator(pAllocator), m_pFreeBlocks(NULL), m_kind(kind), // CRST_DEBUGGER_THREAD - We take this lock on debugger thread during EnC add meth - m_CritSec(CrstCodeFragmentHeap, CrstFlags(CRST_UNSAFE_ANYMODE | CRST_DEBUGGER_THREAD)) + m_Lock(CrstCodeFragmentHeap, CrstFlags(CRST_UNSAFE_ANYMODE | CRST_DEBUGGER_THREAD)) { WRAPPER_NO_CONTRACT; } @@ -2038,7 +1983,7 @@ TaggedMemAllocPtr CodeFragmentHeap::RealAllocAlignedMem(size_t dwRequestedSize #endif ) { - CrstHolder ch(&m_CritSec); + CrstHolder ch(&m_Lock); dwRequestedSize = ALIGN_UP(dwRequestedSize, sizeof(TADDR)); @@ -2078,7 +2023,7 @@ TaggedMemAllocPtr CodeFragmentHeap::RealAllocAlignedMem(size_t dwRequestedSize dwSize = dwRequestedSize; if (dwSize < SMALL_BLOCK_THRESHOLD) dwSize = 4 * SMALL_BLOCK_THRESHOLD; - pMem = ExecutionManager::GetEEJitManager()->allocCodeFragmentBlock(dwSize, dwAlignment, m_pAllocator, m_kind); + pMem = ExecutionManager::GetEEJitManager()->AllocCodeFragmentBlock(dwSize, dwAlignment, m_pAllocator, m_kind); ReportStubBlock(pMem, dwSize, m_kind); } @@ -2115,7 +2060,7 @@ void CodeFragmentHeap::RealBackoutMem(void *pMem #endif ) { - CrstHolder ch(&m_CritSec); + CrstHolder ch(&m_Lock); { ExecutableWriterHolder memWriterHolder((BYTE*)pMem, dwSize); @@ -2190,7 +2135,7 @@ BYTE * EEJitManager::AllocateFromEmergencyJumpStubReserve(const BYTE * loAddr, c CONTRACTL { NOTHROW; GC_NOTRIGGER; - PRECONDITION(m_CodeHeapCritSec.OwnedByCurrentThread()); + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); } CONTRACTL_END; for (EmergencyJumpStubReserve ** ppPrev = &m_pEmergencyJumpStubReserveList; *ppPrev != NULL; ppPrev = &(*ppPrev)->m_pNext) @@ -2221,7 +2166,7 @@ VOID EEJitManager::EnsureJumpStubReserve(BYTE * pImageBase, SIZE_T imageSize, SI GC_NOTRIGGER; } CONTRACTL_END; - CrstHolder ch(&m_CodeHeapCritSec); + CrstHolder ch(&m_CodeHeapLock); BYTE * loAddr = pImageBase + imageSize + INT32_MIN; if (loAddr > pImageBase) loAddr = NULL; // overflow @@ -2560,7 +2505,7 @@ HeapList* EECodeGenManager::NewCodeHeap(CodeHeapRequestInfo *pInfo, DomainCodeHe CONTRACT(HeapList *) { THROWS; GC_NOTRIGGER; - PRECONDITION(m_CodeHeapCritSec.OwnedByCurrentThread()); + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); POSTCONDITION((RETVAL != NULL) || !pInfo->getThrowOnOutOfMemoryWithinRange()); } CONTRACT_END; @@ -2631,7 +2576,8 @@ HeapList* EECodeGenManager::NewCodeHeap(CodeHeapRequestInfo *pInfo, DomainCodeHe _ASSERTE (pHp != NULL); _ASSERTE (pHp->maxCodeHeapSize >= initialRequestSize); - pHp->SetNext(GetCodeHeapList()); + // Append the current code heap to the new code heap element. + pHp->SetNext(m_pAllCodeHeaps); EX_TRY { @@ -2674,7 +2620,7 @@ HeapList* EECodeGenManager::NewCodeHeap(CodeHeapRequestInfo *pInfo, DomainCodeHe ThrowOutOfMemory(); } - m_pCodeHeap = pHp; + m_pAllCodeHeaps = pHp; HeapList **ppHeapList = pADHeapList->m_CodeHeapList.AppendThrowing(); *ppHeapList = pHp; @@ -2682,14 +2628,14 @@ HeapList* EECodeGenManager::NewCodeHeap(CodeHeapRequestInfo *pInfo, DomainCodeHe RETURN(pHp); } -void* EECodeGenManager::allocCodeRaw(CodeHeapRequestInfo *pInfo, +void* EECodeGenManager::AllocCodeWorker(CodeHeapRequestInfo *pInfo, size_t header, size_t blockSize, unsigned align, HeapList ** ppCodeHeap) { CONTRACT(void *) { THROWS; GC_NOTRIGGER; - PRECONDITION(m_CodeHeapCritSec.OwnedByCurrentThread()); + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); POSTCONDITION((RETVAL != NULL) || !pInfo->getThrowOnOutOfMemoryWithinRange()); } CONTRACT_END; @@ -2823,7 +2769,7 @@ void* EECodeGenManager::allocCodeRaw(CodeHeapRequestInfo *pInfo, } template -void EECodeGenManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, void** ppCodeHeader, void** ppCodeHeaderRW, +void EECodeGenManager::AllocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, void** ppCodeHeader, void** ppCodeHeaderRW, size_t* pAllocatedSize, HeapList** ppCodeHeap , BYTE** ppRealHeader #ifdef FEATURE_EH_FUNCLETS @@ -2904,19 +2850,22 @@ void EECodeGenManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reser // Scope the lock { - CrstHolder ch(&m_CodeHeapCritSec); + CrstHolder ch(&m_CodeHeapLock); + + // Allocate the record code pointer early to avoid allocation failures. + void* dummyRecordedCodePtr; + void** recordedCodePtr = pMD->IsLCGMethod() + ? pMD->AsDynamicMethodDesc()->GetLCGMethodResolver()->AllocateRecordCodePointer() + : &dummyRecordedCodePtr; *ppCodeHeap = NULL; - TADDR pCode = (TADDR) allocCodeRaw(&requestInfo, sizeof(TCodeHeader), totalSize, alignment, ppCodeHeap); + TADDR pCode = (TADDR) AllocCodeWorker(&requestInfo, sizeof(TCodeHeader), totalSize, alignment, ppCodeHeap); _ASSERTE(*ppCodeHeap); - - if (pMD->IsLCGMethod()) - { - pMD->AsDynamicMethodDesc()->GetLCGMethodResolver()->m_recordCodePointer = (void*) pCode; - } - _ASSERTE(IS_ALIGNED(pCode, alignment)); + // Record the code pointer + *recordedCodePtr = (void*)pCode; + pCodeHdr = ((TCodeHeader *)pCode) - 1; *pAllocatedSize = sizeof(TCodeHeader) + totalSize; @@ -2973,7 +2922,7 @@ void EECodeGenManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reser *ppCodeHeaderRW = pCodeHdrRW; } -template void EECodeGenManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, void** ppCodeHeader, void** ppCodeHeaderRW, +template void EECodeGenManager::AllocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, void** ppCodeHeader, void** ppCodeHeaderRW, size_t* pAllocatedSize, HeapList** ppCodeHeap , BYTE** ppRealHeader #ifdef FEATURE_EH_FUNCLETS @@ -2982,7 +2931,7 @@ template void EECodeGenManager::allocCode(MethodDesc* pMD, size_t bl ); #ifdef FEATURE_INTERPRETER -template void EECodeGenManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, void** ppCodeHeader, void** ppCodeHeaderRW, +template void EECodeGenManager::AllocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, void** ppCodeHeader, void** ppCodeHeaderRW, size_t* pAllocatedSize, HeapList** ppCodeHeap , BYTE** ppRealHeader #ifdef FEATURE_EH_FUNCLETS @@ -2996,7 +2945,7 @@ EEJitManager::DomainCodeHeapList *EECodeGenManager::GetCodeHeapList(CodeHeapRequ CONTRACTL { NOTHROW; GC_NOTRIGGER; - PRECONDITION(m_CodeHeapCritSec.OwnedByCurrentThread()); + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); } CONTRACTL_END; DomainCodeHeapList *pList = NULL; @@ -3037,18 +2986,16 @@ bool EECodeGenManager::CanUseCodeHeap(CodeHeapRequestInfo *pInfo, HeapList *pCod CONTRACTL { NOTHROW; GC_NOTRIGGER; - PRECONDITION(m_CodeHeapCritSec.OwnedByCurrentThread()); + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); } CONTRACTL_END; - bool retVal = false; - if ((pInfo->m_loAddr == 0) && (pInfo->m_hiAddr == 0)) { // We have no constraint so this non empty heap will be able to satisfy our request if (pInfo->IsDynamicDomain()) { _ASSERTE(pCodeHeap->reserveForJumpStubs == 0); - retVal = true; + return true; } else { @@ -3058,7 +3005,7 @@ bool EECodeGenManager::CanUseCodeHeap(CodeHeapRequestInfo *pInfo, HeapList *pCod BYTE * hiRequestAddr = loRequestAddr + pInfo->getRequestSize() + BYTES_PER_BUCKET; if (hiRequestAddr <= lastAddr - pCodeHeap->reserveForJumpStubs) { - retVal = true; + return true; } } } @@ -3094,7 +3041,7 @@ bool EECodeGenManager::CanUseCodeHeap(CodeHeapRequestInfo *pInfo, HeapList *pCod (lastAddr <= pInfo->m_hiAddr)) { // This heap will always satisfy our constraint - retVal = true; + return true; } } else // non-DynamicDomain @@ -3117,31 +3064,29 @@ bool EECodeGenManager::CanUseCodeHeap(CodeHeapRequestInfo *pInfo, HeapList *pCod if (hiRequestAddr <= lastAddr - (pInfo->getThrowOnOutOfMemoryWithinRange() ? 0 : pCodeHeap->reserveForJumpStubs)) { // This heap will be able to satisfy our constraint - retVal = true; + return true; } } } - } + } - return retVal; + return false; } -EEJitManager::DomainCodeHeapList * EECodeGenManager::CreateCodeHeapList(CodeHeapRequestInfo *pInfo) +EEJitManager::DomainCodeHeapList* EECodeGenManager::CreateCodeHeapList(CodeHeapRequestInfo *pInfo) { - CONTRACTL { + CONTRACTL + { THROWS; GC_NOTRIGGER; - PRECONDITION(m_CodeHeapCritSec.OwnedByCurrentThread()); + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); } CONTRACTL_END; - NewHolder pNewList(new DomainCodeHeapList()); - pNewList->m_pAllocator = pInfo->m_pAllocator; + NewHolder pNewList(new DomainCodeHeapList(pInfo->m_pAllocator)); - DomainCodeHeapList **ppList = NULL; - if (pInfo->IsDynamicDomain()) - ppList = m_DynamicDomainCodeHeaps.AppendThrowing(); - else - ppList = m_DomainCodeHeaps.AppendThrowing(); + DomainCodeHeapList** ppList = pInfo->IsDynamicDomain() + ? m_DynamicDomainCodeHeaps.AppendThrowing() + : m_DomainCodeHeaps.AppendThrowing(); *ppList = pNewList; return pNewList.Extract(); @@ -3160,7 +3105,7 @@ LoaderHeap *EECodeGenManager::GetJitMetaHeap(MethodDesc *pMD) return pAllocator->GetLowFrequencyHeap(); } -JumpStubBlockHeader * EEJitManager::allocJumpStubBlock(MethodDesc* pMD, DWORD numJumps, +JumpStubBlockHeader * EEJitManager::AllocJumpStubBlock(MethodDesc* pMD, DWORD numJumps, BYTE * loAddr, BYTE * hiAddr, LoaderAllocator *pLoaderAllocator, bool throwOnOutOfMemoryWithinRange) @@ -3186,9 +3131,9 @@ JumpStubBlockHeader * EEJitManager::allocJumpStubBlock(MethodDesc* pMD, DWORD n // Scope the lock { - CrstHolder ch(&m_CodeHeapCritSec); + CrstHolder ch(&m_CodeHeapLock); - mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(CodeHeader), blockSize, CODE_SIZE_ALIGN, &pCodeHeap); + mem = (TADDR) AllocCodeWorker(&requestInfo, sizeof(CodeHeader), blockSize, CODE_SIZE_ALIGN, &pCodeHeap); if (mem == (TADDR)0) { _ASSERTE(!throwOnOutOfMemoryWithinRange); @@ -3223,7 +3168,7 @@ JumpStubBlockHeader * EEJitManager::allocJumpStubBlock(MethodDesc* pMD, DWORD n RETURN((JumpStubBlockHeader*)mem); } -void * EEJitManager::allocCodeFragmentBlock(size_t blockSize, unsigned alignment, LoaderAllocator *pLoaderAllocator, StubCodeBlockKind kind) +void * EEJitManager::AllocCodeFragmentBlock(size_t blockSize, unsigned alignment, LoaderAllocator *pLoaderAllocator, StubCodeBlockKind kind) { CONTRACT(void *) { THROWS; @@ -3245,9 +3190,9 @@ void * EEJitManager::allocCodeFragmentBlock(size_t blockSize, unsigned alignment // Scope the lock { - CrstHolder ch(&m_CodeHeapCritSec); + CrstHolder ch(&m_CodeHeapLock); - mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(CodeHeader), blockSize, alignment, &pCodeHeap); + mem = (TADDR) AllocCodeWorker(&requestInfo, sizeof(CodeHeader), blockSize, alignment, &pCodeHeap); // CodeHeader comes immediately before the block CodeHeader * pCodeHdr = (CodeHeader *) (mem - sizeof(CodeHeader)); @@ -3263,7 +3208,7 @@ void * EEJitManager::allocCodeFragmentBlock(size_t blockSize, unsigned alignment RETURN((void *)mem); } -BYTE* EECodeGenManager::allocFromJitMetaHeap(MethodDesc* pMD, DWORD blockSize, size_t * pAllocationSize) +BYTE* EECodeGenManager::AllocFromJitMetaHeap(MethodDesc* pMD, size_t blockSize) { CONTRACTL { THROWS; @@ -3273,7 +3218,7 @@ BYTE* EECodeGenManager::allocFromJitMetaHeap(MethodDesc* pMD, DWORD blockSize, s BYTE *pMem = NULL; if (pMD->IsLCGMethod()) { - CrstHolder ch(&m_CodeHeapCritSec); + CrstHolder ch(&m_CodeHeapLock); pMem = (BYTE*)(void*)pMD->AsDynamicMethodDesc()->GetResolver()->GetJitMetaHeap()->New(blockSize); } else @@ -3281,117 +3226,10 @@ BYTE* EECodeGenManager::allocFromJitMetaHeap(MethodDesc* pMD, DWORD blockSize, s pMem = (BYTE*) (void*)GetJitMetaHeap(pMD)->AllocMem(S_SIZE_T(blockSize)); } - *pAllocationSize = blockSize; // Store the allocation size so we can backout later. - return pMem; } - -template -void EECodeGenManager::RemoveJitData(TCodeHeader * pCHdr, size_t GCinfo_len, size_t EHinfo_len) -{ - CONTRACTL { - NOTHROW; - GC_TRIGGERS; - } CONTRACTL_END; - - MethodDesc* pMD = pCHdr->GetMethodDesc(); - - void * codeStart = (void*)pCHdr->GetCodeStartAddress(); - - if (pMD->IsLCGMethod()) - { - { - CrstHolder ch(&m_CodeHeapCritSec); - - LCGMethodResolver * pResolver = pMD->AsDynamicMethodDesc()->GetLCGMethodResolver(); - - // Clear the pointer only if it matches what we are about to free. - // There can be cases where the JIT is reentered and we JITed the method multiple times. - if (pResolver->m_recordCodePointer == codeStart) - pResolver->m_recordCodePointer = NULL; - } - - // Remove the unwind information (if applicable) - UnpublishUnwindInfoForMethod((TADDR)codeStart); - - HostCodeHeap* pHeap = HostCodeHeap::GetCodeHeap((TADDR)codeStart); - FreeCodeMemory(pHeap, codeStart); - - // We are leaking GCInfo and EHInfo. They will be freed once the dynamic method is destroyed. - - return; - } - - { - CrstHolder ch(&m_CodeHeapCritSec); - - HeapList *pHp = GetCodeHeapList(); - - while (pHp && ((pHp->startAddress > (TADDR)pCHdr) || - (pHp->endAddress < (TADDR)codeStart))) - { - pHp = pHp->GetNext(); - } - - _ASSERTE(pHp && pHp->pHdrMap); - - // Better to just return than AV? - if (pHp == NULL) - return; - - NibbleMapDeleteUnlocked(pHp, (TADDR)codeStart); - } - - // Backout the GCInfo - if (GCinfo_len > 0) { - GetJitMetaHeap(pMD)->BackoutMem(pCHdr->GetGCInfo(), GCinfo_len); - } - - // Backout the EHInfo - BYTE *EHInfo = (BYTE *)pCHdr->GetEHInfo(); - if (EHInfo) { - EHInfo -= sizeof(size_t); - - _ASSERTE(EHinfo_len>0); - GetJitMetaHeap(pMD)->BackoutMem(EHInfo, EHinfo_len); - } - - // - // TODO: Although we have backout the GCInfo and EHInfo, we haven't actually backout the - // code buffer itself. As a result, we might leak the CodeHeap if jitting fails after - // the code buffer is allocated. - // - // However, it appears non-trivial to fix this. - // Here are some of the reasons: - // (1) AllocCode calls in AllocCodeRaw to alloc code buffer in the CodeHeap. The exact size - // of the code buffer is not known until the alignment is calculated deep on the stack. - // (2) AllocCodeRaw is called in 3 different places. We might need to remember the - // information for these places. - // (3) AllocCodeRaw might create a new CodeHeap. We should remember exactly which - // CodeHeap is used to allocate the code buffer. - // - // Fortunately, this is not a severe leak since the CodeHeap will be reclaimed on appdomain unload. - // - // - return; -} - -// Explicit instantiation of the templates so that they can be used externally without the bodies of the methods -// being in the header file. The bodies call methods of multiple data types that cannot be reasonably defined -// before the codeman.h is included. - -template -void EECodeGenManager::RemoveJitData(CodeHeader * pCHdr, size_t GCinfo_len, size_t EHinfo_len); - -#ifdef FEATURE_INTERPRETER - -template -void EECodeGenManager::RemoveJitData(InterpreterCodeHeader * pCHdr, size_t GCinfo_len, size_t EHinfo_len); -#endif // FEATURE_INTERPRETER - #endif // !DACCESS_COMPILE - GCInfoToken EEJitManager::GetGCInfoToken(const METHODTOKEN& MethodToken) { CONTRACTL { @@ -3505,13 +3343,6 @@ TypeHandle EECodeGenManager::ResolveEHClause(EE_ILEXCEPTION_CLAUSE* pEHClause, ClassLoader::ReturnNullIfNotFound); } -void EEJitManager::UnpublishUnwindInfoForMethod(TADDR codeStart) -{ -#if defined(TARGET_AMD64) - UnwindInfoTable::UnpublishUnwindInfoForMethod((TADDR)codeStart); -#endif // defined(TARGET_AMD64) -} - void EEJitManager::DeleteFunctionTable(PVOID pvTableID) { DeleteEEFunctionTable(pvTableID); @@ -3524,14 +3355,59 @@ void EEJitManager::DeleteFunctionTable(PVOID pvTableID) // count is 0, we can safely delete, otherwise we must add to the cleanup list to be deleted later. We know // there can only be one unload at a time, so we can use a single var to hold the unlinked, but not deleted, // elements. -void EECodeGenManager::Unload(LoaderAllocator *pAllocator) +void EECodeGenManager::Unload(LoaderAllocator* pAllocator) { - CONTRACTL { + CONTRACTL + { NOTHROW; GC_NOTRIGGER; - } CONTRACTL_END; + PRECONDITION(pAllocator != NULL); + } + CONTRACTL_END; - CrstHolder ch(&m_CodeHeapCritSec); + CrstHolder ch(&m_CodeHeapLock); + // If we are in the middle of an enumeration, we cannot unload any code heaps. + if (m_iteratorCount != 0) + { + // Record the LoaderAllocator and return. + LoaderAllocator** toUnload = m_delayUnload.Append(); + if (toUnload == NULL) + { + EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_FAILFAST, + W("Failed to delay unload code heap for LoaderAllocator")); + return; + } + + *toUnload = pAllocator; + return; + } + + // Unload any code heaps that were delayed for unloading. + UINT32 unloadCount = m_delayUnload.Count(); + if (unloadCount != 0) + { + for (UINT32 i = 0; i < unloadCount; ++i) + { + UnloadWorker(m_delayUnload.Table()[i]); + } + m_delayUnload.Clear(); + } + + UnloadWorker(pAllocator); + + ExecutableAllocator::ResetLazyPreferredRangeHint(); +} + +void EECodeGenManager::UnloadWorker(LoaderAllocator* pAllocator) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); + PRECONDITION(pAllocator != NULL); + } + CONTRACTL_END; DomainCodeHeapList **ppList = m_DomainCodeHeaps.Table(); int count = m_DomainCodeHeaps.Count(); @@ -3576,17 +3452,10 @@ void EECodeGenManager::Unload(LoaderAllocator *pAllocator) break; } } - - ExecutableAllocator::ResetLazyPreferredRangeHint(); } -EEJitManager::DomainCodeHeapList::DomainCodeHeapList() -{ - LIMITED_METHOD_CONTRACT; - m_pAllocator = NULL; -} - -EEJitManager::DomainCodeHeapList::~DomainCodeHeapList() +EEJitManager::DomainCodeHeapList::DomainCodeHeapList(LoaderAllocator* allocator) + : m_pAllocator{ allocator } { LIMITED_METHOD_CONTRACT; } @@ -3596,7 +3465,7 @@ void EECodeGenManager::RemoveCodeHeapFromDomainList(CodeHeap *pHeap, LoaderAlloc CONTRACTL { NOTHROW; GC_NOTRIGGER; - PRECONDITION(m_CodeHeapCritSec.OwnedByCurrentThread()); + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); } CONTRACTL_END; // get the AppDomain heap list for pAllocator in m_DynamicDomainCodeHeaps @@ -3629,10 +3498,10 @@ void EECodeGenManager::RemoveCodeHeapFromDomainList(CodeHeap *pHeap, LoaderAlloc #ifdef FEATURE_INTERPRETER -InterpreterJitManager::InterpreterJitManager() : - m_interpreter(NULL), - m_interpreterHandle(NULL), - m_interpreterLoadCritSec(CrstSingleUseLock) +InterpreterJitManager::InterpreterJitManager() + : m_interpreter(NULL) + , m_interpreterHandle(NULL) + , m_interpreterLoadLock(CrstSingleUseLock) { LIMITED_METHOD_CONTRACT; SetCodeManager(ExecutionManager::GetInterpreterCodeManager()); @@ -3646,8 +3515,8 @@ BOOL InterpreterJitManager::LoadInterpreter() if (IsInterpreterLoaded()) return TRUE; - // Use m_interpreterLoadCritSec to ensure that the interpreter is loaded on one thread only - CrstHolder chRead(&m_interpreterLoadCritSec); + // Use m_interpreterLoadLock to ensure that the interpreter is loaded on one thread only + CrstHolder chRead(&m_interpreterLoadLock); // Did someone load the interpreter before we got the lock? if (IsInterpreterLoaded()) @@ -3679,25 +3548,23 @@ BOOL InterpreterJitManager::LoadInterpreter() } #endif // FEATURE_INTERPRETER -void EECodeGenManager::FreeCodeMemory(HostCodeHeap *pCodeHeap, void * codeStart) +void EECodeGenManager::FreeHostCodeHeapMemoryWorker(HostCodeHeap* pCodeHeap, void* codeStart) { CONTRACTL { NOTHROW; GC_NOTRIGGER; + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); + PRECONDITION(pCodeHeap != NULL); + PRECONDITION(codeStart != NULL); } CONTRACTL_END; - CrstHolder ch(&m_CodeHeapCritSec); - - // FreeCodeMemory is only supported on LCG methods, - // so pCodeHeap can only be a HostCodeHeap. - // clean up the NibbleMap NibbleMapDeleteUnlocked(pCodeHeap->m_pHeapList, (TADDR)codeStart); // The caller of this method doesn't call HostCodeHeap->FreeMemForCode - // directly because the operation should be protected by m_CodeHeapCritSec. + // directly because the operation should be protected by m_CodeHeapLock. pCodeHeap->FreeMemForCode(codeStart); } @@ -3729,17 +3596,16 @@ void EECodeGenManager::CleanupCodeHeaps() _ASSERTE (IsAtProcessExit() || (GCHeapUtilities::IsGCInProgress() && ::IsGCThread())); - // Quick out, don't even take the lock if we have not cleanup to do. - // This is important because ETW takes the CodeHeapLock when it is doing - // rundown, and if there are many JIT compiled methods, this can take a while. - // Because cleanup is called synchronously before a GC, this means GCs get - // blocked while ETW is doing rundown. By not taking the lock we avoid - // this stall most of the time since cleanup is rare, and ETW rundown is rare - // the likelihood of both is very very rare. - if (m_cleanupList == NULL) - return; + // Check outside the lock if there are any heaps to clean up + if (m_cleanupList == NULL) + return; + + CrstHolder ch(&m_CodeHeapLock); - CrstHolder ch(&m_CodeHeapCritSec); + // If there are any iterators, we cannot clean up the heaps yet. + // We will try on the next GC to do the cleanup. + if (m_iteratorCount != 0) + return; if (m_cleanupList == NULL) return; @@ -3754,13 +3620,13 @@ void EECodeGenManager::CleanupCodeHeaps() DWORD allocCount = pHeap->m_AllocationCount; if (allocCount == 0) { - LOG((LF_BCL, LL_INFO100, "Level2 - Destryoing CodeHeap [0x%p, vt(0x%x)] - ref count 0\n", pHeap, *(size_t*)pHeap)); + LOG((LF_BCL, LL_INFO100, "Level2 - Destryoing CodeHeap [%p, vt(0x%zx)] - ref count 0\n", pHeap, *(size_t*)pHeap)); RemoveCodeHeapFromDomainList(pHeap, pHeap->m_pAllocator); DeleteCodeHeap(pHeap->m_pHeapList); } else { - LOG((LF_BCL, LL_INFO100, "Level2 - Restoring CodeHeap [0x%p, vt(0x%x)] - ref count %d\n", pHeap, *(size_t*)pHeap, allocCount)); + LOG((LF_BCL, LL_INFO100, "Level2 - Restoring CodeHeap [%p, vt(0x%zx)] - ref count %d\n", pHeap, *(size_t*)pHeap, allocCount)); } pHeap = pNextHeap; } @@ -3771,7 +3637,7 @@ void EECodeGenManager::RemoveFromCleanupList(HostCodeHeap *pCodeHeap) CONTRACTL { NOTHROW; GC_NOTRIGGER; - PRECONDITION(m_CodeHeapCritSec.OwnedByCurrentThread()); + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); } CONTRACTL_END; HostCodeHeap *pHeap = m_cleanupList; @@ -3796,13 +3662,60 @@ void EECodeGenManager::RemoveFromCleanupList(HostCodeHeap *pCodeHeap) } } +CodeHeapIterator EECodeGenManager::GetCodeHeapIterator(LoaderAllocator* pLoaderAllocatorFilter) +{ + CONTRACTL + { + THROWS; + GC_NOTRIGGER; + } + CONTRACTL_END; + + CrstHolder ch(&m_CodeHeapLock); + return CodeHeapIterator + { + this, + m_pAllCodeHeaps, + pLoaderAllocatorFilter + }; +} + +void EECodeGenManager::AddRefIterator() +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); + } + CONTRACTL_END; + + m_iteratorCount++; +} + +void EECodeGenManager::ReleaseIterator() +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + } + CONTRACTL_END; + + CrstHolder ch(&m_CodeHeapLock); + _ASSERTE(m_iteratorCount > 0); + m_iteratorCount--; +} + void EECodeGenManager::AddToCleanupList(HostCodeHeap *pCodeHeap) { - CONTRACTL { + CONTRACTL + { NOTHROW; GC_NOTRIGGER; - PRECONDITION(m_CodeHeapCritSec.OwnedByCurrentThread()); - } CONTRACTL_END; + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); + } + CONTRACTL_END; // it may happen that the current heap count goes to 0 and later on, before it is destroyed, it gets reused // for another dynamic method. @@ -3813,7 +3726,7 @@ void EECodeGenManager::AddToCleanupList(HostCodeHeap *pCodeHeap) { if (pHeap == pCodeHeap) { - LOG((LF_BCL, LL_INFO100, "Level2 - CodeHeap [0x%p, vt(0x%x)] - Already in list\n", pCodeHeap, *(size_t*)pCodeHeap)); + LOG((LF_BCL, LL_INFO100, "Level2 - CodeHeap [%p, vt(0x%zx)] - Already in list\n", pCodeHeap, *(size_t*)pCodeHeap)); break; } pHeap = pHeap->m_pNextHeapToRelease; @@ -3822,21 +3735,48 @@ void EECodeGenManager::AddToCleanupList(HostCodeHeap *pCodeHeap) { pCodeHeap->m_pNextHeapToRelease = m_cleanupList; m_cleanupList = pCodeHeap; - LOG((LF_BCL, LL_INFO100, "Level2 - CodeHeap [0x%p, vt(0x%x)] - ref count %d - Adding to cleanup list\n", pCodeHeap, *(size_t*)pCodeHeap, pCodeHeap->m_AllocationCount)); + LOG((LF_BCL, LL_INFO100, "Level2 - CodeHeap [%p, vt(0x%zx)] - ref count %d - Adding to cleanup list\n", pCodeHeap, *(size_t*)pCodeHeap, pCodeHeap->m_AllocationCount)); + } +} + +bool EECodeGenManager::TryFreeHostCodeHeapMemory(HostCodeHeap* pCodeHeap, void* codeStart) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + PRECONDITION(pCodeHeap != NULL); + PRECONDITION(codeStart != NULL); } + CONTRACTL_END; + + CrstHolder ch(&m_CodeHeapLock); + if (m_iteratorCount != 0) + { + // If we are in the middle of an enumeration, we cannot destroy code heap memory. + return false; + } + + FreeHostCodeHeapMemoryWorker(pCodeHeap, codeStart); + return true; } void EECodeGenManager::DeleteCodeHeap(HeapList *pHeapList) { - CONTRACTL { + CONTRACTL + { NOTHROW; GC_NOTRIGGER; - PRECONDITION(m_CodeHeapCritSec.OwnedByCurrentThread()); - } CONTRACTL_END; + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); + } + CONTRACTL_END; - HeapList *pHp = GetCodeHeapList(); + // Remove from the list of heaps + HeapList *pHp = m_pAllCodeHeaps; if (pHp == pHeapList) - m_pCodeHeap = pHp->GetNext(); + { + m_pAllCodeHeaps = pHp->GetNext(); + } else { HeapList *pHpNext = pHp->GetNext(); @@ -3854,7 +3794,7 @@ void EECodeGenManager::DeleteCodeHeap(HeapList *pHeapList) ExecutionManager::DeleteRange((TADDR)pHeapList->GetModuleBase()); - LOG((LF_JIT, LL_INFO100, "DeleteCodeHeap start" FMT_ADDR "end" FMT_ADDR "\n", + LOG((LF_JIT, LL_INFO100, "DeleteCodeHeap start %p end %p\n", (const BYTE*)pHeapList->startAddress, (const BYTE*)pHeapList->endAddress )); @@ -3888,7 +3828,9 @@ static TCodeHeader * GetCodeHeaderFromDebugInfoRequest(const DebugInfoRequest & //----------------------------------------------------------------------------- BOOL EECodeGenManager::GetBoundariesAndVarsWorker( PTR_BYTE pDebugInfo, - IN FP_IDS_NEW fpNew, IN void * pNewData, + IN FP_IDS_NEW fpNew, + IN void * pNewData, + BoundsType boundsType, OUT ULONG32 * pcMap, OUT ICorDebugInfo::OffsetMapping **ppMap, OUT ULONG32 * pcVars, @@ -3917,7 +3859,9 @@ BOOL EECodeGenManager::GetBoundariesAndVarsWorker( // Uncompress. This allocates memory and may throw. CompressDebugInfo::RestoreBoundariesAndVars( - fpNew, pNewData, // allocators + fpNew, + pNewData, // allocators + boundsType, pDebugInfo, // input pcMap, ppMap, // output pcVars, ppVars, // output @@ -3929,7 +3873,9 @@ BOOL EECodeGenManager::GetBoundariesAndVarsWorker( BOOL EEJitManager::GetBoundariesAndVars( const DebugInfoRequest & request, - IN FP_IDS_NEW fpNew, IN void * pNewData, + IN FP_IDS_NEW fpNew, + IN void * pNewData, + BoundsType boundsType, OUT ULONG32 * pcMap, OUT ICorDebugInfo::OffsetMapping **ppMap, OUT ULONG32 * pcVars, @@ -3946,9 +3892,66 @@ BOOL EEJitManager::GetBoundariesAndVars( PTR_BYTE pDebugInfo = pHdr->GetDebugInfo(); - return GetBoundariesAndVarsWorker(pDebugInfo, fpNew, pNewData, pcMap, ppMap, pcVars, ppVars); + return GetBoundariesAndVarsWorker(pDebugInfo, fpNew, pNewData, boundsType, pcMap, ppMap, pcVars, ppVars); +} + +size_t EEJitManager::WalkILOffsets( + const DebugInfoRequest & request, + BoundsType boundsType, + void* pContext, + size_t (* pfnWalkILOffsets)(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext)) +{ + CONTRACTL { + THROWS; // on OOM. + GC_NOTRIGGER; // getting vars shouldn't trigger + SUPPORTS_DAC; + } CONTRACTL_END; + + CodeHeader * pHdr = GetCodeHeaderFromDebugInfoRequest(request); + _ASSERTE(pHdr != NULL); + + PTR_BYTE pDebugInfo = pHdr->GetDebugInfo(); + + return WalkILOffsetsWorker(pDebugInfo, boundsType, pContext, pfnWalkILOffsets); } +size_t EECodeGenManager::WalkILOffsetsWorker(PTR_BYTE pDebugInfo, + BoundsType boundsType, + void* pContext, + size_t (* pfnWalkILOffsets)(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext)) +{ + CONTRACTL { + THROWS; // on OOM. + GC_NOTRIGGER; // getting vars shouldn't trigger + SUPPORTS_DAC; + } CONTRACTL_END; + + // No header created, which means no jit information is available. + if (pDebugInfo == NULL) + return 0; + +#ifdef FEATURE_ON_STACK_REPLACEMENT + BOOL hasFlagByte = TRUE; +#else + BOOL hasFlagByte = FALSE; +#endif + + if (m_storeRichDebugInfo) + { + hasFlagByte = TRUE; + } + + // Uncompress. This allocates memory and may throw. + return CompressDebugInfo::WalkILOffsets( + pDebugInfo, // input + boundsType, + hasFlagByte, + pContext, + pfnWalkILOffsets + ); +} + + BOOL EECodeGenManager::GetRichDebugInfoWorker( PTR_BYTE pDebugInfo, IN FP_IDS_NEW fpNew, IN void* pNewData, @@ -4006,7 +4009,9 @@ BOOL EEJitManager::GetRichDebugInfo( #ifdef FEATURE_INTERPRETER BOOL InterpreterJitManager::GetBoundariesAndVars( const DebugInfoRequest & request, - IN FP_IDS_NEW fpNew, IN void * pNewData, + IN FP_IDS_NEW fpNew, + IN void * pNewData, + BoundsType boundsType, OUT ULONG32 * pcMap, OUT ICorDebugInfo::OffsetMapping **ppMap, OUT ULONG32 * pcVars, @@ -4033,9 +4038,36 @@ BOOL InterpreterJitManager::GetBoundariesAndVars( return TRUE; } - return GetBoundariesAndVarsWorker(pDebugInfo, fpNew, pNewData, pcMap, ppMap, pcVars, ppVars); + return GetBoundariesAndVarsWorker(pDebugInfo, fpNew, pNewData, boundsType, pcMap, ppMap, pcVars, ppVars); } +size_t InterpreterJitManager::WalkILOffsets( + const DebugInfoRequest & request, + BoundsType boundsType, + void* pContext, + size_t (* pfnWalkILOffsets)(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext)) +{ + CONTRACTL { + THROWS; // on OOM. + GC_NOTRIGGER; // getting vars shouldn't trigger + SUPPORTS_DAC; + } CONTRACTL_END; + + InterpreterCodeHeader * pHdr = GetCodeHeaderFromDebugInfoRequest(request); + _ASSERTE(pHdr != NULL); + + PTR_BYTE pDebugInfo = pHdr->GetDebugInfo(); + + // Interpreter-TODO: This is a temporary workaround until the interpreter produces the debug info + if (pDebugInfo == NULL) + { + return 0; + } + + return WalkILOffsetsWorker(pDebugInfo, boundsType, pContext, pfnWalkILOffsets); +} + + BOOL InterpreterJitManager::GetRichDebugInfo( const DebugInfoRequest& request, IN FP_IDS_NEW fpNew, IN void* pNewData, @@ -4510,7 +4542,7 @@ void EECodeGenManager::NibbleMapSet(HeapList * pHp, TADDR pCode, size_t codeSize GC_NOTRIGGER; } CONTRACTL_END; - CrstHolder ch(&m_CodeHeapCritSec); + CrstHolder ch(&m_CodeHeapLock); NibbleMapSetUnlocked(pHp, pCode, codeSize); } @@ -4522,12 +4554,9 @@ void EECodeGenManager::NibbleMapSetUnlocked(HeapList * pHp, TADDR pCode, size_t CONTRACTL { NOTHROW; GC_NOTRIGGER; + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); } CONTRACTL_END; - // Currently all callers to this method ensure EEJitManager::m_CodeHeapCritSec - // is held. - _ASSERTE(m_CodeHeapCritSec.OwnedByCurrentThread()); - _ASSERTE(pCode >= pHp->mapBase); _ASSERTE(pCode + codeSize <= pHp->startAddress + pHp->maxCodeHeapSize); @@ -4566,18 +4595,6 @@ void EECodeGenManager::NibbleMapSetUnlocked(HeapList * pHp, TADDR pCode, size_t } } -// For implementation details, see comment in nibblemapmacros.h -void EECodeGenManager::NibbleMapDelete(HeapList* pHp, TADDR pCode) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - } CONTRACTL_END; - - CrstHolder ch(&m_CodeHeapCritSec); - NibbleMapDeleteUnlocked(pHp, pCode); -} - void EECodeGenManager::NibbleMapDeleteUnlocked(HeapList* pHp, TADDR pCode) { using namespace NibbleMap; @@ -4585,12 +4602,9 @@ void EECodeGenManager::NibbleMapDeleteUnlocked(HeapList* pHp, TADDR pCode) CONTRACTL { NOTHROW; GC_NOTRIGGER; + PRECONDITION(m_CodeHeapLock.OwnedByCurrentThread()); } CONTRACTL_END; - // Currently all callers to this method ensure EEJitManager::m_CodeHeapCritSec - // is held. - _ASSERTE(m_CodeHeapCritSec.OwnedByCurrentThread()); - _ASSERTE(pCode >= pHp->mapBase); // remove bottom two bits to ensure alignment math @@ -4854,8 +4868,7 @@ void EECodeGenManager::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) // HeapList* heap; - - for (heap = m_pCodeHeap; heap; heap = heap->GetNext()) + for (heap = m_pAllCodeHeaps; heap; heap = heap->GetNext()) { DacEnumHostDPtrMem(heap); @@ -5428,7 +5441,7 @@ void ExecutionManager::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) void ExecutionManager::Unload(LoaderAllocator *pLoaderAllocator) { CONTRACTL { - NOTHROW; + THROWS; GC_NOTRIGGER; } CONTRACTL_END; @@ -5601,7 +5614,7 @@ PCODE ExecutionManager::getNextJumpStub(MethodDesc* pMD, PCODE target, // with any other methods and very frequently our method only needs one jump stub. // Using 4 gives a request size of (32 + 4*12) or 80 bytes. // Also note that request sizes are rounded up to a multiples of 16. - // The request size is calculated into 'blockSize' in allocJumpStubBlock. + // The request size is calculated into 'blockSize' in AllocJumpStubBlock. // For x64 the value of BACK_TO_BACK_JUMP_ALLOCATE_SIZE is 12 bytes // and the sizeof(JumpStubBlockHeader) is 32. // @@ -5661,12 +5674,12 @@ PCODE ExecutionManager::getNextJumpStub(MethodDesc* pMD, PCODE target, m_normal_JumpStubBlockAllocCount++; } - // allocJumpStubBlock will allocate from the LoaderCodeHeap for normal methods + // AllocJumpStubBlock will allocate from the LoaderCodeHeap for normal methods // and will allocate from a HostCodeHeap for LCG methods. // // note that this can throw an OOM exception - curBlock = ExecutionManager::GetEEJitManager()->allocJumpStubBlock(pMD, numJumpStubs, loAddr, hiAddr, pLoaderAllocator, throwOnOutOfMemoryWithinRange); + curBlock = ExecutionManager::GetEEJitManager()->AllocJumpStubBlock(pMD, numJumpStubs, loAddr, hiAddr, pLoaderAllocator, throwOnOutOfMemoryWithinRange); if (curBlock == NULL) { _ASSERTE(!throwOnOutOfMemoryWithinRange); @@ -6261,7 +6274,9 @@ TypeHandle ReadyToRunJitManager::ResolveEHClause(EE_ILEXCEPTION_CLAUSE* pEHClaus //----------------------------------------------------------------------------- BOOL ReadyToRunJitManager::GetBoundariesAndVars( const DebugInfoRequest & request, - IN FP_IDS_NEW fpNew, IN void * pNewData, + IN FP_IDS_NEW fpNew, + IN void * pNewData, + BoundsType boundsType, OUT ULONG32 * pcMap, OUT ICorDebugInfo::OffsetMapping **ppMap, OUT ULONG32 * pcVars, @@ -6286,7 +6301,9 @@ BOOL ReadyToRunJitManager::GetBoundariesAndVars( // Uncompress. This allocates memory and may throw. CompressDebugInfo::RestoreBoundariesAndVars( - fpNew, pNewData, // allocators + fpNew, + pNewData, // allocators + boundsType, pDebugInfo, // input pcMap, ppMap, // output pcVars, ppVars, // output @@ -6295,6 +6312,37 @@ BOOL ReadyToRunJitManager::GetBoundariesAndVars( return TRUE; } +size_t ReadyToRunJitManager::WalkILOffsets( + const DebugInfoRequest & request, + BoundsType boundsType, + void* pContext, + size_t (* pfnWalkILOffsets)(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext)) +{ + CONTRACTL { + THROWS; // on OOM. + GC_NOTRIGGER; // getting vars shouldn't trigger + SUPPORTS_DAC; + } CONTRACTL_END; + + EECodeInfo codeInfo(request.GetStartAddress()); + if (!codeInfo.IsValid()) + return FALSE; + + ReadyToRunInfo * pReadyToRunInfo = JitTokenToReadyToRunInfo(codeInfo.GetMethodToken()); + PTR_RUNTIME_FUNCTION pRuntimeFunction = JitTokenToRuntimeFunction(codeInfo.GetMethodToken()); + + PTR_BYTE pDebugInfo = pReadyToRunInfo->GetDebugInfo(pRuntimeFunction); + if (pDebugInfo == NULL) + return FALSE; + + // Uncompress. This allocates memory and may throw. + return CompressDebugInfo::WalkILOffsets( + pDebugInfo, // input + boundsType, + FALSE, // no patchpoint info + pContext, pfnWalkILOffsets); +} + BOOL ReadyToRunJitManager::GetRichDebugInfo( const DebugInfoRequest& request, IN FP_IDS_NEW fpNew, IN void* pNewData, diff --git a/src/coreclr/vm/codeman.h b/src/coreclr/vm/codeman.h index 4e4401c7589919..47304d833fc0ea 100644 --- a/src/coreclr/vm/codeman.h +++ b/src/coreclr/vm/codeman.h @@ -183,9 +183,6 @@ struct RealCodeHeader DWORD nUnwindInfos; T_RUNTIME_FUNCTION unwindInfos[0]; #endif // FEATURE_EH_FUNCLETS - -public: -// if we're using the indirect codeheaders then all enumeration is done by the code header }; struct InterpreterRealCodeHeader @@ -468,10 +465,10 @@ struct CodeHeapRequestInfo // committed on demand). // // A CodeHeap is naturally protected from multiple threads by the code heap -// critical section - m_pCodeHeapCritSec - so if the implementation of the heap +// critical section - m_CodeHeapLock - so if the implementation of the heap // is only for the code manager, no locking needs to occur. // It's important however that a delete operation on the CodeHeap (if any) happens -// via EECodeGenManager::FreeCodeMemory(HostCodeHeap*, void*) +// via a EECodeGenManager and not directly. // // The heap to be created depends on the MethodDesc that is being compiled. // Standard code uses the LoaderCodeHeap, a heap based on the LoaderHeap. @@ -490,10 +487,10 @@ class CodeHeap VPTR_BASE_VTABLE_CLASS(CodeHeap) public: - CodeHeap() {} + CodeHeap() = default; // virtual dtor. Clean up heap - virtual ~CodeHeap() {} + virtual ~CodeHeap() = default; // Alloc the specified numbers of bytes for code. Returns NULL if the request does not fit // Space for header is reserved immediately before. It is not included in size. @@ -502,9 +499,6 @@ class CodeHeap #ifdef DACCESS_COMPILE virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags) = 0; #endif - -protected: - friend class EEJitManager; }; //----------------------------------------------------------------------------- @@ -562,7 +556,7 @@ struct HeapList // typedef VPTR(class LoaderCodeHeap) PTR_LoaderCodeHeap; -class LoaderCodeHeap : CodeHeap +class LoaderCodeHeap final : public CodeHeap { #ifdef DACCESS_COMPILE friend class ClrDataAccess; @@ -582,10 +576,7 @@ class LoaderCodeHeap : CodeHeap static HeapList* CreateCodeHeap(CodeHeapRequestInfo *pInfo, LoaderHeap *pJitMetaHeap); public: - virtual ~LoaderCodeHeap() - { - WRAPPER_NO_CONTRACT; - } + virtual ~LoaderCodeHeap() = default; virtual void* AllocMemForCode_NoThrow(size_t header, size_t size, DWORD alignment, size_t reserveForJumpStubs) DAC_EMPTY_RET(NULL); @@ -598,32 +589,23 @@ class LoaderCodeHeap : CodeHeap #endif }; -#if defined(HOST_64BIT) -// On non X86 platforms, the OS defined UnwindInfo (accessed from RUNTIME_FUNCTION -// structures) to support the ability unwind the stack. Unfortunatey the pre-Win8 +typedef DPTR(class UnwindInfoTable) PTR_UnwindInfoTable; +// On Windows x64, publish OS UnwindInfo (accessed from RUNTIME_FUNCTION +// structures) to support the ability unwind the stack. Unfortunately the pre-Win8 // APIs defined a callback API for publishing this data dynamically that ETW does -// not use (and really can't because the walk happens in the kernel). In Win8 +// not use (and really can't because the walk happens in the kernel). In Win8 // new APIs were defined that allow incremental publishing via a table. // // UnwindInfoTable is a class that wraps the OS APIs that we use to publish -// this table. Its job is to allocate the table, deallocate it when we are -// done and allow us to add new entries one at a time (AddToUnwindInfoTable) +// this table. Its job is to allocate the table, deallocate it when we are +// done and allow us to add new entries one at a time (AddToUnwindInfoTable). // // Each _rangesection has a UnwindInfoTable's which hold the // RUNTIME_FUNCTION array as well as other bookkeeping (the current and maximum // size of the array, and the handle used to publish it to the OS. // -// Ideally we would just use this new API when it is available, however to mininmize -// risk and to make the change perfectly pay-for-play, we us the original mechanism -// ALWAYS, and in addition publish via the Table ONLY WHEN ETW JIT events are turned -// on. -// -// This class implements a 'catchup' routine that allows us to publish existing JITTed -// methods when ETW turns on. Currently this is 'sticky' (once we start publishing -// both ways, we do so for the life of the process. -// -typedef DPTR(class UnwindInfoTable) PTR_UnwindInfoTable; -class UnwindInfoTable { +class UnwindInfoTable final +{ public: // All public functions are thread-safe. @@ -631,25 +613,24 @@ class UnwindInfoTable { static void PublishUnwindInfoForMethod(TADDR baseAddress, T_RUNTIME_FUNCTION* unwindInfo, int unwindInfoCount); static void UnpublishUnwindInfoForMethod(TADDR entryPoint); + static void Initialize(); + +#if defined(TARGET_AMD64) && defined(TARGET_WINDOWS) +private: // These are lower level functions that assume you have found the list of UnwindInfoTable entries - // These are used by the stublinker and the high-level method functions above + // These are used by the high-level method functions above static void AddToUnwindInfoTable(UnwindInfoTable** unwindInfoPtr, T_RUNTIME_FUNCTION* data, TADDR rangeStart, TADDR rangeEnd); static void RemoveFromUnwindInfoTable(UnwindInfoTable** unwindInfoPtr, TADDR baseAddress, TADDR entryPoint); - // By default this publishing is off, this routine turns it on (and optionally publishes existing methods) - static void PublishUnwindInfo(bool publishExisting); +public: ~UnwindInfoTable(); private: void UnRegister(); void Register(); UnwindInfoTable(ULONG_PTR rangeStart, ULONG_PTR rangeEnd, ULONG size); - static void PublishUnwindInfoForExistingMethods(); private: - static Volatile s_publishingActive; // Publishing to ETW is turned on - static class Crst* s_pUnwindInfoTableLock; // lock protects all public UnwindInfoTable functions - PVOID hHandle; // OS handle for a published RUNTIME_FUNCTION table ULONG_PTR iRangeStart; // Start of memory described by this table ULONG_PTR iRangeEnd; // End of memory described by this table @@ -657,10 +638,9 @@ class UnwindInfoTable { ULONG cTableCurCount; ULONG cTableMaxCount; int cDeletedEntries; // Number of slots we removed. +#endif // defined(TARGET_AMD64) && defined(TARGET_WINDOWS) }; -#endif // defined(HOST_64BIT) - //----------------------------------------------------------------------------- // The ExecutionManager uses RangeSection as the abstraction of a contiguous // address range to track the code heaps. @@ -1649,7 +1629,7 @@ class CodeFragmentHeap : public ILoaderHeapBackout PTR_FreeBlock m_pFreeBlocks; StubCodeBlockKind m_kind; - Crst m_CritSec; + Crst m_Lock; void AddBlock(VOID * pMem, size_t dwSize); void RemoveBlock(FreeBlock ** ppBlock); @@ -1722,12 +1702,20 @@ class IJitManager virtual BOOL GetBoundariesAndVars( const DebugInfoRequest & request, - IN FP_IDS_NEW fpNew, IN void * pNewData, + IN FP_IDS_NEW fpNew, + IN void * pNewData, + BoundsType boundsType, OUT ULONG32 * pcMap, OUT ICorDebugInfo::OffsetMapping **ppMap, OUT ULONG32 * pcVars, OUT ICorDebugInfo::NativeVarInfo **ppVars) = 0; + virtual size_t WalkILOffsets( + const DebugInfoRequest & request, + BoundsType boundsType, + void* pContext, + size_t (*pfnWalkILOffsets)(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext)) = 0; + virtual BOOL GetRichDebugInfo( const DebugInfoRequest& request, IN FP_IDS_NEW fpNew, IN void* pNewData, @@ -1807,6 +1795,53 @@ class IJitManager PTR_ICodeManager m_runtimeSupport; }; +#if !defined(DACCESS_COMPILE) +class CodeHeapIterator final +{ + // Captured state for each heap in the iterator. + struct HeapListState + { + HeapList* Heap; + void* MapBase; + void* HdrMap; + size_t MaxCodeHeapSize; + }; + + EECodeGenManager* m_manager; + MethodSectionIterator m_Iterator; + CUnorderedArray m_Heaps; + int32_t m_HeapsIndexNext; + LoaderAllocator* m_pLoaderAllocatorFilter; + MethodDesc* m_pCurrent; + +public: + CodeHeapIterator(EECodeGenManager* manager, HeapList* heapList, LoaderAllocator* pLoaderAllocatorFilter); + ~CodeHeapIterator(); + + CodeHeapIterator(CodeHeapIterator const&) = delete; + CodeHeapIterator& operator=(CodeHeapIterator const&) = delete; + CodeHeapIterator(CodeHeapIterator&&) = default; + CodeHeapIterator& operator=(CodeHeapIterator&&) = default; + + bool Next(); + + MethodDesc* GetMethod() + { + LIMITED_METHOD_CONTRACT; + return m_pCurrent; + } + + TADDR GetMethodCode() + { + LIMITED_METHOD_CONTRACT; + return (TADDR)m_Iterator.GetMethodCode(); + } + +private: + bool NextMethodSectionIterator(); +}; +#endif // !DACCESS_COMPILE + class HostCodeHeap; typedef VPTR(class HostCodeHeap) PTR_HostCodeHeap; @@ -1818,14 +1853,16 @@ class EECodeGenManager : public IJitManager #endif friend class CheckDuplicatedStructLayouts; friend class EECodeInfo; + friend class CodeHeapIterator; VPTR_ABSTRACT_VTABLE_CLASS(EECodeGenManager, IJitManager) - struct DomainCodeHeapList { + struct DomainCodeHeapList + { LoaderAllocator *m_pAllocator; CDynArray m_CodeHeapList; - DomainCodeHeapList(); - ~DomainCodeHeapList(); + DomainCodeHeapList(LoaderAllocator* allocator); + ~DomainCodeHeapList() = default; }; public: @@ -1850,12 +1887,20 @@ class EECodeGenManager : public IJitManager protected: BOOL GetBoundariesAndVarsWorker( PTR_BYTE pDebugInfo, - IN FP_IDS_NEW fpNew, IN void * pNewData, + IN FP_IDS_NEW fpNew, + IN void * pNewData, + BoundsType boundsType, OUT ULONG32 * pcMap, OUT ICorDebugInfo::OffsetMapping **ppMap, OUT ULONG32 * pcVars, OUT ICorDebugInfo::NativeVarInfo **ppVars); + size_t WalkILOffsetsWorker( + PTR_BYTE pDebugInfo, + BoundsType boundsType, + void* pContext, + size_t (*pfnWalkILOffsets)(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext)); + BOOL GetRichDebugInfoWorker( PTR_BYTE pDebugInfo, IN FP_IDS_NEW fpNew, IN void* pNewData, @@ -1876,50 +1921,51 @@ class EECodeGenManager : public IJitManager virtual TypeHandle ResolveEHClause(EE_ILEXCEPTION_CLAUSE* pEHClause, CrawlFrame *pCf); - template - void RemoveJitData(TCodeHeader* pCHdr, size_t GCinfo_len, size_t EHinfo_len); void Unload(LoaderAllocator* pAllocator); + +public: void CleanupCodeHeaps(); template - void allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, void** ppCodeHeader, void** ppCodeHeaderRW, + void AllocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, void** ppCodeHeader, void** ppCodeHeaderRW, size_t* pAllocatedSize, HeapList** ppCodeHeap , BYTE** ppRealHeader #ifdef FEATURE_EH_FUNCLETS , UINT nUnwindInfos #endif ); - BYTE *allocFromJitMetaHeap(MethodDesc *pMD, DWORD blockSize, size_t * pAllocationSize); + BYTE *AllocFromJitMetaHeap(MethodDesc *pMD, size_t blockSize); - // Heap Management functions + // Heap Management functions void NibbleMapSet(HeapList * pHp, TADDR pCode, size_t codeSize); + void AddToCleanupList(HostCodeHeap* pCodeHeap); + bool TryFreeHostCodeHeapMemory(HostCodeHeap* pCodeHeap, void* codeStart); + CodeHeapIterator GetCodeHeapIterator(LoaderAllocator* pLoaderAllocatorFilter = NULL); + +private: + void AddRefIterator(); + void ReleaseIterator(); + +protected: + virtual void DeleteFunctionTable(PVOID pvTableID) = 0; + + void* AllocCodeWorker(CodeHeapRequestInfo *pInfo, size_t header, size_t blockSize, unsigned align, HeapList ** ppCodeHeap); void NibbleMapSetUnlocked(HeapList * pHp, TADDR pCode, size_t codeSize); - void NibbleMapDelete(HeapList* pHp, TADDR pCode); void NibbleMapDeleteUnlocked(HeapList* pHp, TADDR pCode); - void FreeCodeMemory(HostCodeHeap *pCodeHeap, void * codeStart); - void RemoveFromCleanupList(HostCodeHeap *pCodeHeap); - void AddToCleanupList(HostCodeHeap *pCodeHeap); +private: + HeapList* NewCodeHeap(CodeHeapRequestInfo *pInfo, DomainCodeHeapList *pADHeapList); void DeleteCodeHeap(HeapList *pHeapList); + void RemoveFromCleanupList(HostCodeHeap *pCodeHeap); void RemoveCodeHeapFromDomainList(CodeHeap *pHeap, LoaderAllocator *pAllocator); - - HeapList* NewCodeHeap(CodeHeapRequestInfo *pInfo, DomainCodeHeapList *pADHeapList); bool CanUseCodeHeap(CodeHeapRequestInfo *pInfo, HeapList *pCodeHeap); -protected: - void* allocCodeRaw(CodeHeapRequestInfo *pInfo, size_t header, size_t blockSize, unsigned align, HeapList ** ppCodeHeap); - virtual void UnpublishUnwindInfoForMethod(TADDR codeStart) = 0; - virtual void DeleteFunctionTable(PVOID pvTableID) = 0; - - DomainCodeHeapList *GetCodeHeapList(CodeHeapRequestInfo *pInfo, LoaderAllocator *pAllocator, BOOL fDynamicOnly = FALSE); + DomainCodeHeapList* GetCodeHeapList(CodeHeapRequestInfo *pInfo, LoaderAllocator *pAllocator, BOOL fDynamicOnly = FALSE); DomainCodeHeapList* CreateCodeHeapList(CodeHeapRequestInfo *pInfo); LoaderHeap* GetJitMetaHeap(MethodDesc *pMD); - HeapList * GetCodeHeapList() - { - return m_pCodeHeap; - } - + void UnloadWorker(LoaderAllocator* pAllocator); + void FreeHostCodeHeapMemoryWorker(HostCodeHeap* pCodeHeap, void* codeStart); #else // !DACCESS_COMPILE virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); protected: @@ -1928,13 +1974,17 @@ class EECodeGenManager : public IJitManager #endif // !DACCESS_COMPILE private: - PTR_HeapList m_pCodeHeap; + PTR_HeapList m_pAllCodeHeaps; // Includes all code heaps, including dynamic ones. PTR_HostCodeHeap m_cleanupList; + // must hold critical section to access this structure. - CUnorderedArray m_DomainCodeHeaps; - CUnorderedArray m_DynamicDomainCodeHeaps; + CUnorderedArray m_DomainCodeHeaps; + CUnorderedArray m_DynamicDomainCodeHeaps; + CUnorderedArray m_delayUnload; + protected: - Crst m_CodeHeapCritSec; + Crst m_CodeHeapLock; + ULONG m_iteratorCount; bool m_storeRichDebugInfo; }; @@ -1995,7 +2045,6 @@ class EEJitManager final : public EECodeGenManager friend class DacDbiInterfaceImpl; #endif friend class CheckDuplicatedStructLayouts; - friend class CodeHeapIterator; VPTR_VTABLE_CLASS(EEJitManager, EECodeGenManager) @@ -2041,12 +2090,9 @@ class EEJitManager final : public EECodeGenManager #if !defined DACCESS_COMPILE EEJitManager(); - - // No destructor necessary. Only one instance of this class that is destroyed at process shutdown. - // ~EEJitManager(); + ~EEJitManager() = default; #endif // !DACCESS_COMPILE - virtual DWORD GetCodeType() { LIMITED_METHOD_DAC_CONTRACT; @@ -2056,12 +2102,20 @@ class EEJitManager final : public EECodeGenManager // Used to read debug info. virtual BOOL GetBoundariesAndVars( const DebugInfoRequest & request, - IN FP_IDS_NEW fpNew, IN void * pNewData, + IN FP_IDS_NEW fpNew, + IN void * pNewData, + BoundsType boundsType, OUT ULONG32 * pcMap, OUT ICorDebugInfo::OffsetMapping **ppMap, OUT ULONG32 * pcVars, OUT ICorDebugInfo::NativeVarInfo **ppVars); + virtual size_t WalkILOffsets( + const DebugInfoRequest & request, + BoundsType boundsType, + void* pContext, + size_t (*pfnWalkILOffsets)(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext)); + virtual BOOL GetRichDebugInfo( const DebugInfoRequest& request, IN FP_IDS_NEW fpNew, IN void* pNewData, @@ -2091,12 +2145,12 @@ class EEJitManager final : public EECodeGenManager #if !defined DACCESS_COMPILE BOOL LoadJIT(); - JumpStubBlockHeader* allocJumpStubBlock(MethodDesc* pMD, DWORD numJumps, + JumpStubBlockHeader* AllocJumpStubBlock(MethodDesc* pMD, DWORD numJumps, BYTE * loAddr, BYTE * hiAddr, LoaderAllocator *pLoaderAllocator, bool throwOnOutOfMemoryWithinRange); - void * allocCodeFragmentBlock(size_t blockSize, unsigned alignment, LoaderAllocator *pLoaderAllocator, StubCodeBlockKind kind); + void * AllocCodeFragmentBlock(size_t blockSize, unsigned alignment, LoaderAllocator *pLoaderAllocator, StubCodeBlockKind kind); #endif // !DACCESS_COMPILE static CodeHeader * GetCodeHeader(const METHODTOKEN& MethodToken); @@ -2124,33 +2178,7 @@ class EEJitManager final : public EECodeGenManager #endif // FEATURE_EH_FUNCLETS #if !defined DACCESS_COMPILE - class CodeHeapIterator - { - CrstHolder m_lockHolder; - HeapList *m_pHeapList; - LoaderAllocator *m_pLoaderAllocator; - MethodSectionIterator m_Iterator; - MethodDesc *m_pCurrent; - - public: - CodeHeapIterator(LoaderAllocator *pLoaderAllocatorFilter = NULL); - ~CodeHeapIterator(); - BOOL Next(); - - MethodDesc *GetMethod() - { - LIMITED_METHOD_CONTRACT; - return m_pCurrent; - } - - TADDR GetMethodCode() - { - LIMITED_METHOD_CONTRACT; - return (TADDR)m_Iterator.GetMethodCode(); - } - }; protected: - virtual void UnpublishUnwindInfoForMethod(TADDR codeStart); virtual void DeleteFunctionTable(PVOID pvTableID); #endif // !DACCESS_COMPILE @@ -2169,7 +2197,7 @@ class EEJitManager final : public EECodeGenManager } private : - Crst m_JitLoadCritSec; + Crst m_JitLoadLock; #ifdef TARGET_AMD64 private: @@ -2204,8 +2232,17 @@ private : HINSTANCE m_AltJITCompiler; bool m_AltJITRequired; #endif //ALLOW_SXS_JIT + + friend struct ::cdac_data; }; +template<> +struct cdac_data +{ + static constexpr size_t StoreRichDebugInfo = offsetof(EEJitManager, m_storeRichDebugInfo); +}; + + //***************************************************************************** // // This class manages IJitManagers and ICorJitCompilers. It has only static @@ -2599,7 +2636,7 @@ class HotColdMappingLookupTable #ifdef FEATURE_READYTORUN -class ReadyToRunJitManager final: public IJitManager +class ReadyToRunJitManager final : public IJitManager { VPTR_VTABLE_CLASS(ReadyToRunJitManager, IJitManager) @@ -2617,12 +2654,20 @@ class ReadyToRunJitManager final: public IJitManager // Used to read debug info. virtual BOOL GetBoundariesAndVars( const DebugInfoRequest & request, - IN FP_IDS_NEW fpNew, IN void * pNewData, + IN FP_IDS_NEW fpNew, + IN void * pNewData, + BoundsType boundsType, OUT ULONG32 * pcMap, OUT ICorDebugInfo::OffsetMapping **ppMap, OUT ULONG32 * pcVars, OUT ICorDebugInfo::NativeVarInfo **ppVars); + virtual size_t WalkILOffsets( + const DebugInfoRequest & request, + BoundsType boundsType, + void* pContext, + size_t (*pfnWalkILOffsets)(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext)); + virtual BOOL GetRichDebugInfo( const DebugInfoRequest & request, IN FP_IDS_NEW fpNew, IN void * pNewData, @@ -2736,12 +2781,20 @@ class InterpreterJitManager final : public EECodeGenManager // Used to read debug info. virtual BOOL GetBoundariesAndVars( const DebugInfoRequest & request, - IN FP_IDS_NEW fpNew, IN void * pNewData, + IN FP_IDS_NEW fpNew, + IN void * pNewData, + BoundsType boundsType, OUT ULONG32 * pcMap, OUT ICorDebugInfo::OffsetMapping **ppMap, OUT ULONG32 * pcVars, OUT ICorDebugInfo::NativeVarInfo **ppVars); + virtual size_t WalkILOffsets( + const DebugInfoRequest & request, + BoundsType boundsType, + void* pContext, + size_t (*pfnWalkILOffsets)(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext)); + virtual BOOL GetRichDebugInfo( const DebugInfoRequest& request, IN FP_IDS_NEW fpNew, IN void* pNewData, @@ -2763,11 +2816,6 @@ class InterpreterJitManager final : public EECodeGenManager #if !defined DACCESS_COMPILE protected: - virtual void UnpublishUnwindInfoForMethod(TADDR codeStart) - { - // Nothing to do for the interpreter - } - virtual void DeleteFunctionTable(PVOID pvTableID) { // Nothing to do for the interpreter @@ -2797,7 +2845,7 @@ class InterpreterJitManager final : public EECodeGenManager #endif // FEATURE_EH_FUNCLETS #endif // DACCESS_COMPILE private : - Crst m_interpreterLoadCritSec; + Crst m_interpreterLoadLock; }; #endif // FEATURE_INTERPRETER diff --git a/src/coreclr/vm/codeversion.cpp b/src/coreclr/vm/codeversion.cpp index 9b95ef12f9de83..9a2af2a97f79d0 100644 --- a/src/coreclr/vm/codeversion.cpp +++ b/src/coreclr/vm/codeversion.cpp @@ -12,9 +12,11 @@ #ifdef FEATURE_CODE_VERSIONING #include "threadsuspend.h" #include "methoditer.h" +#ifdef DDEBUGGING_SUPPORTED #include "../debug/ee/debugger.h" #include "../debug/ee/walker.h" #include "../debug/ee/controller.h" +#endif // DDEBUGGING_SUPPORTED #endif // FEATURE_CODE_VERSIONING #ifndef FEATURE_CODE_VERSIONING @@ -911,7 +913,7 @@ PTR_COR_ILMETHOD ILCodeVersion::GetIL() const { PTR_Module pModule = GetModule(); PTR_MethodDesc pMethodDesc = dac_cast(pModule->LookupMethodDef(GetMethodDef())); - if (pMethodDesc != NULL) + if (pMethodDesc != NULL && pMethodDesc->MayHaveILHeader()) { pIL = dac_cast(pMethodDesc->GetILHeader()); } diff --git a/src/coreclr/vm/comdelegate.cpp b/src/coreclr/vm/comdelegate.cpp index d9ff94baaabe42..cc9535ca13f6ed 100644 --- a/src/coreclr/vm/comdelegate.cpp +++ b/src/coreclr/vm/comdelegate.cpp @@ -475,6 +475,18 @@ BOOL GenerateShuffleArrayPortable(MethodDesc* pMethodSrc, MethodDesc *pMethodDst #endif // !defined(TARGET_ARM64) || !defined(CALLDESCR_RETBUFFARGREG) } + // Handle async continuation argument. + _ASSERTE(!!sArgPlacerDst.HasAsyncContinuation() == !!sArgPlacerSrc.HasAsyncContinuation()); + if (sArgPlacerDst.HasAsyncContinuation()) + { + // The async continuation is implicit in both signatures. + sArgPlacerSrc.GetAsyncContinuationLoc(&sArgSrc); + sArgPlacerDst.GetAsyncContinuationLoc(&sArgDst); + + if (!AddNextShuffleEntryToArray(sArgSrc, sArgDst, pShuffleEntryArray, shuffleType)) + return FALSE; + } + // Iterate all the regular arguments. mapping source registers and stack locations to the corresponding // destination locations. while ((ofsSrc = sArgPlacerSrc.GetNextOffset()) != TransitionBlock::InvalidOffset) @@ -1541,9 +1553,9 @@ PCODE COMDelegate::GetStubForILStub(EEImplMethodDesc* pDelegateMD, MethodDesc** ValidateDelegatePInvoke(pDelegateMD); - dwStubFlags |= NDIRECTSTUB_FL_DELEGATE; + dwStubFlags |= PINVOKESTUB_FL_DELEGATE; - RETURN NDirect::GetStubForILStub(pDelegateMD, ppStubMD, dwStubFlags); + RETURN PInvoke::GetStubForILStub(pDelegateMD, ppStubMD, dwStubFlags); } @@ -1555,10 +1567,10 @@ MethodDesc* COMDelegate::GetILStubMethodDesc(EEImplMethodDesc* pDelegateMD, DWOR MethodTable *pMT = pDelegateMD->GetMethodTable(); - dwStubFlags |= NDIRECTSTUB_FL_DELEGATE; + dwStubFlags |= PINVOKESTUB_FL_DELEGATE; PInvokeStaticSigInfo sigInfo(pDelegateMD); - return NDirect::CreateCLRToNativeILStub(&sigInfo, dwStubFlags, pDelegateMD); + return PInvoke::CreateCLRToNativeILStub(&sigInfo, dwStubFlags, pDelegateMD); } extern "C" void QCALLTYPE Delegate_InitializeVirtualCallStub(QCall::ObjectHandleOnStack d, PCODE method) @@ -2034,7 +2046,7 @@ void COMDelegate::ThrowIfInvalidUnmanagedCallersOnlyUsage(MethodDesc* pMD) // Arguments - Scenarios involving UnmanagedCallersOnly are handled during the jit. bool unmanagedCallersOnlyRequiresMarshalling = false; - if (NDirect::MarshalingRequired(pMD, NULL, NULL, NULL, unmanagedCallersOnlyRequiresMarshalling)) + if (PInvoke::MarshalingRequired(pMD, NULL, NULL, NULL, unmanagedCallersOnlyRequiresMarshalling)) EX_THROW(EEResourceException, (kInvalidProgramException, W("InvalidProgram_NonBlittableTypes"))); } diff --git a/src/coreclr/vm/comdependenthandle.cpp b/src/coreclr/vm/comdependenthandle.cpp index 8f78d01b365bc7..74a1834ca0b514 100644 --- a/src/coreclr/vm/comdependenthandle.cpp +++ b/src/coreclr/vm/comdependenthandle.cpp @@ -43,7 +43,6 @@ extern "C" OBJECTHANDLE QCALLTYPE DependentHandle_InternalAllocWithGCTransition( FCIMPL1(Object*, DependentHandle::InternalGetTarget, OBJECTHANDLE handle) { FCALL_CONTRACT; - FCUnique(0x54); _ASSERTE(handle != NULL); diff --git a/src/coreclr/vm/common.h b/src/coreclr/vm/common.h index bb587124cf168f..858f6523bb7f05 100644 --- a/src/coreclr/vm/common.h +++ b/src/coreclr/vm/common.h @@ -142,7 +142,7 @@ typedef DPTR(class MethodImpl) PTR_MethodImpl; typedef DPTR(class MethodTable) PTR_MethodTable; typedef DPTR(class CoreLibBinder) PTR_CoreLibBinder; typedef VPTR(class Module) PTR_Module; -typedef DPTR(class NDirectMethodDesc) PTR_NDirectMethodDesc; +typedef DPTR(class PInvokeMethodDesc) PTR_PInvokeMethodDesc; typedef DPTR(class Thread) PTR_Thread; typedef DPTR(class Object) PTR_Object; typedef DPTR(PTR_Object) PTR_PTR_Object; @@ -202,7 +202,7 @@ Thread * const CURRENT_THREAD = NULL; (void)CURRENT_THREAD_AVAILABLE; /* silence "local variable initialized but not used" warning */ \ #ifndef DACCESS_COMPILE -EXTERN_C AppDomain* STDCALL GetAppDomain(); +AppDomain* GetAppDomain(); #endif //!DACCESS_COMPILE extern BOOL isMemoryReadable(const TADDR start, unsigned len); diff --git a/src/coreclr/vm/comtoclrcall.cpp b/src/coreclr/vm/comtoclrcall.cpp index bd77809701cded..cc8a1129618712 100644 --- a/src/coreclr/vm/comtoclrcall.cpp +++ b/src/coreclr/vm/comtoclrcall.cpp @@ -174,8 +174,7 @@ inline static void InvokeStub(ComCallMethodDesc *pCMD, PCODE pManagedTarget, OBJ ARG_SLOT retVal = 0; PCODE pStubEntryPoint = pCMD->GetILStub(); - INT_PTR dangerousThis; - *(OBJECTREF *)&dangerousThis = orThis; + INT_PTR dangerousThis = (INT_PTR)OBJECTREFToObject(orThis); DWORD dwStackSlots = pCMD->GetNumStackBytes() / TARGET_POINTER_SIZE; @@ -1212,7 +1211,7 @@ void ComCall::PopulateComCallMethodDesc(ComCallMethodDesc *pCMD, DWORD *pdwStubF } CONTRACTL_END; - DWORD dwStubFlags = NDIRECTSTUB_FL_COM | NDIRECTSTUB_FL_REVERSE_INTEROP; + DWORD dwStubFlags = PINVOKESTUB_FL_COM | PINVOKESTUB_FL_REVERSE_INTEROP; BOOL BestFit = TRUE; BOOL ThrowOnUnmappableChar = FALSE; @@ -1220,9 +1219,9 @@ void ComCall::PopulateComCallMethodDesc(ComCallMethodDesc *pCMD, DWORD *pdwStubF if (pCMD->IsFieldCall()) { if (pCMD->IsFieldGetter()) - dwStubFlags |= NDIRECTSTUB_FL_FIELDGETTER; + dwStubFlags |= PINVOKESTUB_FL_FIELDGETTER; else - dwStubFlags |= NDIRECTSTUB_FL_FIELDSETTER; + dwStubFlags |= PINVOKESTUB_FL_FIELDSETTER; FieldDesc *pFD = pCMD->GetFieldDesc(); _ASSERTE(IsMemberVisibleFromCom(pFD->GetApproxEnclosingMethodTable(), pFD->GetMemberDef(), mdTokenNil) && "Calls are not permitted on this member since it isn't visible from COM. The only way you can have reached this code path is if your native interface doesn't match the managed interface."); @@ -1241,10 +1240,10 @@ void ComCall::PopulateComCallMethodDesc(ComCallMethodDesc *pCMD, DWORD *pdwStubF } if (BestFit) - dwStubFlags |= NDIRECTSTUB_FL_BESTFIT; + dwStubFlags |= PINVOKESTUB_FL_BESTFIT; if (ThrowOnUnmappableChar) - dwStubFlags |= NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR; + dwStubFlags |= PINVOKESTUB_FL_THROWONUNMAPPABLECHAR; // // fill in out param @@ -1305,7 +1304,7 @@ MethodDesc* ComCall::GetILStubMethodDesc(MethodDesc *pCallMD, DWORD dwStubFlags) // Get the call signature information StubSigDesc sigDesc(pCallMD); - return NDirect::CreateCLRToNativeILStub(&sigDesc, + return PInvoke::CreateCLRToNativeILStub(&sigDesc, (CorNativeLinkType)0, (CorNativeLinkFlags)0, CallConv::GetDefaultUnmanagedCallingConvention(), @@ -1332,7 +1331,7 @@ MethodDesc* ComCall::GetILStubMethodDesc(FieldDesc *pFD, DWORD dwStubFlags) // Get the field signature information pFD->GetSig(&pSig, &cSig); - return NDirect::CreateFieldAccessILStub(pSig, + return PInvoke::CreateFieldAccessILStub(pSig, cSig, pFD->GetModule(), pFD->GetMemberDef(), diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index e8b08578d97d79..95a615ca36207d 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -33,6 +33,7 @@ #include "typestring.h" #include "finalizerthread.h" #include "threadsuspend.h" +#include #ifdef FEATURE_COMINTEROP #include "comcallablewrapper.h" @@ -1561,7 +1562,7 @@ extern "C" void QCALLTYPE Interlocked_MemoryBarrierProcessWide() { QCALL_CONTRACT; - FlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); } static BOOL HasOverriddenMethod(MethodTable* mt, MethodTable* classMT, WORD methodSlot) diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 16cd41fd7e90f4..0b979353253f72 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -709,7 +709,7 @@ DEFINE_METHOD(RUNTIME_HELPERS, GET_RAW_DATA, GetRawData, DEFINE_METHOD(RUNTIME_HELPERS, GET_UNINITIALIZED_OBJECT, GetUninitializedObject, SM_Type_RetObj) DEFINE_METHOD(RUNTIME_HELPERS, ENUM_EQUALS, EnumEquals, NoSig) DEFINE_METHOD(RUNTIME_HELPERS, ENUM_COMPARE_TO, EnumCompareTo, NoSig) -DEFINE_METHOD(RUNTIME_HELPERS, ALLOC_TAILCALL_ARG_BUFFER, AllocTailCallArgBuffer, SM_Int_IntPtr_RetIntPtr) +DEFINE_METHOD(RUNTIME_HELPERS, ALLOC_TAILCALL_ARG_BUFFER, AllocTailCallArgBuffer, NoSig) DEFINE_METHOD(RUNTIME_HELPERS, GET_TAILCALL_INFO, GetTailCallInfo, NoSig) DEFINE_METHOD(RUNTIME_HELPERS, DISPATCH_TAILCALLS, DispatchTailCalls, NoSig) #ifdef FEATURE_IJW @@ -728,6 +728,9 @@ DEFINE_METHOD(ASYNC_HELPERS, FINALIZE_VALUETASK_RETURNING_THUNK_1, Finalize DEFINE_METHOD(ASYNC_HELPERS, UNSAFE_AWAIT_AWAITER_1, UnsafeAwaitAwaiter, GM_T_RetVoid) DEFINE_METHOD(ASYNC_HELPERS, CAPTURE_EXECUTION_CONTEXT, CaptureExecutionContext, NoSig) DEFINE_METHOD(ASYNC_HELPERS, RESTORE_EXECUTION_CONTEXT, RestoreExecutionContext, NoSig) +DEFINE_METHOD(ASYNC_HELPERS, CAPTURE_CONTINUATION_CONTEXT, CaptureContinuationContext, NoSig) +DEFINE_METHOD(ASYNC_HELPERS, CAPTURE_CONTEXTS, CaptureContexts, NoSig) +DEFINE_METHOD(ASYNC_HELPERS, RESTORE_CONTEXTS, RestoreContexts, NoSig) DEFINE_CLASS(SPAN_HELPERS, System, SpanHelpers) DEFINE_METHOD(SPAN_HELPERS, MEMSET, Fill, SM_RefByte_Byte_UIntPtr_RetVoid) @@ -1038,7 +1041,7 @@ DEFINE_METHOD(BUFFER, MEMCOPYGC, BulkMoveWithWriteBar DEFINE_CLASS(STUBHELPERS, StubHelpers, StubHelpers) DEFINE_METHOD(STUBHELPERS, GET_DELEGATE_TARGET, GetDelegateTarget, SM_Delegate_RetIntPtr) #ifdef FEATURE_COMINTEROP -DEFINE_METHOD(STUBHELPERS, GET_COM_HR_EXCEPTION_OBJECT, GetCOMHRExceptionObject, SM_Int_IntPtr_Obj_RetException) +DEFINE_METHOD(STUBHELPERS, GET_COM_HR_EXCEPTION_OBJECT, GetCOMHRExceptionObject, SM_Int_IntPtr_IntPtr_RetException) DEFINE_METHOD(STUBHELPERS, GET_COM_IP_FROM_RCW, GetCOMIPFromRCW, SM_Obj_IntPtr_RefIntPtr_RefBool_RetIntPtr) #endif // FEATURE_COMINTEROP DEFINE_METHOD(STUBHELPERS, SET_LAST_ERROR, SetLastError, SM_RetVoid) diff --git a/src/coreclr/vm/corhost.cpp b/src/coreclr/vm/corhost.cpp index 028534a932b8a9..2537e0bf3d5a33 100644 --- a/src/coreclr/vm/corhost.cpp +++ b/src/coreclr/vm/corhost.cpp @@ -636,7 +636,7 @@ HRESULT CorHost2::CreateAppDomainWithManager( sAppPaths)); } -#if defined(TARGET_UNIX) +#if defined(TARGET_UNIX) && !defined(FEATURE_STATICALLY_LINKED) if (!g_coreclr_embedded) { // Check if the current code is executing in the single file host or in libcoreclr.so. The libSystem.Native is linked diff --git a/src/coreclr/vm/crst.cpp b/src/coreclr/vm/crst.cpp index 3e662b7162acd3..4825e44e744dc5 100644 --- a/src/coreclr/vm/crst.cpp +++ b/src/coreclr/vm/crst.cpp @@ -645,10 +645,13 @@ BOOL CrstBase::IsSafeToTake() // when the thread is doing a stressing GC, some Crst violations could be ignored // also, we want to keep an explicit list of Crst's that we may take during GC stress || (pThread && pThread->GetGCStressing () - && (m_crstType == CrstThreadStore || m_crstType == CrstHandleTable - || m_crstType == CrstSyncBlockCache || m_crstType == CrstIbcProfile - || m_crstType == CrstAvailableParamTypes || m_crstType == CrstSystemDomainDelayedUnloadList - || m_crstType == CrstAssemblyList || m_crstType == CrstJumpStubCache + && (m_crstType == CrstThreadStore + || m_crstType == CrstHandleTable + || m_crstType == CrstSyncBlockCache + || m_crstType == CrstAvailableParamTypes + || m_crstType == CrstSystemDomainDelayedUnloadList + || m_crstType == CrstAssemblyList + || m_crstType == CrstJumpStubCache || m_crstType == CrstSingleUseLock) ) || (pThread && pThread->GetUniqueStacking ()) diff --git a/src/coreclr/vm/crst.h b/src/coreclr/vm/crst.h index a43fc54111d267..12bdad22224cba 100644 --- a/src/coreclr/vm/crst.h +++ b/src/coreclr/vm/crst.h @@ -168,8 +168,6 @@ class CrstBase void Enter(INDEBUG(NoLevelCheckFlag noLevelCheckFlag = CRST_LEVEL_CHECK)); void Leave(); - void SpinEnter(); - #ifndef DACCESS_COMPILE DEBUG_NOINLINE static void AcquireLock(CrstBase *c) { WRAPPER_NO_CONTRACT; @@ -344,18 +342,23 @@ class CrstBase CrstBase * m_pCrst; public: - inline CrstHolder(CrstBase * pCrst) - : m_pCrst(pCrst) + CrstHolder(CrstBase* pCrst) + : m_pCrst{ pCrst } { WRAPPER_NO_CONTRACT; AcquireLock(pCrst); } - inline ~CrstHolder() + ~CrstHolder() { WRAPPER_NO_CONTRACT; ReleaseLock(m_pCrst); } + + CrstHolder(CrstHolder const&) = delete; + CrstHolder &operator=(CrstHolder const&) = delete; + CrstHolder(CrstHolder&& other) = delete; + CrstHolder& operator=(CrstHolder&& other) = delete; }; // Note that the holders for CRSTs are used in extremely low stack conditions. Because of this, they diff --git a/src/coreclr/debug/runtimeinfo/.editorconfig b/src/coreclr/vm/datadescriptor/.editorconfig similarity index 100% rename from src/coreclr/debug/runtimeinfo/.editorconfig rename to src/coreclr/vm/datadescriptor/.editorconfig diff --git a/src/coreclr/vm/datadescriptor/CMakeLists.txt b/src/coreclr/vm/datadescriptor/CMakeLists.txt new file mode 100644 index 00000000000000..3114d94b23d3b7 --- /dev/null +++ b/src/coreclr/vm/datadescriptor/CMakeLists.txt @@ -0,0 +1,18 @@ +# cDAC contract descriptor + +if(CDAC_BUILD_TOOL_BINARY_PATH AND "${CLR_DOTNET_RID}" STREQUAL "") + message(FATAL_ERROR "CLR_DOTNET_RID is not set. Please ensure it is being set to the portable RID of the target platform by runtime.proj.") +endif() +configure_file(configure.h.in ${CMAKE_CURRENT_BINARY_DIR}/configure.h) + +add_library(runtime_descriptor_interface INTERFACE) +target_include_directories(runtime_descriptor_interface INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}) +add_dependencies(runtime_descriptor_interface cee_wks_core) +generate_data_descriptors( + LIBRARY_NAME cdac_contract_descriptor + CONTRACT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/contracts.jsonc" + CONTRACT_NAME "DotNetRuntimeContractDescriptor" + INTERFACE_TARGET runtime_descriptor_interface + EXPORT_VISIBLE) diff --git a/src/coreclr/debug/runtimeinfo/configure.h.in b/src/coreclr/vm/datadescriptor/configure.h.in similarity index 100% rename from src/coreclr/debug/runtimeinfo/configure.h.in rename to src/coreclr/vm/datadescriptor/configure.h.in diff --git a/src/coreclr/debug/runtimeinfo/contracts.jsonc b/src/coreclr/vm/datadescriptor/contracts.jsonc similarity index 90% rename from src/coreclr/debug/runtimeinfo/contracts.jsonc rename to src/coreclr/vm/datadescriptor/contracts.jsonc index 56eda8d256e469..63d61aeda40baf 100644 --- a/src/coreclr/debug/runtimeinfo/contracts.jsonc +++ b/src/coreclr/vm/datadescriptor/contracts.jsonc @@ -11,18 +11,18 @@ { "CodeVersions": 1, "DacStreams": 1, - "ECall": 1, - "EcmaMetadata" : 1, + "DebugInfo": 1, + "EcmaMetadata": 1, "Exception": 1, "ExecutionManager": 2, "Loader": 1, "Object": 1, "PlatformMetadata": 1, - "PrecodeStubs": 2, + "PrecodeStubs": 3, "ReJIT": 1, "RuntimeInfo": 1, "RuntimeTypeSystem": 1, "StackWalk": 1, "StressLog": 2, "Thread": 1 -} +} \ No newline at end of file diff --git a/src/coreclr/vm/datadescriptor/datadescriptor.h b/src/coreclr/vm/datadescriptor/datadescriptor.h new file mode 100644 index 00000000000000..2123bd81f8ebce --- /dev/null +++ b/src/coreclr/vm/datadescriptor/datadescriptor.h @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "common.h" + +#include +#include + +#include "static_assert.h" + +#include +#include "cdacplatformmetadata.hpp" +#include "methodtable.h" +#include "threads.h" +#include "vars.hpp" +#include "exinfo.h" + +#include "configure.h" + +#include "../debug/ee/debugger.h" +#include "patchpointinfo.h" + +#ifdef HAVE_GCCOVER +#include "gccover.h" +#endif // HAVE_GCCOVER diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.h b/src/coreclr/vm/datadescriptor/datadescriptor.inc similarity index 87% rename from src/coreclr/debug/runtimeinfo/datadescriptor.h rename to src/coreclr/vm/datadescriptor/datadescriptor.inc index 94157d0e8f955c..ffc5f2ec3a0c9d 100644 --- a/src/coreclr/debug/runtimeinfo/datadescriptor.h +++ b/src/coreclr/vm/datadescriptor/datadescriptor.inc @@ -2,108 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // // No include guards. This file is included multiple times. - -// The format is: -// CDAC_BASELINE("string") baseline data contract that the runtime should follow. "empty" is reasonable -// CDAC_TYPES_BEGIN() -// ... ... -// CDAC_TYPES_END() -// CDAC_GLOBALS_BEGIN() -// ... ... -// CDAC_GLOBALS_END() -// -// In the format is: -// CDAC_TYPE_BEGIN(cdacTypeIdentifier) // defined a new data descriptor named cdacIdentifier -// -// CDAC_TYPE_SIZE(k) -or- CDAC_TYPE_INDETERMINATE(cdacTypeIdentifier) specifies that the type has -// size k (bytes - usually sizeof(SomeNativeType)) or specify that the type's size is not provided -// It is important that CDAC_TYPE_SIZE or CDAC_TYPE_INDETERMINATE immediately follows -// CDAC_TYPE_BEGIN -// -// CDAC_TYPE_FIELD(cdacTypeIdentifier, cdacFieldTypeIdentifier, cdacFieldName, k) specifies the -// field of "cdacTypeIdentifier" that has name cdacFieldName and has the type -// "cdacFieldtypeIdentifier" located at offset k in the type layout. k is usually -// offsetof(SomeClass, m_FieldName) if the field is public -// -// if the field is private, the convention is that SomeClass declares a friend struct -// cdac_data and provides a specialization of cdac_data with a public constexpr -// size_t member that holds the offset: -// -// class MyClass { -// private: -// void* m_myField; -// friend template cdac_data; -// }; -// template<> struct cdac_data { -// static constexpr size_t MyField = offsetof(MyClass, m_myField); -// }; -// -// then the field layout can be specified as -// CDAC_TYPE_FIELD(MyClassLayout, pointer, MyField, cdac_data::MyField) -// There can be zero or more CDAC_TYPE_FIELD entries per type layout -// For types mapping to managed objects, use exact managed type field names in the descriptor, as -// field names often can't change due to binary serialization or implicit diagnostic contracts -// -// CDAC_TYPE_END(cdacTypeIdentifier) specifies the end of the type layout for cdacTypeIdentifier -// -// In the format is: -// -// CDAC_GLOBAL(cdacGlobalName, cdacTypeIdentifier, value) -// or -// CDAC_GLOBAL_POINTER(cdacGlobalName, cdacTypeIdentifier, address) -// -// Zero or more globals can be defined -// -// if a global is given with CDAC_GLOBAL(), `value` should be a constexpr uint64_t (or convertible -// to uint64_t) for example, it can be a literal constant or a preprocessor definition -// -// if a global is a CDAC_GLOBAL_POINTER(), address should be a constexpr pointer or a constexpr -// uintptr_t -// -// // // This file is compiled using the target architecture. Preprocessor defines for the target // platform will be available. It is ok to use `#ifdef`. -#ifndef CDAC_BASELINE -#define CDAC_BASELINE(identifier) -#endif -#ifndef CDAC_TYPES_BEGIN -#define CDAC_TYPES_BEGIN() -#endif -#ifndef CDAC_TYPE_BEGIN -#define CDAC_TYPE_BEGIN(tyname) -#endif -#ifndef CDAC_TYPE_SIZE -#define CDAC_TYPE_SIZE(k) -#endif -#ifndef CDAC_TYPE_INDETERMINATE -#define CDAC_TYPE_INDETERMINATE(tyname) -#endif -#ifndef CDAC_TYPE_FIELD -#define CDAC_TYPE_FIELD(tyname,fieldtyname,fieldname,off) -#endif -#ifndef CDAC_TYPE_END -#define CDAC_TYPE_END(tyname) -#endif -#ifndef CDAC_TYPES_END -#define CDAC_TYPES_END() -#endif -#ifndef CDAC_GLOBALS_BEGIN -#define CDAC_GLOBALS_BEGIN() -#endif -#ifndef CDAC_GLOBAL -#define CDAC_GLOBAL(globalname,tyname,val) -#endif -#ifndef CDAC_GLOBAL_POINTER -#define CDAC_GLOBAL_POINTER(globalname,addr) -#endif -#ifndef CDAC_GLOBAL_STRING -#define CDAC_GLOBAL_STRING(globalname,stringval) -#endif -#ifndef CDAC_GLOBALS_END -#define CDAC_GLOBALS_END() -#endif CDAC_BASELINE("empty") CDAC_TYPES_BEGIN() @@ -120,6 +22,7 @@ CDAC_TYPE_FIELD(Thread, /*pointer*/, ExceptionTracker, cdac_data::Except CDAC_TYPE_FIELD(Thread, GCHandle, GCHandle, cdac_data::ExposedObject) CDAC_TYPE_FIELD(Thread, GCHandle, LastThrownObject, cdac_data::LastThrownObject) CDAC_TYPE_FIELD(Thread, pointer, LinkNext, cdac_data::Link) +CDAC_TYPE_FIELD(Thread, /*pointer*/, ThreadLocalDataPtr, cdac_data::ThreadLocalDataPtr) #ifndef TARGET_UNIX CDAC_TYPE_FIELD(Thread, /*pointer*/, TEB, cdac_data::TEB) #endif @@ -140,6 +43,39 @@ CDAC_TYPE_INDETERMINATE(RuntimeThreadLocals) CDAC_TYPE_FIELD(RuntimeThreadLocals, /*EEAllocContext*/, AllocContext, offsetof(RuntimeThreadLocals, alloc_context)) CDAC_TYPE_END(RuntimeThreadLocals) +CDAC_TYPE_BEGIN(IdDispenser) +CDAC_TYPE_INDETERMINATE(IdDispenser) +CDAC_TYPE_FIELD(IdDispenser, /*pointer*/, IdToThread, cdac_data::IdToThread) +CDAC_TYPE_FIELD(IdDispenser, /*uint32*/, HighestId, cdac_data::HighestId) +CDAC_TYPE_END(IdDispenser) + +CDAC_TYPE_BEGIN(ThreadStaticsInfo) +CDAC_TYPE_SIZE(sizeof(ThreadStaticsInfo)) +CDAC_TYPE_FIELD(ThreadStaticsInfo, /*TLSIndex*/, GCTlsIndex, offsetof(ThreadStaticsInfo, GCTlsIndex)) +CDAC_TYPE_FIELD(ThreadStaticsInfo, /*TLSIndex*/, NonGCTlsIndex, offsetof(ThreadStaticsInfo, NonGCTlsIndex)) +CDAC_TYPE_END(ThreadStaticsInfo) + +CDAC_TYPE_BEGIN(ThreadLocalData) +CDAC_TYPE_INDETERMINATE(ThreadLocalData) +CDAC_TYPE_FIELD(ThreadLocalData, /*pointer*/, CollectibleTlsArrayData, offsetof(ThreadLocalData, pCollectibleTlsArrayData)) +CDAC_TYPE_FIELD(ThreadLocalData, /*pointer*/, NonCollectibleTlsArrayData, offsetof(ThreadLocalData, pNonCollectibleTlsArrayData)) +CDAC_TYPE_FIELD(ThreadLocalData, /*int32*/, CollectibleTlsDataCount, offsetof(ThreadLocalData, cCollectibleTlsData)) +CDAC_TYPE_FIELD(ThreadLocalData, /*int32*/, NonCollectibleTlsDataCount, offsetof(ThreadLocalData, cNonCollectibleTlsData)) +CDAC_TYPE_FIELD(ThreadLocalData, /*pointer*/, InFlightData, offsetof(ThreadLocalData, pInFlightData)) +CDAC_TYPE_END(ThreadLocalData) + +CDAC_TYPE_BEGIN(InFlightTLSData) +CDAC_TYPE_INDETERMINATE(InFlightTLSData) +CDAC_TYPE_FIELD(InFlightTLSData, /*pointer*/, Next, offsetof(InFlightTLSData, pNext)) +CDAC_TYPE_FIELD(InFlightTLSData, /*TLSIndex*/, TlsIndex, offsetof(InFlightTLSData, tlsIndex)) +CDAC_TYPE_FIELD(InFlightTLSData, /*OBJECTHANDLE*/, TLSData, offsetof(InFlightTLSData, hTLSData)) +CDAC_TYPE_END(InFlightTLSData) + +CDAC_TYPE_BEGIN(TLSIndex) +CDAC_TYPE_INDETERMINATE(TLSIndex) +CDAC_TYPE_FIELD(TLSIndex, /*uint32*/, TLSIndexRawIndex, offsetof(TLSIndex, TLSIndexRawIndex)) +CDAC_TYPE_END(TLSIndex) + CDAC_TYPE_BEGIN(EEAllocContext) CDAC_TYPE_INDETERMINATE(EEAllocContext) CDAC_TYPE_FIELD(EEAllocContext, /*GCAllocContext*/, GCAllocationContext, offsetof(ee_alloc_context, m_GCAllocContext)) @@ -260,13 +196,22 @@ CDAC_TYPE_END(Assembly) CDAC_TYPE_BEGIN(LoaderAllocator) CDAC_TYPE_INDETERMINATE(LoaderAllocator) CDAC_TYPE_FIELD(LoaderAllocator, /*uint32*/, ReferenceCount, cdac_data::ReferenceCount) +CDAC_TYPE_FIELD(LoaderAllocator, /*pointer*/, HighFrequencyHeap, cdac_data::HighFrequencyHeap) +CDAC_TYPE_FIELD(LoaderAllocator, /*pointer*/, LowFrequencyHeap, cdac_data::LowFrequencyHeap) +CDAC_TYPE_FIELD(LoaderAllocator, /*pointer*/, StubHeap, cdac_data::StubHeap) CDAC_TYPE_END(LoaderAllocator) CDAC_TYPE_BEGIN(PEAssembly) CDAC_TYPE_INDETERMINATE(PEAssembly) CDAC_TYPE_FIELD(PEAssembly, /*pointer*/, PEImage, cdac_data::PEImage) +CDAC_TYPE_FIELD(PEAssembly, /*pointer*/, AssemblyBinder, cdac_data::AssemblyBinder) CDAC_TYPE_END(PEAssembly) +CDAC_TYPE_BEGIN(AssemblyBinder) +CDAC_TYPE_INDETERMINATE(AssemblyBinder) +CDAC_TYPE_FIELD(AssemblyBinder, /*pointer*/, AssemblyLoadContext, cdac_data::AssemblyLoadContext) +CDAC_TYPE_END(AssemblyBinder) + CDAC_TYPE_BEGIN(PEImage) CDAC_TYPE_INDETERMINATE(PEImage) CDAC_TYPE_FIELD(PEImage, /*pointer*/, LoadedImageLayout, cdac_data::LoadedImageLayout) @@ -294,8 +239,14 @@ CDAC_TYPE_BEGIN(AppDomain) CDAC_TYPE_INDETERMINATE(AppDomain) CDAC_TYPE_FIELD(AppDomain, /*pointer*/, RootAssembly, cdac_data::RootAssembly) CDAC_TYPE_FIELD(AppDomain, /*DomainAssemblyList*/, DomainAssemblyList, cdac_data::DomainAssemblyList) +CDAC_TYPE_FIELD(AppDomain, /*pointer*/, FriendlyName, cdac_data::FriendlyName) CDAC_TYPE_END(AppDomain) +CDAC_TYPE_BEGIN(SystemDomain) +CDAC_TYPE_INDETERMINATE(SystemDomain) +CDAC_TYPE_FIELD(SystemDomain, /*GlobalLoaderAllocator*/, GlobalLoaderAllocator, cdac_data::GlobalLoaderAllocator) +CDAC_TYPE_END(SystemDomain) + CDAC_TYPE_BEGIN(ArrayListBase) CDAC_TYPE_INDETERMINATE(ArrayListBase) CDAC_TYPE_FIELD(ArrayListBase, /*uint32*/, Count, cdac_data::Count) @@ -325,10 +276,17 @@ CDAC_TYPE_FIELD(MethodTable, /*pointer*/, PerInstInfo, cdac_data::P CDAC_TYPE_FIELD(MethodTable, /*pointer*/, AuxiliaryData, cdac_data::AuxiliaryData) CDAC_TYPE_END(MethodTable) +CDAC_TYPE_BEGIN(DynamicStaticsInfo) +CDAC_TYPE_SIZE(sizeof(DynamicStaticsInfo)) +CDAC_TYPE_FIELD(DynamicStaticsInfo, /*uint32*/, GCStatics, offsetof(DynamicStaticsInfo, m_pGCStatics)) +CDAC_TYPE_FIELD(DynamicStaticsInfo, /*uint32*/, NonGCStatics, offsetof(DynamicStaticsInfo, m_pNonGCStatics)) +CDAC_TYPE_END(DynamicStaticsInfo) + CDAC_TYPE_BEGIN(MethodTableAuxiliaryData) CDAC_TYPE_INDETERMINATE(MethodTableAuxiliaryData) CDAC_TYPE_FIELD(MethodTableAuxiliaryData, /*pointer*/, LoaderModule, offsetof(MethodTableAuxiliaryData, m_pLoaderModule)) CDAC_TYPE_FIELD(MethodTableAuxiliaryData, /*int16*/, OffsetToNonVirtualSlots, offsetof(MethodTableAuxiliaryData, m_offsetToNonVirtualSlots)) +CDAC_TYPE_FIELD(MethodTableAuxiliaryData, /*uint32*/, Flags, offsetof(MethodTableAuxiliaryData, m_dwFlags)) CDAC_TYPE_END(MethodTableAuxiliaryData) CDAC_TYPE_BEGIN(EEClass) @@ -336,8 +294,12 @@ CDAC_TYPE_INDETERMINATE(EEClass) CDAC_TYPE_FIELD(EEClass, /*pointer*/, MethodTable, cdac_data::MethodTable) CDAC_TYPE_FIELD(EEClass, /*pointer*/, MethodDescChunk, cdac_data::MethodDescChunk) CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumMethods, cdac_data::NumMethods) +CDAC_TYPE_FIELD(EEClass, /*pointer*/, FieldDescList, cdac_data::FieldDescList) CDAC_TYPE_FIELD(EEClass, /*uint32*/, CorTypeAttr, cdac_data::CorTypeAttr) CDAC_TYPE_FIELD(EEClass, /*uint8*/, InternalCorElementType, cdac_data::InternalCorElementType) +CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumInstanceFields, cdac_data::NumInstanceFields) +CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumStaticFields, cdac_data::NumStaticFields) +CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumThreadStaticFields, cdac_data::NumThreadStaticFields) CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumNonVirtualSlots, cdac_data::NumNonVirtualSlots) CDAC_TYPE_END(EEClass) @@ -393,6 +355,7 @@ CDAC_TYPE_FIELD(StressLog, /* pointer */, Logs, cdac_offsets::logs) CDAC_TYPE_FIELD(StressLog, /* uint64 */, TickFrequency, cdac_offsets::tickFrequency) CDAC_TYPE_FIELD(StressLog, /* uint64 */, StartTimestamp, cdac_offsets::startTimeStamp) CDAC_TYPE_FIELD(StressLog, /* nuint */, ModuleOffset, cdac_offsets::moduleOffset) +CDAC_TYPE_FIELD(StressLog, /* StressLogModuleDesc[] */, Modules, cdac_offsets::modules) CDAC_TYPE_END(StressLog) CDAC_TYPE_BEGIN(StressLogModuleDesc) @@ -495,7 +458,7 @@ CDAC_TYPE_SIZE(sizeof(FCallMethodDesc)) CDAC_TYPE_END(FCallMethodDesc) CDAC_TYPE_BEGIN(PInvokeMethodDesc) -CDAC_TYPE_SIZE(sizeof(NDirectMethodDesc)) +CDAC_TYPE_SIZE(sizeof(PInvokeMethodDesc)) CDAC_TYPE_END(PInvokeMethodDesc) CDAC_TYPE_BEGIN(EEImplMethodDesc) @@ -526,20 +489,35 @@ CDAC_TYPE_END(MethodDescVersioningState) CDAC_TYPE_BEGIN(PrecodeMachineDescriptor) CDAC_TYPE_INDETERMINATE(PrecodeMachineDescriptor) -CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, ReadWidthOfPrecodeType, offsetof(PrecodeMachineDescriptor, ReadWidthOfPrecodeType)) -CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, ShiftOfPrecodeType, offsetof(PrecodeMachineDescriptor, ShiftOfPrecodeType)) -CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, OffsetOfPrecodeType, offsetof(PrecodeMachineDescriptor, OffsetOfPrecodeType)) CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, InvalidPrecodeType, offsetof(PrecodeMachineDescriptor, InvalidPrecodeType)) -CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, StubPrecodeType, offsetof(PrecodeMachineDescriptor, StubPrecodeType)) -#ifdef HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_PINVOKE_IMPORT_PRECODE CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, PInvokeImportPrecodeType, offsetof(PrecodeMachineDescriptor, PInvokeImportPrecodeType)) #endif + #ifdef HAS_FIXUP_PRECODE CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, FixupPrecodeType, offsetof(PrecodeMachineDescriptor, FixupPrecodeType)) -#endif +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, FixupCodeOffset, offsetof(PrecodeMachineDescriptor, FixupCodeOffset)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, FixupStubPrecodeSize, offsetof(PrecodeMachineDescriptor, FixupStubPrecodeSize)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*byte[]*/, FixupBytes, offsetof(PrecodeMachineDescriptor, FixupBytes)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*byte[]*/, FixupIgnoredBytes, offsetof(PrecodeMachineDescriptor, FixupIgnoredBytes)) +#endif // HAS_FIXUP_PRECODE + +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, StubPrecodeSize, offsetof(PrecodeMachineDescriptor, StubPrecodeSize)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, StubPrecodeType, offsetof(PrecodeMachineDescriptor, StubPrecodeType)) + +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*byte[]*/, StubBytes, offsetof(PrecodeMachineDescriptor, StubBytes)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*byte[]*/, StubIgnoredBytes, offsetof(PrecodeMachineDescriptor, StubIgnoredBytes)) + #ifdef HAS_THISPTR_RETBUF_PRECODE CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, ThisPointerRetBufPrecodeType, offsetof(PrecodeMachineDescriptor, ThisPointerRetBufPrecodeType)) #endif +#ifdef FEATURE_INTERPRETER +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, InterpreterPrecodeType, offsetof(PrecodeMachineDescriptor, InterpreterPrecodeType)) +#endif +#ifdef FEATURE_STUBPRECODE_DYNAMIC_HELPERS +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, DynamicHelperPrecodeType, offsetof(PrecodeMachineDescriptor, DynamicHelperPrecodeType)) +#endif +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, UMEntryPrecodeType, offsetof(PrecodeMachineDescriptor, UMEntryPrecodeType)) CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint32*/, StubCodePageSize, offsetof(PrecodeMachineDescriptor, StubCodePageSize)) CDAC_TYPE_END(PrecodeMachineDescriptor) @@ -576,6 +554,7 @@ CDAC_TYPE_FIELD(ReadyToRunInfo, /*pointer*/, RuntimeFunctions, cdac_data::NumHotColdMap) CDAC_TYPE_FIELD(ReadyToRunInfo, /*pointer*/, HotColdMap, cdac_data::HotColdMap) CDAC_TYPE_FIELD(ReadyToRunInfo, /*pointer*/, DelayLoadMethodCallThunks, cdac_data::DelayLoadMethodCallThunks) +CDAC_TYPE_FIELD(ReadyToRunInfo, /*pointer*/, DebugInfoSection, cdac_data::DebugInfoSection) CDAC_TYPE_FIELD(ReadyToRunInfo, /*HashMap*/, EntryPointToMethodDescMap, cdac_data::EntryPointToMethodDescMap) CDAC_TYPE_END(ReadyToRunInfo) @@ -642,9 +621,15 @@ CDAC_TYPE_FIELD(RangeSection, /*pointer*/, HeapList, cdac_data::He CDAC_TYPE_FIELD(RangeSection, /*pointer*/, R2RModule, cdac_data::R2RModule) CDAC_TYPE_END(RangeSection) +CDAC_TYPE_BEGIN(EEJitManager) +CDAC_TYPE_INDETERMINATE(EEJitManager) +CDAC_TYPE_FIELD(EEJitManager, /*bool*/, StoreRichDebugInfo, cdac_data::StoreRichDebugInfo) +CDAC_TYPE_END(EEJitManager) + CDAC_TYPE_BEGIN(RealCodeHeader) CDAC_TYPE_INDETERMINATE(RealCodeHeader) CDAC_TYPE_FIELD(RealCodeHeader, /*pointer*/, MethodDesc, offsetof(RealCodeHeader, phdrMDesc)) +CDAC_TYPE_FIELD(RealCodeHeader, /*pointer*/, DebugInfo, offsetof(RealCodeHeader, phdrDebugInfo)) CDAC_TYPE_FIELD(RealCodeHeader, /*pointer*/, GCInfo, offsetof(RealCodeHeader, phdrJitGCInfo)) #ifdef FEATURE_EH_FUNCLETS CDAC_TYPE_FIELD(RealCodeHeader, /*uint32*/, NumUnwindInfos, offsetof(RealCodeHeader, nUnwindInfos)) @@ -652,6 +637,11 @@ CDAC_TYPE_FIELD(RealCodeHeader, /* T_RUNTIME_FUNCTION */, UnwindInfos, offsetof( #endif // FEATURE_EH_FUNCLETS CDAC_TYPE_END(RealCodeHeader) +CDAC_TYPE_BEGIN(PatchpointInfo) +CDAC_TYPE_SIZE(sizeof(PatchpointInfo)) +CDAC_TYPE_FIELD(PatchpointInfo, /*uint32*/, LocalCount, cdac_data::LocalCount) +CDAC_TYPE_END(PatchpointInfo) + CDAC_TYPE_BEGIN(CodeHeapListNode) CDAC_TYPE_FIELD(CodeHeapListNode, /*pointer*/, Next, offsetof(HeapList, hpNext)) CDAC_TYPE_FIELD(CodeHeapListNode, /*pointer*/, StartAddress, offsetof(HeapList, startAddress)) @@ -898,13 +888,6 @@ CDAC_TYPE_FIELD(InstMethodHashTable, /*pointer*/, VolatileEntryValue, cdac_data< CDAC_TYPE_FIELD(InstMethodHashTable, /*pointer*/, VolatileEntryNextEntry, cdac_data::VolatileEntryNextEntry) CDAC_TYPE_END(InstMethodHashTable) -CDAC_TYPE_BEGIN(ECHash) -CDAC_TYPE_INDETERMINATE(ECHash) -CDAC_TYPE_FIELD(ECHash, /*pointer*/, Next, offsetof(ECHash, m_pNext)) -CDAC_TYPE_FIELD(ECHash, /*pointer*/, Implementation, offsetof(ECHash, m_pImplementation)) -CDAC_TYPE_FIELD(ECHash, /*pointer*/, MethodDesc, offsetof(ECHash, m_pMD)) -CDAC_TYPE_END(ECHash) - CDAC_TYPES_END() CDAC_GLOBALS_BEGIN() @@ -938,7 +921,7 @@ CDAC_GLOBAL_STRING(RID, RID_STRING) CDAC_GLOBAL(GCInfoVersion, uint32, GCINFO_VERSION) CDAC_GLOBAL_POINTER(AppDomain, &AppDomain::m_pTheAppDomain) -CDAC_GLOBAL_POINTER(SystemDomain, cdac_data::SystemDomain) +CDAC_GLOBAL_POINTER(SystemDomain, cdac_data::SystemDomainPtr) CDAC_GLOBAL_POINTER(ThreadStore, &ThreadStore::s_pThreadStore) CDAC_GLOBAL_POINTER(FinalizerThread, &::g_pFinalizerThread) CDAC_GLOBAL_POINTER(GCThread, &::g_pSuspensionThread) @@ -956,6 +939,11 @@ CDAC_GLOBAL(FeatureCOMInterop, uint8, 1) #else CDAC_GLOBAL(FeatureCOMInterop, uint8, 0) #endif +#ifdef FEATURE_ON_STACK_REPLACEMENT +CDAC_GLOBAL(FeatureOnStackReplacement, uint8, 1) +#else +CDAC_GLOBAL(FeatureOnStackReplacement, uint8, 0) +#endif // FEATURE_ON_STACK_REPLACEMENT // See Object::GetGCSafeMethodTable #ifdef TARGET_64BIT CDAC_GLOBAL(ObjectToMethodTableUnmask, uint8, 1 | 1 << 1 | 1 << 2) @@ -970,6 +958,12 @@ CDAC_GLOBAL(MethodDescAlignment, uint64, MethodDesc::ALIGNMENT) CDAC_GLOBAL(ObjectHeaderSize, uint64, OBJHEADER_SIZE) CDAC_GLOBAL(SyncBlockValueToObjectOffset, uint16, OBJHEADER_SIZE - cdac_data::SyncBlockValue) CDAC_GLOBAL(StubCodeBlockLast, uint8, STUB_CODE_BLOCK_LAST) +CDAC_GLOBAL(DefaultADID, uint32, DefaultADID) +CDAC_GLOBAL(StaticsPointerMask, uintptr_t, DynamicStaticsInfo::STATICSPOINTERMASK) +CDAC_GLOBAL(PtrArrayOffsetToDataArray, uintptr_t, offsetof(PtrArray, m_Array)) +CDAC_GLOBAL(NumberOfTlsOffsetsNotUsedInNoncollectibleArray, uint8, NUMBER_OF_TLSOFFSETS_NOT_USED_IN_NONCOLLECTIBLE_ARRAY) +CDAC_GLOBAL(MaxClrNotificationArgs, uint32, MAX_CLR_NOTIFICATION_ARGS) +CDAC_GLOBAL_POINTER(ClrNotificationArguments, &::g_clrNotificationArguments) CDAC_GLOBAL_POINTER(ArrayBoundsZero, cdac_data::ArrayBoundsZero) CDAC_GLOBAL_POINTER(ExceptionMethodTable, &::g_pExceptionClass) CDAC_GLOBAL_POINTER(FreeObjectMethodTable, &::g_pFreeObjectMethodTable) @@ -979,11 +973,16 @@ CDAC_GLOBAL_POINTER(StringMethodTable, &::g_pStringClass) CDAC_GLOBAL_POINTER(SyncTableEntries, &::g_pSyncTable) CDAC_GLOBAL_POINTER(MiniMetaDataBuffAddress, &::g_MiniMetaDataBuffAddress) CDAC_GLOBAL_POINTER(MiniMetaDataBuffMaxSize, &::g_MiniMetaDataBuffMaxSize) +CDAC_GLOBAL_POINTER(DacNotificationFlags, &::g_dacNotificationFlags) +CDAC_GLOBAL_POINTER(OffsetOfCurrentThreadInfo, &::g_offsetOfCurrentThreadInfo) +CDAC_GLOBAL_POINTER(ThinlockThreadIdDispenser, &::g_pThinLockThreadIdDispenser) +#ifdef TARGET_WINDOWS +CDAC_GLOBAL_POINTER(TlsIndexBase, &::_tls_index) +#endif // TARGET_WINDOWS #ifdef STRESS_LOG CDAC_GLOBAL(StressLogEnabled, uint8, 1) CDAC_GLOBAL_POINTER(StressLog, &g_pStressLog) CDAC_GLOBAL(StressLogHasModuleTable, uint8, 1) -CDAC_GLOBAL_POINTER(StressLogModuleTable, &g_pStressLog->modules) CDAC_GLOBAL(StressLogMaxModules, uint64, cdac_offsets::MAX_MODULES) CDAC_GLOBAL(StressLogChunkSize, uint32, STRESSLOG_CHUNK_SIZE) CDAC_GLOBAL(StressLogValidChunkSig, uint32, StressLogChunk::ValidChunkSig) @@ -996,21 +995,4 @@ CDAC_GLOBAL_POINTER(PlatformMetadata, &::g_cdacPlatformMetadata) CDAC_GLOBAL_POINTER(ProfilerControlBlock, &::g_profControlBlock) CDAC_GLOBAL_POINTER(MethodDescSizeTable, &MethodDesc::s_ClassificationSizeTable) -CDAC_GLOBAL(FCallHashSize, uint32, FCALL_HASH_SIZE) -CDAC_GLOBAL_POINTER(FCallMethods, &::gFCallMethods) - CDAC_GLOBALS_END() - -#undef CDAC_BASELINE -#undef CDAC_TYPES_BEGIN -#undef CDAC_TYPE_BEGIN -#undef CDAC_TYPE_INDETERMINATE -#undef CDAC_TYPE_SIZE -#undef CDAC_TYPE_FIELD -#undef CDAC_TYPE_END -#undef CDAC_TYPES_END -#undef CDAC_GLOBALS_BEGIN -#undef CDAC_GLOBAL -#undef CDAC_GLOBAL_POINTER -#undef CDAC_GLOBAL_STRING -#undef CDAC_GLOBALS_END diff --git a/src/coreclr/vm/dbginterface.h b/src/coreclr/vm/dbginterface.h index a6b47311fe7e93..a72102ef62ad0b 100644 --- a/src/coreclr/vm/dbginterface.h +++ b/src/coreclr/vm/dbginterface.h @@ -60,10 +60,12 @@ class DebugInterface virtual void DetachThread(Thread *pRuntimeThread) = 0; + virtual void AppDomainCreated(AppDomain * pAppDomain) = 0; + // Called when a module is being loaded into an AppDomain. // This includes when a domain neutral module is loaded into a new AppDomain. // This is called only when a debugger is attached, and will occur after the - // related LoadAssembly and AddAppDomainToIPCBlock calls and before any + // related LoadAssembly calls and before any // LoadClass calls for this module. virtual void LoadModule(Module * pRuntimeModule, // the module being loaded LPCWSTR psModuleName, // module file name @@ -277,6 +279,7 @@ class DebugInterface ULONG32 *pcMap, COR_DEBUG_IL_TO_NATIVE_MAP map[]) = 0; +#ifdef DEBUG virtual HRESULT GetILToNativeMappingIntoArrays( MethodDesc * pMethodDesc, PCODE pNativeCodeStartAddress, @@ -284,27 +287,10 @@ class DebugInterface USHORT * pcMap, UINT ** prguiILOffset, UINT ** prguiNativeOffset) = 0; +#endif // DEBUG virtual DWORD GetHelperThreadID(void ) = 0; - // Called whenever a new AppDomain is created, regardless of whether a debugger is attached. - // This will be called before any LoadAssembly calls for assemblies in this domain. - virtual HRESULT AddAppDomainToIPC (AppDomain *pAppDomain) = 0; - - // Called whenever an AppDomain is unloaded, regardless of whether a Debugger is attached - // This will occur after any UnloadAssembly and UnloadModule callbacks for this domain (if any). - virtual HRESULT RemoveAppDomainFromIPC (AppDomain *pAppDomain) = 0; - - 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/coreclr/vm/debugdebugger.cpp b/src/coreclr/vm/debugdebugger.cpp index cfda91207568fc..1d09d0d1a6b797 100644 --- a/src/coreclr/vm/debugdebugger.cpp +++ b/src/coreclr/vm/debugdebugger.cpp @@ -1180,6 +1180,364 @@ void InsertIntoNativeToILCache(void* ip, bool fAdjustOffset, uint32_t dwILOffset } +struct WalkILOffsetsData +{ + WalkILOffsetsData(DWORD dwSearchNativeOffset, bool skipPrologsParam = false) + : dwSearchNativeOffset(dwSearchNativeOffset), + skipPrologs(skipPrologsParam) + { + } + DWORD prevILOffsetFound = 0; + DWORD dwILOffsetFound = 0; + DWORD dwCurrentNativeOffset = 0; + int greatestILOffsetFound = 0; + const DWORD dwSearchNativeOffset; + + DWORD dwFinalILOffset = 0; + const bool skipPrologs; + bool skipPrologCase = false; + bool firstCall = true; + bool epilogCase = false; +}; + +// This callback is used to walk the IL offsets for a given method, and find the IL offset that corresponds to a given native offset. +size_t WalkILOffsetsCallback(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext) +{ + WalkILOffsetsData *pWalkData = (WalkILOffsetsData *)pContext; + // Callbacks into this api are sorted by native offset, but not sorted by IL offset. + // In addition, there are several special IL offsets that are not actual IL offsets. + + if ((int32_t)pOffsetMapping->ilOffset > pWalkData->greatestILOffsetFound) + { + // Calculate the greatest IL offset found so far. We use this as the IL offset for epilogs + pWalkData->greatestILOffsetFound = (int)pOffsetMapping->ilOffset; + } + + // Also, ignore all the CALL_INSTRUCTION mappings since they are not relevant for the standard Native-IL mapping + + if ((pOffsetMapping->source & (DWORD)ICorDebugInfo::CALL_INSTRUCTION) == (DWORD)ICorDebugInfo::CALL_INSTRUCTION) + { + // This is a call instruction mapping, so we don't care about it. + return 0; + } + + if (pWalkData->epilogCase) + { + if (pOffsetMapping->nativeOffset == 0xFFFFFFFF) + { + pWalkData->dwFinalILOffset = pWalkData->greatestILOffsetFound; + return 1; + } + else + { + return 0; + } + } + + // The general rule is that we need to find the lowest IL offset that applies to the given native offset + // An IL offset in the mapping of ICorDebugInfo::NO_MAPPING indicates that the IL offset we report should be 0 + // An IL offset in the mapping of ICorDebugInfo::PROLOG indicates that we should report the "next" IL offset. + // An IL offset in the mapping of ICorDebugInfo::EPILOG indicates that we should report the "previous" IL offset. + + if (pWalkData->firstCall) + { + pWalkData->firstCall = false; + // This is the first time we are called, so set the current native offset to the one we are looking for + pWalkData->dwCurrentNativeOffset = pOffsetMapping->nativeOffset; + if (pOffsetMapping->nativeOffset > pWalkData->dwSearchNativeOffset) + { + // We are looking for an IL offset, and all IL offsets are are about portions of the method that are after the native offset we were passed initially. + // Treat this like a PROLOG and set the IL offset to 0 + pWalkData->dwFinalILOffset = 0; + return 1; + } + pWalkData->dwILOffsetFound = pOffsetMapping->ilOffset; + } + else + { + // If the current native offset is less than the one we are looking for, then we need to set the IL offset + // to the one we are looking for. + if (pOffsetMapping->nativeOffset > pWalkData->dwCurrentNativeOffset) + { + if (pWalkData->skipPrologCase) + { + if (pWalkData->prevILOffsetFound != (DWORD)ICorDebugInfo::NO_MAPPING && + pWalkData->prevILOffsetFound != (DWORD)ICorDebugInfo::PROLOG && + pWalkData->prevILOffsetFound != (DWORD)ICorDebugInfo::EPILOG) + { + // We found a valid IL offset after the prolog, so set the final IL offset to the one we found + pWalkData->dwFinalILOffset = pWalkData->dwILOffsetFound; + } + else + { + pWalkData->dwFinalILOffset = 0; + } + return 1; + } + if (pOffsetMapping->nativeOffset > pWalkData->dwSearchNativeOffset) + { + // We were searching for the IL offset, and we found it (unless we were in a PROLOG) + if (pWalkData->dwILOffsetFound == (DWORD)ICorDebugInfo::EPILOG) + { + // We found we were in an EPILOG. Report the last il offset reported as part of the method. + pWalkData->epilogCase = true; + if (pOffsetMapping->nativeOffset == 0xFFFFFFFF) + { + pWalkData->dwFinalILOffset = pWalkData->greatestILOffsetFound; + return 1; + } + } + else if (pWalkData->dwILOffsetFound == (DWORD)ICorDebugInfo::NO_MAPPING) + { + pWalkData->dwFinalILOffset = 0; + return 1; + } + else if (!(pWalkData->dwILOffsetFound == (DWORD)ICorDebugInfo::PROLOG)) + { + pWalkData->dwFinalILOffset = pWalkData->dwILOffsetFound; + return 1; + } + else + { + // PROLOG case + if (pWalkData->skipPrologs) + { + _ASSERTE(pWalkData->dwILOffsetFound == (DWORD)ICorDebugInfo::PROLOG); + pWalkData->skipPrologCase = true; + } + else + { + pWalkData->dwFinalILOffset = 0; + return 1; + } + } + } + pWalkData->dwCurrentNativeOffset = pOffsetMapping->nativeOffset; + pWalkData->prevILOffsetFound = pWalkData->dwILOffsetFound; + pWalkData->dwILOffsetFound = pOffsetMapping->ilOffset; + } + else if (((int32_t)pOffsetMapping->ilOffset < (int32_t)pWalkData->dwILOffsetFound) && (pOffsetMapping->ilOffset != (DWORD)ICorDebugInfo::NO_MAPPING)) + { + // We found a new IL offset that is less than the one we are looking for + pWalkData->dwILOffsetFound = pOffsetMapping->ilOffset; + } + } + + return 0; +} + +#ifndef DACCESS_COMPILE +#ifdef DEBUG +size_t WalkILOffsetsCallback_Printer(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext) +{ + printf("IL Offset: %d, Native Offset: %d, %s%s%s%s%s\n", + pOffsetMapping->ilOffset, + pOffsetMapping->nativeOffset, + pOffsetMapping->source & ICorDebugInfo::SEQUENCE_POINT ? "SEQUENCE_POINT " : "", + pOffsetMapping->source & ICorDebugInfo::STACK_EMPTY ? "STACK_EMPTY " : "", + pOffsetMapping->source & ICorDebugInfo::CALL_SITE ? "CALL_SITE " : "", + pOffsetMapping->source & ICorDebugInfo::NATIVE_END_OFFSET_UNKNOWN ? "NATIVE_END_OFFSET_UNKNOWN " : "", + pOffsetMapping->source & ICorDebugInfo::CALL_INSTRUCTION ? "CALL_INSTRUCTION " : ""); + return 0; +} + +void ValidateILOffset(MethodDesc *pFunc, uint8_t* ip) +{ + EECodeInfo codeInfo((PCODE)ip); + if (!codeInfo.IsValid()) + { + return; + } + DWORD dwNativeOffset = codeInfo.GetRelOffset(); + + DWORD dwILOffsetDebugInterface = 0; + DWORD dwILOffsetWalk = 0; + + bool bResGetILOffsetFromNative = g_pDebugInterface->GetILOffsetFromNative( + pFunc, + (LPCBYTE)ip, + dwNativeOffset, + &dwILOffsetDebugInterface); + + WalkILOffsetsData data(dwNativeOffset); + TADDR startAddress = codeInfo.GetStartAddress(); + DebugInfoRequest request; + request.InitFromStartingAddr(codeInfo.GetMethodDesc(), startAddress); + bool bWalkILOffsets; + + if (pFunc->IsDynamicMethod()) + { + bWalkILOffsets = false; + } + else + { + bWalkILOffsets = codeInfo.GetJitManager()->WalkILOffsets(request, BoundsType::Uninstrumented, &data, WalkILOffsetsCallback); + if (bWalkILOffsets) + dwILOffsetWalk = data.dwFinalILOffset; + else + { + dwILOffsetWalk = 0; + bWalkILOffsets = true; + } + } + + if (bWalkILOffsets && bResGetILOffsetFromNative) + { + if (dwILOffsetWalk != dwILOffsetDebugInterface) + { + printf("Mismatch in IL offsets for %p at IP %p Native Offset %d:\n", pFunc, ip, dwNativeOffset); + printf(" Debug Interface IL Offset: %d\n", dwILOffsetDebugInterface); + printf(" Walk IL Offsets IL Offset: %d\n", dwILOffsetWalk); + codeInfo.GetJitManager()->WalkILOffsets(request, BoundsType::Uninstrumented, NULL, WalkILOffsetsCallback_Printer); + } + _ASSERTE(dwILOffsetWalk == dwILOffsetDebugInterface); + } + + if (bWalkILOffsets != bResGetILOffsetFromNative) + { + printf("Mismatch in IL offsets validity for %p at IP %p Native Offset %d:\n", pFunc, ip, dwNativeOffset); + printf(" Debug Interface IL Offset: %d Valid = %s\n", dwILOffsetDebugInterface, bResGetILOffsetFromNative ? "true" : "false"); + printf(" Walk IL Offsets IL Offset: %d Valid = %s\n", dwILOffsetWalk, bWalkILOffsets ? "true" : "false"); + codeInfo.GetJitManager()->WalkILOffsets(request, BoundsType::Uninstrumented, NULL, WalkILOffsetsCallback_Printer); + _ASSERTE(bWalkILOffsets == bResGetILOffsetFromNative); + } +} + +void ValidateILOffsets(MethodDesc *pFunc, uint8_t* ipColdStart, size_t coldLen, uint8_t* ipHotStart, size_t hotLen) +{ + LIMITED_METHOD_CONTRACT; + { + USHORT cMap; + NewArrayHolder rguiILOffset; + NewArrayHolder rguiNativeOffset; + + if (pFunc->IsWrapperStub() || pFunc->IsDynamicMethod()) + { + return; + } + + // This is the limit on how big the il-to-native map can get, as measured by number + // of entries in each parallel array (IL offset array and native offset array). + // This number was chosen to ensure the overall event stays under the Windows limit + // of 64K + const USHORT kMapEntriesMax = 7000; + + HRESULT hr = g_pDebugInterface->GetILToNativeMappingIntoArrays( + pFunc, + PINSTRToPCODE((TADDR)ipHotStart), + kMapEntriesMax, + &cMap, + &rguiILOffset, + &rguiNativeOffset); + + if (FAILED(hr)) + { + printf("Failed to get IL to Native mapping for %p: %x\n", pFunc, hr); + return; + } + + EECodeInfo codeInfo((PCODE)ipHotStart); + if (!codeInfo.IsValid()) + { + return; + } + TADDR startAddress = codeInfo.GetStartAddress(); + DebugInfoRequest request; + request.InitFromStartingAddr(codeInfo.GetMethodDesc(), startAddress); + + ILToNativeMapArrays context(kMapEntriesMax); + codeInfo.GetJitManager()->WalkILOffsets(request, BoundsType::Uninstrumented, &context, ComputeILOffsetArrays); + + uint32_t cMapWalk; + uint32_t* rguiILOffsetWalk; + uint32_t* rguiNativeOffsetWalk; + + context.GetArrays(&cMapWalk, &rguiNativeOffsetWalk, &rguiILOffsetWalk); + + bool failure = false; + + if (cMapWalk != cMap) + { + printf("Mismatch in IL to Native mapping count for %p: Expected %d, got %d\n", pFunc, cMap, cMapWalk); + failure = true; + } + + if (cMapWalk == cMap) + { + for (uint32_t i = 0; i < cMapWalk; i++) + { + // We should never have a prolog or epilog entry in the map. + if ((rguiILOffsetWalk[i] != rguiILOffset[i]) || rguiNativeOffsetWalk[i] != rguiNativeOffset[i]) + { + printf("Mismatch in IL to Native mapping at index %d\n", (int)i); + failure = true; + break; + } + } + } + + if (failure) + { + codeInfo.GetJitManager()->WalkILOffsets(request, BoundsType::Uninstrumented, NULL, WalkILOffsetsCallback_Printer); + + printf("cMap: %d\n", cMap); + printf("cMapWalk: %d\n", cMapWalk); + + uint32_t i = 0; + for (i = 0; i < cMap && i < cMapWalk; i++) + { + if ((rguiILOffsetWalk[i] != rguiILOffset[i]) || rguiNativeOffsetWalk[i] != rguiNativeOffset[i]) + { + printf("MISMATCH - "); + } + + printf("IL Offset: %d, IL Offset(walk): %d, Native Offset: %d Native Offset(walk): %d\n", (int)rguiILOffset[i], (int)rguiILOffsetWalk[i], (int)rguiNativeOffset[i], (int)rguiNativeOffsetWalk[i]); + } + + for (; i < cMap; i++) + { + printf("IL Offset: %d, Native Offset: %d\n", (int)rguiILOffsetWalk[i], (int)rguiNativeOffsetWalk[i]); + } + + for (; i < cMapWalk; i++) + { + printf("IL Offset(walk): %d, Native Offset(walk): %d\n", (int)rguiILOffsetWalk[i], (int)rguiNativeOffsetWalk[i]); + } + _ASSERTE(!failure); + } + } + + uint8_t *ip; + if (ipColdStart != NULL) + { + size_t step = coldLen / 100; + if (step == 0) + { + step = 1; // Ensure we step at least once + } + for (ip = ipColdStart; ip <= (ipColdStart + coldLen);ip += step) + { + ValidateILOffset(pFunc, ip); + } + } + + if (ipHotStart != NULL) + { + size_t step = hotLen / 100; + if (step == 0) + { + step = 1; // Ensure we step at least once + } + for (ip = ipHotStart; ip <= (ipHotStart + hotLen);ip += step) + { + ValidateILOffset(pFunc, ip); + } + } +} +#endif // DEBUG + +#endif // !DACCESS_COMPILE + // Initialization done outside the TSL. // This may need to call locking operations that aren't safe under the TSL. void DebugStackTrace::Element::InitPass2() @@ -1197,54 +1555,48 @@ void DebugStackTrace::Element::InitPass2() bool bRes = false; bool fAdjustOffset = (this->flags & STEF_IP_ADJUSTED) == 0 && this->dwOffset > 0; - if (this->ip != (PCODE)NULL) + + // Check the cache! + uint32_t dwILOffsetFromCache; + if (CheckNativeToILCache((void*)this->ip, fAdjustOffset, &dwILOffsetFromCache)) { - // Check the cache! - uint32_t dwILOffsetFromCache; - if (CheckNativeToILCache((void*)this->ip, fAdjustOffset, &dwILOffsetFromCache)) + this->dwILOffset = dwILOffsetFromCache; + bRes = true; + } + else + { + // Get IL Offset from the JitManager directly + EECodeInfo codeInfo(this->ip); + + // We are allowed to get a result for non-dynamic methods only, other methods will either have good data, or be returned as IL offset 0. + if (codeInfo.IsValid() && !codeInfo.GetMethodDesc()->IsDynamicMethod()) { - this->dwILOffset = dwILOffsetFromCache; + TADDR startAddress = codeInfo.GetStartAddress(); + WalkILOffsetsData data(fAdjustOffset ? this->dwOffset - STACKWALK_CONTROLPC_ADJUST_OFFSET : this->dwOffset); + DebugInfoRequest request; + request.InitFromStartingAddr(codeInfo.GetMethodDesc(), startAddress); + if (!codeInfo.GetJitManager()->WalkILOffsets(request, BoundsType::Uninstrumented, &data, WalkILOffsetsCallback)) + { + data.dwFinalILOffset = 0; // If we didn't find any IL offsets, set the final IL offset to 0 + } + + this->dwILOffset = data.dwFinalILOffset; bRes = true; - } -#ifdef DEBUGGING_SUPPORTED - else if (g_pDebugInterface) - { - // To get the source line number of the actual code that threw an exception, the dwOffset needs to be - // adjusted in certain cases when calculating the IL offset. - // - // The dwOffset of the stack frame points to either: - // - // 1) The instruction that caused a hardware exception (div by zero, null ref, etc). - // 2) The instruction after the call to an internal runtime function (FCALL like IL_Throw, IL_Rethrow, - // JIT_OverFlow, etc.) that caused a software exception. - // 3) The instruction after the call to a managed function (non-leaf node). - // - // #2 and #3 are the cases that need to adjust dwOffset because they point after the call instruction - // and may point to the next (incorrect) IL instruction/source line. If STEF_IP_ADJUSTED is set, - // IP/dwOffset has already be decremented so don't decrement it again. - // - // When the dwOffset needs to be adjusted it is a lot simpler to decrement instead of trying to figure out - // the beginning of the instruction. It is enough for GetILOffsetFromNative to return the IL offset of the - // instruction throwing the exception. - bRes = g_pDebugInterface->GetILOffsetFromNative( - pFunc, - (LPCBYTE)this->ip, - fAdjustOffset ? this->dwOffset - STACKWALK_CONTROLPC_ADJUST_OFFSET : this->dwOffset, - &this->dwILOffset); - - if (bRes) + + MethodDesc* pMD = codeInfo.GetMethodDesc(); + if (!pMD->IsLCGMethod() && !pMD->GetLoaderAllocator()->IsCollectible()) { - if (!pFunc->IsLCGMethod() && !pFunc->GetLoaderAllocator()->IsCollectible()) - { - // Only insert into the cache if the value found will not change throughout the lifetime of the process. - InsertIntoNativeToILCache( - (void*)this->ip, - fAdjustOffset, - this->dwILOffset); - } + // Only insert into the cache if the value found will not change throughout the lifetime of the process. + InsertIntoNativeToILCache( + (void*)this->ip, + fAdjustOffset, + this->dwILOffset); } } -#endif + else + { + bRes = false; + } } // If there was no mapping information, then set to an invalid value @@ -1254,4 +1606,192 @@ void DebugStackTrace::Element::InitPass2() } } +int32_t ILToNativeMapArrays::CompareILOffsets(uint32_t ilOffsetA, uint32_t ilOffsetB) +{ + if (ilOffsetA == ilOffsetB) + { + return 0; + } + + if (ilOffsetA == (uint32_t)ICorDebugInfo::PROLOG) + { + // Prolog entries are always at the start of the list. + return -1; + } + if (ilOffsetB == (uint32_t)ICorDebugInfo::PROLOG) + { + // Prolog entries are always at the start of the list. + return 1; + } + else if (ilOffsetA == (uint32_t)ICorDebugInfo::NO_MAPPING) + { + // No mappings are always at the end of the list. + return 1; + } + else if (ilOffsetB == (uint32_t)ICorDebugInfo::NO_MAPPING) + { + // No mappings are always at the end of the list. + return -1; + } + else if (ilOffsetA == (uint32_t)ICorDebugInfo::EPILOG) + { + // Epilog entries are always just before the NO_MAPPING regions + return 1; + } + else if (ilOffsetB == (uint32_t)ICorDebugInfo::EPILOG) + { + // Epilog entries are always just before the NO_MAPPING regions + return -1; + } + else if (ilOffsetA < ilOffsetB) + { + return -1; + } + else + { + return 1; + } +} +bool ILToNativeMapArrays::CompareLessOffsets(uint32_t ilOffsetA, uint32_t nativeOffsetA, uint32_t ilOffsetB, uint32_t nativeOffsetB) +{ + int32_t ilOffsetCompare = CompareILOffsets(ilOffsetA, ilOffsetB); + _ASSERTE(CompareILOffsets(ilOffsetB, ilOffsetA) == -ilOffsetCompare); + + if (ilOffsetCompare != 0) + { + // If IL offsets are not equal, then we can return the result of the IL offset comparison. + return ilOffsetCompare < 0; + } + return nativeOffsetA < nativeOffsetB; +} + +bool ILToNativeMapArrays::CompareGreaterOffsets(uint32_t ilOffsetA, uint32_t nativeOffsetA, uint32_t ilOffsetB, uint32_t nativeOffsetB) +{ + int32_t ilOffsetCompare = CompareILOffsets(ilOffsetA, ilOffsetB); + _ASSERTE(CompareILOffsets(ilOffsetB, ilOffsetA) == -ilOffsetCompare); + + if (ilOffsetCompare != 0) + { + // If IL offsets are not equal, then we can return the result of the IL offset comparison. + return ilOffsetCompare > 0; + } + return nativeOffsetA > nativeOffsetB; +} + +void ILToNativeMapArrays::Swap(uint32_t* rguiNativeOffset, uint32_t *rguiILOffset, int32_t i, int32_t j) +{ + LIMITED_METHOD_CONTRACT; + + uint32_t tempNative = rguiNativeOffset[i]; + uint32_t tempIL = rguiILOffset[i]; + rguiNativeOffset[i] = rguiNativeOffset[j]; + rguiILOffset[i] = rguiILOffset[j]; + rguiNativeOffset[j] = tempNative; + rguiILOffset[j] = tempIL; +} + +void ILToNativeMapArrays::Copy(uint32_t* rguiNativeOffset, uint32_t *rguiILOffset, int32_t i, int32_t j) +{ + LIMITED_METHOD_CONTRACT; + + rguiNativeOffset[i] = rguiNativeOffset[j]; + rguiILOffset[i] = rguiILOffset[j]; +} + +int32_t ILToNativeMapArrays::Partition(uint32_t* rguiNativeOffset, uint32_t *rguiILOffset, int32_t low, int32_t high) +{ + LIMITED_METHOD_CONTRACT; + + // Choose the pivot as the middle element and + // pull the pivot the the end of the array. + Swap(rguiNativeOffset, rguiILOffset, low + (high - low) / 2, high); + + uint32_t pivotNative = rguiNativeOffset[high]; + uint32_t pivotIL = rguiILOffset[high]; + int i = low - 1; + + for (int j = low; j < high; j++) + { + if (CompareLessOffsets(rguiILOffset[j], rguiNativeOffset[j], pivotIL, pivotNative)) + { + i++; + Swap(rguiNativeOffset, rguiILOffset, j, i); + } + } + + // Place pivot in the correct position + Swap(rguiNativeOffset, rguiILOffset, i+1, high); + return i + 1; +} + +void ILToNativeMapArrays::QuickSort(uint32_t* rguiNativeOffset, uint32_t *rguiILOffset, int32_t low, int32_t high, int32_t stackDepth) +{ + LIMITED_METHOD_CONTRACT; + + if ((stackDepth > 5) || (high - low) < 10) + { + for (int i = low + 1; i <= high; i++) + { + uint32_t keyNative = rguiNativeOffset[i]; + uint32_t keyIL = rguiILOffset[i]; + int j = i - 1; + + // Move elements of rguiNativeOffset[low..i-1], that are greater than keyNative, + // to one position ahead of their current position + while (j >= low && CompareGreaterOffsets(rguiILOffset[j], rguiNativeOffset[j], keyIL, keyNative)) + { + Copy(rguiNativeOffset, rguiILOffset, j + 1, j); + j--; + } + rguiNativeOffset[j + 1] = keyNative; + rguiILOffset[j + 1] = keyIL; + } + } + else + { + int pi = Partition(rguiNativeOffset, rguiILOffset, low, high); + + // Recursively sort elements before and after partition + QuickSort(rguiNativeOffset, rguiILOffset, low, pi - 1, stackDepth + 1); + QuickSort(rguiNativeOffset, rguiILOffset, pi + 1, high, stackDepth + 1); + } +} + +void ILToNativeMapArrays::AddEntry(ICorDebugInfo::OffsetMapping *pOffsetMapping) +{ + if ((pOffsetMapping->source & ICorDebugInfo::CALL_INSTRUCTION) != ICorDebugInfo::CALL_INSTRUCTION) + { + if (callInstrSequence < 2) + { + // Check to see if we should prefer to drop this mapping in favor of a future mapping. + if ((m_rguiILOffset.GetCount() > 0) && + (m_rguiILOffset[m_rguiILOffset.GetCount() - 1] == pOffsetMapping->ilOffset)) + { + callInstrSequence = 0; + return; + } + } + m_rguiNativeOffset.Append(pOffsetMapping->nativeOffset); + m_rguiILOffset.Append(pOffsetMapping->ilOffset); + + callInstrSequence = 0; + } + else + { + callInstrSequence++; + } +} + +// This callback is used to walk the IL offsets for a given method, and produce a pair of arrays that contain the IL and native offsets for the method. +size_t ComputeILOffsetArrays(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext) +{ + if (pOffsetMapping->nativeOffset == 0xFFFFFFFF) + { + // This is a special case for the end of the method, where the native offset is 0xFFFFFFFF. + return 1; + } + ILToNativeMapArrays* pArrays = (ILToNativeMapArrays*)pContext; + pArrays->AddEntry(pOffsetMapping); + return 0; +} #endif // !DACCESS_COMPILE diff --git a/src/coreclr/vm/debugdebugger.h b/src/coreclr/vm/debugdebugger.h index f09fc5e00cdfe7..3add9926d97819 100644 --- a/src/coreclr/vm/debugdebugger.h +++ b/src/coreclr/vm/debugdebugger.h @@ -70,6 +70,8 @@ typedef REF STACKFRAMEHELPERREF; typedef StackFrameHelper* STACKFRAMEHELPERREF; #endif +// Validate that the IL offsets in the method returned by WalkILOffsets matches that as reported by the debugger. +void ValidateILOffsets(MethodDesc *pFunc, uint8_t* ipColdStart, size_t coldLen, uint8_t* ipHotStart, size_t hotLen); class DebugStackTrace { @@ -135,4 +137,82 @@ extern "C" void QCALLTYPE StackTrace_GetStackFramesInternal( extern "C" MethodDesc* QCALLTYPE StackFrame_GetMethodDescFromNativeIP(LPVOID ip); + +class ILToNativeMapArrays +{ +private: + // This is the limit on how big the il-to-native map can get, as measured by number + // of entries in each parallel array (IL offset array and native offset array). + // The logic is used to by tracing to ensure that the size of the event does not exceed the Windows event size limit. + uint32_t m_cMapEntriesMax; + bool m_fHasLastMapping = false; + bool m_fNextReplacesLast = false; + int callInstrSequence = 0; + InlineSArray m_rguiNativeOffset; + InlineSArray m_rguiILOffset; + + static int32_t CompareILOffsets(uint32_t ilOffsetA, uint32_t ilOffsetB); + static bool CompareLessOffsets(uint32_t ilOffsetA, uint32_t nativeOffsetA, uint32_t ilOffsetB, uint32_t nativeOffsetB); + static bool CompareGreaterOffsets(uint32_t ilOffsetA, uint32_t nativeOffsetA, uint32_t ilOffsetB, uint32_t nativeOffsetB); + static void Swap(uint32_t* rguiNativeOffset, uint32_t *rguiILOffset, int32_t i, int32_t j); + static void Copy(uint32_t* rguiNativeOffset, uint32_t *rguiILOffset, int32_t i, int32_t j); + static int32_t Partition(uint32_t* rguiNativeOffset, uint32_t *rguiILOffset, int32_t low, int32_t high); + static void QuickSort(uint32_t* rguiNativeOffset, uint32_t *rguiILOffset, int32_t low, int32_t high, int32_t stackDepth = 0); + + void Sort() + { + LIMITED_METHOD_CONTRACT; + + if (m_rguiNativeOffset.GetCount() > 1) + { + // Sort the arrays in place. + QuickSort(m_rguiNativeOffset.GetElements(), m_rguiILOffset.GetElements(), 0, m_rguiNativeOffset.GetCount() - 1); + } + } + +public: + + ILToNativeMapArrays(uint32_t cMapEntriesMax) + : m_cMapEntriesMax(cMapEntriesMax) + { + LIMITED_METHOD_CONTRACT; + } + + void GetArrays(uint32_t *pcMap, uint32_t **prguiNativeOffset, uint32_t **prguiILOffset) + { + LIMITED_METHOD_CONTRACT; + Sort(); + if (m_rguiNativeOffset.GetCount() > 0) + { + static_assert_no_msg(sizeof(uint32_t) == sizeof(COUNT_T)); + if (m_rguiNativeOffset.GetCount() > m_cMapEntriesMax) + { + // If the number of entries exceeds the maximum, we cap it to the maximum. + // This is to ensure that we do not exceed the Windows event size limit. + // Note that this is a rare case, as the JIT should not produce more than + // m_cMapEntriesMax entries in a method in common scenarios, unless code is + // extremely large + *pcMap = m_cMapEntriesMax; + } + else + { + *pcMap = m_rguiNativeOffset.GetCount(); + } + *prguiNativeOffset = m_rguiNativeOffset.GetElements(); + *prguiILOffset = m_rguiILOffset.GetElements(); + } + else + { + *pcMap = 0; + *prguiNativeOffset = NULL; + *prguiILOffset = NULL; + } + } + + void AddEntry(ICorDebugInfo::OffsetMapping *pOffsetMapping); +}; + + +size_t ComputeILOffsetArrays(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext); + #endif // __DEBUG_DEBUGGER_h__ diff --git a/src/coreclr/vm/debuginfostore.cpp b/src/coreclr/vm/debuginfostore.cpp index e3ef94a196066b..9852d79e8324f2 100644 --- a/src/coreclr/vm/debuginfostore.cpp +++ b/src/coreclr/vm/debuginfostore.cpp @@ -22,6 +22,54 @@ static bool Dbg_ShouldUseCookies() } #endif + +static uint32_t u32_min(uint32_t a, uint32_t b) +{ + return a < b ? a : b; +} + +static int32_t i32_max(int32_t a, int32_t b) +{ + return a > b ? a : b; +} + +static uint32_t u32_max(uint32_t a, uint32_t b) +{ + return a > b ? a : b; +} + +static uint64_t ReadFromBitOffsets(PTR_UINT64 pArray, uint32_t bitStart, uint32_t bitCount) +{ + uint32_t elementBitSize = (sizeof(uint64_t) * 8); + _ASSERTE(bitCount <= elementBitSize); + uint32_t lowOffset = bitStart / elementBitSize; + + uint64_t low = pArray[lowOffset]; + + uint32_t bitOffsetInLow = bitStart - lowOffset * elementBitSize; + uint32_t bitsInLow = u32_min(elementBitSize - bitOffsetInLow, bitCount); + + + // Extract LowBits from low + uint64_t lowShift1 = (low >> (int32_t)bitOffsetInLow); + + uint64_t loBitMask = ((1ULL << (bitsInLow)) - 1); + uint64_t result = (lowShift1 & loBitMask); + + if (bitsInLow < bitCount) + { + uint64_t high = pArray[lowOffset + 1]; + int32_t bitsInHigh = bitCount - bitsInLow; + uint64_t hiBitMask = ((1ULL << (bitsInHigh)) - 1); + uint64_t BitsFromHigh = high & hiBitMask; + uint64_t resultBitsFromHigh = BitsFromHigh << bitsInLow; + + result = result | resultBitsFromHigh; + } + + return result; +} + //----------------------------------------------------------------------------- // We have "Transfer" objects that sit on top of the streams. // The objects look identical, but one serializes and the other deserializes. @@ -158,7 +206,7 @@ class TransferReader void DoEncodedU32(uint32_t & dw) { SUPPORTS_DAC; - dw = m_r.ReadEncodedU32(); + dw = m_r.ReadEncodedU32_NoThrow(); } // Use to decode a monotonically increasing delta. @@ -166,7 +214,7 @@ class TransferReader void DoEncodedDeltaU32(uint32_t & dw, uint32_t dwLast) { SUPPORTS_DAC; - uint32_t dwDelta = m_r.ReadEncodedU32(); + uint32_t dwDelta = m_r.ReadEncodedU32_NoThrow(); dw = dwLast + dwDelta; } @@ -174,7 +222,7 @@ class TransferReader { SUPPORTS_DAC; //_ASSERTE(dwAdjust < 0); - dw = m_r.ReadEncodedU32() + dwAdjust; + dw = m_r.ReadEncodedU32_NoThrow() + dwAdjust; } void DoEncodedDeltaU32NonMonotonic(uint32_t& dw, uint32_t dwLast) @@ -187,19 +235,19 @@ class TransferReader void DoEncodedSourceType(ICorDebugInfo::SourceTypes & dw) { SUPPORTS_DAC; - dw = (ICorDebugInfo::SourceTypes) m_r.ReadEncodedU32(); + dw = (ICorDebugInfo::SourceTypes) m_r.ReadEncodedU32_NoThrow(); } void DoEncodedVarLocType(ICorDebugInfo::VarLocType & dw) { SUPPORTS_DAC; - dw = (ICorDebugInfo::VarLocType) m_r.ReadEncodedU32(); + dw = (ICorDebugInfo::VarLocType) m_r.ReadEncodedU32_NoThrow(); } void DoEncodedUnsigned(unsigned & dw) { SUPPORTS_DAC; - dw = (unsigned) m_r.ReadEncodedU32(); + dw = (unsigned) m_r.ReadEncodedU32_NoThrow(); } @@ -208,27 +256,27 @@ class TransferReader { SUPPORTS_DAC; #ifdef TARGET_X86 - dwOffset = m_r.ReadEncodedI32() * sizeof(DWORD); + dwOffset = m_r.ReadEncodedI32_NoThrow() * sizeof(DWORD); #else // Non x86 platforms don't need it to be dword aligned. - dwOffset = m_r.ReadEncodedI32(); + dwOffset = m_r.ReadEncodedI32_NoThrow(); #endif } void DoEncodedRegIdx(ICorDebugInfo::RegNum & reg) { SUPPORTS_DAC; - reg = (ICorDebugInfo::RegNum) m_r.ReadEncodedU32(); + reg = (ICorDebugInfo::RegNum) m_r.ReadEncodedU32_NoThrow(); } void DoMethodHandle(CORINFO_METHOD_HANDLE& p) { #ifdef TARGET_64BIT - uint32_t lo = m_r.ReadUnencodedU32(); - uint32_t hi = m_r.ReadUnencodedU32(); + uint32_t lo = m_r.ReadUnencodedU32_NoThrow(); + uint32_t hi = m_r.ReadUnencodedU32_NoThrow(); p = reinterpret_cast(uintptr_t(lo) | (uintptr_t(hi) << 32)); #else - uint32_t val = m_r.ReadUnencodedU32(); + uint32_t val = m_r.ReadUnencodedU32_NoThrow(); p = reinterpret_cast(static_cast(val)); #endif } @@ -241,7 +289,7 @@ class TransferReader #ifdef _DEBUG if (Dbg_ShouldUseCookies()) { - BYTE b2 = m_r.ReadNibble(); + BYTE b2 = m_r.ReadNibble_NoThrow(); _ASSERTE(b == b2); } #endif @@ -266,52 +314,6 @@ static int g_CDI_bRichDebugInfoTotalUncompress = 0; static int g_CDI_bRichDebugInfoTotalCompress = 0; #endif -//----------------------------------------------------------------------------- -// Serialize Bounds info. -//----------------------------------------------------------------------------- -template -static void DoBounds( - T trans, // transfer object. - ULONG32 cMap, - ICorDebugInfo::OffsetMapping *pMap -) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - SUPPORTS_DAC; - } - CONTRACTL_END; - - - // Bounds info contains (Native Offset, IL Offset, flags) - // - Sorted by native offset (so use a delta encoding for that). - // - IL offsets aren't sorted, but they should be close to each other (so a signed delta encoding) - // They may also include a sentinel value from MappingTypes. - // - flags is 3 independent bits. - - // Loop through and transfer each Entry in the Mapping. - uint32_t dwLastNativeOffset = 0; - for(uint32_t i = 0; i < cMap; i++) - { - ICorDebugInfo::OffsetMapping * pBound = &pMap[i]; - - trans.DoEncodedDeltaU32(pBound->nativeOffset, dwLastNativeOffset); - dwLastNativeOffset = pBound->nativeOffset; - - - trans.DoEncodedAdjustedU32(pBound->ilOffset, (DWORD) ICorDebugInfo::MAX_MAPPING_VALUE); - - trans.DoEncodedSourceType(pBound->source); - - trans.DoCookie(0xA); - } -} - - - // Helper to write a compressed Native Var Info template static void DoNativeVarInfo( @@ -465,6 +467,17 @@ enum EXTRA_DEBUG_INFO_FLAGS #ifndef DACCESS_COMPILE +BYTE* DecompressNew(void*, size_t cBytes) +{ + BYTE* p = (BYTE *)malloc(cBytes); + return p; +} + +void DecompressDelete(void* p) +{ + free(p); +} + void CompressDebugInfo::CompressBoundaries( IN ULONG32 cMap, IN ICorDebugInfo::OffsetMapping *pMap, @@ -484,11 +497,118 @@ void CompressDebugInfo::CompressBoundaries( if (cMap != 0) { + // Get max IL offset and native offsets + uint32_t maxNativeOffsetDelta = 0; + uint32_t maxILOffset = 0; + for (ULONG32 i = 0; i < cMap; i++) + { + maxILOffset = u32_max(maxILOffset, (uint32_t)((int32_t)pMap[i].ilOffset - (int32_t)ICorDebugInfo::MAX_MAPPING_VALUE)); + uint32_t prevNativeOffset = 0; + if (i > 0) + { + prevNativeOffset = pMap[i - 1].nativeOffset; + } + uint32_t nativeOffsetDelta = pMap[i].nativeOffset - prevNativeOffset; + maxNativeOffsetDelta = u32_max(nativeOffsetDelta, maxNativeOffsetDelta); + } + uint32_t ilOffsetBits = 0; + if (maxILOffset == 0) + { + ilOffsetBits = 1; // always have at least 1 bit + } + else + { + BitScanReverse((DWORD*)&ilOffsetBits, maxILOffset); + ilOffsetBits++; // BitScanReverse finds the index of the highest set bit, which is one less than the number of bits needed. + } + uint32_t nativeOffsetBits = 0; + if (maxNativeOffsetDelta == 0) + { + nativeOffsetBits = 1; // always have at least 1 bit + } + else + { + BitScanReverse((DWORD*)&nativeOffsetBits, maxNativeOffsetDelta); + nativeOffsetBits++; // BitScanReverse finds the index of the highest set bit, which is one less than the number of bits needed. + } + pWriter->WriteEncodedU32(cMap); + pWriter->WriteEncodedU32(nativeOffsetBits - 1); + pWriter->WriteEncodedU32(ilOffsetBits - 1); + + uint32_t bitWidth = 2 + nativeOffsetBits + ilOffsetBits; + + uint8_t bitsInProgress = 0; + uint8_t bitsInProgressCount = 0; + + for (uint32_t i = 0; i < cMap; i++) + { + uint32_t prevNativeOffset = 0; + if (i > 0) + { + prevNativeOffset = pMap[i - 1].nativeOffset; + } + uint32_t nativeOffsetDelta = pMap[i].nativeOffset - prevNativeOffset; + + ICorDebugInfo::OffsetMapping * pBound = &pMap[i]; + + uint32_t sourceBits = 0; + switch ((int)pBound->source) + { + case (int)ICorDebugInfo::SOURCE_TYPE_INVALID: + sourceBits = 0; + break; + case (int)ICorDebugInfo::CALL_INSTRUCTION: + sourceBits = 1; + break; + case (int)ICorDebugInfo::STACK_EMPTY: + sourceBits = 2; + break; + case (int)(ICorDebugInfo::CALL_INSTRUCTION | ICorDebugInfo::STACK_EMPTY): + sourceBits = 3; + break; + default: + _ASSERTE(!"Unknown source type in CompressDebugInfo::CompressBoundaries"); + sourceBits = 0; // default to invalid + break; + } - TransferWriter t(*pWriter); - DoBounds(t, cMap, pMap); + uint64_t mappingDataEncoded = sourceBits | + ((uint64_t)nativeOffsetDelta << 2) | + ((uint64_t)((int32_t)pBound->ilOffset - (int32_t)ICorDebugInfo::MAX_MAPPING_VALUE) << (2 + nativeOffsetBits)); + + for (uint8_t bitsToWrite = (uint8_t)bitWidth; bitsToWrite > 0;) + { + // Figure out next bits to write if we need to combine with a previous byte. + if (bitsInProgressCount > 0) + { + uint8_t bitsToAddFromNewEncoding = 8 - bitsInProgressCount; + uint8_t bitsToAddOnToInProgress = (mappingDataEncoded & ((1ULL << bitsToAddFromNewEncoding) - 1)) << bitsInProgressCount; + pWriter->WriteRawByte(bitsToAddOnToInProgress | bitsInProgress); + mappingDataEncoded >>= bitsToAddFromNewEncoding; + bitsToWrite -= bitsToAddFromNewEncoding; + bitsInProgressCount = 0; + } + else if (bitsToWrite >= 8) + { + pWriter->WriteRawByte((uint8_t)mappingDataEncoded); + mappingDataEncoded >>= 8; + bitsToWrite -= 8; + } + else + { + bitsInProgress = (uint8_t)mappingDataEncoded; + bitsInProgressCount = bitsToWrite; + bitsToWrite = 0; + } + } + } + if (bitsInProgressCount > 0) + { + _ASSERTE(bitsInProgressCount < 8); + pWriter->WriteRawByte(bitsInProgress); + } pWriter->Flush(); } @@ -496,6 +616,7 @@ void CompressDebugInfo::CompressBoundaries( DWORD cbBlob; PVOID pBlob = pWriter->GetBlob(&cbBlob); + // Track perf #s for compression... g_CDI_TotalMethods++; g_CDI_bMethodTotalUncompress += sizeof(ICorDebugInfo::OffsetMapping) * cMap; @@ -577,9 +698,122 @@ void CompressDebugInfo::CompressRichDebugInfo( #endif } +// ---------------------------------------------------------------------------- +// DacDbiInterfaceImpl::TranslateInstrumentedILOffsetToOriginal +// +// Description: +// Helper function to convert an instrumented IL offset to the corresponding original IL offset. +// +// Arguments: +// * ilOffset - offset to be translated +// * pMapping - the profiler-provided mapping between original IL offsets and instrumented IL offsets +// +// Return Value: +// Return the translated offset. +// + + +static ULONG TranslateInstrumentedILOffsetToOriginal(ULONG ilOffset, + const InstrumentedILOffsetMapping * pMapping) +{ + SIZE_T cMap = pMapping->GetCount(); + ARRAY_PTR_COR_IL_MAP rgMap = pMapping->GetOffsets(); + + _ASSERTE((cMap == 0) == (rgMap == NULL)); + + // Early out if there is no mapping, or if we are dealing with a special IL offset such as + // prolog, epilog, etc. + if ((cMap == 0) || ((int)ilOffset < 0)) + { + return ilOffset; + } + + SIZE_T i = 0; + for (i = 1; i < cMap; i++) + { + if (ilOffset < rgMap[i].newOffset) + { + return rgMap[i - 1].oldOffset; + } + } + return rgMap[i - 1].oldOffset; +} + +//----------------------------------------------------------------------------- +// Given a instrumented IL map from the profiler that maps: +// Original offset IL_A -> Instrumentend offset IL_B +// And a native mapping from the JIT that maps: +// Instrumented offset IL_B -> native offset Native_C +// This function merges the two maps and stores the result back into the nativeMap. +// The nativeMap now maps: +// Original offset IL_A -> native offset Native_C +// pEntryCount is the number of valid entries in nativeMap, and it may be adjusted downwards +// as part of the composition. +//----------------------------------------------------------------------------- +static void ComposeMapping(const InstrumentedILOffsetMapping * pProfilerILMap, ICorDebugInfo::OffsetMapping nativeMap[], ULONG32* pEntryCount) +{ + // Translate the IL offset if the profiler has provided us with a mapping. + // The ICD public API should always expose the original IL offsets, but GetBoundaries() + // directly accesses the debug info, which stores the instrumented IL offsets. + + ULONG32 entryCount = *pEntryCount; + // The map pointer could be NULL or there could be no entries in the map, in either case no work to do + if (pProfilerILMap && !pProfilerILMap->IsNull()) + { + // If we did instrument, then we can't have any sequence points that + // are "in-between" the old-->new map that the profiler gave us. + // Ex, if map is: + // (6 old -> 36 new) + // (8 old -> 50 new) + // And the jit gives us an entry for 44 new, that will map back to 6 old. + // Since the map can only have one entry for 6 old, we remove 44 new. + + // First Pass: invalidate all the duplicate entries by setting their IL offset to MAX_ILNUM + ULONG32 cDuplicate = 0; + ULONG32 prevILOffset = (ULONG32)(ICorDebugInfo::MAX_ILNUM); + for (ULONG32 i = 0; i < entryCount; i++) + { + ULONG32 origILOffset = TranslateInstrumentedILOffsetToOriginal(nativeMap[i].ilOffset, pProfilerILMap); + + if (origILOffset == prevILOffset) + { + // mark this sequence point as invalid; refer to the comment above + nativeMap[i].ilOffset = (ULONG32)(ICorDebugInfo::MAX_ILNUM); + cDuplicate += 1; + } + else + { + // overwrite the instrumented IL offset with the original IL offset + nativeMap[i].ilOffset = origILOffset; + prevILOffset = origILOffset; + } + } + + // Second Pass: move all the valid entries up front + ULONG32 realIndex = 0; + for (ULONG32 curIndex = 0; curIndex < entryCount; curIndex++) + { + if (nativeMap[curIndex].ilOffset != (ULONG32)(ICorDebugInfo::MAX_ILNUM)) + { + // This is a valid entry. Move it up front. + nativeMap[realIndex] = nativeMap[curIndex]; + realIndex += 1; + } + } + + // make sure we have done the bookkeeping correctly + _ASSERTE((realIndex + cDuplicate) == entryCount); + + // Final Pass: derecement entryCount + entryCount -= cDuplicate; + *pEntryCount = entryCount; + } +} + PTR_BYTE CompressDebugInfo::CompressBoundariesAndVars( IN ICorDebugInfo::OffsetMapping* pOffsetMapping, IN ULONG iOffsetMapping, + const InstrumentedILOffsetMapping * pInstrumentedILBounds, IN ICorDebugInfo::NativeVarInfo* pNativeVarInfo, IN ULONG iNativeVarInfo, IN PatchpointInfo* patchpointInfo, @@ -623,6 +857,23 @@ PTR_BYTE CompressDebugInfo::CompressBoundariesAndVars( pBounds = boundsBuffer.GetBlob(&cbBounds); } + NibbleWriter instrumentedILBoundsBuffer; + DWORD cbUninstrumentedBounds = 0; + PVOID pUninstrumentedBounds = NULL; + if (pInstrumentedILBounds != NULL) + { + NewArrayHolder pInstrumentedILBoundsArray( + new ICorDebugInfo::OffsetMapping[iOffsetMapping]); + + memcpy(pInstrumentedILBoundsArray, pOffsetMapping, iOffsetMapping * sizeof(ICorDebugInfo::OffsetMapping)); + + uint32_t instrumentedEntryCount = iOffsetMapping; + ComposeMapping(pInstrumentedILBounds, pInstrumentedILBoundsArray, &instrumentedEntryCount); + + CompressDebugInfo::CompressBoundaries(instrumentedEntryCount, pInstrumentedILBoundsArray, &instrumentedILBoundsBuffer); + pUninstrumentedBounds = instrumentedILBoundsBuffer.GetBlob(&cbUninstrumentedBounds); + } + NibbleWriter varsBuffer; DWORD cbVars = 0; PVOID pVars = NULL; @@ -643,7 +894,16 @@ PTR_BYTE CompressDebugInfo::CompressBoundariesAndVars( // Now write it all out to the buffer in a compact fashion. NibbleWriter w; - w.WriteEncodedU32(cbBounds); + if (cbUninstrumentedBounds != 0) + { + w.WriteEncodedU32(DebugInfoBoundsHasInstrumentedBounds); // 0xFFFFFFFF is used to indicate that the instrumented bounds are present. + w.WriteEncodedU32(cbBounds); + w.WriteEncodedU32(cbUninstrumentedBounds); + } + else + { + w.WriteEncodedU32(cbBounds); + } w.WriteEncodedU32(cbVars); w.Flush(); @@ -656,7 +916,7 @@ PTR_BYTE CompressDebugInfo::CompressBoundariesAndVars( cbFinalSize += cbPatchpointInfo; cbFinalSize += S_UINT32(4) + S_UINT32(cbRichDebugInfo); - cbFinalSize += S_UINT32(cbHeader) + S_UINT32(cbBounds) + S_UINT32(cbVars); + cbFinalSize += S_UINT32(cbHeader) + S_UINT32(cbBounds) + S_UINT32(cbUninstrumentedBounds) + S_UINT32(cbVars); if (cbFinalSize.IsOverflow()) ThrowHR(COR_E_OVERFLOW); @@ -694,22 +954,117 @@ PTR_BYTE CompressDebugInfo::CompressBoundariesAndVars( memcpy(ptr, pBounds, cbBounds); ptr += cbBounds; + if (cbUninstrumentedBounds > 0) + memcpy(ptr, pUninstrumentedBounds, cbUninstrumentedBounds); + ptr += cbUninstrumentedBounds; + if (cbVars > 0) memcpy(ptr, pVars, cbVars); ptr += cbVars; +#ifdef _DEBUG + ULONG32 cNewBounds = 0; + ULONG32 cNewVars = 0; + ICorDebugInfo::OffsetMapping *pNewMap = NULL; + ICorDebugInfo::NativeVarInfo *pNewVars = NULL; + RestoreBoundariesAndVars( + DecompressNew, NULL, BoundsType::Instrumented, ptrStart, &cNewBounds, &pNewMap, &cNewVars, &pNewVars, writeFlagByte); + + _ASSERTE(cNewBounds == iOffsetMapping); + _ASSERTE(cNewBounds == 0 || pNewMap != NULL); + for (ULONG32 i = 0; i < cNewBounds; i++) + { + _ASSERTE(pNewMap[i].nativeOffset == pOffsetMapping[i].nativeOffset); + _ASSERTE(pNewMap[i].ilOffset == pOffsetMapping[i].ilOffset); + _ASSERTE(pNewMap[i].source == pOffsetMapping[i].source); + } + + _ASSERTE(cNewVars == iNativeVarInfo); + _ASSERTE(cNewVars == 0 || pNewVars != NULL); + + for (ULONG32 i = 0; i < iNativeVarInfo; i++) + { + _ASSERTE(pNewVars[i].startOffset == pNativeVarInfo[i].startOffset); + _ASSERTE(pNewVars[i].endOffset == pNativeVarInfo[i].endOffset); + _ASSERTE(pNewVars[i].varNumber == pNativeVarInfo[i].varNumber); + _ASSERTE(pNewVars[i].loc == pNativeVarInfo[i].loc); + } + + if (pNewMap != NULL) + { + DecompressDelete(pNewMap); + } + if (pNewVars != NULL) + { + DecompressDelete(pNewVars); + } +#endif // _DEBUG + return ptrStart; } #endif // DACCESS_COMPILE +template +static void DoBounds(PTR_BYTE addrBounds, uint32_t cbBounds, TNumBounds countHandler, TPerBound boundHandler) +{ + NibbleReader r(addrBounds, cbBounds); + uint32_t cNumEntries = r.ReadEncodedU32_NoThrow();// writer2.WriteUInt((uint)offsetMapping.Length); // We need the total count + uint32_t bitsForNativeDelta = r.ReadEncodedU32_NoThrow() + 1; // Number of bits needed for native deltas + uint32_t bitsForILOffsets = r.ReadEncodedU32_NoThrow() + 1; // How many bits needed for IL offsets + + uint32_t bitsPerEntry = bitsForNativeDelta + bitsForILOffsets + 2; // 2 bits for source type + TADDR addrBoundsArray = dac_cast(addrBounds) + r.GetNextByteIndex(); + TADDR addrBoundsArrayForReads = AlignDown(addrBoundsArray, sizeof(uint64_t)); + uint32_t bitOffsetForReads = (uint32_t)((addrBoundsArray - addrBoundsArrayForReads) * 8); // We want to read using aligned 64bit reads, but we want to start at the right bit offset. + uint32_t currentNativeOffset = 0; + ICorDebugInfo::OffsetMapping bound; + + _ASSERTE(cNumEntries > 0); + + if (countHandler(cNumEntries)) + { + for (uint32_t iEntry = 0; iEntry < cNumEntries; iEntry++, bitOffsetForReads += bitsPerEntry) + { + uint64_t mappingDataEncoded = ReadFromBitOffsets(dac_cast(addrBoundsArrayForReads), bitOffsetForReads, bitsPerEntry); + switch (mappingDataEncoded & 0x3) // Last 2 bits are source type + { + case 0: + bound.source = ICorDebugInfo::SOURCE_TYPE_INVALID; + break; + case 1: + bound.source = ICorDebugInfo::CALL_INSTRUCTION; + break; + case 2: + bound.source = ICorDebugInfo::STACK_EMPTY; + break; + case 3: + bound.source = (ICorDebugInfo::SourceTypes)(ICorDebugInfo::STACK_EMPTY | ICorDebugInfo::CALL_INSTRUCTION); + break; + } + + mappingDataEncoded = mappingDataEncoded >> 2; // Remove source type bits + uint32_t nativeOffsetDelta = (uint32_t)(mappingDataEncoded & ((1ULL << bitsForNativeDelta) - 1)); + currentNativeOffset += nativeOffsetDelta; + bound.nativeOffset = currentNativeOffset; + + mappingDataEncoded = mappingDataEncoded >> bitsForNativeDelta; // Remove native offset delta bits + bound.ilOffset = (uint32_t)((uint32_t)mappingDataEncoded + (uint32_t)ICorDebugInfo::MAX_MAPPING_VALUE); + if (!boundHandler(bound)) + return; + } + } +} + //----------------------------------------------------------------------------- // Uncompression (restore) routines //----------------------------------------------------------------------------- // Uncompress data supplied by Compress functions. void CompressDebugInfo::RestoreBoundariesAndVars( - IN FP_IDS_NEW fpNew, IN void * pNewData, + IN FP_IDS_NEW fpNew, + IN void * pNewData, + BoundsType boundsType, IN PTR_BYTE pDebugInfo, OUT ULONG32 * pcMap, // number of entries in ppMap OUT ICorDebugInfo::OffsetMapping **ppMap, // pointer to newly allocated array @@ -756,38 +1111,55 @@ void CompressDebugInfo::RestoreBoundariesAndVars( _ASSERTE(flagByte == 0); } - NibbleReader r(pDebugInfo, 12 /* maximum size of compressed 2 UINT32s */); + NibbleReader r(pDebugInfo, 24 /* maximum size of compressed 4 UINT32s */); ULONG cbBounds = r.ReadEncodedU32(); + ULONG cbUninstrumentedBounds = 0; + if (cbBounds == DebugInfoBoundsHasInstrumentedBounds) + { + // This means we have instrumented bounds. + cbBounds = r.ReadEncodedU32(); + cbUninstrumentedBounds = r.ReadEncodedU32(); + } ULONG cbVars = r.ReadEncodedU32(); PTR_BYTE addrBounds = pDebugInfo + r.GetNextByteIndex(); - PTR_BYTE addrVars = addrBounds + cbBounds; + PTR_BYTE addrVars = addrBounds + cbBounds + cbUninstrumentedBounds; - if ((pcMap != NULL || ppMap != NULL) && (cbBounds != 0)) + if ((boundsType == BoundsType::Uninstrumented) && cbUninstrumentedBounds != 0) { - NibbleReader r(addrBounds, cbBounds); - TransferReader t(r); - - UINT32 cNumEntries = r.ReadEncodedU32(); - _ASSERTE(cNumEntries > 0); - - if (pcMap != NULL) - *pcMap = cNumEntries; + // If we have uninstrumented bounds, we will use them instead of the regular bounds. + addrBounds = addrBounds + cbBounds; + cbBounds = cbUninstrumentedBounds; + } - if (ppMap != NULL) - { - ICorDebugInfo::OffsetMapping * pMap = reinterpret_cast - (fpNew(pNewData, cNumEntries * sizeof(ICorDebugInfo::OffsetMapping))); - if (pMap == NULL) + if ((pcMap != NULL || ppMap != NULL) && (cbBounds != 0)) + { + uint32_t iEntry = 0; + DoBounds(addrBounds, cbBounds, + [fpNew, pNewData, &pcMap, &ppMap](uint32_t cNumEntries) { - ThrowOutOfMemory(); - } - *ppMap = pMap; - - // Main decompression routine. - DoBounds(t, cNumEntries, pMap); - } + if (pcMap != NULL) + *pcMap = cNumEntries; + + if (ppMap != NULL) + { + ICorDebugInfo::OffsetMapping * pMap = reinterpret_cast + (fpNew(pNewData, cNumEntries * sizeof(ICorDebugInfo::OffsetMapping))); + if (pMap == NULL) + { + ThrowOutOfMemory(); + } + *ppMap = pMap; + return true; + } + return false; + }, + [&iEntry, &ppMap](ICorDebugInfo::OffsetMapping bound) + { + (*ppMap)[iEntry++] = bound; + return true; + }); } if ((pcVars != NULL || ppVars != NULL) && (cbVars != 0)) @@ -819,6 +1191,100 @@ void CompressDebugInfo::RestoreBoundariesAndVars( } } +size_t CompressDebugInfo::WalkILOffsets( + IN PTR_BYTE pDebugInfo, + BoundsType boundsType, + BOOL hasFlagByte, + void* pContext, + size_t (* pfnWalkILOffsets)(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext) +) +{ + CONTRACTL + { + THROWS; // reading from nibble stream may throw on invalid data. + GC_NOTRIGGER; + MODE_ANY; + SUPPORTS_DAC; + } + CONTRACTL_END; + + if (hasFlagByte) + { + // Check flag byte and skip over any patchpoint info + BYTE flagByte = *pDebugInfo; + pDebugInfo++; + + if ((flagByte & EXTRA_DEBUG_INFO_PATCHPOINT) != 0) + { + PTR_PatchpointInfo patchpointInfo = dac_cast(pDebugInfo); + pDebugInfo += patchpointInfo->PatchpointInfoSize(); + flagByte &= ~EXTRA_DEBUG_INFO_PATCHPOINT; + } + + if ((flagByte & EXTRA_DEBUG_INFO_RICH) != 0) + { + UINT32 cbRichDebugInfo = *PTR_UINT32(pDebugInfo); + pDebugInfo += 4; + pDebugInfo += cbRichDebugInfo; + flagByte &= ~EXTRA_DEBUG_INFO_RICH; + } + + _ASSERTE(flagByte == 0); + } + + NibbleReader r(pDebugInfo, 24 /* maximum size of compressed 4 UINT32s */); + + ULONG cbBounds = r.ReadEncodedU32_NoThrow(); + ULONG cbUninstrumentedBounds = 0; + if (cbBounds == DebugInfoBoundsHasInstrumentedBounds) + { + // This means we have instrumented bounds. + cbBounds = r.ReadEncodedU32(); + cbUninstrumentedBounds = r.ReadEncodedU32(); + } + ULONG cbVars = r.ReadEncodedU32_NoThrow(); + + PTR_BYTE addrBounds = pDebugInfo + r.GetNextByteIndex(); + PTR_BYTE addrVars = addrBounds + cbBounds + cbUninstrumentedBounds; + + if ((boundsType == BoundsType::Uninstrumented) && cbUninstrumentedBounds != 0) + { + // If we have uninstrumented bounds, we will use them instead of the regular bounds. + addrBounds = addrBounds + cbBounds; + cbBounds = cbUninstrumentedBounds; + } + + if (cbBounds != 0) + { + size_t callbackResult = 0; + DoBounds(addrBounds, cbBounds, + [](uint32_t cNumEntries) + { + return true; + }, + [&callbackResult, pfnWalkILOffsets, pContext](ICorDebugInfo::OffsetMapping bound) + { + callbackResult = pfnWalkILOffsets(&bound, pContext); + return callbackResult == 0; + } + ); + if (callbackResult != 0) + { + // We have a callback that wants to stop the walk. + return callbackResult; + } + + ICorDebugInfo::OffsetMapping bound; + bound.nativeOffset = 0xFFFFFFFF; + bound.ilOffset = ICorDebugInfo::NO_MAPPING; + bound.source = ICorDebugInfo::SOURCE_TYPE_INVALID; + + return pfnWalkILOffsets(&bound, pContext); + } + + return 0; +} + #ifdef FEATURE_ON_STACK_REPLACEMENT PatchpointInfo * CompressDebugInfo::RestorePatchpointInfo(IN PTR_BYTE pDebugInfo) @@ -976,7 +1442,9 @@ void DebugInfoRequest::InitFromStartingAddr(MethodDesc * pMD, PCODE addrCode) //----------------------------------------------------------------------------- BOOL DebugInfoManager::GetBoundariesAndVars( const DebugInfoRequest & request, - IN FP_IDS_NEW fpNew, IN void * pNewData, + IN FP_IDS_NEW fpNew, + IN void * pNewData, + BoundsType boundsType, OUT ULONG32 * pcMap, OUT ICorDebugInfo::OffsetMapping ** ppMap, OUT ULONG32 * pcVars, @@ -996,7 +1464,7 @@ BOOL DebugInfoManager::GetBoundariesAndVars( return FALSE; // no info available. } - return pJitMan->GetBoundariesAndVars(request, fpNew, pNewData, pcMap, ppMap, pcVars, ppVars); + return pJitMan->GetBoundariesAndVars(request, fpNew, pNewData, boundsType, pcMap, ppMap, pcVars, ppVars); } BOOL DebugInfoManager::GetRichDebugInfo( diff --git a/src/coreclr/vm/debuginfostore.h b/src/coreclr/vm/debuginfostore.h index 699940486e2130..b8ca0b27ad2a9c 100644 --- a/src/coreclr/vm/debuginfostore.h +++ b/src/coreclr/vm/debuginfostore.h @@ -54,6 +54,11 @@ class DebugInfoRequest // Eg, perhaps we have multiple heaps (eg, loader-heaps per appdomain). typedef BYTE* (*FP_IDS_NEW)(void * pData, size_t cBytes); +enum class BoundsType +{ + Instrumented, // Get the instrumented bounds (or the uninstrumented bounds if no instrumented bounds are available) + Uninstrumented, // Get the uninstrumented bounds +}; //----------------------------------------------------------------------------- // Utility routines used for compression @@ -87,6 +92,7 @@ class CompressDebugInfo static PTR_BYTE CompressBoundariesAndVars( IN ICorDebugInfo::OffsetMapping * pOffsetMapping, IN ULONG iOffsetMapping, + const InstrumentedILOffsetMapping * pInstrumentedILBounds, IN ICorDebugInfo::NativeVarInfo * pNativeVarInfo, IN ULONG iNativeVarInfo, IN PatchpointInfo * patchpointInfo, @@ -100,7 +106,9 @@ class CompressDebugInfo // Uncompress data supplied by Compress functions. static void RestoreBoundariesAndVars( - IN FP_IDS_NEW fpNew, IN void * pNewData, + IN FP_IDS_NEW fpNew, + IN void * pNewData, + BoundsType boundsType, IN PTR_BYTE pDebugInfo, OUT ULONG32 * pcMap, // number of entries in ppMap OUT ICorDebugInfo::OffsetMapping **ppMap, // pointer to newly allocated array @@ -109,6 +117,15 @@ class CompressDebugInfo BOOL hasFlagByte ); + // Walk the ILOffsets without needing to allocate a buffer + static size_t WalkILOffsets( + IN PTR_BYTE pDebugInfo, + BoundsType boundsType, + BOOL hasFlagByte, + void* pContext, + size_t (* pfnWalkILOffsets)(ICorDebugInfo::OffsetMapping *pOffsetMapping, void *pContext) + ); + #ifdef FEATURE_ON_STACK_REPLACEMENT static PatchpointInfo * RestorePatchpointInfo( IN PTR_BYTE pDebugInfo @@ -139,7 +156,9 @@ class DebugInfoManager public: static BOOL GetBoundariesAndVars( const DebugInfoRequest & request, - IN FP_IDS_NEW fpNew, IN void * pNewData, + IN FP_IDS_NEW fpNew, + IN void * pNewData, + BoundsType boundsType, OUT ULONG32 * pcMap, OUT ICorDebugInfo::OffsetMapping ** ppMap, OUT ULONG32 * pcVars, @@ -158,6 +177,6 @@ class DebugInfoManager #endif }; - +#define DebugInfoBoundsHasInstrumentedBounds 0xFFFFFFFF #endif // __DebugInfoStore_H_ diff --git a/src/coreclr/vm/dispatchinfo.cpp b/src/coreclr/vm/dispatchinfo.cpp index 6967b196927371..57043fc89d9922 100644 --- a/src/coreclr/vm/dispatchinfo.cpp +++ b/src/coreclr/vm/dispatchinfo.cpp @@ -2340,7 +2340,7 @@ void DispatchInfo::MarshalParamManagedToNativeRef(DispatchMemberInfo *pMemberInf if (ElementVt == VT_RECORD && pElementMT->IsBlittable()) { GCX_PREEMP(); - pStructMarshalStubAddress = NDirect::GetEntryPointForStructMarshalStub(pElementMT); + pStructMarshalStubAddress = PInvoke::GetEntryPointForStructMarshalStub(pElementMT); } GCPROTECT_END(); diff --git a/src/coreclr/vm/dispparammarshaler.cpp b/src/coreclr/vm/dispparammarshaler.cpp index 5ec105ce4de85b..b54030f814debe 100644 --- a/src/coreclr/vm/dispparammarshaler.cpp +++ b/src/coreclr/vm/dispparammarshaler.cpp @@ -250,7 +250,7 @@ void DispParamArrayMarshaler::MarshalNativeToManaged(VARIANT *pSrcVar, OBJECTREF if (vt == VT_RECORD && !pElemMT->IsBlittable()) { GCX_PREEMP(); - pStructMarshalStubAddress = NDirect::GetEntryPointForStructMarshalStub(pElemMT); + pStructMarshalStubAddress = PInvoke::GetEntryPointForStructMarshalStub(pElemMT); } // Create an array from the SAFEARRAY. @@ -296,7 +296,7 @@ void DispParamArrayMarshaler::MarshalManagedToNative(OBJECTREF *pSrcObj, VARIANT if (vt == VT_RECORD && !pElemMT->IsBlittable()) { GCX_PREEMP(); - pStructMarshalStubAddress = NDirect::GetEntryPointForStructMarshalStub(pElemMT); + pStructMarshalStubAddress = PInvoke::GetEntryPointForStructMarshalStub(pElemMT); } GCPROTECT_END(); @@ -407,7 +407,7 @@ void DispParamRecordMarshaler::MarshalNativeToManaged(VARIANT *pSrcVar, OBJECTRE { GCX_PREEMP(); - pStructMarshalStub = NDirect::CreateStructMarshalILStub(m_pRecordMT); + pStructMarshalStub = PInvoke::CreateStructMarshalILStub(m_pRecordMT); } MarshalStructViaILStub(pStructMarshalStub, BoxedValueClass->GetData(), pvRecord, StructMarshalStubs::MarshalOperation::Unmarshal); diff --git a/src/coreclr/vm/dllimport.cpp b/src/coreclr/vm/dllimport.cpp index ace24da99e6849..e6171f60ebebe2 100644 --- a/src/coreclr/vm/dllimport.cpp +++ b/src/coreclr/vm/dllimport.cpp @@ -493,7 +493,7 @@ class ILStubState : public StubState { STANDARD_VM_CONTRACT; - m_slIL.DoNDirect(m_slIL.GetDispatchCodeStream(), m_dwStubFlags, pStubMD); + m_slIL.DoPInvoke(m_slIL.GetDispatchCodeStream(), m_dwStubFlags, pStubMD); } virtual void EmitExceptionHandler(LocalDesc* pNativeReturnType, LocalDesc* pManagedReturnType, @@ -736,14 +736,9 @@ class ILStubState : public StubState #ifdef FEATURE_COMINTEROP if (SF_IsForwardCOMStub(m_dwStubFlags)) { - // Make sure that the RCW stays alive for the duration of the call. Note that if we do HRESULT - // swapping, we'll pass 'this' to GetCOMHRExceptionObject after returning from the target so - // GC.KeepAlive is not necessary. - if (!SF_IsHRESULTSwapping(m_dwStubFlags)) - { - m_slIL.EmitLoadRCWThis(pcsDispatch, m_dwStubFlags); - pcsDispatch->EmitCALL(METHOD__GC__KEEP_ALIVE, 1, 0); - } + // Make sure that the RCW stays alive for the duration of the call. + m_slIL.EmitLoadRCWThis(pcsDispatch, m_dwStubFlags); + pcsDispatch->EmitCALL(METHOD__GC__KEEP_ALIVE, 1, 0); } #endif // FEATURE_COMINTEROP @@ -761,7 +756,7 @@ class ILStubState : public StubState if (SF_IsCOMStub(m_dwStubFlags)) { m_slIL.EmitLoadStubContext(pcsDispatch, m_dwStubFlags); - m_slIL.EmitLoadRCWThis(pcsDispatch, m_dwStubFlags); + pcsDispatch->EmitLDLOC(m_slIL.GetTargetInterfacePointerLocalNum()); pcsDispatch->EmitCALL(METHOD__STUBHELPERS__GET_COM_HR_EXCEPTION_OBJECT, 3, 1); } @@ -898,7 +893,7 @@ class ILStubState : public StubState #ifdef LOGGING LOG((LF_STUBS, LL_INFO1000, "---------------------------------------------------------------------\n")); - LOG((LF_STUBS, LL_INFO1000, "NDirect IL stub dump: %s::%s\n", pStubMD->m_pszDebugClassName, pStubMD->m_pszDebugMethodName)); + LOG((LF_STUBS, LL_INFO1000, "PInvoke IL stub dump: %s::%s\n", pStubMD->m_pszDebugClassName, pStubMD->m_pszDebugMethodName)); if (LoggingEnabled() && LoggingOn(LF_STUBS, LL_INFO1000)) { CQuickBytes qbManaged; @@ -1019,7 +1014,7 @@ class ILStubState : public StubState // Native Signature // SString strNativeSignature; - if (m_dwStubFlags & NDIRECTSTUB_FL_REVERSE_INTEROP) + if (m_dwStubFlags & PINVOKESTUB_FL_REVERSE_INTEROP) { // Reverse interop. Use StubSignature strNativeSignature = stubMethodSignature; @@ -1073,19 +1068,19 @@ class ILStubState : public StubState // Fire the event // DWORD dwFlags = 0; - if (m_dwStubFlags & NDIRECTSTUB_FL_REVERSE_INTEROP) + if (m_dwStubFlags & PINVOKESTUB_FL_REVERSE_INTEROP) dwFlags |= ETW_IL_STUB_FLAGS_REVERSE_INTEROP; #ifdef FEATURE_COMINTEROP - if (m_dwStubFlags & NDIRECTSTUB_FL_COM) + if (m_dwStubFlags & PINVOKESTUB_FL_COM) dwFlags |= ETW_IL_STUB_FLAGS_COM_INTEROP; #endif // FEATURE_COMINTEROP - if (m_dwStubFlags & NDIRECTSTUB_FL_DELEGATE) + if (m_dwStubFlags & PINVOKESTUB_FL_DELEGATE) dwFlags |= ETW_IL_STUB_FLAGS_DELEGATE; - if (m_dwStubFlags & NDIRECTSTUB_FL_CONVSIGASVARARG) + if (m_dwStubFlags & PINVOKESTUB_FL_CONVSIGASVARARG) dwFlags |= ETW_IL_STUB_FLAGS_VARARG; - if (m_dwStubFlags & NDIRECTSTUB_FL_UNMANAGED_CALLI) + if (m_dwStubFlags & PINVOKESTUB_FL_UNMANAGED_CALLI) dwFlags |= ETW_IL_STUB_FLAGS_UNMANAGED_CALLI; - if (m_dwStubFlags & NDIRECTSTUB_FL_STRUCT_MARSHAL) + if (m_dwStubFlags & PINVOKESTUB_FL_STRUCT_MARSHAL) dwFlags |= ETW_IL_STUB_FLAGS_STRUCT_MARSHAL; DWORD dwToken = 0; @@ -1142,22 +1137,22 @@ class ILStubState : public StubState { LIMITED_METHOD_CONTRACT; LOG((facility, level, "dwStubFlags: 0x%08x\n", dwStubFlags)); - LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_CONVSIGASVARARG, " NDIRECTSTUB_FL_CONVSIGASVARARG\n", facility, level); - LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_BESTFIT, " NDIRECTSTUB_FL_BESTFIT\n", facility, level); - LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR, " NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR\n", facility, level); - LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_SKIP_TRANSITION_NOTIFY, " NDIRECTSTUB_FL_SKIP_TRANSITION_NOTIFY\n", facility, level); - LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_DELEGATE, " NDIRECTSTUB_FL_DELEGATE\n", facility, level); - LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_DOHRESULTSWAPPING, " NDIRECTSTUB_FL_DOHRESULTSWAPPING\n", facility, level); - LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_REVERSE_INTEROP, " NDIRECTSTUB_FL_REVERSE_INTEROP\n", facility, level); - LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_STRUCT_MARSHAL, " NDIRECTSTUB_FL_STRUCT_MARSHAL\n", facility, level); + LogOneFlag(dwStubFlags, PINVOKESTUB_FL_CONVSIGASVARARG, " PINVOKESTUB_FL_CONVSIGASVARARG\n", facility, level); + LogOneFlag(dwStubFlags, PINVOKESTUB_FL_BESTFIT, " PINVOKESTUB_FL_BESTFIT\n", facility, level); + LogOneFlag(dwStubFlags, PINVOKESTUB_FL_THROWONUNMAPPABLECHAR, " PINVOKESTUB_FL_THROWONUNMAPPABLECHAR\n", facility, level); + LogOneFlag(dwStubFlags, PINVOKESTUB_FL_SKIP_TRANSITION_NOTIFY, " PINVOKESTUB_FL_SKIP_TRANSITION_NOTIFY\n", facility, level); + LogOneFlag(dwStubFlags, PINVOKESTUB_FL_DELEGATE, " PINVOKESTUB_FL_DELEGATE\n", facility, level); + LogOneFlag(dwStubFlags, PINVOKESTUB_FL_DOHRESULTSWAPPING, " PINVOKESTUB_FL_DOHRESULTSWAPPING\n", facility, level); + LogOneFlag(dwStubFlags, PINVOKESTUB_FL_REVERSE_INTEROP, " PINVOKESTUB_FL_REVERSE_INTEROP\n", facility, level); + LogOneFlag(dwStubFlags, PINVOKESTUB_FL_STRUCT_MARSHAL, " PINVOKESTUB_FL_STRUCT_MARSHAL\n", facility, level); #ifdef FEATURE_COMINTEROP - LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_COM, " NDIRECTSTUB_FL_COM\n", facility, level); + LogOneFlag(dwStubFlags, PINVOKESTUB_FL_COM, " PINVOKESTUB_FL_COM\n", facility, level); #endif // FEATURE_COMINTEROP - LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_GENERATEDEBUGGABLEIL, " NDIRECTSTUB_FL_GENERATEDEBUGGABLEIL\n", facility, level); - LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_UNMANAGED_CALLI, " NDIRECTSTUB_FL_UNMANAGED_CALLI\n", facility, level); + LogOneFlag(dwStubFlags, PINVOKESTUB_FL_GENERATEDEBUGGABLEIL, " PINVOKESTUB_FL_GENERATEDEBUGGABLEIL\n", facility, level); + LogOneFlag(dwStubFlags, PINVOKESTUB_FL_UNMANAGED_CALLI, " PINVOKESTUB_FL_UNMANAGED_CALLI\n", facility, level); #ifdef FEATURE_COMINTEROP - LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_FIELDGETTER, " NDIRECTSTUB_FL_FIELDGETTER\n", facility, level); - LogOneFlag(dwStubFlags, NDIRECTSTUB_FL_FIELDSETTER, " NDIRECTSTUB_FL_FIELDSETTER\n", facility, level); + LogOneFlag(dwStubFlags, PINVOKESTUB_FL_FIELDGETTER, " PINVOKESTUB_FL_FIELDGETTER\n", facility, level); + LogOneFlag(dwStubFlags, PINVOKESTUB_FL_FIELDSETTER, " PINVOKESTUB_FL_FIELDSETTER\n", facility, level); #endif // FEATURE_COMINTEROP // @@ -1167,22 +1162,22 @@ class ILStubState : public StubState CONSISTENCY_CHECK(!SF_IsCOMEventCallStub(dwStubFlags)); DWORD dwKnownMask = - NDIRECTSTUB_FL_CONVSIGASVARARG | - NDIRECTSTUB_FL_BESTFIT | - NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR | - NDIRECTSTUB_FL_SKIP_TRANSITION_NOTIFY | - NDIRECTSTUB_FL_DELEGATE | - NDIRECTSTUB_FL_DOHRESULTSWAPPING | - NDIRECTSTUB_FL_REVERSE_INTEROP | - NDIRECTSTUB_FL_GENERATEDEBUGGABLEIL | - NDIRECTSTUB_FL_UNMANAGED_CALLI | - NDIRECTSTUB_FL_STRUCT_MARSHAL | + PINVOKESTUB_FL_CONVSIGASVARARG | + PINVOKESTUB_FL_BESTFIT | + PINVOKESTUB_FL_THROWONUNMAPPABLECHAR | + PINVOKESTUB_FL_SKIP_TRANSITION_NOTIFY | + PINVOKESTUB_FL_DELEGATE | + PINVOKESTUB_FL_DOHRESULTSWAPPING | + PINVOKESTUB_FL_REVERSE_INTEROP | + PINVOKESTUB_FL_GENERATEDEBUGGABLEIL | + PINVOKESTUB_FL_UNMANAGED_CALLI | + PINVOKESTUB_FL_STRUCT_MARSHAL | #ifdef FEATURE_COMINTEROP - NDIRECTSTUB_FL_COM | - NDIRECTSTUB_FL_COMLATEBOUND | // internal - NDIRECTSTUB_FL_COMEVENTCALL | // internal - NDIRECTSTUB_FL_FIELDGETTER | - NDIRECTSTUB_FL_FIELDSETTER | + PINVOKESTUB_FL_COM | + PINVOKESTUB_FL_COMLATEBOUND | // internal + PINVOKESTUB_FL_COMEVENTCALL | // internal + PINVOKESTUB_FL_FIELDGETTER | + PINVOKESTUB_FL_FIELDSETTER | #endif // FEATURE_COMINTEROP 0; @@ -1242,7 +1237,7 @@ class ILStubState : public StubState protected: CQuickBytes m_qbNativeFnSigBuffer; - NDirectStubLinker m_slIL; + PInvokeStubLinker m_slIL; BOOL m_fSetLastError; DWORD m_dwStubFlags; }; @@ -1395,20 +1390,20 @@ class PInvoke_ILStubState : public ILStubState { if (TargetHasThis(dwStubFlags)) { - dwStubFlags |= NDIRECTSTUB_FL_TARGET_HAS_THIS; + dwStubFlags |= PINVOKESTUB_FL_TARGET_HAS_THIS; } if (StubHasThis(dwStubFlags)) { - dwStubFlags |= NDIRECTSTUB_FL_STUB_HAS_THIS; + dwStubFlags |= PINVOKESTUB_FL_STUB_HAS_THIS; } - if ((dwStubFlags & NDIRECTSTUB_FL_SUPPRESSGCTRANSITION) == 0 + if ((dwStubFlags & PINVOKESTUB_FL_SUPPRESSGCTRANSITION) == 0 && TargetSuppressGCTransition(dwStubFlags, pTargetMD)) { - dwStubFlags |= NDIRECTSTUB_FL_SUPPRESSGCTRANSITION; + dwStubFlags |= PINVOKESTUB_FL_SUPPRESSGCTRANSITION; } if (HasCheckForPendingException(pTargetMD)) { - dwStubFlags |= NDIRECTSTUB_FL_CHECK_PENDING_EXCEPTION; + dwStubFlags |= PINVOKESTUB_FL_CHECK_PENDING_EXCEPTION; } return dwStubFlags; } @@ -1439,10 +1434,10 @@ class PInvoke_ILStubState : public ILStubState static BOOL HasCheckForPendingException(MethodDesc* pTargetMD) { - if (pTargetMD == NULL || !pTargetMD->IsNDirect()) + if (pTargetMD == NULL || !pTargetMD->IsPInvoke()) return FALSE; - auto pNMD = (NDirectMethodDesc*)pTargetMD; + auto pNMD = (PInvokeMethodDesc*)pTargetMD; if (!Interop::ShouldCheckForPendingException(pNMD)) return FALSE; @@ -1461,7 +1456,7 @@ class CLRToCOM_ILStubState : public ILStubState pStubModule, signature, pTypeContext, - dwStubFlags | NDIRECTSTUB_FL_STUB_HAS_THIS | NDIRECTSTUB_FL_TARGET_HAS_THIS, + dwStubFlags | PINVOKESTUB_FL_STUB_HAS_THIS | PINVOKESTUB_FL_TARGET_HAS_THIS, iLCIDParamIdx, pTargetMD) { @@ -1527,7 +1522,7 @@ class COMToCLR_ILStubState : public ILStubState pStubModule, signature, pTypeContext, - dwStubFlags | NDIRECTSTUB_FL_STUB_HAS_THIS | NDIRECTSTUB_FL_TARGET_HAS_THIS, + dwStubFlags | PINVOKESTUB_FL_STUB_HAS_THIS | PINVOKESTUB_FL_TARGET_HAS_THIS, iLCIDParamIdx, pTargetMD) { @@ -1586,7 +1581,7 @@ class COMToCLRFieldAccess_ILStubState : public COMToCLR_ILStubState }; #endif // FEATURE_COMINTEROP -ILStubLinkerFlags GetILStubLinkerFlagsForNDirectStubFlags(NDirectStubFlags flags) +ILStubLinkerFlags GetILStubLinkerFlagsForPInvokeStubFlags(PInvokeStubFlags flags) { DWORD result = ILSTUB_LINKER_FLAG_NONE; if (!SF_IsCOMStub(flags)) @@ -1597,36 +1592,36 @@ ILStubLinkerFlags GetILStubLinkerFlagsForNDirectStubFlags(NDirectStubFlags flags { result |= ILSTUB_LINKER_FLAG_REVERSE; } - if (flags & NDIRECTSTUB_FL_SUPPRESSGCTRANSITION) + if (flags & PINVOKESTUB_FL_SUPPRESSGCTRANSITION) { result |= ILSTUB_LINKER_FLAG_SUPPRESSGCTRANSITION; } - if (flags & NDIRECTSTUB_FL_STUB_HAS_THIS) + if (flags & PINVOKESTUB_FL_STUB_HAS_THIS) { result |= ILSTUB_LINKER_FLAG_STUB_HAS_THIS; } - if (flags & NDIRECTSTUB_FL_TARGET_HAS_THIS) + if (flags & PINVOKESTUB_FL_TARGET_HAS_THIS) { result |= ILSTUB_LINKER_FLAG_TARGET_HAS_THIS; } return (ILStubLinkerFlags)result; } -NDirectStubLinker::NDirectStubLinker( +PInvokeStubLinker::PInvokeStubLinker( DWORD dwStubFlags, Module* pModule, const Signature &signature, SigTypeContext *pTypeContext, MethodDesc* pTargetMD, int iLCIDParamIdx) - : ILStubLinker(pModule, signature, pTypeContext, pTargetMD, GetILStubLinkerFlagsForNDirectStubFlags((NDirectStubFlags)dwStubFlags)), + : ILStubLinker(pModule, signature, pTypeContext, pTargetMD, GetILStubLinkerFlagsForPInvokeStubFlags((PInvokeStubFlags)dwStubFlags)), m_pCleanupFinallyBeginLabel(NULL), m_pCleanupFinallyEndLabel(NULL), m_pSkipExceptionCleanupLabel(NULL), m_fHasCleanupCode(FALSE), m_fHasExceptionCleanupCode(FALSE), m_fCleanupWorkListIsSetup(FALSE), - m_targetHasThis((dwStubFlags & NDIRECTSTUB_FL_TARGET_HAS_THIS) != 0), + m_targetHasThis((dwStubFlags & PINVOKESTUB_FL_TARGET_HAS_THIS) != 0), m_dwCleanupWorkListLocalNum(-1), m_dwRetValLocalNum(-1), m_ErrorResID(-1), @@ -1665,7 +1660,7 @@ NDirectStubLinker::NDirectStubLinker( #endif // FEATURE_COMINTEROP } -void NDirectStubLinker::SetCallingConvention(CorInfoCallConvExtension unmngCallConv, BOOL fIsVarArg) +void PInvokeStubLinker::SetCallingConvention(CorInfoCallConvExtension unmngCallConv, BOOL fIsVarArg) { LIMITED_METHOD_CONTRACT; @@ -1683,7 +1678,7 @@ void NDirectStubLinker::SetCallingConvention(CorInfoCallConvExtension unmngCallC } } -void NDirectStubLinker::EmitSetArgMarshalIndex(ILCodeStream* pcsEmit, UINT uArgIdx) +void PInvokeStubLinker::EmitSetArgMarshalIndex(ILCodeStream* pcsEmit, UINT uArgIdx) { WRAPPER_NO_CONTRACT; @@ -1713,7 +1708,7 @@ void NDirectStubLinker::EmitSetArgMarshalIndex(ILCodeStream* pcsEmit, UINT uArgI pcsEmit->EmitSTLOC(m_dwArgMarshalIndexLocalNum); } -void NDirectStubLinker::EmitCheckForArgCleanup(ILCodeStream* pcsEmit, UINT uArgIdx, ArgCleanupBranchKind branchKind, ILCodeLabel* pSkipCleanupLabel) +void PInvokeStubLinker::EmitCheckForArgCleanup(ILCodeStream* pcsEmit, UINT uArgIdx, ArgCleanupBranchKind branchKind, ILCodeLabel* pSkipCleanupLabel) { STANDARD_VM_CONTRACT; @@ -1744,55 +1739,55 @@ void NDirectStubLinker::EmitCheckForArgCleanup(ILCodeStream* pcsEmit, UINT uArgI } } -int NDirectStubLinker::GetLCIDParamIdx() +int PInvokeStubLinker::GetLCIDParamIdx() { LIMITED_METHOD_CONTRACT; return m_iLCIDParamIdx; } -ILCodeStream* NDirectStubLinker::GetSetupCodeStream() +ILCodeStream* PInvokeStubLinker::GetSetupCodeStream() { LIMITED_METHOD_CONTRACT; return m_pcsSetup; } -ILCodeStream* NDirectStubLinker::GetMarshalCodeStream() +ILCodeStream* PInvokeStubLinker::GetMarshalCodeStream() { LIMITED_METHOD_CONTRACT; return m_pcsMarshal; } -ILCodeStream* NDirectStubLinker::GetUnmarshalCodeStream() +ILCodeStream* PInvokeStubLinker::GetUnmarshalCodeStream() { LIMITED_METHOD_CONTRACT; return m_pcsUnmarshal; } -ILCodeStream* NDirectStubLinker::GetReturnUnmarshalCodeStream() +ILCodeStream* PInvokeStubLinker::GetReturnUnmarshalCodeStream() { LIMITED_METHOD_CONTRACT; return m_pcsRetUnmarshal; } -ILCodeStream* NDirectStubLinker::GetDispatchCodeStream() +ILCodeStream* PInvokeStubLinker::GetDispatchCodeStream() { LIMITED_METHOD_CONTRACT; return m_pcsDispatch; } -ILCodeStream* NDirectStubLinker::GetCleanupCodeStream() +ILCodeStream* PInvokeStubLinker::GetCleanupCodeStream() { LIMITED_METHOD_CONTRACT; return m_pcsCleanup; } -ILCodeStream* NDirectStubLinker::GetExceptionCleanupCodeStream() +ILCodeStream* PInvokeStubLinker::GetExceptionCleanupCodeStream() { LIMITED_METHOD_CONTRACT; return m_pcsExceptionCleanup; } -void NDirectStubLinker::SetInteropParamExceptionInfo(UINT resID, UINT paramIdx) +void PInvokeStubLinker::SetInteropParamExceptionInfo(UINT resID, UINT paramIdx) { LIMITED_METHOD_CONTRACT; @@ -1806,14 +1801,14 @@ void NDirectStubLinker::SetInteropParamExceptionInfo(UINT resID, UINT paramIdx) m_ErrorParamIdx = paramIdx; } -bool NDirectStubLinker::HasInteropParamExceptionInfo() +bool PInvokeStubLinker::HasInteropParamExceptionInfo() { LIMITED_METHOD_CONTRACT; return !(((DWORD)-1 == m_ErrorResID) && ((DWORD)-1 == m_ErrorParamIdx)); } -void NDirectStubLinker::GenerateInteropParamException(ILCodeStream* pcsEmit) +void PInvokeStubLinker::GenerateInteropParamException(ILCodeStream* pcsEmit) { STANDARD_VM_CONTRACT; @@ -1826,20 +1821,20 @@ void NDirectStubLinker::GenerateInteropParamException(ILCodeStream* pcsEmit) } #ifdef FEATURE_COMINTEROP -DWORD NDirectStubLinker::GetTargetInterfacePointerLocalNum() +DWORD PInvokeStubLinker::GetTargetInterfacePointerLocalNum() { LIMITED_METHOD_CONTRACT; CONSISTENCY_CHECK(m_dwTargetInterfacePointerLocalNum != (DWORD)-1); return m_dwTargetInterfacePointerLocalNum; } -DWORD NDirectStubLinker::GetTargetEntryPointLocalNum() +DWORD PInvokeStubLinker::GetTargetEntryPointLocalNum() { LIMITED_METHOD_CONTRACT; CONSISTENCY_CHECK(m_dwTargetEntryPointLocalNum != (DWORD)-1); return m_dwTargetEntryPointLocalNum; } -void NDirectStubLinker::EmitLoadRCWThis(ILCodeStream *pcsEmit, DWORD dwStubFlags) +void PInvokeStubLinker::EmitLoadRCWThis(ILCodeStream *pcsEmit, DWORD dwStubFlags) { STANDARD_VM_CONTRACT; @@ -1847,34 +1842,34 @@ void NDirectStubLinker::EmitLoadRCWThis(ILCodeStream *pcsEmit, DWORD dwStubFlags } #endif // FEATURE_COMINTEROP -DWORD NDirectStubLinker::GetCleanupWorkListLocalNum() +DWORD PInvokeStubLinker::GetCleanupWorkListLocalNum() { LIMITED_METHOD_CONTRACT; CONSISTENCY_CHECK(m_dwCleanupWorkListLocalNum != (DWORD)-1); return m_dwCleanupWorkListLocalNum; } -DWORD NDirectStubLinker::GetReturnValueLocalNum() +DWORD PInvokeStubLinker::GetReturnValueLocalNum() { LIMITED_METHOD_CONTRACT; return m_dwRetValLocalNum; } -BOOL NDirectStubLinker::IsCleanupNeeded() +BOOL PInvokeStubLinker::IsCleanupNeeded() { LIMITED_METHOD_CONTRACT; return (m_fHasCleanupCode || IsCleanupWorkListSetup()); } -BOOL NDirectStubLinker::IsExceptionCleanupNeeded() +BOOL PInvokeStubLinker::IsExceptionCleanupNeeded() { LIMITED_METHOD_CONTRACT; return m_fHasExceptionCleanupCode; } -void NDirectStubLinker::InitCleanupCode() +void PInvokeStubLinker::InitCleanupCode() { CONTRACTL { @@ -1887,7 +1882,7 @@ void NDirectStubLinker::InitCleanupCode() m_pcsExceptionCleanup->EmitLabel(m_pCleanupFinallyBeginLabel); } -void NDirectStubLinker::InitExceptionCleanupCode() +void PInvokeStubLinker::InitExceptionCleanupCode() { CONTRACTL { @@ -1903,7 +1898,7 @@ void NDirectStubLinker::InitExceptionCleanupCode() EmitCheckForArgCleanup(m_pcsExceptionCleanup, CLEANUP_INDEX_ALL_DONE, BranchIfMarshaled, m_pSkipExceptionCleanupLabel); } -void NDirectStubLinker::SetCleanupNeeded() +void PInvokeStubLinker::SetCleanupNeeded() { WRAPPER_NO_CONTRACT; @@ -1914,7 +1909,7 @@ void NDirectStubLinker::SetCleanupNeeded() } } -void NDirectStubLinker::SetExceptionCleanupNeeded() +void PInvokeStubLinker::SetExceptionCleanupNeeded() { WRAPPER_NO_CONTRACT; @@ -1925,7 +1920,7 @@ void NDirectStubLinker::SetExceptionCleanupNeeded() } } -void NDirectStubLinker::NeedsCleanupList() +void PInvokeStubLinker::NeedsCleanupList() { STANDARD_VM_CONTRACT; @@ -1941,7 +1936,7 @@ void NDirectStubLinker::NeedsCleanupList() } -BOOL NDirectStubLinker::IsCleanupWorkListSetup () +BOOL PInvokeStubLinker::IsCleanupWorkListSetup () { LIMITED_METHOD_CONTRACT; @@ -1949,7 +1944,7 @@ BOOL NDirectStubLinker::IsCleanupWorkListSetup () } -void NDirectStubLinker::LoadCleanupWorkList(ILCodeStream* pcsEmit) +void PInvokeStubLinker::LoadCleanupWorkList(ILCodeStream* pcsEmit) { STANDARD_VM_CONTRACT; @@ -1965,7 +1960,7 @@ void NDirectStubLinker::LoadCleanupWorkList(ILCodeStream* pcsEmit) } -void NDirectStubLinker::Begin(DWORD dwStubFlags) +void PInvokeStubLinker::Begin(DWORD dwStubFlags) { STANDARD_VM_CONTRACT; @@ -1990,7 +1985,7 @@ void NDirectStubLinker::Begin(DWORD dwStubFlags) m_pcsMarshal->EmitLabel(m_pCleanupTryBeginLabel); } -void NDirectStubLinker::End(DWORD dwStubFlags) +void PInvokeStubLinker::End(DWORD dwStubFlags) { STANDARD_VM_CONTRACT; @@ -2089,7 +2084,7 @@ void NDirectStubLinker::End(DWORD dwStubFlags) } } -void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, MethodDesc * pStubMD) +void PInvokeStubLinker::DoPInvoke(ILCodeStream *pcsEmit, DWORD dwStubFlags, MethodDesc * pStubMD) { STANDARD_VM_CONTRACT; @@ -2128,7 +2123,7 @@ void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth { EmitLoadStubContext(pcsEmit, dwStubFlags); - pcsEmit->EmitLDC(offsetof(NDirectMethodDesc, ndirect.m_pNDirectTarget)); + pcsEmit->EmitLDC(offsetof(PInvokeMethodDesc, m_pPInvokeTarget)); pcsEmit->EmitADD(); pcsEmit->EmitLDIND_I(); } @@ -2179,7 +2174,7 @@ void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth pcsEmit->EmitCALLI(TOKEN_ILSTUB_TARGET_SIG, 0, m_iTargetStackDelta); } -void NDirectStubLinker::EmitLogNativeArgument(ILCodeStream* pslILEmit, DWORD dwPinnedLocal) +void PInvokeStubLinker::EmitLogNativeArgument(ILCodeStream* pslILEmit, DWORD dwPinnedLocal) { STANDARD_VM_CONTRACT; @@ -2200,7 +2195,7 @@ void NDirectStubLinker::EmitLogNativeArgument(ILCodeStream* pslILEmit, DWORD dwP } #ifndef DACCESS_COMPILE -void NDirectStubLinker::GetCleanupFinallyOffsets(ILStubEHClause * pClause) +void PInvokeStubLinker::GetCleanupFinallyOffsets(ILStubEHClause * pClause) { CONTRACTL { @@ -2224,7 +2219,7 @@ void NDirectStubLinker::GetCleanupFinallyOffsets(ILStubEHClause * pClause) } #endif // DACCESS_COMPILE -void NDirectStubLinker::ClearCode() +void PInvokeStubLinker::ClearCode() { WRAPPER_NO_CONTRACT; ILStubLinker::ClearCode(); @@ -2236,7 +2231,7 @@ void NDirectStubLinker::ClearCode() } #ifdef PROFILING_SUPPORTED -DWORD NDirectStubLinker::EmitProfilerBeginTransitionCallback(ILCodeStream* pcsEmit, DWORD dwStubFlags) +DWORD PInvokeStubLinker::EmitProfilerBeginTransitionCallback(ILCodeStream* pcsEmit, DWORD dwStubFlags) { STANDARD_VM_CONTRACT; @@ -2266,7 +2261,7 @@ DWORD NDirectStubLinker::EmitProfilerBeginTransitionCallback(ILCodeStream* pcsEm return dwMethodDescLocalNum; } -void NDirectStubLinker::EmitProfilerEndTransitionCallback(ILCodeStream* pcsEmit, DWORD dwStubFlags, DWORD dwMethodDescLocalNum) +void PInvokeStubLinker::EmitProfilerEndTransitionCallback(ILCodeStream* pcsEmit, DWORD dwStubFlags, DWORD dwMethodDescLocalNum) { STANDARD_VM_CONTRACT; @@ -2277,7 +2272,7 @@ void NDirectStubLinker::EmitProfilerEndTransitionCallback(ILCodeStream* pcsEmit, #endif // PROFILING_SUPPPORTED #ifdef VERIFY_HEAP -void NDirectStubLinker::EmitValidateLocal(ILCodeStream* pcsEmit, DWORD dwLocalNum, bool fIsByref, DWORD dwStubFlags) +void PInvokeStubLinker::EmitValidateLocal(ILCodeStream* pcsEmit, DWORD dwLocalNum, bool fIsByref, DWORD dwStubFlags) { STANDARD_VM_CONTRACT; @@ -2310,7 +2305,7 @@ void NDirectStubLinker::EmitValidateLocal(ILCodeStream* pcsEmit, DWORD dwLocalNu } } -void NDirectStubLinker::EmitObjectValidation(ILCodeStream* pcsEmit, DWORD dwStubFlags) +void PInvokeStubLinker::EmitObjectValidation(ILCodeStream* pcsEmit, DWORD dwStubFlags) { STANDARD_VM_CONTRACT; @@ -2346,7 +2341,7 @@ void NDirectStubLinker::EmitObjectValidation(ILCodeStream* pcsEmit, DWORD dwStub #endif // VERIFY_HEAP // Loads the 'secret argument' passed to the stub. -void NDirectStubLinker::EmitLoadStubContext(ILCodeStream* pcsEmit, DWORD dwStubFlags) +void PInvokeStubLinker::EmitLoadStubContext(ILCodeStream* pcsEmit, DWORD dwStubFlags) { STANDARD_VM_CONTRACT; @@ -2704,7 +2699,7 @@ void PInvokeStaticSigInfo::DllImportInit( PRECONDITION(CheckPointer(pMD)); // These preconditions to prevent multithreaded regression - // where pMD->ndirect.m_szLibName was passed in directly, cleared + // where pMD->m_szLibName was passed in directly, cleared // by this API, then accessed on another thread before being reset here. PRECONDITION(CheckPointer(ppLibName, NULL_OK) && (!ppLibName || *ppLibName == NULL)); PRECONDITION(CheckPointer(ppEntryPointName, NULL_OK) && (!ppEntryPointName || *ppEntryPointName == NULL)); @@ -2991,7 +2986,7 @@ namespace { STANDARD_VM_CHECK; PRECONDITION(pMD != NULL); - PRECONDITION(pMD->IsNDirect()); + PRECONDITION(pMD->IsPInvoke()); PRECONDITION(callConv != NULL); } CONTRACTL_END; @@ -3048,13 +3043,13 @@ namespace } } -void NDirect::GetCallingConvention_IgnoreErrors(_In_ MethodDesc* pMD, _Out_opt_ CorInfoCallConvExtension* callConv, _Out_opt_ bool* suppressGCTransition) +void PInvoke::GetCallingConvention_IgnoreErrors(_In_ MethodDesc* pMD, _Out_opt_ CorInfoCallConvExtension* callConv, _Out_opt_ bool* suppressGCTransition) { CONTRACTL { STANDARD_VM_CHECK; PRECONDITION(pMD != NULL); - PRECONDITION(pMD->IsNDirect()); + PRECONDITION(pMD->IsPInvoke()); PRECONDITION(callConv != NULL || suppressGCTransition != NULL); } CONTRACTL_END; @@ -3148,7 +3143,7 @@ void NDirect::GetCallingConvention_IgnoreErrors(_In_ MethodDesc* pMD, _Out_opt_ // FAILED = unknown because something failed. //--------------------------------------------------------- /*static*/ -HRESULT NDirect::HasNAT_LAttribute(IMDInternalImport *pInternalImport, mdToken token, DWORD dwMemberAttrs) +HRESULT PInvoke::HasNAT_LAttribute(IMDInternalImport *pInternalImport, mdToken token, DWORD dwMemberAttrs) { CONTRACTL { @@ -3177,7 +3172,7 @@ HRESULT NDirect::HasNAT_LAttribute(IMDInternalImport *pInternalImport, mdToken t // Either MD or signature & module must be given. /*static*/ -BOOL NDirect::MarshalingRequired( +BOOL PInvoke::MarshalingRequired( _In_opt_ MethodDesc* pMD, _In_opt_ SigPointer sigPointer, _In_opt_ Module* pModule, @@ -3192,7 +3187,7 @@ BOOL NDirect::MarshalingRequired( CONTRACTL_END; // As a by-product, when returning FALSE we will also set the native stack size to the MD if it's - // an NDirectMethodDesc. This number is needed to link the P/Invoke (it determines the @n entry + // an PInvokeMethodDesc. This number is needed to link the P/Invoke (it determines the @n entry // point name suffix and affects alignment thunk generation on the Mac). If this method returns // TRUE, the stack size will be set when building the marshaling IL stub. DWORD dwStackSize = 0; @@ -3201,14 +3196,14 @@ BOOL NDirect::MarshalingRequired( if (pMD != NULL) { // HRESULT swapping is handled by stub - if (pMD->IsNDirect() || pMD->IsCLRToCOMCall()) + if (pMD->IsPInvoke() || pMD->IsCLRToCOMCall()) { if (!IsMiPreserveSig(pMD->GetImplAttrs())) return TRUE; } PInvokeStaticSigInfo sigInfo; - if (!pMD->IsNDirect()) + if (!pMD->IsPInvoke()) { new (&sigInfo) PInvokeStaticSigInfo(pMD); } @@ -3224,8 +3219,8 @@ BOOL NDirect::MarshalingRequired( if (unmanagedCallersOnlyRequiresMarshalling && pMD->HasUnmanagedCallersOnlyAttribute()) return TRUE; - NDirectMethodDesc* pNMD = (NDirectMethodDesc*)pMD; - InitializeSigInfoAndPopulateNDirectMethodDesc(pNMD, &sigInfo); + PInvokeMethodDesc* pNMD = (PInvokeMethodDesc*)pMD; + InitializeSigInfoAndPopulatePInvokeMethodDesc(pNMD, &sigInfo); // Pending exceptions are handled by stub if (Interop::ShouldCheckForPendingException(pNMD)) @@ -3419,9 +3414,9 @@ BOOL NDirect::MarshalingRequired( // do not set the stack size for varargs - the number is call site specific if (pMD != NULL && !pMD->IsVarArg()) { - if (pMD->IsNDirect()) + if (pMD->IsPInvoke()) { - ((NDirectMethodDesc *)pMD)->SetStackArgumentSize(static_cast(dwStackSize), callConv); + ((PInvokeMethodDesc *)pMD)->SetStackArgumentSize(static_cast(dwStackSize), callConv); } #ifdef FEATURE_COMINTEROP else if (pMD->IsCLRToCOMCall()) @@ -3435,7 +3430,7 @@ BOOL NDirect::MarshalingRequired( return FALSE; } -// factorization of CreateNDirectStubWorker +// factorization of CreatePInvokeStubWorker static MarshalInfo::MarshalType DoMarshalReturnValue(MetaSig& msig, mdParamDef* params, CorNativeLinkType nlType, @@ -3568,11 +3563,11 @@ static MarshalInfo::MarshalType DoMarshalReturnValue(MetaSig& msig, } //--------------------------------------------------------- -// Creates a new stub for a N/Direct call. Return refcount is 1. +// Creates a new stub for a PInvoke call. Return refcount is 1. // Note that this function may now throw if it fails to create // a stub. //--------------------------------------------------------- -static void CreateNDirectStubWorker(StubState* pss, +static void CreatePInvokeStubWorker(StubState* pss, StubSigDesc* pSigDesc, CorNativeLinkType nlType, CorNativeLinkFlags nlFlags, @@ -3936,18 +3931,18 @@ static void CreateStructStub(ILStubState* pss, namespace { - class NDirectStubParameters + class PInvokeStubParameters { public: - NDirectStubParameters(Signature sig, + PInvokeStubParameters(Signature sig, SigTypeContext* pTypeContext, Module* pModule, Module* pLoaderModule, CorNativeLinkType nlType, CorNativeLinkFlags nlFlags, CorInfoCallConvExtension unmgdCallConv, - DWORD dwStubFlags, // NDirectStubFlags + DWORD dwStubFlags, // PInvokeStubFlags int nParamTokens, mdParamDef* pParamTokenArray, int iLCIDArg, @@ -3983,14 +3978,14 @@ namespace MethodTable* m_pMT; }; - class NDirectStubHashBlob : public ILStubHashBlobBase + class PInvokeStubHashBlob : public ILStubHashBlobBase { public: Module* m_pModule; MethodTable* m_pMT; WORD m_unmgdCallConv; - BYTE m_nlType; // C_ASSERTS are in NDirect::CreateHashBlob + BYTE m_nlType; // C_ASSERTS are in PInvoke::CreateHashBlob BYTE m_nlFlags; DWORD m_StubFlags; @@ -4012,11 +4007,11 @@ namespace PCCOR_SIGNATURE pvNativeType; }; - ILStubHashBlob* CreateHashBlob(NDirectStubParameters* pParams) + ILStubHashBlob* CreateHashBlob(PInvokeStubParameters* pParams) { STANDARD_VM_CONTRACT; - NDirectStubHashBlob* pBlob; + PInvokeStubHashBlob* pBlob; IMDInternalImport* pInternalImport = pParams->m_pModule->GetMDImport(); @@ -4061,7 +4056,7 @@ namespace // // Build hash blob for IL stub sharing // - S_SIZE_T cbSizeOfBlob = S_SIZE_T(offsetof(NDirectStubHashBlob, m_rgbSigAndParamData)) + + S_SIZE_T cbSizeOfBlob = S_SIZE_T(offsetof(PInvokeStubHashBlob, m_rgbSigAndParamData)) + S_SIZE_T(sizeof(ULONG)) * S_SIZE_T(pParams->m_nParamTokens) + // Parameter attributes S_SIZE_T(sizeof(DWORD)) * S_SIZE_T(pParams->m_nParamTokens) + // Native type blob size S_SIZE_T(cbNativeTypeTotal) + // Native type blob data @@ -4077,7 +4072,7 @@ namespace NewArrayHolder pBytes = new BYTE[cbSizeOfBlob.Value()]; // zero out the hash bytes to ensure all bit fields are deterministically set ZeroMemory(pBytes, cbSizeOfBlob.Value()); - pBlob = (NDirectStubHashBlob*)(BYTE*)pBytes; + pBlob = (PInvokeStubHashBlob*)(BYTE*)pBytes; pBlob->m_pModule = NULL; @@ -4136,7 +4131,7 @@ namespace return (ILStubHashBlob*)pBlob; } - ILStubCache* GetILStubCache(NDirectStubParameters* pParams) + ILStubCache* GetILStubCache(PInvokeStubParameters* pParams) { CONTRACTL { @@ -4153,7 +4148,7 @@ namespace MethodDesc* GetStubMethodDesc( MethodDesc *pTargetMD, - NDirectStubParameters* pParams, + PInvokeStubParameters* pParams, ILStubHashBlob* pHashParams, AllocMemTracker* pamTracker, bool& bILStubCreator, @@ -4190,7 +4185,7 @@ namespace RETURN pMD; } - void RemoveILStubCacheEntry(NDirectStubParameters* pParams, ILStubHashBlob* pHashParams) + void RemoveILStubCacheEntry(PInvokeStubParameters* pParams, ILStubHashBlob* pHashParams) { CONTRACTL { @@ -4210,7 +4205,7 @@ namespace pCache->DeleteEntry(pHashParams); } - void AddMethodDescChunkWithLockTaken(NDirectStubParameters* pParams, MethodDesc *pMD) + void AddMethodDescChunkWithLockTaken(PInvokeStubParameters* pParams, MethodDesc *pMD) { CONTRACTL { @@ -4229,12 +4224,12 @@ namespace } // -// Additional factorization of CreateNDirectStub. This hoists all the metadata accesses -// into one location so that we can leave CreateNDirectStubWorker to just generate the -// IL. This allows us to cache a stub based on the inputs to CreateNDirectStubWorker +// Additional factorization of CreatePInvokeStub. This hoists all the metadata accesses +// into one location so that we can leave CreatePInvokeStubWorker to just generate the +// IL. This allows us to cache a stub based on the inputs to CreatePInvokeStubWorker // instead of having to generate the IL first before doing the caching. // -static void CreateNDirectStubAccessMetadata( +static void CreatePInvokeStubAccessMetadata( StubSigDesc* pSigDesc, // IN CorInfoCallConvExtension unmgdCallConv, // IN DWORD* pdwStubFlags, // IN/OUT @@ -4286,7 +4281,7 @@ static void CreateNDirectStubAccessMetadata( // only COM-to-CLR call supports hresult swapping in the reverse direction if (SF_IsCOMStub(*pdwStubFlags) && !IsMiPreserveSig(dwImplFlags)) { - (*pdwStubFlags) |= NDIRECTSTUB_FL_DOHRESULTSWAPPING; + (*pdwStubFlags) |= PINVOKESTUB_FL_DOHRESULTSWAPPING; } } else @@ -4295,7 +4290,7 @@ static void CreateNDirectStubAccessMetadata( // delegate to an unmanaged method does not. if (!IsMiPreserveSig(dwImplFlags) && !SF_IsDelegateStub(*pdwStubFlags)) { - (*pdwStubFlags) |= NDIRECTSTUB_FL_DOHRESULTSWAPPING; + (*pdwStubFlags) |= PINVOKESTUB_FL_DOHRESULTSWAPPING; } } } @@ -4326,7 +4321,7 @@ static void CreateNDirectStubAccessMetadata( // Do not notify the profiler about QCalls // See ProfilerManagedToUnmanagedTransitionMD() if (pMD->IsQCall()) - *pdwStubFlags |= NDIRECTSTUB_FL_SKIP_TRANSITION_NOTIFY; + *pdwStubFlags |= PINVOKESTUB_FL_SKIP_TRANSITION_NOTIFY; } (*piLCIDArg) = lcidArg; @@ -4346,8 +4341,8 @@ static void CreateNDirectStubAccessMetadata( namespace { - void PopulateNDirectMethodDescImpl( - _Inout_ NDirectMethodDesc* pNMD, + void PopulatePInvokeMethodDescImpl( + _Inout_ PInvokeMethodDesc* pNMD, _In_ const PInvokeStaticSigInfo& sigInfo, _In_opt_z_ LPCUTF8 libName, _In_opt_z_ LPCUTF8 entryPointName) @@ -4361,40 +4356,40 @@ namespace WORD ndirectflags = 0; if (pNMD->MethodDesc::IsVarArg()) - ndirectflags |= NDirectMethodDesc::kVarArgs; + ndirectflags |= PInvokeMethodDesc::kVarArgs; if (sigInfo.GetCharSet() == nltAnsi) - ndirectflags |= NDirectMethodDesc::kNativeAnsi; + ndirectflags |= PInvokeMethodDesc::kNativeAnsi; CorNativeLinkFlags linkflags = sigInfo.GetLinkFlags(); if (linkflags & nlfLastError) - ndirectflags |= NDirectMethodDesc::kLastError; + ndirectflags |= PInvokeMethodDesc::kLastError; if (linkflags & nlfNoMangle) - ndirectflags |= NDirectMethodDesc::kNativeNoMangle; + ndirectflags |= PInvokeMethodDesc::kNativeNoMangle; CorInfoCallConvExtension callConv = sigInfo.GetCallConv(); if (callConv == CorInfoCallConvExtension::Stdcall) - ndirectflags |= NDirectMethodDesc::kStdCall; + ndirectflags |= PInvokeMethodDesc::kStdCall; if (callConv == CorInfoCallConvExtension::Thiscall) - ndirectflags |= NDirectMethodDesc::kThisCall; + ndirectflags |= PInvokeMethodDesc::kThisCall; if (pNMD->GetLoaderModule()->IsSystem() && (strcmp(libName, "QCall") == 0)) { - ndirectflags |= NDirectMethodDesc::kIsQCall; + ndirectflags |= PInvokeMethodDesc::kIsQCall; } else { - pNMD->ndirect.m_pszLibName = libName; + pNMD->m_pszLibName = libName; } - pNMD->ndirect.m_pszEntrypointName = entryPointName; + pNMD->m_pszEntrypointName = entryPointName; // Do not publish incomplete prestub flags or you will introduce a race condition. - pNMD->InterlockedSetNDirectFlags(ndirectflags | NDirectMethodDesc::kNDirectPopulated); + pNMD->InterlockedSetPInvokeFlags(ndirectflags | PInvokeMethodDesc::kPInvokePopulated); } } -void NDirect::PopulateNDirectMethodDesc(_Inout_ NDirectMethodDesc* pNMD) +void PInvoke::PopulatePInvokeMethodDesc(_Inout_ PInvokeMethodDesc* pNMD) { CONTRACTL { @@ -4411,10 +4406,10 @@ void NDirect::PopulateNDirectMethodDesc(_Inout_ NDirectMethodDesc* pNMD) LPCUTF8 szLibName = NULL, szEntryPointName = NULL; PInvokeStaticSigInfo sigInfo(pNMD, &szLibName, &szEntryPointName); - PopulateNDirectMethodDescImpl(pNMD, sigInfo, szLibName, szEntryPointName); + PopulatePInvokeMethodDescImpl(pNMD, sigInfo, szLibName, szEntryPointName); } -void NDirect::InitializeSigInfoAndPopulateNDirectMethodDesc(_Inout_ NDirectMethodDesc* pNMD, _Inout_ PInvokeStaticSigInfo* pSigInfo) +void PInvoke::InitializeSigInfoAndPopulatePInvokeMethodDesc(_Inout_ PInvokeMethodDesc* pNMD, _Inout_ PInvokeStaticSigInfo* pSigInfo) { CONTRACTL { @@ -4433,7 +4428,7 @@ void NDirect::InitializeSigInfoAndPopulateNDirectMethodDesc(_Inout_ NDirectMetho if (pNMD->IsPopulated()) return; - PopulateNDirectMethodDescImpl(pNMD, *pSigInfo, szLibName, szEntryPointName); + PopulatePInvokeMethodDescImpl(pNMD, *pSigInfo, szLibName, szEntryPointName); } #ifdef FEATURE_COMINTEROP @@ -4721,14 +4716,14 @@ namespace //======================================================================= // ILStubCreatorHelper // The class is used as a helper class in CreateInteropILStub. It mainly - // puts two methods NDirect::GetStubMethodDesc and NDirect::RemoveILStubCacheEntry + // puts two methods PInvoke::GetStubMethodDesc and PInvoke::RemoveILStubCacheEntry // into a holder. See CreateInteropILStub for more information //======================================================================= class ILStubCreatorHelper { public: ILStubCreatorHelper(MethodDesc *pTargetMD, - NDirectStubParameters* pParams + PInvokeStubParameters* pParams ) : m_pTargetMD(pTargetMD), m_pParams(pParams), @@ -4799,7 +4794,7 @@ namespace private: MethodDesc* m_pTargetMD; - NDirectStubParameters* m_pParams; + PInvokeStubParameters* m_pParams; NewArrayHolder m_pHashParams; AllocMemTracker* m_pAmTracker; MethodDesc* m_pStubMD; @@ -4866,7 +4861,7 @@ namespace #endif // FEATURE_COMINTEROP // Otherwise, fall back to generating IL stub on-the-fly - NDirectStubParameters params(pSigDesc->m_sig, + PInvokeStubParameters params(pSigDesc->m_sig, &pSigDesc->m_typeContext, pModule, pLoaderModule, @@ -5019,7 +5014,7 @@ namespace BOOL fSigIsStatic = !(callConvInfo & IMAGE_CEE_CS_CALLCONV_HASTHIS); - // CreateNDirectStubWorker will throw an exception for these cases. + // CreatePInvokeStubWorker will throw an exception for these cases. BOOL fCanHaveThis = SF_IsDelegateStub(dwStubFlags) || SF_IsCOMStub(dwStubFlags); if (fSigIsStatic || fCanHaveThis) @@ -5044,7 +5039,7 @@ namespace { // For generic calli, we only support blittable types if (SF_IsCALLIStub(dwStubFlags) - && NDirect::MarshalingRequired(NULL, pStubMD->GetSigPointer(), pSigDesc->m_pModule, &pSigDesc->m_typeContext)) + && PInvoke::MarshalingRequired(NULL, pStubMD->GetSigPointer(), pSigDesc->m_pModule, &pSigDesc->m_typeContext)) { COMPlusThrow(kMarshalDirectiveException, IDS_EE_BADMARSHAL_GENERICS_RESTRICTION); } @@ -5055,7 +5050,7 @@ namespace } } - CreateNDirectStubWorker(pss, + CreatePInvokeStubWorker(pss, pSigDesc, nlType, nlFlags, @@ -5120,9 +5115,9 @@ namespace // (we don't set it for varargs - the number is call site specific) WORD cbStackArgSize = pStubMD->AsDynamicMethodDesc()->GetNativeStackArgSize(); - if (pTargetMD->IsNDirect()) + if (pTargetMD->IsPInvoke()) { - NDirectMethodDesc *pTargetNMD = (NDirectMethodDesc *)pTargetMD; + PInvokeMethodDesc *pTargetNMD = (PInvokeMethodDesc *)pTargetMD; pTargetNMD->SetStackArgumentSize(cbStackArgSize, CallConv::GetDefaultUnmanagedCallingConvention()); } @@ -5147,12 +5142,12 @@ namespace } } -MethodDesc* NDirect::CreateCLRToNativeILStub( +MethodDesc* PInvoke::CreateCLRToNativeILStub( StubSigDesc* pSigDesc, CorNativeLinkType nlType, CorNativeLinkFlags nlFlags, CorInfoCallConvExtension unmgdCallConv, - DWORD dwStubFlags) // NDirectStubFlags + DWORD dwStubFlags) // PInvokeStubFlags { CONTRACT(MethodDesc*) { @@ -5168,7 +5163,7 @@ MethodDesc* NDirect::CreateCLRToNativeILStub( int numParamTokens = 0; mdParamDef* pParamTokenArray = NULL; - CreateNDirectStubAccessMetadata(pSigDesc, + CreatePInvokeStubAccessMetadata(pSigDesc, unmgdCallConv, &dwStubFlags, &iLCIDArg, @@ -5216,12 +5211,12 @@ MethodDesc* NDirect::CreateCLRToNativeILStub( } #ifdef FEATURE_COMINTEROP -MethodDesc* NDirect::CreateFieldAccessILStub( +MethodDesc* PInvoke::CreateFieldAccessILStub( PCCOR_SIGNATURE szMetaSig, DWORD cbMetaSigSize, Module* pModule, mdFieldDef fd, - DWORD dwStubFlags, // NDirectStubFlags + DWORD dwStubFlags, // PInvokeStubFlags FieldDesc* pFD) { CONTRACT(MethodDesc*) @@ -5245,7 +5240,7 @@ MethodDesc* NDirect::CreateFieldAccessILStub( pParamTokenArray[numArgs] = (mdParamDef)fd; // fields are never preserve-sig - dwStubFlags |= NDIRECTSTUB_FL_DOHRESULTSWAPPING; + dwStubFlags |= PINVOKESTUB_FL_DOHRESULTSWAPPING; // convert field signature to getter/setter signature SigBuilder sigBuilder; @@ -5291,7 +5286,7 @@ MethodDesc* NDirect::CreateFieldAccessILStub( #ifndef DACCESS_COMPILE -MethodDesc* NDirect::CreateStructMarshalILStub(MethodTable* pMT) +MethodDesc* PInvoke::CreateStructMarshalILStub(MethodTable* pMT) { CONTRACT(MethodDesc*) { @@ -5310,7 +5305,7 @@ MethodDesc* NDirect::CreateStructMarshalILStub(MethodTable* pMT) if (pCachedStubMD != NULL) RETURN pCachedStubMD; - DWORD dwStubFlags = NDIRECTSTUB_FL_STRUCT_MARSHAL; + DWORD dwStubFlags = PINVOKESTUB_FL_STRUCT_MARSHAL; BOOL bestFit, throwOnUnmappableChar; @@ -5318,11 +5313,11 @@ MethodDesc* NDirect::CreateStructMarshalILStub(MethodTable* pMT) if (bestFit == TRUE) { - dwStubFlags |= NDIRECTSTUB_FL_BESTFIT; + dwStubFlags |= PINVOKESTUB_FL_BESTFIT; } if (throwOnUnmappableChar == TRUE) { - dwStubFlags |= NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR; + dwStubFlags |= PINVOKESTUB_FL_THROWONUNMAPPABLECHAR; } // ValueClass signature: @@ -5409,7 +5404,7 @@ MethodDesc* NDirect::CreateStructMarshalILStub(MethodTable* pMT) RETURN pStubMD; } -PCODE NDirect::GetEntryPointForStructMarshalStub(MethodTable* pMT) +PCODE PInvoke::GetEntryPointForStructMarshalStub(MethodTable* pMT) { LIMITED_METHOD_CONTRACT; @@ -5422,7 +5417,7 @@ PCODE NDirect::GetEntryPointForStructMarshalStub(MethodTable* pMT) #endif // DACCESS_COMPILE -MethodDesc* NDirect::CreateCLRToNativeILStub(PInvokeStaticSigInfo* pSigInfo, +MethodDesc* PInvoke::CreateCLRToNativeILStub(PInvokeStaticSigInfo* pSigInfo, DWORD dwStubFlags, MethodDesc* pMD) { @@ -5444,7 +5439,7 @@ MethodDesc* NDirect::CreateCLRToNativeILStub(PInvokeStaticSigInfo* pSigInfo, namespace { - MethodDesc* GetILStubMethodDesc(NDirectMethodDesc* pNMD, PInvokeStaticSigInfo* pSigInfo, DWORD dwStubFlags) + MethodDesc* GetILStubMethodDesc(PInvokeMethodDesc* pNMD, PInvokeStaticSigInfo* pSigInfo, DWORD dwStubFlags) { CONTRACTL { @@ -5457,16 +5452,16 @@ namespace if (!pNMD->IsVarArgs() || SF_IsForNumParamBytes(dwStubFlags)) { - pStubMD = NDirect::CreateCLRToNativeILStub( + pStubMD = PInvoke::CreateCLRToNativeILStub( pSigInfo, - dwStubFlags & ~NDIRECTSTUB_FL_FOR_NUMPARAMBYTES, + dwStubFlags & ~PINVOKESTUB_FL_FOR_NUMPARAMBYTES, pNMD); } return pStubMD; } - LPVOID NDirectGetEntryPoint(NDirectMethodDesc *pMD, NATIVE_LIBRARY_HANDLE hMod) + LPVOID PInvokeGetEntryPoint(PInvokeMethodDesc *pMD, NATIVE_LIBRARY_HANDLE hMod) { // GetProcAddress cannot be called while preemptive GC is disabled. // It requires the OS to take the loader lock. @@ -5482,9 +5477,9 @@ namespace } //--------------------------------------------------------- - // Loads the DLL and finds the procaddress for an N/Direct call. + // Loads the DLL and finds the procaddress for an PInvoke call. //--------------------------------------------------------- - VOID NDirectLink(NDirectMethodDesc *pMD) + VOID PInvokeLink(PInvokeMethodDesc *pMD) { CONTRACTL { @@ -5506,7 +5501,7 @@ namespace ("%s::%s is not registered using DllImportEntry macro in qcallentrypoints.cpp", pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); #endif - pMD->SetNDirectTarget(pvTarget); + pMD->SetPInvokeTarget(pvTarget); return; } @@ -5517,7 +5512,7 @@ namespace LPVOID pvTarget = (LPVOID)PInvokeOverride::GetMethodImpl(pMD->GetLibNameRaw(), pMD->GetEntrypointName()); if (pvTarget != NULL) { - pMD->SetNDirectTarget(pvTarget); + pMD->SetPInvokeTarget(pvTarget); return; } } @@ -5526,10 +5521,10 @@ namespace _ASSERTE(hmod != NULL); BOOL fSuccess = FALSE; - LPVOID pvTarget = NDirectGetEntryPoint(pMD, hmod); + LPVOID pvTarget = PInvokeGetEntryPoint(pMD, hmod); if (pvTarget) { - pMD->SetNDirectTarget(pvTarget); + pMD->SetPInvokeTarget(pvTarget); fSuccess = TRUE; } @@ -5552,7 +5547,7 @@ namespace } } -PCODE NDirect::GetStubForILStub(MethodDesc* pManagedMD, MethodDesc** ppStubMD, DWORD dwStubFlags) +PCODE PInvoke::GetStubForILStub(MethodDesc* pManagedMD, MethodDesc** ppStubMD, DWORD dwStubFlags) { CONTRACT(PCODE) { @@ -5566,12 +5561,12 @@ PCODE NDirect::GetStubForILStub(MethodDesc* pManagedMD, MethodDesc** ppStubMD, D CONSISTENCY_CHECK(*ppStubMD == NULL); PInvokeStaticSigInfo sigInfo(pManagedMD); - *ppStubMD = NDirect::CreateCLRToNativeILStub(&sigInfo, dwStubFlags, pManagedMD); + *ppStubMD = PInvoke::CreateCLRToNativeILStub(&sigInfo, dwStubFlags, pManagedMD); RETURN JitILStub(*ppStubMD); } -PCODE NDirect::GetStubForILStub(NDirectMethodDesc* pNMD, MethodDesc** ppStubMD, DWORD dwStubFlags) +PCODE PInvoke::GetStubForILStub(PInvokeMethodDesc* pNMD, MethodDesc** ppStubMD, DWORD dwStubFlags) { STANDARD_VM_CONTRACT; @@ -5580,7 +5575,7 @@ PCODE NDirect::GetStubForILStub(NDirectMethodDesc* pNMD, MethodDesc** ppStubMD, CONSISTENCY_CHECK(*ppStubMD == NULL); PInvokeStaticSigInfo sigInfo; - NDirect::InitializeSigInfoAndPopulateNDirectMethodDesc(pNMD, &sigInfo); + PInvoke::InitializeSigInfoAndPopulatePInvokeMethodDesc(pNMD, &sigInfo); *ppStubMD = GetILStubMethodDesc(pNMD, &sigInfo, dwStubFlags); @@ -5596,24 +5591,24 @@ PCODE NDirect::GetStubForILStub(NDirectMethodDesc* pNMD, MethodDesc** ppStubMD, CONSISTENCY_CHECK(pNMD->IsVarArgs()); // - // varargs goes through vararg NDirect stub + // varargs goes through vararg PInvoke stub // - pStub = TheVarargNDirectStub(pNMD->HasRetBuffArg()); + pStub = TheVarargPInvokeStub(pNMD->HasRetBuffArg()); } if (pNMD->IsEarlyBound()) { - pNMD->InitEarlyBoundNDirectTarget(); + pNMD->InitEarlyBoundPInvokeTarget(); } else { - NDirectLink(pNMD); + PInvokeLink(pNMD); } // // NOTE: there is a race in updating this MethodDesc. We depend on all // threads getting back the same DynamicMethodDesc for a particular - // NDirectMethodDesc, in that case, the locking around the actual JIT + // PInvokeMethodDesc, in that case, the locking around the actual JIT // operation will prevent the code from being jitted more than once. // By the time we get here, all threads get the same address of code // back from the JIT operation and they all just fill in the same value @@ -5681,17 +5676,17 @@ PCODE GetStubForInteropMethod(MethodDesc* pMD, DWORD dwStubFlags) STANDARD_VM_CHECK; PRECONDITION(CheckPointer(pMD)); - PRECONDITION(pMD->IsNDirect() || pMD->IsCLRToCOMCall() || pMD->IsEEImpl() || pMD->IsIL()); + PRECONDITION(pMD->IsPInvoke() || pMD->IsCLRToCOMCall() || pMD->IsEEImpl() || pMD->IsIL()); } CONTRACT_END; PCODE pStub = (PCODE)NULL; MethodDesc* pStubMD = NULL; - if (pMD->IsNDirect()) + if (pMD->IsPInvoke()) { - NDirectMethodDesc* pNMD = (NDirectMethodDesc*)pMD; - pStub = NDirect::GetStubForILStub(pNMD, &pStubMD, dwStubFlags); + PInvokeMethodDesc* pNMD = (PInvokeMethodDesc*)pMD; + pStub = PInvoke::GetStubForILStub(pNMD, &pStubMD, dwStubFlags); } #ifdef FEATURE_COMINTEROP else @@ -5711,7 +5706,7 @@ PCODE GetStubForInteropMethod(MethodDesc* pMD, DWORD dwStubFlags) if (pMD->IsIL()) { CONSISTENCY_CHECK(SF_IsReverseStub(dwStubFlags)); - pStub = NDirect::GetStubForILStub(pMD, &pStubMD, dwStubFlags); + pStub = PInvoke::GetStubForILStub(pMD, &pStubMD, dwStubFlags); } else { @@ -5732,7 +5727,7 @@ PCODE GetStubForInteropMethod(MethodDesc* pMD, DWORD dwStubFlags) #ifdef FEATURE_COMINTEROP void CreateCLRToDispatchCOMStub( MethodDesc * pMD, - DWORD dwStubFlags) // NDirectStubFlags + DWORD dwStubFlags) // PInvokeStubFlags { CONTRACTL { @@ -5760,7 +5755,7 @@ void CreateCLRToDispatchCOMStub( int numParamTokens = 0; mdParamDef* pParamTokenArray = NULL; - CreateNDirectStubAccessMetadata(&sigDesc, + CreatePInvokeStubAccessMetadata(&sigDesc, CallConv::GetDefaultUnmanagedCallingConvention(), &dwStubFlags, &iLCIDArg, @@ -5772,12 +5767,12 @@ void CreateCLRToDispatchCOMStub( DispatchStubState MyStubState; - CreateNDirectStubWorker(&MyStubState, + CreatePInvokeStubWorker(&MyStubState, &sigDesc, (CorNativeLinkType)0, (CorNativeLinkFlags)0, CallConv::GetDefaultUnmanagedCallingConvention(), - dwStubFlags | NDIRECTSTUB_FL_COM, + dwStubFlags | PINVOKESTUB_FL_COM, pMD, pParamTokenArray, iLCIDArg); @@ -5791,7 +5786,7 @@ void CreateCLRToDispatchCOMStub( #endif // FEATURE_COMINTEROP -VOID NDirectMethodDesc::SetNDirectTarget(LPVOID pTarget) +VOID PInvokeMethodDesc::SetPInvokeTarget(LPVOID pTarget) { CONTRACTL { @@ -5799,12 +5794,12 @@ VOID NDirectMethodDesc::SetNDirectTarget(LPVOID pTarget) GC_TRIGGERS; MODE_ANY; - PRECONDITION(IsNDirect()); + PRECONDITION(IsPInvoke()); PRECONDITION(pTarget != NULL); } CONTRACTL_END; - ndirect.m_pNDirectTarget = pTarget; + m_pPInvokeTarget = pTarget; } void MarshalStructViaILStub(MethodDesc* pStubMD, void* pManagedData, void* pNativeData, StructMarshalStubs::MarshalOperation operation, void** ppCleanupWorkList /* = nullptr */) @@ -5844,14 +5839,14 @@ void MarshalStructViaILStubCode(PCODE pStubCode, void* pManagedData, void* pNati //========================================================================== -// This function is reached only via NDirectImportThunk. It's purpose +// This function is reached only via PInvokeImportThunk. It's purpose // is to ensure that the target DLL is fully loaded and ready to run. // // FUN FACTS: Though this function is actually entered in unmanaged mode, // it can reenter managed mode and throw a CLR exception if the DLL linking // fails. //========================================================================== -EXTERN_C LPVOID STDCALL NDirectImportWorker(NDirectMethodDesc* pMD) +EXTERN_C LPVOID STDCALL PInvokeImportWorker(PInvokeMethodDesc* pMD) { LPVOID ret = NULL; @@ -5874,10 +5869,10 @@ EXTERN_C LPVOID STDCALL NDirectImportWorker(NDirectMethodDesc* pMD) if (pMD->IsEarlyBound()) { // we need the MD to be populated in case we decide to build an intercept - // stub to wrap the target in InitEarlyBoundNDirectTarget - NDirect::PopulateNDirectMethodDesc(pMD); + // stub to wrap the target in InitEarlyBoundPInvokeTarget + PInvoke::PopulatePInvokeMethodDesc(pMD); - pMD->InitEarlyBoundNDirectTarget(); + pMD->InitEarlyBoundPInvokeTarget(); } else { @@ -5889,19 +5884,19 @@ EXTERN_C LPVOID STDCALL NDirectImportWorker(NDirectMethodDesc* pMD) _ASSERTE((pThread->GetFrame() != FRAME_TOP && pThread->GetFrame()->GetFrameIdentifier() == FrameIdentifier::InlinedCallFrame) || pMD->ShouldSuppressGCTransition()); - CONSISTENCY_CHECK(pMD->IsNDirect()); + CONSISTENCY_CHECK(pMD->IsPInvoke()); // // With IL stubs, we don't have to do anything but ensure the DLL is loaded. // - NDirect::PopulateNDirectMethodDesc(pMD); + PInvoke::PopulatePInvokeMethodDesc(pMD); pMD->CheckRestore(); - NDirectLink(pMD); + PInvokeLink(pMD); } } - ret = pMD->GetNDirectTarget(); + ret = pMD->GetPInvokeTarget(); UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; @@ -5999,13 +5994,13 @@ PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD) Signature signature = pVASigCookie->signature; CorInfoCallConvExtension unmgdCallConv = CorInfoCallConvExtension::Managed; - DWORD dwStubFlags = NDIRECTSTUB_FL_BESTFIT; + DWORD dwStubFlags = PINVOKESTUB_FL_BESTFIT; // The MethodDesc pointer may in fact be the unmanaged target, see PInvokeStubs.asm. if (pMD == NULL || (UINT_PTR)pMD & 0x1) { pMD = NULL; - dwStubFlags |= NDIRECTSTUB_FL_UNMANAGED_CALLI; + dwStubFlags |= PINVOKESTUB_FL_UNMANAGED_CALLI; // need to convert the CALLI signature to stub signature with managed calling convention BYTE callConv = MetaSig::GetCallingConvention(signature); @@ -6031,7 +6026,7 @@ PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD) if (builder.IsCurrentCallConvModSet(CallConvBuilder::CALL_CONV_MOD_SUPPRESSGCTRANSITION)) { - dwStubFlags |= NDIRECTSTUB_FL_SUPPRESSGCTRANSITION; + dwStubFlags |= PINVOKESTUB_FL_SUPPRESSGCTRANSITION; } } @@ -6047,8 +6042,8 @@ PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD) } else { - _ASSERTE(pMD->IsNDirect()); - dwStubFlags |= NDIRECTSTUB_FL_CONVSIGASVARARG; + _ASSERTE(pMD->IsPInvoke()); + dwStubFlags |= PINVOKESTUB_FL_CONVSIGASVARARG; // vararg P/Invoke must be cdecl unmgdCallConv = CorInfoCallConvExtension::C; @@ -6080,7 +6075,7 @@ PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD) StubSigDesc sigDesc(pMD, signature, pVASigCookie->pModule, pVASigCookie->pLoaderModule); sigDesc.InitTypeContext(pVASigCookie->classInst, pVASigCookie->methodInst); - MethodDesc* pStubMD = NDirect::CreateCLRToNativeILStub(&sigDesc, + MethodDesc* pStubMD = PInvoke::CreateCLRToNativeILStub(&sigDesc, nlType, nlFlags, unmgdCallConv, @@ -6088,14 +6083,14 @@ PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD) pTempILStub = JitILStub(pStubMD); - InterlockedCompareExchangeT(&pVASigCookie->pNDirectILStub, + InterlockedCompareExchangeT(&pVASigCookie->pPInvokeILStub, pTempILStub, (PCODE)NULL); UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; - RETURN pVASigCookie->pNDirectILStub; + RETURN pVASigCookie->pPInvokeILStub; } namespace diff --git a/src/coreclr/vm/dllimport.h b/src/coreclr/vm/dllimport.h index b53222626757c8..c9a079f727e106 100644 --- a/src/coreclr/vm/dllimport.h +++ b/src/coreclr/vm/dllimport.h @@ -70,9 +70,9 @@ struct StubSigDesc }; //======================================================================= -// Collects code and data pertaining to the NDirect interface. +// Collects code and data pertaining to the PInvoke interface. //======================================================================= -class NDirect +class PInvoke { public: // Get the calling convention and whether to suppress GC transition for a method by checking: @@ -95,7 +95,7 @@ class NDirect static HRESULT HasNAT_LAttribute(IMDInternalImport *pInternalImport, mdToken token, DWORD dwMemberAttrs); // Either MD or signature & module must be given. - // Note: This method can be called at a time when the associated NDirectMethodDesc + // Note: This method can be called at a time when the associated PInvokeMethodDesc // has not been fully populated. This means the optimized path for this call is to rely // on the most basic P/Invoke metadata. An example when this can happen is when the JIT // is compiling a method containing a P/Invoke that is being considered for inlining. @@ -106,15 +106,15 @@ class NDirect _In_opt_ SigTypeContext* pTypeContext = NULL, _In_ bool unmanagedCallersOnlyRequiresMarshalling = true); - static void PopulateNDirectMethodDesc(_Inout_ NDirectMethodDesc* pNMD); - static void InitializeSigInfoAndPopulateNDirectMethodDesc(_Inout_ NDirectMethodDesc* pNMD, _Inout_ PInvokeStaticSigInfo* pSigInfo); + static void PopulatePInvokeMethodDesc(_Inout_ PInvokeMethodDesc* pNMD); + static void InitializeSigInfoAndPopulatePInvokeMethodDesc(_Inout_ PInvokeMethodDesc* pNMD, _Inout_ PInvokeStaticSigInfo* pSigInfo); static MethodDesc* CreateCLRToNativeILStub( StubSigDesc* pSigDesc, CorNativeLinkType nlType, CorNativeLinkFlags nlFlags, CorInfoCallConvExtension unmgdCallConv, - DWORD dwStubFlags); // NDirectStubFlags + DWORD dwStubFlags); // PInvokeStubFlags #ifdef FEATURE_COMINTEROP static MethodDesc* CreateFieldAccessILStub( @@ -122,7 +122,7 @@ class NDirect DWORD cbMetaSigSize, Module* pModule, mdFieldDef fd, - DWORD dwStubFlags, // NDirectStubFlags + DWORD dwStubFlags, // PInvokeStubFlags FieldDesc* pFD); #endif // FEATURE_COMINTEROP @@ -133,58 +133,58 @@ class NDirect DWORD dwStubFlags, MethodDesc* pMD); - static PCODE GetStubForILStub(NDirectMethodDesc* pNMD, MethodDesc** ppStubMD, DWORD dwStubFlags); + static PCODE GetStubForILStub(PInvokeMethodDesc* pNMD, MethodDesc** ppStubMD, DWORD dwStubFlags); static PCODE GetStubForILStub(MethodDesc* pMD, MethodDesc** ppStubMD, DWORD dwStubFlags); private: - NDirect() {LIMITED_METHOD_CONTRACT;}; // prevent "new"'s on this class + PInvoke() {LIMITED_METHOD_CONTRACT;}; // prevent "new"'s on this class }; //---------------------------------------------------------------- -// Flags passed to CreateNDirectStub that control stub generation +// Flags passed to CreatePInvokeStub that control stub generation //---------------------------------------------------------------- -enum NDirectStubFlags +enum PInvokeStubFlags { - NDIRECTSTUB_FL_CONVSIGASVARARG = 0x00000001, - NDIRECTSTUB_FL_BESTFIT = 0x00000002, - NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR = 0x00000004, - NDIRECTSTUB_FL_SKIP_TRANSITION_NOTIFY = 0x00000008, - NDIRECTSTUB_FL_DELEGATE = 0x00000010, - NDIRECTSTUB_FL_DOHRESULTSWAPPING = 0x00000020, - NDIRECTSTUB_FL_REVERSE_INTEROP = 0x00000040, + PINVOKESTUB_FL_CONVSIGASVARARG = 0x00000001, + PINVOKESTUB_FL_BESTFIT = 0x00000002, + PINVOKESTUB_FL_THROWONUNMAPPABLECHAR = 0x00000004, + PINVOKESTUB_FL_SKIP_TRANSITION_NOTIFY = 0x00000008, + PINVOKESTUB_FL_DELEGATE = 0x00000010, + PINVOKESTUB_FL_DOHRESULTSWAPPING = 0x00000020, + PINVOKESTUB_FL_REVERSE_INTEROP = 0x00000040, #ifdef FEATURE_COMINTEROP - NDIRECTSTUB_FL_COM = 0x00000080, + PINVOKESTUB_FL_COM = 0x00000080, #endif // FEATURE_COMINTEROP // unused = 0x00000100, - NDIRECTSTUB_FL_GENERATEDEBUGGABLEIL = 0x00000200, - NDIRECTSTUB_FL_STRUCT_MARSHAL = 0x00000400, - NDIRECTSTUB_FL_UNMANAGED_CALLI = 0x00000800, + PINVOKESTUB_FL_GENERATEDEBUGGABLEIL = 0x00000200, + PINVOKESTUB_FL_STRUCT_MARSHAL = 0x00000400, + PINVOKESTUB_FL_UNMANAGED_CALLI = 0x00000800, // unused = 0x00001000, #ifdef FEATURE_COMINTEROP - NDIRECTSTUB_FL_FIELDGETTER = 0x00002000, // COM->CLR field getter - NDIRECTSTUB_FL_FIELDSETTER = 0x00004000, // COM->CLR field setter + PINVOKESTUB_FL_FIELDGETTER = 0x00002000, // COM->CLR field getter + PINVOKESTUB_FL_FIELDSETTER = 0x00004000, // COM->CLR field setter #endif // FEATURE_COMINTEROP - NDIRECTSTUB_FL_SUPPRESSGCTRANSITION = 0x00008000, - NDIRECTSTUB_FL_STUB_HAS_THIS = 0x00010000, - NDIRECTSTUB_FL_TARGET_HAS_THIS = 0x00020000, - NDIRECTSTUB_FL_CHECK_PENDING_EXCEPTION = 0x00040000, + PINVOKESTUB_FL_SUPPRESSGCTRANSITION = 0x00008000, + PINVOKESTUB_FL_STUB_HAS_THIS = 0x00010000, + PINVOKESTUB_FL_TARGET_HAS_THIS = 0x00020000, + PINVOKESTUB_FL_CHECK_PENDING_EXCEPTION = 0x00040000, // unused = 0x00080000, // unused = 0x00100000, // unused = 0x00200000, // unused = 0x00400000, // unused = 0x00800000, - // internal flags -- these won't ever show up in an NDirectStubHashBlob - NDIRECTSTUB_FL_FOR_NUMPARAMBYTES = 0x10000000, // do just enough to return the right value from Marshal.NumParamBytes + // internal flags -- these won't ever show up in an PInvokeStubHashBlob + PINVOKESTUB_FL_FOR_NUMPARAMBYTES = 0x10000000, // do just enough to return the right value from Marshal.NumParamBytes #ifdef FEATURE_COMINTEROP - NDIRECTSTUB_FL_COMLATEBOUND = 0x20000000, // we use a generic stub for late bound calls - NDIRECTSTUB_FL_COMEVENTCALL = 0x40000000, // we use a generic stub for event calls + PINVOKESTUB_FL_COMLATEBOUND = 0x20000000, // we use a generic stub for late bound calls + PINVOKESTUB_FL_COMEVENTCALL = 0x40000000, // we use a generic stub for event calls #endif // FEATURE_COMINTEROP // Note: The upper half of the range is reserved for ILStubTypes enum - NDIRECTSTUB_FL_MASK = 0x7FFFFFFF, - NDIRECTSTUB_FL_INVALID = 0x80000000, + PINVOKESTUB_FL_MASK = 0x7FFFFFFF, + PINVOKESTUB_FL_INVALID = 0x80000000, }; enum ILStubTypes @@ -213,18 +213,18 @@ enum ILStubTypes #define COM_ONLY(x) false #endif // FEATURE_COMINTEROP -inline bool SF_IsVarArgStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_CONVSIGASVARARG)); } -inline bool SF_IsBestFit (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_BESTFIT)); } -inline bool SF_IsThrowOnUnmappableChar (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR)); } -inline bool SF_SkipTransitionNotify (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_SKIP_TRANSITION_NOTIFY)); } -inline bool SF_IsDelegateStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_DELEGATE)); } -inline bool SF_IsHRESULTSwapping (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_DOHRESULTSWAPPING)); } -inline bool SF_IsReverseStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_REVERSE_INTEROP)); } -inline bool SF_IsDebuggableStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_GENERATEDEBUGGABLEIL)); } -inline bool SF_IsCALLIStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_UNMANAGED_CALLI)); } -inline bool SF_IsForNumParamBytes (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_FOR_NUMPARAMBYTES)); } -inline bool SF_IsStructMarshalStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_STRUCT_MARSHAL)); } -inline bool SF_IsCheckPendingException (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_CHECK_PENDING_EXCEPTION)); } +inline bool SF_IsVarArgStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_CONVSIGASVARARG)); } +inline bool SF_IsBestFit (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_BESTFIT)); } +inline bool SF_IsThrowOnUnmappableChar (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_THROWONUNMAPPABLECHAR)); } +inline bool SF_SkipTransitionNotify (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_SKIP_TRANSITION_NOTIFY)); } +inline bool SF_IsDelegateStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_DELEGATE)); } +inline bool SF_IsHRESULTSwapping (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_DOHRESULTSWAPPING)); } +inline bool SF_IsReverseStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_REVERSE_INTEROP)); } +inline bool SF_IsDebuggableStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_GENERATEDEBUGGABLEIL)); } +inline bool SF_IsCALLIStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_UNMANAGED_CALLI)); } +inline bool SF_IsForNumParamBytes (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_FOR_NUMPARAMBYTES)); } +inline bool SF_IsStructMarshalStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_STRUCT_MARSHAL)); } +inline bool SF_IsCheckPendingException (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_CHECK_PENDING_EXCEPTION)); } inline bool SF_IsVirtualStaticMethodDispatchStub(DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return dwStubFlags == ILSTUB_STATIC_VIRTUAL_DISPATCH_STUB; } @@ -245,11 +245,11 @@ inline bool SF_IsTailCallCallTargetStub (DWORD dwStubFlags) { LIMITED_METHOD_CON inline bool SF_IsDelegateShuffleThunk (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags == ILSTUB_DELEGATE_SHUFFLE_THUNK); } inline bool SF_IsAsyncResumeStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags == ILSTUB_ASYNC_RESUME); } -inline bool SF_IsCOMStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_COM)); } -inline bool SF_IsCOMLateBoundStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_COMLATEBOUND)); } -inline bool SF_IsCOMEventCallStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_COMEVENTCALL)); } -inline bool SF_IsFieldGetterStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_FIELDGETTER)); } -inline bool SF_IsFieldSetterStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < NDIRECTSTUB_FL_INVALID && 0 != (dwStubFlags & NDIRECTSTUB_FL_FIELDSETTER)); } +inline bool SF_IsCOMStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_COM)); } +inline bool SF_IsCOMLateBoundStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_COMLATEBOUND)); } +inline bool SF_IsCOMEventCallStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_COMEVENTCALL)); } +inline bool SF_IsFieldGetterStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_FIELDGETTER)); } +inline bool SF_IsFieldSetterStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return COM_ONLY(dwStubFlags < PINVOKESTUB_FL_INVALID && 0 != (dwStubFlags & PINVOKESTUB_FL_FIELDSETTER)); } inline bool SF_IsSharedStub(DWORD dwStubFlags) { @@ -328,7 +328,7 @@ enum ETW_IL_STUB_FLAGS // each flavor supports roughly the same switches. Those switches which can be // statically determined via CAs (DllImport, UnmanagedFunctionPointer, // BestFitMappingAttribute, etc) or via MetaSig are parsed and unified by this -// class. There are two flavors of constructor, one for NDirectMethodDescs and one +// class. There are two flavors of constructor, one for PInvokeMethodDescs and one // for Delegates. //--------------------------------------------------------- struct PInvokeStaticSigInfo @@ -373,16 +373,16 @@ struct PInvokeStaticSigInfo WRAPPER_NO_CONTRACT; DWORD flags = 0; if (GetThrowOnUnmappableChar()) - flags |= NDIRECTSTUB_FL_THROWONUNMAPPABLECHAR; + flags |= PINVOKESTUB_FL_THROWONUNMAPPABLECHAR; if (GetBestFitMapping()) - flags |= NDIRECTSTUB_FL_BESTFIT; + flags |= PINVOKESTUB_FL_BESTFIT; if (IsDelegateInterop()) - flags |= NDIRECTSTUB_FL_DELEGATE; + flags |= PINVOKESTUB_FL_DELEGATE; if (ShouldSuppressGCTransition()) - flags |= NDIRECTSTUB_FL_SUPPRESSGCTRANSITION; + flags |= PINVOKESTUB_FL_SUPPRESSGCTRANSITION; return flags; } @@ -461,10 +461,10 @@ struct PInvokeStaticSigInfo #include "stubgen.h" #ifndef DACCESS_COMPILE -class NDirectStubLinker : public ILStubLinker +class PInvokeStubLinker : public ILStubLinker { public: - NDirectStubLinker( + PInvokeStubLinker( DWORD dwStubFlags, Module* pModule, const Signature &signature, @@ -476,7 +476,7 @@ class NDirectStubLinker : public ILStubLinker void Begin(DWORD dwStubFlags); void End(DWORD dwStubFlags); - void DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, MethodDesc * pStubMD); + void DoPInvoke(ILCodeStream *pcsEmit, DWORD dwStubFlags, MethodDesc * pStubMD); void EmitLogNativeArgument(ILCodeStream* pslILEmit, DWORD dwPinnedLocal); void LoadCleanupWorkList(ILCodeStream* pcsEmit); #ifdef PROFILING_SUPPORTED diff --git a/src/coreclr/vm/dllimportcallback.cpp b/src/coreclr/vm/dllimportcallback.cpp index 405da3b43d8e25..58cd290172cbc3 100644 --- a/src/coreclr/vm/dllimportcallback.cpp +++ b/src/coreclr/vm/dllimportcallback.cpp @@ -289,6 +289,8 @@ void UMEntryThunkData::Terminate() // TheUMEntryPrestub includes diagnostic for collected delegates m_pUMEntryThunk->SetTargetUnconditional(TheUMThunkPreStub()); + FlushCacheForDynamicMappedStub(m_pUMEntryThunk, sizeof(UMEntryThunk)); + OBJECTHANDLE pObjectHandle = m_pObjectHandle; // Set m_pObjectHandle indicate the collected state @@ -336,18 +338,18 @@ MethodDesc* UMThunkMarshInfo::GetILStubMethodDesc(MethodDesc* pInvokeMD, PInvoke STANDARD_VM_CONTRACT; MethodDesc* pStubMD = NULL; - dwStubFlags |= NDIRECTSTUB_FL_REVERSE_INTEROP; // could be either delegate interop or not--that info is passed in from the caller + dwStubFlags |= PINVOKESTUB_FL_REVERSE_INTEROP; // could be either delegate interop or not--that info is passed in from the caller #if defined(DEBUGGING_SUPPORTED) // Combining the next two lines, and eliminating jitDebuggerFlags, leads to bad codegen in x86 Release builds using Visual C++ 19.00.24215.1. CORJIT_FLAGS jitDebuggerFlags = GetDebuggerCompileFlags(pSigInfo->GetModule(), CORJIT_FLAGS()); if (jitDebuggerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE)) { - dwStubFlags |= NDIRECTSTUB_FL_GENERATEDEBUGGABLEIL; + dwStubFlags |= PINVOKESTUB_FL_GENERATEDEBUGGABLEIL; } #endif // DEBUGGING_SUPPORTED - pStubMD = NDirect::CreateCLRToNativeILStub( + pStubMD = PInvoke::CreateCLRToNativeILStub( pSigInfo, dwStubFlags, pInvokeMD // may be NULL @@ -411,7 +413,7 @@ VOID UMThunkMarshInfo::RunTimeInit() DWORD dwStubFlags = 0; if (sigInfo.IsDelegateInterop()) - dwStubFlags |= NDIRECTSTUB_FL_DELEGATE; + dwStubFlags |= PINVOKESTUB_FL_DELEGATE; MethodDesc* pStubMD = GetILStubMethodDesc(pMD, &sigInfo, dwStubFlags); PCODE pFinalILStub = JitILStub(pStubMD); diff --git a/src/coreclr/vm/dllimportcallback.h b/src/coreclr/vm/dllimportcallback.h index b79d066c0b5470..5341c1420e4d61 100644 --- a/src/coreclr/vm/dllimportcallback.h +++ b/src/coreclr/vm/dllimportcallback.h @@ -142,7 +142,7 @@ class UMEntryThunk : private StubPrecode class UMEntryThunkData { friend class UMEntryThunkFreeList; - friend class NDirectStubLinker; + friend class PInvokeStubLinker; // The start of the managed code. // if m_pObjectHandle is non-NULL, this field is still set to help with diagnostic of call on collected delegate crashes @@ -208,6 +208,8 @@ class UMEntryThunkData #ifdef _DEBUG m_state = kLoadTimeInited; #endif + + FlushCacheForDynamicMappedStub(m_pUMEntryThunk, sizeof(UMEntryThunk)); } void Terminate(); diff --git a/src/coreclr/vm/domainassembly.cpp b/src/coreclr/vm/domainassembly.cpp index 653117ba3ecc29..8a34fbe57be54e 100644 --- a/src/coreclr/vm/domainassembly.cpp +++ b/src/coreclr/vm/domainassembly.cpp @@ -38,8 +38,10 @@ DomainAssembly::DomainAssembly(PEAssembly* pPEAssembly, LoaderAllocator* pLoader m_pAssembly->SetDomainAssembly(this); +#ifndef PEIMAGE_FLAT_LAYOUT_ONLY // Creating the Assembly should have ensured the PEAssembly is loaded _ASSERT(GetPEAssembly()->IsLoaded()); +#endif } DomainAssembly::~DomainAssembly() diff --git a/src/coreclr/vm/dwbucketmanager.hpp b/src/coreclr/vm/dwbucketmanager.hpp index 372f37f928ce8d..c51c6f0f3ac411 100644 --- a/src/coreclr/vm/dwbucketmanager.hpp +++ b/src/coreclr/vm/dwbucketmanager.hpp @@ -326,7 +326,6 @@ class BaseBucketParamsManager void GetExceptionName(_Out_writes_(maxLength) WCHAR* targetParam, int maxLength); void GetPackageMoniker(_Out_writes_(maxLength) WCHAR* targetParam, int maxLength); void GetPRAID(_Out_writes_(maxLength) WCHAR* targetParam, int maxLength); - void GetIlRva(_Out_writes_(maxLength) WCHAR* targetParam, int maxLength); public: BaseBucketParamsManager(GenericModeBlock* pGenericModeBlock, TypeOfReportedError typeOfError, PCODE initialFaultingPc, Thread* pFaultingThread, OBJECTREF* pThrownException); @@ -810,31 +809,6 @@ void BaseBucketParamsManager::GetPRAID(_Out_writes_(maxLength) WCHAR* targetPara _ASSERTE(!"PRAID support NYI for CoreCLR"); } -void BaseBucketParamsManager::GetIlRva(_Out_writes_(maxLength) WCHAR* targetParam, int maxLength) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - DWORD ilOffset = GetILOffset(); - - if (ilOffset == MAXDWORD) - ilOffset = 0; - - if (m_pFaultingMD) - ilOffset += m_pFaultingMD->GetRVA(); - - _snwprintf_s(targetParam, - maxLength, - _TRUNCATE, - W("%x"), - ilOffset); -} - // helper functions DWORD BaseBucketParamsManager::GetILOffset() diff --git a/src/coreclr/vm/dynamicmethod.cpp b/src/coreclr/vm/dynamicmethod.cpp index a02cd30a21b5bb..0af6c360bf7973 100644 --- a/src/coreclr/vm/dynamicmethod.cpp +++ b/src/coreclr/vm/dynamicmethod.cpp @@ -11,6 +11,7 @@ #include "nibblemapmacros.h" #include "stringliteralmap.h" #include "virtualcallstub.h" +#include "finalizerthread.h" #include "CachedInterfaceDispatchPal.h" #include "CachedInterfaceDispatch.h" @@ -181,10 +182,7 @@ void DynamicMethodTable::AddMethodsToList() | DynamicMethodDesc::FlagStatic | DynamicMethodDesc::FlagIsLCGMethod); - LCGMethodResolver* pResolver = new (pResolvers) LCGMethodResolver(); - pResolver->m_pDynamicMethod = pNewMD; - pResolver->m_DynamicMethodTable = this; - pNewMD->m_pResolver = pResolver; + pNewMD->m_pResolver = new (pResolvers) LCGMethodResolver(pNewMD, this); pNewMD->SetTemporaryEntryPoint(&amt); @@ -194,7 +192,7 @@ void DynamicMethodTable::AddMethodsToList() if (pPrevMD) { - pPrevMD->GetLCGMethodResolver()->m_next = pNewMD; + pPrevMD->GetLCGMethodResolver()->SetNextFreeDynamicMethod(pNewMD); } pPrevMD = pNewMD; pNewMD = (DynamicMethodDesc *)(dac_cast(pNewMD) + pNewMD->SizeOf()); @@ -243,7 +241,7 @@ DynamicMethodDesc* DynamicMethodTable::GetDynamicMethod(BYTE *psig, DWORD sigSiz pNewMD = m_DynamicMethodList; if (pNewMD) { - m_DynamicMethodList = pNewMD->GetLCGMethodResolver()->m_next; + m_DynamicMethodList = pNewMD->GetLCGMethodResolver()->GetNextFreeDynamicMethodDesc(); #ifdef _DEBUG m_Used++; #endif @@ -290,28 +288,26 @@ DynamicMethodDesc* DynamicMethodTable::GetDynamicMethod(BYTE *psig, DWORD sigSiz RETURN pNewMD; } -void DynamicMethodTable::LinkMethod(DynamicMethodDesc *pMethod) +void DynamicMethodTable::AddToFreeList(DynamicMethodDesc *pMethod) { - CONTRACT_VOID + CONTRACTL { NOTHROW; - GC_TRIGGERS; - MODE_ANY; + GC_NOTRIGGER; + MODE_PREEMPTIVE; PRECONDITION(CheckPointer(pMethod)); } - CONTRACT_END; + CONTRACTL_END; - LOG((LF_BCL, LL_INFO10000, "Level4 - Returning DynamicMethod to free list {0x%p} (used %d)\n", pMethod, m_Used)); + LOG((LF_BCL, LL_INFO10000, "Level4 - Returning DynamicMethod to free list {%p} (used %d)\n", pMethod, m_Used)); { LockHolder lh(this); - pMethod->GetLCGMethodResolver()->m_next = m_DynamicMethodList; + pMethod->GetLCGMethodResolver()->SetNextFreeDynamicMethod(m_DynamicMethodList); m_DynamicMethodList = pMethod; #ifdef _DEBUG m_Used--; #endif } - - RETURN; } @@ -859,7 +855,6 @@ HostCodeHeap* HostCodeHeap::GetCodeHeap(TADDR codeStart) return HostCodeHeap::GetTrackAllocation(codeStart)->pHeap; } - #ifndef DACCESS_COMPILE void HostCodeHeap::FreeMemForCode(void * codeStart) @@ -873,7 +868,7 @@ void HostCodeHeap::FreeMemForCode(void * codeStart) m_ApproximateLargestBlock += pTracker->size; m_AllocationCount--; - LOG((LF_BCL, LL_INFO100, "Level2 - CodeHeap released [0x%p, vt(0x%x)] - ref count %d\n", this, *(size_t*)this, m_AllocationCount)); + LOG((LF_BCL, LL_INFO100, "Level2 - CodeHeap released [%p, vt(0x%zx)] - ref count %d\n", this, *(size_t*)this, m_AllocationCount)); if (m_AllocationCount == 0) { @@ -884,47 +879,41 @@ void HostCodeHeap::FreeMemForCode(void * codeStart) // // Implementation for DynamicMethodDesc declared in method.hpp // -void DynamicMethodDesc::Destroy() +bool DynamicMethodDesc::TryDestroy() { - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; + STANDARD_VM_CONTRACT; + _ASSERTE(FinalizerThread::IsCurrentThreadFinalizer()); - _ASSERTE(IsDynamicMethod()); LoaderAllocator *pLoaderAllocator = GetLoaderAllocator(); - LOG((LF_BCL, LL_INFO1000, "Level3 - Destroying DynamicMethod {0x%p}\n", this)); + LOG((LF_BCL, LL_INFO1000, "Level3 - Destroying DynamicMethodDesc {%p}\n", this)); - // The m_pSig and m_pszMethodName need to be destroyed after the GetLCGMethodResolver()->Destroy() call - // otherwise the EEJitManager::CodeHeapIterator could return DynamicMethodDesc with these members NULLed, but - // the nibble map for the corresponding code memory indicating that this DynamicMethodDesc is still alive. - PCODE pSig = m_pSig; - PTR_CUTF8 pszMethodName = m_pszMethodName; - - GetLCGMethodResolver()->Destroy(); - // The current DynamicMethodDesc storage is destroyed at this point + PTR_LCGMethodResolver methodResolver = GetLCGMethodResolver(); - if (pszMethodName != NULL) + // Destroy the code heap memory associated with this method first. + // This is done before any other destruction to ensure that CodeHeap + // iteration won't find this method while it is being destroyed. + if (!methodResolver->TryDestroyCodeHeapMemory()) { - delete[] pszMethodName; + // We failed to destroy the code heap memory, so we cannot continue with the destruction. + return false; } - if (pSig != (PCODE)NULL) - { - delete[] (BYTE*)pSig; - } + // See ModuleHandle_GetDynamicMethod() for allocation of these DynamicMethodDesc members. + // Free the member field memory here prior to storage reclamation below. + delete[] m_pszMethodName; + delete[] (BYTE*)m_pSig; + + methodResolver->DestroyResolver(); + // The current DynamicMethodDesc storage is destroyed at this point + // If the LoaderAllocator is collectible, we release it. if (pLoaderAllocator->IsCollectible()) { if (pLoaderAllocator->Release()) - { - GCX_PREEMP(); LoaderAllocator::GCLoaderAllocators(pLoaderAllocator); - } } + + return true; } // @@ -934,7 +923,7 @@ void DynamicMethodDesc::Destroy() void LCGMethodResolver::Reset() { m_DynamicStringLiterals = NULL; - m_recordCodePointer = NULL; + m_DynamicCodePointers = NULL; m_UsedIndCellList = NULL; m_pJumpStubCache = NULL; m_next = NULL; @@ -946,11 +935,13 @@ void LCGMethodResolver::Reset() // void LCGMethodResolver::RecycleIndCells() { - CONTRACTL { + CONTRACTL + { NOTHROW; GC_TRIGGERS; - MODE_ANY; - } CONTRACTL_END; + MODE_PREEMPTIVE; + } + CONTRACTL_END; // Append the list of indirection cells used by this dynamic method to the free list IndCellList * list = m_UsedIndCellList; @@ -997,15 +988,74 @@ void LCGMethodResolver::RecycleIndCells() } } -void LCGMethodResolver::Destroy() +bool LCGMethodResolver::TryDestroyCodeHeapMemory() { - CONTRACTL { + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_PREEMPTIVE; + PRECONDITION(FinalizerThread::IsCurrentThreadFinalizer()); + } + CONTRACTL_END; + + while (m_DynamicCodePointers != NULL) + { + void* recordCodePointer = m_DynamicCodePointers->m_pEntry; + if (recordCodePointer != NULL) + { + // Remove the unwind information (if applicable) + UnwindInfoTable::UnpublishUnwindInfoForMethod((TADDR)recordCodePointer); + + HostCodeHeap *pHeap = HostCodeHeap::GetCodeHeap((TADDR)recordCodePointer); + LOG((LF_BCL, LL_INFO1000, "Level3 - Resolver {0x%p} - Release reference to heap {%p, vt(0x%zx)} \n", this, pHeap, *(size_t*)pHeap)); + if (!pHeap->GetJitManager()->TryFreeHostCodeHeapMemory(pHeap, recordCodePointer)) + return false; + } + + m_DynamicCodePointers = m_DynamicCodePointers->m_pNext; + } + + if (m_pJumpStubCache != NULL) + { + JumpStubBlockHeader* current = m_pJumpStubCache->m_pBlocks; + while (current) + { + JumpStubBlockHeader* next = current->m_next; + + HostCodeHeap *pHeap = current->GetHostCodeHeap(); + LOG((LF_BCL, LL_INFO1000, "Level3 - Resolver {0x%p} - Release reference to heap {%p, vt(0x%zx)} \n", current, pHeap, *(size_t*)pHeap)); + if (!pHeap->GetJitManager()->TryFreeHostCodeHeapMemory(pHeap, current)) + { + // We were unable to destroy this code heap memory. + // Update the JumpStub cache in place so clean-up can be done later. + m_pJumpStubCache->m_pBlocks = current; + return false; + } + + current = next; + } + m_pJumpStubCache->m_pBlocks = NULL; + + delete m_pJumpStubCache; + m_pJumpStubCache = NULL; + } + + return true; +} + +void LCGMethodResolver::DestroyResolver() +{ + CONTRACTL + { NOTHROW; GC_TRIGGERS; - MODE_ANY; - } CONTRACTL_END; + MODE_PREEMPTIVE; + PRECONDITION(FinalizerThread::IsCurrentThreadFinalizer()); + } + CONTRACTL_END; - LOG((LF_BCL, LL_INFO100, "Level2 - Resolver - Destroying Resolver {0x%p}\n", this)); + LOG((LF_BCL, LL_INFO100, "Level2 - Resolver - Destroying Resolver {%p}\n", this)); if (m_Code) { delete[] m_Code; @@ -1018,14 +1068,16 @@ void LCGMethodResolver::Destroy() m_LocalSig = SigPointer(); } - // Get the global string literal interning map - GlobalStringLiteralMap* pStringLiteralMap = SystemDomain::GetGlobalStringLiteralMapNoCreate(); - // release references to all the string literals used in this Dynamic Method - if (pStringLiteralMap != NULL) + if (m_DynamicStringLiterals != NULL) { + // Get the global string literal interning map + GlobalStringLiteralMap* pStringLiteralMap = SystemDomain::GetGlobalStringLiteralMapNoCreate(); + + // If we have string literals, we should have a string literal map + _ASSERTE(pStringLiteralMap != NULL); + // lock the global string literal interning map - // we cannot use GetGlobalStringLiteralMap() here because it might throw CrstHolder gch(pStringLiteralMap->GetHashTableCrstGlobal()); // Access to m_DynamicStringLiterals doesn't need to be synchronized because @@ -1035,40 +1087,13 @@ void LCGMethodResolver::Destroy() m_DynamicStringLiterals->m_pEntry->Release(); m_DynamicStringLiterals = m_DynamicStringLiterals->m_pNext; } - } - - if (m_recordCodePointer) - { -#if defined(TARGET_AMD64) - // Remove the unwind information (if applicable) - UnwindInfoTable::UnpublishUnwindInfoForMethod((TADDR)m_recordCodePointer); -#endif // defined(TARGET_AMD64) - - HostCodeHeap *pHeap = HostCodeHeap::GetCodeHeap((TADDR)m_recordCodePointer); - LOG((LF_BCL, LL_INFO1000, "Level3 - Resolver {0x%p} - Release reference to heap {%p, vt(0x%x)} \n", this, pHeap, *(size_t*)pHeap)); - pHeap->m_pJitManager->FreeCodeMemory(pHeap, m_recordCodePointer); - m_recordCodePointer = NULL; + m_DynamicStringLiterals = NULL; } - if (m_pJumpStubCache != NULL) - { - JumpStubBlockHeader* current = m_pJumpStubCache->m_pBlocks; - while (current) - { - JumpStubBlockHeader* next = current->m_next; - - HostCodeHeap *pHeap = current->GetHostCodeHeap(); - LOG((LF_BCL, LL_INFO1000, "Level3 - Resolver {0x%p} - Release reference to heap {%p, vt(0x%x)} \n", current, pHeap, *(size_t*)pHeap)); - pHeap->m_pJitManager->FreeCodeMemory(pHeap, current); - - current = next; - } - m_pJumpStubCache->m_pBlocks = NULL; - - delete m_pJumpStubCache; - m_pJumpStubCache = NULL; - } + // Code heap memory should be destroyed before the resolver is destroyed + _ASSERTE(m_DynamicCodePointers == NULL); + _ASSERTE(m_pJumpStubCache == NULL); // Note that we need to do this before m_jitTempData is deleted RecycleIndCells(); @@ -1082,22 +1107,14 @@ void LCGMethodResolver::Destroy() m_managedResolver = NULL; } - m_DynamicMethodTable->LinkMethod(m_pDynamicMethod); + m_pDynamicMethodTable->AddToFreeList(m_pDynamicMethod); } void LCGMethodResolver::FreeCompileTimeState() { - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - //m_jitTempData.Delete(); + LIMITED_METHOD_CONTRACT; } - - void LCGMethodResolver::GetJitContext(SecurityControlFlags * securityControlFlags, TypeHandle *typeOwner) { @@ -1349,7 +1366,6 @@ void LCGMethodResolver::AddToUsedIndCellList(BYTE * indcell) if (InterlockedCompareExchangeT(&m_UsedIndCellList, link, link->pNext) == link->pNext) break; } - } void LCGMethodResolver::ResolveToken(mdToken token, ResolvedToken* resolvedToken) @@ -1510,7 +1526,6 @@ void LCGMethodResolver::GetEHInfo(unsigned EHnumber, CORINFO_EH_CLAUSE* clause) #endif // !DACCESS_COMPILE - // Get the associated managed resolver. This method will be called during a GC so it should not throw, trigger a GC or cause the // object in question to be validated. OBJECTREF LCGMethodResolver::GetManagedResolver() @@ -1519,10 +1534,29 @@ OBJECTREF LCGMethodResolver::GetManagedResolver() return ObjectFromHandle(m_managedResolver); } +void** LCGMethodResolver::AllocateRecordCodePointer() +{ + CONTRACTL + { + THROWS; + GC_NOTRIGGER; + } + CONTRACTL_END; + + DynamicCodePointer* codePointer = (DynamicCodePointer*)m_jitTempData.New(sizeof(DynamicCodePointer)); + *codePointer = {}; + codePointer->m_pNext = m_DynamicCodePointers; + m_DynamicCodePointers = codePointer; + + return &codePointer->m_pEntry; +} // // ChunkAllocator implementation // + +#define CHUNK_SIZE 64 + ChunkAllocator::~ChunkAllocator() { LIMITED_METHOD_CONTRACT; @@ -1618,3 +1652,4 @@ void* ChunkAllocator::New(size_t size) return pNewBlock; } +#undef CHUNK_SIZE diff --git a/src/coreclr/vm/dynamicmethod.h b/src/coreclr/vm/dynamicmethod.h index 9412f80cc5695c..ea004313258819 100644 --- a/src/coreclr/vm/dynamicmethod.h +++ b/src/coreclr/vm/dynamicmethod.h @@ -13,20 +13,16 @@ #include //--------------------------------------------------------------------------------------- -// // This links together a set of news and release in one object. // The idea is to have a predefined size allocated up front and used by different calls to new. -// All the allocation will be released at the same time releaseing an instance of this class +// All the allocation will be released at the same time releasing an instance of this class // Here is how the object is laid out // | ptr_to_next_chunk | size_left_in_chunk | data | ... | data // This is not a particularly efficient allocator but it works well for a small number of allocation // needed while jitting a method // -class ChunkAllocator +class ChunkAllocator final { -private: - #define CHUNK_SIZE 64 - BYTE *m_pData; public: @@ -107,16 +103,19 @@ class DynamicResolver virtual MethodDesc * GetDynamicMethod() = 0; }; // class DynamicResolver -//--------------------------------------------------------------------------------------- -// +// Forward declaration class StringLiteralEntry; -//--------------------------------------------------------------------------------------- -// -struct DynamicStringLiteral +struct DynamicStringLiteral final { - DynamicStringLiteral * m_pNext; - StringLiteralEntry * m_pEntry; + DynamicStringLiteral* m_pNext; + StringLiteralEntry* m_pEntry; +}; + +struct DynamicCodePointer final +{ + DynamicCodePointer* m_pNext; + void* m_pEntry; }; //--------------------------------------------------------------------------------------- @@ -125,20 +124,27 @@ struct DynamicStringLiteral // // a jit resolver for managed dynamic methods // -class LCGMethodResolver : public DynamicResolver +class LCGMethodResolver final : public DynamicResolver { friend class DynamicMethodDesc; friend class DynamicMethodTable; - // review this to see whether the EEJitManageris the only thing to worry about friend class ExecutionManager; friend class EECodeGenManager; friend class EEJitManager; friend class InterpreterJitManager; friend class HostCodeHeap; - friend struct ExecutionManager::JumpStubCache; + + // We clean-up in stages due to how locks are structured. + bool TryDestroyCodeHeapMemory(); + void DestroyResolver(); public: - void Destroy(); + LCGMethodResolver(DynamicMethodDesc* pDynamicMethod, DynamicMethodTable* pDynamicMethodTable) + : m_pDynamicMethod{ pDynamicMethod } + , m_pDynamicMethodTable{ pDynamicMethodTable } + { + LIMITED_METHOD_CONTRACT; + } void FreeCompileTimeState(); void GetJitContext(SecurityControlFlags * securityControlFlags, @@ -160,7 +166,31 @@ class LCGMethodResolver : public DynamicResolver MethodDesc* GetDynamicMethod() { LIMITED_METHOD_CONTRACT; return m_pDynamicMethod; } OBJECTREF GetManagedResolver(); void SetManagedResolver(OBJECTHANDLE obj) { LIMITED_METHOD_CONTRACT; m_managedResolver = obj; } - void * GetRecordCodePointer() { LIMITED_METHOD_CONTRACT; return m_recordCodePointer; } + void** AllocateRecordCodePointer(); + +private: + DynamicMethodDesc* GetNextFreeDynamicMethodDesc() { LIMITED_METHOD_CONTRACT; return m_next; } + void SetNextFreeDynamicMethod(DynamicMethodDesc* next) + { + LIMITED_METHOD_CONTRACT; + // In this path, we permit the case where next is NULL or m_next is not NULL. + // This is because this method is used to set the next pointer when we are + // working with the free list of DynamicMethodDescs and the field may have been + // used to hold the next DynamicMethodDesc for delay clean-up. + m_next = next; + } + +public: + DynamicMethodDesc* GetNextDynamicMethodForDelayCleanup() { LIMITED_METHOD_CONTRACT; return m_next; } + void SetNextDynamicMethodForDelayCleanup(DynamicMethodDesc* next) + { + LIMITED_METHOD_CONTRACT; + _ASSERTE(next != NULL && m_next == NULL); + + // We shouldn't be overriding an existing next pointer. + // See declaration of the field for its uses. + m_next = next; + } STRINGREF GetStringLiteral(mdToken metaTok); STRINGREF * GetOrInternString(STRINGREF *pString); @@ -176,26 +206,31 @@ class LCGMethodResolver : public DynamicResolver struct IndCellList { - BYTE * indcell; - IndCellList * pNext; + BYTE* indcell; + IndCellList* pNext; }; DynamicMethodDesc* m_pDynamicMethod; + DynamicMethodTable* m_pDynamicMethodTable; OBJECTHANDLE m_managedResolver; - BYTE *m_Code; + BYTE* m_Code; DWORD m_CodeSize; SigPointer m_LocalSig; unsigned short m_StackSize; CorInfoOptions m_Options; unsigned m_EHSize; - DynamicMethodTable *m_DynamicMethodTable; - DynamicMethodDesc *m_next; - void *m_recordCodePointer; + + // The next field is currently used for clean-up purposes. + // It holds the next free DynamicMethodDesc that is available for reuse + // or it holds the next DynamicMethodDesc that is scheduled for delayed + // destruction. + DynamicMethodDesc* m_next; ChunkAllocator m_jitMetaHeap; ChunkAllocator m_jitTempData; + DynamicCodePointer* m_DynamicCodePointers; DynamicStringLiteral* m_DynamicStringLiterals; - IndCellList * m_UsedIndCellList; // list to keep track of all the indirection cells used by the jitted code - ExecutionManager::JumpStubCache * m_pJumpStubCache; + IndCellList* m_UsedIndCellList; // list to keep track of all the indirection cells used by the jitted code + ExecutionManager::JumpStubCache* m_pJumpStubCache; #ifdef FEATURE_PGO Volatile m_pgoManager; @@ -242,9 +277,9 @@ class DynamicMethodTable public: void Destroy(); DynamicMethodDesc* GetDynamicMethod(BYTE *psig, DWORD sigSize, PTR_CUTF8 name); - void LinkMethod(DynamicMethodDesc *pMethod); + void AddToFreeList(DynamicMethodDesc *pMethod); -#endif +#endif // !DACCESS_COMPILE #ifdef _DEBUG public: @@ -265,7 +300,7 @@ class DynamicMethodTable // for reclamation of generated code // (Check the base class - CodeHeap in codeman.h - for comments on the functions) // -class HostCodeHeap : CodeHeap +class HostCodeHeap final : public CodeHeap { #ifdef DACCESS_COMPILE friend class ClrDataAccess; @@ -316,6 +351,7 @@ class HostCodeHeap : CodeHeap void AddToFreeList(TrackAllocation *pBlockToInsert, TrackAllocation *pBlockToInsertRW); TrackAllocation* AllocMemory_NoThrow(size_t header, size_t size, DWORD alignment, size_t reserveForJumpStubs); + void FreeMemForCode(void* codeStart); public: // Space for header is reserved immediately before. It is not included in size. @@ -334,11 +370,7 @@ class HostCodeHeap : CodeHeap void DestroyCodeHeap(); -protected: - friend class DynamicMethodDesc; - friend class LCGMethodResolver; - - void FreeMemForCode(void * codeStart); + PTR_EECodeGenManager GetJitManager() { return m_pJitManager; } }; // class HostCodeHeap //--------------------------------------------------------------------------------------- diff --git a/src/coreclr/vm/ecall.cpp b/src/coreclr/vm/ecall.cpp index 84745cde7c341f..fcbdc16d48d5f5 100644 --- a/src/coreclr/vm/ecall.cpp +++ b/src/coreclr/vm/ecall.cpp @@ -96,22 +96,8 @@ void ECall::PopulateManagedStringConstructors() INDEBUG(fInitialized = true); } -static CrstStatic gFCallLock; - #endif // !DACCESS_COMPILE -// To provide a quick check, this is the lowest and highest -// addresses of any FCALL starting address -GVAL_IMPL_INIT(TADDR, gLowestFCall, (TADDR)-1); -GVAL_IMPL(TADDR, gHighestFCall); - -GARY_IMPL(PTR_ECHash, gFCallMethods, FCALL_HASH_SIZE); - -inline unsigned FCallHash(PCODE pTarg) { - LIMITED_METHOD_DAC_CONTRACT; - return pTarg % FCALL_HASH_SIZE; -} - #ifdef DACCESS_COMPILE GARY_IMPL(PCODE, g_FCDynamicallyAssignedImplementations, @@ -303,7 +289,7 @@ static ECFunc* FindECFuncForMethod(MethodDesc* pMD) * Returns 0 if it is an ECALL, * Otherwise returns the native entry point (FCALL) */ -PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /*=NULL*/) +PCODE ECall::GetFCallImpl(MethodDesc * pMD, bool throwForInvalidFCall) { CONTRACTL { @@ -322,9 +308,6 @@ PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /* // if (pMT->IsDelegate()) { - if (pfSharedOrDynamicFCallImpl) - *pfSharedOrDynamicFCallImpl = TRUE; - _ASSERTE(pMD->IsCtor()); // We need to set up the ECFunc properly. We don't want to use the pMD passed in, @@ -337,9 +320,6 @@ PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /* // COM imported classes have special constructors if (pMT->IsComObjectType() && pMT != g_pBaseCOMObject) { - if (pfSharedOrDynamicFCallImpl) - *pfSharedOrDynamicFCallImpl = TRUE; - // This has to be tlbimp constructor _ASSERTE(pMD->IsCtor()); @@ -350,11 +330,19 @@ PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /* // This code path is taken when a class marked with ComImport is being created. // If we get here and COM interop isn't suppported, throw. if (pMT->IsComObjectType()) - COMPlusThrow(kPlatformNotSupportedException, IDS_EE_ERROR_COM); + { + if (throwForInvalidFCall) + COMPlusThrow(kPlatformNotSupportedException, IDS_EE_ERROR_COM); + return (PCODE)NULL; + } #endif // FEATURE_COMINTEROP if (!pMD->GetModule()->IsSystem()) - COMPlusThrow(kSecurityException, BFA_ECALLS_MUST_BE_IN_SYS_MOD); + { + if (throwForInvalidFCall) + COMPlusThrow(kSecurityException, BFA_ECALLS_MUST_BE_IN_SYS_MOD); + return (PCODE)NULL; + } ECFunc* ret = FindECFuncForMethod(pMD); @@ -390,74 +378,15 @@ PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /* int iDynamicID = ret->DynamicID(); if (iDynamicID != InvalidDynamicFCallId) { - if (pfSharedOrDynamicFCallImpl) - *pfSharedOrDynamicFCallImpl = TRUE; - pImplementation = g_FCDynamicallyAssignedImplementations[iDynamicID]; _ASSERTE(pImplementation != (PCODE)NULL); return pImplementation; } - - // Insert the implementation into hash table if it is not there already. - - CrstHolder holder(&gFCallLock); - - MethodDesc * pMDinTable = ECall::MapTargetBackToMethod(pImplementation, &pImplementation); - - if (pMDinTable != NULL) - { - if (pMDinTable != pMD) - { - // The fcall entrypoints has to be at unique addresses. If you get failure here, use the following steps - // to fix it: - // 1. Consider merging the offending fcalls into one fcall. Do they really do different things? - // 2. If it does not make sense to merge the offending fcalls into one, - // add FCUnique(); to one of the offending fcalls. - - _ASSERTE(!"Duplicate pImplementation entries found in reverse fcall table"); - ThrowHR(E_FAIL); - } - } - else - { - ECHash * pEntry = (ECHash *)(PVOID)SystemDomain::GetGlobalLoaderAllocator()->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(ECHash))); - - pEntry->m_pImplementation = pImplementation; - pEntry->m_pMD = pMD; - - if(gLowestFCall > pImplementation) - gLowestFCall = pImplementation; - if(gHighestFCall < pImplementation) - gHighestFCall = pImplementation; - - // add to hash table - ECHash** spot = &gFCallMethods[FCallHash(pImplementation)]; - for(;;) { - if (*spot == 0) { // found end of list - *spot = pEntry; - break; - } - spot = &(*spot)->m_pNext; - } - } - - if (pfSharedOrDynamicFCallImpl) - *pfSharedOrDynamicFCallImpl = FALSE; - _ASSERTE(pImplementation != (PCODE)NULL); return pImplementation; } -BOOL ECall::IsSharedFCallImpl(PCODE pImpl) -{ - LIMITED_METHOD_CONTRACT; - - PCODE pNativeCode = pImpl; - - return (pNativeCode == GetEEFuncEntryPoint(FCComCtor)); -} - BOOL ECall::CheckUnusedECalls(SetSHash& usedIDs) { STANDARD_VM_CONTRACT; @@ -508,179 +437,7 @@ BOOL ECall::CheckUnusedECalls(SetSHash& usedIDs) FCIMPL1(VOID, FCComCtor, LPVOID pV) { FCALL_CONTRACT; - - FCUnique(0x34); } FCIMPLEND - - -/* static */ -void ECall::Init() -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - gFCallLock.Init(CrstFCall); -} #endif // !DACCESS_COMPILE - -MethodDesc* ECall::MapTargetBackToMethod(PCODE pTarg, PCODE * ppAdjustedEntryPoint /*=NULL*/) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - SUPPORTS_DAC; - } - CONTRACTL_END; - - // Searching all of the entries is expensive - // and we are often called with pTarg == NULL so - // check for this value and early exit. - - if (!pTarg) - return NULL; - - // Could this possibily be an FCall? - if ((pTarg < gLowestFCall) || (pTarg > gHighestFCall)) - return NULL; - - ECHash * pECHash = gFCallMethods[FCallHash(pTarg)]; - while (pECHash != NULL) - { - if (pECHash->m_pImplementation == pTarg) - { - return pECHash->m_pMD; - } - pECHash = pECHash->m_pNext; - } - return NULL; -} - -#ifndef DACCESS_COMPILE - -#ifdef _DEBUG - -void FCallAssert(void*& cache, void* target) -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_DEBUG_ONLY; - - if (cache != 0) - { - return; - } - - // - // Special case fcalls with 1:N mapping between implementation and methoddesc - // - if (ECall::IsSharedFCallImpl((PCODE)target)) - { - cache = (void*)1; - return; - } - - MethodDesc* pMD = ECall::MapTargetBackToMethod((PCODE)target); - if (pMD != 0) - { - return; - } - - // Slow but only for debugging. This is needed because in some places - // we call FCALLs directly from EE code. - - unsigned num = c_nECClasses; - for (unsigned i=0; i < num; i++) - { - for (ECFunc* ptr = (ECFunc*)c_rgECClasses[i].m_pECFunc; !ptr->IsEndOfArray(); ptr = ptr->NextInArray()) - { - if (ptr->m_pImplementation == target) - { - cache = target; - return; - } - } - } - - // Now check the dynamically assigned table too. - for (unsigned i=0; i(ecHash), sizeof(ECHash))) - break; - ecHash = ecHash->m_pNext; - -#if defined (_DEBUG) - // Test hook: when testing on debug builds, we want an easy way to test that the while - // correctly terminates in the face of ridiculous stuff from the target. - if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DumpGeneration_IntentionallyCorruptDataFromTarget) == 1) - { - // Force us to struggle on with something bad. - if (!ecHash) - { - ecHash = (ECHash *)(((unsigned char *)&gFCallMethods[i])+1); - } - } -#endif // defined (_DEBUG) - - } - } -} - -#endif // DACCESS_COMPILE diff --git a/src/coreclr/vm/ecall.h b/src/coreclr/vm/ecall.h index a07143958f2e0e..4fb173396dbca5 100644 --- a/src/coreclr/vm/ecall.h +++ b/src/coreclr/vm/ecall.h @@ -15,25 +15,6 @@ class MethodDesc; -// CoreCLR defines fewer FCalls so make the hashtable even smaller. -#define FCALL_HASH_SIZE 127 - -typedef DPTR(struct ECHash) PTR_ECHash; - -struct ECHash -{ - PTR_ECHash m_pNext; - PCODE m_pImplementation; - PTR_MethodDesc m_pMD; // for reverse mapping -}; - -#ifdef DACCESS_COMPILE -GVAL_DECL(TADDR, gLowestFCall); -GVAL_DECL(TADDR, gHighestFCall); -#endif - -GARY_DECL(PTR_ECHash, gFCallMethods, FCALL_HASH_SIZE); - enum { FCFuncFlag_EndOfArray = 0x01, FCFuncFlag_HasSignature = 0x02, @@ -75,31 +56,15 @@ struct ECClass class ECall { public: - //--------------------------------------------------------- - // One-time init - //--------------------------------------------------------- - static void Init(); - - static PCODE GetFCallImpl(MethodDesc* pMD, BOOL * pfSharedOrDynamicFCallImpl = NULL); - static MethodDesc* MapTargetBackToMethod(PCODE pTarg, PCODE * ppAdjustedEntryPoint = NULL); + static PCODE GetFCallImpl(MethodDesc* pMD, bool throwForInvalidFCall = true); static DWORD GetIDForMethod(MethodDesc *pMD); - // Some fcalls (delegate ctors and tlbimpl ctors) shared one implementation. - // We should never patch vtable for these since they have 1:N mapping between - // MethodDesc and the actual implementation - static BOOL IsSharedFCallImpl(PCODE pImpl); - static BOOL CheckUnusedECalls(SetSHash& usedIDs); static void DynamicallyAssignFCallImpl(PCODE impl, DWORD index); static void PopulateManagedStringConstructors(); -#ifdef DACCESS_COMPILE - // Enumerates all gFCallMethods for minidumps. - static void EnumFCallMethods(); -#endif // DACCESS_COMPILE - #define _DYNAMICALLY_ASSIGNED_FCALLS_BASE() \ DYNAMICALLY_ASSIGNED_FCALL_IMPL(FastAllocateString, RhpNewVariableSizeObject) \ DYNAMICALLY_ASSIGNED_FCALL_IMPL(CtorCharArrayManaged, NULL) \ diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index c901a56b50d96a..502586170e843f 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -334,7 +334,7 @@ FCFuncStart(gRuntimeHelpers) FCFuncElement("TryGetHashCode", ObjectNative::TryGetHashCode) FCFuncElement("ContentEquals", ObjectNative::ContentEquals) FCFuncElement("TryEnsureSufficientExecutionStack", ReflectionInvocation::TryEnsureSufficientExecutionStack) - FCFuncElement("AllocTailCallArgBufferWorker", TailCallHelp::AllocTailCallArgBufferWorker) + FCFuncElement("GetTailCallArgBuffer", TailCallHelp::GetTailCallArgBuffer) FCFuncElement("GetTailCallInfo", TailCallHelp::GetTailCallInfo) FCFuncEnd() @@ -356,8 +356,6 @@ FCFuncStart(gStubHelperFuncs) #endif // FEATURE_COMINTEROP FCFuncElement("CalcVaListSize", StubHelpers::CalcVaListSize) FCFuncElement("LogPinnedArgument", StubHelpers::LogPinnedArgument) - FCFuncElement("GetStubContext", StubHelpers::GetStubContext) - FCFuncElement("NextCallReturnAddress", StubHelpers::NextCallReturnAddress) FCFuncEnd() FCFuncStart(gGCHandleFuncs) diff --git a/src/coreclr/vm/eeconfig.cpp b/src/coreclr/vm/eeconfig.cpp index b3233af059de62..d0679d620bd1c8 100644 --- a/src/coreclr/vm/eeconfig.cpp +++ b/src/coreclr/vm/eeconfig.cpp @@ -237,6 +237,8 @@ HRESULT EEConfig::Init() fGDBJitEmitDebugFrame = false; #endif + runtimeAsync = false; + return S_OK; } @@ -763,6 +765,8 @@ HRESULT EEConfig::sync() fUseCachedInterfaceDispatch = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_UseCachedInterfaceDispatch) != 0; #endif // defined(FEATURE_CACHED_INTERFACE_DISPATCH) && defined(FEATURE_VIRTUAL_STUB_DISPATCH) + runtimeAsync = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_RuntimeAsync) != 0; + return hr; } diff --git a/src/coreclr/vm/eeconfig.h b/src/coreclr/vm/eeconfig.h index e0110069258512..2300be8fba075e 100644 --- a/src/coreclr/vm/eeconfig.h +++ b/src/coreclr/vm/eeconfig.h @@ -439,6 +439,8 @@ class EEConfig #endif + bool RuntimeAsync() const { LIMITED_METHOD_CONTRACT; return runtimeAsync; } + private: //---------------------------------------------------------------- bool fInited; // have we synced to the registry at least once? @@ -634,6 +636,8 @@ class EEConfig bool fUseCachedInterfaceDispatch; #endif // defined(FEATURE_CACHED_INTERFACE_DISPATCH) && defined(FEATURE_VIRTUAL_STUB_DISPATCH) + bool runtimeAsync; // True if the runtime supports async methods + public: enum BitForMask { diff --git a/src/coreclr/vm/eedbginterface.h b/src/coreclr/vm/eedbginterface.h index 048c573c3ba936..e6cae0fc3ff698 100644 --- a/src/coreclr/vm/eedbginterface.h +++ b/src/coreclr/vm/eedbginterface.h @@ -36,9 +36,6 @@ class Frame; // between the EE and the Debugger. // // -typedef BOOL (*HashMapEnumCallback)(HashMap* h, - void* pData, - ULONG value); typedef enum AttachAppDomainEventsEnum { @@ -267,8 +264,6 @@ class EEDebugInterface virtual COR_ILMETHOD* MethodDescGetILHeader(MethodDesc *pFD) = 0; - virtual ULONG MethodDescGetRVA(MethodDesc *pFD) = 0; - virtual void MarkDebuggerAttached(void) = 0; virtual void MarkDebuggerUnattached(void) = 0; diff --git a/src/coreclr/vm/eedbginterfaceimpl.cpp b/src/coreclr/vm/eedbginterfaceimpl.cpp index fda4f6795e6a4b..f810dbdab7960e 100644 --- a/src/coreclr/vm/eedbginterfaceimpl.cpp +++ b/src/coreclr/vm/eedbginterfaceimpl.cpp @@ -173,11 +173,7 @@ void* EEDbgInterfaceImpl::GetObjectFromHandle(OBJECTHANDLE handle) } CONTRACTL_END; - void *v; - - *((OBJECTREF *)&v) = *(OBJECTREF *)handle; - - return v; + return OBJECTREFToObject(ObjectFromHandle(handle)); } OBJECTHANDLE EEDbgInterfaceImpl::GetHandleFromObject(void *obj, @@ -721,19 +717,6 @@ COR_ILMETHOD* EEDbgInterfaceImpl::MethodDescGetILHeader(MethodDesc *pFD) RETURN NULL; } -ULONG EEDbgInterfaceImpl::MethodDescGetRVA(MethodDesc *pFD) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - PRECONDITION(CheckPointer(pFD)); - } - CONTRACTL_END; - - return pFD->GetRVA(); -} - MethodDesc *EEDbgInterfaceImpl::FindLoadedMethodRefOrDef(Module* pModule, mdToken memberRef) { diff --git a/src/coreclr/vm/eedbginterfaceimpl.h b/src/coreclr/vm/eedbginterfaceimpl.h index 4f45e0df1044db..c2d62dad7674b8 100644 --- a/src/coreclr/vm/eedbginterfaceimpl.h +++ b/src/coreclr/vm/eedbginterfaceimpl.h @@ -156,8 +156,6 @@ class EEDbgInterfaceImpl : public EEDebugInterface COR_ILMETHOD* MethodDescGetILHeader(MethodDesc *pFD); - ULONG MethodDescGetRVA(MethodDesc *pFD); - MethodDesc *FindLoadedMethodRefOrDef(Module* pModule, mdToken memberRef); diff --git a/src/coreclr/vm/eetwain.cpp b/src/coreclr/vm/eetwain.cpp index 39844aa3171080..1e9f14c10e6f32 100644 --- a/src/coreclr/vm/eetwain.cpp +++ b/src/coreclr/vm/eetwain.cpp @@ -1120,6 +1120,17 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pRD, return true; } +void EECodeManager::UnwindStackFrame(T_CONTEXT *pContext) +{ + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + } CONTRACTL_END; + + EECodeInfo codeInfo(dac_cast(GetIP(pContext))); + Thread::VirtualUnwindCallFrame(pContext, NULL, &codeInfo); +} + /*****************************************************************************/ #endif // FEATURE_EH_FUNCLETS @@ -2459,6 +2470,20 @@ bool InterpreterCodeManager::UnwindStackFrame(PREGDISPLAY pRD, return true; } +void InterpreterCodeManager::UnwindStackFrame(T_CONTEXT *pContext) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + SUPPORTS_DAC; + } + CONTRACTL_END; + + _ASSERTE(pContext != NULL); + VirtualUnwindInterpreterCallFrame(GetSP(pContext), pContext); +} + void InterpreterCodeManager::EnsureCallerContextIsValid(PREGDISPLAY pRD, EECodeInfo * pCodeInfo /*= NULL*/, unsigned flags /*= 0*/) { CONTRACTL diff --git a/src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h b/src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h index a9886849c7da15..5ac80179fc5e0a 100644 --- a/src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h +++ b/src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h @@ -229,6 +229,15 @@ ep_rt_atomic_dec_int64_t (volatile int64_t *value) return static_cast(InterlockedDecrement64 ((volatile LONG64 *)(value))); } +static +inline +int64_t +ep_rt_atomic_compare_exchange_int64_t (volatile int64_t *target, int64_t expected, int64_t value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(InterlockedCompareExchangeT (target, value, expected)); +} + static inline size_t diff --git a/src/coreclr/vm/eventtrace.cpp b/src/coreclr/vm/eventtrace.cpp index 1d27b777c73fa4..2ab23dfad1bbbf 100644 --- a/src/coreclr/vm/eventtrace.cpp +++ b/src/coreclr/vm/eventtrace.cpp @@ -43,6 +43,7 @@ #endif // FEATURE_NATIVEAOT #include "eventtracepriv.h" +#include "debugdebugger.h" #ifndef HOST_UNIX DOTNET_TRACE_CONTEXT MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context = { &MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_EVENTPIPE_Context }; @@ -2682,29 +2683,39 @@ extern "C" ClrFlsThreadTypeSwitch etwRundownThreadHolder(ThreadType_ETWRundownThread); PMCGEN_TRACE_CONTEXT context = (PMCGEN_TRACE_CONTEXT)CallbackContext; - BOOLEAN bIsPublicTraceHandle = (context->RegistrationHandle==Microsoft_Windows_DotNETRuntimeHandle); + BOOLEAN bIsPublicTraceHandle = (context == MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context.EtwProvider); - BOOLEAN bIsPrivateTraceHandle = (context->RegistrationHandle==Microsoft_Windows_DotNETRuntimePrivateHandle); + BOOLEAN bIsPrivateTraceHandle = (context == MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context.EtwProvider); - BOOLEAN bIsRundownTraceHandle = (context->RegistrationHandle==Microsoft_Windows_DotNETRuntimeRundownHandle); + BOOLEAN bIsRundownTraceHandle = (context == MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EtwProvider); + + BOOLEAN bIsStressTraceHandle = (context == MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_DOTNET_Context.EtwProvider); // EventPipeEtwCallback contains some GC eventing functionality shared between EventPipe and ETW. // Eventually, we'll want to merge these two codepaths whenever we can. CallbackProviderIndex providerIndex = DotNETRuntime; DOTNET_TRACE_CONTEXT providerContext = MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context; - if (context->RegistrationHandle == Microsoft_Windows_DotNETRuntimeHandle) { + if (bIsPublicTraceHandle) + { providerIndex = DotNETRuntime; providerContext = MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context; - } else if (context->RegistrationHandle == Microsoft_Windows_DotNETRuntimeRundownHandle) { + } + else if (bIsRundownTraceHandle) + { providerIndex = DotNETRuntimeRundown; providerContext = MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context; - } else if (context->RegistrationHandle == Microsoft_Windows_DotNETRuntimeStressHandle) { + } + else if (bIsStressTraceHandle) + { providerIndex = DotNETRuntimeStress; providerContext = MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_DOTNET_Context; - } else if (context->RegistrationHandle == Microsoft_Windows_DotNETRuntimePrivateHandle) { + } + else if (bIsPrivateTraceHandle) + { providerIndex = DotNETRuntimePrivate; providerContext = MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context; - } else { + } + else { assert(!"unknown registration handle"); return; } @@ -2729,15 +2740,6 @@ extern "C" } } -#ifdef TARGET_AMD64 - // We only do this on amd64 (NOT ARM, because ARM uses frame based stack crawling) - // If we have turned on the JIT keyword to the INFORMATION setting (needed to get JIT names) then - // we assume that we also want good stack traces so we need to publish unwind information so - // ETW can get at it - if(bIsPublicTraceHandle && ETW_CATEGORY_ENABLED(providerContext, TRACE_LEVEL_INFORMATION, CLR_RUNDOWNJIT_KEYWORD)) - UnwindInfoTable::PublishUnwindInfo(g_fEEStarted != FALSE); -#endif - if(g_fEEStarted && !g_fEEShutDown && bIsRundownTraceHandle) { // Start and End Method/Module Rundowns @@ -3540,14 +3542,6 @@ VOID ETW::MethodLog::MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrC TRACE_LEVEL_INFORMATION, CLR_JITTEDMETHODILTONATIVEMAP_KEYWORD)) { - // The call to SendMethodILToNativeMapEvent assumes that the debugger's lazy - // data has already been initialized. - - // g_pDebugInterface is initialized on startup on desktop CLR, regardless of whether a debugger - // or profiler is loaded. So it should always be available. - _ASSERTE(g_pDebugInterface != NULL); - g_pDebugInterface->InitializeLazyDataIfNecessary(); - ETW::MethodLog::SendMethodILToNativeMapEvent(pMethodDesc, ETW::EnumerationLog::EnumerationStructs::JitMethodILToNativeMap, pNativeCodeStartAddress, @@ -3557,9 +3551,6 @@ VOID ETW::MethodLog::MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrC if (ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context, JittedMethodRichDebugInfo)) { - _ASSERTE(g_pDebugInterface != NULL); - g_pDebugInterface->InitializeLazyDataIfNecessary(); - ETW::MethodLog::SendMethodRichDebugInfo(pMethodDesc, pNativeCodeStartAddress, pConfig->GetCodeVersion().GetVersionId(), pConfig->GetCodeVersion().GetILCodeVersionId(), NULL); } @@ -3620,7 +3611,7 @@ VOID ETW::MethodLog::DynamicMethodDestroyed(MethodDesc *pMethodDesc) { CONTRACTL { NOTHROW; - GC_TRIGGERS; + GC_NOTRIGGER; } CONTRACTL_END; EX_TRY @@ -4263,15 +4254,16 @@ VOID ETW::MethodLog::SendMethodDetailsEvent(MethodDesc *pMethodDesc) GC_NOTRIGGER; } CONTRACTL_END; + // There are not relevant method details for dynamic methods. + if (pMethodDesc->IsDynamicMethod()) + return; + EX_TRY { if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context, TRACE_LEVEL_INFORMATION, CLR_METHODDIAGNOSTIC_KEYWORD)) { - if (pMethodDesc->IsDynamicMethod()) - goto done; - Instantiation inst = pMethodDesc->GetMethodInstantiation(); if (inst.GetNumArgs() > 1024) // ETW has a limit for maximum event size. Do not log overly large method type argument sets @@ -4285,19 +4277,10 @@ VOID ETW::MethodLog::SendMethodDetailsEvent(MethodDesc *pMethodDesc) StackSArray rgTypeParameters; DWORD cParams = inst.GetNumArgs(); - - BOOL fSucceeded = FALSE; - EX_TRY + for (COUNT_T i = 0; i < cParams; i++) { - for (COUNT_T i = 0; i < cParams; i++) - { - rgTypeParameters.Append((ULONGLONG)inst[i].AsPtr()); - } - fSucceeded = TRUE; + rgTypeParameters.Append((ULONGLONG)inst[i].AsPtr()); } - EX_SWALLOW_NONTERMINAL - if (!fSucceeded) - goto done; // Log any referenced parameter types for (COUNT_T i=0; i < cParams; i++) @@ -4416,6 +4399,39 @@ VOID ETW::MethodLog::SendMethodJitStartEvent( } } +TADDR MethodAndStartAddressToEECodeInfoPointer(MethodDesc *pMethodDesc, PCODE pNativeCodeStartAddress) +{ + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + PRECONDITION(CheckPointer(pMethodDesc)); + } CONTRACTL_END; + + // MethodDesc ==> Code Address ==>JitManager + TADDR start = PCODEToPINSTR(pNativeCodeStartAddress ? pNativeCodeStartAddress : pMethodDesc->GetNativeCode()); + if(start == 0) { + // this method hasn't been jitted + return 0; + } + +#ifdef FEATURE_INTERPRETER + RangeSection * pRS = ExecutionManager::FindCodeRange(PINSTRToPCODE(start), ExecutionManager::GetScanFlags()); + if (pRS != NULL && pRS->_flags & RangeSection::RANGE_SECTION_RANGELIST) + { + if (pRS->_pRangeList->GetCodeBlockKind() == STUB_CODE_BLOCK_STUBPRECODE) + { + if (((StubPrecode*)start)->GetType() == PRECODE_INTERPRETER) + { + start = ((InterpreterPrecode*)start)->GetData()->ByteCodeAddr; + } + } + } +#endif // FEATURE_INTERPRETER + + return start; +} + /****************************************************************************/ /* This routine is used to send a method load/unload or rundown event */ /****************************************************************************/ @@ -4500,27 +4516,12 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio ulColdMethodFlags = ulMethodFlags | ETW::MethodLog::MethodStructs::ColdSection; // Method Extent (bits 28, 29, 30, 31) ulMethodFlags = ulMethodFlags | ETW::MethodLog::MethodStructs::HotSection; // Method Extent (bits 28, 29, 30, 31) - // MethodDesc ==> Code Address ==>JitManager - TADDR start = PCODEToPINSTR(pNativeCodeStartAddress ? pNativeCodeStartAddress : pMethodDesc->GetNativeCode()); + TADDR start = MethodAndStartAddressToEECodeInfoPointer(pMethodDesc, pNativeCodeStartAddress); if(start == 0) { // this method hasn't been jitted return; } -#ifdef FEATURE_INTERPRETER - RangeSection * pRS = ExecutionManager::FindCodeRange(PINSTRToPCODE(start), ExecutionManager::GetScanFlags()); - if (pRS != NULL && pRS->_flags & RangeSection::RANGE_SECTION_RANGELIST) - { - if (pRS->_pRangeList->GetCodeBlockKind() == STUB_CODE_BLOCK_STUBPRECODE) - { - if (((StubPrecode*)start)->GetType() == PRECODE_INTERPRETER) - { - start = ((InterpreterPrecode*)start)->GetData()->ByteCodeAddr; - } - } - } -#endif // FEATURE_INTERPRETER - // EECodeInfo is technically initialized by a "PCODE", but it can also be initialized // by a TADDR (i.e., w/out thumb bit set on ARM) EECodeInfo codeInfo(start); @@ -4732,25 +4733,34 @@ VOID ETW::MethodLog::SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWOR if (pMethodDesc->HasClassOrMethodInstantiation() && pMethodDesc->IsTypicalMethodDefinition()) return; - // g_pDebugInterface is initialized on startup on desktop CLR, regardless of whether a debugger - // or profiler is loaded. So it should always be available. - _ASSERTE(g_pDebugInterface != NULL); - ULONGLONG ullMethodIdentifier = (ULONGLONG)pMethodDesc; - USHORT cMap; - NewArrayHolder rguiILOffset; - NewArrayHolder rguiNativeOffset; - - HRESULT hr = g_pDebugInterface->GetILToNativeMappingIntoArrays( - pMethodDesc, - pNativeCodeStartAddress, - kMapEntriesMax, - &cMap, - &rguiILOffset, - &rguiNativeOffset); - if (FAILED(hr)) + if (pMethodDesc->IsWrapperStub() || pMethodDesc->IsDynamicMethod()) + { + return; + } + + TADDR start = MethodAndStartAddressToEECodeInfoPointer(pMethodDesc, pNativeCodeStartAddress); + if(start == 0) { + // this method hasn't been jitted return; + } + + // EECodeInfo is technically initialized by a "PCODE", but it can also be initialized + // by a TADDR (i.e., w/out thumb bit set on ARM) + EECodeInfo codeInfo(start); + TADDR startAddress = codeInfo.GetStartAddress(); + DebugInfoRequest request; + request.InitFromStartingAddr(codeInfo.GetMethodDesc(), startAddress); + + ILToNativeMapArrays context(kMapEntriesMax); + codeInfo.GetJitManager()->WalkILOffsets(request, BoundsType::Uninstrumented, &context, ComputeILOffsetArrays); + + uint32_t cMap; + uint32_t* rguiILOffset; + uint32_t* rguiNativeOffset; + + context.GetArrays(&cMap, &rguiNativeOffset, &rguiILOffset); // Runtime provider. // @@ -4763,7 +4773,7 @@ VOID ETW::MethodLog::SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWOR nativeCodeId, 0, // Extent: This event is only sent for JITted (not NGENd) methods, and // currently there is only one extent (hot) for JITted methods. - cMap, + (USHORT)cMap, rguiILOffset, rguiNativeOffset, GetClrInstanceId(), @@ -4779,9 +4789,9 @@ VOID ETW::MethodLog::SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWOR // // (for an explanation of the parameters see the FireEtwMethodILToNativeMap call above) if ((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::MethodDCStartILToNativeMap) != 0) - FireEtwMethodDCStartILToNativeMap_V1(ullMethodIdentifier, nativeCodeId, 0, cMap, rguiILOffset, rguiNativeOffset, GetClrInstanceId(), ilCodeId); + FireEtwMethodDCStartILToNativeMap_V1(ullMethodIdentifier, nativeCodeId, 0, (USHORT)cMap, rguiILOffset, rguiNativeOffset, GetClrInstanceId(), ilCodeId); if ((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::MethodDCEndILToNativeMap) != 0) - FireEtwMethodDCEndILToNativeMap_V1(ullMethodIdentifier, nativeCodeId, 0, cMap, rguiILOffset, rguiNativeOffset, GetClrInstanceId(), ilCodeId); + FireEtwMethodDCEndILToNativeMap_V1(ullMethodIdentifier, nativeCodeId, 0, (USHORT)cMap, rguiILOffset, rguiNativeOffset, GetClrInstanceId(), ilCodeId); } template @@ -4978,7 +4988,7 @@ VOID ETW::MethodLog::SendEventsForJitMethodsHelper(LoaderAllocator *pLoaderAlloc MethodDescSet sentMethodDetailsSet; MethodDescSet* pSentMethodDetailsSet = fSendRichDebugInfoEvent ? &sentMethodDetailsSet : NULL; - EEJitManager::CodeHeapIterator heapIterator(pLoaderAllocatorFilter); + CodeHeapIterator heapIterator = ExecutionManager::GetEEJitManager()->GetCodeHeapIterator(pLoaderAllocatorFilter); while (heapIterator.Next()) { MethodDesc * pMD = heapIterator.GetMethod(); @@ -5022,7 +5032,7 @@ VOID ETW::MethodLog::SendEventsForJitMethodsHelper(LoaderAllocator *pLoaderAlloc } } else -#endif +#endif // FEATURE_CODE_VERSIONING if (codeStart != pMD->GetNativeCode()) { continue; @@ -5114,24 +5124,12 @@ VOID ETW::MethodLog::SendEventsForJitMethods(BOOL getCodeVersionIds, LoaderAlloc BOOL fSendRichDebugInfoEvent = (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JittedMethodRichDebugInfo) != 0; - if (fSendILToNativeMapEvent || fSendRichDebugInfoEvent) - { - // The call to SendMethodILToNativeMapEvent assumes that the debugger's lazy - // data has already been initialized, to ensure we don't try to do the lazy init - // while under the implicit, notrigger CodeHeapIterator lock below. - - // g_pDebugInterface is initialized on startup on desktop CLR, regardless of whether a debugger - // or profiler is loaded. So it should always be available. - _ASSERTE(g_pDebugInterface != NULL); - g_pDebugInterface->InitializeLazyDataIfNecessary(); - } - // #TableLockHolder: // // A word about ReJitManager::TableLockHolder... As we enumerate through the functions, // we may need to grab their code IDs. The ReJitManager grabs its table Crst in order to // fetch these. However, several other kinds of locks are being taken during this - // enumeration, such as the SystemDomain lock and the EEJitManager::CodeHeapIterator's + // enumeration, such as the SystemDomain lock and the CodeHeapIterator's // lock. In order to avoid lock-leveling issues, we grab the appropriate ReJitManager // table locks after SystemDomain and before CodeHeapIterator. In particular, we need to // grab the SharedDomain's ReJitManager table lock as well as the specific AppDomain's diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index 2fe3fba668d368..08620b3c715375 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -946,8 +946,8 @@ bool EHRangeTreeNode::TryContains(EHRangeTreeNode* pNode) { // Iterate all the contained clauses, and for the ones which are contained in the try region, // ask if the requested range is contained by it. - USHORT i = 0; - USHORT numNodes = m_containees.Count(); + INT32 i = 0; + INT32 numNodes = m_containees.Count(); EHRangeTreeNode** ppNodes = NULL; for (i = 0, ppNodes = m_containees.Table(); i < numNodes; i++, ppNodes++) { @@ -1023,8 +1023,8 @@ bool EHRangeTreeNode::HandlerContains(EHRangeTreeNode* pNode) { // Iterate all the contained clauses, and for the ones which are contained in the try region, // ask if the requested range is contained by it. - USHORT i = 0; - USHORT numNodes = m_containees.Count(); + INT32 i = 0; + INT32 numNodes = m_containees.Count(); EHRangeTreeNode** ppNodes = NULL; for (i = 0, ppNodes = m_containees.Table(); i < numNodes; i++, ppNodes++) { @@ -1099,8 +1099,8 @@ bool EHRangeTreeNode::FilterContains(EHRangeTreeNode* pNode) { // Iterate all the contained clauses, and for the ones which are contained in the try region, // ask if the requested range is contained by it. - USHORT i = 0; - USHORT numNodes = m_containees.Count(); + INT32 i = 0; + INT32 numNodes = m_containees.Count(); EHRangeTreeNode** ppNodes = NULL; for (i = 0, ppNodes = m_containees.Table(); i < numNodes; i++, ppNodes++) { @@ -1416,10 +1416,10 @@ EHRangeTreeNode *EHRangeTree::FindNextMostSpecificContainer(EHRangeTreeNode *pNo // keep a reasonable default around. EHRangeTreeNode *pNodeCandidate = pNodeSearch; - USHORT cSubRanges = pNodeSearch->m_containees.Count(); + INT32 cSubRanges = pNodeSearch->m_containees.Count(); EHRangeTreeNode **ppNodeCur = pNodeSearch->m_containees.Table(); - for (int i = 0; i < cSubRanges; i++, ppNodeCur++) + for (INT32 i = 0; i < cSubRanges; i++, ppNodeCur++) { if ((*ppNodeCur)->Contains(addr) && pNodeCandidate->Contains((*ppNodeCur))) @@ -3223,21 +3223,6 @@ BOOL IsExceptionOfType(RuntimeExceptionKind reKind, OBJECTREF *pThrowable) return CoreLibBinder::IsException(pThrowableMT, reKind); } -BOOL IsAsyncThreadException(OBJECTREF *pThrowable) { - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_MODE_COOPERATIVE; - STATIC_CONTRACT_FORBID_FAULT; - - if ( (GetThreadNULLOk() && GetThread()->IsRudeAbort() && GetThread()->IsRudeAbortInitiated()) - ||IsExceptionOfType(kThreadAbortException, pThrowable) - ||IsExceptionOfType(kThreadInterruptedException, pThrowable)) { - return TRUE; - } else { - return FALSE; - } -} - BOOL IsUncatchable(OBJECTREF *pThrowable) { CONTRACTL { @@ -3567,8 +3552,14 @@ LONG WatsonLastChance( // EXCEPTION_CONTINUE_SEARCH, _CONTINUE_ #ifdef HOST_WINDOWS CreateCrashDumpIfEnabled(fSOException); #endif - RaiseFailFastException(pExceptionInfo == NULL ? NULL : pExceptionInfo->ExceptionRecord, - pExceptionInfo == NULL ? NULL : pExceptionInfo->ContextRecord, + // RaiseFailFastException validates that the context matches a valid return address on the stack as part of CET. + // If the return address is not valid, it rejects the context, flags it as a potential attack and asserts in + // checked builds of Windows OS. + // Avoid reporting thread context captured by EEPolicy::HandleFatalError since it has IP that does not + // match a valid return address on the stack. + bool fAvoidReportContextToRaiseFailFast = tore.IsFatalError(); + RaiseFailFastException(pExceptionInfo == NULL ? NULL : pExceptionInfo->ExceptionRecord, + pExceptionInfo == NULL || fAvoidReportContextToRaiseFailFast ? NULL : pExceptionInfo->ContextRecord, 0); STRESS_LOG0(LF_CORDB, LL_INFO10, "D::RFFE: Return from RaiseFailFastException\n"); } @@ -4954,7 +4945,7 @@ DefaultCatchHandler(PEXCEPTION_POINTERS pExceptionPointers, IsOutOfMemory) { // We have to be very careful. If we walk off the end of the stack, the process will just - // die. e.g. IsAsyncThreadException() and Exception.ToString both consume too much stack -- and can't + // die. e.g. Exception.ToString both consume too much stack -- and can't // be called here. dump = FALSE; @@ -4967,12 +4958,6 @@ DefaultCatchHandler(PEXCEPTION_POINTERS pExceptionPointers, PrintToStdErrA("Stack overflow.\n"); } } - else if (IsAsyncThreadException(&throwable)) - { - // We don't print anything on async exceptions, like ThreadAbort. - dump = FALSE; - INDEBUG(suppressSelectiveBreak=TRUE); - } // Finally, should we print the message? if (dump) @@ -10839,7 +10824,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowHR(HRESULT hr) CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -10852,7 +10837,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowHR(HRESULT hr) // ! // ! COMPlusThrowHR(hr, kGetErrorInfo) - RealCOMPlusThrowHR(hr, (IErrorInfo*)NULL); + EX_THROW(EEMessageException, (hr)); } VOID DECLSPEC_NORETURN RealCOMPlusThrowHR(HRESULT hr, tagGetErrorInfo) @@ -10898,7 +10883,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowHR(HRESULT hr, UINT resID, LPCWSTR wszArg CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; diff --git a/src/coreclr/vm/excep.h b/src/coreclr/vm/excep.h index f1b5aafbb96bc2..9558c4c4f85bcb 100644 --- a/src/coreclr/vm/excep.h +++ b/src/coreclr/vm/excep.h @@ -125,7 +125,6 @@ DWORD ComputeEnclosingHandlerNestingLevel(IJitManager *pIJM, const METHODTOKEN& BOOL IsException(MethodTable *pMT); BOOL IsExceptionOfType(RuntimeExceptionKind reKind, OBJECTREF *pThrowable); BOOL IsExceptionOfType(RuntimeExceptionKind reKind, Exception *pException); -BOOL IsAsyncThreadException(OBJECTREF *pThrowable); BOOL IsUncatchable(OBJECTREF *pThrowable); VOID FixupOnRethrow(Thread *pCurThread, EXCEPTION_POINTERS *pExceptionPointers); BOOL UpdateCurrentThrowable(PEXCEPTION_RECORD pExceptionRecord); diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index 27b4a379e7efbd..818f5dbef72639 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -579,32 +579,21 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord, } #endif - if (pThread->HasThreadStateNC(Thread::TSNC_UnhandledException2ndPass) && !(pExceptionRecord->ExceptionFlags & EXCEPTION_UNWINDING)) - { - // We are in the 1st pass of exception handling, but the thread mark says that it has already executed 2nd pass - // of unhandled exception handling. That means that some external native code on top of the stack has caught the - // exception that runtime considered to be unhandled, and a new native exception was thrown on the current thread. - // We need to reset the flags below so that we no longer block exception handling for the managed frames. - pThread->ResetThreadStateNC(Thread::TSNC_UnhandledException2ndPass); - pThread->ResetThreadStateNC(Thread::TSNC_ProcessedUnhandledException); - } - // Also skip all frames when processing unhandled exceptions. That allows them to reach the host app // level and let 3rd party the chance to handle them. - if (pThread->HasThreadStateNC(Thread::TSNC_ProcessedUnhandledException)) + if (pThread->HasThreadStateNC(Thread::TSNC_SkipManagedPersonalityRoutine)) { if (pExceptionRecord->ExceptionFlags & EXCEPTION_UNWINDING) { - if (!pThread->HasThreadStateNC(Thread::TSNC_UnhandledException2ndPass)) + // The 3rd argument passes to PopExplicitFrame is normally the parent SP to correctly handle InlinedCallFrame embbeded + // in parent managed frame. But at this point there are no further managed frames are on the stack, so we can pass NULL. + // Also don't pop the GC frames, their destructor will pop them as the exception propagates. + // NOTE: this needs to be popped in the 2nd pass to ensure that crash dumps and Watson get the dump with these still + // present. + ExInfo *pExInfo = (ExInfo*)pThread->GetExceptionState()->GetCurrentExceptionTracker(); + if (pExInfo != NULL) { - pThread->SetThreadStateNC(Thread::TSNC_UnhandledException2ndPass); GCX_COOP(); - // The 3rd argument passes to PopExplicitFrame is normally the parent SP to correctly handle InlinedCallFrame embbeded - // in parent managed frame. But at this point there are no further managed frames are on the stack, so we can pass NULL. - // Also don't pop the GC frames, their destructor will pop them as the exception propagates. - // NOTE: this needs to be popped in the 2nd pass to ensure that crash dumps and Watson get the dump with these still - // present. - ExInfo *pExInfo = (ExInfo*)pThread->GetExceptionState()->GetCurrentExceptionTracker(); void *sp = (void*)GetRegdisplaySP(pExInfo->m_frameIter.m_crawl.GetRegisterSet()); PopExplicitFrames(pThread, sp, NULL /* targetCallerSp */, false /* popGCFrames */); ExInfo::PopExInfos(pThread, sp); @@ -2738,8 +2727,7 @@ StackFrame ExInfo::GetCallerSPOfParentOfNonExceptionallyInvokedFunclet(CrawlFram CopyOSContext(&tempContext, pRD->pCallerContext); // Now unwind it to get the context of the caller's caller. - EECodeInfo codeInfo(dac_cast(GetIP(pRD->pCallerContext))); - Thread::VirtualUnwindCallFrame(&tempContext, NULL, &codeInfo); + pCF->GetCodeManager()->UnwindStackFrame(&tempContext); StackFrame sfRetVal = StackFrame((UINT_PTR)(GetSP(&tempContext))); _ASSERTE(!sfRetVal.IsNull() && !sfRetVal.IsMaxVal()); @@ -2986,7 +2974,7 @@ void MarkInlinedCallFrameAsFuncletCall(Frame* pFrame) { _ASSERTE(pFrame->GetFrameIdentifier() == FrameIdentifier::InlinedCallFrame); InlinedCallFrame* pInlinedCallFrame = (InlinedCallFrame*)pFrame; - pInlinedCallFrame->m_Datum = (PTR_NDirectMethodDesc)((TADDR)pInlinedCallFrame->m_Datum | (TADDR)InlinedCallFrameMarker::ExceptionHandlingHelper | (TADDR)InlinedCallFrameMarker::SecondPassFuncletCaller); + pInlinedCallFrame->m_Datum = (PTR_PInvokeMethodDesc)((TADDR)pInlinedCallFrame->m_Datum | (TADDR)InlinedCallFrameMarker::ExceptionHandlingHelper | (TADDR)InlinedCallFrameMarker::SecondPassFuncletCaller); } // Mark the pinvoke frame as invoking any exception handling helper @@ -2994,7 +2982,7 @@ void MarkInlinedCallFrameAsEHHelperCall(Frame* pFrame) { _ASSERTE(pFrame->GetFrameIdentifier() == FrameIdentifier::InlinedCallFrame); InlinedCallFrame* pInlinedCallFrame = (InlinedCallFrame*)pFrame; - pInlinedCallFrame->m_Datum = (PTR_NDirectMethodDesc)((TADDR)pInlinedCallFrame->m_Datum | (TADDR)InlinedCallFrameMarker::ExceptionHandlingHelper); + pInlinedCallFrame->m_Datum = (PTR_PInvokeMethodDesc)((TADDR)pInlinedCallFrame->m_Datum | (TADDR)InlinedCallFrameMarker::ExceptionHandlingHelper); } static TADDR GetSpForDiagnosticReporting(REGDISPLAY *pRD) @@ -3758,7 +3746,10 @@ extern "C" CLR_BOOL QCALLTYPE SfiInit(StackFrameIterator* pThis, CONTEXT* pStack Thread* pThread = GET_THREAD(); ExInfo* pExInfo = (ExInfo*)pThread->GetExceptionState()->GetCurrentExceptionTracker(); - pThread->ResetThreadStateNC(Thread::TSNC_ProcessedUnhandledException); + if (pExInfo->m_passNumber == 1) + { + pThread->ResetThreadStateNC(Thread::TSNC_SkipManagedPersonalityRoutine); + } BEGIN_QCALL; @@ -3873,14 +3864,13 @@ extern "C" CLR_BOOL QCALLTYPE SfiInit(StackFrameIterator* pThis, CONTEXT* pStack } else { + // There are no managed frames on the stack EH_LOG((LL_INFO100, "SfiInit: No more managed frames found on stack\n")); - // There are no managed frames on the stack, fail fast and report unhandled exception - LONG disposition = InternalUnhandledExceptionFilter_Worker((EXCEPTION_POINTERS *)&pExInfo->m_ptrs); #ifdef HOST_WINDOWS - CreateCrashDumpIfEnabled(/* fSOException */ FALSE); - GetThread()->SetThreadStateNC(Thread::TSNC_ProcessedUnhandledException); + GetThread()->SetThreadStateNC(Thread::TSNC_SkipManagedPersonalityRoutine); RaiseException(pExInfo->m_ExceptionCode, EXCEPTION_NONCONTINUABLE, pExInfo->m_ptrs.ExceptionRecord->NumberParameters, pExInfo->m_ptrs.ExceptionRecord->ExceptionInformation); #else + LONG disposition = InternalUnhandledExceptionFilter_Worker((EXCEPTION_POINTERS *)&pExInfo->m_ptrs); CrashDumpAndTerminateProcess(pExInfo->m_ExceptionCode); #endif } @@ -3971,6 +3961,7 @@ extern "C" CLR_BOOL QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollid if (isPropagatingToNativeCode) { + // Propagating through Reverse pinvoke #ifdef HOST_UNIX void* callbackCxt = NULL; Interop::ManagedToNativeExceptionCallback callback = Interop::GetPropagatingExceptionCallback( @@ -3984,13 +3975,14 @@ extern "C" CLR_BOOL QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollid pTopExInfo->m_propagateExceptionContext = callbackCxt; } else +#endif // HOST_UNIX { isPropagatingToExternalNativeCode = true; } -#endif // HOST_UNIX } else { + // Propagating to CallDescrWorkerInternal, filter funclet or CallEHFunclet. if (IsCallDescrWorkerInternalReturnAddress(GetIP(pThis->m_crawl.GetRegisterSet()->pCurrentContext))) { EH_LOG((LL_INFO100, "SfiNext: the native frame is CallDescrWorkerInternal")); @@ -4001,10 +3993,6 @@ extern "C" CLR_BOOL QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollid EH_LOG((LL_INFO100, "SfiNext: current frame is filter funclet")); isPropagatingToNativeCode = TRUE; } - else - { - isPropagatingToExternalNativeCode = true; - } } if (isPropagatingToNativeCode) @@ -4025,18 +4013,21 @@ extern "C" CLR_BOOL QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollid if (isNotHandledByRuntime && IsExceptionFromManagedCode(pTopExInfo->m_ptrs.ExceptionRecord)) { - EH_LOG((LL_INFO100, "SfiNext (pass %d): no more managed frames on the stack, the exception is unhandled", pTopExInfo->m_passNumber)); + EH_LOG((LL_INFO100, "SfiNext (pass %d): no more managed frames on the stack, the exception is not handled by the runtime\n", pTopExInfo->m_passNumber)); if (pTopExInfo->m_passNumber == 1) { - LONG disposition = InternalUnhandledExceptionFilter_Worker((EXCEPTION_POINTERS *)&pTopExInfo->m_ptrs); #ifdef HOST_WINDOWS - CreateCrashDumpIfEnabled(/* fSOException */ FALSE); + if (!isPropagatingToExternalNativeCode) #endif + { + LONG disposition = InternalUnhandledExceptionFilter_Worker((EXCEPTION_POINTERS *)&pTopExInfo->m_ptrs); + GetThread()->SetThreadStateNC(Thread::TSNC_ProcessedUnhandledException); + } } else { #ifdef HOST_WINDOWS - GetThread()->SetThreadStateNC(Thread::TSNC_ProcessedUnhandledException); + GetThread()->SetThreadStateNC(Thread::TSNC_SkipManagedPersonalityRoutine); RaiseException(pTopExInfo->m_ExceptionCode, EXCEPTION_NONCONTINUABLE, pTopExInfo->m_ptrs.ExceptionRecord->NumberParameters, pTopExInfo->m_ptrs.ExceptionRecord->ExceptionInformation); #else CrashDumpAndTerminateProcess(pTopExInfo->m_ExceptionCode); diff --git a/src/coreclr/vm/fcall.h b/src/coreclr/vm/fcall.h index 082d2131e28f1f..f592ada170894c 100644 --- a/src/coreclr/vm/fcall.h +++ b/src/coreclr/vm/fcall.h @@ -19,8 +19,6 @@ // // FCIMPL2(INT32, Div, INT32 x, INT32 y) // { -// if (y == 0) -// FCThrow(kDivideByZeroException); // return x/y; // } // FCIMPLEND @@ -212,23 +210,14 @@ class ForbidGC { }; // FC_COMMON_PROLOG is used for both FCalls and HCalls -#define FC_COMMON_PROLOG(target, assertFn) \ +#define FC_COMMON_PROLOG() \ /* The following line has to be first. We do not want to trash last error */ \ DWORD __lastError = ::GetLastError(); \ - static void* __cache = 0; \ - assertFn(__cache, (LPVOID)target); \ - { \ - Thread *_pThread = GetThread(); \ - Thread::ObjectRefFlush(_pThread); \ - } \ ForbidGC __fCallCheck(__FILE__, __LINE__); \ ::SetLastError(__lastError); \ -void FCallAssert(void*& cache, void* target); -void HCallAssert(void*& cache, void* target); - #else -#define FC_COMMON_PROLOG(target, assertFn) +#define FC_COMMON_PROLOG() #define FC_CAN_TRIGGER_GC() #define FC_CAN_TRIGGER_GC_END() #endif // ENABLE_CONTRACTS @@ -244,9 +233,7 @@ void HCallAssert(void*& cache, void* target); #define GetEEFuncEntryPointMacro(func) ((LPVOID)(func)) #define FCIMPL_PROLOG(funcname) \ - LPVOID __me; \ - __me = GetEEFuncEntryPointMacro(funcname); \ - FC_COMMON_PROLOG(__me, FCallAssert) + FC_COMMON_PROLOG() #if defined(_DEBUG) && !defined(__GNUC__) @@ -419,7 +406,7 @@ struct FCSigCheck { #define FCIMPLEND } -#define HCIMPL_PROLOG(funcname) LPVOID __me; __me = 0; FC_COMMON_PROLOG(funcname, HCallAssert) +#define HCIMPL_PROLOG(funcname) FC_COMMON_PROLOG() // HCIMPL macros are used to implement JIT helpers. The only difference is that // HCIMPL methods are not mapped to a managed method in CoreLib in ecalllist.h. @@ -500,11 +487,6 @@ typedef INT32 FC_BOOL_ARG; #define FC_ACCESS_BOOL(x) ((BYTE)x != 0) -// The fcall entrypoints has to be at unique addresses. Use this helper macro to make -// the code of the fcalls unique if you get assert in ecall.cpp that mentions it. -// The parameter of the FCUnique macro is an arbitrary 32-bit random non-zero number. -#define FCUnique(unique) { Volatile u = (unique); while (u.LoadWithoutBarrier() == 0) { }; } - // FCALL contracts come in two forms: // // Short form that should be used if the FCALL contract does not have any extras like preconditions, failure injection. Example: diff --git a/src/coreclr/vm/field.h b/src/coreclr/vm/field.h index bf10e953281fc4..ddc5665190327c 100644 --- a/src/coreclr/vm/field.h +++ b/src/coreclr/vm/field.h @@ -450,7 +450,7 @@ class FieldDesc OBJECTREF GetStaticOBJECTREF() { WRAPPER_NO_CONTRACT; - return *(OBJECTREF *)GetCurrentStaticAddress(); + return ObjectToOBJECTREF(*(Object**)GetCurrentStaticAddress()); } VOID SetStaticOBJECTREF(OBJECTREF objRef); diff --git a/src/coreclr/vm/finalizerthread.cpp b/src/coreclr/vm/finalizerthread.cpp index 86a019419b1c97..0ad3d680bcd8bc 100644 --- a/src/coreclr/vm/finalizerthread.cpp +++ b/src/coreclr/vm/finalizerthread.cpp @@ -32,7 +32,7 @@ CLREvent * FinalizerThread::hEventFinalizerToShutDown = NULL; HANDLE FinalizerThread::MHandles[kHandleCount]; -BOOL FinalizerThread::IsCurrentThreadFinalizer() +bool FinalizerThread::IsCurrentThreadFinalizer() { LIMITED_METHOD_CONTRACT; @@ -46,11 +46,124 @@ void FinalizerThread::EnableFinalization() hEventFinalizer->Set(); } -BOOL FinalizerThread::HaveExtraWorkForFinalizer() +namespace +{ + // This is a linked list of the LCGMethodResolvers that represent DynamicMethodDescs + // waiting to be destroyed. The resolvers are used since they can be chained together + // to avoid allocations when destroying multiple DynamicMethodDescs. + VolatilePtr s_delayDestroyDynamicMethod = nullptr; + + bool HasDelayedDynamicMethod() + { + LIMITED_METHOD_CONTRACT; + return s_delayDestroyDynamicMethod != nullptr; + } + + void AddDelayedDynamicMethod(DynamicMethodDesc* pDMD) + { + STANDARD_VM_CONTRACT; + _ASSERTE(pDMD != nullptr); + + // Get the LCGMethodResolver from the DynamicMethodDesc. + LCGMethodResolver* lcgResolver = pDMD->GetLCGMethodResolver(); + + // Append any existing resolvers to form a linked list. + if (s_delayDestroyDynamicMethod != nullptr) + lcgResolver->SetNextDynamicMethodForDelayCleanup((DynamicMethodDesc*)s_delayDestroyDynamicMethod->GetDynamicMethod()); + + s_delayDestroyDynamicMethod = lcgResolver; + } + + void CleanupDelayedDynamicMethods() + { + STANDARD_VM_CONTRACT; + + while (s_delayDestroyDynamicMethod != nullptr) + { + // Get the next method to destroy. + DynamicMethodDesc* next = s_delayDestroyDynamicMethod->GetNextDynamicMethodForDelayCleanup(); + + // Destroy the current method. + DynamicMethodDesc* curr = (DynamicMethodDesc*)s_delayDestroyDynamicMethod->GetDynamicMethod(); + if (!curr->TryDestroy()) + return; + + // Update the head of the list. + s_delayDestroyDynamicMethod = next == nullptr ? nullptr : next->GetLCGMethodResolver(); + } + } +} + +void FinalizerThread::DelayDestroyDynamicMethodDesc(DynamicMethodDesc* pDMD) { WRAPPER_NO_CONTRACT; + _ASSERTE(FinalizerThread::IsCurrentThreadFinalizer()); + + AddDelayedDynamicMethod(pDMD); +} + +bool FinalizerThread::HaveExtraWorkForFinalizer() +{ + LIMITED_METHOD_CONTRACT; + + Thread* finalizerThread = GetFinalizerThread(); + return finalizerThread->RequireSyncBlockCleanup() + || SystemDomain::System()->RequireAppDomainCleanup() + || (Thread::m_DetachCount > 0) + || Thread::CleanupNeededForFinalizedThread() + || YieldProcessorNormalization::IsMeasurementScheduled() + || HasDelayedDynamicMethod() + || ThreadStore::s_pThreadStore->ShouldTriggerGCForDeadThreads(); +} + +static void DoExtraWorkForFinalizer(Thread* finalizerThread) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + PRECONDITION(finalizerThread != NULL); + PRECONDITION(finalizerThread == FinalizerThread::GetFinalizerThread()); + PRECONDITION(FinalizerThread::HaveExtraWorkForFinalizer()); + } + CONTRACTL_END; + +#ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT + if (finalizerThread->RequiresCoInitialize()) + { + finalizerThread->SetApartment(Thread::AS_InMTA); + } +#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT + + if (finalizerThread->RequireSyncBlockCleanup()) + { + SyncBlockCache::GetSyncBlockCache()->CleanupSyncBlocks(); + } + if (SystemDomain::System()->RequireAppDomainCleanup()) + { + SystemDomain::System()->ProcessDelayedUnloadLoaderAllocators(); + } + + if (Thread::m_DetachCount > 0 + || Thread::CleanupNeededForFinalizedThread()) + { + Thread::CleanupDetachedThreads(); + } + + if (YieldProcessorNormalization::IsMeasurementScheduled()) + { + GCX_PREEMP(); + YieldProcessorNormalization::PerformMeasurement(); + } + + if (HasDelayedDynamicMethod()) + { + GCX_PREEMP(); + CleanupDelayedDynamicMethods(); + } - return GetFinalizerThread()->HaveExtraWorkForFinalizer(); + ThreadStore::s_pThreadStore->TriggerGCForDeadThreadsIfNecessary(); } OBJECTREF FinalizerThread::GetNextFinalizableObject() @@ -342,9 +455,9 @@ VOID FinalizerThread::FinalizerThreadWorker(void *args) // we might want to do some extra work on the finalizer thread // check and do it - if (GetFinalizerThread()->HaveExtraWorkForFinalizer()) + if (HaveExtraWorkForFinalizer()) { - GetFinalizerThread()->DoExtraWorkForFinalizer(); + DoExtraWorkForFinalizer(GetFinalizerThread()); } LOG((LF_GC, LL_INFO100, "***** Calling Finalizers\n")); diff --git a/src/coreclr/vm/finalizerthread.h b/src/coreclr/vm/finalizerthread.h index 46d104853f380c..f76899fc60bf4c 100644 --- a/src/coreclr/vm/finalizerthread.h +++ b/src/coreclr/vm/finalizerthread.h @@ -42,11 +42,14 @@ class FinalizerThread return g_pFinalizerThread; } - static BOOL IsCurrentThreadFinalizer(); + static bool IsCurrentThreadFinalizer(); static void EnableFinalization(); - static BOOL HaveExtraWorkForFinalizer(); + static void DelayDestroyDynamicMethodDesc(DynamicMethodDesc* pDMD); + + // returns if there is some extra work for the finalizer thread. + static bool HaveExtraWorkForFinalizer(); static OBJECTREF GetNextFinalizableObject(); diff --git a/src/coreclr/vm/frames.cpp b/src/coreclr/vm/frames.cpp index 53ff4599c8453c..98ce961660caee 100644 --- a/src/coreclr/vm/frames.cpp +++ b/src/coreclr/vm/frames.cpp @@ -1530,6 +1530,17 @@ void TransitionFrame::PromoteCallerStackHelper(promote_func* fn, ScanContext* sc (fn)(PTR_PTR_Object(pThis), sc, CHECK_APP_DOMAIN); } + // Promote async continuation for async methods + if (argit.HasAsyncContinuation()) + { + PTR_PTR_VOID pAsyncCont = dac_cast(pTransitionBlock + argit.GetAsyncContinuationArgOffset()); + LOG((LF_GC, INFO3, + " async continuation argument at " FMT_ADDR "promoted from" FMT_ADDR "\n", + DBG_ADDR(pAsyncCont), DBG_ADDR(*pAsyncCont) )); + + (fn)(PTR_PTR_Object(pAsyncCont), sc, CHECK_APP_DOMAIN); + } + int argOffset; while ((argOffset = argit.GetNextOffset()) != TransitionBlock::InvalidOffset) { diff --git a/src/coreclr/vm/frames.h b/src/coreclr/vm/frames.h index 5a7d4e70ff29c3..31b5e321584f46 100644 --- a/src/coreclr/vm/frames.h +++ b/src/coreclr/vm/frames.h @@ -2125,7 +2125,7 @@ struct ReversePInvokeFrame //------------------------------------------------------------------------ // This frame is pushed by any JIT'ted method that contains one or more -// inlined N/Direct calls. Note that the JIT'ted method keeps it pushed +// inlined PInvoke calls. Note that the JIT'ted method keeps it pushed // the whole time to amortize the pushing cost across the entire method. //------------------------------------------------------------------------ @@ -2134,6 +2134,21 @@ typedef DPTR(class InlinedCallFrame) PTR_InlinedCallFrame; class InlinedCallFrame : public Frame { public: + +#ifndef DACCESS_COMPILE +#ifdef FEATURE_INTERPRETER + InlinedCallFrame() : Frame(FrameIdentifier::InlinedCallFrame) + { + WRAPPER_NO_CONTRACT; + m_Datum = NULL; + m_pCallSiteSP = NULL; + m_pCallerReturnAddress = 0; + m_pCalleeSavedFP = 0; + m_pThread = NULL; + } +#endif // FEATURE_INTERPRETER +#endif // DACCESS_COMPILE + MethodDesc *GetFunction_Impl() { WRAPPER_NO_CONTRACT; @@ -2195,7 +2210,7 @@ class InlinedCallFrame : public Frame // - bit 1 set indicates invoking new exception handling helpers // - bit 2 indicates CallCatchFunclet or CallFinallyFunclet // See code:HasFunction. - PTR_NDirectMethodDesc m_Datum; + PTR_PInvokeMethodDesc m_Datum; // X86: ESP after pushing the outgoing arguments, and just before calling // out to unmanaged code. @@ -2212,7 +2227,7 @@ class InlinedCallFrame : public Frame // This is used only for EBP. Hence, a stackwalk will miss the other // callee-saved registers for the method with the InlinedCallFrame. // To prevent GC-holes, we do not keep any GC references in callee-saved - // registers across an NDirect call. + // registers across an PInvoke call. TADDR m_pCalleeSavedFP; // This field is used to cache the current thread object where this frame is diff --git a/src/coreclr/vm/gccover.cpp b/src/coreclr/vm/gccover.cpp index 063857a8bd98d4..26d0f0b78efa8b 100644 --- a/src/coreclr/vm/gccover.cpp +++ b/src/coreclr/vm/gccover.cpp @@ -406,7 +406,7 @@ static MethodDesc* getTargetMethodDesc(PCODE target) switch (pPrecode->GetType()) { case PRECODE_STUB: - case PRECODE_NDIRECT_IMPORT: + case PRECODE_PINVOKE_IMPORT: case PRECODE_THISPTR_RETBUF: return dac_cast(pPrecode->AsStubPrecode()->GetMethodDesc()); default: @@ -444,13 +444,27 @@ void ReplaceInstrAfterCall(PBYTE instrToReplace, MethodDesc* callMD) return; } - if (IsPointerReturnKind(returnKind)) + if (callMD->IsAsyncMethod()) { - *instrToReplace = INTERRUPT_INSTR_PROTECT_FIRST_RET; + if (IsPointerReturnKind(returnKind)) + { + *instrToReplace = INTERRUPT_INSTR_PROTECT_CONT_AND_RET; + } + else + { + *instrToReplace = INTERRUPT_INSTR_PROTECT_CONT; + } } else { - *instrToReplace = INTERRUPT_INSTR; + if (IsPointerReturnKind(returnKind)) + { + *instrToReplace = INTERRUPT_INSTR_PROTECT_RET; + } + else + { + *instrToReplace = INTERRUPT_INSTR; + } } } @@ -639,14 +653,22 @@ void DoGcStress (PCONTEXT regs, NativeCodeVersion nativeCodeVersion) // `if (!IsGcCoverageInterruptInstruction(instrPtr))` after we read `*instrPtr`. bool atCall; - bool afterCallProtect = false; + bool afterCallRetProtect = false; + bool afterCallContProtect = false; BYTE instrVal = *instrPtr; atCall = (instrVal == INTERRUPT_INSTR_CALL); - if (instrVal == INTERRUPT_INSTR_PROTECT_FIRST_RET) + if (instrVal == INTERRUPT_INSTR_PROTECT_RET || + instrVal == INTERRUPT_INSTR_PROTECT_CONT_AND_RET) { - afterCallProtect = true; + afterCallRetProtect = true; + } + + if (instrVal == INTERRUPT_INSTR_PROTECT_CONT || + instrVal == INTERRUPT_INSTR_PROTECT_CONT_AND_RET) + { + afterCallContProtect = true; } if (!IsGcCoverageInterruptInstruction(instrPtr)) @@ -842,15 +864,20 @@ void DoGcStress (PCONTEXT regs, NativeCodeVersion nativeCodeVersion) // The legacy X86 GC encoder does not encode the state of return registers at // call sites, so we must add an extra frame to protect returns. - DWORD_PTR retValReg = 0; + DWORD_PTR protRegs[2] = {}; - if (afterCallProtect) + if (afterCallRetProtect) { - retValReg = regs->Eax; + protRegs[0] = regs->Eax; + } + + if (afterCallContProtect) + { + protRegs[1] = regs->Ecx; } _ASSERTE(sizeof(OBJECTREF) == sizeof(DWORD_PTR)); - GCFrame gcFrame(pThread, (OBJECTREF*)&retValReg, 1, TRUE); + GCFrame gcFrame(pThread, (OBJECTREF*)protRegs, 2, TRUE); MethodDesc *pMD = nativeCodeVersion.GetMethodDesc(); LOG((LF_GCROOTS, LL_EVERYTHING, "GCCOVER: Doing GC at method %s::%s offset 0x%x\n", @@ -876,9 +903,14 @@ void DoGcStress (PCONTEXT regs, NativeCodeVersion nativeCodeVersion) CONSISTENCY_CHECK(!pThread->HasPendingGCStressInstructionUpdate()); - if (afterCallProtect) + if (afterCallRetProtect) + { + regs->Eax = protRegs[0]; + } + + if (afterCallContProtect) { - regs->Eax = retValReg; + regs->Ecx = protRegs[1]; } if (!Thread::UseRedirectForGcStress()) diff --git a/src/coreclr/vm/gccover.h b/src/coreclr/vm/gccover.h index 182a24bb975752..3310c3d8bc9bce 100644 --- a/src/coreclr/vm/gccover.h +++ b/src/coreclr/vm/gccover.h @@ -58,7 +58,9 @@ typedef DPTR(GCCoverageInfo) PTR_GCCoverageInfo; // see code:GCCoverageInfo::sav #if defined(TARGET_X86) #define INTERRUPT_INSTR_CALL 0xFA // X86 CLI instruction -#define INTERRUPT_INSTR_PROTECT_FIRST_RET 0xFB // X86 STI instruction, protect the first return register +#define INTERRUPT_INSTR_PROTECT_RET 0xFB // X86 STI instruction, protect the first return register +#define INTERRUPT_INSTR_PROTECT_CONT 0xEC // X86 IN instruction, protect the continuation register +#define INTERRUPT_INSTR_PROTECT_CONT_AND_RET 0xED // X86 IN instruction, protect both continuation and return registers #endif #elif defined(TARGET_ARM) @@ -117,7 +119,9 @@ inline bool IsGcCoverageInterruptInstructionVal(UINT32 instrVal) { case INTERRUPT_INSTR: case INTERRUPT_INSTR_CALL: - case INTERRUPT_INSTR_PROTECT_FIRST_RET: + case INTERRUPT_INSTR_PROTECT_RET: + case INTERRUPT_INSTR_PROTECT_CONT: + case INTERRUPT_INSTR_PROTECT_CONT_AND_RET: return true; default: return false; diff --git a/src/coreclr/vm/gcenv.ee.cpp b/src/coreclr/vm/gcenv.ee.cpp index 84d1080c8ce0d8..c16f6a1b31c9a2 100644 --- a/src/coreclr/vm/gcenv.ee.cpp +++ b/src/coreclr/vm/gcenv.ee.cpp @@ -25,6 +25,7 @@ #include "configuration.h" #include "genanalysis.h" #include "eventpipeadapter.h" +#include // Finalizes a weak reference directly. extern void FinalizeWeakReference(Object* obj); @@ -235,7 +236,7 @@ static void ScanTailCallArgBufferRoots(Thread* pThread, promote_func* fn, ScanCo if (argBuffer == NULL || argBuffer->GCDesc == NULL) return; - if (argBuffer->State == TAILCALLARGBUFFER_ABANDONED) + if (argBuffer->State == TAILCALLARGBUFFER_INACTIVE) return; bool instArgOnly = argBuffer->State == TAILCALLARGBUFFER_INSTARG_ONLY; @@ -1006,7 +1007,7 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args) { // If runtime is not suspended, force all threads to see the changed table before seeing updated heap boundaries. // See: http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/346765 - FlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); } #endif @@ -1058,7 +1059,7 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args) if (!is_runtime_suspended) { // If runtime is not suspended, force all threads to see the changed state before observing future allocations. - FlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); } #endif diff --git a/src/coreclr/vm/gcinfodecoder.cpp b/src/coreclr/vm/gcinfodecoder.cpp index 00bfa6b96f6d63..48e8eddf25498f 100644 --- a/src/coreclr/vm/gcinfodecoder.cpp +++ b/src/coreclr/vm/gcinfodecoder.cpp @@ -2183,6 +2183,15 @@ template void TGcInfoDecoder::ReportRe _ASSERTE( !"NYI" ); } +template OBJECTREF* TGcInfoDecoder::GetCapturedRegister( + int regNum, + PREGDISPLAY pRD + ) +{ + _ASSERTE( !"NYI" ); + return nullptr; +} + #endif // Unknown platform #ifdef FEATURE_INTERPRETER diff --git a/src/coreclr/vm/hostinformation.cpp b/src/coreclr/vm/hostinformation.cpp index 4d85f74671d7dd..acaa23bb141848 100644 --- a/src/coreclr/vm/hostinformation.cpp +++ b/src/coreclr/vm/hostinformation.cpp @@ -45,7 +45,8 @@ bool HostInformation::GetProperty(_In_z_ const char* name, SString& value) bool HostInformation::HasExternalProbe() { - return s_hostContract.external_assembly_probe != nullptr; + size_t requiredSize = offsetof(host_runtime_contract, external_assembly_probe) + sizeof(s_hostContract.external_assembly_probe); + return s_hostContract.size >= requiredSize && s_hostContract.external_assembly_probe != nullptr; } bool HostInformation::ExternalAssemblyProbe(_In_ const SString& path, _Out_ void** data, _Out_ int64_t* size) diff --git a/src/coreclr/vm/i386/asmconstants.h b/src/coreclr/vm/i386/asmconstants.h index 82887f9ad9fa61..6f5321582c84dd 100644 --- a/src/coreclr/vm/i386/asmconstants.h +++ b/src/coreclr/vm/i386/asmconstants.h @@ -105,7 +105,7 @@ ASMCONSTANTS_C_ASSERT(EHContext_Eip == offsetof(EHContext,Eip)) #endif // FEATURE_EH_FUNCLETS #define VASigCookie__StubOffset 4 -ASMCONSTANTS_C_ASSERT(VASigCookie__StubOffset == offsetof(VASigCookie, pNDirectILStub)) +ASMCONSTANTS_C_ASSERT(VASigCookie__StubOffset == offsetof(VASigCookie, pPInvokeILStub)) #ifndef UNIX_X86_ABI #define SIZEOF_TailCallFrame 32 diff --git a/src/coreclr/vm/i386/asmhelpers.S b/src/coreclr/vm/i386/asmhelpers.S index b77d482fe2d670..8d578f3243c5a8 100644 --- a/src/coreclr/vm/i386/asmhelpers.S +++ b/src/coreclr/vm/i386/asmhelpers.S @@ -299,8 +299,8 @@ NESTED_END OnHijackFPTripThread, _TEXT // ========================================================================== // This function is reached only via the embedded ImportThunkGlue code inside -// an NDirectMethodDesc. It's purpose is to load the DLL associated with an -// N/Direct method, then backpatch the DLL target into the methoddesc. +// an PInvokeMethodDesc. It's purpose is to load the DLL associated with an +// PInvoke method, then backpatch the DLL target into the methoddesc. // // Initial state: // @@ -318,24 +318,24 @@ NESTED_END OnHijackFPTripThread, _TEXT // // // ========================================================================== -LEAF_ENTRY NDirectImportThunk, _TEXT +LEAF_ENTRY PInvokeImportThunk, _TEXT // Preserve argument registers push ecx push edx // Invoke the function that does the real work. push eax - call C_FUNC(NDirectImportWorker) + call C_FUNC(PInvokeImportWorker) // Restore argument registers pop edx pop ecx - // If we got back from NDirectImportWorker, the MD has been successfully + // If we got back from PInvokeImportWorker, the MD has been successfully // linked and "eax" contains the DLL target. Proceed to execute the // original DLL call. jmp eax // Jump to DLL target -LEAF_END NDirectImportThunk, _TEXT +LEAF_END PInvokeImportThunk, _TEXT // // Used to get the current instruction pointer value @@ -356,7 +356,7 @@ LEAF_END GetCurrentSP, _TEXT // ========================================================================== // Invoked for vararg forward P/Invoke calls as a stub. // Except for secret return buffer, arguments come on the stack so EDX is available as scratch. -// EAX - the NDirectMethodDesc +// EAX - the PInvokeMethodDesc // ECX - may be return buffer address // [ESP + 4] - the VASigCookie // diff --git a/src/coreclr/vm/i386/asmhelpers.asm b/src/coreclr/vm/i386/asmhelpers.asm index 77d5bd32439551..798fefe9f564a4 100644 --- a/src/coreclr/vm/i386/asmhelpers.asm +++ b/src/coreclr/vm/i386/asmhelpers.asm @@ -44,7 +44,7 @@ EXTERN _COMPlusFrameHandlerRevCom:PROC endif ; FEATURE_COMINTEROP endif ; FEATURE_EH_FUNCLETS EXTERN __alloca_probe:PROC -EXTERN _NDirectImportWorker@4:PROC +EXTERN _PInvokeImportWorker@4:PROC EXTERN _VarargPInvokeStubWorker@12:PROC EXTERN _GenericPInvokeCalliStubWorker@12:PROC @@ -618,8 +618,8 @@ endif ; FEATURE_HIJACK ;========================================================================== ; This function is reached only via the embedded ImportThunkGlue code inside -; an NDirectMethodDesc. It's purpose is to load the DLL associated with an -; N/Direct method, then backpatch the DLL target into the methoddesc. +; an PInvokeMethodDesc. It's purpose is to load the DLL associated with an +; PInvoke method, then backpatch the DLL target into the methoddesc. ; ; Initial state: ; @@ -637,7 +637,7 @@ endif ; FEATURE_HIJACK ; ; ;========================================================================== -_NDirectImportThunk@0 proc public +_PInvokeImportThunk@0 proc public ; Preserve argument registers push ecx @@ -645,17 +645,17 @@ _NDirectImportThunk@0 proc public ; Invoke the function that does the real work. push eax - call _NDirectImportWorker@4 + call _PInvokeImportWorker@4 ; Restore argument registers pop edx pop ecx - ; If we got back from NDirectImportWorker, the MD has been successfully + ; If we got back from PInvokeImportWorker, the MD has been successfully ; linked and "eax" contains the DLL target. Proceed to execute the ; original DLL call. jmp eax ; Jump to DLL target -_NDirectImportThunk@0 endp +_PInvokeImportThunk@0 endp ; void __stdcall setFPReturn(int fpSize, INT64 retVal) _setFPReturn@12 proc public @@ -901,7 +901,7 @@ _ProfileTailcallNaked@4 endp ;========================================================================== ; Invoked for vararg forward P/Invoke calls as a stub. ; Except for secret return buffer, arguments come on the stack so EDX is available as scratch. -; EAX - the NDirectMethodDesc +; EAX - the PInvokeMethodDesc ; ECX - may be return buffer address ; [ESP + 4] - the VASigCookie ; diff --git a/src/coreclr/vm/i386/cgencpu.h b/src/coreclr/vm/i386/cgencpu.h index 1a9d9145d8a439..7eacba4cf74234 100644 --- a/src/coreclr/vm/i386/cgencpu.h +++ b/src/coreclr/vm/i386/cgencpu.h @@ -44,7 +44,7 @@ class ComCallMethodDesc; #define BACK_TO_BACK_JUMP_ALLOCATE_SIZE 8 // # bytes to allocate for a back to back jump instruction // Needed for PInvoke inlining in ngened images -#define HAS_NDIRECT_IMPORT_PRECODE 1 +#define HAS_PINVOKE_IMPORT_PRECODE 1 #define HAS_FIXUP_PRECODE 1 diff --git a/src/coreclr/vm/i386/cgenx86.cpp b/src/coreclr/vm/i386/cgenx86.cpp index e242668963dcd9..98c845c00e14b7 100644 --- a/src/coreclr/vm/i386/cgenx86.cpp +++ b/src/coreclr/vm/i386/cgenx86.cpp @@ -381,11 +381,11 @@ void InlinedCallFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateF if (stackArgSize & ~0xFFFF) { - NDirectMethodDesc * pMD = PTR_NDirectMethodDesc(datum); + PInvokeMethodDesc * pMD = PTR_PInvokeMethodDesc(datum); - /* if this is not an NDirect frame, something is really wrong */ + /* if this is not an PInvoke frame, something is really wrong */ - _ASSERTE(pMD->SanityCheck() && pMD->IsNDirect()); + _ASSERTE(pMD->SanityCheck() && pMD->IsPInvoke()); stackArgSize = pMD->GetStackArgumentSize(); } @@ -786,11 +786,11 @@ PCODE DynamicHelpers::CreateHelper(LoaderAllocator * pAllocator, TADDR arg, PCOD BEGIN_DYNAMIC_HELPER_EMIT(10); *p++ = 0xB9; // mov ecx, XXXXXX - *(INT32 *)p = (INT32)arg; + SET_UNALIGNED_32(p, (INT32)arg); p += 4; *p++ = X86_INSTR_JMP_REL32; // jmp rel32 - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), target); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), target)); p += 4; END_DYNAMIC_HELPER_EMIT(); @@ -808,11 +808,11 @@ void DynamicHelpers::EmitHelperWithArg(BYTE*& p, size_t rxOffset, LoaderAllocato // Move an argument into the second argument register and jump to a target function. *p++ = 0xBA; // mov edx, XXXXXX - *(INT32 *)p = (INT32)arg; + SET_UNALIGNED_32(p, (INT32)arg); p += 4; *p++ = X86_INSTR_JMP_REL32; // jmp rel32 - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), target); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), target)); p += 4; } @@ -830,15 +830,15 @@ PCODE DynamicHelpers::CreateHelper(LoaderAllocator * pAllocator, TADDR arg, TADD BEGIN_DYNAMIC_HELPER_EMIT(15); *p++ = 0xB9; // mov ecx, XXXXXX - *(INT32 *)p = (INT32)arg; + SET_UNALIGNED_32(p, (INT32)arg); p += 4; *p++ = 0xBA; // mov edx, XXXXXX - *(INT32 *)p = (INT32)arg2; + SET_UNALIGNED_32(p, (INT32)arg2); p += 4; *p++ = X86_INSTR_JMP_REL32; // jmp rel32 - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), target); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), target)); p += 4; END_DYNAMIC_HELPER_EMIT(); @@ -848,15 +848,15 @@ PCODE DynamicHelpers::CreateHelperArgMove(LoaderAllocator * pAllocator, TADDR ar { BEGIN_DYNAMIC_HELPER_EMIT(12); - *(UINT16 *)p = 0xD18B; // mov edx, ecx + SET_UNALIGNED_16(p, 0xD18B); // mov edx, ecx p += 2; *p++ = 0xB9; // mov ecx, XXXXXX - *(INT32 *)p = (INT32)arg; + SET_UNALIGNED_32(p, (INT32)arg); p += 4; *p++ = X86_INSTR_JMP_REL32; // jmp rel32 - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), target); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), target)); p += 4; END_DYNAMIC_HELPER_EMIT(); @@ -876,7 +876,7 @@ PCODE DynamicHelpers::CreateReturnConst(LoaderAllocator * pAllocator, TADDR arg) BEGIN_DYNAMIC_HELPER_EMIT(6); *p++ = 0xB8; // mov eax, XXXXXX - *(INT32 *)p = (INT32)arg; + SET_UNALIGNED_32(p, (INT32)arg); p += 4; *p++ = 0xC3; // ret @@ -889,7 +889,7 @@ PCODE DynamicHelpers::CreateReturnIndirConst(LoaderAllocator * pAllocator, TADDR BEGIN_DYNAMIC_HELPER_EMIT((offset != 0) ? 9 : 6); *p++ = 0xA1; // mov eax, [XXXXXX] - *(INT32 *)p = (INT32)arg; + SET_UNALIGNED_32(p, (INT32)arg); p += 4; if (offset != 0) @@ -927,13 +927,13 @@ PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADD // push arg *p++ = 0x68; - *(INT32 *)p = arg; + SET_UNALIGNED_32(p, arg); p += 4; #ifdef UNIX_X86_ABI // mov eax, target *p++ = 0xB8; - *(INT32 *)p = target; + SET_UNALIGNED_32(p, target); p += 4; #else // push eax @@ -942,9 +942,9 @@ PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADD *p++ = X86_INSTR_JMP_REL32; // jmp rel32 #ifdef UNIX_X86_ABI - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), (PCODE)DynamicHelperArgsStub); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), (PCODE)DynamicHelperArgsStub)); #else - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), target); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), target)); #endif p += 4; @@ -971,18 +971,18 @@ PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADD // push arg *p++ = 0x68; - *(INT32 *)p = arg; + SET_UNALIGNED_32(p, arg); p += 4; // push arg2 *p++ = 0x68; - *(INT32 *)p = arg2; + SET_UNALIGNED_32(p, arg2); p += 4; #ifdef UNIX_X86_ABI // mov eax, target *p++ = 0xB8; - *(INT32 *)p = target; + SET_UNALIGNED_32(p, target); p += 4; #else // push eax @@ -991,9 +991,9 @@ PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADD *p++ = X86_INSTR_JMP_REL32; // jmp rel32 #ifdef UNIX_X86_ABI - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), (PCODE)DynamicHelperArgsStub); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), (PCODE)DynamicHelperArgsStub)); #else - *(INT32 *)p = rel32UsingJumpStub((INT32 *)(p + rxOffset), target); + SET_UNALIGNED_32(p, rel32UsingJumpStub((INT32 *)(p + rxOffset), target)); #endif p += 4; @@ -1045,9 +1045,9 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator, _ASSERTE(pLookup->testForNull && i > 0); // cmp dword ptr[eax + sizeOffset],slotOffset - *(UINT16*)p = 0xb881; p += 2; - *(UINT32*)p = (UINT32)pLookup->sizeOffset; p += 4; - *(UINT32*)p = (UINT32)slotOffset; p += 4; + SET_UNALIGNED_16(p, 0xb881); p += 2; + SET_UNALIGNED_32(p, (UINT32)pLookup->sizeOffset); p += 4; + SET_UNALIGNED_32(p, (UINT32)slotOffset); p += 4; // jle 'HELPER CALL' *p++ = 0x7e; @@ -1058,12 +1058,12 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator, // mov eax,dword ptr [ecx|eax + offset] if (pLookup->offsets[i] >= 0x80) { - *(UINT16*)p = (i == 0 ? 0x818b : 0x808b); p += 2; - *(UINT32*)p = (UINT32)pLookup->offsets[i]; p += 4; + SET_UNALIGNED_16(p, (i == 0 ? 0x818b : 0x808b)); p += 2; + SET_UNALIGNED_32(p, (UINT32)pLookup->offsets[i]); p += 4; } else { - *(UINT16*)p = (i == 0 ? 0x418b : 0x408b); p += 2; + SET_UNALIGNED_16(p, (i == 0 ? 0x418b : 0x408b)); p += 2; *p++ = (BYTE)pLookup->offsets[i]; } } @@ -1083,10 +1083,10 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator, _ASSERTE(pLookup->indirections != 0); // test eax,eax - *(UINT16*)p = 0xc085; p += 2; + SET_UNALIGNED_16(p, 0xc085); p += 2; // je 'HELPER_CALL' (a jump of 1 byte) - *(UINT16*)p = 0x0174; p += 2; + SET_UNALIGNED_16(p, 0x0174); p += 2; *p++ = 0xC3; // ret diff --git a/src/coreclr/vm/ilmarshalers.cpp b/src/coreclr/vm/ilmarshalers.cpp index aa9b3d6531553a..b8bd7360dbe5b4 100644 --- a/src/coreclr/vm/ilmarshalers.cpp +++ b/src/coreclr/vm/ilmarshalers.cpp @@ -1093,7 +1093,7 @@ void ILValueClassMarshaler::EmitClearNative(ILCodeStream * pslILEmit) { STANDARD_VM_CONTRACT; - MethodDesc* pStructMarshalStub = NDirect::CreateStructMarshalILStub(m_pargs->m_pMT); + MethodDesc* pStructMarshalStub = PInvoke::CreateStructMarshalILStub(m_pargs->m_pMT); EmitLoadManagedHomeAddr(pslILEmit); EmitLoadNativeHomeAddr(pslILEmit); @@ -1108,7 +1108,7 @@ void ILValueClassMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEm { STANDARD_VM_CONTRACT; - MethodDesc* pStructMarshalStub = NDirect::CreateStructMarshalILStub(m_pargs->m_pMT); + MethodDesc* pStructMarshalStub = PInvoke::CreateStructMarshalILStub(m_pargs->m_pMT); EmitLoadManagedHomeAddr(pslILEmit); EmitLoadNativeHomeAddr(pslILEmit); @@ -1122,7 +1122,7 @@ void ILValueClassMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEm { STANDARD_VM_CONTRACT; - MethodDesc* pStructMarshalStub = NDirect::CreateStructMarshalILStub(m_pargs->m_pMT); + MethodDesc* pStructMarshalStub = PInvoke::CreateStructMarshalILStub(m_pargs->m_pMT); EmitLoadManagedHomeAddr(pslILEmit); EmitLoadNativeHomeAddr(pslILEmit); @@ -2313,7 +2313,7 @@ void ILLayoutClassPtrMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* psl ILCodeLabel* isNotMatchingTypeLabel = pslILEmit->NewCodeLabel(); bool emittedTypeCheck = EmitExactTypeCheck(pslILEmit, isNotMatchingTypeLabel); - MethodDesc* pStructMarshalStub = NDirect::CreateStructMarshalILStub(m_pargs->m_pMT); + MethodDesc* pStructMarshalStub = PInvoke::CreateStructMarshalILStub(m_pargs->m_pMT); EmitLoadManagedValue(pslILEmit); pslILEmit->EmitCALL(METHOD__RUNTIME_HELPERS__GET_RAW_DATA, 1, 1); @@ -2349,7 +2349,7 @@ void ILLayoutClassPtrMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* psl ILCodeLabel* isNotMatchingTypeLabel = pslILEmit->NewCodeLabel(); bool emittedTypeCheck = EmitExactTypeCheck(pslILEmit, isNotMatchingTypeLabel); - MethodDesc* pStructMarshalStub = NDirect::CreateStructMarshalILStub(m_pargs->m_pMT); + MethodDesc* pStructMarshalStub = PInvoke::CreateStructMarshalILStub(m_pargs->m_pMT); EmitLoadManagedValue(pslILEmit); pslILEmit->EmitCALL(METHOD__RUNTIME_HELPERS__GET_RAW_DATA, 1, 1); @@ -2378,7 +2378,7 @@ void ILLayoutClassPtrMarshaler::EmitClearNativeContents(ILCodeStream * pslILEmit ILCodeLabel* cleanedUpLabel = pslILEmit->NewCodeLabel(); bool emittedTypeCheck = EmitExactTypeCheck(pslILEmit, isNotMatchingTypeLabel); - MethodDesc* pStructMarshalStub = NDirect::CreateStructMarshalILStub(m_pargs->m_pMT); + MethodDesc* pStructMarshalStub = PInvoke::CreateStructMarshalILStub(m_pargs->m_pMT); EmitLoadManagedValue(pslILEmit); pslILEmit->EmitCALL(METHOD__RUNTIME_HELPERS__GET_RAW_DATA, 1, 1); @@ -2529,7 +2529,7 @@ void ILLayoutClassMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILE pslILEmit->EmitBRFALSE(pNullRefLabel); - MethodDesc* pStructMarshalStub = NDirect::CreateStructMarshalILStub(m_pargs->m_pMT); + MethodDesc* pStructMarshalStub = PInvoke::CreateStructMarshalILStub(m_pargs->m_pMT); EmitLoadManagedValue(pslILEmit); pslILEmit->EmitCALL(METHOD__RUNTIME_HELPERS__GET_RAW_DATA, 1, 1); @@ -2553,7 +2553,7 @@ void ILLayoutClassMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILE { STANDARD_VM_CONTRACT; - MethodDesc* pStructMarshalStub = NDirect::CreateStructMarshalILStub(m_pargs->m_pMT); + MethodDesc* pStructMarshalStub = PInvoke::CreateStructMarshalILStub(m_pargs->m_pMT); EmitLoadManagedValue(pslILEmit); pslILEmit->EmitCALL(METHOD__RUNTIME_HELPERS__GET_RAW_DATA, 1, 1); @@ -2568,7 +2568,7 @@ void ILLayoutClassMarshaler::EmitClearNativeContents(ILCodeStream* pslILEmit) { STANDARD_VM_CONTRACT; - MethodDesc* pStructMarshalStub = NDirect::CreateStructMarshalILStub(m_pargs->m_pMT); + MethodDesc* pStructMarshalStub = PInvoke::CreateStructMarshalILStub(m_pargs->m_pMT); EmitLoadManagedValue(pslILEmit); pslILEmit->EmitCALL(METHOD__RUNTIME_HELPERS__GET_RAW_DATA, 1, 1); @@ -2629,7 +2629,7 @@ void ILBlittableLayoutClassMarshaler::EmitConvertContentsNativeToCLR(ILCodeStrea pslILEmit->EmitCPBLK(); } -MarshalerOverrideStatus ILHandleRefMarshaler::ArgumentOverride(NDirectStubLinker* psl, +MarshalerOverrideStatus ILHandleRefMarshaler::ArgumentOverride(PInvokeStubLinker* psl, BOOL byref, BOOL fin, BOOL fout, @@ -2675,7 +2675,7 @@ MarshalerOverrideStatus ILHandleRefMarshaler::ArgumentOverride(NDirectStubLinker } } -MarshalerOverrideStatus ILHandleRefMarshaler::ReturnOverride(NDirectStubLinker* psl, +MarshalerOverrideStatus ILHandleRefMarshaler::ReturnOverride(PInvokeStubLinker* psl, BOOL fManagedToNative, BOOL fHresultSwap, OverrideProcArgs* pargs, @@ -2721,7 +2721,7 @@ void ILSafeHandleMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEm pslILEmit->EmitLabel(successLabel); } -MarshalerOverrideStatus ILSafeHandleMarshaler::ArgumentOverride(NDirectStubLinker* psl, +MarshalerOverrideStatus ILSafeHandleMarshaler::ArgumentOverride(PInvokeStubLinker* psl, BOOL byref, BOOL fin, BOOL fout, @@ -2854,7 +2854,7 @@ MarshalerOverrideStatus ILSafeHandleMarshaler::ArgumentOverride(NDirectStubLinke if (fout) { // We will use cleanup stream to avoid leaking the handle on thread abort. - psl->EmitSetArgMarshalIndex(pslIL, NDirectStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + argidx); + psl->EmitSetArgMarshalIndex(pslIL, PInvokeStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + argidx); psl->SetCleanupNeeded(); ILCodeStream *pslCleanupIL = psl->GetCleanupCodeStream(); @@ -2862,8 +2862,8 @@ MarshalerOverrideStatus ILSafeHandleMarshaler::ArgumentOverride(NDirectStubLinke ILCodeLabel *pDoneLabel = pslCleanupIL->NewCodeLabel(); psl->EmitCheckForArgCleanup(pslCleanupIL, - NDirectStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + argidx, - NDirectStubLinker::BranchIfNotMarshaled, + PInvokeStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + argidx, + PInvokeStubLinker::BranchIfNotMarshaled, pDoneLabel); // If this is an [in, out] handle check if the native handles have changed. If not we're finished. @@ -2931,7 +2931,7 @@ MarshalerOverrideStatus ILSafeHandleMarshaler::ArgumentOverride(NDirectStubLinke // MarshalerOverrideStatus ILSafeHandleMarshaler::ReturnOverride( - NDirectStubLinker * psl, + PInvokeStubLinker * psl, BOOL fManagedToNative, BOOL fHresultSwap, OverrideProcArgs * pargs, @@ -3013,15 +3013,15 @@ ILSafeHandleMarshaler::ReturnOverride( EmitLoadNativeLocalAddrForByRefDispatch(pslILDispatch, dwReturnNativeHandleLocal); // We will use cleanup stream to avoid leaking the handle on thread abort. - psl->EmitSetArgMarshalIndex(pslIL, NDirectStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL); + psl->EmitSetArgMarshalIndex(pslIL, PInvokeStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL); psl->SetCleanupNeeded(); ILCodeStream *pslCleanupIL = psl->GetCleanupCodeStream(); ILCodeLabel *pDoneLabel = pslCleanupIL->NewCodeLabel(); psl->EmitCheckForArgCleanup(pslCleanupIL, - NDirectStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL, - NDirectStubLinker::BranchIfNotMarshaled, + PInvokeStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL, + PInvokeStubLinker::BranchIfNotMarshaled, pDoneLabel); // 6) store return value in safehandle @@ -3078,7 +3078,7 @@ void ILCriticalHandleMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* psl //--------------------------------------------------------------------------------------- // -MarshalerOverrideStatus ILCriticalHandleMarshaler::ArgumentOverride(NDirectStubLinker* psl, +MarshalerOverrideStatus ILCriticalHandleMarshaler::ArgumentOverride(PInvokeStubLinker* psl, BOOL byref, BOOL fin, BOOL fout, @@ -3207,7 +3207,7 @@ MarshalerOverrideStatus ILCriticalHandleMarshaler::ArgumentOverride(NDirectStubL if (fout) { // We will use cleanup stream to avoid leaking the handle on thread abort. - psl->EmitSetArgMarshalIndex(pslIL, NDirectStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + argidx); + psl->EmitSetArgMarshalIndex(pslIL, PInvokeStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + argidx); psl->SetCleanupNeeded(); ILCodeStream *pslCleanupIL = psl->GetCleanupCodeStream(); @@ -3215,8 +3215,8 @@ MarshalerOverrideStatus ILCriticalHandleMarshaler::ArgumentOverride(NDirectStubL ILCodeLabel *pDoneLabel = pslCleanupIL->NewCodeLabel(); psl->EmitCheckForArgCleanup(pslCleanupIL, - NDirectStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + argidx, - NDirectStubLinker::BranchIfNotMarshaled, + PInvokeStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + argidx, + PInvokeStubLinker::BranchIfNotMarshaled, pDoneLabel); // If this is an [in, out] handle check if the native handles have changed. If not we're finished. @@ -3264,7 +3264,7 @@ MarshalerOverrideStatus ILCriticalHandleMarshaler::ArgumentOverride(NDirectStubL // MarshalerOverrideStatus ILCriticalHandleMarshaler::ReturnOverride( - NDirectStubLinker * psl, + PInvokeStubLinker * psl, BOOL fManagedToNative, BOOL fHresultSwap, OverrideProcArgs * pargs, @@ -3347,7 +3347,7 @@ ILCriticalHandleMarshaler::ReturnOverride( EmitLoadNativeLocalAddrForByRefDispatch(pslILDispatch, dwReturnNativeHandleLocal); // We will use cleanup stream to avoid leaking the handle on thread abort. - psl->EmitSetArgMarshalIndex(pslIL, NDirectStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL); + psl->EmitSetArgMarshalIndex(pslIL, PInvokeStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL); psl->SetCleanupNeeded(); ILCodeStream *pslCleanupIL = psl->GetCleanupCodeStream(); @@ -3355,8 +3355,8 @@ ILCriticalHandleMarshaler::ReturnOverride( // 6) store return value in criticalhandle psl->EmitCheckForArgCleanup(pslCleanupIL, - NDirectStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL, - NDirectStubLinker::BranchIfNotMarshaled, + PInvokeStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL, + PInvokeStubLinker::BranchIfNotMarshaled, pDoneLabel); pslCleanupIL->EmitLDLOC(dwReturnHandleLocal); @@ -3384,7 +3384,7 @@ ILCriticalHandleMarshaler::ReturnOverride( } // ILCriticalHandleMarshaler::ReturnOverride #if defined(FEATURE_IJW) -MarshalerOverrideStatus ILBlittableValueClassWithCopyCtorMarshaler::ArgumentOverride(NDirectStubLinker* psl, +MarshalerOverrideStatus ILBlittableValueClassWithCopyCtorMarshaler::ArgumentOverride(PInvokeStubLinker* psl, BOOL byref, BOOL fin, BOOL fout, @@ -3894,7 +3894,7 @@ void ILNativeArrayMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) if (mops.elementType == VT_RECORD && !mops.methodTable->IsBlittable()) { - pslILEmit->EmitLDFTN(pslILEmit->GetToken(NDirect::CreateStructMarshalILStub(mops.methodTable))); + pslILEmit->EmitLDFTN(pslILEmit->GetToken(PInvoke::CreateStructMarshalILStub(mops.methodTable))); } else { @@ -3985,7 +3985,7 @@ BOOL ILNativeArrayMarshaler::CheckSizeParamIndexArg( Module *pModule = m_pargs->m_pMarshalInfo->GetModule(); _ASSERT(pModule); - SigTypeContext emptyTypeContext; // this is an empty type context: ndirect and COM calls are guaranteed to not be generics. + SigTypeContext emptyTypeContext; // this is an empty type context: PInvoke and COM calls are guaranteed to not be generics. MetaSig msig(pMD->GetSignature(), pModule, &emptyTypeContext); @@ -4464,7 +4464,7 @@ void ILFixedArrayMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) if (mops.elementType == VT_RECORD && !mops.methodTable->IsBlittable()) { - pslILEmit->EmitLDFTN(pslILEmit->GetToken(NDirect::CreateStructMarshalILStub(mops.methodTable))); + pslILEmit->EmitLDFTN(pslILEmit->GetToken(PInvoke::CreateStructMarshalILStub(mops.methodTable))); } else { @@ -4662,7 +4662,7 @@ void ILSafeArrayMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit) if (mops.elementType == VT_RECORD && !mops.methodTable->IsBlittable()) { - pslILEmit->EmitLDFTN(pslILEmit->GetToken(NDirect::CreateStructMarshalILStub(mops.methodTable))); + pslILEmit->EmitLDFTN(pslILEmit->GetToken(PInvoke::CreateStructMarshalILStub(mops.methodTable))); } else { diff --git a/src/coreclr/vm/ilmarshalers.h b/src/coreclr/vm/ilmarshalers.h index 7f5dad6bb2276d..08e01d3463bab6 100644 --- a/src/coreclr/vm/ilmarshalers.h +++ b/src/coreclr/vm/ilmarshalers.h @@ -273,7 +273,7 @@ class ILMarshaler DWORD m_dwMngdMarshalerLocalNum; private: - NDirectStubLinker* m_pslNDirect; + PInvokeStubLinker* m_pslPInvoke; ILCodeStream* m_pcsMarshal; ILCodeStream* m_pcsUnmarshal; ILStubMarshalHome m_nativeHome; @@ -282,7 +282,7 @@ class ILMarshaler public: ILMarshaler() : - m_pslNDirect(NULL) + m_pslPInvoke(NULL) { } @@ -291,11 +291,11 @@ class ILMarshaler LIMITED_METHOD_CONTRACT; } - void SetNDirectStubLinker(NDirectStubLinker* pslNDirect) + void SetPInvokeStubLinker(PInvokeStubLinker* pslPInvoke) { LIMITED_METHOD_CONTRACT; - CONSISTENCY_CHECK(NULL == m_pslNDirect); - m_pslNDirect = pslNDirect; + CONSISTENCY_CHECK(NULL == m_pslPInvoke); + m_pslPInvoke = pslPInvoke; } private: @@ -306,7 +306,7 @@ class ILMarshaler OverrideProcArgs* pargs) { LIMITED_METHOD_CONTRACT; - CONSISTENCY_CHECK_MSG(m_pslNDirect != NULL, "please call SetNDirectStubLinker() before EmitMarshalArgument or EmitMarshalReturnValue"); + CONSISTENCY_CHECK_MSG(m_pslPInvoke != NULL, "please call SetPInvokeStubLinker() before EmitMarshalArgument or EmitMarshalReturnValue"); m_pcsMarshal = pcsMarshal; m_pcsUnmarshal = pcsUnmarshal; m_pargs = pargs; @@ -431,7 +431,7 @@ class ILMarshaler WRAPPER_NO_CONTRACT; if (g_pConfig->InteropLogArguments()) { - m_pslNDirect->EmitLogNativeArgument(pslILEmit, dwPinnedLocal); + m_pslPInvoke->EmitLogNativeArgument(pslILEmit, dwPinnedLocal); } } @@ -484,12 +484,12 @@ class ILMarshaler // we set the clr-to-native flag so the marshal phase is CLR->Native and the unmarshal phase is Native->CLR Init(pcsMarshal, pcsUnmarshal, argidx, MARSHAL_FLAG_IN | MARSHAL_FLAG_OUT | MARSHAL_FLAG_CLR_TO_NATIVE | MARSHAL_FLAG_FIELD, pargs); - EmitCreateMngdMarshaler(m_pslNDirect->GetSetupCodeStream()); + EmitCreateMngdMarshaler(m_pslPInvoke->GetSetupCodeStream()); - EmitSetupArgumentForMarshalling(m_pslNDirect->GetSetupCodeStream()); + EmitSetupArgumentForMarshalling(m_pslPInvoke->GetSetupCodeStream()); EmitSetupDefaultHomesForField( - m_pslNDirect->GetSetupCodeStream(), + m_pslPInvoke->GetSetupCodeStream(), managedOffset, nativeOffset); @@ -519,10 +519,10 @@ class ILMarshaler // we know that we don't need a managed marshaler since we will just pin. if (!CanMarshalViaPinning()) { - EmitCreateMngdMarshaler(m_pslNDirect->GetSetupCodeStream()); + EmitCreateMngdMarshaler(m_pslPInvoke->GetSetupCodeStream()); } - EmitSetupArgumentForMarshalling(m_pslNDirect->GetSetupCodeStream()); + EmitSetupArgumentForMarshalling(m_pslPInvoke->GetSetupCodeStream()); if (IsCLRToNative(dwMarshalFlags)) { @@ -627,7 +627,7 @@ class ILMarshaler if (NeedsMarshalCleanupIndex()) { - m_pslNDirect->EmitSetArgMarshalIndex(m_pcsUnmarshal, NDirectStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_argidx); + m_pslPInvoke->EmitSetArgMarshalIndex(m_pcsUnmarshal, PInvokeStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_argidx); } EmitConvertSpaceAndContentsNativeToCLR(m_pcsUnmarshal); @@ -642,7 +642,7 @@ class ILMarshaler if (NeedsMarshalCleanupIndex()) { - m_pslNDirect->EmitSetArgMarshalIndex(m_pcsUnmarshal, NDirectStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_argidx); + m_pslPInvoke->EmitSetArgMarshalIndex(m_pcsUnmarshal, PInvokeStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_argidx); } if (IsHresultSwap(dwMarshalFlags)) @@ -665,7 +665,7 @@ class ILMarshaler if (NeedsUnmarshalCleanupIndex()) { // if an exception is thrown after this point, we will clean up the unmarshaled retval - m_pslNDirect->EmitSetArgMarshalIndex(m_pcsUnmarshal, NDirectStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL); + m_pslPInvoke->EmitSetArgMarshalIndex(m_pcsUnmarshal, PInvokeStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL); } EmitCleanupNativeToCLR(); @@ -723,12 +723,12 @@ class ILMarshaler void EmitLoadCleanupWorkList(ILCodeStream* pslILEmit) { - m_pslNDirect->LoadCleanupWorkList(pslILEmit); + m_pslPInvoke->LoadCleanupWorkList(pslILEmit); } int GetLCIDParamIndex() { - return m_pslNDirect->GetLCIDParamIdx(); + return m_pslPInvoke->GetLCIDParamIdx(); } void EmitSetupSigAndDefaultHomesCLRToNative() @@ -756,12 +756,12 @@ class ILMarshaler { CONSISTENCY_CHECK(NeedsMarshalCleanupIndex()); - ILCodeStream* pcsCleanup = m_pslNDirect->GetCleanupCodeStream(); + ILCodeStream* pcsCleanup = m_pslPInvoke->GetCleanupCodeStream(); ILCodeLabel* pSkipClearNativeLabel = pcsCleanup->NewCodeLabel(); - m_pslNDirect->EmitCheckForArgCleanup(pcsCleanup, - NDirectStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_argidx, - NDirectStubLinker::BranchIfNotMarshaled, + m_pslPInvoke->EmitCheckForArgCleanup(pcsCleanup, + PInvokeStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_argidx, + PInvokeStubLinker::BranchIfNotMarshaled, pSkipClearNativeLabel); EmitClearNativeTemp(pcsCleanup); @@ -777,12 +777,12 @@ class ILMarshaler { CONSISTENCY_CHECK(NeedsMarshalCleanupIndex()); - ILCodeStream* pcsCleanup = m_pslNDirect->GetCleanupCodeStream(); + ILCodeStream* pcsCleanup = m_pslPInvoke->GetCleanupCodeStream(); ILCodeLabel* pSkipClearNativeLabel = pcsCleanup->NewCodeLabel(); - m_pslNDirect->EmitCheckForArgCleanup(pcsCleanup, - NDirectStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_argidx, - NDirectStubLinker::BranchIfNotMarshaled, + m_pslPInvoke->EmitCheckForArgCleanup(pcsCleanup, + PInvokeStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_argidx, + PInvokeStubLinker::BranchIfNotMarshaled, pSkipClearNativeLabel); EmitClearNative(pcsCleanup); @@ -1021,7 +1021,7 @@ class ILMarshaler EmitConvertSpaceAndContentsNativeToCLR(m_pcsUnmarshal); if (NeedsClearNative()) { - ILCodeStream* pcsCleanup = m_pslNDirect->GetCleanupCodeStream(); + ILCodeStream* pcsCleanup = m_pslPInvoke->GetCleanupCodeStream(); EmitClearNative(pcsCleanup); } } @@ -1034,12 +1034,12 @@ class ILMarshaler { CONSISTENCY_CHECK(NeedsMarshalCleanupIndex()); - ILCodeStream* pcsCleanup = m_pslNDirect->GetCleanupCodeStream(); + ILCodeStream* pcsCleanup = m_pslPInvoke->GetCleanupCodeStream(); ILCodeLabel* pSkipClearCLRLabel = pcsCleanup->NewCodeLabel(); - m_pslNDirect->EmitCheckForArgCleanup(pcsCleanup, - NDirectStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_argidx, - NDirectStubLinker::BranchIfNotMarshaled, + m_pslPInvoke->EmitCheckForArgCleanup(pcsCleanup, + PInvokeStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_argidx, + PInvokeStubLinker::BranchIfNotMarshaled, pSkipClearCLRLabel); EmitClearCLR(pcsCleanup); @@ -1071,11 +1071,11 @@ class ILMarshaler _ASSERTE(IsRetval(m_dwMarshalFlags) || IsOut(m_dwMarshalFlags)); LocalDesc nativeType = GetNativeType(); - ILCodeStream *pcsCleanup = m_pslNDirect->GetExceptionCleanupCodeStream(); + ILCodeStream *pcsCleanup = m_pslPInvoke->GetExceptionCleanupCodeStream(); if (NeedsClearNative()) { - m_pslNDirect->SetExceptionCleanupNeeded(); + m_pslPInvoke->SetExceptionCleanupNeeded(); ILCodeLabel *pSkipCleanupLabel = pcsCleanup->NewCodeLabel(); @@ -1086,9 +1086,9 @@ class ILMarshaler ILCodeLabel *pSkipCopyLabel = pcsCleanup->NewCodeLabel(); CONSISTENCY_CHECK(NeedsMarshalCleanupIndex()); - m_pslNDirect->EmitCheckForArgCleanup(pcsCleanup, - NDirectStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_argidx, - NDirectStubLinker::BranchIfMarshaled, + m_pslPInvoke->EmitCheckForArgCleanup(pcsCleanup, + PInvokeStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_argidx, + PInvokeStubLinker::BranchIfMarshaled, pSkipCopyLabel); pcsCleanup->EmitLDARG(m_argidx); @@ -1105,12 +1105,12 @@ class ILMarshaler CONSISTENCY_CHECK(NeedsUnmarshalCleanupIndex()); UINT uArgIdx = (IsRetval(m_dwMarshalFlags) ? - NDirectStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL : - NDirectStubLinker::CLEANUP_INDEX_ARG0_UNMARSHAL + m_argidx); + PInvokeStubLinker::CLEANUP_INDEX_RETVAL_UNMARSHAL : + PInvokeStubLinker::CLEANUP_INDEX_ARG0_UNMARSHAL + m_argidx); - m_pslNDirect->EmitCheckForArgCleanup(pcsCleanup, + m_pslPInvoke->EmitCheckForArgCleanup(pcsCleanup, uArgIdx, - NDirectStubLinker::BranchIfNotMarshaled, + PInvokeStubLinker::BranchIfNotMarshaled, pSkipCleanupLabel); } @@ -1132,7 +1132,7 @@ class ILMarshaler // if there is an output buffer, zero it out so the caller does not get pointer to already freed data if (IsRetval(m_dwMarshalFlags) || (IsOut(m_dwMarshalFlags) && IsByref(m_dwMarshalFlags))) { - m_pslNDirect->SetExceptionCleanupNeeded(); + m_pslPInvoke->SetExceptionCleanupNeeded(); EmitReInitNative(pcsCleanup); if (IsHresultSwap(m_dwMarshalFlags) || IsOut(m_dwMarshalFlags)) @@ -1458,9 +1458,9 @@ class ILMarshaler void EmitKeepAliveManagedValue() { // Don't use the cleanup work list to avoid any extra allocations. - m_pslNDirect->SetCleanupNeeded(); + m_pslPInvoke->SetCleanupNeeded(); - ILCodeStream* pslILEmit = m_pslNDirect->GetCleanupCodeStream(); + ILCodeStream* pslILEmit = m_pslPInvoke->GetCleanupCodeStream(); ILCodeLabel* pNoManagedValueLabel = nullptr; if (IsFieldMarshal(m_dwMarshalFlags)) @@ -1483,7 +1483,7 @@ class ILMarshaler // Extension point to allow a marshaler to conditionally override all of the ILMarshaler logic with its own or block marshalling when marshalling an argument. // See MarshalInfo::GetArgumentOverrideProc for the implementation. - static MarshalerOverrideStatus ArgumentOverride(NDirectStubLinker* psl, + static MarshalerOverrideStatus ArgumentOverride(PInvokeStubLinker* psl, BOOL byref, BOOL fin, BOOL fout, @@ -1498,7 +1498,7 @@ class ILMarshaler // Extension point to allow a marshaler to conditionally override all of the ILMarshaler logic with its own or block marshalling when marshalling a return value. // See MarshalInfo::GetReturnOverrideProc for the implementation. - static MarshalerOverrideStatus ReturnOverride(NDirectStubLinker* psl, + static MarshalerOverrideStatus ReturnOverride(PInvokeStubLinker* psl, BOOL fManagedToNative, BOOL fHresultSwap, OverrideProcArgs* pargs, @@ -2199,7 +2199,7 @@ class ILHandleRefMarshaler : public ILMarshaler return false; } - static MarshalerOverrideStatus ArgumentOverride(NDirectStubLinker* psl, + static MarshalerOverrideStatus ArgumentOverride(PInvokeStubLinker* psl, BOOL byref, BOOL fin, BOOL fout, @@ -2208,7 +2208,7 @@ class ILHandleRefMarshaler : public ILMarshaler UINT* pResID, UINT argidx); - static MarshalerOverrideStatus ReturnOverride(NDirectStubLinker* psl, + static MarshalerOverrideStatus ReturnOverride(PInvokeStubLinker* psl, BOOL fManagedToNative, BOOL fHresultSwap, OverrideProcArgs* pargs, @@ -2239,7 +2239,7 @@ class ILSafeHandleMarshaler : public ILMarshaler void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override; void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override; - static MarshalerOverrideStatus ArgumentOverride(NDirectStubLinker* psl, + static MarshalerOverrideStatus ArgumentOverride(PInvokeStubLinker* psl, BOOL byref, BOOL fin, BOOL fout, @@ -2248,7 +2248,7 @@ class ILSafeHandleMarshaler : public ILMarshaler UINT* pResID, UINT argidx); - static MarshalerOverrideStatus ReturnOverride(NDirectStubLinker *psl, + static MarshalerOverrideStatus ReturnOverride(PInvokeStubLinker *psl, BOOL fManagedToNative, BOOL fHresultSwap, OverrideProcArgs *pargs, @@ -2282,7 +2282,7 @@ class ILCriticalHandleMarshaler : public ILMarshaler void EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) override; void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) override; - static MarshalerOverrideStatus ArgumentOverride(NDirectStubLinker* psl, + static MarshalerOverrideStatus ArgumentOverride(PInvokeStubLinker* psl, BOOL byref, BOOL fin, BOOL fout, @@ -2291,7 +2291,7 @@ class ILCriticalHandleMarshaler : public ILMarshaler UINT* pResID, UINT argidx); - static MarshalerOverrideStatus ReturnOverride(NDirectStubLinker *psl, + static MarshalerOverrideStatus ReturnOverride(PInvokeStubLinker *psl, BOOL fManagedToNative, BOOL fHresultSwap, OverrideProcArgs *pargs, @@ -2941,7 +2941,7 @@ class ILBlittableValueClassWithCopyCtorMarshaler : public ILMarshaler return LocalDesc(); } - static MarshalerOverrideStatus ArgumentOverride(NDirectStubLinker* psl, + static MarshalerOverrideStatus ArgumentOverride(PInvokeStubLinker* psl, BOOL byref, BOOL fin, BOOL fout, diff --git a/src/coreclr/vm/ilstubcache.cpp b/src/coreclr/vm/ilstubcache.cpp index 5aeeb2776aed3e..a5558713e17ee9 100644 --- a/src/coreclr/vm/ilstubcache.cpp +++ b/src/coreclr/vm/ilstubcache.cpp @@ -70,7 +70,7 @@ void CreateModuleIndependentSignature(LoaderHeap* pCreationHeap, // static MethodDesc* ILStubCache::CreateAndLinkNewILStubMethodDesc(LoaderAllocator* pAllocator, MethodTable* pMT, DWORD dwStubFlags, Module* pSigModule, PCCOR_SIGNATURE pSig, DWORD cbSig, SigTypeContext *pTypeContext, - ILStubLinker* pStubLinker) + ILStubLinker* pStubLinker, BOOL isAsync /* = FALSE */) { CONTRACT (MethodDesc*) { @@ -86,6 +86,7 @@ MethodDesc* ILStubCache::CreateAndLinkNewILStubMethodDesc(LoaderAllocator* pAllo dwStubFlags, pSigModule, pSig, cbSig, + isAsync, pTypeContext, &amTracker); @@ -143,7 +144,7 @@ namespace // static MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTable* pMT, DWORD dwStubFlags, - Module* pSigModule, PCCOR_SIGNATURE pSig, DWORD cbSig, SigTypeContext *pTypeContext, + Module* pSigModule, PCCOR_SIGNATURE pSig, DWORD cbSig, BOOL isAsync, SigTypeContext *pTypeContext, AllocMemTracker* pamTracker) { CONTRACT (MethodDesc*) @@ -160,7 +161,7 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa mcDynamic, TRUE /* fNonVtableSlot */, TRUE /* fNativeCodeSlot */, - FALSE /* HasAsyncMethodData */, + isAsync /* HasAsyncMethodData */, pMT, pamTracker); @@ -175,6 +176,13 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa pMD->InitializeFlags(DynamicMethodDesc::FlagPublic | DynamicMethodDesc::FlagIsILStub); pMD->SetTemporaryEntryPoint(pamTracker); + if (isAsync) + { + pMD->SetHasAsyncMethodData(); + // Async stubs are standalone methods that do not form async/task-returning variant pairs. + pMD->GetAddrOfAsyncMethodData()->kind = AsyncMethodKind::AsyncExplicitImpl; + } + // // convert signature to a compatible signature if needed // @@ -531,7 +539,8 @@ MethodDesc* ILStubCache::GetStubMethodDesc( } MethodTable *pStubMT = GetOrCreateStubMethodTable(pSigLoaderModule); - pMD = ILStubCache::CreateNewMethodDesc(m_pAllocator->GetHighFrequencyHeap(), pStubMT, dwStubFlags, pSigModule, pSig, cbSig, pTypeContext, pamTracker); + BOOL isAsync = pTargetMD == NULL ? FALSE: pTargetMD->IsAsyncMethod(); + pMD = ILStubCache::CreateNewMethodDesc(m_pAllocator->GetHighFrequencyHeap(), pStubMT, dwStubFlags, pSigModule, pSig, cbSig, isAsync, pTypeContext, pamTracker); if (SF_IsSharedStub(dwStubFlags)) { diff --git a/src/coreclr/vm/ilstubcache.h b/src/coreclr/vm/ilstubcache.h index c53fd7a1878c28..52be99d9fb8ef1 100644 --- a/src/coreclr/vm/ilstubcache.h +++ b/src/coreclr/vm/ilstubcache.h @@ -51,7 +51,7 @@ class ILStubCache final MethodDesc* GetStubMethodDesc( MethodDesc *pTargetMD, ILStubHashBlob* pHashBlob, - DWORD dwStubFlags, // bitmask of NDirectStubFlags + DWORD dwStubFlags, // bitmask of PInvokeStubFlags Module* pSigModule, Module* pSigLoaderModule, PCCOR_SIGNATURE pSig, @@ -68,12 +68,13 @@ class ILStubCache final static MethodDesc* CreateAndLinkNewILStubMethodDesc( LoaderAllocator* pAllocator, MethodTable* pMT, - DWORD dwStubFlags, // bitmask of NDirectStubFlags + DWORD dwStubFlags, // bitmask of PInvokeStubFlags Module* pSigModule, PCCOR_SIGNATURE pSig, DWORD cbSig, SigTypeContext *pTypeContext, - ILStubLinker* pStubLinker); + ILStubLinker* pStubLinker, + BOOL isAsync = FALSE); MethodTable * GetStubMethodTable() { @@ -93,10 +94,11 @@ class ILStubCache final static MethodDesc* CreateNewMethodDesc( LoaderHeap* pCreationHeap, MethodTable* pMT, - DWORD dwStubFlags, // bitmask of NDirectStubFlags + DWORD dwStubFlags, // bitmask of PInvokeStubFlags Module* pSigModule, PCCOR_SIGNATURE pSig, DWORD cbSig, + BOOL isAsync, SigTypeContext *pTypeContext, AllocMemTracker* pamTracker); diff --git a/src/coreclr/vm/interoplibinterface.h b/src/coreclr/vm/interoplibinterface.h index aeffe64d41a4fe..4ab07ddf5979a8 100644 --- a/src/coreclr/vm/interoplibinterface.h +++ b/src/coreclr/vm/interoplibinterface.h @@ -97,7 +97,7 @@ class Interop { public: // Check if pending exceptions are possible for the following native export. - static bool ShouldCheckForPendingException(_In_ NDirectMethodDesc* md); + static bool ShouldCheckForPendingException(_In_ PInvokeMethodDesc* md); // A no return callback that is designed to help propagate a managed // exception going from Managed to Native. diff --git a/src/coreclr/vm/interoplibinterface_comwrappers.cpp b/src/coreclr/vm/interoplibinterface_comwrappers.cpp index 54bb985229d6a5..7b984171ff6715 100644 --- a/src/coreclr/vm/interoplibinterface_comwrappers.cpp +++ b/src/coreclr/vm/interoplibinterface_comwrappers.cpp @@ -355,14 +355,18 @@ namespace InteropLibImports return TryInvokeICustomQueryInterfaceResult::FailedToInvoke; } + // Switch to Cooperative mode since object references + // are being manipulated and the catchFrame needs that so that it can push + // itself to the explicit frame stack. + GCX_COOP(); + // Indicate to the debugger and exception handling that managed exceptions are being caught + // here. + DebuggerU2MCatchHandlerFrame catchFrame(true /* catchesAllExceptions */); + HRESULT hr; auto result = TryInvokeICustomQueryInterfaceResult::FailedToInvoke; EX_TRY_THREAD(CURRENT_THREAD) { - // Switch to Cooperative mode since object references - // are being manipulated. - GCX_COOP(); - struct { OBJECTREF objRef; @@ -380,6 +384,8 @@ namespace InteropLibImports } EX_CATCH_HRESULT(hr); + catchFrame.Pop(); + // Assert valid value. _ASSERTE(TryInvokeICustomQueryInterfaceResult::Min <= result && result <= TryInvokeICustomQueryInterfaceResult::Max); diff --git a/src/coreclr/vm/interoplibinterface_java.cpp b/src/coreclr/vm/interoplibinterface_java.cpp index 0a30dce519f471..e4f1f07f11997b 100644 --- a/src/coreclr/vm/interoplibinterface_java.cpp +++ b/src/coreclr/vm/interoplibinterface_java.cpp @@ -36,11 +36,11 @@ namespace // Free memory in each of the SCCs for (size_t i = 0; i < args->ComponentCount; i++) { - free(args->Components[i].Contexts); + delete[] args->Components[i].Contexts; } - free(args->Components); - free(args->CrossReferences); - free(args); + delete[] args->Components; + delete[] args->CrossReferences; + delete args; } } diff --git a/src/coreclr/vm/interoplibinterface_shared.cpp b/src/coreclr/vm/interoplibinterface_shared.cpp index 2fc5d604ba394c..5cd3378ff66b72 100644 --- a/src/coreclr/vm/interoplibinterface_shared.cpp +++ b/src/coreclr/vm/interoplibinterface_shared.cpp @@ -9,7 +9,7 @@ using ManagedToNativeExceptionCallback = Interop::ManagedToNativeExceptionCallback; -bool Interop::ShouldCheckForPendingException(_In_ NDirectMethodDesc* md) +bool Interop::ShouldCheckForPendingException(_In_ PInvokeMethodDesc* md) { CONTRACTL { diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index aea5fac135f511..144357e8deb5b0 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -6,12 +6,50 @@ #include "threads.h" #include "gcenv.h" #include "interpexec.h" -#include "callstubgenerator.h" +#include "frames.h" // for numeric_limits #include -void InvokeCompiledMethod(MethodDesc *pMD, int8_t *pArgs, int8_t *pRet) +#ifdef TARGET_WASM +void InvokeCalliStub(PCODE ftn, CallStubHeader *stubHeaderTemplate, int8_t *pArgs, int8_t *pRet); +void InvokeCompiledMethod(MethodDesc *pMD, int8_t *pArgs, int8_t *pRet, PCODE target); +void InvokeDelegateInvokeMethod(MethodDesc *pMDDelegateInvoke, int8_t *pArgs, int8_t *pRet, PCODE target); +#else +#include "callstubgenerator.h" + +CallStubHeader *UpdateCallStubForMethod(MethodDesc *pMD) +{ + CONTRACTL + { + THROWS; + MODE_ANY; + PRECONDITION(CheckPointer(pMD)); + } + CONTRACTL_END + + GCX_PREEMP(); + + CallStubGenerator callStubGenerator; + + AllocMemTracker amTracker; + CallStubHeader *header = callStubGenerator.GenerateCallStub(pMD, &amTracker, true /* interpreterToNative */); + + if (pMD->SetCallStub(header)) + { + amTracker.SuppressRelease(); + } + else + { + // We have lost the race for generating the header, use the one that was generated by another thread + // and let the amTracker release the memory of the one we generated. + header = pMD->GetCallStub(); + } + + return header; +} + +void InvokeCompiledMethod(MethodDesc *pMD, int8_t *pArgs, int8_t *pRet, PCODE target) { CONTRACTL { @@ -26,26 +64,40 @@ void InvokeCompiledMethod(MethodDesc *pMD, int8_t *pArgs, int8_t *pRet) CallStubHeader *pHeader = pMD->GetCallStub(); if (pHeader == NULL) { - CallStubGenerator callStubGenerator; - GCX_PREEMP(); + pHeader = UpdateCallStubForMethod(pMD); + } - AllocMemTracker amTracker; - pHeader = callStubGenerator.GenerateCallStub(pMD, &amTracker, true /* interpreterToNative */); + // Interpreter-FIXME: Potential race condition if a single CallStubHeader is reused for multiple targets. + pHeader->SetTarget(target); // The method to call - if (pMD->SetCallStub(pHeader)) - { - amTracker.SuppressRelease(); - } - else - { - // We have lost the race for generating the header, use the one that was generated by another thread - // and let the amTracker release the memory of the one we generated. - pHeader = pMD->GetCallStub(); - } + pHeader->Invoke(pHeader->Routines, pArgs, pRet, pHeader->TotalStackSize); +} + +void InvokeDelegateInvokeMethod(MethodDesc *pMDDelegateInvoke, int8_t *pArgs, int8_t *pRet, PCODE target) +{ + CONTRACTL + { + THROWS; + MODE_ANY; + PRECONDITION(CheckPointer(pMDDelegateInvoke)); + PRECONDITION(CheckPointer(pArgs)); + PRECONDITION(CheckPointer(pRet)); } + CONTRACTL_END - pHeader->SetTarget(pMD->GetMultiCallableAddrOfCode()); // The method to call + CallStubHeader *stubHeaderTemplate = pMDDelegateInvoke->GetCallStub(); + if (stubHeaderTemplate == NULL) + { + stubHeaderTemplate = UpdateCallStubForMethod(pMDDelegateInvoke); + } + // CallStubHeaders encode their destination addresses in the Routines array, so they need to be + // copied to a local buffer before we can actually set their target address. + size_t templateSize = stubHeaderTemplate->GetSize(); + uint8_t* actualCallStub = (uint8_t*)alloca(templateSize); + memcpy(actualCallStub, stubHeaderTemplate, templateSize); + CallStubHeader *pHeader = (CallStubHeader*)actualCallStub; + pHeader->SetTarget(target); // The method to call pHeader->Invoke(pHeader->Routines, pArgs, pRet, pHeader->TotalStackSize); } @@ -77,7 +129,6 @@ CallStubHeader *CreateNativeToInterpreterCallStub(InterpMethod* pInterpMethod) CallStubHeader *pHeader = VolatileLoadWithoutBarrier(&pInterpMethod->pCallStub); GCX_PREEMP(); - AllocMemTracker amTracker; if (pHeader == NULL) { // Ensure that there is an interpreter thread context instance and thus an interpreter stack @@ -105,6 +156,8 @@ CallStubHeader *CreateNativeToInterpreterCallStub(InterpMethod* pInterpMethod) return pHeader; } +#endif // !TARGET_WASM + typedef void* (*HELPER_FTN_P_P)(void*); typedef void* (*HELPER_FTN_BOX_UNBOX)(MethodTable*, void*); typedef Object* (*HELPER_FTN_NEWARR)(MethodTable*, intptr_t); @@ -160,13 +213,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_INDIRECT_HELPER_TAG) - return *(THelper *)(helperDirectOrIndirect & ~INTERP_INDIRECT_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 @@ -268,18 +331,44 @@ template static void ConvOvfFpHelperU64(int8_t *stack, const template void ConvOvfHelper(int8_t *stack, const int32_t *ip) { - static_assert(sizeof(TResult) < sizeof(TSource), "ConvOvfHelper only can convert to results smaller than the source value"); static_assert(std::numeric_limits::is_integer, "ConvOvfHelper is only for use on integers"); + constexpr bool shrinking = sizeof(TResult) < sizeof(TSource); TSource src = LOCAL_VAR(ip[2], TSource); bool inRange; - if (std::numeric_limits::is_signed) + if (shrinking) { - inRange = (src >= (TSource)std::numeric_limits::lowest()) && (src <= (TSource)std::numeric_limits::max()); + if (std::numeric_limits::is_signed) + inRange = (src >= (TSource)std::numeric_limits::lowest()) && (src <= (TSource)std::numeric_limits::max()); + else + inRange = (src <= (TSource)std::numeric_limits::max()); } else { - inRange = (src <= (TSource)std::numeric_limits::max()); + // Growing conversions with the same signedness shouldn't use an ovf opcode. + static_assert( + shrinking || (std::numeric_limits::is_signed != std::numeric_limits::is_signed), + "ConvOvfHelper only does growing conversions with sign changes" + ); + + if (std::numeric_limits::is_signed) + { + if (sizeof(TSource) == sizeof(TResult)) + { + // unsigned -> signed conv with same size. check to make sure the source value isn't too big. + inRange = src <= (TSource)std::numeric_limits::max(); + } + else + { + // growing unsigned -> signed conversion. this can never fail. + inRange = true; + } + } + else + { + // signed -> unsigned conv. check to make sure the source value isn't negative. + inRange = src >= 0; + } } if (inRange) @@ -289,7 +378,10 @@ template void ConvOvfHelper(int8_t *stack, // The spec says that conversion results are stored on the evaluation stack as signed, so we always want to convert // the final truncated result into int32_t before storing it on the stack, even if the truncated result is unsigned. TResult result = (TResult)src; - LOCAL_VAR(ip[1], int32_t) = (int32_t)result; + if (sizeof (TResult) < 4) + LOCAL_VAR(ip[1], int32_t) = (int32_t)result; + else + LOCAL_VAR(ip[1], TResult) = result; } else { @@ -300,7 +392,7 @@ template void ConvOvfHelper(int8_t *stack, void* DoGenericLookup(void* genericVarAsPtr, InterpGenericLookup* pLookup) { // TODO! If this becomes a performance bottleneck, we could expand out the various permutations of this - // so that we have 24 versions of lookup (or 48 is we allow for avoiding the null check), do the only + // so that we have 24 versions of lookup (or 48 is we allow for avoiding the null check), do the only // if check to figure out which one to use, and then have the rest of the logic be straight-line code. MethodTable *pMT = nullptr; MethodDesc* pMD = nullptr; @@ -477,6 +569,10 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr LOCAL_VAR(ip[1], void*) = *(void**)pMethod->pDataItems[ip[2]]; ip += 3; break; + case INTOP_NULLCHECK: + NULL_CHECK(LOCAL_VAR(ip[1], void*)); + ip += 2; + break; case INTOP_RET: // Return stack slot sized value *(int64_t*)pFrame->pRetVal = LOCAL_VAR(ip[1], int64_t); @@ -645,6 +741,10 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr LOCAL_VAR(ip[1], double) = (double)LOCAL_VAR(ip[2], float); ip += 3; break; + case INTOP_CONV_U8_U4: + LOCAL_VAR(ip[1], uint64_t) = LOCAL_VAR(ip[2], uint32_t); + ip += 3; + break; case INTOP_CONV_U8_R4: ConvFpHelper(stack, ip); ip += 3; @@ -722,6 +822,10 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr ip += 3; break; + case INTOP_CONV_OVF_I4_U4: + ConvOvfHelper(stack, ip); + ip += 3; + break; case INTOP_CONV_OVF_I4_I8: ConvOvfHelper(stack, ip); ip += 3; @@ -735,6 +839,10 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr ip += 3; break; + case INTOP_CONV_OVF_U4_I4: + ConvOvfHelper(stack, ip); + ip += 3; + break; case INTOP_CONV_OVF_U4_I8: ConvOvfHelper(stack, ip); ip += 3; @@ -748,6 +856,10 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr ip += 3; break; + case INTOP_CONV_OVF_I8_U8: + ConvOvfHelper(stack, ip); + ip += 3; + break; case INTOP_CONV_OVF_I8_R4: ConvOvfFpHelperI64(stack, ip); ip += 3; @@ -757,6 +869,14 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr ip += 3; break; + case INTOP_CONV_OVF_U8_I4: + ConvOvfHelper(stack, ip); + ip += 3; + break; + case INTOP_CONV_OVF_U8_I8: + ConvOvfHelper(stack, ip); + ip += 3; + break; case INTOP_CONV_OVF_U8_R4: ConvOvfFpHelperU64(stack, ip); ip += 3; @@ -766,6 +886,52 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr ip += 3; break; + case INTOP_CONV_OVF_I1_U4: + ConvOvfHelper(stack, ip); + ip += 3; + break; + case INTOP_CONV_OVF_I1_U8: + ConvOvfHelper(stack, ip); + ip += 3; + break; + + case INTOP_CONV_OVF_U1_U4: + ConvOvfHelper(stack, ip); + ip += 3; + break; + case INTOP_CONV_OVF_U1_U8: + ConvOvfHelper(stack, ip); + ip += 3; + break; + + case INTOP_CONV_OVF_I2_U4: + ConvOvfHelper(stack, ip); + ip += 3; + break; + case INTOP_CONV_OVF_I2_U8: + ConvOvfHelper(stack, ip); + ip += 3; + break; + + case INTOP_CONV_OVF_U2_U4: + ConvOvfHelper(stack, ip); + ip += 3; + break; + case INTOP_CONV_OVF_U2_U8: + ConvOvfHelper(stack, ip); + ip += 3; + break; + + case INTOP_CONV_OVF_I4_U8: + ConvOvfHelper(stack, ip); + ip += 3; + break; + + case INTOP_CONV_OVF_U4_U8: + ConvOvfHelper(stack, ip); + ip += 3; + break; + case INTOP_SWITCH: { uint32_t val = LOCAL_VAR(ip[1], uint32_t); @@ -1438,7 +1604,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr ip += 4; break; case INTOP_CGT_UN_I8: - LOCAL_VAR(ip[1], int32_t) = LOCAL_VAR(ip[2], uint32_t) > LOCAL_VAR(ip[3], uint32_t); + LOCAL_VAR(ip[1], int32_t) = LOCAL_VAR(ip[2], uint64_t) > LOCAL_VAR(ip[3], uint64_t); ip += 4; break; case INTOP_CGT_UN_R4: @@ -1589,7 +1755,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); @@ -1599,8 +1765,8 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_P_S: { - HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[2]]); - void* helperArg = LOCAL_VAR(ip[3], void*); + HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod, ip[3]); + void* helperArg = LOCAL_VAR(ip[2], void*); LOCAL_VAR(ip[1], void*) = helperFtn(helperArg); ip += 4; @@ -1609,7 +1775,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*)); @@ -1619,7 +1785,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); @@ -1632,7 +1798,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; @@ -1644,7 +1810,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; @@ -1656,7 +1822,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; @@ -1664,7 +1830,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; @@ -1676,7 +1842,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; @@ -1684,7 +1850,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; @@ -1724,6 +1890,65 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr break; } + case INTOP_CALL_PINVOKE: + { + // This opcode handles p/invokes that don't use a managed wrapper for marshaling. These + // calls are special in that they need an InlinedCallFrame in order for proper EH to happen + + returnOffset = ip[1]; + callArgsOffset = ip[2]; + methodSlot = ip[3]; + int32_t targetAddrSlot = ip[4]; + int32_t flags = ip[5]; + + ip += 6; + targetMethod = (MethodDesc*)pMethod->pDataItems[methodSlot]; + PCODE callTarget = (flags & (int32_t)PInvokeCallFlags::Indirect) + ? *(PCODE *)pMethod->pDataItems[targetAddrSlot] + : (PCODE)pMethod->pDataItems[targetAddrSlot]; + + InlinedCallFrame inlinedCallFrame; + inlinedCallFrame.m_pCallerReturnAddress = (TADDR)ip; + inlinedCallFrame.m_pCallSiteSP = pFrame; + inlinedCallFrame.m_pCalleeSavedFP = (TADDR)stack; + inlinedCallFrame.m_pThread = GetThread(); + inlinedCallFrame.m_Datum = NULL; + inlinedCallFrame.Push(); + + { + GCX_MAYBE_PREEMP(!(flags & (int32_t)PInvokeCallFlags::SuppressGCTransition)); + InvokeCompiledMethod(targetMethod, stack + callArgsOffset, stack + returnOffset, callTarget); + } + + inlinedCallFrame.Pop(); + + break; + } + + case INTOP_CALLDELEGATE: + { + returnOffset = ip[1]; + callArgsOffset = ip[2]; + methodSlot = ip[3]; + + // targetMethod holds a pointer to the Invoke method of the delegate, not the final actual target. + targetMethod = (MethodDesc*)pMethod->pDataItems[methodSlot]; + + ip += 4; + + DELEGATEREF delegateObj = LOCAL_VAR(callArgsOffset, DELEGATEREF); + NULL_CHECK(delegateObj); + PCODE targetAddress = delegateObj->GetMethodPtr(); + OBJECTREF targetMethodObj = delegateObj->GetTarget(); + LOCAL_VAR(callArgsOffset, OBJECTREF) = targetMethodObj; + + // TODO! Once we are investigating performance here, we may want to optimize this so that + // delegate calls to interpeted methods don't have to go through the native invoke here, but for + // now this should work well. + InvokeDelegateInvokeMethod(targetMethod, stack + callArgsOffset, stack + returnOffset, targetAddress); + break; + } + case INTOP_CALL: { returnOffset = ip[1]; @@ -1748,7 +1973,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr pInterpreterFrame->SetTopInterpMethodContextFrame(pFrame); GCX_PREEMP(); // Attempt to setup the interpreter code for the target method. - if (targetMethod->IsIL() || targetMethod->IsNoMetadata()) + if ((targetMethod->IsIL() || targetMethod->IsNoMetadata()) && !targetMethod->IsUnboxingStub()) { targetMethod->PrepareInitialCode(CallerGCMode::Coop); } @@ -1757,7 +1982,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr if (targetIp == NULL) { // If we didn't get the interpreter code pointer setup, then this is a method we need to invoke as a compiled method. - InvokeCompiledMethod(targetMethod, stack + callArgsOffset, stack + returnOffset); + InvokeCompiledMethod(targetMethod, stack + callArgsOffset, stack + returnOffset, targetMethod->GetMultiCallableAddrOfCode(CORINFO_ACCESS_ANY)); break; } } @@ -1845,8 +2070,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; @@ -1857,6 +2080,18 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr memset(LOCAL_VAR(ip[1], void*), 0, ip[2]); ip += 3; break; + case INTOP_CPBLK: + { + void* dst = LOCAL_VAR(ip[1], void*); + void* src = LOCAL_VAR(ip[2], void*); + uint32_t size = LOCAL_VAR(ip[3], uint32_t); + if (size && (!dst || !src)) + COMPlusThrow(kNullReferenceException); + else + memcpyNoGCRefs(dst, src, size); + ip += 4; + break; + } case INTOP_LOCALLOC: { size_t len = LOCAL_VAR(ip[2], size_t); @@ -1879,18 +2114,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; @@ -1926,7 +2149,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) @@ -1946,7 +2169,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*); @@ -1963,7 +2186,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); @@ -1980,7 +2203,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); @@ -2059,7 +2282,7 @@ do { \ COMPlusThrow(kIndexOutOfRangeException); uint8_t* pData = arr->GetDataPtr(); - OBJECTREF elemRef = *(OBJECTREF*)(pData + idx * sizeof(OBJECTREF)); + OBJECTREF elemRef = ObjectToOBJECTREF(*(Object**)(pData + idx * sizeof(OBJECTREF))); LOCAL_VAR(ip[1], OBJECTREF) = elemRef; ip += 4; break; @@ -2236,11 +2459,38 @@ do { \ COMPlusThrow(kIndexOutOfRangeException); uint8_t* pData = arr->GetDataPtr(); - size_t elemSize = ip[4]; - void* elemAddr = pData + idx * elemSize; + void* elemAddr = pData + idx * sizeof(void*); MethodTable* arrayElemMT = arr->GetArrayElementTypeHandle().AsMethodTable(); - MethodTable* expectedMT = (MethodTable*)pMethod->pDataItems[ip[5]]; + MethodTable* expectedMT = (MethodTable*)pMethod->pDataItems[ip[4]]; + if (arrayElemMT != expectedMT) + { + COMPlusThrow(kArrayTypeMismatchException); + } + + LOCAL_VAR(ip[1], void*) = elemAddr; + ip += 5; + break; + } + + case INTOP_LDELEMA_REF_GENERIC: + { + BASEARRAYREF arrayRef = LOCAL_VAR(ip[2], BASEARRAYREF); + if (arrayRef == NULL) + COMPlusThrow(kNullReferenceException); + + ArrayBase* arr = (ArrayBase*)OBJECTREFToObject(arrayRef); + uint32_t len = arr->GetNumComponents(); + uint32_t idx = (uint32_t)LOCAL_VAR(ip[3], int32_t); + if (idx >= len) + COMPlusThrow(kIndexOutOfRangeException); + + uint8_t* pData = arr->GetDataPtr(); + void* elemAddr = pData + idx * sizeof(void*); + + MethodTable* arrayElemMT = arr->GetArrayElementTypeHandle().AsMethodTable(); + InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[5]]; + MethodTable* expectedMT = (MethodTable*)DoGenericLookup(LOCAL_VAR(ip[4], void*), pLookup); if (arrayElemMT != expectedMT) { COMPlusThrow(kArrayTypeMismatchException); @@ -2261,6 +2511,29 @@ do { \ break; } +#define COMPARE_EXCHANGE(type) \ +do \ +{ \ + type* dst = (type*)LOCAL_VAR(ip[2], void*); \ + NULL_CHECK(dst); \ + type newValue = LOCAL_VAR(ip[3], type); \ + type comparand = LOCAL_VAR(ip[4], type); \ + type old = InterlockedCompareExchangeT(dst, newValue, comparand); \ + LOCAL_VAR(ip[1], type) = old; \ + ip += 5; \ +} while (0) + case INTOP_COMPARE_EXCHANGE_I4: + { + COMPARE_EXCHANGE(int32_t); + break; + } + + case INTOP_COMPARE_EXCHANGE_I8: + { + COMPARE_EXCHANGE(int64_t); + break; + } + case INTOP_CALL_FINALLY: { const int32_t* targetIp = ip + ip[1]; @@ -2292,11 +2565,11 @@ do { \ case INTOP_LEAVE_CATCH: *(const int32_t**)pFrame->pRetVal = ip + ip[1]; goto EXIT_FRAME; - case INTOP_FAILFAST: - assert(0); + case INTOP_THROW_PNSE: + COMPlusThrow(kPlatformNotSupportedException); break; default: - assert(0); + assert(!"Unimplemented or invalid interpreter opcode"); break; } } diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index d14f3155e5310f..b93e15ad331e78 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -1176,7 +1176,7 @@ void JIT_PInvokeEndRarePath() } /*************************************************************/ -// For an inlined N/Direct call (and possibly for other places that need this service) +// For an inlined PInvoke call (and possibly for other places that need this service) // we have noticed that the returning thread should trap for one reason or another. // ECall sets up the frame. diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 7e818028899d9f..f7a238c5ce7373 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -49,6 +49,7 @@ #ifdef HAVE_GCCOVER #include "gccover.h" #endif // HAVE_GCCOVER +#include "debugdebugger.h" #ifdef FEATURE_PERFMAP #include "perfmap.h" @@ -477,19 +478,26 @@ static void ConvToJitSig( uint32_t data; IfFailThrow(sig.GetCallingConvInfo(&data)); - sigRet->callConv = (CorInfoCallConv) data; #if defined(TARGET_UNIX) || defined(TARGET_ARM) - if ((isCallConv(sigRet->callConv, IMAGE_CEE_CS_CALLCONV_VARARG)) || - (isCallConv(sigRet->callConv, IMAGE_CEE_CS_CALLCONV_NATIVEVARARG))) + if ((isCallConv(data, IMAGE_CEE_CS_CALLCONV_VARARG)) || + (isCallConv(data, IMAGE_CEE_CS_CALLCONV_NATIVEVARARG))) { // This signature corresponds to a method that uses varargs, which are not supported. COMPlusThrow(kInvalidProgramException, IDS_EE_VARARG_NOT_SUPPORTED); } #endif // defined(TARGET_UNIX) || defined(TARGET_ARM) + // We have an internal calling convention for async used for signatures + // in IL stubs. Translate that to the flag representation in + // CorInfoCallConv. + if (isCallConv(data, IMAGE_CEE_CS_CALLCONV_ASYNC)) + sigRet->callConv = (CorInfoCallConv)(CORINFO_CALLCONV_DEFAULT | CORINFO_CALLCONV_ASYNCCALL | (data & ~IMAGE_CEE_CS_CALLCONV_MASK)); + else + sigRet->callConv = (CorInfoCallConv) data; + // Skip number of type arguments - if (sigRet->callConv & IMAGE_CEE_CS_CALLCONV_GENERIC) + if (data & IMAGE_CEE_CS_CALLCONV_GENERIC) IfFailThrow(sig.GetData(NULL)); uint32_t numArgs; @@ -1795,7 +1803,6 @@ CEEInfo::findSig( if (IsDynamicScope(scopeHnd)) { sig = GetDynamicResolver(scopeHnd)->ResolveSignature(sigTok); - sigTok = mdTokenNil; } else { @@ -6137,6 +6144,7 @@ CorInfoHelpFunc CEEInfo::getBoxHelper(CORINFO_CLASS_HANDLE clsHnd) // registers a vararg sig & returns a class-specific cookie for it. CORINFO_VARARGS_HANDLE CEEInfo::getVarArgsHandle(CORINFO_SIG_INFO *sig, + CORINFO_METHOD_HANDLE methHnd, void **ppIndirection) { CONTRACTL { @@ -6165,12 +6173,6 @@ CORINFO_VARARGS_HANDLE CEEInfo::getVarArgsHandle(CORINFO_SIG_INFO *sig, return result; } -bool CEEInfo::canGetVarArgsHandle(CORINFO_SIG_INFO *sig) -{ - LIMITED_METHOD_CONTRACT; - return true; -} - /***********************************************************************/ unsigned CEEInfo::getMethodHash (CORINFO_METHOD_HANDLE ftnHnd) { @@ -6500,7 +6502,7 @@ DWORD CEEInfo::getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftn) result |= CORINFO_FLG_SHAREDINST; } - if (pMD->IsNDirect()) + if (pMD->IsPInvoke()) { result |= CORINFO_FLG_PINVOKE; } @@ -7679,20 +7681,17 @@ CEEInfo::getMethodInfo( JIT_TO_EE_TRANSITION(); MethodDesc* ftn = GetMethod(ftnHnd); - if (ftn->IsDynamicMethod()) - { - getMethodInfoWorker(ftn, NULL, methInfo, context); - result = true; - } - else if (!ftn->IsWrapperStub() && ftn->HasILHeader()) + COR_ILMETHOD* pILHeader; + if (ftn->MayHaveILHeader() && (pILHeader = ftn->GetILHeader()) != NULL) { // Get the IL header and set it. - COR_ILMETHOD_DECODER header(ftn->GetILHeader(), ftn->GetMDImport(), NULL); + COR_ILMETHOD_DECODER header(pILHeader, ftn->GetMDImport(), NULL); getMethodInfoWorker(ftn, &header, methInfo, context); result = true; } - else if (ftn->IsIL() && ftn->GetRVA() == 0) // IL methods with no RVA indicate there is no implementation defined in metadata. + else if (ftn->IsIL() || ftn->IsDynamicMethod()) { + // IL methods with no IL header indicate there is no implementation defined in metadata. getMethodInfoWorker(ftn, NULL, methInfo, context); result = true; } @@ -7864,9 +7863,10 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller, if (pRootModule->IsRuntimeWrapExceptions() != pCalleeModule->IsRuntimeWrapExceptions()) { - if (pCallee->HasILHeader()) + COR_ILMETHOD* pILHeader; + if (pCallee->MayHaveILHeader() && (pILHeader = pCallee->GetILHeader()) != NULL) { - COR_ILMETHOD_DECODER header(pCallee->GetILHeader(), pCallee->GetMDImport(), NULL); + COR_ILMETHOD_DECODER header(pILHeader, pCallee->GetMDImport(), NULL); if (header.EHCount() > 0) { result = INLINE_FAIL; @@ -7874,7 +7874,7 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller, goto exit; } } - else if (pCallee->IsIL() && pCallee->GetRVA() == 0) + else if (pCallee->IsIL()) { CORINFO_METHOD_INFO methodInfo; getMethodInfoWorker(pCallee, NULL, &methodInfo); @@ -8663,7 +8663,7 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info) else if (pObjMT->IsSharedByGenericInstantiations() || pBaseMT->IsSharedByGenericInstantiations()) { MethodTable* pCanonBaseMT = pBaseMT->GetCanonicalMethodTable(); - + // Check to see if the derived class implements multiple variants of a matching interface. // If so, we cannot predict exactly which implementation is in use here. MethodTable::InterfaceMapIterator it = pObjMT->IterateInterfaceMap(); @@ -8686,7 +8686,7 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info) } } } - + if (canonicallyMatchingInterfacesFound == 0) { // The object doesn't implement the interface... @@ -9132,7 +9132,17 @@ void CEEInfo::getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftnHnd, // Resolve methodImpl. ftn = ftn->GetMethodTable()->MapMethodDeclToMethodImpl(ftn); - if (!ftn->IsFCall() && ftn->IsVersionableWithPrecode() && (ftn->GetPrecodeType() == PRECODE_FIXUP) && !ftn->IsPointingToStableNativeCode()) + if (ftn->IsFCall()) + { + // FCalls can be called directly + ret = (void*)ECall::GetFCallImpl(ftn, false /* throwForInvalidFCall */); + if (ret == NULL) + { + ret = ((FixupPrecode*)ftn->GetOrCreatePrecode())->GetTargetSlot(); + accessType = IAT_PVALUE; + } + } + else if (ftn->IsVersionableWithPrecode() && (ftn->GetPrecodeType() == PRECODE_FIXUP) && !ftn->IsPointingToStableNativeCode()) { ret = ((FixupPrecode*)ftn->GetOrCreatePrecode())->GetTargetSlot(); accessType = IAT_PVALUE; @@ -9868,11 +9878,11 @@ namespace if (methodCallConv == CORINFO_CALLCONV_DEFAULT || methodCallConv == CORINFO_CALLCONV_VARARG) { - _ASSERTE(pMD->IsNDirect() || pMD->HasUnmanagedCallersOnlyAttribute()); - if (pMD->IsNDirect()) + _ASSERTE(pMD->IsPInvoke() || pMD->HasUnmanagedCallersOnlyAttribute()); + if (pMD->IsPInvoke()) { CorInfoCallConvExtension unmanagedCallConv; - NDirect::GetCallingConvention_IgnoreErrors(pMD, &unmanagedCallConv, pSuppressGCTransition); + PInvoke::GetCallingConvention_IgnoreErrors(pMD, &unmanagedCallConv, pSuppressGCTransition); return unmanagedCallConv; } else @@ -9952,7 +9962,7 @@ bool CEEInfo::pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SI // check the call site signature SigTypeContext typeContext; GetTypeContext(&callSiteSig->sigInst, &typeContext); - result = NDirect::MarshalingRequired( + result = PInvoke::MarshalingRequired( NULL, SigPointer{ callSiteSig->pSig, callSiteSig->cbSig }, GetModule(callSiteSig->scope), @@ -9961,13 +9971,13 @@ bool CEEInfo::pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SI else { MethodDesc* ftn = GetMethod(method); - _ASSERTE(ftn->IsNDirect()); - NDirectMethodDesc *pMD = (NDirectMethodDesc*)ftn; + _ASSERTE(ftn->IsPInvoke()); + PInvokeMethodDesc *pMD = (PInvokeMethodDesc*)ftn; -#if defined(HAS_NDIRECT_IMPORT_PRECODE) +#if defined(HAS_PINVOKE_IMPORT_PRECODE) if (pMD->IsVarArg()) { - // Varag P/Invoke must not be inlined because its NDirectMethodDesc + // Varag P/Invoke must not be inlined because its PInvokeMethodDesc // does not contain a meaningful stack size (it is call site specific). // See code:InlinedCallFrame.UpdateRegDisplay where this is needed. result = TRUE; @@ -9984,7 +9994,7 @@ bool CEEInfo::pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SI } #else // Marshalling is required to lazy initialize the indirection cell - // without NDirectImportPrecode. + // without PInvokeImportPrecode. result = TRUE; #endif } @@ -10016,16 +10026,9 @@ LPVOID CEEInfo::GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, { WRAPPER_NO_CONTRACT; - return getVarArgsHandle(szMetaSig, ppIndirection); + return getVarArgsHandle(szMetaSig, NULL, ppIndirection); } -bool CEEInfo::canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig) -{ - LIMITED_METHOD_CONTRACT; - return true; -} - - // Check any constraints on method type arguments bool CEEInfo::satisfiesMethodConstraints( CORINFO_CLASS_HANDLE parent, @@ -10052,7 +10055,7 @@ bool CEEInfo::satisfiesMethodConstraints( /*********************************************************************/ -// return address of fixup area for late-bound N/Direct calls. +// return address of fixup area for late-bound PInvoke calls. void CEEInfo::getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP *pLookup) { @@ -10065,12 +10068,12 @@ void CEEInfo::getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, JIT_TO_EE_TRANSITION(); MethodDesc* pMD = GetMethod(method); - _ASSERTE(pMD->IsNDirect()); + _ASSERTE(pMD->IsPInvoke()); - NDirectMethodDesc* pNMD = reinterpret_cast(pMD); + PInvokeMethodDesc* pNMD = reinterpret_cast(pMD); void* pIndirection; - if (NDirectMethodDesc::TryGetResolvedNDirectTarget(pNMD, &pIndirection)) + if (PInvokeMethodDesc::TryGetResolvedPInvokeTarget(pNMD, &pIndirection)) { pLookup->accessType = IAT_VALUE; pLookup->addr = pIndirection; @@ -10078,7 +10081,7 @@ void CEEInfo::getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, else { pLookup->accessType = IAT_PVALUE; - pLookup->addr = (LPVOID)&(pNMD->ndirect.m_pNDirectTarget); + pLookup->addr = (LPVOID)&(pNMD->m_pPInvokeTarget); } EE_TO_JIT_TRANSITION(); @@ -10256,6 +10259,9 @@ void CEEInfo::getAsyncInfo(CORINFO_ASYNC_INFO* pAsyncInfoOut) pAsyncInfoOut->continuationsNeedMethodHandle = m_pMethodBeingCompiled->GetLoaderAllocator()->CanUnload(); pAsyncInfoOut->captureExecutionContextMethHnd = CORINFO_METHOD_HANDLE(CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__CAPTURE_EXECUTION_CONTEXT)); pAsyncInfoOut->restoreExecutionContextMethHnd = CORINFO_METHOD_HANDLE(CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__RESTORE_EXECUTION_CONTEXT)); + pAsyncInfoOut->captureContinuationContextMethHnd = CORINFO_METHOD_HANDLE(CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__CAPTURE_CONTINUATION_CONTEXT)); + pAsyncInfoOut->captureContextsMethHnd = CORINFO_METHOD_HANDLE(CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__CAPTURE_CONTEXTS)); + pAsyncInfoOut->restoreContextsMethHnd = CORINFO_METHOD_HANDLE(CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__RESTORE_CONTEXTS)); EE_TO_JIT_TRANSITION(); } @@ -10721,8 +10727,6 @@ CEECodeGenInfo::CEECodeGenInfo(PrepareCodeConfig* config, MethodDesc* fd, COR_IL , m_pCodeHeap(NULL) , m_ILHeader(header) , m_MethodInfo() - , m_GCinfo_len(0) - , m_EHinfo_len(0) , m_iOffsetMapping(0) , m_pOffsetMapping(NULL) , m_iNativeVarInfo(0) @@ -10844,7 +10848,9 @@ void CEECodeGenInfo::getHelperFtn(CorInfoHelpFunc ftnNum, /* IN activeCodeVersion = manager->GetActiveILCodeVersion(helperMD).GetActiveNativeCodeVersion(helperMD); } - if (activeCodeVersion.IsFinalTier()) + // activeCodeVersion may be a null version if the current active ILCodeVersion + // does not have an associated NativeCodeVersion + if (!activeCodeVersion.IsNull() && activeCodeVersion.IsFinalTier()) { finalTierAddr = (LPVOID)activeCodeVersion.GetNativeCode(); if (finalTierAddr != NULL) @@ -11012,23 +11018,6 @@ void CEEJitInfo::PublishFinalCodeAddress(PCODE addr) } } -/*********************************************************************/ -void CEEJitInfo::BackoutJitData(EECodeGenManager * jitMgr) -{ - CONTRACTL { - NOTHROW; - GC_TRIGGERS; - } CONTRACTL_END; - - // The RemoveJitData call below requires the m_CodeHeader to be valid, so we need to write - // the code bytes to the target memory location. - WriteCodeBytes(); - - CodeHeader* pCodeHeader = (CodeHeader*)m_CodeHeader; - if (pCodeHeader) - jitMgr->RemoveJitData(pCodeHeader, m_GCinfo_len, m_EHinfo_len); -} - template void CEECodeGenInfo::NibbleMapSet() { @@ -11056,11 +11045,11 @@ void CEEJitInfo::WriteCode(EECodeGenManager * jitMgr) // Now that the code header was written to the final location, publish the code via the nibble map NibbleMapSet(); -#if defined(TARGET_AMD64) +#if defined(FEATURE_EH_FUNCLETS) // Publish the new unwind information in a way that the ETW stack crawler can find _ASSERTE(m_usedUnwindInfos == m_totalUnwindInfos); UnwindInfoTable::PublishUnwindInfoForMethod(m_moduleBase, ((CodeHeader*)m_CodeHeader)->GetUnwindInfo(0), m_totalUnwindInfos); -#endif // defined(TARGET_AMD64) +#endif // defined(FEATURE_EH_FUNCLETS) } /*********************************************************************/ @@ -11205,9 +11194,11 @@ LPVOID CEEInfo::GetCookieForInterpreterCalliSig(CORINFO_SIG_INFO* szMetaSig) #ifdef FEATURE_INTERPRETER + LPVOID CInterpreterJitInfo::GetCookieForInterpreterCalliSig(CORINFO_SIG_INFO* szMetaSig) { void* result = NULL; +#ifndef TARGET_WASM JIT_TO_EE_TRANSITION(); Module* module = GetModule(szMetaSig->scope); @@ -11221,7 +11212,9 @@ LPVOID CInterpreterJitInfo::GetCookieForInterpreterCalliSig(CORINFO_SIG_INFO* sz result = callStubGenerator.GenerateCallStubForSig(sig); EE_TO_JIT_TRANSITION(); - +#else + PORTABILITY_ASSERT("GetCookieForInterpreterCalliSig is not supported on wasm yet"); +#endif // !TARGET_WASM return result; } @@ -11262,7 +11255,7 @@ void CInterpreterJitInfo::allocMem(AllocMemArgs *pArgs) pArgs->hotCodeSize, pArgs->roDataSize, totalSize.Value(), pArgs->flag, GetClrInstanceId()); } - m_jitManager->allocCode(m_pMethodBeingCompiled, totalSize.Value(), 0, pArgs->flag, &m_CodeHeader, &m_CodeHeaderRW, &m_codeWriteBufferSize, &m_pCodeHeap + m_jitManager->AllocCode(m_pMethodBeingCompiled, totalSize.Value(), 0, pArgs->flag, &m_CodeHeader, &m_CodeHeaderRW, &m_codeWriteBufferSize, &m_pCodeHeap , &m_pRealCodeHeader #ifdef FEATURE_EH_FUNCLETS , 0 @@ -11315,8 +11308,8 @@ void * CInterpreterJitInfo::allocGCInfo (size_t size) } #endif // HOST_64BIT - block = m_jitManager->allocFromJitMetaHeap(m_pMethodBeingCompiled,(DWORD)size, &m_GCinfo_len); - _ASSERTE(block); // allocFromJitMetaHeap throws if there's not enough memory + block = m_jitManager->AllocFromJitMetaHeap(m_pMethodBeingCompiled, size); + _ASSERTE(block); // AllocFromJitMetaHeap throws if there's not enough memory ((InterpreterCodeHeader*)m_CodeHeaderRW)->SetGCInfo(block); @@ -11359,22 +11352,6 @@ void CInterpreterJitInfo::WriteCodeBytes() SetRealCodeHeader(); } -void CInterpreterJitInfo::BackoutJitData(EECodeGenManager * jitMgr) -{ - CONTRACTL { - NOTHROW; - GC_TRIGGERS; - } CONTRACTL_END; - - // The RemoveJitData call below requires the m_CodeHeader to be valid, so we need to write - // the code bytes to the target memory location. - WriteCodeBytes(); - - InterpreterCodeHeader* pCodeHeader = (InterpreterCodeHeader*)m_CodeHeader; - if (pCodeHeader) - jitMgr->RemoveJitData(pCodeHeader, m_GCinfo_len, m_EHinfo_len); -} - void CInterpreterJitInfo::WriteCode(EECodeGenManager * jitMgr) { CONTRACTL { @@ -11393,7 +11370,7 @@ void CInterpreterJitInfo::SetDebugInfo(PTR_BYTE pDebugInfo) } #endif // FEATURE_INTERPRETER -void CEECodeGenInfo::CompressDebugInfo(PCODE nativeEntry) +void CEECodeGenInfo::CompressDebugInfo(PCODE nativeEntry, NativeCodeVersion nativeCodeVersion) { CONTRACTL { THROWS; @@ -11427,8 +11404,36 @@ void CEECodeGenInfo::CompressDebugInfo(PCODE nativeEntry) if (m_jitManager->IsStoringRichDebugInfo()) writeFlagByte = TRUE; + + const InstrumentedILOffsetMapping *pILOffsetMapping = NULL; + InstrumentedILOffsetMapping loadTimeMapping; +#ifdef FEATURE_REJIT + ILCodeVersion ilVersion; + + if (!nativeCodeVersion.IsNull()) + { + ilVersion = nativeCodeVersion.GetILCodeVersion(); + } + + // if there is a rejit IL map for this function, apply that in preference to load-time mapping + if (!ilVersion.IsNull() && !ilVersion.IsDefaultVersion()) + { + pILOffsetMapping = ilVersion.GetInstrumentedILMap(); + } + else + { +#endif + // if there is a profiler load-time mapping and not a rejit mapping, apply that instead + loadTimeMapping = + m_pMethodBeingCompiled->GetAssembly()->GetModule()->GetInstrumentedILOffsetMapping(m_pMethodBeingCompiled->GetMemberDef()); + if (!loadTimeMapping.IsNull()) + pILOffsetMapping = &loadTimeMapping; +#ifdef FEATURE_REJIT + } +#endif + PTR_BYTE pDebugInfo = CompressDebugInfo::CompressBoundariesAndVars( - m_pOffsetMapping, m_iOffsetMapping, + m_pOffsetMapping, m_iOffsetMapping, pILOffsetMapping, m_pNativeVarInfo, m_iNativeVarInfo, patchpointInfo, m_inlineTreeNodes, m_numInlineTreeNodes, @@ -11917,6 +11922,19 @@ void CEEJitInfo::recordRelocation(void * location, #endif // TARGET_LOONGARCH64 + +#ifdef TARGET_RISCV64 + case IMAGE_REL_RISCV64_PC: + { + _ASSERTE(addlDelta == 0); + + INT64 offset = (INT64)target - (INT64)location; + PutRiscV64AuipcItype((UINT32 *)locationRW, offset); + } + break; + +#endif // TARGET_RISCV64 + default: _ASSERTE(!"Unknown reloc type"); break; @@ -12360,41 +12378,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; @@ -12597,7 +12580,7 @@ void CEEJitInfo::allocMem (AllocMemArgs *pArgs) pArgs->hotCodeSize + pArgs->coldCodeSize, pArgs->roDataSize, totalSize.Value(), pArgs->flag, GetClrInstanceId()); } - m_jitManager->allocCode(m_pMethodBeingCompiled, totalSize.Value(), GetReserveForJumpStubs(), pArgs->flag, &m_CodeHeader, &m_CodeHeaderRW, &m_codeWriteBufferSize, &m_pCodeHeap + m_jitManager->AllocCode(m_pMethodBeingCompiled, totalSize.Value(), GetReserveForJumpStubs(), pArgs->flag, &m_CodeHeader, &m_CodeHeaderRW, &m_codeWriteBufferSize, &m_pCodeHeap , &m_pRealCodeHeader #ifdef FEATURE_EH_FUNCLETS , m_totalUnwindInfos @@ -12667,8 +12650,8 @@ void * CEEJitInfo::allocGCInfo (size_t size) } #endif // HOST_64BIT - block = m_jitManager->allocFromJitMetaHeap(m_pMethodBeingCompiled,(DWORD)size, &m_GCinfo_len); - _ASSERTE(block); // allocFromJitMetaHeap throws if there's not enough memory + block = m_jitManager->AllocFromJitMetaHeap(m_pMethodBeingCompiled, size); + _ASSERTE(block); // AllocFromJitMetaHeap throws if there's not enough memory ((CodeHeader*)m_CodeHeaderRW)->SetGCInfo(block); @@ -12700,9 +12683,8 @@ void CEECodeGenInfo::setEHcountWorker(unsigned cEH) if (!ClrSafeInt::addition(temp, sizeof(size_t), blockSize)) COMPlusThrowOM(); - BYTE *pEHInfo = m_jitManager->allocFromJitMetaHeap(m_pMethodBeingCompiled, blockSize, &m_EHinfo_len); - _ASSERTE(pEHInfo); // allocFromJitMetaHeap throws if there's not enough memory - _ASSERTE(m_EHinfo_len != 0); + BYTE *pEHInfo = m_jitManager->AllocFromJitMetaHeap(m_pMethodBeingCompiled, blockSize); + _ASSERTE(pEHInfo); // AllocFromJitMetaHeap throws if there's not enough memory pCodeHeaderRW->SetEHInfo((EE_ILEXCEPTION*)(pEHInfo + sizeof(size_t))); pCodeHeaderRW->GetEHInfo()->Init(cEH); @@ -12752,7 +12734,7 @@ void CEECodeGenInfo::setEHinfoWorker( LOG((LF_EH, LL_INFO1000000, " FilterOffset : 0x%08lx -> 0x%08lx\n", clause->FilterOffset, pEHClause->FilterOffset)); if (IsDynamicScope(m_MethodInfo.scope) && - ((pEHClause->Flags & COR_ILEXCEPTION_CLAUSE_FILTER) == 0) && + ((pEHClause->Flags & (COR_ILEXCEPTION_CLAUSE_FILTER | COR_ILEXCEPTION_CLAUSE_FINALLY | COR_ILEXCEPTION_CLAUSE_FAULT)) == 0) && (clause->ClassToken != mdTokenNil)) { ResolvedToken resolved{}; @@ -12798,6 +12780,8 @@ void CEECodeGenInfo::getEHinfo( JIT_TO_EE_TRANSITION(); MethodDesc* pMD = GetMethod(ftn); + + COR_ILMETHOD* pILHeader; if (IsDynamicMethodHandle(ftn)) { pMD->AsDynamicMethodDesc()->GetResolver()->GetEHInfo(EHnumber, clause); @@ -12806,12 +12790,12 @@ void CEECodeGenInfo::getEHinfo( { getEHinfoHelper(ftn, EHnumber, clause, m_ILHeader); } - else if (pMD->HasILHeader()) + else if (pMD->MayHaveILHeader() && (pILHeader = pMD->GetILHeader()) != NULL) { - COR_ILMETHOD_DECODER header(pMD->GetILHeader(), pMD->GetMDImport(), NULL); + COR_ILMETHOD_DECODER header(pILHeader, pMD->GetMDImport(), NULL); getEHinfoHelper(ftn, EHnumber, clause, &header); } - else if (pMD->IsIL() && pMD->GetRVA() == 0) + else if (pMD->IsIL()) { TransientMethodDetails* details; if (!FindTransientMethodDetails(pMD, &details)) @@ -12832,7 +12816,8 @@ void CEECodeGenInfo::getEHinfo( static CorJitResult invokeCompileMethod(EECodeGenManager *jitMgr, CEECodeGenInfo *comp, BYTE **nativeEntry, - uint32_t *nativeSizeOfCode) + uint32_t *nativeSizeOfCode, + NativeCodeVersion nativeCodeVersion) { STANDARD_VM_CONTRACT; @@ -12855,7 +12840,6 @@ static CorJitResult invokeCompileMethod(EECodeGenManager *jitMgr, if (FAILED(ret)) { - comp->BackoutJitData(jitMgr); comp->ResetForJitRetry(); ret = CORJIT_SKIPPED; } @@ -12876,7 +12860,6 @@ static CorJitResult invokeCompileMethod(EECodeGenManager *jitMgr, nativeSizeOfCode); if (FAILED(ret)) { - comp->BackoutJitData(jitMgr); comp->ResetForJitRetry(); ret = CORJIT_SKIPPED; } @@ -12889,7 +12872,7 @@ static CorJitResult invokeCompileMethod(EECodeGenManager *jitMgr, // if (SUCCEEDED(ret) && !comp->JitAgain()) { - comp->CompressDebugInfo((PCODE)*nativeEntry); + comp->CompressDebugInfo((PCODE)*nativeEntry, nativeCodeVersion); comp->MethodCompileComplete(methodInfo->ftn); } @@ -13096,7 +13079,8 @@ static TADDR UnsafeJitFunctionWorker( res = invokeCompileMethod(pJitMgr, pJitInfo, &nativeEntry, - &sizeOfCode); + &sizeOfCode, + nativeCodeVersion); #if FEATURE_PERFMAP _ASSERTE(pSizeOfCode != NULL); @@ -13142,12 +13126,17 @@ static TADDR UnsafeJitFunctionWorker( if (g_pDebugInterface) { g_pDebugInterface->JITComplete(nativeCodeVersion, (TADDR)nativeEntry); + + // Validation currently disabled, see https://github.com/dotnet/runtime/issues/117561 + // +//#ifdef DEBUG +// ValidateILOffsets(ftn, NULL, 0, (uint8_t*)nativeEntry, sizeOfCode); +//#endif // DEBUG } #endif // DEBUGGING_SUPPORTED } else { - pJitInfo->BackoutJitData(pJitMgr); ThrowExceptionForJit(res); } @@ -13236,8 +13225,7 @@ class JumpStubOverflowCheck final #if defined(TARGET_AMD64) || defined(TARGET_ARM64) if (jitInfo.IsJumpStubOverflow()) { - // Backout and try again with fAllowRel32 == FALSE. - jitInfo.BackoutJitData(jitMgr); + // Try again with fAllowRel32 == FALSE. #if defined(TARGET_AMD64) // Disallow rel32 relocs in future. @@ -13694,7 +13682,7 @@ bool IsInstructionSetSupported(CORJIT_FLAGS jitFlags, ReadyToRunInstructionSet r BOOL LoadDynamicInfoEntry(Module *currentModule, RVA fixupRva, SIZE_T *entry, - BOOL mayUsePrecompiledNDirectMethods) + BOOL mayUsePrecompiledPInvokeMethods) { STANDARD_VM_CONTRACT; @@ -13832,20 +13820,20 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, { MethodDesc *pMethod = ZapSig::DecodeMethod(currentModule, pInfoModule, pBlob); - _ASSERTE(pMethod->IsNDirect()); - NDirectMethodDesc *pMD = (NDirectMethodDesc*)pMethod; - result = (size_t)(LPVOID)&(pMD->ndirect.m_pNDirectTarget); + _ASSERTE(pMethod->IsPInvoke()); + PInvokeMethodDesc *pMD = (PInvokeMethodDesc*)pMethod; + result = (size_t)(LPVOID)&(pMD->m_pPInvokeTarget); } break; case READYTORUN_FIXUP_PInvokeTarget: { - if (mayUsePrecompiledNDirectMethods) + if (mayUsePrecompiledPInvokeMethods) { MethodDesc *pMethod = ZapSig::DecodeMethod(currentModule, pInfoModule, pBlob); - _ASSERTE(pMethod->IsNDirect()); - result = (size_t)(LPVOID)NDirectMethodDesc::ResolveAndSetNDirectTarget((NDirectMethodDesc*)pMethod); + _ASSERTE(pMethod->IsPInvoke()); + result = (size_t)(LPVOID)PInvokeMethodDesc::ResolveAndSetPInvokeTarget((PInvokeMethodDesc*)pMethod); } else { @@ -14457,7 +14445,6 @@ static Signature BuildResumptionStubCalliSignature(MetaSig& msig, MethodTable* m auto appendTypeHandle = [](SigBuilder& sigBuilder, TypeHandle th) { - _ASSERTE(!th.IsByRef()); CorElementType ty = th.GetSignatureCorElementType(); if (CorTypeInfo::IsObjRef(ty)) { @@ -14494,12 +14481,12 @@ static Signature BuildResumptionStubCalliSignature(MetaSig& msig, MethodTable* m } #ifdef TARGET_X86 + sigBuilder.AppendElementType(ELEMENT_TYPE_OBJECT); // continuation + if (msig.HasGenericContextArg()) { sigBuilder.AppendElementType(ELEMENT_TYPE_I); } - - sigBuilder.AppendElementType(ELEMENT_TYPE_OBJECT); // continuation #endif return AllocateSignature(alloc, sigBuilder, pamTracker); @@ -14570,14 +14557,15 @@ CORINFO_METHOD_HANDLE CEEJitInfo::getAsyncResumptionStub() } #ifdef TARGET_X86 + // Continuation + pCode->EmitLDARG(0); + if (msig.HasGenericContextArg()) { pCode->EmitLDC(0); numArgs++; } - // Continuation - pCode->EmitLDARG(0); numArgs++; #endif @@ -14854,13 +14842,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/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index df07408dd942b3..8cc6c6773ed43b 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -84,7 +84,7 @@ void getMethodInfoILMethodHeaderHelper( BOOL LoadDynamicInfoEntry(Module *currentModule, RVA fixupRva, SIZE_T *entry, - BOOL mayUsePrecompiledNDirectMethods = TRUE); + BOOL mayUsePrecompiledPInvokeMethods = TRUE); // These must be implemented in assembly and generate a TransitionBlock then calling JIT_PatchpointWorkerWithPolicy in order to actually be used. EXTERN_C FCDECL2(void, JIT_Patchpoint, int* counter, int ilOffset); @@ -149,7 +149,7 @@ EXTERN_C FCDECL1(void*, JIT_GetDynamicNonGCStaticBaseNoCtor_Portable, DynamicSta EXTERN_C FCDECL1(Object*, RhpNewFast, CORINFO_CLASS_HANDLE typeHnd_); EXTERN_C FCDECL2(Object*, RhpNewArrayFast, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); EXTERN_C FCDECL2(Object*, RhpNewPtrArrayFast, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); -EXTERN_C FCDECL2(Object*, RhNewString, CORINFO_CLASS_HANDLE typeHnd_, DWORD stringLength); +EXTERN_C FCDECL2(Object*, RhNewString, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR stringLength); #if defined(FEATURE_64BIT_ALIGNMENT) EXTERN_C FCDECL1(Object*, RhpNewFastAlign8, CORINFO_CLASS_HANDLE typeHnd_); @@ -161,7 +161,7 @@ EXTERN_C FCDECL2(Object*, RhpNewArrayFastAlign8, CORINFO_CLASS_HANDLE typeHnd_, EXTERN_C FCDECL1(Object*, RhpNewFast_UP, CORINFO_CLASS_HANDLE typeHnd_); EXTERN_C FCDECL2(Object*, RhpNewArrayFast_UP, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); EXTERN_C FCDECL2(Object*, RhpNewPtrArrayFast_UP, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); -EXTERN_C FCDECL2(Object*, RhNewString_UP, CORINFO_CLASS_HANDLE typeHnd_, DWORD stringLength); +EXTERN_C FCDECL2(Object*, RhNewString_UP, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR stringLength); #endif EXTERN_C FCDECL1(Object*, RhpNew, CORINFO_CLASS_HANDLE typeHnd_); @@ -169,9 +169,6 @@ EXTERN_C FCDECL2(Object*, RhpNewVariableSizeObject, CORINFO_CLASS_HANDLE typeHnd EXTERN_C FCDECL1(Object*, RhpNewMaybeFrozen, CORINFO_CLASS_HANDLE typeHnd_); EXTERN_C FCDECL2(Object*, RhpNewArrayMaybeFrozen, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); -EXTERN_C FCDECL1(Object*, AllocateStringFast, DWORD stringLength); -EXTERN_C FCDECL1(Object*, AllocateStringSlow, DWORD stringLength); - EXTERN_C FCDECL2(void, JITutil_MonReliableEnter, Object* obj, BYTE* pbLockTaken); EXTERN_C FCDECL3(void, JITutil_MonTryEnter, Object* obj, INT32 timeOut, BYTE* pbLockTaken); EXTERN_C FCDECL2(void, JITutil_MonReliableContention, AwareLock* awarelock, BYTE* pbLockTaken); @@ -541,14 +538,12 @@ class CEECodeGenInfo : public CEEInfo m_numRichOffsetMappings = 0; } - virtual void BackoutJitData(EECodeGenManager * jitMgr) = 0; - // ICorDebugInfo stuff. void setBoundaries(CORINFO_METHOD_HANDLE ftn, ULONG32 cMap, ICorDebugInfo::OffsetMapping *pMap) override final; void setVars(CORINFO_METHOD_HANDLE ftn, ULONG32 cVars, ICorDebugInfo::NativeVarInfo *vars) override final; - void CompressDebugInfo(PCODE nativeEntry); + void CompressDebugInfo(PCODE nativeEntry, NativeCodeVersion nativeCodeVersion); virtual void SetDebugInfo(PTR_BYTE pDebugInfo) = 0; virtual PatchpointInfo* GetPatchpointInfo() @@ -579,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(); @@ -620,9 +614,6 @@ class CEECodeGenInfo : public CEEInfo ULONG m_codeSize; // Code size requested via allocMem #endif - size_t m_GCinfo_len; // Cached copy of GCinfo_len so we can backout in BackoutJitData() - size_t m_EHinfo_len; // Cached copy of EHinfo_len so we can backout in BackoutJitData() - ULONG32 m_iOffsetMapping; ICorDebugInfo::OffsetMapping * m_pOffsetMapping; @@ -717,7 +708,6 @@ class CEEJitInfo final : public CEECodeGenInfo uint32_t getExpectedTargetArchitecture() override; - void BackoutJitData(EECodeGenManager * jitMgr) override; void SetDebugInfo(PTR_BYTE pDebugInfo) override; void ResetForJitRetry() override @@ -974,7 +964,6 @@ class CInterpreterJitInfo final : public CEECodeGenInfo void WriteCodeBytes(); void WriteCode(EECodeGenManager * jitMgr) override; - void BackoutJitData(EECodeGenManager * jitMgr) override; void SetDebugInfo(PTR_BYTE pDebugInfo) override; LPVOID GetCookieForInterpreterCalliSig(CORINFO_SIG_INFO* szMetaSig) override; diff --git a/src/coreclr/vm/loaderallocator.cpp b/src/coreclr/vm/loaderallocator.cpp index f31d2d068bbfb8..58740770b2b644 100644 --- a/src/coreclr/vm/loaderallocator.cpp +++ b/src/coreclr/vm/loaderallocator.cpp @@ -501,9 +501,7 @@ void LoaderAllocator::GCLoaderAllocators(LoaderAllocator* pOriginalLoaderAllocat { CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; + STANDARD_VM_CHECK; PRECONDITION(pOriginalLoaderAllocator != NULL); PRECONDITION(pOriginalLoaderAllocator->IsCollectible()); PRECONDITION(pOriginalLoaderAllocator->Id()->GetType() == LAT_Assembly); @@ -576,7 +574,7 @@ void LoaderAllocator::GCLoaderAllocators(LoaderAllocator* pOriginalLoaderAllocat // (Also debugging NULL AVs if someone uses it accidentally is so much easier) pDomainLoaderAllocatorDestroyIterator->m_pFirstDomainAssemblyFromSameALCToDelete = NULL; - pDomainLoaderAllocatorDestroyIterator->ReleaseManagedAssemblyLoadContext(); + pDomainLoaderAllocatorDestroyIterator->ReleaseAssemblyLoadContext(); // The native objects in dependent handles may refer to the virtual call stub manager's heaps, so clear the dependent // handles first @@ -2070,7 +2068,7 @@ void LoaderAllocator::CleanupFailedTypeInit() } } -void AssemblyLoaderAllocator::ReleaseManagedAssemblyLoadContext() +void AssemblyLoaderAllocator::ReleaseAssemblyLoadContext() { CONTRACTL { diff --git a/src/coreclr/vm/loaderallocator.hpp b/src/coreclr/vm/loaderallocator.hpp index 58d2431e3b07a5..4e8de0ffa6470c 100644 --- a/src/coreclr/vm/loaderallocator.hpp +++ b/src/coreclr/vm/loaderallocator.hpp @@ -625,7 +625,7 @@ class LoaderAllocator } #if defined(FEATURE_READYTORUN) && defined(FEATURE_STUBPRECODE_DYNAMIC_HELPERS) - PTR_LoaderHeap GetDynamicHelpersStubHeap() + PTR_InterleavedLoaderHeap GetDynamicHelpersStubHeap() { LIMITED_METHOD_CONTRACT; return m_pDynamicHelpersStubHeap; @@ -751,7 +751,7 @@ class LoaderAllocator virtual BOOL CanUnload() = 0; void Init(BYTE *pExecutableHeapMemory); void Terminate(); - virtual void ReleaseManagedAssemblyLoadContext() {} + virtual void ReleaseAssemblyLoadContext() {} SIZE_T EstimateSize(); @@ -885,6 +885,9 @@ template<> struct cdac_data { static constexpr size_t ReferenceCount = offsetof(LoaderAllocator, m_cReferences); + static constexpr size_t HighFrequencyHeap = offsetof(LoaderAllocator, m_pHighFrequencyHeap); + static constexpr size_t LowFrequencyHeap = offsetof(LoaderAllocator, m_pLowFrequencyHeap); + static constexpr size_t StubHeap = offsetof(LoaderAllocator, m_pStubHeap); }; typedef VPTR(LoaderAllocator) PTR_LoaderAllocator; @@ -958,7 +961,7 @@ class AssemblyLoaderAllocator : public LoaderAllocator } virtual ~AssemblyLoaderAllocator(); void RegisterBinder(CustomAssemblyBinder* binderToRelease); - virtual void ReleaseManagedAssemblyLoadContext(); + virtual void ReleaseAssemblyLoadContext(); #endif // !defined(DACCESS_COMPILE) private: diff --git a/src/coreclr/vm/loongarch64/asmconstants.h b/src/coreclr/vm/loongarch64/asmconstants.h index 2ca6ef9a5499db..41589253cb9752 100644 --- a/src/coreclr/vm/loongarch64/asmconstants.h +++ b/src/coreclr/vm/loongarch64/asmconstants.h @@ -90,8 +90,8 @@ ASMCONSTANTS_C_ASSERT(CallDescrData__returnValue == offsetof(CallDescrD #define FpStruct__BothFloat 0b10 ASMCONSTANTS_C_ASSERT(FpStruct__BothFloat == (int)FpStruct::BothFloat) -#define VASigCookie__pNDirectILStub 0x8 -ASMCONSTANTS_C_ASSERT(VASigCookie__pNDirectILStub == offsetof(VASigCookie, pNDirectILStub)) +#define VASigCookie__pPInvokeILStub 0x8 +ASMCONSTANTS_C_ASSERT(VASigCookie__pPInvokeILStub == offsetof(VASigCookie, pPInvokeILStub)) #define SIZEOF__Frame 0x10 ASMCONSTANTS_C_ASSERT(SIZEOF__Frame == sizeof(Frame)); diff --git a/src/coreclr/vm/loongarch64/asmhelpers.S b/src/coreclr/vm/loongarch64/asmhelpers.S index c40821314bc2ac..ce5a90fe2d5f8d 100644 --- a/src/coreclr/vm/loongarch64/asmhelpers.S +++ b/src/coreclr/vm/loongarch64/asmhelpers.S @@ -359,30 +359,28 @@ NESTED_ENTRY ThePreStub, _TEXT, NoHandler NESTED_END ThePreStub, _TEXT // ------------------------------------------------------------------ -// The call in ndirect import precode points to this function. -NESTED_ENTRY NDirectImportThunk, _TEXT, NoHandler +// The call in PInvokeImportPrecode points to this function. +NESTED_ENTRY PInvokeImportThunk, _TEXT, NoHandler // $fp,$ra PROLOG_SAVE_REG_PAIR_INDEXED 22, 1, 0xa0 - //PROLOG_SAVE_REG gp, 16 SAVE_ARGUMENT_REGISTERS $sp, 0x20 SAVE_FLOAT_ARGUMENT_REGISTERS $sp, 0x60 ori $a0, $t2, 0 - bl C_FUNC(NDirectImportWorker) + bl C_FUNC(PInvokeImportWorker) ori $t4,$a0,0 // pop the stack and restore original register state RESTORE_FLOAT_ARGUMENT_REGISTERS $sp, 0x60 RESTORE_ARGUMENT_REGISTERS $sp, 0x20 - //EPILOG_RESTORE_REG gp, 16 // $fp,$ra EPILOG_RESTORE_REG_PAIR_INDEXED 22, 1, 0xa0 - // If we got back from NDirectImportWorker, the MD has been successfully + // If we got back from PInvokeImportWorker, the MD has been successfully // linked. Proceed to execute the original DLL call. EPILOG_BRANCH_REG $t4 -NESTED_END NDirectImportThunk, _TEXT +NESTED_END PInvokeImportThunk, _TEXT #ifdef FEATURE_PREJIT //------------------------------------------------ @@ -406,7 +404,6 @@ NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler // Save arguments and return address // $fp,$ra PROLOG_SAVE_REG_PAIR_INDEXED 22, 1, 0xa0 - //PROLOG_SAVE_REG gp, 16 SAVE_ARGUMENT_REGISTERS $sp, 32 SAVE_FLOAT_ARGUMENT_REGISTERS $sp, 96 @@ -425,7 +422,6 @@ NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler // pop the stack and restore original register state RESTORE_FLOAT_ARGUMENT_REGISTERS $sp, 96 RESTORE_ARGUMENT_REGISTERS $sp, 32 - //EPILOG_RESTORE_REG gp, 16 // $fp,$ra EPILOG_RESTORE_REG_PAIR_INDEXED 22, 1, 0xa0 @@ -476,7 +472,6 @@ NESTED_ENTRY TheUMEntryPrestub, _TEXT, UnhandledExceptionHandlerUnix // Save arguments and return address // $fp,$ra PROLOG_SAVE_REG_PAIR_INDEXED 22, 1, 0xa0 - //PROLOG_SAVE_REG gp, 16 SAVE_ARGUMENT_REGISTERS $sp, 32 SAVE_FLOAT_ARGUMENT_REGISTERS $sp, 96 @@ -488,7 +483,6 @@ NESTED_ENTRY TheUMEntryPrestub, _TEXT, UnhandledExceptionHandlerUnix // pop the stack and restore original register state RESTORE_FLOAT_ARGUMENT_REGISTERS $sp, 96 RESTORE_ARGUMENT_REGISTERS $sp, 32 - //EPILOG_RESTORE_REG gp, 16 // $fp,$ra EPILOG_RESTORE_REG_PAIR_INDEXED 22, 1, 0xa0 @@ -604,34 +598,6 @@ LOCAL_LABEL(Fail): b C_FUNC(ResolveWorkerAsmStub) // call the ResolveWorkerAsmStub method to transition into the VM NESTED_END ResolveWorkerChainLookupAsmStub, _TEXT - -//NOTE: Frame_Size = SIZEOF__ArgumentRegisters + SIZEOF__FloatArgumentRegisters + extra. -// -// |gp | -// |s0 | -// |$t2 | -// |t9 | -// |$a7 | -// |$a6 | -// |$a5 | -// |$a4 | -// |$a3 | -// |$a2 | -// |$a1 | -// |$a0 | -// |$ra | $sp+8 -// |fp | $sp -// -// |f19 | if needed. -// |f18 | -// |f17 | -// |f16 | -// |f15 | -// |f14 | -// |f13 | -// |f12 | -// - // ------------------------------------------------------------------ // void ResolveWorkerAsmStub(args in regs $a0-$a7 & stack, t8:IndirectionCellAndFlags, $t2:DispatchToken) // diff --git a/src/coreclr/vm/loongarch64/cgencpu.h b/src/coreclr/vm/loongarch64/cgencpu.h index 08a147b4a0d713..608c9ec356a7c5 100644 --- a/src/coreclr/vm/loongarch64/cgencpu.h +++ b/src/coreclr/vm/loongarch64/cgencpu.h @@ -57,7 +57,7 @@ extern PCODE GetPreStubEntryPoint(); #define JUMP_ALLOCATE_SIZE 40 // # bytes to allocate for a jump instruction #define BACK_TO_BACK_JUMP_ALLOCATE_SIZE 40 // # bytes to allocate for a back to back jump instruction -#define HAS_NDIRECT_IMPORT_PRECODE 1 +#define HAS_PINVOKE_IMPORT_PRECODE 1 #define HAS_FIXUP_PRECODE 1 #define HAS_FIXUP_PRECODE_CHUNKS 1 diff --git a/src/coreclr/vm/loongarch64/pinvokestubs.S b/src/coreclr/vm/loongarch64/pinvokestubs.S index 3690f8cc88e2f5..d1bb4e462481a9 100644 --- a/src/coreclr/vm/loongarch64/pinvokestubs.S +++ b/src/coreclr/vm/loongarch64/pinvokestubs.S @@ -21,7 +21,7 @@ NESTED_ENTRY \__PInvokeStubFuncName, _TEXT, NoHandler // get the stub - ld.d $t0, \VASigCookieReg, VASigCookie__pNDirectILStub + ld.d $t0, \VASigCookieReg, VASigCookie__pPInvokeILStub // if null goto stub generation beq $t0, $zero, \__PInvokeGenStubFuncName diff --git a/src/coreclr/vm/loongarch64/thunktemplates.S b/src/coreclr/vm/loongarch64/thunktemplates.S index 7deab2b6eadf29..52be9666d29582 100644 --- a/src/coreclr/vm/loongarch64/thunktemplates.S +++ b/src/coreclr/vm/loongarch64/thunktemplates.S @@ -7,19 +7,20 @@ // Note that the offsets specified in pcaddi must match the behavior of GetStubCodePageSize() on this architecture/os. LEAF_ENTRY StubPrecodeCode - pcaddi $r21, 0x1004 //4, for Type encoding. - ld.d $t2,$r21, (StubPrecodeData__SecretParam - 4*4) - ld.d $r21,$r21, (StubPrecodeData__Target - 4*4) + pcaddi $r21, 0x1000 + ld.d $t2,$r21, StubPrecodeData__SecretParam + ld.d $r21,$r21, StubPrecodeData__Target jirl $r0,$r21,0 LEAF_END_MARKED StubPrecodeCode LEAF_ENTRY FixupPrecodeCode - pcaddi $r21, 0x1003 //3, for Type encoding. - ld.d $r21,$r21, (FixupPrecodeData__Target - 4*3) + pcaddi $r21, 0x1000 + ld.d $r21,$r21, FixupPrecodeData__Target jirl $r0,$r21,0 - pcaddi $r21, 0x1003 - ld.d $t2,$r21, (FixupPrecodeData__MethodDesc - 4*3 -4*3) - ld.d $r21,$r21, (FixupPrecodeData__PrecodeFixupThunk - 4*3 - 4*3) + pcaddi $r21, 0xFFD + dbar 0 + ld.d $t2,$r21, FixupPrecodeData__MethodDesc + ld.d $r21,$r21, FixupPrecodeData__PrecodeFixupThunk jirl $r0,$r21,0 LEAF_END_MARKED FixupPrecodeCode diff --git a/src/coreclr/vm/marshalnative.cpp b/src/coreclr/vm/marshalnative.cpp index 0bea08d7a75592..f0e5d17c81963e 100644 --- a/src/coreclr/vm/marshalnative.cpp +++ b/src/coreclr/vm/marshalnative.cpp @@ -49,7 +49,7 @@ #endif // FEATURE_JAVAMARSHAL // Prelink -// Does advance loading of an N/Direct library +// Does advance loading of an PInvoke library extern "C" VOID QCALLTYPE MarshalNative_Prelink(MethodDesc * pMD) { QCALL_CONTRACT; @@ -62,8 +62,8 @@ extern "C" VOID QCALLTYPE MarshalNative_Prelink(MethodDesc * pMD) if (!pMD->IsPointingToPrestub()) return; - // Silently ignore if not N/Direct and not runtime generated. - if (!(pMD->IsNDirect()) && !(pMD->IsRuntimeSupplied())) + // Silently ignore if not PInvoke and not runtime generated. + if (!(pMD->IsPInvoke()) && !(pMD->IsRuntimeSupplied())) return; BEGIN_QCALL; @@ -126,7 +126,7 @@ extern "C" BOOL QCALLTYPE MarshalNative_TryGetStructMarshalStub(void* enregister if (structMarshalStub == NULL) { - structMarshalStub = NDirect::CreateStructMarshalILStub(pMT); + structMarshalStub = PInvoke::CreateStructMarshalILStub(pMT); } *pStructMarshalStub = structMarshalStub->GetSingleCallableAddrOfCode(); diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 1dcfce6a42ba39..4d6e8666749c2b 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -169,7 +169,7 @@ // static methods: -DEFINE_METASIG_T(SM(Int_IntPtr_Obj_RetException, i I j, C(EXCEPTION))) +DEFINE_METASIG_T(SM(Int_IntPtr_IntPtr_RetException, i I I, C(EXCEPTION))) DEFINE_METASIG_T(SM(Type_CharPtr_RuntimeAssembly_Bool_Bool_IntPtr_RetRuntimeType, P(u) C(ASSEMBLY) F F I, C(CLASS))) DEFINE_METASIG_T(SM(Type_RetIntPtr, C(TYPE), I)) DEFINE_METASIG(SM(RefIntPtr_IntPtr_IntPtr_Int_RetObj, r(I) I I i, j)) @@ -330,7 +330,6 @@ DEFINE_METASIG_T(SM(RetMethodBase, _, C(METHOD_BASE))) DEFINE_METASIG(SM(RetVoid, _, v)) DEFINE_METASIG(SM(Str_IntPtr_Int_RetVoid, s I i, v)) DEFINE_METASIG(SM(Int_RetIntPtr, i, I)) -DEFINE_METASIG(SM(Int_IntPtr_RetIntPtr, i I, I)) DEFINE_METASIG_T(SM(DateTime_RetDbl, g(DATE_TIME), d)) DEFINE_METASIG(SM(Dbl_RetLong, d, l)) diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index df4bf10406533d..349a05ec3c5396 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -59,7 +59,7 @@ bool FixupSignatureContainingInternalTypes( static_assert_no_msg((sizeof(MethodDescChunk) & MethodDesc::ALIGNMENT_MASK) == 0); static_assert_no_msg((sizeof(MethodDesc) & MethodDesc::ALIGNMENT_MASK) == 0); static_assert_no_msg((sizeof(FCallMethodDesc) & MethodDesc::ALIGNMENT_MASK) == 0); -static_assert_no_msg((sizeof(NDirectMethodDesc) & MethodDesc::ALIGNMENT_MASK) == 0); +static_assert_no_msg((sizeof(PInvokeMethodDesc) & MethodDesc::ALIGNMENT_MASK) == 0); static_assert_no_msg((sizeof(EEImplMethodDesc) & MethodDesc::ALIGNMENT_MASK) == 0); static_assert_no_msg((sizeof(ArrayMethodDesc) & MethodDesc::ALIGNMENT_MASK) == 0); static_assert_no_msg((sizeof(CLRToCOMCallMethodDesc) & MethodDesc::ALIGNMENT_MASK) == 0); @@ -68,7 +68,7 @@ static_assert_no_msg((sizeof(DynamicMethodDesc) & MethodDesc::ALIGNMENT_MASK #define METHOD_DESC_SIZES(adjustment) \ adjustment + sizeof(MethodDesc), /* mcIL */ \ adjustment + sizeof(FCallMethodDesc), /* mcFCall */ \ - adjustment + sizeof(NDirectMethodDesc), /* mcPInvoke */ \ + adjustment + sizeof(PInvokeMethodDesc), /* mcPInvoke */ \ adjustment + sizeof(EEImplMethodDesc), /* mcEEImpl */ \ adjustment + sizeof(ArrayMethodDesc), /* mcArray */ \ adjustment + sizeof(InstantiatedMethodDesc), /* mcInstantiated */ \ @@ -141,7 +141,7 @@ SIZE_T MethodDesc::SizeOf() /*********************************************************************/ #ifndef DACCESS_COMPILE -BOOL NDirectMethodDesc::HasDefaultDllImportSearchPathsAttribute() +BOOL PInvokeMethodDesc::HasDefaultDllImportSearchPathsAttribute() { CONTRACTL { @@ -153,21 +153,21 @@ BOOL NDirectMethodDesc::HasDefaultDllImportSearchPathsAttribute() if(IsDefaultDllImportSearchPathsAttributeCached()) { - return (ndirect.m_wFlags & kDefaultDllImportSearchPathsStatus) != 0; + return (m_wPInvokeFlags & kDefaultDllImportSearchPathsStatus) != 0; } - BOOL attributeIsFound = GetDefaultDllImportSearchPathsAttributeValue(GetModule(),GetMemberDef(),&ndirect.m_DefaultDllImportSearchPathsAttributeValue); + BOOL attributeIsFound = GetDefaultDllImportSearchPathsAttributeValue(GetModule(),GetMemberDef(),&m_DefaultDllImportSearchPathsAttributeValue); if(attributeIsFound ) { - InterlockedSetNDirectFlags(kDefaultDllImportSearchPathsIsCached | kDefaultDllImportSearchPathsStatus); + InterlockedSetPInvokeFlags(kDefaultDllImportSearchPathsIsCached | kDefaultDllImportSearchPathsStatus); } else { - InterlockedSetNDirectFlags(kDefaultDllImportSearchPathsIsCached); + InterlockedSetPInvokeFlags(kDefaultDllImportSearchPathsIsCached); } - return (ndirect.m_wFlags & kDefaultDllImportSearchPathsStatus) != 0; + return (m_wPInvokeFlags & kDefaultDllImportSearchPathsStatus) != 0; } #endif //!DACCESS_COMPILE @@ -1017,7 +1017,7 @@ WORD MethodDescChunk::InterlockedUpdateFlags(WORD wMask, BOOL fSet) // Returns the address of the native code. // // Methods which have no native code are either implemented by stubs or not jitted yet. -// For example, NDirectMethodDesc's have no native code. They are treated as +// For example, PInvokeMethodDesc's have no native code. They are treated as // implemented by stubs. On WIN64, these stubs are IL stubs, which DO have native code. // // This function returns null if the method has no native code. @@ -1123,8 +1123,10 @@ BOOL MethodDesc::HasRetBuffArg() } //******************************************************************************* -// This returns the offset of the IL. -// The offset is relative to the base of the IL image. +// This typically returns the offset of the IL. +// Another case when a method may have an RVA is earlybound IJW PInvokes, +// in which case the RVA is referring to native code. +// The offset is relative to the base of the image. ULONG MethodDesc::GetRVA() { CONTRACTL @@ -1133,27 +1135,11 @@ ULONG MethodDesc::GetRVA() GC_NOTRIGGER; FORBID_FAULT; SUPPORTS_DAC; + PRECONDITION((IsIL() && MayHaveILHeader()) || + (IsPInvoke() && ((PInvokeMethodDesc*)this)->IsEarlyBound())); } CONTRACTL_END - if (IsRuntimeSupplied()) - { - return 0; - } - - // Methods without metadata don't have an RVA. Examples are IL stubs and LCG methods. - if (IsNoMetadata()) - { - return 0; - } - - // Between two Async variants of the same method only one represents the actual IL. - // It is the variant that is not a thunk. - if (IsAsyncThunkMethod()) - { - return 0; - } - if (GetMemberDef() & 0x00FFFFFF) { Module *pModule = GetModule(); @@ -1167,7 +1153,7 @@ ULONG MethodDesc::GetRVA() _ASSERTE(!"If this ever fires, then this method should return HRESULT"); return 0; } - BAD_FORMAT_NOTHROW_ASSERT(IsNDirect() || IsMiIL(dwImplFlags) || IsMiOPTIL(dwImplFlags) || dwDescrOffset == 0); + BAD_FORMAT_NOTHROW_ASSERT(IsPInvoke() || IsMiIL(dwImplFlags) || IsMiOPTIL(dwImplFlags) || dwDescrOffset == 0); return dwDescrOffset; } @@ -1198,14 +1184,14 @@ COR_ILMETHOD* MethodDesc::GetILHeader() { THROWS; GC_NOTRIGGER; - PRECONDITION(IsIL()); - PRECONDITION(!IsUnboxingStub()); + PRECONDITION(MayHaveILHeader()); } CONTRACTL_END Module *pModule = GetModule(); - // Always pickup overrides like reflection emit, EnC, etc. + // Always pickup overrides like reflection emit, EnC, etc. irrespective of RVA. + // Profilers can attach dynamic IL to methods with zero RVA. TADDR pIL = pModule->GetDynamicIL(GetMemberDef()); if (pIL == (TADDR)NULL) @@ -2138,18 +2124,8 @@ PCODE MethodDesc::TryGetMultiCallableAddrOfCode(CORINFO_ACCESS_FLAGS accessFlags if (IsFCall()) { - // Call FCalls directly when possible - if (!IsInterface() && !GetMethodTable()->ContainsGenericVariables()) - { - BOOL fSharedOrDynamicFCallImpl; - PCODE pFCallImpl = ECall::GetFCallImpl(this, &fSharedOrDynamicFCallImpl); - - if (!fSharedOrDynamicFCallImpl) - return pFCallImpl; - - // Fake ctors share one implementation that has to be wrapped by prestub - GetOrCreatePrecode(); - } + // FCalls need stable entrypoint that can be mapped back to MethodDesc + return GetStableEntryPoint(); } else { @@ -2234,13 +2210,6 @@ MethodDesc* NonVirtualEntry2MethodDesc(PCODE entryPoint) RangeSection* pRS = ExecutionManager::FindCodeRange(entryPoint, ExecutionManager::GetScanFlags()); if (pRS == NULL) { - // Is it an FCALL? - MethodDesc* pFCallMD = ECall::MapTargetBackToMethod(entryPoint); - if (pFCallMD != NULL) - { - return pFCallMD; - } - return NULL; } @@ -2316,9 +2285,13 @@ bool IsTypeDefOrRefImplementedInSystemModule(Module* pModule, mdToken tk) MethodReturnKind ClassifyMethodReturnKind(SigPointer sig, Module* pModule, ULONG* offsetOfAsyncDetails, bool *isValueTask) { - // Without FEATURE_RUNTIME_ASYNC every declared method is classified as a NormalMethod. + // Without runtime async, every declared method is classified as a NormalMethod. // Thus code that handles runtime async scenarios becomes unreachable. -#ifdef FEATURE_RUNTIME_ASYNC + if (!g_pConfig->RuntimeAsync()) + { + return MethodReturnKind::NormalMethod; + } + PCCOR_SIGNATURE initialSig = sig.GetPtr(); uint32_t data; IfFailThrow(sig.GetCallingConvInfo(&data)); @@ -2376,7 +2349,6 @@ MethodReturnKind ClassifyMethodReturnKind(SigPointer sig, Module* pModule, ULONG return MethodReturnKind::NonGenericTaskReturningMethod; } } -#endif // FEATURE_RUNTIME_ASYNC return MethodReturnKind::NormalMethod; } @@ -2495,7 +2467,7 @@ BOOL MethodDesc::RequiresMethodDescCallingConvention(BOOL fEstimateForChunk /*=F LIMITED_METHOD_CONTRACT; // Interop marshaling is implemented using shared stubs - if (IsNDirect() || IsCLRToCOMCall()) + if (IsPInvoke() || IsCLRToCOMCall()) return TRUE; @@ -2552,6 +2524,10 @@ BOOL MethodDesc::RequiresStableEntryPointCore(BOOL fEstimateForChunk) // TODO: Can we avoid early allocation of precodes for interfaces and cominterop? if ((IsInterface() && !IsStatic() && IsVirtual()) || IsCLRToCOMCall()) return TRUE; + + // FCalls need stable entrypoint that can be mapped back to MethodDesc + if (IsFCall()) + return TRUE; } return FALSE; @@ -2578,7 +2554,7 @@ BOOL MethodDesc::MayHaveNativeCode() break; case mcFCall: // FCalls do not have real native code. return FALSE; - case mcPInvoke: // NDirect never have native code (note that the NDirect method + case mcPInvoke: // PInvoke never have native code (note that the PInvoke method return FALSE; // does not appear as having a native code even for stubs as IL) case mcEEImpl: // Runtime provided implementation. No native code. return FALSE; @@ -3268,17 +3244,17 @@ BOOL MethodDesc::SetStableEntryPointInterlocked(PCODE addr) return fResult; } -BOOL NDirectMethodDesc::ComputeMarshalingRequired() +BOOL PInvokeMethodDesc::ComputeMarshalingRequired() { WRAPPER_NO_CONTRACT; - return NDirect::MarshalingRequired(this); + return PInvoke::MarshalingRequired(this); } /**********************************************************************************/ -// Forward declare the NDirectImportWorker function - See dllimport.cpp -EXTERN_C LPVOID STDCALL NDirectImportWorker(NDirectMethodDesc*); -void *NDirectMethodDesc::ResolveAndSetNDirectTarget(_In_ NDirectMethodDesc* pMD) +// Forward declare the PInvokeImportWorker function - See dllimport.cpp +EXTERN_C LPVOID STDCALL PInvokeImportWorker(PInvokeMethodDesc*); +void *PInvokeMethodDesc::ResolveAndSetPInvokeTarget(_In_ PInvokeMethodDesc* pMD) { CONTRACTL { @@ -3291,14 +3267,14 @@ void *NDirectMethodDesc::ResolveAndSetNDirectTarget(_In_ NDirectMethodDesc* pMD) // This build conditional is here due to dllimport.cpp // not being relevant during the crossgen build. - LPVOID targetMaybe = NDirectImportWorker(pMD); + LPVOID targetMaybe = PInvokeImportWorker(pMD); _ASSERTE(targetMaybe != nullptr); - pMD->SetNDirectTarget(targetMaybe); + pMD->SetPInvokeTarget(targetMaybe); return targetMaybe; } -BOOL NDirectMethodDesc::TryGetResolvedNDirectTarget(_In_ NDirectMethodDesc* pMD, _Out_ void** ndirectTarget) +BOOL PInvokeMethodDesc::TryGetResolvedPInvokeTarget(_In_ PInvokeMethodDesc* pMD, _Out_ void** ndirectTarget) { CONTRACTL { @@ -3310,23 +3286,23 @@ BOOL NDirectMethodDesc::TryGetResolvedNDirectTarget(_In_ NDirectMethodDesc* pMD, } CONTRACTL_END - if (!pMD->NDirectTargetIsImportThunk()) + if (!pMD->PInvokeTargetIsImportThunk()) { // This is an early out to handle already resolved targets - *ndirectTarget = pMD->GetNDirectTarget(); + *ndirectTarget = pMD->GetPInvokeTarget(); return TRUE; } if (!pMD->ShouldSuppressGCTransition()) return FALSE; - *ndirectTarget = ResolveAndSetNDirectTarget(pMD); + *ndirectTarget = ResolveAndSetPInvokeTarget(pMD); return TRUE; } //******************************************************************************* -void NDirectMethodDesc::InterlockedSetNDirectFlags(WORD wFlags) +void PInvokeMethodDesc::InterlockedSetPInvokeFlags(WORD wFlags) { CONTRACTL { @@ -3338,12 +3314,12 @@ void NDirectMethodDesc::InterlockedSetNDirectFlags(WORD wFlags) // Since InterlockedCompareExchange only works on ULONGs, // we'll have to operate on the entire ULONG. Ugh. - WORD *pFlags = &ndirect.m_wFlags; + WORD *pFlags = &m_wPInvokeFlags; // Make sure that m_flags is aligned on a 4 byte boundry _ASSERTE( ( ((size_t) pFlags) & (sizeof(ULONG)-1) ) == 0); - // Ensure we won't be reading or writing outside the bounds of the NDirectMethodDesc. + // Ensure we won't be reading or writing outside the bounds of the PInvokeMethodDesc. _ASSERTE((BYTE*)pFlags >= (BYTE*)this); _ASSERTE((BYTE*)pFlags+sizeof(ULONG) <= (BYTE*)(this+1)); @@ -3358,7 +3334,7 @@ void NDirectMethodDesc::InterlockedSetNDirectFlags(WORD wFlags) #ifdef TARGET_WINDOWS -FARPROC NDirectMethodDesc::FindEntryPointWithMangling(NATIVE_LIBRARY_HANDLE hMod, PTR_CUTF8 entryPointName) +FARPROC PInvokeMethodDesc::FindEntryPointWithMangling(NATIVE_LIBRARY_HANDLE hMod, PTR_CUTF8 entryPointName) { CONTRACTL { @@ -3399,7 +3375,7 @@ FARPROC NDirectMethodDesc::FindEntryPointWithMangling(NATIVE_LIBRARY_HANDLE hMod return pFunc; } -FARPROC NDirectMethodDesc::FindEntryPointWithSuffix(NATIVE_LIBRARY_HANDLE hMod, PTR_CUTF8 entryPointName, char suffix) +FARPROC PInvokeMethodDesc::FindEntryPointWithSuffix(NATIVE_LIBRARY_HANDLE hMod, PTR_CUTF8 entryPointName, char suffix) { // Allocate space for a copy of the entry point name. DWORD entryPointWithSuffixLen = (DWORD)(strlen(entryPointName) + 1); // +1 for charset decorations @@ -3418,7 +3394,7 @@ FARPROC NDirectMethodDesc::FindEntryPointWithSuffix(NATIVE_LIBRARY_HANDLE hMod, #endif //******************************************************************************* -LPVOID NDirectMethodDesc::FindEntryPoint(NATIVE_LIBRARY_HANDLE hMod) +LPVOID PInvokeMethodDesc::FindEntryPoint(NATIVE_LIBRARY_HANDLE hMod) { CONTRACTL { @@ -3469,17 +3445,17 @@ LPVOID NDirectMethodDesc::FindEntryPoint(NATIVE_LIBRARY_HANDLE hMod) #if defined(TARGET_X86) //******************************************************************************* -void NDirectMethodDesc::EnsureStackArgumentSize() +void PInvokeMethodDesc::EnsureStackArgumentSize() { STANDARD_VM_CONTRACT; - if (ndirect.m_cbStackArgumentSize == 0xFFFF) + if (m_cbStackArgumentSize == 0xFFFF) { // Marshalling required check sets the stack size as side-effect when marshalling is not required. if (MarshalingRequired()) { // Generating interop stub sets the stack size as side-effect in all cases - GetStubForInteropMethod(this, NDIRECTSTUB_FL_FOR_NUMPARAMBYTES); + GetStubForInteropMethod(this, PINVOKESTUB_FL_FOR_NUMPARAMBYTES); } } } @@ -3487,7 +3463,7 @@ void NDirectMethodDesc::EnsureStackArgumentSize() //******************************************************************************* -void NDirectMethodDesc::InitEarlyBoundNDirectTarget() +void PInvokeMethodDesc::InitEarlyBoundPInvokeTarget() { CONTRACTL { @@ -3512,10 +3488,10 @@ void NDirectMethodDesc::InitEarlyBoundNDirectTarget() target = (BYTE*)FalseGetLastError; #endif - // As long as we've set the NDirect target field we don't need to backpatch the import thunk glue. - // All NDirect calls all through the NDirect target, so if it's updated, then we won't go into - // NDirectImportThunk(). In fact, backpatching the import thunk glue leads to race conditions. - SetNDirectTarget((LPVOID)target); + // As long as we've set the PInvoke target field we don't need to backpatch the import thunk glue. + // All PInvoke calls all through the PInvoke target, so if it's updated, then we won't go into + // PInvokeImportThunk(). In fact, backpatching the import thunk glue leads to race conditions. + SetPInvokeTarget((LPVOID)target); } //******************************************************************************* @@ -3556,7 +3532,7 @@ BOOL MethodDesc::ShouldSuppressGCTransition() CONTRACTL_END; MethodDesc* tgt = nullptr; - if (IsNDirect()) + if (IsPInvoke()) { tgt = this; } @@ -3580,7 +3556,7 @@ BOOL MethodDesc::ShouldSuppressGCTransition() _ASSERTE(tgt != nullptr); bool suppressGCTransition; - NDirect::GetCallingConvention_IgnoreErrors(tgt, NULL /*callConv*/, &suppressGCTransition); + PInvoke::GetCallingConvention_IgnoreErrors(tgt, NULL /*callConv*/, &suppressGCTransition); return suppressGCTransition ? TRUE : FALSE; } diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index 4d9c6bdfe5b599..1438276e35b42c 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -28,7 +28,7 @@ class Stub; class FCallMethodDesc; class FieldDesc; -class NDirect; +class PInvoke; class MethodDescChunk; class InstantiatedMethodDesc; class DictionaryLayout; @@ -53,7 +53,7 @@ GVAL_DECL(DWORD, g_MiniMetaDataBuffMaxSize); GVAL_DECL(TADDR, g_MiniMetaDataBuffAddress); #endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS -EXTERN_C VOID STDCALL NDirectImportThunk(); +EXTERN_C VOID STDCALL PInvokeImportThunk(); #define METHOD_TOKEN_REMAINDER_BIT_COUNT 12 #define METHOD_TOKEN_REMAINDER_MASK ((1 << METHOD_TOKEN_REMAINDER_BIT_COUNT) - 1) @@ -166,7 +166,7 @@ enum MethodClassification { mcIL = 0, // IL mcFCall = 1, // FCall (also includes tlbimped ctor, Delegate ctor) - mcPInvoke = 2, // PInvoke method also known as N/Direct in this codebase + mcPInvoke = 2, // PInvoke method mcEEImpl = 3, // special method; implementation provided by EE (like Delegate Invoke) mcArray = 4, // Array ECall mcInstantiated = 5, // Instantiated generic methods, including descriptors @@ -194,7 +194,7 @@ enum MethodDescFlags // Has local slot (vs. has real slot in MethodTable) mdfHasNonVtableSlot = 0x0008, - // Method is a body for a method impl (MI_MethodDesc, MI_NDirectMethodDesc, etc) + // Method is a body for a method impl (MI_MethodDesc, MI_PInvokeMethodDesc, etc) // where the function explicitly implements IInterface.foo() instead of foo(). mdfMethodImpl = 0x0010, @@ -726,7 +726,7 @@ class MethodDesc inline bool IsILStub(); inline bool IsLCGMethod(); - inline DWORD IsNDirect() + inline DWORD IsPInvoke() { LIMITED_METHOD_DAC_CONTRACT; return mcPInvoke == GetClassification(); @@ -901,7 +901,8 @@ class MethodDesc MODE_ANY; } CONTRACTL_END; - return IsIL() && !IsUnboxingStub() && GetRVA(); + + return MayHaveILHeader() && GetRVA(); } COR_ILMETHOD* GetILHeader(); @@ -1499,6 +1500,14 @@ class MethodDesc BOOL MayHaveNativeCode(); + BOOL MayHaveILHeader() + { + LIMITED_METHOD_DAC_CONTRACT; + + // methods with transient IL bodies do not have IL headers + return IsIL() && !IsUnboxingStub() && !IsAsyncThunkMethod(); + } + ULONG GetRVA(); public: @@ -2776,7 +2785,7 @@ class DynamicMethodDesc : public StoredSigMethodDesc bool IsILStub() const { LIMITED_METHOD_DAC_CONTRACT; return HasFlags(FlagIsILStub); } bool IsLCGMethod() const { LIMITED_METHOD_DAC_CONTRACT; return HasFlags(FlagIsLCGMethod); } - inline PTR_DynamicResolver GetResolver(); + inline PTR_DynamicResolver GetResolver(); inline PTR_LCGMethodResolver GetLCGMethodResolver(); inline PTR_ILStubResolver GetILStubResolver(); @@ -2906,7 +2915,7 @@ class DynamicMethodDesc : public StoredSigMethodDesc // // following implementations defined in DynamicMethod.cpp // - void Destroy(); + bool TryDestroy(); friend struct ::cdac_data; }; @@ -2951,11 +2960,11 @@ class ArrayMethodDesc : public StoredSigMethodDesc DWORD GetAttrs(); }; -#ifdef HAS_NDIRECT_IMPORT_PRECODE -typedef NDirectImportPrecode NDirectImportThunkGlue; -#else // HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_PINVOKE_IMPORT_PRECODE +typedef PInvokeImportPrecode PInvokeImportThunkGlue; +#else // HAS_PINVOKE_IMPORT_PRECODE -class NDirectImportThunkGlue +class PInvokeImportThunkGlue { PVOID m_dummy; // Dummy field to make the alignment right @@ -2971,53 +2980,49 @@ class NDirectImportThunkGlue } }; -#endif // HAS_NDIRECT_IMPORT_PRECODE +#endif // HAS_PINVOKE_IMPORT_PRECODE -typedef DPTR(NDirectImportThunkGlue) PTR_NDirectImportThunkGlue; +typedef DPTR(PInvokeImportThunkGlue) PTR_PInvokeImportThunkGlue; //----------------------------------------------------------------------- -// Operations specific to NDirect methods. We use a derived class to get +// Operations specific to PInvoke methods. We use a derived class to get // the compiler involved in enforcing proper method type usage. // DO NOT ADD FIELDS TO THIS CLASS. //----------------------------------------------------------------------- -class NDirectMethodDesc : public MethodDesc +class PInvokeMethodDesc : public MethodDesc { public: - struct temp1 - { - // Information about the entrypoint - PTR_CUTF8 m_pszEntrypointName; + // Information about the entrypoint + PTR_CUTF8 m_pszEntrypointName; - union - { - PTR_CUTF8 m_pszLibName; - DWORD m_dwECallID; // ECallID for QCalls - }; + union + { + PTR_CUTF8 m_pszLibName; + DWORD m_dwECallID; // ECallID for QCalls + }; - // The JIT generates an indirect call through this location in some cases. - // Initialized to NDirectImportThunkGlue. Patched to the true target or - // host interceptor stub or alignment thunk after linking. - LPVOID m_pNDirectTarget; + // The JIT generates an indirect call through this location in some cases. + // Initialized to PInvokeImportThunkGlue. Patched to the true target or + // host interceptor stub or alignment thunk after linking. + LPVOID m_pPInvokeTarget; -#ifdef HAS_NDIRECT_IMPORT_PRECODE - PTR_NDirectImportThunkGlue m_pImportThunkGlue; -#else // HAS_NDIRECT_IMPORT_PRECODE - NDirectImportThunkGlue m_ImportThunkGlue; -#endif // HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_PINVOKE_IMPORT_PRECODE + PTR_PInvokeImportThunkGlue m_pImportThunkGlue; +#else // HAS_PINVOKE_IMPORT_PRECODE + PInvokeImportThunkGlue m_ImportThunkGlue; +#endif // HAS_PINVOKE_IMPORT_PRECODE - ULONG m_DefaultDllImportSearchPathsAttributeValue; // DefaultDllImportSearchPathsAttribute is saved. + ULONG m_DefaultDllImportSearchPathsAttributeValue; // DefaultDllImportSearchPathsAttribute is saved. - // Various attributes needed at runtime. - WORD m_wFlags; + // Various attributes needed at runtime. + WORD m_wPInvokeFlags; #if defined(TARGET_X86) - // Size of outgoing arguments (on stack). Note that in order to get the @n stdcall name decoration, - WORD m_cbStackArgumentSize; + // Size of outgoing arguments (on stack). Note that in order to get the @n stdcall name decoration, + WORD m_cbStackArgumentSize; #endif // defined(TARGET_X86) - } ndirect; - enum Flags { // There are two groups of flag bits here each which gets initialized @@ -3060,15 +3065,15 @@ class NDirectMethodDesc : public MethodDesc kDefaultDllImportSearchPathsStatus = 0x2000, // either method has custom attribute or not. - kNDirectPopulated = 0x8000, // Indicate if the NDirect has been fully populated. + kPInvokePopulated = 0x8000, // Indicate if the PInvoke has been fully populated. }; - // Resolve the import to the NDirect target and set it on the NDirectMethodDesc. - static void* ResolveAndSetNDirectTarget(_In_ NDirectMethodDesc* pMD); + // Resolve the import to the PInvoke target and set it on the PInvokeMethodDesc. + static void* ResolveAndSetPInvokeTarget(_In_ PInvokeMethodDesc* pMD); - // Attempt to get a resolved NDirect target. This will return true for already resolved + // Attempt to get a resolved PInvoke target. This will return true for already resolved // targets and methods that are resolved at JIT time, such as those marked SuppressGCTransition - static BOOL TryGetResolvedNDirectTarget(_In_ NDirectMethodDesc* pMD, _Out_ void** ndirectTarget); + static BOOL TryGetResolvedPInvokeTarget(_In_ PInvokeMethodDesc* pMD, _Out_ void** ndirectTarget); // Retrieves the cached result of marshaling required computation, or performs the computation // if the result is not cached yet. @@ -3076,52 +3081,52 @@ class NDirectMethodDesc : public MethodDesc { STANDARD_VM_CONTRACT; - if ((ndirect.m_wFlags & kIsMarshalingRequiredCached) == 0) + if ((m_wPInvokeFlags & kIsMarshalingRequiredCached) == 0) { // Compute the flag and cache the result - InterlockedSetNDirectFlags(kIsMarshalingRequiredCached | + InterlockedSetPInvokeFlags(kIsMarshalingRequiredCached | (ComputeMarshalingRequired() ? kCachedMarshalingRequired : 0)); } - _ASSERTE((ndirect.m_wFlags & kIsMarshalingRequiredCached) != 0); - return (ndirect.m_wFlags & kCachedMarshalingRequired) != 0; + _ASSERTE((m_wPInvokeFlags & kIsMarshalingRequiredCached) != 0); + return (m_wPInvokeFlags & kCachedMarshalingRequired) != 0; } BOOL ComputeMarshalingRequired(); // Atomically set specified flags. Only setting of the bits is supported. - void InterlockedSetNDirectFlags(WORD wFlags); + void InterlockedSetPInvokeFlags(WORD wFlags); void SetIsEarlyBound() { LIMITED_METHOD_CONTRACT; - ndirect.m_wFlags |= kEarlyBound; + m_wPInvokeFlags |= kEarlyBound; } BOOL IsEarlyBound() { LIMITED_METHOD_CONTRACT; - return (ndirect.m_wFlags & kEarlyBound) != 0; + return (m_wPInvokeFlags & kEarlyBound) != 0; } BOOL IsNativeAnsi() const { LIMITED_METHOD_CONTRACT; - return (ndirect.m_wFlags & kNativeAnsi) != 0; + return (m_wPInvokeFlags & kNativeAnsi) != 0; } BOOL IsNativeNoMangled() const { LIMITED_METHOD_CONTRACT; - return (ndirect.m_wFlags & kNativeNoMangle) != 0; + return (m_wPInvokeFlags & kNativeNoMangle) != 0; } PTR_CUTF8 GetLibNameRaw() { LIMITED_METHOD_DAC_CONTRACT; - return ndirect.m_pszLibName; + return m_pszLibName; } #ifndef DACCESS_COMPILE @@ -3129,7 +3134,7 @@ class NDirectMethodDesc : public MethodDesc { LIMITED_METHOD_CONTRACT; - return IsQCall() ? "QCall" : ndirect.m_pszLibName; + return IsQCall() ? "QCall" : m_pszLibName; } #endif // !DACCESS_COMPILE @@ -3137,28 +3142,28 @@ class NDirectMethodDesc : public MethodDesc { LIMITED_METHOD_DAC_CONTRACT; - return ndirect.m_pszEntrypointName; + return m_pszEntrypointName; } BOOL IsVarArgs() const { LIMITED_METHOD_DAC_CONTRACT; - return (ndirect.m_wFlags & kVarArgs) != 0; + return (m_wPInvokeFlags & kVarArgs) != 0; } BOOL IsStdCall() const { LIMITED_METHOD_DAC_CONTRACT; - return (ndirect.m_wFlags & kStdCall) != 0; + return (m_wPInvokeFlags & kStdCall) != 0; } BOOL IsThisCall() const { LIMITED_METHOD_DAC_CONTRACT; - return (ndirect.m_wFlags & kThisCall) != 0; + return (m_wPInvokeFlags & kThisCall) != 0; } // Returns TRUE if this MethodDesc is internal call from CoreLib to VM @@ -3166,7 +3171,7 @@ class NDirectMethodDesc : public MethodDesc { LIMITED_METHOD_DAC_CONTRACT; - return (ndirect.m_wFlags & kIsQCall) != 0; + return (m_wPInvokeFlags & kIsQCall) != 0; } BOOL HasDefaultDllImportSearchPathsAttribute(); @@ -3174,57 +3179,57 @@ class NDirectMethodDesc : public MethodDesc BOOL IsDefaultDllImportSearchPathsAttributeCached() { LIMITED_METHOD_CONTRACT; - return (ndirect.m_wFlags & kDefaultDllImportSearchPathsIsCached) != 0; + return (m_wPInvokeFlags & kDefaultDllImportSearchPathsIsCached) != 0; } BOOL IsPopulated() { LIMITED_METHOD_CONTRACT; - return (ndirect.m_wFlags & kNDirectPopulated) != 0; + return (VolatileLoad(&m_wPInvokeFlags) & kPInvokePopulated) != 0; } ULONG DefaultDllImportSearchPathsAttributeCachedValue() { LIMITED_METHOD_CONTRACT; - return ndirect.m_DefaultDllImportSearchPathsAttributeValue & 0xFFFFFFFD; + return m_DefaultDllImportSearchPathsAttributeValue & 0xFFFFFFFD; } BOOL DllImportSearchAssemblyDirectory() { LIMITED_METHOD_CONTRACT; - return (ndirect.m_DefaultDllImportSearchPathsAttributeValue & 0x2) != 0; + return (m_DefaultDllImportSearchPathsAttributeValue & 0x2) != 0; } - PTR_NDirectImportThunkGlue GetNDirectImportThunkGlue() + PTR_PInvokeImportThunkGlue GetPInvokeImportThunkGlue() { LIMITED_METHOD_DAC_CONTRACT; - return ndirect.m_pImportThunkGlue; + return m_pImportThunkGlue; } - LPVOID GetNDirectTarget() + LPVOID GetPInvokeTarget() { LIMITED_METHOD_CONTRACT; - _ASSERTE(IsNDirect()); - return ndirect.m_pNDirectTarget; + _ASSERTE(IsPInvoke()); + return m_pPInvokeTarget; } - VOID SetNDirectTarget(LPVOID pTarget); + VOID SetPInvokeTarget(LPVOID pTarget); #ifndef DACCESS_COMPILE - BOOL NDirectTargetIsImportThunk() + BOOL PInvokeTargetIsImportThunk() { WRAPPER_NO_CONTRACT; - _ASSERTE(IsNDirect()); + _ASSERTE(IsPInvoke()); - return (GetNDirectTarget() == GetNDirectImportThunkGlue()->GetEntrypoint()); + return (GetPInvokeTarget() == GetPInvokeImportThunkGlue()->GetEntrypoint()); } #endif // !DACCESS_COMPILE // Find the entry point name and function address - // based on the module and data from NDirectMethodDesc + // based on the module and data from PInvokeMethodDesc // LPVOID FindEntryPoint(NATIVE_LIBRARY_HANDLE hMod); @@ -3248,13 +3253,13 @@ class NDirectMethodDesc : public MethodDesc } // Don't write to the field if it's already initialized to avoid creating private pages (NGEN) - if (ndirect.m_cbStackArgumentSize == 0xFFFF) + if (m_cbStackArgumentSize == 0xFFFF) { - ndirect.m_cbStackArgumentSize = cbDstBuffer; + m_cbStackArgumentSize = cbDstBuffer; } else { - _ASSERTE(ndirect.m_cbStackArgumentSize == cbDstBuffer); + _ASSERTE(m_cbStackArgumentSize == cbDstBuffer); } #endif // defined(TARGET_X86) } @@ -3266,18 +3271,18 @@ class NDirectMethodDesc : public MethodDesc { LIMITED_METHOD_DAC_CONTRACT; - _ASSERTE(ndirect.m_cbStackArgumentSize != 0xFFFF); + _ASSERTE(m_cbStackArgumentSize != 0xFFFF); // If we have a methoddesc, stackArgSize is the number of bytes of // the outgoing marshalling buffer. - return ndirect.m_cbStackArgumentSize; + return m_cbStackArgumentSize; } #endif // defined(TARGET_X86) - VOID InitEarlyBoundNDirectTarget(); + VOID InitEarlyBoundPInvokeTarget(); // In AppDomains, we can trigger declarer's cctor when we link the P/Invoke, - // which takes care of inlined calls as well. See code:NDirect.NDirectLink. + // which takes care of inlined calls as well. See code:PInvoke.PInvokeLink. // Although the cctor is guaranteed to run in the shared domain before the // target is invoked, we will trigger it at link time as well because linking // may depend on it - cctor may change the target DLL, DLL search path etc. @@ -3290,7 +3295,7 @@ class NDirectMethodDesc : public MethodDesc return FALSE; return !pMT->GetClass()->IsBeforeFieldInit(); } -}; //class NDirectMethodDesc +}; //class PInvokeMethodDesc //----------------------------------------------------------------------- // Operations specific to EEImplCall methods. We use a derived class to get diff --git a/src/coreclr/vm/method.inl b/src/coreclr/vm/method.inl index bf25d6f6955705..475af80856c44a 100644 --- a/src/coreclr/vm/method.inl +++ b/src/coreclr/vm/method.inl @@ -130,7 +130,7 @@ inline bool MethodDesc::IsILStub() inline BOOL MethodDesc::IsQCall() { WRAPPER_NO_CONTRACT; - return (IsNDirect() && dac_cast(this)->IsQCall()); + return (IsPInvoke() && dac_cast(this)->IsQCall()); } #ifdef FEATURE_COMINTEROP diff --git a/src/coreclr/vm/methoddescbackpatchinfo.cpp b/src/coreclr/vm/methoddescbackpatchinfo.cpp index c1b0283169e197..f8280bc044171e 100644 --- a/src/coreclr/vm/methoddescbackpatchinfo.cpp +++ b/src/coreclr/vm/methoddescbackpatchinfo.cpp @@ -28,17 +28,17 @@ void EntryPointSlots::Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entr switch (slotType) { case SlotType_Normal: - *(PCODE *)slot = entryPoint; + VolatileStore((PCODE *)slot, entryPoint); break; case SlotType_Vtable: - *((MethodTable::VTableIndir2_t *)slot) = entryPoint; + VolatileStore(((MethodTable::VTableIndir2_t *)slot), entryPoint); break; case SlotType_Executable: { ExecutableWriterHolder slotWriterHolder((void*)slot, sizeof(PCODE*)); - *(PCODE *)slotWriterHolder.GetRW() = entryPoint; + VolatileStore((PCODE *)slotWriterHolder.GetRW(), entryPoint); goto Flush; } @@ -48,7 +48,7 @@ void EntryPointSlots::Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entr _ASSERTE(sizeof(void *) <= 4); ExecutableWriterHolder slotWriterHolder((void*)slot, sizeof(PCODE*)); - *(PCODE *)slotWriterHolder.GetRW() = entryPoint - ((PCODE)slot + sizeof(PCODE)); + VolatileStore((PCODE *)slotWriterHolder.GetRW(), entryPoint - ((PCODE)slot + sizeof(PCODE))); // fall through } @@ -76,14 +76,28 @@ void MethodDescBackpatchInfoTracker::Backpatch_Locked(MethodDesc *pMethodDesc, P WRAPPER_NO_CONTRACT; _ASSERTE(IsLockOwnedByCurrentThread()); _ASSERTE(pMethodDesc != nullptr); + bool fReadyToPatchExecutableCode = false; - auto lambda = [&entryPoint](LoaderAllocator *pLoaderAllocatorOfSlot, MethodDesc *pMethodDesc, UINT_PTR slotData) + auto lambda = [&entryPoint, &fReadyToPatchExecutableCode](LoaderAllocator *pLoaderAllocatorOfSlot, MethodDesc *pMethodDesc, UINT_PTR slotData) { TADDR slot; EntryPointSlots::SlotType slotType; EntryPointSlots::ConvertUINT_PTRToSlotAndTypePair(slotData, &slot, &slotType); + if (!fReadyToPatchExecutableCode && ((slotType == EntryPointSlots::SlotType_Executable) || slotType == EntryPointSlots::SlotType_ExecutableRel32)) + { + // We need to patch the executable code, so we need to make absolutely sure that all writes to the entry point contents are written before + // we patch the executable code. We only need to do this once, and it isn't equivalent to VolatileStore, as our definition of VolatileStore + // doesn't include a means to drain the store queue before the patch. The important detail is that executing the instruction stream is not + // logically equivalent to performing a memory load, and does not participate in all of the same load/store ordering guarantees. + // Intel does not provide a precise definition of this, but it does describe the situation as "cross modifying code", and describes an unfortunately + // impractical scheme involving running cpuid on all cores that might execute the code in question. Since both the old/new code are semantically + // equivalent, we're going to use an sfence to ensure that at least all the writes to establish the new code are completely visible to all cores + // before we actually patch the executable code. + SFENCE_MEMORY_BARRIER(); + fReadyToPatchExecutableCode = true; + } EntryPointSlots::Backpatch_Locked(slot, slotType, entryPoint); return true; // Keep walking diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index b2300ea6e6e22c..722383e058dd7f 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -6213,31 +6213,12 @@ MethodDesc* MethodTable::GetMethodDescForSlotAddress(PCODE addr, BOOL fSpeculati } CONTRACT_END; - // If we see shared fcall implementation as an argument to this - // function, it means that a vtable slot for the shared fcall - // got backpatched when it shouldn't have. The reason we can't - // backpatch this method is that it is an FCall that has many - // MethodDescs for one implementation. If we backpatch delegate - // constructors, this function will not be able to recover the - // MethodDesc for the method. - // - _ASSERTE_IMPL(!ECall::IsSharedFCallImpl(addr) && - "someone backpatched shared fcall implementation -- " - "see comment in code"); - MethodDesc* pMethodDesc = ExecutionManager::GetCodeMethodDesc(addr); if (NULL != pMethodDesc) { goto lExit; } - // Is it an FCALL? - pMethodDesc = ECall::MapTargetBackToMethod(addr); - if (pMethodDesc != 0) - { - goto lExit; - } - pMethodDesc = MethodDesc::GetMethodDescFromStubAddr(addr, fSpeculative); lExit: diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 66d9199dcfc410..1e8b5c87893c2c 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -1771,6 +1771,12 @@ MethodTableBuilder::BuildMethodTableThrowing( { BuildMethodTableThrowException(IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT); } + + ULONG classSize; + if (SUCCEEDED(GetMDImport()->GetClassTotalSize(cl, &classSize)) && classSize != 0) + { + BuildMethodTableThrowException(IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT_SIZE); + } } } } @@ -1806,12 +1812,6 @@ MethodTableBuilder::BuildMethodTableThrowing( BuildMethodTableThrowException(IDS_CLASSLOAD_ZEROSIZE); } - if (bmtFP->fHasSelfReferencingStaticValueTypeField_WithRVA) - { // Verify self-referencing statics with RVA (now when the ValueType size is known) - VerifySelfReferencingStaticValueTypeFields_WithRVA(pByValueClassCache); - } - - // Now setup the method table SetupMethodTable2(pLoaderModule); @@ -2682,10 +2682,13 @@ MethodTableBuilder::EnumerateClassMethods() BuildMethodTableThrowException(IDS_CLASSLOAD_TOO_MANY_METHODS); bmtMethod->m_cMaxDeclaredMethods = (SLOT_INDEX)cMethAndGaps; -#ifdef FEATURE_RUNTIME_ASYNC - // TODO: (async) the index is uint16 and can potentially overflow. This needs to be more robust. - bmtMethod->m_cMaxDeclaredMethods *= 2; -#endif + + if (g_pConfig->RuntimeAsync()) + { + // TODO: (async) the index is uint16 and can potentially overflow. This needs to be more robust. + bmtMethod->m_cMaxDeclaredMethods *= 2; + } + bmtMethod->m_cDeclaredMethods = 0; bmtMethod->m_rgDeclaredMethods = new (GetStackingAllocator()) bmtMDMethod *[bmtMethod->m_cMaxDeclaredMethods]; @@ -3142,7 +3145,7 @@ MethodTableBuilder::EnumerateClassMethods() if (IsReallyMdPinvokeImpl(dwMemberAttrs) || IsMiInternalCall(dwImplFlags)) { - hr = NDirect::HasNAT_LAttribute(pMDInternalImport, tok, dwMemberAttrs); + hr = PInvoke::HasNAT_LAttribute(pMDInternalImport, tok, dwMemberAttrs); // There was a problem querying for the attribute if (FAILED(hr)) @@ -3178,7 +3181,7 @@ MethodTableBuilder::EnumerateClassMethods() type = mcPInvoke; } } - // The NAT_L attribute is present, marking this method as NDirect + // The NAT_L attribute is present, marking this method as PInvoke else { CONSISTENCY_CHECK(hr == S_OK); @@ -3798,7 +3801,7 @@ VOID MethodTableBuilder::AllocateFieldDescs() // table in every single method desc, we allocate memory in the // following manner: // o Field descs get a single contiguous block. - // o Method descs of different sizes (normal vs NDirect) are + // o Method descs of different sizes (normal vs PInvoke) are // allocated in different MethodDescChunks. // o Each method desc chunk starts with a header, and has // at most MAX_ method descs (if there are more @@ -3818,62 +3821,175 @@ VOID MethodTableBuilder::AllocateFieldDescs() } } -//******************************************************************************* -BOOL MethodTableBuilder::IsSelfReferencingStaticValueTypeField(mdToken dwByValueClassToken, - bmtInternalInfo* bmtInternal, - const bmtGenericsInfo *bmtGenerics, - PCCOR_SIGNATURE pMemberSignature, - DWORD cMemberSignature) +CorElementType MethodTableBuilder::GetCorElementTypeOfTypeDefOrRefForStaticField(Module* module, mdToken typeDefOrRef) { STANDARD_VM_CONTRACT; - if (dwByValueClassToken != this->GetCl()) + MethodTable *pMTFound = NULL; + + if (TypeFromToken(typeDefOrRef) == mdtTypeDef) { - return FALSE; + pMTFound = module->LookupTypeDef(typeDefOrRef).AsMethodTable(); + } + else if (TypeFromToken(typeDefOrRef) == mdtTypeRef) + { + pMTFound = module->LookupTypeRef(typeDefOrRef).AsMethodTable(); } - if (!bmtGenerics->HasInstantiation()) + // The checking here for typeDefOrRef which matches GetCl is only intended to reduce the number + // of cases where we throw exceptions. It is not actually a correctness check, so that obviously + // self-referential loads don't trigger exceptions. + if ((pMTFound == NULL) && bmtInternal->pType != NULL && (typeDefOrRef != GetCl())) { - return TRUE; + EX_TRY + { + pMTFound = ClassLoader::LoadTypeDefOrRefThrowing(module, typeDefOrRef, ClassLoader::ThrowIfNotFound, ClassLoader::PermitUninstDefOrRef, 0, CLASS_LOAD_APPROXPARENTS).AsMethodTable(); + } + EX_CATCH + { + // If this failed, we can fall back to directly working with the type definition, so catch all the exceptions + } + EX_END_CATCH } - // The value class is generic. Check that the signature of the field - // is _exactly_ equivalent to VC. Do this by consing up a fake - // signature. - DWORD nGenericArgs = bmtGenerics->GetNumGenericArgs(); - CONSISTENCY_CHECK(nGenericArgs != 0); + if (pMTFound != NULL) + { + if (pMTFound->IsByRefLike()) + { + BuildMethodTableThrowException(IDS_CLASSLOAD_BYREF_OR_BYREFLIKE_STATICFIELD); + } + + if (pMTFound->IsEnum()) + { + return pMTFound->GetApproxFieldDescListRaw()[0].GetFieldType(); + } + else + { + _ASSERTE(pMTFound->IsValueType()); + return ELEMENT_TYPE_VALUETYPE; + } + } - SigBuilder sigBuilder; + Module *pModuleOfTypeDef; + mdTypeDef tkTypeDef; - sigBuilder.AppendElementType(ELEMENT_TYPE_GENERICINST); - sigBuilder.AppendElementType(ELEMENT_TYPE_VALUETYPE); - sigBuilder.AppendToken(dwByValueClassToken); - sigBuilder.AppendData(nGenericArgs); - for (unsigned int typearg = 0; typearg < nGenericArgs; typearg++) + ClassLoader::ResolveTokenToTypeDefThrowing(module, typeDefOrRef, &pModuleOfTypeDef, &tkTypeDef); + + // First check to see if the type is byref-like + if (pModuleOfTypeDef->GetCustomAttribute(tkTypeDef, + WellKnownAttribute::IsByRefLike, + NULL, NULL) == S_OK) + { + BuildMethodTableThrowException(IDS_CLASSLOAD_BYREF_OR_BYREFLIKE_STATICFIELD); + } + + mdToken tkTypeDefExtends; + IfFailThrow(pModuleOfTypeDef->GetMDImport()->GetTypeDefProps(tkTypeDef, NULL, &tkTypeDefExtends)); + bool thisIsAnEnum = false; + + if (TypeFromToken(tkTypeDefExtends) == mdtTypeDef) + { + if (pModuleOfTypeDef->IsSystem()) + { + if (tkTypeDefExtends == CoreLibBinder::GetClassIfExist(CLASS__ENUM)->GetCl()) + { + thisIsAnEnum = true; + } + } + } + else { - sigBuilder.AppendElementType(ELEMENT_TYPE_VAR); - sigBuilder.AppendData(typearg); + _ASSERTE(TypeFromToken(tkTypeDefExtends) == mdtTypeRef); + LPCSTR pszNameSpace; + LPCSTR pszClassName; + pModuleOfTypeDef->GetMDImport()->GetNameOfTypeRef(tkTypeDefExtends, &pszNameSpace, &pszClassName); + if (pszNameSpace != NULL && pszClassName != NULL && strcmp(pszNameSpace, "System") == 0 && strcmp(pszClassName, "Enum") == 0) + { + Module *pModuleOfSystemEnumType; + mdTypeDef tkTypeDefOfSystemEnumType; + + ClassLoader::ResolveTokenToTypeDefThrowing(pModuleOfTypeDef, tkTypeDefExtends, &pModuleOfSystemEnumType, &tkTypeDefOfSystemEnumType); + + if (pModuleOfSystemEnumType != NULL && pModuleOfSystemEnumType->IsSystem()) + { + thisIsAnEnum = true; + } + } } - DWORD cFakeSig; - PCCOR_SIGNATURE pFakeSig = (PCCOR_SIGNATURE)sigBuilder.GetSignature(&cFakeSig); + if (thisIsAnEnum) + { + // If this is an enum, we can return the type of the instance field + IMDInternalImport *pEnumModuleImport = pModuleOfTypeDef->GetMDImport(); + HENUMInternalHolder hEnumField(pEnumModuleImport); + IfFailThrow(hEnumField.EnumInitNoThrow(mdtFieldDef, tkTypeDef)); + mdFieldDef tkFieldDef; + while (hEnumField.EnumNext(&tkFieldDef)) + { + ULONG cMemberSignature; + PCCOR_SIGNATURE pMemberSignature; + DWORD flags; - PCCOR_SIGNATURE pFieldSig = pMemberSignature + 1; // skip the CALLCONV_FIELD + IfFailThrow(pEnumModuleImport->GetFieldDefProps(tkFieldDef, &flags)); - return MetaSig::CompareElementType(pFakeSig, pFieldSig, - pFakeSig + cFakeSig, pMemberSignature + cMemberSignature, - GetModule(), GetModule(), - NULL, NULL); + if (IsFdStatic(flags) || IsFdLiteral(flags)) + { + continue; // Skip static and literal fields + } + IfFailThrow(pEnumModuleImport->GetSigOfFieldDef(tkFieldDef, &cMemberSignature, &pMemberSignature)); -} + SigParser sig(pMemberSignature, cMemberSignature); + uint32_t ulCallConv; + IfFailThrow(sig.GetCallingConvInfo(&ulCallConv)); + if (ulCallConv != IMAGE_CEE_CS_CALLCONV_FIELD) + { + ThrowHR(COR_E_TYPELOAD); + } -//******************************************************************************* -// -// Used pByValueClass cache to mark self-references -// -static BOOL IsSelfRef(MethodTable * pMT) -{ - return pMT == (MethodTable *)-1; + CorElementType elemType; + IfFailThrow(sig.GetElemType(&elemType)); + + switch (elemType) + { + case ELEMENT_TYPE_BOOLEAN: + case ELEMENT_TYPE_CHAR: + case ELEMENT_TYPE_I1: + case ELEMENT_TYPE_U1: + case ELEMENT_TYPE_I2: + case ELEMENT_TYPE_U2: + case ELEMENT_TYPE_I4: + case ELEMENT_TYPE_U4: + case ELEMENT_TYPE_I8: + case ELEMENT_TYPE_U8: + case ELEMENT_TYPE_R4: + case ELEMENT_TYPE_R8: + case ELEMENT_TYPE_U: + case ELEMENT_TYPE_I: + return elemType; + default: + break; + } + + // Invalid enum base type (probably) fall back to using the loaded type. + break; + } + + // Something went wrong looking for the instance field. Fall back to using the loaded type. + _ASSERTE(!"Could not find instance field on enum, fallback to using loaded type"); + MethodTable *pMTEnum = ClassLoader::LoadTypeDefThrowing(pModuleOfTypeDef, tkTypeDef, ClassLoader::ThrowIfNotFound, ClassLoader::PermitUninstDefOrRef).AsMethodTable(); + + if (!pMTEnum->IsEnum()) + { + ThrowHR(COR_E_TYPELOAD); + } + + return pMTEnum->GetApproxFieldDescListRaw()[0].GetFieldType(); + } + else + { + // If this is not an enum, we can return ELEMENT_TYPE_VALUETYPE + return ELEMENT_TYPE_VALUETYPE; + } } //******************************************************************************* @@ -3941,9 +4057,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, if (IsFdLiteral(dwMemberAttrs)) continue; - if (!IsFdPublic(dwMemberAttrs)) - SetHasNonPublicFields(); - IfFailThrow(pInternalImport->GetSigOfFieldDef(bmtMetaData->pFields[i], &cMemberSignature, &pMemberSignature)); // Signature validation IfFailThrow(validateTokenSig(bmtMetaData->pFields[i],pMemberSignature,cMemberSignature,dwMemberAttrs,pInternalImport)); @@ -4095,6 +4208,7 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, case ELEMENT_TYPE_TYPEDBYREF: { + ElementType = ELEMENT_TYPE_VALUETYPE; goto IS_VALUETYPE; } @@ -4135,73 +4249,11 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, // By-value class BAD_FORMAT_NOTHROW_ASSERT(dwByValueClassToken != 0); - if (this->IsValueClass() && (pTokenModule == GetModule())) + if (fIsStatic) { - if (TypeFromToken(dwByValueClassToken) == mdtTypeRef) - { - // It's a typeref - check if it's a class that has a static field of itself - LPCUTF8 pszNameSpace; - LPCUTF8 pszClassName; - if (FAILED(pInternalImport->GetNameOfTypeRef(dwByValueClassToken, &pszNameSpace, &pszClassName))) - { - BuildMethodTableThrowException(IDS_CLASSLOAD_BADFORMAT); - } - - if (IsStrLongerThan((char *)pszClassName, MAX_CLASS_NAME) - || IsStrLongerThan((char *)pszNameSpace, MAX_CLASS_NAME) - || (strlen(pszClassName) + strlen(pszNameSpace) + 1 >= MAX_CLASS_NAME)) - { - BuildMethodTableThrowException(BFA_TYPEREG_NAME_TOO_LONG, mdMethodDefNil); - } - - mdToken tkRes; - if (FAILED(pInternalImport->GetResolutionScopeOfTypeRef(dwByValueClassToken, &tkRes))) - { - BuildMethodTableThrowException(BFA_BAD_TYPEREF_TOKEN, dwByValueClassToken); - } - - if (TypeFromToken(tkRes) == mdtTypeRef) - { - if (!pInternalImport->IsValidToken(tkRes)) - { - BuildMethodTableThrowException(BFA_BAD_TYPEREF_TOKEN, mdMethodDefNil); - } - } - else - { - tkRes = mdTokenNil; - } - - if (FAILED(pInternalImport->FindTypeDef(pszNameSpace, - pszClassName, - tkRes, - &dwByValueClassToken))) - { - dwByValueClassToken = mdTokenNil; - } - } // If field is static typeref - - BOOL selfref = IsSelfReferencingStaticValueTypeField(dwByValueClassToken, - bmtInternal, - bmtGenerics, - pMemberSignature, - cMemberSignature); - - if (selfref) - { // immediately self-referential fields must be static. - if (!fIsStatic) - { - BuildMethodTableThrowException(IDS_CLASSLOAD_VALUEINSTANCEFIELD, mdMethodDefNil); - } - - if (!IsValueClass()) - { - BuildMethodTableThrowException(COR_E_BADIMAGEFORMAT, IDS_CLASSLOAD_MUST_BE_BYVAL, mdTokenNil); - } - - pByValueClass = (MethodTable *)-1; - } - } // If 'this' is a value class + ElementType = GetCorElementTypeOfTypeDefOrRefForStaticField(pTokenModule, dwByValueClassToken); + pByValueClass = (MethodTable *)-1; + } } // TypedReference shares the rest of the code here IS_VALUETYPE: @@ -4213,7 +4265,7 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, { // Loading a non-self-ref valuetype field. OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOAD_APPROXPARENTS); - if (isEnCField || fIsStatic) + if (isEnCField) { // EnCFieldDescs are not created at normal MethodTableBuilder time, and don't need to avoid recursive generic instantiation pByValueClass = fsig.GetArgProps().GetTypeHandleThrowing(GetModule(), @@ -4222,8 +4274,23 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, CLASS_LOAD_APPROXPARENTS, TRUE ).GetMethodTable(); + + if (fIsStatic) + { + if (pByValueClass->IsEnum()) + { + BAD_FORMAT_NOTHROW_ASSERT(pByValueClass->GetNumInstanceFields() == 1); // enums must have exactly one field + FieldDesc * enumField = pByValueClass->GetApproxFieldDescListRaw(); + BAD_FORMAT_NOTHROW_ASSERT(!enumField->IsStatic()); // no real static fields on enums + ElementType = enumField->GetFieldType(); + } + else + { + ElementType = ELEMENT_TYPE_VALUETYPE; + } + } } - else + else if (!fIsStatic) { // We load the approximate type of the field to avoid recursion problems. // MethodTable::DoFullyLoad() will later load it fully @@ -4239,26 +4306,17 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, } } + if (fIsStatic && ElementType != ELEMENT_TYPE_VALUETYPE) + { + fIsByValue = FALSE; // we're going to treat it as the underlying type now + goto GOT_ELEMENT_TYPE; + } + // #FieldDescTypeMorph IF it is an enum, strip it down to its underlying type - if (IsSelfRef(pByValueClass) ? IsEnum() : pByValueClass->IsEnum()) - { - if (IsSelfRef(pByValueClass)) - { // It is self-referencing enum (ValueType) static field - it is forbidden in the ECMA spec, but supported by CLR since v1 - // Note: literal static fields are skipped early in this loop - if (bmtMFDescs->ppFieldDescList[0] == NULL) - { // The field is defined before (the only) instance field - // AppCompat with 3.5 SP1 and 4.0 RTM behavior - BuildMethodTableThrowException(COR_E_BADIMAGEFORMAT, IDS_CLASSLOAD_BAD_FIELD, mdTokenNil); - } - // We will treat the field type as if it was its underlying type (we know its size and will check correctly RVA with the size - // later in this method) - // Therefore we do not have to run code:VerifySelfReferencingStaticValueTypeFields_WithRVA or code:#SelfReferencingStaticValueTypeField_Checks - } - BAD_FORMAT_NOTHROW_ASSERT((IsSelfRef(pByValueClass) ? - bmtEnumFields->dwNumInstanceFields : pByValueClass->GetNumInstanceFields()) - == 1); // enums must have exactly one field - FieldDesc * enumField = IsSelfRef(pByValueClass) ? - bmtMFDescs->ppFieldDescList[0] : pByValueClass->GetApproxFieldDescListRaw(); + if (!fIsStatic && pByValueClass->IsEnum()) + { + BAD_FORMAT_NOTHROW_ASSERT(pByValueClass->GetNumInstanceFields() == 1); // enums must have exactly one field + FieldDesc * enumField = pByValueClass->GetApproxFieldDescListRaw(); BAD_FORMAT_NOTHROW_ASSERT(!enumField->IsStatic()); // no real static fields on enums ElementType = enumField->GetFieldType(); BAD_FORMAT_NOTHROW_ASSERT(ElementType != ELEMENT_TYPE_VALUETYPE); @@ -4267,13 +4325,8 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, } // Check ByRefLike fields - if (!IsSelfRef(pByValueClass) && pByValueClass->IsByRefLike()) + if (!fIsStatic && pByValueClass->IsByRefLike()) { - if (fIsStatic) - { - // Byref-like types cannot be used for static fields - BuildMethodTableThrowException(IDS_CLASSLOAD_BYREF_OR_BYREFLIKE_STATICFIELD); - } if (!bmtFP->fIsByRefLikeType) { // Non-byref-like types cannot contain byref-like instance fields @@ -4281,12 +4334,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, } } - if (!IsSelfRef(pByValueClass) && pByValueClass->GetClass()->HasNonPublicFields()) - { // If a class has a field of type ValueType with non-public fields in it, - // the class must "inherit" this characteristic - SetHasNonPublicFields(); - } - if (!fHasRVA) { if (!fIsStatic) @@ -4294,8 +4341,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, // Inherit instance attributes EEClass * pFieldClass = pByValueClass->GetClass(); - if (pFieldClass->HasNonPublicFields()) - SetHasNonPublicFields(); if (pFieldClass->HasFieldsWhichMustBeInited()) SetHasFieldsWhichMustBeInited(); @@ -4325,7 +4370,7 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, // Thread static fields come after instance fields and regular static fields in this list if (fIsThreadStatic) { - (*pByValueClassCache)[bmtEnumFields->dwNumInstanceFields + bmtEnumFields->dwNumStaticFields - bmtEnumFields->dwNumThreadStaticFields + dwCurrentThreadStaticField] = pByValueClass; + (*pByValueClassCache)[bmtEnumFields->dwNumInstanceFields + bmtEnumFields->dwNumStaticFields - bmtEnumFields->dwNumThreadStaticFields + dwCurrentThreadStaticField] = NULL; // make sure to record the correct size for static field // layout dwLog2FieldSize = LOG2_PTRSIZE; // handle @@ -4333,7 +4378,7 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, // Regular static fields come after instance fields in this list else if (fIsStatic) { - (*pByValueClassCache)[bmtEnumFields->dwNumInstanceFields + dwCurrentStaticField] = pByValueClass; + (*pByValueClassCache)[bmtEnumFields->dwNumInstanceFields + dwCurrentStaticField] = NULL; // make sure to record the correct size for static field // layout dwLog2FieldSize = LOG2_PTRSIZE; // handle @@ -4450,21 +4495,8 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, BAD_FORMAT_NOTHROW_ASSERT(!"ObjectRef in an RVA field"); BuildMethodTableThrowException(COR_E_BADIMAGEFORMAT, IDS_CLASSLOAD_BAD_FIELD, mdTokenNil); } - if (FieldDescElementType == ELEMENT_TYPE_VALUETYPE) - { - if (IsSelfRef(pByValueClass)) - { // We will verify self-referencing statics after the loop through all fields - see code:#SelfReferencingStaticValueTypeField_Checks - bmtFP->fHasSelfReferencingStaticValueTypeField_WithRVA = TRUE; - } - else - { - if (pByValueClass->GetClass()->HasFieldsWhichMustBeInited()) - { // RVA fields are not allowed to have GC pointers. - BAD_FORMAT_NOTHROW_ASSERT(!"ObjectRef in an RVA field"); - BuildMethodTableThrowException(COR_E_BADIMAGEFORMAT, IDS_CLASSLOAD_BAD_FIELD, mdTokenNil); - } - } - } + + SetHasRVAStaticFields(); // The PE should be loaded by now. _ASSERT(GetModule()->GetPEAssembly()->IsLoaded()); @@ -4510,20 +4542,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, } // We processed all fields - //#SelfReferencingStaticValueTypeField_Checks - if (bmtFP->fHasSelfReferencingStaticValueTypeField_WithRVA) - { // The type has self-referencing static ValueType field with RVA, do more checks now that depend on all fields being processed - - // For enums we already checked its underlying type, we should not get here - _ASSERTE(!IsEnum()); - - if (HasFieldsWhichMustBeInited()) - { // RVA fields are not allowed to have GC pointers. - BAD_FORMAT_NOTHROW_ASSERT(!"ObjectRef in an RVA self-referencing static field"); - BuildMethodTableThrowException(COR_E_BADIMAGEFORMAT, IDS_CLASSLOAD_BAD_FIELD, mdTokenNil); - } - } - DWORD dwNumInstanceFields = dwCurrentDeclaredField + (HasParent() ? GetParentMethodTable()->GetNumInstanceFields() : 0); DWORD dwNumStaticFields = bmtEnumFields->dwNumStaticFields; DWORD dwNumThreadStaticFields = bmtEnumFields->dwNumThreadStaticFields; @@ -4557,40 +4575,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, return; } // MethodTableBuilder::InitializeFieldDescs -//******************************************************************************* -// Verify self-referencing static ValueType fields with RVA (when the size of the ValueType is known). -void -MethodTableBuilder::VerifySelfReferencingStaticValueTypeFields_WithRVA( - MethodTable ** pByValueClassCache) -{ - STANDARD_VM_CONTRACT; - - _ASSERTE(bmtFP->fHasSelfReferencingStaticValueTypeField_WithRVA); - // Enum's static self-referencing fields have been verified as the underlying type of the enum, we should not get here for them - _ASSERTE(!IsEnum()); - // The size of the ValueType should be known at this point (the caller throws if it is 0) - _ASSERTE(bmtFP->NumInstanceFieldBytes != 0); - - FieldDesc * pFieldDescList = GetApproxFieldDescListRaw(); - DWORD nFirstThreadStaticFieldIndex = bmtEnumFields->dwNumInstanceFields + bmtEnumFields->dwNumStaticFields - bmtEnumFields->dwNumThreadStaticFields; - for (DWORD i = bmtEnumFields->dwNumInstanceFields; i < nFirstThreadStaticFieldIndex; i++) - { - FieldDesc * pFD = &pFieldDescList[i]; - _ASSERTE(pFD->IsStatic()); - - if (pFD->IsRVA() && pFD->IsByValue()) - { - _ASSERTE(pByValueClassCache[i] != NULL); - - if (IsSelfRef(pByValueClassCache[i])) - { - DWORD rva; - IfFailThrow(GetMDImport()->GetFieldRVA(pFD->GetMemberDef(), &rva)); - } - } - } -} // MethodTableBuilder::VerifySelfReferencingStaticValueTypeFields_WithRVA - //******************************************************************************* // Returns true if hEnclosingTypeCandidate encloses, at any arbitrary depth, // hNestedTypeCandidate; returns false otherwise. @@ -6134,8 +6118,8 @@ MethodTableBuilder::InitMethodDesc( DWORD dwImplFlags, DWORD dwMemberAttrs, BOOL fEnC, - DWORD RVA, // Only needed for NDirect case - IMDInternalImport * pIMDII, // Needed for NDirect, EEImpl(Delegate) cases + DWORD RVA, // Only needed for PInvoke case + IMDInternalImport * pIMDII, // Needed for PInvoke, EEImpl(Delegate) cases LPCSTR pMethodName, // Only needed for mcEEImpl (Delegate) case Signature sig, // Only needed for the Async thunk case AsyncMethodKind asyncKind @@ -6163,18 +6147,18 @@ MethodTableBuilder::InitMethodDesc( { case mcPInvoke: { - // NDirect specific initialization. - NDirectMethodDesc *pNewNMD = (NDirectMethodDesc*)pNewMD; + // PInvoke specific initialization. + PInvokeMethodDesc *pNewNMD = (PInvokeMethodDesc*)pNewMD; -#ifdef HAS_NDIRECT_IMPORT_PRECODE - pNewNMD->ndirect.m_pImportThunkGlue = Precode::Allocate(PRECODE_NDIRECT_IMPORT, pNewMD, - GetLoaderAllocator(), GetMemTracker())->AsNDirectImportPrecode(); -#else // !HAS_NDIRECT_IMPORT_PRECODE - pNewNMD->GetNDirectImportThunkGlue()->Init(pNewNMD); -#endif // !HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_PINVOKE_IMPORT_PRECODE + pNewNMD->m_pImportThunkGlue = Precode::Allocate(PRECODE_PINVOKE_IMPORT, pNewMD, + GetLoaderAllocator(), GetMemTracker())->AsPInvokeImportPrecode(); +#else // !HAS_PINVOKE_IMPORT_PRECODE + pNewNMD->GetPInvokeImportThunkGlue()->Init(pNewNMD); +#endif // !HAS_PINVOKE_IMPORT_PRECODE #if defined(TARGET_X86) - pNewNMD->ndirect.m_cbStackArgumentSize = 0xFFFF; + pNewNMD->m_cbStackArgumentSize = 0xFFFF; #endif // defined(TARGET_X86) // If the RVA of a native method is set, this is an early-bound IJW call @@ -6185,7 +6169,7 @@ MethodTableBuilder::InitMethodDesc( pNewNMD->SetIsEarlyBound(); } - pNewNMD->ndirect.m_pNDirectTarget = pNewNMD->GetNDirectImportThunkGlue()->GetEntrypoint(); + pNewNMD->m_pPInvokeTarget = pNewNMD->GetPInvokeImportThunkGlue()->GetEntrypoint(); } break; @@ -6278,7 +6262,7 @@ MethodTableBuilder::InitMethodDesc( DWORD stressSynchronizedVal = stressSynchronized.val(CLRConfig::INTERNAL_stressSynchronized); bool isStressSynchronized = stressSynchronizedVal && - pNewMD->IsIL() && // Synchronized is not supported on Ecalls, NDirect method, etc + pNewMD->IsIL() && // Synchronized is not supported on Ecalls, PInvoke method, etc // IsValueClass() and IsEnum() do not work for System.ValueType and System.Enum themselves ((g_pValueTypeClass != NULL && g_pEnumClass != NULL && !IsValueClass()) || // Can not synchronize on byref "this" diff --git a/src/coreclr/vm/methodtablebuilder.h b/src/coreclr/vm/methodtablebuilder.h index ebd987467d9c61..ccbca89b16c304 100644 --- a/src/coreclr/vm/methodtablebuilder.h +++ b/src/coreclr/vm/methodtablebuilder.h @@ -189,7 +189,6 @@ class MethodTableBuilder void SetIsComClassInterface() { WRAPPER_NO_CONTRACT; GetHalfBakedClass()->SetIsComClassInterface(); } #endif // FEATURE_COMINTEROP BOOL IsEnum() { WRAPPER_NO_CONTRACT; return bmtProp->fIsEnum; } - BOOL HasNonPublicFields() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->HasNonPublicFields(); } BOOL IsValueClass() { WRAPPER_NO_CONTRACT; return bmtProp->fIsValueClass; } BOOL IsUnsafeValueClass() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->IsUnsafeValueClass(); } BOOL IsAbstract() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->IsAbstract(); } @@ -222,7 +221,7 @@ class MethodTableBuilder // we create that object. void SetUnsafeValueClass() { WRAPPER_NO_CONTRACT; GetHalfBakedClass()->SetUnsafeValueClass(); } void SetHasFieldsWhichMustBeInited() { WRAPPER_NO_CONTRACT; GetHalfBakedClass()->SetHasFieldsWhichMustBeInited(); } - void SetHasNonPublicFields() { WRAPPER_NO_CONTRACT; GetHalfBakedClass()->SetHasNonPublicFields(); } + void SetHasRVAStaticFields() { WRAPPER_NO_CONTRACT; GetHalfBakedClass()->SetHasRVAStaticFields(); } void SetNumHandleRegularStatics(WORD x) { WRAPPER_NO_CONTRACT; GetHalfBakedClass()->SetNumHandleRegularStatics(x); } void SetNumHandleThreadStatics(WORD x) { WRAPPER_NO_CONTRACT; GetHalfBakedClass()->SetNumHandleThreadStatics(x); } void SetAlign8Candidate() { WRAPPER_NO_CONTRACT; GetHalfBakedClass()->SetAlign8Candidate(); } @@ -2091,7 +2090,6 @@ class MethodTableBuilder bool fIsAllGCPointers; bool fIsByRefLikeType; bool fHasFixedAddressValueTypes; - bool fHasSelfReferencingStaticValueTypeField_WithRVA; // These data members are specific to regular statics DWORD RegularStaticFieldStart[MAX_LOG2_PRIMITIVE_FIELD_SIZE+1]; // Byte offset where to start placing fields of this size @@ -2671,10 +2669,9 @@ class MethodTableBuilder unsigned * totalDeclaredSize); // -------------------------------------------------------------------------------------------- - // Verify self-referencing static ValueType fields with RVA (when the size of the ValueType is known). - void - VerifySelfReferencingStaticValueTypeFields_WithRVA( - MethodTable ** pByValueClassCache); + // Returns the CorElementType for the type referenced by typeDefOrRef, which must not be + // byreflike, and must be a valuetype of some form (enum or valuetype) + CorElementType GetCorElementTypeOfTypeDefOrRefForStaticField(Module* module, mdToken typeDefOrRef); // -------------------------------------------------------------------------------------------- // Returns TRUE if dwByValueClassToken refers to the type being built; otherwise returns FALSE. @@ -2701,8 +2698,8 @@ class MethodTableBuilder DWORD dwImplFlags, DWORD dwMemberAttrs, BOOL fEnC, - DWORD RVA, // Only needed for NDirect case - IMDInternalImport * pIMDII, // Needed for NDirect, EEImpl(Delegate) cases + DWORD RVA, // Only needed for PInvoke case + IMDInternalImport * pIMDII, // Needed for PInvoke, EEImpl(Delegate) cases LPCSTR pMethodName, // Only needed for mcEEImpl (Delegate) case Signature sig, // Only needed for the Async thunk case AsyncMethodKind asyncKind diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp index 27b6d9f83aec97..fd695c46741bc1 100644 --- a/src/coreclr/vm/mlinfo.cpp +++ b/src/coreclr/vm/mlinfo.cpp @@ -2077,7 +2077,7 @@ MarshalInfo::MarshalInfo(Module* pModule, goto lExit; } -VOID MarshalInfo::EmitOrThrowInteropParamException(NDirectStubLinker* psl, BOOL fMngToNative, UINT resID, UINT paramIdx) +VOID MarshalInfo::EmitOrThrowInteropParamException(PInvokeStubLinker* psl, BOOL fMngToNative, UINT resID, UINT paramIdx) { CONTRACTL { @@ -2241,7 +2241,7 @@ HRESULT MarshalInfo::HandleArrayElemType(NativeTypeParamInfo *pParamInfo, TypeHa return S_OK; } -ILMarshaler* CreateILMarshaler(MarshalInfo::MarshalType mtype, NDirectStubLinker* psl) +ILMarshaler* CreateILMarshaler(MarshalInfo::MarshalType mtype, PInvokeStubLinker* psl) { CONTRACTL { @@ -2265,7 +2265,7 @@ ILMarshaler* CreateILMarshaler(MarshalInfo::MarshalType mtype, NDirectStubLinker UNREACHABLE_MSG("unexpected MarshalType passed to CreateILMarshaler"); } - pMarshaler->SetNDirectStubLinker(psl); + pMarshaler->SetPInvokeStubLinker(psl); return pMarshaler; } @@ -2318,7 +2318,7 @@ namespace } } -void MarshalInfo::GenerateArgumentIL(NDirectStubLinker* psl, +void MarshalInfo::GenerateArgumentIL(PInvokeStubLinker* psl, int argOffset, // the argument's index is m_paramidx + argOffset BOOL fMngToNative) { @@ -2388,12 +2388,12 @@ void MarshalInfo::GenerateArgumentIL(NDirectStubLinker* psl, if (pMarshaler->NeedsMarshalCleanupIndex()) { // we don't bother writing to the counter if marshaling does not need cleanup - psl->EmitSetArgMarshalIndex(pcsMarshal, NDirectStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_paramidx + argOffset); + psl->EmitSetArgMarshalIndex(pcsMarshal, PInvokeStubLinker::CLEANUP_INDEX_ARG0_MARSHAL + m_paramidx + argOffset); } if (pMarshaler->NeedsUnmarshalCleanupIndex()) { // we don't bother writing to the counter if unmarshaling does not need exception cleanup - psl->EmitSetArgMarshalIndex(pcsUnmarshal, NDirectStubLinker::CLEANUP_INDEX_ARG0_UNMARSHAL + m_paramidx + argOffset); + psl->EmitSetArgMarshalIndex(pcsUnmarshal, PInvokeStubLinker::CLEANUP_INDEX_ARG0_UNMARSHAL + m_paramidx + argOffset); } pcsMarshal->EmitNOP("// } argument"); @@ -2411,7 +2411,7 @@ void MarshalInfo::GenerateArgumentIL(NDirectStubLinker* psl, } } -void MarshalInfo::GenerateReturnIL(NDirectStubLinker* psl, +void MarshalInfo::GenerateReturnIL(PInvokeStubLinker* psl, int argOffset, BOOL fMngToNative, BOOL fieldGetter, @@ -2489,7 +2489,7 @@ void MarshalInfo::GenerateReturnIL(NDirectStubLinker* psl, } } -void MarshalInfo::GenerateFieldIL(NDirectStubLinker* psl, +void MarshalInfo::GenerateFieldIL(PInvokeStubLinker* psl, UINT32 managedOffset, UINT32 nativeOffset, FieldDesc* pFieldDesc) diff --git a/src/coreclr/vm/mlinfo.h b/src/coreclr/vm/mlinfo.h index 3d2c5186556191..947f8a87f50b39 100644 --- a/src/coreclr/vm/mlinfo.h +++ b/src/coreclr/vm/mlinfo.h @@ -112,7 +112,7 @@ struct OverrideProcArgs }; }; -typedef MarshalerOverrideStatus (*OVERRIDEPROC)(NDirectStubLinker* psl, +typedef MarshalerOverrideStatus (*OVERRIDEPROC)(PInvokeStubLinker* psl, BOOL byref, BOOL fin, BOOL fout, @@ -121,7 +121,7 @@ typedef MarshalerOverrideStatus (*OVERRIDEPROC)(NDirectStubLinker* psl, UINT* pResID, UINT argidx); -typedef MarshalerOverrideStatus (*RETURNOVERRIDEPROC)(NDirectStubLinker* psl, +typedef MarshalerOverrideStatus (*RETURNOVERRIDEPROC)(PInvokeStubLinker* psl, BOOL fManagedToNative, BOOL fHresultSwap, OverrideProcArgs* pargs, @@ -301,7 +301,7 @@ class MarshalInfo ); - VOID EmitOrThrowInteropParamException(NDirectStubLinker* psl, BOOL fMngToNative, UINT resID, UINT paramIdx); + VOID EmitOrThrowInteropParamException(PInvokeStubLinker* psl, BOOL fMngToNative, UINT resID, UINT paramIdx); void ThrowTypeLoadExceptionForInvalidFieldMarshal(FieldDesc* pFieldDesc, UINT resID); @@ -314,17 +314,17 @@ class MarshalInfo Assembly *pAssembly, BOOL isArrayClass = FALSE); - void GenerateArgumentIL(NDirectStubLinker* psl, + void GenerateArgumentIL(PInvokeStubLinker* psl, int argOffset, // the argument's index is m_paramidx + argOffset BOOL fMngToNative); - void GenerateReturnIL(NDirectStubLinker* psl, + void GenerateReturnIL(PInvokeStubLinker* psl, int argOffset, // the argument's index is m_paramidx + argOffset BOOL fMngToNative, BOOL fieldGetter, BOOL retval); - void GenerateFieldIL(NDirectStubLinker* psl, + void GenerateFieldIL(PInvokeStubLinker* psl, UINT32 managedOffset, // the field's byte offset into the managed object UINT32 nativeOffset, // the field's byte offset into the native object FieldDesc* pFieldDesc); // The field descriptor for reporting errors diff --git a/src/coreclr/vm/nativelibrary.cpp b/src/coreclr/vm/nativelibrary.cpp index 4d7bee8c8a74d9..534e25db221cc1 100644 --- a/src/coreclr/vm/nativelibrary.cpp +++ b/src/coreclr/vm/nativelibrary.cpp @@ -227,7 +227,7 @@ namespace // If a pInvoke has the DefaultDllImportSearchPathsAttribute, get DllImportSearchPathFlags from it, and returns true. // Otherwise, if the containing assembly has the DefaultDllImportSearchPathsAttribute, get DllImportSearchPathFlags from it, and returns true. // Otherwise, get CoreCLR's default value for DllImportSearchPathFlags, and return false. - BOOL GetDllImportSearchPathFlags(NDirectMethodDesc * pMD, DWORD *dllImportSearchPathFlags, BOOL *searchAssemblyDirectory) + BOOL GetDllImportSearchPathFlags(PInvokeMethodDesc * pMD, DWORD *dllImportSearchPathFlags, BOOL *searchAssemblyDirectory) { STANDARD_VM_CONTRACT; @@ -356,13 +356,13 @@ namespace GCPROTECT_BEGIN(pUnmanagedDllName); // Get the pointer to the managed assembly load context - INT_PTR ptrManagedAssemblyLoadContext = pCurrentBinder->GetManagedAssemblyLoadContext(); + INT_PTR ptrAssemblyLoadContext = pCurrentBinder->GetAssemblyLoadContext(); // Prepare to invoke System.Runtime.Loader.AssemblyLoadContext.ResolveUnmanagedDll method. PREPARE_NONVIRTUAL_CALLSITE(METHOD__ASSEMBLYLOADCONTEXT__RESOLVEUNMANAGEDDLL); DECLARE_ARGHOLDER_ARRAY(args, 2); args[ARGNUM_0] = STRINGREF_TO_ARGHOLDER(pUnmanagedDllName); - args[ARGNUM_1] = PTR_TO_ARGHOLDER(ptrManagedAssemblyLoadContext); + args[ARGNUM_1] = PTR_TO_ARGHOLDER(ptrAssemblyLoadContext); // Make the call CALL_MANAGED_METHOD(hmod, NATIVE_LIBRARY_HANDLE, args); @@ -373,20 +373,20 @@ namespace } // Return the AssemblyLoadContext for an assembly - INT_PTR GetManagedAssemblyLoadContext(Assembly* pAssembly) + INT_PTR GetAssemblyLoadContext(Assembly* pAssembly) { STANDARD_VM_CONTRACT; PTR_AssemblyBinder pBinder = pAssembly->GetPEAssembly()->GetAssemblyBinder(); - return pBinder->GetManagedAssemblyLoadContext(); + return pBinder->GetAssemblyLoadContext(); } NATIVE_LIBRARY_HANDLE LoadNativeLibraryViaAssemblyLoadContextEvent(Assembly * pAssembly, PCWSTR wszLibName) { STANDARD_VM_CONTRACT; - INT_PTR ptrManagedAssemblyLoadContext = GetManagedAssemblyLoadContext(pAssembly); - if (ptrManagedAssemblyLoadContext == 0) + INT_PTR ptrAssemblyLoadContext = GetAssemblyLoadContext(pAssembly); + if (ptrAssemblyLoadContext == 0) { return NULL; } @@ -413,7 +413,7 @@ namespace DECLARE_ARGHOLDER_ARRAY(args, 3); args[ARGNUM_0] = STRINGREF_TO_ARGHOLDER(gc.DllName); args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(gc.AssemblyRef); - args[ARGNUM_2] = PTR_TO_ARGHOLDER(ptrManagedAssemblyLoadContext); + args[ARGNUM_2] = PTR_TO_ARGHOLDER(ptrAssemblyLoadContext); // Make the call CALL_MANAGED_METHOD(hmod, NATIVE_LIBRARY_HANDLE, args); @@ -423,7 +423,7 @@ namespace return hmod; } - NATIVE_LIBRARY_HANDLE LoadNativeLibraryViaDllImportResolver(NDirectMethodDesc * pMD, LPCWSTR wszLibName) + NATIVE_LIBRARY_HANDLE LoadNativeLibraryViaDllImportResolver(PInvokeMethodDesc * pMD, LPCWSTR wszLibName) { STANDARD_VM_CONTRACT; @@ -756,7 +756,7 @@ namespace return hmod; } - NATIVE_LIBRARY_HANDLE LoadNativeLibraryBySearch(NDirectMethodDesc *pMD, LoadLibErrorTracker *pErrorTracker, PCWSTR wszLibName) + NATIVE_LIBRARY_HANDLE LoadNativeLibraryBySearch(PInvokeMethodDesc *pMD, LoadLibErrorTracker *pErrorTracker, PCWSTR wszLibName) { STANDARD_VM_CONTRACT; @@ -828,7 +828,7 @@ NATIVE_LIBRARY_HANDLE NativeLibrary::LoadLibraryByName(LPCWSTR libraryName, Asse namespace { - NATIVE_LIBRARY_HANDLE LoadNativeLibrary(NDirectMethodDesc * pMD, LoadLibErrorTracker * pErrorTracker) + NATIVE_LIBRARY_HANDLE LoadNativeLibrary(PInvokeMethodDesc * pMD, LoadLibErrorTracker * pErrorTracker) { CONTRACTL { @@ -883,7 +883,7 @@ namespace } } -NATIVE_LIBRARY_HANDLE NativeLibrary::LoadLibraryFromMethodDesc(NDirectMethodDesc * pMD) +NATIVE_LIBRARY_HANDLE NativeLibrary::LoadLibraryFromMethodDesc(PInvokeMethodDesc * pMD) { CONTRACT(NATIVE_LIBRARY_HANDLE) { diff --git a/src/coreclr/vm/nativelibrary.h b/src/coreclr/vm/nativelibrary.h index f05146862c285d..0745a5a3e41b03 100644 --- a/src/coreclr/vm/nativelibrary.h +++ b/src/coreclr/vm/nativelibrary.h @@ -16,7 +16,7 @@ class NativeLibrary static void FreeNativeLibrary(NATIVE_LIBRARY_HANDLE handle); static INT_PTR GetNativeLibraryExport(NATIVE_LIBRARY_HANDLE handle, LPCWSTR symbolName, BOOL throwOnError); - static NATIVE_LIBRARY_HANDLE LoadLibraryFromMethodDesc(NDirectMethodDesc *pMD); + static NATIVE_LIBRARY_HANDLE LoadLibraryFromMethodDesc(PInvokeMethodDesc *pMD); }; #endif // _NATIVELIBRARY_H_ diff --git a/src/coreclr/vm/olevariant.cpp b/src/coreclr/vm/olevariant.cpp index 67ea84d55afc5b..78cacd10afbe6a 100644 --- a/src/coreclr/vm/olevariant.cpp +++ b/src/coreclr/vm/olevariant.cpp @@ -3298,7 +3298,7 @@ void OleVariant::MarshalArrayVariantOleToObject(const VARIANT* pOleVariant, { GCX_PREEMP(); - pStructMarshalStub = NDirect::CreateStructMarshalILStub(pElemMT); + pStructMarshalStub = PInvoke::CreateStructMarshalILStub(pElemMT); } BASEARRAYREF pArrayRef = CreateArrayRefForSafeArray(pSafeArray, vt, pElemMT); @@ -3343,7 +3343,7 @@ void OleVariant::MarshalArrayVariantObjectToOle(OBJECTREF * const & pObj, { GCX_PREEMP(); - pStructMarshalStub = NDirect::CreateStructMarshalILStub(pElemMT); + pStructMarshalStub = PInvoke::CreateStructMarshalILStub(pElemMT); } GCPROTECT_END(); @@ -3385,7 +3385,7 @@ void OleVariant::MarshalArrayVariantOleRefToObject(const VARIANT *pOleVariant, { GCX_PREEMP(); - pStructMarshalStub = NDirect::CreateStructMarshalILStub(pElemMT); + pStructMarshalStub = PInvoke::CreateStructMarshalILStub(pElemMT); } BASEARRAYREF pArrayRef = CreateArrayRefForSafeArray(pSafeArray, vt, pElemMT); @@ -3886,7 +3886,7 @@ void OleVariant::ConvertValueClassToVariant(OBJECTREF *pBoxedValueClass, VARIANT MethodDesc* pStructMarshalStub; { GCX_PREEMP(); - pStructMarshalStub = NDirect::CreateStructMarshalILStub(pValueClassMT); + pStructMarshalStub = PInvoke::CreateStructMarshalILStub(pValueClassMT); } MarshalStructViaILStub(pStructMarshalStub, (*pBoxedValueClass)->GetData(), (BYTE*)V_RECORD(pRecHolder), StructMarshalStubs::MarshalOperation::Marshal); diff --git a/src/coreclr/vm/peassembly.cpp b/src/coreclr/vm/peassembly.cpp index adc08d6fc020b6..6551714eab7817 100644 --- a/src/coreclr/vm/peassembly.cpp +++ b/src/coreclr/vm/peassembly.cpp @@ -68,7 +68,13 @@ void PEAssembly::EnsureLoaded() RETURN; // Ensure that loaded layout is available. - PEImageLayout* pLayout = GetPEImage()->GetOrCreateLayout(PEImageLayout::LAYOUT_LOADED); + PEImageLayout* pLayout = GetPEImage()->GetOrCreateLayout( +#ifdef PEIMAGE_FLAT_LAYOUT_ONLY + PEImageLayout::LAYOUT_FLAT +#else + PEImageLayout::LAYOUT_LOADED +#endif + ); if (pLayout == NULL) { EEFileLoadException::Throw(this, COR_E_BADIMAGEFORMAT, NULL); @@ -641,6 +647,7 @@ PEAssembly::PEAssembly( BINDER_SPACE::Assembly* pBindResultInfo, IMetaDataEmit* pEmit, BOOL isSystem, + AssemblyBinder* pFallbackBinder /*= NULL*/, PEImage * pPEImage /*= NULL*/, BINDER_SPACE::Assembly * pHostAssembly /*= NULL*/) { @@ -664,7 +671,7 @@ PEAssembly::PEAssembly( m_refCount = 1; m_isSystem = isSystem; m_pHostAssembly = nullptr; - m_pFallbackBinder = nullptr; + m_pAssemblyBinder = nullptr; pPEImage = pBindResultInfo ? pBindResultInfo->GetPEImage() : pPEImage; if (pPEImage) @@ -716,6 +723,15 @@ PEAssembly::PEAssembly( m_pHostAssembly = pBindResultInfo; } + if (m_pHostAssembly != nullptr) + { + m_pAssemblyBinder = m_pHostAssembly->GetBinder(); + } + else + { + m_pAssemblyBinder = pFallbackBinder; + } + #ifdef LOGGING GetPathOrCodeBase(m_debugName); m_pDebugName = m_debugName.GetUTF8(); @@ -734,6 +750,7 @@ PEAssembly *PEAssembly::Open( nullptr, // BindResult nullptr, // IMetaDataEmit FALSE, // isSystem + nullptr, // FallbackBinder pPEImageIL, pHostAssembly); @@ -827,7 +844,7 @@ PEAssembly* PEAssembly::Open(BINDER_SPACE::Assembly* pBindResult) }; /* static */ -PEAssembly *PEAssembly::Create(IMetaDataAssemblyEmit *pAssemblyEmit) +PEAssembly *PEAssembly::Create(IMetaDataAssemblyEmit *pAssemblyEmit, AssemblyBinder *pFallbackBinder) { CONTRACT(PEAssembly *) { @@ -841,7 +858,7 @@ PEAssembly *PEAssembly::Create(IMetaDataAssemblyEmit *pAssemblyEmit) // we have.) SafeComHolder pEmit; pAssemblyEmit->QueryInterface(IID_IMetaDataEmit, (void **)&pEmit); - RETURN new PEAssembly(NULL, pEmit, FALSE); + RETURN new PEAssembly(NULL, pEmit, FALSE, pFallbackBinder); } #endif // #ifndef DACCESS_COMPILE @@ -1077,25 +1094,5 @@ TADDR PEAssembly::GetMDInternalRWAddress() // Returns the AssemblyBinder* instance associated with the PEAssembly PTR_AssemblyBinder PEAssembly::GetAssemblyBinder() { - LIMITED_METHOD_CONTRACT; - - PTR_AssemblyBinder pBinder = NULL; - - PTR_BINDER_SPACE_Assembly pHostAssembly = GetHostAssembly(); - if (pHostAssembly) - { - pBinder = pHostAssembly->GetBinder(); - } - else - { - // If we do not have a host assembly, check if we are dealing with - // a dynamically emitted assembly and if so, use its fallback load context - // binder reference. - if (IsReflectionEmit()) - { - pBinder = GetFallbackBinder(); - } - } - - return pBinder; + return m_pAssemblyBinder; } diff --git a/src/coreclr/vm/peassembly.h b/src/coreclr/vm/peassembly.h index 43b14abe9fe41d..fe1aa193ab1970 100644 --- a/src/coreclr/vm/peassembly.h +++ b/src/coreclr/vm/peassembly.h @@ -312,20 +312,18 @@ class PEAssembly final // For Dynamic assemblies this is the fallback binder. PTR_AssemblyBinder GetAssemblyBinder(); -#ifndef DACCESS_COMPILE - void SetFallbackBinder(PTR_AssemblyBinder pFallbackBinder) - { - LIMITED_METHOD_CONTRACT; - m_pFallbackBinder = pFallbackBinder; - } - -#endif //!DACCESS_COMPILE - + // For certain assemblies, we do not have m_pHostAssembly since they are not bound using an actual binder. + // An example is Ref-Emitted assemblies. Thus, when such assemblies trigger load of their dependencies, + // we need to ensure they are loaded in appropriate load context. + // + // To enable this, we maintain a concept of "FallbackBinder", which will be set to the Binder of the + // assembly that created the dynamic assembly. If the creator assembly is dynamic itself, then its fallback + // load context would be propagated to the assembly being dynamically generated. PTR_AssemblyBinder GetFallbackBinder() { LIMITED_METHOD_CONTRACT; - return m_pFallbackBinder; + return (m_pHostAssembly != NULL) ? NULL : m_pAssemblyBinder; } // ------------------------------------------------------------ @@ -341,7 +339,7 @@ class PEAssembly final static PEAssembly* Open(BINDER_SPACE::Assembly* pBindResult); - static PEAssembly* Create(IMetaDataAssemblyEmit* pEmit); + static PEAssembly* Create(IMetaDataAssemblyEmit* pEmit, AssemblyBinder* pFallbackBinder); // ------------------------------------------------------------ // Utility functions @@ -372,6 +370,7 @@ class PEAssembly final BINDER_SPACE::Assembly* pBindResultInfo, IMetaDataEmit* pEmit, BOOL isSystem, + AssemblyBinder* pFallbackBinder = NULL, PEImage* pPEImageIL = NULL, BINDER_SPACE::Assembly* pHostAssembly = NULL ); @@ -425,15 +424,7 @@ class PEAssembly final bool m_isSystem; PTR_BINDER_SPACE_Assembly m_pHostAssembly; - - // For certain assemblies, we do not have m_pHostAssembly since they are not bound using an actual binder. - // An example is Ref-Emitted assemblies. Thus, when such assemblies trigger load of their dependencies, - // we need to ensure they are loaded in appropriate load context. - // - // To enable this, we maintain a concept of "FallbackBinder", which will be set to the Binder of the - // assembly that created the dynamic assembly. If the creator assembly is dynamic itself, then its fallback - // load context would be propagated to the assembly being dynamically generated. - PTR_AssemblyBinder m_pFallbackBinder; + PTR_AssemblyBinder m_pAssemblyBinder; friend struct cdac_data; }; // class PEAssembly @@ -442,6 +433,7 @@ template<> struct cdac_data { static constexpr size_t PEImage = offsetof(PEAssembly, m_PEImage); + static constexpr size_t AssemblyBinder = offsetof(PEAssembly, m_pAssemblyBinder); }; typedef ReleaseHolder PEAssemblyHolder; diff --git a/src/coreclr/vm/peassembly.inl b/src/coreclr/vm/peassembly.inl index eb485215f14cf2..3153136eecd897 100644 --- a/src/coreclr/vm/peassembly.inl +++ b/src/coreclr/vm/peassembly.inl @@ -329,7 +329,7 @@ inline BOOL PEAssembly::IsReadyToRun() } CONTRACTL_END; - if (HasPEImage()) + if (HasPEImage() && HasLoadedPEImage()) { return GetLoadedLayout()->HasReadyToRunHeader(); } diff --git a/src/coreclr/vm/peimage.cpp b/src/coreclr/vm/peimage.cpp index 090c2ed5b864ed..4362b3b571d28e 100644 --- a/src/coreclr/vm/peimage.cpp +++ b/src/coreclr/vm/peimage.cpp @@ -636,11 +636,13 @@ PTR_PEImageLayout PEImage::GetOrCreateLayoutInternal(DWORD imageLayoutMask) _ASSERTE(bIsLoadedLayoutSuitable || bIsFlatLayoutSuitable); +#ifndef PEIMAGE_FLAT_LAYOUT_ONLY if (bIsLoadedLayoutPreferred) { _ASSERTE(bIsLoadedLayoutSuitable); pRetVal = PEImage::CreateLoadedLayout(!bIsFlatLayoutSuitable); } +#endif if (pRetVal == NULL) { diff --git a/src/coreclr/vm/peimage.inl b/src/coreclr/vm/peimage.inl index 3c12013030e82b..592a84792646be 100644 --- a/src/coreclr/vm/peimage.inl +++ b/src/coreclr/vm/peimage.inl @@ -170,6 +170,9 @@ inline BOOL PEImage::HasLoadedLayout() inline PTR_PEImageLayout PEImage::GetLoadedLayout() { +#ifdef PEIMAGE_FLAT_LAYOUT_ONLY + return GetFlatLayout(); +#endif LIMITED_METHOD_CONTRACT; SUPPORTS_DAC; diff --git a/src/coreclr/vm/peimagelayout.h b/src/coreclr/vm/peimagelayout.h index e086e023d7dcbb..79b5efda31b257 100644 --- a/src/coreclr/vm/peimagelayout.h +++ b/src/coreclr/vm/peimagelayout.h @@ -145,18 +145,18 @@ class LoadedImageLayout: public PEImageLayout #endif // !DACCESS_COMPILE }; -#ifndef DACCESS_COMPILE // A special layout that is used to load standalone composite r2r files. // This layout is not owned by a PEImage and created by simply loading the file // at the given path. class NativeImageLayout : public PEImageLayout { VPTR_VTABLE_CLASS(NativeImageLayout, PEImageLayout) - -public: + + public: +#ifndef DACCESS_COMPILE NativeImageLayout(LPCWSTR fullPath); -}; #endif +}; #endif // PEIMAGELAYOUT_H_ diff --git a/src/coreclr/vm/perfmap.cpp b/src/coreclr/vm/perfmap.cpp index a026da0ebb4b7e..df46fe9c1ce965 100644 --- a/src/coreclr/vm/perfmap.cpp +++ b/src/coreclr/vm/perfmap.cpp @@ -149,7 +149,7 @@ void PerfMap::Enable(PerfMapType type, bool sendExisting) { CodeVersionManager::LockHolder codeVersioningLockHolder; - EEJitManager::CodeHeapIterator heapIterator(nullptr); + CodeHeapIterator heapIterator = ExecutionManager::GetEEJitManager()->GetCodeHeapIterator(); while (heapIterator.Next()) { MethodDesc * pMethod = heapIterator.GetMethod(); diff --git a/src/coreclr/vm/precode.cpp b/src/coreclr/vm/precode.cpp index 798e9849de3a6a..d5d8cffdec6487 100644 --- a/src/coreclr/vm/precode.cpp +++ b/src/coreclr/vm/precode.cpp @@ -10,6 +10,7 @@ #include "common.h" #include "dllimportcallback.h" +#include "../interpreter/interpretershared.h" #ifdef FEATURE_PERFMAP #include "perfmap.h" @@ -30,9 +31,9 @@ BOOL Precode::IsValidType(PrecodeType t) switch (t) { case PRECODE_STUB: -#ifdef HAS_NDIRECT_IMPORT_PRECODE - case PRECODE_NDIRECT_IMPORT: -#endif // HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_PINVOKE_IMPORT_PRECODE + case PRECODE_PINVOKE_IMPORT: +#endif // HAS_PINVOKE_IMPORT_PRECODE #ifdef HAS_FIXUP_PRECODE case PRECODE_FIXUP: #endif // HAS_FIXUP_PRECODE @@ -66,10 +67,10 @@ SIZE_T Precode::SizeOf(PrecodeType t) { case PRECODE_STUB: return sizeof(StubPrecode); -#ifdef HAS_NDIRECT_IMPORT_PRECODE - case PRECODE_NDIRECT_IMPORT: - return sizeof(NDirectImportPrecode); -#endif // HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_PINVOKE_IMPORT_PRECODE + case PRECODE_PINVOKE_IMPORT: + return sizeof(PInvokeImportPrecode); +#endif // HAS_PINVOKE_IMPORT_PRECODE #ifdef HAS_FIXUP_PRECODE case PRECODE_FIXUP: return sizeof(FixupPrecode); @@ -133,16 +134,19 @@ MethodDesc* Precode::GetMethodDesc(BOOL fSpeculative /*= FALSE*/) TADDR pMD = (TADDR)NULL; PrecodeType precodeType = GetType(); +#ifdef TARGET_WASM + pMD = *(TADDR*)(m_data + OFFSETOF_PRECODE_MD); +#else switch (precodeType) { case PRECODE_STUB: pMD = AsStubPrecode()->GetMethodDesc(); break; -#ifdef HAS_NDIRECT_IMPORT_PRECODE - case PRECODE_NDIRECT_IMPORT: - pMD = AsNDirectImportPrecode()->GetMethodDesc(); +#ifdef HAS_PINVOKE_IMPORT_PRECODE + case PRECODE_PINVOKE_IMPORT: + pMD = AsPInvokeImportPrecode()->GetMethodDesc(); break; -#endif // HAS_NDIRECT_IMPORT_PRECODE +#endif // HAS_PINVOKE_IMPORT_PRECODE #ifdef HAS_FIXUP_PRECODE case PRECODE_FIXUP: pMD = AsFixupPrecode()->GetMethodDesc(); @@ -158,13 +162,14 @@ MethodDesc* Precode::GetMethodDesc(BOOL fSpeculative /*= FALSE*/) break; #ifdef FEATURE_INTERPRETER case PRECODE_INTERPRETER: - return NULL; + pMD = AsInterpreterPrecode()->GetMethodDesc(); break; #endif // FEATURE_INTERPRETER default: break; } +#endif // TARGET_WASM if (pMD == (TADDR)NULL) { @@ -180,6 +185,16 @@ MethodDesc* Precode::GetMethodDesc(BOOL fSpeculative /*= FALSE*/) return (PTR_MethodDesc)pMD; } +#ifdef FEATURE_INTERPRETER +TADDR InterpreterPrecode::GetMethodDesc() +{ + LIMITED_METHOD_DAC_CONTRACT; + + InterpByteCodeStart* pInterpreterCode = dac_cast(GetData()->ByteCodeAddr); + return (TADDR)pInterpreterCode->Method->methodHnd; +} +#endif // FEATURE_INTERPRETER + BOOL Precode::IsPointingToPrestub(PCODE target) { CONTRACTL @@ -201,19 +216,20 @@ BOOL Precode::IsPointingToPrestub(PCODE target) return FALSE; } -// If addr is patched fixup precode, returns address that it points to. Otherwise returns NULL. -PCODE Precode::TryToSkipFixupPrecode(PCODE addr) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - } CONTRACTL_END; +#ifndef DACCESS_COMPILE - return 0; +void FlushCacheForDynamicMappedStub(void* code, SIZE_T size) +{ +#ifdef FEATURE_CORECLR_FLUSH_INSTRUCTION_CACHE_TO_PROTECT_STUB_READS + // While the allocation of a stub will use a memory mapping technique, and not actually write to the set of instructions, + // the set of instructions in the stub has non-barrier protected reads from the StubPrecodeData structure. In order to protect those + // reads we would either need barrier instructions in the stub, or we need to ensure that the precode is flushed in the instruction cache + // which will have the side effect of ensuring that the reads within the stub will happen *after* the writes to the StubPrecodeData structure which + // happened in the Init routine above. + ClrFlushInstructionCache(code, size); +#endif // FEATURE_CORECLR_FLUSH_INSTRUCTION_CACHE_TO_PROTECT_STUB_READS } -#ifndef DACCESS_COMPILE - #ifdef FEATURE_INTERPRETER InterpreterPrecode* Precode::AllocateInterpreterPrecode(PCODE byteCode, LoaderAllocator * pLoaderAllocator, @@ -229,6 +245,9 @@ InterpreterPrecode* Precode::AllocateInterpreterPrecode(PCODE byteCode, InterpreterPrecode* pPrecode = (InterpreterPrecode*)pamTracker->Track(pLoaderAllocator->GetNewStubPrecodeHeap()->AllocStub()); pPrecode->Init(pPrecode, byteCode); + + FlushCacheForDynamicMappedStub(pPrecode, sizeof(InterpreterPrecode)); + #ifdef FEATURE_PERFMAP PerfMap::LogStubs(__FUNCTION__, "UMEntryThunk", (PCODE)pPrecode, sizeof(InterpreterPrecode), PerfMapStubType::IndividualWithinBlock); #endif @@ -254,6 +273,16 @@ Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD, { pPrecode = (Precode*)pamTracker->Track(pLoaderAllocator->GetFixupPrecodeHeap()->AllocStub()); pPrecode->Init(pPrecode, t, pMD, pLoaderAllocator); + + // PRECODE_FIXUP is the most common precode type, and we are able to optimize creation of it in a special + // way that allows us to avoid the need for FlushInstructionCache when the precode is created. Notably, + // Before we map the memory for the executable section of the FixupPrecodeThunks into the process, we fill + // the Target with pointers so that Target points at the second portion of the FixupPrecodeThunk. So when + // we map the executable memory in, we get a natural FlushInstructionCache for that scenario. So there is + // never a case where we need to worry about the Target field being set to NULL. Then we either are able + // to see the actual final Target (which doesn't require any further synchronization), or we'll hit the memory + // barrier in the second portion of the FixupPrecodeThunk and find that the MethodDesc/PrecodeFixupThunk are + // properly set. See FixupPrecode::GenerateDataPage for the code to fill in the target. #ifdef FEATURE_PERFMAP PerfMap::LogStubs(__FUNCTION__, "FixupPrecode", (PCODE)pPrecode, sizeof(FixupPrecode), PerfMapStubType::IndividualWithinBlock); #endif @@ -265,6 +294,9 @@ Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD, ThisPtrRetBufPrecodeData *pData = (ThisPtrRetBufPrecodeData*)pamTracker->Track(pLoaderAllocator->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(ThisPtrRetBufPrecodeData)))); pThisPtrRetBufPrecode->Init(pData, pMD, pLoaderAllocator); pPrecode = (Precode*)pThisPtrRetBufPrecode; + + FlushCacheForDynamicMappedStub(pPrecode, sizeof(ThisPtrRetBufPrecode)); + #ifdef FEATURE_PERFMAP PerfMap::LogStubs(__FUNCTION__, "ThisPtrRetBuf", (PCODE)pPrecode, sizeof(ThisPtrRetBufPrecodeData), PerfMapStubType::IndividualWithinBlock); #endif @@ -272,9 +304,12 @@ Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD, #endif // HAS_THISPTR_RETBUF_PRECODE else { - _ASSERTE(t == PRECODE_STUB || t == PRECODE_NDIRECT_IMPORT); + _ASSERTE(t == PRECODE_STUB || t == PRECODE_PINVOKE_IMPORT); pPrecode = (Precode*)pamTracker->Track(pLoaderAllocator->GetNewStubPrecodeHeap()->AllocStub()); pPrecode->Init(pPrecode, t, pMD, pLoaderAllocator); + + FlushCacheForDynamicMappedStub(pPrecode, sizeof(StubPrecode)); + #ifdef FEATURE_PERFMAP PerfMap::LogStubs(__FUNCTION__, t == PRECODE_STUB ? "StubPrecode" : "PInvokeImportPrecode", (PCODE)pPrecode, sizeof(StubPrecode), PerfMapStubType::IndividualWithinBlock); #endif @@ -287,15 +322,19 @@ void Precode::Init(Precode* pPrecodeRX, PrecodeType t, MethodDesc* pMD, LoaderAl { LIMITED_METHOD_CONTRACT; +#ifdef TARGET_WASM + m_data[OFFSETOF_PRECODE_TYPE] = t; + *(TADDR*)(m_data + OFFSETOF_PRECODE_MD) = (TADDR)pMD; +#else switch (t) { case PRECODE_STUB: ((StubPrecode*)this)->Init((StubPrecode*)pPrecodeRX, (TADDR)pMD, pLoaderAllocator); break; -#ifdef HAS_NDIRECT_IMPORT_PRECODE - case PRECODE_NDIRECT_IMPORT: - ((NDirectImportPrecode*)this)->Init((NDirectImportPrecode*)pPrecodeRX, pMD, pLoaderAllocator); +#ifdef HAS_PINVOKE_IMPORT_PRECODE + case PRECODE_PINVOKE_IMPORT: + ((PInvokeImportPrecode*)this)->Init((PInvokeImportPrecode*)pPrecodeRX, pMD, pLoaderAllocator); break; -#endif // HAS_NDIRECT_IMPORT_PRECODE +#endif // HAS_PINVOKE_IMPORT_PRECODE #ifdef HAS_FIXUP_PRECODE case PRECODE_FIXUP: ((FixupPrecode*)this)->Init((FixupPrecode*)pPrecodeRX, pMD, pLoaderAllocator); @@ -310,6 +349,7 @@ void Precode::Init(Precode* pPrecodeRX, PrecodeType t, MethodDesc* pMD, LoaderAl UnexpectedPrecodeType("Precode::Init", t); break; } +#endif _ASSERTE(IsValidType(GetType())); } @@ -393,9 +433,9 @@ void Precode::Reset() switch (t) { case PRECODE_STUB: -#ifdef HAS_NDIRECT_IMPORT_PRECODE - case PRECODE_NDIRECT_IMPORT: -#endif // HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_PINVOKE_IMPORT_PRECODE + case PRECODE_PINVOKE_IMPORT: +#endif // HAS_PINVOKE_IMPORT_PRECODE #ifdef HAS_FIXUP_PRECODE case PRECODE_FIXUP: #endif // HAS_FIXUP_PRECODE @@ -496,8 +536,8 @@ extern "C" size_t StubPrecodeCode_Target_Offset; #endif #if defined(TARGET_ARM64) && defined(TARGET_UNIX) -void (*StubPrecode::StubPrecodeCode)(); -void (*StubPrecode::StubPrecodeCode_End)(); +static void (*StubPrecodeCode)(); +static void (*StubPrecodeCode_End)(); #endif #ifdef FEATURE_MAP_THUNKS_FROM_IMAGE @@ -531,24 +571,25 @@ void StubPrecode::StaticInitialize() } #undef ENUM_PAGE_SIZE +#elif defined(TARGET_WASM) + // StubPrecode is not implemented on WASM #else _ASSERTE((SIZE_T)((BYTE*)StubPrecodeCode_End - (BYTE*)StubPrecodeCode) <= StubPrecode::CodeSize); #endif -#ifdef TARGET_LOONGARCH64 - _ASSERTE(((*((short*)PCODEToPINSTR((PCODE)StubPrecodeCode) + OFFSETOF_PRECODE_TYPE)) >> 5) == StubPrecode::Type); -#elif TARGET_RISCV64 - _ASSERTE((*((BYTE*)PCODEToPINSTR((PCODE)StubPrecodeCode) + OFFSETOF_PRECODE_TYPE)) == StubPrecode::Type); -#else - _ASSERTE((*((BYTE*)PCODEToPINSTR((PCODE)StubPrecodeCode) + OFFSETOF_PRECODE_TYPE)) == StubPrecode::Type); -#endif + _ASSERTE(IsStubPrecodeByASM_DAC((PCODE)StubPrecodeCode)); + if (StubPrecodeCodeTemplate != NULL) + { + _ASSERTE(IsStubPrecodeByASM_DAC((PCODE)StubPrecodeCodeTemplate)); + } - InitializeLoaderHeapConfig(&s_stubPrecodeHeapConfig, StubPrecode::CodeSize, (void*)StubPrecodeCodeTemplate, StubPrecode::GenerateCodePage); + InitializeLoaderHeapConfig(&s_stubPrecodeHeapConfig, StubPrecode::CodeSize, (void*)StubPrecodeCodeTemplate, StubPrecode::GenerateCodePage, NULL); } void StubPrecode::GenerateCodePage(uint8_t* pageBase, uint8_t* pageBaseRX, size_t pageSize) { +#ifndef TARGET_WASM + int totalCodeSize = (int)(pageSize / StubPrecode::CodeSize) * StubPrecode::CodeSize; #ifdef TARGET_X86 - int totalCodeSize = (pageSize / StubPrecode::CodeSize) * StubPrecode::CodeSize; for (int i = 0; i < totalCodeSize; i += StubPrecode::CodeSize) { memcpy(pageBase + i, (const void*)StubPrecodeCode, (uint8_t*)StubPrecodeCode_End - (uint8_t*)StubPrecodeCode); @@ -562,6 +603,14 @@ void StubPrecode::GenerateCodePage(uint8_t* pageBase, uint8_t* pageBaseRX, size_ #else // TARGET_X86 FillStubCodePage(pageBase, (const void*)PCODEToPINSTR((PCODE)StubPrecodeCode), StubPrecode::CodeSize, pageSize); #endif // TARGET_X86 +#ifdef _DEBUG + for (int i = 0; i < totalCodeSize; i += StubPrecode::CodeSize) + { + _ASSERTE(StubPrecode::IsStubPrecodeByASM((PCODE)(pageBaseRX + i))); + _ASSERTE(StubPrecode::IsStubPrecodeByASM_DAC((PCODE)(pageBaseRX + i))); + } +#endif // _DEBUG +#endif // TARGET_WASM } BOOL StubPrecode::IsStubPrecodeByASM(PCODE addr) @@ -597,15 +646,15 @@ void InterpreterPrecode::Init(InterpreterPrecode* pPrecodeRX, TADDR byteCodeAddr } #endif // FEATURE_INTERPRETER -#ifdef HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_PINVOKE_IMPORT_PRECODE -void NDirectImportPrecode::Init(NDirectImportPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator) +void PInvokeImportPrecode::Init(PInvokeImportPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator) { WRAPPER_NO_CONTRACT; - StubPrecode::Init(pPrecodeRX, (TADDR)pMD, pLoaderAllocator, NDirectImportPrecode::Type, GetEEFuncEntryPoint(NDirectImportThunk)); + StubPrecode::Init(pPrecodeRX, (TADDR)pMD, pLoaderAllocator, PInvokeImportPrecode::Type, GetEEFuncEntryPoint(PInvokeImportThunk)); } -#endif // HAS_NDIRECT_IMPORT_PRECODE +#endif // HAS_PINVOKE_IMPORT_PRECODE #ifdef HAS_FIXUP_PRECODE void FixupPrecode::Init(FixupPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator) @@ -619,8 +668,8 @@ void FixupPrecode::Init(FixupPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocat _ASSERTE(GetMethodDesc() == (TADDR)pMD); - pData->Target = (PCODE)pPrecodeRX + FixupPrecode::FixupCodeOffset; pData->PrecodeFixupThunk = GetPreStubEntryPoint(); + VolatileStore(&pData->Target, (PCODE)pPrecodeRX + FixupPrecode::FixupCodeOffset); } #if defined(TARGET_ARM64) && defined(TARGET_UNIX) @@ -641,8 +690,8 @@ extern "C" size_t FixupPrecodeCode_PrecodeFixupThunk_Offset; #endif #if defined(TARGET_ARM64) && defined(TARGET_UNIX) -void (*FixupPrecode::FixupPrecodeCode)(); -void (*FixupPrecode::FixupPrecodeCode_End)(); +static void (*FixupPrecodeCode)(); +static void (*FixupPrecodeCode_End)(); #endif #ifdef FEATURE_MAP_THUNKS_FROM_IMAGE @@ -676,24 +725,48 @@ void FixupPrecode::StaticInitialize() // This should fail if the template is used on a platform which doesn't support the supported page size for templates ThrowHR(COR_E_EXECUTIONENGINE); } +#elif defined(TARGET_WASM) + // FixupPrecode is not implemented on WASM #else _ASSERTE((SIZE_T)((BYTE*)FixupPrecodeCode_End - (BYTE*)FixupPrecodeCode) <= FixupPrecode::CodeSize); #endif -#ifdef TARGET_LOONGARCH64 - _ASSERTE(((*((short*)PCODEToPINSTR((PCODE)StubPrecodeCode) + OFFSETOF_PRECODE_TYPE)) >> 5) == StubPrecode::Type); -#elif TARGET_RISCV64 - _ASSERTE((*((BYTE*)PCODEToPINSTR((PCODE)FixupPrecodeCode) + OFFSETOF_PRECODE_TYPE)) == FixupPrecode::Type); -#else - _ASSERTE(*((BYTE*)PCODEToPINSTR((PCODE)FixupPrecodeCode) + OFFSETOF_PRECODE_TYPE) == FixupPrecode::Type); -#endif + _ASSERTE(IsFixupPrecodeByASM_DAC((PCODE)FixupPrecodeCode)); + if (FixupPrecodeCodeTemplate != NULL) + { + _ASSERTE(IsFixupPrecodeByASM_DAC((PCODE)FixupPrecodeCodeTemplate)); + } + InitializeLoaderHeapConfig(&s_fixupStubPrecodeHeapConfig, FixupPrecode::CodeSize, (void*)FixupPrecodeCodeTemplate, FixupPrecode::GenerateCodePage, FixupPrecode::GenerateDataPage); +} - InitializeLoaderHeapConfig(&s_fixupStubPrecodeHeapConfig, FixupPrecode::CodeSize, (void*)FixupPrecodeCodeTemplate, FixupPrecode::GenerateCodePage); +void FixupPrecode::GenerateDataPage(uint8_t* pageBase, size_t pageSize) +{ +#ifndef TARGET_WASM + // Fill in the data page such that the target of the fixup precode starts as initialized to point + // to the start of the precode itself, so that before the memory for the precode is initialized, + // the precode is in a state where it will loop forever. + // When initializing the precode to have the MethodDesc/Prestub target, the write to update the Target + // to go through the code which passes the extra MethodDesc argument, will be done with a VolatileStore + // such that both the MethodDesc and the PrecodeFixupThunk are updated before the Target is updated to + // make it possible to hit that code. Finally, the FixupPrecode assembly logic will have a load memory + // barrier, which will match up with that store. + // + // Finally, to make this all work, we ensure that this data page generation function is called + // BEFORE the code page is ever mapped into memory, so that it cannot be speculatively executed + // before this logic completes. + int totalCodeSize = (int)((pageSize / FixupPrecode::CodeSize) * FixupPrecode::CodeSize); + for (int i = 0; i < totalCodeSize; i += FixupPrecode::CodeSize) + { + PCODE* ppTargetSlot = (PCODE*)(pageBase + i + offsetof(FixupPrecodeData, Target)); + *ppTargetSlot = ((Precode*)(pageBase - pageSize + i))->GetEntryPoint(); + } +#endif // !TARGET_WASM } void FixupPrecode::GenerateCodePage(uint8_t* pageBase, uint8_t* pageBaseRX, size_t pageSize) { +#ifndef TARGET_WASM + int totalCodeSize = (int)((pageSize / FixupPrecode::CodeSize) * FixupPrecode::CodeSize); #ifdef TARGET_X86 - int totalCodeSize = (pageSize / FixupPrecode::CodeSize) * FixupPrecode::CodeSize; for (int i = 0; i < totalCodeSize; i += FixupPrecode::CodeSize) { @@ -710,6 +783,14 @@ void FixupPrecode::GenerateCodePage(uint8_t* pageBase, uint8_t* pageBaseRX, size #else // TARGET_X86 FillStubCodePage(pageBase, (const void*)PCODEToPINSTR((PCODE)FixupPrecodeCode), FixupPrecode::CodeSize, pageSize); #endif // TARGET_X86 +#ifdef _DEBUG + for (int i = 0; i < totalCodeSize; i += FixupPrecode::CodeSize) + { + _ASSERTE(FixupPrecode::IsFixupPrecodeByASM((PCODE)(pageBaseRX + i))); + _ASSERTE(FixupPrecode::IsFixupPrecodeByASM_DAC((PCODE)(pageBaseRX + i))); + } +#endif // _DEBUG +#endif // !TARGET_WASM } BOOL FixupPrecode::IsFixupPrecodeByASM(PCODE addr) @@ -775,35 +856,114 @@ BOOL DoesSlotCallPrestub(PCODE pCode) void PrecodeMachineDescriptor::Init(PrecodeMachineDescriptor *dest) { - dest->OffsetOfPrecodeType = OFFSETOF_PRECODE_TYPE; - // cDAC will do (where N = 8*ReadWidthOfPrecodeType): - // uintN_t PrecodeType = *(uintN_t*)(pPrecode + OffsetOfPrecodeType); - // PrecodeType >>= ShiftOfPrecodeType; - // return (byte)PrecodeType; -#ifdef TARGET_LOONGARCH64 - dest->ReadWidthOfPrecodeType = 2; -#else - dest->ReadWidthOfPrecodeType = 1; -#endif -#if defined(SHIFTOF_PRECODE_TYPE) - dest->ShiftOfPrecodeType = SHIFTOF_PRECODE_TYPE; -#else - dest->ShiftOfPrecodeType = 0; + dest->InvalidPrecodeType = PRECODE_INVALID; +#ifdef HAS_PINVOKE_IMPORT_PRECODE + dest->PInvokeImportPrecodeType = PRECODE_PINVOKE_IMPORT; #endif - dest->InvalidPrecodeType = InvalidPrecode::Type; - dest->StubPrecodeType = StubPrecode::Type; -#ifdef HAS_NDIRECT_IMPORT_PRECODE - dest->PInvokeImportPrecodeType = NDirectImportPrecode::Type; -#endif // HAS_NDIRECT_IMPORT_PRECODE #ifdef HAS_FIXUP_PRECODE - dest->FixupPrecodeType = FixupPrecode::Type; -#endif + dest->FixupPrecodeType = PRECODE_FIXUP; + dest->FixupCodeOffset = FixupPrecode::FixupCodeOffset; + dest->FixupStubPrecodeSize = FixupPrecode::CodeSize; + + memset(dest->FixupBytes, 0, FixupPrecode::CodeSize); + memset(dest->FixupIgnoredBytes, 0, FixupPrecode::CodeSize); + + BYTE *pTemplateInstr; + BYTE *pTemplateInstrEnd; + uint8_t bytesMeaningful; +#ifdef TARGET_X86 + memset(dest->FixupIgnoredBytes + SYMBOL_VALUE(FixupPrecodeCode_Target_Offset), 1, 4); + memset(dest->FixupIgnoredBytes + SYMBOL_VALUE(FixupPrecodeCode_MethodDesc_Offset), 1, 4); + memset(dest->FixupIgnoredBytes + SYMBOL_VALUE(FixupPrecodeCode_PrecodeFixupThunk_Offset), 1, 4); +#endif // TARGET_X86 + pTemplateInstr = (BYTE*)PCODEToPINSTR((PCODE)FixupPrecodeCode); + pTemplateInstrEnd = (BYTE*)PCODEToPINSTR((PCODE)FixupPrecodeCode_End); + bytesMeaningful = (uint8_t)(pTemplateInstrEnd - pTemplateInstr); + memcpy(dest->FixupBytes, pTemplateInstr, bytesMeaningful); + memset(dest->FixupIgnoredBytes + bytesMeaningful, 1, FixupPrecode::CodeSize - bytesMeaningful); +#endif // HAS_FIXUP_PRECODE + + dest->StubPrecodeSize = StubPrecode::CodeSize; + dest->StubPrecodeType = PRECODE_STUB; + + memset(dest->StubBytes, 0, StubPrecode::CodeSize); + memset(dest->StubIgnoredBytes, 0, StubPrecode::CodeSize); +#ifdef TARGET_X86 + memset(dest->StubIgnoredBytes + SYMBOL_VALUE(StubPrecodeCode_Target_Offset), 1, 4); + memset(dest->StubIgnoredBytes + SYMBOL_VALUE(StubPrecodeCode_MethodDesc_Offset), 1, 4); +#endif // TARGET_X86 + pTemplateInstr = (BYTE*)PCODEToPINSTR((PCODE)StubPrecodeCode); + pTemplateInstrEnd = (BYTE*)PCODEToPINSTR((PCODE)StubPrecodeCode_End); + bytesMeaningful = (uint8_t)(pTemplateInstrEnd - pTemplateInstr); + memcpy(dest->StubBytes, pTemplateInstr, bytesMeaningful); + memset(dest->StubIgnoredBytes + bytesMeaningful, 1, StubPrecode::CodeSize - bytesMeaningful); + #ifdef HAS_THISPTR_RETBUF_PRECODE - dest->ThisPointerRetBufPrecodeType = ThisPtrRetBufPrecode::Type; + dest->ThisPointerRetBufPrecodeType = PRECODE_THISPTR_RETBUF; +#endif + +#ifdef FEATURE_INTERPRETER + dest->InterpreterPrecodeType = PRECODE_INTERPRETER; +#endif +#ifdef FEATURE_STUBPRECODE_DYNAMIC_HELPERS + dest->DynamicHelperPrecodeType = PRECODE_DYNAMIC_HELPERS; #endif + dest->UMEntryPrecodeType = PRECODE_UMENTRY_THUNK; + dest->StubCodePageSize = GetStubCodePageSize(); } #endif // !DACCESS_COMPILE +#include + +#ifdef HAS_FIXUP_PRECODE +#ifndef DACCESS_COMPILE +BOOL FixupPrecode::IsFixupPrecodeByASM_DAC(PCODE addr) +#else +BOOL FixupPrecode::IsFixupPrecodeByASM(PCODE addr) +#endif +{ + LIMITED_METHOD_DAC_CONTRACT; + PrecodeMachineDescriptor *precodeDescriptor = &(&g_cdacPlatformMetadata)->precode; + PTR_BYTE pInstr = dac_cast(PCODEToPINSTR(addr)); + for (int i = 0; i < precodeDescriptor->FixupStubPrecodeSize; i++) + { + if (precodeDescriptor->FixupIgnoredBytes[i] == 0) + { + if (precodeDescriptor->FixupBytes[i] != *pInstr) + { + return FALSE; + } + } + pInstr++; + } + + return TRUE; +} +#endif // HAS_FIXUP_PRECODE + +#ifndef DACCESS_COMPILE +BOOL StubPrecode::IsStubPrecodeByASM_DAC(PCODE addr) +#else +BOOL StubPrecode::IsStubPrecodeByASM(PCODE addr) +#endif +{ + LIMITED_METHOD_DAC_CONTRACT; + PrecodeMachineDescriptor *precodeDescriptor = &(&g_cdacPlatformMetadata)->precode; + PTR_BYTE pInstr = dac_cast(PCODEToPINSTR(addr)); + for (int i = 0; i < precodeDescriptor->StubPrecodeSize; i++) + { + if (precodeDescriptor->StubIgnoredBytes[i] == 0) + { + if (precodeDescriptor->StubBytes[i] != *pInstr) + { + return FALSE; + } + } + pInstr++; + } + + return TRUE; +} diff --git a/src/coreclr/vm/precode.h b/src/coreclr/vm/precode.h index 5c0a7299da4c93..d7786271670bc2 100644 --- a/src/coreclr/vm/precode.h +++ b/src/coreclr/vm/precode.h @@ -13,48 +13,36 @@ #if defined(TARGET_AMD64) -#define OFFSETOF_PRECODE_TYPE 0 -#define OFFSETOF_PRECODE_TYPE_CALL_OR_JMP 5 -#define OFFSETOF_PRECODE_TYPE_MOV_R10 10 - #define SIZEOF_PRECODE_BASE 16 #elif defined(TARGET_X86) EXTERN_C VOID STDCALL PrecodeRemotingThunk(); -#define OFFSETOF_PRECODE_TYPE 0 -#define OFFSETOF_PRECODE_TYPE_CALL_OR_JMP 5 -#define OFFSETOF_PRECODE_TYPE_MOV_RM_R 6 - #define SIZEOF_PRECODE_BASE 8 #elif defined(TARGET_ARM64) #define SIZEOF_PRECODE_BASE CODE_SIZE_ALIGN -#define OFFSETOF_PRECODE_TYPE 0 #elif defined(TARGET_ARM) #define SIZEOF_PRECODE_BASE CODE_SIZE_ALIGN * 2 -#define OFFSETOF_PRECODE_TYPE 7 #elif defined(TARGET_LOONGARCH64) #define SIZEOF_PRECODE_BASE CODE_SIZE_ALIGN -#define OFFSETOF_PRECODE_TYPE 0 -#define SHIFTOF_PRECODE_TYPE 5 #elif defined(TARGET_RISCV64) #define SIZEOF_PRECODE_BASE CODE_SIZE_ALIGN -#define OFFSETOF_PRECODE_TYPE 0 #elif defined(TARGET_WASM) -#define SIZEOF_PRECODE_BASE 0 +// on wasm we have "fake" precode, with precode type and MethodDesc information stored +#define SIZEOF_PRECODE_BASE 2*sizeof(void*) #define OFFSETOF_PRECODE_TYPE 0 - +#define OFFSETOF_PRECODE_MD 4 #endif // TARGET_AMD64 #ifndef DACCESS_COMPILE @@ -67,19 +55,7 @@ BOOL DoesSlotCallPrestub(PCODE pCode); // Invalid precode type struct InvalidPrecode { -#if defined(TARGET_AMD64) || defined(TARGET_X86) - // int3 - static const int Type = 0xCC; -#elif defined(TARGET_ARM64) || defined(TARGET_ARM) - static const int Type = 0; -#elif defined(TARGET_LOONGARCH64) static const int Type = 0xff; -#elif defined(TARGET_RISCV64) - static const int Type = 0xff; -#elif defined(TARGET_WASM) - // unreachable instruction - static const int Type = 0; -#endif }; struct StubPrecodeData @@ -111,36 +87,25 @@ typedef DPTR(class UMEntryThunk) PTR_UMEntryThunk; // Regular precode struct StubPrecode { + static const BYTE Type = 0x3; #if defined(TARGET_AMD64) - static const BYTE Type = 0x4C; static const SIZE_T CodeSize = 24; #elif defined(TARGET_X86) - static const BYTE Type = 0xA1; static const SIZE_T CodeSize = 24; #elif defined(TARGET_ARM64) - static const int Type = 0x4A; static const SIZE_T CodeSize = 24; #elif defined(TARGET_ARM) - static const int Type = 0xFF; static const SIZE_T CodeSize = 12; #elif defined(TARGET_LOONGARCH64) - static const int Type = 0x4; static const SIZE_T CodeSize = 24; #elif defined(TARGET_RISCV64) - static const int Type = 0x17; static const SIZE_T CodeSize = 24; #elif defined(TARGET_WASM) - static const int Type = 0; - static const SIZE_T CodeSize = 0; + static const SIZE_T CodeSize = 3*sizeof(void*); #endif // TARGET_AMD64 BYTE m_code[CodeSize]; -#if defined(TARGET_ARM64) && defined(TARGET_UNIX) - static void (*StubPrecodeCode)(); - static void (*StubPrecodeCode_End)(); -#endif - void Init(StubPrecode* pPrecodeRX, TADDR secretParam, LoaderAllocator *pLoaderAllocator = NULL, TADDR type = StubPrecode::Type, TADDR target = 0); static void StaticInitialize(); @@ -182,8 +147,9 @@ struct StubPrecode BYTE GetType(); -#ifndef DACCESS_COMPILE static BOOL IsStubPrecodeByASM(PCODE addr); + static BOOL IsStubPrecodeByASM_DAC(PCODE addr); +#ifndef DACCESS_COMPILE void ResetTargetInterlocked() { @@ -233,15 +199,15 @@ struct StubPrecode typedef DPTR(StubPrecode) PTR_StubPrecode; -#ifdef HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_PINVOKE_IMPORT_PRECODE -// NDirect import precode +// PInvoke import precode // (This is fake precode. VTable slot does not point to it.) -struct NDirectImportPrecode : StubPrecode +struct PInvokeImportPrecode : StubPrecode { static const int Type = 0x05; - void Init(NDirectImportPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator); + void Init(PInvokeImportPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator); LPVOID GetEntrypoint() { @@ -249,9 +215,9 @@ struct NDirectImportPrecode : StubPrecode return (LPVOID)PINSTRToPCODE(dac_cast(this)); } }; -typedef DPTR(NDirectImportPrecode) PTR_NDirectImportPrecode; +typedef DPTR(PInvokeImportPrecode) PTR_PInvokeImportPrecode; -#endif // HAS_NDIRECT_IMPORT_PRECODE +#endif // HAS_PINVOKE_IMPORT_PRECODE #ifdef HAS_THISPTR_RETBUF_PRECODE @@ -370,7 +336,12 @@ struct InterpreterPrecode LIMITED_METHOD_CONTRACT; return (InterpreterPrecode*)PCODEToPINSTR(entryPoint); } + + TADDR GetMethodDesc(); }; + +typedef DPTR(InterpreterPrecode) PTR_InterpreterPrecode; + #endif // FEATURE_INTERPRETER #ifdef HAS_FIXUP_PRECODE @@ -393,48 +364,38 @@ extern "C" void FixupPrecodeCode_End(); // The fixup precode is simple jump once patched. It does not have the two instruction overhead of regular precode. struct FixupPrecode { + static const int Type = 0x2; #if defined(TARGET_AMD64) - static const int Type = 0xFF; static const SIZE_T CodeSize = 24; static const int FixupCodeOffset = 6; #elif defined(TARGET_X86) - static const int Type = 0xFF; static const SIZE_T CodeSize = 24; static const int FixupCodeOffset = 6; #elif defined(TARGET_ARM64) - static const int Type = 0x0B; static const SIZE_T CodeSize = 24; static const int FixupCodeOffset = 8; #elif defined(TARGET_ARM) - static const int Type = 0xCF; - static const SIZE_T CodeSize = 12; + static const SIZE_T CodeSize = 16; static const int FixupCodeOffset = 4 + THUMB_CODE; #elif defined(TARGET_LOONGARCH64) - static const int Type = 0x3; static const SIZE_T CodeSize = 32; static const int FixupCodeOffset = 12; #elif defined(TARGET_RISCV64) - static const int Type = 0x97; static const SIZE_T CodeSize = 32; static const int FixupCodeOffset = 10; #elif defined(TARGET_WASM) - static const int Type = 2; - static const SIZE_T CodeSize = 0; + static const SIZE_T CodeSize = 2*sizeof(void*); static const int FixupCodeOffset = 0; #endif // TARGET_AMD64 BYTE m_code[CodeSize]; -#if defined(TARGET_ARM64) && defined(TARGET_UNIX) - static void (*FixupPrecodeCode)(); - static void (*FixupPrecodeCode_End)(); -#endif - void Init(FixupPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator); static void StaticInitialize(); static void GenerateCodePage(uint8_t* pageBase, uint8_t* pageBaseRX, size_t size); + static void GenerateDataPage(uint8_t* pageBase, size_t size); PTR_FixupPrecodeData GetData() const { @@ -460,8 +421,9 @@ struct FixupPrecode return &GetData()->Target; } -#ifndef DACCESS_COMPILE static BOOL IsFixupPrecodeByASM(PCODE addr); + static BOOL IsFixupPrecodeByASM_DAC(PCODE addr); +#ifndef DACCESS_COMPILE void ResetTargetInterlocked() { @@ -517,21 +479,21 @@ typedef DPTR(FixupPrecode) PTR_FixupPrecode; typedef DPTR(class Precode) PTR_Precode; enum PrecodeType { - PRECODE_INVALID = InvalidPrecode::Type, - PRECODE_STUB = StubPrecode::Type, + PRECODE_INVALID = InvalidPrecode::Type, // 0xFF + PRECODE_STUB = StubPrecode::Type, // 0x3 #ifdef FEATURE_INTERPRETER - PRECODE_INTERPRETER = InterpreterPrecode::Type, + PRECODE_INTERPRETER = InterpreterPrecode::Type, // 0x6 #endif // FEATURE_INTERPRETER -#ifdef HAS_NDIRECT_IMPORT_PRECODE - PRECODE_NDIRECT_IMPORT = NDirectImportPrecode::Type, -#endif // HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_PINVOKE_IMPORT_PRECODE + PRECODE_PINVOKE_IMPORT = PInvokeImportPrecode::Type, // 0x5 +#endif // HAS_PINVOKE_IMPORT_PRECODE #ifdef HAS_FIXUP_PRECODE PRECODE_FIXUP = FixupPrecode::Type, #endif // HAS_FIXUP_PRECODE #ifdef HAS_THISPTR_RETBUF_PRECODE - PRECODE_THISPTR_RETBUF = ThisPtrRetBufPrecode::Type, + PRECODE_THISPTR_RETBUF = ThisPtrRetBufPrecode::Type, // 0x8 #endif // HAS_THISPTR_RETBUF_PRECODE - PRECODE_UMENTRY_THUNK = PRECODE_UMENTRY_THUNK_VALUE, // Set the value here and not in UMEntryThunk to avoid circular dependency + PRECODE_UMENTRY_THUNK = PRECODE_UMENTRY_THUNK_VALUE, // 0x7 - Set the value here and not in UMEntryThunk to avoid circular dependency #ifdef FEATURE_STUBPRECODE_DYNAMIC_HELPERS PRECODE_DYNAMIC_HELPERS = 0xa, #endif // FEATURE_STUBPRECODE_DYNAMIC_HELPERS @@ -544,7 +506,7 @@ inline TADDR StubPrecode::GetMethodDesc() switch (GetType()) { case PRECODE_STUB: - case PRECODE_NDIRECT_IMPORT: + case PRECODE_PINVOKE_IMPORT: return GetSecretParam(); case PRECODE_UMENTRY_THUNK: @@ -569,6 +531,10 @@ inline BYTE StubPrecode::GetType() LIMITED_METHOD_DAC_CONTRACT; TADDR type = GetData()->Type; +#ifdef TARGET_WASM + return (BYTE)type; +#endif + // There are a limited number of valid bit patterns here. Restrict to those, so that the // speculative variant of GetPrecodeFromEntryPoint is more robust. Type is stored as a TADDR // so that a single byte matching is not enough to cause a false match. @@ -576,7 +542,7 @@ inline BYTE StubPrecode::GetType() { case PRECODE_UMENTRY_THUNK: case PRECODE_STUB: - case PRECODE_NDIRECT_IMPORT: + case PRECODE_PINVOKE_IMPORT: case PRECODE_THISPTR_RETBUF: #ifdef FEATURE_INTERPRETER case PRECODE_INTERPRETER: @@ -604,19 +570,19 @@ class Precode { } private: -#ifdef HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_PINVOKE_IMPORT_PRECODE public: // Fake precodes has to be exposed - NDirectImportPrecode* AsNDirectImportPrecode() + PInvokeImportPrecode* AsPInvokeImportPrecode() { LIMITED_METHOD_CONTRACT; SUPPORTS_DAC; - return dac_cast(this); + return dac_cast(this); } private: -#endif // HAS_NDIRECT_IMPORT_PRECODE +#endif // HAS_PINVOKE_IMPORT_PRECODE #ifdef HAS_FIXUP_PRECODE PTR_FixupPrecode AsFixupPrecode() @@ -637,6 +603,16 @@ class Precode { } #endif // HAS_THISPTR_RETBUF_PRECODE +#ifdef FEATURE_INTERPRETER + InterpreterPrecode* AsInterpreterPrecode() + { + LIMITED_METHOD_CONTRACT; + SUPPORTS_DAC; + + return dac_cast(this); + } +#endif // FEATURE_INTERPRETER + TADDR GetStart() { SUPPORTS_DAC; @@ -660,36 +636,32 @@ class Precode { { LIMITED_METHOD_CONTRACT; SUPPORTS_DAC; - -#ifdef OFFSETOF_PRECODE_TYPE - -#if defined(TARGET_LOONGARCH64) - assert(0 == OFFSETOF_PRECODE_TYPE); - static_assert(5 == SHIFTOF_PRECODE_TYPE, "expected shift of 5"); - short type = *((short*)m_data); - type >>= SHIFTOF_PRECODE_TYPE; -#elif defined(TARGET_RISCV64) - assert(0 == OFFSETOF_PRECODE_TYPE); - BYTE type = *((BYTE*)m_data + OFFSETOF_PRECODE_TYPE); -#else -#if defined(SHIFTOF_PRECODE_TYPE) -#error "did not expect SHIFTOF_PRECODE_TYPE to be defined" +#ifdef TARGET_WASM // WASM-TODO: we will not need this once we have real precode on Wasm + return (PrecodeType)m_data[OFFSETOF_PRECODE_TYPE]; #endif - BYTE type = m_data[OFFSETOF_PRECODE_TYPE]; + PrecodeType basicPrecodeType = PRECODE_INVALID; + if (StubPrecode::IsStubPrecodeByASM(PINSTRToPCODE(dac_cast(this)))) + { + basicPrecodeType = PRECODE_STUB; + } + +#ifdef HAS_FIXUP_PRECODE + if (FixupPrecode::IsFixupPrecodeByASM(PINSTRToPCODE(dac_cast(this)))) + { + basicPrecodeType = PRECODE_FIXUP; + } #endif - if (type == StubPrecode::Type) + if (basicPrecodeType == PRECODE_STUB) { - // StubPrecode code is used for both StubPrecode, NDirectImportPrecode, InterpreterPrecode, and ThisPtrRetBufPrecode, + // StubPrecode code is used for both StubPrecode, PInvokeImportPrecode, InterpreterPrecode, and ThisPtrRetBufPrecode, // so we need to get the real type - type = AsStubPrecode()->GetType(); + return (PrecodeType)AsStubPrecode()->GetType(); + } + else + { + return basicPrecodeType; } - - return (PrecodeType)type; - -#else // OFFSETOF_PRECODE_TYPE - return PRECODE_STUB; -#endif // OFFSETOF_PRECODE_TYPE } static BOOL IsValidType(PrecodeType t); @@ -783,15 +755,29 @@ class Precode { fSpeculative = TRUE; #endif +#ifdef TARGET_WASM // WASM-TODO: we will not need this once we have real precode on Wasm + return (PTR_Precode)addr; +#endif + TADDR pInstr = PCODEToPINSTR(addr); // Always do consistency check in debug if (fSpeculative INDEBUG(|| TRUE)) { - if (!IS_ALIGNED(pInstr, PRECODE_ALIGNMENT) || !IsValidType(PTR_Precode(pInstr)->GetType())) + if (!IS_ALIGNED(pInstr, PRECODE_ALIGNMENT)) { - if (fSpeculative) return NULL; - _ASSERTE(!"Precode::GetPrecodeFromEntryPoint: Unexpected code in precode"); + // This not a fixup precode or stub precode + return NULL; + } + if (!StubPrecode::IsStubPrecodeByASM(addr)) + { +#ifdef HAS_FIXUP_PRECODE + if (!FixupPrecode::IsFixupPrecodeByASM(addr)) +#endif + { + // This not a fixup precode or stub precode + return NULL; + } } } @@ -799,9 +785,6 @@ class Precode { return pPrecode; } - // If addr is patched fixup precode, returns address that it points to. Otherwise returns NULL. - static PCODE TryToSkipFixupPrecode(PCODE addr); - // // Precode as temporary entrypoint // @@ -818,54 +801,69 @@ class Precode { #endif }; +void FlushCacheForDynamicMappedStub(void* code, SIZE_T size); + // Verify that the type for each precode is different -static_assert_no_msg(StubPrecode::Type != NDirectImportPrecode::Type); +static_assert_no_msg(StubPrecode::Type != PInvokeImportPrecode::Type); static_assert_no_msg(StubPrecode::Type != FixupPrecode::Type); static_assert_no_msg(StubPrecode::Type != ThisPtrRetBufPrecode::Type); -static_assert_no_msg(FixupPrecode::Type != NDirectImportPrecode::Type); +static_assert_no_msg(FixupPrecode::Type != PInvokeImportPrecode::Type); static_assert_no_msg(FixupPrecode::Type != ThisPtrRetBufPrecode::Type); -static_assert_no_msg(NDirectImportPrecode::Type != ThisPtrRetBufPrecode::Type); +static_assert_no_msg(PInvokeImportPrecode::Type != ThisPtrRetBufPrecode::Type); // Verify that the base type for each precode fits into each specific precode type -static_assert_no_msg(sizeof(Precode) <= sizeof(NDirectImportPrecode)); +static_assert_no_msg(sizeof(Precode) <= sizeof(PInvokeImportPrecode)); static_assert_no_msg(sizeof(Precode) <= sizeof(FixupPrecode)); static_assert_no_msg(sizeof(Precode) <= sizeof(ThisPtrRetBufPrecode)); -#ifndef DACCESS_COMPILE +#ifdef FEATURE_INTERPRETER +// we are allocating InterpreterPrecode in the interleaved StubPrecodeHeap +// (in Precode::AllocateInterpreterPrecode) +// and so we need it to fit the data into the StubPrecode::CodeSize +static_assert_no_msg(sizeof(InterpreterPrecodeData) <= StubPrecode::CodeSize); +#endif // FEATURE_INTERPRETER + // A summary of the precode layout for diagnostic purposes struct PrecodeMachineDescriptor { uint32_t StubCodePageSize; - - uint8_t OffsetOfPrecodeType; - // cDAC will do (where N = 8*ReadWidthOfPrecodeType): - // uintN_t PrecodeType = *(uintN_t*)(pPrecode + OffsetOfPrecodeType); - // PrecodeType >>= ShiftOfPrecodeType; - // return (byte)PrecodeType; - uint8_t ReadWidthOfPrecodeType; - uint8_t ShiftOfPrecodeType; - uint8_t InvalidPrecodeType; - uint8_t StubPrecodeType; -#ifdef HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_PINVOKE_IMPORT_PRECODE uint8_t PInvokeImportPrecodeType; #endif #ifdef HAS_FIXUP_PRECODE uint8_t FixupPrecodeType; -#endif + uint8_t FixupCodeOffset; + uint8_t FixupStubPrecodeSize; + BYTE FixupBytes[FixupPrecode::CodeSize]; + BYTE FixupIgnoredBytes[FixupPrecode::CodeSize]; +#endif // HAS_FIXUP_PRECODE + + uint8_t StubPrecodeSize; + uint8_t StubPrecodeType; + + BYTE StubBytes[StubPrecode::CodeSize]; + BYTE StubIgnoredBytes[StubPrecode::CodeSize]; #ifdef HAS_THISPTR_RETBUF_PRECODE uint8_t ThisPointerRetBufPrecodeType; #endif +#ifdef FEATURE_INTERPRETER + uint8_t InterpreterPrecodeType; +#endif +#ifdef FEATURE_STUBPRECODE_DYNAMIC_HELPERS + uint8_t DynamicHelperPrecodeType; +#endif + uint8_t UMEntryPrecodeType; + public: PrecodeMachineDescriptor() = default; PrecodeMachineDescriptor(const PrecodeMachineDescriptor&) = delete; PrecodeMachineDescriptor& operator=(const PrecodeMachineDescriptor&) = delete; static void Init(PrecodeMachineDescriptor* dest); }; -#endif //DACCESS_COMPILE extern InterleavedLoaderHeapConfig s_stubPrecodeHeapConfig; #ifdef HAS_FIXUP_PRECODE diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp index d63251294dab6a..9336a11d44f317 100644 --- a/src/coreclr/vm/prestub.cpp +++ b/src/coreclr/vm/prestub.cpp @@ -706,15 +706,20 @@ namespace _ASSERTE(pConfig != NULL); _ASSERTE(pDecoderMemory != NULL); + if (!pMD->MayHaveILHeader()) + return NULL; + COR_ILMETHOD_DECODER* pHeader = NULL; + COR_ILMETHOD* ilHeader = pConfig->GetILHeader(); // For a Runtime Async method the methoddef maps to a Task-returning thunk with runtime-provided implementation, // while the default IL belongs to the Async implementation variant. // By default the config captures the default methoddesc, which would be a thunk, thus no IL header. // So, if config provides no header and we see an implementation method desc, then just ask the method desc itself. - if (ilHeader == NULL && pMD->IsAsyncVariantMethod() && !pMD->IsAsyncThunkMethod()) + if (ilHeader == NULL && pMD->IsAsyncVariantMethod()) { + _ASSERTE(!pMD->IsAsyncThunkMethod()); ilHeader = pMD->GetILHeader(); } @@ -1389,9 +1394,9 @@ PrepareCodeConfigBuffer::PrepareCodeConfigBuffer(NativeCodeVersion codeVersion) // CreateDerivedTargetSigWithExtraParams: // This method is used to create the signature of the target of the ILStub for -// instantiating, unboxing, and async variant stubs, when/where we need to -// introduce a generic context/async continuation. -// And since the generic context/async continuations are hidden parameters, +// instantiating and unboxing stubs, when/where we need to +// introduce a generic context. +// And since the generic contexts are hidden parameters, // we're creating a signature that looks like non-generic but with additional // parameters right after the thisptr void MethodDesc::CreateDerivedTargetSigWithExtraParams(MetaSig& msig, SigBuilder *stubSigBuilder) @@ -1399,6 +1404,8 @@ void MethodDesc::CreateDerivedTargetSigWithExtraParams(MetaSig& msig, SigBuilder STANDARD_VM_CONTRACT; BYTE callingConvention = IMAGE_CEE_CS_CALLCONV_DEFAULT; + if (msig.HasAsyncContinuation()) + callingConvention = IMAGE_CEE_CS_CALLCONV_ASYNC; if (msig.HasThis()) callingConvention |= IMAGE_CEE_CS_CALLCONV_HASTHIS; // CallingConvention @@ -1438,15 +1445,15 @@ void MethodDesc::CreateDerivedTargetSigWithExtraParams(MetaSig& msig, SigBuilder } #ifdef TARGET_X86 - if (msig.HasGenericContextArg()) + if (msig.HasAsyncContinuation()) { - // The hidden context parameter - stubSigBuilder->AppendElementType(ELEMENT_TYPE_I); + stubSigBuilder->AppendElementType(ELEMENT_TYPE_OBJECT); } - if (msig.HasAsyncContinuation()) + if (msig.HasGenericContextArg()) { - stubSigBuilder->AppendElementType(ELEMENT_TYPE_OBJECT); + // The hidden context parameter + stubSigBuilder->AppendElementType(ELEMENT_TYPE_I); } #endif // TARGET_X86 } @@ -1491,12 +1498,17 @@ Stub * CreateUnboxingILStubForSharedGenericValueTypeMethods(MethodDesc* pTargetM pCode->EmitLoadThis(); pCode->EmitLDFLDA(tokRawData); -#if defined(TARGET_X86) +#ifdef TARGET_X86 // Push the rest of the arguments for x86 for (unsigned i = 0; i < msig.NumFixedArgs();i++) { pCode->EmitLDARG(i); } + + if (msig.HasAsyncContinuation()) + { + pCode->EmitLDNULL(); + } #endif // Push the hidden context param @@ -1507,7 +1519,12 @@ Stub * CreateUnboxingILStubForSharedGenericValueTypeMethods(MethodDesc* pTargetM pCode->EmitSUB(); pCode->EmitLDIND_I(); -#if !defined(TARGET_X86) +#ifndef TARGET_X86 + if (msig.HasAsyncContinuation()) + { + pCode->EmitLDNULL(); + } + // Push the rest of the arguments for not x86 for (unsigned i = 0; i < msig.NumFixedArgs();i++) { @@ -1532,7 +1549,8 @@ Stub * CreateUnboxingILStubForSharedGenericValueTypeMethods(MethodDesc* pTargetM pTargetMD->GetModule(), pSig, cbSig, &typeContext, - &sl); + &sl, + pTargetMD->IsAsyncMethod()); ILStubResolver *pResolver = pStubMD->AsDynamicMethodDesc()->GetILStubResolver(); @@ -1596,31 +1614,37 @@ Stub * CreateInstantiatingILStub(MethodDesc* pTargetMD, void* pHiddenArg) pCode->EmitLoadThis(); } -#if defined(TARGET_X86) +#ifdef TARGET_X86 // Push the rest of the arguments for x86 for (unsigned i = 0; i < msig.NumFixedArgs();i++) { pCode->EmitLDARG(i); } -#endif // TARGET_X86 + + if (msig.HasAsyncContinuation()) + { + pCode->EmitLDNULL(); + } // Push the hidden context param // InstantiatingStub pCode->EmitLDC((TADDR)pHiddenArg); +#else + // Push the hidden context param + // InstantiatingStub + pCode->EmitLDC((TADDR)pHiddenArg); - // Push the async continuation if (msig.HasAsyncContinuation()) { pCode->EmitLDNULL(); } -#if !defined(TARGET_X86) - // Push the rest of the arguments for not x86 + // Push the rest of the arguments for x86 for (unsigned i = 0; i < msig.NumFixedArgs();i++) { pCode->EmitLDARG(i); } -#endif // !TARGET_X86 +#endif // Push the target address pCode->EmitLDC((TADDR)pTargetMD->GetMultiCallableAddrOfCode(CORINFO_ACCESS_ANY)); @@ -1639,7 +1663,8 @@ Stub * CreateInstantiatingILStub(MethodDesc* pTargetMD, void* pHiddenArg) pTargetMD->GetModule(), pSig, cbSig, &typeContext, - &sl); + &sl, + pTargetMD->IsAsyncMethod()); ILStubResolver *pResolver = pStubMD->AsDynamicMethodDesc()->GetILStubResolver(); @@ -1984,18 +2009,42 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method } #ifdef FEATURE_INTERPRETER -extern "C" void* STDCALL ExecuteInterpretedMethod(TransitionBlock* pTransitionBlock, TADDR byteCodeAddr, void* retBuff) +static InterpThreadContext* GetInterpThreadContext() { - // Argument registers are in the TransitionBlock - // The stack arguments are right after the pTransitionBlock Thread *pThread = GetThread(); InterpThreadContext *threadContext = pThread->GetInterpThreadContext(); if (threadContext == nullptr || threadContext->pStackStart == nullptr) { COMPlusThrow(kOutOfMemoryException); } + + return threadContext; +} + +EXTERN_C void STDCALL ReversePInvokeBadTransition(); + +extern "C" void* STDCALL ExecuteInterpretedMethod(TransitionBlock* pTransitionBlock, TADDR byteCodeAddr, void* retBuff) +{ + // Argument registers are in the TransitionBlock + // The stack arguments are right after the pTransitionBlock + InterpThreadContext *threadContext = GetInterpThreadContext(); int8_t *sp = threadContext->pStackPointer; + InterpByteCodeStart* pInterpreterCode = dac_cast(byteCodeAddr); + + if (pInterpreterCode->Method->unmanagedCallersOnly) + { + Thread* thread = GetThreadNULLOk(); + if (thread == NULL) + CREATETHREAD_IF_NULL_FAILFAST(thread, W("Failed to setup new thread during reverse P/Invoke")); + + // Verify the current thread isn't in COOP mode. + if (thread->PreemptiveGCDisabled()) + ReversePInvokeBadTransition(); + } + + GCX_MAYBE_COOP(pInterpreterCode->Method->unmanagedCallersOnly); + // This construct ensures that the InterpreterFrame is always stored at a higher address than the // InterpMethodContextFrame. This is important for the stack walking code. struct Frames @@ -2020,6 +2069,20 @@ extern "C" void* STDCALL ExecuteInterpretedMethod(TransitionBlock* pTransitionBl return frames.interpMethodContextFrame.pRetVal; } + +extern "C" void* STDCALL ExecuteInterpretedMethodWithArgs(TransitionBlock* pTransitionBlock, TADDR byteCodeAddr, int8_t* pArgs, size_t size, void* retBuff) +{ + // copy the arguments to the stack + if (size > 0 && pArgs != nullptr) + { + InterpThreadContext *threadContext = GetInterpThreadContext(); + int8_t *sp = threadContext->pStackPointer; + + memcpy(sp, pArgs, size); + } + + return ExecuteInterpretedMethod(pTransitionBlock, byteCodeAddr, retBuff); +} #endif // FEATURE_INTERPRETER #ifdef _DEBUG @@ -2214,7 +2277,7 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMo } pCode = PrepareInitialCode(callerGCMode); } // end else if (IsIL() || IsNoMetadata()) - else if (IsNDirect()) + else if (IsPInvoke()) { if (GetModule()->IsReadyToRun() && GetModule()->GetReadyToRunInfo()->HasNonShareablePInvokeStubs() && MayUsePrecompiledILStub()) { @@ -2238,14 +2301,10 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMo else if (IsFCall()) { // Get the fcall implementation - BOOL fSharedOrDynamicFCallImpl; - pCode = ECall::GetFCallImpl(this, &fSharedOrDynamicFCallImpl); + pCode = ECall::GetFCallImpl(this); - if (fSharedOrDynamicFCallImpl) - { - // Fake ctors share one implementation that has to be wrapped by prestub - GetOrCreatePrecode(); - } + // FCalls are always wrapped in a precode to enable mapping of the entrypoint back to MethodDesc + GetOrCreatePrecode(); } else if (IsArray()) { @@ -2318,13 +2377,13 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMo pCode = DoBackpatch(pMT, pDispatchingMT, FALSE); Return: -#ifdef FEATURE_INTERPRETER +#if defined(FEATURE_INTERPRETER) && defined(FEATURE_JIT) InterpByteCodeStart *pInterpreterCode = GetInterpreterCode(); if (pInterpreterCode != NULL) { CreateNativeToInterpreterCallStub(pInterpreterCode->Method); } -#endif // FEATURE_INTERPRETER +#endif // FEATURE_INTERPRETER && FEATURE_JIT RETURN pCode; } @@ -2366,7 +2425,7 @@ PCODE TheUMThunkPreStub() return GetEEFuncEntryPoint(TheUMEntryPrestub); } -PCODE TheVarargNDirectStub(BOOL hasRetBuffArg) +PCODE TheVarargPInvokeStub(BOOL hasRetBuffArg) { LIMITED_METHOD_CONTRACT; @@ -2387,14 +2446,13 @@ static PCODE PatchNonVirtualExternalMethod(MethodDesc * pMD, PCODE pCode, PTR_RE STANDARD_VM_CONTRACT; // - // Skip fixup precode jump for better perf. Since we have MethodDesc available, we can use cheaper method - // than code:Precode::TryToSkipFixupPrecode. + // Skip fixup precode jump for better perf. // #ifdef HAS_FIXUP_PRECODE if (pMD->HasPrecode() && pMD->GetPrecode()->GetType() == PRECODE_FIXUP && pMD->IsNativeCodeStableAfterInit()) { - PCODE pDirectTarget = pMD->IsFCall() ? ECall::GetFCallImpl(pMD) : pMD->GetNativeCode(); + PCODE pDirectTarget = pMD->IsFCall() ? ECall::GetFCallImpl(pMD, false /* throwForInvalidFCall */) : pMD->GetNativeCode(); if (pDirectTarget != (PCODE)NULL) pCode = pDirectTarget; } @@ -3300,7 +3358,7 @@ PCODE DynamicHelperFixup(TransitionBlock * pTransitionBlock, TADDR * pCell, DWOR if (pHelper != (PCODE)NULL) { - *(TADDR *)pCell = pHelper; + VolatileStore((TADDR *)pCell, pHelper); } #ifdef _DEBUG diff --git a/src/coreclr/vm/profilingenumerators.cpp b/src/coreclr/vm/profilingenumerators.cpp index 50883da5ea8822..d26fc03ea18d0b 100644 --- a/src/coreclr/vm/profilingenumerators.cpp +++ b/src/coreclr/vm/profilingenumerators.cpp @@ -47,46 +47,50 @@ BOOL ProfilerFunctionEnum::Init(BOOL fWithReJITIDs) } CONTRACTL_END; - EEJitManager::CodeHeapIterator heapIterator; - while(heapIterator.Next()) + BOOL result = TRUE; + EX_TRY { - MethodDesc *pMD = heapIterator.GetMethod(); - - // On AMD64 JumpStub is used to call functions that is 2GB away. JumpStubs have a CodeHeader - // with NULL MethodDesc, are stored in code heap and are reported by EEJitManager::EnumCode. - if (pMD == NULL) - continue; - - // There are two possible reasons to skip this MD. - // - // 1) If it has no metadata (i.e., LCG / IL stubs), then skip it - // - // 2) If it has no code compiled yet for it, then skip it. - // - if (pMD->IsNoMetadata() || !pMD->HasNativeCode()) + CodeHeapIterator heapIterator = ExecutionManager::GetEEJitManager()->GetCodeHeapIterator(); + while (heapIterator.Next()) { - continue; - } + MethodDesc *pMD = heapIterator.GetMethod(); + + // Stubs (see StubCodeBlockKind) have no MethodDesc. Skip them. + if (pMD == NULL) + continue; + + // There are two possible reasons to skip this MD. + // + // 1) If it has no metadata (i.e., LCG / IL stubs), then skip it + // + // 2) If it has no code compiled yet for it, then skip it. + // + if (pMD->IsNoMetadata() || !pMD->HasNativeCode()) + { + continue; + } - COR_PRF_FUNCTION * element = m_elements.Append(); - if (element == NULL) - { - return FALSE; - } - element->functionId = (FunctionID) pMD; + COR_PRF_FUNCTION * element = m_elements.AppendThrowing(); + element->functionId = (FunctionID) pMD; - if (fWithReJITIDs) - { - // This causes triggering and locking, while the non-rejitid case does not. - element->reJitId = ReJitManager::GetReJitId(pMD, heapIterator.GetMethodCode()); - } - else - { - element->reJitId = 0; + if (fWithReJITIDs) + { + // This causes triggering and locking, while the non-rejitid case does not. + element->reJitId = ReJitManager::GetReJitId(pMD, heapIterator.GetMethodCode()); + } + else + { + element->reJitId = 0; + } } } + EX_CATCH + { + result = FALSE; + } + EX_END_CATCH - return TRUE; + return result; } // --------------------------------------------------------------------------------------- @@ -210,15 +214,8 @@ HRESULT IterateAppDomains(CallbackObject * callbackObj, // #ProfilerEnumAppDomains (See also code:#ProfilerEnumGeneral) // - // When enumerating AppDomains, ensure this timeline: - // AD available in catch-up enumeration - // < AppDomainCreationFinished issued - // < AD NOT available from catch-up enumeration - // - // * AppDomainCreationFinished (with S_OK hrStatus) is issued once the AppDomain - // reaches STAGE_ACTIVE. AppDomain * pAppDomain = ::GetAppDomain(); - if (pAppDomain->IsActive()) + if (pAppDomain) { // Of course, the AD could start unloading here, but if it does we're guaranteed @@ -567,7 +564,7 @@ HRESULT ProfilerThreadEnum::Init() // 1. Include Thread::TS_FullyInitialized threads for ThreadCreated // 2. Exclude Thread::TS_Dead | Thread::TS_ReportDead for ThreadDestroyed // - while((pThread = ThreadStore::GetAllThreadList( + while ((pThread = ThreadStore::GetAllThreadList( pThread, Thread::TS_Dead | Thread::TS_ReportDead | Thread::TS_FullyInitialized, Thread::TS_FullyInitialized diff --git a/src/coreclr/vm/profilinghelper.cpp b/src/coreclr/vm/profilinghelper.cpp index 99eb7eb0921ec0..ccf23ed65ef1be 100644 --- a/src/coreclr/vm/profilinghelper.cpp +++ b/src/coreclr/vm/profilinghelper.cpp @@ -85,7 +85,7 @@ // these actions: // * (a) Set the profiler's status to a non-active state like kProfStatusDetaching or // kProfStatusNone -// * (b) Call FlushProcessWriteBuffers() +// * (b) Call minipal_memory_barrier_process_wide() // * (c) Grab thread store lock, iterate through all threads, and verify each per-thread // evacuation counter is zero. // @@ -110,6 +110,7 @@ #include "proftoeeinterfaceimpl.inl" #include "profilinghelper.h" #include "profilinghelper.inl" +#include #ifdef FEATURE_PROFAPI_ATTACH_DETACH @@ -208,7 +209,7 @@ void CurrentProfilerStatus::Set(ProfilerStatus newProfStatus) // can safely perform catchup at that time (see // code:#ProfCatchUpSynchronization). // - ::FlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); } #endif // !defined(DACCESS_COMPILE) } diff --git a/src/coreclr/vm/proftoeeinterfaceimpl.cpp b/src/coreclr/vm/proftoeeinterfaceimpl.cpp index 5ee0da02ac2a30..effd3b73b37441 100644 --- a/src/coreclr/vm/proftoeeinterfaceimpl.cpp +++ b/src/coreclr/vm/proftoeeinterfaceimpl.cpp @@ -8087,7 +8087,7 @@ StackWalkAction ProfilerStackWalkCallback(CrawlFrame *pCf, PROFILER_STACK_WALK_D { // Skip new exception handling helpers InlinedCallFrame *pInlinedCallFrame = dac_cast(pCf->GetFrame()); - PTR_NDirectMethodDesc pMD = pInlinedCallFrame->m_Datum; + PTR_PInvokeMethodDesc pMD = pInlinedCallFrame->m_Datum; TADDR datum = dac_cast(pMD); if ((datum & (TADDR)InlinedCallFrameMarker::Mask) == (TADDR)InlinedCallFrameMarker::ExceptionHandlingHelper) { diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index f8238e0811025e..e2dd498b8b483a 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -518,9 +518,7 @@ static const Entry s_QCall[] = DllImportEntry(StubHelpers_ProfilerBeginTransitionCallback) DllImportEntry(StubHelpers_ProfilerEndTransitionCallback) #endif - DllImportEntry(StubHelpers_GetHRExceptionObject) #if defined(FEATURE_COMINTEROP) - DllImportEntry(StubHelpers_GetCOMHRExceptionObject) DllImportEntry(StubHelpers_GetCOMIPFromRCWSlow) DllImportEntry(ObjectMarshaler_ConvertToNative) DllImportEntry(ObjectMarshaler_ConvertToManaged) @@ -550,6 +548,7 @@ static const Entry s_QCall[] = DllImportEntry(ThrowInvalidCastException) DllImportEntry(IsInstanceOf_NoCacheLookup) DllImportEntry(VersionResilientHashCode_TypeHashCode) + DllImportEntry(TailCallHelp_AllocTailCallArgBufferInternal) }; const void* QCallResolveDllImport(const char* name) diff --git a/src/coreclr/vm/readytoruninfo.cpp b/src/coreclr/vm/readytoruninfo.cpp index 2fa9632fea82b8..e9e68f9c1fb45f 100644 --- a/src/coreclr/vm/readytoruninfo.cpp +++ b/src/coreclr/vm/readytoruninfo.cpp @@ -333,14 +333,13 @@ PTR_BYTE ReadyToRunInfo::GetDebugInfo(PTR_RUNTIME_FUNCTION pRuntimeFunction) } CONTRACTL_END; - IMAGE_DATA_DIRECTORY * pDebugInfoDir = m_pComposite->FindSection(ReadyToRunSectionType::DebugInfo); - if (pDebugInfoDir == NULL) + if (m_pSectionDebugInfo == NULL) return NULL; SIZE_T methodIndex = pRuntimeFunction - m_pRuntimeFunctions; _ASSERTE(methodIndex < m_nRuntimeFunctions); - NativeArray debugInfoIndex(dac_cast(PTR_HOST_INT_TO_TADDR(&m_nativeReader)), pDebugInfoDir->VirtualAddress); + NativeArray debugInfoIndex(dac_cast(PTR_HOST_INT_TO_TADDR(&m_nativeReader)), m_pSectionDebugInfo->VirtualAddress); uint offset; if (!debugInfoIndex.TryGetAt((DWORD)methodIndex, &offset)) @@ -884,6 +883,7 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, LoaderAllocator* pLoaderAllocat } m_pSectionDelayLoadMethodCallThunks = m_pComposite->FindSection(ReadyToRunSectionType::DelayLoadMethodCallThunks); + m_pSectionDebugInfo = m_pComposite->FindSection(ReadyToRunSectionType::DebugInfo); IMAGE_DATA_DIRECTORY * pinstMethodsDir = m_pComposite->FindSection(ReadyToRunSectionType::InstanceMethodEntryPoints); if (pinstMethodsDir != NULL) @@ -1251,10 +1251,10 @@ PCODE ReadyToRunInfo::GetEntryPoint(MethodDesc * pMD, PrepareCodeConfig* pConfig if (fFixups) { - BOOL mayUsePrecompiledNDirectMethods = TRUE; - mayUsePrecompiledNDirectMethods = !pConfig->IsForMulticoreJit(); + BOOL mayUsePrecompiledPInvokeMethods = TRUE; + mayUsePrecompiledPInvokeMethods = !pConfig->IsForMulticoreJit(); - if (!m_pModule->FixupDelayList(dac_cast(GetImage()->GetBase()) + offset, mayUsePrecompiledNDirectMethods)) + if (!m_pModule->FixupDelayList(dac_cast(GetImage()->GetBase()) + offset, mayUsePrecompiledPInvokeMethods)) { pConfig->SetReadyToRunRejectedPrecompiledCode(); goto done; @@ -2033,9 +2033,11 @@ PCODE CreateDynamicHelperPrecode(LoaderAllocator *pAllocator, AllocMemTracker *p STANDARD_VM_CONTRACT; size_t size = sizeof(StubPrecode); - StubPrecode *pPrecode = (StubPrecode *)pamTracker->Track(pAllocator->GetDynamicHelpersStubHeap()->AllocAlignedMem(size, 1)); + StubPrecode *pPrecode = (StubPrecode *)pamTracker->Track(pAllocator->GetDynamicHelpersStubHeap()->AllocStub()); pPrecode->Init(pPrecode, DynamicHelperArg, pAllocator, PRECODE_DYNAMIC_HELPERS, DynamicHelper); + FlushCacheForDynamicMappedStub(pPrecode, sizeof(StubPrecode)); + #ifdef FEATURE_PERFMAP PerfMap::LogStubs(__FUNCTION__, "DynamicHelper", (PCODE)pPrecode, size, PerfMapStubType::IndividualWithinBlock); #endif diff --git a/src/coreclr/vm/readytoruninfo.h b/src/coreclr/vm/readytoruninfo.h index a67a539f743a17..5b7d071c171eb9 100644 --- a/src/coreclr/vm/readytoruninfo.h +++ b/src/coreclr/vm/readytoruninfo.h @@ -119,6 +119,7 @@ class ReadyToRunInfo DWORD m_nHotColdMap; PTR_IMAGE_DATA_DIRECTORY m_pSectionDelayLoadMethodCallThunks; + PTR_IMAGE_DATA_DIRECTORY m_pSectionDebugInfo; PTR_READYTORUN_IMPORT_SECTION m_pImportSections; DWORD m_nImportSections; @@ -351,6 +352,7 @@ struct cdac_data static constexpr size_t NumHotColdMap = offsetof(ReadyToRunInfo, m_nHotColdMap); static constexpr size_t HotColdMap = offsetof(ReadyToRunInfo, m_pHotColdMap); static constexpr size_t DelayLoadMethodCallThunks = offsetof(ReadyToRunInfo, m_pSectionDelayLoadMethodCallThunks); + static constexpr size_t DebugInfoSection = offsetof(ReadyToRunInfo, m_pSectionDebugInfo); static constexpr size_t EntryPointToMethodDescMap = offsetof(ReadyToRunInfo, m_entryPointToMethodDescMap); }; diff --git a/src/coreclr/vm/reflectioninvocation.cpp b/src/coreclr/vm/reflectioninvocation.cpp index b3a8b99bb92a52..17bc9e61303cc1 100644 --- a/src/coreclr/vm/reflectioninvocation.cpp +++ b/src/coreclr/vm/reflectioninvocation.cpp @@ -242,6 +242,13 @@ class ArgIteratorBaseForMethodInvoke return FALSE; } + BOOL HasAsyncContinuation() + { + LIMITED_METHOD_CONTRACT; + // async calls are also not supported for reflection invoke + return FALSE; + } + BOOL IsVarArg() { LIMITED_METHOD_CONTRACT; @@ -335,6 +342,11 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_InvokeMethod( COMPlusThrow(kNotSupportedException, W("NotSupported_Type")); } + if (pMeth->IsAsyncMethod()) + { + COMPlusThrow(kNotSupportedException, W("NotSupported_Async")); + } + #ifdef _DEBUG if (g_pConfig->ShouldInvokeHalt(pMeth)) { @@ -605,7 +617,7 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_InvokeMethod( // We have a special case for Strings...The object is returned... if (fCtorOfVariableSizedObject) { PVOID pReturnValue = &callDescrData.returnValue; - gc.retVal = *(OBJECTREF *)pReturnValue; + gc.retVal = ObjectToOBJECTREF(*(Object**)pReturnValue); } // If it is a Nullable, box it using Nullable conventions. @@ -1468,11 +1480,13 @@ extern "C" void QCALLTYPE ReflectionInvocation_GetGuid(MethodTable* pMT, GUID* r * doesn't guarantee that a ctor will succeed, only that the VM is able * to support an instance of this type on the heap. * ========== + * The 'allowByRefLike' parameter controls whether the type should be validated as not ByRefLike. * The 'fForGetUninitializedInstance' parameter controls the type of * exception that is thrown if a check fails. */ -void RuntimeTypeHandle::ValidateTypeAbleToBeInstantiated( +static void ValidateTypeAbleToBeInstantiated( TypeHandle typeHandle, + bool allowByRefLike, bool fGetUninitializedObject) { STANDARD_VM_CONTRACT; @@ -1528,14 +1542,14 @@ void RuntimeTypeHandle::ValidateTypeAbleToBeInstantiated( } // Don't allow ref structs - if (pMT->IsByRefLike()) + if (!allowByRefLike && pMT->IsByRefLike()) { COMPlusThrow(kNotSupportedException, W("NotSupported_ByRefLike")); } } /* - * Given a RuntimeType, queries info on how to instantiate the object. + * Given a RuntimeType, queries info on how to instantiate the type. * pRuntimeType - [required] the RuntimeType object * ppfnAllocator - [required, null-init] fnptr to the allocator * mgd sig: void* -> object @@ -1586,7 +1600,7 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_GetActivationInfo( typeHandle = ((REFLECTCLASSBASEREF)pRuntimeType.Get())->GetType(); } - RuntimeTypeHandle::ValidateTypeAbleToBeInstantiated(typeHandle, false /* fGetUninitializedObject */); + ValidateTypeAbleToBeInstantiated(typeHandle, true /* allowByRefLike */, false /* fGetUninitializedObject */); MethodTable* pMT = typeHandle.AsMethodTable(); _ASSERTE(pMT != NULL); @@ -1739,7 +1753,8 @@ extern "C" void QCALLTYPE ReflectionSerialization_GetCreateUninitializedObjectIn TypeHandle type = pType.AsTypeHandle(); - RuntimeTypeHandle::ValidateTypeAbleToBeInstantiated(type, true /* fForGetUninitializedInstance */); + // ByRefLike types can't be boxed (allocated as an uninitialized object). + ValidateTypeAbleToBeInstantiated(type, false /* allowRefLike */, true /* fForGetUninitializedInstance */); MethodTable* pMT = type.AsMethodTable(); @@ -1912,7 +1927,8 @@ extern "C" void QCALLTYPE ReflectionInvocation_GetBoxInfo( TypeHandle type = pType.AsTypeHandle(); - RuntimeTypeHandle::ValidateTypeAbleToBeInstantiated(type, true /* fForGetUninitializedInstance */); + // ByRefLike types can't be boxed. + ValidateTypeAbleToBeInstantiated(type, false /* allowRefLike */, true /* fForGetUninitializedInstance */); MethodTable* pMT = type.AsMethodTable(); diff --git a/src/coreclr/vm/rejit.cpp b/src/coreclr/vm/rejit.cpp index f0bdf78289f507..4f0b02c2416f75 100644 --- a/src/coreclr/vm/rejit.cpp +++ b/src/coreclr/vm/rejit.cpp @@ -548,7 +548,9 @@ HRESULT ReJitManager::UpdateActiveILVersions( if ((flags & COR_PRF_REJIT_BLOCK_INLINING) == COR_PRF_REJIT_BLOCK_INLINING) { - hr = UpdateNativeInlinerActiveILVersions(&mgrToCodeActivationBatch, pModule, rgMethodDefs[i], fIsRevert, flags); + _ASSERTE(!fIsRevert); + + hr = UpdateNativeInlinerActiveILVersions(&mgrToCodeActivationBatch, pModule, rgMethodDefs[i], flags); if (FAILED(hr)) { return hr; @@ -711,7 +713,6 @@ HRESULT ReJitManager::UpdateNativeInlinerActiveILVersions( SHash *pMgrToCodeActivationBatch, Module *pInlineeModule, mdMethodDef inlineeMethodDef, - BOOL fIsRevert, COR_PRF_REJIT_FLAGS flags) { CONTRACTL @@ -758,7 +759,7 @@ HRESULT ReJitManager::UpdateNativeInlinerActiveILVersions( } } - hr = UpdateActiveILVersion(pMgrToCodeActivationBatch, inliner.m_module, inliner.m_methodDef, fIsRevert, flags); + hr = UpdateActiveILVersion(pMgrToCodeActivationBatch, inliner.m_module, inliner.m_methodDef, FALSE /* fIsRevert */, flags); if (FAILED(hr)) { ReportReJITError(inliner.m_module, inliner.m_methodDef, NULL, hr); diff --git a/src/coreclr/vm/rejit.h b/src/coreclr/vm/rejit.h index a994f9d3455b5d..5dfb5697d12860 100644 --- a/src/coreclr/vm/rejit.h +++ b/src/coreclr/vm/rejit.h @@ -166,7 +166,6 @@ class ReJitManager SHash *pMgrToCodeActivationBatch, Module *pInlineeModule, mdMethodDef inlineeMethodDef, - BOOL fIsRevert, COR_PRF_REJIT_FLAGS flags); static HRESULT UpdateJitInlinerActiveILVersions( diff --git a/src/coreclr/vm/riscv64/asmconstants.h b/src/coreclr/vm/riscv64/asmconstants.h index 0b88275bc32870..b2260e8a30f26d 100644 --- a/src/coreclr/vm/riscv64/asmconstants.h +++ b/src/coreclr/vm/riscv64/asmconstants.h @@ -85,8 +85,8 @@ ASMCONSTANTS_C_ASSERT(CallDescrData__returnValue == offsetof(CallDescrD #define FpStruct__BothFloat 0b10 ASMCONSTANTS_C_ASSERT(FpStruct__BothFloat == (int)FpStruct::BothFloat) -#define VASigCookie__pNDirectILStub 0x8 -ASMCONSTANTS_C_ASSERT(VASigCookie__pNDirectILStub == offsetof(VASigCookie, pNDirectILStub)) +#define VASigCookie__pPInvokeILStub 0x8 +ASMCONSTANTS_C_ASSERT(VASigCookie__pPInvokeILStub == offsetof(VASigCookie, pPInvokeILStub)) #define SIZEOF__Frame 0x10 ASMCONSTANTS_C_ASSERT(SIZEOF__Frame == sizeof(Frame)); diff --git a/src/coreclr/vm/riscv64/asmhelpers.S b/src/coreclr/vm/riscv64/asmhelpers.S index 69e1acee43767f..1c03436880c0cc 100644 --- a/src/coreclr/vm/riscv64/asmhelpers.S +++ b/src/coreclr/vm/riscv64/asmhelpers.S @@ -318,14 +318,14 @@ NESTED_ENTRY ThePreStub, _TEXT, NoHandler NESTED_END ThePreStub, _TEXT // ------------------------------------------------------------------ -// The call in ndirect import precode points to this function. -NESTED_ENTRY NDirectImportThunk, _TEXT, NoHandler +// The call in PInvokeImportPrecode points to this function. +NESTED_ENTRY PInvokeImportThunk, _TEXT, NoHandler PROLOG_SAVE_REG_PAIR_INDEXED fp, ra, 0xa0 SAVE_ARGUMENT_REGISTERS sp, 0x20 SAVE_FLOAT_ARGUMENT_REGISTERS sp, 0x60 addi a0, t2, 0 - call C_FUNC(NDirectImportWorker) + call C_FUNC(PInvokeImportWorker) addi t4, a0, 0 // pop the stack and restore original register state @@ -334,10 +334,10 @@ NESTED_ENTRY NDirectImportThunk, _TEXT, NoHandler //EPILOG_RESTORE_REG gp, 16 EPILOG_RESTORE_REG_PAIR_INDEXED fp, ra, 0xa0 - // If we got back from NDirectImportWorker, the MD has been successfully + // If we got back from PInvokeImportWorker, the MD has been successfully // linked. Proceed to execute the original DLL call. EPILOG_BRANCH_REG t4 -NESTED_END NDirectImportThunk, _TEXT +NESTED_END PInvokeImportThunk, _TEXT // ------------------------------------------------------------------ // ThePreStubPatch() diff --git a/src/coreclr/vm/riscv64/cgencpu.h b/src/coreclr/vm/riscv64/cgencpu.h index 8f09e0ed6433e9..f4c10a3d0e7c04 100644 --- a/src/coreclr/vm/riscv64/cgencpu.h +++ b/src/coreclr/vm/riscv64/cgencpu.h @@ -65,7 +65,7 @@ extern PCODE GetPreStubEntryPoint(); #define JUMP_ALLOCATE_SIZE 40 // # bytes to allocate for a jump instruction #define BACK_TO_BACK_JUMP_ALLOCATE_SIZE 40 // # bytes to allocate for a back to back jump instruction -#define HAS_NDIRECT_IMPORT_PRECODE 1 +#define HAS_PINVOKE_IMPORT_PRECODE 1 #define HAS_FIXUP_PRECODE 1 diff --git a/src/coreclr/vm/riscv64/pinvokestubs.S b/src/coreclr/vm/riscv64/pinvokestubs.S index 9f065a37e474d1..85eb386154f905 100644 --- a/src/coreclr/vm/riscv64/pinvokestubs.S +++ b/src/coreclr/vm/riscv64/pinvokestubs.S @@ -21,7 +21,7 @@ NESTED_ENTRY \__PInvokeStubFuncName, _TEXT, NoHandler // get the stub - ld t0, (VASigCookie__pNDirectILStub)(\VASigCookieReg) + ld t0, (VASigCookie__pPInvokeILStub)(\VASigCookieReg) // if null goto stub generation beq t0, zero, \__PInvokeGenStubFuncName diff --git a/src/coreclr/vm/riscv64/thunktemplates.S b/src/coreclr/vm/riscv64/thunktemplates.S index 8b58b4ec48b0db..e2990d44c57eee 100644 --- a/src/coreclr/vm/riscv64/thunktemplates.S +++ b/src/coreclr/vm/riscv64/thunktemplates.S @@ -16,9 +16,10 @@ LEAF_ENTRY FixupPrecodeCode ld t2, (FixupPrecodeData__Target)(t2) c.jr t2 + fence r,rw auipc t2, 0x4 - ld t1, (FixupPrecodeData__PrecodeFixupThunk - 0xa)(t2) - ld t2, (FixupPrecodeData__MethodDesc - 0xa)(t2) + ld t1, (FixupPrecodeData__PrecodeFixupThunk - 0xe)(t2) + ld t2, (FixupPrecodeData__MethodDesc - 0xe)(t2) jr t1 LEAF_END_MARKED FixupPrecodeCode diff --git a/src/coreclr/vm/runtimecallablewrapper.cpp b/src/coreclr/vm/runtimecallablewrapper.cpp index 3a48edd4f1f8fa..a87c2305e1beb9 100644 --- a/src/coreclr/vm/runtimecallablewrapper.cpp +++ b/src/coreclr/vm/runtimecallablewrapper.cpp @@ -941,7 +941,7 @@ VOID RCWCleanupList::AddWrapper(RCW* pRCW) CONTRACTL_END; // For the global cleanup list, this is called only from the finalizer thread - _ASSERTE(this != g_pRCWCleanupList || GetThread() == FinalizerThread::GetFinalizerThread()); + _ASSERTE(this != g_pRCWCleanupList || FinalizerThread::IsCurrentThreadFinalizer()); { CrstHolder ch(&m_lock); @@ -1002,7 +1002,7 @@ VOID RCWCleanupList::CleanupAllWrappers() MODE_ANY; // For the global cleanup list, this is called only from the finalizer thread - PRECONDITION( (this != g_pRCWCleanupList) || (GetThread() == FinalizerThread::GetFinalizerThread())); + PRECONDITION( (this != g_pRCWCleanupList) || FinalizerThread::IsCurrentThreadFinalizer()); } CONTRACTL_END; diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 9718435c4f703b..9641005ec0aefd 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -30,6 +30,7 @@ #include "invokeutil.h" #include "castcache.h" #include "encee.h" +#include "finalizerthread.h" extern "C" BOOL QCALLTYPE MdUtf8String_EqualsCaseInsensitive(LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes) { @@ -440,6 +441,15 @@ extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetMethodAt(MethodTable* pMT, } } + if (pRetMethod != NULL && pRetMethod->IsAsyncVariantMethod()) + { + // do not return methoddescs for async variants. + // NOTE: The only scenario where this is relevant is when caller iterates through all slots. + // If GetMethodAt is used to find a method associated with another one, + // then we would be starting with "real" method and will get a "real" method here. + pRetMethod = NULL; + } + END_QCALL; return pRetMethod; @@ -1758,30 +1768,32 @@ FCIMPLEND extern "C" void QCALLTYPE RuntimeMethodHandle_Destroy(MethodDesc * pMethod) { QCALL_CONTRACT; + _ASSERTE(pMethod != NULL); + _ASSERTE(pMethod->IsDynamicMethod()); BEGIN_QCALL; - if (pMethod == NULL) - COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle")); - DynamicMethodDesc* pDynamicMethodDesc = pMethod->AsDynamicMethodDesc(); - GCX_COOP(); + { + GCX_COOP(); - // Destroy should be called only if the managed part is gone. - _ASSERTE(OBJECTREFToObject(pDynamicMethodDesc->GetLCGMethodResolver()->GetManagedResolver()) == NULL); + // Destroy should be called only if the managed part is gone. + _ASSERTE(OBJECTREFToObject(pDynamicMethodDesc->GetLCGMethodResolver()->GetManagedResolver()) == NULL); - // Fire Unload Dynamic Method Event here - ETW::MethodLog::DynamicMethodDestroyed(pMethod); + // Fire Unload Dynamic Method Event here + ETW::MethodLog::DynamicMethodDestroyed(pMethod); - BEGIN_PROFILER_CALLBACK(CORProfilerTrackDynamicFunctionUnloads()); - (&g_profControlBlock)->DynamicMethodUnloaded((FunctionID)pMethod); - END_PROFILER_CALLBACK(); + BEGIN_PROFILER_CALLBACK(CORProfilerTrackDynamicFunctionUnloads()); + (&g_profControlBlock)->DynamicMethodUnloaded((FunctionID)pMethod); + END_PROFILER_CALLBACK(); + } - pDynamicMethodDesc->Destroy(); + if (!pDynamicMethodDesc->TryDestroy()) + FinalizerThread::DelayDestroyDynamicMethodDesc(pDynamicMethodDesc); END_QCALL; - } +} FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsTypicalMethodDefinition, ReflectMethodObject *pMethodUNSAFE) { diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 52dfc53d21b363..a35021f74375d2 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -113,8 +113,6 @@ class RuntimeTypeHandle static FCDECL1(FC_BOOL_RET, IsUnmanagedFunctionPointer, ReflectClassBaseObject *pTypeUNSAFE); - static FCDECL2(TypeHandle::CastResult, CanCastToInternal, ReflectClassBaseObject *pType, ReflectClassBaseObject *pTarget); - static FCDECL1(FC_BOOL_RET, IsGenericVariable, PTR_ReflectClassBaseObject pType); @@ -132,10 +130,6 @@ class RuntimeTypeHandle static FCDECL1(MethodDesc *, GetFirstIntroducedMethod, ReflectClassBaseObject* pType); static FCDECL1(void, GetNextIntroducedMethod, MethodDesc **ppMethod); - - // Helper methods not called by managed code - - static void ValidateTypeAbleToBeInstantiated(TypeHandle typeHandle, bool fGetUninitializedObject); }; extern "C" void QCALLTYPE RuntimeTypeHandle_GetRuntimeTypeFromHandleSlow(void* typeHandleRaw, QCall::ObjectHandleOnStack result); diff --git a/src/coreclr/vm/siginfo.cpp b/src/coreclr/vm/siginfo.cpp index 70e0c9d4751ab7..e23a17418e89f1 100644 --- a/src/coreclr/vm/siginfo.cpp +++ b/src/coreclr/vm/siginfo.cpp @@ -185,7 +185,7 @@ void SigPointer::ConvertToInternalExactlyOne(Module* pSigModule, const SigTypeCo { mdToken tk; IfFailThrowBF(GetToken(&tk), BFA_BAD_COMPLUS_SIG, pSigModule); - TypeHandle th = ClassLoader::LoadTypeDefOrRefThrowing(pSigModule, tk); + TypeHandle th = ClassLoader::LoadTypeDefOrRefThrowing(pSigModule, tk, ClassLoader::ThrowIfNotFound, ClassLoader::PermitUninstDefOrRef); pSigBuilder->AppendElementType(ELEMENT_TYPE_CMOD_INTERNAL); pSigBuilder->AppendByte(typ == ELEMENT_TYPE_CMOD_REQD); // "is required" byte pSigBuilder->AppendPointer(th.AsPtr()); diff --git a/src/coreclr/vm/specialstatics.h b/src/coreclr/vm/specialstatics.h index 6ad0fdc63c9a2a..aa6c1b6f08c00c 100644 --- a/src/coreclr/vm/specialstatics.h +++ b/src/coreclr/vm/specialstatics.h @@ -34,6 +34,4 @@ typedef struct _STATIC_DATA } STATIC_DATA; typedef SPTR(STATIC_DATA) PTR_STATIC_DATA; -typedef SimpleList ObjectHandleList; - #endif diff --git a/src/coreclr/vm/stackingallocator.cpp b/src/coreclr/vm/stackingallocator.cpp index b49a96ccd0ec58..e97ae4a69e8fd3 100644 --- a/src/coreclr/vm/stackingallocator.cpp +++ b/src/coreclr/vm/stackingallocator.cpp @@ -321,7 +321,7 @@ void StackingAllocator::Validate(StackBlock *block, void* spot) { // If this assert goes off then someone overwrote their buffer! // A common candidate is PINVOKE buffer run. To confirm look - // up on the stack for NDirect.* Look for the MethodDesc + // up on the stack for PInvoke.* Look for the MethodDesc // associated with it. Be very suspicious if it is one that // has a return string buffer!. This usually means the end // programmer did not allocate a big enough buffer before passing diff --git a/src/coreclr/vm/stackwalk.cpp b/src/coreclr/vm/stackwalk.cpp index c7275c7d9cbefa..3376d945e0ca91 100644 --- a/src/coreclr/vm/stackwalk.cpp +++ b/src/coreclr/vm/stackwalk.cpp @@ -1053,9 +1053,6 @@ void StackFrameIterator::CommonCtor(Thread * pThread, PTR_Frame pFrame, ULONG32 m_movedPastFirstExInfo = false; m_fFuncletNotSeen = false; m_fFoundFirstFunclet = false; -#ifdef FEATURE_INTERPRETER - m_walkingInterpreterFrames = false; -#endif #if defined(RECORD_RESUMABLE_FRAME_SP) m_pvResumableFrameTargetSP = NULL; #endif @@ -1285,7 +1282,7 @@ BOOL StackFrameIterator::ResetRegDisp(PREGDISPLAY pRegDisp, // 0012e884 ntdll32!DbgBreakPoint // 0012e89c CLRStub[StubLinkStub]@1f0ac1e // 0012e8a4 invalid ESP of Foo() according to the REGDISPLAY specified by the debuggers - // 0012e8b4 address of transition frame (NDirectMethodFrameStandalone) + // 0012e8b4 address of transition frame (PInvokeMethodFrameStandalone) // 0012e8c8 real ESP of Foo() according to the transition frame // 0012e8d8 managed!Dummy.Foo()+0x20 // @@ -2844,20 +2841,20 @@ void StackFrameIterator::ProcessCurrentFrame(void) #ifdef FEATURE_INTERPRETER if (!m_crawl.isFrameless) { + PREGDISPLAY pRD = m_crawl.GetRegisterSet(); + if (m_crawl.pFrame->GetFrameIdentifier() == FrameIdentifier::InterpreterFrame) { - PREGDISPLAY pRD = m_crawl.GetRegisterSet(); - - if (!m_walkingInterpreterFrames) + if (GetIP(pRD->pCurrentContext) != (PCODE)InterpreterFrame::DummyCallerIP) { // We have hit the InterpreterFrame while we were not processing the interpreter frames. // Switch to walking the underlying interpreted frames. // Save the registers the interpreter frames walking reuses so that we can restore them // after we are done with the interpreter frames. - m_interpExecMethodIP = (TADDR)GetIP(pRD->pCurrentContext); - m_interpExecMethodSP = (TADDR)GetSP(pRD->pCurrentContext); - m_interpExecMethodFP = (TADDR)GetFP(pRD->pCurrentContext); - m_interpExecMethodFirstArgReg = (TADDR)GetFirstArgReg(pRD->pCurrentContext); + m_interpExecMethodIP = GetIP(pRD->pCurrentContext); + m_interpExecMethodSP = GetSP(pRD->pCurrentContext); + m_interpExecMethodFP = GetFP(pRD->pCurrentContext); + m_interpExecMethodFirstArgReg = GetFirstArgReg(pRD->pCurrentContext); ((PTR_InterpreterFrame)m_crawl.pFrame)->SetContextToInterpMethodContextFrame(pRD->pCurrentContext); if (pRD->pCurrentContext->ContextFlags & CONTEXT_EXCEPTION_ACTIVE) @@ -2868,12 +2865,10 @@ void StackFrameIterator::ProcessCurrentFrame(void) SyncRegDisplayToCurrentContext(pRD); ProcessIp(GetControlPC(pRD)); - m_walkingInterpreterFrames = m_crawl.isFrameless; } else { // We have finished walking the interpreted frames. Process the InterpreterFrame itself. - m_walkingInterpreterFrames = false; // Restore the registers to the values they had before we started walking the interpreter frames. SetIP(pRD->pCurrentContext, m_interpExecMethodIP); SetSP(pRD->pCurrentContext, m_interpExecMethodSP); @@ -2882,6 +2877,16 @@ void StackFrameIterator::ProcessCurrentFrame(void) SyncRegDisplayToCurrentContext(pRD); } } + else if (InlinedCallFrame::FrameHasActiveCall(m_crawl.pFrame) && + (m_crawl.pFrame->PtrNextFrame() != FRAME_TOP) && + (m_crawl.pFrame->PtrNextFrame()->GetFrameIdentifier() == FrameIdentifier::InterpreterFrame)) + { + // There is an active inlined call frame and the next frame is the interpreter frame. This is a special case where we need to save the current context registers that the interpreter frames walking reuses. + m_interpExecMethodIP = GetIP(pRD->pCurrentContext); + m_interpExecMethodSP = GetSP(pRD->pCurrentContext); + m_interpExecMethodFP = GetFP(pRD->pCurrentContext); + m_interpExecMethodFirstArgReg = GetFirstArgReg(pRD->pCurrentContext); + } } #endif // FEATURE_INTERPRETER diff --git a/src/coreclr/vm/stackwalk.h b/src/coreclr/vm/stackwalk.h index ca4afa3e2df93a..6b650a277137e3 100644 --- a/src/coreclr/vm/stackwalk.h +++ b/src/coreclr/vm/stackwalk.h @@ -769,7 +769,6 @@ class StackFrameIterator // Indicates that the stack walk has moved past a funclet bool m_fFoundFirstFunclet; #ifdef FEATURE_INTERPRETER - bool m_walkingInterpreterFrames; // Saved registers of the context of the InterpExecMethod. These registers are reused for interpreter frames, // but we need to restore the original values after we are done with all the interpreted frames belonging to // that InterpExecMethod. diff --git a/src/coreclr/vm/stubgen.cpp b/src/coreclr/vm/stubgen.cpp index 14dec4e6bba036..06c99d1cb0cbd6 100644 --- a/src/coreclr/vm/stubgen.cpp +++ b/src/coreclr/vm/stubgen.cpp @@ -2517,7 +2517,7 @@ ILStubLinker::ILStubLinker(Module* pStubSigModule, const Signature &signature, S if ((flags & (ILSTUB_LINKER_FLAG_TARGET_HAS_THIS | ILSTUB_LINKER_FLAG_NDIRECT)) == ILSTUB_LINKER_FLAG_TARGET_HAS_THIS) { - // ndirect native sig never has a 'this' pointer + // PInvoke native sig never has a 'this' pointer uNativeCallingConv |= IMAGE_CEE_CS_CALLCONV_HASTHIS; } @@ -2680,7 +2680,7 @@ void ILStubLinker::TransformArgForJIT(LocalDesc *pLoc) STANDARD_VM_CONTRACT; // Turn everything into blittable primitives. The reason this method is needed are // byrefs which are OK only when they ref stack data or are pinned. This condition - // cannot be verified by code:NDirect.MarshalingRequired so we explicitly get rid + // cannot be verified by code:PInvoke.MarshalingRequired so we explicitly get rid // of them here. bool again; BYTE* elementType = pLoc->ElementType; diff --git a/src/coreclr/vm/stubhelpers.cpp b/src/coreclr/vm/stubhelpers.cpp index afcab14de162d7..4437f432123d05 100644 --- a/src/coreclr/vm/stubhelpers.cpp +++ b/src/coreclr/vm/stubhelpers.cpp @@ -543,81 +543,6 @@ extern "C" void QCALLTYPE StubHelpers_ProfilerEndTransitionCallback(MethodDesc* } #endif // PROFILING_SUPPORTED -extern "C" void QCALLTYPE StubHelpers_GetHRExceptionObject(HRESULT hr, QCall::ObjectHandleOnStack result) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - GCX_COOP(); - - OBJECTREF oThrowable = NULL; - GCPROTECT_BEGIN(oThrowable); - - // GetExceptionForHR uses equivalant logic as COMPlusThrowHR - GetExceptionForHR(hr, &oThrowable); - result.Set(oThrowable); - - GCPROTECT_END(); - - END_QCALL; -} - -#ifdef FEATURE_COMINTEROP -extern "C" void QCALLTYPE StubHelpers_GetCOMHRExceptionObject( - HRESULT hr, - MethodDesc* pMD, - QCall::ObjectHandleOnStack pThis, - QCall::ObjectHandleOnStack result) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - GCX_COOP(); - - struct - { - OBJECTREF oThrowable; - OBJECTREF oref; - } gc; - gc.oThrowable = NULL; - gc.oref = NULL; - GCPROTECT_BEGIN(gc); - - IErrorInfo* pErrorInfo = NULL; - if (pMD != NULL) - { - // Retrieve the interface method table. - MethodTable* pItfMT = CLRToCOMCallInfo::FromMethodDesc(pMD)->m_pInterfaceMT; - - // get 'this' - gc.oref = ObjectToOBJECTREF(pThis.Get()); - - // Get IUnknown pointer for this interface on this object - IUnknown* pUnk = ComObject::GetComIPFromRCW(&gc.oref, pItfMT); - if (pUnk != NULL) - { - // Check to see if the component supports error information for this interface. - IID ItfIID; - pItfMT->GetGuid(&ItfIID, TRUE); - pErrorInfo = GetSupportedErrorInfo(pUnk, ItfIID); - - DWORD cbRef = SafeRelease(pUnk); - LogInteropRelease(pUnk, cbRef, "IUnk to QI for ISupportsErrorInfo"); - } - } - - // GetExceptionForHR will handle lifetime of IErrorInfo. - GetExceptionForHR(hr, pErrorInfo, &gc.oThrowable); - result.Set(gc.oThrowable); - - GCPROTECT_END(); - - END_QCALL; -} -#endif // FEATURE_COMINTEROP - extern "C" void QCALLTYPE StubHelpers_MarshalToManagedVaList(va_list va, VARARGS* pArgIterator) { QCALL_CONTRACT; @@ -724,15 +649,6 @@ extern "C" void QCALLTYPE StubHelpers_ValidateByref(void *pByref, MethodDesc *pM END_QCALL; } -FCIMPL0(void*, StubHelpers::GetStubContext) -{ - FCALL_CONTRACT; - - FCUnique(0xa0); - UNREACHABLE_MSG_RET("This is a JIT intrinsic!"); -} -FCIMPLEND - FCIMPL2(void, StubHelpers::LogPinnedArgument, MethodDesc *target, Object *pinnedArg) { FCALL_CONTRACT; @@ -776,10 +692,3 @@ extern "C" void QCALLTYPE StubHelpers_MulticastDebuggerTraceHelper(QCall::Object END_QCALL; } - -FCIMPL0(void*, StubHelpers::NextCallReturnAddress) -{ - FCALL_CONTRACT; - UNREACHABLE_MSG("This is a JIT intrinsic!"); -} -FCIMPLEND diff --git a/src/coreclr/vm/stubhelpers.h b/src/coreclr/vm/stubhelpers.h index e77ce5f2e7f46e..00fdd97b6d1b64 100644 --- a/src/coreclr/vm/stubhelpers.h +++ b/src/coreclr/vm/stubhelpers.h @@ -35,11 +35,8 @@ class StubHelpers static FCDECL2(FC_BOOL_RET, TryGetStringTrailByte, StringObject* thisRefUNSAFE, UINT8 *pbData); - static FCDECL0(void*, GetStubContext); static FCDECL2(void, LogPinnedArgument, MethodDesc *localDesc, Object *nativeArg); static FCDECL1(DWORD, CalcVaListSize, VARARGS *varargs); - - static FCDECL0(void*, NextCallReturnAddress); }; extern "C" void QCALLTYPE StubHelpers_CreateCustomMarshaler(MethodDesc* pMD, mdToken paramToken, TypeHandle hndManagedType, QCall::ObjectHandleOnStack retObject); @@ -49,11 +46,7 @@ extern "C" void* QCALLTYPE StubHelpers_ProfilerBeginTransitionCallback(MethodDes extern "C" void QCALLTYPE StubHelpers_ProfilerEndTransitionCallback(MethodDesc* pTargetMD); #endif -extern "C" void QCALLTYPE StubHelpers_GetHRExceptionObject(HRESULT hr, QCall::ObjectHandleOnStack result); - #ifdef FEATURE_COMINTEROP -extern "C" void QCALLTYPE StubHelpers_GetCOMHRExceptionObject(HRESULT hr, MethodDesc *pMD, QCall::ObjectHandleOnStack pThis, QCall::ObjectHandleOnStack result); - extern "C" IUnknown* QCALLTYPE StubHelpers_GetCOMIPFromRCWSlow(QCall::ObjectHandleOnStack pSrc, MethodDesc* pMD, void** ppTarget); extern "C" void QCALLTYPE ObjectMarshaler_ConvertToNative(QCall::ObjectHandleOnStack pSrcUNSAFE, VARIANT* pDest); diff --git a/src/coreclr/vm/stublink.h b/src/coreclr/vm/stublink.h index cb83cda5c3e9fb..0cadd021266223 100644 --- a/src/coreclr/vm/stublink.h +++ b/src/coreclr/vm/stublink.h @@ -821,7 +821,7 @@ class InstructionFormat #define CPUSTUBLINKER StubLinkerCPU -class NDirectStubLinker; +class PInvokeStubLinker; class CPUSTUBLINKER; #endif // __stublink_h__ diff --git a/src/coreclr/vm/stubmgr.cpp b/src/coreclr/vm/stubmgr.cpp index 12a4ae6abe13ad..19159828008faa 100644 --- a/src/coreclr/vm/stubmgr.cpp +++ b/src/coreclr/vm/stubmgr.cpp @@ -1013,7 +1013,7 @@ BOOL PrecodeStubManager::CheckIsStub_Internal(PCODE stubStartAddress) switch (pPrecode->GetType()) { case PRECODE_STUB: - case PRECODE_NDIRECT_IMPORT: + case PRECODE_PINVOKE_IMPORT: case PRECODE_UMENTRY_THUNK: #ifdef HAS_THISPTR_RETBUF_PRECODE case PRECODE_THISPTR_RETBUF: @@ -1073,22 +1073,22 @@ BOOL PrecodeStubManager::DoTraceStub(PCODE stubStartAddress, case PRECODE_STUB: break; -#ifdef HAS_NDIRECT_IMPORT_PRECODE - case PRECODE_NDIRECT_IMPORT: +#ifdef HAS_PINVOKE_IMPORT_PRECODE + case PRECODE_PINVOKE_IMPORT: #ifndef DACCESS_COMPILE #if defined(TARGET_ARM64) && defined(__APPLE__) - // On ARM64 Mac, we cannot put a breakpoint inside of NDirectImportThunk + // On ARM64 Mac, we cannot put a breakpoint inside of PInvokeImportThunk LOG((LF_CORDB, LL_INFO10000, "PSM::DoTraceStub: Skipping on arm64-macOS\n")); return FALSE; #else - trace->InitForUnmanaged(GetEEFuncEntryPoint(NDirectImportThunk)); + trace->InitForUnmanaged(GetEEFuncEntryPoint(PInvokeImportThunk)); #endif //defined(TARGET_ARM64) && defined(__APPLE__) #else trace->InitForOther((PCODE)NULL); #endif - LOG_TRACE_DESTINATION(trace, stubStartAddress, "PrecodeStubManager::DoTraceStub - NDirect import"); + LOG_TRACE_DESTINATION(trace, stubStartAddress, "PrecodeStubManager::DoTraceStub - PInvoke import"); return TRUE; -#endif // HAS_NDIRECT_IMPORT_PRECODE +#endif // HAS_PINVOKE_IMPORT_PRECODE #ifdef HAS_FIXUP_PRECODE case PRECODE_FIXUP: @@ -1796,11 +1796,11 @@ BOOL ILStubManager::TraceManager(Thread *thread, // This is either direct forward P/Invoke or a CLR-to-COM call, the argument is MD MethodDesc *pMD = (MethodDesc *)arg; - if (pMD->IsNDirect()) + if (pMD->IsPInvoke()) { - NDirectMethodDesc* pNMD = reinterpret_cast(pMD); - _ASSERTE_IMPL(!pNMD->NDirectTargetIsImportThunk()); - target = (PCODE)pNMD->GetNDirectTarget(); + PInvokeMethodDesc* pNMD = reinterpret_cast(pMD); + _ASSERTE_IMPL(!pNMD->PInvokeTargetIsImportThunk()); + target = (PCODE)pNMD->GetPInvokeTarget(); LOG((LF_CORDB, LL_INFO10000, "ILSM::TraceManager: Forward P/Invoke case 0x%p\n", target)); trace->InitForUnmanaged(target); } @@ -1961,9 +1961,9 @@ BOOL InteropDispatchStubManager::TraceManager(Thread *thread, LOG((LF_CORDB, LL_INFO10000, "IDSM::TraceManager: Skipping on arm64-macOS\n")); return FALSE; #else - NDirectMethodDesc *pNMD = (NDirectMethodDesc *)arg; - _ASSERTE(pNMD->IsNDirect()); - PCODE target = (PCODE)pNMD->GetNDirectTarget(); + PInvokeMethodDesc *pNMD = (PInvokeMethodDesc *)arg; + _ASSERTE(pNMD->IsPInvoke()); + PCODE target = (PCODE)pNMD->GetPInvokeTarget(); LOG((LF_CORDB, LL_INFO10000, "IDSM::TraceManager: Vararg P/Invoke case %p\n", target)); trace->InitForUnmanaged(target); diff --git a/src/coreclr/vm/syncblk.cpp b/src/coreclr/vm/syncblk.cpp index 50bd8f110c64d6..55c7f39fe48904 100644 --- a/src/coreclr/vm/syncblk.cpp +++ b/src/coreclr/vm/syncblk.cpp @@ -510,7 +510,7 @@ void SyncBlockCache::CleanupSyncBlocks() STATIC_CONTRACT_THROWS; STATIC_CONTRACT_MODE_COOPERATIVE; - _ASSERTE(GetThread() == FinalizerThread::GetFinalizerThread()); + _ASSERTE(FinalizerThread::IsCurrentThreadFinalizer()); // Set the flag indicating sync block cleanup is in progress. // IMPORTANT: This must be set before the sync block cleanup bit is reset on the thread. diff --git a/src/coreclr/vm/tailcallhelp.cpp b/src/coreclr/vm/tailcallhelp.cpp index d59a2861a80c42..da2dcca7d1da13 100644 --- a/src/coreclr/vm/tailcallhelp.cpp +++ b/src/coreclr/vm/tailcallhelp.cpp @@ -11,14 +11,28 @@ #include "threads.h" -FCIMPL2(void*, TailCallHelp::AllocTailCallArgBufferWorker, INT32 size, void* gcDesc) +FCIMPL0(void*, TailCallHelp::GetTailCallArgBuffer) { FCALL_CONTRACT; - _ASSERTE(size >= 0); - return GetThread()->GetTailCallTls()->AllocArgBuffer(size, gcDesc); + return GetThread()->GetTailCallTls()->GetArgBuffer(); } FCIMPLEND +extern "C" void* QCALLTYPE TailCallHelp_AllocTailCallArgBufferInternal(int size) +{ + QCALL_CONTRACT; + + void* retVal = NULL; + + BEGIN_QCALL; + + retVal = GetThread()->GetTailCallTls()->AllocArgBuffer(size); + + END_QCALL; + + return retVal; +} + FCIMPL2(void*, TailCallHelp::GetTailCallInfo, void** retAddrSlot, void** retAddr) { FCALL_CONTRACT; @@ -30,7 +44,6 @@ FCIMPL2(void*, TailCallHelp::GetTailCallInfo, void** retAddrSlot, void** retAddr } FCIMPLEND - struct ArgBufferValue { TypeHandle TyHnd; @@ -486,14 +499,17 @@ MethodDesc* TailCallHelp::CreateCallTargetStub(const TailCallInfo& info) EmitLoadTyHnd(pCode, arg.TyHnd); } - // All arguments are loaded on the stack, it is safe to disable the GC reporting of ArgBuffer now. - // This is optimization to avoid extending argument lifetime unnecessarily. - // We still need to report the inst argument of shared generic code to prevent it from being unloaded. The inst - // argument is just a regular IntPtr on the stack. It is safe to stop reporting it only after the target method - // takes over. - pCode->EmitLDARG(ARG_ARG_BUFFER); - pCode->EmitLDC(info.ArgBufLayout.HasInstArg ? TAILCALLARGBUFFER_INSTARG_ONLY : TAILCALLARGBUFFER_ABANDONED); - pCode->EmitSTIND_I(); + if (info.HasGCDescriptor) + { + // All arguments are loaded on the stack, it is safe to disable the GC reporting of ArgBuffer now. + // This is optimization to avoid extending argument lifetime unnecessarily. + // We still need to report the inst argument of shared generic code to prevent it from being unloaded. The inst + // argument is just a regular IntPtr on the stack. It is safe to stop reporting it only after the target method + // takes over. + pCode->EmitLDARG(ARG_ARG_BUFFER); + pCode->EmitLDC(info.ArgBufLayout.HasInstArg ? TAILCALLARGBUFFER_INSTARG_ONLY : TAILCALLARGBUFFER_INACTIVE); + pCode->EmitSTIND_I4(); + } int numRetVals = info.CallSiteSig->IsReturnTypeVoid() ? 0 : 1; // Normally there will not be any target and we just emit a normal diff --git a/src/coreclr/vm/tailcallhelp.h b/src/coreclr/vm/tailcallhelp.h index 10b14bd9f6161d..aaa4f2f83ba52b 100644 --- a/src/coreclr/vm/tailcallhelp.h +++ b/src/coreclr/vm/tailcallhelp.h @@ -13,7 +13,7 @@ struct ArgBufferLayout; class TailCallHelp { public: - static FCDECL2(void*, AllocTailCallArgBufferWorker, INT32, void*); + static FCDECL0(void*, GetTailCallArgBuffer); static FCDECL2(void*, GetTailCallInfo, void**, void**); static void CreateTailCallHelperStubs( @@ -47,4 +47,6 @@ class TailCallHelp static void* AllocateBlob(LoaderAllocator* alloc, const void* blob, size_t blobLen); }; +extern "C" void* QCALLTYPE TailCallHelp_AllocTailCallArgBufferInternal(int size); + #endif diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp index a87bbafe1b46c6..92344beb931331 100644 --- a/src/coreclr/vm/threads.cpp +++ b/src/coreclr/vm/threads.cpp @@ -25,6 +25,7 @@ #include "comutilnative.h" #include "finalizerthread.h" #include "threadsuspend.h" +#include "configuration.h" #include "wrappers.h" @@ -80,39 +81,37 @@ Thread* STDCALL GetThreadHelper() return GetThreadNULLOk(); } -TailCallArgBuffer* TailCallTls::AllocArgBuffer(int size, void* gcDesc) +TailCallArgBuffer* TailCallTls::AllocArgBuffer(int size) { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END + STANDARD_VM_CONTRACT; _ASSERTE(size >= (int)offsetof(TailCallArgBuffer, Args)); - if (m_argBuffer != NULL && m_argBuffer->Size < size) - { - FreeArgBuffer(); - } + // Round the size up + size = max(size, (int)(8 * sizeof(void*))); + + TailCallArgBuffer* pBuffer = (TailCallArgBuffer*)new BYTE[size]; + TailCallArgBuffer* pOldBuffer; + + pBuffer->Size = size; + pBuffer->State = TAILCALLARGBUFFER_INACTIVE; - if (m_argBuffer == NULL) { - m_argBuffer = (TailCallArgBuffer*)new (nothrow) BYTE[size]; - if (m_argBuffer == NULL) - return NULL; - m_argBuffer->Size = size; - } + // We need to ensure that the GC does not run while we are switching the arg buffer. + GCX_COOP(); - m_argBuffer->State = TAILCALLARGBUFFER_ACTIVE; + pOldBuffer = m_argBuffer; + m_argBuffer = pBuffer; + } - m_argBuffer->GCDesc = gcDesc; - if (gcDesc != NULL) + if (pOldBuffer != NULL) { - memset(m_argBuffer->Args, 0, size - offsetof(TailCallArgBuffer, Args)); + _ASSERTE(pOldBuffer->Size < size); + + delete[] (BYTE*)pOldBuffer; } - return m_argBuffer; + return pBuffer; } #if defined (_DEBUG_IMPL) @@ -1142,13 +1141,13 @@ void InitThreadManager() #ifndef TARGET_UNIX _ASSERTE(GetThreadNULLOk() == NULL); - size_t offsetOfCurrentThreadInfo = Thread::GetOffsetOfThreadStatic(&t_CurrentThreadInfo); + g_offsetOfCurrentThreadInfo = (DWORD)Thread::GetOffsetOfThreadStatic(&t_CurrentThreadInfo); - _ASSERTE(offsetOfCurrentThreadInfo < 0x8000); + _ASSERTE(g_offsetOfCurrentThreadInfo < 0x8000); _ASSERTE(_tls_index < 0x10000); // Save t_CurrentThreadInfo location for debugger - SetIlsIndex((DWORD)(_tls_index + (offsetOfCurrentThreadInfo << 16) + 0x80000000)); + SetIlsIndex((DWORD)(_tls_index + (g_offsetOfCurrentThreadInfo << 16) + 0x80000000)); _ASSERTE(g_TrapReturningThreads == 0); #endif // !TARGET_UNIX @@ -2078,9 +2077,11 @@ void ParseDefaultStackSize(LPCWSTR valueStr) SIZE_T GetDefaultStackSizeSetting() { - static DWORD s_defaultStackSizeEnv = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DefaultStackSize); + static DWORD s_defaultStackSizeEnv = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Thread_DefaultStackSize); + static DWORD s_defaultStackSizeProp = Configuration::GetKnobDWORDValue(W("System.Threading.DefaultStackSize"), 0); - uint64_t value = s_defaultStackSizeEnv ? s_defaultStackSizeEnv : s_defaultStackSizeProperty; + uint64_t value = s_defaultStackSizeEnv ? s_defaultStackSizeEnv + : (s_defaultStackSizeProperty ? s_defaultStackSizeProperty : s_defaultStackSizeProp); SIZE_T minStack = 0x10000; // 64K - Somewhat arbitrary minimum thread stack size SIZE_T maxStack = 0x80000000; // 2G - Somewhat arbitrary maximum thread stack size @@ -2478,8 +2479,6 @@ Thread::~Thread() Exception::Delete (m_pExceptionDuringStartup); } - ClearContext(); - if (!IsAtProcessExit()) { // Destroy any handles that we're using to hold onto exception objects @@ -2850,7 +2849,6 @@ void Thread::OnThreadTerminate(BOOL holdingLock) GCX_COOP(); _ASSERTE(IsAtProcessExit()); - ClearContext(); if (m_ExposedObject != NULL) DecExternalCount(holdingLock); // may destruct now } @@ -3309,12 +3307,12 @@ DWORD Thread::DoAppropriateWaitWorker(int countHandles, HANDLE *handles, BOOL wa } ULONGLONG dwStart = 0, dwEnd; -retry: if (millis != INFINITE) { dwStart = minipal_lowres_ticks(); } +retry: if (tryNonblockingWaitFirst) { // We have a final wait result from the nonblocking wait above @@ -3344,10 +3342,9 @@ DWORD Thread::DoAppropriateWaitWorker(int countHandles, HANDLE *handles, BOOL wa ret = WAIT_TIMEOUT; goto WaitCompleted; } - else - { - millis -= (DWORD)(dwEnd - dwStart); - } + + millis -= (DWORD)(dwEnd - dwStart); + dwStart = dwEnd; } goto retry; } @@ -3421,18 +3418,17 @@ DWORD Thread::DoAppropriateWaitWorker(int countHandles, HANDLE *handles, BOOL wa // Compute the new timeout value by assume that the timeout // is not large enough for more than one wrap - dwEnd = minipal_lowres_ticks(); if (millis != INFINITE) { + dwEnd = minipal_lowres_ticks(); if (dwEnd - dwStart >= millis) { ret = WAIT_TIMEOUT; goto WaitCompleted; } - else - { - millis -= (DWORD)(dwEnd - dwStart); - } + + millis -= (DWORD)(dwEnd - dwStart); + dwStart = dwEnd; } goto retry; } @@ -3574,11 +3570,9 @@ DWORD Thread::DoSignalAndWaitWorker(HANDLE* pHandles, DWORD millis,BOOL alertabl ret = WAIT_TIMEOUT; goto WaitCompleted; } - else - { - millis -= (DWORD)(dwEnd - dwStart); - } - dwStart = minipal_lowres_ticks(); + + millis -= (DWORD)(dwEnd - dwStart); + dwStart = dwEnd; } //Retry case we don't want to signal again so only do the wait... ret = WaitForSingleObjectEx(pHandles[1],millis,TRUE); @@ -6047,11 +6041,13 @@ BOOL Thread::SetStackLimits(SetStackLimitScope scope) { m_CacheStackBase = GetStackUpperBound(); m_CacheStackLimit = GetStackLowerBound(); +#if !defined(TARGET_WASM) // WASM-TODO: stack can start at address 0 on wasm/emscripten and usually does in Debug builds if (m_CacheStackLimit == NULL) { _ASSERTE(!"Failed to set stack limits"); return FALSE; } +#endif // Compute the limit used by TryEnsureSufficientExecutionStack and cache it on the thread. This minimum stack size should // be sufficient to allow a typical non-recursive call chain to execute, including potential exception handling and @@ -6133,24 +6129,15 @@ HRESULT Thread::CLRSetThreadStackGuarantee(SetThreadStackGuaranteeScope fScope) // -additionally, we need to provide some region to hosts to allow for lock acquisition in a hosted scenario // EXTRA_PAGES = 3; - INDEBUG(EXTRA_PAGES += 1); - - int ThreadGuardPages = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_ThreadGuardPages); - if (ThreadGuardPages == 0) - { - uGuardSize += (EXTRA_PAGES * GetOsPageSize()); - } - else - { - uGuardSize += (ThreadGuardPages * GetOsPageSize()); - } - #else // HOST_64BIT -#ifdef _DEBUG - uGuardSize += (1 * GetOsPageSize()); // one extra page for debug infrastructure -#endif // _DEBUG + EXTRA_PAGES = 1; #endif // HOST_64BIT + INDEBUG(EXTRA_PAGES += 1); + + int ThreadGuardPages = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_ThreadGuardPages, EXTRA_PAGES); + uGuardSize += (ThreadGuardPages * GetOsPageSize()); + LOG((LF_EH, LL_INFO10000, "STACKOVERFLOW: setting thread stack guarantee to 0x%x\n", uGuardSize)); if (!::SetThreadStackGuarantee(&uGuardSize)) @@ -6788,72 +6775,6 @@ T_CONTEXT *Thread::GetFilterContext(void) #ifndef DACCESS_COMPILE -void Thread::ClearContext() -{ - CONTRACTL { - NOTHROW; - if (GetThreadNULLOk()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);} - } - CONTRACTL_END; -#ifdef FEATURE_COMINTEROP - m_fDisableComObjectEagerCleanup = false; -#endif //FEATURE_COMINTEROP -} - -BOOL Thread::HaveExtraWorkForFinalizer() -{ - LIMITED_METHOD_CONTRACT; - - return RequireSyncBlockCleanup() - || Thread::CleanupNeededForFinalizedThread() - || (m_DetachCount > 0) - || SystemDomain::System()->RequireAppDomainCleanup() - || YieldProcessorNormalization::IsMeasurementScheduled() - || ThreadStore::s_pThreadStore->ShouldTriggerGCForDeadThreads(); -} - -void Thread::DoExtraWorkForFinalizer() -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - } - CONTRACTL_END; - - _ASSERTE(GetThread() == this); - _ASSERTE(this == FinalizerThread::GetFinalizerThread()); - -#ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT - if (RequiresCoInitialize()) - { - SetApartment(AS_InMTA); - } -#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT - - if (RequireSyncBlockCleanup()) - { - SyncBlockCache::GetSyncBlockCache()->CleanupSyncBlocks(); - } - if (SystemDomain::System()->RequireAppDomainCleanup()) - { - SystemDomain::System()->ProcessDelayedUnloadLoaderAllocators(); - } - - if(m_DetachCount > 0 || Thread::CleanupNeededForFinalizedThread()) - { - Thread::CleanupDetachedThreads(); - } - - if (YieldProcessorNormalization::IsMeasurementScheduled()) - { - GCX_PREEMP(); - YieldProcessorNormalization::PerformMeasurement(); - } - - ThreadStore::s_pThreadStore->TriggerGCForDeadThreadsIfNecessary(); -} - - // HELPERS FOR THE BASE OF A MANAGED THREAD, INCLUDING AD TRANSITION SUPPORT // We have numerous places where we start up a managed thread. This includes several places in the diff --git a/src/coreclr/vm/threads.h b/src/coreclr/vm/threads.h index 3397b50a9315ec..d50b680f4862e4 100644 --- a/src/coreclr/vm/threads.h +++ b/src/coreclr/vm/threads.h @@ -126,7 +126,7 @@ class ThreadStore; class MethodDesc; struct PendingSync; class AppDomain; -class NDirect; +class PInvoke; class Frame; class ThreadBaseObject; class AppDomainStack; @@ -162,7 +162,7 @@ class Module; // TailCallArgBuffer states #define TAILCALLARGBUFFER_ACTIVE 0 #define TAILCALLARGBUFFER_INSTARG_ONLY 1 -#define TAILCALLARGBUFFER_ABANDONED 2 +#define TAILCALLARGBUFFER_INACTIVE 2 struct TailCallArgBuffer { @@ -414,7 +414,7 @@ class TailCallTls public: TailCallTls(); - TailCallArgBuffer* AllocArgBuffer(int size, void* gcDesc); + TailCallArgBuffer* AllocArgBuffer(int size); void FreeArgBuffer() { delete[] (BYTE*)m_argBuffer; m_argBuffer = NULL; } TailCallArgBuffer* GetArgBuffer() { @@ -642,7 +642,7 @@ class Thread // effort. // // Once we are completely independent of the OS UEF, we could remove this. - TSNC_UnhandledException2ndPass = 0x02000000, // The unhandled exception propagation is in the 2nd pass + TSNC_SkipManagedPersonalityRoutine = 0x02000000, // Ignore the ProcessCLRException calls when propagating exception to external native code TSNC_DebuggerSleepWaitJoin = 0x04000000, // Indicates to the debugger that this thread is in a sleep wait or join state // This almost mirrors the TS_Interruptible state however that flag can change // during GC-preemptive mode whereas this one cannot. @@ -837,12 +837,6 @@ class Thread } #endif // !DACCESS_COMPILE - // returns if there is some extra work for the finalizer thread. - BOOL HaveExtraWorkForFinalizer(); - - // do the extra finalizer work. - void DoExtraWorkForFinalizer(); - #ifndef DACCESS_COMPILE DWORD CatchAtSafePoint() { @@ -1569,10 +1563,6 @@ class Thread return PTR_ThreadExceptionState(PTR_HOST_MEMBER_TADDR(Thread, this, m_ExceptionState)); } -private: - // ClearContext are to be called only during shutdown - void ClearContext(); - public: //--------------------------------------------------------------- @@ -3956,6 +3946,7 @@ struct cdac_data static constexpr size_t ExposedObject = offsetof(Thread, m_ExposedObject); static constexpr size_t LastThrownObject = offsetof(Thread, m_LastThrownObjectHandle); static constexpr size_t Link = offsetof(Thread, m_Link); + static constexpr size_t ThreadLocalDataPtr = offsetof(Thread, m_ThreadLocalDataPtr); static_assert(std::is_same().m_ExceptionState), ThreadExceptionState>::value, "Thread::m_ExceptionState is of type ThreadExceptionState"); @@ -4400,7 +4391,17 @@ class IdDispenser _ASSERTE(result == NULL || (dac_cast(result) & 0x3) == 0 || ((Thread*)result)->GetThreadId() == id); return result; } + + friend struct ::cdac_data; }; + +template<> +struct cdac_data +{ + static constexpr size_t IdToThread = offsetof(IdDispenser, m_idToThread); + static constexpr size_t HighestId = offsetof(IdDispenser, m_highestId); +}; + typedef DPTR(IdDispenser) PTR_IdDispenser; @@ -5155,17 +5156,24 @@ class CoopTransitionHolder { Frame * m_pFrame; +#ifdef DEBUG + int m_uncaughtExceptions; +#endif + public: CoopTransitionHolder(Thread * pThread) : m_pFrame(pThread->m_pFrame) { LIMITED_METHOD_CONTRACT; +#ifdef DEBUG + m_uncaughtExceptions = std::uncaught_exceptions(); +#endif } ~CoopTransitionHolder() { WRAPPER_NO_CONTRACT; - _ASSERTE_MSG(m_pFrame == nullptr || std::uncaught_exception(), "Early return from JIT/EE interface method"); + _ASSERTE_MSG(m_pFrame == nullptr || m_uncaughtExceptions < std::uncaught_exceptions(), "Early return from JIT/EE interface method"); if (m_pFrame != nullptr) COMPlusCooperativeTransitionHandler(m_pFrame); } diff --git a/src/coreclr/vm/threads.inl b/src/coreclr/vm/threads.inl index 1cf28d27c6dc42..ada63f848853fa 100644 --- a/src/coreclr/vm/threads.inl +++ b/src/coreclr/vm/threads.inl @@ -45,7 +45,7 @@ inline Thread* GetThread() return pThread; } -EXTERN_C inline AppDomain* STDCALL GetAppDomain() +inline AppDomain* GetAppDomain() { return AppDomain::GetCurrentDomain(); } diff --git a/src/coreclr/vm/threadstatics.cpp b/src/coreclr/vm/threadstatics.cpp index 8c2f7e9588226e..5847cc5c13bb47 100644 --- a/src/coreclr/vm/threadstatics.cpp +++ b/src/coreclr/vm/threadstatics.cpp @@ -3,22 +3,16 @@ #include "common.h" #include "threadstatics.h" -struct InFlightTLSData -{ #ifndef DACCESS_COMPILE - InFlightTLSData(TLSIndex index) : pNext(NULL), tlsIndex(index), hTLSData(0) { } - ~InFlightTLSData() +InFlightTLSData::InFlightTLSData(TLSIndex index) : pNext(NULL), tlsIndex(index), hTLSData(0) { } +InFlightTLSData::~InFlightTLSData() { if (!IsHandleNullUnchecked(hTLSData)) { DestroyTypedHandle(hTLSData); } } -#endif // !DACCESS_COMPILE - PTR_InFlightTLSData pNext; // Points at the next in-flight TLS data - TLSIndex tlsIndex; // The TLS index for the static - OBJECTHANDLE hTLSData; // The TLS data for the static -}; +#endif struct ThreadLocalLoaderAllocator diff --git a/src/coreclr/vm/threadstatics.h b/src/coreclr/vm/threadstatics.h index b114555982de46..54fd6c5984277b 100644 --- a/src/coreclr/vm/threadstatics.h +++ b/src/coreclr/vm/threadstatics.h @@ -67,6 +67,16 @@ struct TLSIndex // Used to store access to TLS data for a single index when the TLS is accessed while the class constructor is running struct InFlightTLSData; typedef DPTR(InFlightTLSData) PTR_InFlightTLSData; +struct InFlightTLSData +{ +#ifndef DACCESS_COMPILE + InFlightTLSData(TLSIndex index); + ~InFlightTLSData(); +#endif // !DACCESS_COMPILE + PTR_InFlightTLSData pNext; // Points at the next in-flight TLS data + TLSIndex tlsIndex; // The TLS index for the static + OBJECTHANDLE hTLSData; // The TLS data for the static +}; #define EXTENDED_DIRECT_THREAD_LOCAL_SIZE 48 diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp index 4aa8e67d478bc5..1411e56ff39e7f 100644 --- a/src/coreclr/vm/threadsuspend.cpp +++ b/src/coreclr/vm/threadsuspend.cpp @@ -14,6 +14,7 @@ #include "finalizerthread.h" #include "dbginterface.h" +#include #include #ifdef FEATURE_EH_FUNCLETS @@ -802,7 +803,7 @@ StackWalkAction TAStackCrawlCallBack(CrawlFrame* pCf, void* data) else { MethodDesc *pMD = pCf->GetFunction(); - if (pCf->GetFrame() != NULL && pMD != NULL && (pMD->IsNDirect() || pMD->IsCLRToCOMCall())) + if (pCf->GetFrame() != NULL && pMD != NULL && (pMD->IsPInvoke() || pMD->IsCLRToCOMCall())) { // This may be interop method of an interesting interop call - latch it. frameAction = LatchCurrentFrame; @@ -2303,11 +2304,7 @@ void Thread::HandleThreadAbort () exceptObj = CLRException::GetThrowableFromException(&eeExcept); } -#ifdef FEATURE_EH_FUNCLETS - DispatchManagedException(exceptObj); -#else // FEATURE_EH_FUNCLETS RaiseTheExceptionInternalOnly(exceptObj, FALSE); -#endif // FEATURE_EH_FUNCLETS } ::SetLastError(lastError); @@ -3314,7 +3311,7 @@ void ThreadSuspend::SuspendAllThreads() // - we get a reliable reading of the threads' m_fPreemptiveGCDisabled state // - other threads see that g_TrapReturningThreads is set // See VSW 475315 and 488918 for details. - ::FlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); int prevRemaining = INT32_MAX; bool observeOnly = true; @@ -3385,7 +3382,7 @@ void ThreadSuspend::SuspendAllThreads() // This is needed to synchronize threads that were running in preemptive mode thus were // left alone by suspension to flush their writes that they made before they switched to // preemptive mode. - ::FlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); #endif //TARGET_ARM || TARGET_ARM64 STRESS_LOG0(LF_SYNC, LL_INFO1000, "Thread::SuspendAllThreads() - Success\n"); @@ -3610,7 +3607,7 @@ void ThreadSuspend::ResumeAllThreads(BOOL SuspendSucceeded) // This is needed to synchronize threads that were running in preemptive mode while // the runtime was suspended and that will return to cooperative mode after the runtime // is restarted. - ::FlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); #endif //TARGET_ARM || TARGET_ARM64 // @@ -5392,7 +5389,7 @@ void ThreadSuspend::RestartEE(BOOL bFinishedGC, BOOL SuspendSucceeded) // This is needed to synchronize threads that were running in preemptive mode while // the runtime was suspended and that will return to cooperative mode after the runtime // is restarted. - ::FlushProcessWriteBuffers(); + minipal_memory_barrier_process_wide(); #endif //TARGET_ARM || TARGET_ARM64 // diff --git a/src/coreclr/vm/typestring.cpp b/src/coreclr/vm/typestring.cpp index c42ad58ac47417..4321492601e3f7 100644 --- a/src/coreclr/vm/typestring.cpp +++ b/src/coreclr/vm/typestring.cpp @@ -577,7 +577,7 @@ void TypeString::AppendNestedTypeDef(TypeNameBuilder& tnb, IMDInternalImport *pI // Append a square-bracket-enclosed, comma-separated list of n type parameters in inst to the string s // and enclose each parameter in square brackets to disambiguate the commas -// The following flags in the FormatFlags argument are significant: FormatNamespace FormatFullInst FormatAssembly FormatNoVersion +// The following flags in the FormatFlags argument are significant: FormatNamespace FormatFullInst FormatAssembly void TypeString::AppendInst(SString& ss, Instantiation inst, DWORD format) { CONTRACT_VOID @@ -668,9 +668,8 @@ void TypeString::AppendParamTypeQualifier(TypeNameBuilder& tnb, CorElementType k } } -// Append a representation of the type t to the string s -// The following flags in the FormatFlags argument are significant: FormatNamespace FormatFullInst FormatAssembly FormatNoVersion - +// Append a representation of the type to the string +// The following flags in the FormatFlags argument are significant: FormatNamespace FormatFullInst FormatAssembly void TypeString::AppendType(SString& ss, TypeHandle ty, DWORD format) { CONTRACT_VOID @@ -875,9 +874,7 @@ void TypeString::AppendType(TypeNameBuilder& tnb, TypeHandle ty, Instantiation t #ifdef DACCESS_COMPILE pAssemblyName.SetUTF8(pAssembly->GetSimpleName()); #else - pAssembly->GetDisplayName(pAssemblyName, - ASM_DISPLAYF_PUBLIC_KEY_TOKEN | ASM_DISPLAYF_CONTENT_TYPE | - (format & FormatNoVersion ? 0 : ASM_DISPLAYF_VERSION | ASM_DISPLAYF_CULTURE)); + pAssembly->GetDisplayName(pAssemblyName, ASM_DISPLAYF_FULL); #endif tnb.AddAssemblySpec(pAssemblyName.GetUnicode()); @@ -1184,9 +1181,7 @@ void TypeString::AppendTypeKey(TypeNameBuilder& tnb, const TypeKey *pTypeKey, DW #ifdef DACCESS_COMPILE pAssemblyName.SetUTF8(pAssembly->GetSimpleName()); #else - pAssembly->GetDisplayName(pAssemblyName, - ASM_DISPLAYF_PUBLIC_KEY_TOKEN | ASM_DISPLAYF_CONTENT_TYPE | - (format & FormatNoVersion ? 0 : ASM_DISPLAYF_VERSION | ASM_DISPLAYF_CULTURE)); + pAssembly->GetDisplayName(pAssemblyName, ASM_DISPLAYF_FULL); #endif tnb.AddAssemblySpec(pAssemblyName.GetUnicode()); } diff --git a/src/coreclr/vm/typestring.h b/src/coreclr/vm/typestring.h index f3bd23bfc6707b..c8706144c6ebe0 100644 --- a/src/coreclr/vm/typestring.h +++ b/src/coreclr/vm/typestring.h @@ -148,7 +148,7 @@ class TypeString FormatFullInst = 0x00000002, // Include namespace and assembly in generic types (regardless of other flag settings) FormatAssembly = 0x00000004, // Include assembly display name in type names FormatSignature = 0x00000008, // Include signature in method names - FormatNoVersion = 0x00000010, // Suppress version and culture information in all assembly names + // unused = 0x00000010, #ifdef _DEBUG FormatDebug = 0x00000020, // For debug printing of types only #endif @@ -165,11 +165,11 @@ class TypeString // Append a square-bracket-enclosed, comma-separated list of n type parameters in inst to the string s // and enclose each parameter in square brackets to disambiguate the commas - // The following flags in the FormatFlags argument are significant: FormatNamespace FormatFullInst FormatAssembly FormatNoVersion + // The following flags in the FormatFlags argument are significant: FormatNamespace FormatFullInst FormatAssembly static void AppendInst(SString& s, Instantiation inst, DWORD format = FormatNamespace); // Append a representation of the type t to the string s - // The following flags in the FormatFlags argument are significant: FormatNamespace FormatFullInst FormatAssembly FormatNoVersion + // The following flags in the FormatFlags argument are significant: FormatNamespace FormatFullInst FormatAssembly static void AppendType(SString& s, TypeHandle t, DWORD format = FormatNamespace); // Append a representation of the type t to the string s, using the generic @@ -183,7 +183,7 @@ class TypeString static void AppendMethod(SString& s, MethodDesc *pMD, Instantiation typeInstantiation, const DWORD format = FormatNamespace|FormatSignature); // Append a representation of the method m to the string s - // The following flags in the FormatFlags argument are significant: FormatNamespace FormatFullInst FormatAssembly FormatSignature FormatNoVersion + // The following flags in the FormatFlags argument are significant: FormatNamespace FormatFullInst FormatAssembly FormatSignature static void AppendMethodInternal(SString& s, MethodDesc *pMD, const DWORD format); // Append the field name and generic instantiation info. diff --git a/src/coreclr/vm/unsafeaccessors.cpp b/src/coreclr/vm/unsafeaccessors.cpp index 31d4e3aff0e1b8..6b039f780ec629 100644 --- a/src/coreclr/vm/unsafeaccessors.cpp +++ b/src/coreclr/vm/unsafeaccessors.cpp @@ -1019,7 +1019,7 @@ bool MethodDesc::TryGenerateUnsafeAccessor(DynamicResolver** resolver, COR_ILMET _ASSERTE(methodILDecoder != NULL); _ASSERTE(*resolver == NULL && *methodILDecoder == NULL); _ASSERTE(IsIL()); - _ASSERTE(GetRVA() == 0); + _ASSERTE(!HasILHeader()); // The UnsafeAccessorAttribute is applied to methods with an // RVA of 0 (for example, C#'s extern keyword). diff --git a/src/coreclr/vm/util.cpp b/src/coreclr/vm/util.cpp index fdf8dc33e33a29..1b3499bdfe0f27 100644 --- a/src/coreclr/vm/util.cpp +++ b/src/coreclr/vm/util.cpp @@ -166,6 +166,7 @@ bool operator ==(const ICorDebugInfo::VarLoc &varLoc1, switch(varLoc1.vlType) { case ICorDebugInfo::VLT_REG: + case ICorDebugInfo::VLT_REG_FP: case ICorDebugInfo::VLT_REG_BYREF: return varLoc1.vlReg.vlrReg == varLoc2.vlReg.vlrReg; @@ -195,6 +196,9 @@ bool operator ==(const ICorDebugInfo::VarLoc &varLoc1, case ICorDebugInfo::VLT_FPSTK: return varLoc1.vlFPstk.vlfReg == varLoc2.vlFPstk.vlfReg; + case ICorDebugInfo::VLT_FIXED_VA: + return varLoc1.vlFixedVarArg.vlfvOffset == varLoc2.vlFixedVarArg.vlfvOffset; + default: _ASSERTE(!"Bad vlType"); return false; } diff --git a/src/coreclr/vm/vars.cpp b/src/coreclr/vm/vars.cpp index 7b527e70c29ff3..31fc88e6005bf0 100644 --- a/src/coreclr/vm/vars.cpp +++ b/src/coreclr/vm/vars.cpp @@ -93,6 +93,7 @@ GPTR_IMPL(RCWCleanupList,g_pRCWCleanupList); GVAL_IMPL_INIT(DWORD, g_debuggerWordTLSIndex, TLS_OUT_OF_INDEXES); #endif GVAL_IMPL_INIT(DWORD, g_TlsIndex, TLS_OUT_OF_INDEXES); +GVAL_IMPL_INIT(DWORD, g_offsetOfCurrentThreadInfo, 0); MethodTable* g_pCastHelpers; #ifdef FEATURE_EH_FUNCLETS diff --git a/src/coreclr/vm/vars.hpp b/src/coreclr/vm/vars.hpp index b846b25bdb20a1..9e98fbb87cb999 100644 --- a/src/coreclr/vm/vars.hpp +++ b/src/coreclr/vm/vars.hpp @@ -356,6 +356,7 @@ GPTR_DECL(MethodDesc, g_pObjectFinalizerMD); GVAL_DECL(DWORD, g_debuggerWordTLSIndex); #endif GVAL_DECL(DWORD, g_TlsIndex); +GVAL_DECL(DWORD, g_offsetOfCurrentThreadInfo); #ifdef FEATURE_EH_FUNCLETS GPTR_DECL(MethodTable, g_pEHClass); diff --git a/src/coreclr/vm/versionresilienthashcode.cpp b/src/coreclr/vm/versionresilienthashcode.cpp index 005bda437f8342..ad090be540c7bc 100644 --- a/src/coreclr/vm/versionresilienthashcode.cpp +++ b/src/coreclr/vm/versionresilienthashcode.cpp @@ -368,6 +368,7 @@ bool GetVersionResilientILCodeHashCode(MethodDesc *pMD, int* hashCode, unsigned* { uint32_t maxStack; uint32_t EHCount; + COR_ILMETHOD* pILHeader; const BYTE* pILCode; uint32_t cbILCode; bool initLocals; @@ -388,15 +389,9 @@ bool GetVersionResilientILCodeHashCode(MethodDesc *pMD, int* hashCode, unsigned* initLocals = (options & CORINFO_OPT_INIT_LOCALS) == CORINFO_OPT_INIT_LOCALS; } - else if (!pMD->HasILHeader()) + else if (pMD->MayHaveILHeader() && (pILHeader = pMD->GetILHeader()) != NULL) { - // Dynamically generated IL methods like UnsafeAccessors may not have - // an IL header. - return false; - } - else - { - COR_ILMETHOD_DECODER header(pMD->GetILHeader(), pMD->GetMDImport(), NULL); + COR_ILMETHOD_DECODER header(pILHeader, pMD->GetMDImport(), NULL); pILCode = header.Code; cbILCode = header.GetCodeSize(); @@ -422,6 +417,11 @@ bool GetVersionResilientILCodeHashCode(MethodDesc *pMD, int* hashCode, unsigned* // Do not hash the classToken field, as is possibly token dependent } } + else + { + // Dynamically generated IL methods like UnsafeAccessors are not handled yet. + return false; + } hashILData.Add(maxStack); hashILData.Add(EHCount); diff --git a/src/coreclr/vm/virtualcallstub.cpp b/src/coreclr/vm/virtualcallstub.cpp index bf937b052ba6d0..41edef935b716e 100644 --- a/src/coreclr/vm/virtualcallstub.cpp +++ b/src/coreclr/vm/virtualcallstub.cpp @@ -2322,11 +2322,6 @@ VirtualCallStubManager::Resolver( BOOL fSlotCallsPrestub = DoesSlotCallPrestub(implSlot.GetTarget()); if (!fSlotCallsPrestub) { - // Skip fixup precode jump for better perf - PCODE pDirectTarget = Precode::TryToSkipFixupPrecode(implSlot.GetTarget()); - if (pDirectTarget != (PCODE)NULL) - implSlot = DispatchSlot(pDirectTarget); - // Only patch to a target if it's not going to call the prestub. fShouldPatch = TRUE; } diff --git a/src/coreclr/vm/wasm/calldescrworkerwasm.cpp b/src/coreclr/vm/wasm/calldescrworkerwasm.cpp new file mode 100644 index 00000000000000..afbf3e07ff7913 --- /dev/null +++ b/src/coreclr/vm/wasm/calldescrworkerwasm.cpp @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// + +#include + +extern "C" void* STDCALL ExecuteInterpretedMethodWithArgs(TransitionBlock* pTransitionBlock, TADDR byteCodeAddr, int8_t* pArgs, size_t size, void* retBuff); + +extern "C" void STDCALL CallDescrWorkerInternal(CallDescrData * pCallDescrData) +{ + MethodDesc* pMethod = pCallDescrData->pMD; + InterpByteCodeStart* targetIp = pMethod->GetInterpreterCode(); + if (targetIp == NULL) + { + GCX_PREEMP(); + pMethod->PrepareInitialCode(CallerGCMode::Coop); + targetIp = pMethod->GetInterpreterCode(); + } + + ExecuteInterpretedMethodWithArgs(pCallDescrData->pTransitionBlock, (TADDR)targetIp, (int8_t*)pCallDescrData->pSrc, pCallDescrData->nArgsSize, pCallDescrData->returnValue); +} diff --git a/src/coreclr/vm/wasm/cgencpu.h b/src/coreclr/vm/wasm/cgencpu.h index 2093a7a80a5499..975f892a17f1f1 100644 --- a/src/coreclr/vm/wasm/cgencpu.h +++ b/src/coreclr/vm/wasm/cgencpu.h @@ -15,7 +15,7 @@ #define LOG2SLOT LOG2_PTRSIZE // looks like this is mandatory for now -#define HAS_NDIRECT_IMPORT_PRECODE 1 +#define HAS_PINVOKE_IMPORT_PRECODE 1 #define HAS_FIXUP_PRECODE 1 // ThisPtrRetBufPrecode one is necessary for closed delegates over static methods with return buffer #define HAS_THISPTR_RETBUF_PRECODE 1 @@ -85,9 +85,13 @@ struct ArgumentRegisters { class StubLinkerCPU : public StubLinker { public: - static void Init(); - void EmitShuffleThunk(struct ShuffleEntry *pShuffleEntryArray); - VOID EmitComputedInstantiatingMethodStub(MethodDesc* pSharedMD, struct ShuffleEntry *pShuffleEntryArray, void* extraArg); + static void Init() { /* no-op on wasm */ } + inline void EmitShuffleThunk(struct ShuffleEntry *pShuffleEntryArray) { + _ASSERTE("The EmitShuffleThunk is not implemented on wasm"); + } + inline VOID EmitComputedInstantiatingMethodStub(MethodDesc* pSharedMD, struct ShuffleEntry *pShuffleEntryArray, void* extraArg) { + _ASSERTE("The EmitComputedInstantiatingMethodStub is not implemented on wasm"); + } }; //********************************************************************** @@ -162,4 +166,26 @@ FORCEINLINE int64_t PalInterlockedCompareExchange64(_Inout_ int64_t volatile *pD return result; } +inline void SetFirstArgReg(T_CONTEXT *context, TADDR value) +{ + PORTABILITY_ASSERT("SetFirstArgReg is not implemented on wasm"); +} + +inline TADDR GetFirstArgReg(T_CONTEXT *context) +{ + PORTABILITY_ASSERT("GetFirstArgReg is not implemented on wasm"); + return 0; +} + +inline void SetSecondArgReg(T_CONTEXT *context, TADDR value) +{ + PORTABILITY_ASSERT("SetSecondArgReg is not implemented on wasm"); +} + +inline TADDR GetSecondArgReg(T_CONTEXT *context) +{ + PORTABILITY_ASSERT("GetSecondArgReg is not implemented on wasm"); + return 0; +} + #endif // __cgenwasm_h__ diff --git a/src/coreclr/vm/wasm/excepcpu.h b/src/coreclr/vm/wasm/excepcpu.h index 7ca5a994a60760..bb819cae090f5d 100644 --- a/src/coreclr/vm/wasm/excepcpu.h +++ b/src/coreclr/vm/wasm/excepcpu.h @@ -29,6 +29,9 @@ PCODE GetAdjustedCallAddress(PCODE returnAddress) return returnAddress; } -BOOL AdjustContextForVirtualStub(EXCEPTION_RECORD *pExceptionRecord, T_CONTEXT *pContext); +inline BOOL AdjustContextForVirtualStub(EXCEPTION_RECORD *pExceptionRecord, T_CONTEXT *pContext) { + _ASSERTE("AdjustContextForVirtualStub is not implemented on wasm"); + return FALSE; +} #endif // __excepcpu_h__ diff --git a/src/coreclr/vm/wasm/helpers.cpp b/src/coreclr/vm/wasm/helpers.cpp new file mode 100644 index 00000000000000..ac2298f34837a1 --- /dev/null +++ b/src/coreclr/vm/wasm/helpers.cpp @@ -0,0 +1,494 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// + +extern "C" void STDCALL CallCountingStubCode() +{ + PORTABILITY_ASSERT("CallCountingStubCode is not implemented on wasm"); +} + +extern "C" void CallCountingStubCode_End() +{ + PORTABILITY_ASSERT("CallCountingStubCode_End is not implemented on wasm"); +} + +extern "C" void STDCALL OnCallCountThresholdReachedStub() +{ + PORTABILITY_ASSERT("OnCallCountThresholdReachedStub is not implemented on wasm"); +} + +extern "C" void STDCALL ThePreStub() +{ + PORTABILITY_ASSERT("ThePreStub is not implemented on wasm"); +} + +extern "C" void InterpreterStub() +{ + PORTABILITY_ASSERT("InterpreterStub is not implemented on wasm"); +} + +extern "C" UINT_PTR STDCALL GetCurrentIP(void) +{ + PORTABILITY_ASSERT("GetCurrentIP is not implemented on wasm"); + return 0; +} + +extern "C" void STDMETHODCALLTYPE JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle) +{ + PORTABILITY_ASSERT("JIT_ProfilerEnterLeaveTailcallStub is not implemented on wasm"); +} + +extern "C" void STDCALL DelayLoad_MethodCall() +{ + PORTABILITY_ASSERT("DelayLoad_MethodCall is not implemented on wasm"); +} + +extern "C" void STDCALL DelayLoad_Helper() +{ + PORTABILITY_ASSERT("DelayLoad_Helper is not implemented on wasm"); +} + +extern "C" void STDCALL DelayLoad_Helper_Obj() +{ + PORTABILITY_ASSERT("DelayLoad_Helper_Obj is not implemented on wasm"); +} + +extern "C" void STDCALL DelayLoad_Helper_ObjObj() +{ + PORTABILITY_ASSERT("DelayLoad_Helper_ObjObj is not implemented on wasm"); +} + +extern "C" void STDCALL PInvokeImportThunk() +{ + PORTABILITY_ASSERT("PInvokeImportThunk is not implemented on wasm"); +} + +extern "C" void STDCALL StubPrecodeCode() +{ + PORTABILITY_ASSERT("StubPrecodeCode is not implemented on wasm"); +} + +extern "C" void STDCALL StubPrecodeCode_End() +{ + PORTABILITY_ASSERT("StubPrecodeCode_End is not implemented on wasm"); +} + +extern "C" void STDCALL FixupPrecodeCode() +{ + PORTABILITY_ASSERT("FixupPrecodeCode is not implemented on wasm"); +} + +extern "C" void STDCALL FixupPrecodeCode_End() +{ + PORTABILITY_ASSERT("FixupPrecodeCode_End is not implemented on wasm"); +} + +extern "C" void STDCALL JIT_PatchedCodeLast() +{ + PORTABILITY_ASSERT("JIT_PatchedCodeLast is not implemented on wasm"); +} + +extern "C" void STDCALL JIT_PatchedCodeStart() +{ + PORTABILITY_ASSERT("JIT_PatchedCodeStart is not implemented on wasm"); +} + +extern "C" void RhpInitialInterfaceDispatch() +{ + PORTABILITY_ASSERT("RhpInitialInterfaceDispatch is not implemented on wasm"); +} + +unsigned FuncEvalFrame::GetFrameAttribs_Impl(void) +{ + PORTABILITY_ASSERT("FuncEvalFrame::GetFrameAttribs_Impl is not implemented on wasm"); + return 0; +} + +TADDR FuncEvalFrame::GetReturnAddressPtr_Impl() +{ + PORTABILITY_ASSERT("FuncEvalFrame::GetReturnAddressPtr_Impl is not implemented on wasm"); + return 0; +} + +void FuncEvalFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats) +{ + PORTABILITY_ASSERT("FuncEvalFrame::UpdateRegDisplay_Impl is not implemented on wasm"); +} + +void InlinedCallFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats) +{ + PORTABILITY_ASSERT("InlinedCallFrame::UpdateRegDisplay_Impl is not implemented on wasm"); +} + +void FaultingExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats) +{ + PORTABILITY_ASSERT("FaultingExceptionFrame::UpdateRegDisplay_Impl is not implemented on wasm"); +} + +void TransitionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats) +{ + PORTABILITY_ASSERT("TransitionFrame::UpdateRegDisplay_Impl is not implemented on wasm"); +} + +size_t CallDescrWorkerInternalReturnAddressOffset; + +VOID PALAPI RtlRestoreContext(IN PCONTEXT ContextRecord, IN PEXCEPTION_RECORD ExceptionRecord) +{ + PORTABILITY_ASSERT("RtlRestoreContext is not implemented on wasm"); +} + +extern "C" void TheUMEntryPrestub(void) +{ + PORTABILITY_ASSERT("TheUMEntryPrestub is not implemented on wasm"); +} + +extern "C" void STDCALL VarargPInvokeStub(void) +{ + PORTABILITY_ASSERT("VarargPInvokeStub is not implemented on wasm"); +} + +extern "C" void STDCALL VarargPInvokeStub_RetBuffArg(void) +{ + PORTABILITY_ASSERT("VarargPInvokeStub_RetBuffArg is not implemented on wasm"); +} + +extern "C" PCODE CID_VirtualOpenDelegateDispatch(TransitionBlock * pTransitionBlock) +{ + PORTABILITY_ASSERT("CID_VirtualOpenDelegateDispatch is not implemented on wasm"); + return 0; +} + +extern "C" FCDECL2(VOID, JIT_WriteBarrier_Callable, Object **dst, Object *ref) +{ + PORTABILITY_ASSERT("JIT_WriteBarrier_Callable is not implemented on wasm"); +} + +EXTERN_C void JIT_WriteBarrier_End() +{ + PORTABILITY_ASSERT("JIT_WriteBarrier_End is not implemented on wasm"); +} + +EXTERN_C void JIT_CheckedWriteBarrier_End() +{ + PORTABILITY_ASSERT("JIT_CheckedWriteBarrier_End is not implemented on wasm"); +} + +EXTERN_C void JIT_ByRefWriteBarrier_End() +{ + PORTABILITY_ASSERT("JIT_ByRefWriteBarrier_End is not implemented on wasm"); +} + +EXTERN_C void JIT_StackProbe_End() +{ + PORTABILITY_ASSERT("JIT_StackProbe_End is not implemented on wasm"); +} + +EXTERN_C VOID STDCALL ResetCurrentContext() +{ + PORTABILITY_ASSERT("ResetCurrentContext is not implemented on wasm"); +} + +extern "C" void STDCALL GenericPInvokeCalliHelper(void) +{ + PORTABILITY_ASSERT("GenericPInvokeCalliHelper is not implemented on wasm"); +} + +EXTERN_C void JIT_PInvokeBegin(InlinedCallFrame* pFrame) +{ + PORTABILITY_ASSERT("JIT_PInvokeBegin is not implemented on wasm"); +} + +EXTERN_C void JIT_PInvokeEnd(InlinedCallFrame* pFrame) +{ + PORTABILITY_ASSERT("JIT_PInvokeEnd is not implemented on wasm"); +} + +extern "C" void STDCALL JIT_StackProbe() +{ + PORTABILITY_ASSERT("JIT_StackProbe is not implemented on wasm"); +} + +EXTERN_C FCDECL0(void, JIT_PollGC) +{ + PORTABILITY_ASSERT("JIT_PollGC is not implemented on wasm"); +} + +extern "C" FCDECL2(VOID, JIT_WriteBarrier, Object **dst, Object *ref) +{ + PORTABILITY_ASSERT("JIT_WriteBarrier is not implemented on wasm"); +} + +extern "C" FCDECL2(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref) +{ + PORTABILITY_ASSERT("JIT_CheckedWriteBarrier is not implemented on wasm"); +} + +extern "C" void STDCALL JIT_ByRefWriteBarrier() +{ + PORTABILITY_ASSERT("JIT_ByRefWriteBarrier is not implemented on wasm"); +} + +void InitJITHelpers1() +{ + /* no-op WASM-TODO do we need to do anything for the interpreter? */ +} + +extern "C" HRESULT __cdecl CorDBGetInterface(DebugInterface** rcInterface) +{ + PORTABILITY_ASSERT("CorDBGetInterface is not implemented on wasm"); + return 0; +} + +extern "C" void RhpInterfaceDispatch1() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatch1 is not implemented on wasm"); +} + +extern "C" void RhpInterfaceDispatch2() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatch2 is not implemented on wasm"); +} + +extern "C" void RhpInterfaceDispatch4() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatch4 is not implemented on wasm"); +} + +extern "C" void RhpInterfaceDispatch8() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatch8 is not implemented on wasm"); +} + +extern "C" void RhpInterfaceDispatch16() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatch16 is not implemented on wasm"); +} + +extern "C" void RhpInterfaceDispatch32() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatch32 is not implemented on wasm"); +} + +extern "C" void RhpInterfaceDispatch64() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatch64 is not implemented on wasm"); +} + +extern "C" void RhpVTableOffsetDispatch() +{ + PORTABILITY_ASSERT("RhpVTableOffsetDispatch is not implemented on wasm"); +} + +typedef uint8_t CODE_LOCATION; +CODE_LOCATION RhpAssignRefAVLocation; +CODE_LOCATION RhpCheckedAssignRefAVLocation; +CODE_LOCATION RhpByRefAssignRefAVLocation1; +CODE_LOCATION RhpByRefAssignRefAVLocation2; + +extern "C" void ThisPtrRetBufPrecodeWorker() +{ + PORTABILITY_ASSERT("ThisPtrRetBufPrecodeWorker is not implemented on wasm"); +} + +extern "C" FCDECL2(VOID, RhpAssignRef, Object **dst, Object *ref) +{ + PORTABILITY_ASSERT("RhpAssignRef is not implemented on wasm"); +} + +extern "C" FCDECL2(VOID, RhpCheckedAssignRef, Object **dst, Object *ref) +{ + PORTABILITY_ASSERT("RhpCheckedAssignRef is not implemented on wasm"); +} + +extern "C" FCDECL2(VOID, RhpByRefAssignRef, Object **dst, Object *ref) +{ + PORTABILITY_ASSERT("RhpByRefAssignRef is not implemented on wasm"); +} + +extern "C" void RhpInterfaceDispatchAVLocation1() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatchAVLocation1 is not implemented on wasm"); +} + +extern "C" void RhpInterfaceDispatchAVLocation2() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatchAVLocation2 is not implemented on wasm"); +} + +extern "C" void RhpInterfaceDispatchAVLocation4() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatchAVLocation4 is not implemented on wasm"); +} + +extern "C" void RhpInterfaceDispatchAVLocation8() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatchAVLocation8 is not implemented on wasm"); +} + +extern "C" void RhpInterfaceDispatchAVLocation16() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatchAVLocation16 is not implemented on wasm"); +} + +extern "C" void RhpInterfaceDispatchAVLocation32() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatchAVLocation32 is not implemented on wasm"); +} + +extern "C" void RhpInterfaceDispatchAVLocation64() +{ + PORTABILITY_ASSERT("RhpInterfaceDispatchAVLocation64 is not implemented on wasm"); +} + +extern "C" void RhpVTableOffsetDispatchAVLocation() +{ + PORTABILITY_ASSERT("RhpVTableOffsetDispatchAVLocation is not implemented on wasm"); +} + +EXTERN_C FCDECL2(Object*, RhpNewVariableSizeObject, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size) +{ + PORTABILITY_ASSERT("RhpNewVariableSizeObject is not implemented on wasm"); + return nullptr; +} + +EXTERN_C FCDECL1(Object*, RhpNewMaybeFrozen, CORINFO_CLASS_HANDLE typeHnd_) +{ + PORTABILITY_ASSERT("RhpNewMaybeFrozen is not implemented on wasm"); + return nullptr; +} + +EXTERN_C FCDECL2(Object*, RhpNewArrayFast, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size) +{ + PORTABILITY_ASSERT("RhpNewArrayFast is not implemented on wasm"); + return nullptr; +} + +EXTERN_C FCDECL2(Object*, RhpNewPtrArrayFast, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size) +{ + PORTABILITY_ASSERT("RhpNewPtrArrayFast is not implemented on wasm"); + return nullptr; +} + +EXTERN_C FCDECL2(Object*, RhpNewArrayFastAlign8, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size) +{ + PORTABILITY_ASSERT("RhpNewArrayFastAlign8 is not implemented on wasm"); + return nullptr; +} + +EXTERN_C FCDECL1(Object*, RhpNewFastAlign8, CORINFO_CLASS_HANDLE typeHnd_) +{ + PORTABILITY_ASSERT("RhpNewFastAlign8 is not implemented on wasm"); + return nullptr; +} + +EXTERN_C FCDECL1(Object*, RhpNewFastMisalign, CORINFO_CLASS_HANDLE typeHnd_) +{ + PORTABILITY_ASSERT("RhpNewFastMisalign is not implemented on wasm"); + return nullptr; +} + +EXTERN_C FCDECL1(Object*, RhpNewFast, CORINFO_CLASS_HANDLE typeHnd_) +{ + PORTABILITY_ASSERT("RhpNewFast is not implemented on wasm"); + return nullptr; +} + +EXTERN_C FCDECL1(Object*, RhpNew, CORINFO_CLASS_HANDLE typeHnd_) +{ + PORTABILITY_ASSERT("RhpNew is not implemented on wasm"); + return nullptr; +} + +EXTERN_C FCDECL2(Object*, RhpNewArrayMaybeFrozen, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size) +{ + PORTABILITY_ASSERT("RhpNewArrayMaybeFrozen is not implemented on wasm"); + return nullptr; +} + +EXTERN_C FCDECL2(Object*, RhNewString, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR stringLength) +{ + PORTABILITY_ASSERT("RhNewString is not implemented on wasm"); + return nullptr; +} + +extern "C" void STDCALL ThePreStubPatchLabel(void) +{ + PORTABILITY_ASSERT("ThePreStubPatchLabel is not implemented on wasm"); +} + +LONG CLRNoCatchHandler(EXCEPTION_POINTERS* pExceptionInfo, PVOID pv) +{ + PORTABILITY_ASSERT("CLRNoCatchHandler is not implemented on wasm"); + return EXCEPTION_CONTINUE_SEARCH; +} + +EXTERN_C void STDMETHODCALLTYPE ProfileEnterNaked(FunctionIDOrClientID functionIDOrClientID) +{ + PORTABILITY_ASSERT("ProfileEnterNaked is not implemented on wasm"); +} + +EXTERN_C void STDMETHODCALLTYPE ProfileLeaveNaked(UINT_PTR clientData) +{ + PORTABILITY_ASSERT("ProfileLeaveNaked is not implemented on wasm"); +} + +EXTERN_C void STDMETHODCALLTYPE ProfileTailcallNaked(UINT_PTR clientData) +{ + PORTABILITY_ASSERT("ProfileTailcallNaked is not implemented on wasm"); +} + +void InitJITWriteBarrierHelpers() +{ + // Nothing to do - wasm has static write barriers +} + +int StompWriteBarrierEphemeral(bool isRuntimeSuspended) +{ + // WASM-TODO: implement me + return 0; +} + +int StompWriteBarrierResize(bool isRuntimeSuspended, bool bReqUpperBoundsCheck) +{ + // Nothing to do - wasm has static write barriers + return SWB_PASS; +} + +void FlushWriteBarrierInstructionCache() +{ + // Nothing to do - wasm has static write barriers +} + +EXTERN_C Thread * JIT_InitPInvokeFrame(InlinedCallFrame *pFrame) +{ + PORTABILITY_ASSERT("JIT_InitPInvokeFrame is not implemented on wasm"); + return nullptr; +} + +void _DacGlobals::Initialize() +{ + /* no-op on wasm */ +} + +int g_pDebugger; + +extern "C" int32_t mono_wasm_browser_entropy(uint8_t* buffer, int32_t bufferLength) +{ + PORTABILITY_ASSERT("mono_wasm_browser_entropy is not implemented"); + return -1; +} + +void InvokeCalliStub(PCODE ftn, CallStubHeader *stubHeaderTemplate, int8_t *pArgs, int8_t *pRet) +{ + PORTABILITY_ASSERT("InvokeCalliStub is not implemented on wasm"); +} + +void InvokeCompiledMethod(MethodDesc *pMD, int8_t *pArgs, int8_t *pRet, PCODE target) +{ + PORTABILITY_ASSERT("Attempted to execute non-interpreter code from interpreter on wasm, this is not yet implemented"); +} + +void InvokeDelegateInvokeMethod(MethodDesc *pMDDelegateInvoke, int8_t *pArgs, int8_t *pRet, PCODE target) +{ + PORTABILITY_ASSERT("Attempted to execute non-interpreter code from interpreter on wasm, this is not yet implemented"); +} \ No newline at end of file diff --git a/src/coreclr/vm/wasm/profiler.cpp b/src/coreclr/vm/wasm/profiler.cpp new file mode 100644 index 00000000000000..b4004f1c4c4347 --- /dev/null +++ b/src/coreclr/vm/wasm/profiler.cpp @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "common.h" + +#ifdef PROFILING_SUPPORTED +#include "asmconstants.h" +#include "proftoeeinterfaceimpl.h" + +UINT_PTR ProfileGetIPFromPlatformSpecificHandle(void* pPlatformSpecificHandle) +{ + _ASSERTE(!"ProfileGetIPFromPlatformSpecificHandle is not implemented on wasm"); + return 0; +} + +void ProfileSetFunctionIDInPlatformSpecificHandle(void* pPlatformSpecificHandle, FunctionID functionId) +{ + _ASSERTE(!"ProfileSetFunctionIDInPlatformSpecificHandle is not implemented on wasm"); +} + +ProfileArgIterator::ProfileArgIterator(MetaSig* pSig, void* pPlatformSpecificHandle) + : m_argIterator(pSig) +{ + _ASSERTE(!"ProfileArgIterator constructor is not implemented on wasm"); +} + +ProfileArgIterator::~ProfileArgIterator() +{ + _ASSERTE(!"ProfileArgIterator destructor is not implemented on wasm"); +} + +LPVOID ProfileArgIterator::GetNextArgAddr() +{ + _ASSERTE(!"GetNextArgAddr is not implemented on wasm"); + return nullptr; +} + +LPVOID ProfileArgIterator::GetHiddenArgValue(void) +{ + _ASSERTE(!"GetHiddenArgValue is not implemented on wasm"); + return nullptr; +} + +LPVOID ProfileArgIterator::GetThis(void) +{ + _ASSERTE(!"GetThis is not implemented on wasm"); + return nullptr; +} + +LPVOID ProfileArgIterator::GetReturnBufferAddr(void) +{ + _ASSERTE(!"GetReturnBufferAddr is not implemented on wasm"); + return nullptr; +} + + +#endif // PROFILING_SUPPORTED diff --git a/src/coreclr/vm/zapsig.cpp b/src/coreclr/vm/zapsig.cpp index 6b6ce6c45c1c8b..09d9800df3e143 100644 --- a/src/coreclr/vm/zapsig.cpp +++ b/src/coreclr/vm/zapsig.cpp @@ -953,6 +953,11 @@ MethodDesc *ZapSig::DecodeMethod(ModuleBase *pInfoModule, MemberLoader::ThrowMissingMethodException(constrainedType.GetMethodTable(), NULL, NULL, NULL, 0, NULL); } + if (directMethod->IsStatic() && (ppTH != NULL)) + { + *ppTH = directMethod->GetMethodTable(); + } + // Strip the instantiating stub if the signature did not ask for one if (directMethod->IsInstantiatingStub() && !isInstantiatingStub) { diff --git a/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/Microsoft.DotNet.ILCompiler.pkgproj b/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/Microsoft.DotNet.ILCompiler.pkgproj index bb6d4154b85be1..09f900900e1142 100644 --- a/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/Microsoft.DotNet.ILCompiler.pkgproj +++ b/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/Microsoft.DotNet.ILCompiler.pkgproj @@ -29,48 +29,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + Condition="'$(PackageTargetRuntime)' != ''"> - - - + + <_ILCompilerFilesRoot>$(CoreCLRILCompilerDir) + <_ILCompilerFilesRoot Condition="'$(PackHostILCompiler)' == 'true'">$(CoreCLRCrossILCompilerDir) + - - - + + @@ -93,5 +63,4 @@ - diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props index 1ea9a545581745..44625877c6561d 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -114,6 +114,8 @@ + + diff --git a/src/installer/pkg/sfx/installers/dotnet-host.proj b/src/installer/pkg/sfx/installers/dotnet-host.proj index c4a61a297595c1..64282f8de95808 100644 --- a/src/installer/pkg/sfx/installers/dotnet-host.proj +++ b/src/installer/pkg/sfx/installers/dotnet-host.proj @@ -12,7 +12,11 @@ Dotnet_CLI_SharedHost HostSrc - afterInstallExecute + + + afterInstallInitialize false true sharedhost @@ -26,7 +30,7 @@ - + diff --git a/src/installer/pkg/sfx/installers/host.wxs b/src/installer/pkg/sfx/installers/host.wxs index 322b9038d92939..893520ff557275 100644 --- a/src/installer/pkg/sfx/installers/host.wxs +++ b/src/installer/pkg/sfx/installers/host.wxs @@ -38,12 +38,12 @@ - + - + NOT NON_NATIVE_ARCHITECTURE - + NOT VersionNT64 @@ -51,7 +51,6 @@ - @@ -63,6 +62,7 @@ + @@ -76,6 +76,32 @@ + + + + + + + + + + + + "#1" AND NOT NON_NATIVE_ARCHITECTURE]]> + + + "#1" AND NOT VersionNT64]]> + + + + + + + + "#1"]]> + + + diff --git a/src/installer/tests/AppHost.Bundle.Tests/AppLaunch.cs b/src/installer/tests/AppHost.Bundle.Tests/AppLaunch.cs index c1ccb708ad6719..67179e1577a625 100644 --- a/src/installer/tests/AppHost.Bundle.Tests/AppLaunch.cs +++ b/src/installer/tests/AppHost.Bundle.Tests/AppLaunch.cs @@ -82,6 +82,34 @@ private void RunApp(bool selfContained) } } + [Fact] + private void NonAsciiCharacterSelfContainedApp() + { + // Bundle to a single-file + bool selfContained = true; + string singleFile = sharedTestState.SpecialCharacterSelfContainedApp.Bundle(); + + // Run the bundled app + RunTheApp(singleFile, selfContained); + + if (OperatingSystem.IsMacOS()) + { + string fatApp = MakeUniversalBinary(singleFile, RuntimeInformation.OSArchitecture); + + // Run the fat app + RunTheApp(fatApp, selfContained); + } + + if (OperatingSystem.IsWindows()) + { + // StandaloneApp sets FileVersion to NETCoreApp version. On Windows, this should be copied to singlefilehost resources. + string expectedVersion = TestContext.MicrosoftNETCoreAppVersion.Contains('-') + ? TestContext.MicrosoftNETCoreAppVersion[..TestContext.MicrosoftNETCoreAppVersion.IndexOf('-')] + : TestContext.MicrosoftNETCoreAppVersion; + Assert.Equal(expectedVersion, System.Diagnostics.FileVersionInfo.GetVersionInfo(singleFile).FileVersion); + } + } + [ConditionalTheory(typeof(Binaries.CetCompat), nameof(Binaries.CetCompat.IsSupported))] [InlineData(true)] [InlineData(false)] @@ -186,17 +214,20 @@ public class SharedTestState : IDisposable { public SingleFileTestApp FrameworkDependentApp { get; } public SingleFileTestApp SelfContainedApp { get; } + public SingleFileTestApp SpecialCharacterSelfContainedApp { get; } public SharedTestState() { FrameworkDependentApp = SingleFileTestApp.CreateFrameworkDependent("HelloWorld"); SelfContainedApp = SingleFileTestApp.CreateSelfContained("HelloWorld"); + SpecialCharacterSelfContainedApp = SingleFileTestApp.CreateSelfContained("HelloWorld_中文"); } public void Dispose() { FrameworkDependentApp.Dispose(); SelfContainedApp.Dispose(); + SpecialCharacterSelfContainedApp.Dispose(); } } } diff --git "a/src/installer/tests/Assets/Projects/HelloWorld/HelloWorld_\344\270\255\346\226\207.csproj" "b/src/installer/tests/Assets/Projects/HelloWorld/HelloWorld_\344\270\255\346\226\207.csproj" new file mode 100644 index 00000000000000..a600aa229c5ec8 --- /dev/null +++ "b/src/installer/tests/Assets/Projects/HelloWorld/HelloWorld_\344\270\255\346\226\207.csproj" @@ -0,0 +1,19 @@ + + + + $(NetCoreAppCurrent) + Exe + + + + + + $(ProductVersion) + + + + + + + + diff --git a/src/installer/tests/Assets/Projects/HostApiInvokerApp/HostFXR.cs b/src/installer/tests/Assets/Projects/HostApiInvokerApp/HostFXR.cs index 1a67e91e1d8c72..fb5714be004b81 100644 --- a/src/installer/tests/Assets/Projects/HostApiInvokerApp/HostFXR.cs +++ b/src/installer/tests/Assets/Projects/HostApiInvokerApp/HostFXR.cs @@ -23,6 +23,7 @@ internal enum hostfxr_resolve_sdk2_result_key_t : int resolved_sdk_dir = 0, global_json_path = 1, requested_version = 2, + global_json_state = 3, } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] @@ -159,7 +160,7 @@ static void Test_hostfxr_resolve_sdk2(string[] args) var data = new List<(hostfxr.hostfxr_resolve_sdk2_result_key_t, string)>(); int rc = hostfxr.hostfxr_resolve_sdk2( exe_dir: args[0], - working_dir: args[1], + working_dir: args[1] == "" ? string.Empty : args[1], // Empty string disables global.json look-up flags: Enum.Parse(args[2]), result: (key, value) => data.Add((key, value))); diff --git a/src/installer/tests/Assets/Projects/HostApiInvokerApp/Program.cs b/src/installer/tests/Assets/Projects/HostApiInvokerApp/Program.cs index 0f5743a018e445..ee699613871b9e 100644 --- a/src/installer/tests/Assets/Projects/HostApiInvokerApp/Program.cs +++ b/src/installer/tests/Assets/Projects/HostApiInvokerApp/Program.cs @@ -35,30 +35,7 @@ public static void MainCore(string[] args) foreach (string arg in args) Console.WriteLine($" {arg}"); - // If requested, test multilevel lookup using fake Global SDK directories: - // 1. using a fake ProgramFiles location - // 2. using a fake SDK Self-Registered location - // Note that this has to be set here and not in the calling test process because - // %ProgramFiles% gets reset on process creation. - string testMultilevelLookupProgramFiles = Environment.GetEnvironmentVariable("TEST_MULTILEVEL_LOOKUP_PROGRAM_FILES"); - string testMultilevelLookupSelfRegistered = Environment.GetEnvironmentVariable("TEST_MULTILEVEL_LOOKUP_SELF_REGISTERED"); - - string hostfxrPath; - if (testMultilevelLookupProgramFiles != null && testMultilevelLookupSelfRegistered != null) - { - Environment.SetEnvironmentVariable("_DOTNET_TEST_GLOBALLY_REGISTERED_PATH", testMultilevelLookupSelfRegistered); - Environment.SetEnvironmentVariable("ProgramFiles", testMultilevelLookupProgramFiles); - Environment.SetEnvironmentVariable("ProgramFiles(x86)", testMultilevelLookupProgramFiles); - Environment.SetEnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1"); - hostfxrPath = AppContext.GetData("HOSTFXR_PATH_TEST_BEHAVIOR") as string; - } - else - { - // never rely on machine state in test if we're not faking the multi-level lookup - Environment.SetEnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0"); - hostfxrPath = AppContext.GetData("HOSTFXR_PATH") as string; - } - + string hostfxrPath = AppContext.GetData("HOSTFXR_PATH") as string; if (hostfxrPath is not null) { Console.WriteLine($"Registering DLLImportResolver for {nameof(HostFXR.hostfxr)} -> {hostfxrPath}"); diff --git a/src/installer/tests/HostActivation.Tests/DependencyResolution/DependencyResolutionCommandResultExtensions.cs b/src/installer/tests/HostActivation.Tests/DependencyResolution/DependencyResolutionCommandResultExtensions.cs index 7e057cff09cec4..ed3335d00e4fc5 100644 --- a/src/installer/tests/HostActivation.Tests/DependencyResolution/DependencyResolutionCommandResultExtensions.cs +++ b/src/installer/tests/HostActivation.Tests/DependencyResolution/DependencyResolutionCommandResultExtensions.cs @@ -12,8 +12,9 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution public static class DependencyResolutionCommandResultExtensions { // App asset resolution extensions - public const string TRUSTED_PLATFORM_ASSEMBLIES = "TRUSTED_PLATFORM_ASSEMBLIES"; - public const string NATIVE_DLL_SEARCH_DIRECTORIES = "NATIVE_DLL_SEARCH_DIRECTORIES"; + private const string TRUSTED_PLATFORM_ASSEMBLIES = nameof(TRUSTED_PLATFORM_ASSEMBLIES); + private const string NATIVE_DLL_SEARCH_DIRECTORIES = nameof(NATIVE_DLL_SEARCH_DIRECTORIES); + private const string PLATFORM_RESOURCE_ROOTS = nameof(PLATFORM_RESOURCE_ROOTS); public static AndConstraint HaveRuntimePropertyContaining(this CommandResultAssertions assertion, string propertyName, params string[] values) { @@ -67,6 +68,16 @@ public static AndConstraint NotHaveResolvedNativeLibrar return assertion.NotHaveRuntimePropertyContaining(NATIVE_DLL_SEARCH_DIRECTORIES, RelativePathsToAbsoluteAppPaths(path, app)); } + public static AndConstraint HaveResolvedResourceRootPath(this CommandResultAssertions assertion, string path, TestApp app = null) + { + return assertion.HaveRuntimePropertyContaining(PLATFORM_RESOURCE_ROOTS, RelativePathsToAbsoluteAppPaths(path, app)); + } + + public static AndConstraint NotHaveResolvedResourceRootPath(this CommandResultAssertions assertion, string path, TestApp app = null) + { + return assertion.NotHaveRuntimePropertyContaining(PLATFORM_RESOURCE_ROOTS, RelativePathsToAbsoluteAppPaths(path, app)); + } + // Component asset resolution extensions private const string assemblies = "assemblies"; private const string native_search_paths = "native_search_paths"; diff --git a/src/installer/tests/HostActivation.Tests/DependencyResolution/LocalPath.cs b/src/installer/tests/HostActivation.Tests/DependencyResolution/LocalPath.cs new file mode 100644 index 00000000000000..bad9c83eacede9 --- /dev/null +++ b/src/installer/tests/HostActivation.Tests/DependencyResolution/LocalPath.cs @@ -0,0 +1,265 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using Microsoft.DotNet.Cli.Build; +using Xunit; +using static Microsoft.DotNet.CoreSetup.Test.NetCoreAppBuilder; + +namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution +{ + public class LocalPath : IClassFixture + { + private readonly SharedTestState sharedState; + + public LocalPath(SharedTestState sharedState) + { + this.sharedState = sharedState; + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void RuntimeAssemblies_FrameworkDependent(bool useLocalPath) => RuntimeAssemblies(isSelfContained: false, useLocalPath); + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void RuntimeAssemblies_SelfContained(bool useLocalPath) => RuntimeAssemblies(isSelfContained: true, useLocalPath); + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void NativeLibraries_FrameworkDependent(bool useLocalPath) => NativeLibraries(isSelfContained: false, useLocalPath); + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void NativeLibraries_SelfContained(bool useLocalPath) => NativeLibraries(isSelfContained: true, useLocalPath); + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ResourceAssemblies_FrameworkDependent(bool useLocalPath) => ResourceAssemblies(isSelfContained: false, useLocalPath); + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ResourceAssemblies_SelfContained(bool useLocalPath) => ResourceAssemblies(isSelfContained: true, useLocalPath); + + private void RuntimeAssemblies(bool isSelfContained, bool useLocalPath) + { + RuntimeLibraryType[] libraryTypes = [ RuntimeLibraryType.project, RuntimeLibraryType.package, RuntimeLibraryType.runtimepack ]; + + Action customizer = b => + { + foreach (var libraryType in libraryTypes) + { + string library = $"Test{libraryType}"; + (string path, string localPath) = GetPaths(libraryType, false); + b.WithRuntimeLibrary(libraryType, library, "1.0.0", p => p + .WithAssemblyGroup(null, g => g + .WithAsset(path, useLocalPath ? f => f.WithLocalPath(localPath) : null))); + + if (!isSelfContained) + { + // Add RID-specific assembly + (string ridPath, string localRidPath) = GetPaths(libraryType, true); + b.WithRuntimeLibrary(libraryType, $"{library}-{TestContext.BuildRID}", "1.0.0", p => p + .WithAssemblyGroup(TestContext.BuildRID, g => g + .WithAsset(ridPath, useLocalPath ? f => f.WithLocalPath(localRidPath) : null))); + } + } + + b.WithLocalPathsInDepsJson(useLocalPath); + }; + + using TestApp app = CreateApp(isSelfContained, customizer); + var result = sharedState.DotNetWithNetCoreApp.Exec(app.AppDll) + .EnableTracingAndCaptureOutputs() + .Execute(); + result.Should().Pass(); + + // Check all library types + foreach (var libraryType in libraryTypes) + { + // Check RID-agnostic assembly + (string path, string localPath) = GetPaths(libraryType, false); + + // Without localPath, RID-agnostic non-runtimepack runtime assemblies are assumed to be in + string relativePath = useLocalPath + ? localPath + : libraryType == RuntimeLibraryType.runtimepack ? path : Path.GetFileName(path); + string expectedPath = Path.Join(app.Location, relativePath); + result.Should().HaveResolvedAssembly(expectedPath); + if (useLocalPath) + { + result.Should().NotHaveResolvedAssembly(Path.Join(app.Location, path)); + } + + // Check RID-specific assembly + if (!isSelfContained) + { + (string ridPath, string localRidPath) = GetPaths(libraryType, true); + string expectedRidPath = Path.Join(app.Location, useLocalPath ? localRidPath : ridPath); + result.Should().HaveResolvedAssembly(expectedRidPath); + if (useLocalPath) + { + result.Should().NotHaveResolvedAssembly(Path.Join(app.Location, ridPath)); + } + } + } + + static (string Path, string LocalPath) GetPaths(RuntimeLibraryType libraryType, bool useRid) + { + string library = $"Test{libraryType}"; + string path = useRid ? $"lib/{TestContext.BuildRID}/{library}-{TestContext.BuildRID}.dll" : $"lib/{library}.dll"; + return (path, $"{libraryType}/{path}"); + } + } + + private void NativeLibraries(bool isSelfContained, bool useLocalPath) + { + NetCoreAppBuilder.RuntimeLibraryType[] libraryTypes = [NetCoreAppBuilder.RuntimeLibraryType.project, NetCoreAppBuilder.RuntimeLibraryType.package, NetCoreAppBuilder.RuntimeLibraryType.runtimepack]; + + Action customizer = b => + { + foreach (var libraryType in libraryTypes) + { + string library = $"Test{libraryType}"; + (string path, string localPath) = GetPaths(libraryType, false); + b.WithRuntimeLibrary(libraryType, library, "1.0.0", p => p + .WithNativeLibraryGroup(null, g => g + .WithAsset($"{path}/{library}.native", useLocalPath ? f => f.WithLocalPath($"{localPath}/{library}.native") : null))); + + if (!isSelfContained) + { + // Add RID-specific native library + (string ridPath, string localRidPath) = GetPaths(libraryType, true); + b.WithRuntimeLibrary(libraryType, $"{library}-{TestContext.BuildRID}", "1.0.0", p => p + .WithNativeLibraryGroup(TestContext.BuildRID, g => g + .WithAsset($"{ridPath}/{library}-{TestContext.BuildRID}.native", useLocalPath ? f => f.WithLocalPath($"{localRidPath}/{library}-{TestContext.BuildRID}.native") : null))); + } + } + + b.WithLocalPathsInDepsJson(useLocalPath); + }; + + using TestApp app = CreateApp(isSelfContained, customizer); + var result = sharedState.DotNetWithNetCoreApp.Exec(app.AppDll) + .EnableTracingAndCaptureOutputs() + .Execute(); + result.Should().Pass(); + + // Check all library types + foreach (NetCoreAppBuilder.RuntimeLibraryType libraryType in libraryTypes) + { + // Check RID-agnostic native library path + (string path, string localPath) = GetPaths(libraryType, false); + + // Without localPath, RID-agnostic non-runtimepack native libraries are assumed to be in + string relativePath = useLocalPath + ? localPath + : libraryType == RuntimeLibraryType.runtimepack ? path : string.Empty; + string expectedPath = Path.Join(app.Location, relativePath); + result.Should().HaveResolvedNativeLibraryPath(expectedPath); + if (useLocalPath) + { + result.Should().NotHaveResolvedNativeLibraryPath(Path.Join(app.Location, path)); + } + + // Check RID-specific native library path + if (!isSelfContained) + { + (string ridPath, string localRidPath) = GetPaths(libraryType, true); + string expectedRidPath = Path.Join(app.Location, useLocalPath ? localRidPath : ridPath); + result.Should().HaveResolvedNativeLibraryPath(expectedRidPath); + if (useLocalPath) + { + result.Should().NotHaveResolvedNativeLibraryPath(Path.Join(app.Location, ridPath)); + } + } + } + + static (string Path, string LocalPath) GetPaths(NetCoreAppBuilder.RuntimeLibraryType libraryType, bool useRid) + { + string path = useRid ? $"native/{TestContext.BuildRID}" : "native"; + return (path, $"{libraryType}/{path}"); + } + } + + private void ResourceAssemblies(bool isSelfContained, bool useLocalPath) + { + NetCoreAppBuilder.RuntimeLibraryType[] libraryTypes = [NetCoreAppBuilder.RuntimeLibraryType.project, NetCoreAppBuilder.RuntimeLibraryType.package, NetCoreAppBuilder.RuntimeLibraryType.runtimepack]; + + Action customizer = b => + { + foreach (var libraryType in libraryTypes) + { + string library = $"Test{libraryType}"; + (string path, string localPath) = GetPaths(libraryType); + b.WithRuntimeLibrary(libraryType, library, "1.0.0", p => p + .WithResourceAssembly($"{path}/fr/{library}.resources.dll", useLocalPath ? f => f.WithLocalPath($"{localPath}/fr/{library}.resources.dll") : null)); + } + + b.WithLocalPathsInDepsJson(useLocalPath); + }; + + using TestApp app = CreateApp(isSelfContained, customizer); + var result = sharedState.DotNetWithNetCoreApp.Exec(app.AppDll) + .EnableTracingAndCaptureOutputs() + .Execute(); + result.Should().Pass(); + + // Check all library types + foreach (var libraryType in libraryTypes) + { + (string path, string localPath) = GetPaths(libraryType); + + // Without localPath, non-runtimepack resource assemblies are assumed to be in // + string relativePath = useLocalPath + ? localPath + : libraryType == RuntimeLibraryType.runtimepack ? path : string.Empty; + string expectedPath = Path.Join(app.Location, relativePath); + result.Should().HaveResolvedResourceRootPath(expectedPath); + if (useLocalPath) + { + result.Should().NotHaveResolvedResourceRootPath(Path.Join(app.Location, path)); + } + } + + static (string Path, string LocalPath) GetPaths(NetCoreAppBuilder.RuntimeLibraryType libraryType) + { + string path = $"resources"; + return (path, $"{libraryType}/{path}"); + } + } + + private static TestApp CreateApp(bool isSelfContained, Action customizer) + { + TestApp app = TestApp.CreateEmpty("App"); + if (isSelfContained) + { + app.PopulateSelfContained(TestApp.MockedComponent.CoreClr, customizer); + } + else + { + app.PopulateFrameworkDependent(Constants.MicrosoftNETCoreApp, TestContext.MicrosoftNETCoreAppVersion, customizer); + } + return app; + } + + public class SharedTestState : SharedTestStateBase + { + public DotNetCli DotNetWithNetCoreApp { get; } + + public SharedTestState() + { + DotNetWithNetCoreApp = DotNet("WithNetCoreApp") + .AddMicrosoftNETCoreAppFrameworkMockCoreClr(TestContext.MicrosoftNETCoreAppVersion) + .Build(); + } + } + } +} diff --git a/src/installer/tests/HostActivation.Tests/DependencyResolution/ResolveComponentDependencies.cs b/src/installer/tests/HostActivation.Tests/DependencyResolution/ResolveComponentDependencies.cs index 5c66d948f6d0f2..43bb088f2e7f9d 100644 --- a/src/installer/tests/HostActivation.Tests/DependencyResolution/ResolveComponentDependencies.cs +++ b/src/installer/tests/HostActivation.Tests/DependencyResolution/ResolveComponentDependencies.cs @@ -365,7 +365,7 @@ public void ComponentWithCorruptedDepsJsonShouldFail() .Should().Fail() .And.HaveStdOutContaining($"corehost_resolve_component_dependencies:Fail[0x{Constants.ErrorCode.ResolverInitFailure.ToString("x")}]") .And.HaveStdOutContaining("corehost reported errors:") - .And.HaveStdOutContaining($"A JSON parsing exception occurred in [{component.DepsJson}], offset 0 (line 1, column 1): Invalid value.") + .And.HaveStdOutContaining($"Failed to parse file [{component.DepsJson}]. JSON parsing exception: Invalid value. [offset 0: line 1, column 1]") .And.HaveStdOutContaining($"Error initializing the dependency resolver: An error occurred while parsing: {component.DepsJson}"); } @@ -426,7 +426,7 @@ public void MultiThreadedComponentDependencyResolutionWithFailures() .Should().Fail() .And.HaveStdOutContaining($"ComponentA: corehost_resolve_component_dependencies:Fail[0x{Constants.ErrorCode.ResolverInitFailure.ToString("x")}]") .And.HaveStdOutContaining($"ComponentA: corehost reported errors:") - .And.HaveStdOutContaining($"ComponentA: A JSON parsing exception occurred in [{componentWithNoDependencies.DepsJson}], offset 0 (line 1, column 1): Invalid value.") + .And.HaveStdOutContaining($"ComponentA: Failed to parse file [{componentWithNoDependencies.DepsJson}]. JSON parsing exception: Invalid value. [offset 0: line 1, column 1]") .And.HaveStdOutContaining($"ComponentA: Error initializing the dependency resolver: An error occurred while parsing: {componentWithNoDependencies.DepsJson}") .And.HaveStdOutContaining($"ComponentB: corehost_resolve_component_dependencies:Fail[0x{Constants.ErrorCode.LibHostInvalidArgs.ToString("x")}]") .And.HaveStdOutContaining($"ComponentB: corehost reported errors:") @@ -458,7 +458,7 @@ public TestApp CreateComponentWithDependencies(Action customi .WithPackage(AdditionalDependencyName, "2.0.1", p => p.WithAssemblyGroup(null, g => g .WithAsset($"lib/netstandard1.0/{AdditionalDependencyName}.dll", f => f .WithVersion("2.0.0.0", "2.0.1.23344") - .WithFileOnDiskPath($"{AdditionalDependencyName}.dll")))) + .WithLocalPath($"{AdditionalDependencyName}.dll")))) .WithPackage("Libuv", "1.9.1", p => p .WithNativeLibraryGroup("debian-x64", g => g.WithAsset("runtimes/debian-x64/native/libuv.so")) .WithNativeLibraryGroup("fedora-x64", g => g.WithAsset("runtimes/fedora-x64/native/libuv.so")) diff --git a/src/installer/tests/HostActivation.Tests/DotnetArgValidation.cs b/src/installer/tests/HostActivation.Tests/DotnetArgValidation.cs index cb44c319fb9e92..18ce6bbf5716fd 100644 --- a/src/installer/tests/HostActivation.Tests/DotnetArgValidation.cs +++ b/src/installer/tests/HostActivation.Tests/DotnetArgValidation.cs @@ -68,41 +68,6 @@ public void MissingArgumentValue_Fails() .And.HaveStdErrContaining($"Failed to parse supported options or their values:"); } - [Fact] - public void File_ExistsNoDirectorySeparator_RoutesToSDK() - { - // Create a file named "build" in the current directory to simulate a file that happens to match the name of a command - string buildFile = Path.Combine(sharedTestState.BaseDirectory.Location, "build"); - File.WriteAllText(buildFile, string.Empty); - - // Test that "dotnet build" still routes to SDK, not to the file - TestContext.BuiltDotNet.Exec("build") - .WorkingDirectory(sharedTestState.BaseDirectory.Location) - .EnableTracingAndCaptureOutputs() - .Execute() - .Should().Fail() - .And.HaveStdErrContaining("The command could not be loaded, possibly because:") // This is a generic error for when we can't tell what exactly the user intended to do - .And.HaveStdErrContaining("Resolving SDKs"); - } - - [Fact] - public void RelativePathToNonManagedFile_ShowsSpecificError() - { - // Test relative path with directory separator - Directory.CreateDirectory(Path.Combine(sharedTestState.BaseDirectory.Location, "subdir")); - string testFile = Path.Combine(sharedTestState.BaseDirectory.Location, "subdir", "test.json"); - File.WriteAllText(testFile, "{}"); - - string relativePath = Path.GetRelativePath(sharedTestState.BaseDirectory.Location, testFile); - TestContext.BuiltDotNet.Exec(relativePath) - .WorkingDirectory(sharedTestState.BaseDirectory.Location) - .CaptureStdOut() - .CaptureStdErr() - .Execute() - .Should().Fail() - .And.HaveStdErrContaining($"The application '{relativePath}' is not a managed .dll."); - } - [Fact] public void InvalidFileOrCommand_NoSDK_ListsPossibleIssues() { diff --git a/src/installer/tests/HostActivation.Tests/FrameworkDependentAppLaunch.cs b/src/installer/tests/HostActivation.Tests/FrameworkDependentAppLaunch.cs index c6c462dcec6da7..e818c74a6e5973 100644 --- a/src/installer/tests/HostActivation.Tests/FrameworkDependentAppLaunch.cs +++ b/src/installer/tests/HostActivation.Tests/FrameworkDependentAppLaunch.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Text.Json; using Microsoft.DotNet.Cli.Build.Framework; using Microsoft.Extensions.DependencyModel; @@ -58,7 +59,7 @@ public void Muxer_AssemblyWithDifferentFileExtension_Fails() .CaptureStdErr() .Execute() .Should().Fail() - .And.HaveStdErrContaining($"The application '{appOtherExt}' is not a managed .dll."); + .And.HaveStdErrContaining($"The application '{appOtherExt}' does not exist or is not a managed .dll or .exe"); } [Fact] @@ -187,83 +188,17 @@ public void AppHost() if (Binaries.CetCompat.IsSupported) Assert.True(Binaries.CetCompat.IsMarkedCompatible(appExe)); - // Get the framework location that was built - string builtDotnet = TestContext.BuiltDotNet.BinPath; - - // Verify running with the default working directory Command.Create(appExe) .CaptureStdErr() .CaptureStdOut() - .DotNetRoot(builtDotnet, TestContext.BuildArchitecture) - .MultilevelLookup(false) - .Execute() - .Should().Pass() - .And.HaveStdOutContaining("Hello World") - .And.HaveStdOutContaining(TestContext.MicrosoftNETCoreAppVersion); - - - // Verify running from within the working directory - Command.Create(appExe) - .WorkingDirectory(sharedTestState.App.Location) - .DotNetRoot(builtDotnet, TestContext.BuildArchitecture) + .DotNetRoot(TestContext.BuiltDotNet.BinPath, TestContext.BuildArchitecture) .MultilevelLookup(false) - .CaptureStdErr() - .CaptureStdOut() .Execute() .Should().Pass() .And.HaveStdOutContaining("Hello World") .And.HaveStdOutContaining(TestContext.MicrosoftNETCoreAppVersion); } - [Theory] - [InlineData(true)] - [InlineData(false)] - public void AppHost_GlobalLocation(bool useRegisteredLocation) - { - string appExe = sharedTestState.App.AppExe; - - // Get the framework location that was built - string builtDotnet = TestContext.BuiltDotNet.BinPath; - - using (var registeredInstallLocationOverride = new RegisteredInstallLocationOverride(appExe)) - { - string architecture = TestContext.BuildArchitecture; - if (useRegisteredLocation) - { - registeredInstallLocationOverride.SetInstallLocation(new (string, string)[] { (architecture, builtDotnet) }); - } - - // Verify running with the default working directory - Command.Create(appExe) - .CaptureStdErr() - .CaptureStdOut() - .MultilevelLookup(false) - .ApplyRegisteredInstallLocationOverride(registeredInstallLocationOverride) - .EnvironmentVariable(Constants.TestOnlyEnvironmentVariables.DefaultInstallPath, useRegisteredLocation ? null : builtDotnet) - .DotNetRoot(null) - .Execute() - .Should().Pass() - .And.HaveStdOutContaining("Hello World") - .And.HaveStdOutContaining(TestContext.MicrosoftNETCoreAppVersion) - .And.NotHaveStdErr(); - - // Verify running from within the working directory - Command.Create(appExe) - .CaptureStdErr() - .CaptureStdOut() - .MultilevelLookup(false) - .WorkingDirectory(sharedTestState.App.Location) - .ApplyRegisteredInstallLocationOverride(registeredInstallLocationOverride) - .EnvironmentVariable(Constants.TestOnlyEnvironmentVariables.DefaultInstallPath, useRegisteredLocation ? null : builtDotnet) - .DotNetRoot(null) - .Execute() - .Should().Pass() - .And.HaveStdOutContaining("Hello World") - .And.HaveStdOutContaining(TestContext.MicrosoftNETCoreAppVersion) - .And.NotHaveStdErr(); - } - } - [ConditionalFact(typeof(Binaries.CetCompat), nameof(Binaries.CetCompat.IsSupported))] public void AppHost_DisableCetCompat() { @@ -391,7 +326,6 @@ public void MissingFrameworkInRuntimeConfig_Fails(bool useAppHost) } command.EnableTracingAndCaptureOutputs() - .MultilevelLookup(false) .Execute() .Should().Fail() .And.HaveStdErrContaining($"The library '{Binaries.HostPolicy.FileName}' required to execute the application was not found") @@ -399,6 +333,45 @@ public void MissingFrameworkInRuntimeConfig_Fails(bool useAppHost) .And.HaveStdErrContaining($"'{app.RuntimeConfigJson}' did not specify a framework"); } + [Fact] + public void MissingFrameworkName() + { + TestApp app = sharedTestState.MockApp.Copy(); + + // Create a runtimeconfig.json with a framework that has no name property + var framework = new RuntimeConfig.Framework(null, TestContext.MicrosoftNETCoreAppVersion); + new RuntimeConfig(app.RuntimeConfigJson) + .WithFramework(framework) + .Save(); + + Command.Create(app.AppExe) + .DotNetRoot(TestContext.BuiltDotNet.BinPath) + .EnableTracingAndCaptureOutputs() + .Execute() + .Should().Fail() + .And.HaveStdErrContaining($"No framework name specified: {framework.ToJson().ToJsonString(new JsonSerializerOptions { WriteIndented = false })}") + .And.HaveStdErrContaining($"Invalid runtimeconfig.json [{app.RuntimeConfigJson}]"); + } + + [Fact] + public void MissingFrameworkVersion() + { + TestApp app = sharedTestState.MockApp.Copy(); + + // Create a runtimeconfig.json with a framework that has no version property + new RuntimeConfig(app.RuntimeConfigJson) + .WithFramework(Constants.MicrosoftNETCoreApp, null) + .Save(); + + Command.Create(app.AppExe) + .DotNetRoot(TestContext.BuiltDotNet.BinPath) + .EnableTracingAndCaptureOutputs() + .Execute() + .Should().Fail() + .And.HaveStdErrContaining($"Framework '{Constants.MicrosoftNETCoreApp}' is missing a version") + .And.HaveStdErrContaining($"Invalid runtimeconfig.json [{app.RuntimeConfigJson}]"); + } + [Theory] [InlineData(true)] [InlineData(false)] diff --git a/src/installer/tests/HostActivation.Tests/FrameworkResolution/FrameworkResolution.cs b/src/installer/tests/HostActivation.Tests/FrameworkResolution/FrameworkResolution.cs index 43803b698669a4..42e724c8ad5356 100644 --- a/src/installer/tests/HostActivation.Tests/FrameworkResolution/FrameworkResolution.cs +++ b/src/installer/tests/HostActivation.Tests/FrameworkResolution/FrameworkResolution.cs @@ -33,7 +33,7 @@ public FrameworkResolution(SharedTestState sharedState) public void Default(string requestedVersion, string resolvedVersion) { CommandResult result = RunTest( - new TestSettings().WithRuntimeConfigCustomizer(rc => + new TestSettings().WithRuntimeConfigCustomizer(rc => rc.WithFramework(MicrosoftNETCoreApp, requestedVersion))); result.ShouldHaveResolvedFrameworkOrFailToFind(MicrosoftNETCoreApp, resolvedVersion); @@ -137,6 +137,12 @@ public SharedTestState() foreach (string version in EmptyVersions) Directory.CreateDirectory(Path.Combine(InstalledDotNet.SharedFxPath, version)); + // Enable test-only behaviour. We always do this - even for tests that don't need the behaviour. + // On macOS with system integrity protection enabled, if the binary is loaded, modified (test-only + // behaviour rewrites part of the binary), and loaded again, the process will crash. + // We don't bother disabling it later, as we just delete the containing folder after tests run. + _ = TestOnlyProductBehavior.Enable(InstalledDotNet.GreatestVersionHostFxrFilePath); + App = CreateFrameworkReferenceApp(); } } diff --git a/src/installer/tests/HostActivation.Tests/FrameworkResolution/IncludedFrameworksSettings.cs b/src/installer/tests/HostActivation.Tests/FrameworkResolution/IncludedFrameworksSettings.cs index cd3efe4ddcc862..a46105cb933c10 100644 --- a/src/installer/tests/HostActivation.Tests/FrameworkResolution/IncludedFrameworksSettings.cs +++ b/src/installer/tests/HostActivation.Tests/FrameworkResolution/IncludedFrameworksSettings.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.CompilerServices; +using System.Text.Json; using Microsoft.DotNet.Cli.Build; using Microsoft.DotNet.Cli.Build.Framework; using Xunit; @@ -45,14 +46,28 @@ public void SelfContainedCanHaveIncludedFrameworks() } [Fact] - public void IncludedFrameworkMustSpecifyName() + public void MissingName() { + var framework = new RuntimeConfig.Framework(null, TestContext.MicrosoftNETCoreAppVersion); RunSelfContainedTest( new TestSettings() .WithRuntimeConfigCustomizer(runtimeConfig => runtimeConfig - .WithIncludedFramework(null, "5.1.2"))) + .WithIncludedFramework(framework))) .Should().Fail() - .And.HaveStdErrContaining("No framework name specified."); + .And.HaveStdErrContaining($"No framework name specified: {framework.ToJson().ToJsonString(new JsonSerializerOptions { WriteIndented = false })}") + .And.HaveStdErrContaining($"Invalid runtimeconfig.json [{SharedState.SelfContainedApp.RuntimeConfigJson}]"); + } + + [Fact] + public void MissingVersion() + { + RunSelfContainedTest( + new TestSettings() + .WithRuntimeConfigCustomizer(runtimeConfig => runtimeConfig + .WithIncludedFramework(Constants.MicrosoftNETCoreApp, null))) + .Should().Fail() + .And.HaveStdErrContaining($"Framework '{Constants.MicrosoftNETCoreApp}' is missing a version") + .And.HaveStdErrContaining($"Invalid runtimeconfig.json [{SharedState.SelfContainedApp.RuntimeConfigJson}]"); } [Fact] diff --git a/src/installer/tests/HostActivation.Tests/HostCommands.cs b/src/installer/tests/HostActivation.Tests/HostCommands.cs index 44883cf75ffe89..d7fb6d30cfd83a 100644 --- a/src/installer/tests/HostActivation.Tests/HostCommands.cs +++ b/src/installer/tests/HostActivation.Tests/HostCommands.cs @@ -8,6 +8,7 @@ using Microsoft.DotNet.Cli.Build; using Microsoft.DotNet.CoreSetup.Test; using Microsoft.DotNet.CoreSetup.Test.HostActivation; +using Microsoft.DotNet.TestUtils; using Xunit; namespace HostActivation.Tests @@ -83,6 +84,150 @@ public void Info_Utf8Path() .And.HaveStdOutMatching($@"DOTNET_ROOT.*{installLocation}"); } + [Fact] + public void Info_ListEnvironment() + { + var command = TestContext.BuiltDotNet.Exec("--info") + .CaptureStdOut(); + + // Add DOTNET_ROOT environment variables + (string Architecture, string Path)[] dotnetRootEnvVars = [ + ("arm64", "/arm64/dotnet/root"), + ("x64", "/x64/dotnet/root"), + ("x86", "/x86/dotnet/root"), + ("unknown", "/unknown/dotnet/root") + ]; + foreach (var envVar in dotnetRootEnvVars) + { + command = command.DotNetRoot(envVar.Path, envVar.Architecture); + } + + string dotnetRootNoArch = "/dotnet/root"; + command = command.DotNetRoot(dotnetRootNoArch); + + // Add additional DOTNET_* environment variables + (string Name, string Value)[] envVars = [ + ("DOTNET_ROLL_FORWARD", "Major"), + ("DOTNET_SOME_SETTING", "/some/setting"), + ("DOTNET_HOST_TRACE", "1") + ]; + + (string Name, string Value)[] differentCaseEnvVars = [ + ("dotnet_env_var", "dotnet env var value"), + ("dOtNeT_setting", "doOtNeT setting value"), + ]; + foreach ((string name, string value) in envVars.Concat(differentCaseEnvVars)) + { + command = command.EnvironmentVariable(name, value); + } + + string otherEnvVar = "OTHER"; + command = command.EnvironmentVariable(otherEnvVar, "value"); + + var result = command.Execute(); + result.Should().Pass() + .And.HaveStdOutContaining("Environment variables:") + .And.HaveStdOutMatching($@"{Constants.DotnetRoot.EnvironmentVariable}\s*\[{dotnetRootNoArch}\]") + .And.NotHaveStdOutContaining(otherEnvVar); + + foreach ((string architecture, string path) in dotnetRootEnvVars) + { + result.Should() + .HaveStdOutMatching($@"{Constants.DotnetRoot.ArchitectureEnvironmentVariablePrefix}{architecture.ToUpper()}\s*\[{path}\]"); + } + + foreach ((string name, string value) in envVars) + { + result.Should().HaveStdOutMatching($@"{name}\s*\[{value}\]"); + } + + foreach ((string name, string value) in differentCaseEnvVars) + { + if (OperatingSystem.IsWindows()) + { + // Environment variables are case-insensitive on Windows + result.Should().HaveStdOutMatching($@"{name}\s*\[{value}\]"); + } + else + { + result.Should().NotHaveStdOutContaining(name); + } + } + } + + [Fact] + public void Info_ListEnvironment_LegacyPrefixDetection() + { + string comPlusEnvVar = "COMPlus_ReadyToRun"; + TestContext.BuiltDotNet.Exec("--info") + .EnvironmentVariable(comPlusEnvVar, "0") + .CaptureStdOut() + .Execute() + .Should().Pass() + .And.HaveStdOutContaining("Environment variables:") + .And.NotHaveStdOutContaining(comPlusEnvVar) + .And.HaveStdOutContaining("Detected COMPlus_* environment variable(s). Consider transitioning to DOTNET_* equivalent."); + } + + [Fact] + public void Info_GlobalJson_InvalidJson() + { + using (TestArtifact workingDir = TestArtifact.Create(nameof(Info_GlobalJson_InvalidJson))) + { + string globalJsonPath = GlobalJson.Write(workingDir.Location, "{ \"sdk\": { }"); + TestContext.BuiltDotNet.Exec("--info") + .WorkingDirectory(workingDir.Location) + .CaptureStdOut().CaptureStdErr() + .Execute() + .Should().Pass() + .And.HaveStdOutContaining($"Invalid [{globalJsonPath}]") + .And.HaveStdOutContaining("JSON parsing exception:") + .And.NotHaveStdErr(); + } + } + + [Theory] + [InlineData("9")] + [InlineData("9.0")] + [InlineData("9.0.x")] + [InlineData("invalid")] + public void Info_GlobalJson_InvalidData(string version) + { + using (TestArtifact workingDir = TestArtifact.Create(nameof(Info_GlobalJson_InvalidData))) + { + string globalJsonPath = GlobalJson.CreateWithVersion(workingDir.Location, version); + TestContext.BuiltDotNet.Exec("--info") + .WorkingDirectory(workingDir.Location) + .CaptureStdOut().CaptureStdErr() + .Execute() + .Should().Pass() + .And.HaveStdOutContaining($"Invalid [{globalJsonPath}]") + .And.HaveStdOutContaining($"Version '{version}' is not valid for the 'sdk/version' value") + .And.HaveStdOutContaining($"Invalid global.json is ignored for SDK resolution") + .And.NotHaveStdErr(); + } + } + + [Theory] + [InlineData("9.0.0")] + [InlineData("9.1.99")] + public void Info_GlobalJson_NonExistentFeatureBand(string version) + { + using (TestArtifact workingDir = TestArtifact.Create(nameof(Info_GlobalJson_NonExistentFeatureBand))) + { + string globalJsonPath = GlobalJson.CreateWithVersion(workingDir.Location, version); + var result = TestContext.BuiltDotNet.Exec("--info") + .WorkingDirectory(workingDir.Location) + .CaptureStdOut().CaptureStdErr() + .Execute() + .Should().Pass() + .And.HaveStdOutContaining($"Invalid [{globalJsonPath}]") + .And.HaveStdOutContaining($"Version '{version}' is not valid for the 'sdk/version' value. SDK feature bands start at 1 - for example, {Version.Parse(version).ToString(2)}.100") + .And.NotHaveStdOutContaining($"Invalid global.json is ignored for SDK resolution") + .And.NotHaveStdErr(); + } + } + [Fact] public void ListRuntimes() { diff --git a/src/installer/tests/HostActivation.Tests/HostVersionCompatibility.cs b/src/installer/tests/HostActivation.Tests/HostVersionCompatibility.cs index fe008645f75594..37a9a4b24e2168 100644 --- a/src/installer/tests/HostActivation.Tests/HostVersionCompatibility.cs +++ b/src/installer/tests/HostActivation.Tests/HostVersionCompatibility.cs @@ -80,7 +80,8 @@ private void OldHost_LatestRuntime_ForwardCompatible(TestApp previousVersionApp) // 2) App rolls forward to newer runtime File.Copy(previousVersionApp.AppExe, appExe, true); Command.Create(appExe) - .EnableTracingAndCaptureOutputs() + .CaptureStdOut().CaptureStdErr() + .EnvironmentVariable("COREHOST_TRACE", "1") // Old host, so we need to use the old variable name .Execute() .Should().Pass() .And.HaveStdOutContaining("Hello World") @@ -95,7 +96,8 @@ private void OldHost_LatestRuntime_ForwardCompatible(TestApp previousVersionApp) { File.Copy(previousVersionApp.HostFxrDll, app.HostFxrDll, true); Command.Create(appExe) - .EnableTracingAndCaptureOutputs() + .CaptureStdOut().CaptureStdErr() + .EnvironmentVariable("COREHOST_TRACE", "1") // Old host, so we need to use the old variable name .Execute() .Should().Pass() .And.HaveStdOutContaining("Hello World") diff --git a/src/installer/tests/HostActivation.Tests/InstallLocation.cs b/src/installer/tests/HostActivation.Tests/InstallLocation.cs index dba3a2b7c43263..e85e8043177d01 100644 --- a/src/installer/tests/HostActivation.Tests/InstallLocation.cs +++ b/src/installer/tests/HostActivation.Tests/InstallLocation.cs @@ -64,7 +64,7 @@ public void EnvironmentVariable_ArchSpecificDotnetRootIsUsedOverDotnetRoot() [Fact] public void EnvironmentVariable_DotNetRootIsUsedOverInstallLocationIfSet() { - var app = sharedTestState.App.Copy(); + var app = sharedTestState.TestBehaviourEnabledApp; var appExe = app.AppExe; var arch = TestContext.BuildArchitecture.ToUpper(); var dotnet = TestContext.BuiltDotNet.BinPath; @@ -87,86 +87,83 @@ public void EnvironmentVariable_DotNetRootIsUsedOverInstallLocationIfSet() [Fact] public void EnvironmentVariable_DotnetRootPathDoesNotExist() { - var app = sharedTestState.App.Copy(); - using (TestOnlyProductBehavior.Enable(app.AppExe)) - { - Command.Create(app.AppExe) - .EnableTracingAndCaptureOutputs() - .DotNetRoot("non_existent_path") - .MultilevelLookup(false) - .EnvironmentVariable( - Constants.TestOnlyEnvironmentVariables.GloballyRegisteredPath, - TestContext.BuiltDotNet.BinPath) - .Execute() - .Should().Pass() - .And.HaveStdErrContaining("Did not find [DOTNET_ROOT] directory [non_existent_path]") - // If DOTNET_ROOT points to a folder that does not exist, we fall back to the global install path. - .And.HaveUsedGlobalInstallLocation(TestContext.BuiltDotNet.BinPath) - .And.HaveStdOutContaining("Hello World"); - } + var app = sharedTestState.TestBehaviourEnabledApp; + Command.Create(app.AppExe) + .EnableTracingAndCaptureOutputs() + .DotNetRoot("non_existent_path") + .MultilevelLookup(false) + .EnvironmentVariable( + Constants.TestOnlyEnvironmentVariables.GloballyRegisteredPath, + TestContext.BuiltDotNet.BinPath) + .Execute() + .Should().Pass() + .And.HaveStdErrContaining("Did not find [DOTNET_ROOT] directory [non_existent_path]") + // If DOTNET_ROOT points to a folder that does not exist, we fall back to the global install path. + .And.HaveUsedGlobalInstallLocation(TestContext.BuiltDotNet.BinPath) + .And.HaveStdOutContaining("Hello World"); } [Fact] public void EnvironmentVariable_DotnetRootPathExistsButHasNoHost() { - var app = sharedTestState.App.Copy(); - using (TestOnlyProductBehavior.Enable(app.AppExe)) + var app = sharedTestState.TestBehaviourEnabledApp; + Command.Create(app.AppExe) + .EnableTracingAndCaptureOutputs() + .DotNetRoot(app.Location) + .MultilevelLookup(false) + .EnvironmentVariable( + Constants.TestOnlyEnvironmentVariables.GloballyRegisteredPath, + TestContext.BuiltDotNet.BinPath) + .Execute() + .Should().Fail() + .And.HaveUsedDotNetRootInstallLocation(app.Location, TestContext.BuildRID) + // If DOTNET_ROOT points to a folder that exists we assume that there's a dotnet installation in it + .And.HaveStdErrContaining($"The required library {Binaries.HostFxr.FileName} could not be found."); + } + + [Fact] + public void DefaultInstallLocation() + { + TestApp app = sharedTestState.TestBehaviourEnabledApp; + + // Ensure no install locations are registered, so the default install location is used + using (var registeredInstallLocationOverride = new RegisteredInstallLocationOverride(app.AppExe)) { Command.Create(app.AppExe) .EnableTracingAndCaptureOutputs() - .DotNetRoot(app.Location) - .MultilevelLookup(false) - .EnvironmentVariable( - Constants.TestOnlyEnvironmentVariables.GloballyRegisteredPath, - TestContext.BuiltDotNet.BinPath) + .ApplyRegisteredInstallLocationOverride(registeredInstallLocationOverride) + .EnvironmentVariable(Constants.TestOnlyEnvironmentVariables.DefaultInstallPath, TestContext.BuiltDotNet.BinPath) + .DotNetRoot(null) .Execute() - .Should().Fail() - .And.HaveUsedDotNetRootInstallLocation(app.Location, TestContext.BuildRID) - // If DOTNET_ROOT points to a folder that exists we assume that there's a dotnet installation in it - .And.HaveStdErrContaining($"The required library {Binaries.HostFxr.FileName} could not be found."); + .Should().Pass() + .And.HaveUsedGlobalInstallLocation(TestContext.BuiltDotNet.BinPath); } } [Fact] - public void EnvironmentVariable_DotNetInfo_ListEnvironment() + public void RegisteredInstallLocation() { - var command = TestContext.BuiltDotNet.Exec("--info") - .CaptureStdOut(); - - var envVars = new (string Architecture, string Path)[] { - ("arm64", "/arm64/dotnet/root"), - ("x64", "/x64/dotnet/root"), - ("x86", "/x86/dotnet/root") - }; - foreach(var envVar in envVars) + TestApp app = sharedTestState.TestBehaviourEnabledApp; + using (var registeredInstallLocationOverride = new RegisteredInstallLocationOverride(app.AppExe)) { - command = command.DotNetRoot(envVar.Path, envVar.Architecture); - } - - string dotnetRootNoArch = "/dotnet/root"; - command = command.DotNetRoot(dotnetRootNoArch); - - (string Architecture, string Path) unknownEnvVar = ("unknown", "/unknown/dotnet/root"); - command = command.DotNetRoot(unknownEnvVar.Path, unknownEnvVar.Architecture); - - var result = command.Execute(); - result.Should().Pass() - .And.HaveStdOutContaining("Environment variables:") - .And.HaveStdOutMatching($@"{Constants.DotnetRoot.EnvironmentVariable}\s*\[{dotnetRootNoArch}\]") - .And.NotHaveStdOutContaining($"{Constants.DotnetRoot.ArchitectureEnvironmentVariablePrefix}{unknownEnvVar.Architecture.ToUpper()}") - .And.NotHaveStdOutContaining($"[{unknownEnvVar.Path}]"); + registeredInstallLocationOverride.SetInstallLocation( + (TestContext.BuildArchitecture, TestContext.BuiltDotNet.BinPath)); - foreach ((string architecture, string path) in envVars) - { - result.Should() - .HaveStdOutMatching($@"{Constants.DotnetRoot.ArchitectureEnvironmentVariablePrefix}{architecture.ToUpper()}\s*\[{path}\]"); + Command.Create(app.AppExe) + .EnableTracingAndCaptureOutputs() + .ApplyRegisteredInstallLocationOverride(registeredInstallLocationOverride) + .DotNetRoot(null) + .Execute() + .Should().Pass() + .And.HaveUsedRegisteredInstallLocation(TestContext.BuiltDotNet.BinPath) + .And.HaveUsedGlobalInstallLocation(TestContext.BuiltDotNet.BinPath); } } [Fact] public void RegisteredInstallLocation_ArchSpecificLocationIsPickedFirst() { - var app = sharedTestState.App.Copy(); + var app = sharedTestState.TestBehaviourEnabledApp; var arch1 = "someArch"; var path1 = "x/y/z"; var arch2 = TestContext.BuildArchitecture; @@ -202,7 +199,7 @@ public void RegisteredInstallLocation_ArchSpecificLocationIsPickedFirst() [SkipOnPlatform(TestPlatforms.Windows, "This test targets the install_location config file which is only used on Linux and macOS.")] public void InstallLocationFile_ReallyLongInstallPathIsParsedCorrectly() { - var app = sharedTestState.App.Copy(); + var app = sharedTestState.TestBehaviourEnabledApp; using (var registeredInstallLocationOverride = new RegisteredInstallLocationOverride(app.AppExe)) { var reallyLongPath = @@ -225,9 +222,8 @@ public void InstallLocationFile_ReallyLongInstallPathIsParsedCorrectly() [SkipOnPlatform(TestPlatforms.Windows, "This test targets the install_location config file which is only used on Linux and macOS.")] public void InstallLocationFile_MissingFile() { - var app = sharedTestState.App.Copy(); + var app = sharedTestState.TestBehaviourEnabledApp; using (var testArtifact = TestArtifact.Create("missingInstallLocation")) - using (var testOnlyProductBehavior = TestOnlyProductBehavior.Enable(app.AppExe)) { string installLocationDirectory = Path.Combine(testArtifact.Location, "installLocationOverride"); Directory.CreateDirectory(installLocationDirectory); @@ -290,6 +286,51 @@ public void RegisteredInstallLocation_DotNetInfo_ListOtherArchitectures() } } + [Fact] + public void NotFound() + { + TestApp app = sharedTestState.TestBehaviourEnabledApp; + + // Ensure no install locations are registered + using (var registeredInstallLocationOverride = new RegisteredInstallLocationOverride(app.AppExe)) + { + string defaultLocation = Path.GetTempPath(); + string registeredLocationOverride = OperatingSystem.IsWindows() // Host uses short form of base key for Windows + ? registeredInstallLocationOverride.PathValueOverride.Replace(Microsoft.Win32.Registry.CurrentUser.Name, "HKCU") + : registeredInstallLocationOverride.PathValueOverride; + Command.Create(app.AppExe) + .CaptureStdOut() + .CaptureStdErr() + .ApplyRegisteredInstallLocationOverride(registeredInstallLocationOverride) + .EnvironmentVariable(Constants.TestOnlyEnvironmentVariables.DefaultInstallPath, defaultLocation) + .DotNetRoot(null) + .Execute() + .Should().Fail() + .And.HaveStdErrContaining("The following locations were searched:") + .And.HaveStdErrContaining( + $""" + Application directory: + {app.Location} + """) + .And.HaveStdErrContaining( + $""" + Environment variable: + DOTNET_ROOT_{TestContext.BuildArchitecture.ToUpper()} = + DOTNET_ROOT = + """) + .And.HaveStdErrMatching( + $""" + Registered location: + {System.Text.RegularExpressions.Regex.Escape(registeredLocationOverride)}.*{TestContext.BuildArchitecture}.* = + """) + .And.HaveStdErrContaining( + $""" + Default location: + {defaultLocation} + """); + } + } + [Theory] [InlineData(SearchLocation.AppLocal)] [InlineData(SearchLocation.AppRelative)] @@ -345,7 +386,7 @@ public void SearchOptions(SearchLocation searchLocation) } [Fact] - public void AppHost_AppRelative_MissingPath() + public void SearchOptions_AppRelative_MissingPath() { TestApp app = sharedTestState.App.Copy(); app.CreateAppHost(dotNetRootOptions: new HostWriter.DotNetSearchOptions() @@ -450,16 +491,25 @@ public void SearchOptions_Precedence(SearchLocation expectedResult) public class SharedTestState : IDisposable { public TestApp App { get; } + public TestApp TestBehaviourEnabledApp { get; } public SharedTestState() { App = TestApp.CreateFromBuiltAssets("HelloWorld"); App.CreateAppHost(); + + TestBehaviourEnabledApp = TestApp.CreateFromBuiltAssets("HelloWorld"); + TestBehaviourEnabledApp.CreateAppHost(); + + // Enable test-only behavior for the app. We don't bother disabling the behaviour later, + // as we just delete the entire app after the tests run. + _ = TestOnlyProductBehavior.Enable(TestBehaviourEnabledApp.AppExe); } public void Dispose() { App?.Dispose(); + TestBehaviourEnabledApp?.Dispose(); } } } diff --git a/src/installer/tests/HostActivation.Tests/NativeHostApis.cs b/src/installer/tests/HostActivation.Tests/NativeHostApis.cs index e8b071b8fc7e83..35b73c5fc1dd2e 100644 --- a/src/installer/tests/HostActivation.Tests/NativeHostApis.cs +++ b/src/installer/tests/HostActivation.Tests/NativeHostApis.cs @@ -4,12 +4,15 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using FluentAssertions; using Microsoft.DotNet.Cli.Build; +using Microsoft.DotNet.CoreSetup.Test; +using Microsoft.DotNet.CoreSetup.Test.HostActivation; using Microsoft.DotNet.TestUtils; using Xunit; -namespace Microsoft.DotNet.CoreSetup.Test.HostActivation +namespace HostActivation.Tests { internal class ApiNames { @@ -21,6 +24,7 @@ internal class ApiNames public class NativeHostApis : IClassFixture { + private const string NoGlobalJson = ""; private SharedTestState sharedTestState; public NativeHostApis(SharedTestState fixture) @@ -32,12 +36,13 @@ internal sealed class SdkAndFrameworkFixture : IDisposable { private readonly TestArtifact _artifact; - public string EmptyGlobalJsonDir => Path.Combine(_artifact.Location, "wd"); - + // Versions are assumed to be in ascending order. We use these properties to check against the + // expected values passed to hostfxr API callbacks in the expected order. public string ExeDir => Path.Combine(_artifact.Location, "ed"); - public string LocalSdkDir => Path.Combine(ExeDir, "sdk"); + public string LocalSdkDir { get; } public string LocalFrameworksDir => Path.Combine(ExeDir, "shared"); - public string[] LocalSdks = new[] { "0.1.2", "5.6.7-preview", "1.2.3" }; + public string[] LocalSdks = new[] { "0.1.200", "1.2.300", "5.6.701-preview" }; + public IEnumerable LocalSdkPaths => LocalSdks.Select(sdk => Path.Combine(LocalSdkDir, sdk)); public List<(string fwName, string[] fwVersions)> LocalFrameworks = new List<(string fwName, string[] fwVersions)>() { @@ -45,52 +50,15 @@ internal sealed class SdkAndFrameworkFixture : IDisposable ("HostFxr.Test.C", new[] { "3.0.0" }) }; - public string ProgramFiles => Path.Combine(_artifact.Location, "pf"); - public string ProgramFilesGlobalSdkDir => Path.Combine(ProgramFiles, "dotnet", "sdk"); - public string ProgramFilesGlobalFrameworksDir => Path.Combine(ProgramFiles, "dotnet", "shared"); - public string[] ProgramFilesGlobalSdks = new[] { "4.5.6", "1.2.3", "2.3.4-preview" }; - public List<(string fwName, string[] fwVersions)> ProgramFilesGlobalFrameworks = - new List<(string fwName, string[] fwVersions)>() - { - ("HostFxr.Test.A", new[] { "1.2.3", "3.0.0" }), - ("HostFxr.Test.B", new[] { "5.6.7-A" }) - }; - - public string SelfRegistered => Path.Combine(_artifact.Location, "sr"); - public string SelfRegisteredGlobalSdkDir => Path.Combine(SelfRegistered, "sdk"); - public string[] SelfRegisteredGlobalSdks = new[] { "3.0.0", "15.1.4-preview", "5.6.7" }; - public SdkAndFrameworkFixture() { _artifact = TestArtifact.Create(nameof(SdkAndFrameworkFixture)); - Directory.CreateDirectory(EmptyGlobalJsonDir); - - // start with an empty global.json, it will be ignored, but prevent one lying on disk - // on a given machine from impacting the test. - GlobalJson.CreateEmpty(EmptyGlobalJsonDir); - - foreach (string sdk in ProgramFilesGlobalSdks) - { - AddSdkDirectory(ProgramFilesGlobalSdkDir, sdk); - } - foreach (string sdk in SelfRegisteredGlobalSdks) - { - AddSdkDirectory(SelfRegisteredGlobalSdkDir, sdk); - } - foreach (string sdk in LocalSdks) - { - AddSdkDirectory(LocalSdkDir, sdk); - } + LocalSdkDir = CreateSdkDirectories(ExeDir, LocalSdks); // Empty SDK directory - this should not be recognized as a valid SDK directory Directory.CreateDirectory(Path.Combine(LocalSdkDir, "9.9.9")); - foreach ((string fwName, string[] fwVersions) in ProgramFilesGlobalFrameworks) - { - foreach (string fwVersion in fwVersions) - AddFrameworkDirectory(ProgramFilesGlobalFrameworksDir, fwName, fwVersion); - } foreach ((string fwName, string[] fwVersions) in LocalFrameworks) { foreach (string fwVersion in fwVersions) @@ -100,18 +68,29 @@ public SdkAndFrameworkFixture() Directory.CreateDirectory(Path.Combine(LocalFrameworksDir, fwName, "9.9.9")); } - static void AddSdkDirectory(string sdkDir, string version) + static void AddFrameworkDirectory(string frameworkDir, string name, string version) { - string versionDir = Path.Combine(sdkDir, version); + string versionDir = Path.Combine(frameworkDir, name, version); Directory.CreateDirectory(versionDir); - File.WriteAllText(Path.Combine(versionDir, "dotnet.dll"), string.Empty); + File.WriteAllText(Path.Combine(versionDir, $"{name}.deps.json"), string.Empty); } + } - static void AddFrameworkDirectory(string frameworkDir, string name, string version) + public static string CreateSdkDirectories(string root, string[] versions) + { + string sdkDirectory = Path.Combine(root, "sdk"); + foreach (string sdk in versions) { - string versionDir = Path.Combine(frameworkDir, name, version); + AddSdkDirectory(sdkDirectory, sdk); + } + + return sdkDirectory; + + static void AddSdkDirectory(string sdkDir, string version) + { + string versionDir = Path.Combine(sdkDir, version); Directory.CreateDirectory(versionDir); - File.WriteAllText(Path.Combine(versionDir, $"{name}.deps.json"), string.Empty); + File.WriteAllText(Path.Combine(versionDir, "dotnet.dll"), string.Empty); } } @@ -121,43 +100,13 @@ public void Dispose() } } - [Fact] - [PlatformSpecific(TestPlatforms.Windows)] // The test setup only works on Windows (and MLL was Windows-only anyway) - public void Hostfxr_get_available_sdks_with_multilevel_lookup() - { - // Starting with .NET 7, multi-level lookup is completely disabled for hostfxr API calls. - // This test is still valuable to validate that it is in fact disabled - var f = sharedTestState.SdkAndFrameworkFixture; - string expectedList = string.Join(';', new[] - { - Path.Combine(f.LocalSdkDir, "0.1.2"), - Path.Combine(f.LocalSdkDir, "1.2.3"), - Path.Combine(f.LocalSdkDir, "5.6.7-preview"), - }); - - string api = ApiNames.hostfxr_get_available_sdks; - sharedTestState.TestBehaviorEnabledDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, api, f.ExeDir) - .EnvironmentVariable("TEST_MULTILEVEL_LOOKUP_PROGRAM_FILES", f.ProgramFiles) - .EnvironmentVariable("TEST_MULTILEVEL_LOOKUP_SELF_REGISTERED", f.SelfRegistered) - .EnableTracingAndCaptureOutputs() - .Execute() - .Should().Pass() - .And.ReturnStatusCode(api, Constants.ErrorCode.Success) - .And.HaveStdOutContaining($"{api} sdks:[{expectedList}]"); - } - [Fact] public void Hostfxr_get_available_sdks() { // Get SDKs sorted by ascending version var f = sharedTestState.SdkAndFrameworkFixture; - string expectedList = string.Join(';', new[] - { - Path.Combine(f.LocalSdkDir, "0.1.2"), - Path.Combine(f.LocalSdkDir, "1.2.3"), - Path.Combine(f.LocalSdkDir, "5.6.7-preview"), - }); + string expectedList = string.Join(';', f.LocalSdkPaths); string api = ApiNames.hostfxr_get_available_sdks; TestContext.BuiltDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, api, f.ExeDir) @@ -169,18 +118,19 @@ public void Hostfxr_get_available_sdks() } [Fact] - public void Hostfxr_resolve_sdk2_without_global_json_or_flags() + public void Hostfxr_resolve_sdk2_NoGlobalJson() { - // with no global.json and no flags, pick latest SDK + // With no global.json and no flags, pick latest SDK var f = sharedTestState.SdkAndFrameworkFixture; string expectedData = string.Join(';', new[] { - ("resolved_sdk_dir", Path.Combine(f.LocalSdkDir, "5.6.7-preview")), + ("resolved_sdk_dir", Path.Combine(f.LocalSdkDir, f.LocalSdks[^1])), + ("global_json_state", "not_found"), }); string api = ApiNames.hostfxr_resolve_sdk2; - TestContext.BuiltDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, api, f.ExeDir, f.EmptyGlobalJsonDir, "0") + TestContext.BuiltDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, api, f.ExeDir, NoGlobalJson, "0") .EnableTracingAndCaptureOutputs() .Execute() .Should().Pass() @@ -189,18 +139,19 @@ public void Hostfxr_resolve_sdk2_without_global_json_or_flags() } [Fact] - public void Hostfxr_resolve_sdk2_without_global_json_and_disallowing_previews() + public void Hostfxr_resolve_sdk2_NoGlobalJson_DisallowPrerelease() { - // Without global.json and disallowing previews, pick latest non-preview + // With no global.json and disallowing previews, pick latest non-preview var f = sharedTestState.SdkAndFrameworkFixture; string expectedData = string.Join(';', new[] { - ("resolved_sdk_dir", Path.Combine(f.LocalSdkDir, "1.2.3")) + ("resolved_sdk_dir", Path.Combine(f.LocalSdkDir, "1.2.300")), + ("global_json_state", "not_found"), }); string api = ApiNames.hostfxr_resolve_sdk2; - TestContext.BuiltDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, api, f.ExeDir, f.EmptyGlobalJsonDir, "disallow_prerelease") + TestContext.BuiltDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, api, f.ExeDir, NoGlobalJson, "disallow_prerelease") .EnableTracingAndCaptureOutputs() .Execute() .Should().Pass() @@ -209,7 +160,7 @@ public void Hostfxr_resolve_sdk2_without_global_json_and_disallowing_previews() } [Fact] - public void Hostfxr_resolve_sdk2_with_global_json_and_disallowing_previews() + public void Hostfxr_resolve_sdk2_GlobalJson_DisallowPrerelease() { // With global.json specifying a preview, roll forward to preview // since flag has no impact if global.json specifies a preview. @@ -218,13 +169,14 @@ public void Hostfxr_resolve_sdk2_with_global_json_and_disallowing_previews() var f = sharedTestState.SdkAndFrameworkFixture; using (TestArtifact workingDir = TestArtifact.Create(nameof(workingDir))) { - string requestedVersion = "5.6.6-preview"; + string requestedVersion = "5.6.700-preview"; string globalJson = GlobalJson.CreateWithVersion(workingDir.Location, requestedVersion); string expectedData = string.Join(';', new[] { - ("resolved_sdk_dir", Path.Combine(f.LocalSdkDir, "5.6.7-preview")), + ("resolved_sdk_dir", Path.Combine(f.LocalSdkDir, "5.6.701-preview")), ("global_json_path", globalJson), ("requested_version", requestedVersion), + ("global_json_state", "valid"), }); string api = ApiNames.hostfxr_resolve_sdk2; @@ -246,11 +198,16 @@ public void Hostfxr_resolve_sdk2_GlobalJson_Paths() var f = sharedTestState.SdkAndFrameworkFixture; using (TestArtifact workingDir = TestArtifact.Create(nameof(workingDir))) { - string globalJson = GlobalJson.Write(workingDir.Location, new GlobalJson.Sdk() { Paths = [ f.SelfRegistered, f.LocalSdkDir ] }); + string customSdkRoot = workingDir.GetUniqueSubdirectory("custom_paths"); + string[] versions = [ "3.0.100", "5.6.700", "15.1.400-preview" ]; + string customSdkDirectory = SdkAndFrameworkFixture.CreateSdkDirectories(customSdkRoot, versions); + + string globalJson = GlobalJson.Write(workingDir.Location, new GlobalJson.Sdk() { Paths = [ customSdkRoot, f.LocalSdkDir ] }); string expectedData = string.Join(';', new[] { - ("resolved_sdk_dir", Path.Combine(f.SelfRegisteredGlobalSdkDir, "15.1.4-preview")), - ("global_json_path", globalJson) + ("resolved_sdk_dir", Path.Combine(customSdkDirectory, versions[^1])), + ("global_json_path", globalJson), + ("global_json_state", "valid"), }); string api = ApiNames.hostfxr_resolve_sdk2; @@ -264,84 +221,101 @@ public void Hostfxr_resolve_sdk2_GlobalJson_Paths() } [Fact] - public void Hostfxr_corehost_set_error_writer_test() + public void Hostfxr_resolve_sdk2_GlobalJson_InvalidJson() { - TestContext.BuiltDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, "Test_hostfxr_set_error_writer") - .EnableTracingAndCaptureOutputs() - .Execute() - .Should().Pass(); + // With global.json with malformed JSON + // Pick latest SDK (invalid global.json ignored), report invalid JSON for global.json + + var f = sharedTestState.SdkAndFrameworkFixture; + using (TestArtifact workingDir = TestArtifact.Create(nameof(Hostfxr_resolve_sdk2_GlobalJson_InvalidJson))) + { + GlobalJson.Write(workingDir.Location, "{ \"sdk\": { }"); + string expectedData = string.Join(';', new[] + { + ("resolved_sdk_dir", Path.Combine(f.LocalSdkDir, "5.6.701-preview")), + ("global_json_state", "invalid_json"), + }); + + string api = ApiNames.hostfxr_resolve_sdk2; + TestContext.BuiltDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, api, f.ExeDir, workingDir.Location, "0") + .EnableTracingAndCaptureOutputs() + .Execute() + .Should().Pass() + .And.ReturnStatusCode(api, Constants.ErrorCode.Success) + .And.HaveStdOutContaining($"{api} data:[{expectedData}]"); + } } [Fact] - public void Hostfxr_get_dotnet_environment_info_dotnet_root_only() + public void Hostfxr_resolve_sdk2_GlobalJson_InvalidData() { + // With global.json with invalid version value + // Pick latest SDK (invalid global.json ignored), report invalid data for global.json + var f = sharedTestState.SdkAndFrameworkFixture; - string expectedSdkVersions = string.Join(";", new[] + using (TestArtifact workingDir = TestArtifact.Create(nameof(Hostfxr_resolve_sdk2_GlobalJson_InvalidData))) { - "0.1.2", - "1.2.3", - "5.6.7-preview" - }); + string invalidVersion = "invalid"; + GlobalJson.CreateWithVersion(workingDir.Location, invalidVersion); + string expectedData = string.Join(';', new[] + { + ("resolved_sdk_dir", Path.Combine(f.LocalSdkDir, "5.6.701-preview")), + ("global_json_state", "invalid_data"), + }); - string expectedSdkPaths = string.Join(';', new[] - { - Path.Combine(f.LocalSdkDir, "0.1.2"), - Path.Combine(f.LocalSdkDir, "1.2.3"), - Path.Combine(f.LocalSdkDir, "5.6.7-preview"), - }); + string api = ApiNames.hostfxr_resolve_sdk2; + TestContext.BuiltDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, api, f.ExeDir, workingDir.Location, "0") + .EnableTracingAndCaptureOutputs() + .Execute() + .Should().Pass() + .And.ReturnStatusCode(api, Constants.ErrorCode.Success) + .And.HaveStdOutContaining($"{api} data:[{expectedData}]"); + } + } - string expectedFrameworkNames = string.Join(';', new[] - { - "HostFxr.Test.B", - "HostFxr.Test.B", - "HostFxr.Test.C" - }); + [Fact] + public void Hostfxr_resolve_sdk2_GlobalJson_InvalidDataNoFallback() + { + // With global.json with invalid version value - feature band < 1 + // No match, report invalid data for global.json - string expectedFrameworkVersions = string.Join(';', new[] + var f = sharedTestState.SdkAndFrameworkFixture; + using (TestArtifact workingDir = TestArtifact.Create(nameof(Hostfxr_resolve_sdk2_GlobalJson_InvalidData))) { - "4.0.0", - "5.6.7-A", - "3.0.0" - }); + string invalidVersion = "1.2.0"; + string globalJson = GlobalJson.CreateWithVersion(workingDir.Location, invalidVersion); + string expectedData = string.Join(';', new[] + { + ("global_json_path", globalJson), + ("requested_version", invalidVersion), + ("global_json_state", "__invalid_data_no_fallback"), + }); - string expectedFrameworkPaths = string.Join(';', new[] - { - Path.Combine(f.LocalFrameworksDir, "HostFxr.Test.B"), - Path.Combine(f.LocalFrameworksDir, "HostFxr.Test.B"), - Path.Combine(f.LocalFrameworksDir, "HostFxr.Test.C") - }); + string api = ApiNames.hostfxr_resolve_sdk2; + TestContext.BuiltDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, api, f.ExeDir, workingDir.Location, "0") + .EnableTracingAndCaptureOutputs() + .Execute() + .Should().Pass() + .And.ReturnStatusCode(api, Constants.ErrorCode.SdkResolveFailure) + .And.HaveStdOutContaining($"{api} data:[{expectedData}]"); + } + } - string api = ApiNames.hostfxr_get_dotnet_environment_info; - TestContext.BuiltDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, api, f.ExeDir) + [Fact] + public void Hostfxr_corehost_set_error_writer_test() + { + TestContext.BuiltDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, "Test_hostfxr_set_error_writer") .EnableTracingAndCaptureOutputs() .Execute() - .Should().Pass() - .And.ReturnStatusCode(api, Constants.ErrorCode.Success) - .And.HaveStdOutContaining($"{api} sdk versions:[{expectedSdkVersions}]") - .And.HaveStdOutContaining($"{api} sdk paths:[{expectedSdkPaths}]") - .And.HaveStdOutContaining($"{api} framework names:[{expectedFrameworkNames}]") - .And.HaveStdOutContaining($"{api} framework versions:[{expectedFrameworkVersions}]") - .And.HaveStdOutContaining($"{api} framework paths:[{expectedFrameworkPaths}]"); + .Should().Pass(); } [Fact] - [PlatformSpecific(TestPlatforms.Windows)] // The test setup only works on Windows (and MLL was Windows-only anyway) - public void Hostfxr_get_dotnet_environment_info_with_multilevel_lookup_with_dotnet_root() + public void Hostfxr_get_dotnet_environment_info_dotnet_root_only() { var f = sharedTestState.SdkAndFrameworkFixture; - string expectedSdkVersions = string.Join(';', new[] - { - "0.1.2", - "1.2.3", - "5.6.7-preview", - }); - - string expectedSdkPaths = string.Join(';', new[] - { - Path.Combine(f.LocalSdkDir, "0.1.2"), - Path.Combine(f.LocalSdkDir, "1.2.3"), - Path.Combine(f.LocalSdkDir, "5.6.7-preview"), - }); + string expectedSdkVersions = string.Join(";", f.LocalSdks); + string expectedSdkPaths = string.Join(';', f.LocalSdkPaths); string expectedFrameworkNames = string.Join(';', new[] { @@ -365,9 +339,7 @@ public void Hostfxr_get_dotnet_environment_info_with_multilevel_lookup_with_dotn }); string api = ApiNames.hostfxr_get_dotnet_environment_info; - sharedTestState.TestBehaviorEnabledDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, new[] { api, f.ExeDir }) - .EnvironmentVariable("TEST_MULTILEVEL_LOOKUP_PROGRAM_FILES", f.ProgramFiles) - .EnvironmentVariable("TEST_MULTILEVEL_LOOKUP_SELF_REGISTERED", f.SelfRegistered) + TestContext.BuiltDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, api, f.ExeDir) .EnableTracingAndCaptureOutputs() .Execute() .Should().Pass() @@ -379,29 +351,6 @@ public void Hostfxr_get_dotnet_environment_info_with_multilevel_lookup_with_dotn .And.HaveStdOutContaining($"{api} framework paths:[{expectedFrameworkPaths}]"); } - [Fact] - [PlatformSpecific(TestPlatforms.Windows)] // The test setup only works on Windows (and MLL was Windows-only anyway) - public void Hostfxr_get_dotnet_environment_info_with_multilevel_lookup_only() - { - var f = sharedTestState.SdkAndFrameworkFixture; - - // Multi-level lookup is completely disabled on 7+ - // The test runs the API with the dotnet root directory set to a location which doesn't have any SDKs or frameworks - string api = ApiNames.hostfxr_get_dotnet_environment_info; - sharedTestState.TestBehaviorEnabledDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, api, sharedTestState.HostApiInvokerApp.Location) - .EnvironmentVariable("TEST_MULTILEVEL_LOOKUP_PROGRAM_FILES", f.ProgramFiles) - .EnvironmentVariable("TEST_MULTILEVEL_LOOKUP_SELF_REGISTERED", f.SelfRegistered) - .EnableTracingAndCaptureOutputs() - .Execute() - .Should().Pass() - .And.ReturnStatusCode(api, Constants.ErrorCode.Success) - .And.HaveStdOutContaining($"{api} sdk versions:[]") - .And.HaveStdOutContaining($"{api} sdk paths:[]") - .And.HaveStdOutContaining($"{api} framework names:[]") - .And.HaveStdOutContaining($"{api} framework versions:[]") - .And.HaveStdOutContaining($"{api} framework paths:[]"); - } - [Fact] public void Hostfxr_get_dotnet_environment_info_global_install_path() { @@ -749,6 +698,38 @@ public void Hostfxr_resolve_frameworks_for_runtime_config_InvalidConfig() } } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void Hostfxr_resolve_frameworks_for_runtime_config_MissingVersion(bool selfContained) + { + string api = ApiNames.hostfxr_resolve_frameworks_for_runtime_config; + using (TestArtifact artifact = TestArtifact.Create(api)) + { + // Create a runtimeconfig.json with a framework reference that has no version property + string configPath = Path.Combine(artifact.Location, "test.runtimeconfig.json"); + RuntimeConfig config = RuntimeConfig.FromFile(configPath); + if (selfContained) + { + config.WithIncludedFramework(Constants.MicrosoftNETCoreApp, null); + } + else + { + config.WithFramework(Constants.MicrosoftNETCoreApp, null); + } + + config.Save(); + + TestContext.BuiltDotNet.Exec(sharedTestState.HostApiInvokerApp.AppDll, api, configPath, TestContext.BuiltDotNet.BinPath) + .CaptureStdOut() + .CaptureStdErr() + .Execute() + .Should().Pass() + .And.HaveStdErrContaining($"Framework '{Constants.MicrosoftNETCoreApp}' is missing a version") + .And.ReturnStatusCode(api, Constants.ErrorCode.InvalidConfigFile); + } + } + [Fact] public void Hostpolicy_corehost_set_error_writer_test() { @@ -789,28 +770,16 @@ public class SharedTestState : IDisposable { public TestApp HostApiInvokerApp { get; } - public DotNetCli TestBehaviorEnabledDotNet { get; } - private readonly TestArtifact copiedDotnet; - internal SdkAndFrameworkFixture SdkAndFrameworkFixture { get; } public SharedTestState() { - // Make a copy of the built .NET, as we will enable test-only behaviour - copiedDotnet = TestArtifact.CreateFromCopy(nameof(NativeHostApis), TestContext.BuiltDotNet.BinPath); - TestBehaviorEnabledDotNet = new DotNetCli(copiedDotnet.Location); - - // Enable test-only behavior for the copied .NET. We don't bother disabling the behaviour later, - // as we just delete the entire copy after the tests run. - _ = TestOnlyProductBehavior.Enable(TestBehaviorEnabledDotNet.GreatestVersionHostFxrFilePath); - HostApiInvokerApp = TestApp.CreateFromBuiltAssets("HostApiInvokerApp"); // On non-Windows, we can't just P/Invoke to already loaded hostfxr, so provide the app with // paths to hostfxr so that it can handle resolving the library. RuntimeConfig.FromFile(HostApiInvokerApp.RuntimeConfigJson) .WithProperty("HOSTFXR_PATH", TestContext.BuiltDotNet.GreatestVersionHostFxrFilePath) - .WithProperty("HOSTFXR_PATH_TEST_BEHAVIOR", TestBehaviorEnabledDotNet.GreatestVersionHostFxrFilePath) .Save(); SdkAndFrameworkFixture = new SdkAndFrameworkFixture(); @@ -819,7 +788,6 @@ public SharedTestState() public void Dispose() { HostApiInvokerApp?.Dispose(); - copiedDotnet.Dispose(); SdkAndFrameworkFixture.Dispose(); } } diff --git a/src/installer/tests/HostActivation.Tests/NativeHosting/GetNativeSearchDirectories.cs b/src/installer/tests/HostActivation.Tests/NativeHosting/GetNativeSearchDirectories.cs index 16cf0ee8bb68c8..d382ff9244bd59 100644 --- a/src/installer/tests/HostActivation.Tests/NativeHosting/GetNativeSearchDirectories.cs +++ b/src/installer/tests/HostActivation.Tests/NativeHosting/GetNativeSearchDirectories.cs @@ -125,7 +125,7 @@ public void WithInvalidDepsJson() .And.HaveStdOutContaining($"get_native_search_directories (null,0) returned unexpected error code 0x{Constants.ErrorCode.ResolverInitFailure:x} expected HostApiBufferTooSmall (0x80008098).") .And.HaveStdOutContaining("buffer_size: 0") .And.HaveStdOutContaining("hostfxr reported errors:") - .And.HaveStdOutContaining($"A JSON parsing exception occurred in [{depsJsonFile}], offset 1 (line 1, column 2): Missing a name for object member.") + .And.HaveStdOutContaining($"Failed to parse file [{depsJsonFile}]. JSON parsing exception: Missing a name for object member. [offset 1: line 1, column 2]") .And.HaveStdOutContaining($"Error initializing the dependency resolver: An error occurred while parsing: {depsJsonFile}"); } diff --git a/src/installer/tests/HostActivation.Tests/SDKLookup.cs b/src/installer/tests/HostActivation.Tests/SDKLookup.cs index 29d0eab362664c..d633ec94d8d0f8 100644 --- a/src/installer/tests/HostActivation.Tests/SDKLookup.cs +++ b/src/installer/tests/HostActivation.Tests/SDKLookup.cs @@ -632,7 +632,7 @@ public static IEnumerable InvalidGlobalJsonData yield return new object[] { "{ sdk: { \"version\": \"9999.0.100\" } }", new[] { - "A JSON parsing exception occurred", + "JSON parsing exception:", IgnoringSDKSettings } }; diff --git a/src/installer/tests/HostActivation.Tests/SelfContainedAppLaunch.cs b/src/installer/tests/HostActivation.Tests/SelfContainedAppLaunch.cs index f421335995f696..ba53bd13d33f91 100644 --- a/src/installer/tests/HostActivation.Tests/SelfContainedAppLaunch.cs +++ b/src/installer/tests/HostActivation.Tests/SelfContainedAppLaunch.cs @@ -3,12 +3,15 @@ using System; using System.IO; +using System.Linq; using System.Runtime.InteropServices; using FluentAssertions; using Microsoft.DotNet.Cli.Build.Framework; using Microsoft.DotNet.CoreSetup.Test; using Microsoft.NET.HostModel.AppHost; using Xunit; +using static Microsoft.DotNet.CoreSetup.Test.NetCoreAppBuilder; +using static Microsoft.NET.HostModel.AppHost.HostWriter; namespace HostActivation.Tests { @@ -180,6 +183,51 @@ public void DevicePath() .And.HaveStdOutContaining(TestContext.MicrosoftNETCoreAppVersion); } + [Fact] + public void CustomRuntimeLocation() + { + string subdirectory = "runtime-directory"; + Action customizer = b => + { + // Find the NETCoreApp runtime pack + RuntimeLibraryBuilder netCoreApp = b.RuntimeLibraries.First( + r => r.Type == RuntimeLibraryType.runtimepack.ToString() && r.Name == $"runtimepack.{Constants.MicrosoftNETCoreApp}.Runtime.{TestContext.BuildRID}"); + + // Update all NETCoreApp asset paths to point to the subdirectory + RuntimeAssetGroupBuilder[] groups = [.. netCoreApp.AssemblyGroups, .. netCoreApp.NativeLibraryGroups]; + foreach (RuntimeAssetGroupBuilder group in groups) + { + foreach (RuntimeFileBuilder asset in group.Assets) + { + asset.Path = Path.Join(subdirectory, asset.Path); + } + } + + foreach (ResourceAssemblyBuilder resource in netCoreApp.ResourceAssemblies) + { + resource.Path = Path.Join(subdirectory, resource.Path); + } + }; + + using TestApp app = TestApp.CreateFromBuiltAssets("HelloWorld"); + app.PopulateSelfContained(TestApp.MockedComponent.None, customizer); + app.CreateAppHost(dotNetRootOptions: new() + { + Location = DotNetSearchOptions.SearchLocation.AppRelative, + AppRelativeDotNet = subdirectory + }); + + // Apphost should be able to find hostfxr based on the .NET search options + // Runtime files should be resolved based on relative path in .deps.json + Command.Create(app.AppExe) + .EnableTracingAndCaptureOutputs() + .Execute() + .Should().Pass() + .And.HaveStdOutContaining("Hello World") + .And.HaveStdOutContaining(TestContext.MicrosoftNETCoreAppVersion) + .And.HaveStdErrContaining($"CoreCLR path = '{Path.Join(app.Location, subdirectory, Binaries.CoreClr.FileName)}'"); + } + public class SharedTestState : IDisposable { public TestApp App { get; } diff --git a/src/installer/tests/HostActivation.Tests/Tracing.cs b/src/installer/tests/HostActivation.Tests/Tracing.cs index 9c99d9d68d1b2c..9c0eb97c1f08ab 100644 --- a/src/installer/tests/HostActivation.Tests/Tracing.cs +++ b/src/installer/tests/HostActivation.Tests/Tracing.cs @@ -7,24 +7,18 @@ namespace Microsoft.DotNet.CoreSetup.Test.HostActivation { - public class Tracing : IClassFixture + public class Tracing { - private SharedTestState sharedTestState; + // Trace messages currently expected for running dotnet --list-runtimes + private const string ExpectedVerboseMessage = "--- Executing in muxer mode"; + private const string ExpectedInfoMessage = "--- Invoked dotnet"; - // Trace messages currently expected for a passing app (somewhat randomly selected) - private const string ExpectedVerboseMessage = "--- Begin breadcrumb write"; - private const string ExpectedInfoMessage = "Deps file:"; - private const string ExpectedBadPathMessage = "Unable to open COREHOST_TRACEFILE="; - - public Tracing(Tracing.SharedTestState fixture) - { - sharedTestState = fixture; - } + private const string ExpectedBadPathMessage = "Unable to open specified trace file for writing:"; [Fact] public void TracingOff() { - TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll) + TestContext.BuiltDotNet.Exec("--list-runtimes") .CaptureStdOut() .CaptureStdErr() .Execute() @@ -36,11 +30,10 @@ public void TracingOff() [Fact] public void TracingOnDefault() { - TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll) + TestContext.BuiltDotNet.Exec("--list-runtimes") .EnableTracingAndCaptureOutputs() .Execute() .Should().Pass() - .And.HaveStdOutContaining("Hello World") .And.HaveStdErrContaining(ExpectedInfoMessage) .And.HaveStdErrContaining(ExpectedVerboseMessage); } @@ -48,12 +41,11 @@ public void TracingOnDefault() [Fact] public void TracingOnVerbose() { - TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll) + TestContext.BuiltDotNet.Exec("--list-runtimes") .EnableTracingAndCaptureOutputs() .EnvironmentVariable(Constants.HostTracing.VerbosityEnvironmentVariable, "4") .Execute() .Should().Pass() - .And.HaveStdOutContaining("Hello World") .And.HaveStdErrContaining(ExpectedInfoMessage) .And.HaveStdErrContaining(ExpectedVerboseMessage); } @@ -61,12 +53,11 @@ public void TracingOnVerbose() [Fact] public void TracingOnInfo() { - TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll) + TestContext.BuiltDotNet.Exec("--list-runtimes") .EnableTracingAndCaptureOutputs() .EnvironmentVariable(Constants.HostTracing.VerbosityEnvironmentVariable, "3") .Execute() .Should().Pass() - .And.HaveStdOutContaining("Hello World") .And.HaveStdErrContaining(ExpectedInfoMessage) .And.NotHaveStdErrContaining(ExpectedVerboseMessage); } @@ -74,12 +65,11 @@ public void TracingOnInfo() [Fact] public void TracingOnWarning() { - TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll) + TestContext.BuiltDotNet.Exec("--list-runtimes") .EnableTracingAndCaptureOutputs() .EnvironmentVariable(Constants.HostTracing.VerbosityEnvironmentVariable, "2") .Execute() .Should().Pass() - .And.HaveStdOutContaining("Hello World") .And.NotHaveStdErrContaining(ExpectedInfoMessage) .And.NotHaveStdErrContaining(ExpectedVerboseMessage); } @@ -87,15 +77,13 @@ public void TracingOnWarning() [Fact] public void TracingOnToFileDefault() { - string traceFilePath; - TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll) + TestContext.BuiltDotNet.Exec("--list-runtimes") .EnableHostTracingToFile(out traceFilePath) .CaptureStdOut() .CaptureStdErr() .Execute() .Should().Pass() - .And.HaveStdOutContaining("Hello World") .And.NotHaveStdErrContaining(ExpectedInfoMessage) .And.NotHaveStdErrContaining(ExpectedVerboseMessage) .And.FileExists(traceFilePath) @@ -107,12 +95,11 @@ public void TracingOnToFileDefault() [Fact] public void TracingOnToFileBadPathDefault() { - TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll) + TestContext.BuiltDotNet.Exec("--list-runtimes") .EnableTracingAndCaptureOutputs() .EnvironmentVariable(Constants.HostTracing.TraceFileEnvironmentVariable, "badpath/TracingOnToFileBadPathDefault.log") .Execute() .Should().Pass() - .And.HaveStdOutContaining("Hello World") .And.HaveStdErrContaining(ExpectedInfoMessage) .And.HaveStdErrContaining(ExpectedVerboseMessage) .And.HaveStdErrContaining(ExpectedBadPathMessage); @@ -123,7 +110,7 @@ public void TracingOnToDirectory() { using (TestArtifact directory = TestArtifact.Create("trace")) { - var result = TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll) + var result = TestContext.BuiltDotNet.Exec("--list-runtimes") .EnableHostTracingToPath(directory.Location) .CaptureStdOut() .CaptureStdErr() @@ -131,7 +118,6 @@ public void TracingOnToDirectory() string traceFilePath = Path.Combine(directory.Location, $"{Path.GetFileNameWithoutExtension(Binaries.DotNet.FileName)}.{result.ProcessId}.log"); result.Should().Pass() - .And.HaveStdOutContaining("Hello World") .And.NotHaveStdErrContaining(ExpectedInfoMessage) .And.NotHaveStdErrContaining(ExpectedVerboseMessage) .And.FileExists(traceFilePath) @@ -139,20 +125,16 @@ public void TracingOnToDirectory() } } - public class SharedTestState : IDisposable + [Fact] + public void LegacyVariableName() { - public TestApp App { get; } - - public SharedTestState() - { - App = TestApp.CreateFromBuiltAssets("HelloWorld"); - App.CreateAppHost(); - } - - public void Dispose() - { - App?.Dispose(); - } + TestContext.BuiltDotNet.Exec("--list-runtimes") + .EnvironmentVariable("COREHOST_TRACE", "1") + .CaptureStdErr() + .Execute() + .Should().Pass() + .And.HaveStdErrContaining(ExpectedInfoMessage) + .And.HaveStdErrContaining(ExpectedVerboseMessage); } } } diff --git a/src/installer/tests/Microsoft.NET.HostModel.Tests/Bundle/BundlerConsistencyTests.cs b/src/installer/tests/Microsoft.NET.HostModel.Tests/Bundle/BundlerConsistencyTests.cs index 7cce3c76fdd8bb..44cfdfd95358cf 100644 --- a/src/installer/tests/Microsoft.NET.HostModel.Tests/Bundle/BundlerConsistencyTests.cs +++ b/src/installer/tests/Microsoft.NET.HostModel.Tests/Bundle/BundlerConsistencyTests.cs @@ -116,6 +116,29 @@ public void DuplicateBundleRelativePath_Fails() .And.Contain(sharedTestState.App.AppDll); } + [Fact] + public void FilesWithNonAsciiCharsCanBundle() + { + string appPath = sharedTestState.NonAsciiApp.AppDll; + string systemLibPath = sharedTestState.SystemDll; + + // File specification with non-ASCII characters in the relative paths + var fileSpecs = new FileSpec[] + { + new FileSpec(Binaries.AppHost.FilePath, BundlerHostName), + new FileSpec(appPath, "中文/app.dll"), + new FileSpec(appPath, "rel/中文.dll"), + new FileSpec(systemLibPath, "中文") + }; + + Bundler bundler = CreateBundlerInstance(); + var bundlePath = bundler.GenerateBundle(fileSpecs); + + bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals("中文/app.dll")).Single().Type.Should().Be(FileType.Assembly); + bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals("rel/中文.dll")).Single().Type.Should().Be(FileType.Assembly); + bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals("中文")).Single().Type.Should().Be(FileType.Assembly); + } + [Fact] public void CaseSensitiveBundleRelativePath() { @@ -366,11 +389,13 @@ public class SharedTestState : IDisposable { public const string AppName = "HelloWorld"; public TestApp App { get; } + public TestApp NonAsciiApp { get; } public string SystemDll { get; } public SharedTestState() { App = TestApp.CreateFromBuiltAssets(AppName); + NonAsciiApp = TestApp.CreateFromBuiltAssets("HelloWorld_中文"); SystemDll = Path.Combine(TestContext.BuiltDotNet.GreatestVersionSharedFxPath, "System.dll"); } @@ -378,6 +403,7 @@ public SharedTestState() public void Dispose() { App.Dispose(); + NonAsciiApp.Dispose(); } } } diff --git a/src/installer/tests/TestUtils/Assertions/CommandResultAssertions.cs b/src/installer/tests/TestUtils/Assertions/CommandResultAssertions.cs index 25acf3d3123e32..f2331aec6d69a2 100644 --- a/src/installer/tests/TestUtils/Assertions/CommandResultAssertions.cs +++ b/src/installer/tests/TestUtils/Assertions/CommandResultAssertions.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Linq; using System.Text.RegularExpressions; using FluentAssertions; using FluentAssertions.Execution; @@ -63,7 +62,7 @@ public AndConstraint HaveStdOut(string expectedOutput) public AndConstraint HaveStdOutContaining(string pattern) { - CurrentAssertionChain.ForCondition(Result.StdOut.Contains(pattern)) + CurrentAssertionChain.ForCondition(!string.IsNullOrEmpty(Result.StdOut) && Result.StdOut.Contains(pattern)) .FailWith($"The command output did not contain expected result: '{pattern}'{GetDiagnosticsInfo()}"); return new AndConstraint(this); } @@ -98,7 +97,7 @@ public AndConstraint HaveStdErr() public AndConstraint HaveStdErrContaining(string pattern) { - CurrentAssertionChain.ForCondition(Result.StdErr.Contains(pattern)) + CurrentAssertionChain.ForCondition(!string.IsNullOrEmpty(Result.StdErr) && Result.StdErr.Contains(pattern)) .FailWith($"The command error output did not contain expected result: '{pattern}'{GetDiagnosticsInfo()}"); return new AndConstraint(this); } @@ -154,18 +153,6 @@ public AndConstraint NotFileContains(string path, strin return new AndConstraint(this); } - public string GetDiagnosticsInfo() - => $""" - - File Name: {Result.StartInfo.FileName} - Arguments: {Result.StartInfo.Arguments} - Environment: - {string.Join(Environment.NewLine, Result.StartInfo.Environment.Where(i => i.Key.StartsWith(Constants.DotnetRoot.EnvironmentVariable)).Select(i => $" {i.Key} = {i.Value}"))} - Exit Code: 0x{Result.ExitCode:x} - StdOut: - {Result.StdOut} - StdErr: - {Result.StdErr} - """; + public string GetDiagnosticsInfo() => Result.GetDiagnosticsInfo(); } } diff --git a/src/installer/tests/TestUtils/Assertions/CommandResultExtensions.cs b/src/installer/tests/TestUtils/Assertions/CommandResultExtensions.cs index d0e0175060b893..7ca15639b7dc2d 100644 --- a/src/installer/tests/TestUtils/Assertions/CommandResultExtensions.cs +++ b/src/installer/tests/TestUtils/Assertions/CommandResultExtensions.cs @@ -4,7 +4,6 @@ using FluentAssertions; using FluentAssertions.Execution; using Microsoft.DotNet.Cli.Build.Framework; -using System; namespace Microsoft.DotNet.CoreSetup.Test { @@ -20,10 +19,7 @@ public static CommandResult StdErrAfter(this CommandResult commandResult, string int i = commandResult.StdErr.IndexOf(pattern); i.Should().BeGreaterThanOrEqualTo( 0, - "Trying to filter StdErr after '{0}', but such string can't be found in the StdErr.{1}{2}", - pattern, - Environment.NewLine, - commandResult.StdErr); + $"'{pattern}' should be in StdErr - cannot filter StdErr to after expected string.{commandResult.GetDiagnosticsInfo()}"); string filteredStdErr = commandResult.StdErr.Substring(i); return new CommandResult(commandResult.StartInfo, commandResult.ProcessId, commandResult.ExitCode, commandResult.StdOut, filteredStdErr); diff --git a/src/installer/tests/TestUtils/Command.cs b/src/installer/tests/TestUtils/Command.cs index 416a60dac2bb2a..fdb73494b93a8f 100644 --- a/src/installer/tests/TestUtils/Command.cs +++ b/src/installer/tests/TestUtils/Command.cs @@ -9,6 +9,8 @@ using System.Runtime.CompilerServices; using System.Text; using System.Threading; +using Microsoft.DotNet.CoreSetup.Test; +using static Microsoft.DotNet.CoreSetup.Test.Constants; namespace Microsoft.DotNet.Cli.Build.Framework { @@ -22,11 +24,6 @@ public class Command public Process Process { get; } - // Priority order of runnable suffixes to look for and run - private static readonly string[] RunnableSuffixes = OperatingSystem.IsWindows() - ? new string[] { ".exe", ".cmd", ".bat" } - : new string[] { string.Empty }; - private Command(string executable, string args) { // Set the things we need @@ -54,84 +51,17 @@ public static Command Create(string executable, IEnumerable args) public static Command Create(string executable, string args) { - ResolveExecutablePath(ref executable, ref args); - - return new Command(executable, args); - } - - private static void ResolveExecutablePath(ref string executable, ref string args) - { - foreach (string suffix in RunnableSuffixes) - { - var fullExecutable = Path.GetFullPath(Path.Combine( - AppContext.BaseDirectory, executable + suffix)); - - if (File.Exists(fullExecutable)) - { - executable = fullExecutable; - - // In priority order we've found the best runnable extension, so break. - break; - } - } - - // On Windows, we want to avoid using "cmd" if possible (it mangles the colors, and a bunch of other things) - // So, do a quick path search to see if we can just directly invoke it - var useCmd = ShouldUseCmd(executable); - - if (useCmd) - { - var comSpec = System.Environment.GetEnvironmentVariable("ComSpec"); - - // cmd doesn't like "foo.exe ", so we need to ensure that if - // args is empty, we just run "foo.exe" - if (!string.IsNullOrEmpty(args)) - { - executable = (executable + " " + args).Replace("\"", "\\\""); - } - args = $"/C \"{executable}\""; - executable = comSpec; - } - } - - private static bool ShouldUseCmd(string executable) - { - if (OperatingSystem.IsWindows()) - { - var extension = Path.GetExtension(executable); - if (!string.IsNullOrEmpty(extension)) - { - return !string.Equals(extension, ".exe", StringComparison.Ordinal); - } - else if (executable.Contains(Path.DirectorySeparatorChar)) - { - // It's a relative path without an extension - if (File.Exists(executable + ".exe")) - { - // It refers to an exe! - return false; - } - } - else - { - // Search the path to see if we can find it - foreach (var path in System.Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator)) - { - var candidate = Path.Combine(path, executable + ".exe"); - if (File.Exists(candidate)) - { - // We found an exe! - return false; - } - } - } - - // It's a non-exe :( - return true; - } - - // Non-windows never uses cmd - return false; + // Clear out .NET root and tracing environment variables by default + string oldPrefix = "COREHOST_"; + string prefix = "DOTNET_HOST_"; + return new Command(executable, args) + .DotNetRoot(null) + .RemoveEnvironmentVariable(HostTracing.TraceLevelEnvironmentVariable) + .RemoveEnvironmentVariable(HostTracing.TraceFileEnvironmentVariable) + .RemoveEnvironmentVariable(HostTracing.VerbosityEnvironmentVariable) + .RemoveEnvironmentVariable(HostTracing.TraceLevelEnvironmentVariable.Replace(prefix, oldPrefix)) + .RemoveEnvironmentVariable(HostTracing.TraceFileEnvironmentVariable.Replace(prefix, oldPrefix)) + .RemoveEnvironmentVariable(HostTracing.VerbosityEnvironmentVariable.Replace(prefix, oldPrefix)); } public Command DisableDumps() diff --git a/src/installer/tests/TestUtils/CommandResult.cs b/src/installer/tests/TestUtils/CommandResult.cs index ac2f959835fca0..5e850ab4220fa2 100644 --- a/src/installer/tests/TestUtils/CommandResult.cs +++ b/src/installer/tests/TestUtils/CommandResult.cs @@ -2,8 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Text; using System.Diagnostics; +using System.Linq; +using System.Text; namespace Microsoft.DotNet.Cli.Build.Framework { @@ -23,5 +24,19 @@ public CommandResult(ProcessStartInfo startInfo, int pid, int exitCode, string s StdOut = stdOut; StdErr = stdErr; } + + internal string GetDiagnosticsInfo() + => $""" + + File Name: {StartInfo.FileName} + Arguments: {StartInfo.Arguments} + Environment: + {string.Join(Environment.NewLine, StartInfo.Environment.Where(i => i.Key.StartsWith("DOTNET_", OperatingSystem.IsWindows() ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)).Select(i => $" {i.Key} = {i.Value}"))} + Exit Code: 0x{ExitCode:x} + StdOut: + {StdOut} + StdErr: + {StdErr} + """; } } diff --git a/src/installer/tests/TestUtils/Constants.cs b/src/installer/tests/TestUtils/Constants.cs index 9eb5b6e661e32f..4d3be90319ad15 100644 --- a/src/installer/tests/TestUtils/Constants.cs +++ b/src/installer/tests/TestUtils/Constants.cs @@ -103,9 +103,9 @@ public static class MultilevelLookup public static class HostTracing { - public const string TraceLevelEnvironmentVariable = "COREHOST_TRACE"; - public const string TraceFileEnvironmentVariable = "COREHOST_TRACEFILE"; - public const string VerbosityEnvironmentVariable = "COREHOST_TRACE_VERBOSITY"; + public const string TraceLevelEnvironmentVariable = "DOTNET_HOST_TRACE"; + public const string TraceFileEnvironmentVariable = "DOTNET_HOST_TRACEFILE"; + public const string VerbosityEnvironmentVariable = "DOTNET_HOST_TRACE_VERBOSITY"; } public static class DotnetRoot @@ -128,6 +128,7 @@ public static class ErrorCode public const int AppArgNotRunnable = unchecked((int)0x80008094); public const int AppHostExeNotBoundFailure = unchecked((int)0x80008095); public const int FrameworkMissingFailure = unchecked((int)0x80008096); + public const int SdkResolveFailure = unchecked((int)0x8000809b); public const int FrameworkCompatFailure = unchecked((int)0x8000809c); public const int BundleExtractionFailure = unchecked((int)0x8000809f); diff --git a/src/installer/tests/TestUtils/DotNetBuilder.cs b/src/installer/tests/TestUtils/DotNetBuilder.cs index b761b76b517c4b..db9a316e2704fa 100644 --- a/src/installer/tests/TestUtils/DotNetBuilder.cs +++ b/src/installer/tests/TestUtils/DotNetBuilder.cs @@ -140,13 +140,13 @@ public DotNetBuilder AddMicrosoftNETCoreAppFrameworkMockCoreClr(string version, // ./shared/Microsoft.NETCore.App//coreclr.dll - this is a mock, will not actually run CoreClr .WithAsset((new NetCoreAppBuilder.RuntimeFileBuilder($"runtimes/{currentRid}/native/{Binaries.CoreClr.FileName}")) .CopyFromFile(Binaries.CoreClr.MockPath) - .WithFileOnDiskPath(Binaries.CoreClr.FileName)))) + .WithLocalPath(Binaries.CoreClr.FileName)))) .WithPackage($"runtime.{currentRid}.Microsoft.NETCore.DotNetHostPolicy", version, p => p .WithNativeLibraryGroup(null, g => g // ./shared/Microsoft.NETCore.App//hostpolicy.dll - this is the real component and will load CoreClr library .WithAsset((new NetCoreAppBuilder.RuntimeFileBuilder($"runtimes/{currentRid}/native/{Binaries.HostPolicy.FileName}")) .CopyFromFile(Binaries.HostPolicy.FilePath) - .WithFileOnDiskPath(Binaries.HostPolicy.FileName)))) + .WithLocalPath(Binaries.HostPolicy.FileName)))) .WithCustomizer(customizer) .Build(new TestApp(netCoreAppPath, "Microsoft.NETCore.App")); diff --git a/src/installer/tests/TestUtils/NetCoreAppBuilder.cs b/src/installer/tests/TestUtils/NetCoreAppBuilder.cs index 636b8260af6af0..7ddabe8d5e7ae2 100644 --- a/src/installer/tests/TestUtils/NetCoreAppBuilder.cs +++ b/src/installer/tests/TestUtils/NetCoreAppBuilder.cs @@ -6,6 +6,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.Json; +using System.Text.Json.Nodes; namespace Microsoft.DotNet.CoreSetup.Test { @@ -16,6 +18,7 @@ public class NetCoreAppBuilder public string Runtime { get; set; } private TestApp _sourceApp; + private bool _includeLocalPathsInDepsJson = true; public Action RuntimeConfigCustomizer { get; set; } @@ -33,7 +36,9 @@ public abstract class FileBuilder public string Path { get; set; } public string SourcePath { get; set; } - public string FileOnDiskPath { get; set; } + + // If set, path relative to the app location where the file will be created. + public string LocalPath { get; set; } public FileBuilder(string path) { @@ -42,14 +47,14 @@ public FileBuilder(string path) internal void Build(BuildContext context) { - string path = ToDiskPath(FileOnDiskPath ?? Path); + string path = ToDiskPath(LocalPath ?? Path); string absolutePath = System.IO.Path.Combine(context.App.Location, path); if (SourcePath != null) { FileUtils.EnsureFileDirectoryExists(absolutePath); File.Copy(SourcePath, absolutePath); } - else if ((FileOnDiskPath == null || FileOnDiskPath.Length > 0) + else if ((LocalPath == null || LocalPath.Length > 0) && !File.Exists(absolutePath)) { FileUtils.CreateEmptyFile(absolutePath); @@ -76,15 +81,15 @@ public T CopyFromFile(string sourcePath) return this as T; } - public T WithFileOnDiskPath(string relativePath) + public T WithLocalPath(string localPath) { - FileOnDiskPath = relativePath; + LocalPath = localPath; return this as T; } public T NotOnDisk() { - FileOnDiskPath = string.Empty; + LocalPath = string.Empty; return this as T; } } @@ -109,6 +114,8 @@ public RuntimeFileBuilder WithVersion(string assemblyVersion, string fileVersion internal new RuntimeFile Build(BuildContext context) { base.Build(context); + + // TODO: Pass in LocalPath once we can upgrade to a Microsoft.Extensions.DependencyModel version that supports it. return new RuntimeFile(Path, AssemblyVersion, FileVersion); } } @@ -136,6 +143,8 @@ public ResourceAssemblyBuilder WithLocale(string locale) internal new ResourceAssembly Build(BuildContext context) { base.Build(context); + + // TODO: Pass in LocalPath once we can upgrade to a Microsoft.Extensions.DependencyModel version that supports it. return new ResourceAssembly(Path, Locale); } } @@ -367,6 +376,12 @@ public NetCoreAppBuilder WithStandardRuntimeFallbacks() .WithRuntimeFallbacks("osx-x64", "osx", "any"); } + public NetCoreAppBuilder WithLocalPathsInDepsJson(bool includeLocalPaths) + { + _includeLocalPathsInDepsJson = includeLocalPaths; + return this; + } + public NetCoreAppBuilder WithCustomizer(Action customizer) { customizer?.Invoke(this); @@ -418,7 +433,60 @@ public TestApp Build(TestApp testApp) writer.Write(dependencyContext, stream); } + // Add localPath properties + // TODO: Remove once we can upgrade to a Microsoft.Extensions.DependencyModel version that supports localPath. + if (_includeLocalPathsInDepsJson) + { + AddLocalPathsToJson(testApp.DepsJson, buildContext); + } + return testApp; } + + private void AddLocalPathsToJson(string depsJsonPath, BuildContext buildContext) + { + // Read the generated JSON + string jsonContent = File.ReadAllText(depsJsonPath); + + // Parse and modify the JSON to add localPath properties + JsonNode rootNode = JsonNode.Parse(jsonContent); + JsonNode targets = rootNode["targets"][$"{Framework}{(Runtime is null ? "" : $"/{Runtime}")}"]; + foreach (var l in RuntimeLibraries) + { + JsonNode library = targets[$"{l.Name}/{l.Version}"]; + AddLocalPathsForFiles(library, l.AssemblyGroups, "runtime"); + AddLocalPathsForFiles(library, l.NativeLibraryGroups, "native"); + + // Add localPath for resources + JsonNode assets = library["resources"]; + foreach (var resource in l.ResourceAssemblies) + { + if (string.IsNullOrEmpty(resource.LocalPath)) + continue; + + assets[resource.Path]["localPath"] = resource.LocalPath; + } + } + + // Write the modified JSON back to the file + var options = new JsonSerializerOptions { WriteIndented = true }; + string modifiedJson = rootNode.ToJsonString(options); + File.WriteAllText(depsJsonPath, modifiedJson); + } + + private void AddLocalPathsForFiles(JsonNode library, List groups, string assetType) + { + foreach (var group in groups) + { + JsonNode assets = library[!string.IsNullOrEmpty(group.Runtime) ? "runtimeTargets" : assetType]; + foreach (var asset in group.Assets) + { + if (string.IsNullOrEmpty(asset.LocalPath)) + continue; + + assets[asset.Path]["localPath"] = asset.LocalPath.Replace('\\', '/'); // .deps.json explicitly uses forward slashes; + } + } + } } } diff --git a/src/installer/tests/TestUtils/RuntimeConfig.cs b/src/installer/tests/TestUtils/RuntimeConfig.cs index 7f13e3dab88538..3ff9ab746b99f1 100644 --- a/src/installer/tests/TestUtils/RuntimeConfig.cs +++ b/src/installer/tests/TestUtils/RuntimeConfig.cs @@ -46,7 +46,7 @@ public Framework WithApplyPatches(bool? value) return this; } - internal JsonObject ToJson() + public JsonObject ToJson() { JsonObject frameworkReference = new(); diff --git a/src/installer/tests/TestUtils/TestFileBackup.cs b/src/installer/tests/TestUtils/TestFileBackup.cs index c17f5d96f7f18f..bea70071f233b2 100644 --- a/src/installer/tests/TestUtils/TestFileBackup.cs +++ b/src/installer/tests/TestUtils/TestFileBackup.cs @@ -116,7 +116,7 @@ private static void CopyOverDirectory(string source, string destination) } } - private static void RetryOnIOError(Func action, string errorMessage, int maxRetries = 5) + private static void RetryOnIOError(Func action, string errorMessage, int maxRetries = 25) { IOException exception = null; for (int i = 0; i < maxRetries; i++) diff --git a/src/libraries/Common/src/Internal/Cryptography/PkcsHelpers.cs b/src/libraries/Common/src/Internal/Cryptography/PkcsHelpers.cs index 10bc0179aff2cf..ea4d04400092c3 100644 --- a/src/libraries/Common/src/Internal/Cryptography/PkcsHelpers.cs +++ b/src/libraries/Common/src/Internal/Cryptography/PkcsHelpers.cs @@ -223,7 +223,7 @@ internal static string GetOidFromHashAlgorithm(HashAlgorithmName algName) return Oids.Sha384; if (algName == HashAlgorithmName.SHA512) return Oids.Sha512; -#if NET8_0_OR_GREATER +#if NET if (algName == HashAlgorithmName.SHA3_256) return Oids.Sha3_256; if (algName == HashAlgorithmName.SHA3_384) diff --git a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Ssl.cs b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Ssl.cs index d663095cd8cead..91b7136059f24d 100644 --- a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Ssl.cs +++ b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Ssl.cs @@ -78,6 +78,7 @@ private static unsafe partial int SSLStreamInitializeImpl( IntPtr managedContextHandle, delegate* unmanaged streamRead, delegate* unmanaged streamWrite, + delegate* unmanaged managedContextCleanup, int appBufferSize, [MarshalAs(UnmanagedType.LPUTF8Str)] string? peerHost); internal static unsafe void SSLStreamInitialize( @@ -86,10 +87,11 @@ internal static unsafe void SSLStreamInitialize( IntPtr managedContextHandle, delegate* unmanaged streamRead, delegate* unmanaged streamWrite, + delegate* unmanaged managedContextCleanup, int appBufferSize, string? peerHost) { - int ret = SSLStreamInitializeImpl(sslHandle, isServer, managedContextHandle, streamRead, streamWrite, appBufferSize, peerHost); + int ret = SSLStreamInitializeImpl(sslHandle, isServer, managedContextHandle, streamRead, streamWrite, managedContextCleanup, appBufferSize, peerHost); if (ret != SUCCESS) throw new SslException(); } diff --git a/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs b/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs index b82c030e4232d4..f3951931e03910 100644 --- a/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs +++ b/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs @@ -14,6 +14,7 @@ internal static partial class Libraries internal const string OpenLdap = "libldap.dylib"; internal const string SystemConfigurationLibrary = "/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration"; internal const string AppleCryptoNative = "libSystem.Security.Cryptography.Native.Apple"; + internal const string NetworkFramework = "/System/Library/Frameworks/Network.framework/Network"; internal const string MsQuic = "libmsquic.dylib"; } } diff --git a/src/libraries/Common/src/Interop/OSX/Interop.NetworkFramework.Tls.cs b/src/libraries/Common/src/Interop/OSX/Interop.NetworkFramework.Tls.cs new file mode 100644 index 00000000000000..ee216667d6a06a --- /dev/null +++ b/src/libraries/Common/src/Interop/OSX/Interop.NetworkFramework.Tls.cs @@ -0,0 +1,88 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Diagnostics; +using System.Net; +using System.Net.Security; +using System.Runtime.InteropServices; +using System.Security.Authentication; +using Microsoft.Win32.SafeHandles; + +internal static partial class Interop +{ + // TLS 1.3 specific Network Framework implementation for macOS + internal static partial class NetworkFramework + { + internal static partial class Tls + { + // Initialize internal shim for NetworkFramework integration + [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_Init")] + [return: MarshalAs(UnmanagedType.I4)] + internal static unsafe partial bool Init( + delegate* unmanaged statusCallback, + delegate* unmanaged writeCallback, + delegate* unmanaged challengeCallback); + + // Create a new connection context + [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwConnectionCreate", StringMarshalling = StringMarshalling.Utf8)] + internal static unsafe partial SafeNwHandle NwConnectionCreate([MarshalAs(UnmanagedType.I4)] bool isServer, IntPtr context, string targetName, byte* alpnBuffer, int alpnLength, SslProtocols minTlsProtocol, SslProtocols maxTlsProtocol, uint* cipherSuites, int cipherSuitesLength); + + // Start the TLS handshake, notifications are received via the status callback (potentially from a different thread). + [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwConnectionStart")] + internal static partial int NwConnectionStart(SafeNwHandle connection, IntPtr context); + + // takes encrypted input from underlying stream and feed it to the connection. + [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwFramerDeliverInput")] + internal static unsafe partial int NwFramerDeliverInput(SafeNwHandle framer, IntPtr context, byte* buffer, int bufferLength, delegate* unmanaged completionCallback); + + // sends plaintext data to the connection. + [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwConnectionSend")] + internal static unsafe partial void NwConnectionSend(SafeNwHandle connection, IntPtr context, void* buffer, int bufferLength, delegate* unmanaged completionCallback); + + // read plaintext data from the connection. + [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwConnectionReceive")] + internal static unsafe partial void NwConnectionReceive(SafeNwHandle connection, IntPtr context, int length, delegate* unmanaged readCompletionCallback); + + // starts connection cleanup + [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_NwConnectionCancel")] + internal static partial void NwConnectionCancel(SafeNwHandle connection); + + // gets TLS connection information + [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_GetConnectionInfo")] + internal static unsafe partial int GetConnectionInfo(SafeNwHandle connection, IntPtr context, out SslProtocols pProtocol, out TlsCipherSuite pCipherSuiteOut, byte* negotiatedAlpn, ref int negotiatedAlpnLength); + } + + // Status enumeration for Network Framework TLS operations + internal enum StatusUpdates + { + UnknownError = 0, + FramerStart = 1, + HandshakeFinished = 3, + ConnectionFailed = 4, + ConnectionCancelled = 103, + CertificateAvailable = 104, + DebugLog = 200, + } + } + + // Safe handle classes for Network Framework TLS resources + internal sealed class SafeNwHandle : SafeHandleZeroOrMinusOneIsInvalid + { + public SafeNwHandle() : base(ownsHandle: true) { } + + public SafeNwHandle(IntPtr handle, bool ownsHandle) : base(ownsHandle) + { + SetHandle(handle); + } + + protected override bool ReleaseHandle() + { + NetworkFramework.Release(handle); + SetHandle(IntPtr.Zero); + return true; + } + } +} diff --git a/src/libraries/Common/src/Interop/OSX/Interop.NetworkFramework.cs b/src/libraries/Common/src/Interop/OSX/Interop.NetworkFramework.cs new file mode 100644 index 00000000000000..d5eb743a333b35 --- /dev/null +++ b/src/libraries/Common/src/Interop/OSX/Interop.NetworkFramework.cs @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +internal static partial class Interop +{ + internal static partial class NetworkFramework + { + // Network Framework reference counting functions + [LibraryImport(Libraries.NetworkFramework, EntryPoint = "nw_retain")] + internal static partial IntPtr Retain(IntPtr obj); + + [LibraryImport(Libraries.NetworkFramework, EntryPoint = "nw_release")] + internal static partial void Release(IntPtr obj); + + // Network Framework error domains + internal enum NetworkFrameworkErrorDomain + { + Invalid = 0, + POSIX = 1, + DNS = 2, + TLS = 3 + } + + internal enum NWErrorDomainPOSIX + { + OperationCanceled = 89, // ECANCELED + } + + internal sealed class NetworkFrameworkException : Exception + { + public int ErrorCode { get; } + public NetworkFrameworkErrorDomain ErrorDomain { get; } + + internal NetworkFrameworkException() + { + } + + internal NetworkFrameworkException(int errorCode, NetworkFrameworkErrorDomain errorDomain, string? message) + : base(message ?? $"Network Framework error {errorCode} in domain {errorDomain}") + { + HResult = errorCode; + ErrorCode = errorCode; + ErrorDomain = errorDomain; + } + + internal NetworkFrameworkException(int errorCode, NetworkFrameworkErrorDomain errorDomain, string? message, Exception innerException) + : base(message ?? $"Network Framework error {errorCode} in domain {errorDomain}", innerException) + { + HResult = errorCode; + ErrorCode = errorCode; + ErrorDomain = errorDomain; + } + + public override string ToString() + { + return $"{base.ToString()}, ErrorCode: {ErrorCode}, ErrorDomain: {ErrorDomain}"; + } + } + + [StructLayout(LayoutKind.Sequential)] + internal struct NetworkFrameworkError + { + public int ErrorCode; + public int ErrorDomain; + public IntPtr ErrorMessage; // C string of NULL + } + + internal static Exception CreateExceptionForNetworkFrameworkError(in NetworkFrameworkError error) + { + string? message = null; + NetworkFrameworkErrorDomain domain = (NetworkFrameworkErrorDomain)error.ErrorDomain; + + if (error.ErrorMessage != IntPtr.Zero) + { + message = Marshal.PtrToStringUTF8(error.ErrorMessage); + } + + return new NetworkFrameworkException(error.ErrorCode, domain, message); + } + } +} diff --git a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.OSStatus.cs b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.OSStatus.cs new file mode 100644 index 00000000000000..ac271a5b4e0f8c --- /dev/null +++ b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.OSStatus.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +internal static partial class Interop +{ + internal static partial class AppleCrypto + { + internal static class OSStatus + { + public const int NoErr = 0; + public const int ReadErr = -19; + public const int WritErr = -20; + public const int EOFErr = -39; + public const int SecUserCanceled = -128; + public const int ErrSSLWouldBlock = -9803; + } + } +} diff --git a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs index 9abf075d60c967..d24a7314592000 100644 --- a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs +++ b/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/libraries/Common/src/Interop/Unix/Interop.Odbc.cs b/src/libraries/Common/src/Interop/Unix/Interop.Odbc.cs index 96e64bdda18a3e..af41aa36075c7c 100644 --- a/src/libraries/Common/src/Interop/Unix/Interop.Odbc.cs +++ b/src/libraries/Common/src/Interop/Unix/Interop.Odbc.cs @@ -16,7 +16,7 @@ internal static partial class Odbc { internal static string GetNativeLibraryName() { - if (OperatingSystem.IsMacOS() || OperatingSystem.IsIOS() || OperatingSystem.IsTvOS() || OperatingSystem.IsWatchOS()) + if (OperatingSystem.IsMacOS() || OperatingSystem.IsIOS() || OperatingSystem.IsTvOS()) { return "libodbc.2.dylib"; } diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.MLDsa.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.MLDsa.cs index 2f41b60b6d1628..4279cdb1fc94b5 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.MLDsa.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.MLDsa.cs @@ -132,6 +132,117 @@ internal static bool MLDsaVerifyPure( } } + [LibraryImport(Libraries.CryptoNative)] + private static partial int CryptoNative_MLDsaSignPreEncoded( + SafeEvpPKeyHandle pkey, IntPtr extraHandle, + ReadOnlySpan msg, int msgLength, + Span destination, int destinationLength); + + internal static void MLDsaSignPreEncoded( + SafeEvpPKeyHandle pkey, + ReadOnlySpan msg, + Span destination) + { + int ret = CryptoNative_MLDsaSignPreEncoded( + pkey, GetExtraHandle(pkey), + msg, msg.Length, + destination, destination.Length); + + if (ret != 1) + { + throw Interop.Crypto.CreateOpenSslCryptographicException(); + } + } + + [LibraryImport(Libraries.CryptoNative)] + private static partial int CryptoNative_MLDsaVerifyPreEncoded( + SafeEvpPKeyHandle pkey, IntPtr extraHandle, + ReadOnlySpan msg, int msgLength, + ReadOnlySpan signature, int signatureLength); + + internal static bool MLDsaVerifyPreEncoded( + SafeEvpPKeyHandle pkey, + ReadOnlySpan msg, + ReadOnlySpan signature) + { + int ret = CryptoNative_MLDsaVerifyPreEncoded( + pkey, GetExtraHandle(pkey), + msg, msg.Length, + signature, signature.Length); + + if (ret == 1) + { + return true; + } + else if (ret == 0) + { + return false; + } + else + { + throw Interop.Crypto.CreateOpenSslCryptographicException(); + } + } + + [LibraryImport(Libraries.CryptoNative)] + private static partial int CryptoNative_MLDsaSignExternalMu( + SafeEvpPKeyHandle pkey, IntPtr extraHandle, + ReadOnlySpan mu, int muLength, + Span destination, int destinationLength); + + internal static void MLDsaSignExternalMu( + SafeEvpPKeyHandle pkey, + ReadOnlySpan mu, + Span destination) + { + const int Success = 1; + const int SigningFailure = 0; + + int ret = CryptoNative_MLDsaSignExternalMu( + pkey, GetExtraHandle(pkey), + mu, mu.Length, + destination, destination.Length); + + if (ret != Success) + { + Debug.Assert(ret == SigningFailure, $"Unexpected return value {ret} from {nameof(CryptoNative_MLDsaSignExternalMu)}."); + throw Interop.Crypto.CreateOpenSslCryptographicException(); + } + } + + [LibraryImport(Libraries.CryptoNative)] + private static partial int CryptoNative_MLDsaVerifyExternalMu( + SafeEvpPKeyHandle pkey, IntPtr extraHandle, + ReadOnlySpan mu, int muLength, + ReadOnlySpan signature, int signatureLength); + + internal static bool MLDsaVerifyExternalMu( + SafeEvpPKeyHandle pkey, + ReadOnlySpan mu, + ReadOnlySpan signature) + { + const int ValidSignature = 1; + const int InvalidSignature = 0; + + int ret = CryptoNative_MLDsaVerifyExternalMu( + pkey, GetExtraHandle(pkey), + mu, mu.Length, + signature, signature.Length); + + if (ret == ValidSignature) + { + return true; + } + else if (ret == InvalidSignature) + { + return false; + } + else + { + throw Interop.Crypto.CreateOpenSslCryptographicException(); + } + } + [LibraryImport(Libraries.CryptoNative)] private static partial int CryptoNative_MLDsaExportSecretKey(SafeEvpPKeyHandle pkey, Span destination, int destinationLength); diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.ProcessOptions.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.ProcessOptions.cs index 8ef5167d70edc6..893a0aaed9073c 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.ProcessOptions.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.ProcessOptions.cs @@ -43,6 +43,7 @@ internal static partial class StartupInfoOptions internal const int STARTF_USESTDHANDLES = 0x00000100; internal const int CREATE_UNICODE_ENVIRONMENT = 0x00000400; internal const int CREATE_NO_WINDOW = 0x08000000; + internal const int CREATE_NEW_PROCESS_GROUP = 0x00000200; } } } diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs index 0f69af42cb0bc1..376a133244b17a 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs +++ b/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/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptVerifySignature.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptVerifySignature.cs index 6934e7e2c11ba0..da39ca0dcdd4a2 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptVerifySignature.cs +++ b/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/libraries/Common/src/Interop/Windows/BCrypt/Interop.Blobs.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.Blobs.cs index 83b614863f6889..f919daf562998b 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.Blobs.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.Blobs.cs @@ -78,6 +78,15 @@ internal static byte[] Consume(ReadOnlySpan blob, ref int offset, int coun return value; } + /// + /// Peel off the next "count" bytes in blob and copy them into the destination. + /// + internal static void Consume(ReadOnlySpan blob, ref int offset, int count, Span destination) + { + blob.Slice(offset, count).CopyTo(destination); + offset += count; + } + /// /// Magic numbers identifying blob types /// diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertSetCertificateContextProperty_CRYPT_KEY_PROV_INFO.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertSetCertificateContextProperty_CRYPT_KEY_PROV_INFO.cs index 4a0e3735451be6..7cf4707b33a9bb 100644 --- a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertSetCertificateContextProperty_CRYPT_KEY_PROV_INFO.cs +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertSetCertificateContextProperty_CRYPT_KEY_PROV_INFO.cs @@ -11,5 +11,9 @@ internal static partial class Crypt32 [LibraryImport(Libraries.Crypt32, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static unsafe partial bool CertSetCertificateContextProperty(SafeCertContextHandle pCertContext, CertContextPropId dwPropId, CertSetPropertyFlags dwFlags, CRYPT_KEY_PROV_INFO* pvData); + + [LibraryImport(Libraries.Crypt32, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static unsafe partial bool CertSetCertificateContextProperty(nint pCertContext, CertContextPropId dwPropId, CertSetPropertyFlags dwFlags, CRYPT_KEY_PROV_INFO* pvData); } } diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertSetCertificateContextProperty_SafeNCryptKeyHandle.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertSetCertificateContextProperty_SafeNCryptKeyHandle.cs index 35ceeaffe3b4ec..33639afcbbba57 100644 --- a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertSetCertificateContextProperty_SafeNCryptKeyHandle.cs +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertSetCertificateContextProperty_SafeNCryptKeyHandle.cs @@ -11,5 +11,9 @@ internal static partial class Crypt32 [LibraryImport(Libraries.Crypt32, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static unsafe partial bool CertSetCertificateContextProperty(SafeCertContextHandle pCertContext, CertContextPropId dwPropId, CertSetPropertyFlags dwFlags, SafeNCryptKeyHandle keyHandle); + + [LibraryImport(Libraries.Crypt32, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static unsafe partial bool CertSetCertificateContextProperty(nint pCertContext, CertContextPropId dwPropId, CertSetPropertyFlags dwFlags, SafeNCryptKeyHandle keyHandle); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Threading.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Threading.cs index 14863bf1e4f749..b323cacc6bcaee 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Threading.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Threading.cs @@ -10,6 +10,7 @@ internal static partial class Interop internal static partial class Kernel32 { internal const int WAIT_FAILED = unchecked((int)0xFFFFFFFF); + internal const int WAIT_IO_COMPLETION = 0x000000C0; [LibraryImport(Libraries.Kernel32)] internal static partial uint WaitForMultipleObjectsEx(uint nCount, IntPtr lpHandles, BOOL bWaitAll, uint dwMilliseconds, BOOL bAlertable); @@ -17,6 +18,9 @@ internal static partial class Kernel32 [LibraryImport(Libraries.Kernel32)] internal static partial uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds); + [LibraryImport(Libraries.Kernel32)] + internal static partial uint WaitForSingleObjectEx(IntPtr hHandle, uint dwMilliseconds, BOOL bAlertable); + [LibraryImport(Libraries.Kernel32)] internal static partial uint SignalObjectAndWait(IntPtr hObjectToSignal, IntPtr hObjectToWaitOn, uint dwMilliseconds, BOOL bAlertable); diff --git a/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Properties.cs b/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Properties.cs index ec001c0b55a93d..377924f386948f 100644 --- a/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Properties.cs +++ b/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Properties.cs @@ -1,12 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Cryptography; - +using Internal.Cryptography; using Microsoft.Win32.SafeHandles; internal static partial class Interop @@ -56,9 +55,7 @@ internal static unsafe ErrorCode NCryptGetIntProperty(SafeNCryptHandle hObject, { fixed (int* pResult = &result) { -#if NETSTANDARD || NET - Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); -#endif + Debug.Assert(Helpers.IsOSPlatformWindows); ErrorCode errorCode = Interop.NCrypt.NCryptGetProperty( hObject, diff --git a/src/libraries/Common/src/Interop/Windows/OleAut32/Interop.GetErrorInfo.cs b/src/libraries/Common/src/Interop/Windows/OleAut32/Interop.GetErrorInfo.cs new file mode 100644 index 00000000000000..eb450acf651a36 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/OleAut32/Interop.GetErrorInfo.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class OleAut32 + { + [LibraryImport(Libraries.OleAut32)] + internal static partial int GetErrorInfo(uint dwReserved, out IntPtr ppErrorInfo); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Shell32/Interop.SHGetKnownFolderPath.cs b/src/libraries/Common/src/Interop/Windows/Shell32/Interop.SHGetKnownFolderPath.cs index 136d93f8e43e9f..740ea18cc5526f 100644 --- a/src/libraries/Common/src/Interop/Windows/Shell32/Interop.SHGetKnownFolderPath.cs +++ b/src/libraries/Common/src/Interop/Windows/Shell32/Interop.SHGetKnownFolderPath.cs @@ -24,290 +24,390 @@ internal static class KnownFolders /// /// (CSIDL_ADMINTOOLS) Per user Administrative Tools /// "%APPDATA%\Microsoft\Windows\Start Menu\Programs\Administrative Tools" + /// {724EF170-A42D-4FEF-9F26-B60E846FBA4F} /// - internal const string AdminTools = "{724EF170-A42D-4FEF-9F26-B60E846FBA4F}"; + internal static ReadOnlySpan AdminTools => + [0x70, 0xF1, 0x4E, 0x72, 0x2D, 0xA4, 0xEF, 0x4F, 0x9F, 0x26, 0xB6, 0x0E, 0x84, 0x6F, 0xBA, 0x4F]; /// /// (CSIDL_CDBURN_AREA) Temporary Burn folder /// "%LOCALAPPDATA%\Microsoft\Windows\Burn\Burn" + /// {9E52AB10-F80D-49DF-ACB8-4330F5687855} /// - internal const string CDBurning = "{9E52AB10-F80D-49DF-ACB8-4330F5687855}"; + internal static ReadOnlySpan CDBurning => + [0x10, 0xAB, 0x52, 0x9E, 0x0D, 0xF8, 0xDF, 0x49, 0xAC, 0xB8, 0x43, 0x30, 0xF5, 0x68, 0x78, 0x55]; /// /// (CSIDL_COMMON_ADMINTOOLS) Common Administrative Tools /// "%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Administrative Tools" + /// {D0384E7D-BAC3-4797-8F14-CBA229B392B5} /// - internal const string CommonAdminTools = "{D0384E7D-BAC3-4797-8F14-CBA229B392B5}"; + internal static ReadOnlySpan CommonAdminTools => + [0x7D, 0x4E, 0x38, 0xD0, 0xC3, 0xBA, 0x97, 0x47, 0x8F, 0x14, 0xCB, 0xA2, 0x29, 0xB3, 0x92, 0xB5]; /// /// (CSIDL_COMMON_OEM_LINKS) OEM Links folder /// "%ALLUSERSPROFILE%\OEM Links" + /// {C1BAE2D0-10DF-4334-BEDD-7AA20B227A9D} /// - internal const string CommonOEMLinks = "{C1BAE2D0-10DF-4334-BEDD-7AA20B227A9D}"; + internal static ReadOnlySpan CommonOEMLinks => + [0xD0, 0xE2, 0xBA, 0xC1, 0xDF, 0x10, 0x34, 0x43, 0xBE, 0xDD, 0x7A, 0xA2, 0x0B, 0x22, 0x7A, 0x9D]; /// /// (CSIDL_COMMON_PROGRAMS) Common Programs folder /// "%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs" + /// {0139D44E-6AFE-49F2-8690-3DAFCAE6FFB8} /// - internal const string CommonPrograms = "{0139D44E-6AFE-49F2-8690-3DAFCAE6FFB8}"; + internal static ReadOnlySpan CommonPrograms => + [0x4E, 0xD4, 0x39, 0x01, 0xFE, 0x6A, 0xF2, 0x49, 0x86, 0x90, 0x3D, 0xAF, 0xCA, 0xE6, 0xFF, 0xB8]; /// /// (CSIDL_COMMON_STARTMENU) Common Start Menu folder /// "%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu" + /// {A4115719-D62E-491D-AA7C-E74B8BE3B067} /// - internal const string CommonStartMenu = "{A4115719-D62E-491D-AA7C-E74B8BE3B067}"; + internal static ReadOnlySpan CommonStartMenu => + [0x19, 0x57, 0x11, 0xA4, 0x2E, 0xD6, 0x1D, 0x49, 0xAA, 0x7C, 0xE7, 0x4B, 0x8B, 0xE3, 0xB0, 0x67]; /// /// (CSIDL_COMMON_STARTUP, CSIDL_COMMON_ALTSTARTUP) Common Startup folder /// "%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\StartUp" + /// {82A5EA35-D9CD-47C5-9629-E15D2F714E6E} /// - internal const string CommonStartup = "{82A5EA35-D9CD-47C5-9629-E15D2F714E6E}"; + internal static ReadOnlySpan CommonStartup => + [0x35, 0xEA, 0xA5, 0x82, 0xCD, 0xD9, 0xC5, 0x47, 0x96, 0x29, 0xE1, 0x5D, 0x2F, 0x71, 0x4E, 0x6E]; /// /// (CSIDL_COMMON_TEMPLATES) Common Templates folder /// "%ALLUSERSPROFILE%\Microsoft\Windows\Templates" + /// {B94237E7-57AC-4347-9151-B08C6C32D1F7} /// - internal const string CommonTemplates = "{B94237E7-57AC-4347-9151-B08C6C32D1F7}"; + internal static ReadOnlySpan CommonTemplates => + [0xE7, 0x37, 0x42, 0xB9, 0xAC, 0x57, 0x47, 0x43, 0x91, 0x51, 0xB0, 0x8C, 0x6C, 0x32, 0xD1, 0xF7]; /// /// (CSIDL_DRIVES) Computer virtual folder + /// {0AC0837C-BBF8-452A-850D-79D08E667CA7} /// - internal const string ComputerFolder = "{0AC0837C-BBF8-452A-850D-79D08E667CA7}"; + internal static ReadOnlySpan ComputerFolder => + [0x7C, 0x83, 0xC0, 0x0A, 0xF8, 0xBB, 0x2A, 0x45, 0x85, 0x0D, 0x79, 0xD0, 0x8E, 0x66, 0x7C, 0xA7]; /// /// (CSIDL_CONNECTIONS) Network Connections virtual folder + /// {6F0CD92B-2E97-45D1-88FF-B0D186B8DEDD} /// - internal const string ConnectionsFolder = "{6F0CD92B-2E97-45D1-88FF-B0D186B8DEDD}"; + internal static ReadOnlySpan ConnectionsFolder => + [0x2B, 0xD9, 0x0C, 0x6F, 0x97, 0x2E, 0xD1, 0x45, 0x88, 0xFF, 0xB0, 0xD1, 0x86, 0xB8, 0xDE, 0xDD]; /// /// (CSIDL_CONTROLS) Control Panel virtual folder + /// {82A74AEB-AEB4-465C-A014-D097EE346D63} /// - internal const string ControlPanelFolder = "{82A74AEB-AEB4-465C-A014-D097EE346D63}"; + internal static ReadOnlySpan ControlPanelFolder => + [0xEB, 0x4A, 0xA7, 0x82, 0xB4, 0xAE, 0x5C, 0x46, 0xA0, 0x14, 0xD0, 0x97, 0xEE, 0x34, 0x6D, 0x63]; /// /// (CSIDL_COOKIES) Cookies folder /// "%APPDATA%\Microsoft\Windows\Cookies" + /// {2B0F765D-C0E9-4171-908E-08A611B84FF6} /// - internal const string Cookies = "{2B0F765D-C0E9-4171-908E-08A611B84FF6}"; + internal static ReadOnlySpan Cookies => + [0x5D, 0x76, 0x0F, 0x2B, 0xE9, 0xC0, 0x71, 0x41, 0x90, 0x8E, 0x08, 0xA6, 0x11, 0xB8, 0x4F, 0xF6]; /// /// (CSIDL_DESKTOP, CSIDL_DESKTOPDIRECTORY) Desktop folder /// "%USERPROFILE%\Desktop" + /// {B4BFCC3A-DB2C-424C-B029-7FE99A87C641} /// - internal const string Desktop = "{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}"; + internal static ReadOnlySpan Desktop => + [0x3A, 0xCC, 0xBF, 0xB4, 0x2C, 0xDB, 0x4C, 0x42, 0xB0, 0x29, 0x7F, 0xE9, 0x9A, 0x87, 0xC6, 0x41]; /// /// (CSIDL_MYDOCUMENTS, CSIDL_PERSONAL) Documents (My Documents) folder /// "%USERPROFILE%\Documents" + /// {FDD39AD0-238F-46AF-ADB4-6C85480369C7} /// - internal const string Documents = "{FDD39AD0-238F-46AF-ADB4-6C85480369C7}"; + internal static ReadOnlySpan Documents => + [0xD0, 0x9A, 0xD3, 0xFD, 0x8F, 0x23, 0xAF, 0x46, 0xAD, 0xB4, 0x6C, 0x85, 0x48, 0x03, 0x69, 0xC7]; /// /// (CSIDL_FAVORITES, CSIDL_COMMON_FAVORITES) Favorites folder /// "%USERPROFILE%\Favorites" + /// {1777F761-68AD-4D8A-87BD-30B759FA33DD} /// - internal const string Favorites = "{1777F761-68AD-4D8A-87BD-30B759FA33DD}"; + internal static ReadOnlySpan Favorites => + [0x61, 0xF7, 0x77, 0x17, 0xAD, 0x68, 0x8A, 0x4D, 0x87, 0xBD, 0x30, 0xB7, 0x59, 0xFA, 0x33, 0xDD]; /// /// (CSIDL_FONTS) Fonts folder /// "%windir%\Fonts" + /// {FD228CB7-AE11-4AE3-864C-16F3910AB8FE} /// - internal const string Fonts = "{FD228CB7-AE11-4AE3-864C-16F3910AB8FE}"; + internal static ReadOnlySpan Fonts => + [0xB7, 0x8C, 0x22, 0xFD, 0x11, 0xAE, 0xE3, 0x4A, 0x86, 0x4C, 0x16, 0xF3, 0x91, 0x0A, 0xB8, 0xFE]; /// /// (CSIDL_HISTORY) History folder /// "%LOCALAPPDATA%\Microsoft\Windows\History" + /// {D9DC8A3B-B784-432E-A781-5A1130A75963} /// - internal const string History = "{D9DC8A3B-B784-432E-A781-5A1130A75963}"; + internal static ReadOnlySpan History => + [0x3B, 0x8A, 0xDC, 0xD9, 0x84, 0xB7, 0x2E, 0x43, 0xA7, 0x81, 0x5A, 0x11, 0x30, 0xA7, 0x59, 0x63]; /// /// (CSIDL_INTERNET_CACHE) Temporary Internet Files folder /// "%LOCALAPPDATA%\Microsoft\Windows\Temporary Internet Files" + /// {352481E8-33BE-4251-BA85-6007CAEDCF9D} /// - internal const string InternetCache = "{352481E8-33BE-4251-BA85-6007CAEDCF9D}"; + internal static ReadOnlySpan InternetCache => + [0xE8, 0x81, 0x24, 0x35, 0xBE, 0x33, 0x51, 0x42, 0xBA, 0x85, 0x60, 0x07, 0xCA, 0xED, 0xCF, 0x9D]; /// /// (CSIDL_INTERNET) The Internet virtual folder + /// {4D9F7874-4E0C-4904-967B-40B0D20C3E4B} /// - internal const string InternetFolder = "{4D9F7874-4E0C-4904-967B-40B0D20C3E4B}"; + internal static ReadOnlySpan InternetFolder => + [0x74, 0x78, 0x9F, 0x4D, 0x0C, 0x4E, 0x04, 0x49, 0x96, 0x7B, 0x40, 0xB0, 0xD2, 0x0C, 0x3E, 0x4B]; /// /// (CSIDL_LOCAL_APPDATA) Local folder /// "%LOCALAPPDATA%" ("%USERPROFILE%\AppData\Local") + /// {F1B32785-6FBA-4FCF-9D55-7B8E7F157091} /// - internal const string LocalAppData = "{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}"; + internal static ReadOnlySpan LocalAppData => + [0x85, 0x27, 0xB3, 0xF1, 0xBA, 0x6F, 0xCF, 0x4F, 0x9D, 0x55, 0x7B, 0x8E, 0x7F, 0x15, 0x70, 0x91]; /// /// (CSIDL_RESOURCES_LOCALIZED) Fixed localized resources folder /// "%windir%\resources\0409" (per active codepage) + /// {2A00375E-224C-49DE-B8D1-440DF7EF3DDC} /// - internal const string LocalizedResourcesDir = "{2A00375E-224C-49DE-B8D1-440DF7EF3DDC}"; + internal static ReadOnlySpan LocalizedResourcesDir => + [0x5E, 0x37, 0x00, 0x2A, 0x4C, 0x22, 0xDE, 0x49, 0xB8, 0xD1, 0x44, 0x0D, 0xF7, 0xEF, 0x3D, 0xDC]; /// /// (CSIDL_MYMUSIC) Music folder /// "%USERPROFILE%\Music" + /// {4BD8D571-6D19-48D3-BE97-422220080E43} /// - internal const string Music = "{4BD8D571-6D19-48D3-BE97-422220080E43}"; + internal static ReadOnlySpan Music => + [0x71, 0xD5, 0xD8, 0x4B, 0x19, 0x6D, 0xD3, 0x48, 0xBE, 0x97, 0x42, 0x22, 0x20, 0x08, 0x0E, 0x43]; /// /// (CSIDL_NETHOOD) Network shortcuts folder "%APPDATA%\Microsoft\Windows\Network Shortcuts" + /// {C5ABBF53-E17F-4121-8900-86626FC2C973} /// - internal const string NetHood = "{C5ABBF53-E17F-4121-8900-86626FC2C973}"; + internal static ReadOnlySpan NetHood => + [0x53, 0xBF, 0xAB, 0xC5, 0x7F, 0xE1, 0x21, 0x41, 0x89, 0x00, 0x86, 0x62, 0x6F, 0xC2, 0xC9, 0x73]; /// /// (CSIDL_NETWORK, CSIDL_COMPUTERSNEARME) Network virtual folder + /// {D20BEEC4-5CA8-4905-AE3B-BF251EA09B53} /// - internal const string NetworkFolder = "{D20BEEC4-5CA8-4905-AE3B-BF251EA09B53}"; + internal static ReadOnlySpan NetworkFolder => + [0xC4, 0xEE, 0x0B, 0xD2, 0xA8, 0x5C, 0x05, 0x49, 0xAE, 0x3B, 0xBF, 0x25, 0x1E, 0xA0, 0x9B, 0x53]; /// /// (CSIDL_MYPICTURES) Pictures folder "%USERPROFILE%\Pictures" + /// {33E28130-4E1E-4676-835A-98395C3BC3BB} /// - internal const string Pictures = "{33E28130-4E1E-4676-835A-98395C3BC3BB}"; + internal static ReadOnlySpan Pictures => + [0x30, 0x81, 0xE2, 0x33, 0x1E, 0x4E, 0x76, 0x46, 0x83, 0x5A, 0x98, 0x39, 0x5C, 0x3B, 0xC3, 0xBB]; /// /// (CSIDL_PRINTERS) Printers virtual folder + /// {76FC4E2D-D6AD-4519-A663-37BD56068185} /// - internal const string PrintersFolder = "{76FC4E2D-D6AD-4519-A663-37BD56068185}"; + internal static ReadOnlySpan PrintersFolder => + [0x2D, 0x4E, 0xFC, 0x76, 0xAD, 0xD6, 0x19, 0x45, 0xA6, 0x63, 0x37, 0xBD, 0x56, 0x06, 0x81, 0x85]; /// /// (CSIDL_PRINTHOOD) Printer Shortcuts folder /// "%APPDATA%\Microsoft\Windows\Printer Shortcuts" + /// {9274BD8D-CFD1-41C3-B35E-B13F55A758F4} /// - internal const string PrintHood = "{9274BD8D-CFD1-41C3-B35E-B13F55A758F4}"; + internal static ReadOnlySpan PrintHood => + [0x8D, 0xBD, 0x74, 0x92, 0xD1, 0xCF, 0xC3, 0x41, 0xB3, 0x5E, 0xB1, 0x3F, 0x55, 0xA7, 0x58, 0xF4]; /// /// (CSIDL_PROFILE) The root users profile folder "%USERPROFILE%" /// ("%SystemDrive%\Users\%USERNAME%") + /// {5E6C858F-0E22-4760-9AFE-EA3317B67173} /// - internal const string Profile = "{5E6C858F-0E22-4760-9AFE-EA3317B67173}"; + internal static ReadOnlySpan Profile => + [0x8F, 0x85, 0x6C, 0x5E, 0x22, 0x0E, 0x60, 0x47, 0x9A, 0xFE, 0xEA, 0x33, 0x17, 0xB6, 0x71, 0x73]; /// /// (CSIDL_COMMON_APPDATA) ProgramData folder /// "%ALLUSERSPROFILE%" ("%ProgramData%", "%SystemDrive%\ProgramData") + /// {62AB5D82-FDC1-4DC3-A9DD-070D1D495D97} /// - internal const string ProgramData = "{62AB5D82-FDC1-4DC3-A9DD-070D1D495D97}"; + internal static ReadOnlySpan ProgramData => + [0x82, 0x5D, 0xAB, 0x62, 0xC1, 0xFD, 0xC3, 0x4D, 0xA9, 0xDD, 0x07, 0x0D, 0x1D, 0x49, 0x5D, 0x97]; /// /// (CSIDL_PROGRAM_FILES) Program Files folder for the current process architecture /// "%ProgramFiles%" ("%SystemDrive%\Program Files") + /// {905e63b6-c1bf-494e-b29c-65b732d3d21a} /// - internal const string ProgramFiles = "{905e63b6-c1bf-494e-b29c-65b732d3d21a}"; + internal static ReadOnlySpan ProgramFiles => + [0xb6, 0x63, 0x5e, 0x90, 0xbf, 0xc1, 0x4e, 0x49, 0xb2, 0x9c, 0x65, 0xb7, 0x32, 0xd3, 0xd2, 0x1a]; /// /// (CSIDL_PROGRAM_FILESX86) 32 bit Program Files folder (available to both 32/64 bit processes) + /// {7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E} /// - internal const string ProgramFilesX86 = "{7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}"; + internal static ReadOnlySpan ProgramFilesX86 => + [0xEF, 0x40, 0x5A, 0x7C, 0xFB, 0xA0, 0xFC, 0x4B, 0x87, 0x4A, 0xC0, 0xF2, 0xE0, 0xB9, 0xFA, 0x8E]; /// /// (CSIDL_PROGRAM_FILES_COMMON) Common Program Files folder for the current process architecture /// "%ProgramFiles%\Common Files" + /// {F7F1ED05-9F6D-47A2-AAAE-29D317C6F066} /// - internal const string ProgramFilesCommon = "{F7F1ED05-9F6D-47A2-AAAE-29D317C6F066}"; + internal static ReadOnlySpan ProgramFilesCommon => + [0x05, 0xED, 0xF1, 0xF7, 0x6D, 0x9F, 0xA2, 0x47, 0xAA, 0xAE, 0x29, 0xD3, 0x17, 0xC6, 0xF0, 0x66]; /// /// (CSIDL_PROGRAM_FILES_COMMONX86) Common 32 bit Program Files folder (available to both 32/64 bit processes) + /// {DE974D24-D9C6-4D3E-BF91-F4455120B917} /// - internal const string ProgramFilesCommonX86 = "{DE974D24-D9C6-4D3E-BF91-F4455120B917}"; + internal static ReadOnlySpan ProgramFilesCommonX86 => + [0x24, 0x4D, 0x97, 0xDE, 0xC6, 0xD9, 0x3E, 0x4D, 0xBF, 0x91, 0xF4, 0x45, 0x51, 0x20, 0xB9, 0x17]; /// /// (CSIDL_PROGRAMS) Start menu Programs folder /// "%APPDATA%\Microsoft\Windows\Start Menu\Programs" + /// {A77F5D77-2E2B-44C3-A6A2-ABA601054A51} /// - internal const string Programs = "{A77F5D77-2E2B-44C3-A6A2-ABA601054A51}"; + internal static ReadOnlySpan Programs => + [0x77, 0x5D, 0x7F, 0xA7, 0x2B, 0x2E, 0xC3, 0x44, 0xA6, 0xA2, 0xAB, 0xA6, 0x01, 0x05, 0x4A, 0x51]; /// /// (CSIDL_COMMON_DESKTOPDIRECTORY) Public Desktop folder /// "%PUBLIC%\Desktop" + /// {C4AA340D-F20F-4863-AFEF-F87EF2E6BA25} /// - internal const string PublicDesktop = "{C4AA340D-F20F-4863-AFEF-F87EF2E6BA25}"; + internal static ReadOnlySpan PublicDesktop => + [0x0D, 0x34, 0xAA, 0xC4, 0x0F, 0xF2, 0x63, 0x48, 0xAF, 0xEF, 0xF8, 0x7E, 0xF2, 0xE6, 0xBA, 0x25]; /// /// (CSIDL_COMMON_DOCUMENTS) Public Documents folder /// "%PUBLIC%\Documents" + /// {ED4824AF-DCE4-45A8-81E2-FC7965083634} /// - internal const string PublicDocuments = "{ED4824AF-DCE4-45A8-81E2-FC7965083634}"; + internal static ReadOnlySpan PublicDocuments => + [0xAF, 0x24, 0x48, 0xED, 0xE4, 0xDC, 0xA8, 0x45, 0x81, 0xE2, 0xFC, 0x79, 0x65, 0x08, 0x36, 0x34]; /// /// (CSIDL_COMMON_MUSIC) Public Music folder /// "%PUBLIC%\Music" + /// {3214FAB5-9757-4298-BB61-92A9DEAA44FF} /// - internal const string PublicMusic = "{3214FAB5-9757-4298-BB61-92A9DEAA44FF}"; + internal static ReadOnlySpan PublicMusic => + [0xB5, 0xFA, 0x14, 0x32, 0x57, 0x97, 0x98, 0x42, 0xBB, 0x61, 0x92, 0xA9, 0xDE, 0xAA, 0x44, 0xFF]; /// /// (CSIDL_COMMON_PICTURES) Public Pictures folder /// "%PUBLIC%\Pictures" + /// {B6EBFB86-6907-413C-9AF7-4FC2ABF07CC5} /// - internal const string PublicPictures = "{B6EBFB86-6907-413C-9AF7-4FC2ABF07CC5}"; + internal static ReadOnlySpan PublicPictures => + [0x86, 0xFB, 0xEB, 0xB6, 0x07, 0x69, 0x3C, 0x41, 0x9A, 0xF7, 0x4F, 0xC2, 0xAB, 0xF0, 0x7C, 0xC5]; /// /// (CSIDL_COMMON_VIDEO) Public Videos folder /// "%PUBLIC%\Videos" + /// {2400183A-6185-49FB-A2D8-4A392A602BA3} /// - internal const string PublicVideos = "{2400183A-6185-49FB-A2D8-4A392A602BA3}"; + internal static ReadOnlySpan PublicVideos => + [0x3A, 0x18, 0x00, 0x24, 0x85, 0x61, 0xFB, 0x49, 0xA2, 0xD8, 0x4A, 0x39, 0x2A, 0x60, 0x2B, 0xA3]; /// /// (CSIDL_RECENT) Recent Items folder /// "%APPDATA%\Microsoft\Windows\Recent" + /// {AE50C081-EBD2-438A-8655-8A092E34987A} /// - internal const string Recent = "{AE50C081-EBD2-438A-8655-8A092E34987A}"; + internal static ReadOnlySpan Recent => + [0x81, 0xC0, 0x50, 0xAE, 0xD2, 0xEB, 0x8A, 0x43, 0x86, 0x55, 0x8A, 0x09, 0x2E, 0x34, 0x98, 0x7A]; /// /// (CSIDL_BITBUCKET) Recycle Bin virtual folder + /// {B7534046-3ECB-4C18-BE4E-64CD4CB7D6AC} /// - internal const string RecycleBinFolder = "{B7534046-3ECB-4C18-BE4E-64CD4CB7D6AC}"; + internal static ReadOnlySpan RecycleBinFolder => + [0x46, 0x40, 0x53, 0xB7, 0xCB, 0x3E, 0x18, 0x4C, 0xBE, 0x4E, 0x64, 0xCD, 0x4C, 0xB7, 0xD6, 0xAC]; /// /// (CSIDL_RESOURCES) Resources fixed folder /// "%windir%\Resources" + /// {8AD10C31-2ADB-4296-A8F7-E4701232C972} /// - internal const string ResourceDir = "{8AD10C31-2ADB-4296-A8F7-E4701232C972}"; + internal static ReadOnlySpan ResourceDir => + [0x31, 0x0C, 0xD1, 0x8A, 0xDB, 0x2A, 0x96, 0x42, 0xA8, 0xF7, 0xE4, 0x70, 0x12, 0x32, 0xC9, 0x72]; /// /// (CSIDL_APPDATA) Roaming user application data folder /// "%APPDATA%" ("%USERPROFILE%\AppData\Roaming") + /// {3EB685DB-65F9-4CF6-A03A-E3EF65729F3D} /// - internal const string RoamingAppData = "{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}"; + internal static ReadOnlySpan RoamingAppData => + [0xDB, 0x85, 0xB6, 0x3E, 0xF9, 0x65, 0xF6, 0x4C, 0xA0, 0x3A, 0xE3, 0xEF, 0x65, 0x72, 0x9F, 0x3D]; /// /// (CSIDL_SENDTO) SendTo folder /// "%APPDATA%\Microsoft\Windows\SendTo" + /// {8983036C-27C0-404B-8F08-102D10DCFD74} /// - internal const string SendTo = "{8983036C-27C0-404B-8F08-102D10DCFD74}"; + internal static ReadOnlySpan SendTo => + [0x6C, 0x03, 0x83, 0x89, 0xC0, 0x27, 0x4B, 0x40, 0x8F, 0x08, 0x10, 0x2D, 0x10, 0xDC, 0xFD, 0x74]; /// /// (CSIDL_STARTMENU) Start Menu folder /// "%APPDATA%\Microsoft\Windows\Start Menu" + /// {625B53C3-AB48-4EC1-BA1F-A1EF4146FC19} /// - internal const string StartMenu = "{625B53C3-AB48-4EC1-BA1F-A1EF4146FC19}"; + internal static ReadOnlySpan StartMenu => + [0xC3, 0x53, 0x5B, 0x62, 0x48, 0xAB, 0xC1, 0x4E, 0xBA, 0x1F, 0xA1, 0xEF, 0x41, 0x46, 0xFC, 0x19]; /// /// (CSIDL_STARTUP, CSIDL_ALTSTARTUP) Startup folder /// "%APPDATA%\Microsoft\Windows\Start Menu\Programs\StartUp" + /// {B97D20BB-F46A-4C97-BA10-5E3608430854} /// - internal const string Startup = "{B97D20BB-F46A-4C97-BA10-5E3608430854}"; + internal static ReadOnlySpan Startup => + [0xBB, 0x20, 0x7D, 0xB9, 0x6A, 0xF4, 0x97, 0x4C, 0xBA, 0x10, 0x5E, 0x36, 0x08, 0x43, 0x08, 0x54]; /// /// (CSIDL_SYSTEMX86) X86 System32 folder /// "%windir%\system32" or "%windir%\syswow64" + /// {D65231B0-B2F1-4857-A4CE-A8E7C6EA7D27} /// - internal const string SystemX86 = "{D65231B0-B2F1-4857-A4CE-A8E7C6EA7D27}"; + internal static ReadOnlySpan SystemX86 => + [0xB0, 0x31, 0x52, 0xD6, 0xF1, 0xB2, 0x57, 0x48, 0xA4, 0xCE, 0xA8, 0xE7, 0xC6, 0xEA, 0x7D, 0x27]; /// /// (CSIDL_TEMPLATES) Templates folder /// "%APPDATA%\Microsoft\Windows\Templates" + /// {A63293E8-664E-48DB-A079-DF759E0509F7} /// - internal const string Templates = "{A63293E8-664E-48DB-A079-DF759E0509F7}"; + internal static ReadOnlySpan Templates => + [0xE8, 0x93, 0x32, 0xA6, 0x4E, 0x66, 0xDB, 0x48, 0xA0, 0x79, 0xDF, 0x75, 0x9E, 0x05, 0x09, 0xF7]; /// /// (CSIDL_MYVIDEO) Videos folder /// "%USERPROFILE%\Videos" + /// {18989B1D-99B5-455B-841C-AB7C74E4DDFC} /// - internal const string Videos = "{18989B1D-99B5-455B-841C-AB7C74E4DDFC}"; + internal static ReadOnlySpan Videos => + [0x1D, 0x9B, 0x98, 0x18, 0xB5, 0x99, 0x5B, 0x45, 0x84, 0x1C, 0xAB, 0x7C, 0x74, 0xE4, 0xDD, 0xFC]; /// /// (CSIDL_WINDOWS) Windows folder "%windir%" + /// {F38BF404-1D43-42F2-9305-67DE0B28FC23} /// - internal const string Windows = "{F38BF404-1D43-42F2-9305-67DE0B28FC23}"; + internal static ReadOnlySpan Windows => + [0x04, 0xF4, 0x8B, 0xF3, 0x43, 0x1D, 0xF2, 0x42, 0x93, 0x05, 0x67, 0xDE, 0x0B, 0x28, 0xFC, 0x23]; } } } diff --git a/src/libraries/Common/src/System/CodeDom/CodeObject.cs b/src/libraries/Common/src/System/CodeDom/CodeObject.cs index f1cd5e40f4af2b..fa06d64db95c9b 100644 --- a/src/libraries/Common/src/System/CodeDom/CodeObject.cs +++ b/src/libraries/Common/src/System/CodeDom/CodeObject.cs @@ -16,10 +16,8 @@ public class CodeObject internal class CodeObject #endif { - private IDictionary? _userData; - public CodeObject() { } - public IDictionary UserData => _userData ??= new ListDictionary(); + public IDictionary UserData => field ??= new ListDictionary(); } } diff --git a/src/libraries/Common/src/System/Data/Common/AdapterUtil.cs b/src/libraries/Common/src/System/Data/Common/AdapterUtil.cs index 956e6ca855e2ef..9a6926208f8690 100644 --- a/src/libraries/Common/src/System/Data/Common/AdapterUtil.cs +++ b/src/libraries/Common/src/System/Data/Common/AdapterUtil.cs @@ -19,11 +19,8 @@ internal static partial class ADP { // NOTE: Initializing a Task in SQL CLR requires the "UNSAFE" permission set (https://learn.microsoft.com/dotnet/framework/performance/sql-server-programming-and-host-protection-attributes) // Therefore we are lazily initializing these Tasks to avoid forcing customers to use the "UNSAFE" set when they are actually using no Async features - private static Task? _trueTask; - internal static Task TrueTask => _trueTask ??= Task.FromResult(true); - - private static Task? _falseTask; - internal static Task FalseTask => _falseTask ??= Task.FromResult(false); + internal static Task TrueTask => field ??= Task.FromResult(true); + internal static Task FalseTask => field ??= Task.FromResult(false); internal const CompareOptions DefaultCompareOptions = CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase; internal const int DefaultConnectionTimeout = DbConnectionStringDefaults.ConnectTimeout; diff --git a/src/libraries/Common/src/System/HexConverter.cs b/src/libraries/Common/src/System/HexConverter.cs index 261009571f8cfa..2b97cdc6b9f812 100644 --- a/src/libraries/Common/src/System/HexConverter.cs +++ b/src/libraries/Common/src/System/HexConverter.cs @@ -3,8 +3,9 @@ using System.Diagnostics; using System.Runtime.CompilerServices; +using System.Numerics; + #if SYSTEM_PRIVATE_CORELIB -using System.Buffers.Binary; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.Arm; @@ -98,6 +99,7 @@ public static void ToCharsBuffer(byte value, Span buffer, int startingInde internal static (Vector128, Vector128) AsciiToHexVector128(Vector128 src, Vector128 hexMap) { Debug.Assert(Ssse3.IsSupported || AdvSimd.Arm64.IsSupported); + // The algorithm is simple: a single srcVec (contains the whole 16b Guid) is converted // into nibbles and then, via hexMap, converted into a HEX representation via // Shuffle(nibbles, srcVec). ASCII is then expanded to UTF-16. @@ -105,18 +107,20 @@ internal static (Vector128, Vector128) AsciiToHexVector128(Vector128 Vector128 lowNibbles = Vector128.UnpackLow(shiftedSrc, src); Vector128 highNibbles = Vector128.UnpackHigh(shiftedSrc, src); - return (Vector128.ShuffleNative(hexMap, lowNibbles & Vector128.Create((byte)0xF)), - Vector128.ShuffleNative(hexMap, highNibbles & Vector128.Create((byte)0xF))); + return ( + Vector128.ShuffleNative(hexMap, lowNibbles & Vector128.Create((byte)0xF)), + Vector128.ShuffleNative(hexMap, highNibbles & Vector128.Create((byte)0xF)) + ); } [CompExactlyDependsOn(typeof(Ssse3))] [CompExactlyDependsOn(typeof(AdvSimd.Arm64))] - private static void EncodeToUtf16_Vector128(ReadOnlySpan bytes, Span chars, Casing casing) + private static void EncodeTo_Vector128(ReadOnlySpan source, Span destination, Casing casing) { - Debug.Assert(bytes.Length >= Vector128.Count); + Debug.Assert(source.Length >= (Vector128.Count / 2)); - ref byte srcRef = ref MemoryMarshal.GetReference(bytes); - ref ushort destRef = ref Unsafe.As(ref MemoryMarshal.GetReference(chars)); + ref byte srcRef = ref MemoryMarshal.GetReference(source); + ref TChar destRef = ref MemoryMarshal.GetReference(destination); Vector128 hexMap = casing == Casing.Upper ? Vector128.Create((byte)'0', (byte)'1', (byte)'2', (byte)'3', @@ -129,25 +133,41 @@ private static void EncodeToUtf16_Vector128(ReadOnlySpan bytes, Span (byte)'c', (byte)'d', (byte)'e', (byte)'f'); nuint pos = 0; - nuint lengthSubVector128 = (nuint)bytes.Length - (nuint)Vector128.Count; + nuint lengthSubVector128 = (nuint)source.Length - (nuint)(Vector128.Count / 2); do { - // This implementation processes 4 bytes of input at once, it can be easily modified + // This implementation processes 4 or 8 bytes of input at once, it can be easily modified // to support 16 bytes at once, but that didn't demonstrate noticeable wins // for Converter.ToHexString (around 8% faster for large inputs) so // it focuses on small inputs instead. - uint i32 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref srcRef, pos)); - Vector128 vec = Vector128.CreateScalar(i32).AsByte(); + Vector128 vec; + + if (typeof(TChar) == typeof(byte)) + { + vec = Vector128.CreateScalar(Unsafe.ReadUnaligned(ref Unsafe.Add(ref srcRef, pos))).AsByte(); + } + else + { + Debug.Assert(typeof(TChar) == typeof(ushort)); + vec = Vector128.CreateScalar(Unsafe.ReadUnaligned(ref Unsafe.Add(ref srcRef, pos))).AsByte(); + } // JIT is expected to eliminate all unused calculations (Vector128 hexLow, _) = AsciiToHexVector128(vec, hexMap); - (Vector128 v0, _) = Vector128.Widen(hexLow); - v0.StoreUnsafe(ref destRef, pos * 2); + if (typeof(TChar) == typeof(byte)) + { + hexLow.As().StoreUnsafe(ref destRef, pos * 2); + } + else + { + Debug.Assert(typeof(TChar) == typeof(ushort)); + Vector128.WidenLower(hexLow).As().StoreUnsafe(ref destRef, pos * 2); + } - pos += (nuint)Vector128.Count; - if (pos == (nuint)bytes.Length) + pos += (nuint)(Vector128.Count / 2); + if (pos == (nuint)source.Length) { return; } @@ -162,27 +182,44 @@ private static void EncodeToUtf16_Vector128(ReadOnlySpan bytes, Span } #endif - public static void EncodeToUtf16(ReadOnlySpan bytes, Span chars, Casing casing = Casing.Upper) + public static void EncodeToUtf8(ReadOnlySpan source, Span utf8Destination, Casing casing = Casing.Upper) { - Debug.Assert(chars.Length >= bytes.Length * 2); + Debug.Assert(utf8Destination.Length >= (source.Length * 2)); #if SYSTEM_PRIVATE_CORELIB - if ((AdvSimd.Arm64.IsSupported || Ssse3.IsSupported) && bytes.Length >= 4) + if ((AdvSimd.Arm64.IsSupported || Ssse3.IsSupported) && (source.Length >= (Vector128.Count / 2))) { - EncodeToUtf16_Vector128(bytes, chars, casing); + EncodeTo_Vector128(source, utf8Destination, casing); return; } #endif - for (int pos = 0; pos < bytes.Length; pos++) + for (int pos = 0; pos < source.Length; pos++) { - ToCharsBuffer(bytes[pos], chars, pos * 2, casing); + ToBytesBuffer(source[pos], utf8Destination, pos * 2, casing); + } + } + + public static void EncodeToUtf16(ReadOnlySpan source, Span destination, Casing casing = Casing.Upper) + { + Debug.Assert(destination.Length >= (source.Length * 2)); + +#if SYSTEM_PRIVATE_CORELIB + if ((AdvSimd.Arm64.IsSupported || Ssse3.IsSupported) && (source.Length >= (Vector128.Count / 2))) + { + EncodeTo_Vector128(source, Unsafe.BitCast, Span>(destination), casing); + return; + } +#endif + for (int pos = 0; pos < source.Length; pos++) + { + ToCharsBuffer(source[pos], destination, pos * 2, casing); } } public static string ToString(ReadOnlySpan bytes, Casing casing = Casing.Upper) { #if NETFRAMEWORK || NETSTANDARD2_0 - Span result = bytes.Length > 16 ? + Span result = (bytes.Length > 16) ? new char[bytes.Length * 2].AsSpan() : stackalloc char[bytes.Length * 2]; @@ -241,85 +278,138 @@ public static char ToCharLower(int value) return (char)value; } - public static bool TryDecodeFromUtf16(ReadOnlySpan chars, Span bytes, out int charsProcessed) + public static bool TryDecodeFromUtf8(ReadOnlySpan utf8Source, Span destination, out int bytesProcessed) + { +#if SYSTEM_PRIVATE_CORELIB + if (BitConverter.IsLittleEndian && (Ssse3.IsSupported || AdvSimd.Arm64.IsSupported || PackedSimd.IsSupported) && + (utf8Source.Length >= Vector128.Count)) + { + return TryDecodeFrom_Vector128(utf8Source, destination, out bytesProcessed); + } +#endif + return TryDecodeFromUtf8_Scalar(utf8Source, destination, out bytesProcessed); + } + + public static bool TryDecodeFromUtf16(ReadOnlySpan source, Span destination, out int charsProcessed) { #if SYSTEM_PRIVATE_CORELIB if (BitConverter.IsLittleEndian && (Ssse3.IsSupported || AdvSimd.Arm64.IsSupported || PackedSimd.IsSupported) && - chars.Length >= Vector128.Count * 2) + (source.Length >= (Vector128.Count * 2))) { - return TryDecodeFromUtf16_Vector128(chars, bytes, out charsProcessed); + return TryDecodeFrom_Vector128(Unsafe.BitCast, ReadOnlySpan>(source), destination, out charsProcessed); } #endif - return TryDecodeFromUtf16_Scalar(chars, bytes, out charsProcessed); + return TryDecodeFromUtf16_Scalar(source, destination, out charsProcessed); } #if SYSTEM_PRIVATE_CORELIB [CompExactlyDependsOn(typeof(AdvSimd.Arm64))] [CompExactlyDependsOn(typeof(Ssse3))] [CompExactlyDependsOn(typeof(PackedSimd))] - public static bool TryDecodeFromUtf16_Vector128(ReadOnlySpan chars, Span bytes, out int charsProcessed) + public static bool TryDecodeFrom_Vector128(ReadOnlySpan source, Span destination, out int elementsProcessed) { Debug.Assert(Ssse3.IsSupported || AdvSimd.Arm64.IsSupported || PackedSimd.IsSupported); - Debug.Assert(chars.Length <= bytes.Length * 2); - Debug.Assert(chars.Length % 2 == 0); - Debug.Assert(chars.Length >= Vector128.Count * 2); + Debug.Assert(source.Length <= (destination.Length * 2)); + Debug.Assert((source.Length % 2) == 0); + + int elementsReadPerIteration; + + if (typeof(TChar) == typeof(byte)) + { + elementsReadPerIteration = Vector128.Count; + } + else + { + Debug.Assert(typeof(TChar) == typeof(ushort)); + elementsReadPerIteration = Vector128.Count * 2; + } + Debug.Assert(source.Length >= elementsReadPerIteration); nuint offset = 0; - nuint lengthSubTwoVector128 = (nuint)chars.Length - ((nuint)Vector128.Count * 2); + nuint lengthSubElementsReadPerIteration = (nuint)source.Length - (nuint)elementsReadPerIteration; - ref ushort srcRef = ref Unsafe.As(ref MemoryMarshal.GetReference(chars)); - ref byte destRef = ref MemoryMarshal.GetReference(bytes); + ref TChar srcRef = ref MemoryMarshal.GetReference(source); + ref byte destRef = ref MemoryMarshal.GetReference(destination); do { // The algorithm is UTF8 so we'll be loading two UTF-16 vectors to narrow them into a // single UTF8 ASCII vector - the implementation can be shared with UTF8 paths. - Vector128 vec1 = Vector128.LoadUnsafe(ref srcRef, offset); - Vector128 vec2 = Vector128.LoadUnsafe(ref srcRef, offset + (nuint)Vector128.Count); - Vector128 vec = Ascii.ExtractAsciiVector(vec1, vec2); + Vector128 vec; + + if (typeof(TChar) == typeof(byte)) + { + vec = Vector128.LoadUnsafe(ref srcRef, offset).AsByte(); + + if (!Utf8Utility.AllBytesInVector128AreAscii(vec)) + { + // Input is non-ASCII + break; + } + } + else + { + Debug.Assert(typeof(TChar) == typeof(ushort)); + + Vector128 vec1 = Vector128.LoadUnsafe(ref srcRef, offset).AsUInt16(); + Vector128 vec2 = Vector128.LoadUnsafe(ref srcRef, offset + (nuint)Vector128.Count).AsUInt16(); + + vec = Ascii.ExtractAsciiVector(vec1, vec2); + + if (!Utf16Utility.AllCharsInVectorAreAscii(vec1 | vec2)) + { + // Input is non-ASCII + break; + } + } // Based on "Algorithm #3" https://github.com/WojciechMula/toys/blob/master/simd-parse-hex/geoff_algorithm.cpp // by Geoff Langdale and Wojciech Mula // Move digits '0'..'9' into range 0xf6..0xff. - Vector128 t1 = vec + Vector128.Create((byte)(0xFF - '9')); + Vector128 t1 = vec + Vector128.Create(0xFF - '9'); + // And then correct the range to 0xf0..0xf9. // All other bytes become less than 0xf0. - Vector128 t2 = Vector128.SubtractSaturate(t1, Vector128.Create((byte)6)); + Vector128 t2 = Vector128.SubtractSaturate(t1, Vector128.Create(6)); + // Convert into uppercase 'a'..'f' => 'A'..'F' and // move hex letter 'A'..'F' into range 0..5. - Vector128 t3 = (vec & Vector128.Create((byte)0xDF)) - Vector128.Create((byte)'A'); + Vector128 t3 = (vec & Vector128.Create(0xDF)) - Vector128.Create((byte)'A'); + // And correct the range into 10..15. // The non-hex letters bytes become greater than 0x0f. - Vector128 t4 = Vector128.AddSaturate(t3, Vector128.Create((byte)10)); + Vector128 t4 = Vector128.AddSaturate(t3, Vector128.Create(10)); + // Convert '0'..'9' into nibbles 0..9. Non-digit bytes become // greater than 0x0f. Finally choose the result: either valid nibble (0..9/10..15) // or some byte greater than 0x0f. - Vector128 nibbles = Vector128.Min(t2 - Vector128.Create((byte)0xF0), t4); + Vector128 nibbles = Vector128.Min(t2 - Vector128.Create(0xF0), t4); + // Any high bit is a sign that input is not a valid hex data - if (!Utf16Utility.AllCharsInVectorAreAscii(vec1 | vec2) || - Vector128.AddSaturate(nibbles, Vector128.Create((byte)(127 - 15))).ExtractMostSignificantBits() != 0) + if (Vector128.AddSaturate(nibbles, Vector128.Create(127 - 15)).ExtractMostSignificantBits() != 0) { - // Input is either non-ASCII or invalid hex data + // Input is invalid hex data break; } + Vector128 output; if (Ssse3.IsSupported) { - output = Ssse3.MultiplyAddAdjacent(nibbles, - Vector128.Create((short)0x0110).AsSByte()).AsByte(); + output = Ssse3.MultiplyAddAdjacent(nibbles, Vector128.Create(0x0110).AsSByte()).AsByte(); } else if (AdvSimd.Arm64.IsSupported) { // Workaround for missing MultiplyAddAdjacent on ARM Vector128 even = AdvSimd.Arm64.TransposeEven(nibbles, Vector128.Zero).AsInt16(); Vector128 odd = AdvSimd.Arm64.TransposeOdd(nibbles, Vector128.Zero).AsInt16(); + even = AdvSimd.ShiftLeftLogical(even, 4).AsInt16(); output = AdvSimd.AddSaturate(even, odd).AsByte(); } else if (PackedSimd.IsSupported) { Vector128 shiftedNibbles = PackedSimd.ShiftLeft(nibbles, 4); - Vector128 zipped = PackedSimd.BitwiseSelect(nibbles, shiftedNibbles, Vector128.Create((ushort)0xFF00).AsByte()); + Vector128 zipped = PackedSimd.BitwiseSelect(nibbles, shiftedNibbles, Vector128.Create(0xFF00).AsByte()); output = PackedSimd.AddPairwiseWidening(zipped).AsByte(); } else @@ -328,57 +418,111 @@ public static bool TryDecodeFromUtf16_Vector128(ReadOnlySpan chars, Span.Count * 2; - if (offset == (nuint)chars.Length) + offset += (nuint)elementsReadPerIteration; + if (offset == (nuint)source.Length) { - charsProcessed = chars.Length; + elementsProcessed = source.Length; return true; } + // Overlap with the current chunk for trailing elements - if (offset > lengthSubTwoVector128) + if (offset > lengthSubElementsReadPerIteration) { - offset = lengthSubTwoVector128; + offset = lengthSubElementsReadPerIteration; } } while (true); // Fall back to the scalar routine in case of invalid input. - bool fallbackResult = TryDecodeFromUtf16_Scalar(chars.Slice((int)offset), bytes.Slice((int)(offset / 2)), out int fallbackProcessed); - charsProcessed = (int)offset + fallbackProcessed; + bool fallbackResult; + + if (typeof(TChar) == typeof(byte)) + { + fallbackResult = TryDecodeFromUtf8_Scalar(Unsafe.BitCast, ReadOnlySpan>(source.Slice((int)offset)), destination.Slice((int)(offset / 2)), out elementsProcessed); + } + else + { + Debug.Assert(typeof(TChar) == typeof(ushort)); + fallbackResult = TryDecodeFromUtf16_Scalar(Unsafe.BitCast, ReadOnlySpan>(source.Slice((int)offset)), destination.Slice((int)(offset / 2)), out elementsProcessed); + } + + elementsProcessed = (int)offset + elementsProcessed; return fallbackResult; } #endif - private static bool TryDecodeFromUtf16_Scalar(ReadOnlySpan chars, Span bytes, out int charsProcessed) + private static bool TryDecodeFromUtf8_Scalar(ReadOnlySpan utf8Source, Span destination, out int bytesProcessed) + { + Debug.Assert((utf8Source.Length % 2) == 0, "Un-even number of characters provided"); + Debug.Assert((utf8Source.Length / 2) == destination.Length, "Target buffer not right-sized for provided characters"); + + int i = 0; + int j = 0; + int byteLo = 0; + int byteHi = 0; + + while (j < destination.Length) + { + byteLo = FromChar(utf8Source[i + 1]); + byteHi = FromChar(utf8Source[i]); + + // byteHi hasn't been shifted to the high half yet, so the only way the bitwise or produces this pattern + // is if either byteHi or byteLo was not a hex character. + if ((byteLo | byteHi) == 0xFF) + { + break; + } + + destination[j++] = (byte)((byteHi << 4) | byteLo); + i += 2; + } + + if (byteLo == 0xFF) + { + i++; + } + + bytesProcessed = i; + return (byteLo | byteHi) != 0xFF; + } + + private static bool TryDecodeFromUtf16_Scalar(ReadOnlySpan source, Span destination, out int charsProcessed) { - Debug.Assert(chars.Length % 2 == 0, "Un-even number of characters provided"); - Debug.Assert(chars.Length / 2 == bytes.Length, "Target buffer not right-sized for provided characters"); + Debug.Assert((source.Length % 2) == 0, "Un-even number of characters provided"); + Debug.Assert((source.Length / 2) == destination.Length, "Target buffer not right-sized for provided characters"); int i = 0; int j = 0; int byteLo = 0; int byteHi = 0; - while (j < bytes.Length) + + while (j < destination.Length) { - byteLo = FromChar(chars[i + 1]); - byteHi = FromChar(chars[i]); + byteLo = FromChar(source[i + 1]); + byteHi = FromChar(source[i]); // byteHi hasn't been shifted to the high half yet, so the only way the bitwise or produces this pattern // is if either byteHi or byteLo was not a hex character. if ((byteLo | byteHi) == 0xFF) + { break; + } - bytes[j++] = (byte)((byteHi << 4) | byteLo); + destination[j++] = (byte)((byteHi << 4) | byteLo); i += 2; } if (byteLo == 0xFF) + { i++; + } charsProcessed = i; return (byteLo | byteHi) != 0xFF; @@ -387,23 +531,27 @@ private static bool TryDecodeFromUtf16_Scalar(ReadOnlySpan chars, Span= CharToHexLookup.Length ? 0xFF : CharToHexLookup[c]; + return (c >= CharToHexLookup.Length) ? 0xFF : CharToHexLookup[c]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int FromUpperChar(int c) { - return c > 71 ? 0xFF : CharToHexLookup[c]; + return (c > 71) ? 0xFF : CharToHexLookup[c]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int FromLowerChar(int c) { - if ((uint)(c - '0') <= '9' - '0') + if ((uint)(c - '0') <= ('9' - '0')) + { return c - '0'; + } - if ((uint)(c - 'a') <= 'f' - 'a') + if ((uint)(c - 'a') <= ('f' - 'a')) + { return c - 'a' + 10; + } return 0xFF; } @@ -442,13 +590,13 @@ public static bool IsHexChar(int c) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsHexUpperChar(int c) { - return (uint)(c - '0') <= 9 || (uint)(c - 'A') <= ('F' - 'A'); + return ((uint)(c - '0') <= 9) || ((uint)(c - 'A') <= ('F' - 'A')); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsHexLowerChar(int c) { - return (uint)(c - '0') <= 9 || (uint)(c - 'a') <= ('f' - 'a'); + return ((uint)(c - '0') <= 9) || ((uint)(c - 'a') <= ('f' - 'a')); } /// Map from an ASCII char to its hex value, e.g. arr['b'] == 11. 0xFF means it's not a hex digit. diff --git a/src/libraries/Common/src/System/IO/PathInternal.CaseSensitivity.cs b/src/libraries/Common/src/System/IO/PathInternal.CaseSensitivity.cs index 32769debc29d12..0e1278fd1a2cab 100644 --- a/src/libraries/Common/src/System/IO/PathInternal.CaseSensitivity.cs +++ b/src/libraries/Common/src/System/IO/PathInternal.CaseSensitivity.cs @@ -24,7 +24,7 @@ internal static bool IsCaseSensitive { get { - return !(OperatingSystem.IsWindows() || OperatingSystem.IsMacOS() || OperatingSystem.IsIOS() || OperatingSystem.IsTvOS() || OperatingSystem.IsWatchOS()); + return !(OperatingSystem.IsWindows() || OperatingSystem.IsMacOS() || OperatingSystem.IsIOS() || OperatingSystem.IsTvOS()); } } } diff --git a/src/libraries/Common/src/System/IO/PathInternal.cs b/src/libraries/Common/src/System/IO/PathInternal.cs index f13819c8ea3d62..4e4145c2ec4120 100644 --- a/src/libraries/Common/src/System/IO/PathInternal.cs +++ b/src/libraries/Common/src/System/IO/PathInternal.cs @@ -218,7 +218,7 @@ internal static bool RemoveRelativeSegments(ReadOnlySpan path, int rootLen [return: NotNullIfNotNull(nameof(path))] internal static string? TrimEndingDirectorySeparator(string? path) => EndsInDirectorySeparator(path) && !IsRoot(path.AsSpan()) ? - path!.Substring(0, path.Length - 1) : + path.Substring(0, path.Length - 1) : path; /// diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HuffmanDecodingException.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HuffmanDecodingException.cs index b83ca6502e8c55..181d441c54588a 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HuffmanDecodingException.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HuffmanDecodingException.cs @@ -19,26 +19,20 @@ public HuffmanDecodingException(string message) { } -#if NET8_0_OR_GREATER [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] -#endif private HuffmanDecodingException(SerializationInfo info, StreamingContext context) : base(info, context) { } -#if NET8_0_OR_GREATER [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] -#endif void ISerializable.GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext) { base.GetObjectData(serializationInfo, streamingContext); } -#if NET8_0_OR_GREATER [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] -#endif public override void GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext) { base.GetObjectData(serializationInfo, streamingContext); diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/H3StaticTable.Http3.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/H3StaticTable.Http3.cs index aa157ab41b6763..aee248efc78a35 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/H3StaticTable.Http3.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/H3StaticTable.Http3.cs @@ -1,24 +1,12 @@ // 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.Generic; using System.Text; namespace System.Net.Http.QPack { internal static partial class H3StaticTable { - private static readonly Dictionary s_methodIndex = new Dictionary - { - // TODO connect is internal to system.net.http - [HttpMethod.Delete] = 16, - [HttpMethod.Get] = 17, - [HttpMethod.Head] = 18, - [HttpMethod.Options] = 19, - [HttpMethod.Post] = 20, - [HttpMethod.Put] = 21, - }; - public static bool TryGetStatusIndex(int status, out int index) { index = status switch @@ -45,9 +33,6 @@ public static bool TryGetStatusIndex(int status, out int index) public static int Count => s_staticTable.Length; - // TODO: just use Dictionary directly to avoid interface dispatch. - public static IReadOnlyDictionary MethodIndex => s_methodIndex; - public static ref readonly HeaderField Get(int index) => ref s_staticTable[index]; private static readonly HeaderField[] s_staticTable = new HeaderField[] diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackDecodingException.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackDecodingException.cs index 5de0efff935d4f..0442ef2252e634 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackDecodingException.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackDecodingException.cs @@ -21,9 +21,7 @@ public QPackDecodingException(string message, Exception innerException) : base(m { } -#if NET8_0_OR_GREATER [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] -#endif private QPackDecodingException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackEncodingException.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackEncodingException.cs index 7e6eb6f1b79280..f2eb1b6944946b 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackEncodingException.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackEncodingException.cs @@ -18,9 +18,7 @@ public QPackEncodingException(string message, Exception innerException) { } -#if NET8_0_OR_GREATER [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] -#endif private QPackEncodingException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/libraries/Common/src/System/Net/NetworkInformation/NetworkInformationException.cs b/src/libraries/Common/src/System/Net/NetworkInformation/NetworkInformationException.cs index 14d23cad452391..d973aaedf8f458 100644 --- a/src/libraries/Common/src/System/Net/NetworkInformation/NetworkInformationException.cs +++ b/src/libraries/Common/src/System/Net/NetworkInformation/NetworkInformationException.cs @@ -35,10 +35,8 @@ public NetworkInformationException(int errorCode) : base(errorCode) { } -#if NET8_0_OR_GREATER [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] -#endif protected NetworkInformationException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { } diff --git a/src/libraries/Common/src/System/Net/ReadWriteAdapter.cs b/src/libraries/Common/src/System/Net/ReadWriteAdapter.cs index 78fe5e65c4d49f..7019d6f1da4917 100644 --- a/src/libraries/Common/src/System/Net/ReadWriteAdapter.cs +++ b/src/libraries/Common/src/System/Net/ReadWriteAdapter.cs @@ -14,6 +14,8 @@ internal interface IReadWriteAdapter static abstract ValueTask WriteAsync(Stream stream, ReadOnlyMemory buffer, CancellationToken cancellationToken); static abstract Task FlushAsync(Stream stream, CancellationToken cancellationToken); static abstract Task WaitAsync(TaskCompletionSource waiter); + static abstract Task WaitAsync(Task task); + static abstract ValueTask WaitAsync(ValueTask task); } internal readonly struct AsyncReadWriteAdapter : IReadWriteAdapter @@ -30,6 +32,8 @@ public static ValueTask WriteAsync(Stream stream, ReadOnlyMemory buffer, C public static Task FlushAsync(Stream stream, CancellationToken cancellationToken) => stream.FlushAsync(cancellationToken); public static Task WaitAsync(TaskCompletionSource waiter) => waiter.Task; + public static Task WaitAsync(Task task) => task; + public static ValueTask WaitAsync(ValueTask task) => task; } internal readonly struct SyncReadWriteAdapter : IReadWriteAdapter @@ -57,5 +61,16 @@ public static Task WaitAsync(TaskCompletionSource waiter) waiter.Task.GetAwaiter().GetResult(); return Task.CompletedTask; } + + public static Task WaitAsync(Task task) + { + task.GetAwaiter().GetResult(); + return Task.CompletedTask; + } + + public static ValueTask WaitAsync(ValueTask task) + { + return ValueTask.FromResult(task.AsTask().GetAwaiter().GetResult()); + } } } diff --git a/src/libraries/Common/src/System/Net/Security/CertificateValidation.OSX.cs b/src/libraries/Common/src/System/Net/Security/CertificateValidation.OSX.cs index b269a0fb70fa5b..f0ce7002b3d4e8 100644 --- a/src/libraries/Common/src/System/Net/Security/CertificateValidation.OSX.cs +++ b/src/libraries/Common/src/System/Net/Security/CertificateValidation.OSX.cs @@ -13,8 +13,9 @@ internal static class CertificateValidation { private static readonly IdnMapping s_idnMapping = new IdnMapping(); - // WARNING: This function will do the verification using OpenSSL. If the intention is to use OS function, caller should use CertificatePal interface. - internal static SslPolicyErrors BuildChainAndVerifyProperties(X509Chain chain, X509Certificate2 remoteCertificate, bool checkCertName, bool _ /*isServer*/, string? hostName, Span certificateBuffer) +#pragma warning disable IDE0060 + internal static SslPolicyErrors BuildChainAndVerifyProperties(X509Chain chain, X509Certificate2 remoteCertificate, bool checkCertName, bool isServer, string? hostName, Span certificateBuffer) +#pragma warning restore IDE0060 { SslPolicyErrors errors = chain.Build(remoteCertificate) ? SslPolicyErrors.None : @@ -30,53 +31,19 @@ internal static SslPolicyErrors BuildChainAndVerifyProperties(X509Chain chain, X return errors | SslPolicyErrors.RemoteCertificateNameMismatch; } - SafeX509Handle certHandle; - unsafe + bool match; + + if (IPAddress.TryParse(hostName, out _)) { - if (certificateBuffer.Length > 0) - { - fixed (byte* pCert = certificateBuffer) - { - certHandle = Interop.Crypto.DecodeX509((IntPtr)pCert, certificateBuffer.Length); - } - } - else - { - // We dont't have DER encoded buffer. - byte[] der = remoteCertificate.Export(X509ContentType.Cert); - fixed (byte* pDer = der) - { - certHandle = Interop.Crypto.DecodeX509((IntPtr)pDer, der.Length); - } - } + match = remoteCertificate.MatchesHostname(hostName); } - - int hostNameMatch; - using (certHandle) + else { - IPAddress? hostnameAsIp; - if (IPAddress.TryParse(hostName, out hostnameAsIp)) - { - byte[] addressBytes = hostnameAsIp.GetAddressBytes(); - hostNameMatch = Interop.Crypto.CheckX509IpAddress(certHandle, addressBytes, addressBytes.Length, hostName, hostName.Length); - } - else - { - // 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.-]+" - string matchName = s_idnMapping.GetAscii(hostName); - hostNameMatch = Interop.Crypto.CheckX509Hostname(certHandle, matchName, matchName.Length); - - if (hostNameMatch < 0) - { - throw Interop.Crypto.CreateOpenSslCryptographicException(); - } - } + string matchName = s_idnMapping.GetAscii(hostName); + match = remoteCertificate.MatchesHostname(matchName); } - Debug.Assert(hostNameMatch == 0 || hostNameMatch == 1, $"Expected 0 or 1 from CheckX509Hostname, got {hostNameMatch}"); - return hostNameMatch == 1 ? + return match ? errors : errors | SslPolicyErrors.RemoteCertificateNameMismatch; } diff --git a/src/libraries/Common/src/System/Obsoletions.cs b/src/libraries/Common/src/System/Obsoletions.cs index cbba37ed07be17..45a552749a9614 100644 --- a/src/libraries/Common/src/System/Obsoletions.cs +++ b/src/libraries/Common/src/System/Obsoletions.cs @@ -195,6 +195,9 @@ internal static class Obsoletions internal const string QueryableMinByMaxByTSourceObsoleteMessage = "The Queryable MinBy and MaxBy taking an IComparer are obsolete. Use the new ones that take an IComparer."; internal const string QueryableMinByMaxByTSourceObsoleteDiagId = "SYSLIB0061"; + internal const string XsltSettingsEnableScriptMessage = "XSLT Script blocks are not supported."; + internal const string XsltSettingsEnableScriptDiagId = "SYSLIB0062"; + // When adding a new diagnostic ID, add it to the table in docs\project\list-of-diagnostics.md as well. // Keep new const identifiers above this comment. } diff --git a/src/libraries/Common/src/System/Reflection/AssemblyNameParser.cs b/src/libraries/Common/src/System/Reflection/AssemblyNameParser.cs index 5e60f0d5badf2d..162c2273392321 100644 --- a/src/libraries/Common/src/System/Reflection/AssemblyNameParser.cs +++ b/src/libraries/Common/src/System/Reflection/AssemblyNameParser.cs @@ -246,7 +246,7 @@ private static bool IsAttribute(string candidate, string attributeKind) private static bool TryParseVersion(string attributeValue, ref Version? version) { -#if NET8_0_OR_GREATER +#if NET ReadOnlySpan attributeValueSpan = attributeValue; Span parts = stackalloc Range[5]; parts = parts.Slice(0, attributeValueSpan.Split(parts, '.')); @@ -262,7 +262,7 @@ private static bool TryParseVersion(string attributeValue, ref Version? version) for (int i = 0; i < parts.Length; i++) { if (!ushort.TryParse( -#if NET8_0_OR_GREATER +#if NET attributeValueSpan[parts[i]], #else parts[i], diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml index 2467b1348ac786..e6101a539349f9 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml @@ -2,8 +2,7 @@ + namespace="System.Security.Cryptography.Asn1"> - - - - - - - - + + + + + + + + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs index cb41a1559f8549..1dd2b4dc52f808 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs @@ -12,14 +12,14 @@ namespace System.Security.Cryptography.Asn1 internal partial struct RSAPrivateKeyAsn { internal int Version; - internal System.Numerics.BigInteger Modulus; - internal System.Numerics.BigInteger PublicExponent; - internal System.Numerics.BigInteger PrivateExponent; - internal System.Numerics.BigInteger Prime1; - internal System.Numerics.BigInteger Prime2; - internal System.Numerics.BigInteger Exponent1; - internal System.Numerics.BigInteger Exponent2; - internal System.Numerics.BigInteger Coefficient; + internal ReadOnlyMemory Modulus; + internal ReadOnlyMemory PublicExponent; + internal ReadOnlyMemory PrivateExponent; + internal ReadOnlyMemory Prime1; + internal ReadOnlyMemory Prime2; + internal ReadOnlyMemory Exponent1; + internal ReadOnlyMemory Exponent2; + internal ReadOnlyMemory Coefficient; internal readonly void Encode(AsnWriter writer) { @@ -31,14 +31,14 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag) writer.PushSequence(tag); writer.WriteInteger(Version); - writer.WriteInteger(Modulus); - writer.WriteInteger(PublicExponent); - writer.WriteInteger(PrivateExponent); - writer.WriteInteger(Prime1); - writer.WriteInteger(Prime2); - writer.WriteInteger(Exponent1); - writer.WriteInteger(Exponent2); - writer.WriteInteger(Coefficient); + writer.WriteInteger(Modulus.Span); + writer.WriteInteger(PublicExponent.Span); + writer.WriteInteger(PrivateExponent.Span); + writer.WriteInteger(Prime1.Span); + writer.WriteInteger(Prime2.Span); + writer.WriteInteger(Exponent1.Span); + writer.WriteInteger(Exponent2.Span); + writer.WriteInteger(Coefficient.Span); writer.PopSequence(tag); } @@ -53,7 +53,7 @@ internal static RSAPrivateKeyAsn Decode(Asn1Tag expectedTag, ReadOnlyMemory rebind, out RSAPrivateKeyAsn decoded) { - Decode(ref reader, Asn1Tag.Sequence, out decoded); + Decode(ref reader, Asn1Tag.Sequence, rebind, out decoded); } - internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, out RSAPrivateKeyAsn decoded) + internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory rebind, out RSAPrivateKeyAsn decoded) { try { - DecodeCore(ref reader, expectedTag, out decoded); + DecodeCore(ref reader, expectedTag, rebind, out decoded); } catch (AsnContentException e) { @@ -80,10 +80,13 @@ internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, out } } - private static void DecodeCore(ref AsnValueReader reader, Asn1Tag expectedTag, out RSAPrivateKeyAsn decoded) + private static void DecodeCore(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory rebind, out RSAPrivateKeyAsn decoded) { decoded = default; AsnValueReader sequenceReader = reader.ReadSequence(expectedTag); + ReadOnlySpan rebindSpan = rebind.Span; + int offset; + ReadOnlySpan tmpSpan; if (!sequenceReader.TryReadInt32(out decoded.Version)) @@ -91,14 +94,22 @@ private static void DecodeCore(ref AsnValueReader reader, Asn1Tag expectedTag, o sequenceReader.ThrowIfNotEmpty(); } - decoded.Modulus = sequenceReader.ReadInteger(); - decoded.PublicExponent = sequenceReader.ReadInteger(); - decoded.PrivateExponent = sequenceReader.ReadInteger(); - decoded.Prime1 = sequenceReader.ReadInteger(); - decoded.Prime2 = sequenceReader.ReadInteger(); - decoded.Exponent1 = sequenceReader.ReadInteger(); - decoded.Exponent2 = sequenceReader.ReadInteger(); - decoded.Coefficient = sequenceReader.ReadInteger(); + tmpSpan = sequenceReader.ReadIntegerBytes(); + decoded.Modulus = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray(); + tmpSpan = sequenceReader.ReadIntegerBytes(); + decoded.PublicExponent = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray(); + tmpSpan = sequenceReader.ReadIntegerBytes(); + decoded.PrivateExponent = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray(); + tmpSpan = sequenceReader.ReadIntegerBytes(); + decoded.Prime1 = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray(); + tmpSpan = sequenceReader.ReadIntegerBytes(); + decoded.Prime2 = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray(); + tmpSpan = sequenceReader.ReadIntegerBytes(); + decoded.Exponent1 = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray(); + tmpSpan = sequenceReader.ReadIntegerBytes(); + decoded.Exponent2 = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray(); + tmpSpan = sequenceReader.ReadIntegerBytes(); + decoded.Coefficient = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray(); sequenceReader.ThrowIfNotEmpty(); } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml index a0b90d25c84879..d74ed507512a39 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml @@ -2,8 +2,7 @@ + namespace="System.Security.Cryptography.Asn1"> - - + + \ No newline at end of file diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs index fbbf3cea960f26..acaf3474954359 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs @@ -11,8 +11,8 @@ namespace System.Security.Cryptography.Asn1 [StructLayout(LayoutKind.Sequential)] internal partial struct RSAPublicKeyAsn { - internal System.Numerics.BigInteger Modulus; - internal System.Numerics.BigInteger PublicExponent; + internal ReadOnlyMemory Modulus; + internal ReadOnlyMemory PublicExponent; internal readonly void Encode(AsnWriter writer) { @@ -23,8 +23,8 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag) { writer.PushSequence(tag); - writer.WriteInteger(Modulus); - writer.WriteInteger(PublicExponent); + writer.WriteInteger(Modulus.Span); + writer.WriteInteger(PublicExponent.Span); writer.PopSequence(tag); } @@ -39,7 +39,7 @@ internal static RSAPublicKeyAsn Decode(Asn1Tag expectedTag, ReadOnlyMemory { AsnValueReader reader = new AsnValueReader(encoded.Span, ruleSet); - DecodeCore(ref reader, expectedTag, out RSAPublicKeyAsn decoded); + DecodeCore(ref reader, expectedTag, encoded, out RSAPublicKeyAsn decoded); reader.ThrowIfNotEmpty(); return decoded; } @@ -49,16 +49,16 @@ internal static RSAPublicKeyAsn Decode(Asn1Tag expectedTag, ReadOnlyMemory } } - internal static void Decode(ref AsnValueReader reader, out RSAPublicKeyAsn decoded) + internal static void Decode(ref AsnValueReader reader, ReadOnlyMemory rebind, out RSAPublicKeyAsn decoded) { - Decode(ref reader, Asn1Tag.Sequence, out decoded); + Decode(ref reader, Asn1Tag.Sequence, rebind, out decoded); } - internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, out RSAPublicKeyAsn decoded) + internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory rebind, out RSAPublicKeyAsn decoded) { try { - DecodeCore(ref reader, expectedTag, out decoded); + DecodeCore(ref reader, expectedTag, rebind, out decoded); } catch (AsnContentException e) { @@ -66,13 +66,18 @@ internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, out } } - private static void DecodeCore(ref AsnValueReader reader, Asn1Tag expectedTag, out RSAPublicKeyAsn decoded) + private static void DecodeCore(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory rebind, out RSAPublicKeyAsn decoded) { decoded = default; AsnValueReader sequenceReader = reader.ReadSequence(expectedTag); + ReadOnlySpan rebindSpan = rebind.Span; + int offset; + ReadOnlySpan tmpSpan; - decoded.Modulus = sequenceReader.ReadInteger(); - decoded.PublicExponent = sequenceReader.ReadInteger(); + tmpSpan = sequenceReader.ReadIntegerBytes(); + decoded.Modulus = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray(); + tmpSpan = sequenceReader.ReadIntegerBytes(); + decoded.PublicExponent = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray(); sequenceReader.ThrowIfNotEmpty(); } diff --git a/src/libraries/Common/src/System/Security/Cryptography/AsymmetricAlgorithmHelpers.Der.cs b/src/libraries/Common/src/System/Security/Cryptography/AsymmetricAlgorithmHelpers.Der.cs index 0f0a8b173be7c7..794e0b79dfc7cf 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/AsymmetricAlgorithmHelpers.Der.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/AsymmetricAlgorithmHelpers.Der.cs @@ -2,11 +2,109 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Formats.Asn1; namespace System.Security.Cryptography { internal static partial class AsymmetricAlgorithmHelpers { + /// + /// Convert Ieee1363 format of (r, s) to Der format + /// + public static byte[] ConvertIeee1363ToDer(ReadOnlySpan input) + { + AsnWriter writer = WriteIeee1363ToDer(input); + return writer.Encode(); + } + + internal static bool TryConvertIeee1363ToDer( + ReadOnlySpan input, + Span destination, + out int bytesWritten) + { + AsnWriter writer = WriteIeee1363ToDer(input); + return writer.TryEncode(destination, out bytesWritten); + } + + private static AsnWriter WriteIeee1363ToDer(ReadOnlySpan input) + { + Debug.Assert(input.Length % 2 == 0); + Debug.Assert(input.Length > 1); + + // Input is (r, s), each of them exactly half of the array. + // Output is the DER encoded value of SEQUENCE(INTEGER(r), INTEGER(s)). + int halfLength = input.Length / 2; + + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + writer.PushSequence(); + writer.WriteKeyParameterInteger(input.Slice(0, halfLength)); + writer.WriteKeyParameterInteger(input.Slice(halfLength, halfLength)); + writer.PopSequence(); + return writer; + } + + /// + /// Convert Der format of (r, s) to Ieee1363 format + /// + public static byte[] ConvertDerToIeee1363(ReadOnlySpan input, int fieldSizeBits) + { + int fieldSizeBytes = BitsToBytes(fieldSizeBits); + int encodedSize = 2 * fieldSizeBytes; + byte[] response = new byte[encodedSize]; + + ConvertDerToIeee1363(input, fieldSizeBits, response); + return response; + } + + internal static int ConvertDerToIeee1363(ReadOnlySpan input, int fieldSizeBits, Span destination) + { + int fieldSizeBytes = BitsToBytes(fieldSizeBits); + int encodedSize = 2 * fieldSizeBytes; + + Debug.Assert(destination.Length >= encodedSize); + + try + { + AsnValueReader reader = new AsnValueReader(input, AsnEncodingRules.DER); + AsnValueReader sequenceReader = reader.ReadSequence(); + reader.ThrowIfNotEmpty(); + ReadOnlySpan rDer = sequenceReader.ReadIntegerBytes(); + ReadOnlySpan sDer = sequenceReader.ReadIntegerBytes(); + sequenceReader.ThrowIfNotEmpty(); + + CopySignatureField(rDer, destination.Slice(0, fieldSizeBytes)); + CopySignatureField(sDer, destination.Slice(fieldSizeBytes, fieldSizeBytes)); + return encodedSize; + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void CopySignatureField(ReadOnlySpan signatureField, Span response) + { + if (signatureField.Length > response.Length) + { + if (signatureField.Length != response.Length + 1 || + signatureField[0] != 0 || + signatureField[1] <= 0x7F) + { + // The only way this should be true is if the value required a zero-byte-pad. + Debug.Fail($"A signature field was longer ({signatureField.Length}) than expected ({response.Length})"); + throw new CryptographicException(); + } + + signatureField = signatureField.Slice(1); + } + + // If the field is too short then it needs to be prepended + // with zeroes in the response. + int writeOffset = response.Length - signatureField.Length; + response.Slice(0, writeOffset).Clear(); + signatureField.CopyTo(response.Slice(writeOffset)); + } + internal static int BitsToBytes(int bitLength) { int byteLength = (bitLength + 7) / 8; diff --git a/src/libraries/Common/src/System/Security/Cryptography/CngHelpers.cs b/src/libraries/Common/src/System/Security/Cryptography/CngHelpers.cs index e13c839f6ea2bc..1c781f653ce425 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CngHelpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CngHelpers.cs @@ -17,6 +17,22 @@ internal static CryptographicException ToCryptographicException(this Interop.NCr return ((int)errorCode).ToCryptographicException(); } + internal static SafeNCryptProviderHandle OpenStorageProvider(this CngProvider provider) + { + ErrorCode errorCode = Interop.NCrypt.NCryptOpenStorageProvider( + out SafeNCryptProviderHandle providerHandle, + provider.Provider, + 0); + + if (errorCode != ErrorCode.ERROR_SUCCESS) + { + providerHandle.Dispose(); + throw errorCode.ToCryptographicException(); + } + + return providerHandle; + } + internal static void SetExportPolicy(this SafeNCryptKeyHandle keyHandle, CngExportPolicies exportPolicy) { unsafe @@ -125,6 +141,40 @@ internal static void SetExportPolicy(this SafeNCryptKeyHandle keyHandle, CngExpo } } + internal delegate void ExportKeyBlobCallback(ReadOnlySpan blob); + + internal static void ExportKeyBlob( + this SafeNCryptKeyHandle handle, + string blobType, + ExportKeyBlobCallback callback) + { + int numBytesNeeded; + ErrorCode errorCode = Interop.NCrypt.NCryptExportKey(handle, IntPtr.Zero, blobType, IntPtr.Zero, null, 0, out numBytesNeeded, 0); + if (errorCode != ErrorCode.ERROR_SUCCESS) + throw errorCode.ToCryptographicException(); + + byte[] buffer = CryptoPool.Rent(numBytesNeeded); + + try + { + using (PinAndClear.Track(buffer)) + { + errorCode = Interop.NCrypt.NCryptExportKey(handle, IntPtr.Zero, blobType, IntPtr.Zero, buffer, buffer.Length, out numBytesNeeded, 0); + if (errorCode != ErrorCode.ERROR_SUCCESS) + throw errorCode.ToCryptographicException(); + + // The second call to NCryptExportKey should always return the same number of bytes as the first call, + // but we will slice the buffer just in case. + callback(buffer.AsSpan(0, numBytesNeeded)); + } + } + finally + { + // Already cleared by PinAndClear.Track above + CryptoPool.Return(buffer, clearSize: 0); + } + } + internal static bool TryExportKeyBlob( this SafeNCryptKeyHandle handle, string blobType, @@ -192,11 +242,7 @@ internal static unsafe bool ExportPkcs8KeyBlob( Interop.NCrypt.PBE_PARAMS pbeParams = default; Span salt = new Span(pbeParams.rgbSalt, Interop.NCrypt.PBE_PARAMS.RgbSaltSize); -#if NET RandomNumberGenerator.Fill(salt); -#else - CngHelpers.GetRandomBytes(salt); -#endif pbeParams.Params.cbSalt = salt.Length; pbeParams.Params.iIterations = kdfCount; diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsa.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsa.cs index ace8f116be1a51..6b7cd722e3ecd5 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsa.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsa.cs @@ -89,8 +89,15 @@ protected CompositeMLDsa(CompositeMLDsaAlgorithm algorithm) /// /// if the algorithm is supported; otherwise, . /// - public static bool IsAlgorithmSupported(CompositeMLDsaAlgorithm algorithm) => - CompositeMLDsaImplementation.IsAlgorithmSupportedImpl(algorithm); + /// + /// is . + /// + public static bool IsAlgorithmSupported(CompositeMLDsaAlgorithm algorithm) + { + ArgumentNullException.ThrowIfNull(algorithm); + + return CompositeMLDsaImplementation.IsAlgorithmSupportedImpl(algorithm); + } /// /// Signs the specified data. @@ -136,23 +143,32 @@ public byte[] SignData(byte[] data, byte[]? context = default) ThrowIfDisposed(); - // TODO If we know exact size of signature, then we can allocate instead of renting and copying. - byte[] rented = CryptoPool.Rent(Algorithm.MaxSignatureSizeInBytes); - - try + if (Algorithm.MinSignatureSizeInBytes == Algorithm.MaxSignatureSizeInBytes) { - if (!TrySignDataCore(new ReadOnlySpan(data), new ReadOnlySpan(context), rented, out int written)) + byte[] signature = new byte[Algorithm.MaxSignatureSizeInBytes]; + int bytesWritten = SignDataCore(new ReadOnlySpan(data), new ReadOnlySpan(context), signature); + + if (signature.Length != bytesWritten) { - Debug.Fail($"Signature exceeds {nameof(Algorithm.MaxSignatureSizeInBytes)} ({Algorithm.MaxSignatureSizeInBytes})."); throw new CryptographicException(); } - return rented.AsSpan(0, written).ToArray(); + return signature; } - finally + + using (CryptoPoolLease lease = CryptoPoolLease.Rent(Algorithm.MaxSignatureSizeInBytes, skipClear: true)) { - // Signature does not contain sensitive information. - CryptoPool.Return(rented, clearSize: 0); + int bytesWritten = SignDataCore( + new ReadOnlySpan(data), + new ReadOnlySpan(context), + lease.Span); + + if (!Algorithm.IsValidSignatureSize(bytesWritten)) + { + throw new CryptographicException(); + } + + return lease.Span.Slice(0, bytesWritten).ToArray(); } } @@ -163,20 +179,18 @@ public byte[] SignData(byte[] data, byte[]? context = default) /// The data to sign. /// /// - /// The buffer to receive the signature. + /// The buffer to receive the signature. Its length must be at least . /// /// /// An optional context-specific value to limit the scope of the signature. /// The default value is an empty buffer. /// - /// - /// When this method returns, contains the number of bytes written to the buffer. - /// This parameter is treated as uninitialized. - /// /// - /// if was large enough to hold the result; - /// otherwise, . + /// The number of bytes written to the buffer. /// + /// + /// is less than in length. + /// /// /// has a in excess of /// 255 bytes. @@ -189,10 +203,7 @@ public byte[] SignData(byte[] data, byte[]? context = default) /// -or- /// An error occurred while signing the data. /// - /// - /// The signature will be at most in length. - /// - public bool TrySignData(ReadOnlySpan data, Span destination, out int bytesWritten, ReadOnlySpan context = default) + public int SignData(ReadOnlySpan data, Span destination, ReadOnlySpan context = default) { if (context.Length > MaxContextLength) { @@ -202,15 +213,23 @@ public bool TrySignData(ReadOnlySpan data, Span destination, out int SR.Argument_SignatureContextTooLong255); } + if (destination.Length < Algorithm.MaxSignatureSizeInBytes) + { + throw new ArgumentException(SR.Argument_DestinationTooShort, nameof(destination)); + } + ThrowIfDisposed(); - if (destination.Length < Algorithm.MLDsaAlgorithm.SignatureSizeInBytes) + int bytesWritten = SignDataCore(data, context, destination.Slice(0, Algorithm.MaxSignatureSizeInBytes)); + + if (!Algorithm.IsValidSignatureSize(bytesWritten)) { - bytesWritten = 0; - return false; + CryptographicOperations.ZeroMemory(destination); + + throw new CryptographicException(); } - return TrySignDataCore(data, context, destination, out bytesWritten); + return bytesWritten; } /// @@ -224,20 +243,15 @@ public bool TrySignData(ReadOnlySpan data, Span destination, out int /// The signature context. /// /// - /// The buffer to receive the signature, whose length will be at least the ML-DSA component's signature size. - /// - /// - /// When this method returns, contains the number of bytes written to the buffer. - /// This parameter is treated as uninitialized. + /// The buffer to receive the signature, whose length will be exactly . /// /// - /// if was large enough to hold the result; - /// otherwise, . + /// The number of bytes written to the buffer. /// /// /// An error occurred while signing the data. /// - protected abstract bool TrySignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination, out int bytesWritten); + protected abstract int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination); /// /// Verifies that the specified signature is valid for this key and the provided data. @@ -316,7 +330,7 @@ public bool VerifyData(ReadOnlySpan data, ReadOnlySpan signature, Re ThrowIfDisposed(); - if (signature.Length < Algorithm.MLDsaAlgorithm.SignatureSizeInBytes) + if (!Algorithm.IsValidSignatureSize(signature.Length)) { return false; } @@ -660,9 +674,9 @@ static void SubjectPublicKeyReader(ReadOnlyMemory key, in AlgorithmIdentif { CompositeMLDsaAlgorithm algorithm = GetAlgorithmIdentifier(in identifier); - if (key.Length < algorithm.MLDsaAlgorithm.PublicKeySizeInBytes) + if (!algorithm.IsValidPublicKeySize(key.Length)) { - throw new CryptographicException(SR.Argument_PublicKeyTooShortForAlgorithm); + throw new CryptographicException(SR.Argument_PublicKeyWrongSizeForAlgorithm); } dsa = CompositeMLDsaImplementation.ImportCompositeMLDsaPublicKeyImpl(algorithm, key.Span); @@ -859,15 +873,27 @@ static void PrivateKeyReader( throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } - if (key.Length < algorithm.MLDsaAlgorithm.PrivateSeedSizeInBytes) + if (!algorithm.IsValidPrivateKeySize(key.Length)) { - throw new CryptographicException(SR.Argument_PrivateKeyTooShortForAlgorithm); + throw new CryptographicException(SR.Argument_PrivateKeyWrongSizeForAlgorithm); } dsa = CompositeMLDsaImplementation.ImportCompositeMLDsaPrivateKeyImpl(algorithm, key); } } + /// + /// + /// or is . + /// + public static CompositeMLDsa ImportCompositeMLDsaPublicKey(CompositeMLDsaAlgorithm algorithm, byte[] source) + { + ArgumentNullException.ThrowIfNull(algorithm); + ArgumentNullException.ThrowIfNull(source); + + return ImportCompositeMLDsaPublicKey(algorithm, new ReadOnlySpan(source)); + } + /// /// Imports a Composite ML-DSA public key. /// @@ -882,7 +908,7 @@ static void PrivateKeyReader( /// /// /// - /// length is too small for the specified algorithm. + /// length is the wrong size for the specified algorithm. /// /// -or- /// @@ -895,15 +921,29 @@ static void PrivateKeyReader( /// public static CompositeMLDsa ImportCompositeMLDsaPublicKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) { + ArgumentNullException.ThrowIfNull(algorithm); ThrowIfNotSupported(algorithm); - if (source.Length < algorithm.MLDsaAlgorithm.PublicKeySizeInBytes) + if (!algorithm.IsValidPublicKeySize(source.Length)) { - throw new CryptographicException(SR.Argument_PublicKeyTooShortForAlgorithm); + throw new CryptographicException(SR.Argument_PublicKeyWrongSizeForAlgorithm); } return CompositeMLDsaImplementation.ImportCompositeMLDsaPublicKeyImpl(algorithm, source); } + + /// + /// + /// or is . + /// + public static CompositeMLDsa ImportCompositeMLDsaPrivateKey(CompositeMLDsaAlgorithm algorithm, byte[] source) + { + ArgumentNullException.ThrowIfNull(algorithm); + ArgumentNullException.ThrowIfNull(source); + + return ImportCompositeMLDsaPrivateKey(algorithm, new ReadOnlySpan(source)); + } + /// /// Imports a Composite ML-DSA private key. /// @@ -918,7 +958,7 @@ public static CompositeMLDsa ImportCompositeMLDsaPublicKey(CompositeMLDsaAlgorit /// /// /// - /// length is too small for the specified algorithm. + /// length is the wrong size for the specified algorithm. /// /// -or- /// @@ -931,11 +971,12 @@ public static CompositeMLDsa ImportCompositeMLDsaPublicKey(CompositeMLDsaAlgorit /// public static CompositeMLDsa ImportCompositeMLDsaPrivateKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) { + ArgumentNullException.ThrowIfNull(algorithm); ThrowIfNotSupported(algorithm); - if (source.Length < algorithm.MLDsaAlgorithm.PrivateSeedSizeInBytes) + if (!algorithm.IsValidPrivateKeySize(source.Length)) { - throw new CryptographicException(SR.Argument_PrivateKeyTooShortForAlgorithm); + throw new CryptographicException(SR.Argument_PrivateKeyWrongSizeForAlgorithm); } return CompositeMLDsaImplementation.ImportCompositeMLDsaPrivateKeyImpl(algorithm, source); @@ -1344,9 +1385,9 @@ public bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritte { ThrowIfDisposed(); - // The bound can be tightened but private key length of some traditional algorithms, + // The bound can be tightened but private key length of some traditional algorithms // can vary and aren't worth the complex calculation. - int minimumPossiblePkcs8Key = Algorithm.MLDsaAlgorithm.PrivateSeedSizeInBytes; + int minimumPossiblePkcs8Key = Algorithm.MinPrivateKeySizeInBytes; if (destination.Length < minimumPossiblePkcs8Key) { @@ -1465,7 +1506,54 @@ public byte[] ExportCompositeMLDsaPublicKey() { ThrowIfDisposed(); - return ExportPublicKeyCallback(static publicKey => publicKey.ToArray()); + byte[] publicKey = new byte[Algorithm.MaxPublicKeySizeInBytes]; + + if (!TryExportCompositeMLDsaPublicKey(publicKey, out int bytesWritten)) + { + Debug.Fail("Max sized buffer was not large enough."); + throw new CryptographicException(); + } + + if (bytesWritten < publicKey.Length) + { + Array.Resize(ref publicKey, bytesWritten); + } + + return publicKey; + } + + /// + /// Exports the public-key portion of the current key into the provided buffer. + /// + /// + /// The buffer to receive the Composite ML-DSA public key value. + /// + /// + /// The number of bytes written to the buffer. + /// + /// + /// This instance has been disposed. + /// + /// + /// was too not large enough to hold the result. + /// -or- + /// An error occurred while exporting the key. + /// + public int ExportCompositeMLDsaPublicKey(Span destination) + { + ThrowIfDisposed(); + + if (destination.Length < Algorithm.MinPublicKeySizeInBytes) + { + throw new CryptographicException(SR.Argument_DestinationTooShort); + } + + if (!TryExportCompositeMLDsaPublicKey(destination, out int bytesWritten)) + { + throw new CryptographicException(SR.Argument_DestinationTooShort); + } + + return bytesWritten; } /// @@ -1492,9 +1580,36 @@ public bool TryExportCompositeMLDsaPublicKey(Span destination, out int byt { ThrowIfDisposed(); - // TODO short-circuit based on known required length lower bounds + if (destination.Length < Algorithm.MinPublicKeySizeInBytes) + { + bytesWritten = 0; + return false; + } + + using (CryptoPoolLease lease = CryptoPoolLease.RentConditionally(Algorithm.MaxPublicKeySizeInBytes, destination, skipClear: true)) + { + int localBytesWritten = ExportCompositeMLDsaPublicKeyCore(lease.Span); + + if (!Algorithm.IsValidPublicKeySize(localBytesWritten)) + { + bytesWritten = 0; + throw new CryptographicException(); + } + + if (lease.IsRented) + { + if (localBytesWritten > destination.Length) + { + bytesWritten = 0; + return false; + } + + lease.Span.Slice(0, localBytesWritten).CopyTo(destination); + } - return TryExportCompositeMLDsaPublicKeyCore(destination, out bytesWritten); + bytesWritten = localBytesWritten; + return true; + } } /// @@ -1513,13 +1628,57 @@ public byte[] ExportCompositeMLDsaPrivateKey() { ThrowIfDisposed(); - // TODO The private key has a max size so add it as CompositeMLDsaAlgorithm.MaxPrivateKeySize and use it here. - int initalSize = 1; + byte[] privateKey = new byte[Algorithm.MaxPrivateKeySizeInBytes]; + + if (!TryExportCompositeMLDsaPrivateKey(privateKey, out int bytesWritten)) + { + Debug.Fail("Max sized buffer was not large enough."); + throw new CryptographicException(); + } + + if (bytesWritten < privateKey.Length) + { + byte[] temp = new byte[bytesWritten]; + Array.Copy(privateKey, temp, bytesWritten); + CryptographicOperations.ZeroMemory(privateKey); + privateKey = temp; + } + + return privateKey; + } + + /// + /// Exports the private-key portion of the current key into the provided buffer. + /// + /// + /// The buffer to receive the Composite ML-DSA private key value. + /// + /// + /// The number of bytes written to the buffer. + /// + /// + /// This instance has been disposed. + /// + /// + /// was too not large enough to hold the result. + /// -or- + /// An error occurred while exporting the key. + /// + public int ExportCompositeMLDsaPrivateKey(Span destination) + { + ThrowIfDisposed(); + + if (destination.Length < Algorithm.MinPrivateKeySizeInBytes) + { + throw new CryptographicException(SR.Argument_DestinationTooShort); + } + + if (!TryExportCompositeMLDsaPrivateKey(destination, out int bytesWritten)) + { + throw new CryptographicException(SR.Argument_DestinationTooShort); + } - return ExportWithCallback( - initalSize, - static (key, dest, out written) => key.TryExportCompositeMLDsaPrivateKeyCore(dest, out written), - static privateKey => privateKey.ToArray()); + return bytesWritten; } /// @@ -1546,23 +1705,51 @@ public bool TryExportCompositeMLDsaPrivateKey(Span destination, out int by { ThrowIfDisposed(); - // TODO short-circuit based on known required length lower bounds + if (destination.Length < Algorithm.MinPrivateKeySizeInBytes) + { + bytesWritten = 0; + return false; + } - return TryExportCompositeMLDsaPrivateKeyCore(destination, out bytesWritten); + using (CryptoPoolLease lease = CryptoPoolLease.RentConditionally(Algorithm.MaxPrivateKeySizeInBytes, destination, skipClearIfNotRented: true)) + { + int localBytesWritten = ExportCompositeMLDsaPrivateKeyCore(lease.Span); + + if (!Algorithm.IsValidPrivateKeySize(localBytesWritten)) + { + if (!lease.IsRented) + { + CryptographicOperations.ZeroMemory(destination); + } + + bytesWritten = 0; + throw new CryptographicException(); + } + + if (lease.IsRented) + { + if (localBytesWritten > destination.Length) + { + bytesWritten = 0; + return false; + } + + lease.Span.Slice(0, localBytesWritten).CopyTo(destination); + } + + bytesWritten = localBytesWritten; + return true; + } } /// - /// When overridden in a derived class, attempts to export the public key portion of the current key. + /// When overridden in a derived class, exports the public key portion of the current key. /// /// /// The buffer to receive the public key value. /// - /// - /// When this method returns, contains the number of bytes written to the buffer. - /// /// - /// if was large enough to hold the result; - /// otherwise, . + /// The number of bytes written to the buffer. /// /// /// This instance has been disposed. @@ -1570,20 +1757,16 @@ public bool TryExportCompositeMLDsaPrivateKey(Span destination, out int by /// /// An error occurred while exporting the key. /// - protected abstract bool TryExportCompositeMLDsaPublicKeyCore(ReadOnlySpan destination, out int bytesWritten); + protected abstract int ExportCompositeMLDsaPublicKeyCore(Span destination); /// - /// When overridden in a derived class, attempts to export the private key portion of the current key. + /// When overridden in a derived class, exports the private key portion of the current key. /// /// /// The buffer to receive the private key value. /// - /// - /// When this method returns, contains the number of bytes written to the buffer. - /// /// - /// if was large enough to hold the result; - /// otherwise, . + /// The number of bytes written to the buffer. /// /// /// This instance has been disposed. @@ -1591,7 +1774,7 @@ public bool TryExportCompositeMLDsaPrivateKey(Span destination, out int by /// /// An error occurred while exporting the key. /// - protected abstract bool TryExportCompositeMLDsaPrivateKeyCore(ReadOnlySpan destination, out int bytesWritten); + protected abstract int ExportCompositeMLDsaPrivateKeyCore(Span destination); /// /// Releases all resources used by the class. @@ -1668,72 +1851,51 @@ private AsnWriter WritePkcs8ToAsnWriter() }); } - private TResult ExportPkcs8PrivateKeyCallback(ProcessExportedContent func) - { - // TODO Pick a good estimate for the initial size of the buffer. - int initialSize = 1; - - return ExportWithCallback( - initialSize, - static (key, dest, out written) => key.TryExportPkcs8PrivateKeyCore(dest, out written), - func); - } - private AsnWriter WriteSubjectPublicKeyToAsnWriter() { - return ExportPublicKeyCallback(publicKey => + byte[] buffer = new byte[Algorithm.MaxPublicKeySizeInBytes]; + int written = ExportCompositeMLDsaPublicKeyCore(buffer); + + if (!Algorithm.IsValidPublicKeySize(written)) { - // TODO verify overhead + throw new CryptographicException(); + } + + ReadOnlySpan publicKey = buffer.AsSpan(0, written); + + // TODO verify overhead - // TODO: The ASN.1 overhead of a SubjectPublicKeyInfo encoding a public key is ___ bytes. - // Round it off to 32. This checked operation should never throw because the inputs are not - // user provided. - int capacity = checked(32 + publicKey.Length); - AsnWriter writer = new AsnWriter(AsnEncodingRules.DER, capacity); + // TODO: The ASN.1 overhead of a SubjectPublicKeyInfo encoding a public key is ___ bytes. + // Round it off to 32. This checked operation should never throw because the inputs are not + // user provided. + int capacity = checked(32 + publicKey.Length); + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER, capacity); + using (writer.PushSequence()) + { using (writer.PushSequence()) { - using (writer.PushSequence()) - { - writer.WriteObjectIdentifier(Algorithm.Oid); - } - - writer.WriteBitString(publicKey); + writer.WriteObjectIdentifier(Algorithm.Oid); } - Debug.Assert(writer.GetEncodedLength() <= capacity); - return writer; - }); - } + writer.WriteBitString(publicKey); + } - private TResult ExportPublicKeyCallback(ProcessExportedContent func) - { - // TODO RSA is the only algo without a strict max size. The exponent can be arbitrarily large, - // but in practice it is always 65537. Add an internal CompositeMLDsaAlgorithm.EstimatedMaxPublicKeySizeInBytes and use that here. - int initialSize = 1; - - return ExportWithCallback( - initialSize, - static (key, dest, out written) => key.TryExportCompositeMLDsaPublicKeyCore(dest, out written), - func); + Debug.Assert(writer.GetEncodedLength() <= capacity); + return writer; } - private delegate bool TryExportFunc(CompositeMLDsa compositeMLDsa, Span destination, out int written); private delegate TResult ProcessExportedContent(ReadOnlySpan exportedContent); - private TResult ExportWithCallback( - int initialSize, - TryExportFunc tryExportFunc, - ProcessExportedContent callbackFunc) + private TResult ExportPkcs8PrivateKeyCallback(ProcessExportedContent func) { - Debug.Assert(initialSize > 0); - - int size = initialSize; + int size = Algorithm.MaxPrivateKeySizeInBytes; byte[] buffer = CryptoPool.Rent(size); int written; - while (!tryExportFunc(this, buffer, out written)) + while (!TryExportPkcs8PrivateKeyCore(buffer, out written)) { + size = buffer.Length; CryptoPool.Return(buffer); size = checked(size * 2); buffer = CryptoPool.Rent(size); @@ -1748,7 +1910,7 @@ private TResult ExportWithCallback( try { - return callbackFunc(buffer.AsSpan(0, written)); + return func(buffer.AsSpan(0, written)); } finally { @@ -1771,7 +1933,7 @@ private static CompositeMLDsaAlgorithm GetAlgorithmIdentifier(ref readonly Algor return algorithm; } - internal static void ThrowIfNotSupported() + private static void ThrowIfNotSupported() { if (!IsSupported) { @@ -1779,7 +1941,7 @@ internal static void ThrowIfNotSupported() } } - internal static void ThrowIfNotSupported(CompositeMLDsaAlgorithm algorithm) + private static void ThrowIfNotSupported(CompositeMLDsaAlgorithm algorithm) { if (!IsSupported || !IsAlgorithmSupported(algorithm)) { diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaAlgorithm.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaAlgorithm.cs index 60caef2db61fcb..bd5d12f6d6cbdd 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaAlgorithm.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaAlgorithm.cs @@ -1,10 +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; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Security.Cryptography; -using Internal.Cryptography; namespace System.Security.Cryptography { @@ -14,6 +12,8 @@ namespace System.Security.Cryptography [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public sealed class CompositeMLDsaAlgorithm : IEquatable { + internal const int RandomizerSizeInBytes = 32; + /// /// Gets the name of the algorithm. /// @@ -30,22 +30,42 @@ public sealed class CompositeMLDsaAlgorithm : IEquatable public int MaxSignatureSizeInBytes { get; } - internal MLDsaAlgorithm MLDsaAlgorithm { get; } + internal int MinPrivateKeySizeInBytes { get; } + internal int MaxPrivateKeySizeInBytes { get; } + internal int MinPublicKeySizeInBytes { get; } + internal int MaxPublicKeySizeInBytes { get; } + internal int MinSignatureSizeInBytes { get; } internal string Oid { get; } private CompositeMLDsaAlgorithm( string name, - MLDsaAlgorithm mlDsaAlgorithm, - int maxTraditionalSignatureSize, + int minPrivateKeySizeInBytes, + int maxPrivateKeySizeInBytes, + int minPublicKeySizeInBytes, + int maxPublicKeySizeInBytes, + int minSignatureSize, + int maxSignatureSize, string oid) { + Debug.Assert(minPrivateKeySizeInBytes <= maxPrivateKeySizeInBytes); + Debug.Assert(minPublicKeySizeInBytes <= maxPublicKeySizeInBytes); + Debug.Assert(minSignatureSize <= maxSignatureSize); + Name = name; - MLDsaAlgorithm = mlDsaAlgorithm; - MaxSignatureSizeInBytes = MLDsaAlgorithm.SignatureSizeInBytes + maxTraditionalSignatureSize; + MinPrivateKeySizeInBytes = minPrivateKeySizeInBytes; + MaxPrivateKeySizeInBytes = maxPrivateKeySizeInBytes; + MinPublicKeySizeInBytes = minPublicKeySizeInBytes; + MaxPublicKeySizeInBytes = maxPublicKeySizeInBytes; + MinSignatureSizeInBytes = minSignatureSize; + MaxSignatureSizeInBytes = maxSignatureSize; Oid = oid; } + internal bool IsValidPrivateKeySize(int size) => MinPrivateKeySizeInBytes <= size && size <= MaxPrivateKeySizeInBytes; + internal bool IsValidPublicKeySize(int size) => MinPublicKeySizeInBytes <= size && size <= MaxPublicKeySizeInBytes; + internal bool IsValidSignatureSize(int size) => MinSignatureSizeInBytes <= size && size <= MaxSignatureSizeInBytes; + /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-44 and 2048-bit RSASSA-PSS with SHA256 algorithm. /// @@ -53,7 +73,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-44 and 2048-bit RSASSA-PSS with SHA256 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa44WithRSA2048Pss { get; } = - new("MLDSA44-RSA2048-PSS-SHA256", MLDsaAlgorithm.MLDsa44, 2048 / 8, Oids.MLDsa44WithRSA2048PssPreHashSha256); + CreateRsa( + "MLDSA44-RSA2048-PSS-SHA256", + MLDsaAlgorithm.MLDsa44, + 2048, + Oids.MLDsa44WithRSA2048PssPreHashSha256); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-44 and 2048-bit RSASSA-PKCS1-v1_5 with SHA256 algorithm. @@ -62,7 +86,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-44 and 2048-bit RSASSA-PKCS1-v1_5 with SHA256 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa44WithRSA2048Pkcs15 { get; } = - new("MLDSA44-RSA2048-PKCS15-SHA256", MLDsaAlgorithm.MLDsa44, 2048 / 8, Oids.MLDsa44WithRSA2048Pkcs15PreHashSha256); + CreateRsa( + "MLDSA44-RSA2048-PKCS15-SHA256", + MLDsaAlgorithm.MLDsa44, + 2048, + Oids.MLDsa44WithRSA2048Pkcs15PreHashSha256); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-44 and Ed25519 algorithm. @@ -71,7 +99,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-44 and Ed25519 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa44WithEd25519 { get; } = - new("MLDSA44-Ed25519-SHA512", MLDsaAlgorithm.MLDsa44, 64, Oids.MLDsa44WithEd25519PreHashSha512); + CreateEdDsa( + "MLDSA44-Ed25519-SHA512", + MLDsaAlgorithm.MLDsa44, + 32 * 8, + Oids.MLDsa44WithEd25519PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-44 and ECDSA P-256 with SHA256 algorithm. @@ -80,7 +112,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-44 and ECDSA P-256 with SHA256 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa44WithECDsaP256 { get; } = - new("MLDSA44-ECDSA-P256-SHA256", MLDsaAlgorithm.MLDsa44, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(256), Oids.MLDsa44WithECDsaP256PreHashSha256); + CreateECDsa( + "MLDSA44-ECDSA-P256-SHA256", + MLDsaAlgorithm.MLDsa44, + 256, + Oids.MLDsa44WithECDsaP256PreHashSha256); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and 3072-bit RSASSA-PSS with SHA512 algorithm. @@ -89,7 +125,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and 3072-bit RSASSA-PSS with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithRSA3072Pss { get; } = - new("MLDSA65-RSA3072-PSS-SHA512", MLDsaAlgorithm.MLDsa65, 3072 / 8, Oids.MLDsa65WithRSA3072PssPreHashSha512); + CreateRsa( + "MLDSA65-RSA3072-PSS-SHA512", + MLDsaAlgorithm.MLDsa65, + 3072, + Oids.MLDsa65WithRSA3072PssPreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and 3072-bit RSASSA-PKCS1-v1_5 with SHA512 algorithm. @@ -98,7 +138,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and 3072-bit RSASSA-PKCS1-v1_5 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithRSA3072Pkcs15 { get; } = - new("MLDSA65-RSA3072-PKCS15-SHA512", MLDsaAlgorithm.MLDsa65, 3072 / 8, Oids.MLDsa65WithRSA3072Pkcs15PreHashSha512); + CreateRsa( + "MLDSA65-RSA3072-PKCS15-SHA512", + MLDsaAlgorithm.MLDsa65, + 3072, + Oids.MLDsa65WithRSA3072Pkcs15PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and 4096-bit RSASSA-PSS with SHA512 algorithm. @@ -107,7 +151,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and 4096-bit RSASSA-PSS with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithRSA4096Pss { get; } = - new("MLDSA65-RSA4096-PSS-SHA512", MLDsaAlgorithm.MLDsa65, 4096 / 8, Oids.MLDsa65WithRSA4096PssPreHashSha512); + CreateRsa( + "MLDSA65-RSA4096-PSS-SHA512", + MLDsaAlgorithm.MLDsa65, + 4096, + Oids.MLDsa65WithRSA4096PssPreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and 4096-bit RSASSA-PKCS1-v1_5 with SHA512 algorithm. @@ -116,7 +164,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and 4096-bit RSASSA-PKCS1-v1_5 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithRSA4096Pkcs15 { get; } = - new("MLDSA65-RSA4096-PKCS15-SHA512", MLDsaAlgorithm.MLDsa65, 4096 / 8, Oids.MLDsa65WithRSA4096Pkcs15PreHashSha512); + CreateRsa( + "MLDSA65-RSA4096-PKCS15-SHA512", + MLDsaAlgorithm.MLDsa65, + 4096, + Oids.MLDsa65WithRSA4096Pkcs15PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and ECDSA P-256 with SHA512 algorithm. @@ -125,7 +177,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and ECDSA P-256 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithECDsaP256 { get; } = - new("MLDSA65-ECDSA-P256-SHA512", MLDsaAlgorithm.MLDsa65, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(256), Oids.MLDsa65WithECDsaP256PreHashSha512); + CreateECDsa( + "MLDSA65-ECDSA-P256-SHA512", + MLDsaAlgorithm.MLDsa65, + 256, + Oids.MLDsa65WithECDsaP256PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and ECDSA P-384 with SHA512 algorithm. @@ -134,7 +190,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and ECDSA P-384 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithECDsaP384 { get; } = - new("MLDSA65-ECDSA-P384-SHA512", MLDsaAlgorithm.MLDsa65, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(384), Oids.MLDsa65WithECDsaP384PreHashSha512); + CreateECDsa( + "MLDSA65-ECDSA-P384-SHA512", + MLDsaAlgorithm.MLDsa65, + 384, + Oids.MLDsa65WithECDsaP384PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and ECDSA BrainpoolP256r1 with SHA512 algorithm. @@ -143,7 +203,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and ECDSA BrainpoolP256r1 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithECDsaBrainpoolP256r1 { get; } = - new("MLDSA65-ECDSA-brainpoolP256r1-SHA512", MLDsaAlgorithm.MLDsa65, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(256), Oids.MLDsa65WithECDsaBrainpoolP256r1PreHashSha512); + CreateECDsa( + "MLDSA65-ECDSA-brainpoolP256r1-SHA512", + MLDsaAlgorithm.MLDsa65, + 256, + Oids.MLDsa65WithECDsaBrainpoolP256r1PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-65 and Ed25519 algorithm. @@ -152,7 +216,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-65 and Ed25519 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa65WithEd25519 { get; } = - new("MLDSA65-Ed25519-SHA512", MLDsaAlgorithm.MLDsa65, 64, Oids.MLDsa65WithEd25519PreHashSha512); + CreateEdDsa( + "MLDSA65-Ed25519-SHA512", + MLDsaAlgorithm.MLDsa65, + 32 * 8, + Oids.MLDsa65WithEd25519PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-87 and ECDSA P-384 with SHA512 algorithm. @@ -161,7 +229,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-87 and ECDSA P-384 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa87WithECDsaP384 { get; } = - new("MLDSA87-ECDSA-P384-SHA512", MLDsaAlgorithm.MLDsa87, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(384), Oids.MLDsa87WithECDsaP384PreHashSha512); + CreateECDsa( + "MLDSA87-ECDSA-P384-SHA512", + MLDsaAlgorithm.MLDsa87, + 384, + Oids.MLDsa87WithECDsaP384PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-87 and ECDSA BrainpoolP384r1 with SHA512 algorithm. @@ -170,7 +242,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-87 and ECDSA BrainpoolP384r1 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa87WithECDsaBrainpoolP384r1 { get; } = - new("MLDSA87-ECDSA-brainpoolP384r1-SHA512", MLDsaAlgorithm.MLDsa87, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(384), Oids.MLDsa87WithECDsaBrainpoolP384r1PreHashSha512); + CreateECDsa( + "MLDSA87-ECDSA-brainpoolP384r1-SHA512", + MLDsaAlgorithm.MLDsa87, + 384, + Oids.MLDsa87WithECDsaBrainpoolP384r1PreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-87 and Ed448 algorithm. @@ -179,7 +255,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-87 and Ed448 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa87WithEd448 { get; } = - new("MLDSA87-Ed448-SHAKE256", MLDsaAlgorithm.MLDsa87, 114, Oids.MLDsa87WithEd448PreHashShake256_512); + CreateEdDsa( + "MLDSA87-Ed448-SHAKE256", + MLDsaAlgorithm.MLDsa87, + 57 * 8, + Oids.MLDsa87WithEd448PreHashShake256_512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-87 and 3072-bit RSASSA-PSS with SHA512 algorithm. @@ -188,7 +268,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-87 and 3072-bit RSASSA-PSS with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa87WithRSA3072Pss { get; } = - new("MLDSA87-RSA3072-PSS-SHA512", MLDsaAlgorithm.MLDsa87, 3072 / 8, Oids.MLDsa87WithRSA3072PssPreHashSha512); + CreateRsa( + "MLDSA87-RSA3072-PSS-SHA512", + MLDsaAlgorithm.MLDsa87, + 3072, + Oids.MLDsa87WithRSA3072PssPreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-87 and 4096-bit RSASSA-PSS with SHA512 algorithm. @@ -197,7 +281,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-87 and 4096-bit RSASSA-PSS with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa87WithRSA4096Pss { get; } = - new("MLDSA87-RSA4096-PSS-SHA512", MLDsaAlgorithm.MLDsa87, 4096 / 8, Oids.MLDsa87WithRSA4096PssPreHashSha512); + CreateRsa( + "MLDSA87-RSA4096-PSS-SHA512", + MLDsaAlgorithm.MLDsa87, + 4096, + Oids.MLDsa87WithRSA4096PssPreHashSha512); /// /// Gets a Composite ML-DSA algorithm identifier for the ML-DSA-87 and ECDSA P-521 with SHA512 algorithm. @@ -206,7 +294,11 @@ private CompositeMLDsaAlgorithm( /// An ML-DSA algorithm identifier for the ML-DSA-87 and ECDSA P-521 with SHA512 algorithm. /// public static CompositeMLDsaAlgorithm MLDsa87WithECDsaP521 { get; } = - new("MLDSA87-ECDSA-P521-SHA512", MLDsaAlgorithm.MLDsa87, AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(521), Oids.MLDsa87WithECDsaP521PreHashSha512); + CreateECDsa( + "MLDSA87-ECDSA-P521-SHA512", + MLDsaAlgorithm.MLDsa87, + 521, + Oids.MLDsa87WithECDsaP521PreHashSha512); /// /// Compares two objects. @@ -289,5 +381,187 @@ private CompositeMLDsaAlgorithm( _ => null, }; } + + private static CompositeMLDsaAlgorithm CreateRsa( + string name, + MLDsaAlgorithm mldsaAlgorithm, + int keySizeInBits, + string oid) + { + Debug.Assert(keySizeInBits % 8 == 0); + int keySizeInBytes = keySizeInBits / 8; + + const int MaxUniversalTagLength = 1; + + // long form prefix and 4 bytes for length. CLR arrays and spans only support length up to int.MaxValue. + // Padding with leading zero bytes is allowed, but we still limit the length to 4 bytes since the only + // plausible scenario would be encoding a 4-byte numeric data type without trimming. + // Note this bound also covers indefinite length encodings which require only 1 + 2 bytes of overhead. + const int MaxLengthLength = 1 + 4; + + const int MaxPrefixLength = MaxUniversalTagLength + MaxLengthLength; + + const int PossibleLeadingZeroByte = 1; // ASN.1 INTEGER can have a leading zero byte. + int maxKeyEncodingLength = keySizeInBytes + PossibleLeadingZeroByte; + int maxHalfKeyEncodingLength = (keySizeInBytes + 1) / 2 + PossibleLeadingZeroByte; + int maxExponentEncodingLength = 256 / 8 + PossibleLeadingZeroByte; // FIPS 186-5, 5.4 (e): The exponent e shall be an odd, positive integer such that 2^16 < e < 2^256 + + // RFC 8017, A.1.1 + // RSAPublicKey::= SEQUENCE { + // modulus INTEGER, --n + // publicExponent INTEGER --e + // } + + int maxRsaPublicKeySizeInBytes = + MaxPrefixLength + + ( + MaxPrefixLength + maxKeyEncodingLength + + MaxPrefixLength + maxExponentEncodingLength + ); + + // RFC 8017, A.1.2 + // RSAPrivateKey::= SEQUENCE { + // version Version, + // modulus INTEGER, --n + // publicExponent INTEGER, --e + // privateExponent INTEGER, --d + // prime1 INTEGER, --p + // prime2 INTEGER, --q + // exponent1 INTEGER, --d mod(p - 1) + // exponent2 INTEGER, --d mod(q - 1) + // coefficient INTEGER, --(inverse of q) mod p + // otherPrimeInfos OtherPrimeInfos OPTIONAL + // } + + int maxRsaPrivateKeySizeInBytes = + MaxPrefixLength + + ( + MaxPrefixLength + 1 + // Version should always be 0 or 1 + MaxPrefixLength + maxKeyEncodingLength + + MaxPrefixLength + maxExponentEncodingLength + + MaxPrefixLength + maxKeyEncodingLength + + MaxPrefixLength + maxHalfKeyEncodingLength + + MaxPrefixLength + maxHalfKeyEncodingLength + + MaxPrefixLength + maxHalfKeyEncodingLength + + MaxPrefixLength + maxHalfKeyEncodingLength + + MaxPrefixLength + maxHalfKeyEncodingLength + // OtherPrimeInfos omitted since multi-prime is not supported + ); + + return new CompositeMLDsaAlgorithm( + name, + mldsaAlgorithm.PrivateSeedSizeInBytes + keySizeInBytes, // Private key contains at least n + mldsaAlgorithm.PrivateSeedSizeInBytes + maxRsaPrivateKeySizeInBytes, + mldsaAlgorithm.PublicKeySizeInBytes + keySizeInBytes, // Private key contains at least n + mldsaAlgorithm.PublicKeySizeInBytes + maxRsaPublicKeySizeInBytes, + RandomizerSizeInBytes + mldsaAlgorithm.SignatureSizeInBytes + keySizeInBytes, + RandomizerSizeInBytes + mldsaAlgorithm.SignatureSizeInBytes + keySizeInBytes, + oid); + } + + private static CompositeMLDsaAlgorithm CreateECDsa( + string name, + MLDsaAlgorithm mldsaAlgorithm, + int keySizeInBits, + string oid) + { + // The key size calculation depends on the size of the curve algorithm's OID, and only includes the curves + // supported at the time of writing this code. If more curves are added, ensure the OID length is accounted for in the calculation. + Debug.Assert(oid is + Oids.MLDsa44WithECDsaP256PreHashSha256 or + Oids.MLDsa65WithECDsaP256PreHashSha512 or + Oids.MLDsa65WithECDsaP384PreHashSha512 or + Oids.MLDsa87WithECDsaP384PreHashSha512 or + Oids.MLDsa87WithECDsaP521PreHashSha512 or + Oids.MLDsa65WithECDsaBrainpoolP256r1PreHashSha512 or + Oids.MLDsa87WithECDsaBrainpoolP384r1PreHashSha512); + + int keySizeInBytes = (keySizeInBits + 7) / 8; + + const int MaxUniversalTagLength = 1; + + // long form prefix and 4 bytes for length. CLR arrays and spans only support length up to int.MaxValue. + // Padding with leading zero bytes is allowed, but we still limit the length to 4 bytes since the only + // plausible scenario would be encoding a 4-byte numeric data type without trimming. + // Note this bound also covers indefinite length encodings which require only 1 + 2 bytes of overhead. + const int MaxLengthLength = 1 + 4; + + const int MaxPrefixLength = MaxUniversalTagLength + MaxLengthLength; + + // RFC 5915, Section 3 + // ECPrivateKey ::= SEQUENCE { + // version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + // privateKey OCTET STRING, + // parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + // publicKey [1] BIT STRING OPTIONAL + // } + + int maxPrivateKeySizeInBytes = + MaxPrefixLength + + ( + // version + MaxPrefixLength + 1 + // Version should always be 1 + + // privateKey + MaxPrefixLength + keySizeInBytes + + + // parameters + 1 + MaxLengthLength + // Explicit tag + ( + // RFC5480, Section 2.1.1 + // ECParameters ::= CHOICE { + // namedCurve OBJECT IDENTIFIER + // -- implicitCurve NULL + // -- specifiedCurve SpecifiedECDomain + // } + // -- implicitCurve and specifiedCurve MUST NOT be used in PKIX. + // + // So this is a CHOICE with with the only option being a namedCurve OBJECT IDENTIFIER. + // + // Curve | OID | DER Encoding with prefix | Length without prefix + // ----------------|-----------------------|----------------------------------|---------------------- + // secp256r1 | 1.2.840.10045.3.1.7 | 06 08 2A 86 48 CE 3D 03 01 07 | 8 + // secp384r1 | 1.3.132.0.34 | 06 05 2B 81 04 00 22 | 5 + // secp521r1 | 1.3.132.0.35 | 06 05 2B 81 04 00 23 | 5 + // brainpoolP256r1 | 1.3.36.3.3.2.8.1.1.7 | 06 09 2B 24 03 03 02 08 01 01 07 | 9 + // brainpoolP384r1 | 1.3.36.3.3.2.8.1.1.11 | 06 09 2B 24 03 03 02 08 01 01 0B | 9 + MaxPrefixLength + 9 // This doesn't need to be exact, but it does need to consider all supported curves. + ) + + + // publicKey + 1 + MaxLengthLength + // Explicit tag + 1 + 2 * keySizeInBytes + ); + + return new CompositeMLDsaAlgorithm( + name, + mldsaAlgorithm.PrivateSeedSizeInBytes + keySizeInBytes, // ECPrivateKey has at least the private key + mldsaAlgorithm.PrivateSeedSizeInBytes + maxPrivateKeySizeInBytes, + mldsaAlgorithm.PublicKeySizeInBytes + 1 + 2 * keySizeInBytes, + mldsaAlgorithm.PublicKeySizeInBytes + 1 + 2 * keySizeInBytes, + RandomizerSizeInBytes + mldsaAlgorithm.SignatureSizeInBytes + 2 + 3 * 2, // 2 non-zero INTEGERS and overhead for 3 ASN.1 values + RandomizerSizeInBytes + mldsaAlgorithm.SignatureSizeInBytes + AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(keySizeInBits), + oid); + } + + private static CompositeMLDsaAlgorithm CreateEdDsa( + string name, + MLDsaAlgorithm mldsaAlgorithm, + int keySizeInBits, + string oid) + { + Debug.Assert(keySizeInBits % 8 == 0); + int keySizeInBytes = keySizeInBits / 8; + + return new CompositeMLDsaAlgorithm( + name, + mldsaAlgorithm.PrivateSeedSizeInBytes + keySizeInBytes, + mldsaAlgorithm.PrivateSeedSizeInBytes + keySizeInBytes, + mldsaAlgorithm.PublicKeySizeInBytes + keySizeInBytes, + mldsaAlgorithm.PublicKeySizeInBytes + keySizeInBytes, + RandomizerSizeInBytes + mldsaAlgorithm.SignatureSizeInBytes + 2 * keySizeInBytes, + RandomizerSizeInBytes + mldsaAlgorithm.SignatureSizeInBytes + 2 * keySizeInBytes, + oid); + } } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaCng.Windows.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaCng.Windows.cs new file mode 100644 index 00000000000000..4b1165677d5c63 --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaCng.Windows.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + public sealed partial class CompositeMLDsaCng : CompositeMLDsa + { + public partial CngKey GetKey() => + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(CompositeMLDsa))); + + /// + protected override int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) => + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(CompositeMLDsa))); + + /// + protected override int ExportCompositeMLDsaPrivateKeyCore(Span destination) => + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(CompositeMLDsa))); + + /// + protected override int ExportCompositeMLDsaPublicKeyCore(Span destination) => + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(CompositeMLDsa))); + + /// + protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) => + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(CompositeMLDsa))); + + /// + protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(CompositeMLDsa))); + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaCng.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaCng.cs new file mode 100644 index 00000000000000..246109e6c8b2d6 --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaCng.cs @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.Versioning; + +namespace System.Security.Cryptography +{ + /// + /// Provides a Cryptography Next Generation (CNG) implementation of Composite ML-DSA. + /// + /// + /// + /// Developers are encouraged to program against the base class, + /// rather than any specific derived class. + /// The derived classes are intended for interop with the underlying system + /// cryptographic libraries. + /// + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public sealed partial class CompositeMLDsaCng : CompositeMLDsa + { + /// + /// Initializes a new instance of the class by using the specified . + /// + /// + /// The key that will be used as input to the cryptographic operations performed by the current object. + /// + /// + /// is . + /// + /// + /// does not specify a Composite ML-DSA group. + /// + /// + /// Cryptography Next Generation (CNG) classes are not supported on this system. + /// + [SupportedOSPlatform("windows")] + public CompositeMLDsaCng(CngKey key) + : base(AlgorithmFromHandle(key)) + { + throw new PlatformNotSupportedException(); + } + + private static CompositeMLDsaAlgorithm AlgorithmFromHandle(CngKey key) => + throw new PlatformNotSupportedException(); + + /// + /// Gets a new representing the key used by the current instance. + /// + /// + /// This instance has been disposed. + /// + /// + /// This object is not the same as the one passed to , + /// if that constructor was used. However, it will point to the same CNG key. + /// + public partial CngKey GetKey(); + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.NotSupported.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.NotSupported.cs index 7cc6ae81d277d0..0c4b3461d90bc6 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.NotSupported.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.NotSupported.cs @@ -15,20 +15,20 @@ public CompositeMLDsaImplementation(CompositeMLDsaAlgorithm algorithm) throw new PlatformNotSupportedException(); } - internal static bool SupportsAny() => false; + internal static partial bool SupportsAny() => false; - internal static bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm algorithm) => false; + internal static partial bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm algorithm) => false; - internal static CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) => + internal static partial CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) => throw new PlatformNotSupportedException(); - internal static CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => + internal static partial CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => throw new PlatformNotSupportedException(); - internal static CompositeMLDsa ImportCompositeMLDsaPrivateKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => + internal static partial CompositeMLDsa ImportCompositeMLDsaPrivateKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => throw new PlatformNotSupportedException(); - protected override bool TrySignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination, out int bytesWritten) => + protected override int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) => throw new PlatformNotSupportedException(); protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => @@ -37,10 +37,10 @@ protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan destination, out int bytesWritten) => throw new PlatformNotSupportedException(); - protected override bool TryExportCompositeMLDsaPublicKeyCore(ReadOnlySpan destination, out int bytesWritten) => + protected override int ExportCompositeMLDsaPublicKeyCore(Span destination) => throw new PlatformNotSupportedException(); - protected override bool TryExportCompositeMLDsaPrivateKeyCore(ReadOnlySpan destination, out int bytesWritten) => + protected override int ExportCompositeMLDsaPrivateKeyCore(Span destination) => throw new PlatformNotSupportedException(); } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.Windows.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.Windows.cs new file mode 100644 index 00000000000000..dc0fa563d9f7be --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.Windows.cs @@ -0,0 +1,81 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Internal.Cryptography; + +namespace System.Security.Cryptography +{ + internal sealed partial class CompositeMLDsaImplementation : CompositeMLDsa + { + private CompositeMLDsaImplementation(CompositeMLDsaAlgorithm algorithm) + : base(algorithm) + { + throw new PlatformNotSupportedException(); + } + + internal static partial bool SupportsAny() + { + if (!Helpers.IsOSPlatformWindows) + { + return false; + } + + return CompositeMLDsaManaged.SupportsAny(); + } + + internal static partial bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm algorithm) + { + if (!Helpers.IsOSPlatformWindows) + { + return false; + } + + return CompositeMLDsaManaged.IsAlgorithmSupportedImpl(algorithm); + } + + internal static partial CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) + { + if (!Helpers.IsOSPlatformWindows) + { + throw new PlatformNotSupportedException(); + } + + return CompositeMLDsaManaged.GenerateKeyImpl(algorithm); + } + + internal static partial CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) + { + if (!Helpers.IsOSPlatformWindows) + { + throw new PlatformNotSupportedException(); + } + + return CompositeMLDsaManaged.ImportCompositeMLDsaPublicKeyImpl(algorithm, source); + } + + internal static partial CompositeMLDsa ImportCompositeMLDsaPrivateKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) + { + if (!Helpers.IsOSPlatformWindows) + { + throw new PlatformNotSupportedException(); + } + + return CompositeMLDsaManaged.ImportCompositeMLDsaPrivateKeyImpl(algorithm, source); + } + + protected override int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) => + throw new PlatformNotSupportedException(); + + protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + throw new PlatformNotSupportedException(); + + protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) => + throw new PlatformNotSupportedException(); + + protected override int ExportCompositeMLDsaPublicKeyCore(Span destination) => + throw new PlatformNotSupportedException(); + + protected override int ExportCompositeMLDsaPrivateKeyCore(Span destination) => + throw new PlatformNotSupportedException(); + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.cs new file mode 100644 index 00000000000000..c565db17ef39dd --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaImplementation.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + internal sealed partial class CompositeMLDsaImplementation : CompositeMLDsa + { + internal static partial bool SupportsAny(); + + internal static partial bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm algorithm); + + internal static partial CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm); + + internal static partial CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source); + + internal static partial CompositeMLDsa ImportCompositeMLDsaPrivateKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source); + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.ECDsa.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.ECDsa.cs new file mode 100644 index 00000000000000..55e2448d538f62 --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.ECDsa.cs @@ -0,0 +1,496 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers; +using System.Diagnostics; +using System.Formats.Asn1; +using System.Runtime.InteropServices; +using System.Security.Cryptography.Asn1; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; + +#if NETFRAMEWORK +using KeyBlobMagicNumber = Interop.BCrypt.KeyBlobMagicNumber; +#endif + +namespace System.Security.Cryptography +{ + internal sealed partial class CompositeMLDsaManaged + { + private sealed class ECDsaComponent : ComponentAlgorithm +#if DESIGNTIMEINTERFACES +#pragma warning disable SA1001 // Commas should be spaced correctly + , IComponentAlgorithmFactory +#pragma warning restore SA1001 // Commas should be spaced correctly +#endif + { + private readonly ECDsaAlgorithm _algorithm; + +#if NET || NETSTANDARD + private ECDsa _ecdsa; +#else + private ECDsaCng _ecdsa; +#endif + + private ECDsaComponent( +#if NET || NETSTANDARD + ECDsa ecdsa, +#else + ECDsaCng ecdsa, +#endif + ECDsaAlgorithm algorithm) + { + Debug.Assert(ecdsa != null); + + _ecdsa = ecdsa; + _algorithm = algorithm; + } + + // While some of our OSes support the brainpool curves, not all do. + // Limit this implementation to the NIST curves until we have a better understanding + // of where native implementations of composite are aligning. + public static bool IsAlgorithmSupported(ECDsaAlgorithm algorithm) => + algorithm.CurveOidValue is Oids.secp256r1 or Oids.secp384r1 or Oids.secp521r1; + + public static ECDsaComponent GenerateKey(ECDsaAlgorithm algorithm) + { +#if NET || NETSTANDARD + return new ECDsaComponent(ECDsa.Create(algorithm.Curve), algorithm); +#else + return new ECDsaComponent(CreateKey(algorithm.CurveOid.FriendlyName), algorithm); +#endif + } + + public static unsafe ECDsaComponent ImportPrivateKey(ECDsaAlgorithm algorithm, ReadOnlySpan source) + { + Helpers.ThrowIfAsnInvalidLength(source); + + fixed (byte* ptr = &MemoryMarshal.GetReference(source)) + { + using (MemoryManager manager = new PointerMemoryManager(ptr, source.Length)) + { + ECPrivateKey ecPrivateKey = ECPrivateKey.Decode(manager.Memory, AsnEncodingRules.BER); + + if (ecPrivateKey.Version != 1) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + // If domain parameters are present, validate that they match the composite ML-DSA algorithm. + if (ecPrivateKey.Parameters is ECDomainParameters domainParameters) + { + if (domainParameters.Named is not string curveOid || curveOid != algorithm.CurveOidValue) + { + // The curve specified must be named and match the required curve for the composite ML-DSA algorithm. + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + } + + byte[]? x = null; + byte[]? y = null; + + // If public key is present, add it to the parameters. + if (ecPrivateKey.PublicKey is ReadOnlyMemory publicKey) + { + EccKeyFormatHelper.GetECPointFromUncompressedPublicKey(publicKey.Span, algorithm.KeySizeInBytes, out x, out y); + } + + byte[] d = new byte[ecPrivateKey.PrivateKey.Length]; + + using (PinAndClear.Track(d)) + { + ecPrivateKey.PrivateKey.CopyTo(d); + +#if NET || NETSTANDARD + ECParameters parameters = new ECParameters + { + Curve = algorithm.Curve, + Q = new ECPoint + { + X = x, + Y = y, + }, + D = d + }; + + parameters.Validate(); + + return new ECDsaComponent(ECDsa.Create(parameters), algorithm); +#else // NETFRAMEWORK +#if NET472_OR_GREATER +#error ECDsa.Create(ECParameters) is avaliable in .NET Framework 4.7.2 and later, so this workaround is not needed anymore. +#endif + Debug.Assert(!string.IsNullOrEmpty(algorithm.CurveOid.FriendlyName)); + Debug.Assert(x is null == y is null); + + if (x is null) + { + byte[] zero = new byte[d.Length]; + x = zero; + y = zero; + } + + if (!TryValidateNamedCurve(x, y, d)) + { + throw new CryptographicException(SR.Cryptography_InvalidECPrivateKeyParameters); + } + + return new ECDsaComponent( + ECCng.EncodeEccKeyBlob( + algorithm.PrivateKeyBlobMagicNumber, + x, + y, + d, + blob => ImportKeyBlob(blob, algorithm.CurveOid.FriendlyName, includePrivateParameters: true)), + algorithm); +#endif + } + } + } + } + + public static unsafe ECDsaComponent ImportPublicKey(ECDsaAlgorithm algorithm, ReadOnlySpan source) + { + int fieldWidth = algorithm.KeySizeInBytes; + + if (source.Length != 1 + fieldWidth * 2) + { + Debug.Fail("Public key format is fixed size, so caller needs to provide exactly correct sized buffer."); + throw new CryptographicException(); + } + + // Implementation limitation. + // 04 (Uncompressed ECPoint) is almost always used. + if (source[0] != 0x04) + { + throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); + } + + byte[] x = source.Slice(1, fieldWidth).ToArray(); + byte[] y = source.Slice(1 + fieldWidth).ToArray(); + +#if NET || NETSTANDARD + ECParameters parameters = new ECParameters() + { + Curve = algorithm.Curve, + Q = new ECPoint() + { + X = x, + Y = y, + } + }; + + return new ECDsaComponent(ECDsa.Create(parameters), algorithm); +#else // NETFRAMEWORK +#if NET472_OR_GREATER +#error ECDsa.Create(ECParameters) is available in .NET Framework 4.7.2 and later, so this workaround is not needed anymore. +#endif + Debug.Assert(!string.IsNullOrEmpty(algorithm.CurveOid.FriendlyName)); + + return new ECDsaComponent( + ECCng.EncodeEccKeyBlob( + algorithm.PublicKeyBlobMagicNumber, + x, + y, + d: null, + blob => ImportKeyBlob(blob, algorithm.CurveOid.FriendlyName, includePrivateParameters: false)), + algorithm); +#endif + } + + internal override bool TryExportPrivateKey(Span destination, out int bytesWritten) + { +#if NET || NETSTANDARD + ECParameters ecParameters = _ecdsa.ExportParameters(includePrivateParameters: true); + + Debug.Assert(ecParameters.D != null); + + using (PinAndClear.Track(ecParameters.D)) + { + ecParameters.Validate(); + + if (ecParameters.D.Length != _algorithm.KeySizeInBytes) + { + Debug.Fail("Unexpected key size."); + throw new CryptographicException(); + } + + // The curve OID must match the composite ML-DSA algorithm. + if (!ecParameters.Curve.IsNamed || + (ecParameters.Curve.Oid.Value != _algorithm.CurveOidValue && ecParameters.Curve.Oid.FriendlyName != _algorithm.CurveOid.FriendlyName)) + { + Debug.Fail("Unexpected curve OID."); + throw new CryptographicException(); + } + + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + + try + { + WriteKey(ecParameters.D, ecParameters.Q.X, ecParameters.Q.Y, _algorithm.CurveOidValue, writer); + return writer.TryEncode(destination, out bytesWritten); + } + finally + { + writer.Reset(); + } + } +#else + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + + try + { + _ecdsa.Key.ExportKeyBlob( + CngKeyBlobFormat.EccPrivateBlob.Format, + blob => + { + ECCng.DecodeEccKeyBlob( + blob, + (magic, x, y, d) => + { + if (magic != _algorithm.PrivateKeyBlobMagicNumber) + { + Debug.Fail("Unexpected magic number."); + throw new CryptographicException(); + } + + if (!TryValidateNamedCurve(x, y, d)) + { + Debug.Fail("Invalid EC parameters."); + throw new CryptographicException(); + } + + WriteKey(d, x, y, _algorithm.CurveOidValue, writer); + return true; + }); + }); + + return writer.TryEncode(destination, out bytesWritten); + } + finally + { + writer.Reset(); + } +#endif + + static void WriteKey(byte[] d, byte[]? x, byte[]? y, string curveOid, AsnWriter writer) + { + // ECPrivateKey + using (writer.PushSequence()) + { + // version 1 + writer.WriteInteger(1); + + // privateKey + writer.WriteOctetString(d); + + // domainParameters + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0, isConstructed: true))) + { + writer.WriteObjectIdentifier(curveOid); + } + + // publicKey + if (x != null) + { + Debug.Assert(y != null); + + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 1, isConstructed: true))) + { + EccKeyFormatHelper.WriteUncompressedPublicKey(x, y, writer); + } + } + } + } + } + + internal override bool TryExportPublicKey(Span destination, out int bytesWritten) + { + int fieldWidth = _algorithm.KeySizeInBytes; + + if (destination.Length < 1 + 2 * fieldWidth) + { + Debug.Fail("Public key format is fixed size, so caller needs to provide exactly correct sized buffer."); + + bytesWritten = 0; + return false; + } + + byte[]? x = null; + byte[]? y = null; + +#if NET || NETSTANDARD + ECParameters ecParameters = _ecdsa.ExportParameters(includePrivateParameters: false); + + ecParameters.Validate(); + + x = ecParameters.Q.X; + y = ecParameters.Q.Y; +#else + // Public parameters, x and y, don't need pinning so they can be pulled out of the inner lambdas. + _ecdsa.Key.ExportKeyBlob( + CngKeyBlobFormat.EccPublicBlob.Format, + blob => + { + ECCng.DecodeEccKeyBlob( + blob, + (magic, localX, localY, _) => + { + if (magic != _algorithm.PublicKeyBlobMagicNumber) + { + Debug.Fail("Unexpected magic number."); + throw new CryptographicException(); + } + + if (!TryValidateNamedCurve(localX, localY, null)) + { + Debug.Fail("Invalid EC parameters."); + throw new CryptographicException(); + } + + x = localX; + y = localY; + return true; + }); + }); +#endif + + Debug.Assert(x is not null); + Debug.Assert(y is not null); + + if (x.Length != fieldWidth || y.Length != fieldWidth) + { + Debug.Fail("Unexpected key size."); + throw new CryptographicException(); + } + + // Uncompressed ECPoint format + destination[0] = 0x04; + + x.CopyTo(destination.Slice(1, fieldWidth)); + y.CopyTo(destination.Slice(1 + fieldWidth)); + + bytesWritten = 1 + 2 * fieldWidth; + return true; + } + + internal override bool VerifyData( +#if NET + ReadOnlySpan data, +#else + byte[] data, +#endif + ReadOnlySpan signature) + { +#if NET + return _ecdsa.VerifyData(data, signature, _algorithm.HashAlgorithmName, DSASignatureFormat.Rfc3279DerSequence); +#else + byte[] ieeeSignature = null; + + try + { + ieeeSignature = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(signature, _algorithm.KeySizeInBits); + } + catch (CryptographicException) + { + return false; + } + + return _ecdsa.VerifyData(data, ieeeSignature, _algorithm.HashAlgorithmName); +#endif + } + + internal override int SignData( +#if NET + ReadOnlySpan data, +#else + byte[] data, +#endif + Span destination) + { +#if NET + if (!_ecdsa.TrySignData(data, destination, _algorithm.HashAlgorithmName, DSASignatureFormat.Rfc3279DerSequence, out int bytesWritten)) + { + Debug.Fail("Buffer size should have been validated by caller."); + throw new CryptographicException(); + } + + return bytesWritten; +#else + byte[] ieeeSignature = _ecdsa.SignData(data, _algorithm.HashAlgorithmName); + + if (!AsymmetricAlgorithmHelpers.TryConvertIeee1363ToDer(ieeeSignature, destination, out int bytesWritten)) + { + Debug.Fail("Buffer size should have been validated by caller."); + throw new CryptographicException(); + } + + return bytesWritten; +#endif + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _ecdsa?.Dispose(); + _ecdsa = null!; + } + + base.Dispose(disposing); + } + +#if NETFRAMEWORK +#if NET472_OR_GREATER +#error ECDsa.Create(ECParameters) is available in .NET Framework 4.7.2 and later, so this workaround is not needed anymore. +#endif + private static ECDsaCng ImportKeyBlob(byte[] ecKeyBlob, string curveName, bool includePrivateParameters) + { + CngKeyBlobFormat blobFormat = includePrivateParameters ? CngKeyBlobFormat.EccPrivateBlob : CngKeyBlobFormat.EccPublicBlob; + CngProvider provider = CngProvider.MicrosoftSoftwareKeyStorageProvider; + + using (SafeNCryptProviderHandle providerHandle = provider.OpenStorageProvider()) + using (SafeNCryptKeyHandle keyHandle = ECCng.ImportKeyBlob(blobFormat.Format, ecKeyBlob, curveName, providerHandle)) + using (CngKey key = CngKey.Open(keyHandle, CngKeyHandleOpenOptions.EphemeralKey)) + { + key.SetExportPolicy(CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport); + return new ECDsaCng(key); + } + } + + private static ECDsaCng CreateKey(string curveName) + { + CngKeyCreationParameters creationParameters = new CngKeyCreationParameters() + { + ExportPolicy = CngExportPolicies.AllowPlaintextExport, + }; + + byte[] curveNameBytes = new byte[(curveName.Length + 1) * sizeof(char)]; // +1 to add trailing null + System.Text.Encoding.Unicode.GetBytes(curveName, 0, curveName.Length, curveNameBytes, 0); + creationParameters.Parameters.Add(new CngProperty(KeyPropertyName.ECCCurveName, curveNameBytes, CngPropertyOptions.None)); + + using (CngKey key = CngKey.Create(new CngAlgorithm("ECDSA"), null, creationParameters)) + { + return new ECDsaCng(key); + } + } + + private static bool TryValidateNamedCurve(byte[]? x, byte[]? y, byte[]? d) + { + bool hasErrors = true; + + if (d is not null && y is null && x is null) + { + hasErrors = false; + } + else if (y is not null && x is not null && y.Length == x.Length) + { + hasErrors = (d is not null && (d.Length != x.Length)); + } + + return !hasErrors; + } +#endif + } + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.RSA.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.RSA.cs new file mode 100644 index 00000000000000..1aed30d805a0a6 --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.RSA.cs @@ -0,0 +1,285 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Formats.Asn1; + +namespace System.Security.Cryptography +{ + internal sealed partial class CompositeMLDsaManaged + { + private sealed class RsaComponent : ComponentAlgorithm +#if DESIGNTIMEINTERFACES +#pragma warning disable SA1001 // Commas should be spaced correctly + , IComponentAlgorithmFactory +#pragma warning restore SA1001 // Commas should be spaced correctly +#endif + { + private readonly HashAlgorithmName _hashAlgorithmName; + private readonly RSASignaturePadding _padding; + + private RSA _rsa; + + private RsaComponent(RSA rsa, HashAlgorithmName hashAlgorithmName, RSASignaturePadding padding) + { + Debug.Assert(rsa is not null); + Debug.Assert(padding is not null); + + _rsa = rsa; + _hashAlgorithmName = hashAlgorithmName; + _padding = padding; + } + + public static bool IsAlgorithmSupported(RsaAlgorithm _) => true; + +#if NETFRAMEWORK + // RSA-PSS requires RSACng on .NET Framework + private static RSACng CreateRSA() => new RSACng(); + private static RSACng CreateRSA(int keySizeInBits) => new RSACng(keySizeInBits); +#elif NETSTANDARD2_0 + private static RSA CreateRSA() => RSA.Create(); + + private static RSA CreateRSA(int keySizeInBits) + { + RSA rsa = RSA.Create(); + + try + { + rsa.KeySize = keySizeInBits; + return rsa; + } + catch + { + rsa.Dispose(); + throw; + } + } +#else + private static RSA CreateRSA() => RSA.Create(); + private static RSA CreateRSA(int keySizeInBits) => RSA.Create(keySizeInBits); +#endif + + internal override int SignData( +#if NET + ReadOnlySpan data, +#else + byte[] data, +#endif + Span destination) + { +#if NET + return _rsa.SignData(data, destination, _hashAlgorithmName, _padding); +#else + // Composite ML-DSA virtual methods only accept ROS so we need to allocate for signature + byte[] signature = _rsa.SignData(data, _hashAlgorithmName, _padding); + + if (signature.AsSpan().TryCopyTo(destination)) + { + return signature.Length; + } + + CryptographicOperations.ZeroMemory(destination); + + throw new CryptographicException(); +#endif + } + + internal override bool VerifyData( +#if NET + ReadOnlySpan data, +#else + byte[] data, +#endif + ReadOnlySpan signature) + { +#if NET + return _rsa.VerifyData(data, signature, _hashAlgorithmName, _padding); +#else + // Composite ML-DSA virtual methods only accept ROS so we need to use ToArray() for signature + return _rsa.VerifyData(data, signature.ToArray(), _hashAlgorithmName, _padding); +#endif + } + + public static RsaComponent GenerateKey(RsaAlgorithm algorithm) + { + RSA? rsa = null; + + try + { + rsa = CreateRSA(algorithm.KeySizeInBits); + + // RSA key generation is lazy, so we need to force it to happen eagerly. + _ = rsa.ExportParameters(includePrivateParameters: false); + + return new RsaComponent(rsa, algorithm.HashAlgorithmName, algorithm.Padding); + } + catch (CryptographicException) + { + rsa?.Dispose(); + throw; + } + } + + public static RsaComponent ImportPrivateKey(RsaAlgorithm algorithm, ReadOnlySpan source) + { + Debug.Assert(IsAlgorithmSupported(algorithm)); + + RSA? rsa = null; + + try + { + int bytesRead; + rsa = CreateRSA(); + +#if NET + rsa.ImportRSAPrivateKey(source, out bytesRead); +#else + try + { + AsnDecoder.ReadEncodedValue( + source, + AsnEncodingRules.BER, + out _, + out _, + out bytesRead); + + RSAKeyFormatHelper.FromPkcs1PrivateKey( + source.Slice(0, bytesRead), + rsaParameters => + { + rsa.ImportParameters(rsaParameters); + return true; + }); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } +#endif + if (rsa.KeySize != algorithm.KeySizeInBits) + { + throw new CryptographicException(SR.Argument_PrivateKeyWrongSizeForAlgorithm); + } + + if (bytesRead != source.Length) + { + throw new CryptographicException(SR.Argument_PrivateKeyWrongSizeForAlgorithm); + } + } + catch (CryptographicException) + { + rsa?.Dispose(); + throw; + } + + return new RsaComponent(rsa, algorithm.HashAlgorithmName, algorithm.Padding); + } + + public static RsaComponent ImportPublicKey(RsaAlgorithm algorithm, ReadOnlySpan source) + { + Debug.Assert(IsAlgorithmSupported(algorithm)); + + RSA? rsa = null; + + try + { + int bytesRead; + rsa = CreateRSA(); + +#if NET + rsa.ImportRSAPublicKey(source, out bytesRead); +#else + try + { + AsnDecoder.ReadEncodedValue( + source, + AsnEncodingRules.BER, + out _, + out _, + out bytesRead); + + RSAKeyFormatHelper.FromPkcs1PublicKey( + source.Slice(0, bytesRead), + rsaParameters => + { + rsa.ImportParameters(rsaParameters); + return true; + }); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } +#endif + if (rsa.KeySize != algorithm.KeySizeInBits) + { + throw new CryptographicException(SR.Argument_PublicKeyWrongSizeForAlgorithm); + } + + if (bytesRead != source.Length) + { + throw new CryptographicException(SR.Argument_PublicKeyWrongSizeForAlgorithm); + } + } + catch (CryptographicException) + { + rsa?.Dispose(); + throw; + } + + return new RsaComponent(rsa, algorithm.HashAlgorithmName, algorithm.Padding); + } + + internal override bool TryExportPublicKey(Span destination, out int bytesWritten) + { +#if NET + return _rsa.TryExportRSAPublicKey(destination, out bytesWritten); +#else + RSAParameters parameters = _rsa.ExportParameters(includePrivateParameters: false); + AsnWriter writer = RSAKeyFormatHelper.WritePkcs1PublicKey(in parameters); + return writer.TryEncode(destination, out bytesWritten); +#endif + } + + internal override bool TryExportPrivateKey(Span destination, out int bytesWritten) + { +#if NET + return _rsa.TryExportRSAPrivateKey(destination, out bytesWritten); +#else + RSAParameters parameters = _rsa.ExportParameters(includePrivateParameters: true); + + using (PinAndClear.Track(parameters.D)) + using (PinAndClear.Track(parameters.P)) + using (PinAndClear.Track(parameters.Q)) + using (PinAndClear.Track(parameters.DP)) + using (PinAndClear.Track(parameters.DQ)) + using (PinAndClear.Track(parameters.InverseQ)) + { + AsnWriter? writer = null; + + try + { + writer = RSAKeyFormatHelper.WritePkcs1PrivateKey(in parameters); + return writer.TryEncode(destination, out bytesWritten); + } + finally + { + writer?.Reset(); + } + } +#endif + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _rsa?.Dispose(); + _rsa = null!; + } + + base.Dispose(disposing); + } + } + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.cs b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.cs new file mode 100644 index 00000000000000..5bb63453387841 --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/CompositeMLDsaManaged.cs @@ -0,0 +1,843 @@ +// 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.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; +using Internal.Cryptography; + +#if NETFRAMEWORK +using KeyBlobMagicNumber = Interop.BCrypt.KeyBlobMagicNumber; +#endif + +namespace System.Security.Cryptography +{ +#if !SYSTEM_SECURITY_CRYPTOGRAPHY + // System.Security.Cryptography excludes browser at build time, but we need to rely on UnsupportedOSPlatform for Microsoft.Bcl.Cryptography. + [UnsupportedOSPlatform("browser")] +#endif + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + internal sealed partial class CompositeMLDsaManaged : CompositeMLDsa + { + private static readonly Dictionary s_algorithmMetadata = CreateAlgorithmMetadata(); + private static readonly ConcurrentDictionary s_algorithmSupport = new(); + + private static ReadOnlySpan MessageRepresentativePrefix => "CompositeAlgorithmSignatures2025"u8; + + private MLDsa _mldsa; + private ComponentAlgorithm _componentAlgorithm; + + private AlgorithmMetadata AlgorithmDetails => field ??= s_algorithmMetadata[Algorithm]; + + private CompositeMLDsaManaged(CompositeMLDsaAlgorithm algorithm, MLDsa mldsa, ComponentAlgorithm componentAlgorithm) + : base(algorithm) + { + _mldsa = mldsa; + _componentAlgorithm = componentAlgorithm; + } + + internal static bool SupportsAny() => MLDsaImplementation.SupportsAny(); + + internal static bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm algorithm) + { + AlgorithmMetadata metadata = s_algorithmMetadata[algorithm]; + + return s_algorithmSupport.GetOrAdd( + algorithm, + alg => MLDsaImplementation.IsAlgorithmSupported(metadata.MLDsaAlgorithm) && metadata.TraditionalAlgorithm switch + { + RsaAlgorithm rsaAlgorithm => RsaComponent.IsAlgorithmSupported(rsaAlgorithm), + ECDsaAlgorithm ecdsaAlgorithm => ECDsaComponent.IsAlgorithmSupported(ecdsaAlgorithm), + _ => false, + }); + } + + internal static CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) + { + Debug.Assert(IsAlgorithmSupportedImpl(algorithm)); + + AlgorithmMetadata metadata = s_algorithmMetadata[algorithm]; + + // draft-ietf-lamps-pq-composite-sigs-latest (July 7, 2025), 4.1 + // 1. Generate component keys + // + // mldsaSeed = Random(32) + // (mldsaPK, _) = ML-DSA.KeyGen(mldsaSeed) + // (tradPK, tradSK) = Trad.KeyGen() + + MLDsa? mldsaKey = null; + ComponentAlgorithm? tradKey = null; + + try + { + mldsaKey = MLDsaImplementation.GenerateKey(metadata.MLDsaAlgorithm); + } + catch (CryptographicException) + { + } + + try + { + tradKey = metadata.TraditionalAlgorithm switch + { + RsaAlgorithm rsaAlgorithm => RsaComponent.GenerateKey(rsaAlgorithm), + ECDsaAlgorithm ecdsaAlgorithm => ECDsaComponent.GenerateKey(ecdsaAlgorithm), + _ => FailAndGetNull(), + }; + + static ComponentAlgorithm? FailAndGetNull() + { + Debug.Fail("Only supported algorithms should reach here."); + return null; + } + } + catch (CryptographicException) + { + } + + // 2. Check for component key gen failure + // + // if NOT (mldsaPK, mldsaSK) or NOT (tradPK, tradSK): + // output "Key generation error" + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] + static bool KeyGenFailed([NotNullWhen(false)] MLDsa? mldsaKey, [NotNullWhen(false)] ComponentAlgorithm? tradKey) => + (mldsaKey is null) | (tradKey is null); + + if (KeyGenFailed(mldsaKey, tradKey)) + { + try + { + Debug.Assert(mldsaKey is null || tradKey is null); + + mldsaKey?.Dispose(); + tradKey?.Dispose(); + } + catch (CryptographicException) + { + } + + throw new CryptographicException(); + } + + // 3. Output the composite public and private keys + // + // pk = SerializePublicKey(mldsaPK, tradPK) + // sk = SerializePrivateKey(mldsaSeed, tradSK) + // return (pk, sk) + + return new CompositeMLDsaManaged(algorithm, mldsaKey, tradKey); + } + + internal static CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) + { + Debug.Assert(IsAlgorithmSupportedImpl(algorithm)); + + AlgorithmMetadata metadata = s_algorithmMetadata[algorithm]; + + // draft-ietf-lamps-pq-composite-sigs-latest (June 20, 2025), 5.1 + // 1. Parse each constituent encoded public key. + // The length of the mldsaKey is known based on the size of + // the ML-DSA component key length specified by the Object ID. + // + // switch ML-DSA do + // case ML-DSA-44: + // mldsaPK = bytes[:1312] + // tradPK = bytes[1312:] + // case ML-DSA-65: + // mldsaPK = bytes[:1952] + // tradPK = bytes[1952:] + // case ML-DSA-87: + // mldsaPK = bytes[:2592] + // tradPK = bytes[2592:] + // + // Note that while ML-DSA has fixed-length keys, RSA and ECDSA + // may not, depending on encoding, so rigorous length - checking + // of the overall composite key is not always possible. + // + // 2. Output the component public keys + // + // output(mldsaPK, tradPK) + + ReadOnlySpan mldsaKey = source.Slice(0, metadata.MLDsaAlgorithm.PublicKeySizeInBytes); + ReadOnlySpan tradKey = source.Slice(metadata.MLDsaAlgorithm.PublicKeySizeInBytes); + + MLDsaImplementation mldsa = MLDsaImplementation.ImportPublicKey(metadata.MLDsaAlgorithm, mldsaKey); + ComponentAlgorithm componentAlgorithm = metadata.TraditionalAlgorithm switch + { + RsaAlgorithm rsaAlgorithm => RsaComponent.ImportPublicKey(rsaAlgorithm, tradKey), + ECDsaAlgorithm ecdsaAlgorithm => ECDsaComponent.ImportPublicKey(ecdsaAlgorithm, tradKey), + _ => throw FailAndGetException(), + }; + + static CryptographicException FailAndGetException() + { + Debug.Fail("Only supported algorithms should reach here."); + return new CryptographicException(); + } + + return new CompositeMLDsaManaged(algorithm, mldsa, componentAlgorithm); + } + + internal static CompositeMLDsa ImportCompositeMLDsaPrivateKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) + { + Debug.Assert(IsAlgorithmSupportedImpl(algorithm)); + + AlgorithmMetadata metadata = s_algorithmMetadata[algorithm]; + + // draft-ietf-lamps-pq-composite-sigs-latest (June 20, 2025), 5.2 + // 1. Parse each constituent encoded key. + // The length of an ML-DSA private key is always a 32 byte seed + // for all parameter sets. + // + // mldsaSeed = bytes[:32] + // tradSK = bytes[32:] + // + // Note that while ML-DSA has fixed-length keys, RSA and ECDSA + // may not, depending on encoding, so rigorous length-checking + // of the overall composite key is not always possible. + // + // 2. Output the component private keys + // + // output (mldsaSeed, tradSK) + + ReadOnlySpan mldsaKey = source.Slice(0, metadata.MLDsaAlgorithm.PrivateSeedSizeInBytes); + ReadOnlySpan tradKey = source.Slice(metadata.MLDsaAlgorithm.PrivateSeedSizeInBytes); + + MLDsaImplementation mldsa = MLDsaImplementation.ImportSeed(metadata.MLDsaAlgorithm, mldsaKey); + ComponentAlgorithm componentAlgorithm = metadata.TraditionalAlgorithm switch + { + RsaAlgorithm rsaAlgorithm => RsaComponent.ImportPrivateKey(rsaAlgorithm, tradKey), + ECDsaAlgorithm ecdsaAlgorithm => ECDsaComponent.ImportPrivateKey(ecdsaAlgorithm, tradKey), + _ => throw FailAndGetException(), + }; + + static CryptographicException FailAndGetException() + { + Debug.Fail("Only supported algorithms should reach here."); + return new CryptographicException(); + } + + return new CompositeMLDsaManaged(algorithm, mldsa, componentAlgorithm); + } + + protected override int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) + { + // draft-ietf-lamps-pq-composite-sigs-latest (June 20, 2025), 4.2 + // 1. If len(ctx) > 255: + // return error + + Debug.Assert(context.Length <= 255, $"Caller should have checked context.Length, got {context.Length}"); + + // 2. Compute the Message representative M'. + // As in FIPS 204, len(ctx) is encoded as a single unsigned byte. + // Randomize the message representative + // + // r = Random(32) + // M' := Prefix || Domain || len(ctx) || ctx || r + // || PH( M ) + + Span r = stackalloc byte[CompositeMLDsaAlgorithm.RandomizerSizeInBytes]; + RandomNumberGenerator.Fill(r); + + byte[] M_prime = GetMessageRepresentative(AlgorithmDetails, context, r, data); + + // 3. Separate the private key into component keys + // and re-generate the ML-DSA key from seed. + // + // (mldsaSeed, tradSK) = DeserializePrivateKey(sk) + // (_, mldsaSK) = ML-DSA.KeyGen(mldsaSeed) + + /* no-op */ + + // 4. Generate the two component signatures independently by calculating + // the signature over M' according to their algorithm specifications. + // + // mldsaSig = ML-DSA.Sign( mldsaSK, M', ctx=Domain ) + // tradSig = Trad.Sign( tradSK, M' ) + + // Note that in step 4 above, both component signature processes are + // invoked, and no indication is given about which one failed.This + // SHOULD be done in a timing-invariant way to prevent side-channel + // attackers from learning which component algorithm failed. + + Span randomizer = destination.Slice(0, CompositeMLDsaAlgorithm.RandomizerSizeInBytes); + Span mldsaSig = destination.Slice(CompositeMLDsaAlgorithm.RandomizerSizeInBytes, AlgorithmDetails.MLDsaAlgorithm.SignatureSizeInBytes); + Span tradSig = destination.Slice(CompositeMLDsaAlgorithm.RandomizerSizeInBytes + AlgorithmDetails.MLDsaAlgorithm.SignatureSizeInBytes); + + bool mldsaSigned = false; + bool tradSigned = false; + + try + { + _mldsa.SignData(M_prime, mldsaSig, AlgorithmDetails.DomainSeparator); + mldsaSigned = true; + } + catch (CryptographicException) + { + } + + int tradBytesWritten = 0; + + try + { + tradBytesWritten = _componentAlgorithm.SignData(M_prime, tradSig); + tradSigned = true; + } + catch (CryptographicException) + { + } + + // 5. If either ML-DSA.Sign() or Trad.Sign() return an error, then this + // process MUST return an error. + // + // if NOT mldsaSig or NOT tradSig: + // output "Signature generation error" + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] + static bool Or(bool x, bool y) => x | y; + + if (Or(!mldsaSigned, !tradSigned)) + { + CryptographicOperations.ZeroMemory(destination); + throw new CryptographicException(SR.Cryptography_CompositeSignDataError); + } + + // 6. Output the encoded composite signature value. + // + // s = SerializeSignatureValue(r, mldsaSig, tradSig) + // return s + + r.CopyTo(randomizer); + return randomizer.Length + mldsaSig.Length + tradBytesWritten; + } + + protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) + { + // draft-ietf-lamps-pq-composite-sigs-latest (June 20, 2025), 4.3 + // 1. If len(ctx) > 255 + // return error + + Debug.Assert(context.Length <= 255, $"Caller should have checked context.Length, got {context.Length}"); + + // 2. Separate the keys and signatures + // + // (mldsaPK, tradPK) = DeserializePublicKey(pk) + // (r, mldsaSig, tradSig) = DeserializeSignatureValue(s) + // + // If Error during deserialization, or if any of the component + // keys or signature values are not of the correct type or + // length for the given component algorithm then output + // "Invalid signature" and stop. + + ReadOnlySpan r = signature.Slice(0, CompositeMLDsaAlgorithm.RandomizerSizeInBytes); + ReadOnlySpan mldsaSig = signature.Slice(CompositeMLDsaAlgorithm.RandomizerSizeInBytes, AlgorithmDetails.MLDsaAlgorithm.SignatureSizeInBytes); + ReadOnlySpan tradSig = signature.Slice(CompositeMLDsaAlgorithm.RandomizerSizeInBytes + AlgorithmDetails.MLDsaAlgorithm.SignatureSizeInBytes); + + // 3. Compute a Hash of the Message. + // As in FIPS 204, len(ctx) is encoded as a single unsigned byte. + // + // M' = Prefix || Domain || len(ctx) || ctx || r + // || PH( M ) + + byte[] M_prime = GetMessageRepresentative(AlgorithmDetails, context, r, data); + + // 4. Check each component signature individually, according to its + // algorithm specification. + // If any fail, then the entire signature validation fails. + // + // if not ML-DSA.Verify( mldsaPK, M', mldsaSig, ctx=Domain ) then + // output "Invalid signature" + // + // if not Trad.Verify( tradPK, M', tradSig ) then + // output "Invalid signature" + // + // if all succeeded, then + // output "Valid signature" + + // We don't short circuit here because we want to avoid revealing which component signature failed. + // This is not required in the spec, but it is a good practice to avoid timing attacks. + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] + static bool And(bool x, bool y) => x & y; + + return And(_mldsa.VerifyData(M_prime, mldsaSig, AlgorithmDetails.DomainSeparator), _componentAlgorithm.VerifyData(M_prime, tradSig)); + } + + protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) => + throw new PlatformNotSupportedException(); + + protected override int ExportCompositeMLDsaPublicKeyCore(Span destination) + { + // draft-ietf-lamps-pq-composite-sigs-latest (June 20, 2025), 5.1 + // 1. Combine and output the encoded public key + // + // output mldsaPK || tradPK + + int bytesWritten = 0; + + _mldsa.ExportMLDsaPublicKey(destination.Slice(0, AlgorithmDetails.MLDsaAlgorithm.PublicKeySizeInBytes)); + bytesWritten += AlgorithmDetails.MLDsaAlgorithm.PublicKeySizeInBytes; + + if (!_componentAlgorithm.TryExportPublicKey(destination.Slice(AlgorithmDetails.MLDsaAlgorithm.PublicKeySizeInBytes), out int componentBytesWritten)) + { + throw new CryptographicException(); + } + + bytesWritten += componentBytesWritten; + + return bytesWritten; + } + + protected override int ExportCompositeMLDsaPrivateKeyCore(Span destination) + { + // draft-ietf-lamps-pq-composite-sigs-latest (June 20, 2025), 5.2 + // 1. Combine and output the encoded private key + // + // output mldsaSeed || tradSK + + try + { + int bytesWritten = 0; + + _mldsa.ExportMLDsaPrivateSeed(destination.Slice(0, AlgorithmDetails.MLDsaAlgorithm.PrivateSeedSizeInBytes)); + bytesWritten += AlgorithmDetails.MLDsaAlgorithm.PrivateSeedSizeInBytes; + + if (!_componentAlgorithm.TryExportPrivateKey(destination.Slice(AlgorithmDetails.MLDsaAlgorithm.PrivateSeedSizeInBytes), out int componentBytesWritten)) + { + throw new CryptographicException(); + } + + bytesWritten += componentBytesWritten; + + return bytesWritten; + } + catch (CryptographicException) + { + CryptographicOperations.ZeroMemory(destination); + throw; + } + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _mldsa?.Dispose(); + _mldsa = null!; + + _componentAlgorithm?.Dispose(); + _componentAlgorithm = null!; + } + + base.Dispose(disposing); + } + + private static byte[] GetMessageRepresentative( + AlgorithmMetadata metadata, + ReadOnlySpan context, + ReadOnlySpan r, + ReadOnlySpan message) + { + checked + { + Debug.Assert(r.Length is CompositeMLDsaAlgorithm.RandomizerSizeInBytes); + + // M' = Prefix || Domain || len(ctx) || ctx || r || PH( M ) + + using (IncrementalHash hash = IncrementalHash.CreateHash(metadata.HashAlgorithmName)) + { +#if NET + int hashLength = hash.HashLengthInBytes; +#else + int hashLength = hash.GetHashLengthInBytes(); +#endif + + int length = + MessageRepresentativePrefix.Length + // Prefix + metadata.DomainSeparator.Length + // Domain + 1 + // len(ctx) + context.Length + // ctx + r.Length + // r + hashLength; // PH( M ) + + // The representative message will often be < 256 bytes so we can stackalloc with a callback. + // That gets a little messy on .NET Framework where by-ref generics aren't supported, so we just allocate. + byte[] M_prime = new byte[length]; + + int offset = 0; + + // Prefix + MessageRepresentativePrefix.CopyTo(M_prime.AsSpan(offset, MessageRepresentativePrefix.Length)); + offset += MessageRepresentativePrefix.Length; + + // Domain + metadata.DomainSeparator.AsSpan().CopyTo(M_prime.AsSpan(offset, metadata.DomainSeparator.Length)); + offset += metadata.DomainSeparator.Length; + + // len(ctx) + M_prime[offset] = (byte)context.Length; + offset++; + + // ctx + context.CopyTo(M_prime.AsSpan(offset, context.Length)); + offset += context.Length; + + // r + r.CopyTo(M_prime.AsSpan(offset, r.Length)); + offset += r.Length; + + // PH( M ) + hash.AppendData(message); +#if NET + hash.GetHashAndReset(M_prime.AsSpan(offset, hashLength)); +#else + byte[] hashBytes = hash.GetHashAndReset(); + hashBytes.CopyTo(M_prime.AsSpan(offset, hashLength)); +#endif + offset += hashLength; + + Debug.Assert(offset == M_prime.Length); + + return M_prime; + } + } + } + +#if DESIGNTIMEINTERFACES + private interface IComponentAlgorithmFactory + where TComponentAlgorithm : ComponentAlgorithm, IComponentAlgorithmFactory + { + internal static abstract bool IsAlgorithmSupported(TAlgorithmDescriptor algorithm); + internal static abstract TComponentAlgorithm GenerateKey(TAlgorithmDescriptor algorithm); + internal static abstract TComponentAlgorithm ImportPrivateKey(TAlgorithmDescriptor algorithm, ReadOnlySpan source); + internal static abstract TComponentAlgorithm ImportPublicKey(TAlgorithmDescriptor algorithm, ReadOnlySpan source); + } +#endif + + private abstract class ComponentAlgorithm : IDisposable + { + private bool _disposed; + + internal abstract bool TryExportPublicKey(Span destination, out int bytesWritten); + internal abstract bool TryExportPrivateKey(Span destination, out int bytesWritten); + + internal abstract int SignData( +#if NET + ReadOnlySpan data, +#else + byte[] data, +#endif + Span destination); + + internal abstract bool VerifyData( +#if NET + ReadOnlySpan data, +#else + byte[] data, +#endif + ReadOnlySpan signature); + + public void Dispose() + { + if (!_disposed) + { + _disposed = true; + Dispose(true); + GC.SuppressFinalize(this); + } + } + + protected virtual void Dispose(bool disposing) + { + } + } + + private static Dictionary CreateAlgorithmMetadata() + { + const int count = 18; + + Dictionary algorithmMetadata = new(count) + { + { + CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa44, + new RsaAlgorithm(2048, HashAlgorithmName.SHA256, RSASignaturePadding.Pss), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x00], + HashAlgorithmName.SHA256) + }, + { + CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pkcs15, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa44, + new RsaAlgorithm(2048, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x01], + HashAlgorithmName.SHA256) + }, + { + CompositeMLDsaAlgorithm.MLDsa44WithEd25519, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa44, + new EdDsaAlgorithm(), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x02], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa44, + ECDsaAlgorithm.CreateP256(HashAlgorithmName.SHA256), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x03], + HashAlgorithmName.SHA256) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + new RsaAlgorithm(3072, HashAlgorithmName.SHA256, RSASignaturePadding.Pss), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x04], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pkcs15, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + new RsaAlgorithm(3072, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x05], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + new RsaAlgorithm(4096, HashAlgorithmName.SHA384, RSASignaturePadding.Pss), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x06], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pkcs15, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + new RsaAlgorithm(4096, HashAlgorithmName.SHA384, RSASignaturePadding.Pkcs1), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x07], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + ECDsaAlgorithm.CreateP256(HashAlgorithmName.SHA256), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x08], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + ECDsaAlgorithm.CreateP384(HashAlgorithmName.SHA384), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x09], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithECDsaBrainpoolP256r1, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + ECDsaAlgorithm.CreateBrainpoolP256r1(HashAlgorithmName.SHA256), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x0A], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa65WithEd25519, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa65, + new EdDsaAlgorithm(), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x0B], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa87WithECDsaP384, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa87, + ECDsaAlgorithm.CreateP384(HashAlgorithmName.SHA384), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x0C], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa87WithECDsaBrainpoolP384r1, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa87, + ECDsaAlgorithm.CreateBrainpoolP384r1(HashAlgorithmName.SHA384), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x0D], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa87WithEd448, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa87, + new EdDsaAlgorithm(), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x0E], + new HashAlgorithmName("SHAKE256")) + }, + { + CompositeMLDsaAlgorithm.MLDsa87WithRSA3072Pss, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa87, + new RsaAlgorithm(3072, HashAlgorithmName.SHA256, RSASignaturePadding.Pss), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x0F], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa87WithRSA4096Pss, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa87, + new RsaAlgorithm(4096, HashAlgorithmName.SHA384, RSASignaturePadding.Pss), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x10], + HashAlgorithmName.SHA512) + }, + { + CompositeMLDsaAlgorithm.MLDsa87WithECDsaP521, + new AlgorithmMetadata( + MLDsaAlgorithm.MLDsa87, + ECDsaAlgorithm.CreateP521(HashAlgorithmName.SHA512), + [0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xFA, 0x6B, 0x50, 0x09, 0x01, 0x11], + HashAlgorithmName.SHA512) + } + }; + + Debug.Assert(count == algorithmMetadata.Count); + + return algorithmMetadata; + } + + private sealed class AlgorithmMetadata( + MLDsaAlgorithm mldsaAlgorithm, + object traditionalAlgorithm, + byte[] domainSeparator, + HashAlgorithmName hashAlgorithmName) + { + internal MLDsaAlgorithm MLDsaAlgorithm { get; } = mldsaAlgorithm; + internal object TraditionalAlgorithm { get; } = traditionalAlgorithm; + internal byte[] DomainSeparator { get; } = domainSeparator; + internal HashAlgorithmName HashAlgorithmName { get; } = hashAlgorithmName; + } + + private sealed class RsaAlgorithm(int keySizeInBits, HashAlgorithmName hashAlgorithmName, RSASignaturePadding padding) + { + internal int KeySizeInBits { get; } = keySizeInBits; + internal HashAlgorithmName HashAlgorithmName { get; } = hashAlgorithmName; + internal RSASignaturePadding Padding { get; } = padding; + } + + private sealed class ECDsaAlgorithm + { + internal int KeySizeInBits { get; } + internal HashAlgorithmName HashAlgorithmName { get; } + +#if NET || NETSTANDARD + internal ECCurve Curve { get; } + internal Oid CurveOid => Curve.Oid; +#else + internal Oid CurveOid { get; } + internal KeyBlobMagicNumber PrivateKeyBlobMagicNumber { get; } + internal KeyBlobMagicNumber PublicKeyBlobMagicNumber { get; } +#endif + + internal string CurveOidValue => CurveOid.Value!; + + internal int KeySizeInBytes => (KeySizeInBits + 7) / 8; + + private ECDsaAlgorithm( + int keySizeInBits, +#if NET || NETSTANDARD + ECCurve curve, +#else + Oid curveOid, + KeyBlobMagicNumber privateKeyBlobMagicNumber, + KeyBlobMagicNumber publicKeyBlobMagicNumber, +#endif + HashAlgorithmName hashAlgorithmName) + { + KeySizeInBits = keySizeInBits; + HashAlgorithmName = hashAlgorithmName; + +#if NET || NETSTANDARD + Curve = curve; +#else + CurveOid = curveOid; + PrivateKeyBlobMagicNumber = privateKeyBlobMagicNumber; + PublicKeyBlobMagicNumber = publicKeyBlobMagicNumber; +#endif + + Debug.Assert(CurveOid.Value is not null); + } + + internal static ECDsaAlgorithm CreateP256(HashAlgorithmName hashAlgorithmName) => + new ECDsaAlgorithm( + 256, +#if NET || NETSTANDARD + ECCurve.NamedCurves.nistP256, +#else + new Oid(Oids.secp256r1, "nistP256"), + KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_P256_MAGIC, + KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_P256_MAGIC, +#endif + hashAlgorithmName); + + internal static ECDsaAlgorithm CreateP384(HashAlgorithmName hashAlgorithmName) => + new ECDsaAlgorithm( + 384, +#if NET || NETSTANDARD + ECCurve.NamedCurves.nistP384, +#else + new Oid(Oids.secp384r1, "nistP384"), + KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_P384_MAGIC, + KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_P384_MAGIC, +#endif + hashAlgorithmName); + + internal static ECDsaAlgorithm CreateP521(HashAlgorithmName hashAlgorithmName) => + new ECDsaAlgorithm( + 521, +#if NET || NETSTANDARD + ECCurve.NamedCurves.nistP521, +#else + new Oid(Oids.secp521r1, "nistP521"), + KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_P521_MAGIC, + KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_P521_MAGIC, +#endif + hashAlgorithmName); + + internal static ECDsaAlgorithm CreateBrainpoolP256r1(HashAlgorithmName hashAlgorithmName) => + new ECDsaAlgorithm( + 256, +#if NET || NETSTANDARD + ECCurve.NamedCurves.brainpoolP256r1, +#else + new Oid(Oids.brainpoolP256r1, "brainpoolP256r1"), + KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC, + KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC, +#endif + hashAlgorithmName); + + internal static ECDsaAlgorithm CreateBrainpoolP384r1(HashAlgorithmName hashAlgorithmName) => + new ECDsaAlgorithm( + 384, +#if NET || NETSTANDARD + ECCurve.NamedCurves.brainpoolP384r1, +#else + new Oid(Oids.brainpoolP384r1, "brainpoolP384r1"), + KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC, + KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC, +#endif + hashAlgorithmName); + } + + private sealed class EdDsaAlgorithm + { + } + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/CryptoPool.cs b/src/libraries/Common/src/System/Security/Cryptography/CryptoPool.cs index ed2d5d7ad73dde..1857fd43e63b7b 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CryptoPool.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CryptoPool.cs @@ -45,6 +45,8 @@ internal static void Return(byte[] array, int clearSize = ClearAll) internal Span Span { get; private set; } + internal readonly bool IsRented => _rented is not null; + public void Dispose() { Return(); diff --git a/src/libraries/Common/src/System/Security/Cryptography/CryptoThrowHelper.Windows.cs b/src/libraries/Common/src/System/Security/Cryptography/CryptoThrowHelper.Windows.cs index e7cd24e0eeb1f8..5e6aadd44137df 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CryptoThrowHelper.Windows.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CryptoThrowHelper.Windows.cs @@ -52,7 +52,7 @@ public WindowsCryptographicException(int hr, string message) HResult = hr; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECCng.ImportExport.NamedCurve.cs b/src/libraries/Common/src/System/Security/Cryptography/ECCng.ImportExport.NamedCurve.cs new file mode 100644 index 00000000000000..5dd46b4213c4af --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/ECCng.ImportExport.NamedCurve.cs @@ -0,0 +1,205 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; +using BCRYPT_ECCKEY_BLOB = Interop.BCrypt.BCRYPT_ECCKEY_BLOB; +using ErrorCode = Interop.NCrypt.ErrorCode; +using KeyBlobMagicNumber = Interop.BCrypt.KeyBlobMagicNumber; + +namespace System.Security.Cryptography +{ + internal static partial class ECCng + { + internal delegate TResult EncodeBlobFunc(byte[] blob); + + // When possible, operate on the blob inside the callback since the array will be pinned during its execution. + internal static T EncodeEccKeyBlob(KeyBlobMagicNumber magic, byte[] x, byte[] y, byte[]? d, Func encodeCallback, bool clearBlob = true) + { + bool includePrivateParameters = d is not null; + byte[] blob; + unsafe + { + // We need to build a key blob structured as follows: + // BCRYPT_ECCKEY_BLOB header + // byte[cbKey] Q.X + // byte[cbKey] Q.Y + // -- Only if "includePrivateParameters" is true -- + // byte[cbKey] D + + Debug.Assert(x.Length == y.Length); + + int blobSize; + + checked + { + blobSize = sizeof(BCRYPT_ECCKEY_BLOB) + + x.Length + + y.Length; + if (includePrivateParameters) + { + blobSize += d!.Length; + } + } + + blob = new byte[blobSize]; + fixed (byte* pBlob = &blob[0]) + { + try + { + // Build the header + BCRYPT_ECCKEY_BLOB* pBcryptBlob = (BCRYPT_ECCKEY_BLOB*)pBlob; + pBcryptBlob->Magic = magic; + pBcryptBlob->cbKey = x.Length; + + // Emit the blob + int offset = sizeof(BCRYPT_ECCKEY_BLOB); + Interop.BCrypt.Emit(blob, ref offset, x); + Interop.BCrypt.Emit(blob, ref offset, y); + + if (includePrivateParameters) + { + Debug.Assert(x.Length == d?.Length); + Interop.BCrypt.Emit(blob, ref offset, d!); + } + + // We better have computed the right allocation size above! + Debug.Assert(offset == blobSize); + return encodeCallback(blob); + } + finally + { + if (clearBlob) + { + CryptographicOperations.ZeroMemory(blob); + } + } + } + } + } + + internal delegate T DecodeBlobFunc(KeyBlobMagicNumber magic, byte[] x, byte[] y, byte[]? d); + + // When possible, operate on the private key inside the callback since the array will be pinned during its execution. + internal static T DecodeEccKeyBlob(ReadOnlySpan ecBlob, DecodeBlobFunc decodeCallback, bool clearPrivateKey = true) + { + // We now have a buffer laid out as follows: + // BCRYPT_ECCKEY_BLOB header + // byte[cbKey] Q.X + // byte[cbKey] Q.Y + // -- Private only -- + // byte[cbKey] D + + KeyBlobMagicNumber magic = (KeyBlobMagicNumber)MemoryMarshal.Cast(ecBlob)[0]; + + unsafe + { + // Fail-fast if a rogue provider gave us a blob that isn't even the size of the blob header. + if (ecBlob.Length < sizeof(BCRYPT_ECCKEY_BLOB)) + throw ErrorCode.E_FAIL.ToCryptographicException(); + + fixed (byte* pEcBlob = &ecBlob[0]) + { + BCRYPT_ECCKEY_BLOB* pBcryptBlob = (BCRYPT_ECCKEY_BLOB*)pEcBlob; + + int offset = sizeof(BCRYPT_ECCKEY_BLOB); + + byte[] x = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbKey); + byte[] y = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbKey); + + if (offset < ecBlob.Length) + { + byte[] d = new byte[pBcryptBlob->cbKey]; + + fixed (byte* pinnedD = d) + { + try + { + Interop.BCrypt.Consume(ecBlob, ref offset, d.Length, d); + + Debug.Assert(offset == ecBlob.Length); + + return decodeCallback(magic, x, y, d); + } + finally + { + if (clearPrivateKey) + { + CryptographicOperations.ZeroMemory(d); + } + } + } + } + else + { + Debug.Assert(offset == ecBlob.Length); + + return decodeCallback(magic, x, y, null); + } + } + } + } + + internal static SafeNCryptKeyHandle ImportKeyBlob( + string blobType, + ReadOnlySpan keyBlob, + string curveName, + SafeNCryptProviderHandle provider) + { + ErrorCode errorCode; + SafeNCryptKeyHandle keyHandle; + + using (SafeUnicodeStringHandle safeCurveName = new SafeUnicodeStringHandle(curveName)) + { + Interop.BCrypt.BCryptBufferDesc desc = default; + Interop.BCrypt.BCryptBuffer buff = default; + + IntPtr descPtr = IntPtr.Zero; + IntPtr buffPtr = IntPtr.Zero; + try + { + descPtr = Marshal.AllocHGlobal(Marshal.SizeOf(desc)); + buffPtr = Marshal.AllocHGlobal(Marshal.SizeOf(buff)); + buff.cbBuffer = (curveName.Length + 1) * 2; // Add 1 for null terminator + buff.BufferType = Interop.BCrypt.CngBufferDescriptors.NCRYPTBUFFER_ECC_CURVE_NAME; + buff.pvBuffer = safeCurveName.DangerousGetHandle(); + Marshal.StructureToPtr(buff, buffPtr, false); + + desc.cBuffers = 1; + desc.pBuffers = buffPtr; + desc.ulVersion = Interop.BCrypt.BCRYPTBUFFER_VERSION; + Marshal.StructureToPtr(desc, descPtr, false); + + errorCode = Interop.NCrypt.NCryptImportKey( + provider, + IntPtr.Zero, + blobType, + descPtr, + out keyHandle, + ref MemoryMarshal.GetReference(keyBlob), + keyBlob.Length, + 0); + } + finally + { + Marshal.FreeHGlobal(descPtr); + Marshal.FreeHGlobal(buffPtr); + } + } + + if (errorCode != ErrorCode.ERROR_SUCCESS) + { + Exception e = errorCode.ToCryptographicException(); + keyHandle.Dispose(); + if (errorCode == ErrorCode.NTE_INVALID_PARAMETER) + { + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CurveNotSupported, curveName), e); + } + throw e; + } + + return keyHandle; + } + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECCng.ImportExport.cs b/src/libraries/Common/src/System/Security/Cryptography/ECCng.ImportExport.cs index d7c9c8a1a56a1b..f31194296c8852 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/ECCng.ImportExport.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/ECCng.ImportExport.cs @@ -2,13 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using System.Runtime.InteropServices; -using Internal.Cryptography; -using Microsoft.Win32.SafeHandles; using static Internal.NativeCrypto.BCryptNative; using BCRYPT_ECC_PARAMETER_HEADER = Interop.BCrypt.BCRYPT_ECC_PARAMETER_HEADER; using BCRYPT_ECCFULLKEY_BLOB = Interop.BCrypt.BCRYPT_ECCFULLKEY_BLOB; -using BCRYPT_ECCKEY_BLOB = Interop.BCrypt.BCRYPT_ECCKEY_BLOB; using ErrorCode = Interop.NCrypt.ErrorCode; using KeyBlobMagicNumber = Interop.BCrypt.KeyBlobMagicNumber; @@ -20,49 +16,19 @@ internal static byte[] GetNamedCurveBlob(ref ECParameters parameters, bool ecdh) { Debug.Assert(parameters.Curve.IsNamed); - bool includePrivateParameters = (parameters.D != null); - byte[] blob; - unsafe - { - // We need to build a key blob structured as follows: - // BCRYPT_ECCKEY_BLOB header - // byte[cbKey] Q.X - // byte[cbKey] Q.Y - // -- Only if "includePrivateParameters" is true -- - // byte[cbKey] D + bool includePrivateParameters = parameters.D is not null; - int blobSize = sizeof(BCRYPT_ECCKEY_BLOB) + - parameters.Q.X!.Length + - parameters.Q.Y!.Length; - if (includePrivateParameters) - { - blobSize += parameters.D!.Length; - } + KeyBlobMagicNumber magic = ecdh ? + EcdhCurveNameToMagicNumber(parameters.Curve.Oid.FriendlyName, includePrivateParameters) : + EcdsaCurveNameToMagicNumber(parameters.Curve.Oid.FriendlyName, includePrivateParameters); - blob = new byte[blobSize]; - fixed (byte* pBlob = &blob[0]) - { - // Build the header - BCRYPT_ECCKEY_BLOB* pBcryptBlob = (BCRYPT_ECCKEY_BLOB*)pBlob; - pBcryptBlob->Magic = ecdh ? - EcdhCurveNameToMagicNumber(parameters.Curve.Oid.FriendlyName, includePrivateParameters) : - EcdsaCurveNameToMagicNumber(parameters.Curve.Oid.FriendlyName, includePrivateParameters); - pBcryptBlob->cbKey = parameters.Q.X.Length; - - // Emit the blob - int offset = sizeof(BCRYPT_ECCKEY_BLOB); - Interop.BCrypt.Emit(blob, ref offset, parameters.Q.X); - Interop.BCrypt.Emit(blob, ref offset, parameters.Q.Y); - if (includePrivateParameters) - { - Interop.BCrypt.Emit(blob, ref offset, parameters.D!); - } - - // We better have computed the right allocation size above! - Debug.Assert(offset == blobSize); - } - } - return blob; + return EncodeEccKeyBlob( + magic, + parameters.Q.X!, + parameters.Q.Y!, + parameters.D, + static blob => blob, + clearBlob: false); // Returning blob to caller, so don't clear it. } internal static byte[] GetPrimeCurveBlob(ref ECParameters parameters, bool ecdh) @@ -152,42 +118,43 @@ internal static byte[] GetPrimeCurveBlob(ref ECParameters parameters, bool ecdh) internal static void ExportNamedCurveParameters(ref ECParameters ecParams, byte[] ecBlob, bool includePrivateParameters) { - // We now have a buffer laid out as follows: - // BCRYPT_ECCKEY_BLOB header - // byte[cbKey] Q.X - // byte[cbKey] Q.Y - // -- Private only -- - // byte[cbKey] D - - KeyBlobMagicNumber magic = (KeyBlobMagicNumber)BitConverter.ToInt32(ecBlob, 0); - - // Check the magic value in the key blob header. If the blob does not have the required magic, - // then throw a CryptographicException. - CheckMagicValueOfKey(magic, includePrivateParameters); - - unsafe + if (includePrivateParameters) { - // Fail-fast if a rogue provider gave us a blob that isn't even the size of the blob header. - if (ecBlob.Length < sizeof(BCRYPT_ECCKEY_BLOB)) - throw ErrorCode.E_FAIL.ToCryptographicException(); - - fixed (byte* pEcBlob = &ecBlob[0]) - { - BCRYPT_ECCKEY_BLOB* pBcryptBlob = (BCRYPT_ECCKEY_BLOB*)pEcBlob; - - int offset = sizeof(BCRYPT_ECCKEY_BLOB); - - ecParams.Q = new ECPoint + ecParams = DecodeEccKeyBlob( + ecBlob, + static (KeyBlobMagicNumber magic, byte[] x, byte[] y, byte[]? d) => { - X = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbKey), - Y = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbKey) - }; - - if (includePrivateParameters) + CheckMagicValueOfKey(magic, includePrivateParameters: true); + + return new ECParameters + { + Q = new ECPoint + { + X = x, + Y = y, + }, + D = d, + }; + }, + clearPrivateKey: false); // Returning key to caller, so don't clear it. + } + else + { + ecParams = DecodeEccKeyBlob( + ecBlob, + static (KeyBlobMagicNumber magic, byte[] x, byte[] y, byte[]? d) => { - ecParams.D = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbKey); - } - } + CheckMagicValueOfKey(magic, includePrivateParameters: false); + + return new ECParameters + { + Q = new ECPoint + { + X = x, + Y = y, + }, + }; + }); } } @@ -451,66 +418,5 @@ private static ECCurve.ECCurveType ConvertToCurveTypeEnum(Interop.BCrypt.ECC_CUR curveType == ECCurve.ECCurveType.PrimeTwistedEdwards); return curveType; } - - internal static SafeNCryptKeyHandle ImportKeyBlob( - string blobType, - ReadOnlySpan keyBlob, - string curveName, - SafeNCryptProviderHandle provider) - { - ErrorCode errorCode; - SafeNCryptKeyHandle keyHandle; - - using (SafeUnicodeStringHandle safeCurveName = new SafeUnicodeStringHandle(curveName)) - { - Interop.BCrypt.BCryptBufferDesc desc = default; - Interop.BCrypt.BCryptBuffer buff = default; - - IntPtr descPtr = IntPtr.Zero; - IntPtr buffPtr = IntPtr.Zero; - try - { - descPtr = Marshal.AllocHGlobal(Marshal.SizeOf(desc)); - buffPtr = Marshal.AllocHGlobal(Marshal.SizeOf(buff)); - buff.cbBuffer = (curveName.Length + 1) * 2; // Add 1 for null terminator - buff.BufferType = Interop.BCrypt.CngBufferDescriptors.NCRYPTBUFFER_ECC_CURVE_NAME; - buff.pvBuffer = safeCurveName.DangerousGetHandle(); - Marshal.StructureToPtr(buff, buffPtr, false); - - desc.cBuffers = 1; - desc.pBuffers = buffPtr; - desc.ulVersion = Interop.BCrypt.BCRYPTBUFFER_VERSION; - Marshal.StructureToPtr(desc, descPtr, false); - - errorCode = Interop.NCrypt.NCryptImportKey( - provider, - IntPtr.Zero, - blobType, - descPtr, - out keyHandle, - ref MemoryMarshal.GetReference(keyBlob), - keyBlob.Length, - 0); - } - finally - { - Marshal.FreeHGlobal(descPtr); - Marshal.FreeHGlobal(buffPtr); - } - } - - if (errorCode != ErrorCode.ERROR_SUCCESS) - { - Exception e = errorCode.ToCryptographicException(); - keyHandle.Dispose(); - if (errorCode == ErrorCode.NTE_INVALID_PARAMETER) - { - throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CurveNotSupported, curveName), e); - } - throw e; - } - - return keyHandle; - } } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/EccKeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/EccKeyFormatHelper.cs index 1b5059af55b09d..72df332a19fade 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/EccKeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/EccKeyFormatHelper.cs @@ -1,798 +1,39 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Buffers; -using System.Collections; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Formats.Asn1; -using System.Runtime.InteropServices; -using System.Security.Cryptography.Asn1; namespace System.Security.Cryptography { - internal static class EccKeyFormatHelper + internal static partial class EccKeyFormatHelper { - // This is the same limit that OpenSSL 1.0.2-1.1.1 has, - // there's no real point reading anything bigger than this (for now). - private const int MaxFieldBitSize = 661; - - private static readonly string[] s_validOids = - { - Oids.EcPublicKey, - }; - - internal static void ReadSubjectPublicKeyInfo( - ReadOnlySpan source, - out int bytesRead, - out ECParameters key) - { - KeyFormatHelper.ReadSubjectPublicKeyInfo( - s_validOids, - source, - FromECPublicKey, - out bytesRead, - out key); - } - - internal static ReadOnlyMemory ReadSubjectPublicKeyInfo( - ReadOnlyMemory source, - out int bytesRead) - { - return KeyFormatHelper.ReadSubjectPublicKeyInfo( - s_validOids, - source, - out bytesRead); - } - - internal static void ReadEncryptedPkcs8( - ReadOnlySpan source, - ReadOnlySpan password, - out int bytesRead, - out ECParameters key) - { - KeyFormatHelper.ReadEncryptedPkcs8( - s_validOids, - source, - password, - FromECPrivateKey, - out bytesRead, - out key); - } - - internal static void ReadEncryptedPkcs8( - ReadOnlySpan source, - ReadOnlySpan passwordBytes, - out int bytesRead, - out ECParameters key) - { - KeyFormatHelper.ReadEncryptedPkcs8( - s_validOids, - source, - passwordBytes, - FromECPrivateKey, - out bytesRead, - out key); - } - - internal static unsafe ECParameters FromECPrivateKey(ReadOnlySpan key, out int bytesRead) - { - try - { - AsnDecoder.ReadEncodedValue( - key, - AsnEncodingRules.BER, - out _, - out _, - out int firstValueLength); - - fixed (byte* ptr = &MemoryMarshal.GetReference(key)) - { - using (MemoryManager manager = new PointerMemoryManager(ptr, firstValueLength)) - { - AlgorithmIdentifierAsn algId = default; - FromECPrivateKey(manager.Memory, algId, out ECParameters ret); - bytesRead = firstValueLength; - return ret; - } - } - } - catch (AsnContentException e) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); - } - } - - internal static void FromECPrivateKey( - ReadOnlyMemory keyData, - in AlgorithmIdentifierAsn algId, - out ECParameters ret) - { - ECPrivateKey key = ECPrivateKey.Decode(keyData, AsnEncodingRules.BER); - FromECPrivateKey(key, algId, out ret); - } - - internal static void FromECPrivateKey( - ECPrivateKey key, - in AlgorithmIdentifierAsn algId, - out ECParameters ret) - { - ValidateParameters(key.Parameters, algId); - - if (key.Version != 1) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - byte[]? x = null; - byte[]? y = null; - - if (key.PublicKey != null) - { - ReadOnlySpan publicKeyBytes = key.PublicKey.Value.Span; - - if (publicKeyBytes.Length == 0) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - // Implementation limitation - // 04 (Uncompressed ECPoint) is almost always used. - if (publicKeyBytes[0] != 0x04) - { - throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); - } - - // https://www.secg.org/sec1-v2.pdf, 2.3.4, #3 (M has length 2 * CEIL(log2(q)/8) + 1) - if (publicKeyBytes.Length != 2 * key.PrivateKey.Length + 1) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - x = publicKeyBytes.Slice(1, key.PrivateKey.Length).ToArray(); - y = publicKeyBytes.Slice(1 + key.PrivateKey.Length).ToArray(); - } - - ECDomainParameters domainParameters; - - if (key.Parameters != null) - { - domainParameters = key.Parameters.Value; - } - else - { - domainParameters = ECDomainParameters.Decode(algId.Parameters!.Value, AsnEncodingRules.DER); - } - - Debug.Assert((x == null) == (y == null)); - - ret = new ECParameters - { - Curve = GetCurve(domainParameters), - Q = - { - X = x, - Y = y, - }, - D = key.PrivateKey.ToArray(), - }; - - ret.Validate(); - } - - internal static void FromECPublicKey( - ReadOnlyMemory key, - in AlgorithmIdentifierAsn algId, - out ECParameters ret) + internal static void GetECPointFromUncompressedPublicKey(ReadOnlySpan publicKey, int fieldWidthInBytes, out byte[] x, out byte[] y) { - if (algId.Parameters == null) + if (publicKey.Length == 0) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } - ReadOnlySpan publicKeyBytes = key.Span; - - if (publicKeyBytes.Length == 0) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - // Implementation limitation. + // Implementation limitation // 04 (Uncompressed ECPoint) is almost always used. - if (publicKeyBytes[0] != 0x04) + if (publicKey[0] != 0x04) { throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); } // https://www.secg.org/sec1-v2.pdf, 2.3.4, #3 (M has length 2 * CEIL(log2(q)/8) + 1) - if ((publicKeyBytes.Length & 0x01) != 1) + if (publicKey.Length != 2 * fieldWidthInBytes + 1) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } - int fieldWidth = publicKeyBytes.Length / 2; - - ECDomainParameters domainParameters = ECDomainParameters.Decode( - algId.Parameters.Value, - AsnEncodingRules.DER); - - ret = new ECParameters - { - Curve = GetCurve(domainParameters), - Q = - { - X = publicKeyBytes.Slice(1, fieldWidth).ToArray(), - Y = publicKeyBytes.Slice(1 + fieldWidth).ToArray(), - }, - }; - - ret.Validate(); - } - - private static void ValidateParameters(ECDomainParameters? keyParameters, in AlgorithmIdentifierAsn algId) - { - // At least one is required - if (keyParameters == null && algId.Parameters == null) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - // If they are both specified they must match. - if (keyParameters != null && algId.Parameters != null) - { - ReadOnlySpan algIdParameters = algId.Parameters.Value.Span; - - // X.509 SubjectPublicKeyInfo specifies DER encoding. - // RFC 5915 specifies DER encoding for EC Private Keys. - // So we can compare as DER. - AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - keyParameters.Value.Encode(writer); - - if (!writer.EncodedValueEquals(algIdParameters)) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - } - } - - private static ECCurve GetCurve(ECDomainParameters domainParameters) - { - if (domainParameters.Specified.HasValue) - { - return GetSpecifiedECCurve(domainParameters.Specified.Value); - } - - if (domainParameters.Named == null) - { - throw new CryptographicException(SR.Cryptography_ECC_NamedCurvesOnly); - } - - Oid curveOid = domainParameters.Named switch { - Oids.secp256r1 => Oids.secp256r1Oid, - Oids.secp384r1 => Oids.secp384r1Oid, - Oids.secp521r1 => Oids.secp521r1Oid, - _ => new Oid(domainParameters.Named, null) - }; - - return ECCurve.CreateFromOid(curveOid); - } - - private static ECCurve GetSpecifiedECCurve(SpecifiedECDomain specifiedParameters) - { - try - { - return GetSpecifiedECCurveCore(specifiedParameters); - } - catch (AsnContentException e) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); - } - } - - private static ECCurve GetSpecifiedECCurveCore(SpecifiedECDomain specifiedParameters) - { - // sec1-v2 C.3: - // - // Versions 1, 2, and 3 are defined. - // 1 is just data, 2 and 3 mean that a seed is required (with different reasons for why, - // but they're human-reasons, not technical ones). - if (specifiedParameters.Version < 1 || specifiedParameters.Version > 3) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - if (specifiedParameters.Version > 1 && !specifiedParameters.Curve.Seed.HasValue) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - byte[] primeOrPoly; - bool prime; - - switch (specifiedParameters.FieldID.FieldType) - { - case Oids.EcPrimeField: - prime = true; - AsnReader primeReader = new AsnReader(specifiedParameters.FieldID.Parameters, AsnEncodingRules.BER); - ReadOnlySpan primeValue = primeReader.ReadIntegerBytes().Span; - primeReader.ThrowIfNotEmpty(); - - if (primeValue[0] == 0) - { - primeValue = primeValue.Slice(1); - } - - if (primeValue.Length > (MaxFieldBitSize / 8)) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - primeOrPoly = primeValue.ToArray(); - break; - case Oids.EcChar2Field: - prime = false; - AsnReader char2Reader = new AsnReader(specifiedParameters.FieldID.Parameters, AsnEncodingRules.BER); - AsnReader innerReader = char2Reader.ReadSequence(); - char2Reader.ThrowIfNotEmpty(); - - // Characteristic-two ::= SEQUENCE - // { - // m INTEGER, -- Field size - // basis CHARACTERISTIC-TWO.&id({BasisTypes}), - // parameters CHARACTERISTIC-TWO.&Type({BasisTypes}{@basis}) - // } - - if (!innerReader.TryReadInt32(out int m) || m > MaxFieldBitSize || m < 0) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - int k1; - int k2 = -1; - int k3 = -1; - - switch (innerReader.ReadObjectIdentifier()) - { - case Oids.EcChar2TrinomialBasis: - // Trinomial ::= INTEGER - if (!innerReader.TryReadInt32(out k1) || k1 >= m || k1 < 1) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - break; - case Oids.EcChar2PentanomialBasis: - // Pentanomial ::= SEQUENCE - // { - // k1 INTEGER, -- k1 > 0 - // k2 INTEGER, -- k2 > k1 - // k3 INTEGER -- k3 > k2 - // } - AsnReader pentanomialReader = innerReader.ReadSequence(); - - if (!pentanomialReader.TryReadInt32(out k1) || - !pentanomialReader.TryReadInt32(out k2) || - !pentanomialReader.TryReadInt32(out k3) || - k1 < 1 || - k2 <= k1 || - k3 <= k2 || - k3 >= m) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - pentanomialReader.ThrowIfNotEmpty(); - - break; - default: - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - innerReader.ThrowIfNotEmpty(); - - BitArray poly = new BitArray(m + 1); - poly.Set(m, true); - poly.Set(k1, true); - poly.Set(0, true); - - if (k2 > 0) - { - poly.Set(k2, true); - poly.Set(k3, true); - } - - primeOrPoly = new byte[(m + 7) / 8]; - poly.CopyTo(primeOrPoly, 0); - Array.Reverse(primeOrPoly); - break; - default: - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - ECCurve curve; - - if (prime) - { - curve = new ECCurve - { - CurveType = ECCurve.ECCurveType.PrimeShortWeierstrass, - Prime = primeOrPoly, - }; - } - else - { - curve = new ECCurve - { - CurveType = ECCurve.ECCurveType.Characteristic2, - Polynomial = primeOrPoly, - }; - } - - curve.A = specifiedParameters.Curve.A.ToUnsignedIntegerBytes(primeOrPoly.Length); - curve.B = specifiedParameters.Curve.B.ToUnsignedIntegerBytes(primeOrPoly.Length); - curve.Order = specifiedParameters.Order.ToUnsignedIntegerBytes(primeOrPoly.Length); - - ReadOnlySpan baseSpan = specifiedParameters.Base.Span; - - // We only understand the uncompressed point encoding, but that's almost always what's used. - if (baseSpan[0] != 0x04 || baseSpan.Length != 2 * primeOrPoly.Length + 1) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - curve.G.X = baseSpan.Slice(1, primeOrPoly.Length).ToArray(); - curve.G.Y = baseSpan.Slice(1 + primeOrPoly.Length).ToArray(); - - if (specifiedParameters.Cofactor.HasValue) - { - curve.Cofactor = specifiedParameters.Cofactor.Value.ToUnsignedIntegerBytes(); - } - - return curve; - } - - internal static AsnWriter WriteSubjectPublicKeyInfo(ECParameters ecParameters) - { - ecParameters.Validate(); - - // Since the public key format for EC keys is not ASN.1, - // write the SPKI structure manually. - - AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - - // SubjectPublicKeyInfo - writer.PushSequence(); - - // algorithm - WriteAlgorithmIdentifier(ecParameters, writer); - - // subjectPublicKey - WriteUncompressedPublicKey(ecParameters, writer); - - writer.PopSequence(); - return writer; - } - - private static AsnWriter WriteAlgorithmIdentifier(in ECParameters ecParameters) - { - AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - WriteAlgorithmIdentifier(ecParameters, writer); - return writer; - } - - private static void WriteAlgorithmIdentifier(in ECParameters ecParameters, AsnWriter writer) - { - writer.PushSequence(); - - writer.WriteObjectIdentifier(Oids.EcPublicKey); - WriteEcParameters(ecParameters, writer); - - writer.PopSequence(); - } - - internal static AsnWriter WritePkcs8PrivateKey(ECParameters ecParameters, AttributeAsn[]? attributes = null) - { - ecParameters.Validate(); - - if (ecParameters.D == null) - { - throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey); - } - - // Don't need the domain parameters because they're contained in the algId. - AsnWriter ecPrivateKey = WriteEcPrivateKey(ecParameters, includeDomainParameters: false); - AsnWriter algorithmIdentifier = WriteAlgorithmIdentifier(ecParameters); - AsnWriter? attributeWriter = WritePrivateKeyInfoAttributes(attributes); - - return KeyFormatHelper.WritePkcs8(algorithmIdentifier, ecPrivateKey, attributeWriter); - } - - [return: NotNullIfNotNull(nameof(attributes))] - private static AsnWriter? WritePrivateKeyInfoAttributes(AttributeAsn[]? attributes) - { - if (attributes == null) - return null; - - AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - Asn1Tag tag = new Asn1Tag(TagClass.ContextSpecific, 0); - writer.PushSetOf(tag); - - for (int i = 0; i < attributes.Length; i++) - { - attributes[i].Encode(writer); - } - - writer.PopSetOf(tag); - return writer; - } - - private static void WriteEcParameters(ECParameters ecParameters, AsnWriter writer) - { - if (ecParameters.Curve.IsNamed) - { - Oid oid = ecParameters.Curve.Oid; - - // On Windows the FriendlyName is populated in places where the Value mightn't be. - if (string.IsNullOrEmpty(oid.Value)) - { - Debug.Assert(oid.FriendlyName != null); - oid = Oid.FromFriendlyName(oid.FriendlyName, OidGroup.All); - } - - writer.WriteObjectIdentifier(oid.Value!); - } - else if (ecParameters.Curve.IsExplicit) - { - Debug.Assert(ecParameters.Curve.IsPrime || ecParameters.Curve.IsCharacteristic2); - WriteSpecifiedECDomain(ecParameters, writer); - } - else - { - throw new CryptographicException( - SR.Format(SR.Cryptography_CurveNotSupported, ecParameters.Curve.CurveType.ToString())); - } - } - - private static void WriteSpecifiedECDomain(ECParameters ecParameters, AsnWriter writer) - { - int m; - int k1; - int k2; - int k3; - m = k1 = k2 = k3 = -1; - - if (ecParameters.Curve.IsCharacteristic2) - { - DetermineChar2Parameters(ecParameters, ref m, ref k1, ref k2, ref k3); - } - - // SpecifiedECDomain - writer.PushSequence(); - { - // version - // We don't know if the seed (if present) is verifiably random (2). - // We also don't know if the base point is verifiably random (3). - // So just be version 1. - writer.WriteInteger(1); - - // fieldId - writer.PushSequence(); - { - if (ecParameters.Curve.IsPrime) - { - writer.WriteObjectIdentifier(Oids.EcPrimeField); - writer.WriteIntegerUnsigned(ecParameters.Curve.Prime); - } - else - { - Debug.Assert(ecParameters.Curve.IsCharacteristic2); - - // id - writer.WriteObjectIdentifier(Oids.EcChar2Field); - - // Parameters (Characteristic-two) - writer.PushSequence(); - { - // m - writer.WriteInteger(m); - - if (k3 > 0) - { - writer.WriteObjectIdentifier(Oids.EcChar2PentanomialBasis); - - writer.PushSequence(); - { - writer.WriteInteger(k1); - writer.WriteInteger(k2); - writer.WriteInteger(k3); - - writer.PopSequence(); - } - } - else - { - Debug.Assert(k2 < 0); - Debug.Assert(k1 > 0); - - writer.WriteObjectIdentifier(Oids.EcChar2TrinomialBasis); - writer.WriteInteger(k1); - } - - writer.PopSequence(); - } - } - - writer.PopSequence(); - } - - // curve - WriteCurve(ecParameters.Curve, writer); - - // base - WriteUncompressedBasePoint(ecParameters, writer); - - // order - writer.WriteIntegerUnsigned(ecParameters.Curve.Order); - - // cofactor - if (ecParameters.Curve.Cofactor != null) - { - writer.WriteIntegerUnsigned(ecParameters.Curve.Cofactor); - } - - // hash is omitted. - - writer.PopSequence(); - } + x = publicKey.Slice(1, fieldWidthInBytes).ToArray(); + y = publicKey.Slice(1 + fieldWidthInBytes).ToArray(); } - private static void DetermineChar2Parameters( - in ECParameters ecParameters, - ref int m, - ref int k1, - ref int k2, - ref int k3) + internal static void WriteUncompressedPublicKey(byte[] x, byte[] y, AsnWriter writer) { - byte[] polynomial = ecParameters.Curve.Polynomial!; - int lastIndex = polynomial.Length - 1; - - // The most significant byte needs a set bit, and the least significant bit must be set. - if (polynomial[0] == 0 || (polynomial[lastIndex] & 1) != 1) - { - throw new CryptographicException(SR.Cryptography_InvalidECCharacteristic2Curve); - } - - for (int localBitIndex = 7; localBitIndex >= 0; localBitIndex--) - { - int test = 1 << localBitIndex; - - if ((polynomial[0] & test) == test) - { - m = checked(8 * lastIndex + localBitIndex); - } - } - - // Find the other set bits. Since we've already found m and 0, there is either - // one remaining (trinomial) or 3 (pentanomial). - for (int inverseIndex = 0; inverseIndex < polynomial.Length; inverseIndex++) - { - int forwardIndex = lastIndex - inverseIndex; - byte val = polynomial[forwardIndex]; - - for (int localBitIndex = 0; localBitIndex < 8; localBitIndex++) - { - int test = 1 << localBitIndex; - - if ((val & test) == test) - { - int bitIndex = 8 * inverseIndex + localBitIndex; - - if (bitIndex == 0) - { - // The bottom bit is always set, it's not considered a parameter. - } - else if (bitIndex == m) - { - break; - } - else if (k1 < 0) - { - k1 = bitIndex; - } - else if (k2 < 0) - { - k2 = bitIndex; - } - else if (k3 < 0) - { - k3 = bitIndex; - } - else - { - // More than pentanomial. - throw new CryptographicException(SR.Cryptography_InvalidECCharacteristic2Curve); - } - } - } - } - - if (k3 > 0) - { - // Pentanomial - } - else if (k2 > 0) - { - // There is no quatranomial - throw new CryptographicException(SR.Cryptography_InvalidECCharacteristic2Curve); - } - else if (k1 > 0) - { - // Trinomial - } - else - { - // No smaller bases exist - throw new CryptographicException(SR.Cryptography_InvalidECCharacteristic2Curve); - } - } - - private static void WriteCurve(in ECCurve curve, AsnWriter writer) - { - writer.PushSequence(); - WriteFieldElement(curve.A!, writer); - WriteFieldElement(curve.B!, writer); - - if (curve.Seed != null) - { - writer.WriteBitString(curve.Seed); - } - - writer.PopSequence(); - } - - private static void WriteFieldElement(byte[] fieldElement, AsnWriter writer) - { - int start = 0; - - while (start < fieldElement.Length - 1 && fieldElement[start] == 0) - { - start++; - } - - writer.WriteOctetString(fieldElement.AsSpan(start)); - } - - private static void WriteUncompressedBasePoint(in ECParameters ecParameters, AsnWriter writer) - { - int basePointLength = ecParameters.Curve.G.X!.Length * 2 + 1; - - // A NIST P-521 G will be at most 133 bytes (NIST 186-4 defines G.) - // 256 should be plenty for all but very atypical uses. - const int MaxStackAllocSize = 256; - Span basePointBytes = stackalloc byte[MaxStackAllocSize]; - byte[]? rented = null; - - if (basePointLength > MaxStackAllocSize) - { - basePointBytes = rented = CryptoPool.Rent(basePointLength); - } - - basePointBytes[0] = 0x04; - ecParameters.Curve.G.X.CopyTo(basePointBytes.Slice(1)); - ecParameters.Curve.G.Y.CopyTo(basePointBytes.Slice(1 + ecParameters.Curve.G.X.Length)); - - writer.WriteOctetString(basePointBytes.Slice(0, basePointLength)); - - if (rented is not null) - { - // G contains public EC parameters that are not sensitive. - CryptoPool.Return(rented, clearSize: 0); - } - } - - private static void WriteUncompressedPublicKey(in ECParameters ecParameters, AsnWriter writer) - { - int publicKeyLength = ecParameters.Q.X!.Length * 2 + 1; + int publicKeyLength = x.Length * 2 + 1; // A NIST P-521 Q will encode to 133 bytes: (521 + 7)/8 * 2 + 1. // 256 should be plenty for all but very atypical uses. @@ -806,8 +47,8 @@ private static void WriteUncompressedPublicKey(in ECParameters ecParameters, Asn } publicKeyBytes[0] = 0x04; - ecParameters.Q.X.CopyTo(publicKeyBytes.Slice(1)); - ecParameters.Q.Y.CopyTo(publicKeyBytes.Slice(1 + ecParameters.Q.X!.Length)); + x.CopyTo(publicKeyBytes.Slice(1)); + y.CopyTo(publicKeyBytes.Slice(1 + x.Length)); writer.WriteBitString(publicKeyBytes.Slice(0, publicKeyLength)); @@ -817,50 +58,5 @@ private static void WriteUncompressedPublicKey(in ECParameters ecParameters, Asn CryptoPool.Return(rented, clearSize: 0); } } - - internal static AsnWriter WriteECPrivateKey(in ECParameters ecParameters) - { - return WriteEcPrivateKey(ecParameters, includeDomainParameters: true); - } - - private static AsnWriter WriteEcPrivateKey(in ECParameters ecParameters, bool includeDomainParameters) - { - AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - - // ECPrivateKey - writer.PushSequence(); - - // version 1 - writer.WriteInteger(1); - - // privateKey - writer.WriteOctetString(ecParameters.D); - - // domainParameters - if (includeDomainParameters) - { - Asn1Tag explicit0 = new Asn1Tag(TagClass.ContextSpecific, 0, isConstructed: true); - writer.PushSequence(explicit0); - - WriteEcParameters(ecParameters, writer); - - writer.PopSequence(explicit0); - } - - // publicKey - if (ecParameters.Q.X != null) - { - Debug.Assert(ecParameters.Q.Y != null); - Asn1Tag explicit1 = new Asn1Tag(TagClass.ContextSpecific, 1, isConstructed: true); - writer.PushSequence(explicit1); - - WriteUncompressedPublicKey(ecParameters, writer); - - writer.PopSequence(explicit1); - } - - writer.PopSequence(); - return writer; - } } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs b/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs index e656d8411de491..e6b8ec6b91fb46 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs @@ -53,6 +53,14 @@ internal static partial class Helpers true; #endif + [SupportedOSPlatformGuard("windows")] + internal static bool IsOSPlatformWindows => +#if NETFRAMEWORK + true; +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows); +#endif + [return: NotNullIfNotNull(nameof(src))] public static byte[]? CloneByteArray(this byte[]? src) { @@ -100,20 +108,65 @@ internal static bool TryCopyToDestination(this ReadOnlySpan source, Span hashOid) { - // This file is compiled in netstandard2.0, can't use the HashSizeInBytes consts. return hashOid switch { - Oids.Sha256 => 256 >> 3, - Oids.Sha384 => 384 >> 3, - Oids.Sha512 => 512 >> 3, - Oids.Sha1 => 160 >> 3, - Oids.Md5 => 128 >> 3, - _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashOid)), + Oids.Md5 => 128 / 8, + Oids.Sha1 => 160 / 8, + Oids.Sha256 => 256 / 8, + Oids.Sha384 => 384 / 8, + Oids.Sha512 => 512 / 8, + Oids.Sha3_256 => 256 / 8, + Oids.Sha3_384 => 384 / 8, + Oids.Sha3_512 => 512 / 8, + Oids.Shake128 => 256 / 8, + Oids.Shake256 => 512 / 8, + _ => null, }; } + internal static int HashOidToByteLength(string hashOid) + { + return TryGetHashOidToByteLength(hashOid) ?? + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashOid)); + } + +#if !BUILDING_PKCS + /// + /// Validates if the hash length matches the expected output size for the given hash algorithm OID. + /// When the OID is not one of the common hash algorithms, it only validates the format of the OID. + /// + internal static void ValidateHashLength(ReadOnlySpan hash, ReadOnlySpan hashAlgorithmOid) + { + int? outputSize = TryGetHashOidToByteLength(hashAlgorithmOid); + + if (outputSize is not null) + { + if (hash.Length != outputSize) + { + throw new CryptographicException(SR.Cryptography_HashLengthMismatch); + } + } + else + { + // The OIDs for the algorithms above have max length 11. We'll just round up for a conservative initial estimate. + const int MaxEncodedOidLengthForCommonHashAlgorithms = 16; + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER, MaxEncodedOidLengthForCommonHashAlgorithms); + + try + { + // Only the format of the OID is validated here. The derived classes can decide to do more if they want to. + writer.WriteObjectIdentifier(hashAlgorithmOid); + } + catch (ArgumentException ae) + { + throw new CryptographicException(SR.Cryptography_HashLengthMismatch, ae); + } + } + } +#endif + internal static bool HashAlgorithmRequired(string? keyAlgorithm) { // This list could either be written as "ML-DSA and friends return false", @@ -211,5 +264,18 @@ internal static void ThrowIfAsnInvalidLength(ReadOnlySpan data) throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } } + +#if !BUILDING_PKCS + internal static void ThrowIfDestinationWrongLength( + Span destination, + int expectedLength, + [System.Runtime.CompilerServices.CallerArgumentExpression(nameof(destination))] string? paramName = null) + { + if (destination.Length != expectedLength) + { + throw new ArgumentException(SR.Format(SR.Argument_DestinationImprecise, expectedLength), paramName); + } + } +#endif } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs b/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs index 40d07a69e24999..d2570a9173dc19 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs @@ -3,67 +3,47 @@ using System.Diagnostics; using System.Formats.Asn1; -using System.Numerics; namespace System.Security.Cryptography { - internal static class KeyBlobHelpers + internal static partial class KeyBlobHelpers { - internal static byte[] ToUnsignedIntegerBytes(this ReadOnlyMemory memory, int length) + internal static byte[] ToUnsignedIntegerBytes(this ReadOnlyMemory memory) { - if (memory.Length == length) - { - return memory.ToArray(); - } - - ReadOnlySpan span = memory.Span; - - if (memory.Length == length + 1) + if (memory.Length > 1 && memory.Span[0] == 0) { - if (span[0] == 0) - { - return span.Slice(1).ToArray(); - } + return memory.Slice(1).ToArray(); } - if (span.Length > length) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - byte[] target = new byte[length]; - span.CopyTo(target.AsSpan(length - span.Length)); - return target; + return memory.ToArray(); } - internal static byte[] ToUnsignedIntegerBytes(this ReadOnlyMemory memory) + internal static void ToUnsignedIntegerBytes(this ReadOnlyMemory memory, Span destination) { - ReadOnlySpan span = memory.Span; + int length = destination.Length; - if (span.Length > 1 && span[0] == 0) + if (memory.Length == length) { - return span.Slice(1).ToArray(); + memory.Span.CopyTo(destination); + return; } - return span.ToArray(); - } - - internal static byte[] ExportKeyParameter(this BigInteger value, int length) - { - byte[] target = new byte[length]; - - if (value.TryWriteBytes(target, out int bytesWritten, isUnsigned: true, isBigEndian: true)) + if (memory.Length == length + 1) { - if (bytesWritten < length) + if (memory.Span[0] == 0) { - Buffer.BlockCopy(target, 0, target, length - bytesWritten, bytesWritten); - target.AsSpan(0, length - bytesWritten).Clear(); + memory.Span.Slice(1).CopyTo(destination); + return; } + } - return target; + if (memory.Length > length) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } - throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); + destination.Slice(0, destination.Length - memory.Length).Clear(); + memory.Span.CopyTo(destination.Slice(length - memory.Length)); } internal static void WriteKeyParameterInteger(this AsnWriter writer, ReadOnlySpan integer) diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs index e6f6f0bbdab0ea..662addf92386e8 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs @@ -14,10 +14,15 @@ namespace System.Security.Cryptography /// Represents an ML-DSA key. /// /// - /// Developers are encouraged to program against the base class, - /// rather than any specific derived class. - /// The derived classes are intended for interop with the underlying system - /// cryptographic libraries. + /// + /// This algorithm is specified by FIPS-204. + /// + /// + /// Developers are encouraged to program against the base class, + /// rather than any specific derived class. + /// The derived classes are intended for interop with the underlying system + /// cryptographic libraries. + /// /// [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public abstract partial class MLDsa : IDisposable @@ -39,6 +44,9 @@ public abstract partial class MLDsa : IDisposable /// /// Gets the specific ML-DSA algorithm for this key. /// + /// + /// The specific ML-DSA algorithm for this key. + /// public MLDsaAlgorithm Algorithm { get; } private bool _disposed; @@ -48,6 +56,9 @@ public abstract partial class MLDsa : IDisposable /// /// The specific ML-DSA algorithm for this key. /// + /// + /// is . + /// protected MLDsa(MLDsaAlgorithm algorithm) { ArgumentNullException.ThrowIfNull(algorithm); @@ -79,7 +90,7 @@ public void Dispose() } /// - /// Sign the specified data, writing the signature into the provided buffer. + /// Signs the specified data, writing the signature into the provided buffer. /// /// /// The data to sign. @@ -109,14 +120,7 @@ public void Dispose() /// public void SignData(ReadOnlySpan data, Span destination, ReadOnlySpan context = default) { - int signatureSizeInBytes = Algorithm.SignatureSizeInBytes; - - if (destination.Length != signatureSizeInBytes) - { - throw new ArgumentException( - SR.Format(SR.Argument_DestinationImprecise, signatureSizeInBytes), - nameof(destination)); - } + Helpers.ThrowIfDestinationWrongLength(destination, Algorithm.SignatureSizeInBytes); if (context.Length > MaxContextLength) { @@ -169,8 +173,6 @@ public byte[] SignData(byte[] data, byte[]? context = default) return destination; } - // TODO: SignPreHash - /// /// Verifies that the specified signature is valid for this key and the provided data. /// @@ -197,7 +199,7 @@ public byte[] SignData(byte[] data, byte[]? context = default) /// /// The instance represents only a public key. /// -or- - /// An error occurred while signing the data. + /// An error occurred while verifying the data. /// public bool VerifyData(ReadOnlySpan data, ReadOnlySpan signature, ReadOnlySpan context = default) { @@ -258,7 +260,388 @@ public bool VerifyData(byte[] data, byte[] signature, byte[]? context = default) return VerifyData(new ReadOnlySpan(data), new ReadOnlySpan(signature), new ReadOnlySpan(context)); } - // TODO: VerifyPreHash + /// + /// Signs the specified hash using the FIPS 204 pre-hash signing algorithm, writing the signature into the provided buffer. + /// + /// + /// The hash to sign. + /// + /// + /// The buffer to receive the signature. Its length must be exactly + /// . + /// + /// + /// The OID of the hash algorithm used to create the hash. + /// + /// + /// An optional context-specific value to limit the scope of the signature. + /// The default value is an empty buffer. + /// + /// + /// is . + /// + /// + /// The buffer in is the incorrect length to receive the signature. + /// + /// + /// has a in excess of + /// 255 bytes. + /// + /// + /// This instance has been disposed. + /// + /// + /// is not a well-formed OID. + /// -or- + /// is a well-known algorithm and does not have the expected length. + /// -or- + /// The instance represents only a public key. + /// -or- + /// An error occurred while signing the hash. + /// + public void SignPreHash(ReadOnlySpan hash, Span destination, string hashAlgorithmOid, ReadOnlySpan context = default) + { + ArgumentNullException.ThrowIfNull(hashAlgorithmOid); + Helpers.ThrowIfDestinationWrongLength(destination, Algorithm.SignatureSizeInBytes); + + if (context.Length > MaxContextLength) + { + throw new ArgumentOutOfRangeException( + nameof(context), + context.Length, + SR.Argument_SignatureContextTooLong255); + } + + 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); + } + + /// + /// Signs the specified hash using the FIPS 204 pre-hash signing algorithm. + /// + /// + /// The hash to sign. + /// + /// + /// The OID of the hash algorithm used to create the hash. + /// + /// + /// An optional context-specific value to limit the scope of the signature. + /// The default value is . + /// + /// + /// or is . + /// An error occurred while verifying the data. + /// is not a well-formed OID. + /// -or- + /// is a well-known algorithm and does not have the expected length. + /// -or- + /// The instance represents only a public key. + /// -or- + /// An error occurred while signing the hash. + /// + public byte[] SignPreHash(byte[] hash, string hashAlgorithmOid, byte[]? context = default) + { + ArgumentNullException.ThrowIfNull(hash); + ArgumentNullException.ThrowIfNull(hashAlgorithmOid); + + byte[] destination = new byte[Algorithm.SignatureSizeInBytes]; + SignPreHash(new ReadOnlySpan(hash), destination.AsSpan(), hashAlgorithmOid, new ReadOnlySpan(context)); + return destination; + } + + /// + /// Verifies that the specified FIPS 204 pre-hash signature is valid for this key and the provided hash. + /// + /// + /// The hash to verify. + /// + /// + /// The signature to verify. + /// + /// + /// The OID of the hash algorithm used to create the hash. + /// + /// + /// The context value which was provided during signing. + /// The default value is an empty buffer. + /// + /// + /// if the signature validates the hash; otherwise, . + /// + /// + /// is . + /// + /// + /// has a in excess of + /// 255 bytes. + /// + /// + /// This instance has been disposed. + /// + /// + /// is not a well-formed OID. + /// -or- + /// is a well-known algorithm and does not have the expected length. + /// -or- + /// An error occurred while verifying the hash. + /// + public bool VerifyPreHash(ReadOnlySpan hash, ReadOnlySpan signature, string hashAlgorithmOid, ReadOnlySpan context = default) + { + ArgumentNullException.ThrowIfNull(hashAlgorithmOid); + + if (context.Length > MaxContextLength) + { + throw new ArgumentOutOfRangeException( + nameof(context), + context.Length, + SR.Argument_SignatureContextTooLong255); + } + + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); + + 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); + } + + /// + /// Verifies that the specified FIPS 204 pre-hash signature is valid for this key and the provided hash. + /// + /// + /// The hash to verify. + /// + /// + /// The signature to verify. + /// + /// + /// The OID of the hash algorithm used to create the hash. + /// + /// + /// The context value which was provided during signing. + /// The default value is . + /// + /// + /// if the signature validates the hash; otherwise, . + /// + /// + /// or or is . + /// + /// + /// has a length in excess of 255 bytes. + /// + /// + /// This instance has been disposed. + /// + /// + /// is not a well-formed OID. + /// -or- + /// is a well-known algorithm and does not have the expected length. + /// -or- + /// An error occurred while verifying the hash. + /// + /// + /// A context is treated as empty. + /// + public bool VerifyPreHash(byte[] hash, byte[] signature, string hashAlgorithmOid, byte[]? context = null) + { + ArgumentNullException.ThrowIfNull(hash); + ArgumentNullException.ThrowIfNull(signature); + ArgumentNullException.ThrowIfNull(hashAlgorithmOid); + + return VerifyPreHash( + new ReadOnlySpan(hash), + new ReadOnlySpan(signature), + hashAlgorithmOid, + new ReadOnlySpan(context)); + } + + /// + /// is . + public byte[] SignMu(byte[] externalMu) + { + ArgumentNullException.ThrowIfNull(externalMu); + + return SignMu(new ReadOnlySpan(externalMu)); + } + + /// + /// Signs the specified externally computed signature mu (μ) value. + /// + /// + /// The signature mu value to sign. + /// + /// + /// ML-DSA signature for the specified mu value. + /// + /// + /// The buffer in is the incorrect length for the signature mu value. + /// + /// + /// This instance has been disposed. + /// + /// + /// The instance represents only a public key. + /// -or- + /// An error occurred while signing the hash. + /// + /// + /// The current platform does not support signing with an externally computed mu value. + /// + /// + public byte[] SignMu(ReadOnlySpan externalMu) + { + byte[] destination = new byte[Algorithm.SignatureSizeInBytes]; + SignMu(externalMu, destination.AsSpan()); + return destination; + } + + /// + /// Signs the specified externally computed signature mu (μ) value, + /// writing the signature into the provided buffer. + /// + /// + /// The signature mu value to sign. + /// + /// + /// The buffer to receive the signature. Its length must be exactly + /// . + /// + /// + /// + /// The buffer in is the incorrect length for the signature mu value. + /// + /// -or- + /// + /// The buffer in is the incorrect length to receive the signature. + /// + /// + /// + /// This instance has been disposed. + /// + /// + /// The instance represents only a public key. + /// -or- + /// An error occurred while signing the hash. + /// + /// + /// The current platform does not support signing with an externally computed mu value. + /// + /// + public void SignMu(ReadOnlySpan externalMu, Span destination) + { + if (externalMu.Length != Algorithm.MuSizeInBytes) + throw new ArgumentException(SR.Argument_MLDsaMuInvalidLength, nameof(externalMu)); + + Helpers.ThrowIfDestinationWrongLength(destination, Algorithm.SignatureSizeInBytes); + ThrowIfDisposed(); + + SignMuCore(externalMu, destination); + } + + /// + /// When overridden in a derived class, computes the remainder of the signature from the + /// precomputed mu (μ) value, writing it into the provided buffer. + /// + /// + /// The signature mu value to sign. + /// + /// + /// The buffer to receive the signature, which will always be the exactly correct size for the algorithm. + /// + /// + /// An error occurred while computing the signature. + /// + protected abstract void SignMuCore(ReadOnlySpan externalMu, Span destination); + + /// + /// + /// or is . + /// + public bool VerifyMu(byte[] externalMu, byte[] signature) + { + ArgumentNullException.ThrowIfNull(externalMu); + ArgumentNullException.ThrowIfNull(signature); + + return VerifyMu(new ReadOnlySpan(externalMu), new ReadOnlySpan(signature)); + } + + /// + /// Verifies that a digital signature is valid for the provided externally computed signature mu (μ) value. + /// + /// The signature mu value. + /// The signature to verify. + /// + /// if the digital signature is valid for the provided mu value; + /// otherwise, . + /// + /// + /// This instance has been disposed. + /// + /// An error occurred while verifying the mu value. + /// + /// The current platform does not support verification with an externally computed mu value. + /// + public bool VerifyMu(ReadOnlySpan externalMu, ReadOnlySpan signature) + { + if (externalMu.Length != Algorithm.MuSizeInBytes || signature.Length != Algorithm.SignatureSizeInBytes) + { + return false; + } + + ThrowIfDisposed(); + + return VerifyMuCore(externalMu, signature); + } + + /// + /// When overridden in a derived class, + /// verifies that a digital signature is valid for the provided externally computed signature mu (μ) value. + /// + /// The signature mu value. + /// The signature to verify. + /// + /// if the mu value is valid; otherwise, . + /// + protected abstract bool VerifyMuCore(ReadOnlySpan externalMu, ReadOnlySpan signature); /// /// Exports the public-key portion of the current key in the X.509 SubjectPublicKeyInfo format. @@ -388,7 +771,7 @@ public bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritte 3 + // Version Integer 2 + // AlgorithmIdentifier Sequence 3 + // AlgorithmIdentifier OID value, undervalued to be safe - 2 + // Secret key Octet String prefix, undervalued to be safe + 2 + // Private key Octet String prefix, undervalued to be safe Algorithm.PrivateSeedSizeInBytes; if (destination.Length < minimumPossiblePkcs8MLDsaKey) @@ -816,68 +1199,52 @@ public byte[] ExportMLDsaPublicKey() /// public void ExportMLDsaPublicKey(Span destination) { - int publicKeySizeInBytes = Algorithm.PublicKeySizeInBytes; - - if (destination.Length != publicKeySizeInBytes) - { - throw new ArgumentException( - SR.Format(SR.Argument_DestinationImprecise, publicKeySizeInBytes), - nameof(destination)); - } - + Helpers.ThrowIfDestinationWrongLength(destination, Algorithm.PublicKeySizeInBytes); ThrowIfDisposed(); ExportMLDsaPublicKeyCore(destination); } /// - /// Exports the current key in the FIPS 204 secret key format. + /// Exports the current key in the FIPS 204 private key format. /// /// - /// The FIPS 204 secret key. + /// The FIPS 204 private key. /// /// - /// The current instance cannot export a secret key. + /// The current instance cannot export a private key. /// -or- /// An error occurred while exporting the key. /// /// The object has already been disposed. - public byte[] ExportMLDsaSecretKey() + public byte[] ExportMLDsaPrivateKey() { ThrowIfDisposed(); - byte[] destination = new byte[Algorithm.SecretKeySizeInBytes]; - ExportMLDsaSecretKeyCore(destination); + byte[] destination = new byte[Algorithm.PrivateKeySizeInBytes]; + ExportMLDsaPrivateKeyCore(destination); return destination; } /// - /// Exports the current key in the FIPS 204 secret key format. + /// Exports the current key in the FIPS 204 private key format. /// /// - /// The buffer to receive the secret key. Its length must be exactly - /// . + /// The buffer to receive the private key. Its length must be exactly + /// . /// /// - /// is the incorrect length to receive the secret key. + /// is the incorrect length to receive the private key. /// /// /// An error occurred while exporting the key. /// - public void ExportMLDsaSecretKey(Span destination) + public void ExportMLDsaPrivateKey(Span destination) { - int secretKeySizeInBytes = Algorithm.SecretKeySizeInBytes; - - if (destination.Length != secretKeySizeInBytes) - { - throw new ArgumentException( - SR.Format(SR.Argument_DestinationImprecise, secretKeySizeInBytes), - nameof(destination)); - } - + Helpers.ThrowIfDestinationWrongLength(destination, Algorithm.PrivateKeySizeInBytes); ThrowIfDisposed(); - ExportMLDsaSecretKeyCore(destination); + ExportMLDsaPrivateKeyCore(destination); } /// @@ -914,14 +1281,7 @@ public byte[] ExportMLDsaPrivateSeed() /// public void ExportMLDsaPrivateSeed(Span destination) { - int privateSeedSizeInBytes = Algorithm.PrivateSeedSizeInBytes; - if (destination.Length != privateSeedSizeInBytes) - { - throw new ArgumentException( - SR.Format(SR.Argument_DestinationImprecise, privateSeedSizeInBytes), - nameof(destination)); - } - + Helpers.ThrowIfDestinationWrongLength(destination, Algorithm.PrivateSeedSizeInBytes); ThrowIfDisposed(); ExportMLDsaPrivateSeedCore(destination); @@ -1063,7 +1423,7 @@ public static MLDsa ImportPkcs8PrivateKey(ReadOnlySpan source) return dsa; } - /// > + /// /// /// is . /// @@ -1460,13 +1820,13 @@ public static MLDsa ImportMLDsaPublicKey(MLDsaAlgorithm algorithm, byte[] source } /// - /// Imports an ML-DSA private key in the FIPS 204 secret key format. + /// Imports an ML-DSA private key in the FIPS 204 private key format. /// /// /// The specific ML-DSA algorithm for this key. /// /// - /// The bytes of a FIPS 204 secret key. + /// The bytes of a FIPS 204 private key. /// /// /// The imported key. @@ -1484,29 +1844,29 @@ public static MLDsa ImportMLDsaPublicKey(MLDsaAlgorithm algorithm, byte[] source /// An error occurred while importing the key. /// /// - public static MLDsa ImportMLDsaSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) + public static MLDsa ImportMLDsaPrivateKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) { ArgumentNullException.ThrowIfNull(algorithm); - if (source.Length != algorithm.SecretKeySizeInBytes) + if (source.Length != algorithm.PrivateKeySizeInBytes) { - throw new ArgumentException(SR.Cryptography_KeyWrongSizeForAlgorithm, nameof(source)); + throw new ArgumentException(SR.Argument_PrivateKeyWrongSizeForAlgorithm, nameof(source)); } ThrowIfNotSupported(); - return MLDsaImplementation.ImportSecretKey(algorithm, source); + return MLDsaImplementation.ImportPrivateKey(algorithm, source); } - /// + /// /// /// or is . /// - public static MLDsa ImportMLDsaSecretKey(MLDsaAlgorithm algorithm, byte[] source) + public static MLDsa ImportMLDsaPrivateKey(MLDsaAlgorithm algorithm, byte[] source) { ArgumentNullException.ThrowIfNull(algorithm); ArgumentNullException.ThrowIfNull(source); - return ImportMLDsaSecretKey(algorithm, new ReadOnlySpan(source)); + return ImportMLDsaPrivateKey(algorithm, new ReadOnlySpan(source)); } /// @@ -1605,10 +1965,54 @@ protected virtual void Dispose(bool disposing) /// if the signature validates the data; otherwise, . /// /// - /// An error occurred while signing the data. + /// An error occurred while verifying the data. /// protected abstract bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature); + /// + /// When overridden in a derived class, computes the pre-hash signature of the specified hash and context, + /// writing it into the provided buffer. + /// + /// + /// The hash to sign. + /// + /// + /// The signature context. + /// + /// + /// The OID of the hash algorithm used to create the hash. + /// + /// + /// The buffer to receive the signature, which will always be the exactly correct size for the algorithm. + /// + /// + /// An error occurred while signing the hash. + /// + protected abstract void SignPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination); + + /// + /// When overridden in a derived class, verifies the pre-hash signature of the specified hash and context. + /// + /// + /// The data to verify. + /// + /// + /// The signature context. + /// + /// + /// The OID of the hash algorithm used to create the hash. + /// + /// + /// The signature to verify. + /// + /// + /// if the signature validates the hash; otherwise, . + /// + /// + /// An error occurred while verifying the hash. + /// + protected abstract bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature); + /// /// When overridden in a derived class, exports the FIPS 204 public key to the specified buffer. /// @@ -1618,12 +2022,12 @@ protected virtual void Dispose(bool disposing) protected abstract void ExportMLDsaPublicKeyCore(Span destination); /// - /// When overridden in a derived class, exports the FIPS 204 secret key to the specified buffer. + /// When overridden in a derived class, exports the FIPS 204 private key to the specified buffer. /// /// - /// The buffer to receive the secret key. + /// The buffer to receive the private key. /// - protected abstract void ExportMLDsaSecretKeyCore(Span destination); + protected abstract void ExportMLDsaPrivateKeyCore(Span destination); /// /// When overridden in a derived class, exports the private seed to the specified buffer. @@ -1729,10 +2133,10 @@ private AsnWriter ExportEncryptedPkcs8PrivateKeyCore(ReadOnlySpan password private TResult ExportPkcs8PrivateKeyCallback(ExportPkcs8PrivateKeyFunc func) { - // A PKCS#8 ML-DSA secret key has an ASN.1 overhead of 28 bytes, assuming no attributes. + // A PKCS#8 ML-DSA private key has an ASN.1 overhead of 28 bytes, assuming no attributes. // Make it an even 32 and that should give a good starting point for a buffer size. - // The secret key is always larger than the seed so this buffer size can accommodate both. - int size = Algorithm.SecretKeySizeInBytes + 32; + // The private key is always larger than the seed so this buffer size can accommodate both. + int size = Algorithm.PrivateKeySizeInBytes + 32; // The buffer is only being passed out as a span, so the derived type can't meaningfully // hold on to it without being malicious. byte[] buffer = CryptoPool.Rent(size); @@ -1781,30 +2185,30 @@ private static void MLDsaKeyReader( } else if (dsaKey.ExpandedKey is ReadOnlyMemory expandedKey) { - if (expandedKey.Length != algorithm.SecretKeySizeInBytes) + if (expandedKey.Length != algorithm.PrivateKeySizeInBytes) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } - dsa = MLDsaImplementation.ImportSecretKey(algorithm, expandedKey.Span); + dsa = MLDsaImplementation.ImportPrivateKey(algorithm, expandedKey.Span); } else if (dsaKey.Both is MLDsaPrivateKeyBothAsn both) { - int secretKeySize = algorithm.SecretKeySizeInBytes; + int privateKeySize = algorithm.PrivateKeySizeInBytes; if (both.Seed.Length != algorithm.PrivateSeedSizeInBytes || - both.ExpandedKey.Length != secretKeySize) + both.ExpandedKey.Length != privateKeySize) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } MLDsa key = MLDsaImplementation.ImportMLDsaPrivateSeed(algorithm, both.Seed.Span); - byte[] rent = CryptoPool.Rent(secretKeySize); - Span buffer = rent.AsSpan(0, secretKeySize); + byte[] rent = CryptoPool.Rent(privateKeySize); + Span buffer = rent.AsSpan(0, privateKeySize); try { - key.ExportMLDsaSecretKey(buffer); + key.ExportMLDsaPrivateKey(buffer); if (CryptographicOperations.FixedTimeEquals(buffer, both.ExpandedKey.Span)) { @@ -1822,7 +2226,7 @@ private static void MLDsaKeyReader( } finally { - CryptoPool.Return(rent, secretKeySize); + CryptoPool.Return(rent, privateKeySize); } } else @@ -1855,7 +2259,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/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs index c058daab3bb2e3..1b30552e4ceddc 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs @@ -22,12 +22,12 @@ public sealed class MLDsaAlgorithm : IEquatable public string Name { get; } /// - /// Gets the size, in bytes, of the ML-DSA secret key for the current ML-DSA algorithm. + /// Gets the size, in bytes, of the ML-DSA private key for the current ML-DSA algorithm. /// /// - /// The size, in bytes, of the ML-DSA secret key for the current ML-DSA algorithm. + /// The size, in bytes, of the ML-DSA private key for the current ML-DSA algorithm. /// - public int SecretKeySizeInBytes { get; } + public int PrivateKeySizeInBytes { get; } /// /// Gets the size, in bytes, of the ML-DSA private seed for the current ML-DSA algorithm. @@ -53,32 +53,30 @@ public sealed class MLDsaAlgorithm : IEquatable /// public int SignatureSizeInBytes { get; } - internal string Oid { get; } - /// - /// Initializes a new instance of the structure with a custom name. + /// Gets the size, in bytes, of the mu (μ) value for the current ML-DSA algorithm. /// - /// - /// 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) + /// + /// The size, in bytes, of the mu (μ) value for the current ML-DSA algorithm. + /// + public int MuSizeInBytes => 64; + + internal string Oid { get; } + internal int LambdaCollisionStrength { get; } + + private MLDsaAlgorithm( + string name, + int privateKeySizeInBytes, + int publicKeySizeInBytes, + int signatureSizeInBytes, + int lambdaCollisionStrength, + string oid) { Name = name; - SecretKeySizeInBytes = secretKeySizeInBytes; + PrivateKeySizeInBytes = privateKeySizeInBytes; PublicKeySizeInBytes = publicKeySizeInBytes; SignatureSizeInBytes = signatureSizeInBytes; + LambdaCollisionStrength = lambdaCollisionStrength; Oid = oid; } @@ -91,7 +89,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 +97,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 +105,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/libraries/Common/src/System/Security/Cryptography/MLDsaCng.Windows.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.Windows.cs index 5b38c97540868f..dee5e6b7c7db3a 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.Windows.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.Windows.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using System.Formats.Asn1; using System.Security.Cryptography.Asn1; -using System.Runtime.InteropServices; using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; @@ -95,16 +94,21 @@ static Exception DebugFailAndGetException(string? parameterSet) } } - public partial CngKey Key + public partial CngKey GetKey() { - get - { - ThrowIfDisposed(); + ThrowIfDisposed(); - return _key; - } +#if SYSTEM_SECURITY_CRYPTOGRAPHY + return CngHelpers.Duplicate(_key.HandleNoDuplicate, _key.IsEphemeral); +#else +#pragma warning disable CA1416 // only supported on: 'windows' + return _key.Duplicate(); +#pragma warning restore CA1416 // only supported on: 'windows' +#endif } + internal CngKey KeyNoDuplicate => _key; + /// protected override void ExportMLDsaPublicKeyCore(Span destination) => ExportKey(CngKeyBlobFormat.PQDsaPublicBlob, Algorithm.PublicKeySizeInBytes, destination); @@ -144,7 +148,7 @@ protected override void ExportMLDsaPrivateSeedCore(Span destination) } /// - protected override void ExportMLDsaSecretKeyCore(Span destination) + protected override void ExportMLDsaPrivateKeyCore(Span destination) { bool encryptedOnlyExport = CngPkcs8.AllowsOnlyEncryptedExport(_key); @@ -156,16 +160,16 @@ protected override void ExportMLDsaSecretKeyCore(Span destination) if (expandedKey is ReadOnlyMemory expandedKeyValue) { - if (expandedKeyValue.Length != algorithm.SecretKeySizeInBytes) + if (expandedKeyValue.Length != algorithm.PrivateKeySizeInBytes) { - throw new CryptographicException(SR.Argument_SecretKeyWrongSizeForAlgorithm); + throw new CryptographicException(SR.Argument_PrivateKeyWrongSizeForAlgorithm); } expandedKeyValue.Span.CopyTo(destination); return; } - // If PKCS#8 only has seed, then we can calculate the secret key + // If PKCS#8 only has seed, then we can calculate the private key ReadOnlyMemory? seed = mldsaPrivateKeyAsn.Seed; if (seed is ReadOnlyMemory seedValue) @@ -177,7 +181,7 @@ protected override void ExportMLDsaSecretKeyCore(Span destination) using (MLDsa cloned = MLDsaImplementation.ImportSeed(algorithm, seedValue.Span)) { - cloned.ExportMLDsaSecretKey(destination); + cloned.ExportMLDsaPrivateKey(destination); return; } } @@ -189,7 +193,7 @@ protected override void ExportMLDsaSecretKeyCore(Span destination) } else { - ExportKey(CngKeyBlobFormat.PQDsaPrivateBlob, Algorithm.SecretKeySizeInBytes, destination); + ExportKey(CngKeyBlobFormat.PQDsaPrivateBlob, Algorithm.PrivateKeySizeInBytes, destination); } } @@ -211,7 +215,7 @@ protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out } bytesWritten = pkcs8.Count; - pkcs8.Array.CopyTo(destination); + pkcs8.AsSpan().CopyTo(destination); return true; } finally @@ -266,6 +270,76 @@ protected override unsafe bool VerifyDataCore(ReadOnlySpan data, ReadOnlyS } } + /// + 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 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) { @@ -298,16 +372,6 @@ internal static MLDsaCng ImportPkcs8PrivateKey(byte[] source, out int bytesRead) { key = CngKey.Import(pkcs8Source, CngKeyBlobFormat.Pkcs8PrivateBlob); } - catch (CryptographicException) - { - // TODO: Once Windows moves to new PKCS#8 format, we can remove this conversion. - byte[] newPkcs8Source = MLDsaPkcs8.ConvertToOldChoicelessFormat(pkcs8Source); - - using (PinAndClear.Track(newPkcs8Source)) - { - key = CngKey.Import(newPkcs8Source, CngKeyBlobFormat.Pkcs8PrivateBlob); - } - } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); @@ -416,13 +480,6 @@ private void ExportKeyWithEncryptedOnlyExport(KeySelectorFunc keySelector, MLDsa { mldsaPrivateKeyAsn = MLDsaPrivateKeyAsn.Decode(privateKey, AsnEncodingRules.BER); } - catch (CryptographicException) - { - // TODO: Once Windows moves to new PKCS#8 format, we can remove this conversion. - newPkcs8 = MLDsaPkcs8.ConvertFromOldChoicelessFormat(pkcs8); - ReadOnlyMemory newPrivateKey = KeyFormatHelper.ReadPkcs8(KnownOids, newPkcs8, out _); - mldsaPrivateKeyAsn = MLDsaPrivateKeyAsn.Decode(newPrivateKey, AsnEncodingRules.BER); - } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.cs index f4d7ab54006a25..ba51f4aba7fdec 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.cs @@ -2,8 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; using System.Runtime.Versioning; +using Internal.Cryptography; namespace System.Security.Cryptography { @@ -48,14 +48,20 @@ public MLDsaCng(CngKey key) _key = duplicateKey; } + /// + protected override void SignMuCore(ReadOnlySpan mu, Span destination) => + throw new PlatformNotSupportedException(); + + /// + protected override bool VerifyMuCore(ReadOnlySpan mu, ReadOnlySpan signature) => + throw new PlatformNotSupportedException(); + private static MLDsaAlgorithm AlgorithmFromHandleWithPlatformCheck(CngKey key, out CngKey duplicateKey) { -#if !NETFRAMEWORK - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (!Helpers.IsOSPlatformWindows) { throw new PlatformNotSupportedException(); } -#endif return AlgorithmFromHandle(key, out duplicateKey); } @@ -63,18 +69,15 @@ private static MLDsaAlgorithm AlgorithmFromHandleWithPlatformCheck(CngKey key, o private static partial MLDsaAlgorithm AlgorithmFromHandle(CngKey key, out CngKey duplicateKey); /// - /// Gets the key that will be used by the object for any cryptographic operation that it performs. + /// Gets a new representing the key used by the current instance. /// - /// - /// The key that will be used by the object for any cryptographic operation that it performs. - /// /// /// This instance has been disposed. /// /// - /// This object is not the same as the one passed to the constructor, + /// This object is not the same as the one passed to , /// if that constructor was used. However, it will point to the same CNG key. /// - public partial CngKey Key { get; } + public partial CngKey GetKey(); } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.CreateCng.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.CreateCng.cs index 55b81de4939e83..af103e88ff3b86 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.CreateCng.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.CreateCng.cs @@ -7,16 +7,18 @@ namespace System.Security.Cryptography { internal sealed partial class MLDsaImplementation { +#if !SYSTEM_SECURITY_CRYPTOGRAPHY [SupportedOSPlatform("windows")] +#endif internal CngKey CreateEphemeralCng() { string bcryptBlobType = _hasSeed ? Interop.BCrypt.KeyBlobType.BCRYPT_PQDSA_PRIVATE_SEED_BLOB : - _hasSecretKey ? Interop.BCrypt.KeyBlobType.BCRYPT_PQDSA_PRIVATE_BLOB : + _hasPrivateKey ? Interop.BCrypt.KeyBlobType.BCRYPT_PQDSA_PRIVATE_BLOB : Interop.BCrypt.KeyBlobType.BCRYPT_PQDSA_PUBLIC_BLOB; CngKeyBlobFormat cngBlobFormat = - _hasSecretKey ? CngKeyBlobFormat.PQDsaPrivateBlob : + _hasPrivateKey ? CngKeyBlobFormat.PQDsaPrivateBlob : _hasSeed ? CngKeyBlobFormat.PQDsaPrivateSeedBlob : CngKeyBlobFormat.PQDsaPublicBlob; diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.NotSupported.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.NotSupported.cs index 3333c9a06086de..fb0913784db586 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.NotSupported.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.NotSupported.cs @@ -16,6 +16,8 @@ private MLDsaImplementation(MLDsaAlgorithm algorithm) internal static partial bool SupportsAny() => false; + internal static partial bool IsAlgorithmSupported(MLDsaAlgorithm algorithm) => false; + // The instance override methods are unreachable, as the constructor will always throw. protected override void SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) => throw new PlatformNotSupportedException(); @@ -23,10 +25,22 @@ protected override void SignDataCore(ReadOnlySpan data, ReadOnlySpan protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => throw new PlatformNotSupportedException(); + protected override void SignPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => + throw new PlatformNotSupportedException(); + + protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => + throw new PlatformNotSupportedException(); + + protected override void SignMuCore(ReadOnlySpan mu, Span destination) => + throw new PlatformNotSupportedException(); + + protected override bool VerifyMuCore(ReadOnlySpan mu, ReadOnlySpan signature) => + throw new PlatformNotSupportedException(); + protected override void ExportMLDsaPublicKeyCore(Span destination) => throw new PlatformNotSupportedException(); - protected override void ExportMLDsaSecretKeyCore(Span destination) => + protected override void ExportMLDsaPrivateKeyCore(Span destination) => throw new PlatformNotSupportedException(); protected override void ExportMLDsaPrivateSeedCore(Span destination) => @@ -41,7 +55,7 @@ internal static partial MLDsaImplementation GenerateKeyImpl(MLDsaAlgorithm algor internal static partial MLDsaImplementation ImportPublicKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) => throw new PlatformNotSupportedException(); - internal static partial MLDsaImplementation ImportSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) => + internal static partial MLDsaImplementation ImportPrivateKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) => throw new PlatformNotSupportedException(); internal static partial MLDsaImplementation ImportSeed(MLDsaAlgorithm algorithm, ReadOnlySpan source) => diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs index 621d891d4d7289..dcbd34ed8a2015 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs @@ -3,7 +3,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; +using Internal.Cryptography; using Internal.NativeCrypto; using Microsoft.Win32.SafeHandles; @@ -16,29 +16,32 @@ internal sealed partial class MLDsaImplementation : MLDsa private static readonly SafeBCryptAlgorithmHandle? s_algHandle = OpenAlgorithmHandle(); private readonly bool _hasSeed; - private readonly bool _hasSecretKey; + private readonly bool _hasPrivateKey; private SafeBCryptKeyHandle _key; private MLDsaImplementation( MLDsaAlgorithm algorithm, SafeBCryptKeyHandle key, bool hasSeed, - bool hasSecretKey) + bool hasPrivateKey) : base(algorithm) { _key = key; _hasSeed = hasSeed; - _hasSecretKey = hasSecretKey; + _hasPrivateKey = hasPrivateKey; } [MemberNotNullWhen(true, nameof(s_algHandle))] internal static partial bool SupportsAny() => s_algHandle is not null; + [MemberNotNullWhen(true, nameof(s_algHandle))] + internal static partial bool IsAlgorithmSupported(MLDsaAlgorithm algorithm) => SupportsAny(); + protected override void SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) { - if (!_hasSecretKey) + if (!_hasPrivateKey) { - throw new CryptographicException(SR.Cryptography_MLDsaNoSecretKey); + throw new CryptographicException(SR.Cryptography_NoPrivateKeyAvailable); } Interop.BCrypt.BCryptSignHashPqcPure(_key, data, context, destination); @@ -47,6 +50,53 @@ 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) + { + if (!_hasPrivateKey) + { + throw new CryptographicException(SR.Cryptography_NoPrivateKeyAvailable); + } + + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); + + Debug.Assert(hashAlgorithmIdentifier is not null); + Debug.Assert(!insufficientCollisionResistance); + Debug.Assert(hashLengthInBytes == hash.Length); + + 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); + } + + protected override void SignMuCore(ReadOnlySpan externalMu, Span destination) => + throw new PlatformNotSupportedException(); + + protected override bool VerifyMuCore(ReadOnlySpan externalMu, ReadOnlySpan signature) => + throw new PlatformNotSupportedException(); + internal static partial MLDsaImplementation GenerateKeyImpl(MLDsaAlgorithm algorithm) { Debug.Assert(SupportsAny()); @@ -65,7 +115,7 @@ internal static partial MLDsaImplementation GenerateKeyImpl(MLDsaAlgorithm algor throw; } - return new MLDsaImplementation(algorithm, keyHandle, hasSeed: true, hasSecretKey: true); + return new MLDsaImplementation(algorithm, keyHandle, hasSeed: true, hasPrivateKey: true); } internal static partial MLDsaImplementation ImportPublicKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) @@ -81,10 +131,10 @@ internal static partial MLDsaImplementation ImportPublicKey(MLDsaAlgorithm algor PublicBlobType, static blob => Interop.BCrypt.BCryptImportKeyPair(s_algHandle, PublicBlobType, blob)); - return new MLDsaImplementation(algorithm, key, hasSeed: false, hasSecretKey: false); + return new MLDsaImplementation(algorithm, key, hasSeed: false, hasPrivateKey: false); } - internal static partial MLDsaImplementation ImportSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) + internal static partial MLDsaImplementation ImportPrivateKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) { Debug.Assert(SupportsAny()); @@ -97,7 +147,7 @@ internal static partial MLDsaImplementation ImportSecretKey(MLDsaAlgorithm algor PrivateBlobType, static blob => Interop.BCrypt.BCryptImportKeyPair(s_algHandle, PrivateBlobType, blob)); - return new MLDsaImplementation(algorithm, key, hasSeed: false, hasSecretKey: true); + return new MLDsaImplementation(algorithm, key, hasSeed: false, hasPrivateKey: true); } internal static partial MLDsaImplementation ImportSeed(MLDsaAlgorithm algorithm, ReadOnlySpan source) @@ -113,7 +163,7 @@ internal static partial MLDsaImplementation ImportSeed(MLDsaAlgorithm algorithm, PrivateSeedBlobType, static blob => Interop.BCrypt.BCryptImportKeyPair(s_algHandle, PrivateSeedBlobType, blob)); - return new MLDsaImplementation(algorithm, key, hasSeed: true, hasSecretKey: true); + return new MLDsaImplementation(algorithm, key, hasSeed: true, hasPrivateKey: true); } protected override void ExportMLDsaPublicKeyCore(Span destination) => @@ -122,16 +172,16 @@ protected override void ExportMLDsaPublicKeyCore(Span destination) => Algorithm.PublicKeySizeInBytes, destination); - protected override void ExportMLDsaSecretKeyCore(Span destination) + protected override void ExportMLDsaPrivateKeyCore(Span destination) { - if (!_hasSecretKey) + if (!_hasPrivateKey) { - throw new CryptographicException(SR.Cryptography_MLDsaNoSecretKey); + throw new CryptographicException(SR.Cryptography_NoPrivateKeyAvailable); } ExportKey( Interop.BCrypt.KeyBlobType.BCRYPT_PQDSA_PRIVATE_BLOB, - Algorithm.SecretKeySizeInBytes, + Algorithm.PrivateKeySizeInBytes, destination); } @@ -153,7 +203,7 @@ protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out return MLDsaPkcs8.TryExportPkcs8PrivateKey( this, _hasSeed, - _hasSecretKey, + _hasPrivateKey, destination, out bytesWritten); } @@ -204,12 +254,10 @@ private void ExportKey(string keyBlobType, int expectedKeySize, Span desti private static SafeBCryptAlgorithmHandle? OpenAlgorithmHandle() { -#if !NETFRAMEWORK - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (!Helpers.IsOSPlatformWindows) { return null; } -#endif NTSTATUS status = Interop.BCrypt.BCryptOpenAlgorithmProvider( out SafeBCryptAlgorithmHandle hAlgorithm, diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.cs index b3ca249c345ea9..0f2fa494dd84c4 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.cs @@ -10,10 +10,11 @@ namespace System.Security.Cryptography internal sealed partial class MLDsaImplementation : MLDsa { internal static partial bool SupportsAny(); + internal static partial bool IsAlgorithmSupported(MLDsaAlgorithm algorithm); internal static partial MLDsaImplementation GenerateKeyImpl(MLDsaAlgorithm algorithm); internal static partial MLDsaImplementation ImportPublicKey(MLDsaAlgorithm algorithm, ReadOnlySpan source); - internal static partial MLDsaImplementation ImportSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan source); + internal static partial MLDsaImplementation ImportPrivateKey(MLDsaAlgorithm algorithm, ReadOnlySpan source); internal static partial MLDsaImplementation ImportSeed(MLDsaAlgorithm algorithm, ReadOnlySpan source); /// @@ -28,8 +29,8 @@ internal static MLDsaImplementation DuplicatePrivateKey(MLDsa key) Debug.Assert(key is not MLDsaImplementation); MLDsaAlgorithm alg = key.Algorithm; - Debug.Assert(alg.SecretKeySizeInBytes > alg.PrivateSeedSizeInBytes); - byte[] rented = CryptoPool.Rent(alg.SecretKeySizeInBytes); + Debug.Assert(alg.PrivateKeySizeInBytes > alg.PrivateSeedSizeInBytes); + byte[] rented = CryptoPool.Rent(alg.PrivateKeySizeInBytes); try { @@ -40,9 +41,9 @@ internal static MLDsaImplementation DuplicatePrivateKey(MLDsa key) catch (CryptographicException) { // Rented array may still be larger but we expect exact length - Span skSpan = rented.AsSpan(0, alg.SecretKeySizeInBytes); - key.ExportMLDsaSecretKey(skSpan); - return ImportSecretKey(alg, skSpan); + Span skSpan = rented.AsSpan(0, alg.PrivateKeySizeInBytes); + key.ExportMLDsaPrivateKey(skSpan); + return ImportPrivateKey(alg, skSpan); } finally { diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLDsaPkcs8.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsaPkcs8.cs index 259c0320ff65a8..9851b4408c0266 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLDsaPkcs8.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsaPkcs8.cs @@ -1,10 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Buffers; -using System.Diagnostics; using System.Formats.Asn1; -using System.Runtime.InteropServices; using System.Security.Cryptography.Asn1; namespace System.Security.Cryptography @@ -14,7 +11,7 @@ internal static class MLDsaPkcs8 internal static bool TryExportPkcs8PrivateKey( MLDsa dsa, bool hasSeed, - bool hasSecretKey, + bool hasPrivateKey, Span destination, out int bytesWritten) { @@ -39,12 +36,12 @@ internal static bool TryExportPkcs8PrivateKey( written = buffer.Length; privateKeyAsn.Seed = buffer; } - else if (hasSecretKey) + else if (hasPrivateKey) { - int secretKeySize = dsa.Algorithm.SecretKeySizeInBytes; - rented = CryptoPool.Rent(secretKeySize); - Memory buffer = rented.AsMemory(0, secretKeySize); - dsa.ExportMLDsaSecretKey(buffer.Span); + int privateKeySize = dsa.Algorithm.PrivateKeySizeInBytes; + rented = CryptoPool.Rent(privateKeySize); + Memory buffer = rented.AsMemory(0, privateKeySize); + dsa.ExportMLDsaPrivateKey(buffer.Span); written = buffer.Length; privateKeyAsn.ExpandedKey = buffer; } @@ -72,74 +69,5 @@ internal static bool TryExportPkcs8PrivateKey( } } } - - // TODO: Remove this once Windows moves to the new format. - internal static unsafe byte[] ConvertToOldChoicelessFormat(ReadOnlySpan pkcs8WithChoice) - { - fixed (byte* ptr = &MemoryMarshal.GetReference(pkcs8WithChoice)) - { - using (MemoryManager manager = new PointerMemoryManager(ptr, pkcs8WithChoice.Length)) - { - PrivateKeyInfoAsn privateKeyInfo = PrivateKeyInfoAsn.Decode(manager.Memory, AsnEncodingRules.BER); - AlgorithmIdentifierAsn privateAlgorithm = privateKeyInfo.PrivateKeyAlgorithm; - - if (privateAlgorithm.Algorithm is not (Oids.MLDsa44 or Oids.MLDsa65 or Oids.MLDsa87)) - { - Debug.Fail("Unexpected algorithm"); - throw new CryptographicException(); - } - - MLDsaPrivateKeyAsn mldsaPrivateKeyAsn = MLDsaPrivateKeyAsn.Decode(privateKeyInfo.PrivateKey, AsnEncodingRules.BER); - privateKeyInfo.PrivateKey = mldsaPrivateKeyAsn.Seed - ?? mldsaPrivateKeyAsn.ExpandedKey.GetValueOrDefault(); // Old format does not support having both - - AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - privateKeyInfo.Encode(writer); - return writer.Encode(); - } - } - } - - // TODO: Remove this once Windows moves to the new format. - internal static unsafe byte[] ConvertFromOldChoicelessFormat(ReadOnlySpan pkcs8WithoutChoice) - { - fixed (byte* ptr = &MemoryMarshal.GetReference(pkcs8WithoutChoice)) - { - using (MemoryManager manager = new PointerMemoryManager(ptr, pkcs8WithoutChoice.Length)) - { - PrivateKeyInfoAsn privateKeyInfo = PrivateKeyInfoAsn.Decode(manager.Memory, AsnEncodingRules.BER); - AlgorithmIdentifierAsn privateAlgorithm = privateKeyInfo.PrivateKeyAlgorithm; - - int seedSize = privateAlgorithm.Algorithm switch - { - Oids.MLDsa44 => MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes, - Oids.MLDsa65 => MLDsaAlgorithm.MLDsa65.PrivateSeedSizeInBytes, - Oids.MLDsa87 => MLDsaAlgorithm.MLDsa87.PrivateSeedSizeInBytes, - _ => throw new CryptographicException(), - }; - - ReadOnlyMemory key = privateKeyInfo.PrivateKey; - - MLDsaPrivateKeyAsn mldsaPrivateKeyAsn = default; - - if (key.Length == seedSize) - { - mldsaPrivateKeyAsn.Seed = key; - } - else - { - mldsaPrivateKeyAsn.ExpandedKey = key; - } - - AsnWriter writer = new(AsnEncodingRules.DER); - mldsaPrivateKeyAsn.Encode(writer); - privateKeyInfo.PrivateKey = writer.Encode(); - - writer = new AsnWriter(AsnEncodingRules.DER); - privateKeyInfo.Encode(writer); - return writer.Encode(); - } - } - } } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLKem.cs b/src/libraries/Common/src/System/Security/Cryptography/MLKem.cs index 478d8be5a6d072..0bcf585e0ec0c6 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLKem.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLKem.cs @@ -24,7 +24,6 @@ namespace System.Security.Cryptography /// cryptographic libraries. /// /// - [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public abstract partial class MLKem : IDisposable { private static readonly string[] s_knownOids = [Oids.MlKem512, Oids.MlKem768, Oids.MlKem1024]; @@ -40,10 +39,10 @@ public abstract partial class MLKem : IDisposable public static bool IsSupported => MLKemImplementation.IsSupported; /// - /// Gets the algorithm of the current instance. + /// Gets the specific ML-KEM algorithm for this key. /// /// - /// A value representing the ML-KEM algorithm. + /// The specific ML-KEM algorithm for this key. /// public MLKemAlgorithm Algorithm { get; } @@ -183,6 +182,14 @@ public void Encapsulate(out byte[] ciphertext, out byte[] sharedSecret) /// /// The buffer to receive the shared secret. /// + /// + /// Decapsulation can only decapsulate a shared secret created with the the decapsulation key's + /// corresponding encapsulation key. If a different key is used, ML-KEM performs implicit rejection. + /// Implicit rejection means an error will not be returned. Instead, the shared secret will be a + /// deterministic but incorrect result. + /// Detecting incorrect key use is a concern for consumers of the ML-KEM algorithm. + /// For more information, see FIPS 203, Section 6.3. + /// /// /// An error occurred during decapsulation. /// @@ -219,6 +226,14 @@ public void Decapsulate(ReadOnlySpan ciphertext, Span sharedSecret) /// /// The shared secret. /// + /// + /// Decapsulation can only decapsulate a shared secret created with the the decapsulation key's + /// corresponding encapsulation key. If a different key is used, ML-KEM performs implicit rejection. + /// Implicit rejection means an error will not be returned. Instead, the shared secret will be a + /// deterministic but incorrect result. + /// Detecting incorrect key use is a concern for consumers of the ML-KEM algorithm. + /// For more information, see FIPS 203, Section 6.3. + /// /// /// An error occurred during decapsulation. /// @@ -617,6 +632,7 @@ public byte[] ExportEncapsulationKey() /// /// An error occurred while exporting the key. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public bool TryExportSubjectPublicKeyInfo(Span destination, out int bytesWritten) { ThrowIfDisposed(); @@ -635,6 +651,7 @@ public bool TryExportSubjectPublicKeyInfo(Span destination, out int bytesW /// /// An error occurred while exporting the key. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public byte[] ExportSubjectPublicKeyInfo() { ThrowIfDisposed(); @@ -655,6 +672,7 @@ public byte[] ExportSubjectPublicKeyInfo() /// /// An error occurred while exporting the key. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public string ExportSubjectPublicKeyInfoPem() { ThrowIfDisposed(); @@ -684,6 +702,7 @@ public string ExportSubjectPublicKeyInfoPem() /// /// An error occurred while exporting the key. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritten) { ThrowIfDisposed(); @@ -713,6 +732,7 @@ public bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritte /// /// An error occurred while exporting the key. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public byte[] ExportPkcs8PrivateKey() { ThrowIfDisposed(); @@ -731,6 +751,7 @@ public byte[] ExportPkcs8PrivateKey() /// /// An error occurred while exporting the key. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public string ExportPkcs8PrivateKeyPem() { ThrowIfDisposed(); @@ -757,6 +778,7 @@ public string ExportPkcs8PrivateKeyPem() /// /// An error occurred while exporting the key. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] protected abstract bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten); /// @@ -795,6 +817,7 @@ public string ExportPkcs8PrivateKeyPem() /// -or- /// does not represent a valid password-based encryption algorithm. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public bool TryExportEncryptedPkcs8PrivateKey( ReadOnlySpan password, PbeParameters pbeParameters, @@ -848,6 +871,7 @@ public bool TryExportEncryptedPkcs8PrivateKey( /// -or- /// does not represent a valid password-based encryption algorithm. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public bool TryExportEncryptedPkcs8PrivateKey( string password, PbeParameters pbeParameters, @@ -894,6 +918,7 @@ public bool TryExportEncryptedPkcs8PrivateKey( /// -or- /// does not represent a valid password-based encryption algorithm. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public bool TryExportEncryptedPkcs8PrivateKey( ReadOnlySpan passwordBytes, PbeParameters pbeParameters, @@ -938,6 +963,7 @@ public bool TryExportEncryptedPkcs8PrivateKey( /// -or- /// does not represent a valid password-based encryption algorithm. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public byte[] ExportEncryptedPkcs8PrivateKey(ReadOnlySpan passwordBytes, PbeParameters pbeParameters) { ArgumentNullException.ThrowIfNull(pbeParameters); @@ -978,6 +1004,7 @@ public byte[] ExportEncryptedPkcs8PrivateKey(ReadOnlySpan passwordBytes, P /// -or- /// does not represent a valid password-based encryption algorithm. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public byte[] ExportEncryptedPkcs8PrivateKey(ReadOnlySpan password, PbeParameters pbeParameters) { ArgumentNullException.ThrowIfNull(pbeParameters); @@ -1018,6 +1045,7 @@ public byte[] ExportEncryptedPkcs8PrivateKey(ReadOnlySpan password, PbePar /// -or- /// does not represent a valid password-based encryption algorithm. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public byte[] ExportEncryptedPkcs8PrivateKey(string password, PbeParameters pbeParameters) { ArgumentNullException.ThrowIfNull(password); @@ -1052,6 +1080,7 @@ public byte[] ExportEncryptedPkcs8PrivateKey(string password, PbeParameters pbeP /// -or- /// An error occurred while exporting the key. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public string ExportEncryptedPkcs8PrivateKeyPem(ReadOnlySpan passwordBytes, PbeParameters pbeParameters) { ArgumentNullException.ThrowIfNull(pbeParameters); @@ -1093,6 +1122,7 @@ public string ExportEncryptedPkcs8PrivateKeyPem(ReadOnlySpan passwordBytes /// -or- /// An error occurred while exporting the key. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public string ExportEncryptedPkcs8PrivateKeyPem(ReadOnlySpan password, PbeParameters pbeParameters) { ArgumentNullException.ThrowIfNull(pbeParameters); @@ -1134,6 +1164,7 @@ public string ExportEncryptedPkcs8PrivateKeyPem(ReadOnlySpan password, Pbe /// -or- /// An error occurred while exporting the key. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public string ExportEncryptedPkcs8PrivateKeyPem(string password, PbeParameters pbeParameters) { ArgumentNullException.ThrowIfNull(password); @@ -1166,6 +1197,7 @@ public string ExportEncryptedPkcs8PrivateKeyPem(string password, PbeParameters p /// The platform does not support ML-KEM. Callers can use the property /// to determine if the platform supports ML-KEM. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem ImportSubjectPublicKeyInfo(ReadOnlySpan source) { Helpers.ThrowIfAsnInvalidLength(source); @@ -1192,6 +1224,7 @@ static void SubjectPublicKeyReader(ReadOnlyMemory key, in AlgorithmIdentif /// /// is /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem ImportSubjectPublicKeyInfo(byte[] source) { ArgumentNullException.ThrowIfNull(source); @@ -1228,6 +1261,7 @@ public static MLKem ImportSubjectPublicKeyInfo(byte[] source) /// The platform does not support ML-KEM. Callers can use the property /// to determine if the platform supports ML-KEM. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem ImportPkcs8PrivateKey(ReadOnlySpan source) { Helpers.ThrowIfAsnInvalidLength(source); @@ -1242,6 +1276,7 @@ public static MLKem ImportPkcs8PrivateKey(ReadOnlySpan source) /// /// is /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem ImportPkcs8PrivateKey(byte[] source) { ArgumentNullException.ThrowIfNull(source); @@ -1286,6 +1321,7 @@ public static MLKem ImportPkcs8PrivateKey(byte[] source) /// The platform does not support ML-KEM. Callers can use the property /// to determine if the platform supports ML-KEM. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem ImportEncryptedPkcs8PrivateKey(ReadOnlySpan passwordBytes, ReadOnlySpan source) { Helpers.ThrowIfAsnInvalidLength(source); @@ -1331,6 +1367,7 @@ public static MLKem ImportEncryptedPkcs8PrivateKey(ReadOnlySpan passwordBy /// The platform does not support ML-KEM. Callers can use the property /// to determine if the platform supports ML-KEM. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem ImportEncryptedPkcs8PrivateKey(ReadOnlySpan password, ReadOnlySpan source) { Helpers.ThrowIfAsnInvalidLength(source); @@ -1379,6 +1416,7 @@ public static MLKem ImportEncryptedPkcs8PrivateKey(ReadOnlySpan password, /// The platform does not support ML-KEM. Callers can use the property /// to determine if the platform supports ML-KEM. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem ImportEncryptedPkcs8PrivateKey(string password, byte[] source) { ArgumentNullException.ThrowIfNull(password); @@ -1425,6 +1463,7 @@ public static MLKem ImportEncryptedPkcs8PrivateKey(string password, byte[] sourc /// /// /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem ImportFromPem(ReadOnlySpan source) { ThrowIfNotSupported(); @@ -1442,6 +1481,7 @@ public static MLKem ImportFromPem(ReadOnlySpan source) /// /// is /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem ImportFromPem(string source) { ArgumentNullException.ThrowIfNull(source); @@ -1503,6 +1543,7 @@ public static MLKem ImportFromPem(string source) /// /// This method supports the ENCRYPTED PRIVATE KEY PEM label. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem ImportFromEncryptedPem(ReadOnlySpan source, ReadOnlySpan password) { return PemKeyHelpers.ImportEncryptedFactoryPem( @@ -1561,6 +1602,7 @@ public static MLKem ImportFromEncryptedPem(ReadOnlySpan source, ReadOnlySp /// /// This method supports the ENCRYPTED PRIVATE KEY PEM label. /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem ImportFromEncryptedPem(ReadOnlySpan source, ReadOnlySpan passwordBytes) { return PemKeyHelpers.ImportEncryptedFactoryPem( @@ -1573,6 +1615,7 @@ public static MLKem ImportFromEncryptedPem(ReadOnlySpan source, ReadOnlySp /// /// or is /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem ImportFromEncryptedPem(string source, string password) { ArgumentNullException.ThrowIfNull(source); @@ -1585,6 +1628,7 @@ public static MLKem ImportFromEncryptedPem(string source, string password) /// /// or is /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem ImportFromEncryptedPem(string source, byte[] passwordBytes) { ArgumentNullException.ThrowIfNull(source); diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLKemAlgorithm.cs b/src/libraries/Common/src/System/Security/Cryptography/MLKemAlgorithm.cs index 03114c63378e44..e3bf5c0aa08c42 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLKemAlgorithm.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLKemAlgorithm.cs @@ -11,7 +11,6 @@ namespace System.Security.Cryptography /// /// [DebuggerDisplay("{Name,nq}")] - [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public sealed class MLKemAlgorithm : IEquatable { private MLKemAlgorithm( diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLKemCng.cs b/src/libraries/Common/src/System/Security/Cryptography/MLKemCng.cs index 0af40a873709da..f99549aad6df30 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLKemCng.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLKemCng.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; using System.Runtime.Versioning; +using Internal.Cryptography; namespace System.Security.Cryptography { @@ -22,7 +21,6 @@ namespace System.Security.Cryptography /// cryptographic libraries. /// /// - [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public sealed partial class MLKemCng : MLKem { private CngKey _key; @@ -51,12 +49,10 @@ public MLKemCng(CngKey key) : base(AlgorithmFromHandleWithPlatformCheck(key, out private static MLKemAlgorithm AlgorithmFromHandleWithPlatformCheck(CngKey key, out CngKey duplicateKey) { -#if !NETFRAMEWORK - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (!Helpers.IsOSPlatformWindows) { throw new PlatformNotSupportedException(); } -#endif return AlgorithmFromHandle(key, out duplicateKey); } diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLKemImplementation.Windows.cs b/src/libraries/Common/src/System/Security/Cryptography/MLKemImplementation.Windows.cs index db14a7d2abbbed..345beb64d6e249 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLKemImplementation.Windows.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLKemImplementation.Windows.cs @@ -3,8 +3,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; -using System.Text; using Internal.NativeCrypto; using Microsoft.Win32.SafeHandles; @@ -12,6 +10,7 @@ using KeyBlobMagicNumber = Interop.BCrypt.KeyBlobMagicNumber; using KeyBlobType = Interop.BCrypt.KeyBlobType; using BCRYPT_MLKEM_KEY_BLOB = Interop.BCrypt.BCRYPT_MLKEM_KEY_BLOB; +using Internal.Cryptography; namespace System.Security.Cryptography { @@ -139,12 +138,10 @@ protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out private static SafeBCryptAlgorithmHandle? OpenAlgorithmHandle() { -#if !NETFRAMEWORK - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (!Helpers.IsOSPlatformWindows) { return null; } -#endif NTSTATUS status = Interop.BCrypt.BCryptOpenAlgorithmProvider( out SafeBCryptAlgorithmHandle hAlgorithm, diff --git a/src/libraries/Common/src/System/Security/Cryptography/Oids.Shared.cs b/src/libraries/Common/src/System/Security/Cryptography/Oids.Shared.cs index 2f584a0bbfd7f8..8ff904d32edfe3 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Oids.Shared.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Oids.Shared.cs @@ -8,74 +8,41 @@ namespace System.Security.Cryptography { internal static partial class Oids { - private static Oid? s_rsaOid; - private static Oid? s_ecPublicKeyOid; - private static Oid? s_tripleDesCbcOid; - private static Oid? s_aes256CbcOid; - private static Oid? s_secp256R1Oid; - private static Oid? s_secp384R1Oid; - private static Oid? s_secp521R1Oid; - private static Oid? s_sha256Oid; - private static Oid? s_pkcs7DataOid; - private static Oid? s_contentTypeOid; - private static Oid? s_documentDescriptionOid; - private static Oid? s_documentNameOid; - private static Oid? s_localKeyIdOid; - private static Oid? s_messageDigestOid; - private static Oid? s_signingTimeOid; - private static Oid? s_pkcs9ExtensionRequestOid; - private static Oid? s_basicConstraints2Oid; - private static Oid? s_enhancedKeyUsageOid; - private static Oid? s_keyUsageOid; - private static Oid? s_subjectAltNameOid; - private static Oid? s_subjectKeyIdentifierOid; - private static Oid? s_authorityKeyIdentifierOid; - private static Oid? s_authorityInformationAccessOid; - private static Oid? s_crlNumberOid; - private static Oid? s_crlDistributionPointOid; - private static Oid? s_commonNameOid; - private static Oid? s_countryOrRegionOid; - private static Oid? s_localityNameOid; - private static Oid? s_stateOrProvinceNameOid; - private static Oid? s_organizationOid; - private static Oid? s_organizationalUnitOid; - private static Oid? s_emailAddressOid; - - internal static Oid RsaOid => s_rsaOid ??= InitializeOid(Rsa); - internal static Oid EcPublicKeyOid => s_ecPublicKeyOid ??= InitializeOid(EcPublicKey); - internal static Oid TripleDesCbcOid => s_tripleDesCbcOid ??= InitializeOid(TripleDesCbc); - internal static Oid Aes256CbcOid => s_aes256CbcOid ??= InitializeOid(Aes256Cbc); - internal static Oid secp256r1Oid => s_secp256R1Oid ??= new Oid(secp256r1, nameof(ECCurve.NamedCurves.nistP256)); - internal static Oid secp384r1Oid => s_secp384R1Oid ??= new Oid(secp384r1, nameof(ECCurve.NamedCurves.nistP384)); - internal static Oid secp521r1Oid => s_secp521R1Oid ??= new Oid(secp521r1, nameof(ECCurve.NamedCurves.nistP521)); - internal static Oid Sha256Oid => s_sha256Oid ??= InitializeOid(Sha256); - - internal static Oid Pkcs7DataOid => s_pkcs7DataOid ??= InitializeOid(Pkcs7Data); - internal static Oid ContentTypeOid => s_contentTypeOid ??= InitializeOid(ContentType); - internal static Oid DocumentDescriptionOid => s_documentDescriptionOid ??= InitializeOid(DocumentDescription); - internal static Oid DocumentNameOid => s_documentNameOid ??= InitializeOid(DocumentName); - internal static Oid LocalKeyIdOid => s_localKeyIdOid ??= InitializeOid(LocalKeyId); - internal static Oid MessageDigestOid => s_messageDigestOid ??= InitializeOid(MessageDigest); - internal static Oid SigningTimeOid => s_signingTimeOid ??= InitializeOid(SigningTime); - internal static Oid Pkcs9ExtensionRequestOid => s_pkcs9ExtensionRequestOid ??= InitializeOid(Pkcs9ExtensionRequest); - - internal static Oid BasicConstraints2Oid => s_basicConstraints2Oid ??= InitializeOid(BasicConstraints2); - internal static Oid EnhancedKeyUsageOid => s_enhancedKeyUsageOid ??= InitializeOid(EnhancedKeyUsage); - internal static Oid KeyUsageOid => s_keyUsageOid ??= InitializeOid(KeyUsage); - internal static Oid AuthorityKeyIdentifierOid => s_authorityKeyIdentifierOid ??= InitializeOid(AuthorityKeyIdentifier); - internal static Oid SubjectKeyIdentifierOid => s_subjectKeyIdentifierOid ??= InitializeOid(SubjectKeyIdentifier); - internal static Oid SubjectAltNameOid => s_subjectAltNameOid ??= InitializeOid(SubjectAltName); - internal static Oid AuthorityInformationAccessOid => s_authorityInformationAccessOid ??= InitializeOid(AuthorityInformationAccess); - internal static Oid CrlNumberOid => s_crlNumberOid ??= InitializeOid(CrlNumber); - internal static Oid CrlDistributionPointsOid => s_crlDistributionPointOid ??= InitializeOid(CrlDistributionPoints); - - internal static Oid CommonNameOid => s_commonNameOid ??= InitializeOid(CommonName); - internal static Oid CountryOrRegionNameOid => s_countryOrRegionOid ??= InitializeOid(CountryOrRegionName); - internal static Oid LocalityNameOid => s_localityNameOid ??= InitializeOid(LocalityName); - internal static Oid StateOrProvinceNameOid => s_stateOrProvinceNameOid ??= InitializeOid(StateOrProvinceName); - internal static Oid OrganizationOid => s_organizationOid ??= InitializeOid(Organization); - internal static Oid OrganizationalUnitOid => s_organizationalUnitOid ??= InitializeOid(OrganizationalUnit); - internal static Oid EmailAddressOid => s_emailAddressOid ??= InitializeOid(EmailAddress); + internal static Oid RsaOid => field ??= InitializeOid(Rsa); + internal static Oid EcPublicKeyOid => field ??= InitializeOid(EcPublicKey); + internal static Oid TripleDesCbcOid => field ??= InitializeOid(TripleDesCbc); + internal static Oid Aes256CbcOid => field ??= InitializeOid(Aes256Cbc); + internal static Oid secp256r1Oid => field ??= new Oid(secp256r1, nameof(ECCurve.NamedCurves.nistP256)); + internal static Oid secp384r1Oid => field ??= new Oid(secp384r1, nameof(ECCurve.NamedCurves.nistP384)); + internal static Oid secp521r1Oid => field ??= new Oid(secp521r1, nameof(ECCurve.NamedCurves.nistP521)); + internal static Oid Sha256Oid => field ??= InitializeOid(Sha256); + + internal static Oid Pkcs7DataOid => field ??= InitializeOid(Pkcs7Data); + internal static Oid ContentTypeOid => field ??= InitializeOid(ContentType); + internal static Oid DocumentDescriptionOid => field ??= InitializeOid(DocumentDescription); + internal static Oid DocumentNameOid => field ??= InitializeOid(DocumentName); + internal static Oid LocalKeyIdOid => field ??= InitializeOid(LocalKeyId); + internal static Oid MessageDigestOid => field ??= InitializeOid(MessageDigest); + internal static Oid SigningTimeOid => field ??= InitializeOid(SigningTime); + internal static Oid Pkcs9ExtensionRequestOid => field ??= InitializeOid(Pkcs9ExtensionRequest); + + internal static Oid BasicConstraints2Oid => field ??= InitializeOid(BasicConstraints2); + internal static Oid EnhancedKeyUsageOid => field ??= InitializeOid(EnhancedKeyUsage); + internal static Oid KeyUsageOid => field ??= InitializeOid(KeyUsage); + internal static Oid AuthorityKeyIdentifierOid => field ??= InitializeOid(AuthorityKeyIdentifier); + internal static Oid SubjectKeyIdentifierOid => field ??= InitializeOid(SubjectKeyIdentifier); + internal static Oid SubjectAltNameOid => field ??= InitializeOid(SubjectAltName); + internal static Oid AuthorityInformationAccessOid => field ??= InitializeOid(AuthorityInformationAccess); + internal static Oid CrlNumberOid => field ??= InitializeOid(CrlNumber); + internal static Oid CrlDistributionPointsOid => field ??= InitializeOid(CrlDistributionPoints); + + internal static Oid CommonNameOid => field ??= InitializeOid(CommonName); + internal static Oid CountryOrRegionNameOid => field ??= InitializeOid(CountryOrRegionName); + internal static Oid LocalityNameOid => field ??= InitializeOid(LocalityName); + internal static Oid StateOrProvinceNameOid => field ??= InitializeOid(StateOrProvinceName); + internal static Oid OrganizationOid => field ??= InitializeOid(Organization); + internal static Oid OrganizationalUnitOid => field ??= InitializeOid(OrganizationalUnit); + internal static Oid EmailAddressOid => field ??= InitializeOid(EmailAddress); private static Oid InitializeOid(string oidValue) { diff --git a/src/libraries/Common/src/System/Security/Cryptography/Oids.cs b/src/libraries/Common/src/System/Security/Cryptography/Oids.cs index d7dd37968b1849..10785201fde8ab 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Oids.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Oids.cs @@ -135,24 +135,24 @@ internal static partial class Oids internal const string Mgf1 = "1.2.840.113549.1.1.8"; internal const string PSpecified = "1.2.840.113549.1.1.9"; - internal const string MLDsa44WithRSA2048PssPreHashSha256 = "2.16.840.1.114027.80.9.0"; - internal const string MLDsa44WithRSA2048Pkcs15PreHashSha256 = "2.16.840.1.114027.80.9.1"; - internal const string MLDsa44WithEd25519PreHashSha512 = "2.16.840.1.114027.80.9.2"; - internal const string MLDsa44WithECDsaP256PreHashSha256 = "2.16.840.1.114027.80.9.3"; - internal const string MLDsa65WithRSA3072PssPreHashSha512 = "2.16.840.1.114027.80.9.4"; - internal const string MLDsa65WithRSA3072Pkcs15PreHashSha512 = "2.16.840.1.114027.80.9.5"; - internal const string MLDsa65WithRSA4096PssPreHashSha512 = "2.16.840.1.114027.80.9.6"; - internal const string MLDsa65WithRSA4096Pkcs15PreHashSha512 = "2.16.840.1.114027.80.9.7"; - internal const string MLDsa65WithECDsaP256PreHashSha512 = "2.16.840.1.114027.80.9.8"; - internal const string MLDsa65WithECDsaP384PreHashSha512 = "2.16.840.1.114027.80.9.9"; - internal const string MLDsa65WithECDsaBrainpoolP256r1PreHashSha512 = "2.16.840.1.114027.80.9.10"; - internal const string MLDsa65WithEd25519PreHashSha512 = "2.16.840.1.114027.80.9.11"; - internal const string MLDsa87WithECDsaP384PreHashSha512 = "2.16.840.1.114027.80.9.12"; - internal const string MLDsa87WithECDsaBrainpoolP384r1PreHashSha512 = "2.16.840.1.114027.80.9.13"; - internal const string MLDsa87WithEd448PreHashShake256_512 = "2.16.840.1.114027.80.9.14"; - internal const string MLDsa87WithRSA3072PssPreHashSha512 = "2.16.840.1.114027.80.9.15"; - internal const string MLDsa87WithRSA4096PssPreHashSha512 = "2.16.840.1.114027.80.9.16"; - internal const string MLDsa87WithECDsaP521PreHashSha512 = "2.16.840.1.114027.80.9.17"; + internal const string MLDsa44WithRSA2048PssPreHashSha256 = "2.16.840.1.114027.80.9.1.0"; + internal const string MLDsa44WithRSA2048Pkcs15PreHashSha256 = "2.16.840.1.114027.80.9.1.1"; + internal const string MLDsa44WithEd25519PreHashSha512 = "2.16.840.1.114027.80.9.1.2"; + internal const string MLDsa44WithECDsaP256PreHashSha256 = "2.16.840.1.114027.80.9.1.3"; + internal const string MLDsa65WithRSA3072PssPreHashSha512 = "2.16.840.1.114027.80.9.1.4"; + internal const string MLDsa65WithRSA3072Pkcs15PreHashSha512 = "2.16.840.1.114027.80.9.1.5"; + internal const string MLDsa65WithRSA4096PssPreHashSha512 = "2.16.840.1.114027.80.9.1.6"; + internal const string MLDsa65WithRSA4096Pkcs15PreHashSha512 = "2.16.840.1.114027.80.9.1.7"; + internal const string MLDsa65WithECDsaP256PreHashSha512 = "2.16.840.1.114027.80.9.1.8"; + internal const string MLDsa65WithECDsaP384PreHashSha512 = "2.16.840.1.114027.80.9.1.9"; + internal const string MLDsa65WithECDsaBrainpoolP256r1PreHashSha512 = "2.16.840.1.114027.80.9.1.10"; + internal const string MLDsa65WithEd25519PreHashSha512 = "2.16.840.1.114027.80.9.1.11"; + internal const string MLDsa87WithECDsaP384PreHashSha512 = "2.16.840.1.114027.80.9.1.12"; + internal const string MLDsa87WithECDsaBrainpoolP384r1PreHashSha512 = "2.16.840.1.114027.80.9.1.13"; + internal const string MLDsa87WithEd448PreHashShake256_512 = "2.16.840.1.114027.80.9.1.14"; + internal const string MLDsa87WithRSA3072PssPreHashSha512 = "2.16.840.1.114027.80.9.1.15"; + internal const string MLDsa87WithRSA4096PssPreHashSha512 = "2.16.840.1.114027.80.9.1.16"; + internal const string MLDsa87WithECDsaP521PreHashSha512 = "2.16.840.1.114027.80.9.1.17"; // PKCS#7 internal const string NoSignature = "1.3.6.1.5.5.7.6.2"; @@ -263,6 +263,9 @@ internal static partial class Oids internal const string secp384r1 = "1.3.132.0.34"; internal const string secp521r1 = "1.3.132.0.35"; + internal const string brainpoolP256r1 = "1.3.36.3.3.2.8.1.1.7"; + internal const string brainpoolP384r1 = "1.3.36.3.3.2.8.1.1.11"; + // LDAP internal const string DomainComponent = "0.9.2342.19200300.100.1.25"; diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs new file mode 100644 index 00000000000000..016082439bc35c --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs @@ -0,0 +1,172 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers; +using System.Formats.Asn1; +using System.Runtime.InteropServices; +using System.Security.Cryptography.Asn1; + +namespace System.Security.Cryptography +{ + internal static partial class RSAKeyFormatHelper + { + internal delegate TRet RSAParametersCallback(RSAParameters parameters); + + internal static unsafe TRet FromPkcs1PrivateKey( + ReadOnlySpan keyData, + RSAParametersCallback parametersReader, + bool pinAndClearParameters = true) + { + fixed (byte* ptr = &MemoryMarshal.GetReference(keyData)) + { + using (MemoryManager manager = new PointerMemoryManager(ptr, keyData.Length)) + { + return FromPkcs1PrivateKey(manager.Memory, parametersReader, pinAndClearParameters); + } + } + } + + internal static TRet FromPkcs1PrivateKey( + ReadOnlyMemory keyData, + RSAParametersCallback parametersReader, + bool pinAndClearParameters = true) + { + RSAPrivateKeyAsn key = RSAPrivateKeyAsn.Decode(keyData, AsnEncodingRules.BER); + + const int MaxSupportedVersion = 0; + + if (key.Version > MaxSupportedVersion) + { + throw new CryptographicException( + SR.Format( + SR.Cryptography_RSAPrivateKey_VersionTooNew, + key.Version, + MaxSupportedVersion)); + } + + // The modulus size determines the encoded output size of the CRT parameters. + byte[] n = key.Modulus.ToUnsignedIntegerBytes(); + int halfModulusLength = (n.Length + 1) / 2; + + RSAParameters parameters = new RSAParameters + { + Modulus = n, + Exponent = key.PublicExponent.ToUnsignedIntegerBytes(), + + D = new byte[n.Length], + P = new byte[halfModulusLength], + Q = new byte[halfModulusLength], + DP = new byte[halfModulusLength], + DQ = new byte[halfModulusLength], + InverseQ = new byte[halfModulusLength], + }; + + if (pinAndClearParameters) + { + using (PinAndClear.Track(parameters.D)) + using (PinAndClear.Track(parameters.P)) + using (PinAndClear.Track(parameters.Q)) + using (PinAndClear.Track(parameters.DP)) + using (PinAndClear.Track(parameters.DQ)) + using (PinAndClear.Track(parameters.InverseQ)) + { + return ExtractParametersWithCallback(parametersReader, ref key, ref parameters); + } + } + else + { + return ExtractParametersWithCallback(parametersReader, ref key, ref parameters); + } + + static TRet ExtractParametersWithCallback(RSAParametersCallback parametersReader, ref RSAPrivateKeyAsn key, ref RSAParameters parameters) + { + key.PrivateExponent.ToUnsignedIntegerBytes(parameters.D); + key.Prime1.ToUnsignedIntegerBytes(parameters.P); + key.Prime2.ToUnsignedIntegerBytes(parameters.Q); + key.Exponent1.ToUnsignedIntegerBytes(parameters.DP); + key.Exponent2.ToUnsignedIntegerBytes(parameters.DQ); + key.Coefficient.ToUnsignedIntegerBytes(parameters.InverseQ); + + return parametersReader(parameters); + } + } + + internal static unsafe TRet FromPkcs1PublicKey( + ReadOnlySpan keyData, + RSAParametersCallback parametersReader) + { + fixed (byte* ptr = &MemoryMarshal.GetReference(keyData)) + { + using (MemoryManager manager = new PointerMemoryManager(ptr, keyData.Length)) + { + return FromPkcs1PublicKey(manager.Memory, parametersReader); + } + } + } + + internal static TRet FromPkcs1PublicKey(ReadOnlyMemory keyData, RSAParametersCallback parametersReader) + { + RSAPublicKeyAsn key = RSAPublicKeyAsn.Decode(keyData, AsnEncodingRules.BER); + + RSAParameters parameters = new RSAParameters + { + Modulus = key.Modulus.ToUnsignedIntegerBytes(), + Exponent = key.PublicExponent.ToUnsignedIntegerBytes(), + }; + + return parametersReader(parameters); + } + + internal static AsnWriter WritePkcs1PublicKey(in RSAParameters rsaParameters) + { + if (rsaParameters.Modulus == null || rsaParameters.Exponent == null) + { + throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); + } + + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + writer.PushSequence(); + writer.WriteKeyParameterInteger(rsaParameters.Modulus); + writer.WriteKeyParameterInteger(rsaParameters.Exponent); + writer.PopSequence(); + + return writer; + } + + internal static AsnWriter WritePkcs1PrivateKey(in RSAParameters rsaParameters) + { + if (rsaParameters.Modulus == null || rsaParameters.Exponent == null) + { + throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); + } + + if (rsaParameters.D == null || + rsaParameters.P == null || + rsaParameters.Q == null || + rsaParameters.DP == null || + rsaParameters.DQ == null || + rsaParameters.InverseQ == null) + { + throw new CryptographicException(SR.Cryptography_NotValidPrivateKey); + } + + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + + writer.PushSequence(); + + // Format version 0 + writer.WriteInteger(0); + writer.WriteKeyParameterInteger(rsaParameters.Modulus); + writer.WriteKeyParameterInteger(rsaParameters.Exponent); + writer.WriteKeyParameterInteger(rsaParameters.D); + writer.WriteKeyParameterInteger(rsaParameters.P); + writer.WriteKeyParameterInteger(rsaParameters.Q); + writer.WriteKeyParameterInteger(rsaParameters.DP); + writer.WriteKeyParameterInteger(rsaParameters.DQ); + writer.WriteKeyParameterInteger(rsaParameters.InverseQ); + + writer.PopSequence(); + return writer; + } + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs index c77944c204c658..7f62903d67f0f1 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs @@ -20,39 +20,12 @@ internal static void FromPkcs1PrivateKey( in AlgorithmIdentifierAsn algId, out RSAParameters ret) { - RSAPrivateKeyAsn key = RSAPrivateKeyAsn.Decode(keyData, AsnEncodingRules.BER); - if (!algId.HasNullEquivalentParameters()) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } - const int MaxSupportedVersion = 0; - - if (key.Version > MaxSupportedVersion) - { - throw new CryptographicException( - SR.Format( - SR.Cryptography_RSAPrivateKey_VersionTooNew, - key.Version, - MaxSupportedVersion)); - } - - // The modulus size determines the encoded output size of the CRT parameters. - byte[] n = key.Modulus.ToByteArray(isUnsigned: true, isBigEndian: true); - int halfModulusLength = (n.Length + 1) / 2; - - ret = new RSAParameters - { - Modulus = n, - Exponent = key.PublicExponent.ToByteArray(isUnsigned: true, isBigEndian: true), - D = key.PrivateExponent.ExportKeyParameter(n.Length), - P = key.Prime1.ExportKeyParameter(halfModulusLength), - Q = key.Prime2.ExportKeyParameter(halfModulusLength), - DP = key.Exponent1.ExportKeyParameter(halfModulusLength), - DQ = key.Exponent2.ExportKeyParameter(halfModulusLength), - InverseQ = key.Coefficient.ExportKeyParameter(halfModulusLength), - }; + ret = FromPkcs1PrivateKey(keyData, rsaParameters => rsaParameters, pinAndClearParameters: false); } internal static void ReadRsaPublicKey( @@ -60,13 +33,7 @@ internal static void ReadRsaPublicKey( in AlgorithmIdentifierAsn algId, out RSAParameters ret) { - RSAPublicKeyAsn key = RSAPublicKeyAsn.Decode(keyData, AsnEncodingRules.BER); - - ret = new RSAParameters - { - Modulus = key.Modulus.ToByteArray(isUnsigned: true, isBigEndian: true), - Exponent = key.PublicExponent.ToByteArray(isUnsigned: true, isBigEndian: true), - }; + ret = FromPkcs1PublicKey(keyData, rsaParameters => rsaParameters); } internal static void ReadRsaPublicKey( @@ -131,19 +98,6 @@ internal static unsafe int CheckSubjectPublicKeyInfo(ReadOnlySpan source) return bytesRead; } - public static void ReadPkcs8( - ReadOnlySpan source, - out int bytesRead, - out RSAParameters key) - { - KeyFormatHelper.ReadPkcs8( - s_validOids, - source, - FromPkcs1PrivateKey, - out bytesRead, - out key); - } - internal static ReadOnlyMemory ReadPkcs8( ReadOnlyMemory source, out int bytesRead) @@ -254,57 +208,5 @@ private static void WriteAlgorithmIdentifier(AsnWriter writer) writer.PopSequence(); } - - internal static AsnWriter WritePkcs1PublicKey(in RSAParameters rsaParameters) - { - if (rsaParameters.Modulus == null || rsaParameters.Exponent == null) - { - throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); - } - - AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - writer.PushSequence(); - writer.WriteKeyParameterInteger(rsaParameters.Modulus); - writer.WriteKeyParameterInteger(rsaParameters.Exponent); - writer.PopSequence(); - - return writer; - } - - internal static AsnWriter WritePkcs1PrivateKey(in RSAParameters rsaParameters) - { - if (rsaParameters.Modulus == null || rsaParameters.Exponent == null) - { - throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); - } - - if (rsaParameters.D == null || - rsaParameters.P == null || - rsaParameters.Q == null || - rsaParameters.DP == null || - rsaParameters.DQ == null || - rsaParameters.InverseQ == null) - { - throw new CryptographicException(SR.Cryptography_NotValidPrivateKey); - } - - AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - - writer.PushSequence(); - - // Format version 0 - writer.WriteInteger(0); - writer.WriteKeyParameterInteger(rsaParameters.Modulus); - writer.WriteKeyParameterInteger(rsaParameters.Exponent); - writer.WriteKeyParameterInteger(rsaParameters.D); - writer.WriteKeyParameterInteger(rsaParameters.P); - writer.WriteKeyParameterInteger(rsaParameters.Q); - writer.WriteKeyParameterInteger(rsaParameters.DP); - writer.WriteKeyParameterInteger(rsaParameters.DQ); - writer.WriteKeyParameterInteger(rsaParameters.InverseQ); - - writer.PopSequence(); - return writer; - } } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdf.cs b/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdf.cs index 523f99be26051b..6ad21f7528bff5 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdf.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdf.cs @@ -542,7 +542,7 @@ private static void CheckHashAlgorithm(HashAlgorithmName hashAlgorithm) case HashAlgorithmNames.SHA384: case HashAlgorithmNames.SHA512: break; -#if NET8_0_OR_GREATER +#if NET case HashAlgorithmNames.SHA3_256: if (!HMACSHA3_256.IsSupported) { diff --git a/src/libraries/Common/src/System/Security/Cryptography/SlhDsa.cs b/src/libraries/Common/src/System/Security/Cryptography/SlhDsa.cs index 40f3057e88bb7f..c915248b1caa9b 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/SlhDsa.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/SlhDsa.cs @@ -14,10 +14,15 @@ namespace System.Security.Cryptography /// Represents an SLH-DSA key. /// /// - /// Developers are encouraged to program against the SlhDsa base class, - /// rather than any specific derived class. - /// The derived classes are intended for interop with the underlying system - /// cryptographic libraries. + /// + /// This algorithm is specified by FIPS-205. + /// + /// + /// Developers are encouraged to program against the base class, + /// rather than any specific derived class. + /// The derived classes are intended for interop with the underlying system + /// cryptographic libraries. + /// /// [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public abstract partial class SlhDsa : IDisposable @@ -62,9 +67,6 @@ protected SlhDsa(SlhDsaAlgorithm algorithm) Algorithm = algorithm; } - /// - /// Throws if the current instance is disposed. - /// private protected void ThrowIfDisposed() => ObjectDisposedException.ThrowIf(_disposed, typeof(SlhDsa)); /// @@ -328,7 +330,7 @@ public void SignPreHash(ReadOnlySpan hash, Span destination, string SR.Argument_SignatureContextTooLong255); } - ValidateHashAlgorithm(hash, hashAlgorithmOid); + Helpers.ValidateHashLength(hash, hashAlgorithmOid); ThrowIfDisposed(); SignPreHashCore(hash, context, hashAlgorithmOid, destination); @@ -426,7 +428,7 @@ public bool VerifyPreHash(ReadOnlySpan hash, ReadOnlySpan signature, SR.Argument_SignatureContextTooLong255); } - ValidateHashAlgorithm(hash, hashAlgorithmOid); + Helpers.ValidateHashLength(hash, hashAlgorithmOid); ThrowIfDisposed(); if (signature.Length != Algorithm.SignatureSizeInBytes) @@ -614,8 +616,8 @@ public bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritte 3 + // Version Integer 2 + // AlgorithmIdentifier Sequence 3 + // AlgorithmIdentifier OID value, undervalued to be safe - 2 + // Secret key Octet String prefix, undervalued to be safe - Algorithm.SecretKeySizeInBytes; + 2 + // Private key Octet String prefix, undervalued to be safe + Algorithm.PrivateKeySizeInBytes; if (destination.Length < MinimumPossiblePkcs8SlhDsaKey) { @@ -648,19 +650,19 @@ public bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritte /// protected virtual bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) { - // Secret key size for SLH-DSA is at most 128 bytes so we can stack allocate it. - int secretKeySizeInBytes = Algorithm.SecretKeySizeInBytes; - Debug.Assert(secretKeySizeInBytes is <= 128); - Span secretKey = (stackalloc byte[128])[..secretKeySizeInBytes]; + // Private key size for SLH-DSA is at most 128 bytes so we can stack allocate it. + int privateKeySizeInBytes = Algorithm.PrivateKeySizeInBytes; + Debug.Assert(privateKeySizeInBytes is <= 128); + Span privateKey = (stackalloc byte[128])[..privateKeySizeInBytes]; try { - ExportSlhDsaSecretKey(secretKey); + ExportSlhDsaPrivateKey(privateKey); // The ASN.1 overhead of a PrivateKeyInfo encoding a private key is 22 bytes. // Round it off to 32. This checked operation should never throw because the inputs are not // user provided. - int capacity = checked(32 + secretKeySizeInBytes); + int capacity = checked(32 + privateKeySizeInBytes); AsnWriter writer = new AsnWriter(AsnEncodingRules.DER, capacity); using (writer.PushSequence()) @@ -672,7 +674,7 @@ protected virtual bool TryExportPkcs8PrivateKeyCore(Span destination, out writer.WriteObjectIdentifier(Algorithm.Oid); } - writer.WriteOctetString(secretKey); + writer.WriteOctetString(privateKey); } Debug.Assert(writer.GetEncodedLength() <= capacity); @@ -680,7 +682,7 @@ protected virtual bool TryExportPkcs8PrivateKeyCore(Span destination, out } finally { - CryptographicOperations.ZeroMemory(secretKey); + CryptographicOperations.ZeroMemory(privateKey); } } @@ -1106,55 +1108,55 @@ public byte[] ExportSlhDsaPublicKey() } /// - /// Exports the current key in the FIPS 205 secret key format. + /// Exports the current key in the FIPS 205 private key format. /// /// - /// The buffer to receive the secret key. Its length must be exactly - /// . + /// The buffer to receive the private key. Its length must be exactly + /// . /// /// - /// is the incorrect length to receive the secret key. + /// is the incorrect length to receive the private key. /// /// - /// The current instance cannot export a secret key. + /// The current instance cannot export a private key. /// -or- /// An error occurred while exporting the key. /// /// The object has already been disposed. - public void ExportSlhDsaSecretKey(Span destination) + public void ExportSlhDsaPrivateKey(Span destination) { - int secretKeySizeInBytes = Algorithm.SecretKeySizeInBytes; + int privateKeySizeInBytes = Algorithm.PrivateKeySizeInBytes; - if (destination.Length != secretKeySizeInBytes) + if (destination.Length != privateKeySizeInBytes) { throw new ArgumentException( - SR.Format(SR.Argument_DestinationImprecise, secretKeySizeInBytes), + SR.Format(SR.Argument_DestinationImprecise, privateKeySizeInBytes), nameof(destination)); } ThrowIfDisposed(); - ExportSlhDsaSecretKeyCore(destination); + ExportSlhDsaPrivateKeyCore(destination); } /// - /// Exports the current key in the FIPS 205 secret key format. + /// Exports the current key in the FIPS 205 private key format. /// /// - /// The FIPS 205 secret key. + /// The FIPS 205 private key. /// /// - /// The current instance cannot export a secret key. + /// The current instance cannot export a private key. /// -or- /// An error occurred while exporting the key. /// /// The object has already been disposed. - public byte[] ExportSlhDsaSecretKey() + public byte[] ExportSlhDsaPrivateKey() { ThrowIfDisposed(); - byte[] destination = new byte[Algorithm.SecretKeySizeInBytes]; - ExportSlhDsaSecretKeyCore(destination); + byte[] destination = new byte[Algorithm.PrivateKeySizeInBytes]; + ExportSlhDsaPrivateKeyCore(destination); return destination; } @@ -1291,12 +1293,12 @@ public static SlhDsa ImportPkcs8PrivateKey(ReadOnlySpan source) SlhDsaAlgorithm info = GetAlgorithmIdentifier(in algId); ReadOnlySpan privateKey = key.Span; - if (privateKey.Length != info.SecretKeySizeInBytes) + if (privateKey.Length != info.PrivateKeySizeInBytes) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } - ret = ImportSlhDsaSecretKey(info, key.Span); + ret = ImportSlhDsaPrivateKey(info, key.Span); }, out int read, out SlhDsa slhDsa); @@ -1702,13 +1704,13 @@ public static SlhDsa ImportSlhDsaPublicKey(SlhDsaAlgorithm algorithm, byte[] sou } /// - /// Imports an SLH-DSA private key in the FIPS 205 secret key format. + /// Imports an SLH-DSA private key in the FIPS 205 private key format. /// /// /// The specific SLH-DSA algorithm for this key. /// /// - /// The bytes of a FIPS 205 secret key. + /// The bytes of a FIPS 205 private key. /// /// /// The imported key. @@ -1726,29 +1728,29 @@ public static SlhDsa ImportSlhDsaPublicKey(SlhDsaAlgorithm algorithm, byte[] sou /// The platform does not support SLH-DSA. Callers can use the property /// to determine if the platform supports SLH-DSA. /// - public static SlhDsa ImportSlhDsaSecretKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) + public static SlhDsa ImportSlhDsaPrivateKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) { ArgumentNullException.ThrowIfNull(algorithm); - if (source.Length != algorithm.SecretKeySizeInBytes) + if (source.Length != algorithm.PrivateKeySizeInBytes) { - throw new ArgumentException(SR.Argument_SecretKeyWrongSizeForAlgorithm, nameof(source)); + throw new ArgumentException(SR.Argument_PrivateKeyWrongSizeForAlgorithm, nameof(source)); } ThrowIfNotSupported(); - return SlhDsaImplementation.ImportSecretKey(algorithm, source); + return SlhDsaImplementation.ImportPrivateKey(algorithm, source); } - /// + /// /// /// or is . /// - public static SlhDsa ImportSlhDsaSecretKey(SlhDsaAlgorithm algorithm, byte[] source) + public static SlhDsa ImportSlhDsaPrivateKey(SlhDsaAlgorithm algorithm, byte[] source) { ArgumentNullException.ThrowIfNull(source); - return ImportSlhDsaSecretKey(algorithm, new ReadOnlySpan(source)); + return ImportSlhDsaPrivateKey(algorithm, new ReadOnlySpan(source)); } /// @@ -1854,12 +1856,12 @@ protected virtual void Dispose(bool disposing) protected abstract void ExportSlhDsaPublicKeyCore(Span destination); /// - /// When overridden in a derived class, exports the FIPS 205 secret key to the specified buffer. + /// When overridden in a derived class, exports the FIPS 205 private key to the specified buffer. /// /// - /// The buffer to receive the secret key. + /// The buffer to receive the private key. /// - protected abstract void ExportSlhDsaSecretKeyCore(Span destination); + protected abstract void ExportSlhDsaPrivateKeyCore(Span destination); private AsnWriter ExportSubjectPublicKeyInfoCore() { @@ -1950,7 +1952,7 @@ private TResult ExportPkcs8PrivateKeyCallback(ExportPkcs8PrivateKeyFunc { // A PKCS#8 SLH-DSA-SHA2-256s private key has an ASN.1 overhead of 22 bytes, assuming no attributes. // Make it an even 32 and that should give a good starting point for a buffer size. - int size = Algorithm.SecretKeySizeInBytes + 32; + int size = Algorithm.PrivateKeySizeInBytes + 32; // The buffer is only being passed out as a span, so the derived type can't meaningfully // hold on to it without being malicious. byte[] buffer = CryptoPool.Rent(size); @@ -1995,48 +1997,6 @@ private static SlhDsaAlgorithm GetAlgorithmIdentifier(ref readonly AlgorithmIden return algorithm; } - private static void ValidateHashAlgorithm(ReadOnlySpan hash, ReadOnlySpan hashAlgorithmOid) - { - int? outputSize = hashAlgorithmOid switch - { - Oids.Md5 => 128 / 8, - Oids.Sha1 => 160 / 8, - Oids.Sha256 => 256 / 8, - Oids.Sha384 => 384 / 8, - Oids.Sha512 => 512 / 8, - Oids.Sha3_256 => 256 / 8, - Oids.Sha3_384 => 384 / 8, - Oids.Sha3_512 => 512 / 8, - Oids.Shake128 => 256 / 8, - Oids.Shake256 => 512 / 8, - _ => null, - }; - - if (outputSize is not null) - { - if (hash.Length != outputSize) - { - throw new CryptographicException(SR.Cryptography_HashLengthMismatch); - } - } - else - { - // The OIDs for the algorithms above have max length 11. We'll just round up for a conservative initial estimate. - const int MaxEncodedOidLengthForCommonHashAlgorithms = 16; - AsnWriter writer = new AsnWriter(AsnEncodingRules.DER, MaxEncodedOidLengthForCommonHashAlgorithms); - - try - { - // Only the format of the OID is validated here. The derived classes can decide to do more if they want to. - writer.WriteObjectIdentifier(hashAlgorithmOid); - } - catch (ArgumentException ae) - { - throw new CryptographicException(SR.Cryptography_HashLengthMismatch, ae); - } - } - } - private static void ThrowIfNotSupported() { if (!IsSupported) diff --git a/src/libraries/Common/src/System/Security/Cryptography/SlhDsaAlgorithm.cs b/src/libraries/Common/src/System/Security/Cryptography/SlhDsaAlgorithm.cs index 987e92e1767dbd..4d5b261c64863b 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/SlhDsaAlgorithm.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/SlhDsaAlgorithm.cs @@ -22,12 +22,12 @@ public sealed class SlhDsaAlgorithm : IEquatable public string Name { get; } /// - /// Gets the size of the secret key in bytes for this algorithm. + /// Gets the size of the private key in bytes for this algorithm. /// /// - /// The size of the secret key in bytes for this algorithm. + /// The size of the private key in bytes for this algorithm. /// - public int SecretKeySizeInBytes { get; } + public int PrivateKeySizeInBytes { get; } /// /// Gets the size of the public key in bytes for this algorithm. @@ -72,9 +72,9 @@ private SlhDsaAlgorithm(string name, int n, int signatureSizeInBytes, string oid { Name = name; - // The secret key and public key sizes are shown to be 4n and 2n respectively in + // The private key and public key sizes are shown to be 4n and 2n respectively in // section 9.1 "Key Generation", particularly figure 15 and 16. - SecretKeySizeInBytes = 4 * n; + PrivateKeySizeInBytes = 4 * n; PublicKeySizeInBytes = 2 * n; SignatureSizeInBytes = signatureSizeInBytes; Oid = oid; diff --git a/src/libraries/Common/src/System/Security/Cryptography/SlhDsaCng.cs b/src/libraries/Common/src/System/Security/Cryptography/SlhDsaCng.cs new file mode 100644 index 00000000000000..3c0511d16907f5 --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/SlhDsaCng.cs @@ -0,0 +1,92 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.Versioning; + +namespace System.Security.Cryptography +{ + /// + /// Provides a Cryptography Next Generation (CNG) implementation of the Stateless Hash-Based Digital Signature + /// Algorithm (SLH-DSA). + /// + /// + /// + /// This algorithm is specified by FIPS-205. + /// + /// + /// Developers are encouraged to program against the base class, + /// rather than any specific derived class. + /// The derived classes are intended for interop with the underlying system + /// cryptographic libraries. + /// + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public sealed partial class SlhDsaCng : SlhDsa + { + /// + /// Initializes a new instance of the class by using the specified . + /// + /// + /// The key that will be used as input to the cryptographic operations performed by the current object. + /// + /// + /// is . + /// + /// + /// does not specify a Stateless Hash-Based Digital Signature Algorithm (SLH-DSA) group. + /// + /// + /// Cryptography Next Generation (CNG) classes are not supported on this system. + /// + [SupportedOSPlatform("windows")] + public SlhDsaCng(CngKey key) : base(SlhDsaAlgorithm.SlhDsaShake256f) // We need to pass something to the base so we can throw PNSE. + { + ArgumentNullException.ThrowIfNull(key); + throw new PlatformNotSupportedException(); + } + + /// + /// Gets a new representing the key used by the current instance. + /// + /// + /// This instance has been disposed. + /// + /// + /// This object is not the same as the one passed to , + /// if that constructor was used. However, it will point to the same CNG key. + /// + public CngKey GetKey() + { + throw new PlatformNotSupportedException(); + } + + /// + protected override void SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) => + throw new PlatformNotSupportedException(); + + /// + protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + throw new PlatformNotSupportedException(); + + /// + protected override void SignPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => + throw new PlatformNotSupportedException(); + + /// + protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => + throw new PlatformNotSupportedException(); + + /// + protected override void ExportSlhDsaPublicKeyCore(Span destination) => + throw new PlatformNotSupportedException(); + + /// + protected override void ExportSlhDsaPrivateKeyCore(Span destination) => + throw new PlatformNotSupportedException(); + + /// + protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) => + throw new PlatformNotSupportedException(); + } +} diff --git a/src/libraries/Common/src/System/Security/Cryptography/SlhDsaImplementation.NotSupported.cs b/src/libraries/Common/src/System/Security/Cryptography/SlhDsaImplementation.NotSupported.cs index a28ee9db020821..4a220cf7f0e332 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/SlhDsaImplementation.NotSupported.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/SlhDsaImplementation.NotSupported.cs @@ -32,7 +32,7 @@ protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan< protected override void ExportSlhDsaPublicKeyCore(Span destination) => throw new PlatformNotSupportedException(); - protected override void ExportSlhDsaSecretKeyCore(Span destination) => + protected override void ExportSlhDsaPrivateKeyCore(Span destination) => throw new PlatformNotSupportedException(); protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) => @@ -44,7 +44,7 @@ internal static partial SlhDsaImplementation ImportPublicKey(SlhDsaAlgorithm alg internal static partial SlhDsaImplementation ImportPkcs8PrivateKeyValue(SlhDsaAlgorithm algorithm, ReadOnlySpan source) => throw new PlatformNotSupportedException(); - internal static partial SlhDsaImplementation ImportSecretKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) => + internal static partial SlhDsaImplementation ImportPrivateKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) => throw new PlatformNotSupportedException(); } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/SlhDsaImplementation.Windows.cs b/src/libraries/Common/src/System/Security/Cryptography/SlhDsaImplementation.Windows.cs index 5e4f3808ad3f67..ad5ffc5c95a03a 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/SlhDsaImplementation.Windows.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/SlhDsaImplementation.Windows.cs @@ -32,7 +32,7 @@ protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan< protected override void ExportSlhDsaPublicKeyCore(Span destination) => throw new PlatformNotSupportedException(); - protected override void ExportSlhDsaSecretKeyCore(Span destination) => + protected override void ExportSlhDsaPrivateKeyCore(Span destination) => throw new PlatformNotSupportedException(); protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) => @@ -44,7 +44,7 @@ internal static partial SlhDsaImplementation ImportPublicKey(SlhDsaAlgorithm alg internal static partial SlhDsaImplementation ImportPkcs8PrivateKeyValue(SlhDsaAlgorithm algorithm, ReadOnlySpan source) => throw new PlatformNotSupportedException(); - internal static partial SlhDsaImplementation ImportSecretKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) => + internal static partial SlhDsaImplementation ImportPrivateKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) => throw new PlatformNotSupportedException(); } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/SlhDsaImplementation.cs b/src/libraries/Common/src/System/Security/Cryptography/SlhDsaImplementation.cs index 3f655e57815a05..80b5c95ce9f1c8 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/SlhDsaImplementation.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/SlhDsaImplementation.cs @@ -14,7 +14,7 @@ internal sealed partial class SlhDsaImplementation : SlhDsa internal static partial SlhDsaImplementation GenerateKeyCore(SlhDsaAlgorithm algorithm); internal static partial SlhDsaImplementation ImportPublicKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source); internal static partial SlhDsaImplementation ImportPkcs8PrivateKeyValue(SlhDsaAlgorithm algorithm, ReadOnlySpan source); - internal static partial SlhDsaImplementation ImportSecretKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source); + internal static partial SlhDsaImplementation ImportPrivateKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source); /// /// Duplicates an SLH-DSA private key by export/import. @@ -23,14 +23,14 @@ internal sealed partial class SlhDsaImplementation : SlhDsa internal static SlhDsaImplementation DuplicatePrivateKey(SlhDsa key) { Debug.Assert(key is not SlhDsaImplementation); - Debug.Assert(key.Algorithm.SecretKeySizeInBytes <= 128); + Debug.Assert(key.Algorithm.PrivateKeySizeInBytes <= 128); - Span secretKey = (stackalloc byte[128])[..key.Algorithm.SecretKeySizeInBytes]; - key.ExportSlhDsaSecretKey(secretKey); + Span secretKey = (stackalloc byte[128])[..key.Algorithm.PrivateKeySizeInBytes]; + key.ExportSlhDsaPrivateKey(secretKey); try { - return ImportSecretKey(key.Algorithm, secretKey); + return ImportPrivateKey(key.Algorithm, secretKey); } finally { diff --git a/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/CertificateHelpers.Windows.cs b/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/CertificateHelpers.Windows.cs new file mode 100644 index 00000000000000..06b4f618a49d95 --- /dev/null +++ b/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/CertificateHelpers.Windows.cs @@ -0,0 +1,333 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; + +#if SYSTEM_SECURITY_CRYPTOGRAPHY +using TCertificate = System.Security.Cryptography.X509Certificates.CertificatePal; +#else +using TCertificate = System.Security.Cryptography.X509Certificates.X509Certificate2; +#endif + +namespace System.Security.Cryptography.X509Certificates +{ + internal static partial class CertificateHelpers + { + private static partial CryptographicException GetExceptionForLastError(); + + private static partial SafeNCryptKeyHandle CreateSafeNCryptKeyHandle(IntPtr handle, SafeHandle parentHandle); + + private static partial TCertificate CopyFromRawBytes(TCertificate certificate); + + private static partial int GuessKeySpec(CngProvider provider, string keyName, bool machineKey, CngAlgorithmGroup? algorithmGroup); + +#if !SYSTEM_SECURITY_CRYPTOGRAPHY + [SupportedOSPlatform("windows")] +#endif + internal static TCertificate CopyWithPrivateKey(TCertificate certificate, MLDsa privateKey) + { + if (privateKey is MLDsaCng mldsaCng) + { + CngKey key = mldsaCng.KeyNoDuplicate; + + TCertificate? clone = CopyWithPersistedCngKey(certificate, key); + + if (clone is not null) + { + return clone; + } + } + + if (privateKey is MLDsaImplementation mldsaImplementation) + { + using (CngKey clonedKey = mldsaImplementation.CreateEphemeralCng()) + { + return CopyWithEphemeralKey(certificate, clonedKey); + } + } + + // MLDsaCng and third-party implementations can be copied by exporting the PKCS#8 and importing it into + // a new MLDsaCng. An alternative to PKCS#8 would be to try the private seed and fall back to private key, + // but that potentially requires two calls and wouldn't allow implementations to do anything smarter internally. + // Blobs may also be an option for MLDsaCng, but for now we will stick with PKCS#8. + byte[] exportedPkcs8 = privateKey.ExportPkcs8PrivateKey(); + + using (PinAndClear.Track(exportedPkcs8)) + using (MLDsaCng clonedKey = MLDsaCng.ImportPkcs8PrivateKey(exportedPkcs8, out _)) + { + CngKey clonedCngKey = clonedKey.KeyNoDuplicate; + + if (clonedCngKey.AlgorithmGroup != CngAlgorithmGroup.MLDsa) + { + Debug.Fail($"{nameof(MLDsaCng)} should only give ML-DSA keys."); + throw new CryptographicException(); + } + + return CopyWithEphemeralKey(certificate, clonedCngKey); + } + } + + [SupportedOSPlatform("windows")] + internal static T? GetPrivateKey(TCertificate certificate, Func createCsp, Func createCng) + where T : class, IDisposable + { + using (SafeCertContextHandle certContext = Interop.Crypt32.CertDuplicateCertificateContext(certificate.Handle)) + { + SafeNCryptKeyHandle? ncryptKey = TryAcquireCngPrivateKey(certContext, out CngKeyHandleOpenOptions cngHandleOptions); + if (ncryptKey != null) + { +#if SYSTEM_SECURITY_CRYPTOGRAPHY + CngKey cngKey = CngKey.OpenNoDuplicate(ncryptKey, cngHandleOptions); +#else + CngKey cngKey = CngKey.Open(ncryptKey, cngHandleOptions); +#endif + T? result = createCng(cngKey); + + // Dispose of cngKey if its ownership did not transfer to the underlying algorithm. + if (result is null) + { + cngKey.Dispose(); + } + + return result; + } + + CspParameters? cspParameters = GetPrivateKeyCsp(certContext); + if (cspParameters == null) + return null; + + if (cspParameters.ProviderType == 0) + { + // ProviderType being 0 signifies that this is actually a CNG key, not a CAPI key. Crypt32.dll stuffs the CNG Key Storage Provider + // name into CRYPT_KEY_PROV_INFO->ProviderName, and the CNG key name into CRYPT_KEY_PROV_INFO->KeyContainerName. + + string keyStorageProvider = cspParameters.ProviderName!; + string keyName = cspParameters.KeyContainerName!; + CngKey cngKey = CngKey.Open(keyName, new CngProvider(keyStorageProvider)); + return createCng(cngKey); + } + else + { + // ProviderType being non-zero signifies that this is a CAPI key. + // We never want to stomp over certificate private keys. + cspParameters.Flags |= CspProviderFlags.UseExistingKey; + return createCsp(cspParameters); + } + } + } + +#if !SYSTEM_SECURITY_CRYPTOGRAPHY + [SupportedOSPlatform("windows")] +#endif + private static SafeNCryptKeyHandle? TryAcquireCngPrivateKey( + SafeCertContextHandle certificateContext, + out CngKeyHandleOpenOptions handleOptions) + { + Debug.Assert(certificateContext != null); + Debug.Assert(!certificateContext.IsClosed && !certificateContext.IsInvalid); + + // If the certificate has a key handle without a key prov info, return the + // ephemeral key + if (!certificateContext.HasPersistedPrivateKey) + { + int cbData = IntPtr.Size; + + if (Interop.Crypt32.CertGetCertificateContextProperty( + certificateContext, + Interop.Crypt32.CertContextPropId.CERT_NCRYPT_KEY_HANDLE_PROP_ID, + out IntPtr privateKeyPtr, + ref cbData)) + { + handleOptions = CngKeyHandleOpenOptions.EphemeralKey; + return CreateSafeNCryptKeyHandle(privateKeyPtr, certificateContext); + } + } + + bool freeKey = true; + SafeNCryptKeyHandle? privateKey = null; + handleOptions = CngKeyHandleOpenOptions.None; + try + { + if (!Interop.Crypt32.CryptAcquireCertificatePrivateKey( + certificateContext, + Interop.Crypt32.CryptAcquireCertificatePrivateKeyFlags.CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, + IntPtr.Zero, + out privateKey, + out Interop.Crypt32.CryptKeySpec _, + out freeKey)) + { + + // The documentation for CryptAcquireCertificatePrivateKey says that freeKey + // should already be false if "key acquisition fails", and it can be presumed + // that privateKey was set to 0. But, just in case: + freeKey = false; + privateKey?.SetHandleAsInvalid(); + return null; + } + + // It is very unlikely that Windows will tell us !freeKey other than when reporting failure, + // because we set neither CRYPT_ACQUIRE_CACHE_FLAG nor CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, which are + // currently the only two success situations documented. However, any !freeKey response means the + // key's lifetime is tied to that of the certificate, so re-register the handle as a child handle + // of the certificate. + if (!freeKey && privateKey != null && !privateKey.IsInvalid) + { + SafeNCryptKeyHandle newKeyHandle = CreateSafeNCryptKeyHandle(privateKey.DangerousGetHandle(), certificateContext); + privateKey.SetHandleAsInvalid(); + privateKey = newKeyHandle; + freeKey = true; + } + + return privateKey; + } + catch + { + // If we aren't supposed to free the key, and we're not returning it, + // just tell the SafeHandle to not free itself. + if (privateKey != null && !freeKey) + { + privateKey.SetHandleAsInvalid(); + } + + throw; + } + } + + // + // Returns the private key referenced by a store certificate. Note that despite the return type being declared "CspParameters", + // the key can actually be a CNG key. To distinguish, examine the ProviderType property. If it is 0, this key is a CNG key with + // the various properties of CspParameters being "repurposed" into storing CNG info. + // + // This is a behavior this method inherits directly from the Crypt32 CRYPT_KEY_PROV_INFO semantics. + // + // It would have been nice not to let this ugliness escape out of this helper method. But X509Certificate2.ToString() calls this + // method too so we cannot just change it without breaking its output. + // +#if !SYSTEM_SECURITY_CRYPTOGRAPHY + [SupportedOSPlatform("windows")] +#endif + internal static CspParameters? GetPrivateKeyCsp(SafeCertContextHandle hCertContext) + { + int cbData = 0; + if (!Interop.Crypt32.CertGetCertificateContextProperty(hCertContext, Interop.Crypt32.CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, null, ref cbData)) + { +#if NETFRAMEWORK + int dwErrorCode = Marshal.GetHRForLastWin32Error(); +#else + int dwErrorCode = Marshal.GetLastPInvokeError(); +#endif + if (dwErrorCode == ErrorCode.CRYPT_E_NOT_FOUND) + return null; + throw dwErrorCode.ToCryptographicException(); + } + + unsafe + { + byte[] privateKey = new byte[cbData]; + fixed (byte* pPrivateKey = privateKey) + { + if (!Interop.Crypt32.CertGetCertificateContextProperty(hCertContext, Interop.Crypt32.CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, privateKey, ref cbData)) + throw GetExceptionForLastError(); + Interop.Crypt32.CRYPT_KEY_PROV_INFO* pKeyProvInfo = (Interop.Crypt32.CRYPT_KEY_PROV_INFO*)pPrivateKey; + + return new CspParameters + { + ProviderName = Marshal.PtrToStringUni((IntPtr)(pKeyProvInfo->pwszProvName)), + KeyContainerName = Marshal.PtrToStringUni((IntPtr)(pKeyProvInfo->pwszContainerName)), + ProviderType = pKeyProvInfo->dwProvType, + KeyNumber = pKeyProvInfo->dwKeySpec, + Flags = (pKeyProvInfo->dwFlags & Interop.Crypt32.CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET) == Interop.Crypt32.CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET ? CspProviderFlags.UseMachineKeyStore : 0, + }; + } + } + } + +#if !SYSTEM_SECURITY_CRYPTOGRAPHY + [UnsupportedOSPlatform("browser")] +#endif + internal static unsafe TCertificate? CopyWithPersistedCngKey(TCertificate certificate, CngKey cngKey) + { + if (string.IsNullOrEmpty(cngKey.KeyName)) + { + return null; + } + + // Make a new pal from bytes. + TCertificate newCert = CopyFromRawBytes(certificate); + + CngProvider provider = cngKey.Provider!; + string keyName = cngKey.KeyName; + bool machineKey = cngKey.IsMachineKey; + + // CAPI RSA_SIGN keys won't open correctly under CNG without the key number being specified, so + // check to see if we can figure out what key number it needs to re-open. + int keySpec = GuessKeySpec(provider, keyName, machineKey, cngKey.AlgorithmGroup); + + Interop.Crypt32.CRYPT_KEY_PROV_INFO keyProvInfo = default; + + fixed (char* keyNamePtr = cngKey.KeyName) + fixed (char* provNamePtr = cngKey.Provider!.Provider) + { + keyProvInfo.pwszContainerName = keyNamePtr; + keyProvInfo.pwszProvName = provNamePtr; + keyProvInfo.dwFlags = machineKey ? Interop.Crypt32.CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET : 0; + keyProvInfo.dwKeySpec = keySpec; + + if (!Interop.Crypt32.CertSetCertificateContextProperty( + newCert.Handle, + Interop.Crypt32.CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, + Interop.Crypt32.CertSetPropertyFlags.None, + &keyProvInfo)) + { + Exception e = GetExceptionForLastError(); + newCert.Dispose(); + throw e; + } + } + + return newCert; + } + +#if !SYSTEM_SECURITY_CRYPTOGRAPHY + [UnsupportedOSPlatform("browser")] +#endif + internal static TCertificate CopyWithEphemeralKey(TCertificate certificate, CngKey cngKey) + { + Debug.Assert(string.IsNullOrEmpty(cngKey.KeyName)); + + // Handle makes a copy of the handle. This is required given that CertSetCertificateContextProperty accepts a SafeHandle + // and transfers ownership of the handle to the certificate. We can't transfer that ownership out of the cngKey, as it's + // owned by the caller, so we make a copy. + using (SafeNCryptKeyHandle handle = cngKey.Handle) + { + // Make a new certificate from bytes. + TCertificate newCert = CopyFromRawBytes(certificate); + try + { + if (!Interop.Crypt32.CertSetCertificateContextProperty( + newCert.Handle, + Interop.Crypt32.CertContextPropId.CERT_NCRYPT_KEY_HANDLE_PROP_ID, + Interop.Crypt32.CertSetPropertyFlags.CERT_SET_PROPERTY_INHIBIT_PERSIST_FLAG, + handle)) + { + throw GetExceptionForLastError(); + } + + // The value was transferred to the certificate. + handle.SetHandleAsInvalid(); + + return newCert; + } + catch + { + newCert.Dispose(); + throw; + } + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ErrorCode.cs b/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/ErrorCode.cs similarity index 100% rename from src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ErrorCode.cs rename to src/libraries/Common/src/System/Security/Cryptography/X509Certificates/ErrorCode.cs diff --git a/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/Pkcs12LoaderLimits.cs b/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/Pkcs12LoaderLimits.cs index 678e8ea6d78a34..c9c0a6a6f772d8 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/Pkcs12LoaderLimits.cs +++ b/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/libraries/Common/tests/Extensions/TypeNameHelperTest.cs b/src/libraries/Common/tests/Extensions/TypeNameHelperTest.cs index a187cfd4888a77..54f4d29387849e 100644 --- a/src/libraries/Common/tests/Extensions/TypeNameHelperTest.cs +++ b/src/libraries/Common/tests/Extensions/TypeNameHelperTest.cs @@ -176,7 +176,7 @@ public void Can_pretty_print_open_generics(Type type, bool fullName, string expe Assert.Equal(expected, TypeNameHelper.GetTypeDisplayName(type, fullName)); } - public static TheoryData GetTypeDisplayName_IncludesGenericParameterNamesWhenOptionIsSetData => + public static TheoryData GetTypeDisplayName_IncludesGenericParameterNamesWhenOptionIsSetData => new TheoryData { { typeof(B<>),"Microsoft.Extensions.Internal.TypeNameHelperTest+B" }, @@ -196,7 +196,7 @@ public void GetTypeDisplayName_IncludesGenericParameterNamesWhenOptionIsSet(Type Assert.Equal(expected, actual); } - public static TheoryData GetTypeDisplayName_WithoutFullName_IncludesGenericParameterNamesWhenOptionIsSetData => + public static TheoryData GetTypeDisplayName_WithoutFullName_IncludesGenericParameterNamesWhenOptionIsSetData => new TheoryData { { typeof(B<>),"B" }, diff --git a/src/libraries/Common/tests/System/Collections/IEnumerableTest.cs b/src/libraries/Common/tests/System/Collections/IEnumerableTest.cs index a52bae97e4eceb..ccf2a1d5c69d9f 100644 --- a/src/libraries/Common/tests/System/Collections/IEnumerableTest.cs +++ b/src/libraries/Common/tests/System/Collections/IEnumerableTest.cs @@ -20,6 +20,7 @@ public abstract class IEnumerableTest protected T DefaultValue => default(T); protected bool MoveNextAtEndThrowsOnModifiedCollection => true; + protected virtual bool CurrentAfterFullEnumerationThrows => true; protected virtual CollectionOrder CollectionOrder => CollectionOrder.Sequential; @@ -352,7 +353,7 @@ public void EnumeratePastEndThenModify() VerifyModifiedEnumerator( enumerator, DefaultValue, - false, + CurrentAfterFullEnumerationThrows, true); } diff --git a/src/libraries/Common/tests/System/MockType.cs b/src/libraries/Common/tests/System/MockType.cs index 4de0fed4077d1d..0e0870140a306a 100644 --- a/src/libraries/Common/tests/System/MockType.cs +++ b/src/libraries/Common/tests/System/MockType.cs @@ -86,7 +86,7 @@ internal class MockType : Type public override bool IsSecurityCritical => throw Unexpected; public override bool IsSecuritySafeCritical => throw Unexpected; public override bool IsSecurityTransparent => throw Unexpected; -#if NET8_0_OR_GREATER +#if NET [Obsolete("Formatter-based serialization is obsolete and should not be used.", DiagnosticId = "SYSLIB0050", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public override bool IsSerializable => throw Unexpected; diff --git a/src/libraries/Common/tests/System/Net/Configuration.WebSockets.cs b/src/libraries/Common/tests/System/Net/Configuration.WebSockets.cs index c5686be67b4ef9..fcd4f9faf743db 100644 --- a/src/libraries/Common/tests/System/Net/Configuration.WebSockets.cs +++ b/src/libraries/Common/tests/System/Net/Configuration.WebSockets.cs @@ -22,35 +22,13 @@ public static partial class WebSockets public static readonly Uri RemoteEchoHeadersServer = new Uri("ws://" + Host + "/" + EchoHeadersHandler); public static readonly Uri SecureRemoteEchoHeadersServer = new Uri("wss://" + SecureHost + "/" + EchoHeadersHandler); - public static object[][] GetEchoServers() - { - if (PlatformDetection.IsFirefox) - { - // https://github.com/dotnet/runtime/issues/101115 - return new object[][] { - new object[] { RemoteEchoServer }, - }; - } - return new object[][] { - new object[] { RemoteEchoServer }, - new object[] { SecureRemoteEchoServer }, - }; - } - - public static object[][] GetEchoHeadersServers() - { - if (PlatformDetection.IsFirefox) - { - // https://github.com/dotnet/runtime/issues/101115 - return new object[][] { - new object[] { RemoteEchoHeadersServer }, - }; - } - return new object[][] { - new object[] { RemoteEchoHeadersServer }, - new object[] { SecureRemoteEchoHeadersServer }, - }; - } + public static Uri[] GetEchoServers() => PlatformDetection.IsFirefox + ? [ RemoteEchoServer ] // https://github.com/dotnet/runtime/issues/101115 + : [ RemoteEchoServer, SecureRemoteEchoServer ]; + + public static Uri[] GetEchoHeadersServers() => PlatformDetection.IsFirefox + ? [ RemoteEchoHeadersServer ] // https://github.com/dotnet/runtime/issues/101115 + : [ RemoteEchoHeadersServer, SecureRemoteEchoHeadersServer ]; } } } diff --git a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs index 93a9c6318b601e..f92e651ec0a675 100644 --- a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs @@ -148,7 +148,7 @@ public abstract class GenericLoopbackConnection : IAsyncDisposable /// If isFinal is false, the body is not completed and you can call SendResponseBodyAsync to send more. public abstract Task SendResponseAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "", bool isFinal = true); /// Sends response headers. - public abstract Task SendResponseHeadersAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null); + public abstract Task SendResponseHeadersAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, bool isTrailingHeader = false); /// Sends valid but incomplete headers. Once called, there is no way to continue the response past this point. public abstract Task SendPartialResponseHeadersAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null); /// Sends Response body after SendResponse was called with isFinal: false. diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index 72e5cd31d984ca..58bc1a8ccc5141 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -28,6 +28,8 @@ public class Http2LoopbackConnection : GenericLoopbackConnection private readonly TimeSpan _timeout; private int _lastStreamId; private bool _expectClientDisconnect; + private readonly SemaphoreSlim? _readLock; + private readonly SemaphoreSlim? _writeLock; private readonly byte[] _prefix = new byte[24]; public string PrefixString => Encoding.UTF8.GetString(_prefix, 0, _prefix.Length); @@ -35,12 +37,59 @@ public class Http2LoopbackConnection : GenericLoopbackConnection public Stream Stream => _connectionStream; public Task SettingAckWaiter => _ignoredSettingsAckPromise?.Task; - private Http2LoopbackConnection(SocketWrapper socket, Stream stream, TimeSpan timeout, bool transparentPingResponse) + private Http2LoopbackConnection(SocketWrapper socket, Stream stream, TimeSpan timeout, Http2Options httpOptions) { _connectionSocket = socket; _connectionStream = stream; _timeout = timeout; - _transparentPingResponse = transparentPingResponse; + _transparentPingResponse = httpOptions.EnableTransparentPingResponse; + + if (httpOptions.EnsureThreadSafeIO) + { + _readLock = new SemaphoreSlim(1, 1); + _writeLock = new SemaphoreSlim(1, 1); + _connectionStream = CreateConcurrentConnectionStream(stream, _readLock, _writeLock); + } + + static Stream CreateConcurrentConnectionStream(Stream stream, SemaphoreSlim readLock, SemaphoreSlim writeLock) + { + return new DelegateStream( + canReadFunc: () => true, + canWriteFunc: () => true, + readAsyncFunc: async (buffer, offset, count, cancellationToken) => + { + await readLock.WaitAsync(cancellationToken); + try + { + return await stream.ReadAsync(buffer, offset, count, cancellationToken); + } + finally + { + readLock.Release(); + } + }, + writeAsyncFunc: async (buffer, offset, count, cancellationToken) => + { + await writeLock.WaitAsync(cancellationToken); + try + { + await stream.WriteAsync(buffer, offset, count, cancellationToken); + await stream.FlushAsync(cancellationToken); + } + finally + { + writeLock.Release(); + } + }, + disposeFunc: (disposing) => + { + if (disposing) + { + stream.Dispose(); + } + } + ); + } } public override string ToString() @@ -83,7 +132,7 @@ public static async Task CreateAsync(SocketWrapper sock stream = sslStream; } - var con = new Http2LoopbackConnection(socket, stream, timeout, httpOptions.EnableTransparentPingResponse); + var con = new Http2LoopbackConnection(socket, stream, timeout, httpOptions); await con.ReadPrefixAsync().ConfigureAwait(false); return con; @@ -959,10 +1008,10 @@ public override Task SendResponseAsync(HttpStatusCode statusCode = HttpStatusCod return SendResponseAsync(statusCode, headers, content, isFinal, requestId: 0); } - public override Task SendResponseHeadersAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null) + public override Task SendResponseHeadersAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, bool isTrailingHeader = false) { int streamId = _lastStreamId; - return SendResponseHeadersAsync(streamId, endStream: false, statusCode, isTrailingHeader: false, endHeaders: true, headers); + return SendResponseHeadersAsync(streamId, endStream: isTrailingHeader, statusCode, isTrailingHeader: isTrailingHeader, endHeaders: true, headers); } public override Task SendPartialResponseHeadersAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null) diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs index 90929b70eec379..3e4c7584ad03ce 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs @@ -185,6 +185,7 @@ public class Http2Options : GenericLoopbackOptions public bool ClientCertificateRequired { get; set; } public bool EnableTransparentPingResponse { get; set; } = true; + public bool EnsureThreadSafeIO { get; set; } public Http2Options() { @@ -216,7 +217,12 @@ public override async Task CreateConnectionAsync(Sock private static Http2Options CreateOptions(GenericLoopbackOptions options) { - Http2Options http2Options = new Http2Options(); + if (options is Http2Options http2Options) + { + return http2Options; + } + + http2Options = new Http2Options(); if (options != null) { http2Options.Address = options.Address; diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs index a8e18ae6fce781..27ebd955072b68 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs @@ -229,9 +229,15 @@ public override async Task SendResponseBodyAsync(byte[] content, bool isFinal = } } - public override Task SendResponseHeadersAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null) + public override async Task SendResponseHeadersAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, bool isTrailingHeader = false) { - return _currentStream.SendResponseHeadersAsync(statusCode, headers); + await _currentStream.SendResponseHeadersAsync(statusCode: isTrailingHeader ? null : statusCode, headers); + + if (isTrailingHeader) + { + _currentStream.Stream.CompleteWrites(); + await DisposeCurrentStream().ConfigureAwait(false); + } } public override Task SendPartialResponseHeadersAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs index 430cfeb2d47295..d0f9ecc4feed5a 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs @@ -226,7 +226,7 @@ public static IEnumerable Authentication_TestData() [InlineData("NTLM")] [InlineData("Kerberos")] [InlineData("Negotiate")] - public async Task PreAuthenticate_NoPreviousAuthenticatedRequests_NoCredentialsSent(string credCacheScheme) + public async Task PreAuthenticate_NoPreviousAuthenticatedRequests_NoCredentialsSent(string? credCacheScheme) { const int NumRequests = 3; await LoopbackServer.CreateClientAndServerAsync(async uri => @@ -268,7 +268,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => [Theory] [InlineData(null, "WWW-Authenticate: Basic realm=\"hello\"\r\n")] [InlineData("Basic", "WWW-Authenticate: Basic realm=\"hello\"\r\n")] - public async Task PreAuthenticate_FirstRequestNoHeaderAndAuthenticates_SecondRequestPreauthenticates(string credCacheScheme, string authResponse) + public async Task PreAuthenticate_FirstRequestNoHeaderAndAuthenticates_SecondRequestPreauthenticates(string? credCacheScheme, string authResponse) { await LoopbackServer.CreateClientAndServerAsync(async uri => { diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index fd9460726f5888..7fee0affc047c3 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -73,7 +73,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [InlineData(15)] public async Task LargeSingleHeader_ThrowsException(int maxResponseHeadersLength) { - var semaphore = new SemaphoreSlim(0); + using var ce = new CountdownEvent(2); using HttpClientHandler handler = CreateHttpClientHandler(); handler.MaxResponseHeadersLength = maxResponseHeadersLength; @@ -86,22 +86,29 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { Assert.Contains((handler.MaxResponseHeadersLength * 1024).ToString(), e.ToString()); } - await semaphore.WaitAsync(); + ce.Signal(); + ce.Wait(TestHelper.PassingTestTimeout); }, async server => { + var connection = await server.EstablishGenericConnectionAsync(); try { - await server.HandleRequestAsync(headers: new[] { new HttpHeaderData("Foo", new string('a', handler.MaxResponseHeadersLength * 1024)) }); + // Do not use HandleRequestAsync. It sends GO_AWAY before sending the response, making client close the connection right after the stream abort. + // QUIC is based on UDP and packet ordering is not preserved, so the connection close might race with the expected stream error in H/3 case. + await connection.ReadRequestDataAsync(); + await connection.SendResponseAsync(headers: new[] { new HttpHeaderData("Foo", new string('a', handler.MaxResponseHeadersLength * 1024)) }); } // Client can respond by closing/aborting the underlying stream while we are still sending the headers, ignore these exceptions catch (IOException ex) when (ex.InnerException is SocketException se && se.SocketErrorCode == SocketError.Shutdown) { } #if !WINHTTPHANDLER_TEST - catch (QuicException ex) when (ex.QuicError == QuicError.StreamAborted && ex.ApplicationErrorCode == Http3ExcessiveLoad) {} + catch (QuicException ex) when (ex.QuicError == QuicError.StreamAborted && ex.ApplicationErrorCode == Http3ExcessiveLoad) { } #endif finally { - semaphore.Release(); + ce.Signal(); + ce.Wait(TestHelper.PassingTestTimeout); + await connection.DisposeAsync(); } }); } @@ -114,7 +121,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [InlineData(int.MaxValue / 800, 100 * 1024)] // Capped at int.MaxValue public async Task ThresholdExceeded_ThrowsException(int? maxResponseHeadersLength, int headersLengthEstimate) { - var semaphore = new SemaphoreSlim(0); + using var ce = new CountdownEvent(2); await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { using HttpClientHandler handler = CreateHttpClientHandler(); @@ -138,7 +145,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.Contains((handler.MaxResponseHeadersLength * 1024).ToString(), e.ToString()); } } - await semaphore.WaitAsync(); + ce.Signal(); + ce.Wait(TestHelper.PassingTestTimeout); }, async server => { @@ -148,9 +156,13 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => headers.Add(new HttpHeaderData($"Custom-{i}", new string('a', 480))); } + var connection = await server.EstablishGenericConnectionAsync(); try { - await server.HandleRequestAsync(headers: headers); + // Do not use HandleRequestAsync. It sends GO_AWAY before sending the response, making client close the connection right after the stream abort. + // QUIC is based on UDP and packet ordering is not preserved, so the connection close might race with the expected stream error in H/3 case. + await connection.ReadRequestDataAsync(); + await connection.SendResponseAsync(headers: headers); } // Client can respond by closing/aborting the underlying stream while we are still sending the headers, ignore these exceptions catch (IOException ex) when (ex.InnerException is SocketException se && se.SocketErrorCode == SocketError.Shutdown) { } @@ -159,7 +171,9 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => #endif finally { - semaphore.Release(); + ce.Signal(); + ce.Wait(TestHelper.PassingTestTimeout); + await connection.DisposeAsync(); } }); } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs index d027b87f0d86df..b2d0179378eca8 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs @@ -48,7 +48,7 @@ public void Ctor_ExpectedDefaultValues() using (HttpClientHandler handler = CreateHttpClientHandler()) { Assert.Null(handler.ServerCertificateCustomValidationCallback); - Assert.True(handler.CheckCertificateRevocationList); + Assert.False(handler.CheckCertificateRevocationList); } } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 981d32cbd3f3a0..b18dd83dcbeb71 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -76,9 +76,9 @@ public void Ctor_ExpectedDefaultPropertyValues() Assert.False(handler.PreAuthenticate); Assert.True(handler.SupportsProxy); Assert.True(handler.SupportsRedirectConfiguration); + Assert.False(handler.CheckCertificateRevocationList); // Changes from .NET Framework. - Assert.True(handler.CheckCertificateRevocationList); Assert.Equal(0, handler.MaxRequestContentBufferSize); Assert.Equal(SslProtocols.None, handler.SslProtocols); } @@ -2173,6 +2173,7 @@ public async Task SendAsync_InvalidRequestUri_Throws() public async Task SendAsync_RequestWithDangerousControlHeaderValue_ThrowsHttpRequestException(char dangerousChar, HeaderType headerType) { TaskCompletionSource acceptConnection = new TaskCompletionSource(); + SemaphoreSlim clientFinished = new SemaphoreSlim(0); await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { @@ -2216,14 +2217,14 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => // WinHTTP validates the input before opening connection whereas SocketsHttpHandler opens connection first and validates only when writing to the wire. acceptConnection.SetResult(!IsWinHttpHandler); var ex = await Assert.ThrowsAnyAsync(() => client.SendAsync(request)); + clientFinished.Release(); + var hrex = Assert.IsType(ex); if (IsWinHttpHandler) { - var fex = Assert.IsType(ex); - Assert.Contains("Latin-1", fex.Message); + Assert.Contains("Error 87", hrex.InnerException.Message); } else { - var hrex = Assert.IsType(ex); var message = UseVersion == HttpVersion30 ? hrex.InnerException.Message : hrex.Message; Assert.Contains("ASCII", message); } @@ -2232,7 +2233,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { if (await acceptConnection.Task) { - await IgnoreExceptions(server.AcceptConnectionAsync(c => Task.CompletedTask)); + await IgnoreExceptions(() => server.AcceptConnectionAsync(_ => clientFinished.WaitAsync(TestHelper.PassingTestTimeout))); } }); } @@ -2343,5 +2344,33 @@ public enum HeaderType Content, Cookie } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + public async Task LargeUriAndHeaders_Works() + { + int length = IsWinHttpHandler ? 65_000 : 10_000_000; + + string longPath = "/" + new string('X', length); + string longHeaderName = new string('Y', length); + string longHeaderValue = new string('Z', length); + + await LoopbackServerFactory.CreateClientAndServerAsync( + async uri => + { + using HttpClient client = CreateHttpClient(); + + HttpRequestMessage request = CreateRequest(HttpMethod.Get, new UriBuilder(uri) { Path = longPath }.Uri, UseVersion); + request.Headers.Add(longHeaderName, longHeaderValue); + + await client.SendAsync(request); + }, + async server => + { + HttpRequestData requestData = await server.HandleRequestAsync(); + + Assert.Equal(longPath, requestData.Path); + Assert.Equal(longHeaderValue, requestData.GetSingleHeaderValue(longHeaderName)); + }); + } } } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs b/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs index 9c1838a2ea9225..0d3f460d586dd5 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs @@ -287,44 +287,33 @@ await TestHelper.WhenAllCompletedOrAnyFailed( }, new LoopbackServer.Options { StreamWrapper = GetStream }); } - public static IEnumerable GetInvalidStatusLine() - { - yield return "HTTP/1.1 2345"; - yield return "HTTP/A.1 200 OK"; - yield return "HTTP/X.Y.Z 200 OK"; - - yield return "HTTP/0.1 200 OK"; - yield return "HTTP/3.5 200 OK"; - yield return "HTTP/1.12 200 OK"; - yield return "HTTP/12.1 200 OK"; - yield return "HTTP/1.1 200 O\rK"; - - yield return "HTTP/1.A 200 OK"; - yield return "HTTP/1.1 "; - yield return "HTTP/1.1 !11"; - yield return "HTTP/1.1 a11"; - yield return "HTTP/1.1 abc"; - yield return "HTTP/1.1\t\t"; - yield return "HTTP/1.1\t"; - yield return "HTTP/1.1 "; - - yield return "HTTP/1.1 200OK"; - yield return "HTTP/1.1 20c"; - yield return "HTTP/1.1 23"; - yield return "HTTP/1.1 2bc"; - - yield return "NOTHTTP/1.1"; - yield return "HTTP 1.1 200 OK"; - yield return "ABCD/1.1 200 OK"; - yield return "HTTP/1.1"; - yield return "HTTP\\1.1 200 OK"; - yield return "NOTHTTP/1.1 200 OK"; - } - - public static TheoryData InvalidStatusLine = GetInvalidStatusLine().ToTheoryData(); - [Theory] - [MemberData(nameof(InvalidStatusLine))] + [InlineData("HTTP/1.1 2345")] + [InlineData("HTTP/A.1 200 OK")] + [InlineData("HTTP/X.Y.Z 200 OK")] + [InlineData("HTTP/0.1 200 OK")] + [InlineData("HTTP/3.5 200 OK")] + [InlineData("HTTP/1.12 200 OK")] + [InlineData("HTTP/12.1 200 OK")] + [InlineData("HTTP/1.1 200 O\rK")] + [InlineData("HTTP/1.A 200 OK")] + [InlineData("HTTP/1.1 ")] + [InlineData("HTTP/1.1 !11")] + [InlineData("HTTP/1.1 a11")] + [InlineData("HTTP/1.1 abc")] + [InlineData("HTTP/1.1\t\t")] + [InlineData("HTTP/1.1\t")] + [InlineData("HTTP/1.1 ")] + [InlineData("HTTP/1.1 200OK")] + [InlineData("HTTP/1.1 20c")] + [InlineData("HTTP/1.1 23")] + [InlineData("HTTP/1.1 2bc")] + [InlineData("NOTHTTP/1.1")] + [InlineData("HTTP 1.1 200 OK")] + [InlineData("ABCD/1.1 200 OK")] + [InlineData("HTTP/1.1")] + [InlineData("HTTP\\1.1 200 OK")] + [InlineData("NOTHTTP/1.1 200 OK")] public async Task GetAsync_InvalidStatusLine_ThrowsException(string responseString) { await GetAsyncThrowsExceptionHelper(responseString); diff --git a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs index e4fb8f027c1623..0ac084afc4e3e2 100644 --- a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs @@ -979,9 +979,21 @@ private string GetResponseHeaderString(HttpStatusCode statusCode, IList headers = null) + private string GetTrailerString(IList trailers) { - string headerString = GetResponseHeaderString(statusCode, headers); + StringBuilder bld = new StringBuilder(); + bld.Append("0\r\n"); + foreach (HttpHeaderData headerData in trailers) + { + bld.Append($"{headerData.Name}: {headerData.Value}\r\n"); + } + bld.Append("\r\n"); + return bld.ToString(); + } + + public override async Task SendResponseHeadersAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, bool isTrailingHeader = false) + { + string headerString = isTrailingHeader ? GetTrailerString(headers) : GetResponseHeaderString(statusCode, headers); await SendResponseAsync(headerString).ConfigureAwait(false); } @@ -1133,6 +1145,11 @@ public override async Task CreateConnectionAsync(Sock private static LoopbackServer.Options CreateOptions(GenericLoopbackOptions options) { + if (options is LoopbackServer.Options { } loopbackOptions) + { + return loopbackOptions; + } + LoopbackServer.Options newOptions = new LoopbackServer.Options(); if (options != null) { diff --git a/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs b/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs index 591d0776accc16..2a7cf22e7afcbc 100644 --- a/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs +++ b/src/libraries/Common/tests/System/Net/Http/QPackTestDecoder.cs @@ -92,15 +92,15 @@ public static (int bytesConsumed, int value) DecodeInteger(ReadOnlySpan he ulong extra = 0; int length = 1; - ulong b; + byte b; do { // https://http2.github.io/http2-spec/compression.html#integer.representation // HPack encodes integers from the least significant byte to the most. // Every 7-bits of the next byte is shifted by (7 * index) and added to the result. - b = (ulong)headerBlock[length++]; - extra = checked(b << (7 * (length - 2))) | extra; + b = headerBlock[length++]; + extra = checked((ulong)(b & 0x7F) << (7 * (length - 2))) | extra; } while ((b & 0b10000000) != 0); diff --git a/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs b/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs index 786ee3c4ccf6ad..3a8feb437fefc4 100644 --- a/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs @@ -319,8 +319,18 @@ public async Task BrowserHttpHandler_StreamingResponseAbort(HttpMethod method, s using HttpClient client = CreateHttpClientForRemoteServer(Configuration.Http.RemoteHttp11Server); if (abort == "abortDuringBody") { - using var res = await client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead); + HttpResponseMessage res; + try + { + res = await client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead); + } + catch (HttpRequestException) + { + // sometimes the server aborts earlier than the browser is able to return from the non-blocking send/fetch + return; + } await Assert.ThrowsAsync(() => res.Content.ReadAsByteArrayAsync()); + res.Dispose(); } else { @@ -487,7 +497,7 @@ public async Task BrowserHttpHandler_StreamingRequest_ThrowFromContentCopy_Reque } } - public static TheoryData CancelRequestReadFunctions + public static TheoryData CancelRequestReadFunctions => new TheoryData { { false, 0, false }, diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Directory.Build.targets b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Directory.Build.targets index 242d10ebfa0fac..a354006e837eae 100644 --- a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Directory.Build.targets +++ b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Directory.Build.targets @@ -1,6 +1,7 @@ $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, global.json))/ + $([MSBuild]::NormalizeDirectory('$(RepositoryRoot)', 'src', 'libraries', 'Common', 'tests')) diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoHandler.cs b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoHandler.cs index f9f8b0c24f2e01..03ccb4ff4f812d 100644 --- a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoHandler.cs +++ b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoHandler.cs @@ -85,7 +85,7 @@ public static async Task InvokeAsync(HttpContext context) if (qs.Contains("abortDuringBody")) { await context.Response.Body.FlushAsync(); - await Task.Delay(10); + await Task.Delay(100); context.Abort(); return; } diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHandler.cs b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHandler.cs index a290ce63bd4ffb..6cfaa4ff7109be 100644 --- a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHandler.cs +++ b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHandler.cs @@ -3,8 +3,7 @@ using System; using System.Net.WebSockets; -using System.Text; -using System.Threading; +using System.Net.Test.Common; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; @@ -12,177 +11,25 @@ namespace NetCoreServer { public class EchoWebSocketHandler { - private const int MaxBufferSize = 128 * 1024; - public static async Task InvokeAsync(HttpContext context) { - QueryString queryString = context.Request.QueryString; - bool replyWithPartialMessages = queryString.HasValue && queryString.Value.Contains("replyWithPartialMessages"); - bool replyWithEnhancedCloseMessage = queryString.HasValue && queryString.Value.Contains("replyWithEnhancedCloseMessage"); - - string subProtocol = context.Request.Query["subprotocol"]; - - if (context.Request.QueryString.HasValue && context.Request.QueryString.Value.Contains("delay10sec")) - { - await Task.Delay(10000); - } - else if (context.Request.QueryString.HasValue && context.Request.QueryString.Value.Contains("delay20sec")) - { - await Task.Delay(20000); - } - + var queryString = context.Request.QueryString.ToUriComponent(); // Returns empty string if request URI has no query + WebSocketEchoOptions options = await WebSocketEchoHelper.ProcessOptions(queryString); try { - if (!context.WebSockets.IsWebSocketRequest) + WebSocket socket = await WebSocketAcceptHelper.AcceptAsync(context, options.SubProtocol); + if (socket is null) { - context.Response.StatusCode = 200; - context.Response.ContentType = "text/plain"; - await context.Response.WriteAsync("Not a websocket request"); - return; } - WebSocket socket; - if (!string.IsNullOrEmpty(subProtocol)) - { - socket = await context.WebSockets.AcceptWebSocketAsync(subProtocol); - } - else - { - socket = await context.WebSockets.AcceptWebSocketAsync(); - } - - await ProcessWebSocketRequest(socket, replyWithPartialMessages, replyWithEnhancedCloseMessage); + await WebSocketEchoHelper.RunEchoAll( + socket, options.ReplyWithPartialMessages, options.ReplyWithEnhancedCloseMessage); } catch (Exception) { // We might want to log these exceptions. But for now we ignore them. } } - - private static async Task ProcessWebSocketRequest( - WebSocket socket, - bool replyWithPartialMessages, - bool replyWithEnhancedCloseMessage) - { - var receiveBuffer = new byte[MaxBufferSize]; - var throwAwayBuffer = new byte[MaxBufferSize]; - - // Stay in loop while websocket is open - while (socket.State == WebSocketState.Open || socket.State == WebSocketState.CloseSent) - { - var receiveResult = await socket.ReceiveAsync(new ArraySegment(receiveBuffer), CancellationToken.None); - if (receiveResult.MessageType == WebSocketMessageType.Close) - { - if (receiveResult.CloseStatus == WebSocketCloseStatus.Empty) - { - await socket.CloseAsync(WebSocketCloseStatus.Empty, null, CancellationToken.None); - } - else - { - WebSocketCloseStatus closeStatus = receiveResult.CloseStatus.GetValueOrDefault(); - await socket.CloseAsync( - closeStatus, - replyWithEnhancedCloseMessage ? - ("Server received: " + (int)closeStatus + " " + receiveResult.CloseStatusDescription) : - receiveResult.CloseStatusDescription, - CancellationToken.None); - } - - continue; - } - - // Keep reading until we get an entire message. - int offset = receiveResult.Count; - while (receiveResult.EndOfMessage == false) - { - if (offset < MaxBufferSize) - { - receiveResult = await socket.ReceiveAsync( - new ArraySegment(receiveBuffer, offset, MaxBufferSize - offset), - CancellationToken.None); - } - else - { - receiveResult = await socket.ReceiveAsync( - new ArraySegment(throwAwayBuffer), - CancellationToken.None); - } - - offset += receiveResult.Count; - } - - // Close socket if the message was too big. - if (offset > MaxBufferSize) - { - await socket.CloseAsync( - WebSocketCloseStatus.MessageTooBig, - String.Format("{0}: {1} > {2}", WebSocketCloseStatus.MessageTooBig.ToString(), offset, MaxBufferSize), - CancellationToken.None); - - continue; - } - - bool sendMessage = false; - string receivedMessage = null; - if (receiveResult.MessageType == WebSocketMessageType.Text) - { - receivedMessage = Encoding.UTF8.GetString(receiveBuffer, 0, offset); - if (receivedMessage == ".close") - { - await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, CancellationToken.None); - } - else if (receivedMessage == ".shutdown") - { - await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, CancellationToken.None); - } - else if (receivedMessage == ".abort") - { - socket.Abort(); - } - else if (receivedMessage == ".delay5sec") - { - await Task.Delay(5000); - } - else if (receivedMessage == ".receiveMessageAfterClose") - { - byte[] buffer = new byte[1024]; - string message = $"{receivedMessage} {DateTime.Now.ToString("HH:mm:ss")}"; - buffer = System.Text.Encoding.UTF8.GetBytes(message); - await socket.SendAsync( - new ArraySegment(buffer, 0, message.Length), - WebSocketMessageType.Text, - true, - CancellationToken.None); - await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, CancellationToken.None); - } - else if (socket.State == WebSocketState.Open) - { - sendMessage = true; - } - } - else - { - sendMessage = true; - } - - if (sendMessage) - { - await socket.SendAsync( - new ArraySegment(receiveBuffer, 0, offset), - receiveResult.MessageType, - !replyWithPartialMessages, - CancellationToken.None); - } - if (receivedMessage == ".closeafter") - { - await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, CancellationToken.None); - } - else if (receivedMessage == ".shutdownafter") - { - await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, CancellationToken.None); - } - } - } } } diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHeadersHandler.cs b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHeadersHandler.cs index c5ebca53b63a94..0df2a3089c1238 100644 --- a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHeadersHandler.cs +++ b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Handlers/EchoWebSocketHeadersHandler.cs @@ -3,81 +3,35 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net.WebSockets; -using System.Text; -using System.Threading; +using System.Net.Test.Common; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Primitives; namespace NetCoreServer { public class EchoWebSocketHeadersHandler { - private const int MaxBufferSize = 1024; - public static async Task InvokeAsync(HttpContext context) { try { - if (!context.WebSockets.IsWebSocketRequest) + WebSocket socket = await WebSocketAcceptHelper.AcceptAsync(context); + if (socket is null) { - context.Response.StatusCode = 200; - context.Response.ContentType = "text/plain"; - await context.Response.WriteAsync("Not a websocket request"); - return; } - WebSocket socket = await context.WebSockets.AcceptWebSocketAsync(); - await ProcessWebSocketRequest(socket, context.Request.Headers); + var headers = context.Request.Headers.Select( + h => new KeyValuePair(h.Key, h.Value.ToString())); + await WebSocketEchoHelper.RunEchoHeaders(socket, headers); } catch (Exception) { // We might want to log these exceptions. But for now we ignore them. } } - - private static async Task ProcessWebSocketRequest(WebSocket socket, IHeaderDictionary headers) - { - var receiveBuffer = new byte[MaxBufferSize]; - - // Reflect all headers and cookies - var sb = new StringBuilder(); - sb.AppendLine("Headers:"); - - foreach (KeyValuePair pair in headers) - { - sb.Append(pair.Key); - sb.Append(":"); - sb.AppendLine(pair.Value.ToString()); - } - - byte[] sendBuffer = Encoding.UTF8.GetBytes(sb.ToString()); - await socket.SendAsync(new ArraySegment(sendBuffer), WebSocketMessageType.Text, true, new CancellationToken()); - - // Stay in loop while websocket is open - while (socket.State == WebSocketState.Open || socket.State == WebSocketState.CloseSent) - { - var receiveResult = await socket.ReceiveAsync(new ArraySegment(receiveBuffer), CancellationToken.None); - if (receiveResult.MessageType == WebSocketMessageType.Close) - { - if (receiveResult.CloseStatus == WebSocketCloseStatus.Empty) - { - await socket.CloseAsync(WebSocketCloseStatus.Empty, null, CancellationToken.None); - } - else - { - await socket.CloseAsync( - receiveResult.CloseStatus.GetValueOrDefault(), - receiveResult.CloseStatusDescription, - CancellationToken.None); - } - - continue; - } - } - } } } diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Helpers/WebSocketAcceptHelper.cs b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Helpers/WebSocketAcceptHelper.cs new file mode 100644 index 00000000000000..4476a2a928ac28 --- /dev/null +++ b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/Helpers/WebSocketAcceptHelper.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Net.WebSockets; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; + +namespace NetCoreServer +{ + public static class WebSocketAcceptHelper + { + public static async Task AcceptAsync(HttpContext context, string subProtocol = null) + { + if (!context.WebSockets.IsWebSocketRequest) + { + context.Response.StatusCode = 200; + context.Response.ContentType = "text/plain"; + await context.Response.WriteAsync("Not a websocket request"); + return null; + } + + if (!string.IsNullOrEmpty(subProtocol)) + { + return await context.WebSockets.AcceptWebSocketAsync(subProtocol); + } + + return await context.WebSockets.AcceptWebSocketAsync(); + } + } +} diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/NetCoreServer.csproj b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/NetCoreServer.csproj index 057ce2b8fda562..04ae3c5c19b116 100644 --- a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/NetCoreServer.csproj +++ b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/NetCoreServer.csproj @@ -2,7 +2,7 @@ $(_TargetFrameworkForXHarness) - @@ -33,6 +33,8 @@ + + @@ -51,6 +53,7 @@ + diff --git a/src/libraries/Common/tests/System/Net/WebSockets/WebSocketEchoHelper.cs b/src/libraries/Common/tests/System/Net/WebSockets/WebSocketEchoHelper.cs new file mode 100644 index 00000000000000..4b1e44b6b223a6 --- /dev/null +++ b/src/libraries/Common/tests/System/Net/WebSockets/WebSocketEchoHelper.cs @@ -0,0 +1,201 @@ +// 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.Generic; +using System.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Test.Common +{ + public static class WebSocketEchoHelper + { + public static class EchoControlMessage + { + public const string Close = ".close"; + public const string Shutdown = ".shutdown"; + public const string Abort = ".abort"; + public const string Delay5Sec = ".delay5sec"; + public const string ReceiveMessageAfterClose = ".receiveMessageAfterClose"; + public const string CloseAfter = ".closeafter"; + public const string ShutdownAfter = ".shutdownafter"; + } + + public static async Task RunEchoAll(WebSocket socket, bool replyWithPartialMessages, bool replyWithEnhancedCloseMessage, CancellationToken cancellationToken = default) + { + const int MaxBufferSize = 128 * 1024; + + var receiveBuffer = new byte[MaxBufferSize]; + var throwAwayBuffer = new byte[MaxBufferSize]; + + // Stay in loop while websocket is open + while (socket.State == WebSocketState.Open || socket.State == WebSocketState.CloseSent) + { + var receiveResult = await socket.ReceiveAsync(new ArraySegment(receiveBuffer), cancellationToken); + + if (receiveResult.MessageType == WebSocketMessageType.Close) + { + if (receiveResult.CloseStatus == WebSocketCloseStatus.Empty) + { + await socket.CloseAsync(WebSocketCloseStatus.Empty, null, cancellationToken); + } + else + { + WebSocketCloseStatus closeStatus = receiveResult.CloseStatus.GetValueOrDefault(); + await socket.CloseAsync( + closeStatus, + replyWithEnhancedCloseMessage ? + ("Server received: " + (int)closeStatus + " " + receiveResult.CloseStatusDescription) : + receiveResult.CloseStatusDescription, + cancellationToken); + } + + continue; + } + + // Keep reading until we get an entire message. + int offset = receiveResult.Count; + while (receiveResult.EndOfMessage == false) + { + if (offset < MaxBufferSize) + { + receiveResult = await socket.ReceiveAsync( + new ArraySegment(receiveBuffer, offset, MaxBufferSize - offset), + cancellationToken); + } + else + { + receiveResult = await socket.ReceiveAsync( + new ArraySegment(throwAwayBuffer), + cancellationToken); + } + + offset += receiveResult.Count; + } + + // Close socket if the message was too big. + if (offset > MaxBufferSize) + { + await socket.CloseAsync( + WebSocketCloseStatus.MessageTooBig, + string.Format("{0}: {1} > {2}", WebSocketCloseStatus.MessageTooBig.ToString(), offset, MaxBufferSize), + cancellationToken); + + continue; + } + + bool sendMessage = false; + string receivedMessage = null; + if (receiveResult.MessageType == WebSocketMessageType.Text) + { + receivedMessage = Encoding.UTF8.GetString(receiveBuffer, 0, offset); + if (receivedMessage == EchoControlMessage.Close) + { + await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, cancellationToken); + } + else if (receivedMessage == EchoControlMessage.Shutdown) + { + await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, cancellationToken); + } + else if (receivedMessage == EchoControlMessage.Abort) + { + socket.Abort(); + } + else if (receivedMessage == EchoControlMessage.Delay5Sec) + { + await Task.Delay(5000); + } + else if (receivedMessage == EchoControlMessage.ReceiveMessageAfterClose) + { + string message = $"{receivedMessage} {DateTime.Now:HH:mm:ss}"; + byte[] buffer = Encoding.UTF8.GetBytes(message); + await socket.SendAsync( + new ArraySegment(buffer, 0, message.Length), + WebSocketMessageType.Text, + true, + cancellationToken); + await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, cancellationToken); + } + else if (socket.State == WebSocketState.Open) + { + sendMessage = true; + } + } + else + { + sendMessage = true; + } + + if (sendMessage) + { + await socket.SendAsync( + new ArraySegment(receiveBuffer, 0, offset), + receiveResult.MessageType, + !replyWithPartialMessages, + cancellationToken); + } + if (receivedMessage == EchoControlMessage.CloseAfter) + { + await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, cancellationToken); + } + else if (receivedMessage == EchoControlMessage.ShutdownAfter) + { + await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, receivedMessage, cancellationToken); + } + } + } + + public static async Task RunEchoHeaders(WebSocket socket, IEnumerable> headers, CancellationToken cancellationToken = default) + { + const int MaxBufferSize = 1024; + var receiveBuffer = new byte[MaxBufferSize]; + + // Reflect all headers and cookies + var sb = new StringBuilder(); + sb.AppendLine("Headers:"); + + foreach (KeyValuePair pair in headers) + { + sb.Append(pair.Key); + sb.Append(":"); + sb.AppendLine(pair.Value); + } + + byte[] sendBuffer = Encoding.UTF8.GetBytes(sb.ToString()); + await socket.SendAsync(new ArraySegment(sendBuffer), WebSocketMessageType.Text, true, cancellationToken); + + // Stay in loop while websocket is open + while (socket.State == WebSocketState.Open || socket.State == WebSocketState.CloseSent) + { + var receiveResult = await socket.ReceiveAsync(new ArraySegment(receiveBuffer), cancellationToken); + if (receiveResult.MessageType == WebSocketMessageType.Close) + { + if (receiveResult.CloseStatus == WebSocketCloseStatus.Empty) + { + await socket.CloseAsync(WebSocketCloseStatus.Empty, null, cancellationToken); + } + else + { + await socket.CloseAsync( + receiveResult.CloseStatus.GetValueOrDefault(), + receiveResult.CloseStatusDescription, + cancellationToken); + } + + continue; + } + } + } + + public static async ValueTask ProcessOptions(string queryString, CancellationToken cancellationToken = default) + { + WebSocketEchoOptions options = WebSocketEchoOptions.Parse(queryString); + if (options.Delay is TimeSpan d) + { + await Task.Delay(d, cancellationToken).ConfigureAwait(false); + } + return options; + } + } +} diff --git a/src/libraries/Common/tests/System/Net/WebSockets/WebSocketEchoOptions.cs b/src/libraries/Common/tests/System/Net/WebSockets/WebSocketEchoOptions.cs new file mode 100644 index 00000000000000..9f8576e50bacea --- /dev/null +++ b/src/libraries/Common/tests/System/Net/WebSockets/WebSocketEchoOptions.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. + +namespace System.Net.Test.Common +{ + public readonly struct WebSocketEchoOptions + { + public static class EchoQueryKey + { + public const string ReplyWithPartialMessages = "replyWithPartialMessages"; + public const string ReplyWithEnhancedCloseMessage = "replyWithEnhancedCloseMessage"; + public const string SubProtocol = "subprotocol"; + public const string Delay10Sec = "delay10sec"; + public const string Delay20Sec = "delay20sec"; + } + + public static readonly WebSocketEchoOptions Default = new(); + + public bool ReplyWithPartialMessages { get; init; } + public bool ReplyWithEnhancedCloseMessage { get; init; } + public string SubProtocol { get; init; } + public TimeSpan? Delay { get; init; } + + public static WebSocketEchoOptions Parse(string query) + { + if (query is null or "" or "?") + { + return Default; + } + + return new WebSocketEchoOptions + { + ReplyWithPartialMessages = query.Contains(EchoQueryKey.ReplyWithPartialMessages), + ReplyWithEnhancedCloseMessage = query.Contains(EchoQueryKey.ReplyWithEnhancedCloseMessage), + SubProtocol = ParseSubProtocol(query), + Delay = ParseDelay(query) + }; + } + + private static string ParseSubProtocol(string query) + { + const string subProtocolEquals = $"{EchoQueryKey.SubProtocol}="; + + var index = query.IndexOf(subProtocolEquals); + if (index == -1) + { + return null; + } + + var subProtocol = query.Substring(index + subProtocolEquals.Length); + return subProtocol.Contains("&") + ? subProtocol.Substring(0, subProtocol.IndexOf("&")) + : subProtocol; + } + + private static TimeSpan? ParseDelay(string query) + => query.Contains(EchoQueryKey.Delay10Sec) + ? TimeSpan.FromSeconds(10) + : query.Contains(EchoQueryKey.Delay20Sec) ? TimeSpan.FromSeconds(20) : null; + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaContractTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaContractTests.cs new file mode 100644 index 00000000000000..5e1dd854f41660 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaContractTests.cs @@ -0,0 +1,946 @@ +// 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.Generic; +using System.Linq; +using Xunit; + +using CompositeMLDsaTestVector = System.Security.Cryptography.Tests.CompositeMLDsaTestData.CompositeMLDsaTestVector; + +namespace System.Security.Cryptography.Tests +{ + public static class CompositeMLDsaContractTests + { + public static IEnumerable ArgumentValidationData => + from algorithm in CompositeMLDsaTestData.AllAlgorithms + from shouldDispose in new[] { true, false } + select new object[] { algorithm, shouldDispose }; + + [Theory] + [MemberData(nameof(ArgumentValidationData))] + public static void NullArgumentValidation(CompositeMLDsaAlgorithm algorithm, bool shouldDispose) + { + using CompositeMLDsa dsa = CompositeMLDsaMockImplementation.Create(algorithm); + + if (shouldDispose) + { + // Test that argument validation exceptions take precedence over ObjectDisposedException + dsa.Dispose(); + } + + AssertExtensions.Throws("data", () => dsa.SignData(null)); + AssertExtensions.Throws("data", () => dsa.VerifyData(null, null)); + + AssertExtensions.Throws("signature", () => dsa.VerifyData(Array.Empty(), null)); + } + + [Fact] + public static void ArgumentValidation_Ctor_NullAlgorithm() + { + AssertExtensions.Throws("algorithm", static () => new CompositeMLDsaMockImplementation(null)); + } + + [Theory] + [MemberData(nameof(ArgumentValidationData))] + public static void ArgumentValidation(CompositeMLDsaAlgorithm algorithm, bool shouldDispose) + { + using CompositeMLDsa dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int maxSignatureSize = algorithm.MaxSignatureSizeInBytes; + + if (shouldDispose) + { + // Test that argument validation exceptions take precedence over ObjectDisposedException + dsa.Dispose(); + } + + AssertExtensions.Throws("destination", () => dsa.SignData(ReadOnlySpan.Empty, new byte[maxSignatureSize - 1], [])); + + // Context length must be less than 256 + AssertExtensions.Throws("context", () => dsa.SignData(ReadOnlySpan.Empty, new byte[maxSignatureSize], new byte[256])); + AssertExtensions.Throws("context", () => dsa.SignData(Array.Empty(), new byte[256])); + AssertExtensions.Throws("context", () => dsa.VerifyData(ReadOnlySpan.Empty, new byte[maxSignatureSize], new byte[256])); + AssertExtensions.Throws("context", () => dsa.VerifyData(Array.Empty(), new byte[maxSignatureSize], new byte[256])); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPublicKey_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int lowerBound = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeLowerBound(algorithm); + + // Buffer is too small + byte[] bytes = new byte[lowerBound - 1]; + AssertExtensions.FalseExpression(dsa.TryExportCompositeMLDsaPublicKey(bytes, out int bytesWritten)); + Assert.Equal(0, bytesWritten); + + // Buffer meets the lower bound + bytes = new byte[lowerBound]; + + dsa.ExportCompositeMLDsaPublicKeyCoreHook = destination => + { + AssertExtensions.GreaterThanOrEqualTo(destination.Length, lowerBound); + destination.Fill(1); + return lowerBound; + }; + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPublicKey(bytes, out bytesWritten)); + Assert.Equal(lowerBound, bytesWritten); + AssertExtensions.FilledWith(1, bytes); + Assert.Equal(lowerBound, bytesWritten); + + // Buffer meets the lower bound, but returned value is too small + dsa.ExportCompositeMLDsaPublicKeyCoreHook = destination => + { + AssertExtensions.GreaterThanOrEqualTo(destination.Length, lowerBound); + destination.Fill(1); + + // Writing less than lower bound isn't allowed. + return lowerBound - 1; + }; + + Assert.Throws(() => dsa.TryExportCompositeMLDsaPublicKey(bytes, out bytesWritten)); + Assert.Equal(2, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + Assert.Equal(0, bytesWritten); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPublicKey_Span_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int lowerBound = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeLowerBound(algorithm); + + byte[] bytes = new byte[lowerBound]; + + // Buffer is too small + Assert.Throws(() => dsa.ExportCompositeMLDsaPublicKey(bytes.AsSpan(0, lowerBound - 1))); + AssertExtensions.FilledWith(0, bytes); + + // Buffer meets the lower bound + dsa.ExportCompositeMLDsaPublicKeyCoreHook = destination => + { + AssertExtensions.GreaterThanOrEqualTo(destination.Length, lowerBound); + destination.Fill(1); + return lowerBound; + }; + + int bytesWritten = dsa.ExportCompositeMLDsaPublicKey(bytes.AsSpan(0, lowerBound)); + Assert.Equal(1, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + AssertExtensions.FilledWith(1, bytes); + Assert.Equal(lowerBound, bytesWritten); + + // Buffer meets the lower bound, but returned value is too small + dsa.ExportCompositeMLDsaPublicKeyCoreHook = destination => + { + AssertExtensions.GreaterThanOrEqualTo(destination.Length, lowerBound); + destination.Fill(1); + // Writing less than lower bound isn't allowed. + return lowerBound - 1; + }; + + Assert.Throws(() => dsa.ExportCompositeMLDsaPublicKey(bytes.AsSpan(0, lowerBound))); + Assert.Equal(2, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPublicKey_Array_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int lowerBound = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeLowerBound(algorithm); + + dsa.ExportCompositeMLDsaPublicKeyCoreHook = destination => + { + AssertExtensions.GreaterThanOrEqualTo(destination.Length, lowerBound); + destination.Fill(1); + + // Writing less than lower bound isn't allowed. + return lowerBound - 1; + }; + + Assert.Throws(() => dsa.ExportCompositeMLDsaPublicKey()); + Assert.Equal(1, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPublicKey_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int upperBound = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeUpperBound(algorithm); + + // Buffer is the max size + byte[] bytes = new byte[upperBound]; + + dsa.ExportCompositeMLDsaPublicKeyCoreHook = destination => + { + Assert.Equal(upperBound, destination.Length); + destination.Fill(1); + + return upperBound; + }; + + dsa.AddDestinationBufferIsSameAssertion(bytes); + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPublicKey(bytes, out int bytesWritten)); + Assert.Equal(upperBound, bytesWritten); + Assert.Equal(1, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + AssertExtensions.FilledWith(1, bytes); + + // Buffer is the max size, but returned value is too big + dsa.ExportCompositeMLDsaPublicKeyCoreHook = destination => + { + // Writing more than upper bound isn't allowed. + return upperBound + 1; + }; + + dsa.AddDestinationBufferIsSameAssertion(bytes); + + Assert.Throws(() => dsa.TryExportCompositeMLDsaPublicKey(bytes, out bytesWritten)); + Assert.Equal(2, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + Assert.Equal(0, bytesWritten); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPublicKey_Span_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int upperBound = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeUpperBound(algorithm); + + byte[] bytes = new byte[upperBound]; + + // Buffer is the max size + dsa.ExportCompositeMLDsaPublicKeyCoreHook = destination => + { + Assert.Equal(upperBound, destination.Length); + destination.Fill(1); + return upperBound; + }; + + dsa.AddDestinationBufferIsSameAssertion(bytes); + + int bytesWritten = dsa.ExportCompositeMLDsaPublicKey(bytes); + Assert.Equal(1, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + AssertExtensions.FilledWith(1, bytes); + Assert.Equal(upperBound, bytesWritten); + + // Buffer is the max size, but returned value is too big + dsa.ExportCompositeMLDsaPublicKeyCoreHook = destination => + { + // Writing more than upper bound isn't allowed. + return upperBound + 1; + }; + + dsa.AddDestinationBufferIsSameAssertion(bytes); + + Assert.Throws(() => dsa.ExportCompositeMLDsaPublicKey(bytes.AsSpan(0, upperBound))); + Assert.Equal(2, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPublicKey_Array_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int upperBound = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeUpperBound(algorithm); + + dsa.ExportCompositeMLDsaPublicKeyCoreHook = destination => + { + // Writing more than upper bound isn't allowed. + return upperBound + 1; + }; + + Assert.Throws(() => dsa.ExportCompositeMLDsaPublicKey()); + Assert.Equal(1, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPrivateKey_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int lowerBound = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeLowerBound(algorithm); + + // Buffer is too small + byte[] bytes = new byte[lowerBound - 1]; + AssertExtensions.FalseExpression(dsa.TryExportCompositeMLDsaPrivateKey(bytes, out int bytesWritten)); + Assert.Equal(0, bytesWritten); + + // Buffer meets the lower bound + bytes = new byte[lowerBound]; + + dsa.ExportCompositeMLDsaPrivateKeyCoreHook = destination => + { + AssertExtensions.GreaterThanOrEqualTo(destination.Length, lowerBound); + destination.Fill(1); + return lowerBound; + }; + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPrivateKey(bytes, out bytesWritten)); + Assert.Equal(1, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + AssertExtensions.FilledWith(1, bytes); + Assert.Equal(lowerBound, bytesWritten); + + // Buffer meets the lower bound, but returned value is too small + dsa.ExportCompositeMLDsaPrivateKeyCoreHook = destination => + { + AssertExtensions.GreaterThanOrEqualTo(destination.Length, lowerBound); + destination.Fill(1); + + // Writing less than lower bound isn't allowed. + return lowerBound - 1; + }; + + bytes.AsSpan().Clear(); + + Assert.Throws(() => dsa.TryExportCompositeMLDsaPrivateKey(bytes, out bytesWritten)); + Assert.Equal(2, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + AssertExtensions.FilledWith(0, bytes); + Assert.Equal(0, bytesWritten); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPrivateKey_Span_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int lowerBound = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeLowerBound(algorithm); + + byte[] bytes = new byte[lowerBound]; + + // Buffer is too small + Assert.Throws(() => dsa.ExportCompositeMLDsaPrivateKey(bytes.AsSpan(0, lowerBound - 1))); + AssertExtensions.FilledWith(0, bytes); + + // Buffer meets the lower bound + dsa.ExportCompositeMLDsaPrivateKeyCoreHook = destination => + { + AssertExtensions.GreaterThanOrEqualTo(destination.Length, lowerBound); + destination.Fill(1); + return lowerBound; + }; + + int bytesWritten = dsa.ExportCompositeMLDsaPrivateKey(bytes.AsSpan(0, lowerBound)); + Assert.Equal(1, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + AssertExtensions.FilledWith(1, bytes); + Assert.Equal(lowerBound, bytesWritten); + + // Buffer meets the lower bound, but returned value is too small + dsa.ExportCompositeMLDsaPrivateKeyCoreHook = destination => + { + AssertExtensions.GreaterThanOrEqualTo(destination.Length, lowerBound); + destination.Fill(1); + + // Writing less than lower bound isn't allowed. + return lowerBound - 1; + }; + + bytes.AsSpan().Clear(); + + Assert.Throws(() => dsa.ExportCompositeMLDsaPrivateKey(bytes.AsSpan(0, lowerBound))); + Assert.Equal(2, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + AssertExtensions.FilledWith(0, bytes); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPrivateKey_Array_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int lowerBound = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeLowerBound(algorithm); + + dsa.ExportCompositeMLDsaPrivateKeyCoreHook = destination => + { + AssertExtensions.GreaterThanOrEqualTo(destination.Length, lowerBound); + destination.Fill(1); + + // Writing less than lower bound isn't allowed. + return lowerBound - 1; + }; + + Assert.Throws(() => dsa.ExportCompositeMLDsaPrivateKey()); + Assert.Equal(1, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPrivateKey_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int upperBound = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeUpperBound(algorithm); + + // Buffer is the max size + byte[] bytes = new byte[upperBound]; + + dsa.ExportCompositeMLDsaPrivateKeyCoreHook = destination => + { + Assert.Equal(upperBound, destination.Length); + destination.Fill(1); + + return upperBound; + }; + + dsa.AddDestinationBufferIsSameAssertion(bytes); + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPrivateKey(bytes, out int bytesWritten)); + Assert.Equal(1, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + Assert.Equal(upperBound, bytesWritten); + AssertExtensions.FilledWith(1, bytes); + + // Buffer is the max size, but returned value is too big + dsa.ExportCompositeMLDsaPrivateKeyCoreHook = destination => + { + Assert.Equal(upperBound, destination.Length); + destination.Fill(1); + + // Writing more than upper bound isn't allowed. + return upperBound + 1; + }; + + dsa.AddDestinationBufferIsSameAssertion(bytes); + + bytes.AsSpan().Clear(); + + Assert.Throws(() => dsa.TryExportCompositeMLDsaPrivateKey(bytes, out bytesWritten)); + Assert.Equal(2, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + Assert.Equal(0, bytesWritten); + AssertExtensions.FilledWith(0, bytes); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPrivateKey_Span_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int upperBound = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeUpperBound(algorithm); + + byte[] bytes = new byte[upperBound]; + + // Buffer is the max size + dsa.ExportCompositeMLDsaPrivateKeyCoreHook = destination => + { + Assert.Equal(upperBound, destination.Length); + destination.Fill(1); + + return upperBound; + }; + + dsa.AddDestinationBufferIsSameAssertion(bytes); + + int bytesWritten = dsa.ExportCompositeMLDsaPrivateKey(bytes); + Assert.Equal(1, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + AssertExtensions.FilledWith(1, bytes); + Assert.Equal(upperBound, bytesWritten); + + // Buffer is the max size, but returned value is too big + dsa.ExportCompositeMLDsaPrivateKeyCoreHook = destination => + { + Assert.Equal(upperBound, destination.Length); + destination.Fill(1); + + // Writing more than upper bound isn't allowed. + return upperBound + 1; + }; + + dsa.AddDestinationBufferIsSameAssertion(bytes); + + bytes.AsSpan().Clear(); + + Assert.Throws(() => dsa.ExportCompositeMLDsaPrivateKey(bytes.AsSpan(0, upperBound))); + Assert.Equal(2, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + AssertExtensions.FilledWith(0, bytes); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPrivateKey_Array_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int upperBound = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeUpperBound(algorithm); + + dsa.ExportCompositeMLDsaPrivateKeyCoreHook = destination => + { + Assert.Equal(upperBound, destination.Length); + destination.Fill(1); + + // Writing more than upper bound isn't allowed. + return upperBound + 1; + }; + + Assert.Throws(() => dsa.ExportCompositeMLDsaPrivateKey()); + Assert.Equal(1, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void SignData_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int lowerBound = 32 + CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].SignatureSizeInBytes + + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => rsa.KeySizeInBits / 8, + ecdsa => 8, + eddsa => 2 * eddsa.KeySizeInBits / 8); + + Assert.Throws(() => dsa.SignData(ReadOnlySpan.Empty, new byte[lowerBound - 1])); + Assert.Throws(() => dsa.SignData(ReadOnlySpan.Empty, new byte[algorithm.MaxSignatureSizeInBytes - 1])); + + dsa.SignDataCoreHook = (data, context, destination) => + { + AssertExtensions.GreaterThanOrEqualTo(destination.Length, lowerBound); + return lowerBound; + }; + + Assert.Equal(lowerBound, dsa.SignData(ReadOnlySpan.Empty, new byte[algorithm.MaxSignatureSizeInBytes])); + Assert.Equal(lowerBound, dsa.SignData(ReadOnlySpan.Empty, new byte[algorithm.MaxSignatureSizeInBytes + 1])); + + AssertExtensions.GreaterThanOrEqualTo(algorithm.MaxSignatureSizeInBytes, lowerBound); + + dsa.SignDataCoreHook = (data, context, destination) => + { + // Writing less than lower bound isn't allowed. + return lowerBound - 1; + }; + + Assert.Throws(() => dsa.SignData(ReadOnlySpan.Empty, new byte[algorithm.MaxSignatureSizeInBytes])); + Assert.Throws(() => dsa.SignData([])); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void SignData_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + + int upperBound = algorithm.MaxSignatureSizeInBytes; + + dsa.SignDataCoreHook = (data, context, destination) => + { + Assert.Equal(upperBound, destination.Length); + return upperBound; + }; + + Assert.Equal(upperBound, dsa.SignData(ReadOnlySpan.Empty, new byte[upperBound])); + Assert.Equal(upperBound, dsa.SignData(ReadOnlySpan.Empty, new byte[upperBound + 1])); + + dsa.SignDataCoreHook = (data, context, destination) => + { + // Writing more than upper bound isn't allowed. + return upperBound + 1; + }; + + Assert.Throws(() => dsa.SignData(ReadOnlySpan.Empty, new byte[upperBound + 1])); + Assert.Throws(() => dsa.SignData([])); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void VerifyData_Threshold(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int threshold = + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => algorithm.MaxSignatureSizeInBytes, + ecdsa => 32 + CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm].SignatureSizeInBytes + 8, + eddsa => algorithm.MaxSignatureSizeInBytes); + + AssertExtensions.FalseExpression(dsa.VerifyData(ReadOnlySpan.Empty, new byte[threshold - 1])); + + dsa.VerifyDataCoreHook = (data, signature, context) => true; + + AssertExtensions.TrueExpression(dsa.VerifyData(ReadOnlySpan.Empty, new byte[threshold])); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPublicKey_BufferSize(CompositeMLDsaAlgorithm algorithm) + { + int maxPublicKeySize = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeUpperBound(algorithm); + int minPublicKeySize = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeLowerBound(algorithm); + + TestWithMockKeySize(algorithm, minPublicKeySize, minPublicKeySize); + TestWithMockKeySize(algorithm, minPublicKeySize, (minPublicKeySize + maxPublicKeySize) / 2); + TestWithMockKeySize(algorithm, minPublicKeySize, maxPublicKeySize); + TestWithMockKeySize(algorithm, minPublicKeySize, maxPublicKeySize + 1); + + TestWithMockKeySize(algorithm, maxPublicKeySize, maxPublicKeySize); + TestWithMockKeySize(algorithm, maxPublicKeySize, maxPublicKeySize + 1); + + TestWithMockKeySize(algorithm, (minPublicKeySize + maxPublicKeySize) / 2, (minPublicKeySize + maxPublicKeySize) / 2); + TestWithMockKeySize(algorithm, (minPublicKeySize + maxPublicKeySize) / 2, maxPublicKeySize); + TestWithMockKeySize(algorithm, (minPublicKeySize + maxPublicKeySize) / 2, maxPublicKeySize + 1); + + static void TestWithMockKeySize(CompositeMLDsaAlgorithm algorithm, int mockKeySize, int inputBufferSize) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + dsa.ExportCompositeMLDsaPublicKeyCoreHook = destination => + { + // Buffer size must always be upper bound for the key length. + Assert.Equal(CompositeMLDsaTestHelpers.ExpectedPublicKeySizeUpperBound(algorithm), destination.Length); + return mockKeySize; + }; + + byte[] bytes = dsa.ExportCompositeMLDsaPublicKey(); + Assert.Equal(1, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + Assert.Equal(mockKeySize, bytes.Length); + + Assert.Equal(mockKeySize, dsa.ExportCompositeMLDsaPublicKey(new byte[inputBufferSize])); + Assert.Equal(2, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPublicKey(new byte[inputBufferSize], out int bytesWritten)); + Assert.Equal(3, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + Assert.Equal(mockKeySize, bytesWritten); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPrivateKey_BufferSize(CompositeMLDsaAlgorithm algorithm) + { + int maxPrivateKeySize = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeUpperBound(algorithm); + int minPrivateKeySize = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeLowerBound(algorithm); + + TestWithMockKeySize(algorithm, minPrivateKeySize, minPrivateKeySize); + TestWithMockKeySize(algorithm, minPrivateKeySize, (minPrivateKeySize + maxPrivateKeySize) / 2); + TestWithMockKeySize(algorithm, minPrivateKeySize, maxPrivateKeySize); + TestWithMockKeySize(algorithm, minPrivateKeySize, maxPrivateKeySize + 1); + + TestWithMockKeySize(algorithm, maxPrivateKeySize, maxPrivateKeySize); + TestWithMockKeySize(algorithm, maxPrivateKeySize, maxPrivateKeySize + 1); + + TestWithMockKeySize(algorithm, (minPrivateKeySize + maxPrivateKeySize) / 2, (minPrivateKeySize + maxPrivateKeySize) / 2); + TestWithMockKeySize(algorithm, (minPrivateKeySize + maxPrivateKeySize) / 2, maxPrivateKeySize); + TestWithMockKeySize(algorithm, (minPrivateKeySize + maxPrivateKeySize) / 2, maxPrivateKeySize + 1); + + static void TestWithMockKeySize(CompositeMLDsaAlgorithm algorithm, int mockKeySize, int inputBufferSize) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + dsa.ExportCompositeMLDsaPrivateKeyCoreHook = destination => + { + // Buffer size must always be upper bound for the key length. + Assert.Equal(CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeUpperBound(algorithm), destination.Length); + return mockKeySize; + }; + + byte[] bytes = dsa.ExportCompositeMLDsaPrivateKey(); + Assert.Equal(1, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + Assert.Equal(mockKeySize, bytes.Length); + + Assert.Equal(mockKeySize, dsa.ExportCompositeMLDsaPrivateKey(new byte[inputBufferSize])); + Assert.Equal(2, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPrivateKey(new byte[inputBufferSize], out int bytesWritten)); + Assert.Equal(3, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + Assert.Equal(mockKeySize, bytesWritten); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void SignData_BufferSize(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + int testSignatureSize = vector.Algorithm.MaxSignatureSizeInBytes - + // Test returning less than maximum size for non-fixed size signatures. + CompositeMLDsaTestHelpers.ExecuteComponentFunc( + vector.Algorithm, + rsa => 0, + ecdsa => 1, + eddsa => 0); + + dsa.SignDataCoreHook = (data, context, destination) => + { + Assert.Equal(vector.Algorithm.MaxSignatureSizeInBytes, destination.Length); + return testSignatureSize; + }; + + byte[] signature = dsa.SignData(vector.Message); + Assert.Equal(testSignatureSize, signature.Length); + + signature = new byte[vector.Algorithm.MaxSignatureSizeInBytes]; + dsa.AddSignatureBufferIsSameAssertion(signature); + + Assert.Equal(testSignatureSize, dsa.SignData(vector.Message, signature, [])); + + AssertExtensions.Equal(2, dsa.SignDataCoreCallCount); + } + + private const int PaddingSize = 10; + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPublicKey_CallsCore(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int maxPublicKeySize = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeUpperBound(algorithm); + int minPublicKeySize = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeLowerBound(algorithm); + + int keySize = (minPublicKeySize + maxPublicKeySize) / 2; + + dsa.ExportCompositeMLDsaPublicKeyCoreHook = destination => + { + // Filling past the expected size is allowed, but ignored. + destination.Fill(1); + return keySize; + }; + + byte[] exported = dsa.ExportCompositeMLDsaPublicKey(); + Assert.Equal(1, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + AssertExtensions.FilledWith(1, exported); + Assert.Equal(keySize, exported.Length); + + byte[] publicKey = CreatePaddedFilledArray(keySize, 42); + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPublicKey(publicKey.AsSpan(PaddingSize, keySize), out int bytesWritten)); + Assert.Equal(2, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + Assert.Equal(keySize, bytesWritten); + + // Padding should not be touched + AssertExtensions.FilledWith(42, publicKey.AsSpan(0, PaddingSize)); + AssertExtensions.FilledWith(1, publicKey.AsSpan(PaddingSize, keySize)); + AssertExtensions.FilledWith(42, publicKey.AsSpan(PaddingSize + keySize)); + + publicKey = CreatePaddedFilledArray(keySize, 42); + + Assert.Equal(keySize, dsa.ExportCompositeMLDsaPublicKey(publicKey.AsSpan(PaddingSize, keySize))); + Assert.Equal(3, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + + AssertExtensions.FilledWith(42, publicKey.AsSpan(0, PaddingSize)); + AssertExtensions.FilledWith(1, publicKey.AsSpan(PaddingSize, keySize)); + AssertExtensions.FilledWith(42, publicKey.AsSpan(PaddingSize + keySize)); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TryExportCompositeMLDsaPrivateKey_CallsCore(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int maxPrivateKeySize = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeUpperBound(algorithm); + int minPrivateKeySize = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeLowerBound(algorithm); + + int keySize = (minPrivateKeySize + maxPrivateKeySize) / 2; + + dsa.ExportCompositeMLDsaPrivateKeyCoreHook = destination => + { + // Filling past the expected size is allowed, but ignored. + destination.Fill(1); + return keySize; + }; + + byte[] exported = dsa.ExportCompositeMLDsaPrivateKey(); + Assert.Equal(1, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + AssertExtensions.FilledWith(1, exported); + Assert.Equal(keySize, exported.Length); + + byte[] privateKey = CreatePaddedFilledArray(keySize, 42); + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPrivateKey(privateKey.AsSpan(PaddingSize, keySize), out int bytesWritten)); + Assert.Equal(2, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + Assert.Equal(keySize, bytesWritten); + + // Padding should not be touched + AssertExtensions.FilledWith(42, privateKey.AsSpan(0, PaddingSize)); + AssertExtensions.FilledWith(1, privateKey.AsSpan(PaddingSize, keySize)); + AssertExtensions.FilledWith(42, privateKey.AsSpan(PaddingSize + keySize)); + + privateKey = CreatePaddedFilledArray(keySize, 42); + + Assert.Equal(keySize, dsa.ExportCompositeMLDsaPrivateKey(privateKey.AsSpan(PaddingSize, keySize))); + Assert.Equal(3, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + + AssertExtensions.FilledWith(42, privateKey.AsSpan(0, PaddingSize)); + AssertExtensions.FilledWith(1, privateKey.AsSpan(PaddingSize, keySize)); + AssertExtensions.FilledWith(42, privateKey.AsSpan(PaddingSize + keySize)); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void TrySignData_CallsCore(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + dsa.SignDataCoreHook = (_, _, _) => { return -1; }; + dsa.AddFillDestination(vector.Signature); + dsa.AddDataBufferIsSameAssertion(vector.Message); + dsa.AddContextBufferIsSameAssertion(Array.Empty()); + + byte[] exported = dsa.SignData(vector.Message, Array.Empty()); + AssertExtensions.LessThan(0, dsa.SignDataCoreCallCount); + AssertExtensions.SequenceEqual(exported, vector.Signature); + + byte[] signature = CreatePaddedFilledArray(vector.Signature.Length, 42); + + // Extra bytes in destination buffer should not be touched + Memory destination = signature.AsMemory(PaddingSize, vector.Algorithm.MaxSignatureSizeInBytes); + dsa.AddDestinationBufferIsSameAssertion(destination); + dsa.SignDataCoreCallCount = 0; + + int bytesWritten = dsa.SignData(vector.Message, destination.Span, Array.Empty()); + Assert.Equal(vector.Signature.Length, bytesWritten); + Assert.Equal(1, dsa.SignDataCoreCallCount); + AssertExpectedFill(signature, vector.Signature, PaddingSize, 42); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void VerifyData_CallsCore(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + dsa.VerifyDataCoreHook = (_, _, _) => true; + dsa.AddDataBufferIsSameAssertion(vector.Message); + dsa.AddSignatureBufferIsSameAssertion(vector.Signature); + dsa.AddContextBufferIsSameAssertion(Array.Empty()); + + AssertExtensions.TrueExpression(dsa.VerifyData(vector.Message, vector.Signature, Array.Empty())); + AssertExtensions.Equal(1, dsa.VerifyDataCoreCallCount); + + AssertExtensions.TrueExpression(dsa.VerifyData(vector.Message, vector.Signature, Array.Empty())); + AssertExtensions.Equal(2, dsa.VerifyDataCoreCallCount); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPublicKey_MaxSizeKey_MinSizeDestination(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int maxKeyLength = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeUpperBound(algorithm); + int minKeyLength = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeLowerBound(algorithm); + byte[] minSizeKey = new byte[minKeyLength]; + + dsa.ExportCompositeMLDsaPublicKeyCoreHook = destination => + { + Assert.Equal(maxKeyLength, destination.Length); + destination.Fill(1); + return maxKeyLength; + }; + + if (minKeyLength != maxKeyLength) + { + Assert.Throws(() => dsa.ExportCompositeMLDsaPublicKey(minSizeKey)); + Assert.Equal(1, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + AssertExtensions.FilledWith(0, minSizeKey); + + AssertExtensions.FalseExpression(dsa.TryExportCompositeMLDsaPublicKey(minSizeKey, out int bytesWritten)); + Assert.Equal(2, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + Assert.Equal(0, bytesWritten); + AssertExtensions.FilledWith(0, minSizeKey); + } + else + { + dsa.AddDestinationBufferIsSameAssertion(minSizeKey); + + int bytesWritten = dsa.ExportCompositeMLDsaPublicKey(minSizeKey); + Assert.Equal(1, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + Assert.Equal(minKeyLength, bytesWritten); + AssertExtensions.FilledWith(1, minSizeKey); + + minSizeKey.AsSpan().Clear(); + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPublicKey(minSizeKey, out bytesWritten)); + Assert.Equal(2, dsa.ExportCompositeMLDsaPublicKeyCoreCallCount); + Assert.Equal(minKeyLength, bytesWritten); + AssertExtensions.FilledWith(1, minSizeKey); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ExportCompositeMLDsaPrivateKey_MaxSizeKey_MinSizeDestination(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + int maxKeyLength = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeUpperBound(algorithm); + int minKeyLength = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeLowerBound(algorithm); + byte[] minSizeKey = new byte[minKeyLength]; + + dsa.ExportCompositeMLDsaPrivateKeyCoreHook = destination => + { + Assert.Equal(maxKeyLength, destination.Length); + destination.Fill(1); + return maxKeyLength; + }; + + if (minKeyLength != maxKeyLength) + { + Assert.Throws(() => dsa.ExportCompositeMLDsaPrivateKey(minSizeKey)); + Assert.Equal(1, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + AssertExtensions.FilledWith(0, minSizeKey); + + AssertExtensions.FalseExpression(dsa.TryExportCompositeMLDsaPrivateKey(minSizeKey, out int bytesWritten)); + Assert.Equal(2, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + Assert.Equal(0, bytesWritten); + AssertExtensions.FilledWith(0, minSizeKey); + } + else + { + dsa.AddDestinationBufferIsSameAssertion(minSizeKey); + + int bytesWritten = dsa.ExportCompositeMLDsaPrivateKey(minSizeKey); + Assert.Equal(1, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + Assert.Equal(minKeyLength, bytesWritten); + AssertExtensions.FilledWith(1, minSizeKey); + + minSizeKey.AsSpan().Clear(); + + AssertExtensions.TrueExpression(dsa.TryExportCompositeMLDsaPrivateKey(minSizeKey, out bytesWritten)); + Assert.Equal(2, dsa.ExportCompositeMLDsaPrivateKeyCoreCallCount); + Assert.Equal(minKeyLength, bytesWritten); + AssertExtensions.FilledWith(1, minSizeKey); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void VerifyData_CoreReturnsFalse(CompositeMLDsaTestVector vector) + { + using CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(vector.Algorithm); + dsa.VerifyDataCoreHook = (_, _, _) => false; + AssertExtensions.FalseExpression(dsa.VerifyData(vector.Message, vector.Signature, Array.Empty())); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void Dispose_CallsVirtual(CompositeMLDsaAlgorithm algorithm) + { + CompositeMLDsaMockImplementation dsa = CompositeMLDsaMockImplementation.Create(algorithm); + bool disposeCalled = false; + + // First Dispose call should invoke overridden Dispose should be called + dsa.DisposeHook = (bool disposing) => + { + AssertExtensions.TrueExpression(disposing); + disposeCalled = true; + }; + + dsa.Dispose(); + AssertExtensions.TrueExpression(disposeCalled); + + // Subsequent Dispose calls should be a no-op + dsa.DisposeHook = _ => Assert.Fail(); + + dsa.Dispose(); + dsa.Dispose(); // no throw + + CompositeMLDsaTestHelpers.VerifyDisposed(dsa); + } + + private static void AssertExpectedFill(ReadOnlySpan buffer, ReadOnlySpan content, int offset, byte paddingElement) + { + // Ensure that the data was filled correctly + AssertExtensions.SequenceEqual(content, buffer.Slice(offset, content.Length)); + + // And that the padding was not touched + AssertExtensions.FilledWith(paddingElement, buffer.Slice(0, offset)); + AssertExtensions.FilledWith(paddingElement, buffer.Slice(offset + content.Length)); + } + + private static byte[] CreatePaddedFilledArray(int size, byte filling) + { + byte[] publicKey = new byte[size + 2 * PaddingSize]; + publicKey.AsSpan().Fill(filling); + return publicKey; + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs index 66cf09da1100e7..24617d110df62c 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs @@ -1,21 +1,498 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Formats.Asn1; +using System.Linq; +using Microsoft.DotNet.RemoteExecutor; using Xunit; +using Xunit.Sdk; namespace System.Security.Cryptography.Tests { public static class CompositeMLDsaFactoryTests { [Fact] - public static void NoSupportYet() + public static void NullArgumentValidation() { - AssertExtensions.FalseExpression(CompositeMLDsa.IsSupported); - AssertExtensions.FalseExpression(CompositeMLDsa.IsAlgorithmSupported(CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss)); + AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.GenerateKey(null)); + AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.IsAlgorithmSupported(null)); + AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(null, Array.Empty())); + AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(null, ReadOnlySpan.Empty)); + AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.ImportCompositeMLDsaPublicKey(null, Array.Empty())); + AssertExtensions.Throws("algorithm", static () => CompositeMLDsa.ImportCompositeMLDsaPublicKey(null, ReadOnlySpan.Empty)); - Assert.Throws(() => CompositeMLDsa.GenerateKey(CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss)); - Assert.Throws(() => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss, new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes])); - Assert.Throws(() => CompositeMLDsa.ImportCompositeMLDsaPublicKey(CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss, new byte[MLDsaAlgorithm.MLDsa44.PublicKeySizeInBytes])); + AssertExtensions.Throws("source", static () => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256, null)); + AssertExtensions.Throws("source", static () => CompositeMLDsa.ImportCompositeMLDsaPublicKey(CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256, null)); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPrivateKey_Empty(CompositeMLDsaAlgorithm algorithm) + { + AssertImportBadPrivateKey(algorithm, Array.Empty()); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPrivateKey_ShortMLDsaSeed(CompositeMLDsaAlgorithm algorithm) + { + MLDsaKeyInfo mldsaVector = CompositeMLDsaTestData.GetMLDsaIetfTestVector(algorithm); + AssertImportBadPrivateKey(algorithm, new byte[mldsaVector.PrivateSeed.Length - 1]); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPrivateKey_OnlyMLDsaSeed(CompositeMLDsaAlgorithm algorithm) + { + MLDsaKeyInfo mldsaVector = CompositeMLDsaTestData.GetMLDsaIetfTestVector(algorithm); + AssertImportBadPrivateKey(algorithm, mldsaVector.PrivateSeed.ToArray()); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPrivateKey_ShortTradKey(CompositeMLDsaAlgorithm algorithm) + { + MLDsaKeyInfo mldsaVector = CompositeMLDsaTestData.GetMLDsaIetfTestVector(algorithm); + byte[] shortTradKey = mldsaVector.PrivateSeed; + Array.Resize(ref shortTradKey, shortTradKey.Length + 1); + + AssertImportBadPrivateKey(algorithm, shortTradKey); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPrivateKey_TrailingData(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + byte[] key = vector.SecretKey; + Array.Resize(ref key, key.Length + 1); + + AssertImportBadPrivateKey(vector.Algorithm, key); + } + + [Fact] + public static void ImportBadPrivateKey_Rsa_WrongAlgorithm() + { + // Get vector for MLDsa65WithRSA3072Pss + CompositeMLDsaTestData.CompositeMLDsaTestVector differentTradKey = + CompositeMLDsaTestData.AllIetfVectors.Single(vector => vector.Algorithm == CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss); + + // But use MLDsa65WithRSA4096Pss + AssertImportBadPrivateKey(CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss, differentTradKey.SecretKey); + + // And flip + differentTradKey = + CompositeMLDsaTestData.AllIetfVectors.Single(vector => vector.Algorithm == CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss); + + AssertImportBadPrivateKey(CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss, differentTradKey.SecretKey); + } + + [Fact] + public static void ImportBadPrivateKey_ECDsa_WrongAlgorithm() + { + // Get vector for MLDsa65WithECDsaP256 + CompositeMLDsaTestData.CompositeMLDsaTestVector differentTradKey = + CompositeMLDsaTestData.AllIetfVectors.Single(vector => vector.Algorithm == CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256); + + // But use MLDsa65WithECDsaP384 + AssertImportBadPrivateKey(CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384, differentTradKey.SecretKey); + + // And flip + differentTradKey = + CompositeMLDsaTestData.AllIetfVectors.Single(vector => vector.Algorithm == CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384); + + AssertImportBadPrivateKey(CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256, differentTradKey.SecretKey); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportPrivateKey_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + int bound = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeLowerBound(algorithm); + + AssertImportBadPrivateKey(algorithm, new byte[bound - 1]); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportPrivateKey_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + int bound = CompositeMLDsaTestHelpers.ExpectedPrivateKeySizeUpperBound(algorithm); + + AssertImportBadPrivateKey(algorithm, new byte[bound + 1]); + } + + [Fact] + public static void ImportBadPrivateKey_ECDsa_InvalidVersion() + { + CompositeMLDsaAlgorithm algorithm = CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256; + + // No version + AssertImportBadPrivateKey(algorithm, CreateKeyWithVersion(null)); + + // Unsupported version + AssertImportBadPrivateKey(algorithm, CreateKeyWithVersion(0)); + AssertImportBadPrivateKey(algorithm, CreateKeyWithVersion(2)); + + // Correct version, don't throw (unless platform does not support Composite ML-DSA) + CompositeMLDsaTestHelpers.AssertImportPrivateKey( + import => AssertThrowIfNotSupported(() => import(), algorithm), + algorithm, + CreateKeyWithVersion(1)); + + static byte[] CreateKeyWithVersion(int? version) + { + ECParameters ecdsaKey = EccTestData.GetNistP256ReferenceKey(); + + return ComposeKeys( + MLDsaTestsData.IetfMLDsa65.PrivateSeed, + WriteECPrivateKey(version, ecdsaKey.D, ecdsaKey.Curve.Oid.Value, ecdsaKey.Q)); + } + } + + [Fact] + public static void ImportBadPrivateKey_ECDsa_NoPrivateKey() + { + ECParameters ecdsaKey = EccTestData.GetNistP256ReferenceKey(); + + // no private key + byte[] compositeKey = ComposeKeys( + MLDsaTestsData.IetfMLDsa65.PrivateSeed, + WriteECPrivateKey(version: 1, d: null, ecdsaKey.Curve.Oid.Value, point: ecdsaKey.Q)); + + AssertImportBadPrivateKey(CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256, compositeKey); + } + + [Fact] + public static void ImportBadPrivateKey_ECDsa_WrongCurve() + { + CompositeMLDsaAlgorithm algorithm = CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256; + + // Wrong curve OID + AssertImportBadPrivateKey( + algorithm, + CreateKeyWithCurveOid(ECCurve.NamedCurves.nistP521.Oid.Value)); + + AssertImportBadPrivateKey( + algorithm, + CreateKeyWithCurveOid("1.3.36.3.3.2.8.1.1.7")); // brainpoolP256r1 + + // Domain parameters are optional, don't throw (unless platform does not support Composite ML-DSA) + CompositeMLDsaTestHelpers.AssertImportPrivateKey( + import => AssertThrowIfNotSupported(() => import(), algorithm), + algorithm, + CreateKeyWithCurveOid(ECCurve.NamedCurves.nistP256.Oid.Value)); + + static byte[] CreateKeyWithCurveOid(string? oid) + { + ECParameters ecdsaKey = EccTestData.GetNistP256ReferenceKey(); + + return ComposeKeys( + MLDsaTestsData.IetfMLDsa65.PrivateSeed, + WriteECPrivateKey(version: 1, ecdsaKey.D, oid, ecdsaKey.Q)); + } + } + + [Fact] + public static void ImportPrivateKey_ECDsa_NoPublicKey() + { + CompositeMLDsaAlgorithm algorithm = CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256; + ECParameters ecdsaKey = EccTestData.GetNistP256ReferenceKey(); + + // no public key + byte[] compositeKey = ComposeKeys( + MLDsaTestsData.IetfMLDsa65.PrivateSeed, + WriteECPrivateKey(version: 1, ecdsaKey.D, ecdsaKey.Curve.Oid.Value, point: null)); + + // Public key is optional, don't throw (unless platform does not support Composite ML-DSA) + CompositeMLDsaTestHelpers.AssertImportPrivateKey( + import => AssertThrowIfNotSupported(() => import(), algorithm), + algorithm, + compositeKey); + } + + static byte[] ComposeKeys(byte[] mldsaKey, AsnWriter tradKey) + { + byte[] compositeKey = new byte[mldsaKey.Length + tradKey.GetEncodedLength()]; + mldsaKey.CopyTo(compositeKey, 0); + tradKey.Encode(compositeKey.AsSpan(mldsaKey.Length)); + return compositeKey; + } + + private static AsnWriter WriteECPrivateKey(int? version, byte[]? d, string? oid, ECPoint? point) + { + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + + // ECPrivateKey + using (writer.PushSequence()) + { + // version + if (version is int v) + { + writer.WriteInteger(v); + } + + // privateKey + if (d is not null) + { + writer.WriteOctetString(d); + } + + // domainParameters + if (oid is not null) + { + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0, isConstructed: true))) + { + writer.WriteObjectIdentifier(oid); + } + } + + // publicKey + if (point is ECPoint q) + { + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 1, isConstructed: true))) + { + int publicKeyLength = 1 + q.X.Length + q.Y.Length; + byte[] publicKeyBytes = new byte[publicKeyLength]; + + publicKeyBytes[0] = 0x04; + q.X.CopyTo(publicKeyBytes.AsSpan(1)); + q.Y.CopyTo(publicKeyBytes.AsSpan(1 + q.X.Length)); + + writer.WriteBitString(publicKeyBytes); + } + } + } + + return writer; + } + + private static void AssertImportBadPrivateKey(CompositeMLDsaAlgorithm algorithm, byte[] key) + { + CompositeMLDsaTestHelpers.AssertImportPrivateKey( + import => AssertThrowIfNotSupported( + () => AssertExtensions.Throws(() => import()), + algorithm), + algorithm, + key); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPublicKey_Empty(CompositeMLDsaAlgorithm algorithm) + { + AssertImportBadPublicKey(algorithm, Array.Empty()); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPublicKey_ShortMLDsaKey(CompositeMLDsaAlgorithm algorithm) + { + MLDsaKeyInfo mldsaVector = CompositeMLDsaTestData.GetMLDsaIetfTestVector(algorithm); + AssertImportBadPublicKey(algorithm, new byte[mldsaVector.PublicKey.Length - 1]); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPublicKey_OnlyMLDsaKey(CompositeMLDsaAlgorithm algorithm) + { + MLDsaKeyInfo mldsaVector = CompositeMLDsaTestData.GetMLDsaIetfTestVector(algorithm); + AssertImportBadPublicKey(algorithm, mldsaVector.PublicKey.ToArray()); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPublicKey_ShortTradKey(CompositeMLDsaAlgorithm algorithm) + { + MLDsaKeyInfo mldsaVector = CompositeMLDsaTestData.GetMLDsaIetfTestVector(algorithm); + byte[] shortTradKey = mldsaVector.PublicKey; + Array.Resize(ref shortTradKey, shortTradKey.Length + 1); + + AssertImportBadPublicKey(algorithm, shortTradKey); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPublicKey_TrailingData(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + byte[] key = vector.PublicKey; + Array.Resize(ref key, key.Length + 1); + + AssertImportBadPublicKey(vector.Algorithm, key); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedECDsaAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportBadPublicKey_ECDsa_Uncompressed(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + byte[] key = vector.PublicKey.AsSpan().ToArray(); + int formatIndex = CompositeMLDsaTestHelpers.MLDsaAlgorithms[vector.Algorithm].PublicKeySizeInBytes; + + // Uncompressed + Assert.Equal(4, key[formatIndex]); + + key[formatIndex] = 0; + AssertImportBadPublicKey(vector.Algorithm, key); + + key[formatIndex] = 1; + AssertImportBadPublicKey(vector.Algorithm, key); + + key[formatIndex] = 2; + AssertImportBadPublicKey(vector.Algorithm, key); + + key[formatIndex] = 3; + AssertImportBadPublicKey(vector.Algorithm, key); + } + + [Fact] + public static void ImportBadPublicKey_Rsa_WrongAlgorithm() + { + // Get vector for MLDsa65WithRSA3072Pss + CompositeMLDsaTestData.CompositeMLDsaTestVector differentTradKey = + CompositeMLDsaTestData.AllIetfVectors.Single(vector => vector.Algorithm == CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss); + + // But use MLDsa65WithRSA4096Pss + AssertImportBadPublicKey(CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss, differentTradKey.PublicKey); + + // And flip + differentTradKey = + CompositeMLDsaTestData.AllIetfVectors.Single(vector => vector.Algorithm == CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss); + + AssertImportBadPublicKey(CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss, differentTradKey.PublicKey); + } + + [Fact] + public static void ImportBadPublicKey_ECDsa_WrongAlgorithm() + { + // Get vector for MLDsa65WithECDsaP256 + CompositeMLDsaTestData.CompositeMLDsaTestVector differentTradKey = + CompositeMLDsaTestData.AllIetfVectors.Single(vector => vector.Algorithm == CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256); + + // But use MLDsa65WithECDsaP384 + AssertImportBadPublicKey(CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384, differentTradKey.PublicKey); + + // And flip + differentTradKey = + CompositeMLDsaTestData.AllIetfVectors.Single(vector => vector.Algorithm == CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384); + + AssertImportBadPublicKey(CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256, differentTradKey.PublicKey); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportPublicKey_LowerBound(CompositeMLDsaAlgorithm algorithm) + { + int bound = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeLowerBound(algorithm); + + AssertImportBadPublicKey(algorithm, new byte[bound - 1]); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void ImportPublicKey_UpperBound(CompositeMLDsaAlgorithm algorithm) + { + int bound = CompositeMLDsaTestHelpers.ExpectedPublicKeySizeUpperBound(algorithm); + + AssertImportBadPublicKey(algorithm, new byte[bound + 1]); + } + + private static void AssertImportBadPublicKey(CompositeMLDsaAlgorithm algorithm, byte[] key) + { + CompositeMLDsaTestHelpers.AssertImportPublicKey( + import => AssertThrowIfNotSupported( + () => AssertExtensions.Throws(() => import()), + algorithm), + algorithm, + key); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void AlgorithmMatches_GenerateKey(CompositeMLDsaAlgorithm algorithm) + { + AssertThrowIfNotSupported( + () => + { + using CompositeMLDsa dsa = CompositeMLDsa.GenerateKey(algorithm); + Assert.Equal(algorithm, dsa.Algorithm); + }, + algorithm); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void AlgorithmMatches_Import(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + CompositeMLDsaTestHelpers.AssertImportPublicKey( + import => AssertThrowIfNotSupported(() => Assert.Equal(vector.Algorithm, import().Algorithm), vector.Algorithm), + vector.Algorithm, + vector.PublicKey); + + CompositeMLDsaTestHelpers.AssertImportPrivateKey( + import => AssertThrowIfNotSupported(() => Assert.Equal(vector.Algorithm, import().Algorithm), vector.Algorithm), + vector.Algorithm, + vector.SecretKey); + } + + [Fact] + public static void IsSupported_AgreesWithPlatform() + { + // Composites are supported everywhere MLDsa is supported + Assert.Equal(MLDsa.IsSupported, CompositeMLDsa.IsSupported); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.AllAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void IsAlgorithmSupported_AgreesWithPlatform(CompositeMLDsaAlgorithm algorithm) + { + bool supported = CompositeMLDsaTestHelpers.ExecuteComponentFunc( + algorithm, + rsa => MLDsa.IsSupported, + ecdsa => ecdsa.IsSec && MLDsa.IsSupported, + eddsa => false); + + Assert.Equal( + supported, + CompositeMLDsa.IsAlgorithmSupported(algorithm)); + } + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public static void IsSupported_InitializesCrypto() + { + string arg = CompositeMLDsa.IsSupported ? "1" : "0"; + + // This ensures that Composite ML-DSA is the first cryptographic algorithm touched in the process, which kicks off + // the initialization of the crypto layer on some platforms. Running in a remote executor ensures no other + // test has pre-initialized anything. + RemoteExecutor.Invoke(static (string isSupportedStr) => + { + bool isSupported = isSupportedStr == "1"; + return CompositeMLDsa.IsSupported == isSupported ? RemoteExecutor.SuccessExitCode : 0; + }, arg).Dispose(); + } + + // Asserts the test throws PlatformNotSupportedException if Composite ML-DSA is supported; + // otherwise runs the test normally. + private static void AssertThrowIfNotSupported(Action test, CompositeMLDsaAlgorithm algorithm) + { + if (CompositeMLDsa.IsAlgorithmSupported(algorithm)) + { + test(); + } + else + { + try + { + test(); + } + catch (PlatformNotSupportedException pnse) + { + Assert.Contains("CompositeMLDsa", pnse.Message); + } + catch (ThrowsException te) when (te.InnerException is PlatformNotSupportedException pnse) + { + Assert.Contains("CompositeMLDsa", pnse.Message); + } + } } } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaImplementationTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaImplementationTests.cs new file mode 100644 index 00000000000000..03ac1315b541ff --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaImplementationTests.cs @@ -0,0 +1,139 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Security.Cryptography.Tests +{ + [ConditionalClass(typeof(CompositeMLDsa), nameof(CompositeMLDsa.IsSupported))] + public sealed class CompositeMLDsaImplementationTests : CompositeMLDsaTestsBase + { + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void CompositeMLDsaIsOnlyPublicAncestor_GenerateKey(CompositeMLDsaAlgorithm algorithm) + { + AssertCompositeMLDsaIsOnlyPublicAncestor(() => CompositeMLDsa.GenerateKey(algorithm)); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public static void CompositeMLDsaIsOnlyPublicAncestor_Import(CompositeMLDsaTestData.CompositeMLDsaTestVector info) + { + CompositeMLDsaTestHelpers.AssertImportPublicKey( + AssertCompositeMLDsaIsOnlyPublicAncestor, info.Algorithm, info.PublicKey); + + CompositeMLDsaTestHelpers.AssertImportPrivateKey( + AssertCompositeMLDsaIsOnlyPublicAncestor, info.Algorithm, info.SecretKey); + } + + private static void AssertCompositeMLDsaIsOnlyPublicAncestor(Func createKey) + { + using CompositeMLDsa key = createKey(); + Type keyType = key.GetType(); + while (keyType != null && keyType != typeof(CompositeMLDsa)) + { + AssertExtensions.FalseExpression(keyType.IsPublic); + keyType = keyType.BaseType; + } + + Assert.Equal(typeof(CompositeMLDsa), keyType); + } + + #region Roundtrip by exporting then importing + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void RoundTrip_Export_Import_PublicKey(CompositeMLDsaAlgorithm algorithm) + { + // Generate new key + using CompositeMLDsa dsa = GenerateKey(algorithm); + + CompositeMLDsaTestHelpers.AssertExportPublicKey( + export => + { + // Roundtrip using public key. First export it. + byte[] exportedPublicKey = export(dsa); + CompositeMLDsaTestHelpers.AssertImportPublicKey( + import => + { + // Then import it. + using CompositeMLDsa roundTrippedDsa = import(); + + // Verify the roundtripped object has the same key + Assert.Equal(algorithm, roundTrippedDsa.Algorithm); + AssertExtensions.SequenceEqual(dsa.ExportCompositeMLDsaPublicKey(), roundTrippedDsa.ExportCompositeMLDsaPublicKey()); + Assert.Throws(() => roundTrippedDsa.ExportCompositeMLDsaPrivateKey()); + }, + algorithm, + exportedPublicKey); + }); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void RoundTrip_Export_Import_PrivateKey(CompositeMLDsaAlgorithm algorithm) + { + // Generate new key + using CompositeMLDsa dsa = GenerateKey(algorithm); + + CompositeMLDsaTestHelpers.AssertExportPrivateKey( + export => + { + // Roundtrip using secret key. First export it. + byte[] exportedSecretKey = export(dsa); + CompositeMLDsaTestHelpers.AssertImportPrivateKey( + import => + { + // Then import it. + using CompositeMLDsa roundTrippedDsa = import(); + + // Verify the roundtripped object has the same key + Assert.Equal(algorithm, roundTrippedDsa.Algorithm); + AssertExtensions.SequenceEqual(dsa.ExportCompositeMLDsaPrivateKey(), roundTrippedDsa.ExportCompositeMLDsaPrivateKey()); + AssertExtensions.SequenceEqual(dsa.ExportCompositeMLDsaPublicKey(), roundTrippedDsa.ExportCompositeMLDsaPublicKey()); + }, + algorithm, + exportedSecretKey); + }); + } + + #endregion Roundtrip by exporting then importing + + #region Roundtrip by importing then exporting + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void RoundTrip_Import_Export_PublicKey(CompositeMLDsaTestData.CompositeMLDsaTestVector info) + { + CompositeMLDsaTestHelpers.AssertImportPublicKey(import => + CompositeMLDsaTestHelpers.AssertExportPublicKey(export => + CompositeMLDsaTestHelpers.WithDispose(import(), dsa => + CompositeMLDsaTestHelpers.AssertPublicKeyEquals(info.Algorithm, info.PublicKey, export(dsa)))), + info.Algorithm, + info.PublicKey); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void RoundTrip_Import_Export_PrivateKey(CompositeMLDsaTestData.CompositeMLDsaTestVector info) + { + CompositeMLDsaTestHelpers.AssertImportPrivateKey(import => + CompositeMLDsaTestHelpers.AssertExportPrivateKey(export => + CompositeMLDsaTestHelpers.WithDispose(import(), dsa => + CompositeMLDsaTestHelpers.AssertPrivateKeyEquals(info.Algorithm, info.SecretKey, export(dsa)))), + info.Algorithm, + info.SecretKey); + } + + #endregion Roundtrip by importing then exporting + + protected override CompositeMLDsa GenerateKey(CompositeMLDsaAlgorithm algorithm) => + CompositeMLDsa.GenerateKey(algorithm); + + protected override CompositeMLDsa ImportPublicKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => + CompositeMLDsa.ImportCompositeMLDsaPublicKey(algorithm, source); + + protected override CompositeMLDsa ImportPrivateKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => + CompositeMLDsa.ImportCompositeMLDsaPrivateKey(algorithm, source); + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaMockImplementation.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaMockImplementation.cs new file mode 100644 index 00000000000000..b78e08e5b3ca4b --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaMockImplementation.cs @@ -0,0 +1,258 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Security.Cryptography.Tests +{ + internal sealed class CompositeMLDsaMockImplementation : CompositeMLDsa + { + internal static CompositeMLDsaMockImplementation Create(CompositeMLDsaAlgorithm algorithm) => + new CompositeMLDsaMockImplementation(algorithm); + + public CompositeMLDsaMockImplementation(CompositeMLDsaAlgorithm algorithm) + : base(algorithm) + { + } + + internal delegate int SignDataFunc(ReadOnlySpan data, ReadOnlySpan context, Span destination); + internal delegate bool VerifyDataFunc(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature); + internal delegate int ExportFunc(Span destination); + internal delegate void DisposeAction(bool disposing); + + public int SignDataCoreCallCount = 0; + public int VerifyDataCoreCallCount = 0; + public int ExportCompositeMLDsaPublicKeyCoreCallCount = 0; + public int ExportCompositeMLDsaPrivateKeyCoreCallCount = 0; + public int DisposeCallCount = 0; + + public SignDataFunc SignDataCoreHook { get; set; } = (_, _, _) => { Assert.Fail(); return 0; }; + public VerifyDataFunc VerifyDataCoreHook { get; set; } = (_, _, _) => { Assert.Fail(); return false; }; + public ExportFunc ExportCompositeMLDsaPublicKeyCoreHook { get; set; } = _ => { Assert.Fail(); return 0; }; + public ExportFunc ExportCompositeMLDsaPrivateKeyCoreHook { get; set; } = _ => { Assert.Fail(); return 0; }; + public DisposeAction DisposeHook { get; set; } = _ => { }; + + protected override int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) + { + SignDataCoreCallCount++; + return SignDataCoreHook(data, context, destination); + } + + protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) + { + VerifyDataCoreCallCount++; + return VerifyDataCoreHook(data, context, signature); + } + + protected override int ExportCompositeMLDsaPublicKeyCore(Span destination) + { + ExportCompositeMLDsaPublicKeyCoreCallCount++; + return ExportCompositeMLDsaPublicKeyCoreHook(destination); + } + + protected override int ExportCompositeMLDsaPrivateKeyCore(Span destination) + { + ExportCompositeMLDsaPrivateKeyCoreCallCount++; + return ExportCompositeMLDsaPrivateKeyCoreHook(destination); + } + + protected override void Dispose(bool disposing) + { + DisposeCallCount++; + DisposeHook(disposing); + } + + protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) + { + throw new NotImplementedException(); + } + + public void AddLengthAssertion() + { + SignDataFunc oldTrySignDataCoreHook = SignDataCoreHook; + SignDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, Span destination) => + { + int ret = oldTrySignDataCoreHook(data, context, destination); + AssertExtensions.LessThanOrEqualTo( + 32 + CompositeMLDsaTestHelpers.MLDsaAlgorithms[Algorithm].SignatureSizeInBytes, // randomizer + mldsaSig + destination.Length); + return ret; + }; + + VerifyDataFunc oldVerifyDataCoreHook = VerifyDataCoreHook; + VerifyDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + { + bool ret = oldVerifyDataCoreHook(data, context, signature); + AssertExtensions.LessThanOrEqualTo( + 32 + CompositeMLDsaTestHelpers.MLDsaAlgorithms[Algorithm].SignatureSizeInBytes, // randomizer + mldsaSig + signature.Length); + return ret; + }; + + ExportFunc oldExportCompositeMLDsaPublicKeyCoreHook = ExportCompositeMLDsaPublicKeyCoreHook; + ExportCompositeMLDsaPublicKeyCoreHook = (Span destination) => + { + int ret = oldExportCompositeMLDsaPublicKeyCoreHook(destination); + AssertExtensions.LessThanOrEqualTo( + CompositeMLDsaTestHelpers.MLDsaAlgorithms[Algorithm].PublicKeySizeInBytes, + destination.Length); + return ret; + }; + + ExportFunc oldExportCompositeMLDsaPrivateKeyCoreHook = ExportCompositeMLDsaPrivateKeyCoreHook; + ExportCompositeMLDsaPrivateKeyCoreHook = (Span destination) => + { + int ret = oldExportCompositeMLDsaPrivateKeyCoreHook(destination); + AssertExtensions.LessThanOrEqualTo( + CompositeMLDsaTestHelpers.MLDsaAlgorithms[Algorithm].PrivateSeedSizeInBytes, + destination.Length); + return ret; + }; + } + + public void AddDestinationBufferIsSameAssertion(ReadOnlyMemory buffer) + { + SignDataFunc oldTrySignDataCoreHook = SignDataCoreHook; + SignDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, Span destination) => + { + int ret = oldTrySignDataCoreHook(data, context, destination); + AssertExtensions.Same(buffer.Span, destination); + return ret; + }; + + ExportFunc oldExportCompositeMLDsaPublicKeyCoreHook = ExportCompositeMLDsaPublicKeyCoreHook; + ExportCompositeMLDsaPublicKeyCoreHook = (Span destination) => + { + int ret = oldExportCompositeMLDsaPublicKeyCoreHook(destination); + AssertExtensions.Same(buffer.Span, destination); + return ret; + }; + + ExportFunc oldExportCompositeMLDsaPrivateKeyCoreHook = ExportCompositeMLDsaPrivateKeyCoreHook; + ExportCompositeMLDsaPrivateKeyCoreHook = (Span destination) => + { + int ret = oldExportCompositeMLDsaPrivateKeyCoreHook(destination); + AssertExtensions.Same(buffer.Span, destination); + return ret; + }; + } + + public void AddContextBufferIsSameAssertion(ReadOnlyMemory buffer) + { + SignDataFunc oldTrySignDataCoreHook = SignDataCoreHook; + SignDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, Span destination) => + { + int ret = oldTrySignDataCoreHook(data, context, destination); + AssertExtensions.Same(buffer.Span, context); + return ret; + }; + + VerifyDataFunc oldVerifyDataCoreHook = VerifyDataCoreHook; + VerifyDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + { + bool ret = oldVerifyDataCoreHook(data, context, signature); + AssertExtensions.Same(buffer.Span, context); + return ret; + }; + } + + public void AddSignatureBufferIsSameAssertion(ReadOnlyMemory buffer) + { + VerifyDataFunc oldVerifyDataCoreHook = VerifyDataCoreHook; + VerifyDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + { + bool ret = oldVerifyDataCoreHook(data, context, signature); + AssertExtensions.Same(buffer.Span, signature); + return ret; + }; + } + + public void AddDataBufferIsSameAssertion(ReadOnlyMemory buffer) + { + SignDataFunc oldTrySignDataCoreHook = SignDataCoreHook; + SignDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, Span destination) => + { + int ret = oldTrySignDataCoreHook(data, context, destination); + AssertExtensions.Same(buffer.Span, data); + return ret; + }; + + VerifyDataFunc oldVerifyDataCoreHook = VerifyDataCoreHook; + VerifyDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + { + bool ret = oldVerifyDataCoreHook(data, context, signature); + AssertExtensions.Same(buffer.Span, data); + return ret; + }; + } + + public void AddFillDestination(byte b) + { + SignDataFunc oldTrySignDataCoreHook = SignDataCoreHook; + SignDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, Span destination) => + { + _ = oldTrySignDataCoreHook(data, context, destination); + destination.Fill(b); + return destination.Length; + }; + + ExportFunc oldExportCompositeMLDsaPublicKeyCoreHook = ExportCompositeMLDsaPublicKeyCoreHook; + ExportCompositeMLDsaPublicKeyCoreHook = (Span destination) => + { + _ = oldExportCompositeMLDsaPublicKeyCoreHook(destination); + destination.Fill(b); + return destination.Length; + }; + + ExportFunc oldExportCompositeMLDsaPrivateKeyCoreHook = ExportCompositeMLDsaPrivateKeyCoreHook; + ExportCompositeMLDsaPrivateKeyCoreHook = (Span destination) => + { + _ = oldExportCompositeMLDsaPrivateKeyCoreHook(destination); + destination.Fill(b); + return destination.Length; + }; + } + + public void AddFillDestination(byte[] fillContents) + { + SignDataFunc oldTrySignDataCoreHook = SignDataCoreHook; + SignDataCoreHook = (ReadOnlySpan data, ReadOnlySpan context, Span destination) => + { + _ = oldTrySignDataCoreHook(data, context, destination); + + if (fillContents.AsSpan().TryCopyTo(destination)) + { + return fillContents.Length; + } + + return 0; + }; + + ExportFunc oldExportCompositeMLDsaPublicKeyCoreHook = ExportCompositeMLDsaPublicKeyCoreHook; + ExportCompositeMLDsaPublicKeyCoreHook = (Span destination) => + { + _ = oldExportCompositeMLDsaPublicKeyCoreHook(destination); + + if (fillContents.AsSpan().TryCopyTo(destination)) + { + return fillContents.Length; + } + + return 0; + }; + + ExportFunc oldExportCompositeMLDsaPrivateKeyCoreHook = ExportCompositeMLDsaPrivateKeyCoreHook; + ExportCompositeMLDsaPrivateKeyCoreHook = (Span destination) => + { + _ = oldExportCompositeMLDsaPrivateKeyCoreHook(destination); + + if (fillContents.AsSpan().TryCopyTo(destination)) + { + return fillContents.Length; + } + + return 0; + }; + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.Raw.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.Raw.cs new file mode 100644 index 00000000000000..7ca48b35a17eb4 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.Raw.cs @@ -0,0 +1,157 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.Tests +{ + public static partial class CompositeMLDsaTestData + { + // https://github.com/lamps-wg/draft-composite-sigs/blob/656445f814e83e2d6c553f756911b9328e454d46/src/testvectors.json + internal static partial CompositeMLDsaTestVector[] AllIetfVectors => field ??= + [ + new("id-MLDSA44-RSA2048-PSS-SHA256", + CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss, + "DcdFDpknhN4feq6aqZfBHmi97YLeyFPgUhlnSUl6MOBdBotJw0HfNd1d8h7/A/tt8o6VewSlEqM1V0L052OUBKbXHOmEXNWsZc4Jbi5ZR0s29CoQ1k1F+PvBi4KFhtE3e8tEYfuXqslB2b2EDq19hgMc/pPxqk5t0ccDSVuwl2EtZ6kBeuQFkt8gtZlCfxXXhc2TNEPiXIWKCWpf5SSph9T7iqvx/o7G3fHReUCTRN6k1IpC4kAGdOarnEFh1c0W2DLlilKgfRaQxhOvRT6Uf0kXIwt82xz4wESjRZV9axtHU+6H5aRk8GRLVGl75rjeHZPhcmkBuyPW7wJIZrDVlgILwpPTUURjViEG0TCGGrOlU0EYOFADxYOZKe40PXoAMwZ0gJijGfreKhV0woOHOsC3hkXinlg5bucrqHT5pSKImK6i3FXeagGgKmysg+nfCra637Ffx+QiFy1N45D6AJLVZegcm6d1Evk9Xqc5JJ71f/pkvUPidw+p1JPtFeTanwHZnEWA3+6p0pWOSy9j5d4sk4bMaXefoJM7ebSy7j7Xd8AHF8+nkJ4i0faQw4cCU6u7snVsLkcQG7OcYlefpbNlgzJYwRGs3Ll7Y7BU9f95niTXU+98xYSs1W1ha/miZmlh9U3VIs1b+G8+WSjUgJtat0jijQs65Q034GhOLoxFR3sFMmZpqIqtlOTNWrpHSlumR9uza3pDmG6fT7WXe5IKgdrwcuiNNpnnm1p6Q/KvUe37vkWiTf63VjHNGWDWwdIKe7BncmWv2yD7ajTGQvNOEdFvtgrwspxC/Ugut1Ymq0AROYhDHtUY+Mw/ru03trVhcq16wCIaKgHlxvxX3sD5WP2S/cY/fESxh0hzPcusrfhLD3iDjl+quqQHjpdaJekeaJEY8N9CZYBom5+/t4j/Bwj4/sDO3Qx1AHoMzCrbrxlXev9auLwxK+aWwHrB7zLnEDQGGPFHcuZOHiHwrX0jE7YsGbxXp8blNEQee6t71/C7pmVavL98zd2rAbJlcC9p8np5teKrMjQy1gshXCwqT4V03dTC91WRV8b5KummHsGo5uEsxholTEWLcLCIpG27PDr52Qf8berpu3ErJj5X5/DGY0s+qG9RUOmSa0s8Kv1QVRnBy5omq0WhwpszJGxUfzuq/8IyEs2XXX5ZFYAxxlu6ylFyyPSbuhK6Qat1xUIrQ3MuPPxV96Dgt79N5JJ7gM2E1OqWqL08SBYcUCbnXSXitruI/z5QYuu2uuT9u0YF9a+M/g4nzN3WryuPM8RvHxEjKdUQvqMUlib0K/sKHXy3xJApEe7iyvhL73V64+bZ0XAeTAAOzL5K0QsROV0/vyqT9c68Klfq0HsPCoo6BuKEiQqtU6vRT9yfS2IX6z5D9523L6JdT+d8ojq0IV20zqOqL85YI7ENqbpIrdgDF6xNic/cyhIHTdynI6UVhjV/v4VMd9EoA8IZJWsOyCxnvU/6rXhhpnMJHfWAq2Lfjltuq/8RY2si/yMUS3MCb/wD+QNhwKhJpYIoJ0uORjhjVpCkMxkGXxw+a4MePTZQp72VAa8k0eFSkKKMTO8pyh5gLCjfzDxIAaOQ5uSuSgx8H6fs0Pgfiy97iUuPhKqQWTog4T03Rea0P6n8NwiNnsgYub4MU6k2JGYcC+6G+oF8tsbG0+CRft57gmmZn2PnEDUx+Yx43UsAc9e5d3b7UFw9rWM3uTyhJKX49SZ0m0Wkis3+zzL1Nmzttv58ITCCAQoCggEBAKL0gYF8m+uW2ZSizHsTVzkSPfjAa7eit7CPr7K12kjq196WIfBS1B/IWW9nmTIwU+ckLvZK5hg1x7KDqlZnj5T1NAlg9J64e1x7yg38+MeFMiawhNb/8uy9yGVOAm7fEOz2B+0HiLHgTNyOmnPw4BOJEMjpbso0ePGQEyTyHK7QaB53+zKRKVCiJvF2FocLL07ibEOn/0OaFewko8uhTTaiEKm9dsISFAkJatAVZjOn5/y9rtv48LKZx5x9QwdYiZFvVRkTKjV3YNwZaZA6abvSdeAuKPRHOE+KoYKrosvjHv/ON6PgNtgfWncQkZw7fX4sF26o14tMLZOSHGnvQUUCAwEAAQ==", + "MIIR4jCCBzagAwIBAgIUfOx8p+nC3WcJnF1oQPn+XzIn8f4wDQYLYIZIAYb6a1AJAQAwRzENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJjAkBgNVBAMMHWlkLU1MRFNBNDQtUlNBMjA0OC1QU1MtU0hBMjU2MB4XDTI1MDcyMTIzMzAwNFoXDTM1MDcyMjIzMzAwNFowRzENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJjAkBgNVBAMMHWlkLU1MRFNBNDQtUlNBMjA0OC1QU1MtU0hBMjU2MIIGQjANBgtghkgBhvprUAkBAAOCBi8ADcdFDpknhN4feq6aqZfBHmi97YLeyFPgUhlnSUl6MOBdBotJw0HfNd1d8h7/A/tt8o6VewSlEqM1V0L052OUBKbXHOmEXNWsZc4Jbi5ZR0s29CoQ1k1F+PvBi4KFhtE3e8tEYfuXqslB2b2EDq19hgMc/pPxqk5t0ccDSVuwl2EtZ6kBeuQFkt8gtZlCfxXXhc2TNEPiXIWKCWpf5SSph9T7iqvx/o7G3fHReUCTRN6k1IpC4kAGdOarnEFh1c0W2DLlilKgfRaQxhOvRT6Uf0kXIwt82xz4wESjRZV9axtHU+6H5aRk8GRLVGl75rjeHZPhcmkBuyPW7wJIZrDVlgILwpPTUURjViEG0TCGGrOlU0EYOFADxYOZKe40PXoAMwZ0gJijGfreKhV0woOHOsC3hkXinlg5bucrqHT5pSKImK6i3FXeagGgKmysg+nfCra637Ffx+QiFy1N45D6AJLVZegcm6d1Evk9Xqc5JJ71f/pkvUPidw+p1JPtFeTanwHZnEWA3+6p0pWOSy9j5d4sk4bMaXefoJM7ebSy7j7Xd8AHF8+nkJ4i0faQw4cCU6u7snVsLkcQG7OcYlefpbNlgzJYwRGs3Ll7Y7BU9f95niTXU+98xYSs1W1ha/miZmlh9U3VIs1b+G8+WSjUgJtat0jijQs65Q034GhOLoxFR3sFMmZpqIqtlOTNWrpHSlumR9uza3pDmG6fT7WXe5IKgdrwcuiNNpnnm1p6Q/KvUe37vkWiTf63VjHNGWDWwdIKe7BncmWv2yD7ajTGQvNOEdFvtgrwspxC/Ugut1Ymq0AROYhDHtUY+Mw/ru03trVhcq16wCIaKgHlxvxX3sD5WP2S/cY/fESxh0hzPcusrfhLD3iDjl+quqQHjpdaJekeaJEY8N9CZYBom5+/t4j/Bwj4/sDO3Qx1AHoMzCrbrxlXev9auLwxK+aWwHrB7zLnEDQGGPFHcuZOHiHwrX0jE7YsGbxXp8blNEQee6t71/C7pmVavL98zd2rAbJlcC9p8np5teKrMjQy1gshXCwqT4V03dTC91WRV8b5KummHsGo5uEsxholTEWLcLCIpG27PDr52Qf8berpu3ErJj5X5/DGY0s+qG9RUOmSa0s8Kv1QVRnBy5omq0WhwpszJGxUfzuq/8IyEs2XXX5ZFYAxxlu6ylFyyPSbuhK6Qat1xUIrQ3MuPPxV96Dgt79N5JJ7gM2E1OqWqL08SBYcUCbnXSXitruI/z5QYuu2uuT9u0YF9a+M/g4nzN3WryuPM8RvHxEjKdUQvqMUlib0K/sKHXy3xJApEe7iyvhL73V64+bZ0XAeTAAOzL5K0QsROV0/vyqT9c68Klfq0HsPCoo6BuKEiQqtU6vRT9yfS2IX6z5D9523L6JdT+d8ojq0IV20zqOqL85YI7ENqbpIrdgDF6xNic/cyhIHTdynI6UVhjV/v4VMd9EoA8IZJWsOyCxnvU/6rXhhpnMJHfWAq2Lfjltuq/8RY2si/yMUS3MCb/wD+QNhwKhJpYIoJ0uORjhjVpCkMxkGXxw+a4MePTZQp72VAa8k0eFSkKKMTO8pyh5gLCjfzDxIAaOQ5uSuSgx8H6fs0Pgfiy97iUuPhKqQWTog4T03Rea0P6n8NwiNnsgYub4MU6k2JGYcC+6G+oF8tsbG0+CRft57gmmZn2PnEDUx+Yx43UsAc9e5d3b7UFw9rWM3uTyhJKX49SZ0m0Wkis3+zzL1Nmzttv58ITCCAQoCggEBAKL0gYF8m+uW2ZSizHsTVzkSPfjAa7eit7CPr7K12kjq196WIfBS1B/IWW9nmTIwU+ckLvZK5hg1x7KDqlZnj5T1NAlg9J64e1x7yg38+MeFMiawhNb/8uy9yGVOAm7fEOz2B+0HiLHgTNyOmnPw4BOJEMjpbso0ePGQEyTyHK7QaB53+zKRKVCiJvF2FocLL07ibEOn/0OaFewko8uhTTaiEKm9dsISFAkJatAVZjOn5/y9rtv48LKZx5x9QwdYiZFvVRkTKjV3YNwZaZA6abvSdeAuKPRHOE+KoYKrosvjHv/ON6PgNtgfWncQkZw7fX4sF26o14tMLZOSHGnvQUUCAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgeAMA0GC2CGSAGG+mtQCQEAA4IKlQCrUXF/eq7sJ/4r66Ellsm/YXWgvuLUE69sq/JpdP8PXltmk0lnGs1pHaVHQO9h021dj9Z3kbbPN7WPdVf+6rOYrDv3fALi+1mOL7WAAcAQVAuQiN10BJbJfZ8WeBP49TUspm3o98ihY4kocCCK+nKYLz+1nyXZPj6A/Plp+e2Mqtaw7sRbknNBNdT8elsEeaMTzrM9PLtbTr2QW9ZsbOy5Iq27FKQO99xZQ4c9BP25TaOb15stq8T5a7i0pQVS19LgD90b89Jh1QWDAMSa8YRNq6P/ehbyYuDCZ0oROWheLu9hKsFky3xgV5yU7G3/eOtoOz4xPcOSwzSLBhs2MXK0eVZNwLh7zWFo1F3XBSvKj9mL+tT/2JGwLJZtcU3RTcUu/XoK1yOOPJVHWSSTJz7U4QZBN8OyR8BR0JNd4IJr2hivvQDytLw4smSAMtOQWz3lX66u5K/9G9h9Kb/XCg7JFaIJzGu9KxDOZjBhrHb9HQ33ZBTaH0XXr5Aakzwlk8OU4HEG//KUTN388ENv2g2SGhIoosskMf6zUFJUCRCLjzBVlF+fxkl+E0zpHZdThS99qPcJdpom2fsT/4Yx7IFj0lUthO8ZbAevfTFold6AHOIriBWoOQsaRZlUx6hQClN7q1YiuzqV+ukwffWjVuGkZoeuYecVFSTQb5wdQwrbiYR9Ax8bIiwmgdUTSY/YS0T/yigRSQSwGT7tzgNWIH2/wL6QCc/Tsk0b+QGsjKBdwRg80RqeVsAYmJlF01bgV+4mBstKOmk3nGb2cG8u5zCcw7d0iyyq3gESpcaikSvBwGOQfRcVEBkhwRIh/FYtb9EwyaiPt7/KWXym3tUMoi6lccn/l03qPiMbyJdt4RFSB03mTqNut/md9vbZMi2dBqBFyyzgf6CN0Lww5tWcY9vFlNPlNzuPOY59TxM84GOTEf1EQIBZ9hKVgKOYnnn+DBR7SY1g/DjF/OhQxruPY3vLQveJ0b2lNE/a/zEjVQJ30d27EBWEdT27EJlfOciuCKW3M2J4NYzTK3uBAiYym9AO4Atn//rR7RiCyVfu7Pj/+PcIhO6NEDR5dZzXL8jCDpisATZuokHJhfcI3SwIPnNP/4PNZd1NXP3YtC4YlA9Rsx+mLFB3q9GfyAoaIvacoLeqgdmJ2hAUG25lSo3Kc8pp4ULlZG1/aglZQK/RdoOX6BBW8yVYSPgrIfaJYrFEBEib361ZEaKOvU/IUeW1UHnWQL1iaM1emwuLVU5sUkzSIRSxPTF7oKJalHYp1y5KLzeTKtrQjjpJFvrAk3RC8HBBS0yR8oa2aIBpFZ5cnsAu9irC457saC3dZz2e2NcRa/0hWmhrX4S/V2okQoPKhpEsX1Uxa3UZvJHGYipOKLFPOHWpT14kRDZGcObeVcQN9Jvjk5o+t4R4pNPY3oAVyfajahE9in9IuHW0Buygv1DEv6Af6Jr4VNUZQd5NfAQ1XivcYernQuS895NxTvdZDhP6sU5bmNum1j1qqUV3y8abJU+VJkVPZAqj1sj1LT+MsgsN7cXE3JBZpewbqMv+JPcU7C23e0IUSN7W+5ugLiKqx//aPgVGA3dfi6r303MU1Y2G13S+KwOWnWhZTy9Wr2McqtdTxByw8cE+tAJ4lF4nir2PldmugLs6N7BVHheFYBs18oOE75ZJRooQ2tt/udFZLdcqtPOViVSsV8EgYp1fPEa/wZZHBsS4lieY6CuPixGtwRSHe574LpgWZkPOg/AWpODYZFLsriGkXaFabQCqlHdSFGi1w7S4TgJYmT95GHRIn8q1fEWNKmznRYUmzApXC35WmNvI/58TnlpqDlrPZ0WyY24bO1VQKAcezndNcPfGljPu13pmFoiGUYCwpOwMqABHTecss/1E/lnaKamBVASPu8sikRe6bxLqoQ/s7A6NAajOxDB0xJpbisbgTlFZCvfqjxJMSSbUPRzGv6FwF/ExEgNsWIXo6wlFshI7bFgoikFKvza2ykKiJmgWAN2t321iWcWvqVyTo3vEBdsPkd8A12mW4BzTTckzU2T6LF5U0WYmAc3/H2yi/rEnOP7m+iyuPPi7rYV/fenhXlx3uTRhBTZUDabBKjgtNr/Cw7CxUNQLe6OW/dgBUbfoVybmp7SoAYEQOR6Rlxp4o3fs1aLKmBQlsDEZVfead+528RwQN/8293xtMaZBei0veAqI8esHFVaEUvw3groVwi/whNvG9VYjK13sEBkkhR4Oq+Dt/CThbOKGp3UtclWkym3iK33PKppZyFIsUze+bwhVuI7ZHwj3Ja3Li/6t6buNNxAseM7dV9nRhRx7j4NCBuZWtaDPBt6cbuaEFZ46b1zddbLy4QmSo+qifxqfXxS5ipW3ZAyjwsKZh2lpUuU65NDyHaynXnpPgahiJc3ssFz95lZ+dyDBManiPRuGl06KckUWKF4WDqOjObLwjn91z4SdB7WNSloX9TKLa8SJHn8zuJpolIEGhO7tFVNlJ6re0L/N9riUok24+tawvJZf3E+sOg79gP7kFB9m2uNyVuOibDXwHRklUXc0G6qCJO7G7ucR9PcxDhjsHz29Rpg351dOa+aJYDy7vy0OPBGSTxYZhVjht4c/Q2LqbmDvkmQTEaHycpMyi0dN/H54PYdzKW538Q0PiwHTAJAUH5ZVK+q13I0wDYjfzUptEJI8DPHRLXxbtyvY2xt/i7wDtHgOr7S0jnIXBuK5L+webEwUReDFETkaan8Tvkney3nwiOTKISvHX+jAU9AcTifHX0v4PFhhV1PCg3y7hW0N7YXkJgBPx+vrkuevIpYkZzzODuKC2hHHwmHUnpMp6RVcn+5G68CbjdNmpxpecjvfbg8tScr95OjvJ/Ai9gAEDq9H7ImX9ceRdZKpN2Vc+alm8/VAimjZQCgm4dsogWNOxpp0m4RlVwai3q1EgsVyFvF4V1ChvSadoB9os9Ek62kdXwGM6LWluOG1gkNOliulBH411Yxgr0JlRZBux+WxTCh+tT/zt/RgIGeSHnpuzRIuu83SdYJuei82SWblVyTUYVzCYdzzgi/WQiNomXPJIiKu6U80A722rqB30G0A5LeXI6M7BKIVYU+nNynsgHK3e/uI7DLz9bgAy0OE3Fc2X43/aKcONxEA3wAs5RpUXJ14waJOwq7mEBMfJSw0V2Z0n6a66/AtNFJccYKDkrq+xNLd6PoPEjxRc4PD8PX3CxsiXHJ0eZ+yxeL5+gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOHSc0XaqF9uNh07ZLVGHMrtly/8yQNpWUmeW5ciZqI9tMQEguVM844YSFapXLYM3XwWL2CKu+KXdvoJB+Lzyxrc19TQ2ktr0m3Ytg/Z3BVwyDjJUEMKMiSrH3HC+LpLx560JSm+ULbNn+8aJ+YtnPWO1g875VNG1s9+lQ6GjVkyFJHWbgMxsUeN5dxn3J7WMmJQFvoniwubZH3aKU3VHTleY/5eguLnkTxJ5sPpmuS746CAlps9pccax12fdE7U13om7jYasUbVEnz+qAhTWYT+ccxhsaTenfF+BjxBOWA6o1RkevFTsGKS0ca0XMUpU3PsS+iKuqOY24Juic8amHdYd50w==", + "zzc6jNNJXPPKHXdCQ0h7i8OcMtHrpeJE5DbX684LxAYwggSjAgEAAoIBAQCi9IGBfJvrltmUosx7E1c5Ej34wGu3orewj6+ytdpI6tfeliHwUtQfyFlvZ5kyMFPnJC72SuYYNceyg6pWZ4+U9TQJYPSeuHtce8oN/PjHhTImsITW//LsvchlTgJu3xDs9gftB4ix4Ezcjppz8OATiRDI6W7KNHjxkBMk8hyu0Gged/sykSlQoibxdhaHCy9O4mxDp/9DmhXsJKPLoU02ohCpvXbCEhQJCWrQFWYzp+f8va7b+PCymcecfUMHWImRb1UZEyo1d2DcGWmQOmm70nXgLij0RzhPiqGCq6LL4x7/zjej4DbYH1p3EJGcO31+LBduqNeLTC2Tkhxp70FFAgMBAAECggEARu5lPObvu9HS7fcbSOt3SRlerlubx7hles5grUqpNJo80t/I8CItwZPlEjAnKAiPTQqcAotBswId5d+YErpLbox5VSfF8xzcXbpojkQySi75UIv/ltKcfF5zz1zwhDBG3s6NTqi74KmA63SLWLJd50L/cmTh29SRXJzZKHjW8WSGSp+lCZPZQsstqRaqNpzOb5HCSCQBvWIbDbrXyEHXddmWA2LmhE3nT2jooM3JU7s+CaUcBfpti26v0Nj/Blq685AobJGyC4qgVvQF5Fwdcw1O4Zpbvpjrtf6aDTDLABMr+d1FZMB9Izhn7PTWbAjzc6AyNic3ZmGF2oA+dxgtVQKBgQDOxUblXFgtfmoANErhlazq7JLdUVwkqdM6YPaAl8l7SLjzBWhu/E9yyGOYsjcBukuYv5YLnFUaB/kSlT8d/kv6kOvLd7k5p+h7M1xy1IPf1ZktDB8722fQ0lY+W4hT83qtWjPg8Rsi6k36IcwKe6ixhBX5lXLMsaS/0iCgp2rX0wKBgQDJwKl5VDxi4ZsRMKkgartYNEEzjn6OzZyaswjUA/PSQVK2qoHLFrp+dSuaqQPgIWkk9GI7SyP7Xwm+u7qGWtAdxBmlI01Vr/MHkQaUGyam6R2VHeKHZU6NihajY+t/TAJIssrZfAnrBPKmgZMAbehZoCcPlfKNo+aV15J7IO0rhwKBgQCGy4zgUUcawWKRJ4X5cf38WKWVqkiLjjqpwDRyuIEc4dfQdiIS2GFizsg+7090zOIjfiJvB0djZPc26hzvjKwzeO5/Alm6AIBKcL1ADtK5xSHKgDCMcQhI1hZrKHjDYeMDx94yMnwiUuTqv8Wov9zFfPpmbsscLmLcujuTABFjCQKBgHClkfqcfdr3/IzsjoH7Ff95ra4Lsb4qL3Zw4E0Ap/KNZpF3QmESn65b3azNEczi2sI3cWGJ4t1HgzlruAmsSudTxr3dqCBfzWI8J2AqiLpJDqtjtEfE2MdOgrVX5PV+iwfsTDaCe0ctzA4L6vgiZcklEqoxHuzWxriDVNZK3CGhAoGAZFIIsg3jtf/crHehZYeNZwPKsvNL915U3kvWbZiuiiMEAIsLzfOeTIsU80Jq/PiE5dny2kvt/8f069vd/mt+la/awEzdO3ohpulZlbcXhWxJvWZiC4Xbwb2nr4lWIcOWKEeTAlYW6Vo/UoSluTll4H1SKwd21YTMXTmREryAbEA=", + "MIIE3QIBADANBgtghkgBhvprUAkBAASCBMfPNzqM00lc88odd0JDSHuLw5wy0eul4kTkNtfrzgvEBjCCBKMCAQACggEBAKL0gYF8m+uW2ZSizHsTVzkSPfjAa7eit7CPr7K12kjq196WIfBS1B/IWW9nmTIwU+ckLvZK5hg1x7KDqlZnj5T1NAlg9J64e1x7yg38+MeFMiawhNb/8uy9yGVOAm7fEOz2B+0HiLHgTNyOmnPw4BOJEMjpbso0ePGQEyTyHK7QaB53+zKRKVCiJvF2FocLL07ibEOn/0OaFewko8uhTTaiEKm9dsISFAkJatAVZjOn5/y9rtv48LKZx5x9QwdYiZFvVRkTKjV3YNwZaZA6abvSdeAuKPRHOE+KoYKrosvjHv/ON6PgNtgfWncQkZw7fX4sF26o14tMLZOSHGnvQUUCAwEAAQKCAQBG7mU85u+70dLt9xtI63dJGV6uW5vHuGV6zmCtSqk0mjzS38jwIi3Bk+USMCcoCI9NCpwCi0GzAh3l35gSuktujHlVJ8XzHNxdumiORDJKLvlQi/+W0px8XnPPXPCEMEbezo1OqLvgqYDrdItYsl3nQv9yZOHb1JFcnNkoeNbxZIZKn6UJk9lCyy2pFqo2nM5vkcJIJAG9YhsNutfIQdd12ZYDYuaETedPaOigzclTuz4JpRwF+m2Lbq/Q2P8GWrrzkChskbILiqBW9AXkXB1zDU7hmlu+mOu1/poNMMsAEyv53UVkwH0jOGfs9NZsCPNzoDI2JzdmYYXagD53GC1VAoGBAM7FRuVcWC1+agA0SuGVrOrskt1RXCSp0zpg9oCXyXtIuPMFaG78T3LIY5iyNwG6S5i/lgucVRoH+RKVPx3+S/qQ68t3uTmn6HszXHLUg9/VmS0MHzvbZ9DSVj5biFPzeq1aM+DxGyLqTfohzAp7qLGEFfmVcsyxpL/SIKCnatfTAoGBAMnAqXlUPGLhmxEwqSBqu1g0QTOOfo7NnJqzCNQD89JBUraqgcsWun51K5qpA+AhaST0YjtLI/tfCb67uoZa0B3EGaUjTVWv8weRBpQbJqbpHZUd4odlTo2KFqNj639MAkiyytl8CesE8qaBkwBt6FmgJw+V8o2j5pXXknsg7SuHAoGBAIbLjOBRRxrBYpEnhflx/fxYpZWqSIuOOqnANHK4gRzh19B2IhLYYWLOyD7vT3TM4iN+Im8HR2Nk9zbqHO+MrDN47n8CWboAgEpwvUAO0rnFIcqAMIxxCEjWFmsoeMNh4wPH3jIyfCJS5Oq/xai/3MV8+mZuyxwuYty6O5MAEWMJAoGAcKWR+px92vf8jOyOgfsV/3mtrguxviovdnDgTQCn8o1mkXdCYRKfrlvdrM0RzOLawjdxYYni3UeDOWu4CaxK51PGvd2oIF/NYjwnYCqIukkOq2O0R8TYx06CtVfk9X6LB+xMNoJ7Ry3MDgvq+CJlySUSqjEe7NbGuINU1krcIaECgYBkUgiyDeO1/9ysd6Flh41nA8qy80v3XlTeS9ZtmK6KIwQAiwvN855MixTzQmr8+ITl2fLaS+3/x/Tr293+a36Vr9rATN07eiGm6VmVtxeFbEm9ZmILhdvBvaeviVYhw5YoR5MCVhbpWj9ShKW5OWXgfVIrB3bVhMxdOZESvIBsQA==", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "EaKY7YjzM4yKnZ/uVPzOyhl22eWxbGAjz0LQo5fwYGWiKVmIZRLgahVkE9midVfxz52izLYflIlvUETa+FIdduulxHjb43xs7RQMV4kdGCTmBjY/U2zAMxY1XbMBs3tzH3wIIbb5QdU+6TAWHqQCq+Y6t3VMW6CC0Naqts7lHeLePuxAYDFnSR2ItJ5xQfmM4FSdNH9yPmCXA969B3eghkLaHkHzygAO86i8yIO3Ks+70jTuxMMPyLuUzZv1monsAzWj512aYp2n6Ex4LVToYNz4vZrYMzZaaMif43E7vbR5TNib5Smjekrqi6T9r4BHGEfKQKiLDCeSq9tcA/+Z25IzV/dMtq/hzp2F4o+joQbiKcwNd0aQLnMnV3qcs1f04560+H9bGMqwfqs55coOORhODEtjNcJYbvPDtX0RC66VDZ39ymSX7iRw/APcYpsI38df8z9XFmbrHZCfSvtyM8GJdDcoYabx3G1QD1eG7G5EpzkiyWkNPkHq8LucgLuPtj1Gg9nu0hxIGeyrQO3uHWGwD+9vqwKecbZfSl2IGvfKJCPyECOGpxOV/nwTPJ7Oq5lUwHFantU7ZlFzrNkbg1Y0n33dA4GWRu03vmdtRWmqAfnElUv+Wwp47yNHFyz4AVMvLKO99e/rXpUV3sSGQvybRNvMahExCZHboUwBEHUBYaHcbvjW2FnbPiOurrJwNLgCJ3lsrsvdP1fwrCiGzMg/sfgGf8BAydj65BtFnj3E3dtjTTT8BRYLE3XESgMNLf23BaPwRC0KGWiq2FlFEGywKyMjtIneRLjOVWT0HdPGZDRiRn1Z9imGoCq4L20UTyu8TEFlGC5+HS3FCdeI68W+kbN55Q9g3/R1PjRPtpBqKiV6xFK/TQNSMbPnXccf7/fBdy5Nzai4/t7tBSFhqbpS+CnzlLIlAEzXg1PXm9o4gSGL8dZUDTIvNxs6GyusxNJU7w6FlGeYlIDQNu5nc8NA2Nl2oO7cZ7kBVDXJ16shyjzUoh60hc/gACeJz5LnoTlf4JJsRoH6ALjN47WcxQ+cVQJr88MKa2w83fi8QU/cXj89O1ZJSbGRg5y6KciYtWmyIuydKs/Fc9xEq8mxLG7O8peUX0ZR7vDfGXnLJeloF5t8JIfKzDqSU1qEncQmEOQI5thTawyLIZaGjsbCkWOYs58kfiBJKzFwao3FJ/AmZbUhS6xfDPuwiEclgZZQyddNZFXSqwDlf7/fD2YjkZx1Ysxejow/+00ZWQjeGefZPf1eE2QyW06kiLP7HH0uPIa3UOawYAj5dB4yOlTI6U3oOgO3T6Qp3I7ZGWwntEpT+x6LKI+TKG31eA99JMg3UtD3sd9riPDByUqhhOYG0RQ/FsOlE52LWeUdboeHSnPDu9zEbrwK0KMNdaGZM5Yfo6fNlx6ihQjl2EpEyARmYRpctal7ya/3RTVVv0Lgp4k+llxj9458pW8PQWrtVwFXQ5LxRxJtvRtIMEouDbSrVRMTUKGZsqU1GAjqoi6jTo9VYEeRi0Ck6dgMrOdG78/8qKj27KF7G8mFjm3zmaam4mv1V4Nz9SKqOUtmgTNo8sOa1gRAOtzb2HSnD3OW0vcZ99IjkRgRT3MoYbFfJw6SiRjK3Y3YvKoeWMzW5tq8uYg4Gz3eqCNNHhSbjWL3dw8rzTqsyEvWE2Nk0bjCVN+hujB26GwLdjrZEFC2UQKbzNgtRbr0/1FsbPLL36YZOyPPxwk/cFNBo1Q6dRrcLWe0Ude36qXD7bbA6g+lDtn+n98b2ns2WYUSEyBGrss7TA+lhe++0Pvlmt6aLmAjVuHdb7QmsQIfDNse2JV6rHWa8aHoMIDq4jDyOCG3Xomb6pOnkDgOcx7BoViyqAzBDjVRb9lX2UIxE8awXNSYo3ZiKHZ5Q0IrDl0zxUsGCBdAU0rY33Xlhxn2PNYCkgXln9Y4W+SH9oSAx4zbPY6EPN7NL+0ucxbwOcDJKom1QABh8nANZEf2W0J4eES2ucAALUOlrNeqcSSycvpXuvH5svLgxBQsCuhBYKre1C+4l8cVSdNuKvlYTvkvif0GU2H44a2BskHfkNaPH2j9Jq7dYamXB4iQa3RuwH/tFnEKa9PWLoJoj2u05cIpWkV9PeE6PiSzbCcQl5UsCmdl2is/OPYtZDZu2xEyaTPUmGOKO0jQYe3295ghASqScWlnsxEm4K2J4tur2RNxYTQIgnuX2vOy9iEGPvBOO5s8j2/RNmYLPBuazEX/gOsNsXvx9bkLfTDKUq8KAHkdt8dJm9ndM4PYd1OSgE4zlWw2F04rSEk7kQ2OUtx/Tf23RcZJRFMT5kXrU1E003x3cZrGv0Bw9pRebUZ2glNL40iavK2ukZyUCeGlekgAKmpdqGVAJ2ChSWnEfcxnhiwyMz6QsDCr1VbRu3EYk/pW32e4kC7b9Xvt11LX/k7z++3ju7Q4Kv9eAn8eiM4mYOxCmoXcMTl2P/2Uq0g6wsV3W7G6qeHI/weBu0hfXPRNVPzreqU500D1hjL/2iSkSw7DzRIQ10jEzh+2uf33it4OSHEVCVjZhWqiimR/PJXfMteBge8ANdrFlfjN7z3bRidOZHq4tGGhmAlJWrLEZJO8p60NoUY/Jnu5wH5kSrUqj7stdtAFzlpzCUO/57i3dEDVpzksS9VazqHMm3365SJMQoW5j78P+ifZAPnS3/TOP1iVZoTNhWlLp3WFaRcdHStSAX9hCEZW1w4ylu1XAX4MfvcqCQbZ6PLeDSuRfZxDYiVnjKYb6XdgUF17H3mZuz/jekO5lor4UIPQ5FfVUJ6yeHtNwOT19qx+RZRBcEmHjRQm+Oezy5gwRQ4S1tqYRHyX+lX7UJ+NsvATcrmd4HCedb2/0ysEy2tOeMtpao4iVi0cMTQwHVhmoigV1Y38YMFnb9HGzgRwFRr+NI+IecSYureJot2A6ygLeCPp0rZ6AMOUN49nEqc80QgLU50OU+47HOhXMRfOfNq/D8RFHy5/yw/FFxzoeCsZ9pllY8EfTZa+m5MxH9jtkRvKLvFoZsuRF9+g9bHJXwppr5vyo3LoxluLbULPDDZXzIjojAdwzWpFTbFhv4rh5/bza21HE3VuMqfTh+v/JuFaSyCboovm+JiFfy+XKNdWOPfPbOtgOoY9qsq5Gkt3176lsAIWHyIwND1Ae3+IlJ2uur7W8f4OEhYdPE1PY2xzeHt8qa21xM/6BhohOz1DX2JlstPs/xIXHCUrMl13e3+MnKO719veAAAAAAAAAAAAAAAAEyYzRGwFGFbd1WCw2N8+gcgF9J41nVwk9OWF40gC//FqnOPw2eU4d4uccZ19jnMEU/nn0F0ZNfeA8VABa7yqtY81v/7v9K1W+txe3tFLmn3zV2Cz4D6e71+fg1L0cAVzKQEXJ1KTfCycYvOWAnDcJdgdoVH122lkUapUPLhl+9Nr0Tsj2bSZsEEYNNTG99GN9eipUSKuYm/G6G3H7c2TayBU9mlqF+h1bMhCTWPCRDGM9BhM+brw5svEVO8E6i++JAVM3XsLKgySs/ZWHBa9QoNK2EcXKPAOHTgdMTBjCZ+FC35+ssmdeiaF7TfLC+sn8XBJ7plUZVz8j/NoK+Unmwz/peQ="), + new("id-MLDSA44-RSA2048-PKCS15-SHA256", + CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pkcs15, + "KVKcMmihxqbhK5ZQYgNj0Q3efufYrF6p4jjg0xJnK0RyyMyf9gF0o0zNAVK6gWwL/zl/fPwbY++9fxNMqr8V3EMWw+Jlxss9q8uCaghj4OXlisVuOi0ZWFGdypgKrCtZmArpLMMbXPie9cIjoQg27HrER2GmKcfqgHguiNJb160sx3V+CgJPs6F9dnX2vMSxpMWpthg3FmZmxLKqMDbiApEu4fwk9hHpANyJ+3u69aoe7GKePXnRi41x/axUso4yW7XPXoLXD6yOP1GxeOwq36gV1RZTTLYUk7uUF9PIqbintZPcXakFkmavuZ8zuoUNT9RNhecdonxH5ggJ12IaxunXkNvBX/ztX2z+NSpBjWu+SBFSfSKEr8ZUyFlH5jm+xQwYXZWK8IPQG0LJW3AoDFanKm2v4yl207dOeGU5kpt+QpjiJrsIjc9zUFkqImglwMI3HIdAbhOgRJAkBDowzbVYhKbf1wrO673LqAdZbsFaBAcm+JzvzE0iKOQxa4/r6CzKHvoC9vqoR0SVqTRAZ1lh3P4upJXld17aqiKJCGhBb4lfW9ZZqqwcXf+YF3b15fTf3vEUT1ZFb5hrg0hVFj742gcPKMPZpSDqeZVP6g75V1pwDpCpJNf8wcMWHVu3m/OTIliU2cimik27sM6HFoWvijIwxheckIJD35QGqrXLcELPgZ/PMTjiyR4UbiFRsuulbXhNklrObmgFjkWnMfySGimnVznSTBCQ3dwBbNCTlkGjZDYM/e2rbDAzxI7F6dYwGmVw+sozPHKcC2V49bHW7uRjwl9MSod6F0GZanaxXZxXB8ujYMd3OrPbILEAvB1B1lyJgS26EKOiGsWguNXqAg7uJMrkdvc3AnJwO8LbqaoxdCWDsV5jT/pqTgoPjcAC4OXUo8/5um5JkraEh4OTyTIQlEKDi62PDxykI4K6kZyowsqGpv6NHlkJLUa2wvgBQvayZqoFS9n1TIX/8xHZipoo542Q00hwFwY2Eo5W0KUDeXux5tXQJ/wnhpp5a9Mgaqzr3CNlW8PgIG0SPaG05/G3JI+oqcFvPuJdRG+EgGZgQJXh0/Ai0TmKcsAL8PlO02yuWJSPZ0NjKxjt7TM8ExDaMTbx/fp2mxfiMZJLYH9esDlXQqdZiUFQHDLk1yNHwPoHcaWYiYiw4i9PgEVpCYl9ZyQF9uREmfqI9FCLtERY8xtN8ZC6tuaXHznnO7S8xPpJAvFYIY4gZe9HKLi9UEdwXG5lwmaBb3K4kKTx0AT5kPVQNRnz6FAbrwi9ivLSBqIWluTvHiKe2FS9hYGUyiW/ZDYuYSCa8vcJBaOFWGXDCVgmdR7wambGTUlbxAXhXi5g+FSBwl4yR8jVMbjAIsfVqnksMu2gLk4OunHVDjiOgXE0398lAv2Cv2ywQMx2QzZrTL4ZZADpnckv8yDUwNjFcTszZqhcuYlIsIhL6hz7aVcvUJinxDXQvQ9VfmUPJ2T7ZKOCyex5uR0+mnsJ3L9i4xh+ZKoZlc47AuQ4RG/4J8Aqbo++eUFtnSgQ5Dl+/tIdc+NAHCzzv463yu7+2iqKZISHO1kHVjwZOMausaVsXiDQiSsbOochqZFyPvh7jXsjtIPqF5S3QKXq3yevMgm72KD5zfvZmCb3U14G+0oZ+H8OJxt6yntlX9xtdhzjk+C3ANJvTeJsr489k9FRbME7xv+JqCA85fZ9FjWKsZwcrt+zlYq4hzEG+wsYqLie5juGzeiLfFM3Aj8yfDCCAQoCggEBANMoSiC1VYMm6HSUd3IKwjsa4IyRV5Z5RmEIrRiryE6XzdDxwCF0dJznLQKh4TBRhzj0W3DwyaEsBAoOL4eSTVCn4bLRBPKDps/ZzW00+Wnvu4vmU73avT6nJYdu7vwRnClOdVvWya1aZRmysBjCa6h+yKnKmg4QP0plmSiVLJfSUub23BlwA1yvc3Q5syj8roCN8NfhmX2ocHPlfxmOvxqf8G23CaQXjcshuLgYI2rjNm70b1qEO2SlikJh9K7wIFhgt4NnJAbZOAd5TJxvZTFhhjBqsOYrxDp+Zv3WgurmFS2UtErRWEep6XIci9oPj3C21vZYv4K665PAsSg/RqsCAwEAAQ==", + "MIIR6DCCBzygAwIBAgIUSZmgZD6UoMTji7nsJLHxaqMLsHcwDQYLYIZIAYb6a1AJAQEwSjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxKTAnBgNVBAMMIGlkLU1MRFNBNDQtUlNBMjA0OC1QS0NTMTUtU0hBMjU2MB4XDTI1MDcyMTIzMzAwNFoXDTM1MDcyMjIzMzAwNFowSjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxKTAnBgNVBAMMIGlkLU1MRFNBNDQtUlNBMjA0OC1QS0NTMTUtU0hBMjU2MIIGQjANBgtghkgBhvprUAkBAQOCBi8AKVKcMmihxqbhK5ZQYgNj0Q3efufYrF6p4jjg0xJnK0RyyMyf9gF0o0zNAVK6gWwL/zl/fPwbY++9fxNMqr8V3EMWw+Jlxss9q8uCaghj4OXlisVuOi0ZWFGdypgKrCtZmArpLMMbXPie9cIjoQg27HrER2GmKcfqgHguiNJb160sx3V+CgJPs6F9dnX2vMSxpMWpthg3FmZmxLKqMDbiApEu4fwk9hHpANyJ+3u69aoe7GKePXnRi41x/axUso4yW7XPXoLXD6yOP1GxeOwq36gV1RZTTLYUk7uUF9PIqbintZPcXakFkmavuZ8zuoUNT9RNhecdonxH5ggJ12IaxunXkNvBX/ztX2z+NSpBjWu+SBFSfSKEr8ZUyFlH5jm+xQwYXZWK8IPQG0LJW3AoDFanKm2v4yl207dOeGU5kpt+QpjiJrsIjc9zUFkqImglwMI3HIdAbhOgRJAkBDowzbVYhKbf1wrO673LqAdZbsFaBAcm+JzvzE0iKOQxa4/r6CzKHvoC9vqoR0SVqTRAZ1lh3P4upJXld17aqiKJCGhBb4lfW9ZZqqwcXf+YF3b15fTf3vEUT1ZFb5hrg0hVFj742gcPKMPZpSDqeZVP6g75V1pwDpCpJNf8wcMWHVu3m/OTIliU2cimik27sM6HFoWvijIwxheckIJD35QGqrXLcELPgZ/PMTjiyR4UbiFRsuulbXhNklrObmgFjkWnMfySGimnVznSTBCQ3dwBbNCTlkGjZDYM/e2rbDAzxI7F6dYwGmVw+sozPHKcC2V49bHW7uRjwl9MSod6F0GZanaxXZxXB8ujYMd3OrPbILEAvB1B1lyJgS26EKOiGsWguNXqAg7uJMrkdvc3AnJwO8LbqaoxdCWDsV5jT/pqTgoPjcAC4OXUo8/5um5JkraEh4OTyTIQlEKDi62PDxykI4K6kZyowsqGpv6NHlkJLUa2wvgBQvayZqoFS9n1TIX/8xHZipoo542Q00hwFwY2Eo5W0KUDeXux5tXQJ/wnhpp5a9Mgaqzr3CNlW8PgIG0SPaG05/G3JI+oqcFvPuJdRG+EgGZgQJXh0/Ai0TmKcsAL8PlO02yuWJSPZ0NjKxjt7TM8ExDaMTbx/fp2mxfiMZJLYH9esDlXQqdZiUFQHDLk1yNHwPoHcaWYiYiw4i9PgEVpCYl9ZyQF9uREmfqI9FCLtERY8xtN8ZC6tuaXHznnO7S8xPpJAvFYIY4gZe9HKLi9UEdwXG5lwmaBb3K4kKTx0AT5kPVQNRnz6FAbrwi9ivLSBqIWluTvHiKe2FS9hYGUyiW/ZDYuYSCa8vcJBaOFWGXDCVgmdR7wambGTUlbxAXhXi5g+FSBwl4yR8jVMbjAIsfVqnksMu2gLk4OunHVDjiOgXE0398lAv2Cv2ywQMx2QzZrTL4ZZADpnckv8yDUwNjFcTszZqhcuYlIsIhL6hz7aVcvUJinxDXQvQ9VfmUPJ2T7ZKOCyex5uR0+mnsJ3L9i4xh+ZKoZlc47AuQ4RG/4J8Aqbo++eUFtnSgQ5Dl+/tIdc+NAHCzzv463yu7+2iqKZISHO1kHVjwZOMausaVsXiDQiSsbOochqZFyPvh7jXsjtIPqF5S3QKXq3yevMgm72KD5zfvZmCb3U14G+0oZ+H8OJxt6yntlX9xtdhzjk+C3ANJvTeJsr489k9FRbME7xv+JqCA85fZ9FjWKsZwcrt+zlYq4hzEG+wsYqLie5juGzeiLfFM3Aj8yfDCCAQoCggEBANMoSiC1VYMm6HSUd3IKwjsa4IyRV5Z5RmEIrRiryE6XzdDxwCF0dJznLQKh4TBRhzj0W3DwyaEsBAoOL4eSTVCn4bLRBPKDps/ZzW00+Wnvu4vmU73avT6nJYdu7vwRnClOdVvWya1aZRmysBjCa6h+yKnKmg4QP0plmSiVLJfSUub23BlwA1yvc3Q5syj8roCN8NfhmX2ocHPlfxmOvxqf8G23CaQXjcshuLgYI2rjNm70b1qEO2SlikJh9K7wIFhgt4NnJAbZOAd5TJxvZTFhhjBqsOYrxDp+Zv3WgurmFS2UtErRWEep6XIci9oPj3C21vZYv4K665PAsSg/RqsCAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgeAMA0GC2CGSAGG+mtQCQEBA4IKlQAFmqzptl0Srzc79jUTXMNvzVl3ioGMaTxf8w4o6vQk6tzcbB90OnIY623jr5M8Th7m4MWTSjC7f849Ih5fAI32Ofub4gLeQeuQsyxJXiPgAPBHhubmLusRrLOK+XM42PxgIoO3A2914/AqDcnpdY1u4wWVwl0fTGC5mpYPh3T863QyNNHskfkZyhjUH/R0GKzyAN7twO0AXqILUPg4p/Lj3Qm/jIkCBB8dMahjhTjfQDePPBLCQDrz5Ky4n+vinmm2MCIvTF6LzE2y9oJDrKcOK9ETrdkfOwwJ8wD/OHC/p9BoaNz+XQl+33RpJQykRywQoULlGHcNS93iJEAYvhzOPcG3sgoRmtNZkIteeG3ALLidU1QYutPZXRx2jzom6dU9M3cPcY+ZeIgqDWlmk3/Tb5COdG9B8tQdW0PwIXVd/0YX6cAPhelLr7GXFAdTqsGqtVxJJTGppq8mAbNmGJ4lBDX5Bs8LEWrHffQa5aPRAfs+6dhla5SOODpnKa6KkRAiVTrfzCIqo1UjILJtjgfaOtaKJ906bIS5RB1g/BlrrhFdBGMMQfc9CQltwNBVxGOLeNvnCJfyVJKOtFVeGbayk+NyN5GolNvM6cVA60DbvF6E/g4kT/zG/9wiqcxcgkrom5HINyz8aPn9T71BCAOI/XqVfWu83DnBMlP/EfGWVCGcC6JMDx6GUFo1yHzYFVLzBKHxpAHMpgIib5D8rZVXuuF6a3Fb5KeugcKEWhvHvYmm4VwF4AOGjH+3rGaptMxOfHfQ8w41976KMjIIbw3pfX/uIZ1Js5JaFEMsc0logQxb3WKtx1P1DtQMoNbwgbkDaalRKCPwH6cvnXC1cdj49oZjeCn0U5W8td1PIkyDfenpyJgRJAYy82sH1XLQoFTtYzzyF25j8sMFVvuFe1RtARqmq1TXZQx04DhZZ+UyDlnhqlFRcps5biNvEOj8qaOwua0PWWeBc3wKu+p5aygLxv2v+BgquZZrQls+ZlM8tL3gwpYxm1+vdiLIkaRQpNbDp0UrzOQRhPYyJB/v6nEjyq2pK7MNtMd1+ujzr1+a6M/GYxpKQuDdqbvJzCesL3kkOJ5Q2NPwRsMCYd726hUFa9UDFhC7hFMEI6QFCFQLrGIg0w7XKcRLnrPHg/zdGWH+FJnpk0twXdCXc6Gdfvbma511c9YX6tua9Aok9C996+CH0GvUxkgKA64v98o2nROPcCxMeJDi76M3OKqd83mk8Dn6lMAmcpwE4Iq4ylezfa4e8N1yPkaePoRDXJ31dgJFnVFIqe3wBgzs23XgI4SsxIFnkQdr5fKmurbeRgMa68kWNIYwtjvbkk9tINCNb2s4ZDHoFQ7Um9vGWjtlA9UmKN5s3DcRZ82mupylC8jfWkem9NJeMkeC3l977djX7aFgolvDqgra4yuav/RTmGovk88R+p1h9G1hhKT0ochiZNaz6mEcsYP8CqLmg75LOs5PIo2q9p8TTl+z30uAvYXEDr2Ig2mHD2m4yGeUWXpUgN6e0TBlK/CQ7JPRPv2rEpj/b0nOAu37HaUkXKq8mTsu4u5cYpkstGM/218/jooULXRbrqP5cfLF28l7oXG52tHHb/h70jfVMNOVaY7mBQIGMCPImjFyvjzH6qayd3EXNOX3aKhJAxuHA5qd8WKvvDcrv91p1WbsgmLSthFyIal1CM8M8Jn0QB8RkvSYzAT0KaI+3Zp7qRJ3g72qmPRjmPH3X7gnGegtR4I/B+QG4OlwiWhMxXLUA+Y9LYXGRhS2NpGhvgpN3LXHKjKPG4I00ONSOLryaIFc+yu866VGHmjeHzxv2JuXwlWsKAUkfuDxfIhFrP3hhqr5OHq4f43fvHMpVHkQlaEiDrM2gUMVkuNNZNSY/+s0hxxyk08NGLZr7jDewy0wxfTKJ2cAU0Bviieq8WydJJpbMYSQAvpq37nycHhQTbBWWh/FU8k73f26wi2+T3r72Schnv0NzB4wJH8Fj1vdmrg332CUrR8+PPwK5F479fQ5s7EuRqlTAKgD+we3gvaWgzFpnKrnhZEYoaCrUwbytqguwOovIb2IbZIs4AttWWdNu3q5HtaR6BjjsT1qiUsBIIoGDBKzYBiw6RNw0BEBkXydf93qw8bWZ/vvdCc1TMizjL38RknJ64kEB+5eLV6MPtG8Df371KBoas4GvsJ8ExAS94C3JaGDkHBFrUB39Blpbl7p5fQy0j6/4E0YhFPjYe/TmmjaelpRQA/zaKB/Y9NELp2utceOD6iJormOY2AZRj0S2MJjhPOKpStllzHB991ltiHMGhms4F6XXQ1o+tKAuJgPjag7WiS2YtQ0Ll72IakqFDqm9PyOxT/Z+K0W1QcuQ8xjX9Q7KY5EnluG/FrvCU+MSWu6KUYOUJRO0rY6/nIUGCNXvj6eBGcyH+sRyCIELcC5e8LX7aMMq0Ij2j/yeMHWn3OmR8kl/Zco2Vc6Z3/FVyeLfyNejk/Jj8M851YO1n+81oXvIByeN9sC8fea3RBPJs4ByKzc1VaITpcAc5NXNQYEcDC8H3FesHMQusAe0ld6hRLhcHyQZ3aV2lyFdgn6oT4/so+/r0/WRfsO8WiCttLh/lmT+iG51jAVvm0xRI0nQUYqwfT1hErj6vkEuCvPdndjZ8P60yyIFZpYw3t6oFAHBSe0beZO2GGcJnyT5UR+g6kx4nunPTRlLvIEkYXHs+X9niyuYm2/gVU+yxX6XbCqd4RwU5lW8X8pNLBO0z+X3Uwimc++Nz/9Nuu4SYSTYWxlLuQ3wYV+1X4wC4E29vjsswX6w0my+ucqB/2kN1CAnB58gA+bg1m11S6lRNROX9CFd3VO9D5oS+jr1U/TC8roPB/oXsVG38OIgqUpvDe3s+zyZtqx74IEb76laaBbx/mGl5wlQtqS1IsnSujIxV/LrFWXm8HeilN2iL8V0qOCRX5Tsj3C60WRWvfkGGDHLXwuQjlszLivbdgLNlU8FvxfnpMZablrQDowHQPkwkNUB89jQfIObu6fvLvBetlxxcXxUubsug5P1fHDUdfZbXPMiwk3DPcpaQKUA/AF8HBXjF9U8P5/650JpHEJxZz4H/k3mllXnMmAYzEtLxOwPi3SVM9WvaO/eOvLBz49pD5UTQHKaXdInJ7aaW3Al5EI6s7prVCMHCAiNl1fbG50fJqdpLzBx+bo9QAJCgwSL4G5vsLHy+IqNVZhboyfoMjJ0vMBBQoMKi08VWRvfsHGz9na9AAAAAAAAAAAAAAAAAAAAAAAAAATICw9nhM9P0HDb3sNG1J39+1NyBDgoMUoVJtOWjW/uaLBsc7LUCziD0OIjk+Vvwdc1BtoF78omJF9k0OKZoJ13kvtOGXilt3gZu8Z0TJ9wGOd3U2RxqOSZuHB81S4aFFgL25KhiZvb84wmrwbcPUCmz8J/Gw8z2I/yZyaGDkibu768u9qSTFKWFjx0rw1PcJk/h48uOS7LQv/zFpftb6lzfL0F/qMABW/pd0u7oCI1bP0g9Ya2w1eB3DFHW2sjQulBt3lE78YHqrHwwZ84MFg3bBRkhOwBetE3Ptd5UBhRj2cJjypC4UhSeeMMv4YjpeJWYQhg+oJAcTUTAj7ohSBoyFNVQ==", + "xaktCJvh3kXtpw5jAOw97uUrKDumV87VlutrW58wIVYwggSjAgEAAoIBAQDTKEogtVWDJuh0lHdyCsI7GuCMkVeWeUZhCK0Yq8hOl83Q8cAhdHSc5y0CoeEwUYc49Ftw8MmhLAQKDi+Hkk1Qp+Gy0QTyg6bP2c1tNPlp77uL5lO92r0+pyWHbu78EZwpTnVb1smtWmUZsrAYwmuofsipypoOED9KZZkolSyX0lLm9twZcANcr3N0ObMo/K6AjfDX4Zl9qHBz5X8Zjr8an/BttwmkF43LIbi4GCNq4zZu9G9ahDtkpYpCYfSu8CBYYLeDZyQG2TgHeUycb2UxYYYwarDmK8Q6fmb91oLq5hUtlLRK0VhHqelyHIvaD49wttb2WL+CuuuTwLEoP0arAgMBAAECggEADBgaVCXutZSslcN3KpoBJp99za9Ow/iYQQXdMYo37oB1XQqrsCmFEFjmqWhE3J6ezx1NK3qEd0MXzCJPM0Wm61ViRlAAfN9w1iYpxPUsH+wyOBYYz8lP3jR2oCYzcU6U54IYk1+0V3B+VUAjI+08Jf91ANHw4ZipTK/lsNRdJH41y7So7qWLI18KM9ip8mpm7bu2YFg0+UxprWwxXLp4cw3k8NX6hyHR3EKi1C67UcnZkzKny8ZdukTtBVnMZRxCnLEvRK9OAdwNkkDLQ4x7pRNsb2tIp93WyxjFFkM9PMTo9INTD2L4lCkdAgkg7OtMdWGYn0AxHXtfShCduTmi+QKBgQDtYkKCVUfe0HxNrdBwc0Qvvfn9cggYVj4WVnkmCUQOr70YySNJMp9wC33//iJ/FUHiUWvNksE0ENLgy3bAhbmlk638nJ6AayMIzrMyrt44ieLvnds525GVvXVy2Z6JvrWPV9Ln6jZs8F1NNsy0BMD6V/4D2seZt7SVynTxcFKIlwKBgQDjt4FQ+GNmhoy+9cBGbsTWrvAmUQ3n5ZlMSBRuGOtJt9CiH9Hs4RyR0crW7bsGHtqjIhZf6k4wxb2RgelJ7EnMkOzuGxl6Iab98BIKcipFKwwulAjVSJXFlBf3xs7SAKUp32B7vT3IgSwc5GSfvzHj0jjhmWicpHVhWbooB6BBDQKBgGpLj4CQ82fAb4jRBf70flnqdaCZiSpso8yY2BLCH2l8I+6PUm+abW5clwUkJQpG2IOg9ebNihnoVqU2Nmyq9KBB6qys7QSP9NYiyHcvem5Sv/2P7/SObzhf59GPxL/lV6NiLhyO8eQCFaVXnn4VitwOvr23H52jdweD6q2aIDrtAoGBAMWoZTEZSX6Wz9h5jBoWz/jhBEbeGEnvu27BKiqeqqzkRs5S/G62v4u7JGwHEk2vvmvXjMBYquIe4ftJXmvyE+Ti7yWGlEi0qTTGi4JRsmszgHF1wW0QgiBr+ZnzEVarhLGh2SfPDa/an6W8gbM/zFhKA2GfPXSqM9D6h2FzrSCJAoGAVAm1Ci1YyiPSVevcyKUpRUIBQIj8W2O4PvnItTuOGBG21cFrG/Fm64OfUCAwcsEQzjGfw5tVnRKUJr0uMNa7GCFHKJvQz+1MgkNGgo8gg04HZ7dInR2tLVabmHF3Cyk+NxxOApu+9zD7kciEUvF1IVJJASj2MIit1JI70h/bCGk=", + "MIIE3QIBADANBgtghkgBhvprUAkBAQSCBMfFqS0Im+HeRe2nDmMA7D3u5SsoO6ZXztWW62tbnzAhVjCCBKMCAQACggEBANMoSiC1VYMm6HSUd3IKwjsa4IyRV5Z5RmEIrRiryE6XzdDxwCF0dJznLQKh4TBRhzj0W3DwyaEsBAoOL4eSTVCn4bLRBPKDps/ZzW00+Wnvu4vmU73avT6nJYdu7vwRnClOdVvWya1aZRmysBjCa6h+yKnKmg4QP0plmSiVLJfSUub23BlwA1yvc3Q5syj8roCN8NfhmX2ocHPlfxmOvxqf8G23CaQXjcshuLgYI2rjNm70b1qEO2SlikJh9K7wIFhgt4NnJAbZOAd5TJxvZTFhhjBqsOYrxDp+Zv3WgurmFS2UtErRWEep6XIci9oPj3C21vZYv4K665PAsSg/RqsCAwEAAQKCAQAMGBpUJe61lKyVw3cqmgEmn33Nr07D+JhBBd0xijfugHVdCquwKYUQWOapaETcnp7PHU0reoR3QxfMIk8zRabrVWJGUAB833DWJinE9Swf7DI4FhjPyU/eNHagJjNxTpTnghiTX7RXcH5VQCMj7Twl/3UA0fDhmKlMr+Ww1F0kfjXLtKjupYsjXwoz2Knyambtu7ZgWDT5TGmtbDFcunhzDeTw1fqHIdHcQqLULrtRydmTMqfLxl26RO0FWcxlHEKcsS9Er04B3A2SQMtDjHulE2xva0in3dbLGMUWQz08xOj0g1MPYviUKR0CCSDs60x1YZifQDEde19KEJ25OaL5AoGBAO1iQoJVR97QfE2t0HBzRC+9+f1yCBhWPhZWeSYJRA6vvRjJI0kyn3ALff/+In8VQeJRa82SwTQQ0uDLdsCFuaWTrfycnoBrIwjOszKu3jiJ4u+d2znbkZW9dXLZnom+tY9X0ufqNmzwXU02zLQEwPpX/gPax5m3tJXKdPFwUoiXAoGBAOO3gVD4Y2aGjL71wEZuxNau8CZRDeflmUxIFG4Y60m30KIf0ezhHJHRytbtuwYe2qMiFl/qTjDFvZGB6UnsScyQ7O4bGXohpv3wEgpyKkUrDC6UCNVIlcWUF/fGztIApSnfYHu9PciBLBzkZJ+/MePSOOGZaJykdWFZuigHoEENAoGAakuPgJDzZ8BviNEF/vR+Wep1oJmJKmyjzJjYEsIfaXwj7o9Sb5ptblyXBSQlCkbYg6D15s2KGehWpTY2bKr0oEHqrKztBI/01iLIdy96blK//Y/v9I5vOF/n0Y/Ev+VXo2IuHI7x5AIVpVeefhWK3A6+vbcfnaN3B4PqrZogOu0CgYEAxahlMRlJfpbP2HmMGhbP+OEERt4YSe+7bsEqKp6qrORGzlL8bra/i7skbAcSTa++a9eMwFiq4h7h+0lea/IT5OLvJYaUSLSpNMaLglGyazOAcXXBbRCCIGv5mfMRVquEsaHZJ88Nr9qfpbyBsz/MWEoDYZ89dKoz0PqHYXOtIIkCgYBUCbUKLVjKI9JV69zIpSlFQgFAiPxbY7g++ci1O44YEbbVwWsb8Wbrg59QIDBywRDOMZ/Dm1WdEpQmvS4w1rsYIUcom9DP7UyCQ0aCjyCDTgdnt0idHa0tVpuYcXcLKT43HE4Cm773MPuRyIRS8XUhUkkBKPYwiK3UkjvSH9sIaQ==", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "fkjkGon+fRZrosQR1nE3PfrBhQg2Pa7d9W20v/kaOsMlSADmefcyo+LB02j6lXGqnY/a7scRi/M8nshXYNejbPru+TMbw4hQSoNyIVzxVCqPLOQLqvD6qQCKk/iQmjx625tADS+SJAhetvRXla+wNCPCi41l4I7IHeUUTw3NTkpeGWGEbXAlmcOOBfYW3gS1FFzPWsKkqoJ/fTtOqwdpcSPBDqFEIlNtSGtSObNmP8h3QtahnHRvf7t9r29cQioHCb++BVfVjqYQUhL1nyaOzLBBsUiYxpFpjmXMHnMk8zIH3eXZNrWfYQ7FIW8Vwg4J7L8AfRZ6KgqsY+0LN7UZNxhl66PnuemXvjJpRHup2jO/3VyX2mn3Uz7LbCAcrY6ZqvXlQ1C7+k5CePNkMlmQPCDzCnnPKxe4PQhnTvHNbRup09594DyCwdMfZitcslY3nFRPDeffaj1DHhV2qfbliVLnoV+xbRs3NJIZwxSZ+LwdKuHvnF8qrPGEVDJuPgulzA9Mtfx1PxqJxIK8PKRrjcqXGkuuQOeRdHi05pSAtMaCggtIi/eBm283cdpKP2DRz1f1hF3of38xZErMWFwUfwzmKzxBWg6AWv+OjS2Z3oRnZtKvPzpC2M4giGvoEgnzWYBQxguoz52swyof4KjiJ+yX2/UBJnnqnu5Fec1xwtUEmrVqli7LvgRMdYNQzbn2XsMajagMnEVaFsfAi0qeEMvLmf+hcjg8VyBbv8c7N7Zg3xQmyVLLRVlkq3DQgy0m5QP1FW0NOYYxCy0H689JQgUfuPIIvFW5T9niNjTE7OMPqVNCimnmPyMf02/QXyBw1bLlaWMfWYmoPdiRFuBOaFCb7qWv/DI61ujEdP7VsK6higY8JbJ9ZXjOXQE+2zxaHY0POF+6a3Lkc42MhkklPrmHVWjJqDcBkLOOwiTXWKWGmVV6QDfCbQTWHCss9BZxvU6a7ZUzHWuS31uat02BZLiTmKPJn+1L5O1rKWiMNRKZKoiLvFHbs1titr8YsxWumUbuy/j8dL5Vmk9QXdsGidAHdu0HVWuC6QyuE+w9x/mJo18DixIoGK592BBfaW/H1wahRDCTiuZE0IVh+7tnnYgyqJ2QFrMWvm9JKX2Tar1Wh8/IXLv+asgsLnjkfhbHd+11eXMln6DfcW1CBasz05xiZRK+qBUViUVsQdsZiI7Pf8CnI2zDeJq1OK7BjUFFr//6J+63aTMuyql0SXvYJ0duLO7XuGb8L9/xrxoeaKPCoucuMKOp9xy5d0Z+a5EN1TcdvLryQnhkI/uNCrCaRZsVqMlNvK+0FJ+EW0FzFM9tflnvr18NkU7w4alBWohxPQkSv4Y5BGunHTLtb4ZdyofpNxvgNRJ1FWxjCy5OgctEy6WS3hQtIIVK/vK13wAEs04yskYJ3hJU52EBKwlx0gJTGd4pGlJe7e1rwdurtCrUhLqFAWUfHxHg8qZZDhYr64PrpChWmtO5QFy+QLqRCv/8VtuD82mSxRHmTMcmMpZNArCrtXUgPHdpATysI+AKXloZ76oQnVgX4einDXQx0AtfOkMznXcVz9BjvrgjrtFjFQGRWAul9/wqRlvmgCNf+b7hoxR4oQmHVbFJZdLm8vVWAC0IpYY4Wu7AAgDFJUW+GzYvt/k/mgWE9/g7AXtVJJ3lY/lGTmcC6mT+TlYbSwigHcyp0Tax92UUgTpKOVgEnLbKh8JI59o2vWHMIf5XKTATglGg3cvZWqAkMqa6RH/ZPKltrV3/6mLNb+MmFe745Craz0vPdFm2NghbGCHP3Vxkgb12JZBurdZc5hcw0KVFsICecVyxGshZm1znWnKU2cwOuROumCd4PbS2m+TVHNj7xA+dJC8RgPGkVOclVww9WXSyc20OV+lr5z40BIWg7tpSPA60VSIv2OpHLf6pekRXVpKQ7JQDqE7lcRxsmjHbzXcP9P0b43pZD8OVLKECfpmHfEeWU33g+yHpJLOlGVjukJHLYTq0WrMhEkx0RNhovtMHddxr6DTcgp/9WTVk7HGd6JHHbpmbiDiJt5CWHY4Vftk18bbksAxPjNp0IxcVJU2S0xiXm3B3z5NUUwUbQDDWo0xSRJ8NKqiF/VtnQWtWb82cmluRrgru7nTZv3BY3uiJo8S1/HgOiCfWBlybbeBNm21Q/u5ygWADoEgFvD++VuyoZpfP6GfAfRpJ3QVqrOnGLnLwUR8Bc/bT7Wr37kLTQZuu/cFqT7y7PORmaN6+bB9+i09p8gV4sVIlK9/AhLplVz3XtlAZzROSxRl2iyiI/ny8Bi8I8iUs8TjsR5QOx+xFwKAlSSvNqSnAq256dLkzvbPFKGjRpTF55xGry88TQgheO1jeM2Zz5wnKv+Yb1yP7W3Lt3FwGkHaN/Cptuo9s34jO2zF1x1AYKwvErM2zEWOI/Ify/Mtr4j0i7rbw0CBapUavOCbzFeiWC382e0/YgVwaskb8lP0Xq69ElgkOi20827tjbYXl6FwmJ+6yDUxhSq4dYUxXhKt47Pl+b3Nq32z/2dKzfIx3Y3HvW/H58vn3ZtSmXgqiccFCDVHsr6pwhIqNXUfLa5r9T3M3hEPpt+Ucy5aScKRMmGdgojzhhIYsl3SOvel8432ce06/KQHydzG12M6WYd6He9pavP3GYO3qmtxJjgh/5sUe2bVDdMRTUEjI77dVGoirAsJ4YfCgSDSmfVhtyc2R1fnmcg4TxYXAGDEggzyBUVcSFzmkm1dY+ifRIXZCDIWVY18ndkHnMEhF5x6GXA+ORLusIIVEu0zIdFIUcDJtU8rIZxZfE9V97c13K1vA02UkNctMU0++3UqoSHmjrTCzDN0GI8OhD+wSDqzxkFVJ6PQDCIRjHwSoLB6uyESWOm8wX98RDRNG146h7aadc00dorUET5VC2VyA3JT5VgnfNXHVAu4EhmsdUYVUtjvouzflu8lydSTFCCSM6sQQBMyVy9MppmzMsBQSy1dltEdg195iJaIJbtK7Kd+p4Hto5+fx7n/g/cXVOOreRLOsTxDjRDH41E96WZCZtnJ+BrVy2EHTdmWqW7n8DBz2kk09FkEC2fqJowTIbxAfjfr0VL14YjbVLaVdxjg5qUFyUnUTFfTVq1dQymt+3PagtBedK/O02uTdWrbcH3KZJkTPL7/vyhQVJCk/WV9sbYOEjY6wt8XQ5wETJjc/TGFmkJ2utsTP1gcLDhUbHyIzaYaHiY2Oj5mtu9oZIikui5qsyuLq8v8AAAAAAAAAAAAAAAAAAAAAEiE0QGqXvrSQiOB2h39AtaenjLBQpd7DYLaKif80Pnj5OfS0DPueU5aGDLDoMvCzI5PXQUFRcprBtuMl0I17/iSAob8Ob9qwdpa1vnn/oZNo/GZ4/obTxL8TCQuk0ubhE+VHxQukwdyvsngNGytJP8wPFreVtmeiQWK4pvjTMdV0REyrIGUPrSLtE+ref9dm20a5zoGYwTOOSBLJCrS8VyIup9EJD3di8acgUPX9qYW9ByfBWWHVjztMcSFaNoypU5yn7ncJX9MnjD4Aqy03nR7aDTtiSlk7Dvr/5Wbqh8xcZiSNMpiDHZjVj8U4MpL8UPUgrsv19057NuZkV2QTdqsQx9w="), + new("id-MLDSA44-Ed25519-SHA512", + CompositeMLDsaAlgorithm.MLDsa44WithEd25519, + "PxScsIORcXBeXS8zaAhyAlLdOfDAeBq0xzKI1H9zKRvNOpNnjxv7WsSggPmFIG1kZn5Gh+1VU/bXO+LWg8FeSD6RLPOND9vGbio+VuNTJ4SDLG4+nlv6Go5zp/typV7RyBX6iLSQP3zZ4L+EO33r0AVBIdoVzOJGLzneKmSCCeBL4m2ALe7oxatD9ilv4yA0hHJiCm19PmuNoo+H3lp9PtJr4zyyHwKUBY8aEUMXbTZ+brGaKZZCIfCGPBn/4IDiUVCpxGKuvpuujlv6AnvMjbzq0CPdEPYhMqwyGBK3xvswnEyoyx6IiwVQcZ7peedpvQyuomiWqzRYKeZ3s+2D23wLZxwqMXNo9Y3lmIl9te1PaU7oWwj1IGvnucWipl6LViQfYfdYwuaQwhtjoqqfjFj2gaZVzQ5ag5a4KrTC97TVdanN7dFKhGAheUemcbqygEe2ADaGwUOO1dR8lp8G6ynUglKQTswtaB7LMgzYGuIyfEvyrZZSShFIkl6waZieyOOw+8PFBoUKly3RnBh8a5PDCjEUpeM0EoxFi2UAPvIw/lHc+EkxBMHJWRkmNyB9jwsF0y5+yvgxTX/nYathoPNmU10kBe7xigPCrUhhLo54DvBewEithJ7vnutBV45JiUvuUcANZAs9BK48KjwSBuEp32OR3MeDPwX7ZalbW+J83H61+5HSUQzTqVt8r6ERghqWziqK0PlJOQkq5vpc1y6vcYpGxwOse7u9/0S1lVQ9rxXKR2ced6VRrpNZ0qU3dgxJxWxDG1Ix9dzBfGiMRvL64jzzknnSVyr5af7ouloCtrHzCpSmRpjOII4Qdk6Pj2a/xwAUgejq3On6qgyxbYEZ9BWlKS+T6tnQlkk59E1jozoAVSe0hju7C5maD7YykYMGLrA5D/2wGJVZguNmbAm40uzYiwxi6Sri1FYz3SvslpJuIJBSVhk/JTuoHx8xKdp/X6bEP0IMNKDwSXocZwhdiZrvQ4GqH0WGgSRT53H+cwJTUwdKlRYBSxtNPDf7aI7qG94xY2kXK8Qu4ntsElA8ZI9lcNIj70cfj72ay7MKLd/08NxIxlW6h8pisqBiGsIsVfgA1ARVvr5bueOkgKfmDl1QoiFYg/lLq8PWPuAtZhHI33X9G2XYCtkNizZUa0nZSfYfR9qSCbqhImtwn+Q09vuJMRZgIc5CgWmVqQIFAyB4J2H5cRW9MNaz03rcQO66KgXCBNFVh1LfHBF5dqUTmDMQDr0RNTZz85g9DwdTQpsH7OfymSZlIPOlmCpbu13BK6ng0t+AgI6xlAUFKuD7GALpUBU8uGRXybDsnvqfXx8j8q2FwuePAEpuL1Y/APQNdUZKkM6iOCI1RstvdDvonuktmHQxp4NaYWMMfaMsVY+Q5DqqWQAUXbpLTkcWme7jz6lV58EjbOCu2pA9sHvHXnnHfdiNQCuXUp/g0dGTz5wu4Pzw1VrxwnfuHOZIOWonjtXd1AfXxHTt21x5AJ1Egfxd/YgUWD+L7Yl3lmqcnCxF6I9V0dWHWzkmD/gw2ajvJCkz9qrIVvcTvC4QXr++fNs0sw20wKtTRxATer+RA2I6dEag2vvRYp0w5Y5lUgeLa0tzHQMmYg69pG/j/OWfR/cgHriKzo1y1jrrHzrJYSn6scLsvMq1oH8EMzQOzoOtXOUc+OjhbU8P7RjBJ40E4GA3ghxDNJoFHFA+rXUgVmdeoi8eCOsbDOu9CB57PhF2E7TpEyxChwDPhqznLCDCfirrN6OY6VT6Sjk/WAHDig1iseu0a8BE3Qq5I0qK", + "MIIQLDCCBkCgAwIBAgIULHnt1xl2XSXv0Rve0J0F/Th0dDcwDQYLYIZIAYb6a1AJAQIwQzENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxIjAgBgNVBAMMGWlkLU1MRFNBNDQtRWQyNTUxOS1TSEE1MTIwHhcNMjUwNzIxMjMzMDA0WhcNMzUwNzIyMjMzMDA0WjBDMQ0wCwYDVQQKDARJRVRGMQ4wDAYDVQQLDAVMQU1QUzEiMCAGA1UEAwwZaWQtTUxEU0E0NC1FZDI1NTE5LVNIQTUxMjCCBVQwDQYLYIZIAYb6a1AJAQIDggVBAD8UnLCDkXFwXl0vM2gIcgJS3TnwwHgatMcyiNR/cykbzTqTZ48b+1rEoID5hSBtZGZ+RoftVVP21zvi1oPBXkg+kSzzjQ/bxm4qPlbjUyeEgyxuPp5b+hqOc6f7cqVe0cgV+oi0kD982eC/hDt969AFQSHaFcziRi853ipkggngS+JtgC3u6MWrQ/Ypb+MgNIRyYgptfT5rjaKPh95afT7Sa+M8sh8ClAWPGhFDF202fm6xmimWQiHwhjwZ/+CA4lFQqcRirr6bro5b+gJ7zI286tAj3RD2ITKsMhgSt8b7MJxMqMseiIsFUHGe6Xnnab0MrqJolqs0WCnmd7Ptg9t8C2ccKjFzaPWN5ZiJfbXtT2lO6FsI9SBr57nFoqZei1YkH2H3WMLmkMIbY6Kqn4xY9oGmVc0OWoOWuCq0wve01XWpze3RSoRgIXlHpnG6soBHtgA2hsFDjtXUfJafBusp1IJSkE7MLWgeyzIM2BriMnxL8q2WUkoRSJJesGmYnsjjsPvDxQaFCpct0ZwYfGuTwwoxFKXjNBKMRYtlAD7yMP5R3PhJMQTByVkZJjcgfY8LBdMufsr4MU1/52GrYaDzZlNdJAXu8YoDwq1IYS6OeA7wXsBIrYSe757rQVeOSYlL7lHADWQLPQSuPCo8EgbhKd9jkdzHgz8F+2WpW1vifNx+tfuR0lEM06lbfK+hEYIals4qitD5STkJKub6XNcur3GKRscDrHu7vf9EtZVUPa8VykdnHnelUa6TWdKlN3YMScVsQxtSMfXcwXxojEby+uI885J50lcq+Wn+6LpaArax8wqUpkaYziCOEHZOj49mv8cAFIHo6tzp+qoMsW2BGfQVpSkvk+rZ0JZJOfRNY6M6AFUntIY7uwuZmg+2MpGDBi6wOQ/9sBiVWYLjZmwJuNLs2IsMYukq4tRWM90r7JaSbiCQUlYZPyU7qB8fMSnaf1+mxD9CDDSg8El6HGcIXYma70OBqh9FhoEkU+dx/nMCU1MHSpUWAUsbTTw3+2iO6hveMWNpFyvELuJ7bBJQPGSPZXDSI+9HH4+9msuzCi3f9PDcSMZVuofKYrKgYhrCLFX4ANQEVb6+W7njpICn5g5dUKIhWIP5S6vD1j7gLWYRyN91/Rtl2ArZDYs2VGtJ2Un2H0fakgm6oSJrcJ/kNPb7iTEWYCHOQoFplakCBQMgeCdh+XEVvTDWs9N63EDuuioFwgTRVYdS3xwReXalE5gzEA69ETU2c/OYPQ8HU0KbB+zn8pkmZSDzpZgqW7tdwSup4NLfgICOsZQFBSrg+xgC6VAVPLhkV8mw7J76n18fI/KthcLnjwBKbi9WPwD0DXVGSpDOojgiNUbLb3Q76J7pLZh0MaeDWmFjDH2jLFWPkOQ6qlkAFF26S05HFpnu48+pVefBI2zgrtqQPbB7x155x33YjUArl1Kf4NHRk8+cLuD88NVa8cJ37hzmSDlqJ47V3dQH18R07dtceQCdRIH8Xf2IFFg/i+2Jd5ZqnJwsReiPVdHVh1s5Jg/4MNmo7yQpM/aqyFb3E7wuEF6/vnzbNLMNtMCrU0cQE3q/kQNiOnRGoNr70WKdMOWOZVIHi2tLcx0DJmIOvaRv4/zln0f3IB64is6NctY66x86yWEp+rHC7LzKtaB/BDM0Ds6DrVzlHPjo4W1PD+0YwSeNBOBgN4IcQzSaBRxQPq11IFZnXqIvHgjrGwzrvQgeez4RdhO06RMsQocAz4as5ywgwn4q6zejmOlU+ko5P1gBw4oNYrHrtGvARN0KuSNKiqMSMBAwDgYDVR0PAQH/BAQDAgeAMA0GC2CGSAGG+mtQCQECA4IJ1QApua5odlqXWBspTzWz/OrFCmJf/j5idLHE2OmGlJPlnIs8VGGVe6iT8sjzG0n/l6SmsF2Hz2kNUhz4CBAAG+aepweyE7E1hJzCdEXKFdmI4VbirysjQNd8ZSCR2MSmkiLyaJYja6ZvskoM7YPEuACmNL419TkvwEk0K84Pea6W403qbKBZfjmurbqmQXFZO/yPFukfCj6TzUhQKf8/YKeVrrymxBfy/9BCRVsf7lvQs7B/5stge32MiFtHppIXay1JjXTtRrGueYsukWbT425WQwu9h9kQNPSXGoFyrnHLAsIgdeME+czZquNYGpVaSeAfttb8cWDrRQs4jeDK7HXVZFjmjWzRhtsGL48fJeRIkYjfrFGykr+Ghj4yVoPVkI5g2wysPW0uk/kl2z4RyNy1+Om30uVDzL3FfP2vcK/u2lhQvlWx0n2g0NSRJVEMObnlxe+fH2fzGShmuA3MbkJYClLZHl3tcxoWrQMerzT+h7Uxye7bHExGtfUdocoL94hkIOKKNQwOEpyrPNRQHLVM2vcmkpWYEdeE0+BfB2jOCedtwZ35u5LWZx9cOyddz94+JHmjiCuDBZHuRw28yjNut/spVW/HfxizmVQFGLKKbsKexLqW4/r+CQv8dXnpF6C5dVV+e8L2D3m7lN0lUWlKmq98QtLP67XF8fbwjGU6E9furt32BDFJdE2vY9wII7Gerl1JqSAj+b3L28HwFnxrQFDHRGVIrXZnDIGqOySfxUnPs1CyKEYnFiRH5D4Z003u91qRcZru7cJ9YkdHbBiozqagw2iSweNpLh6nw3KCK/ODUPZHc3InnSnljFKq/BB1PCvWlvMCkS8N1XL5jjjMLh3mrrgbGClFBZeg2wS837Q2FXwlVURmKoJ2sTRO7lt//k5xD+Unc44vMYHckBfDDrUqObbAtJNoIMljT6PQUead8Fbcla1qUCbsdfoN0gRNViQTQIubi0DJrRLEc78I890Kg1C4IxrIBl+at+rx6XNrLnjnFmqIpzrTPiQir6cViTCVDU0p5EALdCJrZrTT0pV5riiDzftNyHfOTkuxkfksy57Ni+GtfYxQ/cXtHHOYvkhQq5VZLUB6wdc5TQgIR0fgzxPep9g8KN2KWT5JYI2NIYwy4WCGY2KLx+pEdWPaj/r50CEkt5aTUVpfucMPrxYQgRomjLoVSJ2a30IS+nkSZhW/oRzhA8wtChVnBRiFVGiyeT/A4FQhr9OIOOVFE7/1HSzBIx62Wtav5QEAZ2yRf4f648Z9IVX6iGTFJZ7DwG1bl2OZFLqNWxmholkzqWrAstdoMOEfhg8ZerNT/LuiFGeWHTlUjPSpV66aE0J+G6TFZE5AdroTvXKrZlcw3O2TcSDj8D/1VV1G0zTq7Qr9bhZ3AnUFQXB3zC7mvXo82ZbMSUr1UQJjliACKBNEFAF3125Bpp4SXihozXk9Xie49WuwaahQPnavhhbukvymFGKooBvjd+iTDnxCOcYMN7oSB9tI0cFJ1J4wVXRqVDkN9mepYptOyFI/l+sSIcsplXvwfWCmGiEjLlpgb2Ng9P0KnThTJXzGQaoADwnSL3MuFtAWi/TInF5AlBo8P/YtrvcsaNzOlV1BCPzj3C3gW48kNibj2nEdSdi0ML+2C/IeakmuW46nXRfUkxo68edk5coZfPtGH2I3BwGXHAWZkNtdtLCeOGJeU7yIKT1j6V1LKd/WZzb/kPQPS13NA4llre7jIwv6cZSTNV9hPxtQPwketduktakrlaiQWApsVpjfuRay9f5DL+JwNHKjaS7p9Gl08122APFlaoAhPTzsxLBOFhsNxUfYd1HbY4YXtAeGBpklOcGBtiJUfv2n4eYzbaw/zKUH23g5ZOWRCXdsAoESYJ4JrLPIymAMpu4vykpjrHNbTbVuLyWyPzGVALF7JY0fsehZFPRXp476Dq9+kXKhIE9+xTRCHxykTqQ/drIh1r4VrVDaWYRezieFwYPUNajHX9vg1gceYRK/yIqgC0b01trLVoo5KA7N3w9EXLJgpBL+alq6k1tSKtIrZGGZC1+YtJmoYf3MarTukofYNCn2uDdQ8eQdLxuM4Q2TkDylQYYFDaBIiZcbCK9dgygpX26XIPl9Rq2+NurfsYo4uirJjgyd5YrL+YS3SKZBx9puBLTQXFi3iAKWBCoz7W47nCsh5RzPuOAx6h42ZFHewlyon5H8WeRE+h0s3NJwROH/rniuapx96DF6wCGrwEh6Mdr0llO0BRFt9ZcbdzGDGc9pPHDWS1WEAIEZC72R0R08T4QioRAYbEGI0hWLSdPsSdf1E47bvQriaoR2BZ99eyt4jaA3IN4BTPQl2BU+V+FitPXz26a1JBxlx0+fCght1qZcsczdyxHFAk97uo0MpVd+tjCvMtRd640KnQye2G0O0EsMD2s5ZAvzeP+1t+Se4hD5u2VkFS3Ug85nAvz/5ofI9nOQRZHstK2WiCayyawi0kqJ1rMJk+/xDe+Dsg/REYN/j2bI2ZCrrDts+N7pg3EI0zNN3MW0tjgVO3UVkfghesCKpEAbCsUsnqNX9xtFoX4yyMJBKiz9NH3miunucXUHR89LW2eXTML4KatWsXSHhNilstq7htUhuruJ93lrEGXS7tRcJ8UWoOegzd0GBbDII47UI7Xz2F/fmtip7+28vfy2JZcC+3ERS0o7LSZz3zPMmZW40Pvf+ReHtMaTr/eeDz2ROOoUVA2o78KuLlW4T+Et0mVgUqCX/YYI8p6qCvRcy5R8kA8lvlCvdMXcG15N9fGGX1YCKg904dBG5J6nxjF/oyV7pNo/CRmFlefxEHAugATIhLqct9RutYLNT3/6ygLZrpdNXtGXCLuJkzSNmBXKWjxuiPEt2mkRLv+rkn3AB8TKsdUTgeOSituMItuTJymUVh7T79aNUHq8k+v8Qi8T9ShsaLNfJ2lUUq8CFy24OuVMhv6u+5iMN2dzY9c+C3Np0z/QkEILr1r7gKwxLulZqvfDuvFLybr0iub/TKmZEWmeGvyKR6uFXoM8c66MhYUHsTiP8QTq0Eca88wsV9iHntyrypq20BZdqnnn8ERNp7EGStpNq4XivAplqwwdDdkzp9Jav8ciYSYgWL4qH6/WUwy2umOcoWUoo5Bf3YMos6nFiuPugbAl6CrLFBciND9QYX+Zqq21wM7XExg3RWJla4+etsbm6Pb3GCowR2iKrLXG2PpRVFtvdXl6pq64vuYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPHik1XHVl4Vw/xyNwXXyE3empIDDg/QzOxx9l2PtA8l8ke7Sd9a2ozzMJ2TVb5OegEd9z1Qm5uTEGjLiQ4s6yjh1xBQ==", + "kfbdRDwNxMFZLePm/b7kREY1cfbMJmNDXt6hTNdHCoXRHlbUa+UIHnD3V33mKDC0JvWEUQTGHmU+duhycSN0Ew==", + "MFQCAQAwDQYLYIZIAYb6a1AJAQIEQJH23UQ8DcTBWS3j5v2+5ERGNXH2zCZjQ17eoUzXRwqF0R5W1GvlCB5w91d95igwtCb1hFEExh5lPnbocnEjdBM=", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "mrvM3v4o/n/apoaTmCucjdvifdARuzcAY5E2hCr2KnbFyns8tVFskTQOfxEmbNcLE2brcxhdzQFtdTK3/qEoRMo6Cczs/V7owjM01IrPjRyz24kTG2Lbp4CpXrOXmnVvNPCAfupFc4BGC5veBvptNRrK37Lwxo65m1w3202x8KJ5Fdbzpdrdw2wZz7XLe2W9FloqHHPeMCCsZGeDITZgvQ4biFQPtNLR124lffRpa7F3v373UibFUIkYiltVdjQ/ybsnZHfeE4gLHrK8tQlNdXiqsNEoN86U2i+qkMt7zQ3isqMx59SYJtz/j3luEDoF8E6ehvV0AttWJHkgC/2tESizikel7Z2K9gWkRsOrwhqbjUdnBZoR4upRdNlamW+UtxwgL38ds77SCxfGQvqEoM1+q0YNmE6F32LG4qNrYDhV9WFouT/ByDnvFR92qb1p9Q5XbQBdNIVPPtHclR8LTPG2Knqb/Bb0RsBqxbPup60ivWfEflSn+3EE0itGEJtdJKOT9/CwLF5VFnmuQ8MPfQSaeSNqpgnyxugDqaIzDnEse5MaGXO5NikAp0+GrzO+yEbwy2BAP33aJi3fNK9sw7eV+AbLYtfJmJt8cPlMvxIh+iVa/OTNW4nimYpg4ABFUBpKC5Wv7VcMCYUR56b5Yl5SR3klvHtw3ctLS23OMhvBUPlrJ8wrIT0Vxe6EPBFnW6Y4Koy85eT5Jl3+FueRC/K00191dZXkkm9EXE9S/tZT52kMf4YCffgxooGSqTS5QPPuRJpzkWN0YQTFOOHGiGq8vgSrvplXmEPOKc7swagadIYAy1AcoQcUgztzfT2grVTB9+N2EnrZJUjK82ONHMjilIvrG7VJxcxz5riVv1UAflaypUXJiR4ejS4IYv6REmiuJ2hPv5fScRL412rFQvGrjQqqPjTGrPD8WE4ADT+Uc8UDnqwrSaP8szER/nhdEQTqeoTy1DJjfKZOyfHFAZHWNPZr50se+RfjNlZ0xrZB9xO++QKS4Q8qKjzTjPnirWy48TZNJFePkgSH1BVua7KPhdbcctWd46WOdz/ZwhYerah5mJxUTzu9jdv7vGmIhVpvrTLoehVH0O0oxKmA3xHmpcrRB4LDH7yVoRk6CATIiitqlg6A2oR8FLFpQ2XPV1bswIrcVdoKIB7wtDoclE2p/2Am651Ne7UNvslYk6lziJJq/IC30WLli3q70/+XP0M/oIy4oWvAuR1yxescFXZUJna1EiSqPGQ+iM+60xnycnvbaIJHIEPyvrPVoUFiRv8K/RaoMg4GTnp1khvHuMCyCKpyMkmUD9wDg3vBwEZ0t2mHrzN6gk68nJEoa9rfcoqX+W3c4JbIe7a+Ybyn7jHb9h+fAoq1TnSHewYTRqgjS8m6yu41FHtUvUrR8MfPtf1ur/+wvWM9b7aWr4mOlDA7qZkd2PajB05hXHNMIlADJ35y0uvol7vbihx6zWe6PDvEafBsgWvcbVq4BtbOxKjrpWBnraJq0uuMGgCR2wEbsX/AXKfuhfcyV+b4wc+TE76xSumSJG8ezFuwJxBmZ1c0jPj8XvQomQ1uMrULUC2F1IsO2vDpx0YSYIZxWV2qVMk1HsCtp/0gtsBGmYrV/a55lAjUMmCX0KAGYy2Se6gx6pJvFBcylEJcD7zeqgNibg0AwhHFIDOWKSlzAXh5jpssrYNS3iGdnqlKIxfd1qg2vkp63sr1HK0c/asa44xaVJHYngSNZi4vhzsnFBWhW/C28gvjn/055f543ZltXCuW5zB970Ic5KfsonQNnoAAX6FfuZNVTnMWC8b9drYyNXdlE2p4WTx4EoMwcsBs2tqNi/Kx5g4P+REUM/5QkB6Tqt2f72qqo7dJ590G6bYlb7VPAKrWuX6dQs0GN/wRO7lMQUiXyOGveglxJvpiLDW5F6YSH26TSbrXe4/spYQpX//qouTvs2IVEUvLGtBrtvr6xhla3KCJZ0ARuMwJsraz54PRUoPGQDLZajp7B1ErCTDpGujotHJJzqUhrUavkpR9FGAr4iBOP9BATQUtRI2vZmpHeAQGXoXxI8f0nwzC7xFXQVNhRkmg1Ws8r154OP4DW/GMDvCvKLbXPKqn+jGI3yaSRfmSltd0zPin/L/8SQLHFW154Orz/iywsRp5w9VX76hLwISybJ3zOtHCluqZ3QvTMMcMsCOQEx4w9jMPjIY9x6v087p9/SkMRC6A3aI/TvpJR/FcRmae5oBs6cPE7n7DfNsKxD1xG6v58OK0ajr4zhfsrU8U3o3EUIpHqheVkol3Pk4ZjrxDjR9bAhNWKcat+VpI/CtX7Vi/hMv4Jjsbuids1mQvFj03AHLaelu4C4tFGJNUqDlUVTaDlIbcrbM0Rrm4zB4GPyHmMAiB3p5timNe55xpLJxutSDUiGwBbTOrnWA70OuHM/MRApUjCenf/s6pLAYgpUZ+r7hO9utyZfGZz5KReCc78wPOuBFiCoHWWdeoZ4jF+mANuQWL11n0t0hzQmCnV2qavLZPLOIxl2V/pMNvRgYPRVFRY2Gl+6iUX3dTr2aS43BNuk3JYh0oeI5XAJu0Tm8/OhGs7PLS3w6LDC+jrzgmA3UyRe0C1xdRDw1jYXhZT/Rdp0B6r0iGra86ieWgVuoIJCqXx0D2Pq10jBA6Qi2hhZVfj9/XqtuoEkCmbg/8knI/voe89VpzF7dC8DrQTdWyMywmDn4kMpo2uZrKVsK1xU12GrB/eCBZCLKH8V15QZf1WBgRY3gV35321WgL7MrT6ee5Khh7BzUS0YA3Gw89bn2/lfoOYuS2MXX05762EO8wPxJrdsgO8gf9nru9xlMbru9K01s9knZvg74tMFzayoVDGc7kBGGi3iZqS3zk1t0qb1Ld1vCydkl/PdM3FqjsAxun/bXlnrMv5PxgmoE0sqS5iugT7RkVpZs4MyFVhndutozR1xaW280/+ljFnPehAs4wAoOjF/BOQmVdavl8a1XuUDHr0Ib5LjYOV29+vlNFojCRN+kEziC80iVonBjr4BV1DtmtcRwaiUifa00qgXcW1xuOaT7/7xB9qi9R+jS1lxRU+NoxlMmGeE4WlPY0qnXK6aJZxTRCAu4gI3Qh42Ww0bxgYJTHMWQsbmInowl3cOVKUeFIYbSNtLYfqD8gk5YRnAA0X250dYiJsbTBz9/w9TAxPkxYXmR/iqCms8TR1NbZ4ePo/P8cK0pXXmBkhIeRnay6ztXW3BghOj9UXWF+pqfMz9Lb+gAAAAAAAAAAAAAADyU2Raiko2tODdKWJvWWSoigrELCLttGPJZWcu3kKbNhkoXGeYV6CqMA/3K6lBSiEADa7kn5xrH7bYHQLnkHRlSvpQ8="), + new("id-MLDSA44-ECDSA-P256-SHA256", + CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256, + "mMoQSWST/dagjP/+D6zm9UBXGf4qu+WvOz3PObdU6NkUafZHEQXWhM8+QWqet5VoNL1yc0WLCjwokYdi5j20ckwK1KbV7Z7p4d1I070z+CrNb5ysGxVsc2jd4SLH8OyOAay7b+z46wh6SKzbB9+sovfb3t1x94laAiioiyEaG5eYg8AQSOBMFi8WSn4Br/KgQU8giZWn3Dx2dASo5WWKWjUvYgVQX0sSQO9R3eckdmJQtTY/ZRA/z3PHFpItPekn4yimznyr4jiW+4KlgL/txtfhqFJD77urQpCGBfQaTxqozSxg5ZKWXtdsr26VKteonA96sDKeJQZ/HwX197LcS3M8bg//5KYnttD8g/jlD4evH34Co0FAlcBX4clmwltekRuBMsaJyQXNeNk7qnS2vfZaglXPHggUZ8O4/TmvQj1ZhD4iKUp+jAuArxlH2fRN9e1wZlHid4AN5KYNY6LrQ1ODTpetLyY3zt69wKr8RKs7Buu772XzenOmUfDqOYm+fKMmg/7eA04vRQ7EZBkwgQSpjgdCmIEGG/03s7Yfg7MAaddTorXgm7qldXf3RvgbTHOV/8o3rCHf+88j1fAORYvDoqks/G5xNxiaMFQs8uZVHlDq+LcKZFGDBYvbyJjjSt0YVRaHYsPWQEP28fCDzQv7HQ49aCQsuoJdGUlW+t9kxUNlrE/TkkJ9yrlN2ox/26DJoAfRRUhdgeaOvvCTtaWxcX9izpYusgWzV8TAP8JegAKMwgqDz6EgyIvu1a5I3weJs11Z7g7hnTyASBXXUGC8PHsh5G8ai6lOPOmBU5zg8rifoHgmUa2nuay0A8PH7GM81wy+QVSHQfDXLMRxxh9gbXb5KmPwkjama78siM5rWanHYCwNGaAgcaEpGzam77KnxtUCcE0IEgl6ncjDS0UnlELpxV2PtJOiuqTQoffVb7ImBKU+SoAS2Q3IETHfMIVUZFAKabn8nbgX9s4rFcsyeBB/72nAZhDYm+U7sw7KBhEy6XNr3uNGXvEwPaz3wk9UzB68UfZcwL28Et5Ey2nXMUXB/9fZePX7XZhV6H27SBn67kPEwU+6tG95i3jH4+qBwGuVTDAg3CO5TUVGxOBiMFPI6V86gah/336eKQZ/Sn03kij5RuM59fH1cml5ujGv4gbl6/ALLbjr+mN3UgDrc9eXHcwGYQ5H9TaFb6jhtFCSxhWkYy+v5yB6NQEBbaDb9/rTxxzmRC1UjwG49APHYnjDeDjUQZEIXeAUXhp0za72BF4KEIerXsWSMg7e72mDU9BZwa5uFKR6nZrd6l3N1IBvKuqCZB58Tnh0o9lde8y+L+SnM/vxcyX4dP/QcURAc7h+IR6SgW0Y5LerOlfAJD/0N0zW0Fdz7VWWbDaPBANfPaUrMb4R0+ZSurH8Cajt7W0SDFCJ/enfNUOnWcDJqf61AsUnvrZYrmxD+e0vWI6sc0eOD3cEtC3b3oJS9Az5jB5abu9q61a610UJJxjYaE5s6/iipsCMsu8xjsvO3UYxeWuo3PFu6SLU3EoSw03f1dzjHMvnSnEe+TEzqCiomdpTCyCEjNIxCYN9TvM7iRGEFT5X//YjSPMgg1Rlw1Z1t5yV4UHh5tWO3l1I2GOSM72DpOb0deP2oyKQ1HdEJdeK48tXmYTG/2mM9Gmg16yDPnZZzk/Ut+aAbTvxicZUzu4vs48Y+nz7OIre7jnJdLqc6ZI51s/ZQh8kiZTzdf9Jepu8D6WQBlrVX2JiXwTYzav+Gr3WLyIPHtabNplMtaCADpYahGY+wDnO/cdGmPoXci8JhG/21dY2e0kbWu2uVFVTHbeN5y3H+8d27AbP", + "MIIQWjCCBmegAwIBAgIUf5ryn8WjqsU93zonsX1in1SEbV4wDQYLYIZIAYb6a1AJAQMwRjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJTAjBgNVBAMMHGlkLU1MRFNBNDQtRUNEU0EtUDI1Ni1TSEEyNTYwHhcNMjUwNzIxMjMzMDA0WhcNMzUwNzIyMjMzMDA0WjBGMQ0wCwYDVQQKDARJRVRGMQ4wDAYDVQQLDAVMQU1QUzElMCMGA1UEAwwcaWQtTUxEU0E0NC1FQ0RTQS1QMjU2LVNIQTI1NjCCBXUwDQYLYIZIAYb6a1AJAQMDggViAJjKEElkk/3WoIz//g+s5vVAVxn+Krvlrzs9zzm3VOjZFGn2RxEF1oTPPkFqnreVaDS9cnNFiwo8KJGHYuY9tHJMCtSm1e2e6eHdSNO9M/gqzW+crBsVbHNo3eEix/DsjgGsu2/s+OsIekis2wffrKL3297dcfeJWgIoqIshGhuXmIPAEEjgTBYvFkp+Aa/yoEFPIImVp9w8dnQEqOVlilo1L2IFUF9LEkDvUd3nJHZiULU2P2UQP89zxxaSLT3pJ+Mops58q+I4lvuCpYC/7cbX4ahSQ++7q0KQhgX0Gk8aqM0sYOWSll7XbK9ulSrXqJwPerAyniUGfx8F9fey3EtzPG4P/+SmJ7bQ/IP45Q+Hrx9+AqNBQJXAV+HJZsJbXpEbgTLGickFzXjZO6p0tr32WoJVzx4IFGfDuP05r0I9WYQ+IilKfowLgK8ZR9n0TfXtcGZR4neADeSmDWOi60NTg06XrS8mN87evcCq/ESrOwbru+9l83pzplHw6jmJvnyjJoP+3gNOL0UOxGQZMIEEqY4HQpiBBhv9N7O2H4OzAGnXU6K14Ju6pXV390b4G0xzlf/KN6wh3/vPI9XwDkWLw6KpLPxucTcYmjBULPLmVR5Q6vi3CmRRgwWL28iY40rdGFUWh2LD1kBD9vHwg80L+x0OPWgkLLqCXRlJVvrfZMVDZaxP05JCfcq5TdqMf9ugyaAH0UVIXYHmjr7wk7WlsXF/Ys6WLrIFs1fEwD/CXoACjMIKg8+hIMiL7tWuSN8HibNdWe4O4Z08gEgV11BgvDx7IeRvGoupTjzpgVOc4PK4n6B4JlGtp7mstAPDx+xjPNcMvkFUh0Hw1yzEccYfYG12+Spj8JI2pmu/LIjOa1mpx2AsDRmgIHGhKRs2pu+yp8bVAnBNCBIJep3Iw0tFJ5RC6cVdj7STorqk0KH31W+yJgSlPkqAEtkNyBEx3zCFVGRQCmm5/J24F/bOKxXLMngQf+9pwGYQ2JvlO7MOygYRMulza97jRl7xMD2s98JPVMwevFH2XMC9vBLeRMtp1zFFwf/X2Xj1+12YVeh9u0gZ+u5DxMFPurRveYt4x+PqgcBrlUwwINwjuU1FRsTgYjBTyOlfOoGof99+nikGf0p9N5Io+UbjOfXx9XJpeboxr+IG5evwCy246/pjd1IA63PXlx3MBmEOR/U2hW+o4bRQksYVpGMvr+cgejUBAW2g2/f608cc5kQtVI8BuPQDx2J4w3g41EGRCF3gFF4adM2u9gReChCHq17FkjIO3u9pg1PQWcGubhSkep2a3epdzdSAbyrqgmQefE54dKPZXXvMvi/kpzP78XMl+HT/0HFEQHO4fiEekoFtGOS3qzpXwCQ/9DdM1tBXc+1Vlmw2jwQDXz2lKzG+EdPmUrqx/Amo7e1tEgxQif3p3zVDp1nAyan+tQLFJ762WK5sQ/ntL1iOrHNHjg93BLQt296CUvQM+YweWm7vautWutdFCScY2GhObOv4oqbAjLLvMY7Lzt1GMXlrqNzxbuki1NxKEsNN39Xc4xzL50pxHvkxM6goqJnaUwsghIzSMQmDfU7zO4kRhBU+V//2I0jzIINUZcNWdbecleFB4ebVjt5dSNhjkjO9g6Tm9HXj9qMikNR3RCXXiuPLV5mExv9pjPRpoNesgz52Wc5P1LfmgG078YnGVM7uL7OPGPp8+ziK3u45yXS6nOmSOdbP2UIfJImU83X/SXqbvA+lkAZa1V9iYl8E2M2r/hq91i8iDx7WmzaZTLWggA6WGoRmPsA5zv3HRpj6F3IvCYRv9tXWNntJG1rtrlRVUx23jectx/vHduwGz6MSMBAwDgYDVR0PAQH/BAQDAgeAMA0GC2CGSAGG+mtQCQEDA4IJ3AC7MOBzO8FaKUL8QBWjfIh3VKVQOh1m/LQH+xEmBWImpkeFYBAC/+2hwBac/aQOxrSmo2H34s4Q4pX2qGTsXCZrJMFO97CnQrvOOAORBTnlc3WCTEL19j0GJFzEAbofTW/NIHpV4WHrhkXR3ekJ/zSn0sMw7Yi4KDt7Agx28u1vnWTzYV9CFNnXaS0KdaG7kk7eSBY1GnZfyXpYam68K22jQlwp43/zFtl7BfzYa2HjwTsqTRNI6b8EF7SydfAxx4Sv2xTRdIgdceOCK56gL7uEAb5eFXjR0vk6OPcBfV2vZvfI11AEvTlud380agMmtU5hOSu18FF/nEYoVBjuAQMC3zLXY+r/ciDFjwGGirpwtteu+Q4Q5JgsTZRMZHJXyssZejsMl5T8gsOEPcq/JKmjiYCKvjUESBBHgBnYX4QBh1CLcc2Iusa4VB5Is8/H9PU3F9E32drY9a9t73D/p2DOcG68P3ta1M+YG3urrJZg8MQhyHY5lo98T4zdvePSC1QL3CQsomGgtc1anDBIN6inj0pKoLZr1UfzKXdFRbF8hw6q/G/R2PDjA7dLgmiuqpB/qvQKZvnUPxver1htJYTCax2Qn68PGDx8N8sGJg3d10X43le29iFwi0/EkSKSVLS0tGEjLY67AUZZCNcuaLSdYW6DKfNJ9zBXCxSswhkf1o/p0JFNAEyXY6vINlGSqplf9CqDD150dcIuYXGsZUuqNPMU2NV9sQBrV0RVl8dCnB1fkxoXluC9SRtesT3ELRw+mB+++4E+dtVVcJO/Z5oZj7iBpN5GR9zwQLdYjpwdNSWzGhdsyHn2ZGDES8peGS1PQzWgRpgw84wr0gzpDICquw6AkuE12drgigeOqgkKtiEhE+MYCCRZfMiCUjVNH/4c2Ld2N5z8zCEUFoituOesY/yLEDDOAdFVnq3GhynvLS4lfMKYijPGob7s8H/P1Ob5FW/XSE22tocRsui7GeKBSB3YJuwoy45IZRnEODK8hx2bVRJd05VFm4C4Qxqw15FBW/XGzqRwphbtZ6A59Wv3wbrKnonnRx0gvVZxqkpsSLeXs+GheDgpgUqC/MZRufn7BsHM/EL0cum5+tcQZOZInXn7We/QUcQYoQwfwDdoojuCetqwwFzKknkNATyNSusZKd1W8BJrRph7+VRXyMdOl82qRY7WC9WT9mI5JZhbdS9oSA9fNkSkWRMMGYMSh+HRSGfYeJHz+2AEFDUAr9viqgW5bplsalmCspNUoQM+CNP5/ztzF6LvzZRomo0ehw4tC6S5NGIayjAI9hk0F/hpYPX1reEMif5KGTT9yf1EkabNJrWeKac0QJAQKCPMEzxYs5Y9ZAryld57vvqMkAsWnszTyDHuKBphSK55sA600md1UTT65qVLyzk5VrscErICOKwtdgSNZiNDSRt4EHAWJ944nuw+Fl0mJrGGfMjH81lC7aAo5aJG1tHGO2nL9Tdr+wi0i4Ae7bs7pa2KCT3abXtPZxzG0bD+OoOP07UZE0BwYR29cRhKGK7BdEpgvGvwISrBp+bktX9f4PsuDwD57Lri1d6Fu5tpo6vSmY2Jh10hHfuM4s2yJtRsVf/21mV2PAYZNISD8/nDH0c6vNsTxpjcgbj4BiJL+DIn/RxEME29/hRk3le1xTjv7g49tbbAwjdFYY4p8CEaGqD+EISEOOS7/sqbknqSepW6TH6q/fjjhW9ww2xUZR7rO1Fa9IM2dO6qaNxHvL8i1qhJJaesCdIyDBPNkL+6k23jtOV7BCGi8L6CWF1TVAK4B8dsIMKrE815ElnvMaowMzLr/sZxXiaul/yocHP1xKyTS/4e+tnr6PzgeSWAS/nvkkgc6/5XEmj/u/lct91DaL8vDUy48w0N+GnMRLt4j7uNhNBHMFkNnxP+lTmQiCI64NeYYt3V67i6/O1P9B745VJpoUnQKzwYsKmP2uu1Ry+QjKir7wZelZPTOav9kgrVf+v+bBeZJthn83oZO00Lb1ake2SRn/SKQHr94knIFdoWYlZR2BfEqPWgdlZWv3GtCtfafSAJEqOV0utMS9k6vqc23wgLwQrbEG9mym2QndC/9XEtsG4GTpHBIKkNOt9Z6MGaeboq3NHMKoaUVDbOuH3uzaSv22kGgYVMAIHCjp2nxVv0KStVN9HojSFFSnU+KT+r4gRX7bOQzJsXBgYvOwFuONGmEB0CRH2yNKvkH3wU9ZFsOneex6rMn/bzJ9fQzatU8+FuXt8fygOUfHoPtoQmA7pG5xXbxojk3z75q7oKPDWLYH4p09iqeHTC1fTN3A7K2YOCNrOpwbas/17NTtE+hf4agryqOAh9aM89tLzfTP6riA5oMSk4JabhWjrPOV6qSGB6RBaY1R16f7iku/m3gOGuh86xEvCHcr4Ck21HGXdAMvgR61uRjzifEl0zM0OOFhtI2IC99RiTI2uTUjCs9dtwn3aYtCFq93aWohfOyp+EmC5hRewSeeZrzLyf+AOdXSVtujI+w4DFHKm2QhnPb36qARUu2I2siqytruYGEf7n9VtWqXVltVI3Avy93+IuhUEmbzVAJfzcw2z9Psa9YphjFf6PBD0wBMRtNlrveFbZQaCsK9Bj1CR72NTSGQT3yvPJ3VqIGuZjeIE0JLXg79+O4n4dlqmrFcC1EhfN1DD08N6MKzJrxiInP5sbQ3qKWgeiI7sd9XMAdIR0O2LztoyGnQKUzWQlDVOdgRdTaszHIqLZQNIC9Zs3XjA9OAucMlUYdFdVc3tc90ImfbYUWv7AYf3fA2KoEmR3y5lLdmOqmcNntRc1hcACR1aKXv58Z1ziOd7u1/jBOjxOuf4fox9LCS7ZL1wSOXO/IesuwdoMwKTCnx48VimmBsf56i8B0LjK3P5axT4fwUMHhUlrPScjUZM6JX6rBN+/6tEu37uOYRUe0M2W83d2o4GqAvpMAkG6rxR7pn1NNyFxFMVb/+qyolKtC/yiWiFM482pj4D7GlCV/eUwJ+2UvMvqhbeIi+k5ktFppTAW2E+FRZbE6O4ag0tGoGjklHRsIefyWUBHtXo04cXK6Dzp8OfUig8/Ce35ixHw9aZeu0iBYegjSgqFhtQSy9VK1VUtlPb2FwxmEitF4juEVpw1VUhFu24jxQbZ9FLbmjx9ELGYwAFdqCp+DTo+WV5hY2R4fI+vsb/P0dPe5vwLVlhjeZeYvMjb3unqBhstTq+0u87Q1tzgCSI0O0hjbIqTr7zI2u8AAAAAAAAAAAAAAAAAAAAAAAAAAAAUIS07MEUCIQCBdxrvjlcGpVusMl+umrPwyK7rGM40ipk77XyZPjADzAIgYptZwZ5o9/XX61vCXTmCP1eVgV7/R8F29RY7K7efTrI=", + "pRrvDGIXJtUVRccPFSJNBwRmpXYM65Y01ff4BCe8N/8wdwIBAQQg5exWsXy/CAjaJpeD3MWzmBNObP3uMzwvw3olLiPyc+CgCgYIKoZIzj0DAQehRANCAATYzav+Gr3WLyIPHtabNplMtaCADpYahGY+wDnO/cdGmPoXci8JhG/21dY2e0kbWu2uVFVTHbeN5y3H+8d27AbP", + "MIGuAgEAMA0GC2CGSAGG+mtQCQEDBIGZpRrvDGIXJtUVRccPFSJNBwRmpXYM65Y01ff4BCe8N/8wdwIBAQQg5exWsXy/CAjaJpeD3MWzmBNObP3uMzwvw3olLiPyc+CgCgYIKoZIzj0DAQehRANCAATYzav+Gr3WLyIPHtabNplMtaCADpYahGY+wDnO/cdGmPoXci8JhG/21dY2e0kbWu2uVFVTHbeN5y3H+8d27AbP", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "+XAHBu5SqiYXOOxq4tSzYb7aa8tK1fP4aGhRpegp1Sh1BH3rJH+EY13auFSpQnuBDJvTB4VYUtaeXAMCoxP0/eCdh4O9KhTUReGZs/6iRatrAsmgmxm9qcMSmoRdN5zTGSZ5siK5qU9qMpZnlUSs5uRcwEHtRIVdO8TCejwwJd6GCRPYE2uxE5wXtDF6JtJPvRyVj1yH5lWGiJjuDXZJijNtgfVQUCboi20kCulTfNHJRfg5uz74pEA0op3FswqlQKP7CJR4kVsT27nyRtEBQ1+v/3VfdEWoJ1a88hig2HBWm0Bvbh5jrm3YmXIzP+USNA2G2XBkwJlcnsVicEdc1fTeE5JsQZ1JS0vf5cXtq1CX4/flm/6FeepTEGMOxBTfDNzDLieYI215e/FJ95bdkGVEAehJcyhC4Jp/5iXjCp2yz/wbQDncwBlZN+gH914JyBonfnDHdrC6mJnncgQkN9o0K8AfvvJbJTXgMVTyyin25kzzVrbJA84z+DH01jAQtHK6wnZ7EgLHzMaz4GU6v5IVa9vQs9is3mq6jz5PNRy8YKkOGayOEEYe5Cnnm/Ho+r9IlF8bGnJZyuh5/1U5Ug+TLDk04gSeXJks/Tdnd+cGrZItDvjUxQNgGhywX58MucLSaTZWuP0M/Hxk8YlOCMaPP15mclyiPF2cs8ucZdFCHGB10GFLnqk5numm1ilEKSJ1FuWzDrQvge+iDCGPVIGVbCzq+jkqHdmb9VGLlsQ72mokEQkVAkWYxkuXLHtcsx+duBiC4Nxj0/4lQ7R0VkylRsmSEn2VKilfeH80cnZYvPCnVM3J7n1LBa0Kk2rutnnvyTSX63VasVVRThIgnkLhg1U303JIZvWana1IG6uPW/plwzNRXIZ9ZnjYmyTT9SKXdwHCyNdN96nS4847hqKb/aaZY/JqDTby+/VPEeHt3XXj3dYsoVh6fBo3JT/uoIK46TMfL6LZ3Jk3pVQWF+ljDfxwfAY0zehaOAsHbLV1FKGBndy2MwCq4UFjE+YJA/jERin2SSKyfs5Ue8Ps0rVuoBWAUu/sjLSlKVoB6tAdPTxMuxitbOxmECr1PBA7lyDHPBEnvMtOTCXEFyZAkNypAxkcb1Kc2M1YgFq+QqBKnLAnRzZ19IQP8QytujWDmwK8mHVJwb6WDfc/0FprSKuFz4zrQ5AJYVldztFHCfPj1EpHvjRQf+HmVQZXaxg8w82UdgFTaow3QI9p9OVs0HSVi6qLEJR1uUxEjSRQ1vLv8lSBpSFXP9Oln22QLEDZhUaBKtqtQ0g9FoNEQGBTasv5Z7Ja3c0NfTBD+MEHMqP7udMxbtRXZ610i9mbe4ImG3sJt89LXkg4T3f9PWGN/7KWwGbaj8ON2teO4AcfVHsre0p09HHzMoj/ndYqwWxlrMv2aPQnkoj71hZcNJV/SXHSIF7+cVFHtc46vdIaFTvblU8DsdA+vsgduDI9QVEdab2k6zrhl5Hz/Y0QLDrcDxAabgBZUFzPOqhWbjgOkD0/ZwmoU+dWVPz4lVvJ4lo8yRE1wo9fpPOGPq1zeB1Y3AEazrGtOnkkUVvnShPS6MzI5qlbnkBow0rfu+Iy6CoUxMaZhU52HxDKz3F3IiWpt3XprDYKycS5ojtthiPYg1JI+HlDQhAlwfCRrpuFeft9rYImZvXzVaA6gCFCiJSFHIoZmeYL984F8ziAYiaQdKMR62iEf+3jkzRQq0WcuDWcL89UEOW8T1flrkV1DFvkX8RXMcfJGuVi6fw5PxRvPV/qGd8gJzAajMZ2Vm8RcXW8w4hDyqyiVM1ewsE5IgBln/3qTyF2D4MBVvemdZHmX4epzResw/Tp11NMIXtt4WSkCDKjO4XvCID52YUZMBZk9y/imUN3fBisqHqhHZbxI083vHU+nhNc2oX0t4agKpPm7madpRjzQSrs5nTzFwxu8MAi3Qyh+KoySeNQPMXXl48WHJKKJIdcwMSSLSaQFg1YbbIhBP7/qzLbDxL3JW99byRmXBE8+Lxm2AgRlOJiYW1EecqtTcROp0cICgUa1O8ZQmUQFyLMn/yhD+HENzebkRJZT0CmX5ClVp2P3IuKBzbdwBY1QMPsiasn/GfaP/iFsHwA0pKn5XlZ6FfAIi7flzOhnbMGLZugocvCduWK2tkeMzsZDQdlfhpI16N6KnqsFr/8PYwKiiqi+1dgqLRQxUwOgaqShO7+XbuGzmBYf8pPmoYcqLOzicpIugkV8ipKIIr6NnPGWg+O2C48hGgHcycapHPQ+q5BOPjT4t08zJPrsm40fq0OpSUbuUqbESGz/Ncd8KrWJ8kxa0OmoHOllnzYeXK1vlXTwYmMDe0M+MAj8nevev7fcrfJtIm2vqTCTkZtToZQh8uHCIP4NKV1gB50TcZ2XUkOdEBRUmroSr3fjPElDE/mZndu6Z4Qyd1fD5Ee/uaVDKzwNKgVjFyA7UB+riARiRt3smuniquCwwL6FP35LlwfqJWePrzxZOR89QVT95XVAU5IZ774bPoffjrgRJnZYivTvfC5h7CKmyUpZljLCInOXVmwL3UE4G2p68UrPlID7CYyCVfQyorfsm8wr/tLbOwkbhuqUkzBmVHRVUka0ESbhJ2DUZ/+yzHtfjKd/8rbn6aIPYVs9eB6ctHhaWKRgtyXbzY8r4zR1w2gi6MnjDFho5cl02uUe03zjSpfTfuNYeiXOeGuHqahVk1jHX4W1b6+ghcydbvG6xmDXYhrNkJUr0ArXCzGU9FIiph1WM64o1o2YOHAxlwmyzruA+KB639sGqDxwwOWeSezCgwvmiPYyisbZly6jvPM240lNhLkoJSw5FtA+oBCLB6AuKWj9VxkAMKFAC79CKQmMOfUtHimnHnXgsHl7tB67pPrqsY6e8EKy5eSsjg+epbzKR302hXXBNyak05+H+eyRkIfKQM0lFdiV0cHGcsolT46Ya997/xkM6k9I2RS/mPJzuBy61wyxqG5WeEY9FNthSrzAArdB8b4fEXuiDl95JLVDwi8qAfM9PKOdpgR2hxkuY8Uwe+nE8QM2KC0Lq5xEHNqEXFkR7RmZ+ylCjk0L8qkGRABv/umVJysRKRf3dHuSf77f8DW1kaDEtsYTDbpYleZxdpBZWz8nfWnoRembGY6gKUK5yVv2lqrfjo8/1aMjZK3wMPc5+32/AsvMkRHSE9daWxwcXSVn6myytjm5+ju9gopLS4wYWdpjJa8ytPoS0xRVWRliaeoutDY4/YAAAAAAAAAAAAAAAAAAAAADCQyQDBFAiEA1d9RO7OL1jUunhDjiaEN8tRl4vpbXqf2t9bDkwLaREICIFbRGHqy4vbFHxg/NThFD1TLvH4O70VBFCARikZR/ixB"), + new("id-MLDSA65-RSA3072-PSS-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss, + "baWsr5Lrqg3/ZQzxmvYNfmhYe7lfkxav5db7xGcQ1528ukPD3FpXFoQeG+dNqC2D0/surcdhwDrubGrF4mPJmO0XCEooQYTfh7fZ+Jwdnyym8rLCVidlx18KfrKOcbqH6/DcRkwY5UoDjSnU3AZhY5rTV1Oar52voBD7+gtWrUlYuAHQzaoutySdaa0VKefrHHz6RBl42o+Qh4Bilwogkh7UJbXEtWeUCssCwnvnQtR98yfelMJuvEQEKSAOhgVgR3sMfeb3/wOZ8bJvsLMJbECS5zdlPQkjBA52UhsKR/s4muapFc31Nzfcot19+5SujGMeQDRi8yeAG8eC85MBWFE1DhZbby53rsg4xRPaOxfb64WyV+SHRlfmos7DYHPFChJKbxmd7onfLMMYC6E0Tvm1aTIBfIvsyBHaipv0U6yh8DrdqjBjmaQtrIuWjkQZv4PVdh6h4CJxN4aHdVKbV2UpvUfOvsZKHriKsYP0h/K2qK/g7RqExpIz1BM1tXPAgFzCpUOkl9s3Dxhv2gOgsiiKTLVTXpgNQfuSFVV/zJn7KIwWn/14Hc6jSR48szQN9S4S6MT+JRCsPGqbRpQ8dRHCZVN5Iw9hy4Uuc+gmUYB+oJ091HQW/5pka1hyQtIq8LKvsjn5/3iWeUMB0WpSEq6kCe0QFkRlEogQzPugBZe8RcTGpK7V4ESIzBzKOoRujwA1DpmXqWdm6k/d0TCL1wjoG1I2HiDUSMfeZWotlFid4AUbHQF4GF3vKGDKlsPYOmWCFa5pqCAb/khaMWtloRbPy1qNl97rPmh2jak8Lx5kYfvBx1FZ/jRkHjMfAUmfD7DYWnOh1FYxglYc+35mSUs0108puSgyFkGvkD89c9dnHoYeWEWf9Z2HHMCXq/PAPI6cGMhdXCeRl27wd53tO53u+BGu8ObYEfwhpfnLjiUc5Nog/Sra57E4YBZ/jg85LhZyDEhsPiAG9wVTjP4YExuo1G/CPcN9RCojTXx8xwbxeIisK/Z8mcDy171MIU45DIUcdT/kldurbq6knO03dik2NpvP5maf96NG8hN+hW4Y5j52Wn7ItQRpf5Huc+Z/hF+OqfBzmlL6CMe5otu6Ff3/XProvpi9nsxDIkGlRZp71hT5bCnLzlNnYuF8gK+V00uvPZkDn8PefYm9UaS+4Yjztxp/zLEu1HqYzMHmQrkxrgdn6quDP6YOK3L5+Zpb9/VyxVR2HatuFrOPg+d3Fa2uY/bb7Mabl/3Xx13li2N3DlTx1AzZ6zOIk8gnpWUHtkoy99nBDFnQmkKUx/4wX2f1U60Hhn0x7mZ29JOFllKTBlMctNcF27KgOpIqL79QH1NySdZ6M+MwJdpjkdZVIHJXnqQGiwwngcOx6Ze9dvt/55Uy/q3rzZ1Bxy2SFeQlkGsyCuTjjGaYv3PqccinNqKZaDB+cFmt1npuDdg3MTqouBcwQvhYscaUOT3CfN+xaER/MUWPCKFIS4EVFE7WadgrM3QzEdVYErxD5e1+nnWHeuZB5PLNtgWKpHRr3FdRzGl60XCQe7Vk6xAvSHkfTfyoI774gm1xCLFk9hay3s0IajgkDWzrsGFLK1tncyPqhsTfE8HTaxhBcO0ryUiFgvSG/GGljf8fzpX8qsxYsbbYLxslAn4iIOVQSuZeyBw7DK5I6Hypu/2BFKnJJqvkg9NmBubqKHUQ1P3EWXNYXRe6nDnGIwvgJ3FISEBOZ6lVlz1d82Mg7f+y1yAX/0N4aSNV71ei+Bubu8FJKkg7FukpSzV+Mk7c09/y2f5138xKMOY4VosJtuKCbRqWSz50AcOd+rNICWampKIbnjQhDf1pR6DSuZvCBjjz+3iwCFO7pXW/Rwt/qc/q07JI8IKunM7osNR3y45S9jn7IsaIq5QiZEJh0WeH/QAq0rbbEZiagQptr9dflk9SV2w2v3QXirKnywiHZ+Z48vlJZqj6rHVZk/ATFLuLR5hxsxN5rEJY7hgcNuCDUYLzDB89U/+ilW0JuZznsX45+KhROpsG/yMyycbL5ClhWmjh+wzv2B1BO8PJVCk8dNHjQb2pnPBWfsmlGPUzuVmTocnZ+yCy/Kp5qFPLwabpusMpbv9ONdH4iMNzrkbbL/9AWZ3brDFLyI+/Xc76wR2kN4posBvHZUaxERjeh0/szRNwbpDkfi2UiwNuQgXoixgPZOcozJEC7n+Y8NCr2qrKp7PZ65tNtO8DmAwkz1d/UM/Eu8Bd0hPcTsubWO2BKOdY2Hn4BB0fxYO1giwFYEUXhablSrLnAv2fN1/Ty25xJaRrgH1trRrZ31mQhYlAfHFkwUZxoSFHbERuq2jndBhhwxHr2p/z+V/LcFhvvBr28JJjl+aZLjpWp7CB0cMKT8EfMA6IAP7DBUcUZMtqSibruZdcMDsreiuPZ7VMwogfv4/2E+ajqVaaGmlqvsQ/HlqUgkCmSncgKnNPbGFSGAQ6ATJV/XGfO6fchH9mOfItFtvEtZVTp8Q2bGjG9f7RCvKijJyrd133IX7L08uuBjE72fDbv9fiHmWzud3CBVIvPJUD63NxPYd1jTVQrfjCQnku2vo4t8fqz/gGOcevymNNVRvSF6KDW3gwggGKAoIBgQC1Wdo2WhVDofS438BPbUREdxtSpbZkw2WOEsSFWHvnzc4buF9nR6u2a1DVGXyr17OIples43x1aQgPlf2yXdbRGIMr3fCG02c8NP+r38+bgGOHIa2dX0lMHIgOyXUX0iX1PyTmOSedFn5iQWA46SC2dmDZe3KAfbn9BhgRbB1ZogO7I/8dbcYYPXcRT2dr96tPIiPJfLdqMG4lFZ/Zp48Lcn615CmF/p/uoDMhVjKb6DEBQVQyUef1cMOs+qFAm2ivU1IL7XM5GmxEIEg8OPv2D+BrHQ18FzpdlPEjtqknP1ypH45AFbrL0tO4vVK4OaPQNmIkqC5aO60/xgPgIXsw642kpbfxhwqa+a3ZeRdJLuRGtYvl79qL/OTl7XDcetPuTYMYjXLXhxBSBu5tM0zgarP2RwXDqiMGKEjgMSTl5Ei0EJfXCoUGgI4vZVVqUHkhRgE5z909piVNsnCdOip80LNcT/Qxz0g8dUmKBsH0Y4hmgKJEvTYTuHucv6+N6dkCAwEAAQ==", + "MIIY2zCCCjagAwIBAgIUKWBPLTU3XOqAaLhy9XOZ87nfvMMwDQYLYIZIAYb6a1AJAQQwRzENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJjAkBgNVBAMMHWlkLU1MRFNBNjUtUlNBMzA3Mi1QU1MtU0hBNTEyMB4XDTI1MDcyMTIzMzAwNVoXDTM1MDcyMjIzMzAwNVowRzENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJjAkBgNVBAMMHWlkLU1MRFNBNjUtUlNBMzA3Mi1QU1MtU0hBNTEyMIIJQjANBgtghkgBhvprUAkBBAOCCS8AbaWsr5Lrqg3/ZQzxmvYNfmhYe7lfkxav5db7xGcQ1528ukPD3FpXFoQeG+dNqC2D0/surcdhwDrubGrF4mPJmO0XCEooQYTfh7fZ+Jwdnyym8rLCVidlx18KfrKOcbqH6/DcRkwY5UoDjSnU3AZhY5rTV1Oar52voBD7+gtWrUlYuAHQzaoutySdaa0VKefrHHz6RBl42o+Qh4Bilwogkh7UJbXEtWeUCssCwnvnQtR98yfelMJuvEQEKSAOhgVgR3sMfeb3/wOZ8bJvsLMJbECS5zdlPQkjBA52UhsKR/s4muapFc31Nzfcot19+5SujGMeQDRi8yeAG8eC85MBWFE1DhZbby53rsg4xRPaOxfb64WyV+SHRlfmos7DYHPFChJKbxmd7onfLMMYC6E0Tvm1aTIBfIvsyBHaipv0U6yh8DrdqjBjmaQtrIuWjkQZv4PVdh6h4CJxN4aHdVKbV2UpvUfOvsZKHriKsYP0h/K2qK/g7RqExpIz1BM1tXPAgFzCpUOkl9s3Dxhv2gOgsiiKTLVTXpgNQfuSFVV/zJn7KIwWn/14Hc6jSR48szQN9S4S6MT+JRCsPGqbRpQ8dRHCZVN5Iw9hy4Uuc+gmUYB+oJ091HQW/5pka1hyQtIq8LKvsjn5/3iWeUMB0WpSEq6kCe0QFkRlEogQzPugBZe8RcTGpK7V4ESIzBzKOoRujwA1DpmXqWdm6k/d0TCL1wjoG1I2HiDUSMfeZWotlFid4AUbHQF4GF3vKGDKlsPYOmWCFa5pqCAb/khaMWtloRbPy1qNl97rPmh2jak8Lx5kYfvBx1FZ/jRkHjMfAUmfD7DYWnOh1FYxglYc+35mSUs0108puSgyFkGvkD89c9dnHoYeWEWf9Z2HHMCXq/PAPI6cGMhdXCeRl27wd53tO53u+BGu8ObYEfwhpfnLjiUc5Nog/Sra57E4YBZ/jg85LhZyDEhsPiAG9wVTjP4YExuo1G/CPcN9RCojTXx8xwbxeIisK/Z8mcDy171MIU45DIUcdT/kldurbq6knO03dik2NpvP5maf96NG8hN+hW4Y5j52Wn7ItQRpf5Huc+Z/hF+OqfBzmlL6CMe5otu6Ff3/XProvpi9nsxDIkGlRZp71hT5bCnLzlNnYuF8gK+V00uvPZkDn8PefYm9UaS+4Yjztxp/zLEu1HqYzMHmQrkxrgdn6quDP6YOK3L5+Zpb9/VyxVR2HatuFrOPg+d3Fa2uY/bb7Mabl/3Xx13li2N3DlTx1AzZ6zOIk8gnpWUHtkoy99nBDFnQmkKUx/4wX2f1U60Hhn0x7mZ29JOFllKTBlMctNcF27KgOpIqL79QH1NySdZ6M+MwJdpjkdZVIHJXnqQGiwwngcOx6Ze9dvt/55Uy/q3rzZ1Bxy2SFeQlkGsyCuTjjGaYv3PqccinNqKZaDB+cFmt1npuDdg3MTqouBcwQvhYscaUOT3CfN+xaER/MUWPCKFIS4EVFE7WadgrM3QzEdVYErxD5e1+nnWHeuZB5PLNtgWKpHRr3FdRzGl60XCQe7Vk6xAvSHkfTfyoI774gm1xCLFk9hay3s0IajgkDWzrsGFLK1tncyPqhsTfE8HTaxhBcO0ryUiFgvSG/GGljf8fzpX8qsxYsbbYLxslAn4iIOVQSuZeyBw7DK5I6Hypu/2BFKnJJqvkg9NmBubqKHUQ1P3EWXNYXRe6nDnGIwvgJ3FISEBOZ6lVlz1d82Mg7f+y1yAX/0N4aSNV71ei+Bubu8FJKkg7FukpSzV+Mk7c09/y2f5138xKMOY4VosJtuKCbRqWSz50AcOd+rNICWampKIbnjQhDf1pR6DSuZvCBjjz+3iwCFO7pXW/Rwt/qc/q07JI8IKunM7osNR3y45S9jn7IsaIq5QiZEJh0WeH/QAq0rbbEZiagQptr9dflk9SV2w2v3QXirKnywiHZ+Z48vlJZqj6rHVZk/ATFLuLR5hxsxN5rEJY7hgcNuCDUYLzDB89U/+ilW0JuZznsX45+KhROpsG/yMyycbL5ClhWmjh+wzv2B1BO8PJVCk8dNHjQb2pnPBWfsmlGPUzuVmTocnZ+yCy/Kp5qFPLwabpusMpbv9ONdH4iMNzrkbbL/9AWZ3brDFLyI+/Xc76wR2kN4posBvHZUaxERjeh0/szRNwbpDkfi2UiwNuQgXoixgPZOcozJEC7n+Y8NCr2qrKp7PZ65tNtO8DmAwkz1d/UM/Eu8Bd0hPcTsubWO2BKOdY2Hn4BB0fxYO1giwFYEUXhablSrLnAv2fN1/Ty25xJaRrgH1trRrZ31mQhYlAfHFkwUZxoSFHbERuq2jndBhhwxHr2p/z+V/LcFhvvBr28JJjl+aZLjpWp7CB0cMKT8EfMA6IAP7DBUcUZMtqSibruZdcMDsreiuPZ7VMwogfv4/2E+ajqVaaGmlqvsQ/HlqUgkCmSncgKnNPbGFSGAQ6ATJV/XGfO6fchH9mOfItFtvEtZVTp8Q2bGjG9f7RCvKijJyrd133IX7L08uuBjE72fDbv9fiHmWzud3CBVIvPJUD63NxPYd1jTVQrfjCQnku2vo4t8fqz/gGOcevymNNVRvSF6KDW3gwggGKAoIBgQC1Wdo2WhVDofS438BPbUREdxtSpbZkw2WOEsSFWHvnzc4buF9nR6u2a1DVGXyr17OIples43x1aQgPlf2yXdbRGIMr3fCG02c8NP+r38+bgGOHIa2dX0lMHIgOyXUX0iX1PyTmOSedFn5iQWA46SC2dmDZe3KAfbn9BhgRbB1ZogO7I/8dbcYYPXcRT2dr96tPIiPJfLdqMG4lFZ/Zp48Lcn615CmF/p/uoDMhVjKb6DEBQVQyUef1cMOs+qFAm2ivU1IL7XM5GmxEIEg8OPv2D+BrHQ18FzpdlPEjtqknP1ypH45AFbrL0tO4vVK4OaPQNmIkqC5aO60/xgPgIXsw642kpbfxhwqa+a3ZeRdJLuRGtYvl79qL/OTl7XDcetPuTYMYjXLXhxBSBu5tM0zgarP2RwXDqiMGKEjgMSTl5Ei0EJfXCoUGgI4vZVVqUHkhRgE5z909piVNsnCdOip80LNcT/Qxz0g8dUmKBsH0Y4hmgKJEvTYTuHucv6+N6dkCAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgeAMA0GC2CGSAGG+mtQCQEEA4IOjgAVgXjZ0awyrJv39BOvB0gCdi1MA3Rahy/pa15F13siG9yN2W5HEyMtkRg49k/juE8Veh/c91IHy/TILwZBmcIEmqmQrZGzk+t2PmuNyGz75a5YJa7Yv1EWN142Yac6YOkSwT4WVd6uGaz1rVzwS3RAoSqxxd2F65J9i1Wzo19cwm5YtQxsFU4UHHzrfhCdiRN+ohFOt2K39CfsLJSVkLBvuW5Ud9dkHEwayNRnBNG2bnBhTAR+7jV2ONfc4nH8+SehclMKqComX09TbbHXBZ9Xo9rRt7azUInYTfI0wuCYqCG4F3tjL0s1RFHvj6iYmT5K40YfPgMzslUB8h0JUIdipacfLBZ0T/NBaIddWt4drIisXeun2K1bZ8tdklkk5wo/sbNuPNMKXL66aumYAFVTFX8lEu1ovM1NAmBlXl6+fa/KD9blAhOYQGTkiQfXcybubs2AQ/7xqzz+NOjuy14Za7Uim8E40XrAX9HeFH5qPJcljAQ+v9XWE3A0ZaPi7U+ccfbwuoEyT2fGpq7BVs9RAdVG3RmYilUxNc9FK3aSG0vYgwsh+HanVaSCmoTk1VXBHTeEcqu5ejQhxCD28ynLk4/LMdWIPELmsSctI1uT9mh6X/cwJHlNqxGTNws6PcELx5biGqjUSXBHyM0szEXoqujo+8NMoPhdz3HNvflvgmAkA7A3WrfK1lADTcI/ezVla7f4laWaXFESsIgQPoFRMKdXDpup/t5Fge7m7PBweF5Y5IuIV4wBlyWBEQsgoY1Cmc63mzZluPwMQ04LgTcaQZtW6wmEm7+Sy/RaA4XSqcHzr5GPwd9nJqdcwztE4h8zTu0nwGJwZlgtdc7T7PndmzzcbmTEyU0rgVN9hFwEYlXHChVaiCKECmAVuVBBu1zqYr24xQKKqdvsCN7JhfcBiTBjUXDLSnHe78rYNA5QCaLguLvBVUnSln24RYG4hYwic2ewTlURbLE85NtC0p1yl+wcWEKJnWdhBMJrb1J2yC5XIig5LsU9n5SZNpW+SLJ8qqfApS/CXYts1Bi5knxjEOJCTBu2scOQw/r10UmDr+0xai2eNVNL0Oq3/nkn5CoORkqPaayxTxEGQFdpaY7ZyF66A/jHMEHvkDsPj+ADGTMa1jLBv/ny/LPt3G4oqnalHrUTTPOltUOii2dwSe1lwO/MvvgWmVNuAq+kRucTrKWE+hcjup38xdf47q/K5MHjgwELKzUa2R1bQJOIIWhgTr2YB9S0vp1XTNVZ5AAC74VQjVDUoUHyJINlQWu7wGd+7Xqwf8Kg03+9daJA5W3L4JkKiw8dv1X1DWUaZ4clI/Yn6EnOw8eK8TX7v8JRaUYnnwrudit7EziiluNgkFb0KsFW4de2FnQm9T+ErxT14EMbmC80aAU+VrEp9uUzw63+WXq2fgm6f13f4m0Sg3k17HiEAuiHxFZGvWvHDAD0JrSQHybKIS7nlkDbs82tQHG6seVOgSF8w43YNY5QyWj2DEfxWlCliflsPYZ10tB+aipplEEZZio48/MREohIlau5irV0OwDlP+fnjvBaBpbzkVsWiz6zwVGErDX9ZPpjtL51WyK91KZte8CLIqLoP+5VIofRpPHMYQQvjgCTh3LS/2e/rVroZSug0BKza7Zu1ckcuOOqBBx/4soMjZTblzdpHfmfCNFhKVDvEJuymN69uh7Qwdo19/hem4E0z+PMJ6AnDKZta5ti1eCjWLc6No9S7/xiojh34zSo/l/0pC0NSPve52rKogqgUghGXZP4NQuVEj4nYM4MlUE+0aO/IjwQoAtO5H1e7sllfGQ3JD9yKD7f9XWiztoOWqg5pZB9ZSl9oGmBI2eE2hbxSlXFCHzMhZ3Oqlxek5andXArYC1s+cqv19SnY6olzteGCgGjhvR/AIgWQUpNC+wLdOvkkQaF0x7HHK3CxJrX2tq7j+vDwjFhGmio9nFrlTTwW4KnxaIxgQsWt/vPHzCRbufMoRUkZelP+S5Cxd+sHk3nHItcXZL5YBCxoBSryKObCE+KCKJAgmM00C0fT7meJlZO9teFODDZLB3I+S+NZkE+jBaC/pqqwMTpS8kZouqNy+ddE8IYV3XGssajfK39HMwFGPaCtep/A2Ft+x2+uceMAaIoLhd+mWrV2jXlu4SpKSuQQMRK3ErkJMcmHTRM0kJu8p9AYgWLxkt3Ljw3Jtv5wn6lquz6vqhx3X4IBXcXhlAtx4lHNsUuiRPgh8oSdazuu5X/in/pBdNrEvQZjYPELKfTRv4ahsy4qhevDohNpz5CTAnJECpa6eNWn9ea4JuglDdHVaDoeeXwDP2cRlp/V/VVa+mwaIBemLUHdaiw3ExDKMuIL+iBY2geEm8OYSqCyztOwCubZ2gLlq+nYU/Ylu4s8hi6fCH89DV0doesCE0Y3ypFum8Zhcv/dAT/5xzFUlI1hksFniUewT93hWs025Em7h1DeX09yl2IItbpeJ5afzQbCPSBfKL1JFO24dEf/uLooNwTGW8B3r3IIWHx2XvcXDDBRJNf4/gmjxy9p5mLPDmQ4HkByWm7zN8lWC86C/mG0QlBzOaP2RQfruBs5poQT/UEh8LnoH+CzeMGEM8Q0wDlFzc8EEscdYoYmguDXHgTwgiLD27yD3wAyToZpZMVW+JdE4zDSuQqWipxKPrLhsKk3TtA38EAe6JRPkx49Kx/+IVHH5nVE418PKjUv7EKxrgH3Z43oVBpU0LYrTiRKQ4XpyovEEJfgg+iGHaM+/uChl1pLm0A6ybeQgknriGxPwzwRD9iPHlqzFaQNgjiTXg75iBbOy82On4H50I1nILb92disu7O84wCy/3JgvQxvIUk/ZTY66Xw8gXrS77LAup8ViDUOc9hhxHEITAXbsoUIdq1Q/rzs0Z0Np+wLZImS+laDUa1iaCgR2z1HAfcCjmvGVxq/J6O/52hlwya3+ijMkif8nHwdLqZTLUvqa3+RbTGqsAxYFtV+lsQeM8stBJhVE5sYm0SOtXeutKgTOzg2qLa2uQ5l3HrnIVg9G+vbNcv66B7p57kWs0oAxvsDgy5Td4Y4W2zX2yRQeQcWb/fubhMyw/suLZ5u5WH4wKhsQGdu38uYz0cr8JV9Okq9kF0GfOyReUv2ln0jEipETtx040IAmREkCAcd0qxpuaKVUSjDHV4+o9xlWulKUMwbk95PkDQHA4oj4fGFmaaZ12QrqVo2uXoxj7zUKG/18Sg1kBzHsYget0HJC8GNMF884C5l8pK79i2vWSTrTi8uaX6t2CjWmTZdu4YnLPAhyAF0MvagHHGSDjUomp03wxh928pMg0lTIwU6cQalv92MnSaNPSUP4ZSzR+iaPzLJHUzURJGDokeh3tP7CwWRW1zRCoAd4qrmo1AeO23gHrGTwDR5QHWR7oFBmEmeXob/MjffJQgHheFZjyIpkc1FQKGitnnDSe2o3bHI/RPwu4ZnYGo8hV6JxCuW08vzqwADjvx3nGSRcc3mAfZgfNFQb6lmjNxjFt+Xa57KIwjqwAO5CUY0eBVkkPWRurEX18JzjeyPszG5DBmxcAAWTFTWz9eqioztN70yJvwijDQJRLdfhmuv3+R7BsA3HY5V93gQjG7IwItAukqizOxK0JOZjfV8LMPyOyAo/rJ20X90VEoS2/Qa4m/fzd6gIDWU2pYII04KQqTTHcCLLE5fo1t6eiQkoK/MOSPZNNyy7O6fmEUZWEKCpmSz9ExmhMjdayqB1yA4mJvxHFiVyZTYHrVFvjEE8Jn/dkiMNEgB0urkfGWwsYe2fPF0kEiHBnx7CZELuVSUGpcbTIfRdxfEj3vkpaLV8mL2F/gqTA0P0Rm6v8REEK9YiSKqSd4rXhggcZbg8iAzobkzs4vxfA+aA9MNXB8MG9rIz0CjE93ZxySu9K76hKzJNdGdQyyz2IYI0nj9rzjve4s9cZkASGlfM6gmNw4iiDIThfUSzmvm/MgQaQ6P1RlBFE3lnp07sOK88/GR4I6leCOuIFUVJhqCNo2InyKY8cvQ42ga7QCHWk2s3XjEP1RRlJExrIVNTCnfbt5QAT0lWkQUfLDiBJ2HE7pv0sNl37uCQMMfAgcfs/Mb7aWy1f7+41Vl+cDriATOFvYnjelXmI4TAxu9Q352EZ28PPhQIHh7z9iupm9IZ8eZAFkPnnkv0YkawRarNmxkddNdjiWqd6awuKDAFPLWjkATiQJZ3Vt9is6DR4KbyOzLskNHH7pkvyUJrzJ41JF5dqHDS9SJD0A5PkCEnSWKBdmEvIcIbBDu1tuMbUcggPssjPjgaYZPcn8snddh2ubGc20crw1AA2yAKHxmgyv1aZG3fxi+7t/X17qs4sC+DW3Qm+/h5CpGB9VRJaPdVaN90uS2rijEz2Esf8uNkRdYdz3+AEMJCw9WGWDj5ucwMTWFj5gl6y9v9Li+Pk9R4KTtsfXZn2Ik9oAAAAAAAUNGyYtMmYys+IZTq4EfKvqbyZVnbFWMS/grA2PhaPWx48fy0poCOkh0Q6KSjUldSbDeYfzr+Gnm+cIT1YDG8bpQAKpaFkz4DNgDjE0PkEaQPnjQ0DNNnZe+sKrquPdZwjUTBvGSNk+7pwdlVgRjMrxaRLz+Eqo5qq0GnXbrdlBm6WONYMSGSvnQT0XwpGKnLofibc66uSWndDijKmeQJqH804F/muZhfuQcmDzjElPithL69GU/UphqR/yirNE3HTHr5Tx7XT873e1V3AX1zZFNiG/jjxrnenoszVA0R+YIyMYg/4IfF1jrUOgGK9vWAH0Wd0AL99WuEzybWpSLTO8HU9wZpXsNimltwq+d4Jsi8hR9nAmsAN+zYH3piPa5fYQJtt8swzNPkEwIMk9HfLiu6nHRiD9yTPvBakxm+cTDTTArwG4OG7baN4zfhduepfWLVTulhLJcSlWthNz7zDUkNMhctmYt0YzUmbrqaSqJhcpPUIatoBEHyf0BApma6OZo/XV3Q==", + "wcltTbF83I73TCv2m50TYqyxH4DxowlnGBbzG/+BlMEwggbkAgEAAoIBgQC1Wdo2WhVDofS438BPbUREdxtSpbZkw2WOEsSFWHvnzc4buF9nR6u2a1DVGXyr17OIples43x1aQgPlf2yXdbRGIMr3fCG02c8NP+r38+bgGOHIa2dX0lMHIgOyXUX0iX1PyTmOSedFn5iQWA46SC2dmDZe3KAfbn9BhgRbB1ZogO7I/8dbcYYPXcRT2dr96tPIiPJfLdqMG4lFZ/Zp48Lcn615CmF/p/uoDMhVjKb6DEBQVQyUef1cMOs+qFAm2ivU1IL7XM5GmxEIEg8OPv2D+BrHQ18FzpdlPEjtqknP1ypH45AFbrL0tO4vVK4OaPQNmIkqC5aO60/xgPgIXsw642kpbfxhwqa+a3ZeRdJLuRGtYvl79qL/OTl7XDcetPuTYMYjXLXhxBSBu5tM0zgarP2RwXDqiMGKEjgMSTl5Ei0EJfXCoUGgI4vZVVqUHkhRgE5z909piVNsnCdOip80LNcT/Qxz0g8dUmKBsH0Y4hmgKJEvTYTuHucv6+N6dkCAwEAAQKCAYAbEdbzLv4mksm7QNbtZDOA/sBq1UaFAu+pRd7kwqD4KG3AEITZH0cf2yP9Myk7Y16uopnKukgtJGjqHqr4UW6L1ptZ1G6fSXYK9CRHzQgpv3/bv2ixaXRA8q9SebrLO/ijg3HoFZb2qVFjLDwHMrFJ2yC4xecBDANTo/G6xAcbhoYFDKn7hBPCMYaQ5GfdI2KEVOW/oSilpqYCThiGvi6peEU2tGCIWkoYLfyD2OCECiQqekxtmHFF3zeuHdktEiVMvVVQu2AE1tqI7C9YdjrBuz8gSqTRKONrB6CiFS49FjKwmBpf8HJEr3H/0aUNnsiJ1vMOReuUUb58ZOImxN5ySA59pXRxp3cJsvxJrEHsVRYUSkExCIMuovuQrLU0qNZimXXb9yWCGez675798EpY4ldNNhja95Y1VRB0N1yXM27G4UVQw0+Ki7DSBJ5O5t1P6pVEW1A7JBAWFIS1Eh5n47BZEJjophFvmdbAzg3oWv4c8V6d4Fq6UOJ4xoxG1QsCgcEA9wChcsb1QwjbRZQL92sBFUhWUzs+FOTkSFp+GTF7jKGLoK2553eBOUSNFvOcBHqNJnlFzd0UPQg2P7LEqwEqEnWj2pxikoSCc7OvnwS73gyd6JLn3mpU/lGluIM4g75yB0mOT/egEOhCJrA5Q5v09898bwchVfQIgd9EpJ49brfqioFP7jhjyhkcA3SUsdVYwJ6VlIQtGBGRADlbhOVkrpsUhGq1lSGb+aU8eSo9fF0PH4NjkyfiQTc8Vt/yoGaTAoHBALv1ALNNLTXpYwwO9OAaiD62sLEbz7I0iE3Ap1xh3hT43W311zlCTNsQogICHJJikDCCo259fPLj3QEPWLSVK3HL2H/IZ8c+flXutMRuKmNf3ckr7mhhprSyKcsGVeHLur+Yev5+XQVqPg8qONFrefM9ObZKlKZvPvWd5uBrF8JUoTMY3DjvONTLUvxQazZZpobJBFTSxWW5+BhVbrWFV+Gz+N8sBRKY6yQfRNrTu20uRyOLJU2azqE5sW6KVWElYwKBwQCEtt0Ie6haTU7rsqE/XkolsklXzTQNK/MQgTbRuImmxUHtooqJuOdA6vlYBKqmqWZf7rc35nqyVFA5p4cOTsDZTEYu9unrybECE+Df8z4yD9tklFJrafyi7SG64x6hgtln2vjRNL7XdsPcX8FU914HLH+ydEVQFp/fkCQkwzVE4SLvKo3U9I2BkD5CCQjACF74l/zM4LwN+5pKYYcv/8U6H+9FOsS4DWfuGf9FJxIEWUf/6au97Kcf3VrZXtjRoGsCgcEAtEGvvkWRylZdyz680gAgEiUbJ3/InNuMrSTKXOrvFaXmloJjOmK/WoiFFu/3ftxP9HYVTu3CWx704QNayzUUSTp6E3KbNJZWiws3CfutY0iZZ0leh3S/cCQ9uJwG2VmNbBpMOq3tgDf39ItFmnI8rm5VXuH/1e5yrxQUS73pN1H6lwqMiX3DPzEQETL+30zzS+iU4tSQw5KqwIuOdT/AnJEBaObKpp9JQ4dJfaP56CetygS0bcy9xhmSdLTuVRCJAoHAValhbV9NukzQXwmKKtFLxx62xZqeIPzxIWA4G339+xfmM09+OkB3rrer0ZCROs4X27cGT5zolPusEv/XxJVPKfC0uGkAxPrhg3CozqGBr85aPnFbI7xdhWTsko+7M+r3OGJ/NyCKakY3cwJLrtPYrkj/SE1o1OPyxseP45V0SQ97NzzNt3yr03thCJPAWPiMQeA7S/tkGWAL81YF3NBErM1yGE/fN0zrcruHbyv+NaUfZIG0hy7oNRinAhufQWyf", + "MIIHHgIBADANBgtghkgBhvprUAkBBASCBwjByW1NsXzcjvdMK/abnRNirLEfgPGjCWcYFvMb/4GUwTCCBuQCAQACggGBALVZ2jZaFUOh9LjfwE9tRER3G1KltmTDZY4SxIVYe+fNzhu4X2dHq7ZrUNUZfKvXs4imV6zjfHVpCA+V/bJd1tEYgyvd8IbTZzw0/6vfz5uAY4chrZ1fSUwciA7JdRfSJfU/JOY5J50WfmJBYDjpILZ2YNl7coB9uf0GGBFsHVmiA7sj/x1txhg9dxFPZ2v3q08iI8l8t2owbiUVn9mnjwtyfrXkKYX+n+6gMyFWMpvoMQFBVDJR5/Vww6z6oUCbaK9TUgvtczkabEQgSDw4+/YP4GsdDXwXOl2U8SO2qSc/XKkfjkAVusvS07i9Urg5o9A2YiSoLlo7rT/GA+AhezDrjaSlt/GHCpr5rdl5F0ku5Ea1i+Xv2ov85OXtcNx60+5NgxiNcteHEFIG7m0zTOBqs/ZHBcOqIwYoSOAxJOXkSLQQl9cKhQaAji9lVWpQeSFGATnP3T2mJU2ycJ06KnzQs1xP9DHPSDx1SYoGwfRjiGaAokS9NhO4e5y/r43p2QIDAQABAoIBgBsR1vMu/iaSybtA1u1kM4D+wGrVRoUC76lF3uTCoPgobcAQhNkfRx/bI/0zKTtjXq6imcq6SC0kaOoeqvhRbovWm1nUbp9Jdgr0JEfNCCm/f9u/aLFpdEDyr1J5uss7+KODcegVlvapUWMsPAcysUnbILjF5wEMA1Oj8brEBxuGhgUMqfuEE8IxhpDkZ90jYoRU5b+hKKWmpgJOGIa+Lql4RTa0YIhaShgt/IPY4IQKJCp6TG2YcUXfN64d2S0SJUy9VVC7YATW2ojsL1h2OsG7PyBKpNEo42sHoKIVLj0WMrCYGl/wckSvcf/RpQ2eyInW8w5F65RRvnxk4ibE3nJIDn2ldHGndwmy/EmsQexVFhRKQTEIgy6i+5CstTSo1mKZddv3JYIZ7Prvnv3wSljiV002GNr3ljVVEHQ3XJczbsbhRVDDT4qLsNIEnk7m3U/qlURbUDskEBYUhLUSHmfjsFkQmOimEW+Z1sDODeha/hzxXp3gWrpQ4njGjEbVCwKBwQD3AKFyxvVDCNtFlAv3awEVSFZTOz4U5ORIWn4ZMXuMoYugrbnnd4E5RI0W85wEeo0meUXN3RQ9CDY/ssSrASoSdaPanGKShIJzs6+fBLveDJ3okufealT+UaW4gziDvnIHSY5P96AQ6EImsDlDm/T3z3xvByFV9AiB30Sknj1ut+qKgU/uOGPKGRwDdJSx1VjAnpWUhC0YEZEAOVuE5WSumxSEarWVIZv5pTx5Kj18XQ8fg2OTJ+JBNzxW3/KgZpMCgcEAu/UAs00tNeljDA704BqIPrawsRvPsjSITcCnXGHeFPjdbfXXOUJM2xCiAgIckmKQMIKjbn188uPdAQ9YtJUrccvYf8hnxz5+Ve60xG4qY1/dySvuaGGmtLIpywZV4cu6v5h6/n5dBWo+Dyo40Wt58z05tkqUpm8+9Z3m4GsXwlShMxjcOO841MtS/FBrNlmmhskEVNLFZbn4GFVutYVX4bP43ywFEpjrJB9E2tO7bS5HI4slTZrOoTmxbopVYSVjAoHBAIS23Qh7qFpNTuuyoT9eSiWySVfNNA0r8xCBNtG4iabFQe2iiom450Dq+VgEqqapZl/utzfmerJUUDmnhw5OwNlMRi726evJsQIT4N/zPjIP22SUUmtp/KLtIbrjHqGC2Wfa+NE0vtd2w9xfwVT3Xgcsf7J0RVAWn9+QJCTDNUThIu8qjdT0jYGQPkIJCMAIXviX/MzgvA37mkphhy//xTof70U6xLgNZ+4Z/0UnEgRZR//pq73spx/dWtle2NGgawKBwQC0Qa++RZHKVl3LPrzSACASJRsnf8ic24ytJMpc6u8VpeaWgmM6Yr9aiIUW7/d+3E/0dhVO7cJbHvThA1rLNRRJOnoTcps0llaLCzcJ+61jSJlnSV6HdL9wJD24nAbZWY1sGkw6re2AN/f0i0WacjyublVe4f/V7nKvFBRLvek3UfqXCoyJfcM/MRARMv7fTPNL6JTi1JDDkqrAi451P8CckQFo5sqmn0lDh0l9o/noJ63KBLRtzL3GGZJ0tO5VEIkCgcBVqWFtX026TNBfCYoq0UvHHrbFmp4g/PEhYDgbff37F+YzT346QHeut6vRkJE6zhfbtwZPnOiU+6wS/9fElU8p8LS4aQDE+uGDcKjOoYGvzlo+cVsjvF2FZOySj7sz6vc4Yn83IIpqRjdzAkuu09iuSP9ITWjU4/LGx4/jlXRJD3s3PM23fKvTe2EIk8BY+IxB4DtL+2QZYAvzVgXc0ESszXIYT983TOtyu4dvK/41pR9kgbSHLug1GKcCG59BbJ8=", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "y35WuSgIaGApnOj+cOsFBKZZ5BBc9e1yWoqysWOlm8/tLFSlPurIIfhRg10xDcoNzrEzpnHlQwo+mc1VZ6PAPAjT8TxSDgdODEZyArOoujWvRARC3bbUn38plRfAFtMnuApLc4T+LN7T6rIjfW2WDZEFsyB1FGdbS5ZsEg98N+lLQDBeZMK/34p+FefkXTDAUZ5ZVG0SR9PP/rOBaLEO3NJJSESHJClKZxHbAcsHGL1HX13YXnpPfPHIzt+3Ah+/f676L9yvTJ90etLFmZ/2cA78amQFgkGf/iyG2nOb1ZAXRVr1k8Ljq83hhvz5xEfDitO8hzrK8PohS8rC/hOwF8hi3zcP5nndMjzGFrB67qYAJTQkFfpn+Pr5sn2oBRjHS0YL4dLaVyNXBoVJ/v48bgSmk+FeB/0s1sXbQWE1Svmymoi18I0XJxNwSnWZfebpUiHKFSuNLIRj7TFYOQbTGkp0eBLVLpwETajzfiU5A16spy7kXpu38WBvK1bAu6Nt8jlU0FNBNRIAMh+2gMDHNfBCUZMHpW0mbMTD53/Uoo5wHerqv/8DWmya4HTny/UJjAHmjengMGpfDRGnU+4BNrh4vPcpv8w7jfrOTneC+/aud94xBCnqdte2sfMH2vBB8IRRf1Cql4A/jT7veAWIw+nyXXZJPbIcMJu+lgUlpaDzJEG2OVHHnhsS4rRm3yYRZyFin8slptVAHjIoaoJD+JK2DDbgKIlLR5M43SLJLKapkuTiGGLD4gnxND5ZWv8BUAv1E9iRz36ugCEaR322ZkW+IO4ExzOTGuPDIPNPnfyMRKh8+OtcqPbsTJXUA6mbpouh6H2eMHBqlSA/dibTynT1D4AnwZqkMFEdg4isyv2bskU0DyJqKwtJEdUqbjhudC12HGJkERI1B9xdpFAknKDaGZxmikcdUnPHn3fhbT53buVnCrM8imN3pedvOom2vSrPGmTMKvMCpT7ReOOqodGx42Juu1EvJMPzHGsFuVlb0kAhAiW4aheQYZlxk5aYm4YzLdKkS0ia2mTRKR5ZuEH+x0YsXxQY2uOp2EIHPt6/UXOVE5l18L6fdI0HKWI0l4cua3jnxBAdZlW8DQhCcu/BHUGbtgEgTWvQHQoi6Ge2Hhwn5M6qqqqLXpbTDvRywfseOvfZhZNDW1GqxFz+acl1NkuWADHPgFTaglhzbbhpO9/qAJvODRT0/OLOsb8dO/oYUuoHUKxIUmPcZArtAT1zVQ9qMYa91VKqeBmOpoXZmdxXSSALaHPrpbLAADvd3bMQWaoO+pMtKsaB8sT8J3XcKZrJtLw0XbA44/8e1Fs2wjs8TpBTxPKkjCvhqWpbkegM5RaRXpNW4nYIQmb+SWeGrw4lvb1Kx6QpL47gVaK1m7qf/lgFfZb8tgi78fnrWlD+cW5AUNGgMy89kzGwAwUsBSKoc7XQsHeQGkJ1q6HyCca2lEuL+kHc7fXIHF9mcg7Y5RnYysI6crVnMACmkYKv6DAwVc6a9JUSup03RtEwGDSgOrx6K9KaoLsMAMVKG7EwjkaqvaMWrmNBx7ZDSq5DhxhriT22D5IEyVNtnslGVMJPmBSkzJhCVI0BWsEBgFzU8kSBsJ7HO+lWZd9g6kaqNC0z8lLxoT7OTV2+3yE3Omx843MZiTgJhc/dvpizdnTphrOZsjA161GqoU4aRpEhWt4RyTB6T9GbKSD4jka8BtfjdS09YZ+0AqnQWTRGxqg7I5ZB0vEemhnh0xqAf1mpP8Bk1sO1AQylCooGXVPLBWSDSK/uUQ9SMk1RLB6tPYyNdovI1GkJw2XPs6hn4O7quDw4mheZKrtVR65Zz8DqyfdeIyfSHki6HS1gVDhxhzY++czYrNr9qRphY6KKK1loX6KwGwUHdFnMN03FIHeb9Sp+sJPuRGpOu5a/dLvzSC6SwHQwDgt6v6C3zmYq0t6dbwYlaU34eRfU4mWLsPPmevZ3LNRIedr+yurc3sPAWJf+gYMEReK3o64W3j4WXY/Z708Tp9BSTDH43BMfOsyk+tQ1s4vDs+7PheCGbAwXNxJY5VuxuA+gBk+Z0AMKuUSFW6bIg1Ee1WWe/pA4V0jGAjkjYlGql5nHR3t4hTmH+eA8aGiXNLV1iQD/T1Td3rLsaeDiNoke9Yy0Lx34jZl1iru5MsgYwqw0dmrAwQDSE846p8l4cuTHK04T3E6/oBZ/K+YVw2uPJt4OwZKCR9w0kh1OtpkLeM19WHbktvqX9bRmN6qgyTJ6nTQHyTEzfJ+O76QpXOkv4tKmuxyIizpue2BhHtitAKOuK681C12tCpZidQSTCmxmMc5Y+wi391ZrdGMqSAGbsOC1lgeaPW9qyDEEgqwydjiH/ubNw2M4kQ0t+kOOQ8jVAIyqmhC+8DFScZ3FeOUfu66useSVko0lvWCX97CW+8WrJoYGZXIVTvWYpK3pmOuQizDFAzNe+aOtD1hMhvbGDScgPG4VRhphVJHRGryBqrViJtaYK18d+Ratpatn+JFsQq5FUL7IZzBxwcbShJ0WCSfN2BvT+XTfXUgGMTOos4AhAm1TWAes/wF1JX7w8unNiD5V4KGDZs6zeIkAFJzOs+2vvd5rP4V7WFypttopBUHpFN3kdfJzOnF9UrrnkWUlha6V0CyVpXe46MgCt85p/jjEr+0QWO7AR6foztnINtj93dk0JbXfOQSFpzQ39irPb4bcVdJ6D496VNDLSv31XQtXSkceypGgTWS7sr+k1Fp5hyWMa4JVNx3tcEGaNCI1zcVKcgdsl8BxL0tsEM5+MN/vXc/W7EwA2HzayG9I2LksCor83VBXGklls5AaKYzmt5b+2fpkuZvuk2XeEx0YGtlH7HsSbquKaj0mOyTvq7Xzk78o8HokWJ3FKrKuvNTHGiS/sK9P+A8LkqfGWHo7l5F5X0g7wlcSQ5ven8MFmel8Vb520CzvzgP5Q0AtvuxBXkuVRxc+02qkM+ESWLOYwgqcexPdj3yNUql2sOznD/xUEUHIDHMNm4DNO83p/5OBULZPRyztjXKPIpRyta6Lx+BsBAhtUQ0ppsAHzDachRstc6usbepf6M+m6sJzjzAboeA9sn89YbAikt0EOIAuskI2wOpOYsNWLj70vTM26nDOF3PMmThEMaF1O4XVGk2kA/v/Z1743nSkcuiIgRJE1U3E08yu6Kk85ljK/0B7qTVA7VwYlbvk0JSKJk5gdcngMy59AuBjynhqXTBnpfQ3yLYtHbTQbOz7foY4k1n/PvS2mtxC4T/715bWzuunwHuPw+oUx4wcBBFJvzlk7UBK9VNCBVUY3sQi2m6ShC6nHewSN+i31Vu7FR1HV4Or6QNFYUCdK2GEe4Ne8EhLsMl0YCKcekTxndjEo89AMem4Xh5vmu64lY/PKAR3ffbjYSVDDQlmkWXxoHiJK6X2UwWfP44PGdqKFam6kZpvbo3akrhKSd3DHVIttkHRDpqKh54X0NMeVzQj65jo7Cb3+7yxL/PkSAmqXsytPjANEjZAl9Yel3FihvZT8nLz2+xuYLMcjrrIFIDfToAlgeOu8Zex0+AUkI2739LwxCL28ypmKgFaz3wJ5VQb7jE9Av0bAs2Z3ZmFHcss2FT13TvzKLlKcb3ukqsJ3zo9FdmyzFNvyIHcFIR7rUDhLIdgLJo+t350kuPS/9A7CK0o+T7zJj7AIHSxyT/awWMoDcakHyUKxyadONv/780rgqcfU8bkqmeXmaXSEE8InqdHUf1+3zfkbAWRy6SQ1GldR+CHcxlyQK2DVTybqW6CqyOE8/h0+g/NSicwiDnMJ1tqWcnXhQu+g/dSueFj5xaHL43ut0BJgStu2kZVQGRaAgFHLM4arNt07Nx7xzq4Zmp2+lu5n9Hlne64dtffqFbDgc6KOWnfQ/PPFE95aaoKL6jYqtHQudFFzIcQoWFRaPgXHSQ5ssKsfXEw3yDcuC7zzQJa/A4Ac6qQJf19Rq+XbsCiMQ48cnf8u/042K6chOZlj6GpT8JnK9LuV8Z79/MopxKdZgAQOSmTS1D1YuX3RSDlU/mZBhsQCAwaq+mPh+7okcK1FRqP93iheoP6PYNwNzsTUzcVQA4K1MllLUIBXOXJnrFbuDFu5H/UeU3FlJe/vodKEh+lZBh6s4oUMNyW73t5FviytNjbiPl/Gz/+DL1WCmlYAbbL1MEZUvefxrpKthcfxqyxneTtUliFzg2YKHqfhv7OJEXDrTjlT4qBDWtrTRvIgTsWqBQkQaHxUucAgJIVLI+nrEcrL9KM4mhuhy4PTzXa/DLenTWxl3HbZhP1b5x07oZkkSElyJiorjQiUSXQISOH9GkPIubhirj8R748FMXtYCxaZS8N2mccPEWKlTjV+OCdZB+JiIgMBjdLTm2fxAANPJWpCCVYho2VmKWx0N3lQ0aHptni4+jxQkR1kqjE6RgcKaWyAAAAAAAAAAAAAAAGCxcgJyyqk8qZr2jPvhn5OtMvBEVUFN9rfAFahrqemAs9YgjhdXwfua1bZvGK3//9uXnIUKWjB0e3UD2ZVrZv1OsNWxlh0cuFSuyQ8MfNEwcNXRIQDtqGe4+dbNVriqWG3KnkrFp42qQmqux/p8vtJxeVedIcpTM7+r6CCOHxfXm04beCr/5wt3a2WhO+LCyIPrfVcLmQX3NG3AFLX7Uj4dr4OFFKlv9nWUWoJaK6teFBnW2YXKMW/+BEwYRdMwTOSuvFuBG71RiHXYGARMx6lMspwlZmiaj7pMHal1DgF97XEjrhtyNn6NdZjaAvHBGXVVe0P32aIgA7nZxR7yWV8siMDNq6gu1C8ahT3//e43LA0HWwUF2RF5BcFhmuafT5DSVrwL196f7oJJSxquXYAFUENCgTTPio3n7vt5iCIUbB7y/i/d/GZ91s4QthfbZqzaxBZEiENC1cGC7WKPp0oCzIIxgkmKhZksxf/8mCFKwfvkZZuZ0sq75Ss94rrMPWNA3QYcE="), + new("id-MLDSA65-RSA3072-PKCS15-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pkcs15, + "60MJxEXwr9xo+CjxdqrcvLwYmRu2QXVKW1Q5phaeCder1sboCnhQm4ge6f4HsxLtJZzYNpzWnl3k0gM4hs8p2nEt2gVJ05HTkAAOcu+8n8Txl/aTWvIeu6z/ayJoK7b0jBRRoyGRg7QeefLgNAqc5nLIXx9NExAjtrsrpjGoE1dgsqwzZqLOtyJPabESHVQ0JLyw8s8jgAzsRS76/QDXvNsEFEjVW40NdJExBQ1ODrwVMFxWrUnRPQpCxNsGd//Lq6V0m9yCJr5ZdJZo4rFVZtfAWIIdd5CycmpVaM6hzxfHAcRopCWcOLUwEg1Tc6ZpdOMLjUMwLNXbmhjeoEz8PASp9reLuSzqxk/UjDa6ip370h+CS/Dgq3KyYufwvkPCFd2rknAOegTumpAcHdO3SELmKVXtuZXe4vd6eSB5EuZNWfm3+FEIUZ4g7r/EmQp85dCS+ulFqlPSJ4VzTegX6k5U4YHcYZZw3NOzl8pOYH34QGhEkQplIKpjPnH397DvcUqyD189c7q++6EcrLETthQwgGOFYAyb8w317a7PkYujdZhw61uBj+lxCOR3JzOmJcB/yfeNcJDdag4mw+1IIBUl9FS5D9NCr2e/1ucAUlNiUpF8nT25XR1eJ71dw2th31HMpngvIw8BVB771ooZsAGEBnxTCfmirqS9QAE+Mu1X13ZLeTmEAHYzkPethgnwlMpryPPEjuiBW3dbBOjCuSdi6Oe8Tjhb3CnImlXMDj+PXDshsY3jwUePxMANJHnX1hPfLg8w38g93Si2m43y9Y/fHRYU7tzRqXtkwdioJiq0Xm4a35vO88T+4WvH6E07SXHio4X5t+gCfy704F6egYaUcU/6uoIFBvk9q2OutWwlsQ2tmC6/0cMt0iK3XtwIMWtwkwXlG2e8OHmdflbN7jut4ed2TpBl/y6rvp1GfkIo2zPWC7ckuPkkbaElMRaLXkjLaiWvzQcjY47vuDm68HEZdcht2CHnyJamp/67Rn5OngmK2fx5m+XQpKnHvuuFBf9vXqeFx8saCj5zScXrLpb+640P74OX4dTjm2wwgFVo6UmJcyAo4wnf5lW7RjW9Os/8084uCmYOmaYPqJktJNmg1hN9d40SZNs3qwWpWULvindSzVUmYrlBm3CdT1kD77BLI6lvNzM/txexpxsooEtvMeN/TIhRcq0MlaOHVSIT3+HigZm/YhOZdNZzirHa0qwOyzHOlL1H7yfGsHgtiNV3uwQrNK0cWSvHiWrsvMDkiG6q6ZUYWLqnAXwGUMXiI4xopsrOFGURQmk5zeuxhpAOsNoTsoznv173EmWwKyQO8pF4NJV3Zzvefjn2Crz2qYJkO3Hij5yZlE7QtndQXzymdJii644k1uSmKtPr2Qnz1OxCVcfKnrguBOb79emVD65qB/Lx1yRrDUfuXp3rD3RekAAGkaKOmQWOV0vn1eXbAuNFFwmDCu+FROJF2xBMkQXXz5yP+X2q62aSt5ocyeBJsgj5FghplGKuTba8FDAQxwS19ylazwq63gClAOiNIpI8m9PPRjBm05E/UMlIMyVj1+zB5Cs3opuxd87UQeU8p/B45qi5zEX+03eJxKinRmliEg9dBEgZ2Hb/sKrAL+zKx0AJ1Ws+pZYxIwcV9vEhW0o3+7iEBi6vQ9e8MVNj8WYLzCjTG7Ea00Hzo0S6rB3oBx/Ez6AZtpTmdT4SzR5EP4tXMCNCWn0qQhqE395YXH+keX2YOK1hMP3cPEEK1cQtT5Fmra9zSptOZKs8Q5AafCRD3yKbR7Rpq1iUoFXh/TP63uTPfuMBcPe1ukxe0DfCOrEftnY+MqG61tM20DKq2WLX/ol9f6taO0E/1+XLwIP6EWB1RwTckMsmY9inOphEH7Qx2NvIiyRVn4SEFZhvc1KZWCRfoXUtWueShqYgSNzPlCUFok8cu9yoX9F5INi3j+ZaG4cBPprplpvV4BCDrDuYFQ/zSMZvAoHsHe9X8125vv0+eZh41gM7snnN+GwQw2PdmpkU9SHSCeLH4ehkZI0QHAZqHh33WiwLDI7voRJ1YySnnmLv3fKLCGQL4JKknXO8qQrHr+9wNYutfQppRppfLWoCrDKcRRVh8fjsRjeoO7F9vUIezzE8o3Nu5a3Nq7lyDle+MYE0l329me25h94Qj+QI2QkYLx7miAGevqiA+DmxqtZnc1iBjj3km3Qbfg9NitViVgABIIEp5moL7G7wOsp6YTltW1EGJsZlLu7+SN/hbSwKIdxNZevf1MvqBL554usob51s3hJuNC6WJH9W7GAQQOep32XsdsP5wHssLFcQNX6pZ17i8o9rW/iYpE7fJuvCHasGE2h7ajsUJC7WlsUP2/tkzwxV5O8yMe/JwX3cX1kjvyZ+voGs+Ajl+Kx95clqvdj8YzHV0J/kjogtJy0fTr35eZERI8PcEUFJvZHQktyEciYFJUzD2oU5si43dl02kOSHriMKpSeF9Vn7fT0nEHBkEPu0U2e/Yi3DiCmrZu/afnmQYlkYRmRo1KbV0MgBrrmObtixvDVRuFPS5E51s9H8yrqQmsdVFofegG/qpWV7vR6yA9W5F0F2zmcNy0Oq5Gr2xIJZVqUwggGKAoIBgQCmRNu1edDV+ybB65VMju90GYUouQYdhdpUzVELbt7Jmoek68J+xlLARklaJMe5nztEK6fp6mehw2HEJOCWpjMvPk4t3R+w/lk+Vqks8YN2cAvayQ/ebp88bNQhDAqqCsakX+XAAy2CngfvwSXe8M+PEnrG9u2zhDn6vPtVPUslg70YgmRX9oN0HjG0GKMfYeRO10qb38e5z/cilKnVzDy691VwVzbwNQU35aNQhjeBRezFn5mipLr7Q/o3hKVFGgqnOd6JWCN/rluvLWfGe65XlT5m/zEJvKuTOrZn3oqQMlffVdKTdgw90eaKc02EJDCP8nrNyHAbuSLrh89vAr0ktqrDxhjKXV8oy60yHSe2VJje7ft38uo3+aJnENTqtw/uNuJTPzEtNVI5CNUTH4G28+MLMaFgMgPQcJlch/fZg3FvszyxE9zej65aLqymktQFjrRBDXOmu4UsHCcX4sAecMks/aAndAMnwNH17/6pK7F4IC/wqwZpqb9MdTSjwW0CAwEAAQ==", + "MIIY4TCCCjygAwIBAgIUJFfNeKnkehIkXWEJm8nNwH+qHiswDQYLYIZIAYb6a1AJAQUwSjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxKTAnBgNVBAMMIGlkLU1MRFNBNjUtUlNBMzA3Mi1QS0NTMTUtU0hBNTEyMB4XDTI1MDcyMTIzMzAwNVoXDTM1MDcyMjIzMzAwNVowSjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxKTAnBgNVBAMMIGlkLU1MRFNBNjUtUlNBMzA3Mi1QS0NTMTUtU0hBNTEyMIIJQjANBgtghkgBhvprUAkBBQOCCS8A60MJxEXwr9xo+CjxdqrcvLwYmRu2QXVKW1Q5phaeCder1sboCnhQm4ge6f4HsxLtJZzYNpzWnl3k0gM4hs8p2nEt2gVJ05HTkAAOcu+8n8Txl/aTWvIeu6z/ayJoK7b0jBRRoyGRg7QeefLgNAqc5nLIXx9NExAjtrsrpjGoE1dgsqwzZqLOtyJPabESHVQ0JLyw8s8jgAzsRS76/QDXvNsEFEjVW40NdJExBQ1ODrwVMFxWrUnRPQpCxNsGd//Lq6V0m9yCJr5ZdJZo4rFVZtfAWIIdd5CycmpVaM6hzxfHAcRopCWcOLUwEg1Tc6ZpdOMLjUMwLNXbmhjeoEz8PASp9reLuSzqxk/UjDa6ip370h+CS/Dgq3KyYufwvkPCFd2rknAOegTumpAcHdO3SELmKVXtuZXe4vd6eSB5EuZNWfm3+FEIUZ4g7r/EmQp85dCS+ulFqlPSJ4VzTegX6k5U4YHcYZZw3NOzl8pOYH34QGhEkQplIKpjPnH397DvcUqyD189c7q++6EcrLETthQwgGOFYAyb8w317a7PkYujdZhw61uBj+lxCOR3JzOmJcB/yfeNcJDdag4mw+1IIBUl9FS5D9NCr2e/1ucAUlNiUpF8nT25XR1eJ71dw2th31HMpngvIw8BVB771ooZsAGEBnxTCfmirqS9QAE+Mu1X13ZLeTmEAHYzkPethgnwlMpryPPEjuiBW3dbBOjCuSdi6Oe8Tjhb3CnImlXMDj+PXDshsY3jwUePxMANJHnX1hPfLg8w38g93Si2m43y9Y/fHRYU7tzRqXtkwdioJiq0Xm4a35vO88T+4WvH6E07SXHio4X5t+gCfy704F6egYaUcU/6uoIFBvk9q2OutWwlsQ2tmC6/0cMt0iK3XtwIMWtwkwXlG2e8OHmdflbN7jut4ed2TpBl/y6rvp1GfkIo2zPWC7ckuPkkbaElMRaLXkjLaiWvzQcjY47vuDm68HEZdcht2CHnyJamp/67Rn5OngmK2fx5m+XQpKnHvuuFBf9vXqeFx8saCj5zScXrLpb+640P74OX4dTjm2wwgFVo6UmJcyAo4wnf5lW7RjW9Os/8084uCmYOmaYPqJktJNmg1hN9d40SZNs3qwWpWULvindSzVUmYrlBm3CdT1kD77BLI6lvNzM/txexpxsooEtvMeN/TIhRcq0MlaOHVSIT3+HigZm/YhOZdNZzirHa0qwOyzHOlL1H7yfGsHgtiNV3uwQrNK0cWSvHiWrsvMDkiG6q6ZUYWLqnAXwGUMXiI4xopsrOFGURQmk5zeuxhpAOsNoTsoznv173EmWwKyQO8pF4NJV3Zzvefjn2Crz2qYJkO3Hij5yZlE7QtndQXzymdJii644k1uSmKtPr2Qnz1OxCVcfKnrguBOb79emVD65qB/Lx1yRrDUfuXp3rD3RekAAGkaKOmQWOV0vn1eXbAuNFFwmDCu+FROJF2xBMkQXXz5yP+X2q62aSt5ocyeBJsgj5FghplGKuTba8FDAQxwS19ylazwq63gClAOiNIpI8m9PPRjBm05E/UMlIMyVj1+zB5Cs3opuxd87UQeU8p/B45qi5zEX+03eJxKinRmliEg9dBEgZ2Hb/sKrAL+zKx0AJ1Ws+pZYxIwcV9vEhW0o3+7iEBi6vQ9e8MVNj8WYLzCjTG7Ea00Hzo0S6rB3oBx/Ez6AZtpTmdT4SzR5EP4tXMCNCWn0qQhqE395YXH+keX2YOK1hMP3cPEEK1cQtT5Fmra9zSptOZKs8Q5AafCRD3yKbR7Rpq1iUoFXh/TP63uTPfuMBcPe1ukxe0DfCOrEftnY+MqG61tM20DKq2WLX/ol9f6taO0E/1+XLwIP6EWB1RwTckMsmY9inOphEH7Qx2NvIiyRVn4SEFZhvc1KZWCRfoXUtWueShqYgSNzPlCUFok8cu9yoX9F5INi3j+ZaG4cBPprplpvV4BCDrDuYFQ/zSMZvAoHsHe9X8125vv0+eZh41gM7snnN+GwQw2PdmpkU9SHSCeLH4ehkZI0QHAZqHh33WiwLDI7voRJ1YySnnmLv3fKLCGQL4JKknXO8qQrHr+9wNYutfQppRppfLWoCrDKcRRVh8fjsRjeoO7F9vUIezzE8o3Nu5a3Nq7lyDle+MYE0l329me25h94Qj+QI2QkYLx7miAGevqiA+DmxqtZnc1iBjj3km3Qbfg9NitViVgABIIEp5moL7G7wOsp6YTltW1EGJsZlLu7+SN/hbSwKIdxNZevf1MvqBL554usob51s3hJuNC6WJH9W7GAQQOep32XsdsP5wHssLFcQNX6pZ17i8o9rW/iYpE7fJuvCHasGE2h7ajsUJC7WlsUP2/tkzwxV5O8yMe/JwX3cX1kjvyZ+voGs+Ajl+Kx95clqvdj8YzHV0J/kjogtJy0fTr35eZERI8PcEUFJvZHQktyEciYFJUzD2oU5si43dl02kOSHriMKpSeF9Vn7fT0nEHBkEPu0U2e/Yi3DiCmrZu/afnmQYlkYRmRo1KbV0MgBrrmObtixvDVRuFPS5E51s9H8yrqQmsdVFofegG/qpWV7vR6yA9W5F0F2zmcNy0Oq5Gr2xIJZVqUwggGKAoIBgQCmRNu1edDV+ybB65VMju90GYUouQYdhdpUzVELbt7Jmoek68J+xlLARklaJMe5nztEK6fp6mehw2HEJOCWpjMvPk4t3R+w/lk+Vqks8YN2cAvayQ/ebp88bNQhDAqqCsakX+XAAy2CngfvwSXe8M+PEnrG9u2zhDn6vPtVPUslg70YgmRX9oN0HjG0GKMfYeRO10qb38e5z/cilKnVzDy691VwVzbwNQU35aNQhjeBRezFn5mipLr7Q/o3hKVFGgqnOd6JWCN/rluvLWfGe65XlT5m/zEJvKuTOrZn3oqQMlffVdKTdgw90eaKc02EJDCP8nrNyHAbuSLrh89vAr0ktqrDxhjKXV8oy60yHSe2VJje7ft38uo3+aJnENTqtw/uNuJTPzEtNVI5CNUTH4G28+MLMaFgMgPQcJlch/fZg3FvszyxE9zej65aLqymktQFjrRBDXOmu4UsHCcX4sAecMks/aAndAMnwNH17/6pK7F4IC/wqwZpqb9MdTSjwW0CAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgeAMA0GC2CGSAGG+mtQCQEFA4IOjgBKOpLHa8+ijodqUSCccJJFruklrCoGGD5dmUWhMKaydN69UD707/qSJdOLfkvO3UTAvGc9yJAPHkQVf/wbrFV/vv8g9fWCo6J0VvT4y5advna23V4FS3gAz+GbrcnCXW0VR75glyuXNvVMI2t9YYg+qUcSAWNiJvwDTUjmE85FZqeN14W8/OvEkneoHtdVlwNrBxsMilz49l8lihtGPFPzUzU/UYCisNvcyhDj+0imJ7ywDiQ+8+O6TSxHytfzJe7JkkKTl8/ucT9SkVx93qLR4Re9raxWSRFAuz1Jinlkqlki4y0RZ1k6CH73Br5fUosjS5+fmUDFAWGGUEJ9mn3C2SD6dYFRqQyOoTElhKzCG1FLCQA9DDcMxRrrt22H6usQS0tqW1tcAKoAwpsirW6mU/4/vmZLyq9lUba/sw3jNUdiFcop+YYcoHIz5kdn9qOYthWI8of7cH4wbJzha+D4v1OWcyYJxvTkiwVTrly2Tk2f8aHnQU9lwrQ2zoBTV+YQRl7wQCBw5K1kNc3huoGCcwGpNO+92RSP5LQkbMpF6ZXTt/hiRWscPny/5pKic0TSKJl4Hha+JwVwvPGaeQuMDVaRmTCZQ8jXHKFx2gbFHNcjvxX1tjEU7Xsu/exY3Xj42p8ZVcEr+qitBhFEOEr9UNV+etfTys5j2EI5bsjDaMhkKEQZT9CvMMAjOxAsPX5hzT6RoYlAfTEG/6tKnmHI2O2vf1gVox3QxRIU8JI7I9EAtowLc0GcL7M2SUWl8xenRNkz9UTuDz63CGb9oKMTldl6QgC2Cw/U6Z9picBHk4FA45xjez/bhzhVY7qCZYECRNm5LLL0uk6IocwYbXsJzr/Lz7rWUdSmKeENBtO0f5Wxp1PweJ+YqqBJCiqaEGTeQpxGfP4UKKm9VzUwY2hQPhAHUie+ThcnnTo78wmSCyd23c4BiI5Un7Y3zA/XvI976d4ZRFiVK+/namUXvXXUnQwInj1AzGEJeMA1DLw/m+aIUoBrnTpRA5cfKYrpnC1wHWAthmRasjX/zcNY2FQKO1Lqh2pevDKI7xkk3j81A9GzvkSGTPCf9WpkxNIO9QfRcfCJk2avyCvReuFm/sT5Gdw366NjmGduI20uvkPnHtkLa+9A5cb/cfRHCylIZyM8TXXUyBKKO4LaEK0CZGqvJiysbYSc5BTydgD2uAd8tBzrCr8iADIqfFNdIYiD3DSPHUAXRnhYlN1B/KMTMeF1zMMuXg0SGAqoHXSY2lafuZIKpxURBVLiu6yc9RfI3oprS5gDKzR2ftBn7JTri/eLmQCtW99f8gr0eXdbn5SmptI1z59m7JfS5K750ARTKRJYKuUqqRU4S/5A6aLC86o15bj0bndGcQ9AQVvpl1ZLtc+EHvbOpCs8p1t4SRYBF9KeirwQP/xyG+1QncJ0Juv+YMZ33BXQ9e3M7/c87yOgx1dprClAQ3+FKoRvnSPPeUVbm2NMpFMkvf/XuwnvGlvMGe+3U7FQ6Afc+oQmTYCXgys5MU4F71Xm/ijE0EBRV3hcxnwvCGBvE8OeXxjk/aJnOkEZk1aNRVMOMWPrWMxAFA/jPgU3NAhOjKm6rQT0JYQIQaqwigIJA2+LHs+8j5Txrto2FET0Tp+r9e/TvTVQlzlpf38s/1EeIaMbNRje7azaX/motP7Ob+3new1su/Ma6niQjVTodPZMYY7iv8QxCuzK2duw+KK5HwgdqcwsoKeSz9kS8uneE+6KgVxEAsr51gXxX1hJ5DkkU9Ju9jiLrml9oDB4C877zpneJEnkjckf3br/jr5aDBrbD7cmWd1KROJ7xkUiAW5VTYzn9ZyL9pEiyGYsamHA6YDTWJurW326ngZOLcn4aUdjyPqbyxT6GOA8aKGCcqGulBOtsZHOvrA4X3kHnJplZTyprhppjqRnmeNPCDo3bgV75GV48mDF23xcpOJ3tKw/1SIaDmNaBCcbvZnwt5oSSCwmoiaQF7gxe+J8mhwhffRUqxfZ84hHcVauAIC+Cd7+UOkVMisD/nRbUU1Hhq4HzAdq6j8j6qIK5KDHI6qoR2fTpGDsxbRaD4pcrZ0eXj5r4fhIOSgRvc0Jhdd2xHLt3VRzaolte+TzI97ouYke7zLxN2D9ixLYMv2iYR0jMMO8xrvJ59gl60OqApC+FZIPBSwEDmLUMC/leSwusyZevlnG7qJJzt+20rt82X3nBC9Zc7T8T4MgSuNN5Ref2qOqBGfeb+NytkWrt8suJG78xPS0gSejwsQbbz3qjCoQlJQzBv5Ji1TrZv1tnT9JnPOo60BGgURmrXac31V+hEO4uEog30Megr3poVeQdGTbWKE0foRpDu7gPINTBgnN14se9B1blEYuyBbLvOGvg+kEvYNWqieuUWwzM1Ox5cjZWJx87Lyt6keXbcpY/c3+8l0JiZMLTdJKwd851XHVsGOH7vc9ifOXo07YPc7H4GF9GJlG9cC20DbFnGiDRBZUnb9vpq5e0nTc8ZrvrE4N0SU7A6j4GqC6fg7fhOBP8WnfKZ3JD5JaeDfisKvygYzrmMOp0gHAfoLjtjMlrhrGsBrnFul0DamWUZNP0fU7hYw/U/gB1WvQwHJNK6Qjm+HUi0e3KjYxkYzBOf9/KkdPG30TZ3HvBCuGmB5vYtRr7svofJ+hRbVvrjmcqRbOWcMX6bwQtDkC2m3nVG2Y6dfx39vBAZlgzSYz+kxxgOnDK6Pale33gGU41Qz093U6rHYW4Or1VdtNIhR0lmH6m4JAM9JWPHPwyG6QtMrTazSkKokvQ1U0l2QLvdNWALObEbWXweuCG/VqGvrRV4ksfEKbnkxroDjWA6txsIdit5mcBe3VK5daUeTGl34QYW7MepOwaVa6TjL/WJC+WHydIlZux8p6MxLq3idW7xUX1v8Gdo7A/Sg+VWVFthWH3mwe9BSNi7Fj6Z5r7Ce28Qto+TdsCcKPt5rxWf44XGj/YH+U5g7JWT/z1P1+3kuyievZsyXhBUbmfY28+aAVf7l8/hYXpM2YulpVub1nCLgAoxuoh/kayxro02u3cIWNxYU2jZgv4damxcHmAn3Cz3uUtgetZz86weZBTVUGb3OAWqJRcX4yiLHZ4OKJcORMNthnGFb3WVSFCCGAdPA6gdH8sSDbkBxVYJ2VY4fL2XBkVUTzDfNmEMsWAgjL7eRzOSyiaNk+rPNxpvoTJREbO1jBQ29qMTjJOZ4o43kMMVTUK1dKqbau1GsEXrr54unjtd02PNRR2XEdMGWdJ9jBPsSgCUz24oa9ZaHUZ4CkhtSkqmWAWq5yVMeIALxq7+K+3aQHCdR0tkNkCxjm8LSap8AxUJ4ZkHSxipSvtnowtdcLrtn3mo00BS2c24LKivVD9/rQPRiJkKyWhOM+uL+Pb/yVUmuQN04sd9W9T8dG01lIR92Z5A0qNetn1GihrXC0JHFSKGuzhi6m2zHZRtN4s7Vu0kgIlL0wqUIG0d+o8XPtvAIjne2FNRah5uapfNsbMl5e+Xc/V6CMbUgjv36IQwy4sDrIAE6XA1VrGPWGHDJdRq0u02iF3bsA4zAF/6eQjdGMsyi1n5XLIUQ4e8vOC1g+GYG+T7LZV3zy2aptREBpuB99QFbU/hHx0zxYbyg28Z0+iNFL/n9ZSOETWe8m1soBWeJRj7dT+5EWY/cI1hWyQWrCu2K94OfF/mhhsPnoDjPcG+c+eC72FMQoOqwIjXdqSscuEDgNlZfg+pUpNbbiozQOgqW5npgXAnhAMptqRAZRpslSXEG1N4SX1KW7PiSLzkDByuAWYvh2mho2sJ6F+IqC0PbPi+vb9Jg0S/FptrMWEbkNWA0UiXsbxwPAK2m4rF5CkZAR0xq0NcUEwrXwO1QP5lmf1Wiqmt+76KPkEE/SPF7qhUeCWQMtrsDYKP1XRmC/pzWXmE2vNsnz061XrDpHA1pWXQPUubi9PjH6dEGhecKKBadXMld+v7q/VM9BO2RzCKkkMCiuY7Xv7rKL0PrppuY9dM91rup8BdqBuwttAoGVsl3LgSHjnauyiHQUHa5gP+1TMLgKZJlPXNJ7NxahjHAVffyeb1geiKmG1LFsWa+g/a09JAyXRUMr/SbqvkNSB5gdYDHhORtV6zMWjnxfjiPGwap1c5zgBIG1xd9+IiubdLprqfnLM1jM+Ys/dSfcov++NSgUKP8Rs4lW+rdfeW+pBKC1tTGz6eCZ/36dq9xOZyoMZK7V8lvc3KPCiId+kX4PB0rk+CkpHvrtlVLlKJzZDztZ3Lm+XN0f2BHZH+hlm78le469SUxX1m/2NztNZIEIoadhvDswLqUBpokoG2y2RxemhhNzOPqPVYTN5pFUE9roryHj4FSXh2W4qKqVa8KD+TjFjR/CZH7YDElvj5KozNjmcHV8D6iuJytudHiInazH0+8hndj6KiwtmqHmAAAAAAAAAAAAAAAAAAAAAAAAAAkMDxoeJIbH8fb5W3txo5KEz3u0Jx1loqmAXyfOwGlTd4pIcQ2zpNIsiDnMewPM18My6RqNTcWYIg0aiN51GMGUSC+oz02Rv5QCgpYnjlHhc8L9SHtjtVjY4M0JsNLQ9ldx2Kg1g0u5wHRZSuXa+XhIdO4kLEumTjgXqgzHGmnOTFpXCgEJI5TYPy3jb0oGQBaXoabLsUgztvUFFDELtWTezttUHZxHrIX8cJ2HMNwlt7hcFGINXaao04EYCfEaofbAqHbzn3kB2SKag4zT/NHUKdMlg5Qvx+7KnsJT+d09l0zX4KDcilslrWVLwnz62mCjcE+kj722CK0BDkZALZC0Q22WMbyAoDfviICUKxVwe1oY/ewHzvFxNRwFq2laXxmihnPsfoZgand9qDP4BaO0G3AkDvXcr8YDgehhvK+gN/eBOULr2P2taL4znT9ZMiguMK0pJ+OdG+bFfjfcuJ8M/X0NRObT/Af6MKTpiJf4v5nzMr8hwbXUJM/hiJFbiiauvpQ/8Q==", + "X+doLYsryin9XWZ07/ho5nes8qW90KCfl4UZb+rh8DowggbkAgEAAoIBgQCmRNu1edDV+ybB65VMju90GYUouQYdhdpUzVELbt7Jmoek68J+xlLARklaJMe5nztEK6fp6mehw2HEJOCWpjMvPk4t3R+w/lk+Vqks8YN2cAvayQ/ebp88bNQhDAqqCsakX+XAAy2CngfvwSXe8M+PEnrG9u2zhDn6vPtVPUslg70YgmRX9oN0HjG0GKMfYeRO10qb38e5z/cilKnVzDy691VwVzbwNQU35aNQhjeBRezFn5mipLr7Q/o3hKVFGgqnOd6JWCN/rluvLWfGe65XlT5m/zEJvKuTOrZn3oqQMlffVdKTdgw90eaKc02EJDCP8nrNyHAbuSLrh89vAr0ktqrDxhjKXV8oy60yHSe2VJje7ft38uo3+aJnENTqtw/uNuJTPzEtNVI5CNUTH4G28+MLMaFgMgPQcJlch/fZg3FvszyxE9zej65aLqymktQFjrRBDXOmu4UsHCcX4sAecMks/aAndAMnwNH17/6pK7F4IC/wqwZpqb9MdTSjwW0CAwEAAQKCAYBJOESa59CoEshQGIswYjef5Icn1kcTpDjwJFR+2O3CUUtPvMTzaCnT43/08wKDQ1RpomH5GFFXwr9gja7bmMgsk18BQoHswy2QzsAEezzd4NzPlcBnv0ZfaTuHbBKcLE+q3lJCWwPlI+ux0Nh5E4oL4uLvkJk/90hDG4sA0BOyKxAQZYeD1xqvfYZ83WakcMsGTzfbadI+CQ+3ikk6Tg0mdroI1Vdrs6WfJoDjep+hzaXFp5GUNr/i294qKb9QLXVxsFb1kOix5yXKe+IjYOeDLc4B0yH8GY+Yn1Aa41Whovg0623KQBqsNJtHlRXFpxGTT0iqABN37c47nJepthdL9d6kO2LHsd+MCjskUKViJEuPGubvsK7tifDumnJm4e9ITwmhCwF2xesSQQWZmIpPPhKtZGEfw8Yo6ogz6hOETLYGn6Y4zY2lbUexD5OJsd/AA+wYvaRbNShNv4HHrU0GTJ2hVFZiBgq/AHSMs1EwGpgchnYSvzDaEWA6FII2NH8CgcEA5tdfrolQiW5SOw9gVA2ynkyi2hRyJr1nZ+RJsY87uvort0wW8BHPNZ6OULTkaktn+h6MizZinflB5/RCLctY3MVcOhMqHm9KCe+E6k3TDyooJL70Z4z2am3MYVTVakH539nj1yt6GV1twx98QXkDpyvR9BirJ0ZZRZXN4ANTu7PDLaO8qQrjPK+N35qk4Ovy2BPJ93pjR55Ii1FXaEFv7xuqA20FRAYlekqdsJWL16TziqZ+MlIZVV7YV7Je+ag/AoHBALhj36AnjiuaCGa7BKnxmL+r/QG9zmKqk2a2Ifg3YVhp/mDEO48ddpxM4LcGJ4sRcvrBPukKeJu96s2TaExvW8hp2STCd+y+XOG13gXTcLYkQYiyZ5JVR5gD8ahD32EyEwibqblnnmuP9L6uqH/Y/dt6pdunKkfVFm38FpvruRGwIpsxFrX5UK0jDmue4LfnXMbarEvSKoSYaLo3T95U0Hl5KYX3cwbV4Es+efIEuREwqbzlks+lfkYwsB27DqiLUwKBwQCP/s9Xv542bFPtNXVAWV8PcfywDsr6MXH8k6IImbGHvCBi8ZrpXCKmbuaVn5FQYQNWOZIwENfJdT/QYkSZ7lvbM12JeITwgTltIzUFN1CuB/0MlvU8VukrkJxKJrIN22P0aCXBBgTfJ7GdYtmOud82e5Y3LuAs2qw7ROwsjcbAsqzQnm/D/t+q7lOQpRWunGBau1VkA7tEZI8aIL5mcVNSky4lfu8m9LKSK1NcYJzgAqxM0/iqiR32a/iGE+U81N8CgcAbEl7Ezsnq0OSm4JJguR3qFkBBPzLL/atCiz8ViFv8dSNp5aWw72x4qjjb5kVr/5XYBwNLh8QJaarNn/TSNA9Pr2q4IO0mjxRn9yGvzUlhFJWikj7ulyK5yOpz//MN/CIbQ295zyLNPAd873vBuYQb8zfitfpZLYnrf/V50vQLCscp7d0dvor/wIPffSYVGhze/UAKqcKgURgfLvvE8sLg8s8L4ja7LC+QHI4e4F6jjXd+Sl5xqiSN/Zv94XbXfA0CgcEArJq4MV2ewtKVz/ePhgmdYL9XzZEmcMs7r9uBJZnLG4vbHOtUZEX90EHOnHC8xmEtaufIe0l17f5DXCgkjFma+JIFITMAu0Fuc1aPijx5jUPTUjVdNolj/Dbauq4nbmVAPS2Puli3+Q3C5XYF0f31uadmin6c35HFZJDCOpXhPa2m78utyprjlXLnuS96vXusPUCQcTVuESTIZ2AfOose+NbazDeBnFcaO6ab4Lx12oSvLxrxQWvoRJDBTXd6emkT", + "MIIHHgIBADANBgtghkgBhvprUAkBBQSCBwhf52gtiyvKKf1dZnTv+Gjmd6zypb3QoJ+XhRlv6uHwOjCCBuQCAQACggGBAKZE27V50NX7JsHrlUyO73QZhSi5Bh2F2lTNUQtu3smah6Trwn7GUsBGSVokx7mfO0Qrp+nqZ6HDYcQk4JamMy8+Ti3dH7D+WT5WqSzxg3ZwC9rJD95unzxs1CEMCqoKxqRf5cADLYKeB+/BJd7wz48Sesb27bOEOfq8+1U9SyWDvRiCZFf2g3QeMbQYox9h5E7XSpvfx7nP9yKUqdXMPLr3VXBXNvA1BTflo1CGN4FF7MWfmaKkuvtD+jeEpUUaCqc53olYI3+uW68tZ8Z7rleVPmb/MQm8q5M6tmfeipAyV99V0pN2DD3R5opzTYQkMI/yes3IcBu5IuuHz28CvSS2qsPGGMpdXyjLrTIdJ7ZUmN7t+3fy6jf5omcQ1Oq3D+424lM/MS01UjkI1RMfgbbz4wsxoWAyA9BwmVyH99mDcW+zPLET3N6PrlourKaS1AWOtEENc6a7hSwcJxfiwB5wySz9oCd0AyfA0fXv/qkrsXggL/CrBmmpv0x1NKPBbQIDAQABAoIBgEk4RJrn0KgSyFAYizBiN5/khyfWRxOkOPAkVH7Y7cJRS0+8xPNoKdPjf/TzAoNDVGmiYfkYUVfCv2CNrtuYyCyTXwFCgezDLZDOwAR7PN3g3M+VwGe/Rl9pO4dsEpwsT6reUkJbA+Uj67HQ2HkTigvi4u+QmT/3SEMbiwDQE7IrEBBlh4PXGq99hnzdZqRwywZPN9tp0j4JD7eKSTpODSZ2ugjVV2uzpZ8mgON6n6HNpcWnkZQ2v+Lb3iopv1AtdXGwVvWQ6LHnJcp74iNg54MtzgHTIfwZj5ifUBrjVaGi+DTrbcpAGqw0m0eVFcWnEZNPSKoAE3ftzjucl6m2F0v13qQ7Ysex34wKOyRQpWIkS48a5u+wru2J8O6acmbh70hPCaELAXbF6xJBBZmYik8+Eq1kYR/DxijqiDPqE4RMtgafpjjNjaVtR7EPk4mx38AD7Bi9pFs1KE2/gcetTQZMnaFUVmIGCr8AdIyzUTAamByGdhK/MNoRYDoUgjY0fwKBwQDm11+uiVCJblI7D2BUDbKeTKLaFHImvWdn5Emxjzu6+iu3TBbwEc81no5QtORqS2f6HoyLNmKd+UHn9EIty1jcxVw6Eyoeb0oJ74TqTdMPKigkvvRnjPZqbcxhVNVqQfnf2ePXK3oZXW3DH3xBeQOnK9H0GKsnRllFlc3gA1O7s8Mto7ypCuM8r43fmqTg6/LYE8n3emNHnkiLUVdoQW/vG6oDbQVEBiV6Sp2wlYvXpPOKpn4yUhlVXthXsl75qD8CgcEAuGPfoCeOK5oIZrsEqfGYv6v9Ab3OYqqTZrYh+DdhWGn+YMQ7jx12nEzgtwYnixFy+sE+6Qp4m73qzZNoTG9byGnZJMJ37L5c4bXeBdNwtiRBiLJnklVHmAPxqEPfYTITCJupuWeea4/0vq6of9j923ql26cqR9UWbfwWm+u5EbAimzEWtflQrSMOa57gt+dcxtqsS9IqhJhoujdP3lTQeXkphfdzBtXgSz558gS5ETCpvOWSz6V+RjCwHbsOqItTAoHBAI/+z1e/njZsU+01dUBZXw9x/LAOyvoxcfyTogiZsYe8IGLxmulcIqZu5pWfkVBhA1Y5kjAQ18l1P9BiRJnuW9szXYl4hPCBOW0jNQU3UK4H/QyW9TxW6SuQnEomsg3bY/RoJcEGBN8nsZ1i2Y653zZ7ljcu4CzarDtE7CyNxsCyrNCeb8P+36ruU5ClFa6cYFq7VWQDu0RkjxogvmZxU1KTLiV+7yb0spIrU1xgnOACrEzT+KqJHfZr+IYT5TzU3wKBwBsSXsTOyerQ5KbgkmC5HeoWQEE/Msv9q0KLPxWIW/x1I2nlpbDvbHiqONvmRWv/ldgHA0uHxAlpqs2f9NI0D0+vargg7SaPFGf3Ia/NSWEUlaKSPu6XIrnI6nP/8w38IhtDb3nPIs08B3zve8G5hBvzN+K1+lktiet/9XnS9AsKxynt3R2+iv/Ag999JhUaHN79QAqpwqBRGB8u+8TywuDyzwviNrssL5Acjh7gXqONd35KXnGqJI39m/3hdtd8DQKBwQCsmrgxXZ7C0pXP94+GCZ1gv1fNkSZwyzuv24Elmcsbi9sc61RkRf3QQc6ccLzGYS1q58h7SXXt/kNcKCSMWZr4kgUhMwC7QW5zVo+KPHmNQ9NSNV02iWP8Ntq6riduZUA9LY+6WLf5DcLldgXR/fW5p2aKfpzfkcVkkMI6leE9rabvy63KmuOVcue5L3q9e6w9QJBxNW4RJMhnYB86ix741trMN4GcVxo7ppvgvHXahK8vGvFBa+hEkMFNd3p6aRM=", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "q+Ywu2B13KO+Y3mZhwUErZYp2DYcM7qmaCru0fZk8OY6O8macNCGvgnYD5MGaGQ7StjHb5VWA23FnsD3Vgcj2Tw+cA8bOUL1aBS5EahMpsEloaeP2P6IWK0c1/a/Pn77YG7524rkk8kr+Mb/wDqtuM6isYjeAyKoxD9I/kxwod7sBIL4KV9g8+bzyL6vhq7v2/aawDYDrlf77NrqbJffP8eOz5Xfw2xUCwUEMfKIBR9M4+gy0stKFz/bDTGuqZg2PLUfXcr30Jf7GK8rF2EmVzRgaiOhcdYGP7fR+1zC8ABh8gQrReC56xrW5usO++SuhEZlz17Acv6KsdmqyuUTRJB4KPnshK5BArVO3Qd+OVgUvsi7DS1/KrCrJmMiTaWVSFm0Q0PolHac5Mha1X9bVZxmjrbj6oKqvzwU43m/vl0POLc5qJErYoMx+hlzGxx94Zep4IB7WTYIUzFKuvdDeOZhL166s4jh5qh5Z9Y2B5L3SIz5N61GFe6TK3UxpIUsG0BGq3bqrfHK7WiTb4nsHEODhVVbLiVMCUkfPS/0CX6qts6p2Ze/0XS4kV6laSjixtdnhllasV3pHI+yxL8Bq45UAtyHQZPMMPpVZr8CHl0qzWsW57Yt64/bqjoFnvLhGX6FUYFlzNsOMDbTOFtwIrwdJBvfJBlZosSLDPNcH1pHdIp9wZsd5l/Ih53dqVTZmPKuZrSMaO1gn8Zzb7GBSJRlEJct/aQ48enj9F5ZXx4SOR8J42FS1lgqjFUwVHoAOVsqYVOQwF+KTCSk1aK73ARiYghtob6zD7oyfbvQpyuQpLOGfK9MeMtG7cl09U2vmqWi1QQa8hMVq9YC7eNIzLs2wi+q+rJBDJGSUGQTiWnyiNGrSTMR5M01v3pDMjApD280yBZl/WFo5dqn/E81HuoaSxjOImeek7nLuhf66wn00UjTt18c99IRnTtnYRHBq0qbRzYh5Ln7NgIONm2mJArj3cEwgjm84QoeDVwuLj5IeDuGMxaHEqoJV4/oDrVw2HlMo3Xvniu/a/ZHa34I0EdeKh4kCPELD6neo1jda3LQ7G7wKK93bYSnikzBp3SxqXX6G3N061jnxpyrz5PANbxOZoz2Bcc19GiRnFF2E1J93Ss0wzEzY+xloMbJFg6s4sC8WIHZ42lx4OMu6YdmsCkZrCUHC8IoSrHiQMAQzhRG+CzYOc6pJsVyhxj44tWYgMOpX3Vjv1P3jQJLOwTAGaWgTXEzl9OgV8yl/cQ2VKix0Ymx74Mv5Kue7D5KbZbYRHWBo4vc/3U0jvChcuvhqbg+CgOw4IXo90o1ofuGwoYfqv5C/DqpgOBHikl/40mfz67ftSIj5NlDeKJTesm13X4kv1dfPTtPAzNTzQ3PwN77xggwrG9Z0gmyNnhUZmVqtnWWdPz2KrcA2pSa/bTOYvoe95BhX2r6qaNs2oRKbl0uqc+7cH6f6TmkeIhbQgQO3TBpz/wE8mdpFvfnFLJqPsLHuMMOXpSqQlG0Ibrnnc1MvgaNX80Dwte6spCS6Nqd60s8evNBo5x6g0CPdboKCthisxoIe59u4XakQeaYU8X+mrbQUFTvNupGgRewYE8qrxh6jjDLDdGYuveOQ8JcmV3z+grouODShWfJCITUbzzYvGmEXl6sdGuyUi1Rmj9mecARbFVpYmFv9W74Nmacwg4RRoX5lKJg9C3RPNmMe1XjCH6cKurhujAbPgrOkblw33g5EwxdzUT6UH9aeKuXUHsj2AvnOzdJtH0XGNucvp2bwNk6DXPidmNiNXGI+qafNO9bT61lUFCUVdAAGq5Wj5JVSN9nHJb9N1usPRYoMAinR7Mek0fnm2zClu6QK9bNlK/FCyG62t0t9sQhzxDCLCruP2dAlGfPt+3H7VZ5MD+dwdc9iOcNnuujIqn8YzbTMlXkOrBpwLwnUTOqOhkYxnHlHL9HbJ6LIs7SzlYtIIReRolQJDcqAfe7gsTrfzqR0uYjpsRN+zc4np0ZM4Ui9aYhuaH3oTRJuLJ33ten63T/ob9dkDLzlhwb2c4KhWpUEbVzq691Blrxd5S9NoG5Ybzg3G+3R2fbGH/i0bgbn/xwrwkoloP77/Ze8/LWYdJf6sd3prVzYeJJQMxlPQePQYT0c+PXZLa1IK6P6ydG5PesAVrsE1fW7bZaTlDl0g4rqgpCGybHwo5c2iCCBAbVI8j/TA/TN2gjsvny0NfBY246xKiJ2Ce4KsbrT2oFkDy2doPjjmC2DntOrthxA1TT/0IDXFxDFwfCe+mUoJdO0ybhOs1kJqyQ/O7feiSbdY3FG2pOVlA9U0ftj09+AgaA2brkE3SqFaRVLx+wRzRPhZ7jL6+gVj8j1RNPHhtwp81wiNfPJUUWxSaJoHiazEf5NO1UTAAgLqyFMjDXKExKimITS1QUdrDOaAcPiC+JsaAsT/IGHRMA83bAnB7N3iu7iI3Z5MaUw7F8iAdVoymXgRSAd+umNoKXL8Z7COce/wionDYRxryf46smJ50L2xbWgv5ahmbV6Qw6+qpYjtlHPuQVt7cJjRw+MYFWMHU0Ouz8rPDjTsghsPEq1h4wZQDlveoUl53GVrX1D92+B660+2fXBu4jR9NkdmKm0fUvI7tZLenlaLqAZj1L/6OC49r39SUHYOCPn/4sFTjEZF7Uq9QnJi6iH58HCfycjtw+3Y3l0aFjo3UU6R7kqXcUdmA5KUBADuR//iDFSDKnlx0T6IM/nSz/1hBEO19IoPh/WzssYyUezatKhmQdErEk6ToDv+CdnKULHkK7ucWK6hoT71p7OpAVACNysSiIgPPchLY0jEf/TnUv8h9pbv9YyXtZltVdWg7qcWG5jhkj0Hmy2StwRth1xOk9TmjYrtWQu7tNjBQlZXOgx7tDoAWnmwt74bzAE0sYxF6gwJ4Qq5/h12mQs+PVhATIlwqVyqi2WHz168vzPbtgRAvJ12qpXz0L0BrrzUK1E6EExyZ9BioiaCzi82yUJM82VXzV0seiWMG1FUgD8SJs4tmFCpTiMpgX/dDwgUVAyF4qCwUHIYGkM6PhrN+NrUiZkLV5UAfUd7XsVq2uAwixVs4KmCGeCT+6oJtAaHDBM77rQBKxBAvcmh5R0kq6JrLdCt75JbD/As424vI/Jp6Awi75Y7j2l/epf3EOzIlyEm2I78j273zRoqJhjAOKZLMLdGSiJx0q9DO0d7EIHEFcaMKOnCHhC6laLZSR3NrpSWjChjKb5sTUBBapZwcakxOSZTkWNrkE9hULoSh13sqn8LDpmjdOLK+ugBMcHac9549eXVLRdGqWRGzSvUnPK7JfOxmBNLSqasTH3EdNAdw3gGOqQCJvcQCIZBWQdN6v0xZRsIKITWY0qOZ4vmA7E/LaD56eEBUMpwYhPV1T6ru/j0Knj/Dr/JavYa5URN1afdvW+268mIZH2pAD3/9Eoc3EJEuyRqf/JFxe+kS4SKqaPQCSlcXZBlXxRnSpL1YxP/R74nJuPy2d4vW7nx2HmgFiCKb6gATckiAa/OLPstBVqjgUI00uS1eKDKMLik+KuE4PlUrT/ZBMC4/91L5Sk2jo4jL5pU6RyOJ31oc1Qa1ElSL6I4bgbE7oAEbukaCZVnBse2cfjJ1XO/pXCuQwiwflC+B1o0GNNcfekXH6XnQUMIHtA9+Ob0ZgUIkPIF0MIFY1tn89tLHor7p4bZJfjOuFs+6jD8pMWFtv2IygBaKWZbjPxkns3cbNe9Zhn04zwzqjMwWaAKLIVN7vYmuDOkPX8yc0QuO4BByUAr0kB40s7ugUWqKzkWmqpEJ8x18wtYiU1XsR2FS4nLOlu5h8mTmNK18V4JeM5GMhNaCLYfL9qSpwIg95OUoIVLekwLBu27DiVNlswx+6sfK66eLePrJ5MYMa6164/iFt4kDqW2gilCAQeswZu36LwIo4nj2uCxPtXGn6i9KIAMlPn5DRZpEhLvng1WZCnEllSw3zkYODDlSJ7JaPKGURwFRmBc4gUINd1xe/oZc7khu3czWW5nNKVUDnhkDN5djr+XgbumcCm/ahNTaWbApQsXPiyluEzTOdEaMdATilwMdgXnpD4fGI5F4dYk5d8/2GdLoiaZuKFHVmbe2ArCXKTkvVQCsVWYDeF5mbSWchYAozFjtHGLXNS1ZFSHPb9VRH6y5CsieWOm6Qu7JEvjIf595GY7mO/AjV44kJ3mfqxEPpFjD6iCOAJmV43Nq24WTwvld5HNx6yE7TylrlmAt+xj2vzed0ZEGca3nelb2/StEo24hsHo29CFEBAkMqUb8Q7I4qNKwX1wUb7H4lTiUBoKnZk3+bB3zqvFwD6nc2NSd0n9PEkKLuuttPT2tWygURFZ1UNfI0rkPDkgTNud25XSIzmiIoOTpMwM79AEZXiY2OoKe/xk9dcI69N2p5gN7n7EhNrsvQ2AAAAAAAAAAAAAAAAAAAAAADCxUaISd8nvNIwF+XfSsWTYda8YyxPrFKtV2QOXLWSIlRYYeSzS5ysR9wWbC5iRcYouJz6EjPHA7Fh7nYCh4H9C9VsBTIpgtbKAozyKcdtYpT7yL8Q21fozafZc7o8axJ5uaB45BbBGdAfdwFBHOb1oorNP6YI4qllh9BjD4B5AHpjVXL2StTSCS4yoM0j9UyIEPbXTPqhPR4H1QLxblRrXSOFhM4o13uLbdZKwyiTa7+XVPp2+e8xhmW2B/dt3hykZAe9Q4XbMwH0WvFbV/KhH7DwO7lUqvmEIW9BhE3h4zO6HU8c+BCbMvjtp65R9yKF5zU4w2ba9CIfhAdMaq9sNGl0tBl6veqv7jn8UXOJ6rxhPrPaGpSaB0JUmt7eKNLy8Kz4GtiHDxuhM5MuN/owNaYATKyUpw9HuSZ5Cfq1T1vGn4pBlpjzPPgXvqW5atymQ90duQCnL6ZHMXHs9WPVwzV6mxtse00wUj8vlCUn5zsBLz6KOhQ8KEiL+hqGr2ITGkFlOc="), + new("id-MLDSA65-RSA4096-PSS-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss, + "NUOhxJG0QB+/5ubHa5zeI9+RBDbfHXWCreA7dySYXwKrUbjgpjpY6Yl70Q6MqortOYuDd3UuRryTo/BBCVcUIE1+z6maze0RiE0kLtJmdx6hLpTRSGS3Ju1j/svuvnSYGLiYD1hxDro5wkV7SFp2KtMzSQPl3ft6BYvwEhbnDPHi1hqMSTSmGtdHogirldUDwzCM1B+HYHC+uZApkM75+et1TD63cG53368GiJe12EUilNFSLKffX6BHNDP7aut8Pt1MCshY1V9B2sC+rnJF+3kzfGDJNV6KTLTddHjOFgE5XpdI6HH62EZvuEWWrVZmMXzWJgpbNmTjHhOVLpEvW6AJBwSrnCN6dYZogcqJtoZnt9OcmjSMb12Nc175RxlbFp6G0c6qXWZUlaAyG2tTd4jSwCF7LzFXgQEodD/5dZwFtDyHXOVee8C0NXAXWUjJ22ofGFtcvVlj2QPiLEiMuQbEuzude9atpel1dbLXqydYFMft8o/8NCpkxORLicfFvqdeB20H7bfIwOdiAlfSZ7h3hM3tdrdnpoDnGmqpDMLofoDI2DHSuU65XSHdsrSoLzrWq4Hwfgg5L4fCxHqiueevgQupI7Yu8oYrXk17jXazlHD0h+8Zamedyt8L8tZDxDmYqKiY1AMJuByc1vrEenA8iesViwD5Tlrjw1/EppLQAij9v8KxR1x40Juyaxj3ScH6To+C/VzUfBH6OrxNUY9AD+cmCxXA0NSgKDOkYAs48ILF3jF8zieZvFg+5eWxLdDFQ0BD3bB7X3cZh/DeqmB9hc4Gmd9DFEn2Lj4WF01n6JYtvmjh7bMhTL5ge3W+BnZdqz2YqGVfGGfWvDXYcvWmTbtBeLjX8Badx+E3qGrhXv/jxs3RrwjxTl2ZFxaETb13x35wTBelxofcQVvPBerklv/4ypOrWGUVjMBmJWnjiJeOAap9EEMMRsGBzr1B1CezoNWy2VJ4eavqdC26Rj614VJqrq+5LAkh1nCvhZIZ4BIgZHK20T7jiZsUzxg8lwhB6ESaI+SPHlwsLjKPqtXTBw5g2LynWiB/Iao+MjHJRFgDI8AfgVslR4GLvuRQCiH340Zk18E7rnFVF9I3JMBhzXEbaWDTt+KeZGSd6AfEPvPsy8x5qmUWkSdpsy2f3rqrxqEG0+x3sUiLqsrDOMBNjR5b57DoZ+OA+84iTz95H1uvDYTlcXHNjd6R5U4I7Mezeblm8jX2uw7VwrzlhRMBdsXfo2EJELebws5GpkUPB18jrYR/VzzXTc6KvjAwE18Vf4w9mqzxT1G1UK8COlDQY/dH2T2DlvJ9IYFK7si/vMbfkAknAo9E7sRjYwt9h4RiruXnkw0+NV1YeVqatNoypLZzWgYY5lXqNcNl9mRb7YfGmCbCN5GiSrELA8sGOUhuHV2hAnf26Z6dpeehQHVlH5csGYAPPrPyvmDbVSBk34NKBY3Pf4Q1/zN1mAD3SLQpArHDox6lqfsikJrqd4KRU+Ep8SXhTiLTCnBhUTFvPNkRorK2QOiWMkudds5iW7ko4+4VmEAYxq2NRxsw1jUTdN2AKdfxz5Au+y3J/P+taL4lD7AjZymMpzEKJDOzAeF2J3W7g8a/L6lBkQeNPBv3BtdkN7obKt0JnvzOuEBwWKgAQlEzeQdlSgMJ9vKDCUZpy8dPUELhdXpfv6dB0k0mPZ4ViIQs+PkXFTjQ6PCBwHmt1tG73+IpMZgCoO0DbGNBQAejIsKi+VxuQr5BJL/hVxY/vW7SI1rJf7IcJNSkBswxsTsXOWVWm2wtQV0tllR76dPWJx6HCNca+F1PXcrGOJej5EySSENRwTO5DPggcqZA+MeTTOJIflTTQIIYTiANHDwJDFDLDZe+KTAETvUk4q+zOyOTdW9zHVqa4UdeFe50jFULDemwNJGz26ylKQ6EwFl7/s2NuMVGevEQN195xtLAolg2DzztGA19gHMxRr6O6QX1d4jCuBXbAzI2CbFNE5N1KGm2M4dqbwolIds79XyABBqy+HhvKHTLrgsVIATL5OejmTEDl8nS47bRr10e7rgfY6lKm0wINUk3fCrjPeU6fEk4HZNXFugb+2egFo3+Va/MlE5Zl7cdjUveJS6P5JKPJUeAJQL9ritlm4+d9+7IydlYkMRaVUctQsyg/mtr2dpNfYwdQ/YB8g5iKyxW9R3aF9EBHKCQmQhcryjLjJ84Q/6po2ktIyCD1T4NLFRVBjFHEMkPdLp0go0/yBzgzUUr517zZKrUF3rckWHX/HYr9QbPsD9g6I6jDpZh/gZ3QIDcgxG4JDh0S7KbEmTp5utQ+sqM2rW4KFD5ojbOA1LSbc9D9xCjtfeNdDScTgzngw9q2ktAOsM3AOPnxTSg18dJxcST9nd7obnUGIC18q+kFXfSXQRR12w2zt40lyn0GC01XikfnI5Jut1FK1pK8BBecAWKLejUb0zrbZraL88dtzwinAdL9YiaNAVjk7+QmOMA2ZD5s/vt2vs/bYUVL4d0fjSCm10pdNFYC0e0zFmMpiubbh2/26rZp48lMCjTILI2uvdunLSv98oTvGU4nNw5Lg5nmpR+Bgq+1duci1bvAsjLiYMcYCv7QlswggIKAoICAQDqLmjLbdCgn+22n5GgF5/rkr/unSPxyqoa9iDZOJBu7rcx6QfvpltD2GqAwITm9N9ENcRyJYFXbjRZpZUOGgWmCF9d0RmMXe1j7hpv9ieFVyE0oDJh5d/T5fThNGXJUHek5TMbplE0pIRUrVai+RRPfPDWM+qWGLO7CDZ6/pCcMYZdUSUnMzIb7FpWFkvHj5ZM21ehe4ICUxQuc4Bd0VsIrDpUkKHSbxy175OLiar7IyG92kj533iGWYXV6gt5MIr86z24VNLA7W3OLufA3RS9H/Y+MDzsrxaeDaJyYfFNisguAh9EyUBc1sM5UxzQF2NBZ5JUxSb43JDZfW1/EEW5bey0fSRZpHvEAI92xBudwXX5wrT2ProLJM9F2TuIGwkRDmDA4E7g7sWGRKYve4WVYj3bFcnfH5nDckKns7y26uLtBwtjiX5FqY3xek8jrbTS2taGhddnH4y13Sg5XegIquDYEM6C1Y9hmMLNeZ97IZfIRUQziMci0Ejpg7WevheV0x32Ca2mZ5atnwZZb3mBXz0a4u6HYcLmdgMvb0bnFsPsRNT/QfZv1DuLH1EGL1a4QGQUr0MRjJDANFoZ0zL08tCpZnZzdUy5426e4np291pr3yZb1t60VW+jfQ58nx2ntS5doJm1HGLKaeX7YdPkHCfLibQuqAji11dhDIjNswIDAQAB", + "MIIZ2zCCCragAwIBAgIUWy7HkwtG4fQHtJ+Q0CkCv9kfOhUwDQYLYIZIAYb6a1AJAQYwRzENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJjAkBgNVBAMMHWlkLU1MRFNBNjUtUlNBNDA5Ni1QU1MtU0hBNTEyMB4XDTI1MDcyMTIzMzAwNVoXDTM1MDcyMjIzMzAwNVowRzENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJjAkBgNVBAMMHWlkLU1MRFNBNjUtUlNBNDA5Ni1QU1MtU0hBNTEyMIIJwjANBgtghkgBhvprUAkBBgOCCa8ANUOhxJG0QB+/5ubHa5zeI9+RBDbfHXWCreA7dySYXwKrUbjgpjpY6Yl70Q6MqortOYuDd3UuRryTo/BBCVcUIE1+z6maze0RiE0kLtJmdx6hLpTRSGS3Ju1j/svuvnSYGLiYD1hxDro5wkV7SFp2KtMzSQPl3ft6BYvwEhbnDPHi1hqMSTSmGtdHogirldUDwzCM1B+HYHC+uZApkM75+et1TD63cG53368GiJe12EUilNFSLKffX6BHNDP7aut8Pt1MCshY1V9B2sC+rnJF+3kzfGDJNV6KTLTddHjOFgE5XpdI6HH62EZvuEWWrVZmMXzWJgpbNmTjHhOVLpEvW6AJBwSrnCN6dYZogcqJtoZnt9OcmjSMb12Nc175RxlbFp6G0c6qXWZUlaAyG2tTd4jSwCF7LzFXgQEodD/5dZwFtDyHXOVee8C0NXAXWUjJ22ofGFtcvVlj2QPiLEiMuQbEuzude9atpel1dbLXqydYFMft8o/8NCpkxORLicfFvqdeB20H7bfIwOdiAlfSZ7h3hM3tdrdnpoDnGmqpDMLofoDI2DHSuU65XSHdsrSoLzrWq4Hwfgg5L4fCxHqiueevgQupI7Yu8oYrXk17jXazlHD0h+8Zamedyt8L8tZDxDmYqKiY1AMJuByc1vrEenA8iesViwD5Tlrjw1/EppLQAij9v8KxR1x40Juyaxj3ScH6To+C/VzUfBH6OrxNUY9AD+cmCxXA0NSgKDOkYAs48ILF3jF8zieZvFg+5eWxLdDFQ0BD3bB7X3cZh/DeqmB9hc4Gmd9DFEn2Lj4WF01n6JYtvmjh7bMhTL5ge3W+BnZdqz2YqGVfGGfWvDXYcvWmTbtBeLjX8Badx+E3qGrhXv/jxs3RrwjxTl2ZFxaETb13x35wTBelxofcQVvPBerklv/4ypOrWGUVjMBmJWnjiJeOAap9EEMMRsGBzr1B1CezoNWy2VJ4eavqdC26Rj614VJqrq+5LAkh1nCvhZIZ4BIgZHK20T7jiZsUzxg8lwhB6ESaI+SPHlwsLjKPqtXTBw5g2LynWiB/Iao+MjHJRFgDI8AfgVslR4GLvuRQCiH340Zk18E7rnFVF9I3JMBhzXEbaWDTt+KeZGSd6AfEPvPsy8x5qmUWkSdpsy2f3rqrxqEG0+x3sUiLqsrDOMBNjR5b57DoZ+OA+84iTz95H1uvDYTlcXHNjd6R5U4I7Mezeblm8jX2uw7VwrzlhRMBdsXfo2EJELebws5GpkUPB18jrYR/VzzXTc6KvjAwE18Vf4w9mqzxT1G1UK8COlDQY/dH2T2DlvJ9IYFK7si/vMbfkAknAo9E7sRjYwt9h4RiruXnkw0+NV1YeVqatNoypLZzWgYY5lXqNcNl9mRb7YfGmCbCN5GiSrELA8sGOUhuHV2hAnf26Z6dpeehQHVlH5csGYAPPrPyvmDbVSBk34NKBY3Pf4Q1/zN1mAD3SLQpArHDox6lqfsikJrqd4KRU+Ep8SXhTiLTCnBhUTFvPNkRorK2QOiWMkudds5iW7ko4+4VmEAYxq2NRxsw1jUTdN2AKdfxz5Au+y3J/P+taL4lD7AjZymMpzEKJDOzAeF2J3W7g8a/L6lBkQeNPBv3BtdkN7obKt0JnvzOuEBwWKgAQlEzeQdlSgMJ9vKDCUZpy8dPUELhdXpfv6dB0k0mPZ4ViIQs+PkXFTjQ6PCBwHmt1tG73+IpMZgCoO0DbGNBQAejIsKi+VxuQr5BJL/hVxY/vW7SI1rJf7IcJNSkBswxsTsXOWVWm2wtQV0tllR76dPWJx6HCNca+F1PXcrGOJej5EySSENRwTO5DPggcqZA+MeTTOJIflTTQIIYTiANHDwJDFDLDZe+KTAETvUk4q+zOyOTdW9zHVqa4UdeFe50jFULDemwNJGz26ylKQ6EwFl7/s2NuMVGevEQN195xtLAolg2DzztGA19gHMxRr6O6QX1d4jCuBXbAzI2CbFNE5N1KGm2M4dqbwolIds79XyABBqy+HhvKHTLrgsVIATL5OejmTEDl8nS47bRr10e7rgfY6lKm0wINUk3fCrjPeU6fEk4HZNXFugb+2egFo3+Va/MlE5Zl7cdjUveJS6P5JKPJUeAJQL9ritlm4+d9+7IydlYkMRaVUctQsyg/mtr2dpNfYwdQ/YB8g5iKyxW9R3aF9EBHKCQmQhcryjLjJ84Q/6po2ktIyCD1T4NLFRVBjFHEMkPdLp0go0/yBzgzUUr517zZKrUF3rckWHX/HYr9QbPsD9g6I6jDpZh/gZ3QIDcgxG4JDh0S7KbEmTp5utQ+sqM2rW4KFD5ojbOA1LSbc9D9xCjtfeNdDScTgzngw9q2ktAOsM3AOPnxTSg18dJxcST9nd7obnUGIC18q+kFXfSXQRR12w2zt40lyn0GC01XikfnI5Jut1FK1pK8BBecAWKLejUb0zrbZraL88dtzwinAdL9YiaNAVjk7+QmOMA2ZD5s/vt2vs/bYUVL4d0fjSCm10pdNFYC0e0zFmMpiubbh2/26rZp48lMCjTILI2uvdunLSv98oTvGU4nNw5Lg5nmpR+Bgq+1duci1bvAsjLiYMcYCv7QlswggIKAoICAQDqLmjLbdCgn+22n5GgF5/rkr/unSPxyqoa9iDZOJBu7rcx6QfvpltD2GqAwITm9N9ENcRyJYFXbjRZpZUOGgWmCF9d0RmMXe1j7hpv9ieFVyE0oDJh5d/T5fThNGXJUHek5TMbplE0pIRUrVai+RRPfPDWM+qWGLO7CDZ6/pCcMYZdUSUnMzIb7FpWFkvHj5ZM21ehe4ICUxQuc4Bd0VsIrDpUkKHSbxy175OLiar7IyG92kj533iGWYXV6gt5MIr86z24VNLA7W3OLufA3RS9H/Y+MDzsrxaeDaJyYfFNisguAh9EyUBc1sM5UxzQF2NBZ5JUxSb43JDZfW1/EEW5bey0fSRZpHvEAI92xBudwXX5wrT2ProLJM9F2TuIGwkRDmDA4E7g7sWGRKYve4WVYj3bFcnfH5nDckKns7y26uLtBwtjiX5FqY3xek8jrbTS2taGhddnH4y13Sg5XegIquDYEM6C1Y9hmMLNeZ97IZfIRUQziMci0Ejpg7WevheV0x32Ca2mZ5atnwZZb3mBXz0a4u6HYcLmdgMvb0bnFsPsRNT/QfZv1DuLH1EGL1a4QGQUr0MRjJDANFoZ0zL08tCpZnZzdUy5426e4np291pr3yZb1t60VW+jfQ58nx2ntS5doJm1HGLKaeX7YdPkHCfLibQuqAji11dhDIjNswIDAQABoxIwEDAOBgNVHQ8BAf8EBAMCB4AwDQYLYIZIAYb6a1AJAQYDgg8OAJMwUIenRNabP18/UQG4QDrgfTE1LYx2PVX1d+5b4r6+itGoxSsqITmKE8kfyT3HCqjETAMXXf3q7AoBWCqgRZu7UITikC3beZQEbNDgwn0UBGmqMKycofANanU1FXcZm4WyrjGidtHV9aNsZaWQ4cNNVgyDualE8oMW/G4WLtIiaCTR0Jx7LcrHGeLvk7NB3ESMSK6jIeAyq6pQylYvvpAO2SbPpOgNIQyxkfsUVIHZ79sjx0YMdsCWZXV09sFksbWT6K/0L8pxmCkcP5344gSlzG+GX1NVRWpiK+Kv75C6GV6JERUpRumP7D+14Ap6PmwAa3rb4Y0VcNIRub6z0I0H2ersTscNzJCd/a7WhGWJGtE5wE6kkVzNJe/VzEBEL+HjzOBYxpUEhuSf6Tuk4I8rwL3KthYXSCo9kNTRwTt6ZXVJWXPHxozDPHlEdLMpx8XvFeEtpRPYrUBNd1RvfsrQmDrzD85C7Lnp3yD0dOS1muVSeEk2EfgfyrJw71PukxTGOC5k9ineFL4eihCuLfjLsgy7XN1jDNyb8AEGC9iFxaYm9r01vCq5PwO36Zp1TBSa0u8ddfMyAvGyFcHr6jezMbNW/N7nBpzr9SPIywAuUIW22dsdkv/1qpl1e4atmkyWtSOwoIp8AEHEgabOwKv/nN9ovqWjLC9JHKqzY89JU17Xrh8inAiKaNkz1RKUHnIns8zB4a37pq17EuGY8Z0W9uKTmAr9NY90eb7m2vEGl2i5gg9IySQxENAAYpa9HKlsWsVS86EHMplvUB6Q9Tsa1MPSXp9XUFg5f9XVnXzVTIh6TQdrb2sGMNT/w2udtQIz4kV3anAGY0j90VbwKd4ALnAzoEHF/eAAY/+FORLkeLNLmYl5xSNMdgE8lnXn14//ejQV6gzefQa99uE3vfdG5/v+u7aPLHsNjT/bj4i5TW6WbvwQNEkQlh/vni2LiW9IVUdvVR/ETocttukM5V47wXnecZio5vAtJC4ydS3Dstw1RzVpy2wYIlpNGzDaKk1NvXsxdKmPwdmZyisLNftwF9uTc8A/yE3M1O3mt4/vO0Uty2S/o98dnRPLRF+sZ5c6VEsImIi0st56G6W3b1WspQS2Ob7h3wHW3PLTASLJQRZNTlkmXGujapIfJUQxnx59T6y3tOYwLcc0wi3SZPJ2LhsMVezDJsoo5RsRmTXBc2TxitsXzfGuCdxi/s6RdmS7PNuCEtjxmH0Dxv1/xsYeUyx0zYgWevNQRszBfPNaRLyD2LxqLAMBky3eAmgpCLVRvKipECUM95CwYNN188xJueYEpfVduGI78znbY/IfUEFCjU5KwUbOyxMtfnl2eMLlEjDrZby+30zvMm8JHa53sPaL/2du4Cq1g21J12OoZebssK/2sPF2tVZqQqTTDtMrmvueVsZyCCiWMRyF8kVmbUwSqjRgtITll9+lQbwlYYnQc9/Yo+9XhMotsg/Ufm3oWQseSva8VFTGXpCiz3YZjBCJcUtO/jHIeKKrFMmlf6VG5KAy3cmeARl8r5oyhYrMCl8BqjMCGcmMmR2CMbo44lbkPmNXPjnov0jUQUC+AUrfjn55kBQCKpK2c/AyepNPqtcBeJ/jR4CcvqvYfKOmPMRHtFwNWpFkZEukUtRpZ7xoVwddhYW37aSs5KIbC5PE+QedyOBtb2H3rxJP+3xsmK3/+crN8MJTF941wcWHcO78Qy+jlMmnD3X06qF3F61/oHbkWPvNN1WX77fYoPB+XVEcj8WTCwZyK2aHl1ekSa3hPovqigZ/xeAFYOkVsf/X25Jk9AcUOh10/JRpNKjsRZTv1xpiWaU4BcmIt5RxxzYd0KfD5tQvs4Of8Q40RdgJ+IUMUYllbWaxKsHbE2HaR3fRY2uUdet++yiMvTFei8zpvxUHtP1OcZiVf/FjfqQMkBg7NqXjr63RXG3S+VxqEmb4rAqmde5jecqfKC3zGnY1VJ6y3ys/vAoQbgral5kfTpn2wNLeNMK3V0FJdSC/QBtrkPXe9t6/VbUG/Yppf+gBHDjWm6gn6p5SIBNvIoQqQxt1ZbWDdhKz+3RjCJ9W7082eEiL/RL94Ubvhzd8R389r3JjarAmQDq+tnltLhNqw/PB2wpkZM6ZRvxnOj1q7OMj3WnyhuCMNcXITGYPlpT5sKJ3tTpN9S43kpla5TbGt+HEzS/D3BpB4E3qn49Raja3FAVFqD4/JupjjMBVVDjhyV5P7IxW8E5vcfcBU4YDIlAOlEeo7Y1MG+iMa35ZZJzVRqUouqfVIs56WJIII6a8IbziArfIRtPL+xs+siez3gtFfu1OO78Y5witDCCymFsM+zzynVe0pVrfK66jm27DMYgS0FVc9FGs9n+5KUIa79TVVDF4/apHh9VjM8OSmKm95QTTwY86SKiSFtojtzGmF5pPWhu1I/TISD9GKqYx7aO+X2g1eGtCRBP/gg+UMVNJQ2D1FgQ15WyalNAg6aon2rpe4tj0w35skI/qfFqol3yDa9ozaXtqaNOwfuPwUvIhK9thtDY5T282QbUuITYHm+Bp8PSFUgE40TxyoJwADLgWKNuYNuXA7pZGwWZBpoPL9JZ96zN7zi+0zlslMuGoV7o5HYPZDIk+/+E453e1mTarFDofCdC/KB9rWNuWASg1LCmRMxXuonbd5X26yqQ5cwYn7c/xNgzq2Y6eyP17DLhO2Xcf+L2GIEgL93MamiNloZzUcx+kZ1DNWlZqFAZ39afXkQFx8v1LqGQGtUyMmIvV96TqQF230MZf9dDJGah3H6BSIkrAR0CyJnWydhlc4N9nQH5W0vGC6zgvbehFCnvIdLRMMMdY7JhHv5C27ZeCj3ZnZs4JTKHlf2qlBEGx0/MjwTd1sHp3PsUy06GhL3zRNi1bv+mj7B46fnZ3iYOBCYcsWhgfC19EzwIbeF9syuB796LpkMq3rnK2aZkU1EXIWJQ8meoAH9IACPR7DdYZNH4QPhdfDrRUupIOZ26Y7i2Q7SiDheFf18JZenZzBxGb/rxqwXdLv/gyMeP9W00GAZrq+w0HVU8iJhjmwK+gY44+/qChu4eDh5d5wwMBwceczlv1IBvo8Hic6mZAPVH4D5nSGv9yom0strIQ1iGuChy1bm7f+Ad+9eslfsPK8L3X+TGzGi51k3i2yto5uns+JzSMvw+LRECzDHXvMoCkQShoYz3bW5yWO01BM9ICAPpzKKK310RVt4vgUytOYQokn2qxopAgLUsqr5kZJtwR9zyLGHh3TvQbotOWqBwPwgmzaYCg8uJouRs23IrYzuYKmRvtfxwyuopvUIKgWgLCNUvbyx94DXo5qlKnR7lrYtB8ExaO5hcutSy8f0mfHn3SijdBLxUsHjiAx55Bsvbps9iTbhb2ZqooQ76AuvD5BfFXYubfvBdT9O5gSjpPUrF37InSapYh5PyuBSfDVG2chd47UgQWUe1PS5yX0C1LjPZPIdwCAYKuwVjslXUwvsTEEsoNyyKGEs45nu/+lkRwVgO0v3z6T2w1L4p5szwec3gQ910b4lz+dbqBWuMLKfM/gTo+eFMA00dwW26eMIZZV4oOcLm6dL00nBtvf99UVkfOYO/fAmHRlbev2oKn+Oh+rcfWKLrA5Qlpkul89tVJJVtPr0q6pq8K5gCXvXkqtmz5A40807GfOXCNDu3EFpmm863lPor/cdTuTwGsD5LhkdLQrNMgY4P4/jk4tbXgRAeYHxxVm6So5fmiS88Tf2xMfh9/zuCiqKf4gccJL3e0dBuMib8yXd+NKlmZJfL4kRPKO9yzJn5AHLSVlMkERFDJOAxmbg+NBs4l3xnb4JLffVcy5FMv6ftI/WWgYdvFLTWNCiF3HNcyBo59T/veK9uwOifa9GDwfvAQwUxMAbwKCPmTm7qfAyK1WAl3lq0R1OmHdF69jCo19abLqKCZL9Cu0CzWovA54w0qTv0yyuXJ/+Tw1L4jzCxm7qbQE+2cjN5ektTMRMWIpLS6R1c4x+p0315RFG391F6YCxypsF2VxOjLKjT8YEf7/6wbVq0ryHYF5nyYFeooIxf0eJ+STowi81YUL3hY6cAmsA8Rh5yPeCVzk66vmBOy6LnDm2U5joSwvxEhfVJL8oKMDlyy9bNd1eYj/HvBvnEqsmLiQ/5VvfdRgvUNgMt7keFyDzvPvCBUAwi8UI0sTQEgXxc66x2J14W17Q+YLjAiR+UXb+rqcTu8RkU+lLQdXfbRs/5yiAf9g2NqIHAMGaLMN4P2GC915d5ouy5fEmOiH8jFIvqQEz80oEtTYgNM7J5fKWva6nN31MYab0usD+9zrjuJ9gU26H6yYHpYRZduSTJwMNl8V8k9RYudisKlQs7N/JFfWckeLDtFNLOmIgsc0N0FJThLbICOXKGwzhxSYGYrRlnC4TREXYKeurzl50BVhYyxzc/jAAAAAAAAAAAAAAAAAAAAAAAABwsPFB0ll7Pb4HA44VtZPdIvAU06H6BZFpZSAnc8XnF8GFSQMEyVF75hTU8QCgU2h8PEq9bdQt5XmoHZH8LwA6ERPMGq/EoIvY8A5dLOj9BUsCBvVOs8GNTAtg4vVYhp6cIdzFIcYKUdwvh5TlzWdeglIEDEoE+6I4weJxMh8Qo4CV5XMYXYcDr0w1tAz7RRgrsw8e/nhZ5UaoK4Tmrwl0lRsox5MQ0S4IM+Kv1BNAqy7tKN5QpafOYTLOnqKZ3mSbI0oYe/xpcR8YqRSfj/m3wjT7gOehWG/Y4nCdWMNDjFQZjN9g3GM1c5+gcknaZAhhEklsNm03bg4mBCbg80AeD1MZDM1LsJOXvKcgcuOiL/0wjOiaxLMJa8mJ2Scc6ULy8LhDV0NoSVJuFlfdKm6M8yNZ+kUHp52VRlylONrtbbjIa63TaJBnQVTLL/z5RDtlF2hZc0z+sUr+IuvqtrhEtQBPSSDYTm4wUXeirIET9qcU388dTNCCuLINLMAuSHneEW635klrwxO2kIqa4vxhT7vEKdoNOr8s669CoeSc1nFDsmd6g+ij5A66n7lE6jwruaE4rQn3IUWga9P607KAvlL7W5NGIiZfOCXbFHJTejZpzkjRusuAny99Cg0NTTOCQXfXWav7BPww5ExN39kvCQ4eWp/cWJjWRERuWLuI3EQXdWvoQ=", + "vGyKLAFHEVAG0FkL6u2y5w/NguzP1R8HNloWgFvf61QwggkoAgEAAoICAQDqLmjLbdCgn+22n5GgF5/rkr/unSPxyqoa9iDZOJBu7rcx6QfvpltD2GqAwITm9N9ENcRyJYFXbjRZpZUOGgWmCF9d0RmMXe1j7hpv9ieFVyE0oDJh5d/T5fThNGXJUHek5TMbplE0pIRUrVai+RRPfPDWM+qWGLO7CDZ6/pCcMYZdUSUnMzIb7FpWFkvHj5ZM21ehe4ICUxQuc4Bd0VsIrDpUkKHSbxy175OLiar7IyG92kj533iGWYXV6gt5MIr86z24VNLA7W3OLufA3RS9H/Y+MDzsrxaeDaJyYfFNisguAh9EyUBc1sM5UxzQF2NBZ5JUxSb43JDZfW1/EEW5bey0fSRZpHvEAI92xBudwXX5wrT2ProLJM9F2TuIGwkRDmDA4E7g7sWGRKYve4WVYj3bFcnfH5nDckKns7y26uLtBwtjiX5FqY3xek8jrbTS2taGhddnH4y13Sg5XegIquDYEM6C1Y9hmMLNeZ97IZfIRUQziMci0Ejpg7WevheV0x32Ca2mZ5atnwZZb3mBXz0a4u6HYcLmdgMvb0bnFsPsRNT/QfZv1DuLH1EGL1a4QGQUr0MRjJDANFoZ0zL08tCpZnZzdUy5426e4np291pr3yZb1t60VW+jfQ58nx2ntS5doJm1HGLKaeX7YdPkHCfLibQuqAji11dhDIjNswIDAQABAoICAF3NvD1sXgrRNQuXjGIXxH+81zPR7yF94DiPiaXpQfWlmm0cHokw1lLtX+/17eaDhOFSNj/Q5Sfr5X1ZVcUByGxy4xx10ymGQD5slFtvuvHu7kahury7MzayYK5K6lDC8kHza07yhomzMqymiFMcubWDYwcyYY/BElFjX0tSKAPg1KURiXPTzokf2imsoassyXQ80jPFgNTEiYt3yZ4K68+kCXNxQdjEmDgKYMwel4YkUvI0+1FX4fPS7Ui8CN+BAdOAuUbad1c/Y+IYqM144UNGh8DuWqEmG0WxSXZO5DT+1+OSBwtrH+RwRF/0elCiZag/v/5DwLIjy8PKua8RihOR9vavi+5x5cuWPJleb/+Cu5s0rR4Eq3Rs9V4ras8LyqQphVmBE8T5JtPpdQA5QGNtHOVf6OexIpt+LbVtUhRIcGjrJu5iTyTPOZY3OOz35XCa109MC2tMcX5ghcCLMxj3wIZNAAwH3q0BS/U7cKshRwKkQN58RUDe8S7yssxrmkIWRJlY/n37ie6OcyOlSqjgyFo9nGDJIJhgX9HTKlKVuki6rnzh4npskQ6/VlVPWvPLZVKGnsEXKjefF6p7sjqv/6zOG5HgEs6lnI9OuofslOY5o4jOebiba8Mxx67ZGBKo0O1ElvCVUnYrAh41b05XX0s7MEyp2NsmBeCg5ElZAoIBAQD+ezZHaSjrMSEwFoMWwM+u32ze2XMmDK/Ix+6dJ7PIvnrUv8TnMTD/7duGyjjgnG3UzN18RNYZgpzjEOknL6qZC24rgXoRjYyTQkh9zSCRJ9HAZ0xrF0LLEond10DRTDtD4nHwIsFKKdwkD90wQxLedOTQxEfH0MP90EW8T9EtK0WwddSsIpNvUCh3KpX9qxr3nwPmb2MIVENEwaFvOfracr5vJu0+4vOeBGx9Auu09KYzzZX/U2z0E9cPIb/MPZEm9xuJOKshTifw3Os7KnUvX6GAKs0FEGZYWDqCylTCEq6w5bXRv+RnaVDB7H29jtinEL4Fj3boC3DQHQBR8i/bAoIBAQDrlC8D5fPAjycHfY2+8YPZZvoHnABe0oKpAbezqg58N62w+Ldf5wNdj8zeyEDLZo5sqs8u0n40yLwmSEAhh46M3OFDOzgjljcU+aXZHzqsnYncLz5wyy15Qh2BhrjoyU1/tbaUde93d3nDgPrQjSzrBbY6eeqVCa/4VQlz2zQ7+SUDNw6LITViOtilp7KR18eVDc00Ud7CoZI6umH5ydKrtCaVpHqTwqn4xi0E2zI9zV0NSzJp9ss6cXbTnTMM7LJ8hSOwQKUVZ8pGXVNU/TyjH9Wuyf6pwn6Po2Q5Ie9xCsyyHnVi0+7n4OuTxpgKEt+xv/zNPignJkV/agTW9Q0JAoIBAH3fM9neif7LLj8641w9wnwcxxzzMaGAZPJK8huJp8ODc/4HXL19916fqBXjsH5o4WqAao0s/zlfAXrOwoQ/b4KDxNqAEIDeIsoz3udaruEdcQJaFdJijwcjBE5WShk8O5Q4TWMZzcGBMwIjVqSoiIzABO2+KEMNX+QLQHMEh9JvtOizX55E++fzHhDTX505JP2WCbfRIIreIue/XrpFU275kngoKPESEK34QjETYMMAv7Sf27GO8jVIGvfBGb1MNp+vWk9lWEABCIB6xV9egNgN1TQv93ipw/WurkJDEelslDurY2N8Jt1/mhJRh2BbZ447GcJmU8oy3noR3jaqNEECggEBAMXAwK6/C5zrDlJFXQWaa5nFzcExfUYb5D7HCFQzPrGbc5yJTDWfEL4rhkjFRU75KjmiMQUXAYaBsx9Xqy36QvmQOTBct8V3xYk//66BfpmELUO+DOZWSDfv/iDK3NHcmcfI3BlH3tskWfx5exIyUDCBvPTdfsPZO/R0PdkZe4GUpTNLtlOobs2kpFR6r3Wp8wn2afmveBVd2AigiLpMZyJnubQIPDVpRZFlmkjnUAd9Ks2MACffWb4XnS4KWd5Rm4rXoJvFyE5tr+jdUqSXZ51vjcqKGdKbR+5/tBQZnowACtDCrLtnOLdBob+NB/f82/a0ORx5Pu+OOuy4LJPdZTECggEAIfeJZ8qwtUV/TBFnhKLOeyxs9Z/MSm1WORs8Gx3L0Z2bEYE2y0MAO536s7vD0m/CLUO0L1xFESH86VoOmHCtapUNab6hsJJV2dJkvflJRBGZDxhdMIfSJ5D7ZkmRJhrkkSfLA60DcBoTuZEcGjl8A1+LH2K2PJnaUrpM6deu/HlPWUC7TZeLsCVKgBZV0d6z59780UiBOjrBLsa+t+qBrJ8Kmoo842beamZIdO60E8Si5HePPMIx7aGIm79I/Dv5YmPsIWmlUV1GzyPRZjwu9fmmnWkIC23HSGSSArDR++E1MrnOwW52qhxzLvrI8V4DSg5UwAqHZlZxcOT5d2QPUA==", + "MIIJYgIBADANBgtghkgBhvprUAkBBgSCCUy8bIosAUcRUAbQWQvq7bLnD82C7M/VHwc2WhaAW9/rVDCCCSgCAQACggIBAOouaMtt0KCf7bafkaAXn+uSv+6dI/HKqhr2INk4kG7utzHpB++mW0PYaoDAhOb030Q1xHIlgVduNFmllQ4aBaYIX13RGYxd7WPuGm/2J4VXITSgMmHl39Pl9OE0ZclQd6TlMxumUTSkhFStVqL5FE988NYz6pYYs7sINnr+kJwxhl1RJSczMhvsWlYWS8ePlkzbV6F7ggJTFC5zgF3RWwisOlSQodJvHLXvk4uJqvsjIb3aSPnfeIZZhdXqC3kwivzrPbhU0sDtbc4u58DdFL0f9j4wPOyvFp4NonJh8U2KyC4CH0TJQFzWwzlTHNAXY0FnklTFJvjckNl9bX8QRblt7LR9JFmke8QAj3bEG53BdfnCtPY+ugskz0XZO4gbCREOYMDgTuDuxYZEpi97hZViPdsVyd8fmcNyQqezvLbq4u0HC2OJfkWpjfF6TyOttNLa1oaF12cfjLXdKDld6Aiq4NgQzoLVj2GYws15n3shl8hFRDOIxyLQSOmDtZ6+F5XTHfYJraZnlq2fBllveYFfPRri7odhwuZ2Ay9vRucWw+xE1P9B9m/UO4sfUQYvVrhAZBSvQxGMkMA0WhnTMvTy0KlmdnN1TLnjbp7ienb3WmvfJlvW3rRVb6N9DnyfHae1Ll2gmbUcYspp5fth0+QcJ8uJtC6oCOLXV2EMiM2zAgMBAAECggIAXc28PWxeCtE1C5eMYhfEf7zXM9HvIX3gOI+JpelB9aWabRweiTDWUu1f7/Xt5oOE4VI2P9DlJ+vlfVlVxQHIbHLjHHXTKYZAPmyUW2+68e7uRqG6vLszNrJgrkrqUMLyQfNrTvKGibMyrKaIUxy5tYNjBzJhj8ESUWNfS1IoA+DUpRGJc9POiR/aKayhqyzJdDzSM8WA1MSJi3fJngrrz6QJc3FB2MSYOApgzB6XhiRS8jT7UVfh89LtSLwI34EB04C5Rtp3Vz9j4hiozXjhQ0aHwO5aoSYbRbFJdk7kNP7X45IHC2sf5HBEX/R6UKJlqD+//kPAsiPLw8q5rxGKE5H29q+L7nHly5Y8mV5v/4K7mzStHgSrdGz1XitqzwvKpCmFWYETxPkm0+l1ADlAY20c5V/o57Eim34ttW1SFEhwaOsm7mJPJM85ljc47PflcJrXT0wLa0xxfmCFwIszGPfAhk0ADAferQFL9TtwqyFHAqRA3nxFQN7xLvKyzGuaQhZEmVj+ffuJ7o5zI6VKqODIWj2cYMkgmGBf0dMqUpW6SLqufOHiemyRDr9WVU9a88tlUoaewRcqN58XqnuyOq//rM4bkeASzqWcj066h+yU5jmjiM55uJtrwzHHrtkYEqjQ7USW8JVSdisCHjVvTldfSzswTKnY2yYF4KDkSVkCggEBAP57NkdpKOsxITAWgxbAz67fbN7ZcyYMr8jH7p0ns8i+etS/xOcxMP/t24bKOOCcbdTM3XxE1hmCnOMQ6ScvqpkLbiuBehGNjJNCSH3NIJEn0cBnTGsXQssSid3XQNFMO0PicfAiwUop3CQP3TBDEt505NDER8fQw/3QRbxP0S0rRbB11Kwik29QKHcqlf2rGvefA+ZvYwhUQ0TBoW85+tpyvm8m7T7i854EbH0C67T0pjPNlf9TbPQT1w8hv8w9kSb3G4k4qyFOJ/Dc6zsqdS9foYAqzQUQZlhYOoLKVMISrrDltdG/5GdpUMHsfb2O2KcQvgWPdugLcNAdAFHyL9sCggEBAOuULwPl88CPJwd9jb7xg9lm+gecAF7SgqkBt7OqDnw3rbD4t1/nA12PzN7IQMtmjmyqzy7SfjTIvCZIQCGHjozc4UM7OCOWNxT5pdkfOqydidwvPnDLLXlCHYGGuOjJTX+1tpR173d3ecOA+tCNLOsFtjp56pUJr/hVCXPbNDv5JQM3DoshNWI62KWnspHXx5UNzTRR3sKhkjq6YfnJ0qu0JpWkepPCqfjGLQTbMj3NXQ1LMmn2yzpxdtOdMwzssnyFI7BApRVnykZdU1T9PKMf1a7J/qnCfo+jZDkh73EKzLIedWLT7ufg65PGmAoS37G//M0+KCcmRX9qBNb1DQkCggEAfd8z2d6J/ssuPzrjXD3CfBzHHPMxoYBk8kryG4mnw4Nz/gdcvX33Xp+oFeOwfmjhaoBqjSz/OV8Bes7ChD9vgoPE2oAQgN4iyjPe51qu4R1xAloV0mKPByMETlZKGTw7lDhNYxnNwYEzAiNWpKiIjMAE7b4oQw1f5AtAcwSH0m+06LNfnkT75/MeENNfnTkk/ZYJt9Egit4i579eukVTbvmSeCgo8RIQrfhCMRNgwwC/tJ/bsY7yNUga98EZvUw2n69aT2VYQAEIgHrFX16A2A3VNC/3eKnD9a6uQkMR6WyUO6tjY3wm3X+aElGHYFtnjjsZwmZTyjLeehHeNqo0QQKCAQEAxcDArr8LnOsOUkVdBZprmcXNwTF9RhvkPscIVDM+sZtznIlMNZ8QviuGSMVFTvkqOaIxBRcBhoGzH1erLfpC+ZA5MFy3xXfFiT//roF+mYQtQ74M5lZIN+/+IMrc0dyZx8jcGUfe2yRZ/Hl7EjJQMIG89N1+w9k79HQ92Rl7gZSlM0u2U6huzaSkVHqvdanzCfZp+a94FV3YCKCIukxnIme5tAg8NWlFkWWaSOdQB30qzYwAJ99ZvhedLgpZ3lGbitegm8XITm2v6N1SpJdnnW+NyooZ0ptH7n+0FBmejAAK0MKsu2c4t0Ghv40H9/zb9rQ5HHk+74467Lgsk91lMQKCAQAh94lnyrC1RX9MEWeEos57LGz1n8xKbVY5GzwbHcvRnZsRgTbLQwA7nfqzu8PSb8ItQ7QvXEURIfzpWg6YcK1qlQ1pvqGwklXZ0mS9+UlEEZkPGF0wh9InkPtmSZEmGuSRJ8sDrQNwGhO5kRwaOXwDX4sfYrY8mdpSukzp1678eU9ZQLtNl4uwJUqAFlXR3rPn3vzRSIE6OsEuxr636oGsnwqaijzjZt5qZkh07rQTxKLkd488wjHtoYibv0j8O/liY+whaaVRXUbPI9FmPC71+aadaQgLbcdIZJICsNH74TUyuc7BbnaqHHMu+sjxXgNKDlTACodmVnFw5Pl3ZA9Q", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "8UeqcfPjQ7RfFO3SuSmFy3kh1zIderl/X2eCDXVsHZkfbBWAJDg7PaF3tVy1K+7rilt2D98bqpNSr0UCrGXns0QPvd0gSSC0VHGUo2GOnZqhwcUh/MaKZSAC7uEchAdXlNxC8OJPAmB8Ide2xJUg5uJkDnW540LyqpDVkmz0Ojj5MOM6XF0iUtj/G5QfS4WjdYo/OeZ+bPV65vPkTSLavmzBFa6HkRgOtORB/RpQVazkIPBb4+Io3+q+9IHGglkQtCN4Ht42sYRR1CM3IKanoJWjjSptUNX66+W8ZUzU5bG/1u6PGItQt+Y2Ual3B37U3g0sx7+aUhVcmp8GkrNXJhtJo9rOt7H7nxyhwOhyhr/dKjr5HfuHSXSdnHFsz7fBMEk0ASIVMXvCy4O4AZz7+MgtNeDYzWWM+gJmYF/EhcZM6kAK5sexTgmKAnNxfvhZb2+D8NjqDjKjCTV3GS//tf7fREyBjBXbskQehlUC1iv8ZT5xA01mDnniIl5j2xTJc9te0VJdWhxTYcYG5VNuuYAddbdLWXhAAGx4xXFCl04wVSR3HRlWXT2MRg9onUGbzuYCcZ8XIDkLjHryNZY9J0fmmdqpEDTKEJY0WKZuqno+IA/um0kOv78l/6oQg5GGyw3U/VPRWTTqkoOadZHGB852luEH2TpYJWWPLpfjfSgwuai8IcdpYQnJimpm3hMTeu76qaUVbUoWGqhHgE1PuQdQovIQkcoxhRBQ8oa7VBQc/qu19Wk8/YgZQQAXK8v1vr9b5rLhURveZNxlKTx4rEYJRgF/M5P6ypLu+Y0xyEPTzxLtuH73nBF9jwiud6+L8k/hJgxpLcyUTpJtqPZmQ3+BY+0tr+tb+QQBeHKVN98BoV94X/neelJUsuGkIBTR3jDxAWsFs/5yZX7VS5KuuhiL/34vjDwpilpCq4nupFGqiVG/5WiUmvPVnen7SJdowl2P/BnVm0yOnxG4KlHUhXTwOCglMnfEoHEPBKDh5F2fDMUjr3DhOOnGab1WK48n3U134L4nmr/ETNy/VHukZBiwp9M1mPxzUYbEpJIgWTYvZgC15pThj3fbRMSVRrRgiv+nHhDh5FIBwfyjwze95WpMAvGxfZn3vzi2aHUAr4DqXLI8WzEyMNC1psXPy0fPX72uSolOOD3CgODEX6FGR+X8a8HaLKaYWHaTzn45980YMmleYmVg/66Kbo5v/imUECN95r7ZsC4P85XhajptIPzsusRXTi+Qof+CmGt8/V2XkKXCaFb9KHdPzTdru5Gq5uci1Q09eltishU61eptiMugnmDnnGvLxg/1/CuhDyWFOBYxjy6aqe7fJq5lu3K8LLDVCC47e43T10XuBt/2HYfC37z2sClUcbKI7UQkTjziDEq9cZeO0srwWR8v7aNM7knMs0kjqLfPbtRMaNVIIHAUfqa8Yb7u5dk64MGZOtpZ98uRVwD2u+1zJPh0sbbE5hT1IrPD/o+KyPI+9XlRgXXvB0riU6Gmj/AqheSyedu0Wf+7n7JI8lwFhs3OcV/JsrxDLJRqY49+ZPB0XRHEELab40r0W046hjv1AbO8h05Wy4uA1JGHJ5eEDazDdGOBP/WkrFyxukOeD4FEC+IrN2VlAS9a40D6rQ9CwlVehlizHcJ2XtDUiQZR2vwULmVBuClL7zrZkTfXW9PisjMPHyy2qbT4c3091a9bUyl5A0dcEpMxRCD5fVUkVA/DEAqEWLcMeP7v6gPrMsy8dzCDkctDZXyoZuC4h21akNn+wT7rwj9ld/mo3vEvkE13uuFtSiR6hSX3gcfjcw9R9tXiOAmcpyaCsjoNWVB/NL3IgfIA4uFviALoJjvi7nhNYuL1PTty/S9BsgKf0AVtT7TRxgGAKOn0M/q147+FIeR+YdgrVO5Hkb3V5HAMhDaE79O4Uod7Jw+sckA3c2l0dQGGvyxBtDaKaEgxn8+/qkt+kxAUgzkK4zn5tD5iOlVrAuzA64gZJ4SEMNfrSBfMo5ikEfa7U03Uk/gBJGCTqcSK6M6AHuW2ErUI+oKXAqYxSIZV5jwI5pnon3k7quJLqhRJHSgI/kwja875tHbrns5zio3cd3cX+MBITWOoNj22YdqJkOUYgZJzFfySr5BafNPwFEaDjZYbnMToUWkHxacrjkrU5jn9ZmotrCc7oy9YXHlwvnqjkT9As8zPbBC11I+Jb0toa70XTSgk2X//FXr+u4xJ34BUMGTQTahkS/IzTr246JXA7ew5a/xkT55f2pZXgIdTnnK44h9kwLBOAwP9WWDEPAITG6vC03P/IDr+7cxYKYvpXh/WrCX4uyqwJXV59XWQXUrgSSqB17sdYDimTvCBh4eqJuGdST0tWe6FFSf1kVKc9DRIYbKKhgAEqEkYH5ApyD3EH/hYbDxKrOX5lg3hFXHbf8rPWWRG7iAEUFZXf0CRNwdblRQdACgNJ7UL2hZ41Lfz2dVFkGWbaQPw0l9kJw3X5E9iAFE7q9e84+3Ngy29JvV4st+2MfyAzjU4iZhefSvznDzpMPWCRXKyuQHnmEY9kDb2aB7sgRKvo9biw7FWLwh/91EsvhRGlwbcSJ529/5Z3HgsfodgdD4KS1hZoll3T00RGmSZbnZuuwKH1AMjIC7aiPF/vSTQHSHQv8x5C1rcoXOPxlox4qhK125v6LNAXi5hXihAfoxZrSiXVdc8IBA3nZ9NCWq0BsXxAOKERPDFU7TocE1AyWJmhVotZg4JhnPBPi45mPnGHgOTCe39NaRLt/GZ1kf05LV8aIckylHO92ongXiKksLD4PeS8JZmD9qg8GHbSAuKxd+LVb6amr7y1t+djptaUPoOgDjbMJZXw8w4vsIlaZNAKRCdTYjHw2XDz8HV8/gPWl+8bxibQ9uBx4WZtbcz47Y2qg5+lJIEbDcELD2c1zFJVXb2ukFdNcYjZphMKOGDGUPf5pY3R8AsUipcax7hZqz25b8fOt8FYk3v5zbWAjxfu6cncPJUHw4W7kTKggQAAjH2y6MYPSrSX7tarB+z6me5XVqwpT1ueAlS+o+Plp1wVQpDRF/71zrWK91RPYgqlQiO+yAxSOyscCs0fPwE44P9KCgD5kbSWLmsgSCrzURpKM84OutaM47jYEuhygdBEMk15zlhrcsAt0esmBygaLc1ESxebiX7eNEdmd0fsGt7HAnHqyTmdvqYdAOWa6AM4Qc/ZzM51XNd8TVaOdCvYJUjbL9QzIdtm7C8oax7L7bFcXG4Yp+AR2Rippcdwj7nWvOxyGxqSB0l+frOfMAWYM4+SgTtamEIZzoS8Rs8eA3/zST2/mJsCHZt3D1GDEDWOzQtsFb/g7/EWfdHio1CRuvkTZ+sMq8Yc/3Cjj/5vf/bYZM6oSzbQc2CTWy8VbwnIBxgCPsgTca0CuZYhsO2PCaTZ2kj9p8yZvHnJyftXCTuNsZQmXn4GRcaCfZmXX1LXAJpMH3TUPVkiKm5lzAFyfYvMyNvHC9PxZwATWPoj2kiMIA5NSbvlbmWxkIFWEATZ/Q3065rcXv5xGaqeoHwcWp0UmcNsw/LDLRQcOdAgErZupyiBL1IrYRc7HnFST8t/mv8PyVUsEXP0yaHCZfMdTLSU0cFOHVvFNkoCekGvrJoqhmfS7tTbgYlLyahR2ffmYJWPpzO2KkC0zNUzn/iCC6u8KVdqQrIi46uJdD7b3YOMDYVEHQ+XrizPUds0c5f+SemHY0U/VYgT41aWo1D5x59LBxzNOyzYboCDb2laCB+mz2RYKSi/ClbgZktl9KG3ktkAUpUxKArgfsR7t7WhyX+8BRX4R/p1kk8bjPQ1OStTOkxhKhggw9ITappo/pHXjNEwOegiRK7IPWZglVD8AButfgZScmgPGJvHgvzb0WRmsntv+UqfXcHHG0z6mjVY45Xwd3ItvHMTZTmavKJNAmK5Ci+PnIclCzOtWANudUwCc3J4z3uI+7mvarYdCm6cEhHqUqqqP05OudPol2GkYqgnb2g99u+0D2Amx8T0rFEDAlKkmHQ+gj4lHHQXzouIR3iQpxVnwejczH47tjX0nZjNtzZA6ryNJnzpJY6PgGoWMXoDIHZg9RUar7csJRKI2GlSr1rldub/QWuRWBUeyOARuaAU7sAsFOj3qII5GCMFG69SQLZMM0sCQTjzQxleA1NkQGp1ohAwCkPvbzjdBlu9tAmMqIRjp9g/AOg3Gl7r4Fvf72egJy+r6mXVCa9RAWs0dC8qHvwZzFUGrMEbG9Y1+Unr02+SYHD51SF2fuTibX5Elj12OiacowuyWA2rmjp3cc3SQ99XJwUoGjLGuTFp82asTe1Qa4xQbyd4WBUuaKvsrMaB4D6qbaEHerKJegOkUbLuU95f9tHh6AzwnYoiRRLTE9SU3yCxQ0WJnGPuOAbIWBijr3AOkRvurzo9f4mMkFwDUFlz9cAAAAAAAAAAAAAAAAAAAAJEBcfIyiZhz+np2sf06HRDKfLyP9DxAy1Sw/4YR/1d9IgMLnAKwFYlwTuOi2+0LWQgEAGn7DXWQwS+EYZncXOfa7Xjq5Tl59i1al+aQmKo1WQozCpTS8POpz3OuXJvU4UnO2m3Lm8PQ1bLb4SVtlk3QR7fQWduUVD3YbpswP04I9c6XG9svVpxmWlqJRMOMTc2rFvxuuBxkDBTqD3jdDNsi/y71Wmw+UXWyGpHLR+98D+3YXyb2GWzhO0wH18Jf80heqEUnn7d4dsPRM6ZgdVSqA6T6BQVTi60qmEsBSD2cneTZOrdq84UoGSpb24RUtGhn2zgK2T11TH1Gyr57W7rhumWyS3fBt5Y6PvwUZ6QVEm31eaV3HqIWQ9O95pTktiOePgUeuJnnMoUDuIOL1dNsNjX7bmnUFv39NybYXAdEuMSI7CexCSRP/HBJBpQ2bIw54hXrcEBD48b5WIGG2k8lwDQUUlYDLSiEIp6C5Pr2P7eqFTwKxnE4Q+6hkQwDEEnpmQHllvIz8Q6Fm8yipP5FNkrCFURpJPbRDxjB5PKjccY2u111lKic/FLdh/IJ/eVBd/I9AhpRx1KdTlTVJqfM84IlHJFmWkT/wN0QdKHvRO8eLouugT0/AkzCpBIVPFmPZO3Ydy8xCpYsVLdYvCTQOx2NbYufNTOnY0B3hWRoCW3fANGw=="), + new("id-MLDSA65-RSA4096-PKCS15-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pkcs15, + "6EezpF35J8fD8+MBDD23cX0LKFHb1q2iiEsu9TPRUfQlCYGq0/s18KlUbon58fLQmuqzrEI90rboysIxNc1RxdLiDHFT/zBTlGCPuq4FOTv2HCXZyD0ZF+EOgv2Q/zzmMT5rhwlYichnbwgtpE4XmmGJKfw/f9QuEDLdisb1SMyBQQo4fXZaMnWlyW73OKm97P/NPq+LXZhB2ZRgt4qSAzHLQee5cte99OVnG5c6g9V9nXYTyc5Obd/LAr+5hSCM9zwgcAADvvnCP76WjxgF/1D7u/y/oXWgL2fZIypCl2zMh6kZcWy18lz9cSd0lxs7Y0vNDMPmTnT2jSx0GvFr6CgbkOpPb5Iy9GLv6SzRIng4bmufheZDqWAV5okg7it4yEDTQlvk9bUFVne+U0lRQfBjPHWX3pAi1rsvz6y5xDq3fONa99YuXNolHMTIGpoJ8954pLSPQpRWzXzMv/RfqZkkw3/h4xvlAF7Tz6XcbY3N0pxKQFcS/K7zT0wVrxJsRCce0PQuLprapPlfkJ0QwIW0rK9cCKsuvCCU+KfiSnPsv4+N8HIvRmizxnpMA0/Iy2yE0JI9jNpwQQ+qEtnVBiS/5oG4CAyUwoWapl6Tw7SDZm422oNcxeeM6XMtCE3+M31Ofct5CstisnMjP30lYgkkCzMkm661kx8hYb0yJwG5l8Wjhz8IoredxmDTR8wWtbXZ2lKju/tthHy0+5lrueCGE2JePre2hJAvXDmggyITpfekqBB3+7trelZ1CO/e2R110+andawLors+Tf/RvjG03h8iT3oFYUk6TyZqnkr10XxUI9VIY6/Nwoc24Jh23rtiKk7ppY2iuAx5WtYg2b5TwApoi9GCu8hYn3EoWhtA4+5GYU0is4muSUXl3cepHA2LI2KR6Z3UjfCKriEzmwUzRKaa4ZkYnmiRM6ZxMhO7c3AKXVe/3YiY1xn8ZsZLIbJbm9SJeiX8MdEiBnNuzj8oes6TFs0piVqSYBSUTZ/uLZuimDyFkf5z074FDtLNlGaaDZDEodnZqlKc+NzlRlmQsOz+f7n+KQvmWCoPBOg6zQzHH6oBlnrdlm5DofeqJKJ/g95C79S+zonxMrdTlzNonVbTGHlsGqiWBz/T7ghHFaA+8ykIEjN4SduO6e8r7V3870a89L11e0gMnvU8YymTCIdM/BowDGIcTX9LIQ+/hQF1BfuPjvfhVqNi4BQ55IGri1NR4KWZV8R9sCE6YVO/k6usaXhOJe1Ixr6pyWzpHvmisaYzor1sg6giz+TrsXnFM+Z3w43Vd9zp6PhSd8iswCLITmZtDIWWCYbeTTKj0FX5ujGtfgPar853QwtCr8tcKamaHYUYGVuxIi5LVpwbRy9OZthUxcBjOwY6KEyYZeMsMEFLn/7i9OotzaJ8S/zJKGVFg8kybmTKOhtyi5hrwWVs87uQzPYPDmgQoz24xD8rUhuu3OS6MQUBU1etiZQ8fa+JtOoOUpG1J7nkcWbNcOpUsGScDh8GjKfhXczycYT9Q4HQTcu9Va7yMcAx1cXhPSUgX8rPUbIe9EC173csirVEVNa7F5xqAEtMSVGFRnepaHwOFUjS1GEnnjwxwPX/oAB7Y0VchZqKWk+fK3NrnkM4gY1QH8oslJBzAJL3Wqrx6m8fHoUAYGCq+hvxMrIi8+ylJOQZAnDFWIOJZvQwEOQRDXp8r2NW1yyP/QC6qNIbwRLG7M7JrjEUXqRYhdSLGUNXk/JJ9MsGNWF0DN17r1HL70kYn+SPkeEs7T04XT74OnWKqh48Rvk7+1J19NbvZH89w//6eaMhXFFTeHalNZNulfTd3+j/6P2O7NCQndaLMhJVYKpKRd7MoJ4/eyiYuATi6QgHr/Sw8a2IieYHqX1K+l5Ak/TLMrjspBS8kq12MfvPVqsewQhaXqmLIWDIjBKF5EcJdhY2qShc597It+homFE38IVySAiJ45vx79r9cPLgZ5Q+WGH8S3ktZejSDR8p+VonUuotjOE8RJHPvsCoXaOV4fsquYkSEvQOhdQDz3t6tCuWQ5WB++O3BejIVaKeUU8JYAIxtCIKUZkboMvbE7gUNERF6ZYLh1ltvjg3aWQfFS/9EOGqn+Anat8xs0D4Z3pC36htD+UXZVgyt1BqvQDi5nUU+TuIAn6R1MOKwTMYPhoF5C3rrIEngmFQHORqaH5cRJkEkSEnyQeKL4DrXAPXe20zvflEloVkBYA+iquEYEsnjR5T3LWbDMy2LF+hDsq6WPTso0wZIQxe9/razxkrgeRYck/Qg42quKrQ6qFWhJBHYpG6pvKG9DCApJjo4cFC8Fw6PaBtUHGvlx1naA9cWViKNJxDGTPW4aBvG0ju9PIxSkLnBPGici3ioIkh0cquq44GOKDqWvS4WkZSIufSfmsdehY3FzzaHuLi+NTTxzEZkB+UtZKb8hyoIN6doQ/zoo0gDu3zy9ZI+gxvi+bybFvAtVPnjJHv/wOpOkzqve5ZOZpZ37NzdldFNKc48CJtC8uSRXUCxFqVxZh4DDnYjhnIdpNCapyVRSt3/uZdGD95aFg4m0oGyrye+3Sqww+mQ+uT/pBddD1JMJIHzD34ooNK+oRdK0UwggIKAoICAQC6hUSWDXNIu14cndyGUNYNYyUDvSoXXILoJAPL0PdaSpMZJVzdfhz+F6l2Wuqw+WA2hiXPtlyX1NLMzy8bVXKo8WW92TXE8sy0Etj7noUlQhixc8UPagtn8q7UGUt54zia1w+wPFNyNHENSfCMYcLuJo/PiCFq/sjaMuZ+74sOvZGi2sQ+e14lwNSjt3VbqmTwnumqL3QBN5A22WTI5nrshn6+PniS8O/2/oYuRvnzXJyCNzF2W4hyBG54OWam6ZDG8pWsv/MehNMU5ZU1nr7kKUmSmptUKCZF01AFbnSIc8TYD907YShcwIPUW3sXlRHMJ/erCczAJOA/SZT+hx7i+JZchO/gPhfsGK8DZzuIdcGR4q4FaN7hfx04ltcQ0EbiYkcVau5Ko7/FnVaJg33sQhi3PsdL1jQRd3YcZ4ouxllLau5tq++VQGflX6XJP5bv3mydEIXMWMLUyB+SCLNfpdVEBXURuA4wW7ArHAL44Bc+8liW4gmT/d1yGwL2j5IHjJcuhKilgZC9fgfbZZd5OLBJohphGisAH+GkhXUC25CAsDsfcui3Yh3g0e6HSmvarAJiC1MlIA5oWHqJV0fo69dqUiJJRnHen4hVmRINv6x5fpm5GSofNVXYVUX2EG7pYHF9mZ641/ROF7UzrT1uuCgTUNh3r2DlTGMqw1CYYQIDAQAB", + "MIIZ4TCCCrygAwIBAgIUAVXmTDDqr99QjpoRFLNevrw3GS0wDQYLYIZIAYb6a1AJAQcwSjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxKTAnBgNVBAMMIGlkLU1MRFNBNjUtUlNBNDA5Ni1QS0NTMTUtU0hBNTEyMB4XDTI1MDcyMTIzMzAwNloXDTM1MDcyMjIzMzAwNlowSjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxKTAnBgNVBAMMIGlkLU1MRFNBNjUtUlNBNDA5Ni1QS0NTMTUtU0hBNTEyMIIJwjANBgtghkgBhvprUAkBBwOCCa8A6EezpF35J8fD8+MBDD23cX0LKFHb1q2iiEsu9TPRUfQlCYGq0/s18KlUbon58fLQmuqzrEI90rboysIxNc1RxdLiDHFT/zBTlGCPuq4FOTv2HCXZyD0ZF+EOgv2Q/zzmMT5rhwlYichnbwgtpE4XmmGJKfw/f9QuEDLdisb1SMyBQQo4fXZaMnWlyW73OKm97P/NPq+LXZhB2ZRgt4qSAzHLQee5cte99OVnG5c6g9V9nXYTyc5Obd/LAr+5hSCM9zwgcAADvvnCP76WjxgF/1D7u/y/oXWgL2fZIypCl2zMh6kZcWy18lz9cSd0lxs7Y0vNDMPmTnT2jSx0GvFr6CgbkOpPb5Iy9GLv6SzRIng4bmufheZDqWAV5okg7it4yEDTQlvk9bUFVne+U0lRQfBjPHWX3pAi1rsvz6y5xDq3fONa99YuXNolHMTIGpoJ8954pLSPQpRWzXzMv/RfqZkkw3/h4xvlAF7Tz6XcbY3N0pxKQFcS/K7zT0wVrxJsRCce0PQuLprapPlfkJ0QwIW0rK9cCKsuvCCU+KfiSnPsv4+N8HIvRmizxnpMA0/Iy2yE0JI9jNpwQQ+qEtnVBiS/5oG4CAyUwoWapl6Tw7SDZm422oNcxeeM6XMtCE3+M31Ofct5CstisnMjP30lYgkkCzMkm661kx8hYb0yJwG5l8Wjhz8IoredxmDTR8wWtbXZ2lKju/tthHy0+5lrueCGE2JePre2hJAvXDmggyITpfekqBB3+7trelZ1CO/e2R110+andawLors+Tf/RvjG03h8iT3oFYUk6TyZqnkr10XxUI9VIY6/Nwoc24Jh23rtiKk7ppY2iuAx5WtYg2b5TwApoi9GCu8hYn3EoWhtA4+5GYU0is4muSUXl3cepHA2LI2KR6Z3UjfCKriEzmwUzRKaa4ZkYnmiRM6ZxMhO7c3AKXVe/3YiY1xn8ZsZLIbJbm9SJeiX8MdEiBnNuzj8oes6TFs0piVqSYBSUTZ/uLZuimDyFkf5z074FDtLNlGaaDZDEodnZqlKc+NzlRlmQsOz+f7n+KQvmWCoPBOg6zQzHH6oBlnrdlm5DofeqJKJ/g95C79S+zonxMrdTlzNonVbTGHlsGqiWBz/T7ghHFaA+8ykIEjN4SduO6e8r7V3870a89L11e0gMnvU8YymTCIdM/BowDGIcTX9LIQ+/hQF1BfuPjvfhVqNi4BQ55IGri1NR4KWZV8R9sCE6YVO/k6usaXhOJe1Ixr6pyWzpHvmisaYzor1sg6giz+TrsXnFM+Z3w43Vd9zp6PhSd8iswCLITmZtDIWWCYbeTTKj0FX5ujGtfgPar853QwtCr8tcKamaHYUYGVuxIi5LVpwbRy9OZthUxcBjOwY6KEyYZeMsMEFLn/7i9OotzaJ8S/zJKGVFg8kybmTKOhtyi5hrwWVs87uQzPYPDmgQoz24xD8rUhuu3OS6MQUBU1etiZQ8fa+JtOoOUpG1J7nkcWbNcOpUsGScDh8GjKfhXczycYT9Q4HQTcu9Va7yMcAx1cXhPSUgX8rPUbIe9EC173csirVEVNa7F5xqAEtMSVGFRnepaHwOFUjS1GEnnjwxwPX/oAB7Y0VchZqKWk+fK3NrnkM4gY1QH8oslJBzAJL3Wqrx6m8fHoUAYGCq+hvxMrIi8+ylJOQZAnDFWIOJZvQwEOQRDXp8r2NW1yyP/QC6qNIbwRLG7M7JrjEUXqRYhdSLGUNXk/JJ9MsGNWF0DN17r1HL70kYn+SPkeEs7T04XT74OnWKqh48Rvk7+1J19NbvZH89w//6eaMhXFFTeHalNZNulfTd3+j/6P2O7NCQndaLMhJVYKpKRd7MoJ4/eyiYuATi6QgHr/Sw8a2IieYHqX1K+l5Ak/TLMrjspBS8kq12MfvPVqsewQhaXqmLIWDIjBKF5EcJdhY2qShc597It+homFE38IVySAiJ45vx79r9cPLgZ5Q+WGH8S3ktZejSDR8p+VonUuotjOE8RJHPvsCoXaOV4fsquYkSEvQOhdQDz3t6tCuWQ5WB++O3BejIVaKeUU8JYAIxtCIKUZkboMvbE7gUNERF6ZYLh1ltvjg3aWQfFS/9EOGqn+Anat8xs0D4Z3pC36htD+UXZVgyt1BqvQDi5nUU+TuIAn6R1MOKwTMYPhoF5C3rrIEngmFQHORqaH5cRJkEkSEnyQeKL4DrXAPXe20zvflEloVkBYA+iquEYEsnjR5T3LWbDMy2LF+hDsq6WPTso0wZIQxe9/razxkrgeRYck/Qg42quKrQ6qFWhJBHYpG6pvKG9DCApJjo4cFC8Fw6PaBtUHGvlx1naA9cWViKNJxDGTPW4aBvG0ju9PIxSkLnBPGici3ioIkh0cquq44GOKDqWvS4WkZSIufSfmsdehY3FzzaHuLi+NTTxzEZkB+UtZKb8hyoIN6doQ/zoo0gDu3zy9ZI+gxvi+bybFvAtVPnjJHv/wOpOkzqve5ZOZpZ37NzdldFNKc48CJtC8uSRXUCxFqVxZh4DDnYjhnIdpNCapyVRSt3/uZdGD95aFg4m0oGyrye+3Sqww+mQ+uT/pBddD1JMJIHzD34ooNK+oRdK0UwggIKAoICAQC6hUSWDXNIu14cndyGUNYNYyUDvSoXXILoJAPL0PdaSpMZJVzdfhz+F6l2Wuqw+WA2hiXPtlyX1NLMzy8bVXKo8WW92TXE8sy0Etj7noUlQhixc8UPagtn8q7UGUt54zia1w+wPFNyNHENSfCMYcLuJo/PiCFq/sjaMuZ+74sOvZGi2sQ+e14lwNSjt3VbqmTwnumqL3QBN5A22WTI5nrshn6+PniS8O/2/oYuRvnzXJyCNzF2W4hyBG54OWam6ZDG8pWsv/MehNMU5ZU1nr7kKUmSmptUKCZF01AFbnSIc8TYD907YShcwIPUW3sXlRHMJ/erCczAJOA/SZT+hx7i+JZchO/gPhfsGK8DZzuIdcGR4q4FaN7hfx04ltcQ0EbiYkcVau5Ko7/FnVaJg33sQhi3PsdL1jQRd3YcZ4ouxllLau5tq++VQGflX6XJP5bv3mydEIXMWMLUyB+SCLNfpdVEBXURuA4wW7ArHAL44Bc+8liW4gmT/d1yGwL2j5IHjJcuhKilgZC9fgfbZZd5OLBJohphGisAH+GkhXUC25CAsDsfcui3Yh3g0e6HSmvarAJiC1MlIA5oWHqJV0fo69dqUiJJRnHen4hVmRINv6x5fpm5GSofNVXYVUX2EG7pYHF9mZ641/ROF7UzrT1uuCgTUNh3r2DlTGMqw1CYYQIDAQABoxIwEDAOBgNVHQ8BAf8EBAMCB4AwDQYLYIZIAYb6a1AJAQcDgg8OAC6Blu+/wZKfkeW1EgU3kxMPLktYpQ7WNJumelf1mgkxAQ3keDlGlSWdzL04CQudBDFIP6nUHwjPCRqSL9T+7yJK7Mj3zkScAP+gdPoVBZaOo6gNEW/+Q7D/ECU49f3Hwf+woUWjdwH68qf3pvVnyjCBtQgwCXQBL7OmYWu+8oEiLioiZ8ftZs+SJzSCdmOHhHTvS+HfMY7IhiUg2F0yW9TOwWvfy3rd560aKSVf7gDpvonsiUTGWyG1vB+qhZ/ZXfTbRZvZCTpxEpSoEWkLCKzg5pWPL07MhNT7X2Kx7QtMJVbJsRhTxgvrfIzbGUac08z7uUQJ0jpQfiw3b3LDR/xQjTr9OIbiIYGV9WBnsgvzC1Kx52vz37KMfOJS4bkfxJxO7OmpLrlhMUGf9ysk7HwwQd+ThkV3+Mi8o51RT96TgXG2zqfapvMHSFwOWwfGTmqJi7pXpN9GaVz3/OE9BiApuYA9znCtXTuGlAmnlwZ9CERve5MRdMi80y7peLG6jmgo8XXW1D084BkwSgBjUuvppdKnsjE666lp89GRkpP0m6B3sCMUJrdhWXFpqKx3l7wVW8t2yYxmrD+jVrF42th61gqRe3naGYuYAMpmgPy5ar5AK7IK2gj0SEA4ZYLgovSL66otCOif3A0DyXKmb2cBR+xE4iYP8KUr2bTv3X00KY/EbD6xhHpovsQg3L5ab+vmb5jRLw4KZHp4GeiyZq7e1KvnbABZeriAurL5xqIg7zHJGOR6RoOeLatM8ArRr9XRMs1kT8JIWzgcYdzSyKkPyNGm3/64G+ihXpXHfShx0fR1JA/X8XprHzU3+XodLzK/5dcXtvQLvnYR99rcuTOAjsP0cyyktklwc+6vlRFMzIV6tsP/00nG62h6lI9u0CPjhAULKy7YMlh6ZeEMiXU2RkPSGwL9rlAqdw16D41hZNGNE0ZBaQaCXT/kH8l7VfpN5qWhKFvvy04+43Z24kZ69/Nxf8Z9W4n7jS+HluwXq3QVcw3I0my7dxDOQgmglDD7cQohEXeAu58Yt+uNpLDYaEOPV3Z10o9bY7VLQDrYWCYC2abkYvLtPMjd4TFyb09BRIRhhotgxAoF70GYx3Ha4mFWivWWd0iSVGctFxp6tnSXHA6do3iPMAyoHc12DcpTbEcSr3W9f8T7mNylbjXYq/GU9Vw9CgLfPKGQb91J5BwSMScelqTESsicEPyDqrXeWpJNOsSgyjPfzMeGtJo/BCPfgbl1iqtdaBwbZtpSG/Oox/OumSEPiyYqXi0S5bBDyMp1Jo3wk71Ug21FHzPxqjdP2+uMLvAR/I65qkyixvoz+9ZNZUXBAdd6czDZcGQs+b2RtYM2jXNMOwXH23UYtX0sz6UTFryEfqLepLidTIaHzUfKvBLUZfzJuHxojN3Ox6NZPphIxH6k1IlJDavVdupjhsGMUkhAUHNQs5EwiPLWTIyjrYVcX8BGUkQZOuJbIMDMpegiRFWFjmwDicxJlziKTWRCJp8W9maOksPw3zGTfMbVNXNfV/aB0SVP+C4hEpM/2QF3eGI4tx+CjFeZ2J5thgcy6R59wyI7+Drs7RXJcxyp28fWKENcKTcVOF2hn+GhGMw5Ysjud8851FGhPns2WulBxi53BcPmnnn02WQfRBTYdO7jJyJ6p0YfaUeBTuz3NLYWS7HqFZvjiYYdodKzuA5g4ZZcdWp/Ax9OeVfVvueZOQuH7iK9czH2q3ZoTZTxCuuTmPiGpfGsNmITqrKiiBLwB0ewKKiedKyEkYVRJ+a4iUzDiCaDrAISLtz5sbonEMBjuBrwkabap51Quyq/+YDOKc1XLdbxdSa2SOGwh0l6Ykl9MdEH3IEK0T6wJ6IyA4Xjp9KuHkm1viJyZbVBebsJlrzo7vr5aa+FyrjjWVkFWdeT161ewewDyGGE2uGmEgvU1oRph9RZkJl5GrfVnKEAFgFI8asurb3l80WSGI8039PSwu63m36zF3DtqMtaF6FcUy46QyIwJO+eysy3WxXWvVvoxzVwS78UascyzSZEeG4sMWb9BRLcE9NWuxX1wyn/hoX/5i0RErYBoo7NoYtr0TuXDiwPR1EizeynAA1T6GNNjk6NqEhoN+Vr/1aS+AMw4Z9ewRboEYrlDRyf2HZiweq/mLKl6urHmmk/8sORY9hGE4s7UU4lXefCetuclg+ZLulugazgsanvKuLdgR0zAA4BX/X4Ovtsve23wv8LYBZSctMG/MbaAsBf7CARiQPHePw+DjmNjNQL4MYM6OkxHLMvK/K1O4WhpmVxO3RTi1du85PfU6yX1x9OrR9Ra1Y3nQVJTLUA/Z3ob6q1u9paJzbPXSiq+X0TySxQCbe59c1Km2sCpbT+KgeyjFKmBD0KMpqCm0zfTSicxGn1ARlBS1zmp7S9hy4jcz3mnF7FikpH1h+8Ne74xJ2lXF6+lXB5e774iB8yXn9gc6sc6NI0vMTeorESfjZvyK0qsBPNUNzwsqOk4LlheZUaCCtO+oT7IR2MkWhimhJpWm1Hf2EZP4a09EVlun1lUsLwU+ELurO+jt7GapHZuFmbBZ+bM/LfnOKBMROjn1RZDEtYZdQrGoq4UU59YsCWjq5QgLLnxvRUeVe6pDMa2uv8uxUqAffXwWmUEkE9CsIb68+e4eS4dXKm9cGBksG0GQOjaUpCSHGWf5zfL6A4adN6ORfTLd+FdziHijdolYXOqrVlTBXnQ0s0yUdSmDFMdfD0wNbDd8aZ36ilWwIpZb6CugsRnX7TqDMV5AwkHjor3wXr1J4q7SgHu6y0Hee7t/4ATWzcgnytFL8XehjhjFcLSKkYBlha4gfpzQiA8RQ75NfKbH1L64ssRLUp8d3vCrA3F287dDQyqkFmiQqgh9twVtuFGW6+vCX8mdZgzPYlRurq071aV1sObov2mJk7alCZ2aoNYT9cug7sFVKltV6pYIkflNsT9u4URMdPIgayEgeHBmnmzxLWKO5ZAA0TaHUDXh8+bIfGASN7lcSnUzj49lvNotAEKXIBBrzecmGodNwk+rp+fkMf0KcZKW7F8MIxmXmIou/tSGRx3qtiI7juHlDXd1brwVJime5AtQQTfkbb9fyi3fDMymGVFkPv01TLRdrYitClme0tLuKztZtAWIX3s/tJtWuQKZ8YsOvbTsiluQmLFo7FRL3u1QQvJZdUv8nf/HdQ8e8Ol8ePyR1KT6rpkoS2eljs40ZymDUDQ1yONmXJp1A1+FzPHpB8xmKarBy/B+VTJ6lC+k0Ts9nTuoYhQnrQ5XbildzeMBZ3W2pAXF5wktK3uLVQrJzZWOD1Eq4jEuDw5ZMQBg2toAxvTkfNNpMMBl4mvqW/AxQHvGhg0RnjvmO9nie1ltYgjdpCuNB2eSpZAq9perWDJ7HBWXs/zLQvzMJurFeqOdmAIi+rDrMFZcGuEEKL4UXbCkgUgEgwtSeCsY8zCt73SXfpbblIA7djj8KGTKAbrqsYJJAVL/bG4gjizMBipxxIp02r3b4EidXzGaZ8CCUWf5MHsINvGWltN0V1wLu5rOJtdnOgQ6/cOy7geRXXXq9BctMtJGPJx0XoYMM+fPdIjeq4h3vZTqlnvkpy0fpXcw4lnsdv13hmgQyC5LHWxXLo6WLJU8m4Spj4MC+Zk23zRKgYmU7eGGQhAJ8He8KqMSdlgcIgDAL35NAhQBybHAOswNs/kNNnMmWGySWEb8/8xabCTmwEnd+pHyQjUOoJ7LLSkEdmk+V0Su2dE7AkSMzO1rBfzfACckVLciS30KSo8D/K5/+6C7CNTx8I095l8XYX+6K6XqtaEnmB1IcGvk0ARJR/utU2lJhtwiH2S6F/e6PlSoMozZoIg4L7civoTn8WqhHTAzENTqp5062obtPVN9jov795H4OpVd8f+PGhyprtefp/w1cLFb+QOjEpWnOop5AkZAOxC3REEucqQHlXbbpsXaTNg1pw9+WKdWfA50OZs2XVMr5nBsC7qtmYLVp0xZK93MXUe+1uYt/miR4YjQofHtbI0oPT3rUW+zT3oXmZyBMWIVItBN5rRlMmhzhiVvVUuExh0FPOyhX5g6ToyFwTenMbugXy1dh3Yatb5IjItGrcwgtssKQHsEpBU87Cj0xnILWlP42dFvB585JShiaVB4/CFYedP6Xl2k4lNOpctbvbE12T8UeOi9nJvAKM3JjeArU6BC79k9Us8m7qJ2f3d3l+Ry40oTfNSZIeu2iD48etMbNI3hiH4o5y3eMG4CN0j5jCOjCgLQtSXVAag+egUOFRsGmzWtQ6SZpcSVyfRbh2C2cK2dFhXA4WffmBtA3E1lyg0RPPS46Gb1ex4b4tB11lBZoUy8R1YFhAoSId0V8j7d83vCE6jt6G32EyNWQqM5nN5ewDaInC3itOdba3uLz3HTOIzjl3hqS4wQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwkOFhogBoGyyQupE9U36UI/HUAbUksBldM0SZ2jYTwMVrqyoe9CQlFxVqvSQHauelMLp7kx/DD7gD//YOb4z89XCK489HlVaN2e/HkmRnasadtt2hvvwjHXcEeWbCQjoKwlFlHGWlKE/JbxTy+U2HWArIqraA+GuFl8h0V6PB1a3P0EzYZYMOEnhn4EomC50mu8XV9fpUEGuvS8+agk6HAGD4T7RRvpt2LSGgIuB6xS25PyR1qbSd2CC4b7c3Uv/2RQGrbtkOWartIK6dpt/3IktujPIH/j4hLVeuj5VwI3qY7tDZpZlLMdmO5Exb39tunzCoXjFRewHVWw7MuUmsBevsbtajShZSXQZG4xxWsYacJrInXAwVscnDssRU5xipurpHGAUKOX+gsTHO4AaYjVNf5fYoPstEukp53uHfoxv+RLXv8eDx6A0Wj2kB8VZgCRsWyNK1LgARF16YrsQ9lAppy5TSpLKPFALSCru80ilyA4Z+BcAdtsnhsQiobxG3T8h7KYiAJ0a920p79eoYnEJelj4io7sRYFEGr8JmlNGT+5wChLIqdupxcx0by77bpbyS5VAJCe/pqQkOLyf6jYzYn/AI775d5X4QN6P9kXKleQxgUwlThR+HTGBjaL1cUv+NZGmPv3GewaqsTs3V/H9yt8nWsC4cO+s5OHyamhjylGos4=", + "007hz3ZJ3m6+MANhV9sfNqcm6utAVQ+bm1nKH1x/TYMwggkoAgEAAoICAQC6hUSWDXNIu14cndyGUNYNYyUDvSoXXILoJAPL0PdaSpMZJVzdfhz+F6l2Wuqw+WA2hiXPtlyX1NLMzy8bVXKo8WW92TXE8sy0Etj7noUlQhixc8UPagtn8q7UGUt54zia1w+wPFNyNHENSfCMYcLuJo/PiCFq/sjaMuZ+74sOvZGi2sQ+e14lwNSjt3VbqmTwnumqL3QBN5A22WTI5nrshn6+PniS8O/2/oYuRvnzXJyCNzF2W4hyBG54OWam6ZDG8pWsv/MehNMU5ZU1nr7kKUmSmptUKCZF01AFbnSIc8TYD907YShcwIPUW3sXlRHMJ/erCczAJOA/SZT+hx7i+JZchO/gPhfsGK8DZzuIdcGR4q4FaN7hfx04ltcQ0EbiYkcVau5Ko7/FnVaJg33sQhi3PsdL1jQRd3YcZ4ouxllLau5tq++VQGflX6XJP5bv3mydEIXMWMLUyB+SCLNfpdVEBXURuA4wW7ArHAL44Bc+8liW4gmT/d1yGwL2j5IHjJcuhKilgZC9fgfbZZd5OLBJohphGisAH+GkhXUC25CAsDsfcui3Yh3g0e6HSmvarAJiC1MlIA5oWHqJV0fo69dqUiJJRnHen4hVmRINv6x5fpm5GSofNVXYVUX2EG7pYHF9mZ641/ROF7UzrT1uuCgTUNh3r2DlTGMqw1CYYQIDAQABAoICACjaeMfPAWG8XGQzNXKb8Q50mU5k1/vO8QNMpCI3zn3R2L9IvjrrXQlQgHciecYykN7QaibBQC2nWVavyJcZk6gqW4kGMu9E6Q5GFI2kTnB3NjZj75UtOntVnfJp6ey0FplfopmM1RAuKVbqS4xL+2izPIuNuxgW30JfpLnH2PLtFaGQfixbVCc7wbdsPwHJZBuKCw8SHrwHgghpfFg+l00INmmQAFPa/wxf+l7Xf/bMYaFp2mUcrlme291sYS4M+X+B8cOpNWSJXjx0/sYEU7ZgzrMUNxJrStq/aocOBus+RC645tGTOcZ7CkTwlpj3NzM6y9YEKvso+I8UHFTVnq9jK2BaVLegrepFnoAYY/bD+Jag+uVS1uuFPjAODOCnyEJI6MxANidDuasnnNFebU9dj55X8OYQ7BerTS3gtxoTS/Nix6ECfazDLRjyEMTbtVuQI7erf+jbcR23wLvojCfqlDZGh9pKzP6o2GdauXNhbeW05tdLK1ONxxO478kBNusXQ9qlG1Zla8dbJUSAWGoYCjT3ncT0vsmWFPzbCUkREeBPYp9ICblvNSPJKQtKaBv0/o7QCytNbJ1JCKZGFWpSdeS5pk3SvrfWHuC9qbJvcqI7Xt5N4pZYONOnKJHsRnLi/qqwYU8j1+5ZJJjtnw3JooQZCVvZPE00u074Uiu5AoIBAQDpLjITlnlgoxcvjBP00mmcXsGoI1uiAVn1BVe35v1TMObzN6OA3SpXfQ4YfMDuM8RP4S6sTFyA4loG7oqkMe2q9EO9n4AarwKkmX6fW1fe3VCfdofx5pVShpnJDTuwRof0UCG1eroTgSuMTihdmRVTWWiJFy/dPgob5OxRrjLOipG/2wTYVMU2tYzZxl1wipXMZAHeaa+1io9b3h3RzxKEWrXHXr/s/+xCx8DomSObrHONnRcug8qBtLUnxbLauF7mg5m31uEpYLb8BpvR8zC5If5omQGFPlFQkaRABN0TJMcvrAfEOWwfxi4LlFeDpeE97/Qry5R+65eP4fdkVrQFAoIBAQDMxh2W7vNdOmz/4QjPGjp7+3sNOYV67FxsKfT3NhSQkjjw1DJ4IFkXxF080bR6z8y+pltBLdQzrBtyQx5p7wccu1N6EhKiLGytluGtywBmJtejM69arUwrW4SAh8o8SCGzbQ+Agt2jAxKQJFPsJxkicff/FELAup5z17wL6imGRF3/MFFtFo/2f2bXRKVi79QoaDDMFfsHqXeyUi0BK68da25PZjylRUOOt9jNKuaDwFm26/qtsUnTeIgL/vpNYIxC3n+nIC1gP1gB+q3huKUzv804kEURu+E/PqwyNoL4sxfrR5oAFzQkLGjhcX7prwhsK2ABqw91+RTBdlqakP2tAoIBACRsV9whbBJBR3Tg35klaOPJFVzrMPwMU/3m+L28MiPVhq3FKiAN6/hAi3wduJE8utRzazP0tZpYQRHGHxfoyKQkhZRQHtWMMtB9PX8s6HvifB58iF2r0/VRGyKBk6pESiZKggl0Ay7axW+kIcAFEoSzeZW4bnyTnUagKp3TpRIIKR4b2xTjoO6by0WVK7FRpHaJxJT2U0D7RMtn1aaZPt43wR9EWJxvmXsQ8rwid6JwfJhJSn60jWRXUtjEk9yAYiqFsfQ6d29cMRkK+zn/T8QLYE78X3Vtt4vrRAnP+Kxt2UNEDu6CvbX04epjIIxq09U17yEMKsTsjf8mn9sng/UCggEBAJYM6mvKJux+vpZ1uLXBm290ZMPZDZV4k3Ty/b0UlNcnPrBCXcUmtwIycrv5Uo3XrUlar23Afklq6SW+RxALBiQopE/D5IGPmgdNk4t9QIqaFdNSMUF50WHICv0AA9JObNuEpCJgQraLrtOOuyxFriZOaxIwL4X4edmbEQGOEeWAPXycVF5idRWEX8CIXcR0xvrg9jjmNm9z3/D8RFwiPYyKR2fJG9FjQtDWqPgWYpnSnirrGmKikd1y6gYYTiPbBoyNa+70Jivr3rp8jWPkoLGd72xuUx5elPx6GUYmKazB11ohupgsaJnFLQld2Ei2aK6SziQKzCZ/YZUt+9BdRHUCggEAYKcqMaEYdigXZHxqvFx+J/WmHcdd7tOiQjF1UvVGd82m3Id13ZmpKXMzz7GsI0WYkJo0wIMkQyjoa1CjirC4rTVrq8waWKuqidYluYtsD3uK5OQ0g1kd/o+SnMZoqTa9eA+/1nUoxRPRgnGGDW9YKJaI25qnFoi+0ISX0ZNW7sN05XBBrTaw8wQIbI0TafUvLARWHBYn7om1JNwh9i6agqSEsfPtUh9bMuHK1grvSg2Oha09BGkUfBRZisZ7XzOs8S9a480JJYtaaWdhonOczICbnQYzaa4jkzbIF8qyHqTsxW2atCAO9Nh8ky9KOZn0HMvNlU0U7WKhcCspgqVGeg==", + "MIIJYgIBADANBgtghkgBhvprUAkBBwSCCUzTTuHPdknebr4wA2FX2x82pybq60BVD5ubWcofXH9NgzCCCSgCAQACggIBALqFRJYNc0i7Xhyd3IZQ1g1jJQO9KhdcgugkA8vQ91pKkxklXN1+HP4XqXZa6rD5YDaGJc+2XJfU0szPLxtVcqjxZb3ZNcTyzLQS2PuehSVCGLFzxQ9qC2fyrtQZS3njOJrXD7A8U3I0cQ1J8Ixhwu4mj8+IIWr+yNoy5n7viw69kaLaxD57XiXA1KO3dVuqZPCe6aovdAE3kDbZZMjmeuyGfr4+eJLw7/b+hi5G+fNcnII3MXZbiHIEbng5ZqbpkMbylay/8x6E0xTllTWevuQpSZKam1QoJkXTUAVudIhzxNgP3TthKFzAg9RbexeVEcwn96sJzMAk4D9JlP6HHuL4llyE7+A+F+wYrwNnO4h1wZHirgVo3uF/HTiW1xDQRuJiRxVq7kqjv8WdVomDfexCGLc+x0vWNBF3dhxnii7GWUtq7m2r75VAZ+Vfpck/lu/ebJ0QhcxYwtTIH5IIs1+l1UQFdRG4DjBbsCscAvjgFz7yWJbiCZP93XIbAvaPkgeMly6EqKWBkL1+B9tll3k4sEmiGmEaKwAf4aSFdQLbkICwOx9y6LdiHeDR7odKa9qsAmILUyUgDmhYeolXR+jr12pSIklGcd6fiFWZEg2/rHl+mbkZKh81VdhVRfYQbulgcX2ZnrjX9E4XtTOtPW64KBNQ2HevYOVMYyrDUJhhAgMBAAECggIAKNp4x88BYbxcZDM1cpvxDnSZTmTX+87xA0ykIjfOfdHYv0i+OutdCVCAdyJ5xjKQ3tBqJsFALadZVq/IlxmTqCpbiQYy70TpDkYUjaROcHc2NmPvlS06e1Wd8mnp7LQWmV+imYzVEC4pVupLjEv7aLM8i427GBbfQl+kucfY8u0VoZB+LFtUJzvBt2w/AclkG4oLDxIevAeCCGl8WD6XTQg2aZAAU9r/DF/6Xtd/9sxhoWnaZRyuWZ7b3WxhLgz5f4Hxw6k1ZIlePHT+xgRTtmDOsxQ3EmtK2r9qhw4G6z5ELrjm0ZM5xnsKRPCWmPc3MzrL1gQq+yj4jxQcVNWer2MrYFpUt6Ct6kWegBhj9sP4lqD65VLW64U+MA4M4KfIQkjozEA2J0O5qyec0V5tT12Pnlfw5hDsF6tNLeC3GhNL82LHoQJ9rMMtGPIQxNu1W5Ajt6t/6NtxHbfAu+iMJ+qUNkaH2krM/qjYZ1q5c2Ft5bTm10srU43HE7jvyQE26xdD2qUbVmVrx1slRIBYahgKNPedxPS+yZYU/NsJSRER4E9in0gJuW81I8kpC0poG/T+jtALK01snUkIpkYValJ15LmmTdK+t9Ye4L2psm9yojte3k3illg406cokexGcuL+qrBhTyPX7lkkmO2fDcmihBkJW9k8TTS7TvhSK7kCggEBAOkuMhOWeWCjFy+ME/TSaZxewagjW6IBWfUFV7fm/VMw5vM3o4DdKld9Dhh8wO4zxE/hLqxMXIDiWgbuiqQx7ar0Q72fgBqvAqSZfp9bV97dUJ92h/HmlVKGmckNO7BGh/RQIbV6uhOBK4xOKF2ZFVNZaIkXL90+Chvk7FGuMs6Kkb/bBNhUxTa1jNnGXXCKlcxkAd5pr7WKj1veHdHPEoRatcdev+z/7ELHwOiZI5usc42dFy6DyoG0tSfFstq4XuaDmbfW4SlgtvwGm9HzMLkh/miZAYU+UVCRpEAE3RMkxy+sB8Q5bB/GLguUV4Ol4T3v9CvLlH7rl4/h92RWtAUCggEBAMzGHZbu8106bP/hCM8aOnv7ew05hXrsXGwp9Pc2FJCSOPDUMnggWRfEXTzRtHrPzL6mW0Et1DOsG3JDHmnvBxy7U3oSEqIsbK2W4a3LAGYm16Mzr1qtTCtbhICHyjxIIbNtD4CC3aMDEpAkU+wnGSJx9/8UQsC6nnPXvAvqKYZEXf8wUW0Wj/Z/ZtdEpWLv1ChoMMwV+wepd7JSLQErrx1rbk9mPKVFQ4632M0q5oPAWbbr+q2xSdN4iAv++k1gjELef6cgLWA/WAH6reG4pTO/zTiQRRG74T8+rDI2gvizF+tHmgAXNCQsaOFxfumvCGwrYAGrD3X5FMF2WpqQ/a0CggEAJGxX3CFsEkFHdODfmSVo48kVXOsw/AxT/eb4vbwyI9WGrcUqIA3r+ECLfB24kTy61HNrM/S1mlhBEcYfF+jIpCSFlFAe1Ywy0H09fyzoe+J8HnyIXavT9VEbIoGTqkRKJkqCCXQDLtrFb6QhwAUShLN5lbhufJOdRqAqndOlEggpHhvbFOOg7pvLRZUrsVGkdonElPZTQPtEy2fVppk+3jfBH0RYnG+ZexDyvCJ3onB8mElKfrSNZFdS2MST3IBiKoWx9Dp3b1wxGQr7Of9PxAtgTvxfdW23i+tECc/4rG3ZQ0QO7oK9tfTh6mMgjGrT1TXvIQwqxOyN/yaf2yeD9QKCAQEAlgzqa8om7H6+lnW4tcGbb3Rkw9kNlXiTdPL9vRSU1yc+sEJdxSa3AjJyu/lSjdetSVqvbcB+SWrpJb5HEAsGJCikT8PkgY+aB02Ti31AipoV01IxQXnRYcgK/QAD0k5s24SkImBCtouu0467LEWuJk5rEjAvhfh52ZsRAY4R5YA9fJxUXmJ1FYRfwIhdxHTG+uD2OOY2b3Pf8PxEXCI9jIpHZ8kb0WNC0Nao+BZimdKeKusaYqKR3XLqBhhOI9sGjI1r7vQmK+veunyNY+SgsZ3vbG5THl6U/HoZRiYprMHXWiG6mCxomcUtCV3YSLZorpLOJArMJn9hlS370F1EdQKCAQBgpyoxoRh2KBdkfGq8XH4n9aYdx13u06JCMXVS9UZ3zabch3XdmakpczPPsawjRZiQmjTAgyRDKOhrUKOKsLitNWurzBpYq6qJ1iW5i2wPe4rk5DSDWR3+j5KcxmipNr14D7/WdSjFE9GCcYYNb1golojbmqcWiL7QhJfRk1buw3TlcEGtNrDzBAhsjRNp9S8sBFYcFifuibUk3CH2LpqCpISx8+1SH1sy4crWCu9KDY6FrT0EaRR8FFmKxntfM6zxL1rjzQkli1ppZ2Gic5zMgJudBjNpriOTNsgXyrIepOzFbZq0IA702HyTL0o5mfQcy82VTRTtYqFwKymCpUZ6", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "GRGfM1g083F23gmCg6U7ov/x1TRrzjzB0fCFSe20nGlu6b71Hm089JVVVsqremYMA6S+h7UIz2CJwFm2NkHJC5fsFj2tqsR6iYIaThw1tJ66gcUn8VxVPC/JkJd62xaTDr1ZgBbx2JHvvAChqkVkoTJFGDsG3fhlAgvV8rTXBDzm00phhV/j3Uq2ILOp0FbRribhnioVvSWR1IQBqU5/XPza20skC5C6pUqHhMeGOFWMdbIdNGyCOkT/oBk0K9IyzurFyEKCK7f33oW4y10pBB/nR2dUIdGr7BbMiArc8PivRrLxt80g1W/nW5CxMrzbWZG97iSlZeEimPxN9mAlV7L5PqDaU88Q5U3Q/F/YxJ3dc7K9hr+cgkJVcDCFyiArDld+Bp4zFRIGRdWV29Gokk8XAii0RwF0co7ps0cP/rwPTZUN7YGBYzhQks4lfynDj3EfMeUuBTZuqwH2HuSaosZZ+SEuK/GToHNTaMKCQ5OQt7CsShH1zxBiql5JszBPbzkZ8eD0xtdrJD2Es97ErdukTo0xG1GlmwKVmjp30tMw34F/gl16vKSuWnTgSFX/8lKumWqwUgWY8F1GnZqF68CVcW471CSJlN+B+PeQl9yxz/egbQuJAw9AYWAHrHe6C07N5JtXPqd+I5pIlwDg+YoRUr7bupZ8p3zoKK91EaTBXji+LIcLxGOafi1PrtY/SmUAHmRwCI0CYglHqAsgThofCsjegHUGUtqNHQD/gnHM21pipvBh1iDyiLL/IXu6YrJFSv+8s7G0lDn9MxzoU49SyzdABIkCUJdfDi5EgKS41AOaroyClVsByCJLBMLFtiOsmPSRkzYkvotJHHLAum6KaPVlK1j+2r+Lv0EdWrbeYc0bLj+UqwDUdfj6IzvrIFlzrWyPMVXAxX4o4/s0eBU8J+m288tFuDCjIzHXm1rgk9eOImJK42AaT56sKq2C/jkYyIVIGIf8QKbkVxl0P/JQsp1zhrkmqoAio7/zXhq5hGaG+l8d6Ygc6axZjjvb033jQ1/M29KNUptbuXZPCt9vMkEKXa7O2iHRfTn1xNRaukYZa4r2V5i5NBJmGIUKbC+IdL+eUa16kRrEO94/MVDE//k5z3RSGTO5tL/vQknI+wcXygjQl7CjYyYAxGm2dMMno4zCfSVvLTuTSN33OFpidXcS1rFQe/T3ZzDVwlcbQD/FR4pLGKInhriBT96PHdJD2ci/7ceKEqajk/LEdxyj5da0s49j6CXogVwHK8GpfLQya2pDWMKtL+zO3BVdtYJhIRosqa5DBNdVuTE0Kw8ldzh55E8dUwoTtKMX5iKH7LfVi8/qlUm/pSDwnGkcgnJLChDDZCKGRs3Tb59jYjjvFs6giD9rejkottQlkpFOVmxVE6FYWiVtDFWc5nTwLdgXf/TvtKKkbnA2HSBZDB0mWJevtUgfLF9ET551GLarbcKk0p2air07SBEHKB4OOg7QblbLlGH1c8vaDA4HXr47Byn+vvbXKM4ZKqGWDz57mAaksPL4oHowufHZRsyziIDlfzobkGiJj83Dawzonf8UyU/o1CCx2f4zna9wrvtvDQQKHowKlDSO5Y6iNrBm0ws0lBmTNkSWQcLelTAE1yGxsaBn5AYEB7DGR/nXZiwv4huKmEjfldCHbnXqwjPT6XvMKcf3oioUgDgfPeK94euz9g9XhwfW9ji/L+zyID4atlkWzkBU0MkDVO5LZNDHITiW/puSf8hrCqW1cdxeToOnfoNbrE3Ik9lkEhYVLTEUqIKmSd4FwM43VSH6JIvkyeyHhIy7t5ojKWO/4Wt/c3W5GwTX/UtLhuwVdeg1mxmaZcZITBRsuxwpnCIMQG6vhSzmnEZyH8yRjg978DH0Zp+9YAf9/N0vFhwQtnmMva0xkCyDc038Z84IrQHY2OozzXFfyZHWKrXR06qynFyaHEA0+48xdYuPMLeDOPtO3eHeLdJQr580Irg+KM+JiPiYjroB6oSjLfZJrP7fj2SRGksQmwGaAHCsnv1hfUPf7Mea960cgk3+N/OFuKxxnyWlVY/1+WZFzBkmPqj9lC6h3IiOrCN0yv5Rgaj5E8SQTXZUL7YX7GFc5kNvXM8yDerT1Q4OWfMrdag8xGnClMpDP5DUwPkmQUu4aRjsLpjWyG30eH8zvUFIJbHX+aq6IeT9E7juukV4E28sasMpVaQe6BYzxt/QPAU2El/TMeV+iwY+52vW/BfUNLV679a65Uw9P1Mu8TvR1vW9pjE3Uc9uxqL2zm8tUmEGWehpZjHsDGQLvRJwAhXrPKNgnqJsNtqmoA0rMrhVdYEoadtXxMr5mpOopkPxSMTCaNBhGHKoPJMLrQOyJIztfcKTQUVxGvdQxy3UmYaPgEOFQbTu6uoTG1sz9ZDem4tXL0qAJ3LFJptWphQFMqYD/qHBqS9oa20WteSgjPP0IVHojGAn3dTXl/bQLSS+Iu7nNb1jwW3bB6kjm19aEbXwlUPVoKsS28/4Ld+ArY5dhCsBm+SX4ST+I+RsMjJUin2+e6MuVZRErgfHIeaXO6b67kldaeKoM79eunIqkt8Z2/w62+g8nOrhQQJ+Z70USrf0yT4p76Tcw6CcEwnHEk4Dh7ByI69Prupm5LEkM8p781qPs+qJ7t2Vts7406yFSsPD26TiksFfRWp1X/etbrv6xLVWWCNiD1vtjhGjHW0lOgwFgxy6FPBR0Y3h1DvH/AAO4ZYI9PDAVhJXBpnYgjRHhzNy8u9XSFTpBfaKug745VjVVULmLZoJ1brwN86RIgcUJM7a/wnqElONghbPfc+bY92lpjWGuzP9heAVduE3wY0MGlcbUZlUnELDg1DM+mJak0ZAQy2InphULVh1l8zBH8R60PNEzGkyJaYXnjTNssPfMuqkAQjc4bFickk8i5T50UW9qzeaIWQ0sKXTUXuzW4cByK8ZXFC9jfjIEuBp+FHPIzm4jFvUhvObLyF5ZdC918iJmXmhX5n6KubcJavMBJdBHWExqeNzFjJzDQa6ONscoJ9Xq74nw2FXgm+5SXIKoLGPoRGoiKn0MtDaTNiXquyb3CZ2aHh6Zjmd/DOyQGgmFZtf67kZLNoDKwc6XZU3xjHfr0/v0VY2PEGV+ziCQs0bTAkde6mVoawj7WkczcWGY3KZMgY0hc1otc4OeVs7i+Cx7rVWWhmF6DilENoqZPbScz6idI9IM3qr4x+BKKr/tWFR0HkfOk4THpf30uK6ExHYJISqsZtNwYANjlG2a7cxYL1yF9qpSxeq3hW9MqkePSELSz7bMgmqt+6O0YxvInqugpNg5c9qbkmhsd0+cN16Ey0K3MJUiAR8VV9udWXJLSWdpOfoxRH1gCkOJmXLvuNWv+wrs6VuG3N6OCqQx9ARyVb99tj82uCbPCjYwDtKkZKRaJ5XB+yt9oNVr72s3Y58uTsNktdjGEJyweDBl6L+b9CNVENbobHI7BYopC3z/GzU+tmYpP5PQMSh1PqNl6dU/44Oz70A/E+g3g3ADy35XN+YAPYRW6nbhsVgipY9sscIjzOsCERLEVBrP00QLxun6h7jTjqqhUkcWgCh6lntLh+S9ixTgdt1HK8+xEXf79jxicWGoocBX3k28PFTWbXMVefbU9O2bCoBNW2/0aF/P02KIYdT86ZoDHmqc6a/nyOwSpFlKi6bKgqZ59YSpwzjeF9ukae8fRclscTdzmQXQTOEZjLQKukGbcM3UeIgSa+TWB7tpR1clgDQcnMDgzDwQQa3ownOOv0IyYrR5WAusGgdRSXlXf/0kxk6xvYwfhFu4BfRb2shFpkrKgYUkde2ipGKOdMupfRbaI1lfoWJf5vS/e6edKMM/Azbo4WsvObIcNahAH6C6L4Vp/+EmYte9s26BYiRmelrtMZNqypBFzv17ab1mmxDe9uNFH1+FCd0aeqN5o+gas5JU5s0hn3tMwnx4tUDv8oFxUdN88pt8K3CduDt2f0dI72x/p53oZ7WfbnMO/PHg2e1QRFeeAcYlVsii2Vd+iYbQoxZsb7OhWiZGV2z25B8zrrMpKoiAiLk5ieGRwFo76G/DRMVHNk43p2UqNQLNFAa8G3NWSK3aP9daWMZ3Bw6hCNNlA7GpZ+YiE9tsL09iSmnXART4v8UZ/3P+Z6Jr1cJhLQa7ykCjg/U0aoEU4ftVWkUcpjOHOhLWpUoVtJmZpx9mOT1yCQFL/KM2ULB8X6u4YeQwdQL9vxij0r/f1ZAHdqOxlfCpVwlPbXkdLlRzsKcWlnkcmjsee0O82sW4s1xQe780fOt/BI9XUrtonphPKdtfm39g2bDfXi0dF8uD+2EUq2jGWyi18NBh8ndJBQlzQYmgBMPKi6DSyu0XosSs50rW0K6Mqk21AX2DE1Qa4HEABpBQqUVR5asuAcOEDh5oamtsyNocshYZ4uQtdIAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCg8YHCKNezDGXirt3NKTqy49wfiVGdsjopapwonOd5wOKWWc16oMHAjGYI8jzqmr6ItUa0+eLZHYIQ65Et894xxB7U8pzGSccAgUCxl4OThTREGUJY1+g4gQPND72Voe5LNWHzmZfA0MrYgnUrvDb9VsWtCGNGzwom6FEnfI6azFEEVG1pegpNKKJO9oELu9rplKi6H5bZGBrERUBlU3dx2l+/AkdOSLqjgBB3mNKPzEP6Jt3yxwU1tzDm2+SqDtqkSoGP7tg7rW+0n9ouGb7IOMW397mmFxYjxXZ4Z5k9dF0FszG1SLUq7aVzHepz9uLvTsd759KHQEdcCBjs6qgBPPS9xWT4g8VaqQkRd70Ed36Mx2GfkB0osT/6/WBrRV/1iE7AD0ClhF6F8Faz+t/U836pX0Jg+a11QfiY5ggzmvz4nmpUONb0wXgCZKuohMkw9x1uGDKLTFCZaU9JMJslQjELkYicWi6GwhxnWCI+Eww9GC9kOLxjjsc7hZ8MXsfPo1j5hi1tWIWgJR6gfC83l2z4uhM+YrXkfvTwR47FCNJN/Nje0CfTgVXZLFMm2iZXUN9EpJt3h0s/MVNlW2miT2pVYz2AJeSD6qnVev+SJaPeXL9yWq6TTNZ9/VHXlcg79f/YtOUkTjMIMyS1oWUBf7FsLkQFLs0vh1S97nibKj7vC8Iw=="), + new("id-MLDSA65-ECDSA-P256-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256, + "Q13kc+0JAWW48IN4kLGkJOELbj2c0t19iTqJDmFK9grtsah6WwK2pjuvOTx7THjroS+FFTbDjXxifp38hBobpvBUgBz9UFWoSWLtyLG19MxiIcdNsbjSJnveC0n2sb80EUn4ajo76ZzKqzw/53641kcqJ9kh3idISWzNrAS6xvXV7wl0nPbPLRwj0dMQ6kMcSCI4uSEUV0BIZq/wVJJmkS3zaq05HjxiA4faetjxFY8nNbAUW2tIvNX2iQcmcNMU7lE9BcIFs/e63I3ucOoqSr5P6pnGBJ6le8YyyGLTDY5yAxZuTVYN6Bxn7F7B/XVAsJv52NhykBLeuJqYGZEtawgR/zZeDTgso3OLY+O5ZFWVpNGYpLjqb+tvJHkd9ZVPo3cQi5kj6c68aJ7cz050YDsOb20YcSFASbVb+2pXfVjjvBOmbwpK5wuf0F3Ztq5mYtyR0vKvX+rrtcmVuJLxepqTTi3NOZ4Jh0SJ2dVpqpC3FswVpRATRbW1uLCT14Hv25Y0NMd6Eb1eUZehg9rPQdHq6nVtzQy390Pr2b/+JSEPgJPCgYA8epGjSbriNzuQZoa4JteMRNNe0kcZUEoEATyOmk5RBHK3FZSk1DTr6hvnivc7+CWKyOgQ8XqWjFUIuPxve6LmNtCMX/IQyMGOJ9cEG9p8v2C65N0wngvaytJqXgPZvfCA8eT2CMbp1cZhrHVcJ3+vwMzA+TwHNOG1n+hDvPamrTwFyunMo7+VOEALEqG9jt8XOHAr/2WwlnlHxOJLShs0eFzl06jvc5VuaxRBTJCbU78sdNYMOTFo0MnII6mcMxOu5Uq4DKYXJmQHykmtZLzmUy8ov2z+zUgJqmwGsOP3MzCMKC/wvsLhjQdxfIHct25fQ81NOG7u1BDyhVyK3/U9Tb7SsnskS+SJEcd+ZfCS2LzDxeZQRFUrdam6wjBZ38oPpi84ehT0Fr6yihxODNOMs5DS4eS93ikaYa3WSSde9R+MFaXHGBCL7o+yqpOT6NWQ7An5sqxdzMyV5SKwzfJVNcw+55i0sqL4EM4PMTRUVF4KqSDm4ZluU4lYazWBAo+c9beGY0hIcTVRFPE4pFEdCw3i2To7Xvoy5ykruT6SLguhuIkAPhPcSlSbP2y2oE5+XPKRv0i7ejvSwPoSQLnGX4q+eng/+6ql0CqQFITz8GWXBMnJrh7vt9jbyqDixiNhJc/3Sjellq6R9vo5vKvgCrYC5UpSRt7+Ub0iTKHvXcqKds0ZYktRPEnRd55+HX5StXeeaSvpMqpO5GpYme1KRUHZKb30v68TehW9cV1R+07eXKLobTUmKiF49hAlpcTbTMmJ2vDvz5NnBbR/JbaZO1APGCbawTwCbhWApucosw+BPY/cbBKNPtlO7sk5v+Q8FmxrFKJw/6tk1lyWfttlCR8UzfTOZajyxDPLdqUiRaH1Eh2mBZ1gqC9ebFiCtMoSlbQaNrvFlIb0ELcUZ9DtswZe1BtS5JQGjv1RtbsaM2xq9Oiq1hXSdHIyl1WbMRcaT/7HbW2odJfyF0u/wEy3lVh2vb+2mFegDid6vV1kYX3qd8sknm3Pkz6ZC5ITZ/iD4iwGAATPUB/knepDohTz4WutM/6halDR9oW5PPvG5QA+1nEDU2CCCYEjcS3TNLtr3XcykFhCs61XIaZ+6xq5MifQtWpiUH5GT1RSm4YriVs2yvRNhoNaW0ggoKSG/za332/P+JGwNhz1J7Vt4BGirhWySBasfDwm1HPdb53a2lUTFIXyBAOm4s7Mm5XfRFGmKISb8UyHYK6BkNJ7sETqQqKogajAHnzLUVeNaVcHkDkr2EWk/esb82hKZozmPagOm0giu8md5qab3aE9I/HJM1V/YicAvzVH8DjG6vktd1witPRGGQ1AttPmqPoWG2H3Zi1VgCBY/HGAZhbMD84eiegtgsaGsFfcpefp4sMY2PpEqhFMUS0bJ3Y7d/UGtrn43CW6Ty87E3GKtjw4bef89LIwM/wwc5vDmSR8azo07P6RZ2M8V6SmEXEpFYQd6Zy+OdyCezgul+z7FtVztDeMalb+sC0c2npWJYoF6xZ6JU6qPjc0bZEKdQE4Ks5UmZbygfNzzlycU+NOjYU7coZvlUQtqUsOkEyEOM26zRNh2kg33leVD9vUR8vBWZv/18EyLETA1EjYanGkIabEs89JDm2y8dCG/zUMLT0kRHrPrkG4extyhyyGiNwZ1PsT4GAzatIDvIsZV1nbLKs3xnbqSOrsmEI0VuiEdzY8KDpJ+3306sahRj+gViV+tevGsGUN1NmlAgq3oiL5+N2eaPgdrFbkwYurwiOyP0fLrVbp5oE06eGQoAec1aj6JBTZWcII5XCKsArSnaqb3WlVxyst0L/1Y1qFX24kRPHme6HnfcnFytH0A+u4zpv4S8+DucV/5xWDyB+jdPcx9pieEK41NPgc9R6v+rlj/uc8K2oUBdgwkuEYPj7+FSArLlJQx247ab/cc081G1uJJteUPK47ADrZyJBUMJ/Aj+4LjMDzArdGdjqEZP4V3NrNJPksBoXK7/kx8gBr/4Efn9iuCs8w6nxDMD9G63ewx4fX4pmQP+gcHj37iEIHGJEEwqYBQomB1ZeTdc8fomXtPG8iJ7XykETqQFGOM+zy0C8zccyQOL67LChvbVmhgj4XbvlzoHaVHjNaXDWjXoM18g==", + "MIIWVDCCCOegAwIBAgIUSnoyhZkfRkcpLVASUAUX8UNeHUswDQYLYIZIAYb6a1AJAQgwRjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJTAjBgNVBAMMHGlkLU1MRFNBNjUtRUNEU0EtUDI1Ni1TSEE1MTIwHhcNMjUwNzIxMjMzMDA2WhcNMzUwNzIyMjMzMDA2WjBGMQ0wCwYDVQQKDARJRVRGMQ4wDAYDVQQLDAVMQU1QUzElMCMGA1UEAwwcaWQtTUxEU0E2NS1FQ0RTQS1QMjU2LVNIQTUxMjCCB/UwDQYLYIZIAYb6a1AJAQgDggfiAENd5HPtCQFluPCDeJCxpCThC249nNLdfYk6iQ5hSvYK7bGoelsCtqY7rzk8e0x466EvhRU2w418Yn6d/IQaG6bwVIAc/VBVqEli7cixtfTMYiHHTbG40iZ73gtJ9rG/NBFJ+Go6O+mcyqs8P+d+uNZHKifZId4nSElszawEusb11e8JdJz2zy0cI9HTEOpDHEgiOLkhFFdASGav8FSSZpEt82qtOR48YgOH2nrY8RWPJzWwFFtrSLzV9okHJnDTFO5RPQXCBbP3utyN7nDqKkq+T+qZxgSepXvGMshi0w2OcgMWbk1WDegcZ+xewf11QLCb+djYcpAS3riamBmRLWsIEf82Xg04LKNzi2PjuWRVlaTRmKS46m/rbyR5HfWVT6N3EIuZI+nOvGie3M9OdGA7Dm9tGHEhQEm1W/tqV31Y47wTpm8KSucLn9Bd2bauZmLckdLyr1/q67XJlbiS8Xqak04tzTmeCYdEidnVaaqQtxbMFaUQE0W1tbiwk9eB79uWNDTHehG9XlGXoYPaz0HR6up1bc0Mt/dD69m//iUhD4CTwoGAPHqRo0m64jc7kGaGuCbXjETTXtJHGVBKBAE8jppOUQRytxWUpNQ06+ob54r3O/glisjoEPF6loxVCLj8b3ui5jbQjF/yEMjBjifXBBvafL9guuTdMJ4L2srSal4D2b3wgPHk9gjG6dXGYax1XCd/r8DMwPk8BzThtZ/oQ7z2pq08BcrpzKO/lThACxKhvY7fFzhwK/9lsJZ5R8TiS0obNHhc5dOo73OVbmsUQUyQm1O/LHTWDDkxaNDJyCOpnDMTruVKuAymFyZkB8pJrWS85lMvKL9s/s1ICapsBrDj9zMwjCgv8L7C4Y0HcXyB3LduX0PNTThu7tQQ8oVcit/1PU2+0rJ7JEvkiRHHfmXwkti8w8XmUERVK3WpusIwWd/KD6YvOHoU9Ba+soocTgzTjLOQ0uHkvd4pGmGt1kknXvUfjBWlxxgQi+6PsqqTk+jVkOwJ+bKsXczMleUisM3yVTXMPueYtLKi+BDODzE0VFReCqkg5uGZblOJWGs1gQKPnPW3hmNISHE1URTxOKRRHQsN4tk6O176MucpK7k+ki4LobiJAD4T3EpUmz9stqBOflzykb9Iu3o70sD6EkC5xl+Kvnp4P/uqpdAqkBSE8/BllwTJya4e77fY28qg4sYjYSXP90o3pZaukfb6Obyr4Aq2AuVKUkbe/lG9Ikyh713KinbNGWJLUTxJ0Xeefh1+UrV3nmkr6TKqTuRqWJntSkVB2Sm99L+vE3oVvXFdUftO3lyi6G01JiohePYQJaXE20zJidrw78+TZwW0fyW2mTtQDxgm2sE8Am4VgKbnKLMPgT2P3GwSjT7ZTu7JOb/kPBZsaxSicP+rZNZcln7bZQkfFM30zmWo8sQzy3alIkWh9RIdpgWdYKgvXmxYgrTKEpW0Gja7xZSG9BC3FGfQ7bMGXtQbUuSUBo79UbW7GjNsavToqtYV0nRyMpdVmzEXGk/+x21tqHSX8hdLv8BMt5VYdr2/tphXoA4ner1dZGF96nfLJJ5tz5M+mQuSE2f4g+IsBgAEz1Af5J3qQ6IU8+FrrTP+oWpQ0faFuTz7xuUAPtZxA1NgggmBI3Et0zS7a913MpBYQrOtVyGmfusauTIn0LVqYlB+Rk9UUpuGK4lbNsr0TYaDWltIIKCkhv82t99vz/iRsDYc9Se1beARoq4VskgWrHw8JtRz3W+d2tpVExSF8gQDpuLOzJuV30RRpiiEm/FMh2CugZDSe7BE6kKiqIGowB58y1FXjWlXB5A5K9hFpP3rG/NoSmaM5j2oDptIIrvJneamm92hPSPxyTNVf2InAL81R/A4xur5LXdcIrT0RhkNQLbT5qj6Fhth92YtVYAgWPxxgGYWzA/OHonoLYLGhrBX3KXn6eLDGNj6RKoRTFEtGyd2O3f1Bra5+Nwluk8vOxNxirY8OG3n/PSyMDP8MHObw5kkfGs6NOz+kWdjPFekphFxKRWEHemcvjncgns4Lpfs+xbVc7Q3jGpW/rAtHNp6ViWKBesWeiVOqj43NG2RCnUBOCrOVJmW8oHzc85cnFPjTo2FO3KGb5VELalLDpBMhDjNus0TYdpIN95XlQ/b1EfLwVmb/9fBMixEwNRI2GpxpCGmxLPPSQ5tsvHQhv81DC09JER6z65BuHsbcocshojcGdT7E+BgM2rSA7yLGVdZ2yyrN8Z26kjq7JhCNFbohHc2PCg6Sft99OrGoUY/oFYlfrXrxrBlDdTZpQIKt6Ii+fjdnmj4HaxW5MGLq8Ijsj9Hy61W6eaBNOnhkKAHnNWo+iQU2VnCCOVwirAK0p2qm91pVccrLdC/9WNahV9uJETx5nuh533JxcrR9APruM6b+EvPg7nFf+cVg8gfo3T3MfaYnhCuNTT4HPUer/q5Y/7nPCtqFAXYMJLhGD4+/hUgKy5SUMduO2m/3HNPNRtbiSbXlDyuOwA62ciQVDCfwI/uC4zA8wK3RnY6hGT+FdzazST5LAaFyu/5MfIAa/+BH5/YrgrPMOp8QzA/Rut3sMeH1+KZkD/oHB49+4hCBxiRBMKmAUKJgdWXk3XPH6Jl7TxvIie18pBE6kBRjjPs8tAvM3HMkDi+uywob21ZoYI+F275c6B2lR4zWlw1o16DNfKjEjAQMA4GA1UdDwEB/wQEAwIHgDANBgtghkgBhvprUAkBCAOCDVYAkFUQgtxAwNABW4DGALmrlSY1X0WFTZHpo+tYCpH7/J0Rd+vE6rjJ3lFiaRh9tarxAVN2bToM3QV1cETMjS4rpkkVUMSjvcHreBixdeYGZAR4Us/cG/UjrOV3uB1R4DXbZH15rYB9DoeJJXc/Xbe4yJ5kuq4+cDDqTf+yLwVbIbH1moR/woAFmIxeI4xRF3vRsP31vsBJEjG5etA/Bs2JP/E7TuI4qNugGsr4+vW8F6Kzom5g+AvMoTyUR9ekSXMGRQ/45lzBUxwMMLfUrauWUjj22s57+WMMuErddV54RMZ0Ikmg1FSGfOz0lwIC2IFME/gTwhBMfrMnHKCF8E7fgOs0Nq9aBVQ2/UnHD6TisE0FHUy6XvJjnOJUPZ/dlCGuEpI95YyigfJHyRVDJhduwPvN8J0YAJ0I7SmG8eLp5UWs4P+WmxrSW/GnSkdKQ4iJgUEB5tvKHqcMLrazYu0hox+LBvPfd1mpSaBlFb9JeidzpctFnPnxtIPrsPHaV3q1Dt09NyctqnMaetW5H+naSL0OWr4NnR2NbPBPkcbdjnt2lbtaVSRtrKgXYB5rCHFqpoAsn31YllFE8i+b6UZQK1Q9GggCbryhHmeYPAV/dKjKGGl6dZdNrpGl7OWi9FrGAgoZ3v9Sc4+hzNHzTf2L8dcTFuyih1P/k0n5MQNsxGNjnt5K0JSM2pGLAQS4r+Nb7fBsgfrqFAWzh1GM2qiiEvcSn9j1KnA3VUY8k9+vrnXJZOjDCA0pbpLX4Qngop7sKHiRgWW1gaErUX33D4igDsGNV5sqNg8D1DDGA+EEvId+JTVcp5SBRWTpshWC5jXPfMrkM0JY1FBnT85gMAMpg1bTcuGSSLPGvq016n78EnyGsOeLUABGY1SWEcjyv/BaEJTPMGbwjMvieZw3LhWjusSKr8THOBSedJgapxcL39vky3ZrsvDoJO4sMzONZqyWO31lqk+VNpfvUCugjew38OWMTeh/GKggGZWfw/LaexsWfFVk2xQxAwa7/3QYsafyKmfVeLNx1Kn4w7ywn//M/mMT9pWbB++VFUxeur+sWn4kmM2I5dmIkMI2TK2XwaA3SrugSuSvohkDf3OD3gJx5l/f4PeVqU4o2ZHzFXYufvtRuVeGNY3f9e9NrhufqmIZAeWGyV8zWxREnWF6nNc9kR4VuvW1KUlQ2H9LJ9dEqYkkY/x903jZCGRjV/NH51I05tw5yDeNaNjq42ixPpjXzvhLgEizC4mbp80asQofezJ2a9kot/45epKCgmDSY96RfpRF+pEEr5yZjyOGNy1qoWuIhgG59vgnyAFt53iquOBvS/grLd4riwtngJrG5GE6F/OGhlI6/Qv0u7iovOeSESanxApzdv825YpQ8rB6ZvY760KaxSolLKXNMH50a1cz6fwV7kkq562mUmOdcKhGu56A4kQNT9KasURcQPiia/HuTKZP2hu9tSYK/6YIbCCtlb2Uc8ui1io36xcRJt2ik7kAl7c6LjqzPlr4yKev/Ve/e89T9V99E7sl1sL9IUytkl+dRWpNVzFEvWZEdheMzDdY+Dzr1WjYKBtYDTksW5EsMBZsp2qh45MDastSwr0yCe0iqj5IOjw8DjOzmGtK5eH+b3F6CshxQifYT5hNT1z0XmeXfBoo6S+74QE2tZJmvQ95akUojUNPe8zQk1xtoqRRHMwLdv1jgED4AqeSHI+T7yJIeUZ+0RN8dlXKWrYNwA6R99Wv5EUG5JagFbo4W8Nx92sL/DeLlduzxuazXSkAJ+9J/oymAC1MEZ+sxxZJff9E9zbImWup0N3Nsam8+svIAiGvMcPR0ZVmWDj/ixY790NbQWT6ZxmBESm0/hh/YrvJ/1xJUFTiX7WV8o9ewUsvqX+Y1RasDehwoR1efn+21OI5QMrLoltIfHIuM97ssUSKEEG4Fx6QGOUb/+57LvCcCT+Equ5Al7Dqaa93bjFrWMgPRWoNgaxVzJEHrhUTYrkfYPEc5SLdn1Zab6P42mqWSHSL6OK2VceW1INa8sfP12Y8g05rlf7cqu6uEcBPPCIyjuxIBg4bUwHa4CmqRVAdkOd2b5cApXVxIYWqdnMf2rLPx0OhnEnApck3nVzAW+gAJMtnDZHnXj1m34fnKISDM7Fq8Wb+WVfuaekq8DIeuRHmXopCtb8HukmZBz6aIJRWuV2B5pqBNwtREKT544wURXbFIL4GlCPQ7xzdeN0vTWgIrT8n0VIOtxq8XwERqhpBkKVdxUE3R5/v3srvPrby/dOl0YLvZQQjoptqnrcPpfXa5ahC35lSMxlWGdD7QalJ3wlTyLrIx5UN0z0nrO8rdw2M3n1+absdjEiJbfHZx6MDIw0vsWPXmpHhw2iWYmwQ7imELJzGBmVq2gKYYhyyE84gC3KXccv55ChUDsGs77kMycHcC6n3NgWtmRdshRFjk2JKdF+CLcCb03carPKNtgSvRi7Bc8MQL5IO5vMWn8mgm89ykjtZ9i/bkYIB0VDpU7hzVTnpw4ePuUUT+/RAGrJM5+7D8nmJlgqMxpK30VFENctlL5suviZRMpmvwf/Ii/5HmiAhJIwBCnjZ7YuMw/iF7Xwdc+G93kQ4h1+VTAvgz4MddurXd6XneNZY4lZDr7d7k5ZnaxngwmWYUI0g+kNqctv4alelDQYNiWIb8zFsoAOBZHzJnyuZApuHgTvZFhxep2DkJJL6n3hKD9UF+Gg5Rd/OeNx16jcP+Abzh47PCyrcojfveLDNhFSE8MXF0NiCy6amW9brf90/OCzKPtsbhIRzKUFLMQx3xl2jJsmik2kq2nvKcWuXDmC8TN3Vd2rq5WtVfOuycP4+cgVz50SvIIC+W9S8PzTZccV9MLTxBFRnXCLNOvTLaj9k/lDe4/IuWeNodI07Fndrro+AfFIzo2S8Eo+RbPTchYT/xmqdtYS7E6caSv0fpZAXldu9xZiPUP8nwHSGl149xM19366yvydNOXPIdmTiKVIgb3ZSm7k2Gqi8cbpCj1OF0DgDXKCvC22ji7uqLhc12jo2R9mfamOVR831B0v/44bjoE70xtZik/N2j9e4/M0Wh1K+DXxMkPg77CJPqYW7lpkQLm6RiOkboWLXAe38aU8K70Uco8ZtUaejneROO10nOiv6apceXsiae6Hmo6XjLaX2x83o0pga8ybyOpS8mM6tVyhgGr1xBXXcgUOx/6aux0rT/p5ZoabWbtFWAZUn+hnFVMIuHApiLVU/WUszL/ZbPYhdUGgTfUi5OYh4D7b6rSP4J4zsBYMAGkfXljWrbu/QA+hAprrZBDcPMmfSci58WNOdBYeVuejG+J8u2aICRjwTNkX2VRgPlRFLo7nNcG7A7HVk7/phqKx8S6bSthotRrTHoAiCFVfPne1pb4Kdu2ho12BfjnjOJZnPhpOgi1nN2jpdSUp7NyVepQW+YJDxrRYdWsdVBYZi7R36ZSC+4wm0UTrf+RYwSRECVySO7Wpk9674u/uySsVIlSJo6neCNJk2zXhOyq1e1jF8q3HdNE5RNFxaZKB/jLaSiZs+my+LgAwpCVRk0fLmr3KomjvNMLsLZrxIqeAU3SL339pTsEtWlSJ3ZT5BfGQuvwVSNwwskQDjaUitMLSjBNjLwg/wBtyy+OT3OddJc3goyZTVbYXZt5HFB8SqxUUOskaLv9g3GMt6nPnsGTlc2vxGkWTO8Hl4geWs2nVsPIoLnZY+agJhO3FeH+/bt013lmhRhk9TC0vPP316NbZrx18u7Z4CmgGfF6XA73hkcHwH8/aAhNGRd2FLvBYXsuigAtqBoSD8fg9wtFrW0C2XeXUQnT8Gq/R0hRdLJKv6MYYfgAJWbr+Bhw7iX44TrWuRS0pO443710JK3mzAbruFb7j/NoVLcD3C6fWMZEaTo6KjDO7933lKMnq6wz3ztD/OtPyJBE3hm/qgKXGCdLU3nHjYa9W6izSaYtRjGBal5IqrvOHO6DXdOofCtnTGLwLDqdeiJFinyxJyMmxkqHOumEF4ZxiEYclmc4ua1dtus3huJxE/E8lgAycE58HeQLG7T46oBSRLa9fpGs6gFDs36x85L+GtNhQyyF/Rbgpu56fc9NqcAE0KjZzPOeC9ZXe6dzo3QI95LVKPXdKpNtqiSV+hVN5OU76hBkvm0NsELbnZsts0926brwXDXrLEQc9/u+L59ce+565W7VdS4u2uqjTJXytSbuT3YME9CO01MzfGnrsP73zhB5qqbcAmhWJqP6rfIMcdvlUG/m/D5cd0P3M5K67TkMQ2NHi2hwKoz8Y91aC6S0MWe+4uBR4a+DqMaT6p/kdbF8nyJWrbD5mNmB4SFTAFHc8udweD3fE4o6qeniQ+euLZzoIUYECd/LyDQmlbgAN5e8zjEhZbiIq31dtinab9IlV1kJyj6V6MIXuRz9HzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFDREYGiAwRgIhAL+D4vDzcB3ZM/xvB3yxe9W4tnLOTEADX1C5ZNTSkcHRAiEAn6IRC5L8fjO/qRDVeI5zEFBUFi5Mnl3B0uou9NUzUoo=", + "NCfLco/gqZ46P6/5N4Ahw10pB0VjEju8zg0hgMtAzikwdwIBAQQgDoZCamJZUq/PovJ2AUb4AsvXIU3/DKqbnKFg/AIUIZmgCgYIKoZIzj0DAQehRANCAATCpgFCiYHVl5N1zx+iZe08byIntfKQROpAUY4z7PLQLzNxzJA4vrssKG9tWaGCPhdu+XOgdpUeM1pcNaNegzXy", + "MIGuAgEAMA0GC2CGSAGG+mtQCQEIBIGZNCfLco/gqZ46P6/5N4Ahw10pB0VjEju8zg0hgMtAzikwdwIBAQQgDoZCamJZUq/PovJ2AUb4AsvXIU3/DKqbnKFg/AIUIZmgCgYIKoZIzj0DAQehRANCAATCpgFCiYHVl5N1zx+iZe08byIntfKQROpAUY4z7PLQLzNxzJA4vrssKG9tWaGCPhdu+XOgdpUeM1pcNaNegzXy", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "izrNr4Xw2DTJSO+siSqINeSOEA/iZCOuH+bBGpRHQG+qz/Uosje5MIVqL8q8KBilAO8pA5p/gfi2JAcYYX8IjXC1Y0apa85dkQCfMtXiy8tvdN36REsOCQdsk5xsspbw7uEpxMnP80m0ka5mPT6L7w1I+3keJ0rW0ijCp5QOXGSOGnjvraPSCmR0T+3YN2rSSF7xEPztBaLVcfLubycWgSZRtxdwUBds4mTGdP7OtspmSn9N4qmQVl0eiJ9Ak2dq/fbrgUOkrQSWTGWB6GDEss0fDyxdwNqcsALmWBN9R2POKS/+nZKn51VyFpPs2VNQ4J8C7GhuYD7OjBbx+LfAA+EToYKG7BL8emoqNGPk6uulfbbDcGTXbTekqDdJYoEQA2NT14Lh/PB49zn8D5ldG/9805zYfqickXFhlXLD93v7pzMTWWmOXTMSpq9f6hcNERb8gPXC67oKyWyYNiTlFNr7qStSNBsja3hAkky/PUkgeWZ3kHaWU9xXEX9MH2zScN8sRzLXfxaPHp5r6aEajW4Ft0htIslnyAbg7SLJGM56CllzyVRd5vdfQEzQSGNnHWj+itwFLl73selRCQuzBuBSU9IVnwLwh16lpCS5YpqW5BRzNpw0Uy6QUuTLZe3nWw9cUJKJHJuyGTSJRBEAJDPaJIfmVmXtzHb8Ag4RqWZe+wxvgXvQeQt5YgJ1UbtuCR6XydzDqJE2DWwvlk4kCM0Ge+MccFmZaOFVvr9SJ0VXM+JOBXNUyU9d/wIa4+kNX9/JGoiqy8oNqFt6MT9MJRulx3AeDU5/P+kG7/CwFU3Cz5fNoKDVOyxLUJbV9uztIeK5iGTCuTzTJja/mSN1LZpwwvTG2JZKDa+SZjpK4GvkcGLyA4DcTmX7PgCFFnvmodV/ei9mNKH7VSfAp7Dxyo5TEszP65lQkLIzjxCex0w1rG4A8QbuQdsdUVZ0L4HZBtQj/DocGsCWN/hnVBds9RiVuWfdmRZt34MS3pcyPkgSQxScDVbfEPtlaYDxbL3oRc2vsfr7GDlBSI5cSCEbcm6929F4mg61CTjVr2zb1colrtFf9odrVmQc0H3U6UDhsmvIexe0o329dquwPWlprfR64ZBGb5l2RxLtZ9zwdlIzfJ83msE0fhoZxg6pCTdaGq7pCVR7YM2W+TirMs3QxBv/uktpV4UCdpZZjXVQ79Ohduc0/3T75H+rHQm6S6ijXwM/elWog/PWzYt72sTbup4lFrGUwQJPl5rzpJDJPwNkquDlW8xFxwA5nN4+Pq04CAAjKcBVT9x8Eu0/jOGyyYmeUTybqBtCPFtxHGsFpIMBqIDHgw6VGBiHza6eJR7ysUAWSC4jzVpvhIhJPq0o+vPKoB9FaXP9oNWi0U8TPtxyittLzwJuClN+GX13k1499vdMBaWwYNepCiVI2NoYjV/fecJKwqGBN4iADfT1BxAYEY1OixUrNeZfet1VZrNDkB0C6fNLv5LLyy7RfPyvtuw77ZCNKbfWzGu6PfHdBwWp80RFCMhpKCOUSYOwwKl7xQaKKQqs2F8Gp71tncUqJy5zC72niPiE+J7S5Q3u5i4ODGXmPd5bAbgqmGyQNm4TXYHnv3av6nWtsIJzsqrwwjve+pF+i5cE8T22f8lclesy6+eTpv6WyGHdugF9PYyzPGJdWrhN6w9aB3UXf0I/aCMwQvF8nEJ4vWYXX30MUVzGzdR2o2oW3/BDylrGHGTkMxHBQ2Rbh2xACvMnIr+D05krh8Qymx5PBy1b3K9yYrZhUNGuOELyqVKixFmg/ygeHI7LkQKHJ6/Be2UuZIvzbuYKchA7mhgZ8Dfki4gDzc6q5LGbzl0uqPycSNlvjbk5oYI3706tnV4YT08f2lEYYWwB9D0f3e0iaG8Z2PnrSjXtbG6raAx7h+gZ9FwbGj+Bt6yAnLGSAkkLArO+pEX+62dgxkjfh8iLyZH0pig5hmcs/a/V8hLz00vRDpPqaC79Eu+JY+C59uKALwWN0sL8OT8v4WNh+kth4Emifvf4l6Qx4vRs1AjlpK2RB1clMIY0HePRSAZg/P1HsqzuzbGLG6Af3afDIZlfmMvbuVQMBwz1uB1oFH8wsnHDQlfycC0IAb+NRKO4YBlCPM0+SCqF1A4aSHhersV2lef9btTlTFUGCAwXfm9NlZmpGf8I4pePU7Jv4vKwmi3+lbGd4NzxlIuCV1jeZ9fDOMpE/rLzji9xN7R4A28YPNzbwz8IS0ivcfIVKvai50xs/yoNiq1ctT5mWRxVxf3UyLw2GJFaaC+2HrFwlZIheWAspO/uExhAmuQTOOG1BGDf07puSsnk8zos5Dt+U+SdB/AJy5GvzrlIFH7maZdyHjw19PWTNEkm/vm07gtgrZ4rUhCT2V3tEr0w4iYD9/KZR9P+MsEuBONVbtaLmy+tzgG5fImrTsCl4B3ip7awvjkgg9Od7Uo1pVGYNm+GxuhGz9RRcJltlVCaemtbofODM3XDEcOgYqztJ1tetVazKXwHXTt7DVwivVa2KXx6c+PMofRmklPiuzN8PLJITqSdL0qz4SiDM66hiav9EcTVZJl+UqTAWcKNNefVq7ru4s0OfW07Su7mee/T3PLRqKLESlUnu4KMjuZtAjn4eUsR7jJfZKS+VeLOeM4v3dhaFYLrGNr95fGH8D6pVPkLUq4fMgqm070PRDIdMeMerbbL92+vHDklW8X2neMKIZUnNRtNk9dwfHF3o86FoBRdk5ar9R9P8ZK1qcnqYJ4obKD9bHJa83UsW4p99MCr465nyZXbuAxD6pwW13N7jifMJzKwzBwS49v3e4tzi8Ov3pEZE5oUEmgzcUzZ+zkVI6nvD6b1Trb9m8+JgzlVuUL1EE8yAoyUcUQe9UtU7kzd1scLdycRCtOKBIjGLEAcucDRVGtYbbujPcRFSsWNNRUm/wt2GWf0vumQfgvNOevQ/b5IvlelGjCikaYyYEygadyxg2qf87wW3Ltykltvq5Kyh1oxEljG2ujQlMpeGzDvmjbltNwo4e9VDQyUSrIXhLCdR9tcQ+zgeofVW2LpO2IrXa6lewgQ3qLnWV3yM2RF4gPw4z6c4vKrFTIDUO5UU1ZuY0f7sJ0WmM1FOxLwzsnbcKiT+QIP87Jkw3pPesTM5cDaRQAI/+VHD/QBY/+4bPg4kT52fPEnhSHrAHhk3IX8SOnIR7+31E3Q0GLD0xtcT9acEp7ybmtIyVTvrqjmEEa3A5skFh6r86PSvq1EFSLo9IxnQ8bcgziMW2/HqxlQphNaTxxjhfRvvP8BEV81NMjgMnlsi9qfydNELB3pXdqHpdbr19l7j0icGMJkCqhVrTETG2ngPkR1QMVy1NmNJW36y04f1eB0hXTJlcirgy85wqnAaecZqwB4Zw3GYHE89BQ/dlraEDqn0rh1EcAF6gBKIxywZ4miCQj1XNDCVJ/WYQJtLpnz76Lybu8But8Srb0Zh5X0YN8k5X8meKqYGEvHnB8U6Q/5Yq95ctqq/JcaeREmWXpxiezxUcPHxjve+zvDJyJMiasn0xBtZeOH/GLOQ9dTyaGHx/CMGDCtxXprXZcFrzPRtsgchisfr9ciF2U0cTDUchjZh0bai1O50zUQh9Z7P8DyjvcMnhGOD6PhJ4trv+539KYjLg6rAU3k+q98fOVwyWZibkT0TPk2uUwuebZzOBN7q1TBG2gaOuoE286ZseR0go/zK3W7jdgDWUKaYRarRfPVUBj3aj5yYY0pUYHxMLBFpVadlnfe1/cGOeWrbNbwRiktGIq1MldbJkkspOQTTj6D6ADjT9XZtAqA5D8wU1e1BMcr8h8iZNJ7x7iCl85uQRgW3lVC4z1l5BpQC3xQ/j82pdBINXI20jhbAKjJkzphMQhL6FJ/2K7kMKtdQegaS96d1KcxNRfxXuWNh8jtgzA9eBF/oBrUx6+UArcsuGpbOQbr6ElfGgGVzF4bnKHxsTItPS0dUehd032wQq4DajOU96z+KdS4Uq1kffV+JkjbmuRj/sd3+7FiJR6iMEwpB56drFiEHGwsuHJIdrO8O3+M5KupS7T2GaIDN+XwKLhxmOdKTEiNbsiYH6qRIjrc+pCvgCaxt1KieJ0Mj0WaZQiCRzZtPdrUzO7WEdajs4WXfEw4kJkfXvgNpmxpfFwMdemqzRnZSv2D2L3lUHDN4mjrA8daQ5RvC31UIUMAtH23QI9iZ9FTytJNy7qHRDZUgOP67+EETQJhJk98mC6SJAAzONvljSyPPVFy2hymHjmsGv1nmafllFNGo+EcMJZghTzBVhh6yUzYyf+KSsfUJVjKZP+/pShjsNc5edUCFpk1Pi+Ztn69V2BNi8jvDgUV1w1B3L5Dk3qLwoyzWDzLt0hvsGlPVUFGWrr1CzJ5xMYLLzseNr7P5A0ORl9kzOr0NWvP0dkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCg0SGh8wRQIgF17JPS8Wuf4C/TrYkXBeQDeQUpprIHoo9mKWMOcUveUCIQCFaRDxmsRxJVDiwpFw36Af7dqGaOf56FR5smGiYr71sw=="), + new("id-MLDSA65-ECDSA-P384-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384, + "4XGzcbdDodP67VE8k/dJ97+5ZHOUnJIRv/4yBVlNYDrxrZ6D/d4RPGVld9nTMMD9Qvc7zjX9Oag6w71C+xGKTFSvEdGNEtxB9dvasTpEeTkExN6hwc7mO5BmhDhr3NSrdA6jAqEloLXTZCahvpY7h1788WX2LnVC/dd8KZdb0NOTRfAzTw0QwXTRq/Jk2jqlnsKXiVjPDf0UlemdOKb5CXnAT9U1VlUWHPTIDkIzsHfLzgsSNgZpWZ83tSc10VatWptB6lv3RhVUexsdj3ElBVjyMn6EXnpq1RgzrnlxQuLN7uWj/usJcdKEmvYCWwnV5kWhaJpNrBTT4Lof4ZNrzqzmOB5HeCPyFqCqcOUK+KIfUCZEGjbRle8tT1PzWZsk8pB2OnD2lWM0gEPjN+mVI66uw8bxmZkxmDqRmoik9q0XOCWFqo6GonsVdKcSQVH8TqP3+0Zi3zCOk4ahfbjSMU4M53UnwObOhEAwnZqmQg9MVmnM1fi5NIXsnRIxQbtFeE4TmmfrKpA4uCzmLRXiTHpL0mmzlUG4oYhPa5qva10oriXTAluqAYgcRqJ0WQdKrKFMJfucIVsxr4jZCQsygk+Nm3Sk4wny6zxPNg7gkB6SQ0wqsgJ02lUkPTe8vw4cUq8PAOJ1wq+/P5lfvID+9bP+ir7/CD5PpjoMNXbSuq1vtUouQ9mmFhUR9rzlfnJhsifgwINPqtlKF17ZPR0p+q/ve4KzXan+j/0w1HFGFYP5t6qv8CGJUXUuDErrXowFJ33m4gyI2N46mTpoTPr22wbNDDCjkk3U1Og0U1CpcGiye6uNif9wYvfCzE7lb5MVMtwWsImsPLsAnzSk7McXhlf/aNlBWV54JigOzGhqDHXJ7FIvZT9ZwaKTZR3Qa0ghnnkywTsYdDj8X/KDQqpN0j9f1XJxinrWlIxW0vPUwTgtK/lr+0WyPdPmq4xU4rwcFgz9QWCSUXCT4cha8fmmTvm/WhvHZtakOgHFgH+VtNB0UT0IutVSSsEuwhSJn4YfA25klt66LCBZWJkAJMV7Os8wV6avdgz221HQF5tIZWttnLwlkG3XhbGE+qsh3V/tFlalUgDHfqHSV7nSMIE0eJc22ay91O8R+KG/W+cnVNQzCQuDQiFInxTh79ayO1bvn3oXBgvhorUNI1mG+KWSgBHuFcCAcyfFzhVsYnr48UDNV39wA4Vl49vhIn84Ex8EW50m6TXNy3ZKBl3H3sCfM3GeKBljS4lyNWJ/VcYoX4yW+nY2SSWLkWIg4QnEvb/YfDPNZef89/7JJYkVbGg4qQLeAeFNYpQ3UOBwRgrFR9/FLnis51DBnQ9RTQT/afSqWaNWdISufAuZjHhltvFbJVvcyQYUMO+HTPtpd3KIhS8CgFQn8NGooBAQc4K1DoRjwEHyvzbSFV4rD4I9yjWciVF7KJc169er9gRoherT5lZf/y7jvaZXdgb/5qGHschs3Kjg/JBseDhduWTc3TTX6HIESU7Zk6+6uSwdXHKCEUtyh1Hn/4uDv07bElPmn3srLEMnr7W+px96BVp/Pu4V2Ynw2OLSqyIKG15ztJRZllJW5NjURjWSBy52sZfroQzrc1vnmsA7+gTFPDwDeZSc3CYgVpff9rixFVpfyPsPP4duXWq2nuRhxPfSddZ5G1jjdQeTfcnCKh49HNL4nmZ8nJoFkdV9mJZNOC1ThxagOldg4d/LVlIfq5YS39+zWzi+Lr+U/mnpcvCkfRni6C8kHLmAfK8377SSd7AeooECdrtvWlhEEgkwgxisjTMovodQACuWHE7ctY0+cWyFJv1mj3PbJ3w37QVT6OzQOgkRgnRv9SzjlTcTDjpRGejpXJt6Ukn60QB8b3rbiM7YVX68ds6+TJRilpMqIMD6TvdPzU5s+GQUnDYYqJiKavzzChDgTZSzUQQY5XcZZqyqVwD6ei9WUiNeHdKyPw1HHHmgLFb8yFGXsn7pZkQzlSH4jeI4Ckw00IDg8am3QYF75HBU3+eQO8RpS3LTHZALL1RSGXHBFvwIIWDe5nwqKzWkBus/1sjNl83sLOt8D6Z9y9rD1+JnTjgB1C7qqw2yTjNAwy8AozpSXC1uAJJ0ZWuwgw+SOz8TH1IvUIbFE4LSUAiv/O7K1KrJ8DyIsjRXTSrMjHM1Om1MbfUYNROCaxu5MGABm/FKeyzxkXwvfXpar2/4z9W9b+7alwSHKNKvAKSSltNCGtkk3tlVomQlPUphMh8a6E6kHVYJ3EDTvuPMJMcDmd1lRdgDbl9Xxde7MCFQ8jewfzMdJ+bbFgXI7XQBIjRG60RdGLVcM7gsPXfMCeZRLfrDU9t8QhRp7Kc754RWg+kEUa2ttUCVZOfSBwlKW0d2YapCfLm+EXDhtB+muHp9UrRF6dcpGrHLpN+BCC/NXGVxoBsCeYE9+/mnhTTeuXRYN17DIL4dneS3bkQbrksEIDANat2V784kIgogOaSOkxQkMo3xWug0pU/XCRmhihX78RGQDyDLhg5YokbWvcYqpT3c/NikynHF64pTXXLEOi0HjQKUUPa4lceqaoxHYAXGNtZbLOnogJYF9iwI6lsXCXwlRIcohnCViQosbHhY5IgEGo/g9RgXPDT54ebJZm/egI69KnXObQObFZvK9bbRcwoLmQHIpiuw3fVkxOUcnQTyzWSdcUrqZ/Ddz436GFS2ndJ/OtK4Ba8tlNTCB3q2tKQkQPtuHVcfMfTt1QffKRtO", + "MIIWkjCCCQegAwIBAgIUclGc8SKf02aeKzuc3Rbyzy8WY0YwDQYLYIZIAYb6a1AJAQkwRjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJTAjBgNVBAMMHGlkLU1MRFNBNjUtRUNEU0EtUDM4NC1TSEE1MTIwHhcNMjUwNzIxMjMzMDA2WhcNMzUwNzIyMjMzMDA2WjBGMQ0wCwYDVQQKDARJRVRGMQ4wDAYDVQQLDAVMQU1QUzElMCMGA1UEAwwcaWQtTUxEU0E2NS1FQ0RTQS1QMzg0LVNIQTUxMjCCCBUwDQYLYIZIAYb6a1AJAQkDgggCAOFxs3G3Q6HT+u1RPJP3Sfe/uWRzlJySEb/+MgVZTWA68a2eg/3eETxlZXfZ0zDA/UL3O841/TmoOsO9QvsRikxUrxHRjRLcQfXb2rE6RHk5BMTeocHO5juQZoQ4a9zUq3QOowKhJaC102Qmob6WO4de/PFl9i51Qv3XfCmXW9DTk0XwM08NEMF00avyZNo6pZ7Cl4lYzw39FJXpnTim+Ql5wE/VNVZVFhz0yA5CM7B3y84LEjYGaVmfN7UnNdFWrVqbQepb90YVVHsbHY9xJQVY8jJ+hF56atUYM655cULize7lo/7rCXHShJr2AlsJ1eZFoWiaTawU0+C6H+GTa86s5jgeR3gj8hagqnDlCviiH1AmRBo20ZXvLU9T81mbJPKQdjpw9pVjNIBD4zfplSOursPG8ZmZMZg6kZqIpPatFzglhaqOhqJ7FXSnEkFR/E6j9/tGYt8wjpOGoX240jFODOd1J8DmzoRAMJ2apkIPTFZpzNX4uTSF7J0SMUG7RXhOE5pn6yqQOLgs5i0V4kx6S9Jps5VBuKGIT2uar2tdKK4l0wJbqgGIHEaidFkHSqyhTCX7nCFbMa+I2QkLMoJPjZt0pOMJ8us8TzYO4JAekkNMKrICdNpVJD03vL8OHFKvDwDidcKvvz+ZX7yA/vWz/oq+/wg+T6Y6DDV20rqtb7VKLkPZphYVEfa85X5yYbIn4MCDT6rZShde2T0dKfqv73uCs12p/o/9MNRxRhWD+beqr/AhiVF1LgxK616MBSd95uIMiNjeOpk6aEz69tsGzQwwo5JN1NToNFNQqXBosnurjYn/cGL3wsxO5W+TFTLcFrCJrDy7AJ80pOzHF4ZX/2jZQVleeCYoDsxoagx1yexSL2U/WcGik2Ud0GtIIZ55MsE7GHQ4/F/yg0KqTdI/X9VycYp61pSMVtLz1ME4LSv5a/tFsj3T5quMVOK8HBYM/UFgklFwk+HIWvH5pk75v1obx2bWpDoBxYB/lbTQdFE9CLrVUkrBLsIUiZ+GHwNuZJbeuiwgWViZACTFezrPMFemr3YM9ttR0BebSGVrbZy8JZBt14WxhPqrId1f7RZWpVIAx36h0le50jCBNHiXNtmsvdTvEfihv1vnJ1TUMwkLg0IhSJ8U4e/WsjtW7596FwYL4aK1DSNZhvilkoAR7hXAgHMnxc4VbGJ6+PFAzVd/cAOFZePb4SJ/OBMfBFudJuk1zct2SgZdx97AnzNxnigZY0uJcjVif1XGKF+Mlvp2Nkkli5FiIOEJxL2/2HwzzWXn/Pf+ySWJFWxoOKkC3gHhTWKUN1DgcEYKxUffxS54rOdQwZ0PUU0E/2n0qlmjVnSErnwLmYx4ZbbxWyVb3MkGFDDvh0z7aXdyiIUvAoBUJ/DRqKAQEHOCtQ6EY8BB8r820hVeKw+CPco1nIlReyiXNevXq/YEaIXq0+ZWX/8u472mV3YG/+ahh7HIbNyo4PyQbHg4Xblk3N001+hyBElO2ZOvurksHVxyghFLcodR5/+Lg79O2xJT5p97KyxDJ6+1vqcfegVafz7uFdmJ8Nji0qsiChtec7SUWZZSVuTY1EY1kgcudrGX66EM63Nb55rAO/oExTw8A3mUnNwmIFaX3/a4sRVaX8j7Dz+Hbl1qtp7kYcT30nXWeRtY43UHk33JwioePRzS+J5mfJyaBZHVfZiWTTgtU4cWoDpXYOHfy1ZSH6uWEt/fs1s4vi6/lP5p6XLwpH0Z4ugvJBy5gHyvN++0knewHqKBAna7b1pYRBIJMIMYrI0zKL6HUAArlhxO3LWNPnFshSb9Zo9z2yd8N+0FU+js0DoJEYJ0b/Us45U3Ew46URno6VybelJJ+tEAfG9624jO2FV+vHbOvkyUYpaTKiDA+k73T81ObPhkFJw2GKiYimr88woQ4E2Us1EEGOV3GWasqlcA+novVlIjXh3Ssj8NRxx5oCxW/MhRl7J+6WZEM5Uh+I3iOApMNNCA4PGpt0GBe+RwVN/nkDvEaUty0x2QCy9UUhlxwRb8CCFg3uZ8Kis1pAbrP9bIzZfN7CzrfA+mfcvaw9fiZ044AdQu6qsNsk4zQMMvAKM6UlwtbgCSdGVrsIMPkjs/Ex9SL1CGxROC0lAIr/zuytSqyfA8iLI0V00qzIxzNTptTG31GDUTgmsbuTBgAZvxSnss8ZF8L316Wq9v+M/VvW/u2pcEhyjSrwCkkpbTQhrZJN7ZVaJkJT1KYTIfGuhOpB1WCdxA077jzCTHA5ndZUXYA25fV8XXuzAhUPI3sH8zHSfm2xYFyO10ASI0RutEXRi1XDO4LD13zAnmUS36w1PbfEIUaeynO+eEVoPpBFGtrbVAlWTn0gcJSltHdmGqQny5vhFw4bQfprh6fVK0RenXKRqxy6TfgQgvzVxlcaAbAnmBPfv5p4U03rl0WDdewyC+HZ3kt25EG65LBCAwDWrdle/OJCIKIDmkjpMUJDKN8VroNKVP1wkZoYoV+/ERkA8gy4YOWKJG1r3GKqU93PzYpMpxxeuKU11yxDotB40ClFD2uJXHqmqMR2AFxjbWWyzp6ICWBfYsCOpbFwl8JUSHKIZwlYkKLGx4WOSIBBqP4PUYFzw0+eHmyWZv3oCOvSp1zm0DmxWbyvW20XMKC5kByKYrsN31ZMTlHJ0E8s1knXFK6mfw3c+N+hhUtp3SfzrSuAWvLZTUwgd6trSkJED7bh1XHzH07dUH3ykbTqMSMBAwDgYDVR0PAQH/BAQDAgeAMA0GC2CGSAGG+mtQCQEJA4INdAAqabsBMZYSvKqhPutnJ/6+cI0/rzyhz8eTBkUPLAGg+efS+ZP4vrM5OvvGH5FKZ89Hm/LtSboQwPGBG99TvobDpik/vWFOf6HCLKB4e0MgsnfiGgUilkZh3lATv15AyPQ8lmghZClrHkOA18qiD+7VZ+3jzjEDF84YMRmCZgDBy3HHRAqQohfcliGWE3Wjs1HMJBMYP7JWf3bwbjoa30RUIvVwH+5QpbUqKDeZH/UXRpEm5IYQstKx3v/aoLJ7DJIMoVoq8y06tQlG6mi1mMlhIg7XUoqruxY3GUDQ/nhIUcSmdJzlaU4pVsb0TkOltjA+YDciGwi82KcYglOYvRK3UE/Vp7gSxmUfINSrqjNa4mN+Rf4uGfixFE0//egGbwTqN/biIPvJNxvQipBeduuKFGOjIkBs9K1ZJvKcMaX32aqu/M85awTIneb2Bs9NjjkyeHXeTe07qE4k1+KBPXyrgeYcZ4KeDl//kImcWfL8YQGHOPVjdZMPgbqH9oMqWP2z9cH4tAovBEG2nVTIDjqKomJA7JYUa+2qIb7ifuFW0u38DJDFdkoQV9EIVrgwMdCTnB17RafDLqVosBEOdXfMigT2eDKecpRw4JXelpgR86Sc+3l3iuASyTcqTL/VC9aJd84XPgXIfyt6xkZ5tKPX9a4cFheeTQKL2CxO15h/xtaVHFKEnCil7DXLvRYGGOeJ0ADwXJfD6YuJijXaJDLzWy/I48m9/M/pBaFewdpH7vQm8RkR5A1eXPaV5mXuY+QOHQtFk4xnTFMwNmFTcdhkyIedDkYvgeXQUWf9k8VmB2e5mRxJvOxWWFNJ/lywRlDhnXhpiYBCTjkWoGgFunGgQOWnP3DKIg9NgQSKZ3IjaSuvv3xQkb8FZyI1HViMoJa6brUaJ1aCLr7p73ffh0xT8d2cVqUFo4EUFwhibCXUUYK7SJsxOAh0C5Aiak1r9NkCcjNziz71uidxCFA9u+8eHzBwctoa+ry/y1W27zkt3+pfzuKLpmAZwBd2EznWZs1OkxrIk8gb8q4rVnVa6gRh0pDsm91nmpd/EKUiedeRlrwzFn/gMrSgftpEjmZZLkHDYk8IYFwGxj3ceCFPlN08FzmfaQIzC5BR+doqEHIbdGxE7bQL6lQX0JY0j1k2xSyODUwEY4DumNeyD097Km/yjaMXdTALulhubpMItd7irsuQ2bu6owcJRnE//dWC/OMbCpmUJNO0ebxRVu71WxDF4x/lEUdqXRhMd/24LhQIULCXnX3QmwimjReY8HbrUVkQF+/wSiSqGzdCtml5X06GyoIPcVqpiiEjP99WYRGMGBFrMjeTxsnu7XBZ+TE9nskKw8AlBouIJ/9hkkdo/Nm4yzCqdIKpi7GDdRSEC1H7HV/ThR6/5Q03R02GlgBiNe0c/E8E4MFaqNssWaRubM7tsV9vC7B8hmyovP5p3SfNQ00AHPd+kBcPh+2zwvB9Vqv/1LDgx8hrb7x/gwLRoqAkPL/1g/aLhOlzp1KEcQ0pBhgx7aWo7yiWvrm4Sid/X8IspJdWigevQTRKZJJTzk4k2d+uaZkIAehU6GTan4/gRuz6V1hBb4BNgV71OQ/A7NNRA/PGcbmZY+FKal+gHHsNoCfWhifC6Zvc2gjLBKyLzq0Y01qWR4Cu0+H9s1kqfceyzadxLPzz76+T2QiZRuraYE2JbLmgf8ybJEwoylB9AyOxlYU/ixjwLyDSeb4jnX0JIGmjVFEZ5ytOZ/R3jMgmmH5vmzUCJG6dSq5JrjfTAHpOG4mZe99AVQJCzt8v8YJ3WMTRG4FnpBIpjU3Wg+c0VMstlxc2iTyrtijWztQnU+fBNW7XnhDxzGPc70URMmDuv4vnVCs5hDHfUpZkvXUksNWjTOvowrStK9y4nU87joUzB9iA7fhzLCFbnS9jZAoZa4bAzlBZcY/Yt9cXfGHV+J/nbSFu7cxFz7KENFYXdJMb26t6doFG5QntR/SogHQzmBYSOQoyL6nqPwR8CKb5A67PM8Ezlt99PBH7JN83t8ZSlPYRYNk7qj/0KzKxfyW7ffn+qOQgRSwJrsWPOyFWtHKXn8+ykgUu+zrsuvS4RsvthXxeyjFIA/xaM/MEJjos1/WO/U5hgW6F50LJ8c+QdIyRgOQ6620L4Adc8ivW7L+KWF6pJrzBdjx7pdb7QAF6X5oCs2mRHAQI7l1fgtn+zGU/beVDecvu0AFnfUgosZyawXvfG08u6oQjJZsgHjK8UZIfZRjElXttWZyN79y6Ys60lWyplXfbFjlRyCQFCr0KC0uyitahOi3EUTK9REgXcOUS+8vxC79trcPu/g/XBI5RdfTFWD/DeLtWjlzEQ3hf/1SmLs3g89wPUuw0+XMpId13IpH0tW82HHOMqW+9mtrmAk1o/EjYnZbzoZJ7CxLQhLZmE+hKeyYmlT3L7Zal25eK3/lpdpY7FgYp0VeUDsyGRK3MbiTa0Iiah5CMS8y81TQfuojxrpS+SqWW2iVL0PuYlA+JVSKucZiiHJl1OM5t2FS97zNcg/6JYX0tYoMd1KG3rVmyH3eOeDICshSv4S6g7azVRNVdyLfvNvgBecQvNnsC/ZVuyEVCTxIWfvtMTQSt97csm/zWrxG+nXWd/Z3crSCIRchkFwZl6cgxWV7j8VP5PCsrTc9+rHt8Rcu7hRYocwF4A9hNviwY2Y92A59bv6B7fwACHCEXmXr+aUGrB/LYOXR7L8wv/MJaSRITOnJFlafz0/9Ckq2ScDnQvxP6izYD9E3lrS1pccMxf0oItcPTLs+8WktwnFa0ccyF6QdDraeug1oOrywq+SR4ebmG6veMsqnjRdZEVGOYDOUB+gKIwv4lr2zpCPOgeM8RnD/mCXmffJGkQIpSh5GqKna5DlPfzxX0Q6cnxIUAyNeSXCM1xdHa9KfgxQe+3a9+kpJSGAHrykW1dKSTMQ3ZUy9S+ZYF7XbOqVzJJWbSCWLklhHYsbKVsUf+d9D22LK9wx23+87Q4jvwM89pGj3wMjPjI8bNjKift9LrKA2TnZO9aykGL2m/xWN5pVDVLY5cM88GCaco0Swp/VzEcSIkQ6SB7o+PqnCUGdUQSaxizssZO8tCw7FQf8DkIE0Wm2h5hP34ikuLsa0dR2O7vEH40n0cI8I6V347lUEMuFDrDQETf+Hiu4gBOTZUDjVlv+ZfhyUUBiIl2AywP3uGB8WlBBXPWtYoaBKLLbmWDuOcjlQF45sT11JKmU2Vi4KDbMa+/eq1SUtCKFL+vEda2wbgSz5G33/Lx8VYSdKvbZcEVZ55ICI7cunzDGWCftbYu1k+QwcNlk37cj85/ocrJMsES1yQUgx/TDmf+9GfWXnqBDqjbKY1uUBXCT5aOg623ezsd+XnkXUc5JGHtvYeK8ZHbQZx31whfum7qHLnGjANwcj9H+v1EhocftQ+meJJ7ZtOlYZkPX0PFzsxiSRU6cV6ZXZizf0pvC04+kdRVPqEupFxwFWoRoNk+f0olb4jfx956+6nExTiNBRGU3SdUKw4fyoLAf6Z3pelkJ9P/Ti1qEYPmk9OVGT4+7WOXcTgBdt3A4F/+/MTQ50GAiCN1KFMq1g/IDA7T11Se3WaE5sRpiXthNocDLYqBPcrLSvLW8CXUPsiw4fmFEPa6H0T5Tem2uIXZhTdEJQJ5GjkBtexlXfSD+vSseV7/yoI2qYnsViOPoZS0i7pETYjVTVj/qblzOMWuMBZZMz86hwwOhZZRwz0vslcsoGfGM8PzkLnP98Jut/7BWws/Rysmt798pByzN1exMyK1Ul1vrNVpm2QhZ38oQjR41eBL3zWGg3EGwHjko2jnUmZdnBbgu0g6BvrwEHsVZwzToYTO+G9S57yDIbLODofVLVm6yrj2y0/WjXG5f4R5rKXpmtAG+eVW23h63rN0hKhtg4+GIJlxMJO+EmjWn3cyOsRebAQDgEcqfPLvLB/cde8E/9jM3ea/ic/VYTrYY+PrWsQgETg2PnE2nJjy3MwtxfXRLVnOhH3+GNb+TNTNYQsqxeq3YbzVJD7NCAqNad/ytZkjMzrOrXZ14aRsaHb45+F6eVk1dHeM0xsTN9KIx27z3IREk42ozLctGlo1jqW2RRYB32105S0VMSM/dJa0Qnc61ze1ACPXPJwCqMXXsl1SLaRs7shlnhR7Q/ENxVsD41Jgv7HNwc88h2ZGHn1Fok5tOpUoyygXo49rvvLSSCvvdlkmfTRMCMrp84HQKUuOTb1c1qehG9QAWDPtbnYjC5EQqTGcM6KIVYZAk1tD5wvCaiJNKwO/X5eJKo/RbCRy2+phaKofB3qhg51GI2dqc7n1eBPcYrqFYyzYRw5UUAHhnWeo22nLUw76nfn0+vd7ErWsUyHjn7RAxg1OjtDSlVhkdfj9zA7n/8lLp2p4PUcK4+QlaoPTXizuLmSztLjAAAAAAAAAAAAAAAAAAAAAA0RFx0jJzBkAjB6EsyoY0a8HV7WycjYhv7XhLjoVHmlEKc9fbVTqswOYhQEWj/RUJeGGiStS0i7JXACMCcXoajCM2IT8P16E5T1lM0w4AvrWkbZjpDWULGzDzQ/1ddSss3u2UWeBvCkkfkb8Q==", + "e3IyGp0WElVU+7OAaklWy+mbiRynawDKVfkVSxb+TMQwgaQCAQEEMJw6GVddqcWsaJ7s6SWhzOeo1w8YcA/pOoiElFObuUBzeZ3ks6DqDiTu/IORlXCHJ6AHBgUrgQQAIqFkA2IABBqP4PUYFzw0+eHmyWZv3oCOvSp1zm0DmxWbyvW20XMKC5kByKYrsN31ZMTlHJ0E8s1knXFK6mfw3c+N+hhUtp3SfzrSuAWvLZTUwgd6trSkJED7bh1XHzH07dUH3ykbTg==", + "MIHcAgEAMA0GC2CGSAGG+mtQCQEJBIHHe3IyGp0WElVU+7OAaklWy+mbiRynawDKVfkVSxb+TMQwgaQCAQEEMJw6GVddqcWsaJ7s6SWhzOeo1w8YcA/pOoiElFObuUBzeZ3ks6DqDiTu/IORlXCHJ6AHBgUrgQQAIqFkA2IABBqP4PUYFzw0+eHmyWZv3oCOvSp1zm0DmxWbyvW20XMKC5kByKYrsN31ZMTlHJ0E8s1knXFK6mfw3c+N+hhUtp3SfzrSuAWvLZTUwgd6trSkJED7bh1XHzH07dUH3ykbTg==", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "yg7WmFq1nj9oUG+dMDlsIB4BeQbFyH/ziFSkJrO7rQCEPIxM9WQsMUZG1OFHqbga4YK4qesH4efHX+t9eCwwYclXG6byicURcaQtc2WwC0Z181a4kY2tLrAfo40wMeNr7v39z8VqPdG5FocH4NIQehBEQ9PooszVyCaPze970rCfut0uUX3O1rQKt6+qQnpsBzEPGvfNwqz0Plu3UEf5Q2U5QCIIn04xLOTUMploYaONgiZR0QQ306Zb4EXUPIuAt4oL4PokyFey55cStR6tJw9tQgYYWEc/hXi2qN/hyk2GybAJV8Tyl3AMae5hkOiWZ2uVNNTI7YFehJHEJsqdXMMOUdPIMAQ5YZLW4znCwgRny0gQDuOsB+tSTkSL09Mm+yEiUzOh7fQat/cxbqW0FBBqsiql7qiSFIoTgO0FBhghLEKzYglQ4s+j9wd1UZ/gHbNAY87t6zMNYynQvexsacoVK1GsBhJ++QbnRl/dDE5VK3+ahPpZEgRGemb6t87H/9a5LO/6kNUdY4wMF1O/GTOwGZnQKayeQvqJnbOiIl9pHLZ5leFBWm6WxHCZeV78xJxIiW9w11cV6P9QpL97FzAYPRntoN8fDpszGMY6MoSsGetoih4dBdV9X7CjTa+DJo0GtpkLbtrasFL+UrsoqG2Q4Ny2WUNYkvm+4oxKvPgvyPGf7Opl1ywjj7ynxAKVwfP5iRruWXcrOhsIMnZeh1hRV76P1OG3taE0TENKMDZw0ywutEylzioy2p9Hto+Zg7EI601icLo6GeONdpw7pJTgMPgcyqV7f34gH1x8qT6NIbRaoDrpKLuJKkNh8H9avE711pCCxsmh/x5f7EA7fPJ0/JQYUSykjhdyUpjRvDZV9gVbB7qP6Dvkk9hBJniXqTzWpS1GjZoeUKXHGU9Egnii9TIEPs3pXQ1KjimTl6m93OkdZwCwDcmoIn8FN63D8HDVxVsNjZfvGBAoCbg1C2w57CWJ5z2XlYRiJMHDKga/5zWZ5fihW4ahYJNspWd2yyDze9uoz9ZEUs0PzGA57dtJBsjWpohVgLOTBwglUZJ3izg16Qsa0lyGv7QbfW8dIRv6hleLY6exoRoNvv2RuVPfuuLa8JYYRc6LILKdYFQqvwBQi285mAhpeY5Ui9t+i8LO0Esz1SGzR6K4FmmVxWzooaob79YTIdqR5h0M/Qao8mw9fqs/gdolCZ8BuVEMNQLkqEdgKoldga14G1GE5fKysDo6pmWy+YX+HsyBLn0enU9inVBuNaL2X99CzDdCpIAHOS/vpk81fGsAtQAy8huzlkG+mgBG7qMaOI0dOtR1QyNq9EdlX2BCnkvSi9+ZIel0wanL2bRDXpBmcxE2eXmGn9Q/hTMBLlbsvUARPLqNr6zzAsWjxQsTptCvgN48VsPNza8HWTmcarpqCGde09p6uE2U7D5okEmBmzRupMGK41JaSNNVW1k/Mb1AgwWVZA7nCOFwXN+Ynv8etdu/3EDCPChbmSVlOjc0KFf1o32+8jrclr1SRmwxM7EUHvj2gmuGVNnJMRAmYNkgbCPo7dWWEedypS7dLIdqjI0ShhP3EFFxc9ZeZ/OKxKC85cGdtQxuvYQanfTl4ELSWavWlU39dA3xZlNiXSLqt9tYwemtUZfyxih8NrwNuFP1RSWJ5E558FTGJIAVE7gL+aHe3CPJbNcMYm7C7WOyvJV3rhY0ctcDeJxLLwX9q8AlPcZ4kF9L8jsXrGAt7ghM8JiZcLFUetYGJ1ZmoUabeXtY/uPopHEMH0tszCWZvtMzEUpH8PlvQKC1E/I0emYvMklrJXPFmAZii3usvVyy+7ngGmcc3Rik0shcoPLsAoXuC3hx1fyQ4GGER6PwIjjwcxLp0H8kVvUDCUEbbnbQOhnZyCEKOncrsqtR0d6invh8f+T+1RS+VQ/FeD1PjJMkkh+euK5FrZsZJthfh+0lw2mdtY3sAEhacjUdvbc8McrOmRB9xZwp0Lmweml8lSVBwoFgltikaGbV66u7Xjnn9eXIhUXXLmHdB/ZsUHDJt/WdFo8k6j/IqUsBKTsLyx/bgHLaC7461eYbl+ncVKwhEF/ra6rPJ5oekn9XQGv+et8NKkcV9IW9xYB8Keb3lo/gjs+mYDHwHa7mXAtsuLKqsIdCns9vjyvcj2R/Yqa4NlvxWv6CCTkJN205kDTAm86yl49OIUFpxOCx6kHJa8fGfWMCzXWuea3tDp4lZyZ43KkuyxENqKAXTYnR1vVzk98zB0Ikx0XZSZr5Q/pht3cXLU6BuIb/L46GntlmMPFCten0myT6+sqxnKNEuXA7vPR2e+BhnnPFGZBFMO5i4NzpUGnfvTDtGUwZAQYVW5NSIavddSO2WiPK4lOgNsca280NF3Jcp4o23m6K9GRBS8CLHwXZdRvymIO2lEgOh0f7avPZe/Xq2cLEE6QJ9pE0FDpR6PMpOM8km0T49m204WztH6j83I8pyq+AgbbRiwRRigqQE34DdqCjw3UfleJgpmHbRn56twMgYi9CBg/HwfjdHNbetveeCz/AfWGFH0SN/sA/89VG/IW7lWy4msEw+6xCenVQKFcFsIQaJXHyLqK2eJrhdPeCW4WUPz2eWI7az4pxY/IZFUrDCVXk9wwNNwR31x6+7Vp/b2+Vm2VZRfP+Q0fCHIze2hMLVUqMJOPavOejBOunv4RyvqZNGYJdaKBDTNOwu+OPCE21TDvOh40qKDEfuxkB0KvViIlq58i75eyKwYA3vDja/KrTOAn7aAg86c0iLhMm/BSt2MQrdWfN2bgST2bBakO2WSM0TJqB83JYlIwfLMp/pmWftfTGggp2hhVOMNqFjO6K0QKpyyhQzYzm4f9q/QM4d8r72QoQiYhmuvM6vgkSMJXKTyeYHHMz+MUmXQK4jCUmeSpGXs1iqjezUkool4OA+F+Rk110xRIAf6JMJMbqmtC1a4aSsGHK+fv6F0OZwtkne3FNN6cEIQdgQZ24vK2eddcrFahtTF3b4J9FkA2s321qUGcphcVtPuGzPVRpyKt2wWaLNyiQXdWny+gdggZsRRDGoBls4xoIYBx9FBGRKGjgezZdZhGXn5TinO0feZOcSpyOw+zYwAPPpqDojhp7WBVn+FfAA1EZSXIYGbMD5ykiHC1CKunEEKGuNCwuH0yqi1/3W49QA5SM+yBszV3Y5+69oKuCVJJIuNYafVVBJcQHDuQbixeyel1u3v9ZWLlf406O5Vfhgm1SOJvhJAunVVBl7RmulPSWVveiyzoOt8abPsiku/aAE+TQ9nLm0NngmqP0NZbl3P5ueEu32hj57AxvX6V2qTFiXuYDg8xNaOk5q0Bs0+rA63hBE6IPSwoxf0YlscPA6jOklyaXA2n70SJWNJ0VfDKtBzuYAdj9KHVvWJq26LLnirfH/3/ezB/KtJ34MBrLsbCEK0mQPdTMEq+TGZWC+m3dOpszKJk2eYeajnJTYqTEi2rHTTdT2V7UHGHrmeeGfZyAUlD07iYjqz1u3Tl5dsLn9ZHDZSaJdJXr9EmXU11PcEnK+Ue4bD8Q5dmPbD7U8e95uixDjUgf311SBloLZtfo+weVmciC77YnbNjpsRroaC20cgOKn9SP8qGOZoJ8Syi4Y+78E60L+RFohLiWYUfCkIz5Y4/vR31T63QWnvZeSzUwh1rw4iEyqM2l4LNhHKOuPkUnzf3sVZi36dmthUU8MI0zCnzDs1v9aGN585UBuY0GQMY5d+DcLXu2QAwG9e8ekxZ+tHXEZ9Xa7Id1H2HhAEMG3SENNV9dJGKitSpFo5ycPx+a2BEOT0gT0+F++g07cT3lLNThRycLNOkmqTV4cF6UtTp7R0WsGYEJYypzHoFjmlgGICTwGwFel4NwX5oa5takcfE4GD0EIkNEgWoEc5l6ALYsFg3lW3EThpSxn7pqJpXWZ9rgqCD8gp/cArRIz8iBr3jXNuKLRfXoKZJJXlp7Ur88TQ/rTueF7c5SQmZj2vVF+eQRGAukScC83I2AgqNIV37OeEpho1HQyPbI8cGp6gtc+k4BlOgfSHQ8m48XYYqPkV/ydFOO9Nrc5752eTHzKq5lebOA1GW3GNo4xh7IrhHIRiVHfDMYWLXwgPCBRYSZrna27WduPaJ6lyS4oL/maYbt9okh5S3XxTjcAkKf3dlTyCkHIdtYWcBWmJ3+qax1I93xfP7CmlAuJR3+QGbKn1rr1KWxlOOfByqcV+C+xx3w9IjaWWQNUueU1zOaCrFa3jFi1DUxIOgpeJfhiTP9sUvtiTtwG7Vyu/StEAqZkr4BO3L97fgw+0wSXW+ACxkhmgQaEaHVZGUKkhNUSTZpBU1uu257nRtIwSAfSc5wZ1QpyYMR7JKocWfh0kC8Al16fKJhkKrGHc3rFRsdprq+5er4BxA0TGKDh7/bA2Vti5fK6fgAAAAAAAAAAAAAAAAAAAAAAAAECAsUHSUwZQIwB/u/K5EBAujYjF9QiQa3vg5KoZdosNSPRJygv7e+Cq6SCy0UrGMwJTgl8PkuCaNHAjEA6lU05PE7p12krsxKkJ7WU2gkcy2vWSkojue7P0g7qCWr2JYnWT2Woj/Rj6WP63rP"), + new("id-MLDSA65-ECDSA-brainpoolP256r1-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithECDsaBrainpoolP256r1, + "R/xvurkS2s5WpRyVLB5Nx+FEGH3WF8tVd7JTPd/4dfcTGy/SfHFglt9Qme+Tq3iM2chAf7ebxJmFc19sIY8k8Spuv+UT2QeQhUjk/4/cF8KYIzonPZDDIZE93qHmiZEMH1EblhjdWGJHNjtfZYwkBhzb7KbwIey17PsYjDDXvYg2+T3+oXHoYJP32e9vwk4bdIA5mI6yZxxQsfAV9Tg0cRGP54Q5FimYLqQ4Ur8NVeiCxb6wYN6+OcbQxjCNHlg01BclqmRdH1ymVCWODcyvwpDvi2KWE3s61HSu58X8k3gSmXKD926yd6RfHSqu/anhl4ar+KGMQ6q3DtDH67egg/u0JervbDL0pfL6AEDAoCTBkTbS4kxLJcmOy6TwkfRfheRHEOeW3BkHxCsqHPovTe794sjcMswNOicLjSSQhNnHz32wSdauo0+r13Jhf6CtKK8LdsygebawdzeMA1NpQ1RecpsASHiGR/JVjH8HhL85QMGdckMHqvbp+9Wex6wn8uz+MjfcG7J+17RU0yU/RvJ5I8Cvh1OkhHkjxSoztaeNx5At6LjtehB4Jk+L+7h4yVgQTKFDtRG6jGzSsaWRptKb2SNCkHfibcQL65g1hgwNHJOCuN1FMu59iQtJqp6iRo5I3PloxTUl8URyTyfzBRw8iNcHBrGY1FpfNhDgwylXbWF17/krHUg3DwhkFKQHFndeHaClBEeztrJ9Z5avLFmRSDeoXN1Bp/lUgmIFJfQu61SJ1Z382qkKU/it5f1rDDvGHOCA/pNMNpG9CXBnl8xPDJytlfx5nuKo4VlgjA0Fs0Qzw6uO6nXF9MbfF9/19vVkAnoXg449k35ET1u6GJ1nk0UzkdENLQhsRJM1/bFRF1o7jFdKKdIlNC40G0IYwg8G5zxwStEi/NcDyfmAaXA30vpPVzfucaV5sD+vVUAaaMzW3Kr9MXDFunn1NNYjoitCw5oU9XaZiH1ofsx8NO3EIljnT565Vln5I9IacxPwcWj2BIUto9G+cqlpe2uvsemEqCIWbZHhIygJhBtyd2R9ogSs5ZfOjfu5icqULK+6vRFVbRcEeJGJxjHClqvI/TMmnNRiymsjrou0Bnw8jqjG9DLf1Q8Ti0laDTAW9IcfOpWN9expmYvkqtpoQFu+UieI2B1u4naj35eQ2AZv06AK6rdNvSSVz/dIcoc17sMn/me/S5OZsisNy1x+rU/CK5ELntp+vtfKigW5UX3XhLYnCTsBpH/v6yFhRDIEDFAWf3Q8LlF+SGhnZE21EI7GXuuILPXTwgL/EQuhNFMeUB6AR32UUNWwmNcVPX2wsw/yK8HMfqnC4lhM254+PAAb34OQB0wWI9m3ykftJNxG2bsQQtJI5QrFf1PWg3bn1de7K1bn5eOxXusIcTtSfB604NaWj1+8HfxawPMeX3WiLhLxplGj3mna8fY/J2OxeM6IFsjWlFc4JPYm7Wtre3T5482fYIW1XGY2RXRw2xcFoK3P/f4rM09CMBbvIiIejXMZpraV7izSeSt+p8Ti+0vMB/mssDsFjlT2RnDnIj25S0aF2V3eulvFAVamYSE4unKursacswBtdDDxQT64zvIUiBIN/p0WB1CBWqDxNClBY39+tmtfpClot8gKYfaOwSmAAqix9Qy1AFuZBVSy6FsO7+Sk1itEUC4j4cVsPqq9KiJKfY2N7BaEgkbChW6jKQUGLGMinH+aj10uUNhszJT5L1gYaZ/V3+skIbAvAjEYxlZXd8L0WffKH8MMfep0J/08ArPXqlgwAjC87OKtUPIG7sKAaQjOXRRtUY+gipSnCBVPOQ8IJMKHzGRdeIB/jb8hd/tPTW7QcJ88Mvb8I7Udr4Djx/DDCm34m6zhiKz1NxEP4DEM7Qs/2K2yd6+ZyCNH4jbjhZDYbf/GzwC/b1JX1jvarPjEJQrtpLBtXGhQGhxOBo3RRG3WTwvmbrSZwQeuEkF5gcT1Mq87ASdLFZooXrpufIDbkpN/qDpNT0PdXllJXRZiMS2M4QPuNOfSth/6vHzZQiVwu3nys5OeqM0UGZecPRLfcJzq00GiRVfHHfK55FDCxldj9H1EuE0ZL+egpey8IsdwmyDQR3OdFTqpeGnu+bJJFgWo+XP5x0gnG4A8E0ofBFfohtybCcz9cnz5x2yThr27va0cppdEE2wBbyusg2pLAqXZG+tspLMsT4YfPvqmce8nIe30U1twWLd4kBNeA9I/qJSSUjBWP0NE15tBY8QbQ5kOGqyF4ZQUvKN5y/O/i4PEdB29sfQvpXVjTEwiOtAMTd2cbMHXvMHg5qsW7cpK7/huIZRbKOOfftEWWNo5fA0Sye0FeGLWQRG8JoJHNA94t4L+rDsXp3W4VpegB14zFO+oPdFNm93PXdUWHnwG9vGRKO7JOvmaNfj/aRIleKUdbh7U9q7QB/S731vRKFqdGZapCEZMAr2HfKY47GSs5bRUcnbgluDWoinu66h5vYwGbirtd+vDQfRHWV4uJPCPC/lJE7uIKcLBlKV+iPrHDT2T7fZIJyvKzkcZXdAzHbtmk5o6a+qU8AIV8Soo6Rvdg69aC/J5g/a0wp8oMQPoJB9xZHcGJHg0yu8EL1VO7e9nxYXFIUdZBZfmHhxYdy7RrlPSwr2WOi8Isp5gXCY4lHp0dDx2ZpqdpIiFSWeDVyJE11/cdKBZd4+NTQ==", + "MIIWaDCCCP2gAwIBAgIUeJ06QYG2U+h8wmhSdruiuXqTNCswDQYLYIZIAYb6a1AJAQowUTENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxMDAuBgNVBAMMJ2lkLU1MRFNBNjUtRUNEU0EtYnJhaW5wb29sUDI1NnIxLVNIQTUxMjAeFw0yNTA3MjEyMzMwMDZaFw0zNTA3MjIyMzMwMDZaMFExDTALBgNVBAoMBElFVEYxDjAMBgNVBAsMBUxBTVBTMTAwLgYDVQQDDCdpZC1NTERTQTY1LUVDRFNBLWJyYWlucG9vbFAyNTZyMS1TSEE1MTIwggf1MA0GC2CGSAGG+mtQCQEKA4IH4gBH/G+6uRLazlalHJUsHk3H4UQYfdYXy1V3slM93/h19xMbL9J8cWCW31CZ75OreIzZyEB/t5vEmYVzX2whjyTxKm6/5RPZB5CFSOT/j9wXwpgjOic9kMMhkT3eoeaJkQwfURuWGN1YYkc2O19ljCQGHNvspvAh7LXs+xiMMNe9iDb5Pf6hcehgk/fZ72/CTht0gDmYjrJnHFCx8BX1ODRxEY/nhDkWKZgupDhSvw1V6ILFvrBg3r45xtDGMI0eWDTUFyWqZF0fXKZUJY4NzK/CkO+LYpYTezrUdK7nxfyTeBKZcoP3brJ3pF8dKq79qeGXhqv4oYxDqrcO0Mfrt6CD+7Ql6u9sMvSl8voAQMCgJMGRNtLiTEslyY7LpPCR9F+F5EcQ55bcGQfEKyoc+i9N7v3iyNwyzA06JwuNJJCE2cfPfbBJ1q6jT6vXcmF/oK0orwt2zKB5trB3N4wDU2lDVF5ymwBIeIZH8lWMfweEvzlAwZ1yQweq9un71Z7HrCfy7P4yN9wbsn7XtFTTJT9G8nkjwK+HU6SEeSPFKjO1p43HkC3ouO16EHgmT4v7uHjJWBBMoUO1EbqMbNKxpZGm0pvZI0KQd+JtxAvrmDWGDA0ck4K43UUy7n2JC0mqnqJGjkjc+WjFNSXxRHJPJ/MFHDyI1wcGsZjUWl82EODDKVdtYXXv+SsdSDcPCGQUpAcWd14doKUER7O2sn1nlq8sWZFIN6hc3UGn+VSCYgUl9C7rVInVnfzaqQpT+K3l/WsMO8Yc4ID+k0w2kb0JcGeXzE8MnK2V/Hme4qjhWWCMDQWzRDPDq47qdcX0xt8X3/X29WQCeheDjj2TfkRPW7oYnWeTRTOR0Q0tCGxEkzX9sVEXWjuMV0op0iU0LjQbQhjCDwbnPHBK0SL81wPJ+YBpcDfS+k9XN+5xpXmwP69VQBpozNbcqv0xcMW6efU01iOiK0LDmhT1dpmIfWh+zHw07cQiWOdPnrlWWfkj0hpzE/BxaPYEhS2j0b5yqWl7a6+x6YSoIhZtkeEjKAmEG3J3ZH2iBKzll86N+7mJypQsr7q9EVVtFwR4kYnGMcKWq8j9Myac1GLKayOui7QGfDyOqMb0Mt/VDxOLSVoNMBb0hx86lY317GmZi+Sq2mhAW75SJ4jYHW7idqPfl5DYBm/ToArqt029JJXP90hyhzXuwyf+Z79Lk5myKw3LXH6tT8IrkQue2n6+18qKBblRfdeEticJOwGkf+/rIWFEMgQMUBZ/dDwuUX5IaGdkTbUQjsZe64gs9dPCAv8RC6E0Ux5QHoBHfZRQ1bCY1xU9fbCzD/Irwcx+qcLiWEzbnj48ABvfg5AHTBYj2bfKR+0k3EbZuxBC0kjlCsV/U9aDdufV17srVufl47Fe6whxO1J8HrTg1paPX7wd/FrA8x5fdaIuEvGmUaPeadrx9j8nY7F4zogWyNaUVzgk9ibta2t7dPnjzZ9ghbVcZjZFdHDbFwWgrc/9/iszT0IwFu8iIh6NcxmmtpXuLNJ5K36nxOL7S8wH+aywOwWOVPZGcOciPblLRoXZXd66W8UBVqZhITi6cq6uxpyzAG10MPFBPrjO8hSIEg3+nRYHUIFaoPE0KUFjf362a1+kKWi3yAph9o7BKYACqLH1DLUAW5kFVLLoWw7v5KTWK0RQLiPhxWw+qr0qIkp9jY3sFoSCRsKFbqMpBQYsYyKcf5qPXS5Q2GzMlPkvWBhpn9Xf6yQhsC8CMRjGVld3wvRZ98ofwwx96nQn/TwCs9eqWDACMLzs4q1Q8gbuwoBpCM5dFG1Rj6CKlKcIFU85DwgkwofMZF14gH+NvyF3+09NbtBwnzwy9vwjtR2vgOPH8MMKbfibrOGIrPU3EQ/gMQztCz/YrbJ3r5nII0fiNuOFkNht/8bPAL9vUlfWO9qs+MQlCu2ksG1caFAaHE4GjdFEbdZPC+ZutJnBB64SQXmBxPUyrzsBJ0sVmiheum58gNuSk3+oOk1PQ91eWUldFmIxLYzhA+4059K2H/q8fNlCJXC7efKzk56ozRQZl5w9Et9wnOrTQaJFV8cd8rnkUMLGV2P0fUS4TRkv56Cl7Lwix3CbINBHc50VOql4ae75skkWBaj5c/nHSCcbgDwTSh8EV+iG3JsJzP1yfPnHbJOGvbu9rRyml0QTbAFvK6yDaksCpdkb62yksyxPhh8++qZx7ych7fRTW3BYt3iQE14D0j+olJJSMFY/Q0TXm0FjxBtDmQ4arIXhlBS8o3nL87+Lg8R0Hb2x9C+ldWNMTCI60AxN3Zxswde8weDmqxbtykrv+G4hlFso459+0RZY2jl8DRLJ7QV4YtZBEbwmgkc0D3i3gv6sOxendbhWl6AHXjMU76g90U2b3c9d1RYefAb28ZEo7sk6+Zo1+P9pEiV4pR1uHtT2rtAH9LvfW9EoWp0ZlqkIRkwCvYd8pjjsZKzltFRyduCW4NaiKe7rqHm9jAZuKu1368NB9EdZXi4k8I8L+UkTu4gpwsGUpX6I+scNPZPt9kgnK8rORxld0DMdu2aTmjpr6pTwAhXxKijpG92Dr1oL8nmD9rTCnygxA+gkH3FkdwYkeDTK7wQvVU7t72fFhcUhR1kFl+YeHFh3LtGuU9LCvZY6LwiynmBcJjiUenR0PHZmmp2kiIVJZ4NXIkTXX9x0oFl3j41NoxIwEDAOBgNVHQ8BAf8EBAMCB4AwDQYLYIZIAYb6a1AJAQoDgg1UAKUH4t7+23TVsBJioSPf9Ajpnl4mLJKjoxcuTuWPdLROGbSqxu0t52klINXLmHVcp5jcPyDDuPnPy4dNzPV+LstRK+SlWbmjhb1WirBq/4dMURCd/gso4g0DfZ2sqdvGw2Lo6lXkj6shaNtjvtkzmII2sgG4oamQpvpNFmgcaWcwsmTYNr2XgKPbfIeNIA3UzVXhzoF9xO33DkbFkhOZCiqRO/xvaHVeQcf6yrlS7/T3W2MkL+ElFyZR3QW+0Ka68M7X1gI5BFUwzGKd/sN59ErtfbcxO8Po5YWq1rmGtqqZeKwzfAuYJtazTh3gbTbZyFFK9U4PkdAMG7ldPN89qLtIXFLmpDKB3Ynxgjlv5Scu5dzf5BZAsn+uLwQhL/wRfpxCHA2pOqMT4ToBCCbRYHQ+lBc5cjwmTjTbhL6MA+guBpL6rQ5KojwywJdLRCIV6001jbbw7ZXgQww7qy3N4hYJKb3lXJpIpgfsItUkPxlPUGyNh9BHkX35jTen6tZ+a7fWfSLm+/5wQqvhlt9SiQ34UfAcUvOJDYSTurwOKJgX1EH3Nd6YyYuRtuVbcBcbfLy0ScD6giO4vaQWtnFFFm4zwhcOop55+QPhm8K3dj6YdkyFfYIzPKqeHme943xnoKHmW526PnMNDmru4wlPxETfq9SjOH3+nQmt3H87CBrhorcUcOn9RyH8k311aeAmvZ65lh41RDI/g4bCyF1a6+Kl2ci+JZKWqz2vG/6h1rPZcrDOmi0vWilZhAwsfA8wgg6UvnBTPiX8Wvj+bVVGnrxb7qA8tZuFY8eq4MhNplCN/HQbAPTDHLHh69/E1pBowv33Fz1Lq60JRn97JibhTf59kpaPiKk43bSJmhxvnc8IUVKTKgu3g/bShlwduR9enfCz1Z/BlbAcgL89fjFTbLECM5xjfLiESk7j8Mfvo9zm44SM914IeaCit3tgcuaQzK2wDNEdwz5UcnSn1TqxwaaNoJohTowQrGYHwNW4YGyE7hrqBv4aUGMviju/sMDR9eznSQf1Ibk3HzPCH3LEit1qhK6Q1qJjzAt8l3l/oHn68ICrzAetTMDLsXsMTDZQRDiYlrnL1KrvHfgoLwwykrYaetSoBq3vCp2MQi1gHLrqdJwe12x821eq1jM/4uHFR+fOMSU0KsGuJN+9IRrGnLgRbbhFb10XAbAT0bksEOwWsvjZl1sZxFn7vmPBE7XwsX77WefQoLwQT3WcFfcLinPLsUkEi7wDALtnUR6dJC1/KvwFdcFvY45KRn3uu8r1ZYK6xbKN6htMbkqt2mZ/0RSKV6IbJ1DvKmZZkxGxT/Re6IahJLjLcSA3fWY3ls/SEsxp9HnIszzfwWKUhToJeDhP9lTuQcq6r41lkpJNqQYnHpbQlVJpTv+CTKJqBR46cbDK6CxZ/t1ytjqVKOq6b/3WmbZX9PfrSOPPSk4a6HAfMO1uadIs3bDMIrKVAjLTJpN52L3zy0f/188c1lUZfPifQlk0vFYb8L8wNXJWRO06n0dvQzvPPU4GUgm6GLTjX7xeIbZqVgKfOYpLzFMPXn+0MKXgGsXvMcRb6Xd/UNkW1xfzKphkKIzLx4nN5cWrDEFzAMS3eBHSodRPpvrgo0yrDmypeU3/ehctbhhIkI+sNFfvavq1x44gY34CRtBwVp9K4a+CtDMYu0E2rOzQB3HANAj1cuuVaef9VOOudVik3LtRMXT1mAq9VvtanUAYpjoLrE/t61vyKsCLAyUxtQO491P55bv3CSXOtHdHhiiqzVQ2EAlPd1JqQ03KUX57aLRtbSbt5pwMopM2uhtVQwCPP0iypWD07DeQT3ipp8XyLtRSTikQlL4VR/139wAmUGFEJlaTC3DrW1HKKTklcmUXs4cY8XyDJ4V9fTvRwWSMfjiR8HIgnuBulbfGe0L+oFEbnbI5R5qJRDxH+eNEJfI39Nzvl950r9+j7+kVwOE9krDbanLtCTnOk3EdGLTocFfrmhEZbS9773LGMJdOam0jvoZpeLXNbC0IX5dv7MQbHMTC/oZfgvDGH5V/M60UGewl7Z7o0By9H00s+QJkAjG79hlHf+voRNNp9gS5ewkGMOUWgQch+7ZaBotL8TD4/B+Gxn/luEo58u0brJIa0d95vOdd9dslFUrs8DYJQhML+zn++GVV3qrYUDppukw/tG1BcPz4dScPYCNKBAuO14hE/DGDmKoEDXWPGOy5/rdcnLP9XiiSx9npjhYSJHo2PiuOwNkTw+9ER1DkR/yuMk3ZMoAuo+fNwKiPN4JLaAwX1Am9CyZUWAbfCRci5GqHxCfH46Z2WybO/N3/T8xnBm+em7/DoULuSU+WzSnKQfF9Q2vnlQ4Y1R1/re0mVZJSsE8A5K/qAisUHUIBVSC+r6P+xabUDu3MahHY+tDRiu+cF0+Ji+RocQmol0MDepw1amTeVydh19khA57itDdzHOW+nB4rpXPUax0W8Aj36/R6orjQrm+TSLE3TOM9AhtDItv8CbjwbV00/glTAsYGo4KH2sEJGS0UYqzY3DOOpE747LR/QVm0exbaVGqXaJlEMQFtVoFcu7F4jwkrnQRgAP14r5Ivgl5ypt9Yz/a2u77D2zItAHZVF7rlolEP1CHQmFGwVjIEHXuKcYU29BiFXj3gHNWUc+6Xo3t6qBavvtsFAYhlDpUM/nIwn4pxWy298OAR2iOtNI2IHAwawSSgapXmnEXDUXtxvLoJnQhBrJdK+zorb/mZ5JkncJz+IaJheUIinZ59t4TBvTIp/5EVBBcEKKxP9KxydxZrZxL6j5/9sSH093XMMYUMZ4JuSLlq+QDPWmysr2vvbGgHTohZEpW43Lr+bbx89e66moNDY6BludupK8QgzI928y1wMQFTdEJ1djAEQZcRbP5dH71NBi9cYENaFUkyR7vl+osdu0m3tkY7OFhkF0s5aLysaaVqIf2a4XMSacJ9jEB5x90l8C+yCWEiT8WZJ33YG9ilzhArkW3yRwBKqwzCxT6+Ffwf/um5zlpSZ/VmH0P7K60QQ4Hkq66vT/EQEUBpoJAewurc5Y6yF8GsuB97+vkCaOPVGJgOYgmfWz+1OukXZVO3RCsovu/YDPepTBI5abFGA5Xmy9p8NqyXVgCg0pRF91OwwxTuf6pm/uRO4NxEU+pX3xsp/2uOtP+zelnA2m6102+e70GNnxXN8heqCiNGoCkJE8hf6p3W8mm+ElRyu5UNntMt7+LxlwYyqKTTNpTVc8qjukLAnjeJkJbaI8kBdJV4GF/nu5Hu5bKdJKj1dgjlyIS51Fs0CBu+TH8PnSOa0NcW1CpypgfZdZ8tW6XdWrTrgxb/vQQJoL16HXRxnAqOfQ9Bp1fiKZWrtAGGl1y7w3ySOoQMfOmGNaGdlff7YAUNChBZQuw+F/mCZEPqz4ZQ+4vD31K+4qYd1JovkAtcU0pVTW7nv+F22hWd0k48VOW3jk01Cb74Nh+yySh38zzIswU0U3OuiuTaypBrcoDT3kck7JApdWNON6GtgbjADVdJ+B8yEpHcPyLMAZcr4kVcSKdDdVcNg4vL9Pu6wnTGYqRBg0qFi6uU1K7mBlWsclwxs5VuNxYA1oQHyO+IY/Ao2oVsR7OzZdAQYijl6PrHJoOQAqjG35zfB3apX2LB0QeUbWj7U4mbXAHziWW4xoOr4gvZ2v7rhS572g6JtushVBwr1k9V3QJe9sWcimcrQJeMfLSybho1XgrTIOklrFzdl/5kpgiCQryrpBnSOrSVVquXOkd3akOgjdS19kk/a1NdApJBgybveb+kqkANvKpnwbI5sSYBY6Z+VTsrkFPGOzW7t1Se3EMPWk8dBM8g9x0VK5nFDiq/bCcap1YlSSEWXH3yycOo3+6UIkp665gNR6haWUZgA4mc3UhGjKRc8duvRsEbQmeEeeCU4jyC7zcpCv8SbFLT1H4cke0eVMiAn7m5u8n5MAdZC1Z+gEC27Pdz2I681U+ibHR6ZW+/K9jfQQSS84Xx2ZJoKS164sXo7vUnYgHHr0Ctbr2KQV8fb4/Bu/e5PgSwFkMj2I+wpIDeqo9DR4sblZ73VX5GUtXSGZDfsh759MlfC1H1FCFjTz5Kte23xjMewvRgfW3+5/TrzIk6P9a2CiV/+IFT/Ufca4ibLkUVVvVBC1rLk3SNyYLjs8HHoXZHkypl6PVHmxpYIgjN5NKFieIcrLPGXoJKuLm9OcdBo9tVzFhUyGuJgniwpTnE24m/jMUwtal6p5GFz+qaSNjrPWQ7FR4KnP3sCLjiu09mUykUkXC4RC3g+BY9uK27oC437sq09Sk7/dGD7pYNGqYKVANAeoCwF2u+X54QCdqrT6ze7iCV179JrZfo2CxJ1nOjUGv8ZI+DNofwVcMPG2Rmc5SW0PT9XHKKlygxO5mjJVBor7zD9AUVNllhgpDg5yEsUI2Vmu7v/QAAAAAAAAAAAAAACg4TGiMsMEQCIE9AVw2Tvqr5B8R2cubw+CVRg5MZ8Z03swsarHMATYLuAiArpotxcGRwRVBzMtcKhDBJdZauwiPW16JRdQihjPOzOQ==", + "RqfIMVmRQCod5j4anzlk7qdy3qGL9qQrO5mzFY30G+AweAIBAQQgKTkkS9v7bDwTf0DcSz06xMzrWRGEkraYuOdBQ4bDlVOgCwYJKyQDAwIIAQEHoUQDQgAEL1VO7e9nxYXFIUdZBZfmHhxYdy7RrlPSwr2WOi8Isp5gXCY4lHp0dDx2ZpqdpIiFSWeDVyJE11/cdKBZd4+NTQ==", + "MIGvAgEAMA0GC2CGSAGG+mtQCQEKBIGaRqfIMVmRQCod5j4anzlk7qdy3qGL9qQrO5mzFY30G+AweAIBAQQgKTkkS9v7bDwTf0DcSz06xMzrWRGEkraYuOdBQ4bDlVOgCwYJKyQDAwIIAQEHoUQDQgAEL1VO7e9nxYXFIUdZBZfmHhxYdy7RrlPSwr2WOi8Isp5gXCY4lHp0dDx2ZpqdpIiFSWeDVyJE11/cdKBZd4+NTQ==", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "orjWCTA0wjLKkviihkbzWrMXLkTagl/wYYZ4JAnagA5Le1K632NyJcsk6bxTqhtVgK3hsgYFAEFCtJsxTXTOrb4NcYcOP/FmZMWAfP+tx45yPuh0to11+moUZJXe5k9tGC1qXvmMKl5ciOfd6+i8Xu63+lYJAwreLsISoys+fu64qeGiYkw2HQJyFJqycSBpv0xjCUIhtdWQtx3mpmw/RSnvu6pQB54jSPWLq2hJuG2bYSin7/b0PdKp8eYGCTHwBXnosnZW3ZOPI38XG1Js7lKNmqFjRtqnudBp0QDZhi/vwx920WEpHkwf2hqrRKu2idQn9Vjk/vifmsAoNAsio7Nx5POBjczivQDa0Frelwm98h8NMn0fP5ol9jB2qhxTasH3opZRklsSJc/wgXE8o9K0iICSvFuX2mvBmscVKBQ29qoVfe7F3OkPXq7k9+kupxzs4huSAiwzQhHWa8RueDlGvl4LL6qducOEj/2U2Q21p+r61Qq/oUl2Rj7oOPhw9YGAvJbxT7+AHbn8s2TLmWe352VLzKN/vQSYATIJj28zfNbAIs4F28g7GXXtJRGMeqX2CdQxKALn/Ux882oiszC4UabRAtZ1XsBwdVi/mAfHoUiZKoNsLSyDORmxZS7sUMKEY4TmSPIZ6T/ZHPr6XkUApQxxRvulh4m3i0j+1dcOIVOKNzk2t01HbyEm2zP0Myvr1atkQZ1X/nzTRW1N1W+Ub4w1i+YzdRHUNt3vwim4c0abRZ2DZPGQmbuFjFHWJb6InfSq4IXNhMmY1toAg+WJ6YJ7aUzkKfNxUCox3AFRbI38EzchrHz/bMoKpgFhSxFrt4BgzKsiQk3qzajTzhXvyqd5RV7V780Yt35/Ph8OFShGEIj+96LtgCzIyrzUXvJvTiYy7GxCkvS5chaWkjExliTcTvQwm4sBn72xTesxaZSM8oOseE112PSVnU89ACuFbDx0NmiggRN81r/xH4JKclc/cWDln3ruVis1K8OX5EMnAbt3v4zTUZ/oY7bRu45beLs9v0qY5pb4paV8vzzplC0X5Ed9nEteypwGt9ivTxZsNHWKHPS6AUYd/l8KsY4XunAHkImXBIap6Hl84bd1GEvd4canEY6O4y2HkHy1szAR5luKVOXpEEFdJQ8LxrmijOXfRJZHyUe5yJaG1j44IKUaG4M45RgIM86AotVYrqFdIXW/smcpj3GhIw+0OfMrSW4mQzEEt2KstIvS8NPKDKoQqJIoLazqcOFlvaF1FFiyJSyPai1iJwAItr+V8+zkMtTFTEr7oqKVukD1TFxPfYVYcUAP5WLrG0nFGysd7Bqc7R/6lKFnOvTDGn2GgErO0WvBv9K+TWL8NOQ2vunpR/VfLG+7rT1Iyd3K7JteKnZlrL7CYfZniru5F1AJdN7vK11rvP1ZN+/Sl4m93p749Ci9mSWZ4tEUDTNtTzcnFHoTW8QlBsNN855RXNEIw/v7kxWHyGVDmwrpPT8h8kHhWahyMaghsliVXveNzvGAv7BVNW8HS79DZX18dibm26g+g9hFKf34c/O+nENIracaoh5wdCqaX3WGE2A2oOU9/QqXUCR81DVbX0wQUNMdUu6WGFO4LMnyxFvSRp16B/16xEEy37zKfAH4QJuVc84Q58Z9oplsRb7jUmV6ge85gkU5nOaDsAQU/KomaiqnkagnEQG1iiTpGXf1nuaMfGOpX1qu2wwnMopyJJNkBDzRtv5KKHmIFMpqsvESgLDKdHLIgFTw72cI2tyO4dqHmr+ih8AsWxqoSJw5i12w76jhf78hDljrcfIVQvYTtzzB6ei3d0oMP+NRZPJ6zXz7jhVdAAr3T7gaYlnAFOIVLrRp95KLEsddIRlZWtKyCRn0FZMQzsUKkZt4PavOFUmGwlDgNMb4O/3i4Hoolo+MEKKZplNxCm5o32eLKFIIvVV3OVZr+hpMFPoFZTKK8UqVZiwEHjPnzBTZI7mzcHjBU3y1xUm0UKXvrLv8UeapnlN22DJBoTDuFE8Bp/sRzJ1s8gUlKoihZx8TeKwXK0Kp527xn5lqCcV6WqEXeySmUizOpDT7ZpsUxkN2xg06/lhPcmnYVDI7rE6PIkMReb0B/7eqD3MUhhOxtiMiZw62tCFYoEsc9G6J4c/iQdeUiZMysztP26esA0eLw+3cgP6OG1UPED+3oe0YRKlk01YpEFZdl/+TMpmd6UBKKCA1mh2wTeBcGqsIpgXGvIkmMakzFEjzy9JUwAWhiZmwY/vW8KoecHFxwSZL37jHiA0ffzIRGqvr9v71i6DKLAImmRlPc+X9xspCRITB/Q5ghBE6FyjpiCtIFkMYsquYp71KUeoGA3eZfPOPhzURJZlFr0WcWVrAe2Q/ZnFmBpHv7KO3dDwoV8t3wu4KxyeOOmEOpJ/ApkZdjx44AWSp6spZ+6ONzBsqYKoZ+ZhGveqNPH3+f0P/7OAnanaT1X7fYZ21Q4LVN3/wAyflXWWJcRq/15+qV5d3cJog/r9TtWXPMKO/jVuRL0lZjGxI7sfVPSfWyZfHI5rRrOB1N2IZKMX/gESywI9+x2cJc0qoR1Q5CWF9Decj8WWvCWqD2ZxD8maQ16NsMOWAx9V8H4Z+rr4gRh87AWE6EAkrh0Nc2ep/udVXJiS3tGcpFPj/+KrwzJsgmWg8dc5n5dQAQK3T+S1HEzMcQzQ8Q7CbInYEvq1uhNBycMu7lU/cLzKjxPCJANecfSW46TJJO1JgXHBhWsnt1OsJ71ASLy2ePluG/EYco18ukRJhVPo4M3y99e/r00NaB1VKljFRUDb7iaSeuwtfH9zJRnlAr3fYAwoLWu5jCsUwq6Lv/hLxgOds3oYXql4Q9n6VJn3iuGdNOaJsgDVNuH1II2NZn7hcpXxyDa1P2b4ePLKM6BubPFwCiyiGen8Ojd2hixLUdzsAo6BgotNkhad8cv19mnTIyDMJ5+VLTejFaHm00IlUS/3OAwJ5ZyKvg8YyOM3kSz/YhclyBGT0AkWWQ/kqVkqkaSds19sP01iqV5Z4O6Om47118z8xBbIa1A4Wla/qvMtHvIQJ8tPvVPo+PNr4EMcGuiBwL8W1lWlrEJ7vCARL+kO1ts4gJFG8tlzsu97nxQuvNbatjSPYnb8fSV7Sx1yWb3YybXoMlGEfG9lwbws34SJGO/hQGFfY1jQY+Dg9turGZUKFQQfVGrk3QXTaHiJGoHsgAyfnK7URiRfI3GTAYIyGOgO11R0GsLySPpXVceGmhBlQ6ZsimzMZyvU5P9WqGQUG0clj7W5XT3peJkZwQtjLQbT50nBZoCqIjR7dJoEe1oxmzG9DxrFH8vDyE+0tfmJac/uZUHWl+ZHw/VSnsR1NPcF2MmO+PCTDczr1iHaQZZyVcQTDu2XwL4SRcfCkJAMkplay1WypAtO6zvvMzW9PL0YLPpTKN2pTbfn4oxaj+0wvZx4ryHjIIgdt0trnm/GiJV25F7NiqD5MG7TQcuqHpclH20Z4ggHk3cKneODakc9xdzx9NsOe72dHmHNR24diuvYZsUPaAs9K46VntXPxFPap6fd2CArqbKp9VwD89JiNDQa2WTFBaXEaQ0ico7khb4451qAzLIybMWyPb9UowbC52/AFVlxq+JDt1bRHgUt9AvqPdMSw8Tdy+NXIBTChPH4EN03SLwsTTPQrzFUJre7g0uMFYjMy5Gh6oc+B3R+A2DtdG0oVO7NRr0uVtc6MN2MQHaR9n0HSXjzu0Z+cenW6ulvrZ2gfznm2sbYgCH7tOuCOlMBYPK9kPnzVWLb86hSUhrTXaQJq3gF6vtd17smAJg9OF2VdUFyO3kdjCBJ7KZLfcAvef0FXYDXRTOiTqiOHLy2VR9WEEaQoZTrk6bk2n6mRyZM18k52/VxVjQEFd0rl5+eNkRqkPCXu0KUsZtuWqKtMhRKVduCOTZ0SgvxdOlw85ssXXdqoVbILMQDotW4xMK48DfIlliQ/lGGzoXlv5Aj7DmksoAqPgYg+t+LcH7X1Odty2Oz+iysoVtF+JM/TfJkm18KgvcGE4zIRe9sDgv2HXT/uGyktMBW7TG9Kt6XMDRoNsmI+sYwf1Xx8l4cDckEG4vSt0YzUgNyGb6jlMDgbcNNjRuMSx+SRHtwKG0+C+UnTJdav2QHaoaPxHufW7nR9ks7vVvA28UXEsu7NdCPv19IljSEG9tAUy4AyEDAVwv7H4Qy2xX0OQ9eBo0cd8LsvTXl9BJjMUic9ydET3VgtbufmmTseFxqE5j+Ctr1wr8V7DHfCPVA2+eGoZMPOkvWzNOqa3sZrzgsXaRJL6Aq3IQA9Q0qa7U/lOiJWh5cMbvWu380oAqMglIKjJJpGNKg5c0NjGIq4pV1ee36h5bynYq9O7zI4TU95iZPH9xVka6z5ZX6Q5Sw6b3yNnLS85/cLITNWgKWw3eL3UV6i0uHz+AAAAAAAAAAAAAAJDhIcJi0wRAIgSi+HDdCMHyCL9ZdZ+gX5jcT8aNE2Y2p/7WSQuGIjlGgCIDBGBvjDPQaGRpzMg9FdU68ZNm5eMMtxzeDmnObY5fuY"), + new("id-MLDSA65-Ed25519-SHA512", + CompositeMLDsaAlgorithm.MLDsa65WithEd25519, + "+aWM3cyacDzMz3IgeWTARdrPaK/dBJlixwn9rDvR+KgEsVH5XztJiCpGaV3rBK6V4KOlRLeNJvbbQC56zCZgA2G+tX83g1czpRpDrVNhaAl341u7Ty37LeUDq8PSIVl+jf0LvuDxCq8j9PDPRdsRsSRDZEtZCB+CpSKVOqyDjGTZMxcMzy/EGQQlUDBj6/psZXdymwU59+Q8W0n9xdQYZJjxIEYSlZbe/4EypbFjJ65w9pu30M33X0ILvCjvOArGL3r8Arry/sFFCLAZzWwyUorId0uSfpyKyFlY5Nb2DvYPCAEhQuDvX1qR5cZX6kz42irQH5V809SwikDkYkJhwaPVdizQiFVtx0kp6rIsw7NAeBdYHdaG9ZWmr8YmYdM92SZAY2MStQXvkmJTc79kkNmfblOwziI5lVWkOrUYRqrEGKaMJj3sM/Siin3MCJvFsCL2+S+ZsEAGaTeaKPdKyR4HHhQHRj53JONWnDzbLSKdrf96H5/uayY2emwqLeR6jbPwRrCdyyD5LdPffSSSToVDv45ohTS3aykz8k/qVblPePyEXgENP4JNOJI/he3OzMLD5Nc/5BMo8AqCcj1JZP70W9p0W86KPEBa3MtWGGZ4HCt3I5uWqi9oQQKEAEjdAlBbK15+kiq8RExmkB5pAUKsmNncauFlrZUCCumWqAbID1N6s7HCiBvsW6ANGy8oCafKX7a7/fuWEZku8m6B3EK1keokVKn/NrIvGCuqL9JtxnSYmysD0YccxXCtdAsjOlqkz3ZIlwUhP3VMW9dBO4wIbCE6HTbVj/b/qbMMquIBrg32rCcxUBXU8p51MHyQVSQN0FfHuSQZAADeLv06yVeUdhVYyM4hTx6fodXTvGlxozjP103lr81F5uEK5O3c0h/eXi63cBrAV61rfxhW+i0e1NQ3SOfLrCTlLZ19jezNZc46RKgXsIrl9JDN3rZ0x6yVmQ0sYsh3F9/35NlYxM2GpAWU0AIDKpJHdR7PnW/ilsZMLYWGR/vyuoTarzIUhlQSk8LEYc2SD68EFTLeA1tiKGN+bhdDjvEzaji0SA9p3VU3KWGGWDZZ8ag+b9seljcJ/RLwr47+pv418jacOzi331MSGVJfEZgzR4TRZA6jXBTEfDnZebjXG0A4T08yqrzpukwsMxbEj/IQqL4Qo4YZ6SWrJJupQNElv2OKUlbcH8RXrKil/iFPD6EVo+l4qi/8qCoeFS8BsBGEYivG/nLEe+WvIPDpgN99UwqBYFApgCXrlz+N0aM0VHj1tQVnQgLuDqi+h94eQAnvILM61NFGwcvWphFd6TbmJJHUIdxYKMzuDIC8WE1V5eShnNeIlCnbH10NzyZ2KlaLWZ0IobHM1fMwc/uZikHIykSF3lGSbroQHgP/kIolufeb9tyEx+iSjtNb8ajOVx5AEoyjWLuac52NkEEObxWT73XxK1d6MiB9Gaxd9MswxnCswtFusCV/W7G92SiBzlqswiBNSCMp2yEag5pqID+yySE5vjUVSlXYidnMvm1g5Sa3OzuLGNoJ1bv1ZiuGdFq1T5e9EUhPpY6XWzlGTMlWDq8HiQUhU40nbqd759DEwpGculmUwoytH3rTekZAd8/D/FzhXYV5H+RQUi0NsPCn1MG7CE2Za/cyqBVK+8OEbboD9WHYTE6yvByjyHkUzA9eCkzoIqnQX7bzUFLyUVbDA4rFLYn3GygmLrwky/0F6H+GVZQnX1DsILRRWvA0OVGq3l550XDkGKa1Xw6qdWOohqZzDsC3sI0rirA2SsAzasJRZynn1gQgNqWpziVYMzfsS7wX49NuUW1sEl4ncC/Va3QST2ee+2sw95JC92LaP4yFAn0k5SzYUbGuSQgmQE7O87I5xXG3qYEa1xFIorNOuiy6SbFfEqmljOb+cQQVdN1bY6PGoT29P857ne/eHrl6yKhPbG5pFBybeElubxapeQdqkIWDbY6KuQHu/5S2I1ocBRuvdlyO9oMlxgDoJIyENYWWqEgWlUvBna95PEK5JZwF+czB38MrSCk/YQIxObiX7jCpdW7B5R/iXOSUZ8DIWhsRC14RuNs7XylpOjfHTlU4wYQsXsArIHb37eqJ8BlCnwlQF6Vo98vIfi6gtgUzeOYKLX48Kjj4yksXUL+pXVNSv5PG5ZWERfrsoOYxOnTWd0kSwl+/HhYtsrDe41MRq+d3y+ERobLGxRDiAgs9cwaN+gSTuna1mvQq5p/ZuxxuLFD9fklaW9QrxRwZXiQ7Ikhu2HzdV/akFF+MTtYj0sxu3ibsJZlXdhB86K1QdCGOW8S9sYA8JpL1/SqcM4Mv438n9nLVN+XiD/XDpmRHOxc2eMu9UuQanJnix06o8s8Lx9c+IKisgG+3sYXQPNWOq3Xt562cPjHT73jw3CdM3rWcGghA3pLPiCI4d8cQVdMtsTdMgaadixNJoPdkQEAb8wL8HfB7vC+UyVCmnhr+UXTi57FjGgeueZno0KGFyNf2+M9/K/eqyP0EQD+Vyrzym0KIFXqbCgTzxSWSx6NlgfAF/uUv9+86BQb+TbiIYMF8PecsiEBQpAnILL9xZHFSDAiaKz4mkAY3wbt6yRfK0lXvmy2FSija7Hxeiav5FzxdfIHoNqyGnvhjr/SBjE6puH4OqA==", + "MIIWJTCCCMCgAwIBAgIUP7sG4sn6wTOtFBFByA+QStj3p14wDQYLYIZIAYb6a1AJAQswQzENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxIjAgBgNVBAMMGWlkLU1MRFNBNjUtRWQyNTUxOS1TSEE1MTIwHhcNMjUwNzIxMjMzMDA2WhcNMzUwNzIyMjMzMDA2WjBDMQ0wCwYDVQQKDARJRVRGMQ4wDAYDVQQLDAVMQU1QUzEiMCAGA1UEAwwZaWQtTUxEU0E2NS1FZDI1NTE5LVNIQTUxMjCCB9QwDQYLYIZIAYb6a1AJAQsDggfBAPmljN3MmnA8zM9yIHlkwEXaz2iv3QSZYscJ/aw70fioBLFR+V87SYgqRmld6wSuleCjpUS3jSb220AueswmYANhvrV/N4NXM6UaQ61TYWgJd+Nbu08t+y3lA6vD0iFZfo39C77g8QqvI/Twz0XbEbEkQ2RLWQgfgqUilTqsg4xk2TMXDM8vxBkEJVAwY+v6bGV3cpsFOffkPFtJ/cXUGGSY8SBGEpWW3v+BMqWxYyeucPabt9DN919CC7wo7zgKxi96/AK68v7BRQiwGc1sMlKKyHdLkn6cishZWOTW9g72DwgBIULg719akeXGV+pM+Noq0B+VfNPUsIpA5GJCYcGj1XYs0IhVbcdJKeqyLMOzQHgXWB3WhvWVpq/GJmHTPdkmQGNjErUF75JiU3O/ZJDZn25TsM4iOZVVpDq1GEaqxBimjCY97DP0oop9zAibxbAi9vkvmbBABmk3mij3SskeBx4UB0Y+dyTjVpw82y0ina3/eh+f7msmNnpsKi3keo2z8Eawncsg+S3T330kkk6FQ7+OaIU0t2spM/JP6lW5T3j8hF4BDT+CTTiSP4XtzszCw+TXP+QTKPAKgnI9SWT+9FvadFvOijxAWtzLVhhmeBwrdyOblqovaEEChABI3QJQWytefpIqvERMZpAeaQFCrJjZ3GrhZa2VAgrplqgGyA9TerOxwogb7FugDRsvKAmnyl+2u/37lhGZLvJugdxCtZHqJFSp/zayLxgrqi/SbcZ0mJsrA9GHHMVwrXQLIzpapM92SJcFIT91TFvXQTuMCGwhOh021Y/2/6mzDKriAa4N9qwnMVAV1PKedTB8kFUkDdBXx7kkGQAA3i79OslXlHYVWMjOIU8en6HV07xpcaM4z9dN5a/NRebhCuTt3NIf3l4ut3AawFeta38YVvotHtTUN0jny6wk5S2dfY3szWXOOkSoF7CK5fSQzd62dMeslZkNLGLIdxff9+TZWMTNhqQFlNACAyqSR3Uez51v4pbGTC2Fhkf78rqE2q8yFIZUEpPCxGHNkg+vBBUy3gNbYihjfm4XQ47xM2o4tEgPad1VNylhhlg2WfGoPm/bHpY3Cf0S8K+O/qb+NfI2nDs4t99TEhlSXxGYM0eE0WQOo1wUxHw52Xm41xtAOE9PMqq86bpMLDMWxI/yEKi+EKOGGeklqySbqUDRJb9jilJW3B/EV6yopf4hTw+hFaPpeKov/KgqHhUvAbARhGIrxv5yxHvlryDw6YDffVMKgWBQKYAl65c/jdGjNFR49bUFZ0IC7g6ovofeHkAJ7yCzOtTRRsHL1qYRXek25iSR1CHcWCjM7gyAvFhNVeXkoZzXiJQp2x9dDc8mdipWi1mdCKGxzNXzMHP7mYpByMpEhd5Rkm66EB4D/5CKJbn3m/bchMfoko7TW/GozlceQBKMo1i7mnOdjZBBDm8Vk+918StXejIgfRmsXfTLMMZwrMLRbrAlf1uxvdkogc5arMIgTUgjKdshGoOaaiA/sskhOb41FUpV2InZzL5tYOUmtzs7ixjaCdW79WYrhnRatU+XvRFIT6WOl1s5RkzJVg6vB4kFIVONJ26ne+fQxMKRnLpZlMKMrR9603pGQHfPw/xc4V2FeR/kUFItDbDwp9TBuwhNmWv3MqgVSvvDhG26A/Vh2ExOsrwco8h5FMwPXgpM6CKp0F+281BS8lFWwwOKxS2J9xsoJi68JMv9Beh/hlWUJ19Q7CC0UVrwNDlRqt5eedFw5BimtV8OqnVjqIamcw7At7CNK4qwNkrAM2rCUWcp59YEIDalqc4lWDM37Eu8F+PTblFtbBJeJ3Av1Wt0Ek9nnvtrMPeSQvdi2j+MhQJ9JOUs2FGxrkkIJkBOzvOyOcVxt6mBGtcRSKKzTrosukmxXxKppYzm/nEEFXTdW2OjxqE9vT/Oe53v3h65esioT2xuaRQcm3hJbm8WqXkHapCFg22OirkB7v+UtiNaHAUbr3ZcjvaDJcYA6CSMhDWFlqhIFpVLwZ2veTxCuSWcBfnMwd/DK0gpP2ECMTm4l+4wqXVuweUf4lzklGfAyFobEQteEbjbO18paTo3x05VOMGELF7AKyB29+3qifAZQp8JUBelaPfLyH4uoLYFM3jmCi1+PCo4+MpLF1C/qV1TUr+TxuWVhEX67KDmMTp01ndJEsJfvx4WLbKw3uNTEavnd8vhEaGyxsUQ4gILPXMGjfoEk7p2tZr0Kuaf2bscbixQ/X5JWlvUK8UcGV4kOyJIbth83Vf2pBRfjE7WI9LMbt4m7CWZV3YQfOitUHQhjlvEvbGAPCaS9f0qnDODL+N/J/Zy1Tfl4g/1w6ZkRzsXNnjLvVLkGpyZ4sdOqPLPC8fXPiCorIBvt7GF0DzVjqt17eetnD4x0+948NwnTN61nBoIQN6Sz4giOHfHEFXTLbE3TIGmnYsTSaD3ZEBAG/MC/B3we7wvlMlQpp4a/lF04uexYxoHrnmZ6NChhcjX9vjPfyv3qsj9BEA/lcq88ptCiBV6mwoE88UlksejZYHwBf7lL/fvOgUG/k24iGDBfD3nLIhAUKQJyCy/cWRxUgwImis+JpAGN8G7eskXytJV75sthUoo2ux8Xomr+Rc8XXyB6Dashp74Y6/0gYxOqbh+DqijEjAQMA4GA1UdDwEB/wQEAwIHgDANBgtghkgBhvprUAkBCwOCDU4A4iJ4FahnwMhKmnwXhJEdEsq80FCF8qDvBocFl5c8d4M4KnhgxJHPZEtvxgkXXx4Fd0gTg5NLHTaoSneZoll0CLpsj6Bp3TKrpkuiN8q10AdXUX7jDRmaPHNpgBIwaqNoDvzaxIVMoHJwzi4zHS1k2PHIIBd8NzP/KNsZZdryIMw4jIwpcgFQ/cIwxMtQdpFTxmxLMqKa4UG16O8x15g7kTr6dRC/IY55VvwuLiagj9K9DJGufhluO7J6d6KMAcVoHOyVheLvoF1KyRq76/5XARdzmOpIj9Xa8W6S8m6eI+g1CNQd3GzY9Q5j+aTdkT4BNVOfc92R2dFMNhDMHG72RYG9xhX4nO0pZGZIx58h5HiGFocye5P8Z6pfI+rzTAIz2Ur0J5hkAWqXsYM6r6dwwZ2eNXmjeh0D/6e+8vgGxaG7QcUbjJtIt2i8OAdh6m66y163n9LD5Bwyn8MlBHqU/TQFk3Zu7Vt6AknaU1TkI+QeKdJtNOlVmaRKexdVQozSn4Xkv8ptv4UtRDr+ZTLFzGCxTJt2/eofJYSzP7LmwmEQi18J8GayRHx+H3R7fRmZcAKJB/tKX3i5M7Rrx52qvqcv3cflh3eZ1bDDVqK6GWGVUxGW6QW/eQ5M5SJchmvUgw94PUKLSdX/eJWNNSg2O7zwuCtNVkvOACeaIWNhrpFVsYKr4jqjHjo9P+i5w+zKLds7zQFaRIUSpEXH3fzTJX2SRYlDR/iktqPq7jxJEx73nHMb2ic/KX0hF5eeFzCpw1HDgslNkzvVTJTV2dpPuPbUtAoPKvtmrNHvBLLZ9FnRhJzX5u491q77qGmZcL1ZZFVDUCRKuKAWunp7TrnPBRqoV+LKqcvRScPB3Bj3OSl10TE7ktSJ6oFl11LMX2CvfxBLPoZ105u0RaPxCspwdUVv+ucFKPZAPUhxPEqdf+Xz/1nPjF55hhlYQVLLOLkcjGdpBcXsOMIFFNQ2wUyZawLEXB5YgknchanO+UXI162POxYfR3tSmlUS6+UdRiawmiHZNlek0UWkGNL4XVOa3Hb4R3tkbxsnzvOOKUs/COgLJITXQbI0+lXWhSZFde2WZ6BZRgvpXWBT5YG5CNANMRko82DoICb8/YxNdzpB9SoHhxWCtv5qjENkPRfgBdGV1+9Jd3y65tEPNR+Nz5LRT+zgkKkWiMYhuz5I5THGva7nm3YZjGadvapR9c6oeJwMXDk8dtOg9Vu0V7/s1P9ShaMo4UHmVeXzc06RIxU8WaUnahxzv6DjAjK8Z+Zc8XNgC32vwdcjLns0QXaUbwbuzs/P9QOqranZTImBx/zJu7/0ORnqa7qdTf0yBQMyiS4d38P2f96DpPLUVuUu6Kj63tt1BJxQi/a89Ogfq9t2SZIXV1gWKWua5e883kkEUtO6jAqpzyZ3/GBJXB8xyLsIiGy4I4bsOwXeKrOkByqETliKspUIevELKKXb3gpdDRzVYLD8q1zIEH2JCNvwiRFYpEyovphwR7wB3rROmRvPMkKJ3D6ph8J5GQN7V5bLNQlKrXp5ybXWPcpzliC72WayY63UOoUJOWa7qfk10ju/QXkiPk6pG1pyvhb44h5qEzCps8Qsc3vvYvB2NEZufhvkhDCMoaqtmpfXeH5nROGg1AOH7AueCW+maqEaZCF/0wJnn1P5tcBRzLXApSGn8shFfbCHqEO2uV80UL7VGQd18zTUv1moDhrje4nlKZOsKBJeZs1CMMmlDTzgebJZ/MyxlXb/AXuSGIsKzhaqLYTcnGnvR4yCgrY6LDiotIz4kj4FGq3sIGI+bYPJ6LUbs//bgFLF1J2tU3gNOTxfNfeCs+GL4VcCFZSc515rM/mKuKsE9ftCnntVD1spGVve8IPEp4bsIZ0pbPMRq3CbsNWebY8KAovRdXc/Iqe75fcfgX2ognc2Q7rAEhcRvc1D3j624Xj4YCSwqSzmyE9hNPiZkJR7BzBP9ODcfWZSFDbCK5+V1DjQpDOOY4EFt2PMMyWl7YniTnEXCxp1TxsSpxmm9hugliSti0lSdUWs3iQAp3/pap9ej975iaNadLX686nnoe2ScbwMdYWF5of2uUR1FbATacPgXvzYJYh4no8tiMc6gXLKnXaMPo+edBgb0OmHtt8nl8eVdc5JMdmQDwwc1CrkaIjVDjAma9Gay0B+0J+/lRoz3Jlm7IMPFjePykxmZlTRDzOcDGs7Y4AZ9Sllhz7YHkbf/P4L3NR+9EIZXVsR5gOQJhmb+VoSYquVx2evIgZCviGjMS53DVma8Zr+pFMYEPrkTEYlN7iLLaJJkJvR+U5NAYwSoJ98ukrmKvYovop5ClzKhWtLTWq2vQuj6LnFvdCCHREOE5SmNFGhamtepBYVwR5sbZpt0M/4KJiAa/RMnsNts3h0/Scth4+6PIeO69vJgf9svv3nckB9/Mst2amkqBFmTtSBiM5OFb9SlBZRubOZRZ+ZIarz6wcBNNqMufzBG0QcNgd++jKuxMizdTmATH/DbhpwAgiczuwJDZZMVs7aWgaM+0tJZQeWPZ/VwM0ajz8AzsAzy4uh9lWwFUeahHE+m1Z3JZyJDuZI3/yO0DQPzSliVr5psANplZc6OALkXfFFQqIa7BKGGokO8M89Qs0V5Hrw6oJ2jc9T4ZKbOJR2zKch2QfIV7e1buHHnC6douCjcpTQwv6DKbO7tR+NU8fnhKPbc09XMYtkCoviWfP+vJyLXPII2qfrhtEVGnUBewo7XFw1lc8WmDR/BnkNxpeFowU59pyIkISijg8r1Ph/1UhxpXgdU0W8tI9PmdaCi/irbVLNS4nAXljb2K0lUqE762ZjtJQeeLOM9kYUBqsssXwF5nRU2NmC23Bsb4v4bxGNdwdA9mBBKD2MuLBnxMkalz4XJARiDdyh3+zWnWowjWepHz48+igIg6drM1a78q/K4mk5Bf6Vi7wIj79dUKjV1L+3/1m2mDKT5E9NyKVWVj0kkhxQfRmejaWF+jSbLt4S+8cPjskCACt8jcfD1hJvkjk72KKu5KUkAj2iXmRax1o1GG2eseBISdH2ttK2YYE0ag+Fqq+4CGksBfP4nhlROIYMDYFBkJdT/ocaTcgPxMtAj+x26mBqLLFvk+23oij8J3+dklaSZ2v3YELEDNkWx5HGnGXD5NoRVdV9276+isqFvpz+ePGovj/bWDB5kmxcY8gO3Z1Ws1KmT/bN8ynV8l+rJG9YI5HnJn4NwvPAPb1ycaWZ8LiahJVAZPA+3qC0q2oHk9mJsI9D2zggCzRFBxSWjaKXG9Hd1xp5vN6bfUWOypkc4ZyZGspDciLzk93kH6HgP+5pwAb/NfVa/6eKIcSPM+YX3nK+eDoG8ytYwHT7lxcXb7MKoNpScQ7ABEu/dq0yL27G6VId4XCDKTzEfIB4UeMKsjYzcH9eUGlpc8vyRLASCPEAKbUjiII5DL4fY7BiG+AQd9miuB/kvin51QuB6htUYxxIrkSIDn1yyC0f4CP06V+9xhICn4m6AQpfitJW2hAtn548lr9CNWCSamzD0LPz+V6UYzJp7m4mLaMz/+dmxrIW6PR2PqDJt8qV3HtcGevbvUKx+eA4jXAUyEkcCsasMBS4mXP+NV1cAIB9LLxhmbH+zzOC8+1HWLHpXJSkj+n2YcODzQwwYRK2qGwPbRj39k0iGcuWbKIyJblnK7yJmnkQtRQatPSme+v+n3mc8TaE2/3YbBOk5C0JE8k3n/AwTj+tbRI+OcDVCuN8I1oXUo7a5ztzGZBoiP1D0fHVn6fqlub2CFuumzoTiosDfYZj37m8qNCFXa2jUlkqooT9IECmmNl48lQFaWWYRpzw78mNX1/LnjIzZ6ikQXws3Iqu46N9R508o9aCDzaAo9lkTM9NusVQcf5a8H18s7JONGRarSxZSph40ksQ0zS/YPFDpxmb3V95UibzzmtrwGnmfXEYqITozi5DXLpoAE7tlFsZYz+o6y0UJLgso4zThCr4bNttlXxn91GMgBbIn1RrslNg+OQ0la4Ojf1109brrUukjuZhrWTOyJXS/g5sgX8JtfDwxbE2uRnF59c/UWS+WFxc7/b+s048aNh7Xomi+uR4X0k92frJ5mG06KBhWQ+VMwuRB4YEAta9Q3Q3Hd1rMH2UzB+DyxzL0p3PI/ZHaX05Qep8EvmfrHlvV9GvfP/ge+N6srVKQ15T3Zv5EvB62nTsHTDAdPbcnQP9bPAr73zwqyfoDdCUYh4dDwaIr2UgB+I0q4TnCBAHXvmbzI4RtY+qgeN3PyGlVzHjM23k0KoC7RYEscApFoyn+SYfAopVYgeqyiiT9dYaXCPt9gQJUsM6Y+kmERZC9m1qGNfNJ35Ajfm7gt+GyAUGr1Bl1944bAUS8BE6RkdYYZagsNfzDBx+Bxgab5mcr7rW4u4WIpWaqhMjW1xgbYCJipefo8/l7vIAAAAAAAAAAAALDhkeLS7sj0y2QjvM3C8AS7SZv/lyw6RxJ6qVltw59m8XLFkIinUeUBKZ2sX7YXwXw+hg4wPXkGhlPaPKjrhfSKvjU6wH", + "ihfxkLWYyI+VLVOztZWn+QBxV3UnBGE5DcGfABftYBj2a8u5oW97iqKfHXNBuxfoAdtb9fKfyeq7dq7N0+Jn7w==", + "MFQCAQAwDQYLYIZIAYb6a1AJAQsEQIoX8ZC1mMiPlS1Ts7WVp/kAcVd1JwRhOQ3BnwAX7WAY9mvLuaFve4qinx1zQbsX6AHbW/Xyn8nqu3auzdPiZ+8=", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "fXcZA5PIpfk38ItRI40m/X7+ZQF+RFqsngpy/+JhmP3v+hts0gjkVMa0nu79dcSDW5pJSYySZtcluLUPAblajZfHtP84g3SGkjEkrE4t4tNPdlkXcqw6pJwIkFGeXe9cdjA6DbPlpbp6MHudxhho2XDpCqwzUjkXQBikLfNxXr+pt8wUDHGFSMfmUktqaYuLfH6mp4wPGnKD97e4epvIatdjiK9Fq9QaSao2xk/M5xe0yj/9qPuXShXYDuxFulmxZC2oIUYs6EtB17sIuoKbjN53Kfb/qL0+YoAyctw2Yw9iaZpm9X7q1uQL+rd5wckd9MhrMBxxg4t5h0IXZOV0QE6OeDoQMi2lziFdTBAX17mMgNo7bABgqtB68rlfg4fkPHDGJVHhOCjZodvZh5ZC16j4QD0hBZtPaimd1XOZhvDbTnwx+NfHy8M4Sa7Ire/ZOA7bsDzkNYLgr63SBlcQ+hlqKKiPKzTv44unG/+wNAxMlFRhIJZypKEHNddHs/f+9uoXyZl/UQGDaT76X7TFmlRU5voRnzvtCT3ynD/9G8qjy9BGRQlaVhzL4a/pEafHx/qE7UA3ZVrCbqClUIvOKcWcUlBIq7bRl9S08Obwwr78pi/oPNNCtxWfaXXBL7gCJ71uLVfEe/Mo7pgsFI5sr/wD0hdlhgLXdtmuovWY4ZWH90VwOnBO6p4eW/E8EeysrTvKq11AjPNKOA3Xmr/KoCLBbaojbVBHIc6AiYyWyKHGMIhx4Uco3/fOXt9jG13xG0V0Khyh1PVIt5Og0HZD/FyArh8HQPL5DiO+BfvCrV/1XIihRN8kXmUJssNfA33vPMiiOVoWFfT2dtrQyOJYCloNnok/IuEKWb+P4u8rk52Vv4NjdYWEPmzBCl7Cz9wj+Iz6dXSapkFwg529Ya2U1/RwNvZT4q9K4g78Y5QTL484gWYBTt8Rkc7KEmk5SH3nSa2qk7I+f99nuxFMiBlVZILw7R0SRT8JKmKJykdtDzI1T1B+T/NNvTXnzE8ETkGhP7RzcfpqRwiIOCmVefxLwEfU9CHbqkbGMlfn/jguQjPn9C1QELdMO6205D7Cut11GcXNIsMmNVztqKuypVIk8AtfCCs5PhSDrnaN3eVg20YEYjealXE0Z+c8bmmNkNkM11KFNHzujdqWs3A/alGFe9USIoqUMAYrFop+u2NOg2iH+1t3dU58h6E9GwxYj6OAoOpc21FedNUH/gFMLM1ZPJPsUcyvpP15NwHp/LyXT4tEruC2wje0a/KXVlCtLnL8yEs/nspuDmAd0ZiEpJgB1+j6SGuKsHc0xoc8TGr1VqGFVnjnbJoWxA2jiQo+lxgYZofJgIxXtW1Qx4KPulsBJJv2BFzfYqEyUD+OCIQMOxi3drBZ/Yq8wR1bm2HXM83iK9j4bWnufYBgLmDr/sB8uSjcp5xojIvXGQi0cWBIxPOk16kQLjfWffkOQ21EVCxce4LdDeuUOw3PuFnRPGzLvD507Bh7WZ/L169oPdvo9uEmktskSX/TlWYDJ7Z5o0/SbwPLHIxIPabdLD00bGUyRwqTKN6bntP67nyfAHP9alcDD/w+fKAJdalZOrZcvwwbFgBG7m/usAb6xMKGFsn4wKM68adUQwYRVdJU71OQw7IdZ/F4Ba0IpmtEVSjQjaUEV682t4tTRkwOd6oghyU164YMXBBpr+aI4DCt06iYDfaDyupZ8RfPcvPyXjcavf3/O+4LMzqccIW/Cha+d9FT15+JR9CsXUBX5VxE2w+7v7PcTi5BqAWOOrD6yJM0KvsW+BzhgFR2iBA25NrRriwcpZI1cyZFxk9wlPccVU8XxaJmf6ZHnJZeI8sKI1yrXlKTdrMzlLRVOt5k12yTjY0jLlKzwcsNhKrMkX2YFY7hEY1R/RXtSKMwr6mPI9QMy5MF3qA86ZTSnG+MFq9k2Nya5Ja1ZIcyJd8KDAjhAMWEicmi2gra2AlJ/160mHadfkGXk15uBHQGmEpYucbOScAwkqnR4gc2s/PVy5wprHR1Lo35udKuIGuhc0d1SVXw1x6rbz+5tQ2prYcS/bbjf4bJcZ0zVQ6c6v64PkTUeHgrTyOpL3Z1bFaLKKw1IM6dtTDZYGkuVr4/INg+EuK90f0Ez+LXX74PIe1imndRRetev6Ir04SL5kNN9K5KTTzrNJ7x1bRgwOZvtp5MVVwg2jz8u5/iWVMnA2Nj8wcLsp87ltBZikaJd1jVhq0zmBcqhUZiXizHry7soVM1rnw88tr2izsifejofXtAprXc0hnIG2+MW7aMTsXAs8cWVTX6g17Dk4Aohx1Ko/wIootOTbbExMVplop9J7fzGqTtqdK4Z1lrNQlETffek6g6o9Bpow3UTQhaIeAwXu3Hvw99wMnuEmas7pc5Jxnixmo5/aPyNiiNmErT5JPiwW9pWjOVy0DnfC68+zGM3ALArdQP9UbUEEwFtCuj//OheaOqV8FTecv4++2+HV7IIWEJ0uP9im4wW0r4sxlx4qc+X4AHfkyR7A3s5h0Dr1lx32mQbS7FOrJtntxuOpzjlgwNVd8ziZkdchUnLy4jvrnnzQlbduuMPsgmrl6Mn5yujxIfzbYaaRotS127yWelGKai2x7gldesuJ8Jagln8K6XgYlBGtIjbnuq3S8PG4VccLKPU1pJncsokmqKj0qrIgDbnWSaxt9zsF5NDFGKsLfAEuIcBaVoWOlw6MPhkkWaOBTurJdBK+eAYl2NNCLHU23HwNNh0aBU1WNhi6Sg1gjg0P+pzUVUvSBSXCBGUVhkwmO+DSONNy8rQWW/6YcSbZ9jDBq24XEbTKP0kMljxi/VJ36OqWpVfT+Jgar6nEJMijWtuMr2uw92iOFkvu8b0v77FP4d20kITlr9VYn9HRdpch20Z6iK8pr7KJ7eD2WIV311/urF7rUbgiJWV84BLhECezGHfQS6azdXUELc/pg7eIwPfvWEQOUj//4QacVgSFRHmf0ZVdAKbdQsidFSbdAVPGsjD9BKIl+YsN33aoeCoY3jFdF24pdmlXbsu+cyZesUKHvsJUE14pJESuzSfOCdOU97ayWCN2Cg6d3qtEw7OBuCUT/6Yyvdn6KUxb3vmOUVD6xFNPXYf107p7n8zgwPLVP8qHEnrgXhMclPMNK336ovXrgye8kBDlhAT5641GgTQ88fxt7Tcce0t5b8iNcWDBsfsVidNaLkp+88S8u0XhurRbbG9MdqKzjlNbyI2dU8SOSxGqjrZw8vMWag0gCLRwFq5b05nv0n0nMOXTGqHhEoXqMd0oHxu8I1YFk/a56fHGGLn3/140C+MpYR4GxWN2Ar6As4IP5VUbL7RYC3o32CczLw/Z70vyCy4uzG1ns/105Z+m8Yy5S2MX02fw6PBVo9LpF6OgVhrhkHabwn8+swQ/4jMg6LPSKg7nsfWUyNVXPcjhDDb2cfkfhMeyaijydsfqyPguplN+TIhG870tqu7bJoNcXYAHR2mwBKUxnJu2T6+1nflMamoBevqEAjTOtZwOLZGryCfoyxe0kUbpSY4zJWAfLChawMYiztoa5zRzyZ35YS/iJgQoD/3vO78+CzmhHUX2iNboTcP7GZB2yEIQWTSDbBn8gGO5UjxOxeSaaBvzTRd4vIM9kwWREwADaxsB+FuRnh2WGSovgLZ31T4XX+lBqpRDjAnT4Od/PIvCC3YIQBMJkDwdyhBGrEb6UqQItK+ZeRbcqbyMyafeCDQTlZJ5Rgv+L8cvbHLaInODgq2k/sCEsRK2vs/xXwT+1ZGQFmbKGoScTbJ2aKOO+OpGeYpcpTpV4dSQN5VMw420IBs3seW+BqtQwGiMqoZvqJzQgw1ytXCjIhglwmefNI+37gg538LiaLxubaLyKXX6Sp9h6hJP4ylNN7I0913ZgptDOlwowFMozCNdXBtFxiP7NBdA7fKQc5bYG/XzUG4NvxKvACmvdxrIlhLCLVEyhLiyqruqOqYhatp8JfOZNpuuLzTxOvQsP2HT6jP6UfGPAtke7rMzDOiuZAwMDLeSsxngNx5FtFXFNDjoZdU5aR9lh+m/tRo3eS7+IV3Zr/R4XgvqWiQ/tOUyYCg/pRdlnVjgdEKPbbZyrYQ7B2dL+eg9iYFmH1RHn4uzr9b4NQCPDnsHwFvhjAg/a8EK4dzVQjfcfo826aKnZoSyUdxNNLQ2Xky7Dpx7tF7rboCkW41i0bcApMzr6yc7/DvyY0UwV0hzSl7lQ/nLRvAcMAXZEqbYjzfAeWcFcuFiq9XMpNyGvnhW9dZhhHgm8idlO+QVR7OwfW0MYORM3x1TAE0TogfyYb8HUI2TbBQRw8JidsCwkJbI7StsOabE3WwjxWjbabvRGxUTsOMhTaqPkNjAj+QdH0ZBs/bHGgstj2BRMoLTpEU1tddprZ9Fmftc8+W9YMFh9eYq3u+B00cXqz297xAAAAAAAAAAAAAAAIFRkcJCwpOwP+h8xLIfCm9J23viuCdaWBt3sE+1Q+YM0VoAwJnziE5P5z2fMTJKYH1jmRA3i6Q4UtfYJku8ROV3rK1iII"), + new("id-MLDSA87-ECDSA-P384-SHA512", + CompositeMLDsaAlgorithm.MLDsa87WithECDsaP384, + "4CDuRUfS31qXMe+UU8SPDj+Zf5QgkJg6l97+ILUslRB65nIVpQexhaG1rz0Hs4qu2cY/Bp8saaLACNIx0mo7oX0I41nsQLWmmcZfpbKHYMovjNO/zJuQMWDcFVOLo+tNciSO+I4sEK4WxObiXohGmfYtd161n5gK+YcO461k9v4vD6w5jXaNq966etwRAj4ecjLL35orovRSGpntQtPWFVTp2yuG+17K29gbjwnK1cTBMlneKuZtiUKb9fe1f/RczA5OfCWe3yw+vshGDD78h+Iir5vBPFwRcDToqDTNcxb0KvYmEEJ9ggzX8tSCpRTL5XtWPzygAyKWtEy6cDENc0y2SuTMQ8bFCpT7+jNxSzlcQgX8iAGtjtktM6nomSlrvSXZcuxgYc+IwQLS1I950fCOgm/v93YqU4ZppeN0ly2Ln6zaQwafs8mMOZbJ85YsZSx0892V4fK2eqz9woO2iblro/LC9sGgi5ZZmH4ulye2E3yfk7j82V+5jByHysvRojTY7FMNi9V65Xxs9EKnXpDzlfcLmO3t0/remj6C7IFebjJw6kJenVdqEV/E3l5pMmoWNn6IAqKN8UTN6PJzN9IbxEFWqtH70h+UtWs2rAJTqrZZxKSO0TsKj0Zwj+nHoNq5s7+FOcfrj5G09zKkODGRtFVT7sLL1arob+4mxJTihDe6CVJ9479m9VlvVpy23bH0bAkZotAqNZClQyw+KcEbrDLUHpq5MvZ4/0EkFagHr1nOO5zo+Y2UCL0+cvq+kllU6zQz2zJRoB1NQcEi+zt0q3TKBlK/R6a5n+0PI3ktmHffmWIl3V3FsxmQGcdjr/l6scEH3He1xhNn4ksMyti7FXfi5pWy4HbxKPCUPt6o7F06dl/wP9hYKChnQuYLNjwRgS3hODlcbc4XjKUvWL0hbqyvF+5bfb4x643XjctIfhq3MP480GQIficmEbrLEf78Q8Nmf8tKq4QUinqpsdTImmlaHWRbUxAOQg1bsDq5m/HAe6ErOMHzmzjBxfuOnUNi4fSLmxFEVsBGuDmzri1MIJIYdb7TL3EKxpoTj6NXhB+i2jFv42qv9XhQEyXIm850Ev1wOvP2qXGPFjBswl3pC0HuI8JwvUqNs2IUyBdEUCjwActHc3Sxr+6jOzIlyeS2BoncEU03FUqva8EKsuxF3D1YcVIZ5ECteeOeRMfXzAxvzmxLoVq22gngXmxT5BY6b3GQqk1FeKvEflHwaNOCnxV1CxqjuTSQLZmm5k+tuq3nfM/n6qNhrzbCHBY2knvA+io8mjVsFsGMXQDUVD/pOVAOu56BwDX/r3lmXReAvpL8UNhH/HI2qbQoK5XANToQodE7nJbV2Loo8Zo5xkyysYBcNKLrNypN4YRkjpQE8DBHQyBy4/Sed4m7viOt6Xllyz2cmo9bzgDGuBkuMq6+QXK7i/huS1EIN5GrGQo80O45af5XSyfXDgWDCWez+PBdxB3aEJKhTQB575SR903RL6CxiF1MYQ/p0pv8Nb/uXnUeCug5gktE6hxg17ffv0bMaFngBXxeo8+Wc35FweidH4Av1B67SWhdwlwwjlg3iMmnlZGmI8iP7GEcyQz5kpC2pfAKFV27RsPK5hNaF3mfn3iR8tHIN32QadXxlbJC6qKGiZEdy+kf6rllrJ6WapZC/EtauUoXCy4Hf8VK3zUC6Q9tnBzdQICo4KSfozk9cAIB25PEGDbMv5nPGo5UFoUCxsA3YsMjmE5GWP/9iJ3thlnvGCIwmbaLqXCWRsYKtjUmqzLv5Tfp33YaMtvqn4HUTNqRxaKuHgOnmNvfzAQ1QjCmyd08KBERmOpQCavISUJa75BOWK6UXT5pw39yF72ZFGCQaBVXc2inFvpY/3r1Ehn+x/KnErN3I20TbDf3Oxc1+ZrgR2R6Dsfz9WLcap5OxbOHGCnH7QtI3VkOjmz8Dyb7uDUMtjXoGDntdzaTWnsMiXjWfkRr5vU+4AcMawDKdf1eVFv3hW/tY43QJXfas9IYfmKxIj6iQczMzF/7ne7lm73K34KycFAiOBr4if6ooiK/yuTgs/kieSugD0urgkQNoFUgMNEhzISJDlPFGzQhtHb3BlX+0DmZtRUqa4W5H+jNmdPkHIzNIIuKIvJD++IjeMt9r7MQd00M74fUBA0kBbLiMAXDNhg9XytuwIxHNwu4yWWNrr5LTLm3LvdTRhNlw81UJ/LA7mqqvmfUFcFLwikcbyITEaSAzBjTo6t+a3x+ZzUxjUJlnwoq4SGMkS94ELCQq0gEhigNT5LtDah3iZFsY9MgwMToe7PgeAcWQb+3t01pXhWyWiSJ4YW6GhR0LyQR4nGhljs6ZOQGY5FzuVgMdei5Zko00Z9tISAzI2eP8VzVp0CxTygws3dgsfdxXvuJPjkgF4Ak93NpWYh0jQ9AXC1P2e9H81kQ7CTRHPM1GU3bciEoj5ukm98uolQt2gQUHBqOc/wSnGC6bB7/NN1NoXJkJI+gvENPakxbtUMcfGz1UeaWs/h+69f0MbiAxqKaln9yaF+czWrz13qRBE2FvCo7HFu8qrgR+gqbDAqH2VS702b4n43j910sCe5zjqP8ZtyhZdagm88sU11tJlMWnogI4mnW5aWreaCTSAKAvZ59NWcOIEI/s932uuMt9gJCYrLBqiqjiNeuzVU87oDs5fjxYcSIlf4VrFXnItge2vPZ9rNModYajsuuzQhP2m2liL21RtYYJECItYvh9FBgf1W3/2FA82ZQwhSmPFAo5rn58xjjo4Vg4zeP1vWdP3lSunhcMgTHjQN94NJvXGFT+2E98L+/YISC8OKuqoZ65WznuViRiWQKIM0scjVheYuJl8+eJm8Typ9DeL2cZD/VYhKosbdXmIrq7smgja/S3SrALcjCJqEiYnghi7GeNv5UQVsLPlHownp2CAvjGVJiHsIpK1qVIiZXRVMoKG1CgzbX7n/vinQPBv51jbLaLWonwJPvO0R7rsxu86ThDrutpH+IpdrTVBC+YoRmA4NRGW1iEmIuPbRIMtIFbqyLDUgSxhG7YjoUl7RsPiQpNNBdCoCPBFjE0cUIyHMyHcyzVd8b3rRtbsovpvAu4ZDlaxAWfPIWHeTQRHmy0Pv7+GqRVIqOA9Mqlsr5YTKFvGA9W3jK8kG4R4hspShoh6/CKVJUMfrrqaJywVqN+3yI2LIFC+FLx3cOiycBUIfXA9veJ4JW/6cu9UqRJBJCf9oui8mwwsBAOws5GB2KLCBpoilagu0sF+Kjdqp6NfqJV9m17yqUR3BgrKYasI27VBQaH6A4I3NcN+KZbhoj2EOeptPPJNv7Ozj0eTPT9Oj6ik5M3xGWV1DSDQRoyDXkE7mHrKjTafXg4olcuZ539zKKvOALbH9c7xZxE0UYLus0dvHYReTKZguEx3rTZ4bqmaOx7kgL9JLbI/v3a0N0ZL5RbZMgsmkw5SNdmV5mBPAcvazrvamJChCQvX8zzAk4UOKpqgHq8W0m8qfqPejtn+VZtrbCG9nsX7qnBRAhO/e7sPdSr08aU6V1kEbr360xsIR9fmvqcdvqBNxFM/I7YlRlysP6ZIEqkfggW1Wk1w==", + "MIIeODCCC4egAwIBAgIUYNrQBPrWICmRSM68jjKm8bqWz30wDQYLYIZIAYb6a1AJAQwwRjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJTAjBgNVBAMMHGlkLU1MRFNBODctRUNEU0EtUDM4NC1TSEE1MTIwHhcNMjUwNzIxMjMzMDA2WhcNMzUwNzIyMjMzMDA2WjBGMQ0wCwYDVQQKDARJRVRGMQ4wDAYDVQQLDAVMQU1QUzElMCMGA1UEAwwcaWQtTUxEU0E4Ny1FQ0RTQS1QMzg0LVNIQTUxMjCCCpUwDQYLYIZIAYb6a1AJAQwDggqCAOAg7kVH0t9alzHvlFPEjw4/mX+UIJCYOpfe/iC1LJUQeuZyFaUHsYWhta89B7OKrtnGPwafLGmiwAjSMdJqO6F9CONZ7EC1ppnGX6Wyh2DKL4zTv8ybkDFg3BVTi6PrTXIkjviOLBCuFsTm4l6IRpn2LXdetZ+YCvmHDuOtZPb+Lw+sOY12javeunrcEQI+HnIyy9+aK6L0UhqZ7ULT1hVU6dsrhvteytvYG48JytXEwTJZ3irmbYlCm/X3tX/0XMwOTnwlnt8sPr7IRgw+/IfiIq+bwTxcEXA06Kg0zXMW9Cr2JhBCfYIM1/LUgqUUy+V7Vj88oAMilrRMunAxDXNMtkrkzEPGxQqU+/ozcUs5XEIF/IgBrY7ZLTOp6Jkpa70l2XLsYGHPiMEC0tSPedHwjoJv7/d2KlOGaaXjdJcti5+s2kMGn7PJjDmWyfOWLGUsdPPdleHytnqs/cKDtom5a6PywvbBoIuWWZh+LpcnthN8n5O4/NlfuYwch8rL0aI02OxTDYvVeuV8bPRCp16Q85X3C5jt7dP63po+guyBXm4ycOpCXp1XahFfxN5eaTJqFjZ+iAKijfFEzejyczfSG8RBVqrR+9IflLVrNqwCU6q2WcSkjtE7Co9GcI/px6DaubO/hTnH64+RtPcypDgxkbRVU+7Cy9Wq6G/uJsSU4oQ3uglSfeO/ZvVZb1actt2x9GwJGaLQKjWQpUMsPinBG6wy1B6auTL2eP9BJBWoB69Zzjuc6PmNlAi9PnL6vpJZVOs0M9syUaAdTUHBIvs7dKt0ygZSv0emuZ/tDyN5LZh335liJd1dxbMZkBnHY6/5erHBB9x3tcYTZ+JLDMrYuxV34uaVsuB28SjwlD7eqOxdOnZf8D/YWCgoZ0LmCzY8EYEt4Tg5XG3OF4ylL1i9IW6srxfuW32+MeuN143LSH4atzD+PNBkCH4nJhG6yxH+/EPDZn/LSquEFIp6qbHUyJppWh1kW1MQDkINW7A6uZvxwHuhKzjB85s4wcX7jp1DYuH0i5sRRFbARrg5s64tTCCSGHW+0y9xCsaaE4+jV4Qfotoxb+Nqr/V4UBMlyJvOdBL9cDrz9qlxjxYwbMJd6QtB7iPCcL1KjbNiFMgXRFAo8AHLR3N0sa/uozsyJcnktgaJ3BFNNxVKr2vBCrLsRdw9WHFSGeRArXnjnkTH18wMb85sS6FattoJ4F5sU+QWOm9xkKpNRXirxH5R8GjTgp8VdQsao7k0kC2ZpuZPrbqt53zP5+qjYa82whwWNpJ7wPoqPJo1bBbBjF0A1FQ/6TlQDruegcA1/695Zl0XgL6S/FDYR/xyNqm0KCuVwDU6EKHRO5yW1di6KPGaOcZMsrGAXDSi6zcqTeGEZI6UBPAwR0MgcuP0nneJu74jrel5Zcs9nJqPW84AxrgZLjKuvkFyu4v4bktRCDeRqxkKPNDuOWn+V0sn1w4Fgwlns/jwXcQd2hCSoU0Aee+UkfdN0S+gsYhdTGEP6dKb/DW/7l51HgroOYJLROocYNe3379GzGhZ4AV8XqPPlnN+RcHonR+AL9Qeu0loXcJcMI5YN4jJp5WRpiPIj+xhHMkM+ZKQtqXwChVdu0bDyuYTWhd5n594kfLRyDd9kGnV8ZWyQuqihomRHcvpH+q5ZayelmqWQvxLWrlKFwsuB3/FSt81AukPbZwc3UCAqOCkn6M5PXACAduTxBg2zL+ZzxqOVBaFAsbAN2LDI5hORlj//Yid7YZZ7xgiMJm2i6lwlkbGCrY1Jqsy7+U36d92GjLb6p+B1EzakcWirh4Dp5jb38wENUIwpsndPCgREZjqUAmryElCWu+QTliulF0+acN/che9mRRgkGgVV3Nopxb6WP969RIZ/sfypxKzdyNtE2w39zsXNfma4Edkeg7H8/Vi3GqeTsWzhxgpx+0LSN1ZDo5s/A8m+7g1DLY16Bg57Xc2k1p7DIl41n5Ea+b1PuAHDGsAynX9XlRb94Vv7WON0CV32rPSGH5isSI+okHMzMxf+53u5Zu9yt+CsnBQIjga+In+qKIiv8rk4LP5InkroA9Lq4JEDaBVIDDRIcyEiQ5TxRs0IbR29wZV/tA5mbUVKmuFuR/ozZnT5ByMzSCLiiLyQ/viI3jLfa+zEHdNDO+H1AQNJAWy4jAFwzYYPV8rbsCMRzcLuMllja6+S0y5ty73U0YTZcPNVCfywO5qqr5n1BXBS8IpHG8iExGkgMwY06Orfmt8fmc1MY1CZZ8KKuEhjJEveBCwkKtIBIYoDU+S7Q2od4mRbGPTIMDE6Huz4HgHFkG/t7dNaV4VslokieGFuhoUdC8kEeJxoZY7OmTkBmORc7lYDHXouWZKNNGfbSEgMyNnj/Fc1adAsU8oMLN3YLH3cV77iT45IBeAJPdzaVmIdI0PQFwtT9nvR/NZEOwk0RzzNRlN23IhKI+bpJvfLqJULdoEFBwajnP8Epxgumwe/zTdTaFyZCSPoLxDT2pMW7VDHHxs9VHmlrP4fuvX9DG4gMaimpZ/cmhfnM1q89d6kQRNhbwqOxxbvKq4EfoKmwwKh9lUu9Nm+J+N4/ddLAnuc46j/GbcoWXWoJvPLFNdbSZTFp6ICOJp1uWlq3mgk0gCgL2efTVnDiBCP7Pd9rrjLfYCQmKywaoqo4jXrs1VPO6A7OX48WHEiJX+FaxV5yLYHtrz2fazTKHWGo7Lrs0IT9ptpYi9tUbWGCRAiLWL4fRQYH9Vt/9hQPNmUMIUpjxQKOa5+fMY46OFYOM3j9b1nT95Urp4XDIEx40DfeDSb1xhU/thPfC/v2CEgvDirqqGeuVs57lYkYlkCiDNLHI1YXmLiZfPniZvE8qfQ3i9nGQ/1WISqLG3V5iK6u7JoI2v0t0qwC3IwiahImJ4IYuxnjb+VEFbCz5R6MJ6dggL4xlSYh7CKStalSImV0VTKChtQoM21+5/74p0Dwb+dY2y2i1qJ8CT7ztEe67MbvOk4Q67raR/iKXa01QQvmKEZgODURltYhJiLj20SDLSBW6siw1IEsYRu2I6FJe0bD4kKTTQXQqAjwRYxNHFCMhzMh3Ms1XfG960bW7KL6bwLuGQ5WsQFnzyFh3k0ER5stD7+/hqkVSKjgPTKpbK+WEyhbxgPVt4yvJBuEeIbKUoaIevwilSVDH666micsFajft8iNiyBQvhS8d3DosnAVCH1wPb3ieCVv+nLvVKkSQSQn/aLovJsMLAQDsLORgdiiwgaaIpWoLtLBfio3aqejX6iVfZte8qlEdwYKymGrCNu1QUGh+gOCNzXDfimW4aI9hDnqbTzyTb+zs49Hkz0/To+opOTN8RlldQ0g0EaMg15BO5h6yo02n14OKJXLmed/cyirzgC2x/XO8WcRNFGC7rNHbx2EXkymYLhMd602eG6pmjse5IC/SS2yP792tDdGS+UW2TILJpMOUjXZleZgTwHL2s672piQoQkL1/M8wJOFDiqaoB6vFtJvKn6j3o7Z/lWba2whvZ7F+6pwUQITv3u7D3Uq9PGlOldZBG69+tMbCEfX5r6nHb6gTcRTPyO2JUZcrD+mSBKpH4IFtVpNejEjAQMA4GA1UdDwEB/wQEAwIHgDANBgtghkgBhvprUAkBDAOCEpoAWVLi3Q3BuWR/u/9bFkiJIC6wEaSmhDcMNf3ml65pzld+tlS9ZQ4bU0rUSZ5cguGqIySeVZipPFGnTtACWU+/zxL3fVEbCsubuLGVfZn0n+NPzzrbQByR9ns3xPvMl6MaA2ASgqp3Bg07PIRfU4AK/pX9CXYnRkIwQ5oVv1et2JXY9fKPYSc4g7iOPAn18WRuBwPplOvnoJXGbaRZ2ZwGf9YJ2zth0XYq7cIL2FJWnD2USbxKLyuDyOzyrsvgSYXPUBzdULkDbe0hc8F+JsXFaAc6zV9QYnU09pqUx284xjnkPGZRQqBcIEXul9YgbJPpveR1WuRUK0y3lbFgg7f0zLXyimPh+bML/IdpnLydBl8GIMyQK4bN2Ydiy3WG4Fm9am2lvcZKgvCuUwO0D5CdDxys+4OgUCgB0n/wCmvasnp1xT8x7vmHwox4ZfOp+JRNQeEvxPMxvSPEHGefbqn7RgepOEqxTHiS6GDKWrfnhCZJLmqTHoSkUC2AMQF1zCJMs45rl630WgRqk1M/dxTvMgI3Tglrj5VIPfVQGM4xf8zEaFeo5//KHNDlwq+WQwq8ABoHyjCMjITXyXl/AagqOEG4vEEKEcjqXbTpIkyq9Boai/AJ3BivprXuBU5bhc4wZTyGXIS3D+4wZpRNEGHB3NWtnklBXI8wvkC3V5oEXLKWLdzeo+GRo9pB4GT0kg1gCNhjUElOXo12xoVMBFQxyX+bUqnCNAwZxCfbsNRyaoesNMnBF0hvKBGmqH5qGJ7RPUHDEfBKplB3RsxF5BfuLbag1tYKbAl7S3+jW779ft+hrkkgEntwTGgwM01jdN3+5peTSRzMAqXjYvU6r8vxoXklYJ7oRBoVK7uaTnwTVWdseHz9lMyWnu6RFEOao2JjZttvDGFroaaHWJhQxfHebWafv34ldmnAgIfpPoQkndixb/khLGDTIcJKRHQtIz02qO88xZ5qIAxalVVZqv5V+gToUTJhiSCMTjybddaUMlFTUnGnyK5My/LA9Tz901KM5pQ1pRUSEvvVzXeO30pSm2aPmCoRx8t169M1zc7llV4Yjz4s1uVRS96gexVu1HEp0IVtcyNR4aoSUMGH74FiOxEcKKo1gK++L1fsJYFF8sawbZgcQkcTsEiZ2bdEFZ556w58V5bmr5qkeemL4TykcXvrQczg96Zijo2JJz0A+pX+JjvYWSOqhl+cX+VS1WmyXTMwYFf9h77ZZx0RFTbqGB70Jt2NAf7GH1Nvw/3ynWw9jJ/hUkKx8Ymu1EypWiraAb3mubCW5tqLTpuQcVGchL8ZFCCHSpcSjyRU9FtpWVEtRJWvK2kSRjUuYblQQvrVpDp+SLRl7tHpbK41QAw9MtzdXFkGGR+oQTjqaLFHDOzoxrGYDlU6O5qaSUsKXgAbbdv9jViHZsi2WHzcjjHiyGN1BzQpTEg0qpBgWGzc2wffdJ0WzBhl84TmspRQdR3qxOakH4Ninj7NDXoAZqGDLkzsEy9J7kff79rDWnTvXil0RHbZ4Pt0HKJBzEhdZeEa4LLfUfCCmmp6Hb9OYQDw13jyRL//9IeGYG2bs9Wwa9mi1MWP0aMuhlgj9Gk68lycECu6QNS6aooaolZkZIPuMi5kjmxpNs3tcs3YaRxM2mVTPzAJfXIsOCSbVWRFW6+EY4pFSClr/e4jojOpXtuhnR+FjrrN8Uv1gM7vMFHtLW/MhIGjrFhM+NzFG6H8Lj+NWgv2tva5xeOrPpKPzi8ydHbFP9SodToeUsq2+afz+moxUAPlnfwWG7o/G3ZDCRviTTmHoScVFnOXVGenDbXcKF9RUOdGT/ji52VWRBsWQ+edFBAnRessQvhGiphUSYhTccmAZhNusTxhyunWz0xV5pnbmtpuilh3mw3hHnDEGVc5xOLIStyGPScvYM3346srJC56hhdiVZwxRq4GZixWEsBRLtPPt1HEEgqWKqz+dnm89erez886i8+reB7VhVBvqynkKuMdgIHfUEjup0ihr1/jtNMYjzchzmi4RPS2H6NfhhHc4ysgZMUfkxMvzCqtOAovcPCEgjWaxqXB0xbJLzvMCGWjbQZOUXxp12CnbFf84g+lYDoy2xlYq1zNinOOfZGzyp7E/tm/cF6W2Yog66+a0CXi4gNolizzfAY9YPn8TbFNVkMgT04r0+dLMqk318cBNFX3sHItDAlioKMhE0LuhZiXMuido9is73slk1X/uGhyFEIdd3eEu/6JS54FqnhINPJflRcFvt3Jxrm5LY1/xw/dO4Du9AqVym8Fq+KsCRAGOLnJ8jgRUwPUNQWRxHH8aHjNrNzTOG/Cm8g+Rc97Xlzs8QUbGJgVftzmlfm5F5ylKsx+CR/SxxlpNtswppFwh8HcJ8k2WDFTkVResXTBMlynauC8KLxpN73Rtxkw1hH7YAbrGZTvNXeDLEB46PRvockk+AXK5n1iiCJ6kpddPt+9RxO5dEg0ijIpDjXYX0M76yYZ43xEEm26AU3d+pnjrL4jt5YNOGb+l5S0FxPag77V3QluM/NTSCMLJ9cNwsJ3WOgB9fv3bBXQQN871JWkn1i3oY2KHvxv+GT50ZAqlBQMGISLXGjURsUlvvoZekbwfz1rD418QrpfwzCNVG+12nDBGBT7tNVrSYb/K7hsUfiIy+uheQOUArh6s9scnBR1qx6XBhR7Ud07Og1CH+w+TEP5Y9qgm2quaOb0rYLh8Rg3S5P876KwPWFALITrevQ5qIUn18DqxZ5FeSp3vAzdtzvBFiagSN+B4xBvIsu3nIr+GHQBwjcpanFiLjGE7hU+Z34z2lcj6nBpc1a7Oa4eN8ormPGaJaK5Z5kgmfkY7iY+xocOgDboJHwcU7DuwQr0JcB4XWomL5AHjG752L9caHlPZ/PFle3GjXBLZiX7C8OXBOPB5gOt3XiBrDY6WQfUoPp5ClTXRNwExTRAnEGuwP7oHqhDzgpNLA/VVMmqDYmdIr4ymSFHYTkE1gkN/dBGrq7UcoRRSfYPuLJHEV/P5SjudB2ZOaIQlw/XulLdGu3FzAaDZ0vXvURBHzoNFPw2kuZtI4Vxz0hMDK2XCzBRwbbyz1/QnLaTmJxwnhyF+GyU9jbR2GKtbM6+5pq7jMTEOkvt7fyN5dohJzh1UkisyWAmahf7QUbz7v7WotRLawpYMwAl/I3KlyryZN7ViohvKWvhY8TC+L1OPJY+wBb4C9yzjHnmT9rYrssVJhW+eCyjnV92M13ZtNmsrzzTQpQuZDQJ7JTVYEuAgWT8Adq0KG2q84kGJCJM902MUXd2PewNHcqnOwC72DiXz8df/eRJm7mTrDG+03ytJW9uiqg4H1jHK5R+Zet5v5D8I+pfKGncT3Jo8UQ4U4tsk+uod54dXQLqdmWksoyLk7rAUaHnnK5o7Sd/pZck4f6VQj47gto70IfC1heQrwq0U+fUK6MZrICOAOj2f5zHBt7wZPJjSth7BZjT6UBYPJR4ubDEbpEP7MPRMXzDqfrATajPnzcP2/O1QDNsOvX2pROavNdGnjuBYexi2vzI9DBX0SW3K7MmpG4l69J9QMJ46X/30jV8cWshHvsVls5BmRlWWtp5xf24A7eEf357FVaNdHy3hcSTek9ab5Jqsy+TwbFG4bXtSMC0eBsvEq8i9ZdlmPGMWAkkYBZXRmewN8lLO4QIQVEh/eQXUy9YfMpcSIJ4C3PSD6gSf0okCSg1ha5yQLz9CeolvuWX5Qr2Ew7xa1HSO2uYeMnzKXmJ3T+S7as4j7wFhSGmI8v/8P+V9cyhmzo+wYsf1TkBCNbf7bnLE8eafraReRdh+L5dps2pOpsnk++o3Da5lude0Yj5rH4oDAAm11kpR9eiiM8ihWVqbukXFE9CajEWEc7ePGg4BH/kW1vxKDzJzFAfcdGE4psD6a1EZl1BQoVSTEJDsb4wP5B3Lg7FyPIUrbd1wOBXFRG1tsByralMwyytAlQx1LpIg29+rHvGlbtnTQt7PfyOl8+T9FsofMYtXXGd+j1iJzzFrF4rFva9E7yni7GlTcQu31N5lB4oR9L0TQeWMSzPVk6NWOSHCV7oLfLN/FlMzlzwFd5TwJIZQmhxY4vdp6i5J+v/XC2W36qth95NAukRTx8pUYs+3Ges3aFU5YFbFT8vWDM5C2XCA3z84Ic1LGdYL2zziUqHrluapmsOZqUn/pDQ3Agv0uoVdaZbgHpm+Pj6L+jRcbQ9/hn9v6q2hw9Dcl6f746aY0kpKgcadMHxtaazOkgaj9VET0vVk/S0knK/+cdpxvSRjLg6yVS+RkF5hK9IU9rOwg/aU0frd0npEKXeuUzqim3tPo7TEem/24mC7TCkaVG5+2A1en+fuTLteDr32Do/AMwg4HnWPphbKxz/ikui49FjIf+ajG8SF7XeXOci6YL7vJqN2x0Xw9sp41kPy0GdLL06b1lsVntzH9Kh5VNLpAdrCrppIwIfl2AHvPeLfmTHJs/gdUPUvBOWNHOyXD0ekJVF2nB2KuSZWQx6zPWI3OKJSgS8/bFKtWKieyFJHF6A0/Sbq6T6pGMUMh1oDUr/Ve9XDwdPR06XLxqQCLrTnrI02apDdjcQvvvLECRDYMvvTcl/aGiRnbig4xUzfxCLstin1UID7LmDD7KM5WO1rJUoATw/gfEuRRug5HO9JT235DbGXnYt9XM9iNK+zajNL0IB2mqCEyLUfuZ6lxmeSwEDRjGuFS2b1R+0Jec2PRhWD+aDKF9YtOnkCLSPW+ceSNyfzCHrctngFw4C8Ow2Uo3vFLztT7LCr/vA7UfbxzDp8TwrXKFIA/P3N+Hn0jQ2i6wHZ2s70H6TUcivp+/7fC8Ti0LGqgcxGCpPR+s6i+L7Mm3IZE+TKhtHzWlKpNQzTvDK3lzO4kO9hGaB8J13dyRz/sYmAV1al2SFR1O9aRNN5DaLpzSyETWX762iLYHTo+Q1iPEsGnr6kXvbbe1WIZUGtb8dy9rtpt/45WcCMbRDbvqOXbJ/v+aUGj4ZQnwVaTKBY8Tnf+ytHShujctoA5SQXlDeeN0dx1V17+0eol3ZUoYunm9E3exd+fEAgQfBSzYOm2+vJCb3DTaKKMTzvQSiffIuINEVTiuszeIb30pnY6d4QEGYboy09+i8gLO7kITg22bZNNDXfQq913URQvIGZ0mH+8mmc7Ft3xi2A5A+M8KGE3wjT/hF13fQiP+uSSZzYKa1cf+6jg63urLfNcjDvIQL+LcCZ994q28kZ5bwagj6zPuUxI923F73Jp3gMKKC5W1W6SQqU7b7K/Kt6wSZ05I7JVFOuhPceBi1cMXaknKGjNoHFGx/rmo3CAfUFlRl468SBA7LGHXEZznAFDCJad3IAETxXqoKWLpPfzdqFegPsUOVc768exb2U6My6LWHjWXM4vWFbTTNJIxn6P25fF4QGLK3Nu0MJaE/5tgpV3NT3yXhEGyTDfK9TIdTN2iNdn9uIlqWe3JLDds2HhGUqI0FkctwHs2Yj7cM66SW+XSzrC1pcICJg9tjnTI96oWMUeG43929x1uouabbdDufrlP98d0ydOL2HN1Yel2o7IUSASmjOjIgbx8mTl2i/ttVnAqcTqrStHrKCWYF3GOwMjUoNs2W2ynuNccRh9LHl58an4mTPSZm8vNRwjtbkZY/BVtWmH9lP/K5WxVNijCn3qS4y2lgZqCkPLKZ+jggFHDO5DqakNMTuTZhEStdRbWP6hX674HgCovWOEMydR4cjkFZOhQds8/IRwRGgiT/EyZmU1TW9Yo0q4UIcZ5yD3n+V+PIohCMGdAE28NSc5TQYQRdDkzYFrrTt1cegxhXfiif742MGHfOjZTkvbrgwpSDgvo70XDEsE3D/WWswHAOYP9C700oul6rpDfw3Fvh2tql+Akn0NuXW2KaqjG8CsEqRwNGRsIguC3yTFpXaGgrv3ULkgx84h6shyUNuLMDF8manVuqppISuQ/b90GTh+XErqFqCS6Q1s9yEjN/eVT5Iq2vtxaYI7SgoghO8+35W3FalJ/QrGuy3FJ4BP08VQY1xewfMBcnEVAK3HYcFhqu+46MsirrfSmT1G+z84UPvOC1s5o0d6Xiy9b9qDG829wc0tUb417TqiBtdImbsrQSJJj+C0VVYaXGQ2Fse4Cmr7fb82CFh77y9Al0fcnf5BcbT2iPoKwBNMvl/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcLERshJy4zMGQCMEDvfMT3gNhnOeOxqdCv4QeQUEVLxgreNwSNE1+apbAj3jsfixKVzA1K314NyJXB5wIwDYduuZycOpAghGyMIBwyfeWAPt7b24X8fLKGnoB5698aajc3n4QxZNaNzkTTH2uf", + "jWuxBSKyAqFLNs1/gERGyF2z3K3fEEGrKkWE2CgliPEwgaQCAQEEMIwKkVG7L15IiqeT3BaQbnJ/nY3MXa9PwSxK5efhJE9TH00+zVsbbWWq+BK3f9gBLKAHBgUrgQQAIqFkA2IABPAcvazrvamJChCQvX8zzAk4UOKpqgHq8W0m8qfqPejtn+VZtrbCG9nsX7qnBRAhO/e7sPdSr08aU6V1kEbr360xsIR9fmvqcdvqBNxFM/I7YlRlysP6ZIEqkfggW1Wk1w==", + "MIHcAgEAMA0GC2CGSAGG+mtQCQEMBIHHjWuxBSKyAqFLNs1/gERGyF2z3K3fEEGrKkWE2CgliPEwgaQCAQEEMIwKkVG7L15IiqeT3BaQbnJ/nY3MXa9PwSxK5efhJE9TH00+zVsbbWWq+BK3f9gBLKAHBgUrgQQAIqFkA2IABPAcvazrvamJChCQvX8zzAk4UOKpqgHq8W0m8qfqPejtn+VZtrbCG9nsX7qnBRAhO/e7sPdSr08aU6V1kEbr360xsIR9fmvqcdvqBNxFM/I7YlRlysP6ZIEqkfggW1Wk1w==", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "FFLDJfvIWWcTvNL790AcyaMUObAEpNXlFztIPlLwJBfB/t42omzsge+q8mj41Qu1JDP6/U0qERmqHIHrsDi1IlJhjZCSuV0u7iV8dAelDPCuDG04+Otc7omuaX4hNdGu5kfneFFZE+mNqQslSNpCfzTUGmA0qengF6YCLEbiVxgT8lw2hW9Ett568BTdLEADeGPyjxaJPkt5E00TgdGW8SerU24ebF9ucsh/zfzzB37h5NIv6Zj1903YclfeZdVqhmqqoCIhtNAq1TvhqNUM7RdibaOzxW8Ffetq4NynjAd6N4/ZyXrfw0tJIGZjrZKSltiFre6PC/PAvaq9DRyLO6tKcHk1zJ4TXuXhl2g0gsi55b9wH0k/mdGMZkx/D9hRYqOMJkwRxUHxqVO59PIa6CrYnrNTjK3bZOA7oLTFZrwmzzKUoXQfJeXeGQ5FO968ovlNQkBeYTH5ZTCXGHaAxLsU6hOHjLg8g7rsV8m5Y3CEUpid5B9OjWJ3PnNg+VXXGbNF3ejgUOvhcl+0eAUovJj/gGyRZvbai/vc8r+XZN+iXYzHHoIkv3lesZkngKjaDX0YFAMkZwoM37pNxpRtT6l7eHpWMR9Q++XERe/D8YC5elWneCLdqha4McQewCZAR9s4K+w/+ZDmvAMlCe/XPcv3Ytf5zf4OOS9fSeI622RS6WnWtrzQHn7uKmkvm7+dwXCV+R4SxxYnVUEPCl9a+nvkOd4gVEtR0ouXsKauvkwvP7sFhFgK340nus8Ocrn4rUg2egxz5UZxlJs58qyPCy164wq6uuSSEbqIaOyC6FYP972sPNGWvOUpBQP8pC74BZAyjqjT1QSw+WT9udBSVQwTbKBwl9HWZkPAGUzEoaJH1IGkV0Z0/K1eFt1q3hSqeTU0CWbD9GTpJ354VHh9MhskBzjbotjNGcEvvNhd0PICgLk5r/fXZB3G3pOs+1xOW6VRqJ+4tdVKmNa8mlZbImL7GZAk+v7rkoeZz5uDPzMmu5EqJ74JgHL1YYPsSFn7nVlDl2XxKup0uH1y8jgpVrwPumQ/wICjerhUdCruzp+HIERuVuQqqcLBBPLUhOxlznkjKWoRvkndUYTqhvNr1w/cVpNJGmZWEQblItaPim8XT+4h67pyBDSpCr2qGosVv6IMjxD0BFq29Jx2IiBYZ5A9eN4+f8liUKJHL78Ltwx21/j/QvWzXUecjeRbXiwYgCRUDwfvac+AJ/WKG1DOpWEmp/AXDxXHShXT0r4odpl+w3wepMu79XGZBUtH0Ur674S1NdXQmzracP1koE8Tg8Jajcs7yLbjm24LBCPu0Kw4Ma5upuuNyHR5c+LPIPoofpNXL66bz3/mfqXPzL9jK4OgnUYeYSJezcF91X04DqDOB0d1/1N0prwhhNmvJMukQKSz3pU56J3ZfAxuGGsabmBJ+X2LI/90jljlXvPbGH+PDr1QYU0yxqItMUfkU+0QpfWC+mPKV37XD6TnFlyeJ61V68atJUpbnPgGVu9gmhhmV5UICx+CDRryAG+bo4AtF65U+N1uTLURsWgnnbqTybpdcQ3u6qljInqbTuGPtHA6We9J/k01uXWupykDyUtYSvFqoansE6V6hPVIlAlP3oMpSXg0840ZDY1DMtZc1dafC2l0kUKkNh3CfBnaS/VcV/ZaIASXJsqLpcrBZx1dygc5qU83uWJZ59nnhF22Le9GLXno+a0/btdXMbV4gsayjoEOTwErUwwL8SsGXtzFZfNuYQcH2T/1etbfYZgwNHlQRS/3bPOezD6XkyvdazWhkJZ1T/mJShKN7rXMrI0XSqrUP6E27hOyiwcWX7CnXpjXN3Uv1jWyQ7wvdv36jMfRR6wXLt6Z9LOhqBmPaW4nf4JtmXtGWl5FfgK631Es0GwJAJVvBGKiVnjONJNXYi1YUOaBZQjGtKhFBlW3s2gse5P5Bj9wTFmNodtvGOOu5X/64qo8jKD4WionSWqlCh0i3BjUAqWZZOUjP215z4dOMpYXuqsH53CZPrBp4IECM787AGjkT5L/OzNWe3o1qdPwF2sbvXfgMYu0MSTxKXOmhv1af/b9fYIqgBdsT3oZvXwRFlhO/p7Nx+FeesZ2yoOa7ITcAlf1VoHOQDBhplAAN9YDJtN8BeieJE7gMKQIym2DOZtFAYdA5At/vo2CEdQjVG/WAgZ9rMgJ4qS1qt6qaub3WO13wImFzjC59pMfeeALSXWWsToCMsAThVppL5+RLbUEdpKZx+Gm3ewZjNs3jbnIy7pdUmQEDJNA54dp65AhFhTFXZkZ/Meaj1O0g//EQa8Oh4dthDzk750g7gWNjg1sIHXF5K7isM0H2XtYOQ5oxq0+mX6RXmjk9QFA2IddGZ3s3NbgVFpzXTTjNYGzKjN5my0V0tOtbFSd6lgpbUyOR/NdBEZYhWHC1iCc28zVX6bX72ODO+YLnyckfUHtvJ0ogncDwJrXEckPhgZMXrZ4ex7MQY9u+OzqJBew6QJ5Lda12atMJ7Ojy2d6B1Vsqy5W38IdQbqGob97uLULjrMfaFHyI3rmfq2AIZX7oCZcZ+S7bdngj7WPiVfN32ORi3hMSzlQ/Kv2mHjrVxu8ec/lChRtCiM89PDRFvthAyoBkWRxurkPYEwh3OoapUCvo0TjK/745EmtMzVIVJbVkcOmfwjri7pLCZovmotCS1tJAslppmF1TVxJz1zqiJ1eWTyg+AFhzvrfItkofx+y9PobLbcUP/GRiyuQlDPrXX1Vg2EWnB7FoHco6F2LD7n7B2TpcSAYJlLHT2KktwffclVNlBSKeXncp8M8iWkyYgdlqVC1cLj7YN0MXOZ3HkOF7Gja2xngqPGYUjdjTzkVFM2TBU/2ADhjfLjNyS4NdnUilb1t/ef+PIo68lomhYewBqslp2EvdzLo+de5rUIS2wGnXMIgxePZ5UIhEyPmus4LBhLqFUKpPX0HFSz9fKVnkgaVonxN8jaXRRitGTsmXeyKUuKwMMH6EoBHiRYV7OHUqObv2w+KwbR97EjgSr8GHlOD4aVvZiRWpPt6dZMNaaUfHAI+iXXvrdXJk2iHcqIjNNDCJdCAb49yOsSk/DZMvwsk9PAMZvikr5WbuNx+B0G7kAgIwQWkvqtLaipMnmcYkAD9/gEKl+2kkz5xuIfle0ym2vPUieYRb4y8EJ9km0DKxQ+kTNSLjMcLWtJzxymIGcZsc7vnHNgOe2ys6yXgSSXLuRxh1Qh6rFoN3n05WnctgTHTZTa1KVP8DUy5mbiq2/oWBkq4vRIdT/QuQXaRf9ZHHyDWVqK1EJ23yxaXx+VpURyC8lXKvkGqfvQkNtqAAvG4Ts0LwagxNx8Ai7Zw+ncqOIT7e5UaylPiX4ye65yxoUnHNvqcGcfW5k2hK9Yr0xOe0MtBW+v4kZ3SuY1P5P5RFkI7kAPP32SJOTQbByJStz3C4HptMTwlcsw6PKp0p2diley7xDoD90l6asTV6q95Aa/bNxQy1YYzD+twdVgH7EcciMDmvQFGGhahLgyXDcLdOnoWue8Nplca4fa6iNADBhEsoNQipCNqU5zaYWgDvMixx1F1k5FGtKn4bs+alYhdtJ80BU/LFuLXiOGhRIYuNoqPyctTca/Klauu8nwth15nXzk4CZXLA28MFLZx1WGAOmj3KoTCcGnYMeEdxY5OkM5XaEWmf25VCs0lL+xDDwDIV10Zjs6HACzGOMLeOvaMoYBydiA3Peh3/XVXYx9gfMGOm33MNbhjd2ukZLJcdaLYA/4b/M4NCYGHyKPCKHFV0jPO3zZRQicjloe9qOZ6kxVxzOYCOKg04ChjwFdLhZ60ZLsvyJZHqMWV21oAe/zI8cIyA06N0PTEMcFsOmLONaxLVpxCRUx36Ku9PBKAgXoim8+KiN+YKtfAklQy1AKKJM9R8pweI6xAvtndCkIBW0JNyLzE8pj8irPqJr7Mpza+0BH+Qlkfwv0NUwiPFvUvlo79gXLM8L8jgnav8u+oPC0iTs+kzC0fy6vZftSvOYdWKuKhFvG22ApuQiHIECWueNu9NqfjMq2F4dZcf4YOYALbPMoGYj6qexVct1afRnL3QjAHUjx9mQaWTmJ9a8J0MU2fCQbMvdPFCBrAXmlmUH8sL7h58/0Z62VsHNUD5SxSbtTf7V3biWRrAn0qYHq2xB4GHVzh3YaJO5Vd1ZpNXchkryJRKG4duNUDN7kPx+jYRd1SnLOJ8tGVFrZI4zEDJaEw++IaGDVPTNKYZffbYBgrJ6LQWs6nzU6PEOVxDgQxJq1OqcyvoSP0oZcX5ObdbqnlyDa9Ari349SGpbeEmnKfGqXc+gkmWuz2RNlf2fB0bi8REay8So+4Y7WOxuT2IDnPi0D9ghSCjrEeU0+LGf8bqniTpDiIA7q81CUNNR7+wLEB+58zd1rCXUeQ2FYgn4HguTkHvvvFlNH0T+uDMKybyRfqxi7hbydAk36774v3wX6Ox4ghdGPJAX1weniY0zvPdBT5ll2bDWySHGdcU3vybaDmmnxya5h7e9MtwtDAaiA9X+9nj1kdjv094D6H1TlV0PmI0FjZVC//l+wj6s2a4kvylrbdIGfGkPLPI/CvIee8IgjiYOn/HnYyWGDd5sfu1EI3VyoEBaY9YciyODlGhGlySlc+qhFJ2LCAEwzRw8hwD8KQjHoWEBDjGNDdPn7cM2BPEUCzhQrS8NnEZXkqC0b4QCFiSdu/bTH+WgJ7Gns9RV/Hi4C0bjY2SR7D1hhN02ZziwgmciqvqUf6uNVL6Gt2BDrbYUsjom/OD559SLhMFmQ8uNQ68iX4LOG7KuzXF+3e6NprDup8iUG5IXNF/QWG/Rc7XhlQeCGVloHhVAnkJir1Piei+8yjnKKQ9PKl6SPIA9gf7aIFq8cKfnumlr+mSKoHiNO39+8DOC2XhmzHzE/zjgb+kwwF5eVvye+svOjbXdK1DXpzpYxHNMGff+qpoaTMKhNSS0IeCvC6DX63nLhjvh+DLgFXFn7dG+TQH9I/Ed6BeiY/J/8X3PZ+kIYp87RMIYNS/u0KFHQWqRZGPVrvlXU/Ck6sOJCJmmXSKvKn8ep5DW3LJOypM9pIx9DQIVzSg8CNE6QMEwMRAismpDRgizbQ5lqaCIHImn51X+MRBs4gK7vO2MF3bmKPGsMWUPb7SxGbDRWF85zMyeKofsC2A4MEbk2eHX1rowAyfjkaK1UhXUN6cJu5r6UI4fCROXDA2qL+0BpMo+iNofxBTu8xbz9vwEKHquM3rtdIcwLiryD9szBG8XGdjvVHzMiezPsA/vDhakrxYW24iy21E+maf/NlE3aASLMd8RaYBxbn5NvRDXA+YKna6txxyMp4s1x4hAJ0WsypcC6Gzsjnm37FNokViwQlb82hjH8/Rp3G9TAZPtTMcD0A5BJdM2QJ47fHyt+ZMv0YMXUpOKA1ta6N7FD6iRrkltIWPKwIbkwKObgJilHMtl1Fe0BvBYMwkCkW78fdw+lhUhCx/Jl3kB7WIIJeYynEH3wk7vxhALyFdiysrF/ivlBPVctsWDJSeXXdlWtbm0/wL5A+ShfbU/0rEXPL93Uqs9yP7c+laKYEt9Lc2qCHXP7teFbBBhAJgI4a39m9KZczrcTvHJK5ecDBNplplI2pDfyZO2thpUmvShpnWGD63TAb0SLBrDyGbe8oq/z1bbiOgmb4tf5jZVWT+vkArCqvN48fwpGNY5bPJQmFXb+DycgvKmUF0eW54v/BaYCjMUA7ceaQ0nzRZmFvBhWsudT8mFlRPoNxquPXWj488rEEU4uJ5zlfsrFJvBzIQowz7fj0q0hjsAcptjJEWNQdmv+kSUMwwznDo9IZn8ufqrG5rjndahjuiWpScLAYH9SNi8qPz4LhS2TsYOG/jjEeFBPZ7CbtgGn0zKj8ZWalLNPvIA6EYxB7GDavtDzTi7BEhyWqUxJQxO0ANEEIFuxLBEYPvNeD0cj21Lb0T8s4OSYZQxz7fvqYbuS/XOmtzYpRyc133KT2500mKSRZyO3XsHuCkenaKFw9DVHZvZP3iGmoVT+1UnRcY2R83Eq9uyDA7tQRUXX9McpurF1gulXc/Mji2mhIqlNpENJN4C/EOq1LQyIkMzTd6Rtje/5TkZmb1UFFdZzE9ANMyNf7FSAjfowvR4qVssLrKj5MT1l2qOXm6wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYKDxUaHyYwMGQCMHQgmSvds/aGGSa2tUtf8AifzEkZUGAcMX/+1gygyei4i2mzBy0yHBY0NKKEFpukqgIwTAZmZy57qev0wh1Kl5OTN3ij9dSOLLTSEZlZOyGWDck0sJ+aX6OzRyza6waqCuBc"), + new("id-MLDSA87-ECDSA-brainpoolP384r1-SHA512", + CompositeMLDsaAlgorithm.MLDsa87WithECDsaBrainpoolP384r1, + "7GYDITvKWRGfN1v0az3NA+Vo/7kAmpF3YJBoqr8uQonm4LMOMoBmi8e6xpKGxXsoQ3Llk7DSY0/ATyi1/Q6x+ssVXZX4uz5g2kW+8hUKrffYAL5TWCuNjws40oGFtK2rnWP4kTxRKzbINLdBBoVCdLzwNtUn40fvyuKTWmGbv4XDEkjK8ImrW1OBBMXBeHZBDroIeekG6l2xKUkCvG7+ES41uzUVlxmVV2kZIUU7iJ+0PIhvQhF92yxG0aa158/GRleqP5MT3PsTwE9P7CHPiCQwbN58sH6GXIaePF0sREuSULHrjLX4AK/VRr+oXb9ofWVaLB6lO2gHOjcl32a3xewPDfoWS62bCjNGVf1ZBvMY/E5DTw0LJYA4ScUOLZmH8Mlqody1DPZwu/cKtolEIqXtSwAwQ3RmUs0WdFFOtXHaglpLv0+v+6QlWiMqGCs7kNh7VcRgqhfZAH64O6ozwZLSBCGD2tUfmtIE4TeFfkwTMapQcI/qsXOabjPpwyBi3HIv/1SMy5ok53EbLYzh3L9qtLoWxJhcbc+MC9E2sTWSkR1pNHkaPxokFLjr5jXBvQQGwJYmuuJ3M0mYet3KXuXLfwHqdjRMXMNGbz/WoYKdluLY8h0q99tj+4fDvGr3gpf5r7uY5WvadYLwelx8vx/XCLfThICsqs62v902nwR/xNYzfncedrM5QBdwouYJLXIFzGA7a+tsCEdIlnWgwq/7cdJYFAFdqzckANy6Eevbnz4V9DBrbiPWgA3+YN5ZR7NFmSGODE8wGeUfKG7GcUP0bim2SuXXa9dHI+DWd0WjD0Va9XkdaF6i+RrKQSTRS6T034ixlIJWunjxcYTNgv/7HyhNuiggvlMGlCFz3Xc/o77xBowv77QZiWZi0jq88Gt1kFbfNkUPcX/mG1z8g0Geva126zwozxtoN5a/6YZf5N5ixYskO6XAoZneK8Kjl3fwLAzttotOin31A+oG3GSI+HJOJmWt44NyOl4r5kM/ySvaU6YChzVFAb3oPWygbvWEn0TJM1LetVhDGr67Yc0Z+YR+3+TyT1vXBsqBX2Xz9NJeYSUmYMRtuSMqEVMsTpfZw+vZTBNEEPEDVXJeVOchWTu/pAiue3+OzJtfOBtexJUuh1yhxzeXOW5bVUjm+LNrlO2ERmbf2eFIIxFc4pu71ixADl4uWabVxch1LugpjuGgahAcorXfRhCenENVDqT9ubKoXpqTKWDpgCAxeVzfNlC6Msa+l99axRsJPpMCeNj4vmrhL4WIC/Lgf+Bwa44Aa6ZSlfC504aj26GnySFatsHGrBLT/EX8Smv1L0El4sxK48svrp/pUv26NT0or9mKknsxuWB6nTvu+T/MXvuH4Tm3XDoViTkJez4WxdWrMhOjUvXZBS4PfinQEBEa1KxMcF6I2VgXMdBtRsihIXMH6lY7XAPnorz1uAqgjusWwb9FvH4E8+mCbT9Tf14Ixbq/LY2p7oAq/AhqyaYRB/HDsGFr19l3rwenEWRGVVz2uPKY8kHTLoIKOoKdgzgfP2qzrD7cDWnjLHx9JvZ2MddM+5DaPfWAzU7d1n5c9gkKIeDHaBJjfMVbJTvLTaqKOTnMvDYqQyij41zY+LmNNRsZbcil7Fa1izxSPpEfOQKsXkgaYi+Qm1dGjigfEte+DxjyJoUmDu3VYpUYiGHgUPpw0fH8Khm8CQXGfXoKnLirT7US0u9wG95cw3+crv56ai5+ZFK53zktTePMrTWQmgDbD5wvRYoYltl21t2h03dAJWkSwK5o8HuTlgLYyy7J/oG+o6TFj+5nyMMj6h3SDdhk//iMyw5XxRodS+dSoWeFOWWvm/Gql08oSxmQfDrdCu76YBlw75hFUYN2ZMtT3K24SjoSnTRA6bEfDLOfOAc9VsqLifHde4+vFkTJlnfQuDdVLATFwecRR1BB3ljtos4xTAp85AOGJ0q3U4Y6puB6E2e0+w1v1hcaHE5UD2pnxgzqmRxSMGrzpSZ2QousbOOwYVz7cx6o2omSWSQHEfsV8I32u+26gZ+PdODfCZWyLSDknDb4y8LckiKt2pyktPhehF/qSB6jxbv6yW/ZFShkoNU6VOzlvbw2PLbJF+Vy0rn/3MM7TKON+3JjLRaepU+/FK++yY2vkUGlg9HNmrZdxZwsrEYPxTxGzHCgPzjGyRyf2Q5P389Zn18zj1hVCwXABrbfQXnMKUT/8/R+U5Cccs1GkIiaaOq+NCP/gn4HktH7bAxj2TLB27pJF9J3+Expa1s1Fb0jPsTTWShEOcoVrQdaIRS/lWqzOaM4okidu1UCQNEAWEP8wlo3GXgdZSA7xMntszQSlM2qRwmjLXJ4H28ujIuc0idaNJvOcNFaKq3op06RJZ9N14OTXRK74CkDCYLy297U440Hm3imcTwC7VDK74hUh35IQOxN9wMA3IS4vTO6S0OfjqKL3s20Kf5Bj6+6OPEY/yfZ47s7U0GoRuOgpM0FGTqmfq59UZWvNBApRiDKwDX2A+58VhR9eY9t6WfuVJHl4cGXIM9mOIwEMdbY/ZJ6F8k4f2fpNADM5Z1mYsrNDxGrfbNz0j6MT1RLPRT8cTvh07kw4k2T/Ids7y56pXNNdgcIWvPosVhElWDZ7HrNjiExX2gv7qTkogxRp7T2CKbGNCYpW5UZZ0tVK5DkIFXLGPvDoJXWzq2ASVsEH5QdWiZT0u5Dg2ER9b295SpFfzbbvTv7t3NrTWHgDQ6YilFhrxC8N0ty6vNlcKIyFCtu2gZVtQvbkVInxTm5jh5bgzGaLT2lG9325Wd5YmVkbAmkLiKLOUXbBfrFXRxFp4lBqFGy1885zEuacvT0A66mMIREc7vL2tjfgREbpm7rTDzr6NiZDNMahe7Cke+p7iuq0p/++BeG7wmdE/+SgAu5sOROg5EXVq3u4TyhCFisoLUQeotqAW5idW3Z6FgmbFOWdo/1jZUjuFELkM1Lr656Tin4P4TKHcYnXa/IumEg0ONFAlqIdypwvnmqk1IS0ZjdJ4KhO6CoXlIyUP9Umms1squIKsRids1kAroRuir2YTxWJ59qm6RvC17RoiT9efcWHYWsSP/OtzY5szGUPpZJCY2upl7RkHqE84E5opDMuVkzItstCrdXA3EdMopnJFRid9GaxNr95GoNv1HIkEaJjsRiafV50SOA7QpJeBmzCllwGe4d17Wo8zQi+h4reI+eMtWJNpoXJP10SwT/tplwD9roxRIWrWljVp/6Ha8DSwTcB5lJrYkszC411EXUMIgPf1nh7hH128HAcmnDmRcXo2y1BHFLNiB66NDToSqMEqEO4pHW2iikZJPJuuUYkX58HcE2FD2oC7Hgd5MnaaaYZO5oqgeSxEFRi+kOx74juf7q50lDJLyVIgoo8QJ3ZjV/RMpOq36LGxvgH0DXOjeaX4L3WRgmAB3XaV/Z+lRVCm43+JJYXrMFCgkFBIH1l/cfmIN2URLcZXRyqpI0Jvu5SmNDNf1G/CE9h3LSI0ol+YT/dMiJUg7T93eh4oUqx7MiAbAvqeuD4IoLAr/D9x0wMgJ8AgSxHZFK/+39HVvATIBFyKSt6R9X/XFgkQ==", + "MIIeTjCCC52gAwIBAgIUL7wa1BwUIwz9MWXqLaueGWhbiKcwDQYLYIZIAYb6a1AJAQ0wUTENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxMDAuBgNVBAMMJ2lkLU1MRFNBODctRUNEU0EtYnJhaW5wb29sUDM4NHIxLVNIQTUxMjAeFw0yNTA3MjEyMzMwMDZaFw0zNTA3MjIyMzMwMDZaMFExDTALBgNVBAoMBElFVEYxDjAMBgNVBAsMBUxBTVBTMTAwLgYDVQQDDCdpZC1NTERTQTg3LUVDRFNBLWJyYWlucG9vbFAzODRyMS1TSEE1MTIwggqVMA0GC2CGSAGG+mtQCQENA4IKggDsZgMhO8pZEZ83W/RrPc0D5Wj/uQCakXdgkGiqvy5Ciebgsw4ygGaLx7rGkobFeyhDcuWTsNJjT8BPKLX9DrH6yxVdlfi7PmDaRb7yFQqt99gAvlNYK42PCzjSgYW0raudY/iRPFErNsg0t0EGhUJ0vPA21SfjR+/K4pNaYZu/hcMSSMrwiatbU4EExcF4dkEOugh56QbqXbEpSQK8bv4RLjW7NRWXGZVXaRkhRTuIn7Q8iG9CEX3bLEbRprXnz8ZGV6o/kxPc+xPAT0/sIc+IJDBs3nywfoZchp48XSxES5JQseuMtfgAr9VGv6hdv2h9ZVosHqU7aAc6NyXfZrfF7A8N+hZLrZsKM0ZV/VkG8xj8TkNPDQslgDhJxQ4tmYfwyWqh3LUM9nC79wq2iUQipe1LADBDdGZSzRZ0UU61cdqCWku/T6/7pCVaIyoYKzuQ2HtVxGCqF9kAfrg7qjPBktIEIYPa1R+a0gThN4V+TBMxqlBwj+qxc5puM+nDIGLcci//VIzLmiTncRstjOHcv2q0uhbEmFxtz4wL0TaxNZKRHWk0eRo/GiQUuOvmNcG9BAbAlia64nczSZh63cpe5ct/Aep2NExcw0ZvP9ahgp2W4tjyHSr322P7h8O8aveCl/mvu5jla9p1gvB6XHy/H9cIt9OEgKyqzra/3TafBH/E1jN+dx52szlAF3Ci5gktcgXMYDtr62wIR0iWdaDCr/tx0lgUAV2rNyQA3LoR69ufPhX0MGtuI9aADf5g3llHs0WZIY4MTzAZ5R8obsZxQ/RuKbZK5ddr10cj4NZ3RaMPRVr1eR1oXqL5GspBJNFLpPTfiLGUgla6ePFxhM2C//sfKE26KCC+UwaUIXPddz+jvvEGjC/vtBmJZmLSOrzwa3WQVt82RQ9xf+YbXPyDQZ69rXbrPCjPG2g3lr/phl/k3mLFiyQ7pcChmd4rwqOXd/AsDO22i06KffUD6gbcZIj4ck4mZa3jg3I6XivmQz/JK9pTpgKHNUUBveg9bKBu9YSfRMkzUt61WEMavrthzRn5hH7f5PJPW9cGyoFfZfP00l5hJSZgxG25IyoRUyxOl9nD69lME0QQ8QNVcl5U5yFZO7+kCK57f47Mm184G17ElS6HXKHHN5c5bltVSOb4s2uU7YRGZt/Z4UgjEVzim7vWLEAOXi5ZptXFyHUu6CmO4aBqEByitd9GEJ6cQ1UOpP25sqhempMpYOmAIDF5XN82ULoyxr6X31rFGwk+kwJ42Pi+auEvhYgL8uB/4HBrjgBrplKV8LnThqPboafJIVq2wcasEtP8RfxKa/UvQSXizErjyy+un+lS/bo1PSiv2YqSezG5YHqdO+75P8xe+4fhObdcOhWJOQl7PhbF1asyE6NS9dkFLg9+KdAQERrUrExwXojZWBcx0G1GyKEhcwfqVjtcA+eivPW4CqCO6xbBv0W8fgTz6YJtP1N/XgjFur8tjanugCr8CGrJphEH8cOwYWvX2XevB6cRZEZVXPa48pjyQdMuggo6gp2DOB8/arOsPtwNaeMsfH0m9nYx10z7kNo99YDNTt3Wflz2CQoh4MdoEmN8xVslO8tNqoo5Ocy8NipDKKPjXNj4uY01GxltyKXsVrWLPFI+kR85AqxeSBpiL5CbV0aOKB8S174PGPImhSYO7dVilRiIYeBQ+nDR8fwqGbwJBcZ9egqcuKtPtRLS73Ab3lzDf5yu/npqLn5kUrnfOS1N48ytNZCaANsPnC9FihiW2XbW3aHTd0AlaRLArmjwe5OWAtjLLsn+gb6jpMWP7mfIwyPqHdIN2GT/+IzLDlfFGh1L51KhZ4U5Za+b8aqXTyhLGZB8Ot0K7vpgGXDvmEVRg3Zky1PcrbhKOhKdNEDpsR8Ms584Bz1WyouJ8d17j68WRMmWd9C4N1UsBMXB5xFHUEHeWO2izjFMCnzkA4YnSrdThjqm4HoTZ7T7DW/WFxocTlQPamfGDOqZHFIwavOlJnZCi6xs47BhXPtzHqjaiZJZJAcR+xXwjfa77bqBn4904N8JlbItIOScNvjLwtySIq3anKS0+F6EX+pIHqPFu/rJb9kVKGSg1TpU7OW9vDY8tskX5XLSuf/cwztMo437cmMtFp6lT78Ur77Jja+RQaWD0c2atl3FnCysRg/FPEbMcKA/OMbJHJ/ZDk/fz1mfXzOPWFULBcAGtt9BecwpRP/z9H5TkJxyzUaQiJpo6r40I/+CfgeS0ftsDGPZMsHbukkX0nf4TGlrWzUVvSM+xNNZKEQ5yhWtB1ohFL+VarM5oziiSJ27VQJA0QBYQ/zCWjcZeB1lIDvEye2zNBKUzapHCaMtcngfby6Mi5zSJ1o0m85w0VoqreinTpEln03Xg5NdErvgKQMJgvLb3tTjjQebeKZxPALtUMrviFSHfkhA7E33AwDchLi9M7pLQ5+OoovezbQp/kGPr7o48Rj/J9njuztTQahG46CkzQUZOqZ+rn1Rla80EClGIMrANfYD7nxWFH15j23pZ+5UkeXhwZcgz2Y4jAQx1tj9knoXyTh/Z+k0AMzlnWZiys0PEat9s3PSPoxPVEs9FPxxO+HTuTDiTZP8h2zvLnqlc012Bwha8+ixWESVYNnses2OITFfaC/upOSiDFGntPYIpsY0JilblRlnS1UrkOQgVcsY+8OgldbOrYBJWwQflB1aJlPS7kODYRH1vb3lKkV/Ntu9O/u3c2tNYeANDpiKUWGvELw3S3Lq82VwojIUK27aBlW1C9uRUifFObmOHluDMZotPaUb3fblZ3liZWRsCaQuIos5RdsF+sVdHEWniUGoUbLXzznMS5py9PQDrqYwhERzu8va2N+BERumbutMPOvo2JkM0xqF7sKR76nuK6rSn/74F4bvCZ0T/5KAC7mw5E6DkRdWre7hPKEIWKygtRB6i2oBbmJ1bdnoWCZsU5Z2j/WNlSO4UQuQzUuvrnpOKfg/hModxiddr8i6YSDQ40UCWoh3KnC+eaqTUhLRmN0ngqE7oKheUjJQ/1SaazWyq4gqxGJ2zWQCuhG6KvZhPFYnn2qbpG8LXtGiJP159xYdhaxI/863NjmzMZQ+lkkJja6mXtGQeoTzgTmikMy5WTMi2y0Kt1cDcR0yimckVGJ30ZrE2v3kag2/UciQRomOxGJp9XnRI4DtCkl4GbMKWXAZ7h3XtajzNCL6Hit4j54y1Yk2mhck/XRLBP+2mXAP2ujFEhataWNWn/odrwNLBNwHmUmtiSzMLjXURdQwiA9/WeHuEfXbwcByacOZFxejbLUEcUs2IHro0NOhKowSoQ7ikdbaKKRkk8m65RiRfnwdwTYUPagLseB3kydppphk7miqB5LEQVGL6Q7HviO5/urnSUMkvJUiCijxAndmNX9Eyk6rfosbG+AfQNc6N5pfgvdZGCYAHddpX9n6VFUKbjf4klheswUKCQUEgfWX9x+Yg3ZREtxldHKqkjQm+7lKY0M1/Ub8IT2HctIjSiX5hP90yIlSDtP3d6HihSrHsyIBsC+p64PgigsCv8P3HTAyAnwCBLEdkUr/7f0dW8BMgEXIpK3pH1f9cWCRoxIwEDAOBgNVHQ8BAf8EBAMCB4AwDQYLYIZIAYb6a1AJAQ0DghKaACOYTd93Iv9vbpn281JQ+ffnOO7JhnWkxboUoxh3qiAk+wNGGLM7ToHlZNuyh/1RGmn70XV03G6Rb+hgSg3p94HW7jZlXlcPK+JVajE/HgLAefYNKoYL00JKftRjOPdGV0kIJY7wbulgrIbShfGxTJQeqtE9RmnMfv1Hz9n51XyU5o+fQv6wSOGdvdjolEfIq/GkwpbTbqaW0gJ/Cmv2hcrX3qN6oGqgiOXFECvy+ich/Go8KNJVklsGSc8bdtiPsHImUW0HgcHBFE6VN42/eClQAkwTmbT59lBo9QvVkn/II9rUdzUNoZ9fLPumRvR4DZAMmqASQ2JJm36Gkyj73HuzIHrN7X/W9xv2BSVATJPwct2ELLNgWJlAyGvHmDmrrKpsHw6321uzRLl7MshhzSJDJjirGk/nC5PGUS250I9uCuijan0n3EYVkh71itJ0k4IyVBbkkZidZYIqb6Fr7MQdmonGFwPd74kXFh3V9RaqLfQ9/UgRvBbBKfS7C16IhrtKCcfy+SlbCKpKfHoD5p/lkOclPAZmgsCAFArkuZhDlan9kmrVAk3w1us3ErXjnmtEkZ+iDH3BUDHdvZohJJNnIZ2MZ2JuivRyndZ6+x0INHJJ9jal2wMOf536Ucgm/OaStX3+a0c4GsBz3zupLMuKC5sdG7qM5jz13xPQ8RfGcnTHinpSCbKesQyW8YRmpyxIJC5tv7BEpuOp5Pi5nvUj3nKl+dLdowwWCUi3IB943LKOZnebV/rZCRWtdCCW9KrP0zwqPq6FmnABEvWM2JKj0XuknSA9C2/2vfMw/ocrWVp9dlo4vFnYDL0OtmhOEi14Ds/7jVdw+gV31F93OCZFVQrK0ZP/8/uFwKn5MOMdSSY9ItdOp4Wh6X5vw0K7YuPDpysjxX1m4is17HIK4SVXiBrqmqeplR4hCtcqlroieRePw2LrczSUfqckA3tEp4C+/PPivNn/boK74aRano3lTiEcIfgUK/HruksSC0b2aajcwrrFulVWaDV1VTJkO3SxeyHS9ZvpFFPkQCwoVBWZ97QZleyzwQge7pMchzdpgHQinQn4EjLJWst2j9B1ZdS8WVcJVO0uynSRVNlSlT77PqSuP/vRjsTk8/tLEuVLbXRYxzEf0nory+7PNt/5zl9NUIR4+RkJMgtKt7ytJr3shNmHEzIeOJQRJUOZbc5L0vIwyoM9iX90xPR0gC9pGZMNf8sC4BCL/sOoDwkxHuE3sLZeBuuT3DjsKi2gxaJHug2UHsTvUBM8cRj24Cq0qWF2YXm7w85KjzsMz0WTNJYx9mZFQY++DpYtOCVdh236IvyQ6FHzbJznXvj9kc1NyEWCqO/s1LyWNtLtlEWdppwVyLG2TLxd0wM3GyUXVCRbmR3C0l58CdtL+JW95aUdCB5XzUCcS3u5VAMEYYpSvCAVQ/hVA4o+JN/g4d+kXmL299gLCozXRmWkmjhNeVvaF9ayeQi5fvdgxcWrBpC32Fe62+B4TEZrntaNPfXldD6n31a+POhHr2GXmBIdIsW/piMQR7UJrnbMdRMaBfLthDGVKiLou6jLJlkTVkSmYljSDYuRqfsqKMSXuKyChagul7RVipme1v1DHD0zkP1iAHRnYM76CDTDDpkG5hpF4JsQDBftANf3EJPM+xnHHNtXldDxInlPqTphi2j+r/1O3DqReqjb9ptziD8z+7Yd7md5Q0AKzm5Bx1zbf3SsqncvfdB2KNsD0D0aRYzLIwHbX7HhHuNGbBb0nvjvJSbtkj0IVbNkhSRjXZyHGHd9cQg/CGzRCkWQwHPBDwUjz5uiTwIVSrSeEuBYww1LSba5aHhHNFse6gktzCT8z1PhwHwZySf3a7Z4+/mCsWL318TWcnLHsl+SKjMk4gYYz1RRw5jCVRCL0qfd6WA3P93XnUT+FOWa7241veU0ugOTmfrzusPUUdVmEBtDaUvlBS1bUbBAbKNbTVBWoOeTAcxSKZ4Gr7bvZ32wdQyOIBmHIDjnFNxACLxHxMMsEQVUP1L4Q0tXBQheQC6qiW2PHAMPwJZ8MayMvCLc7+zQLoAF5zl6pImbZMCni00AS0deXfKD/QuMigf5+1bsTF8QOKXjLMZve5r5XvyDmTaJ8N/yKgZWsobztxhNtoo7C1laeKxQgiocjeXW57qQ0Yrg5ycAbUytiTcJi5Tn6kSVMFWXZgYlK/KwKvNkyWERbeOy32FvhNPWGoegN/Rli3jklDmgoQjihFx9EeYPLzWhKVSHUOu4r7CKk92SufUFUvatW+N4jWGuTVjQfvT9L5lEEOXzPLomvOjkeWBel5xXVJaiMc/loICfqcNHWjUldQH21lCuWtAB2D2UBL4tWAe6N7rTLIvQXfKaUGrYEbAKlUI7dyFjz0RUxjo3et2RyFheJVQ1t6ojDBsYrYNcaGadtr3sHctXpe+DE0dL9TJEKAwvGfqn1WYVyZhuRoZo1DdkJFhmUknX2CRyoeFlLXB+nTLH19p9xR834g8ccvNEx6Cv92STs+m3ETXDzz+MO80otzQrDrZ2WZ7KGKBubStdJpEo7tDug6DhwqKlSOagPTqwAU9/c7gTFl7O579M4o0Y4GnsogGYxxQ/qzoHt0F26wizYzDDPhEFQ1tnsul7yWxhw1pFp4PAT4SXvsp538kG9CqkTrhhlsFhctxh/7Ugy9lyQBmmPYcz4L247IGkoEeqtGpJEyXk2TNcds5nMxeqz4qWOpe1YcUJ2jUWhME8JHNbLtlfBHcVrWOPRuJOmrNGSD+nEshrYj9VjjpsV+zMEqnlq9cPfGilxiEcM9+52OzS5zE+YbgSOEccqb7u7KbLWc4FnKdEQNJ0VXILUFpA2v/4k22LFo/Bw7t6PtSxjDIPjGoqvKl9CYVUbXOtlxcmm1mLcHFMYCJOWYwHEiIX/pmzl+QE69H1FM7js5StCOQAGKiD5GoawdBif4ls7Bj3c5P9FRq1UfNv4h2iSglh/QLvyeuzlMiIReVQWBzQgnDKLlTh1IFYbP1VbOx1uEw5g8Zj7pug8wrq20UZUzRp6f/OE4y64beQXM9pEKd25civIdlXBBj1oKca7zcszTbNJrccp+4KfIfSZsR8QoBahO7pFkSACVMGEm1zrmVxmYcwl/++xqZ+KqCrepUSjF5Vgsx7FYsL70fn/O7aVCgSikrkMFq6d+kxTuIouVCibceqL3c8Xj3vX+AJfdyN8Vb0e9HNGyQdEsyodRpMy92SctMWW0qvLDo1bjQPdskPxT8ajF8TzykuXGd0TALgQIAsXoYnQPGSElR1Mc/zpfB6AMaPXiHUcUL7AsB9+yWufOUueOn48O0wAdB31QYYP1RG0Ka2rU+powdfV9PMGzSNDTaJODk5XnC8zXW3P1QCxBxoQWfB03XHn0Glivx/YpNqej8di0Un2h1mZYpkHmkZZJxBgywe63Iaav1LrmKaZgky8QPDYOoVog5tPwc5N2CTrEXf8WCkx/yKDVeqOt4L+jg4CiZsF5Wln6M74uFHKFKo4MUjkJ9/FqER7UOcdozexnvN1xPuoSXz5OWXS9PTkhIWd460t0/kPWKH1R3auAGpYEFtoEtqGElvhO9eHcft6FmexStleXDfZSJGA/o/+F4ej0cuqDP6vH8dZ1xT6WLld4606BKewL1qYtnmdNi57lONDtv8OPYtVYTSImRF4PfnMcnUTMWa0y768wrzcsaDhibX+LzRhcOULoCrdhoXTZTatxjbTu0VHhGgMV2J0pUAHbP/PD/tJ3/aUVqgCeX65ZBdra/FJ6sQcc3+bEJIshYQmeX9cMjkt9LFEzG+6Oh1YlDaNLDlPaYFVjavbTLwoMeQITeaPZEY/y+0uO/yQgw5GK49BTjTr1Xyi/PMPBenCvu2QgtG+RC8JC7bNm/AiRiD3q1RK98hai4SB4dicbTqoHvUK01DzexCUW5mm7Zay+2y5UOxcoR0Bl7hTVb79sdXTsdzR9elZ2YteWDVgzVS0CH7rVZrXVA6Yi1PmNILSB0Bb4DTaH3QO5a6GWZ1Hz25gRdyfzQzYjrHMBkagodBsZUAWXn/pf4BoOtr5w5jOlvSwt57tl7Aa7P6wzVOtGUTDxwHa4/Gu6eeX1Lzhb6l4BhCsdludQnDGhwsOx75UeDBJVQdI+WLlrNeH5hpENDjN28KKpSOv4mU/iLZB5PxPs39Nn/8hr96Gn6+IPvVirVFREsmd//YVQXjnDevaR43Hgw9xZozLDwUBLVRaTXj1VRcsAghG61wFndHVpfDPqMeL+W1dVdPo+X9YkTJQraNA7ap0sRDLaKb6sjbJ0zXLM7+w2p0OuQX1Xu6xHgwZHgBDK698LAvd8L+QmNm/+bQCJFagLbFWAc/GjO1GNtVNcdBM6xA805Atg+e3VvYpIS9/g/57TuYhJsXZEJiEGNw35ZP7V5NeyycWvCF7Je1gX73IEDLc7q9ABHUUgXCQrGemrDuBNhHJY3qulOuIc4oiBB5P1x/g5aX8DNEdm9/4iNOU4yiYoRWZBsuvidvtpQ6rjAW2ZcjzfMFLe1V50cHoi6nYZYR+SkrnzSPYQfwte+16pYTsPPOpaNv4lndKy6m4u2cwKxF1P5kCMei9vaYZhZk4wE3Jqm5nF+CJP9thEpw5DVUJ4iutGJuKe50lWrlPjj/p584mlmX0ZHLcacxE3QqCuorA3KDWDri9RJqDgO7Cb0iACK38uVcGOL4VoT5ctkyMVr79FzRonNiFzkB2Vtw60kUp+zRA1icSo3djk4bsFHgXbdBGs1S/gax6gQMOsmS8Z/EP/CipnC07gxYcvhfUcdRhjIlQfzavEYP93Ipgco5WjlgFMHWDA/T4sVB8dZGT0vJafJ9CqjnD2/qq8nRLNdy5YElIGUteFQ9J/3tu9YOf9JZb8f2IQqA1Dblp9wB/4Wo3s21DWc6faHNm9N/Gcp4u92oDTwIto3ELpHIFIWt56lmp4MwodSCPDwrm97hS9V+va6DhUFuJw/DDY92c8w76opcy+f/6P8icoxBGDQ+vtSbYUwKusIlAI75ppiKvXcT7m898lzGxV5bkBS1YrY31ngKiLFwwe8ob3gge+gk1JcNSdMIpFCkiHDHWhsNr39+E8mDZbD+rv4O4uOjKRX2ggYLNdPNF3bd17jblELdQ73c6LN4XQwpmhSpjvNpiHCfLThJFTQ2RhmGS2M1aZFRY3NxUQzP10R4Qez0n50VZ3kQp477hEh3CfOu5e4YhKfq5GnV/DUf+QnnFaRnLUx5q5vweNKm32xutEl/oqnEVB+JisxsNF3ddWuheNsQwbRN+6x3jpsuwpFVjvxH/wPUsg+08fq+b3owB2q1n0q9yBGKB4x7JwYSScjz0RKLwQzLca/rsZbiWLIrGmnbC/dzS46RkJRDCoWgOQR/pVIhdcrgw9ACgW8/0uA6LK81XxBZJgQ7zT6/T5W33ifv+l1TFBHbkN8QmFV3Kp47Zj07Qz1z+Ba22yuTZGSJ5RAsPNI/Sk7mxHMOjrr9Zm01IjZl4gKErE634Jac9MbvJGPbJeDbAqyBVtE8RSyeYjwGpR7chjJO0YRhRDnrkR5wqu7ZxB3sTKDAopxML7cSbHX+1cOlsw2Elpt9kOfVAbipy+jScrfQfcKq/8m3UYBpB/mBLmojfP0j7FiGsGA0viB6j+HQ9ZuZQYGkoaYTS60+6YmIKHhuBHMOTUUkgPOk2D08HLbvYmz1gJzwVJMEKTjDBoNJN/RWUcmd6Puj3PAc/KCZR0yV2M+0WK1s9bThIwoxrp8ANpkJPZFoFlidtVMYPivVuWowMsEXR50eWcFpuvCS4qs6UqxqKhkzeXiLGxeJbehjEADWB9Wb4krf2Z+7sHgtjI7GDGf+t/Ngu95ywMPj1H5XNRHM8PT683KQ+HbcL3tSVy+vPbaPhXggITXY6mQtXKP/+rPmJqG1fWq5ioUfgkB6x+/bZfXbJJXezuUd92G+QCLVwpP6watryXPUj6hgyUTI6F0+eWtpWlgAGMhuQ9ohbslKIHOAyLojz2QCcnTV5cfoS4tdawoOtFXoN2UfhCUOEzhg7eY9cJ44RuCvpL/nmLuz6xaE2gWTGu28pzUuogzxlfnCQDUDETM0W4mOl6K+1iU+1OT3P1JXZ3aRprS81CG93+X9MjSoxcjUIEyr1e4FCg5KYHOVmtPuBUeNnL/I9AAAAAAAAAAAAAAAAAAAAAALEBofJSo0OzBkAjBHEFfr/3+5wlNXtnfcIP8ybW+awOr+dPREECm0qG9tmN/O2GvBm1otk0v8L8tZwucCMAVdaz8zEvfNDWOKr8itFJyPKfcmljCOiGGjOulXr11CZvv1BkJ8HuPikZ0JaaKPjw==", + "go9o+QRrKP2g7VvQ+uKVaLPBgQSDN52+Uo6vku14UXkwgagCAQEEMGHcNB2ry3rhn6/+RcBpvKsLiVCr/+yG3qxImle40YyrZIdi2TyQvmc4+mLwJ6+eVqALBgkrJAMDAggBAQuhZANiAASB9Zf3H5iDdlES3GV0cqqSNCb7uUpjQzX9RvwhPYdy0iNKJfmE/3TIiVIO0/d3oeKFKsezIgGwL6nrg+CKCwK/w/cdMDICfAIEsR2RSv/t/R1bwEyARcikrekfV/1xYJE=", + "MIHgAgEAMA0GC2CGSAGG+mtQCQENBIHLgo9o+QRrKP2g7VvQ+uKVaLPBgQSDN52+Uo6vku14UXkwgagCAQEEMGHcNB2ry3rhn6/+RcBpvKsLiVCr/+yG3qxImle40YyrZIdi2TyQvmc4+mLwJ6+eVqALBgkrJAMDAggBAQuhZANiAASB9Zf3H5iDdlES3GV0cqqSNCb7uUpjQzX9RvwhPYdy0iNKJfmE/3TIiVIO0/d3oeKFKsezIgGwL6nrg+CKCwK/w/cdMDICfAIEsR2RSv/t/R1bwEyARcikrekfV/1xYJE=", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "JUCUju7zVi5RVKUizlZpWDJLS1UqPUJyRdck5cZ8aQ5yuX04vHfQxQgeg94TvKOEMdSun0J4qwg8kLdOtc9TmRWVdEd05wKczHsFU+MXme9skg2jjg6rJT7NnGYGDF73It63kpIzllC+B0d/nxe43+Gs7U2lf7604JbpVkftXKN2O2Od9WhNMZ23T/FXPaFdmCiy3kdzQgj8ZbO25u77zJJWZN/NEOPVBYY6glpOHNiJkdfyXU62u/AgxUXK04DtW5D7s7xqHTu1zZsv6QoHuuL2AD7FO7lXU3wQIvItsHfzMnvE+09Dl3OV2pE3ZicXFnyNXVqrWsQoECDYpu00Z764m9oityZPxP544vPJjYbRwiGYfVyIbVNQOxizhkE8mEuPH9XTtvH9zKTG4VGotYyF/JcyO9XpGDxT7aA2A+43uH4GjVLosghKuAs0flKyN/ZY+5jBVNFqlN8nfACnZXkI/QnX6yzk88bEwjLQty8Or4DVu5x07iRjF/QJxtv6+fy/npbeoOhih7ck3tvABCuSiA1EI+jRnwJKsQYxdBGDoQm2qSNwcmdVvRFtGcF6yVdzgYbI0VZe3FRmk7ee9vac9OixpUFxwyFPYlMbThetKzLzYkmm/+AKQouMs2QY3gitZ5UlchRQ9eo21Tbr8dh3uZ1lYsYOQ/b4ez53ByL0z0fIezUNLxXcYctX9SSE3kq9/1DmvyWYWRtcZ3vDqk/7gPPyDeOuG8AOu1XbY3pACu7swPncAvpayjGQGerK+u6rdqqTKDvQp/Ev8FsbuHYIQKZWSScNFI4PgEd9hOvfD055S11bt1lmXyPAT6/WnTugTn+qQH9Zjz6mkZ8OBWtMSEadCLQTRFepfAcdTt+5zTRfV0gdI0f+/JGh+SYMeoGe1RK8h7FM3eqgpQxgVzCUw4pnhotFmALNsX3UkQV084UpLOzAuqSQqEQ/NHmsW+Ch1ZRCDvnjqxxXPKJZNbWcH6JYja80SDL8U8wypAxQRdBEfVlG5m2TQKLaqbcp9GeDe/0uLkYuu6MgUROWFFGXwY1A25ZZgpbWdxCao+6UHxE241pMBvanxBQ3t2nYC2mZ9TRFkoyr7tS4USNQcR0IQQYyYDomhzPYJqu6TxdlLb2p7JRdlIDK/seLPJsfr9qPaf4a2F2VH5fx+a0dPLWDQvgO8hLKuAkDqowPugfVVovryzY1K1xeKD27MwDSuU/misufxsxhI6OQNsu8I2ZmtpADL9DWmuxIlhzadelaN8yyb/09ZNFvrE0ywDxAsDCb6FP9ZKisJG1gEJlx7O+cbPsFdP6dPaYvcCjaCDIxecolMTEF6quJ+g0K2nLE5yKtcIs1pa2tfPMLBhBjL0oUHwuffNah+lwUBIcDpanrH02O4zaVjK/s1m7KvU9S0ebhFtv9KhW0D780KjNJ3gWtUMn84yuS5R1YQRCLVgFrIrkxbIIL0Z+tOfoaeZldZ8wy/Nes5S8qpKMIxTuRSQE2akIeuJSa7sp32KsEdfaA8baD3EE2up1YH599UUuyOmtYrkvlRHJfFdnAhrgnOqL5cA+gybCAGIc0dBae0wNv/rMAixtaKTttnYmX2eTPP8c4Ra3eeLgyeifIFJagsEPUCzJl5K2uuSTFlKqpm377nt806A/8uESUBrn5VMFpAy2MSE0qVKG/hD20PeEwtogv6RoyrL1SWAjY7WWkJzs0EVZeVYNcXxWne/MrJFXqwkciVMAf+pgh9V82DS3To0DRmcMle79xDm0lEDGTLYDp40tx+GAi005KNGYe1+hSGYPvqPy2t/FMalZ2pu9aWEndMAIvnOnHDN4Xsxf6/ujt/H8BUVmSJTTYlmXRc+wtvStyM53Z9SZyetVtn8sejlUk0G66fqES9oPEUq5CHqdyHWZfOYxf+9M2vjfUOoC6WmgSG1L7t33ilk5egK1HrqKG45VahkxWC8pZainUOK41Onm2MUFggzgi2MmD82OUGu631eM0J1YCh692SSy3mvX/Q9BfGx08l7qQzfM6ddQQWkEkxwqg0FN006HI2+3fwFR/fELLVAUte9xusXLqYOC1ieCZHc+MZcyEDe2HgNUR2NH84WraH6LQewiuCGppoygjDLq9v3yfHq8HsiqQIJd+gDgx/eDJnSP19OsMJL68CT2mwsuDhjBPLfn9PIquz42Dk2b5oXbMMx3Z4vL8q85eAdyu2ZEzxM9ukvs8rsckpEU/eLKbFaGMDIOriCkHVWQVK17brY75ClNApEps6LMoBeqDOzDj3TWm7icqaT9NAw+1TnLGulQ+n7uq119eWnFbHE+MwYFQVQucCOgco0gUaQhVCkT3sXtrvprLeAn2yYOx0EFd9s/PHdf9OXJA17iy53PUtrkDmveKaNIGpuQMPIdOrPsPNIEatkBoEFGwjdcsTp5Y8DR5zu+xxsakPnd7+KQDIVTuG4JrJQCTLqLTstszbeDIujnNaT/ckLUgOPE/oi7jTfqYdybrCC9WtfHVGppt5Jt72wgOHw16tBj1cALQmQ3sKDPhFW2xJHkSQwycj8EAIG/PyzTCknt53Y65T1hYsp7waL72sP67JfKgNxp4sPIKSqv1myAl5g7HLFGaU0fJsVN3g7SZDU/6hcefNuCIvfg0X5nhuvo7nN/GJH93ZZGVV4lWUBXu4B7pKlUd9rnsAVapfKKbc/LhQFSIwpm70knlIXoL+EdUZ/x2IPbUJzBFiQgG9mCsDakgiY6U3yX18b16c0fAabtFPJhCIHQU9jXE3EkQRZN2kWc0V5nOCabYt4pwhlYGgtchTshOZ9px979XCLYkUr/CqBSKJi63ThEpXOg1rgGDfBH+Xj38kSSIkfBnYH6GRVCamQpCdu8qGfBzLB5p3N0k4UWb6jtyveO0l358YF58xLSl+ISCu4y+Ju/d1Y0VFGTY2z51cRKNlfMDAXOleCDG0NoMtnJnNL9itdG0qmEV4oKgq4glQgXKkuA/q5n8VVKTZtjHqbb3b/O8Sz32lc2wc5tvnEH18k6tSGeUKjk0klssZqkto8KrufPMknfq0nPqYfqjvqa+HmSIlB81HtZShKiP/mo0ftTZ37Tg3EXksJfF2ZIJtjZiPtd5AHoUf82K9Bzbs//tr2u7cH2G/YKHZbQvKE8b8jVx18aWcrssVsbAppt63hEQbQPahhlmlBdNZj82ZXTlFkO/EjgXiR0qeecL8j2phiKBdjUPEJaC4blCQLfONYpJC5p3Z2eSgvBrCZ0qIVsqAqFRh6+9BhFH2+OJNRPgr1izCCOh+4w1KbGdLMShRIpauXl/gy8wPTp3cU6Ff41SolE/NF0SNY1wXIkXpzbOquIupt9iurZNiqpVtSjCfzZWMRlJIkLshis33F0SnUilMdahxrsCcmdvd+QPA7CJApY0YGZYpJzY+rKL/qNxHh0UI7D47Vj0M4zkTOEEcQJHeQpml89XtiORnsB3YAb8zUQ3C+qxWXJH0NW+wdImMP3RulNUHFLIHDFyKtWwJlPr0MlX9HjqPY27XUx9NFXWm+dDSqgmZ+F7d5cB8kby0lPk/y8dMzbdWoqu9c8EZ6lyLFAk9B6MY9Wc6gFdStiHM2VqhRRoj5vzvCxf2E5JlYdzLqcG2T3aMY5t8mu0cxbhM6IXRHlkz1yYcBw1jhl6nlU6iwB6gTeOelm+oS+s+jhmpaqMH1gofS6x33oQS5qXRAMfhUVXz0Awsi78AfxiXxZVRu7Xr0SGcAQpkiHfqJgodkeG6NH1sOGkScx8MJYcsYmxxlAhi27ZrMv5p/AIczSmWRkJPBmW0204W22eBemPihWetsKpjyax9u0udWBpAC1T+wn4V2ZkU3lz5VpUtoi/6wltK49JeO5XuL8aU/fLJoQLpCjpOA2A8+gogTYc+xVk49ISE2k+J4nmMRr8zglr7j8zfIXNKgxQGWBANXh1tssYZ6BsmZel4m4wJX0zlKLKOnP+KiIHgVS2KRZtJkL+vh326Q9VfqGVNBT0hskB2KDoPnQ1VAKNsuuYuYfIyW1o6mblE2o+GVkpysBspNgd3XYhr6PIyPH57UEYW6uWpVfstqFPgWGeVh+AhO2sDG+vcr/Cl8FYhz9in1ZNuogAbH5lOdhhTU+a5+CF9DeXc5SDAFd+q/PjZwYepoRFV52F6hFKgq9GVWS2StPhI2TnVZpQ+Pl1JPaYXVF+f7scEN8pISWYI4SKNViOS3Ogf1b6n/M193ubBnlB8tc8egzO9l81Px7Q1Z1wI3jl8nXJr7MvdcmeZdXO4DXos6TTCfAUqXo8EKGlYPfobcqCdJWzUt/+zj0xZHNpqOLup47wWsGmxivyDgBCPw1Qtrr1hIwhRHwMYoL6C3ppAily1CxVKtHUXxb8Eepq/4QoAoqxCpxQxuByms2afGvo3fYMWXATmunKYGpl3yISvfGPTu/HsqXGL72ZikAQ0UJhCtlWPS3yzma1zrtyTySE/TnJkCEviQ9zHdsWszP09Bk1DB9YdcsFnH0/74Yb/Ua6hZGcedFUiiot1cEJcCNwmmw36i9YT/jwWcfYbCWJ6xjrYc/uZMLl0lOJ2SYc9/r2nqsgj0B7vw2CpmQLzkKa+YiUud92fe49HVnaoU7Ic5uLvHTdudyvpKiHZEHaulW0PQMB7CHU1m6Ef12BvgLbcKlyD1O/PIrq91cv0Bs9YHR4gzqKgvc4MkcSf+7Gzg7pYK54bzKCzz1kjENw9Pk7UXkbg936EbFK5XffPSzUiO1fSndjAh19Y/2OxOZ2CrdWttXMmly9yJLrheO3BfewU/2xST9cavjx6uN4L74Kyoo+aGWrezMUF1nsTjsGc6J6aZhdJdx5Vz5aZgQ8LOYvFgcCLgrbLaIS33ZG9XWo5SIxBO8oAhjC3nczyxJb+zgFfmxDX5LN/C5TEpKDX3ISsphLT3MAb+AyoEXHLewpo2FNstp5aWQsbneT8xXnfeCg/nT36Tc6jmLt0gJssQobJDikRWwk9DWK6qxnxeG/EGx0sKRgCZx5PoVq1a5GceOiEe4SR6ua9x60QDc76Ux0qosupgkMz5KBjVARNfFXJn+18grjVDrKv4VCNAtd8n+yMMOlQCpomwD3hf9vJgtuk3GLW8/qJgD9eEPtY38KQx0VUEO6h9ffGrv25ljnZhS1bxMs3kqMFrrkk6+m0jVqqwJMq9OCNAMLbLeGpMA+Mbn+x8pksV46F9Dvj4QNJpc2fFQXitRqfTCPveNWDFRlrK7WVigz2Ms1R/zzyQUENj5f78DrdHcmV+K9SyUbLNgDAvQDKXVc+H8qChR/FqZrKpxxjJVVLc0engzclglk/5laqx0OMr+y1banmhj7OgklQz59ghmYV8G+DF9xZKuAM4dpcba+h4KYtJ8kk0g7ELK7DrueTJxu3AjLFQpOwC7FXUnpCTNIoQ4ar0GArvZYdWhP76+LgUVnKCzZc5xd7HTYXtk2GmZkwuqISK+BFbEiSlGKz5WiaRzaNLSa3TAfQy1/UJPnJX92Y3/2WZFl/5YT308eRavkX4uJUL97l581HbFmyRSeToRSqySfRQU5dfTUMrofh7nsOCCy8dhIAGn7IFPmZebMITq3qqonmYvzLNmEuKsD7eqbHm0pXlPMR9uErzBW4W30YWufRasj7mY6kdOlIaboySfhnxhWQdy8S0Jg61GEYPo7nBZAz+Qh4P3g9wXjbMndONfg/6BerpSmDbjJm6+ese8Z+MlJRm5QA8XakKV3BOaEbuPF4ONexJa5p+o1ZamdRAXHQQJvT/ME+/KPppWej7kF6+N6RneMvEBmA0uBO4uAkco6Iy9s9D2LvSpFXlSJPdrRDI6DKrHm9eRnY93eLTF6oFeEjjmEESXxAYfPTBI85YsgP6OikuGKJ+GpQ40OXBQFy4lRL1pHpEZ4Ji6cSgkXQ4dH+sP4jW8462mZYEGoqppTyt8UJFJLmnS3LxJiMPvH0T4bF1cm75Vq2NSOZW+kCcfgZX2VidR9z0YAMQqt06RXXeFtV3sifowF4NAmgsBjgPHzZAlu2jjf8iozqrRbcHcPXnlURW+Oxe1xn1ugSvOEYhQNO2ua438UU7UWYzUXU4qOoGNwhghCidjtzXwwNAMIttLU1+PqDDp0qgslJ1Zbb3eBhrfv+CFslrrK0tvoRVKLBxwgN2F4g4SZqa69yuf3D3N7iZzl+BpodbfqAAAAAAAAAAAAAAAAAAgMGCAjMjk+MGQCMCDam6H5oop8016lhMX9JlNvMyFzASC3K7FJztM/IK3Y2DmlzvWPxDYWaGRBjLSIUAIwZyeziuHho1i7LwSBe5MNX2Qy/Iovm5iZJId4Dw+Ourjd1faBo4gTT2DCOOqq+Z50"), + new("id-MLDSA87-Ed448-SHAKE256", + CompositeMLDsaAlgorithm.MLDsa87WithEd448, + "6o8gD2FKFoXYHj01nzOYonHDwZzBB8fP9MUA5j3OqcD3YxkU4WH5akihArOci8OHs/IHhjTsYpnj7T8Zu/SVyE98cmxXX8l/2CViLY8V34AOeX7fAyQ7sDMbY7Ea/k+rG09z6Jy9sQV0YPlZZCxPs0GKX+cudcv77ws9R8RWlcJUWi3eJp0frtPMIGc/OvwVFfJR1cybxFVzSpxNbbwIBhQsSR4tc+DWOekPtI5H297SBUYnZCbEgRR80FDsR1k8h8iWACb7fPQzI2M8zap8a/bK+MDeoF+2H7pL4sRPuxWgPmE1y+ca+4LXtn3EOX8BNJod4ZB5bA9O1U0Y0hU+R4iq9k1J9T8lJSGTwemh7CS6fD23Lry/NdrHgJRhI9tXKRxA4PWwBZAwkDTSYUTsrH8BcGBy/NrbGHHoafj51uHuRhJBiz/hubNLhWOGy7aHNOl8aj3hHSSS5sjwhvZF6LAI0gjalbPeYMw00H7Acb9jjdjfolSLwKkX07YCh6/6u1T8xteNjkGR5DI2pB/IU/cGTIBMGMf9AhWwaFLkjGF70UrvdQ0uZ5n7567hzEHyYAypDZH+PhLZxbz/pzMB2I06C8UaltXs9hupOTtOzKOl/5tcbTvwdBj6guNQIoww3r+sNlUWxrBl8Y7+Qfacb9CVlAz3gLUIePdzDRhKWDNZEeUfQTrh9VNK6ANlT+cOAMjhzCq4BxwzKYFKWUVMfRK06+EoC0JjUKnywK4GPT/mbc5bZTTtxRlhf4UUjBVwwig9HLK/GuFxqaePVMpiPhj/lpubRhGv0iX07yrlAorS1XI3Gk++AOLxxvYy2LZ/Sufz2XiGXixc9aEi6SA7FieiIgaxt6g8z30D0XtT1HGbmQrmonrRP7b3Hh2KZGZD6bx/U0LzrtlAMsWqq4upjOKcNgfdG9dHjcxaWCjXkvN6Ogb9XHM0YDfrbYP0XnIVdUHJh3HkGFynJzecdC4tAaksDyZ79fZya+n845P6QizYhZZ437sIi2n6KBiuirqUrnX9dtZWzD0sTzlzyjM8zqRr8PtSe+4tTLrGrzO7Zxpvy7PTH9kycqPTlLO7HcaPG93NPgWwctMnFet4hzx2VLH3r1XfaBrs5TGXcL7IhQpJIHCjykXaJWS/YoHUFKFL474vz7inUY3V7b552nhPe7gX2lt/C4Uy5uc5BNAFJIKHNEP9dfmoy3BZu/NLAvfW0Rn8FDdOyH52CxyG4hVq4aMB4Z6zZwWErDOyw/lXU4aZZt9LeJrtrAo9h05UGkB0i2UKs9cIaa2+wnci6ziy5k/RKCz7I9reDMWt/rjFoQ2xyuylXD8O0JDmz0bpigUWqzGt0M6XD5uesB47cUvTEFIP4F2q3vaPUT+x4MAuKeQZeYDcBHGz+1aaLTe5LDVZkuFUXfIIvTeYKHJcF+58hW6Yi2Mc5tUzXAUHc1fULd7HZNUlE2mu8iFaOMLIVzLtnvd2Wcl4nqeiISyYgR4puDQK75asyWj52S492m1qMXqhnIv/ZrGT5w4Vnq8q6bZZaYPOSKAXLL4m7UeWG5W5e+OsSvdM85h6PjdiV0tWPfYTooDu1ZleUd8N9r9GCk+YD96gvUBc9NGTEuTHzoAmfxLPc5jl+6wPgsceAzJ0JEWPqxqtCR18rGgRmr2VoP+YXLlfDrarcATmWNQTGyCSn6P5nHoRhUYsxLF1uHYBjAOicop7Hjz76DtVxoSgacBIaKef/6I3kunErx2kwV9sHIT26vYMSQCie8A9PpFXNmIEslb4kAuXVgeNLtRpZ3vWrod89xQG2RnzQk4FxunNgfXSRKE6wxdjgKLy2OSh5ckLiCvHLK5ZpOC1LApKhKTLZRRngH80MZLSeUDWnnehPMuuPO07en1IDxagfgAHeisG8c6ryfqbyCeUfEpJ0GqNPSHTZH6W5i4/j+FGh3XhltH4OJlzDv4sXUlpAkXtKY4P3VXtJOJiYHPpkdB3rTjPdUmZ88AD8WHC4RoQNzH3FU+x2Dc2pM2nBqeZXTHzdSEnDoxYjBaVvGbY4OdSlCzeKIyqAP4KWu4bZa2wpt87IZPqXs4ruyWWRbs/L9RXGh8N/14bfQ3sejOKDgrWjZk7uEkxrlePmaxZxdLHvtx6hKsgAIFMj97ViVmeHuVzRMuu2kiDCypEzwnFZUgcho6uLer4AaXy7454T3BGwZDypAyuqtsv1Ya3yrCoRozdRtQxCP2hL4g67r+XvJEQJwXRFl700b0A13Q3Rvb3Jwi7vqf2y67mXMN3nF5g5z01ohZfviWgTl8Jh7XTS6U0Z3k14LvNFuMNmoXqjuZSKwyluXlDaB69unMNYpMour6Xgg5/M50drky2+NruQr1S+CGCS5tvVGqH5C8qg/BmQKJVVXrV9NQEJ7rLQD+UUATjuGFAc9HkFOAjkJLr0XpL5ftRcRTxmeBCKbzDLxUf9VuXT7JknkmGER1TdLwrOi6TI3MBtiilSK35qQc0P+jLQMUcJ/wqJ3Bb7HYaqrox2jAWx49QGzok8OFXxMM8kWlMyZh26sgm9OWsGMqEotW19FBjFpO1VBuKNDXFySw9Ig+io24/lk625bmDwV7T6Yl9wNA4pvmLMtI9TXMjtAf2yUn8xX107cK6jKKvANkCjmbh18y/ke4cs0BCadBfB7WeCnxQl91XxwTO5c2qgSGf3oudcWcZu7C9QuOUSDCwvsovt/Kyo7ktjOljGH/FC5aQRYDkq8SvoMx4jx5wPWjD5pY7j3XjoVFxml/n5vOPbk7ChuBqzniK+160AGhB2ySCG2OEhtlsj5mNn3W/apxDwE4JP7Ps0uNYLGGLmF52qk1Ul3QuYM4JDDcilHuNDGLfNjUAFEaYbXak13KNXOSLHWfvcDTcu2814WNqYGfP+mZslhInD1umHfPECfXpIM4mw2jzUIefskIlBEXlit5sB2Ob+gWd1QCMaqYxLziWZ4vHH0ZsRaX4R3zGGumIm9q4BJgEnmoOZjzE1idhPYXV834zLlYVt8opvaS8paFktN2n4yAdizM9l5GAKb6ydPpxZLIz7wqoUYQ8/QaiLp37P7UHlZxT6wRDihev9PL6mvKMWDeaMgSRkimiVCK8tVxheCGfKxZTeRE6E2bpVLGcLmZghbDh6mM5thEisZIOB9+66qNvLDhf1k7FbvwzpCEuWxGH9mytFprHpU19akWI6r8jLNlAJk2EihN/7WCxyEir0vThdzx9su2VCjGXx20RnQF3/jDMQkR5x4HoA6yZk8ct9YbO03qdaoRbourwwjD0Na1zBHE+vBlSsuF0IRnTUhDJrAXkhAHWXbT7QRfqO6MRkAfFeApMo/dTCffqA3QGotVKveNmT+W5ZrDyciHNM6wP6Vzc8b/D1SgIpAb4yJp/NiKoLPjPZDH72utwCkRuHytjZh8kbHicHSupctnPrss5TU8a3msHURlAFvdgH4MBbHghDbleaKj2a+AxFMa6uMA5SWeK3qB0VZVAdW+cZbnQbMznRTEEuDG1vwA+fjNGKahIYW7SzlEA", + "MIIeFjCCC1mgAwIBAgIUZNnabfiG5Gx+hiy3w2GVxMReRrEwDQYLYIZIAYb6a1AJAQ4wQzENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxIjAgBgNVBAMMGWlkLU1MRFNBODctRWQ0NDgtU0hBS0UyNTYwHhcNMjUwNzIxMjMzMDA2WhcNMzUwNzIyMjMzMDA2WjBDMQ0wCwYDVQQKDARJRVRGMQ4wDAYDVQQLDAVMQU1QUzEiMCAGA1UEAwwZaWQtTUxEU0E4Ny1FZDQ0OC1TSEFLRTI1NjCCCm0wDQYLYIZIAYb6a1AJAQ4DggpaAOqPIA9hShaF2B49NZ8zmKJxw8GcwQfHz/TFAOY9zqnA92MZFOFh+WpIoQKznIvDh7PyB4Y07GKZ4+0/Gbv0lchPfHJsV1/Jf9glYi2PFd+ADnl+3wMkO7AzG2OxGv5PqxtPc+icvbEFdGD5WWQsT7NBil/nLnXL++8LPUfEVpXCVFot3iadH67TzCBnPzr8FRXyUdXMm8RVc0qcTW28CAYULEkeLXPg1jnpD7SOR9ve0gVGJ2QmxIEUfNBQ7EdZPIfIlgAm+3z0MyNjPM2qfGv2yvjA3qBfth+6S+LET7sVoD5hNcvnGvuC17Z9xDl/ATSaHeGQeWwPTtVNGNIVPkeIqvZNSfU/JSUhk8Hpoewkunw9ty68vzXax4CUYSPbVykcQOD1sAWQMJA00mFE7Kx/AXBgcvza2xhx6Gn4+dbh7kYSQYs/4bmzS4Vjhsu2hzTpfGo94R0kkubI8Ib2ReiwCNII2pWz3mDMNNB+wHG/Y43Y36JUi8CpF9O2Aoev+rtU/MbXjY5BkeQyNqQfyFP3BkyATBjH/QIVsGhS5Ixhe9FK73UNLmeZ++eu4cxB8mAMqQ2R/j4S2cW8/6czAdiNOgvFGpbV7PYbqTk7Tsyjpf+bXG078HQY+oLjUCKMMN6/rDZVFsawZfGO/kH2nG/QlZQM94C1CHj3cw0YSlgzWRHlH0E64fVTSugDZU/nDgDI4cwquAccMymBSllFTH0StOvhKAtCY1Cp8sCuBj0/5m3OW2U07cUZYX+FFIwVcMIoPRyyvxrhcamnj1TKYj4Y/5abm0YRr9Il9O8q5QKK0tVyNxpPvgDi8cb2Mti2f0rn89l4hl4sXPWhIukgOxYnoiIGsbeoPM99A9F7U9Rxm5kK5qJ60T+29x4dimRmQ+m8f1NC867ZQDLFqquLqYzinDYH3RvXR43MWlgo15LzejoG/VxzNGA3622D9F5yFXVByYdx5Bhcpyc3nHQuLQGpLA8me/X2cmvp/OOT+kIs2IWWeN+7CItp+igYroq6lK51/XbWVsw9LE85c8ozPM6ka/D7UnvuLUy6xq8zu2cab8uz0x/ZMnKj05Szux3GjxvdzT4FsHLTJxXreIc8dlSx969V32ga7OUxl3C+yIUKSSBwo8pF2iVkv2KB1BShS+O+L8+4p1GN1e2+edp4T3u4F9pbfwuFMubnOQTQBSSChzRD/XX5qMtwWbvzSwL31tEZ/BQ3Tsh+dgschuIVauGjAeGes2cFhKwzssP5V1OGmWbfS3ia7awKPYdOVBpAdItlCrPXCGmtvsJ3Ius4suZP0Sgs+yPa3gzFrf64xaENscrspVw/DtCQ5s9G6YoFFqsxrdDOlw+bnrAeO3FL0xBSD+Bdqt72j1E/seDALinkGXmA3ARxs/tWmi03uSw1WZLhVF3yCL03mChyXBfufIVumItjHObVM1wFB3NX1C3ex2TVJRNprvIhWjjCyFcy7Z73dlnJeJ6noiEsmIEeKbg0Cu+WrMlo+dkuPdptajF6oZyL/2axk+cOFZ6vKum2WWmDzkigFyy+Ju1HlhuVuXvjrEr3TPOYej43YldLVj32E6KA7tWZXlHfDfa/RgpPmA/eoL1AXPTRkxLkx86AJn8Sz3OY5fusD4LHHgMydCRFj6sarQkdfKxoEZq9laD/mFy5Xw62q3AE5ljUExsgkp+j+Zx6EYVGLMSxdbh2AYwDonKKex48++g7VcaEoGnASGinn/+iN5LpxK8dpMFfbByE9ur2DEkAonvAPT6RVzZiBLJW+JALl1YHjS7UaWd71q6HfPcUBtkZ80JOBcbpzYH10kShOsMXY4Ci8tjkoeXJC4grxyyuWaTgtSwKSoSky2UUZ4B/NDGS0nlA1p53oTzLrjztO3p9SA8WoH4AB3orBvHOq8n6m8gnlHxKSdBqjT0h02R+luYuP4/hRod14ZbR+DiZcw7+LF1JaQJF7SmOD91V7STiYmBz6ZHQd604z3VJmfPAA/FhwuEaEDcx9xVPsdg3NqTNpwanmV0x83UhJw6MWIwWlbxm2ODnUpQs3iiMqgD+ClruG2WtsKbfOyGT6l7OK7sllkW7Py/UVxofDf9eG30N7Hozig4K1o2ZO7hJMa5Xj5msWcXSx77ceoSrIACBTI/e1YlZnh7lc0TLrtpIgwsqRM8JxWVIHIaOri3q+AGl8u+OeE9wRsGQ8qQMrqrbL9WGt8qwqEaM3UbUMQj9oS+IOu6/l7yRECcF0RZe9NG9ANd0N0b29ycIu76n9suu5lzDd5xeYOc9NaIWX74loE5fCYe100ulNGd5NeC7zRbjDZqF6o7mUisMpbl5Q2gevbpzDWKTKLq+l4IOfzOdHa5Mtvja7kK9Uvghgkubb1Rqh+QvKoPwZkCiVVV61fTUBCe6y0A/lFAE47hhQHPR5BTgI5CS69F6S+X7UXEU8ZngQim8wy8VH/Vbl0+yZJ5JhhEdU3S8KzoukyNzAbYopUit+akHND/oy0DFHCf8KidwW+x2Gqq6MdowFsePUBs6JPDhV8TDPJFpTMmYdurIJvTlrBjKhKLVtfRQYxaTtVQbijQ1xcksPSIPoqNuP5ZOtuW5g8Fe0+mJfcDQOKb5izLSPU1zI7QH9slJ/MV9dO3CuoyirwDZAo5m4dfMv5HuHLNAQmnQXwe1ngp8UJfdV8cEzuXNqoEhn96LnXFnGbuwvULjlEgwsL7KL7fysqO5LYzpYxh/xQuWkEWA5KvEr6DMeI8ecD1ow+aWO49146FRcZpf5+bzj25Owobgas54ivtetABoQdskghtjhIbZbI+ZjZ91v2qcQ8BOCT+z7NLjWCxhi5hedqpNVJd0LmDOCQw3IpR7jQxi3zY1ABRGmG12pNdyjVzkix1n73A03LtvNeFjamBnz/pmbJYSJw9bph3zxAn16SDOJsNo81CHn7JCJQRF5YrebAdjm/oFndUAjGqmMS84lmeLxx9GbEWl+Ed8xhrpiJvauASYBJ5qDmY8xNYnYT2F1fN+My5WFbfKKb2kvKWhZLTdp+MgHYszPZeRgCm+snT6cWSyM+8KqFGEPP0Goi6d+z+1B5WcU+sEQ4oXr/Ty+pryjFg3mjIEkZIpolQivLVcYXghnysWU3kROhNm6VSxnC5mYIWw4epjObYRIrGSDgffuuqjbyw4X9ZOxW78M6QhLlsRh/ZsrRaax6VNfWpFiOq/IyzZQCZNhIoTf+1gschIq9L04Xc8fbLtlQoxl8dtEZ0Bd/4wzEJEeceB6AOsmZPHLfWGztN6nWqEW6Lq8MIw9DWtcwRxPrwZUrLhdCEZ01IQyawF5IQB1l20+0EX6jujEZAHxXgKTKP3Uwn36gN0BqLVSr3jZk/luWaw8nIhzTOsD+lc3PG/w9UoCKQG+MiafzYiqCz4z2Qx+9rrcApEbh8rY2YfJGx4nB0rqXLZz67LOU1PGt5rB1EZQBb3YB+DAWx4IQ25Xmio9mvgMRTGurjAOUlnit6gdFWVQHVvnGW50GzM50UxBLgxtb8APn4zRimoSGFu0s5RAKMSMBAwDgYDVR0PAQH/BAQDAgeAMA0GC2CGSAGG+mtQCQEOA4ISpgAXbVXDWwJFkYVOZfYmnrbRJXg9cQGihA7XMGfsyEQtxhtMc0vuyklkcZhnZx36fmjRCyDPYqU/fClaRLRebszNjBzY4oD4K3JtzzcpBqyUE2jrlI48Xg8duKHFfCkWZdzr42cwJvg+Abe15IrZrE6/IUCCQCOZFVC5MsN62l2YUOJM+slVDpXx1J976JjOqVl9KtrnBtwxmpuXzd6q9/VOGfdQ/Y2/ClJl+xHmZ1fOloIhgLJ8ivC+fR2TLtXy0NWlfohi1hsTjibgwLKQBrMVkln1prGvjSakeudNICqpb2TDokh/W3WBz+47s0W8n2XOXdZDAGjnKUfULsXe/ikhHzGdYAdGfDiWoDOeR47nzpoNJWwjcY2lAhaAua37O0Z7p4BA8fL3lsKUKdcK6xFQNP+E6whck/F+BeDSCPyw3LknGu+JCh4m9aNFoxzsLiajajKVTvwOmjFMHMwnutABhT5GuVtdX5CdI/2PgufeAKAHYXdP+/4AsjWYIMDK4h979eo+8TfnTPe1dcsI41mR+DH2EFOnhBV8AXtZ6rqQ16oiZT3ekj0OfpNcJfkNMSrC+MnGMyperK9f5hYwrs9PN/BhLQvE3EF0iHQoNeMgT2SKQKcWj0DGW/ZEZS0I85oNWMF99yScVXx2YPxVPERRZ6KJK0eWYwhP3ippx/6wT+GggoqfqDHwVkmxGCdx2AURn+AJolA5joOJsPJ7t8RWRzw7mERcxWEcg+VatkWa3YlsC4HXoK41jHhM7so6hQGpZVAF/zPdVIoAjcd+bCq8EbqT7BGeOGi6KepYPeSGtyjlGKPz51DpM6VLtYu9E83tVVU98zlAr/atGsAPzMu/0FXF8lhNOVixBn4X6cjXn9QxSUc3vCGUdrhdfjMvavtxaWkMB1VQejvJ3FMS0ah7D4YHZPxjAdLcX7aX7K3/WVqLRYNFtStsCxZ7kPrhsU6BwnEildti/zzQy1BnOH43WDMgjcld8i5dI9qqfjsC75IkosmjOcuIZg9gK6o2ES4KMYWY2JELGqmledasOgDa9cu7JcmHmQytMocWguNHqrJFv5KNQJBsN0GJhzwD4YuKFrk+y5UiGXuqwsQKDIA8vpr5kIdFz05Ewc3ulCM69Ze2q2gIRDxwjrelvE4F24cD+R6kENbdWnYps51hKSUYmggxjYAoIqHJ+jDXnteoKK3gX5UUDJjLbOnTKGherhWG0lLLsI1iPXA0mCU0wExzZtHjKrTL+NbY8VqC1Uew6TIfQmrX8dsFCMrJdvxUrh65HrFD2+izffTJwMXk//ciA2VRhQQHNgWLIq3TDa6nB3Q3D+zJDbu1vPR9liWS2SJoGCgoum/7HpTJkYJmCB1l/m2MyUR6J8ryJ/VcplB7iS8Pyk8yxso0fQ5vEw9jqFUTFHx2nAQegiIDwsoiwgjL1s5beD9yQNfhvgeiJDs22v2SpDWCVhsn8q7jgxhr0PwYNF26dCZ6s8S5WPFG2hSlIdIrPvq6m0Gq88qOkpqj0iof41vWNgJXujT2qc695kGnhIs588GB/PyrcAf/FZ+eh+EeuYxB5aNmUkLJ7vk5cMHmwLPu0tSzKu6YZeO07iWnObuJ1bF48TSE5XPcSufmxNw5zwmg2fPOjBawZyrnmi3a7wGWPAQQU13M4RZCtfqjtAKy0egE9CTPOc8MkJ1JpLxwATv3IuCBe5cQRlqderkFs2/STLv8SSt1EB72u59QVtKNdbukPMp3NRxWQvWf94CayNUycXbqr0qrMRr6D2Bn5W8bEd4iOpLkTPY5HPmHAkNKRqb6vkdxAmo0Wr5Mzf0cIYeSexPAptq3jq3+nqUkqbYewBa/Fd1CUTNYcrUaqk2UXqm3Kue2GVA6SWZ6LTb3soZ4d2TR0kRdIN7bp/xSsby9hAwztTFtAgp8RaAuJ9iXw/rfzf7gMF/A0DIilKAV/QSPH06GiZKDU6/vIsTLSfe80V+Q0xwmbp/1xVNqy8LsjG/5OYQl+xfHoy7fZXDwgFIjfNd7Pr1Prai/rKlzQUL3h/P3sN4o/xw0rRqdflhae4UZkVfyEYAtfxIZCFloyGixTL4SLNKt0HihzghnTNPcYZkmzh/0x7SpmiC9h2r8+vijJuxincqCfYK4sJlk8SaDcFuPPPVP1dzUJ+V87HJLjHVnEImkuLCy0onvCG4whB5F0Z0RRqBLv22xQViCqrFbKP3OIWWdizMJ0fP9qTJnWhuBKwTLesQahuiW/ziMJmqFGnjiicu/ovnGYqNaJwC1XTsbMxeRElVuI4ZBkTtAlYF462YGRIKlwpwDosR/PmJ/Oj07U1JGheeFI2Z4MTdywolxI5R8c47TIvpLrQORsBb8f0wIPYLXP3jX3ivCCTEwlmcj3T59rv0SGftfkfW35dvphBZTJAkBQSdB8xDgJlYTXSmzmFlIY+To9xnZPowlP2lRAPODGiqAX4IKuUskDU6Q49SpBfn620/7xd1/LXUftGS5nQHthxFydKwkmj4dc39dhkH/OvzzVPEVK/UXLk7iGzMliN5aoNp8CNhq2r1V8tC7YhhkitvYWtEHZpsbbQhBu2piX3sJHyd3xIDxkqqIyXMGlzP5LH9FEVrcLL1qFklLMLcunvYPUxqnHb1brX1VmvPK+dwwrPzkJlgzo23VFsPA+3PB332fj8dQohDr085bXiF30Y703wej634/uuCsBAwUsHBDR4B/TrhFVHix1295Eumo/HmS9rZLCpTl1VM06IXkEiXZQH+gIJWfYXBIISq6Rc4dfY7xazEYj/4tinTu6IiHkLQ1OiJH99sS7tb5Kj/nzQwmIV93aeXb/wOoRxoc5386Rw+iwD/cBFzP5titlIEfuYqbtd07eysAQFYpyTE+sQ5jsEgKLc5miRnZRLbSwH3Z/D8qUrVIgDNpcotiHLsQce/VoWJh/O2kkH2ksEPObZXIBDGzQiD7yBAojGwOymFgzASizn5o+ArK4f/ZLkue1ncDV2Lww/JyGZrAq130jr66xA0RdrEXrXUtjx+go39sxozwiwb7hJ1RMPW6rWSsjhdgZZkjnSngwS+cWYFtx2+4k4ofXl1zyO5U/OLHfSJVKXl4WPBmbr133cQKDXTw+flwYUnkHMS38kOAjuUKKwZSh4FDqQXxPBnh281zRE9AW8UiY8gK4RJ71JILezyTFKCAsyWOJcb3ODPYt1E1W0v1MmT3gxQ34C0wlTQ703Ds/3JbME2VD+Kzw+9tOQywNz3PyvNO3QAT8hVl2rLLSLIh/4voiDlET74XLHriH2f8+jGsRFPfGi9hVa7bJKF1EqswCglZ1QLRaqQQLw9L2jUvQ1DXO4O7WtVrDm47D0UAya6AakuOakcz8NE7IGyzh/H4iX+xFe/woqdxmm5c6H5hS40pfBgYIs1VhN7YKg2e2c5n8OSIybNDpkdYU4D/OQiI2Xzy34xzlqBHhrgHfR+8/QfV/D8fupmP0ZAf7gKVsrv+zdVGxMObXBxgjKkw/P1BDyPrMQk86eJglemJI8j7AMp6kwlVgx9nHGYFHPUuLyFuqfdNfvc71OFYOTY4w/gdxikyS2djU79AfuwGUx1SOwR2y/7hm24+AJCbeW+fLHV0u27d+dkxagjkCkcGTXNPc1QT6ktF6W4PQYxcOsAMqfxEu0kJ1VMCKYXSxh0mpFSIScYbr3LBKEi+BvnW4skk78+Wa6teb8pUBPTmOsxdK4tz7BNpN4iYyKrn8ZiR6ufy3M3kO7VhxvP+vqRYo+d4TXD+KlFjZvxEHHCvj0W0K67nBFvvrfSmr8H7hGN70VGc1RNKUGJQpVtdGyxAAFdJfN5ylf3UzlO+eEmuebW5kqE2BgZWIxZSxBTu5G5nyY/oAigfVck9aN66cz8iSu67MGPL1VteLHOrVRcvABWKtE7iIHZN/NQBZsAefBAR1Wi05YOPqTTZZ5y/dKQR45iJCRTEZR5tHfPtvwXjmKOB8IGfPV9gk9wx2Cr/C3qOj4KBkU03bp9wWUFBf19g68+ghOZrvuF7MKRNGFrkBfdHXZq1IjQgmVmwJwc7rmRnZS6Y468ZOGfQTTP/dJ7GDeP+kpxSE3pWdN4F9BLVgGwu3dCyxKbhcQ7KNkpfnfcbYzyJREaTdzzus2TlKP2JOOhg0wCtYT4Ar0XCF759JjXYWkHhPpv5kskw3EJBvDlGZm0fj8bmYqZ4tSNa4SDuPp2bEoPzMG4ARbV3Bur3n133oI493OHtzDraEx0+Ud2ciYaHeZKuRuIvQn64OcSieMUDwu63afXo+s3c+aBeRN1WfmseQkirKZh0jt22J6GzpAxn75BtAYR3ftqGWAbfV1hbZIKrMzCzpkT0ScUwADyfnO8BaLa1tOQG+Tib12TKX/agcHJgSKmkl5u4n6sW2euT/8WJ97/AhWN7z+hjw2iEq6s7/jefH+rM5PDzu6vOgfVPqe/TfVvSH/BxRekoMxj1IIbAdU7Knr5jZwsE23qObWCOoJgXIB0UucCgHGRsxlTqIqL6ZKByjzLNv8ZNdD1XSuAJacyRur1t7a7h5cQoBPMS2XWYMcO47zmGMZTl5ueGvQSngCM0rZn8FJDr+T9GMwFozYBe7X+mpiM4Ib85krhbsL4KjKmhhSDNwxQyN6gJHJ1JQK6mCbnViRwUe6qUKNWPITiEPkquBxPvAAWJN6gkWkaoaEWk1DcYWN03znZGFIwrtmpUCsyozgRfMrd2sr4RMSTJN4a5nNAI3lLozQ3qNFHeaTAadmSAHVZ/cg0Lr15PakldwvuIKsiMiD+RPpDPA1p86H4/w0hhCq0tyMwz1pWjLyBQL4C2GWf+v29RZAxB5A+edzXwjk0oBfx4suCJeigxNqd9ZOwObW/PoCrz/apfHcyUng+QszFsy1VxaPW2u2kvfjtFepYEY2gdSSALyCiopqsiZxlpNGUHEBe+jL9cAHBrgMQxMB6465nW5kvVG7N6swaBbW++Kiws8rPAI8zFfQTY9MBdZBLjlPhA1jNGGfRzoII/zsWepnMeRHGUh/yeHdQ0clVW7S0EScTYAmo6CLJT3SbQTT63aM7LEnWKNtKsIRjqxoGK09eTW1+uy3Bwu/lA5/w5qnhAOsSzt3CmSJ/34vYLMUUgkMOC975OLfQLS3y2NcrSVGqDSHLJv+F0OtINbO35w8JkvLnhCriW4l1q/Ej1FWKCvs9GNgxI/w/HGiqXObipTnBkpm4GSciqnGWA4EaxS8fAa4O9DZeCF4dvDd3fQwwz5Eeofk51hLsakh7bamsjvbuGlmUiZweiDPfZhSB1mfgOFZWLMEb8gTQXuURi689bcs4PGAjB48XyrdX4pmaOjnYYqKK2+tdQjhnq8n+JJQz2KS7TS1GSA29whAk6nDXw4RawmQFzRRFliBFkw7CTjOg3IgIzOCfnvCCfj6wvuix+R8TF/qTCLGpLM7RRL6L2ynexznGWvGbMcj7kLIX4K9U0R2MaJS9AXQoHmUbTLkMMKF0K+xd7sUBIik3+dUvopMcJoh78OjVyqqNHKp9uSzvSWpuG3xyfowuZgDHixOycHdNgf9SueW1qeRooWXEaYIM0ORW6w4L6dv7RRjDxnunK8ISpYeyT1hyZcabTsfL9Wxp5cqOLhMhGQ+rDpcGrVJikIf5SJOBJXiHe0iW6WNKlAjHU4HuM28aMQkNMPSD8lJS0VPpdKvRdvVyWhUIfISGGF7Nv7mBYED5vNKnhLRnTEsccriEAl2U4h5qZVO+1PC82vWRcwY38B5R8H8zgTH+l0wc98/vq3Cv8nt1/ULwKGsCVpciGyzZK3UR11fv/NJi2pnTPtyPUBIFi8ev8yPHugGLy3DuGsOZZf84Zjm15aXKxLy654g1CAYXfoT5hqoXXBQX505D5i92Kl+RuN/3BBP3ELILX885QK64ivwx6khW8LYz53yDUJHKck+q346cDYwpc20R0TgAg1n+3FQc5JAJ29xlsQ+0gCy2d39oteiAbCFuavE2+Uf7UsN09kdfOK19NhevcLINgdKXeQT2ZnSlJkoGl5jmhVMkEFXoEJ0wuFlaY9xBkC7i1sw4NpL4gPbbE/Cw5yPIc1TYG09VTYdSQeNJPgWAP2m36AUtUVamsIyQ1UVV5uvP9BgggMD9HjZb09RiK4wpNUleMwswNYHWUoLXvMl9pktP4SZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABg8ZHCMqMDKHTkx78E9T4MrxpHb5ObFu3X1pJPn5GCTJuij6SuKMfkWjLbfXkQybRHW94AqbPpNYFiK3bvLJDYAycO/D5OysR/KPYMPwDA0l1RzdLUb+N5IDUYR6DP1BN5FD5zUQam35E1L3BKETDANGB5jjJ7QqLwA=", + "hJdJceWkzwGadUYhN7cO+kDYedBoH/KM2igA1D9S8CkPWi7bdehOEAaeFM+WWHcMYveiEzq6tJl+980lEWMqmkK97u0NLsvIAhVb4d6oSUkO5NPkbJzyy5o=", + "MG0CAQAwDQYLYIZIAYb6a1AJAQ4EWYSXSXHlpM8BmnVGITe3DvpA2HnQaB/yjNooANQ/UvApD1ou23XoThAGnhTPllh3DGL3ohM6urSZfvfNJRFjKppCve7tDS7LyAIVW+HeqElJDuTT5Gyc8sua", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "cccnFnoyrVQhhy4JgDm7mIdV6wjL89xJFz9Z1L1KIcqCVXsC4gS7y1gP3cb5f6x6UNDOnk39Q7AyMNmOFOETnMkHqWXHfIEooSSntKoL6LYtZsM6fnRbEMX99QWBe1PaMuaDuK6IVa+luvNgcCOLqynQEKQcL1kBmanX6tVPelXKggyhzWRmdG5gHtGYX7t+jbxy9Frt9XG8MXcDwjYt1944nRI3xZG1TXkADaDV9nRtqob4s7/yrsLW1+ARR+L89LESAdk+OiwuDD1hDPLXlv1qzPUxdqYquacUJzfofxxaKE6/3ybeg+zkK2x/hmWrTKDCTKTjFfF4VPuM962pX5EYlY3xfQ1S8Tz9JrEQNRResOcm560JlEHlQ5HGWtGqPwg5sPM262tUMQmH9xn41CgmrvGoIMmYQ5ybsknfnU8fmqaYxIta0xSQr6J1ibQZHuVIR6bdbgPZDyiuKfhbBRjemky9RBoCaoVQ1+dPhEvdwQFzryxrYREqYGd9Zyc7N04ka+CyoPRHoNyQgO4G666ykzO1XiYCtCC4lQqcr3kxGW0ekS53YMQqbPLaTOM7fSJCDmdjHgxgEjKRg9Hzoa0sBBNHYz0QgUl0TgIDDDs4SeAHwKt6211e2GROl3+8V/jHM88473wruWTLf1bwN6Zr0a7YtmxBeLK5a0V7qXC2V7tK1ZKhoVWmxrS7UzBLit4wUNdv+iEqOHhgoqj5l6Xnw+t1fEmWODlTHDlYBYKKkBC7hdHXuOEEP67iXSoNSq8Ue5LAo0wB9sK7ZlAy5Zh9M4FJE95TwkvFHcfuG0lnYKoI5nosoggWpA8mm/6p9LlRKQ5F+ai4v9IVFmzQA8lTQqoXCNVvcllCKPkKtQTyahxhmpcw9mpJSNxdS8/qh+Kmy74ZZ2xE3MpzVWjeFT2gaLjKW3M7Q7WwOrUm8XhmsSqMm8m1LvDLlF0jyQTdIRrLO518H8T74skMFA9wwxsllV0k+07HhUt1FEoFaVjfJggm+a5ahKmrSF+HzJVMV0Nw/N+5KwXOcDPsVQXQ2DMrT56Tle5NPnhvvdPxcHi5YTAMLRFDbakqWZnWi5mVZUeCaFKIhpAVVhieGisRoERP1PShEThAy0QGhIXTkQ9hZX5BMIBPwhu3SNWN/eYiieZdlDSMRWmMxDeTU5T6oZK+H17PMYXBt2zMQLTet7nYwOgt3N/iNYMEweA3P1oi3tHwvnJlD7XUZKJ3ptEiE2+5fEosVpGWUpUYm+u3zev34cFBe2jO8NB06bU9OW0N3EzpuH/gvSiZmhGJUAeTKITpmByvZJacnMOj3GujJTa4lm4/TRYMb2/vlSOkHcOY/XpOPVeXtfjKlwftUTPTlEXE8YtZNP31weERwWfWvb4I6rs67SEkxjJ7hmVo61UGIaw7e5X/wKrK0/ruuaR2lK08DaC1bu+yvfFiVR5Siz1aH1wd/GeolvWqsC/BZyQNmps4z1/SXfdZdQjoviP4ULXQErZ6b5tJjEmkXukBFsxq8OAdMxvUbcLfttrnLip/Zc6d6nePlwy4qlygy3ny35kM8c5ypwPcfbTBWHwv89G8XZD5DiRP7UrRGCshcQMOa9jQj3lPxYamP2GaWfcy5RpTTrQG30C7iPcPg6DGxZyLiMZnQvIH9iqsDscld9S3r6GJ2Lsgr22Yp9UIVuVWyYtlNuF7AhTan48HkKZIy0kgXTouuzzkTkIrsFKHtIdsQEa/tbb73hi+fDo78DJzvqsHiaoZr5izVGerTBknEEU6fBYinWXTmVguzOCqf29Cbrr1WzDPWsgLDMUu2ek72eO/Lm3DVhVRSyXZWSfcc7h7m/Ib/lLF9a5vfHK5oChQFdr9juDw3mIr8KkLgPsAZ0kUXmOWI3kXZGr3DUfqzGOLm3sIXHdKK8GexNc5K6k0HkKcX1iFZIIkZjNj4lumcmJqSMCe8hmdkzDiRLxL6jt9MvV0mTVQ+jXeQ2Xe+4bizqG8E6ysktGa8vyrP91cuP9xzJy8LGOgEt6W5s931buKTtU/GviBMpeZdlHiwJiIzpSHcvYJwa7hL2lRIT3mz9vuZYhDwfBe75vbtHj3OQXRJsgONn8UmcindZS0wO9UI72BXX4fD6xfo4wyb5u1ujiPZScdYpEITWd5Bo9Vd8ME8Z5FBlKykvevo6lVEFM8JRt7aCvKetq+XOCWNLjBJRfugXzFUFhgjTLjNhUiCHdQ9mhJcX4sge1YiUDn1NxNxYtqQd2goYJKFf9kEKFK+s9zVCU4pTmXtOlZDH2v+LiTsI3NB8ZMGzhCmKGm4gvZRwS/M/bHqEfhT3fDhZu0Tp6xcDUox8vIkpYnP43h+Fq/JNjlfLqoqOiNQYINz3IantyVSmvf7Q1M5uVSWiJVHbNavdkk+mQer05xu8snrnUguG15aLnncMkO4USjLI51bTGIOjr/lAoqlCujNSJ4gJeZLMdbN7zE8SaYTWxuZyLCqSKRk8oR6BaUhrAm0x8CNQSt5oxqjc/vUAK0GAld6eRl2dv31FU8EaIkGyCEJPjaZsJsEIEjukJZ1jClFOKV0x2NRyeFU1W3pF75g5NwbvHWUOp71ukrzWg6papz5C/S3rB4VkQ8DtH7KZt1unZ2nF7knc5sXJOG1ksdsXwF+iyQpeM3xpJH8Z/IgAvYkTKGiRF07lGhhEXR8/smGR3SfEwkLOsbopw6SZlonC7C92wIMN31SBWV1hi18GaR22a2xlMhDMsvkbyC9qRjdmBJa8b85TFkd6tqjFWpSC9OVvfWdVJxwazatAdA/ROyp5tPIFETmmqqMkbU/Y0O1gsfvSrkiEr6kfT/zpIq2W2TcL+xMLq4cQl93mzKhavPC5GQP1G1qwqksXRW9sokIqCNW44oFmWTYOoKoqDiKi8gvRi8LmGX8HwFbQYUehVU/JKW4fUn7VbxlHHcWtdWZYCMwlsAZCngbY65ERtt7oBXJtHoJDxlwtCHWvjQRHWjP0Whi37rC7sccTSG4qCF2PrAHk4wmH4ApxQMzgzk41zApidOUf64XBc2IzrWwrCiwSE728fgpYfEDQ0GAnLWGP2glhQ+3W5YI/Kwi2Y/DA1efxtj7td0DO7ouxQ6hqNr2GRFRTG23ua9Nw8hj5quryAZ4YnDbF7QrTnG3XOooOuXtymEv6QXSl4G3eMSbHE1g2YTEtHa/vrG349QFmCTgCVKGXR+una73QCWXCVnwOXU4UTkOAnEne+8VJraZXIxaO1LU2O0ZU5YjDmJZkd8nEPXWz1iK4gwKfpb8bgA3Z9NwOAAUXJkpkuhXdkHq1sAvU3zFGU3PUFOhOrHivnosIS4hSu0b/y0QO6Uwb3f9nRepLFxUgDlT7llX1iTE5BWij+Aq+e8IiVqzsB3Wbb1hxHFIToOR5c1AMD4FpdoucvS48E6201BTnZ1c9pbaIYGNIKLL1oQIW8UW8OAxGPlVKjKcdeTeuODfemoIbwh9mqeoHKTpcYL0MqJ5GUoqitfvmtGGXjE72IVv+8/4pss5OxesNAGczOqRcaT9V46nPu5n1teMP4V2AKbhVej0iF9kap7C2kuTR26FjjBlR0PtzaQCqlalIdKiyAkr7trQib7EUuQXj4eky68fPcQkfBXdz73lTttmp4sMZcoM2pDMN86AQbUoXuik+bdp3SHGMiq+jp8jbTttmgxuBARvxmnppwjzhaTsV1D2CHPDBsvTo4alX5UpUni2C0kfGZSjE371sMSQ+izr/HjWS+hhBcht3HJaSatZQxCeFW+YVAiPnnw3gMZZ2O/MHbh53t8Sy11yVJVfsxDq4M5HuIF0klIrRwER8XIducd47woPFlk7pNa8W01aqL0lTxn6vf8aZgQhjNk5SFxQdpTeN0n9CufUG3Imq1OSQiMOfwISo9SOH/L7P5FyO7KxXJpE6PeVby1xLPqK1SbeJhoqu/n0kfr41/QFmyWcI6sq84MtH61rdvCkfT3vfCHP/L4uJq/yF/mjWUosTK6KdZneM7/kdkSY945YjpCQZxXMGaFlabuAi+EkTKmixXKlNL1PNS2cfxZ+Luv+vIqmcpvzRx/0frLc5mcO1K4RXMWCiH24f67kD3ka1sUW2fseHLDI3uEJ4R3CssBdNRIHx7T1SxuYQYFqqzwuv0De1EiT1e3/GVKN5NRG9KaU51S0TwnlQ7I2GhHmKjinbc9pr8Z41YXTa7m+8Uc52w3R/wsIweCoL8GkEAp7QBiYjz5+328jbjq1enkclGFFZ3D/ML7trbFK6J0QBF8WbobV9RPcsw6SYFNxL3iSr2qKoIHHG067bkOaxJNqhxI2Vw1/kwKIT/atjAzaHfCmMwVA9wjRWxkYS+ShmT2yxSnXoTA8sw7sULVvSTnDsaWhSAeQ2KW9G7Pa/NZbOY19/8uAdvkmvxX+KaML7CcAVZd8gR2u+43vqi+FKv9J4KUS+dD//z0YqY+JlmeeOmo8O0fmm8jxFe2XZJXMDJnwfritSm8w08UBNGCajC18gcrCs/XKEZhn22TAMBpw8I2g1ty98r43sVnqh2jzJ2xVGnDa4iHMwYXN/Jq/WyXcze7jrwBOYAr70fp0Y50R0pSGnvLMeMH+VYM7/EPnXUCYEcIa3791BjNnnaDj6zxRqts4ZQC0IQvS1zrta38hxG8Zh8G57VaCmShswLu0v4dmuAJf92nYgdxg9A79sVS2hxDV0eSNcju5Dl1ejzZskIYkmQgnelYQWRxDKqdYAkUg1Ik0n2vcMDKAB/0V032PEBLpbLyyEGkHabsqiv560BhvdE5wnBfAtMGOpRfJAiyd4qpCFfG+C+aYpzs2KmbW1c08CKJspg3vVWBfp7W7XsjgpEYYEM2bUcKNQtTssSnQnE90gG9FkYN3NT0MMeght5T4A+nnaXbe+oW/tsMhGVVUI3GspjwamvCb7B4wsIvOWmlzhKbYP8qw5kSjPsbiz3la1h0mG9Vg/cTGUuEfUiuLT5tEK76u9YgaVxjhaIaABC9ighNGdORaF3WfdxHcDZ/VKh/Mtpuou70vk7OWTBHRncTztcUlc04rEG88BjKhilhAzFLgeXtkHa13+b3LGhWbogfAGTnNbyh0P5+VhAHr2QCZAl60R6282D+sVxatAQ+0TwParpYaxwIqR1445QKNLwueqREVm7ZjG2MI8MSkasBlFQD7ujdQt7Yi7v31zLs2KJZD39i6Zx81xBOn7F9fV1fleJGBlknewZxL4D4xMLehYxqm9L36zykGe/a0VU7Ia2cIT2iDBgM7WoYNwxJS2QAcSzxd1KDBjIHsom7/Ub7IJaruAGJuzTK0kVsONe1zS9SHBi2Z0m1LXYpFoTzy3lRsHSErfIhbu/TA3EBQu+VZ0uQX8jPZ9mkV99C6yI/I6hZMfDxcaWU1oTYXgnaz+WtgNB641kQHUJr5qZizzXQkYWjs1uMWiXE3rx1dQROmrFOe8hewuyQrBd/ghpxDiHcRonDY1rpwh/Cc92AlMwLI4QPYNo8UPvc0ATQ3q1jla09zbhx28Erg+bjE0kNG8cP9hcF51c/r2UCJqlqV1VUGaU/wWc37BoqH/lLddrj8Mz+m0iA1mOJ6S3l8xTZdeUxm48lBp8TlA23tNgIOkJnOK3Frx01T333WCi1wLsQRM5/pEh0tJew8o4HIRwEi7wOvvX9aCjm8rAJfGhGhtDeMv2Ip19YoqtI18nycsWt+eLxjikfzJ+smu3wA6nYkN9K1VXoILSUI3DtyljIyTXWUKisM8F7H02fbLsipfbcZFxzd8DY/MnvX3Gke87JgrjmCZZuv/2WXL53xCJGaLeCd1MDTYb3wMg18vuduGhkbkjSzbsY1ccyV6eByrsbSIX06qZgqiKqky1zn/rSVl+P2w90xU+KWhVmYeyWgCtKMjf9ENbgpzHpRsDDxVrqAu4fP7XzIbuQhW1807i7oa6grecij0aVIM9TBj8FgV50uZmkb7F7ZR4pIo0P2U3fXZDjbGk9jHZgNpzQwSMpCKwAgWkKEEShUNzqLzMZywESHWtMuXrDNxalp3KsNq5nA+QctpPeELMlj5QGZRk/3EG3jwyfp+QMpX1DnsKD4P5ol5PfJla95l8Ux1YqI2NofaSv0wgMFTE1TozG7ESNnajX4AMGHyUxRU6Qr90PKCw5RFR9gorH0d34+g0qOjtQU1eq3foKGVNbctDZKiwtL4HiAAAAAAAAAAYPFR8tNz5EFMcUff2sML2ALwfxbvomGF5pOHu2NReQtZ4hOfKj6w4WZD7ntxHVkJBmvgzh4EHKD8RhVSGmrJaADzhU/HGAhHdmwPDhYrKlRy63a9rpvIiueLV0g/x0DW6UKRwITBzLl492IiEtdZ3Oz0+ZN9VJICkA"), + new("id-MLDSA87-RSA3072-PSS-SHA512", + CompositeMLDsaAlgorithm.MLDsa87WithRSA3072Pss, + "UHLt+1ieITpUSmmBPQh9J6MmyUkFWTalc9QBk0G3TSWZ+iroTuNy3vl1U63NMt+av90+5/lPl9UT47ig5UQyLzePuT3kWrMZoY5jtF7hraJzasyS/Cac7sxzru63/PNgQUe0FC3zMPc45RQRO/ZqD3cWRS+00EeSf4cy2Fnbh34uGyB8Jxk2efTeAfNVKWqvpokxzJmtLve3l6f/7hwsE6CD2vrwsZrI288goPDX8/YNsKYJFwdwLf3RdyyL4CgI9ndJpT5sojBE+Aq4XhBafWa7Lw7pw+wQ5V+Ha2vS7yz17tj0A1ZLMhO0Ljma9maXOPcYQvlowYqFyvJhGQMr+14BjC6C3dvTELdQF0lyTjvTKJaDffD3A5re9XEL7l/HOeZg6bUGdUjybf3X25hJLEFtgPfgc//bsr379JUwS3fVO5Shn2xv7kNu/t45CGLJ1fdFyDrJtasgWxgmUZ2eueA3G1TYEGNGBKts+WpExYRNTLujNE89o7JvoUbxn8r4ZqikcepdeVFaUbV4O/96XtZYHoClalhL6Awr3KOS6/TJinFrR4h4J4XgEQXZenVRSyXaFS1olj4MgRPZA+zcyx5msWOryLdJLaFmTvVcQRHVFI4aiavLOYsvrNd3RBfsdnByKuvveF7yA5KRlBeFn+ho4Y231Bk18mUiM/wpCN57wAowLX0yJVt2BVPNqmKFMGBajXWe9qcm0paECaAWVi8DyXVLaFWEpW6Cv8Lxjx5onSVfUworph4hPBHEnIx5ti5Z/PTp2b+ZXF+kbsOxhfkXQj5VT6QqtbSU4CuZZQtcgssHgEpkPg/KIcZyr70eP6xAkpa2ktGZ44bkHE2ry8MuUce4/U2cRz3J7tQur4IQ2G73Kt8vORxul6UrHgId4VrxGB6EsblYnad8HgtYJcVDG1qRHBDr80VdypLeRLix7r574RxD4M09mrcCryARjMXROe9Fp5IjXK3ouiuDZQ5tmM0qCo33hZYKD6QioM/ryGDfMWWhYGuyWzN/RUX8MnNeISw0UfRLoH0vQIJgLnTBvNupfRyEBfn3arSh35SXyFJrfzmAXEe/SnaJygt6MJlMZHNNSEL9udEkuRAIuE550vvVQZ8T7XO6xkWszd7GQCGeWYvl+UUZZY23ugxc0w63Eoi4JUPaQ9YDsjRWoaSykUayr5vD7LyApb1K1PpGLJApB8TTy19lRMSEFFmOCO6ILjeDk15TgWU+8x/ED22yWAA+pdpFW2ufX6xuBESQccktgXo643BRT7gztdqRO0LZDzWwkUmgjQvk0tFDD2ugeNi5+H88OdugCXPe+1vAuXXnomEb69q+zZMQRbE54hI1bMd45KV8f8uWWTZZnGUpmc3qoEhijmxTPOhgnrjx4a1OSBXua9hvAo82qG1hKyrE4YB0Y1Yo9vFdkJ0eH0L4KAkuHnQxy8rZgAOv5OmAeu5bRft+rD0ICbn+Cc808orSg5hHs7IsKBo9GTKgK/hj0JavTFFbJ12GYnle7o3No44x8XocLd6RD9Q2gwt6sOsYWSP2LuQ/6Tfhfa6kaxfn+mTEYI8pfLHd3oeYTxA8bNBvevqNu+/8Fg9v35LYhag/J+iT8NY3ChYFz2FEqcd4NRmEUkEZsYEvp1AB6aB9gqHTSZRqm5419kuXBApBz3iqv9VT8AuCWDwK1WNcoYbTEMjF6wsUeNA+dlkgJLa0nQGNtAHAusKlyu8mWT2bI5ONC0J0E1lSFX0xV215C7wHcE8GVVS9/9mbxQ8NIjbZScYDEix7BDPJfxHe81JUlhVzvAAScVW/20j4tumgDJqCL5P5tGaLe3S1pr10KM0ewIP0zVsArhoBbxohZAWJSQkLkV5hS3m6g0tgLTMuXPO4gAZm32BSauv91uvMOkq1p2tkc3aAN4vTrCKFibV39bDw3qXMLX0jbC0K50UoTHCSGydfl+IBjXYBGvpgnkoPw7H+P6ipHnwaRnyaTyefDKNmvuOwYX3JHMk68X3GC65rjct97dAL4C8tPkGfGONFEM/uny3RR+16mRyAtm3EG0dwRYa8z+H7ReiyQNLMGlr7/+9DOsa9QJmdd4LtPNz2o45Vwvk/QmVc/nNiBSEZ+auY8hdffVLIZIQujhmwOOFwlWLy/FGz/cyH40p2y+TQGitj/qIueal3pUmJJ36eLtfUnTZXZoGGhmNbxcljXmeDFrSl0IYvDmvM2Oa2ChXROmNgMJ9wscbrO6A9ximf9/b1m7ZaWZXRntgeQlQ/J+N8PrsRyqAPSkMAEJGBT1MKou6ChA4vs2E6tArS3U6cf8q0JCk+EBfe/gf2Kpb0fdO1sNVw5HKu9KlAIgs5r/ZWwA9t1czbLY76qE4Bk2AVk5bz3GUrkNrBVR6pM7t3GywiVvimsS+YGO+o4W2FWjZid0F8eUn+NiVI8sKWUxbVUnl5RzBcd7d0dwRfQGjtrzNtQ4CSMhUyyrCxWlRU2jCdaNglbbvXmjG4P1VVHKoJqqkVjMDLv4I6qMFUGfKxy0Pq6MdTB2IUbln4KrSBdodKlPue1isEMQ0ybAjaOX0WT0ZmhYLiu5QoRMC8Y8cLo7v7Zw8+Lwlu8hj6eY95iceKYKzWNteGjzy5LdLF0SA8kTSopaqagWsZnvtCblPo++nHR2NHQebC9gUmH17Eij72VvcwWHkiICMtwjArW4UPF4bUGWPSH6GvBDFZL4jFRf/P5SEk6cIoqN4TGNnqb7GZ0ZmoMy9S4A9ZTKnkUBPQoEGK08WeiNL7PVXNI3uajNe2ZjRCk/Hu1trQC1KVrePToBD6SYIbaz0AVptm8DdeGGyRiV9qtaEZ4Vb1hWNmsLNDJxnguqUgKXgKchYSlSWEfQiDxpD0TPPTBicQi3zVGa0ykHYznpRbxvdQyttnee+j6iERkn9B0BLIhaCAlZrQWLlhVRyRbjU1EY673KwPLbI0og6d+EorxOffrjITyvZN2jAfFsujo3i//t3Vt9T37xAxIOaMmIcjcnhbzKe8mpTCyPnFMMPuursPI3hpBi4nrEaTpimaY6/Fv3qWdgo6C4xn2Gwa+CfbnEL7D8OO2xWmWumqsnBYnPE2J14ADqWetEOlEyTlg3/qSIARvJFNVycNi3/8gL92/Ra3HQFrPmqcesXJfe3hmsKM3/OguTGEoRl33aQxRD1oKWGpAAu3m+zx3eppsckzMTofKW0orfYxjGqH3lxsyuI5Gr8+Xudn6zOC2o9d2SLsGcmT/NEt21hRNp36O8RohNFpJdYWEJaGeiWMyy3p/v1MOXn9gZf3/a8lG74loclWNuOfaOErzEQUFkW+o6FP1fiX4bVD7vMXO7+uU8dJ5Yb4AbJyKT26bGhrkIXDTnH0ZNCjGwgxO6J//xAYp6fpyFGBVgmpaXewUy1EwRIXLY9UF/67vjSXmyLkBhZvnDS79r1HgLtcoK5B1mzmPsgVNDnp9Z7xMIIBigKCAYEA2kUNTgV7R3Tu9g0Hwcb7QdqLzkzrzbm7U7QgcEl+wQLpb6QU2FFYk3ELsbaxOxdoEYBlLncHDO3Nt8TSvbJjzBTrlJdm6+EYb1Eodl1IZkNS6yw8UIu42Se8SVHKdnakVH29rG1wEdmBGVjpAFFUFzn0aBMLv8BAQIYqBsYgMtlkSirTA9btsFVsF75yVzwyUYMKF/6UJIyF0WmMGcCzO8Z+Ahxmu4mjOfpayC4EhrM08xMx/6y7RkyNKfq5g9OKCPw9EJPIcWrFyNUiBgvgTjZj8nHfsVkbIQNt4Pdn+uQG69lYLdafeYs7kmUNaDTTrJ47D5O2SSU0d+7w0WLR3qKBOp0tfmwDsZh7ED8OVBG9XmWJ/Ny3K0b7euejhzSOHKOFwXDbfXQE+YSB8/lrXxxNYI3Qb6YitGfbzWulndGqhFqw2PTSP+Eg01//OlBTx7xjVsB2/2/kJM2rxx2BUuUmxrs8bkfOx7ny3T2QcrOK8M7bVUoP4XJxJG4FLHLfAgMBAAE=", + "MIIggTCCDLagAwIBAgIUWMbSq/NJR8ZhsezSp75EDe0/QYYwDQYLYIZIAYb6a1AJAQ8wRzENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJjAkBgNVBAMMHWlkLU1MRFNBODctUlNBMzA3Mi1QU1MtU0hBNTEyMB4XDTI1MDcyMTIzMzAwN1oXDTM1MDcyMjIzMzAwN1owRzENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJjAkBgNVBAMMHWlkLU1MRFNBODctUlNBMzA3Mi1QU1MtU0hBNTEyMIILwjANBgtghkgBhvprUAkBDwOCC68AUHLt+1ieITpUSmmBPQh9J6MmyUkFWTalc9QBk0G3TSWZ+iroTuNy3vl1U63NMt+av90+5/lPl9UT47ig5UQyLzePuT3kWrMZoY5jtF7hraJzasyS/Cac7sxzru63/PNgQUe0FC3zMPc45RQRO/ZqD3cWRS+00EeSf4cy2Fnbh34uGyB8Jxk2efTeAfNVKWqvpokxzJmtLve3l6f/7hwsE6CD2vrwsZrI288goPDX8/YNsKYJFwdwLf3RdyyL4CgI9ndJpT5sojBE+Aq4XhBafWa7Lw7pw+wQ5V+Ha2vS7yz17tj0A1ZLMhO0Ljma9maXOPcYQvlowYqFyvJhGQMr+14BjC6C3dvTELdQF0lyTjvTKJaDffD3A5re9XEL7l/HOeZg6bUGdUjybf3X25hJLEFtgPfgc//bsr379JUwS3fVO5Shn2xv7kNu/t45CGLJ1fdFyDrJtasgWxgmUZ2eueA3G1TYEGNGBKts+WpExYRNTLujNE89o7JvoUbxn8r4ZqikcepdeVFaUbV4O/96XtZYHoClalhL6Awr3KOS6/TJinFrR4h4J4XgEQXZenVRSyXaFS1olj4MgRPZA+zcyx5msWOryLdJLaFmTvVcQRHVFI4aiavLOYsvrNd3RBfsdnByKuvveF7yA5KRlBeFn+ho4Y231Bk18mUiM/wpCN57wAowLX0yJVt2BVPNqmKFMGBajXWe9qcm0paECaAWVi8DyXVLaFWEpW6Cv8Lxjx5onSVfUworph4hPBHEnIx5ti5Z/PTp2b+ZXF+kbsOxhfkXQj5VT6QqtbSU4CuZZQtcgssHgEpkPg/KIcZyr70eP6xAkpa2ktGZ44bkHE2ry8MuUce4/U2cRz3J7tQur4IQ2G73Kt8vORxul6UrHgId4VrxGB6EsblYnad8HgtYJcVDG1qRHBDr80VdypLeRLix7r574RxD4M09mrcCryARjMXROe9Fp5IjXK3ouiuDZQ5tmM0qCo33hZYKD6QioM/ryGDfMWWhYGuyWzN/RUX8MnNeISw0UfRLoH0vQIJgLnTBvNupfRyEBfn3arSh35SXyFJrfzmAXEe/SnaJygt6MJlMZHNNSEL9udEkuRAIuE550vvVQZ8T7XO6xkWszd7GQCGeWYvl+UUZZY23ugxc0w63Eoi4JUPaQ9YDsjRWoaSykUayr5vD7LyApb1K1PpGLJApB8TTy19lRMSEFFmOCO6ILjeDk15TgWU+8x/ED22yWAA+pdpFW2ufX6xuBESQccktgXo643BRT7gztdqRO0LZDzWwkUmgjQvk0tFDD2ugeNi5+H88OdugCXPe+1vAuXXnomEb69q+zZMQRbE54hI1bMd45KV8f8uWWTZZnGUpmc3qoEhijmxTPOhgnrjx4a1OSBXua9hvAo82qG1hKyrE4YB0Y1Yo9vFdkJ0eH0L4KAkuHnQxy8rZgAOv5OmAeu5bRft+rD0ICbn+Cc808orSg5hHs7IsKBo9GTKgK/hj0JavTFFbJ12GYnle7o3No44x8XocLd6RD9Q2gwt6sOsYWSP2LuQ/6Tfhfa6kaxfn+mTEYI8pfLHd3oeYTxA8bNBvevqNu+/8Fg9v35LYhag/J+iT8NY3ChYFz2FEqcd4NRmEUkEZsYEvp1AB6aB9gqHTSZRqm5419kuXBApBz3iqv9VT8AuCWDwK1WNcoYbTEMjF6wsUeNA+dlkgJLa0nQGNtAHAusKlyu8mWT2bI5ONC0J0E1lSFX0xV215C7wHcE8GVVS9/9mbxQ8NIjbZScYDEix7BDPJfxHe81JUlhVzvAAScVW/20j4tumgDJqCL5P5tGaLe3S1pr10KM0ewIP0zVsArhoBbxohZAWJSQkLkV5hS3m6g0tgLTMuXPO4gAZm32BSauv91uvMOkq1p2tkc3aAN4vTrCKFibV39bDw3qXMLX0jbC0K50UoTHCSGydfl+IBjXYBGvpgnkoPw7H+P6ipHnwaRnyaTyefDKNmvuOwYX3JHMk68X3GC65rjct97dAL4C8tPkGfGONFEM/uny3RR+16mRyAtm3EG0dwRYa8z+H7ReiyQNLMGlr7/+9DOsa9QJmdd4LtPNz2o45Vwvk/QmVc/nNiBSEZ+auY8hdffVLIZIQujhmwOOFwlWLy/FGz/cyH40p2y+TQGitj/qIueal3pUmJJ36eLtfUnTZXZoGGhmNbxcljXmeDFrSl0IYvDmvM2Oa2ChXROmNgMJ9wscbrO6A9ximf9/b1m7ZaWZXRntgeQlQ/J+N8PrsRyqAPSkMAEJGBT1MKou6ChA4vs2E6tArS3U6cf8q0JCk+EBfe/gf2Kpb0fdO1sNVw5HKu9KlAIgs5r/ZWwA9t1czbLY76qE4Bk2AVk5bz3GUrkNrBVR6pM7t3GywiVvimsS+YGO+o4W2FWjZid0F8eUn+NiVI8sKWUxbVUnl5RzBcd7d0dwRfQGjtrzNtQ4CSMhUyyrCxWlRU2jCdaNglbbvXmjG4P1VVHKoJqqkVjMDLv4I6qMFUGfKxy0Pq6MdTB2IUbln4KrSBdodKlPue1isEMQ0ybAjaOX0WT0ZmhYLiu5QoRMC8Y8cLo7v7Zw8+Lwlu8hj6eY95iceKYKzWNteGjzy5LdLF0SA8kTSopaqagWsZnvtCblPo++nHR2NHQebC9gUmH17Eij72VvcwWHkiICMtwjArW4UPF4bUGWPSH6GvBDFZL4jFRf/P5SEk6cIoqN4TGNnqb7GZ0ZmoMy9S4A9ZTKnkUBPQoEGK08WeiNL7PVXNI3uajNe2ZjRCk/Hu1trQC1KVrePToBD6SYIbaz0AVptm8DdeGGyRiV9qtaEZ4Vb1hWNmsLNDJxnguqUgKXgKchYSlSWEfQiDxpD0TPPTBicQi3zVGa0ykHYznpRbxvdQyttnee+j6iERkn9B0BLIhaCAlZrQWLlhVRyRbjU1EY673KwPLbI0og6d+EorxOffrjITyvZN2jAfFsujo3i//t3Vt9T37xAxIOaMmIcjcnhbzKe8mpTCyPnFMMPuursPI3hpBi4nrEaTpimaY6/Fv3qWdgo6C4xn2Gwa+CfbnEL7D8OO2xWmWumqsnBYnPE2J14ADqWetEOlEyTlg3/qSIARvJFNVycNi3/8gL92/Ra3HQFrPmqcesXJfe3hmsKM3/OguTGEoRl33aQxRD1oKWGpAAu3m+zx3eppsckzMTofKW0orfYxjGqH3lxsyuI5Gr8+Xudn6zOC2o9d2SLsGcmT/NEt21hRNp36O8RohNFpJdYWEJaGeiWMyy3p/v1MOXn9gZf3/a8lG74loclWNuOfaOErzEQUFkW+o6FP1fiX4bVD7vMXO7+uU8dJ5Yb4AbJyKT26bGhrkIXDTnH0ZNCjGwgxO6J//xAYp6fpyFGBVgmpaXewUy1EwRIXLY9UF/67vjSXmyLkBhZvnDS79r1HgLtcoK5B1mzmPsgVNDnp9Z7xMIIBigKCAYEA2kUNTgV7R3Tu9g0Hwcb7QdqLzkzrzbm7U7QgcEl+wQLpb6QU2FFYk3ELsbaxOxdoEYBlLncHDO3Nt8TSvbJjzBTrlJdm6+EYb1Eodl1IZkNS6yw8UIu42Se8SVHKdnakVH29rG1wEdmBGVjpAFFUFzn0aBMLv8BAQIYqBsYgMtlkSirTA9btsFVsF75yVzwyUYMKF/6UJIyF0WmMGcCzO8Z+Ahxmu4mjOfpayC4EhrM08xMx/6y7RkyNKfq5g9OKCPw9EJPIcWrFyNUiBgvgTjZj8nHfsVkbIQNt4Pdn+uQG69lYLdafeYs7kmUNaDTTrJ47D5O2SSU0d+7w0WLR3qKBOp0tfmwDsZh7ED8OVBG9XmWJ/Ny3K0b7euejhzSOHKOFwXDbfXQE+YSB8/lrXxxNYI3Qb6YitGfbzWulndGqhFqw2PTSP+Eg01//OlBTx7xjVsB2/2/kJM2rxx2BUuUmxrs8bkfOx7ny3T2QcrOK8M7bVUoP4XJxJG4FLHLfAgMBAAGjEjAQMA4GA1UdDwEB/wQEAwIHgDANBgtghkgBhvprUAkBDwOCE7QAY6pusxBGQez6Nss+k4+OKkHGXuPqMrOUe9qcS+ajewPu36pl1iHvQT0eJLz82Pt6e3g9sNVK2WSb8gMhXSM+N6E3qUzhRoXR9MlLvYJVA0U4unRvb73eSKQ37QtCuXDTWTGC7PmmF9a5yE2LaPR9wtvObqtfhgEylcDXDGPKVkTDu1SdWO5gqdV20dVkd3gqxr0Vun0cZ2HBN4pP7lGskikM8e3Pxgct95C2PeWWQrJTRurvRjqPsqBVhS0GeO1L+tIlIKD5ym9Rbp0GEiKoJ9KGLQqV/N6iRAS0VcZbRHXUX1Agb1t3Wb5IZRidlyAsguIHvDAO3BEHctaBtBblsl2Q4yREdK01uzBDbX+jaZ3YxZQPRYPluxZqMDyCNSFiSYGYD5eaj4PxMxiee7CY/i4cUcGK9/ihIVLFjgUmdiq/TbG3UndiZNfsVn+0REFh9T8vn5l+MPrr3F1XBfBgRkWbrKoruwFIrT3w8BXk130czS3/aESS8HebjaS8He/mMfzuVZmJOw8+HQ3cj0J+W3VEP+Hud4FVCf1YogQpcO9Lk+khlB8eLcgkqM/SlPASa3Z8rDFoM7zKuQvFJdb4t4Q/jqEwoHoY8i5BLh8Fvz/XLXEjE7dqvOQL7BKEaiwUNEArmrnxT0yD4YOWaDo6F7doLM1ws48+dyHIJAdmeThdUpgCVr/n8aNzsPdu0xNsyIx03cQqdbedhGNDi0LfdvtEktyHIITGVSYWiS61WIn857vbjo7RCRA6qeS0kNwErg7kJxB9MRUE5WqWqnnMW1C1ltPzCir6xlzLOu5DbPghSFm4lnOOhUzugP/LHKzmw5kYR8gRB/BtoNGRQbBHSz+SKnqPl5xh5LuVO96mO5KBjvSE396P6rIj8TUkp7pMKsdSYeULpakNwK3qH/ahulPPWSKmdl0+gGazBeDMD28lJ+DnEuUZccmxDgCBBFxis6dXFepLsUHkMj/VuEC/0QMVdQgiacbXxPTdPHA1IL6/o3wgzk8oqOhCVTq6b3F69NKmPB3Ee/lQxqR1PWKbtPPq+VTZCmxVhIs3vaF9EG3pRd5Ellf7fVkN1CoEpuE6MNsco/V0E5nxmLS9yVg363GXclDudoh2eTaAyuNNDwpHXIVzPJgRYWxa0j4jkqfMZ+p8tYerCt0Eyt8UafbiZMgLw/SvO5wGeFxd8pSVyf8FqzRpbWSrFDEt2siLXiHatVo2mPHQieeaE+wN5LmuCj0zUC6T7qtac1KBpvPOxLuXfEAuBFmECU/pKuJ1VcrReihFSex5X+JLXwMDF5eahZC8tQNbVxmrsa0NCNDlh4fJvbHO0Q7otdEdlCRdYoFBiLcqICfsxINGjqpIqFuxQo3+o6jbvZ9tsuED/0RdZL4F0p+qVP7eQ37er0Jngvj9KoRgILNiCQAom2xNb68MDCsqAJzMiukiv9LGapMn9qB1dogurrM8H1+J+IpOBMb6HaCOYBbnZY+DmHhUh7kcRary2bIKrM6HaHHe99/pMEXR5tafF4i2OobiKjtqj5jlSiZQmA3S/P/n28iMaRcXiAptyTKFcFfmSAnkhBWIS/2IL/6uG+uBB+/SSaK6LV3thZzbMPBWLarDVd5Iv6qLaHYMYRsJKCBRivwGz9P/Lv6+5RIG10oD/JlXsLGsT1qdT3m+yolKK368GetJC8wi1fFbbInOEoKwk/g3PQ4Ak08VR/UUMdQXjS43ZuWiyvx9rScBGIvUQn57KIoUMbpX2H91ewTo5a/O1oiBSAwT06oh7IGM5bYN/PkAJijDG2Alq3u9mmxbqQXSpFQ9Bw4+yLWuomQJv1OCXrlg0HbfjV8FDSHu9X2IRdc7Rm2aw9GC/nfXzlRZXXYjdJzi2ChDgmz+u9Aj9XRY7EfXrb35bJE88BDPs6RCRoEnTzvzZ01p5MZ/YxXzL4TG08XZWzniTQKbI582z3+x9h5Cg07ICTRvd5i2LzSt/upsUgob41nzvzaVAbDXBNZMjiFlX/5vgdYZaH8fm8JcOY8Rz2cjp2ZzoBRJALB8dLRd6IIzpf1jpn6fDxwZRe6nRoYgQXhPFTYKWfifJPoEbSV+IZsTpWjTQqazUPO9KAYihzq5aaeRt6AATlbYLwS0lcQszbWH3jW9WRLspYBk8iHqz9pHDpB5tGewCvPTvQ11JdDR1KPckyFInoTUDsSsdEp1VDB2i+dJ7gT75hTzXzJLiFlZU65usPUXjtmv+q9ozmN7EQiEZm3NJwn+lK+/nfrbahKfv6awMzptgWlK/ecnjQV9S5Ohp7u+e7yqPjCYw9ugkWgA0hZgZEqT4xv6SmXpzwb96+m5kdssjMPvDZyAXWVablhT/+AMQfVKK22QuDzWbx/l8S6q+4F4V94gAxJI4WksNrnWTkwCfvfd7VGRtCHjpDqSnzMzk4hFUrXherAbTF1VBW0zXSFexDUSWNC8jRuzmiPgC/zXIJiMxSLT2EXGRgvLvIfOkPPGmH4GbeiNgepHC8V7i7NyTrtVc92RDY0YND55Yn63+GhtdbGQHfbAwyLv7wtY4BSU6OIAHTBXhIiRS5RxD/l3ZNU0ILcbfrulSshUc6R+Z2IDBDaDdPzw15gwspbx3XFN3wPihe+/CObl+HzNmK8Ld7CU43NmPdRolwtkIetBP08OuaV7UVe/mSCFpsTKP2Sckc2jhtvssuutwCBMvtjzoeIJDmTumtYQCWd/NKAx/UmbJmj/g8aI/NOTAlJza5clP+MfafR6DEIM/bFP8yHSZNcBOZqrXA42Dj0Hs7t3XsIL3ARddbttvB5d5JIVzaEGx7krrGbh+c8xruCD47ns73qspCGxO1WdxN5w3EOWDofSzQixfULljAT9/mNKtANUWIAFGsr3BQ8JvJDkHkGJg/hRkL9UBygmhZ6k4RCHwnQNkCFIaCYPdi6UYqhIM3DyL/Pyr0z6jODoAoAW8eh6UgsgiBrGv8W/22FfNV87NvZJLo5Ogxu8N9c7V752Dp6Dzy2jlsgvjy+Wxss9vXDToaLB62QTw8KyxyptVb96241jJR8DztQeAZagUpkEI6rdO1cXZP+Osws0LsrVWusD7ftcP0pF1rFVcLN1TBofgbnCeHx2ALbRZ64s1cg+ZheArGv8K5cir08prTWmZRwsc8aHwB+tNdOChNzmddqsmvOebYDwNuTHt9Ot8PNORzjfrJkCj8SRPkfIYYIF4AQC2lH4UBYqKcSDSA2UsagPD8Lck8y+iPAAQpH5yQgjNLZtm+6CmtdiY81yhn+QBkSaeygdw1x3bD8e8ppR9FQciL2ppETAYAH5yKyg83pZolfhByKWJTjsQBcFg+qFU4Nb2B9x0lbo5qaDiyVJ/uxjl5fs4bF3laRueFgVHAJUcyO3sMaCGriTvXLt8rnw01QgEUVyKIXGA6EFmHnmvE6KlmjOCBNWMvMWPwlIamhaDc3ZkHHT1tI1fbjfUrg4Mt/BsWpun9OJrKbt+8E5Pr/0iYxPvtYDX3SlWh1r2/qrjxo+3V7nly52+RWr0vXzTUZVelpQnA2qcNflmmXPHuEnMGovjZPrnqpb0KVrkVJ+GLi7DoqNjo/SfVgaw9AFmRKSFkChEYxmJXmPWEtpRtui35QPQOleUe4ZJBU7CUmFe1KsnMjtHJuMBc5VwDICiOgNOa+eSGhrHXeQ4spiWuWBGytzYqabIfaT9K1KqYqACqUW9ykCaTDOLVRryYyTny7u37SBKTlEzmyWRr+LcngLrYJMMGU7ZYmyFEEAP0RPUPioMKcxMJPuZPG6Qq18vfLV/dxZWAFnRzTzAWJehuVUMTap38BKzDSPMVTnbHxHYpcTKJCFfTZej0Ax5yI6eUwreP5rkMwmmni7Kw2PP96iHGu4UHzbFwwlUSKlyBDfJfStzf0Rp3v5NCLpQyYG9WSflaGqiBFsdu/liCPvPQEeS9/C2ogBc7KtGgVdM0Qqsm/ZF7ncPANIgymytrMgk1FhmVp3YhbIXhtphLhA7SwLGLl7rrGjqbMngYlFS8HXuiNi/7ZSWidBqhirGzWkZjlRanPzH4nLm7ueV3685+KzQ0CElgovc98dcn00hw+IzPt8CqQIzdk3A6MKgprYcYPAyXc+LG20El/gaiYqsAzHHG+bOicx2AJUmESV7PyohZnHlAyEzDIV4edgJ9Oyo1gkdKqKNZMKij9mGWxTouYY3jOasLD5vNKV2HDlK3gwzqAqv3HI/itVrdcCt3Lq+ehEoswd/lrdZ9qXpqAWbjztj0T8Z3C/DFjbQWmr7olkWLfnI8AwLYmkVyrVxZ+pKg7XJLvYzf7wa4GwXZGr4h2PFfpmP+7jxm8OAYdQSHDqwpQuAkHWmrcvDABY3yuy3dqVbBYLbuarx0nNsoK5pOjvogmoBA1qoOYJOiUxfZ5Fr4yaGE0kPenyRSFS0PAOhg9jlBAHY5/K8KyyTMpgkKsXmhYV9ElhjYiOKMD9S+GKgsn7EC1Lo1t1LyV4r2bCxfLVpEzyp7xcTe+cyIkz1aFLX5DKKazHvEUk0oBxU57ah02NQS7ePdcHPHM0nimmYE1xhZSVyZAGAtSXuqVy+efT+hxz5xtQT1CloEh3GCC0B18giPsgK7jTi6T+uPIqYsOxljOlyu4O6EG82UHQzXB0dnhbis1WaV1xUS4fD/zdTi8rCSCUACRf6/jP7Opw6xDEysWoiSRK8bxuoYUtB7K2tSMuSA1j/J0yMa35wq+5daMBZTIUy3BUB9Xt1VqmgsmMvSaRbT0WABRiIzHYKaHlNIhb8Y2gKu3VFwa+qK2JEtbxbI3SnEhTxgnqyCnl20E+vmmaPSRJNDSoLxxfMJlgCGww+cc1zi7CRu/QjzNxRdyoNqHgpYhStql1NkbsoycVZwvVzwi5fdaCTn7V7lRFKpxaJXuViHmDR12npmw0vMzIcqw3MdgVm6td2KQDB/hi4tkwbXhIXL1P9UD3YnOW6Tu4TtU5Ke3ioGfYOMWk7gQeOuLKd28E6zYDdHhuJkQs2xbPtWlHPK0rVOgnr6+PHH3slSPo9OJ5K8WapzI3HrOvynmPDwz0Chcq82DwgQ4glmmw+5ucEz4kN5cYccMvXZLPH6EMm1MR06K0PPLKj2rrBEJW4H7vwm2/MyNrUoI6fsPyvvrOo+Qq0yx/GZZJTskxdo5swaMv3aKXhIAUWZY8CEM5X3fjoztO/nLEabXk0CHEBhPEfEMF8yJuKDhAMCmjuQQB6vSV7ir/b2+AfqFbO66MCFjt7P3zlFuuE/lZNj5+qS0K4TBoudHm3IVTCsqx7lmdr1O0uY5q98WvOE/Qd/AELrhacYJzFy5rmecQ298srJ664UbAFo21tMpSquB3HZxxbOlYk/ekncjrtsjRuFWiJmDbv2YESUjyTSNFPerTzh0ziyh3KNPDhAIs31/wG8hyv0KLA+tOo6vmaXNrX2enQowm+jpGdoF+ztzbBnR2LkFfyecv9yyDxC0Thlc5MsgAAcnb01ckUbjXdClq2hYKP8otRQ6zcz9+jg5d3qo25gA7+Xd21M9k275hvIlW6otgZSWZhFWpdNoj6C+X7ILO2FkvXlKaNYGKNpVhovMNZeBhrUnU0uzPzVm44kNm5XiUdPGaISwJ88dokExH8KG+0gL2OQzlA2AVozztBkKgR1mcVNEirDYszYgQDpvWivoG1ynKe0ed0kRS29jbW5IfcCjIPOAP8kX/FQ0yPkc6huAk07oJws6YqZdzWqufwkD+JBqZe5Lvi7xIieYC0YZ2OSA84llE+AfEz3O5sCotmTfDIv3QFgBIeeQxW/1q2k9A1SvCToVMFNxOx9HkIC0OiyUiDBOxZEEPFSa+d+f/WoOK3rk6l/0izvs6NWDsQ00zwF/kdSt2h93U+j5tLFnFkW3FA4Co53qZCC/pRaRMnnry+WpkmyIrEQDo0svF+XVkRzNEPuMrHVzn7NDugoKNgE11uwgh+MXP7TKt3UzvzmkUejQ3js6JCHRoq4+TyGkoJDUN8kbN6NOUYL7ggwynikPwc81tD95KxMWS2eCg6obM9FXttvRNBa/InaUj3HMSddMtWjiBGYc+CYKgG8f7i0yeJ79Rn2J8H7ds+XqPOr1nHJELWDg8RXKmvuP/JCYxWmhxdHeY0wEEFG18goivt9nm+io9Y4qhudIVJ3iFrszU1u7vX26qu+ZJl6bD2+g+U8nKy/QAAAAAAAAAAAAAAAgSHiUvNDpAqdL3CY2/kZv4bT/tI5sTpcFZ/oyXLNDIWdxSQxUa9nkxa/Z1SnDOPQ3OFCN/PxAwN6ZpW+Os9nbuB36DvdQbB1Akv5kOLHXIXr+SwJp1RlAYCjUieuayJq1ijT+491gPpS4vQZYtvVgjbmaMc9L93hfIixecjOdjYEWAEIVHr30No2QiiNR3Oz7fD+iUDyOPuxA9E3r0kctLrQv47Pd4eyAqsTcpDG0KSEEj/Qb5LOChRGtHi9kn7G/DxaHqVRS0vcrx1RSXyi/Dv4N963ys37ZyzutDaRLx7i4NVmYuTUN/POpDwjhSPvEjOysmjjGlE7pC8Rnm7kSzhvtGROlHfSj1AsQCCf0v6GJ+E0anAkv26VMdRPLJoMy3YMJAFFpWKzvSWdnyffRDvsfe+20kfQrdrrGGraQHAmW8QmrM/LPIOO6JY4njNlyVN+kHLrMyGp47sk0ykPh7R+bY66CiLHVRSUTL8Z1+wj17wqRnW5Vj3nSE71uBPuqsLIbSPByq", + "z+YybfXFJnkvjQ3BsOcUYAhD/avq49NgXPBQ0NaULTowggbjAgEAAoIBgQDaRQ1OBXtHdO72DQfBxvtB2ovOTOvNubtTtCBwSX7BAulvpBTYUViTcQuxtrE7F2gRgGUudwcM7c23xNK9smPMFOuUl2br4RhvUSh2XUhmQ1LrLDxQi7jZJ7xJUcp2dqRUfb2sbXAR2YEZWOkAUVQXOfRoEwu/wEBAhioGxiAy2WRKKtMD1u2wVWwXvnJXPDJRgwoX/pQkjIXRaYwZwLM7xn4CHGa7iaM5+lrILgSGszTzEzH/rLtGTI0p+rmD04oI/D0Qk8hxasXI1SIGC+BONmPycd+xWRshA23g92f65Abr2Vgt1p95izuSZQ1oNNOsnjsPk7ZJJTR37vDRYtHeooE6nS1+bAOxmHsQPw5UEb1eZYn83LcrRvt656OHNI4co4XBcNt9dAT5hIHz+WtfHE1gjdBvpiK0Z9vNa6Wd0aqEWrDY9NI/4SDTX/86UFPHvGNWwHb/b+QkzavHHYFS5SbGuzxuR87HufLdPZBys4rwzttVSg/hcnEkbgUsct8CAwEAAQKCAYBhiOjEnBt2F3Eu3yy/sTCWwVem9OWMNTpZ0YyLULRFAI2atzofXd5UaHgezjINY0y8QWE1bbfnVZ6PR3MalIwW5qRM7ojtz9TQ7XXEyrNvCxeTAl3jakRMOX7gTp3H6QVOwi+PTQn+1/BiCMJ5w13t0RZ/qT8fTQQJMUq3YzKBNnaj09YeiZ0GJm3agF5sz/f2R7WrejXtzSOBLAaQfXU6OV0WiWV42Szo3BBUEogwPwVit4mopCG9bLjJ8QGUQGLDEH9WtrQr5EHjAWYYRRD/6zFYDX13D+QRq2NBUASzeaLqTw8OtPjvk1BBLUxzy1Zcsh+Lmeb7h/TwRCGzX8q73j9vkBy1Hrh5uGXY9C3SKyCCYqPFK7bAoSgAreqiPsrWMaJX8smkd4n0CTNiyJBKdQxBDd3DuMN0zsi3B2pwAGatN0QE92hvZty9VwedlCIjXlA/nWSVX6zYElj++P7ifQn/sGG6oXifRKJhgNi9YZ8s/PndcZ8Q0nyDexdw2oUCgcEA/Yn/uViEg2es5U/GVnB6iA9/EbCQ6/KAzYW94Nb/VswCfab+o+3ZECIe+gYq+st2V1EHdWR0QrwauvKEBS6pdg6GTBW//wXVFBkFMeM1oKexTQArLzIj7h213QYvhNXawiNURx5DCX7yh1LXnHJQCoyp9aGejQjtyosaGFT2j2JVOayHxY9TzctMuRBET0IZQLny/S1QWvyqRcuBADVzH2d3Qg1Nm09unFfGDcmbcZKVbErJzoQj0hIY9uByXfhdAoHBANxjajIwXH4aiz9bXyjEflVfFi/PgPgHUssvSRAZbtJBP2fYn58f7JFvlPhxpaRyGbICjRrViL1+XnL1Mi+IpewdyInbVvODc8dZXCFltpjbogvVxrls6cA0zQUhxmNTxMMsDAhjiAwY/v270TK41RDUKmvBo2kg4zOT2Qbr2KP7Y2vfVXezpf51X0d8PO8xSN0MZhjCb77VikToIl1ldDTG0T24m2Yztx6NlYu3nUW/H5XU3z7y0Gt7ImDlPRH0awKBwQDsnCG77kDUhSeUZUualaO0YIncj2Pf3lOX+c1HDD4E2aUlcHhJsgmVhdJU0PbBUKnjOOp2AsaBFRz5BKRyVaauV0W7sbyZGe9Nrz/q27jLclQDoTmr9OYVLULwvvoPxKg/70qSiEpVjVR3N7eh+Ah8n+NpKWhXBFMuZ3x14qyrCUCx7zJSC71Q2/6A4w5szSnV/vMmlWhdUVjyg8Wi1T7Xuu5QBSw82fdHDp71dQWNCxhJlM4a3bS0MlF76+Cvk70CgcBi3B2JAfSbhKCt/PjEus/Iz+yN6dD6cZ6MElv94sq5ehdNJ/kCUjm2S41RnPkmuSAZn9dYEC1Ug1kuzBqFBBEZx4prfH6WoYLQC5+uQ4gTLYKVOIH6L4bzdzv4b1wktjDvM9T59lvSwWuwug1vaUX6VJHq4GPDBsOkIVAbMLRvapcAjqAyH934NQJWeL6EtWDv913dAWtK+VMa8d5octgbzIuT2jmrMMuV4wEQOX9NCBzNAz5ZaGZhsEyNloc8hJ0CgcBxRhagAHAnp4Emg8JDnAKjkG+8DC32oLpDWIUnUQQKB9cV9KPdfZlXVH3RH2+s3BtJWB8L/M5HWhHmKU4phRfu+26xhWSs21uJtcrfwBKVwtIdKKe9nlJNggvfRkgy5fMy9Sa1a/5GxTw2rnrQVECL25L51UdnSgCPkKeAOTrgjeD/vYAyPtcSL0wlZpPZZRzcz5/Xa60uE1YU4aQXAOAbthk+I0rfHdaB67FkLvKI8p9NfylyBptcwfiDUDmgROE=", + "MIIHHQIBADANBgtghkgBhvprUAkBDwSCBwfP5jJt9cUmeS+NDcGw5xRgCEP9q+rj02Bc8FDQ1pQtOjCCBuMCAQACggGBANpFDU4Fe0d07vYNB8HG+0Hai85M6825u1O0IHBJfsEC6W+kFNhRWJNxC7G2sTsXaBGAZS53BwztzbfE0r2yY8wU65SXZuvhGG9RKHZdSGZDUussPFCLuNknvElRynZ2pFR9vaxtcBHZgRlY6QBRVBc59GgTC7/AQECGKgbGIDLZZEoq0wPW7bBVbBe+clc8MlGDChf+lCSMhdFpjBnAszvGfgIcZruJozn6WsguBIazNPMTMf+su0ZMjSn6uYPTigj8PRCTyHFqxcjVIgYL4E42Y/Jx37FZGyEDbeD3Z/rkBuvZWC3Wn3mLO5JlDWg006yeOw+TtkklNHfu8NFi0d6igTqdLX5sA7GYexA/DlQRvV5lifzctytG+3rno4c0jhyjhcFw2310BPmEgfP5a18cTWCN0G+mIrRn281rpZ3RqoRasNj00j/hINNf/zpQU8e8Y1bAdv9v5CTNq8cdgVLlJsa7PG5Hzse58t09kHKzivDO21VKD+FycSRuBSxy3wIDAQABAoIBgGGI6MScG3YXcS7fLL+xMJbBV6b05Yw1OlnRjItQtEUAjZq3Oh9d3lRoeB7OMg1jTLxBYTVtt+dVno9HcxqUjBbmpEzuiO3P1NDtdcTKs28LF5MCXeNqREw5fuBOncfpBU7CL49NCf7X8GIIwnnDXe3RFn+pPx9NBAkxSrdjMoE2dqPT1h6JnQYmbdqAXmzP9/ZHtat6Ne3NI4EsBpB9dTo5XRaJZXjZLOjcEFQSiDA/BWK3iaikIb1suMnxAZRAYsMQf1a2tCvkQeMBZhhFEP/rMVgNfXcP5BGrY0FQBLN5oupPDw60+O+TUEEtTHPLVlyyH4uZ5vuH9PBEIbNfyrveP2+QHLUeuHm4Zdj0LdIrIIJio8UrtsChKACt6qI+ytYxolfyyaR3ifQJM2LIkEp1DEEN3cO4w3TOyLcHanAAZq03RAT3aG9m3L1XB52UIiNeUD+dZJVfrNgSWP74/uJ9Cf+wYbqheJ9EomGA2L1hnyz8+d1xnxDSfIN7F3DahQKBwQD9if+5WISDZ6zlT8ZWcHqID38RsJDr8oDNhb3g1v9WzAJ9pv6j7dkQIh76Bir6y3ZXUQd1ZHRCvBq68oQFLql2DoZMFb//BdUUGQUx4zWgp7FNACsvMiPuHbXdBi+E1drCI1RHHkMJfvKHUtecclAKjKn1oZ6NCO3KixoYVPaPYlU5rIfFj1PNy0y5EERPQhlAufL9LVBa/KpFy4EANXMfZ3dCDU2bT26cV8YNyZtxkpVsSsnOhCPSEhj24HJd+F0CgcEA3GNqMjBcfhqLP1tfKMR+VV8WL8+A+AdSyy9JEBlu0kE/Z9ifnx/skW+U+HGlpHIZsgKNGtWIvX5ecvUyL4il7B3IidtW84Nzx1lcIWW2mNuiC9XGuWzpwDTNBSHGY1PEwywMCGOIDBj+/bvRMrjVENQqa8GjaSDjM5PZBuvYo/tja99Vd7Ol/nVfR3w87zFI3QxmGMJvvtWKROgiXWV0NMbRPbibZjO3Ho2Vi7edRb8fldTfPvLQa3siYOU9EfRrAoHBAOycIbvuQNSFJ5RlS5qVo7RgidyPY9/eU5f5zUcMPgTZpSVweEmyCZWF0lTQ9sFQqeM46nYCxoEVHPkEpHJVpq5XRbuxvJkZ702vP+rbuMtyVAOhOav05hUtQvC++g/EqD/vSpKISlWNVHc3t6H4CHyf42kpaFcEUy5nfHXirKsJQLHvMlILvVDb/oDjDmzNKdX+8yaVaF1RWPKDxaLVPte67lAFLDzZ90cOnvV1BY0LGEmUzhrdtLQyUXvr4K+TvQKBwGLcHYkB9JuEoK38+MS6z8jP7I3p0PpxnowSW/3iyrl6F00n+QJSObZLjVGc+Sa5IBmf11gQLVSDWS7MGoUEERnHimt8fpahgtALn65DiBMtgpU4gfovhvN3O/hvXCS2MO8z1Pn2W9LBa7C6DW9pRfpUkergY8MGw6QhUBswtG9qlwCOoDIf3fg1AlZ4voS1YO/3Xd0Ba0r5Uxrx3mhy2BvMi5PaOaswy5XjARA5f00IHM0DPlloZmGwTI2WhzyEnQKBwHFGFqAAcCengSaDwkOcAqOQb7wMLfagukNYhSdRBAoH1xX0o919mVdUfdEfb6zcG0lYHwv8zkdaEeYpTimFF+77brGFZKzbW4m1yt/AEpXC0h0op72eUk2CC99GSDLl8zL1JrVr/kbFPDauetBUQIvbkvnVR2dKAI+Qp4A5OuCN4P+9gDI+1xIvTCVmk9llHNzPn9drrS4TVhThpBcA4Bu2GT4jSt8d1oHrsWQu8ojyn01/KXIGm1zB+INQOaBE4Q==", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "r5U6ZofhmU8nTgysoq6hAwj52VNfjsC/RwvD+FLOvnkk3pfGm3CeaIUgjA1DJCzft3HSrnBAltsWfRDsfUJ5lg1gQ1CVmnRLSykXs+PgJZHIbtCBeTFhKsM796UKVrAH+hi3nwQ/tuhrRZRalSm5PQrG4J6On+8fCXxkzHU9GAbY28co4YnePcZKlniKSoISUDvWigZbCizFwiWpq6TLbpms+lalArXoyQFSVVzem0Ku26dJlEVI2Jn6Q5SgPgqL3yJfHrckaocXSNK5xRhwOPDE6dxou3ALksWOnoDDYASQ1GKlcKkxhVKochjoZGp+Rsh8iO0S8AiDnCK6CLjCE4DDN9WEW7T7+7Gs7g5iJrUHe+FGSTVhoedsDopGNf5Qw9hfW6T02CErgjrU0gM0j+JX8+jR+QQ5WlpEeIaBND+TNxXZSlVKUsqaC5V9Dh0WES9lt2jbTC8gXIEQlrdwxEzeg3mifU39xexDJBskIhw2BkFNRMz5HCxoz5IhzXrWPNAf0jfDz30m0MVqQg6lOKdZr/Y8LxyKuj7cGUf+qEpmdZiyCy4mhoO3h9D1W0tSkPgknQBMV5rKRtagcjeTLHqtBlrycG6Ld7oxklfM+3l5JuzPZHDqyB6Foqecvc/37AJrjGVW58Ouj8cP2K7rQi3ONofkNY5qAk+DZ04XerxxCECU1eaJ9X+H3QMo7DK43W+V7bYYXgGtymBnh7Cwr0a9wWgJQDsZ5kaqD7uxjX1D+cNr0/7Rpc7ZiOtVuJTx2HxtCOKOJhcAGS7tLE+3ffdXx9w4xz0tY/fuwk4dbozMeoHmn35LWketL+GIaNtJApVQDPuULCpQnOyS8f919PDgKx/FWLEaCmpU9xjFHFQIblmC5PoK3kmbAJPDlH3hPGdXfw2k2Bjwp/6wgBynaAjQgQedtuQ0HB/UWTmMUgezuStGuBOozsjMhlDUf86a4jCs37XEYJG6LP+IiMX6fYws2njYD2g7/KO5Z4mvLxxDN8oqPpnSdsEzDJvohcvF5+Z84siBv4geiZPYkkIOr+BR8OT1NLtXe93gdt0t3MdSpGjZCKvQtlXJp7D17QGPZKYGJYGm2eagT5lnxG0Tgg1Ad5iAHFRKQaR7UsrI3v6A22Oqufp8WX4p0niH7vQ+2k0AeGoiEHGGMrBE6uCXAt945tipg7+cLV45pmiD0BPG3s93r5oWc7zmpiR/t05s2NsJCtxjfyYpslj+PZj42x6mr16xCDC2J+uTgowybrYtyXOVsfCpx0lixNmllH8V+ddFgBAZI0ddQ1i1z4z0vznYbdkumhu0hBsAjnqBF1sQqU1ypaXdzdZg7NHPcMapSbgRMBuRgFDlTKBxTbeifMpDrlXA89joDbt4lef2OpBybVJ7VNM7t6hCMQU4wnBbXwTKrnQhuVVeHHxF5Jm9rrLfkZSJNVRFwYk8XfqzQqTLFi7zKOPe+JsUCRvHgQjrd0l8G6tGKI62uOJrUuiPMVnnm2yd+uo43Nr0i5J3zN1c9uH/yngYeICCksOD7rzuO4oKwanpjgCl0A3QYibdaZf/634k1s6M358S5uRfWDuoBtaQjngGxcYI8byyv8bPit8LFn9cJzh/Q7vfQZFxl6n2jLSv3QJ18fQbhwbSEX59lRYn3yUoesFN7SLdRGjmJA17X9nYFNqlQpiIjNkRnxWrmBBAZbYlPPXANeIDA0BUgA2eU/pP3PIP/6MvXEyG0xh2OFBqWjhVP7U6pnZNY41Lhyxrup9knkVmLPauunSDrOV5hOz5RRBErxuNWxCvFniKVVIzTBwYQ5xo34yCeDZk+XuLxWsEflbvpPRJ3c7cs82MjNizW8UzCn/wn42Blfhuhq0GOrDCQcKbdz78zf5AKyF/ZJMLf2kVE9NxppIszPOx70A6nXeK+p9LbJ9hRoE0OY6RJySdouiilvMhU/h0GrWy2BH4IPtoIh6I/nntLiYd09BuekHGVQmz1VfHctBDp1+V/m4rEp88nvoCIfwKRwiLMVjeV0pWv4+11JJkdINuUwSUzX6envuswxSEPYYZZajSNuU6mBPaFCF4CVYmb8CQ1xmNZrMwOPsVZg8nhKmQfGbKR6J4nNMjOgQZVZ/UKJ3NAxImseKHrrFFxo77Rw/JFrRFK1qBq0OEgbqkxAZWY1Vi4cE/AsSCeqirXH8Jh7eaOg4EOh87HIDj4tupyIUqhhWyVP2P7xe7uMWuYrWunKhfEaLp8Njd06qoYScUqgdxRw5+WrEWOrvpMcG6aHNPxDeAFwiDSwdHxkKyQmyYJKcOcqpYRW786A9sC4tif9xtq557LyY1fMQm40a1ryqNvtwM1GguLs/4FYkAWF8Qkk6jLA89kr7i+tCDTpfszdh9Puu3YOwlbowR5+TzyRp/OqctlXS7OwwF/PiDVCQGxUDPm4HtvFZRDaHOb8etadn3NiEe7+yodHi4uVYftgw0/1h5VZqH0SzCFJ3rr+2ocSMGRjgqYlET4vF22L5/6s7R445BEGASqgcHZCXxKeMp9QD+pU7cWgCrnwmeZHx+Z4ceLtg4/pmHi/0/gLroeRN1vmZbGYOUn90fwuSKNmUOVUTdUFuyZbJkrNMUbW4A1OG2nhbrNCu2/pMiSqnFWKuS6cu3bgqEpsJofZRvGcEO/dK6lCONWnI7cT0ygjOfRR9b8BB+PfiA145KEOy9gsxR8hosrpCwuXTqBlTFt9CdscEh3iNmt76CHGIsFg0ZAumqY9KA9JZWLRGz5QVWH34tsGguPqqhgAu9xEdEnf1qbT6Mxsx5PalKySPoyVYLrTv+evlILWkMoHRFMlWpKDiqP5zXEnkv3G+K9ovU6ugVJelMFfb9Bz+bVsFKwl8x1EGoTZkhe0qTApIevaoSQaj216HPZ+CNzmLF3WDjmGKp3hiv51BaTNVIKSu9L9XEZer6UixLtuAO6znKLCI46MOv58vXz0TrRY0BloNn4NJqexVl29NsMwST9xBS0FGx433eimiGJhs/BHReq0KGs27Wc5zLcSv60LQT01XH68Ee9c+zPn+TpJrj1zcGwA+W7C9J5b+uvcvPavIhgtyQ5NZuqLPE+UxCcZfLVS46ihMA+/5qNcXwI9wmXZvAcrLyuE53jkcNsF9/eCIZ5U/8u6QGMwkWp92vEUVjW+1wLfm/4E8IK+EUSsHigQMaYtXjIncWtjcLY8/AuBSaXMCMSOL1B16hdM3JO2RhaP594EMMWISvTc3tGlNHLC5Q/ZWpaLXIFH0E8JkTKNS95uHvKtNKcRBscwSIxgJG2UWzsQ6IbaWDDmxFer+WNzGjDRRIWtJQOcsUDzr4QmyCE9r50pFo4bnfPmZ2hfym1AtC7TfI1yzDqKJ0Oh05uHNc0HgM7fPuRq0VCKaVotjAcdgPHg32Qs18feNFTZVjazNn/Sk4NI9tFoivUiQ8mB305V8ibnUNnNn/RMmFYAnxkl8zWIrtgpPNAHH1+ntOP4YWk5pWVnQLrk47MtrQYSqdUs8zro13TFxyQJinfP2Udv3wObKcRVWaj4sA4SjyDb1f76cdhri2IWzoVJO+DEwp6dT4bOgyglHAi4IY+e+C4u19g9njrFk82KKqHsg0u03RJoECu/pPmEyoRqnOZaax1w8c0ekYZjG2pa8JLHZO4puca7En/MvV06ZM1dRQZhgZKAXzDBZkW6R7CNCycdoeo1fkm+bwR+tskvPM0vrTo4ca9l3+NTrhRnY2QJFIuIFX0LFXG+k7hQZAQ1VB/Wc5Cy0pWnQP5DbhMgYHvEwNFFoLYBxMvdemiWhmKQfYmaTC7V+pZU9imnOLOw6NXTn9KqIB2telIyjHKYuLx+c04yLxAndvfQgNXCMAw2VSuGfsOBmT/Y5Xvoj2EXqU/77sgqFnkqaOgNOsMtnnDXh55OBqKJMuZzuhaiiBLVj1Yun56w93lZij+a5x7haPNnOi2/XopcPwY5JJf8lcejBpbNoCTShmFRYCeFbfI1c27eatqOay8tYB/gDhRzJ2Skq1FxuEa0GTtG2Q5v1DIouSunDMkOvON1YCSbgwqI1rAuzzlsW90aEBZYNA5RZGoV9jtJ9aJI5YS/weWSkV76YrEbEUyIqNWEdSWeH3qDQJtnygK7c9qSRQBIVn3GrDKO4NwZyoB4MCYAL4LwMilN/MHiylmRe4nhsK52gRSklY+Ax3AxEoqrcMGo7dQdOIj5BIIIJOQikb7Ny4bK/hwUwZUyNOZEfzjXGvkoJ5U6RmFQNH9AvpzSvAXKWHq1bWFg23vNYGLRpAv8AYjIiQGvRwYv4of1dO5N/PPjOK9GpYV9c4nz6Y+fhUkH5q2ZwECudQcOL2EGTbiwoYgKQJ923UoA8uc4f3yo0tScIXThVED5i3JghYjL7phdS4z+LP72duT/dVyAtt65Z3+QXSDpcvBg2hfoaDWHQtCM+9SXd3lZxQyn6hzysnqOOCXn8pkZl++NWeRIf0Z6qVptgLhSTMyPasp4x5t080T5ID+70giPr/kG2SBo3YRksSGwilfT7emGmhcD90hwGchVSTLHBv9ZHmnaOlVK58T194X6w8r1kXYCgnhJLq5egyE9RQdIPjFQlCXHxxzMCKqnrTIzNwO5iY9i1hqJTd8Yxi7SApPP5RgJU3fOP0Rhe7+K4qoqRobS1Eo/ouaOW2WZabpACQijatnSSt9rL55ilIgPg5838w/nykK0epqGR82X58r9rlzKj37ZGVQh2SdCBuJb84rru+gGB5/8Cd/igbQcwYM1/pQzvSYtd4yfTjbl7iEXOzNhSupR1ShLfZrAKRLzOiqmMfUfzpCsoNb0+folQ+pDATl/dYmkYijL0mm1HYRBP+2oj7S+yW5qtKEPsAubjLoy+uMOvucc9nDiF3q96+2wGDh+c78tmrtP5IQ3tgwgje5nMlInT2yZyHOsKK6tQsIAT5Jq3r6EPfAP42jg7JZRNBEOj6XYWjloSBNoHHRz2/SzeyxKeu7GOPiihVsTf5YXlXzjK85z5a5IFQafAVQ3Np+svkRbcmmlJ2b0Bg9Da02+N9KF8u5/kpSxHzOUk51pgGcy9up1HeWMTca2mxESFXZWb2n46XV8fy96QPR8zrny4ntAAfAC7GysHCwOP1UQuRnSzFGXvglY8YhmA1FiaAm8WuB2UAqVYz+Mf5ECJZjyncrVlrAJrCU5WthlNCOmXd74+QSKQB3rX8JsKfQ3WFIkE2okOgKsqjxj2L0BdU+dTopH60NOrYleVkNpGMVcQPe3gzap0WshvPNus0RxMXx1LdkWKTNUnt8ptfXtdXmNzL+PYFowY2cJoI0iUUzu3gTvSwFAxbgG3d6y7gjsxZQG6jMMQis3S6MpYayyQ0rvtJ+x9+Dsdp3zNwCCzj0DamuSjEQV/ZqbXXacjgbRwzs2mDv+cKUGMHe2Vm6XZZwVt4p0Na+RQtu52ttpCG+WZ3SGXmik7ukeMU28hLMJbFb9Wbab5aMl/trBYzWSzI07Iv04K0y8rPleyI59RhC8ztCFp0O5hKTNM/QS1zA43bGzZLc1ioH0sJdBKGYUFdJxqYcCng22ce15bN3FEqigNu6pJK5hQ6YF4rUL0e5ekJWDgvo35+HfwTNCTWsG4q8kqXgAaHGRmNo4V9HUYUI5+uCwI3/TWLMzfvaEPfwW0cDOiEXhZc27tcRDa2vFnIGV2fGOjc4nOmXMTowtFWMoQRG2PpE40qtwgwq6YQkgx0D91/cGPVcexob8/kQp52M/Hg6HdGmuoBYaDqsl6jDziFdhK+7yQYO96TBeCTz34BtLAbOEflLgbiazMmsYNw3wzDE7yNdt/p80MovD6YLFPNhfmJWk8R6u1Ms1inCPXXaUBzujgWP39qrlzyZAC1X6Qy6UZQBU5uIB9Jwcag9OSI9r1Zy3PU99sa1m6LXjx7E7XU9kHQuZLGo5WXm9tSgYEc90QmSZDKYs1t921A6Azo8BUJ0vwylpmxmqevOutzGQYDG8BNb7JlQnBJvqnJgp8F4+VQ1oIjFvC3Y0YNun6Z5iSeqRQv82AFT79flgVmyQVuBvDaBi+eCjLvRyFFs0z4JxSOZjId5ARiAWvuKcjOgm6HIF+3BCvTwOmTlyQrVJys0dL6BAwtND9DRmxufoeXsP8dMzd4eXunuOhMXGOlprbM4/X3IyR19gQPPm2X7vYKVYKGh6M/QVSW7wAAAAAAAAAAAAAAAAgWHyktNDo/kmbtJhyfP5Bcj9edW1IZKaGZnlPDoPpMQMsspkSf+9SPptE2+3GijhDcx9koYLinus3254eR68SIdKO741mfxxmddfFcc3MSja7g5jXev90Dh4ddugHs6Hun3ERUpmePgn/HlDXUOrFsTto8idTNBjdn/DTg9tbFecYE/+yBeNZWW7sHUAxeh8fyuGBYbZVJyAS1K6TIhhyVrLTFeyMh05BJ7kczvyXKd1Uz/5ywCpOnFc4395VtbXDVuy8FMQVbYBQ2/6gde5EzVrt6i1fdgx3z3gDfFFxrW0ZLEta7OnbRgga23gOOE0HhnArpHvX8neykGmQkNdwwacEJhuBaB5glFPMJ3x8agtSOj8P7jjo/lMf5qIdNFeKyZDOpmTimxTc4uxR0VwQEmy93zci2J+Q0a2BuNHOcJgWbp/Q2ivockFcfEa38Ed0I+CLSmdz/hPYkh35CZAeK9kRs+e+fInPxrI0lS4S+jPK91Ob1R/hWYb5dZENWpPhzm6hfLQ1k"), + new("id-MLDSA87-RSA4096-PSS-SHA512", + CompositeMLDsaAlgorithm.MLDsa87WithRSA4096Pss, + "sCJhE+NzunR3WvgdR7CbqFKQrkiBnbjaYhZ3GIHATVR7eaQ0p1JxhnLvDjCoIoqVHc1LwdBjOZfN1LOsKBk9/nk4Ji891P6+46TB/pI4jq6Da6Bo7qLTu1o4MsQ+RqA+mpE9EpvHdRQv2OaMnYdLz/NsRcdNrnTBuxa2iE3+65gKpwESaYX7r0uEkCJRkn7B6Njxa+3jKbJGHjIiVjgpZQLhRMb3xaawccO6GxTTq5fc3mdNum66y5fWjn2zunGr0en8DZ5SApeQ2SKLko7Zx31iFCVpfxA1bm3iT7B2AvIUr9pbRViBVRm77/NA/1oG3q2nXA+juUNmoB9lZLwkyI6TVhkpCJOn0Lj6A6zQ9I6HD2XuNBBS+Ukdhum6om8jPJwO3d9TNlHq5cgmj4aYptpjUnGzss+4cDIw7qh3/g8khoFi/e7Rq+WwxeLd3wzXqIW/6mCtsDCFSh+jpsEr/a7SyiLBGlUV2y8e4rywCsojuQErDOBYKC29p4h+aE+SCSnZHvqbD+oDeQDfibDaA6PntWflqxa44Xw1j5PwndVEoIu5mJX6xhv7myBwsmNJX+psLJ8/00LCVLiXvnM1PNxDc2VzyqY/mKfqRud5Q8tZTZKsA8+JmZnDREFKcATsd5lK9CQR4FVXLVUuMF6CriohQUaiVPN5yJrUoggvSniLPbEJvEb/3MDSlAoso5khW5X/JmpieCJAEvOc9sxiUNo7TtOlYa+67fDDg3NDrqS/GkQU3dbmolqD8q0GvGN7MAn8CrOeg23n9dcPjJGOfEjFBFazCuu/Jl8mboxmVMlwaRCM2WGuOVHIXebGoe5mm9umwu1cKLaOi1guezR9h+ntWL893hQi9X9bu8ppFBlh2+3OIrDObgJzeEHtla/pHgINrUOtH3hJbIv4z6nu2Qf2NqJLNIpHo6sxMh7IqEO/mbe7YSZVDBUVZj0P+ykLpZe5p5nKLtmqZfhqdBT2aAVwFdK4fxYife5HHrQd4uzW0uwe4um8h5blThJy7UffexrGCNj8kYJgLOwiSK/307ZmBKKP5/T1ysbvsYtYp3zo1dnvs2ida0hKsa1/t6Imw85Z8CaPTxVdK0czIKurUyAONemyb3xYphEcl55dqca0xKI7VlbrPPu5zJjMA4h+9fO5hla51WngfZTT6Oh9UY4T0j20P1K+tvnxBrp/pL00fHlLbpcQREopqI2tdM0qVWSFQ6e0ARvuRa/bKw96eUmNd5CugOhhyagbdahiSGcfi8ntUAlVJYQzEu9Q5MvNSOWq4GTiCBNKrEi0iRmHmPA0V/NbBxhXop7Ox7EDr6mpf2ee00tMaT8RkxtncxBGy00KC0anESGsbtIcdhYJhaOarVIkfeokRvYGqxs1TSQgyuiTwUMON3j3KKmmsNTFl1a8hLsJ7qweV4B55Lpf6Pwwa7XF2AmqH4bRsOopH5BumWfY4+jn+kkLqj79L4jk9k/IZRAfORiTtPabk/9IpIAe8jYucXA0lOwIhyRmtRaor8kFYAQf2DKPKuwpr4ImNhGlcD0qDhsKKbdAHNzVF/0p2goVmC3jATtkT/8RUiMb0sgSGppOkTOD4X+lfspVaYjHB/xiLODo6WC3DO1Kym4MrjCehAcnwFAamTRBKiJ98YTPFKuTmkOKFBX0mVhQqctHI+rSnm+slNEH7tscpfYeOtGrnG8La9Tpd7iNi80LoU3ihfyPFVjoS0GFLMOp6I31KKe0YRQIHdblGWt7dzgiG95t29WqrwxOpNXAfkNGZATa7pF83h/STawLkQot4Wd565VdIsXKaO6Fq7saWR08f0jscM84xDMcWA2OkKAqTsDusJl9n7Z10Wnq4pXFDKvGTwGQuP6+NZc2o2GW5FpgkaONyH8AVCyPv714iPPmGMOTJ0YRMUh7HGMBh7DuhD/hQ2jJVU1aglsQo1DCZJ1C/E6aiZspOAW8RIn56c4kBnot0RIZ7Q0TL75RYGh00VnT3P3qbPvbiVAT8NGTeKl76dudWlDy0DXEFI/L5Q4W0+q5odM/UA7UTAIT+FvVu/XIkVzbFlxemMfa/1XDQEk1Br5q9bNLJfMViciwvI697aSHx+3QwxauQAyJqo3R4Rk64RrAWnLGw114CQEeFoLqZbihd9Y9vYB7LvOxaixai0SHJcAYLK4Tefjzx4mlFPfB/0aE1dSwjAnFm3UzwSg9jp5EmlOaHWA2uOnPoL6vmhlbvkIFdDEpgErCokXMXOtpjIasZMuJgS78ocHe8Ozs8jFb2zD+qHC8rqOPHl5ripP7FK3FICbWbrZ34M47durfXRTumev5zPXxf/DhCVyfQKoD+rqYZjTCTmitjuJpi7CKng8K7onGAsKtzLBtzv2j6uUbUUTQCz8w0RKE6+jGVXQ/fhiU8Y3IiiPwSK0Zocux5Q39MfD6hsML5+PD54tZmwk4UjsLWxvoo50OFbBSLA7Q4RfuFZUdPcvSEAMPcnxmyk4MZ1eFGu8reQeUAQ+Ezt/wvMZ1t2cbbBnjfe0PLk7iKYS4FwZbVIAOLGY3nZam4qtnk9qgVSR2FjSabQ4bClQE1kk0Scd+hYJd00s1PD3cIjwzocq3zMqD3C2V0Y51r2eB4GQ2P2U5g8aUWSfLJjKi5TLdL0bxgdsUSXPTO6ukuwMi9GDx70/tmsZ7jlI8l2Plc0GYmQszj/qFEfxbc4EJyI5DBrFu323OHSl9KEPbairu+siPFzks1PUBQ3cK6s1ubiym6NbCVFF1he6P1TequNHv86ffzlALnbmL7jZaobf88Ubjwe4RAxcze6o2mBrKqWUDNoYMqk2KLYaQx4pT9lq8ZxKuSRvViwqkYd1G2qm2HddnAfWvhXRERBoYY4/OkYBrsf/awwDpZoeLShADvDkqiXrcKXAMg9jTeURW/KVxRwZ1X28QGUftQ1yi8x9KMUQ/MeLIfdWHAtYkQKCbjUxpqsOlNvSIdZ/8TVTeTca68zRsnCdrK1vvb/lNJ6XIbVXybluRSEPOyIwHGM6M6IZmTtpPcuGdyx1YvpdEws9c4G6fttr9Hh4G/+TlX9DuSc1ypeDwXpywOJWS7UGE5VZUhW3eXzBKmH4VxWAlMa4xr6edKVt/qyq317OHQW3aD48AlQ/HMBFXtzipyNp8nK4FddUugV8pYs5yRPNriKiw0uiAg5CLJ8ONfts5kztkKXbRIYMT+z2Z1C8roP4IvZqtDLw6JwGc4VqoJAmJDJnbcJaaMBMrT7zzIPX/brYAuiCXvQ4HnTAcOObCHnutgM8z+rHX0K3oOWFjRwCyk2RWRutUZ979EpM5HPpzF24UwBGAjQWpErTUza2HlFX6yjg5JLWsxXoQ0L5OJLlgwvU8pTYfoUpuf8N7JeugFWN16myJSK+woMcvIfBDsZ9ns6gm8nYMSGO6cjGAF2kayKoqw6LH6WaUZw7YP/UWVYWyx7Q6VlQH4n5IMIICCgKCAgEAyftH5eqBTTQUcRdQyO9bpayQ1JpSKC6sQgMGzuIBesYuSshIsY5dUsfiUZafu/UTCXAbMiYJa/tprINB4VkOfMmW2fW9BGdU5jLktLuYsdHk6CJjGq3CkMVLQzbVOsK/YrcbI/SpAy1RIRFx+05g/pfP2TUIuyNvtuNDmVrZj7oN1maBGKqgT8Bc0gvhrWcQFop1bQ470CGA1j58getQ4CUOcfifM1w84KIV6RcPsNjNhr/KAzp7i1Uh0eKmQNm0HdYYR55YPa0tB7hejQmBSM5CBvwCVF/L2XEKXTI+yy86NygDSN2smy7njUozkvZ0TMr8hQlV81EyNlR7xu3V/xhVLwsxOSOnMIKF4OKgGZqX/rgRvTgLOgLxpUVW5H9/CIiA+/58wywgxweUjP92e3n9V+TTABxYWpGeyQUO4/3Pk0UKttORbrfiQoXHcwY157RwVxlnw8c/qi3gImOJZg4IuYcrj/l5WI+hHXVwFKHbz4n4bzrIEE6LkrKGcmH4nigGOt+F09fq/6lv9ZFErA4Gc5I5G+Y0D68DKd1IySnHf+t0DSpGLPl+QqR2ShA7oUngxa7PHfPe707eD0TzJSQFHnpXcIgR/DEvi3insPbOlyFaH4qxHB4OYha/aaaRR/+BJNVa5fEJhSv/PjU4qbz9IMcXPic7o9D1F47y0PECAwEAAQ==", + "MIIhgTCCDTagAwIBAgIUGsOJgZ/eV3g3vuIqiOubtFNHIpgwDQYLYIZIAYb6a1AJARAwRzENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJjAkBgNVBAMMHWlkLU1MRFNBODctUlNBNDA5Ni1QU1MtU0hBNTEyMB4XDTI1MDcyMTIzMzAwN1oXDTM1MDcyMjIzMzAwN1owRzENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJjAkBgNVBAMMHWlkLU1MRFNBODctUlNBNDA5Ni1QU1MtU0hBNTEyMIIMQjANBgtghkgBhvprUAkBEAOCDC8AsCJhE+NzunR3WvgdR7CbqFKQrkiBnbjaYhZ3GIHATVR7eaQ0p1JxhnLvDjCoIoqVHc1LwdBjOZfN1LOsKBk9/nk4Ji891P6+46TB/pI4jq6Da6Bo7qLTu1o4MsQ+RqA+mpE9EpvHdRQv2OaMnYdLz/NsRcdNrnTBuxa2iE3+65gKpwESaYX7r0uEkCJRkn7B6Njxa+3jKbJGHjIiVjgpZQLhRMb3xaawccO6GxTTq5fc3mdNum66y5fWjn2zunGr0en8DZ5SApeQ2SKLko7Zx31iFCVpfxA1bm3iT7B2AvIUr9pbRViBVRm77/NA/1oG3q2nXA+juUNmoB9lZLwkyI6TVhkpCJOn0Lj6A6zQ9I6HD2XuNBBS+Ukdhum6om8jPJwO3d9TNlHq5cgmj4aYptpjUnGzss+4cDIw7qh3/g8khoFi/e7Rq+WwxeLd3wzXqIW/6mCtsDCFSh+jpsEr/a7SyiLBGlUV2y8e4rywCsojuQErDOBYKC29p4h+aE+SCSnZHvqbD+oDeQDfibDaA6PntWflqxa44Xw1j5PwndVEoIu5mJX6xhv7myBwsmNJX+psLJ8/00LCVLiXvnM1PNxDc2VzyqY/mKfqRud5Q8tZTZKsA8+JmZnDREFKcATsd5lK9CQR4FVXLVUuMF6CriohQUaiVPN5yJrUoggvSniLPbEJvEb/3MDSlAoso5khW5X/JmpieCJAEvOc9sxiUNo7TtOlYa+67fDDg3NDrqS/GkQU3dbmolqD8q0GvGN7MAn8CrOeg23n9dcPjJGOfEjFBFazCuu/Jl8mboxmVMlwaRCM2WGuOVHIXebGoe5mm9umwu1cKLaOi1guezR9h+ntWL893hQi9X9bu8ppFBlh2+3OIrDObgJzeEHtla/pHgINrUOtH3hJbIv4z6nu2Qf2NqJLNIpHo6sxMh7IqEO/mbe7YSZVDBUVZj0P+ykLpZe5p5nKLtmqZfhqdBT2aAVwFdK4fxYife5HHrQd4uzW0uwe4um8h5blThJy7UffexrGCNj8kYJgLOwiSK/307ZmBKKP5/T1ysbvsYtYp3zo1dnvs2ida0hKsa1/t6Imw85Z8CaPTxVdK0czIKurUyAONemyb3xYphEcl55dqca0xKI7VlbrPPu5zJjMA4h+9fO5hla51WngfZTT6Oh9UY4T0j20P1K+tvnxBrp/pL00fHlLbpcQREopqI2tdM0qVWSFQ6e0ARvuRa/bKw96eUmNd5CugOhhyagbdahiSGcfi8ntUAlVJYQzEu9Q5MvNSOWq4GTiCBNKrEi0iRmHmPA0V/NbBxhXop7Ox7EDr6mpf2ee00tMaT8RkxtncxBGy00KC0anESGsbtIcdhYJhaOarVIkfeokRvYGqxs1TSQgyuiTwUMON3j3KKmmsNTFl1a8hLsJ7qweV4B55Lpf6Pwwa7XF2AmqH4bRsOopH5BumWfY4+jn+kkLqj79L4jk9k/IZRAfORiTtPabk/9IpIAe8jYucXA0lOwIhyRmtRaor8kFYAQf2DKPKuwpr4ImNhGlcD0qDhsKKbdAHNzVF/0p2goVmC3jATtkT/8RUiMb0sgSGppOkTOD4X+lfspVaYjHB/xiLODo6WC3DO1Kym4MrjCehAcnwFAamTRBKiJ98YTPFKuTmkOKFBX0mVhQqctHI+rSnm+slNEH7tscpfYeOtGrnG8La9Tpd7iNi80LoU3ihfyPFVjoS0GFLMOp6I31KKe0YRQIHdblGWt7dzgiG95t29WqrwxOpNXAfkNGZATa7pF83h/STawLkQot4Wd565VdIsXKaO6Fq7saWR08f0jscM84xDMcWA2OkKAqTsDusJl9n7Z10Wnq4pXFDKvGTwGQuP6+NZc2o2GW5FpgkaONyH8AVCyPv714iPPmGMOTJ0YRMUh7HGMBh7DuhD/hQ2jJVU1aglsQo1DCZJ1C/E6aiZspOAW8RIn56c4kBnot0RIZ7Q0TL75RYGh00VnT3P3qbPvbiVAT8NGTeKl76dudWlDy0DXEFI/L5Q4W0+q5odM/UA7UTAIT+FvVu/XIkVzbFlxemMfa/1XDQEk1Br5q9bNLJfMViciwvI697aSHx+3QwxauQAyJqo3R4Rk64RrAWnLGw114CQEeFoLqZbihd9Y9vYB7LvOxaixai0SHJcAYLK4Tefjzx4mlFPfB/0aE1dSwjAnFm3UzwSg9jp5EmlOaHWA2uOnPoL6vmhlbvkIFdDEpgErCokXMXOtpjIasZMuJgS78ocHe8Ozs8jFb2zD+qHC8rqOPHl5ripP7FK3FICbWbrZ34M47durfXRTumev5zPXxf/DhCVyfQKoD+rqYZjTCTmitjuJpi7CKng8K7onGAsKtzLBtzv2j6uUbUUTQCz8w0RKE6+jGVXQ/fhiU8Y3IiiPwSK0Zocux5Q39MfD6hsML5+PD54tZmwk4UjsLWxvoo50OFbBSLA7Q4RfuFZUdPcvSEAMPcnxmyk4MZ1eFGu8reQeUAQ+Ezt/wvMZ1t2cbbBnjfe0PLk7iKYS4FwZbVIAOLGY3nZam4qtnk9qgVSR2FjSabQ4bClQE1kk0Scd+hYJd00s1PD3cIjwzocq3zMqD3C2V0Y51r2eB4GQ2P2U5g8aUWSfLJjKi5TLdL0bxgdsUSXPTO6ukuwMi9GDx70/tmsZ7jlI8l2Plc0GYmQszj/qFEfxbc4EJyI5DBrFu323OHSl9KEPbairu+siPFzks1PUBQ3cK6s1ubiym6NbCVFF1he6P1TequNHv86ffzlALnbmL7jZaobf88Ubjwe4RAxcze6o2mBrKqWUDNoYMqk2KLYaQx4pT9lq8ZxKuSRvViwqkYd1G2qm2HddnAfWvhXRERBoYY4/OkYBrsf/awwDpZoeLShADvDkqiXrcKXAMg9jTeURW/KVxRwZ1X28QGUftQ1yi8x9KMUQ/MeLIfdWHAtYkQKCbjUxpqsOlNvSIdZ/8TVTeTca68zRsnCdrK1vvb/lNJ6XIbVXybluRSEPOyIwHGM6M6IZmTtpPcuGdyx1YvpdEws9c4G6fttr9Hh4G/+TlX9DuSc1ypeDwXpywOJWS7UGE5VZUhW3eXzBKmH4VxWAlMa4xr6edKVt/qyq317OHQW3aD48AlQ/HMBFXtzipyNp8nK4FddUugV8pYs5yRPNriKiw0uiAg5CLJ8ONfts5kztkKXbRIYMT+z2Z1C8roP4IvZqtDLw6JwGc4VqoJAmJDJnbcJaaMBMrT7zzIPX/brYAuiCXvQ4HnTAcOObCHnutgM8z+rHX0K3oOWFjRwCyk2RWRutUZ979EpM5HPpzF24UwBGAjQWpErTUza2HlFX6yjg5JLWsxXoQ0L5OJLlgwvU8pTYfoUpuf8N7JeugFWN16myJSK+woMcvIfBDsZ9ns6gm8nYMSGO6cjGAF2kayKoqw6LH6WaUZw7YP/UWVYWyx7Q6VlQH4n5IMIICCgKCAgEAyftH5eqBTTQUcRdQyO9bpayQ1JpSKC6sQgMGzuIBesYuSshIsY5dUsfiUZafu/UTCXAbMiYJa/tprINB4VkOfMmW2fW9BGdU5jLktLuYsdHk6CJjGq3CkMVLQzbVOsK/YrcbI/SpAy1RIRFx+05g/pfP2TUIuyNvtuNDmVrZj7oN1maBGKqgT8Bc0gvhrWcQFop1bQ470CGA1j58getQ4CUOcfifM1w84KIV6RcPsNjNhr/KAzp7i1Uh0eKmQNm0HdYYR55YPa0tB7hejQmBSM5CBvwCVF/L2XEKXTI+yy86NygDSN2smy7njUozkvZ0TMr8hQlV81EyNlR7xu3V/xhVLwsxOSOnMIKF4OKgGZqX/rgRvTgLOgLxpUVW5H9/CIiA+/58wywgxweUjP92e3n9V+TTABxYWpGeyQUO4/3Pk0UKttORbrfiQoXHcwY157RwVxlnw8c/qi3gImOJZg4IuYcrj/l5WI+hHXVwFKHbz4n4bzrIEE6LkrKGcmH4nigGOt+F09fq/6lv9ZFErA4Gc5I5G+Y0D68DKd1IySnHf+t0DSpGLPl+QqR2ShA7oUngxa7PHfPe707eD0TzJSQFHnpXcIgR/DEvi3insPbOlyFaH4qxHB4OYha/aaaRR/+BJNVa5fEJhSv/PjU4qbz9IMcXPic7o9D1F47y0PECAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgeAMA0GC2CGSAGG+mtQCQEQA4IUNABLCL+e6yGTUhz6nEk63l31iTWACl9ERGijDOo1A41jNcKtfT3t4UZajJAv4VdHTfEB25yCPQZ2S7nBTTOB+tUn0EQGUA3uuRDfLCOFimLANKpRdMYm66Y6wqhorJeQ4pwrYG5Zv7I3q1ttrlzV2A5NSi4Gn2iPQI/3VrnS5gJ3Vin2nY42sT6BSVB+uXQFmCq38SdrdTK6DLx4PQ2JMaPn2HW53XAkTsIGgh1j5GRepGFR0d62eOqPVdMhVDECUDcoPKK73qIbZXeCnfSpylY/URomgU6UcJ9/F/rVinAzLseSKBQnX/js9pwY4yuwMhjNDMFbaTJa9tUL4qvIlGAPw/9E5dOIW6eBcKsPPqV7lqip1XBzLY+Aau/fYsFGBWSTWklFz6+l0UpaqDi9LYH2pxj0ltL04DLVuAto3PXFynm2RqnZFkeq1qm9+5zGSq+bZi7OR+7gQ9MfmIuFNKctuFF0D/EXEtMKu1uGXEf81MvMCxTRN0G6CabPDM2boa/2fodSJlXtBqYtkRy7naS+a5cqsRr2ACLPcr6tuiM56BACnYdHbrCJ7smAeFui6exVC1UOwQiZcyrh4KlWw5yJOFATMkX9nwzG3DjvupatBvd55WMQDqucqBQ7cpmI2lfJC7GBgE69gjgWukeRNGkySlgqu9ZenivTsSgKEN+PFLb6Q5bfZ4vFEQ6I9IhW4YUgnnVQKWr4VLERsnG9oq5ryue7kiCbfBDDyP2KPUcxNGjwmlfDhpcsclzseKSrNMcWQpMJ4Dk+wavslmhsUIHwS6rtU45OIzPpJGzvUQkCDXIX3jMHiwbn9ck4v+F5GRuFQn2NTnxnS6ndykVMF5NIA9vwn2CrBuY0ZPH3phwNvgFIS4l6ltKBZNXFoFfi+vRRgnn/BOUmcItbfQzlkGVNEb9SILuqx8CNRVUXV4SxT+CZGWGF6mc/TRc90NBGHViskLZZZrG2ucFyswq8Sl2k09BymCHK/GQf5S8U368hbeysxRneVMh48jUznBMdsrqK0Hpz8rFAVfr3ewuFQEA1hvMJfJom/i4+jXMn9FSvbiLAXEn70/mGNpmOHC7L8EjFRzsA19/xLYrfc+rvcTLQyldNfkMXWiOn4ufKAC9B7kV0EZ+I2cAftlcltpEnDIBYdfHVuykrgY6KPpkHStUywxWv1zeeP6N6UBLEQR5IvB3ZIbyY4Vaj3aP+YqB3cM6kYeOuxBYJqSi9EXZQO2E7dAlJSIE7ZKjAIH1mWXM6eg0GGv8aXidJczQpxi+dDK/2KN4Y3nPyAqjdWOqAr3VJY3chOZ97kJ54ZQPiLvLsOYcD/7Hio4TDoHSGiTEKJ+s3oTLQhq2qMdzFqgrOSVXa5e7d2ztdLvwsrSQMEqssOt758x/PYP317bZ+K7TTqkVm4I8JM2j7sRNRvfxnso/uMTbA1oG/br8NyjMsSdqHSxjizkJpTsMhXHcziVuWQQzwgXrWUv8pwGRivV9mwS2AFqxYJQt1I/gyQOU4zC1suuoWGPPLhIxpM7mUgGtux15f9SkkFxNCBjiILTXU4uIG9aJ/Vg6DCkZIoXJ1xIuDicfUtlnndX1YCioK2KmMvt7msCDU5810hNHyKC8WQ+WwiWWfPsl3cPGyzK0cBV8rIJqcVTPgKVy8ubxHunTh7buRV6F0Q1kVdliJ1nqxCPpjXSjVrBHprqsBgigLUrmU5ETOJVWauggz4F3prVX3U8izUnZaDO7XSVF6lGZYu7tTIcO6mJRzo6zUkErVUstUYCdVrDGb6Pm2BcpVWmqy2Lea0+mDsP52oNbduxq4XRPczvrFsDMOJd8OZTG+XFW9fmfOtZcI//M1gvmDn+HieC6HVQGR5VOO8m6a+ulBjjnBxtBDEeK4T6f3TTdjNYO1taehDfdOLya5924SkYU4/WFPJ4VnyvZpuSetaGgFCjpCy5KvKrysv+ccmG3QhTvB0LgDv5W9uruXRLIkPjm5bYQR/ETTHh7oBCgeuYw+sWUGcSZuOTisnq284hAl7Ma6DxJgNc4Cxo83gsjcCpE4nXIZLq8/kh5GaflZ5JQyYdK8aIoRu1iqlLrQY2RWOO8i2NKaj3y1UCVAv/P3iBTtzbnERw8Qm3WYnu7ilYcmZem0J/H1l4NO3TXp63SPULxUCpnP7UdllpbCWsrE+4cy5RcpgfDuLlRyZOGCOTRsPanrkNTxoFIIlva83u+PQFUQXewI6Ca6A1RTD/aMDKg4bcE7FG1KoZ08uSXtfOG1xfcoEPzChHia2roHblLEa9NJiMRkGDYOjp7dAbbGbx0Sj3QzB+LDqLv+PV2MXlJob13Z7b5Fz4omCe4wGk23W78/4g/zojkuLVy8XWLs1f5ptsryGyMnwgTOC/npebdX4NLNGESYo5CUvRyVlgnz6qi7AQ2HMmZxvQoIXXYtpW1iLqK9yAYJBR0Bv4jEeZK0h/49B6FgTj5weaagmLq9lFiIJ9ciJ8h/9i5vrYqcXQk3MXfue0DLap5klXQzpmNCphr6Yu+YD154xBxOGACnofcJcML5nQVkntTpNbIZiI+sxxRwnmm3jto0LM0nVWCTuXqkk0DI6gNjxvxId1nSTUe2qxaka1acR+PdSjU0kptzOlxi2k4uluTJCQ2Pfj7xeC7ZRy+4oSWhPC8lMDx3aTsLK1hd1YWIr/PirBf5VLdK5sVVsQbHTmIXFyjlEcqOEcUzaTDBoe3TbdvSGaCS975txTIGOUl/nrNgQ8nHYMGIZE+/5Ne3/ShvlXUbwAr800cfYgvH8ymhBM4KO7o/XFmR1wiNBB6MGQcHIlqzec99AY5pJKJVNHAEya+R5KTMnSI4V2D9/pho0XTfyKMYCDPe7tqxm1kVtJn/UUEzJO10Vr1rEdy2hGcEAyky881tnQ19EbbT3w1DLaT4dJtwGmVdlftRDMW9uEXpA0TjRadDilsElboX1065IKiplpkrUK/3wFAlRyLcgt+xQ0tHAI0uz1jrbzooT9sVSA5cHrOxnmEXtKZDjd6sdeu8XPM9/2gycFRb9meksZtW4qu0TUucIPhVYgu/HZ1msrWyMyGPF+Cg3UnyZvZml/hmxJXfyKsoWlpLNpThvX0PU+zVSDzqML2QmmQqHYd8cTx+k9zJA+4rIvAyvrgU20moMiaL5OPkVk9L4NoiEsEMYTNpxkcundIz7O/8gFu40uU/ocm1WoJavNt8DLMHOtx2e8+DrAW45+g+V1EGZ7vcliZqlFOsHbw1DGtRd2x2eULrm38BPcAVfpF5dLFPOxuqOJSNiNKlxVz3Tks1sObXhygDsvKvEWcGmYCpkY32Deds+P3Mid7K+MzvDdMn8Wlz5fkbBFyNepSLocoXs/F+TL1WCL3GkEEiy8Y3HFVYrhmBF0BbA1iK5a4jLhaTGRBrJ8rWtHnH3BjAy9uX2HkLdpnn2SR4vKsJV1tebMKxfCZYzL3LJxw61mOfY9WFO8IrnAlgm+x+Qay2XwB7U/GHLrovxQwpRK/2T93ynC1y3ZPrEj2icYCMrFX93Q/Vw52VGg320i+ZWQi908uCoVMMpv0bYoVQzvO/51xDCsXukeWmqflNRrzPzqo8Z5FPnuA2HCJef38fb9vFkPWX2PSBEyiIFZzhoAC8lIuZ29mU05C/BxvG3dKJTvj2nlvSiUs+vG1B3qhW2g1AsMW7oJcGDYgZ2vohEz0v1DV4nvBs1KoJnTz/MA3s7Wo8GpkkfyvvlXvjiaPHjVP9X4LPuYIE7WFrMczwe+vgtSyA+RMdBYEuF92wjXbYrfrCena3Et7o1uP3Wg3mYzPJGst1rhZTgNAss2g3wivjX7BSbz3uZ5GzTJDx0G/W8agFicoGLPXfiHuZctX1rIglshxMfG/rGI3BgCxrWG5SHBjXObsqnXw/4zmzLq+9cnI9Cf3UDmGaREWz1VfYBwjatpCMuZhEA9l1zyoMnjjxdmDPc5/o5z2j6OsbCgJsxQmf+xxIN+iaZwTWZzVNpDIi09WSZt9QaZdng1kmSZmgJVDP3PGvPtLeAC1nzBiHQTYsOzdKgDD0bWD//a58Jo5RiUIQdRGnkG8NubBtNPe/JcfyXO5PeE7dChuihggT9aSA2T28VeC+Sal5KprqesN0MiswYxA3ln74b6LQZtnIRoZc3Aoaj82urToiBbk443sIDTFXlbzhIunfe6DNFzm0ZABQzhb/DdWiiBwKV+QWdju+4iC6KbLIcx9rrL1fDvqrW5eFJ3fBJRgG2fH59r/mPbD3CqnehunDubTZjovKixELzzbRT3KOIxeBT/tNdovuAl7A/kmywnmf0rilqAhMC4KfRkpEJvY3ogE81opsTgqhTeuGIw4AsOo6SD+SoScwWaTXYrgmuJngMXzeacPJkaaR2l5TKmeX786vHWaMm6qwBshVsFr47gW1JjyllAvYRXwXsYf4Noh39bcvHQLcVzVA3NPnKXkZC3as42hrzMlGWGmxMQejqGeBcB2hxYwL8R4xcn2Jxi2xFLWAc8PSZJPnNM5fokB6Dv1AT3J7uGJ8hrKFdbo1B1G92GpT+5j6YD9f836eud3FkMS+jnf1GTqv27RZ7rNjth301pS10wvhW8SKGS7Xo8/e433M6lNNdDv+iwN6HDrTfKdMph8By06f3vEDB3SIMRdVMRaiocOhwxbM3vtIhQ3KAfbViubT2vYYbCXQruY7CLc8Lq9zgwpso545INH3pIikvHVH5w2N+ncsMBBct41LnOGQF3F6D/L8jr+KonjDh7o5QOKUItyMc1VqMjz83desDy5RUqxT2G4JFmN+IgAiO1247tjMGUs4C5fgYUtYw3+pQP5NSXDWPfZbTd0s1t1U2oQjKvrQRHoPUtran4nr9YXxBpInxY2f0+9qttwY86mrLjYNHJfDuCh5CwEtlSDCOxA+CxGCPzjz1Fh/gqHhKZ5Y1MjyBM6KbPlKq8Cp8oM5N18KuW6f/3e0Eaa816CJ/nk+ZBclvt2gmcmStOCpr4Om9e3SssLL3b70jMKCvcguz5ruBC4AWVLm/JE9jWFbcYnjcIDp2p9CB4eacerXUpzs3b2G+6XcJ11S801lmuv0Vdq3DU6dINwtyUEd6BVHuKrqQopKM+Bnn2QowyDE7fZkJQMpzq5GxJ8/x2fI6umaCfrp2Sak4mZbGsbM96lcg5SPmLHB7wkaB2UQNImk0KEq6Z4APmPEeZ8ULnkzpxEuMq43+WmtHDd1Aj5qvMWQifxWg5QrE757ofOl92JKV8u8zsR588dcTKpXUtny1od+M4VaTQaAgiJbzBrO9Y8zZod7LbDfLd7E9PcY1E9BW9H9eEtfakW0RrL5BPeFnHCWWFTa1Z72KzW8Om08xsTS1Ivn/OBdPIJVDpWfeodQ8X5B+N8qNe1uVebG/FDVoIBwpYVtpijc3W6fNmc5+XXHceLy7hiC86hTkeDSrm9CTah2JHj2KziTxqNbQj4Qwoo2UR6wMZ3Pi3ekj7DwjNpfT8ruBQeenaA3hOD0ren/bzwL8JbwukLnd8IlhZU7nCKQZfWt7fj6EtFKHjSsFKoY2w9/GP7zQP9GHaibHkMUWylP2pLnlTJDhKeCvCzML6OnRnjZuY3OojJaaRgoOreeY7l0veGNh9mLaspdrERJ8G+tsQm8FjxZz+RI2rfoLR4EUkp0AjqnFm8TFmHYB69C5kEX3Obz7gJRng+y5axZ1O7nnsYr2A2rJFBC0E+LLr1f5uxgi0e0r+20o4K7Xm+BPWT3pFtqlagYIHzJ0V6sUDFdUT8tCe+IwoLjjdC6RxBSSxRsCVrX0HOGwa+ZlxG2I8dYuAuh9Lyje5uvhyuaGIc7yaOdqgFA2DaXALE/zRQh+kgKBY7Zr84sObyIfsgEfq1yCehumX1c6RDJ8Uf5gl4qam4xtpqaGPy8sbBo3N4pFwGRQ6QUgErlGVLW2Twh3y8EdvRBe1WizzWDjSSbi1u7BSyXtys62AFB2lCosh2iNUM4wMgNt5v3EVUiHlIb9Gzj/QGisFAMdbMA26ygNAEezmHHTaJn9mcBauL7y5m3mx0P4L6LckJEm0hmA++vksnYZSaHZVfSA9vssTSx4XUGI/3kjVmYi24RYfV6Igj/EyBZZJCay/8LE1FkaGtxjKyzwuVUYQwTLC2J3iBS5e4NDis5WX+W8v0BKm/M1g4SbIGSmZ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAACBQWHCApLjUO30vBXl9/sgsOm/rMPS7J/zCwg4HFp6hNZ+vfVt4xgnrLs+DvFGv9J4wZIP+BcVcTxB32T7wdM6lgO1SwTz/Bgi0cu31a3GQHC4XXqhSB6ENa1zSgzTnOVPmX9QXLfpKbvoimfzk7o7/gOo3uYRmfu5qvzxBUbkHaortWp6ZtGUla1TgkC+CAE0V8wRYng0OjKGrNbG3i8BNvOxsapeYEnrpNjUQ7qHkbhfwSh+JzUrJ+LwYZB4aZ6dbrEBB6sJDCfqsCnNB/qxzkTt0Fqn0elmpXi9YjzXpyUlktDGCM8kbvH9aghM9xVV/WOslEWMa9Rg8KCQnJsf7GqpsL5shhBD9SWV3coo2uwxqqBLFl0Ar0+ZiMWYnf6ycdvJMJXLOh35Fin0pN3/bRNRgY+jGzCBVZfOrZEOPUdafnYHTqJfiiWBt0T1WArNmT3iI5oJnYpbDNdPkj1B86NBrxf2CGGuK/3XjY1cUbmO4tRCcXMClcO+gj2XDE1qovPI6ZF3agOARhOy+0iLmXRNksMiMTz9KZ1Ry8ms2emGenTNDiDSfRG4F9j4lAL+zO0C0xf1+3SmCoxpwgyBzdLiF+/zKxSjFfkOCqwc54TTQgDqnd7NL6Om3/Fg+EjqJR93NlEif2LzdIjzxyTAWAhMitcsJ5HYJviyvqLEUpGW9uSmxxkQ==", + "q9A3XnQrxNd3GsHrlJMuDZmkC0Jy3IRz0VUbJDjjpMMwggkoAgEAAoICAQDJ+0fl6oFNNBRxF1DI71ulrJDUmlIoLqxCAwbO4gF6xi5KyEixjl1Sx+JRlp+79RMJcBsyJglr+2msg0HhWQ58yZbZ9b0EZ1TmMuS0u5ix0eToImMarcKQxUtDNtU6wr9itxsj9KkDLVEhEXH7TmD+l8/ZNQi7I2+240OZWtmPug3WZoEYqqBPwFzSC+GtZxAWinVtDjvQIYDWPnyB61DgJQ5x+J8zXDzgohXpFw+w2M2Gv8oDOnuLVSHR4qZA2bQd1hhHnlg9rS0HuF6NCYFIzkIG/AJUX8vZcQpdMj7LLzo3KANI3aybLueNSjOS9nRMyvyFCVXzUTI2VHvG7dX/GFUvCzE5I6cwgoXg4qAZmpf+uBG9OAs6AvGlRVbkf38IiID7/nzDLCDHB5SM/3Z7ef1X5NMAHFhakZ7JBQ7j/c+TRQq205Fut+JChcdzBjXntHBXGWfDxz+qLeAiY4lmDgi5hyuP+XlYj6EddXAUodvPifhvOsgQTouSsoZyYfieKAY634XT1+r/qW/1kUSsDgZzkjkb5jQPrwMp3UjJKcd/63QNKkYs+X5CpHZKEDuhSeDFrs8d897vTt4PRPMlJAUeeldwiBH8MS+LeKew9s6XIVofirEcHg5iFr9pppFH/4Ek1Vrl8QmFK/8+NTipvP0gxxc+Jzuj0PUXjvLQ8QIDAQABAoICAE/gvlhg223q0MLA08QDVR06F7Tcqu0VOC6K/+BFZQxm39vXRVhi0ulv/0MA7H7qtvKekULN5B/+N5Zv+lfiXmZfWvcrxeq96sd3DReksQhx17MuFj9wxGd4fwE/6Cfq6MFjZKpdkZGeFF2dhpQ6NQW6iAqAfMl1hDKxwgQd97htfhdyRk+4+tlPW+X9qOxou+YOL85HOMRg25De+WJv63YZcZMFHgCz06eKsluSMTRhKTbHFl8ce8toiY11swYmkqLSDpwUNRV/LTXGZi4kuipO17HnbAxuLjH6EH0257p3HPC/ND1W3XIppI0t8SOHsArGpAMA5Crry43M736GhIA+6rBmeuvwRx8RP+ycRVatZcTAs3KeQrS2ecpIEUzkQKwlnjCT0xtrLDn3tdIN+XxVgGMyCusV9Ac5A2xumtRPju6hdG0KWS7LH0lvE5s5NooTo0Z/5WnW4Nx8O20TaZvPJw36zXQiOFNGChxmYng4lWBhEtcDbyV01hqlkrIqx/jUemDTBj8+e1+3y1/Ko+XFNx/LEv16VB9xTkFTcJo+D9OTXEzBmpQrOP+FNJaytbdLhSnmDwW+BM5NpG4+7xIX4AlM9IfiUB7Q5/NpKApJ2TAFy9WaXzUCl0wXZRBgRpJ/ApM4mFGjLMVFxEBXUNF0ph53n0up5o/L5J32F3W5AoIBAQD+DHQLeICoMOib8dAD6Yh2tIy7ysQEn0PNXSxZqd81BvZ1IhMk18P4e90uSyYLMKTACvoRKXuuSQz2LyLMerFfgxKbjGcDl1sLVQ0g0L6IARD9fhFh6iYd2xuYK3b+d24I3BdZhY1Z7GouJPSmJkGllk+IiSJ5QJWSXu6ic21BCQBSG8U6DzJhh+GnrM+rLwAEMMqXm1x5dBRbXPIUhSyb20whrseZ9LaPnVDcIvrGIKfc7+R5MEPfo6eRhGIsu3vZEhEZEFAJt2WB29cQvkiPi6G1Aze3xWQ6UhNCTJPxfIJY4/UHoas+gvvscZKfffdzYkNDt73yNMbDC897KFonAoIBAQDLiHIh4kzJvTTVdgpPPGUjr7726/h+Gc/+AVovEB69P2QD0g6pDSGDQj9oGEtmBj7h9mO6q+V+1xb0pD3WXcPFes43AUeqde1OvHTDeq7BjV28U3ayVell4mZuwCJPLOHeJoSlhmnTFfRDmjOrfAO/yW56k+d9utUm7sE5SfXN4uDwBP80HuDJ3TLgP2icJW6hTdte+0zVxPZQkg/c+Um3fFXkhQJCv5jE0UCArKQaWrjvLbW8u6Lk5OPgK6EXDwQTW9GxB2PoYHbeq9Ovr4hExnJXddPUiFvVySlUK6Q1dP05hLpuDnfXx1i5wpd/q/OuOCkEkg9WVLMcXheNkGMnAoIBAHiOeFMpMASgkQHP0qLIo9WRAGftZO+8lHRUDsPN9Po4/6O+M898BKdaQC/DwZ31y3jGvLyALw0Z5Wi+HYljf+CPVrkx+4Ccxrut9Ljp1kC8IM/qj10jvErWu1WO6rz+99yEdSAqXFWb9xdGukJOTUDC/6MPUKixmUkIe73jgKkoGFreis1ugL3/uXnUbAgUGbHjZYBkXZHVIAPrK4XJXM3pV0t0oYvRsQCd6s1MXCzBOmeB/63y1YK/KrnHVL9diPwNssduEk1KFoV1Sa3MXqqf3HEFwd8XcOSsJi+EH4CtUT3Vj2W7toPHrL0beDTvlgnPS5RLEXxqxxev9xm+oGkCggEAf7TIcCxPJBH88acUBu2NRFwEhWhATdciY20zye3ia7o3phIKMtZTXcmWgVklDgoDMMLphnpPEEwjUjMvva6tpN5OP8Mk1XcTBGFJHlJ/DmEGHKF+C53OSahJv1n87RLrUfl3J2j0Q4c18ajynLm+nHrmQDFHgeNV1Qzf3nNisOGXY+KuwmRRhTeusXf3ymnORZXVfH5Pkp34M0vCelNMhr2UI0O1zG3tjCkDwPkSKpscCK70pkxRhC9+L+0QMaixVPg61UoezPKiA0trEoQgC488tVXwKR26CaUjsnWDniserBV06JNZbOHe8QeBCZG532nLituelfulOrprKt8a5wKCAQEAjW1WZdB94pJ8fzs2IWMKwgM2KDBIXiOD9PCzZ3CqNPYzUaXsw23hkztSoF6M2fxI68AD6Bc6vXP/wtoRuf8jrC3Y3Q+ctULoO7BFewWz7qzqRC8FsVKcZNhHVEEWAPAiVt4XniEUNQcPeA1I6pKipG12DsYfIqBlkjfY2QN2aiONEjKZzEtE45IuuDJ86sWlwiXopFOeOIJGMA7S8IzE8SLHLI+2+6CwYiC9Z33hSHqva3uNcSN/qvS3WlcQ2NNlCKIdUJO3/4gARawor7eL/OsLVdXzWK5XoBsolfg0RSw/wZOuuZwyqYC2yKkt3qtLvcb2wfrhdwMwkD4EzzscFQ==", + "MIIJYgIBADANBgtghkgBhvprUAkBEASCCUyr0DdedCvE13caweuUky4NmaQLQnLchHPRVRskOOOkwzCCCSgCAQACggIBAMn7R+XqgU00FHEXUMjvW6WskNSaUigurEIDBs7iAXrGLkrISLGOXVLH4lGWn7v1EwlwGzImCWv7aayDQeFZDnzJltn1vQRnVOYy5LS7mLHR5OgiYxqtwpDFS0M21TrCv2K3GyP0qQMtUSERcftOYP6Xz9k1CLsjb7bjQ5la2Y+6DdZmgRiqoE/AXNIL4a1nEBaKdW0OO9AhgNY+fIHrUOAlDnH4nzNcPOCiFekXD7DYzYa/ygM6e4tVIdHipkDZtB3WGEeeWD2tLQe4Xo0JgUjOQgb8AlRfy9lxCl0yPssvOjcoA0jdrJsu541KM5L2dEzK/IUJVfNRMjZUe8bt1f8YVS8LMTkjpzCCheDioBmal/64Eb04CzoC8aVFVuR/fwiIgPv+fMMsIMcHlIz/dnt5/Vfk0wAcWFqRnskFDuP9z5NFCrbTkW634kKFx3MGNee0cFcZZ8PHP6ot4CJjiWYOCLmHK4/5eViPoR11cBSh28+J+G86yBBOi5KyhnJh+J4oBjrfhdPX6v+pb/WRRKwOBnOSORvmNA+vAyndSMkpx3/rdA0qRiz5fkKkdkoQO6FJ4MWuzx3z3u9O3g9E8yUkBR56V3CIEfwxL4t4p7D2zpchWh+KsRweDmIWv2mmkUf/gSTVWuXxCYUr/z41OKm8/SDHFz4nO6PQ9ReO8tDxAgMBAAECggIAT+C+WGDbberQwsDTxANVHToXtNyq7RU4Lor/4EVlDGbf29dFWGLS6W//QwDsfuq28p6RQs3kH/43lm/6V+JeZl9a9yvF6r3qx3cNF6SxCHHXsy4WP3DEZ3h/AT/oJ+rowWNkql2RkZ4UXZ2GlDo1BbqICoB8yXWEMrHCBB33uG1+F3JGT7j62U9b5f2o7Gi75g4vzkc4xGDbkN75Ym/rdhlxkwUeALPTp4qyW5IxNGEpNscWXxx7y2iJjXWzBiaSotIOnBQ1FX8tNcZmLiS6Kk7XsedsDG4uMfoQfTbnuncc8L80PVbdcimkjS3xI4ewCsakAwDkKuvLjczvfoaEgD7qsGZ66/BHHxE/7JxFVq1lxMCzcp5CtLZ5ykgRTORArCWeMJPTG2ssOfe10g35fFWAYzIK6xX0BzkDbG6a1E+O7qF0bQpZLssfSW8Tmzk2ihOjRn/ladbg3Hw7bRNpm88nDfrNdCI4U0YKHGZieDiVYGES1wNvJXTWGqWSsirH+NR6YNMGPz57X7fLX8qj5cU3H8sS/XpUH3FOQVNwmj4P05NcTMGalCs4/4U0lrK1t0uFKeYPBb4Ezk2kbj7vEhfgCUz0h+JQHtDn82koCknZMAXL1ZpfNQKXTBdlEGBGkn8CkziYUaMsxUXEQFdQ0XSmHnefS6nmj8vknfYXdbkCggEBAP4MdAt4gKgw6Jvx0APpiHa0jLvKxASfQ81dLFmp3zUG9nUiEyTXw/h73S5LJgswpMAK+hEpe65JDPYvIsx6sV+DEpuMZwOXWwtVDSDQvogBEP1+EWHqJh3bG5grdv53bgjcF1mFjVnsai4k9KYmQaWWT4iJInlAlZJe7qJzbUEJAFIbxToPMmGH4aesz6svAAQwypebXHl0FFtc8hSFLJvbTCGux5n0to+dUNwi+sYgp9zv5HkwQ9+jp5GEYiy7e9kSERkQUAm3ZYHb1xC+SI+LobUDN7fFZDpSE0JMk/F8gljj9Qehqz6C++xxkp9993NiQ0O3vfI0xsMLz3soWicCggEBAMuIciHiTMm9NNV2Ck88ZSOvvvbr+H4Zz/4BWi8QHr0/ZAPSDqkNIYNCP2gYS2YGPuH2Y7qr5X7XFvSkPdZdw8V6zjcBR6p17U68dMN6rsGNXbxTdrJV6WXiZm7AIk8s4d4mhKWGadMV9EOaM6t8A7/JbnqT53261SbuwTlJ9c3i4PAE/zQe4MndMuA/aJwlbqFN2177TNXE9lCSD9z5Sbd8VeSFAkK/mMTRQICspBpauO8ttby7ouTk4+AroRcPBBNb0bEHY+hgdt6r06+viETGcld109SIW9XJKVQrpDV0/TmEum4Od9fHWLnCl3+r8644KQSSD1ZUsxxeF42QYycCggEAeI54UykwBKCRAc/Sosij1ZEAZ+1k77yUdFQOw830+jj/o74zz3wEp1pAL8PBnfXLeMa8vIAvDRnlaL4diWN/4I9WuTH7gJzGu630uOnWQLwgz+qPXSO8Sta7VY7qvP733IR1ICpcVZv3F0a6Qk5NQML/ow9QqLGZSQh7veOAqSgYWt6KzW6Avf+5edRsCBQZseNlgGRdkdUgA+srhclczelXS3Shi9GxAJ3qzUxcLME6Z4H/rfLVgr8qucdUv12I/A2yx24STUoWhXVJrcxeqp/ccQXB3xdw5KwmL4QfgK1RPdWPZbu2g8esvRt4NO+WCc9LlEsRfGrHF6/3Gb6gaQKCAQB/tMhwLE8kEfzxpxQG7Y1EXASFaEBN1yJjbTPJ7eJrujemEgoy1lNdyZaBWSUOCgMwwumGek8QTCNSMy+9rq2k3k4/wyTVdxMEYUkeUn8OYQYcoX4Lnc5JqEm/WfztEutR+XcnaPRDhzXxqPKcub6ceuZAMUeB41XVDN/ec2Kw4Zdj4q7CZFGFN66xd/fKac5FldV8fk+SnfgzS8J6U0yGvZQjQ7XMbe2MKQPA+RIqmxwIrvSmTFGEL34v7RAxqLFU+DrVSh7M8qIDS2sShCALjzy1VfApHboJpSOydYOeKx6sFXTok1ls4d7xB4EJkbnfacuK256V+6U6umsq3xrnAoIBAQCNbVZl0H3iknx/OzYhYwrCAzYoMEheI4P08LNncKo09jNRpezDbeGTO1KgXozZ/EjrwAPoFzq9c//C2hG5/yOsLdjdD5y1Qug7sEV7BbPurOpELwWxUpxk2EdUQRYA8CJW3heeIRQ1Bw94DUjqkqKkbXYOxh8ioGWSN9jZA3ZqI40SMpnMS0Tjki64MnzqxaXCJeikU544gkYwDtLwjMTxIscsj7b7oLBiIL1nfeFIeq9re41xI3+q9LdaVxDY02UIoh1Qk7f/iABFrCivt4v86wtV1fNYrlegGyiV+DRFLD/Bk665nDKpgLbIqS3eq0u9xvbB+uF3AzCQPgTPOxwV", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "tXT6cynHeqoh69tn5nqoFOhcZee0/GNnPrFw5k61k2puT2fp5WPvrBd8m+BOcJ1OicJb/nXggummYt6XRWOFfZjTkXffShOk+4sfvhhg/mi/BDXUt7W55YEnX20w2wmtf1M/RqFAVkQ0jeqEGfq+jQX3UDHZ/ucyz+YlGPNUhD5ccyVT5KKLFLrPcYulec+Szs5EVrskQW6M5Noix/h1sEDccbPPmCbk8AEfPGn0A/XQlTJYcEoYn3Dee1wnT486O8N9iighRRKj0F3E6O5LaXWmX3KDFwpJCsvcyKdvMfzJpyVNtYTn21cwhZW2qCy7yOUtX/SnSl+mEUuK4c+AcpFBN512Gp2VW4/ALg/UxdD5IpxJ+gVYH/ai9OphMcBByEqBMjlWy7et4qCNdtiuvMD2CA3CV7CbNRIN7/pnLRHuuOMmQa4ZHa1OkfieroVx6OMVkDFRd2V78VzSqEDhn1naiLcZkTPLaJicq5N++aHCGSXXpjYFT/CuY83/blsoL/p+fYWOTDxGmQ8pqj5yi5XBFUjW9V7AFgjTY0vPgnfuNU5mCrpwek3q7SbEnQgQ+HuLSz02ZJ0Iwd6N0dXwy0I3zZHEyRhNkPizYBiB6LtTG2+FyZLaY59Hit5qj+JeKV4VvPX+rEfdt7ifObygo8MIyshssUhvEgi2fFo00UsXVAEpL6B2VLifzsnsEuHdOQE/3K6TlhVqL7NY6zUTLvDLgrVnRsUatuQdD5ea1IlG7VJgvnmhyl6XAIE+HOmCmGtyD56GeKWrtm9lkJDL9vOYAY0xV1oU/YGJma5J5RIi9CR0JyqH6PdAiZ23Sa0pRP+D7RweXrXpEv7k5tNqprHRi/d+ltXAsI8IkzWmlLOMqOJGaVSEOfyz/wfnsehN0eVIOUeXovl+aXzrSPHStdfKtinRDDjNTOkaVfoiX09E2NOLLN5zIQf23ACz8zmIDawV/1IN+3kOT+UOSw0c6b+axnKvABGR81ewsQL6dY99mgL19cKY/7gQcxlWr/TwhUYKXzZs1xi/6cXlA8eKgGPvy7LgO+MQCGMOsGNP6DYyNNsaOmXon0449Xbee1vN7C3c3wlO8WAI8lcgAHb8qV1d3GhYs/mYeUXWTBSWS7mVHvU6ScJMVKEne1ryIl8evH7/LaDZkUUWC6O3Xh1F1Es6PxFWRufhwwEvL9Hk75h/xpNIvVLVmZcWxjiWRBpphNrNiof/27InuvFrE8nscCDVqipapY8i2uMrOcZbGAPcGJcd0k3IJNyKrmyFYx4rWg4c3NWZmv2fKqBgIUgtFT/Q5QDn2pN5kzQssUMBjisTQtFf5uKk4TyqFBXKIWgYGK113YPMEFBkKXlzEHjY6um6V9YQWMZ+Ns6x7M6uzGKjxmDW5U+bEU5YBTWxnlK6H2xHpXRqyVZiSPEbFOUSarDCpExVrptZb0clKxgV8fjoUZ7ouWbEC4z7l2hExwoLeFD7BgKORHLINbWwM+McnV5Rgn7B64xiru5zulLN54IxA63daScDmxz/KaWbFrA1ekdsvwIm96ESmz/+yYXmpgPeG2VRpbrS0eJvjb05SZZk96cO7MGznD6zYFm0wTE06E9/YOiMzBBGo01+PwXjR7gDzUnTTD6zXTGuFFX3I94jbhq9M+8yRgCGP2a4JNO0h6FY5YkY8yYt2BzeZVCvZ+Ba/Qwk0Yo1yZJriSK6CtQbC+xU/by+k1F2R1AM8O/uv7/693pGBCzq2olxneHXNQpCg3QfjDBPGss8Q1hLcRC+bHsg0YoCZgk+NlpOhSDkxu7q4ytPklRrXF+0VsBmfM0QV9rM4datNO9dJ5kqNvOViqfEgEARTJqRvWi9Tk6tdfCSGUCjB7TkKy00zYbhu1xgRXrI4bMz7UFT2tLyy9OTUwRHEoxfQkA3zSuD4u9vcrHYlxB3bQGkgCIkvOoccL/IPOrrazwUBRlyndNb4SmjCo0YVavCeq+UOUJZETzrJ6Go6dLGZ0P8WB+er9KFObTSXbOE7kWr+SSQAEWITg1Lc2ajMAbWwJuT0Y2kgneMFif06nwU1jokTMg51RGkUhX8RAiZe5p0Bd6jeONTUL4oM+9rqOd8yC3xbwxa5yqlXaySpVB9pSsZyt1RT/LhyZMIWGPHSdXhUY/eXwb1WFtrt5M8KxKTB+Yo4atGp00i9f6Cw1JCCZ0N1YdnBtJtiq3DWwOLYT44Z7mXYTxbsSbBRaKNQSqMFg7LZ+GrR2yEChSBpvFgyWi81MSnm9oVqxHYyYZ+ltI5wtTdxZthBQ2NHBh2B/X2I/f8gS6+sQTxs3389Cb5Dag09rGp1VOIcYCPr/ovRi7wohiNy6R+hoOrY/0P+U4dSSCR4GiB11bXjUcHm/Q4dPNiS0gPyqoIRV7L1dGA3E48zWVGhTCJZ2dq2jLnQq2vE7s1b9SS5mC2DJDMf+XARhfAvVS0ICBsaCrTOUs1QlhhiBx1iJKiyNEm17F5SUMDm0c6+kXLJtPHjFXOJu75/h3rMddvMJsb7o/+Ds7zTFAOGZ5g+94zEwtNu5R294mmzig59af4OmjslQVKqlfX53CuWcgQhriF2xy0+96P+g9USTE8a4tqYYzZ3L8/pTZKOjGsIG5GJ7vD7IQ9Kv7akEj6Po0KdIgWBII6rOJOkeZEzy5S5z3T2qcmUAPbKmU/rjMhCRPK+blWcLFvjcJpieVpgrXcLWYCk9q/0kumiGCwSql/RWRXfZOAjjjhUQttnqRm0rKMUGQSLuQah0goIf2h/y5eUwuErunJB+4Iu1qh17/REMoDYnY3ey9Ct0L0u5ENQl7hTiFyD0PsDFCwAMMLOENUdK14NFrekZRoiQicij/CPKmW22aVfM/Ac12W9CuMucLE1Ews4+ymUsGxgfDAJyuhrVd7Thj0zbuC39MM7zo7luMj7QU249L96jcQwcHX8/Esr4ImvXY8SD+GUYUrgfrd4/GbLYYo20MQN+Fcqt5nvfjCQ6iksFtEuKqOKQPFcC2wOV3UA7FVUNGE7BN1oS4LpeLaq0S1UIWZwpC3gqBZQhmh7N/F0C79ASvC3uoVMeHm4z5CNj49ddfnnNJS5sEcIQ/G2tFD18EBZ8VCZGHzrg88HtNpaxdAg9ljYgK3AnRb8RfSnPfHPq18O05yJafP+mneaxpisHSqokpRLn6N2YZbVLH4swHMMUXqI4/W8hxz6Uij3iTsS3qLGb+eZqBOBTlREF4l/ZCyXfDB/TQ60O7ZauFCDZmt0RFZLLUhIGgHk0G5C3OFIz/tCvqwcNfPKsyC4IORbInsLSZUn/nknWcwIYpqwKZeLQs9zn9Q39NR6IW1UOESNkA6eiA0WRJYixzcYzWV1bpyGx4kKsY+TtUSWSMziL6nU4a52hTtqW0JsjXDKgb+cmrjJqV1nE6FRdALB25ISrexn2fQvDyggQipjzIdslOtqk/Vsa6syFVKDLCNZ6mYZHbtHi7lBFa5UGdPp7btKSBNbVTGO7wX6YgezqCoNRVcsaqrY/S2i23ddEHpl1h8eoFeCGe23OcVg81ZcLvOYXk8A0WjhDGslMg2BluDQ+x4Y93FTSTDYLQznnFT4LJ47oV6UewmUx8dFIAyVBv5VRbtX9Fs/GGgz4x+rRPpHoZ6qp+wxa1ebfoyuOy8o+BYsXeo4az99aqkEjgiye8nA8M4/nPYJmjmvXaqBmDP644xdOEbYBBdBCujkGDxjWKD6vdFkpZgagx14UDtL5sjYokiK5fNcAn3BoChHshfpOEbSdfJ2c5s3UWgVr8bLhPeU4G01ba3vYwhGfWa/FAbdtlPPBhMesUaIx5Non1Ma2x1u5XBSVIo+kqfxfF7pe17mdpv3Jr/k9CnxIy5VHhEJ0uab2DMqXzVs9nPMP9w1NPSgNABUICG8JR2GLxenICv421+Ddjs1DvADyso+DB4hwIP07+LRMl8nrFq9PTHursiciPV/Ero9TXLbOOIPsyUf+EpZVZU4gqOfAXgJy/l5A83mihnSoHfOfa2dWXiCpoKyNXTsSBNX+6Ma1FjMf13M391yrjUtRmwo9ZVTQVY3zRjcCBCaDuPcSMl0jgV0XFwelQ8YKzJf1qk8uE1zVDptShMRW+CNAB+CkQihnqTMCJrLPBuX4rIsB6bCXSqwalDH+PZgLNY3LRhH+VOSwhPZWigzNkAdgEh61T4E2/gUPmPqFYD6DArg77Zuujiq6ZrzF6U03WukRPh1LD8I0/l5cQq1gSBmPCsxDax/DN5pWqUjp2p9EdnYZ7fi+m+G48KA5G1+g6hZXdEK6alEE9LARHnCFqBPn9E5qQ1k6X8Q/hmg/VLAowgzMYZtzE+VD5/mwEUsceIEPJLhQClg1eWa6DOfQxGnChzA4Sqjpm3rryxDsVj3KXLrQP9igT/+Tww8lTuVWEDDAgHjCNhmOnDKvz/5W+a4/25CgoMfOuDKwfG8NhCvVPZCQNT7pHIV3shzF8pbXV3ZnvGOFmzx3JaWXfrFkensHVtZ5CW1fGYd531zKaMj+6C+79XV7nju43mzWiQj5hKLD1XCB7xxkIVDFsbxYp2EbhHpiaU9ljdZ6kh1eV/Da4cpN9VmbQRVDpa9lYonu4OPBZ/mLSTSCD47Ox+OyouRY4btTnGC1WVOt0UYLGHzQxdwnWxpInMdJeiuc71obhV9TZ9/Cjum5TjfXqoAcvBWK+T17+lff3v7czuMmhXUoqzbd/VdrNO2GPrAAe15vFHf555uofJKJ+dvnadDh1eWX7PUYObXvkg2sE74dML9g+x0lRhuiFWbEelG3YkB1uyngIySNGSFXDzoA4BH2nG2r9lmTDFfnnBUyjoYOTTFZPZN61t5wIgRAGK5Z6SJ/4Xk3OZN9TUZ4QXHT6/Cx/qZ28CCsBDjxhbwei2JkPIqBMKGNFgIMYylPSA/VlDZwvQMZfjrpnl4WXQInl8D71R6AgDSKzkMuDH/CfXP2J8eL8VoAb4zKCTfSteb+GUPPYD4vcp9aqnsTP7iwTse90iiiYUoASPLdzLttzo2CmBs0+1Chd4m/5/RAzmjpi5Y2lkGqp6YKLwYNQGr/ot8uvz3xEJJ1Cq50KTVBBVSQORRXRhYhEp3EREI0MWU8J5/e3t+mxz5X+DsuhfswK2ZW/ca+ayAwmJ+tgUxwKc0Mg7Mb/hwsUr8qJDyUio7rkzUVFBfQJ/IYWDUmRyNZVdtJArRKhfCRgN1APOEjbDcEA3702NN7Poze+BgQffHuexuL3/OID27/AQQGT+eCLQ6WU0PqYXuiTlKZfTVbXPsFNSFfMfPJiXixoryqn5TsIPtKr0m6UCWQ/G1DlUjjJmlvUL8/1EiiCImdRJ1Fu5uCXhyk6zz/Y5uzk/nSA3x6q+FuH4AR5rt/JNhMiUhp6p7gWO34Uny5KFhgyNhNpKFnd2TLII/mIrxe5xRkLjwut9aAawTfLQAzcxwylYPry10tw4B63W9ERuuKJkbjQX8TnpaF2YqT4bSb9DixwatOc9fu/pYrmejMeUPUnlmZQMZlgwtynB5rR2k6zR90ZffWDTgf7qeObdRCfFZJrnMo3Pw0E3kvN6eImcfSSILv4rWE3v1bTI9ASmzGQxTF4n19388Qbf8kUxhaILjUT1Bo+160riV/FboVXOLQDE49sjWqm5+gzaceYVnneOFAj0+8bhvnIZo6rBb2gb/8CMzvGynPFwx/IcWGyHk7/6ZY5xPuVVcL0gV7DkwZMNMgDosrfUsZTFnAcAyKTYtv6EURC3DhRRQQMEqAKREwciZt7HWJTSCHqqcDlhAphUuBYMsLxEM79GEFoS3perYS5FFEFVvOsufVWr2KNnOqKmh8GE3Kac1jVPq4PwRR8COkD7oqlmklwmyU3kwnGiZan+qa6GF0TQALacR7iKU9BRlyhqfsSxrYvOIqjeAvH6Ks04U/Odp5SZQNUlcBpy23LumzxUqHEZZzASoMHdNVfvZGj7Hyu6h7XpXZFA+hW0oiEUNyuXASjIJvYBd0wTsbhsb0XpvR01P0jk5ug/ggYVp22BpHt6vVoKhociK1CNG7DwPdxaCoSb1nt093nkVv6gpWMqyA2lMQvPkAUdIpwOY+56PL7rwa56CqPPKREbRFZ4H1dznbXQM1J36PuLIS0wlbQccpTS+fsDBQw4cLK3v/FCWXzAxvj5/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAULEBEWHCUtCTbKtbpUNXQhyJrAGYJ8G8/g0cE6NUA7BeEk+Lgnu7FfWBEbeo3/kKG1/oolb10Jl/1S7bFIwpDPQtAmfmEUY1Yv71uWxns/IOoKvjlLilHukJORVisMwLOMcAtQH3IbhGMv17GsBxwkBVwd6fFUfQuYlcz05MY4LzSUwLP4eN4vJNt/ufg04MaciW1neQMvoD9ZeZfGWY3II3dSDj6C2jDfQEEVGHyBvTvarDdkujabfARPYgYILgWbJqWSC3b5ac6Z/vfG2ln9v2b6k8osa1BbG9GtS7k1qbQedw55k/IMML1QL8yz8AlLPoxDjCI+JXm0VYm/trTuenHcmZseJ6QfiWQD3HZwfi3CNNVAL2+2I/3DduOjKfZBr1afMhIki2ubkhF0hnRl6wz6GtBXrO8Gxv25kZPd9g+3/c1wXkAMa38oIaMHnFZPglH6ncDXudY1wqGNfiWahiM+rPFUhbQbRvsOiFNTzhaDlHbIp9B58hwgsHp+7qSiVceu8kIY/NGuHK62fpBQKNsiHTt1XeoGP3qgLXRaq0YN6tqw5OpxZCnr90vscuiEp4u28tnwKOd+YGYDi2WDYP4xKqIJtcXC/meVDvUJxXcp9iRhhBBZd937Xzv/GlxYMVdRLvm0zuIb66HVqK7LSuzUQq87hTYsGQEMZ7Ju2fpkjtvhQtk="), + new("id-MLDSA87-ECDSA-P521-SHA512", + CompositeMLDsaAlgorithm.MLDsa87WithECDsaP521, + "bufEib66fJEvWzrwgB7Kb3Ph95oZeSubF1MHXqTVpkItf2pm+M9LyaXPovmOWERWAuvZOOuyX3oGyQre5KEIvjaeI+Jb6WySDodCKF/zjc9izWX23LW/vEGAM8PlqHUGYNej/x52QO0kfOsZyuPXk2zadrLMIN0PRBWa0wtrX9W7RMrHga4wZSKKlKKaL/oBQf+FX+//MMwU4tOzat8Ftws785DZKkxt5mqzZwpuuFnfbGvvGrN/YUKxFoepAXUrBTTJYKNqvwAju5UjMhWBtfBdXR4Fbc4X85cIfK8AF2p02SEohbyngQA/TDUgj6gScUCDrHttPA/7bsAG5xXcaKFRLbW4Wkf+PduAS7bc3y6u8m6SLNgRUZXAnf8c3eE2n28wQ4S1ii73cqRMvIToKknQh26l+MU8EANgQC08QuWu3vf6NZLDx5u4Jrcd2LrHIJRQw2hC3TNKf0ieRPxp7LlmJlelUi3k4XGzxEWgOtbFkE1sF5GUj4DmYuqhlCA5+/oKNxG3mPnBLClQm1BshbxeXqvPWYmi4uzY6gg4p0WqCJs6iXulHJSCWi/0M9/iD1uKuqLHfztSKIiXjzlYynxGUNn/FZ4iwybP7+BrVUcVBKLfdfD6b9MqyhLv9Cg89xlADwocPgQybFn0j7N2TjHSWLaI3YNgBL/UjR62aWBDuch3HRSI5VrQyq3kY0Ap5umIzwJ4IgSF1ikwzGcCZIlA+tlBRI7t7kMGBvqRr1hq5tLfvzpRzHvbuiP9TuHy5Os0laJKz1jeK3As7GdTvU8tK/J1zdC+dPsGzoJwJyD6w+qquBKg2Q9zg6zWZmr8tUkQUXfhtXl17ZrFbqfB/GNk0MNoS1D591yTwolJCxfmFuzqdB8xnbJq6gjxmJyXGLR8BBL9/ap4nrChFNolgBA0FRAnDNkKmiPIwu34HFMpaSCY65NFgXG4gW4U6BxlDJyi5xXM3Ugvm61v7I77RJB0uHYEArA/M13qg7cfLZmI2TvbTfKcnerkySBYFt5Z3RzDV7o5ebKyIwI/YhZuf+ULBI9OHS7lwglkQ3mvTRT37lVCRrdSJEK81jSzQ9EVxpyfCFKrFebdj4Q7QXe5VawQAbO2Q2AM++JgBK772SpI4rTLB4dwnf9QcPu7BC0jcZ+oBaSC1CQW1ry4mRLcYJ6NtTvDw1f2E8ZQs4ZTdFyI4fggOnrArwGigpzHaAiOK/Ps9czvOWU2pp1gL92gLnByldWzXDQn/Q18FCfVQQSRbA8Moso+PecEhFfMxoL70MphV2HZsVKQjaKnaj4MCMOr4npsFO7DkeoAjnqUD5L2G43pcCxW8EXOPCRofNu0nXrb/s60bLoVcvskS81fhgpS6y63wwIg4BXMRuWN8TJDHpSO+yQDXhTJWtJbkXnmy/MMFh5dVmvcCUACVbRBYbtW8UYEYvwO3hgs/CJF6urFqg0+zO8NxvttlEU6t89w7SJ5i31xtvhpAvVvx9/b+F/WupuEf0j9FLLk6BvCnTKLeJkgE+O8R05jziU7bBs7KZ+zrmuLnPQOBl2vKZyYFF6GmImV9MxFkzb5W669vqt5x8kxyqKJpvPsIOcHOdG3q5CClSGAAeaY6R1Apsu/6BawRFgmFxofBbAVLzDEy/y7oczSnAd0WSuWkY1D5sOIgUGUsCLQaX6z0cQqDbmjfYseF8TMv+0YpQM1tQkuUK2/aKt6oe2aupihH/0d9rMExcE5z1Yne6sXhITrRiovQbgiRUnJMUIjF+xqqyOMjSXN4dzE/OSJjIwBzLIbWTX4kGzg05jj1EjG4Ka1wjiiek0Ya92Lx9onQSy+mSxzDwzQnKGbUWN2ZQBUCDn1/SzXM2z62GZk1sjMXovS2tpczANlyYaDqKPMk2BPIWP5e98jkDSjOp8UuIcmJMVPyMkZHh68uVQ04GZcKDXWQJiuV6TAr1mXsQyHY0c+nH+KR5wabLWrC3kdeMbX1ESXQD7WbgzMFx+v49Gyce3tcnGWDfTD4YyFCA0RyrAJMvqUqDi/vbrENNmnGoEkwqklX28uDVG/0aw4TQ3MmCzkRuN3O3l7jIkgfBp+4ji7U1vWXA5Gzbu/9Vo40RwvxGAVNG1Rc25dgYHP8PG7d+MCOuXUliASWY4oJ4cby7MjDeg9/VVSwVxVWMuM/BdGqsNAOf2WtpgldEFFBSm1tglo9pJSsxMgyAUzE+4gLO7stmk9NDrrXgNs+TAtUwOxt0nGOdFyd+5sJYaQnqK72cIKB33PH1nNwIGP6pzuu2gYUOlVfXSUiMadh4mXBylSJQwId1O6exm2/QzxxYdR8BDmmmAY732laDJPlXk3DmRNCErZLwkzkeYrjOzHbkA/iKOozph6BurNBVAtOSJkng2ySK1XVfYZA+vfB13kQSzc4H5WmBGJ15V7+QTqDFLOIZhYKs+QTALUCxixuD9rPZdyt6gIne7iiNv+yx95WNR8ldYIrSixLSLGaQxX4n50fCvZNoqRjLJ2HzhcRRb4I/WVTU5IcM3syNimgeTztOMSrQVwBgsulnZ5cpIDP5HOynyTtrw7tZUsqMp0EiAKHg6Pzr1cFiA/h4VIF9AMw8O9fqhD4Rkxxu0Zvhheu48YmeipD6fuQi7aWPnJey0KKZWQYrUy2o+qOd8HfbvgjSwD1QuAGjqinPWGvjr5E6RXW293meIY7DjCOUNRl3AvcFIdOg6FtM3bRpbUiVbAC/dhMn4I3zjAneXvqLUyMHEtjEitX4DYR+SoCgKGgQG8JwSf+MHydZCNsa2Suv+c8wk0RejuPbzVZwDcMw+8lFOKXL59HIZO0m47byEnknrhaqghn5PJ7ek8JliohvS9PKfb79ZUZyAjqcrRmNf9S1PP6sSXeZnFz7dxKwxm+n6EIDBOH4BW3tiw+qJ/rfA1W/Gc4rNaFBZF4m//eS1HKp1mLLXbRYV5ekhx79VF/H1acuNuN07nkDtKcoa5JAPlsB4LLvxws6jEboP4Vww4X63x2LVqBzqAWf5kdAE+ekQI9v70oqEp2ZK0mMbTEubAVEZ7b2RLUwokxkr7FZygjjjVr3Fa5VlDyyAePTG7RF8fO31VDeuGJMR1QLrhcQyuhiWQhjeaz/PFoS+4/3b/PtZTT+WMzotwQJnR1qbHOTSHRgQaMM4MHGnskSrqGAPauctBk5OveUuX8oArYselbilWPyyypczwuj+UUaQOdufAfplpYkrJAcvgn27TNW/4KSwoJNJ8VUo/pEYXM7+OH3zPbiT2F4uUU7COUsV/XIIgVkRfihHvJiNKsavKm9O+YNz+hyO2nlfzllaONeeJupbERdl7oVTxNtjpqbabnv4Xtmlei9J2xEvDYSRIdhw8YDxoydX2XiIkDUP/HNJAwe2LnfSWM2FzP7IqTyiBUu0nmzI6phsTVZfpcp46KUkY6MslgBCyu5qCcVJSwhXbmUzfUZEfcMEFBABv+LHZFdXj1Q2k/wmkilPm5IJGwdEZS08qGviCQgcaYjjL8NFHGw6siLkSfPvJw1kdY2p7AXKybMrIC71Au2XYNQApyc/639YRKuy8QnHXpQhWY5def7jvK321cLe3x0frUQxjc2Hl4dxdBP/lTWraocn0OGI88RQ8s/K8J9EMWg0zhw==", + "MIIegDCCC6ugAwIBAgIUDVZHFre0Js8/Eoci2e8Nw6lp+dMwDQYLYIZIAYb6a1AJAREwRjENMAsGA1UECgwESUVURjEOMAwGA1UECwwFTEFNUFMxJTAjBgNVBAMMHGlkLU1MRFNBODctRUNEU0EtUDUyMS1TSEE1MTIwHhcNMjUwNzIxMjMzMDA3WhcNMzUwNzIyMjMzMDA3WjBGMQ0wCwYDVQQKDARJRVRGMQ4wDAYDVQQLDAVMQU1QUzElMCMGA1UEAwwcaWQtTUxEU0E4Ny1FQ0RTQS1QNTIxLVNIQTUxMjCCCrkwDQYLYIZIAYb6a1AJAREDggqmAG7nxIm+unyRL1s68IAeym9z4feaGXkrmxdTB16k1aZCLX9qZvjPS8mlz6L5jlhEVgLr2Tjrsl96BskK3uShCL42niPiW+lskg6HQihf843PYs1l9ty1v7xBgDPD5ah1BmDXo/8edkDtJHzrGcrj15Ns2nayzCDdD0QVmtMLa1/Vu0TKx4GuMGUiipSimi/6AUH/hV/v/zDMFOLTs2rfBbcLO/OQ2SpMbeZqs2cKbrhZ32xr7xqzf2FCsRaHqQF1KwU0yWCjar8AI7uVIzIVgbXwXV0eBW3OF/OXCHyvABdqdNkhKIW8p4EAP0w1II+oEnFAg6x7bTwP+27ABucV3GihUS21uFpH/j3bgEu23N8urvJukizYEVGVwJ3/HN3hNp9vMEOEtYou93KkTLyE6CpJ0IdupfjFPBADYEAtPELlrt73+jWSw8ebuCa3Hdi6xyCUUMNoQt0zSn9InkT8aey5ZiZXpVIt5OFxs8RFoDrWxZBNbBeRlI+A5mLqoZQgOfv6CjcRt5j5wSwpUJtQbIW8Xl6rz1mJouLs2OoIOKdFqgibOol7pRyUglov9DPf4g9birqix387UiiIl485WMp8RlDZ/xWeIsMmz+/ga1VHFQSi33Xw+m/TKsoS7/QoPPcZQA8KHD4EMmxZ9I+zdk4x0li2iN2DYAS/1I0etmlgQ7nIdx0UiOVa0Mqt5GNAKebpiM8CeCIEhdYpMMxnAmSJQPrZQUSO7e5DBgb6ka9YaubS3786Ucx727oj/U7h8uTrNJWiSs9Y3itwLOxnU71PLSvydc3QvnT7Bs6CcCcg+sPqqrgSoNkPc4Os1mZq/LVJEFF34bV5de2axW6nwfxjZNDDaEtQ+fdck8KJSQsX5hbs6nQfMZ2yauoI8Ziclxi0fAQS/f2qeJ6woRTaJYAQNBUQJwzZCpojyMLt+BxTKWkgmOuTRYFxuIFuFOgcZQycoucVzN1IL5utb+yO+0SQdLh2BAKwPzNd6oO3Hy2ZiNk7203ynJ3q5MkgWBbeWd0cw1e6OXmysiMCP2IWbn/lCwSPTh0u5cIJZEN5r00U9+5VQka3UiRCvNY0s0PRFcacnwhSqxXm3Y+EO0F3uVWsEAGztkNgDPviYASu+9kqSOK0yweHcJ3/UHD7uwQtI3GfqAWkgtQkFta8uJkS3GCejbU7w8NX9hPGULOGU3RciOH4IDp6wK8BooKcx2gIjivz7PXM7zllNqadYC/doC5wcpXVs1w0J/0NfBQn1UEEkWwPDKLKPj3nBIRXzMaC+9DKYVdh2bFSkI2ip2o+DAjDq+J6bBTuw5HqAI56lA+S9huN6XAsVvBFzjwkaHzbtJ162/7OtGy6FXL7JEvNX4YKUusut8MCIOAVzEbljfEyQx6UjvskA14UyVrSW5F55svzDBYeXVZr3AlAAlW0QWG7VvFGBGL8Dt4YLPwiRerqxaoNPszvDcb7bZRFOrfPcO0ieYt9cbb4aQL1b8ff2/hf1rqbhH9I/RSy5Ogbwp0yi3iZIBPjvEdOY84lO2wbOymfs65ri5z0DgZdrymcmBRehpiJlfTMRZM2+Vuuvb6recfJMcqiiabz7CDnBznRt6uQgpUhgAHmmOkdQKbLv+gWsERYJhcaHwWwFS8wxMv8u6HM0pwHdFkrlpGNQ+bDiIFBlLAi0Gl+s9HEKg25o32LHhfEzL/tGKUDNbUJLlCtv2ireqHtmrqYoR/9HfazBMXBOc9WJ3urF4SE60YqL0G4IkVJyTFCIxfsaqsjjI0lzeHcxPzkiYyMAcyyG1k1+JBs4NOY49RIxuCmtcI4onpNGGvdi8faJ0Esvpkscw8M0Jyhm1FjdmUAVAg59f0s1zNs+thmZNbIzF6L0traXMwDZcmGg6ijzJNgTyFj+XvfI5A0ozqfFLiHJiTFT8jJGR4evLlUNOBmXCg11kCYrlekwK9Zl7EMh2NHPpx/ikecGmy1qwt5HXjG19REl0A+1m4MzBcfr+PRsnHt7XJxlg30w+GMhQgNEcqwCTL6lKg4v726xDTZpxqBJMKpJV9vLg1Rv9GsOE0NzJgs5Ebjdzt5e4yJIHwafuI4u1Nb1lwORs27v/VaONEcL8RgFTRtUXNuXYGBz/Dxu3fjAjrl1JYgElmOKCeHG8uzIw3oPf1VUsFcVVjLjPwXRqrDQDn9lraYJXRBRQUptbYJaPaSUrMTIMgFMxPuICzu7LZpPTQ6614DbPkwLVMDsbdJxjnRcnfubCWGkJ6iu9nCCgd9zx9ZzcCBj+qc7rtoGFDpVX10lIjGnYeJlwcpUiUMCHdTunsZtv0M8cWHUfAQ5ppgGO99pWgyT5V5Nw5kTQhK2S8JM5HmK4zsx25AP4ijqM6YegbqzQVQLTkiZJ4NskitV1X2GQPr3wdd5EEs3OB+VpgRideVe/kE6gxSziGYWCrPkEwC1AsYsbg/az2XcreoCJ3u4ojb/ssfeVjUfJXWCK0osS0ixmkMV+J+dHwr2TaKkYyydh84XEUW+CP1lU1OSHDN7MjYpoHk87TjEq0FcAYLLpZ2eXKSAz+Rzsp8k7a8O7WVLKjKdBIgCh4Oj869XBYgP4eFSBfQDMPDvX6oQ+EZMcbtGb4YXruPGJnoqQ+n7kIu2lj5yXstCimVkGK1MtqPqjnfB3274I0sA9ULgBo6opz1hr46+ROkV1tvd5niGOw4wjlDUZdwL3BSHToOhbTN20aW1IlWwAv3YTJ+CN84wJ3l76i1MjBxLYxIrV+A2EfkqAoChoEBvCcEn/jB8nWQjbGtkrr/nPMJNEXo7j281WcA3DMPvJRTily+fRyGTtJuO28hJ5J64WqoIZ+Tye3pPCZYqIb0vTyn2+/WVGcgI6nK0ZjX/UtTz+rEl3mZxc+3cSsMZvp+hCAwTh+AVt7YsPqif63wNVvxnOKzWhQWReJv/3ktRyqdZiy120WFeXpIce/VRfx9WnLjbjdO55A7SnKGuSQD5bAeCy78cLOoxG6D+FcMOF+t8di1agc6gFn+ZHQBPnpECPb+9KKhKdmStJjG0xLmwFRGe29kS1MKJMZK+xWcoI441a9xWuVZQ8sgHj0xu0RfHzt9VQ3rhiTEdUC64XEMroYlkIY3ms/zxaEvuP92/z7WU0/ljM6LcECZ0damxzk0h0YEGjDODBxp7JEq6hgD2rnLQZOTr3lLl/KAK2LHpW4pVj8ssqXM8Lo/lFGkDnbnwH6ZaWJKyQHL4J9u0zVv+CksKCTSfFVKP6RGFzO/jh98z24k9heLlFOwjlLFf1yCIFZEX4oR7yYjSrGrypvTvmDc/ocjtp5X85ZWjjXnibqWxEXZe6FU8TbY6am2m57+F7ZpXovSdsRLw2EkSHYcPGA8aMnV9l4iJA1D/xzSQMHti530ljNhcz+yKk8ogVLtJ5syOqYbE1WX6XKeOilJGOjLJYAQsruagnFSUsIV25lM31GRH3DBBQQAb/ix2RXV49UNpP8JpIpT5uSCRsHRGUtPKhr4gkIHGmI4y/DRRxsOrIi5Enz7ycNZHWNqewFysmzKyAu9QLtl2DUAKcnP+t/WESrsvEJx16UIVmOXXn+47yt9tXC3t8dH61EMY3Nh5eHcXQT/5U1q2qHJ9DhiPPEUPLPyvCfRDFoNM4ejEjAQMA4GA1UdDwEB/wQEAwIHgDANBgtghkgBhvprUAkBEQOCEr4AEB0Vby7yQTq++bd6FcSjRCGoCFM11hztEvkURAECKGEGYyhneez+tTvur41njeDacKGnby3J0WJIBoCrrYmIh9ijaLvi4ZWYRm2GhvxgqeiPSkbn9GPsWM3sjfC9OUca7Z2q9m2142tPlg1SKtw+z4KgUz+ZLltj+ZxksD3FtRK6y+5FAsK3SRq8B71KVypWGRhH9plmsE1rIUo1MJWa6blsGCMlFJhLDRukaEgGYXMwP4RTdGA3Rw0ZyOlA4nSLcSlxb2Ma3KjXlbbKJkD0SFKdE85sHVgImx6ZZvWPD/tjuNLlPapElTWytKnDOH5TL69WFdYVrbpsTJdslhqZXpbWiFmABdm4I9V1vQYNu/0/m2TB7my/uHO1eUm+IjopSk7BGyWGx4KeJj7dBhi7GQ1arqI/FPyqWMAUFvUZ047AMOCu+tUEjzmPAsDwqpc/nofWbpjQNxYW1XXsHVBbcnmHJfq8KYhzrBQ6YnWHGdkDE9CC423h5DuHiyvAAmafAasbxARAXjYI/lorr5btLHER7xONXhOaSegsG6PhokQIB32AB7gAXGELnpY07uU1/Mekttyo+O08xyh3l8jpMIwDv9W5Wyj63YAeiVR0UVLu18d11s0mj4YBYz01XCMOW0Q9vXRshDVZBd2yteVH2RxXQFT1L6d5KMAsKh09+gfdmjQ/dTUH97tdbM8k7raG1IdQcl5M6gvtpnHVQsBOHQVPYOEzYHrY+QjFUW1OL8L0g1FovqPRHJsXwT09tz9lfSTNqLVcNL48IzKqXqx2EC+gN2wn+jyIDIGyB+4sYmkdwuzuQKShZ3l9PPPIbfu7Xdcj3R7IY1yUc/Uj2xRpcmWJa4ilmMMQF4PHw+QfKnfIvTyCMDRPg/qMMubseSshe/DiaIfF/yZ8JI+KXt6U4TvEONBCPsO3ia766xpueRqe5m2aEHfgYe2fWp91Czn6UcHJrawhYJwB+z3XpU+nxuXqgvtgZIXhGlsXe8eeVJ/AdaWBr+K4n8oTiJ7wlD/qkRZvO/Sw+qDNS+TY3guvWLVNzMa6sSYP4CLkLknUU2aLGaQ4GGJQnVWUqGpXeEaNjy1/iQmrFYf7KrFVFxgq/mDZclqqzwXDBZgozwtTW29ffx7uFkmuXImSGB1HVgWs9TQ7H1Ot/VJLoMfCM6g6EQU1qM7XE1EMTHCHJHmAETeh9qXsQD98JgTUlpx433QhQNO6KLNSEIn4pdu4D+EeZYbwx7YVGiNZ6RL6mEUkriLuqsrhxnXpWKOC0yw41gKFV5FP/973Ekemf4troBsg+L4Gsqry/UBQ3Mc9dgNkRX9m0aooZlnRTPR/lKR8yuibOpILdeLalmlM0y4882tqJOg9XgsJHtG/ZZFWRx1UV9Nkp0cV3OzaVPVR8aHvtuoUrNLeinlvyorFE8CjbIp9/xEmm+yJMV+0X7d5XAX2fh+VohgfDVHvQUBaWRh2xaQpfbjTwcu0SbEhXmaZ+dlS8vmaZ3QCVV2mv3YLQf865OnTeCczuoabhcF7Ezsu9PrdzN9g3RbggrxwjZfFrBBVyuZ2jpsxmYEXGj2XNSr+3bXAN6cG7gPwfMMI81CaFuF0gg/celnFaP5CQ6e/Ldblm7xEkfcWje2G1T8G9zp25JtykYUY8k3R8vVOTOs0eM/cQewG1L2TetLrcaKkURHlom+75uy4tppLUljw60j1ieiHq6KKxhXQKyfIytWktjTjHbZ6o8JfRJDzDdyDyP+y2Op7kqupJZ7MOlkTRlJN1ePTVt0tJoecPcb/4J1huN5yxzlsE/mN59HYxlvANl9Au8ahQzklq2iJsdqKvTYcnmbGqufjaFd3wbXBPcfDF5CFX7nQLEbgjsmgUlXiae2CDU+bzlLeiQq2+t5i7T4Tfjmo9EbKGm6e/IFN7ADzNBQ2mARysWORQCD3r6aFoHGVS01GiW0BZQHXF+Nj3hyToAMNPLSpXWf0UwCqCxi1cd01iUHHgeKWfk5FzHAPfX7WcheBXpA6sZ3I4yrWHE/pifr7lsiTwnfs0eyzPU5lBYP3jlTragtAURwjRQCYDG2E/gPWwBXWXnHpT4p6IX8dMpYt0PqVF1d4FwFddQodHcXacIIKGy7v/PGowRxc2KLf3xZL8nav/uPIx1OfEo8L9/xTsrbmFw1sPoD8UtmCW/l/UakWDtp6AEqaiZo7PYLNa4JcOcXnDkbnA5ePShuxTNlgCJ26HaDZMaMlPeBHacT1kx8lYvyA3xM5UHJk/QHtJpIzU5l36R2BtlnvDBOsgStfCgqV+zNYBEMm/13FJP5ybbXep9CszFfogwqDpPzCFBlydS7XqBGNn+SXI7jbWpTNbY80f6oppUrdgOrvusI7BJY/+HdqGXGTq/ApSjtadBK+F/RHSKL/SMvC9eprjXvJJ41dRdlLONmqfUvWxeIjY473Zpapz2173shkzrr3hcEbmB196qTypJv4TIqlxCx7Oy8sat8v76t+Mtc4VqVwVjX1jtjyz/jUWv96L5RoqbO1924uLtrLdry3QPjWSp28BVK+6UahVZ9nU7L7Rqkeo0HFn4MGVu1XZNmVGQ/l9e7Hs46fqvjlwkdNN2EzE+6u2qeAtmHghx3090JjDWZ8BTZ3+qvbKXAOeXaRHNX36jMyOROgXjln3G2eBHwlHyytMJfRjcqsAhCpnbiaGmJvoDGZzezHPh13fty5GT455QxWZ7ErPLSLSnpcUEjNHkwRyXLLB5noLrsOubzlEHP5SHafz84Kf99J1v5yS0ch6l/pgiFQ2T09Hp6dDWD6C+pFuz2cEYOrcFKgSOKuuJ16RGTMe44/4lvCN8gq/Z8al2Zlfe1Its42rULTnQS46MGDucPMjiYG7+0nBk+uwT0PkZlFiTkUKLg/hYDQdaZ1Idl9UTrahtq3+wRiG+AY7BbQq0Tnael/8hgeS1rqyuaVjPRT1nZOGKAxX7VhVnccZ/2xo5Vor3uezB86whQtAw/IoShcHRANr/hVWQWYnT0Cgx5ey/eaROn8qN1hz6XPtoZIeA0hWOoy28y6VRkq8GjByDXO/Dymo83XyGvKtlnYp9cvkEDozP/CP9HCvNCy9FHNpGX+mqX3oaF/6LvOLoCn3t1GHzcjKNW4FTK4AGqiIzZEyRkdBH1H5QcWioOvw59aNfYTwoPMHbi2srKFcYeTKzmyngJOULS9EF53XY5z8ENUYNwFlEIEoImZ8jp9BJIDqWr1Z+OW84NWiSYie33tvpyYvLKkWOIo7Dh05lIJSiZOH1Mso7uuZjbW5rx8xA4/ux5dVPx6DM0NShfR5mjKnyT/vJZLrs2FNLwkFuTNColbX7xa7FpdZsE8diY/NGUZek0VPRXj18++PS7tzqI46UXgitc5AFdI1YrEYhriFP3UZijYYP0Be8LSGQ7xCHU1C8lgHakshD/9qx+rqUjvUylgNyzWPuhvwplHhgw3deQJcZo/VtohJyzZKKKHbLlLAHxYU7F56XnzBKwQemB9toPBaNMqC4+1fqIYFtDIzR+d3F0aUcay4dUmvCo7v1yWOnniFMdFIE+JkWHKdQw6tyaY/1B7Q/YNwuPcF9Uwcixoo/uL0OGiYM6UyT/aetTzEXBSxcPfwSF6O62tqh1bVI83jJ4KR/M7YmRxBS/CVeQo8GNA1qTM6joQDlU41ShOULvCSHC+otFXkaJzFKQkIiJmqErAb7kqkozYbBkltJXAcnWbM+WxZvbubyG1/KNEIllwzFwTSd7T0T1vk5ZsBg8GNZmlu0nX7ZrbLCRHxp+S39pN2cxMH2t4YwFE6+/FhPFAP37iqNPdCYpjKS8/ZF7btoONPN8baUYBNFV3gEUb58hCRF9n5ewrfBFBZY/boFfoCehHA99Hk/7nZ4UqoJQgIa/slYbg2YoqSmYEEBBUjL3wAV6CelDmta09FRIp7Icw8L0QerNgSAyTjCWKroYqA9DvfLJo3J6sNxZxhTbRUZyui1NHZzDt/O4RXGxZSgm+a79vpAQt8I4FXY3/pML1C7NJciTDmVfSrmKxKhtcGF7fI31rFRwGAdDe+oMEca7LXICEuOgQVa9AwzPndmm57NR2ENQBVvQHXF/WZEOiEThWcJtgTDlV7Wv7t7YjX7WQQ8sPAgXEhCKQDhs6WJn3mHmXoY9PJUG9ju5bSZ4msx+uxdYOg90yeGVBiN3RIOI88NInL7j+TrXdvpbCjbBTpvs7BIK2jsf9hkathLiUP/bKiOXBZ06IvDElMRaXsfg2uSyNLGSj6M4P3bB1mrRuyVOV7m4mSVZzM+rS9Yyf98zYdzdpvDYciwPMMahDGOHnkBp/GL5IJgQzCfDnCCLtqFQJzjcTmS7YTU9VJUe8MyKBrq8MP7h5GNYxIXte39nVQDip8nTBSRxKTQJD65xSNbGKJqvVUpcBotFkZ2/hiZ+vGCSAfBy7eX7KygRnZe8387WqMaIIzB9sFvS76tGUzfe8AJi0zVg2AdJnOANt8rRZ2IREc/i3sEerATiMJy7ONF3xrFQU5zWeMovLLs6S4NXQk6UpE9ik+iYPlHhYQr30Yy1Gv4mnlcVZl0xBxXRn3I7IUHL+4aliuwusb4xebEFW0VSLfWHFpCcikZcg4KyvWi2NZ0szSq3ZN4drEYxLgQ3DossDxA9DD4AIV3L6GN5kXkKXHg8bbdxG/xia/npB0+F63rirLIGxTrldj+cQribYHBSdr+p6gq3vYKB9TAjdoqGsGS0UKO/DMQMoZkixDf4No9qZQ5j1Bppq9/KbQOQKi0CB5enMo2OkJDy6A6vEzwNuvWlaTsmfDFMC9pwqbe4nNJOE+3gYFsqga0ytr+ObA1XUD9WlvfP8Q1IBVyQ862kppLuQqtms4rJYMP13KdL54A7v657cPJ/u8Hs1oJQRPsv6IDDOCcLqEZHCTvlQwMIPttRG1VT4cfJTE0duhVCeUDAHnmjOTFZrCpm50jT6sUWbFoe/ZlBWYzQFGUp+CclCRufGbU+msUlpvMpAVPgw8kRdtq08P+zyNAwWCD+rO6JcH/tt/HvO1mpK/a+T/DhTHFzI9ERhOTJmb30enFiXBjxz7YyQI8I3DbSmVBsXwska/2rQCJRInkzy1c0XkSYN/HDrQevI0KX9IKH/JCJ+0H2V/jUaGsei4+TcQyfeTf/PLn0H+ngxA1YsjHGjDCRoc3gFJerOgZwYKO/sOAkQ5r3AwWA+4R5VtEhrxp6ubTVGh5EZmrjvNwiPhGZ8YDGN33Sm4+6sRorNERfNiLMvffIsCYClb2/81ckfCyygl9wqad9+13aZe4cLTKmoVUZgLddRvzwSf7J1n5Os4S/QQjZ+iUbcOMzOy0daxukTl304WF5Qkuupw/86UFWWCIcy44a4Dd4/UUTgLXVF/0dL3s0LUlEsYiUZCSixIwZiA+jh8UEQQiW3BXhGBT6pYvM8Wf+bly5rVKj1zWMICUUhxvT6IonF0sRA5ybx/3Ib9PWu7EKCA+eHm6D2Z7i4pFF1ixbu4D92nK0YuP9QmABT+xevPqR/kGkqqdCqNYbheut3E7Iq2QGGdN4/lKA47uoDT5UG9jj3TUPkh416ADSI0KZV2HvEfnvVwy9ASApo8UOsKQ0MMEUM8kkkeRuFyjmMfd+h/s/Nj9HE0AteFpgxZy2mSxYSMqdjhTLUag7ppg3Ec5omWzZDpJ2cSZlaSqsJKw4mNmw4PCu1+ts2p9jTLpru8n0SvLYHO5r1Cxc28wDYGB9m8/QrYYHbDe2YV16KutiuVt81kydTiwyLdcrkIoZ0Nm/Y7iHqnv78x8BAWieGiDXkKOogOfzeejZgX0QiwWZgrp+7qP+PccsWc4ETJ8BqoemGIdOeOZZ9R7ZMKWeYK6C6fk6ZMD2qUrI8yeR+DalKWOiBBIj/p16wwj+9fTN2+wnj1h1wBaMSSBPjdYFrmntsZMKpBybnb0lddpd77JspZJD9aH1k4U6YfFHjgbow6zScLIn2eTOUMsT8GIoCql+zkV/dp0ddBt2D+yxF6fK1vAsO3QY+fJor96Xx42s8WpJ1sCq03Ek0FVfzfNZOHOALDZBr/HA4gc3qs/PYNf5Nysxje3mTIwcSzcBxrqKqHBT/wgswfoGXo7HuECxqh979DkFJVI+90d/o8AMgTZC55fT1EjVdeLvGzgEfP2mFmcLMBiUmWG2KjuEFLmOsssDX6PkAAAAAAAAAAAAAAAgOGCAnLzdAMIGHAkIA6J9cTzs1AjITBS0aSxSKVEiv3tRCWXzlpTsiCcu/Lrqf4aLJ6ABim6vqapMG/4lUZWBY8ZISrGIe3m3gt8ZCJGQCQRTOSt/+0Jmqm6Ft91tUgWCqetOderXcMFIJAkHsIuLEQ5U9NXaZIyIv1At3Lz1Y6xbqLDMv5txKCpc53OM9ubxX", + "v8eVZ+zV4Xt4v75b1Lw/dEpcCZfZc9b7fBEVqOew15kwgdwCAQEEQgCZbJAY2EtmMsQxz5I7Y8mm/W7qponemO3YedJD39E90eeCNUT+vOpYQlGay0LYfSZehak+ByOvFg64sChEPEE0naAHBgUrgQQAI6GBiQOBhgAEAG/4sdkV1ePVDaT/CaSKU+bkgkbB0RlLTyoa+IJCBxpiOMvw0UcbDqyIuRJ8+8nDWR1jansBcrJsysgLvUC7Zdg1ACnJz/rf1hEq7LxCcdelCFZjl15/uO8rfbVwt7fHR+tRDGNzYeXh3F0E/+VNatqhyfQ4YjzxFDyz8rwn0QxaDTOH", + "MIIBFAIBADANBgtghkgBhvprUAkBEQSB/7/HlWfs1eF7eL++W9S8P3RKXAmX2XPW+3wRFajnsNeZMIHcAgEBBEIAmWyQGNhLZjLEMc+SO2PJpv1u6qaJ3pjt2HnSQ9/RPdHngjVE/rzqWEJRmstC2H0mXoWpPgcjrxYOuLAoRDxBNJ2gBwYFK4EEACOhgYkDgYYABABv+LHZFdXj1Q2k/wmkilPm5IJGwdEZS08qGviCQgcaYjjL8NFHGw6siLkSfPvJw1kdY2p7AXKybMrIC71Au2XYNQApyc/639YRKuy8QnHXpQhWY5def7jvK321cLe3x0frUQxjc2Hl4dxdBP/lTWraocn0OGI88RQ8s/K8J9EMWg0zhw==", + "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=", + "x5mRaJCc7puSvynut7d6Cc8I8QjfDR04hirmwHOkyUK+2z42T5SJ29s/98KLV2lHDmTtLJlZK7i9SJ+FwmAqBrPiLRWA9au3H4tE6ERW1azQPC0JqtQc8Q+j26PcWUp5X4G4U+DRr4kpQxHG008Zqo/K2rpMSJiUo5XsZYahDUL/BsXPuQUD5AJTZJL8YixAa3b6zLVv0kcHJGVTR+P27OdBqIOY9XRfDeXmyKE99TDMKAvUzMNu0fU61UeV7M8gKzUx9+nwC0b+h2xarvpd3YSCNYcy6zkvw+bRqvpBs/L9NERTlb0Q2oVaclkAOdszZjrsD8uNdZUx6w+Oyv1PA1LVVgbtVqY1A5uHRqle0z2JhTN1G5abr99lOTp5CmtKzmTnXf28OOq1hjFNrrhTEyMZ5pnh4Z/pOw9axGfM7FHee5lkWnmPA6SPrizQ3ECAfxXd1OmxlmIGKyfBoy5ORZCbTYiN3E8qzkAw5NTuPSGCVNZOoT2oqfEbS+h+RTTYiD0zkwc3TxsrJzeG11DzcryUfoXkuIzI1VHViAb4bx8HJ/ewQDiimdjKXp03LjmDIFF8YbQh8Lr/bb3ggiVKahBKvtkQd/aJCoUqmYaNjRgljmv6Jyh7WAEuaIYoLWC9wk5FjcFIoUm7q+c9SXKtI9gQlt2lwWnon8FpUzYK435Rw20IjcrUpeUtWDAZDBkMa6FxcZ3HblfOksYjuDyiSHaSHP0jfI9OiXbr3oyhiUjNCWBpO274SySu4wantr4b6hYrwtxLKQNehx3E3lesuQEAOCfXsrT+UP7bF2gb8RqgNy88awT2O+wzhAFPNqZ24SRuFTd64VG/8Gh9Gb28xppEOKHallHp2qx9RmV4yJZTzaf1EQ3sAlQjm4xsnV/YfOTXAkiqWSxu1dl/l750mlFP5zvb+aSOrmWb/K3IT1asnucvqrkMmpS7Iu3vLDUh0auiLTi/1soSutBsOzBfboy2SccvdeckxtmGGiZtY3zkk+5FsDD15V1Y+Bo8kcwAUql1YjvB3xyD9xyA/wmVMPznxYwNgvF7mMNw+NIun0QePOpJuu/gHxvaxAMiw0Qw7w5FlPz8HwVwT8y0gIw6InoTr8yQzifI76ry87qx/k3TGIa9dVV2thA2NR70NYzGkoyU9VFIq9ZjJ0952dtqrxPq/1r+PK9X5u3OyPwMS2NwfnCHuyG/N6sVERNOCdBIgxM05K2Ld7NUnjdQijithEAu3FWwo/t6WV/cXVX5XvTSvBJdDdlhZiQ2epzYz3lmJGI71oTD+/suMKa5CSSZv1l5hh2o8+mTwaBUBpnJUptiSgKMSzxI1OZRZ6wH3NkOa4jSMHLO8iwySJhET/EPrHhtkgIp9AVaP8Q2hU2I1IoIszWYgLvfJJ3Cy+rEdrmxzqm9lspfe5wkm0iMlgvN7I4aGjq0l+t7utIPMiDn4TPvLZZcOE+QmkZzMyQt+Vu8Nf58frVU/4ccfqC8e1BUQHYy0Z/oeRwgwDfa5w5YAwZMz/t4IAOnUnIogRsToJ7HCxarpdQVPdENwIAChuRzrbagbVttYK1UHMd+95htLpC7sP77j6i7y7tB9jVLqDvLstQ3CL1ui6+AvWVX6e7LOktQDjcJYsnZP1FXdU51nA9z/4qeHoBlj+FMuGmRRoH9j0itapq4NEInEmXzgD5Cnx1MYy3FWY1TSXVnOkwJuyHgcUhvAH/70DpriSjzDB3/UWbQlVL2nxQL1iBQkvZTM8tD3Og2ysiihkPY8hXRBKMTDxQZ3wzpU4Ik8o8GdSvhKiVC+LYVKZPs/glAsvqXsuCrrV312Vbkw+BeNpG2D4Nw9H8I2d981Go/ULZmLPRBpWsbm2tsXrS7CHWT8ppLJhjnDF5J+iWY2wGxJhaXZzeOIaKrf7CiYxlM5+SwY5WJu1T1Sc5zQ9r93rDMr1ReCKYzhugvj9SAyHzEFrGjEejolBJWm/7rTNaPUsA0m7CYYm7bLqIsT4sBYKWB1/GrM5I7UBVjFCePWeIIrbgIWLPbcTt7EKmB+l2zAAH68nzvBXph0/qAOXZmMpBy17x3BGYfUsFs3z6lfINKW27i1yL9RMfBoR05olmpyCU03gJm4SJ7wF+OQzpCVHbQWuV620yEy+PUE9x/RZ9AdujcHuMrd0Ob5hmeeva1zvcuVN8s7mZFznc1oTHfol30I1x+vMKO3pj3MxmywRn9m7huhhBfYCd/fZ0A+VoRK0pSD9/apsSggjK33vH/31Q8kEL1k3m96Qd1mka7ZJNvHUxvYYRyOrzU23Uv0w1/KAm8414tqS/bGwPO6PDEkttPkS83gANmnl13uB7h63bhwFrfJtlM/zeS8R6P84ksVZRaLKqj8jLteDfJfTKj7fEgIHT4VTVyo1coRt2/XV+EGkwHAdS28Wx0r6y+6vrMstAjuaaPmqMF02B3Lmm0RChAm604qxaa3ljXOOIZmmqKsAXUIFYipf2Jm9fN71Xn6/Bi3KsBygpic6SLdiBwmWnOg8kpdZXD/W8gglC6LvELo7Pvxu3yxebAVriGQVleqklywo/DSwdUNuLfoA+Ut0cNqhHn7xUpHmrx5zBai4/K3YIHdyCKsp0Mcaco7KPMPYzJKv7/xrLMBVwF03pkkCx4UQYMCEsIm10dtf/JVe0Gx5CyvZuk/nK1/6Lpx/Y9wKWuzbjfcXjO6r0GQf1RgJv7sN90u1bE1L547EdAE0tDBUxJmOIKykB76GINgFlFb3JB73V4VhgcF8ruqJFj1D91ReaAFdGng/EkOk3cqNllKOO3v/fHRFCvxr8iqIjiqKVvXjcQwg0MqIm50fjHh/01w4RqBRUY/wpEWRee8/MK89pBm/GKFWJIRN+qmBlYuP7/QcDi3G/jAivULRn6XXwxPOGD6L7VLvoyWpMMjt2BHkcSBNV7nAJP93lHfDNYIl/BxgXO89XGXoSSE9XnhUUNA2KzXGatqHlpKkdhdf/YPpIOtn6F3xS0/6oECxmDCxN0xvwsFCkRcdzoXet8KHvBH/W4YzMoGt/tv4QWgK54wBEx5y3gg4Fhq3EaV/Y9fRMbpkCajD5ofq9MEfQKh8I9fHGw6W8UUVyuUTcw159Jyup5odFLOHI8g1L0aRdZItS6+ABoAb7495+uolMjAg8lkDRLnr5I60/NtfUkhb7kl0TM4q+1NuOe+HJfUcSFVwOXkrwE8J8DgctBtKRtf6RQjWTXGR+z1MDTTGutLuFljpmMbmj7pigtOrs2damRL7DLvNBmoT69JkqmJnXOAGUJZ0Qj21xnB68jqVmV6rsMmkiWBpmmCoaiyTrkS1nZId48WuYYgXZ0OIiOWXp8TIkVbNPdTcKPD6PD+j0945byaV54a6wyXt5mcm4rzd7u14zJTdQNrj1JwXwEa14kmjj3nQt8pxqrC613HOCubpBC7GU/AV39iBrxYS/MrhjgIxzMUmtRUtUtq3KsoOKGlN6qKxxNVvqGYrSrfthGsn3k8YJJvZtr+stTJRjlnieys+wqFe5QRNMkFs3MhClKuG265xAlymLtwY6VvzX7q3nWeDGcl3TfqNaRZAd5FAs3a8cinFNoSwaEe5P8jtKMu7O/32RSVS08HHjoYV4l+5CmrFmR4QeI83o/4WsaKOZGosgoszRhGNih0FtyKw0iXfJBv76fEub0IIXpDzmh48Sir9sNA6AmLk/OuWcgcZRP+X4PTa8VldpcIuzSXRSDuwsp4g5Kzr4IlnJaAlQQFoFsRcaEsMhitInbsBHGYQLciYUA3ym0QUGhMWkOI0StCvwRrAmVTs+i4ZT29VtGiYYyXUNlGsAHtqoW8/sSER1uwXVJVK06HEUSRCSsjFg1zwio/YZz8md5BIuLCHIftbkBQ3c9Anne3i073ViRs+ynUijPQJoFYmuzvg4e86W7yIQueNukQX9ZoTnZsnq2nkBQRpQ4S1NGXxOVYQfGC4qjTGCazKjHLnSmHL38xg/qiUffOPFg9GuyI53gSekrI9BDXdZq31JA2TcGR8hq9ACYoq0i9f8hqgc3e3ULNI+1S4XC/WmhUIzswW7OoTT/jqnato+q7zOuGAMe2NxGkWPgEvlu0f3BO5geo1ZLfVn6WbHxlKdnoi2cnjf4yPBlYF3t58o4gcFs+5fc1XPSAwqgWVNdUIOOv+ukr1OnjweBpJbGGtL4BXfMUaDVxgc5dj1F6vYThOfo98KAlgGddcgMaDs43Ow6Mmseqxc3YMS/rcU7OBiXLhpHB4Q3OHoJu/ZKVJwK5XL5sQPoJ75w+zEW6M6w2yRfLvRGFz4iQH0qeh2QTXCartEm2yN5XrrHn4W5xTTwc5Aa4gS8HCyMNkrJUK4PMYinJ15IKBUfFzOImc0vKdaHy4KAVq6QzQMdLcJns2srUYyYIoLuo+i5tnDPH+oMREB07PoF0NiRiJaIqAkjKu8/UqwijU7+kwsBsVbRPQzK0R8Sj4Pgb88SMsSOJLaEYD9xlCIrOiQ5fwqSd7GXeehNnLJFuV1j0eYgR+DajGVD8LraIqX2H4Z459DMYQuwLWMQMUscpY967+rpWZVHafnep/Py2i9CzTFr+APFNwAFub5dIGdoNAPHJMXdT7gY5+DxtgZ5/G3+CEX8Jm8t4W1eYuT6ZvIRvjTef0AnaRHCywMp/w33xHIpuHQQ+SIwTfB1u0i7HwEH48FEubV5CWMLwgffGeBD8A4aDDDqrsv4lzntycUD4sf1tv9QXuK0H0jT5VDxIenQTNUUqN1yaDk4ZEN6kGR0432X7xe8xluit76YmT+KgQllnHgBSbXQrjHVCv5IxO8XC17B6H8eQFpc3yKCgIPtmxEVqPjckiJKae8ENQ18JjeTURhXZ3O1e5Yp229nzmi1fmPYanxbSzkCLfI6WuPCnlU1GIdsNB1+82Kifbjn2W55052i6A2j6D33c3LxcuC65c3tWu8+BSaODp5cz6nlYJdG1/ThOjk3boBqKyoe2PY73DpD+tS6QsnngO1WVWVlo6PPaVdu/3ggEDlXfzVrMez3sLpudMZlBycBtw7Xmc8Xb0lO6MKbRrdZCPV2SJQ1YTaDTVh4VzGM7mQ0uckftPPmEFyg61Vh9ZEPhXErncjMH7l3caK8kvaKRfjW9yydX4xPq/xJVIDScZOeOAOPp1mZq9ENSof2uoViH1kCKRPuSxEYQS9pnuA/xrX5L4JPDdN0zt+FMnI5LfQSx0WZw2MtoGRt+5SsdCb80dam/xmHoInbsAjfqVB6ji+egd1ExoJn42aJTJ/9Q7wOBQONzfOaKIQ68kATm6x/0QqJXC62GJtX/KB/AhF4Bj0xFp+951fac57O7FIha9fnxntNfneMJ3zwgP38P7qe8witndg87Uk3mCVo76f4B92hb2y0GutxxKe9W5cYADjnDMmm+PShlrFkuLLGS13REU0ulIpoipO7y2/UlXBetIrE+TudS48h3oRH+hvJjGg0bs7zo0+1Y6aDAu+sFYCsUAJD8jQG2VVrGG2gp259Rdqp5UmaGspzyy28QDYPImZocyWRuHSwQ7DR8YQtfC5yvWQ2Yq2EjPNP6pMZBBsp+jBIr8FYckdLNsuDFLdwHbobVC8GkOvHJIO5xLWbWUDFKsUIUi2xp6E+xbcprFlAYqLuvZSWDzHKiZsc/g2xffU6eJIDRoaz6/CBW6kwCIQesO2tQvKl5OW0Zif8CwDwG6n2ynb+WB3wncbfuRtLYBgY948yjF3EYqhNECi3yYgY39T8k0C/fTzTx5XGrVEUg0Ya791Q/7NFhCSnLf+s8lfFQkr8mkZ8VmXMq9knUmrVYCW0DPRln0qvHHpJLuFzp6f9ykIy0O/RfQk08QFgq/laHj5DLduCbTg7yTsGDza+ghuhHMigCiqcAYG/FzUO2IiqSFuJT6nKxA9cQqDyKzl2QStL6Hc19LqnueeQbCaurmlxN6gJ7AKN18q7xZobdHwP5kpi4uWdSXY1FCGIq5o2A+hMtANwwY2OP59Vw5FkRcCArXXy7agj0t0E0kwICP5FDvhQhX3Bbm9FrQiSH+2+rdJ6Jd/mNSt/eZ5V/5Pmsww5fCPBj7vkPeBO0CstuJLqB8dUaZnspL4FTzvkFUBNVFl0s9zkBSuGtQw2dLbQ4ePrHyxQXZapwMvb3BqGMD9bjPgrMFyWts7wByg3bn2gr9sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgMFB4gJSw0MIGHAkIBsd44akSf7cR2b0eRn8Ox0cE9k1KqoStxFz0OS6gEcCfVNRYu2I9JUSQ9mguowqg5ro4ZNK9yepuoBIp/xR1sDtECQQUxXh82JMKtfHRmBzAHN5Jf04/41qez2SmIwiwv8j1/GHtkxcO6seozwMpJxj8/Udqaa+1jGbKa9+9xXieY94oD"), + ]; + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs new file mode 100644 index 00000000000000..65bb8c366609a9 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestData.cs @@ -0,0 +1,104 @@ +// 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.Generic; +using System.Linq; +using Xunit.Sdk; + +namespace System.Security.Cryptography.Tests +{ + public static partial class CompositeMLDsaTestData + { + public class CompositeMLDsaTestVector + { + internal string Id { get; } + internal CompositeMLDsaAlgorithm Algorithm { get; } + internal byte[] Message { get; } + internal byte[] PublicKey { get; } + internal byte[] Certificate { get; } + internal byte[] SecretKey { get; } + internal byte[] Pkcs8 { get; } + internal byte[] Signature { get; } + + internal CompositeMLDsaTestVector(string tcId, CompositeMLDsaAlgorithm algo, string pk, string x5c, string sk, string sk_pkcs8, string m, string s) + { + Id = tcId; + Algorithm = algo; + PublicKey = Convert.FromBase64String(pk); + Certificate = Convert.FromBase64String(x5c); + SecretKey = Convert.FromBase64String(sk); + Pkcs8 = Convert.FromBase64String(sk_pkcs8); + Message = Convert.FromBase64String(m); + Signature = Convert.FromBase64String(s); + } + + public override string ToString() => Id; + } + + internal static partial CompositeMLDsaTestVector[] AllIetfVectors { get; } + + public static IEnumerable AllIetfVectorsTestData => + AllIetfVectors.Select(v => new object[] { v }); + + internal static CompositeMLDsaTestVector[] SupportedAlgorithmIetfVectors => + field ??= AllIetfVectors.Where(v => CompositeMLDsa.IsAlgorithmSupported(v.Algorithm)).ToArray(); + + public static IEnumerableSupportedAlgorithmIetfVectorsTestData => + SupportedAlgorithmIetfVectors.Select(v => new object[] { v }); + + public static IEnumerable SupportedECDsaAlgorithmIetfVectorsTestData => + SupportedAlgorithmIetfVectors + .Where(vector => CompositeMLDsa.IsAlgorithmSupported(vector.Algorithm) && CompositeMLDsaTestHelpers.IsECDsa(vector.Algorithm)) + .Select(v => new object[] { v }); + + internal static CompositeMLDsaAlgorithm[] AllAlgorithms => field ??= + [ + CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss, + CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pkcs15, + CompositeMLDsaAlgorithm.MLDsa44WithEd25519, + CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256, + CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss, + CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pkcs15, + CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss, + CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pkcs15, + CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256, + CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384, + CompositeMLDsaAlgorithm.MLDsa65WithECDsaBrainpoolP256r1, + CompositeMLDsaAlgorithm.MLDsa65WithEd25519, + CompositeMLDsaAlgorithm.MLDsa87WithECDsaP384, + CompositeMLDsaAlgorithm.MLDsa87WithECDsaBrainpoolP384r1, + CompositeMLDsaAlgorithm.MLDsa87WithEd448, + CompositeMLDsaAlgorithm.MLDsa87WithRSA3072Pss, + CompositeMLDsaAlgorithm.MLDsa87WithRSA4096Pss, + CompositeMLDsaAlgorithm.MLDsa87WithECDsaP521, + ]; + + public static IEnumerable AllAlgorithmsTestData => + AllAlgorithms.Select(v => new object[] { v }); + + public static IEnumerable SupportedAlgorithmsTestData => + AllAlgorithms.Where(CompositeMLDsa.IsAlgorithmSupported).Select(v => new object[] { v }); + + internal static MLDsaKeyInfo GetMLDsaIetfTestVector(CompositeMLDsaAlgorithm algorithm) + { + MLDsaAlgorithm mldsaAlgorithm = CompositeMLDsaTestHelpers.MLDsaAlgorithms[algorithm]; + + if (mldsaAlgorithm == MLDsaAlgorithm.MLDsa44) + { + return MLDsaTestsData.IetfMLDsa44; + } + else if (mldsaAlgorithm == MLDsaAlgorithm.MLDsa65) + { + return MLDsaTestsData.IetfMLDsa65; + } + else if (mldsaAlgorithm == MLDsaAlgorithm.MLDsa87) + { + return MLDsaTestsData.IetfMLDsa87; + } + else + { + throw new XunitException($"Algorithm '{algorithm.Name}' doesn't have ML-DSA component."); + } + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestHelpers.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestHelpers.cs new file mode 100644 index 00000000000000..8df9cb261f0503 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestHelpers.cs @@ -0,0 +1,373 @@ +// 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.Generic; +using System.Formats.Asn1; +using System.Security.Cryptography.Rsa.Tests; +using Xunit; +using Xunit.Sdk; + +namespace System.Security.Cryptography.Tests +{ + internal static class CompositeMLDsaTestHelpers + { + internal static readonly Dictionary MLDsaAlgorithms = new() + { + { CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss, MLDsaAlgorithm.MLDsa44 }, + { CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pkcs15, MLDsaAlgorithm.MLDsa44 }, + { CompositeMLDsaAlgorithm.MLDsa44WithEd25519, MLDsaAlgorithm.MLDsa44 }, + { CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256, MLDsaAlgorithm.MLDsa44 }, + + { CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pkcs15, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pkcs15, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithECDsaBrainpoolP256r1, MLDsaAlgorithm.MLDsa65 }, + { CompositeMLDsaAlgorithm.MLDsa65WithEd25519, MLDsaAlgorithm.MLDsa65 }, + + { CompositeMLDsaAlgorithm.MLDsa87WithECDsaP384, MLDsaAlgorithm.MLDsa87 }, + { CompositeMLDsaAlgorithm.MLDsa87WithECDsaBrainpoolP384r1, MLDsaAlgorithm.MLDsa87 }, + { CompositeMLDsaAlgorithm.MLDsa87WithEd448, MLDsaAlgorithm.MLDsa87 }, + { CompositeMLDsaAlgorithm.MLDsa87WithRSA3072Pss, MLDsaAlgorithm.MLDsa87 }, + { CompositeMLDsaAlgorithm.MLDsa87WithRSA4096Pss, MLDsaAlgorithm.MLDsa87 }, + { CompositeMLDsaAlgorithm.MLDsa87WithECDsaP521, MLDsaAlgorithm.MLDsa87 }, + }; + + internal static void AssertImportPublicKey(Action> action, CompositeMLDsaAlgorithm algorithm, byte[] publicKey) + { + action(() => CompositeMLDsa.ImportCompositeMLDsaPublicKey(algorithm, publicKey)); + + if (publicKey?.Length == 0) + { + action(() => CompositeMLDsa.ImportCompositeMLDsaPublicKey(algorithm, Array.Empty().AsSpan())); + action(() => CompositeMLDsa.ImportCompositeMLDsaPublicKey(algorithm, ReadOnlySpan.Empty)); + } + else + { + action(() => CompositeMLDsa.ImportCompositeMLDsaPublicKey(algorithm, publicKey.AsSpan())); + } + } + + internal static void AssertImportPrivateKey(Action> action, CompositeMLDsaAlgorithm algorithm, byte[] privateKey) + { + action(() => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(algorithm, privateKey)); + + if (privateKey?.Length == 0) + { + action(() => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(algorithm, Array.Empty().AsSpan())); + action(() => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(algorithm, ReadOnlySpan.Empty)); + } + else + { + action(() => CompositeMLDsa.ImportCompositeMLDsaPrivateKey(algorithm, privateKey.AsSpan())); + } + } + + internal class RsaAlgorithm(int keySizeInBits) + { + internal int KeySizeInBits { get; } = keySizeInBits; + } + + internal class ECDsaAlgorithm(int keySizeInBits, bool isSec) + { + internal int KeySizeInBits { get; } = keySizeInBits; + internal bool IsSec { get; } = isSec; + } + + internal class EdDsaAlgorithm(int keySizeInBits) + { + internal int KeySizeInBits { get; } = keySizeInBits; + } + + internal static void ExecuteComponentAction( + CompositeMLDsaAlgorithm algo, + Action rsaFunc, + Action ecdsaFunc, + Action eddsaFunc) + { + ExecuteComponentFunc( + algo, + info => { rsaFunc(info); return true; }, + info => { ecdsaFunc(info); return true; }, + info => { eddsaFunc(info); return true; }); + } + + internal static T ExecuteComponentFunc( + CompositeMLDsaAlgorithm algo, + Func rsaFunc, + Func ecdsaFunc, + Func eddsaFunc) + { + if (algo == CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pkcs15 || + algo == CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss) + { + return rsaFunc(new RsaAlgorithm(2048)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pkcs15 || + algo == CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss || + algo == CompositeMLDsaAlgorithm.MLDsa87WithRSA3072Pss) + { + return rsaFunc(new RsaAlgorithm(3072)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pkcs15 || + algo == CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss || + algo == CompositeMLDsaAlgorithm.MLDsa87WithRSA4096Pss) + { + return rsaFunc(new RsaAlgorithm(4096)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256 || + algo == CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256) + { + return ecdsaFunc(new ECDsaAlgorithm(256, isSec: true)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa65WithECDsaBrainpoolP256r1) + { + return ecdsaFunc(new ECDsaAlgorithm(256, isSec: false)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384 || + algo == CompositeMLDsaAlgorithm.MLDsa87WithECDsaP384) + { + return ecdsaFunc(new ECDsaAlgorithm(384, isSec: true)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa87WithECDsaBrainpoolP384r1) + { + return ecdsaFunc(new ECDsaAlgorithm(384, isSec: false)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa87WithECDsaP521) + { + return ecdsaFunc(new ECDsaAlgorithm(521, isSec: true)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa44WithEd25519 || + algo == CompositeMLDsaAlgorithm.MLDsa65WithEd25519) + { + return eddsaFunc(new EdDsaAlgorithm(256)); + } + else if (algo == CompositeMLDsaAlgorithm.MLDsa87WithEd448) + { + return eddsaFunc(new EdDsaAlgorithm(456)); + } + else + { + throw new XunitException($"Unsupported algorithm: {algo}"); + } + } + + internal static int ExpectedPublicKeySizeLowerBound(CompositeMLDsaAlgorithm algorithm) + { + return MLDsaAlgorithms[algorithm].PublicKeySizeInBytes + + ExecuteComponentFunc( + algorithm, + rsa => rsa.KeySizeInBits / 8, + ecdsa => 1 + 2 * ((ecdsa.KeySizeInBits + 7) / 8), + eddsa => eddsa.KeySizeInBits / 8); + } + + internal static int ExpectedPublicKeySizeUpperBound(CompositeMLDsaAlgorithm algorithm) + { + return MLDsaAlgorithms[algorithm].PublicKeySizeInBytes + + ExecuteComponentFunc( + algorithm, + rsa => (rsa.KeySizeInBits / 8) + 52, // Add max ASN.1 overhead + ecdsa => 1 + 2 * ((ecdsa.KeySizeInBits + 7) / 8), + eddsa => eddsa.KeySizeInBits / 8); + } + + internal static int ExpectedPrivateKeySizeLowerBound(CompositeMLDsaAlgorithm algorithm) + { + return MLDsaAlgorithms[algorithm].PrivateSeedSizeInBytes + + ExecuteComponentFunc( + algorithm, + rsa => rsa.KeySizeInBits / 8, + ecdsa => (ecdsa.KeySizeInBits + 7) / 8, + eddsa => eddsa.KeySizeInBits / 8); + } + + internal static int ExpectedPrivateKeySizeUpperBound(CompositeMLDsaAlgorithm algorithm) + { + return MLDsaAlgorithms[algorithm].PrivateSeedSizeInBytes + + ExecuteComponentFunc( + algorithm, + rsa => (rsa.KeySizeInBits / 8) * 9 / 2 + 101, // Add max ASN.1 overhead + ecdsa => 3 * ((ecdsa.KeySizeInBits + 7) / 8) + 47, // Add max ASN.1 overhead + eddsa => eddsa.KeySizeInBits / 8); + } + + internal static bool IsECDsa(CompositeMLDsaAlgorithm algorithm) => ExecuteComponentFunc(algorithm, rsa => false, ecdsa => true, eddsa => false); + + internal static void AssertExportPublicKey(Action> callback) + { + callback(dsa => dsa.ExportCompositeMLDsaPublicKey()); + callback(dsa => DoTryUntilDone(dsa.TryExportCompositeMLDsaPublicKey)); + } + + internal static void AssertExportPrivateKey(Action> callback) + { + callback(dsa => dsa.ExportCompositeMLDsaPrivateKey()); + callback(dsa => DoTryUntilDone(dsa.TryExportCompositeMLDsaPrivateKey)); + } + + internal static void WithDispose(T disposable, Action callback) + where T : IDisposable + { + using (disposable) + { + callback(disposable); + } + } + + internal static void AssertPublicKeyEquals(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan expected, ReadOnlySpan actual) + { + AssertExtensions.SequenceEqual(expected, actual); + } + + internal static void AssertPrivateKeyEquals(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan expected, ReadOnlySpan actual) + { + ReadOnlySpan expectedMLDsaKey = expected.Slice(0, MLDsaAlgorithms[algorithm].PrivateSeedSizeInBytes); + ReadOnlySpan actualMLDsaKey = actual.Slice(0, MLDsaAlgorithms[algorithm].PrivateSeedSizeInBytes); + + AssertExtensions.SequenceEqual(expectedMLDsaKey, actualMLDsaKey); + + byte[] expectedTradKey = expected.Slice(expectedMLDsaKey.Length).ToArray(); + byte[] actualTradKey = actual.Slice(actualMLDsaKey.Length).ToArray(); + + ExecuteComponentAction( + algorithm, + _ => + { + RSAParameters expectedRsaParameters = RSAParametersFromRawPrivateKey(expectedTradKey); + RSAParameters actualRsaParameters = RSAParametersFromRawPrivateKey(actualTradKey); + + RSATestHelpers.AssertKeyEquals(expectedRsaParameters, actualRsaParameters); + }, + _ => Assert.Equal(expectedTradKey, actualTradKey), + _ => Assert.Equal(expectedTradKey, actualTradKey)); + } + + private static RSAParameters RSAParametersFromRawPrivateKey(ReadOnlySpan key) + { + RSAParameters parameters = default; + + AsnValueReader reader = new AsnValueReader(key, AsnEncodingRules.BER); + AsnValueReader sequenceReader = reader.ReadSequence(Asn1Tag.Sequence); + + if (!sequenceReader.TryReadInt32(out int version)) + { + sequenceReader.ThrowIfNotEmpty(); + } + + const int MaxSupportedVersion = 0; + + if (version > MaxSupportedVersion) + { + throw new CryptographicException( + SR.Format( + SR.Cryptography_RSAPrivateKey_VersionTooNew, + version, + MaxSupportedVersion)); + } + + parameters.Modulus = sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(); + + int modulusLength = parameters.Modulus.Length; + int halfModulusLength = modulusLength / 2; + + if (parameters.Modulus.Length != modulusLength) + { + throw new CryptographicException(SR.Cryptography_NotValidPrivateKey); + } + + parameters.Exponent = sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(); + + // We're not pinning and clearing the arrays here because this is a test helper. + // In production code, you should always pin and clear sensitive data. + parameters.D = new byte[modulusLength]; + parameters.P = new byte[halfModulusLength]; + parameters.Q = new byte[halfModulusLength]; + parameters.DP = new byte[halfModulusLength]; + parameters.DQ = new byte[halfModulusLength]; + parameters.InverseQ = new byte[halfModulusLength]; + + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.D); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.P); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.Q); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.DP); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.DQ); + sequenceReader.ReadIntegerBytes().ToUnsignedIntegerBytes(parameters.InverseQ); + + sequenceReader.ThrowIfNotEmpty(); + reader.ThrowIfNotEmpty(); + + return parameters; + } + + private static byte[] ToUnsignedIntegerBytes(this ReadOnlySpan span) + { + if (span.Length > 1 && span[0] == 0) + { + return span.Slice(1).ToArray(); + } + + return span.ToArray(); + } + + private static void ToUnsignedIntegerBytes(this ReadOnlySpan span, Span destination) + { + int length = destination.Length; + + if (span.Length == length) + { + span.CopyTo(destination); + return; + } + + if (span.Length == length + 1) + { + if (span[0] == 0) + { + span.Slice(1).CopyTo(destination); + return; + } + } + + if (span.Length > length) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + destination.Slice(0, destination.Length - span.Length).Clear(); + span.CopyTo(destination.Slice(length - span.Length)); + } + + internal static void VerifyDisposed(CompositeMLDsa dsa) + { + // A signature-sized buffer can be reused for keys as well + byte[] tempBuffer = new byte[dsa.Algorithm.MaxSignatureSizeInBytes]; + + Assert.Throws(() => dsa.SignData([], tempBuffer, [])); + Assert.Throws(() => dsa.SignData([])); + Assert.Throws(() => dsa.VerifyData(ReadOnlySpan.Empty, ReadOnlySpan.Empty, ReadOnlySpan.Empty)); + Assert.Throws(() => dsa.VerifyData(Array.Empty(), Array.Empty(), Array.Empty())); + + Assert.Throws(() => dsa.TryExportCompositeMLDsaPrivateKey([], out _)); + Assert.Throws(() => dsa.ExportCompositeMLDsaPrivateKey()); + Assert.Throws(() => dsa.TryExportCompositeMLDsaPublicKey([], out _)); + Assert.Throws(() => dsa.ExportCompositeMLDsaPublicKey()); + } + + private delegate bool TryExportFunc(Span destination, out int bytesWritten); + private static byte[] DoTryUntilDone(TryExportFunc func) + { + byte[] buffer = new byte[512]; + int written; + + while (!func(buffer, out written)) + { + Array.Resize(ref buffer, buffer.Length * 2); + } + + return buffer.AsSpan(0, written).ToArray(); + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestsBase.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestsBase.cs new file mode 100644 index 00000000000000..17606e753a1e97 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaTestsBase.cs @@ -0,0 +1,359 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Security.Cryptography.Tests +{ + [ConditionalClass(typeof(CompositeMLDsa), nameof(CompositeMLDsa.IsSupported))] + public abstract class CompositeMLDsaTestsBase + { + protected abstract CompositeMLDsa GenerateKey(CompositeMLDsaAlgorithm algorithm); + protected abstract CompositeMLDsa ImportPrivateKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source); + protected abstract CompositeMLDsa ImportPublicKey(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source); + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void GenerateSignVerifyWithPublicKey(CompositeMLDsaAlgorithm algorithm) + { + byte[] signature; + byte[] data = [0, 1, 2, 3]; + byte[] exportedPublicKey; + + using (CompositeMLDsa generatedKey = GenerateKey(algorithm)) + { + signature = generatedKey.SignData(data); + + ExerciseSuccessfulVerify(generatedKey, data, signature, []); + + exportedPublicKey = generatedKey.ExportCompositeMLDsaPublicKey(); + } + + using (CompositeMLDsa publicKey = ImportPublicKey(algorithm, exportedPublicKey)) + { + ExerciseSuccessfulVerify(publicKey, data, signature, []); + + Assert.Throws(() => publicKey.SignData(data)); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void GenerateSignVerifyWithPrivateKey(CompositeMLDsaAlgorithm algorithm) + { + byte[] signature; + byte[] data = [0, 1, 2, 3]; + byte[] exportedPrivateKey; + + using (CompositeMLDsa generatedKey = GenerateKey(algorithm)) + { + signature = generatedKey.SignData(data); + exportedPrivateKey = generatedKey.ExportCompositeMLDsaPrivateKey(); + } + + using (CompositeMLDsa privateKey = ImportPrivateKey(algorithm, exportedPrivateKey)) + { + ExerciseSuccessfulVerify(privateKey, data, signature, []); + + signature = new byte[algorithm.MaxSignatureSizeInBytes]; + Array.Resize(ref signature, privateKey.SignData(data, signature, [])); + + ExerciseSuccessfulVerify(privateKey, data, signature, []); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void GenerateSignVerifyNoContext(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsa dsa = GenerateKey(algorithm); + byte[] data = [1, 2, 3, 4, 5]; + byte[] signature = dsa.SignData(data); + ExerciseSuccessfulVerify(dsa, data, signature, []); + + signature = new byte[algorithm.MaxSignatureSizeInBytes]; + Array.Resize(ref signature, dsa.SignData(data, signature, Array.Empty())); + ExerciseSuccessfulVerify(dsa, data, signature, Array.Empty()); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void GenerateSignVerifyWithContext(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsa dsa = GenerateKey(algorithm); + byte[] context = [1, 1, 3, 5, 6]; + byte[] data = [1, 2, 3, 4, 5]; + + byte[] signature = dsa.SignData(data, context); + ExerciseSuccessfulVerify(dsa, data, signature, context); + + signature = new byte[algorithm.MaxSignatureSizeInBytes]; + Array.Resize(ref signature, dsa.SignData(data, signature, context)); + ExerciseSuccessfulVerify(dsa, data, signature, context); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void GenerateSignVerifyEmptyMessageNoContext(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsa dsa = GenerateKey(algorithm); + byte[] signature = dsa.SignData([]); + ExerciseSuccessfulVerify(dsa, [], signature, []); + + signature = new byte[algorithm.MaxSignatureSizeInBytes]; + Array.Resize(ref signature, dsa.SignData(Array.Empty(), signature, Array.Empty())); + ExerciseSuccessfulVerify(dsa, [], signature, []); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void GenerateSignVerifyEmptyMessageWithContext(CompositeMLDsaAlgorithm algorithm) + { + using CompositeMLDsa dsa = GenerateKey(algorithm); + byte[] context = [1, 1, 3, 5, 6]; + byte[] signature = dsa.SignData([], context); + ExerciseSuccessfulVerify(dsa, [], signature, context); + + signature = new byte[algorithm.MaxSignatureSizeInBytes]; + Array.Resize(ref signature, dsa.SignData(Array.Empty(), signature, context)); + ExerciseSuccessfulVerify(dsa, [], signature, context); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void ImportExportVerify(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + using (CompositeMLDsa privateKey = ImportPrivateKey(vector.Algorithm, vector.SecretKey)) + { + byte[] exportedSecretKey = privateKey.ExportCompositeMLDsaPrivateKey(); + CompositeMLDsaTestHelpers.AssertPrivateKeyEquals(vector.Algorithm, vector.SecretKey, exportedSecretKey); + + byte[] exportedPublicKey = privateKey.ExportCompositeMLDsaPublicKey(); + CompositeMLDsaTestHelpers.AssertPublicKeyEquals(vector.Algorithm, vector.PublicKey, exportedPublicKey); + + ExerciseSuccessfulVerify(privateKey, vector.Message, vector.Signature, []); + } + + using (CompositeMLDsa publicKey = ImportPublicKey(vector.Algorithm, vector.PublicKey)) + { + Assert.Throws(publicKey.ExportCompositeMLDsaPrivateKey); + + CompositeMLDsaTestHelpers.AssertExportPrivateKey( + export => Assert.Throws(() => export(publicKey))); + + byte[] exportedPublicKey = publicKey.ExportCompositeMLDsaPublicKey(); + CompositeMLDsaTestHelpers.AssertPublicKeyEquals(vector.Algorithm, vector.PublicKey, exportedPublicKey); + + ExerciseSuccessfulVerify(publicKey, vector.Message, vector.Signature, []); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void ImportSignVerify(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + byte[] signature; + + using (CompositeMLDsa privateKey = ImportPrivateKey(vector.Algorithm, vector.SecretKey)) + { + signature = privateKey.SignData(vector.Message, null); + + ExerciseSuccessfulVerify(privateKey, vector.Message, signature, []); + ExerciseSuccessfulVerify(privateKey, vector.Message, vector.Signature, []); + } + + using (CompositeMLDsa publicKey = ImportPublicKey(vector.Algorithm, vector.PublicKey)) + { + ExerciseSuccessfulVerify(publicKey, vector.Message, signature, []); + ExerciseSuccessfulVerify(publicKey, vector.Message, vector.Signature, []); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void ImportPublicKey_Export(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + using CompositeMLDsa dsa = ImportPublicKey(vector.Algorithm, vector.PublicKey); + + CompositeMLDsaTestHelpers.AssertExportPublicKey( + export => CompositeMLDsaTestHelpers.AssertPublicKeyEquals(vector.Algorithm, vector.PublicKey, export(dsa))); + + CompositeMLDsaTestHelpers.AssertExportPrivateKey( + export => Assert.Throws(() => export(dsa))); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void ImportPrivateKey_Export(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + using CompositeMLDsa dsa = ImportPrivateKey(vector.Algorithm, vector.SecretKey); + + CompositeMLDsaTestHelpers.AssertExportPublicKey( + export => CompositeMLDsaTestHelpers.AssertPublicKeyEquals(vector.Algorithm, vector.PublicKey, export(dsa))); + + CompositeMLDsaTestHelpers.AssertExportPrivateKey( + export => CompositeMLDsaTestHelpers.AssertPrivateKeyEquals(vector.Algorithm, vector.SecretKey, export(dsa))); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void Generate_Export_Import_PublicKey(CompositeMLDsaAlgorithm algorithm) + { + byte[] exportedPublicKey; + + using (CompositeMLDsa dsa = GenerateKey(algorithm)) + { + exportedPublicKey = dsa.ExportCompositeMLDsaPublicKey(); + + using (CompositeMLDsa importedDsa = ImportPublicKey(algorithm, exportedPublicKey)) + { + Assert.Throws(() => importedDsa.ExportCompositeMLDsaPrivateKey()); + AssertExtensions.SequenceEqual(exportedPublicKey, importedDsa.ExportCompositeMLDsaPublicKey()); + } + } + + using (CompositeMLDsa importedDsa = ImportPublicKey(algorithm, exportedPublicKey)) + { + Assert.Throws(() => importedDsa.ExportCompositeMLDsaPrivateKey()); + AssertExtensions.SequenceEqual(exportedPublicKey, importedDsa.ExportCompositeMLDsaPublicKey()); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void Generate_Export_Import_PrivateKey(CompositeMLDsaAlgorithm algorithm) + { + byte[] exportedPrivateKey; + byte[] exportedPublicKey; + + using (CompositeMLDsa dsa = GenerateKey(algorithm)) + { + exportedPrivateKey = dsa.ExportCompositeMLDsaPrivateKey(); + exportedPublicKey = dsa.ExportCompositeMLDsaPublicKey(); + + using (CompositeMLDsa importedDsa = ImportPrivateKey(algorithm, exportedPrivateKey)) + { + AssertExtensions.SequenceEqual(exportedPrivateKey, importedDsa.ExportCompositeMLDsaPrivateKey()); + AssertExtensions.SequenceEqual(exportedPublicKey, importedDsa.ExportCompositeMLDsaPublicKey()); + } + } + + using (CompositeMLDsa importedDsa = ImportPrivateKey(algorithm, exportedPrivateKey)) + { + AssertExtensions.SequenceEqual(exportedPrivateKey, importedDsa.ExportCompositeMLDsaPrivateKey()); + AssertExtensions.SequenceEqual(exportedPublicKey, importedDsa.ExportCompositeMLDsaPublicKey()); + } + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void SignData_PublicKeyOnlyThrows(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + using CompositeMLDsa dsa = ImportPublicKey(vector.Algorithm, vector.PublicKey); + + CryptographicException ce = + Assert.ThrowsAny(() => dsa.SignData("hello"u8.ToArray())); + + Assert.DoesNotContain("unknown", ce.Message, StringComparison.OrdinalIgnoreCase); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void TryExportPrivateKey_BufferTooSmall(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + using CompositeMLDsa dsa = ImportPrivateKey(vector.Algorithm, vector.SecretKey); + byte[] key = dsa.ExportCompositeMLDsaPrivateKey(); + AssertExtensions.FalseExpression(dsa.TryExportCompositeMLDsaPrivateKey(key.AsSpan(0, key.Length - 1), out int bytesWritten)); + Assert.Equal(0, bytesWritten); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void TryExportPublicKey_BufferTooSmall(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + using CompositeMLDsa dsa = ImportPublicKey(vector.Algorithm, vector.PublicKey); + byte[] key = dsa.ExportCompositeMLDsaPublicKey(); + AssertExtensions.FalseExpression(dsa.TryExportCompositeMLDsaPublicKey(key.AsSpan(0, key.Length - 1), out int bytesWritten)); + Assert.Equal(0, bytesWritten); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void ImportPrivateKey_TrailingData(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + byte[] secretKeyWithTrailingData = vector.SecretKey; + Array.Resize(ref secretKeyWithTrailingData, vector.SecretKey.Length + 1); + Assert.Throws(() => ImportPrivateKey(vector.Algorithm, secretKeyWithTrailingData)); + } + + [Theory] + [MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))] + public void ImportPublicKey_TrailingData(CompositeMLDsaTestData.CompositeMLDsaTestVector vector) + { + byte[] publicKeyWithTrailingData = vector.PublicKey; + Array.Resize(ref publicKeyWithTrailingData, vector.PublicKey.Length + 1); + Assert.Throws(() => ImportPublicKey(vector.Algorithm, publicKeyWithTrailingData)); + } + + protected static void ExerciseSuccessfulVerify(CompositeMLDsa dsa, byte[] data, byte[] signature, byte[] context) + { + ReadOnlySpan buffer = [0, 1, 2, 3]; + + AssertExtensions.TrueExpression(dsa.VerifyData(data, signature, context)); + + if (data.Length > 0) + { + AssertExtensions.FalseExpression(dsa.VerifyData(Array.Empty(), signature, context)); + AssertExtensions.FalseExpression(dsa.VerifyData(ReadOnlySpan.Empty, signature, context)); + + data[0] ^= 1; + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, context)); + data[0] ^= 1; + } + else + { + AssertExtensions.TrueExpression(dsa.VerifyData(Array.Empty(), signature, context)); + AssertExtensions.TrueExpression(dsa.VerifyData(ReadOnlySpan.Empty, signature, context)); + + AssertExtensions.FalseExpression(dsa.VerifyData(buffer.Slice(0, 1), signature, context)); + AssertExtensions.FalseExpression(dsa.VerifyData(buffer.Slice(1, 3), signature, context)); + } + + // Flip randomizer + signature[0] ^= 1; + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, context)); + signature[0] ^= 1; + + // Flip mldsaSig + signature[32] ^= 1; + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, context)); + signature[32] ^= 1; + + // Flip tradSig + int tradSigOffset = 32 + CompositeMLDsaTestHelpers.MLDsaAlgorithms[dsa.Algorithm].SignatureSizeInBytes; + signature[tradSigOffset] ^= 1; + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, context)); + signature[tradSigOffset] ^= 1; + + if (context.Length > 0) + { + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, Array.Empty())); + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, ReadOnlySpan.Empty)); + + context[0] ^= 1; + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, context)); + context[0] ^= 1; + } + else + { + AssertExtensions.TrueExpression(dsa.VerifyData(data, signature, Array.Empty())); + AssertExtensions.TrueExpression(dsa.VerifyData(data, signature, ReadOnlySpan.Empty)); + + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, buffer.Slice(0, 1))); + AssertExtensions.FalseExpression(dsa.VerifyData(data, signature, buffer.Slice(1, 3))); + } + + AssertExtensions.TrueExpression(dsa.VerifyData(data, signature, context)); + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAFactoryTests.cs new file mode 100644 index 00000000000000..992b5357484307 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAFactoryTests.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. + +using Xunit; + +namespace System.Security.Cryptography.Dsa.Tests +{ + [SkipOnPlatform(TestPlatforms.Browser | TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.MacCatalyst, "Not supported on Browser/iOS/tvOS/MacCatalyst")] + public partial class DSAFactoryTests + { + [Fact] + public static void DSACreateDefault_Equals_SameInstance() + { + using DSA dsa = DSAFactory.Create(); + dsa.ImportParameters(DSATestData.GetDSA1024Params()); + AssertExtensions.TrueExpression(dsa.Equals(dsa)); + } + + [Fact] + public static void DSACreateKeySize_Equals_SameInstance() + { + using DSA dsa = DSAFactory.Create(1024); + AssertExtensions.TrueExpression(dsa.Equals(dsa)); + } + + [Fact] + public static void DsaCreate_Equals_DifferentInstance_FalseForSameKeyMaterial() + { + using DSA dsa1 = DSAFactory.Create(); + using DSA dsa2 = DSAFactory.Create(); + dsa1.ImportParameters(DSATestData.GetDSA1024Params()); + dsa2.ImportParameters(DSATestData.GetDSA1024Params()); + AssertExtensions.FalseExpression(dsa1.Equals(dsa2)); + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs index d3d00c754d584e..ece11f82401232 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs @@ -12,7 +12,7 @@ public interface IECDiffieHellmanProvider #endif bool IsCurveValid(Oid oid); bool ExplicitCurvesSupported { get; } - bool ExplicitCurvesSupportFailOnUseOnly => PlatformDetection.IsAzureLinux; + bool ExplicitCurvesSupportFailOnUseOnly => PlatformDetection.IsSymCryptOpenSsl; bool CanDeriveNewPublicKey { get; } bool SupportsRawDerivation { get; } bool SupportsSha3 { get; } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactoryTests.cs new file mode 100644 index 00000000000000..059772aed20d2f --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactoryTests.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Security.Cryptography.Tests; +using Xunit; + +namespace System.Security.Cryptography.EcDiffieHellman.Tests +{ + [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] + public static class ECDiffieHellmanFactoryTests + { + [Fact] + public static void ECDiffieHellmanCreateDefault_Equals_SameInstance() + { + using ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(); + AssertExtensions.TrueExpression(ecdh.Equals(ecdh)); + } + + [Fact] + public static void ECDiffieHellmanCreateKeySize_Equals_SameInstance() + { + using ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(256); + AssertExtensions.TrueExpression(ecdh.Equals(ecdh)); + } + + [Fact] + public static void ECDiffieHellmanCreateKeySize_Equals_DifferentInstance_FalseForSameKeyMaterial() + { + using ECDiffieHellman ecdh1 = ECDiffieHellmanFactory.Create(); + using ECDiffieHellman ecdh2 = ECDiffieHellmanFactory.Create(); + ecdh1.ImportParameters(EccTestData.GetNistP256ReferenceKey()); + ecdh2.ImportParameters(EccTestData.GetNistP256ReferenceKey()); + AssertExtensions.FalseExpression(ecdh1.Equals(ecdh2)); + } + +#if NET + [Fact] + public static void ECDiffieHellmanCreateCurve_Equals_SameInstance() + { + using ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(ECCurve.NamedCurves.nistP256); + AssertExtensions.TrueExpression(ecdh.Equals(ecdh)); + } +#endif + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactory.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactory.cs index 7571ec641fb718..244fcfe9c0c73b 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactory.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactory.cs @@ -12,7 +12,7 @@ public interface IECDsaProvider #endif bool IsCurveValid(Oid oid); bool ExplicitCurvesSupported { get; } - bool ExplicitCurvesSupportFailOnUseOnly => PlatformDetection.IsAzureLinux; + bool ExplicitCurvesSupportFailOnUseOnly => PlatformDetection.IsSymCryptOpenSsl; } public static partial class ECDsaFactory diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactoryTests.cs new file mode 100644 index 00000000000000..84d53afe315413 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactoryTests.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Security.Cryptography.Tests; +using Xunit; + +namespace System.Security.Cryptography.EcDsa.Tests +{ + [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] + public static class ECDsaFactoryTests + { + [Fact] + public static void ECDsaCreateDefault_Equals_SameInstance() + { + using ECDsa ecdsa = ECDsaFactory.Create(); + AssertExtensions.TrueExpression(ecdsa.Equals(ecdsa)); + } + + [Fact] + public static void ECDsaCreateKeySize_Equals_SameInstance() + { + using ECDsa ecdsa = ECDsaFactory.Create(256); + AssertExtensions.TrueExpression(ecdsa.Equals(ecdsa)); + } + + [Fact] + public static void ECDsaCreateKeySize_Equals_DifferentInstance_FalseForSameKeyMaterial() + { + using ECDsa ecdsa1 = ECDsaFactory.Create(); + using ECDsa ecdsa2 = ECDsaFactory.Create(); + ecdsa1.ImportParameters(EccTestData.GetNistP256ReferenceKey()); + ecdsa2.ImportParameters(EccTestData.GetNistP256ReferenceKey()); + AssertExtensions.FalseExpression(ecdsa1.Equals(ecdsa2)); + } + +#if NET + [Fact] + public static void ECDsaCreateCurve_Equals_SameInstance() + { + using ECDsa ecdsa = ECDsaFactory.Create(ECCurve.NamedCurves.nistP256); + AssertExtensions.TrueExpression(ecdsa.Equals(ecdsa)); + } +#endif + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaCngTests.Windows.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaCngTests.Windows.cs index 86d981dcff79a5..6265ab1cbb8d13 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaCngTests.Windows.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaCngTests.Windows.cs @@ -17,8 +17,8 @@ protected override MLDsa GenerateKey(MLDsaAlgorithm algorithm) => protected override MLDsa ImportPrivateSeed(MLDsaAlgorithm algorithm, ReadOnlySpan source) => MLDsaTestHelpers.ImportPrivateSeed(algorithm, source, CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport); - protected override MLDsa ImportSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) => - MLDsaTestHelpers.ImportSecretKey(algorithm, source, CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport); + protected override MLDsa ImportPrivateKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) => + MLDsaTestHelpers.ImportPrivateKey(algorithm, source, CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport); protected override MLDsa ImportPublicKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) => MLDsaTestHelpers.ImportPublicKey(algorithm, source); @@ -37,8 +37,8 @@ protected override MLDsa GenerateKey(MLDsaAlgorithm algorithm) => protected override MLDsa ImportPrivateSeed(MLDsaAlgorithm algorithm, ReadOnlySpan source) => MLDsaTestHelpers.ImportPrivateSeed(algorithm, source, CngExportPolicies.AllowExport); - protected override MLDsa ImportSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) => - MLDsaTestHelpers.ImportSecretKey(algorithm, source, CngExportPolicies.AllowExport); + protected override MLDsa ImportPrivateKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) => + MLDsaTestHelpers.ImportPrivateKey(algorithm, source, CngExportPolicies.AllowExport); protected override MLDsa ImportPublicKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) => MLDsaTestHelpers.ImportPublicKey(algorithm, source); @@ -55,12 +55,12 @@ public sealed class MLDsaCngTests [MemberData(nameof(MLDsaTestsData.IetfMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] public void ImportPrivateKey_NoExportFlag(MLDsaKeyInfo info) { - using MLDsa mldsa = MLDsaTestHelpers.ImportSecretKey(info.Algorithm, info.SecretKey, CngExportPolicies.None); + using MLDsa mldsa = MLDsaTestHelpers.ImportPrivateKey(info.Algorithm, info.PrivateKey, CngExportPolicies.None); MLDsaTestHelpers.AssertExportMLDsaPublicKey( export => AssertExtensions.SequenceEqual(info.PublicKey, export(mldsa))); - MLDsaTestHelpers.AssertExportMLDsaSecretKey( + MLDsaTestHelpers.AssertExportMLDsaPrivateKey( export => Assert.Throws(() => export(mldsa)), export => MLDsaTestHelpers.AssertThrowsCryptographicExceptionWithHResult(() => export(mldsa))); @@ -82,7 +82,7 @@ public void ImportPrivateSeed_NoExportFlag(MLDsaKeyInfo info) MLDsaTestHelpers.AssertExportMLDsaPublicKey( export => AssertExtensions.SequenceEqual(info.PublicKey, export(mldsa))); - MLDsaTestHelpers.AssertExportMLDsaSecretKey( + MLDsaTestHelpers.AssertExportMLDsaPrivateKey( export => Assert.Throws(() => export(mldsa)), export => MLDsaTestHelpers.AssertThrowsCryptographicExceptionWithHResult(() => export(mldsa))); @@ -125,9 +125,9 @@ public void ImportPrivateSeed_Persisted() MLDsaTestHelpers.AssertExportMLDsaPublicKey(export => AssertExtensions.SequenceEqual(MLDsaTestsData.IetfMLDsa44.PublicKey, export(mldsa))); - MLDsaTestHelpers.AssertExportMLDsaSecretKey( - export => AssertExtensions.SequenceEqual(MLDsaTestsData.IetfMLDsa44.SecretKey, export(mldsa)), - // Seed is preferred in PKCS#8, so secret key won't be available + MLDsaTestHelpers.AssertExportMLDsaPrivateKey( + export => AssertExtensions.SequenceEqual(MLDsaTestsData.IetfMLDsa44.PrivateKey, export(mldsa)), + // Seed is preferred in PKCS#8, so private key won't be available export => Assert.Null(export(mldsa))); MLDsaTestHelpers.AssertExportMLDsaPrivateSeed(export => @@ -144,12 +144,12 @@ public void ImportPrivateSeed_Persisted() } } - [Fact] - public void ImportSecretKey_Persisted() + [ConditionalFact(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.SupportsExportingPrivateKeyPkcs8))] + public void ImportPrivateKey_Persisted() { CngKey key = PqcBlobHelpers.EncodeMLDsaBlob( PqcBlobHelpers.GetMLDsaParameterSet(MLDsaAlgorithm.MLDsa44), - MLDsaTestsData.IetfMLDsa44.SecretKey, + MLDsaTestsData.IetfMLDsa44.PrivateKey, Interop.BCrypt.KeyBlobType.BCRYPT_PQDSA_PRIVATE_BLOB, blob => { @@ -163,7 +163,7 @@ public void ImportSecretKey_Persisted() creationParams.ExportPolicy = CngExportPolicies.AllowPlaintextExport; creationParams.KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey; - CngKey key = CngKey.Create(CngAlgorithm.MLDsa, $"MLDsaCngTests_{nameof(ImportSecretKey_Persisted)}", creationParams); + CngKey key = CngKey.Create(CngAlgorithm.MLDsa, $"MLDsaCngTests_{nameof(ImportPrivateKey_Persisted)}", creationParams); return key; }); @@ -174,8 +174,8 @@ public void ImportSecretKey_Persisted() MLDsaTestHelpers.AssertExportMLDsaPublicKey(export => AssertExtensions.SequenceEqual(MLDsaTestsData.IetfMLDsa44.PublicKey, export(mldsa))); - MLDsaTestHelpers.AssertExportMLDsaSecretKey(export => - AssertExtensions.SequenceEqual(MLDsaTestsData.IetfMLDsa44.SecretKey, export(mldsa))); + MLDsaTestHelpers.AssertExportMLDsaPrivateKey(export => + AssertExtensions.SequenceEqual(MLDsaTestsData.IetfMLDsa44.PrivateKey, export(mldsa))); MLDsaTestHelpers.AssertExportMLDsaPrivateSeed( export => Assert.Throws(() => export(mldsa)), @@ -234,5 +234,27 @@ public void MLDsaCng_DuplicateHandle(string? name) key.Delete(); } } + + [Fact] + public static void MLDsaCng_GetKey() + { + CngProperty parameterSet = MLDsaTestHelpers.GetCngProperty(MLDsaAlgorithm.MLDsa65); + CngKeyCreationParameters creationParams = new(); + creationParams.Parameters.Add(parameterSet); + + using CngKey key = CngKey.Create(CngAlgorithm.MLDsa, keyName: null, creationParams); + + using (MLDsaCng mlDsaKey = new(key)) + using (CngKey getKey1 = mlDsaKey.GetKey()) + { + using (CngKey getKey2 = mlDsaKey.GetKey()) + { + Assert.NotSame(key, getKey1); + Assert.NotSame(getKey1, getKey2); + } + + Assert.Equal(key.Algorithm, getKey1.Algorithm); // Assert.NoThrow on getKey1.Algorithm + } + } } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaImplementationTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaImplementationTests.cs index eabcc2f37801a3..2a10aa95a075c6 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaImplementationTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaImplementationTests.cs @@ -13,7 +13,7 @@ public class MLDsaImplementationTests : MLDsaTestsBase { protected override MLDsa GenerateKey(MLDsaAlgorithm algorithm) => MLDsa.GenerateKey(algorithm); protected override MLDsa ImportPrivateSeed(MLDsaAlgorithm algorithm, ReadOnlySpan seed) => MLDsa.ImportMLDsaPrivateSeed(algorithm, seed); - protected override MLDsa ImportSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) => MLDsa.ImportMLDsaSecretKey(algorithm, source); + protected override MLDsa ImportPrivateKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) => MLDsa.ImportMLDsaPrivateKey(algorithm, source); protected override MLDsa ImportPublicKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) => MLDsa.ImportMLDsaPublicKey(algorithm, source); [Fact] @@ -22,11 +22,11 @@ public static void GenerateImport_NullAlgorithm() AssertExtensions.Throws("algorithm", static () => MLDsa.GenerateKey(null)); AssertExtensions.Throws("algorithm", static () => MLDsa.ImportMLDsaPrivateSeed(null, default(ReadOnlySpan))); AssertExtensions.Throws("algorithm", static () => MLDsa.ImportMLDsaPublicKey(null, default(ReadOnlySpan))); - AssertExtensions.Throws("algorithm", static () => MLDsa.ImportMLDsaSecretKey(null, default(ReadOnlySpan))); + AssertExtensions.Throws("algorithm", static () => MLDsa.ImportMLDsaPrivateKey(null, default(ReadOnlySpan))); AssertExtensions.Throws("algorithm", static () => MLDsa.ImportMLDsaPrivateSeed(null, (byte[]?)null)); AssertExtensions.Throws("algorithm", static () => MLDsa.ImportMLDsaPublicKey(null, (byte[]?)null)); - AssertExtensions.Throws("algorithm", static () => MLDsa.ImportMLDsaSecretKey(null, (byte[]?)null)); + AssertExtensions.Throws("algorithm", static () => MLDsa.ImportMLDsaPrivateKey(null, (byte[]?)null)); } [Fact] @@ -34,14 +34,14 @@ public static void Import_NullSource() { AssertExtensions.Throws("source", static () => MLDsa.ImportMLDsaPrivateSeed(MLDsaAlgorithm.MLDsa44, (byte[]?)null)); AssertExtensions.Throws("source", static () => MLDsa.ImportMLDsaPublicKey(MLDsaAlgorithm.MLDsa44, (byte[]?)null)); - AssertExtensions.Throws("source", static () => MLDsa.ImportMLDsaSecretKey(MLDsaAlgorithm.MLDsa44, (byte[]?)null)); + AssertExtensions.Throws("source", static () => MLDsa.ImportMLDsaPrivateKey(MLDsaAlgorithm.MLDsa44, (byte[]?)null)); } [Theory] [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] - public static void ImportMLDsaSecretKey_WrongSize(MLDsaAlgorithm algorithm) + public static void ImportMLDsaPrivateKey_WrongSize(MLDsaAlgorithm algorithm) { - int secretKeySize = algorithm.SecretKeySizeInBytes; + int privateKeySize = algorithm.PrivateKeySizeInBytes; // ML-DSA key size is wrong when importing algorithm key. Throw an argument exception. Action> assertDirectImport = import => AssertExtensions.Throws("source", import); @@ -50,9 +50,9 @@ public static void ImportMLDsaSecretKey_WrongSize(MLDsaAlgorithm algorithm) // Note: this is the algorithm key size, not the PKCS#8 key size. Action> assertEmbeddedImport = import => AssertThrowIfNotSupported(() => Assert.Throws(() => import())); - MLDsaTestHelpers.AssertImportSecretKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[secretKeySize + 1]); - MLDsaTestHelpers.AssertImportSecretKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[secretKeySize - 1]); - MLDsaTestHelpers.AssertImportSecretKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[0]); + MLDsaTestHelpers.AssertImportPrivateKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[privateKeySize + 1]); + MLDsaTestHelpers.AssertImportPrivateKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[privateKeySize - 1]); + MLDsaTestHelpers.AssertImportPrivateKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[0]); } [Theory] @@ -319,7 +319,7 @@ public static void ImportPkcs8PrivateKey_KeyErrorsInAsn() { Both = new MLDsaPrivateKeyBothAsn { - ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.SecretKeySizeInBytes], + ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.PrivateKeySizeInBytes], } }); @@ -328,7 +328,7 @@ public static void ImportPkcs8PrivateKey_KeyErrorsInAsn() Both = new MLDsaPrivateKeyBothAsn { Seed = new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes - 1], - ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.SecretKeySizeInBytes], + ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.PrivateKeySizeInBytes], } }); @@ -337,7 +337,7 @@ public static void ImportPkcs8PrivateKey_KeyErrorsInAsn() Both = new MLDsaPrivateKeyBothAsn { Seed = new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes], - ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.SecretKeySizeInBytes - 1], + ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.PrivateKeySizeInBytes - 1], } }); @@ -347,7 +347,7 @@ public static void ImportPkcs8PrivateKey_KeyErrorsInAsn() { // This will also fail because the seed and expanded key mismatch Seed = new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes], - ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.SecretKeySizeInBytes], + ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.PrivateKeySizeInBytes], } }); @@ -420,13 +420,13 @@ static void AssertThrows(string encryptedPem) public static void AlgorithmMatches_GenerateKey(MLDsaAlgorithm algorithm) { byte[] publicKey = new byte[algorithm.PublicKeySizeInBytes]; - byte[] secretKey = new byte[algorithm.SecretKeySizeInBytes]; + byte[] privateKey = new byte[algorithm.PrivateKeySizeInBytes]; byte[] privateSeed = new byte[algorithm.PrivateSeedSizeInBytes]; AssertThrowIfNotSupported(() => { using MLDsa mldsa = MLDsa.GenerateKey(algorithm); mldsa.ExportMLDsaPublicKey(publicKey); - mldsa.ExportMLDsaSecretKey(secretKey); + mldsa.ExportMLDsaPrivateKey(privateKey); mldsa.ExportMLDsaPrivateSeed(privateSeed); Assert.Equal(algorithm, mldsa.Algorithm); }); @@ -436,10 +436,10 @@ public static void AlgorithmMatches_GenerateKey(MLDsaAlgorithm algorithm) WithDispose(import(), mldsa => Assert.Equal(algorithm, mldsa.Algorithm))), algorithm, publicKey); - MLDsaTestHelpers.AssertImportSecretKey(import => + MLDsaTestHelpers.AssertImportPrivateKey(import => AssertThrowIfNotSupported(() => WithDispose(import(), mldsa => - Assert.Equal(algorithm, mldsa.Algorithm))), algorithm, secretKey); + Assert.Equal(algorithm, mldsa.Algorithm))), algorithm, privateKey); MLDsaTestHelpers.AssertImportPrivateSeed(import => AssertThrowIfNotSupported(() => @@ -462,12 +462,12 @@ public void RoundTrip_Import_Export_PublicKey(MLDsaKeyInfo info) [MemberData(nameof(MLDsaTestsData.IetfMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] public void RoundTrip_Import_Export_PrivateKey(MLDsaKeyInfo info) { - MLDsaTestHelpers.AssertImportSecretKey(import => - MLDsaTestHelpers.AssertExportMLDsaSecretKey(export => + MLDsaTestHelpers.AssertImportPrivateKey(import => + MLDsaTestHelpers.AssertExportMLDsaPrivateKey(export => WithDispose(import(), mldsa => - AssertExtensions.SequenceEqual(info.SecretKey, export(mldsa)))), + AssertExtensions.SequenceEqual(info.PrivateKey, export(mldsa)))), info.Algorithm, - info.SecretKey); + info.PrivateKey); } [Theory] @@ -540,9 +540,9 @@ public void RoundTrip_EncryptedPrivateKey(MLDsaKeyInfo info) // Load key using MLDsa mldsa = MLDsa.ImportEncryptedPkcs8PrivateKey(info.EncryptionPassword, info.Pkcs8EncryptedPrivateKey_Seed); - byte[] secretKey = new byte[mldsa.Algorithm.SecretKeySizeInBytes]; - mldsa.ExportMLDsaSecretKey(secretKey); - AssertExtensions.SequenceEqual(info.SecretKey, secretKey); + byte[] privateKey = new byte[mldsa.Algorithm.PrivateKeySizeInBytes]; + mldsa.ExportMLDsaPrivateKey(privateKey); + AssertExtensions.SequenceEqual(info.PrivateKey, privateKey); byte[] privateSeed = new byte[mldsa.Algorithm.PrivateSeedSizeInBytes]; mldsa.ExportMLDsaPrivateSeed(privateSeed); @@ -563,9 +563,9 @@ public void RoundTrip_EncryptedPrivateKey(MLDsaKeyInfo info) // The keys should be the same Assert.Equal(info.Algorithm, roundTrippedMLDsa.Algorithm); - byte[] roundTrippedSecretKey = new byte[roundTrippedMLDsa.Algorithm.SecretKeySizeInBytes]; - roundTrippedMLDsa.ExportMLDsaSecretKey(roundTrippedSecretKey); - AssertExtensions.SequenceEqual(secretKey, roundTrippedSecretKey); + byte[] roundTrippedPrivateKey = new byte[roundTrippedMLDsa.Algorithm.PrivateKeySizeInBytes]; + roundTrippedMLDsa.ExportMLDsaPrivateKey(roundTrippedPrivateKey); + AssertExtensions.SequenceEqual(privateKey, roundTrippedPrivateKey); byte[] roundTrippedPrivateSeed = new byte[roundTrippedMLDsa.Algorithm.PrivateSeedSizeInBytes]; roundTrippedMLDsa.ExportMLDsaPrivateSeed(roundTrippedPrivateSeed); @@ -585,9 +585,9 @@ public void RoundTrip_EncryptedPrivateKey(MLDsaKeyInfo info) // The keys should be the same Assert.Equal(info.Algorithm, roundTrippedMLDsa.Algorithm); - byte[] roundTrippedSecretKey = new byte[roundTrippedMLDsa.Algorithm.SecretKeySizeInBytes]; - roundTrippedMLDsa.ExportMLDsaSecretKey(roundTrippedSecretKey); - AssertExtensions.SequenceEqual(secretKey, roundTrippedSecretKey); + byte[] roundTrippedPrivateKey = new byte[roundTrippedMLDsa.Algorithm.PrivateKeySizeInBytes]; + roundTrippedMLDsa.ExportMLDsaPrivateKey(roundTrippedPrivateKey); + AssertExtensions.SequenceEqual(privateKey, roundTrippedPrivateKey); byte[] roundTrippedPrivateSeed = new byte[roundTrippedMLDsa.Algorithm.PrivateSeedSizeInBytes]; roundTrippedMLDsa.ExportMLDsaPrivateSeed(roundTrippedPrivateSeed); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.Cng.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.Cng.cs index 8fcf7963476578..f4b585f8343c44 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.Cng.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.Cng.cs @@ -52,7 +52,7 @@ internal static MLDsaCng ImportPrivateSeed(MLDsaAlgorithm algorithm, ReadOnlySpa return new MLDsaCng(key); } - internal static MLDsaCng ImportSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan source, CngExportPolicies exportPolicies) + internal static MLDsaCng ImportPrivateKey(MLDsaAlgorithm algorithm, ReadOnlySpan source, CngExportPolicies exportPolicies) { CngKey key = PqcBlobHelpers.EncodeMLDsaBlob( PqcBlobHelpers.GetMLDsaParameterSet(algorithm), diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.cs index a03ec55bca7eed..d0a645563b02f4 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.cs @@ -14,11 +14,10 @@ internal static partial class MLDsaTestHelpers { internal static bool MLDsaIsNotSupported => !MLDsa.IsSupported; - // TODO: Windows does not support draft 10 PKCS#8 format yet. Remove this and use MLDsa.IsSupported (or remove condition) when it does. - internal static bool SupportsDraft10Pkcs8 => MLDsa.IsSupported && !PlatformDetection.IsWindows; + // TODO (https://github.com/dotnet/runtime/issues/118609): Windows currently does not support PKCS#8 export when imported as private key. + internal static bool SupportsExportingPrivateKeyPkcs8 => MLDsa.IsSupported && !PlatformDetection.IsWindows; - // TODO: Windows does not support signing empty data. Remove this and use MLDsa.IsSupported (or remove condition) when it does. - internal static bool SigningEmptyDataIsSupported => MLDsa.IsSupported && !PlatformDetection.IsWindows; + internal static bool ExternalMuIsSupported => MLDsa.IsSupported && !PlatformDetection.IsWindows; // DER encoding of ASN.1 BitString "foo" internal static readonly ReadOnlyMemory s_derBitStringFoo = new byte[] { 0x03, 0x04, 0x00, 0x66, 0x6f, 0x6f }; @@ -28,29 +27,48 @@ internal static partial class MLDsaTestHelpers internal static void VerifyDisposed(MLDsa mldsa) { PbeParameters pbeParams = new PbeParameters(PbeEncryptionAlgorithm.Aes128Cbc, HashAlgorithmName.SHA256, 10); - - Assert.Throws(() => mldsa.SignData(ReadOnlySpan.Empty, new byte[mldsa.Algorithm.SignatureSizeInBytes])); - Assert.Throws(() => mldsa.VerifyData(ReadOnlySpan.Empty, new byte[mldsa.Algorithm.SignatureSizeInBytes])); - + byte[] signature = new byte[mldsa.Algorithm.SignatureSizeInBytes]; + byte[] bigBuffer = new byte[10000]; + byte[] mu = new byte[64]; + + Assert.Throws(() => mldsa.SignData(Array.Empty())); + Assert.Throws(() => mldsa.SignData(ReadOnlySpan.Empty, signature)); + Assert.Throws(() => mldsa.VerifyData(Array.Empty(), signature)); + Assert.Throws(() => mldsa.VerifyData(ReadOnlySpan.Empty, signature)); + Assert.Throws(() => mldsa.SignPreHash(mu, HashInfo.Sha512.Oid)); + Assert.Throws(() => mldsa.SignPreHash(mu, signature, HashInfo.Sha512.Oid)); + Assert.Throws(() => mldsa.VerifyPreHash(mu, signature, HashInfo.Sha512.Oid)); + Assert.Throws(() => mldsa.VerifyPreHash(new ReadOnlySpan(mu), signature, HashInfo.Sha512.Oid)); + Assert.Throws(() => mldsa.SignMu(mu)); + Assert.Throws(() => mldsa.SignMu(new ReadOnlySpan(mu))); + Assert.Throws(() => mldsa.VerifyMu(mu, signature)); + Assert.Throws(() => mldsa.VerifyMu(new ReadOnlySpan(mu), signature)); + + Assert.Throws(() => mldsa.ExportMLDsaPrivateSeed()); Assert.Throws(() => mldsa.ExportMLDsaPrivateSeed(new byte[mldsa.Algorithm.PrivateSeedSizeInBytes])); + Assert.Throws(() => mldsa.ExportMLDsaPublicKey()); Assert.Throws(() => mldsa.ExportMLDsaPublicKey(new byte[mldsa.Algorithm.PublicKeySizeInBytes])); - Assert.Throws(() => mldsa.ExportMLDsaSecretKey(new byte[mldsa.Algorithm.SecretKeySizeInBytes])); + Assert.Throws(() => mldsa.ExportMLDsaPrivateKey()); + Assert.Throws(() => mldsa.ExportMLDsaPrivateKey(new byte[mldsa.Algorithm.PrivateKeySizeInBytes])); Assert.Throws(() => mldsa.ExportPkcs8PrivateKey()); - Assert.Throws(() => mldsa.TryExportPkcs8PrivateKey(new byte[10000], out _)); + Assert.Throws(() => mldsa.TryExportPkcs8PrivateKey(bigBuffer, out _)); Assert.Throws(() => mldsa.ExportPkcs8PrivateKeyPem()); Assert.Throws(() => mldsa.ExportEncryptedPkcs8PrivateKey([1, 2, 3], pbeParams)); Assert.Throws(() => mldsa.ExportEncryptedPkcs8PrivateKey("123", pbeParams)); - Assert.Throws(() => mldsa.TryExportEncryptedPkcs8PrivateKey([1, 2, 3], pbeParams, new byte[10000], out _)); - Assert.Throws(() => mldsa.TryExportEncryptedPkcs8PrivateKey("123", pbeParams, new byte[10000], out _)); + Assert.Throws(() => mldsa.TryExportEncryptedPkcs8PrivateKey([1, 2, 3], pbeParams, bigBuffer, out _)); + Assert.Throws(() => mldsa.TryExportEncryptedPkcs8PrivateKey("123", pbeParams, bigBuffer, out _)); Assert.Throws(() => mldsa.ExportEncryptedPkcs8PrivateKeyPem([1, 2, 3], pbeParams)); Assert.Throws(() => mldsa.ExportEncryptedPkcs8PrivateKeyPem("123", pbeParams)); Assert.Throws(() => mldsa.ExportSubjectPublicKeyInfo()); - Assert.Throws(() => mldsa.TryExportSubjectPublicKeyInfo(new byte[10000], out _)); + Assert.Throws(() => mldsa.TryExportSubjectPublicKeyInfo(bigBuffer, out _)); Assert.Throws(() => mldsa.ExportSubjectPublicKeyInfoPem()); + + // Doesn't throw: + Assert.NotNull(mldsa.Algorithm); } internal static void AssertImportPublicKey(Action> test, MLDsaAlgorithm algorithm, byte[] publicKey) => @@ -100,31 +118,31 @@ internal static void AssertImportSubjectKeyPublicInfo( testEmbeddedCall(spki => MLDsa.ImportFromPem(PemEncoding.WriteString("PUBLIC KEY", spki).AsSpan())); } - internal static void AssertImportSecretKey(Action> test, MLDsaAlgorithm algorithm, byte[] secretKey) => - AssertImportSecretKey(test, test, algorithm, secretKey); + internal static void AssertImportPrivateKey(Action> test, MLDsaAlgorithm algorithm, byte[] privateKey) => + AssertImportPrivateKey(test, test, algorithm, privateKey); - internal static void AssertImportSecretKey(Action> testDirectCall, Action> testEmbeddedCall, MLDsaAlgorithm algorithm, byte[] secretKey) + internal static void AssertImportPrivateKey(Action> testDirectCall, Action> testEmbeddedCall, MLDsaAlgorithm algorithm, byte[] privateKey) { - testDirectCall(() => MLDsa.ImportMLDsaSecretKey(algorithm, secretKey)); + testDirectCall(() => MLDsa.ImportMLDsaPrivateKey(algorithm, privateKey)); - if (secretKey?.Length == 0) + if (privateKey?.Length == 0) { - testDirectCall(() => MLDsa.ImportMLDsaSecretKey(algorithm, Array.Empty().AsSpan())); - testDirectCall(() => MLDsa.ImportMLDsaSecretKey(algorithm, ReadOnlySpan.Empty)); - testDirectCall(() => MLDsa.ImportMLDsaSecretKey(algorithm, default(ReadOnlySpan))); + testDirectCall(() => MLDsa.ImportMLDsaPrivateKey(algorithm, Array.Empty().AsSpan())); + testDirectCall(() => MLDsa.ImportMLDsaPrivateKey(algorithm, ReadOnlySpan.Empty)); + testDirectCall(() => MLDsa.ImportMLDsaPrivateKey(algorithm, default(ReadOnlySpan))); } else { - testDirectCall(() => MLDsa.ImportMLDsaSecretKey(algorithm, secretKey)); - testDirectCall(() => MLDsa.ImportMLDsaSecretKey(algorithm, secretKey.AsSpan())); + testDirectCall(() => MLDsa.ImportMLDsaPrivateKey(algorithm, privateKey)); + testDirectCall(() => MLDsa.ImportMLDsaPrivateKey(algorithm, privateKey.AsSpan())); } AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - MLDsaPrivateKeyAsn privateKey = new MLDsaPrivateKeyAsn + MLDsaPrivateKeyAsn privateKeyAsn = new MLDsaPrivateKeyAsn { - ExpandedKey = secretKey + ExpandedKey = privateKey }; - privateKey.Encode(writer); + privateKeyAsn.Encode(writer); PrivateKeyInfoAsn pkcs8 = new PrivateKeyInfoAsn { @@ -140,8 +158,8 @@ internal static void AssertImportSecretKey(Action> testDirectCall, A testEmbeddedCall(() => import(pkcs8.Encode()))); } - internal static void AssertImportPrivateSeed(Action> test, MLDsaAlgorithm algorithm, byte[] secretKey) => - AssertImportPrivateSeed(test, test, algorithm, secretKey); + internal static void AssertImportPrivateSeed(Action> test, MLDsaAlgorithm algorithm, byte[] privateSeed) => + AssertImportPrivateSeed(test, test, algorithm, privateSeed); internal static void AssertImportPrivateSeed(Action> testDirectCall, Action> testEmbeddedCall, MLDsaAlgorithm algorithm, byte[] privateSeed) { @@ -270,42 +288,25 @@ internal static void AssertExportMLDsaPublicKey(Action> call SubjectPublicKeyInfoAsn.Decode(exportSpki(mldsa), AsnEncodingRules.DER).SubjectPublicKey.Span.ToArray())); } - internal static void AssertExportMLDsaSecretKey(Action> callback) => - AssertExportMLDsaSecretKey(callback, callback); + internal static void AssertExportMLDsaPrivateKey(Action> callback) => + AssertExportMLDsaPrivateKey(callback, callback); - internal static void AssertExportMLDsaSecretKey(Action> directCallback, Action> indirectCallback) + internal static void AssertExportMLDsaPrivateKey(Action> directCallback, Action> indirectCallback) { directCallback(mldsa => { - byte[] buffer = new byte[mldsa.Algorithm.SecretKeySizeInBytes]; - mldsa.ExportMLDsaSecretKey(buffer.AsSpan()); + byte[] buffer = new byte[mldsa.Algorithm.PrivateKeySizeInBytes]; + mldsa.ExportMLDsaPrivateKey(buffer.AsSpan()); return buffer; }); AssertExportPkcs8PrivateKey(exportPkcs8 => indirectCallback(mldsa => - DecodeExpandedKey( - mldsa, + MLDsaPrivateKeyAsn.Decode( PrivateKeyInfoAsn.Decode( exportPkcs8(mldsa), AsnEncodingRules.DER).PrivateKey, AsnEncodingRules.DER).ExpandedKey?.ToArray())); } - // TODO remove this when windows supports draft 10 PKCS#8 format - internal static MLDsaPrivateKeyAsn DecodeExpandedKey(MLDsa mldsa, ReadOnlyMemory encoded, AsnEncodingRules ruleSet) - { - try - { - return MLDsaPrivateKeyAsn.Decode(encoded, ruleSet); - } - catch (CryptographicException) when (!SupportsDraft10Pkcs8) - { - return new MLDsaPrivateKeyAsn - { - ExpandedKey = (mldsa.Algorithm.SecretKeySizeInBytes == encoded.Length) ? encoded : default(ReadOnlyMemory?), - }; - } - } - internal static void AssertExportMLDsaPrivateSeed(Action> callback) => AssertExportMLDsaPrivateSeed(callback, callback); @@ -320,28 +321,11 @@ internal static void AssertExportMLDsaPrivateSeed(Action> di AssertExportPkcs8PrivateKey(exportPkcs8 => indirectCallback(mldsa => - DecodePrivateSeed( - mldsa, + MLDsaPrivateKeyAsn.Decode( PrivateKeyInfoAsn.Decode( exportPkcs8(mldsa), AsnEncodingRules.DER).PrivateKey, AsnEncodingRules.DER).Seed?.ToArray())); } - // TODO remove this when windows supports draft 10 PKCS#8 format - internal static MLDsaPrivateKeyAsn DecodePrivateSeed(MLDsa mldsa, ReadOnlyMemory encoded, AsnEncodingRules ruleSet) - { - try - { - return MLDsaPrivateKeyAsn.Decode(encoded, ruleSet); - } - catch (CryptographicException) when (!SupportsDraft10Pkcs8) - { - return new MLDsaPrivateKeyAsn - { - Seed = (mldsa.Algorithm.PrivateSeedSizeInBytes == encoded.Length) ? encoded : default(ReadOnlyMemory?), - }; - } - } - internal static void AssertExportPkcs8PrivateKey(MLDsa mldsa, Action callback) => AssertExportPkcs8PrivateKey(export => callback(export(mldsa))); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestImplementation.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestImplementation.cs index 8652e58af24916..1057f300e64635 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestImplementation.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestImplementation.cs @@ -11,21 +11,34 @@ internal sealed class MLDsaTestImplementation : MLDsa internal delegate bool TryExportFunc(Span destination, out int bytesWritten); internal delegate void SignAction(ReadOnlySpan data, ReadOnlySpan context, Span destination); internal delegate bool VerifyFunc(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature); + internal delegate void SignPreHashAction(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination); + internal delegate bool VerifyPreHashFunc(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature); + internal delegate void SignMuAction(ReadOnlySpan mu, Span destination); + internal delegate bool VerifyMuFunc(ReadOnlySpan mu, ReadOnlySpan signature); internal int VerifyDataCoreCallCount = 0; internal int SignDataCoreCallCount = 0; + internal int SignPreHashCoreCallCount = 0; + internal int VerifyPreHashCoreCallCount = 0; + internal int OpenExternalMuHashCoreCallCount = 0; + internal int SignMuCoreCallCount = 0; + internal int VerifyMuCoreCallCount = 0; internal int ExportMLDsaPrivateSeedCoreCallCount = 0; internal int ExportMLDsaPublicKeyCoreCallCount = 0; - internal int ExportMLDsaSecretKeyCoreCallCount = 0; + internal int ExportMLDsaPrivateKeyCoreCallCount = 0; internal int TryExportPkcs8PrivateKeyCoreCallCount = 0; internal int DisposeCallCount = 0; internal ExportAction ExportMLDsaPrivateSeedHook { get; set; } internal ExportAction ExportMLDsaPublicKeyHook { get; set; } - internal ExportAction ExportMLDsaSecretKeyHook { get; set; } + internal ExportAction ExportMLDsaPrivateKeyHook { get; set; } internal TryExportFunc TryExportPkcs8PrivateKeyHook { get; set; } internal SignAction SignDataHook { get; set; } internal VerifyFunc VerifyDataHook { get; set; } + internal SignPreHashAction SignPreHashHook { get; set; } + internal VerifyPreHashFunc VerifyPreHashHook { get; set; } + internal SignMuAction SignMuHook { get; set; } + internal VerifyMuFunc VerifyMuHook { get; set; } internal Action DisposeHook { get; set; } private MLDsaTestImplementation(MLDsaAlgorithm algorithm) : base(algorithm) @@ -50,10 +63,10 @@ protected override void ExportMLDsaPublicKeyCore(Span destination) ExportMLDsaPublicKeyHook(destination); } - protected override void ExportMLDsaSecretKeyCore(Span destination) + protected override void ExportMLDsaPrivateKeyCore(Span destination) { - ExportMLDsaSecretKeyCoreCallCount++; - ExportMLDsaSecretKeyHook(destination); + ExportMLDsaPrivateKeyCoreCallCount++; + ExportMLDsaPrivateKeyHook(destination); } protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) @@ -74,15 +87,43 @@ protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) + { + SignPreHashCoreCallCount++; + SignPreHashHook(hash, context, hashAlgorithmOid, destination); + } + + protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) + { + VerifyPreHashCoreCallCount++; + return VerifyPreHashHook(hash, context, hashAlgorithmOid, signature); + } + + protected override void SignMuCore(ReadOnlySpan externalMu, Span destination) + { + SignMuCoreCallCount++; + SignMuHook(externalMu, destination); + } + + protected override bool VerifyMuCore(ReadOnlySpan externalMu, ReadOnlySpan signature) + { + VerifyMuCoreCallCount++; + return VerifyMuHook(externalMu, signature); + } + internal static MLDsaTestImplementation CreateOverriddenCoreMethodsFail(MLDsaAlgorithm algorithm) { return new MLDsaTestImplementation(algorithm) { ExportMLDsaPrivateSeedHook = _ => Assert.Fail(), ExportMLDsaPublicKeyHook = _ => Assert.Fail(), - ExportMLDsaSecretKeyHook = _ => Assert.Fail(), + ExportMLDsaPrivateKeyHook = _ => Assert.Fail(), SignDataHook = (_, _, _) => Assert.Fail(), + SignPreHashHook = delegate { Assert.Fail(); }, + SignMuHook = (_, _) => Assert.Fail(), VerifyDataHook = (_, _, _) => { Assert.Fail(); return false; }, + VerifyPreHashHook = (_, _, _, _) => { Assert.Fail(); return false; }, + VerifyMuHook = (_, _) => { Assert.Fail(); return false; }, DisposeHook = _ => { }, TryExportPkcs8PrivateKeyHook = (_, out bytesWritten) => @@ -100,9 +141,13 @@ internal static MLDsaTestImplementation CreateNoOp(MLDsaAlgorithm algorithm) { ExportMLDsaPrivateSeedHook = d => d.Clear(), ExportMLDsaPublicKeyHook = d => d.Clear(), - ExportMLDsaSecretKeyHook = d => d.Clear(), + ExportMLDsaPrivateKeyHook = d => d.Clear(), SignDataHook = (data, context, destination) => destination.Clear(), VerifyDataHook = (data, context, signature) => false, + SignPreHashHook = (hash, context, hashAlgorithmOid, destination) => destination.Clear(), + VerifyPreHashHook = (hash, context, hashAlgorithmOid, signature) => false, + SignMuHook = (mu, destination) => destination.Clear(), + VerifyMuHook = (mu, signature) => false, DisposeHook = _ => { }, TryExportPkcs8PrivateKeyHook = (Span destination, out int bytesWritten) => @@ -120,7 +165,7 @@ internal static MLDsaTestImplementation Wrap(MLDsa other) { ExportMLDsaPrivateSeedHook = d => other.ExportMLDsaPrivateSeed(d), ExportMLDsaPublicKeyHook = d => other.ExportMLDsaPublicKey(d), - ExportMLDsaSecretKeyHook = d => other.ExportMLDsaSecretKey(d), + ExportMLDsaPrivateKeyHook = d => other.ExportMLDsaPrivateKey(d), SignDataHook = (data, context, destination) => other.SignData(data, destination, context), VerifyDataHook = (data, context, signature) => other.VerifyData(data, signature, context), DisposeHook = _ => other.Dispose(), @@ -147,11 +192,11 @@ public void AddLengthAssertion() Assert.Equal(Algorithm.PublicKeySizeInBytes, destination.Length); }; - ExportAction oldExportMLDsaSecretKeyHook = ExportMLDsaSecretKeyHook; - ExportMLDsaSecretKeyHook = (Span destination) => + ExportAction oldExportMLDsaPrivateKeyHook = ExportMLDsaPrivateKeyHook; + ExportMLDsaPrivateKeyHook = (Span destination) => { - oldExportMLDsaSecretKeyHook(destination); - Assert.Equal(Algorithm.SecretKeySizeInBytes, destination.Length); + oldExportMLDsaPrivateKeyHook(destination); + Assert.Equal(Algorithm.PrivateKeySizeInBytes, destination.Length); }; SignAction oldSignDataHook = SignDataHook; @@ -168,6 +213,38 @@ public void AddLengthAssertion() Assert.Equal(Algorithm.SignatureSizeInBytes, signature.Length); return ret; }; + + SignPreHashAction oldSignPreHashCoreHook = SignPreHashHook; + SignPreHashHook = (ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => + { + oldSignDataHook(hash, context, destination); + Assert.Equal(Algorithm.SignatureSizeInBytes, destination.Length); + }; + + VerifyPreHashFunc oldVerifyPreHashHook = VerifyPreHashHook; + VerifyPreHashHook = (ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => + { + bool ret = oldVerifyPreHashHook(hash, context, hashAlgorithmOid, signature); + Assert.Equal(Algorithm.SignatureSizeInBytes, signature.Length); + return ret; + }; + + SignMuAction oldSignExternalMuHook = SignMuHook; + SignMuHook = (ReadOnlySpan mu, Span destination) => + { + oldSignExternalMuHook(mu, destination); + Assert.Equal(64, mu.Length); + Assert.Equal(Algorithm.SignatureSizeInBytes, destination.Length); + }; + + VerifyMuFunc oldVerifyExternalMuHook = VerifyMuHook; + VerifyMuHook = (ReadOnlySpan mu, ReadOnlySpan signature) => + { + bool ret = oldVerifyExternalMuHook(mu, signature); + Assert.Equal(64, mu.Length); + Assert.Equal(Algorithm.SignatureSizeInBytes, signature.Length); + return ret; + }; } public void AddDestinationBufferIsSameAssertion(ReadOnlyMemory buffer) @@ -186,10 +263,10 @@ public void AddDestinationBufferIsSameAssertion(ReadOnlyMemory buffer) AssertExtensions.Same(buffer.Span, destination); }; - ExportAction oldExportMLDsaSecretKeyHook = ExportMLDsaSecretKeyHook; - ExportMLDsaSecretKeyHook = (Span destination) => + ExportAction oldExportMLDsaPrivateKeyHook = ExportMLDsaPrivateKeyHook; + ExportMLDsaPrivateKeyHook = (Span destination) => { - oldExportMLDsaSecretKeyHook(destination); + oldExportMLDsaPrivateKeyHook(destination); AssertExtensions.Same(buffer.Span, destination); }; @@ -200,6 +277,13 @@ public void AddDestinationBufferIsSameAssertion(ReadOnlyMemory buffer) AssertExtensions.Same(buffer.Span, destination); }; + SignPreHashAction oldSignPreHashCoreHook = SignPreHashHook; + SignPreHashHook = (ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => + { + oldSignPreHashCoreHook(hash, context, hashAlgorithmOid, destination); + AssertExtensions.Same(buffer.Span, destination); + }; + TryExportFunc oldTryExportPkcs8PrivateKeyHook = TryExportPkcs8PrivateKeyHook; TryExportPkcs8PrivateKeyHook = (Span destination, out int bytesWritten) => { @@ -225,6 +309,21 @@ public void AddContextBufferIsSameAssertion(ReadOnlyMemory buffer) AssertExtensions.Same(buffer.Span, context); return ret; }; + + SignPreHashAction oldSignPreHashCoreHook = SignPreHashHook; + SignPreHashHook = (ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => + { + oldSignPreHashCoreHook(hash, context, hashAlgorithmOid, destination); + AssertExtensions.Same(buffer.Span, context); + }; + + VerifyPreHashFunc oldVerifyPreHashCoreHook = VerifyPreHashHook; + VerifyPreHashHook = (ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => + { + bool ret = oldVerifyPreHashCoreHook(hash, context, hashAlgorithmOid, signature); + AssertExtensions.Same(buffer.Span, context); + return ret; + }; } public void AddSignatureBufferIsSameAssertion(ReadOnlyMemory buffer) @@ -236,6 +335,14 @@ public void AddSignatureBufferIsSameAssertion(ReadOnlyMemory buffer) AssertExtensions.Same(buffer.Span, signature); return ret; }; + + VerifyPreHashFunc oldVerifyPreHashCoreHook = VerifyPreHashHook; + VerifyPreHashHook = (ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => + { + bool ret = oldVerifyPreHashCoreHook(hash, context, hashAlgorithmOid, signature); + AssertExtensions.Same(buffer.Span, signature); + return ret; + }; } public void AddDataBufferIsSameAssertion(ReadOnlyMemory buffer) @@ -254,6 +361,54 @@ public void AddDataBufferIsSameAssertion(ReadOnlyMemory buffer) AssertExtensions.Same(buffer.Span, data); return ret; }; + + SignPreHashAction oldSignPreHashCoreHook = SignPreHashHook; + SignPreHashHook = (ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => + { + oldSignPreHashCoreHook(hash, context, hashAlgorithmOid, destination); + AssertExtensions.Same(buffer.Span, hash); + }; + + VerifyPreHashFunc oldVerifyPreHashCoreHook = VerifyPreHashHook; + VerifyPreHashHook = (ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => + { + bool ret = oldVerifyPreHashCoreHook(hash, context, hashAlgorithmOid, signature); + AssertExtensions.Same(buffer.Span, hash); + return ret; + }; + + SignMuAction oldSignExternalMuHook = SignMuHook; + SignMuHook = (ReadOnlySpan mu, Span destination) => + { + oldSignExternalMuHook(mu, destination); + AssertExtensions.Same(buffer.Span, mu); + }; + + VerifyMuFunc oldVerifyExternalMuHook = VerifyMuHook; + VerifyMuHook = (ReadOnlySpan mu, ReadOnlySpan signature) => + { + bool ret = oldVerifyExternalMuHook(mu, signature); + AssertExtensions.Same(buffer.Span, mu); + return ret; + }; + } + + public void AddHashAlgorithmIsSameAssertion(ReadOnlyMemory buffer) + { + SignPreHashAction oldSignPreHashCoreHook = SignPreHashHook; + SignPreHashHook = (ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => + { + oldSignPreHashCoreHook(hash, context, hashAlgorithmOid, destination); + AssertExtensions.Same(buffer.Span, hashAlgorithmOid); + }; + + VerifyPreHashFunc oldVerifyPreHashCoreHook = VerifyPreHashHook; + VerifyPreHashHook = (ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => + { + bool ret = oldVerifyPreHashCoreHook(hash, context, hashAlgorithmOid, signature); + AssertExtensions.Same(buffer.Span, hashAlgorithmOid); + return ret; + }; } public void AddFillDestination(byte b) @@ -272,10 +427,10 @@ public void AddFillDestination(byte b) destination.Fill(b); }; - ExportAction oldExportMLDsaSecretKeyHook = ExportMLDsaSecretKeyHook; - ExportMLDsaSecretKeyHook = (Span destination) => + ExportAction oldExportMLDsaPrivateKeyHook = ExportMLDsaPrivateKeyHook; + ExportMLDsaPrivateKeyHook = (Span destination) => { - oldExportMLDsaSecretKeyHook(destination); + oldExportMLDsaPrivateKeyHook(destination); destination.Fill(b); }; @@ -286,6 +441,13 @@ public void AddFillDestination(byte b) destination.Fill(b); }; + SignPreHashAction oldSignPreHashCoreHook = SignPreHashHook; + SignPreHashHook = (ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => + { + oldSignPreHashCoreHook(hash, context, hashAlgorithmOid, destination); + destination.Fill(b); + }; + TryExportFunc oldTryExportPkcs8PrivateKeyHook = TryExportPkcs8PrivateKeyHook; TryExportPkcs8PrivateKeyHook = (Span destination, out int bytesWritten) => { diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTests.cs index 6f276d089d798e..a07bd1a9931042 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTests.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Security.Cryptography.Asn1; using Microsoft.DotNet.RemoteExecutor; -using Microsoft.DotNet.XUnitExtensions; using Test.Cryptography; using Xunit; @@ -74,10 +73,22 @@ public static void NullArgumentValidation(MLDsaAlgorithm algorithm, bool shouldD PbeParameters pbeParameters = new PbeParameters(PbeEncryptionAlgorithm.TripleDes3KeyPkcs12, HashAlgorithmName.SHA1, 42); + byte[] hash = [1, 2, 3, 4]; + byte[] signature = [5, 6, 7, 8]; AssertExtensions.Throws("data", () => mldsa.SignData(null)); AssertExtensions.Throws("data", () => mldsa.VerifyData(null, null)); AssertExtensions.Throws("signature", () => mldsa.VerifyData(Array.Empty(), null)); + AssertExtensions.Throws("hash", () => mldsa.SignPreHash(null, null)); + AssertExtensions.Throws("hashAlgorithmOid", () => mldsa.SignPreHash([1, 2, 3, 4], null)); + AssertExtensions.Throws("hash", () => mldsa.VerifyPreHash(null, null, null)); + AssertExtensions.Throws("signature", () => mldsa.VerifyPreHash(hash, null, null)); + AssertExtensions.Throws("hashAlgorithmOid", () => mldsa.VerifyPreHash(hash, signature, null)); + + AssertExtensions.Throws("externalMu", () => mldsa.SignMu(null)); + AssertExtensions.Throws("externalMu", () => mldsa.VerifyMu(null, null)); + AssertExtensions.Throws("signature", () => mldsa.VerifyMu(Array.Empty(), null)); + AssertExtensions.Throws("password", () => mldsa.ExportEncryptedPkcs8PrivateKey((string)null, pbeParameters)); AssertExtensions.Throws("password", () => mldsa.ExportEncryptedPkcs8PrivateKeyPem((string)null, pbeParameters)); AssertExtensions.Throws("password", () => mldsa.TryExportEncryptedPkcs8PrivateKey((string)null, pbeParameters, Span.Empty, out _)); @@ -100,9 +111,16 @@ public static void ArgumentValidation(MLDsaAlgorithm algorithm, bool shouldDispo using MLDsa mldsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(algorithm); int publicKeySize = algorithm.PublicKeySizeInBytes; - int secretKeySize = algorithm.SecretKeySizeInBytes; + int privateKeySize = algorithm.PrivateKeySizeInBytes; int privateSeedSize = algorithm.PrivateSeedSizeInBytes; int signatureSize = algorithm.SignatureSizeInBytes; + byte[] signature = new byte[signatureSize]; + byte[] hash = new byte[HashInfo.Sha256.OutputSize]; + byte[] mu = new byte[64]; + byte[] shortMu = new byte[mu.Length - 1]; + byte[] longMu = new byte[mu.Length + 1]; + byte[] shortSignature = new byte[signatureSize - 1]; + byte[] longSignature = new byte[signatureSize + 1]; if (shouldDispose) { @@ -112,18 +130,207 @@ public static void ArgumentValidation(MLDsaAlgorithm algorithm, bool shouldDispo AssertExtensions.Throws("destination", () => mldsa.ExportMLDsaPublicKey(new byte[publicKeySize - 1])); AssertExtensions.Throws("destination", () => mldsa.ExportMLDsaPublicKey(new byte[publicKeySize + 1])); - AssertExtensions.Throws("destination", () => mldsa.ExportMLDsaSecretKey(new byte[secretKeySize - 1])); - AssertExtensions.Throws("destination", () => mldsa.ExportMLDsaSecretKey(new byte[secretKeySize + 1])); + AssertExtensions.Throws("destination", () => mldsa.ExportMLDsaPrivateKey(new byte[privateKeySize - 1])); + AssertExtensions.Throws("destination", () => mldsa.ExportMLDsaPrivateKey(new byte[privateKeySize + 1])); AssertExtensions.Throws("destination", () => mldsa.ExportMLDsaPrivateSeed(new byte[privateSeedSize - 1])); 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.SignData(ReadOnlySpan.Empty, shortSignature, ReadOnlySpan.Empty)); + AssertExtensions.Throws("destination", () => mldsa.SignData(ReadOnlySpan.Empty, longSignature, ReadOnlySpan.Empty)); + AssertExtensions.Throws("destination", () => mldsa.SignMu(mu, shortSignature)); + AssertExtensions.Throws("destination", () => mldsa.SignMu(mu, longSignature)); + AssertExtensions.Throws("destination", () => mldsa.SignPreHash(new byte[HashInfo.Sha512.OutputSize], shortSignature, HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); + AssertExtensions.Throws("destination", () => mldsa.SignPreHash(new byte[HashInfo.Sha512.OutputSize], longSignature, HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); // Context length must be less than 256 - AssertExtensions.Throws("context", () => mldsa.SignData(ReadOnlySpan.Empty, new byte[signatureSize], new byte[256])); - AssertExtensions.Throws("context", () => mldsa.SignData(Array.Empty(), new byte[signatureSize], new byte[256])); - AssertExtensions.Throws("context", () => mldsa.VerifyData(ReadOnlySpan.Empty, new byte[signatureSize], new byte[256])); - AssertExtensions.Throws("context", () => mldsa.VerifyData(Array.Empty(), new byte[signatureSize], new byte[256])); + AssertExtensions.Throws("context", () => mldsa.SignData(ReadOnlySpan.Empty, signature, new byte[256])); + AssertExtensions.Throws("context", () => mldsa.SignData(Array.Empty(), signature, new byte[256])); + AssertExtensions.Throws("context", () => mldsa.VerifyData(ReadOnlySpan.Empty, signature, new byte[256])); + AssertExtensions.Throws("context", () => mldsa.VerifyData(Array.Empty(), signature, new byte[256])); + AssertExtensions.Throws("context", () => mldsa.SignPreHash(hash.AsSpan(), signature, HashInfo.Sha256.Oid, new byte[256])); + AssertExtensions.Throws("context", () => mldsa.SignPreHash(hash, HashInfo.Sha256.Oid, new byte[256])); + + // Mu must be the correct size + AssertExtensions.Throws("externalMu", () => mldsa.SignMu(shortMu)); + AssertExtensions.Throws("externalMu", () => mldsa.SignMu(longMu)); + AssertExtensions.Throws("externalMu", () => mldsa.SignMu(shortMu, signature)); + AssertExtensions.Throws("externalMu", () => mldsa.SignMu(longMu, signature)); + + // Hash length of known OID hash algorithms must be correct + 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.SignPreHash([1], string.Empty)); + Assert.Throws(() => mldsa.SignPreHash([1], signature, "-1.0.0")); + } + + public static IEnumerable ArgumentValidation_Hash_WrongSizeInputs() + { + foreach (bool shouldDispose in new[] { true, false }) + { + foreach (HashInfo hashInfo in HashInfo.AllHashInfos()) + { + yield return new object[] { shouldDispose, hashInfo }; + } + } + } + + [Theory] + [MemberData(nameof(ArgumentValidation_Hash_WrongSizeInputs))] + public static void ArgumentValidation_Hash_WrongSize(bool shouldDispose, HashInfo hashInfo) + { + using MLDsa mlDsa = MLDsaTestImplementation.CreateNoOp(MLDsaAlgorithm.MLDsa44); + + if (shouldDispose) + { + // Test that argument validation exceptions take precedence over ObjectDisposedException + mlDsa.Dispose(); + } + + byte[] signature = new byte[MLDsaAlgorithm.MLDsa44.SignatureSizeInBytes]; + + Assert.Throws(() => mlDsa.SignPreHash(new byte[hashInfo.OutputSize - 1], hashInfo.Oid)); + Assert.Throws(() => mlDsa.SignPreHash(new byte[hashInfo.OutputSize + 1], hashInfo.Oid)); + Assert.Throws(() => mlDsa.SignPreHash(new byte[hashInfo.OutputSize - 1], signature, hashInfo.Oid)); + Assert.Throws(() => mlDsa.SignPreHash(new byte[hashInfo.OutputSize + 1], signature, hashInfo.Oid)); + + Assert.Throws(() => mlDsa.VerifyPreHash(new byte[hashInfo.OutputSize - 1], signature, hashInfo.Oid)); + Assert.Throws(() => mlDsa.VerifyPreHash(new byte[hashInfo.OutputSize + 1], signature, hashInfo.Oid)); + Assert.Throws(() => mlDsa.VerifyPreHash(new byte[hashInfo.OutputSize - 1], signature.AsSpan(), hashInfo.Oid)); + Assert.Throws(() => mlDsa.VerifyPreHash(new byte[hashInfo.OutputSize + 1], signature.AsSpan(), hashInfo.Oid)); + } + + [Fact] + public static void ArgumentValidation_HashAlgorithm_UnknownOidDoesNotCallCore() + { + using MLDsaTestImplementation mlDsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44); + + byte[] signature = new byte[MLDsaAlgorithm.MLDsa44.SignatureSizeInBytes]; + string hashAlgorithmOid = "1.0"; + CryptographicException ce = Assert.Throws(() => mlDsa.SignPreHash([], hashAlgorithmOid)); + Assert.Contains(hashAlgorithmOid, ce.Message); + } + + public static IEnumerable AllHashesAndLengths() + { + foreach (HashInfo hashInfo in HashInfo.AllHashInfos()) + { + yield return new object[] { hashInfo.Oid, hashInfo.OutputSize }; + } + } + + [Theory] + [MemberData(nameof(AllHashesAndLengths))] + public static void SignPreHash_CallsCore(string hashAlgorithmOid, int hashLength) + { + MLDsaAlgorithm algorithm = MLDsaAlgorithm.MLDsa44; + + byte[] testData = new byte[hashLength]; + byte[] testContext = [3]; + + using MLDsaTestImplementation mlDsa = MLDsaTestImplementation.CreateNoOp(algorithm); + mlDsa.SignPreHashHook = (_, _, _, _) => { }; + + mlDsa.AddDataBufferIsSameAssertion(testData); + mlDsa.AddContextBufferIsSameAssertion(testContext); + mlDsa.AddHashAlgorithmIsSameAssertion(hashAlgorithmOid.AsMemory()); + mlDsa.AddFillDestination(1); + + int signatureSize = algorithm.SignatureSizeInBytes; + + // Array overload + byte[] exported = mlDsa.SignPreHash(testData, hashAlgorithmOid, testContext); + Assert.Equal(1, mlDsa.SignPreHashCoreCallCount); + Assert.Equal(signatureSize, exported.Length); + AssertExpectedFill(exported, fillElement: 1); + + // Span overload + byte[] signature = CreatePaddedFilledArray(signatureSize, 42); + + // Extra bytes in destination buffer should not be touched + Memory destination = signature.AsMemory(PaddingSize, signatureSize); + mlDsa.AddDestinationBufferIsSameAssertion(destination); + + mlDsa.SignPreHash(testData, destination.Span, hashAlgorithmOid, testContext); + Assert.Equal(2, mlDsa.SignPreHashCoreCallCount); + AssertExpectedFill(signature, fillElement: 1, paddingElement: 42, PaddingSize, signatureSize); + } + + [Theory] + [MemberData(nameof(AllHashesAndLengths))] + public static void VerifyPreHash_CallsCore(string hashAlgorithmOid, int hashLength) + { + using MLDsaTestImplementation mlDsa = MLDsaTestImplementation.CreateNoOp(MLDsaAlgorithm.MLDsa44); + + int signatureSize = MLDsaAlgorithm.MLDsa44.SignatureSizeInBytes; + byte[] testSignature = CreatePaddedFilledArray(signatureSize, 42); + byte[] testData = new byte[hashLength]; + byte[] testContext = [3]; + bool returnValue = false; + + mlDsa.VerifyPreHashHook = (_, _, _, _) => returnValue; + mlDsa.AddDataBufferIsSameAssertion(testData); + mlDsa.AddContextBufferIsSameAssertion(testContext); + mlDsa.AddSignatureBufferIsSameAssertion(testSignature.AsMemory(PaddingSize, signatureSize)); + mlDsa.AddHashAlgorithmIsSameAssertion(hashAlgorithmOid.AsMemory()); + + // Since `returnValue` is true, this shows the Core method doesn't get called for the wrong sized signature. + returnValue = true; + AssertExtensions.FalseExpression(mlDsa.VerifyPreHash(testData, testSignature.AsSpan(PaddingSize, signatureSize - 1), hashAlgorithmOid, testContext)); + Assert.Equal(0, mlDsa.VerifyPreHashCoreCallCount); + + AssertExtensions.FalseExpression(mlDsa.VerifyPreHash(testData, testSignature.AsSpan(PaddingSize, signatureSize + 1), hashAlgorithmOid, testContext)); + Assert.Equal(0, mlDsa.VerifyPreHashCoreCallCount); + + // But does for the right one. + AssertExtensions.TrueExpression(mlDsa.VerifyPreHash(testData, testSignature.AsSpan(PaddingSize, signatureSize), hashAlgorithmOid, testContext)); + Assert.Equal(1, mlDsa.VerifyPreHashCoreCallCount); + + // And just to prove that the Core method controls the answer... + returnValue = false; + AssertExtensions.FalseExpression(mlDsa.VerifyPreHash(testData, testSignature.AsSpan(PaddingSize, signatureSize), hashAlgorithmOid, testContext)); + Assert.Equal(2, mlDsa.VerifyPreHashCoreCallCount); + } + + [Theory] + [MemberData(nameof(AllHashesAndLengths))] + public static void VerifyPreHash_ByteArray_CallsCore(string hashAlgorithmOid, int hashLength) + { + using MLDsaTestImplementation mlDsa = MLDsaTestImplementation.CreateNoOp(MLDsaAlgorithm.MLDsa44); + + int signatureSize = MLDsaAlgorithm.MLDsa44.SignatureSizeInBytes; + byte[] testSignature = CreateFilledArray(signatureSize, 42); + byte[] testData = new byte[hashLength]; + byte[] testContext = [3]; + bool returnValue = false; + + mlDsa.VerifyPreHashHook = (_, _, _, _) => returnValue; + mlDsa.AddDataBufferIsSameAssertion(testData); + mlDsa.AddContextBufferIsSameAssertion(testContext); + mlDsa.AddSignatureBufferIsSameAssertion(testSignature); + mlDsa.AddHashAlgorithmIsSameAssertion(hashAlgorithmOid.AsMemory()); + + // Since `returnValue` is true, this shows the Core method doesn't get called for the wrong sized signature. + returnValue = true; + AssertExtensions.FalseExpression(mlDsa.VerifyPreHash(testData, new byte[signatureSize - 1], hashAlgorithmOid, testContext)); + Assert.Equal(0, mlDsa.VerifyPreHashCoreCallCount); + + AssertExtensions.FalseExpression(mlDsa.VerifyPreHash(testData, new byte[signatureSize - 1], hashAlgorithmOid, testContext)); + Assert.Equal(0, mlDsa.VerifyPreHashCoreCallCount); + + // But does for the right one. + AssertExtensions.TrueExpression(mlDsa.VerifyPreHash(testData, testSignature, hashAlgorithmOid, testContext)); + Assert.Equal(1, mlDsa.VerifyPreHashCoreCallCount); + + // And just to prove that the Core method controls the answer... + returnValue = false; + AssertExtensions.FalseExpression(mlDsa.VerifyPreHash(testData, testSignature, hashAlgorithmOid, testContext)); + Assert.Equal(2, mlDsa.VerifyPreHashCoreCallCount); } [Theory] @@ -194,30 +401,30 @@ public static void ExportMLDsaPublicKey_CallsCore(MLDsaAlgorithm algorithm) [Theory] [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] - public static void ExportMLDsaSecretKey_CallsCore(MLDsaAlgorithm algorithm) + public static void ExportMLDsaPrivateKey_CallsCore(MLDsaAlgorithm algorithm) { using MLDsaTestImplementation mldsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(algorithm); - mldsa.ExportMLDsaSecretKeyHook = _ => { }; + mldsa.ExportMLDsaPrivateKeyHook = _ => { }; mldsa.AddFillDestination(1); - int secretKeySize = algorithm.SecretKeySizeInBytes; + int privateKeySize = algorithm.PrivateKeySizeInBytes; // Array overload - byte[] exported = mldsa.ExportMLDsaSecretKey(); - Assert.Equal(1, mldsa.ExportMLDsaSecretKeyCoreCallCount); - Assert.Equal(secretKeySize, exported.Length); + byte[] exported = mldsa.ExportMLDsaPrivateKey(); + Assert.Equal(1, mldsa.ExportMLDsaPrivateKeyCoreCallCount); + Assert.Equal(privateKeySize, exported.Length); AssertExpectedFill(exported, fillElement: 1); // Span overload - byte[] secretKey = CreatePaddedFilledArray(secretKeySize, 42); + byte[] privateKey = CreatePaddedFilledArray(privateKeySize, 42); // Extra bytes in destination buffer should not be touched - Memory destination = secretKey.AsMemory(PaddingSize, secretKeySize); + Memory destination = privateKey.AsMemory(PaddingSize, privateKeySize); mldsa.AddDestinationBufferIsSameAssertion(destination); - mldsa.ExportMLDsaSecretKey(destination.Span); - Assert.Equal(2, mldsa.ExportMLDsaSecretKeyCoreCallCount); - AssertExpectedFill(secretKey, fillElement: 1, paddingElement: 42, PaddingSize, secretKeySize); + mldsa.ExportMLDsaPrivateKey(destination.Span); + Assert.Equal(2, mldsa.ExportMLDsaPrivateKeyCoreCallCount); + AssertExpectedFill(privateKey, fillElement: 1, paddingElement: 42, PaddingSize, privateKeySize); } [Theory] @@ -379,9 +586,9 @@ public static void Dispose_CallsVirtual(MLDsaAlgorithm algorithm) [Theory] [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] - public static void ExportPkcs8PrivateKey_DoesNotCallExportMLDsaSecretKey(MLDsaAlgorithm algorithm) + public static void ExportPkcs8PrivateKey_DoesNotCallExportMLDsaPrivateKey(MLDsaAlgorithm algorithm) { - byte[] secretKeyBytes = CreateFilledArray(algorithm.SecretKeySizeInBytes, 42); + byte[] privateKeyBytes = CreateFilledArray(algorithm.PrivateKeySizeInBytes, 42); PrivateKeyInfoAsn pkcs8 = new PrivateKeyInfoAsn { PrivateKeyAlgorithm = new AlgorithmIdentifierAsn @@ -389,7 +596,7 @@ public static void ExportPkcs8PrivateKey_DoesNotCallExportMLDsaSecretKey(MLDsaAl Algorithm = MLDsaTestHelpers.AlgorithmToOid(algorithm), Parameters = null, }, - PrivateKey = secretKeyBytes, + PrivateKey = privateKeyBytes, }; byte[] minimalEncoding = pkcs8.Encode(); @@ -415,8 +622,8 @@ public static void ExportPkcs8PrivateKey_DoesNotCallExportMLDsaSecretKey(MLDsaAl byte[] exported = export(mldsa); - // Assert that the PKCS#8 private key is NOT generated with the secret key but from our test callback - Assert.Equal(0, mldsa.ExportMLDsaSecretKeyCoreCallCount); + // Assert that the PKCS#8 private key is NOT generated with the private key but from our test callback + Assert.Equal(0, mldsa.ExportMLDsaPrivateKeyCoreCallCount); AssertExtensions.GreaterThan(mldsa.TryExportPkcs8PrivateKeyCoreCallCount, 0); PrivateKeyInfoAsn exportedPkcs8 = PrivateKeyInfoAsn.Decode(exported, AsnEncodingRules.DER); @@ -520,7 +727,7 @@ public static void ExportPkcs8PrivateKey_DestinationInitialSize(MLDsaAlgorithm a { using MLDsaTestImplementation mldsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(algorithm); - byte[] secretKeyBytes = CreateFilledArray(algorithm.SecretKeySizeInBytes, 42); + byte[] privateKeyBytes = CreateFilledArray(algorithm.PrivateKeySizeInBytes, 42); PrivateKeyInfoAsn pkcs8 = new PrivateKeyInfoAsn { PrivateKeyAlgorithm = new AlgorithmIdentifierAsn @@ -528,7 +735,7 @@ public static void ExportPkcs8PrivateKey_DestinationInitialSize(MLDsaAlgorithm a Algorithm = MLDsaTestHelpers.AlgorithmToOid(MLDsaAlgorithm.MLDsa44), Parameters = null, }, - PrivateKey = secretKeyBytes, + PrivateKey = privateKeyBytes, }; byte[] minimalEncoding = pkcs8.Encode(); @@ -564,7 +771,7 @@ public static void ExportPkcs8PrivateKey_Resizes(MLDsaAlgorithm algorithm) { using MLDsaTestImplementation mldsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(algorithm); - byte[] secretKeyBytes = CreateFilledArray(algorithm.SecretKeySizeInBytes, 42); + byte[] privateKeyBytes = CreateFilledArray(algorithm.PrivateKeySizeInBytes, 42); PrivateKeyInfoAsn pkcs8 = new PrivateKeyInfoAsn { PrivateKeyAlgorithm = new AlgorithmIdentifierAsn @@ -572,7 +779,7 @@ public static void ExportPkcs8PrivateKey_Resizes(MLDsaAlgorithm algorithm) Algorithm = MLDsaTestHelpers.AlgorithmToOid(MLDsaAlgorithm.MLDsa44), Parameters = null, }, - PrivateKey = secretKeyBytes, + PrivateKey = privateKeyBytes, }; byte[] minimalEncoding = pkcs8.Encode(); @@ -724,6 +931,82 @@ public static void ExportPkcs8PrivateKey_HandleBadReturnBuffer(MLDsaAlgorithm al }); } + [Theory] + [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] + public static void SignExternalMu_GetsMuAndDestination(MLDsaAlgorithm algorithm) + { + using MLDsaTestImplementation mldsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(algorithm); + int signatureSize = algorithm.SignatureSizeInBytes; + byte[] buffer = CreatePaddedFilledArray(signatureSize, 0x42); + Memory signature = buffer.AsMemory(PaddingSize, signatureSize); + byte[] mu = new byte[64]; + + mldsa.SignMuHook = (mu, destination) => destination.Fill(0xAB); + mldsa.AddLengthAssertion(); + mldsa.AddDataBufferIsSameAssertion(mu); + mldsa.AddDestinationBufferIsSameAssertion(signature); + + mldsa.SignMu(mu, signature.Span); + Assert.Equal(1, mldsa.SignMuCoreCallCount); + + AssertExpectedFill(buffer, fillElement: 0xAB, paddingElement: 0x42, PaddingSize, signatureSize); + } + + [Theory] + [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] + public static void VerifyExternalMu_GetsMuAndSignature(MLDsaAlgorithm algorithm) + { + using MLDsaTestImplementation mldsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(algorithm); + byte[] buffer = CreatePaddedFilledArray(algorithm.SignatureSizeInBytes, 0x42); + Memory signature = buffer.AsMemory(PaddingSize, algorithm.SignatureSizeInBytes); + byte[] mu = new byte[64]; + + mldsa.VerifyMuHook = (mu, signature) => true; + mldsa.AddLengthAssertion(); + mldsa.AddDataBufferIsSameAssertion(mu); + mldsa.AddDestinationBufferIsSameAssertion(signature); + + mldsa.VerifyMu(mu, signature.Span); + Assert.Equal(1, mldsa.VerifyMuCoreCallCount); + } + + [Theory] + [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] + public static void VerifyExternalMu_EarlyFalseForWrongSizeMu(MLDsaAlgorithm algorithm) + { + using MLDsaTestImplementation mldsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(algorithm); + byte[] mu = new byte[100]; + byte[] signature = new byte[mldsa.Algorithm.SignatureSizeInBytes]; + const int CorrectMuLength = 64; + + for (int i = 0; i < mu.Length; i++) + { + // Don't check with the correct length, since the callback is Assert.Fail. + if (i == CorrectMuLength) + { + continue; + } + + AssertExtensions.FalseExpression(mldsa.VerifyMu(mu.AsSpan(0, i), signature)); + } + + Assert.Equal(0, mldsa.VerifyMuCoreCallCount); + } + + [Theory] + [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] + public static void VerifyExternalMu_EarlyFalseForWrongSizeSignature(MLDsaAlgorithm algorithm) + { + using MLDsaTestImplementation mldsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(algorithm); + byte[] mu = new byte[64]; + byte[] signature = new byte[mldsa.Algorithm.SignatureSizeInBytes + 1]; + + AssertExtensions.FalseExpression(mldsa.VerifyMu(mu, signature)); + AssertExtensions.FalseExpression(mldsa.VerifyMu(mu, signature.AsSpan(2))); + + Assert.Equal(0, mldsa.VerifyMuCoreCallCount); + } + private static void AssertExpectedFill(ReadOnlySpan source, byte fillElement) => AssertExpectedFill(source, fillElement, 255, 0, source.Length); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsBase.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsBase.cs index 41e2d5e08cca00..848ce919fe025c 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsBase.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsBase.cs @@ -13,7 +13,7 @@ public abstract class MLDsaTestsBase { protected abstract MLDsa GenerateKey(MLDsaAlgorithm algorithm); protected abstract MLDsa ImportPrivateSeed(MLDsaAlgorithm algorithm, ReadOnlySpan seed); - protected abstract MLDsa ImportSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan source); + protected abstract MLDsa ImportPrivateKey(MLDsaAlgorithm algorithm, ReadOnlySpan source); protected abstract MLDsa ImportPublicKey(MLDsaAlgorithm algorithm, ReadOnlySpan source); [Theory] @@ -29,25 +29,67 @@ 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, []); } + [Theory] + [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] + public void GenerateSignVerifyPreHashNoContext(MLDsaAlgorithm algorithm) + { + using MLDsa mldsa = GenerateKey(algorithm); + byte[] data = [1, 2, 3, 4, 5]; + byte[] hash = HashInfo.Sha512.GetHash(data); + byte[] signature = mldsa.SignPreHash(hash, HashInfo.Sha512.Oid, []); + ExerciseSuccessfulVerifyPreHash(mldsa, HashInfo.Sha512.Oid, hash, signature, []); + } + + [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.ExternalMuIsSupported))] + [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] + public void GenerateSignVerifyExternalMuNoContext(MLDsaAlgorithm algorithm) + { + byte[] data = [1, 2, 3, 4, 5]; + using MLDsa mldsa = GenerateKey(algorithm); + SignAndVerifyExternalMu(mldsa, data, []); + } + [Theory] [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] 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); } - [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.SigningEmptyDataIsSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/116461", TestPlatforms.Windows)] + [Theory] + [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] + 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.Sha512.GetHash(data); + byte[] signature = mldsa.SignPreHash(hash, HashInfo.Sha512.Oid, context); + + ExerciseSuccessfulVerifyPreHash(mldsa, HashInfo.Sha512.Oid, hash, signature, context); + } + + [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.ExternalMuIsSupported))] + [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] + public void GenerateSignVerifyExternalMuWithContext(MLDsaAlgorithm algorithm) + { + byte[] data = [1, 2, 3, 4, 5]; + byte[] context = [1, 1, 3, 5, 6]; + using MLDsa mldsa = GenerateKey(algorithm); + SignAndVerifyExternalMu(mldsa, data, context); + } + + [Theory] [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] public void GenerateSignVerifyEmptyMessageNoContext(MLDsaAlgorithm algorithm) { @@ -56,8 +98,7 @@ public void GenerateSignVerifyEmptyMessageNoContext(MLDsaAlgorithm algorithm) ExerciseSuccessfulVerify(mldsa, [], signature, []); } - [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.SigningEmptyDataIsSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/116461", TestPlatforms.Windows)] + [Theory] [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] public void GenerateSignVerifyEmptyMessageWithContext(MLDsaAlgorithm algorithm) { @@ -67,43 +108,81 @@ public void GenerateSignVerifyEmptyMessageWithContext(MLDsaAlgorithm algorithm) ExerciseSuccessfulVerify(mldsa, [], signature, context); } + [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.ExternalMuIsSupported))] + [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] + public void GenerateSignVerifyEmptyMessageExternalMuNoContext(MLDsaAlgorithm algorithm) + { + using MLDsa mldsa = GenerateKey(algorithm); + SignAndVerifyExternalMu(mldsa, [], []); + } + + [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.ExternalMuIsSupported))] + [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] + public void GenerateSignVerifyEmptyMessageExternalMuWithContext(MLDsaAlgorithm algorithm) + { + using MLDsa mldsa = GenerateKey(algorithm); + byte[] context = [1, 1, 3, 5, 6]; + SignAndVerifyExternalMu(mldsa, [], context); + } + [Theory] [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] 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.Sha512.GetHash(data); + byte[] signaturePreHash; + byte[]? mu = null; + byte[] muSignature = null; using (MLDsa mldsa = GenerateKey(algorithm)) { signature = mldsa.SignData(data); AssertExtensions.TrueExpression(mldsa.VerifyData(data, signature)); + signaturePreHash = mldsa.SignPreHash(hash, HashInfo.Sha512.Oid); + AssertExtensions.TrueExpression(mldsa.VerifyPreHash(hash, signaturePreHash, HashInfo.Sha512.Oid)); + publicKey = mldsa.ExportMLDsaPublicKey(); + + mu = CalculateMu(mldsa, data); + + if (mu is not null) + { + muSignature = mldsa.SignMu(mu); + } } using (MLDsa mldsaPub = ImportPublicKey(algorithm, publicKey)) { - ExerciseSuccessfulVerify(mldsaPub, data, signature, []); + ExerciseSuccessfulVerify(mldsaPub, data, signature, [], mu); + ExerciseSuccessfulVerifyPreHash(mldsaPub, HashInfo.Sha512.Oid, hash, signaturePreHash, []); + AssertExtensions.FalseExpression(mldsaPub.VerifyPreHash(hash, signature, HashInfo.Sha512.Oid)); + + if (muSignature is not null) + { + ExerciseSuccessfulVerify(mldsaPub, data, muSignature, [], mu); + } } } [Theory] [MemberData(nameof(MLDsaTestsData.AllMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] - public void GenerateExportSecretKeySignAndVerify(MLDsaAlgorithm algorithm) + public void GenerateExportPrivateKeySignAndVerify(MLDsaAlgorithm algorithm) { - byte[] secretKey; - byte[] data = [ 1, 2, 3, 4, 5 ]; + byte[] privateKey; + byte[] data = [1, 2, 3, 4, 5]; byte[] signature; using (MLDsa mldsaTmp = GenerateKey(algorithm)) { signature = mldsaTmp.SignData(data); - secretKey = mldsaTmp.ExportMLDsaSecretKey(); + privateKey = mldsaTmp.ExportMLDsaPrivateKey(); } - using (MLDsa mldsa = ImportSecretKey(algorithm, secretKey)) + using (MLDsa mldsa = ImportPrivateKey(algorithm, privateKey)) { AssertExtensions.TrueExpression(mldsa.VerifyData(data, signature)); @@ -122,7 +201,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)) @@ -143,44 +222,44 @@ public void GenerateExportPrivateSeedSignAndVerify(MLDsaAlgorithm algorithm) } } - [Fact] - public void ImportSecretKey_CannotReconstructSeed() + [ConditionalFact(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.SupportsExportingPrivateKeyPkcs8))] + public void ImportPrivateKey_CannotReconstructSeed() { - byte[] secretKey; + byte[] privateKey; using (MLDsa mldsaOriginal = GenerateKey(MLDsaAlgorithm.MLDsa44)) { - secretKey = mldsaOriginal.ExportMLDsaSecretKey(); + privateKey = mldsaOriginal.ExportMLDsaPrivateKey(); } - using (MLDsa mldsa = ImportSecretKey(MLDsaAlgorithm.MLDsa44, secretKey)) + using (MLDsa mldsa = ImportPrivateKey(MLDsaAlgorithm.MLDsa44, privateKey)) { Assert.Throws(() => mldsa.ExportMLDsaPrivateSeed(new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes])); } } [Fact] - public void ImportSeed_CanReconstructSecretKey() + public void ImportSeed_CanReconstructPrivateKey() { - byte[] secretKey; + byte[] privateKey; byte[] seed; using (MLDsa mldsaOriginal = GenerateKey(MLDsaAlgorithm.MLDsa44)) { - secretKey = mldsaOriginal.ExportMLDsaSecretKey(); + privateKey = mldsaOriginal.ExportMLDsaPrivateKey(); seed = mldsaOriginal.ExportMLDsaPrivateSeed(); } using (MLDsa mldsa = ImportPrivateSeed(MLDsaAlgorithm.MLDsa44, seed)) { - byte[] secretKey2 = mldsa.ExportMLDsaSecretKey(); + byte[] privateKey2 = mldsa.ExportMLDsaPrivateKey(); byte[] seed2 = mldsa.ExportMLDsaPrivateSeed(); - AssertExtensions.SequenceEqual(secretKey, secretKey2); + AssertExtensions.SequenceEqual(privateKey, privateKey2); AssertExtensions.SequenceEqual(seed, seed2); } } [Theory] - [MemberData(nameof(MLDsaTestsData.AllNistTestCases), MemberType = typeof(MLDsaTestsData))] + [MemberData(nameof(MLDsaTestsData.AllPureMLDsaNistTestCases), MemberType = typeof(MLDsaTestsData))] public void NistImportPublicKeyVerify(MLDsaNistTestCase testCase) { using MLDsa mldsa = ImportPublicKey(testCase.Algorithm, testCase.PublicKey); @@ -188,16 +267,39 @@ public void NistImportPublicKeyVerify(MLDsaNistTestCase testCase) } [Theory] - [MemberData(nameof(MLDsaTestsData.AllNistTestCases), MemberType = typeof(MLDsaTestsData))] - public void NistImportSecretKeyVerifyExportsAndSignature(MLDsaNistTestCase testCase) + [MemberData(nameof(MLDsaTestsData.AllPreHashMLDsaNistTestCases), MemberType = typeof(MLDsaTestsData))] + public void NistImportPublicKeyVerifyPreHash(MLDsaNistTestCase testCase) { - using MLDsa mldsa = ImportSecretKey(testCase.Algorithm, testCase.SecretKey); + if (!HashInfo.KnownHashAlgorithmOids.Contains(testCase.HashAlgOid)) + { + // This test case is not supported by the current platform. + return; + } + + byte[] hash = HashInfo.HashData(testCase.HashAlgOid, testCase.Message); + using MLDsa mldsa = ImportPublicKey(testCase.Algorithm, testCase.PublicKey); + Assert.Equal(testCase.ShouldPass, mldsa.VerifyPreHash(hash, testCase.Signature, testCase.HashAlgOid, testCase.Context)); + } + + [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.ExternalMuIsSupported))] + [MemberData(nameof(MLDsaTestsData.AllExternalMuMLDsaNistTestCases), MemberType = typeof(MLDsaTestsData))] + public void NistImportPublicKeyVerifyExternalMu(MLDsaNistTestCase testCase) + { + using MLDsa mldsa = ImportPublicKey(testCase.Algorithm, testCase.PublicKey); + Assert.Equal(testCase.ShouldPass, mldsa.VerifyMu(testCase.Mu, testCase.Signature)); + } + + [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.SupportsExportingPrivateKeyPkcs8))] + [MemberData(nameof(MLDsaTestsData.AllPureMLDsaNistTestCases), MemberType = typeof(MLDsaTestsData))] + public void NistImportPrivateKeyVerifyExportsAndSignature(MLDsaNistTestCase testCase) + { + using MLDsa mldsa = ImportPrivateKey(testCase.Algorithm, testCase.PrivateKey); byte[] pubKey = mldsa.ExportMLDsaPublicKey(); AssertExtensions.SequenceEqual(testCase.PublicKey, pubKey); - byte[] secretKey = mldsa.ExportMLDsaSecretKey(); - AssertExtensions.SequenceEqual(testCase.SecretKey, secretKey); + byte[] privateKey = mldsa.ExportMLDsaPrivateKey(); + AssertExtensions.SequenceEqual(testCase.PrivateKey, privateKey); Assert.Throws(() => mldsa.ExportMLDsaPrivateSeed()); Assert.Equal(testCase.ShouldPass, mldsa.VerifyData(testCase.Message, testCase.Signature, testCase.Context)); @@ -215,7 +317,7 @@ public void ImportPublicKey_Export(MLDsaKeyInfo info) MLDsaTestHelpers.AssertExportMLDsaPublicKey( export => AssertExtensions.SequenceEqual(info.PublicKey, export(mldsa))); - MLDsaTestHelpers.AssertExportMLDsaSecretKey( + MLDsaTestHelpers.AssertExportMLDsaPrivateKey( export => Assert.Throws(() => export(mldsa)), export => AssertExportPkcs8FromPublicKey(() => export(mldsa))); @@ -224,17 +326,17 @@ public void ImportPublicKey_Export(MLDsaKeyInfo info) export => AssertExportPkcs8FromPublicKey(() => export(mldsa))); } - [Theory] + [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.SupportsExportingPrivateKeyPkcs8))] [MemberData(nameof(MLDsaTestsData.IetfMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] public void ImportPrivateKey_Export(MLDsaKeyInfo info) { - using MLDsa mldsa = ImportSecretKey(info.Algorithm, info.SecretKey); + using MLDsa mldsa = ImportPrivateKey(info.Algorithm, info.PrivateKey); MLDsaTestHelpers.AssertExportMLDsaPublicKey(export => AssertExtensions.SequenceEqual(info.PublicKey, export(mldsa))); - MLDsaTestHelpers.AssertExportMLDsaSecretKey(export => - AssertExtensions.SequenceEqual(info.SecretKey, export(mldsa))); + MLDsaTestHelpers.AssertExportMLDsaPrivateKey(export => + AssertExtensions.SequenceEqual(info.PrivateKey, export(mldsa))); MLDsaTestHelpers.AssertExportMLDsaPrivateSeed( export => Assert.Throws(() => export(mldsa)), @@ -251,9 +353,9 @@ public void ImportPrivateSeed_Export(MLDsaKeyInfo info) MLDsaTestHelpers.AssertExportMLDsaPublicKey(export => AssertExtensions.SequenceEqual(info.PublicKey, export(mldsa))); - MLDsaTestHelpers.AssertExportMLDsaSecretKey( - export => AssertExtensions.SequenceEqual(info.SecretKey, export(mldsa)), - // Seed is preferred in PKCS#8, so secret key won't be available + MLDsaTestHelpers.AssertExportMLDsaPrivateKey( + export => AssertExtensions.SequenceEqual(info.PrivateKey, export(mldsa)), + // Seed is preferred in PKCS#8, so private key won't be available export => Assert.Null(export(mldsa))); MLDsaTestHelpers.AssertExportMLDsaPrivateSeed(export => @@ -272,7 +374,75 @@ public void SignData_PublicKeyOnlyThrows(MLDsaKeyInfo info) Assert.DoesNotContain("unknown", ce.Message, StringComparison.OrdinalIgnoreCase); } - protected static void ExerciseSuccessfulVerify(MLDsa mldsa, byte[] data, byte[] signature, byte[] context) + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows))] + [MemberData(nameof(UnsupportedWindowsPreHashCombinations))] + public void SignPreHash_ThrowsForUnsupportedAlgorithmCombinations(MLDsaAlgorithm algorithm, HashInfo hashInfo) + { + using MLDsa mldsa = GenerateKey(algorithm); + byte[] hash = new byte[hashInfo.OutputSize]; + + CryptographicException ce = Assert.Throws(() => mldsa.SignPreHash(hash, hashInfo.Oid)); + Assert.Contains(algorithm.Name, ce.Message); + Assert.Contains(hashInfo.Name.Name, ce.Message); + } + + protected static byte[]? CalculateMu(MLDsa mldsa, byte[] data, byte[]? context = null) + { +#if NET + if (MLDsaTestHelpers.ExternalMuIsSupported) + { + byte[] mu = new byte[mldsa.Algorithm.MuSizeInBytes]; + Span trSpan = mu.AsSpan(0, 64); + + using (Shake256 shake = new Shake256()) + { + shake.AppendData(mldsa.ExportMLDsaPublicKey()); + shake.GetHashAndReset(trSpan); + + shake.AppendData(trSpan); + + Span delimOrContextLength = [ 0 ]; + shake.AppendData(delimOrContextLength); + + delimOrContextLength[0] = checked((byte)(context?.Length ?? 0)); + shake.AppendData(delimOrContextLength); + + if (context is not null) + { + shake.AppendData(context); + } + + if (data is not null) + { + shake.AppendData(data); + } + + shake.GetHashAndReset(mu); + } + + return mu; + } +#endif + + return null; + } + + protected static void SignAndVerifyExternalMu(MLDsa mldsa, byte[] data, byte[] context) + { + byte[]? mu = CalculateMu(mldsa, data, context); + byte[] signature; + + if (mu is not null) + { + signature = mldsa.SignMu(mu); + ExerciseSuccessfulVerify(mldsa, data, signature, context, mu); + } + + signature = mldsa.SignData(data, context); + ExerciseSuccessfulVerify(mldsa, data, signature, context, mu); + } + + protected static void ExerciseSuccessfulVerify(MLDsa mldsa, byte[] data, byte[] signature, byte[]? context, byte[]? mu = null) { ReadOnlySpan buffer = [0, 1, 2, 3]; @@ -296,11 +466,23 @@ protected static void ExerciseSuccessfulVerify(MLDsa mldsa, byte[] data, byte[] AssertExtensions.FalseExpression(mldsa.VerifyData(buffer.Slice(1, 3), signature, context)); } + if (mu is not null) + { + AssertExtensions.TrueExpression(mldsa.VerifyMu(mu, signature)); + } + signature[0] ^= 1; - AssertExtensions.FalseExpression(mldsa.VerifyData(data, signature, context)); + { + AssertExtensions.FalseExpression(mldsa.VerifyData(data, signature, context)); + + if (mu is not null) + { + AssertExtensions.FalseExpression(mldsa.VerifyMu(mu, signature)); + } + } signature[0] ^= 1; - if (context.Length > 0) + if (context?.Length > 0) { AssertExtensions.FalseExpression(mldsa.VerifyData(data, signature, Array.Empty())); AssertExtensions.FalseExpression(mldsa.VerifyData(data, signature, ReadOnlySpan.Empty)); @@ -319,6 +501,78 @@ protected static void ExerciseSuccessfulVerify(MLDsa mldsa, byte[] data, byte[] } AssertExtensions.TrueExpression(mldsa.VerifyData(data, signature, context)); + + if (mu is not null) + { + AssertExtensions.TrueExpression(mldsa.VerifyMu(mu, signature)); + } + } + + protected static void ExerciseSuccessfulVerifyPreHash(MLDsa mldsa, string hashAlgorithmOid, byte[] hash, byte[] signature, byte[] context) + { + ReadOnlySpan buffer = [0, 1, 2, 3]; + + AssertExtensions.TrueExpression(mldsa.VerifyPreHash(hash, signature, hashAlgorithmOid, context)); + + if (hash.Length > 0) + { + Assert.Throws(() => mldsa.VerifyPreHash(Array.Empty(), signature, hashAlgorithmOid, context)); + Assert.Throws(() => mldsa.VerifyPreHash(ReadOnlySpan.Empty, signature, hashAlgorithmOid, context)); + + hash[0] ^= 1; + AssertExtensions.FalseExpression(mldsa.VerifyPreHash(hash, signature, hashAlgorithmOid, context)); + hash[0] ^= 1; + } + else + { + Assert.Fail("Empty hash is not supported."); + } + + signature[0] ^= 1; + AssertExtensions.FalseExpression(mldsa.VerifyPreHash(hash, signature, hashAlgorithmOid, context)); + signature[0] ^= 1; + + if (context.Length > 0) + { + AssertExtensions.FalseExpression(mldsa.VerifyPreHash(hash, signature, hashAlgorithmOid, Array.Empty())); + AssertExtensions.FalseExpression(mldsa.VerifyPreHash(hash, signature, hashAlgorithmOid, ReadOnlySpan.Empty)); + + context[0] ^= 1; + AssertExtensions.FalseExpression(mldsa.VerifyPreHash(hash, signature, hashAlgorithmOid, context)); + context[0] ^= 1; + } + else + { + AssertExtensions.TrueExpression(mldsa.VerifyPreHash(hash, signature, hashAlgorithmOid, Array.Empty())); + AssertExtensions.TrueExpression(mldsa.VerifyPreHash(hash, signature, hashAlgorithmOid, ReadOnlySpan.Empty)); + + AssertExtensions.FalseExpression(mldsa.VerifyPreHash(hash, signature, hashAlgorithmOid, buffer.Slice(0, 1))); + AssertExtensions.FalseExpression(mldsa.VerifyPreHash(hash, signature, hashAlgorithmOid, buffer.Slice(1, 3))); + } + + AssertExtensions.FalseExpression(mldsa.VerifyPreHash(hash, signature, "1." + hashAlgorithmOid, context)); + + 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/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.cs index c7b705fa69973e..3ef7fb9961b463 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.cs @@ -14,7 +14,7 @@ public MLDsaKeyInfo( MLDsaAlgorithm algorithm, string publicKeyHex, string privateSeedHex, - string secretKeyHex, + string privateKeyHex, string pkcs8PrivateKey_Seed_Base64, string pkcs8PrivateKey_Expanded_Base64, string pkcs8PrivateKey_Both_Base64, @@ -32,7 +32,7 @@ public MLDsaKeyInfo( Algorithm = algorithm; PublicKeyHex = publicKeyHex; PrivateSeedHex = privateSeedHex; - SecretKeyHex = secretKeyHex; + PrivateKeyHex = privateKeyHex; Pkcs8PrivateKey_Seed_Base64 = pkcs8PrivateKey_Seed_Base64; Pkcs8PrivateKey_Expanded_Base64 = pkcs8PrivateKey_Expanded_Base64; Pkcs8PrivateKey_Both_Base64 = pkcs8PrivateKey_Both_Base64; @@ -51,7 +51,7 @@ public MLDsaKeyInfo( public MLDsaAlgorithm Algorithm { get; } public string PublicKeyHex { get; } public string PrivateSeedHex { get; } - public string SecretKeyHex { get; } + public string PrivateKeyHex { get; } public string Pkcs8PrivateKey_Seed_Base64 { get; } public string Pkcs8PrivateKey_Expanded_Base64 { get; } public string Pkcs8PrivateKey_Both_Base64 { get; } @@ -67,7 +67,7 @@ public MLDsaKeyInfo( public PbeParameters EncryptionParameters { get; } public byte[] PublicKey => PublicKeyHex.HexToByteArray(); public byte[] PrivateSeed => PrivateSeedHex.HexToByteArray(); - public byte[] SecretKey => SecretKeyHex.HexToByteArray(); + public byte[] PrivateKey => PrivateKeyHex.HexToByteArray(); public byte[] Pkcs8PrivateKey_Seed => Convert.FromBase64String(Pkcs8PrivateKey_Seed_Base64); public byte[] Pkcs8PrivateKey_Expanded => Convert.FromBase64String(Pkcs8PrivateKey_Expanded_Base64); public byte[] Pkcs8PrivateKey_Both => Convert.FromBase64String(Pkcs8PrivateKey_Both_Base64); @@ -78,14 +78,14 @@ public MLDsaKeyInfo( public byte[] EncryptionPasswordBytes => Encoding.UTF8.GetBytes(EncryptionPassword); // Assuming UTF-8 encoding public byte[] Certificate => Convert.FromBase64String(CertificateBase64); #if !EXCLUDE_PEM_ENCODING_FROM_TEST_DATA - public string EncryptedPem_Seed => PemEncoding.WriteString("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey_Seed); - public string EncryptedPem_Expanded => PemEncoding.WriteString("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey_Expanded); - public string EncryptedPem_Both => PemEncoding.WriteString("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey_Both); - public string PrivateKeyPem_Seed => PemEncoding.WriteString("PRIVATE KEY", Pkcs8PrivateKey_Seed); - public string PrivateKeyPem_Expanded => PemEncoding.WriteString("PRIVATE KEY", Pkcs8PrivateKey_Expanded); - public string PrivateKeyPem_Both => PemEncoding.WriteString("PRIVATE KEY", Pkcs8PrivateKey_Both); - public string PublicKeyPem => PemEncoding.WriteString("PUBLIC KEY", Pkcs8PublicKey); - public string CertificatePem => PemEncoding.WriteString("CERTIFICATE", Certificate); + public string EncryptedPem_Seed => ByteUtils.PemEncode("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey_Seed); + public string EncryptedPem_Expanded => ByteUtils.PemEncode("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey_Expanded); + public string EncryptedPem_Both => ByteUtils.PemEncode("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey_Both); + public string PrivateKeyPem_Seed => ByteUtils.PemEncode("PRIVATE KEY", Pkcs8PrivateKey_Seed); + public string PrivateKeyPem_Expanded => ByteUtils.PemEncode("PRIVATE KEY", Pkcs8PrivateKey_Expanded); + public string PrivateKeyPem_Both => ByteUtils.PemEncode("PRIVATE KEY", Pkcs8PrivateKey_Both); + public string PublicKeyPem => ByteUtils.PemEncode("PUBLIC KEY", Pkcs8PublicKey); + public string CertificatePem => ByteUtils.PemEncode("CERTIFICATE", Certificate); #endif public byte[] Pfx_Seed => Convert.FromBase64String(Pfx_Seed_Base64); public byte[] Pfx_Expanded => Convert.FromBase64String(Pfx_Expanded_Base64); @@ -97,16 +97,28 @@ public override string ToString() => public class MLDsaNistTestCase { - public MLDsaNistTestCase(int nistTestCaseId, MLDsaAlgorithm algorithm, bool shouldPass, string publicKeyHex, string secretKeyHex, string messageHex, string contextHex, string signatureHex) + public MLDsaNistTestCase(int nistTestCaseId, MLDsaAlgorithm algorithm, bool shouldPass, string publicKeyHex, string privateKeyHex, string messageHex, string contextHex, string signatureHex, string? hashAlgOid = null) { NistTestCaseId = nistTestCaseId; Algorithm = algorithm; ShouldPass = shouldPass; PublicKeyHex = publicKeyHex; - SecretKeyHex = secretKeyHex; + PrivateKeyHex = privateKeyHex; MessageHex = messageHex; ContextHex = contextHex; SignatureHex = signatureHex; + HashAlgOid = hashAlgOid; + } + + public MLDsaNistTestCase(int nistTestCaseId, MLDsaAlgorithm algorithm, bool shouldPass, string publicKeyHex, string privateKeyHex, string muHex, string signatureHex) + { + NistTestCaseId = nistTestCaseId; + Algorithm = algorithm; + ShouldPass = shouldPass; + PublicKeyHex = publicKeyHex; + PrivateKeyHex = privateKeyHex; + MuHex = muHex; + SignatureHex = signatureHex; } public int NistTestCaseId { get; private set; } @@ -114,20 +126,25 @@ public MLDsaNistTestCase(int nistTestCaseId, MLDsaAlgorithm algorithm, bool shou public bool ShouldPass { get; private set; } public string PublicKeyHex { get; private set; } - public string SecretKeyHex { get; private set; } + public string PrivateKeyHex { get; private set; } - public string MessageHex { get; private set; } - public string ContextHex { get; private set; } + public string? MessageHex { get; private set; } + public string? ContextHex { get; private set; } + public string? MuHex { get; private set;} public string SignatureHex { get; private set; } + public string? HashAlgOid { get; private set; } public byte[] PublicKey => PublicKeyHex.HexToByteArray(); - public byte[] SecretKey => SecretKeyHex.HexToByteArray(); + public byte[] PrivateKey => PrivateKeyHex.HexToByteArray(); - public byte[] Message => MessageHex.HexToByteArray(); - public byte[] Context => ContextHex.HexToByteArray(); + public byte[]? Message => MessageHex?.HexToByteArray(); + public byte[]? Context => ContextHex?.HexToByteArray(); + public byte[]? Mu => MuHex?.HexToByteArray(); public byte[] Signature => SignatureHex.HexToByteArray(); - public override string ToString() => $"Nist Test Case {NistTestCaseId} ({Algorithm}, ShouldPass: {ShouldPass})"; + public override string ToString() => HashAlgOid != null ? + $"Nist Test Case {NistTestCaseId} ({Algorithm} + {HashAlgOid}, ShouldPass: {ShouldPass})" : + $"Nist Test Case {NistTestCaseId} ({Algorithm}, ShouldPass: {ShouldPass})"; } public static partial class MLDsaTestsData @@ -150,21 +167,37 @@ public static IEnumerable AllMLDsaAlgorithms() => [MLDsaAlgorithm.MLDsa87], ]; - public static IEnumerable AllNistTestCases() + public static IEnumerable AllPureMLDsaNistTestCases() + { + foreach (MLDsaNistTestCase nistTestCase in s_pureMLDsaNistTestCases) + { + yield return [nistTestCase]; + } + } + + public static IEnumerable AllPreHashMLDsaNistTestCases() + { + foreach (MLDsaNistTestCase nistTestCase in s_preHashMLDsaNistTestCases) + { + yield return [nistTestCase]; + } + } + + public static IEnumerable AllExternalMuMLDsaNistTestCases() { - foreach (MLDsaNistTestCase nistTestCase in s_nistTestCases) + foreach (MLDsaNistTestCase nistTestCase in s_externalMuMLDsaNistTestCases) { yield return [nistTestCase]; } } public static MLDsaNistTestCase GetPassingNistTestCase(MLDsaAlgorithm algorithm) - => s_nistTestCases + => s_pureMLDsaNistTestCases .Where(tc => tc.Algorithm == algorithm && tc.ShouldPass) .Single(); // one failing and one passing test case for each algorithm, each failing for different reason - private static MLDsaNistTestCase[] s_nistTestCases = + private static MLDsaNistTestCase[] s_pureMLDsaNistTestCases = [ new MLDsaNistTestCase( nistTestCaseId: 1, @@ -204,7 +237,7 @@ public static MLDsaNistTestCase GetPassingNistTestCase(MLDsaAlgorithm algorithm) "9FEADD16B260A8D6455902AA3AC2E342C17FBE62702C7D3D28A3EEEE72E7D9871F2F79D8A9FCAADC" + "C6265E78DD29C316DB40357F7A8C743C2C70B0DBF1BDF5E35A2706B9637583D32CFE8A811C96051A" + "D42D29459D8D9EC86987E8C3128B122B688EA2A88CA092DC1B8A76F9F60FB174", - secretKeyHex: + privateKeyHex: "8752B50D81824C9B31E1788C76342AADB31EB7F684AAEA2D73A49381117495242720FEBEE2E2C6F4" + "24BC6B8863053906B0308314127ED799F77F15761A042BB99AC20792D9C1B022FDC328263FA684BB" + "471374B14CC723A9E503CA55600F79F7557EA245144C8EAC4DE6BBFF86FEC7F4B559384932F7218F" + @@ -520,7 +553,7 @@ public static MLDsaNistTestCase GetPassingNistTestCase(MLDsaAlgorithm algorithm) "22A7BD85A18377ED5DAE99A86AB1EB3720AA35AD4CB857A6C5C074F1CE6B4BCCF289CB9C19DBB406" + "8B7FABA0D61233FB9ABFC8F0ECF570704BB9F4CFA4ADB0E86F13D9603B1F79F073C0E56C78FBBF00" + "F50AE33B13CBC7739AE46BF71BB3CC0DA0AA1224319B64E6C9F1E4E4C4F4B0EB", - secretKeyHex: + privateKeyHex: "8DDF48136E57F2EF242382612DDAADFE417FFC335337C07DB85FBE2BDB977E6091B9880181CA468C" + "27551AE45B3B8BA6653FCE717E1227D582EB38CA3E3242E295B6EE1DD99033A2BE3A2AF7EDCA050D" + "143E2E1C9FF80F6FEBCF0952A69CD9FBE6EF0B2E8FF2A2F08DACAD7647403D0009813EE4907F4087" + @@ -895,7 +928,7 @@ public static MLDsaNistTestCase GetPassingNistTestCase(MLDsaAlgorithm algorithm) "4FBAA8172726CA6FEF6BF95576080F1863EE056035FC281FD3245878409339B772F0370AEE605637" + "69CAAF421326FC94C31B9AB864579ED3B5E36B2F640D01A05DC02F8A0B655233BD24C32DEBBA35C7" + "CB260E49A95DD09F828E4346EC6599F0E3930EC48A9387D15287FCEC14F6668F", - secretKeyHex: + privateKeyHex: "C7C058345F5CE645AB72D4E474A7B8F3ACB3C2420652FCD99DAAAC476D1BC4D3621E0F25F2FB11A0" + "24276B1F2F6C22DE4F7FF9BB978589DA147E789DA223FED2E247931E1C7BDFD0EC8A9253E38B373D" + "468AAA89652AAF18425D5F32A8CFD4E57E6DC07A33EFB490346F065A7D6E06491E74A4CFD11A7C36" + @@ -1214,7 +1247,7 @@ public static MLDsaNistTestCase GetPassingNistTestCase(MLDsaAlgorithm algorithm) "9B0EA07B25FCDD8CAF0038F08701F744E70446D145B6CFE10B4B545696E1C2BD01E80E27D03DB552" + "48CDC58746B4F3FA3D378EC36F81B75BE936CAEF4B77B8A2E1B3C1E72215678D3713C8B28D2D046B" + "9AE52656475E783BFD8461DE0C227B21DCF8F3F92D34C5F9890E7E46E15DCAB0", - secretKeyHex: + privateKeyHex: "98AC2EC3D9585F925CE8CA80B7ADA54A856EDC8AA2895B67777B2854C7D26C1EB54D189B178D1F56" + "083FB5304F984549B61F267AAD1A89517A877B822FADC981779D974D228F90179AD901A5FA757FC6" + "266A0854480223F9643433112938867650A4075F29001C78085A0D4E863BCAC5E8594640204F4EB3" + @@ -1598,7 +1631,7 @@ public static MLDsaNistTestCase GetPassingNistTestCase(MLDsaAlgorithm algorithm) "DF1D93EA3E95D2BDE52AAC6D229DAD90D3467B63B7BD8FA3F49FE41A63FBCF1C865775310AA0CAC8" + "92ED992646251AF8D24835841B0B09B987C20F70A1F8F33B04D0567C7EBD6988770A3FAAED563E59" + "CDDD2A243DD9D8671A25581C0D388F9E2B213C0AFF45E93F2687C5D6274E9778", - secretKeyHex: + privateKeyHex: "D82C7D3799B1E6420BA36CC8F96F0A5D1A5C28975B5F762A9A519A3336949389D51162A830E7932A" + "BB1A85BDBDECCB50D386909A3DF29E2CF5091394ECAEE74A339763F73759E92D066ED0FDF8F88D82" + "EA3B8716F74DD59554A740316ABEE068DB82B924BE9B618472F881BF9EE26C7875C39DFA09C517D5" + @@ -1929,7 +1962,7 @@ public static MLDsaNistTestCase GetPassingNistTestCase(MLDsaAlgorithm algorithm) "63E58327EEB2E2D94824EE9FAB022DDCE392C880E522BFB6D50025199B61C2D5A2D3D2F3E8998E0A" + "023B926691656BBA13658E7711FC8445E2C4FC091F7928FE45CE13CB148AE87E6598463F4B0B3A12" + "0F48E761E30272643708C99594A5F02CB63A8AEB4CA5420C1B94E58BF7C0BEE6", - secretKeyHex: + privateKeyHex: "EAF0686CF7EA3FD1C864B91466101F727709D27C141725F0A0338019BF7A5D820D8E801FF36C9951" + "48F727F8C38617D26B0F7F945052AEFDC46C4038AD4283C2DD894E4F624333AC07C724A52BCC2201" + "55C8665690D2EDD2FC511060560BB09595E7A3BFECCF6F5B462C622E844E7FD6A9AE28FEEF3EC542" + @@ -2259,7 +2292,5288 @@ public static MLDsaNistTestCase GetPassingNistTestCase(MLDsaAlgorithm algorithm) "8B3B463F6E95AF0B669C3790B433F4406FF0AAFCCCA93761F23941FF5306E860BC536A7E9F875AAE" + "979869B8DE55AB696F6A51F05DAAEECD18C3C22B9E398412025864828389E2F4FF0E195D62ACD32F" + "5090EE1A8E9F0243565A758AD3F46AA0B3CBEEF25584A1AE0017222F393D4E4F53B3000000000000" + - "00000000000000000000000000000000000000090F13161E242832") + "00000000000000000000000000000000000000090F13161E242832"), + ]; + + // one passing per each hash algorithm and one failing, each failing for different reason + private static MLDsaNistTestCase[] s_preHashMLDsaNistTestCases = + [ + new MLDsaNistTestCase( + nistTestCaseId: 16, + algorithm: MLDsaAlgorithm.MLDsa44, + shouldPass: false, // modified signature - z + publicKeyHex: + "866930601EB856FD921216F506039030224470B3361E4C1E5C897A883370A29EC822282323D36046" + + "97AF027A2D2177E2C8219754CC22E4E0407F003FD24CA806EF3292DA6824B99FBBC8133E53002E4F" + + "3A78EEC1050D252BB9BE8DA4B92BF63661E5082DBEB6753B7D618FCB3FB1961267E61349B1BD5F10" + + "3AFC6C02D74157F85CD1D0F64285F9D1AECD0B955B0E49A28D8004D6D30D4DD30EE1011C5D5B00CA" + + "1C0C45875BC4CA5139B0004A1DADC2EB05E486F42E4DB8F99CAA79D163CBEFC982646F0115EE9AD5" + + "EB3CE9A8DB21073D6DA2417AE9D5BFDD0E04644F965ABF965713CABD53BEC11A6168382F0B759D38" + + "A7678A8B96E98E0853E98BE281A859F3E8A115FA84EF72246F825338584D53A2EB517E8B4EF8E1AD" + + "702B442DBB47CF6976F256FBAFA464D68A17042705255E7D55D833EAD008468420BD3C760F0E1DAD" + + "EB4430C7C9DF16F43DAECB7387F18A22744B050FE1C9604F2062331D2894C26AD367274A538EAC99" + + "591EBDCF0BC7D0D39B40F3E5DC11481B03ED005B94DFF0099725F4F2AEF1BA7FD2719D77FF1A9511" + + "46B41E94A0C53B3924431B03C1D6ACA6F67139A3804A2CE9A8D82E4393051A8967F758167E9B7BC1" + + "9E9A91FE2DA4FA8FFA42D3239D96E503338B71B23C3A563CB20CE7DF8AF7EBEE24CFF2FF899E42A7" + + "C4BB7B896372808E92A2051D0F16869A20AA38213A67AA5CB9AC4BE99D55E3D9B035318E1C031C21" + + "E51D29C73BFD6BCBF2F338AF8C5676DC98348BABE62146507A0568B968493FE3A5E77B114E128C40" + + "C4BA8EDBD72B6A310F23435438B04E2CE88033434130EA617644B85152E77137986279F0B20FBDB6" + + "C8F560C218F9E18DB6F9333852AF51DE0446686419CEB83A891592F740F0EF40937BA2164391F552" + + "DB6B3C77AF0DBFDFF5F6C0A43CFE466773B0795193603C03E40012AAA265041AC8DFE3F3240B1B1F" + + "483F9D72BEBF0E7179D198A57E11891C360EAD0A73E3E4018DD22A82CB063A5930E26C9C17D4A423" + + "85637329E78EA274675622ABDF54163FD42169DE55E6FC08A365755701623BD8324C804854DC2406" + + "6C7F2735DEC0C8F3D6C78615082CBF6C95E00D25106DA1A6913BCAACE7EB34C07F8C9F7744FAEACD" + + "FEA9210B3AECE5FAE7E88DE71656992C05A80421F0F8CEE9C0B7EBA9807A4D253B8CC391B7F600A2" + + "A5F51AFB01B7E434941ACC24FEC26C4909FA01FEAC3CD543C4CEDBA7619BE5707872C8E310EC1A51" + + "4BE4B30B037553EB159303C283E8DEA718D37F013EBC03ED7C1553A4AFC3202C5439FA6779104FAF" + + "22A16C827F78216F45098732622150E7FB37C0A7C5C8B3991983678C1DEB6882E3861DD1BEB1B43B" + + "D4C8C3F9D87AECD734205BBBCDF23CF718C2A20C852753BB01CF9402CD69DD9BF985E32A3FFD91C9" + + "B320E55D1F1E028275E0E51BF6725D0A839D0434EA22703E08B9CAB1B8B7509442E51DCFED9062BA" + + "2084D8894A1CA4B045C14295010E240827E760731BFE3803536E583821F382993231D917C0D7FC54" + + "6261BD3910001B05E94C65CE8FA35BBC1AC059CDDD74D15076E77A5A73205EB4CAD14F5A626F99B2" + + "EF1488496B5B65943B703A1F546B8EC90091CFBAC18F82EB74780F95016235BCB1AAFE093230906B" + + "F4DDA58639A66FAB3139C7E6A615E8F853F1F053A45AE2D841DBDF1584C217387A18DF5C435919D4" + + "1856552625F176EAD2FA46607F259F2311F5203685953E523519E85B28C550498F8B57BB7D60E7CD" + + "5CDC88EE8AC8EA3F50EC278C1247745F26067757A99D551E1EF887AEE5453A4C7D8C9D61A00E4F4E" + + "1E24F2FBC849229EFF0BC7AF51D82FB2777C3F974673FC086BD0C01B49702DAF", + privateKeyHex: + "866930601EB856FD921216F506039030224470B3361E4C1E5C897A883370A29EEEEC161576DD7695" + + "A24FEB1B99DC6418D50C07FE1E4A34B8BAD5E018BF15D9DF5C0C599BF5629CA0EBC1AB2983A541C0" + + "B5DEC0629774AD251285014AC12077446A32CFB45E22FB6163E326D25E3BF9E4ABB36E06E5381806" + + "91D8766D49459A68C2881099880DD10890CA1208E040711B889112036A1A006084C62D48B20CD9B0" + + "2592244501112489224E019664D0B001CC128C22904C0B03329936909A382D4A049020B2684A284A" + + "0111122406109A028652C20D91386503A9904B22808296440482310A268DC326824C4060C8802104" + + "C4288C8601193582C4C89118197121047023840D62064000880C02886023172ED826409232891B44" + + "080C860003A98D09160921C18042B0008AC4655A82008AA00442408E88286A21446D20C725014105" + + "4CC88153268A0431845A9005E4061298A40D59C2501C272AD02006408604CBC60081360D83084144" + + "08318C082564467113450583C84D039781A1002C8A869114343012418E22C521A2B850CB020A6188" + + "090939915B409081800494C670C4048CA432419B428163242E0AB4094BB02CD3268E190469D0326E" + + "64C8494C4426E2422508080D84920CDC280210088614045222B1049036450C9825134325A28051E0" + + "C211120882110522CC22014C2200433452D01840A4C48064106850C6648C066E52004D0130495324" + + "8982942550147114B1681CC6504146922134664892911849055B0812484069C3024A90C071830485" + + "D246248A385119B6309A826824B42D089051D30031D090449A048561422D03358842866413A66440" + + "C80CA0060D9C962DCBA44891C2654A96299226461432315B12604C3405D0080C0C85511B194C02A1" + + "84C9A08D0A48459A0644090710C320615B4205C44270CA382801041151880808C00119228A41B24D" + + "CB186CA0146C0A982D8B468C84202E92324D1B0552980006A3940921C70804378C014072A2A02022" + + "206624166060C48852C271494844D2A02540380E8A880114054241048C929851D82405E1B8109AC2" + + "409418058BA05194A84D2246908A2640C18404A286312335264B367020184DA38871C4C484108204" + + "8314068C048184B2901A928804386D0B9481CA44515A080D20158D12C22CCA989141188AD402918C" + + "448290C0094BC808D3A2409442001239450C49715B14898C3825440608C238662436861A816DE232" + + "8CCB886D942030D29268A22868200291BCA572BF2D756BC7BC31ADDDF460E70AA596D89A32B5906F" + + "B8A2387E0A60989602EB57BC9026E7F7790C3572961A8A0D406B11D0B9B273F4EAE9B65ECB31F5F0" + + "22F4112D0070600CE013C699B0CBB028DFD28365077EEE9B841575BB9328958D1D9836BA073DBF15" + + "8409CDD19936C60A1F42448D2997CC80FF491B1AE6065F89D18E9F5160C9659608278B6B0E85B237" + + "1BD2E23EC9A85B328C2ED4C31290A6E97E4E616A50EF714A89CBD85E6F411B45154434D8FB7DD4DA" + + "1934EAE3AD425489FE9E9ED1A722B834396A30261D2DC9BDF23D04FC1AAF746517A1EBBD2BA1898E" + + "FC2FF91E99A58D1DD82D6E87369935DD13DB75014F4B9D01937BAA077B8066C20705855FA9B1EA2D" + + "336E5B4E5D4EE580F7861172EE859D362E53A05414C1430852B072DEF5AC8F126F705433B8F14974" + + "7FFC943E34C8453DAEC3C95A83FF1BFC83B3C9CF2FB1F953C0D42A2F4B95527E4B26F18B14430970" + + "8C3BC401C4B35795D925BD80BADA011EAECD0CF569DFC76BEC11937DC5182395466348D0522B3490" + + "43BF9398B616962D9D4701D71D64E38766E78128116C0AFBE2B9F693E9CF2074BA25C05A9B1C2BBD" + + "1B9AA0C93A09C8C4E7DDD25E221A660E9B2B95DEFFBFF3B3F37A1226DA705E347A4812CAE821D0CC" + + "65BB0A0A0236328B473EE64A6315416D286135F8429FB2AFA913CA8F891C8B993DD17DAD8AE6CBC8" + + "E90DE3B9390663FBF7110E5469EC9EDA76DE84C344B2FC1534DBE0ABACC3E1D6DC77087BBD4BAA13" + + "E8F4DF3A29C015FCDDAADA9E1DEE1BFC5A8CBA4A7A8A591E4D871E520BB381A36F5A3E91B642FCC6" + + "0E0919A3D58EBB8C146D8FADAE944729BD042557EBF6791B8B131C9B8FC671D5B64A5A09BF5DF28A" + + "0C399515186A1774DAA7B6F67CDC289535553338756272E096A710BABF688E1A90C659B5A91C4D42" + + "B67076F4D9FFECB825CC22214539EB4066BD66520A69C31D8480FCE524BF7BA2CF8CBA9AEF6C8453" + + "82C381C7910517468211D5EECCE68FD7F7934C248F235AD9F5DFEE94F269EA48A89C33425318CF67" + + "4F36072F23B068D6E9E05D7D20E2D4F9768F92B24550BD28F9E607ABE8C6A2FC48AB2517B9BFDB3A" + + "3E25B06D6C7171BA5FD98D44BB58358DFC6FD94FE7E7C6477B974AFD02F4CDDBB49DEE8716091F04" + + "567DF7D6C1530112B8775BAB78FD5952FC3D7B7E158EDC9C769FC5B6EC257AB5753B223E639495B0" + + "1DA831BA208DD289171AEABB82341B4ECA053479CF2DB189124C4225878E60100A0CDC59605A4CE0" + + "33AFBBC02A6FC72CD1C8ECDE1EC5CB2227A24C3826C11FDB17DBB5C7E6332DC9E87DD8508CDC5569" + + "7E06F725C994EB89F357AD79D00F1982AE124182821288705BE40A5882AB44C2ED1C7873C7C9F7BE" + + "29FED0EE76D26B410455A56D7C7957470BEAF69520E8B5B53D3906A754B15539EDA335B4BD505E99" + + "32A358C7BE175296E0D5274BFEB2E06FE8538736B0250C1CAD4F4C1F600BD2438711014A67FB432A" + + "D7875AF594B7CFD0384F4880468649F9F013DE8A2A789C45E679169B13534DB0F0F3C04FB968F94E" + + "772AA354FBB915C080007C5B453560EEFFACB219BD0BD68406C14B51ED878E5A20DCA87DFC6C61F5" + + "4D5BEFAFC1EDF678B3B36B3875F43BBBD16EEBE2F10DA9CE19FF8DEB48899681456D9F9985026695" + + "830CA7DF3C407E12DC1595004F085AE46F5117BA19E042D4C73827DBD93B2A8088BECA7742D49CC5" + + "74998194A6643FEBE54899B4826B2E9B011EBC934320C462BB00C92BFAD9C0542DFA0FF5BE530F97" + + "F83E06512D113FD086320FF1F2B2CEF3CEF29E1306B1A885CBDCAD4BA1B431F31A51FDDF08A40FA0" + + "158EC4F7D557985DCD64A6A1A68F8222D5BFB46B598840339DB9947B2AF0F61C3D7ACC32F5576274" + + "BE43FF042F1E2E546C8335A82DC697824C91590C7434D230350530E94F4034C232AEDC8EF7004CEC" + + "BF28E8B4C1B8F0EAC77765FF183B18B97B0ED2B567075A5FD30F14372242E55DEAB3277138069452" + + "CA04B9A74E21611A42BC25AD63571747A0C4B34EE659AD5CB5C474CF86D9846DC01276C950BE1A46" + + "B4EDFF8A03EFA9A1B1609D8A804273D895B494D2455CE0247C26C32DA9F9E7A6E4A1B226CCBB55DA" + + "0827F71B54AC8DA25F94E215DB7E057536DEC9AADF5B00E0A67915674FD3D9D2BEDB9481417C25A1" + + "38FD2EFFA30298A1DC8FAAFEA2AFFD8D7D5F2AEBB03EEBABFA6313EC8442DCC9EB4ABCE2CBDE855C" + + "315EDB5CDC0CE9EB3FFAF4C2B476DF8FAC092BF2A4F05729168389C627045D0416BDC6EA34EBA8CB" + + "BB30B4055CA5C12D19A5E6247A7141F0B7652C746D16238FFEF2AC9CB7D412B02DFAA31D118AB1C0", + messageHex: + "7398C12475340FA38B36E2BBF1A7C9C6B5372AC4A8B9B91FD28AA268FC8371AF56C58462D554459C" + + "18E3FD2136B9B483A20480DF450473F7FB9679BAD0278788571974A52A6CCB361670C81BB1B4B64C" + + "457290840CC9C8CA6BAFCEA08A5C0CE0FFAFD6ED05F9F632898CA80ECFDEA6C9370317DC0886382E" + + "06799F209E54C3BF7E97FA587EEE505C4F980B44F7CF440BCF6DF44D1C8B78F90754DB555645CA94" + + "D1A0DE13EA76372C51336780804082E1CEF66569E8945F5DAAE4CFB51AA190B6188B857AB1130135" + + "D7DDE27CE823DDD70AF5F7E6FBE31F561A8F26EBAC0E0934AF50A35D178DD7C5DC614C08EB7AECD1" + + "CF7BC424D63F06BCE99C0788D8DE9724E5CEF6D5F4AD53CE19CD25029F09F32118FFC94332EF02A5" + + "25980A6A5BF1930264EC11DE9B05D099BFF613D9E42C54F40763796CE0FB10F7AC92DAC54613C52D" + + "A70A2EF3FDFA84926BAA3F43E7AF37FF5D507D211E3A0D92E00ED820973B43FF39FB891C2BB24485" + + "8498A7ED8EF00685B371018912FF2830275AA6417F092A1298CD33ED35EA705ED99020476B34ED86" + + "505829C14EDBCD6DE8BE079C111E15A4DF12227B7756DEDC324F64DF6D10EE2EF6B76095AD0A25BA" + + "49AA4413C7A3AE3E708D585A63E33DB1EED7CB739516182CD1CF40BF5D8531376C865FB408CCB4FE" + + "C3FAF6853DC0FD3676BD1BDF429240A85F4CDF7BA272386613951A611AB46F09B60D05D6BF7878B1" + + "4AE23195EC45CD87E77A6877D56A0CC9D0B5FDB6724819A85307240F1A2822C7C3B5E6AF3B091B11" + + "4B8DAA345CC210DB1D1FFFE23F3C6631926C9F0756191591AEC539E5462AE8D0973DF2D87AAC15F2" + + "0E7A282FBAD18CFD9A2DD923D9B34E3E6524E071B41E56464EB9B3CC39015E6B9078BAA5577AB68F" + + "36EE049C7037894A0A2CD9D917A56BC91F80A97060C3EC9FCA495B62FE596B3FFEF8171FE876C6F8" + + "2A139025A029B5EBDBB9FEC2BAB4874E0EED12362FB35E9B527902CC9146821E436325E711FA8CDC" + + "808A165CF4BDB900C5A8666B94095C4FFBA2202C053576F216F38073B54CF67558A7408B035A3E72" + + "A6080207389811C3D7DB33086FE584C01619B7332F5F09C7AF9F04A6CD332B2FAB90118AF58D0BCD" + + "26AFD3BF13A6145D4D0DBF2E89E902B892F79444663873AA9A47AE8442D2CDD548401C32189CBE44" + + "E36ADE40DDC6765914545CC363540E42E2EB5BD1EAF8C82C4D9CF40042170DEFBAF798747A5595F6" + + "18997C0AFE1B723D415E4A258C793B7CDF599572BC8FF2915F5BDED5914FA12C10E74B2675A785E3" + + "0FB18F35A86C4B99CC2AC41C82A6DE64BFF1B284FF81EED094F292D71308A7A37518199AF3B28312" + + "DFDE567F20361FA2BF5E2F1C4BFBFB284C83E82B7E2B7823AAE452A1499DC2EE0DFD80FBA93A537C" + + "1E10028B2B5187C8B96238B6A1900F60D900BA74B33DB3C1E95B6DD2C4B48A843989BC8E8B512364" + + "5805DEFD5EAC497BD044AF34BE8D06DA9F8DDC4FB5DFCE975F9662EB0CE0A489347801B918534EC6" + + "AA22B2924CEA1B9C74C86E2FDA58DD59BFF650AD73F49D83D6FC1FDA297AA30EBDB7A892398D8EB0" + + "44D6DFAA637B8553532A34BB620C7E52B5EC1FDB9A5F725473D2AB60AC3084F3B2B2B9F147536FF6" + + "D7B9399BCF16E0681854C2BE804163FEC827FDD2725D0D8CC603D2437596A778AAA01CFD5D3A7B70" + + "A51DBEBABC4AF685F52E88EECB1997F4B797D64A878586D60E7F0977C6582C5015C8EC0951C5249C" + + "4D59C9FB6CB6F7B318E3568A8A903891270F7FE1E744DFBE2AF4A4C2CDB0D70E2160DBBF17AEE58E" + + "60F0BCA6175745BA8BBABA28D345FD2919E0A9524458A3D5896EE1CF4BC34BE2385327E46EF99FD4" + + "47E91B7185607C0330268363901EE287D52A9FB72B8CA3A62B408950492D4F9D443A7126E0780028" + + "250C5CEE6A7722C1A47012BD96E30EB810FCEA8589A2108C15EEDBB2E086F8E7E8369B3945B3A315" + + "C512F359B9648C1FEC51ADD960E85EC146A1A20E8DE7D397CACC222203FA0ABDD54A6EE763562DB7" + + "FC689AB41EC2B30A599E344F71786034F957B0E71C88888605CB9C13F3B7607AF01486ED1BCDEE7B" + + "B33EAB8B811089715D619FC3D11ECB8356B6820D3E6749042AB55FFBEABE95991B8206E80CDE3C88" + + "D8DA7A3DBC8A2F500F70ACB1670AFDB926B86ABD98624BD89E5C4E016EDBF40267E9173B2070BC94" + + "73F75D359634F5698374C300E1A472F0159BAD791FA2486CA642E55D73802EEAB84B620A5261734C" + + "D56DA4B6479B444D478BBC4F5A75E0D502B0960980CBD7272B0B9B26F2B97BD1EA08EFFF784A1D3D" + + "4B66284AA859F5547154C3CE335E54C56C1C0165D890B36FD664A94FCA522AC67ECA67D49044442C" + + "7074B6A52851369358BA51A2109B07B33BB98FED8565C928FAEC2069F1AC7FBEBF1200E044EE2965" + + "512EB5937A24B39E3459811002043E7154FA9452B788C20D4ECCC7C43A3B0CBCC991F1C4D61D238F" + + "3ED7F2B4B9CD8A86D63B1B50ABF3F643F38BB19EB3F176260D3BDE8D8B14AC704B4045AECCB598FF" + + "6A7BB5B1621AF7A81E7CD8838E6FCF8485BE6A52CDF5028CED7E6BA39B15BFCB0F3F0D8376FCE578" + + "8DAB828DA09AEEB7E3E0C38B81A83F78FE2CAD48928554A109791D7C26B264494AECFA0D6D00B89A" + + "C6FE28EFB6C9452CBC3435DB45306488B8EF8D5834B5B50BD07A55C7D4FCAD3407F378F60D0D9197" + + "D25232DCBE35C49FB3CF091A34BF8E3FF435FC4760177FEE11F4100AD01757C20AC217C3F4AA41CC" + + "C2B5DE53EBBE2817FD480E64CF9B59EA152786FF0286559122F4D85DD68C88029ACBE3BA01941697" + + "F3129125A97AB6E31FEE4F7DADDB98A66FE0E801551C2A8F6EB7DF857E79D865A433DB9B2DC5720B" + + "F52E79001BF6BA79516133DAFABACBCFADBEEA1B85AB1199EF6B736755EA07A3BAE3BB21ECD74D58" + + "D265319012C8D1189B318535682CEEB15065D8684F8CDF82F245A2CBD3660132F35248745C61FFC8" + + "D4C3F4356CFAE95DAE8E88ED0A40AB1BD98DF21190A5DC8F66F12F518A9D40D852E3A9FBA8B910E4" + + "573270AFF6672422A4D2129C3A51AB7EBF9CEE7CDE40901F3E7E542E6350EDEC2A2C633B239B2B54" + + "6E0D911ABD7E57A7110C4B95A53B10BA6E944A22BC922F35ECCF1B91F9BD8A0A3293B7EFFBFEB488" + + "A010C19285DABB46BE5CF8AEA55EE726FC8C187106F8B8D39FD1706081CF176642EF80A4B92BC205" + + "402289B1902ADBA2F339BE1265F67820B47ABE48E0FC68480D88D88100DB5FBB9F7E677F186C4E5E" + + "1A515CE91824EF1A71807F18E76184A8A1A21EDE88F5F35022D6375411E9A13493A5AA64A409EB2B" + + "676077F42C8191D6D27869BAA1E103C4B501F30350577BE875AC99783757210A5CBFC08BBAA95215" + + "DA87AC8CD216E12C1EE2BBC61448EB27EC319D7F966C5E7F053BD0830E22A771C7074B3C7F671A12" + + "2C30E596D626462D43CEAE611A1A1D25C42BF3EC280D5D037891EC5B752FF59A93B899B39222AAF9" + + "28F9916B261F03B463C06B7502ADCAC5E477B8811F6F26D43AD4811DCE80E630A0F59AF3D3427B31" + + "130CCB9B03306E14D5683478534BEFC3EC64AEA15016C02E5C6FA570C2A02E18F00CCC0E331339E8" + + "75D2338EAE439F46665D93015B6B3DE01AFEAF3C18E4E709F7E2BCF391552180660A0C8EF6DA2C0C" + + "ACBE54A9A925FBACFF5E645494A0F282602A69DB4F4C04BB073D2757183D3F7F5243DC0B66473360" + + "BE0C3F961128BE8E6125CB355A7F5089C9BBF1DD86BAB93EF5757D522E54A72C5FC35B9FD5CE76F8" + + "1AAD11D17C34F5D0960B600D74932419AB14648821D83B73F647694F4FE6942AC86571AAD465535A" + + "FE9E2B69C79E74C913AA8569F83F5E8C57E536CF8EF36EC17427ACE85D37C4317E5DC7806493592D" + + "17F842BEA70851744ECEE29896D1B7C51E90FC21CB8BC255692C724AB4AC5A3A7ECDA145B98D5170" + + "4977731F8D2D5EF0A77C2CBFCDD7FAB83EFB4BF8799AECC1EE70C6F5C25E424B4FCAF9C6440051B5" + + "25EBE5A16E48AA45C264A4FBD9A13A423EB71FDFE384DC8C1D9B08781DBD1DE2F72599B4DD2B790D" + + "4FAA799FEB60E75842168461E349DABFA0C2CCE856FAEF3C03905BC0F97D58C2190328BE437C4EEA" + + "835F720CF9207353E5923135EE93117868BC1C3A4A6AB7B5227D82569CC051D2F7BB7B677257F81F" + + "CAA62BB0327B409B59C47E954F46A5FEC6E563F2403DF9114364B12E2E6A3DE6516B81F0697E9A86" + + "70C29495D19536A8E9A9D2AF3E4A8A4B96942ECD02B05DEE5A502A85EF8FA89995A13CCA8990A571" + + "31B3DF8C5997377BF1707F11173028AC8D1D257707675CC8352B4775C67BBC16A546FD2B5DEA0B80" + + "C731ED4B58DDC5DD17024645A64AB82EDE3C766418FFADDEBCD8EEDD0D40AFD363CCC2BF963A05AC" + + "906074735A78EE94230A6B0CBE6F4C89F083865D8A563D8B76A0BE95DEDB39494935D465899D6143" + + "3579334BCB25742261A09ACF844EE265C5FD10BCBC230D575637323391AE2A8B530BAB6CBB038986" + + "5C7AB8EC328F817B686613B328B54EE0E6EE4E55ACD19D1A8DCD5F06CA4BCBD8B139710A04F345A4" + + "8CDF052FC8B758B21175B886DC3AC0CE85BDDF78340D5A6E95DB6B816860569E752A906D9F23D76C" + + "46941324B960B41DBBD96B5B91BBCF1C4CA552A0249F47259A71E791587CA7F0197134042AA713E8" + + "7C9021AF85F10F5CBBE8E94713F1DE7A983ECCCC4831ADDC88F14CA1188B0536EC66910319E06467" + + "3D30C2065830E265124C8F30DDFF4E0E933A8FEA584D8D7EEE4277F657F1C6286EAACC973F411718" + + "DBA5EEA509F478635CE8F4E009D21109C702477048BD0B01F199245663AAF6881B99BC6A57558036" + + "B3C0B362F2B8C293012F4236C932B2971045FA8A2B2C240F4BE798CB6513390A3811A3FA551B47EC" + + "234F8387BA416FB364227E905FB84856BB087D39A4E5E284B6FC7839E616BA8ED65A427382DF18C9" + + "203DB14898F006B04B8A110FA91D4666C30566D20A90F1166B1680666993E0CD182757EB4CA68A1D" + + "CF83C9D82D26A457C0AB0763AC30F07829FDEF220ED63314623F364D750711CA681303FB081B145A" + + "388F3C9CA7430C4E75CCF35E71F231D27ED1F34180DCE6FC48AFA6B97F65441C5B60153FA8B2E555" + + "81B72A5B045A790ECC82614C3770BA4DCEE44E8D988D059F28F7B8EA01FE55DF1E2BB23B2AB5E197" + + "3C3E4685056C14144A163DFE91038033F25410E6F1B64D130766B94C8405630CE3E09119C1F8F438" + + "DDA9A14F115D45D77736418EC1C477CD58087DF9A5F2BEEC654F5BD7DBF86A33E2D2AB6884A61B85" + + "605F3E43F2C95B3EB76C112B2BD70A881225F52DE2A636B57933571D032E3A6A33A9D1B07AD0125B" + + "7D3E7D12ADE4663AEFAE97BF114F2F310FB8130425D87C357FBF0F9212F937A9E5067C11D8466E8D" + + "377DF58063B929423CE3AAB279F762F95055581B719EB8E42EFA793A916B15BA6A8DFB87D2CC8AD7" + + "DA8130CADE65A35E410E7DEE00D91A3205C84CEE9104C36DAE89171D55A408CD4459F48CD1BDAC7B" + + "E90A3E55D8C44382AB502CDA9ACF30CE0D01888BE08D68806455B2435BC58331A2E7BDC2D3D16E36" + + "14F8ABBD246C22F69C505254EE4F62A7CD112747FB577B560E5146BCC5CD1F5F5676DA433435928B" + + "9CAE9BD71C9282E9A3838FF231C5ADEF3CDFF3B7F8BEA538276EE77038062A5C04580CA947B73502" + + "083F7B6B0546CE3DE713495E9296E4A857E38E51948A281FEE9538FF039502853E864EDC67FC1BB5" + + "C07BFB602519F23C570F3E4A3D7488561BE36720FC8EB9E3746F7884D33CB8952DCBC61DE1430256" + + "B6358DBC7877F5B60A2218209248818699DDA4286FA872E5CCB7C1322A93793403F9697D1452C119" + + "97E72D4521844CEFFDF1B05A78064F20B2A10F39908D9E38683AA4DE387F7749381C2EBEC82587DB" + + "F151BFC8CBE16EA8D8A1FC8B9CF935C6A5F56AA8603D41BDB97C3CE6AE27C1AF2DAB33C654442DD3" + + "E2041C793C31C67403DDE68AD4B4872418130CF9B451ADF41B39BC626E38A48C803F5DE76259D0C6" + + "75F0375B1CDDE9EA0EA1FFF8D0AE1240EC7ED20DF83C643A390267BD9F96C6170CDDA7C7919973ED" + + "46B49FD373DE8EE7FDFD7D2970DDA41DB7C9F58FCA2F9FAD7572D75F96103E69A743EA9C591C032E" + + "9232ED3E433B89E33C3DD7D0021B303151F8EF770D211AEB3CC164FAC0E05B8E99F7AAFB60F0A664" + + "EAE480B0FC7A2A0C3DAA7CB4AB9D263D2E4E2FEA9F73C7BDEED34A2D276EDCCDAD9A14335E493A6B" + + "AB046E879D4962E325D2693CBE53FEFE17DFFA36E5D511AB321AFE0D814B10988BED3D9E72DF9CE8" + + "092F0339190EE8ABA8967F6EE1C558E8A3E0663A326C13280C834BA6FEA695974EDBFB3EBEB48C99" + + "55307A95741C1CD7943C440776EAC4056EC2EDA5A83EDB222BF48BFD9CED25E8E8DD25F67282EAF9" + + "29F4E5DAC8C08BD9D9982CE49C75777A27EC175F1645CB79170DC802C49E9E9AA68A1B1FB9030E42" + + "53A14368673CF5B1DFE995101C908444149EDED703DE7A1D01932092265664BCFC34EF9A8AE017F5" + + "E5CBE03EBC9F2DC61C41761DC00B77433BCD497F31DB7CC02851B04A57A0868BBC9EE37A22B5EB4A" + + "12526DA3178C0EAC7F473A106BD493C84603F4A7EA3F188AE48DAACEB8F68A75DEB453C5A3C2C31C" + + "F89A8A702A6A19666C9B70AD2BC9FF65171165DBA9074709B7657A843A0064B6B01F71E9A5309B4A" + + "6854D5000042DB59398EC50879743C6A842FA0C6B481BB429B71EF072238F3DC19DF4FE671CB3957" + + "2C2F06F64200289F269322980CB52AB83A46CC399A07883F840708A11463FEA6C8AD7CDF3AF58867" + + "AA890EAB7877E4228163496F720205A80F40EBCA68D229353F9A10F1D8AC1B83B53E3C9FB0978070" + + "D270743D993D40D99E548B55793EA6E628BF43F8E7B693F6A0E2ACB3DBA3FC9A9665090EB952F583" + + "92F8A76BA2BC6662F21743AC3216D5DB7F2E8F8EC0D3D145BF2E12E0A198FE6B6C750FBD91122530" + + "716D87ADE9BCC8A845AAA7B8BD61F9A1B5397EC7ECD8D079C42C68FBBF1B8527E64DEFB975877F3D" + + "F6FFB87112C398D571CED8173A0B7D6027FC3468F9BEA8FE1BBA7B56366A708D50B8D36A39F776F9" + + "9562BA6719A1E162A42523E515CFF5C96AF16888BD2E372B36F1B91B6E22864BE24A38EF8812F084" + + "4238856D95A77F09D3428DBF425843CE52427A0926249B2993B98D94D9C90CF7B1ABE100FC8A6EB1" + + "FADF3F094B19046FDF12B9940AA130243981F703587AE9134BD8D947C822E00CD784AA5748D4AB8B" + + "BDE50FC2DD57D08BF3AA23DD964636A53688DDF6A5C155EED497ECDA2C24CE5D5E8E498E201F9C29" + + "CF7F091E11B5A3C45FD77B17310A1906742FE27A809F0AFDC83592390A957DB29F0F00BEC8CA1EB7" + + "126D7A36229692F1C753239DD13C39D03DD2E82F6CB531D90E9DAEC4FBE15A98CDB3B6B97047D0B1" + + "64FFEF3B6E8B4F4DD4FC9F2362EB6BC827EA7EF248F7F0B78F9128218A0DCCDDF54B1AD77E58C38C" + + "8FF6BBEC98EA2AF5D541C73D25C5FC7FD66D933117DF448FE8370D8DE0400AEE27A3B84576C72423" + + "C34000CE9DB51503D8FB188846EA30473B32B3BD0DED36D50F64F23AC9D57AEFF6DA1B48277FC29C" + + "F41A7A161619521ADE811AF1B61BFDDE88274D5F520A1D52122EA298040FC955246AD80ACCBEFD5D" + + "C34445E7288D1D99722057F0D5E606CD2446D51377165F2468427FD3B470FFE018234658D84299E8" + + "4119AE63333298A33D8D7ACB9F15800A9D1D29C1755EB221838B226D8A445A9E117528F720FC4192" + + "04F4326791826B3A91D09D33E1AB5D6A11CE6075C49D9770F40B4D0B4F11DA3A500B6DD2C9C4F0E4" + + "00E70B22B44FAA5F807809FA37929E72C7FC2B82676C219CF251828C0BDDE31BC99708620F5F6C20" + + "8EB57771AECD8CD39778B0ADDFBA7C084A1A81216F3914F8EAB7C7C46536EA77A90B3CE3756BB673" + + "73F2C51FD5CDD3915C6D99F9D6162CCA98EDDC644100C55D98857AB34BD876E31457389B03ACE5C7" + + "1C08C42B9383FD24BE87BBEC4ECACBAC8EC8CCBB94EF9A21982C7CD33AEA5253D92B2F0CAC542665" + + "400FA3E5F90F0F912A72865500BFF24B15717FB9E83E33626DB5FB5E5BF61E151ECD7A873BAF9217" + + "E565116D4CBF09D58A8B02CB694533BB96DF958C27F5F63CE0D3150A947CD7173DE8FE1BF9C94102" + + "4222535232FFE934D80F0413C7CF00E4800B378EC24BF7DDDD35CB52790BCA9AF25C5C27D9774718" + + "61D8568C5AB54C083B7827C464335F9F4A2CC979174B0D2E9B5EC813D83B5CA7CF9CC122EA410AA7" + + "AFE29D873965F9BA703463351F16B423FB41CD645CFBEBD9FF60295DEECFD4AD62E890CC6E086F69" + + "C2250FC3145C08F8F9AFF1BEEF6C903FAF0C90A9CEBBDF7FF87892280FAED3ECFFBDD1ED3B9AE58F" + + "0AF819CD4FCC25F5119F7A41", + contextHex: + "C967E5ED2857C3594030B1143A1D4C250C1165C641BD53C7C94DCC7EF661A121E47D274987139CB4" + + "53AF0FB494C90222B021AC27AEAC9EF1B16C00C50B170950E545DE3D40FD46B838", + signatureHex: + "8EC20406B1EDCD8C9D17C99B2DEA6E5D599812A68DAAC8263565B7C11F7070D5B808E64C4287990B" + + "63F6F9512C44D6A574D7E726F28D8F4069515814B11BC0F6D3F3959BCA452B5D505586E0929CCC7A" + + "29371BF54E2600DCCB002AF182A0B423CD7B21FCB3CD3E87E2D1153AC4BFD23575EF4AFE1305BF1D" + + "A85EE4054E749865F33591D29E2D3B69950038B0CA1F7C89DD41FA29FF319746013FE831593E7755" + + "682090A8344594466AD77AB3E977BA051681D1E7A73BFEC150405F90DCB1D8C2744CDC698E520694" + + "7192285B2CABF74C324E4B6499467452E669B1EA1FC7EE9159A49966F528A645B3D3581BBBF2D83F" + + "19AB3C65CC31BB56189B5A8544666498733DB74ED7A46A6E89BDB7A2B4A90F62224D10AC1E9A76B0" + + "4C4DE1CD57210C3E6AC205274162F5DC8D818937F0D483EDCEF416ADE6D1D4B9B9CFAF078611CD34" + + "C056B804A50A98299C6730E03B6706CFA8B7C41F422F7580756ABDC839A56804F938A5C477D15493" + + "63B67FF30660ED7882F1C592E9DA6F5125DADBC22A54B9AE398303CDF9CEB7DC54F05F7C46E673FC" + + "A8C68E4A8FF65E1FF67AB3C35555E7E702A885BC23DBB89488A77923EAD56A11C0F54D3869B182E2" + + "16F71979D9C1A26AFC28C64069DD6582874553286AF85514291ABC69AB985BE2B471EE7FDE539A73" + + "5C3F0E0B1F2367530CC0D4BA1C410D8992ED822CE7F360403186CBD30731E38141D2AE1FA29C41CD" + + "9CC0691A76983C6AEDF24ED3221256B97E6EC6E89B2EE3ECC0C6A281E86C6A9678275C8054F5E829" + + "C21159DE543BABEEA13D52DFE7EECAA9CE30B8CA3941BFAFBE5DCCE5B283EDEF5D929C8FA725AF53" + + "50ABDA8D9A4EA6C26097C1FEFDA904D572A5E763A28309DC1C58CEB8984601B6AF9D5C930C9247CB" + + "6496A2FD347D5213F4018A50FB4A6841CB6FE99AF0BB7B0CBE6DD86B10CE674D97B8A9E97FD2F1F1" + + "CC117C1B470E3B1DA223612EFB216879074668852AA5F0A3A2182C240753DEB3E9537D9DB426E0F9" + + "328CFA70F560143C71C06E56F0C9FC5A52029025DA03E631525FEA32E58F40D225FCAB6AC530EED7" + + "F08D11F76C029A302AF94EE01CF8A566AC2D3B503FAACAC975B229BCCE9287F82FF20ADEA967A757" + + "A7249DE24E181D99AB894B5D718B1DEBB40C1E57045E0EFC1CBCF67890D93E479EF45A6FF6691A88" + + "C3F5B83179608AF6554DBD5C1AB1F11A81156425EF91BCE802BF46B183F5253E234889A87BA3DFD9" + + "34853479E5BE750E314FC0C923523A8DBB7D3D66004231EEA7E952F3D48C6E2307D7DB4D3484C191" + + "E8B561ED3DABA762AB69FD6EF6FADB272F4200B311C1B73FF7CD3FE02F0E256ABFEB67C2419F0B6A" + + "E11C877A93E006E446E96D8BC7E6EC7C44B32F0036444762D34E9C67679BAB51DB794A72E4EE39A4" + + "DAB08472B97298D66C56C3F216E340BD3C0B0F2D7BDF32466798261EA39858F1406DA09D60270D2E" + + "C2BDD4227E4F34350B3A9098BD2249FC249BE8A306AE5A22BA03040F04127BDEF28969D259E10AF5" + + "57559C71DEDA8532DB78D8081188992EBB49B06DC036397DC744BD0CEC01074616474C8DCC51D7F7" + + "A4A8DE8459146E6850B5D45070B45DD87CD33FAD1CBF6DC6799213E9D8DDC10C00838A425FD164A9" + + "6347ECB643ACD35664ED18E20DA6A8E898CB717C774FFA9D1FFD987790E9017F218C75B83FBFDCDA" + + "BE2CD3C1BF676CBD9F94AC27F472FD64956CD5AE2A7A99375F324112759F71EFFC59A1F6062F0EFF" + + "A9785D313F06B84003B8FF0866BD08ED7CA73A4FEB4A5782DCB877778DA0BC20ADEC65222FCE71CE" + + "901B45E570805214D6AA407AFA35EA84C92AA7C0923272203313EFDFAEA9B5B7A442219ED2DDEF47" + + "558050C5A5F15DF90930A99275980005ABC4E3E79C9479B4940349FABD43279B96D51311223254A4" + + "F5117C7ECFCBC7FCF231D77C3CA4B789EB3606ECCC653D5129E32753A5AD07B60278B9A1C7CF84DE" + + "5A6384E527CACEED16694977CF8734124DAAC9C880F79C33610F074E19C7DCB8BA532C13D21DC27B" + + "BAEF22AD089763E3D8F14601251B0618FA8605658142A508930141770E3841AAF0091C9A3C9A63E7" + + "BE31227A5768B9759323FC98D24F9B87CFDC0020356E6797B6E5E6188DE0AF1FE51251D39F159913" + + "841980C8AE4853144526F6E7A4C7AF9960A637D6A83D914506AC2DFF1C50C1054573B570CDEC3450" + + "CF242BBEEDE04E4BC0E3048B1202096F111F93DAC9255CF9E945CD69E39008337C1A796B5AF7CE6A" + + "9FB2BFC625258C609368F5912ED7ECABFE8D59967D6933968FAA519CB25095E4A97AC23F1239A62C" + + "AC31806D341E959F7812816069DA8F874400C228EF8706149E3A17A043747E32E0D2DF5483C97B62" + + "DE642B91072FB34AC55DD51CE1A4D113AAC3A40DB842CA5F3B995FEAA64C8613700B8A160C227EC4" + + "EFC5C22F453C5771762F76AAE43AB92C7DBB10C4FED9E8B12B4F7783DC80544F3929A4D8A57E64E5" + + "8D46FB776C36DA323632F6E8D1038046BE7CBC02179DAC7B021A76C75A0019FDD6C7451A0FE1B29B" + + "363F8DD4AE968192E40C2D178A0315B07E5F5E4F3F52A126A54797FBBDD7D4F12B7132E2FF4023E6" + + "A23A496E11FBD10BDF0B91B2E0D9A8C1163B779CC4D4779F2275A230AA7A6B64471BFF569BB2583E" + + "85C49D4C6571881C84D5FA9453E7680AC3D2FCC8384D1F19E5558ADA091F045E04EFF6F024EC65DF" + + "7D7D8CDBD552166217FD8E086C940034AA28345483335BDB96862963C0112FED7655890D56B1FBF0" + + "62A13760A3C213D1938667E5ED9CAB9F167D39BBD82052D7D475C12FD774A4CAA83EFA60792B99CA" + + "39188B72FF238F8A0B774A9528EE2DADB5DC63AA62CC3A1F38AA7ECB2E934AD3414917C07E59D66A" + + "0EA05D23574107E90737574B38862028A45DB779FD5296349592CF80D28372A80690002546A02EDF" + + "4CB28FDDC088B1CBFE9A43B2CFD09B1716EFE22FF46CFF8ED916F9242BEC7B80043B362F42D8E564" + + "64D4BD342201E7BD56BD06BC9AC86FE10D7755BD3CB8CAEC405F9AECACE7531BAE1BC21B8D8820CA" + + "4EFA0BA608E9628A21FC4DC2CA533AFBCDC17EF0D76598184C6796B8C23D7711CBB687BA5EB41401" + + "D15ABFE35A51B0EAA9DF2F73F5EA12CD17954BFF34B81C04D15DDD6029DABC955DE35E79F1A475F5" + + "E229E54E039F095EDCDA5386367A13DCD487FAD3ECDA192AF380F95FAD4F96AF94F7610C0D73D296" + + "A9051810028C78FFC69273FC56C40BEDF4812F865A67068C4E4124E74BDDE031FF5D31DFF17F5BF5" + + "CC7EAD08793080C22390D48C41354A73111415272A3168B0B4C4CFEFF7FE0E1A2425363A45545758" + + "595D6C77797F818795C2D9E9EE01073F577B9EA5ABB1C4D7DBE7EBFA253543474D4F5274778F9DA9" + + "BBD9DBF8FC00000000000000000000000E253445", + hashAlgOid: "2.16.840.1.101.3.4.2.3"), + new MLDsaNistTestCase( + nistTestCaseId: 18, + algorithm: MLDsaAlgorithm.MLDsa44, + shouldPass: true, + publicKeyHex: + "660CFBB3C96CBB29AE2D60277C4BD97111AED10741099DF59CEE6B47A169BD4302D4A8C271C8BC51" + + "A491EB4D2458366B6A3FA1E8A25810BD43A6D426489661D597C06EC9A0DEC66D8C7ACC357489C92E" + + "9B28E494B2BE9BEDF5D6AB2C5516B901F426D60105E9E2A65DD12AA5071054811C3117283F2DD55B" + + "D1018942EE7330A2B5074592E26C53E38160CB8611EDF93B123C1AEE40C458914802F42ACBCCCBD2" + + "BD215D5273AEE983358F2CB3A44DCE30F3F1E387843BC6824565540D522E0573B4073E5563DB8821" + + "2B50EF7E1063D55B77873D774E250F2F4DC150D964938A81FEB59EBD3550D6A3DC3CDDA8AA82B9CD" + + "24E9D855F254514874C299BCD602DA9DD601602B8780965E0912E818944034D6F78F4D2A7835B94D" + + "4C8447C6D6D82B3F7260979CCA94D5072EE2D3D6E14FA1EE705823A7077CD6B4778FF1083B7FE38B" + + "ADBE6D11803189941A0F9EFB70EE1F581E7DBFE32F10541BBE61392ED85BE6DBC6F716955CBBD62F" + + "34A079A81F0B7199E4796D831B2C7EB48418F23BD79A90CD15F307C419D39C7FBAE2779D3D6D7D83" + + "48762585E2DE7E2C6CBF5A506F210BCFC848CBED678E21E7A9A4098D1B53BF20C780AA6C7F14DB25" + + "2B3A0A6DDB0754C56F8641650DB03FE037AA377897FE7853AB4DC03037F4994C54D590B44C2ED6A3" + + "64B5E01CB9759BA3565E9D5D87740DDEADEBEB3941BE5165C1FEB7B434F85BCFA1A6F3558E8C386A" + + "9EE6067D3EADF87E642F370A56D49CC90EFC9E79832EB965418C8473C8F9CD702D09185D7D977983" + + "3B286E7328D05AD81E15D9FD8AF186A3CB0B358E88FF642F11D85809998E828D164AD530D686F819" + + "DE1F6A3634FF6FD420AA0DA694B2CBBC5B3125DBC8B20C207DF5B69B66D865CE75A0D7A50F1EE98F" + + "C0FC9C6F2DD5B3A513C52EB0A4D3537E98A4C8D85FC56A0ACF141DB24747067709D3763F4930BC09" + + "279252F6D10461C3B0ACC4BBC9CC2E12A8803F5690F7B8C1301EC27FE32C992AA34DD7587773CA3B" + + "CA8237C87F2B39CAF913D0EDA328A4B6A40D9713404461E29D55F854FEBCD2546966E16EB4FA49BE" + + "8DB3B63F2189097C1C9916DEC8B1F1365EC7194203F27FC257EDE87CA2E825A509E36D2A2DCB6EFE" + + "EEC68E991D511AE268185EC8E01010938AAECC3047C203B18AB256188FF5EF44189A8F27AC0F0EAB" + + "DA0923F859DB1254C9B10F1D6A560B718D6B8AF6B7D270EC9AE7197DC266862E19943996C8ECA089" + + "188E88AE402995FC1EEB20FE0B8C9B6CD32DA7B680B48072ACAF71D0910BD235F90E94B5CE22F597" + + "B16741BA9EEC076C576F0C2861437E0C2E0E20BEBAD18DBDD9B31C64482F4715BFD26A64E012EA30" + + "B0B5FC01E09CDF222ED20E66177480AF099F85AD9AEBA1B6D913566487F11C80179277FAA70EC3E9" + + "813ABC8202DEE72E9D7CCC8DDAD84112BEC1EF29D7BAB653017FB32747A1734A65F2708C7F8711ED" + + "7856737CF2C566B013E984FE6AB456ED1C53606967ACEA50C1DE5373A049EC3AAB02FCC0C1E8E7F0" + + "3BC3B428352900763F80936127E1DD7F3981C68ABD2FAD170E71BFF33EAEF94F08A280DB5D17D660" + + "90443842F639E70E9BE4DCA09AA56DBE1B84FA33F970CA77FF30F49FF8F06BBA04ABC7DC6BC2D450" + + "6A737C2514B1E99B44D4E136B4D5B7543651199818A977F0A77E13E4AA258A07C9DF0E0BF898075E" + + "62AA4F5D04098B6D3428DC4D0F90BF0A91949D7C76F3CFF57538C8015A8DAF63F7694AC8485CB57E" + + "C373012F07DF41C6852E40C6EE2F2952333CC5E08CD4BA0AAF18016BB1B8521C554674294FCF1CD1" + + "6F8DB507F0BE60BEC505AD3722057D1A76A07EC6782E3FE0A66CCA86AE0D7E80", + privateKeyHex: + "660CFBB3C96CBB29AE2D60277C4BD97111AED10741099DF59CEE6B47A169BD4322B7519ACB08D365" + + "CE6D25F3F67DBD87E1FD122FD4CE4B31B5C2A0A3ADAF9ACDC2460DFF494E413F6787671FADAC28E0" + + "068B4735D8FFFE999A67F044FE388A6D8C31C4DD6B1B3F41FD5D13C01293DB4B2CFFB66DA87B7ADF" + + "AAF61502D1CA70DC933051989688DCC22D1845618AB42099C265212288C10289C0042011926CE484" + + "89A2361022358609C16C989645CA9268243031CA488AC1B08412922964202950468C22B72D8A1800" + + "1843502483281BB891242782D4086900864C4B1271A3868DD3088C21144E5B902D0A098E62140C0C" + + "828C1C88300295040A230A08206418104A12B9010229625A1808CC288920980154C268C8026D9CA0" + + "90599270C3164DE240911A37820A07851B04110139724B280220196AC4164023B188031405084164" + + "084330102944002362620640E134121BC689D4988D1B488C09A98CA0402920A984DBC44002888DC0" + + "0021D4884462882880A2495A423010C650E04691E02425C1C0201B9091E30221D4420CC2A6445914" + + "658B025013258914890491186D81A82102104584048002065201058C1C243211940462226D444066" + + "834448E2380898480588A820410060C81481A30620214582E13260A4268D5B244103A10D582640D0" + + "84100B84294B9620203552E134905A3045D8260559B848A124520347840C425101298063B209D1C4" + + "6121A504D0267023456D61942C12116CC4106E1BA48C0CC00583B20819072CA28249042521A43006" + + "D8064919B54563108C241628633025941251528245CBA28411C785C4065089462DA0304620390022" + + "A60CCB364C19A11082860123425220B86524462E4A824D48844C1A432C42426199026D5A4864D200" + + "8560B22D19C7101B326C9A967012488CD144225A8848902469811086C0941084B629210161091661" + + "5CB03182162219B085241891E0243202432622B78118192A243030D3264E0135211C4205D0B86442" + + "A80D92164C58B83113A08009434C49269052C264201780A2B0109B4050CAB4096318519818901226" + + "4E04B14520246918094C64888D0C9851009010808240103201D4124909182C801271204868081821" + + "0C360C418808543204938084CAA8504186710B4021931624881004D10885124141DA8488E0124213" + + "912DC0382D222326E34649218450E3304AE1168118A209D14000524470A0968C61164264C62C1887" + + "3060466580B22953484E24106EA20671D4E4C3961B57F92171F441DD5227887C7E2AA4E4E0812EF5" + + "F502A97449CDA602211C42E1A4CB7D2B92E73872DDDF0F2F680320214E487A95B37721A139F15D7E" + + "0839A464AFE4864C77DCB7CB5720E23860851562C1AACB394F4229B6587CE68B67EB95C9C8917B30" + + "49C0C7ECE4B9BF5026910882E3FF6A25A6DAF827084AD7C2EF819953D9EBFEBC4D2CE4656A8815EA" + + "B492BA0FC67BCEF67136A012A65B8AFA2EA49D3F7D4FE2C609FF1B636FF48547E842193BBAF95D65" + + "091244F6BF2CFCDFBBA6A6B9E0FB6CB011210FF08A09E9E5165414E2559DE20B116A8868CFED0F92" + + "3B8088F520C2B2D2E6FAD640F7789FA669F8FE9779E4008C31FB77CB1BBEBE5BD99DBEDCC62CB477" + + "78960C670F1B0204B5BC7B5CCD0C32817A97A7A102921B6E0D77335BAD7AA240D60EA8646D9449F2" + + "2844EF1DAC1131701BD6201863E7314628D450157DF5C2FFC2A93F80A12CE130D44B1F427C0C0B65" + + "797F3C538D62294E2661C4D64ECF605B916789EB6A1596E5BCC8B003F963C18BAFD89E9DED5038D3" + + "39DE124237B51E7362162FE4D4422B9BE7CD2AC424B932AA3DDD7D25F2F8694E55748CBBBEF34AEE" + + "136DD2043CD8D85A032C0334E1A00290225C549C360B679FB80401445AA17AF294254CDCE6C7EDD3" + + "187DF93F340D055007ADF58BC55B6100335DADF3C0CB22C537F1DB1D58697AF7C321B7A426A56C82" + + "0E301A19A9D2B0D805FB847F93B6EB1D0A8E4BAD1526315BEE2ED30AAF332CBFC7352014DCDE1443" + + "B9620269CBCDF8286A694EFAEFF4FFC9C4D5E0A187D94661AF8915BD29E6E8CB87717390CD8A8125" + + "DED0E5691502F5AFE85E2BD0E4C2EAF989A52FD7FAD6A4D987E5CAAC31551BA378F2241EF6FE0754" + + "941F2E242743AEB5CEA05E67B3E4604FAA96F147BADC6471A414E6C37C507742FDBC87BA210CDEF1" + + "4423F1B5BDC73B7AE62D46BA049AAC95B785CB49A19EA847F248775003CA0C4640F27CFBAD6C8F2E" + + "C1372E43421270080061DCDD53797B319B6A4FAA54282B6B2F78D3DD0B122D9B79465D0253607A58" + + "B44A7F57F689B53B59ED3BF4A3D69E824168C3F4233042FD224A83739C6E4CEBC321E806932006F5" + + "F35D282DE640AC47DB9E2B38939A8EF85963A7FAF1F8C8F020C2CDDBB2F9EF8AEB421CBABB37BCCA" + + "C3C94C5479E9476E4BFD0C781B71A5D9D90C2BFB0AB69FFBA59FD2C6927D7EA8FD732782DFFDDAEC" + + "5EAE3743128F4A886F622C0483EEF09B5B1F0FC29BFD5EC3FEA64122689B395F1B21F244020D8C6A" + + "3F3CFF641200B102298F3647B1D8EC34F9B6BCBD5EEA37EB35C7B8BA4EDE63535A5BE20006518425" + + "36923E7CEC7FDE3A4A99B5025C2CCB4E57E28E44DE8D7864BFFD1147D5D98970E2642E15460EDB34" + + "F2AB57CA546A59624F31FA2CFA4FFB0AD00702B18032E120D26AC8C19FC66D31F7E411B673CFAAD0" + + "0A4E272B2E486209EABCB3979D326EFAEE903A0F3C7FC182B43F013660F81AB1D011084E2208E15A" + + "0052A7014C69B59E2B2A9EA6F505762FBBDA1E73A5B6A8EB3173DCC61B5A76958F619B2FCC5D2671" + + "062EEAAE609A38C02AF708BDC6CF29C3A623F49298B07BC8FB22AFDD28DC2F04C1FE1A3AD7522D9A" + + "A8FE1F206D98CF22B4A983DD5D5D08462B72AE1E9C415B6869FAAFED5AA577B06298587D82FAF5EF" + + "04445D094E380D5E223AD31FB7A72EB9563B55FAC63415C19B15CA87055D655B5820DEDB0DD0185A" + + "6BF18CD3E8DD0F845859574B77183F4A2F12DA0DA2DEE0A16421009726FCB377066362369BB96C5F" + + "87B9178BA80C1E54BB4F2AF834ED16CA37B3CE5C49BA2182A6720DABC479709A3131DE0744D7C15D" + + "FEC25C2F0A1BE1A3A54CE4404596B3F3365F16C17730E0E969B29C7043309375E2E796389F4B75F6" + + "344234606D546EA0168DAE6E56B6E5B5804DF510D4BEE2A52A5365A2475C8276280451AD071F70DC" + + "00F954206DF2AE9839CE0357A3E4372AC9E2D9DEE1FDB2A17396E3B43F35637179024D5B9CAB462B" + + "5CD7FF6ECD0CE54CEDB2001ABD8672993372323CD11458FFD79252B943454BFC3D8C856B48530E17" + + "2E1DA792CDED9DAB23F148884CF17DB7135AC16BC32C3822A8FD0406B99309A7DE5430D3077B466F" + + "538F0DBCD9CBFB120B58C5AA3118C4278F2DC1C83500B06F00D583345B54EEDE181C7615384D8E60" + + "31DC865E30312BE632F2071D01828006ED4B0E1409FC13B0FC5CC1BCB08C9CDFB038FA2DE3D7E69C" + + "9AD595ACB1565922AE80B62375484AE73049CA912D0D312329D4B1509DD6DC04CEED2DF430848FF1" + + "5CF6A5B665D78964C55EECB9A32CE8E1C998735D520DF846EAE7EFE4FCDE49B332DE4E8ED37B00C5", + messageHex: + "6AF64F60229BF7180C6B152550A3EBFD9F998D1C0E264F02D4EDE229556DF93C4960543A6783A312" + + "36DAF90F37326E79FE5E9118D12124BE31B7E3C6AE2DF3057A4C57BF1DEA5C30B15E3D33E581B9B8" + + "B4905648737388A1207124C3B35571740DDE90F0EB220A55A7048C5AC2442F567A971C1FA100E30B" + + "3D42E2273F03343DB8007814D83450D0B0F849567FC6E4029864C6E8932A7486F368253BF3BA4DF0" + + "5A0B20A747C8BA4180AF491686D674637ED5E28CF38F49D9A7BFDD9276D07FFA0ECF2DF32962D87B" + + "F0BA78DC031C45D1FB9B0C73B45CC088FE49092043ABFCF98B4C32CCA86FFE8A4996E8B4184722B1" + + "DF213E72C90B47419CD56328ED2111D96E912425CD25F2390ED67FFB9E5D5E6172F64155856A8AB0" + + "7200F29AA90D60C892861176A995A82177C3DD53BCBA428F700C354DEAA4607F07CEBB75476AFDEB" + + "293BB5E0ECCE6EA7442CFAE6EA917E2E763A05A6F88A034867FD45183DED4D72A9C8E53AE8B8C975" + + "B32DD8EDEDC87D4CE6F86395DCA6B30F759E99B54422D51D1AE7AE68DE6426D9CFE14DAB9A79E600" + + "B3893B130A675A5730C39E0E92995701D97267D4C830D5210B6DFD36FEE3D314AC2B4E9B23AF9081" + + "BC7698B3863247CC184B8F6D8D932B02245EC29BE916CEC8772540D9666F4D68DFF468F432FA80CE" + + "08E64CCCAC4A39ED04B50A71187075246ACBAE06004FB364183BB7C78130B72ECFDB0B5E3A389425" + + "2C412919D465A497BCE924E92850A9144587054070662F2ECEDED6BC07320E8FB5D657A963F8EC1D" + + "7B282DB05E850DA698139149C849FC83EA8D11C08320BFE99A836F35F74127D6D0CD896CE919BBE0" + + "9E5ADDC71BA812240C4EEB8BCEBDEB059517CA1965AC0175DAACF2DA6E09D1D518E07E6F25540165" + + "9CD5E1F8B60283C3A8F876BBEFD3C11DC9021C1D0DAFFAEE46A18D528094FD0BD3B9ED27C9CB77F7" + + "CA008A68F81877A533FE032260D41F8AFCABC32EF94DC332606ED46779F41CCD257CF12D39F79A0A" + + "D0869F44C65E7AA721671BE5989C74BB2DC45F9222482CD343CA81DA7B40F218905BCB6D09F0F6C0" + + "01F6AFA6C75F97A6576D6D2B0F2A659BF4A834BD1F7B9DD00DE3442F43CB289AF06FBD88E4217B77" + + "87A0561911FFFBD58B0E39328BE630BE7E93C743D71E46AD867E2B0B00F1AA2EDAC0A44F391C64D5" + + "261C4E8979AF191B7ABD798E4F56382BEF903675D422F1D997B3E1A402AA7BF821169A0F49353DBD" + + "F4002DF1CA42E1BC64A6FAB51486EBC12B97BEB76C0D1CA8AE43D031139CD1E9454BFCC0E31C7156" + + "6B4EB21E532A3BF247ADAB1B1E8308F0C1110E3B984D0B16C54DDF5078336FD7B3DD3A74FEDDBABC" + + "7F697E1EB39636249B74F453F32434A6C3B0FC0DE6BA5BC5CC5EB255A7A365B5640260CDF3CEC6C1" + + "5AC60BD4F93C366532E21863931EBEDF3671ED795891EAA748EE8F298A6788DC138F2CA59A9137B9" + + "D80AE6924BAEA4F32BEA347BAADA50866BA56530F50E70197463113712EACA6AED9754A917564CAE" + + "1F8538FB80FD4025C73F9064FB24512CB3FEE8985CC37964E6B478EAFF18C6FC096155473B24175C" + + "FC6DFA8B4FB01E658253C1DD52560F74CC741F97593C92C2CBDF141A8AD38075DC3AEE6C3745D805" + + "4BD22692DA91DC1E7BDF1BBB99F397EADA32D128B56A38A8E69B6F2E748B53E72FB88AF1266CF49C" + + "07C985C27C66104B6963F78B2D08BED6C44DFFCF2DE4E700A29822AA3E014DD1BEFF307441FDF6E5" + + "6A9C135C8CF67F5263C9F3743EB29C383EC6C0724C7BE87CBF8481AD5A219FB7C13E81C91C26C762" + + "0A6E26267E0D563FAC8B96E1B5B723EC662F8253588AC089EF718295F248C3D4A7752A70684FAC42" + + "D8DA381BAB8F2944D37412E0FA6ED735DE8E752B502F1AE5A64170DEFCF76179107DC230C09F1765" + + "9DD2C40C2E6A1518532768C9C8BDBF9A0BF8BAC3F5C6179880414A0F862B5C46583EE810CA25DD61" + + "0466A51390E2BB5B8D495C1CE570A385E28E310CCB197EF93AF8AC84184CE36715A033994CF927B2" + + "4D16290425963F04C2015CAE8DF30138FFF20DB8950871B64D82B3257566873F3CBEFFCD517DEB47" + + "B0418C8A0331EAC8C5A9FFD33964714CE47B8211DEEF464F8B60DF77BBC7E1FEC6471C06555632CF" + + "939214BBB512A01C35BB95337BB28ECD47E1E035017D5ADA64B5E6DA81A70779AEFDC36DBC8E306C" + + "96E1F416A146B3AD219DAE5CCFE0CD57FFD149E67F36FE2AD137792F5FB06AF63EB016CFD45AABAE" + + "9B65117FD2D9B0282D221E27846F1CACB1C9714DF54F13321D80368008FB791DF8CE559BE3B0F343" + + "846E7E72E3887674301FCB4E78A47DF101F42FC51D3596AC9501AFFAE44DCC7C17E9F2724114274D" + + "4653B59FA70F1EA8C83AE8AF2C0B2D77E1C0870AD5BCC8E6BF725D974D462CEAA45CD14AAD776C1C" + + "0B85B7AC338BEF758040B86DFFCBA9179D6317142B2A2D80E71C3B1B80ADB8992D86D67FD46549D6" + + "8689C17BC61306DF7852F8651199A2E1048B127D6176FF42BB7F8006AB226995C828AECE0C320BF9" + + "999C9180F07318AD8C81A13DFB12FE3558CEADD20DA07C0AD2E8D929472F63A6C90E8F60AB571069" + + "518DA6282C3B7EA152F5FE70D8D50828FD3DD701DC6A3B32AACD7979B3512A573E85A715C87A47AA" + + "E9B59483620E74438743B2D5AF4EEFF9A26FA273E56757E678607E4C188F6BAF138750CB63DEA24D" + + "415FE10B38A3B8BCD2C0A5342A5A313981F761045BB5A2694EEA79670BC1B947A3CDCE16A1D9DEDA" + + "65D902BBF9BA9A8CEE5B8D1D26451A107683E5177D1D95D57B9EEFC4E71F940F15874A75C619EC34" + + "01F784A09635E69291B53636E8F461B04EC8D4E5EE9C8473FC24530CD8ACC6ACB9CD0BDFCEE49E4F" + + "83DD616B929033689323218CC5A6020CD7528535856A70F221C8C71C5CF5D370559A8BF0A95BC681" + + "59D876499FE77581EA67D5A154F3EA0FCE0AC758128C410A6CC0743B27EC74ACF4D9286F793EFDE8" + + "21D9A99EFF4030CAD5B3DC1D07BA5A8148F0889CD0975A9306D4E285BDC0C2AB28CE136C0E89FAF5" + + "5C45D3827F7A81D65FE62F3CEA25B73546B827F9358D0FA9355C988991B968782C72C188CDA14B2D" + + "CE1713CD69F707C057A526770126671ECDA023CBA84FEE72B39934F1E60FDB6C2F29209CACDD4A58" + + "2741D9802C1B116064A798A80D7B57EFB4BFAAB34F2F02302552931387CBC565493046003FA3325E" + + "4D8421E84001BFC23DA768724394896D4218235E795EE48590D8AACD3D94971D32ED47D99D444949" + + "B10C726C51553EF3FE8395D6C0644B955DBE2D894A71CFAF14B9C8818787F1D7EEE3C3C5F44243BD" + + "62F43E0C44ABD6FA6FCF608E1C372D74D266AE9413A0E83D90D981975EBB65BE4C49C178E6A115C2" + + "4EDB2270C581B1707B228159009006236D25AE5A6E25D592402610CDA7A89754BFAE2419C456623E" + + "34EFBC344EA5E45C1669207DF5D57172F5E6C627C0E5603756CFFEE4EC1C8C8DA2A42FDF97CA7907" + + "4DD0B208E0ED23BE93113650E305E263CF54FFC7AD322DC871006B199404842B37AA2DA348308B56" + + "97AC161AE5FD8E0DBDC3E41BF6B0B27B73FB386B44BB6AA92B1B4E7213A027B46FF5785FADA1C3A9" + + "6CAFD4FEAEAF47861D404470E4FB4C0F0BC3BBA9A7FBBD92C293CB3D37CFBBB76B1D6790CA766DE7" + + "C5F66ED033EA473B33AF2F68592FC6D33F9F751B970C7C8C10775B2C377FBF3A2C14D96ECFFC3238" + + "AE624AB35BCC2FC7499E1089B199FB9E643DCD6522F69E7E638B3588F610724F2926B592AAE1C9DD" + + "DC7D23D5FD22C5619DCF7F414C5B5E64F5F59525AA0C446D730DAC77FB996EE47F19C0805A9373F8" + + "B0DF953B7EE65DD59DB12B19C649F79DFE7E69711B7641320BFD28AA31FB15210E5B6FA1AA43EBDD" + + "7FC7ED3DCB79E2A7C3F17C70B5825420813F7E6AC3DC9D8BEEF792A8F1BB8F7BEE1EF36F97C3718A" + + "68EB86CE870418A004605D39BEDAFB723784003D034A934AC00374CD225880DF793D44BF4FD410EF" + + "3495F384064F7E63EC16C817A2EBC7ACAAD6A297F34D36F7E463893D3EE888FF9CA228CAF73D2062" + + "9A681B59506542027A83A7D8D3AD915C60EAC127B219CB076F187DE5ED423051AE754485A997E2A6" + + "8B3B570AEFF8171A87160D278FCFD8DFEDC4F0320CCD3ED28E96D0EBC719726D1251F68AF9B9CC5F" + + "4A89B22C14BEE87F600B9E1C05F4F881C650C3BB5862A33A4222E6784E39EB8BE1F526044F052351" + + "52284D6A54B590F9C945C3E444AE55718D023138103BA8AE76F2D295EDC1C78935086AADD3313D74" + + "5AF6B3F6E7617EB48A14C5178E585ABCD6209C912AEAEF7D3CAA46C262DF85531AC0906AF87ECE13" + + "83FC80DD3E03347BCBCC8D58845735EB61AB75B57401B10BF1041BC3D32589637921E85FD65128B1" + + "60BAC413EA77583583648F81E247346C5C562E67B594368FE078CFDC8CB850F02D57FDA96E0D6120" + + "6BD0580AB469DC48FE7518264155095D6433204C97C305DC6F44EBBE9032E2747C70BDBFF29AC201" + + "C567A09294BF3418168DDB5081DE90288F4BA5776AA1AF9F07ADE5766E1FEB4083A22B28EC952714" + + "BB555F40D1EA2162E72BDEDEDA46A3F08F8D28BCD3F06E75CDAD3AA34077546E297FBD0E913F2C30" + + "69B866DC95B9EDBE466CA0410450937964F17FFE1A8A1B4D087497C805E95C2FCE2D0C6769D3674D" + + "AC552E5CC55CE3C048C3F8ED6FFA5D751FD0AFFC069A1474C8669DE810DC3C5DDEEFF977003A1EB8" + + "719E62195E24966C151D43A630463CA5CD2E97E414545EABDD5712056772926377E042433FE1A35F" + + "4AB23C6F871AB4F1F460EA939E9598B4E2A2FB0184E01E528CCBC0E4373105B7C13579AD08414DD8" + + "5896E686C41F2E37C57A7545986595C45F45B0D5F20D88DBE6AEB2CDCD5D2E57E7936619A57E983D" + + "A0B3F2BF0DEC657402470B3799356CBFB08C045C5CCFEBB73A8232FED9970B6B7D490A5ECC3867EB" + + "0B0E9CB81568DA199140B0B1E91586AB12BEF874D871829EFF209F734FFDFF603DEE71E37AFD7632" + + "F70A6F5C360B8B1CBD595CCC99A5DA7DF116B68B9AD224019CE7BD743244046F8B911AB2EE74B5B6" + + "AB3A4573FF9C48FB63A4277E6C01C312BD5DD0ECC2365703CC5B68E1A03E211995238D5EE4E15E6D" + + "D37FAB8947D1CBF472BBF00F8E4BD938982A545D091C7A0F2D6F5037F636CDAE6D5F379B6FF02D21" + + "B972FD1B4D4F89E55B8394B18FCBCC0A1A1A7A75F3846670D73E5E173034BC2DDCE429D6279529A8" + + "E443BC5CA7A4ECCB7768CF2B1E0905E34824B177F76E2917E03C567C974372EA45987FF868AE9588" + + "B655855A4C9C6A3260C11999806F41643C250B3D2DA221FCC21CC8883C65A461BE31E738D2653DEC" + + "79831EB84035060E21BB5E0D1054BA9D8E58BF8989E3B67F795ACF877E621F9A331C91E740AF5481" + + "A5516CF2E41EBC8DB8659AF2FF70080A6B5E6895B6AC5F8DAD432CCCE27302284ABFFA91EE21DDE1" + + "EF8533DDEFCDDE5FE9745B42D89E409FE35A13C200AB13EC428ABFDDD0F27FC6A14034F74C42E7C1" + + "062D78F55F45B3099CCA846DE87F22237C7F1FD78FE48C626ABB888BA8DD6A67C8FC4222CF8F6C62" + + "624EC25C54E9822ACBDCD4B6A9B0BE484F4885CCA715585F26D9566AA9ED005136C9874D2DDCAAEF" + + "8730A0013C91401E67EC10D0E0A22CEA9CEF39FFD9095A6BDE1147EACE25355F19666ED3FFF54E60" + + "D82F740459DF627EB45673623CC356F6049FF68BF1194EDCF069AF4320E0400F5175C32F005E0BD4" + + "9C38041D0126C9C8A98FB44005A0D59B5F756364B3FEB6B8747588058C0086B8E0FB2BC6B5AE5153" + + "CE6341D799B585DA7B4F308617EBCFC7FFB9CB5379972CEB674DF58A7B50EB8FFB7A5083C6B67240" + + "C8029DB8ECED06D585A617A13D4DCE1EE6078D0BF54DDD18081C741DC1556E175A09A048B612F3F4" + + "58EBD75869F4AC709712D935CDCD4A684A53CBDFE25EC05DFF8095EABD6530BF3C5AD83FB6286BD3" + + "FB567C82B26E97F0F35DAEE6D2304F312A8E80D4C8A7C613948BA365BD3DC6F9399E0F3290EBEB80" + + "555D918379C54BE0C0957D7D21A5720B880C6E9EEEED4D85E128AB1E100FC7A80BA27A3AB24E2002" + + "2A91520AC3A821E5BC1F415794F722D09744D29AC8757112A04126428B2F2ACA64029511BDE5CAB3" + + "C27494812268E931E50669DD188405BFA310F08E5CE45A51A164BF7E2907D60122EB1FCD35142391" + + "CF8226E580CC2E2381BE1994E7EC9FE141C99646F9B9B40CEBEAA947A8877EBCA5D77AFBC59B1A38" + + "ABB937DD14C2EBCB33C754B4D1C868497EEC819B04D9DDB89C2D56D3B7D2A9967D670F620233F86D" + + "85AD21853F1BE9FBAA32CE6F3298A0BA1B3A100C2F7179544D94CFBAC4137C4C5CB434A494F8F3AD" + + "3A86443127F62B4D22D3757F7F5421BA52B57E33C92382EF63F5655EE6C28E91B99061512CCB0ACB" + + "C898DE4702DF41C1121A672289AC3E9BD771FC31C1F3E6001A785EC11634D4B9D807DF07BF596060" + + "262752CCC3A909185178850184E3D2A8A09DA1633F68E965E72ACB93C490145D728114949C869EBC" + + "DB9E29FF99BBE4A39AA497D3B7D2E13BBBEE526165E5B77B771FBD68866D4C3770583621A4A45339" + + "8C30787B0B8C7D2FEA9B01E8BE0F1412C0CDA4EDF570D41320A35F3402CBD7BDD7117179F777491C" + + "0DB2D95B806DDBD08D38EC7B612B4AFDAA70F255A88AE2C3F6825699DFA14BAC490519406E7E8413" + + "F807BFE48FCD3F2DAB501B4323922226F348D90581D4D74C1D7B49A158F64EC5B416E7CAB1D60BD0" + + "87D76EB7EE692892A77136BC44382AE0D170BA9A9DC704190809AC4C25C9982A041D3DABB4A9BDD8" + + "16E7695D0F56CF60630C93490010EDC4822261AB413F7910CF451313988DED65BABBAB8B8C873B69" + + "B5EE8B9ED967701830D639A20F7893C273F5E44AC0844EEFAB6DB170291E9ABBC47024D501EC05B3" + + "90D397E77C99D36C2CD4AA274300D9DAC38D8BDF1A01ECC8BDB63BE2E4C0971D1C274B995E127C37" + + "4DCC7215E75871FF520895990A22DBDC6DF6F9F9D020389EEA927FB4002CE258269502F5DD59BFB7" + + "AF0B031C5E82AF9CDC4BC6416AA3CC50C24F6FA70F210A5525F31BB9BFB7283338649D9C71FAEE5A" + + "398FD60B82084C424FC2AD058DF81B4DA774164CDCE92CB356484AB7E51C136F55FD9F2B6FB2CA3C" + + "40F7A3EC6A7F7B821C83B984694357D8BA45BE4C448D39F2AE1884097B37D061F8809033C2E6F815" + + "948F441F0FC187DA061A634014C2BDD02B65D36394101261A2C845F11D5DF31D85D20E025E645781" + + "7B18198D9873293E72AE91B5047EE7A391A284664303F220A7FBB33D012F7FBC1AD7E27BB3A30427" + + "2F89F4107E9B19390F1031DD2172595D94CD309C9A58C866BE0F501EB8F6B3C280A5D99C6087EDD8" + + "984E95C9963ECC6BF59B72676684CC082655986B73B288A5D9C71BEDDE4FF9073496216761EEBC57" + + "7BC3D0419C8D8A9B92B8EC598E216EBAB5F6B75295482FC6DC0EF4F11F5EC112AF268DE16C3E9C91" + + "1AB0350D15D515288741C622006C7D09A53D80381EA54CC8C6022FA44AF6FB7C19B7BE1251D5035D" + + "4613966B278714DFCBD8D867BAB549D9C387E319335C3B1EACEDAA144B48E17EA43BED687E0F4FA9" + + "1B63008615A869C3CC0A5B3353A898347B157B76303042CC5EED0F237916E31FBA36C2CB91B63328" + + "63DA448D14406CB45F677E622E0ADFDD2E923D48D0CD9E11987073C05CF79BF978A981100D715E9B" + + "36E0F117277C902EF61FC32CB0ABD2E4EB52FF73DBA394507EA5DEBE38D6FCF2BF", + contextHex: + "4ADCC0D5EC5A0C02A4552EF588C698EA8B1E8CB2AE78425BDE52151C6A6F518559ECF7C40FC93691" + + "1718844EB390A0D8375A2E1A813C3C42A0CF9E22EC231A29A4E186299FCF44B9380DEFEBBBE32B7D" + + "7501408598F666DF16979453836E9F06034031DE0D16DA77DFC710E81C52D9352221918B291E69D6" + + "C094407947248148F50B3D94184E9E078D6AA402CC27745611DC7804B7941141D54A2CAC1E67E283" + + "C9DC0F90A9EA119A2549203B603E20EC405EE129A84A25049CE77F29E9C350ADA60440ED13B5B5F2" + + "05204EDD99AE28547415706E15888809CA23455EDD17BB7326BAEA89939402B0CDF6B13054EF28E2" + + "455D40A4377667908DD382166682E9", + signatureHex: + "D1759CA6278B3B6770F90BA23CD9252C37EB099FE82B767206373AFAF7DDF2A79F6D518A2257CCAF" + + "9201EBA3A26A0501940A6CC22E1655A75F9A64F5DAD78EC1265015797FE28254EE0D284C82EC2728" + + "8BBD2601F1CE71B205AE19D1A469030089AEE7665AC1372CACA0D16E095069656F6D983022C695F0" + + "0907725ABF520BBD19245C2B3E6533123A89F73164BEA1F3A7BBE0BFE819ABB915160E94ED3FDB21" + + "1734656BAD45EE2C1B02E590B85D8D6CAE95194637689D611916A3280B637CE2A4E5205F9DD8569F" + + "3CA0CD5029F5D7E064DF8D45E1F3178FF768F3178F0E23254B893661722D2B62242C7F8D7304BCD9" + + "1216BCA2D3E918972AE5CDE1D7DFC0A998F9B63B93D28EC2C2F30398DD25DF878EF3828A26C2129A" + + "25C7C6C5F252E8E77DCA7610F6E7EFE3447CF445D05C2C5CDAFAD005EA88AC9D2C19595A13AEAF42" + + "F0486FB4A9298ADD0421A1044B8DAE882E623885A5CDB5DB7639B3B797930A7650A55BBB4AEC5B16" + + "0B13244D89B6AE25C08B8C025BF17829FA216912C8F7085EDD7CC4946B2C2AD1323B9F4940D4B37D" + + "E7E1C2FA7575CBDB13A18B506CDD617641D4DD73AD003741EDA92D3C203248DDF5AE85D827DADB26" + + "5F751738BC3906CDE81F8ADF362527398ED0554D85B2E5FD3721345159694B879A03767031C84B4D" + + "58470FF7D4E34DA416461905392B61959705B2A4FDD72E9A29C6C739D87505F86D2D0DD5E99093EF" + + "0D59A9D08BEBF0F4C3719B0E245E8AB0E665703950BAE0B87A058E8E94DA3E681C4D0762801684AB" + + "8ABEFC9C8BFAD2587ECAC970BEDF928B0745112BE3CA61274E89BEF0ADFC1FBE3BC27B42CDC932C8" + + "620CF64EB3FD2AB8E95ACDFB2DA987C0C426CCED25CC71D857F92B55118622BE47289BD452CA23CB" + + "D04FEF6873D38E132407D50698A192EC663170EB8556AFA3C2258354517C3A6C6C5B1918A6772A93" + + "58F69B07269F33F73B9601C1614EC2EF4942406491EBCDDD1D2FD436573C40FF018376FCE8526265" + + "6D5EC5EA800387ADE46D86F0F0DA45BCFA42525E28B28C0CA03099B01A9AAEAF95D1987459EAAA30" + + "F42ADE2519DCFB3AD8551987ED0413351A9CD47583123BB1C15BEBDC7DA35E41584672D0C8F1418A" + + "05B993C3D3AAC984914FD4428114703CB3AFFC5BE7AA1E377D9D7A4939C83195E36D8DA5CD7C5C57" + + "263E138C6EBDD1C9AA610F32AEF440C7E34670C52E8A7AEBAAAF3FDB646D713C7E4987ED8589094E" + + "03B8F3C357BE1F9A4AC79C5253EE6C3DC1790231374DF96AED8901D618400A191B016CEA1B7D4349" + + "E00AC661E68CD0E1BBA6CB557A2E94DEC693B97E18551DC5680FFD0B3FBD3CA6D9F5B6C16B773DF5" + + "AA1BA6366652A2F91F929C220A237A702A9538DD32AD35EA3756738F8FE38A0876A8D93D0321C43D" + + "1CAA45E67ECD5E7953BDB5F94945F3CC223A92DD00A0EA205D13BC5367C41F0430A4173B7F425C70" + + "A46BF37B783566662923C97883765FAF281B4E66E79B44E987DDCC528151BDF4E06201241A468586" + + "5E68C80CA08ADAEEBD4A110CD5FE05CA2329EE8050A827DE592EF41CD43DC93F922E9836A699E2E0" + + "311A3881289D8BC8201EE3DAB9DEFE742152237C08995A77842E068CAED3E945F5BCBCFD4A8CEC44" + + "DBDA1AD43D2A77120F7C17B6BA9CD5F9FD71E735A33A1E1A30486B119FAAE58482E019973F94B596" + + "891AAE12A6665D8322C9F300CB732C83579663852501513045047E16878CA62CEE49AE3CD0188AE7" + + "8B6049A4FEBCA2D29CD4FA3F4FCDE2F4676DFFA82E253998D35DBCCB048DDA0B7126B74E8D81E6D8" + + "0F8F78E7C9C6E9B9B2577F70135B76DF88FB91330428509EE3C9D11F92595C684AE085646DAB3914" + + "CF5F3C574888F2615B3AEA729FF25F1B927C983B7F0575FB727BE1EC713BB3D17234E8DE0EF873CC" + + "FC5733F6D07C58ED58B6DC71309960226EB210BD31DEC00177F3E566B60852621246DB046C7F362A" + + "B7584BB68ECC7B0B869761A90EDCD2AB366BCEB8A1055A918A3DB6E5F47A3F02D629D61C21CDB8FE" + + "821A7AB4135D1489DC6D9A05120AAB65026C0B809DCDCD71C18C64B8EF3C14B9D9DB1F85534EB0A9" + + "82B99F30648AF35A6FE9C0B89B2BDA0EA497658E23A2A363C3D6BB4DE84C67064A27C64DE9F2223D" + + "08A227942BE43D9A182F32C41767AA265BBBB7E20624041B6B942ACB07B40198D4B20FFA093B5C54" + + "8CF5B23A2078590825C81FB4C447B301B3143D526009EE8DAA05CC5C8D6E5655EE917EB0A3088FCF" + + "ED37D7C16AA48BAA2D79C061D024F75648FCA5548FFA35146409BE00972CC5F2FC9354BD688273DC" + + "1C29FCA0A326844552BDCFB2FB2B6FF062B97A7198E8C00F983F2E46FF8186B2F15E5A6FDACCEA31" + + "26B1846DE349AE218D4CF70F70BD587CD07FCA257C376B250F0CC5145DA2FABB990DB2AABF05DB04" + + "4A36D63D35371A3B0AFB08E86A305EBCB0C85DCF07C4B3150EE016C0597FCA336BC2B9E8B693C845" + + "BF7C85CD7B250B5A183EBDE78FF4C5021C0C039938F49DB1A869447078FB2BCD84CB494015A85675" + + "44F7BCF48D3B23DA01E76C5B9AF46069FA672FE4CEB1A7276F73DB8637C3663F4162EFAE531B5FDA" + + "CD920667A0A4C88A068C1D949DB3D38AA8E9FBC4FBDBC29E10917D5F96A97FCF897871993FFEC36F" + + "AB03A5AC502ECD6AF9EAC4A4039CF0DC83CE4125B59DB319079F26D8B80F0AF496B958DD9D4FF943" + + "EC0DE148BFC569A9EFA00B6558A9CC11B27E5FCDFCCBF127C5D63055D9D79F3116B2904EEC5E9B33" + + "FA4C25EA66127AF56B94B20AACAC7D455F47891A0790AFE7D2E53FF337845C2E0A81FC0126BC8F28" + + "426073F91149229EBD68039D5C8A14543AE6A016CDC2AC91ABD44191416A6B06A01AF639889A884B" + + "47FB1337E924B5FB4B66659BD39C3A129CA30F7EF23117D8DECCDCCBF5E2215CC2D7860A5A42B920" + + "A5361287B603CC1B1C4B7B91BFB2EA9E1137171E07D181A2F94BDC97F7052FE09B95388AEFFAFAF0" + + "EB7ABC0E07125399D3943132CC3F137A5227DC17CFF6079A8D0912F5CCACA13312C5CD97354ACE37" + + "8B5820C1BD548E95FB90232E4781B922A0DAD2DBC590B34BB8064AC57172B4F63AA4D21685A02140" + + "5B951420822257755A18FEEFE0544F0DE8262263E8AFEF8D171CBF2DB41A4DDD0482F41D0F7B85B4" + + "8D03C6F140EFB213DEED9FD43E1D4A39AA9CC50C7B3B4C0C45E5D09B2A8D0128247CEB2308E858C3" + + "9584F4233F1BA1A9CFD5D7BAB8B4BAD97EF8D7B5C00AF4E936B877878C36C5D2D2C926967AE5A646" + + "4EE92D9C0941C2055C92C094EE5C0A8C05152E35365D74777880A0C0C7FD04090C0D4657636B76A4" + + "AAC4CACED500020A1D2552536A75C0C6CAD4DEE6E8EBEFF2F7FB0510292F4350515D6176A8B2B7CB" + + "D3DAE2F5FE00000000000000000000000E1D3245", + hashAlgOid: "2.16.840.1.101.3.4.2.9"), + new MLDsaNistTestCase( + nistTestCaseId: 46, + algorithm: MLDsaAlgorithm.MLDsa65, + shouldPass: false, // modified signature - commitment + publicKeyHex: + "A30347C219786095DAEF91E735ABC25588AB2327C04B1398EE9FDAE9EA5DB34B2890261CC7A6E036" + + "36E23F3DF6750FBE929B75A678A26DFBC54DBF40C596AA4DDA87F5BFC01EA7E35194270BA981CDF6" + + "385B826319B8A50FCF7E748975795F46B03361E925B0D53A068449870B76C1B3A9F2B5268FD78762" + + "EEF553CAAAA00D67CF88ECB3814CBEED5A206E587929164D9EC5A0113159BB3F8D2757287F4E9741" + + "07F36EBC170A85BCC4E6662A13B3BEB8369143CD37AC59D1BAEB90370DEFA601016F40FEC6DD6977" + + "D4BAF314182670CC5D50A81B573855505E4AEFA77C2D952089A951CD01EF4E60F72081AC4B8E6E85" + + "7018F0D6FD23F046AFB289A54F43DAFC77A89A6A29569712FF36C7F66F6BE93D9E1A2C0AE9553857" + + "9CAEFA6FEB80EAFD45E1DF2A408A631715957ED3B332B9B256BF4A3BC7B4255300BE180FC7B4318C" + + "F5488DC98C137735E11B9D56F6FB82B98EEF98421493109016F49CE1FD84534EE17F011DFC202D37" + + "C26EB512B18153A100F5EFBAB2430409B3539AEA28878E979509F030941B7BC16020DE9C06E4DA44" + + "4DB8925139C831F3E895D9725955B2CC35DEAD47A8C5E90EB18E5D97660FEB7380CE851F267979FE" + + "705404CAE808C31BA99AABB2DB44B0C34864AB2FFDE0AF0955F1742E2CCA5AE560C77BB9EDFBD44C" + + "806E7E9A56F08E402B3652BE0A0EE95D14D3F2234793DCC51D715222B468DE64E23445D471AC3ACE" + + "8A6E95749956FBB9FD0C90D7F4DDAEEA7839B539C1CF8F3DF583BD64318AD9E9FD68D15801CE0B9E" + + "65BCAF1AF41E2EFAD6DFBCAE231673A89E6AAD9AAC03BC94481017F74B4264EC658ECDC414129051" + + "FA5F6529B207B3EEC53107B1130A62A0235B6F9EA3E0FC0AC3F0DEB451EFEE24EC9F43AE58F4CA37" + + "A4CC7971E1662467961C696614276BFB397E9B2B542328CDB576174B633AEF2C7256653D11AC0A1E" + + "F781D1D397F5570CB36579692CDA06F12D7EE8BF590628A1D83806286ECA46FBD4C1FEE6CE69327E" + + "68F1FA4053A428840B2B884405B61F40B8F44A7BB9036845000D9EF5097CC6340FAA889258A9BD7A" + + "FEC2569A10EC803B5F210BFF86E166A5CB5C4F1F04B93FD8E25FBE2152AAE2463D859D3F9B4B6665" + + "2425FE68BA84A865A9869E698798226973C632CE5B3818E0BC21B4A7EA9966E0A465D22185B6C75E" + + "D45CEA5C1FEAFE76E250D2542D9818FC151183FAF96426BC60883DEA17A4C39158FA5374802DD7D4" + + "D5A92CFD9875221875DAD2678FB908AC723BC17A80D9FB968AAEA3289DC936BDCCEEC089B845CF1F" + + "A547D62B4E3134E22B9C0D50608A4282B26EED0779C7D305B430935E383E65E75833E858E5F73CF7" + + "851D02DCBD1C6210A50EF002166E42261294EB8FFF2C5E1F29AC50429D9A82288602A43A4AE597CF" + + "A11F2138B4A42CC66AC6C3F3A9C224924DC50BCB62E49C22D767728C95BC9EE8196383C760432EB4" + + "E22A8F14814E13487AC1C99A18EF9C92F9684A726521BECCC32864B2A715782B0C98DAC1985830C4" + + "1B69003E7097640C16B888A28D54EAF44AF9D32F1E201538AD60F398AB088D5D86C61CB46BBFC809" + + "59849F59AF2D0941FCC4AA4C81D4AF283FAAACF9AB124014C09525548E1652D08A7BC783B8BEEDBD" + + "1454255532177EDD529259217D30D84D1DD6CE584387CE00980FE2EFC216CB2821E92F274E5194EF" + + "1C775A70BC508B820904A8BA7829B1B0F064395ED17A3B0BE99103E908A8FA611558CE1F8CBF4E1A" + + "0CFE88835D3576C8C10FFC7CCE1AC082D258F9771BAEFF2295117EA63588126E2472036E00CAE0C6" + + "6712ED3EC94ACDCB1759DACF2EA51D1DDF43F8AC9DF0C8AC32F604810E5F4B5F895916DDEF2CB1B2" + + "D53462A60823597FF8A1E357A14553B96AF631AABE08D62E74653E093523B13BB6567B9AEF247F01" + + "2B48C60FE5FE8C4405EDCA94DAF970AB284DE3B07A38CD71C7038E3B58BDCFCD9D198F039D99B3CF" + + "544E564F806E38872EE0C6DA61390285C4007E7FD7D78957A51C48EE6C62152CF9044A9309C8997D" + + "3761D60CE53AF42A54139D8B54DCA81B364D78738AF3FF29F3781A3DD811C90263A68B1D8B0BA95E" + + "A43BA2C04186C588AC48243C187FD988534BE1A006AD365B988259B44D524AEF502869385D900D1C" + + "D7F4829E16E3DA79159D0C06DE325D0988CA8EC5E92200F1E563FA4DACBCF4D18179B2EA10453AE0" + + "2B3D5B410E8F8B9BA37AB2F0C3F1557F82BF893BA88973B34EF320E34BAEC8F71382A224AFAB0468" + + "31A665DB250D62E468F2A2115F30AD681942B65618E2D9A747CFC5C8F2129FADF0820BB73F5F1BFF" + + "7E41D68ACE194304917B7A6E8BFBB90BC2480755DFC13582FEE9435867751D5A340719BBF7DE9D63" + + "7D92DFBAE0170242DD9AE86788289B45E792BD01F595FACA0935DF84DC191C2BCCD59E33B0D1405D" + + "22581CDAE28081E0098D5FE117D2F250F74E90C89D1CAA2FF34AF71B59090021E0FC651DA614B324" + + "4991873F86674D17170359C63E8D8C97E9CAA63A3CEAE72742D6AEB7FF9E24E31A8E0925C1B4F980" + + "0D2F848079011608227735E7CAFC55DBB5CF44C58A0621A0B63998071736FBDA99B24C150CD27541" + + "A96714EB02D47576F5872EA61BC981755FCF1063C4910C9009FB1F46CE32B197B60CF7F92F4E0A26" + + "C7F93ED19C4A045371F31BEB65372C2641AA697976E14C3A28EE79008848505D3ED3DB16F976BBFE" + + "A7942F63C5BE45E870D4B29AE8386D57C2A39A5D28A09B7E9DE3D59F9F43F15F", + privateKeyHex: + "A30347C219786095DAEF91E735ABC25588AB2327C04B1398EE9FDAE9EA5DB34BC5A2F16B81224267" + + "B2F812D06CFA8D12616BBE022465FC3DA11C3AC2FB2DEC09A109AB7AC6B41793320320164A5F15FE" + + "9257F6D5B47A5A58A71706F5EFAD60007540301A5913C2E47B3D2D8E488A983C60E81834C612EC6C" + + "E33A60EA398919671742005061877663656851876033072270665282065515842284306032708247" + + "63358322066353867668033523626612481227273284680323827142720044573323748601765346" + + "21133377874260343753037721141083350625577781421747681020867404885706082114360132" + + "60628104512266625848630118888711800583838217822857504841446660456341471003564633" + + "51421115016655143787858823738514868500108146505132458357614041088754215725531140" + + "32573267627822362705462621155844530452252018816747112436276415811833117436533506" + + "22736067711283474386605581501301581044306355100147211154314862520787648240856678" + + "15055005820231867180030103466618083784051167451466371064838818541377721472457085" + + "22270723776124340882875807061538358643386860288256280223783006436446645821557470" + + "56102112483848183832442435416204824722166530321264703074881422411020503480173806" + + "03842472224056371784256711574126367432213288580086374023370317235743606828375174" + + "33276530571088282548554444805420402451124768111260058813336133018765557035411124" + + "61168633102245766846455146446184007300258186004452228454630482648386241153017375" + + "67727882437614214180544262087656408168127417744857458716020278053156055651567687" + + "50441107117661014201284345210037042814857628617005512857042345452027441308676442" + + "55673257462022341146077145427554861440406248638285846235120628153277887251276085" + + "24528103057017600237033470537075806048524464676184178071737782453305243644407671" + + "23410063678254514612145373184776673742843545486383703346703407013025112557235810" + + "43417461740704317730282722631521876786405004608041623136163502805062577432844032" + + "13781226652382836586816652535651653875153253553280134706017442835887744540266331" + + "41131078778823054550211766324123850418655204842451700750543700512834822315685118" + + "02521702285557428666188533842775571025733300500050343773110684650588532322735265" + + "28327511673718588841766168854081782681415544441806635408443102737132172358453203" + + "34664623480124857172602233867425534557118104681400860682460755623272563548275050" + + "38472670387602210528018132878625713573370026808435426470648310030054425070025058" + + "85834875716230854353444338822418486328043035685416275458602827100668470831608188" + + "66438466277152634855341050071272613586560531261263088278861438712886357576613555" + + "01735404466023210873346350581331162546313711626064082751075172144564470617057102" + + "80587176220251502564866440221528165566673676870886318015617435725271448152822267" + + "17112218824628408242757111720770473604521715586176017788421207730666371246203643" + + "88648208722827625473374485412452743783441721262716120262266665877010824476281425" + + "25528715704518730643375316755527273244504508524011513664581630483734541341334160" + + "80408227143157373644150106361028786185173358128873660780248151205765278248785670" + + "53615404163441745443543417112147385038421435722257240223627332563454454078326164" + + "45162463158232877232857231065221863476473634447157311452561315723286603802583783" + + "03432703454268737561734104755441E0DC051ED47DF66A651FCAF954479C5DF9B81E5B6429889E" + + "D6101402A8516DB2221A0077540416A3B824F994683AE92F05AA5247593679B767480F6A599BE392" + + "27F627DACE9D23DADEE98AC311929E73EBA01D4015B78439906A33B92733AC60C0B10BFBE16D3AA4" + + "70BDC9EB34D99A250C8030A8174DA92EDEAC2060A60B43880FA450B604B1BC8D41FC40121D0164BE" + + "98DAC8377D9462396DD6C1464B0525CB4E389E8D7FA70F1778F8A810DA033D7CCC30122CB369C463" + + "B983C844537E723065BA6E002910CDE03FC2A4D42FDE972E8A10996D0883AD8C05261F63585C6BA5" + + "07C1DAD827BB84EB0B2B8C66D723C72B08B440B6634EA9B8C5CBCC96246C2C78C306E04BB9F5FE3C" + + "33888CB5B374E9F44D8AEBD868AA61A6EC9F9F34E96F5254AEA17486831981E1A3EA5403A267CDB7" + + "F5716D41C179D7D1412EAFBA7B977FDF035CD7D92FB99CBA6ECA108D3B1F2CAAA5B71A5C68EAF6F1" + + "C717F09372EC4DDE82158F14A96504B1806867F9D1647E2C7D043CD1CF82BEC312B2AE05B677D941" + + "C8E0A5520B7B2F615F2275C9E2C532C1DDB8614CDCD51AD729852B665D888999B3F9096D733EC5F6" + + "A58F8B4BB627EBA7769296776823B656730F053860C610BCC23E1AA52B3AA27D60581208B2F44A5F" + + "EA3B7B4B905D13214AC06C52B27F94326BFC34CC6D7D0A675ECF72B74157075FE3498CC943045B20" + + "0733F2F770A81B9B7B3AAFEBA40BED064BC772842172D885BB2291D86D4BAFA7EAF634EAC8D76D06" + + "A3AEC3264C70333BF46C4F1DB54C1D14F9F57E7D815DB6CCA1D51B300ABC9D99038AA0302D7CAD38" + + "9C27F925E58AD52B7B349DD3D4935048D2188A8B9062EE4FAA637A2CAA5FAFE291257E2C733A1B5F" + + "E58BFC60393B9F6B91F8DDC2A7276A3A95C8A53E3AC4D39DFA7FB49CC2698D44B61C85C0C10B9F01" + + "50AF96138EA7592AE317F77AF067C5CC9016B112990019A9BE30F942932A5464AE307778C009A459" + + "46E4ADC003284F61AE70B528EBBA800856CD29ACEEDFB8511C5FBC5A12EC6080288A79EB799FF4CF" + + "D1095B04FFCE822657264E7C662FDEA1FE4B1083E1525DC87EB610D79ED11392469BA08A674378D2" + + "25A567892CF1734B3CDC72AA538ED62D8146A2D72EC104DF3899AD2E14AF77E64D7A534A0E341304" + + "5BA46690FB7CC1A72354FC8BC12B6DB5BF46B155A6811F39229BEFEC466480CB3D3A72E8A8D9DF00" + + "0F62E4B5405F4AEC498A583A8AE5204A37EF7944D5ADCF4FA72AB638130FC55A86E320827479BE6D" + + "9DFBEB32D93416E7D1408C42E3D3DB653C4B29AD68D18ED601DED0267B2E4685854E5AA4BB64F1D4" + + "1ED0CEED8C584FFA166A22CFCD73146D0CEDCDF42E4557F93A0E8F6A635DF294387CB1B57DEA8552" + + "94A03F8FDBAEE2C1DE2F65A3AA1E7744CB31CF55F9C02BD176DB999D2706CC30EC8BEFADAA1F72A8" + + "7F99B4428016FB2FC23220E637D6B7D90148390219BDB82297B8E346126329C3D7F05A34EB054466" + + "35DA939CA476E1144942889086CD84B7A7F363F9E9EEFA3A21539622AD53E697D396763BC893987F" + + "65BB3AEC480A3E45D9E81CC5271A42292FBCC3E783BE9629C88603B04116E9820D0774108600744B" + + "96E1B233CBC7A7E34E6494994876F4148379FF08E8815A59107E6049DAC5A6A932331806354AA67E" + + "1845BCB659CD848EE24F59DBDE3D04B2FA1C0CD49D7A98BEE682B23BA787A22599A19F1075CAA22A" + + "B35610E6F1D9D4C2D5732528E32D32BE953641CB1E9A4380056CFDE224B73CB41CBC163C09D1715C" + + "EB3B743334D1274E9CB3B3DA691BB1F767F2D0062D35A4E19FB06664A0CF89842D2F2319CEA78D7C" + + "A12A2A0E5B57D1727960E5E5638BF99AA11876EC84F923A3422552ECDC7FEC307DB3C7016A71B07E" + + "14A4AB0FC52B2474A3EF756DCAA76161B34C20878C71E5D9FAC43E6CB86CF22D0C364E520AE32707" + + "7FC7F8FD1B1A6E19B23BB606392FED56B49C2F29B902AE34111C1AFD4E6D327C09E5AB8684904629" + + "B89E300656ACDF9701E91BAE0FC951EF02ED7DCB3CF782B0B4C58D237D566E77F1A674A290945291" + + "CE417B996B511D58C29B78D1473F08C840AF6067393C6A2B6DE8D44E30B000D0CE221BA28309267B" + + "73AA75F6C9C851518BE02C5C1990FEACB0F9F2ABF8C8545E47823F7238C9AAE4A62B0531A3AB8B09" + + "E1DE597873EB55046EE273946571F1A065DCFF807F7ED8665E8B581FF48297BE609C5B3C0595AF47" + + "F1188B68F741344F9B5C1A3E002A85C278ED311D3BDF1A52E3FD571D11853A4A59D528B622ECB504" + + "FDDF827AB5736B2E5E2A060A0BF9F6B3A3CAB9FD83DD5E5702D83720B92CD89636BFDF81C9250AA3" + + "53AA6C2E2960AB2CFD17344431979A728E39EBE46C552AD45ECBCD54C64DE6F291BDFC783051A169" + + "12358C8E1315F2965B6A36C99DE384455A71C33EC5199E1F332F109E0892481B677252B123783A5C" + + "7F42F935C530A153503E4CA2C9AB098E18F864C22766F1D5121507C781A3DA83767A764FC9EF8F54" + + "029BA7A5239B711E6D357406F556C0B35D60B21188117B2DF409DC507017C65112CCBD5147098C28" + + "DFFBC0ED9F8D2049AD9A2C3DC33468D762E486858E96058A465A7E73E19567528AD5D91231A0AA24" + + "E8B15918BB802BA01EEF482D4E57B7163D0761EDD0A18BB171314C64D0D5092809B706319CEA67E6" + + "2638A6847E40719E3D0B335804A98A2395016B23FE5415E93837BFE2E59BEB23FC073B2100F960C0" + + "05F591BB91B4E3BCB61306B44A9BE0D9C22E75D8A09B69664F105C46369B0AD7F06E6AE985B29D3A" + + "03B1AB17E7C287B9CB24A4A71BFBD5731BDAB10B1BB4A4E9D7A0F9A505019E8CB90E79DF2215A58A" + + "5F68D2578F6B8E846D22F248BF8316EA54FFF377B041918083CABDA65B2987098A309494D6F52505" + + "120E75A36E8BA5F9C8964C191911C5831409F3FA91E1785A9EC29A492A27F5E4811DC8EEA3601AD3" + + "348ADF54043FDF312F4CD80974E3582FE34B52C07A9C384E897327E8BBEDAD7117E03EFD500A36A4" + + "0FFAD55C4A712A93F66A5B90737450DA13192009FFFF21445B90FE4711613DBF27C051C67B8D3C2E" + + "7E4DEE9D1349EA88EB2AF971CC85C7500CE187FEB63708238D51020F81EC0895D153B52375AEFC44" + + "DAD1B46D74AC046E36447AE1A58ADD5BD3EF02A1B9BDFDF683ECB70382B68F084C8C65356E89DFE9" + + "B7AA35CD5B4E82090A1FBB4BC0484B56A47255896D45679269432ECC6C8581216E277B2294175A58" + + "88556B1C77CA0ADFDBC3B3767C618728F3AD1F7BD45A279244C160DE0B6A9E8822A96E54DC0D06DC" + + "84D7A85ED11EA570C529CD8677989765883BF548E80CCDB3B167298C95CDE1732AD69105727E7493" + + "A79AD778CCBD1B60CB428553EA864C01355610DE6CA49502C406C4F66296B4F3699E372670AF70C9" + + "231889B2BB944C336F7C218F702EAE663DCA6B286DBC28FA6A174A62982B624264CB9FF8CCBCA688" + + "03666AF1B9B79FFA451E78072AC3109F6BED13E405B143F48AC67C8B34D9E88C", + messageHex: + "AADD8FB620F8E098A4B3425D0272D6D125AED2B91420AC0C7ED71B16C8034633ABF0E42788E9C112" + + "ABA43A111B5FE73332FC0B0A3224F48F04179FE10B8C3DDEC45DBCEAA608CE31B904DE08AFB0231E" + + "B926A205E20A9068DA8B2F561B7A1789ADEAC13E7DA15AD402EE15C38DCE1A346EBB5C2215EAC886" + + "9C3A8B01DDD01FCEC76BD7CAE592D91549B8F0AA902DA3658C0D263A49DFF484B4A7D157B6A48DF2" + + "98A6F03034A64195F6A5020A6F7C2D6D9241A56AC3B875B89B0C702727CFBB4BC35F27BE9B35A731" + + "77E9F3BF97909124CEF82771F05052C0648B66DCD8B97EE964999B00A1FB66B9B395BA1579DA4301" + + "E948E0A6B920E55E60C8B901EF5BC732FF6C99DB927A6DAE9EE092D5AEB3891E8C56389FEB7E56FE" + + "752D7B0FAA049A466B69C802F9D05721E8CC24101E5A8BDBD864058AA1329BC86F92ACEA9B567BC3" + + "F1B0303A8F618392E0DAD28746C6912117166525C88BF69BA358647C6338FBBA546BD6AF7CA3F23D" + + "8ACE1698CE3F20D30F10229710CF2FC760ADDD819F0D60F672A1C76799A0323AAE76F5F753574981" + + "D90389C42F6E5B1BD36F4FAEDDA0B37FC569EF17C0FAD798D451056CEB0237B05CBB22538C266062" + + "B988617039078CB3E3E0F98A07A53CFC5616EA8FD015A335E089B569549760BEF4F6BDFDF62DAFBF" + + "E1D5818E371839112577EAEDE454597685589EE8C66D89656E30A240B761734103CFE4298B298D7F" + + "717CD7DEFCCFEF9637745F6A6EB38FC6FF0DB7C497AB8EFC55E7BCD4EB90EAE5C30D9B5634887226" + + "F539EB455EC928BFA3D0BA750E508C0DD20B676FF5E4D023BABE3497723396B983C61523B86108BD" + + "56B2B8BBB4A4A3F7A40E89CA42F5ED0B5DA3A767867E715C8C6E1AB248311B5CD6A964E2F02EC761" + + "25BB15E48F22289D785E55D3BDDF66BA94A9EA7C06C8B2B9F218ED6A936569B3776446ED39060676" + + "EB217BFBEB0E74C313F8485AE13FC66BA84EEB959813BEF35940E132A37AB2DD03CBBBCC345B08DE" + + "AE867E5259C3F35896E967EBE40942A6EDAF57F3EC2349914AA11DD4975C55103ACF9FDBBAACA3B0" + + "34CE55ED0BFD7E21A053298A6C42AD4E6138FEFC742726ECD773E9632BE2FA1639C3369A71ABCA49" + + "9D92FCBE492C842332CBBEB5C2DD746A68C798D6461CB49D1272B7F066E0191FEDC1D9E8918EB36F" + + "4A2F7FDF800C89F1B39C7A8BCAB80A777B8E4DFD9CCE52B2AB3EC14CCE2807E252628F50942F2B60" + + "6F53BEB892C45DAF0DA711997105D2D980140FAB6CF94472550C4F2768181F8C27BE026EA7D2C6BA" + + "E92E45129B5CEEA18AF769B4BB521F72C1668B597F47DE53BAACF55FA75CD0E9C8CAFE8B6B05D9E1" + + "65CF6E466CD9381C1EAACA78BC8F85E8BAB118743D5471F93DD58DF46F3D1C8CDE48E8042F9804D2" + + "2033B418550EBF56BF6EC98891B7294ED39EDF70AC594FD3C320867BE544568339A92B67A345971D" + + "46394DBF11E0AC64C4CE49861C3E7C4C9A585DED2B05900D2DDB683E1CED1D1D24FBAF28A5EA2C21" + + "0DB2817651845FA2E84854C162BC18F562F3A93D01BA1645449A0A7BE16494EE19C0A944FBF200D7" + + "196AF9333262B82E77908C3AD846E1B7F67C68525B780CE17B87231AEB9086EE2D8284E2720DC1AC" + + "ED66F4ED4610763DDA94D481E02E599D4D6B40F40FA5956C7ED34A4E84BC4CCAFD4980B515594DBC" + + "7B33BF80FC04C178D1089FBED8BEF66D1C0A4793CCF2719A14D185A2A62BA5EC2919B30512B176C5" + + "661741F556619C82EB27E1BB4577D52F39D23173C9288F12FDF51F7441E194FDC58D0AA221AA6C46" + + "444FCB363DA2E1498DF5E7A7AE3C5271B9629FC3A7E0D2B65E1E5E27C06324207AE0AF1C9949749D" + + "B8C7541398F21B23B4CB0545CAE727F36C6480B23F9A10E208809ACA60073CBFA76AAACFD33E1BDE" + + "D09DC1D1452DA015AB0F23D5091C0763962852B4D1ECC1769C4A726BFCD202903A8ACE47FDA70A5A" + + "346CB7217DD80A1AD6A6A1D6CE55699FE5BF784F88D5816231A1AE1337DE0937FE20093A8CA73514" + + "9AFB417D343331E89D062506DE097B3DA743C8B2EDA4151724D50AFF3D06A50BC65758031328A5F9" + + "539BB74DF62D0D091F474132B2FB6BF2FE54A6DA2D848455531C34EC129B85E9757BAD5897146CCA" + + "AF3884C15CF927FA436B9E98121A7501F44E6162F8BD41A4099E2BDAF5AF5E9DEDB8F4A38678A4B5" + + "7E2CAA543F8E87A055A308F5B15983A4DB0A3A01AEA627EEC0DD2799BBCBA4FC4413BB7B621DAF43" + + "9FDA801D9E1E7B1452B06E2B75E8C83AA70D72EED2277BD5C0A6132C6DD5554A36AFE977E0CEFB32" + + "CCF9C036A165A357402950B868E5F3895160EC9950470E13E70F9019400963F8C5DAD3C6B0CC36AC" + + "4064747CE83D59C6C82A8144C7C10CA0C07103D712E3BCB5A539F6C1ABBCB3D2A4B35B5DE7CE84EB" + + "E7A2FCFCBE0931BC9C7F82639FDB5F9BC15C4A6D294069C5263F4DF87DA91F42D5A3B3727F7E11F0" + + "A61F021582DA12F2ACD9060711598E9A147C7ACFFAD7DB9F95043EB1CE0C74C8635CC7B7DB7E42A1" + + "0F48D05948B4471355817EF446754D6DD7DD94C47B213B7C324FBC586DE41B9371C1444745B27C29" + + "C9B9D30988A71720B5349CF611B3625490160BC5DE10CC298B069B5E9502A273D4A578DD76CB923D" + + "149A693A0DA6990D1FDA4AE72551CE419749D51BE42CBA1F6EA99DABC0822EDAFD3116AC52647261" + + "22808A4F21101C72513860A4A6906F2A47BC9E8007BC8DAA296BF842C31F7AF7EE7CAB545601DB0D" + + "29A5674E2D5846F574D9CCCC5C60DDCED5E151FC1E4617B8878DFCED86E3041389FBE0E58A628B7B" + + "681689DBD80185EB6A31385A1564080A8BF2B1B9D4AF0CFDB5A5CEE24C47000D3C67612751A3AB38" + + "46D09D93E1B9B957DD2C2D8A70C7E2CA3EDA7E833ACCBC07C51A14CFBCE637B87C2180B7794AD833" + + "2909AE084FC52750361D0D885B275AC78716DDBAECE2618B357C4F981819E74B63D9AB9594441EA2" + + "D400B11D716C35CCBA98D061963B0DD49E424C6D68FC50E83B7EF590F31560587873F5F9B7FFCE81" + + "EAB795680123CA586A9FAAF49C9616CAFA691C3FED1F834F01D284609377734837E8047EC74B5158" + + "BEE2B07764622AFDD489712B470569EE365CB3537B893B1A160F57C794EB546B946445570EBAACB5" + + "2600E9CF928A578EB098691CB6E6BD043ABE31111751FEBD5904B59E931987A0786A3A388D75D947" + + "206E1892A8AD6F4A03D871955A2520603976456BD177FDC82B12C92631C0DCAB538B3738B138349E" + + "6F871690E2B2B342916BF96A212CD357A7CACADC4BDFD11A6953470D68B1CC33E06698A5CFA492F5" + + "EF150603DA45FF9B999FEA7E6B1404082CE63475A7A258986FD3B021C86CF7914835F150E7FE009D" + + "C8EFAFC0493B0790876012C635DB2BE066ED01DAE3C88B496034BA72A58C683EAC6A50D382BF8670" + + "AE93E954B657C503A797DD503CAD0819C3327FCFACB52471B5C81EFADED377433E3D88EBE24E7BE0" + + "046628CAFE1D06CB652FA6FA02C4AE367FCCA23137C969D061DB6E42786D48692C82945AECA43D57" + + "F956C448A3D81FAC8000582AB8A76398C1146E3C750021297749D322712F36D8F65AD99B612BE4D0" + + "18E4439996C0B2FFA50589237D34B2D3F1267388A93891C499EFEB6AA6089E4B38EC7128D3124FEB" + + "D17C5A02F3D0C8E2C580A300761DBC890C16ABE6AB847B00087DF4451778539526EAA565C19DDA44" + + "D597EF2208A7C82C3188A026A776D576E21CA0CE159D79B4A2ACA73F49ED11AD3D525C81FB5D1CA9" + + "4B09E3902CF641CE29EF53D24A18973218EA80255013351419CD1CE944FF6635EEEBE6ADD0929E23" + + "D1F7527F012A7A5A3CA18061930B9431B6B323CB1913C67C6F55FDC572D4D4994B1430E445ECC73C" + + "9936FD0B7BD58BECB05981A42CEA3702DC976BC967139039ACFC361EF8448A37584FB65015A214DA" + + "1E65D8030D819682322829CF231F8C4F8713AE8FB0A952895C8E25C26C6A2A06678FE9F463184C5A" + + "8CE6C84ACEE7C67E1223BB40A97B6A085A3C1C59DC2269FB72F7B7E99D9F734253570B1AB2ACC579" + + "E802E5D6659DFD1F798794D65B9FB297017AF69360AE80F8F920DDA69BE38FEE1277F98EBA6A7669" + + "8B18981E976C6331FEA7FE429AD8F0E190A040DB06893711A52B43BED1B03EFFBC916B519010983A" + + "FCE430D3F5351A5535CA3EF96A33FBF769282E30A75F152E7AF377B42E26ACCF99AB0E0280A139D4" + + "5CEA1EE6DEB9F334469A773DDF31E60BE6B0742F0A764054B11CB25D674191E0650E618D6BFCDEEF" + + "22812B6E7A5EEC4C08764312829FE3BD7889E3BDA815B67108F19BCB7EEE812AC2F7CEED34B8DD95" + + "DA5A721EB39AD201DAE07CED27A1E6F16E5F2757F3C6A77B94F7AC54A0BD9EF4760A5F8E0625D02F" + + "498F92256A16216F4B6FAAD2AC549F39E9794384C91B916C05E703481032601931D3AB93FF90F5D8" + + "7B75703129A3DB7A5370C0673E0203F52391B660EE9DE5BCA1D47588CEF3A9A9E18186CD10B4FEBB" + + "47F2E6F6EE02EDA75C7A86A93AD659024381E6275F236C3966AF692CA9606FA93BF03648A0283D87" + + "FCD4AC3A2C10594AAD302D7F5E39AC7E3A861E2B8AE97C09B4B3B993210733710044610BA1A7C084" + + "DBF3152669245DF5845850D3993ECC5EE04EE2ED94343EC35797A4BB2F30D68B5AB76A56475C5797" + + "A14EC75FCB8A08A5FF913B78321B3C454A5D82C0BBFE434CB81B5EA1E3CCEF1BC61409D1798921D9" + + "575FBA737C8EA7B9594D2237781DABAA1F41E9EC646004BA04B807D9D596936C94FADE67A9638DA1" + + "08C301E786F3D4CDEEDE670DF5B5D436C664D60A2FB07C5B35A92A4CEB9A89874EDEA23996CA1EDB" + + "C3378951F1C916BF47CA0133EBDC80ABFC98B2A5CE9705783058D60C751C01C898C2E7AF5B78F3E8" + + "4EF9E4F113BAE024EB18559792B69DAAE6E5CAE4B165B82CBB14EDCB016BC3512F455C6B42EC5EFA" + + "3D87712D49BCDD858DE91B1FCA232DAB6427DD71B41DAC5C459F54703C2A9402059407DF101C5498" + + "86A2E8AEC709F184B59996D6EE638F4566814A9E5563287697E228BBA7E344FAFECBD4446212DD8F" + + "3DA9D364A02BE42D50AFC2541753645BE64BC0A5982F2E89FE3602D291DFF429D661F1B9BE0EC258" + + "87C1EAD56C4231019D6623573CB4F12F63927362836CEF3B852F97485401C10AA3FC59895E911B71" + + "99853E801B7A586EAA46BB80196554E14B496788B4CB86DCE63FD294229B761E128CC8D84D3A85ED" + + "B84C14DBDEA74975917C25D5B02EFE625D8CBAA06711BABE229A2863DBE65D701F17B7B32DE469A1" + + "DF39A6DC5A98B93AF0A3BEABABA40470FF42BF484929AF37597F6D6969EE061C3866446C81B900E2" + + "E2718C8B1EB7F08C8121A13401A20724A627965B7A9CAC7C2EDD629B318691A176C1EA504D555FEF" + + "DBE805156B35F99B0275F2125A76A3CDC2DAE07DA6CB7587370D69FB3D099A993AF0D21D696E570F" + + "5A0967A60DC8AEDFBC285AE7EE99E0AD066F84C24554A5691C00DB09565FF51CC2CF1787797BF6BB" + + "D0AE4FE273B69916FA287D5F8A19DF7291E02103847F8D0B0ACD9E88B0DBD583CE0EDC25C7364A3D" + + "045F88E46B00E96058C7624EFEC4CAADD31619BDF39D76830CE85F747A383AF32F1FC84E2C612224" + + "8B9125265EE16B2E83575D012A795DCDAEB5458E2475F27DEDC0306AF34E0430174337516A243852" + + "7684EA6DB527B45F8ABC9C31923A67C3E3904A9634E2B26DC41329DED9E7894BE6D8C88C38D50E38" + + "57644CA6BBC94340221139F36F1F2A3F102242C4600BC4D66258FAD67B8AD41C84BAB55E21C39007" + + "D789EA9DBDEBA3E1AE44160CF192F30CC36D6A4BD01BCA0CAEF7DF1300D983272F345653188743CC" + + "A4CBF14696831364CDB637A4EBBF3C2EDD022501B847AC9F8AAD8F05F6C0C2FB12550B0C49A80ED4" + + "F8985AAC790DD4BF3A4D14DA835622AFD73AEEA5570CFC2863B1B2BF7E767CF2DDA857DAF683DA78" + + "52E611F3E925ACC4158982C59AEB7C50735130548627A54B41FD002F1A37395A008891D35D6F7994" + + "0538E724C1BDEFDED872122FDEDB00E3BA6E6362BAB1FCFCAE448389C954C385810F2F870A60BAA4" + + "60BAE11733E79E84125B2820F5FAA334BFF1857B624F98B98946177C5F123EE38E585D5DE6BCEE33" + + "C0E5D9620E4DCB988C8F99494449FDBD18C7D3221A5E69EBBE366DC1932FC3593BC9C4600DB1805D" + + "6831DBC9FEFD19FC19F18CAA152AFC8545E7138FAA34CA685898465E4517AFA472E84C17E4AFD3D2" + + "C517F55D971CF182270A77BD55F246B549BF79D1CFDF140F4F23C707AD248FBDA46982F0E91327D2" + + "69163D5926FEC839F0F93B736D773C4708DF71BFEE5B9865649DBB1E2C36AF8533E6490B271CEEC0" + + "E3B5624689F35B5F88AE2699995BB8B321647615BEACEE5340C466C8D7C4F52F780A1AA70EBAC9DB" + + "B37ACA1A89EF4A9AAE20CF1C4C67CBFD5C710053CE0ED953C8B088E3F567D3F181C37C8AA94BC440" + + "1835D6B118BEDF01EE0F0EE1AB4B9E2F0474664E2F62CF85D1E8DB2C68B90D6A53AB9E6C3EDEC82E" + + "FEB845C5ECA4D95DEFE544B7B618EBB7A2158FE0EDDEBA33D4FA8684A98E15492B1C661B19729B60" + + "C9C80B22EDE265DA2F47FA5427F44B65D45F378705A226FA0831991CF21BFF9D69B7D539448E920C" + + "828B27CF881D7AC5395937180F04189E014FB180EEE86557178371A2BA84BF0B77478C1D40284AB9" + + "B1880558721621DB598FBD04990A530FA968F7D3D72C4E3EB2A92E31DF722DBF534A8A42F70FBF0E" + + "5748CE08C371B5A6786B906EE79E033CCBFD6832247924289780754EB0CC7A39D6DF72DB68193B1A" + + "DB53AA039BC540C9993B0E724995EDC9233722FE8C91F9226F2B3428689D77D96FB1C712424860BA" + + "7F02E0AAEEEA640A07DA78E0F3ABCBA365ED4CFB7FBFCC79E5FD5DADA0F4A49C1816A958355F10BB" + + "26B3E734165DD7CD5F6806E7E478D0285A1509FEA68BBEEF0F8E3DCB782A0C6CD4307450E8268EEF" + + "FC04395FE3B32B56E1218341CCE4EC9B04CF5AA54DD3D198C7EA9B0FCEB14ADD56D5E39327C3BE69" + + "348B9F49C3D457704043023203E5C5E0976022A21D5FE1806B461623552CDE06015E8B13B469F9EA" + + "8DB96FAF32B5246CF939C005C9C0C8BF9E53B2BDBEE529AFF234E72752BF195766EC63E61F7FD31E" + + "04D4087FDCD13BE986DDD2CDC060D6F19F8E2F06D3284101B89CD705AA4E9D7021731D95D6C93D21" + + "3ABB5094C1D2F43DF10E35BCEFF491226ADE481AF375A4D67293A0B59EC8FFD44A1EFB654BACE001" + + "B6CA7A4F250F03C129BB5DD59D884035209B40A2D3AB086C5D5ACCF3B6BBDEC8B4E6A333ABC572B3" + + "357360A6345C2F1711B120297495E75AFE261498C2393589629132CD9F52E741C5B537BB05069272" + + "F38E2CEB454059E7B34386920738686D2E66ACC6CE22A53E9C656ACE7C9B9D84B81CD02BA663F00F" + + "5801EF459184A72F83B456A28B4A8EC3BAD24F354FB1E8A3881716AF67EC21850938115DE66011EC" + + "9BBA80653F269CCFCB3817C7E9F947695ED6A6A27043E9031995C9271959FCD19A382F971B477A2E" + + "B986F251EF3B1BD2602BB7E231AC24CA519BADB9555655BD89070304CCA89416B9D74E950E3B9FC7" + + "4F1E7E6F1785D89D3CFB3FB05D3306081C008C8F026AF1DE9ACE680A4961C6914B0BEC5B5F71BD16" + + "96056EBD862FE421E298F6D4CCEBD23B7ADDE1D59C6FA3ABB9C6DF4254E8A112D4597AD4A66BBB7C" + + "A30479ED0C80572B4D41440084927011DA142842AC88265B85035424161F7DBFDD66670C807DBFE2" + + "088BCB7B442716297E91F4232A99E30B11FA6ACC6260B619BC89279BBCEEA2CE3853DB8F943755F0" + + "D0B784CD383A49050224FB224CF836E41A5FB29A17E6E1025E2D5E739EE5300C1CB7C49845D1786F" + + "243F829DF100FC96C77A74C44372A7944FC99FB1AA6D4484C2EC23488EFD5F8F24F60DBF7B30CCFD" + + "DF08E1E369F2F840FF5396A4609D6632FFFDCEBEFEDB9FA95DDDB73CB3A7E8E56EFF4F10A0438290" + + "AA22232DA7BC6CDB33C06663163AFD2E198127EB83A36222813D60CD7999F36561E5F9FC0AB82B84" + + "C93AE015C96923CECDC8AA93A9E376A31E2DE6D241351513D630CC3909CBF7C315D0CFF947815067" + + "0FA2038EADC9962E1F03C7017C4055983327971AD03271D057585D401295A7E62F621397CE493B6D" + + "4B9D6C7B9C4E1C7211E18FEE6780C9223AD2D8E937E2CC8C7E635098B3677AC316FE9B9A55ABA32F" + + "419422DE2225497FFAC6FE480D516CE637C2273F7E5D0733C0B114B1FFC4E9381AE53AA3C8034EA5" + + "A2CFF6BA9A3A752AAF9A5E3EE4BD157C38EBE270CBEC4EF0819983827B1B8195000BFD94DA401EA2" + + "22DF9D4EB46AD29D68B6BF4A994FB1A063D0FBB9DC97094DE913A9B75B7D33F8357BBF7C8CB2C17C" + + "535F1A85696BA8AAC259110D38541DE15B2A0076E725FD823B28B542F974F975DE330DF9796577EA" + + "8991DC59FF6F20EABDB8F08527A0B0615993EAE055323B9FB2117C583EDA9A4CB028169786561526" + + "090A743413AB865B8C4CD414B22812A02863B015952AF531ED0431ADFB3CAD2DA79C0968D2640362" + + "261283330C8851E1D612D43484BDC312734799170EAD6D0F80E19D030AE8B2FC9834D2593C687987" + + "1B3F5B694B2D0F44A0135085619B97F96BC09C860F6D21317B1F6294026425C3CCFAB2A6A7D9CF1C" + + "67AC702B192D1CFAC9D5BD622C4681CEE602421B4A76F1113E6AB37D9560CE2923C8CC913B0733BE" + + "3BAC0AF475642E807848067502F2E5333EAC334DEB58A6D3C932C75AC6F916ED78450E2FAA30BD72" + + "B89FD63B34975BEA22938B51F5AC034ADBB52433D7E61F4E843B0D5EDD08C6CAFE28FAEFA28288ED" + + "669F41E6489A2885A3EC3771FABC9BB28E78BDBD85C1896479D4EC1D32A73613261FEF7399AEC742" + + "F89320676C409EEA462C96D895AF0C5512DA9410DC2119C453A3B198A6E1DE2551536C92179C3E0E" + + "E4C83E4B6B89B6D7B8965477D4199565253703AA4E83B3857702624B86C4EB6752692971863EFC57" + + "4DFF1C5A665528B49EF357020390770E3AC58968E104D7D4F0BBCDFCCD33587C3A073BC691EE4A00" + + "6B434F5E98DB231F66F7A5DFBA365E89C5AD48B15693F8EE51EFDE26B0DD06DFA5449E408D9D8139" + + "6D2490C621AA6C192EEBA397CEF0450983DDFB1A149043F6BEC78A274F8D74694417A29B9D7CCB4C" + + "0AF3B7F4D4C4A72F6BEECD0206C6500FBF2E42EDF6760CE5E0775B751FB0F851DF01E065A0032400" + + "B4809D5C7355E1A08CC14C96CDAA4EEA5858F8F9C45CB0094A4057E766DCD10BC40F984460653ED8" + + "7120D1D0BA439136E94642710FE9104CC5FEC1B12D52C05E9106D95EE137319ACA07E2D4A876070C" + + "F1843A263B63129D6E797C91FF08E053F57A46C24F82BB236D7DD522867EC64290C1B90DA5B5D8D8" + + "C829E19C5A9E179F2969536EB898CDAA92DFDC133BDBC74F15D73017A70ABC48E9FF5A1D2D4D0349" + + "9110FD4ECEDB19C1D9611762FEC2D722470EE95DE8A9B027B7214AD159A70CAA41DAD613FE0E5EFE" + + "3419C15731736A33D1B3C539F744246723FC5C2CDA4EDA9AB949D568F6A8D60C48E0A20D10D32314" + + "4E24203341C5F31743CCBBD41BA6DFD726D12B5588B858F1E607FFEA5C6833DFD077D3BA25016CE5" + + "9E5E214E99BD1348CBFF7544B3F48C21DE4535AEAA9275651A55912EEFABD69C16DE4A14DA37361C" + + "B5AA7CD2CD4E3462A6C265FC9E82C4E872FC86D0D9C9F248D14392E85632E44442D3306F7BE862A1" + + "266AF7E2F4A8DFA8C7A047BE7C79EFE519F8BB2FEF5BCD9EA45AA57D2B8B89B9BB0249C8AE0C408C" + + "72824323D0899FE7515BFA04A21DA36F33A6EE3535522B0AC418481B60404113FC5D4D92CB004493" + + "8FDAD056954ED2031DAA09F0203DEABF150E24151C2EC221B290537421C11A3C970F721F124119E9" + + "2D64492261F4A450D16E54E53DDBA202FAE297AE38FF6867CC6AE4C48EBC2E69F361F1BF31BC034A" + + "3F8B748928E6A77CD301DB40AA0C4B1F247ADF643EE3DB46F87CCBE4577603D62342BB831F8CE2AB" + + "CF23A7690226E6BF4649363492268DFA0E93160B91769F7B6ADD6791CC91695AAF718BCCDDEAD90E" + + "875D5BF7F26EB48AD3871488E6921D5AEF8554DB346E1CA14128A347B16182231BFD9DAFD18F01BF" + + "B99CFFE933AA8252B93C2D600EF50B250C2D86F32D6D26D370483269E4D6971CE662D1409329CEC7" + + "1BD0B4D734F36B4E66828569ABE7218ADC921202729E236E146154794372A7929632DB4FF8026583" + + "4AA4080844AB7D3ADC14B23ABC65FAF620ADDA9A77B5F26F8ACA142921FD9F8ECDCF676C95431BEE" + + "FBCB2F36E1315DAB5CFC4D97913353B1119D4B5F9979050B4B936C191057F36D446BCDCA67040CD5" + + "2AAEA32709", + contextHex: + "AC5AA9DE77F1CB53771EE8CE1125E4A1E1658A5269CA08E0837594FA91D6967D6C256E12DB8F604D" + + "6D16BBC931AE25B99D70BDDCA476501A6D846ED73E386A32E8197C36DF82119F412FC8B9E47565F2" + + "4DD333FB097E96E85C4D94EC2FA27C36D09F3F96A0738DD06BC75B3B5FAD6702719D7ABB6F3AD227" + + "B01CAA6C537D669C6A28664B78D790C88EA236DCA6470507B9E86A953FE65E37EBB76D303B1C73A2" + + "A3018264B421EADB33B9A1CD72BEDF1D4DE688C61F099EED8D1A6D62B2C4823070A89A866553ED42" + + "AE899FDED3EB52581A20F5BE4CE34B3D88E7B8A1649965D39775B9C416F93E42A4D5AA6A4726D445" + + "BCD1FB17971AA5296DB080A3959218", + signatureHex: + "7A81E060EE1C4B16BA278208C47EE25F5241B4D1C5B7DD5928CB11B8584074FFE3B8D71245404E04" + + "067FF9D68CCE5FBEE69C2D98BCC50BC1F8896B1B404D68DE18E8402BB3EEC1F3CB9CC6A51460028F" + + "7B6EF522423C478CF4FA1A35469D271391801879FA0C390ECB0E9AB37EB69BCF4939D1FD1B886BB1" + + "2A9B0FEA187D9AD8C3620BD42EA338E601D5AC316174255587C21E066738A2CC86E708D7589B8F0C" + + "F4FA66464979E522B7F9508BF8ED62FA8BAFE7B1945725EE9F406AE9269A5C7469E472F071393130" + + "AB8D532B6EF71190A3509B17548194378C10A8A357A04217712FD5A917BE63522814CE322F329E62" + + "3BF6C8B350D4420B6F565AF207B772B3EF28AB175CED72EB2D62C3901526D5E081F4C12C83532BE1" + + "72E9A26072563E2095BF9052D24B8900681B4F89106FF35B554A59E2C197E8F405F8D41CEBD29CE9" + + "9CB746D19DEE8ED77070631D35151C3EC530D2A2DFBC2F408A1A25A3151E8AC004900CA7CFBF83F9" + + "A064F3EF41D9921EE25A65F241D11D78D5BD050F70E0A89DBEF36C2E7BBF1176E1DCEFBEF41DE6F9" + + "A2DE6B268E8025BA470E1F7E1DAD99DB468FEED9306A7B3168F2C6FF1F55ACA06F920D8108F8E30A" + + "B707DBCDBF95A837B2B94564296454E9A3778EF8522B8B3A2E67404063C8504484D83CF4921F329B" + + "63BF9B01B915D7C0D8EE8493AB8588A2D57054A6695A3CAED52655BE62303DECEBFD349AE4416B17" + + "8CF4AACEDEFCB6BBF42E6DC4507868B6332C6539E03D68599A4F203265174F83F4575B88D73B4AF9" + + "D93905DA220507A6785BF83F5CA94B59359ABA05DE73BE3B9F5B4E16D17F21BA6FA353DC9EBC288C" + + "2315B1901C29859BFAAD9A49EB543D0D2D745B8613D1BC5E3CC8E6B8909D51F9BBAA539CE475B042" + + "A0A33E83F1A6631CB14D12A23071B6761D1587AA5C77F39D25892197076497D1DF5CD9381EBBC23B" + + "392E2126AA4AC29B342F7C31E9636E163204954E1DA0407622BCBFC22A27292D090ABF967CA5DCE2" + + "EBE932AA10A4D4348695D8D92384E99DA34E8910C698873BAF3E736D702735ED07CEB67E308C40E3" + + "FCD77F009B6F76B189CD4A2EA004ACA601499D41345F2170593A5DA48AB4906D2663DD2E3638B9C3" + + "3FFA6D3C02F8D9A96A6E1B0B5E5B0194C0046AE36F323274EAC4EEC5474B9E4BE845AB547F276129" + + "07F1274941F59B153CD7F3806A0237FB2F260DF270B8AF57BAA5A2A25E08CAA5DD7B68BA5765CEED" + + "3AF544E215FDD353206CF3C9E9DE49FA32BA46FAA5F140B5846358E06E15847231121D4B02AC417F" + + "8AD83568C28D33A117C632EC56E7C453D619F516C653CB40729614111DC474181E889C77DB60652B" + + "558224A4A9F6D23ECD3178B190619752B44D8BB1CA7166110620FFD0B29D3CEF7E252911EAA96435" + + "E2925906972BAB086073167A68AADD4C3B5B6F26A2B7459C9EA8820815E538C26B572AD7E2FA0B25" + + "65FE2320DE29E2B993C14D7121152A982FCD929D4973BCB69045E5018D37B65483EA6B689BAF2A50" + + "16084263518F0C77ED5260A63EAF066A4FD4590D22CCDD2C5BD86DCD58263CCC177772EBE301EECC" + + "25CA5DE38CD40F2D6FFB56BA5FCC4436306D89626DFDDAEB6179656AF9E6CF72B87EB3B2B532F867" + + "A8D83B9A03594606129C70FADA67A7EE3DAADC5662C2F139F3E29672FD20138FBD32601E9E853D81" + + "B42F80AFA0C631DEE874D77C6B306EDF242ACB09662E5C678A4E4042FF6D98F346B064219C786FDF" + + "D047A4ACAF8FFBA18AB7696E9D86521B9001FF0310B534540EFA908EF99C6B696217DABAB806A3AF" + + "EC6F2BEFFB017D31D17F5FCD2971F0B16228381DD8AFBF06D049F2BC0FB3BADDD99182BDAE7000DC" + + "FE76F98B6098D78E7FA454C914B3BF525246A0EC766220067D2E9641EB0FF897AB8E349C5ED5252B" + + "3AA73BA547A1F2EA5215DA19A967E2A51686615077F1B17E91F223A2F6DF00D4DDE7F5C656CC79D4" + + "9E386619AA99D820881D757799149C7FED3BC30816B6F0C56A332BE63C7509F5AF754787F17F00B0" + + "75047C79D2BAD746B2F2D104413702211BFF9A9F6E54FE45B4CDC2FD35E098D1FCCE00114AF0517C" + + "0896EA85CEE77FD7A346AFAFFBEC4C92914DB050B93696222EE6BE72FD5869C7B1D5327E63650DA6" + + "ECED0CAD84C3E4602BD1CABCD98C2C90698DAF764DC4CF2B502A90C45468EF175306515C87A9EC32" + + "038BF5C3E3ACCAC51B726ECBFAB957CFDD417106857E14AB5941B1021847C3C98347549D43E85885" + + "476A28B3B0C727CF745A80134D20F7BEE105D65B6134AD24DDDBE7EA1AE8DFCA9F6AF7E3ADD4BC3F" + + "E2205E607FE76EC53F09266D79B65F9B3DA1D5FD42ECBC2F382EE91C0A984F34653D346B8613C6B0" + + "0CFAF4281EAA35CD26D5BF10C85ABF04E75C2D852FC46CF3F8D51E037F27DB7F85438DD9DBB19C4F" + + "89DCB809222009494469EEC04870097F316032BE259F22CA5B3ABCA53093B022DCABAFF0B6C6239C" + + "AD497272AA5D4B15AEF2A4ACCF6ED7E7219E97BA81276DC7DDFD2CA81228D2D7001099EF619FDE71" + + "C567EE8EB092C06498E86F09579E2D8E5C98F89F918C9F1031911EA1203159BFCF2DC9162E577885" + + "92B3F63CBF9C2228F7863482775B3A9626A3CEFBEAF019863F8529486D387DC0CA0D8765AB4BC01F" + + "52E687EB4F333AA55BB75A2C6085C06C02FB57B67CE12E5C38694720422A59ADCB0F3D799577CA08" + + "7B251E744C89CA3026DFC4274422B8337185D1CBE4956C9E7D91DE578D2C496F2C9034474C5BF762" + + "B5443D7E12AE123698FA20851BAF234F0CB3FC608BBF55D65081A6D0534B339FFF5045D978689D08" + + "B9659A4E2DF50E26D7F02FF7992C9F62665E5129D3D274B92413CE061C5F8711D4A971779D22786C" + + "66BF9137C80A0A51767EB33214846832995066BD3DFF234306F5E86E097F9951A4379870420E0D9C" + + "F8892E7C680D9DA71784288269056E31E0461E23FABF5B134E64E5182654089B35DB8F5C2C9E3181" + + "45506F37ECDBEBCB50E4122D59C1417D0031911BCE5C74BD468D5E58C9E38449032292C80956A2ED" + + "E437D3B122834F8DC42AFD541F939F489B953BDD52CBB72430230CAEEEDDEDBC664651D169C8BF68" + + "1DABCED06CD9B6DB28F2394ABE928CB5DC811DE1AF426E68C66062BCACC8C4259D89CF691EDA7A5C" + + "AF413E03C6977CD3F154700DD7C8CBAB75F5EE02C2E18441FDB9772A6014CD77214EE57420AAD951" + + "84D003BA14DD99C90071ABBB56F5300EB8822267039FCE9446E198E50317883305CCBF1798165FD6" + + "33A03F5378A528D9724B30E972B5785BE5D8BF1538C033D834DAAD83B0C93CB90AA22CF5DB2412C2" + + "8D7ABBDFBB5ACCE600A350CFFC3FAE7BC9EFBE6062E970504AE63F9432891EE568F94578BF6634C6" + + "E8B20BC64EDABB33A5B45F73B47A5526C80C5ACF9D555D568E3F2DCDAD0FDC0D8C107E9100FEDD34" + + "DAFBD63AC567A08CF8729DE0699C262BE92FB47249D79599413F5BD4521CCE9EB2A3DD22C2AAF60D" + + "F11BD19F8E00E937D56F6623B9170A9639E576D5EB2CC71DBF3F881F65BD9D19143C127320AE05AB" + + "F9FE4E9BA6B375B700C5DF5DD8C395E3C083198DE3862963ABB3C4AEBF6B4205C74C89A4E33F50F6" + + "CAF998C55319B1A4D851C7A18F20810418CA6EBFBE22C712F4236F5EA847735E532705A5E87CE069" + + "E04B9AC5B2BC4FB31391D1ACC7942434FF09C078A5AE9FF0150EF9A465BE3B15B06B9461B7858E8D" + + "C0DD1997C1B75280AD76F2556EDBEB977C597FAA146C14C39D96D6139C0A11C07973D1F54C48954C" + + "A2157D3305B9556A597C257CC7E49C78BC6DAFBCC9BD80C8D9CB8546605467A93B6D2958C6B956A7" + + "1BC0E262D4E583E25A5D1430F4A045517C4DFC331EDC8B639A5896A75C934E6AB49339BCBE98DABC" + + "DAC2C72633ED39E865584B188BC6A4B176E2E282B76ECBDE94166A1BA0E741B287F07DB57B8C933F" + + "8A4B02305402C5726E3F0690994E9884AC9EFADB93B2604EA6546C2744B3D96E31C4C76300ED9AE2" + + "9B8374A6931350454756C833B0B9AF4C9294B152C95EB5CC4DE75BE8F44AAA008C86826D4BACB02A" + + "3A1535738499E8BA7CAE942006C51DDFE3CED2B47C90722EB3A96D2414AC32F38F29DE6D86F790AC" + + "D8AA904BDC27E67D8412EECC22BD47BF06FE2F309D13C1402FF2249CCC8D9EC8FD8830118F0E0114" + + "3F5E112D3288DBF2AD76481806F948D72F51FC0EDB30BFC3DBDEED61E18D9AA935588E078789033E" + + "456A76D7FFFBB0EF4C66A8F846CCB387BEF7AE0E9737B08BE8A4EA7B487F27A9BED1711028A7E0B3" + + "3E7FC14E310CA91A90907F38F50DFC7ED5E525F100B218D6901B7ECC93035BA3357A5DF5B0F27E03" + + "3653A92A8FFDD49651083B27510B405D8A586C91EE0FE9D501EC5ADBB3F160989519E672107A9D22" + + "A46E163DD3B077A1B7B43842CE6B50C1E04EA8D6489943B1CB3F4CABA4E9D6E5AB5AB190D63C0D17" + + "6E5E093A131CA8442770D68FB71D8406E580F53EEB56C870C311B3FD666C1B8AB426B16C9909A83E" + + "E1D76B5B7DCE7F20042A802F8DE962DB509CE68774099E938662296C85BD63DD889DA5C04250A06D" + + "9F442B2A96F5F6940859666FC8C9DE04061AC834377E7F91A4DF14538C93B8B97A9BAACCFD08094A" + + "4C86A5DFEB000000000000000000000000000000000000070B12181D25", + hashAlgOid: "2.16.840.1.101.3.4.2.3"), + new MLDsaNistTestCase( + nistTestCaseId: 50, + algorithm: MLDsaAlgorithm.MLDsa65, + shouldPass: true, + publicKeyHex: + "299E5B4CB6E5BB7712A9F867C3FA7F24E582D93ABF5C178A676C498B8D94AA3DDAA82FF7528E9C43" + + "BB6010DE12823D7E8BBCB57B4CD45D26E41494F22A53C2A881937D9EEFD8E50EDF1D41318AD7E9D9" + + "FB7BB48D0A22970346F6CAF569C6D9D6E3F643051E24EEF9B83A7E4D3B693BFD49F8F044C9FF08C1" + + "4367D89017400D7D179C797FFE6886FDC0832E48FBBFA5F735D7F5B3D1D93E1428EE503AB12A2F25" + + "6606965527B8F50A1CCEBDB515900E26E571BD3D0AF48F0007E294EC2ADA631ECCAFE2577E43AAC9" + + "E6B3230408AEF3DD2784ECD2B84603E77C9B21C88175F2528411D9118CD40B34099624D93E17E525" + + "7D837A0DC7B5C6F2BCBCB31F81228A8E8F86BD6614F3FB615B2DB16D7D48AC9DCB9A1C5E76F2D6CB" + + "B1D6243A5955B5C16DF46FCA532ACC896AC3E58362AC47730317EE9067F92529B7870CCAC343DD7C" + + "3DFB65E45E9B95AE5C00E1B8A3E5EE687944253911E608816EC90D4EC4D210AC3051006EAD425BF9" + + "DBE6ECED39961CBD00238336A45A6D44B38011AB5341DF573A35309ED6131F6E20EBFFA20318490A" + + "2289F12C994726E4ADB6A22F929F180A4E5AA7655F11A12E7E4AB3F824DB1916D68A7E4778ACE59D" + + "DDDE9AFE79757EFB9BF2D32C7A6DFED18CE2C94BF3F87A1F0761258371B3022651225387135C463E" + + "ADDBAB8E9E7C0C14B7C846527A915AD3811655438208BBAA08239A0BE275900E9123853E7EE55E63" + + "2FCA8D34B9474079BD08A8D38B91EE02343FE95406D2F946ADDE3170E686AB17A02B8D50C1F28CA3" + + "6135853B15EB31DDE456AE7920C4ED2E54060BD16969520B731BD6C34CE7CA55F23C791CF3D13072" + + "6C18CBB62F3AB0EA28244EC89F64E9028776F34758E3774F2F55F6B583D233CDD2280CB65F4AF1E7" + + "7569B7C7B0767917F1C3D92DC6BDF70BACA7FD4623E8D1E6E58EA3FEAF05A1BE7C1283A85E8CDEFE" + + "D1EC152F3FE127B32AED8C5EE9785397666F35E1568EDD64917F9E5BF9B83CD58F4C46ACD47FB159" + + "814E22DB45441BD63BE4F081B77C9ABD7BA40BF9C3963A0967F68F153B2472B17E793047442EEBA9" + + "1456B54821EABEE5445E28FE8A9B510082F29C5D56E42EB1ECC385095B4E035B01D07F8F5F89044E" + + "602FA045B7D42A19A4A5F44EDCE4EE03D8D9D0D8CB52397263508422B3EBB5DD8F660224D3B2367F" + + "3AFA6054F1EFA4887F85F8DBE430333A4F515E059D38AF85C9B8ADF3ABFB4CB8201537049AA5D8C7" + + "493FF4473160FD941DE9E1F1E4633E8AC4206152D07913945413AFBD2EA10A8D22EC9EF793756A83" + + "D1D472F64F48ABCD64E151F6CEB7B527CB93C76F34540D4C609C3AF102118B0DBE58E82FEE23111D" + + "A3D87708F37820FDD10C0448923CB3DBC0066A11A231537C88CCBA3E29517BD699DFFAC4BD8ADAEF" + + "426DD70342A8655C8DAA8F41FC3C6C8C1D35717BEE485D6601A5D3AFCCDF601790D4978E9C528DBC" + + "5BAEC855E26A753DFFF996BD6908A26C30C5DBB6908C8D14BD1A8142649954FA2F1DFD94D30BFB23" + + "E0E49C0819C9CB088CEFADA32955E7E1892217005C2064667EA86BC4B88EC3CDAAA57BE053BCBD02" + + "6EA951C5B8B07781D8033CBD725F81153AE7D8526E8F713D120D563706500240BBDA4F6C7F71C89A" + + "9B7E73CC45AE0C471516729771FBF8D80410FEB8DBB52116CCF715FBCFFC4A7537829A0E864D4858" + + "35F79E3D43DE186DFF5BDDD4BEADD5B07D6885F3704AD6B1BE81896F31710B5B5F90CDAE14B2280C" + + "210F1BE45B6C36E2887FDE4532FE8B36C91784FF56785715EF57B0C6E455B7CA1BFBA7C5B6D6E94C" + + "3D5FD7448DD84B697DAF1DF2C84BA47F39A633B52C666BEDC0F4A496AD5E07DC01182EF21D5D618A" + + "22DBB85FA40AB09C837537260383271FEC35974884380E3CD0C92DA7A3496B5780E5110A67389157" + + "D32C4FA714063678B9EA8640318FC8153977B514728747EACD22950466FC17039D85C2C8DADC8C3C" + + "AFD70C8F14A5793EB27CF8D4A6FE3BB7E8772FBB4FC57C50C751CE6188145F04EAD8E04122114FD0" + + "3D469A639FE04411C998436A6AA76C35588D428EC57B925B83B1412FCA0B60D99177DD373ED88DBD" + + "E7F02D40564948B6861FE9F65401D9B136C18D4D2BE5855550E36FF37C3F5832217B62B8016C5B22" + + "AC0016911D5C092EE47ED0F0BD52CBFA39FD5BF7B87D502B39F0E7B96ED32A31EE0C4AF019BB45E0" + + "DBA203B21C5443D41ABA078B7E07C02EECA1245AC57C3B480FEE441A1093593013C04A1E0292ECB6" + + "16C90CF06C09D5F564CE172810DBF547B5E5EB613F9BD2449E8A98ACFD5044FC505EE7BFE4F1ADB7" + + "F596EAD86FF3A4C21AB874BED34AEE2922B9817E3BB0C4C363CF4137570F1B268BE2984E6FB03BED" + + "16DD988A81A17EE432D565F1DFE08C6B7D1E980BBA1BBD71121926A1ADC944B15762DF210E6EF3BD" + + "F8A483606CE5B472FCB1C475BC711483565000D1E6C246F53938CE6F325D8CDB459B8AB8FF825C81" + + "CDD0A13847A5235FED7AA58E2C9F0873965AE39EAF073F3EA90326A85165A10658796A014B061ADB" + + "9D891AD194F48562708BE0271BC5C853A481C7D05AE49B5E50497F944504C0A098628383AEC2C8DB" + + "DB6860B015BE0B377A6F66F23D7CC36C4B93D6C905EC1A5292AA9A11A9B088ADF516707FF1C5A96B" + + "DE1EAEB4BCB5F270E3C1749A345DDD670A49A17C43D8FB0BEEE4E803A53FF74D4C1797BAAFC91079" + + "93493E91FAF9F327A8C4FECBD78B8A0EF153BD69659B0FCF7258F6215D218CB8", + privateKeyHex: + "299E5B4CB6E5BB7712A9F867C3FA7F24E582D93ABF5C178A676C498B8D94AA3D3C44826A39ECD5FC" + + "4ECF7DCD79617DBA1A21F2A43C7C842A6616CC4F7DC15EE0AE64E5E5C302D90AEED0C40D136F4CAB" + + "53EEB562A763A1BBE98F7E0EE2BEF359D1D1EA2C27FB3B2ABCC1A5C2D24A6B5D69995EF8E74265E4" + + "2A516119CD15B9985637204623845382858158474175261375207082000650048265521365815727" + + "64528137115002036806637445522426250026653370671436378334002467076017460565085028" + + "54788535112160475547323551875452220234571342542174833161401242426376640045171258" + + "52686383880430682331881276014847841302308601143747088162873204244458856031588534" + + "64662855758075136726448118267671662038010776627887014257644544115062427005131210" + + "42521082541248404653205463784786527346028382242776707347010263848138364111143081" + + "73774301247640342808517270313651626137334614770533455630010623378415671230745153" + + "25242006050402877011517486887815048640027820715203711442268747316567683802262343" + + "44606778070160027815641455288520543366300612861150182246281470135414550033064825" + + "85067158608080081122843274151558508013861051280413044225822117685763457353713187" + + "17330142205320550316874323571834187762404280583017763671000472525385568605255537" + + "86837415185818547210173415163051125507822851764473013002873031843481878028722285" + + "27886876672055061062854518666067203435530663020088801750654620205581654152664265" + + "67326731025475867563832428714037486456618472486786576651066781205616700327752274" + + "55887644464484861624140106204385881412724044524450032861325556437304754565214332" + + "36548802572566033804156075210125467512865303185386678272023428325126457604510817" + + "17001112743152375855271252870588816161081538416051037745074184551251218307180475" + + "55700382262242014428364685645845868235845064162400871666462460785605576471153252" + + "86604831407322785417030261530056714460406765616876106172840567314806528781408135" + + "82157284105328867274434512842578137653361415874532051522208650068453500448561257" + + "88166713368733030130358630411352884835816744466643252375771137175853567058661353" + + "76858381378172310823058622827312160156263436751622362738653067431276726506343881" + + "35771472648212088130026241821048233340010300571428687881320322474253466153413315" + + "76355120067002731802457484836471387084560605276322140518862865146113567482357825" + + "78705026017380854114050650582333461315400584878207400520000117236681307337850875" + + "46712330224162081132564202780251251016717238287856708030816224018573006525421762" + + "60285245518630214571316823457646846084528333124208360631533622808501682242207782" + + "70283318711632351221463403373233148748457174782724421531588688477302335571704720" + + "56632158657831123246740637011327521555015310151565520037645700203344016220188773" + + "60641774833827121642522456380753333766757234515476063613866341083251367416022130" + + "82105357707125527642604247077336067386081745803164072587332040887838641318767328" + + "66133816226132128746041568372774177102337115553530156828672445841237127206132783" + + "73720034060214835480372857131508736538070857554386577401113062450557807424810722" + + "06605226463743717818650638427385027657701022870208302855134636852384728802122306" + + "56056412540616377428031812030181467477146415421075766530534548366777670451413581" + + "758616867572337260745310760738889621D1A6357CD851D3B03C08E00CBA6B9EAFF5CCE8CBA5BF" + + "8287B61037A8DE622198A90471282BA32C6A92159E105B3E28D490BC6619BCF5C26199A02D7E5C12" + + "1EE7012941981DDCB23D57E62A47CC03A7F00AB262680EAD68B4FD4FDB916E61CCF1533F86B29242" + + "3D6FE9DEEC91CFE77CC45CE878D52962E7DF442953933B6C70A0D9D0FEF94E08283163102A65885A" + + "081ED1AC061384BECCA1C0A5B135BAE2FDB9926CDA862AFCBA3276AB41050C12FEF5C410D54E75B7" + + "49B37C2475DC5BAC73A848726BF0EE4F2751AA2C759C4605FD295BE6BA1E9EDCBB9CC6CB13D7693B" + + "E9C12F2CDEF83396A6137F8F68BB94365F27599C9C6D4DB974BF1C49AF6D1A8A8856815B3DC26C56" + + "7975F15ED45F79ADFD4E474654534416301FD3B8FB4D0361D61F523378AB8453C56FA661C3CAD9D2" + + "33A708A8871061482FC18AC6A781441AA25D7D9EECA0211C7D6AE737FE16533C5F4D126D0F0A549B" + + "4445246E67BDBAE0FF4EDE37580EB68859EE64C981D18D81545511252DE245844ACA7DD34FC7325B" + + "2E5E499EBA297E4472224ACB7467BB968A474B0AE1CF9B801826CE103D96250450B3F4C1F7807E39" + + "50470A01AC25FB6A3AE3D54B678D039AA089CB8C470DC508E1978F33BEF7278F9EDFEFC3FD98AA78" + + "8C5B173006E733E90749CADB13833E5B7D05F9E673E3C5A4B23CCF1E7D3CF3E0DB87EA20F1144F56" + + "087491670FD7CDDD8413734992BFA5E1B53A5CEBDD34CA77C06689546CE1942311B3031E87EE75AD" + + "F03575E377B5B9D203C3692BAC7CFD2E3CCCC45DD47F86EA5CFB739CE5745762D9540ACB1054AABC" + + "620C75097521E03E120DA586EA0FF1F9935605D1B65C13112B2B8BCAC5FD34C14669B791C9CBB806" + + "84D2F22BE0D9226022AA5F253DD0A320B7A5C894D41F6376F044C84578E7D162CBFFAA73D08DF7C6" + + "F9B3EF66B8CAED7F6B61B57FEC4D88AA823B96A45FB22C302765B0FC072D537901CDA62EAFB7D55F" + + "C84B93FD9ACDD66B704B651D1B3595F37E0E429A36BF05D00C8E09AFD0314C5E79847D00BC79F95A" + + "D679FAEC0476F311E067FC75A77D8ACDF093C35EB5D30A9BEB771730C950768EC9D85F057405FFC2" + + "D0C34AF802666ED106DFE6FAA89C5D17C837B6BFF96A339F638E95EFD2ED63F6135237579A07DF2D" + + "2D41EC6291D1F8CB6B1973C5A1C85ED99E047B8B79DCBC619AA4380F43E8EC113A805C3C1824CC80" + + "096BCFEF92C77D3890401117AE88A2E5C118E36507C5D7BB6A8DCFB54F604FCE88BD52E72A1A7AB0" + + "008EFE57F808E35A5C8DEE2F8B5CC6E923D4EACB0F1994BFBFB4DF534402D93A5781A61A034C58AA" + + "634B7AACB991B396484492CD67ABA5028E7677F9F334477B4BB699C906313D7506E662E55B083DB4" + + "ECC67EA6BC61DD785CAA0625516EF976740436F0C13BEC06FE06B822E2B1B6A2B7B16F6060F5D36F" + + "F01948D7EA60663370DD1B1C3D866BBD1C775ECB41DBA90A8E7BA3AB2E5A99E499E28B7E20C56560" + + "D68EC46104D8E906193D0C3A2FDB9FEE60CD5D8ED898620571976C52BA7BD3F5598FC53B22533DA9" + + "5A2AD16406B7B5297E404F6F5CD4F35320090757D2C47F6BCC1A00F7E57EE8F8595A061A48D5B5DC" + + "D2A33107A92D025CAC8B8C461DD9AD6590A7B5EE260BD5386083B093DB114206BF5661F687F9D208" + + "E8CC3F6C79EDD7AE59610384103A26A19571FB5F5C2169D02A3A4152F015310248FCCC27A3848B2D" + + "2A72614DDDB2F2155E1E01B264696C166EC4B68D8A3983B5B2DCF7CA612A12D33B6D858197CCD07C" + + "0A763494F266797D58D58A9E1E23CE0D5154075074C8B865BED58C57E85BA20C66C9EF74CFFE1E78" + + "8EA500FB5C15C6C5AF3982712BF48E1D48F371E9E00669A7171299C92027DCFC3F48C3DF513836E8" + + "7CACE92C624175530B20F43DA9A7AA7E394D1A1EF27C9AFAB0AA7FB6732691B431B52A72D446F608" + + "DABDECF36E93D01CBB08C2A2CFB9F5DDAE5282025E6B48091A9973056DF441C3FF34ADD023F9B942" + + "570F83845D9187B57D14CCCBBAB758EDF943DCB56D802B014C0F4DF1C84DE2C951ED0817455483C0" + + "42487EF60D8360A2C5A23B81D74EDE0E90D854AF96113A4210FF3DDCD6C2A35B111689120E626C0E" + + "9D2FF1520ADBE16D3B9B6109EA649A030A8701BF527FBDE44EC18DF4C3BFBC7B30603418D8888953" + + "27B7C69AB1264D0B4C0DD898617948BC4AB97D3118C6F0EED9BEDF31F6A46821186C3C2BBE3AF9FC" + + "11276D4B1386377D7969398BFFCA758A280037342125F011BFBF834E9FE6324E86F7E63DC84A748F" + + "6D4423A88976F74DF906D0A22B6E3D443708649D6A0E135D98AD7DE986F6E2F40D999A12EEEB9875" + + "39A3ED24CD7A21C115AC5696C5C52D9F084A7EFBBA0C4D35534FFD9CC11A3F7CA82B9B7A45207CEF" + + "CCCD0753D1394BEA2B35399E7FF4349948585855E85E0751742F5CD7BAD9F8C74A4EB6FE075A5102" + + "846C468C4D56DD23D426737EF6E6919D39E761C4734894A3F68D2BC4DC362CC19A28538281F7E9AB" + + "E6BA506EA201AE49D020A8135E8A17794F2BD67FD7203635A94C47955A9894D45A4C2431137469B9" + + "FAD87608647DD986A21A27B26209618D2C8D816A646240FF0E8F959907A5CEF057301DDB8E0DB1A5" + + "56B9DF9F696E81DC8CBBCE407D44AAD9AC525258F8EE4F734D6125F51330FE806547A72D6A6CDD0A" + + "073C4725420D5F2117D78D3629F0D82462BF20EF0A4CCAD9566A5D3D08088278ED38AFDBCE838C3A" + + "59E421E76EB354462EF2B643567FB3126A75854B356F698F00E88489C137CB0686CB982B3428AC65" + + "105909C148FAEBF86366D7EB603A3B89242272793F6F9F311FF0D8F24181FEBAE42F1501597BBD28" + + "7B04069F5B3B2115820EC62CBC4F3A604785C88644B5E8E91E62AF7A3A764701457AE5EA42BD2CC4" + + "4BCD864E6E923515A3FF5D2B7FFA03B1719D88729A990BAE99527E57C2AFDDA1366F297F5F1F7079" + + "8F3E82F7A529440F6B22FDF3E313FE8AB83EFBE64071A7A6ACFDE1018C5E8C4D190B5D16A2450B9F" + + "D4599C94BE5C28E65E635C6A2013B150126F691C1907E053C822B89DA21705D9595D53BF7679A578" + + "C52EFEE0084A1F65417A6656658050A6EF2BE8A2E568BF4D38D56395FDD2289993E392A0C6E8DEEB" + + "958AEFC3D51C72529C85A7A3F5BED9AD56606455529912680C9711161C9CC896AF2957D8B9497997" + + "810479DE290FA474C47D8562ED7E68D49E5E86985AB773D90DACBB37DB140AB166C6A00A5A5ACBB8" + + "E40FF3DF15415CCCA2AE8693578EF0F37DCD12513D270A6A86FC0F6B29F850C423CA71B587B17800" + + "DB6BB6D17215DEBE8BD282A75D35C6FE6902AD0172BE3BCE6B903D1FBA1AE812235029F8F14D71B6" + + "A9F4E8AA92D407B682D01DF7B8787C8AA91AC10ED7E1805796943B74E2FB3D1F3B3F61F1EEEC090C" + + "7FAB920CB485A01EFF4DE6014D83DF19316C5899B964E2B90F0EE2E244B4A00E38A8884D2247294A" + + "CAC23E8D129C140B472999618699893E77D41837F1AED059E5E009F848411984", + messageHex: + "088025587F3AD6365DB131079D53B93BD6280DCE36D33D4721C7B5BD8504B21BB02CC3AE1C0406A1" + + "4835301D7BC3E64C275003594E6C5BCB2E425D85DC1F6C8DCFACCB849FE18BD9815B3B929F6C8A7F" + + "4C92DCF29182C87BB0628FA8DD87FC83C8CF89054232DE034295DB16E70C2EBEEA3B0CD9A2345D59" + + "B10DB67EE4CE6E5C71239ECE2A75BA596B7F26EFDB7A8867E174774CE46EA6669DB47AFD8B498369" + + "84B790707310326187F047499BFA0D2C0B42C86837F214019412DE5DD6424AB2C9C1E9E8A693AAA9" + + "DCAE3EF86F3B797C11513FD6FC4C2B6DA036041EBA0F10C5E9B78414771E7E4A19C4B56360B43899" + + "30986DE70733694ED6610724DEC36E92129EACA8D4A9157E394709669B01CFA75BE3E129A1226495" + + "6059BD8C9DB791222B50642F5B947C12C10F0A6CC9C9A793EDA5DC6FE69AE276CD083D50BBD78D44" + + "B3D2304295BC4C3853C8C38499329D9DA979632BFB44F55B93F9EBA8CDCFDA8593A49E6667510D51" + + "D0D8B4DBF57570B9B00A1F965C21E851399793A20D1D1007A3B9FA0AEC4EA7C90FC04CE4962EF327" + + "9CF9C5DED67E3E8EAE8AB50E1A1D111CBC4A0AE99D0DB376E8F6149AAF96DBEEA6AEC01E39CD52AE" + + "A297179FC590BF245BFC7B721C99D55D18FFAB282CE026C6297A9FDA426C1837BC2783726ACB7694" + + "1F417BD55C05684588028A52050ED5250A826A3B24DE65D6D2D87785DF5D5FA251B1370106304894" + + "B5C3B8A742EB1034AC62D0CA6EC74556438206A5991D0941AACD3D15438288DA4CD8036A35A859D8" + + "7D11A3E99E0A708FC77A848E0A946DB82DEE509CC38D46504C6ED4DE570CD1C711113906D6362FFB" + + "6901A389D2D44921B75A7607706AEAB6187920CD05DA906A04566354B52412A4F5C006AD445EC96C" + + "3CDAB8E876D61D7465EF2BE8DB24BC6FAFE7E89C4086FB7042EDDD8EDE50A64362FBF2C1493F51EC" + + "F2A4DAB1945591D24FE5FDEAA22B672F9B0227C8C3101940A0BF3D6CF60B55ADD18AC7A8B597726A" + + "B5A09EF89046039F68E9CC9FEC2377BA4C8F4807BF4772EDDD8E31A6CBCF1868A114EB3ACB65D0E8" + + "C6FDB469F9323B03309378CD00147EA0DB695E602FCA9D1C52C6D12826A84EC55D481B3DE84D573B" + + "EF617068EC6B2E733C11E3192A2D31E23B9CB7506D2A64A1FC64382F87BBB2BE82898E61ACD8B90A" + + "163F538A4A4A299577A3F99A0CDAC47DC21D40A57545B3909B2D6354C3A9853437C32B32A826BF3D" + + "0AAE743B4B4DEBE6DD510B320CF0CE4172FBB009873444ECDE45E8F7C0A2CECD504D964487258B4C" + + "36EA89079664791FBBECD477F40F8AA1F2FC60D79A21D16659A196860F892E4672A51812D536E93E" + + "1C82199209286FE7D3A6CDB56CFDF14EFD5E3E7FA395A1D47EDD9F63F65E47C0B1CCD48B70CEC598" + + "21391BB15DAC2411080E701CF79B0BF10D8960CEC09020EF572B62900FF95D6D7B351AAE86AF5DDF" + + "AC5FF3174D9EEB135CE485CD3B41CD3BE8A260BB8BD071FC26BDBBE2AF68D593579C0F8ECC0991B7" + + "E6ED6181F6832A3718C9165C42B57BBBEEC020DF56D201BD667B516678E605FFFEA270068C5FBC46" + + "9C12B4B0253B0EA9028774D208905A57F4EDE1B2CAC749CD7A3C98515E7E436292296FB029F6AB47" + + "2E1C2EC1B3803B96F3CE85D0C24E700CC3DEA6D1833DC53149285244274D2679BEA4013AD40CAC21" + + "0E1B8E23AF8D8BE46D96FE4F7069EB2F5702CE5FA249B181F2355D4E33DDA3C22E173B6E6C1C3417" + + "88F48ED9CF18AF1CF2341877CEDA38498AFA40E3A514D9FB70CE681F85DE63707A9D3ADA933C7C33" + + "1803620DD913909636C04DD08DAEB4C2CF21154C4BC71F5541F28B5F706E0AD7CACD925AD7A91D85" + + "1BB4E7A534A56205FCAB499D134701AB5D39B6F698AB4A1D668175F0B3B16E19BE28934D737D8FF8" + + "E9230BBB8C705840BD450B45C2DBAEAE015A22C39D4C290766D60D6C87BFF1697E79D2475A4C7788" + + "44133CDCB8D5EFCB951B0C64E60E71BB6B660704F89D53FA22C41AB2A743CA0DBE08D10F07946D6E" + + "DA060ADAB9132D992C798A25593691162243712643CAD29FF6C57814A79D35F58B613A8AB4753D94" + + "EB5E7C79E3C0D3361D78AD3C8AF8D01490BE50F7A719F7A8F36DE52C6CAE8FCF80FB1F14DF635E47" + + "BC202D9E462863708EA7394345BE8F0A725BDD41078F564A17F465ED695EBCCA0196B537246904D0" + + "AFEDBCC3F9A6C4E6E989739B2D5FDE725751074BF9125E4A6B32E90AA57894E5F70AA0E501AE9C1E" + + "3F5F00C8A927FCEAA05AAFB84EFBDB50D3BE7196C50346E9511CC22A4A7ECC07095647D5633108DC" + + "C9AE0DEB62E501BA34EB64CEB5A675863563FAB204C699AE45129D50B6103B388C273C3A8A7B4D4B" + + "CFC7F0E32D1219A7A7FDE59E6A950405E89867B031D18124CE92E0CF4D1C841A02644708CB8146AD" + + "C2CE2137350ACA6CF68A560E9650AF16CFBB6574BFDC76C8341AA83401FB903FA6FD00E0E750E033" + + "06A0ACC3E5B935AA9849035BC1EDAAC3AF0988153DD10CA34E3CC7CBFA4860D2172661699F25D2BD" + + "30E6050E9EDE7B6EC9FB294823F85A670A4BE9B77665919E58A13A3D5C73BED852AB0E983917EE37" + + "F33E318CE7B8745164BDDD5EFE24693E7F3E268C166FACFA871001984ABE25E7A9E7DCDFA410DD7E" + + "2E50AC096E45E8534358575EFE981FD01DD69CC437A2A210C64BA3E677AC97D69D24253540CAD023" + + "D4383AECCFEC334DCE548C3CE77AA35485EDD33E69BD8C7E45274B31E6ED24A912833FDAF628FD9A" + + "8A0CA4042BDCFDE8560C236474E2A714133114CD86BD5A7358B718E463FA60A951472110D29FB059" + + "F4D1EF40617D612A68A3D457D14FE2AC1D76A4DB35F2BA464C84E1D50D0FB7E888E51D686977EAFC" + + "934ED71D40AD2E331D2F1F8988393F123A59B84B79F5793FC01504FF8300DC3D002C157504F49F05" + + "D05BCB874E78FE8DE5A06945B5EB29A8C3DB12E0B2FE8EE9B76E0286C625B2A39F6D36A29E3D1BD3" + + "F6B6FE11E993AC03B3DB9AB7983F7206FD69C56A4CF443E4B252D961EEDC845E93AB2024058C527C" + + "D94E7B0A0964F578CE247F229CAE7F16DB049E3B1085522EE6A41C8EB8412B7D8B6119CB0A1FE850" + + "8DE9E7400B6A02AF3AD865310ADDDEF21A8529F2B58362B5658B8D9E5DB9EE4135A819EE786CB40F" + + "96D1111BF7910818FF7785F9601EF9A6D85FADC07A98814BF35CC212F6DD699F7E8911AF2A3A1512" + + "4B0737DF05E29EF8BB10CCE10C3399A7803C550CA3532037568ADBFE17B4B7A441BAF31440018849" + + "6966661715BF2A5A882863E1DF56CC3E1B78E18D2C075E2127E1A1378D22D0E41D356370923CAF37" + + "18070576D6DE86E3F1803610E6A57ECCD7F853C4F742618E9E39BF6539BEBF5288C733ABD3351A7B" + + "A69879EFB06E1EDD9A9C2F518E38FE4BB2D9ACF0592C7B6B70E67F04831969064AE2FDF58D14674A" + + "2A1992B5292F3808CBB6C43D3C655DA48E070417B848F72C525981C640CA017717E855B6D00A7374" + + "FE384C7A45BB5FCCA93EBF8F8B7E3280D062BF9CA4364018300AF89B3106E24E978F96EBC8C78F11" + + "F526FD81E332810F8487BCB3580A0495231541D5CD55F3A6BFA3C20C8EB7078D1618A7A9CB642E72" + + "DFC5F124ACA1F1599C25A2D054A52A9DCFC9E511A560D575AC69554A63A1BAC6E5967AF7F2C370A5" + + "B4686D642CB3F66B620B4A862B14095ABDE3E71D46A6C10A89CF844B118DA81A501025AFBA935994" + + "879CF025AB439669E28C849BDDC0B5DA1727F786487E075230F6CAC17EEBE6427FC5DEFC80D83280" + + "55CCC918E0D9111AD2A39AA1D6D85A659870FEDDC4EB36ACA46574EFDB887DB2C8CD5EA2E4A0C32F" + + "D48FADB4978AA7F3B5BA84FD8AFB4EB46EAEB8A308E5A97F57322B7ECB0F1F1D6E89D813A0A55A5D" + + "087CD48507D5E4F44B2AB204BD31B8ADA24D59F2E8B06F8A3F8CD36FEF9ADE21B276D4C1924CCDB1" + + "25132E3B995FAA41F8C8AD7FC60CD3DD3D67D1D58609087A664B636872B1754FCD1FFEBC8EADF111" + + "625A79F814456C16DF4772089C9AD123CFBCE98B710C9B72C1C2C43322B325B06F6E70572DD8374F" + + "D7D5750E2436119152216FB35E617FD2B2A7D14B9444EB5455963FAE2C24453F7047EDF1DF4D1992" + + "0D59770D087B47AF1C9D7C7217A797C5C6555B3DC91FEBCA2F772EA5119C6F2E19E9F22C09B1AAB1" + + "D408CD17EE74B69EECFE8D4F7B337C008581BFB22C1BB8EAB56AE7CE4583C353A5D7714520704BEE" + + "295BC0C986249801B738B0CD054F88454EED883A63DFF9ADC7137414343339354EC501B56106D73D" + + "A54AAE3F318B6719EBA57959A69AB42A1022CF5E623E4B6678E1596D6874EBC8462ED5170A0ACF97" + + "72D752809AB117A8326A294CCE1E6C7A62B9490123D9F03E25130ABD43E6953A6E9E7DCFB9AE1FC2" + + "E37C4759B311DB51EC18FEA0443E35EFA60C2EBA73FA2579C4DD5DAA70589361598E4059C9974B54" + + "CE7DB868605917CB48ED284C0F795023D610F1FE65AACEA4815FFA5C0A7EDCCE593D33C41EFB8AB5" + + "DBC2543EFD14C054EB4AD7A565A4920141D763EB0FF28E9D2C2661D0CD3B6EADB657A2F7AC107CE5" + + "4A094F991B08F4BA0E01008DA9400D7DBA004F7AF90B5E3AE3F3AE5A5FA00342640D2B1C70499E7C" + + "A05BDB2C7652A164B10198AF53E0F27626BFE2B9849416EA2D76DF4AA5BE7F52B0A35AEB8284FAC5" + + "AD32EF758A31B84457D0DBF09B4E1FFA475EB070174E97A07722E10B24494702B07D08A38F5D48DE" + + "E6F7993C5FF6", + contextHex: "", + signatureHex: + "F1295FBE13D1481D522E1914B92EC2A57C30793579DC4B87ED9E39785A8DE74F74DCC1671CB5AE05" + + "E44197B9745D0E6A68E789DA80A478D255BA71B2D93ED727608F059C9C834C7B9F1482A4D51227E2" + + "2478A103096E9C88BD81D1FAC65C5C1113C49149EDCF4450FDC441892C0DE37A7DDFAE56F23E51B6" + + "EFB0FAB3787294956C952270218B74686E2A25F8248D4E4A619453AFBFCBD59366200B8AA7F9F503" + + "B75A061946936E642ACE96B78E698D8B4F760619377F20FF5906DBED62DFD7E25030D41F9C4273C6" + + "32432CF3F27C7843387614421B815C19AE7107A259FF177806D2215413F05E33B7E8DD2AA660CAD4" + + "C19F004886900D6D3B464572DF45A4CA62B8A8DCB85176694848E8825B27C598363456889ACF8824" + + "52B242CF82007D6CE028DE61D68544EBD09CB571480DBE3666E43F207427D137DD99582CBFC64AB3" + + "74E410FCE17944B8A732E99A26F0DDF564FDEE71F33DC41B815E4A409017073686D8C8599FDD0DE7" + + "EACE83FBE9EF2DB74854715AF0DCE520BCEAB6C3415F4856E9B581BF8EB84658C26C418C150A95CE" + + "6568C6196481AF2296DA3593569D1B785D522E17945F125205F9EB675CEAFA334ECF6424C14D0792" + + "D46411AA3D9828077E46AE4802B5BAF4BA895D256AD3405528717FFB4E08B0B746E016B31400EBD6" + + "D086A290ADEEA8C225DEBD2CC72DD8A6980315272A9EDC1A02470CF7A19ACE4E472284B37987FC32" + + "51AA7DAFC109D18D662900267064DDC22239F47B3D7615549B0E48BC8365C0E4A779E1E4A8A79B7F" + + "42749F7A10A715ABD21D6D02B5F33F1064BEE0BFC7408B06DE8F9E191D540CA8F8758E817465742C" + + "D5B8163FCA9DE2FA1AEDDD2E9A06AD0D714ED9F5D1016ABBAE537203B5274900F10D78E118C97B34" + + "7BCB16B3E5B353635AF25B33BD5974890EA0A9E46E1FFF1FF77B53C95D543DEB443E647C6AF34DEC" + + "BD37CCD9D1473D3E72C76929DDCF9B7D7659203BC291B40787A94C34B00A5A9149951F4D72640762" + + "45327E224A2FBE3022609F832E04B66E1015EABBD39684C6A2E7A01C553FFA43D540FEAE5FD1AC13" + + "F77F720AE46698FD4ADCADC3C0533A40FA5B28469B52CCD046AB67C010CBEB0775491EE261809479" + + "DF853444EB1001D9557958A0E812F65956B8AC6D55B7ADB89FC46153AEF3459FEAA7B72CC67963E3" + + "C8C6ECC7E2215C8B7830ADFBABFEE7094EA1DE4912942DF7F3E6C96F7898CD3BDC78D548BE6C86EE" + + "F6B8D8CA934EC650685C018201E7E3FA20278989A2E69C7F4B95CDBF4AECEB5A8A5C1FEDD4764938" + + "C1B1E27166D4550434C2B1FACF8836115D865ABAA90CD057D5E0BED7F015889C33DFC4217B809CB1" + + "26E9F5D81571C589D09C00E24EAF72BB353D9C25E5D0F1F4DCAF74AF48A484D97FD91FD36C98EAC4" + + "F8EC6C773C5143194BA3BA79CF9EF4ECB3ECCFABD91AB002AE815DDC9FB6B2DF2D16DDFBA704C564" + + "ADAE84AFF9BBE92CC2B50A2E363EF43323EC949AAB7FDB47415DDCE7A4DFD1E1978374699B6AA911" + + "85056FAF7B9E05BF3BFFEDC39901B35D54E7BCE57938CC2D66DCC871FF4F15204CD68B295D96E824" + + "A8D6B9DCA456D83B3629BD77911D66EFF0E45A09EF0EDF33052EA8FE4C2CD45C3E95F184883A2097" + + "703F5BBA0AD3AAC10BA9C9A9C1781C26031828F5ABFED261FA4F1CA72220E895D03F453A507AF0B5" + + "16E155C911FBBA9B9397E3DACBD8226E8C90899526BC09BBB0FBAAACD24DAF1BE128CF8FB6CEFF15" + + "76E2B1654B1C77B748F86F2F6AFEF5D8911E51F82EDE2C0CD7F4E4FB6D9302236B3405D3D54FE840" + + "6C1A479202AA956679A8A3063E771B2C239FC6D7140A2993DE6225A542B4F12077A23BF3C1BB27D6" + + "BB3E17B6D3CAE9B2BBEAE35FD9461FC7151B6B8E78F517CBD03BF9F14FFC093FD292FEC3C3E0CC30" + + "DABE714FC289FD4212A5171E0D28BCCCB62A86C8057B020B5AE824581270ADC34CF298F7D3BC9895" + + "277C3CDCE821EACD41188DD483BBAAABE4D1F5E7DE1733C3625E5DD37989997A98CA3D4D32C2FAB8" + + "D0B6E2BB018697ACE0FB1CE289C265B39270A3582DEC02C85A245D9177F4FDFE2AC9D14C166127A0" + + "8B0D97179594C81F86F3ACFBF4566DF5FEFD9C460822C13DA2E38470D4C4091AB683710E0478E335" + + "5063B2ACBED8D712A0C38FDCA47B4977C64E22ADDF4B2823FBB91EEA85A5984E2C7F6B8BDB12DC2B" + + "F3753558C385E8C065EA0130B78F734C1FE30F734D44B724F3C7D7212B3BB08D2CF33D490FEDEE2E" + + "F9DAB3449C2092178BD9F7600391D4315290DC23CB0820334627DD73D4BA92C7821E9A2477C1C76D" + + "2F26DBD356F24B59F0D1B388A943940CEF5A1D623B223939554CA2B9517737592FC1D608F4017AAE" + + "AF54E60FB6C7691595C9A10899CB7C5BCCC4C70AB0F195413447373D50F61846F38FF583FF56FE98" + + "AB626F8AE41FBF90EAA9E597298582BE1153D85922AD62D108135E2FC79599A2BFC75D6AB966E915" + + "6D2F74D342EA644CE3CB066E8E38832086A495F5D8D98FED93FC81BD1BC99A76B787A9C978FBE82A" + + "13D485A331733746E8FDA46EF50AF951B2FA9D815D68D447DDC840AC2F5930E255A777F90582A70C" + + "BCC62B26ADE1A6A5BE291A13E3F1F5168143CDA5BD77B364ABF852ACB5E71486C6A014EEC99DB688" + + "8FBA8B27B280FB28FE598ED1BC1C5F14AFC94ADF8C7FF63C25BF84B415CED46DF905825649F07AE3" + + "16045426BB7191C27BCC98CB6601BEDFDDB6414BB9D152A16604096BDD50949FE7A04D811C8B354F" + + "7D9EE1999854D0ABC5482F6E1D9AB7B56A1336FEE0DCFD3130749CD231D3E6C99E600CEB86CCEB3A" + + "EC3BF55979F5850483793B22EBE26E9AEB0BE63FE0371183FA2BAB83D57EC5140B9A0B952BCDFD4D" + + "6B05F69BAB51338C2F03F6C4BCE4DD2F7EEB1CC0072DFDF9DDA85FED0A09F7A6A81AD147D9154A7B" + + "3328C88BD9EDD2E67C9471D67F6AE25BCF66C9A3DB4A41A341F46301E5EBBF92D522FA6131045881" + + "0A4E38095A31AAEFB6A84359C3A54B48B5BAD1A72570D03B136EECC55678AE34B200A4E5934C3785" + + "5EEAB371DD6B4024BF05E814D087115DBE3CF0D8057CE6CE12F90423552BE51843C5E14F62C36F79" + + "98E7DB248FA3C0D7C0D02E7A23AC8F2CAD0375F1B2A59DB4B462A5EDE8C8B85F0705EE0B8FCB231E" + + "61B62B2C7B7F0836F463AC6E0187BA9B2ECD70A568DB84003EBA9159C9AF6B325188DB2112FC31BA" + + "A0393F89DD73834F11EF86B15257C6E1CE2D780F4DAC6C533402547AA5DFD8B4ADB6CC37E0D88484" + + "6698115D152D5EC008C2504ED31695BE368FCB5F4F2812F92A6104A665FD5B169D03731D12F552BA" + + "23BEBD0E11EB53E3E7742159809683E8DA227DD3A519F31D847E92629E6FCF4AC5022D28F72329FD" + + "68F856FD9D94846F495959B5C726848C071A7FDB61CD84DD879179458183283F5810990582EE0CE3" + + "A08D94D9E3E7BB842C600B1A759DA04A9391B925211A484D5BC5708D01944CDDF9469FF453357927" + + "51D2F95DF17D6DB27B09B9ABE9E373C84F10907940A3EA70D6217BD20D6EA0703268496E9DCA6293" + + "3872D468D1953D31EEE18260DB9475BD909DF3526058022BEE65CDBEF699C09E2825AF221313F145" + + "9EE2DE4C0491FA4FD033B425B8E892FA136462CE626B6B1CC45CA9C83BD95D1D3B1A6A7B6C82576A" + + "C9D804169EE72F21C5BE250F78EE94FAD12870A021292F9F7693C435B4D5A3BBCEBE2EAF7912B81A" + + "F4AB349DC053914D0679CF3D3DCF6A807F75B58287725D33BF217FA149DAE915ECF56EABBD009188" + + "19E1BFBC2A6E22233CACAE6F86F02F797CD2315540DAC191699749DDE2B33495588A5278429AB782" + + "D414BFECD68BFE0BC43E9A8625103925BFBCD06AD5517870E9F96D0F5618F2D49FDB54D0EE06F3FE" + + "4675E0650A672E9759604D7A3567C92584175ECDA0831DB993964F0862B62C333FA8079653C02A7A" + + "1D4E5BA9848B37382478661EE6797A52CF4A8E316C8ABCE6B5B60967A88884B7182926479FCE7B6B" + + "8AD8095D062F6BA5AC55CA920F980F5FF86DAA5F84285E66730541D4A6DEC03FDFAA6D42B74335DC" + + "C33496A043E076D2408E425F7C7A9041011673B7D29B8E976BD189A32AE402CB67FBABD16EF92977" + + "189E4717512F1F9F00D6AD5DCA689B46DEA041FF2CA018406A1DE759DB717E180A4EF8742B3DEF6E" + + "4A35E884508DC54471369F3FA49B517F21FC764E70584A293F8DD0036126781743B74E9291157537" + + "F06C76BF2450F995B26CC6BB9A4FA8C7F7DA7DD2A6200AF80185805D7983051E0542F843D8F542AD" + + "61EA8C5E60A887DE5B0CC375AE5BEA13D2F10AF490EEAF2DD2F8461CCFDAB667DDD51F8FC8967A6D" + + "78E6A20BB5EF8906489A00285675903A17E4AF5EAB2DED4A177AA7613F64C6B335F4787F1CEFF942" + + "EEB5DDCC4B7DBD74C3B0435FCF27B880B0B425AD4E1DB1FB82DC74879F4FBC52CDD27B53C3BB2500" + + "CD9D8AC70944FD2F3730C909E145A130D4D6C7529F994D65996113E86882FA5AF08D24F450ED3129" + + "2D78E6F202F2E3CE5EF4AFAE18BC7E53F783409CB0109A279D80149DBF9C601824D3252CD097D64B" + + "F1D628815DE34B0B455C5D778DC0C82A2D4C556B7093A2D4E710144C6E8DA5B1F50B4174F8050B6D" + + "77F1000000000000000000000000000000000000000000070B11191D22", + hashAlgOid: "2.16.840.1.101.3.4.2.10"), + new MLDsaNistTestCase( + nistTestCaseId: 54, + algorithm: MLDsaAlgorithm.MLDsa65, + shouldPass: false, // SHAKE128 does not meet lambda requirement of HashML-DSA-65. + publicKeyHex: + "D8D1170517D75DB90659838E13D45E98ED20D1961D98AEC16D2F10C51DF289E7FC4ED97D52166C8C" + + "913E7CE9D2CA02AFD7791B95E8F2919F7487F9F1C6B0FE2133E2227FC405FD890DEE8C1B79114C32" + + "9A7C3DD341D137810B67C84E9DF50BB9EF45C267F36432C371F19ED69A2127F1A7FB02DB0DF8678D" + + "48EAF99196DF46BD1A2BF5A0F44BC091DCDE4B9D9FD93987AF0842FC74A7F8D8D89715909FCB2A85" + + "0655DA6B6D93F5F1323C1B6E66340DB8C64874E2D8CDE17393FF26E575FCA7CC7D032F40D4D74C92" + + "D6BEABC726ECCE599F85EC9406DF76EEBB0A4170B3F846021A287E174DA6BF729993F093A894372E" + + "3A4128D7A258D0B48E5B5C5A9782CE1798FEEC2D93D3FA6CC96719B6213D862CCB614DC302D1BDAD" + + "C00D411FC033F351569EEEB15624BBFF1D2839AC7A9EBAACE2D2B3FE33D96575AB75485A82EBC98C" + + "42664E0B342E800107E02EE9C3F3F32C43AE35EC2CAF6E6D19F3E1FFB92724471E503E08656C0C9B" + + "F748F53A4EAD3995E8D2C612F77E07C2BDC47E40FD6535020C4697EF89E4DFB8AEC763EB426AA672" + + "65D3B675431D1530628A43420891492870328432577F7EA98EC81ECDD5985FB5040E85F167DCB42B" + + "D7B90717826D289B22C200FB429EDCA53963A50CAA6854296C85E08B28ED2C3486E4A73ACFE47079" + + "0093B022E08E773C6A45C7A1059530CB20F8A351EB64A9130DD520B318F356D3F2A7202B44E4CA3E" + + "3C6188BAD5F4651403E3BBB144D6A126F2D1BAB9DE7A0E3088AD0EABC5A80DB3C12214F32613E081" + + "434CD82705DF56E31EADE0641F8DFCC1340E30AEC50A8FECA999FA371F2BAE7123C271CD69F03DCC" + + "827678CA18619F10BB2775AE6E1C98075E6190B0726CA980834B799F5817428EDD952E5B78D8350E" + + "3A04ECCA5DD00BAB8D5A4E028E1782B90B2789CFFC34B2F69120B8C74DFB3501EC6B7E5B2F33170F" + + "6CE1AD03FE6E4D3FF205A6537FB27845C24FD0B7BC988C0D264B873599D10316C72656654C2A155A" + + "91B831942F7E9C6146843FCDB07642287787297A93AD322E601E92C3793885E3109BA9F578CFD449" + + "D796B68276BD91B28FDBD442DCB65E330C95FEEA49CDDD5CFF8BA7042C571DEED98FE569EB584BAE" + + "F5A535175C55EDBC00B73B43369F9916EAD907E012027E3E2301D9D3999365B1822C0BFB007DFFD9" + + "F94900AA5D6269EB65CBC93095B6D6E42D62DDABABBCA0651981BA7FB77F8FDA1F953B7EE04DA90C" + + "43460F9D99E0D407EFBCC16E2294209794624FE7DC589E1ED2CDBD23FACDE396E569863C23A21CD6" + + "BDD4B14F716AB0B33419E54ABACB50273B3952EE226AEDE6461FEFFF01B4B532FE2382D7444974DC" + + "C3BD86167C0B62788DB741B446F9928B06EE26CBB66BB7886EAAECE5EE4525AE44201F5D962AB674" + + "4811192491901879BBECD24CCD96320FB63E47A7F1B1F8F8596054912F67658C9FD1B2D9DAC54244" + + "90072BE75BB90F677D155B997854FD23C25373998B6EE4E6577CD0191640F583C510B4F3A16293D3" + + "B6A7F23398DAF50C822E13E27BC6C119C89D7ECBC3FBE41EA8D50FC664D9795F2FAA3A5E37C72092" + + "602A34903A02C02E8E14B99CE045C07DB648AB5F88096B5FCC318E5DFE912B2ED3E46CEB9B56EB61" + + "9C5F418DF303B87E6FC0EEABF6529479901849FDFA88D5403E287ED1A837618EB4EB91D850739177" + + "595F9CA0FF76D7038CB80187178A0BC6228E7CB10883EF4E06F2DDDA6AA9DC2C517588E82065C161" + + "0C73E2F745899131A6CC0ECE27A37AFEACFCCFB10D5BA7DCFA570EA9B970B7CC154298C2BC8402FF" + + "A281F9BC8E0E8386DD9B639F62FC81C6FF96DC72AE8BC0B31806F2DC0E956CA666283C4BD55E9733" + + "9F1D05EF5E03D84B1B02A1CE434BE9E674E69FC2446123859A8F1D8EAB672D44C014EA5DD8840CB2" + + "69284F2CF832DEE4A3F5CAF5F0A27889C65BAFB922023E9CBA1A322EF382CE54EA3C005C1C406A3B" + + "D19F4B174AF0F40E938664CAB0ED4597953FC843DEFC9E273E91361DFBA69768A5C1DB721FCF0695" + + "97209E75B5ECEE51B75381DBDE8DBEF3778B422AE68AD04A6E5AD27E157FA425859C26EFEB28F412" + + "B3BC56A4F7574431A5FA4999E7656D80FAE32D47C63C530F0B8368281C1D37E9F53E3BC56F66B4F0" + + "77ACC0D816C48414CA37FA30440849A6C0ED59FF917436B678A1CD8C0503155144C96DAE1C74E883" + + "2B5AB171C990FB51C77849174B27A362447FE90C368A1734DB076D73EE040EAF9A883AC9021A9B2E" + + "3DCE6D3961473C03BAE6184CF067BA8152D41F61D9B2EA1C92282585F6ED314E19BD1A30734AA39B" + + "695CD82EE1CBC9CB2456CE414AD8B4B7BCBD6F0DFA0EF4F3C40E9D1CFED52389A82A6AA2463ACD73" + + "51A59FA69D31A4F9FF4199800EA6D3DAD06C59D2C2F8CC45488FFDE4811D8948C00E5CB0086E2B87" + + "55ED5D1EB730F552BA814A3644C79D408D302C6E8ED41AFD0BCDEB170EE6F4159C2ADD1623B84753" + + "F91A3E52E3C4BD63BE63FAFC2E12938B32332AAF7DA8D8D4CFB66296738C5C5A99E31A6F09910470" + + "E1F989E396112746672C8150D5FFD44164191967549A9D5A3CEC1C29FE7B6A6C74A261CA93A461A4" + + "C005B461FC4B0E529C6A4D70FE43B9B6F18856EBCB4E75143C7B53ADDC1128BEAAB1BE86A991FA0E" + + "075EF10989F7F93436274086C054DD92F2833132E4F6B73B279C36D88282C38B9FE6A643BBD056FB" + + "AF35E2E86E3080278BEC572C6F8D0110A83883D0869F71A3BEAB9BE9DED19310", + privateKeyHex: + "D8D1170517D75DB90659838E13D45E98ED20D1961D98AEC16D2F10C51DF289E7D87A9837F3D23E5F" + + "A8F2FC061D482317B190FDAE090A90E2DD24E47F08D32AE02B5DF93C6D2AB9241CBB66A0182A7456" + + "19869EBCA9F62391AFDD4F05883AB7A13780469CB9A79900D579A51026389789E2D652FD9E87F078" + + "B93B6FCD089F01757246336823472484508102701722278723310125787350541442753233403202" + + "54506422128241104410687661532405227363472078720852341550223800371825041500122803" + + "44505064461540307650585802086558834554575437274862300143425107285544612767111275" + + "53505345175884245550104417526730543838826266228246713332005583625500855618555421" + + "66753562840173366600121651418340086333613230317121166663205001767744532650255840" + + "26554282871044241656010082614285510417118768343068417152005745055048251504548366" + + "68870680083483622830538262045784317667380183870131337327777324226162604787425258" + + "11840370372485760673370362440772222723070872644406872662213055558750878263562545" + + "16227733084054645636357058464375167035833628433301260583303336224040815830073646" + + "56606412684014148321582574862672737052810331374520358866617734554673521374132764" + + "85814037772337560466645424212021005581064368241123332200888543300715416242535605" + + "77634710381137288335344084881540522557112605437583041611506646820164236686748706" + + "67780620483216187133648843542644015221123211060514001337046208718113463465012450" + + "52782308810511004864380102407113154628434723044542074031237786885376645306857706" + + "72205737588746600575280337512440204235775310645128028028281116372713340485654045" + + "65666803241865245170186025206082513888023807163650441681370786724845777648247063" + + "64327447466625051066434755605172060614125885166378108253150545808134620443262585" + + "46073167773718263073587676063424727415018661262808351882028641457522658876442747" + + "06642676054864717611565247158258404145188331362288477174110551068881671781676881" + + "86242872818833055561312536557065501826783684447482042156527674243508127030256083" + + "10684451177046566525468256018436757557077540570204801651205700266877715380146242" + + "27456865280777805223863575056846544471250810512374245063767578456618254814131371" + + "42448837507686585411574363073788231186221517141208774525657558554642813550785847" + + "06656310542154841227655848778328740284614723605147172483432234684113235634270825" + + "61224016287133233602707682807066364008540784431478154631024535325223781742386858" + + "12280374288654568023161724437338653037227685205055076422425020533278411228548000" + + "72370512377587843372816025414715157702408276631556713464647704371572401265458068" + + "20267238783818711653655603640588835166121223657362553241618472055788100731518654" + + "66818186771184372426362678387554006037321483733400651487548414232712758854200606" + + "47708046830675658022617585818056210467165323481138518512011438057118333132724006" + + "02123536037844558381477153083312688710560377160078402544822770303686101746142261" + + "05282430134107420016417363820051553018635684754121268748333216637661081285805487" + + "52680162247183627068740307343176608024013767328503508740151380731356374153515372" + + "84045035421803714234526124415737764234844518835454864446775825331368372445343344" + + "40236220220834017702184873733641621823368306573076461714312461267188320786564040" + + "1541235047834600215850605561176161CE0713693CA21944A2178683E9A301A006131B719A7D0C" + + "465F915141E86B2547398A1731DF00755E6D39F0D43CA0B78EED1F21823A8313464DE41295A1A49F" + + "A4C18CB6FA21C88FB4ABB5195721E21BDB8A746EC5CCB7DC2A49EF6F712110000BBAC61F2B59FE78" + + "66A04DD68140C040901CE65E447C8BD04B1743CC342F5CAC9B91ACBD76F5D9BDBA36FBC003A81AFC" + + "4A37307A9AAC181064CAD0A27901C63A64E1993266AC96702A65FAB2A1C01FC6290D247C3504962F" + + "334547C2CCAC18A1EA08C6E110ECCA2A58E01AFB1A872A7F1CEF5ACEB55FB1CB930DB5211EF6EBE0" + + "74E40C47670B7FB3BC362A13150F9449881D21F450DE11165013D32C1BD8463CBD2D338F8B6161F2" + + "9CBCA3C9BCFF7826386749D6CB1294E7D09001FC56BF70922BEEE8CF1355AB098E471F2338FBD6E4" + + "11B4BE28996380B741D8CDC1BB3666DE9C50DF9E6E2E57DD17E5E18893BB002D582DA721068B07BF" + + "7A135EDD6CBEF0E920FAD8DC20214BD7A088680260FEFC64B1338C36353ECB59D304F24EA27C1BFA" + + "DA2D97991FBD59F869B98D8D2E9F66E465C370B0FCF02242CF759BE075A0B02A6CA6D4534297FF5F" + + "B6CDE68C0E23EC0F6B6538FF6A568E36F13F8345B0647BE5BF61436192288F87C2C790DD7200DCEE" + + "4793339A6AE8BEB1DCCB55E01C3D12149CD283C12713F8238E277F31D76B8AAA23F7DD152044B6E5" + + "6A12DE47B2B0AED5088943D895BC1EFD6B370CECAACBA126293608446E75981108252E5BD0C476E5" + + "D6B6AC0761ABA0107A92C59AF89A704E544B1D9556B34B5619410DFDC84A058EE3701A1E29238B20" + + "9840DE96B032B7B510434CFD84CB10930B484115A0A9D55D6C3F82B7D71DB8666E8321052F1A3ABE" + + "6BFE9EFF900E370242B15A22A3CFA2A1F723077D553D0412F6EB762CE9D70F6922FF9FC76D6F7EA5" + + "CCCAC689BF652166FF781940F570A337F0BAC84A8D11C87AC0DB5CD6BAB8FE68F1B0358486E97CE5" + + "2BF4429F00B80D94119198DF385CD03725EDAE8FBA1CC29712BB7C79DD33941AF05C383A6B340A76" + + "A4BE1F5D92FACF2EAFE4BED7A59ECF7595B8ABA0211E6F509A44E34DE5E0F8E8424483CE6E99D840" + + "324501002E47E0D56D23C522E57BA4C8C21CC2E7865BE3BA0941EE08B120816493C5FD84DC157E9E" + + "8A0775D74AA56C7736C9079D96DD8E4F1651FE26B4AA0A7C89C14AD6ADF4995AC6426427BE4383A3" + + "F471D69F1D4CC0DDEA62FB097261934A38B15C4A87E06E2DCE0273677AF54CD07C96D66A31CDAC67" + + "4B23F168361D64AE4F7100ACEDE2E993471A589199002FB43B7F32142BC7D10525E9F6B0B07DC967" + + "5BB6274FE9CE4AF49EE5FC65CA8B5FE1776622CE4395D073CE0AD0D0D589EFCDDD5FA6C8438B3FF8" + + "90A16B4EC23E00F2642E6F85F387D4F57FE84397CD4361727854AD4E403C168CF225EC2A478EC94C" + + "5B7D08F8274F491F0F67850C11A76F59A224C62FE183A63E3624C5245A1B2E80DD7026568392FFF4" + + "A192A33851344783DDB85060675E63E5A66C3329BC4ABB8C9844F82D8D2D64FF83BD9ABA3B966389" + + "5F50AF97546B5A86548D24DF95C9C4C496A23209DD9525B0F17095C4B4EED648B9D639D569EA6E7D" + + "F66CD386CC8B54D60AF4BF0C8C215E8FF0A73D86B2B2A9443643243C6AF3E1B0749CF572DD0E2F00" + + "7F1B3646451F423DA79178B0E7EFB7BF55B9DD7B0B1D04852CBACC20CD05D7DA6A0F6D56D650DBDB" + + "2DCB3F4D97C13B9E430F5101F646DD4DD4BA843843AA4D3062FA7A8551E7B51720056C8117ECFCF5" + + "2473137D16DCBB389308BE07A497402C15F92A6F88045D7426117AA4E871D2AD75AF1C0CA3AFEA81" + + "38263B7C30AE1814836F06A63033F2940249F004D41EF013DBF0EA3DFEBE48C1EBB76EC4674B01B7" + + "221CC581384D183AD6FC285597607CA0194AF84FB8468A58E23A96A226F238B5FA9813F5F50DE473" + + "EDDE1FB74206AAC695402AF9221CA47AE922FC1E8CDF5AD538EBDF33119263FD7A5FA36159454278" + + "ED772715B3C7CFD325707324542D62BE36023F565BA822125A6FE8EAC0A664923D0D696C875CF409" + + "9772A8DAD71E0FDD07F635B667906BB5D66A554184B43654AFCE82DC3ABBEF6811B7C5689E6B5734" + + "4E800B117C8EBB00B0EB75DFE1601BFAF3C1123203C130D7CF6B8EFDA3873AA3081F784D104D96E1" + + "3C243EA0ED0AEB17155387CDEC1ABB71C8177ECAB7C5E97B2239FDDC650942BB28AD16E181EE9763" + + "CB67FF1482742D0B0770DE130C491CD3DC6F814E68C727D11BF9A7CD4C92915F0530175F9E6BBFEC" + + "D2D0F2790A0877F3143E7C2B62CA13B6695A5A50ACDE961B06C392CBC5C501290579FA8A03BA22DA" + + "D7FFC0F8E2EDC1AB6826305B72C77709592E88134C0C685EF4ADA192370E2A42178B682953D8CA0B" + + "4CD06FF5953134A47C180482DBEFED1BA32B5CDFFA8C2C1FC185E7F9CB4BCFD83045C1243F981960" + + "6A8A0FA359DFEB64E20CDA7599E50E8E7ABFCEB29F6A9154ADB4287B2327B7C200D9B7D7A9E2ABD9" + + "AADBE10EBAE2AAC66DA2A95221C206777266A72D85FE2FA685B6AD49F93BA9DB3DA026E13B7E7126" + + "914F4BB7DC50EBAE14DA262E8922979ACC7463A10C19BD09D0AE70CF57AB0876D67A3852D91F35E4" + + "9B44AAB0F8949471506415B13BA28F7CD14273965EEC785935A7D15A82FC8B810A19A0B95463B564" + + "6A3A442E5ED6B7D73A9F46D80E93D6E05DB01B9FE583A46D22D5565B405E55EFDE09A876D8E9BF3B" + + "C212640BA102EEA73B5C78DB407F708D7F690F4333B876D4AF47013348CE5ADCEDE5F056E32759E1" + + "9355EEFF94CD3A1DACD9CCB11736A1325D1B4FD6A4B227A9D7E4E2F046462659AE639B33F1606080" + + "6B33B54E02978FB67F87CB8359E74AAE2BA5F232276828F4DEC027CEB80487016DA0D343EB73C001" + + "4FA874D02808A88E514D4B2E1EB9253402F862C9BF9EED7E640D32E3CA8BB00CB5232DB1FF082577" + + "EC567D0A7E14721A8034A69CBC2AF4735A94191F2E41C46B59CDD626AABE7FFC9C1989D3FC7EE7B1" + + "F1ACB6F44877109AC320CE800E8DBF395A9879911E88ABC4B8FBAF64C248CDD1C4B40DF86DEBBC13" + + "4C7C3CDF897B50E63C9A2BBA8ECCF2C72B80B907570D17B908D57B7DD1ED60A9781F02BF515199F2" + + "27583B96FEA864F13BE0F1D95B65571AF9930B4BCD74D0A0B04A7A7E7FD957B772CAEE40B6F4EAED" + + "4856E7FA5739B56E0B8AD7B8AA0EF456E73BA2972A032F944ECE48912BD0FD7DE8CE7CD7FC31B89D" + + "9C0E321952E2886101571B0A4E80BBC0A614FA505A1B66BF21BFE4BC1BED7D128413CBB4882188FD" + + "5418B54F797E391266469081315EA0C4D2719088F9107EC93BC4F0F0F491C7E2A5891B7ADABAD07B" + + "85095EBA160C742F5352C23B9C4C49AF6161C56EBC1FC5B7A022957AC4BE8C5145D57709C5B99C27" + + "FAB42831BDF29854CED09B92C173FA50EA4552A17F4F778DD6FB5F2194C7BAB93683C3FBA6D97EA3" + + "1D6D3568233DB53A695C6548325E3B2E83AD3CD91F250F92311B62DC7E499407", + messageHex: + "4EEE5C11A84AC5C25154DCD48494A89D61061EA10044892355D2D4A8C90077D1BBD07F03608B0817" + + "7A37E37A11D807E45D39D59A1E9D96CEF2BD9DB1613FFA34CEEEAC8B7806D637A03C3E97127BE0F2" + + "8436E8C43445BF675CF80A37C2A954B8CEF5F5F1CA8B1A45FD0ADFDD05F2C7FCF45F5BB6F8C82AC4" + + "DF7617934CD341801A4389DA77D451DFECE08C5E0A9FDE738C560B042A6FFC57D06DC61C6B062589" + + "68EA7DE3665352FF648525F420FA31A592829A715DAA6A9827EF2DCAD3B66511D5AD583B4570F626" + + "C868AF95072347FD3799D2D018FA36C125C2545C791A68131A2C1868F7693F6553B26C946C905A7B" + + "4CA7E43BCA803DED1550A584D649D834FD1B25619F94A51CD59D5155E84C12CB472AA6524F652F40" + + "8EB7FC9D851502A40755E07F5BA2A5F3F933A1FAC0CBA512ED2A9AD8EEE08ADE9B810444889E4F77" + + "9712218E5E00F6E1039532D943CAC192FC853BD58C99B729E33F7F5184A8892C0DE5C4825EA29729" + + "002672A50A6E1D1AD388ED11CB5D5C5B957F30F52AF608753B3C4761E5951AEA960732E9F54CA913" + + "35AA488D1EC4695546AA17788C2E30331067F2B38252C41B150CD534B2A206ADF8BC245B2918DD2D" + + "F0C9B3AAB030F66C3BE58CFBF9A1D0590572A6FBF1591FF954C8A8839A6C189C63EB5452ABCA8EBB" + + "07C78ED19C5B75A040BEC742B54118441C5F743EEBFE33CAB628576F421117CCB45B3C0A9E3B59C9" + + "079482CD36CFC5BA5A9664C396421644D12C0DF5247D35C28CFE117AFB73DB81220B81024305F6C3" + + "1E7BEC77D3A3CAC6D5387E79BD7BD48996C5D22D92E436470E37666109EC7D4FA6CA71F906CB875E" + + "2BA45E32BBE9B8896D8AEEC0549D8E9075F3425B02F66A336B396375044214848527CA2174AB3A50" + + "926957731FE8890A40763B1A4F0C86F5C5D2DEF53A4BF2C5FE0EA8DDA7CE06B00D926789EC300649" + + "2F9EC1F70712922D0572EF7A5C48E2FAF244A42631B8A8016D422DE13A8C68B54D3B3D1D46E509A3" + + "34DA9650D074F33A74A21554E554846DBB08DD10B5C7079BC2C0EF5082569D0898897BB625640A4B" + + "52E3A942282A753C8BC074E3EDA12CAF90BBB4DABF461E1DE43D7F5B91102D2FECCBB1E277985776" + + "9AAE96A074824517E40CC65393F61604C520DA7FA110EB2161E86633B911BC570E47D0D64AE33DBF" + + "BD206B7D318F1752FE6AF433EF66BE6B85E084B14202375089F8E2AB48156FBA54CAE65F7C7102E6" + + "9AA835F162464FF1F319ECBA9E918AA380E7EE3475B2FB345C577A3F57B285719B2343CDA5B83878" + + "2C575D434ACB11CE0A3D1201E29D09DD75DBA99BBE7C48515D3685B05F95E092E9D1D17F8F700F05" + + "F238BCA003E2A720D3A362864A2249FED6EDB459D00306C7DD15E48ABEDC80D861F4BD087B1F3E12" + + "9056B3665DBEA7CE5C8F5B104971F9AF4137BF41F537768709C045F2F0A58E32FDFECBCAB247FE9D" + + "57D9C235638A98A6E6ADAE09523C105B2066AE5B5CFEA81EC4BF9AE218E05DEF41127D059397EDB8" + + "1BA1F199C453F298E0E4AB103740AFD5DF55CC5142B448D846725D44D4F140CB76E59C0BD3877491" + + "11DD9761B8A4619E5652F6D363649DB8ADC52038E50476774563B498DE0627D62930B5DF6CF59D67" + + "AB42494A68852F2B7E7A12FB5D9EC2C7BD0456560B0CE0A09D5F59938F1B33BFC17ED6A7CB337B9C" + + "BAC0A5BFA6C53582C445FBA0B55EE681EA147EE421E9EB233AB9C19320860CB9A40CB5F28ECAB51C" + + "447B7D7A3F6D798211F72ED8EC20A86FB2338A5BE179FD41C03B0D2FE1F87918ED6B04CA599E57C5" + + "15A20D1EC8CCF4B13B96EA07E3A2874945D71897328E251F16F7A5E0D1E4069D3B6EFE68C24319D8" + + "D240BD06178F10924BD6AE5F3B9333130BD062E1A5C6F2F99D0197F435D21FF437542A66A231EF78" + + "D94AA6C4DDA39FD262333BE237502DFCA660370608EADDF29B8C03DA66964747B29A32D2C29859D5" + + "089FDE12C5BB803B2E90FCEA78A1130B1D695D3679A7724146019DB88B5C8DA24AB0A81BF5FB5CF8" + + "C37C82D8D78D485052BD2F503BA485B0BBD40D21B343B8B169D378C1F266C94CB998DBFF582D1554" + + "2351FC430DF675C2729B81BF4815919E7CDA05ECE26CA24F003C46B166F84B3C93563744E1348B6E" + + "BF5A2D94B5CA89FF4A41F7A46AA8AA5A96DD779965351C9F303689D115DBDF737E6F958CC6382D78" + + "D5ABE683987B731C274D20C1A70ADE54E6F4CDE2425FAB30C58F20DDC5D1A8B69F1EA4438A0394FD" + + "19CB30C10CA5029E4D5A5E6FEECC967AEF71872C798CE8580E2C66A9A92CAF4563BBAED9D99AA14C" + + "BB996AAD29B7E206C84D703949F8B9C8A4095BAEF1BE38B8078826D1D25FC75FAAD02432558C616A" + + "DA5868E1E4B7CD898C8138A1FA4C1DE0CBBF3A8B21BC5E312F55F017824549DDAA56FA0F9F037841" + + "14488E3190F7B49BE7A6789E690CC0D56807E55DF9E2D21AB3C998AEE80587435EA498E292C63814" + + "B2E9F95460FDA64304E3142647D7E6AD2A20F8C90B6685E1FAD99C1050C5B87C2E2C34DF8FFC3BAB" + + "92A4156DE6821CFAB4E9A84A436740E6C989509CA839E71A50FBA863D29A96D26B3B304C4C4E6A4B" + + "75444937DF0878D790067925CFA6E7C3F062BC51CD923FFE208753BB3ED1EC42AE1F4290FDD87C0C" + + "4C76F61198B65ABFF76F1D3991196BB8D4460F5C15C44D861712DC2965DF330E9B4D6A384A144430" + + "E469808C5704558B49A86F30E6185AB6AF4025DDE73E2878FB753DE6A4B4604477F6756F7BFCC63D" + + "EFC3688E572F83D9340FEDAA58BB2659D9FC891D42444FB136C75F6AF28EC59CEA7E990D98017485" + + "93802BF466970BD66067FE4199B1BC89D1008FCCB416595F035341639287C0D73D23CFFECD20B2C6" + + "9314814BEDC9F02CE22B9458D8B2A8627EF915185D9EEAE1B2EB0A8ADE9EB46658687E5C79D85918" + + "6C9F027D6873C348ADAD9D82870A2E1170FA2447E15CCBE4A8FDCB9CFA55101C7C9C238CAF5BDBD7" + + "33ECE6AA835D64240478B289F4D5B58F2BB1D8444AF634945720E0EB2F33892383181C97ECF79681" + + "4216922FE9683C5C8853C0397F5FEF4F83D3A11ADEA63B96A79CF131313DE2EBEB57A43A46B867F9" + + "3ABE926ACA31BF744A4ED4CEE382D9E650D8E75161771B1ABD8A6B3FD4399E58A1849CB88D8B6F8F" + + "ED53A94D58A07656967874E410087ED77720F639C1ADC8F39B2C6F59D9705FC4BCF859E04E923AB4" + + "C42CEC9C2D3A8410DE7528EC502B884734F8DF93553A838315A11E95195D4C9F0C476549F4FCEB7B" + + "BFC4935CF37466DA8E733D9B3147FB2976E19818B544D472D21B61B60616BA719311DA5064FA64AD" + + "BAD3DAEECF1EBB6DFD6C60AF6E7F8C9A15F757572220AE68620CBAEDB5F995D790069741DFEA692A" + + "7383D6B57F1C7E4DFE904AF9D2F4B45215BAD838482EF0D421E0CCECCD8B2B5FF1294CD672C4233A" + + "45031BA6CEB7B75DF365CC0B495B53BF594979A357C4511A3718B08A51A8B7E2C522949CEE4A1D9A" + + "8324B11EA56278A2B39E7E29A6E85DD99F0AF1EB513B81A483726DC2FD075ED872208BB59EF12428" + + "0402C5D34C3A5433E491A44D2390BA0FD94F0FC98B7CA47971CB64FB1C426B4457147C0C4A5AF393" + + "3CF83FA281D0A4D61BA7F709357B3D800F102D40CD902C2334251DC767D6B7D0594545C8FDB48A9F" + + "0C328C48669F6A74DCE3E3012B4DD881C13C560B70B009A8F05DA9A0F01963F212598EA612ED608A" + + "318D77707EA72E02E536E160A69CF99AD89F35C62A9B02545361A95950BEB8A39CFCA7694AE14725" + + "23D33CF26DB653BBB2DE64CB90FC87D9F6C251C5CC51D621294F17FA57AB783D6AC5C2B175F816A5" + + "2775AB27E0E1F2B4F6FF15C31EB2EBE684B1EB845C7B315E0544AD82B17DD80B857077B7385BD315" + + "D3737589097E821748742E4E049C159F2DE382B3F6C6286C881E41A0C9335AB3FFEF21711A5F4187" + + "F8A349D9E9612AC71141EB930FD304F5E590E84B057ABB914E18B02E6326E119769186FBBB0DFC71" + + "6A471B85C5A9CCAF1E8498FB78B7197F9F04E7E5D3940E2CC6B13CDB8223797D8B61031FFA5B9635" + + "FE83C37253A7CAB26C091F358A88D36D6615E05CDECA33E2F7EBA3436A8689BE3A726DA6027441A7" + + "0D1AA6B60570682FA56DA58319D0A76C2AC5E6954FD8CC12C024A6F3B778DA0B98FA2D85375EA7DD" + + "80F31B379849E3E065251FDD80DAA13A9FDD14AD4EE922C1A43ECCFDB10D924AA2676FF0126CF0D4" + + "D1F5DDDA397F4965F7DE92C9A84A45F0E42EA4881EB4D643FF595CCA40981932A6BCF794DA06EF48" + + "C6EAB1875092A3FF31AF892B9F9791C989B7E129C81050A966E25B4C4A77A06E59431FAF7E60FAE1" + + "8225DB90427F150209420B7A74498CE69A30E84A7326240C40CCABB4999A0C9531567254F7EAD94E" + + "2DCE726F84E03A05F7B94A8AF52C37F579D27A1CCE42D17BB1905BAF4E84A0E4BBDD77AA1B9EDFBA" + + "E879F76B16BD258C05C1D898CE952CA4798D0D649B227FEF2560481BB93CB6526B49B1FAE74B09BF" + + "F4F6D2CD73C54403F930E7D1F04B049A74DFB61F7C1983D78E4C5E139925D5605FFDAF9FBCF3CEDB" + + "7FC5353C14449EC95D4A20BDAB68BCA3968EC142A1C4C92E6DFB168E1461E5959D628839BD196650" + + "8EFFD86254435B758CC301A1896B3D07FFF2567A952CC835AD740107DE496697304AAEDFCCC820C4" + + "75ABBBDD9692099E69668223B0979A3CDEA42B7407D12147A09734920AA76E811606113069A7D9D8" + + "E908D8FF90072E65DDB8863A4A36CA87DB2485706BF3A74166132BDFFC78F565DE75ABD258FD6B26" + + "07A085B1E8D49441E60EA85E0DB84E95DB30FCFC2D3605636A6F0FDF78B19683839228BA88827263" + + "0F591602DB5FD4EE542483EE80EFB8305A0E345B38A39BFD1183BEE1A6A3B95F1F7DEBE66760719E" + + "CA478214AEA7074173CF5D42E191E0FA3F7E634CFE9E35D738329688302C00B75016EC199EDB7B74" + + "D0BC7FDC7AF291B5061B126718C2B4B66021EF291CD7FDF3ACD8357347E71652E57B0EB25596F828" + + "5C", + contextHex: + "F2D11E8B54CE7B5BC8737BFAA82209B9F0F3A1142B8C9F79FCC3406C26FD816F717A7F7DDCD0DEA7" + + "157539A09C87D2DEEB3B11B9F38D63724FFA5B337590D1011417817A00F4F401AC95A28FFFEF7457" + + "F6B5FCF8FF9586F2F58071D1D18B3CB705389010DFC894E734104E7A8059F3C1CB2DBEB248D73AA4" + + "28604395DB2912FB1022E8F2B04085B56744CF3939AE5338164DFAE3874CDAEE2A4051647EFC2C04" + + "498829D391090EC61145FE22C564E479C5C192072D5B8339F67AFCBF0696FB6667959E1E2718FAA8" + + "55273F", + signatureHex: + "3A27B77C12BCD14DD019FC20BA9B6EEC335EF936FB0EF5A1BB14989A956A3FEC964E922788FBA1BE" + + "04306FDFEA49DE28254CC2B4F10C03E629F100FE5D0AD629B3B1826A6270CE8884C0B81AA4D615E2" + + "8939C3B37E4AB23436973633994A47BFAF8303E970706D6C36AE579AB83C35816CFBF27D410A316F" + + "0F91C2B485AFB6CE49D004CB8FC152C22D2A33BC549EDDDD57869D72F9B5A7C988E00FDD0789403F" + + "F637D97B008423ED77F0DDD1CBE2E368BE2AC9DFEA7844E909EC337121035B070276E06CBB4CB6BC" + + "1614E8515F9C77F0746BD631486F20B776D787DE4485F8AD2C4C0439D6005FC04621BB1477EFF510" + + "A6E6C408448520E245378CD3842387229E7528D736FCABD166DA52A455A91308F75FA5831FF0DD94" + + "424CB0110F3F0C0C518B914F0CFE7EB718545A9C358BD890475A26AAC5580B21431B9EA23FB78E49" + + "CCC0C9ED081EE6AE71782B18CB644588FCDBC3A682748A377EDE7C54004434771B92E1E70CDD0781" + + "874AC9A4CBE6D34DE905698C0742DAE92524FBEC269B60185A3D584AA4C5622A1191BED6001A3155" + + "1BA13108666E53A86E990839061D1485D0BC7435824F59152465AC9FAEC29E3F7C86657D263699BC" + + "0B128DE859D0EA61DBCBB4513511803583220B03BF50D222EA2F5B0FF4AFD4386D719406C25CA48E" + + "C574EC0F50E2292D2EA7FD644C5C9DBA508D1E61783D2A16D8D371A6078051498DB47A1EED8AD353" + + "1CE46029930EF1103033E3D5023EA751C4829F499C5DD7F14403E970C0D8F4308271BBD2B3AD4B9A" + + "401A1431A40EFE1E55D57B8E9D50BBEC0A97CF77647A24A295E403A61219B0F14A9E1ACF19E9FC67" + + "D5989B8FBAFE6F3E21815BD3773C1BB938BBE46F656BD367FC76520B4E602F620AFA28853182022A" + + "B50BB19429F643B3A44EB0489619B21487F40BBF2859AE6D6AFA8DFF7E03D61AC169F81AB518F70D" + + "F8E2992814081E9A1E70AEE6E4641390E43B934BC413105D96975ADDA5E9D964E7848BDD80C6922F" + + "8FEF9643BC3DFEFCA2EA0A377C83257C28A7102092B2CC8EFCCE12BC6C1F2CB1A2DAA38E1B68BC44" + + "8EAD258D1FB2A879DB81BAE35D97921A31C888703BB889E13F2AD0F28C17165C2DF8FD9F727529DB" + + "618564DF296169A3BC8F5E2D59FB3F99F7F327D1B211699286A0C735ACE3795297861C90E98BEF0E" + + "B51F9B2BBABBD48C84F8AA979C160733E600683E2D4CC9AAB535AAB81672C943F1D731A8EFB9A794" + + "A0DB65832A09FB7BEBDF873C00033FB87A3083027ED9A7966CC21BDF07A578B71526A37993D126F4" + + "E7D1135C41F7C764DC022C8D85C6D15F00D82D1A58FA54771CECF5B776A383151733EB9DF06D5C82" + + "D3DE382567BAFCE418DD7E588C85A9A0049C67466FF086085CD4B58D4BA0A635E224071775D177E6" + + "593BA6C07AB44F2B50A95DC37E48E629CBD4A98D18DE4FE89DEA87AE57AEDBEBE7F976993A500957" + + "EA53B4F03C17C434FE00037DC887A5BD23DF1FDFECB149907AAA6F1EAE60DF85C52FC2BAC9EB6081" + + "7D8E4B5003399DBE06215AE611EB1BCC5C76BFA246FFAC218AD0EBED483A6C97EEC7ABC87B2967D3" + + "8892BD531182CAB76B5856CDA2A44470FC995A3A6338D572E9D8E296B8CF0C714AD2FC2FA8C3B69A" + + "0573551457A909A96BCEB907A1D8B5ACC4434C3488A9A67C377BDBA7BB3B79E3CC4E6817EEA761BD" + + "4864BB7F870CE0705236479EECB00EE3FEF275769B5AEE68930ED1258BDF9B607DF57504E3DB4EE9" + + "2CCACADCA44E76AD9FD69647468F6FACB21BD44B258D3914422695AEFFA06AD0FC0EB505BB419ABC" + + "2E69316AF4AE597A7ED64432BC6034E66B33E75FB2DB956B23F33C16A4EA9C23786D138CD62971AB" + + "5F231851D6EE3D10F387740F77B8E833AB982E18B5320C943888E07FCC6CC37C81FFBC73E2C8D34E" + + "BC68E334036FC58DCCFB3E1D70C595C99412C58D976451AAD92814AAE900B22392EBE4320482E4E3" + + "9BA34C0F95BFA682CAA3F5061521CA301C70CB3D87A81B76B7891EB837F01FB68EA92F66A4CD1441" + + "608911B843A3A1C71CF5014725CF355BE91E03C8122FEFE99267AD9B32DE812545E0ACC04446D92A" + + "5BDF2D8BDD1B96F82DFE77BA0BEBC179BC0F69B47878A298B86FAD2318D29F6E7AB5A04C49B2E0EC" + + "E8B0B6C54CF272CDFCA40B8273DFF299CFC4B5CCE3789B5DC559801F46F5FDFAC61E0665054E1253" + + "453406C912942B0F21EBD68B286743FD4D86405696B566FBF4FEE72C11522D69784C9624866ADCB5" + + "09046B5DBA187A536EE91769085A822C48AD87FB45969D0FD929ED95BF21552786B5005D34F650B4" + + "CEEAB8BA7358BCE4CAB03344C9F3553EE908942BC0AC19726E82F350C37E7CD258F44A977C599C3B" + + "1AD33E38397E8F9EC5D142589733843F585D5743610F12D8945E7BA05A7F0B30D8353C9FC120D96A" + + "64338B010B53B900EA63EFABF5C80D98040F9E83E1C9F1AC361A0A3847C2713E31E5242D44350AB7" + + "67F6696503D47D3933C853597517F8DFE5898E5E08E5BA7D9FDE622AC5B623CD7E20215DCCC6A293" + + "22E848C15FAB76582745D533B1E93CE2913D2A5EDD45556207EEDD5CC7DAC81CDC1BED265C5EDD47" + + "45BDA5761C215C91D5B9B6F32241D7EB44D541D516C30EB8F72E298A36A830B2A26DDF7721EEBFF9" + + "01D55FFC124D497423C286B682CB3D0BE82A9F86F3C64BBC95A110FABFB0557E62DD196E6D4E8DE1" + + "F65C1CC0F6CDBA0185D3C36C17A69FD486CCBEC54B05A6BE7924C29A1B32E6317B65B0D6C14131E5" + + "03971C23E0AB9C8439D6F8EC7345825745D3F68AB45D60B01DB15CC04019F3169F6D5421922CCA18" + + "6A5B2C0B559C793DFAF69A20ED7D9573E6B23CB1F64CB7624FF0DE31EA913F86CDC798BA7A839069" + + "9EAB3B017F6EC2B0C265F79430A47BD967C3CA65D28341F9320B092F877AB7EE16D57522983F4643" + + "8FEB3F9D329FF0CC8167386C065445E765BEA3488C20346B82A47535A3F9F6CEE8AE3EC1AEF98C62" + + "B0774E06FF8D4B019A6CA6829C90412D81401035F7C92EFB946FF0729B832F52D387636910DA3204" + + "FDAFB68EC77E299F03F84D2E80ACA19E1AA0DE7A1E4FB0BA87162AE3B654D52DC0EEEFDB72DA3352" + + "23177EAA550399EEB58210415336E04D033F12E7874F956DE90263B6F344605A5D49DADE119975C6" + + "3E4EEBFD8746EAA8D5B8B703AC339BE9663CC3151AA4F4E142E32C9D14C14064ADEAA4D4C635D33D" + + "AE572A1FB1A988568264AC6F059C30B44933A6DA1D0BE809751306058B9A4C87AF3EE8AE276D6174" + + "AC515E82953B02EE2CBE2C057C3ACAAEFAF51AF289507413F16CF266519B69D9658266F2C73121D5" + + "BCF036D2F02AE675CDDEA66F50D26839B36D9056371615D6B19B3B6B05AAA491EA4CA6A90A4CC85C" + + "817A5E1C6524F3EFD02392445300839D14984CD5774B0E282DF9F2389054426EC5673041220522EB" + + "EF53A88257FD15092E8AA44C5A25CF003565B32A287C89772B8B71A23F325035FE37ED7BC8E0F70C" + + "0A07A6AC642EDF87A354EA970B545C0607BCAF1A41DF7058B7E88E47714292286C7808E631937E11" + + "CAA5D2D60625CA5EBA29748395E4A3235F2A32D34CA294704699DD587C10639BE2791678501ED3D9" + + "BEC3B8D98B5EDC2161200D27E1DBEF6A745F06EF96A7E992303A43C172F338531DCD395F2F61CA61" + + "9C3C076BBE17D782494FB750706A5D778FC47C5F3CB1C30417F29A681D20DCEE404AD0E9E48302E8" + + "1385373792165E7AB4DFEF1EAFC2E010C2B01F9E138AF6359859DABBFC26733A54F14DE77AE2B8BC" + + "DD29F17F85DDF2E188DE8E34CC6123B1AC65546D866921468A6C4729D99D311D375D73C5ABD7EB0B" + + "E73600B998FA286F00ABC09F1206C217BB99E026554239410202A5AED459EF18C0919992B95E3293" + + "069F3FD3FE4E08CFD61DFCFAE34D9D8689E59A335BDF16F15D75BBAE5F688BEBB8FB8F17E390A3A8" + + "1448057966A97F81784A26D530796431D23811DED5A40029A7A3CD6117A17C9DF63BD5CBFDA216D0" + + "4E7B682A4F6080F0393D6F6AC0DC9FE0A33F5E1153093CD2EBED21A9FD503C42E7B41A1BAAE9E395" + + "CE1654B5E54724DA87B7158A1947E51C0AAA60338F639A754C6F007F70A6078887C85C67E2249FBD" + + "3D4D9150FBCCF57FF8BF1DAE5102AB7A1D8ABEAB54B646AEB743803A6312121444C913F94BE8B05C" + + "DC7A9BC68A6F9FDA5402D3F51F2A1809A14472909ABDC9851E51AE0E4B4348873F4DE829087591C1" + + "0D49724FC333A01396C07555CD0E5D58F2E69352834CB319E28F40DEC6A7E308F659B8624E7CA43E" + + "E16127FCEF23B276FADEC6C622C57A907E29D56CA0AB5400ACF0DBF0162DC8DC1CB5E7E0B6166219" + + "AA233D004C1175A31E8E4C48861D4AAB05E2584F17C7974D2FC64D031A942D92BBC833DFCBC99A7C" + + "0D4A461751DDC203F9A742A967850871755CA16949BBDC10A367CD63B582E38A096A3983D94040F5" + + "FF9EC19D4B9222430DEBC7BD4D3F18C48DB32FF50B7679DECBD7822F68BA804B67D02C5DA24A8E4E" + + "80F53C1996891AF21006A032354A7AE38986D05DEB3D02B15B5999F398826CA9C60E8D4D5A2F248E" + + "AD9110B3C93980C20B142A6B85A6B9C8E1323FA2B8D2F14F6370A11A2D3547686A7E92FC334B6878" + + "9697CED3F81A2782C4F100000000000000000000000000090F131C252A", + hashAlgOid: "2.16.840.1.101.3.4.2.11"), + new MLDsaNistTestCase( + nistTestCaseId: 76, + algorithm: MLDsaAlgorithm.MLDsa87, + shouldPass: false, // SHA-3-256 does not meet lambda requirement of ML-DSA-87. + publicKeyHex: + "E4C74427766F1AE8399213E114EFA1EEFC7A85CD583C28B38EDFB5AA2351698ACABF5487E7B721F6" + + "D15D5A60E0D0B629C663D2EF7007CE21C574F3F01A1D9C7A9A80E4DED8B3D14E3996C9FBD4018390" + + "2654B951FCC79089CA2564F30E0437E6EB237522ECEB16ED0ABDB5309EA3C4EBA264A76E4C5CD634" + + "545173284D871528993F7A6187BE78767AC8CAD944896C7AE5AFF07B8CACDF9D9C7C0598BD72CDBF" + + "A379976A180F107130E4487E99F6CC4B5BC0C6D5FD109C7078B1AE30FB38D4A8F5367E137506B5C7" + + "FA7129523211042FC50641993A7114A545103BB8E1C3E68A89919F2805DECECF86E6E1D0CD617EBB" + + "DD7CD49243CD6AF51ED6CFC3B15A49EC32EDA032557235C60ACAA4BBE46F1F170FE461A6C2BE440C" + + "AD47115583D648AB7A4BC6C5E66958637AE62B774969B8CF314B0BF37D87906F0C51E6C7D8AF249A" + + "F5948399D327A2AE6905ED4E76E706073CFCD3449C630C00E558169DBEFCE3C05DD978ACD869938F" + + "08DFE4325085C85AE22B6189A5AE2850BCA9507FED706CDEDDFD2CCF01DC7A3DABD6269632CAE077" + + "F7FB02B28BD448993EA54FA9CB8C73DD40389A47925672DE35489A6E2416340B0DEEEF33D47B87DF" + + "D2A6FAE8D01304DEEC1CD4EB07E5DEF83B3A903A9FA87B1E4BDC4FD458AB816FE0B3341C601E1552" + + "FC4EB20DD2EC9C19ED1C270F0106191F1B588059A93F0E1094F691A0EFE0854789BDDA36CCDB3F73" + + "DEB7A79B86EB91B8950486E5E7CF10559CC73007B95C81F16C8EA013AD9AB8560B266021BA2B943C" + + "A4B95ED75666E1E4EB2152697DCB8FF7B1E84517109261530686D6EEF29C1F08DCAC499E7684C33E" + + "290BB4CBB94A9FD98C519D7A76CB9064356D969647EE067CE3488CCD2ED30557BFC8705F7421B657" + + "627FD488D6B6A0436BE215145689A52B451DA685B336DFB1569BFAE80AF901AF735EB0CFE04E2223" + + "1C9EDE012AFEEAB82CC3154BFF723BBA2B7857AB8519841EFD40D9D2398AB09793243309A9F9F017" + + "892D8380A173BCDD7F0A4E3E490024E553FFE97AAD964A85E8209D6A5C7C6461A7753D4B7ACC2A50" + + "513F6BF83A53FFAF3DFA4778519C9F823865193B5015007D34F9128E291720203442EF012CDF0206" + + "56762351149D02E160180F9EA33BDA1AD23AA53837F73EFD58A83B502E395BAC9DD601657E3BCFE5" + + "D3C041A42E619E95950B893E54CF0D58F1B33004862500992AA95F909A956CEA86886B3E1702CA9D" + + "1CF137B49F5195923AF79EE564380DEAD809EA146A7F652759FE145797F2D50649CF25BCA0465D0D" + + "19EA9B72A08736AD0C30BA4A0205C6D9F2F3E679E9CD85EC12922E39947059B3A8570C9DDEE7AFF5" + + "0CFAF74D2B0BB1BC60A0B1D677AFD560673B5B0A2F30F2C1C225C1A0BFA9CA4638F246D055A033EA" + + "A9316A3C1DB11F6DC73D8EDA93A98F8DBF779287F0B4C6C55936794B20DA2D647CEB6DEC5453AEFF" + + "93580B1AB7FDA81E54B055D80F9880B33E41C4DA4E98FDB92BCA1D2C9FF7CC123BB223D27C5CE2FE" + + "A7A3F2B0E82B2F02879CE0898709865F1B97B0FB0ED6E159938ED9F8E7936A561330FA37B56B94D9" + + "405CDE8C939C195781EC524A9CA934E09D9F649C90E1914D5DF7C34B42225205B9884B3444781A33" + + "9252BBAAEA9D446FA0628F5979B14B2881B702713B9567527B31400209D5AFEEBDF7DE4EADC14988" + + "06A75B3D148B9CD55E0DC677AC9AB717012478C64265078C7BF57E2002F850BDE33D06AF93858191" + + "22D2C83043956C162F704DCF54036C86506931BAD39F90D55AB6806213C0FFAAE59EEFEC9BB229B3" + + "FB45A4E4E61E8BDB5FFBB7BA5A968B6370AA057CB1350EF01BBEF2422AA969F12CB7B8E48BF5A0E6" + + "D68C9D41EAB9B362D13BA35EF6144D798DF2BB28257434B54EFFB725BFC6B2B5BF951EF305CFFFE8" + + "24242D462FE42D88C093CA2CF2DBA8B1035F7FB87F5CC5F78B336769B75EBD850E2F4E3FF3DB9DEC" + + "60A07E718106ED69142A1DEA5A48460104414E0A4F49FC6C91E74A33B1103384BF3496524A462D5F" + + "518B1D731ECC2A6B8549F440C7A432EC0755693E37C2908123CFFD63A456DF1ED3DDB98F776E7C83" + + "3B0C59F448FD106EF784B2F7A78F40DEBE53D6B11DDB5AC5E73673ABCA690590CCE37BACCC07BE3B" + + "FB9329CB6221CEFA156267C5B36EB1FFDDB89C719441978FB8236A9636EE739CD2B302D16EB7B43B" + + "5C9B7CA6A3B94A6C3B2B4731D54E743F951E794B0B775B44250905CE3486868CC243D3AD4DD092DF" + + "554EF8F1F05AB931C030F571F6E5B3F7B911DE435CD8E68FBB377B6E9C747C9F07075DDA3C4CC962" + + "7DDEF56D708C349566059DE1EC48D56C936EB69C727ECE3BAD5FF78C44697862CD5C6D867C2BCE3C" + + "FB8DBE266ADE6DC5DA84C5864E1162B82DDF5241FA2DA159256B63AE43E134E0A0B7092E65F5B4D3" + + "930249E7A1CCE3F9B256B5722E7FBDF2EB97220F06DF0F4C1D2514D47B5342747481E12973B7AFDD" + + "E12DD7CBDCEC9457E1A3EFC8A430310D8BE867E41E629C43A31490655EEF6CC2C5314C796DB673C7" + + "9321F4196B1E0A754310AF055AA2A115BAFF19A1E8B2C7D364A738FE10E02F34DF0B3E8BE5AE6485" + + "AB150B1D9C281F59FEA0CC862B77D613EF6A6FF97A137FCAA8ACEB6112423FC47BA670EBE6A84BB0" + + "AF8317A052A549023DB61A16DE79A064898D38443059C5B4C8641A17C38498F5144CD5BE6CF07A7B" + + "2904EDB3AE8A714EB418EF1DDD638A971FB9C4C1DE9BBB59457042FBEA021F2E9E979B38977F3EEF" + + "B38233352FBB341F492BDCBC1F3198E0ED186F21EF544C503E8F1F3B2D995904B4B9519712B669FD" + + "2070B00E97A258917675602D21CE21872C5D5CDF1656D5E3D023CBF0D43BCBD0E0BFB0443B5AD75B" + + "A5A2365AB0AC68C6366DE97D00B02BFF452374698754CFD8E3EA08EE8E75ECEAF188F4836A52F2EA" + + "4FB3DE06797BA84A757B38730F54D64814363F8FFC202C7729103E2537AB1CAA5A129E96490A85CC" + + "9BB8973DD03289B2C70412C40E9EC2703570D9DF21957C80C907F081ACCC1108D0D0CAF5D98DD7E1" + + "4EB073581A07AAE9A9656C86F258FCF2CAFB29F9319A9587AA745FACF46EE16AA5EAE11CBB141537" + + "3AF84BBE15FE6356188830A95A18D4C17972D44A0B41D69C5E8D60288A1724D5F20FAE974B79EAF7" + + "B1192CF08C8CA5A86027A8C18374D40953DF41B07F483E33064FAAF1082EC09A8C483925148239D3" + + "E03C87952B42B8D3E9FA8C9B83E906948A965A3EF7ED64F1450751960364CAF860009C95208A2A52" + + "7AC1D6F4E8B1034C2A23F83AB67947EB11C118C4E751B9C65889E1A36313FADBB4B953CCEF3C4D70" + + "69A983EC501243DC36A9C4F4B0F97568D00CC98372E5E2657236741843D016BEF2CC6A4FA3F19B80" + + "563C2E9E1648B567236916421AAE4A1F3F688E543C0AA149380A66078EB82DB68803A894E005B8EE" + + "F86126717FAA1D159786CA57C24223B6A3137BAEBB160B9D537D8252BC9D0DC406EAA1290216D831" + + "9E921B22470D20004F490B68208E85318CC4038517B590D9B4686C920EFD62BAF447CD142FDAA5FF" + + "29F633709608E4C4CA7BC4B6900F3DD8521DA01BAE3F77D92F4EF83DDACF64EABDA1895FA5BEBA9B" + + "D043D7EAC831B96C80B8DEA25427012FF87475BE31E64A8E4AD51B33A9A7E0E9", + privateKeyHex: + "E4C74427766F1AE8399213E114EFA1EEFC7A85CD583C28B38EDFB5AA2351698ACE6A58FCB41CEEB5" + + "FAE2B35CF9B911D3EF4122D15B348B7F9DF8EC3A1E63128FC0505689327DB78B4D5F15ED0B102DB0" + + "4C9992933B40E51AA31A8376B4CF3EC04E3CBD3FC5CA5EFAD9A674E9BBD5B916F0069023993FE67A" + + "D91D2508B9D5FBDC028771E1026083228EA01822D8242100405090086920C861191068D4264A9C26" + + "90608201C1402D5C880D5304260A01000BC5010B900D0141050C200CCC880C1C06896116611B406E" + + "9102125140025B18310B406E0116894326520B232EE0309121278D189151008864A0C2818B1620D4" + + "2205112611CB94200204261933208CA0085410659A844C1B26610042901A236248A45122248003C2" + + "042305720C270AC2B85024A66D99C008D3322D0089415C482A09334D0024650C2832C21491C80610" + + "CA9204822029511868D2C024E3464C9C3465E1A28CD8244ED43425A4104A20106958400C23974481" + + "26851102064C160289182E22093294380D942861A10065643871524062500484134444084492C396" + + "71DB1401E20006CB240E93364A8AA0099B169210416C9346650302090A418EDB8861193165423822" + + "20946083048199042A24B44410B16D09238A09A0451A26241125661AB78C13060C01B5041B888502" + + "052891C6700B29264CB4414484851883309BA4298AA631031786CA180C0BA60148B48C42C46C0924" + + "881B448098822C43A4611029029B0642134326D1C671619248CA3204C032058A94845C120C943486" + + "40425291401110C92D02212442064E09432002A64C1AB5700496099A82496444920C9100DC222021" + + "094948A61143080058402C4B9691A4C64808C84848244EE4188122842C48208011A9800043510849" + + "8620A96811010899844CDCB20D8124100B0752089484129241CCB06900C1115CA26058060A9B262A" + + "C21004901480C124891A868C14B204049109C9286053346A1B20420B301119C449DB2068D3005203" + + "188C52368500817123A14DA18828031822434062D2142810B00948C69112A2800299411AA2700803" + + "0543906CDA8069C314820327842105921BC34513B3250CA680A2A88DE22888C10031A12244622201" + + "D814661C011212054C0C374942000C114590CC342A19B58D582410CC365224996123374583262519" + + "C80921A508938051124382D3C65099B84961326C51300E0939204022609B1229A10240A1348E1836" + + "3002B765224602993669D2B42444C07108296DDC08319994051CA42181808D22C48D531431D42064" + + "480491D2084DC04282C04611C1209020280E0C858463146C908600D3A6680828708CC2714B324C49" + + "3065C024919C00410A8604142772608649D2C264DC129024296A1441685C082219B490A494812401" + + "6A1286695218865C382482124460A88500C18CD4B0011A348A01182ECA428840421081B6105B0630" + + "239104048145030306C032841931804C94911A3002044828DC8008632250D03008A3B41014063151" + + "A86D1B00298B9071A1C2690129268494500A430904900D24A6802320218846414A460A0BC70CA1A2" + + "2094128E8B3286598865512401D916914C20700A200C4A1826CB403191280924139298080DC42002" + + "212131A3868050044100B8098086048430425A068508430A4840604A48860C058A9A0860199084DB" + + "282A4B225123A94C48282421C788C0324DC02841134385DA482C221046CC90011CC2511306061983" + + "0123182A84422A4B382D9808311A384D83448918C35141803018B13140426EC8A48092C84D222464" + + "54A44C02974DD9A83042023022257292442483C449132888029984112624DB388E04437244428989" + + "3850091042CA98294CC68510B2091B15285CC2618B244E90121092A45001918441362892C429C938" + + "6D230622E28231CA004562C44DE43808D3360D98048EC3484AA4444CC40489A0086CA4C8250C0082" + + "4B040D0B4065218040E3184D932025C3184049C80DE0844D101720E0A4400A42429A8821400286DA" + + "168221356AD39864D3324448A8711C442121372800C38103A140D038089440726290054C948D1815" + + "324346440C20720B338E134569D4C4404C3606A4087114C028A180451B86210200000901404A3600" + + "4248688AA86050106C1C280D404208021892149388D2964C4A280923C32013032153886913A4058A" + + "304603346D91062CAB7D0530355575FE30CC2AE4CB33B96AE5D78CAB628567D6186AF7F1B3343340" + + "4E99F27EDDD31CEA558F8D08FB56F988F42B82DA4323CF6242904B7E323BD070A1EF53C1BFA7239B" + + "BFB267087CD84A7D0D07080CB78E21B5B5383D37430D4A440909EC9B4204FA7E3D803F7B12BA6604" + + "182F83C3697E371B66C26C838AC7709ABF291614702C28C76AA56572A86BCB847636937E51BDB21C" + + "0E2CDE3EB4538A74B2B8EE6F1B450FE4FD3A133070FD553FB1703359ED16DF294795E5E83D3D6F2A" + + "E02CB22DE95C27F0FC71E3808DD183E50DBDEE8BA8674831EE0D11E457129BE1E0B329E58E949B60" + + "E3E4EA912532A19F0C0E83734620C40643EFFA50D57AA2E9A77E068EC7622F6EDAC166F29EA79E31" + + "1D649ABC1FB49FFEE2FCB3B796976C2075B9F9AF1A6666D4375B2765CB256B3B176B043037D21951" + + "415602CD7BBEF45420B16D1FE46426680FBB3390CA6E5326A9BBBFF832A7FC807D433E6D8F74FD1D" + + "E12E855A99CE92980367F45B7B942A5B82DA50D68C9F3B01382CCE728E23FC9DD0F28A5EED0D33F3" + + "8E762621CB72C13CEFAC0D3A7E307A30932BE826C292791CF8CB97D26E7EA649E176936C5B83E59B" + + "3F61EC22A81A5066D5FA0A339589EE2A3787BA4218FA1E48BAE5DC6DFBD4308805C00CD75742ED4B" + + "0288B17173B3BCC3262969B7C9DB160F30D67E980B0EA82F672B26ECAD889B4186C241012BB990A1" + + "E985FF295E58DE29DE83891E098A8A7D13293253C624E5A96F02406CF8CCA2672B8686701869D201" + + "1F0C0C2232FA623DBCE6510E8DC315E07B4239B460F484305E279284D3685F88BE1FF739A0ABCA1A" + + "9D37B0073A5A9C1EEDE959D1C60832D76DFA9489AA9CE83B1926C63595FD259718194EAE08A44316" + + "60A22E96ED4AF2D57A53C1B2830BA8D43F2D02BC0B127330BB5B884DB08226E1DD780D1706692B14" + + "1B9F78390C2A1A06E8531C42D5217D9E3F954783D5D3C29C7BC10E9560FCFE4853ADA6D0521E407F" + + "2DED05E9EB1D21D4E3E4AF6236EBF7A1C6B9FA134D8CEAC0AF08441BEFD234C0F0451364DA091EDF" + + "0236B0130A19AD2342743D101B1E65C0C8871EB7AB0809159B51F8006DF7A52C3232F41116454F2F" + + "F4155617B1363C6619E90E58DB0115DDD3328F18DD2B79658C5CEBCFFEF567EAE45F0F4DD7EBD9F5" + + "E35AA1B2A249806ABF219D5BD4A8C35C3839DE08E71C7529A81FB26668FB6CD5B6C9BFF124DACD65" + + "03101A08455463457C1F662B14B6624B66144929F705C493DFB31F958FC74222494A178325938BD9" + + "86515559DC4627A6FEC939B143D3A3F35A8F81CF1A270D293216501CBFDB487EE658D41711A2E814" + + "5BC44F2EA5D2BF5915BAB9AA0DCC4BD673C6E940D2DB83213CD1318ABA084111E70235ED681B275E" + + "26D9943F3689E4F95A9C63D4746FE29C40B8645A55A1E84C0DDBFEB9A6FEBB76E3F1372988D9DE57" + + "1EB064212C94B2976014D534FE22605E710F70E0C09176F984AEBF35790F4B0F7B358C0BAED5D8CD" + + "BF9E4EB12290AD05D21E06942DC5723CA5ACE04B3F03F7AE4E123DD5C17F1CFAD9E5426A4982B519" + + "73B2D7AA6B6D53D81C2418587D9A30C96ED71ECD89635DD505586B8E2FDB272F485C0BA3F1F614EC" + + "DA695ACD84B05A9184B5CE4735D1F3396DFC1B0C22A661500FBE7B1E70CA8FBEF308F52AABC6C6F2" + + "3780A78492380BA5530557E5E0DB5771A487EF5D52E30D8A4BD95547B71393557D5E2CD8B4FC880D" + + "C134786FEE49289622E07E17E47B558729DF90D253A0A5E4F9424773C5728956E3EC93F4587F171F" + + "8FB05CA926D9FA107C91415FD94E51F589B835249F6FE73586285815D4953125D84E9D232BEC4824" + + "6ECFC3F0A7820EC5083373996C34C9E426AC6F2D198D8D948BFB4F08666F31E3FAE432C958F8BA86" + + "E50BFED87609260667681D11E7CCAD7B26CBE423213A6A4DCEF1E3390382EFACE3A31DE2CF63449B" + + "F1C8A0047A8B8DCCFEBD59C24BA64443AA2F15100D63B7808878BC7A5967493B4B95911289182229" + + "39CAA0AEDEB420377FE92109F3FD55E1BC424EF733BC3D9A96E109DE92BAD505C538670EFC6FF794" + + "63C54CEA07A99BDA33F8C5ABEC7869F651016C15D8182D1E7BD3DAF3CEA41788CFA918D7424F62EE" + + "20B16CD719AA3BA4F288A87BFB38D5620627B030404ECDF0350543C27EDC7BEBD4A93AD4572A7971" + + "CB0C8513D028639B746E3CE4B79284143A821D0FA8E425DAE47C3D0AA22BC6970D864D822933AE3C" + + "E3F879A62AFDA627DB44EC9850CC0456A27E361A409F82387EC11A6D06BF27DB302BB81BBE7BCD07" + + "D4C9DBDAAD912EAD63ACF61C8FE79F48B61F9F192E4718B08842FE6698ACBFE8E9375BA488BCCE2F" + + "14093752518A7DA5BF894CFB008FA5015DDAF63F5A2AB0012BD5DA894B12B83DA0D518E2D860D21D" + + "0B1289B4E3EB8BE9D1319B17D5179C5A33F6B5B10C287281BD1B50B8465EDA86B88FF81211F9E864" + + "FF4FD9E34E5AEE5AE7919638C151E0FC9C2C5DFDEF276CF0EAB5D6ACE6190BA94017806C4A113A68" + + "78ECBB27DAE7B4C97D5DBF1C21339828B52F658332B822B32F6E1C0FD6362B2C0BEC17233DF772A6" + + "871ED286E6488F6E253DC8D50D21B002F70B9C1167ED68046D65F6F95AF1854E20C8807347CA3EC2" + + "8073F7D7126FE614B758795E4ED2CE612B2EEC91AD43887220FE83BEC1A1707CCD1FC1652CAAABAC" + + "07857653B07103B86EF42A2D35BED007C9F8BE5532DDAC62BE7FCC9F0CFB1AB9FEDA3141D68CECEE" + + "672465A8D2FF42E3B2AA3827B0262EA31E1FF7782052E1C54C133068E300BA29E26D45353B63C8A6" + + "5F6C6F7089C5F86B034E9393650EED4CF4849BAB63605DFBD8BBBC3382593359E052B6CBAF69A13A" + + "3E9C6F173D7D27F79BD0D8CE269E267E363F82708DB6C7418D2E863C57FBA7F640BDA3FAC032D1B1" + + "69E2D48E2D4A715195CDF4AD8AFD215DF4647B05F2C645BE804B013C4928823328A5FB21832161FD" + + "7D89FE685EC5FD533F43B71DE3B214CF99EB750EFCE2F5792CAE12971FAA920EE3D4C13D03B0A09D" + + "C6CE13B1DA3F804A1E83B1E936DD6D63A83962A13EBF492F1EBB6C1330A962EA92DEF4EA6C83C2C5" + + "51E4F9DD932455C2ACBE2EA4EBC0ABCCEF29D59AB9E3B5E268A9DBEBA3C518F2BD26B1D3C019C532" + + "5456BC4849D7BF8346759E63DEA1D0BA93A1591EB9A983BBE79EF9BB4AAF255D97E26B2CC1B47E6C" + + "6C02448E32FCABB4F86FE1B228F0796CC29EACD3765B0906FEABA1131D2123A508043E0C2F887028" + + "871CAC2C416C580ABA66E99498714E6E1706AA90506F78B23947EDCA9312908F69BEBF0F3DEF44A4" + + "EF049F6341B13CAC0B25729CB05AC68B762555705F7F51F96F6C0728F19FDE49E82D6B72FBA1F85F" + + "F46B06B207B3608FEA19C223EB082C302E6F3BD5BB1A7F379C777095882B1C4F256AD3E542FDD212" + + "B686B699E42081427AED5902AFDE1B5A5F10787681E8FC9E0CD993B251BA0173C5B64F91856286CD" + + "455D55A879AA1622FCD00E7D92562F925A43E7DD9E0DD242B3876DAD45FB1C05EE0DBBBCC6C4C174" + + "C171AEB44AD996C0E6224F2FD326EF3C84538A5EEF6661CF9D5E131B69A57A4406B7DCABCC95CEA2" + + "D364CAEAA96C5C0AB4186A01F967D9D4B6FA94572B1BEA08BA60A4B554988D492FA285C1AD229A75" + + "736DFA9940661A5F70CAF7C204A4EC5B6F61A9C3255B86F16645CBAAFBDE33ABCBA6D1A6EFC13ECB" + + "CEA8F042287AF2FA800739FFCBD081863FBD13186E47BD2A74DFFE2A1584B72978AFDF42D2A4BCD1" + + "173826DB3E3935953B5416B245C0E0D50A6405D5F245AEDCBB3ADAAED0776BD1D17215EA45A79CA2" + + "82CAFF8D625E099C91812F827142DCDBF0041AD066761EF5F77CF8FD1685990A4DA8809FBC4CE014" + + "15F45246E9193C79D62301F135DDA3AF45453B145D65934016D5FCD417211F577ECBB6E8B95F9606" + + "917972DD5BEED9D847B15A41AB159B6811B7FAB300C1539B37CDD6F72B920141C6108E20792D9207" + + "E5BB99BD2FC99D32B14AE83BDF0865903E94CF5F0C3DCE7F78DC3AC8576634CC34669AC846A8783B" + + "478793609C78720890F8E1C0612C024813CF06EDA8EC84EF9D38A626C568D2AAC2AF1FE0681F800F" + + "5489657079779E9B77DC7C0185E22D3E1618C71BE175FF59C5F21043F499CA487157F5DB169FA3C9" + + "424B9D9BBADF2DA7F271F97783F0E411AD76593FDC97BC1F4810A0FDC37B34985D41F856AFFC936D" + + "F29A35DF19D74968CDCAF404EC3C439E327691C3481B04B207D8EB35174D63E37E5651F5ECE8E1BC" + + "1699EF5E3CE1C7B7ED42BEF2DC6C961900184B5C899ACBFBDD3490A7556368F548093B96DC98D2E6" + + "4C1F64E8162E5BAEE0A45B977CC742579281CD90D8B9DAF72B4F4599988F6BC69D6E6BA8BB48A189" + + "0264DEA858114C0D679EF426DDEEDED8120F48CF07FBF516ED2892020B0EC96FECFB95E767037834" + + "3438EF737B047EFA3F3A8C1A8FA6C0BB5260C3DBBB4338A32EEE0D24E4B8D602417FE0053B6C7714" + + "485CF9F070297046568B98BBBFEE565BCE6C6512A3A974DF85E98567B8B454EFBA8F5A1E052D0DD6" + + "7D451F775601A11834412DF3C799000490D97D2472C311DF7AD0A17695B2853E6EB1B01CAD304DEA" + + "1DFDEF09A880D8A7DC10DEEB02CCAA351751BDA69A0B660CC58190426E3C97A05884C95864037446" + + "0752D578C5A6050B241A2F17F6053DF5", + messageHex: + "9A2C094188667CC328F9B4F22B2C8E0E44B3A5BD0CEBD2ECDC393A7AE68ADDB33827FB13B8DBDA10" + + "1CEF7749ECCB440F1827A707D0B116953FC21C637699B39F42A0BD703BA736EBBB766E228012AEF9" + + "9CB113992A2054F59837BAEFC695868A11F85B9BC4E1C02BC0D22725A6AECDFAB1E3F8FC23C5989E" + + "3C8151FCD2F7BDE29B14D14E0C5FDC94AD365EC3BF9076E9338DE68478219EE34668FAA0756E621F" + + "95E6B51C9801889768701EC2A8DF073722C76A341653C95031694F94F74405CBF806A3C6C798B19D" + + "C2FCD84172D04C96FDF1E57A3A5B2538AD7DB5499E4A9340B29092F47505290742A4903B8C77CEE7" + + "B2EEDF8A85B75C8BFB18CCF1A0F342523864B841B7FF84DD7C6A3296E62051796E553DE19DCBA56B" + + "D14AF4F9E2A571743B765CDDF13D3CEFCF7C562A222ED6EF12AF9612687DC99442AA7EF4EF535AD3" + + "9454C5BD1063280567A55E6660E715503FE34D3D7806C800336C411942A4952DE3B611377E15D35F" + + "EC0F18307DFD0184C3C19984813D89A68B44D2E3C3151580D5DC64616CD911D868CE7A02AC544406" + + "50052F58246A0A47187E1090ED3B2E6712C584C203528AF319BDEF8B85A2249BD4BF1FF27C27455A" + + "9E67B3F6CC2A95575A00A4D1EF18C670F8AB7F6AC5A8AFCC75DCBA83938967B69774DBC9C2829E98" + + "28B434346E9A778E43B37BE3DEDCCF793176796AC3BE0C8E35126B67A70923748E5D479422E142EF" + + "467E41A0179CC902DC82D3E5F72CF66F495616B189BE0D84539380A7DFABFC055C7097BA2D56E54B" + + "C3F525B58E77070E05263F1EE69E60DD396FF6FDE88DF80137615CFF3BFC968875FC4FE99C46F449" + + "916835D7AD3466B970D2B7C4DE5B4713DEC2FB82C199773BFEEC524D57D0B0F033D55830A1D6C433" + + "E31D98B2389575C849A7B94C37271FE998D6AE71674AD70885EF59542391BB980F32AAE0830F12AD" + + "5DBA972FD836E08D297CC15C6ED3658DFE1BC14A42D382E1D6928317B4496659331D44CCD8D52347" + + "3A9B27A672922A924A5E29E96845CAA2876F04FC7D1A29512234EF9965AFEC27042A900C750950DB" + + "8E0032DD9A888D23B6A97CC5FD2872CAA89DAFC36EB9927C3CC472F668804C03340125F0E5D1EFD2" + + "F75D52F82C29EC7721F98DC20D85DDB3F017AF8A5B858008A2A9EEE9A094C3355FBD494B6D8394EC" + + "4FCD7CE989EEAC23EBC584A8074F8F40A8BF7BC0163B459DE216B0BAA9C97974C0B7DAEBC629C71D" + + "690425E531A54C1077F214E6F854A429B84212510C162811AAB54E54600733BDA57415BA64FDDFF5" + + "67BCD0D1DA242A0F0B3AF2F9E76D927EBF8AE3119AB3CC48C4EF0A2363AF63AA3CF9BE9E95E79B8D" + + "C7E9082D4FF8ADB0977869C8A81BEF265A66B976B2F2F8136741F2941E29F729528B2D89DA27AE7E" + + "65BD165CC3CAEC2E8EDDC88D10ED19F573E254FD76126DADD52D92954A7D0322F3CA63CBE76BF6BB" + + "3F69A78CD7CC56E5207707DE4AA148C988FDC8B9862B9735699F5A66D33A6D7AC09E9FBFDCF6AB9D" + + "E719C0E1B26DC24D31370654E6B65ADE28838283693DFFE159B94B0CEF79008F52AE70E10AC0B8EC" + + "23C4A4D21BC6340BAB8E39DC85FE4B57FBCBA26B59E511D509221B1AC2066D61600881B594FAACFB" + + "25A4F2014F0AB16EC932E8782118F4A57939CCC8C259B09E9088E6376C148AE343C3844E8A8B0ED5" + + "EADE7472A4FDE9473FEECA1FDDF0BFA9F37D8C5DDF9B4C3EA58C760B6034944358A9B88203A31B1C" + + "E5C6D2B9532F70B9CFE4831ECF667FA2607816BF1ACF0E12A81D4E4DA98F8E769C5BC45F3EACB6BB" + + "4C90DB6E473C61A6F762119219B777A92611660AEBBC4AAB52CA5B300D7705710A2F77927934240E" + + "273A0AF43AE140F78CD1D7431EC1EBC32254A36B4B89E101564C735AAF047BFD5584CCD7806CFFF5" + + "36A6BAEF795BBE7E8A2696F4327993F4118A603AD7779E47C0509EDC4075EAB948D5E4DE7DF38CB7" + + "874BD14D4B3B4DF4600C4D6A2548CB1B8538E2051245C95B74E130806DF3005EF58683A292237FA3" + + "55B1210AD15E9A785552D27E52813E0BEE6371CADEA3A582171EC9C0C1216D57B734875050B7BFE6" + + "AC0E231376177DBE4745C4FF7B36D7DC0272C29144478779654896D0408550B263ED01B67FA8F4D9" + + "B00D08499AD3A04D04C7D6A16A22D3AEC5A3BB6AF12ECC508F5ED21B84DCA4D9132CB418F64D1D20" + + "B388FE0CD5E01036098693248107066426FE96B7F353D603D4AC817A59DC3458C73C72F792F24E26" + + "16C66E5AE0788594A70DF42AA6E45D257F90FF240627FC77E1739C069BAD711A293D9C50785593D4" + + "D187A2555415CC64430DA5040D7763B217E7B0734C561B496248407249A03225940C9C69DA135F91" + + "E7E95DB7F7D4636AAFE5F0AB7B28E06DF17C69B3A7B34DA0C49CD870E1139808922B9C2DC30CC6CC" + + "FCE8259641F7C26D7D7D7C721BF1BD831621C3BDA06052D57C32A23D965EEA6EEF85A5653764C288" + + "5A79D133E8153A3569328CAE7BB551A14D5DFB037F1CE74EB16588562627B6A2D03E73F2019F3277" + + "3522597DAD9CD377DBCB8CED0793C7CD6BD2D31B8D7057C3B0394B4E2D2C6DD94B029647E9532185" + + "8015C67EEA66DC1B8DA01F6F797E7ACC6943D0CE21548CA1497654E3AE556D8B424D99073DC10680" + + "086CA3BACEB750A0E6459C57DE63D21A1C033FF1E7E488315AED26C91E6012069AAE32F46FA9A588" + + "683CC83786C7786817B7684FC7A12F3A6112637340B8DCAE7D221F57CCEAD285530693171FEA43BE" + + "616682FB0E8F28BA05FEDE412EF88FFB54E721C986DACF99B277DFF05B35394053926CCFB331959E" + + "ECA5319B8385FC32F6EF4D582A9751CD36352CA42D155F379A62C62B2A86EAA13F4B60D7A805CFDE" + + "1B0D05BB6DD3A21ABD97559DD2D5E94C7CDAA05364173FFCAABA2CCCB10F658BD3FE791762DC113A" + + "B52A426A82945C6B1812E60D91A3DD952567987E0E57450001D7322E40015F63E731F641AC646342" + + "393A24F60F6663062DBA19C140F96CAB6CEFCFE5D795A63C09F674F4A90B4F3F28D8777B03B2F0D1" + + "BD0AC3E73E685A5B269F4DFCA38C1AB0B527A9FF382110F1A157299A55934BB9EB7372F2465B63B2" + + "F6AC16BAFCF1975272CC0E4E6CDC4530FC0A42A11A50083D5A49ED3ADE8D7DC47515DC7D520DFBE4" + + "F943EA5DD1A503D9AE507FC420D9C7D22A68C7F8D690965D2ADFF46FB5F3817CCE637BE12332A621" + + "41C3CB74EAA8A469849171D389C94774250E9077C6459D7AC56A6CC4434C649B3C50C11D05BB6BBB" + + "57BAB5536E47E63A27BE2D87CDE27203E1D1305663FB243AE5DF1A70046E3353955E5938497F4BF6" + + "C0D0BF6886497A56C0C58C380F0119B1F3FED2B93DA70BE626B4D1483832C96D0A40577DAC1838B7" + + "9857180F555A0867A6926B12ED5536184E6B81BF0113AED8D5E2921769C0435F11BF0F74C05952A7" + + "74D35BE70B9F509D57C13DF0784977A8CCD869A8017C3B027977B13DF28ED98B5CF90979BB7AB13E" + + "8A9494A4C2BDD7C2FC01029AE5AEA17D4C1761BDDDDA31EC6500AD4F0C74AACE734E56A3FA8819DB" + + "358F17247A3F8C094816ED6549248DE1378E2CDC980C5214267DD971B8EA933A7DAAE26BBB697A91" + + "DD465B5E88D04B4DC00E8D8EC2978617FAD28EF5D0694FA474753695724DF0C51CEE731E234CE6B4" + + "72AADB078F08AFB33F54B8AB2F978050647FAB6E85BEF79B161C96724BC66BB37EBD8C51BAB4241F" + + "E4BC536AE906E1B361BEE48FFF6572FFFC96BBB328947093BEA1B2104BE10F490EABD4F8BDF432D2" + + "D0BF06BB59295530CED833CAFD33CBB8B4105E1BD8B172687A3DB9549540D72F60B9E7F34D25A31C" + + "BD8BC2BE498987C7FF6A389423928BB7B254E0FC4612BB90967C5485FBCB22EDA582AD646825BC5A" + + "3AFF6751D16DACB43EE2BE7012489E6BF02BE305E4C1C767BC0A02D047CA9971C4F345E57DACBB7A" + + "823847C232DFF7A752F52F0297804D7FE4E4FD8CE82FED85A5F04F0AF0F1601F2D7B863141AC4CBA" + + "96EAFF34503E6213FD35D6DDCBE8F5096A886E7E998E9251298040F9944AB5BBC2C975DD38570E14" + + "6FE898824289A06E741B7CF6670E830CC7378C5F52D1FC96B719676B576924E77ED68C1D9B5989B5" + + "DF93CA91E16CD42A35CC475C3F8DEAFB0534DCCC3F7F013FAC5E633C38B9D90F94CBEC3DCD02CA94" + + "E6A7EB58A8D045E212C5D674691E81CCD09793AB01BAD12125F02D846FFDC1DCA845EBC14CD2D73F" + + "0964F709DAFEFFC2505C3A8EDE73D9D168382A7F104F4709CFB17368E1D2290A26721EDA8C395950" + + "703DD4B706908D1CADCC9375DCFDB1283F8342344E6FFF2413411F6C8F879EFBAD077DC177868D12" + + "E5C2D7E1F63C4C46DEAE622B340657EDFF4B3D94A372DE85AD89B228448FD6A1AF773AA65DFF7051" + + "D5C2DF6E0D4C845F30C1514E273C89206835E0668E2109BD1C6F77B96687AF509965D12C9347BB8E" + + "F0404A4D4DF3102630A12E0D5009B6A6EF72B5C8DA75A07A0F9F413863B9C19742307045C8F82FD2" + + "37522E0602BFF0DA9D34E654DEFDBE608512467DC547795EA731CC40E454DBD5C694C598D5258D55" + + "1C067FDC1868C80E705499A3CEF667FCEB042C90140CE11D11FEBDA70C2EB41FB614742C446462D3" + + "C1E04CC571ECD4833CD1C78A4544699033C4407A3C8AEFBD190B8FA27AA3CEB28E71D47E9D15E152" + + "79F931FBECCE2B46B6EED01217F144965EEADA533E4D7D6DCDB358708A207F04D6586B80204EA7F3" + + "5FCEEFF7119B66E7E15E9E1C19B8AAE57A514993C28A14A6E6E2AE7DD826F5FD07F30CE832F7BF16" + + "471BFA9EC766E685D544A7154BAEE76BB622EFD1B2AD02DCFD6683FF3D802921679541AAF5CBC8D6" + + "B3602BDB03F2638AF34A685C1927AB88C5F06A903C99E50120AB08AF38DBB51F7E08F85D36C8CD67" + + "F6C099238149CD6F447A85ABEA46DEABBE62A3D15A594B8D6DEAA5E697F0034A9C55D61B45A363C3" + + "7C63098468230923EE8F4D3A136ABDCDDCDEC7E50D49D34EFEEDCFF46ACD3A0B9CB63B1727276B35" + + "CFB22F6A3E02386B4A41E97FAF007AB77B30ABD458D9D61EF98C3C4CD5070EC65E77E587004E7EAA" + + "C127CE41EC3497D802101F35EDC9ACB53A30B8BCACFA931883D6B447D87DC89A66989D048E114FB1" + + "48E846681F919C12BEBD05C9E8E4435F2C5D523BE6E0C149793EC789DC6A733FF9A0A1EF5ABF75D6" + + "119A2899C742D92D227A6F01514852EAD8A1289567AEACE657CC0BC11265DA9C5EA48438CA99EBA2" + + "D42F378951CA0B0562B455345CD47A96D2F333B2E4AD5D5A03C1CC5D4DB49E2DD68469E2447FD98A" + + "7EEF6E6FC0DD5D2B01D2ED69C7C2273E117B082B558AF4D0231612B9007B68BF5CFA740BEB6ED60B" + + "EC22E74285C244E93E6A5EAC3F3685F3FB5ADE97E94A4EE914722B0BAB65A86F284761DB7DEF2A02" + + "ADFB044E657C3287061F7193DEFE534DFD6532B0C4F1E442B8C32971BE8C136CEDBC953D974B4E47" + + "23EFFC90A8603251B91F67915C18BE42389B9AB3C4557703B019F3104F0D6D65F68EC882341DDE52" + + "76EDC7358FC385E0CCE54A05B144D6EC7230AD87B2A93E8155F754E2F98B2883A14BF89A41EA345D" + + "A0A5B98E8EC25C4A70C20E5CA17F9E6F870920C32126868673D9C70E8F47AE808D4E065018C68A75" + + "BA750880129C5C685A88E1EF6BC1ACA7F6D254193817C0794220F8FEE8F8F769F98B84CDCE7D59C8" + + "F3002550C0F0A1864CEF480F2F84013F43D6FD6B64506880D8A2E00C47F9973FE2849D3A5603503F" + + "8B5D4E5178D00CD998CCC765BC3B4D903A7C5311302DE39B40C1DF3C5D9A0C0A3BBAA7B1E1A3FC2C" + + "B310392A94D700C2C0FBD4620E8CFA330E2FF475FCC0E9D1F75C3DBDFD0D8C0EDF629D2A60F2CA35" + + "36DCFC476C03667978A5BF6DB1DC8E513A991C5F0D379EBD424066740572D8CE9DA6518B11246B14" + + "BB4AF59CCBCF4F46D7A39D38C068DC88670E6CD71722C36D418A3C012265F4D7D2DDC7E9C006CBAF" + + "187E97C8E01A59D9A774F106FC3EF18334B5A3977E67C46E6C7D531A4184FC5815681609A5F823E5" + + "22BA68E6D4605526F7096EBC5FE1172E873DC104FF7B94105AC5675264E98DA272027895964BAB2D" + + "825295D694571E7CBB7BF2339A95E79A50FE32808DD7788DE002137D5DD3AA7A705B99E616E50E8C" + + "45F52ADD766DA4867FD66940C61C881C39ABBCA2E46372E55869A03F1B6770B93EF89C16F3B2399C" + + "A5F8E0D0B803E4119AB54E869F4D85E10C1E90B00A497E60A62143AA2D23D187325CEF69447E03E9" + + "19AB8999C717DB81A2C93AC53A6BF89561254EBCECFEBC234F159D7BCE27AA46E3CA1B03DEDF86F5" + + "DD2FA8E947219DD0D7BE90EFC4E7B335AE68794E0CB9B14BB281E6D73BD053F21513A39F336A8BC8" + + "64AA347F725DC7CAA257D332D19C0881CEDC54D3E9017A0B3E034D8CB1558D819A4AEA143B7F2806" + + "54D0D9B6DB92F662A055F4C1EC26134EBF6FFF9A641C9A7B0DAFC5C7FEA8D7C39D40FAFD50397B3E" + + "9EB1A94CD19A316012E9BD1243C5474FCD29EF57D1941349A1C55C1D8726377C814260AB6B68A5FD" + + "06965C12F17889F95E812387B6FD81FF5D14B4769738F66FFBAF8ACCBFA6D0F0B1A5555294715D56" + + "3CF4567E95332C0C0F20523B5856A25CE9F1834FCEC5EEB5FFB8BAE20A9120AF500DCC3A94E0607F" + + "FF5992AD5BCFA96B875FE3B420AE63092EEA5EF5B22B66A2CEAD0B02C22ABBCDA5A4FD32CF1C9F5D" + + "AE6C0E7133EF5D5C0F8E6550AD0623FD8C61CAFB2D57D896D017A47D0A7398933A0BFBD528F20499" + + "A9395A9AC08CE54A2108A567B0DA69A9423663388806966A2925DC9250450532C97AD597011ACD34" + + "502C84A0DDC1B9169E4B1B2E24CD147ED05BB58DC03576A6A9832869F107F55D6588059C8566C5DF" + + "B39CC7C6EBAEB5F2E4C69EF67832BD56C80907A2A16DB3651206DCDABFF8456F512EC07D8B3FAFB0" + + "26CAD6A46D07644262C595CAD6160D731A53059B5FDBBCBB6B0CFDDC741F1B5DD3DEB9AEE0CDB917" + + "A13CB57BB4B07B4F0A349DA79D838FDF78B771261F057E1841497B526618A8B7FAA21EEEBB3473DC" + + "321DE2F3385DA64E3020C68984B3BABF2B70B0278DAE6CED27D50444D1BFFF3F41F6DADAC5A988F1" + + "700800D205D08DFFE6F0ADBA74B4D30CF7A89CC14F175730F2CC5911B2A1B0D82B24DB61BA6395C4" + + "96535B29EFF20B9B088D7B7682B4164C69BA369A94235242199DAD7F4FDB99731E1F756563C1EB29" + + "66EE3505E3C976D8A42B3D54D6B3E30BB9BEEADA1C72893E925F40F98CBB77A60E0D4E782F0C0104" + + "78C9F1D91A2CD25E180120DB67F937B5666511E5CEEFA296045780A912FB0DD99A52D45327F0A3A4" + + "440EE82E517CFE8FB760733DE69B564D1D19C9BED1176C003072576689EE16DAA3F780243CBFB0CE" + + "1551C07EFC3E4CF1B85E423DCA479CC43324EE014A13E077DF6F7C328D0FAB5F5794056DDC9F241F" + + "73A2796A66F54A1F2A0D34E71F07621BBF9C1E205DBF9332C8A9331566C6D2670C0E09AC2E9F14FE" + + "90D9F1204173098BA96B34AE07312D7C4FA8097BF3DBF91B2E765B28920C86F34B25528B3CE2DBD2" + + "2427F05FE200DD68379BB9B5925F23E3652D031D452DB29ACB16AFE4996418085E9CDB17BE5E4932" + + "93A15545A65209FA09EBF054EB396FFF3EAFBE2B3370098DE15F079C5A2DCE5682EE56B42CF14989" + + "42E255A3F2F967663935448DB4CC20EA568236F0DB4BDD5F8EE24E529FA835833C72F7545B600F17" + + "50E3E8388C5D38D041F65D617486FC3A37B0030111B849216ED1EAED9C62E0B3E4AA77D785140F91" + + "E45F0BE9C9A354276094B63B13F3C2C7BA6E4D9CEF1D304CDF2705C9AE5CCEEDEC17F5D37F048FBC" + + "6EDA0ACDAFC0DAE97425345402FBA8D9328AED5960C3016B6166FCEEDD36ECEFC2509898F763D7CD" + + "80658CAFC73054E805D3096BF3520C06720130868D5B4F00D5FB8556E4AEAC3CF6E1AB6CC9746C91" + + "EC8A492D36C1EA48A77C47A3A0CDAE2CD2552434C240724F00402DDE9AB382B9A5D0533C872156F9" + + "30479756FDAD7D23BF451F4B2E126240C6D14F8CBB1A8F3ED344501DF06E72F2A05347248139204F" + + "CDE8F92AF255FEF6ED44AAF913F64D776C18901EFC4B0CB86F11A02D094F8471CA63830892FC5763" + + "634D68FC26E2034180507405ABEAB251F18B2649B861445641D1DB1738CDC7E11E3B09AF9CFD4496" + + "5B598F4DA6C643A57BBCD559DD759F6CFD05FA6B785F9B0F9D1ACBEE902E0DC7E503BF58CE415B3B" + + "3C5377D3DD64FBEA2A99DDAAC429991AB15D8E010180F9F28FB3BED960CA05DAAFBE9512794C6C2C" + + "1CCD6E89209D7AA4DC1F22D31C0AFAD265F1204A9118B79923FE473ECD7639D430AB0CFC525FE3B0" + + "FD4FF1176329D8F6FD6288B3219DD729C9C1E9044D77F3CE3785FCF501F735EEA541E86842815A0C" + + "0294B6C145715A2DA00EF4874D88F1E5B83499BD35DA8BB324CE257BCB7738BE48368C3F5DAC02D1" + + "4332D08DAB59BCCABDB3E07A40A2438ED4136E48429E5F709CA0E10A52AF9999AED960796960C793" + + "1667192BE8D45E2941DFEEF645B1AAA4AB39ED73ECD331D7DEC94F9ECC846DC20AB4FAED420BAA89" + + "13CDDD84867762FE782DFED722D24710545C36935E72F71F63756EA8B022D1A911104534E3853315" + + "5CAD10C3A4D137785CAA1014B4BB9A5901C10AB98DBFAC88F0A2A85A4BA4BA6470EB4FF9CCF9E06D" + + "2EFB675CABC24BBA6B90D89EEAA400ABA7DCBC843E6674C407BBD7007506EAD95FF45D8D6B5365AD" + + "26E7C1BF68C22048EBC4FFB6D33F628C89D2B0117071A12D5040600AECEB70A6938FC3A1F3FE97B7" + + "CD477117333B1AC0FF4A79DBF9F93DEA88B5BE0079EE905DDC32F2EDFF61D703AEA90BAE5C2AE20E" + + "40D9F87C494CD8867DC302CA014561D9F5CD41154A5B99F8C6C228D27FBBAE8B7FC046DAC7862B1E" + + "473C4999599DC6D77B8B690AB561CE86B4C002746B20C2C65D5C68C81DDD645FD8F77618E24EB8C9" + + "3793F242820BE7E78863B72BE50315BE552BE81267FD6A6ECDEB159D4957E96CEBE77780DE17F245" + + "6ECFC6874B314AED95C06FCCBAA4B1AE14D159745156B74EEB035D30F1AA7EC5F7A3B619AC7F3F27" + + "5F67F400A5D56F4918682B5DDCE9E925E972078A59AA5489C015A12AEEC917402E365D3A7CA0C1F2" + + "8DB7DA45343FDA98CDA5E2C3C06E5DBDA171A166C7FD00F2AE609DB782B6CACC36C7F8B668F6FA62" + + "7C6827EEBCC5A1CCEDE0F1476CF7BA866D433C2FA25701F5939F89613A4B9D92B80E5E81836E35EB" + + "8F3F0E83AB5E6BBF2833020689B371DAEAAB5DF2B0300BFC639CA6D8B7E3BA7049C5E21332EBA0F1" + + "913A914647012F5EE615653EDE7FB17253406F4C50FCF9BA794A07B91257F04FE93C7161A25F3DD3" + + "E9F6D5B09E34BA517FF46B223B8A2E029C34A585D41855BCC6037299D03066BE63ABD67EFF96EF1F" + + "CFDCD16714B6535CD64192091DA07EBF75D5478D53892D505C7FD88FE604442E3EC22553D8CB910D" + + "91C623FD80C23D3C3ABC8243C42DE2F52FA932A5C3E422F93F13CC5ADCB87CF8180BBB367E5DFA8E" + + "249C7308FD83410A1D020C54C3AA194CFCA25B7B5162D8ADC580C7053700F73BFEF64FDD301E9B9A" + + "8E1DBDB5664178E011F2367699F884747AA327991ECF27DAB873953C8A2A3F3218F474D6D65351EC" + + "1AE5D55FDBAFAE9432DA086F51B48F02F49308B82E93C6E7521126488CB74E8213784EADD21C6EC0" + + "2BC4CF501291443F3C018D24D565656893A87B4970DA58012B1A0195F3CB0382B7DD1E93FC5990CE" + + "5A9622E4B9799C140D4279D69E259E4957CCAAA25F9ED55FE6479D717A72AB0C7F1A6F0E24AFCDD5" + + "BC6034C92AE9C9554F9806A7650FE8C9A54794874E5975410BA3C0687BEEE25D7310B148687AA67A" + + "CEECCBF0B4B6B03F82EAFC070D41E56EA99C44D16497411A89BB5E154E6BB3A24EA2C834C81FDE4F" + + "752400BC086B18D22500B31C1DF41D9720930F9306256482A6057226130B6E5CB961C5812E62AE98" + + "4E653BB2ED5AA7C0C8DC3F367B97B13AA62E1EB604673760B3A177C5B5E67360CA8B2AB85F0BB1C5" + + "BC778D4B6C21FD30267A67A2C27824791D9ABD9F2064385627AC5879C8D8B50ED1E12E28E055FB71" + + "409729ED3C9B0C2205F390141983A7EB9F6DA068923EC85068A43ECF9B296CADAFD722C74FD8C4C8" + + "14EBB890281DB30FB0CA514C02AB48635F79C50163200EBD83B832CC9258B5F1B9A313DBA228C92E" + + "A5A1EFA9E6EF66E1A4B51F04CA7E6B27C65AB8F14B58B1A073383B698CEC197F7E8F7FCF48D5173C" + + "AA7D2544F8282AF50CA0C7BBA747BE2571377EFE2C115FC9FA182DF47478C78E156039097E22D8F1" + + "37677BECB61397AB84F3470F632D9DE487A367D01A615D888C7DCE3FF34219B947E12CC9F5E66D61" + + "E84756D100540CE3A02D4C97DC1FD3633171D2237480F3DBC548636F113D11D33A43F0EDC58EF95F" + + "A043C0E71EDE02AB513D0607BAA8A5D9351B60FAB3AD2661146A75DECB25A037788DCB1A5A29F725" + + "42171D389E263EB022BB1365C671EC6C5D1A10150444C26F75A52DF859C7944981266B9F19837C25" + + "7F7A238D9416DDA68524E1EE72794CAEB636BC1A4BBE2B4549A87CA31871903E09838E51F379A631" + + "C078B6840CDDF1FECA8411AAC285A90ECC16063A479D1F3BA8EECC64771732C7E07EA0F4CCF75B4F" + + "E3C44137AD392CD6E80569264087B0616D827C682DD4C20CBBBEE3EF5C9113353D47C2F8FE8CBE25" + + "56FA393924EE86C46DFD85DF2D9897A5BC40C36B5F83D0223E8D14C64B1E5EF262A901C47A7E4C7F" + + "2942722DB352C2510E0D165D7E20CF58BEB3B7706DAF07E02A3932F0EAA5B3D29D428C2EDB8FD6F6" + + "FD827652FF882C949AEC6A2D51E9C1B6714EBD8948C0D4856015E5ABB5694429E1085A2F66782FE7" + + "C27AB1BE2A13E883ED42981FB8B7FF58B1DDCB2E70EF0F4BAA9441396DAFF8096E7541471985622B" + + "43569AC5B5EFBD2342C7DE5E819D5D04C2CA448C3F2BD987074D0F76DA411F8F3B4CCBCDF3D215EF" + + "218165463600577DEC1B8938159E780F248D97CBDEDFA4A70E155FD81B491F4B03592BB83BFD149F" + + "19ED557EE82DA49B25E717121D18484C39A0444B9F706B429A7266B9399EF63B9FB5E4272BDD4852" + + "60FE49868BBABD691364563239B454FD15815C318005996F6DA3CCDB825CB190D37D00F46D80C3F6" + + "A3E6BFD30D64DE6C906683DD6E1CD061F3B7074FB16150D23764971821E564985ECA4D50668C2674" + + "F27E3CD22EE8F46A9522D9D21922C1F136266033D9D1EBCC39B1C662866583CC892072725287F897" + + "9770EA0CB19E4A252DD4B6EA59AF9565F08E5A26808CDA7F", + contextHex: + "43010BCD636118A44112FDB468BD11F628FB61A136C9A81EF1287BC4120021A87C2222E3A9BDD0BA" + + "445CF0B95985FFE1E78781E49AAC8266E4B48A341C5D0132CB5639679EF97EAADFFB4DB92F8CD27B" + + "5C97211333EDFFB68AC1DC2767B0B5921520462C015C79099BB5D19A620C27C1DCF2E5D2EF175212" + + "833AC418021A5FB195B0C5574EAF6E4169112A86FF83F04ED9DF42C7614B42DB7794DB6F9EE31AC6" + + "3BD01D53", + signatureHex: + "2B9D85DBF766C5FEC48CDDF96CBA0FCC9546E48F2554E3CA6C7206A59FA610561CF82CF62947FEC0" + + "BA15FF26173DECF0A20EF9B7BDA07BA09AB053C96CC7C01060FB0CFDBA3451AFCC894B90C0655887" + + "A4C272CCABA05C2360631EF3D3914D67E5FDEF1D1DF4EA55918DC7F46F354BC91AF27CAE2C510F31" + + "CA027FF1FC6CE44156A7A66B80F9166479AA72120646F4F7804E89D17598678DE3C21A4651027FF3" + + "3B6ABEAC1A713219382231CEFC7E77353D63801DC47D05691D5911E0E4C2374E76782D39D8858AD2" + + "FA91BA0A0DA5434DF2B33070272B492629285220C8175424226AB8AFC4383D902669DEDDAFD2D8C3" + + "9F15C3B48EA97902FF1CB318D3373CE01006A5F8C1DE4E0ABC9347F5F97395962BA4A7F5969056CA" + + "0682EB72AAEEC5DB3FDBE5627423C87EFF97616630368666C09207E24CDF708F295D29D6F98955DF" + + "9984F6761A208F9E0F9DBF305C27CAC470CA376BDE41BD470E34D43F3A5D0A8DC0671B52C59E21B9" + + "0899CD9CBA9336F9F98967CBDE0CB6E4FB81A24BD7FEE49EBF66F66C3A3234FF0A1DDCA6E064A442" + + "849DC7D676302D609C56B0D9583CEDB2EB1CFE6CD54F3BB547C197961E2EBF0E1F22D2AFABD1EF00" + + "F03452FCCA4DFD4BFCAE13CF429C39D9D6C40BAAD9F64E80AA394E9E71D3A86EFCE9350975E9C57F" + + "6B6A9CDC72D5FA246643707767A9403A7A7E5AD8462A18034EF2C29B44B8D12200B56698D9510FB8" + + "CB4ADD3F6167103BE0A09680C865E8EC2CDEEE9D894A019EDC7230F1874EDE01098414495E12AF4F" + + "A7AE724DE8D3F2D08221DC095BCDF53F4EED59C0A9172F385955592CB199E455675E56F3E1F102F5" + + "63505D5C516AC4D8428EDA2453EED7E72694F3D5E7FF5A627F7595E8AA63179C57E6D4070CF7B6CD" + + "A70E582AF863273F9E64EC1955C0926BB54CFE5B8BBDD8F7533920CDD6BE5F63E57DB212D2E82545" + + "C393E0A8D1730B5F0E9400A28F5FB58AAFD6D008C311332476286C34C4AF4C328F7FC15773313DAC" + + "42B7983D0DBA27C0F88D5EEC24DEA9E44C5514207DFFE765887A16BA7BBEF48A10C37FB9476DD773" + + "A9EFEFACDB0935218153190B4F1FC5D27C13A65DD4AC49FB2824454462C662A77570A420245C118F" + + "C5D5C0BCB42EC0A72948333894B23B8004907B0BE8B212CAC8A40D35235597EC5A802721A1A5B719" + + "BBC6C38F1DD4524A4D72E22CE84159B407EB98195DA9D089997E0E5406A212B8B2C51071D718F668" + + "694BFFD3AD23D4C91DF7E585CA402DF06CF201907E96AF6D6039986DDE39C8496CA532D2390F9BC3" + + "5BE4913A4774980BD472302180B2825D692B2C4A133D29B374622C61E69B187249BFE7035AF7745B" + + "F9FD17861CD5B98520503A14B1CE48B2DC8E2574B3BADE2D1DD8A7FBEBE3F16D01D25F3A0BEBB44D" + + "7C2A88AE52C2B14C209A82BBF45D0A87DFF33489879D387DA65DA301F0703885B22F2B6049240370" + + "BF0688E33C22B912A6105EEBF175DF1ABFD0AAC687A19B0F38A8A2D950A583A9A913387342CDF6B1" + + "044357159D1C46F2A7BC2DCFADEA911710EDE71DE423789B4FBE3DD928ADF6FB6CAC438A34D87DAB" + + "0798BD27382C8CB1FCAD42B8F57BB0C8EA0AB41A73675BECA732408DB2AE434377C3B75F68F69968" + + "BFDEEFF72CB39F295AD92A691CE383A973A54F63B97AB6FB8CFF680E0D0A74A13D9D8B99F5E63AD3" + + "F50E35342E3EB4384945C741E5384608B8CA677AB8B4ACE7D74536C7012F1A193064FFB8404CDB0F" + + "16ABD5DA2FBEBEF534F843D3E53B3E0133C0CD4D00CD657A4D164940E172DED25C7E3F9E593A6C9F" + + "CA68DCA94075EA6B623D6E8B1F7EC269DF439098025CF1E0E6818106BFFF643533A40F864BDF7594" + + "2A80333BBD5949C6369268E102B80FDAAD711033D64E5D58B7871C618D58B56B28A294FB8D3175D9" + + "9606FC6E271C5D3A81FFB0CB8A0002D40CF1A05C29F90A58C6D15892670D5C579AE36040A4198DAC" + + "00B5EA9707EABF63B3843810D79BAC5D7810102A11125CA1FFAE1F89CEB3FAC8FC08A036F8FEAFAA" + + "9C2BDA6C6B3C1EA4742A88302A4830B12334BB35B381C0ECFAE3B1C241D75C30E5220E65802829E3" + + "7D6F7D633276F54BD861DE04302C4B4F74724AB7697BA32D01EA3F7D0AF2675D2AAEC67DB039A7EC" + + "425C7A43F7D2FC741407F5834B073489990C6ED54BC6E0C380DC6FE7C4A4F8AC173E276EF139ED31" + + "95138D649D0C17399376BB00D49460E141A50D8E42DE39FFD9F3396A077E70A70C87630E3C84AD34" + + "AC16926E149BDF9179B9BA11DF7C70970C6FBD30120F798D03AF0B26FCA4EB9D92D4B8E79EEB3C6B" + + "F9FD0D172DCF178DD954B926FDE572BAED627476CA16CF51820A54BB79409EA3205B0FEF3F9C92B2" + + "0B1AE2314CD6DCDD9049AA651FE360059450D0E4CF2221E6C9BF95E072AFA0119FD8FBC0B429D483" + + "267D74BDBEB235315D3ECEEEB3C0B4E1B00F7AA9C8AD120460EBBF5A1A1654695C9F3336C630396B" + + "7DFC81B9042009BE6199BF9A4B251C427F57AAAA8D9376526C409C736575C2701D6529892AB3653A" + + "5C48810470CF5E41FD5EA60895E134A3762412739E9E9C7D101868EBFD92B6CDE7167E88F0D62D7B" + + "9E38DAC76C5E327B540B5207B0B471D13D607B7C96FD5E99F375A8F8CFB6B65DA97272AED50C0B30" + + "30F671151A31363ED9F17343273D5506DF1558AD05C84A3C9FE94F23521AF15B87816A83FB081B95" + + "338A4B248D7E4DEDEF5152A6099178178623FFE82977F039CC0D8FB7DAE7BE3C292B4C2A7C070EA6" + + "AA1B2177984E835F493303B43E4EB6BFA55C73AE0DF9CAE64A9FEE88391164EA580A42C1801A8AA3" + + "83C51C6485692A1D64925E40AB060E9EA92E1D0888A0C02D45BE4BDF081BAB074E8499FD1DFA67F7" + + "9BDA200F3C4716500F7261A832BD926F8862B43C0E36F0836477AA48778936C436E0EE6C8E5B337F" + + "AEDBD4AA3996B8E312CD50159FFBBAECAFD467EEF79AFB632610106D3CD631CEC6E163D1903714B6" + + "F49E3743495FD417EF612230906BF11DFF6E9505A7E475BD9A6ABC2544BE055131E09B2B26A90AE3" + + "9E339A66F8C0188397EDF5F819960B15ACC257901213BBBD0349E45E9D92A99FD24A19702967B256" + + "466FB8C0AFE96CD4C4AA259AC9EB8760105F031528B5DD42DC21213DA66C5F9B69911A3EAE6FEE43" + + "BB271616BDFD844BB7971FD962B7BA4D021E011EA56C8727028ECECABE72F06EC96E7F969169FBFA" + + "E98E8AA9EC40EC75AADA45048C3A1E42FB4F95B5AF565E46616DC7EA9318019511D26CC5073BDFA8" + + "EEA619AF22891B8E34AE989C558CDB8556C5E2394E18CB24D8CE3C7A4C552EFA1A894604AD067EE2" + + "969F21788DBF31491855EF38A9F5830FEDFF4B786FF38549BEDFCBCEE94B30CBC6C7F50B54242F5E" + + "00D6D38FAD6A86DC92EFD7E6288C96020A0E58929CF9007830958D1B02210957F091B23279408810" + + "4D11F94616E449A343C96597925C52371221D2DC8D6CA8EF841FF2F91691D1025F1662A619F6A921" + + "23FDFAB9C10EFFB165B63B243EAB6B3C5446ECD1BCD9B612C91405DDA87175FD310B52706DB8F15D" + + "061CA04F763AA79D0210C6F3A3726A05D81A36C2A8A8F5E747499A38442A27F7D5E2FBD20FC82AB2" + + "438095D7C0A9A6A7A71630FCF60AC34A299A27474EA2A12B6189460C3C232C3AF0F3D3DA76C2C37B" + + "B74530AB1AC95336C1B2AEA230CA02FDDCB38B8BAC939B296C1C988BE2D59EA7FA63907F6F015765" + + "A9893524C0D302CDF1332AA3625E7F4F8CEB0A5914D2438700DCC673AACA7310865348370327B1E2" + + "EFEEBA4EB73D727C2A68B4EA943C8009344564C11EBDD1317ADBE4175CF28D9C73BF47C5B21AB4B9" + + "8DA0AFB8B25F067DECF252EDDB8CEEF29C01E27686E0C7AAE02914947E2A474C6456406F0E2CAFE2" + + "8629B515CCF7BE2F65E300CF58885B38D6275954FA2623943D4E9F9F790C869A22C3AC1CA19DA9B2" + + "13671D2C0EC0BA3F51646B4F108FD3ECD870935159505F54347A539D04EB4F26A4F1E6AC2904086D" + + "8BA350B9C3A7BA47473D7897DF81D7D96D8721A6FAC536D5656920F62AFC9FA0F921892A84010A0F" + + "848B55D9F159F9A0CF26A6FAE23714324CF996F5AEA6B5E42C9BF4F1B488AE9A39031386BB178D68" + + "C3E33947E1312E215222AFC21AC1F575FCAE4448183CA7E17A897CC1A16F0A83B794219228561C32" + + "7F1DB47682264006B7A6236EF9612F235D586CE9E4975F6193D03070B98B9947FA83085089B43567" + + "09D07FA2DFD216C13B58D3629397DC8A34C38DF3508AE593051FBD366507861BF3F4BCB7EAB72183" + + "A55D7D7C676C20C118BEF8EC686F1CB0F6C01A623F63483BB22AE8124F522DFD5E9AF6FFD1902182" + + "AA989FC0857B8BEBAF9A7DE45F72D4ACFBCCD08A82AF43D552F731BE5BEA6912912B1EF56E56BC7D" + + "54DC8AAEB94F5D1A31F1578253D4E9025146F1F32F5DD7E2B8704A909374858BAB4755A7A9851895" + + "171A9DCD70A2D41178DA2F6C1A37A2AEC26DF5E9FA2023E3115B3D4118D3EBE9E6F833C1B9585984" + + "30711A87FEBE9AC94744038F8AF68A37F5944E8B6D3CF425E4C8A9BC1303D8A32B4152F37E925469" + + "B4A1307809776470EDFF5E1E099457349C6F42051ADDDA9DC17B2A0EA5D2BDB11D320350C8ACBA44" + + "8F95A3B68FEDC8C03E89818DBEDD9689932C61E71559E61AE85FB8FB5BD07D073DE44B1F691F31A2" + + "C89364FFB63E024D766CB19918F3B519A2DE1A948DD57CA0EC1C2DEFDE027468D3DB047F0F5F5879" + + "D2836F998A8FDF6BD47902EA6BEB0B42F269AC25FCFBEEFD70CE46103D1EA38EB55F964B59E619A9" + + "EEF69193296F9B3441C6881479C0124AC280C12D60B32E15C2485C3DE65D0421999E62A2B2DB2B32" + + "680362E49E596B837571580D4CF141BF726247BFDD179D360F8EFAA91927E6A1F122343E9FBABC47" + + "9046C4F80BB866BFB8A1178791BAF8D2905EBAB9A82790B9AE1340369ACAE23B69DF7059885B73C3" + + "420449CE6754E24C0C7B1F51B63520A89D795A93E3373EB4E70A1C3F186FF3184F76D3DAC9499461" + + "E9655057295813023853ADE3B6ABFF412D59915B4E589F9F85BA0578B70B8F7D95DFD9DC2E59817F" + + "B0A90928DF766DF7FF7E33F9E6DA737E533E3B824292A898F10EAC94C4429508507CB5D2FEE80CB2" + + "ECD8297E5A9D1294A38D4E71958968AF8AA08FE88CFE737A9FC5177744C7E4384F3ACF00A7519381" + + "D8A1BC62E3EB5DC1F1A4E1437D30FC245FC64AD86C52985697EB6AD202C1771D8E28D87945B24D8D" + + "19778DD25AE739E2F0942E5BEE0B607B74F5FDBB2D1E4FC4DF2F631F1D331C30DA7AF0332402D7B3" + + "338FEABF624F735CC4EE0FA3B07D9E85A74210AD166E998AA95F265D7E8557BB7A93139F68E57319" + + "C7BD1B0C92D1D7F23FAC77BB6F4806E557F1B3F331464EE0272EACC6CBA3BC1514377C53BA4D0478" + + "F811E20869DB98CC3C6C0B500B9CBC11D7BCDF3D5D03650C698F8E4AFE0A38FD0E6D9DFB63A3515E" + + "69767205B090C44C2B980DEDCD060902A4BE42618236618081C0A2EC33998ACC5EC55A2C9D5E6CC5" + + "F51FFC2BADE947E8F801654DEA99055B5A2819FBD33D8A051CE310D999F76476B518580D9F0E25D9" + + "E531CA7EF0A020C185E508218C6DF9855954CBC84190CA84A123125FD90BA92092D145043155E310" + + "259F946A41E2D97CFB23436BF6EE4817360364CE705EC1A452393E98FAA81565FACB46143BCF1101" + + "C94EA20549FB543A3954BA07D67D3B82BD295C8D9A2622C061D79DCF461702A371EA68753A0717AC" + + "656F479DC8F273D9025C866D2B321333540DD6749B72EE7D2697AF5EEC45E43BE5B8A648485F48D2" + + "1A79B7D8E07DEB4B5C4EFE2128F2BCFA063938E8F4DA5E9DCB25DFC7C1A9E1E607FBA66FF3268FF5" + + "E9333CA93FACD4398FF2647FF48854FB46E71328ED1ED5515BEBE7FD9CB09F0EBB37267CCBA21A9F" + + "725B77276B8BAE0CF0BEA62AC40B1EA31FE2A3D2DBC4D1A5ADADCF035D659BB13C8E631CB97B583C" + + "4B98A8DE3127FCBD460E786E2E36B6E0B9023713EAC02EDB55A4BE8103C9DA92B6F16E1AE32159CB" + + "1C4EDDE2C9C8A2653F0DDE34CB5302DCF880655BD1432E167D74F17598108D36E4F2B3F8070E1DCC" + + "1282D5CB16615038FC13C93C918FA5E30751CEB954193F0EEACF1BC04A9DE92B5976B4DD5342EE8A" + + "02CD66B8541AC5A7CAFFE0AA4B0DCD4C9F051F157747046206D996F9BF632CCF089C16BFB6ED8528" + + "9ACACA879E23E04E57DD475B30C57DEFA069AD7D4AF64F1B5DA9D84C02D187FDA01D4BA110295A74" + + "4C723A1FB7E7D4C33BBA89ED3B4BC175180EC11A864000C00066291CF3DD412CF8D6AFF401157F6F" + + "D8417990E5C18B3AB1A864347E58C91682145C65F80F848ED59993830889295293B31610B7757384" + + "124EBCCAE3B33F95D2D889EF07EBC649116BF398271A43FA176CA4B1000B568DCFD2D6EBF2042223" + + "374294BCD6E2142027526F8189E5F7065B6396A9D2174CA8F1026494A3E5EBFA4A50566B9EB0D900" + + "00000000000000000000000000000000000000040D161F25293037", + hashAlgOid: "2.16.840.1.101.3.4.2.8"), + new MLDsaNistTestCase( + nistTestCaseId: 77, + algorithm: MLDsaAlgorithm.MLDsa87, + shouldPass: true, + publicKeyHex: + "5E29FF51B7F949BBEBC18FC21104C1CC71BD7AF21EA56A8D05D7AE859A38DED8A084A51DF3E54735" + + "BBD6D10CAFB78EEA24934DABD1B63AE8B1365387293394D32E488D6BFD3694B044A27893DCFCCBAC" + + "37B506E3E38003414691312C2240368C09B1AE2C9035297080BFA114E706978F481D2CF473C15553" + + "95D06D3B0A7A11885B15EE67240B307B318E5449840098933738567F9346B4B53F665605D8D94672" + + "3320AE02EC958E2C82A789F6A28812F8D8426556259C44A8F17395C2827C8EEC6E3C6D788DFCABBE" + + "EBA0DAF3FCEF7541D00087B668ABD7C11330368E271D7E79976A5714F7937037CDE84D872B880B10" + + "159E619112FA1DCBE417B11B3679D481E1A1DD6369208A0F9AA6FDC7C14D5C64899BC18C60444E0C" + + "38BE1BB3D0A2932BB8F0E4F07F9638E1B2FE09F5FBC22A06CEF0D9EA911DB3EF5304989E7C6ED2E6" + + "E16FC47702872D4EDBA2A36456D835EFA43E5ECBE6C56948EBB1E8F4F69168DC068FB18BAED40567" + + "BC5CAC2E194839E7281253BD8F3807CBA9E0FF4E43D7CEF746057698A3D945DB9DFA0C0F32C026AF" + + "D9801D459E98DF48135549FF0885AF2C5863ABA82EEE0542FB65344865144B88998F6671E6634966" + + "CCC6871635B77932E039A0FE441AAB8DFC499B76CF0127B9CB6CBDC887C6BBE3DAC7E5E502108261" + + "14461858F00782BF8D7E28C4546FC5D12E55EA6080AA7131FD1A11DF4D96F94A875B55997403D371" + + "B030CDB61E96C098D73681C205F9596940B739FC83C7C5EA61627B6807083827C0F7FB647F423FE5" + + "0E59C4DD21CA91E3DF6CE3C7D001598058B0CF438DF01B02FFE0F4A56CF19394D256F7FECA0A5788" + + "1A4803374A1AFB3AC88604F8A74B1BFB92E6132F812E048F77A05B9E562AE8B3E9EBEA5BB6B178D5" + + "CBB7CB2718D8A21D5B31EAD87AEC8C81C75E296FDD952C0679D0277F3983705E74AD524C03CC040E" + + "EB2DE0B8411438EA172212018D4D17FB2D9FB7E9E7044E31EDFF536DA77C6260C2ED55525ACC76BD" + + "BB9319FB7F5D64170F1600E862F55C9AB8A602DFBAF21AFF187BD41AF1DBE5FA88F1DFF4C9EBBB30" + + "0EF03B3CF3B9B62FE0B406B860D946957B44149B32F5061E941A5F18FEE1033E315BE099F75C81AC" + + "3B779F5A24C237EB9AD3610194EDEFC296D1ED0DBAF634E13D2678C89261B92DCA0F29EB258DD400" + + "67D681B6273610D5562A7BF9892C78DC4756FDE7274F06D49EB2D3F097F64D3ABCC6BF9AC765D995" + + "B0977B66AC36443B829CFBCF34894BD719F14651A2F34919C11921F3C0C96CFC110F6F2C7DFF9DB3" + + "45F7BF47B3B60538E6ED9C712CE50DA29A744BAAF8F4E99B426183C96AA465E4BE994C20A8D46870" + + "2127D1E48B231E6B35E0D341954D27114E0BB16EDCFBD7E4A6BA1AE4A55AFD0255B4E43153F20BE9" + + "D5136D39E86A53D9E8B70C4809C826FF934E564A06F97C50392CA86345857D6227C0A56121AFF503" + + "CC2506CB4BB56A301340AD16A60736F2689F74F6D88D7A00B01574644C7FF794AAC34505A3D7D0DA" + + "7D252C526D9570A8F18C8C8845266469BD3D67CA649420A8D80E831E3D8AAC8B0974CC346FEB8058" + + "648275DBAD206AFC0FA235F4721428D4BAC46728FE05B5BB6389A39007321F23E4EF198932FB77AA" + + "59BCD4442A6CAA6E29B08C529631D5A2DA7C13C68E4434E77C7ECDA560FE7BA2F14D07602B6ECE15" + + "9FD58EEE41AD3CC99B0F9196F17262FFC388035C300289475CD6C3B5E9FAC7F49BE3E66CBDC1E08E" + + "BBC57EE4B6588685492DBB8F561E0B0A875FBFC9CB1757815FBE3892F5D18D55614BC2DDECFAF437" + + "6E818228D4F9F48ECA598CF8152D0329451F771975596ACCB46344FEA8DB6881D63B42DD2D1AF0DA" + + "94F18B2839DFF0B25B9046984EADAADCBB13DF99D58953837E2E65F0B104322AE19595BE2D2E0A0A" + + "58BC46959E873731447AA2F9E947C5A5B453B25EA81791B0D92EDBFE54139D90F4A31FBB120B55D3" + + "55F9EDAEBBCB0171643AE4BDCF6E50A4E912B42304B2969CD5A41058F719CF6373595D38B5604E7B" + + "809EF7BF0AF20861B7A37FC6439608F93A78A697C4ECD734A11FE07EE39EBCE9CC8DD1DBAC109DC6" + + "0F37ADA7DB533F5B515B630D626899A3452B17EEF3812C4AD2525DE18D3C3855E39D82C7ABE3FA18" + + "50E2D3973E27C6C67096DDB919567A9D7B11A55EB501C0EA8141F2358EA0C7C1A3A3DF79727CF3BD" + + "819152F743E72DF5441DD0A429137D345456526C8779B6ED48496DDE0D15FD676CF2BA1054F24364" + + "2BA00D68B85E67F523354C0431A5EF7AED398278D83FFE4DD6B70866BC79098352784EE16584C1C2" + + "7DF49B6C14CD686F89A1E79AAE9C75C242B6DA821A00B1355BE79234363A321E79BF98DA710EBBEA" + + "44D3D3E496E4B90ADF8200DDBD0257D07FA79531DEFBF960F807E4DD78C892E9404FEE39E8329FD1" + + "DD45A1AE4EACDE6263E258887A03B9FF3B4ADCAC7668BE7AB10E125A6FFDB94272AEFCFAEEAF4DA2" + + "87695F8354AC8B32EBE3442F34937E382D0C8F8F49DC1D4069D5D8B3488C38CCA638403FD6DCF702" + + "A5A8EB589B42E09846C0A73DFB9B738F0441B677638BE1820BDF9681248EA9AEF164EF341374A2E9" + + "B6B82DB4C11E557B976D398E35B7F185F8080BB50670F1BD24DE6342B3EAFD8EE35F242024738C29" + + "AB68D5A8EC5B3D9FE8DE399A8E73B7F35DF58349229553E68625C6BEC443D603F4C0DA64CD5EFA81" + + "91122C65095D2191E2A432E1738C8CA1121F59234ED6D13D4F1315958D13EFB7279E29290F6B5DE8" + + "135D41900A2386D157199A1E29C552D72D18FA255C834B4913FA8D0166E0F5DD79B7313CD0C893D2" + + "5B4F07E8E890057319EE0298B0FFBB647EB260EEB53191A71F85AFDD48BF1E967AC5A74D47D4D535" + + "7DD088C49C2969B839E0240438A6B05117EBC17254157CDE4216A5FA5DF1F8A2B2A6BEE3A41629BF" + + "6B186DF9DB43AB7DDFC5B93D4CC94F353218FCF06EB12CC0DA39BEFB8ECF461372328A27E3007931" + + "99F0E583ABC11328FF172C1EF344D250ED86E7D51FDD9A503A032622F484053A47F824D938EB5184" + + "01DACF5C4EC09CAB6BC2E0ED3E1B1D8654547ED2F04B2FA3B60607AF7F1FC252074152A6BC843A2E" + + "1F58C0DC040D8E389F5DF6CEB947322CC831DCE86C9B869F2073494C9189BEE2A87BB885EF4521C3" + + "3838911510F14CFA2E36B87BCBC5114D1442D6173FA9ABE48CB6FA9500AAC19449C042472A38CB0D" + + "717FCDD02936A3864AA0011112FC577AFA8EC761F355A74AFFE672D222F77C6665A37E187089462F" + + "706C334C67E3BC96ED6CC4B2B8F22D335B2A21B4869F1AD1D46692B1CE3768B318843D3DA5A111B6" + + "97EEF0B9A9FE2871F8B02CB490812AAC20946C8FC64ECBF42F90BCC409116A58EBB79FD5A19AD530" + + "7EC2198391F208C497007007C95C1577B16093FFC0588C1622F2E726E707D2CEB96E7DD153FF3F8E" + + "23CCA246CB2B20AF2027CDB9A4C7C42BFC8E44F0AB14AF454741E662E094E28AD4084C92FAD9350F" + + "281D9A311EC450C25FCC6AAB131257E1E8F41DB5B01A4164C143F65F898A9629B2AEB91CF1165023" + + "8E8FF64ADA357CA7DAB8F734B9B1B488FEF4A99732159476179E4CD6721468677A70F0545764B479" + + "CCCFCFE83F413F28DC40D9FA2ABEF335370D62CEBB33F74067348969372B5C6F", + privateKeyHex: + "5E29FF51B7F949BBEBC18FC21104C1CC71BD7AF21EA56A8D05D7AE859A38DED8EC9CB51898AC5C2B" + + "264AF6B8EFE8AEE2D079427EA698D5F695C2E573234F82E508DA6F6DD8F56D5371DD26786111F687" + + "7F2DCC896D7C568C5BC78D7A48271109FCFB8377735AE0A3AB196DDFCB338575161D560CE57449B1" + + "E10FF148DBC12693A496099134805C12801A4002D20440A0204DCAC46D08331163B06D48C20C1848" + + "8A4B9488C03461DB408943944924220483A08910A5288C08018BC820A3184AA046861102918AB86C" + + "A392111930499040440820910A17901B146A54242008810458864020B2514C1411C21088D3381294" + + "264A412660C3284C190184A4B260882462622232C9C670031089814244A42232121329202240C826" + + "62128929D2B05003468883048818A50904A94DCC905148264088082C09192E0C46080A1229244929" + + "93A668D38470DBB23081B6011CB085043825598808C8462CD8487244368C9016720A440DC8B068D8" + + "90849C9271C2049183C010038005C3006444462854288AE1A04860304C12A54124206C8C080259B8" + + "10DA468203464D0BC9211B29925A4671C1820808A50850988C1B0025E1100854004A50B631038049" + + "1BC64198286618062A221521C30802C488700805528310718C44209A4488922092890824C4C68908" + + "282523058D12425142424A8C308A48989154C0201B2544CA083123A76D191244C080451435651293" + + "290487250904041005648C440D12302920158858824064B60013C68081B88822B62908C88458B444" + + "08C448A08065492280A1126A494042D2B200644269404640C4088C10487283046CCA200912267109" + + "350D02090C8A428C044465599885C2846C1B012591246C43328C58088551C004C8226A1338084982" + + "310C36850B258404A07040140943B88511862804358958025141B2611BC10523C770529660209389" + + "62383218186911A94514014401C40422A681998628E03610CB082D01A11022316091308892320D12" + + "378EE1184101901183208260A02151306E9B4804440252DBB68C9B3441E290204A342893460EC382" + + "510997851C3791D02822E132328A941113332A248224E3265213272812268C8AC48503B85158282A" + + "C0860C941051E00865034481A422400A3560944002C8A0506304464106114424258900860A8161C1" + + "48024498710BA90954A449D04860A32606D832814B944C5932915BA89062204688C464D10850D100" + + "69512422120591D3346023958920424D60984562388119A929529449212612E002415CC804D2A44D" + + "94026A23024CE3A4481928424082050B942913144E03002082802013A164CA984CC8424C888851A1" + + "422D51C224142648C1A4219C8201DB202CA10225A446314C200D04C6640CB2659B066614872444B4" + + "2C60342121998D1887808A448603986810A66803B749D386411A8444603470924460CA866C21A600" + + "1CB16512452ED1406262280E113421E0286E0120428A80501A008511C28D02C0684B38859A282EA4" + + "040EA0B42564A204E402720245048136905312291C348D1B241152A8081A178A1133829892254118" + + "6122268820364D24466121491298984511256663442921104084C44400464D02064D141220D4140D" + + "C14662E2963101118293080DA2064024921198305109840C9B32624280905AA64C8C86495A408C18" + + "1911CA1605A4865120A688D404521A425102486A5AB48980B265E2B8609942241229255C18919320" + + "484C4452E3344C0AC111E23052D3A64C22C160C9963000A55198B4090C4210A2A024C238221C2840" + + "41844890A440E1964D84B00DC4B0810A162DC89268500052249748D4220C6002221C26125C442D61" + + "042A82360821491052085240224413A38C1C4370D8C4081B044140064D8482882409261A13500C39" + + "1018125208421164409261140C51B020212902E0841020238A218589D110089A2085139284981651" + + "5A06808CA46021387250922D83443222B9695A368580068CC4128E48086C5934025B280E62388E84" + + "809110B22054B2254BC868A3824D4938904AB22D98C044A2124E23C36C88228022C941003421C8C2" + + "6449200E10806C0002281C4050CA086E43802D98166C9AC4458288814012891C4710941420501086" + + "8A966D89203208271154042060040610166659184A58066849B64161B2091B97851BA88C2045859C" + + "486EC1B240E20040FE1B88BD4218ABFA18D01964D9EA6852C520CD36B24C3D3E15A5C7B4C0D5733B" + + "E4997E3EEB9EE046B7E3A374CD1BCA03C639248D68D037E7D53EECD8B1021BB810190FAE8ABD8EF2" + + "A27273D8CEBE76B5EF8C0E6D6B5E4F34F1BF8AE0EFABCE39520BCBC2CD962162965B6B86CAD9F28D" + + "979BC01A4F9D9E6B66F0851C19142A16F50124F2B34CD38404C723227EE6F4D920528F07632DCC21" + + "0D69472DA35C177E63DF44659024805D186B6E36CC6264CA50793593EE3DE9F21EE56137A7317001" + + "AA8EA0E4D10F695A88E7EFDA5D7EB530045E1635ABB346D61352848291EDB7261B689B6AB948CBF7" + + "48C9E60F795B7C1724D36D0468F461C8E8E50B253C902B4BB54B33356C0B984B8529538CF65E5C98" + + "AA3A0460B698BEC9AB8DB31023A52A511884EFF696974E39DFF418297CAF19178C004D877931F6A8" + + "1B78F172A265E90A12701A0115CC6B8A824C63ADD43719C9BFB0508B272ED86724C9849ED688AEA6" + + "7EC14B1CA8DF467236FBAE28155A62633A8E120BD9FDBD4C41CDE65C3EB150F16C70ECECE8BD5A10" + + "8B5B852BE2B593713D38567CCC670A7CCE1AD381BAA676A6811967C0ED3354BFEB1859E310901E14" + + "5EBD25FBD7CF52A13C4E2F8E6ECB900C35492D60EBC6851F05B904233D14CAB7AC2707C482E5D7F0" + + "BF3F92EB535EB2343D031C00CA0F6B17F00E3F0D9CF748ECFDA70785AE49C829EA2960D10E0D9D7A" + + "463FFE0EA81811124193B0472449A2DAFE5478019E16868973709E404B1C2187258D591859F20A8F" + + "4D3019B187CFD9CAB8494BB1B679D1BE6182DC9E9FBD4CEB1906A3247845F840FAF1C0ABD7F897FE" + + "2D85E4F7BF658A73EDB60BB0708CC9C3FA8A88008E856AA429C68C8FF477F755CC290E122AEC194C" + + "C68521E2AD4606381FF36D15912B7C31108BE8CBB055330E720E4F995BE8F4966CFB00117F153BB4" + + "EB20A9244867E24ACD3D3AFC5CD00B4F8260CC671F01A0842706CE2DE132176C65EAD11C89BD8687" + + "B8991E9AD063EFEA7AAF5F9B1EFE5DBBA6D041911215E7C0A665D16CB6CBB73EA9C1EF7C835A8F65" + + "8289A08294167468FA47BDB67699788BF99E16A267D9370392A212F4D6E26E959676C85CDA063B33" + + "7CD989E4A7C3E9FB50A9C207AE8BF2B5AB340BBAE4D80BB38C2CEAA3912A5FA0AB47EF36E931D78E" + + "D4C19FE4C82414685484C9C9E4DC220E93B309457FFB2C7DBBFFEBF3ED610ADBC55A0D40BF8DB12B" + + "114757E7BB54F34712952E2525D154A8EAB2DFFBD26A4C6EBFAB4EE20E15B8506A2A502DF6721FB4" + + "EFF7D457FA45F7145B690376EDC2CA49221DA69F6A7EDDCAA4875ACA1F0387CE2D2356C13A15BAF8" + + "2EE368C6BFF70C9450ACBD0562B0D9D3A66BF183CD3ABFDDC6C2FFC0D910C53E0B31824BB6B59FC3" + + "47D905BBD6AD9D7C06F68A1AEBA355A94AA62D370B69E2C6217DDA39C384AA97048DDB165E88C2B5" + + "65B7B3F5310FFC9717940A9CA8DD5C1540282334C902B4D136AF87666736435891EE6342B9025420" + + "B7B68BD72FC432EBA6AA09F3D72D00DB842F49CCBFA2FA741D0F83C2257E207BCCFE4AEF99EF7E23" + + "7A1F10370B2E2D01F6460CE2C0921D6E373088789C0463999FEE4D4BE572CE3BC60EB5B8B2137FD2" + + "C2ED51117AE4001ECFFC7297F577CCDEC02E045DF763464CDCA40EEBD7AE513C4F5078FAF9208196" + + "BCEEB634ACEBE72907D8DC7AEF938798F672E79326E950CC352DA7310B30BEEF95591E725F5D515D" + + "328387993786639443820DBC8F4D0B3E1B965E782343329D3AE7BED32E7E5998F96EB9B7E8496E97" + + "26F4A1F92B04F9DC6C94AB6F548D09AD85EC485655750B45842A2360D0381BC6666122B0FF14C921" + + "908ADB76E0CFC4DB3D4696CA97551F67D07A0D016FBEAF9EE1CE7E87DCC910D5380964AD5618DAF8" + + "DCE317A5A6E3AA568390C35E267DEB44791A972154899B6BE563F5EF4C7603A6D3D7D5C5730CEFDB" + + "1097E1DFE91DEBA887A31914E2930543BB09FE1F1658DE76E87266EAC439D1B30C61FCC9B388C364" + + "F7A679FE704CD31601C1692AD72F55DECF79C5A349E651057A714DDBC1BDC3E19E559BF455406107" + + "A4B626B6CEE0FF322D42B296212B5072582066580CF2ABC08532E1CDB92C30236D626D9AB3F75358" + + "8D1852D5E1F85528C16B82494F94BAFCE8D871AF1E7A854D24DD93DEEDE0F8DB7444A125B10BFD0E" + + "700D2715DAF9165C11D77DDF2ADDC7D78911308A1C948C324812C2FD613F406728F9DEE29E0ECF9D" + + "C7AFE95811DA65CE142A6D204CAFF2CA34225AB3D0F3C7B722F70061EE99C75F60C804C46B4A710D" + + "9C60080A9AB0A06CA2E3801FD46E5C115D087DD0A65CD5BCBBD839FA64EA4742F552790C0AA453EE" + + "4709A8399E0CC5165976B01FBF192CF57754F276A2CC436E8ED6461C153586E767795AC850E27205" + + "D3A2AD3494ADABFAA1D15181281B83709B6B118D0BFBF403B78BCCE5F35997A3A60ACAD897156275" + + "53B5D2AEE3438DAF008D01D71954CEE5E5B8F00BA829C3BCEA00A7A1EB75B28CED2AE0F4506D7003" + + "C57AB97FC35DBEA1EA79AC004447F2636866CDAC0FE35536BC6468AC6892E800106C032488DFF0BB" + + "9975A3798D1401FB4DB2D69355C1A7B43D6D86350541AA5A18B4FC9CC6878D2A14BCD8D97EBC1902" + + "3C3E548A459697E05FEDC3D37F2983D5E388C4D8033FEB6741973A2C17A8F35A88CAEA9B093D205F" + + "EFF41768BA6E51003BC3DE6208098FEEED00281F2BBA75308FE7363234A517E82A7349191CCBF7A6" + + "B92A743B439E66F775326F0759F4BF880A912267F6B8C30D9502548903524456974CD9010E179B8E" + + "517D29CD02D9D624030F798E1D48B7C4467231DE5ED2E31B4A1DABDC33B4100351957CD81EA9A1A3" + + "BD49590BCCA13C2E63975164F264957B5632ADD2AC8C4BD03069B44CE949F262433C7748CF24B5D3" + + "9E25D3AF1C72E788FD8F33EDE6EEC364403CA4F4EAF664022CF4FBC0BCC86EF73BE371E906B32BC7" + + "0B92D53B035F6401B24CDDEB453CBB3F6EB8F9D1E7B9D4678035DFA5977BB91B7BE8434197D5CE55" + + "FBC3735A87DBDE752D714B15E07AF3FB7A5C002C0E6028342DEFA7FF9F786FF29339FB779ECBF2F3" + + "DA26650121BFA31D02DCFB425D6DB2216F33F29F3C3869F5ADB2B03004767A088E11976F36FBF656" + + "86E936858A6AF43D8C7EF167AF747BECB215351F64230BC8BBABCE8ABFC8BECFA6AD3078956D6787" + + "39C4EA1666E43878461430EF3688378835FD08DC940447D3AB5B6C33DB803465C3976C2774EC5F3C" + + "53C95E7F41BA93503043F9D379BEDD2AADAE8715ABDFEFE5C5E03C248C748FC28834A32B27E6952C" + + "09FE3A9A4B91EE38F9C10A4DCDF1722E3A34CE7DC1E2DFB50B52086709817DB5CF7EAAF9CEA322E8" + + "6681E48151D6F5B316768C3026B070057D4F710CDB38BB5A159EEF4DC875D4CACCF30C975F9F7ACD" + + "D9AC5F86109C45CF33883B9CE77CD231FAA80214DC384AEBEF7FDFD8DC24911192A451F91A027D06" + + "8ECCF27355969259CD3C7D468B52495237A4E2556C59DCEEC1EC975BBBE8DF50D9A0F01362177F65" + + "A7C1F9488E1C7AF207D3832543A1C33F4916C05417632C9A4A76F0D5952B4FFAA651CAB9B4F07785" + + "DA348C3FE7E3347F7879E7E47724915E98E5C6A4D4A25F2B991961E70034E82216BBEE8CA3990C67" + + "6B82F85E4F946C58BC9B9157DD68EEA7156C98BB59CC8397F07948DFDDE28168BC14216E22C496E7" + + "085CEC93688712C38A04528B1E51107AD2905F8A5BF68D29D9399D5DDA83DA4A804AABAAB1A74FC1" + + "FD49D2AEADAE98BAA5EC95AB3956D7C9ADA1B44D223C48F74B02CF01A788DD36E8FE9CA57698258D" + + "E3DBFA2C3EFB55FC5349B3D41C1C53BD3220CDE4978658B4C663D5DFD3B8A896A74ACDF69ECCA62A" + + "2B49E8FAF238A617E01BC7C35A9EFD8C627C972479371E62B54ABF535284A68553F131B3A98DC279" + + "1C36387EE1DF0E96DFFF1EB0EA5AFBEE2F5B278B459B8931523C00CB324AB60215129C8E9C33B904" + + "2B0CCB303199128B2C292F6B1608853D4DFD476C6BC6F0744E3D76BA6BC045A3E71C191D5FF9ECF5" + + "A7F88A5ADA66F4C540D8A9749EFA0AAF27076F89432697BFD0CA5AFF38D41FA539EFDF5DFC50C8CC" + + "D319A236DC68F3F8F4625BB3E3DEDB814BBE963A27056105F76E1D4B1ADC878F4B7AD8E12FCB1AA4" + + "78DC431FCCC02AA53AEE24903985B5CF1AC09931F29F9F1EEB2FE02BF9F9BEA1B7E3895ADE472343" + + "BCA741B3E2CD00F661E5A1EEB131DD6DEB779001CAEDF61EEE210DAC7E94161C56D545E6FDD5C3A5" + + "78AB985C77C456837D7526AAE13A2F040C0B3FEA4FC63AAB1276CB89C247AFC09DF522B1B2F46A46" + + "9E17B872CE7477240008EF4B7A91091CA47DA755BF366C73E52F6B30651303924AFB74A3D1162FB9" + + "C7AC2215616F1D7CC13065A92B66DEE8991E4C4B677418AB48873DC1D3836A9E9FDB7642AC7F25A0" + + "455E103D2B87A0B62D944F8D88492D0226E2A63BEEDDE4FBA01406C659BC58C570B5A5665F3BC871" + + "A1320E13D21762C206738BF11CD7874244E2E4F189BC290841B36F4E43280F68F50C4E689CE161BC" + + "62ECF6E8C994B3BC4C77FCA52CA1AA25C387D277B6D2B4AA1AF66A8D992D0A9F552D5A4E901C2BAC" + + "015DC3474636DF3B481A0E4DF3AC64807B20A0BB735699E3FC181078AFCAC600761CDD0BFD6CB840" + + "60AAD2888003578DC8ECD26649968E4C", + messageHex: + "3970F1A45BB86B4D3C88F3E3916347DBB96EAE363FBE5909EBCDD4BDDBD20679E5C3259071A96AD9" + + "E13D7F61A1877E0A1FEF5ABDB87EFD5E01624EC5924D8ABBE9956B106E67CA132B66B53D1D5B6C39" + + "92660A668EF00F50D394F73CBD963F967A9CBC0EC011712A55E8ADC7CFD1F3F99F0B5BD1E40558A6" + + "A32C21E09120FCD92E840E11540B45EE38EF6CE796B37CF575895CB96F6D1B89AD101A0500AA19C1" + + "CF437A4CC66882FBC4CB3FFF8F06B6BE32228AABE1CC1DA8D0D579D70609BA78EEFBED4D71AE17FF" + + "353E868C16EC5F27E7210FBA2208BDBD90ECFBDE68B7394B5856ECEE2D9EDF42DCADB49E89AE94CB" + + "B4E28F405412CEDBE91AEB51F0F4ADE9DC0F3AABB81309766164CDF1E3A6D77C3DEBD315A1165A93" + + "01A401371540A6AA9E9745612AD1B787F73056AFA6D07FEA520092979F4B802271657D709A01A7B7" + + "1473C16391297DCF8372602238CBF87E159B38BCF8BB1D5FFBD68BA7A03BF958528E7B9E4F95868A" + + "BD8A53BCAA7CF9FC0D1EAC9359F9468F1210F817B43A59D72F0B9E31C8059CC12F91B63F4B2F70F4" + + "EE3FE2FA122864F0C043A4EC56B61B73C99EEC1B70E83CF018BFBCBDEA06D3B6FD4FCECFAE23751B" + + "270F1904F6B580EB4EA0451FE66D43BD0F911D88448B00DA489AA1D7A26A140FBDD389B4A54B8136" + + "470048EAE11C519E26703AC23233EFB0C3BF5077ECC8EC978B273B380C6A2D495350BC333BC49998" + + "118D9F8E029F36F90C951ED294D487043484AE7AB4632CC5FF3C61692CFB46E291E44C73CC201C39" + + "A1EF9B39302C85B5BAE92F82A62B7D5E016CAF1ED9D8E9A7CF4EFF1A8A41ED630755A531C12E31AE" + + "5B3A4215A3163190FFD6B5BA84248F47215D6762DBE0F0FCFFD298D8BC7C34B626344268200A0537" + + "B1DAFA7A3EED36A02D61ADF6E558E29DA26220A84DE26BF951F4A7BBC4BCA9CF544DBABD7E935F1F" + + "7BE6BA277686ABCEEF0624CAD959846B98790E9E0DB286E889237C9026D2A4C72DFA02D24E03735F" + + "93B46D4AA533F3D0DDE18F235B8D1A7EB8092AE9E53E835C51CAFDCC2A624D289C692C27303EF1B4" + + "0D62CFA92EF5922AC62D349B2B10C8BFDC9D8897E70033AC8BBE19EDB8E0ABECA456F9AEFE5FFADA" + + "61E4CD5E0ED8E6B656E408DB2B960A0711CD0828D0F30F938B427312C61FA4E479B42DF107457994" + + "E6E9E1C774362F1868C0CEA243738E8FD6D4A3886CCD9F37AC7D125AAF73C7DF6F4C9C5E83E5682E" + + "CBDFDF665650618B0EDD64CF24E9E0834764ADDD64FAF8482625F2A4FF9C6C3AA4C7714C50E79B59" + + "5A7654A7BBEE0462F19BFAEF200DF53C2C304DF2A9BC02638420BE294BD11E4254CDEB5A36257873" + + "179C6001FFF15B62F0BC1E6F29EF2746D08BCC34621CFE529CFAE07B70E6F94B9F76E2D102D2EE51" + + "5420454923BB3C35495B40307018EAFA6D63D4EE42B0833606422A652470A111BB3D4D4C176BB570" + + "E8232CF31CFF8ECADB0742A4E3AA8FA26D5CB5D92C2458754F5D2FFFE3C602AF07B898D152F092BC" + + "1B568A7DE6F16EEB3C3012191BBC2980F57EE4AFBCA921658528955295CCD38075D19655A54DF433" + + "0CEBA8042C87D89D0A2E9D2570088DB1AC2FCBDB257BD7E5353EA0F35933AE93A455B8495BCD9550" + + "04BACD6DB108BF16C5F08854E19989C53503D2C1D7DC57D89B4F2E301E52A13583AC74AE400DE908" + + "0077D0B10B4AE2D385D79CFC0218FC79680E7A9B11BF8D95A1949EC46D0E9CD100D5DAD455C0E615" + + "EA3FEFACE843C92270E2BCDCDEEADDDA4C2671F160CD1374838440CC3B6D5B25EA5985EE9ADABB13" + + "86FE9180831F5540A21541B1E5D16F702E8986A4565020026240FC342B80F08DD757C3CF3D42FE0A" + + "28961D5C6FBE65E78DB06E8A67936A49CECFC2822A7DD7BF71B16F4BB8FC219D14EE37C19AEFD125" + + "C226B2023F613F46A27BCB5EDF13F85F57B74B41E3280E3FB3AEECA7DA0DC59A2EA29522DD2F77BC" + + "F25373C63CD44C019512CE5F89FFC758498F32B71E329A164207332B148E712617D441AB8058CFE5" + + "660BD9742407A261CEAAB14F558E9134FEF41F0BBAB20C6F86F3672B619603FBDF8746B066980B61" + + "13EEDE21FEF8197E00A3418353AE6DACBB400D2F69B550ACCBB0476F0D91D7407873BA285FC8AF93" + + "22D1E0B243CFAB27F753423DD883D4CD163DE9AE8C3B4FE1558453FFD56500FD7EE5B33E8266EAB5" + + "5ED4AB5D732CC4CB728F8D5FC52E79D50F63192E840AFBA2B1B56A9D4F475DA49DAFDC06115F456E" + + "B2D70AD107B1B3E9830286E00A88643ADABCBDB89B77A37C6195107917FDD7964323B6E945D55F6E" + + "6D0614F2C4BE39AE28F303E9F6889269C14FA6671F21EF98F44B9E44368D2EDDA5B3412DE064CC07" + + "FC309A0695CCE1E268ED7774B20521AF34F55690C635DEC3FA98B5D76BFA5638C3596C41D0238D4B" + + "DB6579155129765B8AAC28379C8F6168726A2A2218BD47E203C89D2961AC5B5C2CF320279E512E25" + + "BBCE94B3DC59006082CDEE2C80B93FFC8C18667F4E31291F5F05909DF0E4366097ABDC57B9D4FA6A" + + "47EB5A8ACCBB62BD91110CD5B1C5D098264E87D7C3484BDD58BAE7E376D00D99ED18441EC9506EE7" + + "DC54E63CC18F1B7F8E5328C76DE7828C0924DB3BA33E11774DCE64CC445EEB4F16F5BF46D4550233" + + "F58B2188485B6751E4897DB59F85DC9B9ABA91C3C2110AB0DB7123D439671587D97AC07FDAAC32DF" + + "9127DD4E0FC7C039C9F9ADEADCDBADB60AFB347A3AF979C2D78C7C5FBEA69448A46E9F70C714AC10" + + "EB5DCDB32AEC1355D97E266EF4D74D3197A463BBD7AC9797ACD7D6F0318735306A2951882A10673A" + + "47530B563E401F7B5ED0F7FC4516393DE5F8C491275AA9E5D564AF1453AC028FA0A8D111EA7D8F70" + + "69FE4ADA6C0A94193DA5342CA008E31964F6D3CEB0887AA9AB6406DA3077E31924649A0B730EDBA8" + + "32609DCD55ADF4A7830288CD96B4D50309BEE848B2C77ADA7289DA94AF661BEDC36A82858C846894" + + "ACB8A1AA5155A3FEF94A718FFB9E12B5E62951BD41A06025ACDA233AB3CE4D7B4DE4E7C57C6003C4" + + "471B350F8BC8C7E6A43654D9FFB679937D1E0B551AEA1A2F59FD57C385B7EB3A025173BB34DD43B8" + + "2F3E25CEFEA779A5A86C7C679B0616BAD66AEDCF80F725C9045280795B2100FA85A65C31A5F19947" + + "CCD7BBAA80EF8D83CACEDC34D7C95E8C6FCABF97EE467D6417FD57298AE189B39EC598DF839494C3" + + "EA6FBFD88618F7DCCFE6122EA5380C64B63F3F15B378F38AA7624DCFA52E7281F964CFFBAA34A357" + + "120AA17D6B3116EC943D0DF6168D28BA6B690C2A6F09E771637D60BB24A1A2C43555A2DB325EF3B4" + + "8CBCD88CA0D5FF5920F49D4DF8D9ADB4E5D4DB5FE5A3A86CCAAECB16E648AE08B705031CBECC453F" + + "DD455FCD0E6D72016C8924E166ABB990D99659E614DD9F7FC1ABBB6BDB193E0AB6420A9F34810324" + + "94E0F385C870B37271DE35FCD7FC81E7E5934F129207E25F0FEC521A1D2B6F0F9330E296C5841210" + + "BD4D72BD794DF7085C28CAA39196557676B80ADB8171C0E49CAF4ACE04DD10AF36E0A8E87D591819" + + "C8D38BDE0F0BBEDDFFE673D53349F06635F0169167BFDBE706DAAF4F74545DEA8E3E2471D7F5D5B2" + + "40B18DDFC51689E52F1C3DDB43A657EC4562D3E4BEFF8E8CC539ECBD2F208372CC5A38BEAB204ADA" + + "BE6D4E02E122237AFB53925A68A10C797039FF0FF148537E1F1FFE67205340D7BD3C85CB78FEC6C5" + + "49DD06829FA291CAC15912ECF808164439C601A8E86C5701D632FDFA6BCED28225F718078D8C4520" + + "C7E6D47855160ABA36F1994A81ECBC61E4930FE4C359B095D1670302C34C36D3118394A5CD3C95E6" + + "16C0531B64A4EA28F9DB54C36057A35C8BA2B4EAFD217B890DFDEE6B15B63C3857703B67B53B3786" + + "5200233ED643D100EFAA5B0A75EC56522809579B2A3D281C192A0631579206E7AC29D75373A49365" + + "9919A93ED356635DA193FABC23E3B02A5396E369A86A1998E82E60D84AF8E523C67A7FDA677CB3FD" + + "94AF9C702BEF160C02214B59C759DF19F410BA8653F70D3E0325AC39F0B24B9FF0AAC388840DA8A3" + + "B5B3D05736E94872B36F8DB31BA4A75737207DD392CCC0D279824310CB938881C3D62BFB4F455F81" + + "F93F05B085C52134BA8F1C0C8F6B79E1AE1F9D966B41B1B82013783DD862E6542D0D3F0CAD6EF217" + + "18AE527D4CA8953C13045D35998C8E384BB21F77DC3AE30C0C68B524A78DE50C553722F97AFD6B3F" + + "8B5577BC6FF3BDE331E79A937B474E3BA8CC7BB8E820918BC0CD295670C01FE6459ABF2B758BD988" + + "219E443919A6DA7E8E93BA9AE3B1D94A80ED47497BDE817620B33955C5DCCE62665F69C26A127908" + + "16A435F136409A7FF0840744EE3FE78A60AF4C92AEF122C384F0DA7E31CACE883136886269E1256C" + + "46E846E89F535340DD9B8C399BAB3E9F079ED35BADE068376DA7974180C425ECE8E73DED902A6257" + + "4B875F99013C30C97809278FCE0D5384D5D71202AA9FC83C348E75CB74B6A92F2EA16901643E0E80" + + "A942E049015A7B5EB2B1A33A5990F9B488C4D710BCD90B595329E9496B063679116C92A45451000C" + + "9E32A47F0FFC5818EBD4079AB720ED3BE6359A026619905631B336B2A8E4898F5E8F30A915F18EED" + + "2B5063FC5C672D481E3A88DDE15F9BCFDCB9719DE984684ED16402E5680B766F127B6101E96D10A3" + + "51203611335AF4617499B58C61A1698D524D696D0A7E68554CBC38D5C10F699246D23E5311BB9C3A" + + "D10D64D160C32B4B51231153FF5775907348CCD095C56ED86B164F8CECBAB064A069C4800FDC9D18" + + "8CCE9B30E8D5A8955F2B0DC21F3DA4968E73AEFDDBB819EC53F928A7ECD5BB810AEB0D395CFD4B1A" + + "142B4406A7035DC911B156CB5EA7049908F72D33EFBCC0A431B4C67D06B547E43E0DA5E05121E480" + + "2D1764AD79ED36D06813EEA4E18A27B90B96288B848BE1755FD0B995786CADF79C0EBE1676CC3B5A" + + "404A08E72AA6B4F7A21D4DFF18808FEC2EDB79B548761B71FB194B9682C9D75896410B13770F51D8" + + "85010C93DEA910E7A440E04E24D19B4B5E80F77C7F39F9AEB12BA82967342C0E299E87E3C27AF1F2" + + "95CBCF7B7889833F6B7348A41D7A770CE4CE0ECF9CA6B274BC58D7A81106BFA72415F6F746DE7CC0" + + "FB45D01AA8E966004698EA812115078CC21659F5497E843B8DF18D847BBEA5CF5030E5A333758B15" + + "4D212695424C98B29971B5EBADCDF0E0E8038F34FFB4216D2E2CCEB9C8A1FE780106C23A5F6D3F1D" + + "258C389D2BD3FB1EEAAD4531ED8C1C0F5B86038169BD3ED20FE1BEA9EBDA8E2E347DC01BC37DF431" + + "AD387706740D59C0AFAE14EE9B739AE6A8FC1A1F05A95661B4BA3E464DCCBD6F749FF504A3E6CF29" + + "00C352423B43E873C30EE881ED68D0A33C1AED43375A8402F0503184E75EF4907E0788D54C937CA2" + + "FD75A0D1CFAEC0A523DC6297774D3189999FD5B7E5E6E964E0B72FAD0EF47F9EB2659168E31EA2C5" + + "08166BD0C2D448AEB496CACC312E078FDE84F07174C8BC8FAC246CBFFBE61F646B06E6ED76C7E8D0" + + "28A375CB832BC31E248D4E02830DCCEE04E197ABA470522A614EF7F44D2C1D2D86737F41B7C17044" + + "D011304D1081B363FB331993F46F44A7E52D8CF470932F55DB5F843671C8221E748C1BE8183757EE" + + "4268887D81F88C0BA9F009DADFE4D1EBFA4984686FF6CB84B19B8B817AED98EE076BD9417F2A9E60" + + "C8F42C3D4DD4BA000E96D6B1255E5A1BA908A7205855FFD62D57AE99E5DF81D1FAAAC7C911758C58" + + "BBE4D67AC4C645B505BE2001FB980A8FBE3EB2DA2C76E4E5109B776B145FDACA09A2B863E4BD14E0" + + "31DB0FC9C5926C7116DB29EB4096FB7447BB38D8A677901487E594670A216BE72AF37027EA2CA149" + + "731EE2A47461B09E09C2854FA43FD3A203FAF666DBE090F9809D4DF0340437CC0BDD177A19930F7E" + + "4C70479A1AEB8478E3A52C22F9AC268B99FC3883DFFC0E505D9F3B29B7B7482F1CEF13026B29F5B9" + + "202DED4355946C4706CF3261C32B6D5F72B3C310A5A4A5D1E982B665F42D5BCB5DFCAE4D5B810420" + + "AFE1CE5D8831B2D355072FC6F452B5CF7B49C45AB51C28D52CBB9276FEC366A27AB8625A73211AAD" + + "DC6B821D028787EF72AD10C2237ED8123B427EA3DF8F3ED724324E7B42277C8B0BE8D88D2E6417AA" + + "5F71053D9A8BD4C834A582F0AC2695B5F9B1811931E66178EBAB4DF8460DB7BE322ACA75443888A6" + + "4B7F62A4A0673659E01F9BE6224AD429E64A762331204796492258E37F76D49497A463060F48C261" + + "CF7E198EA301E08B0E49EB19CD204AAF8571EC62C805D8FAAD3EE803D5E373D26443447BD0CD0836" + + "8521E9577182D37FA738E9821A27A513FAEA5CAB3766ACF7A15D9CA1A0F1E86EF4078A6E19D2E40A" + + "EA1F6981DB142F01E5E56DB93CFC3D0F8F0329568CBE9F10BAC4974A288AF967A398A774753BFBCB" + + "B3295F4002A3338B52B2F8123988A29294DFBDD6E0E32A4525705C6F878FC2881663DE2F5034F077" + + "9A772E52CF1FD700082F0438C4112F9258B074F21ACD038005C8311188AAC1981781E70F7682F59A" + + "62763D8A0FC751477467D912CC07F88187A4D5C5B93A7745BA14001559A3FA32C341FA124F8A25DB" + + "8DEB4B00F07CAD179640B370B5B8DC5D898D1535A2DF33C068C98F7A1E8EC23A158A7D959701D2CF" + + "49A3F48C6362FC52BB19A111C53A650B80E201C24CF6BA8ACC17D2B10A97762B9EDA6F08EAB4A269" + + "8CDB70D9198F51E73B882D0D2C71AAB8ABDE4006CB882D2CF2BAA01722A193AEF02D34F6AF66690D" + + "1D9E3A37C368E63FF191AA7E629396C1D21F3F829C6F8676C0F17612B19C49565DA39A6249FF4B32" + + "3D3D86A817539F6740E593F9BCC7B0B70083370F9A247D7839C2D201FAD6A66518FC4A4D2787FAF7" + + "0111362E1483182FA49439F065642E878BAE2F114BA0787613A87CD5F6554C3A749C74C8AB082769" + + "D41DA1724DBA0D95D140A274C16E9475DAE2363CEDEC4D460786AA72FAFFC82D22F180DF1552584A" + + "E469C1449B54C11F0F6FC874364A5A54FDB7C5A605F1FF92853EC8828DA3E5A2566C8647404BFDCC" + + "2CB064FA924D6BEB740E82FAF4AFB76AB1028F9920EDCF73695AC2A135CE6280B2BA55BC5BB19514" + + "D7E9705D164EFD190EBB16A3CBB087826CC0AB276143D4E46B9949F2C8C625C8A55A4AA8703C3315" + + "8224E40AB3CD19FCAC1E82817A3A6F2191E19949637F3DF3C5CA70E5AC33A1EF412562D16466C604" + + "E2AC7105B9EB931640F6DB112B753AE4F5497079D2FCA81D243C6D0D51AF186DF2C5BE9E64323C36" + + "4443E15551C52BAF33B4807CD3B9CAA14BD538F621D75A224C2DD657246E9876C643329C9EF4F35C" + + "328FE4ABD1649AC91CE30CFDA8027977E0804945225D3E175F52E16D82E68457D2E1F89B4E3AA296" + + "72F9B46385F8C8A7B1B583224CC63D2A2A33E573FB0DC2D04692F570AA2B2D63A2960B5F88694B45" + + "C6DC7A45B7CBEAC852A2C67C9D452C7E583CCCD13E8E832CFB3AED368F8FCDF1AF83B9278B1B0D12" + + "6333FF2D57299D90CC9BEF565AFBC97F040661C4DD4DFC51D01EA53BD5F819489326CC070E87335D" + + "FECB838BE19E0F55BE8E20A564A039303A0DB58B869C5C5026D1F46A50880E24ABC665167E375F86" + + "A92CD73148401987901D8F1CACDE2364E202C24024B98196C068E57E28CA4DCA2A616AAA003E52E9" + + "111923D21ECF8D91448DE1CB0189E813D7D8709A2A2BA0B4EFADEB397068F2C3CDC4CA0DCD586F31" + + "0310AAC97F3D78159ADA12F3021FAEDC26F12A8D0090A2EE576008799F83EEE9CB72BAD808C7A61A" + + "3BECC912564923D63E6990BB423AA4BEE9B2902557B30164ED693C26F6EC45B6AD6DC8A44E8BA0E7" + + "85602DA0E7DC530799B0C54D7E53870490189EF730A9366B0A789896423D6EAEFF0E78DEB8927D8C" + + "616DCF2C58502E45030BE2BD3AA0F6FE3EE5336568B47568DD1D9DAC998B0F73D6D89727A775513D" + + "DD004BB7A64CCB9DBB116AC7055364F99477A2A98D0C464FC28809063DB210A9AD39B9CDAE09E07F" + + "C62BB9DFDAD2FCE0DED5D9B81EFE7797CEF9C186CB92C975F14499023443CE6D2FC0A705A3144884" + + "0FD598072701ED473BED117D7710406E315DF322560BB577DC00B90C45B384DF7638970C01FAD2E4" + + "67F00EE9BBAB6EE9CDEDB828F3BEBCA6E19901F9E6553749D7CC28E5F90D5BEA85E7E113B29711DE" + + "F9A0627DFC5CAB9F1E901A5CE457CB4803C081CC8A68892F6AB5849E5DDB37FCF6E551B29E3B0A59" + + "98B24E833DC69F0A853FEEEA9307C44B5200B807B544526C14572284625188F2AB15D44EB3DC3022" + + "BD3AE3B0484C53196AB304262DB66F6D0101606DE85D4468EF3636E7212EFE5727E5BD24B1536E74" + + "C40BE1A6BA7729E2FDF57DB13457087B5F9403B6C018244B59BF9E56986C637EB294C4F1D8A3FDF3" + + "ECF7FF467A5716C63C569114D2200989FCB94AB86B16DAFD3BF7094A1D45D1F0A9D5D7C9A22105A3" + + "770A6D73699F76BCDEE236A993A7C9C3C1A16880FB8ED0A9C9FAB448DDE76C3363DD6034D99C9FA4" + + "7705D8EDEF9BEA5D1EB4B10E556981D73E460F0843EDC1B7D026457E05E77873B0BDE97D650EF0D8" + + "03F7369E9F3C5AA85C651B520F4F6160823EFCE074EE555453514AAF11DD3D59981E57A54E43F6CC" + + "06B96C5A3BCBC4FA6DFA5AA36889F75A9C84E295096061C9C0571DD449CF5BDDE164696B48F1D935" + + "E6531073A7FDB0B6F3A174AA20D7317025B54C1401AB4E7E6E01A01840EAFB102F036D3AD1877E0C" + + "6C1E7F974DC9DF827DAA5644020838538DE2FA25091CD57238C274FF5AAE1A7CFA4E1D39FEDC6069" + + "27AA35155D34D3A302C7E8EC03795A89587E73AE32062CB2BFB479D5AB3B1B76CEFD9F64A62EF0AC" + + "70A6068761DA307324C97519522E66C70EDB434DE0434A094E4AC633ED7E52CE97C6DC99CD3B8E03" + + "015A19F54469C194318CE3F8FC88724D40D4C2F0DD31CD3DBEBA8314C29853F1D43FD653908ADD10" + + "3AA365BBBC11881BDA9F31212D6343D7ADAA80227AFB3896479F0A84A34DEC72F5EF5320097BE73F" + + "DCFD0FFA2E9A91DEC479A07DFDD3008DC46F36A3506518EA9A60BBBE4108514E277DF57A89FC057E" + + "435BEABC3886D2B1AD95285BCA0EBDD27899F73418D439AF36D803D084AE22EDCA00B20D38918491" + + "94D4927BB787272A4D7A29ACE9D07EF669224DBC1767864010E0E3F1390B4DA145E00497CAA2D184" + + "941B370BEF33CDAEF2EC198533C971986C5D1E880BBC45858518E0B67E71E282A7818588FFF29D2F" + + "69EFAE7F90D3BA25978308AD2479051AA437FD8D63369DA06CA958EDEF081C740A430211D7E9BC83" + + "A543EC1C114F2B006F75911C66A8736B0085694C565F69839F1AFC507A749035536435D6A19E25D6" + + "F5AF4D598CBC8F07937C85671F0FE7DA1A8EBA372620B0BCCE1DD8F5AF07E886EC895B3D3A83125A" + + "5122712A305E532B5AE5DD8A24126051ED88DD9E16E02A04A7B6C5733B41C0F818DF4986729D44AB" + + "BCEFD6DA0B8F3CB2FC977EFB7C2B399AA9E3C8750A101A30BFE91A61C45CE86C8359C9507BD3E86F" + + "2CD083567180E132400DE25B09C804863F52ADF4FF68827FEDF07B5D5D7AA88B3FD13D0F975A826D" + + "DE1ACA47DCD65DFEB627CB245F274169DF1AB0F4EDC04C0A55BF3166C6BBAE0A760C1C41D2629A9E" + + "E5681DAA85FE4A703804CA4565F979FA5B9CA976744267D4D25022AA987A6DAA6015ED67BAA8A6FF" + + "36A6A92E90815A98B6B5BC400CFAB3D3D0D8532CFD8117E2325BC6BF9130AF18DCB671281637AD26" + + "7C1F2BB05CA00526D57F976AC183B5A7CEBF653EA7D6B8E16519E012218953684314AFB228E6A198" + + "996E964A121431BCC992B1699FF03B2BD25396FE389F946CC9AA7FF2407E398028052FE2028B35FB" + + "1719B2B5F61C12C207EF316266CA9DC85099D5471049D57B48A786B2", + contextHex: + "ED25DC1B30FAA7CB48DE2A98D5877E62DEBCB4CBF872F6ACECA28E04488CE7A9DCF5D777388D5C0C" + + "94E769C53E0B1084C366F17469D5F3C49D15A88D063CB2B2A469A3E60C41C8CF311DA1EB3793C195" + + "309440FB3E8C1280DBE3B9015C8E2935D2A05900A04119036230007B56CFA85616051C30728553FE" + + "69442826452AFF3299F7BADFEAD79A4DC5B281918B7CC40409FE2C5CC0C32D8D8044D73B8EDEB6E3" + + "C28BF81BD3B1554262DCF39F12D343417FB604FB0EC1BE91128D913F19FD29B9529465CEBD44BB0E" + + "F93A1E7E54", + signatureHex: + "3AC6D70214449B650A63658FDE06213171F68B7818D2A3E5F958C6CFE0359C7042BC7E71B3B95959" + + "344346CE5959E7D637BFED20D02E93C48A1E0FE0F13A1947CE76C8292DB59057074705ED53ABF501" + + "CA4ABB4D4F77A9EDC1DBF6FB62EF66D07ECCD8E11132CB4D5FB62666613A4457C7DEAC54B9D90D72" + + "FE5628793959CAF9B82C84BB97C4CC48892360A5FCE4A982070923BDD76AB17BBA08DBD5FD2F46B3" + + "FBEEF224C541CF837D202B89DA6EC3A3456E2C5F3CFFDAA87E055147102B45CB79BC4C6E16D8F613" + + "4B38381680EC926C10E255EC1379367D962E87DBCB475E32D9422D1B111FF4204D55D4C676C6B6F5" + + "A77EDAC5FCBAC4BA793628946FF06AB71A1189AFA4C6DA8A968ADEBC02B282C8C3B74C946CBCB12D" + + "18906070FFEED88A7C02B6096F3693468A112A6AEDC783EDD567FA3C6572AEF99B72B9C42B3D8B82" + + "8F100CDFD6FCB7EA900A20A7D5730FB9B0E92C53BF83486C304AEA57CC82BED980FCBEF0220DE680" + + "C7EDA414CC6A498FED069BF934AE14A9E319BC4476025EE856BB43384CF8EC2E639A1D9FB4BB0BCF" + + "9CF6C18BDCED8CC58E08699AF0B62DAAA0F5162AD7BD7F6C8015338DD78239731E09D94BF1F70E02" + + "E7977A491640DE68259F2BC2C0EB4D19497A7FF377E332A58F623C9301AA3428C3AD44DB17B2AAB9" + + "635F96D72D41206D3AE184992F929B1F7B69ADAC88410B4914513BF1C657B89E522E0418BCCE5B2C" + + "C888F7BF6DB2F27A187F04CDDA68D3EE5F2C320BBCA14B448A809D0D05A05C37551197E8ADB1E237" + + "537E14AA244117E5EBAFB1642685EC4A1C2117C6F8E56EDFBE04CE9A67E60D898281487F7AB3B31B" + + "BD3DEC924FEEE1C17D8342203AFFF745CC1EF4BA87F6B156CADA505149094ED7C922F3CAC264AEA0" + + "4DA4C23F52918C38B9EECDCC145F804B6C146CEB0B265EEFA24317930563EEB1FABBAFC4449FFDEF" + + "32898A17194FFA11A0C1777C5D2F27952DB5D90BDDC96640C538109A97C3D6BF6A86AC8AE0EA76BC" + + "922392C9572EAF472711B8201057556CE4B1B9928B610248F8D92C37B34DD6F8506B9060475AF033" + + "A7F6123777AED15EAE0CB4DFE2EC8667007F9E4AAA146F79F890380FEB4CD6712E8D18B273EDDDAD" + + "128DF55FE602215BA79BD3B66F8EE62D1F253564B93704CFC7DEF1256AAF03D01345FAF64B8B5AFF" + + "F3D46C524848613EE66BD73554EBAC51D505C08413C21560890EFEC98AFB313AE06DA64D15958C24" + + "8818D029FE8022666F508F73FB3A1B24C4488AB143013C077F84A836322DDABC9D04CDD1D1BF23BE" + + "36FE6F9A984AC7D37A8852ED2967DF6A8189DA0AAA5AE88F3BFE646291868A41F2102697B35785F7" + + "71CF5788441367A6DAD4196281366F367734083705FC10E2523B83C67420FF13145019862049DF58" + + "4DDA24EAD01CB88321B93F646C46C9F89832080E90644BE4827E50DC3EC3BCA845B51216844EAA4A" + + "0100842578898ED79625D9F352FEB48641FF78C4AFA5C8FABAFC9FA5F979854BE9A657FF4B98C0AE" + + "6D8F50DA33AB1D745E71B3BED40496DC2D269E22F1465BD74B2EE3FFD9EA6AAC19001FCAFBA7D4BF" + + "1FC3A726D29E8DBBA033C2331B325E933FB2FD725A6889FB0DD2194CA7EB928EB3A9440A100EE04A" + + "E353435FD1A7AA434B5D86594F630EAE803B90037A21E9ED58EDC713E53FB25AAA8556C3C6A208DF" + + "A3810BCDB77570086F166C4131C9C027263E99D8F070601EA90D99D9ADA0456A6E95C75D12DBB536" + + "DE4F3045B469A7DC8DFF2D5F12B4DC829E9DF19A66F19BF5D3CEEC89861F8036F977C4230EA69202" + + "D20EAF372900699C193002D19A79701D26BBAA8C7389D22C4D66866C95508E98454248CE1DDCD0E6" + + "2BDCBE4BA7FD0B22F76E2F1A235A946D7FC704D7E280692429665BCA57F9196FF620384E4B63170A" + + "33AFE40E03893144619EBCD499533DA935850B3C02DDA5A7FDCDE093035770C04EF776CBFF01A540" + + "E7AE1A84EB0D863EE320E7D135478814703828C17E70DFDC937BAEC374FBB3B921CDBFF8D99D3C24" + + "E2B53B198F2EC36753DCCDDF63B4FD2C800BF1D4D3ED4C78ACEA9B37D590D4C2F713FC35A492B68C" + + "EF85271D636620A06155DB30CCA08DC2608A2AFC30D492738B84C34E7D5A1C56C12F6269E4105FAA" + + "18DE515C5213FE1BDB99779EDC56A4A9BEE1E586B50C41ACC2670EFFF2AA5C1F35599A8DD5070A36" + + "AF89D58D455CAFF3C8A37BCEA276A3C4890FE5539E3F7921AFB30D40CBDA555662894EBA9F90875C" + + "52AE6AEE97ED489A0A32B962F902A2F6C7FAA70F34B16EF8693CB36F59F13AFC1EDF3C7E541BE00A" + + "48FEE767C82FDEF8162E7C33C9C1CAF29D1AE3AC98A6244E2D4D1638AB58DAFFC208CFA06BCBDD3D" + + "8D46AF358AFF920EE8C27D1F0D05317356C0F1679FF5C5094BB8E90EF26C8373610AE55BD13C7B36" + + "68E47B07FB7958F2B2DDC688C67A6969112EDE4AFD8ACFA98D9101A5CD4958BE9734A3D0DA173D11" + + "676ECFF2F517C056650E5C50D6028652FD670E713DC9163183E87251FAA8BBB8EBAB65241589B2A8" + + "CDEF18B0A61AA136B0240FA2166441DCB9AFEAB1D29B5FE375DA04BF8B874E954590881252A7E5B6" + + "A123A1B55DBEA0625B502D67C015372765BFDE4DC2E70D53DA105E5885CD5C6E98A4F4DCF0152DE3" + + "F6360A7B16F5332FDCF8CB3E5BED5E1B2A5197A8FEA3C90EE2D0B52CB203EE4A8FBB144444B4B9E3" + + "D1E6AB6824C85C062454BC43FED12D3DAAA46F1FAF61961DE696C5C3FC59A234E4349D222B7CFDCB" + + "F23BE757530C29EC79EB5A3037577715A7EFA2E5DB5A80426190D7535BAE608950E21771E28DF748" + + "D5D381BA61F10762C11DAFE6B60E9EDE069EF739F9017E1E5F4C293F20DC5905E1237795C26F3AFB" + + "4B1BFEFD8BF269EA4F040E428EA34F7B56660F6D9E2E42B01D5739FCEC5A69BEDED1C078D0EF4F8C" + + "38E23A113A0277517AF651530EB11FBFC6DC728FCC6DCDA578E408D60AE137ED07C7F50DB9C3FEFE" + + "16D43166E30C949AB9EEF85A4BA75A858922992802CE91875CF0FAC77AE67164A478ACD1C0331FE3" + + "655A9FE7260C8A6F45E24FB2AAE9CC6F1BE633C37D89CB93B3D22F7499CA3FE890AC879E45D37E6D" + + "C3CF4F8EE7F0DD065B3FE4AC8C95625B5283F43C723E173BF245942FAFCF25B10944C900F9CF9DE7" + + "D358654231B832C03DA3747DF42B5133EE593F6AEC68DF9D8CC5EE00D124E02C0BCC9DB5E5D1C398" + + "A49AA03FBA8CD19C476A903871E467499D6ADFD7AB82F1D8711D61DD0EE53C4A1F26D59718C74511" + + "9D47B501DB2E8BEFEB0EB2DAA12E93AC444799DA3B71A9FE4B5E1FDCC8FB1F7CB6EB3A9414F56958" + + "85CD1E5095FF21DEE8232F54C2D78C5224021A34B74DC0C4E60990A9ACE32CB9AEC27F7960DC0C53" + + "2AD050BA4605FB13EB3BBE45FFE1E418D656D011A3DFBA42BFBE283082DC89BE6555BABFA8A7E63C" + + "CA8BA3F0438974361EBB6AEDCA3270EE829818B5212E60C5DF3B32FB31A9C55A945F64EC59DB15F3" + + "8D2B89A4D902334459DA6D71C68C7397CABCB105295C8BB944B32C0CBA3D9AFDBC7D143C6FF885B9" + + "046D1011FC7D91BC52CE8879A473278267CE231FB88F6649DEE01306893E7DA3C53E68561BDACD7C" + + "1FB972CD45F152C28C4CC7AA77354E3B69637347934C1B4D5721E01884785937D15D47BEE985EDC4" + + "5541B2ADEE2B0366DC9F8111E4A00637D9339F66F246B7C76C46F3B0A99E16F2354043459AF6C461" + + "E1E4530CE42ABBBEDD8D26E103ED02FAD56544B81242200C35602146409EFC62EED9F234448AB613" + + "9EC930B557E9B573F1B0EDFFD361F14D0432FE7C211E74B94E63B334F57827920FE2DD5F5E09319E" + + "BC89859C61ED728D8D1C661BC0FD62FCBAFE0897C377E1CD9A4BD9399FE5DEFD8DDE3BBD23C9AD5A" + + "7C0AF492B85FEB2DC3053BAC84E73C83DC161D3B0B6B01C5FDA59FA4ECB8F7001CF84E5384F9F7F2" + + "9524E2CA90CF1DF90AEEE56E179ED9BBC29243E91691D12DA3127FFF37F4E7BBC25764D70B077E44" + + "4C4D26AEA0995B0B65D8F2495BE03D30A5D59FAE7379B3F5C75CE6167A3339D6AA64DF74AF7CCD16" + + "08D570B3AB05748E515935FA089D79B947450D3C327E56BACEE82436345337E3D3045E3BB8C0437F" + + "D9EE2BC78C510A8D735327E53801D39245ABCA8166457C1EBA9EDAD3D73745B2F9C07C236E794205" + + "565C5C7EAEA4079F2C297D6978DA50E0BB272D4D19BCF0CF2C6B75A8A92077984F0931863A2D2D6A" + + "A2E61DD28F82953F60E0CDF801D30F4C2AC1B6EBDB888F084FFFA05C42E32F772A511C5177F24F62" + + "09D7CEC79C7023BD51E620D6822687894E6458D36360F3886ED0DF6168DF7997927EFF5E02E7B150" + + "A75A7C89DE9789108AB1424426502121EC804BD576EA553F3E37E5EE24367118C8FAD7704E167318" + + "599DD126230DB79F5E924BAB27AE63E29A0EF56002ECEFA234078BB6ECB0C43F2717CA1E5C444852" + + "36CA914B735747A390D2B4F29E28A67B992E1DCA8A75AA374E0F27C035D1F74A630D1C3D18BEBEF6" + + "9D9C7124CC15B37B4FA2C45D6F2027AB51EE000A6660DFE3E4B2C9F8071F3C261F51A2ABBACE912F" + + "4411D21CA123B667BBE0FC36DA8B1D9BC52B49EFA22C9BADB6AEDA756C774E354F17A36E28E87658" + + "055CEA599BC5D7C415065615C3854E004A6603EC713DCBB70302E2BE2E690F7DF7592E374A91DB43" + + "50CC5968997601A98DCCEFD3911F330A0C968E6F1C5939ADB19B3B3B2DA7C72E8025C1C9D48311D1" + + "AC255F5248FFC7E5134FB34B672C4A3D98091EC4B5A0D5E3942A3AFA1B84D6D453F642ED642F44F4" + + "310D4500CC4D7D40F2708CFD97C1A10579E22427B1F1B921D507BF2B841E5B1C748EE4A019343AF3" + + "F0144BC48170FD53B755A8F0E744882A18CFDA2501C297780D115F4FE0F76F3CD96613F94CE44FC8" + + "E1D4501A6A2C5F24C274BA1D7D56227235BD6477288945DD1809BA94E60D170488CC3AE45A884B07" + + "11ABB43F274654914CFAE959F075A3A721045C9F403CB8B5F9488992CB26B86FFA139CE7CBAE4F77" + + "70DBB45C1F30B2D6CFAEFC38CDD9B27899A538002F9A2AD1A72DBF26F8DCBDF24C79F8A81B56F9A1" + + "47918C358810887A3BC666DBE99C1D9EB7FCDB56A125411B098D443A9F73E0A124013D175BBA96B8" + + "1A8A72AC3E99EA031D5D6E8148BA413DF23298F11C586F6E24A349899A7351E1CFEC92792A18E159" + + "A73836A8A0B667CB2FE54606205975C04CF8B62397EA1035E94CE1832BA4CCE93CBC18A8D3B37126" + + "4C384FB3072F4F5DC6168E399D61B510D2890BF47AAAEF87EAC608646917BD3005F077A726A16F6D" + + "C8878BC9523ADB3AC9950EFC09343527756210A6C08F048F86A443585411D21A0C39A123C800DE28" + + "EBB6691FBF5CEF26045094B5C7F112E24FBB4FCBA37A0DED1EA498997A89F3EC7306452E2BD93586" + + "898ED9E952291A4659F164366D06D1AEC2E588096B1A0B22CF6889382B37BF62F0503A36920DCB02" + + "1A4FEFCA480789B09C730BBBC8482E8FAA4640A5FECADAEEA0DA5A62B15438463DCC5562ADF7EA14" + + "3B4F8D5675CC3E9205CC913E7C8C18482C4FE0EA4553753B7A4635B5408BF7838A2140FB1451E640" + + "5E5F5FF630EFAC8764BC838D4CD378FC87A43361A3E6419811AB1B3194D23B7E17B54FE5851EAC8A" + + "CA0CF8B930AD8D52F9E996E8BE415EDC2CE98D148EE135031D0DDF40F39E98BBB9D8375196E2443E" + + "D9755BE04FF609394770C933CE69140114EAD533980C9E784D2B107F0084F86C4FAA32BC49CAE22C" + + "D0D295EFD57375DE94E6E65E66DE907705D77935C2C53EF9E0D3038D1913A47ED4CF936168C0AB42" + + "0B6B028E2DF4C90E8483770E0DF839504E28A3B8A757BE21D1435079C4A337E96F8B790A0F579BCB" + + "736BE95A96095B0D244AD85FAA823A5FAAE7A66B1237D8744044DD44A5B6E57C32A277B40436CCD6" + + "5416339107A6ED1F67414B3764E416B7EC555C28606F29817BE2D048C2EDB9AF45FB741ABDC6F9CC" + + "4A7A148F363585CEA8339330DE82E389CD85D3C278D0AFDD9F7A32A43C659CE977BC8C50759DE147" + + "678DC14529296E05851323F5B15600B0F3B18BDDD77E81CD016C8CFD176F53F26FC3029509D12C8A" + + "CF5D7E1DC19FCBC250D65119DF3E680E9D8A02D5FB3C28037BEB50A3EA82AE8DDBD8FF8083089AFD" + + "A4712EC5E3963D2CDFBBD4923132E20CDB2D26E9E25866D92BFF67124CDDC8F514CB19EF98257BBE" + + "889DB537F814A0C57786CD9B57A09CC633366B646F77DEBA94A990817B2BCA48BF5AD1603CD5F325" + + "12ED8A95836E5129232D2AA014C3D0B724A52B13187A99109DBC897B4664737A3FE95BAE1B364651" + + "01EF9822BE2E228D59AD30AF4E96A990E020159249693EC72CA7B9EE44B0BC5F8DC8C872DA25EE10" + + "CF4609A9428D9E0DC9C2AB4CEA2B8C7042F509FF80CDD8075E6D939CA6B7BCD5D7E40025282F3031" + + "5C81A8D0D1E5E9ED37878D8F9091979EB1B3DEE1012A8CCED5D7EC1A1B34418B8FE00135456786D6" + + "DB3C5D010D24598591000000000000000000000A18242B32393B41", + hashAlgOid: "2.16.840.1.101.3.4.2.10"), + new MLDsaNistTestCase( + nistTestCaseId: 78, + algorithm: MLDsaAlgorithm.MLDsa87, + shouldPass: false, // modified signature - hint + publicKeyHex: + "E91AD8A5149C5C54087A759F86EE3D6D58ED7D1553A8B92A78815DE62CCC00EC144577F66A1D16C9" + + "0359A0C7BB385AA266706509D3066265D1929E5AE650ED003759EF818495C8FE3BB7201A4C2DBA26" + + "C240E3A9063E68CC323A61D56C6CD0822EC1FE600D3F6B21F8E73403B4EAF682B752DD95A0339ABC" + + "66ED699B70C3A59602930E6539D2D5BDEA2ABE71943764F273BD4F239C73768ECA2A8C5A10CB1CA5" + + "04A636C008FFB3F19CB5B503D32746BC6B2E1641AAACBF4788E1C793447DB21767914A2661C4247D" + + "A0AFFC41B1EAC4F508D808C5A2EFC8A7E66BEE59838F9B02B888FC2F3D81495B6D7430F9B066C61D" + + "B0D1C4EBFEAF424CB6FBF86001B5DBB2C85FB1383C10EAF7FF6EB6E2D6D2789131B3117B9B86C622" + + "A4C9D2B37EB360DED425CE4CCF52E788465393EEAF7B951B1D1658D8E07C48F4A3C82C25A950DF9D" + + "FA24767E5E6ACC076F11BB617AD5DEE86627A411188CEC730021090668F789276DF8E4133815EADE" + + "245886189F1D2B3B0191AFAABD9F93883D3B393339A0DB7D4AB5620E2B27F2C00B124451A94C3187" + + "E3B4EA6C9332A67B78A2647908971116FBB128E44B74BFCE360DDE417F7A2AB191C10B04FDBA83EC" + + "5F459F3D0CD724C82C3C894AC592D29081ADA6A948D2C576E326CDB8FF70E62E9431F591E35A7F57" + + "1C02CF6E74ACD32E17A1F70FA23CF160D3AAFF86BA8CAF3C0922453F72A876BDD0A771107D214147" + + "531E3B5F194C3F6981BBD5F915CC08BC2ED56A00636A1EECDBA2852FC5E23FC7ED85DCBDB0E7CCA0" + + "6D2523B5AAE90E000A5D81DA1245654DAECD2ACBB40990CB53F535535C23F077402DC7D5BB2EFB14" + + "02E763DA2C629945183AB1A59831C061B0E8FCF7D03DFD45B432F7F08FB3A24DC9AE65A527CE8C35" + + "3D577648AC8056DE3A63125B0F6B5E38EA93D3B6222AA595ACD06A53D85F04C4B2BDD39DA3FE7E39" + + "65F9F9068DCA77A5E240DC695AAFB8B5B050523E2D5C401038306639345FAD21A2F74A4ECCC40372" + + "7BC5AD932937E860A2778A0FDA890C0E021A06964F3D96B3B863A229333E38F5B35B916A55E89EDC" + + "04645F212C0D22109FF96772D40F74C6EF952059ABE866F98A175553C3961E24D5ED00381C487EA6" + + "EE999AB4C5ACD90928C3FB6A21DFB5A03C58584EC6435F73239F57881C633784FAE040CF4C0384EA" + + "FCF7057E06A4E261945966B2C6B65989D3EF42B42F714A23CA121820D02D4D6B63A67877436BF7E9" + + "4E5338739B4C80AB1F0147EEFAA30862CE1866F92D7D1432E93286ABEB23959055C5AC2FC52FE47D" + + "2DB896BE010ED14D512AC05EA6D1EB2AED5B05A6E2F6FD47143E8820699534C0F4AC63B0DCF311F8" + + "39D42478B28997663A3FC0822507C3946F3DE45263EB9B74B9A0D4D83AE1922E87F86801F92504C0" + + "A62F47BED921CB9D1E23EF785F960312014828307E203707058758303C53C67A06B4A56251F59C2B" + + "5043CD38FD01CFA19BB012B4B0481B274267FF864A52F945AE490BB3000D498DBE948E0FB884F851" + + "D5F91135783AE78EB5F10AC965F41F82B1A51DD0AD456A21904CFDCB5B666B964DB657E0FA4365C6" + + "AB4AA2C862B11E0468099483A2251C837C95E2CE587005D2FB21A821C97641D7A930E1C7721BF171" + + "1F324C946C5CE5700B5B422C0D1A6EE1E13D37E9249A72BBD000A2A46E78B51706D0A49A6AEDEB89" + + "539B76F55F4B81A6583FCE226C5C4CEA4C39CC8A658F2A301B2BE6E3EAD0EE8A7DEBCF320FA3DD00" + + "8E02CD79AE2AFEFAAFF74DB608BAC9CD6FE26C21C84874712EAB9FBE6E056268F1CD677F94E9BC87" + + "01E773619D38333FD92AB281BC960BA2B62D045E53A38FB82BC5201DB642D00C01E5FED3B7F96D3E" + + "015E3F1B2CE61C4800C227EE33C9A2B7FB3039B9733B442FA5D80710328D13990DB1F487507D09B5" + + "EC34E0BCFB8E082A846264C434E3AD4FDCEE21BC8A2EFF7D3C8D4DD8637E5BD0E98EDFFBDED9BF42" + + "C9B550F6246E7FCC42668E71E510A9476CB5DACFF0C8DC5497BBD00FDC3016A497835761BF798CCC" + + "40F3E97DC6FEE1D47533349543476058782C25E31F66AB894A715859A932F093BCA863645A05BCF3" + + "CDC8B37D40D2192C3568E4BAEB24ACF20E6F2AA5F02FF824C69062900EEA9ADE41BEAAC4700F8260" + + "B330C025323D53C308571F7C3EA3308811F2FE285BC3432BD6BE948AE9B98E4A0BBC1F4A3A7D13FD" + + "E3DC75037A6CA621CB47C5586C63E44C6F1958A2A49A78E58C9A2BEABD7E34E3A0102503BD470523" + + "8DE385991AF392BF1BD79C3E5F9F509AD18812C939A83EDDEE8957243F3AA210033AA3F1686A8870" + + "06AA4A5021D0A67D1E55BDCD9B93076ED4013215CF78B83AE470E54AEE1778C0B427413DD3CA717D" + + "E30329BB06DC5736756E8C6B047CE3594245C0753CB71F5BA9DDA7401B8F976933C80E7A2E74FB8E" + + "CCF8C516A0B09F2C1454B445BEC17E9919B5BBB11EAE3683A73F73159D91275EE114128EE2DACC83" + + "4AE961A0FAAED69594C5B0DF53326490C6FCB72E24881153F68A7D03CB7F130E913164E5270DBF59" + + "130AA4E49B318E889BA7983F023C0C6D858BD01EE9DBEF8088531D12A18C8FDB2AF6AEF2FB0695F3" + + "3B3E3BB6878D37D849D7637403DC7050950968895F5CB664D0EED9803C95564CDE22840BE630BCCD" + + "1B4BF5308CE63B0C7859EFEA4B79E5137F3F382DA541D1406AC84F277AF6F53984807858BE60A071" + + "1FBA0986EC8E777E65B6D7E04A0F93905FC6B7B465250FB69B00BB6796075A1ABFAE64CE9613497A" + + "2566FD2C548EA63DCDFB986E369131B16823528F7E93528971EEACB4581DF90A6A2F68A03542C6BA" + + "8617936ADFF36A9D5EB731B2B84B4E9BD193FDFE556989C2113B75209BF8D47D32893B61185BD1D7" + + "7F6871CAEA32099D0978664D029BD49AAC8280A5E0BA30CFC536F8A2204B6998B70C31D90E4313A3" + + "200EA92F6F555FDEB311884AE98333CF47D6E403F0ADCFF4BC6C3E2799E0E60CF7676FDD469856F9" + + "FA3A222C221259D4123E39F283738E9965B18C7935ED02B506A576F784468E21A71B989D9017475B" + + "234EB506AAEFAAC039075723E91F0F7DB6078BFF3D61DA8EC7E9806D75ED116D7A5AD92F2276977B" + + "543A38512BDDF2B042277EA68E1003D9098D7F3B127B4AB6F26F5F5B8B8EC9BF4B78D2D3CDBD26AA" + + "76F6B4D89ED9540FFD6E359D8ED92648EBFFC32F31CE52070777DD815EE9E30A4C7E516736D58816" + + "6E5B70A3B43F0CC08E5B800488F65738DC816D36E9259B5CE88253295B7FA01C6592D259A2BCAD99" + + "BBF169FBB0711D84ECCF0866A6C42D6AEC9E7870D6A09CEA2A4D41373B09BFD45B60A49FBEB817F0" + + "1D56A75A105C8FF8A8F89DA7B11482D5974E967C76F8D279AEF20D10D37B7FD0B300F4F9C79EB9BF" + + "1AD9C028F251E3C6FAB6F2C1281E495F0B2909F653F67F3D13264BBFFA5D6CE9FE8FC81137B2BB28" + + "E12822954679BA39FEDB7F27CF2A57921453541B6A87D78DFAC843D29363343E6CE7DDE672201C66" + + "754D5C9D1058139812167DC688A2DE496F2BC55BC5D339D1232C981FFEEC6B2F61B2B310F7342ED2" + + "7A49B780FA101BC8A9FCA5BBD86E51F596865444057C9BA75C1684008FF47D502B3ABAF7735963F4" + + "0601C3939DE1B099FBC58A41D02EF20A264F7DFCD84A5434772A5B5F76C74531", + privateKeyHex: + "E91AD8A5149C5C54087A759F86EE3D6D58ED7D1553A8B92A78815DE62CCC00ECE9CA23D2A91ACA84" + + "AA45EF54FCA8D31097C7404F3A0D75CE968CE3E317BFE5F0240F94B4E7B7667BEFAF4ABDFF611D92" + + "325C7F0E8EE0948BAEDACAA0C4C25CAEF334BB88A3744FB1E8F9C82D5B4B2F6D1C03F927ECFC8D63" + + "42FB88EECBD2D1BFD33490CC346A242590E30629DA904D60303094327060086E04C2280C82305030" + + "2EC0228C0A048ED98444CBC66492989151004993B66863B00CD8808952A42811B41104A008190349" + + "11B3696404401C162A01292A04373208962514306422482622B96099A64064B08D04B8480C35629C" + + "C62104192683127058A48884102C1907420A458062209124268A8A40116104421C190E9044701937" + + "50A1024208450454C28C0C886193040A939664DBC6891C4869C820409BB021C4C82D59A68CC9B601" + + "D1841180866C62246AA13429101946C29640DC426118A02C5AA02991080ECB206003C2688B142C02" + + "458E88400644126814051044C62CE344000B04911A128463B465998089E1142D4B9890193284A408" + + "84193064994626242740C3961122B7488B38842033020326521CC88D0C999192406504C78CDC2871" + + "E04604E242805A964C22C92D61B42941968C61C284E1302112252550262444960953C8881B096984" + + "2645CC0065DAC680DA1669E24462484060DA360219320961448E0B00660897250B814DA1A8810036" + + "2A02166D028430944290118145530000DA424C5C380C421088A4962C5C1286981660144860224064" + + "D3262801248888988144428D9814500C83005CB2059C8805530830122120CB344809C51189B48C08" + + "B544D9A27021A12011306E09134E0A337299C66500146A04108A59B480D1465118A96C0B37710002" + + "255306268A44651CB9300B35840B134A133811612624D1108E10166C22A76D54148A8AB010DCC228" + + "043004A4440C01B388D1B03022A46092107243364E9C32915216708B944D1A0462E180441B338563" + + "36401045010A3444138184C08045E438091A05040B3240090464101380203725C1C86C09366C10C6" + + "8561A26CC2026AA408668A86509B24521B32508C22300AB98D51802892044A50366D8A308D22C140" + + "80C84822A7494B40454A420210452662380963422A8230665B340944C8411B476210310981169191" + + "940C4130090A208C5480881139510303898916200BA21122968CD9108190B0702332912305254342" + + "4964183250B630A3307022038423A08C01A7850B330E8A944423128D420851204309C238009B8851" + + "A3346022100624040522B18841108821A444C4C46184184C1CA69024420694222948909108858413" + + "248A618284023845E4226523322D2218109180488B825121C4490B138C2087718CB828010044C998" + + "0148A009C20452D0484624036243044DC0940988182E9C126453328282A68161328DD29664500861" + + "4BC86D9A228203B408C93862DA80704A9668088008A21224903886D19650618225218750614248A3" + + "3280C38070094208911626D248440C34865216316416845C466D1130901C219022910CCBA645C810" + + "9222334E24C52504C44823080A0AC7911904641BB12544369119B240CC26288324409AA045241600" + + "13B341C2B405518404D4200288A005229820598670D3148641422522B98022305201344CC1822518" + + "2110123952D0242E1438014A146E40420491248E8C122944B44C23046483B82D23230D0499011910" + + "8A0CA60D931665482692D9A86DCCA66D5334429C90282149280B34690C156E80068CC2C02014886C" + + "92246E0203440B980D0036108C1461093946028071A386040815026226650BA48D23364552B22963" + + "266C61A650629200DA14485B460648A085614820C31230E49004E3120504368C09126AC3804D0114" + + "25A006051242919046841235125944319A146C14163150022E14A528E0328E5B124D13154804006C" + + "9BB61083822D23B52918A951633048DC928CE448890BA010A1044D23C22C4124455BB62510470422" + + "137244840114168A1023041A9000040108C3C8914B425022870C88140C641090C406900826480817" + + "6153105113310E4C10604C0201E4080280301154866D0932240B96689180414A885011B2209AA44D" + + "2108495AC888219164939210C4189212A94D94004A620092E3960D8B44121A903011B9480219504A" + + "2626D11666C436721C39ACE293E09B7DEAE673C87FC046A1C39FDC1CB38EB0D5E87AFA792B052EAA" + + "6DA2E5CA267A577F7D6EAF2A0D085D82FBD37B774925DEA517F83A91EAECBC31CB521E0430972A0F" + + "D12AB4DD5BBE4A93C3EBD82888416E89D746E74BDC88C35838FE6C9DB5BF06254500E175C3FB377B" + + "6E4A60EC18BC896F0C012E97987EA7E048E8EA82EB451BFDBFA9E58E179EC016267649BDCAA14DE4" + + "3B44EE7D381FD73B345B1F91D5C4422DCFF89C91289994FC01E7FCFF17D74ED037CA70D63B752A76" + + "949D49D9491E3FFF2C6D63C23DFE64B63E0E1ABF86F6BF107D38F7381D2725060CE014668C98BCD3" + + "EE1E7CDF9E9E51C8AE0C44DD979D5C38FDB8D1C43465AD58C1D4DDBB4399FAC4D2E2268582F53DD9" + + "40BBA130FF3E2315BFBDA0D7E62EEE1E82644705E5692B9E802BDACC837CAC9A11D6EE12703E056E" + + "3A6638546EA069299A307E501DE179AB929362BA305B29C1EB9ABFA9E82A5BACA4449D09B9F2D91A" + + "7A9E093CCC6B239D4F456DBC904ED8E718B1887A5548C8B93AE755EB950D1E7904954FC7561DE1CE" + + "27FEB8BEA09EB20F4143A76ECE3FE75D01F636C7315E7E80EB4680A41CDF88B545C7BB63CE6735C6" + + "34CB28B3FAAFC8B2D94F837FE69913B1161DD69630F4BD862DB395503BE363D9A6E855CD3D411B8B" + + "50A4C0F7AA90F3F5E6D94979B0693EBD115EFE96748EF079004355685F5B002A5E56B23C57012AA1" + + "87364F1C78DE2C5BCEAA29673A3C0AFE5D45690CFC4F33188FED91CACE3A79CA12317831398F8154" + + "68FD8B10AC382C837135A5315B139EE0BC654BF5282303301032B1D4FF6425A4FDF82FBB0658DAA5" + + "3ADBE2CBF7A826C771ECA727AC191C936A6172824F1E319AC52F0B97875719A622F96164E859861E" + + "92A196E3459E3653CBDB15E051E9636796BE3E9A327ABE48402B52111E1C079094D0E26366269E94" + + "ABF4EE231DAEEE216E6E14DD71865CB75B271E46825ED6E666553ACD016C29B6E6A0FBF00CAC93A6" + + "1BBA6FB3E23D8915129EBF99C286CDB7D0E291C37AE3C6696B3F5A2D96AFD68E3BB8D18EEE64A242" + + "0F390F46C3CAA7E02B8633F67A36DE80212AB66FF2F56B8860F2E013F282B0FFF5B6CCC791982682" + + "C1D8ABA88EB35E130175222FD22A68224FDEB801D054E5B780FF16F10B94FC1352DDC88318397D96" + + "9E3DA587D100B8362A42FC4A48A1B0449197A4A6CEE3F70CC957F9DFE7934A389A055A618A452732" + + "299D7C51EABF2F4069D22A224C49B5604A48AAEAD7F4BCD979B10926C1BFCA8482A03EDF6329DA53" + + "A97A6FFBD1ADE63D760409136AD85F62DD71E0CC10A5E94FFBBB4364FD55E047E9CD58282FE5D019" + + "185F010B9D782019F60E1CCC9B0D1455351DEB5514EE9227D26144AD4DE01F4FFF2C8A91F85C17C8" + + "B2BB716A11CB0E0C15FBEBAC3F12456CEF86B63D3466AEC6A7DF13241088F0486AA05FA49B50B7EC" + + "2EF79A9F2495647D4498DCBEF0A54FCC0FD632BA662BADEEBA5545CC8106803A07648207FA094458" + + "892FE667F60A43CA7166D91B374C69FC32B79C2E3D9EC0ED77828502EF78D1E5E0E01CAF03F7CF06" + + "1643D96DB8B2632DB2F5AEA56DD50413B5F2BF578D4E7A78A1433153F7D2731B9EE5F859F15B2DE5" + + "5A15F466B12FE94416B4C400C3E31DE7914D905741076E7982648A1AC0DD3DBABF69B51914DF3C71" + + "3FA1D7E3F0B1E4E4845B9ED559D04B327245812AFBD0C37F77B5C6D84BA08918DB72D1CB58FF0F28" + + "724496F6B3E3ADC7D99DAF3B111A3F2F525B032B92845B84E501220A48E05C93B6CC347115D2BC60" + + "43610920A1BD607D712CA9FED2F8BA2FF9B14719F05D699C816E58D317A505BD7F70AE98AE3630F9" + + "D954425CE2B982F541A90484C5413B64B20AEF2028511241D68A0390D581AFA37CEF6951757A935F" + + "CB87D306618DF882AAD9AB61CE142323BE9D013C34574CC61669C6A4CF07DBFECA776A1F95784E32" + + "4D0B810004EA87104F3043EEDC638CFF47B40BFB8B56A631CE91C175E7A2C6F50C9F3283EB1187FC" + + "A1F48F3DF6D71C52B017C236E74FE0356E677E08C7CC6CA0390868F712D00C10DA19E3C4CB5DE2E3" + + "784082166AEC5935A5EFD79482FDB120243258CBC58EFFD4303EB67DF096D0EEE4FFC286F3E6AC9E" + + "5616785AA628D63F487B11BDCAF391678CC3B92AC7ED5C3DC63084F2F542150EEF267337C9EA0E15" + + "0A37D6B818E403582EE27C981906794744AC46462780130C6ED8673A3AAD6712DF007F3BFECA6A90" + + "B8E6228ECE00AAD3308959D3EBD38154E65ADF5FB1B854FBF656EBE216146FBE2F8BF0BD53ECF793" + + "EE2CB9C207E01F3EF315CB0B21C9DE7DEE30A3A02E1B8D64F16DA1162362D24B831209776ED8C513" + + "A1DC6CC9BD52632A1377040A90B2848B0601CD6E880E9ADF772897C9249BD24F30223678BAD3A012" + + "73E2A074C5E4817905D04C7D9A335C1755A2D22E0949646E006231F54CF7EF436C2353F28BE3C451" + + "D21DC866FF027913BD3A42366B7C4E7E905B42D95297CD476C537F5279860689FEA4EBF5DC355B00" + + "B6A58FAC089323738FF3A71FC7B7CCBF9F0FEE0A5448FCE15E97CAEDA78398C976AE97393FFFF535" + + "D2AD75FD69C837ADFAC10D8CCA111630AC3F12695022E472572DA91CB30AF43F30238277675F7C3E" + + "1E1C54FF89E6ACAAEDDAA8EF8CAE3BBC6EFD27C5FC949E48F892FC316C381C272192EDC5D2AD5D5D" + + "F73CFAD1BFFB8AB9A766209272DFFF9EB739753F77C5B537B40C1EE49C15E17660121D08DD3D330A" + + "8EE1D0501879AEDCF94463B494030A4EF206171E15E70E2450FB8EAB8C5862A61DE4B2FCFA2D21CB" + + "D24982EAF8050F20F63BC7D6884D69D28555F704080DD88207E15B7CD08C65F34CF1827B8212EFEE" + + "7170E3715F21D631A2CCDDFAE6DBC9A4DBDF4100072EBBE839E3C9CF1D619858C2757E1465486AED" + + "BCD2C8C96F10CC261D6A107566914FE8E14DED4CF49A256C62448025D4912F9D79C415BBE30960C6" + + "26C7CAAD5D8F85879CDD4EE6FE2B2634D290CAEF883BE7F3186058CA4E72568265F1A36350272A66" + + "8972F4599E7741AB8ECBD5274BD441EFFAE4BAFB2A9813EF36EA7529169326646B1B4CBDC77FC0F0" + + "8091D75D5E72F3772E7FC5B29B90ED6A36DC8349D59626ADDD15708BF77FC3EE10E1E288DD0B3B4A" + + "3C62E28BC9B844D37B0E401EEE3A74057FB8EDA5A2B38E75087EF7F0CD4A5A3D37221FE9311686D1" + + "2943039CA5A2CCFBB3D7CB84AF574F9D17761A11D6DEEE8D77BD32C45389CDAB92368576707ECB6D" + + "93634B67E8DC817D900BEA8F87B238A405599B77F71AB37594E09D94706A5EC2DF6F7AD34022130E" + + "778DC7E4CD6EB6391046E024BB5BE605BA711384775BED578C95E1D3FCB7412FF503188FDB209837" + + "F24D4B01C0103EB9C099FCB502D4B7744C2550B4A7CAA7A7F981248996720C59C33F616FEE5F3A90" + + "E80ED0221B40D5382B1E1B0FFCF4D5D1A5BB339B6255E8689B4408FA3B5E543629EBC8462D2F7E06" + + "55F856911431F12C61DC75ECC600FEB113654CC266996983473D5B7E26C511B805820D22CC065C3B" + + "A55B56E6182156CAB0B3BAFC802779F79E0083C4CE404E91BD4406FF43C6FB3EE90C18A8CAF5C054" + + "FA5B8A116C8E6A474C870ABC4D8841220A202E75770F46439AAD7CA3A81E7DED4BB1AD13C29917A9" + + "AEDC8679ADB98A155A9C147262F4FC7E6EBE4FC71EF1C5F871F26EB1C76E92AAE43B63D186ED33E1" + + "2A3CA832AEAD48782FC25AEAF0E35FE92A64D905FD3E1929539CB237E78264C8EB0A81E2DF603B64" + + "21D4DABA7FD68D89F9C2A8F2C6CFF0C1F6610BE50630FED5571DA8D8BEE6CBCC8DAC3D4D5BD701ED" + + "F39B653BF30DE7F5D4629A58842CD9313262B061D5E3264C5DF22F534651BA0419EE44D1C2E4C9B1" + + "DA8121E333E5F6D2F4E5590BA12ADF6A5BDDD79D417860795A0C3903491EB43AA6623AC8E4EF7734" + + "6B1EEA7FA1DC23C499D4662AAEDA62C343BB79A4E9F40FCE12DE0CC8A923C4BD0FE3D739FC883572" + + "0A8CE8661BB3433AFBDDD9F51E7E52730D725CCA3260A901C4371E2A8575029F9F84C16679CFDFA9" + + "0A999E2EA92A26E170FFFF09D04EBA55F985B024C7686B04386DD9A91244414B0200FF858203EA53" + + "0735D3EFBE82F7C1A0B77B0B5562E3E0D6E6FC7415CC32474D25BDAE06727BB912A724ED2CB8AAFA" + + "E825C9EC11DB0CB08FA1BC3CFDD056A6A9198D2C20F4DB55043BA7BB935AB503A184C0A97958F5DC" + + "E61AABF14A8D463C8C86355EDEEC6EA532E07005256C15BE2260AC543F51BB21F64733B59C0FF0BA" + + "D26FF0DF20C0EC17EEEA831A8AC2BB8212A53FF5F2F30C3CE64D1AF289382A26B20196BE14CFA3E8" + + "9A37EFAB17E7ACDFE7C555AC2EC44DCD8CC1E735A790D5757C59E6F5133AFBA809485F6F7BF195CC" + + "9052E6F2019C055555B0A32AEA887D09AEB29BFC5B0A7FBF14DF95F13850FCFCA2BA26A4C4A0C472" + + "AB54EE2E60A36E650360DC742B307A9554CB7B6E850607CC7FAD05BD660B57306D630E7CAE6C85FF" + + "66BF579D55B3CD038F93B065EEB79F190EB1092951B0F9CEADCEFB59F4EFCFF273368AAA0D70023C" + + "5CD188CE361163C08FE27B5AACB9A4FBB3106B038FF4DF522DCC0699461AD9FD75AAD4E516095277" + + "BEE49E282B029D6BFB7DE5534A7DBECEEE019DC9D6AABC224611E0D0688DFF61BBD98FE9EEBD749C" + + "495C611445979BDF344B8EE233C7D72C", + messageHex: + "FBCAC96861F3854661B8FCC3F787DA14058447A0F2F6BB8B3EFB3274986EFE738E67CE68E4872793" + + "B2E2EFA413E8710EE42CBA452D0660C933ADEF89873729505C10AB6896BE41BFC974A752C0EE392E" + + "84B9ACC2BF5B843ACF64272546F1085935AF934D16F5C890EE79A0B141302E5BD3367A8F915F00EF" + + "5DC25E5E4F2F386A25E883EE490D65FF493D21BF4BE1FC2DC377557F5B2E41B89EDC5A7CF511CE10" + + "38EB933E5DF2D229B6D6BED2179ECCB83E53701D407156B926E0E11C371CD60710395D189A3B8134" + + "9595F1B2E768997FF99198CB19DE4996032D7ADE2668BFA789A53BB11DC64AD71F8AFC89085AE6A0" + + "BF0785F6C45FAD4BEA7BDEE412A0BE921FF90CCD0858877E885C2AC62A3312E2128C7EE5FADEA195" + + "734409A545D233495126BD1A3DF82D3DED7FD565F42090F42024B746E90FB8DC1349C6369674FE5D" + + "C11FE7BA273206C9D368F5B3BBB4DF3A7AA0194430F56938E1E44D43C200A6E232901AD45A0A943A" + + "68E73B534899C1608D89373D5631EEDCF441C5BC6D6FB10EBB3D4D7C156DC3B2DD70751FD15D7AA6" + + "A0BAB3730F621F800C30421EBC71AADE060DB0C240621B40FD469F76B1FB0C3660822D174DB81C6C" + + "FF8DDE30AEC0F97DE6271ADD94DA28CED1012C2BCF1F0DEB60F0DFB5EE900621EA459C6830EC4229" + + "726F95BFE66D273F381CA754D906B29BF60F1DF0EA6BEC7CE7014ABC1960EB7955063281BB04FA7E" + + "E1C921DB0CED223501B5C91C66972FA5F150C3E1EB090859F8B441FC3CB451BF2B84871A11DDCCAA" + + "E236C521BAE32E97026F350CC3260269E333B9D998046CC7D783FF942E3114275D8707EE72EC8DB1" + + "8EDA00A97B29432B18B64C26042A32EA25380E4794BC710318B13507511B1F2F59BD03CBEE92FFE5" + + "CB94519F342DD8938F580A921BE66E", + contextHex: + "CA65B11430103D42799F6D2D5C1E8D7A8CB90F263A6C833FE35E4FBD82AB614BB3417893E5883B8C" + + "B289E0322E08B17A0BB923ED44008A42F9969C6C9DF0CC5AD29C360D989833AFA65426C5AF7CD680" + + "CBECAD4F0633E7E94F112C1937E2E1D94F90AF04887C66B80829202CE9D95426B0D44E7EC91BEA81" + + "A1BE8AFF513CD9C7810F9F03A38654196B766AF0B489A8D9107E5611A962E8EE93528BDD96D22F73" + + "1AD5B591B365A507E5F7E1B2097ED32D9C21D181AFF39D37A15268488D3A114C29746F88B644FBE2" + + "000604469A8940FC9B1917A81E59E7895E6CD5AF47A50DE93E7B3C4A7A6F46B4CAF0DB977CFBA377" + + "01B0EE9B2450C765BFEAF7FCF8C5D2", + signatureHex: + "FA3CF2DF41245A5C292059FF14AD5C1597FA314FE816B3FC6BC0F6FEF6E9620662D42369A980508F" + + "9AC3BCCA6C7FEAC2A6D12848B777A0F7DE879D6ED37AFF460FAA136D4A9EA5E060ACB047BBBEE090" + + "19A360C637625E9A8B4584FB8E5D564A5A91D8564C93403B3729334DBF64160A23F5111C80AAEA8D" + + "742A287A14FB13526FEEB6D906C3101AEFE39369EBEC218372292A1A90C7908A056B59580B9BBBEA" + + "9060AA0DF7446A0E0C93BDC6D62AB9D66379052BF2D10EFC877B18C7F9C7EFF9F9F4B5949F53CAE3" + + "403787C1CBED4F996D911A52604BFB7E6BAFAB4BF839DF9488ADFE56C13CB2CB8F982770CBF1EC02" + + "D5FC7670D1974B5B52697BAEE84A7ED2FAA9421BD51EE622ADDA081F33BCCA65609E513FCD80D3E9" + + "41FF67836D2CF4FD29293219D7522DB8EDED578247BAA62A367734FFE586CB0E6ECD10E41624F610" + + "7F6F8AB7C6C0774E567C343D46C284AADC787C77F4967364CC74DB0EF5BFD6BB3449A02BE569549A" + + "CE3B61F41BD21A432DCDCD01C85189727280A0F327A2CEDA978D5CDF122C91DEE41072C8124C5A7F" + + "7B15DE7B98DD6CB67262F74EB372BB86CBDDFAAE0F5C312A48AE86AD67E79FBDCF74C1EAF36930DD" + + "9E97DCFE24B093627084086A91A21DE839326DD361C709D2EA7348C70E2BD4D3409F4F0DDAFF8A36" + + "D589F0B4CF1F69BC7F3798AF6648133D3052A7F43899715724DC538E8A9FCF93BBCEC520B2230FFE" + + "F9E7468BAFB6C3AA330E8C648360F4E4D59485B4D623F4E24C91BDA570F772DDB5A1DF45DF677970" + + "8FC421427347C109AD6E1472DCC1B0718666DF6F96528B341C228233C46A17E31A1D04D8E4B4757E" + + "7EE097C39D4CDC3F6EFF0F6D4EA7323FCDC36B4731C764D78981D0C77BCDB3C64CFF7AB6CFED7582" + + "E6EE0ABB1ACD7C4469A5D09B2C3C2E992398381EB6907CCF8346F492DD8A5CD4844B4309F9B94006" + + "ACDE9FD67A41FA444614AD33DB20DF6D08E7E94D6294C433FF99289E9D3DBCD3FCBEABFBB5098A3F" + + "9BD61CE7661BA2A15D64BF43187E622B562E0776F0A334E28346D73742EE343B9662C3C90A0E62DF" + + "504BB8D8959B671DE05FFF70CC3CA18B3005B9A23C8D594D67950E3BBAC16392840ED2E5E65C92DB" + + "F521A8A13F94ED98A4F8811291D65C876BD0DD1D7D09B724051F022415DED1031214E4E0E7FF8E2B" + + "DE8B4B007F71D5D38704E3E1A37FFBCABF509655133383DD5462FEE231B861615ED13EB375D775E9" + + "9FD06A08C23E2672593A42433AFBE6E27AED2D937ADBF3E64C79D58EFC23D22D8A2A2D82ADFEBE9F" + + "1BE3A814F11FE9C2A3B0DD5682B9052DE0781032BA570F654FD5D3AA3372BFDB16DCC02FF8EE21A0" + + "A300A87891267CB181F972E6F4A7BFDDF6B775E8901964D3CA8964ECDF95558D77A4BDF983EE5B74" + + "D28A3E8BD69E8102CE7CBC10B19C94334E2B40C2C33337C3DA0654CF02FEAEFA5020AEC116434A2F" + + "814A964327208B65EAF2F14C0D3B81E028DE4EA5ED1FE32A5FCFCCCC30E14408D0B85C6DE48550D1" + + "43969AD5933B1FC78D010A00F7A1D6D598A213514E9CA563D5A5EB13313BDF3E981A1E4A71B1BCE3" + + "652C2826E96CCF5B819DDF0EB5D0D824C2E230D9457318E248D92EDD99B1E4B08EEDB74DC175BCD8" + + "10B976FFF51AA459F5790E74996A34821E92B513CEC3DC96003B75A4AE6A1CB4EA0A72CAC6FA7207" + + "4FEA55950ABE427C5CEEC6E4257A962CD2438B31190AE3C89440C8E82F29F86065A447DC89543041" + + "E183AE2F7AEB5B3D2D7203FF578E36A03D220A0A8808A2819EBD3FE8D716154245C5FDA9F61287A9" + + "FDBAA8766C0F90FB0C8325DC559C27410BA9D8C143B2645762C1F6E879F45E8EE4FA5D922D05FA35" + + "5A15565C015BB4F64E915283BE6B9227F1770D331E7862CE9DA7DB3EAB7A0FC7E0A94264D1832ACC" + + "D87BFD24811A6308AB5DF33123DEBAB262F3F48A0042AAAC0FDD0991C0E748A44277FD16499F3553" + + "3B8D3F1C93D6805FF7CD2E2132FDE1E1081D569AAF44495FE08E001E1F5109C407EB3E3FF0989FED" + + "5825DA09D24A87FEB1B805B346412303B76F893FD27B171127B9A6BA6E7406FA6FA1CABB18533025" + + "19C0A40F00B8A8BEDA45292C1EDE80632F668BA6D8A85E78053775084B10F4A85E8339290DA8618E" + + "DCD3B45DBD7B68153F1B0F63F64255558E84EB4DF57173E517CB30ABE9F4F703EBE60C3A5E2A75C2" + + "6480772E35898ECA6B7D87E7DA2D853A24D2773D8E635490EE5D85DC7D1524936B75745308AD0B8C" + + "4C3CF819F8A83B92FF44A04A28700831D4DB659122981E15621D46987E04B59184F201368C74333C" + + "1912E38F5C88DAB4E2667C8D2F4FAC5BB88A990F577628A93900E44095D5B52FEB24D1EF0CC527B4" + + "B4E7DE297513B5E6E16973A4702895E1FFB0EC92CAD17CC33183859C9B824998FEAEE58CD54A47A5" + + "BC6F0869E00579E3B07AE365536C4D90F8BE55DAA815D3AB0E33962012B38281F7E9CC711D890666" + + "07D5EB61E0B9EFCF19FEE16049A39132D0B2A451471C60D31B9F8711D651AB7BF09516EBD5A26D0A" + + "4357687AA83600B596810F429B230EAAC473E8140537F849F8041488A3185F26318FBF69A58EEE19" + + "E868BC13942A0F4D392E7BABBB9305FF4FEE367D445BAAF582B308674296FCCD6467152F8CC7C6F4" + + "7A73338B612E1C2053151EDEE514A3D42CB6165C9535152BBA3864D431E24921D3DA09919CD062A0" + + "6B79F183EC30A0F989DAE25356D3E182F58FC3B22BBB8D1AF828B54C915A52867B7241701D47A495" + + "98915E0D3E8A228B29CF0CB2479A59B3987E7FC2E994824B2262578BC140FED5D5DAC8D49F61061C" + + "4C71FACA4B65A24517E376D2FB3F1588D22834FE4ACBC7B4C9A1C634EB9DA12F7EAE4F6822D8D56E" + + "7B1DCA8B15446BF2BDB9AAC49EB895A6114916E5891244391353876F176219F81B3A893D8557ACC4" + + "83989F0C5175280EBA080C505499B9F7C015303A1F8CE338A5BCF1C7E6944578C478277AF3EA91EC" + + "6EABFF505F6A9FB8A0AFFCC21C64853FEDCFA6210E61AAE31049A8ACD92EFFD6ED39F6CFD061BA06" + + "B64D80040058F371F3DF744D6525EB26CA297F475A4BBDAD979DF05D40974CB1001B6E3609AE6F39" + + "BAD7215E7D7B0AB5148F258C704A2BFCBCE92AA3BCB95AFD7E05C7801A0C6196525224B93C9C995C" + + "F641ABDD9B8EC4161345D20480D775A68A6EBCD16319B1985B0A8129F6A42152A97F3B118A65AE6C" + + "0B1E6A7A379B05828B208B6B3E1C5A1ACD8C1C4411C2BAB8413A016BD0789E0FC99606E1358312CC" + + "EEB249711F836EA949B053D9300DFAF46B1DD72A132F6575A0902568143AC31BF13A46B72E51EFEC" + + "84C0514D3DCF68DFE8F69A7AFED34351398D2E253F583E407742A6F63902CDBEAACB3C07ACA35D3B" + + "C84542428927B896F9EBFB7942BCA673F843608039023EFD3B0D381783855AEA53BAF32BB80CC2F8" + + "B8ECD72410C29C9D5AF44F4AB518A2D4CA0DACA226D8C62826030047B3043DFFCA796A1C69F6E918" + + "BFFAE755E186738D82BA1E44C880830A329D4CDB7A0EDBCCEC0224F2C6829607957419F7FDD8F87C" + + "6E8F25B55008118C897D4DCFAC2EB43623BB958A4ED435337B91173FC7F35BCD348D44F28031B209" + + "72CE708C33098E51112D89060AD1275AD77BB46EA33BE68E3EFC0072985E6E83AB68733591117FCC" + + "2DA666729C2F29929172F4492C4797311994072E427A631F23AFB9F3D52DD41A55DB510FECF49530" + + "25AA0E5BA953D3FA94B115CC8C7B82861787D915BB913D52170E21B79AF559FF099E6BE3DF6A02BC" + + "6D62C58F2593E626BD0DDCBE7836C5E6B07A87A8A45A291377954004342CD1BF87B3536CF8A7F9E7" + + "BFA1B23032C91705F239BC38E7307C62C8C886F5D237DB6CEFD1EA3099C23F6F66512D7E107D6308" + + "45A03AA08F7ECD145477F4777C988203F5A10CB81BB42A13700DFB3063A1086626ED1F7FBD6F4993" + + "6AA646F8F6E4A89FBBD58ECE8EE6DC832572C8DF1DB9C080503905EF3E284F874E51074A97DC1414" + + "A602E64D3F3E9E8DAC7FDA5A00251BE263BA82D8168CC29C671EFBE81D0F0C01123E800463F62E99" + + "DEC8D6D4516ADF553E42C44E1F88C9352D1FE98210DD8C2ECB0E101951F9A0E155B5724ECD1E29AA" + + "878C22F01E6EC943A6605D2D8515A6F5244EB42490D2EFF18FB603FCADEA74B62953CDA79F857391" + + "0C1D13DF84D576C7FEF889CC68BE9A1A41E1854A445FF1A14BED2297CA14A8188323FFEA9F475D0F" + + "7E65A19B2C59F9E9CEA1523C12C2DE9B34A3D5FE7DF033A7B9D68CD48C3DE4A322C1B249CFFA9CB1" + + "9276AF0E0A53F2E1AAFDEC8B6ED7E44D77B854F86A9FABE1E0B7E324521C9B3CF6F039EA84786C98" + + "299D20EFB56A6FA9B58760F7655C98720B3475CD0A7D9D9733600155FE79596AAC927913B1F9CDC4" + + "11840F998EE13421C9C69740A8B27A979688ED87B6C22EF84F50B38CF3AF8CDCCC30887E73E30CC0" + + "2EE0DD47D4AFD103734B38F621CE700118482BAA5358D0579AD3A03BA9A95373E4F2586F05E77B4D" + + "2DC9B1D984560D1BE9D3494E663FB8D5E06FC5A7EF0119B83A0B5D4604F79ED924ABBE2CD3597BB5" + + "FB3FDE5CA5CE3A7F66A1CBDD6F95FC54AABD292CCE8AF3A6C53459AAD5934033B26755BD40F127E1" + + "BD993B78E46CD887E1B12BC47784BA2EE966405F3176C7CA9A9FD4379F734ADDB12974B6E37ECDE1" + + "EFD82973ECACA99F903902D33D64CD2750D01FC87317283D7D2D3FA37E596F3350B4A6C44C290095" + + "BCFD2272B3E3B6713DE25AEFFA96568C98E208D62AD77796A51D4D060FF9415641454877E9EB2446" + + "F56ED7289FE753D09B70467E37C3C2F49348ACC404924145CA63C7359B8790AE92D9C8F02B107D0F" + + "F4221B7BBE979439800F4878EAE214EECC91189CEEE94C750D539EDE688B4AFFF7C5BEB1FDF4EEFC" + + "F5E576E89AC4122F4305ED531232B5146E2D18A03B558E9487767EF0F614308A8AAEA8F22F20F9BB" + + "E44A502EFCB2326AF2946C4D978B1ED04EEC08EC636EC1EABD2CCE01ACA42CE5D7EABFBEEC7F8998" + + "B97CDE055CBABB070D4CCB8C2FA3EBE5F3ECC1DBBB26C8983EB41C53901D40E2F6F8B85D3D4DEF0C" + + "B430A56659CA46D57A19E55FECD5E4E64320668C2822528585EAB7240CE0359FF20B83AB9969A33F" + + "D02DB7C710A829FEA73D20563109F46380D9077DDAD5643B2F9B339B22EB983843011EABB51E1EE9" + + "0360BA757E102BFA74F722B9462C95D2225C1EDD1958E431589F2AB77C5568839E5B33D2045C5E6B" + + "5B89023756E54D883CE3905265CF5426D38134759379EBAC8207A7464152055E9E8870B09903901D" + + "A7B24CEA76104F2B6088A3E3F31A0A2D806D17567347ED01750B49A0E920CFF03C6BA72621617008" + + "FCA65521387239B85C8FBAC38CA3FC29DDA2C94D0094939F0F756A194B8A553ACA6AB82FBBBC09D1" + + "F343C37D5F40DC5C3A49AA3A9315A444EFA271BB5790E1DD9ADFD587785ECC848CB715152210877A" + + "EE3765508D4A6A9BFC2A44BB30DB95250B6A568EDF8C6EAB5F3D2EC60FB3EF1128622203ED8D58D9" + + "AE199BE9AF55E724F1BF441A500858A9833ADB3657D2C09866CDA4EDEC19486FAD36B407C3292030" + + "BC5DBAA404FBA5616D6968B2FA7947DA31F9E1A63111491972051C3F2AC4CF42BF7D6230E6F51459" + + "33B6FADBD720A9E8276531CA5A557371A7EE74305F03F283C1312E2020562966F92D41F67175F9BA" + + "2041221882228810921D87E92A792F14CE5836538E95C5E5957C83C2B7FCED30C62B46E2AA8EA099" + + "AF9604F8B3F35CACC6A145D2CF4802067DEC49ED9D932A29A61FE66B70DA6F7508E6853D8BD48FB0" + + "09252B2EC07BF2EB3966278FA4C4D906052A900E4B9E2F2F5253FB8F897E2C6E0D6E148972217354" + + "2D0E89168192151934BAA713F8A08A253D3E0FE5FAFD2482560426A19702A52488F6858D6897CB58" + + "922F0AEAD88F41C82B5502B1EFC587914115F924178C33600AF3F3185CCF5346CE899806A7B9C410" + + "372331CE6DEDA58CAACCF68AEE8C5D0018F97C6A61AF128BA6019AE18A47ACC1F48E034729470704" + + "679656078304212AA569D56A18E04202B75DCF734231169E8CAB2DF7195E3A1672A5328473B5CF74" + + "20632DE878F4176A969518DA03C4D2993D4474022B7151A2A37C32CF775721DEC827896A92F8C213" + + "AF7554BD022F7A7685BA10908F89F64363D0D6E8FFC059572EAEB210B68885299C6A802744D068C7" + + "7F3B5D46BADBDA9A3619DE6881C4F5321366BEC98996BE53E478B1E32E5DA19694FF6076C6EB69DB" + + "8B59CCA76E0C2C36C5294E749B55B50010657F074C7EC61FE3D0647A282E57A363972CB27C788B63" + + "2B63BA3E1821155904F37C6A691D5530ADE880490765A1932182ECC3B77BDF0F58304EA092267C8B" + + "56F649F01A05E0C2A5397DA5A456B414001C3AF03329903D49B1B6B9EBF21035516484A9E4E9F53D" + + "4775919B9DB8C443696E82BFD425B1BFDD043038627AB9BDE53683A3BDC9E5F90F4F5CA5C1FC0000" + + "00000000000000000000000000000000000000060F171D21293037", + hashAlgOid: "2.16.840.1.101.3.4.2.2"), + ]; + + private static MLDsaNistTestCase[] s_externalMuMLDsaNistTestCases = + [ + new MLDsaNistTestCase( + nistTestCaseId: 91, + MLDsaAlgorithm.MLDsa44, + shouldPass: true, + publicKeyHex: + "CC54666376A8F353471A16C9D438D64D98916A1DD2E189CA126EA755E33D690AA03BF2D19DE59E06" + + "61A6A5C872EA26FEA8C3641675E3FE1502249F6D47696F93ED862CB8B57D066388D980954AC0A902" + + "960FC21AAD9DE622CB801E10F9A8C85F77DEE8E563CE2EF845FE94646A3FCF2BE04697069B0A1DB3" + + "9C99C4B06459138D0420C2ED4C57B61EADB8A87CD396F18378062B6EAEEDC156DB292A24E6D89570" + + "3801C353FE96EC00863943F0EC9D736B54DFF36E9DA4BCDF1703914DD203F6FB91DF58279EF9D67D" + + "28E0B7F5840E79123DEF9DEB23C5DF05446F2FB833339F5DC778C35E2ABE80B1C7DE0108810FD88C" + + "26DAB205A8450E46F2145F3A2F7B54BE43EE7063612985C4B0A5A03D33A60261EFF14681FC4E1C91" + + "DF5D8A482482164FF1A4FDB9C7F64D27C64C7BF802FB6D6913A627F806D139F67247FC3643583BDD" + + "11C054EB6BFCF5D9B7664B778B89C0F8B6C48C3453CA596AFDB27AEF4C1E99289C8909A822ADFC9C" + + "0AD86B74582B0CDAAE69D290338AC4355AD99AD1904CC170A09498DD9FE63CD7F19EFD4C2F7A2DB1" + + "5254A5B4A4E360DA2DDFED8197744893B77125235C13022D21CFFF8AA96CEC11A5BEA3ACB9B8595B" + + "92F5B04E495A10DA0DFC957EF9B8BF61BCFC3BADFD1EA8FE3BA7FF40F1CBD851999689998B48A78E" + + "8EECF1C70A3B88C26EA60B9098F56D81761B167E188845744A7987BB8110404F36D8DFA7754683E8" + + "C8F67B15C6579F067232F6340EB5747B24A64F65EDE92A039DAFFDBBD1A322CD3CA93D1DB03D5536" + + "209FB12A345F449D98C08C4183EFFF74D2CE562343C1FA235A8D33F1D6AEE6E81AC08209A5395370" + + "BEC02848246209D8AF3F64FB3708224506A3C8E70E1F07C203FD23F6DC1856B32CA049BC87C7A421" + + "23417704DB69496B666D67B04EE85151E2E2922D85E263AA41C01F7CA93B5BAE18A63AD9E99DBF37" + + "02EBA286E2CDCC76AE1F9B88F6F69AFCB994FB944269386C9DF238AFDD24800230074B2307C7F4AC" + + "EECBF4C79CFB480907016D231E40A1F107A6A44923030861C635784678D9AA7C0B385AE8024F18F4" + + "2D65B40194260DE38FA5D0BD3643802D074CDF235F288EB83E4F7DD63242598EFDC03F21FAE4766D" + + "54DC0C013EE13F92B2E8CD9DFDCECEF4E18E607206D88E2C77482347C417412A6D42AF798AEF2736" + + "C8D060C9FFAC1708CB312C581A8686B3055CACD5F6726B620AFFD092561ED218C4521865DA513B9E" + + "EC8804B63BD57A60678F08280DEE9F52A8780EB0FEEB0955517C614C369E8E4C5CB01BA2D819C5A3" + + "C1224A3E79FEAAE3CFAB2AC9C73CA213096F8521789C7A49D4A31A143C65E53405AF5FED2ACA15C8" + + "3C4DC761CBD40A7E8ADAA4298722D1D2D7307CF64DD551A1091C9C30633B62F2535F5C612D1B283D" + + "A34BBE6731CEFA8F334B8E1BC76375035C38E7895C0C5FA0CA63AB61668BD75889E3ADB977F052BA" + + "B420C65E6FC24F38B073D5BA1F0E71E301D524ED0DDA4D93DAD3D6F7E538F8B07E331F9CD450388E" + + "9776573631D1DFBC24E5309DECF810FB6A10EFD6FCD0CFD3E305C47F574DD18884E4F5959B8637E1" + + "18599EFF9417729173AC25428236E7BD4C3C271D47FF633D1C4114D5B0097C43554C5ECDF64FE62C" + + "A008512DBFB86BBA27F9CA3BD4097170DD068D0CE7F510716E02741D170589E64CFB05B6D2E19CD1" + + "01044233A29CD516D82828E6684EE7498B79623FB3F980F13ED2A07514CBBD057106CA0EDB9A10CA" + + "FE878A1EE7792CE390AA5C03E49FC348373BA68429AB06EE9E97153E19CF0E7D0EB9088AD111D725" + + "3BA8927F67A4ECAF7263EB445908C087F5C12EF5FFE089E64E4776DF8FC67A4A", + privateKeyHex: + "CC54666376A8F353471A16C9D438D64D98916A1DD2E189CA126EA755E33D690AEA1E29B5B97E7C0F" + + "70437CD6E8DCFF0D9C30F6704741C5380E837DD14E80902D72231A4F23FDB7C69C1FF0F48A641DEE" + + "1364C2FF06FC4372894B444662F073D7E010A6B44B06E03096AAF18DC4DF66F903C9873EBD21CAFA" + + "C5E623CE82BD0D562332048C066158847008A66119C980CAB450D1184A9234844C9830C4C4200319" + + "2DDA34020A087022496992167114816D09B26DCC122E18226DC28801CC865012104013A004014645" + + "0C452CCA8464500450C320498220004B042421470E1BC8851C29311296885AA6005BA2800107511A" + + "009014894CC2A00C2133528B226E51A461202972592032C0885064247184124513130E1B22228406" + + "22093226180145C1C2652418649B02269B026D18446ACCC641E3067108C2481235521CC170213171" + + "9B266C129140CCA02484288D12A14C9AA80502B88C0B8749D3A651801809A13846229871A1C44D24" + + "216913B264C1A81102318CE20886D2008E4B440DC9B04542342913266449847010112A9C0410C102" + + "8024108D510809C0946C22392CC0382E02904003472210046E54C22989824D23306ADB260A5A186D" + + "43024914088218382D18490440B668E3A684C38860843450C2B884190345D1861112301014186C48" + + "A050CB821102058DE41260A1127022C36000392113C24193A291024946A018914B88701840028C88" + + "415A96840405515C022022846C113889D3B491DA22719136612097240BC791D03202D9284CD43822" + + "88A01089B8411831895984240AA4701106464832520AC89019916481068841808500235112476EC1" + + "B4280296405AB2485236619A066C13238C02164D010671D1384E1AB20CA23066C8288E8292690185" + + "64E1B04882084500070293866D19B1019126725C844114905081128DCAB84D1C44129B444249348A" + + "E39011040791841664C0C090D42432E3384AE0104504A02D9CB271C2C009E3102211800883924123" + + "8190A130290B8920124191E242494C848153280121C291D8C42D23C308049585D8C2518904889C28" + + "4119B5050324050C922502130DCC4024C01005233169DB084912199158486E22294E89B011C31431" + + "4046028A346649105014A38092168D4940010A070900890949084203371120377098A88960446E0A" + + "438061100963A8890C210814C709C38424E0C248E11848CC964C02360544C690E220080189651C07" + + "2E029769D42010D3060A59A06D14C048FB1A5DCCADAD439F22069FF0FA00FC34D2178264FB3E434C" + + "0C7630E20A18FBC163AF11A5F0821EE303ED78345E7F7F8C92A07E2CA82A9DF02BC20E58F095317C" + + "E4B3C898E90290517B0F3F9B003C9D42ADF4B9A658E311B41B7D235B38EB2E36A2C3D29F4938BFB9" + + "80D68F8CEF170DAC0CD7A102C69D39EC01E9B7E9AF1F6840C6CA3B390C58FD3247DF75E161F69EFF" + + "39AEE27AD37692827E42FD2E9194F1DD6622AF6A1F4B92C33FFD5F7F6EA88EF30C4C785263E52CFD" + + "1E1D0685A4FF953D23959052F481EFFEFCC7FF067EEBF3B59A66E34153488080C07CB0D2D5195CFB" + + "5448A6C8E9B79E46B0BE080C743D3598A4E9A975387C754DB099F8CECE6A027ABCF1D568F727D7AD" + + "7AC993C16FF0F19ADE07FB7929707DB0316066FE5AB35135E24DBD3A19A72EC04D0FFAC794E75BF1" + + "6339D5977D3A887705FCB60191E5B82060DDEB56D985E3F289B990B07A9A2D0B2A3BB9E4F831653B" + + "6FBAD8554B8B16D9C25AA3ECDA1AC2B32AF2F55F0A6C5DCAA5EF9702DA6F2FA6075A1923B718B8D8" + + "9CCCE6E1BAF0DFDA0D7509B180970EB84C0ACA8B9695A8F283878A55ACB5A360E8B96D00FCF3F518" + + "C22F35FEBA14668DECCEB0167D21A5D49FC76DB91EF29D95228D7F15E705E91D7480D9BBE0DE1982" + + "668BDC97C703A76DCAA278BC280832D45F05621A9A5FAFFA102A172E543BA3C5380EB20B5DEFA665" + + "4020B49A08CCFD693CE8CAEC190A00E6347DE846F6066F1B000A48EDA723148DFE97BCAB5D92591C" + + "4B5007232A8021A8B76BAAD6111991DF420B790652EB54B5DBB2933C86A05A6D0F0595B9859876CD" + + "3CEE3738BCB990C08039C87501BAE40B38842F2FFF8ED4F9017CEBEFB1367B6D7460251C6977700B" + + "C962A2E0B582E7C2876931E201214905DE237C93AE19D1D18B677B556A509EDC76E3C6422CD0EC0D" + + "D581B740DF92E1B366C7CF2E19CE797511B2F514715ECA342A1157B11A8DA5D4063B397FC7C2D530" + + "50DBE3F716C663D0BDEF571117A9C09AF714495C3CD7A74560DAB41493EA73166208510698AA7B4B" + + "444A181993763DAAFBE6FEAE43EC1A70F478275AD96DF50C3BD89740BD65EC7A689D0AB85DC7E251" + + "EDC784293A08F7EFB7859159607057DF444D0042641A86A66455E9E32918E1DB7838F86E56260BEF" + + "95274102F2F540E68931C699C60C91B17BC5068FF8310E790858D9ADBA119D302D30EBCB72673700" + + "5F772170E3B735F5144170679F092437B7D677070504D51CE1FF9DEACFC43707F490C05547276E5C" + + "821B035596361591DC931EEDCEA158CE4C694DB8D35DA7990C5C32DDE885CD6ABB029A1085466335" + + "F83F3256B64F78B8A939D36F9AFD3A61D3F830B0803F2459A62AE522A5DDCCBAE74E9E6D6E694857" + + "9394FFE8F1BA6DF780E6A436BB011BABB28322DEC0CBA8FD24F01007DA65A15346C0F8B72EC8E708" + + "302040D19EB2709F22213351BCE40E8F84838D4FE1CFBF2A53C6BB1427D4BB72E73C7935A38F7C89" + + "EB9222C5C64C2648F7B1152CA8009212244C8614F616D356260EB52816A42A4BD2D5CC2B4236CD13" + + "F3240F1CC120285F0636104F22CF077BFA9AF92963E2B60E222251E2EB3BD15D51B114A540C5AAC7" + + "92F6A9E289C32F9EF63A28F75FE434C35D22C1F55E46559DC07E2C1B9EE42A6B39BFB1D387267F9F" + + "21949EAC48BCE261AA1BF9C58469F2F4BB68A85A864206DCBFEFB07DBC6446D1EB879F15ABAE8C3B" + + "E1E302F86732B55453EE9C4ABAE42DD2FC0B7E7B4DAB6D7BDA8B42BC427AC78F5E62A6356C0F584C" + + "9130FFBCF307E3652200DCD1A8B86C62F48FDE8D5CEDE7D66B473993699F883404C197301D41BBBB" + + "902A2B6534A3C6B46A920FCF6DB05ACD06DE6FCCBC8B1F9D54D2844A2C1E9F089E89DD02602C4EFB" + + "67D0BF167BF4332299369737856A770AD281552E2884D6E7582397C3DAC9F9A113814D19FA605878" + + "786D9762979042E36CA21C4D281AF7E381783961D5F530D040DFE0324F78D67B65E1BA33A021C583" + + "64E0B683A11C3CC1D8CD11CC831E3C0CE2B93D7AA50757F20AA49F732F8ABA62A10756240CCAE931" + + "F5B5BBFB2AA9DD7DC2B871678C48424281A23A9A6EBB79138E044B8724F2833180C3FCB994DE6B56" + + "9FE05DCF61D03BAF5C958356AEBF5CD39D7C24DD36E9E430AB90FFDEDA2DA3BCB08EB9238BD9E2CB" + + "593C30C965C1F173414C2BD8AFAD407D9D4D0601E83EA9EAC073E10333E37DCF36D7E9727A4896D1" + + "D6CF6F296730F841B963A1742A03E73A864470F0843179A1DCBA136A7C9176113CF00F6BCC117E37" + + "F8D959F11E793D166ACB91C3262770F072E539D5FC61154ACE3F86C219B8DF11722E1B873DB5B318", + muHex: + "210B3DBF8242AD7049A64D58FD830F09F239EB89FEC2A2F05C3005539DA4F52A5E504E71FBC6F9B3" + + "E75DE4717D107A3D3A29E1E143CCDA707D39867CF595CD2E", + signatureHex: + "B2DE7C2563AB34A1357965459ABD4CECEC3A2879B3BDA7360F482B554DE4DABE968D41C74FDFAA23" + + "9EFF0A5FD880EE30FF391310825558F945F9A602DB653434A91E771984BF82C397745962BBEFED74" + + "44769DA1AA776314A49C0B8EF234930E0426622C6067C3206C52A15BAB91CAF323E17BE75EED01D4" + + "CA49B57A6EC5CCB4C969B8FC14BF13ABDA42B61FDA39BD31A32D3D6ED155BA207AE53ED84A26DCE2" + + "BB4C5ADC0254B64E6398159C8A2FF83FEB00AF67D9E48277F0E74BF73678508EEB59B95300E01D0B" + + "5AE608D2E13F7D7BA5B906F8DC246C855D4AC63C106A8160F60298D1F1FB1FCA7DC56279B8DDB920" + + "4571330BB8FFB8F206CCFB9BB2B97EF7E1D45160F46F41EA80A26B3811CE8BDAC0FEE18A55B036BD" + + "CFFA5A58B32EB9CFC8C08B99AA537DBF6283AF6693B6EC01C5C9F628D71474FBC160379AC9BDD910" + + "9C795947BF8E86ED48E991EDEECA6CC0D99B22C771D6EE33990C529C0DCFB6E22EDE5430C427AA28" + + "7CBCAE619C1E5FEF78B135EBCCCB5FF335BD21A1EE0139B85417695C95A7DD5517E8EFD4D430692A" + + "ED7D8516F359B7FE2A7F9F20B26C0C2DA1BB2BED98A5CEB4A2B34166AFAC22FBF1BD9DF1A951DC3C" + + "D6D59CDDA3CF0E30F0F6A3388DDFC464F38BBC0AC9FA7A30E6995243C726C118A16E3ABDAE990B47" + + "247BF5A06F6684A4802C450373C4A9B31E3FC04A86CD7BA9CAB8ED106DBF56EFB167AB35FCE86A5E" + + "77F45D558203F3987F9C4BB45705619AA82171C6863431E9CD1E38615DCEF9DA734C541B1FA7C008" + + "67D15E8E9FE3F2312325FC63FE349C28720155CA7B9D7AFA023BEE2F044566A973CB114B02F700E6" + + "03F98987737E4075F052E4FA6FA7516CC8880019DF28F02FB20F695A63CB571D7616A2FC9DD32431" + + "EC272F678E4A8C4D08113C86C45D4CFC7F93F1F61074EC7AA9A2B6081122E004E62F4B4309535A46" + + "6714FA26AB1D595045798BC3B7B7C6CF7F263757F616A92B5ABB0E26950DBF946E3BA3E71F81FAE9" + + "3F18EE0B8564DB45C5CEC5F735016F319223839D5E433ED82DFD605CA16CDC7D69814F76E4091D9C" + + "2BD6CC58C6C88DFB57AC69F277C503086959C8F7FDEE1847F2B5EBABAA9D79F5D7489204FB0F949A" + + "50E09AB6FEA83F855A21D7B539CB4B5A07F25A88AA9C501879E9F6393E4536934AD2AFBE21DFD0A8" + + "7712285622F56881C9F7A31299C1B81123C7EFF117ADC240C83835AB84C9C5575510A7F1AE1136A6" + + "062D3089B69F8C16002E4C09AFD65170871C250C76E1996A97B70DB3800C1E757CAE6F3A30ED3388" + + "81E5D256CED04FEA9657237A2AC41019A17790DCABEC33990273A4F805A8455CA9EBE8781D80762E" + + "35C1E058A265DDA3A5F9199B22C494CD9AC72DCD146E9423DDED86F526D5FD2FA5344B8E7746E63E" + + "6A491A56AEE76C56E9F9C0E7CA066F80D675F4C04E0C8965E7F9C6A83103E60B50D095605EF631BD" + + "37C3611EFFA979A8E8FEA3411D2A46FD70DC72CC578D9BBED4B9D3CD70011DBFEDE5715C80DF0443" + + "CED6804C2A0DEBF1EBE0010F50158321A52D357D97F2A0186C93D4EB0359554F7891E12111ED542E" + + "B326BB59364E344C5231134AA3E6D08CE3EB146BD79A560EF001A5EC167E2D5E98DDC1FD6089C0AF" + + "82EDD9269EF2DA61A72368BC489291AACC72A6AB512788E1C36EB3E5E54E630E1028457AA7D951D7" + + "2AD65F1220549AE084B3E9735DB00D1FD11300706378ABE3E9425E790C286CAF612055E29434D527" + + "271B6BCBCBBA1F5224882D926E2597A5C1671DBE808CE57BA47587A014935DB3674E95823BA40D82" + + "A7F37AF5C318EEDCBFDF78F8E7D5231B40508AA907FD1F50F7FD30913FB6D5FA3B17F4F785DA661F" + + "FE492D14C997497374018CE718E616D562AD9BB643EFF11330CE4A94351BB8D7A755A591777A30F8" + + "866C2D2B0A2E56A2BAE6C490DB99E886DF9575AFE9D118A0F5524BD685F004FDEC6C07220DED68E2" + + "7C20E0B440AC8D98B502BCF85ACB0E5885539FC160B5C40EBC7BF7AFED62F5F8E8EFD7FB7316D5D3" + + "E45DEE96679F8594AE797FB01177B3A7E65A0E3F92EC46E083D13089206CEA5349463C55A876E08D" + + "A1161CE3FE5870D89856C25615C616D9D117E06D336BC52600B7A3D7CED8236631C7A950E80B0675" + + "98F6308D7A4DF098738700F697FF5349B117571288BE85A48EB282393E7DBAF2313518AED4D63D1E" + + "4812AF24C9EBD71FA1DA9F539BCB484CDE5731EB0C627B63145EEF264B2AAF67D88A19342936B745" + + "861580E03F7CDBB017F84D55C2A92B714CBCF81435197E06D39D078D2530B8DD56F2B5DDB110CB21" + + "FB15A216673FFB1CAAAF32791239046ED7FC588032A005DC814A12F596CA5CE813AD6C23854E6893" + + "F773EAF71078FF4F5A6E948A811FC4A1636C8A7F41DBEC20E7CC966FB75E858FE27F97B86FFA8776" + + "C557F1608AA12A90DC9EA554B15B25A838E17A687E1B6EBB2DA8CBA4021617EAA84E29ACBDA85939" + + "7EE3D01B468B8B97E060408D49FC3580C8B9F987CD47C470BE89B67DC84DCDBF6EE4920472438686" + + "EDD12D64EDBEC8F34B341732A4703CFC79158868F37AF3D5D23BAA41700F649513AC85168560AC6A" + + "74D107BEFB88217743AEEB34D6B2A061A49CEEE1C3BE75A8BE2388E21AE1A246C4894E502172AA55" + + "C5A4CD994266F9A5EDC95FB9F7F69A131BDE7F167E69B7741991DFC3543FEC36800FDF9616914690" + + "31B4684CA2C94A5F77DCFBE3F4B8E42B56CBFCCDCE07FD646DE9D272EEC66C98922F29E4B23B7869" + + "8CFEB00C1121A975C62215DBC231B482FC04A3129F8993773CB40BCC578ACA083F1B050C30BCF2AF" + + "9BE8E9A48CDF8D3814C532418BDF9255F6E47F64882EE634FCE834B72B4DE6EE15E01D14AE20FF63" + + "D1366E78D7EA8755D34039A800801A4A605A7BDCF17B8FCBA9A817501017DD95A309DFE8D34FCB18" + + "D359FACF04FCA6EC694106ADB2434649AFB21CB50E40B959CA97266B2DD1F10E0D61FE5155FB5D9D" + + "D8B0767EDCFD1ACE0657A80BFBF694FE4C2C2914410984CABB6444FF030D877A193B40B1443AAEB1" + + "DA0CE0C5DD53682083B5F8D151969970C68C4B6169116FC524E0939F4FFFCAEDE4FF521D537E18BF" + + "1EEAEF2E66EE5518D8673D1272F2086BE6CEBFCCB69C0D33F1F41441DC6864D90A5A0150F94690C3" + + "524FAFD7E89109EB031EBFBE25C67EDBB6414517411AA969CEAF04438A60FBBB428451976CEB2333" + + "4624E4E25AA002BF9020E75D571472B10FA00E314ABF65693A67FBE4E7A3DFD5B73375F3E6ED9DBE" + + "677E5E8DDA87EFF604FFD1A4ED40FD420416313A585C64737681879699A3C3E2EDF712162A333647" + + "5B9CAAACB0B6BED1F21A30343C3F40494E60C1E60E141A3E56606F9DA3A6ADB1C2C6E1EAF7000000" + + "0000000000000000000000000000000012212C3D"), + + new MLDsaNistTestCase( + nistTestCaseId: 92, + MLDsaAlgorithm.MLDsa44, + shouldPass: false, + publicKeyHex: + "CCDEF3BE4A55A6AE410299BC2A7757D1F915078AC82281072DF79C566BF1E07225DBAEF63A8FC096" + + "CB54A18D3422C52F386BDFA275353BB29B25CB4D8CC4BF05BCA2DBDFE66C12E58A1AC347BF919A7B" + + "25CD8F66A63D4DA4937D26B63AFE09AA54E2291CFB65C38CAECBAF766C54899FB5EA68491ECF89D4" + + "D52B74906B29534A0706E6471D4172AFECD0596B1B6D0DC5A9173514864539B27B71D5B98EFDB513" + + "0BBE927CEE2ABCAEC5C5B0103B23AA019DA996F4DD43196CF1507D7A4A0E998F2F63C365B1F8B109" + + "BC1B1988F3FCAF3840D5471510E1E1436FB0E1C34061C114EE4403BC70B6EE97B884C9D34A728DC9" + + "6F5B95349DC70CC717F7DA76B9D3CACE8591CBA380A14864A92E32C2FD5D62D13020008D3F754B56" + + "C183EBBAD2A834C5DD2D93655CFF07B60B383662493A37B66C38F9512675081A1F5F7FEE0E5D2B92" + + "B2808A7B75033FAE3E1E6B5B94ED1F2A636807957466ACE6E9AD54A2821995AAED843128AF61361B" + + "5CF598708998432598A33CDC97D462BB6A5A4719500989F082589DD88EDEFCAB5CBFFDD8D09A4F98" + + "FEAC7E3866E858D268B4D2E6306EECD78B4E4316E6F2759A302632B2ACA36B4D4E0C28C05B87A913" + + "A3493B39923F43F407CA154F2A1E14A0A7C621FFC1B70F9C9722B15582D31810ED44980BD47103E8" + + "53F1508BED1C361559E52AAB2FCD2997A5B34F6DE2ACCE36056665D35D9D259CBC67C41F9543C9D7" + + "12B057B596DD41D5D3808069A8D1E11710BC0E96C19A84585BF487CD2AAC3280DEB2C8A131002F0E" + + "2CF9DB4516073552729DA2075EA759F4D914A062FA5B93F1141F12DB90BC497CA95D6C8B7347400B" + + "34B3A144BFC3CDCB4B871203FD6C57D58286FF99A97D5FDBA8E4D9F9BB209AA8CC299733AAEC3B18" + + "C3F61E7A25B6FE47705AD295FCEF149754A35ACB33F31836D1F557BBCD6F22FA29AB13D5498BFA14" + + "4415BABB86C55A70DA5D969141574775B52D7605F5F8840E3F80E12FCDD3B0242C8361DC9BD588CB" + + "8FD5682F7F34BC630DAAEA75478AA1E219F7DD6E4AAF4B867806338ADFC41243E6EC1AA4698276B0" + + "7F7844AAB98BE5462999539B3E75CF717619EE0C99886ECDFA5689E87E8B034206E137E9B39FB4F9" + + "3E98B5C70F347498D77053ADD6477C4EE05B7E01B81FBAA72FA1B1DB10F1C952502AC6C9AAF840BA" + + "AC032B5138906EA92599C719A67C65A36F2D9352D6DAF74A432B98721441205D01AE6F372BB32676" + + "19603AD92AA944F114349CAFB5B3597429AC04D065EFA8DD555BB8AD69F2CBEE0B14171B4E14CA75" + + "85E4DAF0D7604BCD89005A105EA8DB585A936A6B75131B47B7B570458B95C630DA643A93EC4366AA" + + "181DF9439D0DA9136ADDE568AA0DC353355B65DB8A29549FD460A75B494F85D13401E8C0C9C44E97" + + "5B3B4221911E876D7ECF6648C2770F62557C23C5D12B0368BBDD9F875603FE0CC2495C0AAB3964FD" + + "5B22FD177494C37FA1E00ACB84B2C759AC55E1B1B5934A0B880E4702153B6B8A6A3C95445E06C950" + + "7FB49DC08072EA574BA94FA68F315682904F061F7F8DC5E6112DEB30BD64D8E1CA7246CEDD8744F6" + + "F8A38F74766D30CDBCE18CAEB672CBD491E5933DE7C088190CAD8A2732A130D674782C06CC893662" + + "666AED83F320570065AED9B54A470DAA74DCE4A34ECAC09DBCA7CF68E72460442C6403F2C032434C" + + "7B4F04CD3D963ECCEA0C6B747C371B1509114A1020DE1C7497ACF9AE68B15C003A163C89E8F625C3" + + "9C61000B088514CF2136A0DD30B0341368C2C3BBADF0641CABBB168780F0DEB67FD46A526811898E" + + "19DBAD2C384E3AA91212D2A8B00758AEF55622A243B71ADD10600733A2C5C95C", + privateKeyHex: + "CCDEF3BE4A55A6AE410299BC2A7757D1F915078AC82281072DF79C566BF1E072DE3D3E91F438ADA6" + + "FD6EF83D31A8FE5913E5B69CB10169824623071ED1045A593C3D161059A0231178B1C2FB4DDB71EB" + + "F464922E1923160AE3F724A6390537CF44E03A0FD550BFCC5F3DADB791336A874F115D376DDDA265" + + "EF6D6915F8D8130CE3085204224EC8060C83964CC0882484B4608816125C000E63983080460DD224" + + "041B1831991866D4C42504A20810B92808C40458142993304842442420016211154942986902184A" + + "44A46483468C43046C08A528DB8625C4308E02376CDAA2245C966D48126D82968CD9C620DC200CA1" + + "4072080246603880DB2665042145C4360C89B06D501220A0B0450C47529BB011D2208651384CC338" + + "64C1348CDA222C1B473140C831D2300018A17141086D1812200C308E12C89114416901C92941C450" + + "A1C051C0260D11278ED33448811652909084C1028EA00041E3A64C4136718234118B3650C9389240" + + "961018346E0B00091BC20424066A40182C0CA43013294C08454958166810358C14236293A22DD4A2" + + "81110931D926605210815CB07020A26801C249D924448B109008282862B2418C1450001248C3980D" + + "CBB44C4C484D13244CCC202820332C82B80518322C801611C8142E62064D03188409B18D441806C3" + + "C808121592021670DA368603008251B871024480A0B825D8461043A0511A0329D492311A242A9214" + + "30443865820640990620CA928CDC94245C48854A120623162E04956859B22820A22811A45123A141" + + "81322C8B4889114969C3164D590091834471234592902261D9204141082EE280811C17040999851B" + + "252A63980C54128283226C13C98502C3684C3891500261444808E100521A304509A929DA46040020" + + "61DC9261CA16524AC650420452C94440C2C08581A08802A091D23265132324A1048E62102923194C" + + "91286D1C248A1BC19061142901A38942405252A09002C2216038608A484A84880124244E0AB26810" + + "2550100385C0062D61868911A289A2120819029209A34D90C285108090521831E396010B4122C882" + + "6C48900D5312491446020242880198218412220096215138040048659BB010E3B08C109505CB1480" + + "4C86041B28510023049AB24D48A090A4104E4AA648224772E48251C8B261A4A251530621E2840D80" + + "2428E08029C2C2101204041C457013A265CCA84DE014251C361180022601232C13140A43A889A424" + + "52A29891983008C9A84CD2162084986C5B3E670B52E742FF18D65DAA5918B0A02F49CB6F173B4391" + + "81588B3D8377DAB51B84A8E5CC66F92CEE7595015488891C8A9D9421CAA103B14FEAF08DB6FC0BB2" + + "DB97EB0FFD68BE0A79A1B9564E65FF995EB7D21BFB26974B2DC1983D0DAD8600AD122B355BCBCC96" + + "CFDE8D1D6B3AD6A09A99587C0269C4CED152BEEF6777F0A01C2DE6CB85CBD59A57B9915F1AC9F58E" + + "F3F34A402F050C66911F917A8DF82B79C5FF3DC96CA4F0CB70ECC108CDA0AB3A1C837A54C1BF501C" + + "D082D4D28C351C18783164BBDA6A3135AF629BCD0D02F0A9D69A0A8ACB770AA5AE942725146042C3" + + "4952EFE095B4B31AA3D2BB695483387C6814953B335CA625C11D335150A43339576405ACC9C6E72E" + + "D778ABB124CE473F30D8CCF14D3423D464037E763B0FC3ACDE1325FCD6B4CE4E34A123F83389A5F1" + + "E98601A33AB5F8ADB51F4765535F40EB4292F335EAB5C7111AFDE0E77C8DB52499DC322C5249AD7E" + + "1D157CD8421F3C1E46515A66FE2E0AF0FF0E0A73EB7F0069588FF951D6C49373444060598B627CF7" + + "CF8D7F2A8A61289CFDE00409FAC9C4E9BF9A8EC3BA4F6EF41438839C84D3FBF7E7CB7103AE83ABF8" + + "DEA88EC5B328D5261D8EE011FF8BE96D8B189F6DC27A754FCA70A751119574031B5113BD5FCB2D78" + + "F7DB43C82320B36F2E51FEB777DC241FFF2F018B2CB722E59E9B37E916740A811E83B05C4BEB099C" + + "0A10619029F9AC8CE549DF547C84C36DACB1A933BA2355651C1D6927E207104D6B7D7EBB4F35C44E" + + "17AF8FC9A13BFDA193A5B98D8D7AF08D6A20C9697CBBD5C7AA9A176DFE24668743F8A7082416DFA7" + + "A8C7A0EEFF3954A6F515554961B29DA471E3C52A00AFDB41467B19812ABFE47EF345DC4113A5EC47" + + "8EABC89AACCA74DF4187E2FE605BF001B92BFF9D23445494DE5A4CD2D4FE703FF82E43B9FD2202E3" + + "D74DD52C8AE0BD04957756DAB77B6859FFF97E41621238D67F7DC20C2A5ECA51F5BA970336C6B48F" + + "D69378CC691E8B0A232121DAEA6FDB312981412A91CE8775F9E85BE0207307B74A9C35C6985F6CA1" + + "D5A22535DFB65297C72D9AE62C9E26E22A0A3D41C7112E0CDC163117B2F8DA90EF62F94CD9C9D3C9" + + "0EDB9DC6C51A9C82F78164EA54CD3FED161E58AFAF10B4E5A4A0F77A56886A718B593AF6E1D0192F" + + "87E09F084080E880C6431B32E2FA19BEFFAB3143F10D1130A757168C68A35ADC152EC22C64F85E57" + + "B772F3C2ADC6E58CF0CE4130E12E8278FD31EBA67E3D7CE1BB7DCD9BDDD37CE048B2BA09E821FE65" + + "3621A458E2A3F0FC383B17708F975737EF5C4EC339162CF76DFEB1281CA7D09FF05E46B6600A3948" + + "CEC4B34593520CDE17CD4B75B6D7FF2F5223923BB58915CEEC07BB86BC36F7E3506E0895325E8759" + + "33221E0EF6F5C606D6B224119001409F3FB86C9D8C7252EE7B25437FB2051A7426AFEA59C71C892B" + + "435DE9CFE4FA0B0DAA20DADEBBB72901AC1ED3AA0AE16E85EF4D2AC54C4F26F420004D19C1AF657E" + + "A76DB75B164D24F79A265996081715E8684AC1ACA0A1673EB8D2FACFA9209D8B3A9E772F694CC087" + + "441DAC4DCC38752AFF19ECBF0A66130E13A1EB1CEEC4D401FE41D892F04AE45F8C8CCAEBAAE166A8" + + "2011C7E4EBD62DD919099746804977A1CC825582C75E6A403F1B0F8B00817E2E967BE4C597F3F274" + + "B1D97C496A471CF579E495EBBE3DCE82EDF9EA76B72F316A24527609AE5E25AA877D0AE2DC215212" + + "03004AC3CA0EDBAE3A34072A79604F0813B7B02FC57ED75FFEBFAAC13F6226CFB81B303F8446CBBC" + + "6D56BCF9A69D218C9A568ABF42AB0E5D8C25586FCFBD18CA514ACF9385BF5912F1708B8E97E97806" + + "245AC5FCFF2FF928E00C1217AEC463C3941B2348807D70A09291F318E0A22351AA156EF0C81A46F6" + + "F69E466A9B09AC36D3B2F1B47AA37BF36F35DF90EA48E201AE2709E56D9C42121D220635FBD08484" + + "99151F7ED5078F9B966FF4C4D10991E57D45DC1E54938E0374A7573BA3003A5C6527A93BDE97E820" + + "0CF781E94E00365BBC65C4A50B8F8E8355D9B6F9395B024F737827C174CFB7967F9FF30184A607B4" + + "4BE4AF82314BD872484628327539454C0017F2C17419721108593F7232332C2BF518BA2AB7F60CFC" + + "8351D081C9A627B29A543BD9C2A9EBC7A6B610B2E164DB9D6984B18803A63AA59CCA5230BCA23F6A" + + "806C779F510762E1D28E40F8595D43D1C120CD40D7DD11D5CDAFE22AAEA5594F91E921764D1B7F99" + + "EDCB0A35932016C463590DDCB8CC215CB5F0630226BA57537E1410D92072713DB1D171B978317590" + + "744565495DEDEBBEECBA855BC38B3B06D871CE5D49B4F6830A52E8FF427793D4A1D3A793E364420B", + muHex: + "1EA679BD0FBCB3887E5907313DA513AF9A50CF5C586DFAA984267B345460D4DB65C7FD1724328545" + + "247983224352434076F42D4746ADAD1BBD9EEF9501D70202", + signatureHex: + "5A2819AEFD47968B00BE54A3F5F1CCF5E2F995BEA0DADF25B5D8C3E8218F4F1A0183F0AF238750A2" + + "261C2423C88369E09CD0EF34DF7F108A3E437F4296B07F8F43B8F34ED67D0B121597C8BC99CA6B3A" + + "4F9C2FCE45687090D12AB2F7A2956027A2D2976391B34943BD5B30164A26F6372CDECEE7FDB0F167" + + "7A428BAC8CC898EB88300B277209F3BE9BC3503CE7A84BEC9EE006826AFD7B9A5BB35654719D50C5" + + "11BE6A62A9EEB7ADA7DD342422766BE614CD3897B050A70F93C6EFC62DB90C2276AE26F252E8A269" + + "B3F7EDD0B938229DF937FB7452CDD40E77EB22511C7F6318CC8A6CAC9108295938695417ADA63F8C" + + "2C1DB63A4AC16B8B8D518574B9A5C7292267D60FA1975388EF838B41286FD17572D0080122D47D7A" + + "92D85FB4E0C7C14491C1779E81050D4F8D4202CB4B35C7B6B701290C7589132D8B85151849380F5B" + + "195DBC6468F22213A6034B9E72CCC3D6DE7DDAA00DA719694D6975E9DBFA6A44F8DC67138ACA5F70" + + "A37738A551AAA00D413EA37F0CEA9EBE931D86E1DF316DDA9008C21FCFDC9031AF372F56651154B9" + + "AEE6979BBDB71CCCEF33E2492CC37F79B6F41688E752DB5C8C1E844FDA1336736314B5A832A54DA7" + + "968B7121451601A5568C1DB6CAE10F71BE9507EA0D5840E8D938309CA20785100244585A9CEC8036" + + "DE115F7BB5CDF3D898EA351379A5EDA06484C080924F1A45990D80ADCA50F8CF5F0C36479097075F" + + "8089E06842D86DF1C5632BE7629F61A3F261AF445D59E07CD1D2D1AC826234933C4A29662561D8E8" + + "EFC4C887BE9970AF8EF9705FD38B16DA47B9198AF1AA697C58DA79809A2153AA4C4C6A7E4E04D958" + + "20A662D430135FEB5E2EB96E11D1CEC5B3B67185FA9574D2C8D8CAA2EF907B3C062894C8BF19B251" + + "034520833D42A4D96DE7E540DDB19F01F984C742F4344D35E328E0D491063A48CCFF08B794458B7A" + + "1BB331E0024EB5A29DA8B6694A2937FC89767A12B4FBB852586E4CD75F3B3F2247C0C96F39924F4A" + + "D4A0141D58AC35FFA029781FC6B1277195350F9CC20BB02738ACD28CB44FD174C31F09CE7713C4AA" + + "1A0FA3CD0C78071768BDB7A0EE8A9D3DD9404C706B0AD902474A19B9A862F5C6C19F7CB101060AA1" + + "E9F65527D6ED044771D0D5A8FBF048CA9466BD574D52BB0C25C865EFA69E20BBF0C6C5B1FC7F4184" + + "B498B7DFBD02506356F01149F0CA18B19FE77D794F7C331798C808DCADE3ED9688D6DA904B72FBC0" + + "C9CBD6A8B67728B348C2D371485E310D99B6A1A64EB8DEDFDA4B0916F0D77BD4E10CE5AB6F02576C" + + "79FFB777FB91AF200465CC751A87244D65731E0AFDC5B3FCFA8608830A958151C02EC4A467713C0D" + + "E9C6FB7AD92E414D6E076224B963524ED77F8CC55243844A7F10986B3A6409E1897216F81D5D5F51" + + "6F0159E1253C7F7D25BEC6847A801A3CF337AC4BFC4DC87CA8F7FD2C5407B9980DEED3E25D31FD56" + + "CF373BC815430C9FAEA60885223D4E56B190263EAA4676009B6C92100E83C9C538B8BF158595A8C1" + + "71C2E4B2D0A16DB09E9D5E1DC2A5300C0AB74306CF107A8C71E4DF2467AD9CF6B81EE32BC152E182" + + "5871858EAD18B1D6206138358D5B7212DAB332401FB3A000DA18358D64D1E759E6770B1A83C174AA" + + "42A74F52B0A96BCD802FDE7348AA0DDF57AE83E46D5855032D527626EF2562515DE42E57B9F0200A" + + "3306118FE4D2CF93D0A8504F3D26D0FBEC6860DC16B993B4ACD26794AE027814CA8084A217D40EB2" + + "4631FB5221FDEFCAAEEC72EDB0C73E37B402D8F2C2F184DED69312AC41E45578B67DDEB32853599F" + + "9BE7069826CF77446AB0FD86218C4F23B774AF85390148D9213C64C4232AC67A57757E438ECC7572" + + "321A3F82F255D9EF3B60D0913BF45C7A5CBF054A9D02F65C32C5FBA29EA0D448F9D433BB78CACF53" + + "B94EBBA97F37DEC2F69793E408AC836A3AED474AD6B1F61AAAFBB94838BECFFD42E68B0B1F12796E" + + "B09F5FD33A44D8F665F5CBEAA8D81540715DA2CF15E709B01C07010FA84487800B911E3C0782C52F" + + "44C7D1F3933BC40D74E43F666183F09F4F850AA174FD8491A78ED2AE4F30947BF2866475DB5D2510" + + "C7B6A8FE7D72B3DE3B73EC6FF21C5ACF4F2AB75A8867ACD32B6CE08876F5168F959D55FDD816B114" + + "C41BBD3134E2AC6033E50EEF25BEDCCF1B5BE7C629B15BA4480E1B2498796C8DA144CA8FBC0871DB" + + "52C4AC9D742ACCE8B431D54AEBE6789FE58A0BE8BD2881AA43D4265DD30F999E854FF8F802D39F13" + + "081C15A9B32A0D9F701C8845A2DABF5B624B6EA5EAAF78E13EB0BECA139E3116AACF4892BAF1D851" + + "CDF92E5718E60AB0DCE2FFA649619A27F2340459F4E9C36703F16812060BB8A7DBA75E19412631E4" + + "1E3541204D4A0D9BB35F1496552F2A20AF87D13950BC561561F318BA425CDA2B2C601BD6B31AF7D6" + + "FED66152255FF07097029EB136ACB97278D74A7D7684DA85E778396953A138E2C650CE8A0792B336" + + "D0D30C5048F7AEEE2E9AC3149CDC4BE8F667D7658E645ABAEE8EF19D038B1CD835959B290EC0C6C2" + + "B79C21F467FF0BB21EB8CE58DD1255C04DED0CB578AD01C40A485A55CE36FEF890EFA4D9612A5A95" + + "093462C71C58FE114C776A67F49C4D914652767A9BACEC870FC2EF5FEA629B1857A4DAC403DA3F60" + + "EE63B6DA1972556966E5EB4EE43F790D61A5CBD8E429342430CF9A5A71E687B8629C51C5B1372A1C" + + "DC4DDC203ACA16617C4FEC98527A7DBA07B9C273F866CB272B77900D52B8431C72995CD2BFF2C239" + + "16741E4FB42E14EEEC389BF356367752F6CDB62A5252BB6254EF4179E1829080ABDB4F1476376AA1" + + "D41F3C09DA71B09D73E6D36726D50E95C8C9C730735EEF70B4F279C94B6133593ABFB5FC1EF37F73" + + "F3F5CE1C26A2BE43EE961763130ED80ACCD02B18550AD848D57772D93EDEFF4DDCFB03685A130EB9" + + "ECAF1533CFE162846B7E6222E4B364381EED1C5A56F00716DDCD830482C088C059E7E6981BB8F731" + + "EF3449AB11B8B0DF91ABBCCABECF94296414764ED476201021255D622E77C87067642C13F1CA0648" + + "3FA164CD8EFED93902F03E6F2320A936638B827AF3AABE85E03E167EE5776976D6506531B6A8E0F4" + + "B0C48BD5A71EE9612E1CF61BC0B9B4E618FF695E8219089AA587960783E3D27CC7AD2A7A6184C73D" + + "DE5A3E027CE3D9AFF4DA965A8EAD190723FE448C17A51149C5906E6975FE4872D347C4BC0F6DCDDC" + + "657E7ADBB4686FAF65F4B5E4669587D23A60AD8A9588C0F29DFECDE63B99B0BBAE2913E7CD51E767" + + "5C1AA9CD66D779DEDD02B1EF6CE4DAA2070D0E1A20232D2E3A4394C6C8FF132E367FA1A6ABAFB5B9" + + "DD01182247525E61697D95A4A6AAB2B6C1E1ECEEF904090F1B2143495455698D8F9195B3C5CFDAEA" + + "FB0000000000000000000000000000000E192D41"), + + new MLDsaNistTestCase( + nistTestCaseId: 93, + MLDsaAlgorithm.MLDsa44, + shouldPass: false, + publicKeyHex: + "2F89674EE5224792B540FF33A1082A4BB841BAC41E4C7AE386F4320460951CA585D221EB6E6ADB9D" + + "038AE9ED8695CDCFA0062CEC0FCD75BB5335ADBDCB96EFBDA01A69808F44BA7A46EBED20FB44A6FE" + + "C69B3D5AFB30BCEA707A47D70574B17AEA71089679886F9C8A0E133EE51B91C18AC7C4FF81B45B65" + + "06065B610B9602EC44812D2C620891957DD73FCFD17C6ED115213CE897BB6794FC96DFEBB21CCEE2" + + "9B733C408167EBD24AEEC17AA17162CE602F1EF10910616DBC3ADB73A364D723AB054CA3B155A875" + + "17072997118A5320716EA7F9F209D10B22DFAC6B0C0BA503CCAC9DFB195EB78BC1E2238DAA312A94" + + "BA3D7A62E7AB9596352E28ED1B766A5FB4883D60062810BB96EDD8443A5119743B64E15FF410B2DD" + + "3D1C196358A3382629BBFC2E54B30CC7243B7414C50B44A46D3ED66437585B873445EF157CA39AE1" + + "A2AFD901580537AE144B45333E02272B84A45171D8095DF49CFA473182DC6F3B1A5517FAC91FC054" + + "E710B49F99AA3EF3DA4D2B3D2D6DC754ABF1423ACB4CDA04A894A7ECFC12E605B58F6816873003E9" + + "8E85DBD775598D575E358424E64F3DD649C2E2282B151EA2490F62835DF2BA687E5427B71B40EAFE" + + "CF93808BFB964D9D4FFA40F0CBE9E883C80ACC6D35054A08A0DC82BED62BC5ADD4806CDB37B012DB" + + "BCD1E7697F5B53CAAFA2820D0508C56BF350E9B484987798F8BD271B08F1F9008FE78AE7E039004B" + + "25A87483D52B4A9E3534B7720FCF34E54CE2A742D0238EB28F4651F1C0C414E2F2639191FF68B48D" + + "6F1BBB5D8759EDBDA822A96FD8DE86160EBBB8F0378DBCEB12CBF133BD7B494F5D911C07ADA204FC" + + "B2EF4ADD22653896FA123C6CAEBD32E270F098782DAD0A388ED66B3E0C3F57F151B499A782F6977F" + + "B7E2F1CB53C37E1FB3F2CE7112980E11CD668EC26E1F1B79EB3EA0C1398BBDF5BCB2CD383E789899" + + "9618C408E8388EEB01A17A5AA9FC7CEF64C3C540E27D0210AC16966F61E6AC90CE67069368975BFB" + + "FDF302E87917C29CEFD2D5A92DC898F2469695153A374E2DBDB668362EF78294CED70E3BFE1C446D" + + "881226F7E2BDF866AA304C39900B1C0171EFE76E2F9461C8955BAB2B186A858A9F1555DD5B3D2861" + + "F3C1E9150E9A1B75B35FFE89EE5972F6F6EB4091CD03428EDC6EE479090D89756791D357E0DE46DA" + + "197E398E3C24B66D4DEA26122C1E8C4A675CEF3ECE5536E29B17B1CF7D4526257BB83586D2EED8FB" + + "CBEB7FA112F34B0F260AED41D5488EBF2265801DB2DB3179B26A57A662F6B15E7FD2E789348F18C3" + + "3E4B097245053F5999ECDE82BF0C0012A2EBCE5A03983DCADB103A379AD4CC435C9FBF7F3FC87AA4" + + "69ECBF71376A2A17CEB90CEDB8344BFB1B0C406915E2E3CE6DBFFF5B63FE5F7635589442B7127BF3" + + "689948B7DFE5E0ED0FA643C688592DFB63254E41FC292FAF771BA35858D932D59C60FCF05A3B5E90" + + "4F493B1803554090648A3DD3EAE8C9D4BE4D66AD991950220CEA0B422C67C3905B7FEADDE1ED9E2E" + + "1F3AF4F8396F43B871C24D6B0B4939B22B1F69CB1376F70934DD7D47D3F3ABE676A52BFB7C20FF78" + + "074296CE0CCAB0A12AF7860145E119A1236211BDBE287A140815BE737A4AE39FA5CA587CC9A21987" + + "3ECD3B8D15A980242903BF510C2B7174F2633821D1940E0EF529B518DA8F2E364A68012C3FFB8963" + + "5DE5E665CFBE8ED6F84AEF8A54BF362CD8DDE4FBC99A6A319280EC6ACA30E791B319F4E747A22D3E" + + "2AA41F9F488C818AD12B8EB77A643312101842C81BA0B20E23D815BA27743746EEF70A897DC75B76" + + "9DD063D13E10D74CE966F8372AEA2EDC87BC0887A7C6FA87B5B061EB94150845", + privateKeyHex: + "2F89674EE5224792B540FF33A1082A4BB841BAC41E4C7AE386F4320460951CA563AC7C32D9FAC7D6" + + "7D256D961F5776E61FE30A3830579CEBE1FE2DA65251B99AEA8BD52CA437427542286EC4308B288A" + + "9FBFAF4748C0C629C7D682887D49E7964CDA142059344B9CF5B5D238E9EB3D5B6A78A2AA2211F29D" + + "33F60C40B90B8DF91889001C0651C9120E03B6105CB2858A26721433210BB0481B417214A40590B8" + + "11C24611E0B04C580408C1060C60428C8A96450CC120A12644622892A1268E9A241040C28112C049" + + "D3B840CC084E44000A8808891C91898190310A144DC81091A3B2658332656120510A180510208520" + + "A14CC98831A18851C1A471E1B2419C248C988210123746518024E314094016821C294C52286CDCA2" + + "2CCCB849529044D9A28C09364222390E02B19110B7859A44518C2009C1307150862859A2700C2966" + + "82824C4A80884A182CD2146E24142DDAA25021370A03368A4044891807205B9468A0C28C4A08849C" + + "0232A39281D3A485C4B68108116918094109452A12A585D2362623988D02B848898640C3908DA2A6" + + "0D0B21494A346D088025A23212CA3466CBC28C9B082A031085C48205022689C3A608C23004223464" + + "520890E042819236241A800C188385C9401183406184860D088605240511231300C8120E02222502" + + "3166D8B60DD0208D5C4066CA322D9B46241225110BC7251091815B080A1A190DE10630A3466EC1A2" + + "5002422A03160E01A5891C97498A186D001961092660E03446E31440081052CB262A2319220B8424" + + "DA9861E0A88509120ED1484A52348ACB488810C9480A35856336884C382C13316E220360D096290A" + + "262288C42D0B052D20882D94062E18157180827154A0491A264652847118B020C8142E8426615088" + + "89D8C64D09C0050A0622A01686D39201D4824863040983C048A2B860C8084603A6511A4692992872" + + "1088314A180110C450CAB440938640C4128D1089609482090000091B2062C182308A80480405625A" + + "86105184480A891120033092C6854A124814C428C042409CB830C98208038904C1467288348D2097" + + "0C11C1109A920DC1386803B64849140A2223859CB290C39261C9026A8C086623418002064D141289" + + "813604A24281DAB86D89C8694122411A368E5348825B264ED9B4912483415840260C196A01C73041" + + "406984B82803126222A98C1A112A9A465254484DC2864513050A1B87715C922102A611D4408ED140" + + "614322482140640382680B21010346058D53CDFA426210FF8E620036AD3F117A19BCCC5EF7ACA039" + + "9491F778A76DCF71DEF0BE17B0D128A0B4AC2F917E762C931C45C5C3B903BE1567EB87674DD3376A" + + "E9091A73B685F162C03A2F29A74A96204F75591A089EE27AC06EDF712DAB61765B58DBFB2FDA18F1" + + "E1A2A853CC13765372071241409F6582D26EC7CD629294DFA6372C7E88F11D885800B3AE85428C1C" + + "3CB34E27180CE804A065D9B5EA16E1812E4375724AD1F2749A088659DF82E4E7764D3602392DE522" + + "28F603C811E31D9C8F691115CD18786BD90FE4D16F5898D3A52D4E73605C885BF79B0A77A27BC559" + + "6687DBE772E8A15B31039203218B42DB14449D51D83208C39F75BD44FD93A0301BCF21CC4FC39233" + + "F697BE31CFCA6234F90EAE5CD674F3C3FC20C2BC0924E7DC8DE444B796357B8063A52142B606B991" + + "74D9F7B024B7C7298327C164323316AB49CAF142940893B379D2FC3A699ACB8B20CA3259D948111F" + + "D2AF12D9A75BE7AB598EDE9EAD1FB7D3BD41C27B3E7D8E6576525FBCC31CC69CBD3AF24A2962D74F" + + "A482DB22EA26B6F6EE5A22ED6C6B6725D73BFE1532C104FA4A612AEF2BE5475CB894DDF146C5C12F" + + "C962C17166E697AE20D7DF28B6B0ED7442B18E2E06FE204576EA65C2541120685098E6F231DFCD2B" + + "8092FFE556D9B36F88EF3AE5371038E810B8BB430620DB5690B4DDDEAB8AE9DA520D9F1EEC54E78F" + + "835003060884BD89720A994DDC42D3AF03D5DECA6B54B1CFD24B9456B30DE53F5522640C39C41877" + + "1B5C506338214622CE920A92D269EC24E45C6B78E98ADD1963CEE08FBACAB91CCC6CAECAB7536AAE" + + "77F923CA2ED0569610455C5ECF5F926F81AB108758B431FD3EA195FE2788573069842D4129D582AF" + + "E689B44576237E98577C9ECCEE8B18A0B0DB6E9A33844E47EC6AF93D1354FD346EAA332F517AD6D5" + + "3CA47929C56C0D64D88E550D781E4C01EB2BB344C99064A034F59EB718FE34601908DB92003AFBF5" + + "929F63848B7993D015EAC01D8C7B8DBC9A984E853E598F801E5EAE1C85E5469119EAE2BFE52C07A6" + + "48F231CDCA2D5827A8B259358BB0B85174D16D09BEBA913160219C93F08853135D2C5D7CBAC39240" + + "6D8072C75FF1105817816665FE0B72397DA8597894146CD1595359AE00AECBC37AAE94231AD040AA" + + "F46D71B828FB0023EE228FF215E5AAA123F6511EB31746C0FB1F3C8C4870B303159CEF2A35B29962" + + "80E76D8DC45CF19865328F4E3E1FD17DD7876F329ADB64BB84DA3530C4CA0CC3D3DC70CDA35402D0" + + "C8974F49AA75D92D49875FAE5150B290AEF33B0A3ADA515B8CD5615C8E455F248B4E83442306BEF4" + + "F51441A18BD56964A0B7985B25485793A4B725DDDA26D77444199D9B8024723458F4838A2753E4FA" + + "C56B3FB3A3A27A44D6F79A2DDA4884BC819EEB1C5E4B7B77652126ACB204A1A8DDE6A4378DDADB94" + + "2F74360508A5D979CAC84A489D0ADFFDE12AFF431B873A591F7BFB86E2331D85ABCCC012F45FC401" + + "6112C167D43DD4C58AF71D6214ADC7BB529D04A7E31429CEFE87E4378ACAF8D228FF0CD0511E7A59" + + "AA9651986B12C0A2620ED6130809E5A0AE035A543B40B352F12C1EA6257D13AE4EB4DAEC9F9EABD4" + + "C6CC85E8DD837C090905374B082D5393F27C649A59ACDD795B8A0F24253F4AB6E56C6220BEE4FC19" + + "F9AFBC845D1EB3EA3B306B900B28200DC1391CBFCF3A6F07363B7E1033DCB17B16B809F6DB86FAF9" + + "34784BF546B57B29FDFED3319A9C48CC3DA1DD6D375313EDC6C160C954B2DB716C61F10746A5799A" + + "85BFB2BEFEE531E789D86F8DA8D34DDC692034A24DC188D564EAB5847D189385BB1FCE9C5F2A12DB" + + "BD97CA9FE2961827985753C66F3EAEDE50781DE7D4506D08088B02F1E4E15F2C0946D32C8C183207" + + "A5F352210D8EDC1677F971BE5FCBB89114BCD331D755283992A207B8E642636D615338FF6822F79A" + + "35058CBC10BFE0014A60F0899CFF78A926A6A115D36EB3FDD0253245959C1E7F193D936CA9BAC332" + + "F618C6D9A5659C6CA73A60E6A7FE638F494AAC3A3BF1AFE19B4C4B3DB29EE388FB211571297164FE" + + "17697CA20CC175A3222BD93E932BC497F4433F0978E8192152C1C7CE2E7685BD2B370CE8CF4DD039" + + "AB9D949FEC45B32803ED266F9B9ECFEA48163E08E95D8DDE7938BF2FDDC36E1D9D3E90AAE8FFE9F2" + + "F54EEBA4F1E220F09A11E0CB1950AA4E4EFD54B517F2ECDA0AB289269D0E93540D50F01D327B8265" + + "E75D4A712FEE41DEE2F2919F03B4BFAFDF62C5377CB4695D2F4378D77C2981978FE4D6F9E169E995" + + "3D47C009BDE7442D3A15273BE96E95AEE472CE37F375A71744E11EA8C915B3BB16B04FBAB7FC6D93", + muHex: + "596B354F6F935D7B4DE7A5DFE94C2A6E5F803C393C8508F992A45D808BD1C4E8CC478A6F66B3A20F" + + "91D467D3EC869B867951FEDAE981ACE4DA9C0211A2EF4FB4", + signatureHex: + "27A255B0526E875B0F77C3C3EBC0965DF9AAD96360CCF856BB71B3AD00C6519740C5969FDFD1FA79" + + "3CAACC2409B3E815A1D1B732FF07F316B1F5433AE26996829C2B6C83FFE31C6E9D1DD37B771E03A6" + + "15B5C72CC85215D8CE5A11B1DDC02FA66854F2C792A469D708FA5CB285AB682544F2C33329C2E96E" + + "7152D30D74BA5E909647ED11ACCB1847AFD4DA799459A0C85D865D294267A558A2E064323CE196BA" + + "D041E829CE7615F65461594636BD69CEC22869E35A5F129869D6046351402EB0D6486AF973785AC9" + + "61D41D6C3EF5C9904B057F0B16D769AD73C9EE376D9ACB7B29B898E7421F568C6D6B7734915D83A3" + + "F37089CDCA2889A3DF0F830D434EC11710BC3F9D4E54053F5D2B3BD056B1BDABCFB3558ABC728599" + + "589F4866CC132D2F1DE46E00623693BD8ACBA3C35DF0BDEC5EFD7FF4CBD8593AC730654EFD4929BB" + + "7987D65A41D98D386F61F13C84F4987B5F77BF9499F8BD44117AE067A40AFC4DE75A63D423D45A03" + + "9E5693E96D2451EDD6EBA1D030813BC65F7065347D1A402461A658CE1A288DFC0D878EA9818CEC17" + + "5DE9040E8031E1FDC2551839EA61190DB0D165BCB1D9F7CB6D409C17AF2A34D5C5C6B0F98CECD920" + + "F4089C1C14386F8C85CE39D2B3496A49AC40825BA1626485E7E749979D83E200DC11B619EF3FCB40" + + "8CCDA3E20D830F9CFDA5EB8F0034CC7A0543ABF6959FB89692A7AA95A991E6219030A5A1F0B7B78D" + + "28C68CDFABB0A84E4F17CBAA906FDAB164D7D203359D1876A676EC353FBF2620E490983B954D7236" + + "E319EB74BD75AB5A55D5291C06DF64FDFA97CBE2E09C6148700AEE970D14A0FB2D35A72688FE33F2" + + "E6A4BF30E01A9BF3ACAE4242F2D649A9E396720ACB413E732DF31B5DD118327E8FFD0EF56B0359A9" + + "080BDA29A0ECC9A905F0D3C6FA0DBE41F4DC7E7233AFEFD32E88640DE00CB825CB50F0D4240F4A6D" + + "4A8353E376A485301513414632A520CA93B1E6A6E112551BEC1E6A67EEACF7E7BB7E7A7AAC4B8980" + + "84899E04980138DC16D927BCC9E033F8D8A6A6E7FB7D418E6913006EAD26E64DB9725CAAC98D2F75" + + "1EDFB031DAAEE199291580846FB586483977139CC76818D2A5385CA5F2184CACFADE504F17157D71" + + "9EFC63C80A132057895CFAC3C72A91FDDBBDE5F16907AA20C0F512BC8878452472F9941C9ECA3D69" + + "E6A1C5D7EAEFE45ED43FD3C36D91411D051D921A2B598A3C1779E5B3E7C213CAD83ECD5F5C1E1DB2" + + "2178681398C38E0E9441B1A4A27EE59A873F1F24C45C2312747B38D0C9FBEBA3B92E4BDDBF4F8443" + + "EC389147E8EAE29CD9DB0BCE13CD3580A76B154A94C1760CAE252F2783C672436AB54CA650B837BB" + + "46FF45952F0A3CFEA29E47E2A24647AAB084B94A94373FDF9BB3DB0517F390370569AE3148293D9A" + + "2EC55429D9651D2C02AAC350D163BDC986D14128E906A906862076B5828DBEAF616D998EFED59BE4" + + "CDF2B17A73435906B479C7431C3E39934EF0CC209BC964732F24DC9BB918673CF51B44CED5554E14" + + "B8D031C2A37DEC64C676E0F2E575CF9695EF89BAACBE3D518F2C18164BBB88BFA60B16EB6E7B9AEF" + + "F1B95545D154C62367876714F673C30EEFA083B7C50C015B33E5567617300241C54D0853ACF2F62F" + + "C4230246CD3670BBBAD08F1860C6570A381FE7FDE5A6CFF736CA62BA1B3A5A44E901A5E58D96DF66" + + "FDA615A4D3DB4C8468168A13C37CD672832CAAA647A0E988F15070B1FAE021037A24B10D7E800F7A" + + "71539FC029657225FE4A5A2CBD91AC84606768D28630A5DCAEB1D0B8DD6BF2903343E2841DE405DC" + + "09C18359C88961AFE3170CCD097BE88EBDCC55E19B4358BF8EA346795E6D8CEAD9327C30614801A5" + + "A90884E59867228433D65D92A6C742366D15F31527473DF2BD79EA4CEE3380DE49F141E76011A458" + + "1CA7F700879EECB7E852DED47BF9E67F7D83CBCC0910864A7861C7771819F1962195D9EA51C3EAAB" + + "CF5E0621E426E6E530EA071073E187BA023E648932E86489C3D6C52B54DD9993455D653A755B7D20" + + "D008D226E3BBD09D03EF5494B032CDBF780DB04B9456A0B585A72BE0B50E86BE721F8F9F5919313A" + + "1CBB55AB64FED4ADA5A7A83C442479A0884A4A3ACF12C75E7157773821F28A37E829AE1A26F9ECD9" + + "7A07187DAB08CECEB3454A37FA165A785669D8E48FF17E99EAD2CCA944EC99934D7E4CC0D446BAD3" + + "7B14C286DD66CEDE8766B28D031080CA1502EBEDA0E92382A4C2752F91789A44B5F31E1B298028F8" + + "2445E98B44973773867674350E6D16CB4C979760F5EEFEB17C358B37E7F05831FC882927AA377771" + + "27B7F22FACE7277AD823CB0AB7AE6387110AE6F35B9BE4468D98CEC1DDBC79C876989C8D5798886C" + + "6F84B6BCE2558647B0A54DA0878719546AA48B8B6820055627479ED380C8797008C6F1939BC60151" + + "9246439F82763A35675B15F4BDDA4A3EE792185CD8B9D3E632C5EDCA0D3924A98E3DF7D84BB9C45F" + + "69A25E86AEE742BDAD2A568F86FA0CD149A911B36A7516CCA23832A4384FEB87FB1A9A26A54459E6" + + "21DA8E91737F21C3BB9BE437622E86BCBA73D5B00C1B9C325025B29900CDDDD7B0469F21747765C7" + + "52B91A804B556908DBE509FB95C8E5FA43E1B3A5CA75FC0BF7A82E1AD6335ADE8595C7B3F766256C" + + "369AE191C7F8EC5455A8F0C3666E606DBBB2D9C9441637DFAFDFFE0919495C2F208207B7D8253D1E" + + "C1EF0A228651D1862F91E0CA155B0D2CE8853E8096B180CD3DFA9841194F569EAD76AE95CC4BB818" + + "CC49EF87E4FCB4D8EB13F2202B952FD52EF21ADCBA71AAF921A67625CB62EB1143F43278F46B1BF2" + + "F07A2374F1CE75D427974404882A18733031C84C91C46F648ABDCE190F0C9B8E50DD76B32D9AE835" + + "29C9B52742EB64D0DBF40680097755DB0690D83068FD6AC67181288FDC9195CB54FF8648EA717ECF" + + "8A13677E8295A115A781D2F9B054A30B9881C7A10588B28295BA64A13FA7B191D89797CF695EF82C" + + "8ECE69FE25C4277005D9F1FC0F4F64148092145B478B3CBD03C27C6C776E5EE6B9737FCC75AD446E" + + "F174EAF615D723CC4E43B3B235D540DEE0161687FBF694CCD490F4572E3A0222CDCD08541091B56A" + + "7A5E5766091F466B38DA5919B2D091EAF38D532130D0BC589C9C26B45801E139D788C15E00B4B790" + + "D33468AA3CCF4B13E209FF78317842B4F610DE7C0BA74A5FC9325C4C4196C08195B63E5A40B3E4FD" + + "9C7CCBD5DFB993675DC677C0DE72E0866255E81E7E1D5907CFE98B58A11A8F22F0902213BC116DE3" + + "F8C03F8C448EC21E1C7DE127BD4CF3F70409111823263043787CB2BCDE171A21252F66676872909F" + + "B0FF07172E3F426BB9C9FD06072341596B99C9CBE4EAED0000000000000000000000000000000000" + + "000000000000000000000000000000000D1A232E"), + + new MLDsaNistTestCase( + nistTestCaseId: 121, + MLDsaAlgorithm.MLDsa65, + shouldPass: false, + publicKeyHex: + "442441A95BD60FC9BD95EA1E9DC4CFF8FBF5721FF0BC498A391EFE7518E692882C7EB37D913DF168" + + "1FF4BCDF8CF90374CDD1550E985DCAFE2341B6B590A093ECA2ACD2A43E1CC0608A77E19B5EABC780" + + "5B6BDA510755C3DA0EE96D22BBA9C3D82D54B7CDC47E41D22202B062F264530B2DE69C7992D47758" + + "31EF7B4B5EA5E0082103665AC128C8F315E226785E6E8A9D8D012FDD32BA3272731E5070FE819D19" + + "91F8176CE85F4EBE329E7F5AC871E345B5BACDE26D2D2FCCE1AE029F3639EA0D4D20EF7A46D01262" + + "89174AACF2E673AE73F6FEDD69E60A0EED90CB178A548323CED716E3333DFC0B0EE54F3E8A24C403" + + "51F87AE65F2554069A8E24118B05586A523E1F41E626A31A08BB14C096371D6175E1F329620716ED" + + "67780A8000B8BE4A4654A02F5EBE2DACA4B7DC7ADE3363321260176C65BE1482724DE4FB99DF99E5" + + "1441B4C2836ACE8E5F702F505C7A4BE4456D1E698AF3AE8DCA9F909D6FC4587DE615688F0778F1C4" + + "EE5ABACBFCEC3ED2BEEC349D1692C3FE93F391A30FBCE281A404DD6B36B5AC4A4FEB59913C282A26" + + "EC3BD00D2C0E38048BB0E27C54194767D65BCA2A2B908EDA63048D8856BC0B4C539ACA7F2708542E" + + "EEE8415D6CFC52C85E160F43A34BBB896A8E79CE438E95C5ACE6ACDCFCBB01611578086641725E92" + + "E4C3FFBED1F94A5540B9F2957CDF83F21177DCDC0BD2AC294E2F254C1906BE55F4C89F3C928AB0A6" + + "EC1B349A64B5632DC06815971A923EBEB7B4FC62571B65D7FD0416C99D9AE59871DC9A706BC8F050" + + "7890223BFBBB99B4EBB4E449079AB36BEEF0F8AFAF9F84439C9C1B1FE434E1768573ADB3AB07319A" + + "5C8FFF884F08A27DA24CE98D2A214F842DED94D3B5505E2B3584682150DB2485FAA4075B78E98709" + + "062EA82E550FAD99B03F4F863040F039A0DBB6957CBD48DCB9E0C5AFAFBE6218956FA4441154477A" + + "6399034D169C2438AD5B4C1432462672EB6270E7E2CD192F51D9BB9CA7B8820EC1647BC4D0E0587B" + + "E01B828FE210CCE3232AC4C0BF176078B31E64418FF46CD573CA48E365B24DBC48436001A23978AA" + + "C64C0E20D4754E2F1ABDEAC3562E656AAB5E5560046B1CCD98F8697E58A3C7CDD39DFC3B6271CF6B" + + "CED12F91443C09FC6D0E1F96DC2124E63AF5DEFE5010B74BD891487E9A4CE9B10FA0FADFCC714CCB" + + "460C31224584C96DF3A0A381A165E0B6C0AFAE687767D897794BE654E6BB4BD8B4D33085FAC6D37F" + + "B2FE92447FC786F4AA1FB070BCBEEC60AD55BCBB36E610D5FF7CC6991AE79CC67206507124E1219B" + + "213DC16B5ADC396B8166B5FF3BAA12C30323B0AF7F48CFB5D8C7795188008B86AB2C4A06DDFAF2E1" + + "65232AAC8B5C55522CB4384715CBD736AD55DD553D46A92A2848E3AE2D9DE1D4AF88B66A1FECA059" + + "2AB9714A0719FB8E5A04CE43D0F73EF1B370B395B713B0F0155A48360D6B53F49CAECC1A16956679" + + "89B826269A4E1B6A8CBA9DE35B2CB9C1F2B74248C5DB6A0D33E652EBE1B60445304730CB607B2CBF" + + "DA23E0200891E45E4C9DD82EF7FEB836ED23BC92A25A6647EFFFC3DE95344288E09C7B05ED05E931" + + "79BED827437CF3F0D2237A4A101A5B5D3B4ED183874CD99782CE156A9DE5798AB523119235EAA8CE" + + "30E3368E61248B5552E8276DB037102496D8133B48ED664ABF1FDA7E30BD4747EE7FA43D5216B913" + + "B5FB94DD249C9D6AA954B38C9AE0DCD685474A6F292B60D9B689D51300955321C2B3EBBE1261FD08" + + "9FCEB1809CF7FA69DBC0CDEA865692B3FB6EA82268CCD6D5B712FE89DD15A8DBBECE81748F78ECC6" + + "A07F096C46829DB775A9DE8E24056031D595928B4EC803466BA074706E8B82E08E697F61FAA933B3" + + "272EE6BCAF84EFC31EAED3B7033CFD6EEBD4242C3AEBD63CA4B5F908D93250C0B9575B8E1C308BB2" + + "63FBA446E98B2A89EDD9E61DA02FCC3C70B1D291F19B427DEE7C0602DDFB717493F83EB33DF44814" + + "6113FFC549CEED1A3CCDE84277C8CADC738D1ED3C0E81C683552FEBCF873C2210DD9956451980DAF" + + "A78BE2B81BE38CD07FF7CF0896F7EAF376920550E0EF684DD6A9665D28861CC0192BB2CB52DE41E6" + + "DAFAACA5570D2F46C23CD73F3018044DF471F5B6462287318697272A8F39CBF173BBC76D887C3BDA" + + "C4E9092374A598025F634EE1B1DFB5F8C5389495E53910D6B78E9646F00999353752D08AA7846999" + + "99A4E40AD7B826D31985B95CEDADB3A66E20AA50584EE8E38E87309FA9C11EA17A58EC227A12B131" + + "204277E7DDC4ABC323D70BEFCC7937DD425339B0C22A3880EC7572610AA21A8765F4EF0C264BAA53" + + "7E473ECD49E3846A5FC375C196DA3247E099F803C45745DD4E32E400FFD0D41ED3DE534D37994FA6" + + "49B4505B610C374B8930939F23B83BDCAF93EA09B288D41389032655830D99F9107CBB47636C7CA6" + + "950C9509908AB66193A329262A5DA8D305F23C7B3E1E174E57A09AA859C7483ABB04041F5853560F" + + "A2BFF1CE4EE65C4D99F7FE13D826C063EB13A9172AE8706E34A9922C8403F98C551B813B2D8474E8" + + "F5D72A4201FBD027EF01C18AE8A5C9AC55454EAD21B26D17F7188A48A3A2776A09BCF18376F5B92A" + + "BEEB356F87DCB83304AE21B4F1FA66F54BD3421A0F490C0576475465052BA52D1CBDDFC5B04F2E4F" + + "8E33FB8D0F2ABFC5BDF64060AB084488B1FF8AC37731103D80924037BDC1A0E2970DB7944B9A295D" + + "57ED0BC3B0CE44FF5568514E0CC1DEF94947148136216761D48CEA9496E00569", + privateKeyHex: + "442441A95BD60FC9BD95EA1E9DC4CFF8FBF5721FF0BC498A391EFE7518E69288C9D4A70E5B145D59" + + "EE9DC162013F317D53F47A1A1378B1F9F23EF7B14F9AC6634349D4A89DD4A75204421D79A292E211" + + "3CCAF5A2E0CF5DB7DF9752CA5619E554C83CF9DF310113048EB4D8BA87819EECABA8669227AE956A" + + "FD5EFF224EA85A633376255883662483144344773723656101517638278383277504515361725184" + + "45255638886652631715337846074817675056833654088173367813507884082266433721211435" + + "72400111280051060107285480703718634186503563342838353105312212345311484532180848" + + "28342227322558683173813323378126015136367327506023573016472847536747638230473382" + + "25008267302664563025720781412565814231315866880706648882131043546823061384871480" + + "51770302622665632385075448167773672143178470106004048608453617554114018557253726" + + "74837280820534863047856861404640172127414514876200425150438504080575216077675047" + + "65130068047280422772547118515853744631062377032048011128317774250533163137500101" + + "71037468176500013016536402073441014328354477881188013775548335631221644238365122" + + "36313860235173813356016850163873511636125853743377578758440020656034513422261031" + + "34860321712772336202263656606317715154456741417288025667628826258500625811465486" + + "20728883501632623277158037717757373410413142172106522800335584020174646301624465" + + "31345641026768783745150817883552408368248368387224747830748651645167641106627440" + + "61788251340458043512130355743450274237021514748063855861328646706736831771771710" + + "56235732377367467538325301612334024615242541361287860057057283071370108247840112" + + "56213540512757205706678276631187764463056182088740700873170753007852862151625370" + + "77074588651476143545531200680361577800361150177343748763481365734153642370081788" + + "47287623766121304256337416725145041253021856814808267652843403218046883760152384" + + "06326526115318468787472674678111082863636384821355550477164855042487426231583775" + + "86168732704425782434666176602534848365210224761135356306526105806812452057411158" + + "73164337661641138607436672782641755621341638562443765636420225521867060121253545" + + "03202322262714518255234118773307474848138084730868121454416747488306373467810341" + + "66370471346002331760187153528585382018676810720877806367786035857556461518173007" + + "86721230102761823466816488441588612867570856652805504170212022463030142878674483" + + "23123766276585325500831268283645776546147374174852007472776725433417670442576688" + + "77717676777074204670535853461074688028601338471771072861627770020652462820770385" + + "52813623017546351418050461345017838413632865747612276432265843023656653547761671" + + "30217278164185665562448566556783652140107772002088264676613338634887405180785351" + + "53337554543407026044381434280452705747784313880804166428721110628136634457822141" + + "70818725088545817743685181756730833876217241414625304607565433617236061215546250" + + "57355832741813475615740165074461662552171462400756785116262607507556385720440618" + + "33465416362405446801277610467345448877420811331147673857023730565066877626478516" + + "43026137447465132237613077333838180211265051506600181621333687422533880322670348" + + "06281370704866764208833510477155611488104454381875626163178457025452001120560602" + + "30362717071473510182737684501347526800130264783880312345083053630081402107225288" + + "75816802452356681468173303040087819ABA98F8BE3827E82D1964AB6ACFD910550A9768A1F256" + + "EC42C473AA5F6CBA401A59267B141A53ACF80CB6B5EC09AC479DCDB65E51E873E05A560D8BAFA062" + + "0FBB33F49B4F3D99909592A3DA27BC38B292DE916DB595258874A9BD598F75767131E1180A5C052F" + + "A27E916F961B10B9DDC5349A55CBC23C40A0142D108B62E9A623A06176C4EAC92B28ECB28E0246DE" + + "BC8DB540B1AF148133B790411914153F16F48C14D27E46AEF64F688305AC690898E3C30ACBE6B777" + + "45B43252BE2193E782BA1D4FBBCF27DA721C7D49DECFE394F3096005AD9B18429B164ED7EE79A45F" + + "5D40BED90EEBBCCE5C75FDC5149E7041943CA446ED424FB6CE5002280A81A5A6BC42C4A615A5D63C" + + "3F88713BC6AE2542D444E72925AE9AEB9F06F44098074B108073D269BDA92C9B4F0C663BE806F1EF" + + "3D13255EBBB6CE32477CBCA80CC76B88EAF8EB419767CC64CCA47B35DE29BE184FC9DF59A1364E6F" + + "F499769A9FC315D9091E166AC7E2DEF3AEB40AA1ABDAD4C749D396C948D3F25A0539FC65B8A4B1E3" + + "BBE9CDD4A7E072DA9349C6836E901354BAD26CAA3EFFABEC1C4FA0D9B5FD6A6F80F52D7F0C679B6A" + + "7A5B79C6AD2CBB0EDC8CD7CAD840A7D31FE9AA4068BE88B40A93A4D466E68CED8E766D800068EC29" + + "C9B807EFF9B111176C896F8B2C44BB82163C1BD54FDAD0720F88A16037E921FBB76AA4EE97172430" + + "E8C2F2878415BB0B24BD4C88525008AF8ACF46DF4DAC0911E509B43D476A608AC2BAB21296A022F4" + + "64914C0496AF491D8D4B22A1423FEB8C887FFDBD81E5A7481F6A61639E748078724A463332CA26E5" + + "5EEAB7C7E61F87868045D72243187F4845CEFBD2D24CE8EB3B545BC90B29C2BF567CB652B80A0321" + + "D1626C50B60CA1135E15F66D8C682056FA6368710705ED17F82FB30FAD2B26F21FBE2C89E34BD5BD" + + "2A1FB8AAA205A8B1D646AFE4521A9355A831BF874F273E5ACD59515D5D85707CCC1D01C3A05D0656" + + "F172EDEB33C742DBA4C51A8490A26911EE85788D7F0879BE49986EC7FAEB07C8F6665F70DD1330F0" + + "B26F2E25D63DB8538B95E3148462C170F50396D8BC0F8F5EDAF1E9C03DD111A9D542C7D38B1E7DB8" + + "ED47331110FAB2FA23E79FB95499D6870F928D059DD07144867EF80EAE3FB15AB7E1C096EF98F90C" + + "5F57BFE846F1C4C65DBD040C7E15D1C6CC2DF3DC7605C685B1B5058EE20D0E8D47BF468CF2144EF0" + + "741A541C45EA6493D1AB0DE148658378893D34352F91277A389A9E7EAE05EAAEBC1571EF03BEAD22" + + "1001C974DCB07E06192452176976DFA1F5944FC437A8D11D1E9B7CB50DEB2D966EA4F38F17539A43" + + "28F40DCA688BD93975FBE076CE7A14DA9E61A2C4348B9D8AE80A638B4082E4047F019A5615D5A7B2" + + "1B132CA62D9289A81A05A21FA392C7D9400EDD57A50098E0F9634E5529260CCAFFBC290B571BC2BE" + + "E586588E3DA0A1A702427690A1C4994642AD1A92CC9CC2DBC86A99917FDD2897325B534707BCA57A" + + "BEB7349FDE3088D0E248054E7031E4BCB51424497282B0012A5DE1E93B6E6B6B20055A4283054ABE" + + "C166EF914539D63C43A58FA333994CE3E09CC69731F9A941776B7F4BB235B53299406715B9B15440" + + "37F2ECD6089FD4ECBF397292257E04386712D9CCF5B57D7E99CC44785D7C380631422FBD953C1A48" + + "C0BE67F889DABCB283225E6A75EC5EC10DF5411F2D7A3350B331C26A2796F26E1F19CDA75A2F3066" + + "DDD66F46A15B22B19A79B8099F6A31DEB3F3B524F42F2B8F52FF2C673DF92C55D1BC88E8B0750D57" + + "F4B4239C84D0411285B3E8F3ECC836089AF03D11A6483094B7D6A5568A412B87564048533159BB23" + + "E421AF5A870DAA5E756E22D751487DC41A58ABAAFF4844B015A44C192CBF5C7B2D9CABDF13360F1B" + + "CA9DFE2642FC9A8A98D756A8EED87DC97AEBB2C779CBF6AE0F0A4733E90A68C123CACFA2C8BEC89C" + + "DC643FD10F4E387EA477392EF621F2FD862A8100E15046CC6B6BD171F6FDDF5AAA4445E2DF9095D0" + + "732DC5D0EAC54EA2C214D9107F22A9697F3A0CB9BA3B9CB28BB5E4FCF7A5D2ECE8BF4D79C4762B63" + + "C9902C6F3821DC600E5C98A96D999D7E48E9249F30E649D877F93DA1EE14F481B10245A61DA0D998" + + "FB71D17B3C3EB5C367951760C8B3A6BF5E74355D7DEEC7400D9090E7E9F91949825BC0F0842437D4" + + "1451F039E8B35EDF93AB58C72357CB8342659368BB902C482B0D6A95DF9042644D8B3A44A42630C7" + + "945FAF8BDE53284699261E8D0063EAB14362B5E5BB2556F6F9100F993218E70E5757971CAFB2AB25" + + "41EE11EF9658150D714F46C5CC095F9F22336B4E30AB00D9DD89138D46FE88B46B11914037A198AE" + + "5907D42A4C6E000A612B581C4B0CEEC0D1CA63568BCF242CF4FCDE6917964C7B934A70668D1DACC1" + + "6129529E5BE73A64499932CE5D450186FF69042A79EEFDC59DAFF897358FF925563E8A28C30494D2" + + "82240D51C419261928B13A25E1D7F0E53F80FA76DAA7F5CA188FB0580F408A70E35CD0752B216938" + + "B41E17E7FC24576E49F210776E67E1171429E80B8D64D68762B6F2EBBB1866096CCF6ADFAE1BA008" + + "BB785A7D22F55AF8EA3D77A8003636BBA4F9B84C3FD79F1AA6FEAEF2FAFDB883C5CD88267E3ED0E6" + + "88B97F9D6DD0FAD73AEDB4EB7320E960A7168F3DEBCEA735233605F0A9A9E12B5089ED76BC8258EB" + + "FEC8FB2FDE995406FC3CC16DB518AF37FFD11D1B5D6568B681E84BCB88A6841CBCFDD8533D66B3C7" + + "5D592A6507E06FB566610FABAD867F837B7E4870ED2DAFE14DC2A9AAFE391E8311DF4A84ABB35732" + + "9533334E2E4F436AC8160C31146950283FEC5DD5F5493FF35A7D1FC07A2CA4DFD1EECFF918667F8C" + + "F6EABE92B53AB9C41BA45822C99BF7F4208E872B9532BDD209331FCD14539BEBCCF9B9754F49CCB2" + + "16D0205261262CA9C9B8333358D19A5833BF024960494CE0966291FE2D092D9D8522B03924CD686B" + + "F88D5DA264D3B8FCBCD32F2FAE60E86C27544AEC6D6407F30C7B7046FBE06A3795E66732088B0A02" + + "482A5C44F1F687604EC3FC75213EBD5635B465EA7DF1BB0F6A41E64EA333265089F6DA569E92D7FD" + + "53F9AC0CFD7E58EBA22CBAD9985C9815A2FFDB1FA74B2261F2A9E0772C1F72E499801E4C37526D5A" + + "A4238B06B7B0E28CF729B809CA8D5C341F6DF9071206F1726A5F90C4BA1445A1C01E9D7B10E5AF96" + + "B8E802002071E3A70D106A28FA577F5DC3D476FFE669B1548D1EEA2E0C4ECED0358F798CD737997D" + + "59220E5C3DCA163ADE0A69F67A3934A3E6BA372B2C4DA318F24F9AADDECEDE945A2311A053E87FBF" + + "682F3125286373FEE64734227E846B4EB1ECC9649768240D20AE00FD736C5FC199B84D73C4CB1422" + + "C11C12829C2DBEF3AA85AFE7534E702D221036D95BF3649367DAEAE3CA15014FFF59F3F41712D3E0" + + "DD587B95E78F540B5CE4169DDD37279DBC22BE86C5467D5E15D607202DECEBFEBA0A92F6B3E3513A" + + "11397D3B3A39EAA51F2DE2D1F36F67274A528CF499553056855CC9D87E1A812C", + muHex: + "F9B2F6DC4F057999123D2292E4F5315FE0DB47FBBB6C1E5AF097759792592206877975EEBC6BDEEA" + + "AABFDED9B7ABA111F253AF7426AA3B6EA1B3482DEF2459F0", + signatureHex: + "07BB87114FBBC9EE7F3625F90DAAE42846C502DF090989AE0FD16B97A52FDBC5A55FC13647F10BC3" + + "9A35979C2C4362FEA0961CCA78ADFD1CF7A85E932AFB600F4A9B269758BCAD415735933A51A59610" + + "BBD49205FEDF0819DB2A8B234C7471B84AF22A11547FB0D17647B5B9C30A22FA2E0901B4DB90E039" + + "18A32D424A11D51C809CEBAA3C6EA44035E7D2209634C9D2B3DAD3F14920305E3EFCBB5313E8E9FC" + + "D0F44BE05A69037366B85908D409C45DD7F313BA4737EEB72B3143892C10CFEB70F79FDF99A08F63" + + "4B382BB324EA934B31F6B25D32888C3A0865BC9957DB0FBC065254B61320405D287A891EFE85FC3B" + + "F51DF9FB3847EE9E0CCCE312B31594A7AECC2B3C2E99D650CE909B9685E824E7AFE68E1CCC93142E" + + "A747237E3E9340332DF9CED7C98210A821F5BC2CE3DB10D0F5FA8D2AEDD9F5E7DB2AAD3B15BF27B0" + + "371B758B188ED86CC7589A7ABCE693E9893E84B9AF99A5DFFA6DAFFA1FB4CE3F9272AC987201E1FC" + + "3FE15CB859F2CF5596635F4105B7DAC5642672EBFC69BA0883D96B6BFF21C5FB14FF30A671E15CC3" + + "C914D2180BC9724B33C6D951F53BF3C668ADA301B15479077761214E27ACCD5D6B1F2FF275BAC56F" + + "975EC760AEE332839B7543693A1C5025598925561E4A38A7D4CC2F1AA35AE866E92F70119A4FF33E" + + "AF717B334AE6B46536E4F6C281718E37FDB073CA9B6CE761643DD7D5E32514A2A462BCDF7293016A" + + "5B9EB7DD40AF68411781B7E21A765C64E3F3E657E541DA3209E503B556F107BE12D42ED3A4BA1A57" + + "C959577C9403C6DB722C12D3A3CAD8A8114A9ADAD0E77F950448424116AD73F56360B1A3EFCFD576" + + "BD5A956AEDBA8E03A865E4603B4DDB2C40750647F1A85A3F3A8D65CA324E6E2C2ECEBF6F6EE999BD" + + "B62DCC636FC32588272DBB15E1E6EBE97A32482FBC6DC4E089EC565BC32C47906C721C77ECC4112D" + + "99DE5260A12C9EE7E0FB4BF907A83C110CC631C7CF49EB6CBB2800D9C7B1B80FBBDDD9A4E5EF3720" + + "6625A409FA10044E9F84F5FB3A2D26AEC2C2BE3C9EBC08607A0447BB30374BCBDABCC41752083353" + + "FCBAEEFE99D6B100860B48E8032DAFE1D63C24B439E1A8CE8A7B812048BB4D63C7D152BE68E6C4BE" + + "4F3B97D00C3D7C08D0D723E15099385F005EF80898C1254E25BC5F36FACAE28EFDD762D0986C66D0" + + "F7D4733B5E7AB1B870A05420D492FEAB755EE39D96A4F157BB89CE68485C96DED15CE550AC4068DF" + + "ED97EC3AAFCFB1B61CB75A83D4C7A86B2C2BA01F32BB86AA22A76382FDC2101938FE11BE04A9507A" + + "94F2563D2F70E54A62AD4B63C0B7D0EC65EF47E8E271373F1D32BAEC0D786C5D5AB60763F50B64E5" + + "8AB0393835CB2AEF93B8A95716F5673C418765CB582F6C521A4C62F26D506A2DAD987E2ACC3E537C" + + "209A90B08C6A45077912F3C1A8D6D1AB1AF7F16B7BFA9C27CD48EAA2A3981CB5CC1D8B6A3EBC92A7" + + "5759ABE1B9C4DF05491FF56B7EE3A6A118E05717F250366AC0FB305E72C8F37E768B434A392613AE" + + "5F69E279C9722F3F4ABB117094FF2F20B787E5B911AF6A102F4590AAF96D2EC439E1CA59905940C5" + + "2DB44C22BB93E67ABC2CD8F5FE804D896B60FB304839A11D9352C6ED7DF9EA2284052E3954ABEA90" + + "8E28B0F5BA8076C9585818A0E5001E77549C54895BBFF1B83891D1139E844EAC771601922B483124" + + "8E58AE78968BCFEC7F6BB8A4C99AD1FE934697033813E3D6A450CC14AA0632F4F2891374E64A6B7D" + + "8175D430C31E1CF8777754BAE69BE83F179E7D1D14CDE02AC2744FEC81E6F7C2ACB8B0572F662E58" + + "61987EF9F9EF36EAF895AD5CA81A45D2E779C8F60DCD9ACA48D74EFC271F08EF1DBFCEBA8DB46C86" + + "F988631D7C1E3094C82EECF8FC8BB739B86F0D057EBB986D003B3BB3BEC3E2E670DED1D7624AEF82" + + "69DDB04369D17672EC748E39D804928B9572C1617428B40D8BAF4E088DB0FFD878BAA88771B8849A" + + "376474BE05F4ED455E16DC69493214D907D4374E61B3D29BAA0CF2A71EC6798CE5C714045AD7E1F4" + + "5E75C8ED5E8537C3759984734A8A9555E93C9F8D917B2F72987C89C67470ABA85E4F44E2010CA312" + + "D965131F253EBDDEBF4152B7C9F0D0B0BB1A738BFA92CB706A6ACDCC35642505E5794D5E968860F9" + + "CC2D325E2640A5D034EFC51581B4F30D1304E66F51A2E606D5E344D26D2F34BE3C943C595F6FFAB1" + + "DA0EF20640F95E36F395D4C3C012EA0E7DD464CC8C2B1AB93A5F389AC69A6626D626A75C3A97478E" + + "84DAFA2FA58157073570F6717873A3DDAD84151D69D3510B3C605A229AD7B47700374888C81286BE" + + "711E3C1DDACD1AB9EB3565D5489C9069CC4C0778800EB6328C7C4F5EC6F76E5F4FA3865E180FCBAB" + + "3D123898CCD1844B6F47E96D36B391F3C249D65954127CB5BAC822890CCDC74ECA92B81B2BB1FA5F" + + "F1CFB5A2845F842F6A29E15C2AEC06891D824B03D6E149742231E13B890181D0235073A56401046C" + + "F6EEF39EA371F56B0CC91562A98A14A604EA46498493246364299C1D2B64C5F6C6A292FB11B8AAE1" + + "7D15EBECC31B3BC210374ED77F464D66990CCCA73D53E7D27B018AA394E23B07F3C53BB254E1F949" + + "0F2D4354F2781BB7A071CFF014601D76286E3B2D62D41A0EA769953AC5E063DD6CE3EBCCE29B85A1" + + "C8474966B0D9628397363C9EE5E1E3C406F66C58F35B7B91D62549BEB0680CA72EDFF3E78435F8E8" + + "228508ADB67FA7587C3E57EBD766F6E863B80CD6C703816D615C8F45D448EAA9140FD5990FF77723" + + "8647D468460D457FC8CEC0F85AB16A838F7800D92FD2DFF6B5E49E615B0BB2FC197EC9A77A12C627" + + "211B428198529E03778B212EA95C04C8091DF2EB5257BA316482A347C51D0FB3C38CF490F48E60C8" + + "B9FF0A0CEC746072019FB046B611075A7593D8F272533D4F49E3A97D554AF3E1A5E00BD9B85AD6F6" + + "07C7CCB4AD4A095C0044ACED711DE2CD30C6EAE76F930A34E757BD9ACF5BE6806E21554BEEE190DC" + + "80A6701C0E791735CAA1D9D6F492EB7F055FC02BC4B1FDD71685BCAAEA3961B509266F2179A9778B" + + "79F94CD21E31BE42E3AAE3E813E9AFE2AD8F340F828E983809CA386487BAF2C10944948A202C9875" + + "2B6CD384D0E0C1119F97E635F4FC88187FC8F5616B5EAD760B38FFE231CCB7A0BA60C8ADCE243303" + + "5C42E3F65BAA87ADC8463E36ACDF39C6D1B0EE23D602ED46A3E201D6F34F7209802A48F93BE0D6A8" + + "6E57072AE09F34C83C0E918CC20FFCF7440FE518B8B28C096B49DBB61DD5E16BA3EB4A8B91B85D0E" + + "31CC65CBFDD507BA34D83227CE256860D5670A25C01BBB5EBA26316A7F76404C826E2EE4D21BB2E2" + + "C3E5994AB53C44D240975FE2BF0948F61DAC0F168F4278F421597DCA7DADD624E92BFDE53B87E89C" + + "379B802D8DFB8D32DBF121D2C104FACA12C1ACC0B1E502320957D28743C5ED08539418241CAD2E15" + + "8DF61590D3636F68604AAF411C96AEFCB306CE98F7A8CD470DB95FAB022690FDD8D456ED3669970F" + + "DA2B0305BC97E4FDB6A9EA3FDBB7060CBB7224380A0C3AD2C59CEDA4495D4A38190B80BAFD9354CA" + + "B38C760AAE467A5C7F8DA14995B74ABD9B026A4CC0D3B61BFFED7FF961649F178EEC7D4EA510349B" + + "09B0D3F886AA8B778050AAE986B444ED2F5A94F564BF44AF6964465E693241567F8BAB93BA79545E" + + "F50C05051B9A66C6888BF100F84C5278F3F81FE4D1D80B7AF5384F5F95B94C8A34218FB00ABCBE6E" + + "BF80EDC1BD978D31F2688A4BAB22414DBEDD7669CB9708DF89353DF9BC62099B7031F7198B1D88F5" + + "1CD9FA4BDC49FFCF745D291E71CAD1967A9C7F12D57EA61E41CA0E5ED230683156954A7184F55C21" + + "490F8427E74A78881284DAC649FE761CDC4A9C7C68740D257BDD47D42C03090F09E19730E8C0F1FE" + + "DDA9251B1FA7058F388F69228D3FCFE04512D232A348F956A367262D4CFDB6FA7D15A6BF17C0AB4C" + + "29FDB6F2DA028A9D3C4585D3839EE190412019FC8208FE6A532825C7497A2084386283A29C8D35F9" + + "64709CE4FF6519838AEB6635E05A6C178ABCC260D10C35512C0091FA5C3CC03BEB9808CDE2D9B45E" + + "CDDD92E1A05B034E86F9704AC17418E8464410240D569EC00F01ED1A6C15FDF41FFE454857E4415E" + + "F23379133903F44A79D55CA52118F1D84854A794AC5FFD32E17B81C8C0A813A067D6D172AA1D7B59" + + "E019F0DE271A2F0097C6D8961B0E6E5AB4E0DB56108082A4886FC1A86C063F1C35770A43B0C5B988" + + "6B3B55868CE986D13BD5D1455E257ACEF5CD020ECA694EBEDA3EE0BC8D94DCC90461101EBD401E74" + + "80DA85464959A9D9CEC002B23CFA2FEA89B58F67C1ECE5027E7E2915F617ADCFF6C479EFC33A039C" + + "72CCDB4135FBEBECD0E5A6B0666E325FC54F678F9223515E98FF2578E825F2D5235754A436B516BD" + + "DD2CE7926FCC6A2A4735F7575D4277A0DBA3E8BE3470B7968646D3D7CCF3822087CC7D8153E83D1A" + + "D4E9C3FC42D471A4391B89BDC904DF62BC7C138CDEC64C7C0DC0F0677137889CF4164339DACE2419" + + "4F7C88855F86A293480925E04784393511A1ED26FA1BFA7F147B694E80450C8855A11B98958EF980" + + "27F4E6C8E3FEC2F47AEF14191A445BB3BBEBED252B84E0F1F9649FB4BBE3FE26637B9CA1AA02132C" + + "3480E60000000000000000000000000000000000000000020B11171D23"), + + new MLDsaNistTestCase( + nistTestCaseId: 122, + MLDsaAlgorithm.MLDsa65, + shouldPass: false, + publicKeyHex: + "776098170EC9457BC9CE22371375706B8EA4D943A07E31FD60A20ACD4ABE9302E3A0D56B1208FE00" + + "CE61A43FB459BDEA25A4F5E1762F59EAC0AEFD198A9355AB4F1AD45BB5ACF794CA2FAAE1A69BC7A1" + + "A0C21B05092E0A2EE9317370CFCA9C3E3CCB9767E85A8F8B5BE8D210F2C9D833828F7C64C94AB0E1" + + "7F841D7F760FA9F0BCD0625C2D9BC175E9908EB3EE085666223092CE5C3547F514D1FC6A160006A2" + + "9F3F9E07E29449701CB8B890CC1F380851C568F664C9864A292F7CFF8CA0688136466D358CDF81E6" + + "1D038D7B1294851B83D542F2D657CA912E93365FD69ABE6A73CC8EA3435A7CC67DA9EACD2A8FDA80" + + "18AF569A8551AC94A3F3ECCAC62840903D6155558A3D1D02C23465F27E76442980DEE089BFF9D94C" + + "F6374C5C404A3A1FB325E771D1C34A321F3D5B4A11D32EEAAF59B5372BF21C31397B064A2E95CB7A" + + "ED64BE13DC1D3A2A1E31F05932C6A04E97E81B920574BCF5AC43B399B485EF98ECA6D9FD698E2BD7" + + "132D61D64703A0639DFB3D319D670D13D5818E48A87A7A0DC56400A5A120B270F931DD0EE2866643" + + "809FDEA12C215CD37107B01647B628CCECB31B744B2FEA5B2E0169724541BB7B46C60B64CE1D71E0" + + "2B5E06E8D1AA557DDC04D3E5E6963E54A84212B39F8A4FB136702F3B90518B1F7A9CFE9ADB23F19D" + + "061335BFDBA92FA4232CA80A254597BB33F5E2771EC0CD7E25E2808BF7E44D95B53C14A66B59C3AF" + + "19868CAC1F8CABC1911199C8E88A7FF2448768CB6DA7EC010B6DD19F635AE3E6084DED2177B4B997" + + "4B21E3D9C2D07ABD9B1BA7A39C232F7F5D8F773B0F29E7DAB4C802B28C5BDC38ECA26FBD94F159E4" + + "302BCC0EE6D033AD6CB912C939D1B18A4CBF077DEB4910EAF018AA4F803F36539565DB209A15F930" + + "E3D1675B5AC11634FCCC72BA7B68F9C1678A02615E7A615159FF061ED979C4CB3CBB794A9E4246C1" + + "ECEBE34046654D754D0B3DB2275ECA563334C1F4D570064CBFF6E6484FF1CC484648B259AFF08F36" + + "CB019177BE2043859C07DA8B05311444A1FE306F70F72F644E0A3A82E5D39E0BAE99562EC275397F" + + "0F5436FF9C2CB462E1A785D817F0AE93168C16357E76368EC12CB079ED7B1ACB4CF6E45891A3F91F" + + "8D08EC91FF91BA7A8A40EB941CA874003A57A6324024B208FFC2E72F838F39E842D5689BE413137C" + + "E609A776995CFBE9883A92F94C631F1FEB66A28CBEABC96BB5CBCDF13246D5C39E3E71D0F08AD497" + + "F43D3C909F1AA340F2783600121443CD8969BBD7BA0F18FDB089F0BC1BF53BFFFC06B7F458523120" + + "445B144806206783BCA121A954D842BDE8736A174696927A91A51A4850DE1168B7CA3592251C4A60" + + "3F23829819B7D76CA7070F5AD93CEDE04A7AE4BF0CE90E10AC56EA143E6CFD7962B22F866F2E90BB" + + "ADAE2E00356DF3ECE88C6D2609C4A41F24BC03B4D0D52E7A38A38B59703738FD9ED2A3DA11616ED8" + + "B3F4ED2B8DA71B283CDE7A97882A7620A738F6640AC06822A33F45CCE53CBEAB3217059C4EA390D9" + + "B8DF4FCDC83762A3A03E41996547783A167A7D2A75BF8B1357EA8CCB8C6B4976EE073C13CC33A4F8" + + "900367B829EAB5790D591DB79897EF7F93882B85AB732D3B1ACF2856B0BBE1D7F169120F5E55DF87" + + "40BD50EA7526255C921C23B200A3385AD7F19FF3D9E0DFA2321BD81CEBE4A7BC9FC2F1094D64AAFE" + + "739F96757314DCCBB10AD11B0E3F469430486108D93239C87180B1F9595368136A70E9FD13970ECA" + + "E089F374728D4086B013ABC8FB5944BF1525E727193917227728A7D1081D98A217FD9611B8D7A5E6" + + "7D60134B023834E98530032C5A74D179C2FAC8B26EB99E0E02CE605E1895C34B128C3C372B5523EA" + + "981AA8F56F065120BACECC1B25FA9EB362D6464FDF2B1833F5F4294000036A8CCB0031E7488476D1" + + "C928708C08BBBF86BB663EDEAA0E8C65DD035B57DA7CDD9A8454D4CEECC8FF266FB4DAE0005BE1C7" + + "904E204DA7238A717D1AAE9B5C9CD6434E8316C5CAA0E98D459C90CD8C3CB009514A71673E41057A" + + "91B8280B08236B38F443C68DC923EE0EB0F6E7C3C99AB4888D9A32B553893DE4C9B5B2C4478883E7" + + "724C82A916002C3EF21F6C5E4DA59A7412B797C89FF5C010B0D27BEC75C6FA42328F85B3E7C62806" + + "0A783B615CE93A13949FA125A9D5816ABCBA957B32EBB91B0519EA2104C38A5A52C58819EAFC49C5" + + "CD75484880B53DB9B350658CDE837E435948ED8C92FF20CA7B8A48CD4364E22DA72412744D2759C3" + + "F3D1C45342B7CD3BEAEF1FE475C9421A86642F8F736772A969858054E8B54CEED0BBCA2CF3CF06D8" + + "40A4E9AF15D8E48FC1C4BCD62FA18F8B18F41684608D8DA926F54A4B795DBE7B6A3699AA59D6495E" + + "489606011667626459E9AEF5003AF167787B0746365A44C9D7107D3DF411B39CA7D660AF4CE9791E" + + "571889104AF334B951C18BFA0C6B25B72ECD6C2EBE52D070D2A006A944764185B4D5DC00BB77E7F3" + + "CBEEB0A60847D965848CD0E5EC5B1416BFA8FFF89CC6C62FAD7DA976E54055A94BB3DF3F6120C255" + + "8752221C64829328468D7E7391A4FDB56265CC0BC2CC6332B4BE2C99D130CAC21014C477E5903736" + + "06FD057E8DCE618674EC9E9020FCD95106588860BE495EA45EC9369BD4FB49CC9D2FB9520F4A988E" + + "824DB43226824A320D1805107A71094C2C5DFD09EBF53B096F36D97A283FDC368993635CE21DC450" + + "528237C7119B8E70C2EB4FB2D7148206A60C3C494FF5D6D92BD765DCDD0B48EB", + privateKeyHex: + "776098170EC9457BC9CE22371375706B8EA4D943A07E31FD60A20ACD4ABE93022A5EA0EB89131AA6" + + "F327F0BA8C70C711BAD8740902B052258CCD23FDD432FCE39D7B651B6502E576B40E1145E2AFC30E" + + "7A3028F65C5CAC8440699A5B1F984440F93C553D78BA11FF9E91636A11F2B1E57702D298303E0B87" + + "35DF2C40CA8FB5E47828526115338730803050710313410415242161205201612800262857870524" + + "44530103747726400650052610162358470745642030123001553217022446256668305178113861" + + "26118385333031310421441004138625652120157220003464403846837803343018274375711545" + + "07721270757777448018466144648321734473723812313136727012285027857680270651702406" + + "63653252518518703054284874454582108316112057502477716037635875285240732731606486" + + "05685026403731538435587846532156544375167467386371573456435008242775745241451577" + + "53742026670458056521483643783284845836705762787841774502440285551860081567748287" + + "00762561375083218645584875768228671870338368183312454284071604420847756723200287" + + "60446155215421246474127238531064551466362106230822151861017502066010235061164708" + + "60230073833844744287401178444347567367240768403283477210346458424627726437403503" + + "54468127233505478452365632013216570180813786535505873441440087735706357831108747" + + "85204237331577641658415771241330512662578557381652230111266535886020680487147244" + + "50666605400332781055061018413442884322848458014485500614201741386238761886035756" + + "33622235103657734538176671501477047407788573425474877656682024212465350061466430" + + "11676531140218207000852131677463054353025466177408123212716265036537850717442734" + + "30177866400314151081365653144787508343870258243447822267745387268160857144878256" + + "38401444752256887617147542535053517741267827238415644060586034714808662600436216" + + "23804014382876326025300610453805536137332052723710272752413116557285817417878072" + + "34381143064608160827828032077067414856483576671845141541700346433170104467551748" + + "35400208200537886636136177841814686671371835135660560858622257811472843028311843" + + "63268831817206036367864650417303704136274258180075746373007828114537374586602657" + + "21770404036582106447538364314825712120372724875502170075057632637317850567724333" + + "62020326246345374810587837163420323204802854175828403843507860408638616417872558" + + "66824228426245053386324544111058315621722167216774858405886774275825338160414748" + + "57284570753271116182622872478133823035884640876344420304686578127242308887387643" + + "01053863620126801658777828121374662057072183307185605768710527381348184715371552" + + "17254336620414401710806808655207805028107308383322388582774713833814371240817662" + + "43770644234578136513211071152553824317684668083320686017753548344346022337735846" + + "31686483303501751271422763858662735445685673747007311133028578488076782057423748" + + "62030852360578280748021854508615058147635011275855878260648382074334525170842240" + + "80230027644438023448675251567188111736223648411445037415071088356603375262865350" + + "12470863272257862462675712628786727354483343816515278240824273777312400725322580" + + "05370820846221215536840380388862551827777870604140206877437043834267777411746038" + + "55402565015477116854711502586155058101107267821628718676334053328810646244641150" + + "22056385431362730376128076818845441480482513042744302301328116758487540171728048" + + "545747332157267751843465020845003D8F92742BC395F40222DAF18EC3B9ADEB5AA0C15332D851" + + "7BCA97C438243A0E481E28009951D5162220381D9FE43FE88390F0D6ABC55A15184E49E5A7EB97D5" + + "C10051C6AA0EE9BA45105C82F66E2E9EDF65DA4EF260429CC3E4FAAEDFEAE675EB1D6AACB226B49C" + + "F3045FA546BB890D3729176C0BC338747137BAEF1A16B6806074DCC14945FAC5400D9F1DB7A38EF5" + + "C5EA5596BAAB1031524363C40F8133C497CD4D91ED5047FCB34AD28174767C682F3718857AB33CA5" + + "1969EC504CC1C8769DEDEBFAE3ECC64C3A8681C5E1847873F59EF47374B5EA9E78091BB636659E0A" + + "CD2BEBD5ECC93E8523FD0803FC27B4EB4EFF689AAA3E505E67EEBA9F44AA0084D20F151817DBDAFA" + + "E8BD9F5BB9C4C5AB4E52DFD33B4A198875BFEA967C6BF73423DE6B606B4796BA9056A3DCEF452E6B" + + "A0EBA43B82769648E492D34FF8289A2BB1FFD051261F30255B2B0F2285E4F1B51CD6CA4F827B2E96" + + "DF6BB2419792313B36F5C867675ED0A5DBE33FCDCBA3AFF7B8825C595C302B72064E3E9F3AFA0158" + + "B7CD9337F1B6F889914484BD7DF07729D7AA8B0795D2764EEF8CAEC5E06B538A549EF77D1821D0C0" + + "C9632801886AC4B3AFCF29A3E368EE90213B162612B3DBFFE4F57686CADD778C744F387758DA76A4" + + "DE8759D4BCD2F9B07FA26CB7E103628C79FB812F2C20CF87995F6AE0E69959717F34B7F792B85DCE" + + "D79DA3E71A057E5B75C8134C743EFBD0B94AB8066528140A47EC6E7515F77074CA17C4E4C44D2A06" + + "F3B4AAD365C6995C96C0DD004CDAA73935B814230B50EED38D8989D93C727C9768180605AE5C36E5" + + "26FB8E472CD3192FBD2D124AB4D5A4E59F63CF59031256B445100002F5E27E3D5A947B156F56517A" + + "E4425D72EE2D89BDFC57BE7104645BA89A463C72FEE601A81BF151A6A7422B1239E352A26229737D" + + "58FD490C3DFA5C35497FF0CC3F6696716BE24805B771307469A3F50284F0B9DAD0369A756DD38EE4" + + "B16679AF6D979D9B1C1FD460B7229F31D83511A95AB35BD8FB303D51C689D147B114C66A744A70A6" + + "688A9FF07C4A7EF750F02B3A608DB3B146ED79502A5D7F01BF868CB122B695EACCA6BC70B9201CC4" + + "2BB087E3D277727DA343BA00D5EE6AA467A1D0642838B809A9B6B873020A2E3FD6378BEE6370FC4F" + + "8135235A0DBABE2606E9FB8F329FF066B919AF5957860221E3B5A0BFD4B6BB35F2CCBAF59C1C269F" + + "DF697E8592021FE8F7EDCCD2AF379C43B8DD0B4195EB9AC07AE57A27880B03D1222FFDCA67FFA2D2" + + "5BFE7BACDCDCD91329CD8BE79B1C9ED6EFA46A259A1872C709E962642ED87B28A37A7C96B1159812" + + "8687804416C655A642C20A4861D0DD8A8E3BC76D8B10D0F64BB05DD5233ACD71487D3C1790B2FEDF" + + "E65157A47EAFB346A993EFE1B49F99BAE0957586C5FD210FB134DCAA9B3253D0C87B5434876B4B19" + + "6A5FF04FC295F6203C7D8EB4DAA507A90B5561674E6B7C244D38E89C7E75E7926A3CE10E89851AE6" + + "8E97FAE2DD293D050217895D7007060CC53837DF48B3B4E9E2CAEF5D4BD6A2F0FE02D0AE4F300E31" + + "98962EA75A0E4ADE2F48CA61655E9BB49BA218CF196BADF226B18D04D8FD73EF127E15A54EBC45C2" + + "103EA07B0819D3A20B63D1339B9D1AF7DF2493AB3E49BCABFC87EC17AB59E71A4C0C3084689D560B" + + "950CB9A6F5C8CD2503C81B49266E9F293B27EF6543549B685845615C3D7687145769FE69D646D67B" + + "1CE339794E558279C1468647DC6C8D71807B8651FD8D203C8D63BD62DE2CB6BBB0F148101073174C" + + "7C9B6D2B1469D07B15D431B700CA1ED5B95CD8647CE06773D8B88271C1465C1EA3D474164FE5A819" + + "77EE69C7578FB727248CE7B7CE325847BCD43831E17B0D21B3F417E60A2DF106784A852A76A8053B" + + "9ABD052022921296E1659D310544B3C9AC5ACAB09C4FAF74F0FB3D7599AAD4D38BCE902D0EE3B040" + + "6BEE441CE47A75DAF2491B72F6624B07202A683070130294CB0A6DE3C0E89A6114D2F9812B16283F" + + "13B4E05D29A51C5FC789DB21B9EDAC6A5FCA939B4D44AB4A6FB269F4DE65E13DF7FC02A6039D2932" + + "3F3C00F0C1AB0784706FE40824A4901D4D0E31024D2937EBDF1D30D6F8D73A3CCE82E08D0AAAE623" + + "DCF3C63EC809556CCC85FCE783A9EF23155B0415461F414F63181BCB1E77CCCD1DC9F824AEEA4F04" + + "6F18CBA4F04162F46031B18CBDC51990D5DFF2B850E539EE0BF8112C52C25A6CAD48C574B2F7BD9F" + + "7574F4BBE7EC2A07D717289F66F949813C416ABA1CB93D3B7A246B755CF8B0299A9090789AA6F53F" + + "70A042487092AD33B57F3BEE1F06E6958680F57C0264D543513A7B357281804280A0A4019C08E8C6" + + "9D9C5F9EE7D7C9BB95915C3FF92EBCCA41332A2BBEE4D6D8BE6A36DB8EBC6ABC5F99CB4BB9A4C70F" + + "08CF29A18B63FE0F15FF817F5ABF20FA40E459C650526D5A8DC7AACF15524D48C933A37FB5C54835" + + "575A83CCECB70E6B0BBBE2BB09B983E981AB371EA1FF8A27576316A156871B3C01B7C5CEF17796D4" + + "125AD2DE2FB91B79BCE9F4580927742E944D4FD6B583822E602A109C04E39B988CA6DDBD2DCA1EB5" + + "0640CBA996230CABFABE9996262D98C7F1214B687ED14AB48D515F0C504092C4E32A760294D59C18" + + "59A1FFCD206BF7B0C2C82C354676DAB901D8384C4FAE5538C0D238C1BE37BDAF191104624EE7587B" + + "0391474853023B0F11229D2685BFB2D3D6214A50DF3F6507F2BCDAE4DEE0607DE95F76EA3C49DEA2" + + "6FDA23034750DF72D746B4BA542C047C58DD7332C11892051B39E36606E43C0777E1810AA8236717" + + "21441A3042B2ADA1C0663B6F78080D6FF1F3D18D6DB8E40BEE8FD780FE2F503742BC9F6CE96E67FC" + + "893431FFA2CA2B2FCB4E003BA1EE1A81D8002BE554AD9B3FC2408B568EE92B9F9A5733FC5E40E41E" + + "519E6D5971A7629806993B46BC06661AAF6D63D61C87B523DB88CFC2A724B63190AF8D3E0F2080C2" + + "E723083EDAAA2E8C7BF387C3903DABB8941264D676B7FA75155E5413C62C7DCE45BA6A830685A960" + + "7B7A976BB03DBEB29D45DB65F8BAD9C3C898F296E8974FD750D513F3A783617FB409D662A462BDF4" + + "64B866A14A8AC0745699FA90EBD6ADD3C45FE9BECCC613EDD06713E9ABC9814484D0842002BA1CD2" + + "CDACCAA7A6FFAC9599E7B956AB1BC9DBC271378EDBB103F2C0D41699E8E2C47D9775790DE2C941FF" + + "B2A5399C1A6404627B10447CF72122ED38BB254AAC2DCEF220C5E412773986902A9DB6F62F561371" + + "6D8D50B52793C460F2CAF67EE92CD5E8A6467C99C2232CCE78218DF7C28CA78A24C4EDEF613CB423" + + "9ADBDEEB12DD01BE30F1F43FA5D066F4BB76964356791D6D67A0AAC16783C32B2CABF9DEA84F0882" + + "263FD9B69CE0437822A266BDDBBD22846BBE5AF09A533FCE67DC8FEED11A6F666982E5E13536C71C" + + "5E21C9EF4154B4F14E4DC7C90E69F8CADE4F4FDB7DB7D6392D7D0A365BC0ABAF5CFF22CBD0B9C71A" + + "B420DDEDFC957F317BF101BC218563E215CF3FCB321E97B162B5EA980752327C", + muHex: + "5AFFEDF20D174F068651672FCADB0527236B3BC0E4AB29437ADC549BBA931B0E28ABD19DECE6DF8D" + + "7364CEC62F5B788137CDFF6E9070432C9CDAD9ECA4C36B55", + signatureHex: + "4D36595A24951350E6EFBA6E6322DF067F0C97FBF581EA0271E396B0D1D57BBB35588F33AFC0362F" + + "C0737415ACE0879D0102A2890764ACB67651D6F04A095A620293BEAC1538AE7D3EE07228C02A0676" + + "875BC6250D25026877BEBE6784CF6BAC6DE5C7B4B857F00BFCEE1780706E28F0B1369974F53FAE37" + + "C9CD3FC36BE779505DE35FD397A57598C051D2ED728AAB0CCEA2537CC8A25A957ACF51A258DB11C4" + + "272BC3EEBD37A9D2654D5ECD8C7A226D8A506E431A34A1E36232AB7634C76D54BA419A7874695970" + + "46A77E100CD9171661EC2D0E762F8AA58A18C8813F228CC3532B3DFD60E3D683F8D9BF49BB87D1ED" + + "D0E1C1822F11C8BF54FA0B0ACF0685F11E29565A997B8DBB5193550FE9EEB2737DF4FB2CF67BE69E" + + "B800689969AE3A2807A05B4D170D20CB8EC878C2BF7456143C7E91BE5C12EE7482A50D1D9347E829" + + "CDC394508FD95271D8DF984E5281BE73DEB6424DE2B1D3FAC5B475731A72BCDC6A249F60C19A6559" + + "2014D07C069277D7F181BA5D9C6C0FFE9565A135C814AFBA539099D2809B8821FB7DE6DBDB6E36AA" + + "2C29CCABF3849CAA195ECAF5E825A594741555A03C1CFB06CA95F2ABB1FE08463071A791103E6836" + + "AFA973725EB5C3091A4DC2D8772FA6D67ECCD450CCA4EFC70685C823EEDD05B2A3FB02375F17081F" + + "8E42ED310D264A18D065425E5CE4787AC4BA7ABE5FFDC5F36E30FB57418738682DB7B93FE10B427D" + + "622FD148B3B27C1E580FCE4EE7C4F591115C88560C6B069C78FFA9BCFB78E844AEE8A60CDD30D27A" + + "5A149B428F103E79AFBA61984390013CE54E574A54A0DA860073FB611F851047D1F1DC9AE54BC455" + + "62375094C70C12FC7096E5CD223D37D03CD284B39A57B408346ECAF2B5FC0BF9E9E6FEA7C5887285" + + "4AB0658569AE4CA080D1E70D94B882248E8D46A25F45EE1254BAC8360D170654EA82108FA55685CA" + + "347CDA072D5D84BBAC609879353E34F196637B55E9F45302CF461DE01B8ADE58AB88DC6F1BCF957A" + + "78C434AD97DECFFA71F25174170DDE5A009544C7AA1BE06C9BFC57E6AE9B2E51338E367C8C3B8C5A" + + "6E35F82C7050AEA6253325E85524CA224BC9EB1966AA63B2B95DF47E90C954E4B99D677AF8036A94" + + "49BA7C3CCBFD98D126BE9294768C077C52899E2B66FAB4E7325F226D08C86BEAD4F3A1DDFAFA4768" + + "C9378005F03B4BC46C2146A1E1D0865E7B24F75D669B78A9FBDBA7313D39784589F69259D365233A" + + "622FB1253A37F18C930489FD7930BD03BC8EDC80297B3E3432A84F22C02026C32006CA525C605382" + + "4CD624E978B7B92E85EF016BD9600710118315D161FFFA0BD2584B1A87E15ED2C09932FDC345C26A" + + "97803E3D65DA4E9CABA5988DEB73E3E52242213D13D88EA68664837029E19C4ACE7DE5A75672321B" + + "618F726EAB42DDBBE6A452540D471B09AF2FDA4002925578EAA4F18B62BBC5159DD1BFE47C214322" + + "77F7A195EF398C06589630371D03D44E050DC13525FDFB40EAF358010275B35660A4B5F81854712F" + + "D9057221246A54300FA6FF223F6270178FE767CF1C0B9B41956090C9621EAFA48442FEC5CBFC63AE" + + "0C35FEC34BFCF66C2BD1C8249E5C51A6FFFCC38BA21945DB347159176C9BA9FB867B6169E52EE2AC" + + "4E2982AA599FC65314D7B7B04C3E88A36AE218721B0BF9CAF8DA10DA48EB3C629BE9D73734897AB6" + + "66A16CD72A1D3D32F84A2B36EDE7CB44CD674DE45F98ECAC7FFC0840AFF5DF166A20E58C367C7F7D" + + "752C64E3E43ED2D0515E07AC41D7465FC28A47527E73984006D951820CC5AE7255BB9359D5F9682C" + + "356A576644C846C4391929CB1EA7790B501021531A87E518F88EB94F386457EF6177D0E4A9F094A1" + + "CEDE1A9B0DA32A3BACE85DAB0A0B33E59B011A19FF6E25AA4E13049AAD2904E233F867FFF729940F" + + "53A1E6F58145C0E988C9DA8C27DE1A001525D9A455FE6E02F931FFE6E9EA37726CD56CA5EBFA7043" + + "99E309D698A7E078062A71166F1EB0B4A477E15392EB7C56CF0A1517494D055CA9FB8DAC3FC82782" + + "83C5FB7E3B01A60465B5184DA883AD81F8FA835BB1B644E5A1FE47ECCA70AA9FBCC68B6D48AC57BA" + + "309A84B9DBEB22708CA5E6E565011120EBBB350A1FFAA4799D929E2BAF180EF6791F117565AB1E58" + + "FF1F5D6282259548C1DE2195747B4C8655C5D05DE2E8F6EED16ABBB4C4CC43E5EF4B234308C49B4D" + + "412741A7355899E680596F9D1305E60AA69CC6C46DA6AD66B09E2806303C17F34AB1B29F0E536BD6" + + "8863EDA9150DF4032DED59388E3DFA0C6113818F95FAE5A6270209AC4783D15621E84229317079C4" + + "A8C2D48FBFF92FDFAB413BAE100F96246045E5AA813F52F7532858D17923B1AF7215981C21D92473" + + "0F7B8A2D246F778BE4D4737730CEE3746549280D64C9C84B3ED504840CB3270734E7AED6C6F06CDB" + + "981EF92D21C1B98006AEF73A0299C696ABAF67F966C9192FC235C11E9EEBDD57057958A672D3B0C7" + + "CBC7C4311F568BFBE7B5031754AF5479B04DCE293C4B5F1BB509F7BF992A82B92F6C80444DE14735" + + "910C2E748486FE548D590903A6070A939D9623C1302F355481787CA398F0E1A9247715042BB0679A" + + "B92165D1A3B6A47143ADFD8AB33A2F3229A08FC22D8956CD86A444D0F98FCDCFF15066AC9E6912F8" + + "5ECC0FA36829BACE36B090760A7B57D6CD5FF3F3698182917447D31E6174BDF0E9598787FD53801C" + + "2D439376761DF867B5F9B6644928714A1447C59BCC8DCA77E1B7D9080455A719F8626B9A5E617217" + + "E57BA88FDF27740F91719D2F28E77DDC045D138F6723450A5C4778A4626B2D17554BC499D4584402" + + "97C655608C03F092874084C3A6595089E8A7189454239BA2E71BDDD1A76BB713C01D72DD2FC97578" + + "166D19E6071CD068D2866F2417136C3D84AB9D6010A3A721CB4BEC968D3615EB5B86740D63193C62" + + "AA51275CC8689D471B39C3ED78BB093DB1DD24CC51CCBD0398206A9502E3F6A8E8CE965E74A76010" + + "58D269EDC0EABE52584F34FC6AC7B925D622494BDAE98C0603C5F3BBB0907210E3EAE42013DDDE47" + + "2030C2DAF806A4883FCB83DBE23D2159BBA94404F2FF411A13E70380E1E5138D9C3BE12A5B105BCA" + + "48EFD64396ECE3F0E3447DB78872AD747B730A16D9EE042C60EE8EC2242B2DDC960C9CA647EAA8F8" + + "A140EA5EC5FF216D9D2186E1BB372659B95E1FF1CCFB1F78390909F85C1CAF2B80ECFA28E4CAD122" + + "EDC723A778850E65E427B45C8D22315E0326CA34EC10AE242ED0322DF1E21D83777FD77251A77CF1" + + "4BBA4867E761006176DD2F01AD048C210547ED104C09C6C94CA056057FF9539F19A1E0E4B907D8F6" + + "39C3D0327D07ACEAD0F17180940A62FB3DEA319303576171454C396C22F143D9443741E4D43A1BA6" + + "2CF3CBA3B2BB07F65E6550660FA5C482416E69835D485EAD039D89D4345DB41329AF08D65DE1A121" + + "AE0B9B10FE995AB054DE980A07571EA17ECFDC71FDC77B6BC3CF0A31A15DB953915966D2179D6308" + + "936F9D14F1589FB505CF03B4978EDE566F10EFE68166A059E943AAEF7DC4156BDD6F631A684DA18D" + + "EFF965720F7D27FB960D953E6E8D3F1BF0A7441A2DF200AB200D1477BFE4F0D363E3A6BF7DBCB4F1" + + "AC0CF6A56B49C557952B276B57F5C3072810E505FC19677115CD111866A3162390AFDA3B4BC9BE08" + + "CC4BC01D6F0C41459E3AF1937765E471E96B177CE330D5008E26CEE0F0DD7F395D9DDE9675FAB27A" + + "6DB81CE0BA6486F0DE10A2DFB65520520028E9E8F86F2D0C3D8AF8CD543D3B2C77A4311B6590A6CF" + + "2E0251BF903E3C14B572636AFAB027D2763E241271D14DCCECFB584758CE3FFC0FE73CF985EC2AC9" + + "8DAB002B22A237777B1C36FA5798C5BD01BBF07F0827D0AB21A96695EFD4F2DB1F2819459E24D32D" + + "CE89C42658226EEA46AF35EB4223DB53B46FEA1B5579502DB491FCC63BA05A709FB9281189702232" + + "8D35E9C66D4CE9CA7EB4667BA622F4E25484311C5733A0E3A15582B55248B0243C99894225DD6388" + + "4AF05C1C6C748C95148677E4282D42FE9B208FAECEA81098956566220DBFA6BEACE03BE5CC737A9E" + + "9EA6B56F7F808798DAABE3A02F63A39C61308A4A60A853F9AECAAFB74BEC882343EA9B93AF850BD0" + + "398A94567242303893FB7A86B685A47A61A787E2964AB0DFF9684C200104FA9BBB4202D2C036BDB9" + + "2E0AED98C7DDCFF9FF37EACD4E6E38C90890396B1A3196B06666C88EA1645B162A4B7407FE25BF8A" + + "498CF8035F3668EA9577CDB492B0AAAF23252574F5B0DD792F50CEB00DACC3DBF721C1EC69FEB2E7" + + "EB8643E99C36A089657A3311F0469196995F6AE17B975C694805C2B96967D8C57409ADE2EADC328D" + + "52E1F159632CF32D9F896ED2568B1E33D914B497F5C447CE11735D572052BCEDB4672A9F35BFDC20" + + "C780C905BD1D2CE549DD080869A8BDEBA92892500E78B6CF4F8774C55005E8AD158687B6433C40F4" + + "6FC8BF597CA8AECBAA1DC77C7FBA26C80D0F31E4BB29307BB3F3B46B8630FEC63F54EC459CF755DE" + + "A7FE6A35C46D42921AB12006B7080B8CBE55B24C3EE7E006544EFFB62352ED4FBD7714C40A8C3F26" + + "37BB7B0CB21EC82F527D8BA7B2ED2A3A4448536082F2357BBBC0C2F0F918DA073B8DBAC2D6396900" + + "0000000000000000000000000000000000000000000000060E15171D1F"), + + new MLDsaNistTestCase( + nistTestCaseId: 126, + MLDsaAlgorithm.MLDsa65, + shouldPass: true, + publicKeyHex: + "4A85E851AD50F93CAD46F6712050807F12C33503971AEC79A1B712C65A546A3576DCE9D9AD1982B0" + + "D423B8B5E5AB064D65EA4EC4A84F52EB0B7B81B8CB08424C490F4F1CA88F4BC963C503B2AC4C0A88" + + "C9F5ABDF183C01622D36906F02FC10BBDC39414B71616A5B8AA3F8A9A90D78BA2414C53FD239C617" + + "9180D1B4B9630EDB92785F2FF6187982F4EBB4A0103F464F7A21E82D354288AC07B0912A16F3F144" + + "5D2C7C1F41C004F4D066D8AD5DE0D6F91CF7F5B78A2A44373DF262AE788DEB38E56D91884B0FAEB0" + + "B30EC2C2C8D12CA4BD3AA16902C883ED05103F4E4447F85044BC0F5B765C0C7C9B0C0812C213CDF9" + + "35E29824978975A670BEE28DF185AC1D333D208843DE449C1D7AAD6279FD4409B050FC07DFF458DC" + + "AB304A6AC435530B050769126D32A25315774928A9028DE0DFA2657471BF30F366BDF536BAF08DF1" + + "0438F433716692EB2BAAA42EBBDA4680E1196B9D9B58249473215C03C4725040B35E8B43810AEB65" + + "70248FDDD8139B47A9D1ED7DF29EADA73312B8FCD1E3249637481AA9AB43F36B7146B09889A1867E" + + "6688BBB876F8B8387FE1EC486AD6AAE7FE42F7EE2D7F2E9BF6C57249408ECC05D622B2ADD05786DC" + + "92BB3CD6FF2436C85185AB2C430A55E97A62FA03C191F65EE20C4CB6BD4FEB9238AA582314C4BDE4" + + "AA49FA1A0264BE6DCA9505BA5F7DFB959B9D19E480E4CCFC8E7C49109ED5E84660A69DE1FB18C821" + + "A97A43DF9F4F4C71E993BFB359EBDE364D8D89E21097A3C3041FD0F47D4D7A99351CAED796C5FB00" + + "DDAC93E218B4B7732AE0DACCF884997D4332102B6B301925754715CFCDAB85EE826AF03C28E8F9B8" + + "9A090F56074886718FBD2645698D182C9E03DC9F16DB5E4B01D6D48708A0B0379C6B438788642B36" + + "81A09195C4457D71C40C1D980739C15D4DB8BD5864F0B4A9DD05E30C369289A5D5B39771DDAD2C1B" + + "14672C21E15D7B04F8A5F38DD6FA789CA19E9E8F169F910E0249083EB6DDCD8E1528B6CE2BC8B378" + + "96F1225BF69CC5C2084103093EBB2D34812F80C21E58F115F74DC2B44035BBF52B259AED275D7625" + + "0AE4015FDC4D6707582C6B0BF5F03914D6570445DE13CE5047727E198D2D600AF1C7FE3AC560A939" + + "5F8E513C337A0AAFA2CC3439F6C77E70D21C6697CF3483E86E932C0D799035204858EE4F4D7E7661" + + "854E8FDA26AE172B8EA40C436B44A3BB8B3A0FD2A827128B020FA5367EBC9D29B3EFB9FED612AD3C" + + "55A8F957B5C55345F1C453FEA3F08FF374D63CE139988F1DFA3DFBEED134C4B6C9D21C2867309724" + + "2032052EC27092B244D99DB69368CE0F125B3ED6B57B05C0181B144B254EF32A9B9ABE9DC8A5EFAB" + + "BCAF7920B1376CF92FF0DEE41188520A361A297A5AD4744B0781596F08FB0F39E3515133C6EDE145" + + "18986B3559FD1CA65B055BBCD365ECD4BFE25B807C44A5F8460D113DBC3C001051A63D75F0BC9C27" + + "578FA5C92F43AFA71289CD8D5188A4EC34887E1CCA9219734EB00A63159590339C9BE5A65D3CC7E6" + + "FCBACC895D895321696AFB192B627E3C9540FD6515D52565C2EF3314FF046004BB7CF539D80DB23C" + + "19CEF0FE2441D838709012074A5F6496273F96142483B2203BC068DCC97EFF912F424F324FC2A50B" + + "E0D32B5ACC9D580C01484C7127B266DEEA11CE78AB8A7E98D244B987CAD4B85ADA60C0BEF869E8FF" + + "3DFE7866221C8FE0C4378ECE999BB3D5FEB59F0282FC5BBFCEA31DB572F59FD759AAE1A03E4082D1" + + "DD93BBDA35F8BD3283BFAC12E2F073BE56F9AD1EB7F916B297A371B70DE2361709CCA0294C108327" + + "A0851975079DE7B19EFA627CC1B413243A97B39FD337C69FC91C997F401E1D266EE536309DB2CCC0" + + "A0DA4069C2B1A1D951E4EB79ACD9714D90F17D9EA43D300575E8DBF167F1578C1B21AD890700CA0E" + + "70D57F90414DCF1F986F9E7ACEF750DA623AB9CF8487F069D614396D5005F3BEF16290DDFBF073C7" + + "1AE118A9D2415D9D0CA67808B74BE206EBA37199E62E01DE48265A0119ADC02AE02BAC32AADB1295" + + "FFCFB3856C790B9AC99D52346EE23686A35F77CF5B7F0B5715F1B0109DAF17E97DBA770616B24E3C" + + "DADD30B968FA4C137AE31EF6A7DD07ACF8F9A912E3617305FF54489A8DCA27B7C90AC35BD4201085" + + "39218C324CBDAB0B13E7F03E753F2657D27EF605EE39F1857DF641C7D8F2F9DAA6BC1A6B607079AD" + + "BF03C66664C527B8417DF3EB1C668950FE1B86AF9D22866431DB28A1EDF1E9FD8E44836C8FB1D8A0" + + "99CDD8CF7F1EFAE525C0ADFBBB3342419A1F3FAC42D187C486108A0D92183695627E092198E5B189" + + "BDBC772FC74E05246148CB6F6264B876B9768AA311D5D016C55AB779D238CD93CD73AA114DBD8940" + + "837C2CBD000382DE2BDF63D11CD0C0ABDA429EEA02A9408379EFB4CB4A9F57718BCC2739D75C20EB" + + "D50D36FEFC2646033FC16B1FCB043605C4908EC983EFF74023CEBDDAF83E5F9191B59622A77897DF" + + "8574DD287DBAA1D1ACBFB2AE8FCDB9E8ADE9FAD36CD676E737E257FF98FCD4023643922D61A73755" + + "F7F85A62988D32A45C85CE63C493E26D0488AA21F3A8C38C5B1A1C42E56C3E0C67633983DA32106C" + + "A47115038B80F1BBC12291C7780317313ADA605D804646C676843FC9F0F9536BCE5812B4DC936AB2" + + "180268DE85ACD4BF7E6494EE33709EB4F174781328D63C5B4CD600BCC235619D1AF48D3FE59DD2B0" + + "7AA8155C864C4527363807C3A3DD4ABF766A3F503F8BD24696F90EE21E8EA723", + privateKeyHex: + "4A85E851AD50F93CAD46F6712050807F12C33503971AEC79A1B712C65A546A357C92A89BC258B254" + + "0BC16972B9A495B979D61088AB611178DC6E0AF27493875EC32FAB9BA2C49340F385F6D4F76E0BD9" + + "82816B6EE8B96D7E4BBBB72D756974B2CE91BA9EF3B18FCC00ECB670DCE6B5C1EE527E3A981EB34E" + + "CE803B53A0A7B4220471383203020430328455441317380602602315060857124644737183236010" + + "66102618756311110488775648233144387402066615884225320645745526581610361781142682" + + "88583274788773074230115747435662352417730447424405334466753814304840547385262576" + + "55368276170237165743585213044868722076800333088380543031757216227750201634706474" + + "88578626245476185086014445822131112381306147074872512024581185606875503631578680" + + "12140201800287318708406470373605047413465610758024205324148244744216650024625676" + + "64137612021624370830000387400863405470175680231634575255675232704768284700585716" + + "64624321185633345337417203401422764602017083275262684788645676646506404755740101" + + "58643576153075125481857062310416310600463563658060031438863122670047612527858307" + + "70856225276475801810044406731641020111823568723167538657543066484472753884448276" + + "64367763365465480588634751750250007888348455607330842301601040411212078464545504" + + "18186300436031277258615817872340365077542426530651034774838708367427600817320784" + + "70740307445317577376716334780618266356467603735843380005137255661616412473768012" + + "53443750081063102338455754315763606462248646444343211860510617643671862836223520" + + "65843734166328817807638224351656762156217704075042576566024402248640411363236762" + + "54511287783474304154126052233832407331772776880365217075481334182158636406064038" + + "63248512175452237543637801036002322336751583620706583235162488734087624527748176" + + "15882463037482226050313714246647537302503506582103766762672864468857688774804468" + + "66163446082030671877270466804556425533010013106110643874512633487300536828336555" + + "34685320057784126578483637175548656464123062872141304561571184362851856800175864" + + "18425661643154711218724471828682161753155468557748830277064625573450080522613100" + + "34604216178030705726601236510131337641840503524143147433650253355721884682161866" + + "62253134320878264553754468403260001484271332260502861558164645647266885450013258" + + "42776154037744574220818270818283050784703407734477803807214726570845765654868651" + + "75261883787471534316682833007674041574252545713822787165201570388211152161484848" + + "53845434025712223666345176448814132133822050687200188028173718483151462873652547" + + "42551336217875278233728121618845770445638228313353784450417602675208338447367155" + + "16715668768531436108425874773448804172177077468403555132168735400341334487066726" + + "06467635561704856286470183234885673643673660387445401834178107852733182635171577" + + "03161044634755301611771227120762445242755215441240836547485235001655520232432473" + + "24421844783424361407512357684888163388583466775362462554232434236868727822188605" + + "76572744358443236152725208775024356825332386620586563668317548635575643281322867" + + "61064516045061133082460626117238043141687702783710318375282326541711573030868060" + + "84541048518288416605163745464073032288361540363847114176884120147518867143032356" + + "60782872312806274234764755307800386063161661510061830543544677512462201257701504" + + "7742606275633208083844816820288095949B0898D373ACEA5F61E33D5071122DC00E3F02C9E134" + + "B191A23A8346F81FC7B2A1C4298AAEC91CAAF75004469BEDF9AF77E2458F31DA22D9122F51CD2026" + + "6F50FB4B86FB03E03EAFA6A0FBC5CD4F2E320DBA9B4ACEB03B81C7A19DEC06372156D5B41EF192FD" + + "53231EBC29B211A3A16B269E69164E82698C3C82D5DF78CC8B899901C2ECCB8DA39C4FA1A78A37B5" + + "9F9336BA0F2D720C93C7013016CCA6A833A1F78C6AD04C6E33FD2897222AE5A96F2D6C9A5BEB5523" + + "9ADB8424484B0123307718F5B995F6AC423DE65CD4E34949C3070C4D288ABAF9E631D94A1D3CAE46" + + "D6063263245E4DF11F3B23C6E0DFA7FBEFC036C70DB08F70569C9F0FE015EF1E27F315A5767619BC" + + "3F73AFA122151FDFE103FBDA33D8132FAFB24A1625B02591055211AE6F248577966CFC18BAC98AF6" + + "A71EDCEA0A519E28DF52B2C233E88A5F47A110E79F606784AFE7009E8D279E52F361E28686713196" + + "0561A516FE5101E32C4C26A7AEF666A79A8EF386650F552480819156C45C54C9E0BC67D35BCDFC9D" + + "33D0058132B230130DCC0B016CFF30F9A8F622A1A9476F113621014D63C6BB46A5BB5AF5F2E1648C" + + "5B08902F7EC97E11AF7DEA4DA506741D8762DB599622A48991AFF70976ED0F0394EC05808AB4272E" + + "13D2AE475F75781FBEC5148529458D88ED6436B4870CE38A41DFAD61F6C787C1349555F237AEF13F" + + "7B8CA388BDE40820669125775806C47907279CF3E94ED5A0FB25E0B880CA40BA06E383804D1F8E22" + + "191D70239A2237FF7928EE4F1927CC07F2E8EB09D0E51014ECDCE1F9FC61FE14C314E4F05796D57D" + + "4CEFC3AE58022DF8560B3BB459104C6D583E248E33CB70B432C0B19EC0F953F8BC48BBBA9D96A927" + + "F6B3880B5C0817CF4D7B48ADEBEE930AACB949A46E77910F33B87C16000E731810EC0E33EC9558F3" + + "CA863AAC2D0671B7E77F25724A5DB5F3E92F377D9F3394279EC06D49A8DAA975969BB63C3DA30E18" + + "1F6597BA8B6FB1FBD67B8B685CBA6181C70C0AB066D5275D70FBCB52422F5FF241EAE960A8E93BC4" + + "FE05FC970A7F8C5AD2E1DA52408FC93054AF028720ACC6A5B78D40493AEFB05216315E1783D80F47" + + "85D3D71B7AF4BD75F70A398695D34747F75BE7D053E302F60D589046AAC41841E10CD4E5E5D260A9" + + "C6E326DB2CEE7D560F2D5E58E9E9E63AD65948E9D5052BBEE0148315DA626D25A69B4E17200D828E" + + "3B19AB55C9659810724C2A0BD16A2CB271CBA908E3663A4162BF15481A49375639EA0736C7EBE7ED" + + "66545F6ABC2ACF0AEC6D86DE42842D48E81FC8085DBA0B2476CD91847DB34CB76615283E5351F712" + + "F8270335DF457B2CC5BC32DE97F7426ED1B21C152C767B22C7BB251FFD143005A5AA2562DF89547F" + + "EDDC24C88914DB75DB6041032E64FD55421B3D57E5302609B739C8887E2F58ACF5C4D8551736F57D" + + "1A3EE5F4FD1A869EC4A17A0DEEBD97D8360DE703D9AA3122ECBFB8A0F6FA2D569B6A42254C4D1A55" + + "FE62AA64CADB1C86257D48C0FB3330453E8AE8777F69D43611308B48CCF76759F15962CBCE399ED2" + + "D0C5819A8726A492C5D6007FCBE0F678FAB088AC7DD0BC8495CB65589F07FAAB6EC1FA36862A4DE2" + + "87685D702B36E053D789923D1C7F21BC1468B4E066E48E69D76DEE3073CE3F1001A411112DD443D6" + + "5CB6F3CF20F77891143E9FED51EBC3FDBCA9D344D05A586BD1A9ABB93F9D1FEC273445A0F8DF0A8A" + + "829EB48AB2A26B146A77EE964C91D7904094E6B04D9CE20735CA9B280F2D216F35B90D8A5B8D5056" + + "002C6AF64FA0CBE9B46D297F84373AE2466893D4AEBE5755C96F662BDF790680826162323E8D1BAA" + + "AB2259A126C817A2F0403F537882F6FC2F153CF2450D13812402D3D625875EE0E3E2D810209180A6" + + "703698B97453A5E98D357FD47C71DD0D587D18A3890BD3222FCA0AA04F48498D1DB9B0CE7E21EB17" + + "BFA5D685D04B98FE6AAC9538E58F4A38B0EFB2D845A01C28E57A9F85F0C6279AAE762B15B5985C82" + + "3CBA7B7864D35772FE91514F862B414510C1A9652B9A6F8C1EDF3B067E5B6AF77B0A8D22F2F4C98C" + + "2DB1C069738E8E9FBA2EBA1F4F38875A438B942BDD424DE4B084CBBCD6C4F758BF926AD6DC505BA0" + + "279E61B3249FB65A7C2C1646C5617D0A1FA3857873A7810659F3D7043F72EB45336C9534BB8146B3" + + "DFE2715A7CF82720C8F62411637227AC4513F0928ADF8FB16BDCF6A53E7BC914DD897CC44FC4FC94" + + "9DBDBECBC4CD1E164B6F335CB03E57A04D58D2E783A39B59372575BACD1484C5FF8FF6BB155F9ED4" + + "405D09E665CE0C0F6E7FD482DE1F131C3B54E3BC7D2EF0583E38DD01BB57579783827EEC8CE7F99E" + + "B4FA643012E11BF26CC456B5368A896E58D54AD5E7D0A30804081F53D2E0CBBAA3546AE1F8DCDFA9" + + "FBD0C5478B843805F39E2ADCEDA365975AF83D516E0E607F5EBB711886DEB4450DDEB4E50201E9B5" + + "4E4034591AD976AB754CDBA03B159E9F4A002FEC231E25367EC7D6A46A97F2898EF7EEEADB978BB0" + + "872DEE38A0645922EA02AEA3CF32A31A12AD0254E855685AC16B2FB70DC65D29308062A2CE1EB876" + + "A5FEEFE1EEC48A90A521A559FFFA66861E67FD4FB2E028973DEEE1A9F36D37D98D0AEEA19ACA2205" + + "3E77F25C039158C023068F83C13761344A39EC8DD1FF303770E422A50442EB75509B9425356EB2A7" + + "510BE086AAD53ECF2F5BB5BC5D1D64DD92FE870183F7619B0936807E36988AC4DF8FF57026B0FA53" + + "CB2B661D9EC5A74FB2D8514FEB74446D6B2AB6174C58B81B0DEE208C0B568C3BE8E34940541D4439" + + "089736D50649E8E16F9E6A4D9E0A2DC908E117631A9C996B306FBEB2B1065A72CD97EE24057EA925" + + "14C4E205FA23FF3A78C3FCDDCF97E7BE92D450204F34A1CD9398C2A8F1BFEF989B0DAC75EB41E85D" + + "053290DFBF07F71BE84E6E3149F724751168D97F28AD04EE0DA39F91458EE3A93A702EF8A8DAF38B" + + "291CA63AE0C89988BE7730477A029479E38F06E2F8AC698BB4739E44E9EC1FC0AD82AFA72343DA13" + + "784FC30C08044EB2E26314E75B5270E709744AE1DDB22F42310BEAC7E17479ACA7717FE38626FFE0" + + "1D947BF5C07CE61ACC760BA8E6D2BCE2063A67CDA928BBE88608D14DABB890CE6D537AA32464F33D" + + "B3AA062FC0AF0A360B91CE28C963809ADD73280081F0C6E80CCC4B6482EC0E7201FA895F82765572" + + "2E4BD8600488096B7DF75F59D899BC62FC02526A3CF1AD3402E55A1C96F0718CA0486B8B5CBCE55D" + + "4473D504CA092C4FA6B13E8E68A549AF36E37BDD3E76DA1C932B7D13285541FCC5155F0E10F57DA8" + + "2755962E446991620783D0E4CBBA5735C2D884895C46164A031FC604D1075B99C7D12F45BFB92700" + + "B046387468C3E142990154C50B80055F4A9E0E55B7CA894D81167B481795FBC25B2ACE80A55B3667" + + "0C80029CB5B0E8BC5C16F5C5C1B589D99FAB3C7EE854BF554ECA476558597C9F9742C50BE09F06D4" + + "A4A2B892C1C3945BDCD8511A721365703019CC679962A4C2F31406087AAD31B8", + muHex: + "9CD233A4D7F964EBD5CECD58DD785F3FE139C0C6CA8A7B26A1F4F6D6F6E6690798054D3BC48F5D10" + + "A8A3F03923FF41AE5A9046D25F4CA2EA0EF83435090C8FC5", + signatureHex: + "4037F2B465C1F054B6F9E62051F68F12DCD34093671111C8BB697A14B328F8FB6266478A2FD7FAE5" + + "89768896F9751A9D08EB14066A676AC353824BD53B2997DBDEF823D7C53E81FB561AE202EBBC87CE" + + "29C216D15D8F5EC49256FE4512831035E76C965431343B46D835B4DF2F43F1558BF09B84C1E572DF" + + "6FAE7F8BFADD236A1560E47A53E7A6CE32A0C96C269767182DB73F6A042E70253C2169BED2F5FE50" + + "7EAFCA21FD1D8765E3D8B381B77DCBD499D937DFE29B553A56C203D6C40E798689C1F4AAB753763E" + + "017B1EE358CEE1D695040B994FFA5D5D91215FC827920180E9C89D3ED85716F29EA6635DA9613CD9" + + "F71519660C2BEBF812F4A4F7D9F831FB0EBCA0177413870166251DC8AE65CA54E85546727CD9B8C4" + + "DBADABC966F2C027BC496048DE3C5EDB04C36E68CB3B336B803A083B52082C67185ED2B2C4068E83" + + "48C6883D8455939C7962FC23A212631C787231DBF2929186D22034FA05736B1A015417958CE2ED6C" + + "AE5AFF892E1E702A7153D97D84B902F9045B530211F99BA73ED9E75AF8EDAE8473FB011093B8690E" + + "B2B02E25AC56FBF3E850FB0AD3450B3C957360E31BAD4F93D0931BD0BA52DE3A4AE792B376D907DA" + + "233811B4AA28FD11B76F68515120BD8A330091A15457CB2E2A22CE0FBCAD8D7863596FD7F5574D4A" + + "03F7B4357C7E62D3757B1533C7952535D10A2EB7B86EE56A51996DBB9360E883B5BBEAC7093047F2" + + "2356F99E5E28301F2A6FCBA8C150E3A82EE122C0E92B1475153E92166C081C8FAA5F0A4B57D7657F" + + "47940C1DABD9DE1CAAAE9431619AFCA706FDB5DC45A42F5FBE72A07C7160ED76225E80E86DE2D156" + + "E2755BF14C96478E6A84071C48646072A8688D08837922CF2EEBC15A93F74E9A0C7F68C55761DAFB" + + "5A55BD5895770702842C389957CE45D2F1B16F87C77843A36C427F227F862D26FEBBA0A4C5EE7BD3" + + "4A5646CA571F25EC039B68AA1F6BF4E8BC90361FF8075C23652CBE6130635EF40C37E29BBFF8ECA0" + + "D061B564D7D36FFF0E78A3ED7FA3A781CDFB338FA242570DAB5DB8CDFAECC5C8DBFB96E0F8B8C935" + + "F3FF3633BD2587776F2E9437ED42CD539621FE96EC74E9BD0F5D087AE28D0D6F1796364E8E43C489" + + "6E79CB751033F35D535C8EBD441B2EE785E13E6A87FF9CCA720F2AFDE131FDFD645E10E15D3E0B00" + + "E6C759FB07048AFFDF8749C80A63445978CB2539F63E076A55C3FC132830F4D8092ECEC4FD687C68" + + "AE3C9559E92FB23FC38F3DBF88312C45AEF4E3957EC58409FCD771EFBA2AFCC004C4004B1648BB02" + + "969D056D72ED0232E63C095422EEDCFC8B023B1AC822C5A65C3DA6E16AD7DA8F17E7454F16A2E62F" + + "69894B17FE0CA50E2EA3D87075332AA9F388372855648BA462414333906E7489141598C276D8AE8C" + + "CC0D03DAD2538E2AB3F9F5A031051CD265AD668CE491951826E0DB1A3F436A8CF6D04877C4CD5B95" + + "2BF32C3055F4BB6000CE38050DB9444A6F8181A95BC60DD347B3F5BFEB0E40BDE3C24FE924B43F15" + + "82A7409CC350D29C327536B1E1DFEE9F594C59F863EEAE06E5D9FCB47A7E0E74778DAF49C9F082EC" + + "8C33D7E7DDD98ECB98D514B84750C5127DD15DEBB9B1EC77FD9A5219A74AC3F99D7816083F3A7522" + + "1329EAAAF9EF82A8F73B37967B9A7C16389A3923B572EA664E0E9A13AC49C1D4BE59ACCFEB143F92" + + "9BC89160EDF266D62582CB90C4D9808BCDA109C3F56BF39D674D0B60FB24D2D1F8743413663701B8" + + "EBE4A393230616FE63166BC235CF1400E502FE97D58379923E788B1E57BB2DA761824F7D60E5AADC" + + "BAB08C96A8D4A3577A8F8AD0A1EFD4A7AB4DF6983E3D775D2E3BD5FA437E526435B7DCF18DC576FA" + + "5AF0321BB8CDE8928C34000F2042D321ED9899A157EE17FCF0966ECB296EC1F992EB628315E57160" + + "E7D618B5FF0CA2D3EA54CFFB084702E5C916EC84C3EEC840486F99BB006F77FD17C788C6074351BA" + + "25904845E3AFCF98CD11F436BC35F1E42E0159F8307D6712F157E0F5CA075B2CD964452A86269D78" + + "59FF7BA474225E1DAA8916D3E5FA9B439D4933E154E1572FFF82346A33AD68B6365846C22D0DE2CD" + + "DC112AB64357C8F2885A40713EDFD9E3B254C500E20FAB362BEE4AFFDC4D04EEE86D58FFEA4BAC00" + + "3AF89B65AADE11947971C818B4B2C7B955C56505A03CC75E28A4BDECFC6BFA612E0030E0FB1B5827" + + "DB9767B8E4714422B6A4F0F325BD79C3A1B874B92E1C7F084AE9C8C62C761C1D4041AD576915763F" + + "D84F64A6B5E26B8C1DED34C6C88497BCF06B4382FAD6C5916B0933C1D4E167944F54AAD5174C81BD" + + "21992AD27E61621D75D40591C9181B540ECA6EF996623B3D5BD4E1D071F8DC8053DA76608CD47592" + + "771507B0D146083D84A3031A7EECBCE3ADF528B27BB7FF2620E6A8C2BA0174B906BCC4E86B4C324C" + + "65478316F636D866BD36B389778287D91ED564DFF1FFEAB2B56E9E3D1872A73DEB9F9D0AFC5D31BC" + + "868A50C5058A183BDB443AE68E371B50D007753B5E2A255EA7C01F1D84BC21B32F33615B85958FDA" + + "346F1C614F070C10C5675AD12D4E33F42A20F0FAAE1D0E962C32D00FBF13383A0EEBED406A5CDA84" + + "D03FB51C036224C2FB412BF99083CB8A7E326E2A097A0C3189A9EF9008F8955E6B198BC6CEFADDBA" + + "AF1526C7579487D929537B55BD21005DE05FB1F5C1825044B99658D0BD16F820BD4AA677D74716BC" + + "78299548ACD21FBCBBAE26941206793A089B430601B26190EEC345FF982E8F71387288E8C6F1D494" + + "A07F3C49C59D98340A3C49760565AB2C64B8197D81773A7F142526F67ACD301C1052416614D04AB3" + + "0AA9B18F572763143474301E2E9F0A206D3355B0C31D5254368B60B1AACC8B71154D496792BFE8E6" + + "7FC6F48B043DA2A4AD8BB5F9DC2FA281CDBC5BE65B1D8D3F14F56CDA812A0DFFE2DD4F8CD9B7FADD" + + "38EDD2A2D8672E15CD2FF53A11EA189D49A29E05DB00423C9C0B8CE05663A96B094BD84E51E429FD" + + "BE0BF2997B6C0D573CD9459935F2BC408FEB8C825B395699B4D0B87EDF2813469A352CECDA0F6086" + + "578520E8A3A63A91F8B3BFCAFB50AED228FFA895DE6624DA327F3B31024041FA8A2DB1F8CE0A4727" + + "42D1CD02D915E8D4613677053B966C24D86208D242B2292896861AF3D0E3D32742280E9F51B93B84" + + "572442CD9F5D70B133FE8D5458A8D4A897F063C88C43BF6B38DDB702F0B75CDBCCCC5A39532485C2" + + "A1C26E28EEC181359CFC9CB702A185FAAFDE7C6F9D2EFFDA3681FF429F0B42786025C33020F3F57C" + + "C840CBA5E6ED47DD4D5A0CDEE5283968900459604AAE38331D9A5D610464E2C8483C179756EC8E4A" + + "E592D7952E110799BABCA701B4DEB9D4CF74E9E901F01249751329D81A497409057C0A958D48798A" + + "07180E55E2EB4DF30198DDF30EF1CBAD219D7A624E311B8C062F5F1DE08F53DA1EE7C223581A25A1" + + "911F36ABA68CB63B275BE05BD6677BC238AB9CC04790E5618102B3B1AFA1CEC926D8BAA4A7257A3B" + + "3A648FA5B370E216CCB67C6540C60C85FC2E128C78AE05E0C3229F7C684809050998C67928D52728" + + "42F7BE54F9E265735BFCD165148D02AD6EB83FF2C9B04D6BBFF7807967601398826B397B970E726C" + + "67DB0754CE710E2A15A253A72F624F2446184202C4B1EC125C1CC860E8529F90DE8A44E50EBEE268" + + "398A799701689790338323CFACBF8D34772CCCA9710EA77673CE370C447CFAA6D3A575782F659119" + + "A5B3AE21373765915128A344093968AB723A8EF1D340186AC899A5406032B1F2E8439478F296A96C" + + "5F7006C7657FA051A33BA138ECF9B4FA2D253E8FBC803C8D557FFDA87A65BA0F07DB33EFEBCD8DC0" + + "8219704565BF755133323665A0B860FEF8E03788777102DD3AEA57D38C860885365BDEA7AED679AA" + + "996FF7BDBF48DF2B9CABDC63B0AE6B38389C73F3A955AD249AEF837028D5C9A9D8350107BDB1BD5B" + + "F3D4729E236999B65C41A73714ECEB85851815536FA05D708E139C3B191EFAE2459659B1D5F461FF" + + "C5328A5E43902D2B7007009CF14B03061C964A0E3860B08E04890F12C4C434A7072115AE984C417D" + + "D84FA6A1E60EA391EBA2400323DC690A79B2DBCEB4324D00954A4CC8CC51893596105D7FBBD23D88" + + "C38DF1957C483319A341D6D97AC465DCB938E9FF98C9F004D7BC182A2D1F77D31AA8491234025A81" + + "089A29F2072C86D1DCED04BD2C1FABFF76AEA97D46B93E77CC7ADC6A10C7385DDB638A9AD314D8F2" + + "4423679F922CBA31ACFEBD52E945CB962285A67B9F3EDE92169A14B4E6EE658E1FCAD1E55E4BACA2" + + "5A04A8EA83E5D07D83118C5AF202D8878077CAA3CB7A4D00A3BBA8CFD533BF7D1400D2835AE1DC98" + + "B18ED4B4890AB102B9809965D06435F8E64BDB64E9968B5F9668106A22EACE191ABF6301B4026E13" + + "1DD46424CC4933346E3CF810157368BA6A601ECAE9BE377F5F201FC799BC8C231A616C3BAB36386E" + + "4A4E73931390DEC263BB1042C98DD921B07D8537489832A12B489B37836D12CD2FA72226F1ACC3D5" + + "8E83E843508F15B22F9319BF88CB4FBC89D63B69C1868AAD25F72883F6995BEB5714E38E9803F35D" + + "B876F4CB3F4E4D4F55B0B2CBFF006271C9DAE5F4041E3EA0A3A9BCE2F8083E6D84B41F34536F829F" + + "A9AA000000000000000000000000000000000000000000050C10151A22"), + + new MLDsaNistTestCase( + nistTestCaseId: 151, + MLDsaAlgorithm.MLDsa87, + shouldPass: false, + publicKeyHex: + "5AC3F7DEE913B265880ECF0D501EDC123B53A5ED6C1480A1A194A00EEC916127219F0C8C41C1D6FA" + + "B813938134BA9A817D2A68250CE4D2E02CA704E673B211F57CF7AC426A0F9C59CAD1F3C9E262172B" + + "AEFF9D9B75C8943C42E7F47B52898695EBB8D47832DB1D345AB6A66EAA1C34442CC77E33887FA11A" + + "551AE46A3EC2E8B31D349C3D7EE8C7C0B3F33770FB474C8FECB9FFC731DB79A0C71DE557D47BF5AD" + + "8E4718368813275C1F1FC3FE92CBDD5AF811DDFBE45A62E9406D763FBE47483F7DCC8FC026332D4A" + + "870B1AD910F8B9E80162217D3E5E06A8887AED248753CB79B177309D512B08ECEB0E8CF6C3B96500" + + "C0C2827FA44D3B78F4376B1F0F54963A60A1869D4008A9F7221FD63E6EA4EF1B002963623A4B7AA6" + + "DE321402A8BE333E4DB4E79B0EB5CBE6B20F7B3623ED69C86B817716DEA226502A8D5D6CEFEC4168" + + "2B7B537FD08E8321C906F7D14D0B909E29A3CAE065605C55D92B953E132714449B9C5A0DAA0AE575" + + "00AB5CF03C10CD02F6898C1875CF86929ADE3752AB676F0799642B22B391E91854E38FE6B191492F" + + "09E12C1A936E5BD2FF126ACFE68723F550ECD14BDBD490AAB0ECFB08B5E8F2818B770F70E03E00E6" + + "3AE6104FF14A2504C940EC7B4DD09A88F91AD1D32E6D0532F0877E978EDBB7FBEF7D220AB57EF280" + + "A60E8306667C00924184BFE99DAFCC51E671DA2A88157B43AD96422A6FFF8B8C7F8BCECCA8016CAE" + + "11A84EE081386DE306AA0ED96D49690BE6A163BAFFC570F6413A6CE4CA5DD28C513705A46A317B25" + + "5DB3FFC8DFEC180F995E10993CEF68BE36848C139E194985772E43D8B091E5C35188D4885227FE57" + + "8CA07E8742E2408DC689A091EFC12DD06026FE336E6F37A84A98EFDC1CE553A0197E9D21A64B60C6" + + "176B20FDE19C9AA09FB96E1354766ACEF61BBB81E1749F96E5CDB4EB1A9AA0C9EA7011A563BF7F23" + + "F7E7423AE0A34A931571812DCB3FEFE47F8C63B9D0EDE8DD1947BDE82F4233A78CD7DF14BEE0834B" + + "A17064B64E3EFC0F832A1B4383A45B2659913727D1C769251BBDD7FF3D0FC1907E326C12B0F9A589" + + "4ACF4AD0E2DC3AAC1CF277384622EB6C4CFC6451FAF348BD315E5DF27F5FC9FCA6188E11276CCDF3" + + "F7939FD806EC8FBF73C6491B4410A35A55761482FEE924BFEC705C4D6E6FE5D3DFB71E737661AF36" + + "0F1250C83CE3C08606ED4D99AAD854B1C2C828BC150A682F2F7B49E7B12DF61969A3DC0B2134B016" + + "09346C7C45AAE2997E4D6E66276DB19B8A0648B42F9805AF8D3853DEA4885FEBB945D82079644AFC" + + "73D264BBDBF11AA2B138C00CFD1BEE41BDBE9FD77D893D3A131EFC8A7F72592170D7B5A5B6263B12" + + "850F3C43E1DE88378FED3E4D420FB7032D0118D45D099EDFB6D34B2B7F98BDC4C075CF8701FB1FA1" + + "B3D7CF383F63A3873B238C756FFE9F8AC4CF18CEA8030C1A8CF3F82B7BA53DBFA047A4E8A80AA77B" + + "5D46C81327549580B3E77F0E5B0D23C3F3B5DB875A0418D292BB151020973C9DC725E21C4436076F" + + "55AB8B3800DB4745231A58E1C2483E0BAB8A133C5F3D37404F2D0DC423CF361529008E71922AE0B1" + + "501ABE25BCC8B5A30F4DD666E324BBFF32ABF2001562B37C67E36087E12D8447CCD7D241999979E9" + + "192ADDA6DCED5EF5A0E6A06278C1B2FBAC1E4AF23AB9B663BEE2C167D4FC5BEE3535B44FF4D1AFD8" + + "E76940B0343A0EC540E60814238AD0219743FD04EC35FEC5F88CFDA0A732D82187CDE36228FE9C52" + + "F4174B32EEFD0557D0BCF85BD73EFCCC655DE08C850E248C60536D9B120052BD88F174352C11AD19" + + "B066111BA79A98281619C9C374E21AB58498E83DE33A0680F07947C19EBA323EB17E68386CD44BDA" + + "A142E3783FBAFAB1FDEA65257B8C63424F8F5FAABB077EFC85934C3C39F535E35262969AEA5682C7" + + "C0E9CF60CE57212D7A33EC07CC4B42157630D43B1927CA347FC2CD5867B3F903D70052F8A2268F46" + + "C0151D67B13D537B17F6D026843A0F2AAEC6C5B961C5B839CBEAE5EB90B2A0C09F6F329B3FE06904" + + "3DA00925312324D4BE0F914E6726E0CBA2D18FEC037D073C70F3A9DB7FA11A1CDE552470F6D015CA" + + "7C168C96BAD5588D93FDA08F0A5DFD6CE39BE7890199D11E1565ABC53A1FCEF21C381725662BCD9D" + + "A5F2354B93B735FF86C253B2890C750EE0CF1FC58B8A7FCFDF0B2A89401A34C8381577B63B2F35D8" + + "F83486FD9BBD82753EB63E9D6ED876977A7183B08FA103408D5C227FFC26C8C34CD96A8A88A15E2B" + + "E026555E5D5EABB5386DC4F615D320907972F89C1080F4EB3ABCF1D6847AEA306C0FA26739A7CB0B" + + "4224A24490655E3B9EE95C1FCF813EE49B9E27EC6A4443FDEEE748775C7EB1CBB60AE48119F0754E" + + "80E8D4BAA38EDFD1B325F486D5A3339BFD0A42955576BB4A81925CC2F8E1E39FD9F1FC6200405DC4" + + "6F75B4C5EE844E1290CBC57AF6851F9402A9BA5D2D7BF1AD34A1C2C89D99D3019DA01CD953D17F0E" + + "2DEF01B108E9256983EBBE0804C1B66396CD88481F48D60FBB61B02B4A8F101FAC4870672872CFAC" + + "7BF250C0C6881A6002F135A85FBF53F7FECF57CB6F88E736212043D771521AC811BF5B3950994D0C" + + "8685CB08DABE2488EDBCF6EA52EA48F2759B7264CC49F55E8A99B3E63894C6084DDDC91D50BE4771" + + "48ED94052371DD0D8271EEBFF94D61981E6A53CBD6C437B9663E7CFFA9B1EEAD6079A2350AB26242" + + "E4AC1C5F62CFDAC159A0ADA60BBE87CF691C396CEA991A9EA7EE83CE908F77BF33B8C3AC887A6A2E" + + "898DE6EF43F714C803DCD4F99C5D97BFABBBC855261FFD5E902143869F86EA407A89D117DF2AB5DE" + + "F98940B0B136F918728FF7EA3B8AB69F63D719F049C737F63E344A4F73E5C281AF92DAC04FBC80A7" + + "E7B794DBD8AA5D398C0825EFD383B022C3234C02B35529930CADDD18B01B5FE88956AFF68BE8B709" + + "62F75254745D13B108E7846213392981AEF5307C867380167BA62FB25ABF685F12D59280AC8171B7" + + "80E4CB50833CB8402769336312F21CD0FB1B4FAC7A752231AFC981DB49D8EC1185D599F19F4B353C" + + "F42686EA2AC94F984AD035ECB9DF877BBEAB5D2C65BBD1F3C1C6D62F111574306973049C648FEBC6" + + "FBCFE7DE73D417E4F23D369E9E7F5734933D977A42CA9F66CEB09EBD0F89EE6B5E56AABAB2814F47" + + "2522854D8A4E82204E5853ADEC0E7A636255A9046375E5765E35645A5B2F83540EA2515A5C9F662C" + + "894C789CBA35A2A353CDB780A9B7FC5B75D39023C5B7122445572D10DF9B9D96A2B47DD57AAC2740" + + "B79BAC24372B8D6ED83799FA907C3285D2E54B968689A5D4AA0E4F8EEC06FB1A28DAAB8163288752" + + "8125F49279A16EB313EF18E99A7DC42926873E3FB4C8E284DD586E9E73364C38A957AF4CDA54E0F9" + + "ACFBAC8080D560AD9DD725DCBE1C67BC664CB075F17F191FB351C2D5D90340E31DD1D1C3B9631F57" + + "B01F3D8CCB90B646DF66C7B9ACEDAA03A067F2E461F82A86F53BF339D80009934C64AFEF784361E2" + + "B134DEB14CDFF932CDC68F7A565A2FFF57C1809E004FF18EAA561F180A7C44D644659B53F0853303" + + "E14A9AB7BA221DFA48DA475C020FF78786F46AF20BEB72CD27C5EAFEC3706A0721CEF50E50E835D8" + + "0FBE3C9B1089BAAB58CDFC61A070C96E5EC9FD817C2D0CCD81CDB5F416A72FFD", + privateKeyHex: + "5AC3F7DEE913B265880ECF0D501EDC123B53A5ED6C1480A1A194A00EEC916127369FEEDACDC4A3D8" + + "D263C00A6FD5C613C9A9D233B7A086BB07BE4397B76BC9D517565D781B2512E0AD21CFDBBBBEE73D" + + "DF69294BB4AB1A6FFD311B133BFA27DF8B8167E5762088062ED776900F7561FA81D0775BD0F63648" + + "6C8E2DC42E805524D8B485C434019A00520B062D533046D294845AB02020110611376C2322648038" + + "4948148563182DA4404DE4342C20234CD840048B9040C3862504C34C249264E4B27008354D221089" + + "89464409A78551220048B06981380E19228C24C2250BB7801B103209B99118342A1015242144289B" + + "26210B00019A223150C420119660D0086E0C8691C916881A342CA2820DE3C2881C2700DC20261323" + + "401C368293164AD8821099982C1A8180DCC670A234601B060E12234C91148D1B1581D1C24561420C" + + "409860C08481443822CBB47091460501C061419269D1105152C8209912458BC468E4428498445183" + + "A884611284D2106D43C251002648242001E42465A2448293864522956C60466658B4901CC0691499" + + "60E4B840D9C0404846261A432A080068118740404401DA16024BB44D11040E040984E43091403668" + + "8408604194014AB84D993471E3342604B64DA1060E09398964828C20918C88A008A1044CC01202A3" + + "068D0186901B922982345150026A619871D012488B1810A2B4415C28055434501B966463322DA300" + + "49CC864CE224814888699C304421280AD4324902156C919469593444002708033191D1B40DCB8444" + + "DC900024B34D52386CC8A020002362E0B648129768A4C4440BA265D434821C212263B60D1BA191E1" + + "1244841822C430054484310C076C53B42142C66DD94845D1A4511CA42442906C0010208C226AE414" + + "11621491E3468852882518A18418192421942CE4406989822CCA2605A2326A43C08CA4006A822851" + + "8026258B9891C4C00C14310E23376A04C90093A831A38228CB0230C4924592B4451C322C1138609C" + + "28890397302385512232722424081428219A280558202A23044C4BA4641C084ED0946D10B6809824" + + "2A1831641A482D93A48923202214220D2442498BC8240248704BA6040B14615C0832011946618650" + + "CB40280192044B362C5A3445623022D4880D59A80C40306E230181213608E2C08CE32825A12208C1" + + "004E418030423411CA346C99422E1A112A2119684332224C344D42308C44388ACA347294A66C2086" + + "91DB02110A38856112418B384EE29285C93681C9840C5B448019A6301B8911024322A34831940244" + + "12414C52142EDC02099C920CD1085193004E52C450D122520A082CD2402D1C870502430C04C68844" + + "C484213088E18290042660244308884486A232125000850BC71024072D4B140D18A16101270EE130" + + "81C2047001292C21A284D8401143286949A6248B242002128CCCC04994068A9C3410C01685C3C840" + + "98060562A8900C866D82306803B8109A268D098484C2B28C01386218B70C20042E8198209CA02C4A" + + "00010AA30914908418088CC482450B1146002600D09609D8448A1B196CA3422242B461C2264411A5" + + "904B1886214251A1164EA49045218745D0A0694B1885A4A665C9082A1085251B2266D2100592102D" + + "0A284E0020016202044B006009B16C13A6692006664410858B040D8A22626108040BA185238445A0" + + "B80912B864A2C6489CC88503254693023161460D9AA090003472C1042524A42502376EE016602048" + + "4A9398059A3210A3C4700C3649D1C090239585533609C1006961906014338004234062A68C432630" + + "0A176D4A300D50C8611987050290900044709C128C88022DC8204658244E90362A1119510431208C" + + "C24C04214818258DDA388C62460120256664402111370408430C14328E13B00411354D12C4911A38" + + "6A91846413852C643666422028A2060C1BA82052846D59A29160044AD0A0484CA8504330881A148E" + + "19B429C1200D9A122A8446889C486C0BA329D2046C5A383182326212B1245C344DCA200DC82448C0" + + "8891219449848245122565180330CAB82D8A4668DB4248D0B28810B84009A7252439519B460E1B23" + + "8219204A222132CA164901C664CB003219471112956D4B3805D4A4401A0182A1408E9A388054B40D" + + "1BA085C246825B20811813318B8425DC368C02018AA0A4849C2609219501190906994010D142889C" + + "A04920414A2104702F18F0E551CF294C73A7C4222C9373A4A1205254394ECE7DE6139D8541CDB022" + + "1F16A1FA672E9389130CC31C3158218CFAFA660D1D64A067987C4236CF51061961EDE82862E55DE2" + + "95FA9BF11D66ECBD49C741258DE18F90AB67BC69E2FB35C599C7E354A56A546D3226E68B972C8394" + + "FCE2417A3D4700CC25280E0ED55B8CAB965A9A2B006FD6BCCADE37329F88EAFB00844E6577A52F34" + + "70A9B63E3920C4745AA5751EDD52FCC61EBD3603E5783C5F3DC846848C8AB32AE2CDA301B3B82B5B" + + "B5922F71BA8A9B49E9E22784E701EDD91E9B662388BAFAF59421C07F2C83C50AA1E2B3B99B255540" + + "D6578B94926B92BBC8F7FEE43AFB7755D51EC34C99AC54D17724EA1FEF3618C5FA91E9FB04022671" + + "C5376AACC2761CACA5C55BF00630ADAE993FCB80BE70432C6324B03FE3190D9C042CC79CA7BA1CE8" + + "118EE9D528C149AEF67E0D3B2F921A904FD667BD32450A15E96F8320AFA73A869534587419121BAD" + + "5391DE9F557093FC97573D6AC0B33E8A1D99E0A9F124CC43AAD4E06D1A8A7301CE568E9708B803F2" + + "806B9EA4AA3E8CF5803AB4A5BF7E9E751E6691213499D966E2BF23032F9E797DAF7F39E4DBDE6E05" + + "58E6C311CA520B6A3E78831B9E2978BB9055DF988559CA820B0EB4DA01B51110D2D50ED9561202F5" + + "A0D544CCB748362C23FD5EC997AF696CCEC1F8A55833AC92AD50E4434EB2534785B8319B2D92F55A" + + "1E46486352DDF3C28679AF00EC867A7E62912BEE876AA7A12213F9918B86B1820C10B6F015920DDF" + + "AB81947A374F878E67048E69574987B53ACD18DB2048502F6A2A8601BF44804ED6EF56C3BAD856B7" + + "06D5608D65F69DF89B64B9E08F7E245805F504434BA1B55CE925BD13C8B0282D36B603F9B15D5C58" + + "8CFCFFD1609FC203373B266EA598B13D43DB63C4519A1C919452F99424D8FB7ECE593F5C19F73D46" + + "E380B3FEC26F7D736772EADF53BE43839D20CBB5FDAF51927FF5A3EA218EF97473BA552A051A5119" + + "A638931497630097DA6AFB9866E47CEF8F161D80C77688F30166F452DA77C388E2253C3E2F794D06" + + "1935BC05206B93048E5ADA33BB278990A202F02DCC5915333335A3A9B2BC0FE8586E7529942CB1E7" + + "6636F89FAA18DF3B7CAB233B34C8A2FF4268C63A26DD5F4D2FD2CD0B2813FC117267E19CF61650F1" + + "AA37A360D3649EB60056F5058FB4842F970F995AA5FEF0D645C9F78030248268115B2BDFF02D6FED" + + "C9E1E06A9B3D9DCB11E02F2BA8369CE4DB38B95406926A9CE8D66B1B5E728AAD02187A84076DF111" + + "996F79F312A0524F6BD89A98FE1C92ABC217FF16A4BD75EE122D33D407BD532A49D12FD789112A60" + + "427BA9274E2867EF3A31EEB16895BE046B9322D13458A3A195DD485AA3C1BEBD04811D8E70162BF5" + + "976F2CFE630BC16FE64BBB0A83E987D5391C46D1F9B21C7A04617E96774232F962A367C3A58C01E8" + + "2971207EAE379505654D0B9B5EB12837D823102629F543DC9963B0E568BFBA9A018A3E6541A6E14A" + + "F244CE06DB78A3D182070D8E082E89EB15EDCF6C097203B26A3E64EA4F91E3C1989D047E7D66267A" + + "0FF12E945D30600FE15968E1F9D814E664E789C234AE670907350EBD81EA7E9B815160D281B219BB" + + "745A76595DEE7CCD66CD178355419E73E6378AAE3BF96CDE3FFFF1AD378E8DE426D23C0AE26957A0" + + "B983515F11DFC3D99ADF77E75E2BF2D10D0A7EDAD4996BFC4DE71815384ADCC83732BED088C286FC" + + "315861BA250F638A6CC2351488DA3EF8BDD6ACB2D6E659536B05C1711149C922393453740B444124" + + "11AFEE2687CF066DA9ECB6F769FFC6BACD20F128357E23843B95BCA1C89DE058E0D29874E7E18E64" + + "010F6302D0EDDFBABBC263F63DABF3605C3C353298773FFA15D3D2E61E5A24F18DB67486481D3DB1" + + "7161B2819CDA29C5C60BA2745DC30E52E6D4D8BAAEBD88DD9F3CA54DDF8F43AC6A5C1652C69441AE" + + "0309B09FC008BCB7F3AC8A0D553DDAAD601789504F87B484265EBAA0BC3061C16272907DBB48F49B" + + "63965AC6C403D9B4DA3EB329CBADEFD63DA52FF9D06C230836EFD57260E07AA04507E0C86E6BD6EE" + + "2744AA41FC3701A6E9CA0A32619BBEBCD0CCBFF46C9CE0098268A73D5D036DA0B79EF9CFEE8270A5" + + "DD0622BB7F642DA8C14FCDCD4B6433DE7755C87B713EC2E088D7BD4C82194B2C60723C5BD97A387F" + + "815176C65D659B08A8163631C3D1C31461B406700FF5FC38F1CCFAE38226255D84CD49ECCA584ABD" + + "F5BDFBD53A80233D7ECBE8FB669A016B02FCECD6D21DEDBC1D3C19DACE8AC59C0F8B7F079AEE81D3" + + "491E80A8D8C6693EA63628457543510412501AD6124637E58ABC653F78F00376E4433C83F2E955D0" + + "6827D4491BBC6D3CC7F4B3CC67A9248E27FEDAC46FE6A398B463F3D99B05897414ECD96E74726E2C" + + "265A0BB881B7F77BEA7CB827334370BC9E7AE19C150910567748CF2BB3122152355A2651E35850E3" + + "1FEA3FAE5D1DCBAABE45AD64CDF6721F738EBB15E226AC7F3377AD8F0003A1B247D70FAFE670F952" + + "41775C7FCACCCCF4299FEC6D50B9D6C69CDF3914ED748DF9961EEBB3ACDB0B8A4C0C04D5DB048E35" + + "7C8C7D5A6CFC44ED2CAA47F30784DB774337873C256B667FC34A9D3948785ECEBAE755D946419991" + + "6C32271D8FDE3E1E7EB5358B84274A61A69D4395C54078B6D057C5F9777B6F2CB4ABAB31E7472549" + + "B0EF4ED5BF6059633881ADDB4A2EB15B0DA3428426BC2D8F3F0FE644C5ED7841EC2E98067A368A79" + + "A67E2558EC68507F244239903E3A14793B2F0199A28A9CA92644DFC2AA410CC9A08AB898B6C0AE30" + + "71F05933F17E1CA17E45DEC9CC7DB5AF5CE513E748C09E44A141E4F44520E5A8F5A8B036157550FA" + + "E9D56B0C6D2D0BA7EF288EB3F48C7E1F24F7C7104D9E47F915492D9AFE7BD589CB6E247D62E2D1DA" + + "AD8A73AFF0FF5E278768D9B7B23A949AAD174A4F45FC39AEB1B12FF4E035918C8FAEE0CE6619F8A1" + + "2B2E984194F85CFC00137BC9398005BD1D295C803CE58FA11290E1F177438272990E4182AE6632F1" + + "50C9C42597B45CBA0CEAC12BA7790168F70B699E829DF746DD2656C096A01CE85794DB8FEDDCE3BB" + + "2616D56D38087C0ACAF44A956CDDCDCA74017E595D9985D9DC8E43137ED1A31995E40E8E9515BD41" + + "FE67F86B1927FBA63EB0EE5ADD814FBDC68D4BECE109A75467B1696249787CF5CEC5E31DA66F375B" + + "A061BB036FA5C21CFBA9AF545267EE167F5BF78FA1B8B9200B7CF8A5C730DE47613D7E452C00D528" + + "02D2D8873941B994EAF990BE1FB041B0B8AFEB9B948A1BFF684251BB89F32297BEDD9137D754D852" + + "55EFED818B2E0A9DCE2D8A74240FD0F094DF22E4978F72BD5660AE404AF584D3E35A654191C8855D" + + "687E0A8DD63FB3D0E5A3E57886970837B009B2D8D7542009A211282D0D3680F22D2DB9366C16364D" + + "CBCD7D643989DD073882B35DA672BAD68E1CB3F6FD96EAEE6D17D8CD65E6C1B7F21D1350836ED3C0" + + "2B71E5C4B07C0DC9FF916504699446B8C2AF22E9280162F6650541EC8BB5E645B938019BF57C26C7" + + "2ED5091710DF64F796EF053680A283081BC51E06E7F73E468DD50E190314D495A696EA9E7E698253" + + "D30CC7305A790876A86F253749316030DD0D26A934D10E8F170F57B6C6FBC2953C8296A27A3A5DDE" + + "3F1EAAA86230EAEB5F6D46E54976140AD4AC7369FE49E3C84B2694C2D4D8D0B4C27B429C23D45951" + + "9A089FB0049E8BDB66D6E13B430458546932155AAFA9333BC08BA92CC5C533F29B6928D2653C30DE" + + "CC91F5782F213EAE938E2FFA4A9E3C5EFACF0E328EE840B660C10C701903B04B23919D021F236E16" + + "F62ED4623035DEEBDD6828605B769FBFFEF8A851FA63B8B25A10860CBD4FBDF73C4C184242202678" + + "7E8F05DFDF1DBC46EA96C43323E1C1C411A8EA24D92078E44F4B01A18C9934222117C7E5FE32D331" + + "6CD274AA5C4B5E2F3B75E03978425A1067595E745B29922A69457F261A01057A76BEF230FB7E0BEA" + + "FB29C2373689998AF24A924F241F6FB9B23B0DF33357B87B3CD37A3BA9BD848313E787991BE03CEB" + + "B583966C7947ED5CAC341AE1DEA775BC125270F759C5A158FC9113B1F60C38A1084D9ED0E66BC72F" + + "8BEC8C5A128044C6B2A59B1E8DF5C4E4A413485E0A419C26B334AE049672D677FF74CD197D8BE319" + + "7A491D80738E0EB6D2E67AA4EFA2B8B3156FAA3E72A6E61C54773F51F73EC7FB71D04A42D6C87EE7" + + "7B1FD911B2848CC12A3AC332C2219BC843EAEBEB59EA9DCAF593D138CC161576579AE442703DBF13" + + "3EFFDDFA3775A7F6D9443426E8C95683329B94AD2FD157DC8813CAD541978D32BB147A744FB75DA0" + + "E510C645A39EDD73F11D6B27C70A5032EBD276928F5E683BF96EC88217820644DC72E4D0BB60E18E" + + "C32B607BEBA4F37F7D2E514898C54A633312E49AE5D3CA9425E5C25BCA6BF8C15A7AC6FBC80BD2AA" + + "BF1260A8D9E79564D360F9C6A16388618D4497FE94967310F3C9741BA159B838F6088B798FDDA9CC" + + "FE57E59ABE290463BF4F2AF50B21DA9D9BE1C617C61CB8C8C86063EBBAF2A4E89FBC0E38B416B165" + + "39DEB93764D2925A6968AC1DE5EB05DC082686532D6420F1ADE2F9A1E3BAAC3411B6EC370744B625" + + "35A26A15BD681A7268B8C4ADFDCCB24A3552E08AF292AD6DF58B3AC4B321A5C957B2271AC9F07E21" + + "68AE079E4FAF6000D6146A68F2E4C53B", + muHex: + "6BAEC3EC694A0B9CDE7201E12B8A2B24A7A4B0502EC7CFC315049BB0EBA0F1F315691A2556FD5533" + + "CF9E993C8FF851D47770C0377ABA8C85D41AEABE7EDA3B78", + signatureHex: + "E9ADD46B6C5CA91F14ED401B28484E11E0CFBB33FE45226E3BC873BF3EE79BA1390A5D61D791BDB6" + + "342759F8A9E05CA231CA8358C12078F7E655F948BA9761E3697B9E3332BEC081CCEBD98F62C3E58E" + + "7A416DD06C5FAE03A32F152952FCEB291BB8185AAB00C9FF87901500ADF9D832F8018A7E08B4984F" + + "E0F0D0DAB6E7F05BEC09A2F70A883D50159AB76BACBEC8FE01A49263EF99DB961C6296F15D726164" + + "AAE37EC583639E29BE3274FBE33E0DED6812D03D00FEE513209B118DAC353A4A42E194C3710BC6E7" + + "E70912F78B2FDD22ABC3B19E86127125BD43D72D16A9649B7D9A28778B61DB77A3A256387070DEBA" + + "2A7DB3F0ECFA0C3E965E15C3E57A8A849218F7526E207B18D0613B02B6A943BBFD54E6F768915891" + + "B7A9B2EB374D0F606B7F90045E3B96647B93C324830074428A191BCCED8CF2B323EDCAFCA805E4F7" + + "3CACB9248DFFD880DA531320623899341FFFCA2F7C4F7C964458148DD8A0639F55A65D813114046F" + + "A484F1416873FA9D8B47D3BAAECB7330EB5A4D2CB78DC3D636D630234B60AF37707D37DBA4E0DC88" + + "C85E70747E29DC5C2F82FA7C92AE3BF0D1B00518945BB5F54CF2CFE14C361D6B2D1469F18D414163" + + "8B68843E200CC435277429396F82EDBD00753E06482856B0230B6EA1E1A8670150F8DB822CEBD44F" + + "DB1A9DCF53196479F8AA82FE0FBBEC9EC611751E2F8486A413C23E6412D0BD9969B538AD9BA13959" + + "2262A4188DF176A5AA3A06E88DFAD27B91F20BC7F75150FF3219547FAFD1CCC4C6865CBADC379418" + + "782D8C438EDBBA68B99CC678A5A9AB0E7033F3C622BEC6295BF41B845834C13343CBADACE14F9F32" + + "393D114935CCD889D488EA7783C694264DBD8A7B967FE438C9DE16A5F9A915F1E192A88BDBD93E91" + + "1DFC1E8267B36705C6BAFD519DF8F449E9090FF831667AE4C7F2C3FA1D8D1BA5BFB357610BA959F6" + + "481B45A79D97EC8574FE6E6E37CA4860876508341C7E85CEE7492D5F2E30269196E7F931F0BFC113" + + "EA085334DF4DDC93D4EE4E6459014A9C830103829B3CB596C624CCC53C9DB173822BA419C17189A7" + + "2312BF1D98834E796CB6AC213E765B141387F67AB6ED750806A8CE7ECB06E1CBD27F71295DE5506A" + + "42F4638E54E742ACDA191392F68ABF866661478F2ECCCBDD298B60CD1FC6EF27BF7451FA9B7BC291" + + "12C6D62A8216ABB5C7D37B17F5AA7CCB5CC2D9F2D3CFB574C3D506F19BF328E993045E6B6206B085" + + "D3390A4C1F81D44A0DCA5051403B9E308E26CBBFDADA8642C1FFB3C3B050FD68A24BFE8735D2345E" + + "0891F2795BDDE738ECC44BB256C2CA44A48BC7DC7778DBF696B594EF6931F38B59719635D0D3F07C" + + "49B11C7D170C787DB1BFD396F45F8F3C1D78DEF675D2E5E48853D2C74245A4A2D73C847292793524" + + "82F17A085E706364EF6B37D6F4CBA04D10D91AD5E1093F1A3AAED313EB773BE68CA8B3C3B94B05CB" + + "0975E1B7D66088802DC954AF846CEE78E21DB3AC51C39F663578EB8103664418DC4528247F0AEB38" + + "0A371D8BB32E7997B99DF1AA0AE6AF459204050375F76613C663D8A9984EDC1877FB230854C9363C" + + "8ABE19FC17EDA4DB75CA37254D0081E3619A4141F2106762910B305298A6C86A5A04980E80F9AB9F" + + "7D686E1C82D8F1775DD3EEE577BD67F5EFFAE78A1F5B4C036AF4FB85754A14CB14A35EFDB256036C" + + "0AD555B170FD76794FEE12C47525738A05067E0918FCE889CF084730A66355E385C8D039D076B662" + + "736481F328ECA7937807B10993002AF2BA16FE53F1829F430D6D266416E37759219EF1F322FB741C" + + "0132DAAEF7474F3972C4E499303EC53117EEA416DEB56F1A37563B6126098F10022E31C36C8E99EE" + + "70DD5AC97DB1BA454F7240D77D8C8A11BACE64E0C70696A097B5E2E004F292D20581B5C73791C519" + + "06767640A5E7CA407CEB0938C43A033306486C449937BD103BC62B2AF8A15A9CCF90DFA088E08A3C" + + "13E0B8FC1F7E0A1FCC2D13FFA80D4F04B20BDD4381D6B4206494AB48D15598038ABE1C4311659FE0" + + "1443A1811F01E8245554EE99D86252CFFC122196E76479F82F368909ADDABF389594EE7E8B93C4EC" + + "F4E02AF4E11E67E265D5CE1DCD9C08F83B2F82250731DDDC0C944CE911A718EB76DA8641412D9968" + + "103DD40361FF4B66169DB76A95E3254A8904C0FEDB8B9B1686009646E7AA26605E1BDAD2BC3C806E" + + "1254FA1FFC9AF843011343C6B13FCC698E641D7DC6231484568C6EF4AE6811B8D78461EE225E87A0" + + "93C38C27E05E687E25E75A2A69568CC8DF9D54B1DF47F603B442694DA596C8991AB2586476CE67A9" + + "F8D5EB1BE6519D0EAE9AAA4FFFE755564D0DBD03DA1D5291088F00337EE57AF6CCD1ACBF24DE8094" + + "178950D7E4318E6AB4D1E37282858674BF1C549A59BE7035319BB7F25F2087A87FA7578C734D94BF" + + "85B9B8598BD7D433678730F69AE9DBC69905927201CD594A44FC56165A458282DE63DC446C6711EB" + + "7EEC391C31A97BEE00B56E59C34EBAA9F9F90FC052F12CD553934259E91202643AB26F3706F0D6D8" + + "0C79A90BCF72842F9CD5157EF6C51DF253FF52ADB9FC87540BDCF5C9828A7B03F0052BF4473BDF7A" + + "8ED99E845A9EE6201D42C92A82B92EA83012B10C47D0B2099F71136C424D33058A589D38B7F0ACE7" + + "E82DD8AB11E7B3CA47428C9E7C9EF088240A89661B3780E2FAC6C6B9DBA8CBCF10161DEBABF0980D" + + "65612D0E82D9D7E929A57CD53F4B554FDBDCB72B076514B4FFDA53A3A086786602D138B35A34587F" + + "6E6112339E72CAECF9B65A1F5F45D323EFEEEC13A6F17C634351C1B68C02EF19975DD7E5A5DA1EA8" + + "9FE60EEDAD06EBA93E372F02416884A776EB8CECCE6F8C42E03E1F3E2A70DF8BEB49ACF3AB4DEA42" + + "CC747A678994AB58C5AEEF16A89E67834BCC8D4B7F9BE369EDE3E0808003921774B89B6A5B5DEBFF" + + "135ABAB870A38F99B01ACD5D8116EA905FE290697F51B102DFE7FEA456465F087A641FACFCC3B79E" + + "A16DFAE1D783E889B5759A90C0F4DEEE4BC1C4596B66B49C214126A91FD9058A9FCEB88AC99BA6FC" + + "C9C2B9BFC97BC5E2AF1A60136BEEC7061B6C7EB8E9730A0FAA543EF30E0E2FD0BF7755BA65F9F0B0" + + "F039A3E1B7FEE67022F74B36F8ABB006FFD276B9828E596C1E5ABA29EE21ABE5DDC3AA7E54ECFAC3" + + "39BEF6095B76525B466ED33DD27D7480136C9565319A6B586885C98D05A22399D83745DAD21B0D14" + + "06F58FB839F74ECAE7122B6F0B1C9832852ACCA92560BCECAAD84F5A739DFA028A7EAD7A21B5D144" + + "A697F19D9A4DBC4EC3096155DE0AD952764E78A886B46C0A3201F0331E4AE2445E4FD44F1BE531B0" + + "EEA1E4E6A0FEBF1CDC4B89FA6794799D5A585E07301CD2CA2971D3B1A4B5CA9DB8C43204AB35BD2C" + + "B2333B972869F28159CFF62395D495E0505F310E930815504E951557C8BD31B9E13F18A76F75D4A7" + + "25E69BE48E31E735D80199876CEFEC2362C00CCCD22D6B8C066E31920213D15E05AF60A09101B36F" + + "B1B4CCB7FF6762F35B1A2968B9DCB984CBC58CFE057601D098C2FAC933B49696C7EDFFC20A8D5192" + + "FB75A296227048B81C19548D048C3EF327EA887F1128DE59815E3B8612A22328B7FCB745602D017A" + + "F3BA043C6A01CFEBFEAE3DDAA6DAC2FA720234463262B2792A48D45B1CD1D183BDBEA3CF08451F7B" + + "FEC65376B2103F340932220F47B2EADBE7A19A7D7D6D93EED419050B2184CD69A458B1F2CBA5FEF4" + + "6AA20CFCF88EBAF5C11D64F076DD7D247735FA080CE0301E33651B871E870C207A3B615DEC367146" + + "72FEDD09C75F6E6C777D0CF6BC4E7103D071F90130F73E3AED8D55C53A6795605BF0E2E696435B6F" + + "A7F18FD8BD895C2D844CB153FAC5989BDC792D5E0085C49782C73E347A799215BCA0DC650957BA10" + + "6357F891EA97C3241317488E6FE8A66E104D979D5A55C36A5EF174DE1B1E62AD185622C8795CB37B" + + "3349D9AE9755EB18EE0B716493955D333DB063A3334C74BC9A6C373BE29C0C9FDA3AB43F2BF99A03" + + "99ADE7B82E395F1171B95910D9DA09766C5695C41E358DCCF7B1D8B2A19DE44403679D7A172D50DB" + + "D5F6E572329EC862EB46EC0F5FBA5DAF70C206F2EA4F947CE09337D0D19D3900C71A68DC4FA01AF7" + + "8A90C36EB0870481D07B5DBC3EBB90BDF8E940D6FE949615D0F78B21AB879EDF2AD7FFEAEF8F68FB" + + "EEF8EA396B25D38E605C75B89EFA4683252F3D513B8EF12CDCD7F811E934FFE26F1344AAA0616383" + + "55B8EEB9599713C41861660C025A434FAD56BF642865FD088A2C5846E76BDB5637F1E1103D1EF927" + + "2AFB9528F189672C7A3987CE26E3FBD252C936F28F67F212038CC1B334A7244DF85B98E1994FE9EC" + + "B9D3C50557ED22925991BFB772485D117A28C0663EB5B120F66265DE970F308E7E003CAD1E60FE87" + + "646D883D7AC195F9911EB46B8919C8CC6BF1D185D071D20B9765FD4202654D52F2228E4660A6FC1E" + + "5A55121D913F0A169559C62D73AD1D34AC05EB305233CB64DE0B4AC3361D1B48C054AFC8E835DF64" + + "7AD9A512F4FF7D6E57F86085F919973B8842ADE1A00B19A5B583F4EBB05687E30151676A75C485C1" + + "DE6FFBED47025FB582DB3EE81706B391A502CFAC50AB13E1C419601D633CD87783A15C076FB8C977" + + "95089FDA5C67C0DD0487BC901BD1389BBEAC79D7EBAA616701C0FFC15C88769AB9DFBEF60C6B7ED9" + + "7C929B81C1DA501EDB47B1D2AE2DBFA488F9A36406B8A1D6456B271CC5A448C45CCBE81AB35506A1" + + "63DCDAB7B88A3D0AF75697A88F12D6B7BD80FF38E4DB149D7B2B185D27111105A7057E774BA68795" + + "8337DE380B7F7DE7198B6AABBC32796F079BD763479379C33DB52862AE062DE55513A1233B33A7B5" + + "2476278CD24AA611BDC2174C1CBCCEA706C6523879AAB62526C3C9AAE36107A25B6CAADB8D8B68AD" + + "74DBABB2C50B7A61A90735DABFBE05010630E8320CB3D29637B04A0A10A2CE5CA4E0F7E3A6AAA7C9" + + "C2404268718602FFE634E2A0F57A333EDDC953092691C831EC5D0591A57CE843F5CF9FE519B7EF76" + + "440695C67ABD729893BAAD263C64140B9ED2D954275F278C26F29AFDDB65181E27EEC6E77B633DF6" + + "4DE436FE5EABCFA6B6555C8936D094C62B228611129AA134523E6AE65EB2400F754C3B11322C3E34" + + "9C1103FADBA0A3331DD6AC880C0349C0AD1FD5D0109784FF51D42CB7B7A274699E3FA93646BF1596" + + "6EC9A9B26CC03CADD04A5148D0A32714A0250089C67F19224528B701F6237B19F57890FDAE1428F0" + + "14EF109CC898EC186439CD05F6F9A3562310EF2A01C5A9FC4131B1A296EC543634430638F1EDC186" + + "DA7613FA21B0A9AB60CD6B8ED9C536A4BC7B7D2553ACC96318AF854349C820595198F258A06B8CBC" + + "4428D257D12F000B43844F2830916D855249572764AACA2F11DDAEB4E0F63C5D23D738B083A0CEE5" + + "9AF15AA08FF3204C345E6845280D1BC4969120E5893EB1A70272ED3DEAC8C5D4712379B0E3BF65B1" + + "69F9FD6A23C081188EDFA09F0E928AC62C61BAFDF7BFED1ADAFB6D7CEEAE97085D7E525B24325787" + + "3183E64E38956E70037D1C1FB0BDB3FEF1705CD03EBF2DCF7865CA2261FCF0FC083C6CA0EA9F4CA5" + + "47C17A8AEBAFBAFBED6CFB5C78239FC064B02E460E0E6ACB2CE50FB8A61383659EE73D894EFBAC14" + + "10CAE2B9360421E519392235437C8050A5E581FA44EB4F9D79A4DD9F0E00F908141F9694BA101C3A" + + "08833D6FAE5730E880A4798E29FE53DE4F09F07449AA7FADE47D994428DD5F3C730A5C5B3A1869D9" + + "57333B1E8FDCFE683F51A580CABD34EA2AAE048C9DDF49572B8D593A21011A07D80D190E7B3E897D" + + "EBA78863823C7AEF966B969073475E67E3FB4653BFF18A4327F7AA823180FDC05217232D280A112D" + + "021638ABC8BD1E32BCCF0129931A7CF3C7E8C384A8D0D556319C1663A18FE6E4C31937E27D380B5A" + + "6E90ECE489129A156CB2A4C5A242DB72D9798EE63D0633BB26AA869A4E0693139F8C0D88C0B713F6" + + "59AFFCB6E0176FA93590DAE12C38AD9173AF5AA261E7039719CDEC9F0FFAF76A2808322BF7233B3E" + + "D63A19AD3FE8C4AEB4A06580D5453E37E6D1B9143755FE01BB9C9004EBEB35C18C3F127CA7A6F636" + + "8E1EF1425C5D738B45689DF9CD09EBCBDBB731F8CBC9CC36AEF6B0C6BB30992E49059AF16CF5BC52" + + "D5A2479007C2B382F54CFB48A5DE7FBCCD6898C8D11CBB988EC59AB01F810A47DA90B4527EA26A58" + + "4D2661ED73AA28EBF9D81AC110C27C31770F19D566A526784A22EB150F4759DF7EC03A09883FE650" + + "ADFB9BFC9A8FFF84C50AA6A849CB7232C16FDF3642A09225EC814525D80D803A03B8BE0D30481FBB" + + "EE0FF8038BAFE37CC35E39115669CC131C9A46C2DC2C0478856F59F5E8C5F832ACE3D75A160F0076" + + "D667ED4FD377FF620D516442BA67A4BE2FB8AB1AED3EFA0A00232441455D616D83C2C6CCDCE4030F" + + "223034425689CDF0F823424954AEBBC1C81738393C599CE1E7EE173E678FC9D6DD0A0E3CABAFEC30" + + "6C95A3A4B2EBF61A4D528DA3AACFD7EFFE00000E19212A31373F49"), + + new MLDsaNistTestCase( + nistTestCaseId: 152, + MLDsaAlgorithm.MLDsa87, + shouldPass: false, + publicKeyHex: + "57D0E0EF35EFABD76B919E9324A98CBEF1DB4FD34A073CFA241D8A3950DE38EA7F301C3C72AF8160" + + "35A8ABF0D887B2CF7350D45AFF2695A223AC912FFEAFC2CA4552D3B8A4FD32A8D29FB64A3947EAC1" + + "F0283DA96696663717758E9885A647686D35A427C1A5ECEDA5E9F44F4D0D462DBF1EB0B79ECA7AC0" + + "5907E75B060F89A67424E76C4FA206C64CF88171A2F77F10EB239351133B1A24D089F3E80FDE854F" + + "D16C83C7A4B0F41DBB6A218EB2C95579F7772B55D022F91B43AD835F2CE3A4A56D879E48CA91A6C7" + + "AC19836E686010A4D75349B29CBE5BFC9D4B65E7E90C9BFD38B34AACF81C1C13FC5C356D4A6690C1" + + "CA999A13212044496F638BF6176074D9846673DA8196C14ED90D566591F6088430F3712B77A33247" + + "126EE016879996EA5E7BAE2F6A65D44E4FBCBF3FD30A336D36A40B9354F6118554F39608B253E4DD" + + "DF744D5159B01E451A1FD9F923BD98B8D07CD38265CBF46CDB4B0FBB91615B0BAE8B39C008A49F98" + + "5223717D13B427EE7C2676FADC7816432CCA0AE63BBB5756AE666BDC1AF6EBDEC1CE155F1729BB62" + + "9D7F6C71BFF34D1C1ED0477C774AAFC525D7AB30FF4D1D985BBC39D1D3D28FE14E6B0BEAA9B9FA3C" + + "B9FC0AC25584B9C516E3DD7A7824B6C474E57B962753B59BB7D3F4B1DFC1DE0B75C546EC524172CC" + + "65701422B16C5CD034A567D8BADA1E3B1A5A6A407B8D855F8EEE4558198AC2AC09A0B9C1C867C86E" + + "ECB24AEB6DFC8E67B8F2B3444DB71B945271B9B0389D1F6882DA665E9868A530B405AA4C84D45237" + + "D683D60B1C41AB7A8ABED8971AF6C39AC8DB6A0825797993177A6494E8E863B8F9D395A23EB0B16C" + + "8331EB8B84FFBDAA380B5161E4AF8BE39B5514BC43FB26EC62FD40153E997C23930CCC83ADBE97E2" + + "B74EE4877E7F48D7D44FCFBF45D7CC12D2D0C204F187D86F1D4D913630BC7F13064C9D3342BA235E" + + "AB8B504B8746AC03BDEFBBE2A8DA7499BD1217D26D6EF10CBEA42189CABA467474ACDA87036C54C9" + + "773CE03C62511E9DAC42A292F758D3854BD865AAF39E6A8201B87EF0FD29455EAA90B69A5213B5D2" + + "C291FA4E8857838F085F782A59FD3DADA29D45AC53F4196B28726DAC1D7507FDB6D4A84024F1D256" + + "E90E7DE50149D7DAD8EDF9CCEA3E0A8829EAE8AB396DDB9226B89023E8660BEF55967ED6E8F9A60C" + + "A646C940C4B3248842BD385BC9A6D97FECAD3F9B63A637D48C56CCA1E8BB180E9B38FE8AEBE3A66E" + + "D45BC0C4C0AF86D4A71B72A4A11C637A494ECAF5C37CF863818583ECFB80A1279E58E4DEB9E16317" + + "144CC9072F19FD44E072B549404EF25FA9D7A7D2043D4C994284D36951B15CB71DCFFDFAD92636B6" + + "E6F8F11D8C14875F3B625129007A6C097C0B28D807B865932852527542E54CDC638339B75EE8ACF9" + + "24B1838FA1B739D495623C41F2554AEE18383B46A21FFA390153039A6A6B57540C056B4784D85A86" + + "8C5DE41D160D8721509C0A7D0B32DF7918294D3E96D37F2930E3004ED8DE4D9A26C4D45EDF811FD4" + + "F78C94BDCE94CD75B91F1DB859F7915ABC058AA61E28C0F1C3CC5CBAB961435571E1641AB2FE11EA" + + "ED5F0D3674CA6320119F417B665F186C74CFA3B1E45836535D6A76846EA9B959E3A846C09F9C763E" + + "12AB522FF9C260B297BCA586768B94DCCEFA9EF6E4F20DF6D5B39DA3F6CBF35AA54FACD504A50618" + + "1D9B7592C1824B59D08C560DA25815040D88C3697DB4363CA30A25693D0006F19FE4A75345445E8C" + + "C294D50E750939428F6C7628E1E7BD55476B38F59073914F9C334531D3FDDF452686ACE8AE41561C" + + "4298AF86FC53B39B946E973977B2C42AE7173B42FFA5313DF28FFF3BCD313EA4731C7C65340F3755" + + "6589DB451FE93A5BD94BFE27320F470B3CDE0D7F208986574725E4EC38DF0D7FBE7596773659D57B" + + "F948720F7CA36E9533DE28B47B19E8A70E0390F9BFF59D4A0722A89111F165D4689B5ABCCC190553" + + "97A165EF25138C8FA28B8BFDC0B22D1D69BBFBBB605A58272BE13521C72BB0B1C91F876F4387F79B" + + "C566579CC0D52C44E48BE55D5036B4432EAC045EFE60682204C6E87AD02C0103D84218882E533874" + + "588B1E4C2509477332679CF25EE6F24CDAD7C1502904C4B133D2898088A8BCDF1B3B4844D21145CA" + + "02ED80F2820E332791CD7E9CCAFF01CC5605240E05B6AB10CF9150869CADC9E2E7BD98F062BBD58D" + + "5FC80A0819835B92AEBE68D6AEE8B42BB5B91FC5034826B82A555636116E1567017560819436A482" + + "D6B46CBE5C298491FB620A50BBF59B70952B04BB449685E2B4A5B179696083683063A903BA872C95" + + "32B23F8929617CC9F3E3E3A77D57804EC2E4019EC577EA9AE1A3657222C06723C13027DD1C266F81" + + "8F01A51590ED14882E66B60B2F11DC581A1E0C37ABD9791F6FFB83296CE11B7D4451CC0165A6A24D" + + "CBC24126742EB8F7DBBABDB01C2BDAAD07D1DC7B38B40B872E455CD7E6BBA895414C2ABF3384D403" + + "C10F49482A26EE46B03E4191887924EDD6419488BABD2AD7AC64C6C418A74586A6D7F5695C7BC3EF" + + "7B009B79E3AE5F15B09AE01F12FB38522FF5D8179E10F98E9440E93455CC35C5C0BD8E942AEFD82E" + + "378355375E96FF8255F4619223D654F679E2B5DD748DFA0D10C1F3F6BD46E9F8FDD135698BE58563" + + "06B7F7CC4B60B12CCE324C32CB5B0A3844A40BBB41C468D7A8B2C2C155D9B072416FD4109C1079E0" + + "7C60A80D9EB6F352B0107E1FF19085B53CFBBDE7FCB2C160CEE37D1EC35BA64C993B1287B28A626C" + + "7FD52286E5DBBFA590A8AE546FB52C2FB329AC1C354A5A3A1FEA6D6CB435F1BD4906876AADAEC1A2" + + "77D3302198186AA7740F86664EE43836EB3DF74BE38B031FFD58C9AFF3668D30F9D1183DAD467B1B" + + "BEC2C8700866DD89BB6FFF1136016B73B62FBA36483E6FA6598CE1CE787F6B62038B2DCCC00DBE7E" + + "57ABCEA3E8F8C3339B8E2C2B6345394817B3652CBB06A7FED53D6EF612A3F450780FFAB5DB17D7A3" + + "ADE9E76C0F0043D185DB030AEC1CC873C79415EF4501C366787FB845E265C5DF198903693BCF2719" + + "643EBEB3A34801BCA545DBA2448D1AE68C50BC16731DF6C01C794C7C5C6E8D1E32256FD20340F29C" + + "93A107E5F2A1AC986A98F842EF8A017B55EAA629EF7E8CC43B1539C1D908E9650EA6219FD6715FD6" + + "2E5077E55D80CAF4F0C148F5C110DDD5D20B6C532E15DBE25BF545E284C7D2E134AB51AE158AF3B7" + + "CAF7E3E38DAFE82B5263251FF7AE482589B19AEB74F018803184F9E307DE1AB31E50F39F8C5D340C" + + "DB4AD926CF047B0BA915E773F67B41E86CA4CE30E47F82F4BB12CFFEC666BAE7FAB60EA95B2F72C5" + + "76F9B79AE91931ADA74564ED132E7BFE64F27A0672C1B31408A2CC8655A86036769E762113F0E13C" + + "A40D62D2D6B1272E6DC020E78BF139CA03F9534BF4075574D774D77E2C78C662B59C71B4FCF57798" + + "183BD3947CC44B28499F7B977D2456F938DE3C3CB03C845AFDBDFB5D8DFB66624EB84F0E63855B67" + + "78AB1CCE43B3C43D62F3B885BA7ADF1AEB630C802F4D47CC04558088CD65DFDE1236226875DAD1F2" + + "F8AA8543BB15B992187E2B5A243BC3BB7DCDAD5F6279E3DBDDEA84DAE0239C639791D1D5FD9AB10E" + + "58D93A79BACB87DF0110109D25C38E666DE3DE27398F827F1655DC20F6FB94B2", + privateKeyHex: + "57D0E0EF35EFABD76B919E9324A98CBEF1DB4FD34A073CFA241D8A3950DE38EA9052689F173144B5" + + "7C6EACEB144A49C27BDA9085E0A7C23BF1568E6CA2DE89EF72C4646E561717566826B8159AF9C3B5" + + "AE0D068DAB7678DFB1F4A033BFF5C00D0EB735168A54A18BEFC58894301F39F2E775F6F7490DB65E" + + "138F9C876F008CAF48B4010C382E22862544B28CE39885D30625C8A229DA9884142542944880D106" + + "6C9AA289181384483880218705D9A02C21364C5A22106210851386814B324244826D62446201A740" + + "8A86614B4281504080A1949103161049080103024EE1C60D110241980250D920841B830444163220" + + "0092C200260A12680B23085328810B404E91044493480E90B44813820C021380183170C908609B24" + + "4ED818208A324DC324911285080B48262133811A906C40422C22376548B81061144540368C849024" + + "184725C4220420B510E39085E49671819645D146880B164C094884881621191441CCB0844146700B" + + "24108332440235608330494AA870032211E028609324720B15920C056DA38268A3B268023372E222" + + "66440261DA9644E0C88D8C283252C82860043101A02C8B96090CC951080781D3326908090AA3102E" + + "E1A8304B0829D94052922684E1146E2346328312258C10328C002519C80142C4108B88259A942922" + + "48251AB59159182A00957113290C03322251382801066682B60D8B002D1BC84CE44822903660DB46" + + "9103290210A0410CA85123432A90A890DA867123140C032812498471E1A24108431261284C63262C" + + "D8322923311244967000472A00A360C3202C43128A8C406E910040A4C88924336C08962DE3842D50" + + "C46D0B933193C46964A00151B68DD1006E901231E0A87164323051284E03001094066199048250A8" + + "01C2888409B76012364D64388A92162EC1026C12B25149904521942050B80D14498C508224E38010" + + "59B00943340A21382E414022D4181109420D11B6652443041B11025906821A16491CC53002019203" + + "14211B294490165094902514C249C3B49120363288B860CB42841C394A6346514BB88C0B21650C92" + + "4DC4165250146552C2019C148AD210620090881020009C860C19B5641B472E8B240544A829082351" + + "63B208DA460A0B965090360C58B291CAC06558882D94461049046903C5498B48265C864000C98103" + + "A82D14040448B65108464A0C408508320048B604C246525988051802101BB7215112695B900C8AC6" + + "518298105B928898B031C9240EC208128A0030D020024C32024C0088501691DAC08C423610110211" + + "C82069E3042AC2A43110A3510CC4050A454523946521A225DC402501422EE428668A38480932424B" + + "C04941168592348D84802C9B480C2405005C32898C087199142964B20002440DD18830A42265C992" + + "31D310024010801BA56450B830A1B66402A60C89248A09808150845150A029021286C02422514072" + + "08318580A40808447201810460B27191B08CD9B04CD8A08100C98904052A10398ECBA8699C183050" + + "388AC4100983184621448284120D9242299A140E54404053A06489C68C88C28C98229102B65014C2" + + "7024B089DA4649D8B245D924205026849B92411B236D4B240A1415402332690144408A4885A1A028" + + "12B02DD1960540B02814968919968C520650E2424E8AC610A33680D0468411996850866110128501" + + "0541DBB421A282908942010A042410236A1C02621381209A18489A1089C24452DC20448048806334" + + "64DAB20C11172C531084890404000644DA800C189584C0187113480E49C4314222520B3100124510" + + "4AA65083224209B5884C9890E2B470080745C3006560C42D0B360A99B870D0864498388D9AB4498B" + + "36310C168E11394A5B3889A4A601D328700C08809224329A24514B142E03C251248970A4A80D6046" + + "060BB461081210D3A825908421D29444D2A028CB182D592866CB906C0B351143B20D0C154DD04231" + + "4B2065DA30329A820562C648A32688D1A860099449D8300E20021244908D00070A221129D9A62919" + + "B30C8C300E00818860906D82B2710A986854B66923077293326DCA24515A0484C23049CAA4691126" + + "440C372623936420C860542026CAC00002B36D83B6449C208D0C8145219848A19211A39248230031" + + "5AA00451C00C5BA4515C4064038301E2024812A35001902DD82231C3866064C07061364CA1088012" + + "2166CAB83119110ECB10F71E6C07AD509B3813BB658E22F2571D5F8C1A483CB7A9A076C205C54127" + + "624B5F3EC23B8E67A726EB9E8ED41A24AF13B79E8B1583752CF90DFF678A87F509EB7748F35F794D" + + "95EC9167DEC38235A0028EB136BFF2534C9EF202B961CFA1AE50AEE018106DF43F25B7088C337419" + + "9999772689E3D9345F4E3FC361802D838D7F2E65A9CB27E0FA7974026B34522F492C199CA37B8121" + + "6EAFCE3684165DD9C0FF39E766C545775BBE843C79A342D6F4644963C7E19834A0461E9ADDDF94AD" + + "36FD968CA132166F285EDEEDAA3820D21D844F8A3289DD832CB491FFF1D40AB78644CCDD7BDB9E58" + + "5DF95A474101B7B0964891D9DE3EDADD533386FA2412BF75F940591C02AB111568620542EA05FE64" + + "FF0F9A3BE5B3AFEF04A888AF8304BEA9F3DA1AA734D3538E33EF28ECA460E25B29B933FE1C9F0A48" + + "CEE8E925A2AED94DEFF7448BAA14406FC31DD213362EE5B3D096A6F94FA1EAA3FE84EB85892C6A42" + + "99CE75A998E5E343C0692AB55939FDD5719392FDA5CA5E34EA33B252864F96A1A8A96FB57AB8BBD6" + + "D10151BBA702EC600C91B55D5673004976A2868DADA6A8E97CB4C98DB7655CDB194B9ECF163CAE81" + + "1593F7F24BAF6DE6654895511726E4E5CC930955F1E2A91D02B84FBF47B36E6239390ED2AA8C4331" + + "325D562F50D4899C5BB03C96700721DDCE979A8B7525C1A8C1479365E789F20C0E3FD8110B17DFF4" + + "D2B4C816E27CCBBD49D0C4416D0D02467A3B275592BF4A0FE285FF4494716BDCE9666C2A590A5F94" + + "AC263F32101423682AF4E4FAD0214DDA5B2440522AE5A8E32956556E715BCA279F1994F0B5B15FBB" + + "8F082C3DD6A615BC3AD2253F006AE020026D3B5417983586CDF438E0237C753E45394B21C94C8049" + + "7234AAC543F73C1FA5E5734D24F0191F8A6CDFE3AD3C0B38D3219ABB9B65BDB147456C9E32F2217E" + + "6D69CB713B890C651B723BCB8BD28A856B297C0120FD508E4163B54EEC8609526B3D4A164F02B278" + + "AF1A8F3661E10115E8DC7F3816D295A5AE5040C98161E29E035C70727E1FF34FA35F433D14E34113" + + "5EF4300B6E055674E1835BEEFFF4641A78F774B7F558AC6A6238C0AF4AFD2F17E7F94ED877E43F61" + + "07EC8B855811B0FE84F2509D0F7AA5596BACEE9FCBFA9C64E48F0AA60277EAFE594F4979CEC59450" + + "A7DB85A3379BEE80E874A69675A48161CF154AE6607272A89C894D427A122E9E82CD972C9F407DE1" + + "F4FEFED367E5F43026F4EC1B6B6095D5DCFC15072E2F0B4365ED3D961B609E7040F0EF5373D979B5" + + "B036254CBC1756A29B4381D3A6C9DB899D63A6C673E253945DA97EC669B0F84453A97460D16947A1" + + "F34C740076F78ADA5B45A7B1DD0D6AD9B47B303A8F0267AEBBFB71BD466AE61AB9B0E60857291C35" + + "9C1E4BF92EA1B62A067E4CFFBEEAC1A688FD99BC92BD2678AA3F46FAEEC20DF477AEDFC9DE204F6A" + + "FAE613E82C4B2AD72EAA1BF5F8926430292A7B38767BF2F7AA3106C822367014C9D13EDCDF05A0E9" + + "FB25B6914814E4F3362B21F609D850E88685CCEBF0285AC9E6F87C624170B8C5FC7E4B11305AAEB7" + + "A70E94DF5509DD5AD0B3F2C0093CB63A78DEBD165E02BD0B48D415E369687E27B0FC6ED8E680B87D" + + "C735231D3A495E5D9B7BD57B4D3F2F37BDAF7C89D5454822F16FFEE20119D66E3E641C11051F23B0" + + "55BB801E9508CBEAE2A8DAB1D5449C9189DFDE1B8994597DE71641BD15F1CED3551EC554DB33A537" + + "82C7B08CAC806878A4B6E8CA4237BB3E4459125468F083D8C392EF221FBB5077C7ED38AB69F61808" + + "A0D1B102CFACF23EFA1F0D2E8C6F3D41F66FDAD6DEEE1A51C8E68DF41809383D2C4B73F6D72F946E" + + "E80DD4CC26E30A51B8565B6FA7A8718E8A3D9FF44022AC693C5079536C20C7DED149235FDA90B962" + + "9F286EA1C1B60550028D9792D5E473A46DB7E98CEF5786798DBDEB7C60FA5164B13ECCAC6BF2A4F5" + + "A6C2470DCE6498559C891BCE21FA3ABAF93DE89D46E0687F228D4F1A495402C23B36735852D66EB7" + + "A76F53052E8D0AC4802C2EF854592343B8AE5CA312CE603F839ECC334D2508CD79BA4404190D68A1" + + "E52B2204C4D3A2FA55D1034588834E5876A6E5B76367293C0D611E77CFA1BCF930C7E15CE4645D20" + + "CB8D1C03870D3873956FF45CD0F72E9A4976AB0526A5CA08C773DD906659F0044802007967111381" + + "68E3679981D432828E2A6780EE1731E59E9CACE0DD3EB2E0322A20F0339AEC4B63531B9BFFBA0985" + + "16E290A264B279E0974C20F9AD94E5C5D082DEC13754BF983DF043CB10C4ADFCB4B6EA6820413156" + + "FBE0885CB340A46C93B7A80FEDABFF71D0D1BB68B1CD62C0C0287FFBA3429DF02720D2E65CEE35E9" + + "61F635C301D30D4F9850F09982723DBBD2E4ED0E8416C88D8446A9032996C85EBA72D05E54AC20BC" + + "0EC15CB126000C803BC0AA0473AB2BD911A214F600E6FE5F2A6EB398A124D02FD10FA004F1097846" + + "1FB474E927DA2E018E8CF2E1E0BDE8A4C58F4D3F6B33D220EA8C44C9EC778023386C77AB9A26C7E0" + + "2421560A48E804EBCB64243ADCB8CD5035A02AA89027342A2E6233BF79B27FD87E7F223EBA864E87" + + "7193C8BA9F48800F0B51F66B2A094D94B18E21F6538DBCE7BF45E066B7F8D51AEA6DFCE5E5DC554D" + + "0BE8803C883D4898AACFBFD8AAB2E40F227CD8366FA1796FFBF24C0E6D2C26F216E6044A552888A0" + + "6B755E28D03E9617865165098DFC2353C1B2132987CB9ABC65F0CA9C0292376EDA7E0D1F15766023" + + "4032AB0326CC0DD109CC54545656D202366770DE31F2DAFE4B80F5F068408E5286F1A0F54F84AAF7" + + "C63540689BBDA8D42AAEE818BE4C0D9A9EF31AF9883D6DC6C762D8FE66E096B255678746C70CACA2" + + "D4B51076D329D3B0CA435D5767FE584F8B5B04FE39F4705128B1C0D5D41EC65A2C00103FCA817790" + + "E9DA30981C8A1AE968B086C4E00BC3FE557D78F54D798FB0CD2AE7BE9F2DD0CE7C187EAACBB1E48D" + + "94CD8CA868A804D47EE26BFA4D880CB76CC2935166FE70AA966C644778B7CE568168B91FA896D341" + + "644A14491BDD98A10BF65EC294DA0EC9F17172F4C3689D24ABAB8DCD852AB050EBE3415830DCAC6A" + + "52ECF0A1256C9583011EDC8B375A2FAD98F581799050EE6CEDE1F0965C335FAF03D7F710D9CE049E" + + "715E8A91946696167B1C9830FE325D06F98F713F827DCA8FCD254C5477EC6C121F15B9521A375A69" + + "EDA498D76210010D2365C0736BA0C05124BB22292CE79857DF3FABDA2A71B7E9023A44EAA7208365" + + "7A23B0A41A2A9DEF6A4AD810EB76C6AF2A3DF8849FE715B7FAB0EE51B5A4357394FF4FBE53744D24" + + "263C3B742D1C1F7A391C200383BAF8B833DDDA573C44E03CCD0D4E3377538399A4EBAEE4222E7EC3" + + "01E0D8F7F8A1BB25C02C682A301BBA959F1AD5882B4BAAF6E7B5952BEB384ADD1150F093ECEF5037" + + "8767CCC733E45A61988AEF69E9C7CED5157BC5CF3EEAB3D2946F746B4870A405A1A214EE8836F345" + + "374C740EEC6EE38336E952A88964250170766978B63208AAD07C2D4C50DBA188D857FCAA8D1060FD" + + "EA44D5AA01E96DCF6A44FF9837CCD1A84A39FF8A1756F38628E3EB86843B773BD4B8C4CFC0F549DF" + + "67D08B05C0CE44E5E252543CD562C3B4AABD8C6D8E0A44212D588E8F344E8CCA1E966FABEBFA4EA7" + + "D7F19E15A2EDAE9354E188887C95FEFEDF74695B74FDECAAE2BC7F937C5C3706242E78D50DC23443" + + "35DDB469C352038A7F1C078FEE43848E30D27BA4FD63DA1023413413F6859126CCAC7C2243DAD245" + + "4DBC829FD87DF5C80752FED8A6F90BF94782BA8D9E5644CAD2E66409F5E58668C0E091E8A48E3E86" + + "8AC4893A32E62FCB4F151B767C9D5CCEDB53D3495B1EBB7E019F3882CE1AB5791568C31523116BDB" + + "30BBA3ADB0B49422DBAE88A1C9636DD10F0D28B417DCD882B022C94A3BB1AAF89DE8595517C0E661" + + "286396962D9D7B3A295796B8CD2E3DFB47EDBEEFED9FAC2248991F027D8339D4D6FB7B3574D679C7" + + "638B3B27F3979EE15666488ECD7B27C518A1539ADC3AD0F9422FCD8B7951B4619E477B984489FF8E" + + "C94FF0A96BE6C8647703642099B6AF3890D27877A2764722728104BD8F517BD630039AE1D0F1965D" + + "D51D5CE3E43E74F1B99786704186076F59E1D2A550227B2E1D0316A884A437C83B134B47E0040C7A" + + "3E9C52FF2A2052440C06AB56D2D24329D23CEFE4E2A1CDB588D1D41870C3FCAF3F9839A88D69B0EA" + + "0E498C77683DEE610301F9B81F5BB8EE70B2A02332C1D0B1B20909413BCAA5A7A24F7CF1FADB3D49" + + "19447E53C2C0AB46B346A18FC4606793EF3403DC32EF5E372D062E2C85A15399C405CCB8C7DB0E2C" + + "4A1D47E415755C4AB526DE229EEDAF28655F8E8D42075DA228300469BB639BC7F50F58FB23FBCE77" + + "8E06ED8C9C16DA02160DA471AE0696792D0DBD97870C58C05542E1E1C1BF1C5784840756EE2B6DF2" + + "428CE64D5084AB21AFE8E394B20E90F99F26E30E22CFAB151232B65C17708B27B74CC92F5F276828" + + "CC899E207A1B97A33DA569B0945233B1329584DCCAF44676BCB39AE1FCC81F7CD285A7BFE6F1BA59" + + "F63E6E072261EF16ACCBDC1C95F35D9CC59537BD91F1C101BF90F49D2B3EEE264348EDC4C6138E6D" + + "93351ED7EB8EDB3C3D962F2EF933E5EE67FEA80A6ECD8137934ACFD015A0C08A07F88D7B8917B827" + + "F1045B38176974A70D10E03F73DB90F3", + muHex: + "940E07EB4C51100FDB5169ADD19BC180C7297ED769E5EDB7CED579E6DD39A05AAD959535F438E247" + + "5C129916AF512BE2609217D04E66432A44FB242F986D2175", + signatureHex: + "8A931761BEB6302E8775189CAEA0B28FB5B3E2AD0880028107137CED0E71B198D251E5B113F36A4D" + + "BAB6B603B407853ABC13758B27D9F0DAA853B6DAD01E7A1E2F276C9DA6AAF50BAE5C0AC6AA4B77F1" + + "A2AE0FA3D37BC90F9B72BE6F3A2127285D66F2546A4FC6F499BDB771FE147170D5D9B2FBDFE773E3" + + "5A53DEBC26FCB4924AA4522AD0655A4A5CB99922E5951528970E6244BB1FEC5C9B7ACD07AE5AB15A" + + "645AEA8C7E9ABFCEE5817A1E5BB02A3C73C48427360C200CB38E7A1ACF7FC0D1544FEB12286A7CD2" + + "8C659C93E7BF1DEF0248872E44BF02FFF8AE9305B3AFE2B82B67DA3EC52607A4FE4366476643C83B" + + "0322F71C5257932E0C3DEC83B737ABAF8D859DF8BF0D5093C1FBFA5385588BC8E6E96C9AF7A290F1" + + "0C072680810D5AFDA00F697107DF459CDE3A7E290C02250F4592E7A2BABFB48A2AA3FEA360A4D608" + + "439928BE1C13B362AA2CB7586A5C184D9D10C396796DDC0EB5DC67A60B7CFC70E4655B7A62D24F66" + + "2D9321FC0F5CE12152A24A88D369C67AE1045BC00F816A938A35CC692260C24D9BE8253A731D0F0C" + + "ABEF790B455403D5AB40FCBF4F85BF2ED68F33D1C5F3A286DD2653531E6D40FD43979BEC812A5894" + + "BD8E0463805777F447B14AC7ED76B6211FD4297CC24FEADD0C4ABAC69CE45A09B430AEE218DBE097" + + "312EE70561FA797F580F0A9BCDB615B9AD3311E4BAD95BF45C7F279DB5B7014440C807652799C862" + + "9D0D7479D285D1F637CD6B5D0B7A5412E0992293EFF348FFEC2FCC820BFEE675C6516CBDB63D183D" + + "09B632D0F1090B346FA77A78939DEEEDB5D792EBAED03AC6DDE3D814CAE273831C116C115776E406" + + "522C9C840DA292AFCE250837659A07F747766E829C94778EBB21B0798DB241F90DC9E9686CC8521A" + + "09968F67797F7B87FE210E7CA25DE85CD22ED40CA6BF757C2EF0FA3E3BA436F639F90455F4359D23" + + "71B0D57617901FC7C81AB4CCCC7C7529A4D7485D1BFD0096D1C8CE46C4F5B9A84DEEC534E6486BA1" + + "ED8B180595056223F962929DF326748A1F4794A13175F03090845348864025218DDB1A22C820ACD1" + + "2881E5D573E023CEF32F7CF9AEC052E6FBBD667E1E4424C9C949F59FF38EDCA54ABFB5F193B39FC8" + + "3634D05687E25B4A4DB2049288B59D26894A37AA20D3955E886295457A5D99AC68C9C91A9FC8E61C" + + "A49A0CB7CF1FF5557FC820E01671E3EF6D907C81E4622A610FF19BCD58B5359FCBD0792EE1242B16" + + "67D1D5E43ABCE8D216884F9FF2D1776CC149CC514BFFE833CFD3B6AACBE8E43C351333A23E1F6D04" + + "213FC25AFD037A819982A6B10EDAA17C4847E5C80F4D3E1D100F37F4705C06BF8493654303EB86A1" + + "BEF0044D612DE7EF13793051B5E15051479DEF89341DED95346195C2BF6FEB8AF3102B064C997FBC" + + "9529341B0FC3B57942D5A7E944A44FD95CEEF876B48A0CAB7E6F45B68CCEB60A95777EC3E25B0F44" + + "369495E74C214BE6D88FA69DCD171C3B98895A6672192105EE105E1C1B4E6DB075DC6C2BC30795E3" + + "F585F47846E078C6460CC1783CBAC1E3F212753E8C5774F907CD6B1759B49926356E449C05C9C608" + + "4DCB587469A65CA1F0EECF615E523A4D79B31170E1A9D91907069CF6723003C1405EEBC87EC2DEE9" + + "138BFD0F0E205CC4E0F30F08CE16227897CF200F9D4F1528DE204F6B854D2E701021FB2ACA84416E" + + "035512DB33D950ED99479FA476DE1E2D5BFE219536980A5CB6DDCCEE7394D51A928FBDB202C566AE" + + "646810DFCF2C1BA4C5842084F7D249D578F893DB7AB4E0C6DB66D6F271679A9FCBCF28A2D57D6407" + + "3F99ABBCE2410ADFEF8842C4897592FDEBC0F9888F02CE0FDF615CDADAB911AECF61063720356AF0" + + "D844FF5A784F789627908C5B951FAA8A00B14B14BA6DCA455DE204B06DB37115FEB9A888130227C6" + + "8418ED2961979D6E1B003B99F119BA1F72A236AA99E46F17D36373713B1A0CAC152EFF81D48D497C" + + "8782B2216348B5F4A92347A65D67926CE7BD6648D21CE29353B04ED28199EDC288B838E371DC7B67" + + "38845EB3ADBCCEF8DC07399A16C89B496A3713093050FC5B8BB8202F5C265602707A79F2371A7B22" + + "96552F6CB075D7BCB953E609B0CBBC7A7E7FEFFDD2D0A8180DC5682CADD0E8FA6CA7D4750BD9A90D" + + "83E6FBE29D2CF353582C31BDCC56D87270B0470E7E693632B30ED66733C0EBC087C08006F13922E1" + + "EC449D83F864BC855C14AF866C6A19627386123F73A08087078432B0502588C67B6A23CBFE7DE7DF" + + "4E78B49AFF6ECC3EC9CD998E2900C012E000D7AEB27AF9B4524244CD4AE179FFC4247A40F1B6CEC4" + + "1ED4E6A951A4E12442FEF342A8B72D4D79DF2E1CF308D90132991F490B05A3A737C9F50E418CA406" + + "7549F4BCC98E3834518C39F8E0218E7630F31844FF9A5B649A2D3F2466AA70FA0E92FC3CE891EA46" + + "CD2ECFE7E0C85F2DCE7D1380AF4659E3D4C8C24E30B5C3AE1A2D1BE97D5E69A3FC39D3813ABFC894" + + "0DF4BB5D4A4DFC473EFD4E7CDDA45B2830A8CC8F07724BA38BE81348DAF944BF0EE270778D5549A1" + + "14332366A7537F0B13E7AFC3211F4B4699EE772238649A24BB9DE13FBEAE08072A87A7E80AA8B2C2" + + "4339CA9FA2790AB2A1C212AFF7942DEC0CFD48C9473903C3DD542F7412FD1429BE3CACEF72EB5764" + + "4F46135907E236C52B6BA3060AB7DB0D599931BDAD4372744E647CEDF87E9C00D05BCE593E4057CB" + + "AFE0F90478DC29A20AE0C77B8ACD9385C3225C588EF17E260F18D62071857AEE73DD7CBC4F38BC31" + + "7E869650DFF415A66A3E54BC339E222E599F7CF5E504805E97B25AFDA1CD5A55B105F3CCC378E24F" + + "61FD36CE6E211B4107261EA5C48413E7D2FB899DF35D12521CEDF7264B458F415C5B97B4C0D097B2" + + "9D9540908DE6E19BFE177B2AC8ED10FF915A5EB028C95D7F1FD811DAA6B52D65480DBD572CD279BC" + + "DEB8DCEC2F96435C6272FFFCDCEF03B3F78B5A733DCB971F72E3F628CE1AA078FE7EB1E442243650" + + "A0A0A40F4EE42F08F1479E5E849D54B1C08B184F8F08BCB2FB7C2FAD2EA66DE45F2A88FD1FF653D3" + + "E181B84377BCC0B9351C75ED0F5E769B37079C651DCDC03D3CF734FA8A7138B54D9A1312A1C7352B" + + "B4EBB087162EACAAB53C9D4822FF89DF754EE71A17B2A05D44C1F885344515572387DCB337E15715" + + "14D2F04FD45010CD8F16CA3A4ECCE6CAD10CBF0B4C22C4CB36ADECEAE383D056B96150E39FDFD454" + + "C8730FFAC87D599E554BD7B7DA0442285D9AC08261C53031948F67E661BCFA465C1A7BB84CD2FA3B" + + "5B9A393BA2866AEC760E74F0EE515E8321891702205B2334160CC8CCDEFA6944EE3E3761018FB535" + + "46C7F167526123C107D9F21DCF45F0A4E12D4CD43F72097B77F2D4BA6BBF76D56C15C0F019755C1F" + + "4DB2E17C69A909573A96D1F4C996A25B458BF69D1B50BF5747F087DBD008701CBDFC2CE989B5E8B2" + + "61D9C8B9C11B05020F22FC917AB6C455F6EF9773DAE1CB4B30BE4802D3FFCBFF29E3F46436D9030D" + + "E789F5587F71BCA5176DD0F82440F31A097833B6DEC3455DA81C6BE7C4ABD0E24FE8F2C9A1E0B862" + + "13E50D12996A2D18F8B6A8B4769E53E0A739CD1400FD08D389D48D6B6A1987D8A379CA6552672591" + + "E7478A579F4266811B7A8075B6EC55ADAA6410E5DE9E443917B337254569BA8B4F658454377F3AAA" + + "291209B4B443FB02A8D46E663830E58D2A850C8BF6CEFD172AC29EBA30C0A6838819FA3A440D1DDF" + + "EB04B8D94C1F8F2E0CCF256312C9F0E82B12EE7FD90637B0F0B4D77B8A8E13A0874BB9875507951B" + + "FF6F30F27A344AEB74FAF6B750BE1E466BE3255E808600608A6FE95969292BC0DFE4D78D521C462C" + + "3574E6FA20E4CE5DD4AA67664540E3629AB1D98C699C6966C0DA200F62BE4856DF0D1041F229BF89" + + "83B23DE53953318003AC4A02DDCC55416C6222FB19770A81E6B1FEBE8AAAC9E5D8A2D0574943007B" + + "6E71F6333B670D5B5988C6A87A4FEF817A8AEDAACA5DF09A4919D60E07234EFA84C3003436A1E193" + + "57A0D7634CB93F597C568752DB39A259605ACCA2AB96A5D845B3322D9C8ABF438DA02ADEF3B55A1D" + + "3408246D66D1D9BA4840798C794B5DCF8B47726E651B09BA46BA3375C491BA29723E5E4F01B8D01B" + + "6BE77DADD9EC600DAE7087CB5007120A2C9F34FA94E1E0BFA64AAF0143C260AFB8D9695288622E80" + + "9AE0D4309792D10AAA84B13853E9E74969E90186254E658BEC9B436A1A8B9D4D7CEF4B0D48DB86D7" + + "A806E02E9C59A8F8832C915ED752448806E4AC530B7BC4D9A526870CC86152A439A38DA75FB5EA00" + + "CEA4D925048E89F51349D8EBD79BD375134C91C6EB60258F20F55FA99517915E88C47D61DC495B1F" + + "193BF07B0670A9D158292194FDEAE917FC2F827F2990992D16EB8D632D286FA784FE5A5D3CA46331" + + "19EC0D384D5369411DE56B2716ED68B656CAD8674E26C62E4F3149317E19F76C1B77A699BD5B80A0" + + "A1FBFEFEFB0FBBBA8ADAE160AC5D0C35C33FDE34C2AFD9CCABBF265C901B7D335B998EF4A3D05C65" + + "E7CF83004C6B80B3454C5727B1DC9F65E9C746B1B737C3306B68F3ABD95338C758662A57A965778C" + + "D0AAF2CA1D26E6B9F54EF58A92E5973941DE3FE7FE80B5A088F5D2951F0DE32CD32D3033873FEDF3" + + "CA956548F8B0D5497C2A5D5A0E70A2253E4E0EC921125A3E56AAADAA5FDB12EBD0AEFC9E6BDA4CCD" + + "BF82B1F9DF04A95A5C37B0FF9F6BD9B075BA6601178C6E2650F4D3E635E5A4F45ABD3ABD59D9A068" + + "32B683FB7F1FF51CD85C320A6A7A67B0B63133C929BE3E3396504A6DF6573CF8E21867EF34F13D6E" + + "FA67BC8570ED48536E437D9BDB1D71078A8FD3E87C908EF7DE6DA12F41A09D4B322B9BFD5C871E86" + + "93297FD8126FB3491B7FEA6274272A2F45C7FA7F2F17ECA2701C3085E620901B71F86932245B313F" + + "BF0DD66B5C187506FEBFDEA255C2795AFB3D61085CB73B04BAABD2A2960F83DD8E347F8A8B5C1B55" + + "C40F078ABBF88B6A6CE3C93542C2B2DB50839B9DC42423E712F79081DCB84B5650C54AF6D6355711" + + "DB79E55A01D4D3CBDB54D335C7F1C71762D4E3AABAC00EEE53F2FE28EC4A5556BA8661C9BEE17A63" + + "0C56EECAC65C95269EF46348671731A1BE239E1F50FD18AD09FFA334140BE28E5120B972B103FD80" + + "739C1042E336ED393132C73FD86E7509EEE2052FD8D8FF668638215287BA46CD2122A48D3D4EF9BE" + + "B7238622304D878C94242371733AB95654E6C4C95C0D6D9DBA2DBCFE2C1B8F3FE7956E2349A00F86" + + "8F8162ABD6163FD9345179EC1DB1A2245B7C67204D34BAF099670F5202F49A4C3BDB657654CD2C0C" + + "1D6879460F1C9ABDC0073591FFC8288D174CFB391A26A5A3C90B7BFAE49D8A2E5585EFCFBA1C042E" + + "7655514A37061AA2CD121380E692F51176F6120B11EFB9191276FF771F0D8FABD4D02D9210388F10" + + "6B191A23B55E90BC243041CB5548C1B4455DB8D0C60DFFA43AFFE572203325DB7467A03F5A06DB3A" + + "FA763EC9F1172D74E2D0461F1226DED5D265077816CB7D2BC4C8785F6792DD20F5222CD66E2716D6" + + "45727397CDD3BEBF42F891A316E9F2AD2424C867DA324275C92BD30D98ABB55F9C5202B25F0613CE" + + "1B2BDDF07DD5469B568C2A77D979D0FF8969C19739B3DE80DB325190B470EF04459FC78BEF2EB649" + + "1BAC1CD2CFA1A340272FEE4D4C31EC8DCFC9C63E3AFD11F31369CE6078E1DD788D691A5F7EA3A771" + + "519733DF3DD39E87E6FD0CDE4853B35419A01AE2F547A6A5F36B7C9547A784F808A558C7EB62D13D" + + "0F546434FA58F129B5A7E813CF1D6AFFC8A53780CA1D67C6CC2A835589545BB155106ED87433C2FF" + + "860BD1B2AB2348BC17684805F52D6328ED960A04E9658B3C3EB50323641BB86C93B1A58DFB0E4864" + + "F1248489E5694738279A0D19EC632D00935CC74B2AAAE80D3656BE581B6D13BDDC93B7E919CD973E" + + "FD11EBFB1EEF07865506A433919B523BA5CDF2E0FF7B3496827D8426659CCF831FBACDF28D1722CC" + + "E410773E937F7CBD005A07F5C4B346FDB2577EF9B5DEC1AC30FBAFB436885C7D83DD541E9F207662" + + "D4E4EFA5CE191C24D6BD0B7E40C9D991D437B7D0A955F6154159768E0E081447D076DF5D625F547B" + + "1151560CC85D22366B58359E214D40F8C6052B3D74A638FEC3867838D002F5B98030867D41F94107" + + "781B5B1A60D22A2DFF6865F23570B09AA9A27FBF50A018A08E48BF34C150965DEEF09841AED11E97" + + "C9637852F9E39C76C0713E9E492EF6EB72518F5784459DEFA149A15ACFBA096B2593A8965F214EC3" + + "29050E1F50EE9886DFC08977DAF87BA60446581C128F3DE26136F8691D773BDB9D17FB662D7CB481" + + "6530A16B41A2358AF7182CC2B52ABA787E96E38C260EAE6E28227692073459D3A7BD2F6AF3B323C3" + + "E838A984D17C8B6A094688D8152A82A3485368CCC09D3D665B6FB3F90B37536393ADB4EF25478691" + + "9EC6F65285CBD7ED42609EA8AEB6FE3683A4A9B5BCD3DB666C799DA2A5C8D2E201224143848ADDEC" + + "00000000000000000000000000000000000000040C13181F273038"), + + new MLDsaNistTestCase( + nistTestCaseId: 154, + MLDsaAlgorithm.MLDsa87, + shouldPass: true, + publicKeyHex: + "E8ACB1814FF5F9C0C9EEB4A9ABAA8F2DA47DBF10B659A1156854423395077C088B55D9A66F5DD428" + + "8EE70680740A2A7B9475F21ABD332260565911A842DCD4B8DB23A2FEAF6305A0E614B08DC0B14A07" + + "D8976CEBEC645DF673DCCF0C5192A1CEBDC9B2CC3050A1305DF29F5C61FF66BB2D129D8714B89727" + + "735071B75E2B0F01D4276181BADA44CF4A570B2811A8C936882ABCE1E3105841F568218AB3BCB50D" + + "84CAFEE426DFAC05429A047670FEBF68A621BF6E3018811F57AA716CFEA1C35638104A7CC27FB905" + + "B1CE1DD8AC1007FC158F34EE6995DA79A79E6037E54A67263456505257CF3931C6F16E545A9A8DF4" + + "3167391C45F57EBD462CE7E96F6A9A736DE2AF8112D6D3DD6C4C11E5D71A7894C6FF8A1124DA24A2" + + "3694509ECFAC93961B93FBA4C7B784B4E713503F5845776228B20B44D06B87A3C57CD73333485A11" + + "3834313C3CB60A860B10685B0E2995ED70204735029A4B3F68E709B4AB2B5A5ACFCE496F843C7C99" + + "7B78B97CC42BD88D727CCB6182B8F285491791B06F24E71E72A9F2DEDD7995FD0EB66CE030A5FF19" + + "4160F4B0FAABC0C4CF6901DE3CC80A3D09534FE6EE01F14ACAD122559FDA7410DAA05441FE6BEB0C" + + "0B2828002B55BE828FB272F61B00E8AE0F58DC906BADA194CBF9860D5BC179969E2722523D50EA2F" + + "AED65A10409925E7056DA3264DC5067779AD8AD903C2C1FA8471E0AE7EEBF5EE3BE85133841A4DD8" + + "9CF280BA10969A42ABF44940A67AC47A1A3EC8B05466DF772ABE151D20B4E0BDFD742E650AE1AD26" + + "42669C4F28E2034D4C3E16F66F46259C88D3BC6ECC5A9725EBC2874464A46D9313CA8F5E5C8CDA28" + + "D1588BC19AC10BD5ECD00BACEBDC2E1F0268712E073FD6A20F0E6C047E30B01B99FEAD5EAEE6B90D" + + "8CBB45EA11C9C6F9C3FE3F491A3E6D1232F613E449A65EE83B766B361F3B579AFC8781716C355608" + + "56577157851D990D9434654489188E55AFCD3BCFFD82F98152E7D99BA2B068C7E22C11BCA3E039E1" + + "319A547B3AEFFAB84079621E1A9ACE3B385D2F49B0332872AB2683022A5784B13E20A2FB9DA450DF" + + "BB76D9097DD9622EEB93D2E6C59F1F339AE6C2EE534D2028D535E41B5BAAD9B0ECE1417461B34E32" + + "4099BA7463A256FCB5931988D7057DCA5A4E86FF22AB6495E2691B6808F323F4073AF777EC0DF99F" + + "CE3B228ED3F99CFF119DAADB482B4F3C6CBB5D3830F62BAD517559142C92FA52E4D3E3302123F54C" + + "225157D207E4203B8CF6AC90CF97DD55B731145DC66EF1C60EDD5A3D4AA53A86AC08DFA4BEF0C789" + + "C83134C17097E1E6DD12F41F20C7D1A04DBAB9B1B87D8960E484EFD9903DA59B7F868CDDCD2446DB" + + "22EE1770AD147A0DCBE3FE53B54C3B0FDEB41375ACEC1AB7A21D247C93CB46181B84EB961534AFC6" + + "110F97C869E9E2AF5AB671C7A641447F7FFFEA3AC84AF465D434DA7C6F0F8146893B95C540834943" + + "021DC761DDB0AAC799A139C1D1C35FB9EA5B3AC176F2B38194A6C9660071AD05CB7AB906BE9B6212" + + "5070A92DAE1FE799F54959B2F212B24248AFDA8D068E516E348642D1AA78DAB952553A2761145F10" + + "FD6CAA8C76B5C27D5A9DE29D5023D95D77C48FE8C983D30E895D7381B858B3163698B2581A277443" + + "1C671F703C31C53E4DB0A68A7EE5A33883DB8587C5EB2BA693C3839AA2D3B480F452E0F69348C763" + + "326581976EB3D48C8B9406A0C9356EAC5B22E0F983ADA7E463FF1CB58673A62D42FA56AD8EDD1839" + + "8489CB2AB62235D4887A6011F6D0ADC86505B1D1CE339323027FEBFED9D86FE56C5A164832BDE069" + + "2C793ACE70B6BA04391F95491E20EE25DB921A2D61326551AF4DA77D173EA0206EA4E8A6F97AF3DF" + + "649F1DE1DE31FF94737611C1738B07E6A1B40BB7A9269DDAC674230A466E076C8BE6D2A0CBFB8ECC" + + "9EE5386BE420F62B4B83CAFDA2FDA45F68A543F61E34A325E4B8081A90EAE1D0614B08A5E0E6BFC6" + + "78ECFED592EE225491DA863242470274D5885A1CB940C2BB719626F76FF79DD5A4D1BB5C3EBB3501" + + "3FE9A8C6D3FB73076AC789E1EBAC5C229D372E39DF518DE3D08740ED92BD94EFDDB7454274930439" + + "5BAAA7C5A4BAEC1D7751870CEB9C186655F5A4F67F195E7D5E62316E746BC519DFDD8F24DA9F527B" + + "D736DE084AF2666EF0B1FBBFD26A0E27BA16BCD31540B62794195CBFA7F47ABD006191E6FF67F4D2" + + "469FB72876AE6BDDA5C7EB5D31DE21BBE5AE9CC6439082602233F6E821D6AC902027FD1BBEABC7B8" + + "8A80C47D45ADF30D8CDEDE6FC5BB38C97F3915FAD97CE6D8010CD0B75024F638955B31CFB2B23FB7" + + "309B17D0225D45B44FF7A8DAA96105E3DAB1E039A1F424DE18B8F871360B9BF989DC7769B7BB898E" + + "29D190078C2CDA374A9888F40D82F692B9228063F489B99B710AD276BAF95992116266254BCB8AB8" + + "C7DBD7545468E354CB52FB29E7D599ED7511C74F8F217B76D48BC44925CFC7443CECF28A3E3D2A96" + + "3F034FFF75D27FA239699310C6230E3375FAA091B3FA05797442F7047E34F71754A198EC0FE39294" + + "82A05F138DB9DB98D6B85F7FE79E14390877821DED8B826F9B7F0D413CDE73C25F57845A9480F710" + + "B53F2A02DC9CFCBAEF09BEEE942BA57F0BF0656135E00B8B5766489DD65C179974C9522CD6CA146E" + + "D34A653C73981BEAD6A98732879FE4AFD6CDE124E2B6FAFCD602B1B3E61F737BA8C9CEA9A1658727" + + "4F51505F5A2BDC79A7FA90623882DB0CAE71461DB3CCFEA5E5CA9A53D10E2A11269DABDB9E6744B3" + + "5EAB629DE43AAA49D290B77C7AD7544B67D2456443400C908DB538A47662A8DF2DD0340146DEBC57" + + "97FBBFA4D86BDC30DDC8165E1C916C9200ACA7CE80B2988F75791F51B1A22F85DC616987ABFBA55C" + + "1E8FCD93F09365A76040C254DB031093858EFFC3E735E20B9328CB7409E396D4F9D353A49A57A36B" + + "98B3DAAF8DF5D27237C638B09E76017E3F742AF299F975CCC24D744CDE2A94C5191E6D193A3B189B" + + "0608A012AC3C055CA60186A23A5438C918294E68C884F20A3A13C2E89F23C501814FC9416962D58F" + + "703F2DBE0DB6E8BD051259E7D508684BD5083A47ACD9397EA50BB7B5111EFE6A9F112F7BBB19358B" + + "2DBF3CDC9BF7F288D75A24DDD44151ECCC5417FCEE70C11CD3249DC57D863A1F18C51A1B7360BC10" + + "83855DD9AD28EF026D4E09ACA199A2B47FDF0B3AA812506CE8FC195A4A3510E17607B4C3ABB4785C" + + "FE9CDACAF5AA81E96B9777FD5AC4EC484E27224A2EFB7256ED994FEAA8F64E43148594CFC0925971" + + "18C9D105C319594D784B973AACC726C65475111E07CB87D2AFCAC2DC927F598605D1A4DE76157A10" + + "D6D0532D71AF47E6A2F6794E00B12D621554D6F53E10B505CA359B81A069A5615FB169BDB3A6ADB4" + + "38F84B24E7E9ED3190358C594E384C7A09D623AFCA916474C8221B4179B326FD4975F55A112C6861" + + "EFC1A7C6E88E44864E9A3730D3346685289D9A4C821C48895EEF4391D7DE6CB3A357A9015078147C" + + "CEA97AEFEED45A90A639BA0451928302DAFDD702BA91F332DC81908E63E10035B940CFDC3557FEC9" + + "A7A47EE949AEC5784EDC1CD19475AADE2ECD162AADA1E9F5D207786524FA7EFA9F0588FEC7C4EC0F" + + "EF59FA4D72D6BF4157BA798BF56FBCEA67F1B925B3E0606D0649211845E5B621", + privateKeyHex: + "E8ACB1814FF5F9C0C9EEB4A9ABAA8F2DA47DBF10B659A1156854423395077C087AF263B94E17465F" + + "26C6A20547E836952B85BE3C4340B716BA07416663766850274CCD0072826BCAE89C93EF5307F1EC" + + "C8EF4C9A76D316B389CC698E477C5A993E74BD6FF02D32A418A64B5FEA8DF7E756CC2CC4CF1F3DBB" + + "E120289A4D01EA2F58121153A64D030485D10071E2B46503868D18124564A080DB9629A486855830" + + "86601862610090C1C6489140891800051C1041D34666D9106CA04461A4249182B645D9423122A224" + + "C1C0412382610302026028321AA7319B82705142001C3652024602A1C424E4B8201432705C326114" + + "C75041C24491848C1B004A5AA28D182192C2B60800491103898920C4840117849C48000B858C0A17" + + "4884A08162C62DD88629DC202D53388C4B3464D82268E4162A83A080C192240C07005A268C149549" + + "D2C644040285D4168888083012C40D9A820D830805494064E1C44483386823A1705906724A446814" + + "21119AC22120A3692000096002328C846103394C22426C92A4211AA168C0B02C54046D213244A4C6" + + "291C364281204E8A304880128150A86D83344AD4862C9C1089C80608502468E4946502A948990669" + + "59046D0436460BA150CCB44540B86D52300A089241D23246E3C6095AC485CC045123C361E0080918" + + "226111136084468163245248C2894B228C8A425122B7041B900983460ADCA6040842649384905908" + + "204B322C538650C19084E480906420251CC14059B24C22976C083944889689112740029040E23264" + + "0B413210084510008E9422320AA270038485E3A0800A3541041141D2B22DE2C07108A5901A8889D2" + + "086120171104156442104D22898D2300110A34451BB98109164E63B821A2386D8B284D1CB44C8214" + + "4248B46D44946D09190459186198268A5B026124010A1AA3248A26510C052943026AA14201919430" + + "E10031404289CB32882105600C19508B146A13C26162C225591050DA164C9CA2681B29121A44619B" + + "1624D43686440651E222625928904B086812239000172980402509325041148992060A240532C486" + + "84E29285923290D9842C24C36403031019A68993082C02254C524832A43488901282E21450111261" + + "D8C89090C28C2122704C98680A971000468D41C82021C72C91826D5B066E00970C1BA7691109329C" + + "28862216081CA38923866001297042B225C4B6451A258A590449D4002103426291B42C5244688212" + + "92A31470C10672CC088403A5110441245C020E13844990386000380CC8A80098A24C1B9168114280" + + "02C2880BB2494936481C492C1A252A19462119893018196E1C860CE3220E9AB80D014011222269C1" + + "848058046494380ECA126443421252168DC3128C43A42893844D43128C6298898A94094130804B00" + + "4101B18508388510C23023888D21092410184913954D60280581C431820889D0B024DCB80923414D" + + "08C0659CC80C03053001A469C418709C9489A31206DC480ED4C82DDCB464C0222590108051020423" + + "A9688C222603A15041B60D483042123092C31429A346288234652400861B10425118060B466DC346" + + "2088340212B368E23605504064142506902248C4A810902870C48885D2142E0A04329C060D1A132E" + + "D932468C483209214843C064D106688B3224C3C64C10C16000316482122C2030601A299112C20900" + + "17008A466823370AE2168624932841167143126A9C0410100240911652D9C651C0108A10C741CA22" + + "715AA03060A44D20C341A30482E3C6459B2410203482E3282922286D52160698882C180280832430" + + "48422482B20849A24CA1B6901906290A468811168224497202164D030748022252902824C4308DCC" + + "3208A0C8050C8581DA9668A02031A39660A286718CB600D8022C9106898406696040092044014480" + + "4022470619008E533045D9042541B6091205821B280E9CB40151A26840A430891821234882918209" + + "1A2132948409CB302023B66DA0942814A280C2A201083486A3146A00018D1C2430C40005D8926DCA" + + "2686E386319118120046829182684B10608C068A92C42418B1440383088BA82902192153482C2443" + + "0461088943060803320C21265154840161886C02159204A71143346918A66593462910B825221230" + + "103752C3247208946D81007108006C0CC8618B8481CBC460CCC06121431090126EE122260A004919" + + "A6850A492AD1C6200FBF4A3D8E199C022D5A10E4160FE3CBC4240BA5F82919CF40BDB1016340D08F" + + "D57380C1F6CA9C63E83736F01ACC9AC79D67BCFB7ED5B3FA076DCE7E467BBB80EBD6499D8414D591" + + "0C1B4D1A847862C8D0AE5B7CCD8FA0FC1387C0D84CFF275C5723BD6727C92D6895C350D8E804AE3B" + + "45A7D8D3EFBDFE430BC5D452B55556A171C6EC1448AF3F2B32CF030BD0331BEA378D50E9E5D3998B" + + "1A249FA3B00484B4FC9067075BCDDB628F3C74BE149222C403797A3F39DC298F99B3B2DCFF14ECA6" + + "58BB78B66975F264238A1B0C78D4B6CB5E420CCC494B850A592B3B568217FC2D60504EAA1851F8A7" + + "2B26A0AA8F7D81EAD697F5206B16352E02403977F4188B71226A874A99DF43F564471A1A28E6866B" + + "CBBAC415A47CBFA4343FE8B6070393A3EC799A335DF6B3DBEF8F1920FB1E37E314C09FEE763118F6" + + "309E259EF5E29FEE5710F09955157786392078B94CA341817DB5B4E8503AE2F9946132C5AAB071E5" + + "9068A8716B49CD0C1ACF1D7D5F1B3634BC09C0270D750AA0F84D70786AF8D1323BCA9C1F82F85681" + + "247A2A0E66782B83AA631FC2F63C8507CC52F1B22795A743E76AE7DCF28D2C4213DD9FC4C7876C19" + + "0F5C62332E6BD3B668B975B449DF4A3588FC205044C52A7DD5A783BDE38B4D4F9D41698339CF2E95" + + "9A9BB2FD80CB826B0F1EB05265297B862EADC72CF60216CC0E212F0055A3081B72F7259EAF9A2DA3" + + "54720D2B00824038B9538AEE11D94D937A5199A2552E4F21159842637678DC6915F932EB51B8C8BB" + + "422AD84023A3C663797315039D911409E9494DE11CBF28F3D2DCC012E809FC86CC6A947A35E9AEA5" + + "F92E118D0115C19DC63BA417E443E6288A57E35BBB54B0DA0D81B1104AC26D3878DD51714AEC7AFE" + + "36D5F0C89F35A94D0A1E64734C1CA18CF9E9E3A3E6A44E2208CD54FC67D6ACC9A904874673BABD38" + + "02F0C9D8CB513BD8410A2E46EDFCC19ED72501FECA743E2ADC81BD465BD626EE196F3829D792C449" + + "FD7817BD701FB91B5260294A5EAD2EF6C0B894091F383DF028F64270C7AB56A214EEE5E90A4072D4" + + "7BB13157165E032EF186E445464B63019032319BCBC4627C385F7D5C8323E7615EE610CACA458953" + + "661F4C5511392E010AEFDFFFFC7DB967265F02A34A338A50BA4D364E00F0D4C41909779EDF6B353E" + + "9EDC2ACC11AB23514E2A05609D2C98288D4369F81B5EBF7F48BCA8383BA0031AA2C53CBA997AE2BC" + + "F257FF35E2F85ED6368C1E9D33227A4A6A56CCBB4C3569C4318B4FB2472F70313D43BE0D0230A360" + + "1B7B924DE6BA6D71895CEEF397ACADA97AFAE49B6A5F64585D8EB9B68A0EC0D7D7E2882AED81C6F3" + + "AC95802D1FA9205C03701005545388D01A44E61799075495E9D8E68F6BA4FBCF2177C00B92A91771" + + "C75ECD6DB8ECD67AD69B391D97A0C6A11F24BC915D0A43CA1075AB7D691F7AB73B0E9AC6021D7AA5" + + "D6D53BD9C869B9FB98A1AA946436E96D423E31487256D7462A2DE073E4B5E2EFA9069144B6C9955B" + + "7C1288C68F94D29D00D541C293C418FB38C4FFB30017C377841381699EE43DC751B33C43EA03678A" + + "06BD875C08C10B3104FC1BFABB8DCB3BC95020EBCC0BD2B6B81173CCC3620E555C93AB6880690A14" + + "7A92FE87F28AB5CD73E4BC7074C69F77D653548D529AFFE81D613EE22906D6CFBB32E077924D1E5D" + + "3997D260403FCB071298336D4812A2CC4B807DDCB78E11ABBF36C8A198E5D8FC61BF9AC3DBC32E7B" + + "1EB0CE3DF6DCB86D3CD793BF0FD3FC0CC63BA40D9211A0405DF92AD947928831A04B0CF818D2CA61" + + "DA9B5FC1E7BC9141D51A76C326CA01B20E0AD94D1D3D013E3AC090A604BFDDCBD06A76F0B7B85061" + + "3B2C4543953B970FADA15E3FC7200108E021EA0BB80B2F25551027D7B391AEE012AC6C1B52E7EDE4" + + "6532F7E6D3D6812B0E9217D5EC24FF1EDEBBA7ABB25D1061F35DF8FDA322C169010E37DB42981EE7" + + "FF09F867ED81283ABDA89D9845F019FC7261741EEDAF7BA62C744F987E1F13047ABF3845FEFE607E" + + "4A65762FF4692963251F2C4C51901324457B404455A06CEC2DCDB543262F3414BCA9F0A4CF40C500" + + "EFDFC0F9E68EAE26998F4EAFBD0AF7161CD2B253A14E43D9C30027632FA6F186311309BEC8A6B6DA" + + "426072D2B487341AA212490BCFE0D12EDB00B1C4767070F86C6280A806D2E0FDA207BDB0576F51A1" + + "A2BB08207C64874A4F06E0F9B580C6299CED6A86F4B8D3CD9282CC4D783A1D94884F9FAD7909449A" + + "75B9039CBA08C18E057B6BBBBFE242383B66AEDD6C6D1B18ACA0DC74C819C3A2103E4C24D8F6AF61" + + "AB1BF4020E62EDF4F34599692D24499FC3DD510454F7A8D8AA23E6863B98AAFF4E645CB953072BEE" + + "BB8ABE23103F5DB6A9EE70D3565F7500A7CC08290885CCAF6CD85220D24FE23E6F5B0209DC6D7951" + + "E6E80C6D970CF4239C85DD5404C60C030785604D07994170B312877B21AF429696A83E69D078F2CA" + + "D5911F81CE516D642C923C7B6B1B45E2AFD4F547EE8A51B0EC2AD654AA27835454AF65D3AC0885E2" + + "660333D1714748F46C835619C11EC16A78545D5BE40AB5AB5B606C00CF125DED47D92190140990DB" + + "FF16EB6A8F2FD63C22E85DBC865D6B64DD0079F692A7E05278CB26DB9774CFF44354635B1E160074" + + "6A3AB85B35931DF813A5D1E53D6AB00ECE858F02A8C5D19FF161A516608E72F2E1B4CB3523ED3556" + + "C966A3A10642E082620307775D81D476365C484DFA7317CC0502F88E8D51F8A216274B4B33DE38C5" + + "EEB734BB6D2BE5349A7B165A6ED8BF5C3B1E360EE41B8D98A8D23AD532E8C9B1ACB0E223F4BA57D1" + + "059BC6376DA32A99DB1BA24346133D13E35B3D3ED10EBB5E7B41E1C3045619EE1FAA633E788500DC" + + "451CF23DE52CAFF2DBA52D9C545DB46461B023B81CBB5A9C839D1113E296E1D6C6940916951A380A" + + "956725F7BA7EBF43C020AAEABE7FB2618D04F78CBAB13B0F9A3637DB9B9586289E242B60A2E3E9E0" + + "082888675100DA43038C7FCD7137394F34AF484F8C916E2462ECE594728D250F9B8B6A41E1962917" + + "BA72634453D9CC58D6D051C7FA87F0937AEDA83EB6574EA3594550847402F1D8CBFA1A7474325B74" + + "23AB62516FF86C00AD14E67E2CDC858CD3482993D5F7FE925CA77EFE67D3FAFD8800B032C5C7E400" + + "E3208F7719EA1303538B17FA1F59B0E9040252E2C88FF517BE3752B5ACFDE0874F9FA7181B6E0D66" + + "DF2962871B42F38C6C57FBDEE2A4B288555283E86A64C6EECB006D9D3D31EC5049C5FB8C3BCC26D8" + + "5CC24D65992027F425D86D212E4FCCE71A993E1E999B336603ABF2C7FCD7985A51C3393107E7C40C" + + "CBB5AE51A2A0C90F6379A1F96DC01351E35A0A6B48B7E8EB1C52F94B3B7BF90AA666B70C7383C354" + + "9322EE6549473BD487FB744D521F9E6E9B275EFB043469D1E3592AD935C50D95D703759BAF2ADD8E" + + "8BEAD095BFF1B4C2948E334BB2F415F40874270205B36ECAB3273EF2F77D67DF6556164A57CC11FD" + + "33F88033B88D1BCFE93DC378717CDC8909C5892E35A17A3FC0ED94AC50F1329ED207ABAF9A652C97" + + "6A28E825A971908C434102EEF6A4C6F7C4394F421E96C33213003B72CF3956A244A33627BE511106" + + "50C26EC4E263A5E2553ED7A8FA5BFB79CB63E8253631E63FAA07772CC719494AB368958721DD9C47" + + "216C5D25DECB2970E2DDC38C47360FE61494E9A290A95688E5A71F2438EE8F802A2F6BF424ED4031" + + "A1BE76862E54579C84B5BF6570A725A35B717129C84B8049BD4CF88FD08776F73B0B7A80D51EE6C3" + + "994488FDFB45457BFA41376711624924940D39411F6CE615C6C982206F2A95EBDDA1D315250108AB" + + "7CDF5ED7E7A401BDBD0F6F057088B1BC4A65A7ED6A39D992693FA901D72C625FA03F1561006208B3" + + "D5E9DE79560DCE33459FD9EBCAECB66174338B577B7BBCD668BC530F2E136E2284DB114AB7B2924F" + + "A5316D025ADA736D9CC6049DD8FE27333CC9D3057F6CF672DA4CF0FEE7C59BAE64D027D36EAECE43" + + "766488AA7FE728237C1C6DE20BB5E64EB49D834027DDAAD8120B93646632C2F69FAFCC85C370552E" + + "CADBD11A564DA1A32321B8EBF1364FB132330C16681F3DA2D3F306B41A85638D147644CB89FE2E5C" + + "537740BAF7915DE123F9D67ACA89AD388959E4085DA16AD4A71413996382D1E39DE1A53A8F9CEEFE" + + "7AFACC9A8C93EEEBD92896B1EBE65853BA1DACCED81C232F9AEC709192BB7080E84400F5F32154EA" + + "DF1259FB3BD3B0F4761E5AE61EEFEF57B3E275162A0D71C0E479CCAD1D4F5B9AC9D3ED48EFC374F8" + + "BB6C81433F1E01BB758B78E95BFB5DBFF8D6F8B49C097679CA15BC3104B9E723010D0C4D79D6283C" + + "2BAFDF2FF4C27457652F39B7E2B5A7E6B9E3D248163A04D972F6BF2857E9810D48C303DCA17F98D5" + + "84914D3B6D194D9FE1DC7576D2C8C7E5EE3975F31DD988DE222B71385515D5A9A043A9A1B090B5DA" + + "270B14B4B7D59C2732F183E1F2669DD88F3711EFB179BE43C4522D6BABDAF348EDC1A77E85D15584" + + "122F6F04CEE2146CAC4D311AEB7AC7A7AB960D0205D13E95C8A80E5905EFAF8EE13324C047B6E46C" + + "DB8E0BD16C3F49536C5E28A68E512FD336F065961E4CC338D0CD9534599BFBD119F5D51F35F6F5E1" + + "ED122F9AFFCBA7381B96D1CF6EB8DF44E0774E99FEE5EE359FF61DA7718CEE3444EA3D7C5C30F488" + + "CC07EE12D36B2C2673484688F8BF3C6C", + muHex: + "D61E59F4E32A526160A9F28B3AEF8C780F89344BEE5C5A5DED47D276A6508B21C154A80DDF77D8D4" + + "C425EB7546F8F30CF29116D1885DBC7E2C386BBCFF17864B", + signatureHex: + "EFC22456E18CE74F4178BD648F62A2314417B3E73DAFC071C0DAA307EDBD97D5D8345C651EED8F9E" + + "9BE76F6EC4BBC5DF5CB2914D8E9606D8E869C254018FB2D04EBC47A2B0DF11E4C24AF05DE5029034" + + "FA9C82A0A6C52AE62D073632F76D0C4FDCD473CD415E8DA42D7F0ACDB30B4960F3B76F83D1DEF25B" + + "1DDAF83F90D8FFF644873F464EDABCA017860CAEE112F2D43BF91F1A00D1CEFAD2A99FDF379A1EE2" + + "CBA47E4617C3D0FBFEE860A9D09C2F451497C55BE55860BAE2E615AFD4DBEE7BFBF1B3E1AF3497B9" + + "EC2AC466E02651D0FDC5EC7B337A05CF4520DFC0C3F87DA85275E0A6AB688CC384D40C718E5E64AC" + + "535A7FF9358F0A4863649CD3A280B320CF4DAFA0BBD9B25ADB642E1F88FA04AC3AA1C1CD6ECA41F2" + + "7FF2DD66D89FCE725F375E7DE3398D678AC6C72178BF8932DC26F4758A91DA6DA6E990185440CC31" + + "387CE0FE265EFCB0529745DD0DA73723AABAFB95E2EAED14E76A013A7B8DBC273FDA23B6246CC549" + + "F6A04FAFE960D6341EE12AD2AE816A305909A60B3B608B0BD0E6CC1C9AAA2E7732BD79A13E44356A" + + "C01CCAB96F9C9A7E14EE523966845ECA9A40B381FB1E3156B417CED113E54CB589B18A11CE270A3E" + + "B975C5B36F40A509E2A55DF45913DE8AF78976A4D38F69ABE7C6277FF0CC92CD5E0D555EB05473C1" + + "81B01AEB4417EA02E4DFBAB55EF4BE36395D74EF60B903F5E5D96DE0FD8789CFC7693AEA083F6032" + + "60D0A6F7B88851AB02FF2B0D9AA759AE2CFAEC4B21DCDEDA3900E8B46ED6DDC60E01D083645852E2" + + "263C75D2DFD4A91E8F3486901C0A22D29EFCC36496C076D2416FB405BB1F7DE4C413F5FC39F3E40B" + + "2674650A20936C5AE5C19B56212DD0A101129AF7A2641D1F1D2E33A77479B4A4DB2C1D585E4B269B" + + "F5F7F6CA0FE509D5235ED485DC0C892B5DA470A7369491D87F4DFE445B0363525C871EE42E44A177" + + "45AEF585AD9DA852500218F7675CBDC27CBD63B4ACB6523C3BFC6EF145D39D13BE5431EA97FD75DF" + + "DA1E6A4ABDB8F8DA3003F3E022DF462B173AB55BFAF09DBD4525090CEAB735C65E27AEFF36192B69" + + "876BCD945E5416C219CB3CBFC9E742F06A0313CF81E0A012B822EFA31714BAC2ADC482E85A8CD3FB" + + "BC005854EFD99E657FF6BCDA1525A6E3EFEA71E6309FF06286C08DEE1AB6318A766777356FF238B5" + + "DAB342FA6916F6A787E6E5BF6058D00DD241159B5673C4B3E2C347D8607757E56648463F49744EC7" + + "05178C85D7279BD69CFD0AE47C614639FA1993F37F0C01D24891D11DE0B6A7C46A4995427FA885AB" + + "51EA5E3AB54AD62B0FD2A2B8840F3FD917862564390CCBE957FE5B7627D3AF81379E1606ED9C3C6B" + + "56C03768FCB645A31753F7A71410F4DD99228C3EA657A34A7D70639B1C3584E9E611D398235B8ABA" + + "31E511180619D602AA5149D13E86C763A5A6792E0ECD0E0990CF0C54356300BB65EA8C8BF5765E42" + + "0E7C6499D3ECEBD3D1B21167E349F218D1DE310678A072380240B71D6D6367381483CBABBA896312" + + "93CC65AAB0773A81AA639ECD4D95618D8FC46A456F6982F638B6BD5A9716760297DCED33179DA566" + + "F0ABE34B6AF70421C87BD6FA620929A62D4BEED3629208431368F9326418D20B2C1EC99250377F7B" + + "958A5601FAB8BA7D702060B231FC603AAF60A9E6828DCDB0A15E950577AFD53E76A1F600163CFCAC" + + "547C1EE670EC5A556EE67F1C40697A3E3B352F54043BF13F18FF6E071F80B22A293B658E44685596" + + "D6DAF08A0E6106F67203277CA7159BFFF8079BF080D6B955F835F080CCACCDA282447F90534B6E6C" + + "AC85910EA202DE1661257C3487B5ECA31E149A727EC612C5F6DBBEA1E2A3A6F4185977DF84FAB8CE" + + "7A97AC3D0DCE0F18776C88B8FC4A03B6F45375CB227580469FF7FE05BF22F37693AEC42500C575F4" + + "F104D20E3D7A8710C7A937D6F24140DD0A09D92291B81A87CEE0951B61494058F65F0FD2F0984C0E" + + "2FFAA534D3C7C86EC20945B2E4A2B5D7FC919BCF8EEEB553B2DCAC2951F59B0141C9C7AE7F067FC7" + + "395784BA1860D02CD7A953554DC13540B23D5B90BE181E7C7833A68AAB6ACE9E4471304414F6C41E" + + "474977882FC35D81B1E73F313D19914B493CC1A681D23FC8036CB77793DD9F91E7CFC8C1F68E8758" + + "A5D5B5F626FA682F41C76B781FBDEE8F3B276D7134EE6398B3F63C4B0C2018255C7C293417CDDDA1" + + "EC1AB996D1F6BE0E42997801FCA60F4671B514E24743FBEB724133B2990AC8A4408D9FCB0D6B5627" + + "A499DF9A97C9C7BB3297591598B924362B758A049B2B5AAE7EA35179835F52FAFDE43B9434645B8D" + + "D11E411B60B99D228CE5FE50DF1711D8157AA86CC7A4E75F23B066D78240DA0BA90FDCB66B5CAFFF" + + "F8152A67E87F871BFC10611F7421C29F8B8B79D1FA3BE2DAE5A1C375A48BBB49D0FC19D7DA5234C4" + + "0410D8BBCA1235C5FB6B919A87BED6B09885DB192327D354B4E25861F5A2A00DAD3DB0DB65BA1BBE" + + "1B64299B859C766F9A1659DC90532A790F439D821B77830E4F26295E79819D9A0737B883331A17D3" + + "FC72C1B94AF6E7B2155DB77F4E68E851FB4EB239415BCEC4D63C09BC69B80E311B09C57C6BD4D32F" + + "31BCC577AC1A2844C39A88FCBA18F0B037B8BA7D5B3018B74135035C86EEFB7A482A3786DED07C33" + + "0E7FFA42209AA1CADBE782E00DABAA083D9C38D2CC66D306BC92A983EBA11804F6CA43155FD5D171" + + "F3C32C7982B321EE0CE8F8A0B6B395CCA10AFCF4B577D68A8E88A2B1BFBED7A4F332F64011B66419" + + "2BB1760C0D801A597BE93D1818C2F1AF0123130E2D1EA03F7712EEF06BCFFFC5554614945CF67862" + + "88EFEE8B687A9C892862EE120D6E5FED787AEC4C8F81D0C3D2A6A8E41BD85666E9E877566A8DDDCC" + + "9E7BE3155A406B1D8AF9727DEEC38633372FF82A7C9BF4007EE908549BA0D5268F7AA6391D54AAB6" + + "94D9F79236826B57BCE4E2663D3DA2838527ED8DAB473ECD9D48D0CD00D6B460E07DDC058CA8334B" + + "9BF11A6ADAC915A1F9A25F3C64270E4B599D913B0517C716CB8AAA89DA61EB95DDB1FD909710733D" + + "C79DB1F5015FE65D359BFC7D26E4FD2FB017D57E19791DF1C01144C7FFDA74BEB0F85361967EF11E" + + "5A04938F98EA053D54D571D787F7D5B000623545E43E434ECDBBAA0819134CD1C231B9F85E4FAE4D" + + "76196F78AB9CA4EAEB08778CE33500E22950F1B83A0B782F8D994DE63112051D648BF69802470831" + + "055289C6A26A1E8157ABFB64F4EF2F8A37B2F4B41379E79E468EB3502880ABE0F47D5D118099C40B" + + "8703CA971100F65D7A161A5AE932C907BDDA25146B0066FFE0955C628E38426F2B1CCAF089F808D7" + + "AD0FE3D60DE731E81012364662FB066F7413A8F253D5B0DCAB4A167B0A59F4B94549288F7374AF28" + + "9F2BA20630502E363EAD66479ABE8F17937B50431D877241580F6B50CBA67FEE0A22AE86641AFA4C" + + "D7C22AB6BA8C03FEB57611D6983FED20ECD7DE24F052F76F575FBE7D1927B48AD8C8664ACD5F9514" + + "BC94E68CF8B56D40722E27B06FFAA94C2CFFF6CDD24DFDC2C4A8B8B731ABD052A07ED918951F4731" + + "D84718F9D55C6040A799DC9123FDD707951A2D11003B628A3A73166948011C52F354885B0AECB08B" + + "AD6B74E39EDF0CA662DCE7BAAFDE92B406C6A9D3EB9F8DE233B810ECE3A51D407774159565E685E6" + + "BA620901EC16DCAD1D3BADB1B51FF662F71DFA53C5E3AB862471E221E39B44268F64B9A0E777C51C" + + "CCCB3599E11AAFFD665737549506AF2F0CD64EF933DD36F701DE6A6EBB5C8753AEFB8804ED597EF6" + + "AB223CDD321FDD7C97DD65D1A6AA404FFB98FD93027C1B7C10D720F45639218504329F1E529A06DC" + + "21C92212F88F3718E3086B7B9D44FEF53B8128175A72C77517B66073BA0D36C7DC4318263ED9E235" + + "02BE2FBA1E9E6E4350C8BBA7CA17164FF2130123E0A09A2D151CB259867D65874E473878784D300B" + + "D9282BEE1B54D229FEF2CDA8AF306232B78374F367AE54919E3544B1078A886718560ED8D6BAB437" + + "09D5AFEA7E5F79CA5E3FC48B9BADC535C7DA7081661347AE869031A2DACA0619A44D8060B45FC1D5" + + "9B7D2E923EF874ED81BB4FA81C6E93D5993A4D1B2F58E3912948633FC661568DADD600444A4DC161" + + "9F1EED37D87BEBE02E909DD0DFE8E527CB51B5E9D933D7EFDA1B3A1E511A6F9482922B7C0BCCD109" + + "2A47BB9A555C94723B2F794E34881A254D3D24E228D109261756D68B597B49EB77EE3300681AC13C" + + "A5939F124C99C3037BC1122A20CBDD947B9799DCF090A7202B29C06FA0700B863A742634A3A0A790" + + "8E6F5EC3B7684A1727DB42ED03D562968A8E14141902044501CFD45A833972116C1F421280EA9954" + + "61E6947977B98CBEAD0F69A855F9873F0EB0336A5A40E8F81399A9107892D135D16CB4A1B146F3D2" + + "5ED6D007BD8234D710332F787D31390F8352ABE06C0F1DD47E4FCACB3B8202C518D23D7336B9DEB3" + + "06AD43298F21BFCB795796ED39B192A92F7AA44F7A0DB4C3C3ACE4E27BF631700DA3A97497B4E409" + + "46BE4A6B505F4513CF013DA81D61B459A5362FA73502583EE33237D50F77F2BD7401D1C09F8AEE96" + + "A61404417D575FBC39145B8A88751B294D91A39D589735B89A51C0EBA3D0C1D2613FE595D9EA74A7" + + "6D7EE238D48BC5BA5CE83E35E4F1CC7D1D181966543275A23BA2FC0C36C56719420303B0390D3984" + + "877E66C28086A2B580DB71B5B4DD1429D2841A7234ABE04D68D5FBACC6B007FF3885382E2E60F0A0" + + "C834D78D97B5DDB2CB06FD0BDF91D32CACC7983133909FE56E33732064FDF85396130FD308BA2014" + + "0A687985087C07B5EDD542D6143E36E7375C19D346DC634184B7D7024372EC2362BEE141A62E57A4" + + "18902E4DDEDBF011A3321293A097C3521FCD542CD37158B0E536AE83B6366FA93F748757DE7EE020" + + "29671784406F929B1CCDAE8F514A1A4B95296598EF94B4C79163441533715314D03FEC9B937050C0" + + "74674B2378DE29C5B8134080BFF66AE8DFC2D093F8E3BD995A34092AE8C508C2693735438B16EA9E" + + "D326EBE051770242DA3E3A3C50D298EC9F19290AC9CD26139426252E6063958502372B4D7923E952" + + "3587DF1F195B0F232DED898DF6EBDEBF127687B90EE9551B893C283DB9B22CCD21C13BDF3AB65A8E" + + "87F316272A7BF4EC493A6E84A07F36FF6212B8D233871039D01E92FA7C2693529B2A82EE27681F89" + + "71EA47FC333A1AA60F6A0FDD536CE9EC3509A3BD1C7AFB86F16C8A43E9380803F70C2AAB878ECDF8" + + "D0042D1BDF768689C4B41D3D6B26D116098F19416A3D20009E5A05C14D0A17C48671BE35B2429679" + + "D418C64FF2E49AED6FA4BE1F7353274C527B69BC87FA3FA20CEB5222D34167BB8CF9A6DB381399CC" + + "914288C5697DDDD00EDAD4AC0D821184439E9EB9347F0268539BE456868EA09570B30DBE5AB040EF" + + "78DC9BA1770B2B9361E15F9DACAF10F908D92A61B529C1231238615E6E2B594E248D3A9795305D49" + + "7C9E926FF6EC85D32CF1B60A493A9F9ADFB5FAAF77B0FAE509BBA23A42E5BC7A5DD80BEC795F2BA3" + + "FED1DC2417B5F202F14D79751AFED7C782AFDDA2EB7CE61E9BD8D1B8E7512873B86DD6CCAA1BB93C" + + "B5B6DB9B9AB472E3EFC52998080B57BBEA270E8C3AFBFE3B7A074C0D0BCA8AD4EB8C83E6F34F94FC" + + "0BAAAC2B55DE9A95E1FD997CDF35356F8C2AFB339BCCF1A3D08877748494709BBBB0FFBCE0046BFD" + + "60882D4ABB5EFDBE888ED5E6B0842F481835D3768EEC003C8924B651FB1DBF3191852F2A82A6E9E0" + + "14EC81D1E30F7AA495CAD78B9E4B0D8F78B9C2BDC22664F1B340ABFB338951762CD04439A6BCF753" + + "1EA09D7B443BC8246D00929CA763F09C1E633E72C8E042927733189B165FDEE5C532AA43A6139DE3" + + "76A683877D5C8BA21888B3C5112096EB81D858EDDDF82E176E0C51814065AA2054D8AF231C711130" + + "7FAD6C8149CA0874233A90253560ED99974E4EAB88280930825F445F9AF23524B80F9BFBF27611A7" + + "DC4A7D49C24208E7B7942DF5432AC55A2F874AEC6B7D20118AAE59D41D2C582F5FC9D2121D71E20E" + + "418DBAB696E150EF1005CA610EE202348E2001A6F1118E8CF6B7B10DE99BF8CF33142FB25BD0E1E5" + + "B32F8839C3A546C8D2B98E5FF93E5194D98D9F6EA934E7EA04E7F191056570F0746C3A5BFDB6B6EE" + + "CBB32F30AAB343B6326BF0624F6FC2BA38FAB736B918CB3C9DAF462A30F0CF6332BC0DA47DBA9224" + + "D9AE735CDE986CC8F423F75F3CECDB93C9FE58812AAC2BE09A66493F3F116580B4BB229B2E1E61EE" + + "0D5AE2D4A8C621EAC8E24E64760CEC64B4E24013E4F6CDC50A8AE6775E66316E607592880A902037" + + "4D59AD617D5516383675CAD12B3B7B22047D3649DE61F3F1C7CF5CA481918112FD4ED6BEA9AB32A5" + + "4CCF8C422C827CA0BA70E2E20F338B0E63A34D9A9616F09F0B0D30525B6886A2ACB7CCD7F84880BF" + + "E8F30C0F286C95A5B0D2D401062C30546D989FB9E8F6010254B2BCCDDEE6133A8183CAD2FE29405F" + + "7EE3020B1C3F51667B85DAF3000000000000000D121B262E353A44"), ]; internal static byte[] IetfMLDsa_Pfx_Pbes1 => field ??= Convert.FromBase64String( diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.cs index 72ffbef169263a..71bd6dfc64e065 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/ImportExport.cs @@ -66,7 +66,7 @@ public static void PaddedExport() // DP is the most likely to fail, the rest just otherwise ensure that Export // isn't losing data. - AssertKeyEquals(diminishedDPParameters, exported); + RSATestHelpers.AssertKeyEquals(diminishedDPParameters, exported); } [Fact] @@ -94,7 +94,7 @@ public static void LargeKeyImportExport() exported = rsa.ExportParameters(true); - AssertKeyEquals(imported, exported); + RSATestHelpers.AssertKeyEquals(imported, exported); } } @@ -119,7 +119,7 @@ public static void UnusualExponentImportExport() // Exponent is the most likely to fail, the rest just otherwise ensure that Export // isn't losing data. - AssertKeyEquals(unusualExponentParameters, exported); + RSATestHelpers.AssertKeyEquals(unusualExponentParameters, exported); } [Fact] @@ -136,7 +136,7 @@ public static void ImportExport1032() exportedPublic = rsa.ExportParameters(false); } - AssertKeyEquals(imported, exported); + RSATestHelpers.AssertKeyEquals(imported, exported); Assert.Equal(exportedPublic.Modulus, imported.Modulus); Assert.Equal(exportedPublic.Exponent, imported.Exponent); @@ -169,7 +169,7 @@ public static void ImportReset() Assert.Equal(imported.Modulus.Length * 8, rsa.KeySize); exported = rsa.ExportParameters(true); - AssertKeyEquals(imported, exported); + RSATestHelpers.AssertKeyEquals(imported, exported); } } @@ -207,18 +207,18 @@ public static void MultiExport() RSAParameters exportedPrivate3 = rsa.ExportParameters(true); RSAParameters exportedPublic3 = rsa.ExportParameters(false); - AssertKeyEquals(imported, exportedPrivate); + RSATestHelpers.AssertKeyEquals(imported, exportedPrivate); Assert.Equal(imported.Modulus, exportedPublic.Modulus); Assert.Equal(imported.Exponent, exportedPublic.Exponent); Assert.Null(exportedPublic.D); ValidateParameters(ref exportedPublic); - AssertKeyEquals(exportedPrivate, exportedPrivate2); - AssertKeyEquals(exportedPrivate, exportedPrivate3); + RSATestHelpers.AssertKeyEquals(exportedPrivate, exportedPrivate2); + RSATestHelpers.AssertKeyEquals(exportedPrivate, exportedPrivate3); - AssertKeyEquals(exportedPublic, exportedPublic2); - AssertKeyEquals(exportedPublic, exportedPublic3); + RSATestHelpers.AssertKeyEquals(exportedPublic, exportedPublic2); + RSATestHelpers.AssertKeyEquals(exportedPublic, exportedPublic3); } } @@ -327,34 +327,6 @@ public static void ImportZeroModulus(bool includePrivateParameters) Assert.ThrowsAny(() => RSAFactory.Create(zeroModulus)); } - internal static void AssertKeyEquals(in RSAParameters expected, in RSAParameters actual) - { - Assert.Equal(expected.Modulus, actual.Modulus); - Assert.Equal(expected.Exponent, actual.Exponent); - - Assert.Equal(expected.P, actual.P); - Assert.Equal(expected.DP, actual.DP); - Assert.Equal(expected.Q, actual.Q); - Assert.Equal(expected.DQ, actual.DQ); - Assert.Equal(expected.InverseQ, actual.InverseQ); - - if (expected.D == null) - { - Assert.Null(actual.D); - } - else - { - Assert.NotNull(actual.D); - - // If the value matched expected, take that as valid and shortcut the math. - // If it didn't, we'll test that the value is at least legal. - if (!expected.D.SequenceEqual(actual.D)) - { - VerifyDValue(actual); - } - } - } - internal static void ValidateParameters(ref RSAParameters rsaParams) { Assert.NotNull(rsaParams.Modulus); @@ -393,56 +365,6 @@ internal static RSAParameters MakePublic(in RSAParameters rsaParams) }; } - private static void VerifyDValue(in RSAParameters rsaParams) - { - if (rsaParams.P == null) - { - return; - } - - // Verify that the formula (D * E) % LCM(p - 1, q - 1) == 1 - // is true. - // - // This is NOT the same as saying D = ModInv(E, LCM(p - 1, q - 1)), - // because D = ModInv(E, (p - 1) * (q - 1)) is a valid choice, but will - // still work through this formula. - BigInteger p = PositiveBigInteger(rsaParams.P); - BigInteger q = PositiveBigInteger(rsaParams.Q); - BigInteger e = PositiveBigInteger(rsaParams.Exponent); - BigInteger d = PositiveBigInteger(rsaParams.D); - - BigInteger lambda = LeastCommonMultiple(p - 1, q - 1); - - BigInteger modProduct = (d * e) % lambda; - Assert.Equal(BigInteger.One, modProduct); - } - - private static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b) - { - BigInteger gcd = BigInteger.GreatestCommonDivisor(a, b); - return BigInteger.Abs(a) / gcd * BigInteger.Abs(b); - } - - private static BigInteger PositiveBigInteger(byte[] bigEndianBytes) - { - byte[] littleEndianBytes; - - if (bigEndianBytes[0] >= 0x80) - { - // Insert a padding 00 byte so the number is treated as positive. - littleEndianBytes = new byte[bigEndianBytes.Length + 1]; - Buffer.BlockCopy(bigEndianBytes, 0, littleEndianBytes, 1, bigEndianBytes.Length); - } - else - { - littleEndianBytes = (byte[])bigEndianBytes.Clone(); - - } - - Array.Reverse(littleEndianBytes); - return new BigInteger(littleEndianBytes); - } - private static bool TestRsa16384() { try diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/KeyGeneration.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/KeyGeneration.cs index 601118c17bd01c..f69cf0c1ec5fd9 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/KeyGeneration.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/KeyGeneration.cs @@ -8,13 +8,13 @@ namespace System.Security.Cryptography.Rsa.Tests [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public class KeyGeneration { - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotAzureLinux))] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotSymCryptOpenSsl))] public static void GenerateMinKey() { GenerateKey(rsa => GetMin(rsa.LegalKeySizes)); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotAzureLinux))] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotSymCryptOpenSsl))] public static void GenerateSecondMinKey() { GenerateKey(rsa => GetSecondMin(rsa.LegalKeySizes)); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAFactoryTests.cs new file mode 100644 index 00000000000000..f08a584709aa9e --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAFactoryTests.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Security.Cryptography.Rsa.Tests +{ + [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] + public static class RSAFactoryTests + { + [Fact] + public static void RSACreateDefault_Equals_SameInstance() + { + using RSA rsa = RSAFactory.Create(); + AssertExtensions.TrueExpression(rsa.Equals(rsa)); + } + + [Fact] + public static void RSACreateKeySize_Equals_SameInstance() + { + using RSA rsa = RSAFactory.Create(2048); + AssertExtensions.TrueExpression(rsa.Equals(rsa)); + } + + [Fact] + public static void RSACreateParameters_Equals_SameInstance() + { + using RSA rsa = RSAFactory.Create(TestData.RSA2048Params); + AssertExtensions.TrueExpression(rsa.Equals(rsa)); + } + + [Fact] + public static void RSACreateParameters_Equals_DifferentInstance_FalseForSameKeyMaterial() + { + using RSA rsa1 = RSAFactory.Create(TestData.RSA2048Params); + using RSA rsa2 = RSAFactory.Create(TestData.RSA2048Params); + AssertExtensions.FalseExpression(rsa1.Equals(rsa2)); + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs index daa175dda47a93..6ac8f53aa78385 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs @@ -1454,7 +1454,7 @@ private static void ReadWriteKey( arrayExport = writeArrayFunc(rsa); RSAParameters rsaParameters = rsa.ExportParameters(isPrivateKey); - ImportExport.AssertKeyEquals(expected, rsaParameters); + RSATestHelpers.AssertKeyEquals(expected, rsaParameters); } // Public key formats are stable. @@ -1478,7 +1478,7 @@ private static void ReadWriteKey( Assert.Equal(arrayExport.Length, bytesRead); RSAParameters rsaParameters = rsa.ExportParameters(isPrivateKey); - ImportExport.AssertKeyEquals(expected, rsaParameters); + RSATestHelpers.AssertKeyEquals(expected, rsaParameters); Assert.False( writeSpanFunc(rsa, Span.Empty, out int bytesWritten), diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyPemTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyPemTests.cs index 27438e93d36e6b..1ef844ac1d0890 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyPemTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyPemTests.cs @@ -44,7 +44,7 @@ public static void ImportFromPem_RSAPrivateKey_Simple() rsa.ImportFromPem(pem); RSAParameters rsaParameters = rsa.ExportParameters(true); - ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); + RSATestHelpers.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); } } @@ -68,7 +68,7 @@ public static void ImportFromPem_Pkcs8UnEncrypted_Simple() rsa.ImportFromPem(pem); RSAParameters rsaParameters = rsa.ExportParameters(true); - ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); + RSATestHelpers.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); } } @@ -97,7 +97,7 @@ public static void ImportFromPem_Pkcs8UnEncrypted_UnrelatedAlgorithmIsIgnored() rsa.ImportFromPem(pem); RSAParameters rsaParameters = rsa.ExportParameters(true); - ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); + RSATestHelpers.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); } } @@ -114,7 +114,7 @@ public static void ImportFromPem_SubjectPublicKeyInfo_Simple() rsa.ImportFromPem(pem); RSAParameters rsaParameters = rsa.ExportParameters(false); - ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters.ToPublic(), rsaParameters); + RSATestHelpers.AssertKeyEquals(TestData.DiminishedDPParameters.ToPublic(), rsaParameters); } } @@ -136,7 +136,7 @@ public static void ImportFromPem_SubjectPublicKeyInfo_IgnoresUnrelatedAlgorithm( rsa.ImportFromPem(pem); RSAParameters rsaParameters = rsa.ExportParameters(false); - ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters.ToPublic(), rsaParameters); + RSATestHelpers.AssertKeyEquals(TestData.DiminishedDPParameters.ToPublic(), rsaParameters); } } @@ -154,7 +154,7 @@ public static void ImportFromPem_RSAPublicKey_Simple() rsa.ImportFromPem(pem); RSAParameters rsaParameters = rsa.ExportParameters(false); - ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters.ToPublic(), rsaParameters); + RSATestHelpers.AssertKeyEquals(TestData.DiminishedDPParameters.ToPublic(), rsaParameters); } } @@ -191,7 +191,7 @@ public static void ImportFromPem_RSAPrivateKey_PrecedingUnrelatedPem() rsa.ImportFromPem(pem); RSAParameters rsaParameters = rsa.ExportParameters(true); - ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); + RSATestHelpers.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); } } @@ -216,7 +216,7 @@ public static void ImportFromPem_RSAPrivateKey_PrecedingMalformedPem() rsa.ImportFromPem(pem); RSAParameters rsaParameters = rsa.ExportParameters(true); - ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); + RSATestHelpers.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); } } @@ -243,7 +243,7 @@ public static void ImportFromPem_RSAPrivateKey_IgnoresOtherAlgorithms() rsa.ImportFromPem(pem); RSAParameters rsaParameters = rsa.ExportParameters(true); - ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); + RSATestHelpers.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); } } @@ -403,7 +403,7 @@ public static void ImportFromEncryptedPem_Pkcs8Encrypted_Char_Simple() rsa.ImportFromEncryptedPem(pem, (ReadOnlySpan)"test"); RSAParameters rsaParameters = rsa.ExportParameters(true); - ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); + RSATestHelpers.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); } } @@ -428,7 +428,7 @@ public static void ImportFromEncryptedPem_Pkcs8Encrypted_Byte_Simple() rsa.ImportFromEncryptedPem(pem, "test"u8); RSAParameters rsaParameters = rsa.ExportParameters(true); - ImportExport.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); + RSATestHelpers.AssertKeyEquals(TestData.DiminishedDPParameters, rsaParameters); } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSATestHelpers.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSATestHelpers.cs new file mode 100644 index 00000000000000..23568417c5f00f --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSATestHelpers.cs @@ -0,0 +1,89 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Numerics; +using Xunit; + +namespace System.Security.Cryptography.Rsa.Tests +{ + public class RSATestHelpers + { + internal static void AssertKeyEquals(in RSAParameters expected, in RSAParameters actual) + { + Assert.Equal(expected.Modulus, actual.Modulus); + Assert.Equal(expected.Exponent, actual.Exponent); + + Assert.Equal(expected.P, actual.P); + Assert.Equal(expected.DP, actual.DP); + Assert.Equal(expected.Q, actual.Q); + Assert.Equal(expected.DQ, actual.DQ); + Assert.Equal(expected.InverseQ, actual.InverseQ); + + if (expected.D == null) + { + Assert.Null(actual.D); + } + else + { + Assert.NotNull(actual.D); + + // If the value matched expected, take that as valid and shortcut the math. + // If it didn't, we'll test that the value is at least legal. + if (!expected.D.SequenceEqual(actual.D)) + { + VerifyDValue(actual); + } + } + } + + private static void VerifyDValue(in RSAParameters rsaParams) + { + if (rsaParams.P == null) + { + return; + } + + // Verify that the formula (D * E) % LCM(p - 1, q - 1) == 1 + // is true. + // + // This is NOT the same as saying D = ModInv(E, LCM(p - 1, q - 1)), + // because D = ModInv(E, (p - 1) * (q - 1)) is a valid choice, but will + // still work through this formula. + BigInteger p = PositiveBigInteger(rsaParams.P); + BigInteger q = PositiveBigInteger(rsaParams.Q); + BigInteger e = PositiveBigInteger(rsaParams.Exponent); + BigInteger d = PositiveBigInteger(rsaParams.D); + + BigInteger lambda = LeastCommonMultiple(p - 1, q - 1); + + BigInteger modProduct = (d * e) % lambda; + Assert.Equal(BigInteger.One, modProduct); + } + + private static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b) + { + BigInteger gcd = BigInteger.GreatestCommonDivisor(a, b); + return BigInteger.Abs(a) / gcd * BigInteger.Abs(b); + } + + private static BigInteger PositiveBigInteger(byte[] bigEndianBytes) + { + byte[] littleEndianBytes; + + if (bigEndianBytes[0] >= 0x80) + { + // Insert a padding 00 byte so the number is treated as positive. + littleEndianBytes = new byte[bigEndianBytes.Length + 1]; + Buffer.BlockCopy(bigEndianBytes, 0, littleEndianBytes, 1, bigEndianBytes.Length); + } + else + { + littleEndianBytes = (byte[])bigEndianBytes.Clone(); + + } + + Array.Reverse(littleEndianBytes); + return new BigInteger(littleEndianBytes); + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAXml.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAXml.cs index 666f9bea3c4095..69389f2adef05d 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAXml.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAXml.cs @@ -996,15 +996,15 @@ public static void FromToXml() { rsaPub.FromXmlString(xmlPub); - ImportExport.AssertKeyEquals(pubOnly, rsaPub.ExportParameters(false)); + RSATestHelpers.AssertKeyEquals(pubOnly, rsaPub.ExportParameters(false)); } using (RSA rsaPriv = RSAFactory.Create()) { rsaPriv.FromXmlString(xmlPriv); - ImportExport.AssertKeyEquals(pubPriv, rsaPriv.ExportParameters(true)); - ImportExport.AssertKeyEquals(pubOnly, rsaPriv.ExportParameters(false)); + RSATestHelpers.AssertKeyEquals(pubPriv, rsaPriv.ExportParameters(true)); + RSATestHelpers.AssertKeyEquals(pubOnly, rsaPriv.ExportParameters(false)); } } } @@ -1274,7 +1274,7 @@ private static void TestReadXml(string xmlString, in RSAParameters expectedParam bool includePrivateParameters = expectedParameters.D != null; - ImportExport.AssertKeyEquals( + RSATestHelpers.AssertKeyEquals( expectedParameters, rsa.ExportParameters(includePrivateParameters)); } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaAlgorithmTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaAlgorithmTests.cs index 41af4928a15405..1f2a43c78e4d40 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaAlgorithmTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaAlgorithmTests.cs @@ -16,73 +16,73 @@ public static void AlgorithmsHaveExpectedParameters() algorithm = SlhDsaAlgorithm.SlhDsaSha2_128s; Assert.Equal("SLH-DSA-SHA2-128s", algorithm.Name); Assert.Equal(32, algorithm.PublicKeySizeInBytes); - Assert.Equal(64, algorithm.SecretKeySizeInBytes); + Assert.Equal(64, algorithm.PrivateKeySizeInBytes); Assert.Equal(7856, algorithm.SignatureSizeInBytes); algorithm = SlhDsaAlgorithm.SlhDsaShake128s; Assert.Equal("SLH-DSA-SHAKE-128s", algorithm.Name); Assert.Equal(32, algorithm.PublicKeySizeInBytes); - Assert.Equal(64, algorithm.SecretKeySizeInBytes); + Assert.Equal(64, algorithm.PrivateKeySizeInBytes); Assert.Equal(7856, algorithm.SignatureSizeInBytes); algorithm = SlhDsaAlgorithm.SlhDsaSha2_128f; Assert.Equal("SLH-DSA-SHA2-128f", algorithm.Name); Assert.Equal(32, algorithm.PublicKeySizeInBytes); - Assert.Equal(64, algorithm.SecretKeySizeInBytes); + Assert.Equal(64, algorithm.PrivateKeySizeInBytes); Assert.Equal(17088, algorithm.SignatureSizeInBytes); algorithm = SlhDsaAlgorithm.SlhDsaShake128f; Assert.Equal("SLH-DSA-SHAKE-128f", algorithm.Name); Assert.Equal(32, algorithm.PublicKeySizeInBytes); - Assert.Equal(64, algorithm.SecretKeySizeInBytes); + Assert.Equal(64, algorithm.PrivateKeySizeInBytes); Assert.Equal(17088, algorithm.SignatureSizeInBytes); algorithm = SlhDsaAlgorithm.SlhDsaSha2_192s; Assert.Equal("SLH-DSA-SHA2-192s", algorithm.Name); Assert.Equal(48, algorithm.PublicKeySizeInBytes); - Assert.Equal(96, algorithm.SecretKeySizeInBytes); + Assert.Equal(96, algorithm.PrivateKeySizeInBytes); Assert.Equal(16224, algorithm.SignatureSizeInBytes); algorithm = SlhDsaAlgorithm.SlhDsaShake192s; Assert.Equal("SLH-DSA-SHAKE-192s", algorithm.Name); Assert.Equal(48, algorithm.PublicKeySizeInBytes); - Assert.Equal(96, algorithm.SecretKeySizeInBytes); + Assert.Equal(96, algorithm.PrivateKeySizeInBytes); Assert.Equal(16224, algorithm.SignatureSizeInBytes); algorithm = SlhDsaAlgorithm.SlhDsaSha2_192f; Assert.Equal("SLH-DSA-SHA2-192f", algorithm.Name); Assert.Equal(48, algorithm.PublicKeySizeInBytes); - Assert.Equal(96, algorithm.SecretKeySizeInBytes); + Assert.Equal(96, algorithm.PrivateKeySizeInBytes); Assert.Equal(35664, algorithm.SignatureSizeInBytes); algorithm = SlhDsaAlgorithm.SlhDsaShake192f; Assert.Equal("SLH-DSA-SHAKE-192f", algorithm.Name); Assert.Equal(48, algorithm.PublicKeySizeInBytes); - Assert.Equal(96, algorithm.SecretKeySizeInBytes); + Assert.Equal(96, algorithm.PrivateKeySizeInBytes); Assert.Equal(35664, algorithm.SignatureSizeInBytes); algorithm = SlhDsaAlgorithm.SlhDsaSha2_256s; Assert.Equal("SLH-DSA-SHA2-256s", algorithm.Name); Assert.Equal(64, algorithm.PublicKeySizeInBytes); - Assert.Equal(128, algorithm.SecretKeySizeInBytes); + Assert.Equal(128, algorithm.PrivateKeySizeInBytes); Assert.Equal(29792, algorithm.SignatureSizeInBytes); algorithm = SlhDsaAlgorithm.SlhDsaShake256s; Assert.Equal("SLH-DSA-SHAKE-256s", algorithm.Name); Assert.Equal(64, algorithm.PublicKeySizeInBytes); - Assert.Equal(128, algorithm.SecretKeySizeInBytes); + Assert.Equal(128, algorithm.PrivateKeySizeInBytes); Assert.Equal(29792, algorithm.SignatureSizeInBytes); algorithm = SlhDsaAlgorithm.SlhDsaSha2_256f; Assert.Equal("SLH-DSA-SHA2-256f", algorithm.Name); Assert.Equal(64, algorithm.PublicKeySizeInBytes); - Assert.Equal(128, algorithm.SecretKeySizeInBytes); + Assert.Equal(128, algorithm.PrivateKeySizeInBytes); Assert.Equal(49856, algorithm.SignatureSizeInBytes); algorithm = SlhDsaAlgorithm.SlhDsaShake256f; Assert.Equal("SLH-DSA-SHAKE-256f", algorithm.Name); Assert.Equal(64, algorithm.PublicKeySizeInBytes); - Assert.Equal(128, algorithm.SecretKeySizeInBytes); + Assert.Equal(128, algorithm.PrivateKeySizeInBytes); Assert.Equal(49856, algorithm.SignatureSizeInBytes); } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaContractTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaContractTests.cs index a335511933c354..e01600c613b0e8 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaContractTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaContractTests.cs @@ -73,7 +73,7 @@ public static void ArgumentValidation(SlhDsaAlgorithm algorithm, bool shouldDisp using SlhDsa slhDsa = SlhDsaMockImplementation.Create(algorithm); int publicKeySize = algorithm.PublicKeySizeInBytes; - int secretKeySize = algorithm.SecretKeySizeInBytes; + int privateKeySize = algorithm.PrivateKeySizeInBytes; int signatureSize = algorithm.SignatureSizeInBytes; if (shouldDispose) @@ -84,8 +84,8 @@ public static void ArgumentValidation(SlhDsaAlgorithm algorithm, bool shouldDisp AssertExtensions.Throws("destination", () => slhDsa.ExportSlhDsaPublicKey(new byte[publicKeySize - 1])); AssertExtensions.Throws("destination", () => slhDsa.ExportSlhDsaPublicKey(new byte[publicKeySize + 1])); - AssertExtensions.Throws("destination", () => slhDsa.ExportSlhDsaSecretKey(new byte[secretKeySize - 1])); - AssertExtensions.Throws("destination", () => slhDsa.ExportSlhDsaSecretKey(new byte[secretKeySize + 1])); + AssertExtensions.Throws("destination", () => slhDsa.ExportSlhDsaPrivateKey(new byte[privateKeySize - 1])); + AssertExtensions.Throws("destination", () => slhDsa.ExportSlhDsaPrivateKey(new byte[privateKeySize + 1])); AssertExtensions.Throws("destination", () => slhDsa.SignData(ReadOnlySpan.Empty, new byte[signatureSize - 1], ReadOnlySpan.Empty)); AssertExtensions.Throws("destination", () => slhDsa.SignData(ReadOnlySpan.Empty, new byte[signatureSize + 1], ReadOnlySpan.Empty)); AssertExtensions.Throws("destination", () => slhDsa.SignPreHash(ReadOnlySpan.Empty, new byte[signatureSize - 1], "", ReadOnlySpan.Empty)); @@ -134,28 +134,20 @@ public static void ArgumentValidation_PbeParameters(SlhDsaAlgorithm algorithm, b }, SlhDsaTestHelpers.EncryptionPasswordType.Byte); } + public static IEnumerable ArgumentValidation_Hash_WrongSizeInputs() + { + foreach (bool shouldDispose in new[] { true, false }) + { + foreach (HashInfo hashInfo in HashInfo.AllHashInfos()) + { + yield return new object[] { shouldDispose, hashInfo }; + } + } + } + [Theory] - [InlineData(true, SlhDsaTestHelpers.Md5Oid, 128 / 8)] - [InlineData(true, SlhDsaTestHelpers.Sha1Oid, 160 / 8)] - [InlineData(true, SlhDsaTestHelpers.Sha256Oid, 256 / 8)] - [InlineData(true, SlhDsaTestHelpers.Sha384Oid, 384 / 8)] - [InlineData(true, SlhDsaTestHelpers.Sha512Oid, 512 / 8)] - [InlineData(true, SlhDsaTestHelpers.Sha3_256Oid, 256 / 8)] - [InlineData(true, SlhDsaTestHelpers.Sha3_384Oid, 384 / 8)] - [InlineData(true, SlhDsaTestHelpers.Sha3_512Oid, 512 / 8)] - [InlineData(true, SlhDsaTestHelpers.Shake128Oid, 256 / 8)] - [InlineData(true, SlhDsaTestHelpers.Shake256Oid, 512 / 8)] - [InlineData(false, SlhDsaTestHelpers.Md5Oid, 128 / 8)] - [InlineData(false, SlhDsaTestHelpers.Sha1Oid, 160 / 8)] - [InlineData(false, SlhDsaTestHelpers.Sha256Oid, 256 / 8)] - [InlineData(false, SlhDsaTestHelpers.Sha384Oid, 384 / 8)] - [InlineData(false, SlhDsaTestHelpers.Sha512Oid, 512 / 8)] - [InlineData(false, SlhDsaTestHelpers.Sha3_256Oid, 256 / 8)] - [InlineData(false, SlhDsaTestHelpers.Sha3_384Oid, 384 / 8)] - [InlineData(false, SlhDsaTestHelpers.Sha3_512Oid, 512 / 8)] - [InlineData(false, SlhDsaTestHelpers.Shake128Oid, 256 / 8)] - [InlineData(false, SlhDsaTestHelpers.Shake256Oid, 512 / 8)] - public static void ArgumentValidation_Hash_WrongSize(bool shouldDispose, string oid, int hashLength) + [MemberData(nameof(ArgumentValidation_Hash_WrongSizeInputs))] + public static void ArgumentValidation_Hash_WrongSize(bool shouldDispose, HashInfo hashInfo) { using SlhDsa slhDsa = SlhDsaMockImplementation.Create(SlhDsaAlgorithm.SlhDsaSha2_128f); @@ -167,15 +159,15 @@ public static void ArgumentValidation_Hash_WrongSize(bool shouldDispose, string byte[] signature = new byte[SlhDsaAlgorithm.SlhDsaSha2_128f.SignatureSizeInBytes]; - Assert.Throws(() => slhDsa.SignPreHash(new byte[hashLength - 1], oid)); - Assert.Throws(() => slhDsa.SignPreHash(new byte[hashLength + 1], oid)); - Assert.Throws(() => slhDsa.SignPreHash(new byte[hashLength - 1], signature, oid)); - Assert.Throws(() => slhDsa.SignPreHash(new byte[hashLength + 1], signature, oid)); + Assert.Throws(() => slhDsa.SignPreHash(new byte[hashInfo.OutputSize - 1], hashInfo.Oid)); + Assert.Throws(() => slhDsa.SignPreHash(new byte[hashInfo.OutputSize + 1], hashInfo.Oid)); + Assert.Throws(() => slhDsa.SignPreHash(new byte[hashInfo.OutputSize - 1], signature, hashInfo.Oid)); + Assert.Throws(() => slhDsa.SignPreHash(new byte[hashInfo.OutputSize + 1], signature, hashInfo.Oid)); - Assert.Throws(() => slhDsa.VerifyPreHash(new byte[hashLength - 1], signature, oid)); - Assert.Throws(() => slhDsa.VerifyPreHash(new byte[hashLength + 1], signature, oid)); - Assert.Throws(() => slhDsa.VerifyPreHash(new byte[hashLength - 1], signature.AsSpan(), oid)); - Assert.Throws(() => slhDsa.VerifyPreHash(new byte[hashLength + 1], signature.AsSpan(), oid)); + Assert.Throws(() => slhDsa.VerifyPreHash(new byte[hashInfo.OutputSize - 1], signature, hashInfo.Oid)); + Assert.Throws(() => slhDsa.VerifyPreHash(new byte[hashInfo.OutputSize + 1], signature, hashInfo.Oid)); + Assert.Throws(() => slhDsa.VerifyPreHash(new byte[hashInfo.OutputSize - 1], signature.AsSpan(), hashInfo.Oid)); + Assert.Throws(() => slhDsa.VerifyPreHash(new byte[hashInfo.OutputSize + 1], signature.AsSpan(), hashInfo.Oid)); } [Theory] @@ -283,30 +275,30 @@ public static void ExportSlhDsaPublicKey_CallsCore(SlhDsaAlgorithm algorithm) [Theory] [MemberData(nameof(SlhDsaTestData.AlgorithmsData), MemberType = typeof(SlhDsaTestData))] - public static void ExportSlhDsaSecretKey_CallsCore(SlhDsaAlgorithm algorithm) + public static void ExportSlhDsaPrivateKey_CallsCore(SlhDsaAlgorithm algorithm) { using SlhDsaMockImplementation slhDsa = SlhDsaMockImplementation.Create(algorithm); - slhDsa.ExportSlhDsaSecretKeyCoreHook = _ => { }; + slhDsa.ExportSlhDsaPrivateKeyCoreHook = _ => { }; slhDsa.AddFillDestination(1); - int secretKeySize = algorithm.SecretKeySizeInBytes; + int privateKeySize = algorithm.PrivateKeySizeInBytes; // Array overload - byte[] exported = slhDsa.ExportSlhDsaSecretKey(); - Assert.Equal(1, slhDsa.ExportSlhDsaSecretKeyCoreCallCount); - Assert.Equal(secretKeySize, exported.Length); + byte[] exported = slhDsa.ExportSlhDsaPrivateKey(); + Assert.Equal(1, slhDsa.ExportSlhDsaPrivateKeyCoreCallCount); + Assert.Equal(privateKeySize, exported.Length); AssertExpectedFill(exported, fillElement: 1); // Span overload - byte[] secretKey = CreatePaddedFilledArray(secretKeySize, 42); + byte[] privateKey = CreatePaddedFilledArray(privateKeySize, 42); // Extra bytes in destination buffer should not be touched - Memory destination = secretKey.AsMemory(PaddingSize, secretKeySize); + Memory destination = privateKey.AsMemory(PaddingSize, privateKeySize); slhDsa.AddDestinationBufferIsSameAssertion(destination); - slhDsa.ExportSlhDsaSecretKey(destination.Span); - Assert.Equal(2, slhDsa.ExportSlhDsaSecretKeyCoreCallCount); - AssertExpectedFill(secretKey, fillElement: 1, paddingElement: 42, PaddingSize, secretKeySize); + slhDsa.ExportSlhDsaPrivateKey(destination.Span); + Assert.Equal(2, slhDsa.ExportSlhDsaPrivateKeyCoreCallCount); + AssertExpectedFill(privateKey, fillElement: 1, paddingElement: 42, PaddingSize, privateKeySize); } [Theory] @@ -412,17 +404,16 @@ public static void VerifyData_ByteArray_CallsCore(SlhDsaAlgorithm algorithm) Assert.Equal(2, slhDsa.VerifyDataCoreCallCount); } + public static IEnumerable AllHashesAndLengths() + { + foreach (HashInfo hashInfo in HashInfo.AllHashInfos()) + { + yield return new object[] { hashInfo.Oid, hashInfo.OutputSize }; + } + } + [Theory] - [InlineData(SlhDsaTestHelpers.Md5Oid, 128 / 8)] - [InlineData(SlhDsaTestHelpers.Sha1Oid, 160 / 8)] - [InlineData(SlhDsaTestHelpers.Sha256Oid, 256 / 8)] - [InlineData(SlhDsaTestHelpers.Sha384Oid, 384 / 8)] - [InlineData(SlhDsaTestHelpers.Sha512Oid, 512 / 8)] - [InlineData(SlhDsaTestHelpers.Sha3_256Oid, 256 / 8)] - [InlineData(SlhDsaTestHelpers.Sha3_384Oid, 384 / 8)] - [InlineData(SlhDsaTestHelpers.Sha3_512Oid, 512 / 8)] - [InlineData(SlhDsaTestHelpers.Shake128Oid, 256 / 8)] - [InlineData(SlhDsaTestHelpers.Shake256Oid, 512 / 8)] + [MemberData(nameof(AllHashesAndLengths))] [InlineData("1.0", 0)] [InlineData("1.0", 1)] [InlineData("1.0", 2)] @@ -462,16 +453,7 @@ public static void SignPreHash_CallsCore(string hashAlgorithmOid, int hashLength } [Theory] - [InlineData(SlhDsaTestHelpers.Md5Oid, 128 / 8)] - [InlineData(SlhDsaTestHelpers.Sha1Oid, 160 / 8)] - [InlineData(SlhDsaTestHelpers.Sha256Oid, 256 / 8)] - [InlineData(SlhDsaTestHelpers.Sha384Oid, 384 / 8)] - [InlineData(SlhDsaTestHelpers.Sha512Oid, 512 / 8)] - [InlineData(SlhDsaTestHelpers.Sha3_256Oid, 256 / 8)] - [InlineData(SlhDsaTestHelpers.Sha3_384Oid, 384 / 8)] - [InlineData(SlhDsaTestHelpers.Sha3_512Oid, 512 / 8)] - [InlineData(SlhDsaTestHelpers.Shake128Oid, 256 / 8)] - [InlineData(SlhDsaTestHelpers.Shake256Oid, 512 / 8)] + [MemberData(nameof(AllHashesAndLengths))] [InlineData("1.0", 0)] [InlineData("1.0", 1)] [InlineData("1.0", 2)] @@ -510,16 +492,7 @@ public static void VerifyPreHash_CallsCore(string hashAlgorithmOid, int hashLeng } [Theory] - [InlineData(SlhDsaTestHelpers.Md5Oid, 128 / 8)] - [InlineData(SlhDsaTestHelpers.Sha1Oid, 160 / 8)] - [InlineData(SlhDsaTestHelpers.Sha256Oid, 256 / 8)] - [InlineData(SlhDsaTestHelpers.Sha384Oid, 384 / 8)] - [InlineData(SlhDsaTestHelpers.Sha512Oid, 512 / 8)] - [InlineData(SlhDsaTestHelpers.Sha3_256Oid, 256 / 8)] - [InlineData(SlhDsaTestHelpers.Sha3_384Oid, 384 / 8)] - [InlineData(SlhDsaTestHelpers.Sha3_512Oid, 512 / 8)] - [InlineData(SlhDsaTestHelpers.Shake128Oid, 256 / 8)] - [InlineData(SlhDsaTestHelpers.Shake256Oid, 512 / 8)] + [MemberData(nameof(AllHashesAndLengths))] [InlineData("1.0", 0)] [InlineData("1.0", 1)] [InlineData("1.0", 2)] @@ -585,31 +558,31 @@ public static void Dispose_CallsVirtual(SlhDsaAlgorithm algorithm) [Theory] [MemberData(nameof(SlhDsaTestData.AlgorithmsData), MemberType = typeof(SlhDsaTestData))] - public static void ExportPkcs8PrivateKey_CallsExportSlhDsaSecretKey(SlhDsaAlgorithm algorithm) + public static void ExportPkcs8PrivateKey_CallsExportSlhDsaPrivateKey(SlhDsaAlgorithm algorithm) { SlhDsaTestHelpers.AssertExportPkcs8PrivateKey(export => { using SlhDsaMockImplementation slhDsa = SlhDsaMockImplementation.Create(algorithm); - slhDsa.ExportSlhDsaSecretKeyCoreHook = _ => { }; + slhDsa.ExportSlhDsaPrivateKeyCoreHook = _ => { }; slhDsa.AddLengthAssertion(); slhDsa.AddFillDestination(1); // SlhDsaMockImplementation overrides TryExportPkcs8PrivateKeyCore with a stub. In order to replicate the // non-overridden behavior, we will replace the stub with a call to base.TryExportPkcs8PrivateKeyCore. - // We can then assert that base.TryExportPkcs8PrivateKeyCore calls ExportSlhDsaSecretKeyCore as expected. + // We can then assert that base.TryExportPkcs8PrivateKeyCore calls ExportSlhDsaPrivateKeyCore as expected. slhDsa.TryExportPkcs8PrivateKeyCoreHook = slhDsa.BaseTryExportPkcs8PrivateKeyCore; // Invoke the export byte[] exported = export(slhDsa); // Assert that the core methods were called - AssertExtensions.GreaterThan(slhDsa.ExportSlhDsaSecretKeyCoreCallCount, 0); + AssertExtensions.GreaterThan(slhDsa.ExportSlhDsaPrivateKeyCoreCallCount, 0); AssertExtensions.GreaterThan(slhDsa.TryExportPkcs8PrivateKeyCoreCallCount, 0); // And check the returned data PrivateKeyInfoAsn exportedPkcs8 = PrivateKeyInfoAsn.Decode(exported, AsnEncodingRules.DER); - AssertExtensions.SequenceEqual(CreateFilledArray(algorithm.SecretKeySizeInBytes, 1), exportedPkcs8.PrivateKey.Span); + AssertExtensions.SequenceEqual(CreateFilledArray(algorithm.PrivateKeySizeInBytes, 1), exportedPkcs8.PrivateKey.Span); Assert.Equal(0, exportedPkcs8.Version); Assert.Equal(SlhDsaTestHelpers.AlgorithmToOid(algorithm), exportedPkcs8.PrivateKeyAlgorithm.Algorithm); AssertExtensions.FalseExpression(exportedPkcs8.PrivateKeyAlgorithm.Parameters.HasValue); @@ -619,9 +592,9 @@ public static void ExportPkcs8PrivateKey_CallsExportSlhDsaSecretKey(SlhDsaAlgori [Theory] [MemberData(nameof(SlhDsaTestData.AlgorithmsData), MemberType = typeof(SlhDsaTestData))] - public static void ExportPkcs8PrivateKey_DoesNotCallExportSlhDsaSecretKey(SlhDsaAlgorithm algorithm) + public static void ExportPkcs8PrivateKey_DoesNotCallExportSlhDsaPrivateKey(SlhDsaAlgorithm algorithm) { - byte[] secretKeyBytes = CreateFilledArray(algorithm.SecretKeySizeInBytes, 42); + byte[] privateKeyBytes = CreateFilledArray(algorithm.PrivateKeySizeInBytes, 42); PrivateKeyInfoAsn pkcs8 = new PrivateKeyInfoAsn { PrivateKeyAlgorithm = new AlgorithmIdentifierAsn @@ -629,7 +602,7 @@ public static void ExportPkcs8PrivateKey_DoesNotCallExportSlhDsaSecretKey(SlhDsa Algorithm = SlhDsaTestHelpers.AlgorithmToOid(algorithm), Parameters = null, }, - PrivateKey = secretKeyBytes, + PrivateKey = privateKeyBytes, }; byte[] minimalEncoding = pkcs8.Encode(); @@ -655,8 +628,8 @@ public static void ExportPkcs8PrivateKey_DoesNotCallExportSlhDsaSecretKey(SlhDsa byte[] exported = export(slhDsa); - // Assert that the PKCS#8 private key is NOT generated with the secret key but from our test callback - Assert.Equal(0, slhDsa.ExportSlhDsaSecretKeyCoreCallCount); + // Assert that the PKCS#8 private key is NOT generated with the private key but from our test callback + Assert.Equal(0, slhDsa.ExportSlhDsaPrivateKeyCoreCallCount); AssertExtensions.GreaterThan(slhDsa.TryExportPkcs8PrivateKeyCoreCallCount, 0); PrivateKeyInfoAsn exportedPkcs8 = PrivateKeyInfoAsn.Decode(exported, AsnEncodingRules.DER); @@ -716,18 +689,18 @@ public static void ExportEncryptedPkcs8PrivateKey_CallsExportSlhDsaPrivateKey(Sl { using SlhDsaMockImplementation slhDsa = SlhDsaMockImplementation.Create(algorithm); - slhDsa.ExportSlhDsaSecretKeyCoreHook = _ => { }; + slhDsa.ExportSlhDsaPrivateKeyCoreHook = _ => { }; slhDsa.AddLengthAssertion(); slhDsa.AddFillDestination(1); // SlhDsaMockImplementation overrides TryExportPkcs8PrivateKeyCore with a stub. In order to replicate the // non-overridden behavior, we will replace the stub with a call to base.TryExportPkcs8PrivateKeyCore. - // We can then assert that base.TryExportPkcs8PrivateKeyCore calls ExportSlhDsaSecretKeyCore as expected. + // We can then assert that base.TryExportPkcs8PrivateKeyCore calls ExportSlhDsaPrivateKeyCore as expected. slhDsa.TryExportPkcs8PrivateKeyCoreHook = slhDsa.BaseTryExportPkcs8PrivateKeyCore; byte[] exported = export(slhDsa, "PLACEHOLDER", pbeParameters); - AssertExtensions.GreaterThan(slhDsa.ExportSlhDsaSecretKeyCoreCallCount, 0); + AssertExtensions.GreaterThan(slhDsa.ExportSlhDsaPrivateKeyCoreCallCount, 0); AssertExtensions.GreaterThan(slhDsa.TryExportPkcs8PrivateKeyCoreCallCount, 0); EncryptedPrivateKeyInfoAsn epki = EncryptedPrivateKeyInfoAsn.Decode(exported, AsnEncodingRules.BER); @@ -742,16 +715,16 @@ public static void ExportEncryptedPkcs8PrivateKey_CallsExportSlhDsaPrivateKey(Sl public static void TryExportPkcs8PrivateKey_DestinationTooSmall(SlhDsaAlgorithm algorithm) { const int MinimumOverhead = 12; - int lengthCutoff = algorithm.SecretKeySizeInBytes + MinimumOverhead; + int lengthCutoff = algorithm.PrivateKeySizeInBytes + MinimumOverhead; // First check that the length cutoff is enforced using SlhDsaMockImplementation slhDsa = SlhDsaMockImplementation.Create(algorithm); - byte[] secretKey = new byte[lengthCutoff]; + byte[] privateKey = new byte[lengthCutoff]; // Early heuristic based bailout so no core methods are called AssertExtensions.FalseExpression( - slhDsa.TryExportPkcs8PrivateKey(secretKey.AsSpan(0, lengthCutoff - 1), out int bytesWritten)); + slhDsa.TryExportPkcs8PrivateKey(privateKey.AsSpan(0, lengthCutoff - 1), out int bytesWritten)); Assert.Equal(0, bytesWritten); // No bailout case: set up the core method @@ -761,8 +734,8 @@ public static void TryExportPkcs8PrivateKey_DestinationTooSmall(SlhDsaAlgorithm return true; }; - AssertExtensions.TrueExpression(slhDsa.TryExportPkcs8PrivateKey(secretKey, out bytesWritten)); - Assert.Equal(secretKey.Length, bytesWritten); + AssertExtensions.TrueExpression(slhDsa.TryExportPkcs8PrivateKey(privateKey, out bytesWritten)); + Assert.Equal(privateKey.Length, bytesWritten); // Now check that the length cutoff permits a minimal encoding // Build the minimal encoding: @@ -776,7 +749,7 @@ public static void TryExportPkcs8PrivateKey_DestinationTooSmall(SlhDsaAlgorithm writer.WriteObjectIdentifier(SlhDsaTestHelpers.AlgorithmToOid(algorithm)); } - writer.WriteOctetString(new byte[algorithm.SecretKeySizeInBytes]); + writer.WriteOctetString(new byte[algorithm.PrivateKeySizeInBytes]); } byte[] encodedMetadata = writer.Encode(); @@ -791,7 +764,7 @@ public static void ExportPkcs8PrivateKey_DestinationInitialSize(SlhDsaAlgorithm { using SlhDsaMockImplementation slhDsa = SlhDsaMockImplementation.Create(algorithm); - byte[] secretKeyBytes = CreateFilledArray(algorithm.SecretKeySizeInBytes, 42); + byte[] privateKeyBytes = CreateFilledArray(algorithm.PrivateKeySizeInBytes, 42); PrivateKeyInfoAsn pkcs8 = new PrivateKeyInfoAsn { PrivateKeyAlgorithm = new AlgorithmIdentifierAsn @@ -799,7 +772,7 @@ public static void ExportPkcs8PrivateKey_DestinationInitialSize(SlhDsaAlgorithm Algorithm = SlhDsaTestHelpers.AlgorithmToOid(SlhDsaAlgorithm.SlhDsaSha2_128s), Parameters = null, }, - PrivateKey = secretKeyBytes, + PrivateKey = privateKeyBytes, }; byte[] minimalEncoding = pkcs8.Encode(); @@ -835,7 +808,7 @@ public static void ExportPkcs8PrivateKey_Resizes(SlhDsaAlgorithm algorithm) { using SlhDsaMockImplementation slhDsa = SlhDsaMockImplementation.Create(algorithm); - byte[] secretKeyBytes = CreateFilledArray(algorithm.SecretKeySizeInBytes, 42); + byte[] privateKeyBytes = CreateFilledArray(algorithm.PrivateKeySizeInBytes, 42); PrivateKeyInfoAsn pkcs8 = new PrivateKeyInfoAsn { PrivateKeyAlgorithm = new AlgorithmIdentifierAsn @@ -843,7 +816,7 @@ public static void ExportPkcs8PrivateKey_Resizes(SlhDsaAlgorithm algorithm) Algorithm = SlhDsaTestHelpers.AlgorithmToOid(SlhDsaAlgorithm.SlhDsaSha2_128s), Parameters = null, }, - PrivateKey = secretKeyBytes, + PrivateKey = privateKeyBytes, }; byte[] minimalEncoding = pkcs8.Encode(); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaFactoryTests.cs index ab0dbf48b12b59..6544bc64fff92c 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaFactoryTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaFactoryTests.cs @@ -16,7 +16,7 @@ public static void NullArgumentValidation() { AssertExtensions.Throws("algorithm", static () => SlhDsa.GenerateKey(null)); AssertExtensions.Throws("algorithm", static () => SlhDsa.ImportSlhDsaPublicKey(null, [])); - AssertExtensions.Throws("algorithm", static () => SlhDsa.ImportSlhDsaSecretKey(null, [])); + AssertExtensions.Throws("algorithm", static () => SlhDsa.ImportSlhDsaPrivateKey(null, [])); AssertExtensions.Throws("source", static () => SlhDsa.ImportEncryptedPkcs8PrivateKey(string.Empty, (byte[])null)); AssertExtensions.Throws("source", static () => SlhDsa.ImportFromEncryptedPem((string)null, string.Empty)); @@ -24,7 +24,7 @@ public static void NullArgumentValidation() AssertExtensions.Throws("source", static () => SlhDsa.ImportFromPem(null)); AssertExtensions.Throws("source", static () => SlhDsa.ImportPkcs8PrivateKey(null)); AssertExtensions.Throws("source", static () => SlhDsa.ImportSlhDsaPublicKey(SlhDsaAlgorithm.SlhDsaSha2_128f, null)); - AssertExtensions.Throws("source", static () => SlhDsa.ImportSlhDsaSecretKey(SlhDsaAlgorithm.SlhDsaSha2_128f, null)); + AssertExtensions.Throws("source", static () => SlhDsa.ImportSlhDsaPrivateKey(SlhDsaAlgorithm.SlhDsaSha2_128f, null)); AssertExtensions.Throws("source", static () => SlhDsa.ImportSubjectPublicKeyInfo(null)); AssertExtensions.Throws("password", static () => SlhDsa.ImportEncryptedPkcs8PrivateKey((string)null, Array.Empty())); @@ -38,7 +38,7 @@ public static void NullArgumentValidation() public static void ArgumentValidation_WrongKeySizeForAlgorithm(SlhDsaAlgorithm algorithm) { int publicKeySize = algorithm.PublicKeySizeInBytes; - int secretKeySize = algorithm.SecretKeySizeInBytes; + int privateKeySize = algorithm.PrivateKeySizeInBytes; // SLH-DSA key size is wrong when importing algorithm key. Throw an argument exception. Action> assertDirectImport = import => AssertExtensions.Throws("source", import); @@ -51,9 +51,9 @@ public static void ArgumentValidation_WrongKeySizeForAlgorithm(SlhDsaAlgorithm a SlhDsaTestHelpers.AssertImportPublicKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[publicKeySize - 1]); SlhDsaTestHelpers.AssertImportPublicKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[0]); - SlhDsaTestHelpers.AssertImportSecretKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[secretKeySize + 1]); - SlhDsaTestHelpers.AssertImportSecretKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[secretKeySize - 1]); - SlhDsaTestHelpers.AssertImportSecretKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[0]); + SlhDsaTestHelpers.AssertImportPrivateKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[privateKeySize + 1]); + SlhDsaTestHelpers.AssertImportPrivateKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[privateKeySize - 1]); + SlhDsaTestHelpers.AssertImportPrivateKey(assertDirectImport, assertEmbeddedImport, algorithm, new byte[0]); } [Fact] @@ -179,7 +179,7 @@ public static void ImportPkcs8PrivateKey_AlgorithmErrorsInAsn() Algorithm = SlhDsaTestHelpers.AlgorithmToOid(SlhDsaAlgorithm.SlhDsaSha2_128s), Parameters = SlhDsaTestHelpers.s_derBitStringFoo, // <-- Invalid }, - PrivateKey = new byte[SlhDsaAlgorithm.SlhDsaSha2_128s.SecretKeySizeInBytes] + PrivateKey = new byte[SlhDsaAlgorithm.SlhDsaSha2_128s.PrivateKeySizeInBytes] }; SlhDsaTestHelpers.AssertImportPkcs8PrivateKey( @@ -253,9 +253,9 @@ public static void AlgorithmMatches_GenerateKey(SlhDsaAlgorithm algorithm) AssertThrowIfNotSupported(() => Assert.Equal(algorithm, import().Algorithm)), algorithm, new byte[algorithm.PublicKeySizeInBytes]); - SlhDsaTestHelpers.AssertImportSecretKey(import => + SlhDsaTestHelpers.AssertImportPrivateKey(import => AssertThrowIfNotSupported(() => - Assert.Equal(algorithm, import().Algorithm)), algorithm, new byte[algorithm.SecretKeySizeInBytes]); + Assert.Equal(algorithm, import().Algorithm)), algorithm, new byte[algorithm.PrivateKeySizeInBytes]); } /// diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaImplementationTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaImplementationTests.cs index defda3c6df049b..1994994012978e 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaImplementationTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaImplementationTests.cs @@ -28,9 +28,9 @@ public static void SlhDsaIsOnlyPublicAncestor_Import(SlhDsaTestData.SlhDsaGenera SlhDsaTestHelpers.AssertImportPublicKey( AssertSlhDsaIsOnlyPublicAncestor, info.Algorithm, info.PublicKey); - // Tests ImportSecretKey, ImportPKCS8PrivateKey, ImportPem (with PRIVATE KEY) - SlhDsaTestHelpers.AssertImportSecretKey( - AssertSlhDsaIsOnlyPublicAncestor, info.Algorithm, info.SecretKey); + // Tests ImportPrivateKey, ImportPKCS8PrivateKey, ImportPem (with PRIVATE KEY) + SlhDsaTestHelpers.AssertImportPrivateKey( + AssertSlhDsaIsOnlyPublicAncestor, info.Algorithm, info.PrivateKey); // Tests ImportEncryptedPKCS8PrivateKey, ImportEncryptedPem (with ENCRYPTED PRIVATE KEY) SlhDsaTestHelpers.AssertImportEncryptedPkcs8PrivateKey(import => @@ -71,32 +71,32 @@ public void RoundTrip_Export_Import_PublicKey(SlhDsaAlgorithm algorithm) // Verify the roundtripped object has the same key Assert.Equal(algorithm, roundTrippedSlhDsa.Algorithm); AssertExtensions.SequenceEqual(slhDsa.ExportSlhDsaPublicKey(), roundTrippedSlhDsa.ExportSlhDsaPublicKey()); - Assert.Throws(() => roundTrippedSlhDsa.ExportSlhDsaSecretKey()); + Assert.Throws(() => roundTrippedSlhDsa.ExportSlhDsaPrivateKey()); }, algorithm, exportedPublicKey); }); } [Theory] [MemberData(nameof(SlhDsaTestData.AlgorithmsData), MemberType = typeof(SlhDsaTestData))] - public void RoundTrip_Export_Import_SecretKey(SlhDsaAlgorithm algorithm) + public void RoundTrip_Export_Import_PrivateKey(SlhDsaAlgorithm algorithm) { // Generate new key using SlhDsa slhDsa = GenerateKey(algorithm); - SlhDsaTestHelpers.AssertExportSlhDsaSecretKey(export => + SlhDsaTestHelpers.AssertExportSlhDsaPrivateKey(export => { - // Roundtrip using secret key. First export it. - byte[] exportedSecretKey = export(slhDsa); - SlhDsaTestHelpers.AssertImportSecretKey(import => + // Roundtrip using private key. First export it. + byte[] exportedPrivateKey = export(slhDsa); + SlhDsaTestHelpers.AssertImportPrivateKey(import => { // Then import it. using SlhDsa roundTrippedSlhDsa = import(); // Verify the roundtripped object has the same key Assert.Equal(algorithm, roundTrippedSlhDsa.Algorithm); - AssertExtensions.SequenceEqual(slhDsa.ExportSlhDsaSecretKey(), roundTrippedSlhDsa.ExportSlhDsaSecretKey()); + AssertExtensions.SequenceEqual(slhDsa.ExportSlhDsaPrivateKey(), roundTrippedSlhDsa.ExportSlhDsaPrivateKey()); AssertExtensions.SequenceEqual(slhDsa.ExportSlhDsaPublicKey(), roundTrippedSlhDsa.ExportSlhDsaPublicKey()); - }, algorithm, exportedSecretKey); + }, algorithm, exportedPrivateKey); }); } @@ -106,7 +106,7 @@ public void RoundTrip_Export_Import_Pkcs8PrivateKey(SlhDsaAlgorithm algorithm) { // Generate new key using SlhDsa slhDsa = GenerateKey(algorithm); - byte[] secretKey = slhDsa.ExportSlhDsaSecretKey(); + byte[] privateKey = slhDsa.ExportSlhDsaPrivateKey(); byte[] publicKey = slhDsa.ExportSlhDsaPublicKey(); SlhDsaTestHelpers.AssertExportPkcs8PrivateKey(export => @@ -118,7 +118,7 @@ public void RoundTrip_Export_Import_Pkcs8PrivateKey(SlhDsaAlgorithm algorithm) // The keys should be the same Assert.Equal(algorithm, roundTrippedSlhDsa.Algorithm); AssertExtensions.SequenceEqual(publicKey, roundTrippedSlhDsa.ExportSlhDsaPublicKey()); - AssertExtensions.SequenceEqual(secretKey, roundTrippedSlhDsa.ExportSlhDsaSecretKey()); + AssertExtensions.SequenceEqual(privateKey, roundTrippedSlhDsa.ExportSlhDsaPrivateKey()); })); } @@ -129,7 +129,7 @@ public void RoundTrip_Export_Import_SPKI(SlhDsaAlgorithm algorithm) // Generate new key using SlhDsa slhDsa = GenerateKey(algorithm); byte[] publicKey = slhDsa.ExportSlhDsaPublicKey(); - byte[] secretKey = slhDsa.ExportSlhDsaSecretKey(); + byte[] privateKey = slhDsa.ExportSlhDsaPrivateKey(); SlhDsaTestHelpers.AssertExportPkcs8PrivateKey(export => SlhDsaTestHelpers.AssertImportPkcs8PrivateKey(import => @@ -140,7 +140,7 @@ public void RoundTrip_Export_Import_SPKI(SlhDsaAlgorithm algorithm) // The keys should be the same Assert.Equal(algorithm, roundTrippedSlhDsa.Algorithm); AssertExtensions.SequenceEqual(publicKey, roundTrippedSlhDsa.ExportSlhDsaPublicKey()); - AssertExtensions.SequenceEqual(secretKey, roundTrippedSlhDsa.ExportSlhDsaSecretKey()); + AssertExtensions.SequenceEqual(privateKey, roundTrippedSlhDsa.ExportSlhDsaPrivateKey()); })); } @@ -150,7 +150,7 @@ public void RoundTrip_Export_Import_EncryptedPkcs8PrivateKey(SlhDsaAlgorithm alg { // Generate new key using SlhDsa slhDsa = GenerateKey(algorithm); - byte[] secretKey = slhDsa.ExportSlhDsaSecretKey(); + byte[] privateKey = slhDsa.ExportSlhDsaPrivateKey(); byte[] publicKey = slhDsa.ExportSlhDsaPublicKey(); PbeParameters pbeParameters = new PbeParameters(PbeEncryptionAlgorithm.Aes128Cbc, HashAlgorithmName.SHA1, 1); @@ -163,7 +163,7 @@ public void RoundTrip_Export_Import_EncryptedPkcs8PrivateKey(SlhDsaAlgorithm alg // The keys should be the same Assert.Equal(algorithm, roundTrippedSlhDsa.Algorithm); - AssertExtensions.SequenceEqual(secretKey, roundTrippedSlhDsa.ExportSlhDsaSecretKey()); + AssertExtensions.SequenceEqual(privateKey, roundTrippedSlhDsa.ExportSlhDsaPrivateKey()); AssertExtensions.SequenceEqual(publicKey, roundTrippedSlhDsa.ExportSlhDsaPublicKey()); })); } @@ -174,7 +174,7 @@ public void RoundTrip_Export_Import_Pkcs8PrivateKeyPem(SlhDsaAlgorithm algorithm { // Generate new key using SlhDsa slhDsa = GenerateKey(algorithm); - byte[] secretKey = slhDsa.ExportSlhDsaSecretKey(); + byte[] privateKey = slhDsa.ExportSlhDsaPrivateKey(); byte[] publicKey = slhDsa.ExportSlhDsaPublicKey(); SlhDsaTestHelpers.AssertExportToPrivateKeyPem(export => @@ -185,7 +185,7 @@ public void RoundTrip_Export_Import_Pkcs8PrivateKeyPem(SlhDsaAlgorithm algorithm // The keys should be the same Assert.Equal(algorithm, roundTrippedSlhDsa.Algorithm); - AssertExtensions.SequenceEqual(secretKey, roundTrippedSlhDsa.ExportSlhDsaSecretKey()); + AssertExtensions.SequenceEqual(privateKey, roundTrippedSlhDsa.ExportSlhDsaPrivateKey()); AssertExtensions.SequenceEqual(publicKey, roundTrippedSlhDsa.ExportSlhDsaPublicKey()); })); } @@ -196,7 +196,7 @@ public void RoundTrip_Export_Import_SPKIPem(SlhDsaAlgorithm algorithm) { // Generate new key using SlhDsa slhDsa = GenerateKey(algorithm); - byte[] secretKey = slhDsa.ExportSlhDsaSecretKey(); + byte[] privateKey = slhDsa.ExportSlhDsaPrivateKey(); byte[] publicKey = slhDsa.ExportSlhDsaPublicKey(); SlhDsaTestHelpers.AssertExportToPublicKeyPem(export => @@ -208,7 +208,7 @@ public void RoundTrip_Export_Import_SPKIPem(SlhDsaAlgorithm algorithm) // The keys should be the same Assert.Equal(algorithm, roundTrippedSlhDsa.Algorithm); AssertExtensions.SequenceEqual(publicKey, roundTrippedSlhDsa.ExportSlhDsaPublicKey()); - Assert.Throws(() => roundTrippedSlhDsa.ExportSlhDsaSecretKey()); + Assert.Throws(() => roundTrippedSlhDsa.ExportSlhDsaPrivateKey()); })); } @@ -218,7 +218,7 @@ public void RoundTrip_Export_Import_EncryptedPkcs8PrivateKeyPem(SlhDsaAlgorithm { // Generate new key using SlhDsa slhDsa = GenerateKey(algorithm); - byte[] secretKey = slhDsa.ExportSlhDsaSecretKey(); + byte[] privateKey = slhDsa.ExportSlhDsaPrivateKey(); byte[] publicKey = slhDsa.ExportSlhDsaPublicKey(); PbeParameters pbeParameters = new PbeParameters(PbeEncryptionAlgorithm.Aes128Cbc, HashAlgorithmName.SHA1, 1); @@ -231,7 +231,7 @@ public void RoundTrip_Export_Import_EncryptedPkcs8PrivateKeyPem(SlhDsaAlgorithm // The keys should be the same Assert.Equal(algorithm, roundTrippedSlhDsa.Algorithm); - AssertExtensions.SequenceEqual(secretKey, roundTrippedSlhDsa.ExportSlhDsaSecretKey()); + AssertExtensions.SequenceEqual(privateKey, roundTrippedSlhDsa.ExportSlhDsaPrivateKey()); AssertExtensions.SequenceEqual(publicKey, roundTrippedSlhDsa.ExportSlhDsaPublicKey()); })); } @@ -256,12 +256,12 @@ public void RoundTrip_Import_Export_PublicKey(SlhDsaTestData.SlhDsaGeneratedKeyI [MemberData(nameof(SlhDsaTestData.GeneratedKeyInfosData), MemberType = typeof(SlhDsaTestData))] public void RoundTrip_Import_Export_PrivateKey(SlhDsaTestData.SlhDsaGeneratedKeyInfo info) { - SlhDsaTestHelpers.AssertImportSecretKey(import => - SlhDsaTestHelpers.AssertExportSlhDsaSecretKey(export => + SlhDsaTestHelpers.AssertImportPrivateKey(import => + SlhDsaTestHelpers.AssertExportSlhDsaPrivateKey(export => SlhDsaTestHelpers.WithDispose(import(), slhDsa => - AssertExtensions.SequenceEqual(info.SecretKey, export(slhDsa)))), + AssertExtensions.SequenceEqual(info.PrivateKey, export(slhDsa)))), info.Algorithm, - info.SecretKey); + info.PrivateKey); } [Theory] @@ -314,8 +314,8 @@ public static void ImportPkcs8PrivateKeyIetf() using SlhDsa slhDsa = SlhDsa.ImportPkcs8PrivateKey(SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyPkcs8); Assert.Equal(SlhDsaAlgorithm.SlhDsaSha2_128s, slhDsa.Algorithm); - byte[] secretKey = slhDsa.ExportSlhDsaSecretKey(); - AssertExtensions.SequenceEqual(SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue, secretKey); + byte[] privateKey = slhDsa.ExportSlhDsaPrivateKey(); + AssertExtensions.SequenceEqual(SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue, privateKey); } [Fact] @@ -335,8 +335,8 @@ public static void ImportPemPrivateKeyIetf() using SlhDsa slhDsa = SlhDsa.ImportFromPem(pem); Assert.Equal(SlhDsaAlgorithm.SlhDsaSha2_128s, slhDsa.Algorithm); - byte[] secretKey = slhDsa.ExportSlhDsaSecretKey(); - AssertExtensions.SequenceEqual(SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue, secretKey); + byte[] privateKey = slhDsa.ExportSlhDsaPrivateKey(); + AssertExtensions.SequenceEqual(SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue, privateKey); } [Fact] @@ -365,7 +365,7 @@ public void NistKeyGenerationTest(SlhDsaTestData.SlhDsaKeyGenTestVector vector) byte[] skPrf = vector.SecretKeyPrf; byte[] pkSeed = vector.PublicKeySeed; - byte[] sk = vector.SecretKey; + byte[] sk = vector.PrivateKey; byte[] pk = vector.PublicKey; // Sanity test for input vectors: SLH-DSA keys are composed of skSeed, skPrf and pkSeed @@ -374,14 +374,14 @@ public void NistKeyGenerationTest(SlhDsaTestData.SlhDsaKeyGenTestVector vector) AssertExtensions.SequenceEqual(pkSeed.AsSpan(), sk.AsSpan(skSeed.Length + skPrf.Length, pkSeed.Length)); AssertExtensions.SequenceEqual(pkSeed.AsSpan(), pk.AsSpan(0, pkSeed.Length)); - // Import secret key and verify exports - using (SlhDsa secretSlhDsa = ImportSlhDsaSecretKey(vector.Algorithm, sk)) + // Import private key and verify exports + using (SlhDsa privateSlhDsa = ImportSlhDsaPrivateKey(vector.Algorithm, sk)) { - byte[] pubKey = secretSlhDsa.ExportSlhDsaPublicKey(); + byte[] pubKey = privateSlhDsa.ExportSlhDsaPublicKey(); AssertExtensions.SequenceEqual(pk, pubKey); - byte[] secretKey = secretSlhDsa.ExportSlhDsaSecretKey(); - AssertExtensions.SequenceEqual(sk, secretKey); + byte[] privateKey = privateSlhDsa.ExportSlhDsaPrivateKey(); + AssertExtensions.SequenceEqual(sk, privateKey); } // Import public key and verify exports @@ -390,8 +390,8 @@ public void NistKeyGenerationTest(SlhDsaTestData.SlhDsaKeyGenTestVector vector) byte[] pubKey = publicSlhDsa.ExportSlhDsaPublicKey(); AssertExtensions.SequenceEqual(pk, pubKey); - byte[] secretKey = new byte[vector.Algorithm.SecretKeySizeInBytes]; - Assert.Throws(() => publicSlhDsa.ExportSlhDsaSecretKey(secretKey)); + byte[] privateKey = new byte[vector.Algorithm.PrivateKeySizeInBytes]; + Assert.Throws(() => publicSlhDsa.ExportSlhDsaPrivateKey(privateKey)); } } @@ -400,16 +400,16 @@ public void NistKeyGenerationTest(SlhDsaTestData.SlhDsaKeyGenTestVector vector) [Fact] public static void ImportPkcs8_BerEncoding() { - // Secret key is DER encoded, so create a BER encoding from it by making it use indefinite length encoding. - byte[] secretKeyPkcs8 = SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyPkcs8; + // Private key is DER encoded, so create a BER encoding from it by making it use indefinite length encoding. + byte[] privateKeyPkcs8 = SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyPkcs8; // Two 0x00 bytes at the end signal the end of the indefinite length encoding - byte[] indefiniteLengthOctet = new byte[secretKeyPkcs8.Length + 2]; - secretKeyPkcs8.CopyTo(indefiniteLengthOctet); + byte[] indefiniteLengthOctet = new byte[privateKeyPkcs8.Length + 2]; + privateKeyPkcs8.CopyTo(indefiniteLengthOctet); indefiniteLengthOctet[1] = 0b1000_0000; // change length to indefinite SlhDsaTestHelpers.AssertImportPkcs8PrivateKey(import => - SlhDsaTestHelpers.AssertExportSlhDsaSecretKey(export => + SlhDsaTestHelpers.AssertExportSlhDsaPrivateKey(export => SlhDsaTestHelpers.WithDispose(import(indefiniteLengthOctet), slhDsa => AssertExtensions.SequenceEqual(SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue, export(slhDsa))))); } @@ -442,7 +442,7 @@ public void ImportPkcs8WithTrailingData(SlhDsaAlgorithm algorithm) [MemberData(nameof(SlhDsaTestData.GeneratedKeyInfosData), MemberType = typeof(SlhDsaTestData))] public void ExportEncryptedPkcs8PrivateKey_PbeParameters(SlhDsaTestData.SlhDsaGeneratedKeyInfo info) { - using SlhDsa slhDsa = ImportSlhDsaSecretKey(info.Algorithm, info.SecretKey); + using SlhDsa slhDsa = ImportSlhDsaPrivateKey(info.Algorithm, info.PrivateKey); SlhDsaTestHelpers.EncryptionPasswordType passwordTypeToTest = SlhDsaTestHelpers.GetValidPasswordTypes(info.EncryptionParameters); @@ -460,7 +460,7 @@ public void ExportEncryptedPkcs8PrivateKey_PbeParameters(SlhDsaTestData.SlhDsaGe [MemberData(nameof(SlhDsaTestData.GeneratedKeyInfosData), MemberType = typeof(SlhDsaTestData))] public void ExportKey_DestinationTooSmall(SlhDsaTestData.SlhDsaGeneratedKeyInfo info) { - using SlhDsa slhDsa = ImportSlhDsaSecretKey(info.Algorithm, info.SecretKey); + using SlhDsa slhDsa = ImportSlhDsaPrivateKey(info.Algorithm, info.PrivateKey); byte[] pkcs8PrivateKey = slhDsa.ExportPkcs8PrivateKey(); byte[] spki = slhDsa.ExportSubjectPublicKeyInfo(); byte[] encryptedPkcs8 = slhDsa.ExportEncryptedPkcs8PrivateKey(info.EncryptionPassword, info.EncryptionParameters); @@ -518,6 +518,6 @@ public void ExportKey_DestinationTooSmall(SlhDsaTestData.SlhDsaGeneratedKeyInfo protected override SlhDsa GenerateKey(SlhDsaAlgorithm algorithm) => SlhDsa.GenerateKey(algorithm); protected override SlhDsa ImportSlhDsaPublicKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) => SlhDsa.ImportSlhDsaPublicKey(algorithm, source); - protected override SlhDsa ImportSlhDsaSecretKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) => SlhDsa.ImportSlhDsaSecretKey(algorithm, source); + protected override SlhDsa ImportSlhDsaPrivateKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) => SlhDsa.ImportSlhDsaPrivateKey(algorithm, source); } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaMockImplementation.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaMockImplementation.cs index c02699376ea588..56d8dfa7c81637 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaMockImplementation.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaMockImplementation.cs @@ -25,7 +25,7 @@ public SlhDsaMockImplementation(SlhDsaAlgorithm algorithm) } public delegate void ExportSlhDsaPublicKeyCoreAction(Span s); - public delegate void ExportSlhDsaSecretKeyCoreAction(Span s); + public delegate void ExportSlhDsaPrivateKeyCoreAction(Span s); public delegate bool TryExportPkcs8PrivateKeyCoreFunc(Span destination, out int bytesWritten); public delegate void SignDataCoreAction(ReadOnlySpan data, ReadOnlySpan context, Span s); public delegate bool VerifyDataCoreFunc(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature); @@ -41,12 +41,12 @@ public SlhDsaMockImplementation(SlhDsaAlgorithm algorithm) public int VerifyPreHashCoreCallCount = 0; public int SignPreHashCoreCallCount = 0; public int ExportSlhDsaPublicKeyCoreCallCount = 0; - public int ExportSlhDsaSecretKeyCoreCallCount = 0; + public int ExportSlhDsaPrivateKeyCoreCallCount = 0; public int TryExportPkcs8PrivateKeyCoreCallCount = 0; public int DisposeCallCount = 0; public ExportSlhDsaPublicKeyCoreAction ExportSlhDsaPublicKeyCoreHook { get; set; } = _ => Assert.Fail(); - public ExportSlhDsaSecretKeyCoreAction ExportSlhDsaSecretKeyCoreHook { get; set; } = _ => Assert.Fail(); + public ExportSlhDsaPrivateKeyCoreAction ExportSlhDsaPrivateKeyCoreHook { get; set; } = _ => Assert.Fail(); public TryExportPkcs8PrivateKeyCoreFunc TryExportPkcs8PrivateKeyCoreHook { get; set; } = (_, out bytesWritten) => { Assert.Fail(); bytesWritten = 0; return false; }; public SignDataCoreAction SignDataCoreHook { get; set; } = (_, _, _) => Assert.Fail(); @@ -61,10 +61,10 @@ protected override void ExportSlhDsaPublicKeyCore(Span destination) ExportSlhDsaPublicKeyCoreHook(destination); } - protected override void ExportSlhDsaSecretKeyCore(Span destination) + protected override void ExportSlhDsaPrivateKeyCore(Span destination) { - ExportSlhDsaSecretKeyCoreCallCount++; - ExportSlhDsaSecretKeyCoreHook(destination); + ExportSlhDsaPrivateKeyCoreCallCount++; + ExportSlhDsaPrivateKeyCoreHook(destination); } protected override void Dispose(bool disposing) @@ -112,11 +112,11 @@ public void AddLengthAssertion() Assert.Equal(Algorithm.PublicKeySizeInBytes, destination.Length); }; - ExportSlhDsaSecretKeyCoreAction oldExportSlhDsaSecretKeyCoreHook = ExportSlhDsaSecretKeyCoreHook; - ExportSlhDsaSecretKeyCoreHook = (Span destination) => + ExportSlhDsaPrivateKeyCoreAction oldExportSlhDsaPrivateKeyCoreHook = ExportSlhDsaPrivateKeyCoreHook; + ExportSlhDsaPrivateKeyCoreHook = (Span destination) => { - oldExportSlhDsaSecretKeyCoreHook(destination); - Assert.Equal(Algorithm.SecretKeySizeInBytes, destination.Length); + oldExportSlhDsaPrivateKeyCoreHook(destination); + Assert.Equal(Algorithm.PrivateKeySizeInBytes, destination.Length); }; SignDataCoreAction oldSignDataCoreHook = SignDataCoreHook; @@ -159,10 +159,10 @@ public void AddDestinationBufferIsSameAssertion(ReadOnlyMemory buffer) AssertExtensions.Same(buffer.Span, destination); }; - ExportSlhDsaSecretKeyCoreAction oldExportSlhDsaSecretKeyCoreHook = ExportSlhDsaSecretKeyCoreHook; - ExportSlhDsaSecretKeyCoreHook = (Span destination) => + ExportSlhDsaPrivateKeyCoreAction oldExportSlhDsaPrivateKeyCoreHook = ExportSlhDsaPrivateKeyCoreHook; + ExportSlhDsaPrivateKeyCoreHook = (Span destination) => { - oldExportSlhDsaSecretKeyCoreHook(destination); + oldExportSlhDsaPrivateKeyCoreHook(destination); AssertExtensions.Same(buffer.Span, destination); }; @@ -301,10 +301,10 @@ public void AddFillDestination(byte b) destination.Fill(b); }; - ExportSlhDsaSecretKeyCoreAction oldExportSlhDsaSecretKeyCoreHook = ExportSlhDsaSecretKeyCoreHook; - ExportSlhDsaSecretKeyCoreHook = (Span destination) => + ExportSlhDsaPrivateKeyCoreAction oldExportSlhDsaPrivateKeyCoreHook = ExportSlhDsaPrivateKeyCoreHook; + ExportSlhDsaPrivateKeyCoreHook = (Span destination) => { - oldExportSlhDsaSecretKeyCoreHook(destination); + oldExportSlhDsaPrivateKeyCoreHook(destination); destination.Fill(b); }; diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaTestData.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaTestData.cs index 497aa2fb13ee84..1c2a21d4591ecb 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaTestData.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaTestData.cs @@ -542,7 +542,7 @@ public static partial class SlhDsaTestData // Generate private key pem: // > openssl genpkey -algorithm "SLH-DSA-SHA2-128f" > private.pem // - // Get secret key: + // Get private key: // > openssl asn1parse -in private.pem | tail -1 | cut -d':' -f4 // // Get base64 private key info: @@ -558,7 +558,7 @@ public class SlhDsaGeneratedKeyInfo public SlhDsaGeneratedKeyInfo( int Id, SlhDsaAlgorithm Algorithm, - string SecretKeyHex, + string PrivateKeyHex, string Pkcs8PrivateKeyBase64, string Pkcs8PublicKeyBase64, string Pkcs8EncryptedPrivateKeyBase64, @@ -570,7 +570,7 @@ public SlhDsaGeneratedKeyInfo( { this.Id = Id; this.Algorithm = Algorithm; - this.SecretKeyHex = SecretKeyHex; + this.PrivateKeyHex = PrivateKeyHex; this.Pkcs8PrivateKeyBase64 = Pkcs8PrivateKeyBase64; this.Pkcs8PublicKeyBase64 = Pkcs8PublicKeyBase64; this.Pkcs8EncryptedPrivateKeyBase64 = Pkcs8EncryptedPrivateKeyBase64; @@ -583,7 +583,7 @@ public SlhDsaGeneratedKeyInfo( public int Id { get; } public SlhDsaAlgorithm Algorithm { get; } - public string SecretKeyHex { get; } + public string PrivateKeyHex { get; } public string Pkcs8PrivateKeyBase64 { get; } public string Pkcs8PublicKeyBase64 { get; } public string Pkcs8EncryptedPrivateKeyBase64 { get; } @@ -593,8 +593,8 @@ public SlhDsaGeneratedKeyInfo( public string EncryptionPassword { get; } public PbeParameters EncryptionParameters { get; } - public byte[] SecretKey => SecretKeyHex.HexToByteArray(); - public byte[] PublicKey => SecretKey.AsSpan(Algorithm.SecretKeySizeInBytes/2).ToArray(); + public byte[] PrivateKey => PrivateKeyHex.HexToByteArray(); + public byte[] PublicKey => PrivateKey.AsSpan(Algorithm.PrivateKeySizeInBytes/2).ToArray(); public byte[] Pkcs8PrivateKey => Convert.FromBase64String(Pkcs8PrivateKeyBase64); public byte[] Pkcs8PublicKey => Convert.FromBase64String(Pkcs8PublicKeyBase64); public byte[] Pkcs8EncryptedPrivateKey => Convert.FromBase64String(Pkcs8EncryptedPrivateKeyBase64); @@ -624,7 +624,7 @@ public SlhDsaKeyGenTestVector( string SecretKeySeedHex, string SecretKeyPrfHex, string PublicKeySeedHex, - string SecretKeyHex, + string PrivateKeyHex, string PublicKeyHex) { this.TestCaseId = TestCaseId; @@ -632,7 +632,7 @@ public SlhDsaKeyGenTestVector( this.SecretKeySeedHex = SecretKeySeedHex; this.SecretKeyPrfHex = SecretKeyPrfHex; this.PublicKeySeedHex = PublicKeySeedHex; - this.SecretKeyHex = SecretKeyHex; + this.PrivateKeyHex = PrivateKeyHex; this.PublicKeyHex = PublicKeyHex; } @@ -641,14 +641,14 @@ public SlhDsaKeyGenTestVector( public string SecretKeySeedHex { get; } public string SecretKeyPrfHex { get; } public string PublicKeySeedHex { get; } - public string SecretKeyHex { get; } + public string PrivateKeyHex { get; } public string PublicKeyHex { get; } public byte[] SecretKeySeed => SecretKeySeedHex.HexToByteArray(); public byte[] SecretKeyPrf => SecretKeyPrfHex.HexToByteArray(); public byte[] PublicKeySeed => PublicKeySeedHex.HexToByteArray(); - public byte[] SecretKey => SecretKeyHex.HexToByteArray(); + public byte[] PrivateKey => PrivateKeyHex.HexToByteArray(); public byte[] PublicKey => PublicKeyHex.HexToByteArray(); public override string ToString() => $"{nameof(SlhDsaKeyGenTestVector)} {{ {nameof(TestCaseId)} = {TestCaseId}, {nameof(Algorithm)} = \"{Algorithm.Name}\" }}"; @@ -774,7 +774,7 @@ public SlhDsaSigVerTestVector( int TestCaseId, bool TestPassed, SlhDsaAlgorithm Algorithm, - string SecretKeyHex, + string PrivateKeyHex, string PublicKeyHex, string MessageHex, string ContextHex, @@ -784,7 +784,7 @@ public SlhDsaSigVerTestVector( this.TestCaseId = TestCaseId; this.TestPassed = TestPassed; this.Algorithm = Algorithm; - this.SecretKeyHex = SecretKeyHex; + this.PrivateKeyHex = PrivateKeyHex; this.PublicKeyHex = PublicKeyHex; this.MessageHex = MessageHex; this.ContextHex = ContextHex; @@ -795,14 +795,14 @@ public SlhDsaSigVerTestVector( public int TestCaseId { get; } public bool TestPassed { get; } public SlhDsaAlgorithm Algorithm { get; } - public string SecretKeyHex { get; } + public string PrivateKeyHex { get; } public string PublicKeyHex { get; } public string MessageHex { get; } public string ContextHex { get; } public string SignatureHex { get; } public string HashAlgorithm { get; } - public byte[] SecretKey => SecretKeyHex.HexToByteArray(); + public byte[] PrivateKey => PrivateKeyHex.HexToByteArray(); public byte[] PublicKey => PublicKeyHex.HexToByteArray(); public byte[] Message => MessageHex.HexToByteArray(); public byte[] Context => ContextHex.HexToByteArray(); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaTestHelpers.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaTestHelpers.cs index 1331cc97e5c5a9..0849eede434f92 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaTestHelpers.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaTestHelpers.cs @@ -40,7 +40,7 @@ internal static void VerifyDisposed(SlhDsa slhDsa) Assert.Throws(() => slhDsa.ExportPkcs8PrivateKey()); Assert.Throws(() => slhDsa.ExportPkcs8PrivateKeyPem()); Assert.Throws(() => slhDsa.ExportSlhDsaPublicKey(tempBuffer.AsSpan(0, slhDsa.Algorithm.PublicKeySizeInBytes))); - Assert.Throws(() => slhDsa.ExportSlhDsaSecretKey(tempBuffer.AsSpan(0, slhDsa.Algorithm.SecretKeySizeInBytes))); + Assert.Throws(() => slhDsa.ExportSlhDsaPrivateKey(tempBuffer.AsSpan(0, slhDsa.Algorithm.PrivateKeySizeInBytes))); Assert.Throws(() => slhDsa.ExportSubjectPublicKeyInfo()); Assert.Throws(() => slhDsa.ExportSubjectPublicKeyInfoPem()); Assert.Throws(() => slhDsa.TryExportEncryptedPkcs8PrivateKey(ReadOnlySpan.Empty, pbeParameters, [], out _)); @@ -94,21 +94,21 @@ internal static void AssertImportSubjectKeyPublicInfo( testEmbeddedCall(spki => SlhDsa.ImportFromPem(PemEncoding.WriteString("PUBLIC KEY", spki).AsSpan())); } - internal static void AssertImportSecretKey(Action> test, SlhDsaAlgorithm algorithm, byte[] secretKey) => - AssertImportSecretKey(test, test, algorithm, secretKey); + internal static void AssertImportPrivateKey(Action> test, SlhDsaAlgorithm algorithm, byte[] PrivateKey) => + AssertImportPrivateKey(test, test, algorithm, PrivateKey); - internal static void AssertImportSecretKey(Action> testDirectCall, Action> testEmbeddedCall, SlhDsaAlgorithm algorithm, byte[] secretKey) + internal static void AssertImportPrivateKey(Action> testDirectCall, Action> testEmbeddedCall, SlhDsaAlgorithm algorithm, byte[] PrivateKey) { - testDirectCall(() => SlhDsa.ImportSlhDsaSecretKey(algorithm, secretKey)); + testDirectCall(() => SlhDsa.ImportSlhDsaPrivateKey(algorithm, PrivateKey)); - if (secretKey?.Length == 0) + if (PrivateKey?.Length == 0) { - testDirectCall(() => SlhDsa.ImportSlhDsaSecretKey(algorithm, Array.Empty().AsSpan())); - testDirectCall(() => SlhDsa.ImportSlhDsaSecretKey(algorithm, ReadOnlySpan.Empty)); + testDirectCall(() => SlhDsa.ImportSlhDsaPrivateKey(algorithm, Array.Empty().AsSpan())); + testDirectCall(() => SlhDsa.ImportSlhDsaPrivateKey(algorithm, ReadOnlySpan.Empty)); } else { - testDirectCall(() => SlhDsa.ImportSlhDsaSecretKey(algorithm, secretKey.AsSpan())); + testDirectCall(() => SlhDsa.ImportSlhDsaPrivateKey(algorithm, PrivateKey.AsSpan())); } PrivateKeyInfoAsn pkcs8 = new PrivateKeyInfoAsn @@ -118,7 +118,7 @@ internal static void AssertImportSecretKey(Action> testDirectCall, Algorithm = AlgorithmToOid(algorithm), Parameters = default(ReadOnlyMemory?), }, - PrivateKey = secretKey, + PrivateKey = PrivateKey, }; AssertImportPkcs8PrivateKey(import => @@ -220,14 +220,14 @@ internal static void AssertExportSlhDsaPublicKey(Action> ca SubjectPublicKeyInfoAsn.Decode(exportSpki(slhDsa), AsnEncodingRules.DER).SubjectPublicKey.Span.ToArray())); } - internal static void AssertExportSlhDsaSecretKey(Action> callback) + internal static void AssertExportSlhDsaPrivateKey(Action> callback) { - callback(slhDsa => slhDsa.ExportSlhDsaSecretKey()); + callback(slhDsa => slhDsa.ExportSlhDsaPrivateKey()); callback( slhDsa => { - byte[] buffer = new byte[slhDsa.Algorithm.SecretKeySizeInBytes]; - slhDsa.ExportSlhDsaSecretKey(buffer.AsSpan()); + byte[] buffer = new byte[slhDsa.Algorithm.PrivateKeySizeInBytes]; + slhDsa.ExportSlhDsaPrivateKey(buffer.AsSpan()); return buffer; }); @@ -406,16 +406,5 @@ internal static string AlgorithmToOid(SlhDsaAlgorithm algorithm) _ => throw new XunitException($"Unknown algorithm: '{algorithm?.Name}'."), }; } - - internal const string Md5Oid = "1.2.840.113549.2.5"; - internal const string Sha1Oid = "1.3.14.3.2.26"; - internal const string Sha256Oid = "2.16.840.1.101.3.4.2.1"; - internal const string Sha384Oid = "2.16.840.1.101.3.4.2.2"; - internal const string Sha512Oid = "2.16.840.1.101.3.4.2.3"; - internal const string Sha3_256Oid = "2.16.840.1.101.3.4.2.8"; - internal const string Sha3_384Oid = "2.16.840.1.101.3.4.2.9"; - internal const string Sha3_512Oid = "2.16.840.1.101.3.4.2.10"; - internal const string Shake128Oid = "2.16.840.1.101.3.4.2.11"; - internal const string Shake256Oid = "2.16.840.1.101.3.4.2.12"; } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaTests.cs index 4650f3e5ee1dcf..8cd6016c93af48 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/SlhDsa/SlhDsaTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; +using Test.Cryptography; using Xunit; using Xunit.Sdk; @@ -12,7 +13,7 @@ public abstract class SlhDsaTests { protected abstract SlhDsa GenerateKey(SlhDsaAlgorithm algorithm); protected abstract SlhDsa ImportSlhDsaPublicKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source); - protected abstract SlhDsa ImportSlhDsaSecretKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source); + protected abstract SlhDsa ImportSlhDsaPrivateKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source); public static IEnumerable NistPureSigVerTestVectorsData => from vector in SlhDsaTestData.NistSigVerTestVectors @@ -31,8 +32,8 @@ public void NistPureSignatureVerificationTest(SlhDsaTestData.SlhDsaSigVerTestVec using SlhDsa publicSlhDsa = ImportSlhDsaPublicKey(vector.Algorithm, vector.PublicKey); Assert.Equal(vector.TestPassed, publicSlhDsa.VerifyData(msg, sig, ctx)); - // Test signature verification with secret key - using SlhDsa secretSlhDsa = ImportSlhDsaSecretKey(vector.Algorithm, vector.SecretKey); + // Test signature verification with private key + using SlhDsa secretSlhDsa = ImportSlhDsaPrivateKey(vector.Algorithm, vector.PrivateKey); Assert.Equal(vector.TestPassed, secretSlhDsa.VerifyData(msg, sig, ctx)); } @@ -48,57 +49,14 @@ public void NistPreHashSignatureVerificationTest(SlhDsaTestData.SlhDsaSigVerTest byte[] msg = vector.Message; byte[] ctx = vector.Context; byte[] sig = vector.Signature; - byte[] hash; - -#if NET - if (vector.HashAlgorithm == SlhDsaTestHelpers.Shake128Oid) - { - using (Shake128 hasher = new Shake128()) - { - hasher.AppendData(msg); - hash = hasher.GetHashAndReset(256 / 8); - } - } - else if (vector.HashAlgorithm == SlhDsaTestHelpers.Shake256Oid) - { - using (Shake256 hasher = new Shake256()) - { - hasher.AppendData(msg); - hash = hasher.GetHashAndReset(512 / 8); - } - } - else -#endif - { - HashAlgorithmName hashAlgorithmName = - vector.HashAlgorithm switch - { - SlhDsaTestHelpers.Md5Oid => HashAlgorithmName.MD5, - SlhDsaTestHelpers.Sha1Oid => HashAlgorithmName.SHA1, - SlhDsaTestHelpers.Sha256Oid => HashAlgorithmName.SHA256, - SlhDsaTestHelpers.Sha384Oid => HashAlgorithmName.SHA384, - SlhDsaTestHelpers.Sha512Oid => HashAlgorithmName.SHA512, -#if NET - SlhDsaTestHelpers.Sha3_256Oid => HashAlgorithmName.SHA3_256, - SlhDsaTestHelpers.Sha3_384Oid => HashAlgorithmName.SHA3_384, - SlhDsaTestHelpers.Sha3_512Oid => HashAlgorithmName.SHA3_512, -#endif - _ => throw new XunitException($"Unknown hash algorithm OID: {vector.HashAlgorithm}"), - }; - - using (IncrementalHash hasher = IncrementalHash.CreateHash(hashAlgorithmName)) - { - hasher.AppendData(msg); - hash = hasher.GetHashAndReset(); - } - } + byte[] hash = HashInfo.HashData(vector.HashAlgorithm, msg); // Test signature verification with public key using SlhDsa publicSlhDsa = ImportSlhDsaPublicKey(vector.Algorithm, vector.PublicKey); Assert.Equal(vector.TestPassed, publicSlhDsa.VerifyPreHash(hash, sig, vector.HashAlgorithm, ctx)); - // Test signature verification with secret key - using SlhDsa secretSlhDsa = ImportSlhDsaSecretKey(vector.Algorithm, vector.SecretKey); + // Test signature verification with private key + using SlhDsa secretSlhDsa = ImportSlhDsaPrivateKey(vector.Algorithm, vector.PrivateKey); Assert.Equal(vector.TestPassed, secretSlhDsa.VerifyPreHash(hash, sig, vector.HashAlgorithm, ctx)); } @@ -198,19 +156,19 @@ public void GenerateSignExportPublicVerifyWithPublicOnly(SlhDsaAlgorithm algorit [Theory] [MemberData(nameof(AlgorithmsData_Small))] - public void GenerateExportSecretKeySignAndVerify(SlhDsaAlgorithm algorithm) + public void GenerateExportPrivateKeySignAndVerify(SlhDsaAlgorithm algorithm) { - byte[] secretKey; + byte[] privateKey; byte[] data = [1, 2, 3, 4, 5]; byte[] signature; using (SlhDsa slhDsa = GenerateKey(algorithm)) { signature = slhDsa.SignData(data); - secretKey = slhDsa.ExportSlhDsaSecretKey(); + privateKey = slhDsa.ExportSlhDsaPrivateKey(); } - using (SlhDsa slhDsa = ImportSlhDsaSecretKey(algorithm, secretKey)) + using (SlhDsa slhDsa = ImportSlhDsaPrivateKey(algorithm, privateKey)) { ExerciseSuccessfulVerify(slhDsa, data, signature, []); @@ -226,8 +184,8 @@ public void GenerateExportSecretKeySignAndVerify(SlhDsaAlgorithm algorithm) public void GenerateSignPreHashExportPublicVerifyWithPublicOnly(SlhDsaAlgorithm algorithm) { byte[] publicKey; - string shake256Oid = SlhDsaTestHelpers.Shake256Oid; - byte[] data = new byte[512 / 8]; + string shake256Oid = HashInfo.Shake256.Oid; + byte[] data = new byte[HashInfo.Shake256.OutputSize]; byte[] signature; using (SlhDsa slhDsa = GenerateKey(algorithm)) @@ -246,20 +204,20 @@ public void GenerateSignPreHashExportPublicVerifyWithPublicOnly(SlhDsaAlgorithm [Theory] [MemberData(nameof(AlgorithmsData_Small))] - public void GenerateExportSecretKeySignPreHashAndVerify(SlhDsaAlgorithm algorithm) + public void GenerateExportPrivateKeySignPreHashAndVerify(SlhDsaAlgorithm algorithm) { - byte[] secretKey; - string shake256Oid = SlhDsaTestHelpers.Shake256Oid; - byte[] data = new byte[512 / 8]; + byte[] privateKey; + string shake256Oid = HashInfo.Shake256.Oid; + byte[] data = new byte[HashInfo.Shake256.OutputSize]; byte[] signature; using (SlhDsa slhDsa = GenerateKey(algorithm)) { signature = slhDsa.SignPreHash(data, shake256Oid); - secretKey = slhDsa.ExportSlhDsaSecretKey(); + privateKey = slhDsa.ExportSlhDsaPrivateKey(); } - using (SlhDsa slhDsa = ImportSlhDsaSecretKey(algorithm, secretKey)) + using (SlhDsa slhDsa = ImportSlhDsaPrivateKey(algorithm, privateKey)) { ExerciseSuccessfulVerifyPreHash(slhDsa, data, signature, shake256Oid, []); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/ByteUtils.cs b/src/libraries/Common/tests/System/Security/Cryptography/ByteUtils.cs index 0b7e708f3eb22b..3c266f82a01d3b 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/ByteUtils.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/ByteUtils.cs @@ -109,8 +109,26 @@ internal static string PemEncode(string label, byte[] data) #if NET return PemEncoding.WriteString(label, data); #else - return - $"-----BEGIN {label}-----\n{Convert.ToBase64String(data, Base64FormattingOptions.InsertLineBreaks)}\n-----END {label}-----"; + StringBuilder sb = new StringBuilder(); + + sb.Append("-----BEGIN "); + sb.Append(label); + sb.Append("-----\n"); + + string base64 = Convert.ToBase64String(data); + + for (int i = 0; i < base64.Length; i += 64) + { + int len = Math.Min(64, base64.Length - i); + sb.Append(base64, i, len); + sb.Append('\n'); + } + + sb.Append("-----END "); + sb.Append(label); + sb.Append("-----"); + + return sb.ToString(); #endif } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/CompositeMLDsaAlgorithmTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/CompositeMLDsaAlgorithmTests.cs index 15e54c330f6f5b..2c312d55101aba 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/CompositeMLDsaAlgorithmTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/CompositeMLDsaAlgorithmTests.cs @@ -15,75 +15,75 @@ public static void AlgorithmsHaveExpectedParameters() algorithm = CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pss; Assert.Equal("MLDSA44-RSA2048-PSS-SHA256", algorithm.Name); - Assert.Equal(2676, algorithm.MaxSignatureSizeInBytes); // MLDsa44 (2420) + RSA2048 (256) + Assert.Equal(32 + 2420 + 256, algorithm.MaxSignatureSizeInBytes); // Randomizer + ML-DSA + Traditional Signature algorithm = CompositeMLDsaAlgorithm.MLDsa44WithRSA2048Pkcs15; Assert.Equal("MLDSA44-RSA2048-PKCS15-SHA256", algorithm.Name); - Assert.Equal(2676, algorithm.MaxSignatureSizeInBytes); // MLDsa44 (2420) + RSA2048 (256) + Assert.Equal(32 + 2420 + 256, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa44WithEd25519; Assert.Equal("MLDSA44-Ed25519-SHA512", algorithm.Name); - Assert.Equal(2484, algorithm.MaxSignatureSizeInBytes); // MLDsa44 (2420) + Ed25519 (64) + Assert.Equal(32 + 2420 + 64, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa44WithECDsaP256; Assert.Equal("MLDSA44-ECDSA-P256-SHA256", algorithm.Name); - Assert.Equal(2492, algorithm.MaxSignatureSizeInBytes); // MLDsa44 (2420) + ECDSA-P256 (72) + Assert.Equal(32 + 2420 + 72, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pss; Assert.Equal("MLDSA65-RSA3072-PSS-SHA512", algorithm.Name); - Assert.Equal(3693, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + RSA3072 (384) + Assert.Equal(32 + 3309 + 384, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithRSA3072Pkcs15; Assert.Equal("MLDSA65-RSA3072-PKCS15-SHA512", algorithm.Name); - Assert.Equal(3693, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + RSA3072 (384) + Assert.Equal(32 + 3309 + 384, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pss; Assert.Equal("MLDSA65-RSA4096-PSS-SHA512", algorithm.Name); - Assert.Equal(3821, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + RSA4096 (512) + Assert.Equal(32 + 3309 + 512, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithRSA4096Pkcs15; Assert.Equal("MLDSA65-RSA4096-PKCS15-SHA512", algorithm.Name); - Assert.Equal(3821, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + RSA4096 (512) + Assert.Equal(32 + 3309 + 512, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithECDsaP256; Assert.Equal("MLDSA65-ECDSA-P256-SHA512", algorithm.Name); - Assert.Equal(3381, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + ECDSA-P256 (72) + Assert.Equal(32 + 3309 + 72, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithECDsaP384; Assert.Equal("MLDSA65-ECDSA-P384-SHA512", algorithm.Name); - Assert.Equal(3413, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + ECDSA-P384 (104) + Assert.Equal(32 + 3309 + 104, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithECDsaBrainpoolP256r1; Assert.Equal("MLDSA65-ECDSA-brainpoolP256r1-SHA512", algorithm.Name); - Assert.Equal(3381, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + ECDSA-brainpoolP256r1 (72) + Assert.Equal(32 + 3309 + 72, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa65WithEd25519; Assert.Equal("MLDSA65-Ed25519-SHA512", algorithm.Name); - Assert.Equal(3373, algorithm.MaxSignatureSizeInBytes); // MLDsa65 (3309) + Ed25519 (64) + Assert.Equal(32 + 3309 + 64, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa87WithECDsaP384; Assert.Equal("MLDSA87-ECDSA-P384-SHA512", algorithm.Name); - Assert.Equal(4731, algorithm.MaxSignatureSizeInBytes); // MLDsa87 (4627) + ECDSA-P384 (104) + Assert.Equal(32 + 4627 + 104, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa87WithECDsaBrainpoolP384r1; Assert.Equal("MLDSA87-ECDSA-brainpoolP384r1-SHA512", algorithm.Name); - Assert.Equal(4731, algorithm.MaxSignatureSizeInBytes); // MLDsa87 (4627) + ECDSA-brainpoolP384r1 (104) + Assert.Equal(32 + 4627 + 104, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa87WithEd448; Assert.Equal("MLDSA87-Ed448-SHAKE256", algorithm.Name); - Assert.Equal(4741, algorithm.MaxSignatureSizeInBytes); // MLDsa87 (4627) + Ed448 (114) + Assert.Equal(32 + 4627 + 114, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa87WithRSA3072Pss; Assert.Equal("MLDSA87-RSA3072-PSS-SHA512", algorithm.Name); - Assert.Equal(5011, algorithm.MaxSignatureSizeInBytes); // MLDsa87 (4627) + RSA3072 (384) + Assert.Equal(32 + 4627 + 384, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa87WithRSA4096Pss; Assert.Equal("MLDSA87-RSA4096-PSS-SHA512", algorithm.Name); - Assert.Equal(5139, algorithm.MaxSignatureSizeInBytes); // MLDsa87 (4627) + RSA4096 (512) + Assert.Equal(32 + 4627 + 512, algorithm.MaxSignatureSizeInBytes); algorithm = CompositeMLDsaAlgorithm.MLDsa87WithECDsaP521; Assert.Equal("MLDSA87-ECDSA-P521-SHA512", algorithm.Name); - Assert.Equal(4766, algorithm.MaxSignatureSizeInBytes); // MLDsa87 (4627) + ECDSA-P521 (139) + Assert.Equal(32 + 4627 + 139, algorithm.MaxSignatureSizeInBytes); } [Fact] diff --git a/src/libraries/Common/tests/System/Security/Cryptography/HashInfo.cs b/src/libraries/Common/tests/System/Security/Cryptography/HashInfo.cs new file mode 100644 index 00000000000000..c43a9b2869cd97 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/HashInfo.cs @@ -0,0 +1,118 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using Xunit; +using Xunit.Sdk; + +namespace Test.Cryptography +{ + public class HashInfo + { + private const string Md5Oid = "1.2.840.113549.2.5"; + private const string Sha1Oid = "1.3.14.3.2.26"; + + private const string Sha256Oid = "2.16.840.1.101.3.4.2.1"; + private const string Sha384Oid = "2.16.840.1.101.3.4.2.2"; + private const string Sha512Oid = "2.16.840.1.101.3.4.2.3"; + + private const string Sha3_256Oid = "2.16.840.1.101.3.4.2.8"; + private const string Sha3_384Oid = "2.16.840.1.101.3.4.2.9"; + private const string Sha3_512Oid = "2.16.840.1.101.3.4.2.10"; + + private const string Shake128Oid = "2.16.840.1.101.3.4.2.11"; + private const string Shake256Oid = "2.16.840.1.101.3.4.2.12"; + + public static readonly HashInfo Md5 = new HashInfo(Md5Oid, 128 / 8, HashAlgorithmName.MD5); + public static readonly HashInfo Sha1 = new HashInfo(Sha1Oid, 160 / 8, HashAlgorithmName.SHA1); + public static readonly HashInfo Sha256 = new HashInfo(Sha256Oid, 256 / 8, HashAlgorithmName.SHA256); + 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("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("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); + public static readonly HashInfo Sha3_384 = new HashInfo(Sha3_384Oid, 384 / 8, HashAlgSHA3_384); + public static readonly HashInfo Sha3_512 = new HashInfo(Sha3_512Oid, 512 / 8, HashAlgSHA3_512); + public static readonly HashInfo Shake128 = new HashInfo(Shake128Oid, 256 / 8, HashAlgSHAKE128); + public static readonly HashInfo Shake256 = new HashInfo(Shake256Oid, 512 / 8, HashAlgSHAKE256); + + public string Oid { get; } + public HashAlgorithmName Name { get; } + public int OutputSize { get; } + + public byte[] GetHash(byte[] data) + { +#if NET + if (Oid == Shake128Oid) + { + return System.Security.Cryptography.Shake128.HashData(data, OutputSize); + } + else if (Oid == Shake256Oid) + { + return System.Security.Cryptography.Shake256.HashData(data, OutputSize); + } + else +#endif + { + using (IncrementalHash hasher = IncrementalHash.CreateHash(Name)) + { + hasher.AppendData(data); + return hasher.GetHashAndReset(); + } + } + } + + public static byte[] HashData(string hashAlgOid, byte[] data) + { + HashInfo hashInfo = AllHashInfos().FirstOrDefault(h => h.Oid == hashAlgOid); + if (hashInfo == null) + { + throw new ArgumentException($"Unknown hash algorithm OID: {hashAlgOid}", nameof(hashAlgOid)); + } + + return hashInfo.GetHash(data); + } + + public static IEnumerable AllHashInfos() + { + yield return Sha256; + yield return Sha384; + yield return Sha512; +#if NET + yield return Sha3_256; + yield return Sha3_384; + yield return Sha3_512; + yield return Shake128; + yield return Shake256; +#endif + } + + internal static HashSet KnownHashAlgorithmOids => field ??= AllHashInfos().Select(h => h.Oid).ToHashSet(); + + private HashInfo(string oid, int outputSize, HashAlgorithmName name) + { + Oid = oid; + OutputSize = outputSize; + Name = name; + } + + public override string ToString() + { + return $"{Name.Name}"; + } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs index 08e9e507176850..5f97ca8d3d576a 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs +++ b/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/libraries/Common/tests/System/Security/Cryptography/MLKemCngTests.NotSupported.cs b/src/libraries/Common/tests/System/Security/Cryptography/MLKemCngTests.NotSupported.cs index bdb64d4638eee6..fd29006249c75b 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/MLKemCngTests.NotSupported.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/MLKemCngTests.NotSupported.cs @@ -10,7 +10,7 @@ namespace System.Security.Cryptography.Tests [PlatformSpecific(~TestPlatforms.Windows)] public sealed class MLKemCngNotSupportedTests { - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBuiltWithAggressiveTrimming))] public static void MLKemCng_NotSupportedOnNonWindowsPlatforms() { // We cannot actually construct a CngKey on non-Windows platforms, so this cheats by just instantiating diff --git a/src/libraries/Common/tests/System/Security/Cryptography/PbeParametersTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/PbeParametersTests.cs index e5e74fb3e48600..48f6f2b4836371 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/PbeParametersTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/PbeParametersTests.cs @@ -31,7 +31,7 @@ public static void EncryptionAlgorithm_NotVerified(int algId) [InlineData("Potato")] [InlineData("")] [InlineData(null)] - public static void HashAlgorithm_NotVerified(string algId) + public static void HashAlgorithm_NotVerified(string? algId) { HashAlgorithmName hashName = new HashAlgorithmName(algId); @@ -54,7 +54,7 @@ public static void HashAlgorithm_NotVerified_DefaultValue() [InlineData("SHA256")] [InlineData("Potato")] [InlineData(default)] - public static void Pkcs12_NotVerifed_InCtor(string hashAlgName) + public static void Pkcs12_NotVerifed_InCtor(string? hashAlgName) { HashAlgorithmName hashName = new HashAlgorithmName(hashAlgName); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs b/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs index 5eb6d097026c65..31191e4164195c 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/SP800108HmacCounterKdfTests.Functional.cs @@ -95,7 +95,7 @@ public static void EmptyTests(byte[] key, string label, string context, byte[] e [InlineData(nameof(HashAlgorithmName.SHA512), 1024 / 8 - 1, new byte[] { 0xa4, 0xe5, 0x24, 0xe8, 0x56, 0x2b, 0x48, 0xa4 })] [InlineData(nameof(HashAlgorithmName.SHA512), 1024 / 8, new byte[] { 0xba, 0xf6, 0xed, 0xa7, 0x3a, 0xf7, 0x12, 0x27 })] [InlineData(nameof(HashAlgorithmName.SHA512), 1024 / 8 + 1, new byte[] { 0x34, 0xdf, 0x2d, 0x21, 0xfd, 0xf1, 0x0e, 0x13 })] -#if NET8_0_OR_GREATER +#if NET [InlineData("SHA3-256", 1088 / 8 - 1, new byte[] { 0xa1, 0x96, 0xae, 0x83, 0x56, 0xf4, 0x2a, 0x4b })] [InlineData("SHA3-256", 1088 / 8, new byte[] { 0xe7, 0xe9, 0xe0, 0x98, 0x09, 0x54, 0x54, 0x2d })] [InlineData("SHA3-256", 1088 / 8 + 1, new byte[] { 0x7d, 0x7a, 0x71, 0xdf, 0x1f, 0x5d, 0x5b, 0x44 })] @@ -108,7 +108,7 @@ public static void EmptyTests(byte[] key, string label, string context, byte[] e #endif public static void Kdk_HmacBlockBoundarySizes(string hashAlgorithmName, int kdkSize, byte[] expected) { -#if NET8_0_OR_GREATER +#if NET if ((hashAlgorithmName == "SHA3-256" && !SHA3_256.IsSupported) || (hashAlgorithmName == "SHA3-384" && !SHA3_384.IsSupported) || (hashAlgorithmName == "SHA3-512" && !SHA3_512.IsSupported)) @@ -328,7 +328,7 @@ public static IEnumerable GetOutputLengthBoundaries() } }; -#if NET8_0_OR_GREATER +#if NET if (HMACSHA3_256.IsSupported) { // HMACSHA3_256 output size is 32 bytes diff --git a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs index 00198a9ac853e3..360c4e36c41190 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs @@ -488,7 +488,7 @@ private byte[] BuildCrlManually( if (CorruptRevocationSignature) { - signature[5] ^= 0xFF; + signature[^2] ^= 0xFF; } // CertificateList @@ -643,7 +643,7 @@ certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } if (CorruptRevocationSignature) { - signature[5] ^= 0xFF; + signature[^2] ^= 0xFF; } writer.WriteBitString(signature); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateCreation/PrivateKeyAssociationTests.Shared.cs b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateCreation/PrivateKeyAssociationTests.Shared.cs index 0b46c21a095a00..d680518e8bc5d5 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateCreation/PrivateKeyAssociationTests.Shared.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateCreation/PrivateKeyAssociationTests.Shared.cs @@ -6,7 +6,6 @@ using System.Security.Cryptography.SLHDsa.Tests; using Test.Cryptography; using Xunit; -using Xunit.Sdk; namespace System.Security.Cryptography.X509Certificates.Tests.CertificateCreation { @@ -18,6 +17,9 @@ public static partial class PrivateKeyAssociationTests private static partial Func CopyWithPrivateKey_SlhDsa { get; } private static partial Func GetSlhDsaPublicKey { get; } private static partial Func GetSlhDsaPrivateKey { get; } + private static partial Func CopyWithPrivateKey_MLDsa { get; } + private static partial Func GetMLDsaPublicKey { get; } + private static partial Func GetMLDsaPrivateKey { get; } [ConditionalFact(typeof(SlhDsa), nameof(SlhDsa.IsSupported))] public static void GetSlhDsaPublicKeyTest() @@ -67,7 +69,7 @@ public static void GetSlhDsaPrivateKeyTest() // Verify the key is actually private AssertExtensions.SequenceEqual( SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue, - certKey.ExportSlhDsaSecretKey()); + certKey.ExportSlhDsaPrivateKey()); } } } @@ -111,8 +113,8 @@ public static void CheckCopyWithPrivateKey_SlhDsa_OtherSlhDsa() { using (SlhDsaMockImplementation publicSlhDsa = SlhDsaMockImplementation.Create(SlhDsaAlgorithm.SlhDsaSha2_128s)) { - Exception e = new Exception("no secret key"); - publicSlhDsa.ExportSlhDsaSecretKeyCoreHook = _ => throw e; + Exception e = new Exception("no private key"); + publicSlhDsa.ExportSlhDsaPrivateKeyCoreHook = _ => throw e; publicSlhDsa.ExportSlhDsaPublicKeyCoreHook = (Span destination) => SlhDsaTestData.IetfSlhDsaSha2_128sPublicKeyValue.CopyTo(destination); @@ -122,7 +124,7 @@ public static void CheckCopyWithPrivateKey_SlhDsa_OtherSlhDsa() SlhDsaMockImplementation privateSlhDsa = SlhDsaMockImplementation.Create(SlhDsaAlgorithm.SlhDsaSha2_128s); privateSlhDsa.ExportSlhDsaPublicKeyCoreHook = (Span destination) => SlhDsaTestData.IetfSlhDsaSha2_128sPublicKeyValue.CopyTo(destination); - privateSlhDsa.ExportSlhDsaSecretKeyCoreHook = (Span destination) => + privateSlhDsa.ExportSlhDsaPrivateKeyCoreHook = (Span destination) => SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue.CopyTo(destination); using (X509Certificate2 privCert = CopyWithPrivateKey_SlhDsa(pubOnly, privateSlhDsa)) @@ -133,16 +135,16 @@ public static void CheckCopyWithPrivateKey_SlhDsa_OtherSlhDsa() { AssertExtensions.SequenceEqual( SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue, - certPrivateSlhDsa.ExportSlhDsaSecretKey()); + certPrivateSlhDsa.ExportSlhDsaPrivateKey()); privateSlhDsa.Dispose(); privateSlhDsa.ExportSlhDsaPublicKeyCoreHook = _ => Assert.Fail(); - privateSlhDsa.ExportSlhDsaSecretKeyCoreHook = _ => Assert.Fail(); + privateSlhDsa.ExportSlhDsaPrivateKeyCoreHook = _ => Assert.Fail(); // Ensure the key is actual a clone AssertExtensions.SequenceEqual( SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue, - certPrivateSlhDsa.ExportSlhDsaSecretKey()); + certPrivateSlhDsa.ExportSlhDsaPrivateKey()); } } } @@ -295,6 +297,415 @@ public static void CheckCopyWithPrivateKey_MLKem_OtherMLKem_DecapsulationKey() } } + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + public static void GetMLDsaPublicKeyTest() + { + // Cert without private key + using (X509Certificate2 cert = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) + using (MLDsa? certKey = GetMLDsaPublicKey(cert)) + { + Assert.NotNull(certKey); + byte[] publicKey = certKey.ExportMLDsaPublicKey(); + AssertExtensions.SequenceEqual(MLDsaTestsData.IetfMLDsa44.PublicKey, publicKey); + + // Verify the key is not actually private + Assert.ThrowsAny(() => certKey.SignData([1, 2, 3])); + } + + // Cert with private key + using (X509Certificate2 cert = LoadMLDsaIetfCertificateWithPrivateKey()) + using (MLDsa? certKey = GetMLDsaPublicKey(cert)) + { + Assert.NotNull(certKey); + byte[] publicKey = certKey.ExportMLDsaPublicKey(); + AssertExtensions.SequenceEqual(MLDsaTestsData.IetfMLDsa44.PublicKey, publicKey); + + // Verify the key is not actually private + Assert.ThrowsAny(() => certKey.SignData([1, 2, 3])); + } + } + + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + public static void GetMLDsaPrivateKeyTest() + { + // Cert without private key + using (X509Certificate2 cert = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) + { + using (MLDsa? certKey = GetMLDsaPrivateKey(cert)) + { + Assert.Null(certKey); + } + } + + // Cert with private key + using (X509Certificate2 certWithPrivateKey = LoadMLDsaIetfCertificateWithPrivateKey()) + { + using (MLDsa? certKey = GetMLDsaPrivateKey(certWithPrivateKey)) + { + Assert.NotNull(certKey); + + // Verify the key is actually private + byte[] privateSeed = certKey.ExportMLDsaPrivateSeed(); + AssertExtensions.SequenceEqual( + MLDsaTestsData.IetfMLDsa44.PrivateSeed, + privateSeed); + } + } + } + + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + public static void CheckCopyWithPrivateKey_MLDSA() + { + Random rng = new Random(); + + using (X509Certificate2 pubOnly = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa65.Certificate)) + using (MLDsa privKey = MLDsa.ImportMLDsaPrivateSeed(MLDsaAlgorithm.MLDsa65, MLDsaTestsData.IetfMLDsa65.PrivateSeed)) + using (X509Certificate2 wrongAlg = X509CertificateLoader.LoadCertificate(TestData.CertWithEnhancedKeyUsage)) + { + CheckCopyWithPrivateKey( + pubOnly, + wrongAlg, + privKey, + [ + () => MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa44), + () => MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa65), + () => MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa87), + ], + (cert, key) => cert.CopyWithPrivateKey(key), + cert => cert.GetMLDsaPublicKey(), + cert => cert.GetMLDsaPrivateKey(), + (priv, pub) => + { + byte[] data = new byte[rng.Next(97)]; + rng.NextBytes(data); + + byte[] signature = priv.SignData(data); + Assert.True(pub.VerifyData(data, signature)); + }); + } + } + + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + public static void CheckCopyWithPrivateKey_MLDsa_OtherMLDsa_PrivateKey() + { + using (X509Certificate2 pubOnly = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) + { + using (MLDsaTestImplementation publicMLDsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44)) + { + Exception e = new Exception("no private key"); + + // The private key can be retrieved directly or from PKCS#8. If the seed is not available, + // it should fall back to the private key. + publicMLDsa.TryExportPkcs8PrivateKeyHook = (_, out _) => throw e; + publicMLDsa.ExportMLDsaPrivateKeyHook = _ => throw e; + publicMLDsa.ExportMLDsaPrivateSeedHook = _ => throw new CryptographicException("Should signal to try private key"); + publicMLDsa.ExportMLDsaPublicKeyHook = MLDsaTestsData.IetfMLDsa44.PublicKey.CopyTo; + + Assert.Same(e, AssertExtensions.Throws(() => CopyWithPrivateKey_MLDsa(pubOnly, publicMLDsa))); + } + + MLDsaTestImplementation privateMLDsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44); + privateMLDsa.ExportMLDsaPrivateSeedHook = _ => throw new CryptographicException("Should signal to try private key"); ; + privateMLDsa.ExportMLDsaPublicKeyHook = MLDsaTestsData.IetfMLDsa44.PublicKey.CopyTo; + privateMLDsa.ExportMLDsaPrivateKeyHook = MLDsaTestsData.IetfMLDsa44.PrivateKey.CopyTo; + + privateMLDsa.TryExportPkcs8PrivateKeyHook = (dest, out written) => + { + if (MLDsaTestsData.IetfMLDsa44.Pkcs8PrivateKey_Seed.AsSpan().TryCopyTo(dest)) + { + written = MLDsaTestsData.IetfMLDsa44.Pkcs8PrivateKey_Seed.Length; + return true; + } + + written = 0; + return false; + }; + + using (X509Certificate2 privCert = CopyWithPrivateKey_MLDsa(pubOnly, privateMLDsa)) + { + AssertExtensions.TrueExpression(privCert.HasPrivateKey); + + using (MLDsa certPrivateMLDsa = GetMLDsaPrivateKey(privCert)) + { + byte[] privateKey = certPrivateMLDsa.ExportMLDsaPrivateKey(); + AssertExtensions.SequenceEqual( + MLDsaTestsData.IetfMLDsa44.PrivateKey, + privateKey); + + privateMLDsa.Dispose(); + privateMLDsa.ExportMLDsaPrivateSeedHook = _ => Assert.Fail(); + privateMLDsa.ExportMLDsaPublicKeyHook = _ => Assert.Fail(); + privateMLDsa.ExportMLDsaPrivateKeyHook = _ => Assert.Fail(); + privateMLDsa.TryExportPkcs8PrivateKeyHook = (_, out w) => { Assert.Fail(); w = 0; return false; }; + + // Ensure the key is actual a clone + privateKey = certPrivateMLDsa.ExportMLDsaPrivateKey(); + AssertExtensions.SequenceEqual( + MLDsaTestsData.IetfMLDsa44.PrivateKey, + privateKey); + } + } + } + } + + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + public static void CheckCopyWithPrivateKey_MLDsa_OtherMLDsa_PrivateSeed() + { + using (X509Certificate2 pubOnly = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) + { + using (MLDsaTestImplementation publicMLDsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44)) + { + Exception e = new Exception("no private key"); + + // The private seed can be retrieved directly or from PKCS#8 + publicMLDsa.TryExportPkcs8PrivateKeyHook = (_, out _) => throw e; + publicMLDsa.ExportMLDsaPrivateSeedHook = _ => throw e; + publicMLDsa.ExportMLDsaPublicKeyHook = MLDsaTestsData.IetfMLDsa44.PublicKey.CopyTo; + + Assert.Same(e, AssertExtensions.Throws(() => CopyWithPrivateKey_MLDsa(pubOnly, publicMLDsa))); + } + + MLDsaTestImplementation privateMLDsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44); + privateMLDsa.ExportMLDsaPublicKeyHook = MLDsaTestsData.IetfMLDsa44.PublicKey.CopyTo; + privateMLDsa.ExportMLDsaPrivateSeedHook = MLDsaTestsData.IetfMLDsa44.PrivateSeed.CopyTo; + + privateMLDsa.TryExportPkcs8PrivateKeyHook = (dest, out written) => + { + if (MLDsaTestsData.IetfMLDsa44.Pkcs8PrivateKey_Seed.AsSpan().TryCopyTo(dest)) + { + written = MLDsaTestsData.IetfMLDsa44.Pkcs8PrivateKey_Seed.Length; + return true; + } + + written = 0; + return false; + }; + + using (X509Certificate2 privCert = CopyWithPrivateKey_MLDsa(pubOnly, privateMLDsa)) + { + AssertExtensions.TrueExpression(privCert.HasPrivateKey); + + using (MLDsa certPrivateMLDsa = GetMLDsaPrivateKey(privCert)) + { + byte[] privateKey = certPrivateMLDsa.ExportMLDsaPrivateSeed(); + AssertExtensions.SequenceEqual( + MLDsaTestsData.IetfMLDsa44.PrivateSeed, + privateKey); + + privateMLDsa.Dispose(); + privateMLDsa.ExportMLDsaPublicKeyHook = _ => Assert.Fail(); + privateMLDsa.ExportMLDsaPrivateSeedHook = _ => Assert.Fail(); + privateMLDsa.TryExportPkcs8PrivateKeyHook = (_, out w) => { Assert.Fail(); w = 0; return false; }; + + // Ensure the key is actual a clone + privateKey = certPrivateMLDsa.ExportMLDsaPrivateSeed(); + AssertExtensions.SequenceEqual( + MLDsaTestsData.IetfMLDsa44.PrivateSeed, + privateKey); + } + } + } + } + + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + public static void CheckCopyWithPrivateKey_MLDsa_OtherMLDsa_WrongPkcs8() + { + const string rsaPkcs8Base64 = """ + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCnDBnNKDxAQOPeb8M+OvGurjRi + 2lB+a2VdTspZXxvRt2wXwtyyqWcV+wGGvLE74hGE21UFPW4Jd2iefuKlkn9U/dvcPEGQjuClO1EY + FlFcZ1Y9LwNuXuS1IA4doiuzEyYgxXJje8w5CIisqXmwZEJX/OY4yEYE4OV/3xoI5FIGv9Kp2AsU + ttGaD2uzgsrCUe1Cj7L6IhBBiqvcp55icXlWXb0oSjd/ovhFgrn9+IPW7ln8wGRRRHKwIi+TBuXK + k7WOVcUECaPZIR7n8AuHHJ90sZHieSnIiMKzah8ZnFc1yG1Y9EnP3jWT00SZ2at84j/vkwfK87lj + gf9Gx9Gg5kVZAgMBAAECggEARofWcQf3AI4laCq6PhE3MDD/j2lsKSSBRPdaeoeswEx4yEOPWaQr + EV3M1C3hi041ZWoSKMc6KacQNjOO0KfdOW6CISgT6sxYz4sO/2OU8LX09JpgEX7hhBRHwX1ShCam + p5mWZajEnqQayQQ5jB+Y33u5XOo6nh6y5920KWL1u0Ed3aYHVa/+rfCIfctsEx+n2CBsiAX4fTaB + ZtTpZaQlDrDnOPtPDcJ1NOq7L/JwBYn6euBwkOZIl9VQ0q0mZ5YkXr9WB0BwNlRSvqa06b7y16qS + 1Y1M4jRzoYEl4hh7mKzVDrkyAVH2oFEsplMIufIQpt3rFvj+vUQciCY2bz8VrQKBgQDcffvWyKnz + Twr/nReoGXvkkYt/RBEZsNVZko4BJK0RYXQLUrPCFy8kxzIidgVPYlVvym3hYYpRXMnydTR0pEHn + UWv9fFp6EISFdssEvP4PvQq1T0EPH6yTo1DflUe82YDtYA/l/nqg24IqYaa7nF2O1RESLYFixh7y + oM1vsn42TwKBgQDB8swph+ei+1v+V64I3s/rQUhl/6FKwxVF4UbmBKlbd/YtAr1ccljNefeXRmWc + KmsVGO/Py5eD+VGNk9EUzZLRFqRnbbhTxPYufCGd4cImvlPceN6U/QS5x/52FJPUvIKVNWw7rgxd + 8Fr5YZDNi28ChvVdJBozjIgthElGQ82H1wKBgFikQVmAxGovbcGDex42WIt0Q7t/Nsy4PZ1MANDO + 2NDy978RmXi+71H+ztXx0oKuiqBtpi0ElKHPBtT1b4gw/Nms7xgyJQGLoGszbbzS6eST4Dkxynr1 + BeE4t+uazQNMAbvscZfJ7ay7cqHtLiWgYDBq0fkX2DtIYOqz4MM14+2bAoGAJ5Qisb74ODxPU6IU + 8950U6/o1FfMVHNnHfGRBFOjM/VRGXJbrkfvc08WhZpqFepaG94Q4jjL3LS+PcQSgMpK0bxrJGgx + m3awPmA6g/uUIU/p0S4hTgosMrVrajFc0ab+hvB1+9/SykDIb+fHIwr3Rm7AF5fMeQSOras3QM2J + XdUCgYEAtsHg+5g8UmIivixcowQ0jd4xoFV54oxJqIywtwWbHKkkiTEC87Y/bM+yB/FOz9CY6zsj + czacDBoMMwiiYWhY4fgfwOpsw+B+ZOX95bBd99iGip5Rv+QeOUCoDibCo0thYuF3ZeRCa+A02xVe + urOzLZcZZcL09b35iX6IaxosmNM= + """; + + byte[] rsaPkcs8 = Convert.FromBase64String(rsaPkcs8Base64); + + using (X509Certificate2 ietfCert = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) + using (MLDsaTestImplementation keyThatExportsRsaPkcs8 = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44)) + { + keyThatExportsRsaPkcs8.ExportMLDsaPublicKeyHook = MLDsaTestsData.IetfMLDsa44.PublicKey.CopyTo; + keyThatExportsRsaPkcs8.ExportMLDsaPrivateSeedHook = MLDsaTestsData.IetfMLDsa44.PrivateSeed.CopyTo; + + // Export RSA PKCS#8 + keyThatExportsRsaPkcs8.TryExportPkcs8PrivateKeyHook = (dest, out written) => + { + if (rsaPkcs8.AsSpan().TryCopyTo(dest)) + { + written = rsaPkcs8.Length; + return true; + } + + written = 0; + return false; + }; + + if (PlatformDetection.IsWindows) + { + // Only Windows uses PKCS#8 for pairing key to cert. + AssertExtensions.Throws(() => ietfCert.CopyWithPrivateKey(keyThatExportsRsaPkcs8)); + } + else + { + // Assert.NoThrow + using (ietfCert.CopyWithPrivateKey(keyThatExportsRsaPkcs8)) { } + } + } + } + + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + public static void CheckCopyWithPrivateKey_MLDsa_OtherMLDsa_MalformedPkcs8() + { + using (X509Certificate2 ietfCert = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) + using (MLDsaTestImplementation keyThatExportsMalformedPkcs8 = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44)) + { + keyThatExportsMalformedPkcs8.ExportMLDsaPublicKeyHook = MLDsaTestsData.IetfMLDsa44.PublicKey.CopyTo; + keyThatExportsMalformedPkcs8.ExportMLDsaPrivateSeedHook = MLDsaTestsData.IetfMLDsa44.PrivateSeed.CopyTo; + + // Export malformed PKCS#8 + keyThatExportsMalformedPkcs8.TryExportPkcs8PrivateKeyHook = + (dest, out written) => + { + written = 0; + return true; + }; + + if (PlatformDetection.IsWindows) + { + // Only Windows uses PKCS#8 for pairing key to cert. + AssertExtensions.Throws(() => ietfCert.CopyWithPrivateKey(keyThatExportsMalformedPkcs8)); + } + else + { + // Assert.NoThrow + using (ietfCert.CopyWithPrivateKey(keyThatExportsMalformedPkcs8)) { } + } + } + } + + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + [PlatformSpecific(TestPlatforms.Windows)] + public static void AssociatePersistedKey_CNG_MLDsa() + { + const string KeyName = $"{nameof(PrivateKeyAssociationTests)}_{nameof(AssociatePersistedKey_CNG_MLDsa)}"; + + CngKeyCreationParameters creationParameters = new CngKeyCreationParameters() + { + ExportPolicy = CngExportPolicies.None, + Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider, + KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey, + }; + + CngProperty parameterSet = MLDsaTestHelpers.GetCngProperty(MLDsaAlgorithm.MLDsa44); + creationParameters.Parameters.Add(parameterSet); + + // Blob for IETF ML-DSA-44 seed + byte[] pqDsaSeedBlob = Convert.FromBase64String("RFNTUwYAAAAgAAAANAA0AAAAAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8="); + CngProperty mldsaBlob = new CngProperty( + CngKeyBlobFormat.PQDsaPrivateSeedBlob.ToString(), + pqDsaSeedBlob, + CngPropertyOptions.None); + creationParameters.Parameters.Add(mldsaBlob); + + CngKey cngKey = null; + byte[] signature = new byte[MLDsaAlgorithm.MLDsa44.SignatureSizeInBytes]; + + try + { + cngKey = CngKey.Create(CngAlgorithm.MLDsa, KeyName, creationParameters); + + using (MLDsaCng mldsaCng = new MLDsaCng(cngKey)) + using (X509Certificate2 unpairedCert = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) + using (X509Certificate2 cert = unpairedCert.CopyWithPrivateKey(mldsaCng)) + using (MLDsa mldsa = cert.GetMLDsaPrivateKey()) + { + mldsa.SignData("test"u8, signature); + Assert.True(mldsaCng.VerifyData("test"u8, signature)); + } + + // Some certs have disposed, did they delete the key? + using (CngKey stillPersistedKey = CngKey.Open(KeyName, CngProvider.MicrosoftSoftwareKeyStorageProvider)) + using (MLDsaCng mldsa = new MLDsaCng(stillPersistedKey)) + { + mldsa.SignData("test"u8, signature); + } + } + finally + { + cngKey?.Delete(); + } + } + + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + [PlatformSpecific(TestPlatforms.Windows)] + public static void AssociateEphemeralKey_CNG_MLDsa() + { + CngKeyCreationParameters creationParameters = new CngKeyCreationParameters + { + ExportPolicy = CngExportPolicies.AllowPlaintextExport, + }; + + CngProperty parameterSet = MLDsaTestHelpers.GetCngProperty(MLDsaAlgorithm.MLDsa44); + creationParameters.Parameters.Add(parameterSet); + + // Blob for IETF ML-DSA-44 seed + byte[] pqDsaSeedBlob = Convert.FromBase64String("RFNTUwYAAAAgAAAANAA0AAAAAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8="); + CngProperty mldsaBlob = new CngProperty( + CngKeyBlobFormat.PQDsaPrivateSeedBlob.ToString(), + pqDsaSeedBlob, + CngPropertyOptions.None); + creationParameters.Parameters.Add(mldsaBlob); + + byte[] signature = new byte[MLDsaAlgorithm.MLDsa44.SignatureSizeInBytes]; + + using (CngKey ephemeralCngKey = CngKey.Create(CngAlgorithm.MLDsa, keyName: null, creationParameters)) + { + using (MLDsaCng mldsaCng = new MLDsaCng(ephemeralCngKey)) + { + using (X509Certificate2 unpairedCert = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) + using (X509Certificate2 cert = unpairedCert.CopyWithPrivateKey(mldsaCng)) + using (MLDsa mldsa = cert.GetMLDsaPrivateKey()) + { + mldsa.SignData("test"u8, signature); + Assert.True(mldsaCng.VerifyData("test"u8, signature)); + } + + // Run a few iterations to catch nondeterministic use-after-dispose issues + for (int i = 0; i < 5; i++) + { + using (X509Certificate2 unpairedCert = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) + using (X509Certificate2 cert = unpairedCert.CopyWithPrivateKey(mldsaCng)) + { + } + } + + mldsaCng.SignData("test"u8, signature); + } + + // Some certs have disposed, did they delete the key? + using (MLDsaCng mldsa = new MLDsaCng(ephemeralCngKey)) + { + mldsa.SignData("test"u8, signature); + } + } + } + private static partial void CheckCopyWithPrivateKey( X509Certificate2 cert, X509Certificate2 wrongAlgorithmCert, @@ -373,7 +784,14 @@ private static partial void CheckCopyWithPrivateKey( private static X509Certificate2 LoadShlDsaIetfCertificateWithPrivateKey() { using (X509Certificate2 cert = X509CertificateLoader.LoadCertificate(SlhDsaTestData.IetfSlhDsaSha2_128sCertificate)) - using (SlhDsa? privateKey = SlhDsa.ImportSlhDsaSecretKey(SlhDsaAlgorithm.SlhDsaSha2_128s, SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue)) + using (SlhDsa? privateKey = SlhDsa.ImportSlhDsaPrivateKey(SlhDsaAlgorithm.SlhDsaSha2_128s, SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue)) + return cert.CopyWithPrivateKey(privateKey); + } + + private static X509Certificate2 LoadMLDsaIetfCertificateWithPrivateKey() + { + using (X509Certificate2 cert = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) + using (MLDsa? privateKey = MLDsa.ImportMLDsaPrivateSeed(MLDsaAlgorithm.MLDsa44, MLDsaTestsData.IetfMLDsa44.PrivateSeed)) return cert.CopyWithPrivateKey(privateKey); } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12CollectionTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12CollectionTests.cs index da5a2d6a7e929a..791c64ff9f87c4 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12CollectionTests.cs +++ b/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/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12Tests.cs b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12Tests.cs index b2005ab6052ac0..2c58efcda33a6d 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12Tests.cs +++ b/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/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs b/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs index a40bbce709b054..f8b51f129837fb 100644 --- a/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs +++ b/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs @@ -100,8 +100,7 @@ protected virtual void Dispose(bool disposing) protected string GetRandomLinkPath([CallerMemberName] string memberName = null, [CallerLineNumber] int lineNumber = 0) => Path.Combine(TestDirectoryActualCasing, GetRandomLinkName(memberName, lineNumber)); protected string GetRandomDirPath([CallerMemberName] string memberName = null, [CallerLineNumber] int lineNumber = 0) => Path.Combine(TestDirectoryActualCasing, GetRandomDirName(memberName, lineNumber)); - private string _testDirectoryActualCasing; - private string TestDirectoryActualCasing => _testDirectoryActualCasing ??= GetTestDirectoryActualCasing(); + private string TestDirectoryActualCasing => field ??= GetTestDirectoryActualCasing(); /// Gets a test file full path that is associated with the call site. /// An optional index value to use as a suffix on the file name. Typically a loop index. diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs index f84bc20c1ef662..e432395e3e922a 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs @@ -34,7 +34,6 @@ public static partial class PlatformDetection public static bool IsNotMonoLinuxArm64 => !IsMonoLinuxArm64; public static bool IsQemuLinux => IsLinux && Environment.GetEnvironmentVariable("DOTNET_RUNNING_UNDER_QEMU") != null; public static bool IsNotQemuLinux => !IsQemuLinux; - public static bool IsNotAzureLinux => !IsAzureLinux; // OSX family public static bool IsApplePlatform => IsOSX || IsiOS || IstvOS || IsMacCatalyst; @@ -44,6 +43,7 @@ public static partial class PlatformDetection public static bool IsNotMacOsAppleSilicon => !IsMacOsAppleSilicon; public static bool IsAppSandbox => Environment.GetEnvironmentVariable("APP_SANDBOX_CONTAINER_ID") != null; public static bool IsNotAppSandbox => !IsAppSandbox; + public static bool IsApplePlatform26OrLater => IsApplePlatform && Environment.OSVersion.Version.Major >= 26; public static Version OpenSslVersion => !IsApplePlatform && !IsWindows && !IsAndroid ? GetOpenSslVersion() : @@ -57,6 +57,18 @@ public static partial class PlatformDetection public static bool IsOpenSsl3_4 => IsOpenSslVersionAtLeast(s_openssl3_4Version); public static bool IsOpenSsl3_5 => IsOpenSslVersionAtLeast(s_openssl3_5Version); + private static readonly Lazy s_isSymCryptOpenSsl = new(() => + { + return IsAzureLinux && + ( + File.Exists("/usr/lib/ossl-modules/symcryptprovider.so") || + File.Exists("/usr/lib64/ossl-modules/symcryptprovider.so") + ); + }); + + public static bool IsSymCryptOpenSsl => s_isSymCryptOpenSsl.Value; + public static bool IsNotSymCryptOpenSsl => !IsSymCryptOpenSsl; + /// /// If gnulibc is available, returns the release, such as "stable". /// Otherwise returns "glibc_not_found". diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index 9a7ef0734ad082..ebdd48c679fc97 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -547,7 +547,7 @@ private static bool GetSsl3Support() } - return (IsOSX || (IsLinux && OpenSslVersion < new Version(1, 0, 2) && !IsDebian)); + return ((IsOSX && !IsNetworkFrameworkEnabled()) || (IsLinux && OpenSslVersion < new Version(1, 0, 2) && !IsDebian)); } private static bool OpenSslGetTlsSupport(SslProtocols protocol) @@ -569,7 +569,7 @@ private static bool AndroidGetSslProtocolSupport(SslProtocols protocol) private static bool GetTls10Support() { // on macOS and Android TLS 1.0 is supported. - if (IsApplePlatform || IsAndroid) + if ((IsApplePlatform && !IsNetworkFrameworkEnabled()) || IsAndroid) { return true; } @@ -580,7 +580,7 @@ private static bool GetTls10Support() return GetProtocolSupportFromWindowsRegistry(SslProtocols.Tls, defaultProtocolSupport: true) && !IsWindows10Version20348OrGreater; } - return OpenSslGetTlsSupport(SslProtocols.Tls); + return IsOpenSslSupported && OpenSslGetTlsSupport(SslProtocols.Tls); } private static bool GetTls11Support() @@ -597,12 +597,12 @@ private static bool GetTls11Support() return GetProtocolSupportFromWindowsRegistry(SslProtocols.Tls11, defaultProtocolSupport: true) && !IsWindows10Version20348OrGreater; } // on macOS and Android TLS 1.1 is supported. - else if (IsApplePlatform || IsAndroid) + else if ((IsApplePlatform && !IsNetworkFrameworkEnabled()) || IsAndroid) { return true; } - return OpenSslGetTlsSupport(SslProtocols.Tls11); + return IsOpenSslSupported && OpenSslGetTlsSupport(SslProtocols.Tls11); } #pragma warning restore SYSLIB0039 @@ -665,6 +665,31 @@ private static bool GetTls13Support() return false; } + /// + /// Determines if Network.framework is enabled for SSL/TLS operations on Apple platforms. + /// This can be controlled via AppContext switch or environment variable. + /// + /// True if Network.framework is enabled, false otherwise. + public static bool IsNetworkFrameworkEnabled() + { + // Check AppContext switch first (highest priority) + if (AppContext.TryGetSwitch("System.Net.Security.UseNetworkFramework", out bool isEnabled)) + { + return isEnabled; + } + + // Fall back to environment variable + string? envVar = Environment.GetEnvironmentVariable("DOTNET_SYSTEM_NET_SECURITY_USENETWORKFRAMEWORK"); + if (!string.IsNullOrEmpty(envVar)) + { + return envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase); + } + + // Default is disabled + return false; + } + + private static bool GetSendsCAListByDefault() { if (IsWindows) diff --git a/src/libraries/Common/tests/TestUtilities/TestEventListener.cs b/src/libraries/Common/tests/TestUtilities/TestEventListener.cs index 772dc40dfd1dd3..bdfae390d47732 100644 --- a/src/libraries/Common/tests/TestUtilities/TestEventListener.cs +++ b/src/libraries/Common/tests/TestUtilities/TestEventListener.cs @@ -129,7 +129,7 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) } } #endif - sb.Append($"[{eventData.EventName}] "); + sb.Append($"[{eventData.EventName}] "); for (int i = 0; i < eventData.Payload?.Count; i++) { diff --git a/src/libraries/Common/tests/Tests/System/IO/PathInternal.Unix.Tests.cs b/src/libraries/Common/tests/Tests/System/IO/PathInternal.Unix.Tests.cs index d97cfacbabe830..d40593653cc15d 100644 --- a/src/libraries/Common/tests/Tests/System/IO/PathInternal.Unix.Tests.cs +++ b/src/libraries/Common/tests/Tests/System/IO/PathInternal.Unix.Tests.cs @@ -33,7 +33,7 @@ public class PathInternalTests_Unix InlineData(@"a\\", @"a\\"), ] [PlatformSpecific(TestPlatforms.AnyUnix)] - public void NormalizeDirectorySeparatorTests(string path, string expected) + public void NormalizeDirectorySeparatorTests(string? path, string? expected) { string result = PathInternal.NormalizeDirectorySeparators(path); Assert.Equal(expected, result); diff --git a/src/libraries/Common/tests/Tests/System/IO/PathInternal.Windows.Tests.cs b/src/libraries/Common/tests/Tests/System/IO/PathInternal.Windows.Tests.cs index 0c8fa43f4e7471..66ec17e331e146 100644 --- a/src/libraries/Common/tests/Tests/System/IO/PathInternal.Windows.Tests.cs +++ b/src/libraries/Common/tests/Tests/System/IO/PathInternal.Windows.Tests.cs @@ -119,7 +119,7 @@ public void IsPartiallyQualifiedTest(string path, bool expected) InlineData(@" \\", @" \"), InlineData(@" //", @" \") ] - public void NormalizeDirectorySeparatorTests(string path, string expected) + public void NormalizeDirectorySeparatorTests(string? path, string? expected) { string result = PathInternal.NormalizeDirectorySeparators(path); Assert.Equal(expected, result); diff --git a/src/libraries/Common/tests/Tests/System/StringTests.cs b/src/libraries/Common/tests/Tests/System/StringTests.cs index 7775280e2edba6..08ce3c6d54dc3e 100644 --- a/src/libraries/Common/tests/Tests/System/StringTests.cs +++ b/src/libraries/Common/tests/Tests/System/StringTests.cs @@ -150,7 +150,7 @@ public static void Ctor_Char_Int_Negative_Count_ThrowsArgumentOutOfRangeExceptio [InlineData(new char[] { '\u041F', '\u0420', '\u0418', '\u0412', '\u0415', '\u0422' }, 0, 6, "\u041F\u0420\u0418\u0412\u0415\u0422")] [InlineData(new char[0], 0, 0, "")] [InlineData(null, 0, 0, "")] - public static void Ctor_CharArray(char[] value, int startIndex, int length, string expected) + public static void Ctor_CharArray(char[]? value, int startIndex, int length, string expected) { if (value == null) { @@ -2556,7 +2556,7 @@ public static void GetHashCode_EmbeddedNull_ReturnsDifferentHashCodes() [InlineData("", "", StringComparison.OrdinalIgnoreCase, true)] [InlineData("123", 123, StringComparison.OrdinalIgnoreCase, false)] // Not a string [InlineData("\0AAAAAAAAA", "\0BBBBBBBBBBBB", StringComparison.OrdinalIgnoreCase, false)] - public static void EqualsTest(string s1, object obj, StringComparison comparisonType, bool expected) + public static void EqualsTest(string? s1, object? obj, StringComparison comparisonType, bool expected) { string s2 = obj as string; if (s1 != null) @@ -2857,7 +2857,7 @@ public static IEnumerable Format_Invalid_FormatExceptionFromArgs_Membe [MemberData(nameof(Format_Invalid_FormatExceptionFromArgs_MemberData))] [InlineData(null, "{10000000}", new object[] { null })] [InlineData(null, "{0,10000000}", new string[] { null })] - public static void Format_Invalid_FormatExceptionFromFormatOrArgs(IFormatProvider provider, string format, object[] args) + public static void Format_Invalid_FormatExceptionFromFormatOrArgs(IFormatProvider? provider, string format, object[] args) { if (provider is null) { @@ -3805,7 +3805,7 @@ public static void Insert_Invalid() [InlineData("", true)] [InlineData("foo", false)] [InlineData(" ", false)] - public static void IsNullOrEmpty(string value, bool expected) + public static void IsNullOrEmpty(string? value, bool expected) { Assert.Equal(expected, string.IsNullOrEmpty(value)); @@ -3970,7 +3970,7 @@ public static void MakeSureNoIsWhiteSpaceChecksGoOutOfRange() [InlineData("$$", new string[] { "Foo", "Bar", "Baz" }, 0, 3, "Foo$$Bar$$Baz")] [InlineData("$$", new string[] { "Foo", "Bar", "Baz" }, 3, 0, "")] [InlineData("$$", new string[] { "Foo", "Bar", "Baz" }, 1, 1, "Bar")] - public static void Join_StringArray(string separator, string[] values, int startIndex, int count, string expected) + public static void Join_StringArray(string? separator, string[] values, int startIndex, int count, string expected) { if (startIndex + count == values.Length && count != 0) { @@ -4892,7 +4892,7 @@ public static void Replace_Char_Char_DoesntAllocateIfNothingIsReplaced(string s, [InlineData("Aa1Bbb1Cccc1Ddddd1Eeeeee1Fffffff", "1", "23", "Aa23Bbb23Cccc23Ddddd23Eeeeee23Fffffff")] [InlineData("11111111111111111111111", "1", "11", "1111111111111111111111111111111111111111111111")] // Checks if we handle the max # of matches [InlineData("11111111111111111111111", "1", "", "")] // Checks if we handle the max # of matches - public static void Replace_String_String(string s, string oldValue, string newValue, string expected) + public static void Replace_String_String(string s, string oldValue, string? newValue, string expected) { Assert.Equal(expected, s.Replace(oldValue, newValue)); } @@ -6149,7 +6149,7 @@ public static void ToLowerToUpperInvariant_ASCII() [InlineData(" ", new char[] { ' ' }, "")] [InlineData("aaaaa", new char[] { 'a' }, "")] [InlineData("abaabaa", new char[] { 'b', 'a' }, "")] - public static void Trim(string s, char[] trimChars, string expected) + public static void Trim(string s, char[]? trimChars, string expected) { if (trimChars == null || trimChars.Length == 0 || (trimChars.Length == 1 && trimChars[0] == ' ')) { @@ -6179,7 +6179,7 @@ public static void Trim(string s, char[] trimChars, string expected) [InlineData(" ", new char[] { ' ' }, "")] [InlineData("aaaaa", new char[] { 'a' }, "")] [InlineData("abaabaa", new char[] { 'b', 'a' }, "")] - public static void TrimEnd(string s, char[] trimChars, string expected) + public static void TrimEnd(string s, char[]? trimChars, string expected) { if (trimChars == null || trimChars.Length == 0 || (trimChars.Length == 1 && trimChars[0] == ' ')) { @@ -6209,7 +6209,7 @@ public static void TrimEnd(string s, char[] trimChars, string expected) [InlineData(" ", new char[] { ' ' }, "")] [InlineData("aaaaa", new char[] { 'a' }, "")] [InlineData("abaabaa", new char[] { 'b', 'a' }, "")] - public static void TrimStart(string s, char[] trimChars, string expected) + public static void TrimStart(string s, char[]? trimChars, string expected) { if (trimChars == null || trimChars.Length == 0 || (trimChars.Length == 1 && trimChars[0] == ' ')) { diff --git a/src/libraries/System.Resources.Extensions/tests/BinaryFormatTests/Legacy/TheoryDataExtensions.cs b/src/libraries/Common/tests/Tests/TheoryDataExtensions.cs similarity index 97% rename from src/libraries/System.Resources.Extensions/tests/BinaryFormatTests/Legacy/TheoryDataExtensions.cs rename to src/libraries/Common/tests/Tests/TheoryDataExtensions.cs index ab5df917fdb5fd..dcc2e9e35b7ddb 100644 --- a/src/libraries/System.Resources.Extensions/tests/BinaryFormatTests/Legacy/TheoryDataExtensions.cs +++ b/src/libraries/Common/tests/Tests/TheoryDataExtensions.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.Generic; + namespace Xunit; internal static class TheoryDataExtensions diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index 77b995afb43bef..33938989e386de 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -48,8 +48,8 @@ enable annotations - - true + + true diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index 2152e79891a88a..44294aa74a7ac5 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -59,7 +59,7 @@ false true @@ -135,7 +135,7 @@ - + @@ -233,4 +233,14 @@ + + + + $(MSBuildProjectName)-project + + diff --git a/src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/ZipArchiveFuzzer.cs b/src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/ZipArchiveFuzzer.cs index f8119f5fabc494..865016f2ca82be 100644 --- a/src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/ZipArchiveFuzzer.cs +++ b/src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/ZipArchiveFuzzer.cs @@ -15,56 +15,73 @@ internal sealed class ZipArchiveFuzzer : IFuzzer public void FuzzTarget(ReadOnlySpan bytes) { - if (bytes.IsEmpty) { return; } - try - { - using var stream = new MemoryStream(bytes.ToArray()); - - Task sync_test = TestArchive(stream, async: false); - Task async_test = TestArchive(stream, async: true); - - Task.WaitAll(sync_test, async_test); - } - catch (Exception) { } + TestArchive(CopyToRentedArray(bytes), bytes.Length, async: false).GetAwaiter().GetResult(); + TestArchive(CopyToRentedArray(bytes), bytes.Length, async: true).GetAwaiter().GetResult(); } - private async Task TestArchive(Stream stream, bool async) + private byte[] CopyToRentedArray(ReadOnlySpan bytes) { - stream.Position = 0; - - ZipArchive archive; - - if (async) + byte[] buffer = ArrayPool.Shared.Rent(bytes.Length); + try { - archive = await ZipArchive.CreateAsync(stream, ZipArchiveMode.Read, leaveOpen: false, entryNameEncoding: null); + bytes.CopyTo(buffer); + return buffer; } - else + catch { - archive = new ZipArchive(stream, ZipArchiveMode.Read, leaveOpen: false, entryNameEncoding: null); + ArrayPool.Shared.Return(buffer); + throw; } + } - foreach (var entry in archive.Entries) + private async Task TestArchive(byte[] buffer, int length, bool async) + { + try { - // Access entry properties to simulate usage - _ = entry.FullName; - _ = entry.Length; - _ = entry.Comment; - _ = entry.LastWriteTime; - _ = entry.Crc32; - } + using var stream = new MemoryStream(buffer, 0, length); - if (async) + ZipArchive archive; + + if (async) + { + archive = await ZipArchive.CreateAsync(stream, ZipArchiveMode.Read, leaveOpen: false, entryNameEncoding: null); + } + else + { + archive = new ZipArchive(stream, ZipArchiveMode.Read, leaveOpen: false, entryNameEncoding: null); + } + + foreach (var entry in archive.Entries) + { + // Access entry properties to simulate usage + _ = entry.FullName; + _ = entry.Length; + _ = entry.Comment; + _ = entry.LastWriteTime; + _ = entry.Crc32; + } + + if (async) + { + await archive.DisposeAsync(); + } + else + { + archive.Dispose(); + } + } + catch (InvalidDataException) { - await archive.DisposeAsync(); + // ignore, this exception is expected to be thrown for invalid/corrupted archives. } - else + finally { - archive.Dispose(); + ArrayPool.Shared.Return(buffer); } } } diff --git a/src/libraries/Microsoft.Bcl.Cryptography/Microsoft.Bcl.Cryptography.slnx b/src/libraries/Microsoft.Bcl.Cryptography/Microsoft.Bcl.Cryptography.slnx index e9c1b1aa420989..e417cbea9de15e 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/Microsoft.Bcl.Cryptography.slnx +++ b/src/libraries/Microsoft.Bcl.Cryptography/Microsoft.Bcl.Cryptography.slnx @@ -1,36 +1,354 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.Forwards.cs b/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.Forwards.cs index 7b13a2918fe597..94568e5fdb1b0b 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.Forwards.cs +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.Forwards.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NET8_0_OR_GREATER +#if NET [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.AesGcm))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.AuthenticationTagMismatchException))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SP800108HmacCounterKdf))] @@ -14,6 +14,7 @@ #if NET10_0_OR_GREATER [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CompositeMLDsa))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CompositeMLDsaAlgorithm))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CompositeMLDsaCng))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.MLDsa))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.MLDsaAlgorithm))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.MLDsaCng))] @@ -22,6 +23,7 @@ [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.MLKemCng))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SlhDsa))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SlhDsaAlgorithm))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SlhDsaCng))] #endif #if NET || NETSTANDARD2_1_OR_GREATER [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.PbeEncryptionAlgorithm))] diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj b/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj index c6d5337565f204..f34fbaa03c6f13 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj +++ b/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 @@ - @@ -112,6 +112,27 @@ Common\System\Security\Cryptography\Asn1\AttributeAsn.manual.cs Common\System\Security\Cryptography\Asn1\AttributeAsn.xml + + Common\System\Security\Cryptography\Asn1\CurveAsn.xml + + + Common\System\Security\Cryptography\Asn1\CurveAsn.xml.cs + Common\System\Security\Cryptography\Asn1\CurveAsn.xml + + + Common\System\Security\Cryptography\Asn1\ECDomainParameters.xml + + + Common\System\Security\Cryptography\Asn1\ECDomainParameters.xml.cs + Common\System\Security\Cryptography\Asn1\ECDomainParameters.xml + + + Common\System\Security\Cryptography\Asn1\ECPrivateKey.xml + + + Common\System\Security\Cryptography\Asn1\ECPrivateKey.xml.cs + Common\System\Security\Cryptography\Asn1\ECPrivateKey.xml + Common\System\Security\Cryptography\Asn1\EncryptedPrivateKeyInfoAsn.xml @@ -119,6 +140,13 @@ Common\System\Security\Cryptography\Asn1\EncryptedPrivateKeyInfoAsn.xml.cs Common\System\Security\Cryptography\Asn1\EncryptedPrivateKeyInfoAsn.xml + + Common\System\Security\Cryptography\Asn1\FieldID.xml + + + Common\System\Security\Cryptography\Asn1\FieldID.xml.cs + Common\System\Security\Cryptography\Asn1\FieldID.xml + Common\System\Security\Cryptography\Asn1\MLDsaPrivateKeyAsn.xml.cs Common\System\Security\Cryptography\Asn1\MLDsaPrivateKeyAsn.xml @@ -173,6 +201,27 @@ Common\System\Security\Cryptography\Asn1\Rc2CbcParameters.manual.cs Common\System\Security\Cryptography\Asn1\Rc2CbcParameters.xml + + Common\System\Security\Cryptography\Asn1\RSAPrivateKeyAsn.xml + + + Common\System\Security\Cryptography\Asn1\RSAPrivateKeyAsn.xml.cs + Common\System\Security\Cryptography\Asn1\RSAPrivateKeyAsn.xml + + + Common\System\Security\Cryptography\Asn1\RSAPublicKeyAsn.xml + + + Common\System\Security\Cryptography\Asn1\RSAPublicKeyAsn.xml.cs + Common\System\Security\Cryptography\Asn1\RSAPublicKeyAsn.xml + + + Common\System\Security\Cryptography\Asn1\SpecifiedECDomain.xml + + + Common\System\Security\Cryptography\Asn1\SpecifiedECDomain.xml.cs + Common\System\Security\Cryptography\Asn1\SpecifiedECDomain.xml + Common\System\Security\Cryptography\Asn1\SubjectPublicKeyInfoAsn.xml @@ -184,8 +233,12 @@ Link="Common\System\Memory\PointerMemoryManager.cs" /> + + + @@ -275,34 +330,12 @@ - - - - - - - - - - - @@ -337,8 +370,8 @@ Link="Common\System\Security\Cryptography\AesAEAD.cs" /> - + @@ -375,6 +408,8 @@ Link="Common\Interop\Windows\BCrypt\Interop.BCryptFinalizeKey.cs" /> + + + + + + - + + + + + + + + Link="Common\Microsoft\Win32\SafeHandles\SafeUnicodeStringHandle.cs" /> + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md b/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md index ebbb68160c47de..879fc832340d1b 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/PACKAGE.md @@ -18,7 +18,7 @@ internal static class Program private static void Main() { byte[] key = LoadKey(); - SP800108HmacCounterKdf kbkdf = new(key, HashAlgorithmName.SHA256); + using SP800108HmacCounterKdf kbkdf = new(key, HashAlgorithmName.SHA256); byte[] derivedKey = kbkdf.DeriveKey("label"u8, "context"u8, derivedKeyLengthInBytes: 32); } } @@ -29,6 +29,10 @@ internal static class Program The main types provided by this library are: * `System.Security.Cryptography.AesGcm` +* `System.Security.Cryptography.CompositeMLDsa` +* `System.Security.Cryptography.MLDsa` +* `System.Security.Cryptography.MLKem` +* `System.Security.Cryptography.SlhDsa` * `System.Security.Cryptography.SP800108HmacCounterKdf` * `System.Security.Cryptography.X509Certificates.X509CertificateLoader` diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/Resources/Strings.resx b/src/libraries/Microsoft.Bcl.Cryptography/src/Resources/Strings.resx index acec0d884405b4..0833032472f622 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/Resources/Strings.resx +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/Resources/Strings.resx @@ -87,6 +87,9 @@ The specified private seed is not the correct length for the ML-KEM algorithm. + + The specified mu value is not the correct length for the ML-DSA algorithm. + The specified label is not valid. @@ -105,21 +108,15 @@ An encrypted key was found, but no password was provided. Use ImportFromEncryptedPem to import this key. - - The private key is too short for the indicated algorithm. + + The private key is not the correct size for the indicated algorithm. - - The public key is too short for the indicated algorithm. + + The private seed is not the correct size for the indicated algorithm. The public key is not the correct size for the indicated algorithm. - - The secret key is not the correct size for the indicated algorithm. - - - The private seed is not the correct size for the indicated algorithm. - The specified signature context exceeds the maximum length of 255 bytes. @@ -153,6 +150,15 @@ The computed authentication tag did not match the input authentication tag. + + The certificate already has an associated private key. + + + Composite signature generation failed due to an error in one or both of the components. + + + The specified curve '{0}' or its parameters are not valid for this platform. + ASN1 corrupted data. @@ -162,9 +168,15 @@ 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}. + + The specified key parameters are not valid. X and Y, or D, must be specified. X, Y must be the same length. If D is specified it must be the same length as X and Y if also specified. + Specified key is not a valid size for this algorithm. @@ -177,6 +189,9 @@ Invalid OID format. + + The specified RSA parameters are not valid. Exponent and Modulus are required. If D is present, it must have the same length as Modulus. If D is present, P, Q, DP, DQ, and InverseQ are required and must have half the length of Modulus, rounded up, otherwise they must be omitted. + The specified PKCS#8 key contains a seed that does not match the expanded key. @@ -189,12 +204,12 @@ The specified key is not the correct size for the indicated algorithm. - - The current instance does not contain a secret key. - The specified PKCS#8 key contains a seed that does not match the expanded key. + + The current instance does not contain a private key. + Key is not a valid private key. @@ -219,6 +234,15 @@ The current instance does not contain a seed. + + The provided key does not match the public key for this certificate. + + + The provided key does not match the public key algorithm for this certificate. + + + The provided RSAPrivateKey value has version '{0}', but version '{1}' is the maximum supported. + The algorithm identified by '{0}' is unknown, not valid for the requested usage, or was not handled. diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/CngExtensions.cs b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/CngExtensions.cs index 464ab69639f00b..8a2f2c1ded858b 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/CngExtensions.cs +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/CngExtensions.cs @@ -49,6 +49,17 @@ internal static bool TryExportKeyBlob( } } + internal static void ExportKeyBlob( + this CngKey key, + string blobType, + CngHelpers.ExportKeyBlobCallback callback) + { + using (SafeNCryptKeyHandle keyHandle = key.Handle) + { + keyHandle.ExportKeyBlob(blobType, callback); + } + } + internal static byte[] ExportPkcs8KeyBlob( this CngKey key, ReadOnlySpan password, diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/CngHelpers.cs b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/CngHelpers.cs deleted file mode 100644 index fd13b4cd9e77c7..00000000000000 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/CngHelpers.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Security.Cryptography -{ - internal static partial class CngHelpers - { - internal static unsafe void GetRandomBytes(Span buffer) - { - if (buffer.Length > 0) - { - fixed (byte* pbBuffer = buffer) - { - Interop.BCrypt.NTSTATUS status = Interop.BCrypt.BCryptGenRandom(IntPtr.Zero, pbBuffer, buffer.Length, Interop.BCrypt.BCRYPT_USE_SYSTEM_PREFERRED_RNG); - if (status != Interop.BCrypt.NTSTATUS.STATUS_SUCCESS) - throw Interop.BCrypt.CreateCryptographicException(status); - } - } - } - } -} diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs index feb43d2caa487b..9344f75762fed0 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs +++ b/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/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/Helpers.cs b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/Helpers.cs index c51de135ddd9b4..2d50b4bd4b445c 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/Helpers.cs +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/Helpers.cs @@ -65,5 +65,55 @@ internal static ReadOnlyMemory DecodeOctetStringAsMemory(ReadOnlyMemory buffer) + { + if (buffer.Length > 0) + { + fixed (byte* pbBuffer = buffer) + { + Interop.BCrypt.NTSTATUS status = Interop.BCrypt.BCryptGenRandom(IntPtr.Zero, pbBuffer, buffer.Length, Interop.BCrypt.BCRYPT_USE_SYSTEM_PREFERRED_RNG); + if (status != Interop.BCrypt.NTSTATUS.STATUS_SUCCESS) + throw Interop.BCrypt.CreateCryptographicException(status); + } + } + } + } +#endif } } diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateHelpers.Windows.cs b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateHelpers.Windows.cs new file mode 100644 index 00000000000000..c6f2a7e7fc0ecf --- /dev/null +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateHelpers.Windows.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; +using System.Runtime.Versioning; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; + +namespace System.Security.Cryptography.X509Certificates +{ + internal static partial class CertificateHelpers + { + private static partial int GuessKeySpec(CngProvider provider, string keyName, bool machineKey, CngAlgorithmGroup? algorithmGroup) => 0; + + [UnsupportedOSPlatform("browser")] + private static partial X509Certificate2 CopyFromRawBytes(X509Certificate2 certificate) => + X509CertificateLoader.LoadCertificate(certificate.RawData); + + private static partial CryptographicException GetExceptionForLastError() => +#if NETFRAMEWORK + Marshal.GetHRForLastWin32Error().ToCryptographicException(); +#else + Marshal.GetLastPInvokeError().ToCryptographicException(); +#endif + +#if NETFRAMEWORK + private static readonly System.Reflection.ConstructorInfo? s_safeNCryptKeyHandleCtor_IntPtr_SafeHandle = + typeof(SafeNCryptKeyHandle).GetConstructor([typeof(IntPtr), typeof(SafeHandle)]); +#endif + + [SupportedOSPlatform("windows")] + private static partial SafeNCryptKeyHandle CreateSafeNCryptKeyHandle(IntPtr handle, SafeHandle parentHandle) + { +#if NETFRAMEWORK + if (s_safeNCryptKeyHandleCtor_IntPtr_SafeHandle == null) + { + throw new PlatformNotSupportedException(); + } + + return (SafeNCryptKeyHandle)s_safeNCryptKeyHandleCtor_IntPtr_SafeHandle.Invoke([handle, parentHandle]); +#else + return new SafeNCryptKeyHandle(handle, parentHandle); +#endif + } + } +} diff --git a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateKeyAccessors.cs b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateKeyAccessors.cs index cdf40e81ee45a8..5b3435facde269 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateKeyAccessors.cs +++ b/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateKeyAccessors.cs @@ -2,14 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; -using System.Formats.Asn1; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; #if !NET10_0_OR_GREATER +using System.Formats.Asn1; using System.Security.Cryptography.Asn1; #endif +#if !NET10_0_OR_GREATER && !NETSTANDARD +using System.Diagnostics; +using Internal.Cryptography; +#endif + namespace System.Security.Cryptography.X509Certificates { /// @@ -35,9 +38,11 @@ public static class X509CertificateKeyAccessors /// /// The public key was invalid, or otherwise could not be imported. /// - [ExperimentalAttribute(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static MLKem? GetMLKemPublicKey(this X509Certificate2 certificate) { + ArgumentNullException.ThrowIfNull(certificate); + #if NET10_0_OR_GREATER return certificate.GetMLKemPublicKey(); #else @@ -54,7 +59,7 @@ public static class X509CertificateKeyAccessors } finally { - // SubjectPublicKeyInfo does not need to clear since it's public + // SubjectPublicKeyInfo does not need to clear since it's public CryptoPool.Return(encoded, clearSize: 0); } #endif @@ -69,16 +74,26 @@ public static class X509CertificateKeyAccessors /// /// The private key, or if this certificate does not have an ML-KEM private key. /// + /// + /// is . + /// + /// + /// Retrieving an ML-KEM private key from a certificate is not supported on this platform. + /// /// /// An error occurred accessing the private key. /// - [ExperimentalAttribute(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] - public static MLKem? GetMLKemPrivateKey(this X509Certificate2 certificate) => + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static MLKem? GetMLKemPrivateKey(this X509Certificate2 certificate) + { + ArgumentNullException.ThrowIfNull(certificate); + #if NET10_0_OR_GREATER - certificate.GetMLKemPrivateKey(); + return certificate.GetMLKemPrivateKey(); #else throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(MLKem))); #endif + } /// /// Combines a private key with a certificate containing the associated public key into a @@ -103,13 +118,180 @@ public static class X509CertificateKeyAccessors /// /// The certificate already has an associated private key. /// - [ExperimentalAttribute(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] - public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certificate, MLKem privateKey) => + /// + /// Combining a certificate and an ML-KEM private key is not supported on this platform. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certificate, MLKem privateKey) + { + ArgumentNullException.ThrowIfNull(certificate); + ArgumentNullException.ThrowIfNull(privateKey); + #if NET10_0_OR_GREATER - certificate.CopyWithPrivateKey(privateKey); + return certificate.CopyWithPrivateKey(privateKey); #else throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(MLKem))); #endif + } + + /// + /// Gets the public key from this certificate. + /// + /// + /// The X.509 certificate that contains the public key. + /// + /// + /// The public key, or if this certificate does not have an ML-DSA public key. + /// + /// + /// is . + /// + /// + /// The certificate has an ML-DSA public key, but the platform does not support ML-DSA. + /// + /// + /// The public key was invalid, or otherwise could not be imported. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static MLDsa? GetMLDsaPublicKey(this X509Certificate2 certificate) + { + ArgumentNullException.ThrowIfNull(certificate); + +#if NET10_0_OR_GREATER + return certificate.GetMLDsaPublicKey(); +#else + if (MLDsaAlgorithm.GetMLDsaAlgorithmFromOid(certificate.GetKeyAlgorithm()) is null) + { + return null; + } + + ArraySegment encoded = GetCertificateSubjectPublicKeyInfo(certificate); + + try + { + return MLDsa.ImportSubjectPublicKeyInfo(encoded); + } + finally + { + // SubjectPublicKeyInfo does not need to clear since it's public + CryptoPool.Return(encoded, clearSize: 0); + } +#endif + } + + /// + /// Gets the private key from this certificate. + /// + /// + /// The X.509 certificate that contains the private key. + /// + /// + /// The private key, or if this certificate does not have an ML-DSA private key. + /// + /// + /// is . + /// + /// + /// Retrieving an ML-DSA private key from a certificate is not supported on this platform. + /// + /// + /// An error occurred accessing the private key. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static MLDsa? GetMLDsaPrivateKey(this X509Certificate2 certificate) + { + ArgumentNullException.ThrowIfNull(certificate); + +#if NET10_0_OR_GREATER + return certificate.GetMLDsaPrivateKey(); +#elif NETSTANDARD + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(MLDsa))); +#else + if (!Helpers.IsOSPlatformWindows) + throw new PlatformNotSupportedException(); + + return CertificateHelpers.GetPrivateKey( + certificate, + _ => + { + Debug.Fail("CryptoApi does not support ML-DSA."); + throw new PlatformNotSupportedException(); + }, + cngKey => new MLDsaCng(cngKey, transferOwnership: true)); +#endif + } + + /// + /// Combines a private key with a certificate containing the associated public key into a + /// new instance that can access the private key. + /// + /// + /// The X.509 certificate that contains the public key. + /// + /// + /// The ML-DSA private key that corresponds to the ML-DSA public key in this certificate. + /// + /// + /// A new certificate with the property set to . + /// The current certificate isn't modified. + /// + /// + /// or is . + /// + /// + /// The specified private key doesn't match the public key for this certificate. + /// + /// + /// The certificate already has an associated private key. + /// + /// + /// Combining a certificate and an ML-DSA private key is not supported on this platform. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certificate, MLDsa privateKey) + { + ArgumentNullException.ThrowIfNull(certificate); + ArgumentNullException.ThrowIfNull(privateKey); + +#if NET10_0_OR_GREATER + return certificate.CopyWithPrivateKey(privateKey); +#elif NETSTANDARD + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(MLDsa))); +#else + if (!Helpers.IsOSPlatformWindows) + throw new PlatformNotSupportedException(); + + if (certificate.HasPrivateKey) + throw new InvalidOperationException(SR.Cryptography_Cert_AlreadyHasPrivateKey); + + using (MLDsa? publicKey = GetMLDsaPublicKey(certificate)) + { + if (publicKey is null) + { + throw new ArgumentException(SR.Cryptography_PrivateKey_WrongAlgorithm); + } + + if (publicKey.Algorithm != privateKey.Algorithm) + { + throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); + } + + using (CryptoPoolLease pk1 = CryptoPoolLease.Rent(publicKey.Algorithm.PublicKeySizeInBytes, skipClear: true)) + using (CryptoPoolLease pk2 = CryptoPoolLease.Rent(publicKey.Algorithm.PublicKeySizeInBytes, skipClear: true)) + { + publicKey.ExportMLDsaPublicKey(pk1.Span); + privateKey.ExportMLDsaPublicKey(pk2.Span); + + if (!pk1.Span.SequenceEqual(pk2.Span)) + { + throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); + } + } + } + + return CertificateHelpers.CopyWithPrivateKey(certificate, privateKey); +#endif + } /// /// Gets the public key from this certificate. @@ -129,13 +311,17 @@ public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certific /// /// The public key was invalid, or otherwise could not be imported. /// - [ExperimentalAttribute(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] - public static SlhDsa? GetSlhDsaPublicKey(this X509Certificate2 certificate) => + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static SlhDsa? GetSlhDsaPublicKey(this X509Certificate2 certificate) + { + ArgumentNullException.ThrowIfNull(certificate); + #if NET10_0_OR_GREATER - certificate.GetSlhDsaPublicKey(); + return certificate.GetSlhDsaPublicKey(); #else throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(SlhDsa))); #endif + } /// /// Gets the private key from this certificate. @@ -146,16 +332,26 @@ public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certific /// /// The private key, or if this certificate does not have an SLH-DSA private key. /// + /// + /// is . + /// + /// + /// Retrieving an SLH-DSA private key from a certificate is not supported on this platform. + /// /// /// An error occurred accessing the private key. /// - [ExperimentalAttribute(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] - public static SlhDsa? GetSlhDsaPrivateKey(this X509Certificate2 certificate) => + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static SlhDsa? GetSlhDsaPrivateKey(this X509Certificate2 certificate) + { + ArgumentNullException.ThrowIfNull(certificate); + #if NET10_0_OR_GREATER - certificate.GetSlhDsaPrivateKey(); + return certificate.GetSlhDsaPrivateKey(); #else throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(SlhDsa))); #endif + } /// /// Combines a private key with a certificate containing the associated public key into a @@ -175,7 +371,7 @@ public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certific /// is . /// /// - /// is . + /// or is . /// /// /// The specified private key doesn't match the public key for this certificate. @@ -183,13 +379,169 @@ public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certific /// /// The certificate already has an associated private key. /// - [ExperimentalAttribute(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] - public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certificate, SlhDsa privateKey) => + /// + /// Combining a certificate and an SLH-DSA private key is not supported on this platform. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certificate, SlhDsa privateKey) + { + ArgumentNullException.ThrowIfNull(certificate); + ArgumentNullException.ThrowIfNull(privateKey); + #if NET10_0_OR_GREATER - certificate.CopyWithPrivateKey(privateKey); + return certificate.CopyWithPrivateKey(privateKey); #else throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(SlhDsa))); #endif + } + + /// + /// Gets the public key from this certificate. + /// + /// + /// The X.509 certificate that contains the public key. + /// + /// + /// The public key, or if this certificate does not have a Composite ML-DSA public key. + /// + /// + /// is . + /// + /// + /// The certificate has a Composite ML-DSA public key, but the platform does not support Composite ML-DSA. + /// + /// + /// The public key was invalid, or otherwise could not be imported. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static CompositeMLDsa? GetCompositeMLDsaPublicKey(this X509Certificate2 certificate) + { + ArgumentNullException.ThrowIfNull(certificate); + +#if NET10_0_OR_GREATER + return certificate.GetCompositeMLDsaPublicKey(); +#else + if (CompositeMLDsaAlgorithm.GetAlgorithmFromOid(certificate.GetKeyAlgorithm()) is null) + { + return null; + } + + ArraySegment encoded = GetCertificateSubjectPublicKeyInfo(certificate); + + try + { + return CompositeMLDsa.ImportSubjectPublicKeyInfo(encoded); + } + finally + { + // SubjectPublicKeyInfo does not need to clear since it's public + CryptoPool.Return(encoded, clearSize: 0); + } +#endif + } + + /// + /// Gets the private key from this certificate. + /// + /// + /// The X.509 certificate that contains the private key. + /// + /// + /// The private key, or if this certificate does not have a Composite ML-DSA private key. + /// + /// + /// is . + /// + /// + /// Retrieving a Composite ML-DSA private key from a certificate is not supported on this platform. + /// + /// + /// An error occurred accessing the private key. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static CompositeMLDsa? GetCompositeMLDsaPrivateKey(this X509Certificate2 certificate) + { + ArgumentNullException.ThrowIfNull(certificate); + +#if NET10_0_OR_GREATER + return certificate.GetCompositeMLDsaPrivateKey(); +#else + if (CompositeMLDsaAlgorithm.GetAlgorithmFromOid(certificate.GetKeyAlgorithm()) is null) + { + return null; + } + + throw new PlatformNotSupportedException(); +#endif + } + + /// + /// Combines a private key with a certificate containing the associated public key into a + /// new instance that can access the private key. + /// + /// + /// The X.509 certificate that contains the public key. + /// + /// + /// The Composite ML-DSA private key that corresponds to the Composite ML-DSA public key in this certificate. + /// + /// + /// A new certificate with the property set to . + /// The current certificate isn't modified. + /// + /// + /// or is . + /// + /// + /// The specified private key doesn't match the public key for this certificate. + /// + /// + /// The certificate already has an associated private key. + /// + /// + /// Combining a certificate and a Composite ML-DSA private key is not supported on this platform. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certificate, CompositeMLDsa privateKey) + { + ArgumentNullException.ThrowIfNull(certificate); + ArgumentNullException.ThrowIfNull(privateKey); + +#if NET10_0_OR_GREATER + return certificate.CopyWithPrivateKey(privateKey); +#elif NETSTANDARD + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(CompositeMLDsa))); +#else + if (!Helpers.IsOSPlatformWindows) + throw new PlatformNotSupportedException(); + + if (certificate.HasPrivateKey) + throw new InvalidOperationException(SR.Cryptography_Cert_AlreadyHasPrivateKey); + + using (CompositeMLDsa? publicKey = GetCompositeMLDsaPublicKey(certificate)) + { + if (publicKey is null) + { + throw new ArgumentException(SR.Cryptography_PrivateKey_WrongAlgorithm); + } + + if (publicKey.Algorithm != privateKey.Algorithm) + { + throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); + } + + byte[] pk1 = publicKey.ExportCompositeMLDsaPublicKey(); + byte[] pk2 = privateKey.ExportCompositeMLDsaPublicKey(); + + if (!pk1.SequenceEqual(pk2)) + { + throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); + } + } + + throw new PlatformNotSupportedException(); +#endif + } #if !NET10_0_OR_GREATER private static ArraySegment GetCertificateSubjectPublicKeyInfo(X509Certificate2 certificate) diff --git a/src/libraries/Microsoft.Bcl.Cryptography/tests/Microsoft.Bcl.Cryptography.Tests.csproj b/src/libraries/Microsoft.Bcl.Cryptography/tests/Microsoft.Bcl.Cryptography.Tests.csproj index 4467b8eaa82d73..5abb2246869ee1 100644 --- a/src/libraries/Microsoft.Bcl.Cryptography/tests/Microsoft.Bcl.Cryptography.Tests.csproj +++ b/src/libraries/Microsoft.Bcl.Cryptography/tests/Microsoft.Bcl.Cryptography.Tests.csproj @@ -114,6 +114,8 @@ Link="CommonTest\System\Security\Cryptography\ByteUtils.cs" /> + + + + + + + + + + GetSlhDsaPrivateKey => X509CertificateKeyAccessors.GetSlhDsaPrivateKey; + private static partial Func CopyWithPrivateKey_MLDsa => + X509CertificateKeyAccessors.CopyWithPrivateKey; + + private static partial Func GetMLDsaPublicKey => + X509CertificateKeyAccessors.GetMLDsaPublicKey; + + private static partial Func GetMLDsaPrivateKey => + X509CertificateKeyAccessors.GetMLDsaPrivateKey; + private static partial void CheckCopyWithPrivateKey( X509Certificate2 cert, X509Certificate2 wrongAlgorithmCert, @@ -35,5 +45,26 @@ private static partial void CheckCopyWithPrivateKey( Func getPrivateKey, Action keyProver) where TKey : class, IDisposable; + + [Fact] + public static void ArgumentValidation() + { + Assert.Throws("certificate", () => X509CertificateKeyAccessors.CopyWithPrivateKey(null, default(MLKem))); + Assert.Throws("certificate", () => X509CertificateKeyAccessors.CopyWithPrivateKey(null, default(MLDsa))); + Assert.Throws("certificate", () => X509CertificateKeyAccessors.CopyWithPrivateKey(null, default(SlhDsa))); + Assert.Throws("certificate", () => X509CertificateKeyAccessors.GetMLKemPublicKey(null)); + Assert.Throws("certificate", () => X509CertificateKeyAccessors.GetMLDsaPublicKey(null)); + Assert.Throws("certificate", () => X509CertificateKeyAccessors.GetSlhDsaPublicKey(null)); + +#pragma warning disable SYSLIB0026 // X509Certificate and X509Certificate2 are immutable + // This constructor is deprecated, but we use it here for test purposes. + using (X509Certificate2 cert = new X509Certificate2()) +#pragma warning restore SYSLIB0026 // X509Certificate and X509Certificate2 are immutable + { + Assert.Throws("privateKey", () => X509CertificateKeyAccessors.CopyWithPrivateKey(cert, default(MLKem))); + Assert.Throws("privateKey", () => X509CertificateKeyAccessors.CopyWithPrivateKey(cert, default(MLDsa))); + Assert.Throws("privateKey", () => X509CertificateKeyAccessors.CopyWithPrivateKey(cert, default(SlhDsa))); + } + } } } diff --git a/src/libraries/Microsoft.Bcl.TimeProvider/src/System/Threading/Tasks/TimeProviderTaskExtensions.cs b/src/libraries/Microsoft.Bcl.TimeProvider/src/System/Threading/Tasks/TimeProviderTaskExtensions.cs index 6274bab9a02c75..1376e63cc011d5 100644 --- a/src/libraries/Microsoft.Bcl.TimeProvider/src/System/Threading/Tasks/TimeProviderTaskExtensions.cs +++ b/src/libraries/Microsoft.Bcl.TimeProvider/src/System/Threading/Tasks/TimeProviderTaskExtensions.cs @@ -12,7 +12,7 @@ namespace System.Threading.Tasks /// public static class TimeProviderTaskExtensions { -#if !NET8_0_OR_GREATER +#if !NET private sealed class DelayState : TaskCompletionSource { public DelayState(CancellationToken cancellationToken) @@ -37,7 +37,7 @@ public WaitAsyncState(CancellationToken cancellationToken) : base(TaskCreationOp public CancellationTokenRegistration Registration; public ITimer? Timer; } -#endif // !NET8_0_OR_GREATER +#endif // !NET /// Creates a task that completes after a specified time interval. /// The with which to interpret . @@ -48,7 +48,7 @@ public WaitAsyncState(CancellationToken cancellationToken) : base(TaskCreationOp /// represents a negative time interval other than . public static Task Delay(this TimeProvider timeProvider, TimeSpan delay, CancellationToken cancellationToken = default) { -#if NET8_0_OR_GREATER +#if NET return Task.Delay(delay, timeProvider, cancellationToken); #else if (timeProvider == TimeProvider.System) @@ -114,7 +114,7 @@ public static Task Delay(this TimeProvider timeProvider, TimeSpan delay, Cancell } return state.Task; -#endif // NET8_0_OR_GREATER +#endif // NET } /// @@ -129,7 +129,7 @@ public static Task Delay(this TimeProvider timeProvider, TimeSpan delay, Cancell /// represents a negative time interval other than . public static Task WaitAsync(this Task task, TimeSpan timeout, TimeProvider timeProvider, CancellationToken cancellationToken = default) { -#if NET8_0_OR_GREATER +#if NET return task.WaitAsync(timeout, timeProvider, cancellationToken); #else ArgumentNullException.ThrowIfNull(task); @@ -204,7 +204,7 @@ public static Task WaitAsync(this Task task, TimeSpan timeout, TimeProvider time } return state.Task; -#endif // NET8_0_OR_GREATER +#endif // NET } /// @@ -217,7 +217,7 @@ public static Task WaitAsync(this Task task, TimeSpan timeout, TimeProvider time /// The representing the asynchronous wait. It may or may not be the same instance as the current instance. /// or is . /// represents a negative time interval other than . -#if NET8_0_OR_GREATER +#if NET public static Task WaitAsync(this Task task, TimeSpan timeout, TimeProvider timeProvider, CancellationToken cancellationToken = default) => task.WaitAsync(timeout, timeProvider, cancellationToken); #else @@ -226,7 +226,7 @@ public static async Task WaitAsync(this Task task, Ti await ((Task)task).WaitAsync(timeout, timeProvider, cancellationToken).ConfigureAwait(false); return task.Result; } -#endif // NET8_0_OR_GREATER +#endif // NET /// Initializes a new instance of the class that will be canceled after the specified . /// The with which to interpret the . @@ -246,7 +246,7 @@ public static async Task WaitAsync(this Task task, Ti /// public static CancellationTokenSource CreateCancellationTokenSource(this TimeProvider timeProvider, TimeSpan delay) { -#if NET8_0_OR_GREATER +#if NET return new CancellationTokenSource(delay, timeProvider); #else ArgumentNullException.ThrowIfNull(timeProvider); @@ -274,7 +274,7 @@ public static CancellationTokenSource CreateCancellationTokenSource(this TimePro cts.Token.Register(static t => ((ITimer)t!).Dispose(), timer); return cts; -#endif // NET8_0_OR_GREATER +#endif // NET } } } diff --git a/src/libraries/Microsoft.CSharp/Microsoft.CSharp.slnx b/src/libraries/Microsoft.CSharp/Microsoft.CSharp.slnx index ca87ed5e043058..e844ddeefa26f3 100644 --- a/src/libraries/Microsoft.CSharp/Microsoft.CSharp.slnx +++ b/src/libraries/Microsoft.CSharp/Microsoft.CSharp.slnx @@ -1,34 +1,522 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj b/src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj index 7a2b989d927840..c0045d94b5e8fa 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj +++ b/src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj @@ -13,7 +13,7 @@ $(DefineConstants);ENABLECOMBINDER true $(DefineConstants);LEGACY_GETRESOURCESTRING_USER - true + true @@ -239,22 +239,22 @@ - - - - + + + + - - - - - - - - - + + + + + + + + + diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ExcepInfo.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ExcepInfo.cs index b839dbb7d21db8..36579c733ee657 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ExcepInfo.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ExcepInfo.cs @@ -33,7 +33,7 @@ static ExcepInfo() } #endif - private static string ConvertAndFreeBstr(ref IntPtr bstr) + private static string? ConvertAndFreeBstr(ref IntPtr bstr) { if (bstr == IntPtr.Zero) { @@ -55,11 +55,17 @@ internal Exception GetException() wReserved = -1; // to ensure that the method gets called only once #endif + // If the scode is zero, we use the wCode. The wCode is a legacy of + // 16-bit Windows error codes. This means it will never be an error + // scode (HRESULT, < 0) and we will get a null exception. int errorCode = (scode != 0) ? scode : wCode; - Exception exception = Marshal.GetExceptionForHR(errorCode); - string message = ConvertAndFreeBstr(ref bstrDescription); - if (message != null) + // If the error code doesn't resolve to an exception, we create a + // generic COMException with the error code and no message. + Exception exception = Marshal.GetExceptionForHR(errorCode) ?? new COMException(null, errorCode); + + string? message = ConvertAndFreeBstr(ref bstrDescription); + if (message is not null) { // If we have a custom message, create a new Exception object with the message set correctly. // We need to create a new object because "exception.Message" is a read-only property. @@ -71,7 +77,7 @@ internal Exception GetException() { Type exceptionType = exception.GetType(); ConstructorInfo ctor = exceptionType.GetConstructor(new Type[] { typeof(string) }); - if (ctor != null) + if (ctor is not null) { exception = (Exception)ctor.Invoke(new object[] { message }); } @@ -80,8 +86,8 @@ internal Exception GetException() exception.Source = ConvertAndFreeBstr(ref bstrSource); - string helpLink = ConvertAndFreeBstr(ref bstrHelpFile); - if (helpLink != null && dwHelpContext != 0) + string? helpLink = ConvertAndFreeBstr(ref bstrHelpFile); + if (helpLink is not null && dwHelpContext != 0) { helpLink += "#" + dwHelpContext; } diff --git a/src/libraries/Microsoft.CSharp/tests/AssignmentTests.cs b/src/libraries/Microsoft.CSharp/tests/AssignmentTests.cs index 1c9d3fc784cadb..db59578a9babaf 100644 --- a/src/libraries/Microsoft.CSharp/tests/AssignmentTests.cs +++ b/src/libraries/Microsoft.CSharp/tests/AssignmentTests.cs @@ -83,7 +83,7 @@ public void AddAssignment(dynamic lhs, dynamic rhs, object expected) { lhs += rhs; Assert.Equal(expected, lhs); - Assert.IsType(expected.GetType(), lhs); + Assert.IsType(expected.GetType(), (object)lhs); } [Theory, MemberData(nameof(PropertyAdditions))] diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/Microsoft.Extensions.Caching.Memory.slnx b/src/libraries/Microsoft.Extensions.Caching.Memory/Microsoft.Extensions.Caching.Memory.slnx index 370f15f2e34463..d9f50ffd934859 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/Microsoft.Extensions.Caching.Memory.slnx +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/Microsoft.Extensions.Caching.Memory.slnx @@ -1,50 +1,514 @@ + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/Microsoft.Extensions.Configuration.Binder.slnx b/src/libraries/Microsoft.Extensions.Configuration.Binder/Microsoft.Extensions.Configuration.Binder.slnx index 31aa097c587c4f..05dbc2a033adc3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/Microsoft.Extensions.Configuration.Binder.slnx +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/Microsoft.Extensions.Configuration.Binder.slnx @@ -1,72 +1,970 @@ + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.cs index c0ee592ed6b879..dda9315fe89b13 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.cs @@ -28,22 +28,22 @@ public static void Bind(this Microsoft.Extensions.Configuration.IConfiguration c public static object? Get(this Microsoft.Extensions.Configuration.IConfiguration configuration, System.Type type) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding strongly typed objects to configuration values requires generating dynamic code at runtime, for example instantiating generic types.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.")] - public static object? Get(this Microsoft.Extensions.Configuration.IConfiguration configuration, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type type, System.Action? configureOptions) { throw null; } + public static object? Get(this Microsoft.Extensions.Configuration.IConfiguration configuration, System.Type type, System.Action? configureOptions) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.")] - public static object? GetValue(this Microsoft.Extensions.Configuration.IConfiguration configuration, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type type, string key) { throw null; } + public static object? GetValue(this Microsoft.Extensions.Configuration.IConfiguration configuration, System.Type type, string key) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.")] [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNull(nameof(defaultValue))] - public static object? GetValue(this Microsoft.Extensions.Configuration.IConfiguration configuration, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type type, string key, object? defaultValue) { throw null; } + public static object? GetValue(this Microsoft.Extensions.Configuration.IConfiguration configuration, System.Type type, string key, object? defaultValue) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.")] - public static T? GetValue<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] T>(this Microsoft.Extensions.Configuration.IConfiguration configuration, string key) { throw null; } + public static T? GetValue(this Microsoft.Extensions.Configuration.IConfiguration configuration, string key) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.")] [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNull(nameof(defaultValue))] - public static T? GetValue<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] T>(this Microsoft.Extensions.Configuration.IConfiguration configuration, string key, T defaultValue) { throw null; } + public static T? GetValue(this Microsoft.Extensions.Configuration.IConfiguration configuration, string key, T defaultValue) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding strongly typed objects to configuration values requires generating dynamic code at runtime, for example instantiating generic types.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.")] - public static T? Get<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] T>(this Microsoft.Extensions.Configuration.IConfiguration configuration) { throw null; } + public static T? Get(this Microsoft.Extensions.Configuration.IConfiguration configuration) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding strongly typed objects to configuration values requires generating dynamic code at runtime, for example instantiating generic types.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.")] - public static T? Get<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] T>(this Microsoft.Extensions.Configuration.IConfiguration configuration, System.Action? configureOptions) { throw null; } + public static T? Get(this Microsoft.Extensions.Configuration.IConfiguration configuration, System.Action? configureOptions) { throw null; } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.csproj index 71445f507e73b7..3e1809ca374d36 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.csproj @@ -13,6 +13,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/CompatibilitySuppressions.xml b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/CompatibilitySuppressions.xml new file mode 100644 index 00000000000000..91eeb345189f64 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/CompatibilitySuppressions.xml @@ -0,0 +1,102 @@ + + + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.Get(Microsoft.Extensions.Configuration.IConfiguration,System.Type,System.Action{Microsoft.Extensions.Configuration.BinderOptions})$1:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + true + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.Get``1(Microsoft.Extensions.Configuration.IConfiguration,System.Action{Microsoft.Extensions.Configuration.BinderOptions})<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + true + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.Get``1(Microsoft.Extensions.Configuration.IConfiguration)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + true + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.GetValue(Microsoft.Extensions.Configuration.IConfiguration,System.Type,System.String,System.Object)$1:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + true + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.GetValue(Microsoft.Extensions.Configuration.IConfiguration,System.Type,System.String)$1:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + true + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.GetValue``1(Microsoft.Extensions.Configuration.IConfiguration,System.String,``0)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + true + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.GetValue``1(Microsoft.Extensions.Configuration.IConfiguration,System.String)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll + true + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.Get(Microsoft.Extensions.Configuration.IConfiguration,System.Type,System.Action{Microsoft.Extensions.Configuration.BinderOptions})$1:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + true + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.Get``1(Microsoft.Extensions.Configuration.IConfiguration,System.Action{Microsoft.Extensions.Configuration.BinderOptions})<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + true + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.Get``1(Microsoft.Extensions.Configuration.IConfiguration)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + true + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.GetValue(Microsoft.Extensions.Configuration.IConfiguration,System.Type,System.String,System.Object)$1:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + true + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.GetValue(Microsoft.Extensions.Configuration.IConfiguration,System.Type,System.String)$1:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + true + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.GetValue``1(Microsoft.Extensions.Configuration.IConfiguration,System.String,``0)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + true + + + CP0014 + M:Microsoft.Extensions.Configuration.ConfigurationBinder.GetValue``1(Microsoft.Extensions.Configuration.IConfiguration,System.String)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll + true + + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs index a34553e73cd3d2..fc6c51d8342d2a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs @@ -34,7 +34,7 @@ public static class ConfigurationBinder /// The new instance of T if successful, default(T) otherwise. [RequiresDynamicCode(DynamicCodeWarningMessage)] [RequiresUnreferencedCode(TrimmingWarningMessage)] - public static T? Get<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(this IConfiguration configuration) + public static T? Get(this IConfiguration configuration) => configuration.Get(null); /// @@ -48,7 +48,7 @@ public static class ConfigurationBinder /// The new instance of T if successful, default(T) otherwise. [RequiresDynamicCode(DynamicCodeWarningMessage)] [RequiresUnreferencedCode(TrimmingWarningMessage)] - public static T? Get<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(this IConfiguration configuration, Action? configureOptions) + public static T? Get(this IConfiguration configuration, Action? configureOptions) { ArgumentNullException.ThrowIfNull(configuration); @@ -86,7 +86,6 @@ public static class ConfigurationBinder [RequiresUnreferencedCode(TrimmingWarningMessage)] public static object? Get( this IConfiguration configuration, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type, Action? configureOptions) { @@ -153,7 +152,7 @@ public static void Bind(this IConfiguration configuration, object? instance, Act /// The key of the configuration section's value to convert. /// The converted value. [RequiresUnreferencedCode(TrimmingWarningMessage)] - public static T? GetValue<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(this IConfiguration configuration, string key) + public static T? GetValue(this IConfiguration configuration, string key) { return GetValue(configuration, key, default(T)); } @@ -168,7 +167,7 @@ public static void Bind(this IConfiguration configuration, object? instance, Act /// The converted value. [RequiresUnreferencedCode(TrimmingWarningMessage)] [return: NotNullIfNotNull(nameof(defaultValue))] - public static T? GetValue<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(this IConfiguration configuration, string key, T defaultValue) + public static T? GetValue(this IConfiguration configuration, string key, T defaultValue) { return (T?)GetValue(configuration, typeof(T), key, defaultValue); } @@ -183,7 +182,6 @@ public static void Bind(this IConfiguration configuration, object? instance, Act [RequiresUnreferencedCode(TrimmingWarningMessage)] public static object? GetValue( this IConfiguration configuration, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type, string key) { @@ -202,7 +200,6 @@ public static void Bind(this IConfiguration configuration, object? instance, Act [return: NotNullIfNotNull(nameof(defaultValue))] public static object? GetValue( this IConfiguration configuration, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type, string key, object? defaultValue) { @@ -321,7 +318,7 @@ private static void BindProperty(PropertyInfo property, object instance, IConfig [RequiresDynamicCode(DynamicCodeWarningMessage)] [RequiresUnreferencedCode(TrimmingWarningMessage)] private static void BindInstance( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type, + Type type, BindingPoint bindingPoint, IConfiguration config, BinderOptions options, @@ -971,7 +968,6 @@ private static Array BindArray(Type type, IEnumerable? source, IConfiguration co [RequiresUnreferencedCode(TrimmingWarningMessage)] private static bool TryConvertValue( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type, string? value, string? path, out object? result, out Exception? error) { @@ -1030,7 +1026,6 @@ private static bool TryConvertValue( [RequiresUnreferencedCode(TrimmingWarningMessage)] private static object? ConvertValue( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type, string value, string? path) { @@ -1096,7 +1091,13 @@ private static bool TypeIsASetInterface(Type type) return null; } - private static List GetAllProperties([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type) + private static List GetAllProperties( +#if NET10_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.AllProperties)] +#else + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] +#endif + Type type) { var allProperties = new List(); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj index 1b594196a3a8ee..4580cca7a2ef12 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj @@ -29,6 +29,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs index a08ff66bd1e4d1..d869a5ad827125 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs @@ -3007,5 +3007,36 @@ public void BindArraysWithNullAndOtherValues() Assert.Equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], instance.ByteArray3); #endif } + + [Fact] + public void TestProvidersOrder() + { + string jsonConfig1 = @" + { + ""SimplePoco"": { + ""A"": ""Provider1A"", + ""B"": ""Provider1B"", + }, + }"; + + // Missing B in the second provider should not override the value from the first provider. + string jsonConfig2 = @" + { + ""SimplePoco"": { + ""A"": ""Provider2A"", + }, + }"; + + var configuration = new ConfigurationBuilder() + .AddJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(jsonConfig1))) + .AddJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(jsonConfig2))) + .Build().GetSection("SimplePoco"); + + SimplePoco? result = configuration.Get(); + + Assert.NotNull(result); + Assert.Equal("Provider2A", result.A); // Value should come from the last provider + Assert.Equal("Provider1B", result.B); // B should not be overridden by the second provider + } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Ini/tests/IniConfigurationExtensionsTest.cs b/src/libraries/Microsoft.Extensions.Configuration.Ini/tests/IniConfigurationExtensionsTest.cs index a6f3564458b472..03da264ae412ad 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Ini/tests/IniConfigurationExtensionsTest.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Ini/tests/IniConfigurationExtensionsTest.cs @@ -13,7 +13,7 @@ public class IniConfigurationExtensionsTest [InlineData(null)] [InlineData("")] [ActiveIssue("https://github.com/dotnet/runtime/issues/50867", TestPlatforms.Android)] - public void AddIniFile_ThrowsIfFilePathIsNullOrEmpty(string path) + public void AddIniFile_ThrowsIfFilePathIsNullOrEmpty(string? path) { // Arrange var configurationBuilder = new ConfigurationBuilder(); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Json/Microsoft.Extensions.Configuration.Json.slnx b/src/libraries/Microsoft.Extensions.Configuration.Json/Microsoft.Extensions.Configuration.Json.slnx index ff14bc920a5f7a..54e4c49f595054 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Json/Microsoft.Extensions.Configuration.Json.slnx +++ b/src/libraries/Microsoft.Extensions.Configuration.Json/Microsoft.Extensions.Configuration.Json.slnx @@ -1,62 +1,890 @@ + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Json/tests/JsonConfigurationExtensionsTest.cs b/src/libraries/Microsoft.Extensions.Configuration.Json/tests/JsonConfigurationExtensionsTest.cs index ba37d44740b88e..b9e0f288361644 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Json/tests/JsonConfigurationExtensionsTest.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Json/tests/JsonConfigurationExtensionsTest.cs @@ -12,7 +12,7 @@ public class JsonConfigurationExtensionsTest [Theory] [InlineData(null)] [InlineData("")] - public void AddJsonFile_ThrowsIfFilePathIsNullOrEmpty(string path) + public void AddJsonFile_ThrowsIfFilePathIsNullOrEmpty(string? path) { // Arrange var configurationBuilder = new ConfigurationBuilder(); diff --git a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/Microsoft.Extensions.Configuration.UserSecrets.slnx b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/Microsoft.Extensions.Configuration.UserSecrets.slnx index 2e2be3cbd2ff69..63a47a3fb7efc9 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/Microsoft.Extensions.Configuration.UserSecrets.slnx +++ b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/Microsoft.Extensions.Configuration.UserSecrets.slnx @@ -1,61 +1,882 @@ + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/Microsoft.Extensions.Configuration.Xml.slnx b/src/libraries/Microsoft.Extensions.Configuration.Xml/Microsoft.Extensions.Configuration.Xml.slnx index 6c84a946aaba1d..684900a2667aab 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/Microsoft.Extensions.Configuration.Xml.slnx +++ b/src/libraries/Microsoft.Extensions.Configuration.Xml/Microsoft.Extensions.Configuration.Xml.slnx @@ -1,57 +1,522 @@ + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration/Microsoft.Extensions.Configuration.slnx b/src/libraries/Microsoft.Extensions.Configuration/Microsoft.Extensions.Configuration.slnx index c2bc3448d24e2d..4b38748d4a6ce1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/Microsoft.Extensions.Configuration.slnx +++ b/src/libraries/Microsoft.Extensions.Configuration/Microsoft.Extensions.Configuration.slnx @@ -1,81 +1,1018 @@ + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration/src/InternalConfigurationRootExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration/src/InternalConfigurationRootExtensions.cs index 30bf4e33752947..a4a57d45d59930 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/src/InternalConfigurationRootExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration/src/InternalConfigurationRootExtensions.cs @@ -42,11 +42,34 @@ internal static IEnumerable GetChildrenImplementation(thi internal static bool TryGetConfiguration(this IConfigurationRoot root, string key, out string? value) { - foreach (IConfigurationProvider provider in root.Providers) + // common cases Providers is IList in ConfigurationRoot + IList providers = root.Providers is IList list + ? list + : root.Providers.ToList(); + + // ensure looping in the reverse order + for (int i = providers.Count - 1; i >= 0; i--) { - if (provider.TryGet(key, out value)) + IConfigurationProvider provider = providers[i]; + + try + { + if (provider.TryGet(key, out value)) + { + return true; + } + } + catch (ObjectDisposedException) { - return true; + // Skip disposed providers to avoid exceptions during access. + // This is especially relevant for cases like ConfigurationManager, + // which implements IConfigurationRoot and may dispose providers + // if configuration sources are concurrently modified. A new collection + // is created in this case, so it's still safe to iterate over it. + // + // If we want to avoid this possible exception altogether, we could update + // ConfigurationSection.TryGetValue to be virtual and have ConfigurationManager + // implement it with reference counting like it does for the indexer. } } diff --git a/src/libraries/Microsoft.Extensions.Configuration/tests/ConfigurationManagerTest.cs b/src/libraries/Microsoft.Extensions.Configuration/tests/ConfigurationManagerTest.cs index 7f2ca2877a48f8..0455727a1f848c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/tests/ConfigurationManagerTest.cs +++ b/src/libraries/Microsoft.Extensions.Configuration/tests/ConfigurationManagerTest.cs @@ -196,7 +196,7 @@ public async Task ProviderCanBlockLoadWaitingOnConcurrentRead() await loadTask; } - public static TheoryData ConcurrentReadActions + public static TheoryData> ConcurrentReadActions { get { diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.csproj index ecb268deba951c..1f7fb2267541d7 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/ref/Microsoft.Extensions.DependencyInjection.Abstractions.csproj @@ -12,6 +12,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj index 052e8a512402b2..98896da330bd82 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/Microsoft.Extensions.DependencyInjection.Abstractions.csproj @@ -28,6 +28,7 @@ Microsoft.Extensions.DependencyInjection.IServiceCollection + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/Microsoft.Extensions.DependencyInjection.Specification.Tests.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/Microsoft.Extensions.DependencyInjection.Specification.Tests.csproj index 3257a2ecfc6f83..ba683d4ad02606 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/Microsoft.Extensions.DependencyInjection.Specification.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Specification.Tests/src/Microsoft.Extensions.DependencyInjection.Specification.Tests.csproj @@ -7,7 +7,7 @@ true false false - false + false $(NoWarn);CA1852 $(NoWarn);1591 diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj index 21e3e191946247..0761a1ea9af0b3 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj @@ -41,6 +41,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj index f69b18b3388114..a601b683d86f9c 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/Microsoft.Extensions.DependencyInjection.Tests.csproj @@ -18,6 +18,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionKeyedServiceExtensionsTest.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionKeyedServiceExtensionsTest.cs index 681336a0a4d542..4255cca0549e60 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionKeyedServiceExtensionsTest.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionKeyedServiceExtensionsTest.cs @@ -13,7 +13,7 @@ public class ServiceCollectionKeyedServiceExtensionsTest { private static readonly FakeService _instance = new FakeService(); - public static TheoryData AddImplementationTypeData + public static TheoryData, Type, object, Type, ServiceLifetime> AddImplementationTypeData { get { @@ -61,7 +61,7 @@ public void AddWithTypeAddsServiceWithRightLifecyle(Action a Assert.Equal(lifeCycle, descriptor.Lifetime); } - public static TheoryData AddImplementationFactoryData + public static TheoryData, Type, object, Type, ServiceLifetime> AddImplementationFactoryData { get { @@ -109,7 +109,7 @@ public void AddWithFactoryAddsServiceWithRightLifecyle( Assert.Equal(lifeCycle, descriptor.Lifetime); } - public static TheoryData AddSingletonData + public static TheoryData> AddSingletonData { get { @@ -158,7 +158,7 @@ public void TryAddNoOpFailsIfExists(Action addAction) Assert.Equal(ServiceLifetime.Singleton, descriptor.Lifetime); } - public static TheoryData TryAddImplementationTypeData + public static TheoryData, Type, object, Type, ServiceLifetime> TryAddImplementationTypeData { get { @@ -256,7 +256,7 @@ public void TryAddIfMissingActuallyAdds() Assert.Equal(ServiceLifetime.Transient, descriptor.Lifetime); } - public static TheoryData TryAddEnumerableImplementationTypeData + public static TheoryData, Type, object, Type, ServiceLifetime> TryAddEnumerableImplementationTypeData { get { @@ -327,7 +327,7 @@ public void TryAddEnumerable_DoesNotAddDuplicate( Assert.Equal(expectedLifetime, d.Lifetime); } - public static TheoryData TryAddEnumerableInvalidImplementationTypeData + public static TheoryData TryAddEnumerableInvalidImplementationTypeData { get { @@ -489,7 +489,7 @@ public void RemoveAll_RemovesAllMatchingServicesWhenKeyIsInt() Assert.Equal(new[] { descriptor }, collection); } - public static TheoryData NullServiceKeyData + public static TheoryData NullServiceKeyData { get { @@ -520,7 +520,7 @@ public void NullServiceKey_IsKeyedServiceFalse(ServiceDescriptor serviceDescript Assert.Throws(() => serviceDescriptor.KeyedImplementationFactory); } - public static TheoryData NotNullServiceKeyData + public static TheoryData NotNullServiceKeyData { get { diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionServiceExtensionsTest.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionServiceExtensionsTest.cs index 3acb7de6679db0..fd5f3c201e5f4a 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionServiceExtensionsTest.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceCollectionServiceExtensionsTest.cs @@ -12,7 +12,7 @@ public class ServiceCollectionServiceExtensionsTest { private static readonly FakeService _instance = new FakeService(); - public static TheoryData AddImplementationTypeData + public static TheoryData, Type, Type, ServiceLifetime> AddImplementationTypeData { get { @@ -58,7 +58,7 @@ public void AddWithTypeAddsServiceWithRightLifecyle(Action a Assert.Equal(lifeCycle, descriptor.Lifetime); } - public static TheoryData AddImplementationFactoryData + public static TheoryData, Type, Type, ServiceLifetime> AddImplementationFactoryData { get { @@ -104,7 +104,7 @@ public void AddWithFactoryAddsServiceWithRightLifecyle( Assert.Equal(lifeCycle, descriptor.Lifetime); } - public static TheoryData AddSingletonData + public static TheoryData> AddSingletonData { get { @@ -152,7 +152,7 @@ public void TryAddNoOpFailsIfExists(Action addAction) Assert.Equal(ServiceLifetime.Singleton, descriptor.Lifetime); } - public static TheoryData TryAddImplementationTypeData + public static TheoryData, Type, Type, ServiceLifetime> TryAddImplementationTypeData { get { @@ -244,7 +244,7 @@ public void TryAddIfMissingActuallyAdds() Assert.Equal(ServiceLifetime.Transient, descriptor.Lifetime); } - public static TheoryData TryAddEnumerableImplementationTypeData + public static TheoryData TryAddEnumerableImplementationTypeData { get { @@ -310,7 +310,7 @@ public void TryAddEnumerable_DoesNotAddDuplicate( Assert.Equal(expectedLifetime, d.Lifetime); } - public static TheoryData TryAddEnumerableInvalidImplementationTypeData + public static TheoryData TryAddEnumerableInvalidImplementationTypeData { get { diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceLookup/CallSiteFactoryTest.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceLookup/CallSiteFactoryTest.cs index 919dee6475909b..655fbe0c333017 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceLookup/CallSiteFactoryTest.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceLookup/CallSiteFactoryTest.cs @@ -423,8 +423,8 @@ public void CreateCallSite_ReturnsMatchingTypesThatMatchCorrectConstraints(Type Assert.Equal(matchingImplementationTypes, enumerableCall.ServiceCallSites.Select(scs => scs.ImplementationType).ToArray()); } - public static TheoryData CreateCallSite_PicksConstructorWithTheMostNumberOfResolvedParametersData => - new TheoryData, Type[]> + public static TheoryData, Type[]> CreateCallSite_PicksConstructorWithTheMostNumberOfResolvedParametersData => + new TheoryData, Type[]> { { typeof(TypeWithSupersetConstructors), @@ -508,11 +508,11 @@ public void CreateCallSite_ReturnsMatchingTypesThatMatchCorrectConstraints(Type [MemberData(nameof(CreateCallSite_PicksConstructorWithTheMostNumberOfResolvedParametersData))] private void CreateCallSite_PicksConstructorWithTheMostNumberOfResolvedParameters( Type type, - Func callSiteFactory, + Func callSiteFactory, Type[] expectedConstructorParameters) { // Act - var callSite = callSiteFactory(type); + var callSite = (ServiceCallSite)callSiteFactory(type); // Assert Assert.Equal(CallSiteResultCacheLocation.Dispose, callSite.Cache.Location); @@ -520,7 +520,7 @@ private void CreateCallSite_PicksConstructorWithTheMostNumberOfResolvedParameter Assert.Equal(expectedConstructorParameters, GetParameters(constructorCallSite)); } - public static TheoryData CreateCallSite_ConsidersConstructorsWithDefaultValuesData => + public static TheoryData, Type[]> CreateCallSite_ConsidersConstructorsWithDefaultValuesData => new TheoryData, Type[]> { { @@ -550,14 +550,14 @@ private void CreateCallSite_PicksConstructorWithTheMostNumberOfResolvedParameter [Theory] [MemberData(nameof(CreateCallSite_ConsidersConstructorsWithDefaultValuesData))] private void CreateCallSite_ConsidersConstructorsWithDefaultValues( - Func callSiteFactory, + Func callSiteFactory, Type[] expectedConstructorParameters) { // Arrange var type = typeof(TypeWithDefaultConstructorParameters); // Act - var callSite = callSiteFactory(type); + var callSite = (ServiceCallSite)callSiteFactory(type); // Assert Assert.Equal(CallSiteResultCacheLocation.Dispose, callSite.Cache.Location); @@ -636,7 +636,7 @@ public void CreateCallSite_ThrowsIfTypeHasNoConstructurWithResolvableParameters( ex.Message); } - public static TheoryData CreateCallSite_ThrowsIfMultipleNonOverlappingConstructorsCanBeResolvedData => + public static TheoryData, Type[][]> CreateCallSite_ThrowsIfMultipleNonOverlappingConstructorsCanBeResolvedData => new TheoryData, Type[][]> { { diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceTableTest.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceTableTest.cs index b2843e39983639..13edb85cd2f329 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceTableTest.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ServiceTableTest.cs @@ -25,7 +25,7 @@ public void Constructor_WithImplementationType_ThrowsIfServiceTypeIsOpenGenericA AssertExtensions.Throws("descriptors", () => new CallSiteFactory(serviceDescriptors)); } - public static TheoryData Constructor_WithInstance_ThrowsIfServiceTypeIsOpenGenericData => + public static TheoryData Constructor_WithInstance_ThrowsIfServiceTypeIsOpenGenericData => new TheoryData { new List(), diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/Microsoft.Extensions.DependencyModel.slnx b/src/libraries/Microsoft.Extensions.DependencyModel/Microsoft.Extensions.DependencyModel.slnx index 7fefbebeda4fe5..4763145b90da6e 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/Microsoft.Extensions.DependencyModel.slnx +++ b/src/libraries/Microsoft.Extensions.DependencyModel/Microsoft.Extensions.DependencyModel.slnx @@ -1,46 +1,762 @@ + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.cs b/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.cs index f7ae0c80486eef..22d31173134c5b 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.cs @@ -127,8 +127,10 @@ public Library(string type, string name, string version, string? hash, System.Co public partial class ResourceAssembly { public ResourceAssembly(string path, string locale) { } + public ResourceAssembly(string path, string locale, string? localPath) { } public string Locale { get { throw null; } set { } } public string Path { get { throw null; } set { } } + public string? LocalPath { get { throw null; } } } public partial class RuntimeAssembly { @@ -156,9 +158,11 @@ public RuntimeFallbacks(string runtime, params string?[] fallbacks) { } public partial class RuntimeFile { public RuntimeFile(string path, string? assemblyVersion, string? fileVersion) { } + public RuntimeFile(string path, string? assemblyVersion, string? fileVersion, string? localPath) { } public string? AssemblyVersion { get { throw null; } } public string? FileVersion { get { throw null; } } public string Path { get { throw null; } } + public string? LocalPath { get { throw null; } } } public partial class RuntimeLibrary : Microsoft.Extensions.DependencyModel.Library { diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextJsonReader.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextJsonReader.cs index 8dfcb8d89b6ba5..af6b584fab09cd 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextJsonReader.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextJsonReader.cs @@ -507,6 +507,7 @@ private static List ReadRuntimeFiles(ref Utf8JsonReader reader) { string? assemblyVersion = null; string? fileVersion = null; + string? localPath = null; string? path = reader.GetString(); @@ -527,12 +528,15 @@ private static List ReadRuntimeFiles(ref Utf8JsonReader reader) case DependencyContextStrings.FileVersionPropertyName: fileVersion = propertyValue; break; + case DependencyContextStrings.LocalPathPropertyName: + localPath = propertyValue; + break; } } reader.CheckEndObject(); - runtimeFiles.Add(new RuntimeFile(path, assemblyVersion, fileVersion)); + runtimeFiles.Add(new RuntimeFile(path, assemblyVersion, fileVersion, localPath)); } reader.CheckEndObject(); @@ -578,6 +582,9 @@ private List ReadTargetLibraryRuntimeTargets(ref Utf8Jso case DependencyContextStrings.FileVersionPropertyName: runtimeTarget.FileVersion = propertyValue; break; + case DependencyContextStrings.LocalPathPropertyName: + runtimeTarget.LocalPath = propertyValue; + break; } } @@ -607,6 +614,7 @@ private List ReadTargetLibraryResources(ref Utf8JsonReader rea } string? locale = null; + string? localPath = null; reader.ReadStartObject(); @@ -616,13 +624,17 @@ private List ReadTargetLibraryResources(ref Utf8JsonReader rea { locale = propertyValue; } + else if (propertyName == DependencyContextStrings.LocalPathPropertyName) + { + localPath = propertyValue; + } } reader.CheckEndObject(); if (locale != null) { - resources.Add(new ResourceAssembly(path, Pool(locale))); + resources.Add(new ResourceAssembly(path, Pool(locale), localPath)); } } @@ -786,7 +798,7 @@ IEnumerable CreateLibrariesNotNull(IEnumerable libraries { RuntimeFile[] groupRuntimeAssemblies = ridGroup .Where(e => e.Type == DependencyContextStrings.RuntimeAssetType) - .Select(e => new RuntimeFile(e.Path, e.AssemblyVersion, e.FileVersion)) + .Select(e => new RuntimeFile(e.Path, e.AssemblyVersion, e.FileVersion, e.LocalPath)) .ToArray(); if (groupRuntimeAssemblies.Length != 0) @@ -798,7 +810,7 @@ IEnumerable CreateLibrariesNotNull(IEnumerable libraries RuntimeFile[] groupNativeLibraries = ridGroup .Where(e => e.Type == DependencyContextStrings.NativeAssetType) - .Select(e => new RuntimeFile(e.Path, e.AssemblyVersion, e.FileVersion)) + .Select(e => new RuntimeFile(e.Path, e.AssemblyVersion, e.FileVersion, e.LocalPath)) .ToArray(); if (groupNativeLibraries.Length != 0) @@ -909,6 +921,8 @@ private struct RuntimeTargetEntryStub public string? AssemblyVersion; public string? FileVersion; + + public string? LocalPath; } private struct LibraryStub diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextStrings.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextStrings.cs index 09802702197491..fcdf9beba015d8 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextStrings.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextStrings.cs @@ -86,5 +86,7 @@ internal static class DependencyContextStrings internal const string AssemblyVersionPropertyName = "assemblyVersion"; internal const string FileVersionPropertyName = "fileVersion"; + + internal const string LocalPathPropertyName = "localPath"; } } diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextWriter.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextWriter.cs index d4247d937067a7..86c1a548b491b8 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextWriter.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextWriter.cs @@ -222,6 +222,11 @@ private static void AddResourceAssemblies(IReadOnlyList resour ResourceAssembly resourceAssembly = resourceAssemblies[i]; jsonWriter.WriteStartObject(NormalizePath(resourceAssembly.Path)); jsonWriter.WriteString(DependencyContextStrings.LocalePropertyName, resourceAssembly.Locale); + if (resourceAssembly.LocalPath != null) + { + jsonWriter.WriteString(DependencyContextStrings.LocalPathPropertyName, NormalizePath(resourceAssembly.LocalPath)); + } + jsonWriter.WriteEndObject(); } jsonWriter.WriteEndObject(); @@ -363,6 +368,11 @@ private static void AddRuntimeSpecificAssets(IEnumerable assets, st jsonWriter.WriteString(DependencyContextStrings.FileVersionPropertyName, asset.FileVersion); } + if (asset.LocalPath != null) + { + jsonWriter.WriteString(DependencyContextStrings.LocalPathPropertyName, NormalizePath(asset.LocalPath)); + } + jsonWriter.WriteEndObject(); } } @@ -396,6 +406,11 @@ private static void WriteAssetList(string key, IEnumerable runtimeF jsonWriter.WriteString(DependencyContextStrings.FileVersionPropertyName, runtimeFile.FileVersion); } + if (runtimeFile.LocalPath != null) + { + jsonWriter.WriteString(DependencyContextStrings.LocalPathPropertyName, NormalizePath(runtimeFile.LocalPath)); + } + jsonWriter.WriteEndObject(); } diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/ResourceAssembly.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/ResourceAssembly.cs index 04d480837c8ad0..9916e19207f826 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/ResourceAssembly.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/ResourceAssembly.cs @@ -8,6 +8,10 @@ namespace Microsoft.Extensions.DependencyModel public class ResourceAssembly { public ResourceAssembly(string path, string locale) + : this(path, locale, null) + { } + + public ResourceAssembly(string path, string locale, string? localPath) { if (string.IsNullOrEmpty(path)) { @@ -19,11 +23,16 @@ public ResourceAssembly(string path, string locale) } Locale = locale; Path = path; + LocalPath = localPath; } public string Locale { get; set; } + // Depending on the source of the resource assembly, this path may be relative to the + // a referenced NuGet package's root or to the app/component root. public string Path { get; set; } + // Path relative to the app/component represented by the dependency context + public string? LocalPath { get; } } } diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeFile.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeFile.cs index 16a4524865ad45..1b9fa096835946 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeFile.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeFile.cs @@ -8,6 +8,10 @@ namespace Microsoft.Extensions.DependencyModel public class RuntimeFile { public RuntimeFile(string path, string? assemblyVersion, string? fileVersion) + : this(path, assemblyVersion, fileVersion, null) + { } + + public RuntimeFile(string path, string? assemblyVersion, string? fileVersion, string? localPath) { if (string.IsNullOrEmpty(path)) { @@ -17,12 +21,18 @@ public RuntimeFile(string path, string? assemblyVersion, string? fileVersion) Path = path; AssemblyVersion = assemblyVersion; FileVersion = fileVersion; + LocalPath = localPath; } + // Depending on the source of the runtime file, this path may be relative to the + // a referenced NuGet package's root or to the app/component root. public string Path { get; } public string? AssemblyVersion { get; } public string? FileVersion { get; } + + // Path relative to the app/component represented by the dependency context + public string? LocalPath { get; } } } diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/tests/DependencyContextJsonReaderTest.cs b/src/libraries/Microsoft.Extensions.DependencyModel/tests/DependencyContextJsonReaderTest.cs index e16ec056079a97..b1e2e126391f52 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/tests/DependencyContextJsonReaderTest.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/tests/DependencyContextJsonReaderTest.cs @@ -835,5 +835,123 @@ public void FailsToReadEmptyLibraryType() } ")); } + + [Fact] + public void ReadsRuntimeFilesWithLocalPath() + { + var context = Read( +@"{ + ""targets"": { + "".NETCoreApp,Version=v5.0"": { + ""System.Banana/1.0.0"": { + ""runtime"": { + ""lib/System.Banana.dll"": { + ""assemblyVersion"": ""1.2.3"", + ""fileVersion"": ""4.5.6"", + ""localPath"": ""local/path/System.Banana.dll"" + } + } + } + } + }, + ""libraries"": { + ""System.Banana/1.0.0"": { + ""type"": ""package"", + ""serviceable"": false, + ""sha512"": ""HASH-System.Banana"" + } + } +}"); + + var runtimeLibrary = context.RuntimeLibraries.Should().ContainSingle().Subject; + var runtimeFile = runtimeLibrary.RuntimeAssemblyGroups.GetDefaultRuntimeFileAssets().Single(); + + Assert.Equal("lib/System.Banana.dll", runtimeFile.Path); + Assert.Equal("1.2.3", runtimeFile.AssemblyVersion); + Assert.Equal("4.5.6", runtimeFile.FileVersion); + Assert.Equal("local/path/System.Banana.dll", runtimeFile.LocalPath); + } + + [Fact] + public void ReadsRuntimeTargetsWithLocalPath() + { + var context = Read( +@"{ + ""targets"": { + "".NETCoreApp,Version=v5.0/unix"": { + ""System.Banana/1.0.0"": { + ""runtimeTargets"": { + ""runtimes/unix/lib/System.Banana.dll"": { + ""rid"": ""unix"", + ""assetType"": ""runtime"", + ""assemblyVersion"": ""1.2.3"", + ""fileVersion"": ""4.5.6"", + ""localPath"": ""unix/custom/System.Banana.dll"" + }, + ""runtimes/linux-x64/native/native.so"": { + ""rid"": ""linux-x64"", + ""assetType"": ""native"", + ""assemblyVersion"": ""1.2.3"", + ""fileVersion"": ""4.5.6"", + ""localPath"": ""local/path/linux-x64/native.so"" + } + } + } + } + }, + ""libraries"": { + ""System.Banana/1.0.0"": { + ""type"": ""package"", + ""serviceable"": false, + ""sha512"": ""HASH-System.Banana"" + } + } +}"); + + var runtimeLibrary = context.RuntimeLibraries.Should().ContainSingle().Subject; + var runtimeFile = runtimeLibrary.RuntimeAssemblyGroups.GetRuntimeFileAssets("unix").Single(); + Assert.Equal("runtimes/unix/lib/System.Banana.dll", runtimeFile.Path); + Assert.Equal("1.2.3", runtimeFile.AssemblyVersion); + Assert.Equal("4.5.6", runtimeFile.FileVersion); + Assert.Equal("unix/custom/System.Banana.dll", runtimeFile.LocalPath); + + runtimeFile = runtimeLibrary.NativeLibraryGroups.GetRuntimeFileAssets("linux-x64").Single(); + Assert.Equal("runtimes/linux-x64/native/native.so", runtimeFile.Path); + Assert.Equal("local/path/linux-x64/native.so", runtimeFile.LocalPath); + } + + [Fact] + public void ReadsResourceAssembliesWithLocalPath() + { + var context = Read( +@"{ + ""targets"": { + "".NETCoreApp,Version=v5.0"": { + ""System.Banana/1.0.0"": { + ""resources"": { + ""fr/System.Banana.resources.dll"": { + ""locale"": ""fr"", + ""localPath"": ""local/path/fr/System.Banana.resources.dll"" + } + } + } + } + }, + ""libraries"": { + ""System.Banana/1.0.0"": { + ""type"": ""package"", + ""serviceable"": false, + ""sha512"": ""HASH-System.Banana"" + } + } +}"); + + var runtimeLibrary = context.RuntimeLibraries.Should().ContainSingle().Subject; + var resourceAssembly = runtimeLibrary.ResourceAssemblies.Single(); + + Assert.Equal("fr/System.Banana.resources.dll", resourceAssembly.Path); + Assert.Equal("fr", resourceAssembly.Locale); + Assert.Equal("local/path/fr/System.Banana.resources.dll", resourceAssembly.LocalPath); + } } } diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/tests/DependencyContextJsonWriterTests.cs b/src/libraries/Microsoft.Extensions.DependencyModel/tests/DependencyContextJsonWriterTests.cs index 3e306f0a46bdd5..93fa5ec7dc9c52 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/tests/DependencyContextJsonWriterTests.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/tests/DependencyContextJsonWriterTests.cs @@ -277,95 +277,6 @@ public void ExcludesPathAndHashPath() library.Should().NotHaveProperty("hashPath"); } - [Fact] - public void WritesRuntimeLibrariesToRuntimeTarget() - { - var group = new RuntimeAssetGroup("win7-x64", "Banana.Win7-x64.dll"); - WritesRuntimeLibrariesToRuntimeTargetCore(group); - } - - [Fact] - public void WritesRuntimeLibrariesToRuntimeTargetWithAssemblyVersions() - { - RuntimeFile[] runtimeFile = { new RuntimeFile("Banana.Win7-x64.dll", "1.2.3", "7.8.9") }; - var group = new RuntimeAssetGroup("win7-x64", runtimeFile); - - var runtimeAssembly = WritesRuntimeLibrariesToRuntimeTargetCore(group); - runtimeAssembly.Should().HavePropertyValue("assemblyVersion", "1.2.3"); - runtimeAssembly.Should().HavePropertyValue("fileVersion", "7.8.9"); - } - - private JObject WritesRuntimeLibrariesToRuntimeTargetCore(RuntimeAssetGroup group) - { - var result = Save(Create( - "Target", - "runtime", - true, - runtimeLibraries: new[] - { - new RuntimeLibrary( - "package", - "PackageName", - "1.2.3", - "HASH", - new [] { - new RuntimeAssetGroup(string.Empty, "Banana.dll"), - group - }, - new [] { - new RuntimeAssetGroup(string.Empty, "runtimes\\linux\\native\\native.so"), - new RuntimeAssetGroup("win7-x64", "native\\Banana.Win7-x64.so") - }, - new [] { new ResourceAssembly("en-US\\Banana.Resource.dll", "en-US")}, - new [] { - new Dependency("Fruits.Abstract.dll","2.0.0") - }, - true, - "PackagePath", - "PackageHashPath", - "placeHolderManifest.xml" - ), - })); - - // targets - var targets = result.Should().HavePropertyAsObject("targets").Subject; - var target = targets.Should().HavePropertyAsObject("Target").Subject; - var library = target.Should().HavePropertyAsObject("PackageName/1.2.3").Subject; - var dependencies = library.Should().HavePropertyAsObject("dependencies").Subject; - dependencies.Should().HavePropertyValue("Fruits.Abstract.dll", "2.0.0"); - - library.Should().HavePropertyAsObject("runtime") - .Subject.Should().HaveProperty("Banana.dll"); - library.Should().HavePropertyAsObject("native") - .Subject.Should().HaveProperty("runtimes/linux/native/native.so"); - - var runtimeTargets = library.Should().HavePropertyAsObject("runtimeTargets").Subject; - - var runtimeAssembly = runtimeTargets.Should().HavePropertyAsObject("Banana.Win7-x64.dll").Subject; - runtimeAssembly.Should().HavePropertyValue("rid", "win7-x64"); - runtimeAssembly.Should().HavePropertyValue("assetType", "runtime"); - - var nativeLibrary = runtimeTargets.Should().HavePropertyAsObject("native/Banana.Win7-x64.so").Subject; - nativeLibrary.Should().HavePropertyValue("rid", "win7-x64"); - nativeLibrary.Should().HavePropertyValue("assetType", "native"); - - var resourceAssemblies = library.Should().HavePropertyAsObject("resources").Subject; - var resourceAssembly = resourceAssemblies.Should().HavePropertyAsObject("en-US/Banana.Resource.dll").Subject; - resourceAssembly.Should().HavePropertyValue("locale", "en-US"); - - //libraries - var libraries = result.Should().HavePropertyAsObject("libraries").Subject; - library = libraries.Should().HavePropertyAsObject("PackageName/1.2.3").Subject; - library.Should().HavePropertyValue("sha512", "HASH"); - library.Should().HavePropertyValue("type", "package"); - library.Should().HavePropertyValue("serviceable", true); - library.Should().HavePropertyValue("path", "PackagePath"); - library.Should().HavePropertyValue("hashPath", "PackageHashPath"); - library.Should().HavePropertyValue("runtimeStoreManifestName", "placeHolderManifest.xml"); - - return runtimeAssembly; - } - [Fact] public void WritesRuntimePackLibrariesWithFrameworkName() { @@ -513,35 +424,105 @@ public void MergesRuntimeAndCompileLibrariesForPortable() library.Should().HavePropertyValue("runtimeStoreManifestName", "placeHolderManifest.xml"); } - [Fact] - public void WritesRuntimeTargetForNonPortableLegacy() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void WritesRuntimeAssembly_PathOnly(bool isPortable) { - var group = new RuntimeAssetGroup(string.Empty, "Banana.dll"); - var assetGroup = WritesRuntimeTarget(group); + List groups = [ new RuntimeAssetGroup(string.Empty, "Banana.dll") ]; + if (isPortable) + groups.Add(new RuntimeAssetGroup("win-x64", "Banana.win-x64.dll")); - var files = assetGroup.Should().HavePropertyAsObject("runtime").Subject; - files.Should().HaveProperty("Banana.dll"); + WritesRuntimeAssembly(isPortable, groups); } - [Fact] - public void WritesRuntimeTargetForNonPortable() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void WritesRuntimeAssembly_Versions(bool isPortable) + { + List groups = [ + new RuntimeAssetGroup(string.Empty, [new RuntimeFile("Banana.dll", "1.2.3", "7.8.9")]) + ]; + if (isPortable) + groups.Add(new RuntimeAssetGroup("win-x64", [ new RuntimeFile("Banana.win-x64.dll", "1.2.3", "7.8.9") ])); + + WritesRuntimeAssembly(isPortable, groups); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void WritesRuntimeAssembly_LocalPath(bool isPortable) { - RuntimeFile[] runtimeFiles = { new RuntimeFile("Banana.dll", "1.2.3", "7.8.9") }; - var group = new RuntimeAssetGroup(string.Empty, runtimeFiles); - var assetGroup = WritesRuntimeTarget(group); - - var files = assetGroup.Should().HavePropertyAsObject("runtime").Subject; - var file = files.Should().HavePropertyAsObject("Banana.dll").Subject; - file.Should().HavePropertyValue("assemblyVersion", "1.2.3"); - file.Should().HavePropertyValue("fileVersion", "7.8.9"); + List groups = [ + new RuntimeAssetGroup(string.Empty, [ new RuntimeFile("Banana.dll", "1.2.3", "7.8.9", "local/path/Banana.dll")]) + ]; + if (isPortable) + groups.Add(new RuntimeAssetGroup("win-x64", [new RuntimeFile("Banana.win-x64.dll", "1.2.3", "7.8.9", "local/path/Banana.win-x64.dll")])); + + WritesRuntimeAssembly(isPortable, groups); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void WritesNativeLibrary_PathOnly(bool isPortable) + { + List groups = [new RuntimeAssetGroup(string.Empty, "native.so")]; + if (isPortable) + groups.Add(new RuntimeAssetGroup("linux-x64", "runtimes/linux-x64/native/native.linux-64.so")); + + WritesNativeLibrary(isPortable, groups); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void WritesNativeLibrary_LocalPath(bool isPortable) + { + List groups = [ + new RuntimeAssetGroup(string.Empty, [new RuntimeFile("native.so", null, null, "local/path/native.so")]) + ]; + if (isPortable) + groups.Add(new RuntimeAssetGroup("linux-x64", [new RuntimeFile("runtimes/linux-x64/native/native.linux-64.so", null, null, "local/path/native.so")])); + + WritesNativeLibrary(isPortable, groups); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void WritesResourceAssembly_PathOnly(bool isPortable) + { + ResourceAssembly resourceAssembly = new ResourceAssembly("fr/Fruits.resources.dll", "fr"); + WritesResourceAssembly(isPortable, [resourceAssembly]); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void WritesResourceAssembly_LocalPath(bool isPortable) + { + ResourceAssembly resourceAssembly = new ResourceAssembly("fr/Fruits.resources.dll", "fr", "local/path/fr/Fruits.resources.dll"); + WritesResourceAssembly(isPortable, [resourceAssembly]); } - private JObject WritesRuntimeTarget(RuntimeAssetGroup group) + private void WritesRuntimeAssembly(bool isPortable, IReadOnlyList runtimeAssemblies) + => WritesRuntimeLibrary(isPortable, runtimeAssemblies, [], []); + + private void WritesNativeLibrary(bool isPortable, IReadOnlyList nativeLibraries) + => WritesRuntimeLibrary(isPortable, [], nativeLibraries, []); + + private void WritesResourceAssembly(bool isPortable, ResourceAssembly[] resourceAssemblies) + => WritesRuntimeLibrary(isPortable, [], [], resourceAssemblies); + + private void WritesRuntimeLibrary(bool isPortable, IReadOnlyList runtimeAssemblies, IReadOnlyList nativeLibraries, ResourceAssembly[] resourceAssemblies) { var result = Save(Create( "Target", "runtime", - false, + isPortable, runtimeLibraries: new[] { new RuntimeLibrary( @@ -549,17 +530,11 @@ private JObject WritesRuntimeTarget(RuntimeAssetGroup group) "PackageName", "1.2.3", "HASH", - new [] { - group - }, - new [] { - new RuntimeAssetGroup(string.Empty, "runtimes\\osx\\native\\native.dylib") - }, - new ResourceAssembly[] {}, - new [] { - new Dependency("Fruits.Abstract.dll","2.0.0") - }, - true, + runtimeAssemblies, + nativeLibraries, + resourceAssemblies, + dependencies: [], + serviceable: true, "PackagePath", "PackageHashPath" ), @@ -567,23 +542,90 @@ private JObject WritesRuntimeTarget(RuntimeAssetGroup group) // targets var targets = result.Should().HavePropertyAsObject("targets").Subject; - var target = targets.Should().HavePropertyAsObject("Target/runtime").Subject; - var assetGroup = target.Should().HavePropertyAsObject("PackageName/1.2.3").Subject; - var dependencies = assetGroup.Should().HavePropertyAsObject("dependencies").Subject; - dependencies.Should().HavePropertyValue("Fruits.Abstract.dll", "2.0.0"); - assetGroup.Should().HavePropertyAsObject("native") - .Subject.Should().HaveProperty("runtimes/osx/native/native.dylib"); + var target = targets.Should().HavePropertyAsObject($"Target{(isPortable ? "" : "/runtime")}").Subject; + var library = target.Should().HavePropertyAsObject("PackageName/1.2.3").Subject; - //libraries - var libraries = result.Should().HavePropertyAsObject("libraries").Subject; - var library = libraries.Should().HavePropertyAsObject("PackageName/1.2.3").Subject; - library.Should().HavePropertyValue("sha512", "HASH"); - library.Should().HavePropertyValue("type", "package"); - library.Should().HavePropertyValue("serviceable", true); - library.Should().HavePropertyValue("path", "PackagePath"); - library.Should().HavePropertyValue("hashPath", "PackageHashPath"); + ValidateRuntimeAssetGroups(library, runtimeAssemblies, DependencyContextStrings.RuntimeAssetType); + ValidateRuntimeAssetGroups(library, nativeLibraries, DependencyContextStrings.NativeAssetType); + + if (resourceAssemblies.Length == 0) + { + library.Should().NotHaveProperty(DependencyContextStrings.ResourceAssembliesPropertyName); + } + else + { + var resources = library.Should().HavePropertyAsObject(DependencyContextStrings.ResourceAssembliesPropertyName).Subject; + foreach (var resource in resourceAssemblies) + { + var resourceJson = resources.Should().HavePropertyAsObject(resource.Path).Subject; + resourceJson.Should().HavePropertyValue(DependencyContextStrings.LocalePropertyName, resource.Locale); + if (string.IsNullOrEmpty(resource.LocalPath)) + { + resourceJson.Should().NotHaveProperty(DependencyContextStrings.LocalPathPropertyName); + } + else + { + resourceJson.Should().HavePropertyValue(DependencyContextStrings.LocalPathPropertyName, resource.LocalPath); + } + } + } + } + + private void ValidateRuntimeAssetGroups(JObject library, IReadOnlyList groups, string assetType) + { + if (groups.Count == 0) + library.Should().NotHaveProperty(assetType); + + foreach (var group in groups) + { + bool hasRuntimeId = !string.IsNullOrEmpty(group.Runtime); + var files = library.Should().HavePropertyAsObject(hasRuntimeId ? DependencyContextStrings.RuntimeTargetsPropertyName : assetType).Subject; + foreach (var file in group.RuntimeFiles) + { + var fileJson = files.Should().HavePropertyAsObject(file.Path).Subject; + ValidateRuntimeFile(file, fileJson); + if (hasRuntimeId) + { + fileJson.Should().HavePropertyValue(DependencyContextStrings.RidPropertyName, group.Runtime); + fileJson.Should().HavePropertyValue(DependencyContextStrings.AssetTypePropertyName, assetType); + } + else + { + fileJson.Should().NotHaveProperty(DependencyContextStrings.RidPropertyName); + fileJson.Should().NotHaveProperty(DependencyContextStrings.AssetTypePropertyName); + } + } + } + } + + private void ValidateRuntimeFile(RuntimeFile file, JObject fileJson) + { + if (string.IsNullOrEmpty(file.AssemblyVersion)) + { + fileJson.Should().NotHaveProperty(DependencyContextStrings.AssemblyVersionPropertyName); + } + else + { + fileJson.Should().HavePropertyValue(DependencyContextStrings.AssemblyVersionPropertyName, file.AssemblyVersion); + } + + if (string.IsNullOrEmpty(file.FileVersion)) + { + fileJson.Should().NotHaveProperty(DependencyContextStrings.FileVersionPropertyName); + } + else + { + fileJson.Should().HavePropertyValue(DependencyContextStrings.FileVersionPropertyName, file.FileVersion); + } - return assetGroup; + if (string.IsNullOrEmpty(file.LocalPath)) + { + fileJson.Should().NotHaveProperty(DependencyContextStrings.LocalPathPropertyName); + } + else + { + fileJson.Should().HavePropertyValue(DependencyContextStrings.LocalPathPropertyName, file.LocalPath); + } } [Fact] @@ -640,78 +682,6 @@ public void WritesPlaceholderRuntimeTargetsForEmptyGroups() osxNative.Should().HavePropertyValue("assetType", "native"); } - [Fact] - public void WritesResourceAssembliesForNonPortable() - { - var result = Save(Create( - "Target", - "runtime", - false, - runtimeLibraries: new[] - { - new RuntimeLibrary( - "package", - "PackageName", - "1.2.3", - "HASH", - new RuntimeAssetGroup[] { }, - new RuntimeAssetGroup[] { }, - new [] - { - new ResourceAssembly("en-US/Fruits.resources.dll", "en-US") - }, - new Dependency[] { }, - true, - "PackagePath", - "PackageHashPath" - ), - })); - - var targets = result.Should().HavePropertyAsObject("targets").Subject; - var target = targets.Should().HavePropertyAsObject("Target/runtime").Subject; - var library = target.Should().HavePropertyAsObject("PackageName/1.2.3").Subject; - var resources = library.Should().HavePropertyAsObject("resources").Subject; - var resource = resources.Should().HavePropertyAsObject("en-US/Fruits.resources.dll").Subject; - resource.Should().HavePropertyValue("locale", "en-US"); - } - - - [Fact] - public void WritesResourceAssembliesForPortable() - { - var result = Save(Create( - "Target", - "runtime", - true, - runtimeLibraries: new[] - { - new RuntimeLibrary( - "package", - "PackageName", - "1.2.3", - "HASH", - new RuntimeAssetGroup[] { }, - new RuntimeAssetGroup[] { }, - new [] - { - new ResourceAssembly("en-US/Fruits.resources.dll", "en-US") - }, - new Dependency[] { }, - true, - "PackagePath", - "PackageHashPath" - ), - })); - - var targets = result.Should().HavePropertyAsObject("targets").Subject; - var target = targets.Should().HavePropertyAsObject("Target").Subject; - var library = target.Should().HavePropertyAsObject("PackageName/1.2.3").Subject; - var resources = library.Should().HavePropertyAsObject("resources").Subject; - var resource = resources.Should().HavePropertyAsObject("en-US/Fruits.resources.dll").Subject; - resource.Should().HavePropertyValue("locale", "en-US"); - } - - [Fact] public void WriteCompilationOnlyAttributeIfOnlyCompilationLibraryProvided() { @@ -743,7 +713,6 @@ public void WriteCompilationOnlyAttributeIfOnlyCompilationLibraryProvided() library.Should().HavePropertyValue("compileOnly", true); } - [Fact] public void WritesCompilationOptions() { diff --git a/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/Microsoft.Extensions.Diagnostics.Abstractions.slnx b/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/Microsoft.Extensions.Diagnostics.Abstractions.slnx index e4fddf9b39f513..25a014b9da362d 100644 --- a/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/Microsoft.Extensions.Diagnostics.Abstractions.slnx +++ b/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/Microsoft.Extensions.Diagnostics.Abstractions.slnx @@ -1,43 +1,458 @@ + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/ref/Microsoft.Extensions.Diagnostics.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/ref/Microsoft.Extensions.Diagnostics.Abstractions.csproj index 63b868b9850364..4e77d2e5b2e094 100644 --- a/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/ref/Microsoft.Extensions.Diagnostics.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/ref/Microsoft.Extensions.Diagnostics.Abstractions.csproj @@ -11,6 +11,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/src/Microsoft.Extensions.Diagnostics.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/src/Microsoft.Extensions.Diagnostics.Abstractions.csproj index 202fe7fc5c436e..0254acdc4052e1 100644 --- a/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/src/Microsoft.Extensions.Diagnostics.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/src/Microsoft.Extensions.Diagnostics.Abstractions.csproj @@ -26,6 +26,7 @@ Microsoft.Extensions.Diagnostics.Metrics.MetricsOptions + diff --git a/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/tests/MetricsBuilderExtensionsRulesTests.cs b/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/tests/MetricsBuilderExtensionsRulesTests.cs index 18568a8480392a..f06f254d5f5abb 100644 --- a/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/tests/MetricsBuilderExtensionsRulesTests.cs +++ b/src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/tests/MetricsBuilderExtensionsRulesTests.cs @@ -15,7 +15,7 @@ public class MetricsBuilderExtensionsRulesTests [InlineData("")] [InlineData("*")] [InlineData("foo")] - public void BuilderEnableMetricsAddsRule(string meterName) + public void BuilderEnableMetricsAddsRule(string? meterName) { var services = new ServiceCollection(); services.AddOptions(); @@ -59,7 +59,7 @@ public void BuilderEnableMetricsWithAllParamsAddsRule() [InlineData("")] [InlineData("*")] [InlineData("foo")] - public void OptionsEnableMetricsAddsRule(string meterName) + public void OptionsEnableMetricsAddsRule(string? meterName) { var services = new ServiceCollection(); services.AddOptions(); @@ -100,7 +100,7 @@ public void OptionsEnableMetricsAllParamsAddsRule() [InlineData("")] [InlineData("*")] [InlineData("foo")] - public void BuilderDisableMetricsAddsRule(string meterName) + public void BuilderDisableMetricsAddsRule(string? meterName) { var services = new ServiceCollection(); services.AddOptions(); @@ -144,7 +144,7 @@ public void BuilderDisableMetricsWithAllParamsAddsRule() [InlineData("")] [InlineData("*")] [InlineData("foo")] - public void OptionsDisableMetricsAddsRule(string meterName) + public void OptionsDisableMetricsAddsRule(string? meterName) { var services = new ServiceCollection(); services.AddOptions(); diff --git a/src/libraries/Microsoft.Extensions.Diagnostics/Microsoft.Extensions.Diagnostics.slnx b/src/libraries/Microsoft.Extensions.Diagnostics/Microsoft.Extensions.Diagnostics.slnx index 26d72e35663f46..638b6bc89015c2 100644 --- a/src/libraries/Microsoft.Extensions.Diagnostics/Microsoft.Extensions.Diagnostics.slnx +++ b/src/libraries/Microsoft.Extensions.Diagnostics/Microsoft.Extensions.Diagnostics.slnx @@ -1,109 +1,1314 @@ + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/ref/Microsoft.Extensions.FileProviders.Abstractions.cs b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/ref/Microsoft.Extensions.FileProviders.Abstractions.cs index 8d3d62bb9c8734..7bdf2d6a102ea4 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/ref/Microsoft.Extensions.FileProviders.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/ref/Microsoft.Extensions.FileProviders.Abstractions.cs @@ -46,7 +46,7 @@ public NotFoundFileInfo(string name) { } [System.Diagnostics.CodeAnalysis.DoesNotReturn] public System.IO.Stream CreateReadStream() { throw null; } } - public partial class NullChangeToken : Microsoft.Extensions.Primitives.IChangeToken + public sealed partial class NullChangeToken : Microsoft.Extensions.Primitives.IChangeToken { internal NullChangeToken() { } public bool ActiveChangeCallbacks { get { throw null; } } diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/NullChangeToken.cs b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/NullChangeToken.cs index 17812a299490ee..eb10eed91052a2 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/NullChangeToken.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Abstractions/src/NullChangeToken.cs @@ -9,7 +9,7 @@ namespace Microsoft.Extensions.FileProviders /// /// An empty change token that doesn't raise any change callbacks. /// - public class NullChangeToken : IChangeToken + public sealed class NullChangeToken : IChangeToken { /// /// Gets a singleton instance of . diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/PathUtils.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/PathUtils.cs index 02bc4d5f6acf41..9b075731b7721f 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/PathUtils.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/PathUtils.cs @@ -17,7 +17,7 @@ private static char[] GetInvalidFileNameChars() => Path.GetInvalidFileNameChars( private static char[] GetInvalidFilterChars() => GetInvalidFileNameChars() .Where(c => c != '*' && c != '|' && c != '?').ToArray(); -#if NET8_0_OR_GREATER +#if NET private static readonly SearchValues _invalidFileNameChars = SearchValues.Create(GetInvalidFileNameChars()); private static readonly SearchValues _invalidFilterChars = SearchValues.Create(GetInvalidFilterChars()); diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/ExclusionFilterTests.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/ExclusionFilterTests.cs index 6afdb6faa12d77..f83cf015fc4c44 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/ExclusionFilterTests.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/tests/ExclusionFilterTests.cs @@ -42,7 +42,7 @@ public void FiltersExcludedDirectories(string dirname, FileAttributes attributes Assert.Equal(excluded, FileSystemInfoHelper.IsExcluded(dirInfo, filters)); } - public static TheoryData Combinations + public static TheoryData Combinations { get { diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/FilePatternMatch.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/FilePatternMatch.cs index e19649700e322c..87d3954ef41292 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/FilePatternMatch.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/FilePatternMatch.cs @@ -28,16 +28,17 @@ public struct FilePatternMatch : IEquatable /// If the matcher searched for "src/Project/**/*.cs" and the pattern matcher found "src/Project/Interfaces/IFile.cs", /// then = "Interfaces/IFile.cs" and = "src/Project/Interfaces/IFile.cs". /// - public string? Stem { get; } + public string Stem { get; } /// /// Initializes new instance of /// /// The path to the file matched, relative to the beginning of the matching search pattern. /// The subpath to the file matched, relative to the first wildcard in the matching search pattern. - public FilePatternMatch(string path, string? stem) + public FilePatternMatch(string path, string stem) { ArgumentNullException.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(stem); Path = path; Stem = stem; diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternTestResult.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternTestResult.cs index d1067b28574e41..4005fdc13ffa81 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternTestResult.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternTestResult.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.Diagnostics.CodeAnalysis; + namespace Microsoft.Extensions.FileSystemGlobbing.Internal { /// @@ -11,6 +13,7 @@ public struct PatternTestResult { public static readonly PatternTestResult Failed = new(isSuccessful: false, stem: null); + [MemberNotNullWhen(returnValue: true, nameof(Stem))] public bool IsSuccessful { get; } public string? Stem { get; } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/FilePatternMatchTests.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/FilePatternMatchTests.cs index c16e991e3b111c..f352c27013b2fe 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/FilePatternMatchTests.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/FilePatternMatchTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using Xunit; namespace Microsoft.Extensions.FileSystemGlobbing.Tests @@ -24,5 +25,17 @@ public void TestGetHashCode() FilePatternMatch matchCase2 = new FilePatternMatch("sub/sub2/bar/baz/three.txt", "Sub2/bar/baz/thrEE.txt"); Assert.Equal(matchCase1.GetHashCode(), matchCase2.GetHashCode()); } + + [Fact] + public void TestPathArgumentNullExceptions() + { + Assert.Throws(() => new FilePatternMatch(null, "sub2/bar/baz/three.txt")); + } + + [Fact] + public void TestStemArgumentNullExceptions() + { + Assert.Throws(() => new FilePatternMatch("sub2/bar/baz/three.txt", null)); + } } } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/PatternContexts/PatternContextRaggedTests.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/PatternContexts/PatternContextRaggedTests.cs index 0622ffb80b4ec1..607f208be1b12a 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/PatternContexts/PatternContextRaggedTests.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/PatternContexts/PatternContextRaggedTests.cs @@ -35,7 +35,7 @@ public void PredictBeforeEnterDirectoryShouldThrow() [InlineData("/a/b/**/c/d", new string[] { "root", "a", "b" }, null)] [InlineData("/a/b/**/c/d", new string[] { "root", "a", "b", "whatever" }, null)] [InlineData("/a/b/**/c/d", new string[] { "root", "a", "b", "whatever", "anything" }, null)] - public void PredictReturnsCorrectResult(string patternString, string[] pushDirectory, string expectSegment) + public void PredictReturnsCorrectResult(string patternString, string[] pushDirectory, string? expectSegment) { var builder = new PatternBuilder(); var pattern = builder.Build(patternString) as IRaggedPattern; diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/PatternSegments/CurrentPathSegmentTests.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/PatternSegments/CurrentPathSegmentTests.cs index c01416171275ad..f5562d440ab284 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/PatternSegments/CurrentPathSegmentTests.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/PatternSegments/CurrentPathSegmentTests.cs @@ -12,7 +12,7 @@ public class CurrentPathSegmentTests [InlineData("anything")] [InlineData("")] [InlineData(null)] - public void Match(string testSample) + public void Match(string? testSample) { var pathSegment = new CurrentPathSegment(); Assert.False(pathSegment.Match(testSample)); diff --git a/src/libraries/Microsoft.Extensions.HostFactoryResolver/Microsoft.Extensions.HostFactoryResolver.slnx b/src/libraries/Microsoft.Extensions.HostFactoryResolver/Microsoft.Extensions.HostFactoryResolver.slnx index 7928614f6f79d2..b1787756837195 100644 --- a/src/libraries/Microsoft.Extensions.HostFactoryResolver/Microsoft.Extensions.HostFactoryResolver.slnx +++ b/src/libraries/Microsoft.Extensions.HostFactoryResolver/Microsoft.Extensions.HostFactoryResolver.slnx @@ -1,126 +1,1450 @@ + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/Microsoft.Extensions.Hosting.Abstractions.slnx b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/Microsoft.Extensions.Hosting.Abstractions.slnx index 10d2d2719e2ced..295fd6a78e17b6 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/Microsoft.Extensions.Hosting.Abstractions.slnx +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/Microsoft.Extensions.Hosting.Abstractions.slnx @@ -1,48 +1,512 @@ + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj index 81d3388ae9eb31..05f82aaaa19252 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.csproj @@ -12,6 +12,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/BackgroundService.cs b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/BackgroundService.cs index f2d1cea2fb25ad..7eb877cba2ec03 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/BackgroundService.cs +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/BackgroundService.cs @@ -69,7 +69,7 @@ public virtual async Task StopAsync(CancellationToken cancellationToken) } finally { -#if NET8_0_OR_GREATER +#if NET await _executeTask.WaitAsync(cancellationToken).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); #else // Wait until the task completes or the stop token triggers diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostAbortedException.cs b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostAbortedException.cs index 7b3184a882eeba..3ff9010b8cc21e 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostAbortedException.cs +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostAbortedException.cs @@ -11,7 +11,7 @@ namespace Microsoft.Extensions.Hosting [Serializable] public sealed class HostAbortedException : Exception { -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif private HostAbortedException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostingAbstractionsHostExtensions.cs b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostingAbstractionsHostExtensions.cs index f5ee438a2a74cf..a57792c8b02fc6 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostingAbstractionsHostExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/HostingAbstractionsHostExtensions.cs @@ -97,7 +97,7 @@ public static async Task WaitForShutdownAsync(this IHost host, CancellationToken }, applicationLifetime); -#if NET8_0_OR_GREATER +#if NET await Task.Delay(Timeout.Infinite, applicationLifetime.ApplicationStopping).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); #else var waitForStop = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj index e96791223b25f9..f63fbd4667b62e 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj @@ -15,6 +15,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Hosting.Systemd/Microsoft.Extensions.Hosting.Systemd.slnx b/src/libraries/Microsoft.Extensions.Hosting.Systemd/Microsoft.Extensions.Hosting.Systemd.slnx index 1bdd1cdd5cecb9..389710287d292d 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Systemd/Microsoft.Extensions.Hosting.Systemd.slnx +++ b/src/libraries/Microsoft.Extensions.Hosting.Systemd/Microsoft.Extensions.Hosting.Systemd.slnx @@ -1,111 +1,1330 @@ + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/Microsoft.Extensions.Hosting.WindowsServices.slnx b/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/Microsoft.Extensions.Hosting.WindowsServices.slnx index cadb034484cdf7..dfa11fe445876c 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/Microsoft.Extensions.Hosting.WindowsServices.slnx +++ b/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/Microsoft.Extensions.Hosting.WindowsServices.slnx @@ -1,113 +1,1346 @@ + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Hosting/Microsoft.Extensions.Hosting.slnx b/src/libraries/Microsoft.Extensions.Hosting/Microsoft.Extensions.Hosting.slnx index c29eaa1b2b2879..a5f4d0a740e969 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/Microsoft.Extensions.Hosting.slnx +++ b/src/libraries/Microsoft.Extensions.Hosting/Microsoft.Extensions.Hosting.slnx @@ -332,6 +332,14 @@ + + + + + + + + @@ -340,6 +348,14 @@ + + + + + + + + @@ -356,6 +372,14 @@ + + + + + + + + @@ -372,6 +396,14 @@ + + + + + + + + @@ -380,6 +412,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -388,6 +444,14 @@ + + + + + + + + @@ -396,6 +460,22 @@ + + + + + + + + + + + + + + + + @@ -404,6 +484,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -420,6 +572,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -436,6 +628,14 @@ + + + + + + + + @@ -444,6 +644,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -685,6 +909,14 @@ + + + + + + + + @@ -693,6 +925,14 @@ + + + + + + + + @@ -709,6 +949,14 @@ + + + + + + + + @@ -733,6 +981,14 @@ + + + + + + + + @@ -741,6 +997,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -749,6 +1029,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -757,6 +1069,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -773,6 +1157,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -789,6 +1213,14 @@ + + + + + + + + @@ -797,6 +1229,22 @@ + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Hosting/ref/Microsoft.Extensions.Hosting.csproj b/src/libraries/Microsoft.Extensions.Hosting/ref/Microsoft.Extensions.Hosting.csproj index 634b13f75c45d3..a465d075a1ce04 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/ref/Microsoft.Extensions.Hosting.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/ref/Microsoft.Extensions.Hosting.csproj @@ -11,6 +11,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/Internal/ConsoleLifetime.netcoreapp.cs b/src/libraries/Microsoft.Extensions.Hosting/src/Internal/ConsoleLifetime.netcoreapp.cs index 7fcccbeb8d411f..c5be9291ffd44c 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/Internal/ConsoleLifetime.netcoreapp.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/src/Internal/ConsoleLifetime.netcoreapp.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; using System.Runtime.InteropServices; +using System.Threading; namespace Microsoft.Extensions.Hosting.Internal { @@ -20,7 +21,7 @@ private partial void RegisterShutdownHandlers() Action handler = HandlePosixSignal; _sigIntRegistration = PosixSignalRegistration.Create(PosixSignal.SIGINT, handler); _sigQuitRegistration = PosixSignalRegistration.Create(PosixSignal.SIGQUIT, handler); - _sigTermRegistration = PosixSignalRegistration.Create(PosixSignal.SIGTERM, handler); + _sigTermRegistration = PosixSignalRegistration.Create(PosixSignal.SIGTERM, OperatingSystem.IsWindows() ? HandleWindowsShutdown : handler); } } @@ -32,6 +33,24 @@ private void HandlePosixSignal(PosixSignalContext context) ApplicationLifetime.StopApplication(); } + private void HandleWindowsShutdown(PosixSignalContext context) + { + // for SIGTERM on Windows we must block this thread until the application is finished + // otherwise the process will be killed immediately on return from this handler + + // don't allow Dispose to unregister handlers, since Windows has a lock that prevents the unregistration while this handler is running + // just leak these, since the process is exiting + _sigIntRegistration = null; + _sigQuitRegistration = null; + _sigTermRegistration = null; + + ApplicationLifetime.StopApplication(); + + // We could wait for a signal here, like Dispose as is done in non-netcoreapp case, but those inevitably could have user + // code that runs after them in the user's Main. Instead we just block this thread completely and let the main routine exit. + Thread.Sleep(HostOptions.ShutdownTimeout); + } + private partial void UnregisterShutdownHandlers() { _sigIntRegistration?.Dispose(); diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj index c173385b1a86ab..b5398e42c182f9 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj @@ -18,6 +18,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/ConsoleLifetimeExitTests.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/ConsoleLifetimeExitTests.cs index 0e54db40045e96..3298400036126a 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/ConsoleLifetimeExitTests.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/ConsoleLifetimeExitTests.cs @@ -2,6 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.IO; +using System.IO.Pipes; +using System.Reflection; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -18,14 +21,22 @@ public class ConsoleLifetimeExitTests /// and the rest of "main" gets executed. /// [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] - [PlatformSpecific(TestPlatforms.AnyUnix)] [InlineData(SIGTERM)] [InlineData(SIGINT)] [InlineData(SIGQUIT)] public async Task EnsureSignalContinuesMainMethod(int signal) { - using var remoteHandle = RemoteExecutor.Invoke(async () => + // simulate signals on Windows by using a pipe to communicate with the remote process + using var messagePipe = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable); + + using var remoteHandle = RemoteExecutor.Invoke(async (pipeHandleAsString) => { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // kick off a thread to simulate the signal on Windows + _ = Task.Run(() => SimulatePosixSignalWindows(pipeHandleAsString)); + } + await Host.CreateDefaultBuilder() .ConfigureServices((hostContext, services) => { @@ -40,7 +51,7 @@ await Host.CreateDefaultBuilder() Console.WriteLine("Run has completed"); return 123; - }, new RemoteInvokeOptions() { Start = false, ExpectedExitCode = 123 }); + }, messagePipe.GetClientHandleAsString(), new RemoteInvokeOptions() { Start = false, ExpectedExitCode = 123 }); remoteHandle.Process.StartInfo.RedirectStandardOutput = true; remoteHandle.Process.Start(); @@ -53,7 +64,16 @@ await Host.CreateDefaultBuilder() } // send the signal to the process - kill(remoteHandle.Process.Id, signal); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // on Windows, we use the pipe to signal the process + messagePipe.WriteByte((byte)signal); + } + else + { + // on Unix, we send the signal directly + kill(remoteHandle.Process.Id, signal); + } remoteHandle.Process.WaitForExit(); @@ -69,6 +89,69 @@ await Host.CreateDefaultBuilder() [DllImport("libc", SetLastError = true)] private static extern int kill(int pid, int sig); + + private const int CTRL_C_EVENT = 0; + private const int CTRL_BREAK_EVENT = 1; + private const int CTRL_CLOSE_EVENT = 2; + private const int CTRL_LOGOFF_EVENT = 5; + private const int CTRL_SHUTDOWN_EVENT = 6; + + private static unsafe void SimulatePosixSignalWindows(string pipeHandleAsString) + { + try + { + using var readPipe = new AnonymousPipeClientStream(PipeDirection.In, pipeHandleAsString); + + int signal = (int)readPipe.ReadByte(); + + int ctrlType = (int)signal switch + { + SIGINT => CTRL_C_EVENT, + SIGQUIT => CTRL_BREAK_EVENT, + SIGTERM => CTRL_SHUTDOWN_EVENT, + _ => throw new ArgumentOutOfRangeException(nameof(signal), "Unsupported signal") + }; + +#if NETFRAMEWORK + if (ctrlType == CTRL_C_EVENT || ctrlType == CTRL_BREAK_EVENT) + { + var handlerMethod = Type.GetType("System.Console, mscorlib")?.GetMethod("BreakEvent", BindingFlags.NonPublic | BindingFlags.Static); + Assert.NotNull(handlerMethod); + handlerMethod.Invoke(null, [ctrlType]); + } + else // CTRL_SHUTDOWN_EVENT + { + var handlerField = typeof(AppDomain).GetField("_processExit", BindingFlags.NonPublic | BindingFlags.Instance); + Assert.NotNull(handlerField); + EventHandler handler = (EventHandler)handlerField.GetValue(AppDomain.CurrentDomain); + Assert.NotNull(handler); + handler.Invoke(AppDomain.CurrentDomain, null); + } +#else + // get the System.Runtime.InteropServices.PosixSignalRegistration.HandlerRoutine private method + var handlerMethod = typeof(PosixSignalRegistration).GetMethod("HandlerRoutine", BindingFlags.NonPublic | BindingFlags.Static); + Assert.NotNull(handlerMethod); + + var handlerPtr = handlerMethod.MethodHandle.GetFunctionPointer(); + delegate* unmanaged handler = (delegate* unmanaged)handlerPtr; + + handler(ctrlType); + + if (signal == SIGTERM) + { + // on Windows the OS will kill the process immediately after this + Environment.FailFast("Simulating shutdown"); + } +#endif + } + catch (Exception ex) + { + // Exceptions on this thread will not be observed, nor will they cause the process to exit. + // Use failfast to ensure the process will exit without running any handlers. + Environment.FailFast(ex.ToString()); + } + } + private class EnsureSignalContinuesMainMethodWorker : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Microsoft.Extensions.Hosting.Unit.Tests.csproj b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Microsoft.Extensions.Hosting.Unit.Tests.csproj index 533ca595e67861..b2ac7ac6ca0aec 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Microsoft.Extensions.Hosting.Unit.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/Microsoft.Extensions.Hosting.Unit.Tests.csproj @@ -4,6 +4,7 @@ $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetFrameworkCurrent) true true + true true true diff --git a/src/libraries/Microsoft.Extensions.Http/Microsoft.Extensions.Http.slnx b/src/libraries/Microsoft.Extensions.Http/Microsoft.Extensions.Http.slnx index ae46e8e1fd54dc..80cc0b41dbff73 100644 --- a/src/libraries/Microsoft.Extensions.Http/Microsoft.Extensions.Http.slnx +++ b/src/libraries/Microsoft.Extensions.Http/Microsoft.Extensions.Http.slnx @@ -1,63 +1,618 @@ + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.csproj b/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.csproj index 152e6594be71ef..5be2c58324408a 100644 --- a/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.csproj +++ b/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.csproj @@ -10,6 +10,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Http/src/DefaultHttpMessageHandlerBuilder.cs b/src/libraries/Microsoft.Extensions.Http/src/DefaultHttpMessageHandlerBuilder.cs index f9466f30103fd0..9517cea528a5fa 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/DefaultHttpMessageHandlerBuilder.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/DefaultHttpMessageHandlerBuilder.cs @@ -13,7 +13,6 @@ namespace Microsoft.Extensions.Http { internal sealed class DefaultHttpMessageHandlerBuilder : HttpMessageHandlerBuilder { - private HttpMessageHandler? _primaryHandler; private string? _name; public DefaultHttpMessageHandlerBuilder(IServiceProvider services) @@ -34,8 +33,8 @@ public override string? Name public override HttpMessageHandler PrimaryHandler { - get => _primaryHandler ??= CreatePrimaryHandler(); - set => _primaryHandler = value; + get => field ??= CreatePrimaryHandler(); + set => field = value; } public override IList AdditionalHandlers { get; } = new List(); diff --git a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientFactoryServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientFactoryServiceCollectionExtensions.cs index 154d05b7254b6b..3ba6f5736fc8de 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientFactoryServiceCollectionExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientFactoryServiceCollectionExtensions.cs @@ -29,7 +29,7 @@ public static IServiceCollection AddHttpClient(this IServiceCollection services) services.AddLogging(); services.AddOptions(); -#if NET8_0_OR_GREATER +#if NET services.AddMetrics(); #endif @@ -51,7 +51,7 @@ public static IServiceCollection AddHttpClient(this IServiceCollection services) // Misc infrastructure // services.TryAddEnumerable(ServiceDescriptor.Singleton()); -#if NET8_0_OR_GREATER +#if NET services.TryAddEnumerable(ServiceDescriptor.Singleton()); #endif diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandlerBuilderFilter.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandlerBuilderFilter.cs index 845725f0994af3..b493d853238385 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandlerBuilderFilter.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandlerBuilderFilter.cs @@ -15,8 +15,7 @@ internal sealed class LoggingHttpMessageHandlerBuilderFilter : IHttpMessageHandl { // we want to prevent a circular depencency between ILoggerFactory and IHttpMessageHandlerBuilderFilter, in case // any of ILoggerProvider instances use IHttpClientFactory to send logs to an external server - private ILoggerFactory? _loggerFactory; - private ILoggerFactory LoggerFactory => _loggerFactory ??= _serviceProvider.GetRequiredService(); + private ILoggerFactory LoggerFactory => field ??= _serviceProvider.GetRequiredService(); private readonly IServiceProvider _serviceProvider; private readonly IOptionsMonitor _optionsMonitor; diff --git a/src/libraries/Microsoft.Extensions.Http/src/MetricsFactoryHttpMessageHandlerFilter.cs b/src/libraries/Microsoft.Extensions.Http/src/MetricsFactoryHttpMessageHandlerFilter.cs index 2a8645b09cb3f6..9b806062e5b932 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/MetricsFactoryHttpMessageHandlerFilter.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/MetricsFactoryHttpMessageHandlerFilter.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NET8_0_OR_GREATER +#if NET using System; using System.Diagnostics.Metrics; using System.Net.Http; diff --git a/src/libraries/Microsoft.Extensions.Http/src/Microsoft.Extensions.Http.csproj b/src/libraries/Microsoft.Extensions.Http/src/Microsoft.Extensions.Http.csproj index 0208f2994e2192..d83147612a7081 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Microsoft.Extensions.Http.csproj +++ b/src/libraries/Microsoft.Extensions.Http/src/Microsoft.Extensions.Http.csproj @@ -23,6 +23,7 @@ System.Net.Http.IHttpClientFactory + diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/FailedHttpRequestLoggingTests.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/FailedHttpRequestLoggingTests.cs index e1ab591fc472ef..2636a9424ae3fe 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/FailedHttpRequestLoggingTests.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/FailedHttpRequestLoggingTests.cs @@ -50,18 +50,18 @@ await Assert.ThrowsAsync(async () => var messages = sink.Writes.ToArray(); - var requestFailedMessage = Assert.Single(messages.Where(m => + var requestFailedMessage = Assert.Single(messages, m => { return m.EventId == EventIds.RequestFailed && m.LoggerName == InnerLoggerName; - })); - var pipelineFailedMessage = Assert.Single(messages.Where(m => + }); + var pipelineFailedMessage = Assert.Single(messages, m => { return m.EventId == EventIds.PipelineFailed && m.LoggerName == OuterLoggerName; - })); + }); } private const string ExceptionMessage = "Dummy error message"; diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs index 8952b020d5d4f4..cb62d0cd6b5f19 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs @@ -122,13 +122,13 @@ await RemoteExecutor.Invoke(static async (syncApiStr, scopeHandlerStr) => if (scopeHandler) { - var pipelineStartMessage = Assert.Single(sink.Writes.Where(m => m.EventId == EventIds.PipelineStart)); + var pipelineStartMessage = Assert.Single(sink.Writes, m => m.EventId == EventIds.PipelineStart); Assert.Equal($"HTTP GET {baseUri}?*", pipelineStartMessage.Scope.ToString()); Assert.Equal($"Start processing HTTP request GET {baseUri}?*", pipelineStartMessage.Message); } else { - var requestStartMessage = Assert.Single(sink.Writes.Where(m => m.EventId == EventIds.RequestStart)); + var requestStartMessage = Assert.Single(sink.Writes, m => m.EventId == EventIds.RequestStart); Assert.Equal($"Sending HTTP request GET {baseUri}?*", requestStartMessage.Message); } }, syncApi.ToString(), scopeHandler.ToString()).DisposeAsync(); @@ -181,13 +181,13 @@ await RemoteExecutor.Invoke(static async (syncApiStr, disableUriQueryRedactionSt _ = await client.SendAsync(request); } - var pipelineStartMessage = Assert.Single(sink.Writes.Where(m => + var pipelineStartMessage = Assert.Single(sink.Writes, m => m.EventId == EventIds.PipelineStart && - m.LoggerName == "System.Net.Http.HttpClient.test.LogicalHandler")); + m.LoggerName == "System.Net.Http.HttpClient.test.LogicalHandler"); - var requestStartMessage = Assert.Single(sink.Writes.Where(m => + var requestStartMessage = Assert.Single(sink.Writes, m => m.EventId == EventIds.RequestStart && - m.LoggerName == "System.Net.Http.HttpClient.test.ClientHandler")); + m.LoggerName == "System.Net.Http.HttpClient.test.ClientHandler"); string expectedUri = disableUriQueryRedaction ? destinationUri : $"{baseUri}?*"; diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/RedactedLogValueIntegrationTest.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/RedactedLogValueIntegrationTest.cs index e2c42c7bc0ecf4..fed0a3f8189000 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/RedactedLogValueIntegrationTest.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/RedactedLogValueIntegrationTest.cs @@ -56,12 +56,12 @@ public async Task RedactLoggedHeadersNotCalled_AllValuesAreRedactedBeforeLogging var messages = sink.Writes.ToArray(); - var message = Assert.Single(messages.Where(m => + var message = Assert.Single(messages, m => { return m.EventId == EventIds.RequestPipelineRequestHeader && m.LoggerName == OuterLoggerName; - })); + }); Assert.StartsWith(LineEndingsHelper.Normalize( """ Request Headers: @@ -70,12 +70,12 @@ public async Task RedactLoggedHeadersNotCalled_AllValuesAreRedactedBeforeLogging """), message.Message); - message = Assert.Single(messages.Where(m => + message = Assert.Single(messages, m => { return m.EventId == EventIds.RequestHeader && m.LoggerName == InnerLoggerName; - })); + }); Assert.StartsWith(LineEndingsHelper.Normalize( """ Request Headers: @@ -84,12 +84,12 @@ public async Task RedactLoggedHeadersNotCalled_AllValuesAreRedactedBeforeLogging """), message.Message); - message = Assert.Single(messages.Where(m => + message = Assert.Single(messages, m => { return m.EventId == EventIds.ResponseHeader && m.LoggerName == InnerLoggerName; - })); + }); Assert.StartsWith(LineEndingsHelper.Normalize( """ Response Headers: @@ -98,12 +98,12 @@ public async Task RedactLoggedHeadersNotCalled_AllValuesAreRedactedBeforeLogging """), message.Message); - message = Assert.Single(messages.Where(m => + message = Assert.Single(messages, m => { return m.EventId == EventIds.RequestPipelineResponseHeader && m.LoggerName == OuterLoggerName; - })); + }); Assert.StartsWith(LineEndingsHelper.Normalize( """ Response Headers: @@ -142,48 +142,48 @@ public async Task RedactHeaderValueWithHeaderList_ValueIsRedactedBeforeLogging() var messages = sink.Writes.ToArray(); - var message = Assert.Single(messages.Where(m => + var message = Assert.Single(messages, m => { return m.EventId == EventIds.RequestPipelineRequestHeader && m.LoggerName == OuterLoggerName; - })); + }); Assert.StartsWith(LineEndingsHelper.Normalize( @"Request Headers: Authorization: * Cache-Control: no-cache "), message.Message); - message = Assert.Single(messages.Where(m => + message = Assert.Single(messages, m => { return m.EventId == EventIds.RequestHeader && m.LoggerName == InnerLoggerName; - })); + }); Assert.StartsWith(LineEndingsHelper.Normalize( @"Request Headers: Authorization: * Cache-Control: no-cache "), message.Message); - message = Assert.Single(messages.Where(m => + message = Assert.Single(messages, m => { return m.EventId == EventIds.ResponseHeader && m.LoggerName == InnerLoggerName; - })); + }); Assert.StartsWith(LineEndingsHelper.Normalize( @"Response Headers: X-Sensitive: * Y-Non-Sensitive: innocuous value "), message.Message); - message = Assert.Single(messages.Where(m => + message = Assert.Single(messages, m => { return m.EventId == EventIds.RequestPipelineResponseHeader && m.LoggerName == OuterLoggerName; - })); + }); Assert.StartsWith(LineEndingsHelper.Normalize( @"Response Headers: X-Sensitive: * @@ -223,48 +223,48 @@ public async Task RedactHeaderValueWithPredicate_ValueIsRedactedBeforeLogging() var messages = sink.Writes.ToArray(); - var message = Assert.Single(messages.Where(m => + var message = Assert.Single(messages, m => { return m.EventId == EventIds.RequestPipelineRequestHeader && m.LoggerName == OuterLoggerName; - })); + }); Assert.StartsWith(LineEndingsHelper.Normalize( @"Request Headers: Authorization: * Cache-Control: no-cache "), message.Message); - message = Assert.Single(messages.Where(m => + message = Assert.Single(messages, m => { return m.EventId == EventIds.RequestHeader && m.LoggerName == InnerLoggerName; - })); + }); Assert.StartsWith(LineEndingsHelper.Normalize( @"Request Headers: Authorization: * Cache-Control: no-cache "), message.Message); - message = Assert.Single(messages.Where(m => + message = Assert.Single(messages, m => { return m.EventId == EventIds.ResponseHeader && m.LoggerName == InnerLoggerName; - })); + }); Assert.StartsWith(LineEndingsHelper.Normalize( @"Response Headers: X-Sensitive: * Y-Non-Sensitive: innocuous value "), message.Message); - message = Assert.Single(messages.Where(m => + message = Assert.Single(messages, m => { return m.EventId == EventIds.RequestPipelineResponseHeader && m.LoggerName == OuterLoggerName; - })); + }); Assert.StartsWith(LineEndingsHelper.Normalize( @"Response Headers: X-Sensitive: * diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/MeterFactoryIntegrationTest.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/MeterFactoryIntegrationTest.cs index a685fb7d8050ff..04cbaff60ed47a 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/MeterFactoryIntegrationTest.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/MeterFactoryIntegrationTest.cs @@ -9,7 +9,7 @@ namespace Microsoft.Extensions.Http { -#if NET8_0_OR_GREATER +#if NET public class MeterFactoryIntegrationTest { [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/Microsoft.Extensions.Logging.Abstractions.slnx b/src/libraries/Microsoft.Extensions.Logging.Abstractions/Microsoft.Extensions.Logging.Abstractions.slnx index 854cf72b5a2648..b319df3c89bc48 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/Microsoft.Extensions.Logging.Abstractions.slnx +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/Microsoft.Extensions.Logging.Abstractions.slnx @@ -1,41 +1,442 @@ + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs index ef55ac527209a7..48749b122b0099 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs @@ -177,7 +177,7 @@ private void GenStruct(LoggerMethod lm, string nestedIndentation) string formatMethodBegin = !lm.Message.Contains('{') ? "" : _hasStringCreate ? "string.Create(global::System.Globalization.CultureInfo.InvariantCulture, " : - "global::System.Diagnostics.CodeAnalysis.FormattableString.Invariant("; + "global::System.FormattableString.Invariant("; string formatMethodEnd = formatMethodBegin.Length > 0 ? ")" : ""; _builder.Append($@" diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs index cd1125477953f3..34f8935ac470cd 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs @@ -193,7 +193,7 @@ public void AddProvider(Microsoft.Extensions.Logging.ILoggerProvider provider) { public Microsoft.Extensions.Logging.ILogger CreateLogger(string name) { throw null; } public void Dispose() { } } - public partial class NullLoggerProvider : Microsoft.Extensions.Logging.ILoggerProvider, System.IDisposable + public sealed partial class NullLoggerProvider : Microsoft.Extensions.Logging.ILoggerProvider, System.IDisposable { internal NullLoggerProvider() { } public static Microsoft.Extensions.Logging.Abstractions.NullLoggerProvider Instance { get { throw null; } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs index 44951b8c84c931..0be51e2b067fff 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs @@ -17,7 +17,7 @@ internal sealed class LogValuesFormatter { private const string NullValue = "(null)"; private readonly List _valueNames = new List(); -#if NET8_0_OR_GREATER +#if NET private readonly CompositeFormat _format; #else private readonly string _format; @@ -44,7 +44,7 @@ public LogValuesFormatter(string format) { // No holes found. _format = -#if NET8_0_OR_GREATER +#if NET CompositeFormat.Parse(format); #else format; @@ -75,7 +75,7 @@ public LogValuesFormatter(string format) } _format = -#if NET8_0_OR_GREATER +#if NET CompositeFormat.Parse(vsb.ToString()); #else vsb.ToString(); @@ -176,14 +176,14 @@ internal string FormatWithOverwrite(object?[]? values) internal string Format() { -#if NET8_0_OR_GREATER +#if NET return _format.Format; #else return _format; #endif } -#if NET8_0_OR_GREATER +#if NET internal string Format(TArg0 arg0) { return diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullLoggerProvider.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullLoggerProvider.cs index 98c8624297100c..1ca696ef2a6430 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullLoggerProvider.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullLoggerProvider.cs @@ -6,7 +6,7 @@ namespace Microsoft.Extensions.Logging.Abstractions /// /// Provider for the . /// - public class NullLoggerProvider : ILoggerProvider + public sealed class NullLoggerProvider : ILoggerProvider { /// /// Returns an instance of . diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs index 5f8dc5f9ca20ed..96f163ff80f4e2 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs @@ -3,6 +3,7 @@ using System; using System.IO; +using System.Linq; using System.Reflection; using System.Threading.Tasks; using SourceGenerators.Tests; @@ -20,7 +21,7 @@ public async Task TestEmitter() string[] sources = Directory.GetFiles("TestClasses"); foreach (var src in sources) { - var testSourceCode = await File.ReadAllTextAsync(src).ConfigureAwait(false); + var testSourceCode = File.ReadAllText(src); var (d, r) = await RoslynTestUtils.RunGenerator( new LoggerMessageGenerator(), @@ -253,9 +254,9 @@ public void GenericTypeParameterAttributesAreRetained() private async Task VerifyAgainstBaselineUsingFile(string filename, string testSourceCode) { - string baseline = LineEndingsHelper.Normalize(await File.ReadAllTextAsync(Path.Combine("Baselines", filename)).ConfigureAwait(false)); + string baseline = LineEndingsHelper.Normalize(File.ReadAllText(Path.Combine("Baselines", filename))); string[] expectedLines = baseline.Replace("%VERSION%", typeof(LoggerMessageGenerator).Assembly.GetName().Version?.ToString()) - .Split(Environment.NewLine); + .Split([Environment.NewLine], StringSplitOptions.None); var (d, r) = await RoslynTestUtils.RunGenerator( new LoggerMessageGenerator(), @@ -265,6 +266,13 @@ private async Task VerifyAgainstBaselineUsingFile(string filename, string testSo Assert.Empty(d); Assert.Single(r); + if (PlatformDetection.IsNetFramework) + { + expectedLines = expectedLines.Select(line => line.Replace( + "string.Create(global::System.Globalization.CultureInfo.InvariantCulture, ", + "global::System.FormattableString.Invariant(")).ToArray(); + } + Assert.True(RoslynTestUtils.CompareLines(expectedLines, r[0].SourceText, out string errorMessage), errorMessage); } diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Microsoft.Extensions.Logging.Generators.targets b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Microsoft.Extensions.Logging.Generators.targets index dfc5b8e9ad7856..8e9141f655bd7b 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Microsoft.Extensions.Logging.Generators.targets +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Microsoft.Extensions.Logging.Generators.targets @@ -1,11 +1,11 @@ - $(NetCoreAppCurrent) + $(NetCoreAppCurrent);$(NetFrameworkCurrent) true true enable - true + true $(NoWarn);NETSDK1206 @@ -16,10 +16,13 @@ Link="SourceGenerators\RoslynTestUtils.cs" /> + + + + - diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/Microsoft.Extensions.Logging.Configuration.slnx b/src/libraries/Microsoft.Extensions.Logging.Configuration/Microsoft.Extensions.Logging.Configuration.slnx index 6302f892ca016d..3bd066fb621f59 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Configuration/Microsoft.Extensions.Logging.Configuration.slnx +++ b/src/libraries/Microsoft.Extensions.Logging.Configuration/Microsoft.Extensions.Logging.Configuration.slnx @@ -1,55 +1,568 @@ + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/ref/Microsoft.Extensions.Logging.Configuration.cs b/src/libraries/Microsoft.Extensions.Logging.Configuration/ref/Microsoft.Extensions.Logging.Configuration.cs index bfa54bb28b8834..1c412900b11190 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Configuration/ref/Microsoft.Extensions.Logging.Configuration.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Configuration/ref/Microsoft.Extensions.Logging.Configuration.cs @@ -25,7 +25,7 @@ public static partial class LoggerProviderOptions { [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding TOptions to configuration values may require generating dynamic code at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("TOptions's dependent types may have their members trimmed. Ensure all required members are preserved.")] - public static void RegisterProviderOptions<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] TOptions, TProvider>(Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TOptions : class { } + public static void RegisterProviderOptions(Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TOptions : class { } } public partial class LoggerProviderOptionsChangeTokenSource : Microsoft.Extensions.Options.ConfigurationChangeTokenSource { diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/ref/Microsoft.Extensions.Logging.Configuration.csproj b/src/libraries/Microsoft.Extensions.Logging.Configuration/ref/Microsoft.Extensions.Logging.Configuration.csproj index 49ac44f12e2871..b73179d355ddeb 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Configuration/ref/Microsoft.Extensions.Logging.Configuration.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Configuration/ref/Microsoft.Extensions.Logging.Configuration.csproj @@ -13,6 +13,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/CompatibilitySuppressions.xml b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/CompatibilitySuppressions.xml new file mode 100644 index 00000000000000..30a50abf1bdb92 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/CompatibilitySuppressions.xml @@ -0,0 +1,18 @@ + + + + + CP0014 + M:Microsoft.Extensions.Logging.Configuration.LoggerProviderOptions.RegisterProviderOptions``2(Microsoft.Extensions.DependencyInjection.IServiceCollection)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Logging.Configuration.dll + lib/net8.0/Microsoft.Extensions.Logging.Configuration.dll + true + + + CP0014 + M:Microsoft.Extensions.Logging.Configuration.LoggerProviderOptions.RegisterProviderOptions``2(Microsoft.Extensions.DependencyInjection.IServiceCollection)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Logging.Configuration.dll + lib/net9.0/Microsoft.Extensions.Logging.Configuration.dll + true + + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/LoggerProviderConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/LoggerProviderConfigurationExtensions.cs index 1a283baf00623a..40150073947496 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/LoggerProviderConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/LoggerProviderConfigurationExtensions.cs @@ -24,7 +24,7 @@ public static class LoggerProviderOptions /// The provider class. [RequiresDynamicCode(RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(TrimmingRequiresUnreferencedCodeMessage)] - public static void RegisterProviderOptions<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions, TProvider>(IServiceCollection services) where TOptions : class + public static void RegisterProviderOptions(IServiceCollection services) where TOptions : class { services.TryAddEnumerable(ServiceDescriptor.Singleton, LoggerProviderConfigureOptions>()); services.TryAddEnumerable(ServiceDescriptor.Singleton, LoggerProviderOptionsChangeTokenSource>()); diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/LoggerProviderConfigureOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/LoggerProviderConfigureOptions.cs index 2e474ae68e4229..960c6437679c36 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/LoggerProviderConfigureOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/LoggerProviderConfigureOptions.cs @@ -9,7 +9,7 @@ namespace Microsoft.Extensions.Logging.Configuration /// /// Loads settings for into type. /// - internal sealed class LoggerProviderConfigureOptions<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions, TProvider> : ConfigureFromConfigurationOptions where TOptions : class + internal sealed class LoggerProviderConfigureOptions : ConfigureFromConfigurationOptions where TOptions : class { [RequiresDynamicCode(LoggerProviderOptions.RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(LoggerProviderOptions.TrimmingRequiresUnreferencedCodeMessage)] diff --git a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj index b8f2e7471cb685..14099251ab4b9a 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Configuration/src/Microsoft.Extensions.Logging.Configuration.csproj @@ -21,6 +21,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/Microsoft.Extensions.Logging.Console.slnx b/src/libraries/Microsoft.Extensions.Logging.Console/Microsoft.Extensions.Logging.Console.slnx index c7914f42c6f4e5..9fef2affb67676 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/Microsoft.Extensions.Logging.Console.slnx +++ b/src/libraries/Microsoft.Extensions.Logging.Console/Microsoft.Extensions.Logging.Console.slnx @@ -1,74 +1,986 @@ + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index ebdce4441e2861..76c9169cf61fa6 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -37,10 +37,10 @@ public static partial class ConsoleLoggerExtensions public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding TOptions to configuration values may require generating dynamic code at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("TOptions's dependent types may have their members trimmed. Ensure all required members are preserved.")] - public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleFormatter<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TFormatter, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] TOptions>(this Microsoft.Extensions.Logging.ILoggingBuilder builder) where TFormatter : Microsoft.Extensions.Logging.Console.ConsoleFormatter where TOptions : Microsoft.Extensions.Logging.Console.ConsoleFormatterOptions { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleFormatter<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TFormatter, TOptions>(this Microsoft.Extensions.Logging.ILoggingBuilder builder) where TFormatter : Microsoft.Extensions.Logging.Console.ConsoleFormatter where TOptions : Microsoft.Extensions.Logging.Console.ConsoleFormatterOptions { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding TOptions to configuration values may require generating dynamic code at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("TOptions's dependent types may have their members trimmed. Ensure all required members are preserved.")] - public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleFormatter<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TFormatter, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] TOptions>(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) where TFormatter : Microsoft.Extensions.Logging.Console.ConsoleFormatter where TOptions : Microsoft.Extensions.Logging.Console.ConsoleFormatterOptions { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleFormatter<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TFormatter, TOptions>(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) where TFormatter : Microsoft.Extensions.Logging.Console.ConsoleFormatter where TOptions : Microsoft.Extensions.Logging.Console.ConsoleFormatterOptions { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddJsonConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddJsonConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddSimpleConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder) { throw null; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj index f0353dbde2288e..b3041036dc657b 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj @@ -15,6 +15,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/CompatibilitySuppressions.xml b/src/libraries/Microsoft.Extensions.Logging.Console/src/CompatibilitySuppressions.xml new file mode 100644 index 00000000000000..478fe7e7af368f --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/CompatibilitySuppressions.xml @@ -0,0 +1,32 @@ + + + + + CP0014 + M:Microsoft.Extensions.Logging.ConsoleLoggerExtensions.AddConsoleFormatter``2(Microsoft.Extensions.Logging.ILoggingBuilder,System.Action{``1})<1>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Logging.Console.dll + lib/net8.0/Microsoft.Extensions.Logging.Console.dll + true + + + CP0014 + M:Microsoft.Extensions.Logging.ConsoleLoggerExtensions.AddConsoleFormatter``2(Microsoft.Extensions.Logging.ILoggingBuilder)<1>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Logging.Console.dll + lib/net8.0/Microsoft.Extensions.Logging.Console.dll + true + + + CP0014 + M:Microsoft.Extensions.Logging.ConsoleLoggerExtensions.AddConsoleFormatter``2(Microsoft.Extensions.Logging.ILoggingBuilder,System.Action{``1})<1>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Logging.Console.dll + lib/net9.0/Microsoft.Extensions.Logging.Console.dll + true + + + CP0014 + M:Microsoft.Extensions.Logging.ConsoleLoggerExtensions.AddConsoleFormatter``2(Microsoft.Extensions.Logging.ILoggingBuilder)<1>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Logging.Console.dll + lib/net9.0/Microsoft.Extensions.Logging.Console.dll + true + + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerExtensions.cs index 2d9525020a76c5..43697320394ad9 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerExtensions.cs @@ -128,7 +128,7 @@ private static ILoggingBuilder AddFormatterWithName(this ILoggingBuilder builder /// The to use. [RequiresDynamicCode(RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(TrimmingRequiresUnreferencedCodeMessage)] - public static ILoggingBuilder AddConsoleFormatter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFormatter, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions>(this ILoggingBuilder builder) + public static ILoggingBuilder AddConsoleFormatter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFormatter, TOptions>(this ILoggingBuilder builder) where TOptions : ConsoleFormatterOptions where TFormatter : ConsoleFormatter { @@ -142,7 +142,7 @@ private static ILoggingBuilder AddFormatterWithName(this ILoggingBuilder builder /// A delegate to configure options 'TOptions' for custom formatter 'TFormatter'. [RequiresDynamicCode(RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(TrimmingRequiresUnreferencedCodeMessage)] - public static ILoggingBuilder AddConsoleFormatter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFormatter, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions>(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder AddConsoleFormatter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFormatter, TOptions>(this ILoggingBuilder builder, Action configure) where TOptions : ConsoleFormatterOptions where TFormatter : ConsoleFormatter { @@ -174,7 +174,7 @@ internal static IConfiguration GetFormatterOptionsSection(this ILoggerProviderCo } [UnsupportedOSPlatform("browser")] - internal sealed class ConsoleLoggerFormatterConfigureOptions : ConfigureFromConfigurationOptions + internal sealed class ConsoleLoggerFormatterConfigureOptions : ConfigureFromConfigurationOptions where TOptions : ConsoleFormatterOptions where TFormatter : ConsoleFormatter { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs index 967fc641d15478..5e4a43846e842a 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs @@ -89,12 +89,12 @@ private void WriteInternal(IExternalScopeProvider? scopeProvider, TextWriter tex writer.WriteString("Message", stateMessage); } if (stateProperties != null) + { + foreach (KeyValuePair item in stateProperties) { - foreach (KeyValuePair item in stateProperties) - { - WriteItem(writer, item); - } + WriteItem(writer, item); } + } writer.WriteEndObject(); } WriteScopeInformation(writer, scopeProvider); diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj index 5727e4e667586c..df94b82a0df8fc 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj @@ -37,6 +37,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerTest.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerTest.cs index 6747e98ebf322f..f48a4a0e1176ab 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerTest.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerTest.cs @@ -239,7 +239,7 @@ public void DoesNotLog_NewLine_WhenNoExceptionIsProvided() [InlineData(null, 1)] [InlineData("missingFormatter", 0)] [InlineData("missingFormatter", 1)] - public void Options_FormatterNameNull_UsesDeprecatedProperties(string formatterName, int formatNumber) + public void Options_FormatterNameNull_UsesDeprecatedProperties(string? formatterName, int formatNumber) { // Arrange ConsoleLoggerFormat format = (ConsoleLoggerFormat)formatNumber; diff --git a/src/libraries/Microsoft.Extensions.Logging.Debug/Microsoft.Extensions.Logging.Debug.slnx b/src/libraries/Microsoft.Extensions.Logging.Debug/Microsoft.Extensions.Logging.Debug.slnx index 9839b17e06fbbd..1c737642e0bcd9 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Debug/Microsoft.Extensions.Logging.Debug.slnx +++ b/src/libraries/Microsoft.Extensions.Logging.Debug/Microsoft.Extensions.Logging.Debug.slnx @@ -1,46 +1,496 @@ + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.EventLog/Microsoft.Extensions.Logging.EventLog.slnx b/src/libraries/Microsoft.Extensions.Logging.EventLog/Microsoft.Extensions.Logging.EventLog.slnx index 00daac9bd18469..1c532b6831ee76 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventLog/Microsoft.Extensions.Logging.EventLog.slnx +++ b/src/libraries/Microsoft.Extensions.Logging.EventLog/Microsoft.Extensions.Logging.EventLog.slnx @@ -1,51 +1,616 @@ + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.EventLog/src/EventLogSettings.cs b/src/libraries/Microsoft.Extensions.Logging.EventLog/src/EventLogSettings.cs index 35be4111fbd586..c361d41d6ec64b 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventLog/src/EventLogSettings.cs +++ b/src/libraries/Microsoft.Extensions.Logging.EventLog/src/EventLogSettings.cs @@ -10,8 +10,6 @@ namespace Microsoft.Extensions.Logging.EventLog /// public class EventLogSettings { - private IEventLog? _eventLog; - /// /// Gets or sets the name of the event log. If or not specified, "Application" is the default. /// @@ -34,10 +32,10 @@ public class EventLogSettings internal IEventLog EventLog { - get => _eventLog ??= CreateDefaultEventLog(); + get => field ??= CreateDefaultEventLog(); // For unit testing purposes only. - set => _eventLog = value; + set => field = value; } private WindowsEventLog CreateDefaultEventLog() diff --git a/src/libraries/Microsoft.Extensions.Logging.EventSource/Microsoft.Extensions.Logging.EventSource.slnx b/src/libraries/Microsoft.Extensions.Logging.EventSource/Microsoft.Extensions.Logging.EventSource.slnx index 9e945d0d948a71..399a05c4126efe 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventSource/Microsoft.Extensions.Logging.EventSource.slnx +++ b/src/libraries/Microsoft.Extensions.Logging.EventSource/Microsoft.Extensions.Logging.EventSource.slnx @@ -1,63 +1,898 @@ + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging.TraceSource/Microsoft.Extensions.Logging.TraceSource.slnx b/src/libraries/Microsoft.Extensions.Logging.TraceSource/Microsoft.Extensions.Logging.TraceSource.slnx index 20b46a62bc2364..c4f9e29f5e0fd0 100644 --- a/src/libraries/Microsoft.Extensions.Logging.TraceSource/Microsoft.Extensions.Logging.TraceSource.slnx +++ b/src/libraries/Microsoft.Extensions.Logging.TraceSource/Microsoft.Extensions.Logging.TraceSource.slnx @@ -1,46 +1,496 @@ + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging/Microsoft.Extensions.Logging.slnx b/src/libraries/Microsoft.Extensions.Logging/Microsoft.Extensions.Logging.slnx index e00eefcf1ef527..5f679216db6d63 100644 --- a/src/libraries/Microsoft.Extensions.Logging/Microsoft.Extensions.Logging.slnx +++ b/src/libraries/Microsoft.Extensions.Logging/Microsoft.Extensions.Logging.slnx @@ -1,96 +1,1210 @@ + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Logging/src/LoggerFactory.cs b/src/libraries/Microsoft.Extensions.Logging/src/LoggerFactory.cs index 3ff5e4714613ab..47153ed10d401c 100644 --- a/src/libraries/Microsoft.Extensions.Logging/src/LoggerFactory.cs +++ b/src/libraries/Microsoft.Extensions.Logging/src/LoggerFactory.cs @@ -8,6 +8,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; namespace Microsoft.Extensions.Logging @@ -211,12 +212,19 @@ private void AddProviderRegistration(ILoggerProvider provider, bool dispose) private LoggerInformation[] CreateLoggers(string categoryName) { - var loggers = new LoggerInformation[_providerRegistrations.Count]; + var loggers = new List(_providerRegistrations.Count); for (int i = 0; i < _providerRegistrations.Count; i++) { - loggers[i] = new LoggerInformation(_providerRegistrations[i].Provider, categoryName); + var loggerInformation = new LoggerInformation(_providerRegistrations[i].Provider, categoryName); + + // We do not need to check for NullLogger.Instance as no provider would reasonably return it (the handling is at + // outer loggers level, not inner level loggers in Logger/LoggerProvider). + if (loggerInformation.Logger != NullLogger.Instance) + { + loggers.Add(loggerInformation); + } } - return loggers; + return loggers.ToArray(); } private (MessageLogger[] MessageLoggers, ScopeLogger[]? ScopeLoggers) ApplyFilters(LoggerInformation[] loggers) diff --git a/src/libraries/Microsoft.Extensions.Logging/tests/Common/FormattedLogValuesTest.cs b/src/libraries/Microsoft.Extensions.Logging/tests/Common/FormattedLogValuesTest.cs index c20ede7d712b97..4f5b3a8af4746b 100644 --- a/src/libraries/Microsoft.Extensions.Logging/tests/Common/FormattedLogValuesTest.cs +++ b/src/libraries/Microsoft.Extensions.Logging/tests/Common/FormattedLogValuesTest.cs @@ -19,7 +19,7 @@ public class FormattedLogValuesTest [InlineData("0064", "{Hex:X4}", new object[] { 100 })] [InlineData("8,765", "{Number:#,#}", new object[] { 8765.4321 })] [InlineData(" 8,765", "{Number,6:#,#}", new object[] { 8765.4321 })] - public void LogValues_With_Basic_Types(string expected, string format, object[] args) + public void LogValues_With_Basic_Types(string expected, string format, object[]? args) { var logValues = new FormattedLogValues(format, args); Assert.Equal(expected, logValues.ToString()); @@ -33,7 +33,7 @@ public void LogValues_With_Basic_Types(string expected, string format, object[] [InlineData("[null]", null, new object[] { })] [InlineData("[null]", null, new object[] { null })] [InlineData("[null]", null, new object[] { 1 })] - public void Log_NullFormat(string expected, string format, object[] args) + public void Log_NullFormat(string expected, string? format, object[]? args) { var logValues = new FormattedLogValues(format, args); Assert.Equal(expected, logValues.ToString()); @@ -42,7 +42,7 @@ public void Log_NullFormat(string expected, string format, object[] args) [Theory] [InlineData("(null), (null) : (null)", "{0} : {1}", new object[] { new object[] { null, null }, null })] [InlineData("(null)", "{0}", new object[] { null })] - public void LogValues_WithNulls(string expected, string format, object[] args) + public void LogValues_WithNulls(string expected, string format, object[]? args) { var logValues = new FormattedLogValues(format, args); Assert.Equal(expected, logValues.ToString()); @@ -70,7 +70,7 @@ public void LogValues_With_DateTime(string expected, string format) "{0} {1} '{{}}' '{{' '{{:}}' '{{,:}}' {{,}}- test string", new object[] { "arg1", "arg2" })] [InlineData("{prefix{arg1}suffix}", "{{prefix{{{Argument}}}suffix}}", new object[] { "arg1" })] - public void LogValues_With_Escaped_Braces(string expected, string format, object[] args) + public void LogValues_With_Escaped_Braces(string expected, string format, object[]? args) { var logValues = args == null ? new FormattedLogValues(format) : diff --git a/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerFactoryTest.cs b/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerFactoryTest.cs index 48b9eb2174f6cf..188dd00d88317a 100644 --- a/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerFactoryTest.cs +++ b/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggerFactoryTest.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging.Abstractions; using Moq; using Xunit; @@ -20,7 +21,7 @@ public void AddProvider_ThrowsAfterDisposed() var factory = new LoggerFactory(); factory.Dispose(); - Assert.Throws(() => ((ILoggerFactory) factory).AddProvider(CreateProvider())); + Assert.Throws(() => ((ILoggerFactory)factory).AddProvider(CreateProvider())); } [Fact] @@ -214,7 +215,7 @@ public void TestActivityIds(ActivityTrackingOptions options) public void TestInvalidActivityTrackingOptions() { Assert.Throws(() => - LoggerFactory.Create(builder => { builder.Configure(o => o.ActivityTrackingOptions = (ActivityTrackingOptions) 0xFF00);}) + LoggerFactory.Create(builder => { builder.Configure(o => o.ActivityTrackingOptions = (ActivityTrackingOptions)0xFF00); }) ); } @@ -434,7 +435,7 @@ public void BaggageFormattedOutput() } activity.Stop(); - string [] loggerOutput = new string[] + string[] loggerOutput = new string[] { $"Inside Scope Info!", $"[TraceId, {activity.GetTraceId()}]", @@ -451,7 +452,7 @@ public void BaggageFormattedOutput() public void CallsSetScopeProvider_OnSupportedProviders() { var loggerProvider = new ExternalScopeLoggerProvider(); - var loggerFactory = new LoggerFactory(new [] { loggerProvider }); + var loggerFactory = new LoggerFactory(new[] { loggerProvider }); var logger = loggerFactory.CreateLogger("Logger"); @@ -480,7 +481,7 @@ public void CallsSetScopeProvider_OnSupportedProviders() public void BeginScope_ReturnsExternalSourceTokenDirectly() { var loggerProvider = new ExternalScopeLoggerProvider(); - var loggerFactory = new LoggerFactory(new [] { loggerProvider }); + var loggerFactory = new LoggerFactory(new[] { loggerProvider }); var logger = loggerFactory.CreateLogger("Logger"); @@ -503,7 +504,7 @@ public void BeginScope_ReturnsCompositeToken_ForMultipleLoggers() { var loggerProvider = new ExternalScopeLoggerProvider(); var loggerProvider2 = new InternalScopeLoggerProvider(); - var loggerFactory = new LoggerFactory(new ILoggerProvider[] { loggerProvider, loggerProvider2}); + var loggerFactory = new LoggerFactory(new ILoggerProvider[] { loggerProvider, loggerProvider2 }); var logger = loggerFactory.CreateLogger("Logger"); @@ -543,12 +544,57 @@ public void CreateDisposeDisposesInnerServiceProvider() var provider = new Mock(); provider.Setup(p => p.Dispose()).Callback(() => disposed = true); - var factory = LoggerFactory.Create(builder => builder.Services.AddSingleton(_=> provider.Object)); + var factory = LoggerFactory.Create(builder => builder.Services.AddSingleton(_ => provider.Object)); factory.Dispose(); Assert.True(disposed); } + // Moq heavily utilizes RefEmit, which does not work on most aot workloads + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsReflectionEmitSupported))] + public void TestCreateLoggers_NullLoggerIsIgnoredWhenReturnedByProvider() + { + // We test this via checking if Scope optimisaion (ie not return scope wrapper but the + // returned scope directly only one logger) is applied. + var nullProvider = new Mock(); + nullProvider.Setup(p => p.CreateLogger(It.IsAny())).Returns(NullLogger.Instance); + + var validProvider = new CustomScopeLoggerProvider(); + + var factory = LoggerFactory.Create(builder => + { + builder.AddProvider(nullProvider.Object); + builder.AddProvider(validProvider); + }); + var logger = factory.CreateLogger("TestLogger"); + + var scope = logger.BeginScope("TestScope"); + Assert.IsType(scope); + + logger.LogInformation("Test message"); + Assert.Equal(1, validProvider.LogText.Count); + } + + private class CustomScopeLoggerProvider : ILoggerProvider, ILogger + { + public List LogText { get; set; } = new List(); + + public void Dispose() { } + + public ILogger CreateLogger(string categoryName) => this; + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) => LogText.Add(formatter(state, exception)); + + public bool IsEnabled(LogLevel logLevel) => true; + + public IDisposable BeginScope(TState state) => new CustomScope(); + + internal class CustomScope : IDisposable + { + public void Dispose() { } + } + } + private class InternalScopeLoggerProvider : ILoggerProvider, ILogger { private IExternalScopeProvider _scopeProvider = new LoggerExternalScopeProvider(); diff --git a/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggingServiceCollectionExtensionsTest.cs b/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggingServiceCollectionExtensionsTest.cs index a9369d6e21bdab..bba8105e69a8a3 100644 --- a/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggingServiceCollectionExtensionsTest.cs +++ b/src/libraries/Microsoft.Extensions.Logging/tests/Common/LoggingServiceCollectionExtensionsTest.cs @@ -55,7 +55,7 @@ public void ClearProviders_RemovesAllProvidersFromServiceCollection() services.AddLogging(builder => builder.ClearProviders()); - Assert.Empty(services.Where(desctriptor => desctriptor.ServiceType == typeof(ILoggerProvider))); + Assert.DoesNotContain(services, descriptor => descriptor.ServiceType == typeof(ILoggerProvider)); } } } diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.cs index 154143a512d562..73c8ab69731d1e 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.cs @@ -10,28 +10,28 @@ public static partial class OptionsBuilderConfigurationExtensions { [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding strongly typed objects to configuration values may require generating dynamic code at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("TOptions's dependent types may have their members trimmed. Ensure all required members are preserved.")] - public static Microsoft.Extensions.Options.OptionsBuilder BindConfiguration<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] TOptions>(this Microsoft.Extensions.Options.OptionsBuilder optionsBuilder, string configSectionPath, System.Action? configureBinder = null) where TOptions : class { throw null; } + public static Microsoft.Extensions.Options.OptionsBuilder BindConfiguration(this Microsoft.Extensions.Options.OptionsBuilder optionsBuilder, string configSectionPath, System.Action? configureBinder = null) where TOptions : class { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding strongly typed objects to configuration values may require generating dynamic code at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("TOptions's dependent types may have their members trimmed. Ensure all required members are preserved.")] - public static Microsoft.Extensions.Options.OptionsBuilder Bind<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] TOptions>(this Microsoft.Extensions.Options.OptionsBuilder optionsBuilder, Microsoft.Extensions.Configuration.IConfiguration config) where TOptions : class { throw null; } + public static Microsoft.Extensions.Options.OptionsBuilder Bind(this Microsoft.Extensions.Options.OptionsBuilder optionsBuilder, Microsoft.Extensions.Configuration.IConfiguration config) where TOptions : class { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding strongly typed objects to configuration values may require generating dynamic code at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("TOptions's dependent types may have their members trimmed. Ensure all required members are preserved.")] - public static Microsoft.Extensions.Options.OptionsBuilder Bind<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] TOptions>(this Microsoft.Extensions.Options.OptionsBuilder optionsBuilder, Microsoft.Extensions.Configuration.IConfiguration config, System.Action? configureBinder) where TOptions : class { throw null; } + public static Microsoft.Extensions.Options.OptionsBuilder Bind(this Microsoft.Extensions.Options.OptionsBuilder optionsBuilder, Microsoft.Extensions.Configuration.IConfiguration config, System.Action? configureBinder) where TOptions : class { throw null; } } public static partial class OptionsConfigurationServiceCollectionExtensions { [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding strongly typed objects to configuration values may require generating dynamic code at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("TOptions's dependent types may have their members trimmed. Ensure all required members are preserved.")] - public static Microsoft.Extensions.DependencyInjection.IServiceCollection Configure<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.Configuration.IConfiguration config) where TOptions : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.Configuration.IConfiguration config) where TOptions : class { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding strongly typed objects to configuration values may require generating dynamic code at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("TOptions's dependent types may have their members trimmed. Ensure all required members are preserved.")] - public static Microsoft.Extensions.DependencyInjection.IServiceCollection Configure<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.Configuration.IConfiguration config, System.Action? configureBinder) where TOptions : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.Configuration.IConfiguration config, System.Action? configureBinder) where TOptions : class { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding strongly typed objects to configuration values may require generating dynamic code at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("TOptions's dependent types may have their members trimmed. Ensure all required members are preserved.")] - public static Microsoft.Extensions.DependencyInjection.IServiceCollection Configure<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name, Microsoft.Extensions.Configuration.IConfiguration config) where TOptions : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name, Microsoft.Extensions.Configuration.IConfiguration config) where TOptions : class { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding strongly typed objects to configuration values may require generating dynamic code at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("TOptions's dependent types may have their members trimmed. Ensure all required members are preserved.")] - public static Microsoft.Extensions.DependencyInjection.IServiceCollection Configure<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name, Microsoft.Extensions.Configuration.IConfiguration config, System.Action? configureBinder) where TOptions : class { throw null; } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name, Microsoft.Extensions.Configuration.IConfiguration config, System.Action? configureBinder) where TOptions : class { throw null; } } } namespace Microsoft.Extensions.Options @@ -43,13 +43,13 @@ public ConfigurationChangeTokenSource(string? name, Microsoft.Extensions.Configu public string Name { get { throw null; } } public Microsoft.Extensions.Primitives.IChangeToken GetChangeToken() { throw null; } } - public partial class ConfigureFromConfigurationOptions<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] TOptions> : Microsoft.Extensions.Options.ConfigureOptions where TOptions : class + public partial class ConfigureFromConfigurationOptions : Microsoft.Extensions.Options.ConfigureOptions where TOptions : class { [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding strongly typed objects to configuration values may require generating dynamic code at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("TOptions's dependent types may have their members trimmed. Ensure all required members are preserved.")] public ConfigureFromConfigurationOptions(Microsoft.Extensions.Configuration.IConfiguration config) : base (default(System.Action)) { } } - public partial class NamedConfigureFromConfigurationOptions<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] TOptions> : Microsoft.Extensions.Options.ConfigureNamedOptions where TOptions : class + public partial class NamedConfigureFromConfigurationOptions : Microsoft.Extensions.Options.ConfigureNamedOptions where TOptions : class { [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding strongly typed objects to configuration values may require generating dynamic code at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("TOptions's dependent types may have their members trimmed. Ensure all required members are preserved.")] diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.csproj b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.csproj index 67ab4702f5b137..a5b7d1a8d81bc9 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.csproj +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/ref/Microsoft.Extensions.Options.ConfigurationExtensions.csproj @@ -13,6 +13,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/CompatibilitySuppressions.xml b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/CompatibilitySuppressions.xml new file mode 100644 index 00000000000000..381533647c1e1b --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/CompatibilitySuppressions.xml @@ -0,0 +1,130 @@ + + + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsBuilderConfigurationExtensions.Bind``1(Microsoft.Extensions.Options.OptionsBuilder{``0},Microsoft.Extensions.Configuration.IConfiguration,System.Action{Microsoft.Extensions.Configuration.BinderOptions})<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsBuilderConfigurationExtensions.Bind``1(Microsoft.Extensions.Options.OptionsBuilder{``0},Microsoft.Extensions.Configuration.IConfiguration)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsBuilderConfigurationExtensions.BindConfiguration``1(Microsoft.Extensions.Options.OptionsBuilder{``0},System.String,System.Action{Microsoft.Extensions.Configuration.BinderOptions})<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure``1(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Configuration.IConfiguration,System.Action{Microsoft.Extensions.Configuration.BinderOptions})<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure``1(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Configuration.IConfiguration)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure``1(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.String,Microsoft.Extensions.Configuration.IConfiguration,System.Action{Microsoft.Extensions.Configuration.BinderOptions})<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure``1(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.String,Microsoft.Extensions.Configuration.IConfiguration)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + T:Microsoft.Extensions.Options.ConfigureFromConfigurationOptions`1<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + T:Microsoft.Extensions.Options.NamedConfigureFromConfigurationOptions`1<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsBuilderConfigurationExtensions.Bind``1(Microsoft.Extensions.Options.OptionsBuilder{``0},Microsoft.Extensions.Configuration.IConfiguration,System.Action{Microsoft.Extensions.Configuration.BinderOptions})<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsBuilderConfigurationExtensions.Bind``1(Microsoft.Extensions.Options.OptionsBuilder{``0},Microsoft.Extensions.Configuration.IConfiguration)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsBuilderConfigurationExtensions.BindConfiguration``1(Microsoft.Extensions.Options.OptionsBuilder{``0},System.String,System.Action{Microsoft.Extensions.Configuration.BinderOptions})<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure``1(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Configuration.IConfiguration,System.Action{Microsoft.Extensions.Configuration.BinderOptions})<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure``1(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Configuration.IConfiguration)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure``1(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.String,Microsoft.Extensions.Configuration.IConfiguration,System.Action{Microsoft.Extensions.Configuration.BinderOptions})<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + M:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure``1(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.String,Microsoft.Extensions.Configuration.IConfiguration)<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + T:Microsoft.Extensions.Options.ConfigureFromConfigurationOptions`1<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + + CP0014 + T:Microsoft.Extensions.Options.NamedConfigureFromConfigurationOptions`1<0>:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll + true + + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/ConfigureFromConfigurationOptions.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/ConfigureFromConfigurationOptions.cs index d85a8ce9b555b2..54ad860ea28e26 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/ConfigureFromConfigurationOptions.cs +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/ConfigureFromConfigurationOptions.cs @@ -14,7 +14,7 @@ namespace Microsoft.Extensions.Options /// Configures an option instance by using against an . /// /// The type of options to bind. - public class ConfigureFromConfigurationOptions<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions> : ConfigureOptions + public class ConfigureFromConfigurationOptions : ConfigureOptions where TOptions : class { /// diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj index 3231765bade214..15ceb28034fccd 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj @@ -13,6 +13,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/NamedConfigureFromConfigurationOptions.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/NamedConfigureFromConfigurationOptions.cs index 112e572f7af28e..9b4477abb77f3d 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/NamedConfigureFromConfigurationOptions.cs +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/NamedConfigureFromConfigurationOptions.cs @@ -12,7 +12,7 @@ namespace Microsoft.Extensions.Options /// Configures an option instance by using against an . /// /// The type of options to bind. - public class NamedConfigureFromConfigurationOptions<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions> : ConfigureNamedOptions + public class NamedConfigureFromConfigurationOptions : ConfigureNamedOptions where TOptions : class { /// diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/OptionsBuilderConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/OptionsBuilderConfigurationExtensions.cs index 2deb91d97ad5b8..50b34192932852 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/OptionsBuilderConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/OptionsBuilderConfigurationExtensions.cs @@ -25,7 +25,7 @@ public static class OptionsBuilderConfigurationExtensions /// The so that additional calls can be chained. [RequiresDynamicCode(RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(TrimmingRequiredUnreferencedCodeMessage)] - public static OptionsBuilder Bind<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions>(this OptionsBuilder optionsBuilder, IConfiguration config) where TOptions : class + public static OptionsBuilder Bind(this OptionsBuilder optionsBuilder, IConfiguration config) where TOptions : class => optionsBuilder.Bind(config, _ => { }); /// @@ -38,7 +38,7 @@ public static class OptionsBuilderConfigurationExtensions /// The so that additional calls can be chained. [RequiresDynamicCode(RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(TrimmingRequiredUnreferencedCodeMessage)] - public static OptionsBuilder Bind<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions>(this OptionsBuilder optionsBuilder, IConfiguration config, Action? configureBinder) where TOptions : class + public static OptionsBuilder Bind(this OptionsBuilder optionsBuilder, IConfiguration config, Action? configureBinder) where TOptions : class { ArgumentNullException.ThrowIfNull(optionsBuilder); @@ -61,7 +61,7 @@ public static class OptionsBuilderConfigurationExtensions /// [RequiresDynamicCode(RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(TrimmingRequiredUnreferencedCodeMessage)] - public static OptionsBuilder BindConfiguration<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions>( + public static OptionsBuilder BindConfiguration( this OptionsBuilder optionsBuilder, string configSectionPath, Action? configureBinder = null) diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/OptionsConfigurationServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/OptionsConfigurationServiceCollectionExtensions.cs index 9fa33a2ec2bded..d855f0aae965db 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/OptionsConfigurationServiceCollectionExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/OptionsConfigurationServiceCollectionExtensions.cs @@ -22,7 +22,7 @@ public static class OptionsConfigurationServiceCollectionExtensions /// The so that additional calls can be chained. [RequiresDynamicCode(OptionsBuilderConfigurationExtensions.RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(OptionsBuilderConfigurationExtensions.TrimmingRequiredUnreferencedCodeMessage)] - public static IServiceCollection Configure<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions>(this IServiceCollection services, IConfiguration config) where TOptions : class + public static IServiceCollection Configure(this IServiceCollection services, IConfiguration config) where TOptions : class => services.Configure(Options.Options.DefaultName, config); /// @@ -35,7 +35,7 @@ public static class OptionsConfigurationServiceCollectionExtensions /// The so that additional calls can be chained. [RequiresDynamicCode(OptionsBuilderConfigurationExtensions.RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(OptionsBuilderConfigurationExtensions.TrimmingRequiredUnreferencedCodeMessage)] - public static IServiceCollection Configure<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions>(this IServiceCollection services, string? name, IConfiguration config) where TOptions : class + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration config) where TOptions : class => services.Configure(name, config, _ => { }); /// @@ -48,7 +48,7 @@ public static class OptionsConfigurationServiceCollectionExtensions /// The so that additional calls can be chained. [RequiresDynamicCode(OptionsBuilderConfigurationExtensions.RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(OptionsBuilderConfigurationExtensions.TrimmingRequiredUnreferencedCodeMessage)] - public static IServiceCollection Configure<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions>(this IServiceCollection services, IConfiguration config, Action? configureBinder) + public static IServiceCollection Configure(this IServiceCollection services, IConfiguration config, Action? configureBinder) where TOptions : class => services.Configure(Options.Options.DefaultName, config, configureBinder); @@ -63,7 +63,7 @@ public static class OptionsConfigurationServiceCollectionExtensions /// The so that additional calls can be chained. [RequiresDynamicCode(OptionsBuilderConfigurationExtensions.RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(OptionsBuilderConfigurationExtensions.TrimmingRequiredUnreferencedCodeMessage)] - public static IServiceCollection Configure<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions>(this IServiceCollection services, string? name, IConfiguration config, Action? configureBinder) + public static IServiceCollection Configure(this IServiceCollection services, string? name, IConfiguration config, Action? configureBinder) where TOptions : class { ArgumentNullException.ThrowIfNull(services); diff --git a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/ref/Microsoft.Extensions.Options.DataAnnotations.csproj b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/ref/Microsoft.Extensions.Options.DataAnnotations.csproj index 2a39704831c014..41ef41a8e47b40 100644 --- a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/ref/Microsoft.Extensions.Options.DataAnnotations.csproj +++ b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/ref/Microsoft.Extensions.Options.DataAnnotations.csproj @@ -11,6 +11,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj index 7fc21d972053f3..b198e88c3e4169 100644 --- a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj +++ b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj @@ -13,6 +13,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Options/Microsoft.Extensions.Options.slnx b/src/libraries/Microsoft.Extensions.Options/Microsoft.Extensions.Options.slnx index b26c1fb242b830..fe0e5ea8592700 100644 --- a/src/libraries/Microsoft.Extensions.Options/Microsoft.Extensions.Options.slnx +++ b/src/libraries/Microsoft.Extensions.Options/Microsoft.Extensions.Options.slnx @@ -1,121 +1,1738 @@ + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.csproj b/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.csproj index 7ee6d82d8a26b3..63de421edb59e1 100644 --- a/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.csproj +++ b/src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.csproj @@ -10,6 +10,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj index 54b1d96ddbfaca..a432b81e669d26 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj +++ b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj @@ -11,6 +11,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsTest.cs b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsTest.cs index 52e4e1a69dce0a..a9a6348743f974 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsTest.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsTest.cs @@ -179,7 +179,7 @@ public void SingleValidateOnStartRegistrationTest() Assert.Equal(1, sc.Count(sd => sd.ServiceType == typeof(IStartupValidator))); } - public static TheoryData Configure_GetsNullableOptionsFromConfiguration_Data + public static TheoryData, IDictionary> Configure_GetsNullableOptionsFromConfiguration_Data { get { @@ -254,7 +254,7 @@ public void Configure_GetsNullableOptionsFromConfiguration( Assert.Collection(expectedValues, assertions.ToArray()); } - public static TheoryData Configure_GetsEnumOptionsFromConfiguration_Data + public static TheoryData, IDictionary> Configure_GetsEnumOptionsFromConfiguration_Data { get { diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs index f55323caeedc14..ae0a282934ee2b 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs @@ -1811,7 +1811,7 @@ public sealed partial class OptionsUsingGeneratedAttributesValidator : IValidate string generatedSource = File.ReadAllText(languageVersion == LanguageVersion.CSharp10 ? @"Baselines/GeneratedAttributesTest.netcore.lang10.g.cs" : @"Baselines/GeneratedAttributesTest.netcore.lang11.g.cs"); #else string generatedSource = File.ReadAllText(languageVersion == LanguageVersion.CSharp10 ? @"Baselines/GeneratedAttributesTest.netfx.lang10.g.cs" : @"Baselines/GeneratedAttributesTest.netfx.lang11.g.cs"); -#endif // NET8_0_OR_GREATER +#endif // NET Assert.Equal(generatedSource.Replace("\r\n", "\n"), emittedSource.Replace("\r\n", "\n")); CSharpCompilation compilation = CreateCompilationForOptionsSource(Path.GetRandomFileName(), source + emittedSource, refAssemblyPath: null, languageVersion); diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs index 761a765752f5f6..736f8251b6bd60 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/OptionsRuntimeTests.cs @@ -238,7 +238,7 @@ public void TestValidationWithCyclicReferences() Assert.True(result1.Succeeded); } -#if NET8_0_OR_GREATER +#if NET [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] public void TestNewDataAnnotationFailures() { @@ -267,14 +267,14 @@ public void TestNewDataAnnotationFailures() "P5: The OptionsUsingNewAttributes.P5 field equals one of the values specified in DeniedValuesAttribute." }, result.Failures); } -#endif // NET8_0_OR_GREATER +#endif // NET [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] public void TestCustomGeneratedAttributes() { OptionsUsingGeneratedAttributes noFailures = new OptionsUsingGeneratedAttributes() { -#if NET8_0_OR_GREATER +#if NET P0 = "123", P11 = new DateTime(2023, 2, 1), P12 = 6, @@ -295,7 +295,7 @@ public void TestCustomGeneratedAttributes() P30 = new HashSet { "1", "2", "3" }, P31 = new List { 1, 2, 3, 4 }, P32 = new HashSet { 1, 2, 3, 4 }, -#endif // NET8_0_OR_GREATER +#endif // NET P1 = 2, P2 = "12345", P3 = "12345", @@ -318,7 +318,7 @@ public void TestCustomGeneratedAttributes() OptionsUsingGeneratedAttributes failing = new OptionsUsingGeneratedAttributes() { -#if NET8_0_OR_GREATER +#if NET P0 = "", P11 = new DateTime(2023, 1, 1), P12 = 5, @@ -339,7 +339,7 @@ public void TestCustomGeneratedAttributes() P30 = new HashSet { "1", "2" }, P31 = new List { 1, 2, 3, 4, 5 }, P32 = new HashSet { 1, 2, 3, 4, 5 }, -#endif // NET8_0_OR_GREATER +#endif // NET P1 = 4, P2 = "1234", P3 = "123456", @@ -361,7 +361,7 @@ public void TestCustomGeneratedAttributes() Assert.True(generatorResult.Failed); Assert.Equal(new [] { -#if NET8_0_OR_GREATER +#if NET "P0: The field OptionsUsingGeneratedAttributes.P0 must be a string or collection type with a minimum length of '1' and maximum length of '3'.", string.Format(CultureInfo.CurrentCulture, "P11: The field OptionsUsingGeneratedAttributes.P11 must be between {0} and {1}.", new DateTime(2023, 1, 30), new DateTime(2023, 12, 30)), "P12: The field OptionsUsingGeneratedAttributes.P12 must be between 5 exclusive and 10.", @@ -382,7 +382,7 @@ public void TestCustomGeneratedAttributes() "P30: The field OptionsUsingGeneratedAttributes.P30 must be a string or array type with a minimum length of '3'.", "P31: The field OptionsUsingGeneratedAttributes.P31 must be a string or array type with a maximum length of '4'.", "P32: The field OptionsUsingGeneratedAttributes.P32 must be a string or array type with a maximum length of '4'.", -#endif // NET8_0_OR_GREATER +#endif // NET "P1: The field OptionsUsingGeneratedAttributes.P1 must be between 1 and 3.", "P2: The field OptionsUsingGeneratedAttributes.P2 must be a string or array type with a minimum length of '5'.", "P3: The field OptionsUsingGeneratedAttributes.P3 must be a string or array type with a maximum length of '5'.", @@ -424,7 +424,7 @@ public class FakeCountChild(int count) : FakeCount(count) { } public class OptionsUsingGeneratedAttributes { -#if NET8_0_OR_GREATER +#if NET [LengthAttribute(1, 3)] public string? P0 { get; set; } @@ -487,7 +487,7 @@ public class OptionsUsingGeneratedAttributes [MaxLengthAttribute(4)] public ICollection P32 { get; set; } -#endif // NET8_0_OR_GREATER +#endif // NET [RangeAttribute(1, 3)] public int P1 { get; set; } @@ -598,7 +598,7 @@ public class MyDictionaryOptions : Dictionary { [Required] publi public class MyListOptions : List { [Required] public T Prop { get; set; } = default; } [OptionsValidator] public partial class MyListOptionsOptionsValidator : IValidateOptions> { } -#if NET8_0_OR_GREATER +#if NET public class OptionsUsingNewAttributes { [Length(5, 10)] @@ -621,7 +621,7 @@ public class OptionsUsingNewAttributes public partial class NewAttributesValidator : IValidateOptions { } -#endif // NET8_0_OR_GREATER +#endif // NET public class OptionsWithTimeSpanRangeAttribute diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/OptionsValidationTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/OptionsValidationTests.cs index 01519b780eba1e..4770f02955751d 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/OptionsValidationTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/OptionsValidationTests.cs @@ -241,7 +241,7 @@ public void MultipleAttributeModelValid() [InlineData("abc", 0, 4, 9)] [InlineData("abc", 2, 8, 8)] [InlineData("abc", 2, 4, 10)] - public void MultipleAttributeModelInvalid(string val1, int val2, int val3, int val4) + public void MultipleAttributeModelInvalid(string? val1, int val2, int val3, int val4) { var validModel = new MultipleAttributeModel { diff --git a/src/libraries/Microsoft.Extensions.Primitives/tests/StringSegmentTest.cs b/src/libraries/Microsoft.Extensions.Primitives/tests/StringSegmentTest.cs index 1d45036a447bfe..edca22286c1f41 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/tests/StringSegmentTest.cs +++ b/src/libraries/Microsoft.Extensions.Primitives/tests/StringSegmentTest.cs @@ -571,7 +571,7 @@ public void StringSegment_IsNullOrEmpty_Invalid() Assert.False(StringSegment.IsNullOrEmpty(new StringSegment("ABCDefg", 3, 2))); } - public static TheoryData GetHashCode_ReturnsSameValueForEqualSubstringsData => new TheoryData + public static TheoryData GetHashCode_ReturnsSameValueForEqualSubstringsData => new TheoryData { { default(StringSegment), default(StringSegment) }, { default(StringSegment), new StringSegment() }, @@ -593,7 +593,7 @@ public void GetHashCode_ReturnsSameValueForEqualSubstrings(StringSegment segment Assert.Equal(hashCode1, hashCode2); } - public static TheoryData GetHashCode_ReturnsDifferentValuesForInequalSubstringsData + public static TheoryData GetHashCode_ReturnsDifferentValuesForInequalSubstringsData { get { diff --git a/src/libraries/Microsoft.VisualBasic.Core/Microsoft.VisualBasic.Core.slnx b/src/libraries/Microsoft.VisualBasic.Core/Microsoft.VisualBasic.Core.slnx index 4c9a7250af0266..e8238153a18f3e 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/Microsoft.VisualBasic.Core.slnx +++ b/src/libraries/Microsoft.VisualBasic.Core/Microsoft.VisualBasic.Core.slnx @@ -1,34 +1,874 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft.VisualBasic.Core.vbproj b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft.VisualBasic.Core.vbproj index 596f1e13926d7c..c3645dd8a9c18c 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft.VisualBasic.Core.vbproj +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft.VisualBasic.Core.vbproj @@ -1,5 +1,7 @@ + + $(NetCoreAppCurrent);$(NetCoreAppCurrent)-windows true None On @@ -7,17 +9,17 @@ Off Empty Binary - 42025 + $(WarningsNotAsErrors);42025 $(DefineConstants),LATEBINDING=True $(NoWarn),CA1052,CA1510,CA1810,CA1822,CA2200 Microsoft.VisualBasic.Core false - $(NetCoreAppCurrent);$(NetCoreAppCurrent)-windows disable false + $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) @@ -25,12 +27,14 @@ $(DefineConstants),TARGET_WINDOWS=True $(NoWarn);CA1823 + + @@ -100,25 +104,27 @@ + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/DecimalTypeTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/DecimalTypeTests.cs index 53d3888a7dcad1..6f833ca11da70e 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/DecimalTypeTests.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/DecimalTypeTests.cs @@ -23,7 +23,7 @@ public void FromBoolean(bool value, decimal expected) [InlineData("&H123", 291)] [InlineData("&O123", 83)] [InlineData("123", 123)] - public void FromString(string value, decimal expected) + public void FromString(string? value, decimal expected) { Assert.Equal(expected, DecimalType.FromString(value)); } diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/DoubleTypeTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/DoubleTypeTests.cs index 9bca77d26a2524..4980956e0582dc 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/DoubleTypeTests.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/DoubleTypeTests.cs @@ -15,7 +15,7 @@ public class DoubleTypeTests [InlineData("&H123", 291)] [InlineData("&O123", 83)] [InlineData("123", 123)] - public void FromString(string value, double expected) + public void FromString(string? value, double expected) { Assert.Equal(expected, DoubleType.FromString(value)); } diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/VersionedTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/VersionedTests.cs index c2a930cf9d00d7..cce74a4855b81b 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/VersionedTests.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/tests/CompilerServices/VersionedTests.cs @@ -83,7 +83,7 @@ public object this[object index] [InlineData('1', true)] [InlineData("&O123", true)] [InlineData("&H123", true)] - public void IsNumeric(object value, bool expected) + public void IsNumeric(object? value, bool expected) { Assert.Equal(expected, Versioned.IsNumeric(value)); } @@ -94,14 +94,14 @@ public void IsNumeric(object value, bool expected) [InlineData(" OBJECT ", "System.Object")] [InlineData("object", "System.Object")] [InlineData("custom", null)] - public void SystemTypeName(string value, string expected) + public void SystemTypeName(string? value, string? expected) { Assert.Equal(expected, Versioned.SystemTypeName(value)); } [Theory] [MemberData(nameof(TypeName_TestData))] - public void TypeName(object expression, string expected) + public void TypeName(object? expression, string expected) { Assert.Equal(expected, Versioned.TypeName(expression)); } @@ -155,7 +155,7 @@ public static IEnumerable TypeName_ComObject_TestData() [InlineData("Object", "Object")] [InlineData(" object ", "Object")] [InlineData("custom", null)] - public void VbTypeName(string value, string expected) + public void VbTypeName(string? value, string? expected) { Assert.Equal(expected, Versioned.VbTypeName(value)); } diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/ConversionTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/ConversionTests.cs index c28005480741b0..09c78b0b48003f 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/tests/ConversionTests.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/tests/ConversionTests.cs @@ -123,7 +123,7 @@ private static void CTypeDynamic(object expression, object expected) [Theory] [InlineData(null, null)] [InlineData("", null)] - public void CTypeDynamic_ArgumentException(object expression, Type targetType) + public void CTypeDynamic_ArgumentException(object? expression, Type? targetType) { Assert.Throws(() => Conversion.CTypeDynamic(expression, targetType)); } @@ -222,7 +222,7 @@ public void Fix_ArgumentException(object value) [Theory] [InlineData(null)] - public void Fix_ArgumentNullException(object value) + public void Fix_ArgumentNullException(object? value) { Assert.Throws(() => Conversion.Fix(value)); } @@ -399,7 +399,7 @@ public void Hex_ArgumentException(object value) [Theory] [InlineData(null)] - public void Hex_ArgumentNullException(object value) + public void Hex_ArgumentNullException(object? value) { Assert.Throws(() => Conversion.Hex(value)); } @@ -565,7 +565,7 @@ public void Int_ArgumentException(object value) [Theory] [InlineData(null)] - public void Int_ArgumentNullException(object value) + public void Int_ArgumentNullException(object? value) { Assert.Throws(() => Conversion.Int(value)); } @@ -737,7 +737,7 @@ public void Oct_ArgumentException(object value) [Theory] [InlineData(null)] - public void Oct_ArgumentNullException(object value) + public void Oct_ArgumentNullException(object? value) { Assert.Throws(() => Conversion.Oct(value)); } @@ -846,7 +846,7 @@ public void Str(object value, string expected) [Theory] [InlineData(null)] - public void Str_ArgumentNullException(object value) + public void Str_ArgumentNullException(object? value) { Assert.Throws(() => Conversion.Str(value)); } diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/ErrObjectTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/ErrObjectTests.cs index 5844f2ccf64d12..61a1f8c4b66fbd 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/tests/ErrObjectTests.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/tests/ErrObjectTests.cs @@ -10,7 +10,7 @@ namespace Microsoft.VisualBasic.Tests public class ErrObjectTests { [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951", typeof(PlatformDetection), nameof(PlatformDetection.IsSingleFile))] + [ActiveIssue("https://github.com/mono/mono/issues/14854", typeof(PlatformDetection), nameof(PlatformDetection.IsSingleFile))] [ActiveIssue("https://github.com/mono/mono/issues/14854", TestRuntimes.Mono)] public void Clear() { @@ -122,7 +122,7 @@ public void MakeHelpLink() [InlineData("#-3", -3, "")] [InlineData("MyFile1", 0, "MyFile1")] [InlineData("MyFile4#4", 4, "MyFile4")] - public void ParseHelpLink(string helpLink, int expectedHelpContext, string expectedHelpFile) + public void ParseHelpLink(string? helpLink, int expectedHelpContext, string expectedHelpFile) { ProjectData.ClearProjectError(); ProjectData.SetProjectError(new ArgumentException() { HelpLink = helpLink }); diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/InformationTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/InformationTests.cs index 474ab884d72ed9..97604b65ce4f43 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/tests/InformationTests.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/tests/InformationTests.cs @@ -12,7 +12,7 @@ public class InformationTests [Theory] [InlineData(new int[0], true)] [InlineData(null, false)] - public void IsArray(object value, bool expected) + public void IsArray(object? value, bool expected) { Assert.Equal(expected, Information.IsArray(value)); } @@ -38,7 +38,7 @@ public void IsDBNull() [Theory] [InlineData(null, true)] [InlineData("abc", false)] - public void IsNothing(object value, bool expected) + public void IsNothing(object? value, bool expected) { Assert.Equal(expected, Information.IsNothing(value)); } @@ -55,7 +55,7 @@ public void IsError() [InlineData(null, true)] [InlineData("abc", true)] [InlineData(1, false)] - public void IsReference(object value, bool expected) + public void IsReference(object? value, bool expected) { Assert.Equal(expected, Information.IsReference(value)); } @@ -137,7 +137,7 @@ public void RGB_Invalid() [InlineData(true, VariantType.Boolean)] [InlineData((byte)1, VariantType.Byte)] [InlineData('a', VariantType.Char)] - public void VarType(object value, VariantType expected) + public void VarType(object? value, VariantType expected) { Assert.Equal(expected, Information.VarType(value)); } @@ -151,7 +151,7 @@ public void VarType(object value, VariantType expected) [InlineData('1', true)] [InlineData("&O123", true)] [InlineData("&H123", true)] - public void IsNumeric(object value, bool expected) + public void IsNumeric(object? value, bool expected) { Assert.Equal(expected, Information.IsNumeric(value)); } @@ -168,7 +168,7 @@ public void IsNumeric_Invalid() [InlineData(" OBJECT ", "System.Object")] [InlineData("object", "System.Object")] [InlineData("custom", null)] - public void SystemTypeName(string value, string expected) + public void SystemTypeName(string? value, string? expected) { Assert.Equal(expected, Information.SystemTypeName(value)); } @@ -212,7 +212,7 @@ public static IEnumerable TypeName_TestData() [InlineData("Object", "Object")] [InlineData(" object ", "Object")] [InlineData("custom", null)] - public void VbTypeName(string value, string expected) + public void VbTypeName(string? value, string? expected) { Assert.Equal(expected, Information.VbTypeName(value)); } diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/InteractionTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/InteractionTests.cs index 962749c6a6e8a2..1d3bc0f9b31d13 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/tests/InteractionTests.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/tests/InteractionTests.cs @@ -334,7 +334,7 @@ public void Shell() [InlineData(new object[] { true, "red", false, "green", false, "blue" }, "red")] [InlineData(new object[] { false, "red", true, "green", false, "blue" }, "green")] [InlineData(new object[] { false, "red", false, "green", true, "blue" }, "blue")] - public void Switch(object[] VarExpr, object expected) + public void Switch(object[]? VarExpr, object? expected) { Assert.Equal(expected, Interaction.Switch(VarExpr)); } diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/Microsoft/VisualBasic/ComClassAttributeTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/Microsoft/VisualBasic/ComClassAttributeTests.cs index f7b256c1f4faba..2c33e6a65c698d 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/tests/Microsoft/VisualBasic/ComClassAttributeTests.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/tests/Microsoft/VisualBasic/ComClassAttributeTests.cs @@ -21,7 +21,7 @@ public void Ctor_Default() [InlineData(null)] [InlineData("")] [InlineData("classID")] - public void Ctor_String(string classID) + public void Ctor_String(string? classID) { var attribute = new ComClassAttribute(classID); Assert.Equal(classID, attribute.ClassID); @@ -34,7 +34,7 @@ public void Ctor_String(string classID) [InlineData(null, null)] [InlineData("", "")] [InlineData("classID", "interfaceID")] - public void Ctor_String_String(string classID, string interfaceID) + public void Ctor_String_String(string? classID, string? interfaceID) { var attribute = new ComClassAttribute(classID, interfaceID); Assert.Equal(classID, attribute.ClassID); @@ -47,7 +47,7 @@ public void Ctor_String_String(string classID, string interfaceID) [InlineData(null, null, null)] [InlineData("", "", "")] [InlineData("classID", "interfaceID", "eventID")] - public void Ctor_String_String_String(string classID, string interfaceID, string eventID) + public void Ctor_String_String_String(string? classID, string? interfaceID, string? eventID) { var attribute = new ComClassAttribute(classID, interfaceID, eventID); Assert.Equal(classID, attribute.ClassID); diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/Microsoft/VisualBasic/MyGroupCollectionAttributeTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/Microsoft/VisualBasic/MyGroupCollectionAttributeTests.cs index 9ab1d9b28a2ba2..d9ef0350a24a5c 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/tests/Microsoft/VisualBasic/MyGroupCollectionAttributeTests.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/tests/Microsoft/VisualBasic/MyGroupCollectionAttributeTests.cs @@ -11,7 +11,7 @@ public class MyGroupCollectionAttributeTests [InlineData(null, null, null, null)] [InlineData("", "", "", "")] [InlineData("typeToCollect", "createInstanceMethodName", "disposeInstanceMethodName", "defaultInstanceAlias")] - public void Ctor_String_String_String(string typeToCollect, string createInstanceMethodName, string disposeInstanceMethodName, string defaultInstanceAlias) + public void Ctor_String_String_String(string? typeToCollect, string? createInstanceMethodName, string? disposeInstanceMethodName, string? defaultInstanceAlias) { var attribute = new MyGroupCollectionAttribute(typeToCollect, createInstanceMethodName, disposeInstanceMethodName, defaultInstanceAlias); Assert.Equal(typeToCollect, attribute.MyGroupName); diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/StringTypeTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/StringTypeTests.cs index 8d4d2842766d7f..1aa4dd7dfc3969 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/tests/StringTypeTests.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/tests/StringTypeTests.cs @@ -339,7 +339,7 @@ public static IEnumerable FromDecimal_Format_TestData() [InlineData("abc", 2, 1, "def", "adc")] [InlineData("abc", 2, 2, "def", "ade")] [InlineData("abc", 2, 3, "def", "ade")] - public void MidStmtStr(string str, int start, int length, string insert, string expected) + public void MidStmtStr(string str, int start, int length, string? insert, string expected) { StringType.MidStmtStr(ref str, start, length, insert); Assert.Equal(expected, str); @@ -358,7 +358,7 @@ public void MidStmtStr(string str, int start, int length, string insert, string [InlineData("abc", 0, 0, "")] [InlineData("abc", 4, 0, "")] [InlineData("abc", 1, -3, "")] - public void MidStmtStr_ArgumentException(string str, int start, int length, string insert) + public void MidStmtStr_ArgumentException(string? str, int start, int length, string? insert) { Assert.Throws(() => StringType.MidStmtStr(ref str, start, length, insert)); } @@ -396,7 +396,7 @@ public static IEnumerable StrCmp_TestData() [InlineData("a", "?", true, true)] [InlineData("a3", "[A-Z]#", false, true)] [InlineData("A3", "[a-z]#", false, true)] - public void StrLike(string source, string pattern, bool expectedBinaryCompare, bool expectedTextCompare) + public void StrLike(string? source, string? pattern, bool expectedBinaryCompare, bool expectedTextCompare) { Assert.Equal(expectedBinaryCompare, StringType.StrLike(source, pattern, CompareMethod.Binary)); Assert.Equal(expectedTextCompare, StringType.StrLike(source, pattern, CompareMethod.Text)); @@ -406,7 +406,7 @@ public void StrLike(string source, string pattern, bool expectedBinaryCompare, b [Theory] [InlineData(null, "*")] - public void StrLike_NullReferenceException(string source, string pattern) + public void StrLike_NullReferenceException(string? source, string pattern) { Assert.Throws(() => StringType.StrLike(source, pattern, CompareMethod.Binary)); Assert.Throws(() => StringType.StrLike(source, pattern, CompareMethod.Text)); diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/StringsTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/StringsTests.cs index 27967fa777fe10..f844e0d0c801b7 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/tests/StringsTests.cs +++ b/src/libraries/Microsoft.VisualBasic.Core/tests/StringsTests.cs @@ -38,7 +38,7 @@ public void Asc_String_ReturnsExpected(string String, int expected) [Theory] [InlineData(null)] [InlineData("")] - public void Asc_NullOrEmpty_ThrowsArgumentException(string String) + public void Asc_NullOrEmpty_ThrowsArgumentException(string? String) { AssertExtensions.Throws("String", null, () => Strings.Asc(String)); } @@ -61,7 +61,7 @@ public void AscW_String_ReturnsExpected(string String, int expected) [Theory] [InlineData(null)] [InlineData("")] - public void AscW_NullOrEmpty_ThrowsArgumentException(string String) + public void AscW_NullOrEmpty_ThrowsArgumentException(string? String) { AssertExtensions.Throws("String", null, () => Strings.AscW(String)); } @@ -151,7 +151,7 @@ public void Asc_Chr_DoubleByte(int charCode, int expected) [Theory] [InlineData(new string[] { }, null, null)] [InlineData(new string[] { }, "", null)] - public void Filter_WhenNoMatchArgument_ReturnsNull(string[] source, string match, string[] expected) + public void Filter_WhenNoMatchArgument_ReturnsNull(string[] source, string? match, string[]? expected) { Assert.Equal(expected, Strings.Filter(source, match)); } @@ -400,7 +400,7 @@ public void GetChar(string str, int index, char expected) [InlineData("", 1)] [InlineData("ABC", 0)] [InlineData("ABC", 4)] - public void GetChar_ArgumentException(string str, int index) + public void GetChar_ArgumentException(string? str, int index) { Assert.Throws< ArgumentException>(() => Strings.GetChar(str, index)); } @@ -564,7 +564,7 @@ public void LCase_Char(char value, char expected) [InlineData("abc", "abc")] [InlineData("ABC", "abc")] [InlineData("123", "123")] - public void LCase_String(string value, string expected) + public void LCase_String(string? value, string? expected) { Assert.Equal(expected, Strings.LCase(value)); } @@ -588,7 +588,7 @@ public void UCase_Char(char value, char expected) [InlineData("abc", "ABC")] [InlineData("ABC", "ABC")] [InlineData("123", "123")] - public void UCase_String(string value, string expected) + public void UCase_String(string? value, string expected) { Assert.Equal(expected, Strings.UCase(value)); } @@ -674,7 +674,7 @@ public void Mid2_Invalid(string str, int start) [InlineData("abc", 1, "abc")] // 1-based strings in VB [InlineData("abcd", 2, "bcd")] [InlineData("abcd", 3, "cd")] - public void Mid2_Valid(string str, int start, string expected) + public void Mid2_Valid(string? str, int start, string? expected) { Assert.Equal(expected, Strings.Mid(str, start)); } @@ -695,7 +695,7 @@ public void Mid3_Invalid(string str, int start, int length) [InlineData("abc", 1, 2, "ab")] // 1-based strings in VB [InlineData("abcd", 2, 2, "bc")] [InlineData("abcd", 2, 3, "bcd")] - public void Mid3_Valid(string str, int start, int length, string expected) + public void Mid3_Valid(string? str, int start, int length, string expected) { Assert.Equal(expected, Strings.Mid(str, start, length)); } @@ -712,7 +712,7 @@ public void Mid3_Valid(string str, int start, int length, string expected) [InlineData("AB", 1, "A")] [InlineData("AB", 2, "AB")] [InlineData("AB", 4, "AB ")] - public void LSet(string source, int length, string expected) + public void LSet(string? source, int length, string expected) { Assert.Equal(expected, Strings.LSet(source, length)); } @@ -729,7 +729,7 @@ public void LSet(string source, int length, string expected) [InlineData("AB", 1, "A")] [InlineData("AB", 2, "AB")] [InlineData("AB", 4, " AB")] - public void RSet(string source, int length, string expected) + public void RSet(string? source, int length, string expected) { Assert.Equal(expected, Strings.RSet(source, length)); } @@ -743,7 +743,7 @@ public void RSet(string source, int length, string expected) [InlineData("\nabc ", "\nabc ")] [InlineData("abc ", "abc ")] [InlineData("abc", "abc")] - public void LTrim_Valid(string str, string expected) + public void LTrim_Valid(string? str, string expected) { // Trims only space and \u3000 specifically Assert.Equal(expected, Strings.LTrim(str)); @@ -758,7 +758,7 @@ public void LTrim_Valid(string str, string expected) [InlineData(" abc\n", " abc\n")] [InlineData(" abc", " abc")] [InlineData("abc", "abc")] - public void RTrim_Valid(string str, string expected) + public void RTrim_Valid(string? str, string expected) { // Trims only space and \u3000 specifically Assert.Equal(expected, Strings.RTrim(str)); @@ -773,7 +773,7 @@ public void RTrim_Valid(string str, string expected) [InlineData("\u3000abc\n\u3000", "abc\n")] [InlineData("abc\n", "abc\n")] [InlineData("abc", "abc")] - public void Trim_Valid(string str, string expected) + public void Trim_Valid(string? str, string expected) { // Trims only space and \u3000 specifically Assert.Equal(expected, Strings.Trim(str)); @@ -793,7 +793,7 @@ public void Trim_Valid(string str, string expected) [InlineData("abc", "bc", "23", 2, -1, CompareMethod.Text, "23")] [InlineData("abc", "bc", "23", 3, -1, CompareMethod.Text, "c")] [InlineData("abc", "bc", "23", 4, -1, CompareMethod.Text, null)] - public void Replace(string expression, string find, string replacement, int start, int n, CompareMethod compare, string expected) + public void Replace(string expression, string? find, string? replacement, int start, int n, CompareMethod compare, string? expected) { Assert.Equal(expected, Strings.Replace(expression, find, replacement, start, n, compare)); } @@ -801,7 +801,7 @@ public void Replace(string expression, string find, string replacement, int star [Theory] [InlineData(null, null, null, 0, 0, CompareMethod.Text)] [InlineData(null, "", "", 0, 0, CompareMethod.Text)] - public void Replace_ArgumentException(string expression, string find, string replacement, int start, int length, CompareMethod compare) + public void Replace_ArgumentException(string? expression, string? find, string? replacement, int start, int length, CompareMethod compare) { Assert.Throws< ArgumentException>(() => Strings.Replace(expression, find, replacement, start, length, compare)); } @@ -828,7 +828,7 @@ public void Space(int number, string expected) [InlineData("A, B, C", ", ", 1, CompareMethod.Text, new string[] { "A, B, C" })] [InlineData("A, B, C", ", ", 2, CompareMethod.Text, new string[] { "A", "B, C" })] [InlineData("A, B, C", ", ", int.MaxValue, CompareMethod.Text, new string[] { "A", "B", "C" })] - public void Split(string expression, string delimiter, int limit, CompareMethod compare, string[] expected) + public void Split(string? expression, string? delimiter, int limit, CompareMethod compare, string[] expected) { Assert.Equal(expected, Strings.Split(expression, delimiter, limit, compare)); } @@ -860,7 +860,7 @@ public void StrComp(string left, string right, int expectedBinaryCompare, int ex [InlineData("", VbStrConv.Lowercase, 0, "")] [InlineData("Abc123", VbStrConv.Lowercase, 0, "abc123")] [InlineData("Abc123", VbStrConv.Uppercase, 0, "ABC123")] - public void StrConv(string str, Microsoft.VisualBasic.VbStrConv conversion, int localeID, string expected) + public void StrConv(string? str, Microsoft.VisualBasic.VbStrConv conversion, int localeID, string? expected) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { @@ -968,7 +968,7 @@ public static IEnumerable StrDup_String_ArgumentException_TestData() [InlineData("ABC", "CBA")] [InlineData("\ud83c\udfc8", "\ud83c\udfc8")] [InlineData("A\ud83c\udfc8", "\ud83c\udfc8A")] - public void StrReverse(string str, string expected) + public void StrReverse(string? str, string expected) { Assert.Equal(expected, Strings.StrReverse(str)); } diff --git a/src/libraries/Microsoft.Win32.Registry/Microsoft.Win32.Registry.slnx b/src/libraries/Microsoft.Win32.Registry/Microsoft.Win32.Registry.slnx index dc14daa381e17b..d8772a0b289fce 100644 --- a/src/libraries/Microsoft.Win32.Registry/Microsoft.Win32.Registry.slnx +++ b/src/libraries/Microsoft.Win32.Registry/Microsoft.Win32.Registry.slnx @@ -1,35 +1,370 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj b/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj index 6e0aae853be85b..b18c834c4e8970 100644 --- a/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj +++ b/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj @@ -14,6 +14,7 @@ SR.PlatformNotSupported_Registry $(NoWarn);IDE0280 + @@ -70,12 +71,12 @@ - - - - - - + + + + + + diff --git a/src/libraries/System.CodeDom/Directory.Build.props b/src/libraries/System.CodeDom/Directory.Build.props index 53773781258106..aad8d8747bf7bd 100644 --- a/src/libraries/System.CodeDom/Directory.Build.props +++ b/src/libraries/System.CodeDom/Directory.Build.props @@ -3,5 +3,6 @@ true browser;wasi;ios;tvos;maccatalyst + false \ No newline at end of file diff --git a/src/libraries/System.CodeDom/src/System.CodeDom.csproj b/src/libraries/System.CodeDom/src/System.CodeDom.csproj index 76ba0e1a9d3f64..3badaf158c75b3 100644 --- a/src/libraries/System.CodeDom/src/System.CodeDom.csproj +++ b/src/libraries/System.CodeDom/src/System.CodeDom.csproj @@ -3,7 +3,6 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true $(DefineConstants);CODEDOM - false false true Provides types that can be used to model the structure of a source code document and to output source code for that model in C# or Visual Basic. diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeArrayIndexerExpression.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeArrayIndexerExpression.cs index 08ecec7e46da5d..70c3e1271cc5cd 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeArrayIndexerExpression.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeArrayIndexerExpression.cs @@ -5,8 +5,6 @@ namespace System.CodeDom { public class CodeArrayIndexerExpression : CodeExpression { - private CodeExpressionCollection _indices; - public CodeArrayIndexerExpression() { } public CodeArrayIndexerExpression(CodeExpression targetObject, params CodeExpression[] indices) @@ -17,6 +15,6 @@ public CodeArrayIndexerExpression(CodeExpression targetObject, params CodeExpres public CodeExpression TargetObject { get; set; } - public CodeExpressionCollection Indices => _indices ??= new CodeExpressionCollection(); + public CodeExpressionCollection Indices => field ??= new CodeExpressionCollection(); } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeCastExpression.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeCastExpression.cs index c72b590ee6796c..afc31b626235b1 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeCastExpression.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeCastExpression.cs @@ -5,8 +5,6 @@ namespace System.CodeDom { public class CodeCastExpression : CodeExpression { - private CodeTypeReference _targetType; - public CodeCastExpression() { } public CodeCastExpression(CodeTypeReference targetType, CodeExpression expression) @@ -29,8 +27,8 @@ public CodeCastExpression(Type targetType, CodeExpression expression) public CodeTypeReference TargetType { - get => _targetType ??= new CodeTypeReference(""); - set => _targetType = value; + get => field ??= new CodeTypeReference(""); + set => field = value; } public CodeExpression Expression { get; set; } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeCatchClause.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeCatchClause.cs index c3e95043c23119..c5e86c5b9de456 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeCatchClause.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeCatchClause.cs @@ -5,7 +5,6 @@ namespace System.CodeDom { public class CodeCatchClause { - private CodeStatementCollection _statements; private CodeTypeReference _catchExceptionType; private string _localName; @@ -41,6 +40,6 @@ public CodeTypeReference CatchExceptionType set => _catchExceptionType = value; } - public CodeStatementCollection Statements => _statements ??= new CodeStatementCollection(); + public CodeStatementCollection Statements => field ??= new CodeStatementCollection(); } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeCompileUnit.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeCompileUnit.cs index dc46a7bd3e9026..b446b1f15d60b6 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeCompileUnit.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeCompileUnit.cs @@ -7,22 +7,16 @@ namespace System.CodeDom { public class CodeCompileUnit : CodeObject { - private StringCollection _assemblies; - private CodeAttributeDeclarationCollection _attributes; - - private CodeDirectiveCollection _startDirectives; - private CodeDirectiveCollection _endDirectives; - public CodeCompileUnit() { } public CodeNamespaceCollection Namespaces { get; } = new CodeNamespaceCollection(); - public StringCollection ReferencedAssemblies => _assemblies ??= new StringCollection(); + public StringCollection ReferencedAssemblies => field ??= new StringCollection(); - public CodeAttributeDeclarationCollection AssemblyCustomAttributes => _attributes ??= new CodeAttributeDeclarationCollection(); + public CodeAttributeDeclarationCollection AssemblyCustomAttributes => field ??= new CodeAttributeDeclarationCollection(); - public CodeDirectiveCollection StartDirectives => _startDirectives ??= new CodeDirectiveCollection(); + public CodeDirectiveCollection StartDirectives => field ??= new CodeDirectiveCollection(); - public CodeDirectiveCollection EndDirectives => _endDirectives ??= new CodeDirectiveCollection(); + public CodeDirectiveCollection EndDirectives => field ??= new CodeDirectiveCollection(); } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeIndexerExpression.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeIndexerExpression.cs index 53d22aaccc1f6d..4ecc67eda5db21 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeIndexerExpression.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeIndexerExpression.cs @@ -5,8 +5,6 @@ namespace System.CodeDom { public class CodeIndexerExpression : CodeExpression { - private CodeExpressionCollection _indices; - public CodeIndexerExpression() { } public CodeIndexerExpression(CodeExpression targetObject, params CodeExpression[] indices) @@ -17,6 +15,6 @@ public CodeIndexerExpression(CodeExpression targetObject, params CodeExpression[ public CodeExpression TargetObject { get; set; } - public CodeExpressionCollection Indices => _indices ??= new CodeExpressionCollection(); + public CodeExpressionCollection Indices => field ??= new CodeExpressionCollection(); } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberEvent.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberEvent.cs index eca336ed49f44d..54587273e728e6 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberEvent.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberEvent.cs @@ -5,19 +5,16 @@ namespace System.CodeDom { public class CodeMemberEvent : CodeTypeMember { - private CodeTypeReference _type; - private CodeTypeReferenceCollection _implementationTypes; - public CodeMemberEvent() { } public CodeTypeReference Type { - get => _type ??= new CodeTypeReference(""); - set => _type = value; + get => field ??= new CodeTypeReference(""); + set => field = value; } public CodeTypeReference PrivateImplementationType { get; set; } - public CodeTypeReferenceCollection ImplementationTypes => _implementationTypes ??= new CodeTypeReferenceCollection(); + public CodeTypeReferenceCollection ImplementationTypes => field ??= new CodeTypeReferenceCollection(); } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberField.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberField.cs index a2b814d59b1a65..56fd7389592d83 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberField.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberField.cs @@ -5,8 +5,6 @@ namespace System.CodeDom { public class CodeMemberField : CodeTypeMember { - private CodeTypeReference _type; - public CodeMemberField() { } public CodeMemberField(CodeTypeReference type, string name) @@ -29,8 +27,8 @@ public CodeMemberField(Type type, string name) public CodeTypeReference Type { - get => _type ??= new CodeTypeReference(""); - set => _type = value; + get => field ??= new CodeTypeReference(""); + set => field = value; } public CodeExpression InitExpression { get; set; } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberMethod.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberMethod.cs index e1cd920c4bc960..aae0227ed897af 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberMethod.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberMethod.cs @@ -7,10 +7,7 @@ public class CodeMemberMethod : CodeTypeMember { private readonly CodeParameterDeclarationExpressionCollection _parameters = new CodeParameterDeclarationExpressionCollection(); private readonly CodeStatementCollection _statements = new CodeStatementCollection(); - private CodeTypeReference _returnType; private CodeTypeReferenceCollection _implementationTypes; - private CodeAttributeDeclarationCollection _returnAttributes; - private CodeTypeParameterCollection _typeParameters; private int _populated; private const int ParametersCollection = 0x1; @@ -23,8 +20,8 @@ public class CodeMemberMethod : CodeTypeMember public CodeTypeReference ReturnType { - get => _returnType ??= new CodeTypeReference(typeof(void).FullName); - set => _returnType = value; + get => field ??= new CodeTypeReference(typeof(void).FullName); + set => field = value; } public CodeStatementCollection Statements @@ -73,8 +70,8 @@ public CodeTypeReferenceCollection ImplementationTypes } } - public CodeAttributeDeclarationCollection ReturnTypeCustomAttributes => _returnAttributes ??= new CodeAttributeDeclarationCollection(); + public CodeAttributeDeclarationCollection ReturnTypeCustomAttributes => field ??= new CodeAttributeDeclarationCollection(); - public CodeTypeParameterCollection TypeParameters => _typeParameters ??= new CodeTypeParameterCollection(); + public CodeTypeParameterCollection TypeParameters => field ??= new CodeTypeParameterCollection(); } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberProperty.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberProperty.cs index 55ec1d37ec7468..f38504f313cc88 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberProperty.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeMemberProperty.cs @@ -5,19 +5,17 @@ namespace System.CodeDom { public class CodeMemberProperty : CodeTypeMember { - private CodeTypeReference _type; private bool _hasGet; private bool _hasSet; - private CodeTypeReferenceCollection _implementationTypes; public CodeTypeReference PrivateImplementationType { get; set; } - public CodeTypeReferenceCollection ImplementationTypes => _implementationTypes ??= new CodeTypeReferenceCollection(); + public CodeTypeReferenceCollection ImplementationTypes => field ??= new CodeTypeReferenceCollection(); public CodeTypeReference Type { - get => _type ??= new CodeTypeReference(""); - set => _type = value; + get => field ??= new CodeTypeReference(""); + set => field = value; } public bool HasGet diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeObjectCreateExpression.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeObjectCreateExpression.cs index f6710d3e3edc9c..0f5afd299199b3 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeObjectCreateExpression.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeObjectCreateExpression.cs @@ -5,8 +5,6 @@ namespace System.CodeDom { public class CodeObjectCreateExpression : CodeExpression { - private CodeTypeReference _createType; - public CodeObjectCreateExpression() { } public CodeObjectCreateExpression(CodeTypeReference createType, params CodeExpression[] parameters) @@ -29,8 +27,8 @@ public CodeObjectCreateExpression(Type createType, params CodeExpression[] param public CodeTypeReference CreateType { - get => _createType ??= new CodeTypeReference(""); - set => _createType = value; + get => field ??= new CodeTypeReference(""); + set => field = value; } public CodeExpressionCollection Parameters { get; } = new CodeExpressionCollection(); diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeParameterDeclarationExpression.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeParameterDeclarationExpression.cs index 60dbb1b1fb75ff..fb0420cb395681 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeParameterDeclarationExpression.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeParameterDeclarationExpression.cs @@ -5,10 +5,6 @@ namespace System.CodeDom { public class CodeParameterDeclarationExpression : CodeExpression { - private CodeTypeReference _type; - private string _name; - private CodeAttributeDeclarationCollection _customAttributes; - public CodeParameterDeclarationExpression() { } public CodeParameterDeclarationExpression(CodeTypeReference type, string name) @@ -31,22 +27,22 @@ public CodeParameterDeclarationExpression(Type type, string name) public CodeAttributeDeclarationCollection CustomAttributes { - get => _customAttributes ??= new CodeAttributeDeclarationCollection(); - set => _customAttributes = value; + get => field ??= new CodeAttributeDeclarationCollection(); + set => field = value; } public FieldDirection Direction { get; set; } = FieldDirection.In; public CodeTypeReference Type { - get => _type ??= new CodeTypeReference(""); - set => _type = value; + get => field ??= new CodeTypeReference(""); + set => field = value; } public string Name { - get => _name ?? string.Empty; - set => _name = value; + get => field ?? string.Empty; + set => field = value; } } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeStatement.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeStatement.cs index 731d87c547fbf0..4895eb878090c3 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeStatement.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeStatement.cs @@ -5,13 +5,10 @@ namespace System.CodeDom { public class CodeStatement : CodeObject { - private CodeDirectiveCollection _startDirectives; - private CodeDirectiveCollection _endDirectives; - public CodeLinePragma LinePragma { get; set; } - public CodeDirectiveCollection StartDirectives => _startDirectives ??= new CodeDirectiveCollection(); + public CodeDirectiveCollection StartDirectives => field ??= new CodeDirectiveCollection(); - public CodeDirectiveCollection EndDirectives => _endDirectives ??= new CodeDirectiveCollection(); + public CodeDirectiveCollection EndDirectives => field ??= new CodeDirectiveCollection(); } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeDeclaration.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeDeclaration.cs index bb59afa6306aae..a8b24366ed4b64 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeDeclaration.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeDeclaration.cs @@ -14,7 +14,6 @@ public class CodeTypeDeclaration : CodeTypeMember private int _populated; private const int BaseTypesCollection = 0x1; private const int MembersCollection = 0x2; - private CodeTypeParameterCollection _typeParameters; public event EventHandler PopulateBaseTypes; public event EventHandler PopulateMembers; @@ -122,6 +121,6 @@ public CodeTypeMemberCollection Members } } - public CodeTypeParameterCollection TypeParameters => _typeParameters ??= new CodeTypeParameterCollection(); + public CodeTypeParameterCollection TypeParameters => field ??= new CodeTypeParameterCollection(); } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeDelegate.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeDelegate.cs index 4239cdf7ba208d..ab828b0f9c2583 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeDelegate.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeDelegate.cs @@ -7,8 +7,6 @@ namespace System.CodeDom { public class CodeTypeDelegate : CodeTypeDeclaration { - private CodeTypeReference _returnType; - public CodeTypeDelegate() { TypeAttributes &= ~TypeAttributes.ClassSemanticsMask; @@ -24,8 +22,8 @@ public CodeTypeDelegate(string name) : this() public CodeTypeReference ReturnType { - get => _returnType ??= new CodeTypeReference(""); - set => _returnType = value; + get => field ??= new CodeTypeReference(""); + set => field = value; } public CodeParameterDeclarationExpressionCollection Parameters { get; } = new CodeParameterDeclarationExpressionCollection(); diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeMember.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeMember.cs index 18a8a44e822cd0..79f65b6d0fdab3 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeMember.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeMember.cs @@ -5,31 +5,26 @@ namespace System.CodeDom { public class CodeTypeMember : CodeObject { - private string _name; - private CodeAttributeDeclarationCollection _customAttributes; - private CodeDirectiveCollection _startDirectives; - private CodeDirectiveCollection _endDirectives; - public string Name { - get => _name ?? string.Empty; - set => _name = value; + get => field ?? string.Empty; + set => field = value; } public MemberAttributes Attributes { get; set; } = MemberAttributes.Private | MemberAttributes.Final; public CodeAttributeDeclarationCollection CustomAttributes { - get => _customAttributes ??= new CodeAttributeDeclarationCollection(); - set => _customAttributes = value; + get => field ??= new CodeAttributeDeclarationCollection(); + set => field = value; } public CodeLinePragma LinePragma { get; set; } public CodeCommentStatementCollection Comments { get; } = new CodeCommentStatementCollection(); - public CodeDirectiveCollection StartDirectives => _startDirectives ??= new CodeDirectiveCollection(); + public CodeDirectiveCollection StartDirectives => field ??= new CodeDirectiveCollection(); - public CodeDirectiveCollection EndDirectives => _endDirectives ??= new CodeDirectiveCollection(); + public CodeDirectiveCollection EndDirectives => field ??= new CodeDirectiveCollection(); } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeOfExpression.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeOfExpression.cs index bb7f4f3430d407..651edbb538cfef 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeOfExpression.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeOfExpression.cs @@ -5,8 +5,6 @@ namespace System.CodeDom { public class CodeTypeOfExpression : CodeExpression { - private CodeTypeReference _type; - public CodeTypeOfExpression() { } public CodeTypeOfExpression(CodeTypeReference type) @@ -26,8 +24,8 @@ public CodeTypeOfExpression(Type type) public CodeTypeReference Type { - get => _type ??= new CodeTypeReference(""); - set => _type = value; + get => field ??= new CodeTypeReference(""); + set => field = value; } } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeParameter.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeParameter.cs index 7c8a0148788574..124df444434ae9 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeParameter.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeParameter.cs @@ -6,8 +6,6 @@ namespace System.CodeDom public class CodeTypeParameter : CodeObject { private string _name; - private CodeAttributeDeclarationCollection _customAttributes; - private CodeTypeReferenceCollection _constraints; public CodeTypeParameter() { } @@ -22,9 +20,9 @@ public string Name set => _name = value; } - public CodeTypeReferenceCollection Constraints => _constraints ??= new CodeTypeReferenceCollection(); + public CodeTypeReferenceCollection Constraints => field ??= new CodeTypeReferenceCollection(); - public CodeAttributeDeclarationCollection CustomAttributes => _customAttributes ??= new CodeAttributeDeclarationCollection(); + public CodeAttributeDeclarationCollection CustomAttributes => field ??= new CodeAttributeDeclarationCollection(); public bool HasConstructorConstraint { get; set; } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeReferenceExpression.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeReferenceExpression.cs index 338c64fb5c5600..d8d04e54fa57f2 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeReferenceExpression.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeTypeReferenceExpression.cs @@ -5,8 +5,6 @@ namespace System.CodeDom { public class CodeTypeReferenceExpression : CodeExpression { - private CodeTypeReference _type; - public CodeTypeReferenceExpression() { } public CodeTypeReferenceExpression(CodeTypeReference type) @@ -26,8 +24,8 @@ public CodeTypeReferenceExpression(Type type) public CodeTypeReference Type { - get => _type ??= new CodeTypeReference(""); - set => _type = value; + get => field ??= new CodeTypeReference(""); + set => field = value; } } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/CodeVariableDeclarationStatement.cs b/src/libraries/System.CodeDom/src/System/CodeDom/CodeVariableDeclarationStatement.cs index 7672c8eb42f6c1..66efd3549b6bc6 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/CodeVariableDeclarationStatement.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/CodeVariableDeclarationStatement.cs @@ -5,9 +5,6 @@ namespace System.CodeDom { public class CodeVariableDeclarationStatement : CodeStatement { - private CodeTypeReference _type; - private string _name; - public CodeVariableDeclarationStatement() { } public CodeVariableDeclarationStatement(CodeTypeReference type, string name) @@ -53,14 +50,14 @@ public CodeVariableDeclarationStatement(Type type, string name, CodeExpression i public string Name { - get => _name ?? string.Empty; - set => _name = value; + get => field ?? string.Empty; + set => field = value; } public CodeTypeReference Type { - get => _type ??= new CodeTypeReference(""); - set => _type = value; + get => field ??= new CodeTypeReference(""); + set => field = value; } } } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/Compiler/CompilerParameters.cs b/src/libraries/System.CodeDom/src/System/CodeDom/Compiler/CompilerParameters.cs index 59fb4c036dc800..f4a57a1dc34e44 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/Compiler/CompilerParameters.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/Compiler/CompilerParameters.cs @@ -7,8 +7,6 @@ namespace System.CodeDom.Compiler { public partial class CompilerParameters { - private TempFileCollection _tempFiles; - public CompilerParameters() : this(null, null) { } @@ -60,8 +58,8 @@ public CompilerParameters(string[] assemblyNames, string outputName, bool includ public TempFileCollection TempFiles { - get => _tempFiles ??= new TempFileCollection(); - set => _tempFiles = value; + get => field ??= new TempFileCollection(); + set => field = value; } public bool IncludeDebugInformation { get; set; } diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/codemethodreferenceexpression.cs b/src/libraries/System.CodeDom/src/System/CodeDom/codemethodreferenceexpression.cs index cf6cd07050d7a8..0cd96716768635 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/codemethodreferenceexpression.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/codemethodreferenceexpression.cs @@ -5,9 +5,6 @@ namespace System.CodeDom { public class CodeMethodReferenceExpression : CodeExpression { - private string _methodName; - private CodeTypeReferenceCollection _typeArguments; - public CodeMethodReferenceExpression() { } public CodeMethodReferenceExpression(CodeExpression targetObject, string methodName) @@ -30,10 +27,10 @@ public CodeMethodReferenceExpression(CodeExpression targetObject, string methodN public string MethodName { - get => _methodName ?? string.Empty; - set => _methodName = value; + get => field ?? string.Empty; + set => field = value; } - public CodeTypeReferenceCollection TypeArguments => _typeArguments ??= new CodeTypeReferenceCollection(); + public CodeTypeReferenceCollection TypeArguments => field ??= new CodeTypeReferenceCollection(); } } diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeAttributeArgumentTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeAttributeArgumentTests.cs index e97d7a17cdff70..1ae72af5762140 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeAttributeArgumentTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeAttributeArgumentTests.cs @@ -42,7 +42,7 @@ public void Ctor(string name, CodeExpression value) [InlineData(null)] [InlineData("")] [InlineData("Name")] - public void Name_Set_Get_ReturnsExpected(string value) + public void Name_Set_Get_ReturnsExpected(string? value) { var argument = new CodeAttributeArgument(); argument.Name = value; diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeAttributeDeclarationTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeAttributeDeclarationTests.cs index 7eb9c59ccdf624..6f52cd1f0f1ea7 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeAttributeDeclarationTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeAttributeDeclarationTests.cs @@ -87,7 +87,7 @@ public void Ctor_NullObjectInArguments_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("Name")] - public void Name_Set_Get_ReturnsExpected(string value) + public void Name_Set_Get_ReturnsExpected(string? value) { var declaration = new CodeAttributeDeclaration(); declaration.Name = value; diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeChecksumPragmaTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeChecksumPragmaTests.cs index 6e85e23d8a337c..494e1328f1333b 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeChecksumPragmaTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeChecksumPragmaTests.cs @@ -62,7 +62,7 @@ public void AlgorithmId_Set_Get_ReturnsExpected(Guid value) [InlineData(null)] [InlineData(new byte[0])] [InlineData(new byte[] { 0, 1, 2, 3 })] - public void ChecksumData_Set_Get_ReturnsExpected(byte[] value) + public void ChecksumData_Set_Get_ReturnsExpected(byte[]? value) { var pragma = new CodeChecksumPragma(); pragma.ChecksumData = value; diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeDelegateCreateExpressionTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeDelegateCreateExpressionTests.cs index 8c411c151ccbb4..f10c2d27e77b2c 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeDelegateCreateExpressionTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeDelegateCreateExpressionTests.cs @@ -57,7 +57,7 @@ public void TargetObject_Set_Get_ReturnsExpected(CodeExpression value) [InlineData(null)] [InlineData("")] [InlineData("MethodName")] - public void MethodName_Set_Get_ReturnsExpected(string value) + public void MethodName_Set_Get_ReturnsExpected(string? value) { var delegateCreate = new CodeDelegateCreateExpression(); delegateCreate.MethodName = value; diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeEventReferenceExpressionTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeEventReferenceExpressionTests.cs index 089dc60416f099..dbbc5617b239fe 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeEventReferenceExpressionTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeEventReferenceExpressionTests.cs @@ -36,7 +36,7 @@ public void Ctor(CodeExpression targetObject, string eventName) [InlineData(null)] [InlineData("")] [InlineData("EventName")] - public void EventName_Set_Get_ReturnsExpected(string value) + public void EventName_Set_Get_ReturnsExpected(string? value) { var eventReference = new CodeEventReferenceExpression(); eventReference.EventName = value; diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeFieldReferenceExpressionTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeFieldReferenceExpressionTests.cs index 662aea82572e93..e73f407f044961 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeFieldReferenceExpressionTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeFieldReferenceExpressionTests.cs @@ -36,7 +36,7 @@ public void Ctor(CodeExpression targetObject, string fieldName) [InlineData(null)] [InlineData("")] [InlineData("FieldName")] - public void EventName_Set_Get_ReturnsExpected(string value) + public void EventName_Set_Get_ReturnsExpected(string? value) { var fieldReference = new CodeFieldReferenceExpression(); fieldReference.FieldName = value; diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeGotoStatement.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeGotoStatement.cs index 00568dceca240f..a1d73dcb5ffd50 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeGotoStatement.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeGotoStatement.cs @@ -26,7 +26,7 @@ public void Ctor_String(string label) [Theory] [InlineData(null)] [InlineData("")] - public void Ctor_StringNullOrEmpty_ThrowsArgumentNullException(string value) + public void Ctor_StringNullOrEmpty_ThrowsArgumentNullException(string? value) { AssertExtensions.Throws("value", () => new CodeGotoStatement(value)); } @@ -44,7 +44,7 @@ public void Label_Set_Get_ReturnsExpected(string value) [Theory] [InlineData(null)] [InlineData("")] - public void Label_SetNullOrEmpty_ThrowsArgumentNullException(string value) + public void Label_SetNullOrEmpty_ThrowsArgumentNullException(string? value) { var gotoStatement = new CodeGotoStatement(); AssertExtensions.Throws("value", () => gotoStatement.Label = value); diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/CodePropertyReferenceExpressionTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/CodePropertyReferenceExpressionTests.cs index 463662afec9e33..9efbe0f448af1f 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/CodePropertyReferenceExpressionTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/CodePropertyReferenceExpressionTests.cs @@ -36,7 +36,7 @@ public void Ctor(CodeExpression targetObject, string PropertyName) [InlineData(null)] [InlineData("")] [InlineData("PropertyName")] - public void EventName_Set_Get_ReturnsExpected(string value) + public void EventName_Set_Get_ReturnsExpected(string? value) { var propertyReference = new CodePropertyReferenceExpression(); propertyReference.PropertyName = value; diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeSnippetTypeMemberTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeSnippetTypeMemberTests.cs index dd361323ed75a3..9184277acae385 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeSnippetTypeMemberTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeSnippetTypeMemberTests.cs @@ -18,7 +18,7 @@ public void Ctor_Default() [InlineData(null)] [InlineData("")] [InlineData("Text")] - public void Ctor_String(string value) + public void Ctor_String(string? value) { var snippet = new CodeSnippetTypeMember(value); Assert.Equal(value ?? string.Empty, snippet.Text); @@ -28,7 +28,7 @@ public void Ctor_String(string value) [InlineData(null)] [InlineData("")] [InlineData("Text")] - public void Text_Set_Get_ReturnsExpected(string value) + public void Text_Set_Get_ReturnsExpected(string? value) { var snippet = new CodeSnippetTypeMember(); snippet.Text = value; diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeTypeMemberTestBase.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeTypeMemberTestBase.cs index 918d128b1eb5f3..bc2272ec1cef49 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeTypeMemberTestBase.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeTypeMemberTestBase.cs @@ -28,7 +28,7 @@ public void Ctor_Default_MemberBase() [InlineData("Name")] [InlineData("")] [InlineData(null)] - public void Name_Set_Get_ReturnsExpected(string value) + public void Name_Set_Get_ReturnsExpected(string? value) { CodeTypeMember member = new T() { Name = value }; Assert.Equal(value ?? string.Empty, member.Name); diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeTypeParameterCollectionTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeTypeParameterCollectionTests.cs index a0f6603215e123..211418a9acbf1d 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/CodeTypeParameterCollectionTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/CodeTypeParameterCollectionTests.cs @@ -34,7 +34,7 @@ public class CodeTypeParameterCollectionTests : CodeCollectionTestBase @@ -50,7 +50,7 @@ public void ContinueOnNewLine_InvokeWithOutput_Appends(string st, string expecte [InlineData(null)] [InlineData("")] [InlineData("st")] - public void ContinueOnNewLine_InvokeWithoutOutput_ThrowsNullReferenceException(string st) + public void ContinueOnNewLine_InvokeWithoutOutput_ThrowsNullReferenceException(string? st) { CodeGeneratorTests generator = this; Assert.Throws(() => generator.ContinueOnNewLine(st)); @@ -409,7 +409,7 @@ public void GenerateCodeFromMember_NullWriter_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("text")] - public void GenerateCommentStatement_Invoke_CallsCorrectMethod(string text) + public void GenerateCommentStatement_Invoke_CallsCorrectMethod(string? text) { CodeGeneratorTests generator = this; var e = new CodeCommentStatement(text); @@ -443,7 +443,7 @@ public void GenerateCommentStatement_NullEComment_ThrowsArgumentException() [InlineData(null)] [InlineData("")] [InlineData("text")] - public void GenerateCommentStatements_InvokeNonEmpty_CallsCorrectMethod(string text) + public void GenerateCommentStatements_InvokeNonEmpty_CallsCorrectMethod(string? text) { CodeGeneratorTests generator = this; generator.GenerateCommentStatementsAction = (actualE, baseMethod) => baseMethod(actualE); @@ -1687,7 +1687,7 @@ public void GeneratePrimitiveExpression_InvokeDecimal_Success() [InlineData(null, "")] [InlineData("", "")] [InlineData("result", "result")] - public void GeneratePrimitiveExpression_InvokeString_Success(string result, string expected) + public void GeneratePrimitiveExpression_InvokeString_Success(string? result, string expected) { CodeGeneratorTests generator = this; generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); @@ -1794,7 +1794,7 @@ public void GenerateSingleFloatValue_InvokeWithoutWriter_ThrowsNullReferenceExce [InlineData(null, "")] [InlineData("", "")] [InlineData("value", "value")] - public void GenerateSnippetCompileUnit_Invoke_Success(string value, string expected) + public void GenerateSnippetCompileUnit_Invoke_Success(string? value, string expected) { CodeGeneratorTests generator = this; var e = new CodeSnippetCompileUnit(value); @@ -1872,7 +1872,7 @@ public void GenerateSnippetCompileUnit_InvokeWithoutOutput_ThrowsNullReferenceEx [InlineData(null, "")] [InlineData("", "")] [InlineData("value", "value")] - public void GenerateSnippetStatement_Invoke_Success(string value, string expected) + public void GenerateSnippetStatement_Invoke_Success(string? value, string expected) { CodeGeneratorTests generator = this; PerformActionWithOutput(writer => @@ -2661,7 +2661,7 @@ public void GenerateTypes_NullValueInE_ThrowsArgumentException() [InlineData("\n", false)] [InlineData("a\n", false)] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] - public void IsValidLanguageIndependentIdentifier_Invoke_ReturnsExpected(string value, bool expected) + public void IsValidLanguageIndependentIdentifier_Invoke_ReturnsExpected(string? value, bool expected) { Assert.Equal(expected, CodeGenerator.IsValidLanguageIndependentIdentifier(value)); } @@ -2670,7 +2670,7 @@ public void IsValidLanguageIndependentIdentifier_Invoke_ReturnsExpected(string v [InlineData(null, "1")] [InlineData("", "1")] [InlineData("name", "name=1")] - public void OutputAttributeArgument_Invoke_Success(string name, string expected) + public void OutputAttributeArgument_Invoke_Success(string? name, string expected) { CodeGeneratorTests generator = this; PerformActionWithOutput(writer => @@ -2713,7 +2713,7 @@ public void OutputAttributeArgument_NullArgValue_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("name")] - public void OutputAttributeArgument_InvokeNonNullNameWithoutOutput_ThrowsNullReferenceException(string name) + public void OutputAttributeArgument_InvokeNonNullNameWithoutOutput_ThrowsNullReferenceException(string? name) { CodeGeneratorTests generator = this; var arg = new CodeAttributeArgument(name, new CodePrimitiveExpression(1)); @@ -2927,7 +2927,7 @@ public void OutputFieldScopeModifier_InvokeWithoutOutputInvalid_Nop(MemberAttrib [InlineData(null, "")] [InlineData("", "")] [InlineData("ident", "ident")] - public void OutputIdentifier_InvokeWithOutput_Appends(string st, string expected) + public void OutputIdentifier_InvokeWithOutput_Appends(string? st, string expected) { CodeGeneratorTests generator = this; generator.PerformActionWithOutput(writer => @@ -2942,7 +2942,7 @@ public void OutputIdentifier_InvokeWithOutput_Appends(string st, string expected [InlineData(null)] [InlineData("")] [InlineData("ident")] - public void OutputIdentifier_InvokeWithoutOutput_ThrowsNullReferenceException(string ident) + public void OutputIdentifier_InvokeWithoutOutput_ThrowsNullReferenceException(string? ident) { CodeGeneratorTests generator = this; generator.OutputIdentifierAction = (actualSt, baseMethod) => baseMethod(actualSt); @@ -3541,7 +3541,7 @@ public void OutputTypeAttributes_InvokeWithoutWriter_ThrowsNullReferenceExceptio [InlineData(null)] [InlineData("")] [InlineData("value")] - public void ValidateIdentifier_InvokeValid_Nop(string value) + public void ValidateIdentifier_InvokeValid_Nop(string? value) { CodeGeneratorTests generator = this; int isValidIdentifierCallCount = 0; @@ -3561,7 +3561,7 @@ public void ValidateIdentifier_InvokeValid_Nop(string value) [InlineData("")] [InlineData("value")] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] - public void ValidateIdentifier_InvokeInvalid_ThrowsArgumentException(string value) + public void ValidateIdentifier_InvokeInvalid_ThrowsArgumentException(string? value) { CodeGeneratorTests generator = this; int isValidIdentifierCallCount = 0; @@ -3586,7 +3586,7 @@ public void ValidateIdentifier_InvokeInvalid_ThrowsArgumentException(string valu [InlineData("identifier", null)] [InlineData("identifier", "")] [InlineData("identifier", "escapedIdentifier")] - public void ICodeGeneratorCreateEscapedIdentifier_Invoke_ReturnsExpected(string value, string result) + public void ICodeGeneratorCreateEscapedIdentifier_Invoke_ReturnsExpected(string? value, string? result) { CodeGeneratorTests generator = this; int callCount = 0; @@ -3611,7 +3611,7 @@ public void ICodeGeneratorCreateEscapedIdentifier_Invoke_ReturnsExpected(string [InlineData("identifier", null)] [InlineData("identifier", "")] [InlineData("identifier", "validIdentifier")] - public void ICodeGeneratorCreateValidIdentifier_Invoke_ReturnsExpected(string value, string result) + public void ICodeGeneratorCreateValidIdentifier_Invoke_ReturnsExpected(string? value, string? result) { CodeGeneratorTests generator = this; int callCount = 0; @@ -3710,7 +3710,7 @@ public void ICodeGeneratorSupports_Invoke_ReturnsExpected(GeneratorSupport suppo [InlineData(null)] [InlineData("")] [InlineData("value")] - public void ICodeGeneratorValidateIdentifier_InvokeValid_Nop(string value) + public void ICodeGeneratorValidateIdentifier_InvokeValid_Nop(string? value) { CodeGeneratorTests generator = this; int isValidIdentifierCallCount = 0; @@ -3731,7 +3731,7 @@ public void ICodeGeneratorValidateIdentifier_InvokeValid_Nop(string value) [InlineData("")] [InlineData("value")] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] - public void ICodeGeneratorValidateIdentifier_InvokeInvalid_ThrowsArgumentException(string value) + public void ICodeGeneratorValidateIdentifier_InvokeInvalid_ThrowsArgumentException(string? value) { CodeGeneratorTests generator = this; int isValidIdentifierCallCount = 0; diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerErrorTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerErrorTests.cs index aa1bd246449807..8feb6d45941ec6 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerErrorTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerErrorTests.cs @@ -23,7 +23,7 @@ public void Ctor_Default() [InlineData(null, 0, 0, null, null)] [InlineData("", -1, -1, "", "")] [InlineData("fileName", 1, 1, "errorNumber", "errorText")] - public void Ctor_String_Int_Int_String_String(string fileName, int line, int column, string errorNumber, string errorText) + public void Ctor_String_Int_Int_String_String(string? fileName, int line, int column, string? errorNumber, string? errorText) { var error = new CompilerError(fileName, line, column, errorNumber, errorText); Assert.Equal(column, error.Column); diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs index f36b765421ba4e..b550a80f0bcdf3 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs @@ -64,7 +64,7 @@ public void CompiledAssembly_Set_GetReturnsExpected(Assembly value) [InlineData(null)] [InlineData("")] [InlineData("name")] - public void PathToAssembly_Set_GetReturnsExpected(string value) + public void PathToAssembly_Set_GetReturnsExpected(string? value) { var results = new CompilerResults(null) { PathToAssembly = value }; Assert.Same(value, results.PathToAssembly); diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/TempFileCollectionTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/TempFileCollectionTests.cs index 0fce53d4f8772d..6385422015123f 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/TempFileCollectionTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/TempFileCollectionTests.cs @@ -59,7 +59,7 @@ public void Ctor_Empty() [InlineData(null)] [InlineData("")] [InlineData("TempDir")] - public void Ctor_String(string tempDir) + public void Ctor_String(string? tempDir) { var collection = new TempFileCollection(tempDir); Assert.Equal(0, collection.Count); @@ -71,7 +71,7 @@ public void Ctor_String(string tempDir) [InlineData(null, false)] [InlineData("", true)] [InlineData("TempDir", false)] - public void Ctor_String_Bool(string tempDir, bool keepFiles) + public void Ctor_String_Bool(string? tempDir, bool keepFiles) { var collection = new TempFileCollection(tempDir, keepFiles); Assert.Equal(0, collection.Count); @@ -116,7 +116,7 @@ public void AddFileExtension() [Theory] [InlineData(null)] [InlineData("")] - public void AddExtension_InvalidFileExtension_ThrowsArgumentException(string fileExtension) + public void AddExtension_InvalidFileExtension_ThrowsArgumentException(string? fileExtension) { using (var collection = new TempFileCollection()) { @@ -199,7 +199,7 @@ public void AddFile_MultipleFiles_DeletesAllIfKeepFilesFalse(bool keepFiles) [Theory] [InlineData(null)] [InlineData("")] - public void AddFile_InvalidFileName_ThrowsArgumentException(string fileName) + public void AddFile_InvalidFileName_ThrowsArgumentException(string? fileName) { using (var collection = new TempFileCollection()) { diff --git a/src/libraries/System.Collections.Immutable/System.Collections.Immutable.slnx b/src/libraries/System.Collections.Immutable/System.Collections.Immutable.slnx index 4cc5852ee5a38b..added1e80b5c9f 100644 --- a/src/libraries/System.Collections.Immutable/System.Collections.Immutable.slnx +++ b/src/libraries/System.Collections.Immutable/System.Collections.Immutable.slnx @@ -1,32 +1,322 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj b/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj index 635a3217a35c0f..a6a8b0eba2912d 100644 --- a/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj +++ b/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj @@ -169,12 +169,12 @@ The System.Collections.Immutable library is built-in as part of the shared frame - - - - - - + + + + + + diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs index 0793b3d12f7315..198b3459655df1 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs @@ -4,7 +4,7 @@ using System.Buffers; using System.Collections.Generic; using System.Diagnostics; -#if !NET8_0_OR_GREATER +#if !NET using System.Runtime.CompilerServices; #endif @@ -201,7 +201,7 @@ private static bool AreAllAscii(ReadOnlySpan strings) internal static unsafe bool IsAllAscii(ReadOnlySpan s) { -#if NET8_0_OR_GREATER +#if NET return System.Text.Ascii.IsValid(s); #else fixed (char* src = s) @@ -238,14 +238,14 @@ internal static unsafe bool IsAllAscii(ReadOnlySpan s) #endif } -#if NET8_0_OR_GREATER +#if NET private static readonly SearchValues s_asciiLetters = SearchValues.Create("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); #endif internal static bool ContainsAnyAsciiLetters(ReadOnlySpan s) { Debug.Assert(IsAllAscii(s)); -#if NET8_0_OR_GREATER +#if NET return s.ContainsAny(s_asciiLetters); #else foreach (char c in s) diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.Builder.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.Builder.cs index 0476b66430d24e..a78409ee75c6a8 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.Builder.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableDictionary_2.Builder.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Threading; namespace System.Collections.Immutable { @@ -56,11 +57,6 @@ public sealed class Builder : IDictionary, IReadOnlyDictionary private int _version; - /// - /// The object callers may use to synchronize access to this collection. - /// - private object? _syncRoot; - /// /// Initializes a new instance of the class. /// @@ -251,18 +247,8 @@ ICollection IDictionary.Values /// /// An object that can be used to synchronize access to the . [DebuggerBrowsable(DebuggerBrowsableState.Never)] - object ICollection.SyncRoot - { - get - { - if (_syncRoot == null) - { - Threading.Interlocked.CompareExchange(ref _syncRoot, new object(), null); - } - - return _syncRoot; - } - } + object ICollection.SyncRoot => + field ?? Interlocked.CompareExchange(ref field, new object(), null) ?? field; /// /// Gets a value indicating whether access to the is synchronized (thread safe). diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Builder.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Builder.cs index fc75f69a594d6c..77021fc61681d7 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Builder.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Builder.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Threading; namespace System.Collections.Immutable { @@ -46,11 +47,6 @@ public sealed class Builder : IList, IList, IReadOnlyList /// private int _version; - /// - /// The object callers may use to synchronize access to this collection. - /// - private object? _syncRoot; - /// /// Initializes a new instance of the class. /// @@ -1159,18 +1155,8 @@ bool ICollection.IsSynchronized /// /// An object that can be used to synchronize access to the . [DebuggerBrowsable(DebuggerBrowsableState.Never)] - object ICollection.SyncRoot - { - get - { - if (_syncRoot == null) - { - System.Threading.Interlocked.CompareExchange(ref _syncRoot, new object(), null); - } - - return _syncRoot; - } - } + object ICollection.SyncRoot => + field ?? Interlocked.CompareExchange(ref field, new object(), null) ?? field; #endregion } } @@ -1185,11 +1171,6 @@ internal sealed class ImmutableListBuilderDebuggerProxy /// private readonly ImmutableList.Builder _list; - /// - /// The simple view of the collection. - /// - private T[]? _cachedContents; - /// /// Initializes a new instance of the class. /// @@ -1204,6 +1185,6 @@ public ImmutableListBuilderDebuggerProxy(ImmutableList.Builder builder) /// Gets a simple debugger-viewable list. /// [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] - public T[] Contents => _cachedContents ??= _list.ToArray(_list.Count); + public T[] Contents => field ??= _list.ToArray(_list.Count); } } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedDictionary_2.Builder.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedDictionary_2.Builder.cs index ff5fe9ae030587..2f273499239656 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedDictionary_2.Builder.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedDictionary_2.Builder.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Threading; namespace System.Collections.Immutable { @@ -59,11 +60,6 @@ public sealed class Builder : IDictionary, IReadOnlyDictionary private int _version; - /// - /// The object callers may use to synchronize access to this collection. - /// - private object? _syncRoot; - /// /// Initializes a new instance of the class. /// @@ -262,18 +258,8 @@ ICollection IDictionary.Values /// /// An object that can be used to synchronize access to the . [DebuggerBrowsable(DebuggerBrowsableState.Never)] - object ICollection.SyncRoot - { - get - { - if (_syncRoot == null) - { - Threading.Interlocked.CompareExchange(ref _syncRoot, new object(), null); - } - - return _syncRoot; - } - } + object ICollection.SyncRoot => + field ?? Interlocked.CompareExchange(ref field, new object(), null) ?? field; /// /// Gets a value indicating whether access to the is synchronized (thread safe). diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.Builder.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.Builder.cs index 2f0a963972d081..1c3a778a5bdc6f 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.Builder.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.Builder.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Threading; namespace System.Collections.Immutable { @@ -51,11 +52,6 @@ public sealed class Builder : IReadOnlyCollection, ISet, ICollection /// private int _version; - /// - /// The object callers may use to synchronize access to this collection. - /// - private object? _syncRoot; - /// /// Initializes a new instance of the class. /// @@ -505,18 +501,8 @@ bool ICollection.IsSynchronized /// /// An object that can be used to synchronize access to the . [DebuggerBrowsable(DebuggerBrowsableState.Never)] - object ICollection.SyncRoot - { - get - { - if (_syncRoot == null) - { - Threading.Interlocked.CompareExchange(ref _syncRoot, new object(), null); - } - - return _syncRoot; - } - } + object ICollection.SyncRoot => + field ?? Interlocked.CompareExchange(ref field, new object(), null) ?? field; #endregion } } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs index b6f3bf81b0f105..902e9168872cf4 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs @@ -1191,7 +1191,7 @@ private ImmutableSortedSet LeafToRootRefill(ReadOnlySpan addedItems) list = new List(this.Count + addedItems.Length); list.AddRange(this); } -#if NET8_0_OR_GREATER +#if NET list.AddRange(addedItems); #else foreach (var item in addedItems) diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetBuilderTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetBuilderTest.cs index 6ec30b901014db..e4d7464cea2124 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetBuilderTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetBuilderTest.cs @@ -99,6 +99,7 @@ public void IndexOf() [Fact] public void EnumerateBuilderWhileMutating() { +#pragma warning disable xUnit2027 // Comparison of sets to linear containers have undefined results ImmutableSortedSet.Builder builder = ImmutableSortedSet.Empty.Union(Enumerable.Range(1, 10)).ToBuilder(); Assert.Equal(Enumerable.Range(1, 10), builder); @@ -116,6 +117,7 @@ public void EnumerateBuilderWhileMutating() // Verify that by obtaining a new enumerator, we can enumerate all the contents. Assert.Equal(Enumerable.Range(1, 11), builder); +#pragma warning restore xUnit2027 } [Fact] diff --git a/src/libraries/System.Collections.NonGeneric/System.Collections.NonGeneric.slnx b/src/libraries/System.Collections.NonGeneric/System.Collections.NonGeneric.slnx index d2c4afe3f0a9a9..17a2b99e1e68b5 100644 --- a/src/libraries/System.Collections.NonGeneric/System.Collections.NonGeneric.slnx +++ b/src/libraries/System.Collections.NonGeneric/System.Collections.NonGeneric.slnx @@ -68,6 +68,14 @@ + + + + + + + + @@ -141,6 +149,14 @@ + + + + + + + + diff --git a/src/libraries/System.Collections.NonGeneric/src/System.Collections.NonGeneric.csproj b/src/libraries/System.Collections.NonGeneric/src/System.Collections.NonGeneric.csproj index 1bc456cd13ba3a..36301e8d8578ed 100644 --- a/src/libraries/System.Collections.NonGeneric/src/System.Collections.NonGeneric.csproj +++ b/src/libraries/System.Collections.NonGeneric/src/System.Collections.NonGeneric.csproj @@ -21,9 +21,9 @@ - - - + + + diff --git a/src/libraries/System.Collections.NonGeneric/src/System/Collections/CaseInsensitiveHashCodeProvider.cs b/src/libraries/System.Collections.NonGeneric/src/System/Collections/CaseInsensitiveHashCodeProvider.cs index 22bb48f8a1c2f0..724bd70d5bdde8 100644 --- a/src/libraries/System.Collections.NonGeneric/src/System/Collections/CaseInsensitiveHashCodeProvider.cs +++ b/src/libraries/System.Collections.NonGeneric/src/System/Collections/CaseInsensitiveHashCodeProvider.cs @@ -12,7 +12,6 @@ namespace System.Collections [Obsolete("CaseInsensitiveHashCodeProvider has been deprecated. Use StringComparer instead.")] public class CaseInsensitiveHashCodeProvider : IHashCodeProvider { - private static CaseInsensitiveHashCodeProvider? s_invariantCaseInsensitiveHashCodeProvider; private readonly CompareInfo _compareInfo; public CaseInsensitiveHashCodeProvider() @@ -29,7 +28,7 @@ public CaseInsensitiveHashCodeProvider(CultureInfo culture) public static CaseInsensitiveHashCodeProvider Default => new CaseInsensitiveHashCodeProvider(); - public static CaseInsensitiveHashCodeProvider DefaultInvariant => s_invariantCaseInsensitiveHashCodeProvider ??= new CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture); + public static CaseInsensitiveHashCodeProvider DefaultInvariant => field ??= new CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture); public int GetHashCode(object obj) { diff --git a/src/libraries/System.Collections.NonGeneric/src/System/Collections/ReadOnlyCollectionBase.cs b/src/libraries/System.Collections.NonGeneric/src/System/Collections/ReadOnlyCollectionBase.cs index 3cf850e4966c8b..5651d5ff2a3b16 100644 --- a/src/libraries/System.Collections.NonGeneric/src/System/Collections/ReadOnlyCollectionBase.cs +++ b/src/libraries/System.Collections.NonGeneric/src/System/Collections/ReadOnlyCollectionBase.cs @@ -16,9 +16,7 @@ namespace System.Collections // Useful base class for typed readonly collections where items derive from object public abstract class ReadOnlyCollectionBase : ICollection { - private ArrayList? _list; - - protected ArrayList InnerList => _list ??= new ArrayList(); + protected ArrayList InnerList => field ??= new ArrayList(); public virtual int Count { diff --git a/src/libraries/System.Collections.NonGeneric/tests/CaseInsensitiveComparerTests.cs b/src/libraries/System.Collections.NonGeneric/tests/CaseInsensitiveComparerTests.cs index 81dcc28a9165e7..dc16af257bf186 100644 --- a/src/libraries/System.Collections.NonGeneric/tests/CaseInsensitiveComparerTests.cs +++ b/src/libraries/System.Collections.NonGeneric/tests/CaseInsensitiveComparerTests.cs @@ -24,7 +24,7 @@ public class CaseInsensitiveComparerTests [InlineData(5, null, 1)] [InlineData(null, 5, -1)] [InlineData(null, null, 0)] - public void Ctor_Empty_Compare(object a, object b, int expected) + public void Ctor_Empty_Compare(object? a, object? b, int expected) { CaseInsensitiveComparer comparer = new CaseInsensitiveComparer(); Assert.Equal(expected, Math.Sign(comparer.Compare(a, b))); @@ -43,7 +43,7 @@ public void Ctor_Empty_Compare(object a, object b, int expected) [InlineData(5, null, 1)] [InlineData(null, 5, -1)] [InlineData(null, null, 0)] - public void Ctor_CultureInfo_Compare(object a, object b, int expected) + public void Ctor_CultureInfo_Compare(object? a, object? b, int expected) { var cultureNames = Helpers.TestCultureNames; @@ -118,7 +118,7 @@ public void Ctor_CultureInfo_NullCulture_ThrowsArgumentNullException() [InlineData(5, null, 1)] [InlineData(null, 5, -1)] [InlineData(null, null, 0)] - public void DefaultInvariant_Compare(object a, object b, int expected) + public void DefaultInvariant_Compare(object? a, object? b, int expected) { var cultureNames = Helpers.TestCultureNames; @@ -157,7 +157,7 @@ public void DefaultInvariant_Compare(object a, object b, int expected) [InlineData(5, null, 1)] [InlineData(null, 5, -1)] [InlineData(null, null, 0)] - public void Default_Compare(object a, object b, int expected) + public void Default_Compare(object? a, object? b, int expected) { Assert.Equal(expected, Math.Sign(CaseInsensitiveComparer.Default.Compare(a, b))); } diff --git a/src/libraries/System.Collections.NonGeneric/tests/ComparerTests.cs b/src/libraries/System.Collections.NonGeneric/tests/ComparerTests.cs index 98662f8152eca9..371aa6e923a4d2 100644 --- a/src/libraries/System.Collections.NonGeneric/tests/ComparerTests.cs +++ b/src/libraries/System.Collections.NonGeneric/tests/ComparerTests.cs @@ -22,7 +22,7 @@ public class ComparerTests [InlineData(1, null, 1)] [InlineData(null, null, 0)] [InlineData(null, 1, -1)] - public void Ctor_CultureInfo(object a, object b, int expected) + public void Ctor_CultureInfo(object? a, object? b, int expected) { var culture = new CultureInfo("en-US"); var comparer = new Comparer(culture); diff --git a/src/libraries/System.Collections.Specialized/System.Collections.Specialized.slnx b/src/libraries/System.Collections.Specialized/System.Collections.Specialized.slnx index 9d554e6b09a836..8e5e7d51518db7 100644 --- a/src/libraries/System.Collections.Specialized/System.Collections.Specialized.slnx +++ b/src/libraries/System.Collections.Specialized/System.Collections.Specialized.slnx @@ -92,6 +92,14 @@ + + + + + + + + @@ -173,6 +181,22 @@ + + + + + + + + + + + + + + + + @@ -181,6 +205,22 @@ + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Collections.Specialized/src/System.Collections.Specialized.csproj b/src/libraries/System.Collections.Specialized/src/System.Collections.Specialized.csproj index 4301d885411c68..cd7438399e8b23 100644 --- a/src/libraries/System.Collections.Specialized/src/System.Collections.Specialized.csproj +++ b/src/libraries/System.Collections.Specialized/src/System.Collections.Specialized.csproj @@ -22,9 +22,9 @@ - - - + + + diff --git a/src/libraries/System.Collections.Specialized/tests/StringDictionary/StringDictionary.ContainsValueTests.cs b/src/libraries/System.Collections.Specialized/tests/StringDictionary/StringDictionary.ContainsValueTests.cs index 164991333fb299..8d694825ab9fd6 100644 --- a/src/libraries/System.Collections.Specialized/tests/StringDictionary/StringDictionary.ContainsValueTests.cs +++ b/src/libraries/System.Collections.Specialized/tests/StringDictionary/StringDictionary.ContainsValueTests.cs @@ -29,7 +29,7 @@ public void ContainsValue_NoSuchValue_ReturnsFalse(int count) [Theory] [InlineData("value")] [InlineData(null)] - public void ContainsValue_DuplicateValues(string value) + public void ContainsValue_DuplicateValues(string? value) { StringDictionary stringDictionary = new StringDictionary(); stringDictionary.Add("key1", value); diff --git a/src/libraries/System.Collections/System.Collections.slnx b/src/libraries/System.Collections/System.Collections.slnx index e0407fa770a604..63b585e0c46441 100644 --- a/src/libraries/System.Collections/System.Collections.slnx +++ b/src/libraries/System.Collections/System.Collections.slnx @@ -68,6 +68,14 @@ + + + + + + + + @@ -141,6 +149,14 @@ + + + + + + + + diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/OrderedDictionary.cs b/src/libraries/System.Collections/src/System/Collections/Generic/OrderedDictionary.cs index 689fec12f12d6c..8eec08838be6ba 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/OrderedDictionary.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/OrderedDictionary.cs @@ -52,11 +52,6 @@ class OrderedDictionary : /// Multiplier used on 64-bit to enable faster % operations. private ulong _fastModMultiplier; - /// Lazily-initialized wrapper collection that serves up only the keys, in order. - private KeyCollection? _keys; - /// Lazily-initialized wrapper collection that serves up only the values, in order. - private ValueCollection? _values; - /// /// Initializes a new instance of the class that is empty, /// has the default initial capacity, and uses the default equality comparer for the key type. @@ -257,7 +252,7 @@ public IEqualityComparer Comparer bool IList.IsFixedSize => false; /// Gets a collection containing the keys in the . - public KeyCollection Keys => _keys ??= new(this); + public KeyCollection Keys => field ??= new(this); /// IEnumerable IReadOnlyDictionary.Keys => Keys; @@ -269,7 +264,7 @@ public IEqualityComparer Comparer ICollection IDictionary.Keys => Keys; /// Gets a collection containing the values in the . - public ValueCollection Values => _values ??= new(this); + public ValueCollection Values => field ??= new(this); /// IEnumerable IReadOnlyDictionary.Values => Values; diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/PriorityQueue.cs b/src/libraries/System.Collections/src/System/Collections/Generic/PriorityQueue.cs index c5f7c7e7e0c28d..158c6d0cb52753 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/PriorityQueue.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/PriorityQueue.cs @@ -30,11 +30,6 @@ public class PriorityQueue /// private readonly IComparer? _comparer; - /// - /// Lazily-initialized collection used to expose the contents of the queue. - /// - private UnorderedItemsCollection? _unorderedItems; - /// /// The number of nodes in the heap. /// @@ -188,7 +183,7 @@ public PriorityQueue(IEnumerable<(TElement Element, TPriority Priority)> items, /// The enumeration does not order items by priority, since that would require N * log(N) time and N space. /// Items are instead enumerated following the internal array heap layout. /// - public UnorderedItemsCollection UnorderedItems => _unorderedItems ??= new UnorderedItemsCollection(this); + public UnorderedItemsCollection UnorderedItems => field ??= new UnorderedItemsCollection(this); /// /// Adds the specified element with associated priority to the . @@ -1017,25 +1012,20 @@ public bool MoveNext() { PriorityQueue localQueue = _queue; - if (_version == localQueue._version && ((uint)_index < (uint)localQueue._size)) + if (_version != localQueue._version) { - _current = localQueue._nodes[_index]; - _index++; - return true; + ThrowHelper.ThrowVersionCheckFailed(); } - return MoveNextRare(); - } - - private bool MoveNextRare() - { - if (_version != _queue._version) + if ((uint)_index < (uint)localQueue._size) { - throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion); + _current = localQueue._nodes[_index]; + _index++; + return true; } - _index = _queue._size + 1; _current = default; + _index = -1; return false; } @@ -1049,7 +1039,7 @@ void IEnumerator.Reset() { if (_version != _queue._version) { - throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion); + ThrowHelper.ThrowVersionCheckFailed(); } _index = 0; diff --git a/src/libraries/System.Collections/tests/Generic/Dictionary/Dictionary.Generic.Tests.ConcurrentAccessDetection.cs b/src/libraries/System.Collections/tests/Generic/Dictionary/Dictionary.Generic.Tests.ConcurrentAccessDetection.cs index 1bfbe361b60391..6e465881483bf7 100644 --- a/src/libraries/System.Collections/tests/Generic/Dictionary/Dictionary.Generic.Tests.ConcurrentAccessDetection.cs +++ b/src/libraries/System.Collections/tests/Generic/Dictionary/Dictionary.Generic.Tests.ConcurrentAccessDetection.cs @@ -40,7 +40,7 @@ private async Task DictionaryConcurrentAccessDetection(Dictionary< [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(null)] [InlineData(typeof(CustomEqualityComparerInt32ValueType))] - public async Task DictionaryConcurrentAccessDetection_ValueTypeKey(Type comparerType) + public async Task DictionaryConcurrentAccessDetection_ValueTypeKey(Type? comparerType) { IEqualityComparer customComparer = null; @@ -62,7 +62,7 @@ await DictionaryConcurrentAccessDetection(dic, [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(null)] [InlineData(typeof(CustomEqualityComparerDummyRefType))] - public async Task DictionaryConcurrentAccessDetection_ReferenceTypeKey(Type comparerType) + public async Task DictionaryConcurrentAccessDetection_ReferenceTypeKey(Type? comparerType) { IEqualityComparer customComparer = null; diff --git a/src/libraries/System.Collections/tests/Generic/Queue/Queue.Generic.Tests.cs b/src/libraries/System.Collections/tests/Generic/Queue/Queue.Generic.Tests.cs index e5adef0e878d7a..c89268887f4dbc 100644 --- a/src/libraries/System.Collections/tests/Generic/Queue/Queue.Generic.Tests.cs +++ b/src/libraries/System.Collections/tests/Generic/Queue/Queue.Generic.Tests.cs @@ -51,7 +51,7 @@ protected override IEnumerable GenericIEnumerableFactory(int count) protected override void CopyTo(IEnumerable enumerable, T[] array, int index) => ((Queue)enumerable).CopyTo(array, index); protected override bool Remove(IEnumerable enumerable) => ((Queue)enumerable).TryDequeue(out _); protected override bool Enumerator_Empty_UsesSingletonInstance => true; - protected override bool Enumerator_Current_UndefinedOperation_Throws => true; + protected override bool Enumerator_Empty_Current_UndefinedOperation_Throws => true; protected override bool Enumerator_Empty_ModifiedDuringEnumeration_ThrowsInvalidOperationException => false; protected override Type IGenericSharedAPI_CopyTo_IndexLargerThanArrayCount_ThrowType => typeof(ArgumentOutOfRangeException); diff --git a/src/libraries/System.Collections/tests/Generic/Queue/Queue.Tests.cs b/src/libraries/System.Collections/tests/Generic/Queue/Queue.Tests.cs index 62b855d3f5dc74..c82e9f5df8994d 100644 --- a/src/libraries/System.Collections/tests/Generic/Queue/Queue.Tests.cs +++ b/src/libraries/System.Collections/tests/Generic/Queue/Queue.Tests.cs @@ -27,7 +27,7 @@ protected override ICollection NonGenericICollectionFactory() return new Queue(); } - protected override bool Enumerator_Current_UndefinedOperation_Throws => true; + protected override bool Enumerator_Empty_Current_UndefinedOperation_Throw => true; protected override Type ICollection_NonGeneric_CopyTo_IndexLargerThanArrayCount_ThrowType => typeof(ArgumentOutOfRangeException); diff --git a/src/libraries/System.ComponentModel.Annotations/System.ComponentModel.Annotations.slnx b/src/libraries/System.ComponentModel.Annotations/System.ComponentModel.Annotations.slnx index b3058897fbb32b..907cd795a9241f 100644 --- a/src/libraries/System.ComponentModel.Annotations/System.ComponentModel.Annotations.slnx +++ b/src/libraries/System.ComponentModel.Annotations/System.ComponentModel.Annotations.slnx @@ -18,6 +18,22 @@ + + + + + + + + + + + + + + + + @@ -42,8 +58,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -52,6 +92,14 @@ + + + + + + + + @@ -60,6 +108,14 @@ + + + + + + + + @@ -92,6 +148,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -100,6 +188,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -116,6 +332,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -124,7 +380,7 @@ - + @@ -132,7 +388,7 @@ - + @@ -140,7 +396,7 @@ - + @@ -148,7 +404,7 @@ - + @@ -156,16 +412,15 @@ - - - - - - - - + + + + + + + - + @@ -173,7 +428,7 @@ - + @@ -181,7 +436,7 @@ - + @@ -189,7 +444,7 @@ - + @@ -197,7 +452,7 @@ - + @@ -205,7 +460,7 @@ - + @@ -213,7 +468,7 @@ - + @@ -221,7 +476,568 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.ComponentModel.Annotations/src/System.ComponentModel.Annotations.csproj b/src/libraries/System.ComponentModel.Annotations/src/System.ComponentModel.Annotations.csproj index 3cbb94253c8e1f..cb998febaaab08 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System.ComponentModel.Annotations.csproj +++ b/src/libraries/System.ComponentModel.Annotations/src/System.ComponentModel.Annotations.csproj @@ -67,16 +67,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/libraries/System.ComponentModel.Composition.Registration/Directory.Build.props b/src/libraries/System.ComponentModel.Composition.Registration/Directory.Build.props index 798ccfd363e813..93a53093be2b00 100644 --- a/src/libraries/System.ComponentModel.Composition.Registration/Directory.Build.props +++ b/src/libraries/System.ComponentModel.Composition.Registration/Directory.Build.props @@ -2,5 +2,6 @@ ECMA + false diff --git a/src/libraries/System.ComponentModel.Composition.Registration/src/System.ComponentModel.Composition.Registration.csproj b/src/libraries/System.ComponentModel.Composition.Registration/src/System.ComponentModel.Composition.Registration.csproj index 530e2e89a7dd0e..b580a7534479c4 100644 --- a/src/libraries/System.ComponentModel.Composition.Registration/src/System.ComponentModel.Composition.Registration.csproj +++ b/src/libraries/System.ComponentModel.Composition.Registration/src/System.ComponentModel.Composition.Registration.csproj @@ -2,7 +2,6 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.1 - false false true true diff --git a/src/libraries/System.ComponentModel.Composition/Directory.Build.props b/src/libraries/System.ComponentModel.Composition/Directory.Build.props index 798ccfd363e813..db56d69d6c8b7d 100644 --- a/src/libraries/System.ComponentModel.Composition/Directory.Build.props +++ b/src/libraries/System.ComponentModel.Composition/Directory.Build.props @@ -2,5 +2,7 @@ ECMA + false + false diff --git a/src/libraries/System.ComponentModel.Composition/ref/System.ComponentModel.Composition.cs b/src/libraries/System.ComponentModel.Composition/ref/System.ComponentModel.Composition.cs index b9528f89e7a02b..c51c8bb868c7d8 100644 --- a/src/libraries/System.ComponentModel.Composition/ref/System.ComponentModel.Composition.cs +++ b/src/libraries/System.ComponentModel.Composition/ref/System.ComponentModel.Composition.cs @@ -55,7 +55,7 @@ public ChangeRejectedException(string? message, System.Exception? innerException public partial class CompositionContractMismatchException : System.Exception { public CompositionContractMismatchException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -145,7 +145,7 @@ public ImportAttribute(System.Type? contractType) { } public partial class ImportCardinalityMismatchException : System.Exception { public ImportCardinalityMismatchException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -543,7 +543,7 @@ protected ComposablePartDefinition() { } public partial class ComposablePartException : System.Exception { public ComposablePartException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -553,7 +553,7 @@ public ComposablePartException(string? message, System.ComponentModel.Compositio public ComposablePartException(string? message, System.ComponentModel.Composition.Primitives.ICompositionElement? element, System.Exception? innerException) { } public ComposablePartException(string? message, System.Exception? innerException) { } public System.ComponentModel.Composition.Primitives.ICompositionElement? Element { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj b/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj index 2f113db3e4cb5e..9172222222e872 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj +++ b/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj @@ -2,8 +2,6 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0 - false - false false true true diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/CompositionContractMismatchException.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/CompositionContractMismatchException.cs index 73b8f0b233529c..7109705145af1c 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/CompositionContractMismatchException.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/CompositionContractMismatchException.cs @@ -77,7 +77,7 @@ public CompositionContractMismatchException(string? message, Exception? innerExc /// /// contains a value that cannot be cast to the correct type. /// -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ImportCardinalityMismatchException.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ImportCardinalityMismatchException.cs index 898934ac298a25..2439528becb040 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ImportCardinalityMismatchException.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ImportCardinalityMismatchException.cs @@ -80,7 +80,7 @@ public ImportCardinalityMismatchException(string? message, Exception? innerExcep /// /// contains a value that cannot be cast to the correct type. /// -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Primitives/ComposablePartException.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Primitives/ComposablePartException.cs index 95a0369cd02024..fe9ba3ae4b8236 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Primitives/ComposablePartException.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Primitives/ComposablePartException.cs @@ -47,7 +47,7 @@ public ComposablePartException() /// /// contains a value that cannot be cast to the correct type. /// -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -164,7 +164,7 @@ public ICompositionElement? Element /// /// is . /// -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberExportDefinition.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberExportDefinition.cs index 58adef95a8005b..3a1cad0370cfcc 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberExportDefinition.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberExportDefinition.cs @@ -12,7 +12,6 @@ internal sealed class ReflectionMemberExportDefinition : ExportDefinition, IComp private readonly LazyMemberInfo _member; private readonly ExportDefinition _exportDefinition; private readonly ICompositionElement? _origin; - private IDictionary? _metadata; public ReflectionMemberExportDefinition(LazyMemberInfo member, ExportDefinition exportDefinition, ICompositionElement? origin) { @@ -33,7 +32,7 @@ public LazyMemberInfo ExportingLazyMember get { return _member; } } - public override IDictionary Metadata => _metadata ??= _exportDefinition.Metadata.AsReadOnly(); + public override IDictionary Metadata => field ??= _exportDefinition.Metadata.AsReadOnly(); string ICompositionElement.DisplayName { diff --git a/src/libraries/System.ComponentModel.EventBasedAsync/System.ComponentModel.EventBasedAsync.slnx b/src/libraries/System.ComponentModel.EventBasedAsync/System.ComponentModel.EventBasedAsync.slnx index ef4dc2233ed53b..95885f8ef44680 100644 --- a/src/libraries/System.ComponentModel.EventBasedAsync/System.ComponentModel.EventBasedAsync.slnx +++ b/src/libraries/System.ComponentModel.EventBasedAsync/System.ComponentModel.EventBasedAsync.slnx @@ -1,35 +1,282 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.ComponentModel.EventBasedAsync/src/System.ComponentModel.EventBasedAsync.csproj b/src/libraries/System.ComponentModel.EventBasedAsync/src/System.ComponentModel.EventBasedAsync.csproj index a5d9913733b441..914718269b1f28 100644 --- a/src/libraries/System.ComponentModel.EventBasedAsync/src/System.ComponentModel.EventBasedAsync.csproj +++ b/src/libraries/System.ComponentModel.EventBasedAsync/src/System.ComponentModel.EventBasedAsync.csproj @@ -16,11 +16,11 @@ - - - - - + + + + + diff --git a/src/libraries/System.ComponentModel.EventBasedAsync/tests/DoWorkEventArgsTests.cs b/src/libraries/System.ComponentModel.EventBasedAsync/tests/DoWorkEventArgsTests.cs index a4360c62f29478..b881e9dc6c468f 100644 --- a/src/libraries/System.ComponentModel.EventBasedAsync/tests/DoWorkEventArgsTests.cs +++ b/src/libraries/System.ComponentModel.EventBasedAsync/tests/DoWorkEventArgsTests.cs @@ -10,7 +10,7 @@ public static class DoWorkEventArgsTests [Theory] [InlineData(null)] [InlineData("non null test argument")] - public static void CtorTest(object expectedArgument) + public static void CtorTest(object? expectedArgument) { var target = new DoWorkEventArgs(expectedArgument); Assert.Equal(expectedArgument, target.Argument); @@ -30,7 +30,7 @@ public static void CancelPropertyTest(bool expectedCancel) [Theory] [InlineData(null)] [InlineData("non null test result")] - public static void ResultPropertyTest(object expectedResult) + public static void ResultPropertyTest(object? expectedResult) { var target = new DoWorkEventArgs(null) { Result = expectedResult }; Assert.Equal(expectedResult, target.Result); diff --git a/src/libraries/System.ComponentModel.EventBasedAsync/tests/ProgressChangedEventArgsTests.cs b/src/libraries/System.ComponentModel.EventBasedAsync/tests/ProgressChangedEventArgsTests.cs index 40ce768981a669..5a5a655b13fa94 100644 --- a/src/libraries/System.ComponentModel.EventBasedAsync/tests/ProgressChangedEventArgsTests.cs +++ b/src/libraries/System.ComponentModel.EventBasedAsync/tests/ProgressChangedEventArgsTests.cs @@ -11,7 +11,7 @@ public static class ProgressChangedEventArgsTests [InlineData(int.MinValue, null)] [InlineData(0, "non null test state")] [InlineData(int.MaxValue, "non null test state")] - public static void CtorAcceptsValuesAsIs(int expectedPercentage, object expectedState) + public static void CtorAcceptsValuesAsIs(int expectedPercentage, object? expectedState) { var target = new ProgressChangedEventArgs(expectedPercentage, expectedState); Assert.Equal(expectedPercentage, target.ProgressPercentage); diff --git a/src/libraries/System.ComponentModel.EventBasedAsync/tests/RunWorkerCompletedEventArgsTests.cs b/src/libraries/System.ComponentModel.EventBasedAsync/tests/RunWorkerCompletedEventArgsTests.cs index 5b3d36c599cd32..42a5b17b8ec8c6 100644 --- a/src/libraries/System.ComponentModel.EventBasedAsync/tests/RunWorkerCompletedEventArgsTests.cs +++ b/src/libraries/System.ComponentModel.EventBasedAsync/tests/RunWorkerCompletedEventArgsTests.cs @@ -28,7 +28,7 @@ public static IEnumerable TestInput [Theory] [InlineData(null)] [InlineData("non null")] - public static void CtorTest(object expectedResult) + public static void CtorTest(object? expectedResult) { var target = new RunWorkerCompletedEventArgs(expectedResult, null, false); Assert.Same(expectedResult, target.Result); diff --git a/src/libraries/System.ComponentModel.Primitives/System.ComponentModel.Primitives.slnx b/src/libraries/System.ComponentModel.Primitives/System.ComponentModel.Primitives.slnx index c78ebf8015c8c9..d6a579622088e5 100644 --- a/src/libraries/System.ComponentModel.Primitives/System.ComponentModel.Primitives.slnx +++ b/src/libraries/System.ComponentModel.Primitives/System.ComponentModel.Primitives.slnx @@ -84,6 +84,14 @@ + + + + + + + + @@ -165,6 +173,14 @@ + + + + + + + + @@ -173,6 +189,22 @@ + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj b/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj index 2938d1e641264e..e7a68cd247695c 100644 --- a/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj +++ b/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj @@ -45,12 +45,12 @@ - - - - - - + + + + + + diff --git a/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/CategoryAttribute.cs b/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/CategoryAttribute.cs index fc06665da5ecfc..8f6560b821dc2e 100644 --- a/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/CategoryAttribute.cs +++ b/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/CategoryAttribute.cs @@ -12,21 +12,6 @@ namespace System.ComponentModel [AttributeUsage(AttributeTargets.All)] public class CategoryAttribute : Attribute { - private static CategoryAttribute? s_action; - private static CategoryAttribute? s_appearance; - private static CategoryAttribute? s_asynchronous; - private static CategoryAttribute? s_behavior; - private static CategoryAttribute? s_data; - private static CategoryAttribute? s_design; - private static CategoryAttribute? s_dragDrop; - private static CategoryAttribute? s_defAttr; - private static CategoryAttribute? s_focus; - private static CategoryAttribute? s_format; - private static CategoryAttribute? s_key; - private static CategoryAttribute? s_layout; - private static CategoryAttribute? s_mouse; - private static CategoryAttribute? s_windowStyle; - private volatile bool _localized; private readonly object _locker = new object(); @@ -39,114 +24,72 @@ public class CategoryAttribute : Attribute /// /// Gets the action category attribute. /// - public static CategoryAttribute Action - { - get => s_action ??= new CategoryAttribute(nameof(Action)); - } + public static CategoryAttribute Action => field ??= new CategoryAttribute(nameof(Action)); /// /// Gets the appearance category attribute. /// - public static CategoryAttribute Appearance - { - get => s_appearance ??= new CategoryAttribute(nameof(Appearance)); - } + public static CategoryAttribute Appearance => field ??= new CategoryAttribute(nameof(Appearance)); /// /// Gets the asynchronous category attribute. /// - public static CategoryAttribute Asynchronous - { - get => s_asynchronous ??= new CategoryAttribute(nameof(Asynchronous)); - } + public static CategoryAttribute Asynchronous => field ??= new CategoryAttribute(nameof(Asynchronous)); /// /// Gets the behavior category attribute. /// - public static CategoryAttribute Behavior - { - get => s_behavior ??= new CategoryAttribute(nameof(Behavior)); - } + public static CategoryAttribute Behavior => field ??= new CategoryAttribute(nameof(Behavior)); /// /// Gets the data category attribute. /// - public static CategoryAttribute Data - { - get => s_data ??= new CategoryAttribute(nameof(Data)); - } + public static CategoryAttribute Data => field ??= new CategoryAttribute(nameof(Data)); /// /// Gets the default category attribute. /// - public static CategoryAttribute Default - { - get => s_defAttr ??= new CategoryAttribute(); - } + public static CategoryAttribute Default => field ??= new CategoryAttribute(); /// /// Gets the design category attribute. /// - public static CategoryAttribute Design - { - get => s_design ??= new CategoryAttribute(nameof(Design)); - } + public static CategoryAttribute Design => field ??= new CategoryAttribute(nameof(Design)); /// /// Gets the drag and drop category attribute. /// - public static CategoryAttribute DragDrop - { - get => s_dragDrop ??= new CategoryAttribute(nameof(DragDrop)); - } + public static CategoryAttribute DragDrop => field ??= new CategoryAttribute(nameof(DragDrop)); /// /// Gets the focus category attribute. /// - public static CategoryAttribute Focus - { - get => s_focus ??= new CategoryAttribute(nameof(Focus)); - } + public static CategoryAttribute Focus => field ??= new CategoryAttribute(nameof(Focus)); /// /// Gets the format category attribute. /// - public static CategoryAttribute Format - { - get => s_format ??= new CategoryAttribute(nameof(Format)); - } + public static CategoryAttribute Format => field ??= new CategoryAttribute(nameof(Format)); /// /// Gets the keyboard category attribute. /// - public static CategoryAttribute Key - { - get => s_key ??= new CategoryAttribute(nameof(Key)); - } + public static CategoryAttribute Key => field ??= new CategoryAttribute(nameof(Key)); /// /// Gets the layout category attribute. /// - public static CategoryAttribute Layout - { - get => s_layout ??= new CategoryAttribute(nameof(Layout)); - } + public static CategoryAttribute Layout => field ??= new CategoryAttribute(nameof(Layout)); /// /// Gets the mouse category attribute. /// - public static CategoryAttribute Mouse - { - get => s_mouse ??= new CategoryAttribute(nameof(Mouse)); - } + public static CategoryAttribute Mouse => field ??= new CategoryAttribute(nameof(Mouse)); /// /// Gets the window style category attribute. /// - public static CategoryAttribute WindowStyle - { - get => s_windowStyle ??= new CategoryAttribute(nameof(WindowStyle)); - } + public static CategoryAttribute WindowStyle => field ??= new CategoryAttribute(nameof(WindowStyle)); /// /// Initializes a new instance of the diff --git a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/CategoryAttributeTests.cs b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/CategoryAttributeTests.cs index a30c2d80edfe0d..6001609fd25995 100644 --- a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/CategoryAttributeTests.cs +++ b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/CategoryAttributeTests.cs @@ -22,7 +22,7 @@ public void Ctor_Default() [InlineData("category", false)] [InlineData("Misc", true)] [InlineData("misc", false)] - public void Ctor_String(string category, bool expectedIsDefaultAttribute) + public void Ctor_String(string? category, bool expectedIsDefaultAttribute) { var attribute = new CategoryAttribute(category); Assert.Equal(category, attribute.Category); @@ -114,7 +114,7 @@ public void GetLocalizedString_InvokeValueExists_ReturnsNonEmpty(string value) [InlineData(null)] [InlineData("")] [InlineData("value")] - public void GetLocalizedString_InvokeNoSuchValue_ReturnsNull(string value) + public void GetLocalizedString_InvokeNoSuchValue_ReturnsNull(string? value) { var attribute = new SubCategoryAttribute(); Assert.Null(attribute.GetLocalizedString(value)); diff --git a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/ComponentTests.cs b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/ComponentTests.cs index d8ef543b7af159..245d152ee1d2a5 100644 --- a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/ComponentTests.cs +++ b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/ComponentTests.cs @@ -234,7 +234,7 @@ public void Finalize_Invoke_DoesNotCallDisposedEvent() [Theory] [InlineData(null)] [InlineData(typeof(int))] - public void GetService_InvokeWithoutSite_ReturnsNull(Type serviceType) + public void GetService_InvokeWithoutSite_ReturnsNull(Type? serviceType) { var component = new SubComponent(); Assert.Null(component.GetService(serviceType)); @@ -245,7 +245,7 @@ public void GetService_InvokeWithoutSite_ReturnsNull(Type serviceType) [InlineData(null, typeof(bool))] [InlineData(typeof(int), null)] [InlineData(typeof(int), typeof(bool))] - public void GetService_InvokeWithSite_ReturnsExpected(Type serviceType, Type result) + public void GetService_InvokeWithSite_ReturnsExpected(Type? serviceType, Type? result) { var site = new MockSite { diff --git a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DescriptionAttributeTests.cs b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DescriptionAttributeTests.cs index cc1ba193cd0905..584492a94448cb 100644 --- a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DescriptionAttributeTests.cs +++ b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DescriptionAttributeTests.cs @@ -21,7 +21,7 @@ public void Ctor_Default() [InlineData(null, false)] [InlineData("", true)] [InlineData("description", false)] - public void Ctor_String(string description, bool expectedIsDefaultAttribute) + public void Ctor_String(string? description, bool expectedIsDefaultAttribute) { var attribute = new SubDescriptionAttribute(description); Assert.Equal(description, attribute.Description); @@ -33,7 +33,7 @@ public void Ctor_String(string description, bool expectedIsDefaultAttribute) [InlineData(null)] [InlineData("")] [InlineData("descriptionValue")] - public void DescriptionValue_Set_GetReturnsExpected(string value) + public void DescriptionValue_Set_GetReturnsExpected(string? value) { var attribute = new SubDescriptionAttribute("Name") { diff --git a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DesignerAttributeTests.cs b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DesignerAttributeTests.cs index 4b7246eadd00dd..45820d63a187cf 100644 --- a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DesignerAttributeTests.cs +++ b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DesignerAttributeTests.cs @@ -35,7 +35,7 @@ public void Ctor_Type(Type designerType) [InlineData("", null)] [InlineData("designerTypeName", "")] [InlineData("designerTypeName.dll", "designerBaseTypeName")] - public void Ctor_String_String(string designerTypeName, string designerBaseTypeName) + public void Ctor_String_String(string designerTypeName, string? designerBaseTypeName) { var attribute = new DesignerAttribute(designerTypeName, designerBaseTypeName); Assert.Equal(designerTypeName, attribute.DesignerTypeName); diff --git a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DesignerCategoryAttributeTests.cs b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DesignerCategoryAttributeTests.cs index f51ef8eeabe62d..4e3dc312f4f404 100644 --- a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DesignerCategoryAttributeTests.cs +++ b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DesignerCategoryAttributeTests.cs @@ -21,7 +21,7 @@ public void Ctor_Default() [InlineData(null, false, "System.ComponentModel.DesignerCategoryAttribute")] [InlineData("", true, "System.ComponentModel.DesignerCategoryAttribute")] [InlineData("category", false, "System.ComponentModel.DesignerCategoryAttributecategory")] - public void Ctor_String(string category, bool expectedIsDefaultAttribute, string expectedTypeId) + public void Ctor_String(string? category, bool expectedIsDefaultAttribute, string expectedTypeId) { var attribute = new DesignerCategoryAttribute(category); Assert.Equal(category, attribute.Category); diff --git a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DisplayNameAttributeTests.cs b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DisplayNameAttributeTests.cs index c9dd2b9081b546..63d32a97624873 100644 --- a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DisplayNameAttributeTests.cs +++ b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/DisplayNameAttributeTests.cs @@ -21,7 +21,7 @@ public void Ctor_Default() [InlineData(null, false)] [InlineData("", true)] [InlineData("displayName", false)] - public void Ctor_String(string displayName, bool expectedIsDefaultAttribute) + public void Ctor_String(string? displayName, bool expectedIsDefaultAttribute) { var attribute = new SubDisplayNameAttribute(displayName); Assert.Equal(displayName, attribute.DisplayName); @@ -33,7 +33,7 @@ public void Ctor_String(string displayName, bool expectedIsDefaultAttribute) [InlineData(null)] [InlineData("")] [InlineData("displayName")] - public void DisplayNameValue_Set_GetReturnsExpected(string value) + public void DisplayNameValue_Set_GetReturnsExpected(string? value) { var attribute = new SubDisplayNameAttribute("Name") { diff --git a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/EditorAttributeTests.cs b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/EditorAttributeTests.cs index 8bf926578c1b8a..5c57ecfb46c8d6 100644 --- a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/EditorAttributeTests.cs +++ b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/EditorAttributeTests.cs @@ -21,7 +21,7 @@ public void Ctor_Default() [InlineData("", null)] [InlineData("typeName", "")] [InlineData("typeName.dll", "baseTypeName")] - public void Ctor_String_String(string typeName, string baseTypeName) + public void Ctor_String_String(string typeName, string? baseTypeName) { var attribute = new EditorAttribute(typeName, baseTypeName); Assert.Equal(typeName, attribute.EditorTypeName); diff --git a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/InitializationEventAttributeTests.cs b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/InitializationEventAttributeTests.cs index 49013a9a5980ae..f23046b5eb51c9 100644 --- a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/InitializationEventAttributeTests.cs +++ b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/InitializationEventAttributeTests.cs @@ -11,7 +11,7 @@ public class InitializationEventAttributeTests [InlineData(null)] [InlineData("")] [InlineData("test name")] - public void Ctor_EventName(string eventName) + public void Ctor_EventName(string? eventName) { var attribute = new InitializationEventAttribute(eventName); Assert.Equal(eventName, attribute.EventName); diff --git a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/InvalidEnumArgumentExceptionTests.cs b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/InvalidEnumArgumentExceptionTests.cs index 4b6187edc248df..2a90bfd6177650 100644 --- a/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/InvalidEnumArgumentExceptionTests.cs +++ b/src/libraries/System.ComponentModel.Primitives/tests/System/ComponentModel/InvalidEnumArgumentExceptionTests.cs @@ -25,7 +25,7 @@ public void Ctor_Default() [InlineData(null)] [InlineData("")] [InlineData("message")] - public void Ctor_Message(string message) + public void Ctor_Message(string? message) { var exception = new InvalidEnumArgumentException(message); if (message == null) @@ -68,7 +68,7 @@ public void Ctor_Message_InnerException(string message, Exception innerException [InlineData(null, 0, typeof(int))] [InlineData("", 1, typeof(int))] [InlineData("argumentName", int.MaxValue, typeof(int))] - public void Ctor_ArgumentName_InvalidValue_EnumClass(string argumentName, int invalidValue, Type enumClass) + public void Ctor_ArgumentName_InvalidValue_EnumClass(string? argumentName, int invalidValue, Type enumClass) { var exception = new InvalidEnumArgumentException(argumentName, invalidValue, enumClass); if (argumentName != null) diff --git a/src/libraries/System.ComponentModel.TypeConverter/System.ComponentModel.TypeConverter.slnx b/src/libraries/System.ComponentModel.TypeConverter/System.ComponentModel.TypeConverter.slnx index 77bb7634e1ca2d..fa39b599c48a16 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/System.ComponentModel.TypeConverter.slnx +++ b/src/libraries/System.ComponentModel.TypeConverter/System.ComponentModel.TypeConverter.slnx @@ -18,6 +18,14 @@ + + + + + + + + @@ -60,6 +68,22 @@ + + + + + + + + + + + + + + + + @@ -68,6 +92,14 @@ + + + + + + + + @@ -76,6 +108,14 @@ + + + + + + + + @@ -100,6 +140,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -108,6 +180,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -124,6 +324,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -132,7 +372,7 @@ - + @@ -140,7 +380,7 @@ - + @@ -148,7 +388,7 @@ - + @@ -156,7 +396,7 @@ - + @@ -164,16 +404,15 @@ - - - - - - - - + + + + + + + - + @@ -181,7 +420,7 @@ - + @@ -189,7 +428,7 @@ - + @@ -197,7 +436,7 @@ - + @@ -205,7 +444,7 @@ - + @@ -213,7 +452,7 @@ - + @@ -221,7 +460,7 @@ - + @@ -229,7 +468,560 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj b/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj index 874d860b1bdcc0..88b57d1c749a32 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj @@ -245,25 +245,25 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerOptionService.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerOptionService.cs index 2185bc5d1a7cbf..26269b11d1e300 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerOptionService.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerOptionService.cs @@ -12,16 +12,11 @@ namespace System.ComponentModel.Design /// public abstract class DesignerOptionService : IDesignerOptionService { - private DesignerOptionCollection? _options; - /// /// Returns the options collection for this service. There is /// always a global options collection that contains child collections. /// - public DesignerOptionCollection Options - { - get => _options ??= new DesignerOptionCollection(this, null, string.Empty, null); - } + public DesignerOptionCollection Options => field ??= new DesignerOptionCollection(this, null, string.Empty, null); /// /// Creates a new DesignerOptionCollection with the given name, and adds it to diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/EnumConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/EnumConverter.cs index c9d6d5a13a384f..11f0c1c6aab08c 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/EnumConverter.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/EnumConverter.cs @@ -87,10 +87,9 @@ private static long GetEnumValue(bool isUnderlyingTypeUInt64, object enumVal, Cu { bool isUnderlyingTypeUInt64 = Enum.GetUnderlyingType(EnumType) == typeof(ulong); long convertedValue = 0; - string[] values = strValue.Split(','); - foreach (string v in values) + foreach (Range v in strValue.AsSpan().Split(',')) { - convertedValue |= GetEnumValue(isUnderlyingTypeUInt64, Enum.Parse(EnumType, v, true), culture); + convertedValue |= GetEnumValue(isUnderlyingTypeUInt64, Enum.Parse(EnumType, strValue.AsSpan(v), true), culture); } return Enum.ToObject(EnumType, convertedValue); } diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ToolboxItemFilterAttribute.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ToolboxItemFilterAttribute.cs index 9dd92762ac76eb..88704ecb6ee819 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ToolboxItemFilterAttribute.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ToolboxItemFilterAttribute.cs @@ -43,8 +43,6 @@ namespace System.ComponentModel [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] public sealed class ToolboxItemFilterAttribute : Attribute { - private string? _typeId; - /// /// Initializes a new ToolboxItemFilterAttribute with the provide filter string and a filter type of /// "Allow". @@ -78,7 +76,7 @@ public ToolboxItemFilterAttribute(string filterString, ToolboxItemFilterType fil /// The unique identifier for this attribute. All ToolboxItemFilterAttributes with the same filter string /// are considered the same, so they return the same TypeId. /// - public override object TypeId => _typeId ??= GetType().FullName + FilterString; + public override object TypeId => field ??= GetType().FullName + FilterString; public override bool Equals([NotNullWhen(true)] object? obj) { diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/AddingNewEventArgsTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/AddingNewEventArgsTests.cs index 9d024f010d8f3c..e80facd9d56cdc 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/AddingNewEventArgsTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/AddingNewEventArgsTests.cs @@ -17,7 +17,7 @@ public void Ctor_Default() [Theory] [InlineData(null)] [InlineData("newObject")] - public void Ctor_NewObject(object newObject) + public void Ctor_NewObject(object? newObject) { var args = new AddingNewEventArgs(newObject); Assert.Same(newObject, args.NewObject); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/AmbientValueAttributeTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/AmbientValueAttributeTests.cs index 9af0e61f424e65..cec74c972f51c9 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/AmbientValueAttributeTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/AmbientValueAttributeTests.cs @@ -15,7 +15,7 @@ public class AmbientValueAttributeTests [InlineData(typeof(int*), "1", null)] [InlineData(typeof(string), "1", "1")] [InlineData(typeof(int), "1", 1)] - public void Ctor_Type_Value(Type type, string value, object expectedValue) + public void Ctor_Type_Value(Type? type, string? value, object? expectedValue) { var attribute = new AmbientValueAttribute(type, value); Assert.Equal(expectedValue, attribute.Value); @@ -88,7 +88,7 @@ public void Ctor_Bool() [Theory] [InlineData(null)] [InlineData("Value")] - public void Ctor_String(string value) + public void Ctor_String(string? value) { var args = new AmbientValueAttribute(value); Assert.Same(value, args.Value); @@ -97,7 +97,7 @@ public void Ctor_String(string value) [Theory] [InlineData(null)] [InlineData("Value")] - public void Ctor_Object(object value) + public void Ctor_Object(object? value) { var args = new AmbientValueAttribute(value); Assert.Same(value, args.Value); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/ArrayConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/ArrayConverterTests.cs index ed5751c0bb27d8..92502f3ca41814 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/ArrayConverterTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/ArrayConverterTests.cs @@ -124,7 +124,7 @@ public void GetProperties_SetValueOutOfRangeWithHandler_CallsValueChanged() [Theory] [InlineData(null)] [InlineData("nonArrayValue")] - public void GetProperties_GetSetInvalidValue_Nop(string value) + public void GetProperties_GetSetInvalidValue_Nop(string? value) { var array = new int[] { 1, 2, 3 }; PropertyDescriptor property = Converter.GetProperties(array)[2]; diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/BindingListTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/BindingListTests.cs index 4d56a15105942d..8fdd9ef1a2da79 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/BindingListTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/BindingListTests.cs @@ -810,7 +810,7 @@ public void ItemPropertyChanged_RaiseListChangedEventsFalse_InvokesItemChanged() [Theory] [InlineData(null)] [InlineData("sender")] - public void ItemPropertyChanged_InvalidSender_InvokesReset(object invokeSender) + public void ItemPropertyChanged_InvalidSender_InvokesReset(object? invokeSender) { var item = new Item(); var bindingList = new BindingList { item }; diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/CollectionChangedEventArgsTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/CollectionChangedEventArgsTests.cs index 256be7e1a9bd29..da994ca965c6de 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/CollectionChangedEventArgsTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/CollectionChangedEventArgsTests.cs @@ -13,7 +13,7 @@ public class CollectionChangedEventArgsTests [InlineData(CollectionChangeAction.Refresh, "element")] [InlineData(CollectionChangeAction.Add - 1, "element")] [InlineData(CollectionChangeAction.Refresh + 1, "element")] - public void Ctor_Action_Element(CollectionChangeAction action, object element) + public void Ctor_Action_Element(CollectionChangeAction action, object? element) { var args = new CollectionChangeEventArgs(action, element); Assert.Equal(action, args.Action); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/ComplexBindingPropertiesAttributeTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/ComplexBindingPropertiesAttributeTests.cs index 6b73ee3c16c493..d6ecb12640fd2b 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/ComplexBindingPropertiesAttributeTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/ComplexBindingPropertiesAttributeTests.cs @@ -19,7 +19,7 @@ public void Ctor_Default() [Theory] [InlineData("DataSource")] [InlineData(null)] - public void Ctor_DataSource(string dataSource) + public void Ctor_DataSource(string? dataSource) { var attribute = new ComplexBindingPropertiesAttribute(dataSource); Assert.Same(dataSource, attribute.DataSource); @@ -29,7 +29,7 @@ public void Ctor_DataSource(string dataSource) [Theory] [InlineData("DataSource", "DataMember")] [InlineData(null, null)] - public void Ctor_DataSource_DataMember(string dataSource, string dataMember) + public void Ctor_DataSource_DataMember(string? dataSource, string? dataMember) { var attribute = new ComplexBindingPropertiesAttribute(dataSource, dataMember); Assert.Same(dataSource, attribute.DataSource); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/CustomTypeDescriptorTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/CustomTypeDescriptorTests.cs index 80c40e50d24377..ebaacd6661ea9b 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/CustomTypeDescriptorTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/CustomTypeDescriptorTests.cs @@ -58,7 +58,7 @@ public void GetClassName_InvokeWithoutParent_ReturnsNull() [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsReflectionEmitSupported))] [InlineData(null)] [InlineData("name")] - public void GetClassName_InvokeWithParent_ReturnsExpected(string result) + public void GetClassName_InvokeWithParent_ReturnsExpected(string? result) { var mockParentDescriptor = new Mock(MockBehavior.Strict); mockParentDescriptor @@ -88,7 +88,7 @@ public void GetComponentName_InvokeWithoutParent_ReturnsNull() [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsReflectionEmitSupported))] [InlineData(null)] [InlineData("name")] - public void GetComponentName_InvokeWithParent_ReturnsExpected(string result) + public void GetComponentName_InvokeWithParent_ReturnsExpected(string? result) { var mockParentDescriptor = new Mock(MockBehavior.Strict); mockParentDescriptor @@ -214,7 +214,7 @@ public void GetDefaultProperty_InvokeWithParent_ReturnsExpected(PropertyDescript [Theory] [InlineData(null)] [InlineData(typeof(int))] - public void GetEditor_InvokeWithoutParent_ReturnsNull(Type editorBaseType) + public void GetEditor_InvokeWithoutParent_ReturnsNull(Type? editorBaseType) { var descriptor = new SubCustomTypeDescriptor(); Assert.Null(descriptor.GetEditor(editorBaseType)); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/DefaultBindingPropertyAttributeTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/DefaultBindingPropertyAttributeTests.cs index 72ed0d51b12b7e..97671ef25f8d0c 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/DefaultBindingPropertyAttributeTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/DefaultBindingPropertyAttributeTests.cs @@ -18,7 +18,7 @@ public void Ctor_Default() [Theory] [InlineData(null)] [InlineData("name")] - public void Ctor_Name(string name) + public void Ctor_Name(string? name) { var attribute = new DefaultBindingPropertyAttribute(name); Assert.Equal(name, attribute.Name); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/DefaultEventAttributeTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/DefaultEventAttributeTests.cs index 4f0295e2046371..e9899aa1b2ac7b 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/DefaultEventAttributeTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/DefaultEventAttributeTests.cs @@ -11,7 +11,7 @@ public class DefaultEventAttributeTests [Theory] [InlineData(null)] [InlineData("name")] - public void Ctor_Name(string name) + public void Ctor_Name(string? name) { var attribute = new DefaultEventAttribute(name); Assert.Equal(name, attribute.Name); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/DefaultPropertyAttributeTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/DefaultPropertyAttributeTests.cs index 84fe3dcc6b6367..33caccbca4d2f4 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/DefaultPropertyAttributeTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/DefaultPropertyAttributeTests.cs @@ -11,7 +11,7 @@ public class DefaultPropertyAttributeTests [Theory] [InlineData(null)] [InlineData("name")] - public void Ctor_Name(string name) + public void Ctor_Name(string? name) { var attribute = new DefaultPropertyAttribute(name); Assert.Equal(name, attribute.Name); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerOptionServiceTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerOptionServiceTests.cs index d306714933c44c..1b6f5244d379fd 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerOptionServiceTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerOptionServiceTests.cs @@ -151,7 +151,7 @@ public void Indexer_ValidName_ReturnsExpected(string name) [Theory] [InlineData(null)] [InlineData("NoSuchName")] - public void Indexer_InvalidName_ReturnsNull(string name) + public void Indexer_InvalidName_ReturnsNull(string? name) { var service = new TestDesignerOptionService(); service.DoCreateOptionCollection(service.Options, "Name", "Value"); @@ -258,7 +258,7 @@ public void DesignerOptionConverterGetProperties_ValidValue_ReturnsExpected() [Theory] [InlineData("Value")] [InlineData(null)] - public void DesignerOptionConverterGetProperties_InvalidValue_ReturnsEmpty(object value) + public void DesignerOptionConverterGetProperties_InvalidValue_ReturnsEmpty(object? value) { TypeConverter converter = TypeDescriptor.GetConverter(typeof(DesignerOptionService.DesignerOptionCollection)); Assert.Empty(converter.GetProperties(value)); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerTransactionTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerTransactionTests.cs index 702e6b138fea8e..602db14cd229a9 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerTransactionTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerTransactionTests.cs @@ -21,7 +21,7 @@ public void Ctor_Default() [Theory] [InlineData(null)] [InlineData("Description")] - public void Ctor_Description(string description) + public void Ctor_Description(string? description) { using (var transaction = new TestDesignerTransaction(description)) { diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerVerbTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerVerbTests.cs index fdbf35d3df17f8..18e077486368fc 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerVerbTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerVerbTests.cs @@ -76,7 +76,7 @@ public void Ctor_NullProperties_ThrowsNullReferenceException() [InlineData(null, "")] [InlineData("", "")] [InlineData("Description", "Description")] - public void Description_GetWithProperties_ReturnsExpected(string value, string expected) + public void Description_GetWithProperties_ReturnsExpected(string? value, string expected) { var verb = new DesignerVerb("Text", new EventHandler(EventHandler)); verb.Properties["Description"] = value; @@ -102,7 +102,7 @@ public void Description_GetWithNullProperties_ThrowsNullReferenceException() [InlineData(null, "")] [InlineData("", "")] [InlineData("Description", "Description")] - public void Description_Set_GetReturnsExpected(string value, string expected) + public void Description_Set_GetReturnsExpected(string? value, string expected) { var verb = new DesignerVerb("Text", new EventHandler(EventHandler)) { @@ -128,7 +128,7 @@ public void Description_SetWithNullProperties_ThrowsNullReferenceException() [InlineData(null, "")] [InlineData("", "")] [InlineData("Text", "Text")] - public void Text_GetWithProperties_ReturnsExpected(string value, string expected) + public void Text_GetWithProperties_ReturnsExpected(string? value, string expected) { var verb = new DesignerVerb("Text", new EventHandler(EventHandler)); verb.Properties["Text"] = value; diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesigntimeLicenseContextTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesigntimeLicenseContextTests.cs index 054dac5427dbdb..3d3a03ee5b3652 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesigntimeLicenseContextTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesigntimeLicenseContextTests.cs @@ -31,7 +31,7 @@ public void GetService_Invoke_ReturnsNull() [Theory] [InlineData(null)] [InlineData("key")] - public void SetSavedLicenseKey_ValidType_Success(string key) + public void SetSavedLicenseKey_ValidType_Success(string? key) { var context = new DesigntimeLicenseContext(); context.SetSavedLicenseKey(typeof(int), key); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/InstanceDescriptorTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/InstanceDescriptorTests.cs index a2415f7b6d1fb7..a898d1bd009e9a 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/InstanceDescriptorTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/InstanceDescriptorTests.cs @@ -69,7 +69,7 @@ public void Constructor_ConstructorInfo_ICollection_Boolean() [Theory] [InlineData(null)] [InlineData(new object[] { new object[] { } })] - public void Ctor_ConstructorInfoArgumentMismatch_ThrowsArgumentException(object[] arguments) + public void Ctor_ConstructorInfoArgumentMismatch_ThrowsArgumentException(object[]? arguments) { ConstructorInfo ci = typeof(Uri).GetConstructor(new Type[] { typeof(string) }); AssertExtensions.Throws(null, () => new InstanceDescriptor(ci, arguments)); @@ -85,7 +85,7 @@ public void Ctor_StaticConstructor_ThrowsArgumentException() [Theory] [InlineData(null)] [InlineData(new object[] { new object[] { } })] - public void Ctor_FieldInfo_ICollection(object[] arguments) + public void Ctor_FieldInfo_ICollection(object[]? arguments) { FieldInfo fi = typeof(StaticField).GetField(nameof(StaticField.Field)); @@ -114,7 +114,7 @@ public void Ctor_NonStaticFieldInfo_ThrowsArgumentException() [Theory] [InlineData(null)] [InlineData(new object[] { new object[] { } })] - public void Ctor_PropertyInfo_ICollection(object[] arguments) + public void Ctor_PropertyInfo_ICollection(object[]? arguments) { PropertyInfo pi = typeof(StaticProperty).GetProperty(nameof(StaticProperty.Property)); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/ResolveNameEventArgsTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/ResolveNameEventArgsTests.cs index 1573983f6bba56..c9ac8dad6cbe29 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/ResolveNameEventArgsTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/ResolveNameEventArgsTests.cs @@ -10,7 +10,7 @@ public class ResolveNameEventArgsTests [Theory] [InlineData(null)] [InlineData("Name")] - public void Ctor_Name(string name) + public void Ctor_Name(string? name) { var eventArgs = new ResolveNameEventArgs(name); Assert.Same(name, eventArgs.Name); @@ -20,7 +20,7 @@ public void Ctor_Name(string name) [Theory] [InlineData(null)] [InlineData("Value")] - public void Value_Set_GetReturnsExpected(object value) + public void Value_Set_GetReturnsExpected(object? value) { var eventArgs = new ResolveNameEventArgs("Name") { Value = value }; Assert.Same(value, eventArgs.Value); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/RootDesignerSerializerAttributeTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/RootDesignerSerializerAttributeTests.cs index 08003d1f2d1c19..0db8e107eba1ec 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/RootDesignerSerializerAttributeTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/RootDesignerSerializerAttributeTests.cs @@ -36,7 +36,7 @@ public void Ctor_NullBaseSerializerType_ThrowsNullReferenceException() [Theory] [InlineData(null, typeof(int), true)] [InlineData("SerializerTypeName", typeof(DesignerSerializerAttribute), false)] - public void Ctor_SerializerTypeName_BaseSerializerType(string serializerTypeName, Type baseSerializerType, bool reloadable) + public void Ctor_SerializerTypeName_BaseSerializerType(string? serializerTypeName, Type baseSerializerType, bool reloadable) { var attribute = new RootDesignerSerializerAttribute(serializerTypeName, baseSerializerType, reloadable); Assert.Equal(serializerTypeName, attribute.SerializerTypeName); @@ -47,7 +47,7 @@ public void Ctor_SerializerTypeName_BaseSerializerType(string serializerTypeName [Theory] [InlineData(null, null, true)] [InlineData("SerializerTypeName", "BaseSerializerTypeName", false)] - public void Ctor_SerializerTypeName_BaseSerializerTypeName(string serializerTypeName, string baseSerializerTypeName, bool reloadable) + public void Ctor_SerializerTypeName_BaseSerializerTypeName(string? serializerTypeName, string? baseSerializerTypeName, bool reloadable) { var attribute = new RootDesignerSerializerAttribute(serializerTypeName, baseSerializerTypeName, reloadable); Assert.Equal(serializerTypeName, attribute.SerializerTypeName); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/ServiceContainerTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/ServiceContainerTests.cs index 846bb10e83196a..0adfe127b64aa3 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/ServiceContainerTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/ServiceContainerTests.cs @@ -519,7 +519,7 @@ public void GetService_DefaultService_ReturnsExpected(Type serviceType) [Theory] [InlineData(null)] [InlineData(typeof(int))] - public void GetService_NoSuchService_ReturnsNull(Type serviceType) + public void GetService_NoSuchService_ReturnsNull(Type? serviceType) { var container = new ServiceContainer(); Assert.Null(container.GetService(serviceType)); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/LicenseExceptionTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/LicenseExceptionTests.cs index e41b3b29e912fc..17a70680ce8244 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/LicenseExceptionTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/LicenseExceptionTests.cs @@ -13,7 +13,7 @@ public class LicenseExceptionTests [Theory] [InlineData(null)] [InlineData(typeof(int))] - public void Ctor_Type(Type type) + public void Ctor_Type(Type? type) { var exception = new LicenseException(type); Assert.Null(exception.InnerException); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/LicenseProviderAttributeTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/LicenseProviderAttributeTests.cs index 1963dcfd5864f8..591ee462e257ac 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/LicenseProviderAttributeTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/LicenseProviderAttributeTests.cs @@ -22,7 +22,7 @@ public void Ctor_Default() [InlineData("")] [InlineData("typeName")] [InlineData("System.Int32")] - public void Ctor_String(string typeName) + public void Ctor_String(string? typeName) { var attribute = new LicenseProviderAttribute(typeName); Assert.Equal(typeName == null ? null : Type.GetType(typeName), attribute.LicenseProvider); @@ -34,7 +34,7 @@ public void Ctor_String(string typeName) [InlineData(null)] [InlineData(typeof(int))] [InlineData(typeof(DesignerAttribute))] - public void Ctor_Type(Type type) + public void Ctor_Type(Type? type) { var attribute = new LicenseProviderAttribute(type); Assert.Same(type, attribute.LicenseProvider); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/LookupBindingPropertiesAttributeTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/LookupBindingPropertiesAttributeTests.cs index 2391d458cefd11..780f9e036e53bc 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/LookupBindingPropertiesAttributeTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/LookupBindingPropertiesAttributeTests.cs @@ -23,7 +23,7 @@ public void Ctor_Default() [InlineData(null, null, null, null)] [InlineData("", "", "", "")] [InlineData("dataSource", "displayMember", "valueMember", "lookupMember")] - public void Ctor_String_String_String_String(string dataSource, string displayMember, string valueMember, string lookupMember) + public void Ctor_String_String_String_String(string? dataSource, string? displayMember, string? valueMember, string? lookupMember) { var attribute = new LookupBindingPropertiesAttribute(dataSource, displayMember, valueMember, lookupMember); Assert.Equal(dataSource, attribute.DataSource); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/MemberDescriptorTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/MemberDescriptorTests.cs index 0d468201dad30f..33ab2c4d4a602f 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/MemberDescriptorTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/MemberDescriptorTests.cs @@ -345,7 +345,7 @@ public void Category_GetWithCategoryAttribute_ReturnsExpected(CategoryAttribute [InlineData(null, "Category2")] [InlineData("", "")] [InlineData("Category", "Category")] - public void Category_GetModifyAttributesAndGet_CachesFirstResult(string originalCategory, string expected) + public void Category_GetModifyAttributesAndGet_CachesFirstResult(string? originalCategory, string expected) { var descriptor = new SubMemberDescriptor("Name", new Attribute[] { new CategoryAttribute(originalCategory) }); Assert.Equal(originalCategory, descriptor.Category); @@ -358,7 +358,7 @@ public void Category_GetModifyAttributesAndGet_CachesFirstResult(string original [InlineData(null)] [InlineData("")] [InlineData("Category")] - public void Category_DontGetModifyAttributesAndGet_DoesNotCacheFirstResult(string originalCategory) + public void Category_DontGetModifyAttributesAndGet_DoesNotCacheFirstResult(string? originalCategory) { var descriptor = new SubMemberDescriptor("Name", new Attribute[] { new CategoryAttribute(originalCategory) }); descriptor.AttributeArray = new Attribute[] { new CategoryAttribute("Category2") }; @@ -400,7 +400,7 @@ public void Description_GetWithDescriptionAttribute_ReturnsExpected(DescriptionA [InlineData(null, "Description2")] [InlineData("", "")] [InlineData("Description", "Description")] - public void Description_GetModifyDescriptionAttribute_CachesFirstResult(string originalDescription, string expected) + public void Description_GetModifyDescriptionAttribute_CachesFirstResult(string? originalDescription, string expected) { var attribute = new ChangingDescriptionAttribute { @@ -417,7 +417,7 @@ public void Description_GetModifyDescriptionAttribute_CachesFirstResult(string o [InlineData(null)] [InlineData("")] [InlineData("Description")] - public void Description_DontGetModifyDescriptionAttribute_DoesNotCacheFirstResult(string originalDescription) + public void Description_DontGetModifyDescriptionAttribute_DoesNotCacheFirstResult(string? originalDescription) { var attribute = new ChangingDescriptionAttribute { @@ -432,7 +432,7 @@ public void Description_DontGetModifyDescriptionAttribute_DoesNotCacheFirstResul [InlineData(null, "Description2")] [InlineData("", "")] [InlineData("Description", "Description")] - public void Description_GetModifyAttributesAndGet_CachesFirstResult(string originalDescription, string expected) + public void Description_GetModifyAttributesAndGet_CachesFirstResult(string? originalDescription, string expected) { var descriptor = new SubMemberDescriptor("Name", new Attribute[] { new DescriptionAttribute(originalDescription) }); Assert.Same(originalDescription, descriptor.Description); @@ -445,7 +445,7 @@ public void Description_GetModifyAttributesAndGet_CachesFirstResult(string origi [InlineData(null)] [InlineData("")] [InlineData("Description")] - public void Description_DontGetModifyAttributesAndGet_DoesNotCacheFirstResult(string originalDescription) + public void Description_DontGetModifyAttributesAndGet_DoesNotCacheFirstResult(string? originalDescription) { var descriptor = new SubMemberDescriptor("Name", new Attribute[] { new DescriptionAttribute(originalDescription) }); descriptor.AttributeArray = new Attribute[] { new DescriptionAttribute("Description2") }; @@ -535,7 +535,7 @@ public void DisplayName_GetWithDisplayNameAttribute_ReturnsExpected(DisplayNameA [InlineData(null, null)] [InlineData("", "Name")] [InlineData("DisplayName", "DisplayName")] - public void DisplayName_GetModifyDisplayNameAttribute_CachesFirstResult(string originalDisplayName, string expected) + public void DisplayName_GetModifyDisplayNameAttribute_CachesFirstResult(string? originalDisplayName, string? expected) { var attribute = new ChangingDisplayNameAttribute { @@ -552,7 +552,7 @@ public void DisplayName_GetModifyDisplayNameAttribute_CachesFirstResult(string o [InlineData(null)] [InlineData("")] [InlineData("DisplayName")] - public void DisplayName_DontGetModifyDisplayNameAttribute_DoesNotCacheFirstResult(string originalDisplayName) + public void DisplayName_DontGetModifyDisplayNameAttribute_DoesNotCacheFirstResult(string? originalDisplayName) { var attribute = new ChangingDisplayNameAttribute { @@ -567,7 +567,7 @@ public void DisplayName_DontGetModifyDisplayNameAttribute_DoesNotCacheFirstResul [InlineData(null, null)] [InlineData("", "Name")] [InlineData("DisplayName", "DisplayName")] - public void DisplayName_GetModifyAttributesAndGet_DoesNotCacheFirstResult(string originalDisplayName, string expected) + public void DisplayName_GetModifyAttributesAndGet_DoesNotCacheFirstResult(string? originalDisplayName, string? expected) { var descriptor = new SubMemberDescriptor("Name", new Attribute[] { new DisplayNameAttribute(originalDisplayName) }); Assert.Equal(expected, descriptor.DisplayName); @@ -580,7 +580,7 @@ public void DisplayName_GetModifyAttributesAndGet_DoesNotCacheFirstResult(string [InlineData(null)] [InlineData("")] [InlineData("DisplayName")] - public void DisplayName_DontGetModifyAttributesAndGet_DoesNotCacheFirstResult(string originalDisplayName) + public void DisplayName_DontGetModifyAttributesAndGet_DoesNotCacheFirstResult(string? originalDisplayName) { var descriptor = new SubMemberDescriptor("Name", new Attribute[] { new DisplayNameAttribute(originalDisplayName) }); descriptor.AttributeArray = new Attribute[] { new DisplayNameAttribute("DisplayName2") }; diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/NestedContainerTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/NestedContainerTests.cs index 16b3b8d159ae0f..2124ae1aee3ff9 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/NestedContainerTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/NestedContainerTests.cs @@ -50,7 +50,7 @@ public void OwnerName_HasINestedSite_ReturnsNull() [InlineData(null)] [InlineData("")] [InlineData("name")] - public void CreateSite_NullOwnerSite_Success(string name) + public void CreateSite_NullOwnerSite_Success(string? name) { var component = new Component(); @@ -68,7 +68,7 @@ public void CreateSite_NullOwnerSite_Success(string name) [InlineData(null)] [InlineData("")] [InlineData("name")] - public void Add_NonNullOwnerSite_Success(string name) + public void Add_NonNullOwnerSite_Success(string? name) { var component = new Component(); @@ -89,7 +89,7 @@ public void Add_NonNullOwnerSite_Success(string name) [InlineData("")] [InlineData("name")] [InlineData("newName")] - public void CreateSite_SetSiteName_Success(string value) + public void CreateSite_SetSiteName_Success(string? value) { var component = new Component(); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/ProvidePropertyAttributeTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/ProvidePropertyAttributeTests.cs index 8f227af7c0522d..e4640bcb7af4e2 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/ProvidePropertyAttributeTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/ProvidePropertyAttributeTests.cs @@ -13,7 +13,7 @@ public class ProvidePropertyAttributeTests [InlineData("", "")] [InlineData("propertyName", "invalidName")] [InlineData("propertyName", "System.Int32")] - public void Ctor_String_String(string propertyName, string receiverTypeName) + public void Ctor_String_String(string? propertyName, string? receiverTypeName) { var attribute = new ProvidePropertyAttribute(propertyName, receiverTypeName); Assert.Equal(propertyName, attribute.PropertyName); @@ -24,7 +24,7 @@ public void Ctor_String_String(string propertyName, string receiverTypeName) [InlineData(null, typeof(int))] [InlineData("", typeof(ProvidePropertyAttribute))] [InlineData("propertyName", typeof(ProvidePropertyAttributeTests))] - public void Ctor_String_Type(string propertyName, Type receiverType) + public void Ctor_String_Type(string? propertyName, Type receiverType) { var attribute = new ProvidePropertyAttribute(propertyName, receiverType); Assert.Equal(propertyName, attribute.PropertyName); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/RefreshEventArgsTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/RefreshEventArgsTests.cs index b3aa3cf1e804ae..8a0635f39e3650 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/RefreshEventArgsTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/RefreshEventArgsTests.cs @@ -11,7 +11,7 @@ public class RefreshEventArgsTests [Theory] [InlineData(null)] [InlineData(typeof(int))] - public void Ctor_Type(Type typeChanged) + public void Ctor_Type(Type? typeChanged) { var args = new RefreshEventArgs(typeChanged); Assert.Null(args.ComponentChanged); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/Security/Authentication/ExtendedProtection/ExtendedProtectionPolicyTypeConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/Security/Authentication/ExtendedProtection/ExtendedProtectionPolicyTypeConverterTests.cs index 5a00c40b8daa13..06c5069ced2a18 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/Security/Authentication/ExtendedProtection/ExtendedProtectionPolicyTypeConverterTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/Security/Authentication/ExtendedProtection/ExtendedProtectionPolicyTypeConverterTests.cs @@ -17,7 +17,7 @@ public class ExtendedProtectionPolicyTypeConverterTests [InlineData(null)] [InlineData(typeof(float))] [InlineData(typeof(TypeConverter))] - public void CanConvertTo_NegativeTests(Type destinationType) + public void CanConvertTo_NegativeTests(Type? destinationType) { Assert.False(converter.CanConvertTo(null, destinationType)); } diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/SyntaxCheckTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/SyntaxCheckTests.cs index 0c7238f36ff79a..2c5d43bc416f6b 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/SyntaxCheckTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/SyntaxCheckTests.cs @@ -14,7 +14,7 @@ public class SyntaxCheckTests [InlineData("machineName\\", false)] [InlineData("machineName", true)] [InlineData(" machineName ", true)] - public void CheckMachineName_Invoke_ReturnsExpected(string value, bool expected) + public void CheckMachineName_Invoke_ReturnsExpected(string? value, bool expected) { Assert.Equal(expected, SyntaxCheck.CheckMachineName(value)); } @@ -28,7 +28,7 @@ public void CheckMachineName_Invoke_ReturnsExpected(string value, bool expected) [InlineData("\\\\", true)] [InlineData("\\\\path", true)] [InlineData(" \\\\path", true)] - public void CheckPath_Invoke_ReturnsExpected(string value, bool expected) + public void CheckPath_Invoke_ReturnsExpected(string? value, bool expected) { Assert.Equal(expected, SyntaxCheck.CheckPath(value)); } @@ -38,7 +38,7 @@ public void CheckPath_Invoke_ReturnsExpected(string value, bool expected) [InlineData("", false)] [InlineData(" ", false)] [InlineData("path", false)] - public void CheckRootedPath_Invoke_ReturnsExpected(string value, bool expected) + public void CheckRootedPath_Invoke_ReturnsExpected(string? value, bool expected) { Assert.Equal(expected, SyntaxCheck.CheckRootedPath(value)); } diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/ToolboxItemFilterAttributeTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/ToolboxItemFilterAttributeTests.cs index 516cd8222f6ebf..0fa9870d460a5c 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/ToolboxItemFilterAttributeTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/ToolboxItemFilterAttributeTests.cs @@ -12,7 +12,7 @@ public class ToolboxItemFilterAttributeTests [InlineData(null)] [InlineData("")] [InlineData("filterString")] - public void Ctor_String(string filterString) + public void Ctor_String(string? filterString) { var attribute = new ToolboxItemFilterAttribute(filterString); Assert.Equal(filterString ?? string.Empty, attribute.FilterString); @@ -26,7 +26,7 @@ public void Ctor_String(string filterString) [InlineData("filterString", ToolboxItemFilterType.Require)] [InlineData("filterString", ToolboxItemFilterType.Allow - 1)] [InlineData("filterString", ToolboxItemFilterType.Require + 1)] - public void Ctor_String_ToolboxItemFilterType(string filterString, ToolboxItemFilterType filterType) + public void Ctor_String_ToolboxItemFilterType(string? filterString, ToolboxItemFilterType filterType) { var attribute = new ToolboxItemFilterAttribute(filterString, filterType); Assert.Equal(filterString ?? string.Empty, attribute.FilterString); @@ -37,7 +37,7 @@ public void Ctor_String_ToolboxItemFilterType(string filterString, ToolboxItemFi [InlineData(null, "System.ComponentModel.ToolboxItemFilterAttribute")] [InlineData("", "System.ComponentModel.ToolboxItemFilterAttribute")] [InlineData("filterString", "System.ComponentModel.ToolboxItemFilterAttributefilterString")] - public void TypeId_ValidEditorBaseTypeName_ReturnsExcepted(string filterType, object expected) + public void TypeId_ValidEditorBaseTypeName_ReturnsExcepted(string? filterType, object expected) { var attribute = new ToolboxItemFilterAttribute(filterType); Assert.Equal(expected, attribute.TypeId); @@ -98,7 +98,7 @@ public void Match_Object_ReturnsExpected(ToolboxItemFilterAttribute attribute, o [InlineData("filterString", ToolboxItemFilterType.Require, "filterString,Require")] [InlineData("filterString", ToolboxItemFilterType.Allow - 1, "filterString,")] [InlineData("filterString", ToolboxItemFilterType.Require + 1, "filterString,")] - public void ToString_Invoke_ReturnsExpected(string filterString, ToolboxItemFilterType filterType, string expected) + public void ToString_Invoke_ReturnsExpected(string? filterString, ToolboxItemFilterType filterType, string expected) { var attribute = new ToolboxItemFilterAttribute(filterString, filterType); Assert.Equal(expected, attribute.ToString()); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptionProviderTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptionProviderTests.cs index 5e840c0a4476e0..884ec70f878e30 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptionProviderTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptionProviderTests.cs @@ -340,7 +340,7 @@ public void GetFullComponentName_NullComponent_ReturnsNull() [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsReflectionEmitSupported))] [InlineData(null)] [InlineData(typeof(int))] - public void GetReflectionType_InvokeTypeWithoutParent_ReturnsExpected(Type objectType) + public void GetReflectionType_InvokeTypeWithoutParent_ReturnsExpected(Type? objectType) { var provider = new SubTypeDescriptionProvider(); Assert.Same(objectType, provider.GetReflectionType(objectType)); @@ -353,7 +353,7 @@ public void GetReflectionType_InvokeTypeWithoutParent_ReturnsExpected(Type objec [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsReflectionEmitSupported))] [InlineData(null)] [InlineData(typeof(int))] - public void GetReflectionType_InvokeTypeWithoutParent_CallsTypeObjectOverload_ByType(Type objectType) + public void GetReflectionType_InvokeTypeWithoutParent_CallsTypeObjectOverload_ByType(Type? objectType) { var mockProvider = new Mock(MockBehavior.Strict); mockProvider @@ -430,7 +430,7 @@ public void GetReflectionType_InvokeTypeWithoutParent_CallsTypeObjectOverload_By [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsReflectionEmitSupported))] [InlineData(1, null)] [InlineData(1, typeof(object))] - public void GetReflectionType_InvokeObjectWithParent_ReturnsExpected(object instance, Type result) + public void GetReflectionType_InvokeObjectWithParent_ReturnsExpected(object instance, Type? result) { var mockParentProvider = new Mock(MockBehavior.Strict); mockParentProvider @@ -452,7 +452,7 @@ public void GetReflectionType_InvokeObjectWithParent_ReturnsExpected(object inst [InlineData(null, 1)] [InlineData(typeof(object), null)] [InlineData(typeof(object), 1)] - public void GetReflectionType_InvokeTypeObjectWithoutParent_ReturnsExpected(Type objectType, object instance) + public void GetReflectionType_InvokeTypeObjectWithoutParent_ReturnsExpected(Type? objectType, object? instance) { var provider = new SubTypeDescriptionProvider(); Assert.Same(objectType, provider.GetReflectionType(objectType, instance)); @@ -475,7 +475,7 @@ public static IEnumerable GetReflectionType_TypeObjectWithParent_TestD // Moq heavily utilizes RefEmit, which does not work on most aot workloads [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsReflectionEmitSupported))] [MemberData(nameof(GetReflectionType_TypeObjectWithParent_TestData))] - public void GetReflectionType_InvokeTypeObjectWithParent_ReturnsExpected(Type objectType, object instance, Type result) + public void GetReflectionType_InvokeTypeObjectWithParent_ReturnsExpected(Type? objectType, object? instance, Type? result) { var mockParentProvider = new Mock(MockBehavior.Strict); mockParentProvider @@ -524,7 +524,7 @@ public void GetRuntimeType_InvokeWithoutParentSystemDefinedType_ReturnsSame(Type [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsReflectionEmitSupported))] [InlineData(null)] [InlineData(typeof(int))] - public void GetRuntimeType_InvokeWithoutParentWithUserDefinedType_RetunsUnderlyingSystemType(Type result) + public void GetRuntimeType_InvokeWithoutParentWithUserDefinedType_RetunsUnderlyingSystemType(Type? result) { var mockType = new Mock(MockBehavior.Strict); mockType @@ -580,7 +580,7 @@ public void GetRuntimeType_NullReflectionType_ThrowsArgumentNullException() [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsReflectionEmitSupported))] [InlineData(null)] [InlineData(typeof(int))] - public void GetTypeDescriptor_InvokeTypeWithoutParent_ReturnsExpected(Type objectType) + public void GetTypeDescriptor_InvokeTypeWithoutParent_ReturnsExpected(Type? objectType) { var provider = new SubTypeDescriptionProvider(); CustomTypeDescriptor result1 = Assert.IsAssignableFrom(provider.GetTypeDescriptor(objectType)); @@ -595,7 +595,7 @@ public void GetTypeDescriptor_InvokeTypeWithoutParent_ReturnsExpected(Type objec [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsReflectionEmitSupported))] [InlineData(null)] [InlineData(typeof(int))] - public void GetTypeDescriptor_InvokeTypeWithoutParent_CallsTypeObjectOverload_Type(Type objectType) + public void GetTypeDescriptor_InvokeTypeWithoutParent_CallsTypeObjectOverload_Type(Type? objectType) { var mockProvider = new Mock(MockBehavior.Strict); mockProvider @@ -713,7 +713,7 @@ public void GetTypeDescriptor_InvokeObjectWithParent_ReturnsExpected(object inst [InlineData(null, 1)] [InlineData(typeof(object), null)] [InlineData(typeof(object), 1)] - public void GetTypeDescriptor_InvokeTypeObjectWithoutParent_ReturnsExpected(Type objectType, object instance) + public void GetTypeDescriptor_InvokeTypeObjectWithoutParent_ReturnsExpected(Type? objectType, object? instance) { var provider = new SubTypeDescriptionProvider(); CustomTypeDescriptor result1 = Assert.IsAssignableFrom(provider.GetTypeDescriptor(objectType, instance)); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/WarningExceptionTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/WarningExceptionTests.cs index 0940a0b7497198..61bbe30898205b 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/WarningExceptionTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/WarningExceptionTests.cs @@ -50,7 +50,7 @@ public void Ctor_String_Exception(string message) [InlineData("message", null)] [InlineData("message", "")] [InlineData("message", "helpUrl")] - public void Ctor_String_String(string message, string helpUrl) + public void Ctor_String_String(string message, string? helpUrl) { var exception = new WarningException(message, helpUrl); Assert.Null(exception.InnerException); @@ -64,7 +64,7 @@ public void Ctor_String_String(string message, string helpUrl) [InlineData("message", null, null)] [InlineData("message", "", "")] [InlineData("message", "helpUrl", "helpTopic")] - public void Ctor_String_String_String(string message, string helpUrl, string helpTopic) + public void Ctor_String_String_String(string message, string? helpUrl, string? helpTopic) { var exception = new WarningException(message, helpUrl, helpTopic); Assert.Null(exception.InnerException); diff --git a/src/libraries/System.ComponentModel/System.ComponentModel.slnx b/src/libraries/System.ComponentModel/System.ComponentModel.slnx index eb105c92034986..ea155d7b6c0d78 100644 --- a/src/libraries/System.ComponentModel/System.ComponentModel.slnx +++ b/src/libraries/System.ComponentModel/System.ComponentModel.slnx @@ -1,29 +1,170 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.ComponentModel/src/System.ComponentModel.csproj b/src/libraries/System.ComponentModel/src/System.ComponentModel.csproj index acb8cab74e4f87..7a19841b027734 100644 --- a/src/libraries/System.ComponentModel/src/System.ComponentModel.csproj +++ b/src/libraries/System.ComponentModel/src/System.ComponentModel.csproj @@ -15,7 +15,7 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Composition.AttributedModel/tests/ExportAttributeTests.cs b/src/libraries/System.Composition.AttributedModel/tests/ExportAttributeTests.cs index 7b937721973c38..4d01ae58799eaf 100644 --- a/src/libraries/System.Composition.AttributedModel/tests/ExportAttributeTests.cs +++ b/src/libraries/System.Composition.AttributedModel/tests/ExportAttributeTests.cs @@ -18,7 +18,7 @@ public void Ctor_Default() [Theory] [InlineData(null)] [InlineData("ContractName")] - public void Ctor_ContractName(string contractName) + public void Ctor_ContractName(string? contractName) { var attribute = new ExportAttribute(contractName); Assert.Equal(contractName, attribute.ContractName); @@ -28,7 +28,7 @@ public void Ctor_ContractName(string contractName) [Theory] [InlineData(null)] [InlineData(typeof(string))] - public void Ctor_ContractType(Type contractType) + public void Ctor_ContractType(Type? contractType) { var attribute = new ExportAttribute(contractType); Assert.Null(attribute.ContractName); @@ -38,7 +38,7 @@ public void Ctor_ContractType(Type contractType) [Theory] [InlineData(null, null)] [InlineData("ContractName", typeof(string))] - public void Ctor_ContractName_ContractType(string contractName, Type contractType) + public void Ctor_ContractName_ContractType(string? contractName, Type? contractType) { var attribute = new ExportAttribute(contractName, contractType); Assert.Equal(contractName, attribute.ContractName); diff --git a/src/libraries/System.Composition.AttributedModel/tests/ExportMetadataAttributeTests.cs b/src/libraries/System.Composition.AttributedModel/tests/ExportMetadataAttributeTests.cs index 8fe4616fa560ef..23ef393e4c9d06 100644 --- a/src/libraries/System.Composition.AttributedModel/tests/ExportMetadataAttributeTests.cs +++ b/src/libraries/System.Composition.AttributedModel/tests/ExportMetadataAttributeTests.cs @@ -10,7 +10,7 @@ public class ExportMetadataAttributeTests [Theory] [InlineData(null, null)] [InlineData("Name", "Value")] - public void Ctor_Name_Value(string name, string value) + public void Ctor_Name_Value(string? name, string? value) { var attribute = new ExportMetadataAttribute(name, value); Assert.Equal(name ?? string.Empty, attribute.Name); diff --git a/src/libraries/System.Composition.AttributedModel/tests/ImportAttributeTests.cs b/src/libraries/System.Composition.AttributedModel/tests/ImportAttributeTests.cs index 03bcd3a707593b..3969defcfc1aaa 100644 --- a/src/libraries/System.Composition.AttributedModel/tests/ImportAttributeTests.cs +++ b/src/libraries/System.Composition.AttributedModel/tests/ImportAttributeTests.cs @@ -18,7 +18,7 @@ public void Ctor_Default() [Theory] [InlineData(null)] [InlineData("ContractName")] - public void Ctor_ContractName(string contractName) + public void Ctor_ContractName(string? contractName) { var attribute = new ImportAttribute(contractName); Assert.Equal(contractName, attribute.ContractName); diff --git a/src/libraries/System.Composition.AttributedModel/tests/ImportManyAttributeTests.cs b/src/libraries/System.Composition.AttributedModel/tests/ImportManyAttributeTests.cs index c8217cf83a8738..a94fac3d13e370 100644 --- a/src/libraries/System.Composition.AttributedModel/tests/ImportManyAttributeTests.cs +++ b/src/libraries/System.Composition.AttributedModel/tests/ImportManyAttributeTests.cs @@ -17,7 +17,7 @@ public void Ctor_Default() [Theory] [InlineData(null)] [InlineData("ContractName")] - public void Ctor_ContractName(string contractName) + public void Ctor_ContractName(string? contractName) { var attribute = new ImportManyAttribute(contractName); Assert.Equal(contractName, attribute.ContractName); diff --git a/src/libraries/System.Composition.AttributedModel/tests/ImportMetadataConstraintAttributeTests.cs b/src/libraries/System.Composition.AttributedModel/tests/ImportMetadataConstraintAttributeTests.cs index d737d254d8868e..91185117c580a9 100644 --- a/src/libraries/System.Composition.AttributedModel/tests/ImportMetadataConstraintAttributeTests.cs +++ b/src/libraries/System.Composition.AttributedModel/tests/ImportMetadataConstraintAttributeTests.cs @@ -10,7 +10,7 @@ public class ImportMetadataConstraintAttributeTests [Theory] [InlineData(null, null)] [InlineData("Name", "Value")] - public void Ctor_Name_Value(string name, string value) + public void Ctor_Name_Value(string? name, string? value) { var attribute = new ImportMetadataConstraintAttribute(name, value); Assert.Equal(name, attribute.Name); diff --git a/src/libraries/System.Composition.AttributedModel/tests/PartMetadataAttributeTests.cs b/src/libraries/System.Composition.AttributedModel/tests/PartMetadataAttributeTests.cs index 4c5353345ee2db..41c6f3a3ac4851 100644 --- a/src/libraries/System.Composition.AttributedModel/tests/PartMetadataAttributeTests.cs +++ b/src/libraries/System.Composition.AttributedModel/tests/PartMetadataAttributeTests.cs @@ -10,7 +10,7 @@ public class PartMetadataAttributeTests [Theory] [InlineData("", null)] [InlineData("Name", "Value")] - public void Ctor_Name_Value(string name, string value) + public void Ctor_Name_Value(string name, string? value) { var attribute = new PartMetadataAttribute(name, value); Assert.Equal(name, attribute.Name); diff --git a/src/libraries/System.Composition.AttributedModel/tests/SharedAttributeTests.cs b/src/libraries/System.Composition.AttributedModel/tests/SharedAttributeTests.cs index 374c0ca668644f..013a3fe440c51f 100644 --- a/src/libraries/System.Composition.AttributedModel/tests/SharedAttributeTests.cs +++ b/src/libraries/System.Composition.AttributedModel/tests/SharedAttributeTests.cs @@ -19,7 +19,7 @@ public void Ctor_Default() [Theory] [InlineData(null)] [InlineData("Name")] - public void Ctor_SharingBoundaryName(string sharingBoundaryName) + public void Ctor_SharingBoundaryName(string? sharingBoundaryName) { var attribute = new SharedAttribute(sharingBoundaryName); Assert.Equal(sharingBoundaryName, attribute.SharingBoundary); diff --git a/src/libraries/System.Composition.Hosting/src/System.Composition.Hosting.csproj b/src/libraries/System.Composition.Hosting/src/System.Composition.Hosting.csproj index 18d027e8ad14bb..c41c4876ca85ed 100644 --- a/src/libraries/System.Composition.Hosting/src/System.Composition.Hosting.csproj +++ b/src/libraries/System.Composition.Hosting/src/System.Composition.Hosting.csproj @@ -3,7 +3,7 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) false - false + false Microsoft false true diff --git a/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/CompositionHostTests.cs b/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/CompositionHostTests.cs index f703345120442f..3fa0ea0153f339 100644 --- a/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/CompositionHostTests.cs +++ b/src/libraries/System.Composition.Hosting/tests/System/Composition/Hosting/Core/CompositionHostTests.cs @@ -105,7 +105,7 @@ public void GetExport_ImoportManyWithMetadataConstraints_ReturnsExpected(Type co [InlineData(typeof(ExportFactory), new string[] { "1", "2", "3" }, new Type[] { typeof(int), typeof(ExportFactory) })] [InlineData(typeof(ExportFactory), null, new Type[] { typeof(int), typeof(ExportFactory) })] [InlineData(typeof(ExportFactory), new string[] { "1", "2", "3" }, new Type[] { typeof(int), typeof(ExportFactory) })] - public void GetExport_ExportFactoryContractWithMetadataConstraints_ReturnsExpected(Type contractType, string[] sharingBoundaryNames, Type[] expectedTypes) + public void GetExport_ExportFactoryContractWithMetadataConstraints_ReturnsExpected(Type contractType, string[]? sharingBoundaryNames, Type[] expectedTypes) { var tracker = new TrackingProvider(); using (CompositionHost host = CompositionHost.CreateCompositionHost(tracker)) diff --git a/src/libraries/System.Composition.Runtime/src/System.Composition.Runtime.csproj b/src/libraries/System.Composition.Runtime/src/System.Composition.Runtime.csproj index 93ef06e572afeb..78743812b829d3 100644 --- a/src/libraries/System.Composition.Runtime/src/System.Composition.Runtime.csproj +++ b/src/libraries/System.Composition.Runtime/src/System.Composition.Runtime.csproj @@ -3,7 +3,7 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) System.Composition - false + false Microsoft false true diff --git a/src/libraries/System.Composition.Runtime/tests/System/Composition/CompositionContextTests.cs b/src/libraries/System.Composition.Runtime/tests/System/Composition/CompositionContextTests.cs index 06776d04fb3f63..6793ff92e6bc80 100644 --- a/src/libraries/System.Composition.Runtime/tests/System/Composition/CompositionContextTests.cs +++ b/src/libraries/System.Composition.Runtime/tests/System/Composition/CompositionContextTests.cs @@ -15,7 +15,7 @@ public class CompositionContextTests [InlineData(false, null)] [InlineData(true, "contractName")] [InlineData(false, "contractName")] - public void GetExport_Invoke_ReturnsExpected(bool success, string contractName) + public void GetExport_Invoke_ReturnsExpected(bool success, string? contractName) { var context = new SubContext(contract => { @@ -82,7 +82,7 @@ public void GetExport_Invoke_ReturnsExpected(bool success, string contractName) [InlineData(false, null)] [InlineData(true, "contractName")] [InlineData(false, "contractName")] - public void GetExports_Invoke_ReturnsExpected(bool success, string contractName) + public void GetExports_Invoke_ReturnsExpected(bool success, string? contractName) { var context = new SubContext(contract => { diff --git a/src/libraries/System.Composition.Runtime/tests/System/Composition/Hosting/Core/CompositionContractTests.cs b/src/libraries/System.Composition.Runtime/tests/System/Composition/Hosting/Core/CompositionContractTests.cs index 7784bad7ba48f3..43bec2c02171cd 100644 --- a/src/libraries/System.Composition.Runtime/tests/System/Composition/Hosting/Core/CompositionContractTests.cs +++ b/src/libraries/System.Composition.Runtime/tests/System/Composition/Hosting/Core/CompositionContractTests.cs @@ -24,7 +24,7 @@ public void Ctor_ContractType(Type contractType) [Theory] [InlineData(typeof(int), null)] [InlineData(typeof(object), "contractName")] - public void Ctor_ContractType_ContractName(Type contractType, string contractName) + public void Ctor_ContractType_ContractName(Type contractType, string? contractName) { var contract = new CompositionContract(contractType, contractName); Assert.Equal(contractType, contract.ContractType); @@ -40,7 +40,7 @@ public static IEnumerable Ctor_ContractType_ContractName_MetadataConst [Theory] [MemberData(nameof(Ctor_ContractType_ContractName_MetadataConstraints_TestData))] - public void Ctor_ContractType_MetadataConstraints(Type contractType, string contractName, IDictionary metadataConstraints) + public void Ctor_ContractType_MetadataConstraints(Type contractType, string? contractName, IDictionary metadataConstraints) { var contract = new CompositionContract(contractType, contractName, metadataConstraints); Assert.Equal(contractType, contract.ContractType); diff --git a/src/libraries/System.Composition.TypedParts/src/System.Composition.TypedParts.csproj b/src/libraries/System.Composition.TypedParts/src/System.Composition.TypedParts.csproj index 3a2874d9d3f0b4..318ec32b398045 100644 --- a/src/libraries/System.Composition.TypedParts/src/System.Composition.TypedParts.csproj +++ b/src/libraries/System.Composition.TypedParts/src/System.Composition.TypedParts.csproj @@ -4,7 +4,7 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) System.Composition false - false + false Microsoft false true diff --git a/src/libraries/System.Configuration.ConfigurationManager/Directory.Build.props b/src/libraries/System.Configuration.ConfigurationManager/Directory.Build.props index 3a3d8f9832479f..c23e70d0e2d061 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/Directory.Build.props +++ b/src/libraries/System.Configuration.ConfigurationManager/Directory.Build.props @@ -3,5 +3,8 @@ true browser;wasi + + false + false \ No newline at end of file diff --git a/src/libraries/System.Configuration.ConfigurationManager/System.Configuration.ConfigurationManager.slnx b/src/libraries/System.Configuration.ConfigurationManager/System.Configuration.ConfigurationManager.slnx index 3ac267d95b24d1..f315405779f837 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/System.Configuration.ConfigurationManager.slnx +++ b/src/libraries/System.Configuration.ConfigurationManager/System.Configuration.ConfigurationManager.slnx @@ -18,6 +18,14 @@ + + + + + + + + @@ -44,6 +52,14 @@ + + + + + + + + @@ -84,6 +100,14 @@ + + + + + + + + @@ -92,6 +116,14 @@ + + + + + + + + @@ -108,6 +140,22 @@ + + + + + + + + + + + + + + + + @@ -124,6 +172,14 @@ + + + + + + + + @@ -132,6 +188,14 @@ + + + + + + + + @@ -165,7 +229,7 @@ - + @@ -221,6 +285,14 @@ + + + + + + + + @@ -229,6 +301,14 @@ + + + + + + + + @@ -245,6 +325,22 @@ + + + + + + + + + + + + + + + + @@ -261,6 +357,14 @@ + + + + + + + + @@ -269,6 +373,14 @@ + + + + + + + + @@ -294,6 +406,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs index c8eaba8e10509a..7c5d7ed0ac0b91 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs @@ -267,7 +267,7 @@ public ConfigurationElementProperty(System.Configuration.ConfigurationValidatorB public partial class ConfigurationErrorsException : System.Configuration.ConfigurationException { public ConfigurationErrorsException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -289,7 +289,7 @@ public ConfigurationErrorsException(string message, System.Xml.XmlReader reader) public static string GetFilename(System.Xml.XmlReader reader) { throw null; } public static int GetLineNumber(System.Xml.XmlNode node) { throw null; } public static int GetLineNumber(System.Xml.XmlReader reader) { throw null; } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -299,7 +299,7 @@ public partial class ConfigurationException : System.SystemException { [System.ObsoleteAttribute("ConfigurationException has been deprecated. Use System.Configuration.ConfigurationErrorsException instead.")] public ConfigurationException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -320,7 +320,7 @@ public ConfigurationException(string message, System.Xml.XmlNode node) { } public virtual string Filename { get { throw null; } } public virtual int Line { get { throw null; } } public override string Message { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -470,7 +470,7 @@ public void CopyTo(System.Configuration.ConfigurationSection[] array, int index) public System.Configuration.ConfigurationSection Get(string name) { throw null; } public override System.Collections.IEnumerator GetEnumerator() { throw null; } public string GetKey(int index) { throw null; } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -506,7 +506,7 @@ public void CopyTo(System.Configuration.ConfigurationSectionGroup[] array, int i public System.Configuration.ConfigurationSectionGroup Get(string name) { throw null; } public override System.Collections.IEnumerator GetEnumerator() { throw null; } public string GetKey(int index) { throw null; } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -887,7 +887,7 @@ internal PropertyInformationCollection() { } public System.Configuration.PropertyInformation this[string propertyName] { get { throw null; } } public void CopyTo(System.Configuration.PropertyInformation[] array, int index) { } public override System.Collections.IEnumerator GetEnumerator() { throw null; } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -1173,7 +1173,7 @@ public void SetReadOnly() { } public partial class SettingsPropertyIsReadOnlyException : System.Exception { public SettingsPropertyIsReadOnlyException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -1184,7 +1184,7 @@ public SettingsPropertyIsReadOnlyException(string message, System.Exception inne public partial class SettingsPropertyNotFoundException : System.Exception { public SettingsPropertyNotFoundException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -1221,7 +1221,7 @@ public void SetReadOnly() { } public partial class SettingsPropertyWrongTypeException : System.Exception { public SettingsPropertyWrongTypeException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -1610,7 +1610,7 @@ void System.Collections.ICollection.CopyTo(System.Array array, int index) { } public partial class ProviderException : System.Exception { public ProviderException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj index 7b71ab3ed15111..9e1859f7e80ef9 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj @@ -3,9 +3,6 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) $(NoWarn);CA2249 - - false - false true false true diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/BaseConfigurationRecord.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/BaseConfigurationRecord.cs index f72769050e5134..276da625a9626e 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/BaseConfigurationRecord.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/BaseConfigurationRecord.cs @@ -19,7 +19,7 @@ namespace System.Configuration [DebuggerDisplay("ConfigPath = {ConfigPath}")] internal abstract class BaseConfigurationRecord : IInternalConfigRecord { -#if NET8_0_OR_GREATER +#if NET private static readonly SearchValues s_invalidSubPathChars = SearchValues.Create(InvalidSubPathCharactersString); #else private static ReadOnlySpan s_invalidSubPathChars => InvalidSubPathCharactersString.AsSpan(); diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationErrorsException.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationErrorsException.cs index e78b7ecbd7fa78..315582fcde4192 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationErrorsException.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationErrorsException.cs @@ -101,7 +101,7 @@ internal ConfigurationErrorsException(ArrayList coll) : coll.CopyTo(_errors, 0); } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -196,7 +196,7 @@ private static ConfigurationException GetFirstException(ICollection + /// Provides methods to register and configure tracing settings from configuration files to and related classes. + /// public static class TraceConfiguration { private static volatile bool s_registered; diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/Mono/ConfigurationManagerTest.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/Mono/ConfigurationManagerTest.cs index d391f308c7faa6..0026d6c9af8f60 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/Mono/ConfigurationManagerTest.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/Mono/ConfigurationManagerTest.cs @@ -42,9 +42,8 @@ namespace MonoTests.System.Configuration public class ConfigurationManagerTest { - [Fact] // OpenExeConfiguration (ConfigurationUserLevel) + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.HasAssemblyFiles))] // OpenExeConfiguration (ConfigurationUserLevel) [ActiveIssue("https://github.com/dotnet/runtime/issues/21528", TargetFrameworkMonikers.NetFramework)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951", typeof(PlatformDetection), nameof(PlatformDetection.IsSingleFile))] public void OpenExeConfiguration1_UserLevel_None() { SysConfig config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); @@ -250,11 +249,10 @@ public void mapped_MachineConfig() Assert.Equal("machineconfig", fi.Name); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.HasAssemblyFiles))] // Doesn't pass on Mono // [Category("NotWorking")] [ActiveIssue("https://github.com/dotnet/runtime/issues/21528", TargetFrameworkMonikers.NetFramework)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951", typeof(PlatformDetection), nameof(PlatformDetection.IsSingleFile))] public void mapped_ExeConfiguration_null() { SysConfig config = ConfigurationManager.OpenMappedExeConfiguration(null, ConfigurationUserLevel.None); diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/ConfigPathUtilityTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/ConfigPathUtilityTests.cs index 1cdf9b0fe46890..313fd690ddf7a8 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/ConfigPathUtilityTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/ConfigPathUtilityTests.cs @@ -29,7 +29,7 @@ public class ConfigPathUtilityTests InlineData(@"a/../c", false), InlineData(@"a/./c", false) ] - public void IsValid(string configPath, bool expected) + public void IsValid(string? configPath, bool expected) { Assert.Equal(expected, ConfigPathUtility.IsValid(configPath)); } diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/StringUtilTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/StringUtilTests.cs index ef87ec2517d92e..cad07166e90f0d 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/StringUtilTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/StringUtilTests.cs @@ -20,7 +20,7 @@ public class StringUtilTests InlineData(@"A", @"a", false), InlineData(@"a", @"a", true) ] - public void EqualsOrBothNullOrEmpty(string s1, string s2, bool expected) + public void EqualsOrBothNullOrEmpty(string? s1, string? s2, bool expected) { Assert.Equal(expected, StringUtil.EqualsOrBothNullOrEmpty(s1, s2)); } @@ -37,7 +37,7 @@ public void EqualsOrBothNullOrEmpty(string s1, string s2, bool expected) InlineData(@"A", @"a", true), InlineData(@"a", @"a", true) ] - public void EqualsIgnoreCase(string s1, string s2, bool expected) + public void EqualsIgnoreCase(string? s1, string? s2, bool expected) { Assert.Equal(expected, StringUtil.EqualsIgnoreCase(s1, s2)); } @@ -58,7 +58,7 @@ public void EqualsIgnoreCase(string s1, string s2, bool expected) InlineData(@"abba", @"abba", true), InlineData(@"ABBA", @"abba", false) ] - public void StartsWithOrdinal(string s1, string s2, bool expected) + public void StartsWithOrdinal(string? s1, string? s2, bool expected) { Assert.Equal(expected, StringUtil.StartsWithOrdinal(s1, s2)); } @@ -79,7 +79,7 @@ public void StartsWithOrdinal(string s1, string s2, bool expected) InlineData(@"abba", @"abba", true), InlineData(@"ABBA", @"abba", true) ] - public void StartsWithOrdinalIgnoreCase(string s1, string s2, bool expected) + public void StartsWithOrdinalIgnoreCase(string? s1, string? s2, bool expected) { Assert.Equal(expected, StringUtil.StartsWithOrdinalIgnoreCase(s1, s2)); } diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/SubclassTypeValidatorAttributeTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/SubclassTypeValidatorAttributeTests.cs index 2772a2bd1fa61d..bf226ce60b6783 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/SubclassTypeValidatorAttributeTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/SubclassTypeValidatorAttributeTests.cs @@ -11,7 +11,7 @@ public class SubclassTypeValidatorAttributeTests [Theory] [InlineData(null)] [InlineData(typeof(string))] - public void GetBaseClass_FlowFromConstructor_Equals(Type expected) + public void GetBaseClass_FlowFromConstructor_Equals(Type? expected) { SubclassTypeValidatorAttribute attr = new SubclassTypeValidatorAttribute(expected); Assert.Equal(expected, attr.BaseClass); diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/ValidatiorUtilsTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/ValidatiorUtilsTests.cs index 66f6c3a198e767..dfcf861eb9eee6 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/ValidatiorUtilsTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/ValidatiorUtilsTests.cs @@ -14,7 +14,7 @@ public class ValidatiorUtilsTests InlineData(@"a", typeof(int), true), InlineData(1, typeof(string), true), ] - public void HelperParamValidation(object value, Type allowedType, bool shouldThrow) + public void HelperParamValidation(object? value, Type allowedType, bool shouldThrow) { Action action = () => ValidatorUtils.HelperParamValidation(value, allowedType); if (!shouldThrow) @@ -43,7 +43,7 @@ public void HelperParamValidation(object value, Type allowedType, bool shouldThr InlineData(2, 1, 1, 1, false, true, "Validation_scalar_range_violation_not_equal"), InlineData(3, 1, 2, 1, false, true, "Validation_scalar_range_violation_not_in_range"), ] - public void ValidateIntScalar(int value, int min, int max, int resolution, bool exclusiveRange, bool shouldThrow, string message) + public void ValidateIntScalar(int value, int min, int max, int resolution, bool exclusiveRange, bool shouldThrow, string? message) { Action action = () => ValidatorUtils.ValidateScalar(value, min, max, resolution, exclusiveRange); if (!shouldThrow) @@ -62,7 +62,7 @@ public void ValidateIntScalar(int value, int min, int max, int resolution, bool InlineData(1, 1, 1, 1, false, false, null), InlineData(1, 1, 1, 2, false, true, "Validator_scalar_resolution_violation") ] - public void ValidateIntBadResolution(int value, int min, int max, int resolution, bool exclusiveRange, bool shouldThrow, string message) + public void ValidateIntBadResolution(int value, int min, int max, int resolution, bool exclusiveRange, bool shouldThrow, string? message) { Action action = () => ValidatorUtils.ValidateScalar(value, min, max, resolution, exclusiveRange); if (!shouldThrow) diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Drawing/Configuration/SystemDrawingSectionTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Drawing/Configuration/SystemDrawingSectionTests.cs index 5a2cc69197f2c2..31a7c4547c74fa 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Drawing/Configuration/SystemDrawingSectionTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Drawing/Configuration/SystemDrawingSectionTests.cs @@ -19,7 +19,7 @@ public void Ctor_Default() [InlineData(null)] [InlineData("")] [InlineData("BitmapSuffix")] - public void BitmapSuffix_Set_GetReturnsExpected(string bitmapSuffix) + public void BitmapSuffix_Set_GetReturnsExpected(string? bitmapSuffix) { var section = new SystemDrawingSection { BitmapSuffix = bitmapSuffix }; Assert.Equal(bitmapSuffix, section.BitmapSuffix); diff --git a/src/libraries/System.Console/System.Console.slnx b/src/libraries/System.Console/System.Console.slnx index 13e4f79f680108..73e4462b9f6a74 100644 --- a/src/libraries/System.Console/System.Console.slnx +++ b/src/libraries/System.Console/System.Console.slnx @@ -1,32 +1,314 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Console/src/System.Console.csproj b/src/libraries/System.Console/src/System.Console.csproj index e3c681be986a95..0b24fa4c0cb1ff 100644 --- a/src/libraries/System.Console/src/System.Console.csproj +++ b/src/libraries/System.Console/src/System.Console.csproj @@ -272,13 +272,13 @@ - - - - - - - + + + + + + + diff --git a/src/libraries/System.Console/tests/Color.cs b/src/libraries/System.Console/tests/Color.cs index 238075e7f09d20..0c43c50c03b424 100644 --- a/src/libraries/System.Console/tests/Color.cs +++ b/src/libraries/System.Console/tests/Color.cs @@ -84,7 +84,7 @@ public static bool TermIsSetAndRemoteExecutorIsSupported [InlineData("tRuE")] [InlineData("0")] [InlineData("false")] - public static void RedirectedOutput_EnvVarSet_EmitsAnsiCodes(string envVar) + public static void RedirectedOutput_EnvVarSet_EmitsAnsiCodes(string? envVar) { var psi = new ProcessStartInfo { RedirectStandardOutput = true }; psi.Environment["DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION"] = envVar; diff --git a/src/libraries/System.Data.Common/System.Data.Common.slnx b/src/libraries/System.Data.Common/System.Data.Common.slnx index 69207ff0a2e62f..84913503d831e1 100644 --- a/src/libraries/System.Data.Common/System.Data.Common.slnx +++ b/src/libraries/System.Data.Common/System.Data.Common.slnx @@ -18,6 +18,14 @@ + + + + + + + + @@ -68,6 +76,14 @@ + + + + + + + + @@ -76,6 +92,14 @@ + + + + + + + + @@ -84,6 +108,14 @@ + + + + + + + + @@ -116,6 +148,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -124,6 +204,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -132,6 +316,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -148,6 +364,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -156,7 +412,7 @@ - + @@ -164,7 +420,7 @@ - + @@ -172,7 +428,7 @@ - + @@ -180,7 +436,7 @@ - + @@ -188,7 +444,7 @@ - + @@ -196,7 +452,7 @@ - + @@ -204,7 +460,7 @@ - + @@ -212,16 +468,15 @@ - - - - - - - - + + + + + + + - + @@ -229,7 +484,7 @@ - + @@ -237,7 +492,7 @@ - + @@ -245,7 +500,7 @@ - + @@ -253,7 +508,7 @@ - + @@ -261,7 +516,7 @@ - + @@ -269,7 +524,7 @@ - + @@ -277,7 +532,576 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -293,6 +1117,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Data.Common/src/System.Data.Common.csproj b/src/libraries/System.Data.Common/src/System.Data.Common.csproj index f1970f717be2ee..6cf029e37bed56 100644 --- a/src/libraries/System.Data.Common/src/System.Data.Common.csproj +++ b/src/libraries/System.Data.Common/src/System.Data.Common.csproj @@ -5,6 +5,9 @@ true $(NoWarn);SYSLIB0038 false + + true + true @@ -312,28 +315,28 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLBinary.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLBinary.cs index ef6fc2d2f0412c..5771769ba908b0 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLBinary.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLBinary.cs @@ -460,6 +460,11 @@ public static XmlQualifiedName GetXsdType(XmlSchemaSet schemaSet) return new XmlQualifiedName("base64Binary", XmlSchema.Namespace); } + /// + /// Wraps a byte array in a without copying the data. + /// + /// The byte array to wrap. + /// A that wraps the provided byte array. public static SqlBinary WrapBytes(byte[] bytes) { return new SqlBinary(bytes, copy: false); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs index 309fc79d90bbc5..b985e7ce88a186 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs @@ -1154,6 +1154,13 @@ private decimal ToDecimal() } } + /// + /// Writes the TDS (Tabular Data Stream) representation of this to the specified destination. + /// + /// The destination span to write the TDS (Tabular Data Stream) value to. Must be at least 4 elements long. + /// The number of values written to the destination. + /// Thrown when the is . + /// Thrown when the destination span is too small. [CLSCompliant(false)] public int WriteTdsValue(Span destination) { diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs index 8d028c5906d489..216769c6ea1abe 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs @@ -208,6 +208,11 @@ public override string ToString() return money.ToString("#0.00##", null); } + /// + /// Gets the TDS (Tabular Data Stream) representation of this value. + /// + /// A long value representing the TDS (Tabular Data Stream) representation. + /// Thrown when the is . public long GetTdsValue() { if (IsNull) @@ -249,6 +254,11 @@ public static SqlMoney Parse(string s) return money; } + /// + /// Creates a from a TDS (Tabular Data Stream) value. + /// + /// The TDS value to convert to . + /// A representing the TDS value. public static SqlMoney FromTdsValue(long value) { return new SqlMoney(value, 0); diff --git a/src/libraries/System.Data.Common/tests/System/Data/Common/DbConnectionTests.cs b/src/libraries/System.Data.Common/tests/System/Data/Common/DbConnectionTests.cs index feed7b22e80bbc..42ea4d30d8e4db 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/Common/DbConnectionTests.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/Common/DbConnectionTests.cs @@ -108,21 +108,21 @@ public void ProviderFactoryTest() } [Fact] - public void GetSchemaAsync_with_cancelled_token() + public async Task GetSchemaAsync_with_cancelled_token() { var conn = new MockDbConnection(); - Assert.ThrowsAsync(async () => await conn.GetSchemaAsync(new CancellationToken(true))); - Assert.ThrowsAsync(async () => await conn.GetSchemaAsync("MetaDataCollections", new CancellationToken(true))); - Assert.ThrowsAsync(async () => await conn.GetSchemaAsync("MetaDataCollections", new string[0], new CancellationToken(true))); + await Assert.ThrowsAsync(async () => await conn.GetSchemaAsync(new CancellationToken(true))); + await Assert.ThrowsAsync(async () => await conn.GetSchemaAsync("MetaDataCollections", new CancellationToken(true))); + await Assert.ThrowsAsync(async () => await conn.GetSchemaAsync("MetaDataCollections", new string[0], new CancellationToken(true))); } [Fact] - public void GetSchemaAsync_with_exception() + public async Task GetSchemaAsync_with_exception() { var conn = new MockDbConnection(); - Assert.ThrowsAsync(async () => await conn.GetSchemaAsync()); - Assert.ThrowsAsync(async () => await conn.GetSchemaAsync("MetaDataCollections")); - Assert.ThrowsAsync(async () => await conn.GetSchemaAsync("MetaDataCollections", new string[0])); + await Assert.ThrowsAsync(async () => await conn.GetSchemaAsync()); + await Assert.ThrowsAsync(async () => await conn.GetSchemaAsync("MetaDataCollections")); + await Assert.ThrowsAsync(async () => await conn.GetSchemaAsync("MetaDataCollections", new string[0])); } [Fact] diff --git a/src/libraries/System.Data.Common/tests/System/Data/Common/DbDataReaderTest.cs b/src/libraries/System.Data.Common/tests/System/Data/Common/DbDataReaderTest.cs index 3d51ee9aac4288..322e4235ccf995 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/Common/DbDataReaderTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/Common/DbDataReaderTest.cs @@ -501,12 +501,12 @@ public Task IsDbNullAsyncByColumnNameCanceledTest() } [Fact] - public void GetSchemaTableAsync_with_cancelled_token() - => Assert.ThrowsAsync(async () => await new DbDataReaderMock().GetSchemaTableAsync(new CancellationToken(true))); + public async Task GetSchemaTableAsync_with_cancelled_token() + => await Assert.ThrowsAsync(async () => await new DbDataReaderMock().GetSchemaTableAsync(new CancellationToken(true))); [Fact] - public void GetSchemaTableAsync_with_exception() - => Assert.ThrowsAsync(async () => await new DbDataReaderMock().GetSchemaTableAsync()); + public async Task GetSchemaTableAsync_with_exception() + => await Assert.ThrowsAsync(async () => await new DbDataReaderMock().GetSchemaTableAsync()); [Fact] public async Task GetSchemaTableAsync_calls_GetSchemaTable() @@ -522,12 +522,12 @@ public async Task GetSchemaTableAsync_calls_GetSchemaTable() } [Fact] - public void GetColumnSchemaAsync_with_cancelled_token() - => Assert.ThrowsAsync(async () => await new DbDataReaderMock().GetColumnSchemaAsync(new CancellationToken(true))); + public async Task GetColumnSchemaAsync_with_cancelled_token() + => await Assert.ThrowsAsync(async () => await new DbDataReaderMock().GetColumnSchemaAsync(new CancellationToken(true))); [Fact] - public void GetColumnSchemaAsync_with_exception() - => Assert.ThrowsAsync(async () => await new DbDataReaderMock().GetColumnSchemaAsync()); + public async Task GetColumnSchemaAsync_with_exception() + => await Assert.ThrowsAsync(async () => await new DbDataReaderMock().GetColumnSchemaAsync()); [Fact] public async Task GetColumnSchemaAsync_calls_GetSchemaTable() diff --git a/src/libraries/System.Data.Odbc/Directory.Build.props b/src/libraries/System.Data.Odbc/Directory.Build.props index 3a3d8f9832479f..6e1b965d020cfa 100644 --- a/src/libraries/System.Data.Odbc/Directory.Build.props +++ b/src/libraries/System.Data.Odbc/Directory.Build.props @@ -3,5 +3,6 @@ true browser;wasi + false \ No newline at end of file diff --git a/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.cs b/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.cs index 9eee7e3847b6b6..b91169b1902935 100644 --- a/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.cs +++ b/src/libraries/System.Data.Odbc/ref/System.Data.Odbc.cs @@ -221,7 +221,7 @@ public sealed partial class OdbcException : System.Data.Common.DbException internal OdbcException() { } public System.Data.Odbc.OdbcErrorCollection Errors { get { throw null; } } public override string Source { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj index 13e559dbb3c3dc..34e55db4831286 100644 --- a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj +++ b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj @@ -5,7 +5,6 @@ $(TargetFrameworks);$(NetCoreAppPrevious)-windows;$(NetCoreAppPrevious)-unix;$(NetCoreAppPrevious) true $(NoWarn);CA2249;CA1838 - false false true Provides a collection of classes used to access an ODBC data source in the managed space diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcException.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcException.cs index b3749cd1c2860f..3e098bc59a6739 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcException.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcException.cs @@ -35,7 +35,7 @@ internal OdbcException(string message, OdbcErrorCollection errors) : base(messag HResult = HResults.OdbcException; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif private OdbcException(SerializationInfo si, StreamingContext sc) : base(si, sc) @@ -53,7 +53,7 @@ public OdbcErrorCollection Errors } } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Data.OleDb/Directory.Build.props b/src/libraries/System.Data.OleDb/Directory.Build.props index 6c6a6c1b425414..5f2e969d9f28ca 100644 --- a/src/libraries/System.Data.OleDb/Directory.Build.props +++ b/src/libraries/System.Data.OleDb/Directory.Build.props @@ -2,5 +2,6 @@ windows + false \ No newline at end of file diff --git a/src/libraries/System.Data.OleDb/System.Data.Oledb.slnx b/src/libraries/System.Data.OleDb/System.Data.Oledb.slnx index 027366e3408697..03bb1d4adbea7e 100644 --- a/src/libraries/System.Data.OleDb/System.Data.Oledb.slnx +++ b/src/libraries/System.Data.OleDb/System.Data.Oledb.slnx @@ -18,6 +18,14 @@ + + + + + + + + @@ -44,6 +52,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -68,6 +108,22 @@ + + + + + + + + + + + + + + + + @@ -76,6 +132,14 @@ + + + + + + + + @@ -84,6 +148,22 @@ + + + + + + + + + + + + + + + + @@ -100,6 +180,14 @@ + + + + + + + + @@ -108,6 +196,22 @@ + + + + + + + + + + + + + + + + @@ -133,7 +237,31 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -173,6 +301,22 @@ + + + + + + + + + + + + + + + + @@ -181,6 +325,14 @@ + + + + + + + + @@ -189,6 +341,22 @@ + + + + + + + + + + + + + + + + @@ -205,6 +373,14 @@ + + + + + + + + @@ -213,6 +389,22 @@ + + + + + + + + + + + + + + + + @@ -230,6 +422,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.cs b/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.cs index c5a31a8183cc84..9a94083b7ac8c5 100644 --- a/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.cs +++ b/src/libraries/System.Data.OleDb/ref/System.Data.OleDb.cs @@ -8,6 +8,9 @@ namespace System.Data.OleDb { [System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.Data.VS.OleDbCommandDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [System.ComponentModel.ToolboxItemAttribute(true)] +#if NET + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("OleDbConnection is not AOT-compatible.")] +#endif public sealed partial class OleDbCommand : System.Data.Common.DbCommand, System.Data.IDbCommand, System.ICloneable, System.IDisposable { public OleDbCommand() { } @@ -81,6 +84,9 @@ protected override void SetRowUpdatingHandler(System.Data.Common.DbDataAdapter a public string UnquoteIdentifier(string quotedIdentifier, System.Data.OleDb.OleDbConnection? connection) { throw null; } } [System.ComponentModel.DefaultEventAttribute("InfoMessage")] +#if NET + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("OleDbConnection is not AOT-compatible.")] +#endif public sealed partial class OleDbConnection : System.Data.Common.DbConnection, System.Data.IDbConnection, System.ICloneable, System.IDisposable { public OleDbConnection() { } @@ -127,6 +133,9 @@ public void ResetState() { } } [System.ComponentModel.DefaultPropertyAttribute("Provider")] [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] +#if NET + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("OleDbConnection is not AOT-compatible.")] +#endif public sealed partial class OleDbConnectionStringBuilder : System.Data.Common.DbConnectionStringBuilder { public OleDbConnectionStringBuilder() { } @@ -151,6 +160,9 @@ public override void Clear() { } } [System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.Data.VS.OleDbDataAdapterDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [System.ComponentModel.ToolboxItemAttribute("Microsoft.VSDesigner.Data.VS.OleDbDataAdapterToolboxItem, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] +#if NET + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("OleDbConnection is not AOT-compatible.")] +#endif public sealed partial class OleDbDataAdapter : System.Data.Common.DbDataAdapter, System.Data.IDataAdapter, System.Data.IDbDataAdapter, System.ICloneable { public OleDbDataAdapter() { } @@ -183,6 +195,9 @@ protected override void OnRowUpdated(System.Data.Common.RowUpdatedEventArgs valu protected override void OnRowUpdating(System.Data.Common.RowUpdatingEventArgs value) { } object System.ICloneable.Clone() { throw null; } } +#if NET + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("OleDbConnection is not AOT-compatible.")] +#endif public sealed partial class OleDbDataReader : System.Data.Common.DbDataReader { internal OleDbDataReader() { } @@ -229,8 +244,17 @@ public override void Close() { } public sealed partial class OleDbEnumerator { public OleDbEnumerator() { } +#if NET + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("OleDbConnection is not AOT-compatible.")] +#endif public System.Data.DataTable GetElements() { throw null; } +#if NET + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("OleDbConnection is not AOT-compatible.")] +#endif public static System.Data.OleDb.OleDbDataReader GetEnumerator(System.Type type) { throw null; } +#if NET + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("OleDbConnection is not AOT-compatible.")] +#endif public static System.Data.OleDb.OleDbDataReader GetRootEnumerator() { throw null; } } public sealed partial class OleDbError @@ -259,12 +283,15 @@ public sealed partial class OleDbException : System.Data.Common.DbException internal OleDbException() { } [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Content)] public System.Data.OleDb.OleDbErrorCollection Errors { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif public override void GetObjectData(System.Runtime.Serialization.SerializationInfo si, System.Runtime.Serialization.StreamingContext context) { } } +#if NET + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("OleDbConnection is not AOT-compatible.")] +#endif public sealed partial class OleDbFactory : System.Data.Common.DbProviderFactory { internal OleDbFactory() { } @@ -477,6 +504,9 @@ public sealed partial class OleDbSchemaGuid public static readonly System.Guid View_Table_Usage; public OleDbSchemaGuid() { } } +#if NET + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("OleDbConnection is not AOT-compatible.")] +#endif public sealed partial class OleDbTransaction : System.Data.Common.DbTransaction { internal OleDbTransaction() { } diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.cs index 0a5151224c1c8e..614f556111c82d 100644 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.cs +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.cs @@ -111,7 +111,7 @@ private void SetLastErrorInfo(OleDbHResult lastErrorHr) } finally { - UnsafeNativeMethods.ReleaseErrorInfoObject(errorInfo); + UnsafeNativeMethods.ReleaseComWrappersObject(errorInfo); } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs deleted file mode 100644 index 8cc99bc095026b..00000000000000 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ /dev/null @@ -1,124 +0,0 @@ -// 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; -using System.Data.Common; -using System.Diagnostics; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// We need to target netstandard2.0, so keep using ref for MemoryMarshal.Write -// CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead. -#pragma warning disable CS9191 - -namespace System.Data.OleDb -{ - /// - /// The ComWrappers implementation for System.Data.OleDb's COM interop usages. - /// - /// Supports IErrorInfo COM interface. - /// - internal sealed unsafe class OleDbComWrappers : ComWrappers - { - private const int S_OK = (int)OleDbHResult.S_OK; - private static readonly Guid IID_IErrorInfo = new Guid(0x1CF2B120, 0x547D, 0x101B, 0x8E, 0x65, 0x08, 0x00, 0x2B, 0x2B, 0xD1, 0x19); - - internal static OleDbComWrappers Instance { get; } = new OleDbComWrappers(); - - private OleDbComWrappers() { } - - protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) - { - throw new NotImplementedException(); - } - - protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flags) - { - Debug.Assert(flags == CreateObjectFlags.UniqueInstance); - - Guid errorInfoIID = IID_IErrorInfo; -#pragma warning disable CS9191 // The 'ref' modifier for argument 1 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead. - int hr = Marshal.QueryInterface(externalComObject, ref errorInfoIID, out IntPtr comObject); -#pragma warning restore CS9191 - if (hr == S_OK) - { - return new ErrorInfoWrapper(comObject); - } - - throw new NotImplementedException(); - } - - protected override void ReleaseObjects(IEnumerable objects) - { - throw new NotImplementedException(); - } - - // Doc and type layout: https://learn.microsoft.com/windows/win32/api/oaidl/nn-oaidl-ierrorinfo - private sealed class ErrorInfoWrapper : UnsafeNativeMethods.IErrorInfo, IDisposable - { - private readonly IntPtr _wrappedInstance; - - public ErrorInfoWrapper(IntPtr wrappedInstance) - { - _wrappedInstance = wrappedInstance; - } - - public void Dispose() - { - Marshal.Release(_wrappedInstance); - } - - [Obsolete("not used", true)] - void UnsafeNativeMethods.IErrorInfo.GetGUID(/*deleted parameter signature*/) - { - throw new NotImplementedException(); - } - - public unsafe System.Data.OleDb.OleDbHResult GetSource(out string? source) - { - IntPtr pSource = IntPtr.Zero; - int errorCode = ((delegate* unmanaged)(*(*(void***)_wrappedInstance + 4 /* IErrorInfo.GetSource slot */))) - (_wrappedInstance, &pSource); - if (pSource == IntPtr.Zero || errorCode < 0) - { - source = null; - } - else - { - source = Marshal.PtrToStringBSTR(pSource); - } - - if (pSource != IntPtr.Zero) - { - Marshal.FreeBSTR(pSource); - } - - return (System.Data.OleDb.OleDbHResult)errorCode; - } - - public unsafe System.Data.OleDb.OleDbHResult GetDescription(out string? description) - { - IntPtr pDescription = IntPtr.Zero; - int errorCode = ((delegate* unmanaged)(*(*(void***)_wrappedInstance + 5 /* IErrorInfo.GetDescription slot */))) - (_wrappedInstance, &pDescription); - if (pDescription == IntPtr.Zero || errorCode < 0) - { - description = null; - } - else - { - description = Marshal.PtrToStringBSTR(pDescription); - } - - if (pDescription != IntPtr.Zero) - { - Marshal.FreeBSTR(pDescription); - } - - return (System.Data.OleDb.OleDbHResult)errorCode; - } - } - - } -} diff --git a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs index 44bb0aceee66d0..279dcf22329a04 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs @@ -14,6 +14,7 @@ namespace System.Data.OleDb { [Designer("Microsoft.VSDesigner.Data.VS.OleDbCommandDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [ToolboxItem(true)] + [RequiresDynamicCode(OleDbConnection.TrimWarning)] public sealed class OleDbCommand : DbCommand, ICloneable, IDbCommand { // command data diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs index 5c8028fed7dd43..686aa0ee323308 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs @@ -19,8 +19,11 @@ namespace System.Data.OleDb // it won't happen if you directly create the provider and set its properties // 2. First call on IDBInitialize must be Initialize, can't QI for any other interfaces before that [DefaultEvent("InfoMessage")] + [RequiresDynamicCode(OleDbConnection.TrimWarning)] public sealed partial class OleDbConnection : DbConnection, ICloneable, IDbConnection { + internal const string TrimWarning = "OleDbConnection is not AOT-compatible."; + private static readonly object EventInfoMessage = new object(); public OleDbConnection(string? connectionString) : this() @@ -615,7 +618,7 @@ internal bool SupportSchemaRowset(Guid schema) } finally { - UnsafeNativeMethods.ReleaseErrorInfoObject(errorInfo); + UnsafeNativeMethods.ReleaseComWrappersObject(errorInfo); } } else if (0 < hresult) diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnectionFactory.cs b/src/libraries/System.Data.OleDb/src/OleDbConnectionFactory.cs index f74fda12f94f33..ea4f81c99203c3 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnectionFactory.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnectionFactory.cs @@ -6,11 +6,13 @@ using System.Data.Common; using System.Data.ProviderBase; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Runtime.Versioning; namespace System.Data.OleDb { + [RequiresDynamicCode("XML deserialization requires dynamic code")] internal sealed class OleDbConnectionFactory : DbConnectionFactory { private OleDbConnectionFactory() : base() { } diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnectionInternal.cs b/src/libraries/System.Data.OleDb/src/OleDbConnectionInternal.cs index e5635abaf90af6..a816de5b7e39ab 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnectionInternal.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnectionInternal.cs @@ -5,6 +5,7 @@ using System.Data.Common; using System.Data.ProviderBase; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.InteropServices; using System.Threading; @@ -12,6 +13,9 @@ namespace System.Data.OleDb { +#if NET + [RequiresDynamicCode(OleDbConnection.TrimWarning)] +#endif internal sealed class OleDbConnectionInternal : DbConnectionInternal, IDisposable { private static volatile OleDbServicesWrapper? idataInitialize; @@ -414,7 +418,11 @@ internal void EnlistTransactionInternal(SysTx.Transaction? transaction) tagDBLITERALINFO tag = new tagDBLITERALINFO(); for (int i = 0; i < literalCount; ++i, offset += ODB.SizeOf_tagDBLITERALINFO) { - Marshal.PtrToStructure((nint)offset, tag); + if (offset is null) + { + throw new NullReferenceException(); + } + tag = Marshal.PtrToStructure((IntPtr)offset)!; DataRow row = table.NewRow(); row[literalName] = ((OleDbLiteral)tag.it).ToString(); @@ -591,7 +599,7 @@ internal DataTable BuildSchemaGuids() for (int i = 0, offset = 0; i < supportedSchemas.Length; ++i, offset += ODB.SizeOf_Guid) { IntPtr ptr = ADP.IntPtrOffset(schemaGuids, i * ODB.SizeOf_Guid); - supportedSchemas[i]._schemaRowset = (Guid)Marshal.PtrToStructure(ptr, typeof(Guid))!; + supportedSchemas[i]._schemaRowset = Marshal.PtrToStructure(ptr)!; } } if (IntPtr.Zero != schemaRestrictions) diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnectionStringBuilder.cs b/src/libraries/System.Data.OleDb/src/OleDbConnectionStringBuilder.cs index 8aeb9fefbb47a1..e3827a3ac40302 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnectionStringBuilder.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnectionStringBuilder.cs @@ -15,6 +15,9 @@ namespace System.Data.OleDb [DefaultProperty("Provider")] [RefreshProperties(RefreshProperties.All)] [TypeConverter(typeof(OleDbConnectionStringBuilder.OleDbConnectionStringBuilderConverter))] +#if NET + [RequiresDynamicCode(OleDbConnection.TrimWarning)] +#endif public sealed class OleDbConnectionStringBuilder : DbConnectionStringBuilder { private enum Keywords @@ -528,6 +531,7 @@ private Dictionary GetProviderInfo(string provider) return providerInfo; } + [RequiresDynamicCode(OleDbConnection.TrimWarning)] private sealed class OleDbProviderConverter : StringConverter { private const int DBSOURCETYPE_DATASOURCE_TDP = 1; @@ -599,6 +603,7 @@ internal enum OleDbServiceValues : int Default = ~(ClientCursor | AggregationAfterSession), }; + [RequiresDynamicCode(OleDbConnection.TrimWarning)] internal sealed class OleDbServicesConverter : TypeConverter { private StandardValuesCollection? _standardValues; diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs index 0ef683f9af61cf..8253b092bb7a0d 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs @@ -4,12 +4,14 @@ using System.ComponentModel; using System.Data.Common; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace System.Data.OleDb { [Designer("Microsoft.VSDesigner.Data.VS.OleDbDataAdapterDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [ToolboxItem("Microsoft.VSDesigner.Data.VS.OleDbDataAdapterToolboxItem, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] + [RequiresDynamicCode(OleDbConnection.TrimWarning)] public sealed class OleDbDataAdapter : DbDataAdapter, IDbDataAdapter, ICloneable { private static readonly object EventRowUpdated = new object(); diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs b/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs index bb84814aff863e..5aed9b32222f6f 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs @@ -14,6 +14,7 @@ namespace System.Data.OleDb { + [RequiresDynamicCode(OleDbConnection.TrimWarning)] public sealed class OleDbDataReader : DbDataReader { private readonly CommandBehavior _commandBehavior; diff --git a/src/libraries/System.Data.OleDb/src/OleDbEnumerator.cs b/src/libraries/System.Data.OleDb/src/OleDbEnumerator.cs index c129596108615f..070cc703293dc9 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbEnumerator.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbEnumerator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Data.Common; +using System.Diagnostics.CodeAnalysis; using System.Globalization; namespace System.Data.OleDb @@ -12,6 +13,9 @@ public OleDbEnumerator() { } +#if NET + [RequiresDynamicCode(OleDbConnection.TrimWarning)] +#endif public DataTable GetElements() { DataTable dataTable = new DataTable("MSDAENUM"); @@ -21,17 +25,26 @@ public DataTable GetElements() return dataTable; } +#if NET + [RequiresDynamicCode(OleDbConnection.TrimWarning)] +#endif public static OleDbDataReader GetEnumerator(Type type) { return GetEnumeratorFromType(type); } +#if NET + [RequiresDynamicCode(OleDbConnection.TrimWarning)] +#endif internal static OleDbDataReader GetEnumeratorFromType(Type type) { object? value = Activator.CreateInstance(type, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance, null, null, CultureInfo.InvariantCulture, null); return GetEnumeratorReader(value); } +#if NET + [RequiresDynamicCode(OleDbConnection.TrimWarning)] +#endif private static OleDbDataReader GetEnumeratorReader(object? value) { NativeMethods.ISourcesRowset? srcrowset; @@ -66,6 +79,9 @@ private static OleDbDataReader GetEnumeratorReader(object? value) return dataReader; } +#if NET + [RequiresDynamicCode(OleDbConnection.TrimWarning)] +#endif public static OleDbDataReader GetRootEnumerator() { //readonly Guid CLSID_MSDAENUM = new Guid(0xc8b522d0,0x5cf3,0x11ce,0xad,0xe5,0x00,0xaa,0x00,0x44,0x77,0x3d); diff --git a/src/libraries/System.Data.OleDb/src/OleDbError.cs b/src/libraries/System.Data.OleDb/src/OleDbError.cs index 6497414fd49628..2e81f631773d41 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbError.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbError.cs @@ -24,7 +24,7 @@ internal OleDbError(UnsafeNativeMethods.IErrorRecords errorRecords, int index) if (OleDbHResult.DB_E_NOLOCALE == hr) { - Marshal.ReleaseComObject(errorInfo); + UnsafeNativeMethods.ReleaseComWrappersObject(errorInfo); lcid = Interop.Kernel32.GetUserDefaultLCID(); errorInfo = errorRecords.GetErrorInfo(index, lcid); @@ -43,7 +43,7 @@ internal OleDbError(UnsafeNativeMethods.IErrorRecords errorRecords, int index) if (OleDbHResult.DB_E_NOLOCALE == hr) { - Marshal.ReleaseComObject(errorInfo); + UnsafeNativeMethods.ReleaseComWrappersObject(errorInfo); lcid = Interop.Kernel32.GetUserDefaultLCID(); errorInfo = errorRecords.GetErrorInfo(index, lcid); @@ -56,7 +56,7 @@ internal OleDbError(UnsafeNativeMethods.IErrorRecords errorRecords, int index) { this.source = ODB.FailedGetSource(hr); } - Marshal.ReleaseComObject(errorInfo!); + UnsafeNativeMethods.ReleaseComWrappersObject(errorInfo); } } @@ -66,7 +66,7 @@ internal OleDbError(UnsafeNativeMethods.IErrorRecords errorRecords, int index) if (null != sqlErrorInfo) { this.nativeError = sqlErrorInfo.GetSQLInfo(out this.sqlState); - Marshal.ReleaseComObject(sqlErrorInfo); + UnsafeNativeMethods.ReleaseComWrappersObject(sqlErrorInfo); } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbException.cs b/src/libraries/System.Data.OleDb/src/OleDbException.cs index 4cead874d43b10..2b14766d87d9c8 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbException.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbException.cs @@ -35,7 +35,7 @@ private OleDbException(string? message, Exception? inner, string? source, OleDbH this.oledbErrors = errors; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Data.OleDb/src/OleDbFactory.cs b/src/libraries/System.Data.OleDb/src/OleDbFactory.cs index e8d1272d106beb..059a670f1a2be0 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbFactory.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbFactory.cs @@ -2,9 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Data.Common; +using System.Diagnostics.CodeAnalysis; namespace System.Data.OleDb { + [RequiresDynamicCode(OleDbConnection.TrimWarning)] public sealed class OleDbFactory : DbProviderFactory { public static readonly OleDbFactory Instance = new OleDbFactory(); diff --git a/src/libraries/System.Data.OleDb/src/OleDbMetaDataFactory.cs b/src/libraries/System.Data.OleDb/src/OleDbMetaDataFactory.cs index f07aecefb55f69..601ee56bb0874a 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbMetaDataFactory.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbMetaDataFactory.cs @@ -4,12 +4,14 @@ using System.Data.Common; using System.Data.ProviderBase; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Text; namespace System.Data.OleDb { + [RequiresDynamicCode(OleDbConnection.TrimWarning)] internal sealed class OleDbMetaDataFactory : DbMetaDataFactory { // V1.2.3300 diff --git a/src/libraries/System.Data.OleDb/src/OleDbTransaction.cs b/src/libraries/System.Data.OleDb/src/OleDbTransaction.cs index fd7fd548e0b85a..3099e82752447f 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbTransaction.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbTransaction.cs @@ -4,11 +4,13 @@ using System.Data.Common; using System.Data.ProviderBase; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace System.Data.OleDb { + [RequiresDynamicCode(OleDbConnection.TrimWarning)] public sealed class OleDbTransaction : DbTransaction { private readonly OleDbTransaction? _parentTransaction; // strong reference to keep parent alive diff --git a/src/libraries/System.Data.OleDb/src/OleDbWrapper.cs b/src/libraries/System.Data.OleDb/src/OleDbWrapper.cs index 4fc5470229df12..feb7274616730d 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbWrapper.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbWrapper.cs @@ -4,6 +4,7 @@ using System.Data.Common; using System.Data.ProviderBase; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -11,6 +12,7 @@ namespace System.Data.OleDb { // SafeHandle wrapper around 'DataLinks' object which pools the native OLE DB providers. // expect 1 per app-domain + [RequiresDynamicCode(OleDbConnection.TrimWarning)] internal sealed class OleDbServicesWrapper : WrappedIUnknown { // we expect to store IDataInitialize instance pointer in base.handle @@ -37,7 +39,7 @@ internal OleDbServicesWrapper(object? unknown) : base() // since IDataInitialize is a public,shipped COM interface, its layout will not change (ever) IntPtr vtable = Marshal.ReadIntPtr(base.handle, 0); IntPtr method = Marshal.ReadIntPtr(vtable, 3 * IntPtr.Size); // GetDataSource is the 4'th vtable entry - DangerousIDataInitializeGetDataSource = (UnsafeNativeMethods.IDataInitializeGetDataSource)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IDataInitializeGetDataSource)); + DangerousIDataInitializeGetDataSource = Marshal.GetDelegateForFunctionPointer(method); } } @@ -143,7 +145,7 @@ internal unsafe OleDbHResult InitializeAndCreateSession(OleDbConnectionString co // we double check before each usage to verify the delegates function pointer if ((null == QueryInterface) || (method != Marshal.GetFunctionPointerForDelegate(QueryInterface))) { - QueryInterface = (UnsafeNativeMethods.IUnknownQueryInterface)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IUnknownQueryInterface)); + QueryInterface = Marshal.GetDelegateForFunctionPointer(method); constr.DangerousDataSourceIUnknownQueryInterface = QueryInterface; } @@ -160,7 +162,7 @@ internal unsafe OleDbHResult InitializeAndCreateSession(OleDbConnectionString co // we double check before each usage to verify the delegates function pointer if ((null == Initialize) || (method != Marshal.GetFunctionPointerForDelegate(Initialize))) { - Initialize = (UnsafeNativeMethods.IDBInitializeInitialize)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IDBInitializeInitialize)); + Initialize = Marshal.GetDelegateForFunctionPointer(method); constr.DangerousIDBInitializeInitialize = Initialize; } @@ -189,7 +191,7 @@ internal unsafe OleDbHResult InitializeAndCreateSession(OleDbConnectionString co // we double check before each usage to verify the delegates function pointer if ((null == CreateSession) || (method != Marshal.GetFunctionPointerForDelegate(CreateSession))) { - CreateSession = (UnsafeNativeMethods.IDBCreateSessionCreateSession)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IDBCreateSessionCreateSession)); + CreateSession = Marshal.GetDelegateForFunctionPointer(method); constr.DangerousIDBCreateSessionCreateSession = CreateSession; } @@ -335,7 +337,7 @@ internal unsafe void QueryInterfaceIDBCreateCommand(OleDbConnectionString constr // since IUnknown is a public,shipped COM interface, its layout will not change (ever) IntPtr vtable = Marshal.ReadIntPtr(base.handle, 0); IntPtr method = Marshal.ReadIntPtr(vtable, 0); - UnsafeNativeMethods.IUnknownQueryInterface QueryInterface = (UnsafeNativeMethods.IUnknownQueryInterface)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IUnknownQueryInterface)); + UnsafeNativeMethods.IUnknownQueryInterface QueryInterface = Marshal.GetDelegateForFunctionPointer(method); int hresult; fixed (Guid* riid = &ODB.IID_IDBCreateCommand) @@ -347,7 +349,7 @@ internal unsafe void QueryInterfaceIDBCreateCommand(OleDbConnectionString constr vtable = Marshal.ReadIntPtr(idbCreateCommand, 0); method = Marshal.ReadIntPtr(vtable, 3 * IntPtr.Size); - DangerousIDBCreateCommandCreateCommand = (UnsafeNativeMethods.IDBCreateCommandCreateCommand)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IDBCreateCommandCreateCommand)); + DangerousIDBCreateCommandCreateCommand = Marshal.GetDelegateForFunctionPointer(method); constr.DangerousIDBCreateCommandCreateCommand = DangerousIDBCreateCommandCreateCommand; } @@ -388,7 +390,7 @@ internal void VerifyIDBCreateCommand(OleDbConnectionString constr) // we double check before each usage to verify the delegates function pointer if ((null == CreateCommand) || (method != Marshal.GetFunctionPointerForDelegate(CreateCommand))) { - CreateCommand = (UnsafeNativeMethods.IDBCreateCommandCreateCommand)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IDBCreateCommandCreateCommand)); + CreateCommand = Marshal.GetDelegateForFunctionPointer(method); constr.DangerousIDBCreateCommandCreateCommand = CreateCommand; } // since this instance can be used to create multiple commands diff --git a/src/libraries/System.Data.OleDb/src/OleDb_Util.cs b/src/libraries/System.Data.OleDb/src/OleDb_Util.cs index 961e0c050f0f26..b6881ba53000c4 100644 --- a/src/libraries/System.Data.OleDb/src/OleDb_Util.cs +++ b/src/libraries/System.Data.OleDb/src/OleDb_Util.cs @@ -559,16 +559,16 @@ internal static InvalidOperationException IDBInfoNotSupported() internal static readonly bool IsRunningOnX86 = RuntimeInformation.ProcessArchitecture == Architecture.X86; - /*internal static readonly int SizeOf_tagDBPARAMINFO = Marshal.SizeOf(typeof(tagDBPARAMINFO));*/ - internal static readonly int SizeOf_tagDBBINDING = Marshal.SizeOf(typeof(tagDBBINDING)); - internal static readonly int SizeOf_tagDBCOLUMNINFO = Marshal.SizeOf(typeof(tagDBCOLUMNINFO)); - internal static readonly int SizeOf_tagDBLITERALINFO = Marshal.SizeOf(typeof(tagDBLITERALINFO)); - internal static readonly int SizeOf_tagDBPROPSET = Marshal.SizeOf(typeof(tagDBPROPSET)); - internal static readonly int SizeOf_tagDBPROP = IsRunningOnX86 ? Marshal.SizeOf(typeof(tagDBPROP_x86)) : Marshal.SizeOf(typeof(tagDBPROP)); - internal static readonly int SizeOf_tagDBPROPINFOSET = Marshal.SizeOf(typeof(tagDBPROPINFOSET)); - internal static readonly int SizeOf_tagDBPROPINFO = IsRunningOnX86 ? Marshal.SizeOf(typeof(tagDBPROPINFO_x86)) : Marshal.SizeOf(typeof(tagDBPROPINFO)); - internal static readonly int SizeOf_tagDBPROPIDSET = Marshal.SizeOf(typeof(tagDBPROPIDSET)); - internal static readonly int SizeOf_Guid = Marshal.SizeOf(typeof(Guid)); + /*internal static readonly int SizeOf_tagDBPARAMINFO = Marshal.SizeOf();*/ + internal static readonly int SizeOf_tagDBBINDING = Marshal.SizeOf(); + internal static readonly int SizeOf_tagDBCOLUMNINFO = Marshal.SizeOf(); + internal static readonly int SizeOf_tagDBLITERALINFO = Marshal.SizeOf(); + internal static readonly int SizeOf_tagDBPROPSET = Marshal.SizeOf(); + internal static readonly int SizeOf_tagDBPROP = IsRunningOnX86 ? Marshal.SizeOf() : Marshal.SizeOf(); + internal static readonly int SizeOf_tagDBPROPINFOSET = Marshal.SizeOf(); + internal static readonly int SizeOf_tagDBPROPINFO = IsRunningOnX86 ? Marshal.SizeOf() : Marshal.SizeOf(); + internal static readonly int SizeOf_tagDBPROPIDSET = Marshal.SizeOf(); + internal static readonly int SizeOf_Guid = Marshal.SizeOf(); internal static readonly int SizeOf_Variant = 8 + (2 * IntPtr.Size); // 16 on 32bit, 24 on 64bit internal static readonly int OffsetOf_tagDBPROP_Status = IsRunningOnX86 ? Marshal.OffsetOf(typeof(tagDBPROP_x86), "dwStatus").ToInt32() : Marshal.OffsetOf(typeof(tagDBPROP), "dwStatus").ToInt32(); diff --git a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj index d366c5cad37b04..91422a3cde6375 100644 --- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj @@ -8,9 +8,11 @@ $(NoWarn);CA2249 $(NoWarn);SYSLIB0004 - false + + $(NoWarn);CS3016 false true + true Provides a collection of classes for OLEDB. Commonly Used Types: @@ -33,36 +35,21 @@ System.Data.OleDb.OleDbTransaction - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -137,18 +124,15 @@ System.Data.OleDb.OleDbTransaction - + - - + diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbBuffer.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbBuffer.cs index 7b089085879bbc..9421102c20b9b8 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbBuffer.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbBuffer.cs @@ -353,11 +353,11 @@ protected override unsafe bool ReleaseHandle() return true; } - private void StructureToPtr(int offset, object structure) + private void StructureToPtr(int offset, T structure) { Debug.Assert(null != structure, "null structure"); offset += BaseOffset; - ValidateCheck(offset, Marshal.SizeOf(structure.GetType())); + ValidateCheck(offset, Marshal.SizeOf()); Debug.Assert(0 == offset % IntPtr.Size, "invalid alignment"); bool mustRelease = false; @@ -367,7 +367,7 @@ private void StructureToPtr(int offset, object structure) DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); - Marshal.StructureToPtr(structure, ptr, false/*fDeleteOld*/); + Marshal.StructureToPtr(structure, ptr, false/*fDeleteOld*/); } finally { diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionHelper.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionHelper.cs index 13eee27ff776e8..0251a3ec131da6 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionHelper.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbConnectionHelper.cs @@ -4,6 +4,7 @@ using System.Data.Common; using System.Data.ProviderBase; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Threading; using SysTx = System.Transactions; @@ -45,6 +46,7 @@ private void CopyFrom(OleDbConnection connection) private static DbConnectionFactory ConnectionFactory { + [RequiresDynamicCode(OleDbConnection.TrimWarning)] get { return _connectionFactory; diff --git a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbMetaDataFactory.cs b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbMetaDataFactory.cs index 1ace12d34a134c..9a66324d50f8fa 100644 --- a/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbMetaDataFactory.cs +++ b/src/libraries/System.Data.OleDb/src/System/Data/ProviderBase/DbMetaDataFactory.cs @@ -32,6 +32,7 @@ internal class DbMetaDataFactory private const string _sqlCommand = "SQLCommand"; private const string _prepareCollection = "PrepareCollection"; + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Members from serialized types may use dynamic code generation.")] public DbMetaDataFactory(Stream xmlStream, string serverVersion, string normalizedServerVersion) { ADP.CheckArgumentNull(xmlStream, "xmlStream"); diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs index d09e45ba0101aa..033bf5bf487318 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs @@ -3,6 +3,7 @@ using System.Data.OleDb; using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; namespace System.Data.Common { @@ -15,27 +16,15 @@ internal static partial class UnsafeNativeMethods [LibraryImport(Interop.Libraries.OleAut32)] internal static unsafe partial OleDbHResult GetErrorInfo( int dwReserved, - System.IntPtr* ppIErrorInfo); + [MarshalUsing(typeof(UniqueComInterfaceMarshaller))] + out IErrorInfo? ppIErrorInfo); - internal static unsafe OleDbHResult GetErrorInfo( - int dwReserved, - out UnsafeNativeMethods.IErrorInfo? ppIErrorInfo) + internal static void ReleaseComWrappersObject(object? obj) { - ppIErrorInfo = null; - IntPtr pErrorInfo; - var hr = GetErrorInfo(dwReserved, &pErrorInfo); - if (hr == OleDbHResult.S_OK) + if (obj is not null) { - ppIErrorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance - .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance); + ((ComObject)obj).FinalRelease(); } - - return hr; - } - - internal static void ReleaseErrorInfoObject(UnsafeNativeMethods.IErrorInfo errorInfo) - { - ((IDisposable)errorInfo).Dispose(); } } } diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs index 474d677280e596..683ea7d8be9f05 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; using System.Security; #pragma warning disable 0618 // ComInterfaceType.InterfaceIsDual is obsolete @@ -507,10 +508,18 @@ System.Data.OleDb.OleDbHResult GetSchemas( [Out] out IntPtr prgRestrictionSupport); } - [Guid("1CF2B120-547D-101B-8E65-08002B2BD119"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComImport, SuppressUnmanagedCodeSecurity] - internal interface IErrorInfo + [Guid("0C733A74-2A1C-11CE-ADE5-00AA0044773D"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GeneratedComInterface, SuppressUnmanagedCodeSecurity] + internal partial interface ISQLErrorInfo { - [Obsolete("not used", true)] void GetGUID(/*deleted parameter signature*/); + [return: MarshalAs(UnmanagedType.I4)] + int GetSQLInfo( + [MarshalAs(UnmanagedType.BStr)] out string pbstrSQLState); + } + + [Guid("1CF2B120-547D-101B-8E65-08002B2BD119"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GeneratedComInterface, SuppressUnmanagedCodeSecurity] + internal partial interface IErrorInfo + { + [Obsolete("not used")] void GetGUID(/*deleted parameter signature*/); [PreserveSig] System.Data.OleDb.OleDbHResult GetSource( @@ -539,25 +548,26 @@ virtual HRESULT STDMETHODCALLTYPE GetHelpContext( /* [out] */ DWORD *pdwHelpContext) = 0; #endif - [Guid("0C733A67-2A1C-11CE-ADE5-00AA0044773D"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComImport, SuppressUnmanagedCodeSecurity] - internal interface IErrorRecords + [Guid("0C733A67-2A1C-11CE-ADE5-00AA0044773D"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GeneratedComInterface, SuppressUnmanagedCodeSecurity] + internal partial interface IErrorRecords { - [Obsolete("not used", true)] void AddErrorRecord(/*deleted parameter signature*/); + [Obsolete("not used")] void AddErrorRecord(/*deleted parameter signature*/); - [Obsolete("not used", true)] void GetBasicErrorInfo(/*deleted parameter signature*/); + [Obsolete("not used")] void GetBasicErrorInfo(/*deleted parameter signature*/); [PreserveSig] System.Data.OleDb.OleDbHResult GetCustomErrorObject( // may return E_NOINTERFACE when asking for IID_ISQLErrorInfo - [In] int ulRecordNum, - [In] in Guid riid, - [Out, MarshalAs(UnmanagedType.Interface)] out ISQLErrorInfo ppObject); + int ulRecordNum, + in Guid riid, + [MarshalUsing(typeof(UniqueComInterfaceMarshaller))] + out ISQLErrorInfo ppObject); - [return: MarshalAs(UnmanagedType.Interface)] + [return: MarshalUsing(typeof(UniqueComInterfaceMarshaller))] IErrorInfo GetErrorInfo( - [In] int ulRecordNum, - [In] int lcid); + int ulRecordNum, + int lcid); - [Obsolete("not used", true)] void GetErrorParameters(/*deleted parameter signature*/); + [Obsolete("not used")] void GetErrorParameters(/*deleted parameter signature*/); int GetRecordCount(); } @@ -725,14 +735,6 @@ System.Data.OleDb.OleDbHResult GetReferencedRowset( //int GetSpecification(/*deleted parameter signature*/); } - [Guid("0C733A74-2A1C-11CE-ADE5-00AA0044773D"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComImport, SuppressUnmanagedCodeSecurity] - internal interface ISQLErrorInfo - { - [return: MarshalAs(UnmanagedType.I4)] - int GetSQLInfo( - [Out, MarshalAs(UnmanagedType.BStr)] out string pbstrSQLState); - } - [Guid("0C733A5F-2A1C-11CE-ADE5-00AA0044773D"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComImport, SuppressUnmanagedCodeSecurity] internal interface ITransactionLocal { diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/System.Diagnostics.DiagnosticSource.slnx b/src/libraries/System.Diagnostics.DiagnosticSource/System.Diagnostics.DiagnosticSource.slnx index 6e313e73e6001e..6ba8a3d1be676d 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/System.Diagnostics.DiagnosticSource.slnx +++ b/src/libraries/System.Diagnostics.DiagnosticSource/System.Diagnostics.DiagnosticSource.slnx @@ -1,32 +1,386 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.csproj index 6356c4f7a158f7..7e75138266a568 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.csproj @@ -15,6 +15,7 @@ + diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj index c0f73eb015d095..d8033564725f59 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -129,6 +129,7 @@ System.Diagnostics.DiagnosticSource + @@ -151,16 +152,16 @@ System.Diagnostics.DiagnosticSource - - - - - - - - - - + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs index 2ff260fc0c2b69..a2d3e7abdf6a31 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs @@ -108,7 +108,7 @@ public void Message(string? Message) } [Event(2, Keywords = Keywords.TimeSeriesValues)] -#if !NET8_0_OR_GREATER +#if !NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif @@ -118,7 +118,7 @@ public void CollectionStart(string sessionId, DateTime intervalStartTime, DateTi } [Event(3, Keywords = Keywords.TimeSeriesValues)] -#if !NET8_0_OR_GREATER +#if !NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif @@ -128,7 +128,7 @@ public void CollectionStop(string sessionId, DateTime intervalStartTime, DateTim } [Event(4, Keywords = Keywords.TimeSeriesValues, Version = 2)] -#if !NET8_0_OR_GREATER +#if !NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif @@ -138,7 +138,7 @@ public void CounterRateValuePublished(string sessionId, string meterName, string } [Event(5, Keywords = Keywords.TimeSeriesValues, Version = 2)] -#if !NET8_0_OR_GREATER +#if !NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif @@ -148,7 +148,7 @@ public void GaugeValuePublished(string sessionId, string meterName, string? mete } [Event(6, Keywords = Keywords.TimeSeriesValues, Version = 2)] -#if !NET8_0_OR_GREATER +#if !NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif @@ -161,7 +161,7 @@ public void HistogramValuePublished(string sessionId, string meterName, string? // or because an instrument matching the pre-existing filter has just been created. This event precedes all *MetricPublished events // for the same named instrument. [Event(7, Keywords = Keywords.TimeSeriesValues, Version = 3)] -#if !NET8_0_OR_GREATER +#if !NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif @@ -186,7 +186,7 @@ public void BeginInstrumentReporting( // Sent when we stop monitoring the value of a instrument, either because new session filter arguments changed subscriptions // or because the Meter has been disposed. [Event(8, Keywords = Keywords.TimeSeriesValues, Version = 3)] -#if !NET8_0_OR_GREATER +#if !NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif @@ -221,7 +221,7 @@ public void InitialInstrumentEnumerationComplete(string sessionId) } [Event(11, Keywords = Keywords.InstrumentPublishing, Version = 3)] -#if !NET8_0_OR_GREATER +#if !NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif @@ -268,7 +268,7 @@ public void MultipleSessionsNotSupportedError(string runningSessionId) } [Event(16, Keywords = Keywords.TimeSeriesValues, Version = 2)] -#if !NET8_0_OR_GREATER +#if !NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif @@ -278,7 +278,7 @@ public void UpDownCounterRateValuePublished(string sessionId, string meterName, } [Event(17, Keywords = Keywords.TimeSeriesValues)] -#if !NET8_0_OR_GREATER +#if !NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif @@ -300,7 +300,7 @@ public void Version(int Major, int Minor, int Patch) /// Used to send the value of a base 2 exponential histogram. /// [Event(19, Keywords = Keywords.TimeSeriesValues, Version = 1)] -#if !NET8_0_OR_GREATER +#if !NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/W3CPropagator.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/W3CPropagator.cs index eb36be1d87f13f..239621061f19f2 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/W3CPropagator.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/W3CPropagator.cs @@ -601,16 +601,37 @@ private static bool NeedToEscapeBaggageValueCharacter(char c) // Example 00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01 private static bool IsInvalidTraceParent(string? traceParent) { - if (string.IsNullOrEmpty(traceParent) || traceParent.Length != 55) + if (string.IsNullOrEmpty(traceParent) || traceParent.Length < 55) { return true; } - if (traceParent[0] == 'f' || traceParent[1] == 'f' || IsInvalidTraceParentCharacter(traceParent[0]) || IsInvalidTraceParentCharacter(traceParent[1])) + if ((traceParent[0] == 'f' && traceParent[1] == 'f') || IsInvalidTraceParentCharacter(traceParent[0]) || IsInvalidTraceParentCharacter(traceParent[1])) { return true; } + if (traceParent[0] == '0' && traceParent[1] == '0') + { + // version 00 should have exactly 55 characters + if (traceParent.Length != 55) + { + return true; // invalid length for version 00 + } + } + else + { + // If a higher version is detected, the implementation SHOULD try to parse it by trying the following: + // o If the size of the header is shorter than 55 characters, the vendor should not parse the header and should restart the trace. + // o Parse trace-id (from the first dash through the next 32 characters). Vendors MUST check that the 32 characters are hex, and that they are followed by a dash (-). + // o Parse parent-id (from the second dash at the 35th position through the next 16 characters). Vendors MUST check that the 16 characters are hex and followed by a dash. + // o Parse the sampled bit of flags (2 characters from the third dash). Vendors MUST check that the 2 characters are either the end of the string or a dash. + if (traceParent.Length > 55 && traceParent[55] != '-') + { + return true; // invalid format for version other than 00 + } + } + if (traceParent[2] != '-' || traceParent[35] != '-' || traceParent[52] != '-') { return true; diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs index ace36d95253df0..dc0eadbd60a0af 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs @@ -1878,7 +1878,7 @@ public void TestGetTagItem() [InlineData("key2", null, false, 0)] [InlineData("key3", "v1", true, 1)] [InlineData("key4", "v2", false, 1)] - public void TestInsertingFirstTag(string key, object value, bool add, int resultCount) + public void TestInsertingFirstTag(string key, object? value, bool add, int resultCount) { Activity a = new Activity("SetFirstTag"); if (add) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs index 3a83e2ba346257..0face5c7c0ec16 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs +++ b/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/libraries/System.Diagnostics.DiagnosticSource/tests/W3CPropagatorTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/W3CPropagatorTests.cs index d44ccae40dda6a..21ffb24016f412 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/W3CPropagatorTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/W3CPropagatorTests.cs @@ -316,6 +316,70 @@ public void TestBaggagePropagationLimits() Assert.Equal(entryCount, decodedBaggage.Count()); } + // Trace ID format is defined in W3C Trace Context specification: + // HEXDIGLC = DIGIT / "a" / "b" / "c" / "d" / "e" / "f"; lowercase hex character + // value = version "-" version-format + // version = 2HEXDIGLC; this document assumes version 00. Version ff is forbidden + // version - format = trace - id "-" parent - id "-" trace - flags + // trace - id = 32HEXDIGLC; 16 bytes array identifier. All zeroes forbidden + // parent-id = 16HEXDIGLC ; 8 bytes array identifier. All zeroes forbidden + // trace-flags = 2HEXDIGLC ; 8 bit flags. + // . . . . . . + // Example 00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01 + // If a higher version is detected, the implementation SHOULD try to parse it by trying the following: + // o If the size of the header is shorter than 55 characters, the vendor should not parse the header and should restart the trace. + // o Parse trace-id (from the first dash through the next 32 characters). Vendors MUST check that the 32 characters are hex, and that they are followed by a dash (-). + // o Parse parent-id (from the second dash at the 35th position through the next 16 characters). Vendors MUST check that the 16 characters are hex and followed by a dash. + // o Parse the sampled bit of flags (2 characters from the third dash). Vendors MUST check that the 2 characters are either the end of the string or a dash. + public static IEnumerable W3CTraceParentData() + { + // TraceId, valid data? + + yield return new object[] { "00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01", true }; // Perfect trace parent + yield return new object[] { "0f-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01", true }; // version is 0f, which is valid + yield return new object[] { "f0-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01", true }; // version is f0, which is valid + yield return new object[] { "ff-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01", false }; // version is ff, which is invalid + yield return new object[] { "f-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01", false }; // version is one digit 'f', which is invalid + yield return new object[] { "0g-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01", false }; // version is 0g, which is invalid + yield return new object[] { "0F-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01", false }; // version is 0F, which is invalid, 'F' should be lower case + yield return new object[] { "00-af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01", false }; // trace-id length is wrong + yield return new object[] { "00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e-01", false }; // parent id length is wrong + yield return new object[] { "00-00000000000000000000000000000000-b9c7c989f97918e1-01", false }; // all zeros trace-id is invalid + yield return new object[] { "00-0af7651916cd43dd8448eb211c80319c-0000000000000000-01", false }; // all zeros parent id is invalid + yield return new object[] { "00-0af7651916cd43dd8448eb211c80319C-b9c7c989f97918e1-01", false }; // trace-id has upper case 'C', which is invalid + yield return new object[] { "00-0af7651916cd43dd8448eb211c80319c-B9c7c989f97918e1-01", false }; // parent-id has upper case 'B', which is invalid + yield return new object[] { "00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-0", false }; // trace flags length is wrong + yield return new object[] { "00-0af7651916cd43dd8448ek211c80319c-b9c7c989f97918e1-01", false }; // trace-id has wrong character 'k', which is invalid + yield return new object[] { "00-0af7651916cd43dd8448ee211c80319c-b9c7c989f97918z1-01", false }; // parent-id has wrong character 'z', which is invalid + yield return new object[] { "00_0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01", false }; // invalid separator, should be '-' + yield return new object[] { "00-0af7651916cd43dd8448eb211c80319c_b9c7c989f97918e1-01", false }; // invalid separator, should be '-' + yield return new object[] { "00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1_01", false }; // invalid separator, should be '-' + yield return new object[] { "00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-011", false }; // invalid trace parent length + yield return new object[] { "01-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-011", false }; // version higher than 00 but it supposes to have '-' after the sampling flags + + // version higher than 00, can have '-' after the sampling flags and more data. Vendors MUST NOT parse or assume anything about unknown fields for this version + yield return new object[] { "01-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01-00", true }; + } + + [Theory] + [MemberData(nameof(W3CTraceParentData))] + public void ValidateTraceIdAndStateExtraction(string traceParent, bool isValid) + { + s_w3cPropagator.ExtractTraceIdAndState(null, (object carrier, string fieldName, out string? fieldValue, out IEnumerable? fieldValues) => + { + fieldValues = null; + fieldValue = null; + + if (fieldName == PropagatorTests.TraceParent) + { + fieldValue = traceParent; + return; + } + }, out string? traceId, out _); + + Assert.Equal(isValid, traceId is not null); + } + private static string? EncodeBaggage(IEnumerable> baggageEntries) { Activity? current = Activity.Current; diff --git a/src/libraries/System.Diagnostics.EventLog/System.Diagnostics.EventLog.slnx b/src/libraries/System.Diagnostics.EventLog/System.Diagnostics.EventLog.slnx index 3758ea2b99c18f..44a456d84025a2 100644 --- a/src/libraries/System.Diagnostics.EventLog/System.Diagnostics.EventLog.slnx +++ b/src/libraries/System.Diagnostics.EventLog/System.Diagnostics.EventLog.slnx @@ -1,31 +1,394 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.EventLog/ref/System.Diagnostics.EventLog.cs b/src/libraries/System.Diagnostics.EventLog/ref/System.Diagnostics.EventLog.cs index 007bd0b4c2eff9..4a1404af7248e8 100644 --- a/src/libraries/System.Diagnostics.EventLog/ref/System.Diagnostics.EventLog.cs +++ b/src/libraries/System.Diagnostics.EventLog/ref/System.Diagnostics.EventLog.cs @@ -227,7 +227,7 @@ public partial class EventLogException : System.Exception { public EventLogException() { } protected EventLogException(int errorCode) { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -235,7 +235,7 @@ protected EventLogException(System.Runtime.Serialization.SerializationInfo seria public EventLogException(string message) { } public EventLogException(string message, System.Exception innerException) { } public override string Message { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -256,7 +256,7 @@ internal EventLogInformation() { } public partial class EventLogInvalidDataException : System.Diagnostics.Eventing.Reader.EventLogException { public EventLogInvalidDataException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -286,7 +286,7 @@ public enum EventLogMode public partial class EventLogNotFoundException : System.Diagnostics.Eventing.Reader.EventLogException { public EventLogNotFoundException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -303,7 +303,7 @@ protected virtual void Dispose(bool disposing) { } public partial class EventLogProviderDisabledException : System.Diagnostics.Eventing.Reader.EventLogException { public EventLogProviderDisabledException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -339,7 +339,7 @@ public void Seek(System.IO.SeekOrigin origin, long offset) { } public partial class EventLogReadingException : System.Diagnostics.Eventing.Reader.EventLogException { public EventLogReadingException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj b/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj index ead0f6629b2bdf..4c75b91cba6a42 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj +++ b/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj @@ -126,6 +126,7 @@ System.Diagnostics.EventLog + diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/EventLogEntry.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/EventLogEntry.cs index 2f963d060616ec..d18b40c71d3a08 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/EventLogEntry.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/EventLogEntry.cs @@ -377,7 +377,8 @@ private static RegistryKey GetSourceRegKey(string logName, string source, string try { eventKey = EventLog.GetEventLogRegKey(machineName, false); - return eventKey?.OpenSubKey(logName ?? "Application", /*writable*/false)?.OpenSubKey(source, /*writeable*/false); + logKey = eventKey?.OpenSubKey(logName ?? "Application", /*writable*/false); + return logKey?.OpenSubKey(source, /*writeable*/false); } finally { diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventLogException.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventLogException.cs index cd1e3e2e4631ec..4de5abf9f0fee1 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventLogException.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventLogException.cs @@ -68,7 +68,7 @@ public override string Message private readonly int _errorCode; -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -78,7 +78,7 @@ protected EventLogException(SerializationInfo serializationInfo, StreamingContex _errorCode = serializationInfo.GetInt32("errorCode"); } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -99,7 +99,7 @@ public EventLogNotFoundException() { } public EventLogNotFoundException(string message) : base(message) { } public EventLogNotFoundException(string message, Exception innerException) : base(message, innerException) { } internal EventLogNotFoundException(int errorCode) : base(errorCode) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -118,7 +118,7 @@ public EventLogReadingException() { } public EventLogReadingException(string message) : base(message) { } public EventLogReadingException(string message, Exception innerException) : base(message, innerException) { } internal EventLogReadingException(int errorCode) : base(errorCode) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -137,7 +137,7 @@ public EventLogProviderDisabledException() { } public EventLogProviderDisabledException(string message) : base(message) { } public EventLogProviderDisabledException(string message, Exception innerException) : base(message, innerException) { } internal EventLogProviderDisabledException(int errorCode) : base(errorCode) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -154,7 +154,7 @@ public EventLogInvalidDataException() { } public EventLogInvalidDataException(string message) : base(message) { } public EventLogInvalidDataException(string message, Exception innerException) : base(message, innerException) { } internal EventLogInvalidDataException(int errorCode) : base(errorCode) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Diagnostics.EventLog/tests/System/Diagnostics/Reader/EventLogExceptionTests.cs b/src/libraries/System.Diagnostics.EventLog/tests/System/Diagnostics/Reader/EventLogExceptionTests.cs index 4bf77f2676e04e..5788c020d8f9b4 100644 --- a/src/libraries/System.Diagnostics.EventLog/tests/System/Diagnostics/Reader/EventLogExceptionTests.cs +++ b/src/libraries/System.Diagnostics.EventLog/tests/System/Diagnostics/Reader/EventLogExceptionTests.cs @@ -11,33 +11,33 @@ public class EventLogExceptionTests [Fact] public void EventLogNotFoundException_Ctor() { - Assert.ThrowsAsync(() => throw new EventLogNotFoundException()); - Assert.ThrowsAsync(() => throw new EventLogNotFoundException("message")); - Assert.ThrowsAsync(() => throw new EventLogNotFoundException("message", new Exception("inner exception"))); + Assert.Throws(new Action(() => { throw new EventLogNotFoundException(); })); + Assert.Throws(new Action(() => { throw new EventLogNotFoundException("message"); })); + Assert.Throws(new Action(() => { throw new EventLogNotFoundException("message", new Exception("inner exception")); })); } [Fact] public void EventLogReadingException_Ctor() { - Assert.ThrowsAsync(() => throw new EventLogReadingException()); - Assert.ThrowsAsync(() => throw new EventLogReadingException("message")); - Assert.ThrowsAsync(() => throw new EventLogReadingException("message", new Exception("inner exception"))); + Assert.Throws(new Action(() => { throw new EventLogReadingException(); })); + Assert.Throws(new Action(() => { throw new EventLogReadingException("message"); })); + Assert.Throws(new Action(() => { throw new EventLogReadingException("message", new Exception("inner exception")); })); } [Fact] public void EventLogProviderDisabledException_Ctor() { - Assert.ThrowsAsync(() => throw new EventLogProviderDisabledException()); - Assert.ThrowsAsync(() => throw new EventLogProviderDisabledException("message")); - Assert.ThrowsAsync(() => throw new EventLogProviderDisabledException("message", new Exception("inner exception"))); + Assert.Throws(new Action(() => { throw new EventLogProviderDisabledException(); })); + Assert.Throws(new Action(() => { throw new EventLogProviderDisabledException("message"); })); + Assert.Throws(new Action(() => { throw new EventLogProviderDisabledException("message", new Exception("inner exception")); })); } [Fact] public void EventLogInvalidDataException_Ctor() { - Assert.ThrowsAsync(() => throw new EventLogInvalidDataException()); - Assert.ThrowsAsync(() => throw new EventLogInvalidDataException("message")); - Assert.ThrowsAsync(() => throw new EventLogInvalidDataException("message", new Exception("inner exception"))); + Assert.Throws(new Action(() => throw new EventLogInvalidDataException())); + Assert.Throws(new Action(() => throw new EventLogInvalidDataException("message"))); + Assert.Throws(new Action(() => throw new EventLogInvalidDataException("message", new Exception("inner exception")))); } } diff --git a/src/libraries/System.Diagnostics.FileVersionInfo/System.Diagnostics.FileVersionInfo.slnx b/src/libraries/System.Diagnostics.FileVersionInfo/System.Diagnostics.FileVersionInfo.slnx index e876759703aa78..a7b23a0f0a78ad 100644 --- a/src/libraries/System.Diagnostics.FileVersionInfo/System.Diagnostics.FileVersionInfo.slnx +++ b/src/libraries/System.Diagnostics.FileVersionInfo/System.Diagnostics.FileVersionInfo.slnx @@ -1,32 +1,426 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.FileVersionInfo/src/System.Diagnostics.FileVersionInfo.csproj b/src/libraries/System.Diagnostics.FileVersionInfo/src/System.Diagnostics.FileVersionInfo.csproj index 230451074f3e08..fd1336ab9e5bd3 100644 --- a/src/libraries/System.Diagnostics.FileVersionInfo/src/System.Diagnostics.FileVersionInfo.csproj +++ b/src/libraries/System.Diagnostics.FileVersionInfo/src/System.Diagnostics.FileVersionInfo.csproj @@ -18,6 +18,7 @@ + - - - + + + - - + + diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/System.Diagnostics.PerformanceCounter.slnx b/src/libraries/System.Diagnostics.PerformanceCounter/System.Diagnostics.PerformanceCounter.slnx index 6c4e4a10d144a9..1a7a8602713e2b 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/System.Diagnostics.PerformanceCounter.slnx +++ b/src/libraries/System.Diagnostics.PerformanceCounter/System.Diagnostics.PerformanceCounter.slnx @@ -18,6 +18,14 @@ + + + + + + + + @@ -44,6 +52,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -60,6 +100,22 @@ + + + + + + + + + + + + + + + + @@ -68,6 +124,14 @@ + + + + + + + + @@ -76,6 +140,22 @@ + + + + + + + + + + + + + + + + @@ -92,6 +172,14 @@ + + + + + + + + @@ -100,6 +188,22 @@ + + + + + + + + + + + + + + + + @@ -125,7 +229,31 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -157,6 +285,22 @@ + + + + + + + + + + + + + + + + @@ -165,6 +309,14 @@ + + + + + + + + @@ -173,6 +325,22 @@ + + + + + + + + + + + + + + + + @@ -189,6 +357,14 @@ + + + + + + + + @@ -197,6 +373,22 @@ + + + + + + + + + + + + + + + + @@ -214,6 +406,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/tests/Helpers.cs b/src/libraries/System.Diagnostics.PerformanceCounter/tests/Helpers.cs index 0e2407302a2ff7..1110cd6fb775e8 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/tests/Helpers.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/tests/Helpers.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.IO; using System.Threading; +using System.ComponentModel; using Xunit; // Implementation is not robust with respect to modifying counter categories @@ -17,6 +18,36 @@ internal class Helpers public static bool CanWriteToPerfCounters { get => PlatformDetection.IsNotWindowsNanoServer; } public static bool CanReadNetPerfCounters { get => File.Exists(Environment.SystemDirectory + Path.DirectorySeparatorChar + "netfxperf.dll"); } + /// + /// Determines if an exception is retriable for performance counter operations. + /// Typically used for file access conflicts and transient system errors. + /// + internal static bool IsRetriableException(Exception ex) + { + // Handle Win32Exception with specific error codes for file access conflicts + if (ex is Win32Exception win32Ex) + { + // ERROR_SHARING_VIOLATION (32) - The process cannot access the file because it is being used by another process + // ERROR_ACCESS_DENIED (5) - Access is denied + // ERROR_LOCK_VIOLATION (33) - The process cannot access the file because another process has locked a portion of the file + return win32Ex.NativeErrorCode == 32 || win32Ex.NativeErrorCode == 5 || win32Ex.NativeErrorCode == 33; + } + + // Handle IOException for file access issues + if (ex is IOException) + { + return true; + } + + // Handle UnauthorizedAccessException + if (ex is UnauthorizedAccessException) + { + return true; + } + + return false; + } + public static void CreateCategory(string categoryName, PerformanceCounterCategoryType categoryType) { string counterName = categoryName.Replace("_Category", "_Counter"); @@ -30,7 +61,12 @@ public static void CreateCategory(string categoryName, string counterName, Perfo // If the category already exists, delete it, then create it. DeleteCategory(categoryName); - PerformanceCounterCategory.Create(categoryName, "description", categoryType, counterName, "counter description"); + + // Retry the Create operation to handle file access conflicts + RetryHelper.Execute(() => + { + PerformanceCounterCategory.Create(categoryName, "description", categoryType, counterName, "counter description"); + }, maxAttempts: 10, retryWhen: IsRetriableException); VerifyPerformanceCounterCategoryCreated(categoryName); } @@ -53,7 +89,11 @@ public static void DeleteCategory(string categoryName) Assert.EndsWith("_Category", categoryName); if (PerformanceCounterCategory.Exists(categoryName)) { - PerformanceCounterCategory.Delete(categoryName); + // Retry the Delete operation to handle file access conflicts + RetryHelper.Execute(() => + { + PerformanceCounterCategory.Delete(categoryName); + }, maxAttempts: 10, retryWhen: IsRetriableException); } int tries = 0; diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceCounterCategoryTests.cs b/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceCounterCategoryTests.cs index 2a164b91ef2aee..dc6d61ad29f49e 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceCounterCategoryTests.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceCounterCategoryTests.cs @@ -87,7 +87,7 @@ public static void PerformanceCounterCategory_CategoryType_MultiInstance() PerformanceCounterCategory pcc = new PerformanceCounterCategory(categoryName); Assert.Equal(PerformanceCounterCategoryType.MultiInstance, Helpers.RetryOnAllPlatformsWithClosingResources(() => pcc.CategoryType)); - PerformanceCounterCategory.Delete(categoryName); + Helpers.DeleteCategory(categoryName); } [ConditionalFact(typeof(Helpers), nameof(Helpers.IsElevatedAndCanWriteAndReadNetPerfCounters))] @@ -100,7 +100,7 @@ public static void PerformanceCounterCategory_CategoryType_SingleInstance() PerformanceCounterCategory pcc = new PerformanceCounterCategory(categoryName); Assert.Equal(PerformanceCounterCategoryType.SingleInstance, Helpers.RetryOnAllPlatformsWithClosingResources(() => pcc.CategoryType)); - PerformanceCounterCategory.Delete(categoryName); + Helpers.DeleteCategory(categoryName); } #pragma warning disable 0618 // obsolete warning @@ -112,10 +112,13 @@ public static void PerformanceCounterCategory_Create_Obsolete() Helpers.DeleteCategory(categoryName); - PerformanceCounterCategory.Create(categoryName, "category help", counterName, "counter help"); + RetryHelper.Execute(() => + { + PerformanceCounterCategory.Create(categoryName, "category help", counterName, "counter help"); + }, maxAttempts: 10, retryWhen: Helpers.IsRetriableException); Assert.True(PerformanceCounterCategory.Exists(categoryName)); - PerformanceCounterCategory.Delete(categoryName); + Helpers.DeleteCategory(categoryName); } [ConditionalFact(typeof(Helpers), nameof(Helpers.IsElevatedAndCanWriteToPerfCounters))] @@ -129,10 +132,13 @@ public static void PerformanceCounterCategory_Create_Obsolete_CCD() Helpers.DeleteCategory(categoryName); - PerformanceCounterCategory.Create(categoryName, "category help", ccdc); + RetryHelper.Execute(() => + { + PerformanceCounterCategory.Create(categoryName, "category help", ccdc); + }, maxAttempts: 10, retryWhen: Helpers.IsRetriableException); Assert.True(PerformanceCounterCategory.Exists(categoryName)); - PerformanceCounterCategory.Delete(categoryName); + Helpers.DeleteCategory(categoryName); } #pragma warning restore 0618 @@ -209,7 +215,7 @@ public static void PerformanceCounterCategory_DeleteCategory() string categoryName = nameof(PerformanceCounterCategory_DeleteCategory) + "_Category"; Helpers.CreateCategory(categoryName, PerformanceCounterCategoryType.SingleInstance); - PerformanceCounterCategory.Delete(categoryName); + Helpers.DeleteCategory(categoryName); Assert.False(PerformanceCounterCategory.Exists(categoryName)); } @@ -232,7 +238,7 @@ public static void PerformanceCounterCategory_GetCounters() PerformanceCounter[] counters = pcc.GetCounters(); Assert.True(counters.Length > 0); - PerformanceCounterCategory.Delete(categoryName); + Helpers.DeleteCategory(categoryName); } [Fact] diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceDataTests.cs b/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceDataTests.cs index a48b07878b4d09..39c46e3ad87192 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceDataTests.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceDataTests.cs @@ -138,7 +138,7 @@ public void PerformanceCounter_PerformanceData_CounterSet_AlreadyRegistered() [ConditionalTheory(typeof(Helpers), nameof(Helpers.IsElevatedAndCanWriteToPerfCounters))] [InlineData("", typeof(ArgumentException))] [InlineData(null, typeof(ArgumentNullException))] - public void PerformanceCounter_PerformanceData_CounterSet_InvalidInstanceName(string instanceName, Type exceptionType) + public void PerformanceCounter_PerformanceData_CounterSet_InvalidInstanceName(string? instanceName, Type exceptionType) { using (CounterSet typingCounterSet = new CounterSet(_fixture._providerId, _fixture._typingCounterSetId, CounterSetInstanceType.Single)) { @@ -151,7 +151,7 @@ public void PerformanceCounter_PerformanceData_CounterSet_InvalidInstanceName(st [ConditionalTheory(typeof(Helpers), nameof(Helpers.IsElevatedAndCanWriteToPerfCounters))] [InlineData("", "counterName", "counterName", typeof(ArgumentException))] [InlineData(null, "counterName", "CounterName", typeof(ArgumentNullException))] - public void PerformanceCounter_PerformanceData_AddCounter_InvalidCounterName(string counterName, string netCoreParameterName, string netfxParameterName, Type exceptionType) + public void PerformanceCounter_PerformanceData_AddCounter_InvalidCounterName(string? counterName, string netCoreParameterName, string netfxParameterName, Type exceptionType) { using (CounterSet typingCounterSet = new CounterSet(_fixture._providerId, _fixture._typingCounterSetId, CounterSetInstanceType.Single)) { @@ -163,7 +163,7 @@ public void PerformanceCounter_PerformanceData_AddCounter_InvalidCounterName(str [ConditionalTheory(typeof(Helpers), nameof(Helpers.IsElevatedAndCanWriteToPerfCounters))] [InlineData("")] [InlineData(null)] - public void PerformanceCounter_PerformanceData_InvalidCounterName_Indexer(string counterName) + public void PerformanceCounter_PerformanceData_InvalidCounterName_Indexer(string? counterName) { using (CounterSet typingCounterSet = new CounterSet(_fixture._providerId, _fixture._typingCounterSetId, CounterSetInstanceType.Single)) { diff --git a/src/libraries/System.Diagnostics.Process/System.Diagnostics.Process.slnx b/src/libraries/System.Diagnostics.Process/System.Diagnostics.Process.slnx index c98a2524ae0738..69c100836b1fc2 100644 --- a/src/libraries/System.Diagnostics.Process/System.Diagnostics.Process.slnx +++ b/src/libraries/System.Diagnostics.Process/System.Diagnostics.Process.slnx @@ -52,6 +52,14 @@ + + + + + + + + @@ -60,6 +68,22 @@ + + + + + + + + + + + + + + + + @@ -100,6 +124,22 @@ + + + + + + + + + + + + + + + + @@ -116,6 +156,14 @@ + + + + + + + + @@ -124,6 +172,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -140,6 +268,14 @@ + + + + + + + + @@ -148,6 +284,14 @@ + + + + + + + + @@ -196,6 +340,14 @@ + + + + + + + + @@ -204,6 +356,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -229,6 +413,14 @@ + + + + + + + + @@ -237,7 +429,71 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -261,6 +517,22 @@ + + + + + + + + + + + + + + + + @@ -269,6 +541,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -277,6 +637,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -285,6 +669,22 @@ + + + + + + + + + + + + + + + + @@ -293,6 +693,14 @@ + + + + + + + + @@ -301,6 +709,14 @@ + + + + + + + + @@ -309,6 +725,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -326,6 +774,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs b/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs index d4cf2170b88b83..17366ae9811736 100644 --- a/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs +++ b/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs @@ -219,6 +219,8 @@ public ProcessStartInfo(string fileName, System.Collections.Generic.IEnumerable< public System.Collections.ObjectModel.Collection ArgumentList { get { throw null; } } [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public string Arguments { get { throw null; } set { } } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public bool CreateNewProcessGroup { get { throw null; } set { } } public bool CreateNoWindow { get { throw null; } set { } } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] [System.Diagnostics.CodeAnalysis.AllowNullAttribute] diff --git a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj index ba226f7bc0da27..ad692fafc90f2c 100644 --- a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj +++ b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj @@ -376,23 +376,23 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Linux.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Linux.cs index 3c707d7473bcd9..5cf8c5c76a993d 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Linux.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Linux.cs @@ -105,7 +105,7 @@ private static DateTime BootTime /// Gets execution path private static string? GetPathToOpenFile() { - string[] allowedProgramsToRun = { "xdg-open", "gnome-open", "kfmclient" }; + ReadOnlySpan allowedProgramsToRun = ["xdg-open", "gnome-open", "kfmclient"]; foreach (var program in allowedProgramsToRun) { string? pathToProgram = FindProgramInPath(program); diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs index 06a2bd51d6d402..dc05e138a5aec6 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs @@ -505,6 +505,7 @@ private unsafe bool StartWithCreateProcess(ProcessStartInfo startInfo) // set up the creation flags parameter int creationFlags = 0; if (startInfo.CreateNoWindow) creationFlags |= Interop.Advapi32.StartupInfoOptions.CREATE_NO_WINDOW; + if (startInfo.CreateNewProcessGroup) creationFlags |= Interop.Advapi32.StartupInfoOptions.CREATE_NEW_PROCESS_GROUP; // set up the environment block parameter string? environmentBlock = null; diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessModule.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessModule.cs index 9d0a3338a38edf..e2b324c801cdd5 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessModule.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessModule.cs @@ -15,7 +15,6 @@ public class ProcessModule : Component { private readonly string _fileName; private readonly string _moduleName; - private FileVersionInfo? _fileVersionInfo; internal ProcessModule(string fileName, string moduleName) { @@ -55,7 +54,7 @@ internal ProcessModule(string fileName, string moduleName) /// /// Returns version information about the module. /// - public FileVersionInfo FileVersionInfo => _fileVersionInfo ??= FileVersionInfo.GetVersionInfo(_fileName); + public FileVersionInfo FileVersionInfo => field ??= FileVersionInfo.GetVersionInfo(_fileName); public override string ToString() => $"{base.ToString()} ({ModuleName})"; } diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Unix.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Unix.cs index 9664815dcde794..196d57bf0b36b9 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Unix.cs @@ -52,5 +52,12 @@ public SecureString? Password get { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(Password))); } set { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(Password))); } } + + [SupportedOSPlatform("windows")] + public bool CreateNewProcessGroup + { + get { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(CreateNewProcessGroup))); } + set { throw new PlatformNotSupportedException(SR.Format(SR.ProcessStartSingleFeatureNotSupported, nameof(CreateNewProcessGroup))); } + } } } diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Windows.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Windows.cs index 8869c1809341f3..6217aeb9c5a5b3 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Windows.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessStartInfo.Windows.cs @@ -46,5 +46,17 @@ public string Domain [CLSCompliant(false)] [SupportedOSPlatform("windows")] public SecureString? Password { get; set; } + + /// + /// Gets or sets a value indicating whether to start the process in a new process group. + /// + /// true if the process should be started in a new process group; otherwise, false. The default is false. + /// + /// When a process is created in a new process group, it becomes the root of a new process group. + /// An implicit call to SetConsoleCtrlHandler(NULL,TRUE) is made on behalf of the new process, this means that the new process has CTRL+C disabled. + /// This property is useful for preventing console control events sent to the child process from affecting the parent process. + /// + [SupportedOSPlatform("windows")] + public bool CreateNewProcessGroup { get; set; } } } diff --git a/src/libraries/System.Diagnostics.Process/tests/Interop.cs b/src/libraries/System.Diagnostics.Process/tests/Interop.cs index 969995e36d8a33..6bd2ddebbc8f6a 100644 --- a/src/libraries/System.Diagnostics.Process/tests/Interop.cs +++ b/src/libraries/System.Diagnostics.Process/tests/Interop.cs @@ -72,6 +72,11 @@ public struct SID_AND_ATTRIBUTES public int Attributes; } + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId); + [DllImport("kernel32.dll")] public static extern bool GetProcessWorkingSetSizeEx(SafeProcessHandle hProcess, out IntPtr lpMinimumWorkingSetSize, out IntPtr lpMaximumWorkingSetSize, out uint flags); diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs index 728e52f520208f..5a7cf2c5c01be6 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs @@ -905,12 +905,35 @@ public void TestEnvironmentVariablesPropertyUnix() }); } + [Fact] + [PlatformSpecific(TestPlatforms.Windows)] + public void CreateNewProcessGroup_SetWindows_GetReturnsExpected() + { + ProcessStartInfo psi = new ProcessStartInfo(); + Assert.False(psi.CreateNewProcessGroup); + + psi.CreateNewProcessGroup = true; + Assert.True(psi.CreateNewProcessGroup); + + psi.CreateNewProcessGroup = false; + Assert.False(psi.CreateNewProcessGroup); + } + + [Fact] + [PlatformSpecific(TestPlatforms.AnyUnix)] + public void CreateNewProcessGroup_GetSetUnix_ThrowsPlatformNotSupportedException() + { + var info = new ProcessStartInfo(); + Assert.Throws(() => info.CreateNewProcessGroup); + Assert.Throws(() => info.CreateNewProcessGroup = true); + } + [Theory] [InlineData(null)] [InlineData("")] [InlineData("domain")] [PlatformSpecific(TestPlatforms.Windows)] - public void Domain_SetWindows_GetReturnsExpected(string domain) + public void Domain_SetWindows_GetReturnsExpected(string? domain) { var info = new ProcessStartInfo { Domain = domain }; Assert.Equal(domain ?? string.Empty, info.Domain); @@ -929,7 +952,7 @@ public void Domain_GetSetUnix_ThrowsPlatformNotSupportedException() [InlineData(null)] [InlineData("")] [InlineData("filename")] - public void FileName_Set_GetReturnsExpected(string fileName) + public void FileName_Set_GetReturnsExpected(string? fileName) { var info = new ProcessStartInfo { FileName = fileName }; Assert.Equal(fileName ?? string.Empty, info.FileName); @@ -978,7 +1001,7 @@ public void UseCredentialsForNetworkingOnly_GetSetUnix_ThrowsPlatformNotSupporte [InlineData("")] [InlineData("passwordInClearText")] [PlatformSpecific(TestPlatforms.Windows)] - public void PasswordInClearText_SetWindows_GetReturnsExpected(string passwordInClearText) + public void PasswordInClearText_SetWindows_GetReturnsExpected(string? passwordInClearText) { var info = new ProcessStartInfo { PasswordInClearText = passwordInClearText }; Assert.Equal(passwordInClearText, info.PasswordInClearText); @@ -1018,7 +1041,7 @@ public void Password_GetSetUnix_ThrowsPlatformNotSupportedException() [InlineData(null)] [InlineData("")] [InlineData("domain")] - public void UserName_Set_GetReturnsExpected(string userName) + public void UserName_Set_GetReturnsExpected(string? userName) { var info = new ProcessStartInfo { UserName = userName }; Assert.Equal(userName ?? string.Empty, info.UserName); @@ -1028,7 +1051,7 @@ public void UserName_Set_GetReturnsExpected(string userName) [InlineData(null)] [InlineData("")] [InlineData("verb")] - public void Verb_Set_GetReturnsExpected(string verb) + public void Verb_Set_GetReturnsExpected(string? verb) { var info = new ProcessStartInfo { Verb = verb }; Assert.Equal(verb ?? string.Empty, info.Verb); @@ -1058,7 +1081,7 @@ public void WindowStyle_Set_GetReturnsExpected(ProcessWindowStyle style) [InlineData(null)] [InlineData("")] [InlineData("workingdirectory")] - public void WorkingDirectory_Set_GetReturnsExpected(string workingDirectory) + public void WorkingDirectory_Set_GetReturnsExpected(string? workingDirectory) { var info = new ProcessStartInfo { WorkingDirectory = workingDirectory }; Assert.Equal(workingDirectory ?? string.Empty, info.WorkingDirectory); diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs index 7f66696c6b2755..a02cc15c3a6626 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs @@ -306,7 +306,7 @@ public void ProcessStart_UseShellExecute_OnUnix_Executable_PassesArguments() [InlineData("Open", true)] [InlineData("invalid", false)] [PlatformSpecific(TestPlatforms.Linux)] // s_allowedProgramsToRun is Linux specific - public void ProcessStart_UseShellExecute_OnUnix_ValidVerbs(string verb, bool isValid) + public void ProcessStart_UseShellExecute_OnUnix_ValidVerbs(string? verb, bool isValid) { // Create a script that we'll use to 'open' the file by putting it on PATH // with the appropriate name. @@ -1047,5 +1047,16 @@ private static string StartAndReadToEnd(string filename, string[] arguments) return process.StandardOutput.ReadToEnd(); } } + + private static void SendSignal(PosixSignal signal, int processId) + { + int result = kill(processId, Interop.Sys.GetPlatformSignalNumber(signal)); + if (result != 0) + { + throw new Win32Exception(Marshal.GetLastWin32Error(), $"Failed to send signal {signal} to process {processId}"); + } + } + + private static unsafe void ReEnableCtrlCHandlerIfNeeded(PosixSignal signal) { } } } diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Windows.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Windows.cs index 6fb91c0f4e113e..7850ca8afcbd7d 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Windows.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.Windows.cs @@ -2,7 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.ComponentModel; using System.IO; +using System.Runtime.InteropServices; +using Microsoft.DotNet.XUnitExtensions; +using Xunit; namespace System.Diagnostics.Tests { @@ -15,5 +19,41 @@ private string WriteScriptFile(string directory, string name, int returnValue) File.WriteAllText(filename, $"exit {returnValue}"); return filename; } + + private static void SendSignal(PosixSignal signal, int processId) + { + uint dwCtrlEvent = signal switch + { + PosixSignal.SIGINT => Interop.Kernel32.CTRL_C_EVENT, + PosixSignal.SIGQUIT => Interop.Kernel32.CTRL_BREAK_EVENT, + _ => throw new ArgumentOutOfRangeException(nameof(signal)) + }; + + if (!Interop.GenerateConsoleCtrlEvent(dwCtrlEvent, (uint)processId)) + { + int error = Marshal.GetLastWin32Error(); + if (error == Interop.Errors.ERROR_INVALID_FUNCTION && PlatformDetection.IsInContainer) + { + // Docker in CI runs without a console attached. + throw new SkipTestException($"GenerateConsoleCtrlEvent failed with ERROR_INVALID_FUNCTION. The process is not a console process or does not have a console."); + } + + throw new Win32Exception(error); + } + } + + // See https://learn.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw#remarks: + // When a process is created with CREATE_NEW_PROCESS_GROUP specified, an implicit call to SetConsoleCtrlHandler(NULL,TRUE) + // is made on behalf of the new process; this means that the new process has CTRL+C disabled. + private static unsafe void ReEnableCtrlCHandlerIfNeeded(PosixSignal signal) + { + if (signal is PosixSignal.SIGINT) + { + if (!Interop.Kernel32.SetConsoleCtrlHandler(null, false)) + { + throw new Win32Exception(); + } + } + } } } diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs index a3b2a7a97f0508..88d8c78073ebb8 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Net; using System.Reflection; +using System.Runtime.InteropServices; using System.Security; using System.Text; using System.Threading; @@ -80,6 +81,82 @@ private void AssertNonZeroAllZeroDarwin(long value) } } + public static IEnumerable SignalTestData() + { + if (OperatingSystem.IsWindows()) + { + // GenerateConsoleCtrlEvent only supports sending CTRL_C_EVENT and CTRL_BREAK_EVENT + yield return new object[] { PosixSignal.SIGINT }; + yield return new object[] { PosixSignal.SIGQUIT }; + } + else + { + foreach (PosixSignal signal in Enum.GetValues()) + { + yield return new object[] { signal }; + } + // Test a few raw signals. + yield return new object[] { (PosixSignal)3 }; // SIGQUIT + yield return new object[] { (PosixSignal)15 }; // SIGTERM + } + } + + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [MemberData(nameof(SignalTestData))] + public void TestCreateNewProcessGroup_HandlerReceivesExpectedSignal(PosixSignal signal) + { + const string PosixSignalRegistrationCreatedMessage = "PosixSignalRegistration created..."; + + var remoteInvokeOptions = new RemoteInvokeOptions { CheckExitCode = false }; + remoteInvokeOptions.StartInfo.RedirectStandardOutput = true; + if (OperatingSystem.IsWindows()) + { + remoteInvokeOptions.StartInfo.CreateNewProcessGroup = true; + } + + using RemoteInvokeHandle remoteHandle = RemoteExecutor.Invoke( + (signalStr) => + { + PosixSignal expectedSignal = Enum.Parse(signalStr); + using ManualResetEvent receivedSignalEvent = new ManualResetEvent(false); + ReEnableCtrlCHandlerIfNeeded(expectedSignal); + + using PosixSignalRegistration p = PosixSignalRegistration.Create(expectedSignal, (ctx) => + { + Assert.Equal(expectedSignal, ctx.Signal); + receivedSignalEvent.Set(); + ctx.Cancel = true; + }); + + Console.WriteLine(PosixSignalRegistrationCreatedMessage); + + Assert.True(receivedSignalEvent.WaitOne(WaitInMS)); + + return 0; + }, + arg: $"{signal}", + remoteInvokeOptions); + + while (!remoteHandle.Process.StandardOutput.ReadLine().EndsWith(PosixSignalRegistrationCreatedMessage)) + { + Thread.Sleep(20); + } + + try + { + SendSignal(signal, remoteHandle.Process.Id); + + Assert.True(remoteHandle.Process.WaitForExit(WaitInMS)); + Assert.Equal(0, remoteHandle.Process.ExitCode); + } + finally + { + // If sending the signal fails, we want to kill the process ASAP + // to prevent RemoteExecutor's timeout from hiding it. + remoteHandle.Process.Kill(); + } + } + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(-2)] [InlineData((long)int.MaxValue + 1)] @@ -1245,7 +1322,7 @@ public void GetProcesses_RemoteMachinePath_ReturnsExpected() [InlineData(null)] [InlineData("")] [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS, "libproc is not supported on iOS/tvOS")] - public void GetProcessesByName_NullEmpty_ReturnsAllProcesses(string name) + public void GetProcessesByName_NullEmpty_ReturnsAllProcesses(string? name) { Process currentProcess = Process.GetCurrentProcess(); Process[] processes = Process.GetProcessesByName(name); diff --git a/src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj b/src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj index a69d3eb2372059..718bddd017ea89 100644 --- a/src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj +++ b/src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj @@ -44,12 +44,18 @@ + + Link="Common\Interop\Windows\Interop.Libraries.cs" /> + Link="Common\Interop\Windows\Kernel32\Interop.LoadLibrary.cs" /> + + @@ -63,6 +69,10 @@ Link="Common\Interop\OSX\Interop.libproc.cs" /> + + diff --git a/src/libraries/System.Diagnostics.StackTrace/System.Diagnostics.StackTrace.slnx b/src/libraries/System.Diagnostics.StackTrace/System.Diagnostics.StackTrace.slnx index 52c75353e4bcd3..cad1229b27db15 100644 --- a/src/libraries/System.Diagnostics.StackTrace/System.Diagnostics.StackTrace.slnx +++ b/src/libraries/System.Diagnostics.StackTrace/System.Diagnostics.StackTrace.slnx @@ -84,6 +84,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -100,6 +140,22 @@ + + + + + + + + + + + + + + + + @@ -108,6 +164,22 @@ + + + + + + + + + + + + + + + + @@ -165,6 +237,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -181,6 +293,22 @@ + + + + + + + + + + + + + + + + @@ -189,6 +317,22 @@ + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/DiagnosticMethodInfoTests.cs b/src/libraries/System.Diagnostics.StackTrace/tests/DiagnosticMethodInfoTests.cs index 662b5f04f63d7b..20859c512b58be 100644 --- a/src/libraries/System.Diagnostics.StackTrace/tests/DiagnosticMethodInfoTests.cs +++ b/src/libraries/System.Diagnostics.StackTrace/tests/DiagnosticMethodInfoTests.cs @@ -192,6 +192,7 @@ public unsafe void Create_MarshalledPointer() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/117165", TestPlatforms.Browser)] public unsafe void Create_StackFrame() { StackTrace tr = NonGenericStackTraceClass.TestNonGeneric(); diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/StackFrameTests.cs b/src/libraries/System.Diagnostics.StackTrace/tests/StackFrameTests.cs index 72664b38685b4e..58984e678e8f04 100644 --- a/src/libraries/System.Diagnostics.StackTrace/tests/StackFrameTests.cs +++ b/src/libraries/System.Diagnostics.StackTrace/tests/StackFrameTests.cs @@ -76,7 +76,7 @@ public void SkipFrames_ManyFrames_HasNoMethod(int skipFrames) [InlineData(null, StackFrame.OFFSET_UNKNOWN)] [InlineData("", 0)] [InlineData("FileName", 1)] - public void Ctor_Filename_LineNumber(string fileName, int lineNumber) + public void Ctor_Filename_LineNumber(string? fileName, int lineNumber) { var stackFrame = new StackFrame(fileName, lineNumber); Assert.Equal(fileName, stackFrame.GetFileName()); @@ -91,7 +91,7 @@ public void Ctor_Filename_LineNumber(string fileName, int lineNumber) [InlineData(null, StackFrame.OFFSET_UNKNOWN, 0)] [InlineData("", 0, StackFrame.OFFSET_UNKNOWN)] [InlineData("FileName", 1, 2)] - public void Ctor_Filename_LineNumber_ColNumber(string fileName, int lineNumber, int columnNumber) + public void Ctor_Filename_LineNumber_ColNumber(string? fileName, int lineNumber, int columnNumber) { var stackFrame = new StackFrame(fileName, lineNumber, columnNumber); Assert.Equal(fileName, stackFrame.GetFileName()); diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs b/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs index edd78bf6e61831..7ce245079cbe3c 100644 --- a/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs +++ b/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceSymbolsTests.cs @@ -10,8 +10,7 @@ namespace System.Diagnostics.SymbolStore.Tests public class StackTraceSymbolsTests { [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.HasAssemblyFiles))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/51399", TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.MacCatalyst)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951", TestPlatforms.Android)] + [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.MacCatalyst | TestPlatforms.Android, "Symbols are in a different location on mobile platforms")] public void StackTraceSymbolsDoNotLockFile() { var asmPath = AssemblyPathHelper.GetAssemblyLocation(typeof(StackTraceSymbolsTests).Assembly); diff --git a/src/libraries/System.Diagnostics.TextWriterTraceListener/System.Diagnostics.TextWriterTraceListener.slnx b/src/libraries/System.Diagnostics.TextWriterTraceListener/System.Diagnostics.TextWriterTraceListener.slnx index f8f3200da374a4..3928393ca05533 100644 --- a/src/libraries/System.Diagnostics.TextWriterTraceListener/System.Diagnostics.TextWriterTraceListener.slnx +++ b/src/libraries/System.Diagnostics.TextWriterTraceListener/System.Diagnostics.TextWriterTraceListener.slnx @@ -1,38 +1,1106 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.TextWriterTraceListener/src/System.Diagnostics.TextWriterTraceListener.csproj b/src/libraries/System.Diagnostics.TextWriterTraceListener/src/System.Diagnostics.TextWriterTraceListener.csproj index 38b5ab697c6f9a..1e651f1220c6e0 100644 --- a/src/libraries/System.Diagnostics.TextWriterTraceListener/src/System.Diagnostics.TextWriterTraceListener.csproj +++ b/src/libraries/System.Diagnostics.TextWriterTraceListener/src/System.Diagnostics.TextWriterTraceListener.csproj @@ -13,19 +13,19 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.TextWriterTraceListener/tests/XmlWriterTraceListenerTests.cs b/src/libraries/System.Diagnostics.TextWriterTraceListener/tests/XmlWriterTraceListenerTests.cs index 20576cc9190b91..b48216eae4f7b9 100644 --- a/src/libraries/System.Diagnostics.TextWriterTraceListener/tests/XmlWriterTraceListenerTests.cs +++ b/src/libraries/System.Diagnostics.TextWriterTraceListener/tests/XmlWriterTraceListenerTests.cs @@ -187,7 +187,7 @@ public void WriteTest(string message, string expectedXml) [Theory] [InlineData("Fail:", null)] [InlineData("Fail:", "the process failed when running")] - public void FailTest(string message, string detailMessage) + public void FailTest(string message, string? detailMessage) { string file = GetTestFilePath(); DateTime date; @@ -213,7 +213,7 @@ public void FailTest(string message, string detailMessage) [Theory] [InlineData("This is a format without args", null)] [InlineData("This is my {0} to {1} a trace with {0} {2} format {3}", new object[] { "test", "try", "", 3 })] - public void TraceEventFormat(string format, object[] args) + public void TraceEventFormat(string format, object[]? args) { string file = GetTestFilePath(); var eventCache = new TraceEventCache(); diff --git a/src/libraries/System.Diagnostics.TraceSource/System.Diagnostics.TraceSource.slnx b/src/libraries/System.Diagnostics.TraceSource/System.Diagnostics.TraceSource.slnx index e514d8b802f30b..2792fd14fc4013 100644 --- a/src/libraries/System.Diagnostics.TraceSource/System.Diagnostics.TraceSource.slnx +++ b/src/libraries/System.Diagnostics.TraceSource/System.Diagnostics.TraceSource.slnx @@ -18,6 +18,14 @@ + + + + + + + + @@ -44,6 +52,22 @@ + + + + + + + + + + + + + + + + @@ -100,6 +124,22 @@ + + + + + + + + + + + + + + + + @@ -116,6 +156,14 @@ + + + + + + + + @@ -124,6 +172,22 @@ + + + + + + + + + + + + + + + + @@ -140,6 +204,14 @@ + + + + + + + + @@ -148,6 +220,14 @@ + + + + + + + + @@ -181,7 +261,15 @@ - + + + + + + + + + @@ -221,6 +309,14 @@ + + + + + + + + @@ -245,6 +341,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -253,6 +373,14 @@ + + + + + + + + @@ -261,6 +389,22 @@ + + + + + + + + + + + + + + + + @@ -277,6 +421,14 @@ + + + + + + + + @@ -285,6 +437,14 @@ + + + + + + + + @@ -310,6 +470,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingSwitchEventArgs.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingSwitchEventArgs.cs index 651bfd29fb0c77..f277ea680e4e19 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingSwitchEventArgs.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingSwitchEventArgs.cs @@ -8,11 +8,18 @@ namespace System.Diagnostics /// public sealed class InitializingSwitchEventArgs : EventArgs { + /// + /// Initializes a new instance of the class. + /// + /// The switch that is being initialized. public InitializingSwitchEventArgs(Switch @switch) { Switch = @switch; } + /// + /// Gets the that is being initialized. + /// public Switch Switch { get; } } } diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingTraceSourceEventArgs.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingTraceSourceEventArgs.cs index b4b3aac66ac5cc..873234cc72d06e 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingTraceSourceEventArgs.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingTraceSourceEventArgs.cs @@ -8,12 +8,23 @@ namespace System.Diagnostics /// public sealed class InitializingTraceSourceEventArgs : EventArgs { + /// + /// Initializes a new instance of the class. + /// + /// The trace source that is being initialized. public InitializingTraceSourceEventArgs(TraceSource traceSource) { TraceSource = traceSource; } + /// + /// Gets the trace source that is being initialized. + /// public TraceSource TraceSource { get; } + + /// + /// Gets or sets a value indicating whether the trace source was initialized from configuration. + /// public bool WasInitialized { get; set; } } } diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs index a6b4f3c41ec044..035debdb32a3c9 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs @@ -25,25 +25,14 @@ public abstract class Switch private bool _initializing; private volatile string? _switchValueString = string.Empty; private readonly string _defaultValue; - private object? _initializedLock; private static readonly List> s_switches = new List>(); private static int s_LastCollectionCount; private StringDictionary? _attributes; - private object InitializedLock - { - get - { - if (_initializedLock == null) - { - object o = new object(); - Interlocked.CompareExchange(ref _initializedLock, o, null); - } + private object InitializedLock => + field ?? Interlocked.CompareExchange(ref field, new object(), null) ?? field; - return _initializedLock; - } - } /// /// Initializes a new instance of the diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs index 52c35b964b8845..3a129ec2b04cd3 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs @@ -19,12 +19,8 @@ private Trace() { } - private static CorrelationManager? s_correlationManager; - public static CorrelationManager CorrelationManager => - Volatile.Read(ref s_correlationManager) ?? - Interlocked.CompareExchange(ref s_correlationManager, new CorrelationManager(), null) ?? - s_correlationManager; + field ?? Interlocked.CompareExchange(ref field, new(), null) ?? field; /// /// Gets the collection of listeners that is monitoring the trace output. diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceEventCache.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceEventCache.cs index 6d314bda14124f..a4afc07f3f33b2 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceEventCache.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceEventCache.cs @@ -13,7 +13,6 @@ public partial class TraceEventCache { private long _timeStamp = -1; private DateTime _dateTime = DateTime.MinValue; - private string? _stackTrace; public DateTime DateTime { @@ -51,7 +50,7 @@ public long Timestamp } } - public string Callstack => _stackTrace ??= Environment.StackTrace; + public string Callstack => field ??= Environment.StackTrace; public Stack LogicalOperationStack { diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs index 0b9975b608d72e..c133a2a547827b 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs @@ -41,7 +41,6 @@ public override void OnIndentSizeChanged(int indentSize) public override void WriteLine(string? message) { TraceInternal.WriteLine(message); } } - private static volatile string? s_appName; private static volatile TraceListenerCollection? s_listeners; private static volatile bool s_autoFlush; private static volatile bool s_useGlobalLock; @@ -81,7 +80,7 @@ public static TraceListenerCollection Listeners } } - internal static string AppName => s_appName ??= Assembly.GetEntryAssembly()?.GetName().Name ?? string.Empty; + internal static string AppName => field ??= Assembly.GetEntryAssembly()?.GetName().Name ?? string.Empty; public static bool AutoFlush { diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs index d739be5250b346..a23cab3659aa3f 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs @@ -21,7 +21,6 @@ public abstract class TraceListener : MarshalByRefObject, IDisposable private int _indentSize = 4; private TraceOptions _traceOptions = TraceOptions.None; private bool _needIndent = true; - private StringDictionary? _attributes; private string? _listenerName; private TraceFilter? _filter; @@ -42,7 +41,7 @@ protected TraceListener(string? name) _listenerName = name; } - public StringDictionary Attributes => _attributes ??= new StringDictionary(); + public StringDictionary Attributes => field ??= new StringDictionary(); /// /// Gets or sets a name for this . diff --git a/src/libraries/System.DirectoryServices.AccountManagement/Directory.Build.props b/src/libraries/System.DirectoryServices.AccountManagement/Directory.Build.props index de81d80c303d7d..395c1d3ae6ba72 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/Directory.Build.props +++ b/src/libraries/System.DirectoryServices.AccountManagement/Directory.Build.props @@ -3,5 +3,6 @@ ECMA windows + false \ No newline at end of file diff --git a/src/libraries/System.DirectoryServices.AccountManagement/System.DirectoryServices.AccountManagement.slnx b/src/libraries/System.DirectoryServices.AccountManagement/System.DirectoryServices.AccountManagement.slnx index 2f1b6ac65ab5c5..71e480bf33a511 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/System.DirectoryServices.AccountManagement.slnx +++ b/src/libraries/System.DirectoryServices.AccountManagement/System.DirectoryServices.AccountManagement.slnx @@ -52,6 +52,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -76,6 +100,14 @@ + + + + + + + + @@ -100,6 +132,22 @@ + + + + + + + + + + + + + + + + @@ -108,6 +156,22 @@ + + + + + + + + + + + + + + + + @@ -124,6 +188,22 @@ + + + + + + + + + + + + + + + + @@ -140,6 +220,22 @@ + + + + + + + + + + + + + + + + @@ -148,6 +244,22 @@ + + + + + + + + + + + + + + + + @@ -181,7 +293,31 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -213,6 +349,14 @@ + + + + + + + + @@ -237,6 +381,14 @@ + + + + + + + + @@ -245,6 +397,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -253,6 +429,22 @@ + + + + + + + + + + + + + + + + @@ -269,6 +461,22 @@ + + + + + + + + + + + + + + + + @@ -277,6 +485,22 @@ + + + + + + + + + + + + + + + + @@ -294,6 +518,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.DirectoryServices.AccountManagement/ref/System.DirectoryServices.AccountManagement.cs b/src/libraries/System.DirectoryServices.AccountManagement/ref/System.DirectoryServices.AccountManagement.cs index 4f7382064d92da..f495f8490f293f 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/ref/System.DirectoryServices.AccountManagement.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/ref/System.DirectoryServices.AccountManagement.cs @@ -151,7 +151,7 @@ public enum MatchType public partial class MultipleMatchesException : System.DirectoryServices.AccountManagement.PrincipalException { public MultipleMatchesException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -162,7 +162,7 @@ public MultipleMatchesException(string message, System.Exception innerException) public partial class NoMatchingPrincipalException : System.DirectoryServices.AccountManagement.PrincipalException { public NoMatchingPrincipalException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -173,7 +173,7 @@ public NoMatchingPrincipalException(string message, System.Exception innerExcept public partial class PasswordException : System.DirectoryServices.AccountManagement.PrincipalException { public PasswordException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -276,7 +276,7 @@ public void Dispose() { } public abstract partial class PrincipalException : System.SystemException { private protected PrincipalException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -285,7 +285,7 @@ protected PrincipalException(System.Runtime.Serialization.SerializationInfo info public partial class PrincipalExistsException : System.DirectoryServices.AccountManagement.PrincipalException { public PrincipalExistsException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -296,7 +296,7 @@ public PrincipalExistsException(string message, System.Exception innerException) public partial class PrincipalOperationException : System.DirectoryServices.AccountManagement.PrincipalException { public PrincipalOperationException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -306,7 +306,7 @@ public PrincipalOperationException(string message, System.Exception innerExcepti public PrincipalOperationException(string message, System.Exception innerException, int errorCode) { } public PrincipalOperationException(string message, int errorCode) { } public int ErrorCode { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -334,7 +334,7 @@ public void Dispose() { } public partial class PrincipalServerDownException : System.DirectoryServices.AccountManagement.PrincipalException { public PrincipalServerDownException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -344,7 +344,7 @@ public PrincipalServerDownException(string message, System.Exception innerExcept public PrincipalServerDownException(string message, System.Exception innerException, int errorCode) { } public PrincipalServerDownException(string message, System.Exception innerException, int errorCode, string serverName) { } public PrincipalServerDownException(string message, int errorCode) { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj b/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj index a92c51f7b9aa4a..2d658680497482 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj @@ -7,7 +7,6 @@ true $(NoWarn);CA2249 $(NoWarn);IDE0059;IDE0060;CA1822;CA1859 - false false true true diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_LoadStore.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_LoadStore.cs index 605ace5c6eca9d..01b5204549dc6c 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_LoadStore.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_LoadStore.cs @@ -602,15 +602,15 @@ private Principal FindPrincipalByIdentRefHelper( // This is the tricky case. They didn't specify a UrnScheme, so we need to // try all of them. - string[] urnSchemesToTry = new string[] - { + ReadOnlySpan urnSchemesToTry = + [ UrnScheme.SamAccountScheme, UrnScheme.UpnScheme, UrnScheme.DistinguishedNameScheme, UrnScheme.SidScheme, UrnScheme.GuidScheme, UrnScheme.NameScheme - }; + ]; StringBuilder innerLdapFilter = new StringBuilder(); diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/exceptions.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/exceptions.cs index 93fe9c7dd24b5a..920b3495dacce0 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/exceptions.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/exceptions.cs @@ -23,7 +23,7 @@ internal PrincipalException(string message, Exception innerException) : base(message, innerException) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -45,7 +45,7 @@ public MultipleMatchesException(string message, Exception innerException) : base(message, innerException) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -67,7 +67,7 @@ public NoMatchingPrincipalException(string message, Exception innerException) : base(message, innerException) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -89,7 +89,7 @@ public PasswordException(string message, Exception innerException) : base(message, innerException) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -111,7 +111,7 @@ public PrincipalExistsException(string message, Exception innerException) : base(message, innerException) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -150,7 +150,7 @@ public PrincipalServerDownException(string message, Exception innerException, in _serverName = serverName; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -161,7 +161,7 @@ protected PrincipalServerDownException(SerializationInfo info, StreamingContext _serverName = (string)info.GetValue("serverName", typeof(string)); } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -196,7 +196,7 @@ public PrincipalOperationException(string message, Exception innerException, int _errorCode = errorCode; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -206,7 +206,7 @@ protected PrincipalOperationException(SerializationInfo info, StreamingContext c _errorCode = info.GetInt32("errorCode"); } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.DirectoryServices.AccountManagement/tests/PrincipalContextTests.cs b/src/libraries/System.DirectoryServices.AccountManagement/tests/PrincipalContextTests.cs index 29fe1ba217dfc6..b81a7847b54ce0 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/tests/PrincipalContextTests.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/tests/PrincipalContextTests.cs @@ -30,7 +30,7 @@ public void Ctor_ContextType() [InlineData(ContextType.Machine, "")] [InlineData(ContextType.Machine, "\0")] [InlineData(ContextType.Machine, "name")] - public void Ctor_ContextType_Name(ContextType contextType, string name) + public void Ctor_ContextType_Name(ContextType contextType, string? name) { var context = new PrincipalContext(contextType, name); Assert.Equal(contextType, context.ContextType); @@ -57,7 +57,7 @@ public void Ctor_ContextType_Name(ContextType contextType, string name) [InlineData(ContextType.Machine, "", null)] [InlineData(ContextType.Machine, "\0", null)] [InlineData(ContextType.Machine, "name", null)] - public void Ctor_ContextType_Name_Container(ContextType contextType, string name, string container) + public void Ctor_ContextType_Name_Container(ContextType contextType, string? name, string? container) { var context = new PrincipalContext(contextType, name, container); Assert.Equal(contextType, context.ContextType); @@ -84,7 +84,7 @@ public void Ctor_ContextType_Name_Container(ContextType contextType, string name [InlineData(ContextType.Machine, "", null, ContextOptions.Negotiate)] [InlineData(ContextType.Machine, "\0", null, ContextOptions.Negotiate)] [InlineData(ContextType.Machine, "name", null, ContextOptions.Negotiate)] - public void Ctor_ContextType_Name_Container_Options(ContextType contextType, string name, string container, ContextOptions options) + public void Ctor_ContextType_Name_Container_Options(ContextType contextType, string? name, string? container, ContextOptions options) { var context = new PrincipalContext(contextType, name, container, options); Assert.Equal(contextType, context.ContextType); @@ -111,7 +111,7 @@ public void Ctor_ContextType_Name_Container_Options(ContextType contextType, str [InlineData(ContextType.Machine, "", "", "")] [InlineData(ContextType.Machine, "\0", "userName", "")] [InlineData(ContextType.Machine, "name", "\0", "\0")] - public void Ctor_ContextType_Name_UserName_Password(ContextType contextType, string name, string userName, string password) + public void Ctor_ContextType_Name_UserName_Password(ContextType contextType, string? name, string userName, string password) { var context = new PrincipalContext(contextType, name, userName, password); Assert.Equal(contextType, context.ContextType); @@ -137,7 +137,7 @@ public void Ctor_ContextType_Name_UserName_Password(ContextType contextType, str [InlineData(ContextType.Machine, "", null, "", "")] [InlineData(ContextType.Machine, "\0", null, "userName", "")] [InlineData(ContextType.Machine, "name", null, "\0", "\0")] - public void Ctor_ContextType_Name_Container_UserName_Password(ContextType contextType, string name, string container, string userName, string password) + public void Ctor_ContextType_Name_Container_UserName_Password(ContextType contextType, string? name, string? container, string userName, string password) { var context = new PrincipalContext(contextType, name, container, userName, password); Assert.Equal(contextType, context.ContextType); @@ -230,7 +230,7 @@ public void Ctor_MachineContextTypeWithContainer_ThrowsArgumentException() [Theory] [InlineData(null, "password")] [InlineData("userName", null)] - public void Ctor_InconsistentUserNameAndPassword_ThrowsArgumentException(string userName, string password) + public void Ctor_InconsistentUserNameAndPassword_ThrowsArgumentException(string? userName, string? password) { AssertExtensions.Throws(null, () => new PrincipalContext(ContextType.Machine, "name", userName, password)); AssertExtensions.Throws(null, () => new PrincipalContext(ContextType.Machine, "name", null, userName, password)); @@ -295,7 +295,7 @@ public void UserName_GetWhenDisposed_ThrowsObjectDisposedException() [ActiveIssue("https://github.com/dotnet/runtime/issues/34442", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] [InlineData(null, null, true)] [InlineData("", "", false)] - public void ValidateCredentials_Invoke_ReturnsExpected(string userName, string password, bool expected) + public void ValidateCredentials_Invoke_ReturnsExpected(string? userName, string? password, bool expected) { var context = new PrincipalContext(ContextType.Machine); Assert.Equal(expected, context.ValidateCredentials(userName, password)); @@ -323,7 +323,7 @@ public void ValidateCredentials_IncorrectUserNamePassword_ThrowsException() [Theory] [InlineData(null, "password")] [InlineData("userName", null)] - public void ValidateCredentials_InvalidUsernamePasswordCombo_ThrowsArgumentException(string userName, string password) + public void ValidateCredentials_InvalidUsernamePasswordCombo_ThrowsArgumentException(string? userName, string? password) { var context = new PrincipalContext(ContextType.Machine); AssertExtensions.Throws(null, () => context.ValidateCredentials(userName, password)); diff --git a/src/libraries/System.DirectoryServices.Protocols/Directory.Build.props b/src/libraries/System.DirectoryServices.Protocols/Directory.Build.props index 831e8089e2459c..ec9059203e7dd9 100644 --- a/src/libraries/System.DirectoryServices.Protocols/Directory.Build.props +++ b/src/libraries/System.DirectoryServices.Protocols/Directory.Build.props @@ -4,5 +4,6 @@ Microsoft true browser;android;ios;tvos + false diff --git a/src/libraries/System.DirectoryServices.Protocols/System.DirectoryServices.Protocols.slnx b/src/libraries/System.DirectoryServices.Protocols/System.DirectoryServices.Protocols.slnx index 017d9b6ed74905..26e5f883fdf6a9 100644 --- a/src/libraries/System.DirectoryServices.Protocols/System.DirectoryServices.Protocols.slnx +++ b/src/libraries/System.DirectoryServices.Protocols/System.DirectoryServices.Protocols.slnx @@ -101,7 +101,7 @@ - + @@ -109,7 +109,7 @@ - + @@ -117,7 +117,7 @@ - + @@ -125,7 +125,7 @@ - + @@ -133,7 +133,7 @@ - + @@ -141,7 +141,7 @@ - + @@ -149,7 +149,9 @@ - + + + diff --git a/src/libraries/System.DirectoryServices.Protocols/ref/System.DirectoryServices.Protocols.cs b/src/libraries/System.DirectoryServices.Protocols/ref/System.DirectoryServices.Protocols.cs index 0c08b61ae5681f..1ccbb5c2c4916f 100644 --- a/src/libraries/System.DirectoryServices.Protocols/ref/System.DirectoryServices.Protocols.cs +++ b/src/libraries/System.DirectoryServices.Protocols/ref/System.DirectoryServices.Protocols.cs @@ -46,7 +46,7 @@ public enum AuthType public partial class BerConversionException : System.DirectoryServices.Protocols.DirectoryException { public BerConversionException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -194,7 +194,7 @@ public void Remove(System.DirectoryServices.Protocols.DirectoryControl value) { public partial class DirectoryException : System.Exception { public DirectoryException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -220,7 +220,7 @@ public DirectoryOperationException() { } public DirectoryOperationException(System.DirectoryServices.Protocols.DirectoryResponse response) { } public DirectoryOperationException(System.DirectoryServices.Protocols.DirectoryResponse response, string message) { } public DirectoryOperationException(System.DirectoryServices.Protocols.DirectoryResponse response, string message, System.Exception inner) { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -228,7 +228,7 @@ protected DirectoryOperationException(System.Runtime.Serialization.Serialization public DirectoryOperationException(string message) { } public DirectoryOperationException(string message, System.Exception inner) { } public System.DirectoryServices.Protocols.DirectoryResponse Response { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -361,7 +361,7 @@ public LdapException(int errorCode) { } public LdapException(int errorCode, string message) { } public LdapException(int errorCode, string message, System.Exception inner) { } public LdapException(int errorCode, string message, string serverErrorMessage) { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -371,7 +371,7 @@ public LdapException(string message, System.Exception inner) { } public int ErrorCode { get { throw null; } } public System.DirectoryServices.Protocols.PartialResultsCollection PartialResults { get { throw null; } } public string ServerErrorMessage { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -735,7 +735,7 @@ public TlsOperationException() { } public TlsOperationException(System.DirectoryServices.Protocols.DirectoryResponse response) { } public TlsOperationException(System.DirectoryServices.Protocols.DirectoryResponse response, string message) { } public TlsOperationException(System.DirectoryServices.Protocols.DirectoryResponse response, string message, System.Exception inner) { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj index a14b7fa4d14b8d..682599efc835d3 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj +++ b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj @@ -12,7 +12,6 @@ Provides the methods defined in the Lightweight Directory Access Protocol (LDAP) version 3 (V3) and Directory Services Markup Language (DSML) version 2.0 (V2) standards. $(NoWarn);CS3016 - false disable diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/DirectoryException.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/DirectoryException.cs index 48235f0cbc1ef5..dc325aa4c2238f 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/DirectoryException.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/DirectoryException.cs @@ -11,7 +11,7 @@ namespace System.DirectoryServices.Protocols [System.Runtime.CompilerServices.TypeForwardedFrom("System.DirectoryServices.Protocols, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public class DirectoryException : Exception { -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -36,7 +36,7 @@ public DirectoryException() : base() [System.Runtime.CompilerServices.TypeForwardedFrom("System.DirectoryServices.Protocols, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public class DirectoryOperationException : DirectoryException, ISerializable { -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -83,7 +83,7 @@ private static string CreateMessage(DirectoryResponse response, string? message) [System.Runtime.CompilerServices.TypeForwardedFrom("System.DirectoryServices.Protocols, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public class BerConversionException : DirectoryException { -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapAsyncResult.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapAsyncResult.cs index 3b83e360ee28a9..01c1eedce5df1a 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapAsyncResult.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapAsyncResult.cs @@ -8,7 +8,6 @@ namespace System.DirectoryServices.Protocols { internal class LdapAsyncResult : IAsyncResult { - private LdapAsyncWaitHandle _asyncWaitHandle; internal AsyncCallback _callback; internal bool _completed; internal ManualResetEvent _manualResetEvent; @@ -26,10 +25,7 @@ public LdapAsyncResult(AsyncCallback callbackRoutine, object state, bool partial object IAsyncResult.AsyncState => _stateObject; - WaitHandle IAsyncResult.AsyncWaitHandle - { - get => _asyncWaitHandle ??= new LdapAsyncWaitHandle(_manualResetEvent.SafeWaitHandle); - } + WaitHandle IAsyncResult.AsyncWaitHandle => field ??= new LdapAsyncWaitHandle(_manualResetEvent.SafeWaitHandle); bool IAsyncResult.CompletedSynchronously => false; diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapException.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapException.cs index 6c972a875df33d..b98ac407223b4a 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapException.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapException.cs @@ -93,7 +93,7 @@ public class LdapException : DirectoryException, ISerializable { private int _errorCode; -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -145,7 +145,7 @@ private set [System.Runtime.CompilerServices.TypeForwardedFrom("System.DirectoryServices.Protocols, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public class TlsOperationException : DirectoryOperationException { -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/AddRequestTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/AddRequestTests.cs index 80d27d83e1c158..5ce9444a1b67db 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/AddRequestTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/AddRequestTests.cs @@ -28,7 +28,7 @@ public static IEnumerable Ctor_DistinguishedName_Attributes_TestData() [Theory] [MemberData(nameof(Ctor_DistinguishedName_Attributes_TestData))] - public void Ctor_DistinguishedString_Attributes(string distinguishedName, DirectoryAttribute[] attributes) + public void Ctor_DistinguishedString_Attributes(string? distinguishedName, DirectoryAttribute[] attributes) { var request = new AddRequest(distinguishedName, attributes); Assert.Equal(attributes ?? Enumerable.Empty(), request.Attributes.Cast()); @@ -46,7 +46,7 @@ public void Ctor_NullObjectInAttributes_ThrowsArgumentException() [Theory] [InlineData(null, "")] [InlineData("DistinguishedName", "ObjectClass")] - public void Ctor_DistinguishedName_ObjectClass(string distinguishedName, string objectClass) + public void Ctor_DistinguishedName_ObjectClass(string? distinguishedName, string objectClass) { var request = new AddRequest(distinguishedName, objectClass); DirectoryAttribute attribute = (DirectoryAttribute)Assert.Single(request.Attributes); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/CompareRequestTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/CompareRequestTests.cs index 8180eaf230a9a5..fa6878ed760a60 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/CompareRequestTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/CompareRequestTests.cs @@ -21,7 +21,7 @@ public void Ctor_Default() [Theory] [InlineData(null, "", "")] [InlineData("DistinguishedName", "AttributeName", "value")] - public void Ctor_DistinguishedName_AttributeName_StringValue(string distinguishedName, string attributeName, string value) + public void Ctor_DistinguishedName_AttributeName_StringValue(string? distinguishedName, string attributeName, string value) { var request = new CompareRequest(distinguishedName, attributeName, value); Assert.Equal(attributeName, request.Assertion.Name); @@ -35,7 +35,7 @@ public void Ctor_DistinguishedName_AttributeName_StringValue(string distinguishe [Theory] [InlineData(null, "", new byte[0])] [InlineData("DistinguishedName", "AttributeName", new byte[] { 1, 2, 3 })] - public void Ctor_DistinguishedName_AttributeName_ByteArrayValue(string distinguishedName, string attributeName, byte[] value) + public void Ctor_DistinguishedName_AttributeName_ByteArrayValue(string? distinguishedName, string attributeName, byte[] value) { var request = new CompareRequest(distinguishedName, attributeName, value); Assert.Equal(attributeName, request.Assertion.Name); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/CrossDomainMoveControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/CrossDomainMoveControlTests.cs index 3841782d96b1d2..063d7f92a156b3 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/CrossDomainMoveControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/CrossDomainMoveControlTests.cs @@ -23,7 +23,7 @@ public void Ctor_Default() [InlineData(null, new byte[0])] [InlineData("", new byte[] { 0, 0 })] [InlineData("A", new byte[] { 65, 0, 0 })] - public void Ctor_String(string targetDomainController, byte[] expectedValue) + public void Ctor_String(string? targetDomainController, byte[] expectedValue) { var control = new CrossDomainMoveControl(targetDomainController); Assert.True(control.IsCritical); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/DeleteRequestTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/DeleteRequestTests.cs index 98ccfc10e535fb..2e70bdcc135789 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/DeleteRequestTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/DeleteRequestTests.cs @@ -19,7 +19,7 @@ public void Ctor_Default() [Theory] [InlineData(null)] [InlineData("DistinguishedName")] - public void Ctor_DistinguishedName(string distinguishedName) + public void Ctor_DistinguishedName(string? distinguishedName) { var request = new DeleteRequest(distinguishedName); Assert.Empty(request.Controls); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryAttributeTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryAttributeTests.cs index c1d117cbdfecb0..55e9cb2da00c19 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryAttributeTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryAttributeTests.cs @@ -139,7 +139,7 @@ public void GetValues_ContainsUri_ThrowsNotSupportedException() [InlineData(null)] [InlineData(typeof(Uri))] [InlineData(typeof(int))] - public void GetValues_InvalidType_ThrowsArgumentException(Type valuesType) + public void GetValues_InvalidType_ThrowsArgumentException(Type? valuesType) { var attribute = new DirectoryAttribute(); AssertExtensions.Throws("valuesType", () => attribute.GetValues(valuesType)); @@ -331,7 +331,7 @@ public void Remove_NullValue_ThrowsArgumentNullException() [Theory] [InlineData("vaLue", null)] [InlineData(1, "value")] - public void Remove_InvalidValue_ThrowsArgumentException(object value, string paramName) + public void Remove_InvalidValue_ThrowsArgumentException(object value, string? paramName) { var attribute = new DirectoryAttribute { "value" }; AssertExtensions.Throws(paramName, () => attribute.Remove(value)); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryControlTests.cs index 32d2b36f062493..51eb7424e5b589 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryControlTests.cs @@ -10,7 +10,7 @@ public class DirectoryControlTests [Theory] [InlineData("", null, false, false)] [InlineData("Type", new byte[] { 1, 2, 3 }, true, true)] - public void Ctor_Type_Value_IsCritical_ServerSide(string type, byte[] value, bool isCritical, bool serverSide) + public void Ctor_Type_Value_IsCritical_ServerSide(string type, byte[]? value, bool isCritical, bool serverSide) { var control = new DirectoryControl(type, value, isCritical, serverSide); Assert.Equal(type, control.Type); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/DsmlAuthRequestTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/DsmlAuthRequestTests.cs index 408e4e57e45f36..5e9c432e9d0778 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/DsmlAuthRequestTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/DsmlAuthRequestTests.cs @@ -19,7 +19,7 @@ public void Ctor_Default() [Theory] [InlineData(null)] [InlineData("Principal")] - public void Ctor_Principal(string principal) + public void Ctor_Principal(string? principal) { var request = new DsmlAuthRequest(principal); Assert.Empty(request.Controls); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/ExtendedRequestTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/ExtendedRequestTests.cs index 74fccf9dd6d02a..e7cfc064a3fdb8 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/ExtendedRequestTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/ExtendedRequestTests.cs @@ -20,7 +20,7 @@ public void Ctor_Default() [Theory] [InlineData(null)] [InlineData("RequestName")] - public void Ctor_RequestName(string requestName) + public void Ctor_RequestName(string? requestName) { var request = new ExtendedRequest(requestName); Assert.Empty(request.Controls); @@ -32,7 +32,7 @@ public void Ctor_RequestName(string requestName) [Theory] [InlineData(null, null)] [InlineData("RequestName", new byte[] { 1, 2, 3 })] - public void Ctor_RequestName_RequestValue(string requestName, byte[] requestValue) + public void Ctor_RequestName_RequestValue(string? requestName, byte[]? requestValue) { var request = new ExtendedRequest(requestName, requestValue); Assert.Empty(request.Controls); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/LdapConnectionTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/LdapConnectionTests.cs index 413c61724b7ec7..bab7e8291f183f 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/LdapConnectionTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/LdapConnectionTests.cs @@ -15,7 +15,7 @@ public class LdapConnectionTests [Theory] [InlineData(null, new string[0])] [InlineData("server", new string[] { "server" })] - public void Ctor_String(string server, string[] expectedServer) + public void Ctor_String(string? server, string[] expectedServer) { var connection = new LdapConnection(server); Assert.Equal(AuthType.Negotiate, connection.AuthType); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/LdapDirectoryIdentifierTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/LdapDirectoryIdentifierTests.cs index 7699a932f74b14..c17d028421f916 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/LdapDirectoryIdentifierTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/LdapDirectoryIdentifierTests.cs @@ -11,7 +11,7 @@ public class LdapDirectoryIdentifierTests [InlineData(null, new string[0])] [InlineData("", new string[] { "" })] [InlineData("server", new string[] { "server" })] - public void Ctor_Server(string server, string[] expectedServers) + public void Ctor_Server(string? server, string[] expectedServers) { var identifier = new LdapDirectoryIdentifier(server); Assert.False(identifier.Connectionless); @@ -24,7 +24,7 @@ public void Ctor_Server(string server, string[] expectedServers) [InlineData(null, 389, new string[0])] [InlineData("", -1, new string[] { "" })] [InlineData("server", int.MaxValue, new string[] { "server" })] - public void Ctor_Server_PortNumber(string server, int portNumber, string[] expectedServers) + public void Ctor_Server_PortNumber(string? server, int portNumber, string[] expectedServers) { var identifier = new LdapDirectoryIdentifier(server, portNumber); Assert.False(identifier.Connectionless); @@ -37,7 +37,7 @@ public void Ctor_Server_PortNumber(string server, int portNumber, string[] expec [InlineData(null, true, false, new string[0])] [InlineData("", false, true, new string[] { "" })] [InlineData("server", true, true, new string[] { "server" })] - public void Ctor_Server_FullQualifiedDnsHostName_Conectionless(string server, bool fullyQualifiedDnsHostName, bool connectionless, string[] expectedServers) + public void Ctor_Server_FullQualifiedDnsHostName_Conectionless(string? server, bool fullyQualifiedDnsHostName, bool connectionless, string[] expectedServers) { var identifier = new LdapDirectoryIdentifier(server, fullyQualifiedDnsHostName, connectionless); Assert.Equal(connectionless, identifier.Connectionless); @@ -50,7 +50,7 @@ public void Ctor_Server_FullQualifiedDnsHostName_Conectionless(string server, bo [InlineData(null, -1, true, false, new string[0])] [InlineData("", 389, false, true, new string[] { "" })] [InlineData("server", int.MaxValue, true, true, new string[] { "server" })] - public void Ctor_PortNumber_Server_FullQualifiedDnsHostName_Conectionless(string server, int portNumber, bool fullyQualifiedDnsHostName, bool connectionless, string[] expectedServers) + public void Ctor_PortNumber_Server_FullQualifiedDnsHostName_Conectionless(string? server, int portNumber, bool fullyQualifiedDnsHostName, bool connectionless, string[] expectedServers) { var identifier = new LdapDirectoryIdentifier(server, portNumber, fullyQualifiedDnsHostName, connectionless); Assert.Equal(connectionless, identifier.Connectionless); @@ -64,7 +64,7 @@ public void Ctor_PortNumber_Server_FullQualifiedDnsHostName_Conectionless(string [InlineData(new string[0], true, false)] [InlineData(new string[] { "server" }, true, true)] [InlineData(new string[] { "server", null }, false, false)] - public void Ctor_Servers_FullQualifiedDnsHostName_Conectionless(string[] servers, bool fullyQualifiedDnsHostName, bool connectionless) + public void Ctor_Servers_FullQualifiedDnsHostName_Conectionless(string[]? servers, bool fullyQualifiedDnsHostName, bool connectionless) { var identifier = new LdapDirectoryIdentifier(servers, fullyQualifiedDnsHostName, connectionless); Assert.Equal(connectionless, identifier.Connectionless); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/ModifyDNRequestTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/ModifyDNRequestTests.cs index 8ef842f3c4a6ed..535a95326623c0 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/ModifyDNRequestTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/ModifyDNRequestTests.cs @@ -24,7 +24,7 @@ public void Ctor_Default() [Theory] [InlineData(null, null, null)] [InlineData("DistinguishedName", "NewParentDistinguishedName", "NewName")] - public void Ctor_DistinguishedName_NewParentDistinguishedName_NewName(string distinguishedName, string newParentDistinguishedName, string newName) + public void Ctor_DistinguishedName_NewParentDistinguishedName_NewName(string? distinguishedName, string? newParentDistinguishedName, string? newName) { var request = new ModifyDNRequest(distinguishedName, newParentDistinguishedName, newName); Assert.Empty(request.Controls); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/SearchRequestTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/SearchRequestTests.cs index eed8af0891ad29..5c948b34824679 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/SearchRequestTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/SearchRequestTests.cs @@ -31,7 +31,7 @@ public void Ctor_Default() [InlineData("", "", SearchScope.OneLevel, new string[0])] [InlineData("DistinguishedName", "LdapFilter", SearchScope.Base, new string[] { "attribute" })] [InlineData("DistinguishedName", "LdapFilter", SearchScope.OneLevel, new string[] { null })] - public void Ctor_DistinguishedName_LdapFilter_SearchScope_AttributeList(string distinguishedName, string ldapFilter, SearchScope searchScope, string[] attributeList) + public void Ctor_DistinguishedName_LdapFilter_SearchScope_AttributeList(string? distinguishedName, string? ldapFilter, SearchScope searchScope, string[]? attributeList) { var request = new SearchRequest(distinguishedName, ldapFilter, searchScope, attributeList); Assert.Equal(DereferenceAlias.Never, request.Aliases); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/SortKeyTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/SortKeyTests.cs index 69ccc4c53261b5..5146c4d979f7b9 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/SortKeyTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/SortKeyTests.cs @@ -19,7 +19,7 @@ public void Ctor_Default() [Theory] [InlineData("", null, false)] [InlineData("AttributeName", null, false)] - public void Ctor_AttributeName_MatchingRule_ReverseOrder(string attributeName, string matchingRule, bool reverseOrder) + public void Ctor_AttributeName_MatchingRule_ReverseOrder(string attributeName, string? matchingRule, bool reverseOrder) { var sortKey = new SortKey(attributeName, matchingRule, reverseOrder); Assert.Equal(attributeName, sortKey.AttributeName); diff --git a/src/libraries/System.DirectoryServices/Directory.Build.props b/src/libraries/System.DirectoryServices/Directory.Build.props index 709a22a7537088..0bcccb8bb216a0 100644 --- a/src/libraries/System.DirectoryServices/Directory.Build.props +++ b/src/libraries/System.DirectoryServices/Directory.Build.props @@ -3,5 +3,6 @@ Microsoft windows + false \ No newline at end of file diff --git a/src/libraries/System.DirectoryServices/System.DirectoryServices.slnx b/src/libraries/System.DirectoryServices/System.DirectoryServices.slnx index dcacc9e894fd24..03d5a5e1c2aa1c 100644 --- a/src/libraries/System.DirectoryServices/System.DirectoryServices.slnx +++ b/src/libraries/System.DirectoryServices/System.DirectoryServices.slnx @@ -93,7 +93,7 @@ - + @@ -101,7 +101,7 @@ - + @@ -109,7 +109,7 @@ - + @@ -117,7 +117,7 @@ - + @@ -125,7 +125,7 @@ - + @@ -133,7 +133,9 @@ - + + + diff --git a/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.cs b/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.cs index 718084c2a9d79d..c4631c89137c77 100644 --- a/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.cs +++ b/src/libraries/System.DirectoryServices/ref/System.DirectoryServices.cs @@ -255,7 +255,7 @@ protected override void Dispose(bool disposing) { } public partial class DirectoryServicesCOMException : System.Runtime.InteropServices.COMException, System.Runtime.Serialization.ISerializable { public DirectoryServicesCOMException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -264,7 +264,7 @@ public DirectoryServicesCOMException(string? message) { } public DirectoryServicesCOMException(string? message, System.Exception? inner) { } public int ExtendedError { get { throw null; } } public string? ExtendedErrorMessage { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -539,7 +539,7 @@ public void Save() { } public partial class ActiveDirectoryObjectExistsException : System.Exception { public ActiveDirectoryObjectExistsException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -550,7 +550,7 @@ public ActiveDirectoryObjectExistsException(string? message, System.Exception? i public partial class ActiveDirectoryObjectNotFoundException : System.Exception, System.Runtime.Serialization.ISerializable { public ActiveDirectoryObjectNotFoundException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -560,7 +560,7 @@ public ActiveDirectoryObjectNotFoundException(string? message, System.Exception? public ActiveDirectoryObjectNotFoundException(string? message, System.Type? type, string? name) { } public string? Name { get { throw null; } } public System.Type? Type { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -569,7 +569,7 @@ public override void GetObjectData(System.Runtime.Serialization.SerializationInf public partial class ActiveDirectoryOperationException : System.Exception, System.Runtime.Serialization.ISerializable { public ActiveDirectoryOperationException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -579,7 +579,7 @@ public ActiveDirectoryOperationException(string? message, System.Exception? inne public ActiveDirectoryOperationException(string? message, System.Exception? inner, int errorCode) { } public ActiveDirectoryOperationException(string? message, int errorCode) { } public int ErrorCode { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -743,7 +743,7 @@ public void Remove(System.DirectoryServices.ActiveDirectory.ActiveDirectorySchem public partial class ActiveDirectoryServerDownException : System.Exception, System.Runtime.Serialization.ISerializable { public ActiveDirectoryServerDownException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -755,7 +755,7 @@ public ActiveDirectoryServerDownException(string? message, int errorCode, string public int ErrorCode { get { throw null; } } public override string Message { get { throw null; } } public string? Name { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -1311,7 +1311,7 @@ public enum ForestMode public partial class ForestTrustCollisionException : System.DirectoryServices.ActiveDirectory.ActiveDirectoryOperationException, System.Runtime.Serialization.ISerializable { public ForestTrustCollisionException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -1320,7 +1320,7 @@ public ForestTrustCollisionException(string? message) { } public ForestTrustCollisionException(string? message, System.Exception? inner) { } public ForestTrustCollisionException(string? message, System.Exception? inner, System.DirectoryServices.ActiveDirectory.ForestTrustRelationshipCollisionCollection? collisions) { } public System.DirectoryServices.ActiveDirectory.ForestTrustRelationshipCollisionCollection? Collisions { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -1703,7 +1703,7 @@ public enum SyncFromAllServersEvent public partial class SyncFromAllServersOperationException : System.DirectoryServices.ActiveDirectory.ActiveDirectoryOperationException, System.Runtime.Serialization.ISerializable { public SyncFromAllServersOperationException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -1712,7 +1712,7 @@ public SyncFromAllServersOperationException(string? message) { } public SyncFromAllServersOperationException(string? message, System.Exception? inner) { } public SyncFromAllServersOperationException(string? message, System.Exception? inner, System.DirectoryServices.ActiveDirectory.SyncFromAllServersErrorInformation[]? errors) { } public System.DirectoryServices.ActiveDirectory.SyncFromAllServersErrorInformation[] ErrorInformation { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj b/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj index 845f7627ca3ee3..20f66fb30edb6f 100644 --- a/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj +++ b/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj @@ -6,7 +6,6 @@ true true $(NoWarn);IDE0059;IDE0060;CA1822;CA1865 - false false true true diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/Exception.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/Exception.cs index 85ea36b623f06a..4a2c0b69a9ab57 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/Exception.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/Exception.cs @@ -47,7 +47,7 @@ public ActiveDirectoryObjectNotFoundException(string? message) : base(message) { public ActiveDirectoryObjectNotFoundException() : base() { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -59,7 +59,7 @@ protected ActiveDirectoryObjectNotFoundException(SerializationInfo info, Streami public string? Name { get; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -103,7 +103,7 @@ public ActiveDirectoryOperationException(string? message) : base(message ?? SR.D public ActiveDirectoryOperationException() : base(SR.DSUnknownFailure) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -113,7 +113,7 @@ protected ActiveDirectoryOperationException(SerializationInfo info, StreamingCon public int ErrorCode { get; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -145,7 +145,7 @@ public ActiveDirectoryServerDownException(string? message) : base(message) { } public ActiveDirectoryServerDownException() : base() { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -170,7 +170,7 @@ public override string Message } } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -190,7 +190,7 @@ public ActiveDirectoryObjectExistsException(string? message) : base(message) { } public ActiveDirectoryObjectExistsException() : base() { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -216,7 +216,7 @@ public SyncFromAllServersOperationException(string? message) : base(message ?? S public SyncFromAllServersOperationException() : base(SR.DSSyncAllFailure) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -239,7 +239,7 @@ public SyncFromAllServersErrorInformation[] ErrorInformation } } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -264,7 +264,7 @@ public ForestTrustCollisionException(string? message) : base(message ?? SR.Fores public ForestTrustCollisionException() : base(SR.ForestTrustCollision) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -274,7 +274,7 @@ protected ForestTrustCollisionException(SerializationInfo info, StreamingContext public ForestTrustRelationshipCollisionCollection? Collisions { get; } = new ForestTrustRelationshipCollisionCollection(); -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/TrustHelper.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/TrustHelper.cs index 6591d54f956ea2..9d4d86d6438dd7 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/TrustHelper.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/TrustHelper.cs @@ -910,7 +910,7 @@ private static void ValidateTrustAttribute(Interop.Advapi32.TRUSTED_DOMAIN_INFOR internal static string CreateTrustPassword() { -#if NET8_0_OR_GREATER +#if NET return RandomNumberGenerator.GetString(PasswordCharacterSet, PASSWORD_LENGTH); #else char[] cBuf = new char[PASSWORD_LENGTH]; diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryServicesCOMException.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryServicesCOMException.cs index 4afcf03e7a834e..311200a1b6d535 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryServicesCOMException.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryServicesCOMException.cs @@ -17,7 +17,7 @@ public DirectoryServicesCOMException(string? message) : base(message) { } public DirectoryServicesCOMException(string? message, Exception? inner) : base(message, inner) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -35,7 +35,7 @@ internal DirectoryServicesCOMException(string? extendedMessage, int extendedErro public string? ExtendedErrorMessage { get; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/ActiveDirectory/DirectoryContextTests.cs b/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/ActiveDirectory/DirectoryContextTests.cs index b665e02976922c..c8288e2c974570 100644 --- a/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/ActiveDirectory/DirectoryContextTests.cs +++ b/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/ActiveDirectory/DirectoryContextTests.cs @@ -23,7 +23,7 @@ public void Ctor_ContextType(DirectoryContextType contextType) [Theory] [InlineData(DirectoryContextType.Domain, null, null)] [InlineData(DirectoryContextType.Forest, "UserName", "Password")] - public void Ctor_ContextType_UserName_Password(DirectoryContextType contextType, string userName, string password) + public void Ctor_ContextType_UserName_Password(DirectoryContextType contextType, string? userName, string? password) { var context = new DirectoryContext(contextType, userName, password); Assert.Equal(contextType, context.ContextType); @@ -61,7 +61,7 @@ public void Ctor_ContextType_Name(DirectoryContextType contextType, string name) [InlineData(DirectoryContextType.DirectoryServer, "Name", "UserName", "Password")] [InlineData(DirectoryContextType.Domain, "Name", "UserName", "Password")] [InlineData(DirectoryContextType.Forest, "Name", "UserName", "Password")] - public void Ctor_ContextType_Name_UserName_Password(DirectoryContextType contextType, string name, string userName, string password) + public void Ctor_ContextType_Name_UserName_Password(DirectoryContextType contextType, string name, string? userName, string? password) { var context = new DirectoryContext(contextType, name, userName, password); Assert.Equal(contextType, context.ContextType); diff --git a/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/DirectoryEntryTests.cs b/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/DirectoryEntryTests.cs index baae5ef11681c5..0c0f0b36c1362c 100644 --- a/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/DirectoryEntryTests.cs +++ b/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/DirectoryEntryTests.cs @@ -25,7 +25,7 @@ public void Ctor_Default() [InlineData(null)] [InlineData("")] [InlineData("Path")] - public void Ctor_Path(string path) + public void Ctor_Path(string? path) { var entry = new DirectoryEntry(path); Assert.Equal(path ?? string.Empty, entry.Path); @@ -41,7 +41,7 @@ public void Ctor_Path(string path) [InlineData(null, null, null)] [InlineData("", "", "")] [InlineData("Path", "UserName", "Password")] - public void Ctor_Path_UserName_Password(string path, string userName, string password) + public void Ctor_Path_UserName_Password(string? path, string? userName, string? password) { var entry = new DirectoryEntry(path, userName, password); Assert.Equal(path ?? string.Empty, entry.Path); @@ -57,7 +57,7 @@ public void Ctor_Path_UserName_Password(string path, string userName, string pas [InlineData(null, null, null, (AuthenticationTypes)int.MinValue)] [InlineData("", "", "", AuthenticationTypes.Anonymous)] [InlineData("Path", "UserName", "Password", AuthenticationTypes.None)] - public void Ctor_Path_UserName_Password_AuthenticationType(string path, string userName, string password, AuthenticationTypes authenticationType) + public void Ctor_Path_UserName_Password_AuthenticationType(string? path, string? userName, string? password, AuthenticationTypes authenticationType) { var entry = new DirectoryEntry(path, userName, password, authenticationType); Assert.Equal(path ?? string.Empty, entry.Path); @@ -72,7 +72,7 @@ public void Ctor_Path_UserName_Password_AuthenticationType(string path, string u [Theory] [InlineData(null)] [InlineData(1)] - public void Ctor_InvalidAdsObject_ThrowsArgumentException(object adsObject) + public void Ctor_InvalidAdsObject_ThrowsArgumentException(object? adsObject) { AssertExtensions.Throws(null, () => new DirectoryEntry(adsObject)); } diff --git a/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/DirectorySynchronizationTests.cs b/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/DirectorySynchronizationTests.cs index deec45477d05f0..80578d4037a77d 100644 --- a/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/DirectorySynchronizationTests.cs +++ b/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/DirectorySynchronizationTests.cs @@ -33,7 +33,7 @@ public void Ctor_Option(DirectorySynchronizationOptions option) [InlineData(null)] [InlineData(new byte[0])] [InlineData(new byte[] { 1, 2, 3, })] - public void Ctor_Cookie(byte[] cookie) + public void Ctor_Cookie(byte[]? cookie) { var synchronization = new DirectorySynchronization(cookie); Assert.Equal(DirectorySynchronizationOptions.None, synchronization.Option); @@ -47,7 +47,7 @@ public void Ctor_Cookie(byte[] cookie) [InlineData(DirectorySynchronizationOptions.None, null)] [InlineData(DirectorySynchronizationOptions.IncrementalValues, new byte[0])] [InlineData(DirectorySynchronizationOptions.IncrementalValues | DirectorySynchronizationOptions.ObjectSecurity, new byte[] { 1, 2, 3 })] - public void Ctor_Option_Cookie(DirectorySynchronizationOptions option, byte[] cookie) + public void Ctor_Option_Cookie(DirectorySynchronizationOptions option, byte[]? cookie) { var synchronization = new DirectorySynchronization(option, cookie); Assert.Equal(option, synchronization.Option); @@ -106,7 +106,7 @@ public void ResetDirectorySynchronizationCookie_Parameterless_SetsToEmpty() [InlineData(null)] [InlineData(new byte[0])] [InlineData(new byte[] { 1, 2, 3 })] - public void ResetDirectorySynchronizationCookie_Cookie_SetsToEmpty(byte[] cookie) + public void ResetDirectorySynchronizationCookie_Cookie_SetsToEmpty(byte[]? cookie) { var synchronization = new DirectorySynchronization(new byte[] { 255, 255, 255 }); synchronization.ResetDirectorySynchronizationCookie(cookie); diff --git a/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/DirectoryVirtualListViewTests.cs b/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/DirectoryVirtualListViewTests.cs index 962d7cf340c765..3ca8129f3b4093 100644 --- a/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/DirectoryVirtualListViewTests.cs +++ b/src/libraries/System.DirectoryServices/tests/System/DirectoryServices/DirectoryVirtualListViewTests.cs @@ -55,7 +55,7 @@ public void Ctor_BeforeCount_AfterCount_Offset(int beforeCount, int afterCount, [InlineData(0, 0, null)] [InlineData(1, 2, "")] [InlineData(1, 2, "target")] - public void Ctor_BeforeCount_AfterCount_Target(int beforeCount, int afterCount, string target) + public void Ctor_BeforeCount_AfterCount_Target(int beforeCount, int afterCount, string? target) { var listView = new DirectoryVirtualListView(beforeCount, afterCount, target); Assert.Equal(afterCount, listView.AfterCount); diff --git a/src/libraries/System.Drawing.Primitives/System.Drawing.Primitives.slnx b/src/libraries/System.Drawing.Primitives/System.Drawing.Primitives.slnx index b62b61d5f4095a..005d060fbae573 100644 --- a/src/libraries/System.Drawing.Primitives/System.Drawing.Primitives.slnx +++ b/src/libraries/System.Drawing.Primitives/System.Drawing.Primitives.slnx @@ -1,37 +1,354 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Drawing.Primitives/src/System.Drawing.Primitives.csproj b/src/libraries/System.Drawing.Primitives/src/System.Drawing.Primitives.csproj index 58b5852c2c916f..bc4df268ea446f 100644 --- a/src/libraries/System.Drawing.Primitives/src/System.Drawing.Primitives.csproj +++ b/src/libraries/System.Drawing.Primitives/src/System.Drawing.Primitives.csproj @@ -46,13 +46,13 @@ - - - - - - - + + + + + + + diff --git a/src/libraries/System.Formats.Asn1/System.Formats.Asn1.slnx b/src/libraries/System.Formats.Asn1/System.Formats.Asn1.slnx index d58229007cde6c..e32a777da59138 100644 --- a/src/libraries/System.Formats.Asn1/System.Formats.Asn1.slnx +++ b/src/libraries/System.Formats.Asn1/System.Formats.Asn1.slnx @@ -1,37 +1,434 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Formats.Asn1/ref/System.Formats.Asn1.cs b/src/libraries/System.Formats.Asn1/ref/System.Formats.Asn1.cs index 4e6516e80b9ca4..eeb4e1a85a9c63 100644 --- a/src/libraries/System.Formats.Asn1/ref/System.Formats.Asn1.cs +++ b/src/libraries/System.Formats.Asn1/ref/System.Formats.Asn1.cs @@ -45,7 +45,7 @@ namespace System.Formats.Asn1 public partial class AsnContentException : System.Exception { public AsnContentException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csproj b/src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csproj index 7b39741b3bb00a..bfe129e148c396 100644 --- a/src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csproj +++ b/src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csproj @@ -54,12 +54,12 @@ - - - - - - + + + + + + diff --git a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnContentException.cs b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnContentException.cs index 782c86ea766738..b35d0ce2b49c3e 100644 --- a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnContentException.cs +++ b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnContentException.cs @@ -55,7 +55,7 @@ public AsnContentException(string? message, Exception? inner) /// /// The contextual information about the source or destination. /// -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Text.cs b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Text.cs index 3f65857b997369..6aebb2aed8bbc9 100644 --- a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Text.cs +++ b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Text.cs @@ -392,7 +392,7 @@ private static unsafe bool TryReadCharacterStringCore( { try { -#if NET8_0_OR_GREATER +#if NET return encoding.TryGetChars(source, destination, out charsWritten); #else if (source.Length == 0) diff --git a/src/libraries/System.Formats.Cbor/ref/System.Formats.Cbor.cs b/src/libraries/System.Formats.Cbor/ref/System.Formats.Cbor.cs index f5c698a1d17e26..d4f52fc0e0ffed 100644 --- a/src/libraries/System.Formats.Cbor/ref/System.Formats.Cbor.cs +++ b/src/libraries/System.Formats.Cbor/ref/System.Formats.Cbor.cs @@ -15,7 +15,7 @@ public enum CborConformanceMode } public partial class CborContentException : System.Exception { -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborContentException.cs b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborContentException.cs index 68f606dac4e7f0..adaeaca66640cf 100644 --- a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborContentException.cs +++ b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborContentException.cs @@ -37,7 +37,7 @@ public CborContentException(string? message, Exception? inner) /// /// The object that holds the serialized object data. /// The contextual information about the source or destination. -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Tag.cs b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Tag.cs index 3ca04f085e04c0..245c5eb0d3f458 100644 --- a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Tag.cs +++ b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Tag.cs @@ -38,11 +38,11 @@ public void WriteTag(CborTag tag) public void WriteDateTimeOffset(DateTimeOffset value) { string dateString = -#if NET8_0_OR_GREATER +#if NET value.TotalOffsetMinutes == 0 ? #else value.Offset == TimeSpan.Zero ? -#endif // NET8_0_OR_GREATER +#endif // NET value.UtcDateTime.ToString(Rfc3339FormatString, CultureInfo.InvariantCulture) : // prefer 'Z' over '+00:00' value.ToString(Rfc3339FormatString, CultureInfo.InvariantCulture); diff --git a/src/libraries/System.Formats.Nrbf/System.Formats.Nrbf.slnx b/src/libraries/System.Formats.Nrbf/System.Formats.Nrbf.slnx index 905b9ab0a13f68..2fc5d9699ec436 100644 --- a/src/libraries/System.Formats.Nrbf/System.Formats.Nrbf.slnx +++ b/src/libraries/System.Formats.Nrbf/System.Formats.Nrbf.slnx @@ -84,6 +84,14 @@ + + + + + + + + @@ -116,6 +124,22 @@ + + + + + + + + + + + + + + + + @@ -124,6 +148,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -132,6 +180,14 @@ + + + + + + + + @@ -140,6 +196,22 @@ + + + + + + + + + + + + + + + + @@ -148,6 +220,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -156,6 +252,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -172,6 +308,22 @@ + + + + + + + + + + + + + + + + @@ -188,6 +340,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -221,6 +405,14 @@ + + + + + + + + @@ -253,6 +445,22 @@ + + + + + + + + + + + + + + + + @@ -261,6 +469,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -269,6 +501,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -277,6 +541,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -285,6 +573,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -301,6 +629,22 @@ + + + + + + + + + + + + + + + + @@ -317,6 +661,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArrayInfo.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArrayInfo.cs index da03a459f35aa9..dd045f7cd9e483 100644 --- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArrayInfo.cs +++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArrayInfo.cs @@ -16,7 +16,7 @@ namespace System.Formats.Nrbf; [DebuggerDisplay("{ArrayType}, rank={Rank}")] internal readonly struct ArrayInfo { -#if NET8_0_OR_GREATER +#if NET internal static int MaxArrayLength => Array.MaxLength; // dynamic lookup in case the value changes in a future runtime #else internal const int MaxArrayLength = 2147483591; // hardcode legacy Array.MaxLength for downlevel runtimes diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/MemberTypeInfo.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/MemberTypeInfo.cs index 84c1073b0ef67a..c46d13f443e119 100644 --- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/MemberTypeInfo.cs +++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/MemberTypeInfo.cs @@ -91,8 +91,10 @@ internal static MemberTypeInfo Decode(BinaryReader reader, int count, PayloadOpt const AllowedRecordTypes SystemClass = Classes | AllowedRecordTypes.SystemClassWithMembersAndTypes // All primitive types can be stored by using one of the interfaces they implement. // Example: `new IEnumerable[1] { "hello" }` or `new IComparable[1] { int.MaxValue }`. - | AllowedRecordTypes.BinaryObjectString | AllowedRecordTypes.MemberPrimitiveTyped; - const AllowedRecordTypes NonSystemClass = Classes | AllowedRecordTypes.ClassWithMembersAndTypes; + | AllowedRecordTypes.BinaryObjectString | AllowedRecordTypes.MemberPrimitiveTyped + // System.Nullable is a special case of SystemClassWithMembersAndTypes + | AllowedRecordTypes.ClassWithMembersAndTypes; + const AllowedRecordTypes NonSystemClass = Classes | AllowedRecordTypes.ClassWithMembersAndTypes; return binaryType switch { diff --git a/src/libraries/System.Formats.Nrbf/tests/EdgeCaseTests.cs b/src/libraries/System.Formats.Nrbf/tests/EdgeCaseTests.cs index f091d47ded8c5f..1d14993a0890c3 100644 --- a/src/libraries/System.Formats.Nrbf/tests/EdgeCaseTests.cs +++ b/src/libraries/System.Formats.Nrbf/tests/EdgeCaseTests.cs @@ -144,4 +144,48 @@ public void CanReadAllKindsOfDateTimes_DateTimeIsMemberOfTheRootRecord(DateTime Assert.Equal(input.Ticks, classRecord.GetDateTime(nameof(ClassWithDateTime.Value)).Ticks); Assert.Equal(input.Kind, classRecord.GetDateTime(nameof(ClassWithDateTime.Value)).Kind); } + + [Fact] + public void CanReadUserClassStoredAsSystemClass() + { + // For the following data, BinaryFormatter serializes the ClassWithNullableStructField class + // as a record with a single field called "NullableField" with BinaryType.SystemClass (!!!) + // and TypeName being System.Nullable`1[[SampleStruct, $AssemblyName]]. + // It most likely does so, because it's System.Nullable<$NonSystemStruct>. + // But later it serializes the SampleStruct as a ClassWithMembersAndTypes record, + // not SystemClassWithMembersAndTypes. + // It does so, only when the payload contains at least one class with the nullable field being null. + + using MemoryStream stream = Serialize( + new ClassWithNullableStructField[] + { + new ClassWithNullableStructField() { NullableField = null }, // having a null here is crucial for the test + new ClassWithNullableStructField() { NullableField = new ClassWithNullableStructField.SampleStruct() { Value = 42 } } + } + ); + + SZArrayRecord arrayRecord = (SZArrayRecord)NrbfDecoder.Decode(stream); + SerializationRecord[] records = arrayRecord.GetArray(); + Assert.Equal(2, arrayRecord.Length); + Assert.All(records, record => Assert.True(record.TypeNameMatches(typeof(ClassWithNullableStructField)))); + Assert.Null(((ClassRecord)records[0]).GetClassRecord(nameof(ClassWithNullableStructField.NullableField))); + + ClassRecord? notNullRecord = ((ClassRecord)records[1]).GetClassRecord(nameof(ClassWithNullableStructField.NullableField)); + Assert.NotNull(notNullRecord); + Assert.Equal(42, notNullRecord.GetInt32(nameof(ClassWithNullableStructField.SampleStruct.Value))); + } + + [Serializable] + public class ClassWithNullableStructField + { +#pragma warning disable IDE0001 // Simplify names + public System.Nullable NullableField; +#pragma warning restore IDE0001 + + [Serializable] + public struct SampleStruct + { + public int Value; + } + } } diff --git a/src/libraries/System.Formats.Nrbf/tests/ReadExactTypesTests.cs b/src/libraries/System.Formats.Nrbf/tests/ReadExactTypesTests.cs index 027293bce05a68..ed6db2790aeb53 100644 --- a/src/libraries/System.Formats.Nrbf/tests/ReadExactTypesTests.cs +++ b/src/libraries/System.Formats.Nrbf/tests/ReadExactTypesTests.cs @@ -173,7 +173,7 @@ public class CustomTypeWithStringArrayField [InlineData("Hello", ", ", "World!")] [InlineData("Single ", "null", null)] [InlineData("Multiple ", null, null)] - public void CanRead_CustomTypeWithStringsArrayField(string value0, string value1, string value2) + public void CanRead_CustomTypeWithStringsArrayField(string value0, string? value1, string? value2) { CustomTypeWithStringArrayField input = new() { diff --git a/src/libraries/System.Formats.Tar/System.Formats.Tar.slnx b/src/libraries/System.Formats.Tar/System.Formats.Tar.slnx index b45679070fc359..15ec8cc119c0d8 100644 --- a/src/libraries/System.Formats.Tar/System.Formats.Tar.slnx +++ b/src/libraries/System.Formats.Tar/System.Formats.Tar.slnx @@ -1,33 +1,290 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Formats.Tar/src/Resources/Strings.resx b/src/libraries/System.Formats.Tar/src/Resources/Strings.resx index ac632535dfd180..1c595d0bc0409d 100644 --- a/src/libraries/System.Formats.Tar/src/Resources/Strings.resx +++ b/src/libraries/System.Formats.Tar/src/Resources/Strings.resx @@ -205,4 +205,7 @@ Cannot write the unseekable data stream of entry '{0}' into an unseekable archive stream. + + The extended header contains invalid records. + diff --git a/src/libraries/System.Formats.Tar/src/System.Formats.Tar.csproj b/src/libraries/System.Formats.Tar/src/System.Formats.Tar.csproj index 6f34a34cc6e7de..465e91734c08aa 100644 --- a/src/libraries/System.Formats.Tar/src/System.Formats.Tar.csproj +++ b/src/libraries/System.Formats.Tar/src/System.Formats.Tar.csproj @@ -74,11 +74,11 @@ - - - - - + + + + + diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/PaxGlobalExtendedAttributesTarEntry.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/PaxGlobalExtendedAttributesTarEntry.cs index 9dc572f8c1c1e4..62a0cf620bdfee 100644 --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/PaxGlobalExtendedAttributesTarEntry.cs +++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/PaxGlobalExtendedAttributesTarEntry.cs @@ -11,8 +11,6 @@ namespace System.Formats.Tar /// public sealed class PaxGlobalExtendedAttributesTarEntry : PosixTarEntry { - private ReadOnlyDictionary? _readOnlyGlobalExtendedAttributes; - // Constructor used when reading an existing archive. internal PaxGlobalExtendedAttributesTarEntry(TarHeader header, TarReader readerOfOrigin) : base(header, readerOfOrigin, TarEntryFormat.Pax) @@ -34,7 +32,7 @@ public PaxGlobalExtendedAttributesTarEntry(IEnumerable /// Returns the global extended attributes stored in this entry. /// - public IReadOnlyDictionary GlobalExtendedAttributes => _readOnlyGlobalExtendedAttributes ??= _header.ExtendedAttributes.AsReadOnly(); + public IReadOnlyDictionary GlobalExtendedAttributes => field ??= _header.ExtendedAttributes.AsReadOnly(); // Determines if the current instance's entry type supports setting a data stream. internal override bool IsDataStreamSetterSupported() => false; diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/PaxTarEntry.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/PaxTarEntry.cs index 30397b03b27ad0..4f1e3f0b4fe022 100644 --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/PaxTarEntry.cs +++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/PaxTarEntry.cs @@ -12,8 +12,6 @@ namespace System.Formats.Tar /// public sealed class PaxTarEntry : PosixTarEntry { - private ReadOnlyDictionary? _readOnlyExtendedAttributes; - // Constructor called when reading a TarEntry from a TarReader. internal PaxTarEntry(TarHeader header, TarReader readerOfOrigin) : base(header, readerOfOrigin, TarEntryFormat.Pax) @@ -122,7 +120,7 @@ public PaxTarEntry(TarEntry other) /// File length, under the name size, as an . /// /// - public IReadOnlyDictionary ExtendedAttributes => _readOnlyExtendedAttributes ??= _header.ExtendedAttributes.AsReadOnly(); + public IReadOnlyDictionary ExtendedAttributes => field ??= _header.ExtendedAttributes.AsReadOnly(); // Determines if the current instance's entry type supports setting a data stream. internal override bool IsDataStreamSetterSupported() => EntryType == TarEntryType.RegularFile; diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/SubReadStream.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/SubReadStream.cs index bda8886efd5a8e..efa933d02fa70b 100644 --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/SubReadStream.cs +++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/SubReadStream.cs @@ -64,23 +64,26 @@ public override long Position public override bool CanWrite => false; - internal bool HasReachedEnd + private long Remaining => _endInSuperStream - _positionInSuperStream; + + private int LimitByRemaining(int bufferSize) => (int)Math.Min(Remaining, bufferSize); + + internal ValueTask AdvanceToEndAsync(CancellationToken cancellationToken) { - get - { - if (!_hasReachedEnd && _positionInSuperStream > _endInSuperStream) - { - _hasReachedEnd = true; - } - return _hasReachedEnd; - } - set - { - if (value) // Don't allow revert to false - { - _hasReachedEnd = true; - } - } + _hasReachedEnd = true; + + long remaining = Remaining; + _positionInSuperStream = _endInSuperStream; + return TarHelpers.AdvanceStreamAsync(_superStream, remaining, cancellationToken); + } + + internal void AdvanceToEnd() + { + _hasReachedEnd = true; + + long remaining = Remaining; + _positionInSuperStream = _endInSuperStream; + TarHelpers.AdvanceStream(_superStream, remaining); } protected void ThrowIfDisposed() @@ -90,7 +93,7 @@ protected void ThrowIfDisposed() private void ThrowIfBeyondEndOfStream() { - if (HasReachedEnd) + if (_hasReachedEnd) { throw new EndOfStreamException(); } @@ -107,21 +110,12 @@ public override int Read(Span destination) ThrowIfDisposed(); ThrowIfBeyondEndOfStream(); - // parameter validation sent to _superStream.Read - int origCount = destination.Length; - int count = destination.Length; - - if (_positionInSuperStream + count > _endInSuperStream) - { - count = (int)(_endInSuperStream - _positionInSuperStream); - } - - Debug.Assert(count >= 0); - Debug.Assert(count <= origCount); + destination = destination[..LimitByRemaining(destination.Length)]; - int ret = _superStream.Read(destination.Slice(0, count)); + int ret = _superStream.Read(destination); _positionInSuperStream += ret; + return ret; } @@ -158,14 +152,12 @@ protected async ValueTask ReadAsyncCore(Memory buffer, CancellationTo cancellationToken.ThrowIfCancellationRequested(); - if (_positionInSuperStream > _endInSuperStream - buffer.Length) - { - buffer = buffer.Slice(0, (int)(_endInSuperStream - _positionInSuperStream)); - } + buffer = buffer[..LimitByRemaining(buffer.Length)]; int ret = await _superStream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false); _positionInSuperStream += ret; + return ret; } diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Read.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Read.cs index 37570d0d33a5ea..509bcd02a24abf 100644 --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Read.cs +++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Read.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.IO; using System.Text; using System.Threading; @@ -384,7 +385,7 @@ private async Task ProcessDataBlockAsync(Stream archiveStream, bool copyData, Ca // Continue with the rest of the fields that require no special checks TarHeader header = new(initialFormat, - name: TarHelpers.GetTrimmedUtf8String(buffer.Slice(FieldLocations.Name, FieldLengths.Name)), + name: TarHelpers.ParseUtf8String(buffer.Slice(FieldLocations.Name, FieldLengths.Name)), mode: TarHelpers.ParseNumeric(buffer.Slice(FieldLocations.Mode, FieldLengths.Mode)), mTime: ParseAsTimestamp(buffer.Slice(FieldLocations.MTime, FieldLengths.MTime)), typeFlag: (TarEntryType)buffer[FieldLocations.TypeFlag]) @@ -393,7 +394,7 @@ private async Task ProcessDataBlockAsync(Stream archiveStream, bool copyData, Ca _size = size, _uid = TarHelpers.ParseNumeric(buffer.Slice(FieldLocations.Uid, FieldLengths.Uid)), _gid = TarHelpers.ParseNumeric(buffer.Slice(FieldLocations.Gid, FieldLengths.Gid)), - _linkName = TarHelpers.GetTrimmedUtf8String(buffer.Slice(FieldLocations.LinkName, FieldLengths.LinkName)) + _linkName = TarHelpers.ParseUtf8String(buffer.Slice(FieldLocations.LinkName, FieldLengths.LinkName)) }; if (header._format == TarEntryFormat.Unknown) @@ -517,8 +518,8 @@ private void ReadVersionAttribute(ReadOnlySpan buffer) private void ReadPosixAndGnuSharedAttributes(ReadOnlySpan buffer) { // Convert the byte arrays - _uName = TarHelpers.GetTrimmedUtf8String(buffer.Slice(FieldLocations.UName, FieldLengths.UName)); - _gName = TarHelpers.GetTrimmedUtf8String(buffer.Slice(FieldLocations.GName, FieldLengths.GName)); + _uName = TarHelpers.ParseUtf8String(buffer.Slice(FieldLocations.UName, FieldLengths.UName)); + _gName = TarHelpers.ParseUtf8String(buffer.Slice(FieldLocations.GName, FieldLengths.GName)); // DevMajor and DevMinor only have values with character devices and block devices. // For all other typeflags, the values in these fields are irrelevant. @@ -560,7 +561,7 @@ private static DateTimeOffset ParseAsTimestamp(ReadOnlySpan buffer) // Throws if a conversion to an expected data type fails. private void ReadUstarAttributes(ReadOnlySpan buffer) { - _prefix = TarHelpers.GetTrimmedUtf8String(buffer.Slice(FieldLocations.Prefix, FieldLengths.Prefix)); + _prefix = TarHelpers.ParseUtf8String(buffer.Slice(FieldLocations.Prefix, FieldLengths.Prefix)); // In ustar, Prefix is used to store the *leading* path segments of // Name, if the full path did not fit in the Name byte array. @@ -631,8 +632,6 @@ void ThrowSizeFieldTooLarge() => // Returns a dictionary containing the extended attributes collected from the provided byte buffer. private void ReadExtendedAttributesFromBuffer(ReadOnlySpan buffer, string name) { - buffer = TarHelpers.TrimEndingNullsAndSpaces(buffer); - while (TryGetNextExtendedAttribute(ref buffer, out string? key, out string? value)) { if (!ExtendedAttributes.TryAdd(key, value)) @@ -640,6 +639,11 @@ private void ReadExtendedAttributesFromBuffer(ReadOnlySpan buffer, string throw new InvalidDataException(SR.Format(SR.TarDuplicateExtendedAttribute, name)); } } + + if (buffer.Length > 0) + { + throw new InvalidDataException(SR.Format(SR.ExtHeaderInvalidRecords)); + } } // Reads the long path found in the data section of a GNU entry of type 'K' or 'L' @@ -691,7 +695,7 @@ private async ValueTask ReadGnuLongPathDataBlockAsync(Stream archiveStream, Canc // Collects the GNU long path info from the buffer and sets it in the right field depending on the type flag. private void ReadGnuLongPathDataFromBuffer(ReadOnlySpan buffer) { - string longPath = TarHelpers.GetTrimmedUtf8String(buffer); + string longPath = TarHelpers.ParseUtf8String(buffer); if (_typeFlag == TarEntryType.LongLink) { @@ -725,15 +729,21 @@ private static bool TryGetNextExtendedAttribute( } ReadOnlySpan line = buffer.Slice(0, newlinePos); - // Update buffer to point to the next line for the next call - buffer = buffer.Slice(newlinePos + 1); - - // Find the end of the length and remove everything up through it. + // Find the end of the length int spacePos = line.IndexOf((byte)' '); if (spacePos < 0) { return false; } + + // Check the length matches the line length + ReadOnlySpan length = buffer.Slice(0, spacePos); + if (!int.TryParse(length, NumberStyles.None, CultureInfo.InvariantCulture, out int lengthValue) || lengthValue != (line.Length + 1)) + { + return false; + } + + // Remove the length line = line.Slice(spacePos + 1); // Find the equal separator. @@ -749,6 +759,9 @@ private static bool TryGetNextExtendedAttribute( // Return the parsed key and value. key = Encoding.UTF8.GetString(keySlice); value = Encoding.UTF8.GetString(valueSlice); + + // Update buffer to point to the next line for the next call + buffer = buffer.Slice(newlinePos + 1); return true; } } diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.cs index a2e037e615e730..77cfc47de0bf70 100644 --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.cs +++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.cs @@ -240,8 +240,10 @@ internal static T ParseNumeric(ReadOnlySpan buffer) where T : struct, I /// Parses a byte span that represents an ASCII string containing a number in octal base. internal static T ParseOctal(ReadOnlySpan buffer) where T : struct, INumber { - buffer = TrimEndingNullsAndSpaces(buffer); - buffer = TrimLeadingNullsAndSpaces(buffer); + buffer = TrimNullTerminated(buffer); + + // We ignore spaces because some archives seem to have them (even though they shouldn't). + buffer = buffer.Trim((byte)' '); if (buffer.Length == 0) { @@ -268,44 +270,23 @@ internal static T ParseOctal(ReadOnlySpan buffer) where T : struct, INu private static void ThrowInvalidNumber() => throw new InvalidDataException(SR.Format(SR.TarInvalidNumber)); - // Returns the string contained in the specified buffer of bytes, - // in the specified encoding, removing the trailing null or space chars. - private static string GetTrimmedString(ReadOnlySpan buffer, Encoding encoding) + // Returns the null-terminated UTF8 string contained in the specified buffer. + internal static string ParseUtf8String(ReadOnlySpan buffer) { - buffer = TrimEndingNullsAndSpaces(buffer); - return buffer.IsEmpty ? string.Empty : encoding.GetString(buffer); - } - - internal static ReadOnlySpan TrimEndingNullsAndSpaces(ReadOnlySpan buffer) - { - int trimmedLength = buffer.Length; - while (trimmedLength > 0 && buffer[trimmedLength - 1] is 0 or 32) - { - trimmedLength--; - } - - return buffer.Slice(0, trimmedLength); + buffer = TrimNullTerminated(buffer); + return Encoding.UTF8.GetString(buffer); } - private static ReadOnlySpan TrimLeadingNullsAndSpaces(ReadOnlySpan buffer) + internal static ReadOnlySpan TrimNullTerminated(ReadOnlySpan buffer) { - int newStart = 0; - while (newStart < buffer.Length && buffer[newStart] is 0 or 32) + int i = buffer.IndexOf((byte)0); + if (i != -1) { - newStart++; + buffer = buffer[0..i]; } - - return buffer.Slice(newStart); + return buffer; } - // Returns the ASCII string contained in the specified buffer of bytes, - // removing the trailing null or space chars. - internal static string GetTrimmedAsciiString(ReadOnlySpan buffer) => GetTrimmedString(buffer, Encoding.ASCII); - - // Returns the UTF8 string contained in the specified buffer of bytes, - // removing the trailing null or space chars. - internal static string GetTrimmedUtf8String(ReadOnlySpan buffer) => GetTrimmedString(buffer, Encoding.UTF8); - // After the file contents, there may be zero or more null characters, // which exist to ensure the data is aligned to the record size. Skip them and // set the stream position to the first byte of the next entry. diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarReader.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarReader.cs index fc2e4001a2a661..747cba3102fecc 100644 --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarReader.cs +++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarReader.cs @@ -221,17 +221,8 @@ internal void AdvanceDataStreamIfNeeded() return; } - if (!dataStream.HasReachedEnd) - { - // If the user did not advance the position, we need to make sure the position - // pointer is located at the beginning of the next header. - if (dataStream.Position < (_previouslyReadEntry._header._size - 1)) - { - long bytesToSkip = _previouslyReadEntry._header._size - dataStream.Position; - TarHelpers.AdvanceStream(_archiveStream, bytesToSkip); - dataStream.HasReachedEnd = true; // Now the pointer is beyond the limit, so any read attempts should throw - } - } + dataStream.AdvanceToEnd(); + TarHelpers.SkipBlockAlignmentPadding(_archiveStream, _previouslyReadEntry._header._size); } } @@ -263,17 +254,8 @@ internal async ValueTask AdvanceDataStreamIfNeededAsync(CancellationToken cancel return; } - if (!dataStream.HasReachedEnd) - { - // If the user did not advance the position, we need to make sure the position - // pointer is located at the beginning of the next header. - if (dataStream.Position < (_previouslyReadEntry._header._size - 1)) - { - long bytesToSkip = _previouslyReadEntry._header._size - dataStream.Position; - await TarHelpers.AdvanceStreamAsync(_archiveStream, bytesToSkip, cancellationToken).ConfigureAwait(false); - dataStream.HasReachedEnd = true; // Now the pointer is beyond the limit, so any read attempts should throw - } - } + await dataStream.AdvanceToEndAsync(cancellationToken).ConfigureAwait(false); + await TarHelpers.SkipBlockAlignmentPaddingAsync(_archiveStream, _previouslyReadEntry._header._size, cancellationToken).ConfigureAwait(false); } } diff --git a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectory.File.Roundtrip.cs b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectory.File.Roundtrip.cs index 84d94cbcb1acfc..eebac48379569a 100644 --- a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectory.File.Roundtrip.cs +++ b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectory.File.Roundtrip.cs @@ -14,7 +14,7 @@ public class TarFile_CreateFromDirectory_Roundtrip_Tests : TarTestsBase [InlineData("../file.txt", "subDirectory1/subDirectory1.1")] [InlineData("./file.txt", "subDirectory1/subDirectory1.1")] [InlineData("./file.txt", null)] - public void SymlinkRelativeTargets_InsideTheArchive_RoundtripsSuccessfully(string symlinkTargetPath, string subDirectory) + public void SymlinkRelativeTargets_InsideTheArchive_RoundtripsSuccessfully(string symlinkTargetPath, string? subDirectory) { using TempDirectory root = new TempDirectory(); @@ -51,7 +51,7 @@ public void SymlinkRelativeTargets_InsideTheArchive_RoundtripsSuccessfully(strin [ConditionalTheory(typeof(MountHelper), nameof(MountHelper.CanCreateSymbolicLinks))] [InlineData("../file.txt", null)] [InlineData("../../file.txt", "subDirectory")] - public void SymlinkRelativeTargets_OutsideTheArchive_Fails(string symlinkTargetPath, string subDirectory) + public void SymlinkRelativeTargets_OutsideTheArchive_Fails(string symlinkTargetPath, string? subDirectory) { using TempDirectory root = new TempDirectory(); diff --git a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.File.Roundtrip.cs b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.File.Roundtrip.cs index d36745c5f0fddc..ddad755cad6e17 100644 --- a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.File.Roundtrip.cs +++ b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.File.Roundtrip.cs @@ -15,7 +15,7 @@ public class TarFile_CreateFromDirectoryAsync_Roundtrip_Tests : TarTestsBase [InlineData("../file.txt", "subDirectory1/subDirectory1.1")] [InlineData("./file.txt", "subDirectory1/subDirectory1.1")] [InlineData("./file.txt", null)] - public async Task SymlinkRelativeTargets_InsideTheArchive_RoundtripsSuccessfully_Async(string symlinkTargetPath, string subDirectory) + public async Task SymlinkRelativeTargets_InsideTheArchive_RoundtripsSuccessfully_Async(string symlinkTargetPath, string? subDirectory) { using TempDirectory root = new TempDirectory(); @@ -52,7 +52,7 @@ public async Task SymlinkRelativeTargets_InsideTheArchive_RoundtripsSuccessfully [ConditionalTheory(typeof(MountHelper), nameof(MountHelper.CanCreateSymbolicLinks))] [InlineData("../file.txt", null)] [InlineData("../../file.txt", "subDirectory")] - public async Task SymlinkRelativeTargets_OutsideTheArchive_Fails_Async(string symlinkTargetPath, string subDirectory) + public async Task SymlinkRelativeTargets_OutsideTheArchive_Fails_Async(string symlinkTargetPath, string? subDirectory) { using TempDirectory root = new TempDirectory(); diff --git a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.Async.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.Async.Tests.cs index e603e6e9aa4691..9692dcca89756a 100644 --- a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.Async.Tests.cs +++ b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.Async.Tests.cs @@ -6,6 +6,7 @@ using System.IO; using System.IO.Compression; using System.Linq; +using System.Text; using System.Threading.Tasks; using Xunit; @@ -261,7 +262,8 @@ public async Task AllowSpacesInOctalFieldsAsync(string folderName, string testCa [InlineData("gnu-multi-hdrs")] // Multiple consecutive GNU metadata entries [InlineData("neg-size")] // Garbage chars [InlineData("invalid-go17")] // Many octal fields are all zero chars - [InlineData("issue11169")] // Checksum with null in the middle + [InlineData("issue11169")] // Extended header uses spaces instead of newlines to separate records + [InlineData("pax-bad-hdr-file")] // Extended header record is not terminated by newline [InlineData("issue10968")] // Garbage chars public async Task Throw_ArchivesWithRandomCharsAsync(string testCaseName) { @@ -308,6 +310,32 @@ public async Task SparseEntryNotSupportedAsync(string testFolderName, string tes await Assert.ThrowsAsync(async () => await reader.GetNextEntryAsync()); } + [Fact] + public async Task ReaderIgnoresFieldValueAfterTrailingNullAsync() + { + // Fields in the tar archives are terminated by a trailing null. + // When reading these fields the reader must ignore all bytes past that null. + + // Construct an archive that has a filename with some data after the trailing null. + const string FileName = " filename "; + const string FileNameWithDataPastTrailingNull = $"{FileName}\0nonesense"; + using MemoryStream ms = new(); + using (TarWriter writer = new(ms, leaveOpen: true)) + { + var entry = new UstarTarEntry(TarEntryType.RegularFile, FileNameWithDataPastTrailingNull); + writer.WriteEntry(entry); + } + ms.Position = 0; + // Check the writer serialized the complete name passed to the constructor. + bool archiveIsExpected = ms.ToArray().IndexOf(Encoding.UTF8.GetBytes(FileNameWithDataPastTrailingNull)) != -1; + Assert.True(archiveIsExpected); + + // Verify the reader doesn't return the data past the trailing null. + using TarReader reader = new(ms); + TarEntry firstEntry = await reader.GetNextEntryAsync(); + Assert.Equal(FileName, firstEntry.Name); + } + [Fact] public async Task DirectoryListRegularFileAndSparseAsync() { diff --git a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.Tests.cs index 955f29c841849f..0d8557d62a22b2 100644 --- a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.Tests.cs +++ b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.File.Tests.cs @@ -6,6 +6,7 @@ using System.IO; using System.IO.Compression; using System.Linq; +using System.Text; using Xunit; using static System.Formats.Tar.Tests.TarTestsBase; @@ -269,7 +270,8 @@ public void AllowSpacesInOctalFields(string folderName, string testCaseName) [InlineData("gnu-multi-hdrs")] // Multiple consecutive GNU metadata entries [InlineData("neg-size")] // Garbage chars [InlineData("invalid-go17")] // Many octal fields are all zero chars - [InlineData("issue11169")] // Checksum with null in the middle + [InlineData("issue11169")] // Extended header uses spaces instead of newlines to separate records + [InlineData("pax-bad-hdr-file")] // Extended header record is not terminated by newline [InlineData("issue10968")] // Garbage chars public void Throw_ArchivesWithRandomChars(string testCaseName) { @@ -316,6 +318,32 @@ public void SparseEntryNotSupported(string testFolderName, string testCaseName) Assert.Throws(() => reader.GetNextEntry()); } + [Fact] + public void ReaderIgnoresFieldValueAfterTrailingNull() + { + // Fields in the tar archives are terminated by a trailing null. + // When reading these fields the reader must ignore all bytes past that null. + + // Construct an archive that has a filename with some data after the trailing null. + const string FileName = " filename "; + const string FileNameWithDataPastTrailingNull = $"{FileName}\0nonesense"; + using MemoryStream ms = new(); + using (TarWriter writer = new(ms, leaveOpen: true)) + { + var entry = new UstarTarEntry(TarEntryType.RegularFile, FileNameWithDataPastTrailingNull); + writer.WriteEntry(entry); + } + ms.Position = 0; + // Check the writer serialized the complete name passed to the constructor. + bool archiveIsExpected = ms.ToArray().IndexOf(Encoding.UTF8.GetBytes(FileNameWithDataPastTrailingNull)) != -1; + Assert.True(archiveIsExpected); + + // Verify the reader doesn't return the data past the trailing null. + using TarReader reader = new(ms); + TarEntry firstEntry = reader.GetNextEntry(); + Assert.Equal(FileName, firstEntry.Name); + } + [Fact] public void DirectoryListRegularFileAndSparse() { diff --git a/src/libraries/System.Formats.Tar/tests/TarTestsBase.cs b/src/libraries/System.Formats.Tar/tests/TarTestsBase.cs index b68493996a095d..16352979db2217 100644 --- a/src/libraries/System.Formats.Tar/tests/TarTestsBase.cs +++ b/src/libraries/System.Formats.Tar/tests/TarTestsBase.cs @@ -137,7 +137,6 @@ public abstract partial class TarTestsBase : FileCleanupTestBase "gnu", "hardlink", "nil-uid", - "pax-bad-hdr-file", "pax-bad-mtime-file", "pax-global-records", "pax-nul-path", diff --git a/src/libraries/System.IO.Compression.Brotli/System.IO.Compression.Brotli.slnx b/src/libraries/System.IO.Compression.Brotli/System.IO.Compression.Brotli.slnx index 199369d4226420..2eb4f1934576f0 100644 --- a/src/libraries/System.IO.Compression.Brotli/System.IO.Compression.Brotli.slnx +++ b/src/libraries/System.IO.Compression.Brotli/System.IO.Compression.Brotli.slnx @@ -1,33 +1,298 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.IO.Compression.Brotli/src/System.IO.Compression.Brotli.csproj b/src/libraries/System.IO.Compression.Brotli/src/System.IO.Compression.Brotli.csproj index 8e642e75833c55..124cd52bc84993 100644 --- a/src/libraries/System.IO.Compression.Brotli/src/System.IO.Compression.Brotli.csproj +++ b/src/libraries/System.IO.Compression.Brotli/src/System.IO.Compression.Brotli.csproj @@ -42,12 +42,12 @@ - - - - - - + + + + + + diff --git a/src/libraries/System.IO.Compression.Brotli/tests/CompressionStreamUnitTests.Brotli.cs b/src/libraries/System.IO.Compression.Brotli/tests/CompressionStreamUnitTests.Brotli.cs index 2fb9eacc9dfc3f..10f46a6ceb5e87 100644 --- a/src/libraries/System.IO.Compression.Brotli/tests/CompressionStreamUnitTests.Brotli.cs +++ b/src/libraries/System.IO.Compression.Brotli/tests/CompressionStreamUnitTests.Brotli.cs @@ -109,7 +109,7 @@ public void InvalidBrotliCompressionQuality() [Theory] [MemberData(nameof(UncompressedTestFilesBrotli))] - public async void BrotliCompressionQuality_SizeInOrder(string testFile) + public async Task BrotliCompressionQuality_SizeInOrder(string testFile) { using var uncompressedStream = await LocalMemoryStream.ReadAppFileAsync(testFile); diff --git a/src/libraries/System.IO.Compression.ZipFile/System.IO.Compression.ZipFile.slnx b/src/libraries/System.IO.Compression.ZipFile/System.IO.Compression.ZipFile.slnx index 22021a6c2286ee..e7dcb9451e0e19 100644 --- a/src/libraries/System.IO.Compression.ZipFile/System.IO.Compression.ZipFile.slnx +++ b/src/libraries/System.IO.Compression.ZipFile/System.IO.Compression.ZipFile.slnx @@ -1,32 +1,290 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.IO.Compression.ZipFile/src/System.IO.Compression.ZipFile.csproj b/src/libraries/System.IO.Compression.ZipFile/src/System.IO.Compression.ZipFile.csproj index 298815a2a9a9c8..1709589cc4d076 100644 --- a/src/libraries/System.IO.Compression.ZipFile/src/System.IO.Compression.ZipFile.csproj +++ b/src/libraries/System.IO.Compression.ZipFile/src/System.IO.Compression.ZipFile.csproj @@ -50,10 +50,10 @@ - - - - + + + + diff --git a/src/libraries/System.IO.Compression/System.IO.Compression.slnx b/src/libraries/System.IO.Compression/System.IO.Compression.slnx index b4d9f77110d393..2325ce22e7b57f 100644 --- a/src/libraries/System.IO.Compression/System.IO.Compression.slnx +++ b/src/libraries/System.IO.Compression/System.IO.Compression.slnx @@ -1,32 +1,282 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.IO.Compression/src/Resources/Strings.resx b/src/libraries/System.IO.Compression/src/Resources/Strings.resx index 86e181e97ff13b..e6235c419f5f12 100644 --- a/src/libraries/System.IO.Compression/src/Resources/Strings.resx +++ b/src/libraries/System.IO.Compression/src/Resources/Strings.resx @@ -293,4 +293,7 @@ System.IO.Compression is not supported on this platform. + + Invalid offset to the Zip64 End of Central Directory record. + diff --git a/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj b/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj index 835c3485162455..7510c1c1052274 100644 --- a/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj +++ b/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj @@ -79,11 +79,11 @@ - - - - - + + + + + diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchive.Async.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchive.Async.cs index db0bdd7b1e63b0..19b025473e39b6 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchive.Async.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchive.Async.cs @@ -247,10 +247,12 @@ private async Task ReadEndOfCentralDirectoryAsync(CancellationToken cancellation cancellationToken).ConfigureAwait(false)) throw new InvalidDataException(SR.EOCDNotFound); + long eocdStart = _archiveStream.Position; + // read the EOCD ZipEndOfCentralDirectoryBlock eocd = await ZipEndOfCentralDirectoryBlock.ReadBlockAsync(_archiveStream, cancellationToken).ConfigureAwait(false); - ReadEndOfCentralDirectoryInnerWork(eocd, out long eocdStart); + ReadEndOfCentralDirectoryInnerWork(eocd); await TryReadZip64EndOfCentralDirectoryAsync(eocd, eocdStart, cancellationToken).ConfigureAwait(false); @@ -284,6 +286,12 @@ private async ValueTask TryReadZip64EndOfCentralDirectoryAsync(ZipEndOfCentralDi { // Read Zip64 End of Central Directory Locator + // Check if there's enough space before the EOCD to look for the Zip64 EOCDL + if (eocdStart < Zip64EndOfCentralDirectoryLocator.TotalSize) + { + throw new InvalidDataException(SR.Zip64EOCDNotWhereExpected); + } + // This seeks forwards almost to the beginning of the Zip64-EOCDL, one byte after where the signature would be located _archiveStream.Seek(eocdStart - Zip64EndOfCentralDirectoryLocator.SizeOfBlockWithoutSignature, SeekOrigin.Begin); diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchive.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchive.cs index 900f40c8ccfcb2..6e1e36fd63b8eb 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchive.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchive.cs @@ -587,10 +587,8 @@ private void ReadCentralDirectory() } } - private void ReadEndOfCentralDirectoryInnerWork(ZipEndOfCentralDirectoryBlock eocd, out long eocdStart) + private void ReadEndOfCentralDirectoryInnerWork(ZipEndOfCentralDirectoryBlock eocd) { - eocdStart = _archiveStream.Position; - if (eocd.NumberOfThisDisk != eocd.NumberOfTheDiskWithTheStartOfTheCentralDirectory) throw new InvalidDataException(SR.SplitSpanned); @@ -624,10 +622,12 @@ private void ReadEndOfCentralDirectory() ZipEndOfCentralDirectoryBlock.ZipFileCommentMaxLength + ZipEndOfCentralDirectoryBlock.FieldLengths.Signature)) throw new InvalidDataException(SR.EOCDNotFound); + long eocdStart = _archiveStream.Position; + // read the EOCD ZipEndOfCentralDirectoryBlock eocd = ZipEndOfCentralDirectoryBlock.ReadBlock(_archiveStream); - ReadEndOfCentralDirectoryInnerWork(eocd, out long eocdStart); + ReadEndOfCentralDirectoryInnerWork(eocd); TryReadZip64EndOfCentralDirectory(eocd, eocdStart); @@ -653,6 +653,9 @@ private void TryReadZip64EndOfCentralDirectoryInnerInitialWork(Zip64EndOfCentral long zip64EOCDOffset = (long)locator.OffsetOfZip64EOCD; + if (zip64EOCDOffset < 0 || zip64EOCDOffset > _archiveStream.Length) + throw new InvalidDataException(SR.InvalidOffsetToZip64EOCD); + _archiveStream.Seek(zip64EOCDOffset, SeekOrigin.Begin); } @@ -686,6 +689,12 @@ private void TryReadZip64EndOfCentralDirectory(ZipEndOfCentralDirectoryBlock eoc { // Read Zip64 End of Central Directory Locator + // Check if there's enough space before the EOCD to look for the Zip64 EOCDL + if (eocdStart < Zip64EndOfCentralDirectoryLocator.TotalSize) + { + throw new InvalidDataException(SR.Zip64EOCDNotWhereExpected); + } + // This seeks forwards almost to the beginning of the Zip64-EOCDL, one byte after where the signature would be located _archiveStream.Seek(eocdStart - Zip64EndOfCentralDirectoryLocator.SizeOfBlockWithoutSignature, SeekOrigin.Begin); @@ -701,7 +710,6 @@ private void TryReadZip64EndOfCentralDirectory(ZipEndOfCentralDirectoryBlock eoc // Read Zip64 End of Central Directory Record Zip64EndOfCentralDirectoryRecord record = Zip64EndOfCentralDirectoryRecord.TryReadBlock(_archiveStream); - TryReadZip64EndOfCentralDirectoryInnerFinalWork(record); } } diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.Async.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.Async.cs index b50b9fdcc91709..030f2d1e25f635 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.Async.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.Async.cs @@ -172,9 +172,9 @@ internal async Task LoadCompressedBytesIfNeededAsync(CancellationToken cancellat for (int i = 0; i < _compressedBytes.Length - 1; i++) { - await ZipHelper.ReadBytesAsync(_archive.ArchiveStream, _compressedBytes[i], maxSingleBufferSize, cancellationToken).ConfigureAwait(false); + await _archive.ArchiveStream.ReadAtLeastAsync(_compressedBytes[i], maxSingleBufferSize, throwOnEndOfStream: true, cancellationToken).ConfigureAwait(false); } - await ZipHelper.ReadBytesAsync(_archive.ArchiveStream, _compressedBytes[_compressedBytes.Length - 1], (int)(_compressedSize % maxSingleBufferSize), cancellationToken).ConfigureAwait(false); + await _archive.ArchiveStream.ReadAtLeastAsync(_compressedBytes[_compressedBytes.Length - 1], (int)(_compressedSize % maxSingleBufferSize), throwOnEndOfStream: true, cancellationToken).ConfigureAwait(false); } } diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs index a7bdf84c4e23a7..3854bc37eddba7 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs @@ -678,9 +678,9 @@ internal void LoadCompressedBytesIfNeeded() for (int i = 0; i < _compressedBytes.Length - 1; i++) { - ZipHelper.ReadBytes(_archive.ArchiveStream, _compressedBytes[i], maxSingleBufferSize); + _archive.ArchiveStream.ReadAtLeast(_compressedBytes[i], maxSingleBufferSize, throwOnEndOfStream: true); } - ZipHelper.ReadBytes(_archive.ArchiveStream, _compressedBytes[_compressedBytes.Length - 1], (int)(_compressedSize % maxSingleBufferSize)); + _archive.ArchiveStream.ReadAtLeast(_compressedBytes[_compressedBytes.Length - 1], (int)(_compressedSize % maxSingleBufferSize), throwOnEndOfStream: true); } } diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipHelper.Async.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipHelper.Async.cs index 04b65b6fda6186..336d2081271893 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipHelper.Async.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipHelper.Async.cs @@ -10,22 +10,6 @@ namespace System.IO.Compression; internal static partial class ZipHelper { - /// - /// Asynchronously reads exactly bytesToRead out of stream, unless it is out of bytes. - /// - internal static async Task ReadBytesAsync(Stream stream, Memory buffer, int bytesToRead, CancellationToken cancellationToken) - { - cancellationToken.ThrowIfCancellationRequested(); - - int bytesRead = await stream.ReadAtLeastAsync(buffer, bytesToRead, throwOnEndOfStream: false, cancellationToken).ConfigureAwait(false); - - if (bytesRead < bytesToRead) - { - throw new IOException(SR.UnexpectedEndOfStream); - } - return bytesRead; - } - // Asynchronously assumes all bytes of signatureToFind are non zero, looks backwards from current position in stream, // assumes maxBytesToRead is positive, ensures to not read beyond the provided max number of bytes, // if the signature is found then returns true and positions stream at first byte of signature @@ -53,11 +37,18 @@ internal static async Task SeekBackwardsToSignatureAsync(Stream stream, Re bool signatureFound = false; int totalBytesRead = 0; - int duplicateBytesRead = 0; - while (!signatureFound && !outOfBytes && totalBytesRead <= maxBytesToRead) + while (!signatureFound && !outOfBytes && totalBytesRead < maxBytesToRead) { - int bytesRead = await SeekBackwardsAndReadAsync(stream, bufferMemory, signatureToFind.Length, cancellationToken).ConfigureAwait(false); + int overlap = totalBytesRead == 0 ? 0 : signatureToFind.Length; + + if (maxBytesToRead - totalBytesRead + overlap < bufferMemory.Length) + { + // If we have less than a full buffer left to read, we adjust the buffer size. + bufferMemory = bufferMemory.Slice(0, maxBytesToRead - totalBytesRead + overlap); + } + + int bytesRead = await SeekBackwardsAndReadAsync(stream, bufferMemory, overlap, cancellationToken).ConfigureAwait(false); outOfBytes = bytesRead < bufferMemory.Length; if (bytesRead < bufferMemory.Length) @@ -68,15 +59,13 @@ internal static async Task SeekBackwardsToSignatureAsync(Stream stream, Re bufferPointer = bufferMemory.Span.LastIndexOf(signatureToFind.Span); Debug.Assert(bufferPointer < bufferMemory.Length); - totalBytesRead += (bufferMemory.Length - duplicateBytesRead); + totalBytesRead += bytesRead - overlap; if (bufferPointer != -1) { signatureFound = true; break; } - - duplicateBytesRead = signatureToFind.Length; } if (!signatureFound) @@ -109,14 +98,14 @@ private static async Task SeekBackwardsAndReadAsync(Stream stream, Memory - /// Reads exactly bytesToRead out of stream, unless it is out of bytes - /// - internal static int ReadBytes(Stream stream, Span buffer, int bytesToRead) - { - int bytesRead = stream.ReadAtLeast(buffer, bytesToRead, throwOnEndOfStream: false); - if (bytesRead < bytesToRead) - { - throw new IOException(SR.UnexpectedEndOfStream); - } - return bytesRead; - } - // will silently return InvalidDateIndicator if the uint is not a valid Dos DateTime internal static DateTime DosTimeToDateTime(uint dateTime) { @@ -124,11 +111,18 @@ internal static bool SeekBackwardsToSignature(Stream stream, ReadOnlySpan bool signatureFound = false; int totalBytesRead = 0; - int duplicateBytesRead = 0; - while (!signatureFound && !outOfBytes && totalBytesRead <= maxBytesToRead) + while (!signatureFound && !outOfBytes && totalBytesRead < maxBytesToRead) { - int bytesRead = SeekBackwardsAndRead(stream, bufferSpan, signatureToFind.Length); + int overlap = totalBytesRead == 0 ? 0 : signatureToFind.Length; + + if (maxBytesToRead - totalBytesRead + overlap < bufferSpan.Length) + { + // If we have less than a full buffer left to read, we adjust the buffer size. + bufferSpan = bufferSpan.Slice(0, maxBytesToRead - totalBytesRead + overlap); + } + + int bytesRead = SeekBackwardsAndRead(stream, bufferSpan, overlap); outOfBytes = bytesRead < bufferSpan.Length; if (bytesRead < bufferSpan.Length) @@ -139,15 +133,13 @@ internal static bool SeekBackwardsToSignature(Stream stream, ReadOnlySpan bufferPointer = bufferSpan.LastIndexOf(signatureToFind); Debug.Assert(bufferPointer < bufferSpan.Length); - totalBytesRead += (bufferSpan.Length - duplicateBytesRead); + totalBytesRead += bytesRead - overlap; if (bufferPointer != -1) { signatureFound = true; break; } - - duplicateBytesRead = signatureToFind.Length; } if (!signatureFound) @@ -178,14 +170,14 @@ private static int SeekBackwardsAndRead(Stream stream, Span buffer, int ov { Debug.Assert(overlap <= buffer.Length); stream.Seek(-(buffer.Length - overlap), SeekOrigin.Current); - bytesRead = ReadBytes(stream, buffer, buffer.Length); + bytesRead = stream.ReadAtLeast(buffer, buffer.Length, throwOnEndOfStream: true); stream.Seek(-buffer.Length, SeekOrigin.Current); } else { int bytesToRead = (int)stream.Position; stream.Seek(0, SeekOrigin.Begin); - bytesRead = ReadBytes(stream, buffer, bytesToRead); + bytesRead = stream.ReadAtLeast(buffer, bytesToRead, throwOnEndOfStream: true); stream.Seek(0, SeekOrigin.Begin); } diff --git a/src/libraries/System.IO.Compression/tests/ZipArchive/zip_InvalidParametersAndStrangeFiles.cs b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_InvalidParametersAndStrangeFiles.cs index 215d8f6249aa92..3d1439f75458c3 100644 --- a/src/libraries/System.IO.Compression/tests/ZipArchive/zip_InvalidParametersAndStrangeFiles.cs +++ b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_InvalidParametersAndStrangeFiles.cs @@ -195,7 +195,7 @@ public static async Task LargeArchive_DataDescriptor_Read_NonZip64_FileLengthGre Stream source = await OpenEntryStream(async, e); byte[] buffer = new byte[s_bufferSize]; int read = await source.ReadAsync(buffer, 0, buffer.Length); // We don't want to inflate this large archive entirely - // just making sure it read successfully + // just making sure it read successfully Assert.Equal(s_bufferSize, read); foreach (byte b in buffer) { @@ -564,7 +564,7 @@ public static async Task UpdateZipArchive_AddFileTo_ZipWithCorruptedFile(bool as byte[] buffer2 = new byte[1024]; file.Seek(0, SeekOrigin.Begin); - while (await s.ReadAsync(buffer1, 0, buffer1.Length) != 0 ) + while (await s.ReadAsync(buffer1, 0, buffer1.Length) != 0) { await file.ReadAsync(buffer2, 0, buffer2.Length); Assert.Equal(buffer1, buffer2); @@ -1418,7 +1418,7 @@ public async Task ZipArchive_InvalidExtraFieldData_Async(byte validVersionToExtr // for first.bin would normally be skipped (because it hasn't changed) but it needs to be rewritten // because the central directory headers will be rewritten with a valid value and the local file header // needs to match. - await using (ZipArchive updatedArchive = await ZipArchive.CreateAsync(updatedStream, ZipArchiveMode.Update, leaveOpen: true, entryNameEncoding: null)) + await using (ZipArchive updatedArchive = await ZipArchive.CreateAsync(updatedStream, ZipArchiveMode.Update, leaveOpen: true, entryNameEncoding: null)) { ZipArchiveEntry newEntry = updatedArchive.CreateEntry("second.bin", CompressionLevel.NoCompression); @@ -1659,6 +1659,39 @@ public static async Task NoSyncCallsWhenUsingAsync() } } + [Theory] + [MemberData(nameof(Get_Booleans_Data))] + public async Task ReadArchive_FrontTruncatedFile_Throws(bool async) + { + for (int i = 1; i < s_slightlyIncorrectZip64.Length - 1; i++) + { + await Assert.ThrowsAsync( + // The archive is truncated, so it should throw an exception + () => CreateZipArchive(async, new MemoryStream(s_slightlyIncorrectZip64, i, s_slightlyIncorrectZip64.Length - i), ZipArchiveMode.Read)); + } + } + + [Theory] + [MemberData(nameof(Get_Booleans_Data))] + public async Task ReadArchive_Zip64EocdLocatorInvalidOffset_Throws(bool async) + { + byte[] data = s_slightlyIncorrectZip64.ToArray(); + + foreach (long offset in new[] { -1, int.MaxValue - 1 }) + { + // Find Zip64 EOCD locator record + int eocdlOffset = data.AsSpan().LastIndexOf(new byte[] { 0x50, 0x4b, 0x06, 0x07 }); + Assert.True(eocdlOffset >= 0, "Zip64 EOCD locator not found in test data"); + + // skip 4B signature and 4B index of disk, then overwrite the 8B offset to start of central directory + BinaryPrimitives.WriteInt64LittleEndian(data.AsSpan(eocdlOffset + 8, 8), offset); + + await Assert.ThrowsAsync( + // The archive is truncated, so it should throw an exception + () => CreateZipArchive(async, new MemoryStream(data), ZipArchiveMode.Read)); + } + } + // Generates a copy of s_invalidExtraFieldData with a variable number of bytes as extra field data. private static byte[] GenerateInvalidExtraFieldData(byte modifiedVersionToExtract, ushort extraFieldDataLength, out int lhVersionToExtractOffset, diff --git a/src/libraries/System.IO.FileSystem.AccessControl/System.IO.FileSystem.AccessControl.slnx b/src/libraries/System.IO.FileSystem.AccessControl/System.IO.FileSystem.AccessControl.slnx index 7a373a78e0c1db..8f10cbb4cb986b 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/System.IO.FileSystem.AccessControl.slnx +++ b/src/libraries/System.IO.FileSystem.AccessControl/System.IO.FileSystem.AccessControl.slnx @@ -52,6 +52,22 @@ + + + + + + + + + + + + + + + + @@ -60,6 +76,22 @@ + + + + + + + + + + + + + + + + @@ -68,6 +100,14 @@ + + + + + + + + @@ -76,6 +116,14 @@ + + + + + + + + @@ -116,6 +164,22 @@ + + + + + + + + + + + + + + + + @@ -141,7 +205,39 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -157,6 +253,14 @@ + + + + + + + + @@ -165,6 +269,14 @@ + + + + + + + + @@ -173,6 +285,22 @@ + + + + + + + + + + + + + + + + @@ -181,6 +309,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -198,6 +350,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj b/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj index 03cbd816a2ff71..3df2d07dc15e4b 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj +++ b/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj @@ -93,13 +93,13 @@ - - - - - - - + + + + + + + diff --git a/src/libraries/System.IO.FileSystem.DriveInfo/System.IO.FileSystem.DriveInfo.slnx b/src/libraries/System.IO.FileSystem.DriveInfo/System.IO.FileSystem.DriveInfo.slnx index 10e58898bcc5aa..8dddff3734734d 100644 --- a/src/libraries/System.IO.FileSystem.DriveInfo/System.IO.FileSystem.DriveInfo.slnx +++ b/src/libraries/System.IO.FileSystem.DriveInfo/System.IO.FileSystem.DriveInfo.slnx @@ -1,31 +1,274 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.IO.FileSystem.DriveInfo/src/System.IO.FileSystem.DriveInfo.csproj b/src/libraries/System.IO.FileSystem.DriveInfo/src/System.IO.FileSystem.DriveInfo.csproj index 0b4edf9dd338dc..5767cefa830089 100644 --- a/src/libraries/System.IO.FileSystem.DriveInfo/src/System.IO.FileSystem.DriveInfo.csproj +++ b/src/libraries/System.IO.FileSystem.DriveInfo/src/System.IO.FileSystem.DriveInfo.csproj @@ -86,10 +86,10 @@ - - - - + + + + diff --git a/src/libraries/System.IO.FileSystem.Watcher/System.IO.FileSystem.Watcher.slnx b/src/libraries/System.IO.FileSystem.Watcher/System.IO.FileSystem.Watcher.slnx index 7479c081c52701..4e5425460e5276 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/System.IO.FileSystem.Watcher.slnx +++ b/src/libraries/System.IO.FileSystem.Watcher/System.IO.FileSystem.Watcher.slnx @@ -1,36 +1,386 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/System.IO.FileSystem.Watcher.csproj b/src/libraries/System.IO.FileSystem.Watcher/src/System.IO.FileSystem.Watcher.csproj index 8544de48d095d5..438efa515b3964 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/System.IO.FileSystem.Watcher.csproj +++ b/src/libraries/System.IO.FileSystem.Watcher/src/System.IO.FileSystem.Watcher.csproj @@ -120,19 +120,19 @@ - - - - - - - - + + + + + + + + - - + + diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/Args.FileSystemEventArgs.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/Args.FileSystemEventArgs.cs index 39e95c72c838ac..81cb55ce1dbc22 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/tests/Args.FileSystemEventArgs.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/tests/Args.FileSystemEventArgs.cs @@ -12,7 +12,7 @@ public class FileSystemEventArgsTests [InlineData(WatcherChangeTypes.All, "C:", "foo.txt")] [InlineData((WatcherChangeTypes)0, "", "")] [InlineData((WatcherChangeTypes)0, "", null)] - public static void FileSystemEventArgs_ctor_NonPathPropertiesAreSetCorrectly(WatcherChangeTypes changeType, string directory, string name) + public static void FileSystemEventArgs_ctor_NonPathPropertiesAreSetCorrectly(WatcherChangeTypes changeType, string directory, string? name) { FileSystemEventArgs args = new FileSystemEventArgs(changeType, directory, name); @@ -31,7 +31,7 @@ public static void FileSystemEventArgs_ctor_NonPathPropertiesAreSetCorrectly(Wat [InlineData("E:\\bar\\", null, "E:\\bar\\")] [InlineData("E:\\bar\\", "", "E:\\bar\\")] [InlineData("E:\\bar\\", "foo.txt", "E:\\bar\\foo.txt")] - public static void FileSystemEventArgs_ctor_DirectoryIsAbsolutePath_Windows(string directory, string name, string expectedFullPath) + public static void FileSystemEventArgs_ctor_DirectoryIsAbsolutePath_Windows(string directory, string? name, string expectedFullPath) { FileSystemEventArgs args = new FileSystemEventArgs(WatcherChangeTypes.All, directory, name); @@ -50,7 +50,7 @@ public static void FileSystemEventArgs_ctor_DirectoryIsAbsolutePath_Windows(stri [InlineData("/bar/", null, "/bar/")] [InlineData("/bar/", "", "/bar/")] [InlineData("/bar/", "foo.txt", "/bar/foo.txt")] - public static void FileSystemEventArgs_ctor_DirectoryIsAbsolutePath_Unix(string directory, string name, string expectedFullPath) + public static void FileSystemEventArgs_ctor_DirectoryIsAbsolutePath_Unix(string directory, string? name, string expectedFullPath) { FileSystemEventArgs args = new FileSystemEventArgs(WatcherChangeTypes.All, directory, name); @@ -89,7 +89,7 @@ public static void FileSystemEventArgs_ctor_DirectoryIsRelativePath_Unix(string [PlatformSpecific(TestPlatforms.Windows)] [InlineData("bar", "", "bar\\")] [InlineData("bar", null, "bar\\")] - public static void FileSystemEventArgs_ctor_EmptyFileName_Windows(string directory, string name, string expectedFullPath) + public static void FileSystemEventArgs_ctor_EmptyFileName_Windows(string directory, string? name, string expectedFullPath) { FileSystemEventArgs args = new FileSystemEventArgs(WatcherChangeTypes.All, directory, name); @@ -100,7 +100,7 @@ public static void FileSystemEventArgs_ctor_EmptyFileName_Windows(string directo [PlatformSpecific(TestPlatforms.AnyUnix)] [InlineData("bar", "", "bar/")] [InlineData("bar", null, "bar/")] - public static void FileSystemEventArgs_ctor_EmptyFileName_Unix(string directory, string name, string expectedFullPath) + public static void FileSystemEventArgs_ctor_EmptyFileName_Unix(string directory, string? name, string expectedFullPath) { FileSystemEventArgs args = new FileSystemEventArgs(WatcherChangeTypes.All, directory, name); diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/Args.RenamedEventArgs.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/Args.RenamedEventArgs.cs index d92324fc53291b..57fc85e9d1f586 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/tests/Args.RenamedEventArgs.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/tests/Args.RenamedEventArgs.cs @@ -12,7 +12,7 @@ public class RenamedEventArgsTests [InlineData(WatcherChangeTypes.All, "bar", "foo.txt", "bar.txt")] [InlineData((WatcherChangeTypes)0, "bar", "", "")] [InlineData((WatcherChangeTypes)0, "bar", null, null)] - public static void RenamedEventArgs_ctor_NonPathPropertiesAreSetCorrectly(WatcherChangeTypes changeType, string directory, string name, string oldName) + public static void RenamedEventArgs_ctor_NonPathPropertiesAreSetCorrectly(WatcherChangeTypes changeType, string directory, string? name, string? oldName) { RenamedEventArgs args = new RenamedEventArgs(changeType, directory, name, oldName); @@ -76,7 +76,7 @@ public static void RenamedEventArgs_ctor_OldFullPath_DirectoryIsRelativePath_Uni [InlineData("bar", "", "", "bar\\")] [InlineData("bar", null, null, "bar\\")] [InlineData("bar", "foo.txt", null, "bar\\")] - public static void RenamedEventArgs_ctor_EmptyOldFileName_Windows(string directory, string name, string oldName, string expectedOldFullPath) + public static void RenamedEventArgs_ctor_EmptyOldFileName_Windows(string directory, string? name, string? oldName, string expectedOldFullPath) { RenamedEventArgs args = new RenamedEventArgs(WatcherChangeTypes.All, directory, name, oldName); @@ -88,7 +88,7 @@ public static void RenamedEventArgs_ctor_EmptyOldFileName_Windows(string directo [InlineData("bar", "", "", "bar/")] [InlineData("bar", null, null, "bar/")] [InlineData("bar", "foo.txt", null, "bar/")] - public static void RenamedEventArgs_ctor_EmptyOldFileName_Unix(string directory, string name, string oldName, string expectedOldFullPath) + public static void RenamedEventArgs_ctor_EmptyOldFileName_Unix(string directory, string? name, string? oldName, string expectedOldFullPath) { RenamedEventArgs args = new RenamedEventArgs(WatcherChangeTypes.All, directory, name, oldName); diff --git a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.Vectorized.cs b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.Vectorized.cs index 2862e5b6b7e186..f263b6384acfc2 100644 --- a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.Vectorized.cs +++ b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.Vectorized.cs @@ -29,6 +29,10 @@ private static bool CanBeVectorized(ReadOnlySpan source) => // Computation for Generic Polynomials Using PCLMULQDQ Instruction" in December, 2009. // https://github.com/intel/isa-l/blob/33a2d9484595c2d6516c920ce39a694c144ddf69/crc/crc32_ieee_by4.asm // https://github.com/SixLabors/ImageSharp/blob/f4f689ce67ecbcc35cebddba5aacb603e6d1068a/src/ImageSharp/Formats/Png/Zlib/Crc32.cs#L80 + // + // Marking this as noinline so the JIT doesn't try and inline this and end up not inlining some of the calls it makes. + // + [MethodImpl(MethodImplOptions.NoInlining)] private static uint UpdateVectorized(uint crc, ReadOnlySpan source) { Debug.Assert(CanBeVectorized(source), "source cannot be vectorized."); diff --git a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc64.Vectorized.cs b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc64.Vectorized.cs index c2156bd473347a..98e5a6741bae59 100644 --- a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc64.Vectorized.cs +++ b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc64.Vectorized.cs @@ -43,6 +43,10 @@ private static Vector128 LoadFromSource(ref byte source, nuint elementOff // "Fast CRC Computation for Generic Polynomials Using PCLMULQDQ Instruction" in December, 2009 and the // Intel reference implementation. // https://github.com/intel/isa-l/blob/33a2d9484595c2d6516c920ce39a694c144ddf69/crc/crc64_ecma_norm_by8.asm + // + // Marking this as noinline so the JIT doesn't try and inline this and end up not inlining some of the calls it makes. + // + [MethodImpl(MethodImplOptions.NoInlining)] private static ulong UpdateVectorized(ulong crc, ReadOnlySpan source) { Debug.Assert(CanBeVectorized(source), "source cannot be vectorized."); diff --git a/src/libraries/System.IO.IsolatedStorage/System.IO.IsolatedStorage.slnx b/src/libraries/System.IO.IsolatedStorage/System.IO.IsolatedStorage.slnx index cfae5ca420b38c..8b9dca24207f6a 100644 --- a/src/libraries/System.IO.IsolatedStorage/System.IO.IsolatedStorage.slnx +++ b/src/libraries/System.IO.IsolatedStorage/System.IO.IsolatedStorage.slnx @@ -18,6 +18,14 @@ + + + + + + + + @@ -44,6 +52,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -52,6 +124,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -60,6 +196,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -68,6 +236,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -76,6 +268,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -101,7 +325,63 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -117,6 +397,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -125,6 +469,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -133,6 +509,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -141,6 +541,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -158,6 +590,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj b/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj index a11a0d7077cc65..169514e7c11026 100644 --- a/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj +++ b/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj @@ -44,14 +44,14 @@ - - - - - - - - + + + + + + + + diff --git a/src/libraries/System.IO.MemoryMappedFiles/System.IO.MemoryMappedFiles.slnx b/src/libraries/System.IO.MemoryMappedFiles/System.IO.MemoryMappedFiles.slnx index 778d00327a2ae9..d5727f97ffdf29 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/System.IO.MemoryMappedFiles.slnx +++ b/src/libraries/System.IO.MemoryMappedFiles/System.IO.MemoryMappedFiles.slnx @@ -1,34 +1,298 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.IO.MemoryMappedFiles/src/System.IO.MemoryMappedFiles.csproj b/src/libraries/System.IO.MemoryMappedFiles/src/System.IO.MemoryMappedFiles.csproj index 1710a652f6d6e3..8e01c1fab825bb 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/src/System.IO.MemoryMappedFiles.csproj +++ b/src/libraries/System.IO.MemoryMappedFiles/src/System.IO.MemoryMappedFiles.csproj @@ -128,11 +128,11 @@ - - - - - + + + + + diff --git a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateNew.Tests.cs b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateNew.Tests.cs index fa238061a2c8ff..7b7b15a0fe5c8d 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateNew.Tests.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateNew.Tests.cs @@ -142,7 +142,7 @@ public void MapNamesNotSupported_Unix(string mapName) [Theory] [MemberData(nameof(CreateValidMapNames))] [InlineData(null)] - public void ValidMapNames_Windows(string name) + public void ValidMapNames_Windows(string? name) { using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew(name, 4096)) { @@ -261,7 +261,7 @@ public static IEnumerable MemberData_ValidArgumentCombinations( [Theory] [MemberData(nameof(CreateValidMapNames))] [InlineData(null)] - public void DataNotPersistedBetweenMaps_Windows(string name) + public void DataNotPersistedBetweenMaps_Windows(string? name) { // Write some data to a map newly created with the specified name using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew(name, 4096)) diff --git a/src/libraries/System.IO.Packaging/ref/System.IO.Packaging.Serialization.cs b/src/libraries/System.IO.Packaging/ref/System.IO.Packaging.Serialization.cs index 58a03be2fa2f60..2d61730d20c73d 100644 --- a/src/libraries/System.IO.Packaging/ref/System.IO.Packaging.Serialization.cs +++ b/src/libraries/System.IO.Packaging/ref/System.IO.Packaging.Serialization.cs @@ -8,12 +8,12 @@ namespace System.IO { public partial class FileFormatException : System.FormatException { -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif protected FileFormatException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/FileFormatException.cs b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/FileFormatException.cs index 9946c94badff4d..426277a101add5 100644 --- a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/FileFormatException.cs +++ b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/FileFormatException.cs @@ -113,7 +113,7 @@ public FileFormatException(Uri? sourceUri, string? message, Exception? innerExce _sourceUri = sourceUri; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -129,7 +129,7 @@ protected FileFormatException(SerializationInfo info, StreamingContext context) /// /// The object that holds the serialized object data. /// The contextual information about the source or destination. -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.IO.Pipelines/System.IO.Pipelines.slnx b/src/libraries/System.IO.Pipelines/System.IO.Pipelines.slnx index c7d909e1a77bea..db01326ffc1788 100644 --- a/src/libraries/System.IO.Pipelines/System.IO.Pipelines.slnx +++ b/src/libraries/System.IO.Pipelines/System.IO.Pipelines.slnx @@ -1,31 +1,250 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.IO.Pipelines/src/System.IO.Pipelines.csproj b/src/libraries/System.IO.Pipelines/src/System.IO.Pipelines.csproj index 7c1901590e388c..9fa320f9440a16 100644 --- a/src/libraries/System.IO.Pipelines/src/System.IO.Pipelines.csproj +++ b/src/libraries/System.IO.Pipelines/src/System.IO.Pipelines.csproj @@ -66,11 +66,11 @@ System.IO.Pipelines.PipeReader - - - - - + + + + + diff --git a/src/libraries/System.IO.Pipelines/tests/PipeWriterTests.cs b/src/libraries/System.IO.Pipelines/tests/PipeWriterTests.cs index bc082b920cfb90..51f206ebf1cdcd 100644 --- a/src/libraries/System.IO.Pipelines/tests/PipeWriterTests.cs +++ b/src/libraries/System.IO.Pipelines/tests/PipeWriterTests.cs @@ -294,7 +294,6 @@ public async Task WritesUsingGetMemoryWorks() } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] public async Task CompleteWithLargeWriteThrows() { var completeDelay = TimeSpan.FromMilliseconds(10); @@ -361,19 +360,97 @@ public async Task GetMemoryFlushWithACompletedReaderNoops() Assert.Equal(0, Pipe.Writer.UnflushedBytes); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser), nameof(PlatformDetection.Is64BitProcess))] + [Fact] public void UnflushedBytes_HandlesLargeValues() { - PipeWriter writer = PipeWriter.Create(Stream.Null); int bufferSize = 10000; + using (SingleBufferMemoryPool pool = new(bufferSize)) + { + PipeWriter writer = PipeWriter.Create(Stream.Null, new StreamPipeWriterOptions(pool)); + + while (writer.UnflushedBytes >= 0 && writer.UnflushedBytes <= int.MaxValue) + { + writer.GetMemory(bufferSize); + writer.Advance(bufferSize); + } + + Assert.Equal(2147490000, writer.UnflushedBytes); + } + } + + internal class SingleBufferMemoryPool : MemoryPool + { + private readonly int _maxBufferSize; + private byte[] _buffer; + private bool _disposed; + + internal SingleBufferMemoryPool(int maxBufferSize) + { + _maxBufferSize = maxBufferSize; + _buffer = new byte[maxBufferSize]; + } + + public override int MaxBufferSize => _maxBufferSize; - while (writer.UnflushedBytes >= 0 && writer.UnflushedBytes <= int.MaxValue) + public override IMemoryOwner Rent(int minBufferSize = -1) { - writer.GetMemory(bufferSize); - writer.Advance(bufferSize); + if (minBufferSize > _maxBufferSize) + { + throw new ArgumentOutOfRangeException(nameof(minBufferSize), $"{nameof(minBufferSize)} should be less than {_maxBufferSize}"); + } + + return new BufferMemoryOwner(minBufferSize, _maxBufferSize, _buffer); } - Assert.Equal(2147490000, writer.UnflushedBytes); + protected override void Dispose(bool disposing) + { + if (!_disposed) + { + return; + } + + if (disposing) + { + _buffer = null; + } + + _disposed = true; + } + } + + internal class BufferMemoryOwner : MemoryManager + { + private int _minBufferSize; + private byte[] _buffer; + private bool _disposed; + + public BufferMemoryOwner(int minBufferSize, int maxBufferSize, byte[] buffer) + { + _minBufferSize = minBufferSize <= 0 ? maxBufferSize : minBufferSize; + _buffer = buffer; + } + + public override Span GetSpan() => new(_buffer, 0, _minBufferSize); + + public override Memory Memory => new(_buffer, 0, _minBufferSize); + + public override MemoryHandle Pin(int elementIndex = 0) => throw new NotImplementedException(); + public override void Unpin() => throw new NotImplementedException(); + + protected override void Dispose(bool disposing) + { + if (!_disposed) + { + return; + } + + if (disposing) + { + _buffer = null; + } + + _disposed = true; + } } } } diff --git a/src/libraries/System.IO.Pipelines/tests/StreamPipeReaderReadAtLeastAsyncTests.cs b/src/libraries/System.IO.Pipelines/tests/StreamPipeReaderReadAtLeastAsyncTests.cs index 887f2057aab4c2..d8211e544c7f54 100644 --- a/src/libraries/System.IO.Pipelines/tests/StreamPipeReaderReadAtLeastAsyncTests.cs +++ b/src/libraries/System.IO.Pipelines/tests/StreamPipeReaderReadAtLeastAsyncTests.cs @@ -18,8 +18,8 @@ protected override void SetPipeReaderOptions(MemoryPool? pool = null, int } private static Func CustomPoolFunc = () => new DisposeTrackingBufferPool(); - public static TheoryData?, int, bool, bool> TestData => - new TheoryData?, int, bool, bool> + public static TheoryData TestData => + new TheoryData { // pool, bufferSize, isSingleSegment, isFromCustomPool { default, 1, true, false }, diff --git a/src/libraries/System.IO.Pipes.AccessControl/System.IO.Pipes.AccessControl.slnx b/src/libraries/System.IO.Pipes.AccessControl/System.IO.Pipes.AccessControl.slnx index d2af834d4bb66a..035fd7260d0373 100644 --- a/src/libraries/System.IO.Pipes.AccessControl/System.IO.Pipes.AccessControl.slnx +++ b/src/libraries/System.IO.Pipes.AccessControl/System.IO.Pipes.AccessControl.slnx @@ -1,37 +1,562 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj b/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj index 6e48d964b2744e..aa947bc5ef42da 100644 --- a/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj +++ b/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj @@ -17,12 +17,11 @@ - - - - - + + + + + diff --git a/src/libraries/System.IO.Pipes/System.IO.Pipes.slnx b/src/libraries/System.IO.Pipes/System.IO.Pipes.slnx index b232b982db47fc..b32b3228c47473 100644 --- a/src/libraries/System.IO.Pipes/System.IO.Pipes.slnx +++ b/src/libraries/System.IO.Pipes/System.IO.Pipes.slnx @@ -52,6 +52,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -68,6 +92,22 @@ + + + + + + + + + + + + + + + + @@ -76,6 +116,14 @@ + + + + + + + + @@ -108,6 +156,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -116,6 +212,22 @@ + + + + + + + + + + + + + + + + @@ -132,6 +244,22 @@ + + + + + + + + + + + + + + + + @@ -148,6 +276,22 @@ + + + + + + + + + + + + + + + + @@ -156,6 +300,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -189,7 +365,31 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -205,6 +405,22 @@ + + + + + + + + + + + + + + + + @@ -221,6 +437,14 @@ + + + + + + + + @@ -253,6 +477,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -261,6 +533,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -269,6 +565,22 @@ + + + + + + + + + + + + + + + + @@ -285,6 +597,22 @@ + + + + + + + + + + + + + + + + @@ -293,6 +621,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -310,6 +670,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj b/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj index b36765a036839e..af23701a5adb30 100644 --- a/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj +++ b/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj @@ -174,26 +174,26 @@ - - - - - - - - + + + + + + + + - - - + + + - - - + + + diff --git a/src/libraries/System.IO.Ports/System.IO.Ports.slnx b/src/libraries/System.IO.Ports/System.IO.Ports.slnx index 6e71f023e5afb1..7ada1d5f80e056 100644 --- a/src/libraries/System.IO.Ports/System.IO.Ports.slnx +++ b/src/libraries/System.IO.Ports/System.IO.Ports.slnx @@ -1,50 +1,426 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs index e5a8618b814cfc..498d989adffa54 100644 --- a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs +++ b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs @@ -31,7 +31,6 @@ internal sealed partial class SerialStream : Stream private readonly byte[] _tempBuf = new byte[1]; private Task _ioLoop; private readonly object _ioLoopLock = new object(); - private bool _hasCancelledTasksToProcess; // Use a Queue with locking instead of ConcurrentQueue because ConcurrentQueue preserves segments for // observation when using TryPeek(). These segments will not clear out references after a dequeue // and as a result they hold on to SerialStreamIORequest instances so that they cannot be GC'ed. @@ -362,8 +361,8 @@ internal byte ParityReplace private bool HasCancelledTasksToProcess { - get => Volatile.Read(ref _hasCancelledTasksToProcess); - set => Volatile.Write(ref _hasCancelledTasksToProcess, value); + get => Volatile.Read(ref field); + set => Volatile.Write(ref field, value); } internal void DiscardInBuffer() diff --git a/src/libraries/System.Linq.AsyncEnumerable/System.Linq.AsyncEnumerable.slnx b/src/libraries/System.Linq.AsyncEnumerable/System.Linq.AsyncEnumerable.slnx index 38aa4ec5fcd0e8..3cbb875fd4ff37 100644 --- a/src/libraries/System.Linq.AsyncEnumerable/System.Linq.AsyncEnumerable.slnx +++ b/src/libraries/System.Linq.AsyncEnumerable/System.Linq.AsyncEnumerable.slnx @@ -1,37 +1,378 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Linq.AsyncEnumerable/ref/System.Linq.AsyncEnumerable.csproj b/src/libraries/System.Linq.AsyncEnumerable/ref/System.Linq.AsyncEnumerable.csproj index f50c80d4cee171..4803dab6d1d10b 100644 --- a/src/libraries/System.Linq.AsyncEnumerable/ref/System.Linq.AsyncEnumerable.csproj +++ b/src/libraries/System.Linq.AsyncEnumerable/ref/System.Linq.AsyncEnumerable.csproj @@ -11,15 +11,16 @@ + + + + + - - - - diff --git a/src/libraries/System.Linq.AsyncEnumerable/src/System.Linq.AsyncEnumerable.csproj b/src/libraries/System.Linq.AsyncEnumerable/src/System.Linq.AsyncEnumerable.csproj index 3efdb64019ab4e..a06669054ceb81 100644 --- a/src/libraries/System.Linq.AsyncEnumerable/src/System.Linq.AsyncEnumerable.csproj +++ b/src/libraries/System.Linq.AsyncEnumerable/src/System.Linq.AsyncEnumerable.csproj @@ -88,18 +88,18 @@ - - - - - - - - + + + + + + + + diff --git a/src/libraries/System.Linq.AsyncEnumerable/tests/SequenceTests.cs b/src/libraries/System.Linq.AsyncEnumerable/tests/SequenceTests.cs index 00ef5f25452ca8..7f7c1dcd05e82a 100644 --- a/src/libraries/System.Linq.AsyncEnumerable/tests/SequenceTests.cs +++ b/src/libraries/System.Linq.AsyncEnumerable/tests/SequenceTests.cs @@ -51,25 +51,28 @@ static void ValidateSigned() where T : INumber { ValidateUnsigned(); - for (int i = 1; i < 3; i++) - { - Assert.NotNull(AsyncEnumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(122), T.CreateTruncating(-i))); - } + // Test negative steps from 123 to 122 + // step=-1: should give [123, 122] (2 elements) + // step=-2: should give [123] (1 element, step too large) + Assert.Equal(2, AsyncEnumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(122), T.CreateTruncating(-1)).CountAsync().Result); + Assert.Single(AsyncEnumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(122), T.CreateTruncating(-2))); ValidateThrows(T.CreateTruncating(123), T.CreateTruncating(124), T.CreateTruncating(-2)); } static void ValidateUnsigned() where T : INumber { + // When start == end, all steps should return single element [123] for (int i = 0; i < 3; i++) { - Assert.NotNull(AsyncEnumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(123), T.CreateTruncating(i))); + Assert.Single(AsyncEnumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(123), T.CreateTruncating(i))); } - for (int i = 1; i < 3; i++) - { - Assert.NotNull(AsyncEnumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(124), T.CreateTruncating(i))); - } + // Test positive steps from 123 to 124 + // step=1: should give [123, 124] (2 elements) + // step=2: should give [123] (1 element, step too large) + Assert.Equal(2, AsyncEnumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(124), T.CreateTruncating(1)).CountAsync().Result); + Assert.Single(AsyncEnumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(124), T.CreateTruncating(2))); ValidateThrows(T.CreateTruncating(123), T.CreateTruncating(122), T.CreateTruncating(2)); } diff --git a/src/libraries/System.Linq.Expressions/System.Linq.Expressions.slnx b/src/libraries/System.Linq.Expressions/System.Linq.Expressions.slnx index fa24bd6fe63936..d8f9e781a0506c 100644 --- a/src/libraries/System.Linq.Expressions/System.Linq.Expressions.slnx +++ b/src/libraries/System.Linq.Expressions/System.Linq.Expressions.slnx @@ -1,31 +1,506 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj b/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj index d06dd2cabb1b9e..3a26aaa9d4aa3d 100644 --- a/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj +++ b/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj @@ -213,16 +213,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Common/CachedReflectionInfo.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Common/CachedReflectionInfo.cs index 76f8ba91925510..c5bf8dd8d25604 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Common/CachedReflectionInfo.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Common/CachedReflectionInfo.cs @@ -9,158 +9,45 @@ namespace System.Linq.Expressions { internal static partial class CachedReflectionInfo { - private static ConstructorInfo? s_Nullable_Boolean_Ctor; - - public static ConstructorInfo Nullable_Boolean_Ctor - => s_Nullable_Boolean_Ctor ??= typeof(bool?).GetConstructor(new[] { typeof(bool) })!; - - private static ConstructorInfo? s_Decimal_Ctor_Int32; - public static ConstructorInfo Decimal_Ctor_Int32 => - s_Decimal_Ctor_Int32 ??= typeof(decimal).GetConstructor(new[] { typeof(int) })!; - - private static ConstructorInfo? s_Decimal_Ctor_UInt32; - public static ConstructorInfo Decimal_Ctor_UInt32 => - s_Decimal_Ctor_UInt32 ??= typeof(decimal).GetConstructor(new[] { typeof(uint) })!; - - private static ConstructorInfo? s_Decimal_Ctor_Int64; - public static ConstructorInfo Decimal_Ctor_Int64 => - s_Decimal_Ctor_Int64 ??= typeof(decimal).GetConstructor(new[] { typeof(long) })!; - - private static ConstructorInfo? s_Decimal_Ctor_UInt64; - public static ConstructorInfo Decimal_Ctor_UInt64 => - s_Decimal_Ctor_UInt64 ??= typeof(decimal).GetConstructor(new[] { typeof(ulong) })!; - - private static ConstructorInfo? s_Decimal_Ctor_Int32_Int32_Int32_Bool_Byte; - public static ConstructorInfo Decimal_Ctor_Int32_Int32_Int32_Bool_Byte => - s_Decimal_Ctor_Int32_Int32_Int32_Bool_Byte ??= typeof(decimal).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(bool), typeof(byte) })!; - - private static FieldInfo? s_Decimal_One; - public static FieldInfo Decimal_One => - s_Decimal_One ??= typeof(decimal).GetField(nameof(decimal.One))!; - - private static FieldInfo? s_Decimal_MinusOne; - public static FieldInfo Decimal_MinusOne => - s_Decimal_MinusOne ??= typeof(decimal).GetField(nameof(decimal.MinusOne))!; - - private static FieldInfo? s_Decimal_MinValue; - public static FieldInfo Decimal_MinValue => - s_Decimal_MinValue ??= typeof(decimal).GetField(nameof(decimal.MinValue))!; - - private static FieldInfo? s_Decimal_MaxValue; - public static FieldInfo Decimal_MaxValue => - s_Decimal_MaxValue ??= typeof(decimal).GetField(nameof(decimal.MaxValue))!; - - private static FieldInfo? s_Decimal_Zero; - public static FieldInfo Decimal_Zero => - s_Decimal_Zero ??= typeof(decimal).GetField(nameof(decimal.Zero))!; - - private static FieldInfo? s_DateTime_MinValue; - public static FieldInfo DateTime_MinValue => - s_DateTime_MinValue ??= typeof(DateTime).GetField(nameof(DateTime.MinValue))!; - - private static MethodInfo? s_MethodBase_GetMethodFromHandle_RuntimeMethodHandle; - public static MethodInfo MethodBase_GetMethodFromHandle_RuntimeMethodHandle => - s_MethodBase_GetMethodFromHandle_RuntimeMethodHandle ??= typeof(MethodBase).GetMethod(nameof(MethodBase.GetMethodFromHandle), new[] { typeof(RuntimeMethodHandle) })!; - - private static MethodInfo? s_MethodBase_GetMethodFromHandle_RuntimeMethodHandle_RuntimeTypeHandle; - public static MethodInfo MethodBase_GetMethodFromHandle_RuntimeMethodHandle_RuntimeTypeHandle => - s_MethodBase_GetMethodFromHandle_RuntimeMethodHandle_RuntimeTypeHandle ??= typeof(MethodBase).GetMethod(nameof(MethodBase.GetMethodFromHandle), new[] { typeof(RuntimeMethodHandle), typeof(RuntimeTypeHandle) })!; - - private static MethodInfo? s_MethodInfo_CreateDelegate_Type_Object; - public static MethodInfo MethodInfo_CreateDelegate_Type_Object => - s_MethodInfo_CreateDelegate_Type_Object ??= typeof(MethodInfo).GetMethod(nameof(MethodInfo.CreateDelegate), new[] { typeof(Type), typeof(object) })!; - - private static MethodInfo? s_String_op_Equality_String_String; - public static MethodInfo String_op_Equality_String_String => - s_String_op_Equality_String_String ??= typeof(string).GetMethod("op_Equality", new[] { typeof(string), typeof(string) })!; - - private static MethodInfo? s_String_Equals_String_String; - public static MethodInfo String_Equals_String_String => - s_String_Equals_String_String ??= typeof(string).GetMethod("Equals", new[] { typeof(string), typeof(string) })!; - - private static MethodInfo? s_DictionaryOfStringInt32_Add_String_Int32; - public static MethodInfo DictionaryOfStringInt32_Add_String_Int32 => - s_DictionaryOfStringInt32_Add_String_Int32 ??= typeof(Dictionary).GetMethod(nameof(Dictionary.Add), new[] { typeof(string), typeof(int) })!; - - private static ConstructorInfo? s_DictionaryOfStringInt32_Ctor_Int32; - public static ConstructorInfo DictionaryOfStringInt32_Ctor_Int32 => - s_DictionaryOfStringInt32_Ctor_Int32 ??= typeof(Dictionary).GetConstructor(new[] { typeof(int) })!; - - private static MethodInfo? s_Type_GetTypeFromHandle; - public static MethodInfo Type_GetTypeFromHandle => - s_Type_GetTypeFromHandle ??= typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle))!; - - private static MethodInfo? s_Object_GetType; - public static MethodInfo Object_GetType => - s_Object_GetType ??= typeof(object).GetMethod(nameof(object.GetType))!; - - private static MethodInfo? s_Decimal_op_Implicit_Byte; - public static MethodInfo Decimal_op_Implicit_Byte => - s_Decimal_op_Implicit_Byte ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(byte) })!; - - private static MethodInfo? s_Decimal_op_Implicit_SByte; - public static MethodInfo Decimal_op_Implicit_SByte => - s_Decimal_op_Implicit_SByte ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(sbyte) })!; - - private static MethodInfo? s_Decimal_op_Implicit_Int16; - public static MethodInfo Decimal_op_Implicit_Int16 => - s_Decimal_op_Implicit_Int16 ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(short) })!; - - private static MethodInfo? s_Decimal_op_Implicit_UInt16; - public static MethodInfo Decimal_op_Implicit_UInt16 => - s_Decimal_op_Implicit_UInt16 ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(ushort) })!; - - private static MethodInfo? s_Decimal_op_Implicit_Int32; - public static MethodInfo Decimal_op_Implicit_Int32 => - s_Decimal_op_Implicit_Int32 ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(int) })!; - - private static MethodInfo? s_Decimal_op_Implicit_UInt32; - public static MethodInfo Decimal_op_Implicit_UInt32 => - s_Decimal_op_Implicit_UInt32 ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(uint) })!; - - private static MethodInfo? s_Decimal_op_Implicit_Int64; - public static MethodInfo Decimal_op_Implicit_Int64 => - s_Decimal_op_Implicit_Int64 ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(long) })!; - - private static MethodInfo? s_Decimal_op_Implicit_UInt64; - public static MethodInfo Decimal_op_Implicit_UInt64 => - s_Decimal_op_Implicit_UInt64 ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(ulong) })!; - - private static MethodInfo? s_Decimal_op_Implicit_Char; - public static MethodInfo Decimal_op_Implicit_Char => - s_Decimal_op_Implicit_Char ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(char) })!; - - private static MethodInfo? s_Math_Pow_Double_Double; - public static MethodInfo Math_Pow_Double_Double => - s_Math_Pow_Double_Double ??= typeof(Math).GetMethod(nameof(Math.Pow), new[] { typeof(double), typeof(double) })!; + public static ConstructorInfo Nullable_Boolean_Ctor => field ??= typeof(bool?).GetConstructor(new[] { typeof(bool) })!; + public static ConstructorInfo Decimal_Ctor_Int32 => field ??= typeof(decimal).GetConstructor(new[] { typeof(int) })!; + public static ConstructorInfo Decimal_Ctor_UInt32 => field ??= typeof(decimal).GetConstructor(new[] { typeof(uint) })!; + public static ConstructorInfo Decimal_Ctor_Int64 => field ??= typeof(decimal).GetConstructor(new[] { typeof(long) })!; + public static ConstructorInfo Decimal_Ctor_UInt64 => field ??= typeof(decimal).GetConstructor(new[] { typeof(ulong) })!; + public static ConstructorInfo Decimal_Ctor_Int32_Int32_Int32_Bool_Byte => field ??= typeof(decimal).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(bool), typeof(byte) })!; + public static FieldInfo Decimal_One => field ??= typeof(decimal).GetField(nameof(decimal.One))!; + public static FieldInfo Decimal_MinusOne => field ??= typeof(decimal).GetField(nameof(decimal.MinusOne))!; + public static FieldInfo Decimal_MinValue => field ??= typeof(decimal).GetField(nameof(decimal.MinValue))!; + public static FieldInfo Decimal_MaxValue => field ??= typeof(decimal).GetField(nameof(decimal.MaxValue))!; + public static FieldInfo Decimal_Zero => field ??= typeof(decimal).GetField(nameof(decimal.Zero))!; + public static FieldInfo DateTime_MinValue => field ??= typeof(DateTime).GetField(nameof(DateTime.MinValue))!; + public static MethodInfo MethodBase_GetMethodFromHandle_RuntimeMethodHandle => field ??= typeof(MethodBase).GetMethod(nameof(MethodBase.GetMethodFromHandle), new[] { typeof(RuntimeMethodHandle) })!; + public static MethodInfo MethodBase_GetMethodFromHandle_RuntimeMethodHandle_RuntimeTypeHandle => field ??= typeof(MethodBase).GetMethod(nameof(MethodBase.GetMethodFromHandle), new[] { typeof(RuntimeMethodHandle), typeof(RuntimeTypeHandle) })!; + public static MethodInfo MethodInfo_CreateDelegate_Type_Object => field ??= typeof(MethodInfo).GetMethod(nameof(MethodInfo.CreateDelegate), new[] { typeof(Type), typeof(object) })!; + public static MethodInfo String_op_Equality_String_String => field ??= typeof(string).GetMethod("op_Equality", new[] { typeof(string), typeof(string) })!; + public static MethodInfo String_Equals_String_String => field ??= typeof(string).GetMethod("Equals", new[] { typeof(string), typeof(string) })!; + public static MethodInfo DictionaryOfStringInt32_Add_String_Int32 => field ??= typeof(Dictionary).GetMethod(nameof(Dictionary.Add), new[] { typeof(string), typeof(int) })!; + public static ConstructorInfo DictionaryOfStringInt32_Ctor_Int32 => field ??= typeof(Dictionary).GetConstructor(new[] { typeof(int) })!; + public static MethodInfo Type_GetTypeFromHandle => field ??= typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle))!; + public static MethodInfo Object_GetType => field ??= typeof(object).GetMethod(nameof(object.GetType))!; + public static MethodInfo Decimal_op_Implicit_Byte => field ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(byte) })!; + public static MethodInfo Decimal_op_Implicit_SByte => field ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(sbyte) })!; + public static MethodInfo Decimal_op_Implicit_Int16 => field ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(short) })!; + public static MethodInfo Decimal_op_Implicit_UInt16 => field ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(ushort) })!; + public static MethodInfo Decimal_op_Implicit_Int32 => field ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(int) })!; + public static MethodInfo Decimal_op_Implicit_UInt32 => field ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(uint) })!; + public static MethodInfo Decimal_op_Implicit_Int64 => field ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(long) })!; + public static MethodInfo Decimal_op_Implicit_UInt64 => field ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(ulong) })!; + public static MethodInfo Decimal_op_Implicit_Char => field ??= typeof(decimal).GetMethod("op_Implicit", new[] { typeof(char) })!; + public static MethodInfo Math_Pow_Double_Double => field ??= typeof(Math).GetMethod(nameof(Math.Pow), new[] { typeof(double), typeof(double) })!; // Closure and RuntimeOps helpers are used only in the compiler. - private static ConstructorInfo? s_Closure_ObjectArray_ObjectArray; - public static ConstructorInfo Closure_ObjectArray_ObjectArray => - s_Closure_ObjectArray_ObjectArray ??= typeof(Closure).GetConstructor(new[] { typeof(object[]), typeof(object[]) })!; - - private static FieldInfo? s_Closure_Constants; - public static FieldInfo Closure_Constants => - s_Closure_Constants ??= typeof(Closure).GetField(nameof(Closure.Constants))!; - - private static FieldInfo? s_Closure_Locals; - public static FieldInfo Closure_Locals => - s_Closure_Locals ??= typeof(Closure).GetField(nameof(Closure.Locals))!; - - private static MethodInfo? s_RuntimeOps_CreateRuntimeVariables_ObjectArray_Int64Array; - public static MethodInfo RuntimeOps_CreateRuntimeVariables_ObjectArray_Int64Array => - s_RuntimeOps_CreateRuntimeVariables_ObjectArray_Int64Array ??= typeof(RuntimeOps).GetMethod(nameof(RuntimeOps.CreateRuntimeVariables), new[] { typeof(object[]), typeof(long[]) })!; - - private static MethodInfo? s_RuntimeOps_CreateRuntimeVariables; - public static MethodInfo RuntimeOps_CreateRuntimeVariables => - s_RuntimeOps_CreateRuntimeVariables ??= typeof(RuntimeOps).GetMethod(nameof(RuntimeOps.CreateRuntimeVariables), Type.EmptyTypes)!; - - private static MethodInfo? s_RuntimeOps_MergeRuntimeVariables; - public static MethodInfo RuntimeOps_MergeRuntimeVariables => - s_RuntimeOps_MergeRuntimeVariables ??= typeof(RuntimeOps).GetMethod(nameof(RuntimeOps.MergeRuntimeVariables))!; - - private static MethodInfo? s_RuntimeOps_Quote; - public static MethodInfo RuntimeOps_Quote => - s_RuntimeOps_Quote ??= typeof(RuntimeOps).GetMethod(nameof(RuntimeOps.Quote))!; + public static ConstructorInfo Closure_ObjectArray_ObjectArray => field ??= typeof(Closure).GetConstructor(new[] { typeof(object[]), typeof(object[]) })!; + public static FieldInfo Closure_Constants => field ??= typeof(Closure).GetField(nameof(Closure.Constants))!; + public static FieldInfo Closure_Locals => field ??= typeof(Closure).GetField(nameof(Closure.Locals))!; + public static MethodInfo RuntimeOps_CreateRuntimeVariables_ObjectArray_Int64Array => field ??= typeof(RuntimeOps).GetMethod(nameof(RuntimeOps.CreateRuntimeVariables), new[] { typeof(object[]), typeof(long[]) })!; + public static MethodInfo RuntimeOps_CreateRuntimeVariables => field ??= typeof(RuntimeOps).GetMethod(nameof(RuntimeOps.CreateRuntimeVariables), Type.EmptyTypes)!; + public static MethodInfo RuntimeOps_MergeRuntimeVariables => field ??= typeof(RuntimeOps).GetMethod(nameof(RuntimeOps.MergeRuntimeVariables))!; + public static MethodInfo RuntimeOps_Quote => field ??= typeof(RuntimeOps).GetMethod(nameof(RuntimeOps.Quote))!; } } diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/ControlFlowInstructions.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/ControlFlowInstructions.cs index 2f4d6e40c7b1cf..ccefd14a9a2e9f 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/ControlFlowInstructions.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/ControlFlowInstructions.cs @@ -47,9 +47,7 @@ public override string ToString() internal sealed class BranchFalseInstruction : OffsetInstruction { - private static Instruction[]? s_cache; - - public override Instruction[] Cache => s_cache ??= new Instruction[CacheSize]; + public override Instruction[] Cache => field ??= new Instruction[CacheSize]; public override string InstructionName => "BranchFalse"; public override int ConsumedStack => 1; @@ -69,9 +67,7 @@ public override int Run(InterpretedFrame frame) internal sealed class BranchTrueInstruction : OffsetInstruction { - private static Instruction[]? s_cache; - - public override Instruction[] Cache => s_cache ??= new Instruction[CacheSize]; + public override Instruction[] Cache => field ??= new Instruction[CacheSize]; public override string InstructionName => "BranchTrue"; public override int ConsumedStack => 1; @@ -91,9 +87,7 @@ public override int Run(InterpretedFrame frame) internal sealed class CoalescingBranchInstruction : OffsetInstruction { - private static Instruction[]? s_cache; - - public override Instruction[] Cache => s_cache ??= new Instruction[CacheSize]; + public override Instruction[] Cache => field ??= new Instruction[CacheSize]; public override string InstructionName => "CoalescingBranch"; public override int ConsumedStack => 1; diff --git a/src/libraries/System.Linq.Expressions/src/System/Runtime/CompilerServices/CallSiteBinder.cs b/src/libraries/System.Linq.Expressions/src/System/Runtime/CompilerServices/CallSiteBinder.cs index 41df675b6aaf94..a68b7f24cb90dc 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Runtime/CompilerServices/CallSiteBinder.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Runtime/CompilerServices/CallSiteBinder.cs @@ -40,9 +40,7 @@ protected CallSiteBinder() private sealed class LambdaSignature where T : class { - private static LambdaSignature? s_instance; - - internal static LambdaSignature Instance => s_instance ??= new LambdaSignature(); + internal static LambdaSignature Instance => field ??= new LambdaSignature(); internal readonly ReadOnlyCollection Parameters; internal readonly LabelTarget ReturnLabel; diff --git a/src/libraries/System.Linq.Expressions/tests/BinaryOperators/Assignment/Assign.cs b/src/libraries/System.Linq.Expressions/tests/BinaryOperators/Assignment/Assign.cs index 17dd7c7b340f0b..dfa0f5a7086046 100644 --- a/src/libraries/System.Linq.Expressions/tests/BinaryOperators/Assignment/Assign.cs +++ b/src/libraries/System.Linq.Expressions/tests/BinaryOperators/Assignment/Assign.cs @@ -231,7 +231,7 @@ public void RightNull_ThrowsArgumentNullException() [InlineData(typeof(SubClass), null, typeof(BaseClass))] [InlineData(typeof(int), null, typeof(BaseClass))] [InlineData(typeof(BaseClass), 1, typeof(int))] - public void MismatchTypes(Type variableType, object constantValue, Type constantType) + public void MismatchTypes(Type variableType, object? constantValue, Type constantType) { AssertExtensions.Throws(null, () => Expression.Assign(Expression.Variable(variableType), Expression.Constant(constantValue, constantType))); } diff --git a/src/libraries/System.Linq.Expressions/tests/ILReader/ILInstruction.cs b/src/libraries/System.Linq.Expressions/tests/ILReader/ILInstruction.cs index 5e65aa288dcb20..a80a7c0d3a9961 100644 --- a/src/libraries/System.Linq.Expressions/tests/ILReader/ILInstruction.cs +++ b/src/libraries/System.Linq.Expressions/tests/ILReader/ILInstruction.cs @@ -158,7 +158,6 @@ internal ShortInlineRInstruction(int offset, OpCode opCode, float value) public sealed class InlineFieldInstruction : ILInstruction { private readonly ITokenResolver _resolver; - private FieldInfo _field; internal InlineFieldInstruction(ITokenResolver resolver, int offset, OpCode opCode, int token) : base(offset, opCode) @@ -167,7 +166,7 @@ internal InlineFieldInstruction(ITokenResolver resolver, int offset, OpCode opCo Token = token; } - public FieldInfo Field => _field ??= _resolver.AsField(Token); + public FieldInfo Field => field ??= _resolver.AsField(Token); public int Token { get; } public override void Accept(ILInstructionVisitor visitor) => visitor.VisitInlineFieldInstruction(this); @@ -176,7 +175,6 @@ internal InlineFieldInstruction(ITokenResolver resolver, int offset, OpCode opCo public sealed class InlineMethodInstruction : ILInstruction { private readonly ITokenResolver _resolver; - private MethodBase _method; internal InlineMethodInstruction(int offset, OpCode opCode, int token, ITokenResolver resolver) : base(offset, opCode) @@ -185,7 +183,7 @@ internal InlineMethodInstruction(int offset, OpCode opCode, int token, ITokenRes Token = token; } - public MethodBase Method => _method ??= _resolver.AsMethod(Token); + public MethodBase Method => field ??= _resolver.AsMethod(Token); public int Token { get; } public override void Accept(ILInstructionVisitor visitor) => visitor.VisitInlineMethodInstruction(this); @@ -194,7 +192,6 @@ internal InlineMethodInstruction(int offset, OpCode opCode, int token, ITokenRes public sealed class InlineTypeInstruction : ILInstruction { private readonly ITokenResolver _resolver; - private Type _type; internal InlineTypeInstruction(int offset, OpCode opCode, int token, ITokenResolver resolver) : base(offset, opCode) @@ -203,7 +200,7 @@ internal InlineTypeInstruction(int offset, OpCode opCode, int token, ITokenResol Token = token; } - public Type Type => _type ??= _resolver.AsType(Token); + public Type Type => field ??= _resolver.AsType(Token); public int Token { get; } public override void Accept(ILInstructionVisitor visitor) => visitor.VisitInlineTypeInstruction(this); @@ -212,7 +209,6 @@ internal InlineTypeInstruction(int offset, OpCode opCode, int token, ITokenResol public sealed class InlineSigInstruction : ILInstruction { private readonly ITokenResolver _resolver; - private byte[] _signature; internal InlineSigInstruction(int offset, OpCode opCode, int token, ITokenResolver resolver) : base(offset, opCode) @@ -221,7 +217,7 @@ internal InlineSigInstruction(int offset, OpCode opCode, int token, ITokenResolv Token = token; } - public byte[] Signature => _signature ??= _resolver.AsSignature(Token); + public byte[] Signature => field ??= _resolver.AsSignature(Token); public int Token { get; } public override void Accept(ILInstructionVisitor visitor) => visitor.VisitInlineSigInstruction(this); @@ -230,7 +226,6 @@ internal InlineSigInstruction(int offset, OpCode opCode, int token, ITokenResolv public sealed class InlineTokInstruction : ILInstruction { private readonly ITokenResolver _resolver; - private MemberInfo _member; internal InlineTokInstruction(int offset, OpCode opCode, int token, ITokenResolver resolver) : base(offset, opCode) @@ -239,7 +234,7 @@ internal InlineTokInstruction(int offset, OpCode opCode, int token, ITokenResolv Token = token; } - public MemberInfo Member => _member ??= _resolver.AsMember(Token); + public MemberInfo Member => field ??= _resolver.AsMember(Token); public int Token { get; } public override void Accept(ILInstructionVisitor visitor) => visitor.VisitInlineTokInstruction(this); @@ -248,7 +243,6 @@ internal InlineTokInstruction(int offset, OpCode opCode, int token, ITokenResolv public sealed class InlineStringInstruction : ILInstruction { private readonly ITokenResolver _resolver; - private string _string; internal InlineStringInstruction(int offset, OpCode opCode, int token, ITokenResolver resolver) : base(offset, opCode) @@ -257,7 +251,7 @@ internal InlineStringInstruction(int offset, OpCode opCode, int token, ITokenRes Token = token; } - public string String => _string ??= _resolver.AsString(Token); + public string String => field ??= _resolver.AsString(Token); public int Token { get; } public override void Accept(ILInstructionVisitor visitor) => visitor.VisitInlineStringInstruction(this); diff --git a/src/libraries/System.Linq.Expressions/tests/default.rd.xml b/src/libraries/System.Linq.Expressions/tests/default.rd.xml index b3f7ab6dd93cde..c531aed03ffc4c 100644 --- a/src/libraries/System.Linq.Expressions/tests/default.rd.xml +++ b/src/libraries/System.Linq.Expressions/tests/default.rd.xml @@ -13,6 +13,8 @@ + + diff --git a/src/libraries/System.Linq.Parallel/System.Linq.Parallel.slnx b/src/libraries/System.Linq.Parallel/System.Linq.Parallel.slnx index 6a9b53667d7a94..9b22915d042110 100644 --- a/src/libraries/System.Linq.Parallel/System.Linq.Parallel.slnx +++ b/src/libraries/System.Linq.Parallel/System.Linq.Parallel.slnx @@ -1,32 +1,322 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Linq.Parallel/src/System.Linq.Parallel.csproj b/src/libraries/System.Linq.Parallel/src/System.Linq.Parallel.csproj index 15ff9887505a59..173fae9740b234 100644 --- a/src/libraries/System.Linq.Parallel/src/System.Linq.Parallel.csproj +++ b/src/libraries/System.Linq.Parallel/src/System.Linq.Parallel.csproj @@ -6,11 +6,13 @@ true false + $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) true $(DefineConstants);FEATURE_WASM_MANAGED_THREADS + @@ -153,13 +155,13 @@ - - - - - - - + + + + + + + diff --git a/src/libraries/System.Linq.Queryable/System.Linq.Queryable.slnx b/src/libraries/System.Linq.Queryable/System.Linq.Queryable.slnx index df1f239e0f0ee4..bebd879b5cf228 100644 --- a/src/libraries/System.Linq.Queryable/System.Linq.Queryable.slnx +++ b/src/libraries/System.Linq.Queryable/System.Linq.Queryable.slnx @@ -1,33 +1,522 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Linq.Queryable/src/System.Linq.Queryable.csproj b/src/libraries/System.Linq.Queryable/src/System.Linq.Queryable.csproj index 4023cdc363dae1..81a729021bfafe 100644 --- a/src/libraries/System.Linq.Queryable/src/System.Linq.Queryable.csproj +++ b/src/libraries/System.Linq.Queryable/src/System.Linq.Queryable.csproj @@ -16,11 +16,11 @@ - - - - - + + + + + diff --git a/src/libraries/System.Linq/System.Linq.slnx b/src/libraries/System.Linq/System.Linq.slnx index c8162ab025ff58..40fae272387972 100644 --- a/src/libraries/System.Linq/System.Linq.slnx +++ b/src/libraries/System.Linq/System.Linq.slnx @@ -1,32 +1,306 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Linq/src/System.Linq.csproj b/src/libraries/System.Linq/src/System.Linq.csproj index abac65e6d7b26d..f032db1a303ee1 100644 --- a/src/libraries/System.Linq/src/System.Linq.csproj +++ b/src/libraries/System.Linq/src/System.Linq.csproj @@ -62,6 +62,7 @@ + @@ -70,12 +71,10 @@ - - @@ -83,17 +82,18 @@ + - - - - - - + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Linq/src/System/Linq/Count.cs b/src/libraries/System.Linq/src/System/Linq/Count.cs index 6a12a11cbe163d..cd175cf6b9b3cc 100644 --- a/src/libraries/System.Linq/src/System/Linq/Count.cs +++ b/src/libraries/System.Linq/src/System/Linq/Count.cs @@ -20,7 +20,7 @@ public static int Count(this IEnumerable source) return collectionoft.Count; } - if (!IsSizeOptimized && source is Iterator iterator) + if (source is Iterator iterator) { return iterator.GetCount(onlyIfCheap: false); } @@ -113,7 +113,7 @@ public static bool TryGetNonEnumeratedCount(this IEnumerable s return true; } - if (!IsSizeOptimized && source is Iterator iterator) + if (source is Iterator iterator) { int c = iterator.GetCount(onlyIfCheap: true); if (c >= 0) diff --git a/src/libraries/System.Linq/src/System/Linq/DebugView.cs b/src/libraries/System.Linq/src/System/Linq/DebugView.cs index ddfb49cc3e2f9c..3cc23a1a542aaa 100644 --- a/src/libraries/System.Linq/src/System/Linq/DebugView.cs +++ b/src/libraries/System.Linq/src/System/Linq/DebugView.cs @@ -94,7 +94,6 @@ public object?[] Items internal sealed class SystemLinq_GroupingDebugView { private readonly Grouping _grouping; - private TElement[]? _cachedValues; public SystemLinq_GroupingDebugView(Grouping grouping) { @@ -105,13 +104,12 @@ public SystemLinq_GroupingDebugView(Grouping grouping) // The name of this property must alphabetically follow `Key` so the elements appear last in the display. [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] - public TElement[] Values => _cachedValues ??= _grouping.ToArray(); + public TElement[] Values => field ??= _grouping.ToArray(); } internal sealed class SystemLinq_LookupDebugView { private readonly ILookup _lookup; - private IGrouping[]? _cachedGroupings; public SystemLinq_LookupDebugView(ILookup lookup) { @@ -119,6 +117,6 @@ public SystemLinq_LookupDebugView(ILookup lookup) } [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] - public IGrouping[] Groupings => _cachedGroupings ??= _lookup.ToArray(); + public IGrouping[] Groupings => field ??= _lookup.ToArray(); } } diff --git a/src/libraries/System.Linq/src/System/Linq/ElementAt.cs b/src/libraries/System.Linq/src/System/Linq/ElementAt.cs index 26c69366fa9f3b..f4dc1f23a16c80 100644 --- a/src/libraries/System.Linq/src/System/Linq/ElementAt.cs +++ b/src/libraries/System.Linq/src/System/Linq/ElementAt.cs @@ -23,7 +23,7 @@ public static TSource ElementAt(this IEnumerable source, int i bool found; TSource? element = - !IsSizeOptimized && source is Iterator iterator ? iterator.TryGetElementAt(index, out found) : + source is Iterator iterator ? iterator.TryGetElementAt(index, out found) : TryGetElementAtNonIterator(source, index, out found); if (!found) @@ -121,7 +121,7 @@ public static TSource ElementAt(this IEnumerable source, Index } return - !IsSizeOptimized && source is Iterator iterator ? iterator.TryGetElementAt(index, out found) : + source is Iterator iterator ? iterator.TryGetElementAt(index, out found) : TryGetElementAtNonIterator(source, index, out found); } diff --git a/src/libraries/System.Linq/src/System/Linq/Last.cs b/src/libraries/System.Linq/src/System/Linq/Last.cs index ca48475259d8e5..c38604e397592f 100644 --- a/src/libraries/System.Linq/src/System/Linq/Last.cs +++ b/src/libraries/System.Linq/src/System/Linq/Last.cs @@ -69,7 +69,7 @@ public static TSource LastOrDefault(this IEnumerable source, F } return - !IsSizeOptimized && source is Iterator iterator ? iterator.TryGetLast(out found) : + source is Iterator iterator ? iterator.TryGetLast(out found) : TryGetLastNonIterator(source, out found); } diff --git a/src/libraries/System.Linq/src/System/Linq/OfType.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/OfType.SpeedOpt.cs index 4420801ee4abcf..f2649e706c8a0e 100644 --- a/src/libraries/System.Linq/src/System/Linq/OfType.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/OfType.SpeedOpt.cs @@ -167,7 +167,7 @@ public override IEnumerable Select(Func s // they're covariant. It's not worthwhile checking for List to use the ListWhereSelectIterator // because List<> is not covariant. Func isTResult = static o => o is TResult; - return objectSource is object[] array ? + return !IsSizeOptimized && objectSource is object[] array ? new ArrayWhereSelectIterator(array, isTResult, localSelector) : new IEnumerableWhereSelectIterator(objectSource, isTResult, localSelector); } @@ -177,7 +177,11 @@ public override IEnumerable Select(Func s public override bool Contains(TResult value) { - if (!typeof(TResult).IsValueType && // don't box TResult + // Avoid checking for IList when size-optimized because it keeps IList + // implementations which may otherwise be trimmed. Since List implements + // IList and List is popular, this could potentially be a lot of code. + if (!IsSizeOptimized && + !typeof(TResult).IsValueType && // don't box TResult _source is IList list) { return list.Contains(value); diff --git a/src/libraries/System.Linq/src/System/Linq/Range.cs b/src/libraries/System.Linq/src/System/Linq/Range.cs index 24da4789b1cb5b..7c5bae3f395e80 100644 --- a/src/libraries/System.Linq/src/System/Linq/Range.cs +++ b/src/libraries/System.Linq/src/System/Linq/Range.cs @@ -97,7 +97,7 @@ private static void FillIncrementing(Span destination, T value) where T : current += increment; pos = ref Unsafe.Add(ref pos, Vector.Count); } - while (!Unsafe.IsAddressGreaterThan(ref pos, ref oneVectorFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref pos, ref oneVectorFromEnd)); value = current[0]; } diff --git a/src/libraries/System.Linq/src/System/Linq/Select.SizeOpt.cs b/src/libraries/System.Linq/src/System/Linq/Select.SizeOpt.cs new file mode 100644 index 00000000000000..bf476355511abd --- /dev/null +++ b/src/libraries/System.Linq/src/System/Linq/Select.SizeOpt.cs @@ -0,0 +1,100 @@ +// 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; +using System.Collections.Generic; +using System.Diagnostics; + +namespace System.Linq +{ + public static partial class Enumerable + { + private sealed class SizeOptIListSelectIterator(IList _source, Func _selector) + : Iterator + { + private IEnumerator? _enumerator; + + public override int GetCount(bool onlyIfCheap) + { + // In case someone uses Count() to force evaluation of + // the selector, run it provided `onlyIfCheap` is false. + + if (onlyIfCheap) + { + return -1; + } + + int count = 0; + + foreach (TSource item in _source) + { + _selector(item); + checked + { + count++; + } + } + + return count; + } + + public override Iterator Skip(int count) + { + Debug.Assert(count > 0); + return new IListSkipTakeSelectIterator(_source, _selector, count, int.MaxValue); + } + + public override Iterator Take(int count) + { + Debug.Assert(count > 0); + return new IListSkipTakeSelectIterator(_source, _selector, 0, count - 1); + } + + public override bool MoveNext() + { + switch (_state) + { + case 1: + _enumerator = _source.GetEnumerator(); + _state = 2; + goto case 2; + case 2: + Debug.Assert(_enumerator is not null); + if (_enumerator.MoveNext()) + { + _current = _selector(_enumerator.Current); + return true; + } + + Dispose(); + break; + } + + return false; + } + + public override TResult[] ToArray() + { + TResult[] array = new TResult[_source.Count]; + for (int i = 0; i < array.Length; i++) + { + array[i] = _selector(_source[i]); + } + return array; + } + + public override List ToList() + { + List list = new List(_source.Count); + for (int i = 0; i < list.Count; i++) + { + list.Add(_selector(_source[i])); + } + return list; + } + + private protected override Iterator Clone() + => new SizeOptIListSelectIterator(_source, _selector); + } + } +} diff --git a/src/libraries/System.Linq/src/System/Linq/Select.cs b/src/libraries/System.Linq/src/System/Linq/Select.cs index ac27c8dda22eeb..d5fcb864384440 100644 --- a/src/libraries/System.Linq/src/System/Linq/Select.cs +++ b/src/libraries/System.Linq/src/System/Linq/Select.cs @@ -32,7 +32,9 @@ public static IEnumerable Select( // don't need more code, just more data structures describing the new types). if (IsSizeOptimized && typeof(TResult).IsValueType) { - return new IEnumerableSelectIterator(iterator, selector); + return source is IList il + ? new SizeOptIListSelectIterator(il, selector) + : new IEnumerableSelectIterator(iterator, selector); } else { @@ -42,6 +44,11 @@ public static IEnumerable Select( if (source is IList ilist) { + if (IsSizeOptimized) + { + return new SizeOptIListSelectIterator(ilist, selector); + } + if (source is TSource[] array) { if (array.Length == 0) diff --git a/src/libraries/System.Linq/src/System/Linq/Skip.SizeOpt.cs b/src/libraries/System.Linq/src/System/Linq/Skip.SizeOpt.cs deleted file mode 100644 index 13e6642ee1fc02..00000000000000 --- a/src/libraries/System.Linq/src/System/Linq/Skip.SizeOpt.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; - -namespace System.Linq -{ - public static partial class Enumerable - { - private static IEnumerable SizeOptimizedSkipIterator(IEnumerable source, int count) - { - using IEnumerator e = source.GetEnumerator(); - while (count > 0 && e.MoveNext()) count--; - if (count <= 0) - { - while (e.MoveNext()) yield return e.Current; - } - } - } -} diff --git a/src/libraries/System.Linq/src/System/Linq/Skip.cs b/src/libraries/System.Linq/src/System/Linq/Skip.cs index ac8252a07c6d0c..4e76f1afba9794 100644 --- a/src/libraries/System.Linq/src/System/Linq/Skip.cs +++ b/src/libraries/System.Linq/src/System/Linq/Skip.cs @@ -30,12 +30,12 @@ public static IEnumerable Skip(this IEnumerable sourc count = 0; } - else if (!IsSizeOptimized && source is Iterator iterator) + else if (source is Iterator iterator) { return iterator.Skip(count) ?? Empty(); } - return IsSizeOptimized ? SizeOptimizedSkipIterator(source, count) : SpeedOptimizedSkipIterator(source, count); + return SpeedOptimizedSkipIterator(source, count); } public static IEnumerable SkipWhile(this IEnumerable source, Func predicate) diff --git a/src/libraries/System.Linq/src/System/Linq/Take.SizeOpt.cs b/src/libraries/System.Linq/src/System/Linq/Take.SizeOpt.cs deleted file mode 100644 index 6f2bd0d9b0fa6b..00000000000000 --- a/src/libraries/System.Linq/src/System/Linq/Take.SizeOpt.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Diagnostics; - -namespace System.Linq -{ - public static partial class Enumerable - { - private static IEnumerable SizeOptimizedTakeIterator(IEnumerable source, int count) - { - Debug.Assert(count > 0); - - foreach (TSource element in source) - { - yield return element; - if (--count == 0) break; - } - } - - private static IEnumerable SizeOptimizedTakeRangeIterator(IEnumerable source, int startIndex, int endIndex) - { - Debug.Assert(source is not null); - Debug.Assert(startIndex >= 0 && startIndex < endIndex); - - using IEnumerator e = source.GetEnumerator(); - - int index = 0; - while (index < startIndex && e.MoveNext()) - { - ++index; - } - - if (index < startIndex) - { - yield break; - } - - while (index < endIndex && e.MoveNext()) - { - yield return e.Current; - ++index; - } - } - } -} diff --git a/src/libraries/System.Linq/src/System/Linq/Take.cs b/src/libraries/System.Linq/src/System/Linq/Take.cs index 9df5fbc8a2bec8..8d6ad9acb3998d 100644 --- a/src/libraries/System.Linq/src/System/Linq/Take.cs +++ b/src/libraries/System.Linq/src/System/Linq/Take.cs @@ -20,7 +20,7 @@ public static IEnumerable Take(this IEnumerable sourc return []; } - return IsSizeOptimized ? SizeOptimizedTakeIterator(source, count) : SpeedOptimizedTakeIterator(source, count); + return SpeedOptimizedTakeIterator(source, count); } /// Returns a specified range of contiguous elements from a sequence. @@ -68,7 +68,7 @@ public static IEnumerable Take(this IEnumerable sourc return []; } - return IsSizeOptimized ? SizeOptimizedTakeRangeIterator(source, startIndex, endIndex) : SpeedOptimizedTakeRangeIterator(source, startIndex, endIndex); + return SpeedOptimizedTakeRangeIterator(source, startIndex, endIndex); } return TakeRangeFromEndIterator(source, isStartIndexFromEnd, startIndex, isEndIndexFromEnd, endIndex); @@ -94,9 +94,7 @@ private static IEnumerable TakeRangeFromEndIterator(IEnumerabl if (startIndex < endIndex) { - IEnumerable rangeIterator = IsSizeOptimized - ? SizeOptimizedTakeRangeIterator(source, startIndex, endIndex) - : SpeedOptimizedTakeRangeIterator(source, startIndex, endIndex); + IEnumerable rangeIterator = SpeedOptimizedTakeRangeIterator(source, startIndex, endIndex); foreach (TSource element in rangeIterator) { yield return element; diff --git a/src/libraries/System.Linq/src/System/Linq/Where.SizeOpt.cs b/src/libraries/System.Linq/src/System/Linq/Where.SizeOpt.cs new file mode 100644 index 00000000000000..ebb94853261d81 --- /dev/null +++ b/src/libraries/System.Linq/src/System/Linq/Where.SizeOpt.cs @@ -0,0 +1,114 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Diagnostics; + +namespace System.Linq +{ + public static partial class Enumerable + { + private sealed partial class SizeOptIListWhereIterator : Iterator + { + private readonly IList _source; + private readonly Func _predicate; + private IEnumerator? _enumerator; + + public SizeOptIListWhereIterator(IList source, Func predicate) + { + Debug.Assert(source is not null); + Debug.Assert(predicate is not null); + _source = source; + _predicate = predicate; + } + + private protected override Iterator Clone() => + new SizeOptIListWhereIterator(_source, _predicate); + + public override bool MoveNext() + { + switch (_state) + { + case 1: + _enumerator = _source.GetEnumerator(); + _state = 2; + goto case 2; + case 2: + while (_enumerator!.MoveNext()) + { + TSource item = _enumerator.Current; + if (_predicate(item)) + { + _current = item; + return true; + } + } + + Dispose(); + break; + } + + return false; + } + + public override IEnumerable Where(Func predicate) => + new SizeOptIListWhereIterator(_source, Utilities.CombinePredicates(_predicate, predicate)); + + public override TSource[] ToArray() + { + SegmentedArrayBuilder.ScratchBuffer scratch = default; + SegmentedArrayBuilder builder = new(scratch); + + foreach (TSource item in _source) + { + if (_predicate(item)) + { + builder.Add(item); + } + } + + TSource[] result = builder.ToArray(); + builder.Dispose(); + + return result; + } + + public override List ToList() + { + SegmentedArrayBuilder.ScratchBuffer scratch = default; + SegmentedArrayBuilder builder = new(scratch); + + foreach (TSource item in _source) + { + if (_predicate(item)) + { + builder.Add(item); + } + } + + List result = builder.ToList(); + builder.Dispose(); + + return result; + } + + public override int GetCount(bool onlyIfCheap) + { + if (onlyIfCheap) + { + return -1; + } + + int count = 0; + foreach (TSource item in _source) + { + if (_predicate(item)) + { + checked { count++; } + } + } + return count; + } + } + } +} diff --git a/src/libraries/System.Linq/src/System/Linq/Where.cs b/src/libraries/System.Linq/src/System/Linq/Where.cs index 4371af8299fb2e..c0028a1c004a22 100644 --- a/src/libraries/System.Linq/src/System/Linq/Where.cs +++ b/src/libraries/System.Linq/src/System/Linq/Where.cs @@ -26,6 +26,12 @@ public static IEnumerable Where(this IEnumerable sour return iterator.Where(predicate); } + // Only use IList when size-optimizing (no array or List specializations). + if (IsSizeOptimized && source is IList sourceList) + { + return new SizeOptIListWhereIterator(sourceList, predicate); + } + if (source is TSource[] array) { if (array.Length == 0) @@ -143,7 +149,7 @@ public override IEnumerable Select(Func sele new IEnumerableWhereSelectIterator(_source, _predicate, selector); public override IEnumerable Where(Func predicate) => - new IEnumerableWhereIterator(_source, CombinePredicates(_predicate, predicate)); + new IEnumerableWhereIterator(_source, Utilities.CombinePredicates(_predicate, predicate)); } /// diff --git a/src/libraries/System.Linq/tests/CountTests.cs b/src/libraries/System.Linq/tests/CountTests.cs index ddf96d4cf4b59a..27b18f77870218 100644 --- a/src/libraries/System.Linq/tests/CountTests.cs +++ b/src/libraries/System.Linq/tests/CountTests.cs @@ -3,10 +3,11 @@ using System.Collections.Generic; using Xunit; +using Xunit.Abstractions; namespace System.Linq.Tests { - public class CountTests : EnumerableTests + public class CountTests(ITestOutputHelper output) : EnumerableTests { [Fact] public void SameResultsRepeatCallsIntQuery() @@ -151,6 +152,7 @@ public void NonEnumeratedCount_SupportedEnumerables_ShouldReturnExpectedCount [MemberData(nameof(NonEnumeratedCount_UnsupportedEnumerables))] public void NonEnumeratedCount_UnsupportedEnumerables_ShouldReturnFalse(IEnumerable source) { + output.WriteLine(source.GetType().FullName); Assert.False(source.TryGetNonEnumeratedCount(out int actualCount)); Assert.Equal(0, actualCount); } @@ -180,15 +182,15 @@ public static IEnumerable NonEnumeratedCount_SupportedEnumerables() yield return WrapArgs(100, Enumerable.Range(1, 100)); yield return WrapArgs(80, Enumerable.Repeat(1, 80)); + yield return WrapArgs(20, Enumerable.Range(1, 20).Reverse()); + yield return WrapArgs(20, Enumerable.Range(1, 20).OrderBy(x => -x)); + yield return WrapArgs(20, Enumerable.Range(1, 10).Concat(Enumerable.Range(11, 10))); if (PlatformDetection.IsLinqSpeedOptimized) { yield return WrapArgs(50, Enumerable.Range(1, 50).Select(x => x + 1)); yield return WrapArgs(4, new int[] { 1, 2, 3, 4 }.Select(x => x + 1)); yield return WrapArgs(50, Enumerable.Range(1, 50).Select(x => x + 1).Select(x => x - 1)); - yield return WrapArgs(20, Enumerable.Range(1, 20).Reverse()); - yield return WrapArgs(20, Enumerable.Range(1, 20).OrderBy(x => -x)); - yield return WrapArgs(20, Enumerable.Range(1, 10).Concat(Enumerable.Range(11, 10))); } static object[] WrapArgs(int expectedCount, IEnumerable source) => [expectedCount, source]; @@ -204,11 +206,8 @@ public static IEnumerable NonEnumeratedCount_UnsupportedEnumerables() if (!PlatformDetection.IsLinqSpeedOptimized) { yield return WrapArgs(Enumerable.Range(1, 50).Select(x => x + 1)); - yield return WrapArgs(new int[] { 1, 2, 3, 4 }.Select(x => x + 1)); + yield return WrapArgs(new int[] { 1, 2, 3, 4 }.Select(x => x + 1)); yield return WrapArgs(Enumerable.Range(1, 50).Select(x => x + 1).Select(x => x - 1)); - yield return WrapArgs(Enumerable.Range(1, 20).Reverse()); - yield return WrapArgs(Enumerable.Range(1, 20).OrderBy(x => -x)); - yield return WrapArgs(Enumerable.Range(1, 10).Concat(Enumerable.Range(11, 10))); } static object[] WrapArgs(IEnumerable source) => [source]; diff --git a/src/libraries/System.Linq/tests/OrderedSubsetting.cs b/src/libraries/System.Linq/tests/OrderedSubsetting.cs index 5804ac1d4229e7..7826fb338dbce5 100644 --- a/src/libraries/System.Linq/tests/OrderedSubsetting.cs +++ b/src/libraries/System.Linq/tests/OrderedSubsetting.cs @@ -224,7 +224,7 @@ public void TakeAndSkip() Assert.Equal(Enumerable.Range(10, 1), ordered.Take(11).Skip(10)); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsLinqSpeedOptimized))] + [Fact] public void TakeAndSkip_DoesntIterateRangeUnlessNecessary() { Assert.Empty(Enumerable.Range(0, int.MaxValue).Take(int.MaxValue).OrderBy(i => i).Skip(int.MaxValue - 4).Skip(15)); diff --git a/src/libraries/System.Linq/tests/RangeTests.cs b/src/libraries/System.Linq/tests/RangeTests.cs index 476d4804fefeef..0bb6acca8bc685 100644 --- a/src/libraries/System.Linq/tests/RangeTests.cs +++ b/src/libraries/System.Linq/tests/RangeTests.cs @@ -236,7 +236,7 @@ public void LastOrDefault() Assert.Equal(int.MaxValue - 101, GetRange(-100, int.MaxValue).LastOrDefault()); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsLinqSpeedOptimized))] + [Fact] public void IListImplementationIsValid() { Validate(GetRange(42, 10), [42, 43, 44, 45, 46, 47, 48, 49, 50, 51]); diff --git a/src/libraries/System.Linq/tests/SelectTests.cs b/src/libraries/System.Linq/tests/SelectTests.cs index c7c84565485c73..5fdae70d06df38 100644 --- a/src/libraries/System.Linq/tests/SelectTests.cs +++ b/src/libraries/System.Linq/tests/SelectTests.cs @@ -12,6 +12,32 @@ namespace System.Linq.Tests { public class SelectTests : EnumerableTests { + [Fact] + public void SelectSideEffectsExecutedOnCount() + { + int i = 0; + // If we made no promises about side effects, i could be 0, but in practice users have + // taken a dependency on side effects executing on Count. + var count = Enumerable.Range(1, 10).Select(x => i++).Count(); + Assert.Equal(10, count); + Assert.Equal(10, i); + + i = 0; + count = Enumerable.Range(1, 10).Skip(5).Select(x => i++).Count(); + Assert.Equal(5, count); + Assert.Equal(5, i); + + i = 0; + count = Enumerable.Range(1, 10).Take(5).Select(x => i++).Count(); + Assert.Equal(5, count); + Assert.Equal(5, i); + + i = 0; + count = Enumerable.Range(1, 10).Skip(2).Take(3).Select(x => i++).Count(); + Assert.Equal(3, count); + Assert.Equal(3, i); + } + [Fact] public void SameResultsRepeatCallsStringQuery() { diff --git a/src/libraries/System.Linq/tests/SequenceTests.cs b/src/libraries/System.Linq/tests/SequenceTests.cs index 18a8fbd880749e..7c39f7437bd69c 100644 --- a/src/libraries/System.Linq/tests/SequenceTests.cs +++ b/src/libraries/System.Linq/tests/SequenceTests.cs @@ -50,25 +50,28 @@ static void ValidateSigned() where T : INumber { ValidateUnsigned(); - for (int i = 1; i < 3; i++) - { - Assert.NotNull(Enumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(122), T.CreateTruncating(-i))); - } + // Test negative steps from 123 to 122 + // step=-1: should give [123, 122] (2 elements) + // step=-2: should give [123] (1 element, step too large) + Assert.Equal(2, Enumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(122), T.CreateTruncating(-1)).Count()); + Assert.Single(Enumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(122), T.CreateTruncating(-2))); ValidateThrows(T.CreateTruncating(123), T.CreateTruncating(124), T.CreateTruncating(-2)); } static void ValidateUnsigned() where T : INumber { + // When start == end, all steps should return single element [123] for (int i = 0; i < 3; i++) { - Assert.NotNull(Enumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(123), T.CreateTruncating(i))); + Assert.Single(Enumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(123), T.CreateTruncating(i))); } - for (int i = 1; i < 3; i++) - { - Assert.NotNull(Enumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(124), T.CreateTruncating(i))); - } + // Test positive steps from 123 to 124 + // step=1: should give [123, 124] (2 elements) + // step=2: should give [123] (1 element, step too large) + Assert.Equal(2, Enumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(124), T.CreateTruncating(1)).Count()); + Assert.Single(Enumerable.Sequence(T.CreateTruncating(123), T.CreateTruncating(124), T.CreateTruncating(2))); ValidateThrows(T.CreateTruncating(123), T.CreateTruncating(122), T.CreateTruncating(2)); } diff --git a/src/libraries/System.Linq/tests/TakeTests.cs b/src/libraries/System.Linq/tests/TakeTests.cs index bcdaa42df0a9b5..310a942e507feb 100644 --- a/src/libraries/System.Linq/tests/TakeTests.cs +++ b/src/libraries/System.Linq/tests/TakeTests.cs @@ -669,7 +669,7 @@ public void RepeatEnumerating() } } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsLinqSpeedOptimized))] + [Theory] [InlineData(1000)] [InlineData(1000000)] [InlineData(int.MaxValue)] @@ -1623,7 +1623,7 @@ public void EmptySource_DoNotThrowException_EnumerablePartition() Assert.Empty(EnumerablePartitionOrEmpty(source).Take(^6..^7)); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsLinqSpeedOptimized))] + [Fact] public void SkipTakeOnIListIsIList() { IList list = new ReadOnlyCollection(Enumerable.Range(0, 100).ToList()); diff --git a/src/libraries/System.Linq/tests/WhereTests.cs b/src/libraries/System.Linq/tests/WhereTests.cs index 21e5f0f86829b5..f877e7bbaba4a6 100644 --- a/src/libraries/System.Linq/tests/WhereTests.cs +++ b/src/libraries/System.Linq/tests/WhereTests.cs @@ -892,14 +892,14 @@ public void SameResultsRepeatCallsStringQuery() public void SingleElementPredicateFalse() { int[] source = [3]; - Assert.Empty(source.Where(IsEven)); + Assert.DoesNotContain(source, IsEven); } [Fact] public void PredicateFalseForAll() { int[] source = [9, 7, 15, 3, 27]; - Assert.Empty(source.Where(IsEven)); + Assert.DoesNotContain(source, IsEven); } [Fact] diff --git a/src/libraries/System.Management/ref/System.Management.cs b/src/libraries/System.Management/ref/System.Management.cs index a7c68e9ce52f14..d9d5e673eefb23 100644 --- a/src/libraries/System.Management/ref/System.Management.cs +++ b/src/libraries/System.Management/ref/System.Management.cs @@ -136,7 +136,7 @@ public InvokeMethodOptions(System.Management.ManagementNamedValueCollection cont public partial class ManagementBaseObject : System.ComponentModel.Component, System.ICloneable, System.Runtime.Serialization.ISerializable { private protected ManagementBaseObject() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -168,7 +168,7 @@ public ManagementClass() { } public ManagementClass(System.Management.ManagementPath path) { } public ManagementClass(System.Management.ManagementPath path, System.Management.ObjectGetOptions options) { } public ManagementClass(System.Management.ManagementScope scope, System.Management.ManagementPath path, System.Management.ObjectGetOptions options) { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -242,7 +242,7 @@ public void Stop() { } public partial class ManagementException : System.SystemException { public ManagementException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -251,7 +251,7 @@ public ManagementException(string message) { } public ManagementException(string message, System.Exception innerException) { } public System.Management.ManagementStatus ErrorCode { get { throw null; } } public System.Management.ManagementBaseObject ErrorInformation { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -260,7 +260,7 @@ public override void GetObjectData(System.Runtime.Serialization.SerializationInf public partial class ManagementNamedValueCollection : System.Collections.Specialized.NameObjectCollectionBase { public ManagementNamedValueCollection() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -277,7 +277,7 @@ public ManagementObject() { } public ManagementObject(System.Management.ManagementPath path) { } public ManagementObject(System.Management.ManagementPath path, System.Management.ObjectGetOptions options) { } public ManagementObject(System.Management.ManagementScope scope, System.Management.ManagementPath path, System.Management.ObjectGetOptions options) { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Management/src/System/Management/ManagementBaseObject.cs b/src/libraries/System.Management/src/System/Management/ManagementBaseObject.cs index 0da42a48cedbbb..76a77643843a8f 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementBaseObject.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementBaseObject.cs @@ -223,7 +223,7 @@ internal IWbemClassObjectFreeThreaded wbemObject /// /// The to populate with data. /// The destination (see ) for this serialization. -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Management/src/System/Management/ManagementClass.cs b/src/libraries/System.Management/src/System/Management/ManagementClass.cs index 96806c56afed32..0d33a6e0465813 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementClass.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementClass.cs @@ -267,7 +267,7 @@ public ManagementClass(ManagementScope scope, ManagementPath path, ObjectGetOpti public ManagementClass(string scope, string path, ObjectGetOptions options) : base(new ManagementScope(scope), new ManagementPath(path), options) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Management/src/System/Management/ManagementException.cs b/src/libraries/System.Management/src/System/Management/ManagementException.cs index d2dc99a119d061..10c1e7cbf4fdb2 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementException.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementException.cs @@ -672,7 +672,7 @@ internal ManagementException(Exception e, string msg, ManagementBaseObject errOb /// /// The to populate with data. /// The destination (see ) for this serialization. -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -720,7 +720,7 @@ public ManagementException(string message, Exception innerException) : this(inne /// /// The to populate with data. /// The destination (see ) for this serialization. -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Management/src/System/Management/ManagementNamedValueCollection.cs b/src/libraries/System.Management/src/System/Management/ManagementNamedValueCollection.cs index 68efddb9bdae59..d6aae5e686cf60 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementNamedValueCollection.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementNamedValueCollection.cs @@ -46,7 +46,7 @@ public ManagementNamedValueCollection() /// /// The to populate with data. /// The destination (see ) for this serialization. -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Management/src/System/Management/ManagementObject.cs b/src/libraries/System.Management/src/System/Management/ManagementObject.cs index 3030400ac54ff9..6686227dd59890 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementObject.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementObject.cs @@ -462,7 +462,7 @@ public ManagementObject(string scopeString, string pathString, ObjectGetOptions /// /// The to populate with data. /// The destination (see ) for this serialization. -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Memory.Data/System.Memory.Data.slnx b/src/libraries/System.Memory.Data/System.Memory.Data.slnx index 94f1a825f58678..d16807b1adc297 100644 --- a/src/libraries/System.Memory.Data/System.Memory.Data.slnx +++ b/src/libraries/System.Memory.Data/System.Memory.Data.slnx @@ -1,45 +1,754 @@ + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs b/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs index 43310364ff9250..6b69ec66631acb 100644 --- a/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs +++ b/src/libraries/System.Memory.Data/tests/BinaryDataTests.cs @@ -710,7 +710,7 @@ public void ValidatesPositionValue() } [Fact] - public void CloseStreamValidation() + public async Task CloseStreamValidation() { byte[] buffer = "some data"u8.ToArray(); Stream stream = new BinaryData(buffer).ToStream(); @@ -719,7 +719,7 @@ public void CloseStreamValidation() Assert.Throws(() => stream.Position); Assert.Throws(() => stream.Seek(0, SeekOrigin.Begin)); Assert.Throws(() => stream.Read(buffer, 0, buffer.Length)); - Assert.ThrowsAsync(() => stream.ReadAsync(buffer, 0, buffer.Length)); + await Assert.ThrowsAsync(async () => await stream.ReadAsync(buffer, 0, buffer.Length)); Assert.Throws(() => stream.ReadByte()); Assert.Throws(() => stream.Length); Assert.False(stream.CanRead); diff --git a/src/libraries/System.Memory/tests/ParsersAndFormatters/StandardFormatTests.cs b/src/libraries/System.Memory/tests/ParsersAndFormatters/StandardFormatTests.cs index d45a4a455111f6..582e71ba8b3e7c 100644 --- a/src/libraries/System.Memory/tests/ParsersAndFormatters/StandardFormatTests.cs +++ b/src/libraries/System.Memory/tests/ParsersAndFormatters/StandardFormatTests.cs @@ -23,7 +23,7 @@ public static void StandardFormatCtorNegative() [InlineData("x99", 'x', StandardFormat.MaxPrecision)] [InlineData(null, default(char), default(byte))] [InlineData("", default(char), default(byte))] - public static void StandardFormatParseString(string formatString, char expectedSymbol, byte expectedPrecision) + public static void StandardFormatParseString(string? formatString, char expectedSymbol, byte expectedPrecision) { StandardFormat format = StandardFormat.Parse(formatString); Assert.Equal(expectedSymbol, format.Symbol); @@ -63,7 +63,7 @@ public static void StandardFormatParseNegative(string badFormatString) [InlineData("G$", default(char), default(byte), false)] [InlineData("Ga", default(char), default(byte), false)] [InlineData("G100", default(char), default(byte), false)] - public static void StandardFormatTryParse(string formatString, char expectedSymbol, byte expectedPrecision, bool expectedResult) + public static void StandardFormatTryParse(string? formatString, char expectedSymbol, byte expectedPrecision, bool expectedResult) { bool result = StandardFormat.TryParse(formatString, out StandardFormat format); Assert.Equal(expectedSymbol, format.Symbol); diff --git a/src/libraries/System.Memory/tests/Span/EnumerateLines.cs b/src/libraries/System.Memory/tests/Span/EnumerateLines.cs index e0abfbc97e38e4..3734f9a7acf3b4 100644 --- a/src/libraries/System.Memory/tests/Span/EnumerateLines.cs +++ b/src/libraries/System.Memory/tests/Span/EnumerateLines.cs @@ -138,7 +138,7 @@ static void TestI(TEnumerator enumerator) where TEnumerator : IEnum [InlineData("xyz", new[] { "..3", "^0.." })] // sequence at end produces empty string [InlineData("xyz", new[] { "..0", "^3.." })] // sequence at beginning produces empty string [InlineData("abc%def", new[] { ".." })] // we don't recognize EBCDIC encodings for LF (see Unicode Standard, Sec. 5.8, Table 5-1) - public static void EnumerateLines_Battery(string input, string[] expectedRanges) + public static void EnumerateLines_Battery(string? input, string[] expectedRanges) { // This test is similar to the string.ReplaceLineEndings test, but it checks ranges instead of substrings, // as we want to ensure that the method under test points to very specific slices within the original input string. diff --git a/src/libraries/System.Memory/tests/Span/StringSearchValues.cs b/src/libraries/System.Memory/tests/Span/StringSearchValues.cs index 2bb171a9826dbc..6e9c7a3451c25a 100644 --- a/src/libraries/System.Memory/tests/Span/StringSearchValues.cs +++ b/src/libraries/System.Memory/tests/Span/StringSearchValues.cs @@ -232,7 +232,11 @@ void TestWithPoisonPages(PoisonPagePlacement poisonPlacement, int haystackLength .First(c => !values.AsSpan().ContainsAny(c, char.ToLowerInvariant(c))); } - TestWithDifferentMarkerChars(haystack, '\0'); + if (!values.Contains('\0')) + { + TestWithDifferentMarkerChars(haystack, '\0'); + } + TestWithDifferentMarkerChars(haystack, '\u00FC'); TestWithDifferentMarkerChars(haystack, asciiNumberNotInSet); TestWithDifferentMarkerChars(haystack, asciiLetterLowerNotInSet); @@ -407,10 +411,26 @@ public static void SimpleIndexOfAnyValues(params string[] valuesArray) valuesArray[offset] = $"{original[0]}\u00F6{original.AsSpan(1)}"; TestCore(valuesArray); + // Test non-ASCII values over 0xFF + valuesArray[offset] = $"{original}\u2049"; + TestCore(valuesArray); + + valuesArray[offset] = $"\u2049{original}"; + TestCore(valuesArray); + + valuesArray[offset] = $"{original[0]}\u2049{original.AsSpan(1)}"; + TestCore(valuesArray); + // Test null chars in values valuesArray[offset] = $"{original[0]}\0{original.AsSpan(1)}"; TestCore(valuesArray); + valuesArray[offset] = $"\0{original}"; + TestCore(valuesArray); + + valuesArray[offset] = $"{original}\0"; + TestCore(valuesArray); + static void TestCore(string[] valuesArray) { Values_ImplementsSearchValuesBase(StringComparison.Ordinal, valuesArray); @@ -529,7 +549,7 @@ public static void TestIndexOfAny_RandomInputs_Stress() if (RemoteExecutor.IsSupported && Avx512F.IsSupported) { var psi = new ProcessStartInfo(); - psi.Environment.Add("DOTNET_EnableAVX512F", "0"); + psi.Environment.Add("DOTNET_EnableAVX512", "0"); RemoteExecutor.Invoke(RunStress, new RemoteInvokeOptions { StartInfo = psi, TimeOut = 10 * 60 * 1000 }).Dispose(); } diff --git a/src/libraries/System.Net.Http.Json/System.Net.Http.Json.slnx b/src/libraries/System.Net.Http.Json/System.Net.Http.Json.slnx index a6948e645335e1..f2c836d937149f 100644 --- a/src/libraries/System.Net.Http.Json/System.Net.Http.Json.slnx +++ b/src/libraries/System.Net.Http.Json/System.Net.Http.Json.slnx @@ -1,59 +1,1010 @@ + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj index 6b6cd6ec4cb172..31c7c9111e8866 100644 --- a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj +++ b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj @@ -15,6 +15,7 @@ + diff --git a/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj b/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj index 5c5bdb02fc1966..94ba61b1e82b15 100644 --- a/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj +++ b/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj @@ -39,6 +39,7 @@ System.Net.Http.Json.JsonContent + @@ -46,17 +47,17 @@ System.Net.Http.Json.JsonContent - + - - - - - - + + + + + + @@ -66,7 +67,6 @@ System.Net.Http.Json.JsonContent - diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.netstandard.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.netstandard.cs index b69e47a3a25a70..62f29b6f58d2ce 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.netstandard.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.netstandard.cs @@ -8,8 +8,7 @@ namespace System.Net.Http.Json { public static partial class HttpClientJsonExtensions { - private static HttpMethod HttpPatch => s_httpPatch ??= new HttpMethod("PATCH"); - private static HttpMethod? s_httpPatch; + private static HttpMethod HttpPatch => field ??= new HttpMethod("PATCH"); private static Task PatchAsync(this HttpClient client, string? requestUri, HttpContent content, CancellationToken cancellationToken) { diff --git a/src/libraries/System.Net.Http.Json/tests/UnitTests/TranscodingReadStreamTests.cs b/src/libraries/System.Net.Http.Json/tests/UnitTests/TranscodingReadStreamTests.cs index 67fa25cd519789..03a82be803fd17 100644 --- a/src/libraries/System.Net.Http.Json/tests/UnitTests/TranscodingReadStreamTests.cs +++ b/src/libraries/System.Net.Http.Json/tests/UnitTests/TranscodingReadStreamTests.cs @@ -164,19 +164,19 @@ private static async Task ReadAsync_WithOverflowBufferAtCharBufferBoundaries(str } } - public static TheoryData ReadAsyncInputLatin(string encoding) + public static TheoryData ReadAsyncInputLatin(string encoding) { int maxCharBufferSize = Encoding.GetEncoding(encoding).GetMaxCharCount(TranscodingReadStream.MaxByteBufferSize); return GetLatinTextInput(maxCharBufferSize, TranscodingReadStream.MaxByteBufferSize); } - public static TheoryData ReadAsyncInputUnicode(string encoding) + public static TheoryData ReadAsyncInputUnicode(string encoding) { int maxCharBufferSize = Encoding.GetEncoding(encoding).GetMaxCharCount(TranscodingReadStream.MaxByteBufferSize); return GetUnicodeText(maxCharBufferSize); } - internal static TheoryData GetLatinTextInput(int maxCharBufferSize, int maxByteBufferSize) + internal static TheoryData GetLatinTextInput(int maxCharBufferSize, int maxByteBufferSize) { return new TheoryData { @@ -189,7 +189,7 @@ internal static TheoryData GetLatinTextInput(int maxCharBufferSize, int maxByteB }; } - internal static TheoryData GetUnicodeText(int maxCharBufferSize) + internal static TheoryData GetUnicodeText(int maxCharBufferSize) { return new TheoryData { diff --git a/src/libraries/System.Net.Http.Json/tests/UnitTests/TranscodingWriteStreamTests.cs b/src/libraries/System.Net.Http.Json/tests/UnitTests/TranscodingWriteStreamTests.cs index b5b32f6c8712eb..e600437808620e 100644 --- a/src/libraries/System.Net.Http.Json/tests/UnitTests/TranscodingWriteStreamTests.cs +++ b/src/libraries/System.Net.Http.Json/tests/UnitTests/TranscodingWriteStreamTests.cs @@ -17,10 +17,10 @@ namespace System.Net.Http.Json.Functional.Tests { public class TranscodingWriteStreamTest { - public static TheoryData WriteAsyncInputLatin => + public static TheoryData WriteAsyncInputLatin => TranscodingReadStreamTest.GetLatinTextInput(TranscodingWriteStream.MaxCharBufferSize, TranscodingWriteStream.MaxByteBufferSize); - public static TheoryData WriteAsyncInputUnicode => + public static TheoryData WriteAsyncInputUnicode => TranscodingReadStreamTest.GetUnicodeText(TranscodingWriteStream.MaxCharBufferSize); [Theory] diff --git a/src/libraries/System.Net.Http.WinHttpHandler/System.Net.Http.WinHttpHandler.slnx b/src/libraries/System.Net.Http.WinHttpHandler/System.Net.Http.WinHttpHandler.slnx index 20b48b5533014a..5b7ad4c95829df 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/System.Net.Http.WinHttpHandler.slnx +++ b/src/libraries/System.Net.Http.WinHttpHandler/System.Net.Http.WinHttpHandler.slnx @@ -1,63 +1,1042 @@ + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/Resources/Strings.resx b/src/libraries/System.Net.Http.WinHttpHandler/src/Resources/Strings.resx index 1746057dc5aecd..82e7445d67e742 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/Resources/Strings.resx @@ -135,7 +135,4 @@ Request version value must be one of 1.0, 1.1, 2.0, or 3.0. - - Request headers must be valid Latin-1 characters. - diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCookieContainerAdapter.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCookieContainerAdapter.cs index b464672d8bb466..70503c868c245a 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCookieContainerAdapter.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCookieContainerAdapter.cs @@ -80,15 +80,7 @@ public static void ResetCookieRequestHeaders(WinHttpRequestState state, Uri redi (uint)cookieHeader.Length, Interop.WinHttp.WINHTTP_ADDREQ_FLAG_ADD)) { - int lastError = Marshal.GetLastWin32Error(); - if (lastError == Interop.WinHttp.ERROR_INVALID_PARAMETER) - { - throw new FormatException(SR.net_http_invalid_header_value); - } - else - { - throw WinHttpException.CreateExceptionUsingError(lastError, nameof(Interop.WinHttp.WinHttpAddRequestHeaders)); - } + throw WinHttpException.CreateExceptionUsingLastError(nameof(Interop.WinHttp.WinHttpAddRequestHeaders)); } } } diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpException.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpException.cs index fb017ebe43612d..22e7caa9256b3c 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpException.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpException.cs @@ -17,7 +17,7 @@ public WinHttpException(int error, string message) : base(error, message) this.HResult = ConvertErrorCodeToHR(error); } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs index ce072519f4cad2..1edeb191cc7ab7 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs @@ -43,10 +43,7 @@ public class WinHttpHandler : HttpMessageHandler internal static readonly Version HttpVersion20 = new Version(2, 0); internal static readonly Version HttpVersion30 = new Version(3, 0); internal static readonly Version HttpVersionUnknown = new Version(0, 0); - internal static bool DefaultCertificateRevocationCheck { get; } = - AppContextSwitchHelper.GetBooleanConfig( - "System.Net.Security.NoRevocationCheckByDefault", - "DOTNET_SYSTEM_NET_SECURITY_NOREVOCATIONCHECKBYDEFAULT") ? false : true; + internal static bool DefaultCertificateRevocationCheck { get; } internal static bool CertificateCachingAppContextSwitchEnabled { get; } = AppContext.TryGetSwitch("System.Net.Http.UseWinHttpCertificateCaching", out bool enabled) && enabled; private static readonly TimeSpan s_maxTimeout = TimeSpan.FromMilliseconds(int.MaxValue); @@ -94,7 +91,6 @@ private Func< private int _maxResponseHeadersLength = HttpHandlerDefaults.DefaultMaxResponseHeadersLength; private int _maxResponseDrainSize = HttpHandlerDefaults.DefaultMaxResponseDrainSize; - private IDictionary? _properties; // Only create dictionary when required. private volatile bool _operationStarted; private volatile int _disposed; private SafeWinHttpHandle? _sessionHandle; @@ -575,7 +571,7 @@ public bool EnableMultipleHttp2Connections } } - public IDictionary Properties => _properties ??= new Dictionary(); + public IDictionary Properties => field ??= new Dictionary(); #endregion protected override void Dispose(bool disposing) @@ -769,15 +765,7 @@ private static void AddRequestHeaders( (uint)requestHeadersBuffer.Length, Interop.WinHttp.WINHTTP_ADDREQ_FLAG_ADD)) { - int lastError = Marshal.GetLastWin32Error(); - if (lastError == Interop.WinHttp.ERROR_INVALID_PARAMETER) - { - throw new FormatException(SR.net_http_invalid_header_value); - } - else - { - throw WinHttpException.CreateExceptionUsingError(lastError, nameof(Interop.WinHttp.WinHttpAddRequestHeaders)); - } + throw WinHttpException.CreateExceptionUsingLastError(nameof(Interop.WinHttp.WinHttpAddRequestHeaders)); } } diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/WinHttpHandlerTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/WinHttpHandlerTest.cs index 2505480230e59e..d257f38d382d6f 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/WinHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/WinHttpHandlerTest.cs @@ -45,7 +45,7 @@ public void Ctor_ExpectedDefaultPropertyValues() Assert.Equal(CookieUsePolicy.UseInternalCookieStoreOnly, handler.CookieUsePolicy); Assert.Null(handler.CookieContainer); Assert.Null(handler.ServerCertificateValidationCallback); - Assert.True(handler.CheckCertificateRevocationList); + Assert.False(handler.CheckCertificateRevocationList); Assert.Equal(ClientCertificateOption.Manual, handler.ClientCertificateOption); X509Certificate2Collection certs = handler.ClientCertificates; Assert.True(certs.Count == 0); @@ -130,7 +130,8 @@ public void TcpKeepalive_WhenEnabled_ForwardsCorrectNativeOptions() { using var handler = new WinHttpHandler(); - SendRequestHelper.Send(handler, () => { + SendRequestHelper.Send(handler, () => + { handler.TcpKeepAliveEnabled = true; handler.TcpKeepAliveTime = TimeSpan.FromMinutes(13); handler.TcpKeepAliveInterval = TimeSpan.FromSeconds(42); @@ -148,7 +149,8 @@ public void TcpKeepalive_InfiniteTimeSpan_TranslatesToUInt32MaxValue() { using var handler = new WinHttpHandler(); - SendRequestHelper.Send(handler, () => { + SendRequestHelper.Send(handler, () => + { handler.TcpKeepAliveEnabled = true; handler.TcpKeepAliveTime = Timeout.InfiniteTimeSpan; handler.TcpKeepAliveInterval = Timeout.InfiniteTimeSpan; @@ -312,7 +314,8 @@ public void CookieUsePolicy_SetUseSpecifiedCookieContainerAndContainer_ExpectedW SendRequestHelper.Send( handler, - delegate { + delegate + { handler.CookieUsePolicy = CookieUsePolicy.UseSpecifiedCookieContainer; handler.CookieContainer = new CookieContainer(); }); diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/WinHttpResponseStreamTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/WinHttpResponseStreamTest.cs index 4665a6a88eba43..74030974906057 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/WinHttpResponseStreamTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/WinHttpResponseStreamTest.cs @@ -278,14 +278,14 @@ public void ReadAsync_WhenDisposed_ThrowsObjectDisposedException() } [Fact] - public void ReadAsync_PriorReadInProgress_ThrowsInvalidOperationException() + public async Task ReadAsync_PriorReadInProgress_ThrowsInvalidOperationException() { Stream stream = MakeResponseStream(); TestControl.WinHttpReadData.Pause(); Task t1 = stream.ReadAsync(new byte[1], 0, 1); - Assert.ThrowsAsync(() => stream.ReadAsync(new byte[1], 0, 1)); + await Assert.ThrowsAsync(async () => await stream.ReadAsync(new byte[1], 0, 1)); TestControl.WinHttpReadData.Resume(); t1.Wait(); diff --git a/src/libraries/System.Net.Http/System.Net.Http.slnx b/src/libraries/System.Net.Http/System.Net.Http.slnx index 092cfc4a08c3f4..cd4a62e6c4080b 100644 --- a/src/libraries/System.Net.Http/System.Net.Http.slnx +++ b/src/libraries/System.Net.Http/System.Net.Http.slnx @@ -68,6 +68,14 @@ + + + + + + + + @@ -76,6 +84,14 @@ + + + + + + + + @@ -92,6 +108,14 @@ + + + + + + + + @@ -100,6 +124,14 @@ + + + + + + + + @@ -124,6 +156,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -132,6 +196,22 @@ + + + + + + + + + + + + + + + + @@ -140,6 +220,14 @@ + + + + + + + + @@ -156,6 +244,14 @@ + + + + + + + + @@ -164,6 +260,14 @@ + + + + + + + + @@ -180,6 +284,14 @@ + + + + + + + + @@ -196,6 +308,22 @@ + + + + + + + + + + + + + + + + @@ -204,6 +332,22 @@ + + + + + + + + + + + + + + + + @@ -212,6 +356,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -245,6 +413,22 @@ + + + + + + + + + + + + + + + + @@ -253,6 +437,22 @@ + + + + + + + + + + + + + + + + @@ -261,6 +461,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -277,6 +501,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -285,6 +613,14 @@ + + + + + + + + @@ -293,6 +629,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -301,6 +661,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -309,6 +709,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.csproj b/src/libraries/System.Net.Http/ref/System.Net.Http.csproj index c355e49e667a80..5c12a22894d477 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.csproj @@ -1,15 +1,20 @@ + $(NetCoreAppCurrent) + + - - - - - + + + + + + + diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index 4fafeccae048ac..63d88d70d79ea0 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -64,6 +64,7 @@ + @@ -209,7 +210,7 @@ - + @@ -468,51 +469,51 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - + + - - - - + + + + diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs index af5fef3c13c30d..a8d7818a323bb6 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs @@ -113,8 +113,7 @@ public bool AllowAutoRedirect public const bool SupportsProxy = false; public const bool SupportsRedirectConfiguration = true; - private Dictionary? _properties; - public IDictionary Properties => _properties ??= new Dictionary(); + public IDictionary Properties => field ??= new Dictionary(); protected internal override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs index 72f1f88e1e1c3d..79fc283aeb421b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs @@ -21,14 +21,16 @@ internal sealed class DiagnosticsHandler : HttpMessageHandlerStage private readonly HttpMessageHandler _innerHandler; private readonly DistributedContextPropagator _propagator; private readonly HeaderDescriptor[]? _propagatorFields; + private readonly IWebProxy? _proxy; - public DiagnosticsHandler(HttpMessageHandler innerHandler, DistributedContextPropagator propagator, bool autoRedirect = false) + public DiagnosticsHandler(HttpMessageHandler innerHandler, DistributedContextPropagator propagator, IWebProxy? proxy, bool autoRedirect = false) { Debug.Assert(GlobalHttpSettings.DiagnosticsHandler.EnableActivityPropagation); Debug.Assert(innerHandler is not null && propagator is not null); _innerHandler = innerHandler; _propagator = propagator; + _proxy = proxy; // Prepare HeaderDescriptors for fields we need to clear when following redirects if (autoRedirect && _propagator.Fields is IReadOnlyCollection fields && fields.Count > 0) @@ -125,7 +127,7 @@ private async ValueTask SendAsyncCore(HttpRequestMessage re if (request.RequestUri is Uri requestUri && requestUri.IsAbsoluteUri) { - activity.SetTag("server.address", requestUri.Host); + activity.SetTag("server.address", DiagnosticsHelper.GetServerAddress(request, _proxy)); activity.SetTag("server.port", requestUri.Port); activity.SetTag("url.full", UriRedactionHelper.GetRedactedUriString(requestUri)); } @@ -354,12 +356,14 @@ private void InjectHeaders(Activity currentActivity, HttpRequestMessage request) { _propagator.Inject(currentActivity, request, static (carrier, key, value) => { - if (carrier is HttpRequestMessage request && - key is not null && - HeaderDescriptor.TryGet(key, out HeaderDescriptor descriptor) && - !request.Headers.TryGetHeaderValue(descriptor, out _)) + if (carrier is HttpRequestMessage request && key is not null) { - request.Headers.TryAddWithoutValidation(descriptor, value); + HeaderDescriptor descriptor = request.Headers.GetHeaderDescriptor(key); + + if (!request.Headers.Contains(descriptor)) + { + request.Headers.Add(descriptor, value); + } } }); request.MarkPropagatorStateInjectedByDiagnosticsHandler(); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHelper.cs b/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHelper.cs index 5b22e671420cd4..95d1e923bcec90 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHelper.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHelper.cs @@ -35,6 +35,21 @@ internal static class DiagnosticsHelper _ => httpVersion.ToString() }; + // Picks the value of the 'server.address' tag following rules specified in + // https://github.com/open-telemetry/semantic-conventions/blob/728e5d1/docs/http/http-spans.md#http-client-span + // When there is no proxy, we need to prioritize the contents of the Host header. + // Note that this is a best-effort guess, e.g. we are not checking if proxy.GetProxy(uri) returns null. + public static string GetServerAddress(HttpRequestMessage request, IWebProxy? proxy) + { + Debug.Assert(request.RequestUri is not null); + if ((proxy is null || proxy.IsBypassed(request.RequestUri)) && request.HasHeaders && request.Headers.Host is string hostHeader) + { + return HttpUtilities.ParseHostNameFromHeader(hostHeader); + } + + return request.RequestUri.IdnHost; + } + public static bool TryGetErrorType(HttpResponseMessage? response, Exception? exception, out string? errorType) { if (response is not null) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs index a4d44b2a307145..cb2e30c52baf95 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs @@ -15,6 +15,8 @@ namespace System.Net.Http.Headers // Use HeaderDescriptor.TryGet to resolve an arbitrary header name to a HeaderDescriptor. internal readonly struct HeaderDescriptor : IEquatable { + private static readonly SearchValues s_dangerousCharacterBytes = SearchValues.Create((byte)'\0', (byte)'\r', (byte)'\n'); + /// /// Either a or . /// @@ -169,7 +171,16 @@ public string GetHeaderValue(ReadOnlySpan headerValue, Encoding? valueEnco } } - return (valueEncoding ?? HttpRuleParser.DefaultHttpEncoding).GetString(headerValue); + string value = (valueEncoding ?? HttpRuleParser.DefaultHttpEncoding).GetString(headerValue); + if (headerValue.ContainsAny(s_dangerousCharacterBytes)) + { + // Depending on the encoding, 'value' may contain a dangerous character. + // We are replacing them with SP to conform with https://www.rfc-editor.org/rfc/rfc9110.html#section-5.5-5. + // This is a low-occurrence corner case, so we don't care about the cost of Replace() and the extra allocations. + value = value.Replace('\0', ' ').Replace('\r', ' ').Replace('\n', ' '); + } + + return value; } internal static string? GetKnownContentType(ReadOnlySpan contentTypeValue) @@ -196,19 +207,25 @@ public string GetHeaderValue(ReadOnlySpan headerValue, Encoding? valueEnco break; case 10: - switch (contentTypeValue[0]) + switch (contentTypeValue[6]) { - case (byte)'t': candidate = "text/plain"; break; // [t]ext/plain - case (byte)'i': candidate = "image/jpeg"; break; // [i]mage/jpeg + case (byte)'l': candidate = "text/plain"; break; // text/p[l]ain + case (byte)'j': candidate = "image/jpeg"; break; // image/[j]peg + case (byte)'w': candidate = "image/webp"; break; // image/[w]ebp } break; + case 13: + candidate = "image/svg+xml"; // image/svg+xml + break; + case 15: switch (contentTypeValue[12]) { case (byte)'p': candidate = "application/pdf"; break; // application/[p]df case (byte)'x': candidate = "application/xml"; break; // application/[x]ml case (byte)'z': candidate = "application/zip"; break; // application/[z]ip + case (byte)'i': candidate = "text/javascript"; break; // text/javascr[i]pt } break; @@ -220,6 +237,10 @@ public string GetHeaderValue(ReadOnlySpan headerValue, Encoding? valueEnco } break; + case 17: + candidate = "text/event-stream"; // text/event-stream + break; + case 19: candidate = "multipart/form-data"; // multipart/form-data break; @@ -228,17 +249,47 @@ public string GetHeaderValue(ReadOnlySpan headerValue, Encoding? valueEnco candidate = "application/javascript"; // application/javascript break; + case 23: + switch (contentTypeValue[18]) + { + case (byte)'u': candidate = "text/html;charset=utf-8"; break; // text/html;charset=[u]tf-8 + case (byte)'U': candidate = "text/html;charset=UTF-8"; break; // text/html;charset=[U]TF-8 + } + break; + case 24: - switch (contentTypeValue[19]) + switch (contentTypeValue[10] ^ contentTypeValue[19]) { - case (byte)'t': candidate = "application/octet-stream"; break; // application/octet-s[t]ream - case (byte)'u': candidate = "text/html; charset=utf-8"; break; // text/html; charset=[u]tf-8 - case (byte)'U': candidate = "text/html; charset=UTF-8"; break; // text/html; charset=[U]TF-8 + case 'n' ^ 't': candidate = "application/octet-stream"; break; // applicatio[n]/octet-s[t]ream + case ' ' ^ 'u': candidate = "text/html; charset=utf-8"; break; // text/html;[ ]charset=[u]tf-8 + case ' ' ^ 'U': candidate = "text/html; charset=UTF-8"; break; // text/html;[ ]charset=[U]TF-8 + case ';' ^ 'u': candidate = "text/plain;charset=utf-8"; break; // text/plain[;]charset=[u]tf-8 + case ';' ^ 'U': candidate = "text/plain;charset=UTF-8"; break; // text/plain[;]charset=[U]TF-8 } break; case 25: - candidate = "text/plain; charset=utf-8"; // text/plain; charset=utf-8 + switch (contentTypeValue[20]) + { + case (byte)'u': candidate = "text/plain; charset=utf-8"; break; // text/plain; charset=[u]tf-8 + case (byte)'U': candidate = "text/plain; charset=UTF-8"; break; // text/plain; charset=[U]TF-8 + } + break; + + case 29: + switch (contentTypeValue[19]) + { + case (byte)'I': candidate = "text/html; charset=ISO-8859-1"; break; // text/html; charset=[I]SO-8859-1 + case (byte)'i': candidate = "text/html; charset=iso-8859-1"; break; // text/html; charset=[i]so-8859-1 + } + break; + + case 30: + switch (contentTypeValue[25]) + { + case (byte)'u': candidate = "text/javascript; charset=utf-8"; break; // text/javascript; charset=[u]tf-8 + case (byte)'U': candidate = "text/javascript; charset=UTF-8"; break; // text/javascript; charset=[U]TF-8 + } break; case 31: diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs index 6fbe9410c496cc..3f179e1789e48b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs @@ -1131,7 +1131,7 @@ private static void ParseAndAddValue(HeaderDescriptor descriptor, HeaderStoreIte } } - private HeaderDescriptor GetHeaderDescriptor(string name) + internal HeaderDescriptor GetHeaderDescriptor(string name) { ArgumentException.ThrowIfNullOrEmpty(name); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeader.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeader.cs index ab78688af1e0c1..bc968d8cf5a7eb 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeader.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeader.cs @@ -8,12 +8,9 @@ namespace System.Net.Http.Headers { internal sealed partial class KnownHeader { - public KnownHeader(string name, int? http2StaticTableIndex = null, int? http3StaticTableIndex = null) : - this(name, HttpHeaderType.Custom, parser: null, knownValues: null, http2StaticTableIndex, http3StaticTableIndex) - { - Debug.Assert(!string.IsNullOrEmpty(name)); - Debug.Assert(name[0] == ':' || HttpRuleParser.IsToken(name)); - } + public KnownHeader(string name, string[]? knownValues = null, int? http2StaticTableIndex = null, int? http3StaticTableIndex = null) + : this(name, HttpHeaderType.Custom, parser: null, knownValues, http2StaticTableIndex, http3StaticTableIndex) + { } public KnownHeader(string name, HttpHeaderType headerType, HttpHeaderParser? parser, string[]? knownValues = null, int? http2StaticTableIndex = null, int? http3StaticTableIndex = null) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeaders.cs index 395a9c766306ac..c9dbd00e58e3f0 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeaders.cs @@ -13,101 +13,104 @@ internal static class KnownHeaders { // If you add a new entry here, you need to add it to TryGetKnownHeader below as well. - public static readonly KnownHeader PseudoStatus = new KnownHeader(":status", HttpHeaderType.Response, parser: null); - public static readonly KnownHeader Accept = new KnownHeader("Accept", HttpHeaderType.Request, MediaTypeHeaderParser.MultipleValuesParser, null, H2StaticTable.Accept, H3StaticTable.AcceptAny); - public static readonly KnownHeader AcceptCharset = new KnownHeader("Accept-Charset", HttpHeaderType.Request, GenericHeaderParser.MultipleValueStringWithQualityParser, null, H2StaticTable.AcceptCharset); - public static readonly KnownHeader AcceptEncoding = new KnownHeader("Accept-Encoding", HttpHeaderType.Request, GenericHeaderParser.MultipleValueStringWithQualityParser, null, H2StaticTable.AcceptEncoding, H3StaticTable.AcceptEncodingGzipDeflateBr); - public static readonly KnownHeader AcceptLanguage = new KnownHeader("Accept-Language", HttpHeaderType.Request, GenericHeaderParser.MultipleValueStringWithQualityParser, null, H2StaticTable.AcceptLanguage, H3StaticTable.AcceptLanguage); - public static readonly KnownHeader AcceptPatch = new KnownHeader("Accept-Patch"); - public static readonly KnownHeader AcceptRanges = new KnownHeader("Accept-Ranges", HttpHeaderType.Response, GenericHeaderParser.TokenListParser, null, H2StaticTable.AcceptRanges, H3StaticTable.AcceptRangesBytes); - public static readonly KnownHeader AccessControlAllowCredentials = new KnownHeader("Access-Control-Allow-Credentials", HttpHeaderType.Response, parser: null, new string[] { "true" }, http3StaticTableIndex: H3StaticTable.AccessControlAllowCredentials); - public static readonly KnownHeader AccessControlAllowHeaders = new KnownHeader("Access-Control-Allow-Headers", HttpHeaderType.Response, parser: null, new string[] { "*" }, http3StaticTableIndex: H3StaticTable.AccessControlAllowHeadersCacheControl); - public static readonly KnownHeader AccessControlAllowMethods = new KnownHeader("Access-Control-Allow-Methods", HttpHeaderType.Response, parser: null, new string[] { "*" }, http3StaticTableIndex: H3StaticTable.AccessControlAllowMethodsGet); - public static readonly KnownHeader AccessControlAllowOrigin = new KnownHeader("Access-Control-Allow-Origin", HttpHeaderType.Response, parser: null, new string[] { "*", "null" }, H2StaticTable.AccessControlAllowOrigin, H3StaticTable.AccessControlAllowOriginAny); - public static readonly KnownHeader AccessControlExposeHeaders = new KnownHeader("Access-Control-Expose-Headers", HttpHeaderType.Response, parser: null, new string[] { "*" }, H3StaticTable.AccessControlExposeHeadersContentLength); - public static readonly KnownHeader AccessControlMaxAge = new KnownHeader("Access-Control-Max-Age"); - public static readonly KnownHeader Age = new KnownHeader("Age", HttpHeaderType.Response | HttpHeaderType.NonTrailing, TimeSpanHeaderParser.Parser, null, H2StaticTable.Age, H3StaticTable.Age0); - public static readonly KnownHeader Allow = new KnownHeader("Allow", HttpHeaderType.Content, GenericHeaderParser.TokenListParser, null, H2StaticTable.Allow); - public static readonly KnownHeader AltSvc = new KnownHeader("Alt-Svc", HttpHeaderType.Response, GetAltSvcHeaderParser(), http3StaticTableIndex: H3StaticTable.AltSvcClear); - public static readonly KnownHeader AltUsed = new KnownHeader("Alt-Used", HttpHeaderType.Request, parser: null); - public static readonly KnownHeader Authorization = new KnownHeader("Authorization", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.SingleValueAuthenticationParser, null, H2StaticTable.Authorization, H3StaticTable.Authorization); - public static readonly KnownHeader CacheControl = new KnownHeader("Cache-Control", HttpHeaderType.General | HttpHeaderType.NonTrailing, CacheControlHeaderParser.Parser, new string[] { "must-revalidate", "no-cache", "no-store", "no-transform", "private", "proxy-revalidate", "public" }, H2StaticTable.CacheControl, H3StaticTable.CacheControlMaxAge0); - public static readonly KnownHeader Connection = new KnownHeader("Connection", HttpHeaderType.General, GenericHeaderParser.TokenListParser, new string[] { "close" }); - public static readonly KnownHeader ContentDisposition = new KnownHeader("Content-Disposition", HttpHeaderType.Content | HttpHeaderType.NonTrailing, GenericHeaderParser.ContentDispositionParser, new string[] { "inline", "attachment" }, H2StaticTable.ContentDisposition, H3StaticTable.ContentDisposition); - public static readonly KnownHeader ContentEncoding = new KnownHeader("Content-Encoding", HttpHeaderType.Content | HttpHeaderType.NonTrailing, GenericHeaderParser.TokenListParser, new string[] { "gzip", "deflate", "br", "compress", "identity" }, H2StaticTable.ContentEncoding, H3StaticTable.ContentEncodingBr); - public static readonly KnownHeader ContentLanguage = new KnownHeader("Content-Language", HttpHeaderType.Content, GenericHeaderParser.TokenListParser, null, H2StaticTable.ContentLanguage); - public static readonly KnownHeader ContentLength = new KnownHeader("Content-Length", HttpHeaderType.Content | HttpHeaderType.NonTrailing, Int64NumberHeaderParser.Parser, null, H2StaticTable.ContentLength, H3StaticTable.ContentLength0); - public static readonly KnownHeader ContentLocation = new KnownHeader("Content-Location", HttpHeaderType.Content | HttpHeaderType.NonTrailing, UriHeaderParser.RelativeOrAbsoluteUriParser, null, H2StaticTable.ContentLocation); - public static readonly KnownHeader ContentMD5 = new KnownHeader("Content-MD5", HttpHeaderType.Content, ByteArrayHeaderParser.Parser); - public static readonly KnownHeader ContentRange = new KnownHeader("Content-Range", HttpHeaderType.Content | HttpHeaderType.NonTrailing, GenericHeaderParser.ContentRangeParser, null, H2StaticTable.ContentRange); - public static readonly KnownHeader ContentSecurityPolicy = new KnownHeader("Content-Security-Policy", http3StaticTableIndex: H3StaticTable.ContentSecurityPolicyAllNone); - public static readonly KnownHeader ContentType = new KnownHeader("Content-Type", HttpHeaderType.Content | HttpHeaderType.NonTrailing, MediaTypeHeaderParser.SingleValueParser, null, H2StaticTable.ContentType, H3StaticTable.ContentTypeApplicationDnsMessage); - public static readonly KnownHeader Cookie = new KnownHeader("Cookie", HttpHeaderType.Custom, CookieHeaderParser.Parser, null, H2StaticTable.Cookie, H3StaticTable.Cookie); - public static readonly KnownHeader Cookie2 = new KnownHeader("Cookie2"); - public static readonly KnownHeader Date = new KnownHeader("Date", HttpHeaderType.General | HttpHeaderType.NonTrailing, DateHeaderParser.Parser, null, H2StaticTable.Date, H3StaticTable.Date); - public static readonly KnownHeader ETag = new KnownHeader("ETag", HttpHeaderType.Response, GenericHeaderParser.SingleValueEntityTagParser, null, H2StaticTable.ETag, H3StaticTable.ETag); - public static readonly KnownHeader Expect = new KnownHeader("Expect", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueNameValueWithParametersParser, new string[] { "100-continue" }, H2StaticTable.Expect); - public static readonly KnownHeader ExpectCT = new KnownHeader("Expect-CT"); - public static readonly KnownHeader Expires = new KnownHeader("Expires", HttpHeaderType.Content | HttpHeaderType.NonTrailing, DateHeaderParser.Parser, null, H2StaticTable.Expires); - public static readonly KnownHeader From = new KnownHeader("From", HttpHeaderType.Request, GenericHeaderParser.SingleValueParserWithoutValidation, null, H2StaticTable.From); - public static readonly KnownHeader GrpcEncoding = new KnownHeader("grpc-encoding", HttpHeaderType.Custom, null, new string[] { "identity", "gzip", "deflate" }); - public static readonly KnownHeader GrpcMessage = new KnownHeader("grpc-message"); - public static readonly KnownHeader GrpcStatus = new KnownHeader("grpc-status", HttpHeaderType.Custom, null, new string[] { "0" }); - public static readonly KnownHeader Host = new KnownHeader("Host", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.HostParser, null, H2StaticTable.Host); - public static readonly KnownHeader IfMatch = new KnownHeader("If-Match", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueEntityTagParser, null, H2StaticTable.IfMatch); - public static readonly KnownHeader IfModifiedSince = new KnownHeader("If-Modified-Since", HttpHeaderType.Request | HttpHeaderType.NonTrailing, DateHeaderParser.Parser, null, H2StaticTable.IfModifiedSince, H3StaticTable.IfModifiedSince); - public static readonly KnownHeader IfNoneMatch = new KnownHeader("If-None-Match", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueEntityTagParser, null, H2StaticTable.IfNoneMatch, H3StaticTable.IfNoneMatch); - public static readonly KnownHeader IfRange = new KnownHeader("If-Range", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.RangeConditionParser, null, H2StaticTable.IfRange, H3StaticTable.IfRange); - public static readonly KnownHeader IfUnmodifiedSince = new KnownHeader("If-Unmodified-Since", HttpHeaderType.Request | HttpHeaderType.NonTrailing, DateHeaderParser.Parser, null, H2StaticTable.IfUnmodifiedSince); - public static readonly KnownHeader KeepAlive = new KnownHeader("Keep-Alive"); - public static readonly KnownHeader LastModified = new KnownHeader("Last-Modified", HttpHeaderType.Content, DateHeaderParser.Parser, null, H2StaticTable.LastModified, H3StaticTable.LastModified); - public static readonly KnownHeader Link = new KnownHeader("Link", H2StaticTable.Link, H3StaticTable.Link); - public static readonly KnownHeader Location = new KnownHeader("Location", HttpHeaderType.Response | HttpHeaderType.NonTrailing, UriHeaderParser.RelativeOrAbsoluteUriParser, null, H2StaticTable.Location, H3StaticTable.Location); - public static readonly KnownHeader MaxForwards = new KnownHeader("Max-Forwards", HttpHeaderType.Request | HttpHeaderType.NonTrailing, Int32NumberHeaderParser.Parser, null, H2StaticTable.MaxForwards); - public static readonly KnownHeader Origin = new KnownHeader("Origin", http3StaticTableIndex: H3StaticTable.Origin); - public static readonly KnownHeader P3P = new KnownHeader("P3P"); - public static readonly KnownHeader Pragma = new KnownHeader("Pragma", HttpHeaderType.General | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueNameValueParser, new string[] { "no-cache" }); - public static readonly KnownHeader ProxyAuthenticate = new KnownHeader("Proxy-Authenticate", HttpHeaderType.Response | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueAuthenticationParser, null, H2StaticTable.ProxyAuthenticate); - public static readonly KnownHeader ProxyAuthorization = new KnownHeader("Proxy-Authorization", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.SingleValueAuthenticationParser, null, H2StaticTable.ProxyAuthorization); - public static readonly KnownHeader ProxyConnection = new KnownHeader("Proxy-Connection"); - public static readonly KnownHeader ProxySupport = new KnownHeader("Proxy-Support"); - public static readonly KnownHeader PublicKeyPins = new KnownHeader("Public-Key-Pins"); - public static readonly KnownHeader Range = new KnownHeader("Range", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.RangeParser, null, H2StaticTable.Range, H3StaticTable.RangeBytes0ToAll); - public static readonly KnownHeader Referer = new KnownHeader("Referer", HttpHeaderType.Request, UriHeaderParser.RelativeOrAbsoluteUriParser, null, H2StaticTable.Referer, H3StaticTable.Referer); // NB: The spelling-mistake "Referer" for "Referrer" must be matched. - public static readonly KnownHeader ReferrerPolicy = new KnownHeader("Referrer-Policy", HttpHeaderType.Custom, null, new string[] { "strict-origin-when-cross-origin", "origin-when-cross-origin", "strict-origin", "origin", "same-origin", "no-referrer-when-downgrade", "no-referrer", "unsafe-url" }); - public static readonly KnownHeader Refresh = new KnownHeader("Refresh", H2StaticTable.Refresh); - public static readonly KnownHeader RetryAfter = new KnownHeader("Retry-After", HttpHeaderType.Response | HttpHeaderType.NonTrailing, GenericHeaderParser.RetryConditionParser, null, H2StaticTable.RetryAfter); - public static readonly KnownHeader SecWebSocketAccept = new KnownHeader("Sec-WebSocket-Accept"); - public static readonly KnownHeader SecWebSocketExtensions = new KnownHeader("Sec-WebSocket-Extensions"); - public static readonly KnownHeader SecWebSocketKey = new KnownHeader("Sec-WebSocket-Key"); - public static readonly KnownHeader SecWebSocketProtocol = new KnownHeader("Sec-WebSocket-Protocol"); - public static readonly KnownHeader SecWebSocketVersion = new KnownHeader("Sec-WebSocket-Version"); - public static readonly KnownHeader Server = new KnownHeader("Server", HttpHeaderType.Response, ProductInfoHeaderParser.MultipleValueParser, null, H2StaticTable.Server, H3StaticTable.Server); - public static readonly KnownHeader ServerTiming = new KnownHeader("Server-Timing"); - public static readonly KnownHeader SetCookie = new KnownHeader("Set-Cookie", HttpHeaderType.Custom | HttpHeaderType.NonTrailing, null, null, H2StaticTable.SetCookie, H3StaticTable.SetCookie); - public static readonly KnownHeader SetCookie2 = new KnownHeader("Set-Cookie2", HttpHeaderType.Custom | HttpHeaderType.NonTrailing, null, null); - public static readonly KnownHeader StrictTransportSecurity = new KnownHeader("Strict-Transport-Security", H2StaticTable.StrictTransportSecurity, H3StaticTable.StrictTransportSecurityMaxAge31536000); - public static readonly KnownHeader TE = new KnownHeader("TE", HttpHeaderType.Request | HttpHeaderType.NonTrailing, TransferCodingHeaderParser.MultipleValueWithQualityParser, new string[] { "trailers", "compress", "deflate", "gzip" }); - public static readonly KnownHeader TSV = new KnownHeader("TSV"); - public static readonly KnownHeader Trailer = new KnownHeader("Trailer", HttpHeaderType.General | HttpHeaderType.NonTrailing, GenericHeaderParser.TokenListParser); - public static readonly KnownHeader TransferEncoding = new KnownHeader("Transfer-Encoding", HttpHeaderType.General | HttpHeaderType.NonTrailing, TransferCodingHeaderParser.MultipleValueParser, new string[] { "chunked", "compress", "deflate", "gzip", "identity" }, H2StaticTable.TransferEncoding); - public static readonly KnownHeader Upgrade = new KnownHeader("Upgrade", HttpHeaderType.General, GenericHeaderParser.MultipleValueProductParser); - public static readonly KnownHeader UpgradeInsecureRequests = new KnownHeader("Upgrade-Insecure-Requests", HttpHeaderType.Custom, null, new string[] { "1" }, http3StaticTableIndex: H3StaticTable.UpgradeInsecureRequests1); - public static readonly KnownHeader UserAgent = new KnownHeader("User-Agent", HttpHeaderType.Request, ProductInfoHeaderParser.MultipleValueParser, null, H2StaticTable.UserAgent, H3StaticTable.UserAgent); - public static readonly KnownHeader Vary = new KnownHeader("Vary", HttpHeaderType.Response | HttpHeaderType.NonTrailing, GenericHeaderParser.TokenListParser, new string[] { "*" }, H2StaticTable.Vary, H3StaticTable.VaryAcceptEncoding); - public static readonly KnownHeader Via = new KnownHeader("Via", HttpHeaderType.General, GenericHeaderParser.MultipleValueViaParser, null, H2StaticTable.Via); - public static readonly KnownHeader WWWAuthenticate = new KnownHeader("WWW-Authenticate", HttpHeaderType.Response | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueAuthenticationParser, null, H2StaticTable.WwwAuthenticate); - public static readonly KnownHeader Warning = new KnownHeader("Warning", HttpHeaderType.General | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueWarningParser); - public static readonly KnownHeader XAspNetVersion = new KnownHeader("X-AspNet-Version"); - public static readonly KnownHeader XCache = new KnownHeader("X-Cache"); - public static readonly KnownHeader XContentDuration = new KnownHeader("X-Content-Duration"); - public static readonly KnownHeader XContentTypeOptions = new KnownHeader("X-Content-Type-Options", HttpHeaderType.Custom, null, new string[] { "nosniff" }, http3StaticTableIndex: H3StaticTable.XContentTypeOptionsNoSniff); - public static readonly KnownHeader XFrameOptions = new KnownHeader("X-Frame-Options", HttpHeaderType.Custom, null, new string[] { "DENY", "SAMEORIGIN" }, http3StaticTableIndex: H3StaticTable.XFrameOptionsDeny); - public static readonly KnownHeader XMSEdgeRef = new KnownHeader("X-MSEdge-Ref"); - public static readonly KnownHeader XPoweredBy = new KnownHeader("X-Powered-By"); - public static readonly KnownHeader XRequestID = new KnownHeader("X-Request-ID"); - public static readonly KnownHeader XUACompatible = new KnownHeader("X-UA-Compatible"); - public static readonly KnownHeader XXssProtection = new KnownHeader("X-XSS-Protection", HttpHeaderType.Custom, null, new string[] { "0", "1", "1; mode=block" }); + public static readonly KnownHeader PseudoStatus = new(":status", HttpHeaderType.Response, parser: null); + public static readonly KnownHeader Accept = new("Accept", HttpHeaderType.Request, MediaTypeHeaderParser.MultipleValuesParser, null, H2StaticTable.Accept, H3StaticTable.AcceptAny); + public static readonly KnownHeader AcceptCharset = new("Accept-Charset", HttpHeaderType.Request, GenericHeaderParser.MultipleValueStringWithQualityParser, null, H2StaticTable.AcceptCharset); + public static readonly KnownHeader AcceptEncoding = new("Accept-Encoding", HttpHeaderType.Request, GenericHeaderParser.MultipleValueStringWithQualityParser, null, H2StaticTable.AcceptEncoding, H3StaticTable.AcceptEncodingGzipDeflateBr); + public static readonly KnownHeader AcceptLanguage = new("Accept-Language", HttpHeaderType.Request, GenericHeaderParser.MultipleValueStringWithQualityParser, null, H2StaticTable.AcceptLanguage, H3StaticTable.AcceptLanguage); + public static readonly KnownHeader AcceptPatch = new("Accept-Patch"); + public static readonly KnownHeader AcceptRanges = new("Accept-Ranges", HttpHeaderType.Response, GenericHeaderParser.TokenListParser, ["bytes", "none"], H2StaticTable.AcceptRanges, H3StaticTable.AcceptRangesBytes); + public static readonly KnownHeader AccessControlAllowCredentials = new("Access-Control-Allow-Credentials", HttpHeaderType.Response, parser: null, ["true"], http3StaticTableIndex: H3StaticTable.AccessControlAllowCredentials); + public static readonly KnownHeader AccessControlAllowHeaders = new("Access-Control-Allow-Headers", HttpHeaderType.Response, parser: null, ["*"], http3StaticTableIndex: H3StaticTable.AccessControlAllowHeadersCacheControl); + public static readonly KnownHeader AccessControlAllowMethods = new("Access-Control-Allow-Methods", HttpHeaderType.Response, parser: null, ["POST", "*"], http3StaticTableIndex: H3StaticTable.AccessControlAllowMethodsGet); + public static readonly KnownHeader AccessControlAllowOrigin = new("Access-Control-Allow-Origin", HttpHeaderType.Response, parser: null, ["*", "null"], H2StaticTable.AccessControlAllowOrigin, H3StaticTable.AccessControlAllowOriginAny); + public static readonly KnownHeader AccessControlExposeHeaders = new("Access-Control-Expose-Headers", HttpHeaderType.Response, parser: null, ["*"], H3StaticTable.AccessControlExposeHeadersContentLength); + public static readonly KnownHeader AccessControlMaxAge = new("Access-Control-Max-Age"); + public static readonly KnownHeader Age = new("Age", HttpHeaderType.Response | HttpHeaderType.NonTrailing, TimeSpanHeaderParser.Parser, ["0"], H2StaticTable.Age, H3StaticTable.Age0); + public static readonly KnownHeader Allow = new("Allow", HttpHeaderType.Content, GenericHeaderParser.TokenListParser, null, H2StaticTable.Allow); + public static readonly KnownHeader AltSvc = new("Alt-Svc", HttpHeaderType.Response, GetAltSvcHeaderParser(), ["h3=\":443\"", "h3=\":443\"; ma=2592000", "clear"], http3StaticTableIndex: H3StaticTable.AltSvcClear); + public static readonly KnownHeader AltUsed = new("Alt-Used", HttpHeaderType.Request, parser: null); + public static readonly KnownHeader Authorization = new("Authorization", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.SingleValueAuthenticationParser, null, H2StaticTable.Authorization, H3StaticTable.Authorization); + public static readonly KnownHeader CacheControl = new("Cache-Control", HttpHeaderType.General | HttpHeaderType.NonTrailing, CacheControlHeaderParser.Parser, ["must-revalidate", "no-cache", "no-store", "no-transform", "private", "proxy-revalidate", "public"], H2StaticTable.CacheControl, H3StaticTable.CacheControlMaxAge0); + public static readonly KnownHeader Connection = new("Connection", HttpHeaderType.General, GenericHeaderParser.TokenListParser, ["keep-alive", "close", "Upgrade", "Transfer-Encoding"]); + public static readonly KnownHeader ContentDisposition = new("Content-Disposition", HttpHeaderType.Content | HttpHeaderType.NonTrailing, GenericHeaderParser.ContentDispositionParser, ["inline", "attachment"], H2StaticTable.ContentDisposition, H3StaticTable.ContentDisposition); + public static readonly KnownHeader ContentEncoding = new("Content-Encoding", HttpHeaderType.Content | HttpHeaderType.NonTrailing, GenericHeaderParser.TokenListParser, ["gzip", "deflate", "br", "zstd", "compress", "identity"], H2StaticTable.ContentEncoding, H3StaticTable.ContentEncodingBr); + public static readonly KnownHeader ContentLanguage = new("Content-Language", HttpHeaderType.Content, GenericHeaderParser.TokenListParser, null, H2StaticTable.ContentLanguage); + public static readonly KnownHeader ContentLength = new("Content-Length", HttpHeaderType.Content | HttpHeaderType.NonTrailing, Int64NumberHeaderParser.Parser, null, H2StaticTable.ContentLength, H3StaticTable.ContentLength0); + public static readonly KnownHeader ContentLocation = new("Content-Location", HttpHeaderType.Content | HttpHeaderType.NonTrailing, UriHeaderParser.RelativeOrAbsoluteUriParser, null, H2StaticTable.ContentLocation); + public static readonly KnownHeader ContentMD5 = new("Content-MD5", HttpHeaderType.Content, ByteArrayHeaderParser.Parser); + public static readonly KnownHeader ContentRange = new("Content-Range", HttpHeaderType.Content | HttpHeaderType.NonTrailing, GenericHeaderParser.ContentRangeParser, null, H2StaticTable.ContentRange); + public static readonly KnownHeader ContentSecurityPolicy = new("Content-Security-Policy", ["upgrade-insecure-requests", "frame-ancestors 'self'"], http3StaticTableIndex: H3StaticTable.ContentSecurityPolicyAllNone); + public static readonly KnownHeader ContentType = new("Content-Type", HttpHeaderType.Content | HttpHeaderType.NonTrailing, MediaTypeHeaderParser.SingleValueParser, null, H2StaticTable.ContentType, H3StaticTable.ContentTypeApplicationDnsMessage); + public static readonly KnownHeader Cookie = new("Cookie", HttpHeaderType.Custom, CookieHeaderParser.Parser, null, H2StaticTable.Cookie, H3StaticTable.Cookie); + public static readonly KnownHeader Cookie2 = new("Cookie2"); + public static readonly KnownHeader CrossOriginResourcePolicy = new("Cross-Origin-Resource-Policy", ["cross-origin", "same-site", "same-origin"]); + public static readonly KnownHeader Date = new("Date", HttpHeaderType.General | HttpHeaderType.NonTrailing, DateHeaderParser.Parser, null, H2StaticTable.Date, H3StaticTable.Date); + public static readonly KnownHeader ETag = new("ETag", HttpHeaderType.Response, GenericHeaderParser.SingleValueEntityTagParser, null, H2StaticTable.ETag, H3StaticTable.ETag); + public static readonly KnownHeader Expect = new("Expect", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueNameValueWithParametersParser, ["100-continue"], H2StaticTable.Expect); + public static readonly KnownHeader ExpectCT = new("Expect-CT"); + public static readonly KnownHeader Expires = new("Expires", HttpHeaderType.Content | HttpHeaderType.NonTrailing, DateHeaderParser.Parser, ["Thu, 01 Jan 1970 00:00:01 GMT", "Mon, 01 Jan 1990 00:00:00 GMT"], H2StaticTable.Expires); + public static readonly KnownHeader From = new("From", HttpHeaderType.Request, GenericHeaderParser.SingleValueParserWithoutValidation, null, H2StaticTable.From); + public static readonly KnownHeader GrpcEncoding = new("grpc-encoding", ["identity", "gzip", "deflate"]); + public static readonly KnownHeader GrpcMessage = new("grpc-message"); + public static readonly KnownHeader GrpcStatus = new("grpc-status", ["0"]); + public static readonly KnownHeader Host = new("Host", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.HostParser, null, H2StaticTable.Host); + public static readonly KnownHeader IfMatch = new("If-Match", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueEntityTagParser, null, H2StaticTable.IfMatch); + public static readonly KnownHeader IfModifiedSince = new("If-Modified-Since", HttpHeaderType.Request | HttpHeaderType.NonTrailing, DateHeaderParser.Parser, null, H2StaticTable.IfModifiedSince, H3StaticTable.IfModifiedSince); + public static readonly KnownHeader IfNoneMatch = new("If-None-Match", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueEntityTagParser, null, H2StaticTable.IfNoneMatch, H3StaticTable.IfNoneMatch); + public static readonly KnownHeader IfRange = new("If-Range", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.RangeConditionParser, null, H2StaticTable.IfRange, H3StaticTable.IfRange); + public static readonly KnownHeader IfUnmodifiedSince = new("If-Unmodified-Since", HttpHeaderType.Request | HttpHeaderType.NonTrailing, DateHeaderParser.Parser, null, H2StaticTable.IfUnmodifiedSince); + public static readonly KnownHeader KeepAlive = new("Keep-Alive"); + public static readonly KnownHeader LastModified = new("Last-Modified", HttpHeaderType.Content, DateHeaderParser.Parser, null, H2StaticTable.LastModified, H3StaticTable.LastModified); + public static readonly KnownHeader Link = new("Link", null, H2StaticTable.Link, H3StaticTable.Link); + public static readonly KnownHeader Location = new("Location", HttpHeaderType.Response | HttpHeaderType.NonTrailing, UriHeaderParser.RelativeOrAbsoluteUriParser, null, H2StaticTable.Location, H3StaticTable.Location); + public static readonly KnownHeader MaxForwards = new("Max-Forwards", HttpHeaderType.Request | HttpHeaderType.NonTrailing, Int32NumberHeaderParser.Parser, null, H2StaticTable.MaxForwards); + public static readonly KnownHeader Origin = new("Origin", http3StaticTableIndex: H3StaticTable.Origin); + public static readonly KnownHeader P3P = new("P3P"); + public static readonly KnownHeader Pragma = new("Pragma", HttpHeaderType.General | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueNameValueParser, ["no-cache"]); + public static readonly KnownHeader ProxyAuthenticate = new("Proxy-Authenticate", HttpHeaderType.Response | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueAuthenticationParser, null, H2StaticTable.ProxyAuthenticate); + public static readonly KnownHeader ProxyAuthorization = new("Proxy-Authorization", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.SingleValueAuthenticationParser, null, H2StaticTable.ProxyAuthorization); + public static readonly KnownHeader ProxyConnection = new("Proxy-Connection"); + public static readonly KnownHeader ProxySupport = new("Proxy-Support"); + public static readonly KnownHeader PublicKeyPins = new("Public-Key-Pins"); + public static readonly KnownHeader Range = new("Range", HttpHeaderType.Request | HttpHeaderType.NonTrailing, GenericHeaderParser.RangeParser, null, H2StaticTable.Range, H3StaticTable.RangeBytes0ToAll); + public static readonly KnownHeader Referer = new("Referer", HttpHeaderType.Request, UriHeaderParser.RelativeOrAbsoluteUriParser, null, H2StaticTable.Referer, H3StaticTable.Referer); // NB: The spelling-mistake "Referer" for "Referrer" must be matched. + public static readonly KnownHeader ReferrerPolicy = new("Referrer-Policy", ["same-origin", "strict-origin-when-cross-origin", "no-referrer-when-downgrade", "origin-when-cross-origin", "strict-origin", "origin", "no-referrer", "unsafe-url"]); + public static readonly KnownHeader Refresh = new("Refresh", null, H2StaticTable.Refresh); + public static readonly KnownHeader RetryAfter = new("Retry-After", HttpHeaderType.Response | HttpHeaderType.NonTrailing, GenericHeaderParser.RetryConditionParser, null, H2StaticTable.RetryAfter); + public static readonly KnownHeader SecWebSocketAccept = new("Sec-WebSocket-Accept"); + public static readonly KnownHeader SecWebSocketExtensions = new("Sec-WebSocket-Extensions", ["permessage-deflate"]); + public static readonly KnownHeader SecWebSocketKey = new("Sec-WebSocket-Key"); + public static readonly KnownHeader SecWebSocketProtocol = new("Sec-WebSocket-Protocol"); + public static readonly KnownHeader SecWebSocketVersion = new("Sec-WebSocket-Version"); + public static readonly KnownHeader Server = new("Server", HttpHeaderType.Response, ProductInfoHeaderParser.MultipleValueParser, null, H2StaticTable.Server, H3StaticTable.Server); + public static readonly KnownHeader ServerTiming = new("Server-Timing"); + public static readonly KnownHeader SetCookie = new("Set-Cookie", HttpHeaderType.Custom | HttpHeaderType.NonTrailing, null, null, H2StaticTable.SetCookie, H3StaticTable.SetCookie); + public static readonly KnownHeader SetCookie2 = new("Set-Cookie2", HttpHeaderType.Custom | HttpHeaderType.NonTrailing, null); + public static readonly KnownHeader StrictTransportSecurity = new("Strict-Transport-Security", ["max-age=31536000", "max-age=31536000; includeSubDomains; preload", "max-age=31536000; includeSubDomains", "max-age=63072000; includeSubDomains; preload"], H2StaticTable.StrictTransportSecurity, H3StaticTable.StrictTransportSecurityMaxAge31536000); + public static readonly KnownHeader TE = new("TE", HttpHeaderType.Request | HttpHeaderType.NonTrailing, TransferCodingHeaderParser.MultipleValueWithQualityParser, ["trailers", "compress", "deflate", "gzip"]); + public static readonly KnownHeader TimingAllowOrigin = new("Timing-Allow-Origin", ["*"]); + public static readonly KnownHeader Trailer = new("Trailer", HttpHeaderType.General | HttpHeaderType.NonTrailing, GenericHeaderParser.TokenListParser); + public static readonly KnownHeader TransferEncoding = new("Transfer-Encoding", HttpHeaderType.General | HttpHeaderType.NonTrailing, TransferCodingHeaderParser.MultipleValueParser, ["chunked", "compress", "deflate", "gzip", "identity"], H2StaticTable.TransferEncoding); + public static readonly KnownHeader TSV = new("TSV"); + public static readonly KnownHeader Upgrade = new("Upgrade", HttpHeaderType.General, GenericHeaderParser.MultipleValueProductParser); + public static readonly KnownHeader UpgradeInsecureRequests = new("Upgrade-Insecure-Requests", ["1"], http3StaticTableIndex: H3StaticTable.UpgradeInsecureRequests1); + public static readonly KnownHeader UserAgent = new("User-Agent", HttpHeaderType.Request, ProductInfoHeaderParser.MultipleValueParser, null, H2StaticTable.UserAgent, H3StaticTable.UserAgent); + public static readonly KnownHeader Vary = new("Vary", HttpHeaderType.Response | HttpHeaderType.NonTrailing, GenericHeaderParser.TokenListParser, ["Accept-Encoding", "accept-encoding", "Origin", "Referer", "*"], H2StaticTable.Vary, H3StaticTable.VaryAcceptEncoding); + public static readonly KnownHeader Via = new("Via", HttpHeaderType.General, GenericHeaderParser.MultipleValueViaParser, null, H2StaticTable.Via); + public static readonly KnownHeader WWWAuthenticate = new("WWW-Authenticate", HttpHeaderType.Response | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueAuthenticationParser, null, H2StaticTable.WwwAuthenticate); + public static readonly KnownHeader Warning = new("Warning", HttpHeaderType.General | HttpHeaderType.NonTrailing, GenericHeaderParser.MultipleValueWarningParser); + public static readonly KnownHeader XAspNetVersion = new("X-AspNet-Version"); + public static readonly KnownHeader XCache = new("X-Cache", ["HIT", "MISS", "hit", "miss"]); + public static readonly KnownHeader XContentDuration = new("X-Content-Duration"); + public static readonly KnownHeader XContentTypeOptions = new("X-Content-Type-Options", ["nosniff"], http3StaticTableIndex: H3StaticTable.XContentTypeOptionsNoSniff); + public static readonly KnownHeader XFrameOptions = new("X-Frame-Options", ["SAMEORIGIN", "DENY", "sameorigin", "deny"], http3StaticTableIndex: H3StaticTable.XFrameOptionsDeny); + public static readonly KnownHeader XMSEdgeRef = new("X-MSEdge-Ref"); + public static readonly KnownHeader XPoweredBy = new("X-Powered-By"); + public static readonly KnownHeader XRequestID = new("X-Request-ID"); + public static readonly KnownHeader XServedBy = new("X-Served-By"); + public static readonly KnownHeader XUACompatible = new("X-UA-Compatible"); + public static readonly KnownHeader XXssProtection = new("X-XSS-Protection", ["1; mode=block", "0", "1"]); #if TARGET_BROWSER || TARGET_WASI private static HttpHeaderParser? GetAltSvcHeaderParser() => null; // Allow for the AltSvcHeaderParser to be trimmed on Browser since Alt-Svc is only for SocketsHttpHandler, which isn't used on Browser. @@ -229,6 +232,7 @@ internal static class KnownHeaders case 'g': return GrpcStatus; // [g]rpc-status case 'r': return RetryAfter; // [R]etry-After case 's': return SetCookie2; // [S]et-Cookie2 + case 'x': return XServedBy; // [X]-Served-By } break; @@ -326,6 +330,7 @@ internal static class KnownHeaders case 'c': return ContentDisposition; // [C]ontent-Disposition case 'i': return IfUnmodifiedSince; // [I]f-Unmodified-Since case 'p': return ProxyAuthorization; // [P]roxy-Authorization + case 't': return TimingAllowOrigin; // [T]iming-Allow-Origin } break; @@ -366,6 +371,7 @@ internal static class KnownHeaders { case 'h': return AccessControlAllowHeaders; // Access-Control-Allow-[H]eaders case 'm': return AccessControlAllowMethods; // Access-Control-Allow-[M]ethods + case '-': return CrossOriginResourcePolicy; // Cross-Origin-Resource[-]Policy } break; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/QPackStaticTable.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/QPackStaticTable.cs index e6664bdbf3b6a3..ff590143dbca6c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/QPackStaticTable.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/QPackStaticTable.cs @@ -102,7 +102,7 @@ internal static class QPackStaticTable (new HeaderDescriptor(KnownHeaders.Origin), ""), // 90 (new HeaderDescriptor("purpose"), "prefetch"), // 91 (new HeaderDescriptor(KnownHeaders.Server), ""), // 92 - (new HeaderDescriptor("timing-allow-origin"), "*"), // 93 + (new HeaderDescriptor(KnownHeaders.TimingAllowOrigin), "*"), // 93 (new HeaderDescriptor(KnownHeaders.UpgradeInsecureRequests), "1"), // 94 (new HeaderDescriptor(KnownHeaders.UserAgent), ""), // 95 (new HeaderDescriptor("x-forwarded-for"), ""), // 96 diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs index da2eb54de9b8d9..da3b0b2f396b05 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs @@ -43,13 +43,14 @@ private HttpMessageHandler Handler // MetricsHandler should be descendant of DiagnosticsHandler in the handler chain to make sure the 'http.request.duration' // metric is recorded before stopping the request Activity. This is needed to make sure that our telemetry supports Exemplars. + // Since HttpClientHandler.Proxy is unsupported on most platforms, don't bother passing it to telemetry handlers. if (GlobalHttpSettings.MetricsHandler.IsGloballyEnabled) { - handler = new MetricsHandler(handler, _nativeMeterFactory, out _); + handler = new MetricsHandler(handler, _nativeMeterFactory, proxy: null, out _); } if (GlobalHttpSettings.DiagnosticsHandler.EnableActivityPropagation) { - handler = new DiagnosticsHandler(handler, DistributedContextPropagator.Current); + handler = new DiagnosticsHandler(handler, DistributedContextPropagator.Current, proxy: null); } // Ensure a single handler is used for all requests. @@ -776,12 +777,11 @@ protected internal override Task SendAsync(HttpRequestMessa } // lazy-load the validator func so it can be trimmed by the ILLinker if it isn't used. - private static Func? s_dangerousAcceptAnyServerCertificateValidator; [UnsupportedOSPlatform("browser")] public static Func DangerousAcceptAnyServerCertificateValidator => - s_dangerousAcceptAnyServerCertificateValidator ?? - Interlocked.CompareExchange(ref s_dangerousAcceptAnyServerCertificateValidator, delegate { return true; }, null) ?? - s_dangerousAcceptAnyServerCertificateValidator; + field ?? + Interlocked.CompareExchange(ref field, delegate { return true; }, null) ?? + field; private void ThrowForModifiedManagedSslOptionsIfStarted() { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs index 9af5dba293170b..00b7861f1112dc 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs @@ -45,13 +45,14 @@ private HttpMessageHandler Handler // MetricsHandler should be descendant of DiagnosticsHandler in the handler chain to make sure the 'http.request.duration' // metric is recorded before stopping the request Activity. This is needed to make sure that our telemetry supports Exemplars. + // Since HttpClientHandler.Proxy is unsupported on most platforms, don't bother passing it to telemetry handlers. if (GlobalHttpSettings.MetricsHandler.IsGloballyEnabled) { - handler = new MetricsHandler(handler, _meterFactory, out _); + handler = new MetricsHandler(handler, _meterFactory, proxy: null, out _); } if (GlobalHttpSettings.DiagnosticsHandler.EnableActivityPropagation) { - handler = new DiagnosticsHandler(handler, DistributedContextPropagator.Current); + handler = new DiagnosticsHandler(handler, DistributedContextPropagator.Current, proxy: null); } // Ensure a single handler is used for all requests. @@ -371,12 +372,11 @@ protected internal override Task SendAsync(HttpRequestMessa } // lazy-load the validator func so it can be trimmed by the ILLinker if it isn't used. - private static Func? s_dangerousAcceptAnyServerCertificateValidator; [UnsupportedOSPlatform("browser")] public static Func DangerousAcceptAnyServerCertificateValidator => - s_dangerousAcceptAnyServerCertificateValidator ?? - Interlocked.CompareExchange(ref s_dangerousAcceptAnyServerCertificateValidator, delegate { return true; }, null) ?? - s_dangerousAcceptAnyServerCertificateValidator; + field ?? + Interlocked.CompareExchange(ref field, delegate { return true; }, null) ?? + field; private void ThrowForModifiedManagedSslOptionsIfStarted() { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs index 2649dcb3de74e3..e7636d297eaff4 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs @@ -7,6 +7,7 @@ using System.Globalization; using System.IO; using System.Net.Http.Headers; +using System.Runtime.ExceptionServices; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -695,7 +696,7 @@ internal static Exception WrapStreamCopyException(Exception e) { Debug.Assert(StreamCopyExceptionNeedsWrapping(e)); HttpRequestError error = e is HttpIOException ioEx ? ioEx.HttpRequestError : HttpRequestError.Unknown; - return new HttpRequestException(error, SR.net_http_content_stream_copy_error, e); + return ExceptionDispatchInfo.SetCurrentStackTrace(new HttpRequestException(error, SR.net_http_content_stream_copy_error, e)); } private static int GetPreambleLength(ReadOnlySpan data, Encoding encoding) @@ -767,7 +768,7 @@ private static async Task WaitAndReturnAsync(Task wait private static HttpRequestException CreateOverCapacityException(long maxBufferSize) { - return new HttpRequestException(HttpRequestError.ConfigurationLimitExceeded, SR.Format(CultureInfo.InvariantCulture, SR.net_http_content_buffersize_exceeded, maxBufferSize)); + return (HttpRequestException)ExceptionDispatchInfo.SetCurrentStackTrace(new HttpRequestException(HttpRequestError.ConfigurationLimitExceeded, SR.Format(CultureInfo.InvariantCulture, SR.net_http_content_buffersize_exceeded, maxBufferSize))); } /// diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpUtilities.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpUtilities.cs new file mode 100644 index 00000000000000..19dc5cc54dd0b0 --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpUtilities.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Net.Http +{ + internal static partial class HttpUtilities + { + public static string ParseHostNameFromHeader(string hostHeader) + { + // See if we need to trim off a port. + int colonPos = hostHeader.IndexOf(':'); + if (colonPos >= 0) + { + // There is colon, which could either be a port separator or a separator in + // an IPv6 address. See if this is an IPv6 address; if it's not, use everything + // before the colon as the host name, and if it is, use everything before the last + // colon iff the last colon is after the end of the IPv6 address (otherwise it's a + // part of the address). + int ipV6AddressEnd = hostHeader.IndexOf(']'); + if (ipV6AddressEnd == -1) + { + return hostHeader.Substring(0, colonPos); + } + else + { + colonPos = hostHeader.LastIndexOf(':'); + if (colonPos > ipV6AddressEnd) + { + return hostHeader.Substring(0, colonPos); + } + } + } + + return hostHeader; + } + } +} diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs index 9b18f93b7d8e1d..4e6f6a05e69ce2 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs @@ -15,12 +15,14 @@ internal sealed class MetricsHandler : HttpMessageHandlerStage private readonly HttpMessageHandler _innerHandler; private readonly UpDownCounter _activeRequests; private readonly Histogram _requestsDuration; + private readonly IWebProxy? _proxy; - public MetricsHandler(HttpMessageHandler innerHandler, IMeterFactory? meterFactory, out Meter meter) + public MetricsHandler(HttpMessageHandler innerHandler, IMeterFactory? meterFactory, IWebProxy? proxy, out Meter meter) { Debug.Assert(GlobalHttpSettings.MetricsHandler.IsGloballyEnabled); _innerHandler = innerHandler; + _proxy = proxy; meter = meterFactory?.Create("System.Net.Http") ?? SharedMeter.Instance; @@ -137,14 +139,14 @@ private void RequestStop(HttpRequestMessage request, HttpResponseMessage? respon } } - private static TagList InitializeCommonTags(HttpRequestMessage request) + private TagList InitializeCommonTags(HttpRequestMessage request) { TagList tags = default; if (request.RequestUri is Uri requestUri && requestUri.IsAbsoluteUri) { tags.Add("url.scheme", requestUri.Scheme); - tags.Add("server.address", requestUri.Host); + tags.Add("server.address", DiagnosticsHelper.GetServerAddress(request, _proxy)); tags.Add("server.port", DiagnosticsHelper.GetBoxedInt32(requestUri.Port)); } tags.Add(DiagnosticsHelper.GetMethodTag(request.Method, out _)); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/ConnectionSetupDistributedTracing.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/ConnectionSetupDistributedTracing.cs index 522a57f76e61aa..3a65389d20e045 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/ConnectionSetupDistributedTracing.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/ConnectionSetupDistributedTracing.cs @@ -12,7 +12,7 @@ internal static class ConnectionSetupDistributedTracing { private static readonly ActivitySource s_connectionsActivitySource = new ActivitySource(DiagnosticsHandlerLoggingStrings.ConnectionsNamespace); - public static Activity? StartConnectionSetupActivity(bool isSecure, HttpAuthority authority) + public static Activity? StartConnectionSetupActivity(bool isSecure, string? serverAddress, int port) { Activity? activity = null; if (s_connectionsActivitySource.HasListeners()) @@ -25,11 +25,12 @@ internal static class ConnectionSetupDistributedTracing if (activity is not null) { - activity.DisplayName = $"HTTP connection_setup {authority.HostValue}:{authority.Port}"; + Debug.Assert(serverAddress is not null, "serverAddress should not be null when System.Net.Http.EnableActivityPropagation is true."); + activity.DisplayName = $"HTTP connection_setup {serverAddress}:{port}"; if (activity.IsAllDataRequested) { - activity.SetTag("server.address", authority.HostValue); - activity.SetTag("server.port", authority.Port); + activity.SetTag("server.address", serverAddress); + activity.SetTag("server.port", port); activity.SetTag("url.scheme", isSecure ? "https" : "http"); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/HttpConnectionPool.Http3.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/HttpConnectionPool.Http3.cs index c2545cd4d7dc36..22bc7aa5f488d0 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/HttpConnectionPool.Http3.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/HttpConnectionPool.Http3.cs @@ -263,7 +263,7 @@ private async Task InjectNewHttp3ConnectionAsync(RequestQueue. { if (TryGetHttp3Authority(queueItem.Request, out authority, out Exception? reasonException)) { - connectionSetupActivity = ConnectionSetupDistributedTracing.StartConnectionSetupActivity(isSecure: true, authority); + connectionSetupActivity = ConnectionSetupDistributedTracing.StartConnectionSetupActivity(isSecure: true, _telemetryServerAddress, authority.Port); // If the authority was sent as an option through alt-svc then include alt-used header. connection = new Http3Connection(this, authority, includeAltUsedHeader: _http3Authority == authority); QuicConnection quicConnection = await ConnectHelper.ConnectQuicAsync(queueItem.Request, new DnsEndPoint(authority.IdnHost, authority.Port), _poolManager.Settings._pooledConnectionIdleTimeout, _sslOptionsHttp3!, connection.StreamCapacityCallback, cts.Token).ConfigureAwait(false); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/HttpConnectionPool.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/HttpConnectionPool.cs index 2b6ae06651122b..e356c0306aba42 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/HttpConnectionPool.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/HttpConnectionPool.cs @@ -35,6 +35,7 @@ internal sealed partial class HttpConnectionPool : IDisposable private readonly HttpConnectionPoolManager _poolManager; private readonly HttpConnectionKind _kind; private readonly Uri? _proxyUri; + private readonly string? _telemetryServerAddress; /// The origin authority used to construct the . private readonly HttpAuthority _originAuthority; @@ -72,12 +73,14 @@ internal sealed partial class HttpConnectionPool : IDisposable /// The port with which this pool is associated. /// The SSL host with which this pool is associated. /// The proxy this pool targets (optional). - public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionKind kind, string? host, int port, string? sslHostName, Uri? proxyUri) + /// The value of the 'server.address' tag to be emitted by Metrics and Distributed Tracing. + public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionKind kind, string? host, int port, string? sslHostName, Uri? proxyUri, string? telemetryServerAddress) { _poolManager = poolManager; _kind = kind; _proxyUri = proxyUri; _maxHttp11Connections = Settings._maxConnectionsPerServer; + _telemetryServerAddress = telemetryServerAddress; // The only case where 'host' will not be set is if this is a Proxy connection pool. Debug.Assert(host is not null || (kind == HttpConnectionKind.Proxy && proxyUri is not null)); @@ -279,6 +282,7 @@ private static SslClientAuthenticationOptions ConstructSslOptions(HttpConnection return sslOptions; } + public string? TelemetryServerAddress => _telemetryServerAddress; public HttpAuthority OriginAuthority => _originAuthority; public HttpConnectionSettings Settings => _poolManager.Settings; public HttpConnectionKind Kind => _kind; @@ -557,7 +561,7 @@ public async ValueTask SendWithVersionDetectionAndRetryAsyn Exception? exception = null; TransportContext? transportContext = null; - Activity? activity = ConnectionSetupDistributedTracing.StartConnectionSetupActivity(IsSecure, OriginAuthority); + Activity? activity = ConnectionSetupDistributedTracing.StartConnectionSetupActivity(IsSecure, _telemetryServerAddress, OriginAuthority.Port); try { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthWriteStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthWriteStream.cs index 077fc8c6d5d3cb..071caa567b1383 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthWriteStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthWriteStream.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; @@ -39,7 +40,7 @@ public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationTo if (BytesWritten > _contentLength) { - return ValueTask.FromException(new HttpRequestException(SR.net_http_content_write_larger_than_content_length)); + return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new HttpRequestException(SR.net_http_content_write_larger_than_content_length))); } HttpConnection connection = GetConnectionOrThrow(); @@ -51,7 +52,7 @@ public override Task FinishAsync(bool async) { if (BytesWritten != _contentLength) { - return Task.FromException(new HttpRequestException(SR.Format(SR.net_http_request_content_length_mismatch, BytesWritten, _contentLength))); + return Task.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new HttpRequestException(SR.Format(SR.net_http_request_content_length_mismatch, BytesWritten, _contentLength)))); } _connection = null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs index 9b48f6790bda7f..5acf3d76e513cd 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs @@ -9,6 +9,7 @@ using System.Net.Http.Headers; using System.Net.Http.HPack; using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; using System.Text; using System.Threading; using System.Threading.Channels; @@ -1197,7 +1198,7 @@ private Task PerformWriteAsync(int writeBytes, T state, Func, // As such, it should not matter that we were not able to actually send the frame. // But just in case, throw ObjectDisposedException. Asynchronous callers will ignore the failure. Debug.Assert(_shutdown && _streamsInUse == 0); - return Task.FromException(new ObjectDisposedException(nameof(Http2Connection))); + return Task.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Http2Connection)))); } return writeEntry.Task; @@ -2173,7 +2174,7 @@ private static void ThrowRetry(string message, Exception? innerException = null) throw new HttpRequestException((innerException as HttpIOException)?.HttpRequestError ?? HttpRequestError.Unknown, message, innerException, RequestRetryType.RetryOnConnectionFailure); private static Exception GetRequestAbortedException(Exception? innerException = null) => - innerException as HttpIOException ?? new IOException(SR.net_http_request_aborted, innerException); + innerException as HttpIOException ?? ExceptionDispatchInfo.SetCurrentStackTrace(new IOException(SR.net_http_request_aborted, innerException)); [DoesNotReturn] private static void ThrowRequestAborted(Exception? innerException = null) => diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs index 4b1f4ccb3ee695..c39b070c15bb28 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs @@ -1503,7 +1503,7 @@ public Http2ReadStream(Http2Stream http2Stream) : base(http2Stream, closeRespons public override void Write(ReadOnlySpan buffer) => throw new NotSupportedException(SR.net_http_content_readonly_stream); - public override ValueTask WriteAsync(ReadOnlyMemory destination, CancellationToken cancellationToken) => ValueTask.FromException(new NotSupportedException(SR.net_http_content_readonly_stream)); + public override ValueTask WriteAsync(ReadOnlyMemory destination, CancellationToken cancellationToken) => ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new NotSupportedException(SR.net_http_content_readonly_stream))); } private sealed class Http2WriteStream : Http2ReadWriteStream @@ -1522,11 +1522,11 @@ public Http2WriteStream(Http2Stream http2Stream, long contentLength) : base(http public override int Read(Span buffer) => throw new NotSupportedException(SR.net_http_content_writeonly_stream); - public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken) => ValueTask.FromException(new NotSupportedException(SR.net_http_content_writeonly_stream)); + public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken) => ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new NotSupportedException(SR.net_http_content_writeonly_stream))); public override void CopyTo(Stream destination, int bufferSize) => throw new NotSupportedException(SR.net_http_content_writeonly_stream); - public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) => Task.FromException(new NotSupportedException(SR.net_http_content_writeonly_stream)); + public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) => Task.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new NotSupportedException(SR.net_http_content_writeonly_stream))); public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken) { @@ -1534,7 +1534,7 @@ public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationTo if ((ulong)BytesWritten > (ulong)ContentLength) // If ContentLength == -1, this will always be false { - return ValueTask.FromException(new HttpRequestException(SR.net_http_content_write_larger_than_content_length)); + return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new HttpRequestException(SR.net_http_content_write_larger_than_content_length))); } return base.WriteAsync(buffer, cancellationToken); @@ -1643,7 +1643,7 @@ public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationTo if (http2Stream == null) { - return ValueTask.FromException(new ObjectDisposedException(nameof(Http2WriteStream))); + return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Http2WriteStream)))); } return http2Stream.SendDataAsync(buffer, cancellationToken); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs index f5087936c59724..a9718781324c8e 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs @@ -1524,7 +1524,7 @@ public override ValueTask ReadAsync(Memory buffer, CancellationToken if (stream is null) { - return ValueTask.FromException(new ObjectDisposedException(nameof(Http3RequestStream))); + return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Http3RequestStream)))); } Debug.Assert(_response != null); @@ -1577,7 +1577,7 @@ public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationTo if (stream is null) { - return ValueTask.FromException(new ObjectDisposedException(nameof(Http3WriteStream))); + return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Http3WriteStream)))); } return stream.WriteRequestContentAsync(buffer, cancellationToken); @@ -1589,7 +1589,7 @@ public override Task FlushAsync(CancellationToken cancellationToken) if (stream is null) { - return Task.FromException(new ObjectDisposedException(nameof(Http3WriteStream))); + return Task.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Http3WriteStream)))); } return stream.FlushSendBufferAsync(endStream: false, cancellationToken).AsTask(); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs index 786aff42b94a76..d92131e892a0a4 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs @@ -69,11 +69,12 @@ protected void MarkConnectionAsEstablished(Activity? connectionSetupActivity, IP this is Http2Connection ? "2" : "3"; + Debug.Assert(_pool.TelemetryServerAddress is not null, "TelemetryServerAddress should not be null when System.Diagnostics.Metrics.Meter.IsSupported is true."); _connectionMetrics = new ConnectionMetrics( metrics, protocol, _pool.IsSecure ? "https" : "http", - _pool.OriginAuthority.HostValue, + _pool.TelemetryServerAddress, _pool.OriginAuthority.Port, remoteEndPoint?.Address?.ToString()); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs index 8424d1b26cebe2..a696e153ca5c89 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs @@ -227,35 +227,6 @@ public void Dispose() public HttpConnectionSettings Settings => _settings; public ICredentials? ProxyCredentials => _proxyCredentials; - private static string ParseHostNameFromHeader(string hostHeader) - { - // See if we need to trim off a port. - int colonPos = hostHeader.IndexOf(':'); - if (colonPos >= 0) - { - // There is colon, which could either be a port separator or a separator in - // an IPv6 address. See if this is an IPv6 address; if it's not, use everything - // before the colon as the host name, and if it is, use everything before the last - // colon iff the last colon is after the end of the IPv6 address (otherwise it's a - // part of the address). - int ipV6AddressEnd = hostHeader.IndexOf(']'); - if (ipV6AddressEnd == -1) - { - return hostHeader.Substring(0, colonPos); - } - else - { - colonPos = hostHeader.LastIndexOf(':'); - if (colonPos > ipV6AddressEnd) - { - return hostHeader.Substring(0, colonPos); - } - } - } - - return hostHeader; - } - private HttpConnectionKey GetConnectionKey(HttpRequestMessage request, Uri? proxyUri, bool isProxyConnect) { Uri? uri = request.RequestUri; @@ -273,7 +244,7 @@ private HttpConnectionKey GetConnectionKey(HttpRequestMessage request, Uri? prox string? hostHeader = request.Headers.Host; if (hostHeader != null) { - sslHostName = ParseHostNameFromHeader(hostHeader); + sslHostName = HttpUtilities.ParseHostNameFromHeader(hostHeader); } else { @@ -330,6 +301,34 @@ private HttpConnectionKey GetConnectionKey(HttpRequestMessage request, Uri? prox } } + // Picks the value of the 'server.address' tag following rules specified in + // https://github.com/open-telemetry/semantic-conventions/blob/728e5d1/docs/http/http-spans.md#http-client-span + // When there is no proxy, we need to prioritize the contents of the Host header. + private static string? GetTelemetryServerAddress(HttpRequestMessage request, HttpConnectionKey key) + { + if (GlobalHttpSettings.MetricsHandler.IsGloballyEnabled || GlobalHttpSettings.DiagnosticsHandler.EnableActivityPropagation) + { + Uri? uri = request.RequestUri; + Debug.Assert(uri is not null); + + if (key.SslHostName is not null) + { + return key.SslHostName; + } + + if (key.ProxyUri is not null && key.Kind == HttpConnectionKind.Proxy) + { + // In case there is no tunnel, return the proxy address since the connection is shared. + return key.ProxyUri.IdnHost; + } + + string? hostHeader = request.Headers.Host; + return hostHeader is null ? uri.IdnHost : HttpUtilities.ParseHostNameFromHeader(hostHeader); + } + + return null; + } + public ValueTask SendAsyncCore(HttpRequestMessage request, Uri? proxyUri, bool async, bool doRequestAuth, bool isProxyConnect, CancellationToken cancellationToken) { HttpConnectionKey key = GetConnectionKey(request, proxyUri, isProxyConnect); @@ -337,7 +336,7 @@ public ValueTask SendAsyncCore(HttpRequestMessage request, HttpConnectionPool? pool; while (!_pools.TryGetValue(key, out pool)) { - pool = new HttpConnectionPool(this, key.Kind, key.Host, key.Port, key.SslHostName, key.ProxyUri); + pool = new HttpConnectionPool(this, key.Kind, key.Host, key.Port, key.SslHostName, key.ProxyUri, GetTelemetryServerAddress(request, key)); if (_cleaningTimer == null) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs index beadbc77f17082..b4006543504d70 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs @@ -149,11 +149,9 @@ public HttpConnectionSettings CloneAndNormalize() public bool EnableMultipleHttp3Connections => _enableMultipleHttp3Connections; - private byte[]? _http3SettingsFrame; - [SupportedOSPlatform("windows")] [SupportedOSPlatform("linux")] [SupportedOSPlatform("macos")] - internal byte[] Http3SettingsFrame => _http3SettingsFrame ??= Http3Connection.BuildSettingsFrame(this); + internal byte[] Http3SettingsFrame => field ??= Http3Connection.BuildSettingsFrame(this); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpUtilities.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpUtilities.SocketsHttpHandler.cs similarity index 97% rename from src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpUtilities.cs rename to src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpUtilities.SocketsHttpHandler.cs index be47d560ea77e1..ed5f1c14459716 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpUtilities.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpUtilities.SocketsHttpHandler.cs @@ -3,7 +3,7 @@ namespace System.Net.Http { - internal static class HttpUtilities + internal static partial class HttpUtilities { internal static bool IsSupportedScheme(string scheme) => IsSupportedNonSecureScheme(scheme) || diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Metrics/SocketsHttpHandlerMetrics.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Metrics/SocketsHttpHandlerMetrics.cs index 8933aa5c3fd23b..eabd5db88de69f 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Metrics/SocketsHttpHandlerMetrics.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Metrics/SocketsHttpHandlerMetrics.cs @@ -46,7 +46,9 @@ public void RequestLeftQueue(HttpRequestMessage request, HttpConnectionPool pool }); tags.Add("url.scheme", pool.IsSecure ? "https" : "http"); - tags.Add("server.address", pool.OriginAuthority.HostValue); + + Debug.Assert(pool.TelemetryServerAddress is not null, "TelemetryServerAddress should not be null when System.Diagnostics.Metrics.Meter.IsSupported is true."); + tags.Add("server.address", pool.TelemetryServerAddress); if (!pool.IsDefaultPort) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs index 19f4197ccd26d6..4d4fccd7033d2b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs @@ -8,6 +8,7 @@ using System.IO; using System.Net.Http.Metrics; using System.Net.Security; +using System.Runtime.ExceptionServices; using System.Runtime.Versioning; using System.Text; using System.Threading; @@ -527,14 +528,14 @@ private HttpMessageHandlerStage SetupHandlerChain() // metric is recorded before stopping the request Activity. This is needed to make sure that our telemetry supports Exemplars. if (GlobalHttpSettings.MetricsHandler.IsGloballyEnabled) { - handler = new MetricsHandler(handler, settings._meterFactory, out Meter meter); + handler = new MetricsHandler(handler, settings._meterFactory, settings._proxy, out Meter meter); settings._metrics = new SocketsHttpHandlerMetrics(meter); } // DiagnosticsHandler is inserted before RedirectHandler so that trace propagation is done on redirects as well if (GlobalHttpSettings.DiagnosticsHandler.EnableActivityPropagation && settings._activityHeadersPropagator is DistributedContextPropagator propagator) { - handler = new DiagnosticsHandler(handler, propagator, settings._allowAutoRedirect); + handler = new DiagnosticsHandler(handler, propagator, settings._proxy, settings._allowAutoRedirect); } if (settings._allowAutoRedirect) @@ -634,7 +635,7 @@ async Task CreateHandlerAndSendAsync(HttpRequestMessage req { if (request.Version != HttpVersion.Version10 && request.Version != HttpVersion.Version11 && request.Version != HttpVersion.Version20 && request.Version != HttpVersion.Version30) { - return new NotSupportedException(SR.net_http_unsupported_version); + return ExceptionDispatchInfo.SetCurrentStackTrace(new NotSupportedException(SR.net_http_unsupported_version)); } // Add headers to define content transfer, if not present @@ -642,8 +643,8 @@ async Task CreateHandlerAndSendAsync(HttpRequestMessage req { if (request.Content == null) { - return new HttpRequestException(SR.net_http_client_execution_error, - new InvalidOperationException(SR.net_http_chunked_not_allowed_with_empty_content)); + return ExceptionDispatchInfo.SetCurrentStackTrace(new HttpRequestException(SR.net_http_client_execution_error, + ExceptionDispatchInfo.SetCurrentStackTrace(new InvalidOperationException(SR.net_http_chunked_not_allowed_with_empty_content)))); } // Since the user explicitly set TransferEncodingChunked to true, we need to remove @@ -661,7 +662,7 @@ async Task CreateHandlerAndSendAsync(HttpRequestMessage req // HTTP 1.0 does not support chunking if (request.Headers.TransferEncodingChunked == true) { - return new NotSupportedException(SR.net_http_unsupported_chunking); + return ExceptionDispatchInfo.SetCurrentStackTrace(new NotSupportedException(SR.net_http_unsupported_chunking)); } // HTTP 1.0 does not support Expect: 100-continue; just disable it. @@ -674,12 +675,12 @@ async Task CreateHandlerAndSendAsync(HttpRequestMessage req Uri? requestUri = request.RequestUri; if (requestUri is null || !requestUri.IsAbsoluteUri) { - return new InvalidOperationException(SR.net_http_client_invalid_requesturi); + return ExceptionDispatchInfo.SetCurrentStackTrace(new InvalidOperationException(SR.net_http_client_invalid_requesturi)); } if (!HttpUtilities.IsSupportedScheme(requestUri.Scheme)) { - return new NotSupportedException(SR.Format(SR.net_http_unsupported_requesturi_scheme, requestUri.Scheme)); + return ExceptionDispatchInfo.SetCurrentStackTrace(new NotSupportedException(SR.Format(SR.net_http_unsupported_requesturi_scheme, requestUri.Scheme))); } return null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpHandler.cs index 1003b63b2dc9d3..e4fd54308d9bfe 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpHandler.cs @@ -148,8 +148,7 @@ internal sealed class WasiHttpHandler : HttpMessageHandler public const bool SupportsProxy = false; public const bool SupportsRedirectConfiguration = false; - private Dictionary? _properties; - public IDictionary Properties => _properties ??= new Dictionary(); + public IDictionary Properties => field ??= new Dictionary(); protected internal override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/DiagnosticsTests.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/DiagnosticsTests.cs index ffc8cc7fdd93ce..0c15d23e312ce4 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/DiagnosticsTests.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/DiagnosticsTests.cs @@ -1406,6 +1406,27 @@ await GetFactoryForVersion(UseVersion).CreateClientAndServerAsync( }); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + [InlineData("A B", "Foo", typeof(FormatException))] // Invalid header name + [InlineData("Content-Length", "42", typeof(InvalidOperationException))] // Invalid header name for the request headers collection + [InlineData("Foo", "Bar\nBaz", typeof(FormatException))] // Invalid header value + public async Task SendAsync_PropagatorInjectsInvalidHeaders_Throws(string headerName, string headerValue, Type exceptionType) + { + using Activity parent = new Activity("parent"); + parent.SetIdFormat(ActivityIdFormat.W3C); + parent.Start(); + + using var handler = CreateSocketsHttpHandler(allowAllCertificates: true); + handler.ActivityHeadersPropagator = new DelegatingPropagator([headerName], (activity, carrier, setter) => setter(carrier, headerName, headerValue)); + + using var client = new HttpClient(handler); + + // Url doesn't matter since the request should fail before hitting the network. + var request = CreateRequest(HttpMethod.Get, new Uri("https://microsoft.com"), UseVersion, exactVersion: true); + + await Assert.ThrowsAsync(exceptionType, () => client.SendAsync(TestAsync, request)); + } + public static IEnumerable SocketsHttpHandler_ActivityCreation_MemberData() { foreach (var currentActivitySet in new bool[] { @@ -1665,6 +1686,112 @@ static async Task RunTest() } } + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [InlineData(false)] + [InlineData(true)] + public async Task UseIPAddressInTargetUri_NoProxy_RecordsHostHeaderAsServerAddress(bool useTls) + { + if (UseVersion == HttpVersion30 && !useTls) return; + + await RemoteExecutor.Invoke(RunTest, UseVersion.ToString(), TestAsync.ToString(), useTls.ToString()).DisposeAsync(); + static async Task RunTest(string useVersion, string testAsync, string useTlsString) + { + bool useTls = bool.Parse(useTlsString); + + Activity parentActivity = new Activity("parent").Start(); + + using ActivityRecorder requestRecorder = new("System.Net.Http", "System.Net.Http.HttpRequestOut") + { + ExpectedParent = parentActivity + }; + + using ActivityRecorder connectionSetupRecorder = new("Experimental.System.Net.Http.Connections", "Experimental.System.Net.Http.Connections.ConnectionSetup"); + + await GetFactoryForVersion(useVersion).CreateClientAndServerAsync( + async uri => + { + string hostName = uri.Host; + uri = new Uri($"{uri.Scheme}://{IPAddress.Loopback}:{uri.Port}"); + + Version version = Version.Parse(useVersion); + + using HttpClient client = new HttpClient(CreateHttpClientHandler(allowAllCertificates: true)); + + using HttpRequestMessage request = CreateRequest(HttpMethod.Get, uri, version, exactVersion: true); + request.Headers.Host = hostName; + + await client.SendAsync(bool.Parse(testAsync), request); + + Activity req = requestRecorder.VerifyActivityRecordedOnce(); + ActivityAssert.HasTag(req, "server.address", hostName); + + Activity conn = connectionSetupRecorder.VerifyActivityRecordedOnce(); + ActivityAssert.HasTag(conn, "server.address", hostName); + }, + async server => + { + await server.AcceptConnectionSendResponseAndCloseAsync(); + }, options: new GenericLoopbackOptions() + { + UseSsl = useTls, + }); + } + } + + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public async Task UseIPAddressInTargetUri_ProxyTunnel() + { + if (UseVersion != HttpVersion.Version11) + { + throw new SkipTestException("Test only for HTTP/1.1"); + } + + await RemoteExecutor.Invoke(RunTest, UseVersion.ToString(), TestAsync.ToString()).DisposeAsync(); + static async Task RunTest(string useVersion, string testAsync) + { + Activity parentActivity = new Activity("parent").Start(); + + using ActivityRecorder requestRecorder = new("System.Net.Http", "System.Net.Http.HttpRequestOut") + { + ExpectedParent = parentActivity + }; + + using ActivityRecorder connectionSetupRecorder = new("Experimental.System.Net.Http.Connections", "Experimental.System.Net.Http.Connections.ConnectionSetup"); + + using LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(); + await GetFactoryForVersion(useVersion).CreateClientAndServerAsync( + async uri => + { + uri = new Uri($"{uri.Scheme}://{IPAddress.Loopback}:{uri.Port}"); + + Version version = Version.Parse(useVersion); + + HttpClientHandler handler = CreateHttpClientHandler(allowAllCertificates: true); + handler.Proxy = new WebProxy(proxyServer.Uri); + using HttpClient client = new HttpClient(handler); + + using HttpRequestMessage request = CreateRequest(HttpMethod.Get, uri, version, exactVersion: true); + request.Headers.Host = "localhost"; + + await client.SendAsync(bool.Parse(testAsync), request); + + // There should be only one Activity for the request. Server address should match the Uri host. + // https://github.com/open-telemetry/semantic-conventions/blob/728e5d1/docs/http/http-spans.md#http-client-span + ActivityAssert.HasTag(requestRecorder.FinishedActivities.Single(), "server.address", IPAddress.Loopback.ToString()); + + // Check the SslProxyTunnel connection only, it should use the host header. + Assert.Contains(connectionSetupRecorder.FinishedActivities, a => a.TagObjects.Any(t => t.Key == "server.port" && t.Value.Equals(uri.Port))); + }, + async server => + { + await server.AcceptConnectionSendResponseAndCloseAsync(); + }, options: new GenericLoopbackOptions() + { + UseSsl = true, + }); + } + } + private static T GetProperty(object obj, string propertyName) { Type t = obj.GetType(); @@ -1749,5 +1876,20 @@ private static void AssertHeadersAreInjected(HttpRequestData request, Activity p var request = CreateRequest(HttpMethod.Get, uri, Version.Parse(useVersion), exactVersion: true); return (request, await client.SendAsync(bool.Parse(testAsync), request, cancellationToken)); } + + private sealed class DelegatingPropagator(string[] fields, Action inject) : DistributedContextPropagator + { + public override IReadOnlyCollection Fields => fields; + + public override IEnumerable>? ExtractBaggage(object? carrier, PropagatorGetterCallback? getter) => []; + + public override void ExtractTraceIdAndState(object? carrier, PropagatorGetterCallback? getter, out string? traceId, out string? traceState) + { + traceId = null; + traceState = null; + } + + public override void Inject(Activity? activity, object? carrier, PropagatorSetterCallback? setter) => inject(activity, carrier, setter); + } } } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs index 48d72d48880133..199517d313b1e1 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs @@ -5,11 +5,10 @@ using System.IO; using System.Linq; using System.Net.Http.Headers; -using System.Net.Quic; using System.Net.Test.Common; using System.Text; using System.Threading.Tasks; - +using Microsoft.DotNet.XUnitExtensions; using Xunit; using Xunit.Abstractions; @@ -160,7 +159,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => // Client should abort at some point so this is going to throw. HttpRequestData requestData = await server.HandleRequestAsync(HttpStatusCode.OK).ConfigureAwait(false); } - catch (Exception) { }; + catch (Exception) { } + ; }); } @@ -595,5 +595,59 @@ await connection.SendResponseAsync(HttpStatusCode.OK, }); }); } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + [InlineData(false, "test\nxwow\nmore\n", false)] + [InlineData(false, "test\rwow\rmore\r\n", false)] + [InlineData(true, "one\0two\0three\0", false)] + [InlineData(false, "test\nxwow\nmore\n", true)] + [InlineData(false, "test\rwow\rmore\r\n", true)] + [InlineData(true, "one\0two\0three\0", true)] + public async Task SendAsync_InvalidCharactersInResponseHeader_ReplacedWithSpaces(bool testHttp11, string value, bool testTrailers) + { + if (!testHttp11 && UseVersion == HttpVersion.Version11) + { + throw new SkipTestException("This case is not valid for HTTP 1.1"); + } + + string expectedValue = value.Replace('\r', ' ').Replace('\n', ' ').Replace('\0', ' '); + await LoopbackServerFactory.CreateClientAndServerAsync( + async uri => + { + using HttpClient client = CreateHttpClient(); + + using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri) + { + Version = UseVersion, + VersionPolicy = HttpVersionPolicy.RequestVersionExact + }; + + using HttpResponseMessage response = await client.SendAsync(request); + HttpResponseHeaders headerCollection = testTrailers ? response.TrailingHeaders : response.Headers; + Assert.Equal(expectedValue, headerCollection.GetValues("test").Single()); + }, + async server => + { + List? headers = testTrailers ? null : [new HttpHeaderData("test", value)]; + List? trailers = testTrailers ? [new HttpHeaderData("test", value)] : null; + string content = "hello"; + + if (testTrailers && UseVersion == HttpVersion.Version11) + { + headers = [new HttpHeaderData("Transfer-Encoding", "chunked")]; + content = $"{content.Length:X}\r\n{content}\r\n"; + } + + await server.AcceptConnectionAsync(async connection => + { + await connection.ReadRequestDataAsync(); + await connection.SendResponseAsync(headers: headers, content: content, isFinal: trailers is null); + if (trailers is { }) + { + await connection.SendResponseHeadersAsync(headers: trailers, isTrailingHeader: true); + } + }); + }); + } } } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs index 1a24fe7e0832ad..e96eb1fe25dc25 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs @@ -254,7 +254,7 @@ public async Task Http2_DataFrameOnlyPadding_Success() [InlineData("Client content", "Server content")] [InlineData(null, null)] [InlineData(null, "Server content")] - public async Task Http2ClearText_SendAsync_Success(string clientContent, string serverContent) + public async Task Http2ClearText_SendAsync_Success(string? clientContent, string? serverContent) { await Http2LoopbackServer.CreateClientAndServerAsync(async uri => { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs index dfbf9ee89beea0..aeae11532594f3 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs @@ -21,7 +21,7 @@ namespace System.Net.Http.Functional.Tests { - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class HttpClientHandlerTest_Http3 : HttpClientHandlerTestBase { protected override Version UseVersion => HttpVersion.Version30; diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs index 220e6706fcf168..662fd3479ce1a3 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs @@ -30,13 +30,14 @@ protected static async Task DefaultConnectCallback(EndPoint endPoint, Ca protected static bool IsWinHttpHandler => false; - public static bool IsQuicSupported + public static bool IsHttp3Supported { get { try { - return QuicConnection.IsSupported; + return QuicConnection.IsSupported + && (bool)Type.GetType("System.Net.Http.GlobalHttpSettings+SocketsHttpHandler, System.Net.Http").GetProperty("AllowHttp3").GetValue(null); } catch (System.PlatformNotSupportedException) { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientMiniStressTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientMiniStressTest.cs index a0844444705d71..b739faf0dd72d8 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientMiniStressTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientMiniStressTest.cs @@ -31,7 +31,7 @@ public void CreateAndDestroyManyClients(int numClients) } } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandler_HttpClientMiniStress_Http3 : HttpClientMiniStress { public SocketsHttpHandler_HttpClientMiniStress_Http3(ITestOutputHelper output) : base(output) { } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs index 52e5900376fcdb..27666715f97847 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs @@ -246,7 +246,7 @@ public async Task Properties_CantChangeAfterOperation_Throws() [Theory] [InlineData(null)] [InlineData("/something.html")] - public void GetAsync_NoBaseAddress_InvalidUri_ThrowsException(string uri) + public void GetAsync_NoBaseAddress_InvalidUri_ThrowsException(string? uri) { using (var client = new HttpClient(new CustomResponseHandler((r, c) => Task.FromResult(new HttpResponseMessage())))) { @@ -257,7 +257,7 @@ public void GetAsync_NoBaseAddress_InvalidUri_ThrowsException(string uri) [Theory] [InlineData(null)] [InlineData("/")] - public async Task GetAsync_BaseAddress_ValidUri_Success(string uri) + public async Task GetAsync_BaseAddress_ValidUri_Success(string? uri) { using (var client = new HttpClient(new CustomResponseHandler((r, c) => Task.FromResult(new HttpResponseMessage())))) { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs index c1cbd3540a823d..bbe6c0bfbf9fb9 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs @@ -920,6 +920,57 @@ await server.AcceptConnectionAsync(async conn => }); } + [ConditionalTheory(typeof(SocketsHttpHandler), nameof(SocketsHttpHandler.IsSupported))] + [InlineData(false)] + [InlineData(true)] + public Task UseIPAddressInTargetUri_NoProxy_RecordsHostHeaderAsServerAddress(bool useTls) + { + if (UseVersion == HttpVersion30 && !useTls) + { + throw new SkipTestException("No insecure connections with HTTP/3."); + } + + return LoopbackServerFactory.CreateClientAndServerAsync(async uri => + { + using HttpMessageInvoker client = CreateHttpMessageInvoker(); + uri = new Uri($"{uri.Scheme}://{IPAddress.Loopback}:{uri.Port}"); + + using InstrumentRecorder activeRequestsRecorder = SetupInstrumentRecorder(InstrumentNames.ActiveRequests); + using InstrumentRecorder requestDurationRecorder = SetupInstrumentRecorder(InstrumentNames.RequestDuration); + using InstrumentRecorder openConnectionsRecorder = SetupInstrumentRecorder(InstrumentNames.OpenConnections); + using InstrumentRecorder connectionDurationRecorder = SetupInstrumentRecorder(InstrumentNames.ConnectionDuration); + using InstrumentRecorder timeInQueueRecorder = SetupInstrumentRecorder(InstrumentNames.TimeInQueue); + + using HttpRequestMessage request = new(HttpMethod.Get, uri) { Version = UseVersion, VersionPolicy = HttpVersionPolicy.RequestVersionExact }; + request.Headers.Host = "localhost"; + HttpResponseMessage response = await SendAsync(client, request); + response.Dispose(); // Make sure disposal doesn't interfere with recording by enforcing early disposal. + + // Request metrics: + VerifyHostName(activeRequestsRecorder); + VerifyHostName(requestDurationRecorder); + + // Connection metrics: + VerifyHostName(openConnectionsRecorder); + VerifyHostName(connectionDurationRecorder); + VerifyHostName(timeInQueueRecorder); + }, async server => + { + await server.AcceptConnectionSendResponseAndCloseAsync(); + }, options: new GenericLoopbackOptions() + { + UseSsl = useTls, + }); + + static void VerifyHostName(InstrumentRecorder recorder) where T : struct + { + foreach (Measurement m in recorder.GetMeasurements()) + { + VerifyTag(m.Tags.ToArray(), "server.address", "localhost"); + } + } + } + protected override void Dispose(bool disposing) { if (disposing) @@ -1158,6 +1209,47 @@ await server.AcceptConnectionAsync(async connection => }, new LoopbackServer.Options() { UseSsl = true }); } + + [ConditionalFact(typeof(SocketsHttpHandler), nameof(SocketsHttpHandler.IsSupported))] + public async Task UseIPAddressInTargetUri_ProxyTunnel_RequestMetricsRecordUriHostAsServerAddress() + { + using LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(); + await LoopbackServerFactory.CreateClientAndServerAsync( + async uri => + { + uri = new Uri($"{uri.Scheme}://{IPAddress.Loopback}:{uri.Port}"); + + //HttpClientHandler handler = CreateHttpClientHandler(allowAllCertificates: true); + Handler.Proxy = new WebProxy(proxyServer.Uri); + using HttpMessageInvoker client = CreateHttpMessageInvoker(); + using HttpRequestMessage request = CreateRequest(HttpMethod.Get, uri, UseVersion, exactVersion: true); + request.Headers.Host = "localhost"; + + using InstrumentRecorder activeRequestsRecorder = SetupInstrumentRecorder(InstrumentNames.ActiveRequests); + using InstrumentRecorder requestDurationRecorder = SetupInstrumentRecorder(InstrumentNames.RequestDuration); + + (await SendAsync(client, request)).Dispose(); + + // Request metrics: + VerifyHostName(activeRequestsRecorder, uri.Host); + VerifyHostName(requestDurationRecorder, uri.Host); + }, + async server => + { + await server.AcceptConnectionSendResponseAndCloseAsync(); + }, options: new GenericLoopbackOptions() + { + UseSsl = true, + }); + + void VerifyHostName(InstrumentRecorder recorder, string hostName) where T : struct + { + foreach (Measurement m in recorder.GetMeasurements()) + { + VerifyTag(m.Tags.ToArray(), "server.address", hostName); + } + } + } } [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMobile))] @@ -1346,7 +1438,7 @@ public HttpMetricsTest_Http20_HttpMessageInvoker(ITestOutputHelper output) : bas } } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public class HttpMetricsTest_Http30 : HttpMetricsTest { protected override Version UseVersion => HttpVersion.Version30; diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/ResponseStreamZeroByteReadTests.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/ResponseStreamZeroByteReadTests.cs index 8fe520464e5784..1f6ad745e82e04 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/ResponseStreamZeroByteReadTests.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/ResponseStreamZeroByteReadTests.cs @@ -181,7 +181,7 @@ public Http2ResponseStreamZeroByteReadTest(ITestOutputHelper output) : base(outp protected override Version UseVersion => HttpVersion.Version20; } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class Http3ResponseStreamZeroByteReadTest : ResponseStreamZeroByteReadTestBase { public Http3ResponseStreamZeroByteReadTest(ITestOutputHelper output) : base(output) { } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index 2577094cb52b4e..f5877a3bd2e286 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -124,7 +124,7 @@ public SocketsHttpHandler_HttpClientHandler_Asynchrony_Test_Http2(ITestOutputHel protected override Version UseVersion => HttpVersion.Version20; } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandler_HttpClientHandler_Asynchrony_Test_Http3 : SocketsHttpHandler_HttpClientHandler_Asynchrony_Test { public SocketsHttpHandler_HttpClientHandler_Asynchrony_Test_Http3(ITestOutputHelper output) : base(output) { } @@ -331,7 +331,7 @@ public SocketsHttpHandler_DiagnosticsTest_Http2(ITestOutputHelper output) : base protected override Version UseVersion => HttpVersion.Version20; } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandler_DiagnosticsTest_Http3 : DiagnosticsTest { public SocketsHttpHandler_DiagnosticsTest_Http3(ITestOutputHelper output) : base(output) { } @@ -1248,7 +1248,7 @@ public async Task Http2GetAsync_TrailerHeaders_TrailingPseudoHeadersThrow() } } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandler_Http3_TrailingHeaders_Test : SocketsHttpHandler_TrailingHeaders_Test { public SocketsHttpHandler_Http3_TrailingHeaders_Test(ITestOutputHelper output) : base(output) { } @@ -1702,11 +1702,16 @@ from lineFolds in BoolValues private delegate int StreamReadSpanDelegate(Span buffer); - [Theory] + [ConditionalTheory] [MemberData(nameof(TripleBoolValues))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/77474", TestPlatforms.Android)] public async Task LargeHeaders_TrickledOverTime_ProcessedEfficiently(bool trailingHeaders, bool async, bool lineFolds) { + if (PlatformDetection.IsAndroid && PlatformDetection.Is32BitProcess) + { + // https://github.com/dotnet/runtime/issues/77474 + throw new SkipTestException("This test runs out of memory on 32-bit Android devices"); + } + Memory responsePrefix = Encoding.ASCII.GetBytes(trailingHeaders ? "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n0\r\nLong-Header: " : "HTTP/1.1 200 OK\r\nContent-Length: 0\r\nLong-Header: "); @@ -1815,7 +1820,7 @@ public SocketsHttpHandler_HttpClientHandler_MaxResponseHeadersLength_Http2(ITest protected override Version UseVersion => HttpVersion.Version20; } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandler_HttpClientHandler_MaxResponseHeadersLength_Http3 : SocketsHttpHandler_HttpClientHandler_MaxResponseHeadersLength { public SocketsHttpHandler_HttpClientHandler_MaxResponseHeadersLength_Http3(ITestOutputHelper output) : base(output) { } @@ -2535,7 +2540,7 @@ public void SslOptions_GetSet_Roundtrips() Assert.True(options.AllowRenegotiation); Assert.Null(options.ApplicationProtocols); - Assert.Equal(X509RevocationMode.Online, options.CertificateRevocationCheckMode); + Assert.Equal(X509RevocationMode.NoCheck, options.CertificateRevocationCheckMode); Assert.Null(options.ClientCertificates); Assert.Equal(SslProtocols.None, options.EnabledSslProtocols); Assert.Equal(EncryptionPolicy.RequireEncryption, options.EncryptionPolicy); @@ -4197,42 +4202,42 @@ public SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http2(ITestOutputH protected override Version UseVersion => HttpVersion.Version20; } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandlerTest_HttpClientHandlerTest_Http3 : HttpClientHandlerTest { public SocketsHttpHandlerTest_HttpClientHandlerTest_Http3(ITestOutputHelper output) : base(output) { } protected override Version UseVersion => HttpVersion.Version30; } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandlerTest_Cookies_Http3 : HttpClientHandlerTest_Cookies { public SocketsHttpHandlerTest_Cookies_Http3(ITestOutputHelper output) : base(output) { } protected override Version UseVersion => HttpVersion.Version30; } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandlerTest_HttpClientHandlerTest_Headers_Http3 : HttpClientHandlerTest_Headers { public SocketsHttpHandlerTest_HttpClientHandlerTest_Headers_Http3(ITestOutputHelper output) : base(output) { } protected override Version UseVersion => HttpVersion.Version30; } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http3 : SocketsHttpHandler_Cancellation_Test { public SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http3(ITestOutputHelper output) : base(output) { } protected override Version UseVersion => HttpVersion.Version30; } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandler_HttpClientHandler_AltSvc_Test_Http3 : HttpClientHandler_AltSvc_Test { public SocketsHttpHandler_HttpClientHandler_AltSvc_Test_Http3(ITestOutputHelper output) : base(output) { } protected override Version UseVersion => HttpVersion.Version30; } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandler_HttpClientHandler_Finalization_Http3 : HttpClientHandler_Finalization_Test { public SocketsHttpHandler_HttpClientHandler_Finalization_Http3(ITestOutputHelper output) : base(output) { } @@ -4389,7 +4394,7 @@ public SocketsHttpHandler_RequestContentLengthMismatchTest_Http2(ITestOutputHelp protected override Version UseVersion => HttpVersion.Version20; } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandler_RequestContentLengthMismatchTest_Http3 : SocketsHttpHandler_RequestContentLengthMismatchTest { public SocketsHttpHandler_RequestContentLengthMismatchTest_Http3(ITestOutputHelper output) : base(output) { } @@ -4573,7 +4578,7 @@ public SocketsHttpHandler_SocketsHttpHandler_SecurityTest_Http2(ITestOutputHelpe protected override Version UseVersion => HttpVersion.Version20; } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandler_SocketsHttpHandler_SecurityTest_Http3 : SocketsHttpHandler_SecurityTest, IClassFixture { public SocketsHttpHandler_SocketsHttpHandler_SecurityTest_Http3(ITestOutputHelper output, CertificateSetup certificateSetup) : base(output, certificateSetup) { } @@ -4701,7 +4706,7 @@ await Http11LoopbackServerFactory.Singleton.CreateClientAndServerAsync(async uri } } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class SocketsHttpHandler_HttpRequestErrorTest_Http30 : SocketsHttpHandler_HttpRequestErrorTest { public SocketsHttpHandler_HttpRequestErrorTest_Http30(ITestOutputHelper output) : base(output) { } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/TelemetryTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/TelemetryTest.cs index 27c29456346db2..85587cac87156e 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/TelemetryTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/TelemetryTest.cs @@ -1175,7 +1175,7 @@ public sealed class TelemetryTest_Http20 : TelemetryTest public TelemetryTest_Http20(ITestOutputHelper output) : base(output) { } } - [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] + [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsHttp3Supported))] public sealed class TelemetryTest_Http30 : TelemetryTest { protected override Version UseVersion => HttpVersion.Version30; diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/CacheControlHeaderValueTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/CacheControlHeaderValueTest.cs index 6d9d50acde4d3a..8a5a2b99057b7f 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/Headers/CacheControlHeaderValueTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/CacheControlHeaderValueTest.cs @@ -643,7 +643,7 @@ public void Parse_SetOfInvalidValueStrings_Throws() [InlineData(",")] [InlineData(",,")] [InlineData(" , , ")] - public void CacheControlHeaderValue_EmptyValue_Parsed(string value) + public void CacheControlHeaderValue_EmptyValue_Parsed(string? value) { Assert.NotNull(CacheControlHeaderValue.Parse(value)); diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/HeaderEncodingTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HeaderEncodingTest.cs index d7f41e0deeee61..d4ff2108475d4a 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/Headers/HeaderEncodingTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HeaderEncodingTest.cs @@ -1,37 +1,85 @@ // 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; using System.Net.Http.Headers; using System.Text; +using Microsoft.DotNet.XUnitExtensions; using Xunit; namespace System.Net.Http.Tests { public class HeaderEncodingTest { - [Theory] - [InlineData("")] - [InlineData("foo")] - [InlineData("\uD83D\uDE03")] - [InlineData("\0")] - [InlineData("\x01")] - [InlineData("\xFF")] - [InlineData("\uFFFF")] - [InlineData("\uFFFD")] - [InlineData("\uD83D\uDE48\uD83D\uDE49\uD83D\uDE4A")] - public void RoundTripsUtf8(string input) + public static readonly TheoryData RoundTrips_Data = new TheoryData { - byte[] encoded = Encoding.UTF8.GetBytes(input); + { "", null }, + { "foo", null }, + { "\uD83D\uDE03", null }, + { "\x01", null }, + { "\xFF", null }, + { "\uFFFF", null }, + { "\uFFFD", null }, + { "\uD83D\uDE48\uD83D\uDE49\uD83D\uDE4A", null }, + { "\0", null }, + { "abc\056", null }, + { "abc\rq", null }, + { "abc\r\n", null }, + { "abc\rfoo", null }, + + { "", "UTF-8" }, + { "foo", "UTF-8" }, + { "\uD83D\uDE03", "UTF-8" }, + { "\x01", "UTF-8" }, + { "\xFF", "UTF-8" }, + { "\uFFFF", "UTF-8" }, + { "\uFFFD", "UTF-8" }, + { "\uD83D\uDE48\uD83D\uDE49\uD83D\uDE4A", "UTF-8" }, + { "\0", "UTF-8" }, + { "abc\056", "UTF-8" }, + { "abc\rq", "UTF-8" }, + { "abc\r\n", "UTF-8" }, + { "abc\rfoo", "UTF-8" }, + + // Fixed, multi byte encodings are discouraged, but we want them to function at HeaderDescriptor level. + { "", "UTF-16" }, + { "foo", "UTF-16" }, + { "\uD83D\uDE03", "UTF-16" }, + { "\x01", "UTF-16" }, + { "\xFF", "UTF-16" }, + { "\uFFFF", "UTF-16" }, + { "\uFFFD", "UTF-16" }, + { "\uD83D\uDE48\uD83D\uDE49\uD83D\uDE4A", "UTF-16" }, + { "\0", "UTF-16" }, + { "abc\056", "UTF-16" }, + { "abc\rq", "UTF-16" }, + { "abc\r\n", "UTF-16" }, + { "abc\rfoo", "UTF-16" }, + }; + + [ConditionalTheory] + [MemberData(nameof(RoundTrips_Data))] + public void GetHeaderValue_RoundTrips_ReplacesDangerousCharacters(string input, string? encodingName) + { + bool isUnicode = input.Any(c => c > 255); + if (isUnicode && encodingName == null) + { + throw new SkipTestException("The test case is invalid for the default encoding."); + } + + Encoding encoding = encodingName == null ? null : Encoding.GetEncoding(encodingName); + byte[] encoded = (encoding ?? Encoding.Latin1).GetBytes(input); + string expectedValue = input.Replace('\0', ' ').Replace('\r', ' ').Replace('\n', ' '); Assert.True(HeaderDescriptor.TryGet("custom-header", out HeaderDescriptor descriptor)); Assert.Null(descriptor.KnownHeader); - string roundtrip = descriptor.GetHeaderValue(encoded, Encoding.UTF8); - Assert.Equal(input, roundtrip); + string roundtrip = descriptor.GetHeaderValue(encoded, encoding); + Assert.Equal(expectedValue, roundtrip); Assert.True(HeaderDescriptor.TryGet("Cache-Control", out descriptor)); Assert.NotNull(descriptor.KnownHeader); - roundtrip = descriptor.GetHeaderValue(encoded, Encoding.UTF8); - Assert.Equal(input, roundtrip); + roundtrip = descriptor.GetHeaderValue(encoded, encoding); + Assert.Equal(expectedValue, roundtrip); } } } diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeadersTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeadersTest.cs index 44495c9593c66c..70615e7b8ad527 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeadersTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeadersTest.cs @@ -85,7 +85,7 @@ public void TryAddWithoutValidation_AddInvalidViaHeaderValue_ValuePassed() [Theory] [InlineData(null)] [InlineData("")] - public void TryAddWithoutValidation_UseEmptyHeaderName_False(string headerName) + public void TryAddWithoutValidation_UseEmptyHeaderName_False(string? headerName) { MockHeaders headers = new MockHeaders(); Assert.False(headers.TryAddWithoutValidation(headerName, "value")); @@ -1149,7 +1149,7 @@ public void Remove_RemoveNonExistingHeader_ReturnsFalse() [Theory] [InlineData(null)] [InlineData("")] - public void TryGetValues_UseEmptyHeaderName_False(string headerName) + public void TryGetValues_UseEmptyHeaderName_False(string? headerName) { MockHeaders headers = new MockHeaders(); diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/KnownHeadersTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/KnownHeadersTest.cs index aac0f0fec5d1c3..d4c645812cd03a 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/Headers/KnownHeadersTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/KnownHeadersTest.cs @@ -41,6 +41,7 @@ public class KnownHeadersTest [InlineData("Content-Type")] [InlineData("Cookie")] [InlineData("Cookie2")] + [InlineData("Cross-Origin-Resource-Policy")] [InlineData("Date")] [InlineData("ETag")] [InlineData("Expect")] @@ -85,6 +86,7 @@ public class KnownHeadersTest [InlineData("Set-Cookie2")] [InlineData("Strict-Transport-Security")] [InlineData("TE")] + [InlineData("Timing-Allow-Origin")] [InlineData("Trailer")] [InlineData("Transfer-Encoding")] [InlineData("TSV")] @@ -103,6 +105,7 @@ public class KnownHeadersTest [InlineData("X-MSEdge-Ref")] [InlineData("X-Powered-By")] [InlineData("X-Request-ID")] + [InlineData("X-Served-By")] [InlineData("X-UA-Compatible")] [InlineData("X-XSS-Protection")] public void TryGetKnownHeader_Known_Found(string name) @@ -168,17 +171,30 @@ public void TryGetKnownHeader_Unknown_NotFound(string name) [InlineData("Content-Type", "text/html")] [InlineData("Content-Type", "text/plain")] [InlineData("Content-Type", "image/jpeg")] + [InlineData("Content-Type", "image/webp")] + [InlineData("Content-Type", "image/svg+xml")] + [InlineData("Content-Type", "text/javascript")] [InlineData("Content-Type", "application/pdf")] [InlineData("Content-Type", "application/xml")] [InlineData("Content-Type", "application/zip")] [InlineData("Content-Type", "application/grpc")] [InlineData("Content-Type", "application/json")] + [InlineData("Content-Type", "text/event-stream")] [InlineData("Content-Type", "multipart/form-data")] [InlineData("Content-Type", "application/javascript")] + [InlineData("Content-Type", "text/html;charset=utf-8")] + [InlineData("Content-Type", "text/html;charset=UTF-8")] [InlineData("Content-Type", "application/octet-stream")] [InlineData("Content-Type", "text/html; charset=utf-8")] [InlineData("Content-Type", "text/html; charset=UTF-8")] + [InlineData("Content-Type", "text/plain;charset=utf-8")] + [InlineData("Content-Type", "text/plain;charset=UTF-8")] [InlineData("Content-Type", "text/plain; charset=utf-8")] + [InlineData("Content-Type", "text/plain; charset=UTF-8")] + [InlineData("Content-Type", "text/html; charset=ISO-8859-1")] + [InlineData("Content-Type", "text/html; charset=iso-8859-1")] + [InlineData("Content-Type", "text/javascript; charset=utf-8")] + [InlineData("Content-Type", "text/javascript; charset=UTF-8")] [InlineData("Content-Type", "application/json; charset=utf-8")] [InlineData("Content-Type", "application/x-www-form-urlencoded")] [InlineData("Expect", "100-continue")] @@ -207,8 +223,6 @@ public void TryGetKnownHeader_Unknown_NotFound(string name) [InlineData("Upgrade-Insecure-Requests", "1")] [InlineData("Vary", "*")] [InlineData("X-Content-Type-Options", "nosniff")] - [InlineData("X-Frame-Options", "DENY")] - [InlineData("X-Frame-Options", "SAMEORIGIN")] [InlineData("X-XSS-Protection", "0")] [InlineData("X-XSS-Protection", "1")] [InlineData("X-XSS-Protection", "1; mode=block")] diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/NameValueHeaderValueTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/NameValueHeaderValueTest.cs index f9078d3736d1ca..dea8b38d6fd332 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/Headers/NameValueHeaderValueTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/NameValueHeaderValueTest.cs @@ -44,7 +44,7 @@ public void Ctor_NameInvalidFormat_ThrowFormatException(string value) [InlineData("host", "server.example.com:80")] [InlineData("quoted", "\"value\"")] [InlineData("empty", "")] - public void Ctor_NameValidFormat_SuccessfullyCreated(string name, string value) + public void Ctor_NameValidFormat_SuccessfullyCreated(string name, string? value) { NameValueHeaderValue nameValue = new NameValueHeaderValue(name, value); Assert.Equal(name, nameValue.Name); diff --git a/src/libraries/System.Net.Http/tests/UnitTests/HttpEnvironmentProxyTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/HttpEnvironmentProxyTest.cs index a263f95bb27d85..9e91d2743e8b92 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/HttpEnvironmentProxyTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/HttpEnvironmentProxyTest.cs @@ -145,7 +145,7 @@ await RemoteExecutor.Invoke(() => [InlineData("socks5://1.2.3.4:8888/foo", "1.2.3.4", "8888", null, null)] [InlineData("https://1.1.1.5:3005", "1.1.1.5", "3005", null, null)] [InlineData("https://1.1.1.5", "1.1.1.5", "443", null, null)] - public async Task HttpProxy_Uri_Parsing(string _input, string _host, string _port, string _user, string _password) + public async Task HttpProxy_Uri_Parsing(string _input, string _host, string _port, string? _user, string? _password) { await RemoteExecutor.Invoke((input, host, port, user, password) => { diff --git a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj index 40eacbfd8e6e08..be119816ef4532 100755 --- a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj @@ -1,4 +1,4 @@ - + ../../src/Resources/Strings.resx true @@ -77,6 +77,8 @@ Link="ProductionCode\System\Net\Http\GlobalHttpSettings.cs"/> + - + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj b/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj index b00428cd035a3b..5f7c136659e1bf 100644 --- a/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj +++ b/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj @@ -14,31 +14,6 @@ $(DefineConstants);TARGET_WINDOWS - - - - - - - - - - - - - - - - - - - - - - - - - @@ -190,8 +165,34 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerRequest.Windows.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerRequest.Windows.cs index dcce980482ae01..6e4738a660b999 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerRequest.Windows.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerRequest.Windows.cs @@ -25,7 +25,6 @@ public sealed unsafe partial class HttpListenerRequest private readonly string? _cookedUrlPath; private readonly string? _cookedUrlQuery; private long _contentLength; - private Stream? _requestStream; private string? _httpMethod; private WebHeaderCollection? _webHeaders; private IPEndPoint? _localEndPoint; @@ -206,7 +205,7 @@ public string HttpMethod } } - public Stream InputStream => _requestStream ??= HasEntityBody ? new HttpRequestStream(HttpListenerContext) : Stream.Null; + public Stream InputStream => field ??= HasEntityBody ? new HttpRequestStream(HttpListenerContext) : Stream.Null; public bool IsAuthenticated { diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerAuthenticationTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerAuthenticationTests.cs index 900fea85114181..0e947993237bf5 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerAuthenticationTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerAuthenticationTests.cs @@ -111,7 +111,7 @@ public static IEnumerable BasicAuthenticationHeader_TestData() [InlineData(" ExampleRealm ")] [InlineData("")] [InlineData(null)] - public async Task BasicAuthentication_RealmSet_SendsChallengeToClient(string realm) + public async Task BasicAuthentication_RealmSet_SendsChallengeToClient(string? realm) { _listener.Realm = realm; _listener.AuthenticationSchemes = AuthenticationSchemes.Basic; diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerRequestTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerRequestTests.cs index 1f2057a9480536..d55eaf48a5845d 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerRequestTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerRequestTests.cs @@ -35,7 +35,7 @@ public void Dispose() [InlineData("Accept: Test, Test2,Test3 , Test4", new string[] { "Test", "Test2", "Test3 ", " Test4" })] [InlineData("Accept: ", new string[] { "" })] [InlineData("Unknown-Header: ", null)] - public async Task AcceptTypes_GetProperty_ReturnsExpected(string acceptString, string[] expected) + public async Task AcceptTypes_GetProperty_ReturnsExpected(string acceptString, string[]? expected) { HttpListenerRequest request = await GetRequest("POST", "", new string[] { acceptString }); Assert.Equal(request.AcceptTypes, request.AcceptTypes); @@ -164,7 +164,7 @@ public async Task ContentLength_SetInHeadersAfterAccessingProperty_DoesNothing() [InlineData("Referer: ", "")] [InlineData("Referer: http://microsoft.com<>", null)] [InlineData("Unknown-Header: ", null)] - public async Task Referer_GetProperty_ReturnsExpected(string refererString, string expected) + public async Task Referer_GetProperty_ReturnsExpected(string refererString, string? expected) { HttpListenerRequest request = await GetRequest("POST", "", new string[] { refererString }); Assert.Equal(expected, request.UrlReferrer?.ToString()); @@ -175,7 +175,7 @@ public async Task Referer_GetProperty_ReturnsExpected(string refererString, stri [InlineData("user-agent: Test", "Test")] [InlineData("User-Agent: ", "")] [InlineData("Unknown-Header: Test", null)] - public async Task UserAgent_GetProperty_ReturnsExpected(string userAgentString, string expected) + public async Task UserAgent_GetProperty_ReturnsExpected(string userAgentString, string? expected) { HttpListenerRequest request = await GetRequest("POST", "", new string[] { userAgentString }); Assert.Equal(expected, request.UserAgent); @@ -246,7 +246,7 @@ public async Task IsWebSocketRequest_GetProperty_ReturnsExpected(string webSocke [InlineData("Accept-Language:", new string[] { "" })] [InlineData("Accept-Language: ", new string[] { "" })] [InlineData("Unknown-Header: Test", null)] - public async Task UserLanguages_GetProperty_ReturnsExpected(string userLanguageString, string[] expected) + public async Task UserLanguages_GetProperty_ReturnsExpected(string userLanguageString, string[]? expected) { HttpListenerRequest request = await GetRequest("POST", "", new string[] { userLanguageString }); Assert.Equal(request.UserLanguages, request.UserLanguages); diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.Headers.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.Headers.cs index 36327b28998075..356add431e6140 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.Headers.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.Headers.cs @@ -159,7 +159,7 @@ public async Task ContentType_SetAndSend_Success(string contentType, int expecte [InlineData(null, null)] [InlineData("", null)] [InlineData("\r \t \n", "")] - public async Task ContentType_SetNullEmptyOrWhitespace_ResetsContentType(string contentType, string expectedContentType) + public async Task ContentType_SetNullEmptyOrWhitespace_ResetsContentType(string? contentType, string? expectedContentType) { using (HttpListenerResponse response = await GetResponse()) { @@ -232,7 +232,7 @@ public async Task RedirectLocation_SetAndSend_Success(string redirectLocation, i [InlineData(null, null)] [InlineData("", null)] [InlineData("\r \t \n", "")] - public async Task RedirectLocation_SetNullOrEmpty_ResetsRedirectLocation(string redirectLocation, string expectedRedirectLocation) + public async Task RedirectLocation_SetNullOrEmpty_ResetsRedirectLocation(string? redirectLocation, string? expectedRedirectLocation) { using (HttpListenerResponse response = await GetResponse()) { diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs index 75baedd07e4a11..e8c731a55abaa8 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs @@ -113,7 +113,7 @@ public async Task CopyFrom_NullTemplateResponse_ThrowsNullReferenceException() [InlineData(" \r \t \n", 123)] [InlineData("http://microsoft.com", 155)] [InlineData(" http://microsoft.com ", 155)] - public async Task Redirect_Invoke_SetsRedirectionProperties(string url, int expectedNumberOfBytes) + public async Task Redirect_Invoke_SetsRedirectionProperties(string? url, int expectedNumberOfBytes) { string expectedUrl = url?.Trim() ?? ""; diff --git a/src/libraries/System.Net.Mail/System.Net.Mail.slnx b/src/libraries/System.Net.Mail/System.Net.Mail.slnx index 8bc0871e0ed701..0eb97778a786c1 100644 --- a/src/libraries/System.Net.Mail/System.Net.Mail.slnx +++ b/src/libraries/System.Net.Mail/System.Net.Mail.slnx @@ -1,53 +1,938 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj b/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj index faa3d9aa5abc67..2052b5a3558690 100644 --- a/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj +++ b/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj @@ -108,20 +108,20 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Mail/src/System/Net/Base64Stream.cs b/src/libraries/System.Net.Mail/src/System/Net/Base64Stream.cs index 83dfbb84cf0417..61456f5ea9986a 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Base64Stream.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Base64Stream.cs @@ -35,7 +35,6 @@ internal sealed class Base64Stream : DelegatedStream, IEncodableStream ]; private readonly Base64WriteStateInfo _writeState; - private ReadStateInfo? _readState; private readonly Base64Encoder _encoder; //bytes with this value in the decode map are invalid @@ -56,7 +55,7 @@ internal Base64Stream(Base64WriteStateInfo writeStateInfo) : base(new MemoryStre public override bool CanRead => BaseStream.CanRead; public override bool CanWrite => BaseStream.CanWrite; - private ReadStateInfo ReadState => _readState ??= new ReadStateInfo(); + private ReadStateInfo ReadState => field ??= new ReadStateInfo(); internal WriteStateInfoBase WriteState { diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailPriority.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailPriority.cs index f45299e71152ed..be70ab7b91a530 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailPriority.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailPriority.cs @@ -23,11 +23,8 @@ internal sealed class Message private MailAddress? _from; private MailAddress? _sender; - private MailAddressCollection? _replyToList; private MailAddress? _replyTo; private MailAddressCollection? _to; - private MailAddressCollection? _cc; - private MailAddressCollection? _bcc; private MimeBasePart? _content; private HeaderCollection? _headers; private HeaderCollection? _envelopeHeaders; @@ -118,13 +115,13 @@ internal MailAddress? ReplyTo } } - internal MailAddressCollection ReplyToList => _replyToList ??= new MailAddressCollection(); + internal MailAddressCollection ReplyToList => field ??= new MailAddressCollection(); internal MailAddressCollection To => _to ??= new MailAddressCollection(); - internal MailAddressCollection Bcc => _bcc ??= new MailAddressCollection(); + internal MailAddressCollection Bcc => field ??= new MailAddressCollection(); - internal MailAddressCollection CC => _cc ??= new MailAddressCollection(); + internal MailAddressCollection CC => field ??= new MailAddressCollection(); internal string? Subject diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpTransport.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpTransport.cs index 9f75bad2dfbc3f..6d678d0f5800ac 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpTransport.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpTransport.cs @@ -22,7 +22,6 @@ internal sealed class SmtpTransport private bool _shouldAbort; private bool _enableSsl; - private X509CertificateCollection? _clientCertificates; internal SmtpTransport(SmtpClient client) : this(client, SmtpAuthenticationManager.GetModules()) { @@ -68,7 +67,7 @@ internal bool EnableSsl } } - internal X509CertificateCollection ClientCertificates => _clientCertificates ??= new X509CertificateCollection(); + internal X509CertificateCollection ClientCertificates => field ??= new X509CertificateCollection(); internal bool ServerSupportsEai { diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mime/EightBitStream.cs b/src/libraries/System.Net.Mail/src/System/Net/Mime/EightBitStream.cs index ae92cf7aeb8def..39f1f673ba37d1 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mime/EightBitStream.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mime/EightBitStream.cs @@ -26,14 +26,12 @@ namespace System.Net.Mime /// internal sealed class EightBitStream : DelegatedStream, IEncodableStream { - private WriteStateInfoBase? _writeState; - // Should we do RFC 2821 Section 4.5.2 encoding of leading dots on a line? // We make this optional because this stream may be used recursively and // the encoding should only be done once. private readonly bool _shouldEncodeLeadingDots; - private WriteStateInfoBase WriteState => _writeState ??= new WriteStateInfoBase(); + private WriteStateInfoBase WriteState => field ??= new WriteStateInfoBase(); /// /// ctor. diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mime/MimeMultiPart.cs b/src/libraries/System.Net.Mail/src/System/Net/Mime/MimeMultiPart.cs index e0ffef86590615..4d5a45725a646f 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mime/MimeMultiPart.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mime/MimeMultiPart.cs @@ -13,7 +13,6 @@ namespace System.Net.Mime { internal sealed class MimeMultiPart : MimeBasePart { - private Collection? _parts; private static int s_boundary; internal MimeMultiPart(MimeMultiPartType type) @@ -39,7 +38,7 @@ private void SetType(MimeMultiPartType type) ContentType.Boundary = GetNextBoundary(); } - internal Collection Parts => _parts ??= new Collection(); + internal Collection Parts => field ??= new Collection(); internal override async Task SendAsync(BaseWriter writer, bool allowUnicode, CancellationToken cancellationToken = default) { diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mime/QEncodedStream.cs b/src/libraries/System.Net.Mail/src/System/Net/Mime/QEncodedStream.cs index cafb9b0577e4ff..5b85a1c2c6aceb 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mime/QEncodedStream.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mime/QEncodedStream.cs @@ -39,7 +39,6 @@ internal sealed class QEncodedStream : DelegatedStream, IEncodableStream 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // F ]; - private ReadStateInfo? _readState; private readonly WriteStateInfoBase _writeState; private readonly QEncoder _encoder; @@ -49,7 +48,7 @@ internal QEncodedStream(WriteStateInfoBase wsi) : base(new MemoryStream()) _encoder = new QEncoder(_writeState); } - private ReadStateInfo ReadState => _readState ??= new ReadStateInfo(); + private ReadStateInfo ReadState => field ??= new ReadStateInfo(); internal WriteStateInfoBase WriteState => _writeState; diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mime/QuotedPrintableStream.cs b/src/libraries/System.Net.Mail/src/System/Net/Mime/QuotedPrintableStream.cs index 773e12b430f6c5..cc193d3479f8c5 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mime/QuotedPrintableStream.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mime/QuotedPrintableStream.cs @@ -58,7 +58,6 @@ internal sealed class QuotedPrintableStream : DelegatedStream, IEncodableStream private static ReadOnlySpan HexEncodeMap => "0123456789ABCDEF"u8; private readonly int _lineLength; - private ReadStateInfo? _readState; private WriteStateInfoBase? _writeState; /// @@ -81,7 +80,7 @@ internal QuotedPrintableStream(Stream stream, bool encodeCRLF) : this(stream, En public override bool CanRead => false; public override bool CanWrite => BaseStream.CanWrite; - private ReadStateInfo ReadState => _readState ??= new ReadStateInfo(); + private ReadStateInfo ReadState => field ??= new ReadStateInfo(); internal WriteStateInfoBase WriteState => _writeState ??= new WriteStateInfoBase(1024, null, null, _lineLength); diff --git a/src/libraries/System.Net.Mail/tests/Functional/ContentDispositionTest.cs b/src/libraries/System.Net.Mail/tests/Functional/ContentDispositionTest.cs index 2f25ed2bf8f12e..ff77e380603992 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/ContentDispositionTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/ContentDispositionTest.cs @@ -50,7 +50,7 @@ public void ConstructorWithOtherPropertyValues_ShouldSetAppropriately() [InlineData(typeof(ArgumentNullException), null)] [InlineData(typeof(FormatException), "inline; creation-date=\"" + InvalidDate + "\";")] [InlineData(typeof(FormatException), "inline; size=\"notANumber\"")] - public static void Ctor_InvalidThrows(Type exceptionType, string contentDisposition) + public static void Ctor_InvalidThrows(Type exceptionType, string? contentDisposition) { Assert.Throws(exceptionType, () => new ContentDisposition(contentDisposition)); } @@ -58,7 +58,7 @@ public static void Ctor_InvalidThrows(Type exceptionType, string contentDisposit [Theory] [InlineData(typeof(ArgumentNullException), null)] [InlineData(typeof(ArgumentException), "")] - public static void DispositionType_SetValue_InvalidThrows(Type exceptionType, string contentDisposition) + public static void DispositionType_SetValue_InvalidThrows(Type exceptionType, string? contentDisposition) { Assert.Throws(exceptionType, () => new ContentDisposition().DispositionType = contentDisposition); } diff --git a/src/libraries/System.Net.Mail/tests/Functional/ContentTypeTest.cs b/src/libraries/System.Net.Mail/tests/Functional/ContentTypeTest.cs index 603b910696c64d..97a52b85bfaac0 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/ContentTypeTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/ContentTypeTest.cs @@ -27,7 +27,7 @@ public static void DefaultCtor_ExpectedDefaultPropertyValues() [InlineData("text/plain; boundary=hello; charset=us-ascii; name=world", "text/plain", "us-ascii", "hello", "world")] [InlineData("text/plain; charset=us-ascii; name=world", "text/plain", "us-ascii", null, "world")] public static void Ctor_ContentString_ParsedValueMatchesExpected( - string contentType, string expectedMediaType, string expectedCharSet, string expectedBoundary, string expectedName) + string contentType, string expectedMediaType, string? expectedCharSet, string? expectedBoundary, string? expectedName) { var ct = new ContentType(contentType); Assert.Equal(expectedMediaType, ct.MediaType); @@ -58,7 +58,7 @@ public static void Ctor_ContentString_ParsedValueMatchesExpected( [InlineData(typeof(FormatException), "text/plain; charset=iso-8859-1; q=1.0, */xml; charset=utf-8; q=0.5")] [InlineData(typeof(FormatException), " , */xml; charset=utf-8; q=0.5 ")] [InlineData(typeof(FormatException), "text/plain; charset=iso-8859-1; q=1.0 , ")] - public static void Ctor_InvalidContentType_Throws(Type exceptionType, string contentType) + public static void Ctor_InvalidContentType_Throws(Type exceptionType, string? contentType) { Assert.Throws(exceptionType, () => new ContentType(contentType)); } diff --git a/src/libraries/System.Net.Mail/tests/Functional/LoopbackSmtpServer.cs b/src/libraries/System.Net.Mail/tests/Functional/LoopbackSmtpServer.cs index 5cd541638b23b0..6d585c91042bcb 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/LoopbackSmtpServer.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/LoopbackSmtpServer.cs @@ -333,8 +333,7 @@ public class ParsedMailMessage public string Cc => GetHeader("Cc"); public string Subject => GetHeader("Subject"); - private ContentType _contentType; - public ContentType ContentType => _contentType ??= new ContentType(GetHeader("Content-Type")); + public ContentType ContentType => field ??= new ContentType(GetHeader("Content-Type")); private ParsedMailMessage(Dictionary headers, string body, string rawBody, List attachments) { diff --git a/src/libraries/System.Net.Mail/tests/Functional/SmtpClientSendMailTest.cs b/src/libraries/System.Net.Mail/tests/Functional/SmtpClientSendMailTest.cs index a65a4d63d05dcb..1f08beefa410af 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/SmtpClientSendMailTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/SmtpClientSendMailTest.cs @@ -42,7 +42,7 @@ public async Task ServerDoesntExist_Throws() [InlineData(null)] [SkipOnCoreClr("System.Net.Tests are flaky and/or long running: https://github.com/dotnet/runtime/issues/131", ~RuntimeConfiguration.Release)] [ActiveIssue("https://github.com/dotnet/runtime/issues/131", TestRuntimes.Mono)] // System.Net.Tests are flaky and/or long running - public async Task MailDelivery(string body) + public async Task MailDelivery(string? body) { Smtp.Credentials = new NetworkCredential("foo", "bar"); MailMessage msg = new MailMessage("foo@example.com", "bar@example.com", "hello", body); diff --git a/src/libraries/System.Net.Mail/tests/Functional/SmtpClientSpecifiedPickupDirectoryTest.cs b/src/libraries/System.Net.Mail/tests/Functional/SmtpClientSpecifiedPickupDirectoryTest.cs index 595cb2eecdf0ef..16279b7a116aea 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/SmtpClientSpecifiedPickupDirectoryTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/SmtpClientSpecifiedPickupDirectoryTest.cs @@ -82,7 +82,7 @@ public async Task Send_SpecifiedPickupDirectory_MessageBodyDoesNotEncodeForTrans [InlineData("")] [InlineData(null)] [InlineData("\0abc")] - public async Task Send_SpecifiedPickupDirectoryInvalid(string location) + public async Task Send_SpecifiedPickupDirectoryInvalid(string? location) { Smtp.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory; Smtp.PickupDirectoryLocation = location; diff --git a/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs b/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs index a7f80b45a61691..7acc7195fa70ab 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs @@ -163,7 +163,7 @@ public void ServicePoint_ReflectsHostAndPortChange() [InlineData("shouldnotexist")] [InlineData("\0")] [InlineData("C:\\some\\path\\like\\string")] - public void PickupDirectoryLocationTest(string folder) + public void PickupDirectoryLocationTest(string? folder) { Smtp.PickupDirectoryLocation = folder; Assert.Equal(folder, Smtp.PickupDirectoryLocation); diff --git a/src/libraries/System.Net.NameResolution/System.Net.NameResolution.slnx b/src/libraries/System.Net.NameResolution/System.Net.NameResolution.slnx index d31378b110cc55..daecfaf79aade1 100644 --- a/src/libraries/System.Net.NameResolution/System.Net.NameResolution.slnx +++ b/src/libraries/System.Net.NameResolution/System.Net.NameResolution.slnx @@ -1,36 +1,474 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj b/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj index 582fe6cc882413..090f939b329777 100644 --- a/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj +++ b/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj @@ -134,19 +134,19 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.NetworkInformation/System.Net.NetworkInformation.slnx b/src/libraries/System.Net.NetworkInformation/System.Net.NetworkInformation.slnx index 95a6b7aba685f0..30c63322741f6e 100644 --- a/src/libraries/System.Net.NetworkInformation/System.Net.NetworkInformation.slnx +++ b/src/libraries/System.Net.NetworkInformation/System.Net.NetworkInformation.slnx @@ -1,35 +1,530 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj b/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj index 20e6095db84303..f4eb734ae8cf06 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj +++ b/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj @@ -220,21 +220,21 @@ - - - - - - - - - - - + + + + + + + + + + + - + diff --git a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/LinuxIPv4InterfaceProperties.cs b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/LinuxIPv4InterfaceProperties.cs index de7b309e48022f..bf6e7b02fb986e 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/LinuxIPv4InterfaceProperties.cs +++ b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/LinuxIPv4InterfaceProperties.cs @@ -35,13 +35,13 @@ public LinuxIPv4InterfaceProperties(LinuxNetworkInterface linuxNetworkInterface) private bool GetIsForwardingEnabled() { - string[] paths = new string[] - { + ReadOnlySpan paths = + [ // /proc/sys/net/ipv4/conf//forwarding Path.Join(NetworkFiles.Ipv4ConfigFolder, _linuxNetworkInterface.Name, NetworkFiles.ForwardingFileName), // Fall back to global forwarding config /proc/sys/net/ipv4/ip_forward NetworkFiles.Ipv4GlobalForwardingFile - }; + ]; for (int i = 0; i < paths.Length; i++) { diff --git a/src/libraries/System.Net.Ping/System.Net.Ping.slnx b/src/libraries/System.Net.Ping/System.Net.Ping.slnx index 90677118c7284a..996318f1a4ca48 100644 --- a/src/libraries/System.Net.Ping/System.Net.Ping.slnx +++ b/src/libraries/System.Net.Ping/System.Net.Ping.slnx @@ -1,41 +1,770 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Ping/src/System.Net.Ping.csproj b/src/libraries/System.Net.Ping/src/System.Net.Ping.csproj index 0cfd246889fa19..baf06dc16d4fca 100644 --- a/src/libraries/System.Net.Ping/src/System.Net.Ping.csproj +++ b/src/libraries/System.Net.Ping/src/System.Net.Ping.csproj @@ -112,24 +112,24 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + - - + + diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs index a004b20d204f68..98403c5570e9d2 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs @@ -78,7 +78,7 @@ private static byte[] GetPingPayload(AddressFamily addressFamily) : Array.Empty(); public static bool DoesNotUsePingUtility => OperatingSystem.IsWindows() || - OperatingSystem.IsMacOS() || OperatingSystem.IsMacCatalyst() || OperatingSystem.IsWatchOS() || OperatingSystem.IsIOS() || OperatingSystem.IsTvOS() || + OperatingSystem.IsMacOS() || OperatingSystem.IsMacCatalyst() || OperatingSystem.IsIOS() || OperatingSystem.IsTvOS() || Capability.CanUseRawSockets(TestSettings.GetLocalIPAddress().AddressFamily); public static bool UsesPingUtility => !DoesNotUsePingUtility; @@ -885,7 +885,7 @@ public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions_ElevatedUnix( [InlineData(AddressFamily.InterNetworkV6, "ja_JP.UTF8", null, null)] [InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", "ja_JP.UTF8", null)] [InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", null, "ja_JP.UTF8")] - public async Task SendPing_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily, string envVar_LANG, string envVar_LC_MESSAGES, string envVar_LC_ALL) + public async Task SendPing_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily, string envVar_LANG, string? envVar_LC_MESSAGES, string? envVar_LC_ALL) { IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); if (localIpAddress == null) @@ -919,7 +919,7 @@ await RemoteExecutor.Invoke(address => [InlineData(AddressFamily.InterNetworkV6, "ja_JP.UTF8", null, null)] [InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", "ja_JP.UTF8", null)] [InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", null, "ja_JP.UTF8")] - public async Task SendPingAsync_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily, string envVar_LANG, string envVar_LC_MESSAGES, string envVar_LC_ALL) + public async Task SendPingAsync_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily, string envVar_LANG, string? envVar_LC_MESSAGES, string? envVar_LC_ALL) { IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); diff --git a/src/libraries/System.Net.Primitives/System.Net.Primitives.slnx b/src/libraries/System.Net.Primitives/System.Net.Primitives.slnx index 1adf38dac623b7..9db1a07d6cf02f 100644 --- a/src/libraries/System.Net.Primitives/System.Net.Primitives.slnx +++ b/src/libraries/System.Net.Primitives/System.Net.Primitives.slnx @@ -1,36 +1,346 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Primitives/src/Resources/Strings.resx b/src/libraries/System.Net.Primitives/src/Resources/Strings.resx index 65d4809398b3b2..c9cc5be51acdf2 100644 --- a/src/libraries/System.Net.Primitives/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Primitives/src/Resources/Strings.resx @@ -81,9 +81,6 @@ An invalid IP network was specified. - - The specified baseAddress has non-zero bits after the network prefix. - An error occurred when adding a cookie to the container. diff --git a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj index 81f974b735bb8b..ee2be350bb7387 100644 --- a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj +++ b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj @@ -163,15 +163,15 @@ - - - - - - - - - + + + + + + + + + diff --git a/src/libraries/System.Net.Primitives/src/System/Net/IPAddressParser.cs b/src/libraries/System.Net.Primitives/src/System/Net/IPAddressParser.cs index 2352c4f88397d2..e9485113f75826 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/IPAddressParser.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/IPAddressParser.cs @@ -194,6 +194,7 @@ static int FormatByte(uint number, Span addressString) internal static int FormatIPv6Address(ushort[] address, uint scopeId, Span destination) where TChar : unmanaged, IBinaryInteger { + Debug.Assert(typeof(TChar) == typeof(byte) || typeof(TChar) == typeof(char)); int pos = 0; if (IPv6AddressHelper.ShouldHaveIpv4Embedded(address)) @@ -220,18 +221,13 @@ internal static int FormatIPv6Address(ushort[] address, uint scopeId, Spa { destination[pos++] = TChar.CreateTruncating('%'); - // TODO https://github.com/dotnet/runtime/issues/84527: Use UInt32 TryFormat for both char and byte once IUtf8SpanFormattable implementation exists - Span chars = stackalloc TChar[10]; - int bytesPos = 10; - do - { - (scopeId, uint digit) = Math.DivRem(scopeId, 10); - chars[--bytesPos] = TChar.CreateTruncating('0' + digit); - } - while (scopeId != 0); - Span used = chars.Slice(bytesPos); - used.CopyTo(destination.Slice(pos)); - pos += used.Length; + int bytesWritten; + bool formatted = typeof(TChar) == typeof(byte) ? + scopeId.TryFormat(MemoryMarshal.Cast(destination).Slice(pos), out bytesWritten) : + scopeId.TryFormat(MemoryMarshal.Cast(destination).Slice(pos), out bytesWritten); + + Debug.Assert(formatted); + pos += bytesWritten; } return pos; diff --git a/src/libraries/System.Net.Primitives/src/System/Net/IPNetwork.cs b/src/libraries/System.Net.Primitives/src/System/Net/IPNetwork.cs index 5350d09b7e9100..52bd0c8cb902a8 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/IPNetwork.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/IPNetwork.cs @@ -50,26 +50,11 @@ public IPNetwork(IPAddress baseAddress, int prefixLength) ThrowArgumentOutOfRangeException(); } - if (HasNonZeroBitsAfterNetworkPrefix(baseAddress, prefixLength)) - { - ThrowInvalidBaseAddressException(); - } - - _baseAddress = baseAddress; + _baseAddress = ClearNonZeroBitsAfterNetworkPrefix(baseAddress, prefixLength); PrefixLength = prefixLength; [DoesNotReturn] static void ThrowArgumentOutOfRangeException() => throw new ArgumentOutOfRangeException(nameof(prefixLength)); - - [DoesNotReturn] - static void ThrowInvalidBaseAddressException() => throw new ArgumentException(SR.net_bad_ip_network_invalid_baseaddress, nameof(baseAddress)); - } - - // Non-validating ctor - private IPNetwork(IPAddress baseAddress, int prefixLength, bool _) - { - _baseAddress = baseAddress; - PrefixLength = prefixLength; } /// @@ -201,11 +186,10 @@ public static bool TryParse(ReadOnlySpan s, out IPNetwork result) if (IPAddress.TryParse(ipAddressSpan, out IPAddress? address) && int.TryParse(prefixLengthSpan, NumberStyles.None, CultureInfo.InvariantCulture, out int prefixLength) && - prefixLength <= GetMaxPrefixLength(address) && - !HasNonZeroBitsAfterNetworkPrefix(address, prefixLength)) + prefixLength <= GetMaxPrefixLength(address)) { Debug.Assert(prefixLength >= 0); // Parsing with NumberStyles.None should ensure that prefixLength is always non-negative. - result = new IPNetwork(address, prefixLength, false); + result = new IPNetwork(address, prefixLength); return true; } } @@ -230,11 +214,10 @@ public static bool TryParse(ReadOnlySpan utf8Text, out IPNetwork result) if (IPAddress.TryParse(ipAddressSpan, out IPAddress? address) && int.TryParse(prefixLengthSpan, NumberStyles.None, CultureInfo.InvariantCulture, out int prefixLength) && - prefixLength <= GetMaxPrefixLength(address) && - !HasNonZeroBitsAfterNetworkPrefix(address, prefixLength)) + prefixLength <= GetMaxPrefixLength(address)) { Debug.Assert(prefixLength >= 0); // Parsing with NumberStyles.None should ensure that prefixLength is always non-negative. - result = new IPNetwork(address, prefixLength, false); + result = new IPNetwork(address, prefixLength); return true; } } @@ -245,36 +228,51 @@ public static bool TryParse(ReadOnlySpan utf8Text, out IPNetwork result) private static int GetMaxPrefixLength(IPAddress baseAddress) => baseAddress.AddressFamily == AddressFamily.InterNetwork ? 32 : 128; - private static bool HasNonZeroBitsAfterNetworkPrefix(IPAddress baseAddress, int prefixLength) + private static IPAddress ClearNonZeroBitsAfterNetworkPrefix(IPAddress baseAddress, int prefixLength) { if (baseAddress.AddressFamily == AddressFamily.InterNetwork) { - // The cast to long ensures that the mask becomes 0 for the case where 'prefixLength == 0'. - uint mask = (uint)((long)uint.MaxValue << (32 - prefixLength)); + // Bitwise shift works only for lower 5-bits count operands. + if (prefixLength == 0) + { + // Corresponds to 0.0.0.0 + return IPAddress.Any; + } + + uint mask = uint.MaxValue << (32 - prefixLength); if (BitConverter.IsLittleEndian) { mask = BinaryPrimitives.ReverseEndianness(mask); } - return (baseAddress.PrivateAddress & mask) != baseAddress.PrivateAddress; + uint newAddress = baseAddress.PrivateAddress & mask; + return newAddress == baseAddress.PrivateAddress + ? baseAddress + : new IPAddress(newAddress); } else { - UInt128 value = default; - baseAddress.TryWriteBytes(MemoryMarshal.AsBytes(new Span(ref value)), out int bytesWritten); - Debug.Assert(bytesWritten == IPAddressParserStatics.IPv6AddressBytes); + // Bitwise shift works only for lower 7-bits count operands. if (prefixLength == 0) { - return value != UInt128.Zero; + // Corresponds to [::] + return IPAddress.IPv6Any; } + UInt128 value = default; + baseAddress.TryWriteBytes(MemoryMarshal.AsBytes(new Span(ref value)), out int bytesWritten); + Debug.Assert(bytesWritten == IPAddressParserStatics.IPv6AddressBytes); + UInt128 mask = UInt128.MaxValue << (128 - prefixLength); if (BitConverter.IsLittleEndian) { mask = BinaryPrimitives.ReverseEndianness(mask); } - return (value & mask) != value; + UInt128 newAddress = value & mask; + return newAddress == value + ? baseAddress + : new IPAddress(MemoryMarshal.AsBytes(new Span(ref newAddress))); } } diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest.cs b/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest.cs index 6a31011d3ca77a..e01a78b70c5f9c 100644 --- a/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest.cs +++ b/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest.cs @@ -166,7 +166,7 @@ public static void Name_GetSet_Success() [InlineData("hello=")] [InlineData("hello;")] [InlineData("hello,")] - public static void Name_Set_Invalid(string name) + public static void Name_Set_Invalid(string? name) { Cookie c = new Cookie(); Assert.Throws(() => c.Name = name); diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/IPNetworkTest.cs b/src/libraries/System.Net.Primitives/tests/FunctionalTests/IPNetworkTest.cs index ea8d31cd808f40..3547c24203de9d 100644 --- a/src/libraries/System.Net.Primitives/tests/FunctionalTests/IPNetworkTest.cs +++ b/src/libraries/System.Net.Primitives/tests/FunctionalTests/IPNetworkTest.cs @@ -1,9 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Buffers.Binary; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; +using System.Net.Sockets; +using System.Runtime.InteropServices; using System.Text; using Xunit; @@ -26,17 +30,17 @@ public class IPNetworkTest { { "127.0.0.1/33" }, // PrefixLength max is 32 for IPv4 { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/129" }, // PrefixLength max is 128 for IPv6 - { "127.0.0.1/31" }, // Bits exceed the prefix length of 31 (32nd bit is on) - { "198.51.255.0/23" }, // Bits exceed the prefix length of 23 - { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/127" }, // Bits exceed the prefix length of 31 - { "2a01:110:8012::/45" }, // Bits exceed the prefix length of 45 (47th bit is on) }; public static TheoryData ValidIPNetworkData = new TheoryData() { { "0.0.0.0/32" }, // the whole IPv4 space { "0.0.0.0/0" }, + { "192.168.0.10/0" }, { "128.0.0.0/1" }, + { "127.0.0.1/8" }, + { "127.0.0.1/31" }, + { "198.51.255.0/23" }, { "::/128" }, // the whole IPv6 space { "255.255.255.255/32" }, { "198.51.254.0/23" }, @@ -44,20 +48,54 @@ public class IPNetworkTest { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" }, { "2a01:110:8012::/47" }, { "2a01:110:8012::/100" }, + { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/127" }, + { "2a01:110:8012::/45" }, }; + private uint GetMask32(int prefix) + { + Debug.Assert(prefix != 0); + + uint mask = uint.MaxValue << (32 - prefix); + return BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(mask) : mask; + } + private UInt128 GetMask128(int prefix) + { + Debug.Assert(prefix != 0); + + UInt128 mask = UInt128.MaxValue << (128 - prefix); + return BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(mask) : mask; + } + private IPAddress GetBaseAddress(IPAddress address, int prefix) + => (address.AddressFamily, prefix) switch + { + (AddressFamily.InterNetwork, 0) => new IPAddress([0, 0, 0, 0]), + (AddressFamily.InterNetwork, _) => new IPAddress(MemoryMarshal.Read(address.GetAddressBytes()) & GetMask32(prefix)), + (AddressFamily.InterNetworkV6, 0) => new IPAddress([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + (AddressFamily.InterNetworkV6, _) => new IPAddress(MemoryMarshal.AsBytes([MemoryMarshal.Read(address.GetAddressBytes()) & GetMask128(prefix)])), + _ => throw new ArgumentOutOfRangeException($"Unexpected address family {address.AddressFamily} of {address}.") + }; + + private (IPAddress, IPAddress, int, string) ParseInput(string input) + { + string[] splitInput = input.Split('/'); + IPAddress address = IPAddress.Parse(splitInput[0]); + int prefixLength = int.Parse(splitInput[1]); + IPAddress baseAddress = GetBaseAddress(address, prefixLength); + return (address, baseAddress, prefixLength, $"{baseAddress}/{prefixLength}"); + } + [Theory] [MemberData(nameof(ValidIPNetworkData))] public void Constructor_Valid_Succeeds(string input) { - string[] splitInput = input.Split('/'); - IPAddress address = IPAddress.Parse(splitInput[0]); - int prefixLegth = int.Parse(splitInput[1]); + var (address, baseAddress, prefixLength, toString) = ParseInput(input); - IPNetwork network = new IPNetwork(address, prefixLegth); + IPNetwork network = new IPNetwork(address, prefixLength); - Assert.Equal(address, network.BaseAddress); - Assert.Equal(prefixLegth, network.PrefixLength); + Assert.Equal(baseAddress, network.BaseAddress); + Assert.Equal(prefixLength, network.PrefixLength); + Assert.Equal(toString, network.ToString()); } [Fact] @@ -77,17 +115,6 @@ public void Constructor_PrefixLenghtOutOfRange_ThrowsArgumentOutOfRangeException Assert.Throws(() => new IPNetwork(address, prefixLength)); } - [Theory] - [InlineData("192.168.0.1", 31)] - [InlineData("42.42.192.0", 17)] - [InlineData("128.0.0.0", 0)] - [InlineData("2a01:110:8012::", 46)] - public void Constructor_NonZeroBitsAfterNetworkPrefix_ThrowsArgumentException(string ipStr, int prefixLength) - { - IPAddress address = IPAddress.Parse(ipStr); - Assert.Throws(() => new IPNetwork(address, prefixLength)); - } - [Theory] [MemberData(nameof(IncorrectFormatData))] public void Parse_IncorrectFormat_ThrowsFormatException(string input) @@ -136,8 +163,15 @@ public void Parse_ValidNetworkNotation_Succeeds(string input) var stringParsedNetwork = IPNetwork.Parse(input); var utf8ParsedNetwork = IPNetwork.Parse(utf8Bytes); - Assert.Equal(input, stringParsedNetwork.ToString()); - Assert.Equal(input, utf8ParsedNetwork.ToString()); + var (_, baseAddress, prefixLength, toString) = ParseInput(input); + + Assert.Equal(baseAddress, stringParsedNetwork.BaseAddress); + Assert.Equal(prefixLength, stringParsedNetwork.PrefixLength); + Assert.Equal(toString, stringParsedNetwork.ToString()); + + Assert.Equal(baseAddress, utf8ParsedNetwork.BaseAddress); + Assert.Equal(prefixLength, utf8ParsedNetwork.PrefixLength); + Assert.Equal(toString, utf8ParsedNetwork.ToString()); } [Theory] @@ -146,11 +180,17 @@ public void TryParse_ValidNetworkNotation_Succeeds(string input) { byte[] utf8Bytes = Encoding.UTF8.GetBytes(input); - Assert.True(IPNetwork.TryParse(input, out IPNetwork network)); - Assert.Equal(input, network.ToString()); + var (_, baseAddress, prefixLength, toString) = ParseInput(input); + + Assert.True(IPNetwork.TryParse(input, out IPNetwork stringParsedNetwork)); + Assert.Equal(baseAddress, stringParsedNetwork.BaseAddress); + Assert.Equal(prefixLength, stringParsedNetwork.PrefixLength); + Assert.Equal(toString, stringParsedNetwork.ToString()); - Assert.True(IPNetwork.TryParse(utf8Bytes, out network)); - Assert.Equal(input, network.ToString()); + Assert.True(IPNetwork.TryParse(utf8Bytes, out IPNetwork utf8ParsedNetwork)); + Assert.Equal(baseAddress, utf8ParsedNetwork.BaseAddress); + Assert.Equal(prefixLength, utf8ParsedNetwork.PrefixLength); + Assert.Equal(toString, utf8ParsedNetwork.ToString()); } [Fact] diff --git a/src/libraries/System.Net.Quic/System.Net.Quic.slnx b/src/libraries/System.Net.Quic/System.Net.Quic.slnx index c5b48ea70dfbac..38336578f79ca3 100644 --- a/src/libraries/System.Net.Quic/System.Net.Quic.slnx +++ b/src/libraries/System.Net.Quic/System.Net.Quic.slnx @@ -1,42 +1,738 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Quic/ref/System.Net.Quic.csproj b/src/libraries/System.Net.Quic/ref/System.Net.Quic.csproj index 59e75f2c8cfc55..3a46e69f9a56d0 100644 --- a/src/libraries/System.Net.Quic/ref/System.Net.Quic.csproj +++ b/src/libraries/System.Net.Quic/ref/System.Net.Quic.csproj @@ -1,4 +1,5 @@ + $(NetCoreAppCurrent) @@ -8,10 +9,12 @@ - - - - + + + + + + diff --git a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj index 546996f4b97c33..e51c658b82ce7a 100644 --- a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj +++ b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj @@ -77,12 +77,9 @@ - - - - + + - @@ -99,6 +96,12 @@ + + + + + + @@ -121,31 +124,31 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - + - + @@ -159,7 +162,6 @@ ('$(TargetArchitecture)' == 'x64' or '$(TargetArchitecture)' == 'x86' or '$(TargetArchitecture)' == 'arm64') and '$(DotNetBuildSourceOnly)' != 'true'"> - + diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs index e609a69f20f582..8b01c1b962496f 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs @@ -62,8 +62,8 @@ private MsQuicApi(QUIC_API_TABLE* apiTable) internal static string MsQuicLibraryVersion { get; } = "unknown"; internal static string? NotSupportedReason { get; } - // workaround for https://github.com/microsoft/msquic/issues/4132 - internal static bool SupportsAsyncCertValidation => Version >= new Version(2, 4); + // Workaround for https://github.com/microsoft/msquic/issues/4132 + internal static bool SupportsAsyncCertValidation => Version > new Version(2, 4); internal static bool UsesSChannelBackend { get; } diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/msquic.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/msquic.cs index 29b4c822d62367..b111a3b85e98f3 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/msquic.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/msquic.cs @@ -148,7 +148,7 @@ internal struct QuicAddr [FieldOffset(0)] public QuicAddrFamilyAndLen FamilyLen; - public static bool SockaddrHasLength => OperatingSystem.IsFreeBSD() || OperatingSystem.IsIOS() || OperatingSystem.IsMacOS() || OperatingSystem.IsMacCatalyst() || OperatingSystem.IsTvOS() || OperatingSystem.IsWatchOS(); + public static bool SockaddrHasLength => OperatingSystem.IsFreeBSD() || OperatingSystem.IsIOS() || OperatingSystem.IsMacOS() || OperatingSystem.IsMacCatalyst() || OperatingSystem.IsTvOS(); public int Family { diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 827841626541ab..b5677746bab267 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -341,6 +341,7 @@ public async Task UntrustedClientCertificateFails() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/114912", TestPlatforms.OSX)] public async Task CertificateCallbackThrowPropagates() { using CancellationTokenSource cts = new CancellationTokenSource(PassingTestTimeout); @@ -1426,7 +1427,7 @@ private async Task SniTestCore(string hostname, bool shouldSendSni) [InlineData("a")] [InlineData("test")] [InlineData("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")] // max allowed hostname length is 63 - [InlineData("\u017C\u00F3\u0142\u0107 g\u0119\u015Bl\u0105 ja\u017A\u0144. \u7EA2\u70E7. \u7167\u308A\u713C\u304D")] + [InlineData("\u017C\u00F3\u0142\u0107g\u0119\u015Bl\u0105ja\u017A\u0144.\u7EA2\u70E7.\u7167\u308A\u713C\u304D")] public Task ClientSendsSniServerReceives_Ok(string hostname) => SniTestCore(hostname, true); [Theory] diff --git a/src/libraries/System.Net.Requests/System.Net.Requests.slnx b/src/libraries/System.Net.Requests/System.Net.Requests.slnx index 1c8c7d143074d0..3313719ac56706 100644 --- a/src/libraries/System.Net.Requests/System.Net.Requests.slnx +++ b/src/libraries/System.Net.Requests/System.Net.Requests.slnx @@ -18,6 +18,14 @@ + + + + + + + + @@ -60,6 +68,14 @@ + + + + + + + + @@ -68,6 +84,14 @@ + + + + + + + + @@ -108,6 +132,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -124,6 +172,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -132,6 +212,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -140,6 +244,14 @@ + + + + + + + + @@ -148,6 +260,14 @@ + + + + + + + + @@ -156,6 +276,14 @@ + + + + + + + + @@ -172,6 +300,22 @@ + + + + + + + + + + + + + + + + @@ -180,6 +324,14 @@ + + + + + + + + @@ -204,6 +356,22 @@ + + + + + + + + + + + + + + + + @@ -212,6 +380,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -237,6 +453,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -245,6 +485,14 @@ + + + + + + + + @@ -253,6 +501,14 @@ + + + + + + + + @@ -261,6 +517,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -269,6 +565,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -277,6 +701,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -293,6 +757,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj b/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj index d4b55af0c6b108..db819723f99f8b 100644 --- a/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj +++ b/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj @@ -100,26 +100,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs b/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs index 7694b7007fdaac..f470879e993e41 100644 --- a/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs +++ b/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs @@ -200,7 +200,6 @@ public sealed class FtpWebRequest : WebRequest private bool _passive = true; private bool _binary = true; private string? _connectionGroupName; - private ServicePoint? _servicePoint; private bool _async; private bool _aborted; @@ -216,7 +215,6 @@ public sealed class FtpWebRequest : WebRequest private Stream? _stream; private RequestStage _requestStage; private bool _onceFailed; - private WebHeaderCollection? _ftpRequestHeaders; private FtpWebResponse? _ftpWebResponse; private int _readWriteTimeout = 5 * 60 * 1000; // 5 minutes. @@ -472,7 +470,7 @@ public override string? ConnectionGroupName } } - public ServicePoint ServicePoint => _servicePoint ??= ServicePointManager.FindServicePoint(_uri); + public ServicePoint ServicePoint => field ??= ServicePointManager.FindServicePoint(_uri); internal bool Aborted { @@ -1560,8 +1558,8 @@ public bool EnableSsl public override WebHeaderCollection Headers { - get => _ftpRequestHeaders ??= new WebHeaderCollection(); - set => _ftpRequestHeaders = value; + get => field ??= new WebHeaderCollection(); + set => field = value; } // NOT SUPPORTED method diff --git a/src/libraries/System.Net.Requests/tests/AuthorizationTest.cs b/src/libraries/System.Net.Requests/tests/AuthorizationTest.cs index 866ce373dae672..c89d3d2c6b531a 100644 --- a/src/libraries/System.Net.Requests/tests/AuthorizationTest.cs +++ b/src/libraries/System.Net.Requests/tests/AuthorizationTest.cs @@ -26,7 +26,7 @@ public void Ctor_Token_ExpectDefaultValues() [Theory] [InlineData(null)] [InlineData("")] - public void Ctor_TokenNullOrEmpty_ExpectMessageNull(string token) + public void Ctor_TokenNullOrEmpty_ExpectMessageNull(string? token) { Authorization authorization = new Authorization(token); Assert.Null(authorization.Message); @@ -35,7 +35,7 @@ public void Ctor_TokenNullOrEmpty_ExpectMessageNull(string token) [Theory] [InlineData(null)] [InlineData("")] - public void Ctor_ConnectionGroupIdNullOrEmpty_ExpectConnectionGroupIdNull(string connectionGroupId) + public void Ctor_ConnectionGroupIdNullOrEmpty_ExpectConnectionGroupIdNull(string? connectionGroupId) { Authorization authorization = new Authorization(null, true, connectionGroupId); Assert.Null(authorization.ConnectionGroupId); @@ -44,7 +44,7 @@ public void Ctor_ConnectionGroupIdNullOrEmpty_ExpectConnectionGroupIdNull(string [Theory] [InlineData(null)] [InlineData(new object[] { new string[0] { } })] - public void ProtectionRealm_SetNullOrEmptyGet_ExpectNullValue(string[] protectionRealm) + public void ProtectionRealm_SetNullOrEmptyGet_ExpectNullValue(string[]? protectionRealm) { Authorization authorization = new Authorization(null); authorization.ProtectionRealm = protectionRealm; diff --git a/src/libraries/System.Net.Security/System.Net.Security.slnx b/src/libraries/System.Net.Security/System.Net.Security.slnx index aa80c218e39b77..48139a04e729cf 100644 --- a/src/libraries/System.Net.Security/System.Net.Security.slnx +++ b/src/libraries/System.Net.Security/System.Net.Security.slnx @@ -68,6 +68,14 @@ + + + + + + + + @@ -84,6 +92,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -100,6 +132,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -108,6 +164,14 @@ + + + + + + + + @@ -116,6 +180,22 @@ + + + + + + + + + + + + + + + + @@ -124,6 +204,14 @@ + + + + + + + + @@ -132,6 +220,14 @@ + + + + + + + + @@ -188,6 +284,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -221,6 +349,14 @@ + + + + + + + + @@ -229,6 +365,14 @@ + + + + + + + + @@ -245,6 +389,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -261,6 +429,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -269,6 +501,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -285,6 +549,14 @@ + + + + + + + + @@ -293,6 +565,14 @@ + + + + + + + + @@ -301,6 +581,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Security/src/System.Net.Security.csproj b/src/libraries/System.Net.Security/src/System.Net.Security.csproj index 5ab3577f673e11..fe26b4a0a12905 100644 --- a/src/libraries/System.Net.Security/src/System.Net.Security.csproj +++ b/src/libraries/System.Net.Security/src/System.Net.Security.csproj @@ -15,6 +15,7 @@ ExcludeApiList.PNSE.txt $(DefineConstants);TARGET_WINDOWS $(DefineConstants);TARGET_ANDROID + $(DefineConstants);TARGET_APPLE true true true @@ -440,11 +441,22 @@ Link="Common\Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.Ssl.cs" /> + + + + + + + @@ -453,30 +465,30 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - + + + diff --git a/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs b/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs index 3bd0c7142c3fc6..213ee2f42698e5 100644 --- a/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs +++ b/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs @@ -1,50 +1,25 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; +using SafeNwHandle = Interop.SafeNwHandle; 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( @@ -58,16 +33,16 @@ internal static SslPolicyErrors VerifyCertificateProperties( return null; } - SafeSslHandle sslContext = ((SafeDeleteSslContext)securityContext).SslContext; + X509Certificate2? result = null; - if (sslContext == null) + SafeX509ChainHandle chainHandle = securityContext switch { - return null; - } - - X509Certificate2? result = null; + SafeDeleteNwContext nwContext => nwContext.PeerX509ChainHandle!, + SafeDeleteSslContext sslContext => Interop.AppleCrypto.SslCopyCertChain(sslContext.SslContext), + _ => throw new ArgumentException("Invalid context type", nameof(securityContext)) + }; - using (SafeX509ChainHandle chainHandle = Interop.AppleCrypto.SslCopyCertChain(sslContext)) + try { long chainSize = Interop.AppleCrypto.X509ChainGetChainSize(chainHandle); @@ -96,6 +71,13 @@ internal static SslPolicyErrors VerifyCertificateProperties( result = new X509Certificate2(certHandle); } } + finally + { + if (securityContext is SafeDeleteSslContext) + { + chainHandle.Dispose(); + } + } if (NetEventSource.Log.IsEnabled()) NetEventSource.Log.RemoteCertificate(result); @@ -103,15 +85,35 @@ internal static SslPolicyErrors VerifyCertificateProperties( } // This is only called when we selected local client certificate. - // Currently this is only when Apple crypto asked for it. - internal static bool IsLocalCertificateUsed(SafeFreeCredentials? _1, SafeDeleteContext? _2) => true; + // We need to check if the server actually requested it during handshake. + internal static bool IsLocalCertificateUsed(SafeFreeCredentials? _, SafeDeleteContext? context) + { + return context switch + { + // For Network Framework, we need to check if the server actually requested + // a client certificate during the handshake. + SafeDeleteNwContext nwContext => nwContext.ClientCertificateRequested, + SafeDeleteSslContext => true, + _ => true + }; + } // // Used only by client SSL code, never returns null. // internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext securityContext) { - SafeSslHandle sslContext = ((SafeDeleteSslContext)securityContext).SslContext; + return securityContext switch + { + SafeDeleteNwContext nwContext => nwContext.AcceptableIssuers, + SafeDeleteSslContext sslContext => GetRequestCertificateAuthorities(sslContext), + _ => throw new ArgumentException("Invalid context type", nameof(securityContext)) + }; + } + + private static string[] GetRequestCertificateAuthorities(SafeDeleteSslContext securityContext) + { + SafeSslHandle sslContext = securityContext.SslContext; if (sslContext == null) { diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Android/SafeDeleteSslContext.cs b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Android/SafeDeleteSslContext.cs index e958a482898f9e..844b0f6095c1c2 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Android/SafeDeleteSslContext.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Android/SafeDeleteSslContext.cs @@ -7,6 +7,7 @@ using System.Security.Authentication; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; +using System.Threading; using PAL_KeyAlgorithm = Interop.AndroidCrypto.PAL_KeyAlgorithm; using PAL_SSLStreamStatus = Interop.AndroidCrypto.PAL_SSLStreamStatus; @@ -29,6 +30,8 @@ internal sealed class SafeDeleteSslContext : SafeDeleteContext private readonly SafeSslHandle _sslContext; + private readonly Lock _lock = new Lock(); + private ArrayBuffer _inputBuffer = new ArrayBuffer(InitialBufferSize); private ArrayBuffer _outputBuffer = new ArrayBuffer(InitialBufferSize); @@ -36,6 +39,8 @@ internal sealed class SafeDeleteSslContext : SafeDeleteContext public SafeSslHandle SslContext => _sslContext; + private volatile bool _disposed; + public SafeDeleteSslContext(SslAuthenticationOptions authOptions) : base(IntPtr.Zero) { @@ -59,13 +64,21 @@ public SafeDeleteSslContext(SslAuthenticationOptions authOptions) protected override void Dispose(bool disposing) { - if (disposing) + lock (_lock) { - if (_sslContext is SafeSslHandle sslContext) + if (!_disposed) { - _inputBuffer.Dispose(); - _outputBuffer.Dispose(); - sslContext.Dispose(); + _disposed = true; + + // First dispose the SSL context to trigger native cleanup + _sslContext.Dispose(); + + if (disposing) + { + // Then dispose the buffers + _inputBuffer.Dispose(); + _outputBuffer.Dispose(); + } } } @@ -75,61 +88,105 @@ protected override void Dispose(bool disposing) [UnmanagedCallersOnly] private static unsafe void WriteToConnection(IntPtr connection, byte* data, int dataLength) { - SafeDeleteSslContext? context = (SafeDeleteSslContext?)GCHandle.FromIntPtr(connection).Target; - Debug.Assert(context != null); + WeakGCHandle h = WeakGCHandle.FromIntPtr(connection); + if (!h.TryGetTarget(out SafeDeleteSslContext? context)) + { + Debug.Write("WriteToConnection: failed to get target context"); + return; + } + + lock (context._lock) + { + if (context._disposed) + { + Debug.Write("WriteToConnection: context is disposed"); + return; + } - var inputBuffer = new ReadOnlySpan(data, dataLength); + var inputBuffer = new ReadOnlySpan(data, dataLength); - context._outputBuffer.EnsureAvailableSpace(dataLength); - inputBuffer.CopyTo(context._outputBuffer.AvailableSpan); - context._outputBuffer.Commit(dataLength); + context._outputBuffer.EnsureAvailableSpace(dataLength); + inputBuffer.CopyTo(context._outputBuffer.AvailableSpan); + context._outputBuffer.Commit(dataLength); + } } [UnmanagedCallersOnly] private static unsafe PAL_SSLStreamStatus ReadFromConnection(IntPtr connection, byte* data, int* dataLength) { - SafeDeleteSslContext? context = (SafeDeleteSslContext?)GCHandle.FromIntPtr(connection).Target; - Debug.Assert(context != null); - - int toRead = *dataLength; - if (toRead == 0) - return PAL_SSLStreamStatus.OK; - - if (context._inputBuffer.ActiveLength == 0) + WeakGCHandle h = WeakGCHandle.FromIntPtr(connection); + if (!h.TryGetTarget(out SafeDeleteSslContext? context)) { + Debug.Write("ReadFromConnection: failed to get target context"); *dataLength = 0; - return PAL_SSLStreamStatus.NeedData; + return PAL_SSLStreamStatus.Error; } - toRead = Math.Min(toRead, context._inputBuffer.ActiveLength); + lock (context._lock) + { + if (context._disposed) + { + Debug.Write("ReadFromConnection: context is disposed"); + *dataLength = 0; + return PAL_SSLStreamStatus.Error; + } + + int toRead = *dataLength; + if (toRead == 0) + return PAL_SSLStreamStatus.OK; + + if (context._inputBuffer.ActiveLength == 0) + { + *dataLength = 0; + return PAL_SSLStreamStatus.NeedData; + } + + toRead = Math.Min(toRead, context._inputBuffer.ActiveLength); - context._inputBuffer.ActiveSpan.Slice(0, toRead).CopyTo(new Span(data, toRead)); - context._inputBuffer.Discard(toRead); + context._inputBuffer.ActiveSpan.Slice(0, toRead).CopyTo(new Span(data, toRead)); + context._inputBuffer.Discard(toRead); + + *dataLength = toRead; + return PAL_SSLStreamStatus.OK; + } + } - *dataLength = toRead; - return PAL_SSLStreamStatus.OK; + [UnmanagedCallersOnly] + private static void CleanupManagedContext(IntPtr managedContextHandle) + { + if (managedContextHandle != IntPtr.Zero) + { + WeakGCHandle handle = WeakGCHandle.FromIntPtr(managedContextHandle); + handle.Dispose(); + } } internal void Write(ReadOnlySpan buf) { - _inputBuffer.EnsureAvailableSpace(buf.Length); - buf.CopyTo(_inputBuffer.AvailableSpan); - _inputBuffer.Commit(buf.Length); + lock (_lock) + { + _inputBuffer.EnsureAvailableSpace(buf.Length); + buf.CopyTo(_inputBuffer.AvailableSpan); + _inputBuffer.Commit(buf.Length); + } } internal int BytesReadyForConnection => _outputBuffer.ActiveLength; internal void ReadPendingWrites(ref ProtocolToken token) { - if (_outputBuffer.ActiveLength == 0) + lock (_lock) { - token.Size = 0; - token.Payload = null; - return; - } + if (_outputBuffer.ActiveLength == 0) + { + token.Size = 0; + token.Payload = null; + return; + } - token.SetPayload(_outputBuffer.ActiveSpan); - _outputBuffer.Discard(_outputBuffer.ActiveLength); + token.SetPayload(_outputBuffer.ActiveSpan); + _outputBuffer.Discard(_outputBuffer.ActiveLength); + } } internal int ReadPendingWrites(byte[] buf, int offset, int count) @@ -139,12 +196,15 @@ internal int ReadPendingWrites(byte[] buf, int offset, int count) Debug.Assert(count >= 0); Debug.Assert(count <= buf.Length - offset); - int limit = Math.Min(count, _outputBuffer.ActiveLength); + lock (_lock) + { + int limit = Math.Min(count, _outputBuffer.ActiveLength); - _outputBuffer.ActiveSpan.Slice(0, limit).CopyTo(new Span(buf, offset, limit)); - _outputBuffer.Discard(limit); + _outputBuffer.ActiveSpan.Slice(0, limit).CopyTo(new Span(buf, offset, limit)); + _outputBuffer.Discard(limit); - return limit; + return limit; + } } private static SafeSslHandle CreateSslContext(SslStream.JavaProxy sslStreamProxy, SslAuthenticationOptions authOptions) @@ -225,11 +285,11 @@ private unsafe void InitializeSslContext( throw new NotImplementedException(nameof(SafeDeleteSslContext)); } - // Make sure the class instance is associated to the session and is provided - // in the Read/Write callback connection parameter + // Make sure the class instance is associated to the session and is provided in the Read/Write callback connection parameter + // Additionally, all calls should be synchronous so there's no risk of the managed object being collected while native code is executing. IntPtr managedContextHandle = GCHandle.ToIntPtr(GCHandle.Alloc(this, GCHandleType.Weak)); string? peerHost = !isServer && !string.IsNullOrEmpty(authOptions.TargetHost) ? authOptions.TargetHost : null; - Interop.AndroidCrypto.SSLStreamInitialize(handle, isServer, managedContextHandle, &ReadFromConnection, &WriteToConnection, InitialBufferSize, peerHost); + Interop.AndroidCrypto.SSLStreamInitialize(handle, isServer, managedContextHandle, &ReadFromConnection, &WriteToConnection, &CleanupManagedContext, InitialBufferSize, peerHost); if (authOptions.EnabledSslProtocols != SslProtocols.None) { diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Managed/SslProtocolsValidation.cs b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Managed/SslProtocolsValidation.cs index b5943e7ba5e76b..f98f4e396d55ef 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Managed/SslProtocolsValidation.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Managed/SslProtocolsValidation.cs @@ -8,7 +8,7 @@ namespace System.Net { internal static class SslProtocolsValidation { - public static (int MinIndex, int MaxIndex) ValidateContiguous(this SslProtocols protocols, SslProtocols[] orderedSslProtocols) + public static (int MinIndex, int MaxIndex) ValidateContiguous(this SslProtocols protocols, ReadOnlySpan orderedSslProtocols) { // A contiguous range of protocols is required. Find the min and max of the range, // or throw if it's non-contiguous or if no protocols are specified. diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteNwContext.cs b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteNwContext.cs new file mode 100644 index 00000000000000..c5b8d4201c225f --- /dev/null +++ b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteNwContext.cs @@ -0,0 +1,813 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using System.Buffers; +using System.Collections.Generic; +using System.Diagnostics; +using System.Net; +using System.Net.Security; +using System.Runtime.InteropServices; +using System.Runtime.ExceptionServices; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Win32.SafeHandles; +using SafeNwHandle = Interop.SafeNwHandle; +using SafeCFStringHandle = Microsoft.Win32.SafeHandles.SafeCFStringHandle; +using NetworkFrameworkStatusUpdates = Interop.NetworkFramework.StatusUpdates; +using NwOSStatus = Interop.AppleCrypto.OSStatus; +using ResettableValueTaskSource = System.Net.Quic.ResettableValueTaskSource; + +namespace System.Net.Security +{ + /// + /// Network Framework-specific SSL/TLS context implementation for macOS. + /// This class provides secure connection management using Apple's modern + /// Network Framework APIs while presenting a synchronous interface + /// consistent with SecureTransport. + /// + internal sealed class SafeDeleteNwContext : SafeDeleteContext + { + // AppContext switch to enable Network Framework usage + internal static bool IsSwitchEnabled { get; } = AppContextSwitchHelper.GetBooleanConfig( + "System.Net.Security.UseNetworkFramework", + "DOTNET_SYSTEM_NET_SECURITY_USENETWORKFRAMEWORK"); + private static readonly Lazy s_isNetworkFrameworkAvailable = new Lazy(CheckNetworkFrameworkAvailability); + + private const int InitialReceiveBufferSize = 2 * 1024; + + // backreference to the SslStream instance + private readonly SslStream _sslStream; + private Stream TransportStream => _sslStream.InnerStream; + private SslAuthenticationOptions SslAuthenticationOptions => _sslStream._sslAuthenticationOptions; + + // Underlying nw_connection_t handle + internal readonly SafeNwHandle ConnectionHandle; + // nw_framer_t handle for tunneling messages + private SafeNwHandle? _framerHandle; + + // Temporary storage for data that are available only during callback + private string[] _acceptableIssuers = Array.Empty(); + internal string[] AcceptableIssuers => _acceptableIssuers; + + // peer certificate chain (obtained from callback once available) + private SafeX509ChainHandle? _peerCertChainHandle; + internal SafeX509ChainHandle? PeerX509ChainHandle => _peerCertChainHandle; + + // Provides backreference from native code. This GC handle is expected + // to be always valid and is only freed once we are sure there will be + // no more callbacks from the native code + private readonly GCHandle _thisHandle; + + internal IntPtr StateHandle => _thisHandle.IsAllocated ? GCHandle.ToIntPtr(_thisHandle) : IntPtr.Zero; + + private TaskCompletionSource _handshakeCompletionSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + private Task? _transportReadTask; + private ResettableValueTaskSource _transportReadTcs = new ResettableValueTaskSource() + { + CancellationAction = target => + { + if (target is SafeDeleteNwContext nwContext) + { + nwContext._transportReadTcs.TrySetException(new OperationCanceledException()); + } + } + }; + private ArrayBuffer _appReceiveBuffer = new(InitialReceiveBufferSize); + private ResettableValueTaskSource _appReceiveBufferTcs = new ResettableValueTaskSource(); + private Task? _pendingAppReceiveBufferFillTask; + private readonly TaskCompletionSource _connectionClosedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + private CancellationTokenSource _shutdownCts = new CancellationTokenSource(); + + private bool _disposed; + private int _challengeCallbackCompleted; // 0 = not called, 1 = called + private IntPtr _selectedClientCertificate; // Cached result from challenge callback + + private ResettableValueTaskSource _appWriteTcs = new ResettableValueTaskSource() + { + CancellationAction = target => + { + if (target is SafeDeleteNwContext nwContext) + { + nwContext._appWriteTcs.TrySetException(new OperationCanceledException()); + } + } + }; + + private TaskCompletionSource? _currentWriteCompletionSource; + + public SafeDeleteNwContext(SslStream stream) : base(IntPtr.Zero) + { + _sslStream = stream; + ValidateSslAuthenticationOptions(SslAuthenticationOptions); + _thisHandle = GCHandle.Alloc(this, GCHandleType.Normal); + ConnectionHandle = CreateConnectionHandle(SslAuthenticationOptions, _thisHandle); + + if (ConnectionHandle.IsInvalid) + { + throw new Exception("Failed to create Network Framework connection"); // TODO: Make this string resource + } + } + + public static bool IsNetworkFrameworkAvailable => IsSwitchEnabled && s_isNetworkFrameworkAvailable.Value; + + internal bool ClientCertificateRequested => _challengeCallbackCompleted == 1 && _selectedClientCertificate != IntPtr.Zero; + + internal async Task HandshakeAsync(CancellationToken cancellationToken) + { + Interop.NetworkFramework.Tls.NwConnectionStart(ConnectionHandle, StateHandle); + + using CancellationTokenRegistration registration = cancellationToken.UnsafeRegister(static (state, token) => + { + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(null, "Handshake cancellation requested"); + ((TaskCompletionSource)state!).TrySetCanceled(token); + }, _handshakeCompletionSource); + + _transportReadTask = Task.Run(async () => + { + try + { + byte[] buffer = ArrayPool.Shared.Rent(16 * 1024); + try + { + Memory readBuffer = new Memory(buffer); + + while (!_shutdownCts.IsCancellationRequested) + { + // Read data from the transport stream + int bytesRead = await TransportStream.ReadAsync(readBuffer, _shutdownCts.Token).ConfigureAwait(false); + + if (bytesRead > 0) + { + // Process the read data + await WriteInboundWireDataAsync(readBuffer.Slice(0, bytesRead)).ConfigureAwait(false); + } + else + { + // EOF reached, signal completion + _transportReadTcs.TrySetResult(final: true); + + // TODO: can this race with actual handshake completion? + Interop.NetworkFramework.Tls.NwConnectionCancel(ConnectionHandle); + break; + } + } + } + finally + { + ArrayPool.Shared.Return(buffer); + } + } + catch (OperationCanceledException) + { + // Handle cancellation gracefully + } + catch (Exception ex) + { + // Propagate transport stream exceptions to the handshake + _handshakeCompletionSource.TrySetException(ex); + _currentWriteCompletionSource?.TrySetException(ex); + } + }, cancellationToken); + + return await _handshakeCompletionSource.Task.ConfigureAwait(false); + } + + internal async Task WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(null, $"App sending {buffer.Length} bytes"); + + TaskCompletionSource transportWriteCompletion = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + _currentWriteCompletionSource = transportWriteCompletion; + + bool success = _appWriteTcs.TryGetValueTask(out ValueTask valueTask, this, CancellationToken.None); + Debug.Assert(success, "Concurrent WriteAsync detected"); + + using MemoryHandle memoryHandle = buffer.Pin(); + unsafe + { + Interop.NetworkFramework.Tls.NwConnectionSend(ConnectionHandle, StateHandle, memoryHandle.Pointer, buffer.Length, &CompletionCallback); + } + try + { + await valueTask.ConfigureAwait(false); + } + catch (Exception ex) + { + _currentWriteCompletionSource = null; + transportWriteCompletion.TrySetException(ex); + } + + // Wait for the transport write to complete + await transportWriteCompletion.Task.ConfigureAwait(false); + + [UnmanagedCallersOnly] + static unsafe void CompletionCallback(IntPtr context, Interop.NetworkFramework.NetworkFrameworkError* error) + { + SafeDeleteNwContext thisContext = ResolveThisHandle(context); + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(thisContext, $"Completing WriteAsync", nameof(WriteAsync)); + + if (error != null) + { + thisContext._appWriteTcs.TrySetException(Interop.NetworkFramework.CreateExceptionForNetworkFrameworkError(in *error)); + } + else + { + thisContext._appWriteTcs.TrySetResult(); + } + } + } + + internal ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + + if (_pendingAppReceiveBufferFillTask == null && _appReceiveBuffer.ActiveLength > 0) + { + // fast path, data available + int length = Math.Min(_appReceiveBuffer.ActiveLength, buffer.Length); + _appReceiveBuffer.ActiveSpan.Slice(0, length).CopyTo(buffer.Span); + _appReceiveBuffer.Discard(length); + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Read {length} bytes"); + return ValueTask.FromResult(length); + } + + return ReadAsyncInternal(buffer, cancellationToken); + + async ValueTask ReadAsyncInternal(Memory buffer, CancellationToken cancellationToken) + { + // Create a linked token that respects both the user's cancellation token and our shutdown token + using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _shutdownCts.Token); + + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, "Internal buffer empty, refilling."); + + // Since the native nw_connection_receive is asynchronous and + // not cancellable, we save reference to the pending task. In + // case of cancellation, we cancel only waiting on the task, and + // on the next ReadAsync call, we don't issue another native + // nw_connection_receive call, but rather wait for the pending + // task to complete. + _pendingAppReceiveBufferFillTask ??= FillAppDataBufferAsync(); + try + { + // Wait for the pending task to complete, which will fill the buffer + await _pendingAppReceiveBufferFillTask.WaitAsync(linkedCts.Token).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + // Throw with correct cancellation token if cancellation was + // requested by user + cancellationToken.ThrowIfCancellationRequested(); + + // otherwise we are tearing down the connection, simulate EOS + Debug.Assert(_shutdownCts.IsCancellationRequested, "Expected shutdown cancellation token to be triggered"); + + ObjectDisposedException.ThrowIf(_disposed, _sslStream); + } + // other exception types are expected to be fatal and it is okay to not + // clear the pending task and rethrow the same exception + + _pendingAppReceiveBufferFillTask = null; + + if (_appReceiveBuffer.ActiveLength == 0) + { + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, "ReadAsync returning 0 bytes, end of stream reached"); + _appReceiveBufferTcs.TrySetResult(final: true); + return 0; // EOF + } + + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"ReadAsync filled buffer with {_appReceiveBuffer.ActiveLength} bytes"); + + int length = Math.Min(_appReceiveBuffer.ActiveLength, buffer.Length); + _appReceiveBuffer.ActiveSpan.Slice(0, length).CopyTo(buffer.Span); + _appReceiveBuffer.Discard(length); + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Read {length} bytes"); + return length; + } + } + + internal Task FillAppDataBufferAsync() + { + bool success = _appReceiveBufferTcs.TryGetValueTask(out ValueTask valueTask, this, CancellationToken.None); + Debug.Assert(success, "Concurrent FillAppDataBufferAsync detected"); + + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Waiting for read from connection"); + unsafe + { + Interop.NetworkFramework.Tls.NwConnectionReceive(ConnectionHandle, StateHandle, 16 * 1024, &CompletionCallback); + } + + return _pendingAppReceiveBufferFillTask = valueTask.AsTask(); + + [UnmanagedCallersOnly] + static unsafe void CompletionCallback(IntPtr context, Interop.NetworkFramework.NetworkFrameworkError* error, byte* data, int length) + { + SafeDeleteNwContext thisContext = ResolveThisHandle(context); + Debug.Assert(thisContext != null, "Expected thisContext to be non-null"); + + if (NetEventSource.Log.IsEnabled()) + NetEventSource.Info(thisContext, $"Completing ConnectionRead, status: {(error != null ? error->ErrorCode : 0)}, len: {length}", nameof(FillAppDataBufferAsync)); + + ref ArrayBuffer buffer = ref thisContext._appReceiveBuffer; + + if (error != null && error->ErrorCode != 0) + { + if (error->ErrorDomain == (int)Interop.NetworkFramework.NetworkFrameworkErrorDomain.POSIX && + error->ErrorCode == (int)Interop.NetworkFramework.NWErrorDomainPOSIX.OperationCanceled) + { + // We cancelled the connection, so this is expected as pending read will be cancelled. + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(thisContext, "Connection read cancelled, no data to process"); + thisContext._appReceiveBufferTcs.TrySetResult(); + return; + } + thisContext._appReceiveBufferTcs.TrySetException(ExceptionDispatchInfo.SetCurrentStackTrace(Interop.NetworkFramework.CreateExceptionForNetworkFrameworkError(in *error))); + } + else + { + buffer.EnsureAvailableSpace(length); + new Span(data, length).CopyTo(buffer.AvailableSpan); + buffer.Commit(length); + thisContext._appReceiveBufferTcs.TrySetResult(); + } + } + } + + internal void Shutdown() + { + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Shutting down Network Framework context"); + _shutdownCts.Cancel(); + Interop.NetworkFramework.Tls.NwConnectionCancel(ConnectionHandle); + } + + private static bool CheckNetworkFrameworkAvailability() + { + try + { + unsafe + { + // Call Init with null callbacks to check if Network Framework is available + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(null, "Checking Network Framework availability..."); + return !Interop.NetworkFramework.Tls.Init(&StatusUpdateCallback, &WriteOutboundWireData, &ChallengeCallback); + } + } + catch + { + return false; + } + } + + private static void ValidateSslAuthenticationOptions(SslAuthenticationOptions options) + { + switch (options.EncryptionPolicy) + { + case EncryptionPolicy.RequireEncryption: +#pragma warning disable SYSLIB0040 // NoEncryption and AllowNoEncryption are obsolete + case EncryptionPolicy.AllowNoEncryption: + // SecureTransport doesn't allow TLS_NULL_NULL_WITH_NULL, but + // since AllowNoEncryption intersect OS-supported isn't nothing, + // let it pass. + break; +#pragma warning restore SYSLIB0040 + default: + throw new PlatformNotSupportedException(SR.Format(SR.net_encryptionpolicy_notsupported, options.EncryptionPolicy)); + } + } + + private static SafeNwHandle CreateConnectionHandle(SslAuthenticationOptions options, GCHandle thisHandle) + { + int alpnLength = GetAlpnProtocolListSerializedLength(options.ApplicationProtocols); + + SslProtocols minProtocol = SslProtocols.None; + SslProtocols maxProtocol = SslProtocols.None; + + if (options.EnabledSslProtocols != SslProtocols.None) + { + (minProtocol, maxProtocol) = GetMinMaxProtocols(options.EnabledSslProtocols); + } + + byte[]? alpnBuffer = null; + try + { + const int StackAllocThreshold = 256; + Span alpn = alpnLength == 0 + ? Span.Empty + : alpnLength <= StackAllocThreshold + ? stackalloc byte[StackAllocThreshold] + : (alpnBuffer = ArrayPool.Shared.Rent(alpnLength)); + + if (alpnLength > 0) + { + SerializeAlpnProtocolList(options.ApplicationProtocols!, alpn.Slice(0, alpnLength)); + } + + Span ciphers = options.CipherSuitesPolicy is null + ? Span.Empty + : options.CipherSuitesPolicy.Pal.TlsCipherSuites; + + string idnHost = TargetHostNameHelper.NormalizeHostName(options.TargetHost); + + unsafe + { + fixed (byte* alpnPtr = alpn) + fixed (uint* ciphersPtr = ciphers) + { + return Interop.NetworkFramework.Tls.NwConnectionCreate(options.IsServer, GCHandle.ToIntPtr(thisHandle), idnHost, alpnPtr, alpnLength, minProtocol, maxProtocol, ciphersPtr, ciphers.Length); + } + } + } + finally + { + if (alpnBuffer != null) + { + ArrayPool.Shared.Return(alpnBuffer); + } + } + + // + // Native API accepts only a single ALPN protocol at a time + // (null-terminated string). We serialize all used app protocols + // into a single buffer in the format <0> + // + + static int GetAlpnProtocolListSerializedLength(List? applicationProtocols) + { + if (applicationProtocols is null) + { + return 0; + } + + int protocolSize = 0; + + foreach (SslApplicationProtocol protocol in applicationProtocols) + { + protocolSize += protocol.Protocol.Length + 2; + } + + return protocolSize; + } + + static void SerializeAlpnProtocolList(List applicationProtocols, Span buffer) + { + Debug.Assert(GetAlpnProtocolListSerializedLength(applicationProtocols) == buffer.Length); + + int offset = 0; + + foreach (SslApplicationProtocol protocol in applicationProtocols) + { + buffer[offset] = (byte)protocol.Protocol.Length; // preffix len + protocol.Protocol.Span.CopyTo(buffer.Slice(offset + 1)); // ALPN + buffer[offset + protocol.Protocol.Length + 1] = 0; // null-terminator + + offset += protocol.Protocol.Length + 2; + } + } + + static (SslProtocols, SslProtocols) GetMinMaxProtocols(SslProtocols protocols) + { + ReadOnlySpan orderedProtocols = [ +#pragma warning disable 0618 + SslProtocols.Ssl2, + SslProtocols.Ssl3, +#pragma warning restore 0618 +#pragma warning disable SYSLIB0039 // TLS 1.0 and 1.1 are obsolete + SslProtocols.Tls, + SslProtocols.Tls11, +#pragma warning restore SYSLIB0039 + SslProtocols.Tls12, + SslProtocols.Tls13 + ]; + + (int minIndex, int maxIndex) = protocols.ValidateContiguous(orderedProtocols); + SslProtocols minProtocolId = orderedProtocols[minIndex]; + SslProtocols maxProtocolId = orderedProtocols[maxIndex]; + + return (minProtocolId, maxProtocolId); + } + } + + protected override void Dispose(bool disposing) + { + if (disposing && !_disposed) + { + _disposed = true; + + Shutdown(); + + // Wait for the transport read task to complete + if (_transportReadTask is Task transportTask) + { + // Ignore exceptions from the transport task + transportTask.ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing).GetAwaiter().GetResult(); + } + + + // Wait for any pending app receive tasks so that we may safely dispose the app receive buffer. + if (_pendingAppReceiveBufferFillTask is Task t) + { + t.ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing).GetAwaiter().GetResult(); + } + + _appReceiveBuffer.Dispose(); + + // wait for callback signalling connection has been truly closed. + _connectionClosedTcs.Task.GetAwaiter().GetResult(); + // Complete all pending operations with ObjectDisposedException + var disposedException = new ObjectDisposedException(nameof(SafeDeleteNwContext)); + + _appReceiveBufferTcs.TrySetException(disposedException); + _transportReadTcs.TrySetException(disposedException); + _handshakeCompletionSource.TrySetException(disposedException); + + // Complete any pending writes with disposed exception + TaskCompletionSource? writeCompletion = _currentWriteCompletionSource; + if (writeCompletion != null) + { + _currentWriteCompletionSource = null; + writeCompletion.TrySetException(new ObjectDisposedException(nameof(SafeDeleteNwContext))); + } + + ConnectionHandle.Dispose(); + _framerHandle?.Dispose(); + _peerCertChainHandle?.Dispose(); + _shutdownCts?.Dispose(); + + // now that we know all callbacks are done, we can free the handle + _thisHandle.Free(); + } + base.Dispose(disposing); + } + + private static SafeDeleteNwContext ResolveThisHandle(IntPtr thisHandle) + { + GCHandle handle = GCHandle.FromIntPtr(thisHandle); + return (SafeDeleteNwContext)handle.Target!; + } + + [UnmanagedCallersOnly] + private static unsafe void WriteOutboundWireData(IntPtr thisHandle, byte* data, ulong dataLength) + { + SafeDeleteNwContext? nwContext = null; + try + { + nwContext = ResolveThisHandle(thisHandle); + Debug.Assert(dataLength <= int.MaxValue); + + nwContext.WriteOutboundWireData(new ReadOnlySpan(data, (int)dataLength)); + } + catch (Exception e) + { + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Error(nwContext, $"WriteOutboundWireData Failed: {e.Message}"); + } + + // Complete the write operation with the exception + TaskCompletionSource? writeCompletion = nwContext?._currentWriteCompletionSource; + if (writeCompletion != null) + { + nwContext?._currentWriteCompletionSource = null; + writeCompletion.TrySetException(e); + } + } + finally + { + nwContext?._currentWriteCompletionSource?.TrySetResult(); + nwContext?._currentWriteCompletionSource = null; + } + } + + [UnmanagedCallersOnly] + private static IntPtr ChallengeCallback(IntPtr thisHandle, IntPtr acceptableIssuersHandle) + { + try + { + SafeDeleteNwContext nwContext = ResolveThisHandle(thisHandle); + + // the callback may end up being called multiple times for some reason. + // check if we've already processed the challenge callback + if (Interlocked.CompareExchange(ref nwContext._challengeCallbackCompleted, 1, 0) != 0) + { + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(nwContext, $"ChallengeCallback already processed, returning cached result: {nwContext._selectedClientCertificate}"); + } + return nwContext._selectedClientCertificate; + } + + nwContext._acceptableIssuers = ExtractAcceptableIssuers(acceptableIssuersHandle); + Debug.Assert(nwContext._peerCertChainHandle != null, "Peer certificate chain handle should be set before challenge callback"); + + byte[]? dummy = null; + nwContext._sslStream.AcquireClientCredentials(ref dummy, true); + return nwContext._selectedClientCertificate = nwContext.SslAuthenticationOptions.CertificateContext?.TargetCertificate.Handle ?? IntPtr.Zero; + } + catch (Exception ex) + { + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Error(null, $"ChallengeCallback exception: {ex}"); + } + return IntPtr.Zero; + } + } + + private void WriteOutboundWireData(ReadOnlySpan data) + { + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Sending {data.Length} bytes"); + + TransportStream.Write(data); + } + + private async Task WriteInboundWireDataAsync(ReadOnlyMemory buf) + { + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Receiving {buf.Length} bytes"); + + if (_framerHandle != null && buf.Length > 0) + { + // the data needs to be pinned until the callback fires + using MemoryHandle memoryHandle = buf.Pin(); + + bool success = _transportReadTcs.TryGetValueTask(out ValueTask valueTask, this, CancellationToken.None); + Debug.Assert(success, "Concurrent WriteInboundWireDataAsync detected"); + + unsafe + { + Interop.NetworkFramework.Tls.NwFramerDeliverInput(_framerHandle, StateHandle, (byte*)memoryHandle.Pointer, buf.Length, &CompletionCallback); + } + + await valueTask.ConfigureAwait(false); + } + + [UnmanagedCallersOnly] + static unsafe void CompletionCallback(IntPtr context, Interop.NetworkFramework.NetworkFrameworkError* error) + { + Debug.Assert(error == null || error->ErrorCode == 0, $"CompletionCallback called with error {(error != null ? error->ErrorCode : 0)}"); + + SafeDeleteNwContext thisContext = ResolveThisHandle(context); + Debug.Assert(thisContext != null, "Expected thisContext to be non-null"); + + thisContext._transportReadTcs.TrySetResult(); + } + } + + public override bool IsInvalid => ConnectionHandle.IsInvalid || (_framerHandle?.IsInvalid ?? true); + + [UnmanagedCallersOnly] + private static unsafe void StatusUpdateCallback(IntPtr thisHandle, NetworkFrameworkStatusUpdates statusUpdate, IntPtr data, IntPtr data2, Interop.NetworkFramework.NetworkFrameworkError* error) + { + try + { + SafeDeleteNwContext? nwContext = null; + + if (thisHandle != IntPtr.Zero) + { + nwContext = ResolveThisHandle(thisHandle); + } + + if (nwContext == null) + { + Debug.Assert(statusUpdate == NetworkFrameworkStatusUpdates.DebugLog, + "StatusUpdateCallback called with null thisHandle, but not a DebugLog update"); + } + + if (NetEventSource.Log.IsEnabled() && statusUpdate != NetworkFrameworkStatusUpdates.DebugLog) + NetEventSource.Info(nwContext, $"Received status update: {statusUpdate}"); + + switch (statusUpdate) + { + case NetworkFrameworkStatusUpdates.FramerStart: + nwContext!.FramerStartCallback(new SafeNwHandle(Interop.NetworkFramework.Retain(data), true)); + break; + case NetworkFrameworkStatusUpdates.HandshakeFinished: + nwContext!.HandshakeFinished(); + break; + case NetworkFrameworkStatusUpdates.ConnectionFailed: + Debug.Assert(error != null, "ConnectionFailed should have an error"); + nwContext!.ConnectionFailed(in *error); + break; + case NetworkFrameworkStatusUpdates.ConnectionCancelled: + nwContext!.ConnectionClosed(); + break; + case NetworkFrameworkStatusUpdates.CertificateAvailable: + global::System.Runtime.InteropServices.Marshalling.SafeHandleMarshaller.ManagedToUnmanagedOut marshaller = new(); + marshaller.FromUnmanaged(data); + nwContext!.CertificateAvailable(marshaller.ToManaged()); + marshaller.Free(); + break; + case NetworkFrameworkStatusUpdates.DebugLog: + if (NetEventSource.Log.IsEnabled()) + NetEventSource.Info(nwContext, Marshal.PtrToStringAnsi(data)!, "Native"); + break; + default: // We shouldn't hit here. + if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(nwContext, $"Unknown status update: {statusUpdate}"); + Debug.Assert(false); + break; + } + } + catch (Exception ex) + { + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Error(null, $"StatusUpdateCallback failed for {statusUpdate}: {ex}"); + } + } + } + private void FramerStartCallback(SafeNwHandle framerHandle) + { + _framerHandle = framerHandle; + } + + private void HandshakeFinished() + { + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, "TLS handshake completed successfully"); + _handshakeCompletionSource.TrySetResult(null); + } + + private void ConnectionFailed(in Interop.NetworkFramework.NetworkFrameworkError error) + { + Exception ex = Interop.NetworkFramework.CreateExceptionForNetworkFrameworkError(in error); + if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, $"TLS handshake failed with error: {ex.Message}"); + _handshakeCompletionSource.TrySetResult(ExceptionDispatchInfo.SetCurrentStackTrace(ex)); + } + + private void ConnectionClosed() + { + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, "Connection was cancelled"); + _connectionClosedTcs.TrySetResult(); + _handshakeCompletionSource.TrySetResult(ExceptionDispatchInfo.SetCurrentStackTrace( + new IOException(SR.net_io_eof))); + // Complete any pending writes with connection closed exception + TaskCompletionSource? writeCompletion = _currentWriteCompletionSource; + if (writeCompletion != null) + { + _currentWriteCompletionSource = null; + writeCompletion.TrySetException(new IOException(SR.net_io_eof)); + } + } + + private void CertificateAvailable(SafeX509ChainHandle peerCertChainHandle) + { + _peerCertChainHandle = peerCertChainHandle; + } + + private static string[] ExtractAcceptableIssuers(IntPtr acceptableIssuersHandle) + { + if (acceptableIssuersHandle == IntPtr.Zero) + { + return Array.Empty(); + } + + var issuers = new List(); + + try + { + using var arrayHandle = new Microsoft.Win32.SafeHandles.SafeCFArrayHandle(acceptableIssuersHandle, ownsHandle: false); + int count = (int)Interop.CoreFoundation.CFArrayGetCount(arrayHandle); + + for (int i = 0; i < count; i++) + { + IntPtr dataRef = Interop.CoreFoundation.CFArrayGetValueAtIndex(arrayHandle, i); + if (dataRef != IntPtr.Zero) + { + // Create a non-owning handle for the CFData + using var dataHandle = new Microsoft.Win32.SafeHandles.SafeCFDataHandle(dataRef, ownsHandle: false); + // Get the DER-encoded DN data + byte[] derData = Interop.CoreFoundation.CFGetData(dataHandle); + + if (derData.Length > 0) + { + // Convert DER-encoded DN to string using X500DistinguishedName + try + { + X500DistinguishedName dn = new X500DistinguishedName(derData); + string issuerDn = dn.Name; + issuers.Add(issuerDn); + } + catch (Exception ex) + { + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Error(null, $"Failed to parse DN at index {i}: {ex.Message}"); + } + } + } + } + } + } + catch (Exception ex) + { + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Error(null, $"Failed to extract acceptable issuers: {ex.Message}"); + } + } + + return issuers.ToArray(); + } + } +} diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs index f1945c428363cd..fc6daac1c1824b 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs @@ -8,18 +8,16 @@ using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; +using OSStatus = Interop.AppleCrypto.OSStatus; namespace System.Net { internal sealed class SafeDeleteSslContext : SafeDeleteContext { // mapped from OSX error codes - private const int OSStatus_writErr = -20; - private const int OSStatus_readErr = -19; - private const int OSStatus_noErr = 0; - private const int OSStatus_errSSLWouldBlock = -9803; private const int InitialBufferSize = 2048; private readonly SafeSslHandle _sslContext; + private readonly object _lock = new object(); private ArrayBuffer _inputBuffer = new ArrayBuffer(InitialBufferSize); private ArrayBuffer _outputBuffer = new ArrayBuffer(InitialBufferSize); @@ -205,7 +203,7 @@ protected override void Dispose(bool disposing) SafeSslHandle sslContext = _sslContext; if (null != sslContext) { - lock (_sslContext) + lock (_lock) { _inputBuffer.Dispose(); _outputBuffer.Dispose(); @@ -228,7 +226,7 @@ private static unsafe int WriteToConnection(IntPtr connection, byte* data, void* // but if we were to pool the buffers we would have a potential use-after-free issue. try { - lock (context) + lock (context._lock) { ulong length = (ulong)*dataLength; Debug.Assert(length <= int.MaxValue); @@ -241,14 +239,14 @@ private static unsafe int WriteToConnection(IntPtr connection, byte* data, void* context._outputBuffer.Commit(toWrite); // Since we can enqueue everything, no need to re-assign *dataLength. - return OSStatus_noErr; + return OSStatus.NoErr; } } catch (Exception e) { if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(context, $"WritingToConnection failed: {e.Message}"); - return OSStatus_writErr; + return OSStatus.WritErr; } } @@ -260,13 +258,13 @@ private static unsafe int ReadFromConnection(IntPtr connection, byte* data, void try { - lock (context) + lock (context._lock) { ulong toRead = (ulong)*dataLength; if (toRead == 0) { - return OSStatus_noErr; + return OSStatus.NoErr; } uint transferred = 0; @@ -274,7 +272,7 @@ private static unsafe int ReadFromConnection(IntPtr connection, byte* data, void if (context._inputBuffer.ActiveLength == 0) { *dataLength = (void*)0; - return OSStatus_errSSLWouldBlock; + return OSStatus.ErrSSLWouldBlock; } int limit = Math.Min((int)toRead, context._inputBuffer.ActiveLength); @@ -284,20 +282,20 @@ private static unsafe int ReadFromConnection(IntPtr connection, byte* data, void transferred = (uint)limit; *dataLength = (void*)transferred; - return OSStatus_noErr; + return OSStatus.NoErr; } } catch (Exception e) { if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(context, $"ReadFromConnectionfailed: {e.Message}"); - return OSStatus_readErr; + return OSStatus.ReadErr; } } internal void Write(ReadOnlySpan buf) { - lock (_sslContext) + lock (_lock) { _inputBuffer.EnsureAvailableSpace(buf.Length); buf.CopyTo(_inputBuffer.AvailableSpan); @@ -309,7 +307,7 @@ internal void Write(ReadOnlySpan buf) internal void ReadPendingWrites(ref ProtocolToken token) { - lock (_sslContext) + lock (_lock) { if (_outputBuffer.ActiveLength == 0) { @@ -331,7 +329,7 @@ internal int ReadPendingWrites(byte[] buf, int offset, int count) Debug.Assert(count >= 0); Debug.Assert(count <= buf.Length - offset); - lock (_sslContext) + lock (_lock) { int limit = Math.Min(count, _outputBuffer.ActiveLength); diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs index 0236ff306152bd..fce59ffaef0d74 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs @@ -9,15 +9,11 @@ namespace System.Net.Security { - internal sealed class SslAuthenticationOptions + internal sealed class SslAuthenticationOptions : IDisposable { private const string EnableOcspStaplingContextSwitchName = "System.Net.Security.EnableServerOcspStaplingFromOnlyCertificateOnLinux"; - internal static readonly X509RevocationMode DefaultRevocationMode = - AppContextSwitchHelper.GetBooleanConfig( - "System.Net.Security.NoRevocationCheckByDefault", - "DOTNET_SYSTEM_NET_SECURITY_NOREVOCATIONCHECKBYDEFAULT") - ? X509RevocationMode.NoCheck : X509RevocationMode.Online; + internal const X509RevocationMode DefaultRevocationMode = X509RevocationMode.NoCheck; internal SslAuthenticationOptions() { @@ -153,7 +149,7 @@ internal void UpdateOptions(SslServerAuthenticationOptions sslServerAuthenticati bool ocspFetch = false; _ = AppContext.TryGetSwitch(EnableOcspStaplingContextSwitchName, out ocspFetch); // given cert is X509Certificate2 with key. We can use it directly. - CertificateContext = SslStreamCertificateContext.Create(certificateWithKey, additionalCertificates: null, offline: false, trust: null, noOcspFetch: !ocspFetch); + SetCertificateContextFromCert(certificateWithKey, !ocspFetch); } else { @@ -165,7 +161,7 @@ internal void UpdateOptions(SslServerAuthenticationOptions sslServerAuthenticati throw new AuthenticationException(SR.net_ssl_io_no_server_cert); } - CertificateContext = SslStreamCertificateContext.Create(certificateWithKey); + SetCertificateContextFromCert(certificateWithKey); } } @@ -195,13 +191,22 @@ private static SslProtocols FilterOutIncompatibleSslProtocols(SslProtocols proto return protocols; } + internal void SetCertificateContextFromCert(X509Certificate2 certificate, bool? noOcspFetch = null) + { + CertificateContext = SslStreamCertificateContext.Create(certificate, null, offline: false, null, noOcspFetch ?? true); + OwnsCertificateContext = true; + } + internal bool AllowRenegotiation { get; set; } internal string TargetHost { get; set; } internal X509CertificateCollection? ClientCertificates { get; set; } internal List? ApplicationProtocols { get; set; } internal bool IsServer { get; set; } internal bool IsClient => !IsServer; - internal SslStreamCertificateContext? CertificateContext { get; set; } + internal SslStreamCertificateContext? CertificateContext { get; private set; } + // If true, the certificate context was created by the SslStream and + // certificates inside should be disposed when no longer needed. + internal bool OwnsCertificateContext { get; private set; } internal SslProtocols EnabledSslProtocols { get; set; } internal X509RevocationMode CertificateRevocationCheckMode { get; set; } internal EncryptionPolicy EncryptionPolicy { get; set; } @@ -221,5 +226,17 @@ private static SslProtocols FilterOutIncompatibleSslProtocols(SslProtocols proto #if TARGET_ANDROID internal SslStream.JavaProxy? SslStreamProxy { get; set; } #endif + + public void Dispose() + { + if (OwnsCertificateContext && CertificateContext != null) + { + CertificateContext.ReleaseResources(); + } + +#if TARGET_ANDROID + SslStreamProxy?.Dispose(); +#endif + } } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslConnectionInfo.OSX.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslConnectionInfo.OSX.cs index 06546583205831..4d9492a77b59cd 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslConnectionInfo.OSX.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslConnectionInfo.OSX.cs @@ -4,12 +4,62 @@ using System.Collections.Generic; using System.Diagnostics; using System.Security.Authentication; +using SafeNwHandle = Interop.SafeNwHandle; namespace System.Net.Security { internal partial struct SslConnectionInfo { - public void UpdateSslConnectionInfo(SafeDeleteSslContext context) + public void UpdateSslConnectionInfo(SafeDeleteContext context) + { + switch (context) + { + case SafeDeleteNwContext nwContext: + UpdateSslConnectionInfoNetworkFramework(nwContext); + break; + case SafeDeleteSslContext sslContext: + UpdateSslConnectionInfoAppleCrypto(sslContext); + break; + default: + throw new NotSupportedException("Unsupported context type."); + } + } + + private void UpdateSslConnectionInfoNetworkFramework(SafeDeleteNwContext context) + { + SafeNwHandle nwContext = context.ConnectionHandle; + SslProtocols protocol; + TlsCipherSuite cipherSuite; + + Span alpn = stackalloc byte[256]; // Ensure the stack is initialized for alpnPtr + int alpnLength = alpn.Length; + + int osStatus; + unsafe + { + fixed (byte* alpnPtr = alpn) + { + // Call the native method to get connection info + osStatus = Interop.NetworkFramework.Tls.GetConnectionInfo(nwContext, context.StateHandle, out protocol, out cipherSuite, alpnPtr, ref alpnLength); + } + } + + if (osStatus != 0) + { + throw Interop.AppleCrypto.CreateExceptionForOSStatus(osStatus); + } + + if (alpnLength > 0) + { + ApplicationProtocol = alpn.Slice(0, alpnLength).ToArray(); + } + + Protocol = (int)protocol; + TlsCipherSuite = cipherSuite; + MapCipherSuite(cipherSuite); + } + + private void UpdateSslConnectionInfoAppleCrypto(SafeDeleteSslContext context) { SafeSslHandle sslContext = context.SslContext; SslProtocols protocol; diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.IO.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.IO.cs index eac06538b92119..cda4db5e7f7cad 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.IO.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.IO.cs @@ -15,7 +15,8 @@ namespace System.Net.Security { public partial class SslStream { - private readonly SslAuthenticationOptions _sslAuthenticationOptions = new SslAuthenticationOptions(); + internal readonly SslAuthenticationOptions _sslAuthenticationOptions = new SslAuthenticationOptions(); + internal new Stream InnerStream => base.InnerStream; private NestedState _nestedAuth; private bool _isRenego; @@ -295,6 +296,30 @@ private async Task ForceAuthenticationAsync(bool receiveFirst, byte[ } try { +#if TARGET_APPLE + if (SslStreamPal.ShouldUseAsyncSecurityContext(_sslAuthenticationOptions)) + { + Debug.Assert(_sslAuthenticationOptions.IsClient); + byte[]? dummy = null; + AcquireClientCredentials(ref dummy, true); + + Task handshakeTask = SslStreamPal.AsyncHandshakeAsync(ref _securityContext, this, cancellationToken); + await TIOAdapter.WaitAsync(handshakeTask).ConfigureAwait(false); + if (await handshakeTask.ConfigureAwait(false) is Exception ex) + { + if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, ex, "Async handshake failed"); + if (ex is ArgumentException or IOException) + { + throw ex; + } + throw new AuthenticationException(SR.net_auth_SSPI, ex); + } + + CompleteHandshake(_sslAuthenticationOptions); + return; + } +#endif // TARGET_APPLE + if (!receiveFirst) { token = NextMessage(reAuthenticationData, out int consumed); @@ -820,7 +845,6 @@ private SecurityStatusPal DecryptData(int frameSize) private async ValueTask ReadAsyncInternal(Memory buffer, CancellationToken cancellationToken) where TIOAdapter : IReadWriteAdapter { - // Throw first if we already have exception. // Check for disposal is not atomic so we will check again below. ThrowIfExceptionalOrNotAuthenticated(); @@ -833,6 +857,15 @@ private async ValueTask ReadAsyncInternal(Memory buffer, try { + +#if TARGET_APPLE + if (SslStreamPal.IsAsyncSecurityContext(_securityContext!)) + { + ValueTask task = SslStreamPal.AsyncReadAsync(_securityContext!, buffer, cancellationToken); + return await TIOAdapter.WaitAsync(task).ConfigureAwait(false); + } +#endif // TARGET_APPLE + int processedLength = 0; int nextTlsFrameLength = UnknownTlsFrameLength; @@ -974,6 +1007,15 @@ private async ValueTask WriteAsyncInternal(ReadOnlyMemory buff try { +#if TARGET_APPLE + if (SslStreamPal.IsAsyncSecurityContext(_securityContext!)) + { + Task task = SslStreamPal.AsyncWriteAsync(_securityContext!, buffer, cancellationToken); + await TIOAdapter.WaitAsync(task).ConfigureAwait(false); + return; + } +#endif // TARGET_APPLE + ValueTask t = buffer.Length < MaxDataSize ? WriteSingleChunk(buffer, cancellationToken) : WriteAsyncChunked(buffer, cancellationToken); diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs index 4e9f4327ee9e22..7e16048b8256ea 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs @@ -50,7 +50,13 @@ internal static bool DisableTlsResume private SafeFreeCredentials? _credentialsHandle; + +#if TARGET_APPLE + // on OSX, we have two implementations of SafeDeleteContext, so store a reference to the base class + private SafeDeleteContext? _securityContext; +#else private SafeDeleteSslContext? _securityContext; +#endif private SslConnectionInfo _connectionInfo; private X509Certificate? _selectedClientCertificate; @@ -170,9 +176,7 @@ internal void CloseContext() _securityContext?.Dispose(); _credentialsHandle?.Dispose(); -#if TARGET_ANDROID - _sslAuthenticationOptions.SslStreamProxy?.Dispose(); -#endif + _sslAuthenticationOptions.Dispose(); } // @@ -568,7 +572,7 @@ This will not restart a session but helps minimizing the number of handles we cr --*/ - private bool AcquireClientCredentials(ref byte[]? thumbPrint, bool newCredentialsRequested = false) + internal bool AcquireClientCredentials(ref byte[]? thumbPrint, bool newCredentialsRequested = false) { // Acquire possible Client Certificate information and set it on the handle. bool cachedCred = false; // this is a return result from this method. @@ -577,11 +581,7 @@ private bool AcquireClientCredentials(ref byte[]? thumbPrint, bool newCredential if (newCredentialsRequested) { - if (selectedCert != null) - { - // build the cert context only if it was not provided by the user - _sslAuthenticationOptions.CertificateContext ??= SslStreamCertificateContext.Create(selectedCert); - } + UpdateCertificateContext(selectedCert); if (SslStreamPal.TryUpdateClintCertificate(_credentialsHandle, _securityContext, _sslAuthenticationOptions)) { @@ -639,17 +639,11 @@ private bool AcquireClientCredentials(ref byte[]? thumbPrint, bool newCredential NetEventSource.Log.UsingCachedCredential(this); _credentialsHandle = cachedCredentialHandle; cachedCred = true; - if (selectedCert != null) - { - _sslAuthenticationOptions.CertificateContext ??= SslStreamCertificateContext.Create(selectedCert!); - } + UpdateCertificateContext(selectedCert); } else { - if (selectedCert != null) - { - _sslAuthenticationOptions.CertificateContext ??= SslStreamCertificateContext.Create(selectedCert!); - } + UpdateCertificateContext(selectedCert); _credentialsHandle = AcquireCredentialsHandle(_sslAuthenticationOptions, newCredentialsRequested); thumbPrint = guessedThumbPrint; // Delay until here in case something above threw. @@ -657,13 +651,18 @@ private bool AcquireClientCredentials(ref byte[]? thumbPrint, bool newCredential } finally { - if (selectedCert != null) - { - _sslAuthenticationOptions.CertificateContext ??= SslStreamCertificateContext.Create(selectedCert); - } + UpdateCertificateContext(selectedCert); } return cachedCred; + + void UpdateCertificateContext(X509Certificate2? cert) + { + if (cert != null && _sslAuthenticationOptions.CertificateContext == null) + { + _sslAuthenticationOptions.SetCertificateContextFromCert(cert); + } + } } private static List EnsureInitialized(ref List? list) => list ??= new List(); @@ -737,7 +736,7 @@ private bool AcquireServerCredentials(ref byte[]? thumbPrint) } Debug.Assert(localCertificate.Equals(selectedCert), "'selectedCert' does not match 'localCertificate'."); - _sslAuthenticationOptions.CertificateContext = SslStreamCertificateContext.Create(selectedCert); + _sslAuthenticationOptions.SetCertificateContextFromCert(selectedCert); } Debug.Assert(_sslAuthenticationOptions.CertificateContext != null); @@ -1048,6 +1047,13 @@ internal bool VerifyRemoteCertificate(RemoteCertificateValidationCallback? remot bool success = false; X509Chain? chain = null; + // We need to note the number of certs in ExtraStore that were + // provided (by the user), we will add more from the received peer + // chain and we want to dispose only these after we perform the + // validation. + // TODO: this forces allocation of X509Certificate2Collection + int preexistingExtraCertsCount = _sslAuthenticationOptions.CertificateChainPolicy?.ExtraStore?.Count ?? 0; + try { X509Certificate2? certificate = CertificateValidationPal.GetRemoteCertificate(_securityContext, ref chain, _sslAuthenticationOptions.CertificateChainPolicy); @@ -1135,7 +1141,13 @@ internal bool VerifyRemoteCertificate(RemoteCertificateValidationCallback? remot if (!success) { - CreateFatalHandshakeAlertToken(sslPolicyErrors, chain!, ref alertToken); +#pragma warning disable CS0162 // unreachable code detected (compile time const) + if (SslStreamPal.CanGenerateCustomAlerts) + { + CreateFatalHandshakeAlertToken(sslPolicyErrors, chain!, ref alertToken); + } +#pragma warning restore CS0162 // unreachable code detected (compile time const) + if (chain != null) { foreach (X509ChainStatus status in chain.ChainStatus) @@ -1152,6 +1164,12 @@ internal bool VerifyRemoteCertificate(RemoteCertificateValidationCallback? remot if (chain != null) { + // Dispose only the certificates that were added by GetRemoteCertificate + for (int i = preexistingExtraCertsCount; i < chain.ChainPolicy.ExtraStore.Count; i++) + { + chain.ChainPolicy.ExtraStore[i].Dispose(); + } + int elementsCount = chain.ChainElements.Count; for (int i = 0; i < elementsCount; i++) { diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs index 06fd705edb8aca..e5073e79538531 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs @@ -416,5 +416,19 @@ private static string MakeUrl(string baseUri, ArraySegment encodedRequest) return uriString; } + + partial void ReleasePlatformSpecificResources() + { + Debug.Assert(_staplingForbidden, "Shouldn't release resources while OCSP stapling may be happening on the background."); + + CertificateHandle.Dispose(); + KeyHandle.Dispose(); + _rootCertificate?.Dispose(); + + foreach (X509Certificate2 cert in _privateIntermediateCertificates) + { + cert.Dispose(); + } + } } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Windows.cs index cc1a881d6f2a72..e84497cfe2db11 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Windows.cs @@ -42,6 +42,8 @@ private SslStreamCertificateContext(X509Certificate2 target, ReadOnlyCollection< count++; } + DisposeChainElements(chain); + // OS failed to build the chain but we have at least some intermediates. // We will try to add them to "Intermediate Certification Authorities" store. if (!osCanBuildChain) @@ -92,6 +94,8 @@ private SslStreamCertificateContext(X509Certificate2 target, ReadOnlyCollection< } } + DisposeChainElements(chain); + if (!osCanBuildChain) { // Add also root to Intermediate CA store so OS can complete building chain. @@ -123,6 +127,15 @@ static void TryAddToStore(X509Store store, X509Certificate2 certificate) } } } + + static void DisposeChainElements(X509Chain chain) + { + int elementsCount = chain.ChainElements.Count; + for (int i = 0; i < elementsCount; i++) + { + chain.ChainElements[i].Certificate.Dispose(); + } + } } } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.cs index b3540d646a1d25..b48b32934cf8bb 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.cs @@ -169,7 +169,29 @@ internal static SslStreamCertificateContext Create( internal SslStreamCertificateContext Duplicate() { - return new SslStreamCertificateContext(new X509Certificate2(TargetCertificate), IntermediateCertificates, Trust); + // Create will internally clone any certificates that it will + // retain, so we don't have to duplicate any of the instances here + X509Certificate2Collection intermediates = new X509Certificate2Collection(); + foreach (X509Certificate2 cert in IntermediateCertificates) + { + intermediates.Add(cert); + } + + return Create(new X509Certificate2(TargetCertificate), intermediates, trust: Trust); + } + + internal void ReleaseResources() + { + // TargetCertificate is owned by the user, but we have created the cert context + // which looked up intermediate certificates and only we have reference to them. + foreach (X509Certificate2 cert in IntermediateCertificates) + { + cert.Dispose(); + } + + ReleasePlatformSpecificResources(); } + + partial void ReleasePlatformSpecificResources(); } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Android.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Android.cs index 4a5de17a2a221f..a57db95f7bd9e5 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Android.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Android.cs @@ -22,6 +22,11 @@ public static Exception GetException(SecurityStatusPal status) internal const bool StartMutualAuthAsAnonymous = false; internal const bool CanEncryptEmptyMessage = false; + // There is no API to generate custom alerts on Android, but the interop layer currently + // depends on SslStream calling HandshakeInternal one last time when tearing down the connection + // due to handshake failures. + internal const bool CanGenerateCustomAlerts = true; + public static void VerifyPackageInfo() { } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs index add3454a6f14eb..4da95d52028243 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.IO; using System.Buffers; using System.Collections.Generic; using System.ComponentModel; @@ -9,6 +10,8 @@ using System.Security.Authentication; using System.Security.Authentication.ExtendedProtection; using System.Security.Cryptography.X509Certificates; +using System.Threading; +using System.Threading.Tasks; using PAL_TlsHandshakeState = Interop.AppleCrypto.PAL_TlsHandshakeState; using PAL_TlsIo = Interop.AppleCrypto.PAL_TlsIo; @@ -28,14 +31,20 @@ public static Exception GetException(SecurityStatusPal status) // Since ST is not producing the framed empty message just call this false and avoid the // special case of an empty array being passed to the `fixed` statement. internal const bool CanEncryptEmptyMessage = false; + internal const bool CanGenerateCustomAlerts = false; public static void VerifyPackageInfo() { } + public static bool IsAsyncSecurityContext(SafeDeleteContext securityContext) + { + return securityContext is SafeDeleteNwContext; + } + public static SecurityStatusPal SelectApplicationProtocol( SafeFreeCredentials? _, - SafeDeleteSslContext context, + SafeDeleteContext securityContext, SslAuthenticationOptions sslAuthenticationOptions, ReadOnlySpan clientProtocols) { @@ -46,6 +55,8 @@ public static SecurityStatusPal SelectApplicationProtocol( return new SecurityStatusPal(SecurityStatusPalErrorCode.OK); } + SafeDeleteSslContext context = (SafeDeleteSslContext)securityContext; + // We do server side ALPN e.g. walk the intersect in server order foreach (SslApplicationProtocol applicationProtocol in sslAuthenticationOptions.ApplicationProtocols) { @@ -88,7 +99,7 @@ public static SecurityStatusPal SelectApplicationProtocol( #pragma warning disable IDE0060 public static ProtocolToken AcceptSecurityContext( ref SafeFreeCredentials credential, - ref SafeDeleteSslContext? context, + ref SafeDeleteContext? context, ReadOnlySpan inputBuffer, out int consumed, SslAuthenticationOptions sslAuthenticationOptions) @@ -98,7 +109,7 @@ public static ProtocolToken AcceptSecurityContext( public static ProtocolToken InitializeSecurityContext( ref SafeFreeCredentials credential, - ref SafeDeleteSslContext? context, + ref SafeDeleteContext? context, string? _ /*targetName*/, ReadOnlySpan inputBuffer, out int consumed, @@ -109,7 +120,7 @@ public static ProtocolToken InitializeSecurityContext( public static ProtocolToken Renegotiate( ref SafeFreeCredentials? credentialsHandle, - ref SafeDeleteSslContext? context, + ref SafeDeleteContext? context, SslAuthenticationOptions sslAuthenticationOptions) { throw new PlatformNotSupportedException(); @@ -123,18 +134,21 @@ public static ProtocolToken Renegotiate( #pragma warning restore IDE0060 public static ProtocolToken EncryptMessage( - SafeDeleteSslContext securityContext, + SafeDeleteContext securityContext, ReadOnlyMemory input, int _ /*headerSize*/, int _1 /*trailerSize*/) { - ProtocolToken token = default; - Debug.Assert(input.Length > 0, $"{nameof(input.Length)} > 0 since {nameof(CanEncryptEmptyMessage)} is false"); + Debug.Assert(securityContext is SafeDeleteSslContext, "SafeDeleteSslContext expected"); + SafeDeleteSslContext sslContext = (SafeDeleteSslContext)securityContext; + + ProtocolToken token = default; + try { - SafeSslHandle sslHandle = securityContext.SslContext; + SafeSslHandle sslHandle = sslContext.SslContext; unsafe { @@ -169,7 +183,7 @@ public static ProtocolToken EncryptMessage( break; } - securityContext.ReadPendingWrites(ref token); + sslContext.ReadPendingWrites(ref token); } finally { @@ -186,18 +200,22 @@ public static ProtocolToken EncryptMessage( } public static SecurityStatusPal DecryptMessage( - SafeDeleteSslContext securityContext, + SafeDeleteContext securityContext, Span buffer, out int offset, out int count) { + Debug.Assert(securityContext is SafeDeleteSslContext, "SafeDeleteSslContext expected"); + SafeDeleteSslContext sslContext = (SafeDeleteSslContext)securityContext; + offset = 0; count = 0; try { - SafeSslHandle sslHandle = securityContext.SslContext; - securityContext.Write(buffer); + SafeSslHandle sslHandle = sslContext.SslContext; + + sslContext.Write(buffer); unsafe { @@ -261,7 +279,7 @@ public static void QueryContextStreamSizes( } public static void QueryContextConnectionInfo( - SafeDeleteSslContext securityContext, + SafeDeleteContext securityContext, ref SslConnectionInfo connectionInfo) { connectionInfo.UpdateSslConnectionInfo(securityContext); @@ -269,10 +287,23 @@ public static void QueryContextConnectionInfo( public static bool TryUpdateClintCertificate( SafeFreeCredentials? _, - SafeDeleteSslContext? context, + SafeDeleteContext? context, SslAuthenticationOptions sslAuthenticationOptions) { - SafeDeleteSslContext? sslContext = ((SafeDeleteSslContext?)context); + if (context == null) + { + return false; + } + + if (context is SafeDeleteNwContext) + { + // We are being called from Network Framework, we will retrieve + // the selected certificate from higher frame in the callstack + // and return it as return value of the callback + return true; + } + + SafeDeleteSslContext sslContext = ((SafeDeleteSslContext)context); if (sslAuthenticationOptions.CertificateContext != null) { @@ -283,7 +314,7 @@ public static bool TryUpdateClintCertificate( } private static ProtocolToken HandshakeInternal( - ref SafeDeleteSslContext? context, + ref SafeDeleteContext? context, ReadOnlySpan inputBuffer, out int consumed, SslAuthenticationOptions sslAuthenticationOptions) @@ -293,23 +324,27 @@ private static ProtocolToken HandshakeInternal( try { - SafeDeleteSslContext? sslContext = ((SafeDeleteSslContext?)context); - if ((null == context) || context.IsInvalid) { - sslContext = new SafeDeleteSslContext(sslAuthenticationOptions); - context = sslContext; + Debug.Assert(!ShouldUseAsyncSecurityContext(sslAuthenticationOptions)); + + if (NetEventSource.Log.IsEnabled()) + NetEventSource.Info(null, $"Using SecureTransport (SafeDeleteSslContext) for TLS connection - Protocols: {sslAuthenticationOptions.EnabledSslProtocols}, IsClient: {sslAuthenticationOptions.IsClient}, NetworkFrameworkAvailable: {SafeDeleteNwContext.IsNetworkFrameworkAvailable}"); + + context = new SafeDeleteSslContext(sslAuthenticationOptions); } + Debug.Assert(context is SafeDeleteSslContext, "SafeDeleteSslContext expected"); + SafeDeleteSslContext sslContext = (SafeDeleteSslContext)context; + if (inputBuffer.Length > 0) { - sslContext!.Write(inputBuffer); + sslContext.Write(inputBuffer); } consumed = inputBuffer.Length; - SafeSslHandle sslHandle = sslContext!.SslContext; - token.Status = PerformHandshake(sslHandle); + token.Status = PerformHandshake(sslContext.SslContext); if (token.Status.ErrorCode == SecurityStatusPalErrorCode.CredentialsNeeded) { @@ -370,14 +405,23 @@ public static SecurityStatusPal ApplyAlertToken( // There doesn't seem to be an exposed API for writing an alert, // the API seems to assume that all alerts are generated internally by // SSLHandshake. + Debug.Assert(CanGenerateCustomAlerts); return new SecurityStatusPal(SecurityStatusPalErrorCode.OK); } #pragma warning restore IDE0060 public static SecurityStatusPal ApplyShutdownToken( - SafeDeleteSslContext securityContext) + SafeDeleteContext securityContext) { - SafeSslHandle sslHandle = securityContext.SslContext; + if (securityContext is SafeDeleteNwContext nwContext) + { + nwContext.Shutdown(); + return new SecurityStatusPal(SecurityStatusPalErrorCode.OK); + } + + Debug.Assert(securityContext is SafeDeleteSslContext, "SafeDeleteSslContext expected"); + SafeDeleteSslContext context = (SafeDeleteSslContext)securityContext; + SafeSslHandle sslHandle = context.SslContext; int osStatus = Interop.AppleCrypto.SslShutdown(sslHandle); @@ -390,5 +434,60 @@ public static SecurityStatusPal ApplyShutdownToken( SecurityStatusPalErrorCode.InternalError, Interop.AppleCrypto.CreateExceptionForOSStatus(osStatus)); } + + internal static bool ShouldUseAsyncSecurityContext(SslAuthenticationOptions sslAuthenticationOptions) + { + return ShouldUseNetworkFramework(sslAuthenticationOptions); + } + + private static bool ShouldUseNetworkFramework( + SslAuthenticationOptions sslAuthenticationOptions) + { + return + sslAuthenticationOptions.IsClient && + SafeDeleteNwContext.IsNetworkFrameworkAvailable && + (sslAuthenticationOptions.EnabledSslProtocols == SslProtocols.None || + sslAuthenticationOptions.EnabledSslProtocols == SslProtocols.Tls13 || + (sslAuthenticationOptions.EnabledSslProtocols == (SslProtocols.Tls12 | SslProtocols.Tls13))); + } + + private static SafeDeleteNwContext CreateAsyncSecurityContext(SslStream stream) + { + Debug.Assert(ShouldUseAsyncSecurityContext(stream._sslAuthenticationOptions), + "ShouldUseAsyncSecurityContext should be true when creating an async security context."); + + if (NetEventSource.Log.IsEnabled()) + NetEventSource.Info(null, $"Using Network Framework (SafeDeleteNwContext) for TLS connection - Protocols: {stream._sslAuthenticationOptions.EnabledSslProtocols}"); + return new SafeDeleteNwContext(stream); + } + + internal static Task AsyncHandshakeAsync(ref SafeDeleteContext? context, SslStream stream, CancellationToken cancellationToken) + { + Debug.Assert(context == null); + try + { + SafeDeleteNwContext nwContext = CreateAsyncSecurityContext(stream); + context = nwContext; + return nwContext.HandshakeAsync(cancellationToken); + } + catch (Exception e) + { + return Task.FromResult(e); + } + } + + internal static Task AsyncWriteAsync(SafeDeleteContext securityContext, ReadOnlyMemory buffer, CancellationToken cancellationToken) + { + Debug.Assert(securityContext is SafeDeleteNwContext, "SafeDeleteNwContext expected for async write"); + SafeDeleteNwContext nwContext = (SafeDeleteNwContext)securityContext; + return nwContext.WriteAsync(buffer, cancellationToken); + } + + internal static ValueTask AsyncReadAsync(SafeDeleteContext securityContext, Memory buffer, CancellationToken cancellationToken) + { + Debug.Assert(securityContext is SafeDeleteNwContext, "SafeDeleteNwContext expected for async read"); + SafeDeleteNwContext nwContext = (SafeDeleteNwContext)securityContext; + return nwContext.ReadAsync(buffer, cancellationToken); + } } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs index 700531aa49d35d..1de318873fca10 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs @@ -19,6 +19,7 @@ public static Exception GetException(SecurityStatusPal status) internal const bool StartMutualAuthAsAnonymous = false; internal const bool CanEncryptEmptyMessage = false; + internal const bool CanGenerateCustomAlerts = false; public static void VerifyPackageInfo() { @@ -242,6 +243,7 @@ public static SecurityStatusPal ApplyAlertToken(SafeDeleteContext? securityConte // There doesn't seem to be an exposed API for writing an alert, // the API seems to assume that all alerts are generated internally by // SSLHandshake. + Debug.Assert(CanGenerateCustomAlerts); return new SecurityStatusPal(SecurityStatusPalErrorCode.OK); } #pragma warning restore IDE0060 diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs index 61bc2fd2e71c04..2f29cc44c2583e 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs @@ -45,6 +45,7 @@ public static Exception GetException(SecurityStatusPal status) internal const bool StartMutualAuthAsAnonymous = true; internal const bool CanEncryptEmptyMessage = true; + internal const bool CanGenerateCustomAlerts = true; private static readonly byte[] s_sessionTokenBuffer = InitSessionTokenBuffer(); diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/LoggingTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/LoggingTest.cs index 52a8282409aacd..46fe333f26860e 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/LoggingTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/LoggingTest.cs @@ -28,6 +28,10 @@ public void EventSource_ExistsWithCorrectId() [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS, "X509 certificate store is not supported on iOS or tvOS.")] // Match SslStream_StreamToStream_Authentication_Success public async Task EventSource_EventsRaisedAsExpected() { + if (PlatformDetection.IsNetworkFrameworkEnabled()) + { + throw new SkipTestException("We'll deal with EventSources later."); + } await RemoteExecutor.Invoke(async () => { try diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamConformanceTests.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamConformanceTests.cs index c89c4802c8d467..dd01c99c4b5a49 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamConformanceTests.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamConformanceTests.cs @@ -7,6 +7,8 @@ using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using Xunit; +using Xunit.Abstractions; +using Microsoft.DotNet.XUnitExtensions; namespace System.Net.Security.Tests { @@ -48,6 +50,23 @@ await new[] return new StreamPair(ssl1, ssl2); } + + [ConditionalTheory] + [InlineData(ReadWriteMode.SyncArray)] + [InlineData(ReadWriteMode.SyncSpan)] + [InlineData(ReadWriteMode.AsyncArray)] + [InlineData(ReadWriteMode.AsyncMemory)] + [InlineData(ReadWriteMode.SyncAPM)] + [InlineData(ReadWriteMode.AsyncAPM)] + public override Task ZeroByteRead_PerformsZeroByteReadOnUnderlyingStreamWhenDataNeeded(ReadWriteMode mode) + { + if (PlatformDetection.IsNetworkFrameworkEnabled()) + { + throw new SkipTestException("NetworkFramework works in Async and does not issue zero-byte reads to underlying stream."); + } + + return base.ZeroByteRead_PerformsZeroByteReadOnUnderlyingStreamWhenDataNeeded(mode); + } } public sealed class SslStreamMemoryConformanceTests : SslStreamConformanceTests diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamDisposeTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamDisposeTest.cs index 9864029c7a0b34..4d2e1e30807f37 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamDisposeTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamDisposeTest.cs @@ -92,8 +92,8 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout( { // This will read everything into internal buffer. Following ReadAsync will not need IO. task = client.ReadAsync(readBuffer, 0, 4, cts.Token); - client.Dispose(); int readLength = await task.ConfigureAwait(false); + client.Dispose(); Assert.Equal(4, readLength); } else diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamMutualAuthenticationTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamMutualAuthenticationTest.cs index e8ddb07f82df76..d87b536f5f6d09 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamMutualAuthenticationTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamMutualAuthenticationTest.cs @@ -114,6 +114,10 @@ public async Task SslStream_RequireClientCert_IsMutuallyAuthenticated_ReturnsTru Assert.False(server.IsMutuallyAuthenticated, "server.IsMutuallyAuthenticated"); } } + + // Assert that the certificates are not being disposed + Assert.NotEqual(_clientCertificate.Handle, IntPtr.Zero); + Assert.NotEqual(_serverCertificate.Handle, IntPtr.Zero); } [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] @@ -152,7 +156,8 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout( // mutual authentication should only be set if server required client cert Assert.Equal(expectMutualAuthentication, server.IsMutuallyAuthenticated); Assert.Equal(expectMutualAuthentication, client.IsMutuallyAuthenticated); - }; + } + ; } } @@ -268,7 +273,8 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout( { Assert.Null(server.RemoteCertificate); } - }; + } + ; } } @@ -322,7 +328,8 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout( { Assert.Null(server.RemoteCertificate); } - }; + } + ; } } @@ -380,7 +387,8 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout( { Assert.Null(server.RemoteCertificate); } - }; + } + ; } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNegotiatedCipherSuiteTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNegotiatedCipherSuiteTest.cs index 38da62537c6401..79ff6cb6120c31 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNegotiatedCipherSuiteTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNegotiatedCipherSuiteTest.cs @@ -55,6 +55,12 @@ public class NegotiatedCipherSuiteTest if (PlatformDetection.IsAndroid) return false; + if (PlatformDetection.IsNetworkFrameworkEnabled()) + { + // Network.framework CipherSuite APIs doesn't enforce the given list. + return false; + } + try { new CipherSuitesPolicy(Array.Empty()); diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs index aadf36b19d114f..811b6932e896de 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs @@ -807,6 +807,18 @@ public async Task SslStream_ServerUntrustedCaWithCustomTrust_OK(bool usePartialC await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2); } + + // the ownership of the ExtraStore cert is not transferred to the + // SslStream, so we need to verify that the certs are still valid. + foreach (X509Certificate2 cert in clientOptions.CertificateChainPolicy.ExtraStore) + { + Assert.NotEqual(cert.Handle, IntPtr.Zero); + } + + foreach (X509Certificate2 cert in clientOptions.CertificateChainPolicy.CustomTrustStore) + { + Assert.NotEqual(cert.Handle, IntPtr.Zero); + } } private async Task SslStream_ClientSendsChain_Core(SslClientAuthenticationOptions clientOptions, X509Certificate2Collection clientChain) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamOpenSslNamedKeysTests.manual.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamOpenSslNamedKeysTests.manual.cs index 4f844044c92222..853e749a1b2ccb 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamOpenSslNamedKeysTests.manual.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamOpenSslNamedKeysTests.manual.cs @@ -23,7 +23,7 @@ public static async Task Provider_TPM2SslStream_ServerCertIsTpmEcDsa() [ConditionalTheory(typeof(OpenSslNamedKeysHelpers), nameof(OpenSslNamedKeysHelpers.ShouldRunProviderRsaTests))] [MemberData(nameof(OpenSslNamedKeysHelpers.RSASignaturePaddingValues), MemberType = typeof(OpenSslNamedKeysHelpers))] - public static async void Provider_TPM2SslStream_ServerCertIsTpmRsa(RSASignaturePadding padding) + public static async Task Provider_TPM2SslStream_ServerCertIsTpmRsa(RSASignaturePadding padding) { using X509Certificate2 serverCert = CreateSelfSignedRsaCertificate(padding); CreateTlsOptionsForRsa(serverCert, out SslServerAuthenticationOptions serverOptions, out SslClientAuthenticationOptions clientOptions); diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamRemoteExecutorTests.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamRemoteExecutorTests.cs index 4ac1691eb7f1fb..46a4707b43cf01 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamRemoteExecutorTests.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamRemoteExecutorTests.cs @@ -83,31 +83,5 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout( Assert.True(File.ReadAllText(tempFile).Length == 0); } } - - [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] - [InlineData(true)] - [InlineData(false)] - public void DefaultRevocationMode_OfflineRevocationByDefault_True_UsesNoCheck(bool useEnvVar) - { - var psi = new ProcessStartInfo(); - if (useEnvVar) - { - psi.Environment.Add("DOTNET_SYSTEM_NET_SECURITY_NOREVOCATIONCHECKBYDEFAULT", "true"); - } - - Assert.Equal(X509RevocationMode.Online, new SslClientAuthenticationOptions().CertificateRevocationCheckMode); - Assert.Equal(X509RevocationMode.Online, new SslServerAuthenticationOptions().CertificateRevocationCheckMode); - - RemoteExecutor.Invoke(useEnvVar => - { - if (!bool.Parse(useEnvVar)) - { - AppContext.SetSwitch("System.Net.Security.NoRevocationCheckByDefault", true); - } - - Assert.Equal(X509RevocationMode.NoCheck, new SslClientAuthenticationOptions().CertificateRevocationCheckMode); - Assert.Equal(X509RevocationMode.NoCheck, new SslServerAuthenticationOptions().CertificateRevocationCheckMode); - }, useEnvVar.ToString(), new RemoteInvokeOptions { StartInfo = psi }).Dispose(); - } } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs index a510fedaf47fd6..520db2e7000b56 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs @@ -274,13 +274,18 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout( Assert.Equal(rawHostname, client.TargetHostName); } - [Theory] + [ConditionalTheory] [InlineData("www-.volal.cz")] [InlineData("www-.colorhexa.com")] [InlineData("xn--www-7m0a.thegratuit.com")] [SkipOnPlatform(TestPlatforms.Android, "Safe invalid IDN hostnames are not supported on Android")] public async Task SslStream_SafeInvalidIdn_Success(string name) { + if (PlatformDetection.IsNetworkFrameworkEnabled()) + { + throw new SkipTestException("Safe invalid IDN hostnames are not supported on Network.framework"); + } + (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams(); using (client) using (server) @@ -378,7 +383,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/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs index d495f9dfc268b7..494080f0c794a0 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs @@ -133,10 +133,15 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout(client.AuthenticateAsClien } } - [Fact] + [ConditionalFact] [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS, "X509 certificate store is not supported on iOS or tvOS.")] public async Task Read_CorrectlyUnlocksAfterFailure() { + if (PlatformDetection.IsNetworkFrameworkEnabled()) + { + throw new SkipTestException("Reads and writes to inner streams are happening on different thread, so the exception does not propagate"); + } + (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams(); var clientStream = new ThrowingDelegatingStream(stream1); using (var clientSslStream = new SslStream(clientStream, false, AllowAnyServerCertificate)) @@ -210,10 +215,15 @@ public async Task Read_InvokedSynchronously() } } - [Fact] + [ConditionalFact] [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS, "X509 certificate store is not supported on iOS or tvOS.")] public async Task Write_InvokedSynchronously() { + if (PlatformDetection.IsNetworkFrameworkEnabled()) + { + throw new SkipTestException("Reads and writes to inner streams are happening on different thread, so we're calling InnerStream Read/Write async."); + } + (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams(); var clientStream = new PreReadWriteActionDelegatingStream(stream1); using (var clientSslStream = new SslStream(clientStream, false, AllowAnyServerCertificate)) diff --git a/src/libraries/System.Net.Security/tests/UnitTests/SslAuthenticationOptionsTests.cs b/src/libraries/System.Net.Security/tests/UnitTests/SslAuthenticationOptionsTests.cs index 22c8bcfffae93d..249a2921c68f29 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/SslAuthenticationOptionsTests.cs +++ b/src/libraries/System.Net.Security/tests/UnitTests/SslAuthenticationOptionsTests.cs @@ -80,7 +80,7 @@ public void LocalCertificateSelectionCallback_Get_Set_Succeeds() [InlineData("hello")] [InlineData(" \t")] [InlineData(null)] - public void TargetHost_Get_Set_Succeeds(string expected) + public void TargetHost_Get_Set_Succeeds(string? expected) { Assert.Null(_clientOptions.TargetHost); _clientOptions.TargetHost = expected; @@ -133,13 +133,13 @@ public void EnabledSslProtocols_Get_Set_Succeeds() [Fact] public void CheckCertificateRevocation_Get_Set_Succeeds() { - Assert.Equal(X509RevocationMode.Online, _clientOptions.CertificateRevocationCheckMode); - Assert.Equal(X509RevocationMode.Online, _serverOptions.CertificateRevocationCheckMode); + Assert.Equal(X509RevocationMode.NoCheck, _clientOptions.CertificateRevocationCheckMode); + Assert.Equal(X509RevocationMode.NoCheck, _serverOptions.CertificateRevocationCheckMode); - _clientOptions.CertificateRevocationCheckMode = X509RevocationMode.NoCheck; + _clientOptions.CertificateRevocationCheckMode = X509RevocationMode.Online; _serverOptions.CertificateRevocationCheckMode = X509RevocationMode.Offline; - Assert.Equal(X509RevocationMode.NoCheck, _clientOptions.CertificateRevocationCheckMode); + Assert.Equal(X509RevocationMode.Online, _clientOptions.CertificateRevocationCheckMode); Assert.Equal(X509RevocationMode.Offline, _serverOptions.CertificateRevocationCheckMode); Assert.Throws(() => _clientOptions.CertificateRevocationCheckMode = (X509RevocationMode)3); diff --git a/src/libraries/System.Net.ServerSentEvents/System.Net.ServerSentEvents.slnx b/src/libraries/System.Net.ServerSentEvents/System.Net.ServerSentEvents.slnx index 20574f56d2c8dd..d5109c9f2c8e72 100644 --- a/src/libraries/System.Net.ServerSentEvents/System.Net.ServerSentEvents.slnx +++ b/src/libraries/System.Net.ServerSentEvents/System.Net.ServerSentEvents.slnx @@ -1,47 +1,754 @@ + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.ServerSentEvents/src/System.Net.ServerSentEvents.csproj b/src/libraries/System.Net.ServerSentEvents/src/System.Net.ServerSentEvents.csproj index f4e9cf654a2d7a..2db346e77547d3 100644 --- a/src/libraries/System.Net.ServerSentEvents/src/System.Net.ServerSentEvents.csproj +++ b/src/libraries/System.Net.ServerSentEvents/src/System.Net.ServerSentEvents.csproj @@ -35,10 +35,10 @@ System.Net.ServerSentEvents.SseParser - - - - + + + + diff --git a/src/libraries/System.Net.Sockets/System.Net.Sockets.slnx b/src/libraries/System.Net.Sockets/System.Net.Sockets.slnx index 0c89c0d5beadf5..cd6713bffc80c8 100644 --- a/src/libraries/System.Net.Sockets/System.Net.Sockets.slnx +++ b/src/libraries/System.Net.Sockets/System.Net.Sockets.slnx @@ -1,36 +1,522 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj index a7776ec2dec283..054cc155bd13f7 100644 --- a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj +++ b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj @@ -303,24 +303,24 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs index ba8aa0aff49648..232c8e24381184 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs +++ b/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); } /// @@ -757,7 +731,7 @@ public ValueTask SendFileAsync(string? fileName, ReadOnlyMemory preBuffer, if (!IsConnectionOriented) { - var ex = new NotSupportedException(SR.net_notconnected); + var ex = ExceptionDispatchInfo.SetCurrentStackTrace(new NotSupportedException(SR.net_notconnected)); return ValueTask.FromException(ex); } @@ -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/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index bd7ba1a90b770e..369860de37bb3f 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -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/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs index c517bb70fc4031..a5527972a432ce 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs @@ -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/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs index c98d0cede114e5..a764b070544b18 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs +++ b/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/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs index 97f0d016b9d8dd..ac90675f515aa2 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs +++ b/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/libraries/System.Net.Sockets/tests/FunctionalTests/DisconnectTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisconnectTest.cs index 9fe7f43c703b29..196b3799033c1b 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisconnectTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisconnectTest.cs @@ -76,23 +76,23 @@ public async Task DisconnectAndReuse_ReconnectSync_ThrowsInvalidOperationExcepti [Theory] [InlineData(true)] [InlineData(false)] - public void Disconnect_NotConnected_ThrowsInvalidOperationException(bool reuseSocket) + public async Task Disconnect_NotConnected_ThrowsSocketException(bool reuseSocket) { using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { - Assert.ThrowsAsync(async () => await DisconnectAsync(s, reuseSocket)); + await Assert.ThrowsAsync(async () => await DisconnectAsync(s, reuseSocket)); } } [Theory] [InlineData(true)] [InlineData(false)] - public void Disconnect_ObjectDisposed_ThrowsObjectDisposedException(bool reuseSocket) + public async Task Disconnect_ObjectDisposed_ThrowsObjectDisposedException(bool reuseSocket) { using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { s.Dispose(); - Assert.ThrowsAsync(async () => await DisconnectAsync(s, reuseSocket)); + await Assert.ThrowsAsync(async () => await DisconnectAsync(s, reuseSocket)); } } } diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/KeepAliveTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/KeepAliveTest.cs index 1ce2ecc707dec7..48921474afdea3 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/KeepAliveTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/KeepAliveTest.cs @@ -144,7 +144,7 @@ public void Socket_Get_KeepAlive_Time_AsByteArray_OptionLengthZero_Failure() [InlineData(null)] [InlineData(new byte[0])] [InlineData(new byte[3] { 0, 0, 0 })] - public void Socket_Get_KeepAlive_Time_AsByteArray_BufferNullOrTooSmall_Failure(byte[] buffer) + public void Socket_Get_KeepAlive_Time_AsByteArray_BufferNullOrTooSmall_Failure(byte[]? buffer) { if (PlatformDetection.IsQemuLinux && (buffer == null || buffer.Length == 0)) { diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketOptionNameTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketOptionNameTest.cs index 6bb1ec42f58866..9df0b3c398b69a 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketOptionNameTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketOptionNameTest.cs @@ -16,6 +16,9 @@ namespace System.Net.Sockets.Tests public partial class SocketOptionNameTest { private static bool SocketsReuseUnicastPortSupport => Capability.SocketsReuseUnicastPortSupport().HasValue; + // Does not work on Nano and Qemu and AzureLinux has firewall enabled by default + private static readonly bool CanRunMulticastTests = !(PlatformDetection.IsWindowsNanoServer || PlatformDetection.IsWindowsServerCore || + PlatformDetection.IsAzureLinux || PlatformDetection.IsQemuLinux); [ConditionalFact(nameof(SocketsReuseUnicastPortSupport))] public void ReuseUnicastPort_CreateSocketGetOption() @@ -66,8 +69,7 @@ public void MulticastOption_CreateSocketSetGetOption_GroupAndInterfaceIndex_SetS } } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoNorServerCore))] // Skip on Nano: https://github.com/dotnet/runtime/issues/26286 - [ActiveIssue("https://github.com/dotnet/runtime/issues/104547", typeof(PlatformDetection), nameof(PlatformDetection.IsQemuLinux))] + [ConditionalFact(nameof(CanRunMulticastTests))] [ActiveIssue("https://github.com/dotnet/runtime/issues/113827", typeof(PlatformDetection), nameof(PlatformDetection.IsAppleMobile))] public async Task MulticastInterface_Set_AnyInterface_Succeeds() { @@ -124,10 +126,9 @@ public void MulticastInterface_Set_InvalidIndex_Throws() } } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoNorServerCore))] // Skip on Nano: https://github.com/dotnet/runtime/issues/26286 + [ConditionalFact(nameof(CanRunMulticastTests))] [SkipOnPlatform(TestPlatforms.OSX | TestPlatforms.FreeBSD, "Expected behavior is different on OSX or FreeBSD")] [ActiveIssue("https://github.com/dotnet/runtime/issues/52124", TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.MacCatalyst)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/104547", typeof(PlatformDetection), nameof(PlatformDetection.IsQemuLinux))] public async Task MulticastInterface_Set_IPv6_AnyInterface_Succeeds() { // On all platforms, index 0 means "any interface" diff --git a/src/libraries/System.Net.WebClient/System.Net.WebClient.slnx b/src/libraries/System.Net.WebClient/System.Net.WebClient.slnx index 90fb02c334e6ae..eea09d6b638ab3 100644 --- a/src/libraries/System.Net.WebClient/System.Net.WebClient.slnx +++ b/src/libraries/System.Net.WebClient/System.Net.WebClient.slnx @@ -1,47 +1,946 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.WebClient/src/System.Net.WebClient.csproj b/src/libraries/System.Net.WebClient/src/System.Net.WebClient.csproj index 8e615f49072629..4ef50ef0f62ac4 100644 --- a/src/libraries/System.Net.WebClient/src/System.Net.WebClient.csproj +++ b/src/libraries/System.Net.WebClient/src/System.Net.WebClient.csproj @@ -11,6 +11,11 @@ SR.SystemNetWebClient_PlatformNotSupported + + + + - - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/libraries/System.Net.WebClient/tests/WebClientTest.cs b/src/libraries/System.Net.WebClient/tests/WebClientTest.cs index e314088be3f9f0..7457d053171147 100644 --- a/src/libraries/System.Net.WebClient/tests/WebClientTest.cs +++ b/src/libraries/System.Net.WebClient/tests/WebClientTest.cs @@ -512,7 +512,7 @@ public abstract class WebClientTestBase [InlineData(null)] [InlineData("text/html; charset=utf-8")] [InlineData("text/html; charset=us-ascii")] - public async Task DownloadString_Success(string contentType) + public async Task DownloadString_Success(string? contentType) { await LoopbackServer.CreateServerAsync(async (server, url) => { diff --git a/src/libraries/System.Net.WebHeaderCollection/System.Net.WebHeaderCollection.slnx b/src/libraries/System.Net.WebHeaderCollection/System.Net.WebHeaderCollection.slnx index a34a1950ff5d7e..ceb6c3277de7db 100644 --- a/src/libraries/System.Net.WebHeaderCollection/System.Net.WebHeaderCollection.slnx +++ b/src/libraries/System.Net.WebHeaderCollection/System.Net.WebHeaderCollection.slnx @@ -1,35 +1,314 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.WebHeaderCollection/src/System.Net.WebHeaderCollection.csproj b/src/libraries/System.Net.WebHeaderCollection/src/System.Net.WebHeaderCollection.csproj index 459f088ee975a9..2150458a847e3d 100644 --- a/src/libraries/System.Net.WebHeaderCollection/src/System.Net.WebHeaderCollection.csproj +++ b/src/libraries/System.Net.WebHeaderCollection/src/System.Net.WebHeaderCollection.csproj @@ -21,11 +21,11 @@ - - - - - + + + + + diff --git a/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs b/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs index adb5537fd6f5b1..f8c6c440170026 100644 --- a/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs +++ b/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs @@ -27,8 +27,6 @@ public class WebHeaderCollection : NameValueCollection, ISerializable private WebHeaderCollectionType _type; private NameValueCollection? _innerCollection; - private static HeaderInfoTable? _headerInfo; - [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] protected WebHeaderCollection(SerializationInfo serializationInfo, StreamingContext streamingContext) @@ -48,7 +46,7 @@ private bool AllowHttpRequestHeader } } - private static HeaderInfoTable HeaderInfo => _headerInfo ??= new HeaderInfoTable(); + private static HeaderInfoTable HeaderInfo => field ??= new HeaderInfoTable(); private NameValueCollection InnerCollection => _innerCollection ??= new NameValueCollection(ApproxHighAvgNumHeaders, StringComparer.OrdinalIgnoreCase); diff --git a/src/libraries/System.Net.WebHeaderCollection/tests/WebHeaderCollectionTest.cs b/src/libraries/System.Net.WebHeaderCollection/tests/WebHeaderCollectionTest.cs index f4ad906fd78f54..256f3d43853553 100644 --- a/src/libraries/System.Net.WebHeaderCollection/tests/WebHeaderCollectionTest.cs +++ b/src/libraries/System.Net.WebHeaderCollection/tests/WebHeaderCollectionTest.cs @@ -135,7 +135,7 @@ public void Setter_ValidName_Success() [Theory] [InlineData(null)] [InlineData("")] - public void Setter_NullOrEmptyName_Throws(string name) + public void Setter_NullOrEmptyName_Throws(string? name) { WebHeaderCollection w = new WebHeaderCollection(); AssertExtensions.Throws("name", () => w[name] = "test"); @@ -222,7 +222,7 @@ public void Remove_HeaderExists_RemovesFromCollection(string name) [Theory] [InlineData(null)] [InlineData("")] - public void Remove_NullOrEmptyHeader_ThrowsArgumentNullException(string name) + public void Remove_NullOrEmptyHeader_ThrowsArgumentNullException(string? name) { var headers = new WebHeaderCollection(); AssertExtensions.Throws("name", () => headers.Remove(name)); @@ -342,7 +342,7 @@ public void ToString_Empty_Success() [Theory] [InlineData(null)] [InlineData("")] - public void ToString_SingleHeaderWithEmptyValue_Success(string value) + public void ToString_SingleHeaderWithEmptyValue_Success(string? value) { WebHeaderCollection w = new WebHeaderCollection(); w["name"] = value; @@ -515,7 +515,7 @@ public void Add_ValidHeader_AddsToHeaders() [Theory] [InlineData(null)] [InlineData("")] - public void Add_NullHeader_ThrowsArgumentNullException(string header) + public void Add_NullHeader_ThrowsArgumentNullException(string? header) { var headers = new WebHeaderCollection(); AssertExtensions.Throws("header", () => headers.Add(header)); diff --git a/src/libraries/System.Net.WebProxy/System.Net.WebProxy.slnx b/src/libraries/System.Net.WebProxy/System.Net.WebProxy.slnx index 5a30979cf64786..b98eae4930ebdd 100644 --- a/src/libraries/System.Net.WebProxy/System.Net.WebProxy.slnx +++ b/src/libraries/System.Net.WebProxy/System.Net.WebProxy.slnx @@ -1,37 +1,698 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.WebProxy/src/System.Net.WebProxy.csproj b/src/libraries/System.Net.WebProxy/src/System.Net.WebProxy.csproj index f23c6072c4df7a..31f73cc666e8dc 100644 --- a/src/libraries/System.Net.WebProxy/src/System.Net.WebProxy.csproj +++ b/src/libraries/System.Net.WebProxy/src/System.Net.WebProxy.csproj @@ -15,13 +15,13 @@ - - - - - - - + + + + + + + diff --git a/src/libraries/System.Net.WebSockets.Client/System.Net.WebSockets.Client.slnx b/src/libraries/System.Net.WebSockets.Client/System.Net.WebSockets.Client.slnx index c3ba39587cb092..b8bee4eafde1ae 100644 --- a/src/libraries/System.Net.WebSockets.Client/System.Net.WebSockets.Client.slnx +++ b/src/libraries/System.Net.WebSockets.Client/System.Net.WebSockets.Client.slnx @@ -26,6 +26,14 @@ + + + + + + + + @@ -60,6 +68,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -100,6 +132,14 @@ + + + + + + + + @@ -108,6 +148,22 @@ + + + + + + + + + + + + + + + + @@ -116,6 +172,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -132,6 +220,22 @@ + + + + + + + + + + + + + + + + @@ -140,6 +244,14 @@ + + + + + + + + @@ -156,6 +268,14 @@ + + + + + + + + @@ -164,6 +284,14 @@ + + + + + + + + @@ -180,6 +308,14 @@ + + + + + + + + @@ -196,6 +332,14 @@ + + + + + + + + @@ -212,6 +356,22 @@ + + + + + + + + + + + + + + + + @@ -220,6 +380,22 @@ + + + + + + + + + + + + + + + + @@ -228,6 +404,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -261,6 +461,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -269,6 +709,14 @@ + + + + + + + + @@ -277,6 +725,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -285,6 +757,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -293,6 +805,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.WebSockets.Client/src/System.Net.WebSockets.Client.csproj b/src/libraries/System.Net.WebSockets.Client/src/System.Net.WebSockets.Client.csproj index 3b68c3da977eb6..1c208e4ecd655d 100644 --- a/src/libraries/System.Net.WebSockets.Client/src/System.Net.WebSockets.Client.csproj +++ b/src/libraries/System.Net.WebSockets.Client/src/System.Net.WebSockets.Client.csproj @@ -40,29 +40,29 @@ - - - - - - - - - - - + + + + + + + + + + + - - - - + + + + - + diff --git a/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/ClientWebSocketOptions.cs b/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/ClientWebSocketOptions.cs index aa8164d1099c29..0628b5df9decb7 100644 --- a/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/ClientWebSocketOptions.cs +++ b/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/BrowserWebSockets/ClientWebSocketOptions.cs @@ -12,7 +12,6 @@ namespace System.Net.WebSockets public sealed class ClientWebSocketOptions { private bool _isReadOnly; // After ConnectAsync is called the options cannot be modified. - private List? _requestedSubProtocols; internal ClientWebSocketOptions() { } @@ -113,7 +112,7 @@ public void AddSubProtocol(string subProtocol) subprotocols.Add(subProtocol); } - internal List RequestedSubProtocols => _requestedSubProtocols ??= new List(); + internal List RequestedSubProtocols => field ??= new List(); [UnsupportedOSPlatform("browser")] public TimeSpan KeepAliveInterval diff --git a/src/libraries/System.Net.WebSockets.Client/tests/AbortTest.Loopback.cs b/src/libraries/System.Net.WebSockets.Client/tests/AbortTest.Loopback.cs index 8d0a89b320d618..1c7823434eb74e 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/AbortTest.Loopback.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/AbortTest.Loopback.cs @@ -1,10 +1,6 @@ // 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.Generic; -using System.IO; -using System.Net.Sockets; -using System.Net.Test.Common; using System.Threading; using System.Threading.Tasks; using Xunit; @@ -14,16 +10,38 @@ namespace System.Net.WebSockets.Client.Tests { [ConditionalClass(typeof(ClientWebSocketTestBase), nameof(WebSocketsSupported))] [SkipOnPlatform(TestPlatforms.Browser, "System.Net.Sockets are not supported on browser")] - public abstract class AbortTest_Loopback : ClientWebSocketTestBase + public abstract class AbortTest_LoopbackBase(ITestOutputHelper output) : AbortTestBase(output) { - public AbortTest_Loopback(ITestOutputHelper output) : base(output) { } + #region Common (Echo Server) tests - protected virtual Version HttpVersion => Net.HttpVersion.Version11; + [Theory, MemberData(nameof(UseSsl))] + public Task Abort_ConnectAndAbort_ThrowsWebSocketExceptionWithMessage(bool useSsl) => RunEchoAsync( + RunClient_Abort_ConnectAndAbort_ThrowsWebSocketExceptionWithMessage, useSsl); - public static object[][] AbortClient_MemberData = ToMemberData(Enum.GetValues(), UseSsl_Values, /* verifySendReceive */ Bool_Values); + [Theory, MemberData(nameof(UseSsl))] + public Task Abort_SendAndAbort_Success(bool useSsl) => RunEchoAsync( + RunClient_Abort_SendAndAbort_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task Abort_ReceiveAndAbort_Success(bool useSsl) => RunEchoAsync( + RunClient_Abort_ReceiveAndAbort_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task Abort_CloseAndAbort_Success(bool useSsl) => RunEchoAsync( + RunClient_Abort_CloseAndAbort_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task ClientWebSocket_Abort_CloseOutputAsync(bool useSsl) => RunEchoAsync( + RunClient_ClientWebSocket_Abort_CloseOutputAsync, useSsl); + + #endregion + + #region Loopback-only tests + + public static object[][] AbortTypeAndUseSslAndBoolean = ToMemberData(Enum.GetValues(), UseSsl_Values, Bool_Values); [Theory] - [MemberData(nameof(AbortClient_MemberData))] + [MemberData(nameof(AbortTypeAndUseSslAndBoolean))] public Task AbortClient_ServerGetsCorrectException(AbortType abortType, bool useSsl, bool verifySendReceive) { var clientMsg = new byte[] { 1, 2, 3, 4, 5, 6 }; @@ -34,11 +52,13 @@ public Task AbortClient_ServerGetsCorrectException(AbortType abortType, bool use var timeoutCts = new CancellationTokenSource(TimeOutMilliseconds); return LoopbackWebSocketServer.RunAsync( - async (clientWebSocket, token) => + async uri => { + ClientWebSocket clientWebSocket = await GetConnectedWebSocket(uri); + if (verifySendReceive) { - await VerifySendReceiveAsync(clientWebSocket, clientMsg, serverMsg, clientAckTcs, serverAckTcs.Task, token); + await VerifySendReceiveAsync(clientWebSocket, clientMsg, serverMsg, clientAckTcs, serverAckTcs.Task, timeoutCts.Token); } switch (abortType) @@ -65,14 +85,14 @@ public Task AbortClient_ServerGetsCorrectException(AbortType abortType, bool use Assert.Equal(WebSocketError.ConnectionClosedPrematurely, exception.WebSocketErrorCode); Assert.Equal(WebSocketState.Aborted, serverWebSocket.State); }, - new LoopbackWebSocketServer.Options(HttpVersion, useSsl, GetInvoker()), + new LoopbackWebSocketServer.Options(HttpVersion, useSsl) { DisposeServerWebSocket = true }, timeoutCts.Token); } - public static object[][] ServerPrematureEos_MemberData = ToMemberData(Enum.GetValues(), UseSsl_Values); + public static object[][] ServerEosTypeAndUseSsl = ToMemberData(Enum.GetValues(), UseSsl_Values); [Theory] - [MemberData(nameof(ServerPrematureEos_MemberData))] + [MemberData(nameof(ServerEosTypeAndUseSsl))] public Task ServerPrematureEos_ClientGetsCorrectException(ServerEosType serverEosType, bool useSsl) { var clientMsg = new byte[] { 1, 2, 3, 4, 5, 6 }; @@ -82,12 +102,6 @@ public Task ServerPrematureEos_ClientGetsCorrectException(ServerEosType serverEo var timeoutCts = new CancellationTokenSource(TimeOutMilliseconds); - var globalOptions = new LoopbackWebSocketServer.Options(HttpVersion, useSsl, HttpInvoker: null) - { - DisposeServerWebSocket = false, - ManualServerHandshakeResponse = true - }; - var serverReceivedEosTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var clientReceivedEosTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); @@ -95,8 +109,7 @@ public Task ServerPrematureEos_ClientGetsCorrectException(ServerEosType serverEo async uri => { var token = timeoutCts.Token; - var clientOptions = globalOptions with { HttpInvoker = GetInvoker() }; - var clientWebSocket = await LoopbackWebSocketServer.GetConnectedClientAsync(uri, clientOptions, token).ConfigureAwait(false); + ClientWebSocket clientWebSocket = await GetConnectedWebSocket(uri); if (serverEosType == ServerEosType.AfterSomeData) { @@ -121,7 +134,7 @@ await SendServerResponseAndEosAsync( (wsData, ct) => { var wsOptions = new WebSocketCreationOptions { IsServer = true }; - serverWebSocket = WebSocket.CreateFromStream(wsData.WebSocketStream, wsOptions); + serverWebSocket = WebSocket.CreateFromStream(wsData.TransportStream, wsOptions); return serverEosType == ServerEosType.AfterSomeData ? VerifySendReceiveAsync(serverWebSocket, serverMsg, clientMsg, serverAckTcs, clientAckTcs.Task, ct) @@ -146,12 +159,11 @@ await SendServerResponseAndEosAsync( serverWebSocket.Dispose(); }, - globalOptions, + new LoopbackWebSocketServer.Options(HttpVersion, useSsl) { SkipServerHandshakeResponse = true }, timeoutCts.Token); } - protected virtual Task SendServerResponseAndEosAsync(WebSocketRequestData requestData, ServerEosType serverEosType, Func serverFunc, CancellationToken cancellationToken) - => WebSocketHandshakeHelper.SendHttp11ServerResponseAndEosAsync(requestData, serverFunc, cancellationToken); // override for HTTP/2 + protected abstract Task SendServerResponseAndEosAsync(WebSocketRequestData data, ServerEosType eos, Func callback, CancellationToken ct); public enum AbortType { @@ -184,42 +196,51 @@ protected static async Task VerifySendReceiveAsync(WebSocket ws, byte[] localMsg await sendTask.ConfigureAwait(false); await remoteAck.WaitAsync(cancellationToken).ConfigureAwait(false); } + + #endregion } - // --- HTTP/1.1 WebSocket loopback tests --- + public abstract class AbortTest_Loopback(ITestOutputHelper output) : AbortTest_LoopbackBase(output) + { + protected override Task SendServerResponseAndEosAsync(WebSocketRequestData data, ServerEosType eos, Func callback, CancellationToken ct) + => WebSocketHandshakeHelper.SendHttp11ServerResponseAndEosAsync(data, callback, ct); + } - public class AbortTest_Invoker_Loopback : AbortTest_Loopback + public abstract class AbortTest_Http2Loopback(ITestOutputHelper output) : AbortTest_LoopbackBase(output) { - public AbortTest_Invoker_Loopback(ITestOutputHelper output) : base(output) { } - protected override bool UseCustomInvoker => true; + internal override Version HttpVersion => Net.HttpVersion.Version20; + + protected override Task SendServerResponseAndEosAsync(WebSocketRequestData data, ServerEosType eos, Func callback, CancellationToken ct) + => WebSocketHandshakeHelper.SendHttp2ServerResponseAndEosAsync(data, eosInHeadersFrame: eos == ServerEosType.WithHeaders, callback, ct); } - public class AbortTest_HttpClient_Loopback : AbortTest_Loopback + #region Runnable test classes: HTTP/1.1 Loopback + + public sealed class AbortTest_SharedHandler_Loopback(ITestOutputHelper output) : AbortTest_Loopback(output) { } + + public sealed class AbortTest_Invoker_Loopback(ITestOutputHelper output) : AbortTest_Loopback(output) { - public AbortTest_HttpClient_Loopback(ITestOutputHelper output) : base(output) { } - protected override bool UseHttpClient => true; + protected override bool UseCustomInvoker => true; } - public class AbortTest_SharedHandler_Loopback : AbortTest_Loopback + public sealed class AbortTest_HttpClient_Loopback(ITestOutputHelper output) : AbortTest_Loopback(output) { - public AbortTest_SharedHandler_Loopback(ITestOutputHelper output) : base(output) { } + protected override bool UseHttpClient => true; } - // --- HTTP/2 WebSocket loopback tests --- + #endregion + + #region Runnable test classes: HTTP/2 Loopback - public class AbortTest_Invoker_Http2 : AbortTest_Invoker_Loopback + public sealed class AbortTest_Invoker_Http2Loopback(ITestOutputHelper output) : AbortTest_Http2Loopback(output) { - public AbortTest_Invoker_Http2(ITestOutputHelper output) : base(output) { } - protected override Version HttpVersion => Net.HttpVersion.Version20; - protected override Task SendServerResponseAndEosAsync(WebSocketRequestData rd, ServerEosType eos, Func callback, CancellationToken ct) - => WebSocketHandshakeHelper.SendHttp2ServerResponseAndEosAsync(rd, eosInHeadersFrame: eos == ServerEosType.WithHeaders, callback, ct); + protected override bool UseCustomInvoker => true; } - public class AbortTest_HttpClient_Http2 : AbortTest_HttpClient_Loopback + public sealed class AbortTest_HttpClient_Http2Loopback(ITestOutputHelper output) : AbortTest_Http2Loopback(output) { - public AbortTest_HttpClient_Http2(ITestOutputHelper output) : base(output) { } - protected override Version HttpVersion => Net.HttpVersion.Version20; - protected override Task SendServerResponseAndEosAsync(WebSocketRequestData rd, ServerEosType eos, Func callback, CancellationToken ct) - => WebSocketHandshakeHelper.SendHttp2ServerResponseAndEosAsync(rd, eosInHeadersFrame: eos == ServerEosType.WithHeaders, callback, ct); + protected override bool UseHttpClient => true; } + + #endregion } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/AbortTest.cs b/src/libraries/System.Net.WebSockets.Client/tests/AbortTest.cs index 85f6e875a824ca..703c7f2a1c477b 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/AbortTest.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/AbortTest.cs @@ -1,48 +1,52 @@ // 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.Generic; -using System.Net.Http; -using System.Net.Test.Common; using System.Threading; using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; +using EchoControlMessage = System.Net.Test.Common.WebSocketEchoHelper.EchoControlMessage; +using EchoQueryKey = System.Net.Test.Common.WebSocketEchoOptions.EchoQueryKey; + namespace System.Net.WebSockets.Client.Tests { - public sealed class InvokerAbortTest : AbortTest - { - public InvokerAbortTest(ITestOutputHelper output) : base(output) { } - - protected override bool UseCustomInvoker => true; - } - - public sealed class HttpClientAbortTest : AbortTest - { - public HttpClientAbortTest(ITestOutputHelper output) : base(output) { } - - protected override bool UseHttpClient => true; - } - - public class AbortTest : ClientWebSocketTestBase + // + // Class hierarchy: + // + // - AbortTestBase → file:AbortTest.cs + // ├─ AbortTest_External + // │ ├─ [*]AbortTest_SharedHandler_External + // │ ├─ [*]AbortTest_Invoker_External + // │ └─ [*]AbortTest_HttpClient_External + // └─ AbortTest_LoopbackBase → file:AbortTest.Loopback.cs + // ├─ AbortTest_Loopback + // │ ├─ [*]AbortTest_SharedHandler_Loopback + // │ ├─ [*]AbortTest_Invoker_Loopback + // │ └─ [*]AbortTest_HttpClient_Loopback + // └─ AbortTest_Http2Loopback + // ├─ [*]AbortTest_Invoker_Http2Loopback + // └─ [*]AbortTest_HttpClient_Http2Loopback + // + // --- + // `[*]` - concrete runnable test classes + // `→ file:` - file containing the class and its concrete subclasses + + public abstract class AbortTestBase(ITestOutputHelper output) : ClientWebSocketTestBase(output) { - public AbortTest(ITestOutputHelper output) : base(output) { } - + #region Common (Echo Server) tests - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task Abort_ConnectAndAbort_ThrowsWebSocketExceptionWithmessage(Uri server) + protected async Task RunClient_Abort_ConnectAndAbort_ThrowsWebSocketExceptionWithMessage(Uri server) { using (var cws = new ClientWebSocket()) { var cts = new CancellationTokenSource(TimeOutMilliseconds); - var ub = new UriBuilder(server); - ub.Query = "delay10sec"; + var ub = new UriBuilder(server) { Query = EchoQueryKey.Delay10Sec }; Task t = ConnectAsync(cws, ub.Uri, cts.Token); + cws.Abort(); WebSocketException ex = await Assert.ThrowsAsync(() => t); @@ -53,16 +57,14 @@ public async Task Abort_ConnectAndAbort_ThrowsWebSocketExceptionWithmessage(Uri } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task Abort_SendAndAbort_Success(Uri server) + protected async Task RunClient_Abort_SendAndAbort_Success(Uri server) { await TestCancellation(async (cws) => { var cts = new CancellationTokenSource(TimeOutMilliseconds); Task t = cws.SendAsync( - WebSocketData.GetBufferFromText(".delay5sec"), + EchoControlMessage.Delay5Sec.ToUtf8(), WebSocketMessageType.Text, true, cts.Token); @@ -73,16 +75,14 @@ await TestCancellation(async (cws) => }, server); } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task Abort_ReceiveAndAbort_Success(Uri server) + protected async Task RunClient_Abort_ReceiveAndAbort_Success(Uri server) { await TestCancellation(async (cws) => { var ctsDefault = new CancellationTokenSource(TimeOutMilliseconds); await cws.SendAsync( - WebSocketData.GetBufferFromText(".delay5sec"), + EchoControlMessage.Delay5Sec.ToUtf8(), WebSocketMessageType.Text, true, ctsDefault.Token); @@ -91,22 +91,21 @@ await cws.SendAsync( var segment = new ArraySegment(recvBuffer); Task t = cws.ReceiveAsync(segment, ctsDefault.Token); + cws.Abort(); await t; }, server); } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task Abort_CloseAndAbort_Success(Uri server) + protected async Task RunClient_Abort_CloseAndAbort_Success(Uri server) { await TestCancellation(async (cws) => { var ctsDefault = new CancellationTokenSource(TimeOutMilliseconds); await cws.SendAsync( - WebSocketData.GetBufferFromText(".delay5sec"), + EchoControlMessage.Delay5Sec.ToUtf8(), WebSocketMessageType.Text, true, ctsDefault.Token); @@ -121,16 +120,14 @@ await cws.SendAsync( }, server); } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task ClientWebSocket_Abort_CloseOutputAsync(Uri server) + protected async Task RunClient_ClientWebSocket_Abort_CloseOutputAsync(Uri server) { await TestCancellation(async (cws) => { var ctsDefault = new CancellationTokenSource(TimeOutMilliseconds); await cws.SendAsync( - WebSocketData.GetBufferFromText(".delay5sec"), + EchoControlMessage.Delay5Sec.ToUtf8(), WebSocketMessageType.Text, true, ctsDefault.Token); @@ -144,5 +141,52 @@ await cws.SendAsync( await t; }, server); } + + #endregion } + + [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] + [ConditionalClass(typeof(ClientWebSocketTestBase), nameof(WebSocketsSupported))] + public abstract class AbortTest_External(ITestOutputHelper output) : AbortTestBase(output) + { + #region Common (Echo Server) tests + + [Theory, MemberData(nameof(EchoServers))] + public Task Abort_ConnectAndAbort_ThrowsWebSocketExceptionWithMessage(Uri server) + => RunClient_Abort_ConnectAndAbort_ThrowsWebSocketExceptionWithMessage(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task Abort_SendAndAbort_Success(Uri server) + => RunClient_Abort_SendAndAbort_Success(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task Abort_ReceiveAndAbort_Success(Uri server) + => RunClient_Abort_ReceiveAndAbort_Success(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task Abort_CloseAndAbort_Success(Uri server) + => RunClient_Abort_CloseAndAbort_Success(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task ClientWebSocket_Abort_CloseOutputAsync(Uri server) + => RunClient_ClientWebSocket_Abort_CloseOutputAsync(server); + + #endregion + } + + #region Runnable test classes: External/Outerloop + + public sealed class AbortTest_SharedHandler_External(ITestOutputHelper output) : AbortTest_External(output) { } + + public sealed class AbortTest_Invoker_External(ITestOutputHelper output) : AbortTest_External(output) + { + protected override bool UseCustomInvoker => true; + } + + public sealed class AbortTest_HttpClient_External(ITestOutputHelper output) : AbortTest_External(output) + { + protected override bool UseHttpClient => true; + } + + #endregion } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/CancelTest.Loopback.cs b/src/libraries/System.Net.WebSockets.Client/tests/CancelTest.Loopback.cs new file mode 100644 index 00000000000000..0e713c566c0d2c --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/CancelTest.Loopback.cs @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; + +namespace System.Net.WebSockets.Client.Tests +{ + [ConditionalClass(typeof(ClientWebSocketTestBase), nameof(WebSocketsSupported))] + [SkipOnPlatform(TestPlatforms.Browser, "System.Net.Sockets are not supported on browser")] + public abstract class CancelTest_Loopback(ITestOutputHelper output) : CancelTestBase(output) + { + #region Common (Echo Server) tests + + [Theory, MemberData(nameof(UseSsl))] + public Task ConnectAsync_Cancel_ThrowsCancellationException(bool useSsl) => RunEchoAsync( + RunClient_ConnectAsync_Cancel_ThrowsCancellationException, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task SendAsync_Cancel_Success(bool useSsl) => RunEchoAsync( + RunClient_SendAsync_Cancel_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task ReceiveAsync_Cancel_Success(bool useSsl) => RunEchoAsync( + RunClient_ReceiveAsync_Cancel_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task CloseAsync_Cancel_Success(bool useSsl) => RunEchoAsync( + RunClient_CloseAsync_Cancel_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task CloseOutputAsync_Cancel_Success(bool useSsl) => RunEchoAsync( + RunClient_CloseOutputAsync_Cancel_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task ReceiveAsync_CancelThenReceive_ThrowsOperationCanceledException(bool useSsl) => RunEchoAsync( + RunClient_ReceiveAsync_CancelThenReceive_ThrowsOperationCanceledException, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task ReceiveAsync_ReceiveThenCancel_ThrowsOperationCanceledException(bool useSsl) => RunEchoAsync( + RunClient_ReceiveAsync_ReceiveThenCancel_ThrowsOperationCanceledException, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task ReceiveAsync_AfterCancellationDoReceiveAsync_ThrowsWebSocketException(bool useSsl) => RunEchoAsync( + RunClient_ReceiveAsync_AfterCancellationDoReceiveAsync_ThrowsWebSocketException, useSsl); + + #endregion + } + + public abstract class CancelTest_Http2Loopback(ITestOutputHelper output) : CancelTest_Loopback(output) + { + internal override Version HttpVersion => Net.HttpVersion.Version20; + } + + #region Runnable test classes: HTTP/1.1 Loopback + + public sealed class CancelTest_SharedHandler_Loopback(ITestOutputHelper output) : CancelTest_Loopback(output) { } + + public sealed class CancelTest_Invoker_Loopback(ITestOutputHelper output) : CancelTest_Loopback(output) + { + protected override bool UseCustomInvoker => true; + } + + public sealed class CancelTest_HttpClient_Loopback(ITestOutputHelper output) : CancelTest_Loopback(output) + { + protected override bool UseHttpClient => true; + } + + #endregion + + #region Runnable test classes: HTTP/2 Loopback + + public sealed class CancelTest_Invoker_Http2Loopback(ITestOutputHelper output) : CancelTest_Http2Loopback(output) + { + protected override bool UseCustomInvoker => true; + } + + public sealed class CancelTest_HttpClient_Http2Loopback(ITestOutputHelper output) : CancelTest_Http2Loopback(output) + { + protected override bool UseHttpClient => true; + } + + #endregion +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/CancelTest.cs b/src/libraries/System.Net.WebSockets.Client/tests/CancelTest.cs index a38b11d2321c87..20df47b2e6180b 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/CancelTest.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/CancelTest.cs @@ -1,68 +1,71 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; +using EchoControlMessage = System.Net.Test.Common.WebSocketEchoHelper.EchoControlMessage; +using EchoQueryKey = System.Net.Test.Common.WebSocketEchoOptions.EchoQueryKey; + namespace System.Net.WebSockets.Client.Tests { - public sealed class InvokerCancelTest : CancelTest - { - public InvokerCancelTest(ITestOutputHelper output) : base(output) { } - - protected override bool UseCustomInvoker => true; - } - - public sealed class HttpClientCancelTest : CancelTest - { - public HttpClientCancelTest(ITestOutputHelper output) : base(output) { } - - protected override bool UseHttpClient => true; - } - - public class CancelTest : ClientWebSocketTestBase + // + // Class hierarchy: + // + // - CancelTestBase → file:CancelTest.cs + // ├─ CancelTest_External + // │ ├─ [*]CancelTest_SharedHandler_External + // │ ├─ [*]CancelTest_Invoker_External + // │ └─ [*]CancelTest_HttpClient_External + // └─ CancelTest_Loopback → file:CancelTest.Loopback.cs + // ├─ [*]CancelTest_SharedHandler_Loopback + // ├─ [*]CancelTest_Invoker_Loopback + // ├─ [*]CancelTest_HttpClient_Loopback + // └─ CancelTest_Http2Loopback + // ├─ [*]CancelTest_Invoker_Http2Loopback + // └─ [*]CancelTest_HttpClient_Http2Loopback + // + // --- + // `[*]` - concrete runnable test classes + // `→ file:` - file containing the class and its concrete subclasses + + public abstract class CancelTestBase(ITestOutputHelper output) : ClientWebSocketTestBase(output) { - public CancelTest(ITestOutputHelper output) : base(output) { } + #region Common (Echo Server) tests - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/83579", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] - public async Task ConnectAsync_Cancel_ThrowsCancellationException(Uri server) + protected async Task RunClient_ConnectAsync_Cancel_ThrowsCancellationException(Uri server) { using (var cws = new ClientWebSocket()) { var cts = new CancellationTokenSource(100); - var ub = new UriBuilder(server); - ub.Query = PlatformDetection.IsBrowser ? "delay20sec" : "delay10sec"; + var ub = new UriBuilder(server) + { + Query = PlatformDetection.IsBrowser ? EchoQueryKey.Delay20Sec : EchoQueryKey.Delay10Sec + }; var ex = await Assert.ThrowsAnyAsync(() => ConnectAsync(cws, ub.Uri, cts.Token)); Assert.True(WebSocketState.Closed == cws.State, $"Actual {cws.State} when {ex}"); } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task SendAsync_Cancel_Success(Uri server) + protected async Task RunClient_SendAsync_Cancel_Success(Uri server) { await TestCancellation((cws) => { var cts = new CancellationTokenSource(5); return cws.SendAsync( - WebSocketData.GetBufferFromText(".delay5sec"), + EchoControlMessage.Delay5Sec.ToUtf8(), WebSocketMessageType.Text, true, cts.Token); }, server); } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task ReceiveAsync_Cancel_Success(Uri server) + protected async Task RunClient_ReceiveAsync_Cancel_Success(Uri server) { await TestCancellation(async (cws) => { @@ -70,7 +73,7 @@ await TestCancellation(async (cws) => var cts = new CancellationTokenSource(5); await cws.SendAsync( - WebSocketData.GetBufferFromText(".delay5sec"), + EchoControlMessage.Delay5Sec.ToUtf8(), WebSocketMessageType.Text, true, ctsDefault.Token); @@ -82,9 +85,7 @@ await cws.SendAsync( }, server); } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseAsync_Cancel_Success(Uri server) + protected async Task RunClient_CloseAsync_Cancel_Success(Uri server) { await TestCancellation(async (cws) => { @@ -92,7 +93,7 @@ await TestCancellation(async (cws) => var cts = new CancellationTokenSource(TimeOutMilliseconds); await cws.SendAsync( - WebSocketData.GetBufferFromText(".delay5sec"), + EchoControlMessage.Delay5Sec.ToUtf8(), WebSocketMessageType.Text, true, ctsDefault.Token); @@ -104,9 +105,7 @@ await cws.SendAsync( }, server); } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseOutputAsync_Cancel_Success(Uri server) + protected async Task RunClient_CloseOutputAsync_Cancel_Success(Uri server) { await TestCancellation(async (cws) => { @@ -115,7 +114,7 @@ await TestCancellation(async (cws) => var ctsDefault = new CancellationTokenSource(TimeOutMilliseconds); await cws.SendAsync( - WebSocketData.GetBufferFromText(".delay5sec"), + EchoControlMessage.Delay5Sec.ToUtf8(), WebSocketMessageType.Text, true, ctsDefault.Token); @@ -127,11 +126,9 @@ await cws.SendAsync( }, server); } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task ReceiveAsync_CancelThenReceive_ThrowsOperationCanceledException(Uri server) + protected async Task RunClient_ReceiveAsync_CancelThenReceive_ThrowsOperationCanceledException(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var recvBuffer = new byte[100]; var segment = new ArraySegment(recvBuffer); @@ -143,11 +140,9 @@ public async Task ReceiveAsync_CancelThenReceive_ThrowsOperationCanceledExceptio } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task ReceiveAsync_ReceiveThenCancel_ThrowsOperationCanceledException(Uri server) + protected async Task RunClient_ReceiveAsync_ReceiveThenCancel_ThrowsOperationCanceledException(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var recvBuffer = new byte[100]; var segment = new ArraySegment(recvBuffer); @@ -159,11 +154,9 @@ public async Task ReceiveAsync_ReceiveThenCancel_ThrowsOperationCanceledExceptio } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task ReceiveAsync_AfterCancellationDoReceiveAsync_ThrowsWebSocketException(Uri server) + protected async Task RunClient_ReceiveAsync_AfterCancellationDoReceiveAsync_ThrowsWebSocketException(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var recvBuffer = new byte[100]; var segment = new ArraySegment(recvBuffer); @@ -180,5 +173,63 @@ public async Task ReceiveAsync_AfterCancellationDoReceiveAsync_ThrowsWebSocketEx ex.Message); } } + + #endregion + } + + [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] + [ConditionalClass(typeof(ClientWebSocketTestBase), nameof(WebSocketsSupported))] + public abstract class CancelTest_External(ITestOutputHelper output) : CancelTestBase(output) + { + #region Common (Echo Server) tests + + [ActiveIssue("https://github.com/dotnet/runtime/issues/83579", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] + [Theory, MemberData(nameof(EchoServers))] + public Task ConnectAsync_Cancel_ThrowsCancellationException(Uri server) + => RunClient_ConnectAsync_Cancel_ThrowsCancellationException(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task SendAsync_Cancel_Success(Uri server) + => RunClient_SendAsync_Cancel_Success(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task ReceiveAsync_Cancel_Success(Uri server) + => RunClient_ReceiveAsync_Cancel_Success(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task CloseAsync_Cancel_Success(Uri server) + => RunClient_CloseAsync_Cancel_Success(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task CloseOutputAsync_Cancel_Success(Uri server) + => RunClient_CloseOutputAsync_Cancel_Success(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task ReceiveAsync_CancelThenReceive_ThrowsOperationCanceledException(Uri server) + => RunClient_ReceiveAsync_CancelThenReceive_ThrowsOperationCanceledException(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task ReceiveAsync_ReceiveThenCancel_ThrowsOperationCanceledException(Uri server) + => RunClient_ReceiveAsync_ReceiveThenCancel_ThrowsOperationCanceledException(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task ReceiveAsync_AfterCancellationDoReceiveAsync_ThrowsWebSocketException(Uri server) + => RunClient_ReceiveAsync_AfterCancellationDoReceiveAsync_ThrowsWebSocketException(server); + + #endregion + } + + #region Runnable test classes: External/Outerloop + public sealed class CancelTest_SharedHandler_External(ITestOutputHelper output) : CancelTest_External(output) { } + + public sealed class CancelTest_Invoker_External(ITestOutputHelper output) : CancelTest_External(output) + { + protected override bool UseCustomInvoker => true; + } + + public sealed class CancelTest_HttpClient_External(ITestOutputHelper output) : CancelTest_External(output) + { + protected override bool UseHttpClient => true; } + #endregion } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketOptionsTests.cs b/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketOptionsTests.cs index 7a39f2423cad86..7e64f6baa61246 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketOptionsTests.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketOptionsTests.cs @@ -7,16 +7,14 @@ using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; - +using Microsoft.DotNet.XUnitExtensions; using Xunit; using Xunit.Abstractions; namespace System.Net.WebSockets.Client.Tests { - public class ClientWebSocketOptionsTests : ClientWebSocketTestBase + public class ClientWebSocketOptionsTests(ITestOutputHelper output) : ClientWebSocketTestBase(output) { - public ClientWebSocketOptionsTests(ITestOutputHelper output) : base(output) { } - [ConditionalFact(nameof(WebSocketsSupported))] [SkipOnPlatform(TestPlatforms.Browser, "Credentials not supported on browser")] public static void UseDefaultCredentials_Roundtrips() @@ -52,7 +50,7 @@ public async Task Proxy_SetNull_ConnectsSuccessfully(Uri server) { for (int i = 0; i < 3; i++) // Connect and disconnect multiple times to exercise shared handler on netcoreapp { - var ws = await WebSocketHelper.Retry(_output, async () => + var ws = await WebSocketHelper.Retry(async () => { var cws = new ClientWebSocket(); cws.Options.Proxy = null; @@ -72,19 +70,13 @@ public async Task Proxy_ConnectThruProxy_Success(Uri server) string proxyServerUri = System.Net.Test.Common.Configuration.WebSockets.ProxyServerUri; if (string.IsNullOrEmpty(proxyServerUri)) { - _output.WriteLine("Skipping test...no proxy server defined."); - return; + throw new SkipTestException("No proxy server defined."); } _output.WriteLine($"ProxyServer: {proxyServerUri}"); IWebProxy proxy = new WebProxy(new Uri(proxyServerUri)); - using (ClientWebSocket cws = await WebSocketHelper.GetConnectedWebSocket( - server, - TimeOutMilliseconds, - _output, - default(TimeSpan), - proxy)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server, o => o.Proxy = proxy)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); Assert.Equal(WebSocketState.Open, cws.State); @@ -119,7 +111,7 @@ public static void SetBuffer_InvalidArgs_Throws() AssertExtensions.Throws("receiveBufferSize", () => cws.Options.SetBuffer(0, 0, new ArraySegment(new byte[1]))); AssertExtensions.Throws("receiveBufferSize", () => cws.Options.SetBuffer(0, minSendBufferSize, new ArraySegment(new byte[1]))); AssertExtensions.Throws("sendBufferSize", () => cws.Options.SetBuffer(minReceiveBufferSize, 0, new ArraySegment(new byte[1]))); - AssertExtensions.Throws("buffer.Array", () => cws.Options.SetBuffer(minReceiveBufferSize, minSendBufferSize, default(ArraySegment))); + AssertExtensions.Throws("buffer.Array", () => cws.Options.SetBuffer(minReceiveBufferSize, minSendBufferSize, default)); AssertExtensions.Throws(bufferName, () => cws.Options.SetBuffer(minReceiveBufferSize, minSendBufferSize, new ArraySegment(new byte[0]))); } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.Echo.Unsupported.cs b/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.Echo.Unsupported.cs new file mode 100644 index 00000000000000..c6070e1e28af6e --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.Echo.Unsupported.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading.Tasks; + +namespace System.Net.WebSockets.Client.Tests +{ + public partial class ClientWebSocketTestBase + { + protected Task RunEchoAsync(Func clientFunc, bool useSsl) + => throw new PlatformNotSupportedException(); + + protected Task RunEchoHeadersAsync(Func clientFunc, bool useSsl) + => throw new PlatformNotSupportedException(); + } +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.Echo.cs b/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.Echo.cs new file mode 100644 index 00000000000000..c29aa596710b32 --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.Echo.cs @@ -0,0 +1,50 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Net.Test.Common; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.WebSockets.Client.Tests +{ + public partial class ClientWebSocketTestBase + { + protected Task RunEchoAsync(Func clientFunc, bool useSsl) + { + var timeoutCts = new CancellationTokenSource(TimeOutMilliseconds); + var options = new LoopbackWebSocketServer.Options(HttpVersion, useSsl) + { + SkipServerHandshakeResponse = true, + IgnoreServerErrors = true, + AbortServerOnClientExit = true, + ParseEchoOptions = true + }; + + return LoopbackWebSocketServer.RunEchoAsync(clientFunc, options, timeoutCts.Token); + } + + protected Task RunEchoHeadersAsync(Func clientFunc, bool useSsl) + { + var timeoutCts = new CancellationTokenSource(TimeOutMilliseconds); + var options = new LoopbackWebSocketServer.Options(HttpVersion, useSsl) + { + IgnoreServerErrors = true, + AbortServerOnClientExit = true + }; + + return LoopbackWebSocketServer.RunAsync( + clientFunc, + async (requestData, token) => + { + var serverWebSocket = WebSocket.CreateFromStream( + requestData.TransportStream, + new WebSocketCreationOptions { IsServer = true }); + + using var registration = token.Register(serverWebSocket.Abort); + await WebSocketEchoHelper.RunEchoHeaders(serverWebSocket, requestData.Headers, token); + }, + options, + timeoutCts.Token); + } + } +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.cs b/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.cs index 4e4fb4b3d87c76..e1cd17fbaa3c4e 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.cs @@ -5,29 +5,26 @@ using System.Diagnostics; using System.Linq; using System.Net.Http; -using System.Reflection; using System.Threading; using System.Threading.Tasks; -using TestUtilities; using Xunit; using Xunit.Abstractions; namespace System.Net.WebSockets.Client.Tests { - public class ClientWebSocketTestBase + public partial class ClientWebSocketTestBase(ITestOutputHelper output) { - public static readonly object[][] EchoServers = System.Net.Test.Common.Configuration.WebSockets.GetEchoServers(); - public static readonly object[][] EchoHeadersServers = System.Net.Test.Common.Configuration.WebSockets.GetEchoHeadersServers(); - public static readonly object[][] EchoServersAndBoolean = EchoServers.SelectMany(o => new object[][] - { - new object[] { o[0], false }, - new object[] { o[0], true } - }).ToArray(); + public static readonly Uri[] EchoServers_Values = System.Net.Test.Common.Configuration.WebSockets.GetEchoServers(); + public static readonly Uri[] EchoHeadersServers_Values = System.Net.Test.Common.Configuration.WebSockets.GetEchoHeadersServers(); + public static readonly bool[] Bool_Values = [ false, true ]; + public static readonly bool[] UseSsl_Values = PlatformDetection.SupportsAlpn ? Bool_Values : [ false ]; - public static readonly bool[] Bool_Values = new[] { false, true }; - public static readonly bool[] UseSsl_Values = PlatformDetection.SupportsAlpn ? Bool_Values : new[] { false }; - public static readonly object[][] UseSsl_MemberData = ToMemberData(UseSsl_Values); + public static readonly object[][] EchoServers = ToMemberData(EchoServers_Values); + public static readonly object[][] EchoHeadersServers = ToMemberData(EchoHeadersServers_Values); + public static readonly object[][] EchoServersAndBoolean = ToMemberData(EchoServers_Values, Bool_Values); + public static readonly object[][] UseSsl = ToMemberData(UseSsl_Values); + public static readonly object[][] UseSslAndBoolean = ToMemberData(UseSsl_Values, Bool_Values); public static object[][] ToMemberData(IEnumerable data) => data.Select(a => new object[] { a }).ToArray(); @@ -40,12 +37,7 @@ public static object[][] ToMemberData(IEnumerable dataA, IEnumer public const int TimeOutMilliseconds = 30000; public const int CloseDescriptionMaxLength = 123; - public readonly ITestOutputHelper _output; - - public ClientWebSocketTestBase(ITestOutputHelper output) - { - _output = output; - } + public readonly ITestOutputHelper _output = output; public static IEnumerable UnavailableWebSocketServers { @@ -66,7 +58,7 @@ public static IEnumerable UnavailableWebSocketServers { server = System.Net.Test.Common.Configuration.Http.RemoteEchoServer; var ub = new UriBuilder("ws", server.Host, server.Port, server.PathAndQuery); - exceptionMessage = ResourceHelper.GetExceptionMessage("net_WebSockets_ConnectStatusExpected", (int) HttpStatusCode.OK, (int) HttpStatusCode.SwitchingProtocols); + exceptionMessage = ResourceHelper.GetExceptionMessage("net_WebSockets_ConnectStatusExpected", (int)HttpStatusCode.OK, (int)HttpStatusCode.SwitchingProtocols); yield return new object[] { ub.Uri, exceptionMessage, WebSocketError.NotAWebSocket }; } @@ -75,27 +67,21 @@ public static IEnumerable UnavailableWebSocketServers public async Task TestCancellation(Func action, Uri server) { - using (ClientWebSocket cws = await WebSocketHelper.GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { try { await action(cws); - // Operation finished before CTS expired. + _output.WriteLine($"Operation finished before CTS expired."); } - catch (OperationCanceledException exception) + catch (Exception e) when (e is OperationCanceledException or ObjectDisposedException or WebSocketException) { - // Expected exception - Assert.True(WebSocketState.Aborted == cws.State, $"Actual {cws.State} when {exception}"); - } - catch (ObjectDisposedException exception) - { - // Expected exception - Assert.True(WebSocketState.Aborted == cws.State, $"Actual {cws.State} when {exception}"); - } - catch (WebSocketException exception) - { - Assert.True(WebSocketError.InvalidState == exception.WebSocketErrorCode, $"Actual WebSocketErrorCode {exception.WebSocketErrorCode} when {exception}"); - Assert.True(WebSocketState.Aborted == cws.State, $"Actual {cws.State} when {exception}"); + Assert.True(WebSocketState.Aborted == cws.State, $"Actual {cws.State} when {e}"); + + if (e is WebSocketException wse) + { + Assert.True(WebSocketError.InvalidState == wse.WebSocketErrorCode, $"Actual WebSocketErrorCode {wse.WebSocketErrorCode} when {wse}"); + } } } } @@ -126,39 +112,101 @@ protected static async Task ReceiveEntireMessageAsync(We protected Action? ConfigureCustomHandler; + internal virtual Version HttpVersion => Net.HttpVersion.Version11; + internal HttpMessageInvoker? GetInvoker() { - var handler = new HttpClientHandler(); + if (UseSharedHandler) + { + return null; + } + HttpClientHandler handler = new HttpClientHandler(); if (PlatformDetection.IsNotBrowser) { - handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; + handler.ServerCertificateCustomValidationCallback = (_, _, _, _) => true; + ConfigureCustomHandler?.Invoke(handler); } - ConfigureCustomHandler?.Invoke(handler); - if (UseCustomInvoker) { Debug.Assert(!UseHttpClient); return new HttpMessageInvoker(handler); } - if (UseHttpClient) + Debug.Assert(UseHttpClient); + return new HttpClient(handler); + } + + public Task GetConnectedWebSocket(Uri uri, Action? configureOptions = null) + => WebSocketHelper.Retry( + async () => + { + var cws = new ClientWebSocket(); + configureOptions?.Invoke(cws.Options); + + using var cts = new CancellationTokenSource(TimeOutMilliseconds); + Task taskConnect = ConnectAsync(cws, uri, cts.Token); + + Assert.True( + (cws.State == WebSocketState.None) || + (cws.State == WebSocketState.Connecting) || + (cws.State == WebSocketState.Open) || + (cws.State == WebSocketState.Aborted), + "State immediately after ConnectAsync incorrect: " + cws.State); + await taskConnect; + + Assert.Equal(WebSocketState.Open, cws.State); + return cws; + }); + + protected Task ConnectAsync(ClientWebSocket cws, Uri uri, CancellationToken cancellationToken) + { + if (PlatformDetection.IsNotBrowser) { - return new HttpClient(handler); + if (uri.Scheme == "wss" && UseSharedHandler) + { + cws.Options.RemoteCertificateValidationCallback = (_, _, _, _) => true; + } + + cws.Options.HttpVersion = HttpVersion; + cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionExact; + + if (HttpVersion == Net.HttpVersion.Version20 && uri.Query is not (null or "" or "?")) + { + // RFC 7540, section 8.3. The CONNECT Method: + // > The ":scheme" and ":path" pseudo-header fields MUST be omitted. + // + // HTTP/2 CONNECT requests must drop query (containing echo options) from the request URI. + // The information needs to be passed in a different way, e.g. in a custom header. + + cws.Options.SetRequestHeader(WebSocketHelper.OriginalQueryStringHeader, uri.Query); + } } - return null; + return UseSharedHandler + ? cws.ConnectAsync(uri, cancellationToken) // Ensure test coverage for both overloads + : cws.ConnectAsync(uri, GetInvoker(), cancellationToken); } - protected Task GetConnectedWebSocket(Uri uri, int TimeOutMilliseconds, ITestOutputHelper output) => - WebSocketHelper.GetConnectedWebSocket(uri, TimeOutMilliseconds, output, invoker: GetInvoker()); - - protected Task ConnectAsync(ClientWebSocket cws, Uri uri, CancellationToken cancellationToken) => - cws.ConnectAsync(uri, GetInvoker(), cancellationToken); + protected Task RunClientAsync( + Uri uri, + Func clientWebSocketFunc, + Action? configureOptions = null) + { + var cts = new CancellationTokenSource(TimeOutMilliseconds); + return RunClientAsync(uri, clientWebSocketFunc, configureOptions, cts.Token); + } - protected Task TestEcho(Uri uri, WebSocketMessageType type, int timeOutMilliseconds, ITestOutputHelper output) => - WebSocketHelper.TestEcho(uri, WebSocketMessageType.Text, TimeOutMilliseconds, _output, GetInvoker()); + protected async Task RunClientAsync( + Uri uri, + Func clientWebSocketFunc, + Action? configureOptions, + CancellationToken cancellationToken) + { + using ClientWebSocket cws = await GetConnectedWebSocket(uri, configureOptions); + await clientWebSocketFunc(cws, cancellationToken); + } public static bool WebSocketsSupported { get { return WebSocketHelper.WebSocketsSupported; } } } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.Loopback.cs b/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.Loopback.cs new file mode 100644 index 00000000000000..66eb8a53715a20 --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.Loopback.cs @@ -0,0 +1,217 @@ +// 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.Generic; +using System.Net.Test.Common; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.DotNet.RemoteExecutor; +using Xunit; +using Xunit.Abstractions; + +namespace System.Net.WebSockets.Client.Tests +{ + + [ConditionalClass(typeof(ClientWebSocketTestBase), nameof(WebSocketsSupported))] + [SkipOnPlatform(TestPlatforms.Browser, "System.Net.Sockets are not supported on browser")] + public abstract class CloseTest_LoopbackBase(ITestOutputHelper output) : CloseTestBase(output) + { + #region Common (Echo Server) tests + + [Theory, MemberData(nameof(UseSslAndBoolean))] + public Task CloseAsync_ServerInitiatedClose_Success(bool useSsl, bool useCloseOutputAsync) => RunEchoAsync( + server => RunClient_CloseAsync_ServerInitiatedClose_Success(server, useCloseOutputAsync), useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task CloseAsync_ClientInitiatedClose_Success(bool useSsl) => RunEchoAsync( + RunClient_CloseAsync_ClientInitiatedClose_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task CloseAsync_CloseDescriptionIsMaxLength_Success(bool useSsl) => RunEchoAsync( + RunClient_CloseAsync_CloseDescriptionIsMaxLength_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task CloseAsync_CloseDescriptionIsMaxLengthPlusOne_ThrowsArgumentException(bool useSsl) => RunEchoAsync( + RunClient_CloseAsync_CloseDescriptionIsMaxLengthPlusOne_ThrowsArgumentException, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task CloseAsync_CloseDescriptionHasUnicode_Success(bool useSsl) => RunEchoAsync( + RunClient_CloseAsync_CloseDescriptionHasUnicode_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task CloseAsync_CloseDescriptionIsNull_Success(bool useSsl) => RunEchoAsync( + RunClient_CloseAsync_CloseDescriptionIsNull_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task CloseOutputAsync_ExpectedStates(bool useSsl) => RunEchoAsync( + RunClient_CloseOutputAsync_ExpectedStates, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task CloseAsync_CloseOutputAsync_Throws(bool useSsl) => RunEchoAsync( + RunClient_CloseAsync_CloseOutputAsync_Throws, useSsl); + + [OuterLoop("Uses Task.Delay")] + [Theory, MemberData(nameof(UseSsl))] + public Task CloseOutputAsync_ClientInitiated_CanReceive_CanClose(bool useSsl) => RunEchoAsync( + RunClient_CloseOutputAsync_ClientInitiated_CanReceive_CanClose, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task CloseOutputAsync_ServerInitiated_CanReceive(bool useSsl) => RunEchoAsync( + server => RunClient_CloseOutputAsync_ServerInitiated_CanReceive(server, delayReceiving: false), useSsl); + + [OuterLoop("Uses Task.Delay")] + [Theory, MemberData(nameof(UseSsl))] + public Task CloseOutputAsync_ServerInitiated_DelayReceiving_CanReceive(bool useSsl) => RunEchoAsync( + server => RunClient_CloseOutputAsync_ServerInitiated_CanReceive(server, delayReceiving: true), useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task CloseOutputAsync_ServerInitiated_CanSend(bool useSsl) => RunEchoAsync( + RunClient_CloseOutputAsync_ServerInitiated_CanSend, useSsl); + + [OuterLoop("Uses Task.Delay")] + [Theory, MemberData(nameof(UseSslAndBoolean))] + public Task CloseOutputAsync_ServerInitiated_CanReceiveAfterClose(bool useSsl, bool syncState) => RunEchoAsync( + server => RunClient_CloseOutputAsync_ServerInitiated_CanReceiveAfterClose(server, syncState), useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task CloseOutputAsync_CloseDescriptionIsNull_Success(bool useSsl) => RunEchoAsync( + RunClient_CloseOutputAsync_CloseDescriptionIsNull_Success, useSsl); + + [ActiveIssue("https://github.com/dotnet/runtime/issues/22000", TargetFrameworkMonikers.Netcoreapp)] + [Theory, MemberData(nameof(UseSsl))] + public Task CloseOutputAsync_DuringConcurrentReceiveAsync_ExpectedStates(bool useSsl) => RunEchoAsync( + RunClient_CloseOutputAsync_DuringConcurrentReceiveAsync_ExpectedStates, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task CloseAsync_DuringConcurrentReceiveAsync_ExpectedStates(bool useSsl) => RunEchoAsync( + RunClient_CloseAsync_DuringConcurrentReceiveAsync_ExpectedStates, useSsl); + + #endregion + } + + public abstract class CloseTest_Loopback(ITestOutputHelper output) : CloseTest_LoopbackBase(output) + { + #region HTTP/1.1-only loopback tests + + [Fact] + public async Task CloseAsync_CancelableEvenWhenPendingReceive_Throws() + { + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + await LoopbackServer.CreateClientAndServerAsync(async uri => + { + try + { + using (var cws = new ClientWebSocket()) + using (var testTimeoutCts = new CancellationTokenSource(TimeOutMilliseconds)) + { + await ConnectAsync(cws, uri, testTimeoutCts.Token); + + Task receiveTask = cws.ReceiveAsync(new byte[1], testTimeoutCts.Token); + + var cancelCloseCts = new CancellationTokenSource(); + await Assert.ThrowsAnyAsync(async () => + { + Task t = cws.CloseAsync(WebSocketCloseStatus.NormalClosure, null, cancelCloseCts.Token); + cancelCloseCts.Cancel(); + await t; + }); + + Assert.True(cancelCloseCts.Token.IsCancellationRequested); + Assert.False(testTimeoutCts.Token.IsCancellationRequested); + + await Assert.ThrowsAnyAsync(() => receiveTask); + + Assert.False(testTimeoutCts.Token.IsCancellationRequested); + } + } + finally + { + tcs.SetResult(); + } + }, server => server.AcceptConnectionAsync(async connection => + { + Dictionary headers = await LoopbackHelper.WebSocketHandshakeAsync(connection); + Assert.NotNull(headers); + + await tcs.Task; + + }), new LoopbackServer.Options { WebSocketEndpoint = true }); + } + + // Regression test for https://github.com/dotnet/runtime/issues/80116. + [OuterLoop("Uses Task.Delay")] + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public async Task CloseHandshake_ExceptionsAreObserved() + { + await RemoteExecutor.Invoke(static (typeName) => + { + ClientWebSocketTestBase test = (ClientWebSocketTestBase)Activator.CreateInstance(typeof(ClientWebSocketTestBase).Assembly.GetType(typeName), new object[] { null }); + using CancellationTokenSource timeoutCts = new CancellationTokenSource(TimeOutMilliseconds); + + Exception unobserved = null; + TaskScheduler.UnobservedTaskException += (obj, args) => + { + unobserved = args.Exception; + }; + + TaskCompletionSource clientCompleted = new TaskCompletionSource(); + + return LoopbackWebSocketServer.RunAsync(async uri => + { + var ct = timeoutCts.Token; + using var clientWs = await test.GetConnectedWebSocket(uri); + await clientWs.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", ct); + await clientWs.ReceiveAsync(new byte[16], ct); + await Task.Delay(1500); + GC.Collect(2); + GC.WaitForPendingFinalizers(); + clientCompleted.SetResult(); + Assert.Null(unobserved); + }, + async (serverWs, ct) => + { + await serverWs.ReceiveAsync(new byte[16], ct); + await serverWs.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", ct); + await clientCompleted.Task; + }, new LoopbackWebSocketServer.Options(Net.HttpVersion.Version11, UseSsl: PlatformDetection.SupportsAlpn), timeoutCts.Token); + }, GetType().FullName).DisposeAsync(); + } + + #endregion + } + + public abstract class CloseTest_Http2Loopback(ITestOutputHelper output) : CloseTest_LoopbackBase(output) + { + internal override Version HttpVersion => Net.HttpVersion.Version20; + } + + #region Runnable test classes: HTTP/1.1 Loopback + + public sealed class CloseTest_SharedHandler_Loopback(ITestOutputHelper output) : CloseTest_Loopback(output) { } + + public sealed class CloseTest_Invoker_Loopback(ITestOutputHelper output) : CloseTest_Loopback(output) + { + protected override bool UseCustomInvoker => true; + } + + public sealed class CloseTest_HttpClient_Loopback(ITestOutputHelper output) : CloseTest_Loopback(output) + { + protected override bool UseHttpClient => true; + } + + #endregion + + #region Runnable test classes: HTTP/2 Loopback + + public sealed class CloseTest_Invoker_Http2Loopback(ITestOutputHelper output) : CloseTest_Http2Loopback(output) + { + protected override bool UseCustomInvoker => true; + } + + public sealed class CloseTest_HttpClient_Http2Loopback(ITestOutputHelper output) : CloseTest_Http2Loopback(output) + { + protected override bool UseHttpClient => true; + } + #endregion +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.cs b/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.cs index 063ee71169d17e..9a8f33299de93e 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/CloseTest.cs @@ -1,95 +1,82 @@ // 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.Generic; -using System.Diagnostics; -using System.Net.Http; -using System.Net.Test.Common; -using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Linq; using Xunit; using Xunit.Abstractions; -using Microsoft.DotNet.RemoteExecutor; + +using EchoControlMessage = System.Net.Test.Common.WebSocketEchoHelper.EchoControlMessage; namespace System.Net.WebSockets.Client.Tests { - public sealed class InvokerCloseTest : CloseTest - { - public InvokerCloseTest(ITestOutputHelper output) : base(output) { } - - protected override bool UseCustomInvoker => true; - } - - public sealed class HttpClientCloseTest : CloseTest + // + // Class hierarchy: + // + // - CloseTestBase → file:CloseTest.cs + // ├─ CloseTest_External + // │ ├─ [*]CloseTest_SharedHandler_External + // │ ├─ [*]CloseTest_Invoker_External + // │ └─ [*]CloseTest_HttpClient_External + // └─ CloseTest_Loopback → file:CloseTest.Loopback.cs + // ├─ [*]CloseTest_SharedHandler_Loopback + // ├─ [*]CloseTest_Invoker_Loopback + // ├─ [*]CloseTest_HttpClient_Loopback + // └─ CloseTest_Http2Loopback + // ├─ [*]CloseTest_Invoker_Http2Loopback + // └─ [*]CloseTest_HttpClient_Http2Loopback + // + // --- + // `[*]` - concrete runnable test classes + // `→ file:` - file containing the class and its concrete subclasses + + public abstract class CloseTestBase(ITestOutputHelper output) : ClientWebSocketTestBase(output) { - public HttpClientCloseTest(ITestOutputHelper output) : base(output) { } - - protected override bool UseHttpClient => true; - } - - public class CloseTest : ClientWebSocketTestBase - { - public CloseTest(ITestOutputHelper output) : base(output) { } - + #region Common (Echo Server) tests - [ActiveIssue("https://github.com/dotnet/runtime/issues/28957", typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServersAndBoolean))] - public async Task CloseAsync_ServerInitiatedClose_Success(Uri server, bool useCloseOutputAsync) + protected async Task RunClient_CloseAsync_ServerInitiatedClose_Success(Uri server, bool useCloseOutputAsync) { - const string shutdownWebSocketMetaCommand = ".shutdown"; - - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); - _output.WriteLine("SendAsync starting."); await cws.SendAsync( - WebSocketData.GetBufferFromText(shutdownWebSocketMetaCommand), + EchoControlMessage.Shutdown.ToUtf8(), WebSocketMessageType.Text, true, cts.Token); - _output.WriteLine("SendAsync done."); var recvBuffer = new byte[256]; - _output.WriteLine("ReceiveAsync starting."); WebSocketReceiveResult recvResult = await cws.ReceiveAsync(new ArraySegment(recvBuffer), cts.Token); - _output.WriteLine("ReceiveAsync done."); // Verify received server-initiated close message. Assert.Equal(WebSocketCloseStatus.NormalClosure, recvResult.CloseStatus); - Assert.Equal(shutdownWebSocketMetaCommand, recvResult.CloseStatusDescription); + Assert.Equal(EchoControlMessage.Shutdown, recvResult.CloseStatusDescription); Assert.Equal(WebSocketMessageType.Close, recvResult.MessageType); // Verify current websocket state as CloseReceived which indicates only partial close. Assert.Equal(WebSocketState.CloseReceived, cws.State); Assert.Equal(WebSocketCloseStatus.NormalClosure, cws.CloseStatus); - Assert.Equal(shutdownWebSocketMetaCommand, cws.CloseStatusDescription); + Assert.Equal(EchoControlMessage.Shutdown, cws.CloseStatusDescription); // Send back close message to acknowledge server-initiated close. - _output.WriteLine("Close starting."); var closeStatus = PlatformDetection.IsNotBrowser ? WebSocketCloseStatus.InvalidMessageType : (WebSocketCloseStatus)3210; await (useCloseOutputAsync ? cws.CloseOutputAsync(closeStatus, string.Empty, cts.Token) : cws.CloseAsync(closeStatus, string.Empty, cts.Token)); - _output.WriteLine("Close done."); Assert.Equal(WebSocketState.Closed, cws.State); // Verify that there is no follow-up echo close message back from the server by // making sure the close code and message are the same as from the first server close message. Assert.Equal(WebSocketCloseStatus.NormalClosure, cws.CloseStatus); - Assert.Equal(shutdownWebSocketMetaCommand, cws.CloseStatusDescription); + Assert.Equal(EchoControlMessage.Shutdown, cws.CloseStatusDescription); } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseAsync_ClientInitiatedClose_Success(Uri server) + protected async Task RunClient_CloseAsync_ClientInitiatedClose_Success(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); Assert.Equal(WebSocketState.Open, cws.State); @@ -107,13 +94,11 @@ public async Task CloseAsync_ClientInitiatedClose_Success(Uri server) } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseAsync_CloseDescriptionIsMaxLength_Success(Uri server) + protected async Task RunClient_CloseAsync_CloseDescriptionIsMaxLength_Success(Uri server) { string closeDescription = new string('C', CloseDescriptionMaxLength); - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); @@ -121,13 +106,11 @@ public async Task CloseAsync_CloseDescriptionIsMaxLength_Success(Uri server) } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseAsync_CloseDescriptionIsMaxLengthPlusOne_ThrowsArgumentException(Uri server) + protected async Task RunClient_CloseAsync_CloseDescriptionIsMaxLengthPlusOne_ThrowsArgumentException(Uri server) { string closeDescription = new string('C', CloseDescriptionMaxLength + 1); - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); @@ -146,11 +129,9 @@ public async Task CloseAsync_CloseDescriptionIsMaxLengthPlusOne_ThrowsArgumentEx } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseAsync_CloseDescriptionHasUnicode_Success(Uri server) + protected async Task RunClient_CloseAsync_CloseDescriptionHasUnicode_Success(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); @@ -165,11 +146,9 @@ public async Task CloseAsync_CloseDescriptionHasUnicode_Success(Uri server) } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseAsync_CloseDescriptionIsNull_Success(Uri server) + protected async Task RunClient_CloseAsync_CloseDescriptionIsNull_Success(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); @@ -181,11 +160,9 @@ public async Task CloseAsync_CloseDescriptionIsNull_Success(Uri server) } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseOutputAsync_ExpectedStates(Uri server) + protected async Task RunClient_CloseOutputAsync_ExpectedStates(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); @@ -200,11 +177,9 @@ public async Task CloseOutputAsync_ExpectedStates(Uri server) } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseAsync_CloseOutputAsync_Throws(Uri server) + protected async Task RunClient_CloseAsync_CloseOutputAsync_Throws(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); @@ -225,20 +200,18 @@ await Assert.ThrowsAnyAsync(async () => } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseOutputAsync_ClientInitiated_CanReceive_CanClose(Uri server) + protected async Task RunClient_CloseOutputAsync_ClientInitiated_CanReceive_CanClose(Uri server) { string message = "Hello WebSockets!"; - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); var closeStatus = PlatformDetection.IsNotBrowser ? WebSocketCloseStatus.InvalidPayloadData : (WebSocketCloseStatus)3210; string closeDescription = "CloseOutputAsync_Client_InvalidPayloadData"; - await cws.SendAsync(WebSocketData.GetBufferFromText(message), WebSocketMessageType.Text, true, cts.Token); + await cws.SendAsync(message.ToUtf8(), WebSocketMessageType.Text, true, cts.Token); // Need a short delay as per WebSocket rfc6455 section 5.5.1 there isn't a requirement to receive any // data fragments after a close has been sent. The delay allows the received data fragment to be // available before calling close. The WinRT MessageWebSocket implementation doesn't allow receiving @@ -252,7 +225,7 @@ public async Task CloseOutputAsync_ClientInitiated_CanReceive_CanClose(Uri serve WebSocketReceiveResult recvResult = await cws.ReceiveAsync(segmentRecv, cts.Token); Assert.Equal(message.Length, recvResult.Count); segmentRecv = new ArraySegment(segmentRecv.Array, 0, recvResult.Count); - Assert.Equal(message, WebSocketData.GetTextFromBuffer(segmentRecv)); + Assert.Equal(message, segmentRecv.Utf8ToString()); Assert.Null(recvResult.CloseStatus); Assert.Null(recvResult.CloseStatusDescription); @@ -263,20 +236,17 @@ public async Task CloseOutputAsync_ClientInitiated_CanReceive_CanClose(Uri serve } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/28957", typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServersAndBoolean))] - public async Task CloseOutputAsync_ServerInitiated_CanReceive(Uri server, bool delayReceiving) + protected async Task RunClient_CloseOutputAsync_ServerInitiated_CanReceive(Uri server, bool delayReceiving) { var expectedCloseStatus = WebSocketCloseStatus.NormalClosure; - var expectedCloseDescription = ".shutdownafter"; + var expectedCloseDescription = EchoControlMessage.ShutdownAfter; - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); await cws.SendAsync( - WebSocketData.GetBufferFromText(expectedCloseDescription), + expectedCloseDescription.ToUtf8(), WebSocketMessageType.Text, true, cts.Token); @@ -291,7 +261,7 @@ await cws.SendAsync( WebSocketReceiveResult recvResult = await cws.ReceiveAsync(segmentRecv, cts.Token); Assert.Equal(expectedCloseDescription.Length, recvResult.Count); segmentRecv = new ArraySegment(segmentRecv.Array, 0, recvResult.Count); - Assert.Equal(expectedCloseDescription, WebSocketData.GetTextFromBuffer(segmentRecv)); + Assert.Equal(expectedCloseDescription, segmentRecv.Utf8ToString()); Assert.Null(recvResult.CloseStatus); Assert.Null(recvResult.CloseStatusDescription); @@ -320,21 +290,18 @@ await cws.SendAsync( } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/28957", typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseOutputAsync_ServerInitiated_CanSend(Uri server) + protected async Task RunClient_CloseOutputAsync_ServerInitiated_CanSend(Uri server) { string message = "Hello WebSockets!"; var expectedCloseStatus = WebSocketCloseStatus.NormalClosure; - var expectedCloseDescription = ".shutdown"; + var expectedCloseDescription = EchoControlMessage.Shutdown; - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); await cws.SendAsync( - WebSocketData.GetBufferFromText(".shutdown"), + EchoControlMessage.Shutdown.ToUtf8(), WebSocketMessageType.Text, true, cts.Token); @@ -354,7 +321,7 @@ await cws.SendAsync( Assert.Equal(WebSocketState.CloseReceived, cws.State); // Should be able to send. - await cws.SendAsync(WebSocketData.GetBufferFromText(message), WebSocketMessageType.Text, true, cts.Token); + await cws.SendAsync(message.ToUtf8(), WebSocketMessageType.Text, true, cts.Token); // Cannot change the close status/description with the final close. var closeStatus = PlatformDetection.IsNotBrowser ? WebSocketCloseStatus.InvalidPayloadData : (WebSocketCloseStatus)3210; @@ -368,15 +335,13 @@ await cws.SendAsync( } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/28957", typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServersAndBoolean))] - public async Task CloseOutputAsync_ServerInitiated_CanReceiveAfterClose(Uri server, bool syncState) + protected async Task RunClient_CloseOutputAsync_ServerInitiated_CanReceiveAfterClose(Uri server, bool syncState) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); await cws.SendAsync( - WebSocketData.GetBufferFromText(".receiveMessageAfterClose"), + EchoControlMessage.ReceiveMessageAfterClose.ToUtf8(), WebSocketMessageType.Text, true, cts.Token); @@ -392,17 +357,16 @@ await cws.SendAsync( var recvBuffer = new ArraySegment(new byte[1024]); WebSocketReceiveResult recvResult = await cws.ReceiveAsync(recvBuffer, cts.Token); - var message = Encoding.UTF8.GetString(recvBuffer.ToArray(), 0, recvResult.Count); + var recvSegment = new ArraySegment(recvBuffer.ToArray(), 0, recvResult.Count); + var message = recvSegment.Utf8ToString(); - Assert.Contains(".receiveMessageAfterClose", message); + Assert.Contains(EchoControlMessage.ReceiveMessageAfterClose, message); } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseOutputAsync_CloseDescriptionIsNull_Success(Uri server) + protected async Task RunClient_CloseOutputAsync_CloseDescriptionIsNull_Success(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); @@ -413,13 +377,10 @@ public async Task CloseOutputAsync_CloseDescriptionIsNull_Success(Uri server) } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/22000", TargetFrameworkMonikers.Netcoreapp)] - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseOutputAsync_DuringConcurrentReceiveAsync_ExpectedStates(Uri server) + protected async Task RunClient_CloseOutputAsync_DuringConcurrentReceiveAsync_ExpectedStates(Uri server) { var receiveBuffer = new byte[1024]; - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { // Issue a receive but don't wait for it. var t = cws.ReceiveAsync(new ArraySegment(receiveBuffer), CancellationToken.None); @@ -451,12 +412,10 @@ public async Task CloseOutputAsync_DuringConcurrentReceiveAsync_ExpectedStates(U } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task CloseAsync_DuringConcurrentReceiveAsync_ExpectedStates(Uri server) + protected async Task RunClient_CloseAsync_DuringConcurrentReceiveAsync_ExpectedStates(Uri server) { var receiveBuffer = new byte[1024]; - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var t = cws.ReceiveAsync(new ArraySegment(receiveBuffer), CancellationToken.None); Assert.False(t.IsCompleted); @@ -478,88 +437,96 @@ public async Task CloseAsync_DuringConcurrentReceiveAsync_ExpectedStates(Uri ser } } - [ConditionalFact(nameof(WebSocketsSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/54153", TestPlatforms.Browser)] - public async Task CloseAsync_CancelableEvenWhenPendingReceive_Throws() - { - var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + #endregion + } - await LoopbackServer.CreateClientAndServerAsync(async uri => - { - try - { - using (var cws = new ClientWebSocket()) - using (var testTimeoutCts = new CancellationTokenSource(TimeOutMilliseconds)) - { - await ConnectAsync(cws, uri, testTimeoutCts.Token); + [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] + [ConditionalClass(typeof(ClientWebSocketTestBase), nameof(WebSocketsSupported))] + public abstract class CloseTest_External(ITestOutputHelper output) : CloseTestBase(output) + { + #region Common (Echo Server) tests - Task receiveTask = cws.ReceiveAsync(new byte[1], testTimeoutCts.Token); + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser))] // See https://github.com/dotnet/runtime/issues/28957 + [MemberData(nameof(EchoServersAndBoolean))] + public Task CloseAsync_ServerInitiatedClose_Success(Uri server, bool useCloseOutputAsync) + => RunClient_CloseAsync_ServerInitiatedClose_Success(server, useCloseOutputAsync); - var cancelCloseCts = new CancellationTokenSource(); - await Assert.ThrowsAnyAsync(async () => - { - Task t = cws.CloseAsync(WebSocketCloseStatus.NormalClosure, null, cancelCloseCts.Token); - cancelCloseCts.Cancel(); - await t; - }); + [Theory, MemberData(nameof(EchoServers))] + public Task CloseAsync_ClientInitiatedClose_Success(Uri server) + => RunClient_CloseAsync_ClientInitiatedClose_Success(server); - Assert.True(cancelCloseCts.Token.IsCancellationRequested); - Assert.False(testTimeoutCts.Token.IsCancellationRequested); + [Theory, MemberData(nameof(EchoServers))] + public Task CloseAsync_CloseDescriptionIsMaxLength_Success(Uri server) + => RunClient_CloseAsync_CloseDescriptionIsMaxLength_Success(server); - await Assert.ThrowsAnyAsync(() => receiveTask); + [Theory, MemberData(nameof(EchoServers))] + public Task CloseAsync_CloseDescriptionIsMaxLengthPlusOne_ThrowsArgumentException(Uri server) + => RunClient_CloseAsync_CloseDescriptionIsMaxLengthPlusOne_ThrowsArgumentException(server); - Assert.False(testTimeoutCts.Token.IsCancellationRequested); - } - } - finally - { - tcs.SetResult(); - } - }, server => server.AcceptConnectionAsync(async connection => - { - Dictionary headers = await LoopbackHelper.WebSocketHandshakeAsync(connection); - Assert.NotNull(headers); + [Theory, MemberData(nameof(EchoServers))] + public Task CloseAsync_CloseDescriptionHasUnicode_Success(Uri server) + => RunClient_CloseAsync_CloseDescriptionHasUnicode_Success(server); - await tcs.Task; + [Theory, MemberData(nameof(EchoServers))] + public Task CloseAsync_CloseDescriptionIsNull_Success(Uri server) + => RunClient_CloseAsync_CloseDescriptionIsNull_Success(server); - }), new LoopbackServer.Options { WebSocketEndpoint = true }); - } + [Theory, MemberData(nameof(EchoServers))] + public Task CloseOutputAsync_ExpectedStates(Uri server) + => RunClient_CloseOutputAsync_ExpectedStates(server); - // Regression test for https://github.com/dotnet/runtime/issues/80116. - [OuterLoop("Uses Task.Delay")] - [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] - public async Task CloseHandshake_ExceptionsAreObserved() - { - await RemoteExecutor.Invoke(static (typeName) => - { - CloseTest test = (CloseTest)Activator.CreateInstance(typeof(CloseTest).Assembly.GetType(typeName), new object[] { null }); - using CancellationTokenSource timeoutCts = new CancellationTokenSource(TimeOutMilliseconds); + [Theory, MemberData(nameof(EchoServers))] + public Task CloseAsync_CloseOutputAsync_Throws(Uri server) + => RunClient_CloseAsync_CloseOutputAsync_Throws(server); - Exception unobserved = null; - TaskScheduler.UnobservedTaskException += (obj, args) => - { - unobserved = args.Exception; - }; + [Theory, MemberData(nameof(EchoServers))] + public Task CloseOutputAsync_ClientInitiated_CanReceive_CanClose(Uri server) + => RunClient_CloseOutputAsync_ClientInitiated_CanReceive_CanClose(server); - TaskCompletionSource clientCompleted = new TaskCompletionSource(); + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser))] // See https://github.com/dotnet/runtime/issues/28957 + [MemberData(nameof(EchoServersAndBoolean))] + public Task CloseOutputAsync_ServerInitiated_CanReceive(Uri server, bool delayReceiving) + => RunClient_CloseOutputAsync_ServerInitiated_CanReceive(server, delayReceiving); - return LoopbackWebSocketServer.RunAsync(async (clientWs, ct) => - { - await clientWs.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", ct); - await clientWs.ReceiveAsync(new byte[16], ct); - await Task.Delay(1500); - GC.Collect(2); - GC.WaitForPendingFinalizers(); - clientCompleted.SetResult(); - Assert.Null(unobserved); - }, - async (serverWs, ct) => - { - await serverWs.ReceiveAsync(new byte[16], ct); - await serverWs.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", ct); - await clientCompleted.Task; - }, new LoopbackWebSocketServer.Options(HttpVersion.Version11, true, test.GetInvoker()), timeoutCts.Token); - }, GetType().FullName).DisposeAsync(); - } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser))] // See https://github.com/dotnet/runtime/issues/28957 + [MemberData(nameof(EchoServers))] + public Task CloseOutputAsync_ServerInitiated_CanSend(Uri server) + => RunClient_CloseOutputAsync_ServerInitiated_CanSend(server); + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser))] // See https://github.com/dotnet/runtime/issues/28957 + [MemberData(nameof(EchoServersAndBoolean))] + public Task CloseOutputAsync_ServerInitiated_CanReceiveAfterClose(Uri server, bool syncState) + => RunClient_CloseOutputAsync_ServerInitiated_CanReceiveAfterClose(server, syncState); + + [Theory, MemberData(nameof(EchoServers))] + public Task CloseOutputAsync_CloseDescriptionIsNull_Success(Uri server) + => RunClient_CloseOutputAsync_CloseDescriptionIsNull_Success(server); + + [ActiveIssue("https://github.com/dotnet/runtime/issues/22000", TargetFrameworkMonikers.Netcoreapp)] + [Theory, MemberData(nameof(EchoServers))] + public Task CloseOutputAsync_DuringConcurrentReceiveAsync_ExpectedStates(Uri server) + => RunClient_CloseOutputAsync_DuringConcurrentReceiveAsync_ExpectedStates(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task CloseAsync_DuringConcurrentReceiveAsync_ExpectedStates(Uri server) + => RunClient_CloseAsync_DuringConcurrentReceiveAsync_ExpectedStates(server); + + #endregion + } + + #region Runnable test classes: External/Outerloop + + public sealed class CloseTest_SharedHandler_External(ITestOutputHelper output) : CloseTest_External(output) { } + + public sealed class CloseTest_Invoker_External(ITestOutputHelper output) : CloseTest_External(output) + { + protected override bool UseCustomInvoker => true; + } + + public sealed class CloseTest_HttpClient_External(ITestOutputHelper output) : CloseTest_External(output) + { + protected override bool UseHttpClient => true; } + + #endregion } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.Http2.cs b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.Http2.cs index eb31ed4b4c0715..814fae5132ac9e 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.Http2.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.Http2.cs @@ -1,67 +1,20 @@ // 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.Generic; using System.Net.Http; using System.Net.Test.Common; using System.Threading; using System.Threading.Tasks; using Xunit; -using Xunit.Abstractions; namespace System.Net.WebSockets.Client.Tests { - public sealed class InvokerConnectTest_Http2 : ConnectTest_Http2 + public abstract partial class ConnectTest_Http2Loopback { - public InvokerConnectTest_Http2(ITestOutputHelper output) : base(output) { } - - protected override bool UseCustomInvoker => true; - } - - public sealed class HttpClientConnectTest_Http2 : ConnectTest_Http2 - { - public HttpClientConnectTest_Http2(ITestOutputHelper output) : base(output) { } - - protected override bool UseHttpClient => true; - } - - public sealed class HttpClientConnectTest_Http2_NoInvoker : ClientWebSocketTestBase - { - public HttpClientConnectTest_Http2_NoInvoker(ITestOutputHelper output) : base(output) { } - - public static IEnumerable ConnectAsync_Http2WithNoInvoker_ThrowsArgumentException_MemberData() - { - yield return Options(options => options.HttpVersion = HttpVersion.Version20); - yield return Options(options => options.HttpVersion = HttpVersion.Version30); - yield return Options(options => options.HttpVersion = new Version(2, 1)); - yield return Options(options => options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher); - - static object[] Options(Action configureOptions) => - new object[] { configureOptions }; - } - - [Theory] - [MemberData(nameof(ConnectAsync_Http2WithNoInvoker_ThrowsArgumentException_MemberData))] - [SkipOnPlatform(TestPlatforms.Browser, "HTTP/2 WebSockets aren't supported on Browser")] - public async Task ConnectAsync_Http2WithNoInvoker_ThrowsArgumentException(Action configureOptions) - { - using var ws = new ClientWebSocket(); - configureOptions(ws.Options); - - Task connectTask = ws.ConnectAsync(new Uri("wss://dummy"), CancellationToken.None); - - Assert.Equal(TaskStatus.Faulted, connectTask.Status); - await Assert.ThrowsAsync("options", () => connectTask); - } - } - - public abstract class ConnectTest_Http2 : ClientWebSocketTestBase - { - public ConnectTest_Http2(ITestOutputHelper output) : base(output) { } + #region HTTP/2-only loopback tests [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "System.Net.Sockets is not supported on this platform")] public async Task ConnectAsync_VersionNotSupported_NoSsl_Throws() { await Http2LoopbackServer.CreateClientAndServerAsync(async uri => @@ -69,7 +22,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => using (var cws = new ClientWebSocket()) using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { - cws.Options.HttpVersion = HttpVersion.Version20; + cws.Options.HttpVersion = Net.HttpVersion.Version20; cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionExact; Task t = cws.ConnectAsync(uri, GetInvoker(), cts.Token); @@ -87,7 +40,6 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => } [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "Self-signed certificates are not supported on browser")] public async Task ConnectAsync_VersionNotSupported_WithSsl_Throws() { await Http2LoopbackServer.CreateClientAndServerAsync(async uri => @@ -95,7 +47,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => using (var cws = new ClientWebSocket()) using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { - cws.Options.HttpVersion = HttpVersion.Version20; + cws.Options.HttpVersion = Net.HttpVersion.Version20; cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionExact; Task t = cws.ConnectAsync(uri, GetInvoker(), cts.Token); @@ -112,48 +64,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => }, new Http2Options() { WebSocketEndpoint = true }); } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "System.Net.Sockets is not supported on this platform")] - public async Task ConnectAsync_Http11Server_DowngradeFail() - { - using (var cws = new ClientWebSocket()) - using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) - { - cws.Options.HttpVersion = HttpVersion.Version20; - cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionExact; - - Task t = cws.ConnectAsync(Test.Common.Configuration.WebSockets.SecureRemoteEchoServer, GetInvoker(), cts.Token); - - var ex = await Assert.ThrowsAnyAsync(() => t); - Assert.True(ex.InnerException.Data.Contains("HTTP2_ENABLED")); - HttpRequestException inner = Assert.IsType(ex.InnerException); - HttpRequestError expectedError = PlatformDetection.SupportsAlpn ? - HttpRequestError.SecureConnectionError : - HttpRequestError.VersionNegotiationError; - Assert.Equal(expectedError, inner.HttpRequestError); - Assert.Equal(WebSocketState.Closed, cws.State); - } - } - - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [Theory] - [MemberData(nameof(EchoServers))] - [SkipOnPlatform(TestPlatforms.Browser, "System.Net.Sockets is not supported on this platform")] - public async Task ConnectAsync_Http11Server_DowngradeSuccess(Uri server) - { - using (var cws = new ClientWebSocket()) - using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) - { - cws.Options.HttpVersion = HttpVersion.Version20; - cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrLower; - await cws.ConnectAsync(server, GetInvoker(), cts.Token); - Assert.Equal(WebSocketState.Open, cws.State); - } - } - [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "System.Net.Sockets is not supported on this platform")] public async Task ConnectAsync_VersionSupported_NoSsl_Success() { await Http2LoopbackServer.CreateClientAndServerAsync(async uri => @@ -161,7 +72,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => using (var cws = new ClientWebSocket()) using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { - cws.Options.HttpVersion = HttpVersion.Version20; + cws.Options.HttpVersion = Net.HttpVersion.Version20; cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionExact; await cws.ConnectAsync(uri, GetInvoker(), cts.Token); } @@ -175,7 +86,6 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => } [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "Self-signed certificates are not supported on browser")] public async Task ConnectAsync_VersionSupported_WithSsl_Success() { await Http2LoopbackServer.CreateClientAndServerAsync(async uri => @@ -183,7 +93,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => using (var cws = new ClientWebSocket()) using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { - cws.Options.HttpVersion = HttpVersion.Version20; + cws.Options.HttpVersion = Net.HttpVersion.Version20; cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionExact; await cws.ConnectAsync(uri, GetInvoker(), cts.Token); } @@ -197,17 +107,16 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => } [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "HTTP/2 WebSockets aren't supported on Browser")] public async Task ConnectAsync_SameHttp2ConnectionUsedForMultipleWebSocketConnection() { await Http2LoopbackServer.CreateClientAndServerAsync(async uri => { using var cws1 = new ClientWebSocket(); - cws1.Options.HttpVersion = HttpVersion.Version20; + cws1.Options.HttpVersion = Net.HttpVersion.Version20; cws1.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionExact; using var cws2 = new ClientWebSocket(); - cws2.Options.HttpVersion = HttpVersion.Version20; + cws2.Options.HttpVersion = Net.HttpVersion.Version20; cws2.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionExact; using var cts = new CancellationTokenSource(TimeOutMilliseconds); @@ -228,45 +137,6 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => }, new Http2Options() { WebSocketEndpoint = true, UseSsl = false }); } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [Theory] - [MemberData(nameof(EchoServers))] - [SkipOnPlatform(TestPlatforms.Browser, "System.Net.Sockets is not supported on this platform")] - public async Task ConnectAsync_Http11WithRequestVersionOrHigher_DowngradeSuccess(Uri server) - { - using (var cws = new ClientWebSocket()) - using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) - { - cws.Options.HttpVersion = HttpVersion.Version11; - cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher; - await cws.ConnectAsync(server, GetInvoker(), cts.Token); - Assert.Equal(WebSocketState.Open, cws.State); - } - } - - [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "System.Net.Sockets is not supported on this platform")] - public async Task ConnectAsync_Http11WithRequestVersionOrHigher_Loopback_Success() - { - await LoopbackServer.CreateServerAsync(async (server, url) => - { - using (var cws = new ClientWebSocket()) - using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) - { - cws.Options.HttpVersion = HttpVersion.Version11; - cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher; - - Task connectTask = cws.ConnectAsync(url, GetInvoker(), cts.Token); - - await server.AcceptConnectionAsync(async connection => - { - await LoopbackHelper.WebSocketHandshakeAsync(connection); - }); - - await connectTask; - Assert.Equal(WebSocketState.Open, cws.State); - } - }, new LoopbackServer.Options { UseSsl = true, WebSocketEndpoint = true }); - } + #endregion } } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.Invoker.cs b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.Invoker.cs new file mode 100644 index 00000000000000..7ee76e9008be9e --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.Invoker.cs @@ -0,0 +1,90 @@ +// 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.Generic; +using System.IO; +using System.Net.Http; +using System.Security.Cryptography.X509Certificates; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Net.WebSockets.Client.Tests +{ + public partial class ConnectTest_Invoker_Loopback + { + #region Invoker-only HTTP/1.1 loopback tests + + public static IEnumerable ConnectAsync_CustomInvokerWithIncompatibleWebSocketOptions_ThrowsArgumentException_MemberData() + { + yield return Throw(options => options.UseDefaultCredentials = true); + yield return NoThrow(options => options.UseDefaultCredentials = false); + yield return Throw(options => options.Credentials = new NetworkCredential()); + yield return Throw(options => options.Proxy = new WebProxy()); + + // Will result in an exception on apple mobile platforms + // and crash the test. + if (PlatformDetection.IsNotAppleMobile) + { + yield return Throw(options => options.ClientCertificates.Add(Test.Common.Configuration.Certificates.GetClientCertificate())); + } + + yield return NoThrow(options => options.ClientCertificates = new X509CertificateCollection()); + yield return Throw(options => options.RemoteCertificateValidationCallback = delegate { return true; }); + yield return Throw(options => options.Cookies = new CookieContainer()); + + // We allow no proxy or the default proxy to be used + yield return NoThrow(options => { }); + yield return NoThrow(options => options.Proxy = null); + + // These options don't conflict with the custom invoker + yield return NoThrow(options => options.HttpVersion = new Version(2, 0)); + yield return NoThrow(options => options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher); + yield return NoThrow(options => options.SetRequestHeader("foo", "bar")); + yield return NoThrow(options => options.AddSubProtocol("foo")); + yield return NoThrow(options => options.KeepAliveInterval = TimeSpan.FromSeconds(42)); + yield return NoThrow(options => options.DangerousDeflateOptions = new WebSocketDeflateOptions()); + yield return NoThrow(options => options.CollectHttpResponseDetails = true); + + static object[] Throw(Action configureOptions) => + new object[] { configureOptions, true }; + + static object[] NoThrow(Action configureOptions) => + new object[] { configureOptions, false }; + } + + [Theory] + [MemberData(nameof(ConnectAsync_CustomInvokerWithIncompatibleWebSocketOptions_ThrowsArgumentException_MemberData))] + [SkipOnPlatform(TestPlatforms.Browser, "Custom invoker is ignored on Browser")] + public async Task ConnectAsync_CustomInvokerWithIncompatibleWebSocketOptions_ThrowsArgumentException(Action configureOptions, bool shouldThrow) + { + using var invoker = new HttpMessageInvoker(new SocketsHttpHandler + { + ConnectCallback = (_, _) => ValueTask.FromException(new Exception("ConnectCallback")) + }); + + using var ws = new ClientWebSocket(); + configureOptions(ws.Options); + + Task connectTask = ws.ConnectAsync(new Uri("wss://dummy"), invoker, CancellationToken.None); + if (shouldThrow) + { + Assert.Equal(TaskStatus.Faulted, connectTask.Status); + await Assert.ThrowsAsync("options", () => connectTask); + } + else + { + WebSocketException ex = await Assert.ThrowsAsync(() => connectTask); + Assert.NotNull(ex.InnerException); + Assert.Contains("ConnectCallback", ex.InnerException.Message); + } + + foreach (X509Certificate cert in ws.Options.ClientCertificates) + { + cert.Dispose(); + } + } + + #endregion + } +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.Loopback.cs b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.Loopback.cs new file mode 100644 index 00000000000000..3002ff8a8a37e6 --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.Loopback.cs @@ -0,0 +1,130 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Net.Http; +using System.Net.Test.Common; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.DotNet.XUnitExtensions; +using Xunit; +using Xunit.Abstractions; + +namespace System.Net.WebSockets.Client.Tests +{ + [ConditionalClass(typeof(ClientWebSocketTestBase), nameof(WebSocketsSupported))] + [SkipOnPlatform(TestPlatforms.Browser, "System.Net.Sockets are not supported on browser")] + public abstract class ConnectTest_LoopbackBase(ITestOutputHelper output) : ConnectTestBase(output) + { + #region Common (Echo Server) tests + + [Theory, MemberData(nameof(UseSsl))] + public Task EchoBinaryMessage_Success(bool useSsl) => RunEchoAsync( + RunClient_EchoBinaryMessage_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task EchoTextMessage_Success(bool useSsl) => RunEchoAsync( + RunClient_EchoTextMessage_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task ConnectAsync_AddCustomHeaders_Success(bool useSsl) => RunEchoHeadersAsync( + RunClient_ConnectAsync_AddCustomHeaders_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task ConnectAsync_CookieHeaders_Success(bool useSsl) => RunEchoHeadersAsync( + RunClient_ConnectAsync_CookieHeaders_Success, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task ConnectAsync_PassNoSubProtocol_ServerRequires_ThrowsWebSocketException(bool useSsl) => RunEchoAsync( + RunClient_ConnectAsync_PassNoSubProtocol_ServerRequires_ThrowsWebSocketException, useSsl); + + [Theory, MemberData(nameof(UseSsl))] + public Task ConnectAsync_PassMultipleSubProtocols_ServerRequires_ConnectionUsesAgreedSubProtocol(bool useSsl) => RunEchoAsync( + RunClient_ConnectAsync_PassMultipleSubProtocols_ServerRequires_ConnectionUsesAgreedSubProtocol, useSsl); + + [ConditionalTheory] // Uses SkipTestException + [MemberData(nameof(UseSsl))] + public Task ConnectAndCloseAsync_UseProxyServer_ExpectedClosedState(bool useSsl) => RunEchoAsync( + RunClient_ConnectAndCloseAsync_UseProxyServer_ExpectedClosedState, useSsl); + + #endregion + } + + public abstract class ConnectTest_Loopback(ITestOutputHelper output) : ConnectTest_LoopbackBase(output) + { + #region HTTP/1.1-only loopback tests + + [ConditionalTheory] // Uses SkipTestException + [MemberData(nameof(UseSsl))] + public async Task ConnectAsync_Http11WithRequestVersionOrHigher_Loopback_DowngradeSuccess(bool useSsl) + { + if (UseSharedHandler) + { + throw new SkipTestException("HTTP/2 is not supported with SharedHandler"); + } + + await LoopbackServer.CreateServerAsync(async (server, url) => + { + using (var cws = new ClientWebSocket()) + using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) + { + cws.Options.HttpVersion = Net.HttpVersion.Version11; + cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher; + + Task connectTask = cws.ConnectAsync(url, GetInvoker(), cts.Token); + + await server.AcceptConnectionAsync(async connection => + { + await LoopbackHelper.WebSocketHandshakeAsync(connection); + }); + + await connectTask; + Assert.Equal(WebSocketState.Open, cws.State); + } + }, new LoopbackServer.Options { UseSsl = useSsl, WebSocketEndpoint = true }); + } + + #endregion + } + + public abstract partial class ConnectTest_Http2Loopback(ITestOutputHelper output) : ConnectTest_LoopbackBase(output) + { + internal override Version HttpVersion => Net.HttpVersion.Version20; + + // #region HTTP/2-only loopback tests -> extracted to ConnectTest.Http2.cs + } + + #region Runnable test classes: HTTP/1.1 Loopback + + public sealed partial class ConnectTest_SharedHandler_Loopback(ITestOutputHelper output) : ConnectTest_Loopback(output) + { + // #region SharedHandler-only HTTP/1.1 loopback tests -> extracted to ConnectTest.SharedHandler.cs + } + + public sealed partial class ConnectTest_Invoker_Loopback(ITestOutputHelper output) : ConnectTest_Loopback(output) + { + protected override bool UseCustomInvoker => true; + + // #region Invoker-only HTTP/1.1 loopback tests -> extracted to ConnectTest.Invoker.cs + } + + public sealed class ConnectTest_HttpClient_Loopback(ITestOutputHelper output) : ConnectTest_Loopback(output) + { + protected override bool UseHttpClient => true; + } + + #endregion + + #region Runnable test classes: HTTP/2 Loopback + + public sealed class ConnectTest_Invoker_Http2Loopback(ITestOutputHelper output) : ConnectTest_Http2Loopback(output) + { + protected override bool UseCustomInvoker => true; + } + + public sealed class ConnectTest_HttpClient_Http2Loopback(ITestOutputHelper output) : ConnectTest_Http2Loopback(output) + { + protected override bool UseHttpClient => true; + } + + #endregion +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.SharedHandler.cs b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.SharedHandler.cs new file mode 100644 index 00000000000000..193d0706dd9629 --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.SharedHandler.cs @@ -0,0 +1,205 @@ +// 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.Generic; +using System.IO; +using System.Net.Http; +using System.Net.Test.Common; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Net.WebSockets.Client.Tests +{ + public partial class ConnectTest_SharedHandler_Loopback + { + #region SharedHandler-only HTTP/1.1 loopback tests + + [Fact] + public async Task ConnectAsync_CancellationRequestedBeforeConnect_ThrowsOperationCanceledException() + { + using (var clientSocket = new ClientWebSocket()) + { + var cts = new CancellationTokenSource(); + cts.Cancel(); + Task t = ConnectAsync(clientSocket, new Uri($"ws://{Guid.NewGuid():N}"), cts.Token); + await Assert.ThrowsAnyAsync(() => t); + } + } + + [Fact] + public async Task ConnectAsync_CancellationRequestedInflightConnect_ThrowsOperationCanceledException() + { + using (var clientSocket = new ClientWebSocket()) + { + var cts = new CancellationTokenSource(); + Task t = ConnectAsync(clientSocket, new Uri($"ws://{Guid.NewGuid():N}"), cts.Token); + cts.Cancel(); + await Assert.ThrowsAnyAsync(() => t); + } + } + + [Fact] + public async Task ConnectAsync_NonStandardRequestHeaders_HeadersAddedWithoutValidation() + { + await LoopbackServer.CreateClientAndServerAsync(async uri => + { + using (var clientSocket = new ClientWebSocket()) + using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) + { + clientSocket.Options.SetRequestHeader("Authorization", "AWS4-HMAC-SHA256 Credential=PLACEHOLDER /20190301/us-east-2/neptune-db/aws4_request, SignedHeaders=host;x-amz-date, Signature=b8155de54d9faab00000000000000000000000000a07e0d7dda49902e4d9202"); + await ConnectAsync(clientSocket, uri, cts.Token); + } + }, server => server.AcceptConnectionAsync(async connection => + { + Assert.NotNull(await LoopbackHelper.WebSocketHandshakeAsync(connection)); + }), new LoopbackServer.Options { WebSocketEndpoint = true }); + } + + [Fact] + public async Task ConnectAsync_CancellationRequestedAfterConnect_ThrowsOperationCanceledException() + { + var releaseServer = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + await LoopbackServer.CreateClientAndServerAsync(async uri => + { + var clientSocket = new ClientWebSocket(); + try + { + var cts = new CancellationTokenSource(); + Task t = ConnectAsync(clientSocket, uri, cts.Token); + Assert.False(t.IsCompleted); + cts.Cancel(); + await Assert.ThrowsAnyAsync(() => t); + } + finally + { + releaseServer.SetResult(); + clientSocket.Dispose(); + } + }, async server => + { + try + { + await server.AcceptConnectionAsync(async connection => + { + await releaseServer.Task; + }); + } + // Ignore IO exception on server as there are race conditions when client is cancelling. + catch (IOException) { } + }, new LoopbackServer.Options { WebSocketEndpoint = true }); + } + + [Fact] + public async Task ConnectAsync_HttpResponseDetailsCollectedOnFailure() + { + await LoopbackServer.CreateClientAndServerAsync(async uri => + { + using (var clientWebSocket = new ClientWebSocket()) + using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) + { + clientWebSocket.Options.CollectHttpResponseDetails = true; + Task t = ConnectAsync(clientWebSocket, uri, cts.Token); + await Assert.ThrowsAnyAsync(() => t); + + Assert.Equal(HttpStatusCode.Unauthorized, clientWebSocket.HttpStatusCode); + Assert.NotEmpty(clientWebSocket.HttpResponseHeaders); + } + }, server => server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.Unauthorized), new LoopbackServer.Options { WebSocketEndpoint = true }); + } + + [Fact] + public async Task ConnectAsync_HttpResponseDetailsCollectedOnFailure_CustomHeader() + { + await LoopbackServer.CreateClientAndServerAsync(async uri => + { + using (var clientWebSocket = new ClientWebSocket()) + using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) + { + clientWebSocket.Options.CollectHttpResponseDetails = true; + Task t = ConnectAsync(clientWebSocket, uri, cts.Token); + await Assert.ThrowsAnyAsync(() => t); + + Assert.Equal(HttpStatusCode.Unauthorized, clientWebSocket.HttpStatusCode); + Assert.NotEmpty(clientWebSocket.HttpResponseHeaders); + Assert.Contains("X-CustomHeader1", clientWebSocket.HttpResponseHeaders); + Assert.Contains("X-CustomHeader2", clientWebSocket.HttpResponseHeaders); + Assert.NotNull(clientWebSocket.HttpResponseHeaders.Values); + } + }, server => server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.Unauthorized, "X-CustomHeader1: Value1\r\nX-CustomHeader2: Value2\r\n"), new LoopbackServer.Options { WebSocketEndpoint = true }); + } + + [Fact] + public async Task ConnectAsync_HttpResponseDetailsCollectedOnSuccess_Extensions() + { + await LoopbackServer.CreateClientAndServerAsync(async uri => + { + using (var clientWebSocket = new ClientWebSocket()) + using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) + { + clientWebSocket.Options.CollectHttpResponseDetails = true; + await ConnectAsync(clientWebSocket, uri, cts.Token); + + Assert.Equal(HttpStatusCode.SwitchingProtocols, clientWebSocket.HttpStatusCode); + Assert.NotEmpty(clientWebSocket.HttpResponseHeaders); + Assert.Contains("Sec-WebSocket-Extensions", clientWebSocket.HttpResponseHeaders); + } + }, server => server.AcceptConnectionAsync(async connection => + { + Dictionary headers = await LoopbackHelper.WebSocketHandshakeAsync(connection, "X-CustomHeader1"); + }), new LoopbackServer.Options { WebSocketEndpoint = true }); + } + + [Fact] + public async Task ConnectAsync_AddHostHeader_Success() + { + string expectedHost = null; + await LoopbackServer.CreateClientAndServerAsync(async uri => + { + expectedHost = "subdomain." + uri.Host; + using (var cws = new ClientWebSocket()) + using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) + { + cws.Options.SetRequestHeader("Host", expectedHost); + await ConnectAsync(cws, uri, cts.Token); + } + }, server => server.AcceptConnectionAsync(async connection => + { + Dictionary headers = await LoopbackHelper.WebSocketHandshakeAsync(connection); + Assert.NotNull(headers); + Assert.True(headers.TryGetValue("Host", out string host)); + Assert.Equal(expectedHost, host); + }), new LoopbackServer.Options { WebSocketEndpoint = true }); + } + + #endregion + + #region SharedHandler-only unsupported HTTP version tests + public static IEnumerable ConnectAsync_Http2WithNoInvoker_ThrowsArgumentException_MemberData() + { + yield return Options(options => options.HttpVersion = Net.HttpVersion.Version20); + yield return Options(options => options.HttpVersion = Net.HttpVersion.Version30); + yield return Options(options => options.HttpVersion = new Version(2, 1)); + yield return Options(options => options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher); + + static object[] Options(Action configureOptions) => + new object[] { configureOptions }; + } + + [Theory] + [MemberData(nameof(ConnectAsync_Http2WithNoInvoker_ThrowsArgumentException_MemberData))] + [SkipOnPlatform(TestPlatforms.Browser, "HTTP/2 WebSockets aren't supported on Browser")] + public async Task ConnectAsync_Http2WithNoInvoker_ThrowsArgumentException(Action configureOptions) + { + using var ws = new ClientWebSocket(); + configureOptions(ws.Options); + + Task connectTask = ws.ConnectAsync(new Uri("wss://dummy"), CancellationToken.None); + + Assert.Equal(TaskStatus.Faulted, connectTask.Status); + await Assert.ThrowsAsync("options", () => connectTask); + } + + #endregion + } +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs index cb5f0f978f761e..01f0fc01138de1 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs @@ -1,150 +1,53 @@ // 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.Generic; -using System.IO; using System.Net.Http; using System.Net.Test.Common; -using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; +using Microsoft.DotNet.XUnitExtensions; using Xunit; using Xunit.Abstractions; +using EchoQueryKey = System.Net.Test.Common.WebSocketEchoOptions.EchoQueryKey; + namespace System.Net.WebSockets.Client.Tests { - public sealed class InvokerConnectTest : ConnectTest + // + // Class hierarchy: + // + // - ConnectTestBase → file:ConnectTest.cs + // ├─ ConnectTest_External + // │ ├─ [*]ConnectTest_SharedHandler_External + // │ ├─ [*]ConnectTest_Invoker_External + // │ └─ [*]ConnectTest_HttpClient_External + // └─ ConnectTest_LoopbackBase → file:ConnectTest.Loopback.cs + // ├─ ConnectTest_Loopback + // │ ├─ [*]ConnectTest_SharedHandler_Loopback → file:ConnectTest.Loopback.cs, ConnectTest.SharedHandler.cs + // │ ├─ [*]ConnectTest_Invoker_Loopback → file:ConnectTest.Loopback.cs, ConnectTest.Invoker.cs + // │ └─ [*]ConnectTest_HttpClient_Loopback + // └─ ConnectTest_Http2Loopback → file:ConnectTest.Loopback.cs, ConnectTest.Http2.cs + // ├─ [*]ConnectTest_Invoker_Http2Loopback + // └─ [*]ConnectTest_HttpClient_Http2Loopback + // + // --- + // `[*]` - concrete runnable test classes + // `→ file:` - file containing the class and its concrete subclasses + + public abstract class ConnectTestBase(ITestOutputHelper output) : ClientWebSocketTestBase(output) { - public InvokerConnectTest(ITestOutputHelper output) : base(output) { } - - protected override bool UseCustomInvoker => true; - - public static IEnumerable ConnectAsync_CustomInvokerWithIncompatibleWebSocketOptions_ThrowsArgumentException_MemberData() - { - yield return Throw(options => options.UseDefaultCredentials = true); - yield return NoThrow(options => options.UseDefaultCredentials = false); - yield return Throw(options => options.Credentials = new NetworkCredential()); - yield return Throw(options => options.Proxy = new WebProxy()); - - // Will result in an exception on apple mobile platforms - // and crash the test. - if (PlatformDetection.IsNotAppleMobile) - { - yield return Throw(options => options.ClientCertificates.Add(Test.Common.Configuration.Certificates.GetClientCertificate())); - } - - yield return NoThrow(options => options.ClientCertificates = new X509CertificateCollection()); - yield return Throw(options => options.RemoteCertificateValidationCallback = delegate { return true; }); - yield return Throw(options => options.Cookies = new CookieContainer()); - - // We allow no proxy or the default proxy to be used - yield return NoThrow(options => { }); - yield return NoThrow(options => options.Proxy = null); + #region Common (Echo Server) tests - // These options don't conflict with the custom invoker - yield return NoThrow(options => options.HttpVersion = new Version(2, 0)); - yield return NoThrow(options => options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher); - yield return NoThrow(options => options.SetRequestHeader("foo", "bar")); - yield return NoThrow(options => options.AddSubProtocol("foo")); - yield return NoThrow(options => options.KeepAliveInterval = TimeSpan.FromSeconds(42)); - yield return NoThrow(options => options.DangerousDeflateOptions = new WebSocketDeflateOptions()); - yield return NoThrow(options => options.CollectHttpResponseDetails = true); + protected Task RunClient_EchoBinaryMessage_Success(Uri server) + => RunClientAsync(server, + (cws, ct) => WebSocketHelper.TestEcho(cws, WebSocketMessageType.Binary, ct)); - static object[] Throw(Action configureOptions) => - new object[] { configureOptions, true }; - static object[] NoThrow(Action configureOptions) => - new object[] { configureOptions, false }; - } + protected Task RunClient_EchoTextMessage_Success(Uri server) + => RunClientAsync(server, + (cws, ct) => WebSocketHelper.TestEcho(cws, WebSocketMessageType.Text, ct)); - [Theory] - [MemberData(nameof(ConnectAsync_CustomInvokerWithIncompatibleWebSocketOptions_ThrowsArgumentException_MemberData))] - [SkipOnPlatform(TestPlatforms.Browser, "Custom invoker is ignored on Browser")] - public async Task ConnectAsync_CustomInvokerWithIncompatibleWebSocketOptions_ThrowsArgumentException(Action configureOptions, bool shouldThrow) - { - using var invoker = new HttpMessageInvoker(new SocketsHttpHandler - { - ConnectCallback = (_, _) => ValueTask.FromException(new Exception("ConnectCallback")) - }); - - using var ws = new ClientWebSocket(); - configureOptions(ws.Options); - - Task connectTask = ws.ConnectAsync(new Uri("wss://dummy"), invoker, CancellationToken.None); - if (shouldThrow) - { - Assert.Equal(TaskStatus.Faulted, connectTask.Status); - await Assert.ThrowsAsync("options", () => connectTask); - } - else - { - WebSocketException ex = await Assert.ThrowsAsync(() => connectTask); - Assert.NotNull(ex.InnerException); - Assert.Contains("ConnectCallback", ex.InnerException.Message); - } - - foreach (X509Certificate cert in ws.Options.ClientCertificates) - { - cert.Dispose(); - } - } - } - - public sealed class HttpClientConnectTest : ConnectTest - { - public HttpClientConnectTest(ITestOutputHelper output) : base(output) { } - - protected override bool UseHttpClient => true; - } - - public class ConnectTest : ClientWebSocketTestBase - { - public ConnectTest(ITestOutputHelper output) : base(output) { } - - [ActiveIssue("https://github.com/dotnet/runtime/issues/1895")] - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(UnavailableWebSocketServers))] - public async Task ConnectAsync_NotWebSocketServer_ThrowsWebSocketExceptionWithMessage(Uri server, string exceptionMessage, WebSocketError errorCode) - { - using (var cws = new ClientWebSocket()) - { - var cts = new CancellationTokenSource(TimeOutMilliseconds); - WebSocketException ex = await Assert.ThrowsAsync(() => - ConnectAsync(cws, server, cts.Token)); - - if (!PlatformDetection.IsInAppContainer) // bug fix in netcoreapp: https://github.com/dotnet/corefx/pull/35960 - { - Assert.Equal(errorCode, ex.WebSocketErrorCode); - } - Assert.Equal(WebSocketState.Closed, cws.State); - Assert.Equal(exceptionMessage, ex.Message); - - // Other operations throw after failed connect - await Assert.ThrowsAsync(() => cws.ReceiveAsync(new byte[1], default)); - await Assert.ThrowsAsync(() => cws.SendAsync(new byte[1], WebSocketMessageType.Binary, true, default)); - await Assert.ThrowsAsync(() => cws.CloseAsync(WebSocketCloseStatus.NormalClosure, null, default)); - await Assert.ThrowsAsync(() => cws.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, null, default)); - } - } - - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task EchoBinaryMessage_Success(Uri server) - { - await TestEcho(server, WebSocketMessageType.Binary, TimeOutMilliseconds, _output); - } - - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task EchoTextMessage_Success(Uri server) - { - await TestEcho(server, WebSocketMessageType.Text, TimeOutMilliseconds, _output); - } - - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoHeadersServers))] - [SkipOnPlatform(TestPlatforms.Browser, "SetRequestHeader not supported on browser")] - public async Task ConnectAsync_AddCustomHeaders_Success(Uri server) + protected async Task RunClient_ConnectAsync_AddCustomHeaders_Success(Uri server) { using (var cws = new ClientWebSocket()) { @@ -171,59 +74,42 @@ public async Task ConnectAsync_AddCustomHeaders_Success(Uri server) } Assert.Equal(WebSocketMessageType.Text, recvResult.MessageType); - string headers = WebSocketData.GetTextFromBuffer(new ArraySegment(buffer, 0, recvResult.Count)); - Assert.Contains("X-CustomHeader1:Value1", headers); - Assert.Contains("X-CustomHeader2:Value2", headers); + string headers = new ArraySegment(buffer, 0, recvResult.Count).Utf8ToString(); + Assert.Contains("X-CustomHeader1:Value1", headers, StringComparison.OrdinalIgnoreCase); + Assert.Contains("X-CustomHeader2:Value2", headers, StringComparison.OrdinalIgnoreCase); await cws.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); } } - [ConditionalFact(nameof(WebSocketsSupported))] - [SkipOnPlatform(TestPlatforms.Browser, "SetRequestHeader not supported on browser")] - public async Task ConnectAsync_AddHostHeader_Success() - { - string expectedHost = null; - await LoopbackServer.CreateClientAndServerAsync(async uri => - { - expectedHost = "subdomain." + uri.Host; - using (var cws = new ClientWebSocket()) - using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) - { - cws.Options.SetRequestHeader("Host", expectedHost); - await ConnectAsync(cws, uri, cts.Token); - } - }, server => server.AcceptConnectionAsync(async connection => - { - Dictionary headers = await LoopbackHelper.WebSocketHandshakeAsync(connection); - Assert.NotNull(headers); - Assert.True(headers.TryGetValue("Host", out string host)); - Assert.Equal(expectedHost, host); - }), new LoopbackServer.Options { WebSocketEndpoint = true }); - } - - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoHeadersServers))] - [SkipOnPlatform(TestPlatforms.Browser, "Cookies not supported on browser")] - public async Task ConnectAsync_CookieHeaders_Success(Uri server) + protected async Task RunClient_ConnectAsync_CookieHeaders_Success(Uri server) { using (var cws = new ClientWebSocket()) { Assert.Null(cws.Options.Cookies); - cws.Options.Cookies = new CookieContainer(); + + var cookies = new CookieContainer(); Cookie cookie1 = new Cookie("Cookies", "Are Yummy"); Cookie cookie2 = new Cookie("Especially", "Chocolate Chip"); - Cookie secureCookie = new Cookie("Occasionally", "Raisin"); - secureCookie.Secure = true; + Cookie secureCookie = new Cookie("Occasionally", "Raisin") { Secure = true }; + + cookies.Add(server, cookie1); + cookies.Add(server, cookie2); + cookies.Add(server, secureCookie); - cws.Options.Cookies.Add(server, cookie1); - cws.Options.Cookies.Add(server, cookie2); - cws.Options.Cookies.Add(server, secureCookie); + if (UseSharedHandler) + { + cws.Options.Cookies = cookies; + } + else + { + ConfigureCustomHandler = handler => handler.CookieContainer = cookies; + } using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { - Task taskConnect = cws.ConnectAsync(server, cts.Token); + Task taskConnect = ConnectAsync(cws, server, cts.Token); Assert.True( cws.State == WebSocketState.None || cws.State == WebSocketState.Connecting || @@ -242,7 +128,7 @@ public async Task ConnectAsync_CookieHeaders_Success(Uri server) } Assert.Equal(WebSocketMessageType.Text, recvResult.MessageType); - string headers = WebSocketData.GetTextFromBuffer(new ArraySegment(buffer, 0, recvResult.Count)); + string headers = new ArraySegment(buffer, 0, recvResult.Count).Utf8ToString(); Assert.Contains("Cookies=Are Yummy", headers); Assert.Contains("Especially=Chocolate Chip", headers); @@ -252,10 +138,7 @@ public async Task ConnectAsync_CookieHeaders_Success(Uri server) } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] - public async Task ConnectAsync_PassNoSubProtocol_ServerRequires_ThrowsWebSocketException(Uri server) + protected async Task RunClient_ConnectAsync_PassNoSubProtocol_ServerRequires_ThrowsWebSocketException(Uri server) { const string AcceptedProtocol = "CustomProtocol"; @@ -263,21 +146,19 @@ public async Task ConnectAsync_PassNoSubProtocol_ServerRequires_ThrowsWebSocketE { var cts = new CancellationTokenSource(TimeOutMilliseconds); - var ub = new UriBuilder(server); - ub.Query = "subprotocol=" + AcceptedProtocol; + var ub = new UriBuilder(server) { Query = $"{EchoQueryKey.SubProtocol}={AcceptedProtocol}" }; WebSocketException ex = await Assert.ThrowsAsync(() => ConnectAsync(cws, ub.Uri, cts.Token)); _output.WriteLine(ex.Message); - Assert.True(ex.WebSocketErrorCode == WebSocketError.Faulted || + Assert.True(ex.WebSocketErrorCode == WebSocketError.UnsupportedProtocol || + ex.WebSocketErrorCode == WebSocketError.Faulted || ex.WebSocketErrorCode == WebSocketError.NotAWebSocket, $"Actual WebSocketErrorCode {ex.WebSocketErrorCode} {ex.InnerException?.Message} \n {ex}"); Assert.Equal(WebSocketState.Closed, cws.State); } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task ConnectAsync_PassMultipleSubProtocols_ServerRequires_ConnectionUsesAgreedSubProtocol(Uri server) + protected async Task RunClient_ConnectAsync_PassMultipleSubProtocols_ServerRequires_ConnectionUsesAgreedSubProtocol(Uri server) { const string AcceptedProtocol = "AcceptedProtocol"; const string OtherProtocol = "OtherProtocol"; @@ -288,8 +169,7 @@ public async Task ConnectAsync_PassMultipleSubProtocols_ServerRequires_Connectio cws.Options.AddSubProtocol(OtherProtocol); var cts = new CancellationTokenSource(TimeOutMilliseconds); - var ub = new UriBuilder(server); - ub.Query = "subprotocol=" + AcceptedProtocol; + var ub = new UriBuilder(server) { Query = $"{EchoQueryKey.SubProtocol}={AcceptedProtocol}" }; await ConnectAsync(cws, ub.Uri, cts.Token); Assert.Equal(WebSocketState.Open, cws.State); @@ -297,39 +177,25 @@ public async Task ConnectAsync_PassMultipleSubProtocols_ServerRequires_Connectio } } - [ConditionalFact(nameof(WebSocketsSupported))] - [SkipOnPlatform(TestPlatforms.Browser, "SetRequestHeader not supported on Browser")] - public async Task ConnectAsync_NonStandardRequestHeaders_HeadersAddedWithoutValidation() + protected async Task RunClient_ConnectAndCloseAsync_UseProxyServer_ExpectedClosedState(Uri server) { - await LoopbackServer.CreateClientAndServerAsync(async uri => + if (HttpVersion != Net.HttpVersion.Version11) { - using (var clientSocket = new ClientWebSocket()) - using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) - { - clientSocket.Options.SetRequestHeader("Authorization", "AWS4-HMAC-SHA256 Credential=PLACEHOLDER /20190301/us-east-2/neptune-db/aws4_request, SignedHeaders=host;x-amz-date, Signature=b8155de54d9faab00000000000000000000000000a07e0d7dda49902e4d9202"); - await ConnectAsync(clientSocket, uri, cts.Token); - } - }, server => server.AcceptConnectionAsync(async connection => - { - Assert.NotNull(await LoopbackHelper.WebSocketHandshakeAsync(connection)); - }), new LoopbackServer.Options { WebSocketEndpoint = true }); - } + throw new SkipTestException("LoopbackProxyServer is HTTP/1.1 only"); + } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - [SkipOnPlatform(TestPlatforms.Browser, "Proxy not supported on Browser")] - public async Task ConnectAndCloseAsync_UseProxyServer_ExpectedClosedState(Uri server) - { using (var cws = new ClientWebSocket()) using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create()) { - ConfigureCustomHandler = handler => handler.Proxy = new WebProxy(proxyServer.Uri); - if (UseSharedHandler) { cws.Options.Proxy = new WebProxy(proxyServer.Uri); } + else + { + ConfigureCustomHandler = handler => handler.Proxy = new WebProxy(proxyServer.Uri); + } await ConnectAsync(cws, server, cts.Token); @@ -343,125 +209,161 @@ public async Task ConnectAndCloseAsync_UseProxyServer_ExpectedClosedState(Uri se } } - [ConditionalFact(nameof(WebSocketsSupported))] - public async Task ConnectAsync_CancellationRequestedBeforeConnect_ThrowsOperationCanceledException() + #endregion + } + + [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] + [ConditionalClass(typeof(ClientWebSocketTestBase), nameof(WebSocketsSupported))] + public abstract class ConnectTest_External(ITestOutputHelper output) : ConnectTestBase(output) + { + #region Common (Echo Server) tests + + [Theory, MemberData(nameof(EchoServers))] + public Task EchoBinaryMessage_Success(Uri server) + => RunClient_EchoBinaryMessage_Success(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task EchoTextMessage_Success(Uri server) + => RunClient_EchoTextMessage_Success(server); + + [SkipOnPlatform(TestPlatforms.Browser, "SetRequestHeader not supported on browser")] + [Theory, MemberData(nameof(EchoHeadersServers))] + public Task ConnectAsync_AddCustomHeaders_Success(Uri server) + => RunClient_ConnectAsync_AddCustomHeaders_Success(server); + + [SkipOnPlatform(TestPlatforms.Browser, "Cookies not supported on browser")] + [Theory, MemberData(nameof(EchoHeadersServers))] + public Task ConnectAsync_CookieHeaders_Success(Uri server) + => RunClient_ConnectAsync_CookieHeaders_Success(server); + + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] + [Theory, MemberData(nameof(EchoServers))] + public Task ConnectAsync_PassNoSubProtocol_ServerRequires_ThrowsWebSocketException(Uri server) + => RunClient_ConnectAsync_PassNoSubProtocol_ServerRequires_ThrowsWebSocketException(server); + + [Theory, MemberData(nameof(EchoServers))] + public Task ConnectAsync_PassMultipleSubProtocols_ServerRequires_ConnectionUsesAgreedSubProtocol(Uri server) + => RunClient_ConnectAsync_PassMultipleSubProtocols_ServerRequires_ConnectionUsesAgreedSubProtocol(server); + + [SkipOnPlatform(TestPlatforms.Browser, "Proxy not supported on Browser")] + [Theory, MemberData(nameof(EchoServers))] + public Task ConnectAndCloseAsync_UseProxyServer_ExpectedClosedState(Uri server) + => RunClient_ConnectAndCloseAsync_UseProxyServer_ExpectedClosedState(server); + + #endregion + + #region External-only tests + + [ActiveIssue("https://github.com/dotnet/runtime/issues/1895")] + [Theory] + [MemberData(nameof(UnavailableWebSocketServers))] + public async Task ConnectAsync_NotWebSocketServer_ThrowsWebSocketExceptionWithMessage(Uri server, string exceptionMessage, WebSocketError errorCode) { - using (var clientSocket = new ClientWebSocket()) + using (var cws = new ClientWebSocket()) { - var cts = new CancellationTokenSource(); - cts.Cancel(); - Task t = ConnectAsync(clientSocket, new Uri($"ws://{Guid.NewGuid():N}"), cts.Token); - await Assert.ThrowsAnyAsync(() => t); + var cts = new CancellationTokenSource(TimeOutMilliseconds); + WebSocketException ex = await Assert.ThrowsAsync(() => + ConnectAsync(cws, server, cts.Token)); + + if (!PlatformDetection.IsInAppContainer) // bug fix in netcoreapp: https://github.com/dotnet/corefx/pull/35960 + { + Assert.Equal(errorCode, ex.WebSocketErrorCode); + } + Assert.Equal(WebSocketState.Closed, cws.State); + Assert.Equal(exceptionMessage, ex.Message); + + // Other operations throw after failed connect + await Assert.ThrowsAsync(() => cws.ReceiveAsync(new byte[1], default)); + await Assert.ThrowsAsync(() => cws.SendAsync(new byte[1], WebSocketMessageType.Binary, true, default)); + await Assert.ThrowsAsync(() => cws.CloseAsync(WebSocketCloseStatus.NormalClosure, null, default)); + await Assert.ThrowsAsync(() => cws.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, null, default)); } } - [ConditionalFact(nameof(WebSocketsSupported))] - public async Task ConnectAsync_CancellationRequestedInflightConnect_ThrowsOperationCanceledException() + [SkipOnPlatform(TestPlatforms.Browser, "HTTP/2 WebSockets are not supported on this platform")] + [ConditionalFact] // Uses SkipTestException + public async Task ConnectAsync_Http11Server_DowngradeFail() { - using (var clientSocket = new ClientWebSocket()) + if (UseSharedHandler) { - var cts = new CancellationTokenSource(); - Task t = ConnectAsync(clientSocket, new Uri($"ws://{Guid.NewGuid():N}"), cts.Token); - cts.Cancel(); - await Assert.ThrowsAnyAsync(() => t); + throw new SkipTestException("HTTP/2 is not supported with SharedHandler"); } - } - [ConditionalFact(nameof(WebSocketsSupported))] - public async Task ConnectAsync_CancellationRequestedAfterConnect_ThrowsOperationCanceledException() - { - var releaseServer = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - await LoopbackServer.CreateClientAndServerAsync(async uri => - { - var clientSocket = new ClientWebSocket(); - try - { - var cts = new CancellationTokenSource(); - Task t = ConnectAsync(clientSocket, uri, cts.Token); - Assert.False(t.IsCompleted); - cts.Cancel(); - await Assert.ThrowsAnyAsync(() => t); - } - finally - { - releaseServer.SetResult(); - clientSocket.Dispose(); - } - }, async server => + using (var cws = new ClientWebSocket()) + using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { - try - { - await server.AcceptConnectionAsync(async connection => - { - await releaseServer.Task; - }); - } - // Ignore IO exception on server as there are race conditions when client is cancelling. - catch (IOException) { } - }, new LoopbackServer.Options { WebSocketEndpoint = true }); + cws.Options.HttpVersion = Net.HttpVersion.Version20; + cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionExact; + + Task t = cws.ConnectAsync(Test.Common.Configuration.WebSockets.SecureRemoteEchoServer, GetInvoker(), cts.Token); + + var ex = await Assert.ThrowsAnyAsync(() => t); + Assert.True(ex.InnerException.Data.Contains("HTTP2_ENABLED")); + HttpRequestException inner = Assert.IsType(ex.InnerException); + HttpRequestError expectedError = PlatformDetection.SupportsAlpn ? + HttpRequestError.SecureConnectionError : + HttpRequestError.VersionNegotiationError; + Assert.Equal(expectedError, inner.HttpRequestError); + Assert.Equal(WebSocketState.Closed, cws.State); + } } - [ConditionalFact(nameof(WebSocketsSupported))] - [SkipOnPlatform(TestPlatforms.Browser, "CollectHttpResponseDetails not supported on Browser")] - public async Task ConnectAsync_HttpResponseDetailsCollectedOnFailure() + [SkipOnPlatform(TestPlatforms.Browser, "HTTP/2 WebSockets are not supported on this platform")] + [ConditionalTheory] // Uses SkipTestException + [MemberData(nameof(EchoServers))] + public async Task ConnectAsync_Http11Server_DowngradeSuccess(Uri server) { - await LoopbackServer.CreateClientAndServerAsync(async uri => + if (UseSharedHandler) { - using (var clientWebSocket = new ClientWebSocket()) - using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) - { - clientWebSocket.Options.CollectHttpResponseDetails = true; - Task t = ConnectAsync(clientWebSocket, uri, cts.Token); - await Assert.ThrowsAnyAsync(() => t); - - Assert.Equal(HttpStatusCode.Unauthorized, clientWebSocket.HttpStatusCode); - Assert.NotEmpty(clientWebSocket.HttpResponseHeaders); - } - }, server => server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.Unauthorized), new LoopbackServer.Options { WebSocketEndpoint = true }); - } + throw new SkipTestException("HTTP/2 is not supported with SharedHandler"); + } - [ConditionalFact(nameof(WebSocketsSupported))] - [SkipOnPlatform(TestPlatforms.Browser, "CollectHttpResponseDetails not supported on Browser")] - public async Task ConnectAsync_HttpResponseDetailsCollectedOnFailure_CustomHeader() - { - await LoopbackServer.CreateClientAndServerAsync(async uri => + using (var cws = new ClientWebSocket()) + using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { - using (var clientWebSocket = new ClientWebSocket()) - using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) - { - clientWebSocket.Options.CollectHttpResponseDetails = true; - Task t = ConnectAsync(clientWebSocket, uri, cts.Token); - await Assert.ThrowsAnyAsync(() => t); - - Assert.Equal(HttpStatusCode.Unauthorized, clientWebSocket.HttpStatusCode); - Assert.NotEmpty(clientWebSocket.HttpResponseHeaders); - Assert.Contains("X-CustomHeader1", clientWebSocket.HttpResponseHeaders); - Assert.Contains("X-CustomHeader2", clientWebSocket.HttpResponseHeaders); - Assert.NotNull(clientWebSocket.HttpResponseHeaders.Values); - } - }, server => server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.Unauthorized, "X-CustomHeader1: Value1\r\nX-CustomHeader2: Value2\r\n"), new LoopbackServer.Options { WebSocketEndpoint = true }); + cws.Options.HttpVersion = Net.HttpVersion.Version20; + cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrLower; + await cws.ConnectAsync(server, GetInvoker(), cts.Token); + Assert.Equal(WebSocketState.Open, cws.State); + } } - [ConditionalFact(nameof(WebSocketsSupported))] - [SkipOnPlatform(TestPlatforms.Browser, "CollectHttpResponseDetails not supported on Browser")] - public async Task ConnectAsync_HttpResponseDetailsCollectedOnSuccess_Extensions() + [SkipOnPlatform(TestPlatforms.Browser, "HTTP/2 WebSockets are not supported on this platform")] + [ConditionalTheory] // Uses SkipTestException + [MemberData(nameof(EchoServers))] + public async Task ConnectAsync_Http11WithRequestVersionOrHigher_DowngradeSuccess(Uri server) { - await LoopbackServer.CreateClientAndServerAsync(async uri => + if (UseSharedHandler) { - using (var clientWebSocket = new ClientWebSocket()) - using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) - { - clientWebSocket.Options.CollectHttpResponseDetails = true; - await ConnectAsync(clientWebSocket, uri, cts.Token); + throw new SkipTestException("HTTP/2 is not supported with SharedHandler"); + } - Assert.Equal(HttpStatusCode.SwitchingProtocols, clientWebSocket.HttpStatusCode); - Assert.NotEmpty(clientWebSocket.HttpResponseHeaders); - Assert.Contains("Sec-WebSocket-Extensions", clientWebSocket.HttpResponseHeaders); - } - }, server => server.AcceptConnectionAsync(async connection => + using (var cws = new ClientWebSocket()) + using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { - Dictionary headers = await LoopbackHelper.WebSocketHandshakeAsync(connection, "X-CustomHeader1"); - }), new LoopbackServer.Options { WebSocketEndpoint = true }); + cws.Options.HttpVersion = Net.HttpVersion.Version11; + cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher; + await cws.ConnectAsync(server, GetInvoker(), cts.Token); + Assert.Equal(WebSocketState.Open, cws.State); + } } + + #endregion } + +#region Runnable test classes: External/Outerloop + + public sealed class ConnectTest_SharedHandler_External(ITestOutputHelper output) : ConnectTest_External(output) { } + + public sealed class ConnectTest_Invoker_External(ITestOutputHelper output) : ConnectTest_External(output) + { + protected override bool UseCustomInvoker => true; + } + + public sealed class ConnectTest_HttpClient_External(ITestOutputHelper output) : ConnectTest_External(output) + { + protected override bool UseHttpClient => true; + } + +#endregion } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/DeflateTests.cs b/src/libraries/System.Net.WebSockets.Client/tests/DeflateTests.cs index 7c8f68ed1f5d99..9394bb0c20b27d 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/DeflateTests.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/DeflateTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Net.Http; using System.Net.Test.Common; using System.Reflection; using System.Text; @@ -14,27 +13,21 @@ namespace System.Net.WebSockets.Client.Tests { - public sealed class InvokerDeflateTests : DeflateTests - { - public InvokerDeflateTests(ITestOutputHelper output) : base(output) { } - - protected override bool UseCustomInvoker => true; - } - - public sealed class HttpClientDeflateTests : DeflateTests - { - public HttpClientDeflateTests(ITestOutputHelper output) : base(output) { } - - protected override bool UseHttpClient => true; - } + // + // Class hierarchy: + // + // - DeflateTests → file:DeflateTests.cs + // ├─ [*]DeflateTests_SharedHandler_Loopback + // ├─ [*]DeflateTests_Invoker_Loopback + // └─ [*]DeflateTests_HttpClient_Loopback + // + // --- + // `[*]` - concrete runnable test classes + // `→ file:` - file containing the class and its concrete subclasses [PlatformSpecific(~TestPlatforms.Browser)] - public class DeflateTests : ClientWebSocketTestBase + public abstract class DeflateTests(ITestOutputHelper output) : ClientWebSocketTestBase(output) { - public DeflateTests(ITestOutputHelper output) : base(output) - { - } - [ConditionalTheory(nameof(WebSocketsSupported))] [InlineData(15, true, 15, true, "permessage-deflate; client_max_window_bits")] [InlineData(14, true, 15, true, "permessage-deflate; client_max_window_bits=14")] @@ -199,4 +192,20 @@ private static string CreateDeflateOptionsHeader(WebSocketDeflateOptions options return builder.ToString(); } } + + #region Runnable test classes: HTTP/1.1 Loopback + + public sealed class DeflateTests_SharedHandler_Loopback(ITestOutputHelper output) : DeflateTests(output) { } + + public sealed class DeflateTests_Invoker_Loopback(ITestOutputHelper output) : DeflateTests(output) + { + protected override bool UseCustomInvoker => true; + } + + public sealed class DeflateTests_HttpClient_Loopback(ITestOutputHelper output) : DeflateTests(output) + { + protected override bool UseHttpClient => true; + } + + #endregion } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/KeepAliveTest.Loopback.cs b/src/libraries/System.Net.WebSockets.Client/tests/KeepAliveTest.Loopback.cs index 08306c0804ee48..767b4ddf8effae 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/KeepAliveTest.Loopback.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/KeepAliveTest.Loopback.cs @@ -1,27 +1,37 @@ // 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.Generic; -using System.Net.Test.Common; using System.Threading; using System.Threading.Tasks; -using System.Threading.Channels; using Xunit; using Xunit.Abstractions; namespace System.Net.WebSockets.Client.Tests { + // + // Class hierarchy: + // + // - KeepAliveTest_Loopback → file:KeepAliveTest.Loopback.cs + // ├─ [*]KeepAliveTest_SharedHandler_Loopback + // ├─ [*]KeepAliveTest_Invoker_Loopback + // ├─ [*]KeepAliveTest_HttpClient_Loopback + // └─ KeepAliveTest_Http2Loopback + // ├─ [*]KeepAliveTest_Invoker_Http2Loopback + // └─ [*]KeepAliveTest_HttpClient_Http2Loopback + // + // --- + // `[*]` - concrete runnable test classes + // `→ file:` - file containing the class and its concrete subclasses + [SkipOnPlatform(TestPlatforms.Browser, "KeepAlive not supported on browser")] - public abstract class KeepAliveTest_Loopback : ClientWebSocketTestBase + public abstract class KeepAliveTest_Loopback(ITestOutputHelper output) : ClientWebSocketTestBase(output) { - public KeepAliveTest_Loopback(ITestOutputHelper output) : base(output) { } - - protected virtual Version HttpVersion => Net.HttpVersion.Version11; + #region Loopback-only tests [OuterLoop("Uses Task.Delay")] [Theory] - [MemberData(nameof(UseSsl_MemberData))] + [MemberData(nameof(UseSsl))] public Task KeepAlive_LongDelayBetweenSendReceives_Succeeds(bool useSsl) { var clientMsg = new byte[] { 1, 2, 3, 4, 5, 6 }; @@ -33,21 +43,17 @@ public Task KeepAlive_LongDelayBetweenSendReceives_Succeeds(bool useSsl) var timeoutCts = new CancellationTokenSource(TimeOutMilliseconds); - var options = new LoopbackWebSocketServer.Options(HttpVersion, useSsl, GetInvoker()) - { - DisposeServerWebSocket = true, - DisposeClientWebSocket = true, - ConfigureClientOptions = clientOptions => - { - clientOptions.KeepAliveInterval = TimeSpan.FromMilliseconds(100); - clientOptions.KeepAliveTimeout = TimeSpan.FromSeconds(1); - } - }; - return LoopbackWebSocketServer.RunAsync( - async (cws, token) => + async uri => { - ReadAheadWebSocket clientWebSocket = new(cws); + var token = timeoutCts.Token; + ClientWebSocket rawCws = await GetConnectedWebSocket(uri, + o => + { + o.KeepAliveInterval = TimeSpan.FromMilliseconds(100); + o.KeepAliveTimeout = TimeSpan.FromSeconds(1); + }); + ReadAheadWebSocket clientWebSocket = new(rawCws); await VerifySendReceiveAsync(clientWebSocket, clientMsg, serverMsg, clientAckTcs, serverAckTcs.Task, token).ConfigureAwait(false); @@ -85,7 +91,7 @@ public Task KeepAlive_LongDelayBetweenSendReceives_Succeeds(bool useSsl) await serverWebSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", token).ConfigureAwait(false); Assert.Equal(WebSocketState.Closed, serverWebSocket.State); }, - options, + new LoopbackWebSocketServer.Options(HttpVersion, useSsl), timeoutCts.Token); } @@ -107,38 +113,42 @@ private static async Task VerifySendReceiveAsync(WebSocket ws, byte[] localMsg, await sendTask.ConfigureAwait(false); await remoteAck.WaitAsync(cancellationToken).ConfigureAwait(false); } + + #endregion + } + + public abstract class KeepAliveTest_Http2Loopback(ITestOutputHelper output) : KeepAliveTest_Loopback(output) + { + internal override Version HttpVersion => Net.HttpVersion.Version20; } - // --- HTTP/1.1 WebSocket loopback tests --- + #region Runnable test classes: HTTP/1.1 Loopback + + public sealed class KeepAliveTest_SharedHandler_Loopback(ITestOutputHelper output) : KeepAliveTest_Loopback(output) { } - public class KeepAliveTest_Invoker_Loopback : KeepAliveTest_Loopback + public sealed class KeepAliveTest_Invoker_Loopback(ITestOutputHelper output) : KeepAliveTest_Loopback(output) { - public KeepAliveTest_Invoker_Loopback(ITestOutputHelper output) : base(output) { } protected override bool UseCustomInvoker => true; } - public class KeepAliveTest_HttpClient_Loopback : KeepAliveTest_Loopback + public sealed class KeepAliveTest_HttpClient_Loopback(ITestOutputHelper output) : KeepAliveTest_Loopback(output) { - public KeepAliveTest_HttpClient_Loopback(ITestOutputHelper output) : base(output) { } protected override bool UseHttpClient => true; } - public class KeepAliveTest_SharedHandler_Loopback : KeepAliveTest_Loopback - { - public KeepAliveTest_SharedHandler_Loopback(ITestOutputHelper output) : base(output) { } - } + #endregion - // --- HTTP/2 WebSocket loopback tests --- + #region Runnable test classes: HTTP/2 Loopback - public class KeepAliveTest_Invoker_Http2 : KeepAliveTest_Invoker_Loopback + public sealed class KeepAliveTest_Invoker_Http2Loopback(ITestOutputHelper output) : KeepAliveTest_Http2Loopback(output) { - public KeepAliveTest_Invoker_Http2(ITestOutputHelper output) : base(output) { } - protected override Version HttpVersion => Net.HttpVersion.Version20; + protected override bool UseCustomInvoker => true; } - public class KeepAliveTest_HttpClient_Http2 : KeepAliveTest_HttpClient_Loopback + public sealed class KeepAliveTest_HttpClient_Http2Loopback(ITestOutputHelper output) : KeepAliveTest_Http2Loopback(output) { - public KeepAliveTest_HttpClient_Http2(ITestOutputHelper output) : base(output) { } - protected override Version HttpVersion => Net.HttpVersion.Version20; + protected override bool UseHttpClient => true; } + + #endregion } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/KeepAliveTest.cs b/src/libraries/System.Net.WebSockets.Client/tests/KeepAliveTest.cs index 5ff9c51e56a6af..f9bea58936cdf5 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/KeepAliveTest.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/KeepAliveTest.cs @@ -1,8 +1,6 @@ // 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.Generic; -using System.Net.Test.Common; using System.Threading; using System.Threading.Tasks; @@ -14,15 +12,13 @@ namespace System.Net.WebSockets.Client.Tests { [SkipOnPlatform(TestPlatforms.Browser, "KeepAlive not supported on browser")] - public class KeepAliveTest : ClientWebSocketTestBase + public class KeepAliveTest(ITestOutputHelper output) : ClientWebSocketTestBase(output) { - public KeepAliveTest(ITestOutputHelper output) : base(output) { } - [ConditionalFact(nameof(WebSocketsSupported))] [OuterLoop("Uses Task.Delay")] public async Task KeepAlive_LongDelayBetweenSendReceives_Succeeds() { - using (ClientWebSocket cws = await WebSocketHelper.GetConnectedWebSocket(RemoteEchoServer, TimeOutMilliseconds, _output, TimeSpan.FromSeconds(1))) + using (ClientWebSocket cws = await GetConnectedWebSocket(RemoteEchoServer, o => o.KeepAliveInterval = TimeSpan.FromSeconds(1))) { await cws.SendAsync(new ArraySegment(new byte[1] { 42 }), WebSocketMessageType.Binary, true, CancellationToken.None); @@ -42,10 +38,8 @@ public async Task KeepAlive_LongDelayBetweenSendReceives_Succeeds() [InlineData(1, 2)] // ping/pong public async Task KeepAlive_LongDelayBetweenReceiveSends_Succeeds(int keepAliveIntervalSec, int keepAliveTimeoutSec) { - using (ClientWebSocket cws = await WebSocketHelper.GetConnectedWebSocket( + using (ClientWebSocket cws = await GetConnectedWebSocket( RemoteEchoServer, - TimeOutMilliseconds, - _output, options => { options.KeepAliveInterval = TimeSpan.FromSeconds(keepAliveIntervalSec); diff --git a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackHelper.cs b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackHelper.cs index cee509ee068467..8632a07236d011 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackHelper.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackHelper.cs @@ -43,7 +43,7 @@ public static async Task> WebSocketHandshakeAsync(Loo return null; } - public static string GetServerResponseString(string secWebSocketKey, string? extensions = null) + public static string GetServerResponseString(string secWebSocketKey, string? extensions = null, string? subProtocol = null) { var responseSecurityAcceptValue = ComputeWebSocketHandshakeSecurityAcceptValue(secWebSocketKey); return @@ -52,6 +52,7 @@ public static string GetServerResponseString(string secWebSocketKey, string? ext "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + (extensions is null ? null : $"Sec-WebSocket-Extensions: {extensions}\r\n") + + (subProtocol is null ? null : $"Sec-WebSocket-Protocol: {subProtocol}\r\n") + "Sec-WebSocket-Accept: " + responseSecurityAcceptValue + "\r\n\r\n"; } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.Echo.cs b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.Echo.cs new file mode 100644 index 00000000000000..d20e70cf1b8055 --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.Echo.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. + +using System.Net.Test.Common; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Net.WebSockets.Client.Tests +{ + public static partial class LoopbackWebSocketServer + { + public static Task RunEchoAsync(Func loopbackClientFunc, Options options, CancellationToken cancellationToken) + { + Assert.True(options.IgnoreServerErrors); + Assert.True(options.AbortServerOnClientExit); + + return RunAsync( + loopbackClientFunc, + (data, token) => RunEchoServerWebSocketAsync(data, options, token), + options, + cancellationToken); + } + + private static async Task RunEchoServerWebSocketAsync(WebSocketRequestData data, Options options, CancellationToken cancellationToken) + { + WebSocketEchoOptions echoOptions = data.EchoOptions ?? WebSocketEchoOptions.Default; + + if (echoOptions.SubProtocol is not null) + { + Assert.True(options.SkipServerHandshakeResponse, "SkipServerHandshakeResponse must be true to negotiate subprotocols"); + Assert.Null(options.ServerSubProtocol); + options = options with { ServerSubProtocol = echoOptions.SubProtocol }; + } + + if (options.SkipServerHandshakeResponse) + { + await SendNegotiatedServerResponseAsync(data, options, cancellationToken).ConfigureAwait(false); + } + + await RunServerWebSocketAsync( + data, + (serverWebSocket, token) => WebSocketEchoHelper.RunEchoAll( + serverWebSocket, + echoOptions.ReplyWithPartialMessages, + echoOptions.ReplyWithEnhancedCloseMessage, + token), + options, + cancellationToken).ConfigureAwait(false); + } + } +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.Http.cs b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.Http.cs new file mode 100644 index 00000000000000..42a2d5fbc7e33a --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.Http.cs @@ -0,0 +1,189 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO; +using System.Net.Sockets; +using System.Net.Test.Common; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Net.WebSockets.Client.Tests +{ + public static partial class LoopbackWebSocketServer + { + abstract class HttpRunner + { + protected abstract LoopbackServerFactory ServerFactory { get; } + protected abstract GenericLoopbackOptions CreateOptions(bool useSsl); + + public async Task RunAsync( + Func clientFunc, + Func wsServerFunc, + Options options, + CancellationToken clientExitCt, + CancellationToken globalCt) + { + using (var server = ServerFactory.CreateServer(CreateOptions(options.UseSsl))) + { + Task clientTask = clientFunc(server.Address); + Task serverTask = ProcessWebSocketRequest(server, wsServerFunc, options, clientExitCt, globalCt); + + await new Task[] { clientTask, serverTask }.WhenAllOrAnyFailed(LoopbackServerFactory.LoopbackServerTimeoutMilliseconds); + } + } + + private async Task ProcessWebSocketRequest( + GenericLoopbackServer httpServer, + Func wsServerFunc, + Options options, + CancellationToken clientExitCt, + CancellationToken globalCt) + { + try + { + using CancellationTokenSource linkedCts = + CancellationTokenSource.CreateLinkedTokenSource(globalCt, clientExitCt); + await ProcessWebSocketRequestCore(httpServer, wsServerFunc, options, linkedCts.Token); + } + catch (Exception e) when (options.IgnoreServerErrors) + { + if (e is OperationCanceledException && clientExitCt.IsCancellationRequested) + { + return; // expected + } + + if (e is WebSocketException or IOException or SocketException) + { + return; // ignore + } + + throw; // don't swallow Assert failures and unexpected exceptions + } + } + + protected abstract Task ProcessWebSocketRequestCore( + GenericLoopbackServer httpServer, + Func loopbackServerFunc, + Options options, + CancellationToken cancellationToken); + } + + class Http11Runner : HttpRunner + { + public static HttpRunner Singleton { get; } = new Http11Runner(); + protected override LoopbackServerFactory ServerFactory => Http11LoopbackServerFactory.Singleton; + + protected override GenericLoopbackOptions CreateOptions(bool useSsl) => new LoopbackServer.Options + { + UseSsl = useSsl, + WebSocketEndpoint = true + }; + + protected override Task ProcessWebSocketRequestCore(GenericLoopbackServer s, Func func, Options o, CancellationToken ct) + => ProcessHttp11WebSocketRequest((LoopbackServer)s, func, o, ct); + } + + class Http2Runner : HttpRunner + { + public static HttpRunner Singleton { get; } = new Http2Runner(); + protected override LoopbackServerFactory ServerFactory => Http2LoopbackServerFactory.Singleton; + + protected override GenericLoopbackOptions CreateOptions(bool useSsl) => new Http2Options + { + UseSsl = useSsl, + WebSocketEndpoint = true, + EnsureThreadSafeIO = true + }; + + protected override Task ProcessWebSocketRequestCore(GenericLoopbackServer s, Func func, Options o, CancellationToken ct) + => ProcessHttp2WebSocketRequest((Http2LoopbackServer)s, func, o, ct); + } + + private static Task ProcessHttp11WebSocketRequest( + LoopbackServer http11server, + Func loopbackServerFunc, + Options options, + CancellationToken cancellationToken) + => http11server.AcceptConnectionAsync( + async connection => + { + var requestData = await WebSocketHandshakeHelper.ProcessHttp11RequestAsync( + connection, + options.SkipServerHandshakeResponse, + options.ParseEchoOptions, + cancellationToken).ConfigureAwait(false); + + await loopbackServerFunc(requestData, cancellationToken).ConfigureAwait(false); + }); + + private static async Task ProcessHttp2WebSocketRequest( + Http2LoopbackServer http2Server, + Func loopbackServerFunc, + Options options, + CancellationToken cancellationToken) + { + var requestData = await WebSocketHandshakeHelper.ProcessHttp2RequestAsync( + http2Server, + options.SkipServerHandshakeResponse, + options.ParseEchoOptions, + cancellationToken).ConfigureAwait(false); + + await loopbackServerFunc(requestData, cancellationToken).ConfigureAwait(false); + var http2Connection = requestData.Http2Connection!; + + if (options.AbortServerOnClientExit) // we need to wait for the client to disconnect + { + // Due to the way Extended CONNECT is implemented, we might receive both EOS and RST_STREAM frames, + // so we might need to drain more than 1 frame before shutting down the connection + while (true) + { + var frame = await http2Connection.ReadFrameAsync(cancellationToken).ConfigureAwait(false); + if (frame is null) + { + // No more frames to read + break; + } + + if (!options.IgnoreServerErrors) + { + Assert.False(frame.Type == FrameType.Data && !((DataFrame)frame).EndStreamFlag, $"Unexpected DATA frame: {frame}"); + } + } + + await http2Connection.WaitForConnectionShutdownAsync(options.IgnoreServerErrors).ConfigureAwait(false); + } + else + { + await http2Connection.ShutdownIgnoringErrorsAsync(requestData.Http2StreamId.Value).ConfigureAwait(false); + } + } + + private static Task SendNegotiatedServerResponseAsync(WebSocketRequestData data, Options options, CancellationToken cancellationToken) + { + Assert.True(options.SkipServerHandshakeResponse); + + if (data.HttpVersion == HttpVersion.Version11) + { + return WebSocketHandshakeHelper.SendHttp11ServerResponseAsync( + data.Http11Connection!, + data.Headers["Sec-WebSocket-Key"], + options.ServerSubProtocol, + options.ServerExtensions, + cancellationToken); + } + + if (data.HttpVersion == HttpVersion.Version20) + { + return WebSocketHandshakeHelper.SendHttp2ServerResponseAsync( + data.Http2Connection!, + data.Http2StreamId!.Value, + options.ServerSubProtocol, + options.ServerExtensions, + cancellationToken: cancellationToken); + } + + throw new NotSupportedException($"HTTP version {data.HttpVersion} is not supported."); + } + } +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.cs b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.cs index ec530201848025..a7384616cfbd51 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/LoopbackWebSocketServer.cs @@ -1,151 +1,90 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Net.Http; -using System.Net.Test.Common; using System.Threading; using System.Threading.Tasks; -using Xunit; namespace System.Net.WebSockets.Client.Tests { - public static class LoopbackWebSocketServer + public static partial class LoopbackWebSocketServer { public static Task RunAsync( - Func clientWebSocketFunc, - Func serverWebSocketFunc, + Func runClient, + Func runServer, Options options, CancellationToken cancellationToken) - { - Assert.False(options.ManualServerHandshakeResponse, "Not supported in this overload"); - - return RunAsyncPrivate( - uri => RunClientAsync(uri, clientWebSocketFunc, options, cancellationToken), - (requestData, token) => RunServerAsync(requestData, serverWebSocketFunc, options, token), - options, - cancellationToken); - } + => RunAsync( + runClient, + (rd, ct) => RunServerWebSocketAsync(rd, runServer, options, ct), + options, + cancellationToken); public static Task RunAsync( - Func loopbackClientFunc, - Func loopbackServerFunc, + Func runClient, + Func runServer, Options options, CancellationToken cancellationToken) { - Assert.False(options.DisposeClientWebSocket, "Not supported in this overload"); - Assert.False(options.DisposeServerWebSocket, "Not supported in this overload"); - Assert.False(options.DisposeHttpInvoker, "Not supported in this overload"); - Assert.Null(options.HttpInvoker); // Not supported in this overload - - return RunAsyncPrivate(loopbackClientFunc, loopbackServerFunc, options, cancellationToken); - } + CancellationToken clientExitCt = CancellationToken.None; - private static Task RunAsyncPrivate( - Func loopbackClientFunc, - Func loopbackServerFunc, - Options options, - CancellationToken cancellationToken) - { - bool sendDefaultServerHandshakeResponse = !options.ManualServerHandshakeResponse; - if (options.HttpVersion == HttpVersion.Version11) + if (options.AbortServerOnClientExit) { - return LoopbackServer.CreateClientAndServerAsync( - loopbackClientFunc, - async server => + CancellationTokenSource clientExitCts = new CancellationTokenSource(); + clientExitCt = clientExitCts.Token; + + var runClientCore = runClient; + runClient = async uri => + { + try { - await server.AcceptConnectionAsync(async connection => - { - var requestData = await WebSocketHandshakeHelper.ProcessHttp11RequestAsync(connection, sendDefaultServerHandshakeResponse, cancellationToken).ConfigureAwait(false); - await loopbackServerFunc(requestData, cancellationToken).ConfigureAwait(false); - }); - }, - new LoopbackServer.Options { WebSocketEndpoint = true, UseSsl = options.UseSsl }); - } - else if (options.HttpVersion == HttpVersion.Version20) - { - return Http2LoopbackServer.CreateClientAndServerAsync( - loopbackClientFunc, - async server => + await runClientCore(uri); + } + finally { - var requestData = await WebSocketHandshakeHelper.ProcessHttp2RequestAsync(server, sendDefaultServerHandshakeResponse, cancellationToken).ConfigureAwait(false); - var http2Connection = requestData.Http2Connection!; - var http2StreamId = requestData.Http2StreamId.Value; - - await loopbackServerFunc(requestData, cancellationToken).ConfigureAwait(false); - - await http2Connection.ShutdownIgnoringErrorsAsync(http2StreamId).ConfigureAwait(false); - }, - new Http2Options { WebSocketEndpoint = true, UseSsl = options.UseSsl }); + clientExitCts.Cancel(); + } + }; } - else + + var httpRunner = options.HttpVersion.Major switch { - throw new ArgumentException(nameof(options.HttpVersion)); - } + 1 => Http11Runner.Singleton, + 2 => Http2Runner.Singleton, + _ => throw new NotSupportedException($"HTTP version {options.HttpVersion} is not supported.") + }; + + return httpRunner.RunAsync(runClient, runServer, options, clientExitCt, cancellationToken); } - private static async Task RunServerAsync( + private static async Task RunServerWebSocketAsync( WebSocketRequestData requestData, Func serverWebSocketFunc, Options options, CancellationToken cancellationToken) { - var wsOptions = new WebSocketCreationOptions { IsServer = true }; - var serverWebSocket = WebSocket.CreateFromStream(requestData.WebSocketStream, wsOptions); - - await serverWebSocketFunc(serverWebSocket, cancellationToken).ConfigureAwait(false); - - if (options.DisposeServerWebSocket) - { - serverWebSocket.Dispose(); - } - } - - private static async Task RunClientAsync( - Uri uri, - Func clientWebSocketFunc, - Options options, - CancellationToken cancellationToken) - { - var clientWebSocket = await GetConnectedClientAsync(uri, options, cancellationToken).ConfigureAwait(false); - - await clientWebSocketFunc(clientWebSocket, cancellationToken).ConfigureAwait(false); - - if (options.DisposeClientWebSocket) - { - clientWebSocket.Dispose(); - } + var wsOptions = new WebSocketCreationOptions { IsServer = true, SubProtocol = options.ServerSubProtocol }; - if (options.DisposeHttpInvoker) + var serverWebSocket = WebSocket.CreateFromStream(requestData.TransportStream, wsOptions); + using (var registration = cancellationToken.Register(serverWebSocket.Abort)) { - options.HttpInvoker?.Dispose(); + await serverWebSocketFunc(serverWebSocket, cancellationToken).ConfigureAwait(false); } - } - - public static async Task GetConnectedClientAsync(Uri uri, Options options, CancellationToken cancellationToken) - { - var clientWebSocket = new ClientWebSocket(); - clientWebSocket.Options.HttpVersion = options.HttpVersion; - clientWebSocket.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionExact; - if (options.UseSsl && options.HttpInvoker is null) + if (options.DisposeServerWebSocket) { - clientWebSocket.Options.RemoteCertificateValidationCallback = delegate { return true; }; + serverWebSocket.Dispose(); } - - options.ConfigureClientOptions?.Invoke(clientWebSocket.Options); - - await clientWebSocket.ConnectAsync(uri, options.HttpInvoker, cancellationToken).ConfigureAwait(false); - - return clientWebSocket; } - public record class Options(Version HttpVersion, bool UseSsl, HttpMessageInvoker? HttpInvoker) + public record class Options(Version HttpVersion, bool UseSsl) { - public bool DisposeServerWebSocket { get; set; } = true; - public bool DisposeClientWebSocket { get; set; } - public bool DisposeHttpInvoker { get; set; } - public bool ManualServerHandshakeResponse { get; set; } - public Action? ConfigureClientOptions { get; set; } + public bool DisposeServerWebSocket { get; set; } + public bool SkipServerHandshakeResponse { get; set; } + public bool ParseEchoOptions { get; set; } + public bool IgnoreServerErrors { get; set; } + public bool AbortServerOnClientExit { get; set; } + public string? ServerSubProtocol { get; set; } + public string? ServerExtensions { get; set; } } } } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketHandshakeHelper.cs b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketHandshakeHelper.cs index 06e62d4a17e48f..e97d2feaf6f3b3 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketHandshakeHelper.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketHandshakeHelper.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Linq; using System.Net.Http; using System.Net.Sockets; using System.Net.Test.Common; @@ -14,7 +13,11 @@ namespace System.Net.WebSockets.Client.Tests { public static class WebSocketHandshakeHelper { - public static async Task ProcessHttp11RequestAsync(LoopbackServer.Connection connection, bool sendServerResponse = true, CancellationToken cancellationToken = default) + public static async Task ProcessHttp11RequestAsync( + LoopbackServer.Connection connection, + bool skipServerHandshakeResponse = false, + bool parseEchoOptions = false, + CancellationToken cancellationToken = default) { List headers = await connection.ReadRequestHeaderAsync().WaitAsync(cancellationToken).ConfigureAwait(false); @@ -24,9 +27,30 @@ public static async Task ProcessHttp11RequestAsync(Loopbac Http11Connection = connection }; - foreach (string header in headers.Skip(1)) + if (parseEchoOptions) { - string[] tokens = header.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries); + // extract query with leading '?' from request line + // e.g. GET /echo?query=string HTTP/1.1 => "?query=string" + int queryIndex = headers[0].IndexOf('?'); + if (queryIndex != -1) + { + int spaceIndex = headers[0].IndexOf(' ', queryIndex); + string query = headers[0].Substring(queryIndex, spaceIndex - queryIndex); + + // NOTE: ProcessOptions needs to be called before sending the server response + // because it may be configured to delay the response. + + data.EchoOptions = await WebSocketEchoHelper.ProcessOptions(query, cancellationToken).ConfigureAwait(false); + } + else + { + data.EchoOptions = WebSocketEchoOptions.Default; + } + } + + for (int i = 1; i < headers.Count; ++i) + { + string[] tokens = headers[i].Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (tokens.Length is 1 or 2) { data.Headers.Add( @@ -38,22 +62,39 @@ public static async Task ProcessHttp11RequestAsync(Loopbac var isValidOpeningHandshake = data.Headers.TryGetValue("Sec-WebSocket-Key", out var secWebSocketKey); Assert.True(isValidOpeningHandshake); - if (sendServerResponse) + if (!skipServerHandshakeResponse) { - await SendHttp11ServerResponseAsync(connection, secWebSocketKey, cancellationToken).ConfigureAwait(false); + foreach (string headerName in new[] { "Sec-WebSocket-Extensions", "Sec-WebSocket-Protocol" }) + { + if (data.Headers.TryGetValue(headerName, out var headerValue)) + { + Assert.Fail($"Header `{headerName}: {headerValue}` requires a custom server response, use skipServerHandshakeResponse=true"); + } + } + + await SendHttp11ServerResponseAsync(connection, secWebSocketKey, cancellationToken: cancellationToken).ConfigureAwait(false); } - data.WebSocketStream = connection.Stream; + data.TransportStream = connection.Stream; return data; } - private static async Task SendHttp11ServerResponseAsync(LoopbackServer.Connection connection, string secWebSocketKey, CancellationToken cancellationToken) + public static async Task SendHttp11ServerResponseAsync( + LoopbackServer.Connection connection, + string secWebSocketKey, + string? negotiatedSubProtocol = null, + string? negotiatedExtensions = null, + CancellationToken cancellationToken = default) { - var serverResponse = LoopbackHelper.GetServerResponseString(secWebSocketKey); + var serverResponse = LoopbackHelper.GetServerResponseString(secWebSocketKey, negotiatedExtensions, negotiatedSubProtocol); await connection.WriteStringAsync(serverResponse).WaitAsync(cancellationToken).ConfigureAwait(false); } - public static async Task ProcessHttp2RequestAsync(Http2LoopbackServer server, bool sendServerResponse = true, CancellationToken cancellationToken = default) + public static async Task ProcessHttp2RequestAsync( + Http2LoopbackServer server, + bool skipServerHandshakeResponse = false, + bool parseEchoOptions = false, + CancellationToken cancellationToken = default) { var connection = await server.EstablishConnectionAsync(new SettingsEntry { SettingId = SettingId.EnableConnect, Value = 1 }) .WaitAsync(cancellationToken).ConfigureAwait(false); @@ -78,21 +119,65 @@ public static async Task ProcessHttp2RequestAsync(Http2Loo var isValidOpeningHandshake = httpRequestData.Method == HttpMethod.Connect.ToString() && data.Headers.ContainsKey(":protocol"); Assert.True(isValidOpeningHandshake); - if (sendServerResponse) + if (parseEchoOptions) + { + // RFC 7540, section 8.3. The CONNECT Method: + // > The ":scheme" and ":path" pseudo-header fields MUST be omitted. + // + // HTTP/2 CONNECT requests must drop query (containing echo options) from the request URI. + // The information needs to be passed in a different way, e.g. in a custom header. + + if (data.Headers.TryGetValue(WebSocketHelper.OriginalQueryStringHeader, out var query)) + { + // NOTE: ProcessOptions needs to be called before sending the server response + // because it may be configured to delay the response. + data.EchoOptions = await WebSocketEchoHelper.ProcessOptions(query, cancellationToken).ConfigureAwait(false); + } + else + { + data.EchoOptions = WebSocketEchoOptions.Default; + } + } + + if (!skipServerHandshakeResponse) { + foreach (string headerName in new[] { "Sec-WebSocket-Extensions", "Sec-WebSocket-Protocol" }) + { + if (data.Headers.TryGetValue(headerName, out var headerValue)) + { + Assert.Fail($"Header `{headerName}: {headerValue}` requires a custom server response, use skipServerHandshakeResponse=true"); + } + } + await SendHttp2ServerResponseAsync(connection, streamId, cancellationToken: cancellationToken).ConfigureAwait(false); } - data.WebSocketStream = new Http2LoopbackStream(connection, streamId, sendResetOnDispose: false); + data.TransportStream = new Http2LoopbackStream(connection, streamId, sendResetOnDispose: false); return data; } - private static async Task SendHttp2ServerResponseAsync(Http2LoopbackConnection connection, int streamId, bool endStream = false, CancellationToken cancellationToken = default) + public static async Task SendHttp2ServerResponseAsync( + Http2LoopbackConnection connection, + int streamId, + string? negotiatedSubProtocol = null, + string? negotiatedExtensions = null, + bool endStream = false, + CancellationToken cancellationToken = default) { + var negotiatedValues = new List(); + if (negotiatedExtensions is not null) + { + negotiatedValues.Add(new HttpHeaderData("Sec-WebSocket-Extensions", negotiatedExtensions)); + } + if (negotiatedSubProtocol is not null) + { + negotiatedValues.Add(new HttpHeaderData("Sec-WebSocket-Protocol", negotiatedSubProtocol)); + } + // send status 200 OK to establish websocket - // we don't need to send anything additional as Sec-WebSocket-Key is not used for HTTP/2 + // we don't need to send Sec-WebSocket-Accept as Sec-WebSocket-Key is not used for HTTP/2 // note: endStream=true is abnormal and used for testing premature EOS scenarios only - await connection.SendResponseHeadersAsync(streamId, endStream: endStream).WaitAsync(cancellationToken).ConfigureAwait(false); + await connection.SendResponseHeadersAsync(streamId, endStream: endStream, headers: negotiatedValues).WaitAsync(cancellationToken).ConfigureAwait(false); } public static async Task SendHttp11ServerResponseAndEosAsync(WebSocketRequestData requestData, Func? requestDataCallback, CancellationToken cancellationToken) @@ -100,7 +185,7 @@ public static async Task SendHttp11ServerResponseAndEosAsync(WebSocketRequestDat Assert.Equal(HttpVersion.Version11, requestData.HttpVersion); // sending default handshake response - await SendHttp11ServerResponseAsync(requestData.Http11Connection!, requestData.Headers["Sec-WebSocket-Key"], cancellationToken).ConfigureAwait(false); + await SendHttp11ServerResponseAsync(requestData.Http11Connection!, requestData.Headers["Sec-WebSocket-Key"], cancellationToken: cancellationToken).ConfigureAwait(false); if (requestDataCallback is not null) { @@ -118,7 +203,7 @@ public static async Task SendHttp2ServerResponseAndEosAsync(WebSocketRequestData var connection = requestData.Http2Connection!; var streamId = requestData.Http2StreamId!.Value; - await SendHttp2ServerResponseAsync(connection, streamId, endStream: eosInHeadersFrame, cancellationToken).ConfigureAwait(false); + await SendHttp2ServerResponseAsync(connection, streamId, endStream: eosInHeadersFrame, cancellationToken: cancellationToken).ConfigureAwait(false); if (requestDataCallback is not null) { diff --git a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketRequestData.cs b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketRequestData.cs index 799157a370f073..190f7af2682e2f 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketRequestData.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/LoopbackServer/WebSocketRequestData.cs @@ -9,8 +9,10 @@ namespace System.Net.WebSockets.Client.Tests { public class WebSocketRequestData { - public Dictionary Headers { get; set; } = new Dictionary(); - public Stream? WebSocketStream { get; set; } + public Dictionary Headers { get; set; } = new Dictionary(StringComparer.OrdinalIgnoreCase); + public WebSocketEchoOptions? EchoOptions { get; set; } + + public Stream? TransportStream { get; set; } public Version HttpVersion { get; set; } public LoopbackServer.Connection? Http11Connection { get; set; } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ResourceHelper.cs b/src/libraries/System.Net.WebSockets.Client/tests/ResourceHelper.cs index 67eb753f475410..fbaba8fa6a57ec 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/ResourceHelper.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/ResourceHelper.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Linq; using System.Reflection; diff --git a/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.Http2.cs b/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.Http2.cs index ef21a36e44fa8f..cefdb72ccdd52a 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.Http2.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.Http2.cs @@ -8,30 +8,14 @@ using System.Threading.Tasks; using Xunit; -using Xunit.Abstractions; namespace System.Net.WebSockets.Client.Tests { - public sealed class HttpClientSendReceiveTest_Http2 : SendReceiveTest_Http2 + public abstract partial class SendReceiveTest_Http2Loopback { - public HttpClientSendReceiveTest_Http2(ITestOutputHelper output) : base(output) { } - - protected override bool UseHttpClient => true; - } - - public sealed class InvokerSendReceiveTest_Http2 : SendReceiveTest_Http2 - { - public InvokerSendReceiveTest_Http2(ITestOutputHelper output) : base(output) { } - - protected override bool UseCustomInvoker => true; - } - - public abstract class SendReceiveTest_Http2 : ClientWebSocketTestBase - { - public SendReceiveTest_Http2(ITestOutputHelper output) : base(output) { } + #region HTTP/2-only loopback tests [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "System.Net.Sockets is not supported on this platform")] public async Task ReceiveNoThrowAfterSend_NoSsl() { var serverMessage = new byte[] { 4, 5, 6 }; @@ -40,7 +24,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => using (var cws = new ClientWebSocket()) using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { - cws.Options.HttpVersion = HttpVersion.Version20; + cws.Options.HttpVersion = Net.HttpVersion.Version20; cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionExact; await cws.ConnectAsync(uri, GetInvoker(), cts.Token); @@ -69,7 +53,6 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => } [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "Self-signed certificates are not supported on browser")] public async Task ReceiveNoThrowAfterSend_WithSsl() { var serverMessage = new byte[] { 4, 5, 6 }; @@ -78,7 +61,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => using (var cws = new ClientWebSocket()) using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { - cws.Options.HttpVersion = HttpVersion.Version20; + cws.Options.HttpVersion = Net.HttpVersion.Version20; cws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionExact; await cws.ConnectAsync(uri, GetInvoker(), cts.Token); @@ -105,5 +88,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri => }, new Http2Options() { WebSocketEndpoint = true }); } + + #endregion } } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.Loopback.cs b/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.Loopback.cs new file mode 100644 index 00000000000000..f54a4202d099d1 --- /dev/null +++ b/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.Loopback.cs @@ -0,0 +1,174 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Net.Sockets; +using System.Net.Test.Common; +using System.Threading; +using System.Threading.Tasks; + +using Xunit; +using Xunit.Abstractions; + +namespace System.Net.WebSockets.Client.Tests +{ + + [ConditionalClass(typeof(ClientWebSocketTestBase), nameof(WebSocketsSupported))] + [SkipOnPlatform(TestPlatforms.Browser, "System.Net.Sockets are not supported on browser")] + public abstract class SendReceiveTest_LoopbackBase(ITestOutputHelper output) : SendReceiveTestBase(output) + { + #region Common (Echo Server) tests + + [Theory, MemberData(nameof(UseSslAndSendReceiveType))] + public Task SendReceive_PartialMessageDueToSmallReceiveBuffer_Success(bool useSsl, SendReceiveType type) => RunEchoAsync( + server => RunSendReceive(RunClient_SendReceive_PartialMessageDueToSmallReceiveBuffer_Success, server, type), useSsl); + + [ConditionalTheory, MemberData(nameof(UseSslAndSendReceiveType))] // Uses SkipTestException + public Task SendReceive_PartialMessageBeforeCompleteMessageArrives_Success(bool useSsl, SendReceiveType type) => RunEchoAsync( + server => RunSendReceive(RunClient_SendReceive_PartialMessageBeforeCompleteMessageArrives_Success, server, type), useSsl); + + [Theory, MemberData(nameof(UseSslAndSendReceiveType))] + public Task SendAsync_SendCloseMessageType_ThrowsArgumentExceptionWithMessage(bool useSsl, SendReceiveType type) => RunEchoAsync( + server => RunSendReceive(RunClient_SendAsync_SendCloseMessageType_ThrowsArgumentExceptionWithMessage, server, type), useSsl); + + [Theory, MemberData(nameof(UseSslAndSendReceiveType))] + public Task SendAsync_MultipleOutstandingSendOperations_Throws(bool useSsl, SendReceiveType type) => RunEchoAsync( + server => RunSendReceive(RunClient_SendAsync_MultipleOutstandingSendOperations_Throws, server, type), useSsl); + + [Theory, MemberData(nameof(UseSslAndSendReceiveType))] + public Task ReceiveAsync_MultipleOutstandingReceiveOperations_Throws(bool useSsl, SendReceiveType type) => RunEchoAsync( + server => RunSendReceive(RunClient_ReceiveAsync_MultipleOutstandingReceiveOperations_Throws, server, type), useSsl); + + [Theory, MemberData(nameof(UseSslAndSendReceiveType))] + public Task SendAsync_SendZeroLengthPayloadAsEndOfMessage_Success(bool useSsl, SendReceiveType type) => RunEchoAsync( + server => RunSendReceive(RunClient_SendAsync_SendZeroLengthPayloadAsEndOfMessage_Success, server, type), useSsl); + + [ConditionalTheory, MemberData(nameof(UseSslAndSendReceiveType))] // Uses SkipTestException + public Task SendReceive_VaryingLengthBuffers_Success(bool useSsl, SendReceiveType type) => RunEchoAsync( + server => RunSendReceive(RunClient_SendReceive_VaryingLengthBuffers_Success, server, type), useSsl); + + [Theory, MemberData(nameof(UseSslAndSendReceiveType))] + public Task SendReceive_Concurrent_Success(bool useSsl, SendReceiveType type) => RunEchoAsync( + server => RunSendReceive(RunClient_SendReceive_Concurrent_Success, server, type), useSsl); + + [Theory, MemberData(nameof(UseSslAndSendReceiveType))] + public Task ZeroByteReceive_CompletesWhenDataAvailable(bool useSsl, SendReceiveType type) => RunEchoAsync( + server => RunSendReceive(RunClient_ZeroByteReceive_CompletesWhenDataAvailable, server, type), useSsl); + + #endregion + } + + public abstract class SendReceiveTest_Loopback(ITestOutputHelper output) : SendReceiveTest_LoopbackBase(output) + { + #region HTTP/1.1-only loopback tests + + [Theory, MemberData(nameof(SendReceiveTypes))] + public Task SendReceive_ConnectionClosedPrematurely_ReceiveAsyncFailsAndWebSocketStateUpdated(SendReceiveType type) => RunSendReceive( + RunClient_SendReceive_ConnectionClosedPrematurely_ReceiveAsyncFailsAndWebSocketStateUpdated, type); + + private async Task RunClient_SendReceive_ConnectionClosedPrematurely_ReceiveAsyncFailsAndWebSocketStateUpdated() + { + var options = new LoopbackServer.Options { WebSocketEndpoint = true }; + + Func connectToServerThatAbortsConnection = async (clientSocket, server, url) => + { + var pendingReceiveAsyncPosted = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + // Start listening for incoming connections on the server side. + Task acceptTask = server.AcceptConnectionAsync(async connection => + { + // Complete the WebSocket upgrade. After this is done, the client-side ConnectAsync should complete. + Assert.NotNull(await LoopbackHelper.WebSocketHandshakeAsync(connection)); + + // Wait for client-side ConnectAsync to complete and for a pending ReceiveAsync to be posted. + await pendingReceiveAsyncPosted.Task.WaitAsync(TimeSpan.FromMilliseconds(TimeOutMilliseconds)); + + // Close the underlying connection prematurely (without sending a WebSocket Close frame). + connection.Socket.Shutdown(SocketShutdown.Both); + connection.Socket.Close(); + }); + + // Initiate a connection attempt. + var cts = new CancellationTokenSource(TimeOutMilliseconds); + await ConnectAsync(clientSocket, url, cts.Token); + + // Post a pending ReceiveAsync before the TCP connection is torn down. + var recvBuffer = new byte[100]; + var recvSegment = new ArraySegment(recvBuffer); + Task pendingReceiveAsync = ReceiveAsync(clientSocket, recvSegment, cts.Token); + pendingReceiveAsyncPosted.SetResult(); + + // Wait for the server to close the underlying connection. + await acceptTask.WaitAsync(cts.Token); + + WebSocketException pendingReceiveException = await Assert.ThrowsAsync(() => pendingReceiveAsync); + + Assert.Equal(WebSocketError.ConnectionClosedPrematurely, pendingReceiveException.WebSocketErrorCode); + + if (PlatformDetection.IsInAppContainer) + { + const uint WININET_E_CONNECTION_ABORTED = 0x80072EFE; + + Assert.NotNull(pendingReceiveException.InnerException); + Assert.Equal(WININET_E_CONNECTION_ABORTED, (uint)pendingReceiveException.InnerException.HResult); + } + + WebSocketException newReceiveException = + await Assert.ThrowsAsync(() => ReceiveAsync(clientSocket, recvSegment, cts.Token)); + + Assert.Equal( + ResourceHelper.GetExceptionMessage("net_WebSockets_InvalidState", "Aborted", "Open, CloseSent"), + newReceiveException.Message); + + Assert.Equal(WebSocketState.Aborted, clientSocket.State); + Assert.Null(clientSocket.CloseStatus); + }; + + await LoopbackServer.CreateServerAsync(async (server, url) => + { + using (ClientWebSocket clientSocket = new ClientWebSocket()) + { + await connectToServerThatAbortsConnection(clientSocket, server, url); + } + }, options); + } + + #endregion + } + + public abstract partial class SendReceiveTest_Http2Loopback(ITestOutputHelper output) : SendReceiveTest_LoopbackBase(output) + { + internal override Version HttpVersion => Net.HttpVersion.Version20; + + // #region HTTP/2-only loopback tests -> extracted to SendReceiveTest.Http2.cs + } + + #region Runnable test classes: HTTP/1.1 Loopback + + public sealed class SendReceiveTest_SharedHandler_Loopback(ITestOutputHelper output) : SendReceiveTest_Loopback(output) { } + + public sealed class SendReceiveTest_Invoker_Loopback(ITestOutputHelper output) : SendReceiveTest_Loopback(output) + { + protected override bool UseCustomInvoker => true; + } + + public sealed class SendReceiveTest_HttpClient_Loopback(ITestOutputHelper output) : SendReceiveTest_Loopback(output) + { + protected override bool UseHttpClient => true; + } + + #endregion + + #region Runnable test classes: HTTP/2 Loopback + + public sealed class SendReceiveTest_Invoker_Http2Loopback(ITestOutputHelper output) : SendReceiveTest_Http2Loopback(output) + { + protected override bool UseCustomInvoker => true; + } + + public sealed class SendReceiveTest_HttpClient_Http2Loopback(ITestOutputHelper output) : SendReceiveTest_Http2Loopback(output) + { + protected override bool UseHttpClient => true; + } + + #endregion +} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.cs b/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.cs index 357dcb0945d665..f74e1efc848f48 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.cs @@ -1,87 +1,96 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Net.Http; -using System.Net.Sockets; -using System.Net.Test.Common; using System.Threading; using System.Threading.Tasks; - +using Microsoft.DotNet.XUnitExtensions; using Xunit; using Xunit.Abstractions; +using EchoControlMessage = System.Net.Test.Common.WebSocketEchoHelper.EchoControlMessage; +using EchoQueryKey = System.Net.Test.Common.WebSocketEchoOptions.EchoQueryKey; + namespace System.Net.WebSockets.Client.Tests { - - public sealed class InvokerMemorySendReceiveTest : MemorySendReceiveTest + // + // Class hierarchy: + // + // - SendReceiveTestBase → file:SendReceiveTest.cs + // ├─ SendReceiveTest_External + // │ ├─ [*]SendReceiveTest_SharedHandler_External + // │ ├─ [*]SendReceiveTest_Invoker_External + // │ └─ [*]SendReceiveTest_HttpClient_External + // └─ SendReceiveTest_LoopbackBase → file:SendReceiveTest.Loopback.cs + // ├─ SendReceiveTest_Loopback + // │ ├─ [*]SendReceiveTest_SharedHandler_Loopback + // │ ├─ [*]SendReceiveTest_Invoker_Loopback + // │ └─ [*]SendReceiveTest_HttpClient_Loopback + // └─ SendReceiveTest_Http2Loopback → file:SendReceiveTest.Loopback.cs, SendReceiveTest.Http2.cs + // ├─ [*]SendReceiveTest_Invoker_Http2Loopback + // └─ [*]SendReceiveTest_HttpClient_Http2Loopback + // --- + // `[*]` - concrete runnable test classes + // `→ file:` - file containing the class and its concrete subclasses + + public abstract class SendReceiveTestBase(ITestOutputHelper output) : ClientWebSocketTestBase(output) { - public InvokerMemorySendReceiveTest(ITestOutputHelper output) : base(output) { } + #region Send-receive type setup - protected override bool UseCustomInvoker => true; - } - - public sealed class HttpClientMemorySendReceiveTest : MemorySendReceiveTest - { - public HttpClientMemorySendReceiveTest(ITestOutputHelper output) : base(output) { } + public static readonly object[][] EchoServersAndSendReceiveType = ToMemberData(EchoServers_Values, Enum.GetValues()); + public static readonly object[][] UseSslAndSendReceiveType = ToMemberData(UseSsl_Values, Enum.GetValues()); + public static readonly object[][] SendReceiveTypes = ToMemberData(Enum.GetValues()); - protected override bool UseHttpClient => true; - } + public enum SendReceiveType + { + ArraySegment = 1, + Memory = 2 + } - public sealed class InvokerArraySegmentSendReceiveTest : ArraySegmentSendReceiveTest - { - public InvokerArraySegmentSendReceiveTest(ITestOutputHelper output) : base(output) { } + protected SendReceiveType TestType { get; private set; } - protected override bool UseCustomInvoker => true; - } + protected Task SendAsync(WebSocket webSocket, ArraySegment buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) + { + return TestType switch + { + SendReceiveType.ArraySegment => webSocket.SendAsync(buffer, messageType, endOfMessage, cancellationToken), + SendReceiveType.Memory => SendAsMemoryAsync(webSocket, buffer, messageType, endOfMessage, cancellationToken), + _ => throw new ArgumentException(nameof(TestType)) + }; - public sealed class HttpClientArraySegmentSendReceiveTest : ArraySegmentSendReceiveTest - { - public HttpClientArraySegmentSendReceiveTest(ITestOutputHelper output) : base(output) { } + static Task SendAsMemoryAsync(WebSocket ws, ArraySegment buf, WebSocketMessageType mt, bool eom, CancellationToken ct) + => ws.SendAsync((ReadOnlyMemory)buf, mt, eom, ct).AsTask(); + } - protected override bool UseHttpClient => true; - } + protected Task ReceiveAsync(WebSocket webSocket, ArraySegment buffer, CancellationToken cancellationToken) + { + return TestType switch + { + SendReceiveType.ArraySegment => webSocket.ReceiveAsync(buffer, cancellationToken), + SendReceiveType.Memory => ReceiveAsMemoryAsync(webSocket, buffer, cancellationToken), + _ => throw new ArgumentException(nameof(TestType)) + }; - public class MemorySendReceiveTest : SendReceiveTest - { - public MemorySendReceiveTest(ITestOutputHelper output) : base(output) { } + static async Task ReceiveAsMemoryAsync(WebSocket ws, ArraySegment buf, CancellationToken ct) + { + ValueWebSocketReceiveResult result = await ws.ReceiveAsync((Memory)buf, ct); + return new WebSocketReceiveResult(result.Count, result.MessageType, result.EndOfMessage, ws.CloseStatus, ws.CloseStatusDescription); + } + } - protected override async Task ReceiveAsync(WebSocket ws, ArraySegment arraySegment, CancellationToken cancellationToken) + protected Task RunSendReceive(Func sendReceiveFunc, SendReceiveType sendReceiveTestType) { - ValueWebSocketReceiveResult r = await ws.ReceiveAsync( - (Memory)arraySegment, - cancellationToken).ConfigureAwait(false); - return new WebSocketReceiveResult(r.Count, r.MessageType, r.EndOfMessage, ws.CloseStatus, ws.CloseStatusDescription); + TestType = sendReceiveTestType; + return sendReceiveFunc(); } - protected override Task SendAsync(WebSocket ws, ArraySegment arraySegment, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) => - ws.SendAsync( - (ReadOnlyMemory)arraySegment, - messageType, - endOfMessage, - cancellationToken).AsTask(); - } + protected Task RunSendReceive(Func sendReceiveFunc, Uri uri, SendReceiveType sendReceiveTestType) + => RunSendReceive(() => sendReceiveFunc(uri), sendReceiveTestType); - public class ArraySegmentSendReceiveTest : SendReceiveTest - { - public ArraySegmentSendReceiveTest(ITestOutputHelper output) : base(output) { } + #endregion - protected override Task ReceiveAsync(WebSocket ws, ArraySegment arraySegment, CancellationToken cancellationToken) => - ws.ReceiveAsync(arraySegment, cancellationToken); + #region Common (Echo Server) tests - protected override Task SendAsync(WebSocket ws, ArraySegment arraySegment, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) => - ws.SendAsync(arraySegment, messageType, endOfMessage, cancellationToken); - } - - public abstract class SendReceiveTest : ClientWebSocketTestBase - { - protected abstract Task SendAsync(WebSocket ws, ArraySegment arraySegment, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken); - protected abstract Task ReceiveAsync(WebSocket ws, ArraySegment arraySegment, CancellationToken cancellationToken); - - public SendReceiveTest(ITestOutputHelper output) : base(output) { } - - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task SendReceive_PartialMessageDueToSmallReceiveBuffer_Success(Uri server) + protected async Task RunClient_SendReceive_PartialMessageDueToSmallReceiveBuffer_Success(Uri server) { const int SendBufferSize = 10; var sendBuffer = new byte[SendBufferSize]; @@ -90,7 +99,7 @@ public async Task SendReceive_PartialMessageDueToSmallReceiveBuffer_Success(Uri var receiveBuffer = new byte[SendBufferSize / 2]; var receiveSegment = new ArraySegment(receiveBuffer); - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var ctsDefault = new CancellationTokenSource(TimeOutMilliseconds); @@ -116,20 +125,21 @@ public async Task SendReceive_PartialMessageDueToSmallReceiveBuffer_Success(Uri } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - [SkipOnPlatform(TestPlatforms.Browser, "JS Websocket does not support see issue https://github.com/dotnet/runtime/issues/46983")] - public async Task SendReceive_PartialMessageBeforeCompleteMessageArrives_Success(Uri server) + protected async Task RunClient_SendReceive_PartialMessageBeforeCompleteMessageArrives_Success(Uri server) { + if (HttpVersion == Net.HttpVersion.Version20) + { + throw new SkipTestException("[ActiveIssue] -- temporarily skipping on HTTP/2"); + } + var sendBuffer = new byte[ushort.MaxValue + 1]; Random.Shared.NextBytes(sendBuffer); var sendSegment = new ArraySegment(sendBuffer); // Ask the remote server to echo back received messages without ever signaling "end of message". - var ub = new UriBuilder(server); - ub.Query = "replyWithPartialMessages"; + var ub = new UriBuilder(server) { Query = EchoQueryKey.ReplyWithPartialMessages }; - using (ClientWebSocket cws = await WebSocketHelper.GetConnectedWebSocket(ub.Uri, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(ub.Uri)) { var ctsDefault = new CancellationTokenSource(TimeOutMilliseconds); @@ -158,11 +168,9 @@ public async Task SendReceive_PartialMessageBeforeCompleteMessageArrives_Success } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task SendAsync_SendCloseMessageType_ThrowsArgumentExceptionWithMessage(Uri server) + protected async Task RunClient_SendAsync_SendCloseMessageType_ThrowsArgumentExceptionWithMessage(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); @@ -186,12 +194,9 @@ public async Task SendAsync_SendCloseMessageType_ThrowsArgumentExceptionWithMess } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - // This will also pass when no exception is thrown. Current implementation doesn't throw. - public async Task SendAsync_MultipleOutstandingSendOperations_Throws(Uri server) + protected async Task RunClient_SendAsync_MultipleOutstandingSendOperations_Throws(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); @@ -203,7 +208,7 @@ public async Task SendAsync_MultipleOutstandingSendOperations_Throws(Uri server) { tasks[i] = SendAsync( cws, - WebSocketData.GetBufferFromText("hello"), + "hello".ToUtf8(), WebSocketMessageType.Text, true, cts.Token); @@ -246,21 +251,20 @@ public async Task SendAsync_MultipleOutstandingSendOperations_Throws(Uri server) } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - // This will also pass when no exception is thrown. Current implementation doesn't throw. - [ActiveIssue("https://github.com/dotnet/runtime/issues/83517", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] - public async Task ReceiveAsync_MultipleOutstandingReceiveOperations_Throws(Uri server) + protected const int SmallTimeoutMs = 200; + protected virtual int MultipleOutstandingReceiveOperations_TimeoutMs => SmallTimeoutMs; + + protected async Task RunClient_ReceiveAsync_MultipleOutstandingReceiveOperations_Throws(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { - var cts = new CancellationTokenSource(PlatformDetection.LocalEchoServerIsNotAvailable ? TimeOutMilliseconds : 200); + var cts = new CancellationTokenSource(MultipleOutstandingReceiveOperations_TimeoutMs); Task[] tasks = new Task[2]; await SendAsync( cws, - WebSocketData.GetBufferFromText(".delay5sec"), + EchoControlMessage.Delay5Sec.ToUtf8(), WebSocketMessageType.Text, true, cts.Token); @@ -288,7 +292,7 @@ await SendAsync( "ReceiveAsync"), ex.Message); - Assert.True(WebSocketState.Aborted == cws.State, cws.State+" state when InvalidOperationException"); + Assert.True(WebSocketState.Aborted == cws.State, cws.State + " state when InvalidOperationException"); } else if (ex is WebSocketException) { @@ -312,17 +316,15 @@ await SendAsync( } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task SendAsync_SendZeroLengthPayloadAsEndOfMessage_Success(Uri server) + protected async Task RunClient_SendAsync_SendZeroLengthPayloadAsEndOfMessage_Success(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); string message = "hello"; await SendAsync( cws, - WebSocketData.GetBufferFromText(message), + message.ToUtf8(), WebSocketMessageType.Text, false, cts.Token); @@ -347,15 +349,18 @@ await SendAsync( Assert.Null(recvRet.CloseStatusDescription); var recvSegment = new ArraySegment(receiveSegment.Array, receiveSegment.Offset, recvRet.Count); - Assert.Equal(message, WebSocketData.GetTextFromBuffer(recvSegment)); + Assert.Equal(message, recvSegment.Utf8ToString()); } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task SendReceive_VaryingLengthBuffers_Success(Uri server) + protected async Task RunClient_SendReceive_VaryingLengthBuffers_Success(Uri server) { - using (ClientWebSocket cws = await WebSocketHelper.GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + if (HttpVersion == Net.HttpVersion.Version20) + { + throw new SkipTestException("[ActiveIssue] -- temporarily skipping on HTTP/2"); + } + + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var rand = new Random(); var ctsDefault = new CancellationTokenSource(TimeOutMilliseconds); @@ -391,11 +396,9 @@ public async Task SendReceive_VaryingLengthBuffers_Success(Uri server) } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task SendReceive_Concurrent_Success(Uri server) + protected async Task RunClient_SendReceive_Concurrent_Success(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { CancellationTokenSource ctsDefault = new CancellationTokenSource(TimeOutMilliseconds); @@ -420,81 +423,9 @@ public async Task SendReceive_Concurrent_Success(Uri server) } } - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalFact(nameof(WebSocketsSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/54153", TestPlatforms.Browser)] - public async Task SendReceive_ConnectionClosedPrematurely_ReceiveAsyncFailsAndWebSocketStateUpdated() - { - var options = new LoopbackServer.Options { WebSocketEndpoint = true }; - - Func connectToServerThatAbortsConnection = async (clientSocket, server, url) => - { - var pendingReceiveAsyncPosted = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - - // Start listening for incoming connections on the server side. - Task acceptTask = server.AcceptConnectionAsync(async connection => - { - // Complete the WebSocket upgrade. After this is done, the client-side ConnectAsync should complete. - Assert.NotNull(await LoopbackHelper.WebSocketHandshakeAsync(connection)); - - // Wait for client-side ConnectAsync to complete and for a pending ReceiveAsync to be posted. - await pendingReceiveAsyncPosted.Task.WaitAsync(TimeSpan.FromMilliseconds(TimeOutMilliseconds)); - - // Close the underlying connection prematurely (without sending a WebSocket Close frame). - connection.Socket.Shutdown(SocketShutdown.Both); - connection.Socket.Close(); - }); - - // Initiate a connection attempt. - var cts = new CancellationTokenSource(TimeOutMilliseconds); - await ConnectAsync(clientSocket, url, cts.Token); - - // Post a pending ReceiveAsync before the TCP connection is torn down. - var recvBuffer = new byte[100]; - var recvSegment = new ArraySegment(recvBuffer); - Task pendingReceiveAsync = ReceiveAsync(clientSocket, recvSegment, cts.Token); - pendingReceiveAsyncPosted.SetResult(); - - // Wait for the server to close the underlying connection. - await acceptTask.WaitAsync(cts.Token); - - WebSocketException pendingReceiveException = await Assert.ThrowsAsync(() => pendingReceiveAsync); - - Assert.Equal(WebSocketError.ConnectionClosedPrematurely, pendingReceiveException.WebSocketErrorCode); - - if (PlatformDetection.IsInAppContainer) - { - const uint WININET_E_CONNECTION_ABORTED = 0x80072EFE; - - Assert.NotNull(pendingReceiveException.InnerException); - Assert.Equal(WININET_E_CONNECTION_ABORTED, (uint)pendingReceiveException.InnerException.HResult); - } - - WebSocketException newReceiveException = - await Assert.ThrowsAsync(() => ReceiveAsync(clientSocket, recvSegment, cts.Token)); - - Assert.Equal( - ResourceHelper.GetExceptionMessage("net_WebSockets_InvalidState", "Aborted", "Open, CloseSent"), - newReceiveException.Message); - - Assert.Equal(WebSocketState.Aborted, clientSocket.State); - Assert.Null(clientSocket.CloseStatus); - }; - - await LoopbackServer.CreateServerAsync(async (server, url) => - { - using (ClientWebSocket clientSocket = new ClientWebSocket()) - { - await connectToServerThatAbortsConnection(clientSocket, server, url); - } - }, options); - } - - [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] - [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] - public async Task ZeroByteReceive_CompletesWhenDataAvailable(Uri server) + protected async Task RunClient_ZeroByteReceive_CompletesWhenDataAvailable(Uri server) { - using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(server)) { var ctsDefault = new CancellationTokenSource(TimeOutMilliseconds); @@ -515,7 +446,7 @@ public async Task ZeroByteReceive_CompletesWhenDataAvailable(Uri server) var receiveBuffer = new byte[1]; t = ReceiveAsync(cws, new ArraySegment(receiveBuffer), ctsDefault.Token); // this is not synchronously possible when the WS client is on another WebWorker - if(!PlatformDetection.IsWasmThreadingSupported) + if (!PlatformDetection.IsWasmThreadingSupported) { Assert.Equal(TaskStatus.RanToCompletion, t.Status); } @@ -527,8 +458,75 @@ public async Task ZeroByteReceive_CompletesWhenDataAvailable(Uri server) Assert.Equal(42, receiveBuffer[0]); // Clean up. - await cws.CloseAsync(WebSocketCloseStatus.NormalClosure, nameof(ZeroByteReceive_CompletesWhenDataAvailable), ctsDefault.Token); + await cws.CloseAsync(WebSocketCloseStatus.NormalClosure, nameof(RunClient_ZeroByteReceive_CompletesWhenDataAvailable), ctsDefault.Token); } } + + #endregion } + + [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] + [ConditionalClass(typeof(ClientWebSocketTestBase), nameof(WebSocketsSupported))] + public abstract class SendReceiveTest_External(ITestOutputHelper output) : SendReceiveTestBase(output) + { + #region Common (Echo Server) tests + + [Theory, MemberData(nameof(EchoServersAndSendReceiveType))] + public Task SendReceive_PartialMessageDueToSmallReceiveBuffer_Success(Uri server, SendReceiveType type) => RunSendReceive( + RunClient_SendReceive_PartialMessageDueToSmallReceiveBuffer_Success, server, type); + + [SkipOnPlatform(TestPlatforms.Browser, "JS Websocket does not support see issue https://github.com/dotnet/runtime/issues/46983")] + [Theory, MemberData(nameof(EchoServersAndSendReceiveType))] + public Task SendReceive_PartialMessageBeforeCompleteMessageArrives_Success(Uri server, SendReceiveType type) => RunSendReceive( + RunClient_SendReceive_PartialMessageBeforeCompleteMessageArrives_Success, server, type); + + [Theory, MemberData(nameof(EchoServersAndSendReceiveType))] + public Task SendAsync_SendCloseMessageType_ThrowsArgumentExceptionWithMessage(Uri server, SendReceiveType type) => RunSendReceive( + RunClient_SendAsync_SendCloseMessageType_ThrowsArgumentExceptionWithMessage, server, type); + + [Theory, MemberData(nameof(EchoServersAndSendReceiveType))] + public Task SendAsync_MultipleOutstandingSendOperations_Throws(Uri server, SendReceiveType type) => RunSendReceive( + RunClient_SendAsync_MultipleOutstandingSendOperations_Throws, server, type); + + protected override int MultipleOutstandingReceiveOperations_TimeoutMs => PlatformDetection.LocalEchoServerIsNotAvailable ? TimeOutMilliseconds : SmallTimeoutMs; + + [ActiveIssue("https://github.com/dotnet/runtime/issues/83517", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] + [Theory, MemberData(nameof(EchoServersAndSendReceiveType))] + public Task ReceiveAsync_MultipleOutstandingReceiveOperations_Throws(Uri server, SendReceiveType type) => RunSendReceive( + RunClient_ReceiveAsync_MultipleOutstandingReceiveOperations_Throws, server, type); + + [Theory, MemberData(nameof(EchoServersAndSendReceiveType))] + public Task SendAsync_SendZeroLengthPayloadAsEndOfMessage_Success(Uri server, SendReceiveType type) => RunSendReceive( + RunClient_SendAsync_SendZeroLengthPayloadAsEndOfMessage_Success, server, type); + + [Theory, MemberData(nameof(EchoServersAndSendReceiveType))] + public Task SendReceive_VaryingLengthBuffers_Success(Uri server, SendReceiveType type) => RunSendReceive( + RunClient_SendReceive_VaryingLengthBuffers_Success, server, type); + + [Theory, MemberData(nameof(EchoServersAndSendReceiveType))] + public Task SendReceive_Concurrent_Success(Uri server, SendReceiveType type) => RunSendReceive( + RunClient_SendReceive_Concurrent_Success, server, type); + + [Theory, MemberData(nameof(EchoServersAndSendReceiveType))] + public Task ZeroByteReceive_CompletesWhenDataAvailable(Uri server, SendReceiveType type) => RunSendReceive( + RunClient_ZeroByteReceive_CompletesWhenDataAvailable, server, type); + + #endregion + } + + #region Runnable test classes: External/Outerloop + + public sealed class SendReceiveTest_SharedHandler_External(ITestOutputHelper output) : SendReceiveTest_External(output) { } + + public sealed class SendReceiveTest_Invoker_External(ITestOutputHelper output) : SendReceiveTest_External(output) + { + protected override bool UseCustomInvoker => true; + } + + public sealed class SendReceiveTest_HttpClient_External(ITestOutputHelper output) : SendReceiveTest_External(output) + { + protected override bool UseHttpClient => true; + } + + #endregion } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj b/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj index d5e28ff2f552cb..de52d1f916203d 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj +++ b/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj @@ -6,6 +6,8 @@ true $(NetCoreAppCurrent);$(NetCoreAppCurrent)-browser $(DefineConstants);NETSTANDARD + + $(NoWarn);xUnit1015 @@ -47,32 +49,50 @@ + + + + + + - + + + + + + + + - + + + + + + diff --git a/src/libraries/System.Net.WebSockets.Client/tests/WebSocketData.cs b/src/libraries/System.Net.WebSockets.Client/tests/WebSocketData.cs deleted file mode 100644 index 320ce788379c76..00000000000000 --- a/src/libraries/System.Net.WebSockets.Client/tests/WebSocketData.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text; - -namespace System.Net.WebSockets.Client.Tests -{ - public static class WebSocketData - { - public static ArraySegment GetBufferFromText(string text) - { - byte[] buffer = Encoding.UTF8.GetBytes(text); - return new ArraySegment(buffer); - } - - public static string GetTextFromBuffer(ArraySegment buffer) - { - return Encoding.UTF8.GetString(buffer.Array, buffer.Offset, buffer.Count); - } - } -} diff --git a/src/libraries/System.Net.WebSockets.Client/tests/WebSocketHelper.cs b/src/libraries/System.Net.WebSockets.Client/tests/WebSocketHelper.cs index df29e843590e9b..5616c0d9fe154d 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/WebSocketHelper.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/WebSocketHelper.cs @@ -1,122 +1,57 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Net.Http; -using System.Net.Test.Common; +using System.Text; using System.Threading; using System.Threading.Tasks; using Xunit; -using Xunit.Abstractions; namespace System.Net.WebSockets.Client.Tests { public static class WebSocketHelper { + public const string OriginalQueryStringHeader = "x-original-query-string"; + private static readonly Lazy s_WebSocketSupported = new Lazy(InitWebSocketSupported); public static bool WebSocketsSupported { get { return s_WebSocketSupported.Value; } } public static async Task TestEcho( - Uri server, + ClientWebSocket cws, WebSocketMessageType type, - int timeOutMilliseconds, - ITestOutputHelper output, - HttpMessageInvoker? invoker = null) + CancellationToken cancellationToken) { - var cts = new CancellationTokenSource(timeOutMilliseconds); string message = "Hello WebSockets!"; string closeMessage = "Good bye!"; var receiveBuffer = new byte[100]; var receiveSegment = new ArraySegment(receiveBuffer); - using (ClientWebSocket cws = await GetConnectedWebSocket(server, timeOutMilliseconds, output, invoker: invoker)) - { - output.WriteLine("TestEcho: SendAsync starting."); - await cws.SendAsync(WebSocketData.GetBufferFromText(message), type, true, cts.Token); - output.WriteLine("TestEcho: SendAsync done."); - Assert.Equal(WebSocketState.Open, cws.State); - - output.WriteLine("TestEcho: ReceiveAsync starting."); - WebSocketReceiveResult recvRet = await cws.ReceiveAsync(receiveSegment, cts.Token); - output.WriteLine("TestEcho: ReceiveAsync done."); - Assert.Equal(WebSocketState.Open, cws.State); - Assert.Equal(message.Length, recvRet.Count); - Assert.Equal(type, recvRet.MessageType); - Assert.True(recvRet.EndOfMessage); - Assert.Null(recvRet.CloseStatus); - Assert.Null(recvRet.CloseStatusDescription); - - var recvSegment = new ArraySegment(receiveSegment.Array, receiveSegment.Offset, recvRet.Count); - Assert.Equal(message, WebSocketData.GetTextFromBuffer(recvSegment)); - - output.WriteLine("TestEcho: CloseAsync starting."); - Task taskClose = cws.CloseAsync(WebSocketCloseStatus.NormalClosure, closeMessage, cts.Token); - Assert.True( - (cws.State == WebSocketState.Open) || (cws.State == WebSocketState.CloseSent) || - (cws.State == WebSocketState.CloseReceived) || (cws.State == WebSocketState.Closed), - "State immediately after CloseAsync : " + cws.State); - await taskClose; - output.WriteLine("TestEcho: CloseAsync done."); - Assert.Equal(WebSocketState.Closed, cws.State); - Assert.Equal(WebSocketCloseStatus.NormalClosure, cws.CloseStatus); - Assert.Equal(closeMessage, cws.CloseStatusDescription); - } + await cws.SendAsync(message.ToUtf8(), type, true, cancellationToken); + Assert.Equal(WebSocketState.Open, cws.State); + + WebSocketReceiveResult recvRet = await cws.ReceiveAsync(receiveSegment, cancellationToken); + Assert.Equal(WebSocketState.Open, cws.State); + Assert.Equal(message.Length, recvRet.Count); + Assert.Equal(type, recvRet.MessageType); + Assert.True(recvRet.EndOfMessage); + Assert.Null(recvRet.CloseStatus); + Assert.Null(recvRet.CloseStatusDescription); + + var recvSegment = new ArraySegment(receiveSegment.Array, receiveSegment.Offset, recvRet.Count); + Assert.Equal(message, recvSegment.Utf8ToString()); + + Task taskClose = cws.CloseAsync(WebSocketCloseStatus.NormalClosure, closeMessage, cancellationToken); + Assert.True( + (cws.State == WebSocketState.Open) || (cws.State == WebSocketState.CloseSent) || + (cws.State == WebSocketState.CloseReceived) || (cws.State == WebSocketState.Closed), + "State immediately after CloseAsync : " + cws.State); + await taskClose; + Assert.Equal(WebSocketState.Closed, cws.State); + Assert.Equal(WebSocketCloseStatus.NormalClosure, cws.CloseStatus); + Assert.Equal(closeMessage, cws.CloseStatusDescription); } - public static Task GetConnectedWebSocket( - Uri server, - int timeOutMilliseconds, - ITestOutputHelper output, - TimeSpan keepAliveInterval = default, - IWebProxy proxy = null, - HttpMessageInvoker? invoker = null) => - GetConnectedWebSocket( - server, - timeOutMilliseconds, - output, - options => - { - if (proxy != null) - { - options.Proxy = proxy; - } - if (keepAliveInterval.TotalSeconds > 0) - { - options.KeepAliveInterval = keepAliveInterval; - } - }, - invoker - ); - - public static Task GetConnectedWebSocket( - Uri server, - int timeOutMilliseconds, - ITestOutputHelper output, - Action configureOptions, - HttpMessageInvoker? invoker = null) => - Retry(output, async () => - { - var cws = new ClientWebSocket(); - configureOptions(cws.Options); - - using (var cts = new CancellationTokenSource(timeOutMilliseconds)) - { - output.WriteLine("GetConnectedWebSocket: ConnectAsync starting."); - Task taskConnect = invoker == null ? cws.ConnectAsync(server, cts.Token) : cws.ConnectAsync(server, invoker, cts.Token); - Assert.True( - (cws.State == WebSocketState.None) || - (cws.State == WebSocketState.Connecting) || - (cws.State == WebSocketState.Open) || - (cws.State == WebSocketState.Aborted), - "State immediately after ConnectAsync incorrect: " + cws.State); - await taskConnect; - output.WriteLine("GetConnectedWebSocket: ConnectAsync done."); - Assert.Equal(WebSocketState.Open, cws.State); - } - return cws; - }); - - public static async Task Retry(ITestOutputHelper output, Func> func) + public static async Task Retry(Func> func) { const int MaxTries = 5; int betweenTryDelayMilliseconds = 1000; @@ -129,10 +64,9 @@ public static async Task Retry(ITestOutputHelper output, Func> fun } catch (WebSocketException exc) { - output.WriteLine($"Retry after attempt #{i} failed with {exc}"); if (i == MaxTries) { - throw; + Assert.Fail($"Failed after {MaxTries} attempts with exception: {exc}"); } await Task.Delay(betweenTryDelayMilliseconds); @@ -160,11 +94,14 @@ private static bool InitWebSocketSupported() } finally { - if (cws != null) - { - cws.Dispose(); - } + cws?.Dispose(); } } + + public static ArraySegment ToUtf8(this string text) + => new ArraySegment(Encoding.UTF8.GetBytes(text)); + + public static string Utf8ToString(this ArraySegment buffer) + => Encoding.UTF8.GetString(buffer.Array, buffer.Offset, buffer.Count); } } diff --git a/src/libraries/System.Net.WebSockets.Client/tests/wasm/BrowserTimerThrottlingTest.cs b/src/libraries/System.Net.WebSockets.Client/tests/wasm/BrowserTimerThrottlingTest.cs index bd44afd52fab56..9db52deb2a9f3f 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/wasm/BrowserTimerThrottlingTest.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/wasm/BrowserTimerThrottlingTest.cs @@ -22,7 +22,7 @@ namespace System.Net.WebSockets.Client.Wasm.Tests // requires --enable-features=IntensiveWakeUpThrottling:grace_period_seconds/1 chromeDriver flags // doesn't work with --disable-background-timer-throttling [TestCaseOrderer("System.Net.WebSockets.Client.Wasm.Tests.AlphabeticalOrderer", "System.Net.WebSockets.Client.Wasm.Tests")] - public class BrowserTimerThrottlingTest : ClientWebSocketTestBase + public class BrowserTimerThrottlingTest(ITestOutputHelper output) : ClientWebSocketTestBase(output) { public static bool IsBrowser => RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")); const double moreThanLightThrottlingThreshold = 1900; @@ -30,8 +30,6 @@ public class BrowserTimerThrottlingTest : ClientWebSocketTestBase const double webSocketMessageFrequency = 45000; const double fastTimeoutFrequency = 100; - public BrowserTimerThrottlingTest(ITestOutputHelper output) : base(output) { } - [ConditionalFact(nameof(PlatformDetection.IsBrowser))] [OuterLoop] // involves long delay // this test is influenced by usage of WS on the same browser tab in previous unit tests. we may need to wait long time for it to fizzle down @@ -90,7 +88,7 @@ public async Task WebSocketKeepsDotnetTimersOnlyLightlyThrottled() DateTime start = DateTime.Now; CancellationTokenSource cts = new CancellationTokenSource(); - using (ClientWebSocket cws = await WebSocketHelper.GetConnectedWebSocket(Test.Common.Configuration.WebSockets.RemoteEchoServer, TimeOutMilliseconds, _output)) + using (ClientWebSocket cws = await GetConnectedWebSocket(Test.Common.Configuration.WebSockets.RemoteEchoServer)) { await SendAndReceive(cws, "test"); using (var timer = new Timers.Timer(fastTimeoutFrequency)) diff --git a/src/libraries/System.Net.WebSockets.Client/tests/wasm/System.Net.WebSockets.Client.Wasm.Tests.csproj b/src/libraries/System.Net.WebSockets.Client/tests/wasm/System.Net.WebSockets.Client.Wasm.Tests.csproj index cd8f38fab54b42..024c780ec7c7cb 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/wasm/System.Net.WebSockets.Client.Wasm.Tests.csproj +++ b/src/libraries/System.Net.WebSockets.Client/tests/wasm/System.Net.WebSockets.Client.Wasm.Tests.csproj @@ -48,7 +48,6 @@ - diff --git a/src/libraries/System.Net.WebSockets/System.Net.WebSockets.slnx b/src/libraries/System.Net.WebSockets/System.Net.WebSockets.slnx index a038728b9e66fc..ae484296a872cd 100644 --- a/src/libraries/System.Net.WebSockets/System.Net.WebSockets.slnx +++ b/src/libraries/System.Net.WebSockets/System.Net.WebSockets.slnx @@ -1,40 +1,618 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Net.WebSockets/src/System.Net.WebSockets.csproj b/src/libraries/System.Net.WebSockets/src/System.Net.WebSockets.csproj index a28435597cac27..f9e2c33e16d2a4 100644 --- a/src/libraries/System.Net.WebSockets/src/System.Net.WebSockets.csproj +++ b/src/libraries/System.Net.WebSockets/src/System.Net.WebSockets.csproj @@ -61,24 +61,24 @@ - + - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs index 25bcdf78fae09b..4e3a261e1ecb77 100644 --- a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs +++ b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs @@ -534,7 +534,7 @@ private ValueTask SendFrameLockAcquiredNonCancelableAsync(MessageOpcode opcode, return ValueTask.FromException( exc is OperationCanceledException ? exc : _state == WebSocketState.Aborted ? CreateOperationCanceledException(exc) : - new WebSocketException(WebSocketError.ConnectionClosedPrematurely, exc)); + ExceptionDispatchInfo.SetCurrentStackTrace(new WebSocketException(WebSocketError.ConnectionClosedPrematurely, exc))); } finally { @@ -1714,10 +1714,10 @@ private void ThrowIfOperationInProgress(bool operationCompleted, [CallerMemberNa /// Creates an OperationCanceledException instance, using a default message and the specified inner exception and token. private static OperationCanceledException CreateOperationCanceledException(Exception innerException, CancellationToken cancellationToken = default(CancellationToken)) { - return new OperationCanceledException( + return (OperationCanceledException)ExceptionDispatchInfo.SetCurrentStackTrace(new OperationCanceledException( new OperationCanceledException().Message, innerException, - cancellationToken); + cancellationToken)); } private void ThrowIfDisposed() => ThrowIfInvalidState(validStates: ManagedWebSocketStates.All); diff --git a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketStream.cs b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketStream.cs index 2f350d4846a6d8..cd262f5bbbc89d 100644 --- a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketStream.cs +++ b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketStream.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; @@ -130,7 +131,7 @@ public override Task ReadAsync(byte[] buffer, int offset, int count, Cancel /// public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) => - ValueTask.FromException(new NotSupportedException()); + ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new NotSupportedException())); /// public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) => @@ -150,7 +151,7 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati /// public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) => - ValueTask.FromException(new NotSupportedException()); + ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new NotSupportedException())); /// public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) => @@ -195,12 +196,12 @@ public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationTo { if (_disposed) { - return ValueTask.FromException(new ObjectDisposedException(GetType().FullName)); + return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(GetType().FullName))); } if (!CanWrite) { - return ValueTask.FromException(new NotSupportedException(SR.NotWriteableStream)); + return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new NotSupportedException(SR.NotWriteableStream))); } if (cancellationToken.IsCancellationRequested) @@ -297,12 +298,12 @@ public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationTo { if (_disposed) { - return ValueTask.FromException(new ObjectDisposedException(GetType().FullName)); + return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(GetType().FullName))); } if (!CanWrite) { - return ValueTask.FromException(new NotSupportedException(SR.NotWriteableStream)); + return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new NotSupportedException(SR.NotWriteableStream))); } if (cancellationToken.IsCancellationRequested) diff --git a/src/libraries/System.Net.WebSockets/tests/WebSocketCreateTest.cs b/src/libraries/System.Net.WebSockets/tests/WebSocketCreateTest.cs index e13d46fc708db8..6dfc67c6a3510c 100644 --- a/src/libraries/System.Net.WebSockets/tests/WebSocketCreateTest.cs +++ b/src/libraries/System.Net.WebSockets/tests/WebSocketCreateTest.cs @@ -344,11 +344,12 @@ private static async Task CreateWebSocketStream(Uri echoUri, Socket clie return stream; } - public static readonly object[][] EchoServers = System.Net.Test.Common.Configuration.WebSockets.GetEchoServers(); - public static readonly object[][] EchoServersAndBoolean = EchoServers.SelectMany(o => new object[][] + public static readonly Uri[] EchoServers_Values = System.Net.Test.Common.Configuration.WebSockets.GetEchoServers(); + public static readonly object[][] EchoServers = EchoServers_Values.Select(uri => new object[] { uri }).ToArray(); + public static readonly object[][] EchoServersAndBoolean = EchoServers_Values.SelectMany(uri => new object[][] { - new object[] { o[0], false }, - new object[] { o[0], true } + new object[] { uri, false }, + new object[] { uri, true } }).ToArray(); protected sealed class UnreadableStream : Stream diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.net9.cs b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.net9.cs index e3e27003e11f91..d91c8c6856e644 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.net9.cs +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.net9.cs @@ -49,16 +49,18 @@ void System.IDisposable.Dispose() { } System.Numerics.Tensors.ReadOnlyTensorSpan System.Numerics.Tensors.IReadOnlyTensor, T>.AsReadOnlyTensorSpan(params scoped System.ReadOnlySpan ranges) { throw null; } System.Numerics.Tensors.ReadOnlyTensorDimensionSpan System.Numerics.Tensors.IReadOnlyTensor, T>.GetDimensionSpan(int dimension) { throw null; } ref readonly T System.Numerics.Tensors.IReadOnlyTensor, T>.GetPinnableReference() { throw null; } + System.ReadOnlySpan System.Numerics.Tensors.IReadOnlyTensor, T>.GetSpan(scoped System.ReadOnlySpan startIndexes, int length) { throw null; } + System.ReadOnlySpan System.Numerics.Tensors.IReadOnlyTensor, T>.GetSpan(scoped System.ReadOnlySpan startIndexes, int length) { throw null; } System.Numerics.Tensors.TensorSpan System.Numerics.Tensors.IReadOnlyTensor, T>.ToDenseTensor() { throw null; } bool System.Numerics.Tensors.ITensor.IsReadOnly { get { throw null; } } object? System.Numerics.Tensors.ITensor.this[params scoped System.ReadOnlySpan indexes] { get { throw null; } set { } } object? System.Numerics.Tensors.ITensor.this[params scoped System.ReadOnlySpan indexes] { get { throw null; } set { } } void System.Numerics.Tensors.ITensor.Fill(object value) { } - static System.Numerics.Tensors.TensorSpan ITensor, T>.Create(scoped System.ReadOnlySpan lengths, bool pinned) { throw null; } - static System.Numerics.Tensors.TensorSpan ITensor, T>.Create(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned) { throw null; } - static System.Numerics.Tensors.TensorSpan ITensor, T>.CreateUninitialized(scoped System.ReadOnlySpan lengths, bool pinned) { throw null; } - static System.Numerics.Tensors.TensorSpan ITensor, T>.CreateUninitialized(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned) { throw null; } + static System.Numerics.Tensors.TensorSpan ITensor, T>.CreateFromShape(scoped System.ReadOnlySpan lengths, bool pinned) { throw null; } + static System.Numerics.Tensors.TensorSpan ITensor, T>.CreateFromShape(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned) { throw null; } + static System.Numerics.Tensors.TensorSpan ITensor, T>.CreateFromShapeUninitialized(scoped System.ReadOnlySpan lengths, bool pinned) { throw null; } + static System.Numerics.Tensors.TensorSpan ITensor, T>.CreateFromShapeUninitialized(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned) { throw null; } System.Numerics.Tensors.TensorSpan System.Numerics.Tensors.ITensor, T>.AsTensorSpan() { throw null; } System.Numerics.Tensors.TensorSpan System.Numerics.Tensors.ITensor, T>.AsTensorSpan(params scoped System.ReadOnlySpan startIndexes) { throw null; } System.Numerics.Tensors.TensorSpan System.Numerics.Tensors.ITensor, T>.AsTensorSpan(params scoped System.ReadOnlySpan startIndexes) { throw null; } diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs index 6b7d71d600b55f..4847b33842bb4b 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs @@ -86,12 +86,16 @@ public partial interface IReadOnlyTensor : System.Numerics.Tensors.IRe void FlattenTo(scoped System.Span destination); System.Numerics.Tensors.ReadOnlyTensorDimensionSpan GetDimensionSpan(int dimension); ref readonly T GetPinnableReference(); + System.ReadOnlySpan GetSpan(scoped System.ReadOnlySpan startIndexes, int length); + System.ReadOnlySpan GetSpan(scoped System.ReadOnlySpan startIndexes, int length); TSelf Slice(params scoped System.ReadOnlySpan startIndexes); TSelf Slice(params scoped System.ReadOnlySpan ranges); TSelf Slice(params scoped System.ReadOnlySpan startIndexes); TSelf ToDenseTensor(); bool TryCopyTo(scoped in System.Numerics.Tensors.TensorSpan destination); bool TryFlattenTo(scoped System.Span destination); + bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.ReadOnlySpan span); + bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.ReadOnlySpan span); } public partial interface ITensor : System.Numerics.Tensors.IReadOnlyTensor { @@ -114,13 +118,17 @@ public partial interface ITensor : System.Numerics.Tensors.IReadOnlyTe System.Numerics.Tensors.TensorSpan AsTensorSpan(params scoped System.ReadOnlySpan startIndexes); System.Numerics.Tensors.TensorSpan AsTensorSpan(params scoped System.ReadOnlySpan ranges); System.Numerics.Tensors.TensorSpan AsTensorSpan(params scoped System.ReadOnlySpan startIndexes); - static abstract TSelf Create(scoped System.ReadOnlySpan lengths, bool pinned = false); - static abstract TSelf Create(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned = false); - static abstract TSelf CreateUninitialized(scoped System.ReadOnlySpan lengths, bool pinned = false); - static abstract TSelf CreateUninitialized(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned = false); + static abstract TSelf CreateFromShape(scoped System.ReadOnlySpan lengths, bool pinned = false); + static abstract TSelf CreateFromShape(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned = false); + static abstract TSelf CreateFromShapeUninitialized(scoped System.ReadOnlySpan lengths, bool pinned = false); + static abstract TSelf CreateFromShapeUninitialized(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned = false); void Fill(T value); new System.Numerics.Tensors.TensorDimensionSpan GetDimensionSpan(int dimension); new ref T GetPinnableReference(); + new System.Span GetSpan(scoped System.ReadOnlySpan startIndexes, int length); + new System.Span GetSpan(scoped System.ReadOnlySpan startIndexes, int length); + bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.Span span); + bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.Span span); } public readonly ref partial struct ReadOnlyTensorDimensionSpan { @@ -189,6 +197,8 @@ public void FlattenTo(scoped System.Span destination) { } #pragma warning restore CS0809 // Obsolete member overrides non-obsolete member [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public ref readonly T GetPinnableReference() { throw null; } + public System.ReadOnlySpan GetSpan(scoped System.ReadOnlySpan startIndexes, int length) { throw null; } + public System.ReadOnlySpan GetSpan(scoped System.ReadOnlySpan startIndexes, int length) { throw null; } public static bool operator ==(in System.Numerics.Tensors.ReadOnlyTensorSpan left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } public static implicit operator System.Numerics.Tensors.ReadOnlyTensorSpan (T[]? array) { throw null; } public static bool operator !=(in System.Numerics.Tensors.ReadOnlyTensorSpan left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } @@ -196,8 +206,11 @@ public void FlattenTo(scoped System.Span destination) { } public System.Numerics.Tensors.ReadOnlyTensorSpan Slice(params scoped System.ReadOnlySpan ranges) { throw null; } public System.Numerics.Tensors.ReadOnlyTensorSpan Slice(params scoped System.ReadOnlySpan startIndexes) { throw null; } public override string ToString() { throw null; } + public string ToString(params scoped System.ReadOnlySpan maximumLengths) { throw null; } public bool TryCopyTo(scoped in System.Numerics.Tensors.TensorSpan destination) { throw null; } public bool TryFlattenTo(scoped System.Span destination) { throw null; } + public bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.ReadOnlySpan span) { throw null; } + public bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.ReadOnlySpan span) { throw null; } public ref partial struct Enumerator : System.Collections.Generic.IEnumerator, System.Collections.IEnumerator, System.IDisposable { private object _dummy; @@ -295,21 +308,16 @@ public static void BroadcastTo(this System.Numerics.Tensors.Tensor source, public static ref readonly System.Numerics.Tensors.TensorSpan CosPi(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.ITrigonometricFunctions { throw null; } public static System.Numerics.Tensors.Tensor Cos(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.ITrigonometricFunctions { throw null; } public static ref readonly System.Numerics.Tensors.TensorSpan Cos(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.ITrigonometricFunctions { throw null; } - public static System.Numerics.Tensors.Tensor CreateAndFillGaussianNormalDistribution(System.Random random, scoped System.ReadOnlySpan lengths) where T : System.Numerics.IFloatingPoint { throw null; } - public static System.Numerics.Tensors.Tensor CreateAndFillGaussianNormalDistribution(scoped System.ReadOnlySpan lengths) where T : System.Numerics.IFloatingPoint { throw null; } - public static System.Numerics.Tensors.Tensor CreateAndFillUniformDistribution(System.Random random, scoped System.ReadOnlySpan lengths) where T : System.Numerics.IFloatingPoint { throw null; } - public static System.Numerics.Tensors.Tensor CreateAndFillUniformDistribution(scoped System.ReadOnlySpan lengths) where T : System.Numerics.IFloatingPoint { throw null; } - public static System.Numerics.Tensors.Tensor CreateUninitialized(scoped System.ReadOnlySpan lengths, bool pinned = false) { throw null; } - public static System.Numerics.Tensors.Tensor CreateUninitialized(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned = false) { throw null; } - public static System.Numerics.Tensors.Tensor Create(System.Collections.Generic.IEnumerable enumerable, bool pinned = false) { throw null; } - public static System.Numerics.Tensors.Tensor Create(System.Collections.Generic.IEnumerable enumerable, scoped System.ReadOnlySpan lengths, bool pinned = false) { throw null; } - public static System.Numerics.Tensors.Tensor Create(System.Collections.Generic.IEnumerable enumerable, scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned = false) { throw null; } - public static System.Numerics.Tensors.Tensor Create(scoped System.ReadOnlySpan lengths, bool pinned = false) { throw null; } - public static System.Numerics.Tensors.Tensor Create(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned = false) { throw null; } public static System.Numerics.Tensors.Tensor Create(T[] array) { throw null; } public static System.Numerics.Tensors.Tensor Create(T[] array, int start, scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides) { throw null; } public static System.Numerics.Tensors.Tensor Create(T[] array, scoped System.ReadOnlySpan lengths) { throw null; } public static System.Numerics.Tensors.Tensor Create(T[] array, scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides) { throw null; } + public static System.Numerics.Tensors.Tensor CreateFromShape(scoped System.ReadOnlySpan lengths, bool pinned = false) { throw null; } + public static System.Numerics.Tensors.Tensor CreateFromShape(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned = false) { throw null; } + public static System.Numerics.Tensors.Tensor CreateFromShapeUninitialized(scoped System.ReadOnlySpan lengths, bool pinned = false) { throw null; } + public static System.Numerics.Tensors.Tensor CreateFromShapeUninitialized(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned = false) { throw null; } + public static System.Numerics.Tensors.Tensor Decrement(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.IDecrementOperators { throw null; } + public static ref readonly System.Numerics.Tensors.TensorSpan Decrement(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.IDecrementOperators { throw null; } public static System.Numerics.Tensors.Tensor DegreesToRadians(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.ITrigonometricFunctions { throw null; } public static ref readonly System.Numerics.Tensors.TensorSpan DegreesToRadians(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.ITrigonometricFunctions { throw null; } public static T Distance(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, scoped in System.Numerics.Tensors.ReadOnlyTensorSpan y) where T : System.Numerics.IRootFunctions { throw null; } @@ -380,6 +388,8 @@ public static void BroadcastTo(this System.Numerics.Tensors.Tensor source, public static ref readonly System.Numerics.Tensors.TensorSpan Ieee754Remainder(T x, scoped in System.Numerics.Tensors.ReadOnlyTensorSpan y, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.IFloatingPointIeee754 { throw null; } public static System.Numerics.Tensors.Tensor ILogB(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.IFloatingPointIeee754 { throw null; } public static ref readonly System.Numerics.Tensors.TensorSpan ILogB(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.IFloatingPointIeee754 { throw null; } + public static System.Numerics.Tensors.Tensor Increment(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.IIncrementOperators { throw null; } + public static ref readonly System.Numerics.Tensors.TensorSpan Increment(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.IIncrementOperators { throw null; } public static nint IndexOfMaxMagnitude(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.INumber { throw null; } public static nint IndexOfMax(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.INumber { throw null; } public static nint IndexOfMinMagnitude(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.INumber { throw null; } @@ -518,6 +528,12 @@ public static void ResizeTo(scoped in System.Numerics.Tensors.Tensor tenso public static bool SequenceEqual(this scoped in System.Numerics.Tensors.TensorSpan tensor, scoped in System.Numerics.Tensors.ReadOnlyTensorSpan other) where T : System.IEquatable? { throw null; } public static ref readonly System.Numerics.Tensors.TensorSpan SetSlice(this in System.Numerics.Tensors.TensorSpan tensor, scoped in System.Numerics.Tensors.ReadOnlyTensorSpan values, params scoped System.ReadOnlySpan ranges) { throw null; } public static System.Numerics.Tensors.Tensor SetSlice(this System.Numerics.Tensors.Tensor tensor, in System.Numerics.Tensors.ReadOnlyTensorSpan values, params scoped System.ReadOnlySpan ranges) { throw null; } + public static Tensor ShiftLeft(in ReadOnlyTensorSpan x, int shiftAmount) where T : IShiftOperators { throw null; } + public static ref readonly TensorSpan ShiftLeft(scoped in ReadOnlyTensorSpan x, int shiftAmount, in TensorSpan destination) where T : IShiftOperators { throw null; } + public static Tensor ShiftRightArithmetic(in ReadOnlyTensorSpan x, int shiftAmount) where T : IShiftOperators { throw null; } + public static ref readonly TensorSpan ShiftRightArithmetic(scoped in ReadOnlyTensorSpan x, int shiftAmount, in TensorSpan destination) where T : IShiftOperators { throw null; } + public static Tensor ShiftRightLogical(in ReadOnlyTensorSpan x, int shiftAmount) where T : IShiftOperators { throw null; } + public static ref readonly TensorSpan ShiftRightLogical(scoped in ReadOnlyTensorSpan x, int shiftAmount, in TensorSpan destination) where T : IShiftOperators { throw null; } public static System.Numerics.Tensors.Tensor Sigmoid(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.IExponentialFunctions { throw null; } public static ref readonly System.Numerics.Tensors.TensorSpan Sigmoid(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.IExponentialFunctions { throw null; } public static System.Numerics.Tensors.Tensor Sinh(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.IHyperbolicFunctions { throw null; } @@ -555,9 +571,6 @@ public static void ResizeTo(scoped in System.Numerics.Tensors.Tensor tenso public static ref readonly System.Numerics.Tensors.TensorSpan TanPi(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.ITrigonometricFunctions { throw null; } public static System.Numerics.Tensors.Tensor Tan(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.ITrigonometricFunctions { throw null; } public static ref readonly System.Numerics.Tensors.TensorSpan Tan(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.ITrigonometricFunctions { throw null; } - public static string ToString(this in System.Numerics.Tensors.ReadOnlyTensorSpan tensor, System.ReadOnlySpan maximumLengths) { throw null; } - public static string ToString(this in System.Numerics.Tensors.TensorSpan tensor, System.ReadOnlySpan maximumLengths) { throw null; } - public static string ToString(this System.Numerics.Tensors.Tensor tensor, System.ReadOnlySpan maximumLengths) { throw null; } public static System.Numerics.Tensors.Tensor TrailingZeroCount(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.IBinaryInteger { throw null; } public static ref readonly System.Numerics.Tensors.TensorSpan TrailingZeroCount(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.IBinaryInteger { throw null; } public static System.Numerics.Tensors.Tensor Transpose(System.Numerics.Tensors.Tensor tensor) { throw null; } @@ -573,6 +586,318 @@ public static void ResizeTo(scoped in System.Numerics.Tensors.Tensor tenso public static ref readonly System.Numerics.Tensors.TensorSpan Xor(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, scoped in System.Numerics.Tensors.ReadOnlyTensorSpan y, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.IBitwiseOperators { throw null; } public static System.Numerics.Tensors.Tensor Xor(in System.Numerics.Tensors.ReadOnlyTensorSpan x, T y) where T : System.Numerics.IBitwiseOperators { throw null; } public static ref readonly System.Numerics.Tensors.TensorSpan Xor(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, T y, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.IBitwiseOperators { throw null; } + extension(System.Numerics.Tensors.ReadOnlyTensorSpan) + where TScalar : System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity + { + public static System.Numerics.Tensors.Tensor operator +(in System.Numerics.Tensors.ReadOnlyTensorSpan left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator +(in System.Numerics.Tensors.ReadOnlyTensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator +(TScalar left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + } + extension(System.Numerics.Tensors.Tensor tensor) + where TScalar : System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity + { + public static System.Numerics.Tensors.Tensor operator +(System.Numerics.Tensors.Tensor left, System.Numerics.Tensors.Tensor right) { throw null; } + public static System.Numerics.Tensors.Tensor operator +(System.Numerics.Tensors.Tensor left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator +(TScalar left, System.Numerics.Tensors.Tensor right) { throw null; } + public void operator +=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator +=(TScalar other) { throw null; } + } + extension(ref System.Numerics.Tensors.TensorSpan tensor) + where TScalar : System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity + { + public static System.Numerics.Tensors.Tensor operator +(in System.Numerics.Tensors.TensorSpan left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator +(in System.Numerics.Tensors.TensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator +(TScalar left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public void operator +=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator +=(TScalar other) { throw null; } + } + extension(System.Numerics.Tensors.ReadOnlyTensorSpan) + where TScalar : System.Numerics.IBitwiseOperators + { + public static System.Numerics.Tensors.Tensor operator &(in System.Numerics.Tensors.ReadOnlyTensorSpan left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator &(in System.Numerics.Tensors.ReadOnlyTensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator &(TScalar left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + } + extension(System.Numerics.Tensors.Tensor tensor) + where TScalar : System.Numerics.IBitwiseOperators + { + public static System.Numerics.Tensors.Tensor operator &(System.Numerics.Tensors.Tensor left, System.Numerics.Tensors.Tensor right) { throw null; } + public static System.Numerics.Tensors.Tensor operator &(System.Numerics.Tensors.Tensor left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator &(TScalar left, System.Numerics.Tensors.Tensor right) { throw null; } + public void operator &=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator &=(TScalar other) { throw null; } + } + extension(ref System.Numerics.Tensors.TensorSpan tensor) + where TScalar : System.Numerics.IBitwiseOperators + { + public static System.Numerics.Tensors.Tensor operator &(in System.Numerics.Tensors.TensorSpan left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator &(in System.Numerics.Tensors.TensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator &(TScalar left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public void operator &=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator &=(TScalar other) { throw null; } + } + extension(System.Numerics.Tensors.ReadOnlyTensorSpan) + where TScalar : System.Numerics.IBitwiseOperators + { + public static System.Numerics.Tensors.Tensor operator |(in System.Numerics.Tensors.ReadOnlyTensorSpan left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator |(in System.Numerics.Tensors.ReadOnlyTensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator |(TScalar left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + } + extension(System.Numerics.Tensors.Tensor tensor) + where TScalar : System.Numerics.IBitwiseOperators + { + public static System.Numerics.Tensors.Tensor operator |(System.Numerics.Tensors.Tensor left, System.Numerics.Tensors.Tensor right) { throw null; } + public static System.Numerics.Tensors.Tensor operator |(System.Numerics.Tensors.Tensor left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator |(TScalar left, System.Numerics.Tensors.Tensor right) { throw null; } + public void operator |=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator |=(TScalar other) { throw null; } + } + extension(ref System.Numerics.Tensors.TensorSpan tensor) + where TScalar : System.Numerics.IBitwiseOperators + { + public static System.Numerics.Tensors.Tensor operator |(in System.Numerics.Tensors.TensorSpan left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator |(in System.Numerics.Tensors.TensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator |(TScalar left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public void operator |=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator |=(TScalar other) { throw null; } + } + extension(System.Numerics.Tensors.Tensor tensor) where TScalar : System.Numerics.IDecrementOperators + { + public void operator --() { throw null; } + } + extension(ref System.Numerics.Tensors.TensorSpan tensor) where TScalar : System.Numerics.IDecrementOperators + { + public void operator --() { throw null; } + } + extension(System.Numerics.Tensors.ReadOnlyTensorSpan) + where TScalar : System.Numerics.IDivisionOperators + { + public static System.Numerics.Tensors.Tensor operator /(in System.Numerics.Tensors.ReadOnlyTensorSpan left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator /(in System.Numerics.Tensors.ReadOnlyTensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator /(TScalar left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + } + extension(System.Numerics.Tensors.Tensor tensor) + where TScalar : System.Numerics.IDivisionOperators + { + public static System.Numerics.Tensors.Tensor operator /(System.Numerics.Tensors.Tensor left, System.Numerics.Tensors.Tensor right) { throw null; } + public static System.Numerics.Tensors.Tensor operator /(System.Numerics.Tensors.Tensor left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator /(TScalar left, System.Numerics.Tensors.Tensor right) { throw null; } + public void operator /=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator /=(TScalar other) { throw null; } + } + extension(ref System.Numerics.Tensors.TensorSpan tensor) + where TScalar : System.Numerics.IDivisionOperators + { + public static System.Numerics.Tensors.Tensor operator /(in System.Numerics.Tensors.TensorSpan left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator /(in System.Numerics.Tensors.TensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator /(TScalar left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public void operator /=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator /=(TScalar other) { throw null; } + } + extension(System.Numerics.Tensors.ReadOnlyTensorSpan) + where TScalar : System.Numerics.IBitwiseOperators + { + public static System.Numerics.Tensors.Tensor operator ^(in System.Numerics.Tensors.ReadOnlyTensorSpan left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator ^(in System.Numerics.Tensors.ReadOnlyTensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator ^(TScalar left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + } + extension(System.Numerics.Tensors.Tensor tensor) + where TScalar : System.Numerics.IBitwiseOperators + { + public static System.Numerics.Tensors.Tensor operator ^(System.Numerics.Tensors.Tensor left, System.Numerics.Tensors.Tensor right) { throw null; } + public static System.Numerics.Tensors.Tensor operator ^(System.Numerics.Tensors.Tensor left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator ^(TScalar left, System.Numerics.Tensors.Tensor right) { throw null; } + public void operator ^=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator ^=(TScalar other) { throw null; } + } + + extension(ref System.Numerics.Tensors.TensorSpan tensor) + where TScalar : System.Numerics.IBitwiseOperators + { + public static System.Numerics.Tensors.Tensor operator ^(in System.Numerics.Tensors.TensorSpan left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator ^(in System.Numerics.Tensors.TensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator ^(TScalar left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public void operator ^=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator ^=(TScalar other) { throw null; } + } + extension(System.Numerics.Tensors.Tensor tensor) where TScalar : System.Numerics.IIncrementOperators + { + public void operator ++() { throw null; } + } + extension(ref System.Numerics.Tensors.TensorSpan tensor) where TScalar : System.Numerics.IIncrementOperators + { + public void operator ++() { throw null; } + } + extension(System.Numerics.Tensors.ReadOnlyTensorSpan) + where TScalar : System.Numerics.IShiftOperators + { + public static System.Numerics.Tensors.Tensor operator <<(in System.Numerics.Tensors.ReadOnlyTensorSpan tensor, int shiftAmount) { throw null; } + } + extension(System.Numerics.Tensors.Tensor) + where TScalar : System.Numerics.IShiftOperators + { + public static System.Numerics.Tensors.Tensor operator <<(System.Numerics.Tensors.Tensor tensor, int shiftAmount) { throw null; } + } + extension(System.Numerics.Tensors.Tensor tensor) + where TScalar : System.Numerics.IShiftOperators + { + public void operator <<=(int shiftAmount) { throw null; } + } + extension(System.Numerics.Tensors.TensorSpan) + where TScalar : System.Numerics.IShiftOperators + { + public static Tensor operator <<(in TensorSpan tensor, int shiftAmount) { throw null; } + } + extension(ref System.Numerics.Tensors.TensorSpan tensor) + where TScalar : System.Numerics.IShiftOperators + { + public void operator <<=(int shiftAmount) { throw null; } + } + extension(System.Numerics.Tensors.ReadOnlyTensorSpan) + where TScalar : System.Numerics.IMultiplyOperators, System.Numerics.IMultiplicativeIdentity + { + public static System.Numerics.Tensors.Tensor operator *(in System.Numerics.Tensors.ReadOnlyTensorSpan left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator *(in System.Numerics.Tensors.ReadOnlyTensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator *(TScalar left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + } + extension(System.Numerics.Tensors.Tensor tensor) + where TScalar : System.Numerics.IMultiplyOperators, System.Numerics.IMultiplicativeIdentity + { + public static System.Numerics.Tensors.Tensor operator *(System.Numerics.Tensors.Tensor left, System.Numerics.Tensors.Tensor right) { throw null; } + public static System.Numerics.Tensors.Tensor operator *(System.Numerics.Tensors.Tensor left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator *(TScalar left, System.Numerics.Tensors.Tensor right) { throw null; } + public void operator *=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator *=(TScalar other) { throw null; } + } + extension(ref System.Numerics.Tensors.TensorSpan tensor) + where TScalar : System.Numerics.IMultiplyOperators, System.Numerics.IMultiplicativeIdentity + { + public static System.Numerics.Tensors.Tensor operator *(in System.Numerics.Tensors.TensorSpan left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator *(in System.Numerics.Tensors.TensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator *(TScalar left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public void operator *=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator *=(TScalar other) { throw null; } + } + extension(System.Numerics.Tensors.ReadOnlyTensorSpan) + where TScalar : System.Numerics.IBitwiseOperators + { + public static System.Numerics.Tensors.Tensor operator ~(in System.Numerics.Tensors.ReadOnlyTensorSpan tensor) { throw null; } + } + extension(System.Numerics.Tensors.Tensor) + where TScalar : System.Numerics.IBitwiseOperators + { + public static System.Numerics.Tensors.Tensor operator ~(in System.Numerics.Tensors.Tensor tensor) { throw null; } + } + extension(System.Numerics.Tensors.TensorSpan) + where TScalar : System.Numerics.IBitwiseOperators + { + public static System.Numerics.Tensors.Tensor operator ~(in System.Numerics.Tensors.TensorSpan tensor) { throw null; } + } + extension(System.Numerics.Tensors.ReadOnlyTensorSpan) + where TScalar : System.Numerics.IShiftOperators + { + public static System.Numerics.Tensors.Tensor operator >>(in System.Numerics.Tensors.ReadOnlyTensorSpan tensor, int shiftAmount) { throw null; } + } + extension(System.Numerics.Tensors.Tensor) + where TScalar : System.Numerics.IShiftOperators + { + public static System.Numerics.Tensors.Tensor operator >>(System.Numerics.Tensors.Tensor tensor, int shiftAmount) { throw null; } + } + extension(System.Numerics.Tensors.Tensor tensor) + where TScalar : System.Numerics.IShiftOperators + { + public void operator >>=(int shiftAmount) { throw null; } + } + extension(System.Numerics.Tensors.TensorSpan) + where TScalar : System.Numerics.IShiftOperators + { + public static Tensor operator >>(in TensorSpan tensor, int shiftAmount) { throw null; } + } + extension(ref System.Numerics.Tensors.TensorSpan tensor) + where TScalar : System.Numerics.IShiftOperators + { + public void operator >>=(int shiftAmount) { throw null; } + } + extension(System.Numerics.Tensors.ReadOnlyTensorSpan) + where TScalar : System.Numerics.ISubtractionOperators + { + public static System.Numerics.Tensors.Tensor operator -(in System.Numerics.Tensors.ReadOnlyTensorSpan left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator -(in System.Numerics.Tensors.ReadOnlyTensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator -(TScalar left, in System.Numerics.Tensors.ReadOnlyTensorSpan right) { throw null; } + } + extension(System.Numerics.Tensors.Tensor tensor) + where TScalar : System.Numerics.ISubtractionOperators + { + public static System.Numerics.Tensors.Tensor operator -(System.Numerics.Tensors.Tensor left, System.Numerics.Tensors.Tensor right) { throw null; } + public static System.Numerics.Tensors.Tensor operator -(System.Numerics.Tensors.Tensor left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator -(TScalar left, System.Numerics.Tensors.Tensor right) { throw null; } + public void operator -=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator -=(TScalar other) { throw null; } + } + extension(ref System.Numerics.Tensors.TensorSpan tensor) + where TScalar : System.Numerics.ISubtractionOperators + { + public static System.Numerics.Tensors.Tensor operator -(in System.Numerics.Tensors.TensorSpan left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public static System.Numerics.Tensors.Tensor operator -(in System.Numerics.Tensors.TensorSpan left, TScalar right) { throw null; } + public static System.Numerics.Tensors.Tensor operator -(TScalar left, in System.Numerics.Tensors.TensorSpan right) { throw null; } + public void operator -=(in System.Numerics.Tensors.ReadOnlyTensorSpan other) { throw null; } + public void operator -=(TScalar other) { throw null; } + } + extension(System.Numerics.Tensors.ReadOnlyTensorSpan) + where TScalar : System.Numerics.IUnaryNegationOperators + { + public static System.Numerics.Tensors.Tensor operator -(in System.Numerics.Tensors.ReadOnlyTensorSpan tensor) { throw null; } + } + extension(System.Numerics.Tensors.Tensor) + where TScalar : System.Numerics.IUnaryNegationOperators + { + public static System.Numerics.Tensors.Tensor operator -(in System.Numerics.Tensors.Tensor tensor) { throw null; } + } + extension(System.Numerics.Tensors.TensorSpan) + where TScalar : System.Numerics.IUnaryNegationOperators + { + public static System.Numerics.Tensors.Tensor operator -(in System.Numerics.Tensors.TensorSpan tensor) { throw null; } + } + extension(System.Numerics.Tensors.ReadOnlyTensorSpan) + where TScalar : System.Numerics.IUnaryPlusOperators + { + public static System.Numerics.Tensors.ReadOnlyTensorSpan operator +(in System.Numerics.Tensors.ReadOnlyTensorSpan tensor) { throw null; } + } + extension(System.Numerics.Tensors.Tensor) + where TScalar : System.Numerics.IUnaryPlusOperators + { + public static System.Numerics.Tensors.Tensor operator +(System.Numerics.Tensors.Tensor tensor) { throw null; } + } + extension(System.Numerics.Tensors.TensorSpan) + where TScalar : System.Numerics.IUnaryPlusOperators + { + public static System.Numerics.Tensors.TensorSpan operator +(in System.Numerics.Tensors.TensorSpan tensor) { throw null; } + } + extension(System.Numerics.Tensors.ReadOnlyTensorSpan) + where TScalar : System.Numerics.IShiftOperators + { + public static System.Numerics.Tensors.Tensor operator >>>(in System.Numerics.Tensors.ReadOnlyTensorSpan tensor, int shiftAmount) { throw null; } + } + extension(System.Numerics.Tensors.Tensor) + where TScalar : System.Numerics.IShiftOperators + { + public static System.Numerics.Tensors.Tensor operator >>>(System.Numerics.Tensors.Tensor tensor, int shiftAmount) { throw null; } + } + extension(System.Numerics.Tensors.Tensor tensor) + where TScalar : System.Numerics.IShiftOperators + { + public void operator >>>=(int shiftAmount) { throw null; } + } + extension(System.Numerics.Tensors.TensorSpan) + where TScalar : System.Numerics.IShiftOperators + { + public static Tensor operator >>>(in TensorSpan tensor, int shiftAmount) { throw null; } + } + extension(ref System.Numerics.Tensors.TensorSpan tensor) + where TScalar : System.Numerics.IShiftOperators + { + public void operator >>>=(int shiftAmount) { throw null; } + } } public readonly ref partial struct TensorDimensionSpan { @@ -881,6 +1206,8 @@ public void FlattenTo(scoped System.Span destination) { } #pragma warning restore CS0809 // Obsolete member overrides non-obsolete member [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public ref T GetPinnableReference() { throw null; } + public System.Span GetSpan(scoped System.ReadOnlySpan startIndexes, int length) { throw null; } + public System.Span GetSpan(scoped System.ReadOnlySpan startIndexes, int length) { throw null; } public static bool operator ==(in System.Numerics.Tensors.TensorSpan left, in System.Numerics.Tensors.TensorSpan right) { throw null; } public static implicit operator System.Numerics.Tensors.ReadOnlyTensorSpan (scoped in System.Numerics.Tensors.TensorSpan tensor) { throw null; } public static implicit operator System.Numerics.Tensors.TensorSpan (T[]? array) { throw null; } @@ -889,8 +1216,13 @@ public void FlattenTo(scoped System.Span destination) { } public System.Numerics.Tensors.TensorSpan Slice(params scoped System.ReadOnlySpan ranges) { throw null; } public System.Numerics.Tensors.TensorSpan Slice(params scoped System.ReadOnlySpan startIndexes) { throw null; } public override string ToString() { throw null; } + public string ToString(params scoped System.ReadOnlySpan maximumLengths) { throw null; } public bool TryCopyTo(scoped in System.Numerics.Tensors.TensorSpan destination) { throw null; } public bool TryFlattenTo(scoped System.Span destination) { throw null; } + public bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.Span span) { throw null; } + public bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.Span span) { throw null; } + public bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.ReadOnlySpan span) { throw null; } + public bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.ReadOnlySpan span) { throw null; } public ref partial struct Enumerator : System.Collections.Generic.IEnumerator, System.Collections.IEnumerator, System.IDisposable { private object _dummy; @@ -942,6 +1274,8 @@ public void FlattenTo(scoped System.Span destination) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public ref T GetPinnableReference() { throw null; } public System.Buffers.MemoryHandle GetPinnedHandle() { throw null; } + public System.Span GetSpan(scoped System.ReadOnlySpan startIndexes, int length) { throw null; } + public System.Span GetSpan(scoped System.ReadOnlySpan startIndexes, int length) { throw null; } public static implicit operator System.Numerics.Tensors.ReadOnlyTensorSpan (System.Numerics.Tensors.Tensor tensor) { throw null; } public static implicit operator System.Numerics.Tensors.TensorSpan (System.Numerics.Tensors.Tensor tensor) { throw null; } public static implicit operator System.Numerics.Tensors.Tensor (T[] array) { throw null; } @@ -953,16 +1287,23 @@ public void FlattenTo(scoped System.Span destination) { } void System.Numerics.Tensors.IReadOnlyTensor, T>.CopyTo(scoped in System.Numerics.Tensors.TensorSpan destination) { } System.Numerics.Tensors.ReadOnlyTensorDimensionSpan System.Numerics.Tensors.IReadOnlyTensor, T>.GetDimensionSpan(int dimension) { throw null; } ref readonly T System.Numerics.Tensors.IReadOnlyTensor, T>.GetPinnableReference() { throw null; } + System.ReadOnlySpan System.Numerics.Tensors.IReadOnlyTensor, T>.GetSpan(scoped System.ReadOnlySpan startIndexes, int length) { throw null; } + System.ReadOnlySpan System.Numerics.Tensors.IReadOnlyTensor, T>.GetSpan(scoped System.ReadOnlySpan startIndexes, int length) { throw null; } bool System.Numerics.Tensors.IReadOnlyTensor, T>.TryCopyTo(scoped in System.Numerics.Tensors.TensorSpan destination) { throw null; } void System.Numerics.Tensors.ITensor.Fill(object value) { } - static System.Numerics.Tensors.Tensor System.Numerics.Tensors.ITensor, T>.Create(scoped System.ReadOnlySpan lengths, bool pinned) { throw null; } - static System.Numerics.Tensors.Tensor System.Numerics.Tensors.ITensor, T>.Create(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned) { throw null; } - static System.Numerics.Tensors.Tensor System.Numerics.Tensors.ITensor, T>.CreateUninitialized(scoped System.ReadOnlySpan lengths, bool pinned) { throw null; } - static System.Numerics.Tensors.Tensor System.Numerics.Tensors.ITensor, T>.CreateUninitialized(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned) { throw null; } + static System.Numerics.Tensors.Tensor System.Numerics.Tensors.ITensor, T>.CreateFromShape(scoped System.ReadOnlySpan lengths, bool pinned) { throw null; } + static System.Numerics.Tensors.Tensor System.Numerics.Tensors.ITensor, T>.CreateFromShape(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned) { throw null; } + static System.Numerics.Tensors.Tensor System.Numerics.Tensors.ITensor, T>.CreateFromShapeUninitialized(scoped System.ReadOnlySpan lengths, bool pinned) { throw null; } + static System.Numerics.Tensors.Tensor System.Numerics.Tensors.ITensor, T>.CreateFromShapeUninitialized(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned) { throw null; } public System.Numerics.Tensors.Tensor ToDenseTensor() { throw null; } + public override string ToString() { throw null; } public string ToString(params scoped System.ReadOnlySpan maximumLengths) { throw null; } public bool TryCopyTo(scoped in System.Numerics.Tensors.TensorSpan destination) { throw null; } public bool TryFlattenTo(scoped System.Span destination) { throw null; } + public bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.Span span) { throw null; } + public bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.Span span) { throw null; } + public bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.ReadOnlySpan span) { throw null; } + public bool TryGetSpan(scoped System.ReadOnlySpan startIndexes, int length, out System.ReadOnlySpan span) { throw null; } public partial struct Enumerator : System.Collections.Generic.IEnumerator, System.Collections.IEnumerator, System.IDisposable { private object _dummy; @@ -976,3 +1317,13 @@ void System.IDisposable.Dispose() { } } } } +namespace System.Runtime.InteropServices +{ + public static class TensorMarshal + { + public static System.Numerics.Tensors.TensorSpan CreateTensorSpan(ref T data, nint dataLength, scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned) { throw null; } + public static System.Numerics.Tensors.ReadOnlyTensorSpan CreateReadOnlyTensorSpan(ref readonly T data, nint dataLength, scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned) { throw null; } + public static ref T GetReference(in System.Numerics.Tensors.TensorSpan tensorSpan) { throw null; } + public static ref readonly T GetReference(in System.Numerics.Tensors.ReadOnlyTensorSpan tensorSpan) { throw null; } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml b/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml index 13243a79731835..cbc50b64ff0de3 100644 --- a/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml @@ -1,6 +1,34 @@  + + CP0002 + M:System.Numerics.Tensors.ITensor`2.Create(System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.ITensor`2.Create(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.ITensor`2.CreateUninitialized(System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.ITensor`2.CreateUninitialized(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + CP0002 M:System.Numerics.Tensors.ReadOnlyTensorSpan`1.#ctor(`0[],System.Index,System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr}) @@ -43,6 +71,76 @@ lib/net8.0/System.Numerics.Tensors.dll true + + CP0002 + M:System.Numerics.Tensors.Tensor.Create``1(System.Collections.Generic.IEnumerable{``0},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.Create``1(System.Collections.Generic.IEnumerable{``0},System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.Create``1(System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.Create``1(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.CreateAndFillGaussianNormalDistribution``1(System.Random,System.ReadOnlySpan{System.IntPtr}) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.CreateAndFillGaussianNormalDistribution``1(System.ReadOnlySpan{System.IntPtr}) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.CreateAndFillUniformDistribution``1(System.Random,System.ReadOnlySpan{System.IntPtr}) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.CreateAndFillUniformDistribution``1(System.ReadOnlySpan{System.IntPtr}) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.CreateUninitialized``1(System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.CreateUninitialized``1(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + CP0002 M:System.Numerics.Tensors.Tensor.GetSmallestBroadcastableLengths(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr}) @@ -78,6 +176,27 @@ lib/net8.0/System.Numerics.Tensors.dll true + + CP0002 + M:System.Numerics.Tensors.Tensor.ToString``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@,System.ReadOnlySpan{System.IntPtr}) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.ToString``1(System.Numerics.Tensors.Tensor{``0},System.ReadOnlySpan{System.IntPtr}) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.ToString``1(System.Numerics.Tensors.TensorSpan{``0}@,System.ReadOnlySpan{System.IntPtr}) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + CP0002 M:System.Numerics.Tensors.Tensor`1.get_Item(System.Numerics.Tensors.Tensor{System.Boolean}) @@ -106,6 +225,34 @@ lib/net8.0/System.Numerics.Tensors.dll true + + CP0002 + M:System.Numerics.Tensors.ITensor`2.Create(System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.ITensor`2.Create(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.ITensor`2.CreateUninitialized(System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.ITensor`2.CreateUninitialized(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + CP0002 M:System.Numerics.Tensors.ReadOnlyTensorSpan`1.#ctor(`0[],System.Index,System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr}) @@ -148,6 +295,76 @@ lib/net9.0/System.Numerics.Tensors.dll true + + CP0002 + M:System.Numerics.Tensors.Tensor.Create``1(System.Collections.Generic.IEnumerable{``0},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.Create``1(System.Collections.Generic.IEnumerable{``0},System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.Create``1(System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.Create``1(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.CreateAndFillGaussianNormalDistribution``1(System.Random,System.ReadOnlySpan{System.IntPtr}) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.CreateAndFillGaussianNormalDistribution``1(System.ReadOnlySpan{System.IntPtr}) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.CreateAndFillUniformDistribution``1(System.Random,System.ReadOnlySpan{System.IntPtr}) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.CreateAndFillUniformDistribution``1(System.ReadOnlySpan{System.IntPtr}) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.CreateUninitialized``1(System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.CreateUninitialized``1(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + CP0002 M:System.Numerics.Tensors.Tensor.GetSmallestBroadcastableLengths(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr}) @@ -183,6 +400,27 @@ lib/net9.0/System.Numerics.Tensors.dll true + + CP0002 + M:System.Numerics.Tensors.Tensor.ToString``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@,System.ReadOnlySpan{System.IntPtr}) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.ToString``1(System.Numerics.Tensors.Tensor{``0},System.ReadOnlySpan{System.IntPtr}) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0002 + M:System.Numerics.Tensors.Tensor.ToString``1(System.Numerics.Tensors.TensorSpan{``0}@,System.ReadOnlySpan{System.IntPtr}) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + CP0002 M:System.Numerics.Tensors.Tensor`1.get_Item(System.Numerics.Tensors.Tensor{System.Boolean}) @@ -218,6 +456,20 @@ lib/net8.0/System.Numerics.Tensors.dll true + + CP0006 + M:System.Numerics.Tensors.IReadOnlyTensor`2.GetSpan(System.ReadOnlySpan{System.Buffers.NIndex},System.Int32) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.IReadOnlyTensor`2.GetSpan(System.ReadOnlySpan{System.IntPtr},System.Int32) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + CP0006 M:System.Numerics.Tensors.IReadOnlyTensor`2.ToDenseTensor @@ -225,6 +477,48 @@ lib/net8.0/System.Numerics.Tensors.dll true + + CP0006 + M:System.Numerics.Tensors.IReadOnlyTensor`2.TryGetSpan(System.ReadOnlySpan{System.Buffers.NIndex},System.Int32,System.ReadOnlySpan{`1}@) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.IReadOnlyTensor`2.TryGetSpan(System.ReadOnlySpan{System.IntPtr},System.Int32,System.ReadOnlySpan{`1}@) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.CreateFromShape(System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.CreateFromShape(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.CreateFromShapeUninitialized(System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.CreateFromShapeUninitialized(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + CP0006 M:System.Numerics.Tensors.ITensor`2.GetDimensionSpan(System.Int32) @@ -232,6 +526,34 @@ lib/net8.0/System.Numerics.Tensors.dll true + + CP0006 + M:System.Numerics.Tensors.ITensor`2.GetSpan(System.ReadOnlySpan{System.Buffers.NIndex},System.Int32) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.GetSpan(System.ReadOnlySpan{System.IntPtr},System.Int32) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.TryGetSpan(System.ReadOnlySpan{System.Buffers.NIndex},System.Int32,System.Span{`1}@) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.TryGetSpan(System.ReadOnlySpan{System.IntPtr},System.Int32,System.Span{`1}@) + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + CP0006 M:System.Numerics.Tensors.IReadOnlyTensor`2.GetDimensionSpan(System.Int32) @@ -239,6 +561,20 @@ lib/net9.0/System.Numerics.Tensors.dll true + + CP0006 + M:System.Numerics.Tensors.IReadOnlyTensor`2.GetSpan(System.ReadOnlySpan{System.Buffers.NIndex},System.Int32) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.IReadOnlyTensor`2.GetSpan(System.ReadOnlySpan{System.IntPtr},System.Int32) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + CP0006 M:System.Numerics.Tensors.IReadOnlyTensor`2.ToDenseTensor @@ -246,6 +582,48 @@ lib/net9.0/System.Numerics.Tensors.dll true + + CP0006 + M:System.Numerics.Tensors.IReadOnlyTensor`2.TryGetSpan(System.ReadOnlySpan{System.Buffers.NIndex},System.Int32,System.ReadOnlySpan{`1}@) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.IReadOnlyTensor`2.TryGetSpan(System.ReadOnlySpan{System.IntPtr},System.Int32,System.ReadOnlySpan{`1}@) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.CreateFromShape(System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.CreateFromShape(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.CreateFromShapeUninitialized(System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.CreateFromShapeUninitialized(System.ReadOnlySpan{System.IntPtr},System.ReadOnlySpan{System.IntPtr},System.Boolean) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + CP0006 M:System.Numerics.Tensors.ITensor`2.GetDimensionSpan(System.Int32) @@ -253,6 +631,34 @@ lib/net9.0/System.Numerics.Tensors.dll true + + CP0006 + M:System.Numerics.Tensors.ITensor`2.GetSpan(System.ReadOnlySpan{System.Buffers.NIndex},System.Int32) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.GetSpan(System.ReadOnlySpan{System.IntPtr},System.Int32) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.TryGetSpan(System.ReadOnlySpan{System.Buffers.NIndex},System.Int32,System.Span{`1}@) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0006 + M:System.Numerics.Tensors.ITensor`2.TryGetSpan(System.ReadOnlySpan{System.IntPtr},System.Int32,System.Span{`1}@) + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + CP0008 T:System.Numerics.Tensors.IReadOnlyTensor`2 @@ -477,6 +883,13 @@ lib/net8.0/System.Numerics.Tensors.dll true + + CP0017 + M:System.Numerics.Tensors.Tensor.OnesComplement``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@,System.Numerics.Tensors.TensorSpan{``0}@)$0 + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + CP0017 M:System.Numerics.Tensors.Tensor`1.AsReadOnlyTensorSpan(System.ReadOnlySpan{System.Buffers.NIndex})$0 @@ -652,6 +1065,13 @@ lib/net9.0/System.Numerics.Tensors.dll true + + CP0017 + M:System.Numerics.Tensors.Tensor.OnesComplement``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@,System.Numerics.Tensors.TensorSpan{``0}@)$0 + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + CP0017 M:System.Numerics.Tensors.Tensor`1.AsReadOnlyTensorSpan(System.ReadOnlySpan{System.Buffers.NIndex})$0 @@ -743,6 +1163,24 @@ lib/net9.0/System.Numerics.Tensors.dll true + + CP0017 + M:System.Numerics.Tensors.Tensor.OnesComplement``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@,System.Numerics.Tensors.TensorSpan{``0}@)$0 + ref/net10.0/System.Numerics.Tensors.dll + lib/net10.0/System.Numerics.Tensors.dll + + + CP0017 + M:System.Numerics.Tensors.Tensor.OnesComplement``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@,System.Numerics.Tensors.TensorSpan{``0}@)$0 + ref/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + + + CP0017 + M:System.Numerics.Tensors.Tensor.OnesComplement``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@,System.Numerics.Tensors.TensorSpan{``0}@)$0 + ref/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + CP0021 M:System.Numerics.Tensors.Tensor.Average``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@)``0:T:System.Numerics.INumberBase{``0} @@ -771,4 +1209,4 @@ lib/net9.0/System.Numerics.Tensors.dll true - + \ No newline at end of file diff --git a/src/libraries/System.Numerics.Tensors/src/PACKAGE.md b/src/libraries/System.Numerics.Tensors/src/PACKAGE.md index 4fcfa9bff72413..056238e75af378 100644 --- a/src/libraries/System.Numerics.Tensors/src/PACKAGE.md +++ b/src/libraries/System.Numerics.Tensors/src/PACKAGE.md @@ -1,12 +1,15 @@ ## About -Provides methods for performing mathematical operations over _tensors_ represented as spans. These methods are accelerated to use SIMD (Single instruction, multiple data) operations supported by the CPU where available. +Provides methods for performing mathematical operations over _tensors_. This library offers both high-level tensor types and low-level primitives for working with multi-dimensional numeric data. Many operations are accelerated to use SIMD (Single instruction, multiple data) operations supported by the CPU where available. ## Key Features -* Numerical operations on tensors represented as `ReadOnlySpan` +* High-level tensor types: `Tensor`, `TensorSpan`, `ReadOnlyTensorSpan` for working with multi-dimensional arrays +* Low-level tensor primitives: `TensorPrimitives` for efficient span-based operations +* Generic support for various numeric types (float, double, int, etc.) * Element-wise arithmetic: Add, Subtract, Multiply, Divide, Exp, Log, Cosh, Tanh, etc. * Tensor arithmetic: CosineSimilarity, Distance, Dot, Normalize, Softmax, Sigmoid, etc. +* SIMD-accelerated operations for improved performance ## How to Use @@ -22,6 +25,7 @@ var movies = new[] { }; var queryEmbedding = new[] { 0.12217915f, -0.034832448f }; +// Using TensorPrimitives for low-level span operations var top3MoviesTensorPrimitives = movies .Select(movie => @@ -36,13 +40,24 @@ foreach (var movie in top3MoviesTensorPrimitives) { Console.WriteLine(movie); } + +// Using higher-level Tensor types for multi-dimensional operations +float[] data1 = [1f, 2f, 3f, 4f, 5f, 6f]; +float[] data2 = [6f, 5f, 4f, 3f, 2f, 1f]; +Tensor tensor1 = Tensor.Create(data1, [2, 3]); // 2x3 tensor +Tensor tensor2 = Tensor.Create(data2, [2, 3]); // 2x3 tensor +Tensor result = tensor1 + tensor2; ``` ## Main Types The main types provided by this library are: -* `System.Numerics.Tensors.TensorPrimitives` +* `System.Numerics.Tensors.TensorPrimitives` - Low-level operations on spans of numeric data +* `System.Numerics.Tensors.Tensor` - Generic tensor class for multi-dimensional arrays +* `System.Numerics.Tensors.TensorSpan` - Span-like view over tensor data +* `System.Numerics.Tensors.ReadOnlyTensorSpan` - Read-only span-like view over tensor data +* `System.Numerics.Tensors.Tensor` - Static class with high-level tensor operations ## Additional Documentation diff --git a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj index 2fe51c32663c6b..24fcfcbaf6225b 100644 --- a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj @@ -39,6 +39,21 @@ + + + + + + + + + + + + + + + @@ -149,6 +164,8 @@ + + @@ -171,6 +188,7 @@ + diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Helpers.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Helpers.cs index 7dc09eb9f65c72..728b3a027dfa9e 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Helpers.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Helpers.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Single.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Single.cs index 3856e66feddabb..9e3a2944c49820 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Single.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Single.cs @@ -1,9 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - namespace System.Numerics.Tensors { /// Performs primitive tensor operations over spans of memory. diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Common/TensorPrimitives.IBooleanUnaryOperator.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Common/TensorPrimitives.IBooleanUnaryOperator.cs index 42a35c6def18cc..fc77b2c6eab946 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Common/TensorPrimitives.IBooleanUnaryOperator.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Common/TensorPrimitives.IBooleanUnaryOperator.cs @@ -5,7 +5,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; -using static System.Numerics.Tensors.TensorPrimitives; namespace System.Numerics.Tensors { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Common/TensorPrimitives.IUnaryInputBinaryOutput.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Common/TensorPrimitives.IUnaryInputBinaryOutput.cs index a3b6a8f31e2fc2..a694f148bd4730 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Common/TensorPrimitives.IUnaryInputBinaryOutput.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Common/TensorPrimitives.IUnaryInputBinaryOutput.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor_1.cs index 1627d66c0c3720..c2d7940498eb69 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor_1.cs @@ -72,6 +72,21 @@ public interface IReadOnlyTensor : IReadOnlyTensor /// This method is intended to support .NET compilers and is not intended to be called by user code. ref readonly T GetPinnableReference(); + /// Return a span that starts at the specified index and contains the specified number of items. + /// The index at which the span should start. + /// The length for the span to return. + /// A span that consists of elements from the current tensor starting at . + /// + /// does not contain elements. + /// -or- + /// is negative, greater than , or would cause the span to contain elements that should be skipped due to . + /// + /// is not a valid index into the tensor. + ReadOnlySpan GetSpan(scoped ReadOnlySpan startIndexes, int length); + + /// + ReadOnlySpan GetSpan(scoped ReadOnlySpan startIndexes, int length); + /// Forms a slice out of the current tensor that begins at a specified index. /// The indexes at which to begin the slice. /// A tensor that consists of all elements of the current tensor from to the end of the tensor. @@ -112,5 +127,17 @@ public interface IReadOnlyTensor : IReadOnlyTensor /// If the length is shorter than the source, no items are copied and the method returns false. /// bool TryFlattenTo(scoped Span destination); + + /// Tries to return a span that starts at the specified index and contains the specified number of items. + /// The index at which the span should start. + /// The desired length of the span to retrieve. + /// On successful return, a span that consists of elements from the current tensor starting at . + /// true if a span was successfully retrieved; otherwise, false which indicates was invalid. + /// does not contain elements. + /// is not a valid index into the tensor. + bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out ReadOnlySpan span); + + /// + bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out ReadOnlySpan span); } } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs index a64d32bfbd3da7..1a992c8703f06a 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers; -using System.Diagnostics.CodeAnalysis; namespace System.Numerics.Tensors { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor_1.cs index 576cd6e4120646..ab7aadfb01ee41 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor_1.cs @@ -25,7 +25,7 @@ public interface ITensor : ITensor, IReadOnlyTensor /// If is true the underlying buffer is created permanently pinned, otherwise the underlying buffer is not pinned. /// The underlying buffer is initialized to default values. /// - static abstract TSelf Create(scoped ReadOnlySpan lengths, bool pinned = false); + static abstract TSelf CreateFromShape(scoped ReadOnlySpan lengths, bool pinned = false); /// Creates a new tensor with the specified lengths and strides. /// The lengths of each dimension. @@ -35,7 +35,7 @@ public interface ITensor : ITensor, IReadOnlyTensor /// If is true the underlying buffer is created permanently pinned, otherwise the underlying buffer is not pinned. /// The underlying buffer is initialized to default values. /// - static abstract TSelf Create(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned = false); + static abstract TSelf CreateFromShape(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned = false); /// Creates a new tensor with the specified lengths and strides. /// The lengths of each dimension. @@ -44,7 +44,7 @@ public interface ITensor : ITensor, IReadOnlyTensor /// If is true the underlying buffer is created permanently pinned, otherwise the underlying buffer is not pinned. /// The underlying buffer is not initialized. /// - static abstract TSelf CreateUninitialized(scoped ReadOnlySpan lengths, bool pinned = false); + static abstract TSelf CreateFromShapeUninitialized(scoped ReadOnlySpan lengths, bool pinned = false); /// Creates a new tensor with the specified lengths and strides. If is true the underlying buffer is created permanently pinned, otherwise the underlying buffer is not pinned. The underlying buffer is not initialized. /// The lengths of each dimension. @@ -54,7 +54,7 @@ public interface ITensor : ITensor, IReadOnlyTensor /// If is true the underlying buffer is created permanently pinned, otherwise the underlying buffer is not pinned. /// The underlying buffer is not initialized. /// - static abstract TSelf CreateUninitialized(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned = false); + static abstract TSelf CreateFromShapeUninitialized(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned = false); /// new ref T this[params scoped ReadOnlySpan indexes] { get; } @@ -93,5 +93,17 @@ public interface ITensor : ITensor, IReadOnlyTensor /// new ref T GetPinnableReference(); + + /// + new Span GetSpan(scoped ReadOnlySpan startIndexes, int length); + + /// + new Span GetSpan(scoped ReadOnlySpan startIndexes, int length); + + /// + bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out Span span); + + /// + bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out Span span); } } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorDimensionSpan_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorDimensionSpan_1.cs index ffa05a45a85909..cd92c08b049a17 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorDimensionSpan_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorDimensionSpan_1.cs @@ -51,7 +51,7 @@ public ReadOnlyTensorSpan this[nint index] ThrowHelper.ThrowArgumentOutOfRangeException(); } - nint linearOffset = _tensor._shape.GetLinearOffset(index, _dimension); + nint linearOffset = _tensor._shape.GetLinearOffsetForDimension(index, _dimension); return new ReadOnlyTensorSpan(ref Unsafe.Add(ref _tensor._reference, linearOffset), _sliceShape); } } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan_1.cs index 30a3139b33cf56..dbc60893e25672 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan_1.cs @@ -238,15 +238,15 @@ public unsafe ReadOnlyTensorSpan(T* data, nint dataLength, scoped ReadOnlySpan(data); } - internal ReadOnlyTensorSpan(ref T data, nint dataLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) + internal ReadOnlyTensorSpan(ref readonly T data, nint dataLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) { - _shape = TensorShape.Create(ref data, dataLength, lengths, strides, pinned); - _reference = ref data; + _shape = TensorShape.Create(in data, dataLength, lengths, strides, pinned); + _reference = ref Unsafe.AsRef(in data); } - internal ReadOnlyTensorSpan(ref T reference, scoped in TensorShape shape) + internal ReadOnlyTensorSpan(ref readonly T reference, scoped in TensorShape shape) { - _reference = ref reference; + _reference = ref Unsafe.AsRef(in reference); _shape = shape; } @@ -382,6 +382,26 @@ public ref readonly T GetPinnableReference() return ref ret; } + /// + public ReadOnlySpan GetSpan(scoped ReadOnlySpan startIndexes, int length) + { + if (!TryGetSpan(startIndexes, length, out ReadOnlySpan span)) + { + ThrowHelper.ThrowArgumentOutOfRangeException(); + } + return span; + } + + /// + public ReadOnlySpan GetSpan(scoped ReadOnlySpan startIndexes, int length) + { + if (!TryGetSpan(startIndexes, length, out ReadOnlySpan span)) + { + ThrowHelper.ThrowArgumentOutOfRangeException(); + } + return span; + } + /// public ReadOnlyTensorSpan Slice(params scoped ReadOnlySpan startIndexes) { @@ -412,9 +432,20 @@ ref Unsafe.Add(ref _reference, linearOffset), ); } - /// Returns the string representation of the tensor span. - /// The string representation of the tensor span. - public override string ToString() => $"System.Numerics.Tensors.ReadOnlyTensorSpan<{typeof(T).Name}>[{_shape}]"; + /// Returns the string representation of the tensor. + /// The string representation of the tensor. + /// This API only lists the shape of the tensor, it does not include the contents. + public override string ToString() => ToString([]); + + /// Creates a representation of the tensor. + /// The maximum number of elements to print for each dimension of the tensor. + /// A representation of the tensor. + /// is not empty and does not contain elements. + /// + /// No contents will be printed if is empty. + /// If a given dimension contains more elements then the corresponding limit specified by , remaining elements will be represented by ... + /// + public string ToString(params scoped ReadOnlySpan maximumLengths) => Tensor.ToString(this, maximumLengths, "System.Numerics.Tensors.ReadOnlyTensorSpan"); /// public bool TryCopyTo(scoped in TensorSpan destination) @@ -438,6 +469,38 @@ public bool TryFlattenTo(scoped Span destination) return false; } + /// + public bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out ReadOnlySpan span) + { + // This validates that startIndexes is valid and will throw ArgumentOutOfRangeException or IndexOutOfRangeException if it is not. + nint longestContiguousLength = _shape.GetLongestContiguousLength(startIndexes, out nint linearOffset); + + if ((length < 0) || (length > longestContiguousLength)) + { + span = default; + return false; + } + + span = MemoryMarshal.CreateReadOnlySpan(in Unsafe.Add(ref _reference, linearOffset), length); + return true; + } + + /// + public bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out ReadOnlySpan span) + { + // This validates that startIndexes is valid and will throw ArgumentOutOfRangeException or IndexOutOfRangeException if it is not. + nint longestContiguousLength = _shape.GetLongestContiguousLength(startIndexes, out nint linearOffset); + + if ((length < 0) || (length > longestContiguousLength)) + { + span = default; + return false; + } + + span = MemoryMarshal.CreateReadOnlySpan(in Unsafe.Add(ref _reference, linearOffset), length); + return true; + } + #if NET9_0_OR_GREATER // // IReadOnlyTensor @@ -465,7 +528,7 @@ ReadOnlyTensorSpan IReadOnlyTensor, T>.ToDenseTensor() if (!IsDense) { - Tensor tmp = Tensor.Create(Lengths, IsPinned); + Tensor tmp = Tensor.CreateFromShape(Lengths, IsPinned); CopyTo(tmp); result = tmp; } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.cs index 2317c6933033ae..c6e4e116744fbd 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.cs @@ -4,7 +4,6 @@ using System.Buffers; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; @@ -68,7 +67,7 @@ public static Tensor Broadcast(scoped in ReadOnlyTensorSpan source, sco public static Tensor Broadcast(scoped in ReadOnlyTensorSpan source, scoped ReadOnlySpan lengths) { TensorOperation.ValidateCompatibility(source, lengths); - Tensor destination = CreateUninitialized(lengths); + Tensor destination = CreateFromShapeUninitialized(lengths); TensorOperation.Invoke, T, T>(source, destination); return destination; } @@ -159,7 +158,7 @@ public static Tensor ConcatenateOnDimension(int dimension, params scoped R nint[] lengths = new nint[tensors[0].Rank]; tensors[0].Lengths.CopyTo(lengths); lengths[dimension] = sumOfAxis; - tensor = Create(lengths); + tensor = CreateFromShape(lengths); } else { @@ -173,7 +172,7 @@ public static Tensor ConcatenateOnDimension(int dimension, params scoped R } } - tensor = Create([totalLength]); + tensor = CreateFromShape([totalLength]); } ConcatenateOnDimension(dimension, tensors, tensor); @@ -292,16 +291,6 @@ private static nint CalculateCopyLength(ReadOnlySpan lengths, int starting #endregion #region Create - /// - /// A new tensor with the specified lengths. - public static Tensor Create(scoped ReadOnlySpan lengths, bool pinned = false) - => new Tensor(lengths, strides: [], pinned); - - /// - /// A new tensor with the specified and . - public static Tensor Create(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned = false) - => new Tensor(lengths, strides, pinned); - /// /// A new tensor that uses as its backing buffer. public static Tensor Create(T[] array) @@ -321,102 +310,25 @@ public static Tensor Create(T[] array, scoped ReadOnlySpan lengths, /// A new tensor that uses as its backing buffer and with the specified and . public static Tensor Create(T[] array, int start, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides) => new Tensor(array, start, lengths, strides); + #endregion - /// A new tensor that contains elements copied from . - public static Tensor Create(IEnumerable enumerable, bool pinned = false) - { - T[] array = [.. enumerable]; - - if (pinned) - { - Tensor tensor = CreateUninitialized([array.Length], pinned); - array.CopyTo(tensor._values); - - return tensor; - } - else - { - return Create(array); - } - } - - /// - /// A new tensor that contains elements copied from and with the specified . - public static Tensor Create(IEnumerable enumerable, scoped ReadOnlySpan lengths, bool pinned = false) - => Create(enumerable, lengths, strides: [], pinned); - - /// - /// A new tensor that contains elements copied from and with the specified and . - public static Tensor Create(IEnumerable enumerable, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned = false) - { - T[] array = [.. enumerable]; - - if (pinned) - { - Tensor tensor = CreateUninitialized(lengths, strides, pinned); - array.CopyTo(tensor._values); - - return tensor; - } - else - { - return Create(array, lengths, strides); - } - } - - /// - /// Creates a and initializes it with random data in a gaussian normal distribution. - /// - /// A indicating the lengths of each dimension. - public static Tensor CreateAndFillGaussianNormalDistribution(scoped ReadOnlySpan lengths) - where T : IFloatingPoint - { - return CreateAndFillGaussianNormalDistribution(Random.Shared, lengths); - } - - /// - /// Creates a and initializes it with random data in a gaussian normal distribution. - /// - /// - /// A indicating the lengths of each dimension. - public static Tensor CreateAndFillGaussianNormalDistribution(Random random, scoped ReadOnlySpan lengths) - where T : IFloatingPoint - { - Tensor tensor = CreateUninitialized(lengths); - FillGaussianNormalDistribution(tensor, random); - return tensor; - } - - - /// - /// Creates a and initializes it with random data uniformly distributed. - /// - /// A indicating the lengths of each dimension. - public static Tensor CreateAndFillUniformDistribution(scoped ReadOnlySpan lengths) - where T : IFloatingPoint - { - return CreateAndFillUniformDistribution(Random.Shared, lengths); - } + #region CreateFromShape + /// + /// A new tensor with the specified lengths. + public static Tensor CreateFromShape(scoped ReadOnlySpan lengths, bool pinned = false) + => new Tensor(lengths, strides: [], pinned); - /// - /// Creates a and initializes it with random data uniformly distributed. - /// - /// - /// A indicating the lengths of each dimension. - public static Tensor CreateAndFillUniformDistribution(Random random, scoped ReadOnlySpan lengths) - where T : IFloatingPoint - { - Tensor tensor = CreateUninitialized(lengths); - FillUniformDistribution(tensor, random); - return tensor; - } + /// + /// A new tensor with the specified and . + public static Tensor CreateFromShape(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned = false) + => new Tensor(lengths, strides, pinned); - /// - public static Tensor CreateUninitialized(scoped ReadOnlySpan lengths, bool pinned = false) - => CreateUninitialized(lengths, strides: [], pinned); + /// + public static Tensor CreateFromShapeUninitialized(scoped ReadOnlySpan lengths, bool pinned = false) + => CreateFromShapeUninitialized(lengths, strides: [], pinned); - /// - public static Tensor CreateUninitialized(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned = false) + /// + public static Tensor CreateFromShapeUninitialized(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned = false) { TensorShape shape = TensorShape.Create(lengths, strides, pinned); T[] values = GC.AllocateUninitializedArray(checked((int)(shape.LinearLength)), pinned); @@ -509,7 +421,7 @@ public static ref readonly TensorSpan Equals(scoped in ReadOnlyTensorSp public static Tensor Equals(in ReadOnlyTensorSpan x, T y) where T : IEqualityOperators { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, bool>(x, y, destination); return destination; } @@ -670,7 +582,7 @@ public static ref readonly TensorSpan GreaterThan(scoped in ReadOnlyTen public static Tensor GreaterThan(in ReadOnlyTensorSpan x, T y) where T : IComparisonOperators { - Tensor destination = Create(x.Lengths, false); + Tensor destination = CreateFromShape(x.Lengths, false); GreaterThan(x, y, destination); return destination; } @@ -851,7 +763,7 @@ public static ref readonly TensorSpan GreaterThanOrEqual(scoped in Read public static Tensor GreaterThanOrEqual(in ReadOnlyTensorSpan x, T y) where T : IComparisonOperators { - Tensor destination = Create(x.Lengths, false); + Tensor destination = CreateFromShape(x.Lengths, false); GreaterThanOrEqual(x, y, destination); return destination; } @@ -1032,7 +944,7 @@ public static ref readonly TensorSpan LessThan(scoped in ReadOnlyTensor public static Tensor LessThan(in ReadOnlyTensorSpan x, T y) where T : IComparisonOperators { - Tensor destination = Create(x.Lengths, false); + Tensor destination = CreateFromShape(x.Lengths, false); LessThan(x, y, destination); return destination; } @@ -1213,7 +1125,7 @@ public static ref readonly TensorSpan LessThanOrEqual(scoped in ReadOnl public static Tensor LessThanOrEqual(in ReadOnlyTensorSpan x, T y) where T : IComparisonOperators { - Tensor destination = Create(x.Lengths, false); + Tensor destination = CreateFromShape(x.Lengths, false); LessThanOrEqual(x, y, destination); return destination; } @@ -1693,7 +1605,7 @@ public static void ResizeTo(scoped in ReadOnlyTensorSpan tensor, in Tensor /// Input . public static Tensor Reverse(in ReadOnlyTensorSpan tensor) { - Tensor output = Create(tensor.Lengths); + Tensor output = CreateFromShape(tensor.Lengths); ReverseDimension(tensor, output, -1); return output; @@ -1707,7 +1619,7 @@ public static Tensor Reverse(in ReadOnlyTensorSpan tensor) /// dimension along which to reverse over. -1 will reverse over all of the dimensions of the left tensor. public static Tensor ReverseDimension(in ReadOnlyTensorSpan tensor, int dimension) { - Tensor output = Create(tensor.Lengths); + Tensor output = CreateFromShape(tensor.Lengths); ReverseDimension(tensor, output, dimension); return output; @@ -2152,98 +2064,147 @@ public static ref readonly TensorSpan StackAlongDimension(scoped ReadOnlyS #endregion #region ToString - /// - /// Creates a representation of the ."/> - /// - /// The you want to represent as a string. - /// Maximum Length of each dimension - /// A representation of the - public static string ToString(this in TensorSpan tensor, ReadOnlySpan maximumLengths) - => tensor.AsReadOnlyTensorSpan().ToString(maximumLengths); - - /// - /// Creates a representation of the ."/> - /// - /// - /// The you want to represent as a string. - /// Maximum Length of each dimension - public static string ToString(this in ReadOnlyTensorSpan tensor, ReadOnlySpan maximumLengths) + internal static string ToString(in ReadOnlyTensorSpan tensor, ReadOnlySpan maximumLengths, string typeName) { - if (maximumLengths.Length != tensor.Rank) + if (!maximumLengths.IsEmpty) { - ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(tensor)); + ArgumentOutOfRangeException.ThrowIfNotEqual(maximumLengths.Length, tensor.Rank); } - StringBuilder sb = new(); - ToString(in tensor, maximumLengths, sb); - return sb.ToString(); - } + var sb = new StringBuilder(typeName); - internal static void ToString(in ReadOnlyTensorSpan tensor, ReadOnlySpan maximumLengths, StringBuilder sb, int indentLevel = 0) - { - Debug.Assert(maximumLengths.Length != tensor.Rank); + sb.Append('<'); + sb.Append(typeof(T).Name); + sb.Append('>'); - sb.Append(' ', indentLevel * 2); sb.Append('['); + sb.AppendJoin(", ", tensor.Lengths); + sb.Append(']'); - if (tensor.Rank != 0) + if (!maximumLengths.IsEmpty) { - nint length = nint.Max(tensor.Lengths[0], maximumLengths[0]); + sb.AppendLine(" {"); - if (tensor.Rank != 1) + if (tensor.Rank == 1) { - string separator = string.Empty; - - for (nint i = 0; i < length; i++) - { - sb.AppendLine(separator); + nint length = nint.Min(tensor.Lengths[0], maximumLengths[0]); + ToString(tensor, length, sb, indentLevel: 1); + sb.AppendLine(); + } + else + { + ToString(tensor, maximumLengths, sb); + } - TensorShape tmpShape = TensorShape.Create(tensor.Lengths[1..], tensor.Strides[1..], tensor.IsPinned); - ReadOnlyTensorSpan tmpTensor = new ReadOnlyTensorSpan(ref Unsafe.Add(ref tensor._reference, i * tensor.Strides[0]), tmpShape); - ToString(tmpTensor, maximumLengths[1..], sb, indentLevel + 1); + sb.Append('}'); + } + return sb.ToString(); + } - separator = ","; - } + private static void ToString(in ReadOnlyTensorSpan tensor, ReadOnlySpan maximumLengths, StringBuilder sb, int indentLevel = 0) + { + nint length = nint.Min(tensor.Lengths[0], maximumLengths[0]); - if (length != tensor.Lengths[0]) - { - sb.AppendLine(separator); - sb.Append(' ', indentLevel * 2); - sb.AppendLine("..."); - } + if (indentLevel != 0) + { + if (tensor.Rank != 1) + { + sb.Append(' ', indentLevel * 2); + sb.AppendLine("["); } else { - string separator = " "; + ToString(tensor, length, sb, indentLevel); + return; + } + } - for (nint i = 0; i < length; i++) - { - sb.Append(separator); - sb.Append(Unsafe.Add(ref tensor._reference, i)); - separator = ", "; - } + if (length != 0) + { + TensorShape tmpShape = TensorShape.Create(tensor.Lengths[1..], tensor.Strides[1..], tensor.IsPinned); - if (length != tensor.Lengths[0]) - { - sb.Append(separator); - sb.Append("..."); - } + ReadOnlyTensorSpan tmpTensor = new ReadOnlyTensorSpan(ref tensor._reference, tmpShape); + ToString(tmpTensor, maximumLengths[1..], sb, indentLevel + 1); + + for (nint i = 1; i < length; i++) + { + sb.AppendLine(","); + tmpTensor = new ReadOnlyTensorSpan(ref Unsafe.Add(ref tensor._reference, i * tensor.Strides[0]), tmpShape); + ToString(tmpTensor, maximumLengths[1..], sb, indentLevel + 1); + } + + if (length != tensor.Lengths[0]) + { + sb.AppendLine(","); + sb.Append(' ', (indentLevel + 1) * 2); + sb.Append(".."); + } + sb.AppendLine(); + } + else + { + sb.Append(' ', (indentLevel + 1) * 2); + sb.AppendLine(".."); + } + sb.Append(' ', indentLevel * 2); + + if (indentLevel != 0) + { + sb.Append(']'); + } + } + + private static void ToString(in ReadOnlyTensorSpan tensor, nint length, StringBuilder sb, int indentLevel) + { + sb.Append(' ', indentLevel * 2); + sb.Append('['); - sb.Append(separator); + if (length != 0) + { + sb.Append(tensor._reference); + + for (nint i = 1; i < length; i++) + { + sb.Append(", "); + sb.Append(Unsafe.Add(ref tensor._reference, i)); + } + + if (length != tensor.Lengths[0]) + { + sb.Append(", .."); } } + else + { + sb.Append(".."); + } + sb.Append(']'); } - /// - /// Creates a representation of the ."/> - /// - /// The you want to represent as a string. - /// Maximum Length of each dimension - /// A representation of the - public static string ToString(this Tensor tensor, ReadOnlySpan maximumLengths) - => tensor.AsReadOnlyTensorSpan().ToString(maximumLengths); + private static StringBuilder AppendJoin(this StringBuilder sb, string separator, ReadOnlySpan values) + { + if (values.IsEmpty) + { + return sb; + } + + if (values[0] is not null) + { + sb.Append(values[0]); + } + + for (int i = 1; i < values.Length; i++) + { + sb.Append(separator); + if (values[i] is not null) + { + sb.Append(values[i]); + } + } + return sb; + } #endregion #region Transpose @@ -2441,7 +2402,7 @@ public static ReadOnlyTensorSpan Unsqueeze(this scoped in ReadOnlyTensorSp public static Tensor Abs(in ReadOnlyTensorSpan x) where T : INumberBase { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2468,7 +2429,7 @@ public static ref readonly TensorSpan Abs(scoped in ReadOnlyTensorSpan public static Tensor Acos(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2495,7 +2456,7 @@ public static ref readonly TensorSpan Acos(scoped in ReadOnlyTensorSpan public static Tensor Acosh(in ReadOnlyTensorSpan x) where T : IHyperbolicFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2522,7 +2483,7 @@ public static ref readonly TensorSpan Acosh(scoped in ReadOnlyTensorSpan AcosPi(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2541,62 +2502,6 @@ public static ref readonly TensorSpan AcosPi(scoped in ReadOnlyTensorSpan< } #endregion - #region Add - /// - /// Adds each element of to each element of and returns a new with the result. - /// - /// The of values to add. - /// The second of values to add. - public static Tensor Add(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) - where T : IAdditionOperators, IAdditiveIdentity - { - TensorOperation.ValidateCompatibility(x, y, out Tensor destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Adds to each element of and returns a new with the result. - /// - /// The of values to add. - /// The to add to each element of . - public static Tensor Add(in ReadOnlyTensorSpan x, T y) - where T : IAdditionOperators, IAdditiveIdentity - { - Tensor destination = CreateUninitialized(x.Lengths); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Adds each element of to each element of and returns a new with the result. - /// - /// The of values to add. - /// The second of values to add. - /// - public static ref readonly TensorSpan Add(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) - where T : IAdditionOperators, IAdditiveIdentity - { - TensorOperation.ValidateCompatibility(x, y, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - - /// - /// Adds to each element of and returns a new with the result. - /// - /// The of values to add. - /// The to add to each element of . - /// - public static ref readonly TensorSpan Add(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) - where T : IAdditionOperators, IAdditiveIdentity - { - TensorOperation.ValidateCompatibility(x, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - #endregion - #region Asin /// /// Takes the inverse sin of each element of the and returns a new with the result. @@ -2605,7 +2510,7 @@ public static ref readonly TensorSpan Add(scoped in ReadOnlyTensorSpan public static Tensor Asin(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2632,7 +2537,7 @@ public static ref readonly TensorSpan Asin(scoped in ReadOnlyTensorSpan public static Tensor Asinh(in ReadOnlyTensorSpan x) where T : IHyperbolicFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2659,7 +2564,7 @@ public static ref readonly TensorSpan Asinh(scoped in ReadOnlyTensorSpan AsinPi(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2686,7 +2591,7 @@ public static ref readonly TensorSpan AsinPi(scoped in ReadOnlyTensorSpan< public static Tensor Atan(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2714,7 +2619,7 @@ public static ref readonly TensorSpan Atan(scoped in ReadOnlyTensorSpan public static Tensor Atan2(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) where T : IFloatingPointIeee754 { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -2741,7 +2646,7 @@ public static ref readonly TensorSpan Atan2(scoped in ReadOnlyTensorSpan Atan2(in ReadOnlyTensorSpan x, T y) where T : IFloatingPointIeee754 { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -2768,7 +2673,7 @@ public static ref readonly TensorSpan Atan2(scoped in ReadOnlyTensorSpan Atan2(T x, in ReadOnlyTensorSpan y) where T : IFloatingPointIeee754 { - Tensor destination = CreateUninitialized(y.Lengths); + Tensor destination = CreateFromShapeUninitialized(y.Lengths); TensorOperation.Invoke, T, T>(y, x, destination); return destination; } @@ -2797,7 +2702,7 @@ public static ref readonly TensorSpan Atan2(T x, scoped in ReadOnlyTensorS public static Tensor Atan2Pi(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) where T : IFloatingPointIeee754 { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -2824,7 +2729,7 @@ public static ref readonly TensorSpan Atan2Pi(scoped in ReadOnlyTensorSpan public static Tensor Atan2Pi(in ReadOnlyTensorSpan x, T y) where T : IFloatingPointIeee754 { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -2851,7 +2756,7 @@ public static ref readonly TensorSpan Atan2Pi(scoped in ReadOnlyTensorSpan public static Tensor Atan2Pi(T x, in ReadOnlyTensorSpan y) where T : IFloatingPointIeee754 { - Tensor destination = CreateUninitialized(y.Lengths); + Tensor destination = CreateFromShapeUninitialized(y.Lengths); TensorOperation.Invoke, T, T>(y, x, destination); return destination; } @@ -2879,7 +2784,7 @@ public static ref readonly TensorSpan Atan2Pi(T x, scoped in ReadOnlyTenso public static Tensor Atanh(in ReadOnlyTensorSpan x) where T : IHyperbolicFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2906,7 +2811,7 @@ public static ref readonly TensorSpan Atanh(scoped in ReadOnlyTensorSpan AtanPi(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2942,118 +2847,6 @@ public static T Average(scoped in ReadOnlyTensorSpan x) } #endregion - #region BitwiseAnd - /// - /// Computes the element-wise bitwise and of the two input and returns a new with the result. - /// - /// The left . - /// The right . - public static Tensor BitwiseAnd(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) - where T : IBitwiseOperators - { - Tensor destination = CreateUninitialized(x.Lengths); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Computes the element-wise bitwise and of the two input and returns a new with the result. - /// - /// The left . - /// The right . - /// - public static ref readonly TensorSpan BitwiseAnd(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) - where T : IBitwiseOperators - { - TensorOperation.ValidateCompatibility(x, y, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - - /// - /// Computes the element-wise bitwise and of the two input and returns a new with the result. - /// - /// The left . - /// The second value. - public static Tensor BitwiseAnd(in ReadOnlyTensorSpan x, T y) - where T : IBitwiseOperators - { - Tensor destination = CreateUninitialized(x.Lengths); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Computes the element-wise bitwise and of the two input and returns a new with the result. - /// - /// The left . - /// The second value. - /// - public static ref readonly TensorSpan BitwiseAnd(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) - where T : IBitwiseOperators - { - TensorOperation.ValidateCompatibility(x, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - #endregion - - #region BitwiseOr - /// - /// Computes the element-wise bitwise of of the two input and returns a new with the result. - /// - /// The left . - /// The right . - public static Tensor BitwiseOr(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) - where T : IBitwiseOperators - { - Tensor destination = CreateUninitialized(x.Lengths); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Computes the element-wise bitwise of of the two input and returns a new with the result. - /// - /// The left . - /// The right . - /// - public static ref readonly TensorSpan BitwiseOr(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) - where T : IBitwiseOperators - { - TensorOperation.ValidateCompatibility(x, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - - /// - /// Computes the element-wise bitwise or of the two input and returns a new with the result. - /// - /// The left . - /// The second value. - public static Tensor BitwiseOr(in ReadOnlyTensorSpan x, T y) - where T : IBitwiseOperators - { - Tensor destination = CreateUninitialized(x.Lengths); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Computes the element-wise bitwise or of the two input and returns a new with the result. - /// - /// The left . - /// The second value. - /// - public static ref readonly TensorSpan BitwiseOr(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) - where T : IBitwiseOperators - { - TensorOperation.ValidateCompatibility(x, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - #endregion - #region CubeRoot /// /// Computes the element-wise cube root of the input and returns a new with the result. @@ -3062,7 +2855,7 @@ public static ref readonly TensorSpan BitwiseOr(scoped in ReadOnlyTensorSp public static Tensor Cbrt(in ReadOnlyTensorSpan x) where T : IRootFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3089,7 +2882,7 @@ public static ref readonly TensorSpan Cbrt(scoped in ReadOnlyTensorSpan public static Tensor Ceiling(in ReadOnlyTensorSpan x) where T : IFloatingPoint { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3118,7 +2911,7 @@ public static Tensor ConvertChecked(in ReadOnlyTensorSpan, IEqualityOperators, INumberBase where TTo : INumberBase { - Tensor destination = CreateUninitialized(source.Lengths); + Tensor destination = CreateFromShapeUninitialized(source.Lengths); TensorOperation.Invoke, TFrom, TTo>(source, destination); return destination; } @@ -3149,7 +2942,7 @@ public static Tensor ConvertSaturating(in ReadOnlyTensorSpan, IEqualityOperators, INumberBase where TTo : INumberBase { - Tensor destination = CreateUninitialized(source.Lengths); + Tensor destination = CreateFromShapeUninitialized(source.Lengths); TensorOperation.Invoke, TFrom, TTo>(source, destination); return destination; } @@ -3180,7 +2973,7 @@ public static Tensor ConvertTruncating(in ReadOnlyTensorSpan, IEqualityOperators, INumberBase where TTo : INumberBase { - Tensor destination = CreateUninitialized(source.Lengths); + Tensor destination = CreateFromShapeUninitialized(source.Lengths); TensorOperation.Invoke, TFrom, TTo>(source, destination); return destination; } @@ -3210,7 +3003,7 @@ public static ref readonly TensorSpan ConvertTruncating(scoped public static Tensor CopySign(in ReadOnlyTensorSpan x, T sign) where T : INumber { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, sign, destination); return destination; } @@ -3223,7 +3016,7 @@ public static Tensor CopySign(in ReadOnlyTensorSpan x, T sign) public static Tensor CopySign(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan sign) where T : INumber { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, sign, destination); return destination; } @@ -3265,7 +3058,7 @@ public static ref readonly TensorSpan CopySign(scoped in ReadOnlyTensorSpa public static Tensor Cos(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3292,7 +3085,7 @@ public static ref readonly TensorSpan Cos(scoped in ReadOnlyTensorSpan public static Tensor Cosh(in ReadOnlyTensorSpan x) where T : IHyperbolicFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3345,7 +3138,7 @@ public static T CosineSimilarity(in ReadOnlyTensorSpan x, in ReadOnlyTenso public static Tensor CosPi(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3382,7 +3175,7 @@ public static ref readonly TensorSpan CosPi(scoped in ReadOnlyTensorSpan DegreesToRadians(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3417,91 +3210,6 @@ public static T Distance(scoped in ReadOnlyTensorSpan x, scoped in ReadOnl } #endregion - #region Divide - /// - /// Divides each element of by and returns a new with the result. - /// - /// Input . - /// The divisor - public static Tensor Divide(in ReadOnlyTensorSpan x, T y) - where T : IDivisionOperators - { - Tensor destination = CreateUninitialized(x.Lengths); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Divides by each element of and returns a new with the result."/> - /// - /// The value to be divided. - /// The divisor. - public static Tensor Divide(T x, in ReadOnlyTensorSpan y) - where T : IDivisionOperators - { - Tensor destination = CreateUninitialized(y.Lengths); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Divides each element of by its corresponding element in and returns - /// a new with the result. - /// - /// The to be divided. - /// The divisor. - public static Tensor Divide(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) - where T : IDivisionOperators - { - TensorOperation.ValidateCompatibility(x, y, out Tensor destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Divides each element of by and returns a new with the result. - /// - /// Input . - /// The divisor - /// - public static ref readonly TensorSpan Divide(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) - where T : IDivisionOperators - { - TensorOperation.ValidateCompatibility(x, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - - /// - /// Divides by each element of and returns a new with the result."/> - /// - /// The value to be divided. - /// The divisor. - /// - public static ref readonly TensorSpan Divide(T x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) - where T : IDivisionOperators - { - TensorOperation.ValidateCompatibility(y, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - - /// - /// Divides each element of by its corresponding element in and returns - /// a new with the result. - /// - /// The to be divided. - /// The divisor. - /// - public static ref readonly TensorSpan Divide(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) - where T : IDivisionOperators - { - TensorOperation.ValidateCompatibility(x, y, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - #endregion - #region Dot /// /// Computes the dot product of two tensors containing numbers. @@ -3526,7 +3234,7 @@ public static T Dot(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) public static Tensor Exp(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3553,7 +3261,7 @@ public static ref readonly TensorSpan Exp(scoped in ReadOnlyTensorSpan public static Tensor Exp10(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3578,7 +3286,7 @@ public static ref readonly TensorSpan Exp10(scoped in ReadOnlyTensorSpan Exp10M1(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3601,7 +3309,7 @@ public static ref readonly TensorSpan Exp10M1(scoped in ReadOnlyTensorSpan public static Tensor Exp2(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3624,7 +3332,7 @@ public static ref readonly TensorSpan Exp2(scoped in ReadOnlyTensorSpan public static Tensor Exp2M1(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3647,7 +3355,7 @@ public static ref readonly TensorSpan Exp2M1(scoped in ReadOnlyTensorSpan< public static Tensor ExpM1(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3670,7 +3378,7 @@ public static ref readonly TensorSpan ExpM1(scoped in ReadOnlyTensorSpan Floor(in ReadOnlyTensorSpan x) where T : IFloatingPoint { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3750,7 +3458,7 @@ public static ref readonly TensorSpan Ieee754Remainder(scoped in ReadOnlyT public static Tensor Ieee754Remainder(in ReadOnlyTensorSpan x, T y) where T : IFloatingPointIeee754 { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -3773,7 +3481,7 @@ public static ref readonly TensorSpan Ieee754Remainder(scoped in ReadOnlyT public static Tensor Ieee754Remainder(T x, in ReadOnlyTensorSpan y) where T : IFloatingPointIeee754 { - Tensor destination = CreateUninitialized(y.Lengths); + Tensor destination = CreateFromShapeUninitialized(y.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -3797,7 +3505,7 @@ public static ref readonly TensorSpan Ieee754Remainder(T x, scoped in Read public static Tensor ILogB(in ReadOnlyTensorSpan x) where T : IFloatingPointIeee754 { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, int>(x, destination); return destination; } @@ -3869,7 +3577,7 @@ public static nint IndexOfMinMagnitude(scoped in ReadOnlyTensorSpan x) public static Tensor LeadingZeroCount(in ReadOnlyTensorSpan x) where T : IBinaryInteger { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3896,7 +3604,7 @@ public static ref readonly TensorSpan LeadingZeroCount(scoped in ReadOnlyT public static Tensor Log(in ReadOnlyTensorSpan x) where T : ILogarithmicFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3943,7 +3651,7 @@ public static ref readonly TensorSpan Log(scoped in ReadOnlyTensorSpan public static Tensor Log(in ReadOnlyTensorSpan x, T y) where T : ILogarithmicFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -3969,7 +3677,7 @@ public static ref readonly TensorSpan Log(scoped in ReadOnlyTensorSpan public static Tensor Log10(in ReadOnlyTensorSpan x) where T : ILogarithmicFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3996,7 +3704,7 @@ public static ref readonly TensorSpan Log10(scoped in ReadOnlyTensorSpan Log10P1(in ReadOnlyTensorSpan x) where T : ILogarithmicFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4023,7 +3731,7 @@ public static ref readonly TensorSpan Log10P1(scoped in ReadOnlyTensorSpan public static Tensor Log2(in ReadOnlyTensorSpan x) where T : ILogarithmicFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4050,7 +3758,7 @@ public static ref readonly TensorSpan Log2(scoped in ReadOnlyTensorSpan public static Tensor Log2P1(in ReadOnlyTensorSpan x) where T : ILogarithmicFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4077,7 +3785,7 @@ public static ref readonly TensorSpan Log2P1(scoped in ReadOnlyTensorSpan< public static Tensor LogP1(in ReadOnlyTensorSpan x) where T : ILogarithmicFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4141,7 +3849,7 @@ public static ref readonly TensorSpan Max(scoped in ReadOnlyTensorSpan public static Tensor Max(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4204,7 +3912,7 @@ public static ref readonly TensorSpan MaxMagnitude(scoped in ReadOnlyTenso public static Tensor MaxMagnitude(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4267,7 +3975,7 @@ public static ref readonly TensorSpan MaxMagnitudeNumber(scoped in ReadOnl public static Tensor MaxMagnitudeNumber(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4330,7 +4038,7 @@ public static ref readonly TensorSpan MaxNumber(scoped in ReadOnlyTensorSp public static Tensor MaxNumber(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4393,7 +4101,7 @@ public static ref readonly TensorSpan Min(scoped in ReadOnlyTensorSpan public static Tensor Min(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4456,7 +4164,7 @@ public static ref readonly TensorSpan MinMagnitude(scoped in ReadOnlyTenso public static Tensor MinMagnitude(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4519,7 +4227,7 @@ public static ref readonly TensorSpan MinMagnitudeNumber(scoped in ReadOnl public static Tensor MinMagnitudeNumber(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4582,7 +4290,7 @@ public static ref readonly TensorSpan MinNumber(scoped in ReadOnlyTensorSp public static Tensor MinNumber(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4600,87 +4308,6 @@ public static ref readonly TensorSpan MinNumber(scoped in ReadOnlyTensorSp } #endregion - #region Multiply - /// - /// Multiplies each element of with and returns a new with the result. - /// - /// Input - /// value to multiply by. - public static Tensor Multiply(in ReadOnlyTensorSpan x, T y) - where T : IMultiplyOperators, IMultiplicativeIdentity - { - Tensor destination = Create(x.Lengths); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Multiplies each element of with and returns a new with the result. - /// If the shapes are not the same they are broadcast to the smallest compatible shape. - /// - /// Left for multiplication. - /// Right for multiplication. - public static Tensor Multiply(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) - where T : IMultiplyOperators, IMultiplicativeIdentity - { - TensorOperation.ValidateCompatibility(x, y, out Tensor destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Multiplies each element of with and returns a new with the result. - /// - /// Input - /// value to multiply by. - /// - public static ref readonly TensorSpan Multiply(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) - where T : IMultiplyOperators, IMultiplicativeIdentity - { - TensorOperation.ValidateCompatibility(x, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - - /// - /// Multiplies each element of with and returns a new with the result. - /// If the shapes are not the same they are broadcast to the smallest compatible shape. - /// - /// Left for multiplication. - /// Right for multiplication. - /// - public static ref readonly TensorSpan Multiply(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) - where T : IMultiplyOperators, IMultiplicativeIdentity - { - TensorOperation.ValidateCompatibility(x, y, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - #endregion - - #region Negate - /// Computes the element-wise negation of each number in the specified tensor. - /// The - public static Tensor Negate(in ReadOnlyTensorSpan x) - where T : IUnaryNegationOperators - { - Tensor destination = CreateUninitialized(x.Lengths); - TensorOperation.Invoke, T, T>(x, destination); - return destination; - } - - /// Computes the element-wise negation of each number in the specified tensor. - /// The - /// - public static ref readonly TensorSpan Negate(scoped in ReadOnlyTensorSpan x, in TensorSpan destination) - where T : IUnaryNegationOperators - { - TensorOperation.ValidateCompatibility(x, destination); - TensorOperation.Invoke, T, T>(x, destination); - return ref destination; - } - #endregion - #region Norm /// /// Takes the norm of the and returns the result. @@ -4695,36 +4322,13 @@ public static T Norm(scoped in ReadOnlyTensorSpan x) } #endregion - #region OnesComplement - /// Computes the element-wise one's complement of numbers in the specified tensor. - /// The - public static Tensor OnesComplement(in ReadOnlyTensorSpan x) - where T : IBitwiseOperators - { - Tensor destination = CreateUninitialized(x.Lengths); - TensorOperation.Invoke, T, T>(x, destination); - return destination; - } - - /// Computes the element-wise one's complement of numbers in the specified tensor. - /// The - /// - public static ref readonly TensorSpan OnesComplement(scoped in ReadOnlyTensorSpan y, in TensorSpan destination) - where T : IBitwiseOperators - { - TensorOperation.ValidateCompatibility(y, destination); - TensorOperation.Invoke, T, T>(y, destination); - return ref destination; - } - #endregion - #region PopCount /// Computes the element-wise population count of numbers in the specified tensor. /// The public static Tensor PopCount(in ReadOnlyTensorSpan x) where T : IBinaryInteger { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4771,7 +4375,7 @@ public static ref readonly TensorSpan Pow(scoped in ReadOnlyTensorSpan public static Tensor Pow(in ReadOnlyTensorSpan x, T y) where T : IPowerFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4794,7 +4398,7 @@ public static ref readonly TensorSpan Pow(scoped in ReadOnlyTensorSpan public static Tensor Pow(T x, in ReadOnlyTensorSpan y) where T : IPowerFunctions { - Tensor destination = CreateUninitialized(y.Lengths); + Tensor destination = CreateFromShapeUninitialized(y.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4830,7 +4434,7 @@ public static T Product(scoped in ReadOnlyTensorSpan x) public static Tensor RadiansToDegrees(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4853,7 +4457,7 @@ public static ref readonly TensorSpan RadiansToDegrees(scoped in ReadOnlyT public static Tensor Reciprocal(in ReadOnlyTensorSpan x) where T : IFloatingPoint { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4877,7 +4481,7 @@ public static ref readonly TensorSpan Reciprocal(scoped in ReadOnlyTensorS public static Tensor RootN(in ReadOnlyTensorSpan x, int n) where T : IRootFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, n, destination); return destination; } @@ -4903,7 +4507,7 @@ public static ref readonly TensorSpan RootN(scoped in ReadOnlyTensorSpan RotateLeft(in ReadOnlyTensorSpan x, int rotateAmount) where T : IBinaryInteger { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, rotateAmount, destination); return destination; } @@ -4930,7 +4534,7 @@ public static ref readonly TensorSpan RotateLeft(scoped in ReadOnlyTensorS public static Tensor RotateRight(in ReadOnlyTensorSpan x, int rotateAmount) where T : IBinaryInteger { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, rotateAmount, destination); return destination; } @@ -4955,7 +4559,7 @@ public static ref readonly TensorSpan RotateRight(scoped in ReadOnlyTensor public static Tensor Round(in ReadOnlyTensorSpan x) where T : IFloatingPoint { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4978,7 +4582,7 @@ public static ref readonly TensorSpan Round(scoped in ReadOnlyTensorSpan Round(in ReadOnlyTensorSpan x, int digits, MidpointRounding mode) where T : IFloatingPoint { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, Tuple, T>(x, Tuple.Create(digits, mode), destination); return destination; } @@ -5002,7 +4606,7 @@ public static ref readonly TensorSpan Round(scoped in ReadOnlyTensorSpan Round(in ReadOnlyTensorSpan x, int digits) where T : IFloatingPoint { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, Tuple, T>(x, Tuple.Create(digits, MidpointRounding.ToEven), destination); return destination; } @@ -5025,7 +4629,7 @@ public static ref readonly TensorSpan Round(scoped in ReadOnlyTensorSpan Round(in ReadOnlyTensorSpan x, MidpointRounding mode) where T : IFloatingPoint { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, Tuple, T>(x, Tuple.Create(0, mode), destination); return destination; } @@ -5049,7 +4653,7 @@ public static ref readonly TensorSpan Round(scoped in ReadOnlyTensorSpan Sigmoid(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5074,7 +4678,7 @@ public static ref readonly TensorSpan Sigmoid(scoped in ReadOnlyTensorSpan public static Tensor Sin(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5099,7 +4703,7 @@ public static ref readonly TensorSpan Sin(scoped in ReadOnlyTensorSpan public static Tensor Sinh(in ReadOnlyTensorSpan x) where T : IHyperbolicFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5122,7 +4726,7 @@ public static ref readonly TensorSpan Sinh(scoped in ReadOnlyTensorSpan public static Tensor SinPi(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5148,7 +4752,7 @@ public static Tensor SoftMax(in ReadOnlyTensorSpan x) T sumExp = T.AdditiveIdentity; TensorOperation.Invoke, T, T>(x, ref sumExp); - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, sumExp, destination); return destination; } @@ -5176,7 +4780,7 @@ public static ref readonly TensorSpan SoftMax(scoped in ReadOnlyTensorSpan public static Tensor Sqrt(in ReadOnlyTensorSpan x) where T : IRootFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5213,89 +4817,6 @@ public static T StdDev(in ReadOnlyTensorSpan x) } #endregion - #region Subtract - /// - /// Subtracts from each element of and returns a new with the result. - /// - /// The . - /// The to subtract. - public static Tensor Subtract(in ReadOnlyTensorSpan x, T y) - where T : ISubtractionOperators - { - Tensor destination = CreateUninitialized(x.Lengths); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Subtracts each element of from and returns a new with the result. - /// - /// The to be subtracted from. - /// The of values to subtract. - public static Tensor Subtract(T x, in ReadOnlyTensorSpan y) - where T : ISubtractionOperators - { - Tensor destination = CreateUninitialized(y.Lengths); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Subtracts each element of from and returns a new with the result. - /// - /// The with values to be subtracted from. - /// The with values to subtract. - public static Tensor Subtract(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) - where T : ISubtractionOperators - { - TensorOperation.ValidateCompatibility(x, y, out Tensor destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Subtracts from each element of and returns a new with the result. - /// - /// The with values to be subtracted from. - /// The value to subtract. - /// - public static ref readonly TensorSpan Subtract(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) - where T : ISubtractionOperators - { - TensorOperation.ValidateCompatibility(x, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - - /// - /// Subtracts each element of from and returns a new with the result. - /// - /// The value to be subtracted from. - /// The values to subtract. - /// - public static ref readonly TensorSpan Subtract(T x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) - where T : ISubtractionOperators - { - TensorOperation.ValidateCompatibility(y, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - - /// - /// Subtracts each element of from and returns a new with the result. - /// - /// The of values to be subtracted from. - /// The of values to subtract. - /// - public static ref readonly TensorSpan Subtract(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) - where T : ISubtractionOperators - { - TensorOperation.ValidateCompatibility(x, y, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - #endregion - #region Sum /// /// Sums the elements of the specified tensor. @@ -5332,7 +4853,7 @@ internal static T SumOfSquares(scoped in ReadOnlyTensorSpan x) public static Tensor Tan(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5355,7 +4876,7 @@ public static ref readonly TensorSpan Tan(scoped in ReadOnlyTensorSpan public static Tensor Tanh(in ReadOnlyTensorSpan x) where T : IHyperbolicFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5378,7 +4899,7 @@ public static ref readonly TensorSpan Tanh(scoped in ReadOnlyTensorSpan public static Tensor TanPi(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5401,7 +4922,7 @@ public static ref readonly TensorSpan TanPi(scoped in ReadOnlyTensorSpan TrailingZeroCount(in ReadOnlyTensorSpan x) where T : IBinaryInteger { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5424,7 +4945,7 @@ public static ref readonly TensorSpan TrailingZeroCount(scoped in ReadOnly public static Tensor Truncate(in ReadOnlyTensorSpan x) where T : IFloatingPoint { - Tensor destination = CreateUninitialized(x.Lengths); + Tensor destination = CreateFromShapeUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5440,58 +4961,6 @@ public static ref readonly TensorSpan Truncate(scoped in ReadOnlyTensorSpa return ref destination; } #endregion - - #region Xor - /// Computes the element-wise XOR of numbers in the specified tensors. - /// The left . - /// The right . - public static Tensor Xor(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) - where T : IBitwiseOperators - { - TensorOperation.ValidateCompatibility(x, y, out Tensor destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// Computes the element-wise XOR of numbers in the specified tensors. - /// The left . - /// The right . - /// - public static ref readonly TensorSpan Xor(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) - where T : IBitwiseOperators - { - TensorOperation.ValidateCompatibility(x, y, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - - /// - /// Computes the element-wise Xor of the two input and returns a new with the result. - /// - /// The left . - /// The second value. - public static Tensor Xor(in ReadOnlyTensorSpan x, T y) - where T : IBitwiseOperators - { - Tensor destination = CreateUninitialized(x.Lengths); - TensorOperation.Invoke, T, T>(x, y, destination); - return destination; - } - - /// - /// Computes the element-wise Xor of the two input and returns a new with the result. - /// - /// The left . - /// The second value. - /// - public static ref readonly TensorSpan Xor(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) - where T : IBitwiseOperators - { - TensorOperation.ValidateCompatibility(x, destination); - TensorOperation.Invoke, T, T>(x, y, destination); - return ref destination; - } - #endregion #endregion } } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Addition.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Addition.cs new file mode 100644 index 00000000000000..1da8f2c678d998 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Addition.cs @@ -0,0 +1,132 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs element-wise addition between two tensors. + /// The type of the elements in the tensor. + /// The tensor to add with . + /// The tensor to add with . + /// A new tensor containing the result of + . + /// The shapes of and are not compatible. + public static Tensor Add(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) + where T : IAdditionOperators, IAdditiveIdentity + { + TensorOperation.ValidateCompatibility(x, y, out Tensor destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs element-wise addition between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor to add with . + /// The scalar to add with . + /// A new tensor containing the result of + . + public static Tensor Add(in ReadOnlyTensorSpan x, T y) + where T : IAdditionOperators, IAdditiveIdentity + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs element-wise addition between two tensors. + /// The type of the elements in the tensor. + /// The tensor to add with . + /// The tensor to add with . + /// The destination where the result of + is written. + /// A reference to . + /// The shapes of , , and are not compatible. + public static ref readonly TensorSpan Add(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) + where T : IAdditionOperators, IAdditiveIdentity + { + TensorOperation.ValidateCompatibility(x, y, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// Performs element-wise addition between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor to add with . + /// The scalar to add with . + /// The destination where the result of + is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan Add(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) + where T : IAdditionOperators, IAdditiveIdentity + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + extension(ReadOnlyTensorSpan) + where TScalar : IAdditionOperators, IAdditiveIdentity + { + /// Performs element-wise addition between two tensors. + /// The tensor to add with . + /// The tensor to add with . + /// A new tensor containing the result of + . + /// The shapes of and are not compatible. + public static Tensor operator +(in ReadOnlyTensorSpan left, in ReadOnlyTensorSpan right) => Add(left, right); + + /// Performs element-wise addition between a tensor and scalar. + /// The tensor to add with . + /// The scalar to add with . + /// A new tensor containing the result of + . + public static Tensor operator +(in ReadOnlyTensorSpan left, TScalar right) => Add(left, right); + + /// Performs element-wise addition between a tensor and scalar. + /// The scalar to add with . + /// The tensor to add with . + /// A new tensor containing the result of + . + public static Tensor operator +(TScalar left, in ReadOnlyTensorSpan right) => Add(right, left); + } + + /// The type of the elements in the tensor. + extension(Tensor tensor) + where TScalar : IAdditionOperators, IAdditiveIdentity + { + /// + public static Tensor operator +(Tensor left, Tensor right) => Add(left, right); + + /// + public static Tensor operator +(Tensor left, TScalar right) => Add(left, right); + + /// + public static Tensor operator +(TScalar left, Tensor right) => Add(right, left); + + /// + public void operator +=(in ReadOnlyTensorSpan other) => Add(tensor, other, tensor); + + /// + public void operator +=(TScalar other) => Add(tensor, other, tensor); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(ref TensorSpan tensor) + where TScalar : IAdditionOperators, IAdditiveIdentity + { + /// + public static Tensor operator +(in TensorSpan left, in TensorSpan right) => Add(left, right); + + /// + public static Tensor operator +(in TensorSpan left, TScalar right) => Add(left, right); + + /// + public static Tensor operator +(TScalar left, in TensorSpan right) => Add(right, left); + + /// Performs in-place element-wise addition between two tensors. + /// The tensor to add to the tensor being operated on. + public void operator +=(in ReadOnlyTensorSpan other) => Add(tensor, other, tensor); + + /// Performs in-place element-wise addition between a tensor and scalar. + /// The scalar to add to the tensor being operated on. + public void operator +=(TScalar other) => Add(tensor, other, tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_BitwiseAnd.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_BitwiseAnd.cs new file mode 100644 index 00000000000000..dc2417aeb7db48 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_BitwiseAnd.cs @@ -0,0 +1,132 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs bitwise-and between two tensors. + /// The type of the elements in the tensor. + /// The tensor to bitwise-and with . + /// The tensor to bitwise-and with . + /// A new tensor containing the result of & . + /// The shapes of and are not compatible. + public static Tensor BitwiseAnd(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) + where T : IBitwiseOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs bitwise-and between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor to bitwise-and with . + /// The scalar to bitwise-and with . + /// A new tensor containing the result of & . + public static Tensor BitwiseAnd(in ReadOnlyTensorSpan x, T y) + where T : IBitwiseOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs bitwise-and between two tensors. + /// The type of the elements in the tensor. + /// The tensor to bitwise-and with . + /// The tensor to bitwise-and with . + /// The destination where the result of & is written. + /// A reference to . + /// The shapes of , , and are not compatible. + public static ref readonly TensorSpan BitwiseAnd(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) + where T : IBitwiseOperators + { + TensorOperation.ValidateCompatibility(x, y, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// Performs bitwise-and between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor to bitwise-and with . + /// The scalar to bitwise-and with . + /// The destination where the result of & is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan BitwiseAnd(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) + where T : IBitwiseOperators + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + extension(ReadOnlyTensorSpan) + where TScalar : IBitwiseOperators + { + /// Performs bitwise-and between two tensors. + /// The tensor to bitwise-and with . + /// The tensor to bitwise-and with . + /// A new tensor containing the result of & . + /// The shapes of and are not compatible. + public static Tensor operator &(in ReadOnlyTensorSpan left, in ReadOnlyTensorSpan right) => BitwiseAnd(left, right); + + /// Performs bitwise-and between a tensor and scalar. + /// The tensor to bitwise-and with . + /// The scalar to bitwise-and with . + /// A new tensor containing the result of & . + public static Tensor operator &(in ReadOnlyTensorSpan left, TScalar right) => BitwiseAnd(left, right); + + /// Performs bitwise-and between a tensor and scalar. + /// The scalar to bitwise-and with . + /// The tensor to bitwise-and with . + /// A new tensor containing the result of & . + public static Tensor operator &(TScalar left, in ReadOnlyTensorSpan right) => BitwiseAnd(right, left); + } + + /// The type of the elements in the tensor. + extension(Tensor tensor) + where TScalar : IBitwiseOperators + { + /// + public static Tensor operator &(Tensor left, Tensor right) => BitwiseAnd(left, right); + + /// + public static Tensor operator &(Tensor left, TScalar right) => BitwiseAnd(left, right); + + /// + public static Tensor operator &(TScalar left, Tensor right) => BitwiseAnd(right, left); + + /// + public void operator &=(in ReadOnlyTensorSpan other) => BitwiseAnd(tensor, other, tensor); + + /// + public void operator &=(TScalar other) => BitwiseAnd(tensor, other, tensor); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(ref TensorSpan tensor) + where TScalar : IBitwiseOperators + { + /// + public static Tensor operator &(in TensorSpan left, in TensorSpan right) => BitwiseAnd(left, right); + + /// + public static Tensor operator &(in TensorSpan left, TScalar right) => BitwiseAnd(left, right); + + /// + public static Tensor operator &(TScalar left, in TensorSpan right) => BitwiseAnd(right, left); + + /// Performs in-place bitwise-and between two tensors. + /// The tensor to bitwise-and with the tensor being operated on. + public void operator &=(in ReadOnlyTensorSpan other) => BitwiseAnd(tensor, other, tensor); + + /// Performs in-place bitwise-and between a tensor and scalar. + /// The scalar to bitwise-and with the tensor being operated on. + public void operator &=(TScalar other) => BitwiseAnd(tensor, other, tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_BitwiseOr.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_BitwiseOr.cs new file mode 100644 index 00000000000000..f54f3600adeb12 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_BitwiseOr.cs @@ -0,0 +1,132 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs bitwise-or between two tensors. + /// The type of the elements in the tensor. + /// The tensor to bitwise-or with . + /// The tensor to bitwise-or with . + /// A new tensor containing the result of | . + /// The shapes of and are not compatible. + public static Tensor BitwiseOr(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) + where T : IBitwiseOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs bitwise-or between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor to bitwise-or with . + /// The scalar to bitwise-or with . + /// A new tensor containing the result of | . + public static Tensor BitwiseOr(in ReadOnlyTensorSpan x, T y) + where T : IBitwiseOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs bitwise-or between two tensors. + /// The type of the elements in the tensor. + /// The tensor to bitwise-or with . + /// The tensor to bitwise-or with . + /// The destination where the result of | is written. + /// A reference to . + /// The shapes of , , and are not compatible. + public static ref readonly TensorSpan BitwiseOr(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) + where T : IBitwiseOperators + { + TensorOperation.ValidateCompatibility(x, y, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// Performs bitwise-or between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor to bitwise-or with . + /// The scalar to bitwise-or with . + /// The destination where the result of | is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan BitwiseOr(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) + where T : IBitwiseOperators + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + extension(ReadOnlyTensorSpan) + where TScalar : IBitwiseOperators + { + /// Performs bitwise-or between two tensors. + /// The tensor to bitwise-or with . + /// The tensor to bitwise-or with . + /// A new tensor containing the result of | . + /// The shapes of and are not compatible. + public static Tensor operator |(in ReadOnlyTensorSpan left, in ReadOnlyTensorSpan right) => BitwiseOr(left, right); + + /// Performs bitwise-or between a tensor and scalar. + /// The tensor to bitwise-or with . + /// The scalar to bitwise-or with . + /// A new tensor containing the result of | . + public static Tensor operator |(in ReadOnlyTensorSpan left, TScalar right) => BitwiseOr(left, right); + + /// Performs bitwise-or between a tensor and scalar. + /// The scalar to bitwise-or with . + /// The tensor to bitwise-or with . + /// A new tensor containing the result of | . + public static Tensor operator |(TScalar left, in ReadOnlyTensorSpan right) => BitwiseOr(right, left); + } + + /// The type of the elements in the tensor. + extension(Tensor tensor) + where TScalar : IBitwiseOperators + { + /// + public static Tensor operator |(Tensor left, Tensor right) => BitwiseOr(left, right); + + /// + public static Tensor operator |(Tensor left, TScalar right) => BitwiseOr(left, right); + + /// + public static Tensor operator |(TScalar left, Tensor right) => BitwiseOr(right, left); + + /// + public void operator |=(in ReadOnlyTensorSpan other) => BitwiseOr(tensor, other, tensor); + + /// + public void operator |=(TScalar other) => BitwiseOr(tensor, other, tensor); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(ref TensorSpan tensor) + where TScalar : IBitwiseOperators + { + /// + public static Tensor operator |(in TensorSpan left, in TensorSpan right) => BitwiseOr(left, right); + + /// + public static Tensor operator |(in TensorSpan left, TScalar right) => BitwiseOr(left, right); + + /// + public static Tensor operator |(TScalar left, in TensorSpan right) => BitwiseOr(right, left); + + /// Performs in-place bitwise-or between two tensors. + /// The tensor to bitwise-or with the tensor being operated on. + public void operator |=(in ReadOnlyTensorSpan other) => BitwiseOr(tensor, other, tensor); + + /// Performs in-place bitwise-or between a tensor and scalar. + /// The scalar to bitwise-or with the tensor being operated on. + public void operator |=(TScalar other) => BitwiseOr(tensor, other, tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Decrement.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Decrement.cs new file mode 100644 index 00000000000000..dbeace8824cc05 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Decrement.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. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs an decrement on a tensor. + /// The type of the elements in the tensor. + /// The tensor to decrement. + /// A new tensor containing the result of --. + public static Tensor Decrement(in ReadOnlyTensorSpan x) + where T : IDecrementOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, T>(x, destination); + return destination; + } + + /// Performs an decrement on a tensor. + /// The type of the elements in the tensor. + /// The tensor to decrement. + /// The destination where the result of -- is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan Decrement(scoped in ReadOnlyTensorSpan x, in TensorSpan destination) + where T : IDecrementOperators + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, T>(x, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(Tensor tensor) + where TScalar : IDecrementOperators + { + /// + public void operator --() => Decrement(tensor, tensor); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(ref TensorSpan tensor) + where TScalar : IDecrementOperators + { + /// Performs in-place decrement on a tensor. + public void operator --() => Decrement(tensor, tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Division.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Division.cs new file mode 100644 index 00000000000000..7dc50d5959f349 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Division.cs @@ -0,0 +1,159 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs element-wise division between two tensors. + /// The type of the elements in the tensor. + /// The tensor dividend. + /// The tensor divisor. + /// A new tensor containing the result of / . + /// The shapes of and are not compatible. + public static Tensor Divide(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) + where T : IDivisionOperators + { + TensorOperation.ValidateCompatibility(x, y, out Tensor destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs element-wise division between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor dividend. + /// The scalar divisor. + /// A new tensor containing the result of / . + public static Tensor Divide(in ReadOnlyTensorSpan x, T y) + where T : IDivisionOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs element-wise division between a tensor and scalar. + /// The type of the elements in the tensor. + /// The scalar dividend. + /// The tensor divisor. + /// A new tensor containing the result of / . + public static Tensor Divide(T x, in ReadOnlyTensorSpan y) + where T : IDivisionOperators + { + Tensor destination = CreateFromShapeUninitialized(y.Lengths); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs element-wise division between two tensors. + /// The type of the elements in the tensor. + /// The tensor dividend. + /// The tensor divisor. + /// The destination where the result of / is written. + /// A reference to . + /// The shapes of , , and are not compatible. + public static ref readonly TensorSpan Divide(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) + where T : IDivisionOperators + { + TensorOperation.ValidateCompatibility(x, y, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// Performs element-wise division between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor dividend. + /// The scalar divisor. + /// The destination where the result of / is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan Divide(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) + where T : IDivisionOperators + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// Performs element-wise division between a tensor and scalar. + /// The type of the elements in the tensor. + /// The scalar dividend. + /// The tensor divisor. + /// The destination where the result of / is written. + /// The shapes of and are not compatible. + public static ref readonly TensorSpan Divide(T x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) + where T : IDivisionOperators + { + TensorOperation.ValidateCompatibility(y, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + extension(ReadOnlyTensorSpan) + where TScalar : IDivisionOperators + { + /// Performs element-wise division between two tensors. + /// The tensor dividend. + /// The tensor divisor. + /// A new tensor containing the result of / . + /// The shapes of and are not compatible. + public static Tensor operator /(in ReadOnlyTensorSpan left, in ReadOnlyTensorSpan right) => Divide(left, right); + + /// Performs element-wise division between a tensor and scalar. + /// The tensor dividend. + /// The scalar divisor. + /// A new tensor containing the result of / . + public static Tensor operator /(in ReadOnlyTensorSpan left, TScalar right) => Divide(left, right); + + /// Performs element-wise division between a tensor and scalar. + /// The scalar dividend. + /// The tensor divisor. + /// A new tensor containing the result of / . + public static Tensor operator /(TScalar left, in ReadOnlyTensorSpan right) => Divide(left, right); + } + + /// The type of the elements in the tensor. + extension(Tensor tensor) + where TScalar : IDivisionOperators + { + /// + public static Tensor operator /(Tensor left, Tensor right) => Divide(left, right); + + /// + public static Tensor operator /(Tensor left, TScalar right) => Divide(left, right); + + /// + public static Tensor operator /(TScalar left, Tensor right) => Divide(left, right); + + /// + public void operator /=(in ReadOnlyTensorSpan other) => Divide(tensor, other, tensor); + + /// + public void operator /=(TScalar other) => Divide(tensor, other, tensor); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(ref TensorSpan tensor) + where TScalar : IDivisionOperators + { + /// + public static Tensor operator /(in TensorSpan left, in TensorSpan right) => Divide(left, right); + + /// + public static Tensor operator /(in TensorSpan left, TScalar right) => Divide(left, right); + + /// + public static Tensor operator /(TScalar left, in TensorSpan right) => Divide(left, right); + + /// Performs in-place element-wise division between two tensors. + /// The tensor divisor. + public void operator /=(in ReadOnlyTensorSpan other) => Divide(tensor, other, tensor); + + /// Performs in-place element-wise division between a tensor and scalar. + /// The scalar divisor. + public void operator /=(TScalar other) => Divide(tensor, other, tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_ExclusiveOr.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_ExclusiveOr.cs new file mode 100644 index 00000000000000..867873be53aa24 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_ExclusiveOr.cs @@ -0,0 +1,132 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs exclusive-or between two tensors. + /// The type of the elements in the tensor. + /// The tensor to exclusive-or with . + /// The tensor to exclusive-or with . + /// A new tensor containing the result of ^ . + /// The shapes of and are not compatible. + public static Tensor Xor(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) + where T : IBitwiseOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs exclusive-or between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor to exclusive-or with . + /// The scalar to exclusive-or with . + /// A new tensor containing the result of ^ . + public static Tensor Xor(in ReadOnlyTensorSpan x, T y) + where T : IBitwiseOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs exclusive-or between two tensors. + /// The type of the elements in the tensor. + /// The tensor to exclusive-or with . + /// The tensor to exclusive-or with . + /// The destination where the result of ^ is written. + /// A reference to . + /// The shapes of , , and are not compatible. + public static ref readonly TensorSpan Xor(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) + where T : IBitwiseOperators + { + TensorOperation.ValidateCompatibility(x, y, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// Performs exclusive-or between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor to exclusive-or with . + /// The scalar to exclusive-or with . + /// The destination where the result of ^ is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan Xor(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) + where T : IBitwiseOperators + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + extension(ReadOnlyTensorSpan) + where TScalar : IBitwiseOperators + { + /// Performs exclusive-or between two tensors. + /// The tensor to exclusive-or with . + /// The tensor to exclusive-or with . + /// A new tensor containing the result of ^ . + /// The shapes of and are not compatible. + public static Tensor operator ^(in ReadOnlyTensorSpan left, in ReadOnlyTensorSpan right) => Xor(left, right); + + /// Performs exclusive-or between a tensor and scalar. + /// The tensor to exclusive-or with . + /// The scalar to exclusive-or with . + /// A new tensor containing the result of ^ . + public static Tensor operator ^(in ReadOnlyTensorSpan left, TScalar right) => Xor(left, right); + + /// Performs exclusive-or between a tensor and scalar. + /// The scalar to exclusive-or with . + /// The tensor to exclusive-or with . + /// A new tensor containing the result of ^ . + public static Tensor operator ^(TScalar left, in ReadOnlyTensorSpan right) => Xor(right, left); + } + + /// The type of the elements in the tensor. + extension(Tensor tensor) + where TScalar : IBitwiseOperators + { + /// + public static Tensor operator ^(Tensor left, Tensor right) => Xor(left, right); + + /// + public static Tensor operator ^(Tensor left, TScalar right) => Xor(left, right); + + /// + public static Tensor operator ^(TScalar left, Tensor right) => Xor(right, left); + + /// + public void operator ^=(in ReadOnlyTensorSpan other) => Xor(tensor, other, tensor); + + /// + public void operator ^=(TScalar other) => Xor(tensor, other, tensor); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(ref TensorSpan tensor) + where TScalar : IBitwiseOperators + { + /// + public static Tensor operator ^(in TensorSpan left, in TensorSpan right) => Xor(left, right); + + /// + public static Tensor operator ^(in TensorSpan left, TScalar right) => Xor(left, right); + + /// + public static Tensor operator ^(TScalar left, in TensorSpan right) => Xor(right, left); + + /// Performs in-place exclusive-or between two tensors. + /// The tensor to exclusive-or with the tensor being operated on. + public void operator ^=(in ReadOnlyTensorSpan other) => Xor(tensor, other, tensor); + + /// Performs in-place exclusive-or between a tensor and scalar. + /// The scalar to exclusive-or with the tensor being operated on. + public void operator ^=(TScalar other) => Xor(tensor, other, tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Increment.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Increment.cs new file mode 100644 index 00000000000000..5773aa51e86351 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Increment.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. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs an increment on a tensor. + /// The type of the elements in the tensor. + /// The tensor to increment. + /// A new tensor containing the result of ++. + public static Tensor Increment(in ReadOnlyTensorSpan x) + where T : IIncrementOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, T>(x, destination); + return destination; + } + + /// Performs an increment on a tensor. + /// The type of the elements in the tensor. + /// The tensor to increment. + /// The destination where the result of ++ is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan Increment(scoped in ReadOnlyTensorSpan x, in TensorSpan destination) + where T : IIncrementOperators + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, T>(x, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(Tensor tensor) + where TScalar : IIncrementOperators + { + /// + public void operator ++() => Increment(tensor, tensor); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(ref TensorSpan tensor) + where TScalar : IIncrementOperators + { + /// Performs in-place increment on a tensor. + public void operator ++() => Increment(tensor, tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_LeftShift.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_LeftShift.cs new file mode 100644 index 00000000000000..68f1e304e7c2f8 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_LeftShift.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs an element-wise left shift on a tensor. + /// The type of the elements in the tensor. + /// The tensor to left shift. + /// The amount to shift each element in . + /// A new tensor containing the result of << . + public static Tensor ShiftLeft(in ReadOnlyTensorSpan x, int shiftAmount) + where T : IShiftOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, int, T>(x, shiftAmount, destination); + return destination; + } + + /// Performs an element-wise left shift on a tensor. + /// The type of the elements in the tensor. + /// The tensor to left shift. + /// The amount to shift each element in . + /// The destination where the result of << is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan ShiftLeft(scoped in ReadOnlyTensorSpan x, int shiftAmount, in TensorSpan destination) + where T : IShiftOperators + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, int, T>(x, shiftAmount, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + extension(ReadOnlyTensorSpan) + where TScalar : IShiftOperators + { + /// Performs an element-wise left shift on a tensor. + /// The tensor to left shift. + /// The amount to shift each element in . + /// A new tensor containing the result of << . + public static Tensor operator <<(in ReadOnlyTensorSpan tensor, int shiftAmount) => ShiftLeft(tensor, shiftAmount); + } + + /// The type of the elements in the tensor. + extension(Tensor) + where TScalar : IShiftOperators + { + /// + public static Tensor operator <<(Tensor tensor, int shiftAmount) => ShiftLeft(tensor, shiftAmount); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(Tensor tensor) + where TScalar : IShiftOperators + { + /// + public void operator <<=(int shiftAmount) => ShiftLeft(tensor, shiftAmount, tensor); + } + + /// The type of the elements in the tensor. + extension(TensorSpan) + where TScalar : IShiftOperators + { + /// + public static Tensor operator <<(in TensorSpan tensor, int shiftAmount) => ShiftLeft(tensor, shiftAmount); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(ref TensorSpan tensor) + where TScalar : IShiftOperators + { + /// Performs in-place element-wise left shift on a tensor. + /// The amount to shift each element in the tensor. + public void operator <<=(int shiftAmount) => ShiftLeft(tensor, shiftAmount, tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Multiply.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Multiply.cs new file mode 100644 index 00000000000000..ca38d7b970a1f8 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Multiply.cs @@ -0,0 +1,132 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs element-wise multiplication between two tensors. + /// The type of the elements in the tensor. + /// The tensor to multiply with . + /// The tensor to multiply with . + /// A new tensor containing the result of * . + /// The shapes of and are not compatible. + public static Tensor Multiply(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) + where T : IMultiplyOperators, IMultiplicativeIdentity + { + TensorOperation.ValidateCompatibility(x, y, out Tensor destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs element-wise multiplication between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor to multiply with . + /// The scalar to multiply with . + /// A new tensor containing the result of * . + public static Tensor Multiply(in ReadOnlyTensorSpan x, T y) + where T : IMultiplyOperators, IMultiplicativeIdentity + { + Tensor destination = CreateFromShape(x.Lengths); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs element-wise multiplication between two tensors. + /// The type of the elements in the tensor. + /// The tensor to multiply with . + /// The tensor to multiply with . + /// The destination where the result of * is written. + /// A reference to . + /// The shapes of , , and are not compatible. + public static ref readonly TensorSpan Multiply(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) + where T : IMultiplyOperators, IMultiplicativeIdentity + { + TensorOperation.ValidateCompatibility(x, y, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// Performs element-wise multiplication between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor to multiply with . + /// The scalar to multiply with . + /// The destination where the result of * is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan Multiply(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) + where T : IMultiplyOperators, IMultiplicativeIdentity + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + extension(ReadOnlyTensorSpan) + where TScalar : IMultiplyOperators, System.Numerics.IMultiplicativeIdentity + { + /// Performs element-wise multiplication between two tensors. + /// The tensor to multiply with . + /// The tensor to multiply with . + /// A new tensor containing the result of * . + /// The shapes of and are not compatible. + public static Tensor operator *(in ReadOnlyTensorSpan left, in ReadOnlyTensorSpan right) => Multiply(left, right); + + /// Performs element-wise multiplication between a tensor and scalar. + /// The tensor to multiply with . + /// The scalar to multiply with . + /// A new tensor containing the result of * . + public static Tensor operator *(in ReadOnlyTensorSpan left, TScalar right) => Multiply(left, right); + + /// Performs element-wise multiplication between a tensor and scalar. + /// The scalar to multiply with . + /// The tensor to multiply with . + /// A new tensor containing the result of * . + public static Tensor operator *(TScalar left, in ReadOnlyTensorSpan right) => Multiply(right, left); + } + + /// The type of the elements in the tensor. + extension(Tensor tensor) + where TScalar : IMultiplyOperators, System.Numerics.IMultiplicativeIdentity + { + /// + public static Tensor operator *(Tensor left, Tensor right) => Multiply(left, right); + + /// + public static Tensor operator *(Tensor left, TScalar right) => Multiply(left, right); + + /// + public static Tensor operator *(TScalar left, Tensor right) => Multiply(right, left); + + /// + public void operator *=(in ReadOnlyTensorSpan other) => Multiply(tensor, other, tensor); + + /// + public void operator *=(TScalar other) => Multiply(tensor, other, tensor); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(ref TensorSpan tensor) + where TScalar : IMultiplyOperators, System.Numerics.IMultiplicativeIdentity + { + /// + public static Tensor operator *(in TensorSpan left, in TensorSpan right) => Multiply(left, right); + + /// + public static Tensor operator *(in TensorSpan left, TScalar right) => Multiply(left, right); + + /// + public static Tensor operator *(TScalar left, in TensorSpan right) => Multiply(right, left); + + /// Performs in-place element-wise multiplication between two tensors. + /// The tensor used to multiply the tensor being operated on. + public void operator *=(in ReadOnlyTensorSpan other) => Multiply(tensor, other, tensor); + + /// Performs in-place element-wise multiplication between a tensor and scalar. + /// The scalar used to multiply the tensor being operated on. + public void operator *=(TScalar other) => Multiply(tensor, other, tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_OnesComplement.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_OnesComplement.cs new file mode 100644 index 00000000000000..484a134d6548c6 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_OnesComplement.cs @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs a one's complement on a tensor. + /// The type of the elements in the tensor. + /// The tensor to one's complement. + /// A new tensor containing the result of ~. + public static Tensor OnesComplement(in ReadOnlyTensorSpan x) + where T : IBitwiseOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, T>(x, destination); + return destination; + } + + /// Performs a one's complement on a tensor. + /// The type of the elements in the tensor. + /// The tensor to one's complement. + /// The destination where the result of ~ is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan OnesComplement(scoped in ReadOnlyTensorSpan x, in TensorSpan destination) + where T : IBitwiseOperators + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, T>(x, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + extension(ReadOnlyTensorSpan) + where TScalar : IBitwiseOperators + { + /// Performs a one's complement on a tensor. + /// The tensor to one's complement. + /// A new tensor containing the result of ~. + public static Tensor operator ~(in ReadOnlyTensorSpan tensor) => OnesComplement(tensor); + } + + /// The type of the elements in the tensor. + extension(Tensor) + where TScalar : IBitwiseOperators + { + /// + public static Tensor operator ~(Tensor tensor) => OnesComplement(tensor); + } + + /// The type of the elements in the tensor. + extension(TensorSpan) + where TScalar : IBitwiseOperators + { + /// + public static Tensor operator ~(in TensorSpan tensor) => OnesComplement(tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_RightShift.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_RightShift.cs new file mode 100644 index 00000000000000..d61559441b96ec --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_RightShift.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs an element-wise arithmetic right shift on a tensor. + /// The type of the elements in the tensor. + /// The tensor to arithmetic right shift. + /// The amount to shift each element in . + /// A new tensor containing the result of >> . + public static Tensor ShiftRightArithmetic(in ReadOnlyTensorSpan x, int shiftAmount) + where T : IShiftOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, int, T>(x, shiftAmount, destination); + return destination; + } + + /// Performs an element-wise arithmetic right shift on a tensor. + /// The type of the elements in the tensor. + /// The tensor to arithmetic right shift. + /// The amount to shift each element in . + /// The destination where the result of >> is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan ShiftRightArithmetic(scoped in ReadOnlyTensorSpan x, int shiftAmount, in TensorSpan destination) + where T : IShiftOperators + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, int, T>(x, shiftAmount, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + extension(ReadOnlyTensorSpan) + where TScalar : IShiftOperators + { + /// Performs an element-wise arithmetic right shift on a tensor. + /// The tensor to arithmetic right shift. + /// The amount to shift each element in . + /// A new tensor containing the result of >> . + public static Tensor operator >>(in ReadOnlyTensorSpan tensor, int shiftAmount) => ShiftRightArithmetic(tensor, shiftAmount); + } + + /// The type of the elements in the tensor. + extension(Tensor) + where TScalar : IShiftOperators + { + /// + public static Tensor operator >>(Tensor tensor, int shiftAmount) => ShiftRightArithmetic(tensor, shiftAmount); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(Tensor tensor) + where TScalar : IShiftOperators + { + /// + public void operator >>=(int shiftAmount) => ShiftRightArithmetic(tensor, shiftAmount, tensor); + } + + /// The type of the elements in the tensor. + extension(TensorSpan) + where TScalar : IShiftOperators + { + /// + public static Tensor operator >>(in TensorSpan tensor, int shiftAmount) => ShiftRightArithmetic(tensor, shiftAmount); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(ref TensorSpan tensor) + where TScalar : IShiftOperators + { + /// Performs in-place element-wise arithmetic right shift on a tensor. + /// The amount to shift each element in the tensor. + public void operator >>=(int shiftAmount) => ShiftRightArithmetic(tensor, shiftAmount, tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Subtraction.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Subtraction.cs new file mode 100644 index 00000000000000..dd8ea6c028e0b9 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_Subtraction.cs @@ -0,0 +1,160 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs element-wise subtraction between two tensors. + /// The type of the elements in the tensor. + /// The tensor from which to subtract . + /// The tensor to subtract from . + /// A new tensor containing the result of - . + /// The shapes of and are not compatible. + public static Tensor Subtract(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) + where T : ISubtractionOperators + { + TensorOperation.ValidateCompatibility(x, y, out Tensor destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs element-wise subtraction between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor from which to subtract . + /// The scalar to subtract from . + /// A new tensor containing the result of - . + public static Tensor Subtract(in ReadOnlyTensorSpan x, T y) + where T : ISubtractionOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs element-wise subtraction between a tensor and scalar. + /// The type of the elements in the tensor. + /// The scalar from which to subtract . + /// The tensor to subtract from . + /// A new tensor containing the result of - . + public static Tensor Subtract(T x, in ReadOnlyTensorSpan y) + where T : ISubtractionOperators + { + Tensor destination = CreateFromShapeUninitialized(y.Lengths); + TensorOperation.Invoke, T, T>(x, y, destination); + return destination; + } + + /// Performs element-wise subtraction between two tensors. + /// The type of the elements in the tensor. + /// The tensor from which to subtract . + /// The tensor to subtract from . + /// The destination where the result of - is written. + /// A reference to . + /// The shapes of , , and are not compatible. + public static ref readonly TensorSpan Subtract(scoped in ReadOnlyTensorSpan x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) + where T : ISubtractionOperators + { + TensorOperation.ValidateCompatibility(x, y, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// Performs element-wise subtraction between a tensor and scalar. + /// The type of the elements in the tensor. + /// The tensor from which to subtract . + /// The scalar to subtract from . + /// The destination where the result of - is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan Subtract(scoped in ReadOnlyTensorSpan x, T y, in TensorSpan destination) + where T : ISubtractionOperators + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// Performs element-wise subtraction between a tensor and scalar. + /// The type of the elements in the tensor. + /// The scalar from which to subtract . + /// The tensor to subtract from . + /// The destination where the result of - is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan Subtract(T x, scoped in ReadOnlyTensorSpan y, in TensorSpan destination) + where T : ISubtractionOperators + { + TensorOperation.ValidateCompatibility(y, destination); + TensorOperation.Invoke, T, T>(x, y, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + extension(ReadOnlyTensorSpan) + where TScalar : ISubtractionOperators + { + /// Performs element-wise subtraction between two tensors. + /// The tensor from which to subtract . + /// The tensor to subtract from . + /// A new tensor containing the result of - . + /// The shapes of and are not compatible. + public static Tensor operator -(in ReadOnlyTensorSpan left, in ReadOnlyTensorSpan right) => Subtract(left, right); + + /// Performs element-wise subtraction between a tensor and scalar. + /// The tensor from which to subtract . + /// The scalar to subtract from . + /// A new tensor containing the result of - . + public static Tensor operator -(in ReadOnlyTensorSpan left, TScalar right) => Subtract(left, right); + + /// Performs element-wise subtraction between a tensor and scalar. + /// The scalar from which to subtract . + /// The tensor to subtract from . + /// A new tensor containing the result of - . + public static Tensor operator -(TScalar left, in ReadOnlyTensorSpan right) => Subtract(left, right); + } + + /// The type of the elements in the tensor. + extension(Tensor tensor) + where TScalar : ISubtractionOperators + { + /// + public static Tensor operator -(Tensor left, Tensor right) => Subtract(left, right); + + /// + public static Tensor operator -(Tensor left, TScalar right) => Subtract(left, right); + + /// + public static Tensor operator -(TScalar left, Tensor right) => Subtract(left, right); + + /// + public void operator -=(in ReadOnlyTensorSpan other) => Subtract(tensor, other, tensor); + + /// + public void operator -=(TScalar other) => Subtract(tensor, other, tensor); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(ref TensorSpan tensor) + where TScalar : ISubtractionOperators + { + /// + public static Tensor operator -(in TensorSpan left, in TensorSpan right) => Subtract(left, right); + + /// + public static Tensor operator -(in TensorSpan left, TScalar right) => Subtract(left, right); + + /// + public static Tensor operator -(TScalar left, in TensorSpan right) => Subtract(left, right); + + /// Performs in-place element-wise subtraction between two tensors. + /// The tensor to subtract from the tensor being operated on. + public void operator -=(in ReadOnlyTensorSpan other) => Subtract(tensor, other, tensor); + + /// Performs in-place element-wise subtraction between a tensor and scalar. + /// The scalar to subtract from the tensor being operated on. + public void operator -=(TScalar other) => Subtract(tensor, other, tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_UnaryNegation.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_UnaryNegation.cs new file mode 100644 index 00000000000000..261ed655688352 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_UnaryNegation.cs @@ -0,0 +1,58 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs element-wise unary negation on a tensor. + /// The tensor to negate. + /// A new tensor containing the result of -. + public static Tensor Negate(in ReadOnlyTensorSpan x) + where T : IUnaryNegationOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, T>(x, destination); + return destination; + } + + /// Performs element-wise unary negation on a tensor. + /// The tensor to negate. + /// The destination where the result of - is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan Negate(scoped in ReadOnlyTensorSpan x, in TensorSpan destination) + where T : IUnaryNegationOperators + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, T>(x, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + extension(ReadOnlyTensorSpan) + where TScalar : IUnaryNegationOperators + { + /// Performs element-wise unary negation on a tensor. + /// The tensor to negate. + /// A new tensor containing the result of -. + public static Tensor operator -(in ReadOnlyTensorSpan tensor) => Negate(tensor); + } + + /// The type of the elements in the tensor. + extension(Tensor) + where TScalar : IUnaryNegationOperators + { + /// + public static Tensor operator -(Tensor tensor) => Negate(tensor); + } + + /// The type of the elements in the tensor. + extension(TensorSpan) + where TScalar : IUnaryNegationOperators + { + /// + public static Tensor operator -(in TensorSpan tensor) => Negate(tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_UnaryPlus.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_UnaryPlus.cs new file mode 100644 index 00000000000000..db11f6d750c962 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_UnaryPlus.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// The type of the elements in the tensor. + extension(ReadOnlyTensorSpan) + where TScalar : IUnaryPlusOperators + { + /// Performs element-wise unary plus on a tensor. + /// The tensor to return. + /// + public static ReadOnlyTensorSpan operator +(in ReadOnlyTensorSpan tensor) => tensor; + } + + /// The type of the elements in the tensor. + extension(Tensor) + where TScalar : IUnaryPlusOperators + { + /// + public static Tensor operator +(Tensor tensor) => tensor; + } + + /// The type of the elements in the tensor. + extension(TensorSpan) + where TScalar : IUnaryPlusOperators + { + /// + public static TensorSpan operator +(in TensorSpan tensor) => tensor; + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_UnsignedRightShift.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_UnsignedRightShift.cs new file mode 100644 index 00000000000000..19147047592fe0 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.op_UnsignedRightShift.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Numerics.Tensors +{ + public static partial class Tensor + { + /// Performs an element-wise logical right shift on a tensor. + /// The type of the elements in the tensor. + /// The tensor to logical right shift. + /// The amount to shift each element in . + /// A new tensor containing the result of >>> . + public static Tensor ShiftRightLogical(in ReadOnlyTensorSpan x, int shiftAmount) + where T : IShiftOperators + { + Tensor destination = CreateFromShapeUninitialized(x.Lengths); + TensorOperation.Invoke, T, int, T>(x, shiftAmount, destination); + return destination; + } + + /// Performs an element-wise logical right shift on a tensor. + /// The type of the elements in the tensor. + /// The tensor to logical right shift. + /// The amount to shift each element in . + /// The destination where the result of >>> is written. + /// A reference to . + /// The shapes of and are not compatible. + public static ref readonly TensorSpan ShiftRightLogical(scoped in ReadOnlyTensorSpan x, int shiftAmount, in TensorSpan destination) + where T : IShiftOperators + { + TensorOperation.ValidateCompatibility(x, destination); + TensorOperation.Invoke, T, int, T>(x, shiftAmount, destination); + return ref destination; + } + + /// The type of the elements in the tensor. + extension(ReadOnlyTensorSpan) + where TScalar : IShiftOperators + { + /// Performs an element-wise logical right shift on a tensor. + /// The tensor to logical right shift. + /// The amount to shift each element in . + /// A new tensor containing the result of >>> . + public static Tensor operator >>>(in ReadOnlyTensorSpan tensor, int shiftAmount) => ShiftRightLogical(tensor, shiftAmount); + } + + /// The type of the elements in the tensor. + extension(Tensor) + where TScalar : IShiftOperators + { + /// + public static Tensor operator >>>(Tensor tensor, int shiftAmount) => ShiftRightLogical(tensor, shiftAmount); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(Tensor tensor) + where TScalar : IShiftOperators + { + /// + public void operator >>>=(int shiftAmount) => ShiftRightLogical(tensor, shiftAmount, tensor); + } + + /// The type of the elements in the tensor. + extension(TensorSpan) + where TScalar : IShiftOperators + { + /// + public static Tensor operator >>>(in TensorSpan tensor, int shiftAmount) => ShiftRightLogical(tensor, shiftAmount); + } + + /// The type of the elements in the tensor. + /// The tensor to operate on. + extension(ref TensorSpan tensor) + where TScalar : IShiftOperators + { + /// Performs in-place element-wise logical right shift on a tensor. + /// The amount to shift each element in the tensor. + public void operator >>>=(int shiftAmount) => ShiftRightLogical(tensor, shiftAmount, tensor); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorDimensionSpan_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorDimensionSpan_1.cs index 0823dbb638f49a..651f2ff9a29511 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorDimensionSpan_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorDimensionSpan_1.cs @@ -48,7 +48,7 @@ public TensorSpan this[nint index] ThrowHelper.ThrowArgumentOutOfRangeException(); } - nint linearOffset = _tensor._shape.GetLinearOffset(index, _dimension); + nint linearOffset = _tensor._shape.GetLinearOffsetForDimension(index, _dimension); return new TensorSpan(ref Unsafe.Add(ref _tensor._reference, linearOffset), _sliceShape); } } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorOperation.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorOperation.cs index fa983d5fff8581..227a8d95db58ed 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorOperation.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorOperation.cs @@ -363,11 +363,11 @@ public static void ValidateCompatibility(in ReadOnlyTensorSpan y.Rank) { - destination = Tensor.CreateUninitialized(x._shape.Lengths); + destination = Tensor.CreateFromShapeUninitialized(x._shape.Lengths); } else { - destination = Tensor.CreateUninitialized(y._shape.Lengths); + destination = Tensor.CreateFromShapeUninitialized(y._shape.Lengths); } return; } @@ -949,6 +949,22 @@ public static void Invoke(ReadOnlySpan x, Span destination) } } + public readonly struct Decrement + : IUnaryOperation_Tensor + where T : IDecrementOperators + { + public static void Invoke(ref readonly T x, ref T destination) + { + T tmp = x; + destination = --tmp; + } + + public static void Invoke(ReadOnlySpan x, Span destination) + { + TensorPrimitives.Decrement(x, destination); + } + } + public readonly struct DegreesToRadians : IUnaryOperation_Tensor where T : ITrigonometricFunctions @@ -1186,6 +1202,22 @@ public static void Invoke(ReadOnlySpan x, Span destination) } } + public readonly struct Increment + : IUnaryOperation_Tensor + where T : IIncrementOperators + { + public static void Invoke(ref readonly T x, ref T destination) + { + T tmp = x; + destination = ++tmp; + } + + public static void Invoke(ReadOnlySpan x, Span destination) + { + TensorPrimitives.Increment(x, destination); + } + } + public readonly struct LeadingZeroCount : IUnaryOperation_Tensor where T : IBinaryInteger @@ -1831,6 +1863,51 @@ public static void Invoke(ReadOnlySpan x, Tuple y, Spa } } + public readonly struct ShiftLeft + : IBinaryOperation_Tensor_Scalar + where T : IShiftOperators + { + public static void Invoke(ref readonly T x, int shiftAmount, ref T destination) + { + destination = x << shiftAmount; + } + + public static void Invoke(ReadOnlySpan x, int shiftAmount, Span destination) + { + TensorPrimitives.ShiftLeft(x, shiftAmount, destination); + } + } + + public readonly struct ShiftRightArithmetic + : IBinaryOperation_Tensor_Scalar + where T : IShiftOperators + { + public static void Invoke(ref readonly T x, int shiftAmount, ref T destination) + { + destination = x >> shiftAmount; + } + + public static void Invoke(ReadOnlySpan x, int shiftAmount, Span destination) + { + TensorPrimitives.ShiftRightArithmetic(x, shiftAmount, destination); + } + } + + public readonly struct ShiftRightLogical + : IBinaryOperation_Tensor_Scalar + where T : IShiftOperators + { + public static void Invoke(ref readonly T x, int shiftAmount, ref T destination) + { + destination = x >>> shiftAmount; + } + + public static void Invoke(ReadOnlySpan x, int shiftAmount, Span destination) + { + TensorPrimitives.ShiftRightLogical(x, shiftAmount, destination); + } + } + public readonly struct Sigmoid : IUnaryOperation_Tensor where T : IExponentialFunctions diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Average.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Average.cs index 5568a3171c0f3f..eef82d2d7890e5 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Average.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Average.cs @@ -1,9 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Runtime.Intrinsics; - namespace System.Numerics.Tensors { public static partial class TensorPrimitives diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Clamp.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Clamp.cs index 8644da0d21773d..8d2a9423841c39 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Clamp.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Clamp.cs @@ -1,9 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ConvertHelpers.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ConvertHelpers.cs index 873293a2befb0e..15402d63fb6543 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ConvertHelpers.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ConvertHelpers.cs @@ -1,9 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Cos.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Cos.cs index c6c7408a7228df..e01c5ef71a0650 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Cos.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Cos.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Runtime.Intrinsics; -using static System.Numerics.Tensors.TensorOperation; namespace System.Numerics.Tensors { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsCanonical.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsCanonical.cs index 3336d4daa72678..e06c7a1a23c227 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsCanonical.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsCanonical.cs @@ -1,10 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsComplexNumber.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsComplexNumber.cs index 321d560e250da9..21da23319199eb 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsComplexNumber.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsComplexNumber.cs @@ -1,10 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsEvenInteger.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsEvenInteger.cs index a8a8455bb0cbdf..e3f46b3a32a547 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsEvenInteger.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsEvenInteger.cs @@ -1,12 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using System.Runtime.Intrinsics.X86; namespace System.Numerics.Tensors { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsFinite.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsFinite.cs index 89ab0e952a3add..cbd0fd74521a2a 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsFinite.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsFinite.cs @@ -1,10 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsImaginaryNumber.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsImaginaryNumber.cs index efaa350165d723..bbecc4681892d3 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsImaginaryNumber.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsImaginaryNumber.cs @@ -1,10 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsInfinity.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsInfinity.cs index a11cfa47d0190c..48efcf69299687 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsInfinity.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsInfinity.cs @@ -1,10 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsInteger.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsInteger.cs index c9d6ce2c1ba713..e24bf2c355418d 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsInteger.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsInteger.cs @@ -1,9 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNaN.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNaN.cs index 156e609c6c24dd..dab9118573a69f 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNaN.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNaN.cs @@ -1,10 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNegative.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNegative.cs index 03a68e4a11375d..86b062b91c5762 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNegative.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNegative.cs @@ -1,9 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNegativeInfinity.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNegativeInfinity.cs index f76ed577debca1..c48c0f67209f13 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNegativeInfinity.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNegativeInfinity.cs @@ -1,10 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNormal.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNormal.cs index cc3b8825de4244..636cd276632cfa 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNormal.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsNormal.cs @@ -1,9 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsOddInteger.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsOddInteger.cs index 92d6a09b84649c..f28f06042e4abf 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsOddInteger.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsOddInteger.cs @@ -1,12 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using System.Runtime.Intrinsics.X86; namespace System.Numerics.Tensors { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsPositive.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsPositive.cs index e3ff34cfe09784..0547de34ebb86f 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsPositive.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsPositive.cs @@ -1,9 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsPositiveInfinity.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsPositiveInfinity.cs index 0f056e055a5dc3..9fe5852e293f6e 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsPositiveInfinity.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsPositiveInfinity.cs @@ -1,10 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsPow2.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsPow2.cs index a32ee72c938e51..7759835d244402 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsPow2.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsPow2.cs @@ -1,9 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsRealNumber.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsRealNumber.cs index c6e9a116468325..8c5e9a9877c7db 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsRealNumber.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsRealNumber.cs @@ -1,10 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsSubnormal.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsSubnormal.cs index ecc1fb6b48997a..a25398121fb0fc 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsSubnormal.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsSubnormal.cs @@ -1,10 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsZero.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsZero.cs index 1fd5528af6c2ec..eaca0c55dc73cf 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsZero.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.IsZero.cs @@ -1,9 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Max.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Max.cs index 411ef98646854f..b47d4b54f9d02c 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Max.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Max.cs @@ -1,11 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; namespace System.Numerics.Tensors { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MaxNumber.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MaxNumber.cs index 05dcd9b8bbbf5c..8b199b197b38a9 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MaxNumber.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MaxNumber.cs @@ -2,10 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using System.Runtime.Intrinsics.X86; namespace System.Numerics.Tensors { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Min.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Min.cs index cfbbb70b94e753..eddf59d22bf36a 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Min.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Min.cs @@ -3,7 +3,6 @@ using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; namespace System.Numerics.Tensors { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MinNumber.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MinNumber.cs index 36ddc54b632c9c..24200d6737d89d 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MinNumber.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MinNumber.cs @@ -2,10 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using System.Runtime.Intrinsics.X86; namespace System.Numerics.Tensors { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MultiplyAddEstimate.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MultiplyAddEstimate.cs index 0ddce9353120e7..007d51b64b95cb 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MultiplyAddEstimate.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MultiplyAddEstimate.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.Arm; diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Round.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Round.cs index 8460da945b1164..e853c28e0467c8 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Round.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Round.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.Arm; diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ShiftLeft.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ShiftLeft.cs index 22d5ea4c268679..63b3ee4d101ee4 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ShiftLeft.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ShiftLeft.cs @@ -22,36 +22,6 @@ public static void ShiftLeft(ReadOnlySpan x, int shiftAmount, Span dest where T : IShiftOperators => InvokeSpanIntoSpan(x, new ShiftLeftOperator(shiftAmount), destination); - /// Computes the element-wise arithmetic (signed) shifting right of numbers in the specified tensor by the specified shift amount. - /// The tensor, represented as a span. - /// The destination tensor, represented as a span. - /// The number of bits to shift, represented as a scalar. - /// Destination is too short. - /// and reference overlapping memory locations and do not begin at the same location. - /// - /// - /// This method effectively computes [i] = [i] >> . - /// - /// - public static void ShiftRightArithmetic(ReadOnlySpan x, int shiftAmount, Span destination) - where T : IShiftOperators => - InvokeSpanIntoSpan(x, new ShiftRightArithmeticOperator(shiftAmount), destination); - - /// Computes the element-wise logical (unsigned) shifting right of numbers in the specified tensor by the specified shift amount. - /// The tensor, represented as a span. - /// The destination tensor, represented as a span. - /// The number of bits to shift, represented as a scalar. - /// Destination is too short. - /// and reference overlapping memory locations and do not begin at the same location. - /// - /// - /// This method effectively computes [i] = [i] >>> . - /// - /// - public static void ShiftRightLogical(ReadOnlySpan x, int shiftAmount, Span destination) - where T : IShiftOperators => - InvokeSpanIntoSpan(x, new ShiftRightLogicalOperator(shiftAmount), destination); - /// T << amount private readonly struct ShiftLeftOperator(int amount) : IStatefulUnaryOperator where T : IShiftOperators { @@ -64,31 +34,5 @@ private readonly struct ShiftLeftOperator(int amount) : IStatefulUnaryOperato public Vector256 Invoke(Vector256 x) => x << _amount; public Vector512 Invoke(Vector512 x) => x << _amount; } - - /// T >> amount - private readonly struct ShiftRightArithmeticOperator(int amount) : IStatefulUnaryOperator where T : IShiftOperators - { - private readonly int _amount = amount; - - public static bool Vectorizable => true; - - public T Invoke(T x) => x >> _amount; - public Vector128 Invoke(Vector128 x) => x >> _amount; - public Vector256 Invoke(Vector256 x) => x >> _amount; - public Vector512 Invoke(Vector512 x) => x >> _amount; - } - - /// T >>> amount - private readonly struct ShiftRightLogicalOperator(int amount) : IStatefulUnaryOperator where T : IShiftOperators - { - private readonly int _amount = amount; - - public static bool Vectorizable => true; - - public T Invoke(T x) => x >>> _amount; - public Vector128 Invoke(Vector128 x) => x >>> _amount; - public Vector256 Invoke(Vector256 x) => x >>> _amount; - public Vector512 Invoke(Vector512 x) => x >>> _amount; - } } } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ShiftRightArithmetic.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ShiftRightArithmetic.cs new file mode 100644 index 00000000000000..26c5bbe388e6cd --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ShiftRightArithmetic.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. + +using System.Runtime.Intrinsics; + +namespace System.Numerics.Tensors +{ + public static partial class TensorPrimitives + { + /// Computes the element-wise arithmetic (signed) shifting right of numbers in the specified tensor by the specified shift amount. + /// The tensor, represented as a span. + /// The destination tensor, represented as a span. + /// The number of bits to shift, represented as a scalar. + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = [i] >> . + /// + /// + public static void ShiftRightArithmetic(ReadOnlySpan x, int shiftAmount, Span destination) + where T : IShiftOperators => + InvokeSpanIntoSpan(x, new ShiftRightArithmeticOperator(shiftAmount), destination); + + /// T >> amount + private readonly struct ShiftRightArithmeticOperator(int amount) : IStatefulUnaryOperator where T : IShiftOperators + { + private readonly int _amount = amount; + + public static bool Vectorizable => true; + + public T Invoke(T x) => x >> _amount; + public Vector128 Invoke(Vector128 x) => x >> _amount; + public Vector256 Invoke(Vector256 x) => x >> _amount; + public Vector512 Invoke(Vector512 x) => x >> _amount; + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ShiftRightLogical.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ShiftRightLogical.cs new file mode 100644 index 00000000000000..0b720c8e9fbf92 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ShiftRightLogical.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. + +using System.Runtime.Intrinsics; + +namespace System.Numerics.Tensors +{ + public static partial class TensorPrimitives + { + /// Computes the element-wise logical (unsigned) shifting right of numbers in the specified tensor by the specified shift amount. + /// The tensor, represented as a span. + /// The destination tensor, represented as a span. + /// The number of bits to shift, represented as a scalar. + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = [i] >>> . + /// + /// + public static void ShiftRightLogical(ReadOnlySpan x, int shiftAmount, Span destination) + where T : IShiftOperators => + InvokeSpanIntoSpan(x, new ShiftRightLogicalOperator(shiftAmount), destination); + + /// T >>> amount + private readonly struct ShiftRightLogicalOperator(int amount) : IStatefulUnaryOperator where T : IShiftOperators + { + private readonly int _amount = amount; + + public static bool Vectorizable => true; + + public T Invoke(T x) => x >>> _amount; + public Vector128 Invoke(Vector128 x) => x >>> _amount; + public Vector256 Invoke(Vector256 x) => x >>> _amount; + public Vector512 Invoke(Vector512 x) => x >>> _amount; + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Sign.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Sign.cs index 8481d50a08974e..b037352a70ab52 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Sign.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Sign.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using System.Reflection.Metadata.Ecma335; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.StdDev.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.StdDev.cs index 0a6b077825b5f7..98f50578f4e71f 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.StdDev.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.StdDev.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.Runtime.Intrinsics; namespace System.Numerics.Tensors diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorShape.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorShape.cs index e1c560dc91d30e..1e4a1ccbe6c0e1 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorShape.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorShape.cs @@ -2,14 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers; -using System.Collections; -using System.Collections.Generic; -using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Linq; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; namespace System.Numerics.Tensors { @@ -909,9 +904,9 @@ public static TensorShape Create(T[]? array, int start, scoped ReadOnlySpan(ref T reference, nint linearLength, bool pinned) + public static TensorShape Create(ref readonly T reference, nint linearLength, bool pinned) { - if (!Unsafe.IsNullRef(ref reference)) + if (!Unsafe.IsNullRef(in reference)) { TensorFlags flags = pinned ? TensorFlags.IsPinned : TensorFlags.None; flags |= TensorFlags.IsDense | TensorFlags.HasAnyDenseDimensions; @@ -931,9 +926,9 @@ public static TensorShape Create(ref T reference, nint linearLength, bool pin return default; } - public static TensorShape Create(ref T reference, nint linearLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) + public static TensorShape Create(ref readonly T reference, nint linearLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) { - if (!Unsafe.IsNullRef(ref reference)) + if (!Unsafe.IsNullRef(in reference)) { TensorFlags flags = pinned ? TensorFlags.IsPinned : TensorFlags.None; return new TensorShape(linearLength, lengths, strides, flags); @@ -1006,7 +1001,7 @@ public nint GetLinearOffset(ReadOnlySpan state) return linearOffset; } - public nint GetLinearOffset(nint index, int dimension) + public nint GetLinearOffsetForDimension(nint index, int dimension) { ReadOnlySpan lengths = Lengths; ReadOnlySpan strides = Strides; @@ -1031,6 +1026,66 @@ public nint GetLinearOffset(nint index, int dimension) return linearOffset; } + public nint GetLongestContiguousLength(ReadOnlySpan state, out nint linearOffset) + where TGetOffsetAndLength : IGetOffsetAndLength + { + int rank = Rank; + + ReadOnlySpan lengths = Lengths; + ReadOnlySpan strides = Strides; + + if ((state.Length != lengths.Length) || + (state.Length != strides.Length)) + { + ThrowHelper.ThrowArgumentOutOfRangeException(); + } + + nint maximumLinearIndex = 0; + nint minimumNonZeroStride = 1; + + nint computedOffset = 0; + nint longestContiguousLength = -1; + + // This is effectively a simplification of the slice algorithm. Rather than initializing a shape + // and tracking the necessary data for that, it simply sets the longest contiguous length to one + // greater than the maximum linear index at the point we are no longer considered dense. + + for (int n = 0; n < rank; n++) + { + int i = rank - (n + 1); + + (nint offset, nint length) = TGetOffsetAndLength.GetOffsetAndLength(state[i], lengths[i]); + + nint stride = strides[i]; + nint adjustedStride = (length > 1) ? stride : 0; + + if (adjustedStride != 0) + { + if ((adjustedStride != minimumNonZeroStride) && (longestContiguousLength == -1)) + { + // We have a gap in the data, so we are no longer dense. + longestContiguousLength = maximumLinearIndex + 1; + } + maximumLinearIndex += ((length - 1) * adjustedStride); + } + else if ((length != 1) && (longestContiguousLength == -1)) + { + // We are no longer dense since we have a broadcast to more than 1 element + longestContiguousLength = maximumLinearIndex + 1; + } + minimumNonZeroStride = adjustedStride * length; + + computedOffset += (offset * stride); + } + linearOffset = computedOffset; + + if (longestContiguousLength == -1) + { + longestContiguousLength = maximumLinearIndex + 1; + } + return longestContiguousLength; + } + public TensorShape Slice(ReadOnlySpan state, out nint linearOffset) where TGetOffsetAndLength : IGetOffsetAndLength { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanDebugView.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanDebugView.cs index 3a420c18ff2059..ab6073a52341ac 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanDebugView.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanDebugView.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; namespace System.Numerics.Tensors { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan_1.cs index de7904a341bc35..e13655b0ca15dc 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan_1.cs @@ -278,6 +278,26 @@ public ref T GetPinnableReference() return ref ret; } + /// + public Span GetSpan(scoped ReadOnlySpan startIndexes, int length) + { + if (!TryGetSpan(startIndexes, length, out Span span)) + { + ThrowHelper.ThrowArgumentOutOfRangeException(); + } + return span; + } + + /// + public Span GetSpan(scoped ReadOnlySpan startIndexes, int length) + { + if (!TryGetSpan(startIndexes, length, out Span span)) + { + ThrowHelper.ThrowArgumentOutOfRangeException(); + } + return span; + } + /// public TensorSpan Slice(params scoped ReadOnlySpan startIndexes) { @@ -308,8 +328,11 @@ ref Unsafe.Add(ref _reference, linearOffset), ); } - /// - public override string ToString() => $"System.Numerics.Tensors.TensorSpan<{typeof(T).Name}>[{_shape}]"; + /// + public override string ToString() => ToString([]); + + /// + public string ToString(params scoped ReadOnlySpan maximumLengths) => Tensor.ToString(AsReadOnlyTensorSpan(), maximumLengths, "System.Numerics.Tensors.TensorSpan"); /// public bool TryCopyTo(scoped in TensorSpan destination) => AsReadOnlyTensorSpan().TryCopyTo(destination); @@ -317,6 +340,44 @@ ref Unsafe.Add(ref _reference, linearOffset), /// public bool TryFlattenTo(scoped Span destination) => AsReadOnlyTensorSpan().TryFlattenTo(destination); + /// + public bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out Span span) + { + // This validates that startIndexes is valid and will throw ArgumentOutOfRangeException or IndexOutOfRangeException if it is not. + nint longestContiguousLength = _shape.GetLongestContiguousLength(startIndexes, out nint linearOffset); + + if ((length < 0) || (length > longestContiguousLength)) + { + span = default; + return false; + } + + span = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref _reference, linearOffset), length); + return true; + } + + /// + public bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out Span span) + { + // This validates that startIndexes is valid and will throw ArgumentOutOfRangeException or IndexOutOfRangeException if it is not. + nint longestContiguousLength = _shape.GetLongestContiguousLength(startIndexes, out nint linearOffset); + + if ((length < 0) || (length > longestContiguousLength)) + { + span = default; + return false; + } + + span = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref _reference, linearOffset), length); + return true; + } + + /// + public bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out ReadOnlySpan span) => AsReadOnlyTensorSpan().TryGetSpan(startIndexes, length, out span); + + /// + public bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out ReadOnlySpan span) => AsReadOnlyTensorSpan().TryGetSpan(startIndexes, length, out span); + #if NET9_0_OR_GREATER // // IReadOnlyTensor @@ -338,13 +399,17 @@ ref Unsafe.Add(ref _reference, linearOffset), ref readonly T IReadOnlyTensor, T>.GetPinnableReference() => ref GetPinnableReference(); + ReadOnlySpan IReadOnlyTensor, T>.GetSpan(scoped ReadOnlySpan startIndexes, int length) => AsReadOnlyTensorSpan().GetSpan(startIndexes, length); + + ReadOnlySpan IReadOnlyTensor, T>.GetSpan(scoped ReadOnlySpan startIndexes, int length) => AsReadOnlyTensorSpan().GetSpan(startIndexes, length); + TensorSpan IReadOnlyTensor, T>.ToDenseTensor() { TensorSpan result = this; if (!IsDense) { - result = Tensor.Create(Lengths, IsPinned); + result = Tensor.CreateFromShape(Lengths, IsPinned); CopyTo(result); } @@ -383,13 +448,13 @@ TensorSpan IReadOnlyTensor, T>.ToDenseTensor() // ITensor // - static TensorSpan ITensor, T>.Create(scoped ReadOnlySpan lengths, bool pinned) => Tensor.Create(lengths, pinned); + static TensorSpan ITensor, T>.CreateFromShape(scoped ReadOnlySpan lengths, bool pinned) => Tensor.CreateFromShape(lengths, pinned); - static TensorSpan ITensor, T>.Create(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) => Tensor.Create(lengths, strides, pinned); + static TensorSpan ITensor, T>.CreateFromShape(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) => Tensor.CreateFromShape(lengths, strides, pinned); - static TensorSpan ITensor, T>.CreateUninitialized(scoped ReadOnlySpan lengths, bool pinned) => Tensor.CreateUninitialized(lengths, pinned); + static TensorSpan ITensor, T>.CreateFromShapeUninitialized(scoped ReadOnlySpan lengths, bool pinned) => Tensor.CreateFromShapeUninitialized(lengths, pinned); - static TensorSpan ITensor, T>.CreateUninitialized(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) => Tensor.CreateUninitialized(lengths, strides, pinned); + static TensorSpan ITensor, T>.CreateFromShapeUninitialized(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) => Tensor.CreateFromShapeUninitialized(lengths, strides, pinned); TensorSpan ITensor, T>.AsTensorSpan() => this; diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor_1.cs index 5bcddc999fdcc8..b475cd2a2e66e4 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor_1.cs @@ -197,6 +197,12 @@ public ref T GetPinnableReference() return ref ret; } + /// + public Span GetSpan(scoped ReadOnlySpan startIndexes, int length) => AsTensorSpan().GetSpan(startIndexes, length); + + /// + public Span GetSpan(scoped ReadOnlySpan startIndexes, int length) => AsTensorSpan().GetSpan(startIndexes, length); + /// Pins and gets a to the backing memory. /// public unsafe MemoryHandle GetPinnedHandle() @@ -257,7 +263,7 @@ public Tensor ToDenseTensor() if (!IsDense) { - result = Tensor.Create(Lengths, IsPinned); + result = Tensor.CreateFromShape(Lengths, IsPinned); CopyTo(result); } @@ -270,21 +276,23 @@ public Tensor ToDenseTensor() /// public bool TryFlattenTo(scoped Span destination) => AsReadOnlyTensorSpan().TryFlattenTo(destination); - /// - /// Creates a representation of the ."/> - /// - /// Maximum Length of each dimension - /// A representation of the - public string ToString(params ReadOnlySpan maximumLengths) - { - var sb = new StringBuilder($"System.Numerics.Tensors.Tensor<{typeof(T).Name}>[{_shape}]"); + /// + public bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out Span span) => AsTensorSpan().TryGetSpan(startIndexes, length, out span); - sb.AppendLine("{"); - Tensor.ToString(AsReadOnlyTensorSpan(), maximumLengths, sb); - sb.AppendLine("}"); + /// + public bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out Span span) => AsTensorSpan().TryGetSpan(startIndexes, length, out span); - return sb.ToString(); - } + /// + public bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out ReadOnlySpan span) => AsReadOnlyTensorSpan().TryGetSpan(startIndexes, length, out span); + + /// + public bool TryGetSpan(scoped ReadOnlySpan startIndexes, int length, out ReadOnlySpan span) => AsReadOnlyTensorSpan().TryGetSpan(startIndexes, length, out span); + + /// + public override string ToString() => ToString([]); + + /// + public string ToString(params scoped ReadOnlySpan maximumLengths) => Tensor.ToString(AsReadOnlyTensorSpan(), maximumLengths, "System.Numerics.Tensors.Tensor"); // // IEnumerable @@ -318,6 +326,10 @@ public string ToString(params ReadOnlySpan maximumLengths) ref readonly T IReadOnlyTensor, T>.GetPinnableReference() => ref GetPinnableReference(); + ReadOnlySpan IReadOnlyTensor, T>.GetSpan(scoped ReadOnlySpan startIndexes, int length) => AsReadOnlyTensorSpan().GetSpan(startIndexes, length); + + ReadOnlySpan IReadOnlyTensor, T>.GetSpan(scoped ReadOnlySpan startIndexes, int length) => AsReadOnlyTensorSpan().GetSpan(startIndexes, length); + // // ITensor // @@ -350,13 +362,13 @@ public string ToString(params ReadOnlySpan maximumLengths) // ITensor // - static Tensor ITensor, T>.Create(scoped ReadOnlySpan lengths, bool pinned) => Tensor.Create(lengths, pinned); + static Tensor ITensor, T>.CreateFromShape(scoped ReadOnlySpan lengths, bool pinned) => Tensor.CreateFromShape(lengths, pinned); - static Tensor ITensor, T>.Create(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) => Tensor.Create(lengths, strides, pinned); + static Tensor ITensor, T>.CreateFromShape(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) => Tensor.CreateFromShape(lengths, strides, pinned); - static Tensor ITensor, T>.CreateUninitialized(scoped ReadOnlySpan lengths, bool pinned) => Tensor.CreateUninitialized(lengths, pinned); + static Tensor ITensor, T>.CreateFromShapeUninitialized(scoped ReadOnlySpan lengths, bool pinned) => Tensor.CreateFromShapeUninitialized(lengths, pinned); - static Tensor ITensor, T>.CreateUninitialized(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) => Tensor.CreateUninitialized(lengths, strides, pinned); + static Tensor ITensor, T>.CreateFromShapeUninitialized(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) => Tensor.CreateFromShapeUninitialized(lengths, strides, pinned); /// Enumerates the elements of a tensor. public struct Enumerator : IEnumerator diff --git a/src/libraries/System.Numerics.Tensors/src/System/Runtime/InteropServices/TensorMarshal.cs b/src/libraries/System.Numerics.Tensors/src/System/Runtime/InteropServices/TensorMarshal.cs new file mode 100644 index 00000000000000..6ea4097e086103 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Runtime/InteropServices/TensorMarshal.cs @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Numerics.Tensors; +using System.Runtime.CompilerServices; + +namespace System.Runtime.InteropServices +{ + /// Provides methods to interoperate with , , and . + public static class TensorMarshal + { + /// Creates a new tensor span over a portion of a regular managed object. + /// The type of the data items. + /// A reference to data. + /// The number of elements that contains. + /// The lengths of the dimensions. If an empty span is provided, the created tensor will have a single dimension that is the same length as . + /// The strides of each dimension. If an empty span is provided, then strides will be automatically calculated from . + /// true if is permanently pinned; otherwise, false. + /// The created tensor span. + /// This method should be used with caution. It is dangerous because the inputs may not be fully checked. Even though is marked as scoped, it will be stored into the returned tensor span, and the lifetime of the returned tensor span will not be validated for safety, even by span-aware languages. + public static TensorSpan CreateTensorSpan(scoped ref T data, nint dataLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) + { + return new TensorSpan(ref Unsafe.AsRef(ref data), dataLength, lengths, strides, pinned); + } + + /// Creates a new readonly tensor span over a portion of a regular managed object. + /// The type of the data items. + /// A readonly reference to data. + /// The number of elements that contains. + /// The lengths of the dimensions. If an empty span is provided, the created tensor will have a single dimension that is the same length as . + /// The strides of each dimension. If an empty span is provided, then strides will be automatically calculated from . + /// true if is permanently pinned; otherwise, false. + /// The created readonly tensor span. + /// This method should be used with caution. It is dangerous because the inputs may not be fully checked. Even though is marked as scoped, it will be stored into the returned tensor span, and the lifetime of the returned tensor span will not be validated for safety, even by span-aware languages. + public static ReadOnlyTensorSpan CreateReadOnlyTensorSpan(scoped ref readonly T data, nint dataLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) + { + return new ReadOnlyTensorSpan(in Unsafe.AsRef(in data), dataLength, lengths, strides, pinned); + } + + /// Returns a reference to the element of the tensor span at index 0. + /// The type of items in the tensor span. + /// The tensor span from which the reference is retrieved. + /// A reference to the element at index 0. + /// If the tensor span is empty, this method returns a reference to the location where the element at index 0 would have been stored. Such a reference may or may not be null. The returned reference can be used for pinning, but it must never be dereferenced. + public static ref T GetReference(in TensorSpan tensorSpan) + { + return ref tensorSpan._reference; + } + + /// Returns a reference to the element of the readonly tensor span at index 0. + /// The type of items in the readonly tensor span. + /// The readonly tensor span from which the reference is retrieved. + /// A readonly reference to the element at index 0. + /// If the readonly tensor span is empty, this method returns a reference to the location where the element at index 0 would have been stored. Such a reference may or may not be null. The returned reference can be used for pinning, but it must never be dereferenced. + public static ref readonly T GetReference(in ReadOnlyTensorSpan tensorSpan) + { + return ref tensorSpan._reference; + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs b/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs index f19d78077b9680..fdf786f21ce982 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs @@ -1,9 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; namespace System { diff --git a/src/libraries/System.Numerics.Tensors/tests/Helpers.cs b/src/libraries/System.Numerics.Tensors/tests/Helpers.cs index aee26fde83813f..4e5e89bbb3cad8 100644 --- a/src/libraries/System.Numerics.Tensors/tests/Helpers.cs +++ b/src/libraries/System.Numerics.Tensors/tests/Helpers.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; -using System.Numerics.Tensors; using Xunit; namespace System.Numerics.Tensors.Tests diff --git a/src/libraries/System.Numerics.Tensors/tests/ReadOnlyTensorSpanTests.cs b/src/libraries/System.Numerics.Tensors/tests/ReadOnlyTensorSpanTests.cs index 1a3b5fd8825a68..bce2ad21e05d6c 100644 --- a/src/libraries/System.Numerics.Tensors/tests/ReadOnlyTensorSpanTests.cs +++ b/src/libraries/System.Numerics.Tensors/tests/ReadOnlyTensorSpanTests.cs @@ -1,9 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Buffers; -using System.Collections.Generic; using System.Linq; using Xunit; @@ -1158,5 +1156,286 @@ public static void NullArrayAsReadOnlyTensorSpan() ReadOnlyTensorSpan d = default; Assert.True(span == d); } + + [Fact] + public static void GetSpanTest() + { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + + ReadOnlySpan span = ReadOnlyTensorSpan.GetSpan([0, 0], 16); + Assert.Equal(16, span.Length); + Assert.Equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], span); + + span = ReadOnlyTensorSpan.GetSpan([1, 1], 3); + Assert.Equal(3, span.Length); + Assert.Equal([5, 6, 7], span); + + span = ReadOnlyTensorSpan.GetSpan([3, 0], 4); + Assert.Equal(4, span.Length); + Assert.Equal([12, 13, 14, 15], span); + + span = ReadOnlyTensorSpan.GetSpan([0, 3], 1); + Assert.Equal(1, span.Length); + Assert.Equal([3], span); + + span = ReadOnlyTensorSpan.GetSpan([3, 3], 1); + Assert.Equal(1, span.Length); + Assert.Equal([15], span); + } + + [Fact] + public static void GetSpanThrowsForInvalidIndexesTest() + { + Assert.Throws(() => { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = ReadOnlyTensorSpan.GetSpan([4, 0], 17); + }); + + Assert.Throws(() => { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = ReadOnlyTensorSpan.GetSpan([0, 4], 17); + }); + + Assert.Throws(() => { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = ReadOnlyTensorSpan.GetSpan([4, 4], 17); + }); + } + + [Fact] + public static void GetSpanThrowsForInvalidLengthsTest() + { + Assert.Throws(() => { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = ReadOnlyTensorSpan.GetSpan([0, 0], -1); + }); + + Assert.Throws(() => { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = ReadOnlyTensorSpan.GetSpan([0, 0], 17); + }); + + Assert.Throws(() => { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = ReadOnlyTensorSpan.GetSpan([1, 1], 4); + }); + + Assert.Throws(() => { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = ReadOnlyTensorSpan.GetSpan([3, 0], 5); + }); + + Assert.Throws(() => { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = ReadOnlyTensorSpan.GetSpan([0, 3], 2); + }); + + Assert.Throws(() => { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = ReadOnlyTensorSpan.GetSpan([3, 3], 2); + }); + } + + [Fact] + public static void TryGetSpanTest() + { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + + Assert.True(ReadOnlyTensorSpan.TryGetSpan([0, 0], 16, out ReadOnlySpan span)); + Assert.Equal(16, span.Length); + Assert.Equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], span); + + Assert.True(ReadOnlyTensorSpan.TryGetSpan([1, 1], 3, out span)); + Assert.Equal(3, span.Length); + Assert.Equal([5, 6, 7], span); + + Assert.True(ReadOnlyTensorSpan.TryGetSpan([3, 0], 4, out span)); + Assert.Equal(4, span.Length); + Assert.Equal([12, 13, 14, 15], span); + + Assert.True(ReadOnlyTensorSpan.TryGetSpan([0, 3], 1, out span)); + Assert.Equal(1, span.Length); + Assert.Equal([3], span); + + Assert.True(ReadOnlyTensorSpan.TryGetSpan([3, 3], 1, out span)); + Assert.Equal(1, span.Length); + Assert.Equal([15], span); + } + + [Fact] + public static void TryGetSpanThrowsForInvalidIndexesTest() + { + Assert.Throws(() => { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = ReadOnlyTensorSpan.TryGetSpan([4, 0], 17, out _); + }); + + Assert.Throws(() => { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = ReadOnlyTensorSpan.TryGetSpan([0, 4], 17, out _); + }); + + Assert.Throws(() => { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = ReadOnlyTensorSpan.TryGetSpan([4, 4], 17, out _); + }); + } + + [Fact] + public static void TryGetSpanFailsForInvalidLengthsTest() + { + ReadOnlyTensorSpan ReadOnlyTensorSpan = new ReadOnlyTensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + + Assert.False(ReadOnlyTensorSpan.TryGetSpan([0, 0], -1, out ReadOnlySpan span)); + Assert.Equal(0, span.Length); + + Assert.False(ReadOnlyTensorSpan.TryGetSpan([0, 0], 17, out span)); + Assert.Equal(0, span.Length); + + Assert.False(ReadOnlyTensorSpan.TryGetSpan([1, 1], 4, out span)); + Assert.Equal(0, span.Length); + + Assert.False(ReadOnlyTensorSpan.TryGetSpan([3, 0], 5, out span)); + Assert.Equal(0, span.Length); + + Assert.False(ReadOnlyTensorSpan.TryGetSpan([0, 3], 2, out span)); + Assert.Equal(0, span.Length); + + Assert.False(ReadOnlyTensorSpan.TryGetSpan([3, 3], 2, out span)); + Assert.Equal(0, span.Length); + } + + [Fact] + public static void ToStringTest() + { + ReadOnlyTensorSpan tensor = Tensor.Create([1, 2, 3, 4, 5], lengths: [5]); + string expected = "System.Numerics.Tensors.ReadOnlyTensorSpan[5]"; + Assert.Equal(expected, tensor.ToString()); + + tensor = Tensor.Create([1, 2, 3, 4], lengths: [2, 2]); + expected = "System.Numerics.Tensors.ReadOnlyTensorSpan[2, 2]"; + Assert.Equal(expected, tensor.ToString()); + + tensor = Tensor.Create(Enumerable.Range(1, 27).ToArray(), lengths: [3, 3, 3]); + expected = "System.Numerics.Tensors.ReadOnlyTensorSpan[3, 3, 3]"; + Assert.Equal(expected, tensor.ToString()); + } + + [Fact] + public static void ToStringAllDataTest() + { + ReadOnlyTensorSpan tensor = Tensor.Create([1, 2, 3, 4, 5], lengths: [5]); + string expected = """ + System.Numerics.Tensors.ReadOnlyTensorSpan[5] { + [1, 2, 3, 4, 5] + } + """; + Assert.Equal(expected, tensor.ToString([5])); + + tensor = Tensor.Create([1, 2, 3, 4], lengths: [2, 2]); + expected = """ + System.Numerics.Tensors.ReadOnlyTensorSpan[2, 2] { + [1, 2], + [3, 4] + } + """; + Assert.Equal(expected, tensor.ToString([2, 2])); + + tensor = Tensor.Create(Enumerable.Range(1, 27).ToArray(), lengths: [3, 3, 3]); + expected = """ + System.Numerics.Tensors.ReadOnlyTensorSpan[3, 3, 3] { + [ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9] + ], + [ + [10, 11, 12], + [13, 14, 15], + [16, 17, 18] + ], + [ + [19, 20, 21], + [22, 23, 24], + [25, 26, 27] + ] + } + """; + Assert.Equal(expected, tensor.ToString([3, 3, 3])); + } + + [Fact] + public static void ToStringPartialDataTest() + { + ReadOnlyTensorSpan tensor = Tensor.Create([1, 2, 3, 4, 5], lengths: [5]); + string expected = """ + System.Numerics.Tensors.ReadOnlyTensorSpan[5] { + [1, 2, 3, ..] + } + """; + Assert.Equal(expected, tensor.ToString([3])); + + tensor = Tensor.Create([1, 2, 3, 4], lengths: [2, 2]); + expected = """ + System.Numerics.Tensors.ReadOnlyTensorSpan[2, 2] { + [1, ..], + [3, ..] + } + """; + Assert.Equal(expected, tensor.ToString([2, 1])); + + tensor = Tensor.Create(Enumerable.Range(1, 27).ToArray(), lengths: [3, 3, 3]); + expected = """ + System.Numerics.Tensors.ReadOnlyTensorSpan[3, 3, 3] { + [ + [1, 2, ..], + [4, 5, ..], + .. + ], + [ + [10, 11, ..], + [13, 14, ..], + .. + ], + .. + } + """; + Assert.Equal(expected, tensor.ToString([2, 2, 2])); + } + + [Fact] + public static void ToStringZeroDataTest() + { + ReadOnlyTensorSpan tensor = Tensor.Create([1, 2, 3, 4, 5], lengths: [5]); + string expected = """ + System.Numerics.Tensors.ReadOnlyTensorSpan[5] { + [..] + } + """; + Assert.Equal(expected, tensor.ToString([0])); + + tensor = Tensor.Create([1, 2, 3, 4], lengths: [2, 2]); + expected = """ + System.Numerics.Tensors.ReadOnlyTensorSpan[2, 2] { + [..], + [..] + } + """; + Assert.Equal(expected, tensor.ToString([2, 0])); + + tensor = Tensor.Create(Enumerable.Range(1, 27).ToArray(), lengths: [3, 3, 3]); + expected = """ + System.Numerics.Tensors.ReadOnlyTensorSpan[3, 3, 3] { + [ + .. + ], + [ + .. + ], + .. + } + """; + Assert.Equal(expected, tensor.ToString([2, 0, 2])); + } } } diff --git a/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj b/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj index c885e5acb0c496..44715d45f4ebb4 100644 --- a/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj +++ b/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj @@ -17,15 +17,16 @@ - - - - - + + + + + + diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorMarshalTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorMarshalTests.cs new file mode 100644 index 00000000000000..727aacfe3a358f --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/tests/TensorMarshalTests.cs @@ -0,0 +1,84 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Xunit; + +namespace System.Numerics.Tensors.Tests +{ + public class TensorMarshalTests + { + [Fact] + public void CreateTensorSpanTest() + { + int[] data = Enumerable.Range(0, 10).ToArray(); + nint[] lengths = [2, 5]; + TensorSpan tensorSpan = TensorMarshal.CreateTensorSpan(ref data[0], data.Length, lengths, strides: [], pinned: false); + + Assert.Equal(10, tensorSpan.FlattenedLength); + Assert.Equal(lengths, tensorSpan.Lengths.ToArray()); + Assert.Equal([5, 1], tensorSpan.Strides.ToArray()); + } + + [Fact] + public void CreateTensorSpanThrowsForInvalidLengthsTest() + { + int[] data = Enumerable.Range(0, 10).ToArray(); + nint[] lengths = [3, 5]; + Assert.Throws(() => TensorMarshal.CreateTensorSpan(ref data[0], data.Length, lengths, strides: [], pinned: false)); + } + + [Fact] + public void CreateReadOnlyTensorSpanTest() + { + int[] data = Enumerable.Range(0, 10).ToArray(); + nint[] lengths = [2, 5]; + ReadOnlyTensorSpan tensorSpan = TensorMarshal.CreateReadOnlyTensorSpan(ref data[0], data.Length, lengths, strides: [], pinned: false); + + Assert.Equal(10, tensorSpan.FlattenedLength); + Assert.Equal(lengths, tensorSpan.Lengths.ToArray()); + Assert.Equal([5, 1], tensorSpan.Strides.ToArray()); + } + + [Fact] + public void CreateReadOnlyTensorSpanThrowsForInvalidLengthsTest() + { + int[] data = Enumerable.Range(0, 10).ToArray(); + nint[] lengths = [3, 5]; + Assert.Throws(() => TensorMarshal.CreateReadOnlyTensorSpan(ref data[0], data.Length, lengths, strides: [], pinned: false)); + } + + [Fact] + public void GetReferenceTensorSpanTest() + { + int[] data = new int[10]; + TensorSpan tensorSpan = data; + Assert.True(Unsafe.AreSame(ref data[0], ref TensorMarshal.GetReference(tensorSpan))); + + data = Array.Empty(); + tensorSpan = data; + Assert.True(Unsafe.AreSame(ref MemoryMarshal.GetArrayDataReference(data), ref TensorMarshal.GetReference(tensorSpan))); + + tensorSpan = TensorSpan.Empty; + Assert.True(Unsafe.IsNullRef(ref TensorMarshal.GetReference(tensorSpan))); + } + + [Fact] + public void GetReferenceReadOnlyTensorSpanTest() + { + int[] data = new int[10]; + ReadOnlyTensorSpan tensorSpan = data; + Assert.True(Unsafe.AreSame(ref data[0], in TensorMarshal.GetReference(tensorSpan))); + + data = Array.Empty(); + tensorSpan = data; + Assert.True(Unsafe.AreSame(ref MemoryMarshal.GetArrayDataReference(data), in TensorMarshal.GetReference(tensorSpan))); + + tensorSpan = TensorSpan.Empty; + Assert.True(Unsafe.IsNullRef(in TensorMarshal.GetReference(tensorSpan))); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorPrimitives.Generic.cs b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitives.Generic.cs index c154157a944159..e1e04b78853257 100644 --- a/src/libraries/System.Numerics.Tensors/tests/TensorPrimitives.Generic.cs +++ b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitives.Generic.cs @@ -3,7 +3,6 @@ using System.Buffers; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorSpanTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorSpanTests.cs index b4616cd4f0d77d..2e8e69c4b336a0 100644 --- a/src/libraries/System.Numerics.Tensors/tests/TensorSpanTests.cs +++ b/src/libraries/System.Numerics.Tensors/tests/TensorSpanTests.cs @@ -1796,5 +1796,286 @@ public static void NullArrayAsTensorSpan() TensorSpan span = a.AsTensorSpan(); Assert.True(span == default); } + + [Fact] + public static void GetSpanTest() + { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + + Span span = tensorSpan.GetSpan([0, 0], 16); + Assert.Equal(16, span.Length); + Assert.Equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], span); + + span = tensorSpan.GetSpan([1, 1], 3); + Assert.Equal(3, span.Length); + Assert.Equal([5, 6, 7], span); + + span = tensorSpan.GetSpan([3, 0], 4); + Assert.Equal(4, span.Length); + Assert.Equal([12, 13, 14, 15], span); + + span = tensorSpan.GetSpan([0, 3], 1); + Assert.Equal(1, span.Length); + Assert.Equal([3], span); + + span = tensorSpan.GetSpan([3, 3], 1); + Assert.Equal(1, span.Length); + Assert.Equal([15], span); + } + + [Fact] + public static void GetSpanThrowsForInvalidIndexesTest() + { + Assert.Throws(() => { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([4, 0], 17); + }); + + Assert.Throws(() => { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([0, 4], 17); + }); + + Assert.Throws(() => { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([4, 4], 17); + }); + } + + [Fact] + public static void GetSpanThrowsForInvalidLengthsTest() + { + Assert.Throws(() => { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([0, 0], -1); + }); + + Assert.Throws(() => { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([0, 0], 17); + }); + + Assert.Throws(() => { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([1, 1], 4); + }); + + Assert.Throws(() => { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([3, 0], 5); + }); + + Assert.Throws(() => { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([0, 3], 2); + }); + + Assert.Throws(() => { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([3, 3], 2); + }); + } + + [Fact] + public static void TryGetSpanTest() + { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + + Assert.True(tensorSpan.TryGetSpan([0, 0], 16, out Span span)); + Assert.Equal(16, span.Length); + Assert.Equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], span); + + Assert.True(tensorSpan.TryGetSpan([1, 1], 3, out span)); + Assert.Equal(3, span.Length); + Assert.Equal([5, 6, 7], span); + + Assert.True(tensorSpan.TryGetSpan([3, 0], 4, out span)); + Assert.Equal(4, span.Length); + Assert.Equal([12, 13, 14, 15], span); + + Assert.True(tensorSpan.TryGetSpan([0, 3], 1, out span)); + Assert.Equal(1, span.Length); + Assert.Equal([3], span); + + Assert.True(tensorSpan.TryGetSpan([3, 3], 1, out span)); + Assert.Equal(1, span.Length); + Assert.Equal([15], span); + } + + [Fact] + public static void TryGetSpanThrowsForInvalidIndexesTest() + { + Assert.Throws(() => { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.TryGetSpan([4, 0], 17, out Span _); + }); + + Assert.Throws(() => { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.TryGetSpan([0, 4], 17, out Span _); + }); + + Assert.Throws(() => { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.TryGetSpan([4, 4], 17, out Span _); + }); + } + + [Fact] + public static void TryGetSpanFailsForInvalidLengthsTest() + { + TensorSpan tensorSpan = new TensorSpan(Enumerable.Range(0, 16).ToArray(), [4, 4]); + + Assert.False(tensorSpan.TryGetSpan([0, 0], -1, out Span span)); + Assert.Equal(0, span.Length); + + Assert.False(tensorSpan.TryGetSpan([0, 0], 17, out span)); + Assert.Equal(0, span.Length); + + Assert.False(tensorSpan.TryGetSpan([1, 1], 4, out span)); + Assert.Equal(0, span.Length); + + Assert.False(tensorSpan.TryGetSpan([3, 0], 5, out span)); + Assert.Equal(0, span.Length); + + Assert.False(tensorSpan.TryGetSpan([0, 3], 2, out span)); + Assert.Equal(0, span.Length); + + Assert.False(tensorSpan.TryGetSpan([3, 3], 2, out span)); + Assert.Equal(0, span.Length); + } + + [Fact] + public static void ToStringTest() + { + TensorSpan tensor = Tensor.Create([1, 2, 3, 4, 5], lengths: [5]); + string expected = "System.Numerics.Tensors.TensorSpan[5]"; + Assert.Equal(expected, tensor.ToString()); + + tensor = Tensor.Create([1, 2, 3, 4], lengths: [2, 2]); + expected = "System.Numerics.Tensors.TensorSpan[2, 2]"; + Assert.Equal(expected, tensor.ToString()); + + tensor = Tensor.Create(Enumerable.Range(1, 27).ToArray(), lengths: [3, 3, 3]); + expected = "System.Numerics.Tensors.TensorSpan[3, 3, 3]"; + Assert.Equal(expected, tensor.ToString()); + } + + [Fact] + public static void ToStringAllDataTest() + { + TensorSpan tensor = Tensor.Create([1, 2, 3, 4, 5], lengths: [5]); + string expected = """ + System.Numerics.Tensors.TensorSpan[5] { + [1, 2, 3, 4, 5] + } + """; + Assert.Equal(expected, tensor.ToString([5])); + + tensor = Tensor.Create([1, 2, 3, 4], lengths: [2, 2]); + expected = """ + System.Numerics.Tensors.TensorSpan[2, 2] { + [1, 2], + [3, 4] + } + """; + Assert.Equal(expected, tensor.ToString([2, 2])); + + tensor = Tensor.Create(Enumerable.Range(1, 27).ToArray(), lengths: [3, 3, 3]); + expected = """ + System.Numerics.Tensors.TensorSpan[3, 3, 3] { + [ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9] + ], + [ + [10, 11, 12], + [13, 14, 15], + [16, 17, 18] + ], + [ + [19, 20, 21], + [22, 23, 24], + [25, 26, 27] + ] + } + """; + Assert.Equal(expected, tensor.ToString([3, 3, 3])); + } + + [Fact] + public static void ToStringPartialDataTest() + { + TensorSpan tensor = Tensor.Create([1, 2, 3, 4, 5], lengths: [5]); + string expected = """ + System.Numerics.Tensors.TensorSpan[5] { + [1, 2, 3, ..] + } + """; + Assert.Equal(expected, tensor.ToString([3])); + + tensor = Tensor.Create([1, 2, 3, 4], lengths: [2, 2]); + expected = """ + System.Numerics.Tensors.TensorSpan[2, 2] { + [1, ..], + [3, ..] + } + """; + Assert.Equal(expected, tensor.ToString([2, 1])); + + tensor = Tensor.Create(Enumerable.Range(1, 27).ToArray(), lengths: [3, 3, 3]); + expected = """ + System.Numerics.Tensors.TensorSpan[3, 3, 3] { + [ + [1, 2, ..], + [4, 5, ..], + .. + ], + [ + [10, 11, ..], + [13, 14, ..], + .. + ], + .. + } + """; + Assert.Equal(expected, tensor.ToString([2, 2, 2])); + } + + [Fact] + public static void ToStringZeroDataTest() + { + TensorSpan tensor = Tensor.Create([1, 2, 3, 4, 5], lengths: [5]); + string expected = """ + System.Numerics.Tensors.TensorSpan[5] { + [..] + } + """; + Assert.Equal(expected, tensor.ToString([0])); + + tensor = Tensor.Create([1, 2, 3, 4], lengths: [2, 2]); + expected = """ + System.Numerics.Tensors.TensorSpan[2, 2] { + [..], + [..] + } + """; + Assert.Equal(expected, tensor.ToString([2, 0])); + + tensor = Tensor.Create(Enumerable.Range(1, 27).ToArray(), lengths: [3, 3, 3]); + expected = """ + System.Numerics.Tensors.TensorSpan[3, 3, 3] { + [ + .. + ], + [ + .. + ], + .. + } + """; + Assert.Equal(expected, tensor.ToString([2, 0, 2])); + } } } diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs index 41c995428b765e..22c86fbbeb695e 100644 --- a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs +++ b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs @@ -3,7 +3,6 @@ using System.Buffers; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using Xunit; @@ -343,7 +342,7 @@ public static void TensorLargeDimensionsTests() public static void TensorFactoryCreateUninitializedTests() { // Basic tensor creation - Tensor t1 = Tensor.CreateUninitialized([1]); + Tensor t1 = Tensor.CreateFromShapeUninitialized([1]); Assert.Equal(1, t1.Rank); Assert.Equal(1, t1.Lengths.Length); Assert.Equal(1, t1.Lengths[0]); @@ -372,10 +371,10 @@ public static void TensorFactoryCreateUninitializedTests() // Make sure lengths can't be negative Assert.Throws(() => { - Tensor t1 = Tensor.CreateUninitialized([-1]); + Tensor t1 = Tensor.CreateFromShapeUninitialized([-1]); }); - t1 = Tensor.CreateUninitialized([0]); + t1 = Tensor.CreateFromShapeUninitialized([0]); Assert.Equal(1, t1.Rank); Assert.Equal(1, t1.Lengths.Length); Assert.Equal(0, t1.Lengths[0]); @@ -383,7 +382,7 @@ public static void TensorFactoryCreateUninitializedTests() Assert.Equal(0, t1.Strides[0]); Assert.False(t1.IsPinned); - t1 = Tensor.CreateUninitialized([]); + t1 = Tensor.CreateFromShapeUninitialized([]); Assert.Equal(1, t1.Rank); Assert.Equal(1, t1.Lengths.Length); Assert.Equal(0, t1.Lengths[0]); @@ -392,7 +391,7 @@ public static void TensorFactoryCreateUninitializedTests() Assert.False(t1.IsPinned); // Null should behave like empty array since there is no "null" span. - t1 = Tensor.CreateUninitialized(null); + t1 = Tensor.CreateFromShapeUninitialized(null); Assert.Equal(1, t1.Rank); Assert.Equal(1, t1.Lengths.Length); Assert.Equal(0, t1.Lengths[0]); @@ -401,7 +400,7 @@ public static void TensorFactoryCreateUninitializedTests() Assert.False(t1.IsPinned); // Make sure pinned works - t1 = Tensor.CreateUninitialized([1], true); + t1 = Tensor.CreateFromShapeUninitialized([1], true); Assert.Equal(1, t1.Rank); Assert.Equal(1, t1.Lengths.Length); Assert.Equal(1, t1.Lengths[0]); @@ -410,7 +409,7 @@ public static void TensorFactoryCreateUninitializedTests() Assert.True(t1.IsPinned); // Make sure 2D array works with basic strides - t1 = Tensor.CreateUninitialized([2, 2], [2, 1]); + t1 = Tensor.CreateFromShapeUninitialized([2, 2], [2, 1]); Assert.Equal(2, t1.Rank); Assert.Equal(2, t1.Lengths[0]); Assert.Equal(2, t1.Lengths[1]); @@ -422,7 +421,7 @@ public static void TensorFactoryCreateUninitializedTests() Assert.IsType(t1[1, 1]); // Make sure 2D array works with stride of 0 to loop over first 2 elements again - t1 = Tensor.CreateUninitialized([2, 2], [0, 1]); + t1 = Tensor.CreateFromShapeUninitialized([2, 2], [0, 1]); Assert.Equal(2, t1.Rank); Assert.Equal(2, t1.Lengths[0]); Assert.Equal(2, t1.Lengths[1]); @@ -432,7 +431,7 @@ public static void TensorFactoryCreateUninitializedTests() Assert.Equal(t1[0, 1], t1[1, 1]); // Make sure 2D array works with strides of all 0 to loop over first element again - t1 = Tensor.CreateUninitialized([2, 2], [0, 0]); + t1 = Tensor.CreateFromShapeUninitialized([2, 2], [0, 0]); Assert.Equal(2, t1.Rank); Assert.Equal(2, t1.Lengths[0]); Assert.Equal(2, t1.Lengths[1]); @@ -444,22 +443,22 @@ public static void TensorFactoryCreateUninitializedTests() // Make sure strides can't be negative Assert.Throws(() => { - var t1 = Tensor.CreateUninitialized([1, 2], [-1, 0], false); + var t1 = Tensor.CreateFromShapeUninitialized([1, 2], [-1, 0], false); }); Assert.Throws(() => { - var t1 = Tensor.CreateUninitialized([1, 2], [0, -1], false); + var t1 = Tensor.CreateFromShapeUninitialized([1, 2], [0, -1], false); }); // Make sure lengths can't be negative Assert.Throws(() => { - var t1 = Tensor.CreateUninitialized([-1, 2], [], false); + var t1 = Tensor.CreateFromShapeUninitialized([-1, 2], [], false); }); Assert.Throws(() => { - var t1 = Tensor.CreateUninitialized([1, -2], [], false); + var t1 = Tensor.CreateFromShapeUninitialized([1, -2], [], false); }); // Make sure 2D array works with strides to hit element 0,0,2,2 - t1 = Tensor.CreateUninitialized([2, 2], [2, 0]); + t1 = Tensor.CreateFromShapeUninitialized([2, 2], [2, 0]); Assert.Equal(2, t1.Rank); Assert.Equal(2, t1.Lengths[0]); Assert.Equal(2, t1.Lengths[1]); @@ -468,7 +467,7 @@ public static void TensorFactoryCreateUninitializedTests() // Make sure you can't overlap elements using strides Assert.Throws(() => { - var t1 = Tensor.CreateUninitialized([2, 2], [1, 1], false); + var t1 = Tensor.CreateFromShapeUninitialized([2, 2], [1, 1], false); }); } @@ -476,7 +475,7 @@ public static void TensorFactoryCreateUninitializedTests() public static void TensorFactoryCreateTests() { // Basic tensor creation - Tensor t1 = Tensor.Create((ReadOnlySpan)([1])); + Tensor t1 = Tensor.CreateFromShape((ReadOnlySpan)([1])); Assert.Equal(1, t1.Rank); Assert.Equal(1, t1.Lengths.Length); Assert.Equal(1, t1.Lengths[0]); @@ -506,10 +505,10 @@ public static void TensorFactoryCreateTests() // Make sure lengths can't be negative Assert.Throws(() => { - Tensor t1 = Tensor.Create((ReadOnlySpan)([-1])); + Tensor t1 = Tensor.CreateFromShape((ReadOnlySpan)([-1])); }); - t1 = Tensor.Create((ReadOnlySpan)([0])); + t1 = Tensor.CreateFromShape((ReadOnlySpan)([0])); Assert.Equal(1, t1.Rank); Assert.Equal(1, t1.Lengths.Length); Assert.Equal(0, t1.Lengths[0]); @@ -517,7 +516,7 @@ public static void TensorFactoryCreateTests() Assert.Equal(0, t1.Strides[0]); Assert.False(t1.IsPinned); - t1 = Tensor.Create((ReadOnlySpan)([])); + t1 = Tensor.CreateFromShape((ReadOnlySpan)([])); Assert.Equal(1, t1.Rank); Assert.Equal(1, t1.Lengths.Length); Assert.Equal(0, t1.Lengths[0]); @@ -533,7 +532,7 @@ public static void TensorFactoryCreateTests() Assert.False(t1.IsPinned); // Make sure pinned works - t1 = Tensor.Create([(nint)1], true); + t1 = Tensor.CreateFromShape([(nint)1], true); Assert.Equal(1, t1.Rank); Assert.Equal(1, t1.Lengths.Length); Assert.Equal(1, t1.Lengths[0]); @@ -586,19 +585,19 @@ public static void TensorFactoryCreateTests() // Make sure strides can't be negative Assert.Throws(() => { Span a = [91, 92, -93, 94]; - var t1 = Tensor.Create((Span)[1, 2], [-1, 0], false); + var t1 = Tensor.CreateFromShape((Span)[1, 2], [-1, 0], false); }); Assert.Throws(() => { Span a = [91, 92, -93, 94]; - var t1 = Tensor.Create((Span)[1, 2], [0, -1], false); + var t1 = Tensor.CreateFromShape((Span)[1, 2], [0, -1], false); }); // Make sure lengths can't be negative Assert.Throws(() => { - var t1 = Tensor.Create([-1, (nint)2], false); + var t1 = Tensor.CreateFromShape([-1, (nint)2], false); }); Assert.Throws(() => { - var t1 = Tensor.Create([(nint)1, -2], false); + var t1 = Tensor.CreateFromShape([(nint)1, -2], false); }); // Make sure 2D array works with strides to hit element 0,0,2,2 @@ -613,7 +612,7 @@ public static void TensorFactoryCreateTests() // Make sure you can't overlap elements using strides Assert.Throws(() => { - var t1 = Tensor.Create((Span)[2, 2], [1, 1], false); + var t1 = Tensor.CreateFromShape((Span)[2, 2], [1, 1], false); }); } @@ -642,8 +641,8 @@ public static void TensorCosineSimilarityTests() //[Fact] //public static void TensorSequenceEqualTests() //{ - // Tensor t0 = Tensor.Create(Enumerable.Range(0, 3), default); - // Tensor t1 = Tensor.Create(Enumerable.Range(0, 3), default); + // Tensor t0 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), default); + // Tensor t1 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), default); // Tensor equal = Tensor.SequenceEqual(t0, t1); // Assert.Equal([3], equal.Lengths.ToArray()); @@ -651,8 +650,8 @@ public static void TensorCosineSimilarityTests() // Assert.True(equal[1]); // Assert.True(equal[2]); - // t0 = Tensor.Create(Enumerable.Range(0, 3), [1, 3]); - // t1 = Tensor.Create(Enumerable.Range(0, 3), default); + // t0 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), [1, 3]); + // t1 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), default); // equal = Tensor.SequenceEqual(t0, t1); // Assert.Equal([1, 3], equal.Lengths.ToArray()); @@ -660,8 +659,8 @@ public static void TensorCosineSimilarityTests() // Assert.True(equal[0, 1]); // Assert.True(equal[0, 2]); - // t0 = Tensor.Create(Enumerable.Range(0, 3), [1, 1, 3]); - // t1 = Tensor.Create(Enumerable.Range(0, 3), default); + // t0 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), [1, 1, 3]); + // t1 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), default); // equal = Tensor.SequenceEqual(t0, t1); // Assert.Equal([1, 1, 3], equal.Lengths.ToArray()); @@ -669,8 +668,8 @@ public static void TensorCosineSimilarityTests() // Assert.True(equal[0, 0, 1]); // Assert.True(equal[0, 0, 2]); - // t0 = Tensor.Create(Enumerable.Range(0, 3), default); - // t1 = Tensor.Create(Enumerable.Range(0, 3), [1, 3]); + // t0 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), default); + // t1 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), [1, 3]); // equal = Tensor.SequenceEqual(t0, t1); // Assert.Equal([1, 3], equal.Lengths.ToArray()); @@ -678,8 +677,8 @@ public static void TensorCosineSimilarityTests() // Assert.True(equal[0, 1]); // Assert.True(equal[0, 2]); - // t0 = Tensor.Create(Enumerable.Range(0, 3), default); - // t1 = Tensor.Create(Enumerable.Range(0, 3), [3, 1]); + // t0 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), default); + // t1 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), [3, 1]); // equal = Tensor.SequenceEqual(t0, t1); // Assert.Equal([3, 3], equal.Lengths.ToArray()); @@ -693,8 +692,8 @@ public static void TensorCosineSimilarityTests() // Assert.False(equal[2, 1]); // Assert.True(equal[2, 2]); - // t0 = Tensor.Create(Enumerable.Range(0, 3), [1, 3]); - // t1 = Tensor.Create(Enumerable.Range(0, 3), [3, 1]); + // t0 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), [1, 3]); + // t1 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), [3, 1]); // equal = Tensor.SequenceEqual(t0, t1); // Assert.Equal([3, 3], equal.Lengths.ToArray()); @@ -709,15 +708,15 @@ public static void TensorCosineSimilarityTests() // Assert.True(equal[2, 2]); // t0 = Tensor.Create(Enumerable.Range(0, 4), default); - // t1 = Tensor.Create(Enumerable.Range(0, 3), default); + // t1 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), default); // Assert.Throws(() => Tensor.SequenceEqual(t0, t1)); //} [Fact] public static void TensorMultiplyTests() { - Tensor t0 = Tensor.Create(Enumerable.Range(0, 3)); - Tensor t1 = Tensor.Create(Enumerable.Range(0, 3), lengths: [3, 1]); + Tensor t0 = Tensor.Create(Enumerable.Range(0, 3).ToArray()); + Tensor t1 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), lengths: [3, 1]); // TODO: This double broadcast will be added back in the future //Tensor t2 = Tensor.Multiply(t0.AsReadOnlyTensorSpan(), t1); @@ -745,7 +744,7 @@ public static void TensorMultiplyTests() //Assert.Equal(2, t2[2, 1]); //Assert.Equal(4, t2[2, 2]); - t1 = Tensor.Create(Enumerable.Range(0, 9), lengths: [3, 3]); + t1 = Tensor.Create(Enumerable.Range(0, 9).ToArray(), lengths: [3, 3]); Tensor t2 = Tensor.Multiply(t0.AsReadOnlyTensorSpan(), t1); Assert.Equal([3, 3], t2.Lengths); @@ -763,7 +762,7 @@ public static void TensorMultiplyTests() [Fact] public static void TensorBroadcastTests() { - Tensor t0 = Tensor.Create(Enumerable.Range(0, 3), lengths: [1, 3, 1, 1, 1]); + Tensor t0 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), lengths: [1, 3, 1, 1, 1]); Tensor t1 = Tensor.Broadcast(t0, [1, 3, 1, 2, 1]); Assert.Equal([1, 3, 1, 2, 1], t1.Lengths); @@ -785,8 +784,8 @@ public static void TensorBroadcastTests() Assert.Equal(2, t1[0, 2, 0, 0, 0]); Assert.Equal(2, t1[0, 2, 1, 0, 0]); - t0 = Tensor.Create(Enumerable.Range(0, 3), lengths: [1, 3]); - t1 = Tensor.Create(Enumerable.Range(0, 3), lengths: [3, 1]); + t0 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), lengths: [1, 3]); + t1 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), lengths: [3, 1]); var t2 = Tensor.Broadcast(t0, [3, 3]); Assert.Equal([3, 3], t2.Lengths); @@ -800,7 +799,7 @@ public static void TensorBroadcastTests() Assert.Equal(1, t2[2, 1]); Assert.Equal(2, t2[2, 2]); - t1 = Tensor.Create(Enumerable.Range(0, 3), lengths: [3, 1]); + t1 = Tensor.Create(Enumerable.Range(0, 3).ToArray(), lengths: [3, 1]); t2 = Tensor.Broadcast(t1, [3, 3]); Assert.Equal([3, 3], t2.Lengths); @@ -828,7 +827,7 @@ public static void TensorBroadcastTests() var t3 = t2.Slice(0..1, ..); Assert.Equal([1, 3], t3.Lengths); - t1 = Tensor.Create(Enumerable.Range(0, 3), default); + t1 = Tensor.Create(Enumerable.Range(0, 3).ToArray()); t2 = Tensor.Broadcast(t1, [3, 3]); Assert.Equal([3, 3], t2.Lengths); @@ -846,7 +845,7 @@ public static void TensorBroadcastTests() [Fact] public static void TensorResizeTests() { - Tensor t0 = Tensor.Create(Enumerable.Range(0, 8), lengths: [2, 2, 2]); + Tensor t0 = Tensor.Create(Enumerable.Range(0, 8).ToArray(), lengths: [2, 2, 2]); var t1 = Tensor.Resize(t0, [1]); Assert.Equal([1], t1.Lengths); Assert.Equal(0, t1[0]); @@ -894,7 +893,7 @@ public static void TensorResizeTests() [Fact] public static void TensorSplitTests() { - Tensor t0 = Tensor.Create(Enumerable.Range(0, 8), lengths: [2, 2, 2]); + Tensor t0 = Tensor.Create(Enumerable.Range(0, 8).ToArray(), lengths: [2, 2, 2]); var t1 = Tensor.Split(t0, 2, 0); Assert.Equal([1, 2, 2], t1[0].Lengths); Assert.Equal([1, 2, 2], t1[1].Lengths); @@ -935,7 +934,7 @@ public static void TensorSplitTests() [Fact] public static void TensorReverseTests() { - Tensor t0 = Tensor.Create(Enumerable.Range(0, 8), lengths: [2, 2, 2]); + Tensor t0 = Tensor.Create(Enumerable.Range(0, 8).ToArray(), lengths: [2, 2, 2]); var t1 = Tensor.Reverse(t0); Assert.Equal(7, t1[0, 0, 0]); Assert.Equal(6, t1[0, 0, 1]); @@ -980,8 +979,8 @@ public static void TensorReverseTests() [Fact] public static void TensorSetSliceTests() { - Tensor t0 = Tensor.Create(Enumerable.Range(0, 10), lengths: [2, 5]); - Tensor t1 = Tensor.Create(Enumerable.Range(10, 10), lengths: [2, 5]); + Tensor t0 = Tensor.Create(Enumerable.Range(0, 10).ToArray(), lengths: [2, 5]); + Tensor t1 = Tensor.Create(Enumerable.Range(10, 10).ToArray(), lengths: [2, 5]); Tensor.SetSlice(t0, t1, .., ..); Assert.Equal(10, t0[0, 0]); @@ -995,8 +994,8 @@ public static void TensorSetSliceTests() Assert.Equal(18, t0[1, 3]); Assert.Equal(19, t0[1, 4]); - t0 = Tensor.Create(Enumerable.Range(0, 10), lengths: [2, 5]); - t1 = Tensor.Create(Enumerable.Range(10, 5), lengths: [1, 5]); + t0 = Tensor.Create(Enumerable.Range(0, 10).ToArray(), lengths: [2, 5]); + t1 = Tensor.Create(Enumerable.Range(10, 5).ToArray(), lengths: [1, 5]); t0.SetSlice(t1, 0..1, ..); Assert.Equal(10, t0[0, 0]); @@ -1010,8 +1009,8 @@ public static void TensorSetSliceTests() Assert.Equal(8, t0[1, 3]); Assert.Equal(9, t0[1, 4]); - t0 = Tensor.Create(Enumerable.Range(0, 10), lengths: [2, 5]); - t1 = Tensor.Create(Enumerable.Range(10, 5), lengths: [1, 5]); + t0 = Tensor.Create(Enumerable.Range(0, 10).ToArray(), lengths: [2, 5]); + t1 = Tensor.Create(Enumerable.Range(10, 5).ToArray(), lengths: [1, 5]); Tensor.SetSlice(t0, t1, 1..2, ..); Assert.Equal(0, t0[0, 0]); @@ -1029,8 +1028,8 @@ public static void TensorSetSliceTests() [Fact] public static void TensorStackTests() { - Tensor t0 = Tensor.Create(Enumerable.Range(0, 10), lengths: [2, 5]); - Tensor t1 = Tensor.Create(Enumerable.Range(0, 10), lengths: [2, 5]); + Tensor t0 = Tensor.Create(Enumerable.Range(0, 10).ToArray(), lengths: [2, 5]); + Tensor t1 = Tensor.Create(Enumerable.Range(0, 10).ToArray(), lengths: [2, 5]); var resultTensor = Tensor.Stack([t0, t1]); Assert.Equal(3, resultTensor.Rank); @@ -1134,7 +1133,7 @@ public static void TensorStackTests() Assert.Equal(30, resultTensor[1, 1, 0]); Assert.Equal(40, resultTensor[1, 1, 1]); - Tensor resultTensor2 = Tensor.Create([(nint)2, 2, 2]); + Tensor resultTensor2 = Tensor.CreateFromShape([(nint)2, 2, 2]); Tensor.StackAlongDimension([v1, v2], resultTensor2, 1); Assert.Equal(3, resultTensor2.Rank); @@ -1156,12 +1155,12 @@ public static void TensorStackTests() [Fact] public static void TensorStdDevTests() { - Tensor t0 = Tensor.Create((Enumerable.Range(0, 4).Select(i => (float)i)), lengths: [2, 2]); + Tensor t0 = Tensor.Create(Enumerable.Sequence(0, 4, 1).ToArray(), lengths: [2, 2]); Assert.Equal(StdDev([0, 1, 2, 3]), Tensor.StdDev(t0), .1); // Test that non-contiguous calculations work - Tensor fourByFour = Tensor.Create([4, 4]); + Tensor fourByFour = Tensor.CreateFromShape([4, 4]); fourByFour[[0, 0]] = 1f; fourByFour[[0, 1]] = 1f; fourByFour[[1, 0]] = 1f; @@ -1224,7 +1223,7 @@ public static float StdDev(float[] values) [Fact] public static void TensorMeanTests() { - Tensor t0 = Tensor.Create((Enumerable.Range(0, 4).Select(i => (float)i)), lengths: [2, 2]); + Tensor t0 = Tensor.Create(Enumerable.Sequence(0, 4, 1).ToArray(), lengths: [2, 2]); Assert.Equal(Mean([0, 1, 2, 3]), Tensor.Average(t0), .1); } @@ -1242,8 +1241,8 @@ public static float Mean(float[] values) [Fact] public static void TensorConcatenateTests() { - Tensor t0 = Tensor.Create((Enumerable.Range(0, 4).Select(i => (float)i)), lengths: [2, 2]); - Tensor t1 = Tensor.Create((Enumerable.Range(0, 4).Select(i => (float)i)), lengths: [2, 2]); + Tensor t0 = Tensor.Create(Enumerable.Sequence(0, 4, 1).ToArray(), lengths: [2, 2]); + Tensor t1 = Tensor.Create(Enumerable.Sequence(0, 4, 1).ToArray(), lengths: [2, 2]); var resultTensor = Tensor.Concatenate([t0, t1]); Assert.Equal(2, resultTensor.Rank); @@ -1283,7 +1282,7 @@ public static void TensorConcatenateTests() Assert.Equal(2, resultTensor[6]); Assert.Equal(3, resultTensor[7]); - Tensor t2 = Tensor.Create((Enumerable.Range(0, 4).Select(i => (float)i)), lengths: [2, 2]); + Tensor t2 = Tensor.Create(Enumerable.Sequence(0, 4, 1).ToArray(), lengths: [2, 2]); resultTensor = Tensor.Concatenate([t0, t1, t2]); Assert.Equal(2, resultTensor.Rank); @@ -1337,9 +1336,9 @@ public static void TensorConcatenateTests() Assert.Equal(2, resultTensor[1, 4]); Assert.Equal(3, resultTensor[1, 5]); - t0 = Tensor.Create((Enumerable.Range(0, 12).Select(i => (float)i)), lengths: [2, 3, 2]); - t1 = Tensor.Create((Enumerable.Range(0, 12).Select(i => (float)i)), lengths: [2, 3, 2]); - t2 = Tensor.Create((Enumerable.Range(0, 8).Select(i => (float)i)), lengths: [2, 2, 2]); + t0 = Tensor.Create(Enumerable.Sequence(0, 12, 1).ToArray(), lengths: [2, 3, 2]); + t1 = Tensor.Create(Enumerable.Sequence(0, 12, 1).ToArray(), lengths: [2, 3, 2]); + t2 = Tensor.Create(Enumerable.Sequence(0, 8, 1).ToArray(), lengths: [2, 2, 2]); Assert.Throws(() => Tensor.ConcatenateOnDimension(0, [t0, t1, t2])); Assert.Throws(() => Tensor.ConcatenateOnDimension(2, [t0, t1, t2])); Assert.Throws(() => Tensor.ConcatenateOnDimension(5, [t0, t1, t2])); @@ -1364,9 +1363,9 @@ public static void TensorConcatenateTests() Helpers.AdjustIndices(resultTensor.Rank - 1, 1, ref indices, resultTensor.Lengths); } - t0 = Tensor.Create((Enumerable.Range(0, 12).Select(i => (float)i)), lengths: [2, 2, 3]); - t1 = Tensor.Create((Enumerable.Range(0, 12).Select(i => (float)i)), lengths: [2, 2, 3]); - t2 = Tensor.Create((Enumerable.Range(0, 8).Select(i => (float)i)), lengths: [2, 2, 2]); + t0 = Tensor.Create(Enumerable.Sequence(0, 12, 1).ToArray(), lengths: [2, 2, 3]); + t1 = Tensor.Create(Enumerable.Sequence(0, 12, 1).ToArray(), lengths: [2, 2, 3]); + t2 = Tensor.Create(Enumerable.Sequence(0, 8, 1).ToArray(), lengths: [2, 2, 2]); Assert.Throws(() => Tensor.Concatenate([t0, t1, t2])); Assert.Throws(() => Tensor.ConcatenateOnDimension(1, [t0, t1, t2])); resultTensor = Tensor.ConcatenateOnDimension(2, [t0, t1, t2]); @@ -1383,9 +1382,9 @@ public static void TensorConcatenateTests() Helpers.AdjustIndices(resultTensor.Rank - 1, 1, ref indices, resultTensor.Lengths); } - t0 = Tensor.Create((Enumerable.Range(0, 12).Select(i => (float)i)), lengths: [3, 2, 2]); - t1 = Tensor.Create((Enumerable.Range(0, 12).Select(i => (float)i)), lengths: [3, 2, 2]); - t2 = Tensor.Create((Enumerable.Range(0, 8).Select(i => (float)i)), lengths: [2, 2, 2]); + t0 = Tensor.Create(Enumerable.Sequence(0, 12, 1).ToArray(), lengths: [3, 2, 2]); + t1 = Tensor.Create(Enumerable.Sequence(0, 12, 1).ToArray(), lengths: [3, 2, 2]); + t2 = Tensor.Create(Enumerable.Sequence(0, 8, 1).ToArray(), lengths: [2, 2, 2]); Assert.Throws(() => Tensor.ConcatenateOnDimension(1, [t0, t1, t2])); Assert.Throws(() => Tensor.ConcatenateOnDimension(2, [t0, t1, t2])); resultTensor = Tensor.ConcatenateOnDimension(0, [t0, t1, t2]); @@ -1406,7 +1405,7 @@ public static void TensorConcatenateTests() [Fact] public static void TensorTransposeTests() { - Tensor t0 = Tensor.Create((Enumerable.Range(0, 4).Select(i => (float)i)), lengths: [2, 2]); + Tensor t0 = Tensor.Create(Enumerable.Sequence(0, 4, 1).ToArray(), lengths: [2, 2]); var t1 = t0.PermuteDimensions([]); Assert.Equal(0, t1[0, 0]); @@ -1414,7 +1413,7 @@ public static void TensorTransposeTests() Assert.Equal(1, t1[1, 0]); Assert.Equal(3, t1[1, 1]); - t0 = Tensor.Create((Enumerable.Range(0, 6).Select(i => (float)i)), lengths: [2, 3]); + t0 = Tensor.Create(Enumerable.Sequence(0, 6, 1).ToArray(), lengths: [2, 3]); t1 = t0.PermuteDimensions([]); Assert.Equal(3, t1.Lengths[0]); @@ -1426,7 +1425,7 @@ public static void TensorTransposeTests() Assert.Equal(2, t1[2, 0]); Assert.Equal(5, t1[2, 1]); - t0 = Tensor.Create((Enumerable.Range(0, 6).Select(i => (float)i)), lengths: [1, 2, 3]); + t0 = Tensor.Create(Enumerable.Sequence(0, 6, 1).ToArray(), lengths: [1, 2, 3]); t1 = t0.PermuteDimensions([]); Assert.Equal(3, t1.Lengths[0]); @@ -1439,7 +1438,7 @@ public static void TensorTransposeTests() Assert.Equal(2, t1[2, 0, 0]); Assert.Equal(5, t1[2, 1, 0]); - t0 = Tensor.Create((Enumerable.Range(0, 12).Select(i => (float)i)), lengths: [2, 2, 3]); + t0 = Tensor.Create(Enumerable.Sequence(0, 12, 1).ToArray(), lengths: [2, 2, 3]); t1 = t0.PermuteDimensions([]); Assert.Equal(3, t1.Lengths[0]); @@ -1458,7 +1457,7 @@ public static void TensorTransposeTests() Assert.Equal(5, t1[2, 1, 0]); Assert.Equal(11, t1[2, 1, 1]); - t0 = Tensor.Create((Enumerable.Range(0, 12).Select(i => (float)i)), lengths: [2, 2, 3]); + t0 = Tensor.Create(Enumerable.Sequence(0, 12, 1).ToArray(), lengths: [2, 2, 3]); t1 = t0.PermuteDimensions([1, 2, 0]); Assert.Equal(2, t1.Lengths[0]); @@ -1481,7 +1480,7 @@ public static void TensorTransposeTests() [Fact] public static void TensorPermuteTests() { - Tensor t0 = Tensor.Create((Enumerable.Range(0, 4).Select(i => (float)i)), lengths: [2, 2]); + Tensor t0 = Tensor.Create(Enumerable.Sequence(0, 4, 1).ToArray(), lengths: [2, 2]); var t1 = Tensor.Transpose(t0); Assert.Equal(0, t1[0, 0]); @@ -1489,7 +1488,7 @@ public static void TensorPermuteTests() Assert.Equal(1, t1[1, 0]); Assert.Equal(3, t1[1, 1]); - t0 = Tensor.Create((Enumerable.Range(0, 12).Select(i => (float)i)), lengths: [2, 2, 3]); + t0 = Tensor.Create(Enumerable.Sequence(0, 12, 1).ToArray(), lengths: [2, 2, 3]); t1 = Tensor.Transpose(t0); Assert.Equal(2, t1.Lengths[0]); @@ -1515,7 +1514,7 @@ public static void IntArrayAsTensor() int[] a = [91, 92, -93, 94]; TensorSpan t1 = a.AsTensorSpan(); nint[] dims = [4]; - var tensor = Tensor.CreateUninitialized(dims.AsSpan(), false); + var tensor = Tensor.CreateFromShapeUninitialized(dims.AsSpan(), false); t1.CopyTo(tensor); Assert.Equal(1, tensor.Rank); @@ -1544,7 +1543,7 @@ public static void IntArrayAsTensor() a[3] = 94; t1 = a.AsTensorSpan([2, 2]); dims = [2, 2]; - tensor = Tensor.CreateUninitialized(dims.AsSpan(), false); + tensor = Tensor.CreateFromShapeUninitialized(dims.AsSpan(), false); t1.CopyTo(tensor); Assert.Equal(a, tensor.ToArray()); Assert.Equal(2, tensor.Rank); @@ -1575,7 +1574,7 @@ public static void IntArrayAsTensor() public static void TensorFillTest() { nint[] dims = [3, 3]; - var tensor = Tensor.CreateUninitialized(dims.AsSpan(), false); + var tensor = Tensor.CreateFromShapeUninitialized(dims.AsSpan(), false); tensor.Fill(-1); var enumerator = tensor.GetEnumerator(); while (enumerator.MoveNext()) @@ -1598,7 +1597,7 @@ public static void TensorFillTest() } dims = [9]; - tensor = Tensor.CreateUninitialized(dims.AsSpan(), false); + tensor = Tensor.CreateFromShapeUninitialized(dims.AsSpan(), false); tensor.Fill(-1); enumerator = tensor.GetEnumerator(); while (enumerator.MoveNext()) @@ -1607,7 +1606,7 @@ public static void TensorFillTest() } dims = [3, 3, 3]; - tensor = Tensor.CreateUninitialized(dims.AsSpan(), false); + tensor = Tensor.CreateFromShapeUninitialized(dims.AsSpan(), false); tensor.Fill(-1); enumerator = tensor.GetEnumerator(); while (enumerator.MoveNext()) @@ -1616,7 +1615,7 @@ public static void TensorFillTest() } dims = [3, 2, 2]; - tensor = Tensor.CreateUninitialized(dims.AsSpan(), false); + tensor = Tensor.CreateFromShapeUninitialized(dims.AsSpan(), false); tensor.Fill(-1); enumerator = tensor.GetEnumerator(); while (enumerator.MoveNext()) @@ -1625,7 +1624,7 @@ public static void TensorFillTest() } dims = [2, 2, 2, 2]; - tensor = Tensor.CreateUninitialized(dims.AsSpan(), false); + tensor = Tensor.CreateFromShapeUninitialized(dims.AsSpan(), false); tensor.Fill(-1); enumerator = tensor.GetEnumerator(); while (enumerator.MoveNext()) @@ -1634,7 +1633,7 @@ public static void TensorFillTest() } dims = [3, 2, 2, 2]; - tensor = Tensor.CreateUninitialized(dims.AsSpan(), false); + tensor = Tensor.CreateFromShapeUninitialized(dims.AsSpan(), false); tensor.Fill(-1); enumerator = tensor.GetEnumerator(); while (enumerator.MoveNext()) @@ -1648,7 +1647,7 @@ public static void TensorClearTest() { int[] a = [1, 2, 3, 4, 5, 6, 7, 8, 9]; TensorSpan t1 = a.AsTensorSpan([3, 3]); - var tensor = Tensor.CreateUninitialized([3, 3], false); + var tensor = Tensor.CreateFromShapeUninitialized([3, 3], false); t1.CopyTo(tensor); var slice = tensor.Slice(0..2, 0..2); slice.Clear(); @@ -1678,7 +1677,7 @@ public static void TensorClearTest() a = [1, 2, 3, 4, 5, 6, 7, 8, 9]; t1 = a.AsTensorSpan([9]); - tensor = Tensor.CreateUninitialized([9], false); + tensor = Tensor.CreateFromShapeUninitialized([9], false); t1.CopyTo(tensor); slice = tensor.Slice(0..1); slice.Clear(); @@ -1705,7 +1704,7 @@ public static void TensorClearTest() a = [.. Enumerable.Range(0, 27)]; t1 = a.AsTensorSpan([3, 3, 3]); - tensor = Tensor.CreateUninitialized([3, 3, 3], false); + tensor = Tensor.CreateFromShapeUninitialized([3, 3, 3], false); t1.CopyTo(tensor); tensor.Clear(); enumerator = tensor.GetEnumerator(); @@ -1716,7 +1715,7 @@ public static void TensorClearTest() a = [.. Enumerable.Range(0, 12)]; t1 = a.AsTensorSpan([3, 2, 2]); - tensor = Tensor.CreateUninitialized([3, 2, 2], false); + tensor = Tensor.CreateFromShapeUninitialized([3, 2, 2], false); t1.CopyTo(tensor); tensor.Clear(); enumerator = tensor.GetEnumerator(); @@ -1727,7 +1726,7 @@ public static void TensorClearTest() a = [.. Enumerable.Range(0, 16)]; t1 = a.AsTensorSpan([2, 2, 2, 2]); - tensor = Tensor.CreateUninitialized([2, 2, 2, 2], false); + tensor = Tensor.CreateFromShapeUninitialized([2, 2, 2, 2], false); t1.CopyTo(tensor); tensor.Clear(); enumerator = tensor.GetEnumerator(); @@ -1738,7 +1737,7 @@ public static void TensorClearTest() a = [.. Enumerable.Range(0, 24)]; t1 = a.AsTensorSpan([3, 2, 2, 2]); - tensor = Tensor.CreateUninitialized([3, 2, 2, 2], false); + tensor = Tensor.CreateFromShapeUninitialized([3, 2, 2, 2], false); t1.CopyTo(tensor); tensor.Clear(); enumerator = tensor.GetEnumerator(); @@ -1892,7 +1891,7 @@ public static void TensorCopyTest() int[] rightData = new int[9]; nint[] dims = [3, 3]; TensorSpan leftSpan = leftData.AsTensorSpan([3, 3]); - var tensor = Tensor.CreateUninitialized(dims.AsSpan(), false); + var tensor = Tensor.CreateFromShapeUninitialized(dims.AsSpan(), false); TensorSpan rightSpan = rightData.AsTensorSpan([3, 3]); leftSpan.CopyTo(tensor); var leftEnum = leftSpan.GetEnumerator(); @@ -1920,7 +1919,7 @@ public static void TensorCopyTest() leftData = [1, 2, 3, 4, 5, 6, 7, 8, 9]; dims = [15]; TensorSpan leftSpan = leftData.AsTensorSpan([9]); - tensor = Tensor.Create(dims.AsSpan(), false); + tensor = Tensor.CreateFromShape(dims.AsSpan(), false); leftSpan.CopyTo(tensor); } ); @@ -1940,7 +1939,7 @@ public static void TensorTryCopyTest() int[] rightData = new int[9]; TensorSpan leftSpan = leftData.AsTensorSpan([3, 3]); nint[] dims = [3, 3]; - var tensor = Tensor.CreateUninitialized(dims.AsSpan(), false); + var tensor = Tensor.CreateFromShapeUninitialized(dims.AsSpan(), false); TensorSpan rightSpan = rightData.AsTensorSpan([3, 3]); var success = leftSpan.TryCopyTo(tensor); Assert.True(success); @@ -1962,14 +1961,14 @@ public static void TensorTryCopyTest() leftData = [1, 2, 3, 4, 5, 6, 7, 8, 9]; dims = [15]; leftSpan = leftData.AsTensorSpan([9]); - tensor = Tensor.Create(dims.AsSpan(), false); + tensor = Tensor.CreateFromShape(dims.AsSpan(), false); success = leftSpan.TryCopyTo(tensor); Assert.False(success); leftData = [.. Enumerable.Range(0, 27)]; var l = leftData.AsTensorSpan([3, 3, 3]); dims = [2, 2]; - tensor = Tensor.Create(dims.AsSpan(), false); + tensor = Tensor.CreateFromShape(dims.AsSpan(), false); var r = new TensorSpan(); success = l.TryCopyTo(tensor); Assert.False(success); @@ -1984,7 +1983,7 @@ public static void TensorTryCopyTest() public static void TensorSliceTest() { int[] a = [1, 2, 3, 4, 5, 6, 7, 8, 9]; - var tensor = Tensor.CreateUninitialized([3, 3], false); + var tensor = Tensor.CreateFromShapeUninitialized([3, 3], false); //Assert.Throws(() => tensor.Slice(0..1)); //Assert.Throws(() => tensor.Slice(1..2)); @@ -2052,7 +2051,7 @@ public static void TensorSliceTest() int[] numbers = [.. Enumerable.Range(0, 27)]; intSpan = numbers.AsTensorSpan([3, 3, 3]); - tensor = Tensor.CreateUninitialized([3, 3, 3], false); + tensor = Tensor.CreateFromShapeUninitialized([3, 3, 3], false); intSpan.CopyTo(tensor.AsTensorSpan()); sp = tensor.Slice(1..2, 1..2, 1..2); Assert.Equal(13, sp[0, 0, 0]); @@ -2085,7 +2084,7 @@ public static void TensorSliceTest() numbers = [.. Enumerable.Range(0, 16)]; intSpan = numbers.AsTensorSpan([2, 2, 2, 2]); - tensor = Tensor.CreateUninitialized([2, 2, 2, 2], false); + tensor = Tensor.CreateFromShapeUninitialized([2, 2, 2, 2], false); intSpan.CopyTo(tensor.AsTensorSpan()); sp = tensor.Slice(1..2, 0..2, 1..2, 0..2); Assert.Equal(10, sp[0, 0, 0, 0]); @@ -2107,7 +2106,7 @@ public static void TensorReshapeTest() { int[] a = [1, 2, 3, 4, 5, 6, 7, 8, 9]; nint[] dims = [9]; - var tensor = Tensor.CreateUninitialized(dims.AsSpan(), false); + var tensor = Tensor.CreateFromShapeUninitialized(dims.AsSpan(), false); var span = a.AsTensorSpan(dims); span.CopyTo(tensor); @@ -2146,7 +2145,7 @@ public static void TensorReshapeTest() Assert.Throws(() => Tensor.Reshape(tensor, [1, 2, 3, 4, 5])); // Make sure reshape works correctly with 0 strides. - tensor = Tensor.Create((ReadOnlySpan)[2], [0], false); + tensor = Tensor.CreateFromShape((ReadOnlySpan)[2], [0], false); tensor = Tensor.Reshape(tensor, [1, 2]); Assert.Equal(2, tensor.Rank); Assert.Equal(1, tensor.Lengths[0]); @@ -2154,7 +2153,7 @@ public static void TensorReshapeTest() Assert.Equal(0, tensor.Strides[0]); Assert.Equal(0, tensor.Strides[1]); - tensor = Tensor.Create((ReadOnlySpan)[2], [0], false); + tensor = Tensor.CreateFromShape((ReadOnlySpan)[2], [0], false); tensor = Tensor.Reshape(tensor, [2, 1]); Assert.Equal(2, tensor.Rank); Assert.Equal(2, tensor.Lengths[0]); @@ -2176,7 +2175,7 @@ public static void TensorReshapeTest() public static void TensorSqueezeTest() { nint[] dims = [1, 2]; - var tensor = Tensor.Create(dims.AsSpan(), false); + var tensor = Tensor.CreateFromShape(dims.AsSpan(), false); Assert.Equal(2, tensor.Rank); Assert.Equal(1, tensor.Lengths[0]); Assert.Equal(2, tensor.Lengths[1]); @@ -2186,7 +2185,7 @@ public static void TensorSqueezeTest() Assert.Equal(2, tensor.Lengths[0]); dims = [1, 2, 1]; - tensor = Tensor.Create(dims.AsSpan(), false); + tensor = Tensor.CreateFromShape(dims.AsSpan(), false); Assert.Equal(3, tensor.Rank); Assert.Equal(1, tensor.Lengths[0]); Assert.Equal(2, tensor.Lengths[1]); @@ -2197,7 +2196,7 @@ public static void TensorSqueezeTest() Assert.Equal(2, tensor.Lengths[0]); dims = [1, 2, 1]; - tensor = Tensor.Create(dims.AsSpan(), false); + tensor = Tensor.CreateFromShape(dims.AsSpan(), false); Assert.Equal(3, tensor.Rank); Assert.Equal(1, tensor.Lengths[0]); Assert.Equal(2, tensor.Lengths[1]); @@ -2209,7 +2208,7 @@ public static void TensorSqueezeTest() Assert.Equal(1, tensor.Lengths[1]); dims = [1, 2, 1]; - tensor = Tensor.Create(dims.AsSpan(), false); + tensor = Tensor.CreateFromShape(dims.AsSpan(), false); Assert.Equal(3, tensor.Rank); Assert.Equal(1, tensor.Lengths[0]); Assert.Equal(2, tensor.Lengths[1]); @@ -2221,7 +2220,7 @@ public static void TensorSqueezeTest() Assert.Equal(2, tensor.Lengths[1]); dims = [1, 2, 1]; - tensor = Tensor.Create(dims.AsSpan(), false); + tensor = Tensor.CreateFromShape(dims.AsSpan(), false); Assert.Equal(3, tensor.Rank); Assert.Equal(1, tensor.Lengths[0]); Assert.Equal(2, tensor.Lengths[1]); @@ -2234,7 +2233,7 @@ public static void TensorSqueezeTest() [Fact] public static void TensorUnsqueezeTest() { - var tensor = Tensor.Create((ReadOnlySpan)[2], [0], false); + var tensor = Tensor.CreateFromShape((ReadOnlySpan)[2], [0], false); tensor = Tensor.Unsqueeze(tensor, 0); Assert.Equal(2, tensor.Rank); Assert.Equal(1, tensor.Lengths[0]); @@ -2242,7 +2241,7 @@ public static void TensorUnsqueezeTest() Assert.Equal(0, tensor.Strides[0]); Assert.Equal(0, tensor.Strides[1]); - tensor = Tensor.Create((ReadOnlySpan)[2], false); + tensor = Tensor.CreateFromShape((ReadOnlySpan)[2], false); Assert.Equal(1, tensor.Rank); Assert.Equal(2, tensor.Lengths[0]); Assert.Equal(1, tensor.Strides[0]); @@ -2274,7 +2273,7 @@ public static void TensorUnsqueezeTest() Assert.Equal(0, tensor.Strides[2]); Assert.Equal(1, tensor.Strides[3]); - tensor = Tensor.Create((ReadOnlySpan)[2], false); + tensor = Tensor.CreateFromShape((ReadOnlySpan)[2], false); Assert.Equal(1, tensor.Rank); Assert.Equal(2, tensor.Lengths[0]); @@ -2283,14 +2282,14 @@ public static void TensorUnsqueezeTest() Assert.Equal(2, tensor.Lengths[0]); Assert.Equal(1, tensor.Lengths[1]); - tensor = Tensor.Create((ReadOnlySpan)[2], false); + tensor = Tensor.CreateFromShape((ReadOnlySpan)[2], false); Assert.Equal(1, tensor.Rank); Assert.Equal(2, tensor.Lengths[0]); Assert.Throws(() => Tensor.Unsqueeze(tensor, -1)); Assert.Throws(() => Tensor.Unsqueeze(tensor, 2)); - Tensor t0 = Tensor.Create(Enumerable.Range(0, 2), default); + Tensor t0 = Tensor.Create(Enumerable.Range(0, 2).ToArray()); t0 = Tensor.Unsqueeze(t0, 1); Assert.Equal(0, t0[0, 0]); Assert.Equal(1, t0[1, 0]); @@ -2793,31 +2792,31 @@ public void IsDenseTests() { // Dense - Assert.True(Tensor.Create([(nint)1]).IsDense); - Assert.True(Tensor.Create([(nint)1], [0]).IsDense); + Assert.True(Tensor.CreateFromShape([(nint)1]).IsDense); + Assert.True(Tensor.CreateFromShape([(nint)1], [0]).IsDense); - Assert.True(Tensor.Create([(nint)2]).IsDense); - Assert.True(Tensor.Create([(nint)2], [1]).IsDense); + Assert.True(Tensor.CreateFromShape([(nint)2]).IsDense); + Assert.True(Tensor.CreateFromShape([(nint)2], [1]).IsDense); - Assert.True(Tensor.Create([(nint)1, 2]).IsDense); - Assert.True(Tensor.Create([(nint)1, 2], [0, 1]).IsDense); + Assert.True(Tensor.CreateFromShape([(nint)1, 2]).IsDense); + Assert.True(Tensor.CreateFromShape([(nint)1, 2], [0, 1]).IsDense); - Assert.True(Tensor.Create([(nint)2, 2]).IsDense); - Assert.True(Tensor.Create([(nint)2, 2], [2, 1]).IsDense); + Assert.True(Tensor.CreateFromShape([(nint)2, 2]).IsDense); + Assert.True(Tensor.CreateFromShape([(nint)2, 2], [2, 1]).IsDense); - Assert.True(Tensor.Create([(nint)4, 3]).IsDense); - Assert.True(Tensor.Create([(nint)4, 3], [3, 1]).IsDense); + Assert.True(Tensor.CreateFromShape([(nint)4, 3]).IsDense); + Assert.True(Tensor.CreateFromShape([(nint)4, 3], [3, 1]).IsDense); // Non-dense - Assert.False(Tensor.Create([(nint)2], [0]).IsDense); - Assert.False(Tensor.Create([(nint)2], [2]).IsDense); + Assert.False(Tensor.CreateFromShape([(nint)2], [0]).IsDense); + Assert.False(Tensor.CreateFromShape([(nint)2], [2]).IsDense); - Assert.False(Tensor.Transpose(Tensor.Create([(nint)2, 2], [2, 1])).IsDense); - Assert.False(Tensor.Create([(nint)2, 2], [1, 0]).IsDense); + Assert.False(Tensor.Transpose(Tensor.CreateFromShape([(nint)2, 2], [2, 1])).IsDense); + Assert.False(Tensor.CreateFromShape([(nint)2, 2], [1, 0]).IsDense); - Assert.False(Tensor.Transpose(Tensor.Create([(nint)3, 4], [8, 1])).IsDense); - Assert.False(Tensor.Create([(nint)3, 4], [1, 0]).IsDense); + Assert.False(Tensor.Transpose(Tensor.CreateFromShape([(nint)3, 4], [8, 1])).IsDense); + Assert.False(Tensor.CreateFromShape([(nint)3, 4], [1, 0]).IsDense); } [Fact] @@ -2825,42 +2824,42 @@ public void HasAnyDenseDimensionTests() { // Dense - Assert.True(Tensor.Create([(nint)1]).HasAnyDenseDimensions); - Assert.True(Tensor.Create([(nint)1], [0]).HasAnyDenseDimensions); + Assert.True(Tensor.CreateFromShape([(nint)1]).HasAnyDenseDimensions); + Assert.True(Tensor.CreateFromShape([(nint)1], [0]).HasAnyDenseDimensions); - Assert.True(Tensor.Create([(nint)2]).HasAnyDenseDimensions); - Assert.True(Tensor.Create([(nint)2], [1]).HasAnyDenseDimensions); + Assert.True(Tensor.CreateFromShape([(nint)2]).HasAnyDenseDimensions); + Assert.True(Tensor.CreateFromShape([(nint)2], [1]).HasAnyDenseDimensions); - Assert.True(Tensor.Create([(nint)1, 2]).HasAnyDenseDimensions); - Assert.True(Tensor.Create([(nint)1, 2], [0, 1]).HasAnyDenseDimensions); + Assert.True(Tensor.CreateFromShape([(nint)1, 2]).HasAnyDenseDimensions); + Assert.True(Tensor.CreateFromShape([(nint)1, 2], [0, 1]).HasAnyDenseDimensions); - Assert.True(Tensor.Create([(nint)2, 2]).HasAnyDenseDimensions); - Assert.True(Tensor.Create([(nint)2, 2], [2, 1]).HasAnyDenseDimensions); + Assert.True(Tensor.CreateFromShape([(nint)2, 2]).HasAnyDenseDimensions); + Assert.True(Tensor.CreateFromShape([(nint)2, 2], [2, 1]).HasAnyDenseDimensions); - Assert.True(Tensor.Create([(nint)4, 3]).HasAnyDenseDimensions); - Assert.True(Tensor.Create([(nint)4, 3], [3, 1]).HasAnyDenseDimensions); + Assert.True(Tensor.CreateFromShape([(nint)4, 3]).HasAnyDenseDimensions); + Assert.True(Tensor.CreateFromShape([(nint)4, 3], [3, 1]).HasAnyDenseDimensions); // Non-dense w/ Dense Dimension - Assert.True(Tensor.Create([(nint)1], [0]).HasAnyDenseDimensions); + Assert.True(Tensor.CreateFromShape([(nint)1], [0]).HasAnyDenseDimensions); - Assert.True(Tensor.Create([(nint)2, 1], [1, 0]).HasAnyDenseDimensions); + Assert.True(Tensor.CreateFromShape([(nint)2, 1], [1, 0]).HasAnyDenseDimensions); - Assert.True(Tensor.Create([(nint)3, 1], [1, 0]).HasAnyDenseDimensions); + Assert.True(Tensor.CreateFromShape([(nint)3, 1], [1, 0]).HasAnyDenseDimensions); // Non-dense w/ Non-dense Dimension - Assert.False(Tensor.Create([(nint)2], [0]).HasAnyDenseDimensions); + Assert.False(Tensor.CreateFromShape([(nint)2], [0]).HasAnyDenseDimensions); - Assert.False(Tensor.Create([(nint)2, 2], [1, 0]).HasAnyDenseDimensions); + Assert.False(Tensor.CreateFromShape([(nint)2, 2], [1, 0]).HasAnyDenseDimensions); - Assert.False(Tensor.Create([(nint)3, 4], [1, 0]).HasAnyDenseDimensions); + Assert.False(Tensor.CreateFromShape([(nint)3, 4], [1, 0]).HasAnyDenseDimensions); - Assert.False(Tensor.Create([(nint)2], [2]).HasAnyDenseDimensions); + Assert.False(Tensor.CreateFromShape([(nint)2], [2]).HasAnyDenseDimensions); - Assert.False(Tensor.Transpose(Tensor.Create([(nint)2, 2], [2, 1])).HasAnyDenseDimensions); + Assert.False(Tensor.Transpose(Tensor.CreateFromShape([(nint)2, 2], [2, 1])).HasAnyDenseDimensions); - Assert.False(Tensor.Transpose(Tensor.Create([(nint)3, 4], [8, 1])).HasAnyDenseDimensions); + Assert.False(Tensor.Transpose(Tensor.CreateFromShape([(nint)3, 4], [8, 1])).HasAnyDenseDimensions); } [Fact] @@ -2868,31 +2867,31 @@ public void ToDenseTensorTests() { // Dense - AssertReturnsSelf(Tensor.Create([(nint)1])); - AssertReturnsSelf(Tensor.Create([(nint)1], [0])); + AssertReturnsSelf(Tensor.CreateFromShape([(nint)1])); + AssertReturnsSelf(Tensor.CreateFromShape([(nint)1], [0])); - AssertReturnsSelf(Tensor.Create([(nint)2])); - AssertReturnsSelf(Tensor.Create([(nint)2], [1])); + AssertReturnsSelf(Tensor.CreateFromShape([(nint)2])); + AssertReturnsSelf(Tensor.CreateFromShape([(nint)2], [1])); - AssertReturnsSelf(Tensor.Create([(nint)1, 2])); - AssertReturnsSelf(Tensor.Create([(nint)1, 2], [0, 1])); + AssertReturnsSelf(Tensor.CreateFromShape([(nint)1, 2])); + AssertReturnsSelf(Tensor.CreateFromShape([(nint)1, 2], [0, 1])); - AssertReturnsSelf(Tensor.Create([(nint)2, 2])); - AssertReturnsSelf(Tensor.Create([(nint)2, 2], [2, 1])); + AssertReturnsSelf(Tensor.CreateFromShape([(nint)2, 2])); + AssertReturnsSelf(Tensor.CreateFromShape([(nint)2, 2], [2, 1])); - AssertReturnsSelf(Tensor.Create([(nint)4, 3])); - AssertReturnsSelf(Tensor.Create([(nint)4, 3], [3, 1])); + AssertReturnsSelf(Tensor.CreateFromShape([(nint)4, 3])); + AssertReturnsSelf(Tensor.CreateFromShape([(nint)4, 3], [3, 1])); // Non-dense - AssertReturnsNewTensor(Tensor.Create([(nint)2], [0])); - AssertReturnsNewTensor(Tensor.Create([(nint)2], [2])); + AssertReturnsNewTensor(Tensor.CreateFromShape([(nint)2], [0])); + AssertReturnsNewTensor(Tensor.CreateFromShape([(nint)2], [2])); - AssertReturnsNewTensor(Tensor.Transpose(Tensor.Create([(nint)2, 2], [2, 1]))); - AssertReturnsNewTensor(Tensor.Create([(nint)2, 2], [1, 0])); + AssertReturnsNewTensor(Tensor.Transpose(Tensor.CreateFromShape([(nint)2, 2], [2, 1]))); + AssertReturnsNewTensor(Tensor.CreateFromShape([(nint)2, 2], [1, 0])); - AssertReturnsNewTensor(Tensor.Transpose(Tensor.Create([(nint)3, 4], [8, 1]))); - AssertReturnsNewTensor(Tensor.Create([(nint)3, 4], [1, 0])); + AssertReturnsNewTensor(Tensor.Transpose(Tensor.CreateFromShape([(nint)3, 4], [8, 1]))); + AssertReturnsNewTensor(Tensor.CreateFromShape([(nint)3, 4], [1, 0])); static void AssertReturnsSelf(Tensor tensor) { @@ -2909,5 +2908,286 @@ static void AssertReturnsNewTensor(Tensor tensor) Assert.True(Tensor.EqualsAll(tensor, denseTensor)); } } + + [Fact] + public static void GetSpanTest() + { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + + Span span = tensorSpan.GetSpan([0, 0], 16); + Assert.Equal(16, span.Length); + Assert.Equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], span); + + span = tensorSpan.GetSpan([1, 1], 3); + Assert.Equal(3, span.Length); + Assert.Equal([5, 6, 7], span); + + span = tensorSpan.GetSpan([3, 0], 4); + Assert.Equal(4, span.Length); + Assert.Equal([12, 13, 14, 15], span); + + span = tensorSpan.GetSpan([0, 3], 1); + Assert.Equal(1, span.Length); + Assert.Equal([3], span); + + span = tensorSpan.GetSpan([3, 3], 1); + Assert.Equal(1, span.Length); + Assert.Equal([15], span); + } + + [Fact] + public static void GetSpanThrowsForInvalidIndexesTest() + { + Assert.Throws(() => { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([4, 0], 17); + }); + + Assert.Throws(() => { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([0, 4], 17); + }); + + Assert.Throws(() => { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([4, 4], 17); + }); + } + + [Fact] + public static void GetSpanThrowsForInvalidLengthsTest() + { + Assert.Throws(() => { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([0, 0], -1); + }); + + Assert.Throws(() => { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([0, 0], 17); + }); + + Assert.Throws(() => { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([1, 1], 4); + }); + + Assert.Throws(() => { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([3, 0], 5); + }); + + Assert.Throws(() => { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([0, 3], 2); + }); + + Assert.Throws(() => { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.GetSpan([3, 3], 2); + }); + } + + [Fact] + public static void TryGetSpanTest() + { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + + Assert.True(tensorSpan.TryGetSpan([0, 0], 16, out Span span)); + Assert.Equal(16, span.Length); + Assert.Equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], span); + + Assert.True(tensorSpan.TryGetSpan([1, 1], 3, out span)); + Assert.Equal(3, span.Length); + Assert.Equal([5, 6, 7], span); + + Assert.True(tensorSpan.TryGetSpan([3, 0], 4, out span)); + Assert.Equal(4, span.Length); + Assert.Equal([12, 13, 14, 15], span); + + Assert.True(tensorSpan.TryGetSpan([0, 3], 1, out span)); + Assert.Equal(1, span.Length); + Assert.Equal([3], span); + + Assert.True(tensorSpan.TryGetSpan([3, 3], 1, out span)); + Assert.Equal(1, span.Length); + Assert.Equal([15], span); + } + + [Fact] + public static void TryGetSpanThrowsForInvalidIndexesTest() + { + Assert.Throws(() => { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.TryGetSpan([4, 0], 17, out Span _); + }); + + Assert.Throws(() => { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.TryGetSpan([0, 4], 17, out Span _); + }); + + Assert.Throws(() => { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + _ = tensorSpan.TryGetSpan([4, 4], 17, out Span _); + }); + } + + [Fact] + public static void TryGetSpanFailsForInvalidLengthsTest() + { + Tensor tensorSpan = Tensor.Create(Enumerable.Range(0, 16).ToArray(), [4, 4]); + + Assert.False(tensorSpan.TryGetSpan([0, 0], -1, out Span span)); + Assert.Equal(0, span.Length); + + Assert.False(tensorSpan.TryGetSpan([0, 0], 17, out span)); + Assert.Equal(0, span.Length); + + Assert.False(tensorSpan.TryGetSpan([1, 1], 4, out span)); + Assert.Equal(0, span.Length); + + Assert.False(tensorSpan.TryGetSpan([3, 0], 5, out span)); + Assert.Equal(0, span.Length); + + Assert.False(tensorSpan.TryGetSpan([0, 3], 2, out span)); + Assert.Equal(0, span.Length); + + Assert.False(tensorSpan.TryGetSpan([3, 3], 2, out span)); + Assert.Equal(0, span.Length); + } + + [Fact] + public static void ToStringTest() + { + Tensor tensor = Tensor.Create([1, 2, 3, 4, 5], lengths: [5]); + string expected = "System.Numerics.Tensors.Tensor[5]"; + Assert.Equal(expected, tensor.ToString()); + + tensor = Tensor.Create([1, 2, 3, 4], lengths: [2, 2]); + expected = "System.Numerics.Tensors.Tensor[2, 2]"; + Assert.Equal(expected, tensor.ToString()); + + tensor = Tensor.Create(Enumerable.Range(1, 27).ToArray(), lengths: [3, 3, 3]); + expected = "System.Numerics.Tensors.Tensor[3, 3, 3]"; + Assert.Equal(expected, tensor.ToString()); + } + + [Fact] + public static void ToStringAllDataTest() + { + Tensor tensor = Tensor.Create([1, 2, 3, 4, 5], lengths: [5]); + string expected = """ + System.Numerics.Tensors.Tensor[5] { + [1, 2, 3, 4, 5] + } + """; + Assert.Equal(expected, tensor.ToString([5])); + + tensor = Tensor.Create([1, 2, 3, 4], lengths: [2, 2]); + expected = """ + System.Numerics.Tensors.Tensor[2, 2] { + [1, 2], + [3, 4] + } + """; + Assert.Equal(expected, tensor.ToString([2, 2])); + + tensor = Tensor.Create(Enumerable.Range(1, 27).ToArray(), lengths: [3, 3, 3]); + expected = """ + System.Numerics.Tensors.Tensor[3, 3, 3] { + [ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9] + ], + [ + [10, 11, 12], + [13, 14, 15], + [16, 17, 18] + ], + [ + [19, 20, 21], + [22, 23, 24], + [25, 26, 27] + ] + } + """; + Assert.Equal(expected, tensor.ToString([3, 3, 3])); + } + + [Fact] + public static void ToStringPartialDataTest() + { + Tensor tensor = Tensor.Create([1, 2, 3, 4, 5], lengths: [5]); + string expected = """ + System.Numerics.Tensors.Tensor[5] { + [1, 2, 3, ..] + } + """; + Assert.Equal(expected, tensor.ToString([3])); + + tensor = Tensor.Create([1, 2, 3, 4], lengths: [2, 2]); + expected = """ + System.Numerics.Tensors.Tensor[2, 2] { + [1, ..], + [3, ..] + } + """; + Assert.Equal(expected, tensor.ToString([2, 1])); + + tensor = Tensor.Create(Enumerable.Range(1, 27).ToArray(), lengths: [3, 3, 3]); + expected = """ + System.Numerics.Tensors.Tensor[3, 3, 3] { + [ + [1, 2, ..], + [4, 5, ..], + .. + ], + [ + [10, 11, ..], + [13, 14, ..], + .. + ], + .. + } + """; + Assert.Equal(expected, tensor.ToString([2, 2, 2])); + } + + [Fact] + public static void ToStringZeroDataTest() + { + Tensor tensor = Tensor.Create([1, 2, 3, 4, 5], lengths: [5]); + string expected = """ + System.Numerics.Tensors.Tensor[5] { + [..] + } + """; + Assert.Equal(expected, tensor.ToString([0])); + + tensor = Tensor.Create([1, 2, 3, 4], lengths: [2, 2]); + expected = """ + System.Numerics.Tensors.Tensor[2, 2] { + [..], + [..] + } + """; + Assert.Equal(expected, tensor.ToString([2, 0])); + + tensor = Tensor.Create(Enumerable.Range(1, 27).ToArray(), lengths: [3, 3, 3]); + expected = """ + System.Numerics.Tensors.Tensor[3, 3, 3] { + [ + .. + ], + [ + .. + ], + .. + } + """; + Assert.Equal(expected, tensor.ToString([2, 0, 2])); + } } } diff --git a/src/libraries/System.ObjectModel/System.ObjectModel.slnx b/src/libraries/System.ObjectModel/System.ObjectModel.slnx index 3dae700e442067..78c35d02f4a4f5 100644 --- a/src/libraries/System.ObjectModel/System.ObjectModel.slnx +++ b/src/libraries/System.ObjectModel/System.ObjectModel.slnx @@ -76,6 +76,14 @@ + + + + + + + + @@ -157,6 +165,14 @@ + + + + + + + + diff --git a/src/libraries/System.ObjectModel/src/System.ObjectModel.csproj b/src/libraries/System.ObjectModel/src/System.ObjectModel.csproj index 0ef93fda9ecd4b..2d5f1c0367de38 100644 --- a/src/libraries/System.ObjectModel/src/System.ObjectModel.csproj +++ b/src/libraries/System.ObjectModel/src/System.ObjectModel.csproj @@ -32,10 +32,10 @@ - - - - + + + + diff --git a/src/libraries/System.ObjectModel/tests/ReadOnlyDictionary/ReadOnlyDictionaryTests.cs b/src/libraries/System.ObjectModel/tests/ReadOnlyDictionary/ReadOnlyDictionaryTests.cs index fc22f2c68cbe2f..31d247a4dd15df 100644 --- a/src/libraries/System.ObjectModel/tests/ReadOnlyDictionary/ReadOnlyDictionaryTests.cs +++ b/src/libraries/System.ObjectModel/tests/ReadOnlyDictionary/ReadOnlyDictionaryTests.cs @@ -391,6 +391,7 @@ public ReadOnlyDictionaryOverNonGenericTests() protected override bool IsGenericCompatibility { get { return false; } } protected override bool ItemsMustBeUnique { get { return true; } } protected override bool ItemsMustBeNonNull { get { return true; } } + protected override bool CurrentAfterFullEnumerationThrows { get { return false; } } protected override object GenerateItem() { return new KeyValuePair(m_next_item.ToString(), m_next_item++); @@ -429,6 +430,7 @@ public ReadOnlyDictionaryTestsStringInt() protected override bool IsGenericCompatibility { get { return false; } } protected override bool ItemsMustBeUnique { get { return true; } } protected override bool ItemsMustBeNonNull { get { return true; } } + protected override bool CurrentAfterFullEnumerationThrows { get { return false; } } protected override object GenerateItem() { return new KeyValuePair(m_next_item.ToString(), m_next_item++); diff --git a/src/libraries/System.ObjectModel/tests/System/Collections/Specialized/NotifyCollectionChangedEventArgsTests.cs b/src/libraries/System.ObjectModel/tests/System/Collections/Specialized/NotifyCollectionChangedEventArgsTests.cs index c0afe20a448254..235697eed47a64 100644 --- a/src/libraries/System.ObjectModel/tests/System/Collections/Specialized/NotifyCollectionChangedEventArgsTests.cs +++ b/src/libraries/System.ObjectModel/tests/System/Collections/Specialized/NotifyCollectionChangedEventArgsTests.cs @@ -189,7 +189,7 @@ public void Ctor_InvalidActionForChanged_ThrowsArgumentException(NotifyCollectio [InlineData(NotifyCollectionChangedAction.Replace, "oldItem", "oldItem")] [InlineData(NotifyCollectionChangedAction.Replace, null, "item")] [InlineData(NotifyCollectionChangedAction.Replace, "item", null)] - public void Ctor_NotifyCollectionChangedAction_Object_Object(NotifyCollectionChangedAction action, object newItem, object oldItem) + public void Ctor_NotifyCollectionChangedAction_Object_Object(NotifyCollectionChangedAction action, object? newItem, object? oldItem) { var e = new NotifyCollectionChangedEventArgs(action, newItem, oldItem); Assert.Equal(action, e.Action); @@ -204,7 +204,7 @@ public void Ctor_NotifyCollectionChangedAction_Object_Object(NotifyCollectionCha [InlineData(NotifyCollectionChangedAction.Replace, "oldItem", "oldItem", 0)] [InlineData(NotifyCollectionChangedAction.Replace, null, "item", -10)] [InlineData(NotifyCollectionChangedAction.Replace, "item", null, -1)] - public void Ctor_NotifyCollectionChangedAction_Object_Object_Int(NotifyCollectionChangedAction action, object newItem, object oldItem, int index) + public void Ctor_NotifyCollectionChangedAction_Object_Object_Int(NotifyCollectionChangedAction action, object? newItem, object? oldItem, int index) { var e = new NotifyCollectionChangedEventArgs(action, newItem, oldItem, index); Assert.Equal(action, e.Action); @@ -291,7 +291,7 @@ public void Ctor_NullOldItemsForReplace_ThrowsArgumentNullException() [InlineData(NotifyCollectionChangedAction.Move, "item", 1, 1)] [InlineData(NotifyCollectionChangedAction.Move, "item", 1, -2)] [InlineData(NotifyCollectionChangedAction.Move, null, 1, 2)] - public void Ctor_NotifyCollectionChangedAction_Object_Int_Int(NotifyCollectionChangedAction action, object changedItem, int index, int oldIndex) + public void Ctor_NotifyCollectionChangedAction_Object_Int_Int(NotifyCollectionChangedAction action, object? changedItem, int index, int oldIndex) { var e = new NotifyCollectionChangedEventArgs(action, changedItem, index, oldIndex); Assert.Equal(action, e.Action); @@ -306,7 +306,7 @@ public void Ctor_NotifyCollectionChangedAction_Object_Int_Int(NotifyCollectionCh [InlineData(NotifyCollectionChangedAction.Move, new object[] { "item" }, 1, 1)] [InlineData(NotifyCollectionChangedAction.Move, new object[0], 1, -2)] [InlineData(NotifyCollectionChangedAction.Move, null, 1, 2)] - public void Ctor_NotifyCollectionChangedAction_IList_Int_Int(NotifyCollectionChangedAction action, IList changedItems, int index, int oldIndex) + public void Ctor_NotifyCollectionChangedAction_IList_Int_Int(NotifyCollectionChangedAction action, IList? changedItems, int index, int oldIndex) { var e = new NotifyCollectionChangedEventArgs(action, changedItems, index, oldIndex); Assert.Equal(action, e.Action); @@ -386,7 +386,7 @@ public void List_Clear_ThrowsNotSupportedException() [InlineData("item", true)] [InlineData(1, false)] [InlineData(null, false)] - public void List_Contains_ReturnsExpected(object value, bool expected) + public void List_Contains_ReturnsExpected(object? value, bool expected) { var e = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, new object[] { "item" }, new object[0]); IList list = e.NewItems; @@ -407,7 +407,7 @@ public void List_CopyToInvoke_Success() [InlineData("item", 0)] [InlineData(1, -1)] [InlineData(null, -1)] - public void List_IndexOf_ReturnsExpected(object value, int expected) + public void List_IndexOf_ReturnsExpected(object? value, int expected) { var e = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, new object[] { "item" }, new object[0]); IList list = e.NewItems; diff --git a/src/libraries/System.ObjectModel/tests/System/ComponentModel/DataErrorsChangedEventArgsTests.cs b/src/libraries/System.ObjectModel/tests/System/ComponentModel/DataErrorsChangedEventArgsTests.cs index b87dd83c8da04c..0a7ce6dfe6e4dc 100644 --- a/src/libraries/System.ObjectModel/tests/System/ComponentModel/DataErrorsChangedEventArgsTests.cs +++ b/src/libraries/System.ObjectModel/tests/System/ComponentModel/DataErrorsChangedEventArgsTests.cs @@ -11,7 +11,7 @@ public class DataErrorsChangedEventArgsTests [InlineData(null)] [InlineData("")] [InlineData("propertyName")] - public void Ctor_String(string propertyName) + public void Ctor_String(string? propertyName) { var e = new DataErrorsChangedEventArgs(propertyName); Assert.Equal(propertyName, e.PropertyName); diff --git a/src/libraries/System.ObjectModel/tests/System/ComponentModel/PropertyChangedEventArgsTests.cs b/src/libraries/System.ObjectModel/tests/System/ComponentModel/PropertyChangedEventArgsTests.cs index 697665bcd14b21..fcb48e38ca3c12 100644 --- a/src/libraries/System.ObjectModel/tests/System/ComponentModel/PropertyChangedEventArgsTests.cs +++ b/src/libraries/System.ObjectModel/tests/System/ComponentModel/PropertyChangedEventArgsTests.cs @@ -11,7 +11,7 @@ public class PropertyChangedEventArgsTests [InlineData(null)] [InlineData("")] [InlineData("propertyName")] - public void Ctor_String(string propertyName) + public void Ctor_String(string? propertyName) { var e = new PropertyChangedEventArgs(propertyName); Assert.Equal(propertyName, e.PropertyName); diff --git a/src/libraries/System.ObjectModel/tests/System/ComponentModel/PropertyChangingEventArgsTests.cs b/src/libraries/System.ObjectModel/tests/System/ComponentModel/PropertyChangingEventArgsTests.cs index 4e18bd5282a3b5..9921e4bb6aafc0 100644 --- a/src/libraries/System.ObjectModel/tests/System/ComponentModel/PropertyChangingEventArgsTests.cs +++ b/src/libraries/System.ObjectModel/tests/System/ComponentModel/PropertyChangingEventArgsTests.cs @@ -11,7 +11,7 @@ public class PropertyChangingEventArgsTests [InlineData(null)] [InlineData("")] [InlineData("propertyName")] - public void Ctor_String(string propertyName) + public void Ctor_String(string? propertyName) { var e = new PropertyChangingEventArgs(propertyName); Assert.Equal(propertyName, e.PropertyName); diff --git a/src/libraries/System.ObjectModel/tests/System/Windows/Markup/ValueSerializerAttributeTests.cs b/src/libraries/System.ObjectModel/tests/System/Windows/Markup/ValueSerializerAttributeTests.cs index 23b513e798a303..8c4f5838a01985 100644 --- a/src/libraries/System.ObjectModel/tests/System/Windows/Markup/ValueSerializerAttributeTests.cs +++ b/src/libraries/System.ObjectModel/tests/System/Windows/Markup/ValueSerializerAttributeTests.cs @@ -13,7 +13,7 @@ public class ValueSerializerAttributeTests [InlineData("propertyName", null)] [InlineData("System.Int32", typeof(int))] [InlineData("System.int32", null)] - public void Ctor_String(string valueSerializerTypeName, Type expectedValueSerializerType) + public void Ctor_String(string? valueSerializerTypeName, Type? expectedValueSerializerType) { var attribute = new ValueSerializerAttribute(valueSerializerTypeName); Assert.Equal(valueSerializerTypeName, attribute.ValueSerializerTypeName); @@ -23,7 +23,7 @@ public void Ctor_String(string valueSerializerTypeName, Type expectedValueSerial [Theory] [InlineData(null)] [InlineData(typeof(int))] - public void Ctor_Type(Type valueSerializerType) + public void Ctor_Type(Type? valueSerializerType) { var attribute = new ValueSerializerAttribute(valueSerializerType); Assert.Equal(valueSerializerType?.AssemblyQualifiedName, attribute.ValueSerializerTypeName); diff --git a/src/libraries/System.Private.CoreLib/gen/NativeRuntimeEventSourceGenerator.cs b/src/libraries/System.Private.CoreLib/gen/NativeRuntimeEventSourceGenerator.cs index 5d8c66a600857e..1303e061a54348 100644 --- a/src/libraries/System.Private.CoreLib/gen/NativeRuntimeEventSourceGenerator.cs +++ b/src/libraries/System.Private.CoreLib/gen/NativeRuntimeEventSourceGenerator.cs @@ -415,10 +415,13 @@ private static bool IsEventManuallyHandled(string eventName) private static readonly List manuallyHandledEventSymbols = [ - // Some threading events are defined manually in NativeRuntimeEventSource.Threading.cs + // Some threading events are defined manually in NativeRuntimeEventSource.Threading.[NativeSinks].cs "ThreadPool", "Contention", - "WaitHandle" + "WaitHandle", + + // Exception event defined manually in NativeRuntimeEventSource.Exceptions.NativeSinks.cs + "ExceptionThrown_V1", ]; } } diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml index ca7f802dc2add2..c13bff30f490c4 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml @@ -1,4 +1,16 @@ + + + + + + + + + + + + diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.LibraryBuild.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.LibraryBuild.xml index c0523c4d646dc0..39fc710bc49aa0 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.LibraryBuild.xml +++ b/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/libraries/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComponentActivator.cs b/src/libraries/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComponentActivator.cs index 33d08bf108174c..df4306da1b7ec8 100644 --- a/src/libraries/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComponentActivator.cs +++ b/src/libraries/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComponentActivator.cs @@ -348,7 +348,7 @@ private static IntPtr InternalGetFunctionPointer(AssemblyLoadContext alc, } else { - Delegate d = Delegate.CreateDelegate(delegateType, type, methodName)!; + Delegate d = Delegate.CreateDelegate(delegateType, type, methodName); functionPtr = Marshal.GetFunctionPointerForDelegate(d); diff --git a/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs b/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs index 476af77370bd66..536cf55d279fb5 100644 --- a/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs @@ -123,10 +123,6 @@ private static SafeFileHandle Open(string path, Interop.Sys.OpenFlags flags, int return handle; } - // Each thread will have its own copy. This prevents race conditions if the handle had the last error. - [ThreadStatic] - internal static Interop.ErrorInfo? t_lastCloseErrorInfo; - protected override bool ReleaseHandle() { // If DeleteOnClose was requested when constructed, delete the file now. @@ -152,15 +148,8 @@ protected override bool ReleaseHandle() _isLocked = false; } - // Close the descriptor. Although close is documented to potentially fail with EINTR, we never want - // to retry, as the descriptor could actually have been closed, been subsequently reassigned, and - // be in use elsewhere in the process. Instead, we simply check whether the call was successful. - int result = Interop.Sys.Close(handle); - if (result != 0) - { - t_lastCloseErrorInfo = Interop.Sys.GetLastErrorInfo(); - } - return result == 0; + // Close the descriptor. + return Interop.Sys.Close(handle) == 0; } public override bool IsInvalid @@ -450,7 +439,7 @@ private bool Init(string path, FileMode mode, FileAccess access, FileShare share // Delete the file we've created. Debug.Assert(mode == FileMode.Create || mode == FileMode.CreateNew); - Interop.Sys.Unlink(path!); + Interop.Sys.Unlink(path); throw new IOException(SR.Format(errorInfo.Error == Interop.Error.EFBIG ? SR.IO_FileTooLarge_Path_AllocationSize diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index 4b45d710bc3fd6..289b1df2b90512 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -633,8 +633,8 @@ Named parameter array cannot be bigger than argument array. - - No PInvoke conversion exists for value passed to Object-typed parameter. + + No PInvoke conversion exists for the value passed to an Object-typed parameter. Array was not a one-dimensional array. @@ -2987,6 +2987,9 @@ ByRef to void return values are not supported in reflection invocation. + + Async infrastructure methods are not supported in reflection invocation. + Vararg calling convention not supported. @@ -3011,6 +3014,9 @@ CreateInstance cannot be used with an object of type TypeBuilder. + + TypeBuilder generic instantiation does not support resolving members. Use TypeBuilder.{0} instead. + Only one DBNull instance may exist, and calls to DBNull deserialization methods are not allowed. @@ -3410,6 +3416,9 @@ The timeout must represent a value between -1 and Int32.MaxValue, inclusive. + + The value needs to translate in milliseconds to -1 (signifying an infinite timeout), or be non-negative. + Non existent ParameterInfo. Position bigger than member's parameters length. @@ -4202,6 +4211,9 @@ InlineArrayAttribute cannot be applied to a type with explicit layout. Type: '{0}'. Assembly: '{1}'. + + InlineArrayAttribute cannot be applied to a type with explicit size. Type: '{0}'. Assembly: '{1}'. + Could not load type '{0}' from assembly '{1}' because generic types cannot have explicit layout. diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 150b1d6a8e11cd..f7bf03c2c81ac3 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -471,6 +471,7 @@ + @@ -834,6 +835,7 @@ + @@ -851,6 +853,7 @@ + @@ -996,7 +999,7 @@ - + @@ -1582,6 +1585,8 @@ + + @@ -2156,6 +2161,9 @@ Common\Interop\Windows\Ole32\Interop.PropVariantClear.cs + + Common\Interop\Windows\OleAut32\Interop.GetErrorInfo.cs + Common\Interop\Windows\Secur32\Interop.GetUserNameExW.cs @@ -2458,10 +2466,8 @@ Common\Interop\Unix\System.Native\Interop.MountPoints.cs - - + + Common\Interop\Unix\System.Native\Interop.Open.cs @@ -2807,6 +2813,15 @@ + + + + + + + + + @@ -2875,4 +2890,4 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Private.CoreLib/src/System/Activator.RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/Activator.RuntimeType.cs index b0837a535f00b7..b0bbaacca31acd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Activator.RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Activator.RuntimeType.cs @@ -145,7 +145,7 @@ public static partial class Activator // Casting the above object to T is technically invalid because // T can be ByRefLike (that is, ref struct). Roslyn blocks the - // cast this in function with a "CS0030: Cannot convert type 'object' to 'T'", + // cast in this function with a "CS0030: Cannot convert type 'object' to 'T'", // which is correct. However, since we are doing the IsValueType // check above, we know this code path will only be taken with // reference types and therefore the below Unsafe.As<> is safe. diff --git a/src/libraries/System.Private.CoreLib/src/System/AppContext.cs b/src/libraries/System.Private.CoreLib/src/System/AppContext.cs index ade462726d58e8..c48d93688fbd3f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/AppContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/AppContext.cs @@ -82,25 +82,50 @@ public static void SetData(string name, object? data) internal static event EventHandler? FirstChanceException; #pragma warning restore CS0067 + private static ulong s_crashingThreadId; + #if NATIVEAOT [System.Runtime.RuntimeExport("OnUnhandledException")] #endif internal static void OnUnhandledException(object e) { - if (UnhandledException is UnhandledExceptionEventHandler handlers) + ulong currentThreadId = Thread.CurrentOSThreadId; + ulong previousCrashingThreadId = Interlocked.CompareExchange(ref s_crashingThreadId, currentThreadId, 0); + if (previousCrashingThreadId == 0) { - UnhandledExceptionEventArgs args = new(e, isTerminating: true); - foreach (UnhandledExceptionEventHandler handler in Delegate.EnumerateInvocationList(handlers)) +#if NATIVEAOT + RuntimeExceptionHelpers.SerializeCrashInfo(System.Runtime.RhFailFastReason.UnhandledException, (e as Exception)?.Message, e as Exception); +#endif + if (UnhandledException is UnhandledExceptionEventHandler handlers) { - try - { - handler(/* AppDomain */ null!, args); - } - catch + UnhandledExceptionEventArgs args = new(e, isTerminating: true); + foreach (UnhandledExceptionEventHandler handler in Delegate.EnumerateInvocationList(handlers)) { + try + { + handler(/* AppDomain */ null!, args); + } + catch + { + } } } } + else + { + if (s_crashingThreadId == previousCrashingThreadId) + { + Environment.FailFast("OnUnhandledException called recursively"); + } + + // If we are already in the process of handling an unhandled + // exception, we do not want to raise the event again. We wait + // here while the other thread raises the unhandled exception. + // Waiting is important because it is possible upon returning, this thread + // could call some rude abort method that would terminate the process + // before the other thread finishes raising the unhandled exception. + Thread.Sleep(-1); + } } internal static void OnProcessExit() diff --git a/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs b/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs index d6666fb704aabf..6c874d8037b558 100644 --- a/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs @@ -623,7 +623,7 @@ public static uint ToUInt32(ReadOnlySpan value) } /// - /// Returns a 64-bit unsigned integer converted from four bytes at a specified position in a byte array. + /// Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a byte array. /// /// An array of bytes. /// The starting position within . @@ -653,7 +653,7 @@ public static ulong ToUInt64(ReadOnlySpan value) } /// - /// Returns a 128-bit unsigned integer converted from four bytes at a specified position in a byte array. + /// Returns a 128-bit unsigned integer converted from sixteen bytes at a specified position in a byte array. /// /// An array of bytes. /// The starting position within . @@ -746,7 +746,7 @@ public static float ToSingle(ReadOnlySpan value) } /// - /// Returns a double-precision floating point number converted from four bytes at a specified position in a byte array. + /// Returns a double-precision floating point number converted from eight bytes at a specified position in a byte array. /// /// An array of bytes. /// The starting position within . diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs index 9c336d924c75d8..eb4c3828cd930e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs @@ -487,7 +487,7 @@ private static unsafe int PickPivotAndPartition(Span keys) while (Unsafe.IsAddressGreaterThan(ref rightRef, ref zeroRef) && LessThan(ref pivot, ref rightRef = ref Unsafe.Add(ref rightRef, -1))) ; } - if (!Unsafe.IsAddressLessThan(ref leftRef, ref rightRef)) + if (Unsafe.IsAddressGreaterThanOrEqualTo(ref leftRef, ref rightRef)) { break; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs index c890bbed83c7ef..c103bd8fe4304c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs +++ b/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/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs index 026456617f8997..421d60b036639b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs @@ -499,7 +499,7 @@ public bool Add(TAlternate item) { index = set._freeList; set._freeCount--; - Debug.Assert((StartOfFreeList - entries![set._freeList].Next) >= -1, "shouldn't overflow because `next` cannot underflow"); + Debug.Assert((StartOfFreeList - entries[set._freeList].Next) >= -1, "shouldn't overflow because `next` cannot underflow"); set._freeList = StartOfFreeList - entries[set._freeList].Next; } else @@ -551,7 +551,7 @@ public bool Remove(TAlternate item) uint collisionCount = 0; int last = -1; - int hashCode = item is not null ? comparer!.GetHashCode(item) : 0; + int hashCode = item is not null ? comparer.GetHashCode(item) : 0; ref int bucket = ref set.GetBucketRef(hashCode); int i = bucket - 1; // Value in buckets is 1-based @@ -1481,7 +1481,7 @@ private bool AddIfNotPresent(T value, out int location) { index = _freeList; _freeCount--; - Debug.Assert((StartOfFreeList - entries![_freeList].Next) >= -1, "shouldn't overflow because `next` cannot underflow"); + Debug.Assert((StartOfFreeList - entries[_freeList].Next) >= -1, "shouldn't overflow because `next` cannot underflow"); _freeList = StartOfFreeList - entries[_freeList].Next; } else diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs index 1df1ea89696c5f..f012603ef9d755 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs @@ -80,7 +80,7 @@ public List(IEnumerable collection) else { _items = s_emptyArray; - using (IEnumerator en = collection!.GetEnumerator()) + using (IEnumerator en = collection.GetEnumerator()) { while (en.MoveNext()) { @@ -1185,16 +1185,15 @@ public bool TrueForAll(Predicate match) public struct Enumerator : IEnumerator, IEnumerator { private readonly List _list; - private int _index; private readonly int _version; + + private int _index; private T? _current; internal Enumerator(List list) { _list = list; - _index = 0; _version = list._version; - _current = default; } public void Dispose() @@ -1205,24 +1204,20 @@ public bool MoveNext() { List localList = _list; - if (_version == localList._version && ((uint)_index < (uint)localList._size)) + if (_version != _list._version) { - _current = localList._items[_index]; - _index++; - return true; + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); } - return MoveNextRare(); - } - private bool MoveNextRare() - { - if (_version != _list._version) + if ((uint)_index < (uint)localList._size) { - ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); + _current = localList._items[_index]; + _index++; + return true; } - _index = _list._size + 1; _current = default; + _index = -1; return false; } @@ -1232,11 +1227,12 @@ private bool MoveNextRare() { get { - if (_index == 0 || _index == _list._size + 1) + if (_index <= 0) { ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen(); } - return Current; + + return _current; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs index 9bc99f7ef4c826..ff903b17f07d20 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs +++ b/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/libraries/System.Private.CoreLib/src/System/Collections/Generic/Queue.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Queue.cs index 516249765515ef..a3f33ef765678d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Queue.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Queue.cs @@ -421,90 +421,76 @@ private void Grow(int capacity) public struct Enumerator : IEnumerator, IEnumerator { - private readonly Queue _q; + private readonly Queue _queue; private readonly int _version; - private int _index; // -1 = not started, -2 = ended/disposed + private int _i; private T? _currentElement; - internal Enumerator(Queue q) + internal Enumerator(Queue queue) { - _q = q; - _version = q._version; - _index = -1; + _queue = queue; + _version = queue._version; + _i = -1; _currentElement = default; } public void Dispose() { - _index = -2; + _i = -2; _currentElement = default; } public bool MoveNext() { - if (_version != _q._version) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); - - if (_index == -2) - return false; - - _index++; - - if (_index == _q._size) + if (_version != _queue._version) { - // We've run past the last element - _index = -2; - _currentElement = default; - return false; + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); } - // Cache some fields in locals to decrease code size - T[] array = _q._array; - uint capacity = (uint)array.Length; + Queue q = _queue; + int size = q._size; - // _index represents the 0-based index into the queue, however the queue - // doesn't have to start from 0 and it may not even be stored contiguously in memory. - - uint arrayIndex = (uint)(_q._head + _index); // this is the actual index into the queue's backing array - if (arrayIndex >= capacity) + int offset = _i + 1; + if ((uint)offset < (uint)size) { - // NOTE: Originally we were using the modulo operator here, however - // on Intel processors it has a very high instruction latency which - // was slowing down the loop quite a bit. - // Replacing it with simple comparison/subtraction operations sped up - // the average foreach loop by 2x. - - arrayIndex -= capacity; // wrap around if needed - } + _i = offset; - _currentElement = array[arrayIndex]; - return true; - } + T[] array = q._array; + int index = q._head + offset; + if ((uint)index < (uint)array.Length) + { + _currentElement = array[index]; + } + else + { + // The index has wrapped around the end of the array. Shift the index and then + // get the current element. It is tempting to dedup this dereferencing with that + // in the if block above, but the if block above avoids a bounds check for the + // accesses that are in that portion, whereas these still incur it. + index -= array.Length; + _currentElement = array[index]; + } - public T Current - { - get - { - if (_index < 0) - ThrowEnumerationNotStartedOrEnded(); - return _currentElement!; + return true; } - } - private void ThrowEnumerationNotStartedOrEnded() - { - Debug.Assert(_index == -1 || _index == -2); - throw new InvalidOperationException(_index == -1 ? SR.InvalidOperation_EnumNotStarted : SR.InvalidOperation_EnumEnded); + _i = -2; + _currentElement = default; + return false; } - object? IEnumerator.Current - { - get { return Current; } - } + public T Current => _currentElement!; + + object? IEnumerator.Current => Current; void IEnumerator.Reset() { - if (_version != _q._version) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); - _index = -1; + if (_version != _queue._version) + { + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); + } + + _i = -1; _currentElement = default; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs index d6d79bb96b9e7b..e613eb8614dcac 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs +++ b/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/libraries/System.Private.CoreLib/src/System/Collections/ObjectModel/CollectionHelpers.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/ObjectModel/CollectionHelpers.cs index d3b9f1f19f5275..9495033ac3b3f1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/ObjectModel/CollectionHelpers.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/ObjectModel/CollectionHelpers.cs @@ -9,7 +9,7 @@ internal static class CollectionHelpers { internal static void ValidateCopyToArguments(int sourceCount, Array array, int index) { -#if NET8_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(array); #else ArgumentNullException.ThrowIfNull(array); @@ -25,7 +25,7 @@ internal static void ValidateCopyToArguments(int sourceCount, Array array, int i throw new ArgumentException(SR.Arg_NonZeroLowerBound, nameof(array)); } -#if NET8_0_OR_GREATER +#if NET ArgumentOutOfRangeException.ThrowIfNegative(index); ArgumentOutOfRangeException.ThrowIfGreaterThan(index, array.Length); #else diff --git a/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs index d10102a150732c..12a04b63a5cb06 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs +++ b/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/libraries/System.Private.CoreLib/src/System/Convert.cs b/src/libraries/System.Private.CoreLib/src/System/Convert.cs index d2bafdc1cfeef8..f177c7746cbbab 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Convert.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Convert.cs @@ -2915,9 +2915,7 @@ private static unsafe int FromBase64_ComputeResultLength(char* inputPtr, int inp return (usefulInputLength / 4) * 3 + padding; } - /// - /// Converts the specified string, which encodes binary data as hex characters, to an equivalent 8-bit unsigned integer array. - /// + /// Converts the specified string, which encodes binary data as hex characters, to an equivalent 8-bit unsigned integer array. /// The string to convert. /// An array of 8-bit unsigned integers that is equivalent to . /// is null. @@ -2925,17 +2923,14 @@ private static unsafe int FromBase64_ComputeResultLength(char* inputPtr, int inp /// The format of is invalid. contains a non-hex character. public static byte[] FromHexString(string s) { - if (s == null) + if (s is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.s); } - return FromHexString(s.AsSpan()); } - /// - /// Converts the span, which encodes binary data as hex characters, to an equivalent 8-bit unsigned integer array. - /// + /// Converts the span, which encodes binary data as hex characters, to an equivalent 8-bit unsigned integer array. /// The span to convert. /// An array of 8-bit unsigned integers that is equivalent to . /// The length of , is not zero or a multiple of 2. @@ -2943,21 +2938,51 @@ public static byte[] FromHexString(string s) public static byte[] FromHexString(ReadOnlySpan chars) { if (chars.Length == 0) - return Array.Empty(); - if ((uint)chars.Length % 2 != 0) - throw new FormatException(SR.Format_BadHexLength); + { + return []; + } + + if (!int.IsEvenInteger(chars.Length)) + { + ThrowHelper.ThrowFormatException_BadHexLength(); + } - byte[] result = GC.AllocateUninitializedArray(chars.Length >> 1); + byte[] result = GC.AllocateUninitializedArray(chars.Length / 2); if (!HexConverter.TryDecodeFromUtf16(chars, result, out _)) - throw new FormatException(SR.Format_BadHexChar); + { + ThrowHelper.ThrowFormatException_BadHexChar(); + } + return result; + } + /// Converts the span, which encodes binary data as hex characters, to an equivalent 8-bit unsigned integer array. + /// The UTF-8 span to convert. + /// An array of 8-bit unsigned integers that is equivalent to . + /// The length of , is not zero or a multiple of 2. + /// The format of is invalid. contains a non-hex character. + public static byte[] FromHexString(ReadOnlySpan utf8Source) + { + if (utf8Source.Length == 0) + { + return []; + } + + if (!int.IsEvenInteger(utf8Source.Length)) + { + ThrowHelper.ThrowFormatException_BadHexLength(); + } + + byte[] result = GC.AllocateUninitializedArray(utf8Source.Length / 2); + + if (!HexConverter.TryDecodeFromUtf8(utf8Source, result, out _)) + { + ThrowHelper.ThrowFormatException_BadHexChar(); + } return result; } - /// - /// Converts the string, which encodes binary data as hex characters, to an equivalent 8-bit unsigned integer span. - /// + /// Converts the string, which encodes binary data as hex characters, to an equivalent 8-bit unsigned integer span. /// The string to convert. /// /// The span in which to write the converted 8-bit unsigned integers. When this method returns value different than , @@ -2971,13 +2996,10 @@ public static byte[] FromHexString(ReadOnlySpan chars) public static OperationStatus FromHexString(string source, Span destination, out int charsConsumed, out int bytesWritten) { ArgumentNullException.ThrowIfNull(source); - return FromHexString(source.AsSpan(), destination, out charsConsumed, out bytesWritten); } - /// - /// Converts the span of chars, which encodes binary data as hex characters, to an equivalent 8-bit unsigned integer span. - /// + /// Converts the span of chars, which encodes binary data as hex characters, to an equivalent 8-bit unsigned integer span. /// The span to convert. /// /// The span in which to write the converted 8-bit unsigned integers. When this method returns value different than , @@ -2996,7 +3018,7 @@ public static OperationStatus FromHexString(ReadOnlySpan source, Span source, Span - /// Converts an array of 8-bit unsigned integers to its equivalent string representation that is encoded with uppercase hex characters. - /// + /// Converts the span of UTF-8 chars, which encodes binary data as hex characters, to an equivalent 8-bit unsigned integer span. + /// The span to convert. + /// + /// The span in which to write the converted 8-bit unsigned integers. When this method returns value different than , + /// either the span remains unmodified or contains an incomplete conversion of , + /// up to the last valid character. + /// + /// When this method returns, contains the number of bytes that were written to . + /// When this method returns, contains the number of bytes that were consumed from . + /// An describing the result of the operation. + public static OperationStatus FromHexString(ReadOnlySpan utf8Source, Span destination, out int bytesConsumed, out int bytesWritten) + { + (int quotient, int remainder) = Math.DivRem(utf8Source.Length, 2); + + if (quotient == 0) + { + bytesConsumed = 0; + bytesWritten = 0; + + return (remainder == 1) ? OperationStatus.NeedMoreData : OperationStatus.Done; + } + + OperationStatus result; + + if (destination.Length < quotient) + { + utf8Source = utf8Source.Slice(0, destination.Length * 2); + quotient = destination.Length; + result = OperationStatus.DestinationTooSmall; + } + else + { + if (remainder == 1) + { + utf8Source = utf8Source.Slice(0, utf8Source.Length - 1); + result = OperationStatus.NeedMoreData; + } + else + { + result = OperationStatus.Done; + } + + destination = destination.Slice(0, quotient); + } + + if (!HexConverter.TryDecodeFromUtf8(utf8Source, destination, out bytesConsumed)) + { + bytesWritten = bytesConsumed / 2; + return OperationStatus.InvalidData; + } + + bytesWritten = quotient; + bytesConsumed = utf8Source.Length; + return result; + } + + /// Converts an array of 8-bit unsigned integers to its equivalent string representation that is encoded with uppercase hex characters. /// An array of 8-bit unsigned integers. /// The string representation in hex of the elements in . /// is null. @@ -3043,7 +3119,6 @@ public static OperationStatus FromHexString(ReadOnlySpan source, Span(inArray)); } @@ -3070,24 +3145,22 @@ public static string ToHexString(byte[] inArray, int offset, int length) return ToHexString(new ReadOnlySpan(inArray, offset, length)); } - /// - /// Converts a span of 8-bit unsigned integers to its equivalent string representation that is encoded with uppercase hex characters. - /// + /// Converts a span of 8-bit unsigned integers to its equivalent string representation that is encoded with uppercase hex characters. /// A span of 8-bit unsigned integers. /// The string representation in hex of the elements in . /// is too large to be encoded. public static string ToHexString(ReadOnlySpan bytes) { if (bytes.Length == 0) + { return string.Empty; + } ArgumentOutOfRangeException.ThrowIfGreaterThan(bytes.Length, int.MaxValue / 2, nameof(bytes)); return HexConverter.ToString(bytes, HexConverter.Casing.Upper); } - /// - /// Converts a span of 8-bit unsigned integers to its equivalent span representation that is encoded with uppercase hex characters. - /// + /// Converts a span of 8-bit unsigned integers to its equivalent span representation that is encoded with uppercase hex characters. /// A span of 8-bit unsigned integers. /// The span representation in hex of the elements in . /// When this method returns, contains the number of chars that were written in . @@ -3099,7 +3172,7 @@ public static bool TryToHexString(ReadOnlySpan source, Span destinat charsWritten = 0; return true; } - else if (source.Length > int.MaxValue / 2 || destination.Length < source.Length * 2) + else if ((source.Length > (int.MaxValue / 2)) || (destination.Length < (source.Length * 2))) { charsWritten = 0; return false; @@ -3110,9 +3183,30 @@ public static bool TryToHexString(ReadOnlySpan source, Span destinat return true; } - /// - /// Converts an array of 8-bit unsigned integers to its equivalent string representation that is encoded with lowercase hex characters. - /// + /// Converts a span of 8-bit unsigned integers to its equivalent UTF-8 span representation that is encoded with uppercase hex characters. + /// A span of 8-bit unsigned integers. + /// The UTF-8 span representation in hex of the elements in . + /// When this method returns, contains the number of bytes that were written in . + /// true if the conversion was successful; otherwise, false. + public static bool TryToHexString(ReadOnlySpan source, Span utf8Destination, out int bytesWritten) + { + if (source.Length == 0) + { + bytesWritten = 0; + return true; + } + else if ((source.Length > (int.MaxValue / 2)) || (utf8Destination.Length < (source.Length * 2))) + { + bytesWritten = 0; + return false; + } + + HexConverter.EncodeToUtf8(source, utf8Destination); + bytesWritten = source.Length * 2; + return true; + } + + /// Converts an array of 8-bit unsigned integers to its equivalent string representation that is encoded with lowercase hex characters. /// An array of 8-bit unsigned integers. /// The string representation in hex of the elements in . /// is null. @@ -3120,7 +3214,6 @@ public static bool TryToHexString(ReadOnlySpan source, Span destinat public static string ToHexStringLower(byte[] inArray) { ArgumentNullException.ThrowIfNull(inArray); - return ToHexStringLower(new ReadOnlySpan(inArray)); } @@ -3147,24 +3240,22 @@ public static string ToHexStringLower(byte[] inArray, int offset, int length) return ToHexStringLower(new ReadOnlySpan(inArray, offset, length)); } - /// - /// Converts a span of 8-bit unsigned integers to its equivalent string representation that is encoded with lowercase hex characters. - /// + /// Converts a span of 8-bit unsigned integers to its equivalent string representation that is encoded with lowercase hex characters. /// A span of 8-bit unsigned integers. /// The string representation in hex of the elements in . /// is too large to be encoded. public static string ToHexStringLower(ReadOnlySpan bytes) { if (bytes.Length == 0) + { return string.Empty; + } ArgumentOutOfRangeException.ThrowIfGreaterThan(bytes.Length, int.MaxValue / 2, nameof(bytes)); return HexConverter.ToString(bytes, HexConverter.Casing.Lower); } - /// - /// Converts a span of 8-bit unsigned integers to its equivalent span representation that is encoded with lowercase hex characters. - /// + /// Converts a span of 8-bit unsigned integers to its equivalent span representation that is encoded with lowercase hex characters. /// A span of 8-bit unsigned integers. /// The span representation in hex of the elements in . /// When this method returns, contains the number of chars that were written in . @@ -3176,7 +3267,7 @@ public static bool TryToHexStringLower(ReadOnlySpan source, Span des charsWritten = 0; return true; } - else if (source.Length > int.MaxValue / 2 || destination.Length < source.Length * 2) + else if ((source.Length > (int.MaxValue / 2)) || (destination.Length < (source.Length * 2))) { charsWritten = 0; return false; @@ -3186,5 +3277,28 @@ public static bool TryToHexStringLower(ReadOnlySpan source, Span des charsWritten = source.Length * 2; return true; } - } // class Convert -} // namespace + + /// Converts a span of 8-bit unsigned integers to its equivalent UTF-8 span representation that is encoded with lowercase hex characters. + /// A span of 8-bit unsigned integers. + /// The UTF-8 span representation in hex of the elements in . + /// When this method returns, contains the number of bytes that were written in . + /// true if the conversion was successful; otherwise, false. + public static bool TryToHexStringLower(ReadOnlySpan source, Span utf8Destination, out int bytesWritten) + { + if (source.Length == 0) + { + bytesWritten = 0; + return true; + } + else if ((source.Length > (int.MaxValue / 2)) || (utf8Destination.Length < (source.Length * 2))) + { + bytesWritten = 0; + return false; + } + + HexConverter.EncodeToUtf8(source, utf8Destination, HexConverter.Casing.Lower); + bytesWritten = source.Length * 2; + return true; + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs index 5cabd72975ee86..c114427965f53c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs +++ b/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/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMembersAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMembersAttribute.cs index 45166d5259b5ff..4d3734b3241c0a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMembersAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMembersAttribute.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.Runtime.CompilerServices; + namespace System.Diagnostics.CodeAnalysis { /// @@ -25,6 +27,7 @@ namespace System.Diagnostics.CodeAnalysis /// should only be used on instance methods of types assignable to System.Type (or string, but no methods /// will use it there). /// + [CompilerLoweringPreserve] [AttributeUsage( AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method | diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresDynamicCodeAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresDynamicCodeAttribute.cs index f6037d8660ba04..fa36f95c0527c6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresDynamicCodeAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresDynamicCodeAttribute.cs @@ -30,6 +30,11 @@ public RequiresDynamicCodeAttribute(string message) Message = message; } + /// + /// When set to true, indicates that the annotation should not apply to static members. + /// + public bool ExcludeStatics { get; set; } + /// /// Gets a message that contains information about the usage of dynamic code. /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttribute.cs index d063603281fd73..327425ca3362f7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttribute.cs @@ -31,6 +31,11 @@ public RequiresUnreferencedCodeAttribute(string message) Message = message; } + /// + /// When set to true, indicates that the annotation should not apply to static members. + /// + public bool ExcludeStatics { get; set; } + /// /// Gets a message that contains information about the usage of unreferenced code. /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs index 0efad03362a47e..5cb9b11658ee1c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs @@ -68,7 +68,7 @@ public void OnStart(string providerName, string activityName, int task, ref Guid if (tplDebug) { log!.DebugFacilityMessage("OnStartEnter", fullActivityName); - log!.DebugFacilityMessage("OnStartEnterActivityState", ActivityInfo.LiveActivities(currentActivity)); + log.DebugFacilityMessage("OnStartEnterActivityState", ActivityInfo.LiveActivities(currentActivity)); } if (currentActivity != null) @@ -114,7 +114,7 @@ public void OnStart(string providerName, string activityName, int task, ref Guid if (tplDebug) { log!.DebugFacilityMessage("OnStartRetActivityState", ActivityInfo.LiveActivities(newActivity)); - log!.DebugFacilityMessage1("OnStartRet", activityId.ToString(), relatedActivityId.ToString()); + log.DebugFacilityMessage1("OnStartRet", activityId.ToString(), relatedActivityId.ToString()); } } @@ -136,7 +136,7 @@ public void OnStop(string providerName, string activityName, int task, ref Guid if (tplDebug) { log!.DebugFacilityMessage("OnStopEnter", fullActivityName); - log!.DebugFacilityMessage("OnStopEnterActivityState", ActivityInfo.LiveActivities(m_current.Value)); + log.DebugFacilityMessage("OnStopEnterActivityState", ActivityInfo.LiveActivities(m_current.Value)); } while (true) // This is a retry loop. @@ -195,7 +195,7 @@ public void OnStop(string providerName, string activityName, int task, ref Guid if (tplDebug) { log!.DebugFacilityMessage("OnStopRetActivityState", ActivityInfo.LiveActivities(newCurrentActivity)); - log!.DebugFacilityMessage("OnStopRet", activityId.ToString()); + log.DebugFacilityMessage("OnStopRet", activityId.ToString()); } return; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index de14da6dd01307..9d04fdf60c5c11 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -1442,7 +1442,10 @@ protected unsafe void WriteEventWithRelatedActivityIdCore(int eventId, Guid* rel if (ex is EventSourceException) throw; else - ThrowEventSourceException(m_eventData[eventId].Name, ex); + { + ref EventMetadata metadata = ref CollectionsMarshal.GetValueRefOrNullRef(m_eventData, eventId); + ThrowEventSourceException(metadata.Name, ex); + } } } } @@ -2072,7 +2075,10 @@ private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object if (ex is EventSourceException) throw; else - ThrowEventSourceException(m_eventData[eventId].Name, ex); + { + ref EventMetadata metadata = ref CollectionsMarshal.GetValueRefOrNullRef(m_eventData, eventId); + ThrowEventSourceException(metadata.Name, ex); + } } } } @@ -2084,7 +2090,8 @@ private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object private object?[] SerializeEventArgs(int eventId, object?[] args) { Debug.Assert(m_eventData != null); - TraceLoggingEventTypes eventTypes = m_eventData[eventId].TraceLoggingEventTypes; + ref EventMetadata metadata = ref CollectionsMarshal.GetValueRefOrNullRef(m_eventData, eventId); + TraceLoggingEventTypes eventTypes = metadata.TraceLoggingEventTypes; int paramCount = Math.Min(eventTypes.typeInfos.Length, args.Length); // parameter count mismatch get logged in LogEventArgsMismatches var eventData = new object?[eventTypes.typeInfos.Length]; for (int i = 0; i < paramCount; i++) @@ -2103,7 +2110,8 @@ private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object private void LogEventArgsMismatches(int eventId, object?[] args) { Debug.Assert(m_eventData != null); - ParameterInfo[] infos = m_eventData[eventId].Parameters; + ref EventMetadata metadata = ref CollectionsMarshal.GetValueRefOrNullRef(m_eventData, eventId); + ParameterInfo[] infos = metadata.Parameters; if (args.Length != infos.Length) { @@ -2360,9 +2368,10 @@ private bool IsEnabledByDefault(int eventNum, bool enable, EventLevel currentLev return false; Debug.Assert(m_eventData != null); - EventLevel eventLevel = (EventLevel)m_eventData[eventNum].Descriptor.Level; - EventKeywords eventKeywords = unchecked((EventKeywords)((ulong)m_eventData[eventNum].Descriptor.Keywords & (~(SessionMask.All.ToEventKeywords())))); - EventChannel channel = unchecked((EventChannel)m_eventData[eventNum].Descriptor.Channel); + ref EventMetadata metadata = ref CollectionsMarshal.GetValueRefOrNullRef(m_eventData, eventNum); + EventLevel eventLevel = (EventLevel)metadata.Descriptor.Level; + EventKeywords eventKeywords = unchecked((EventKeywords)((ulong)metadata.Descriptor.Keywords & (~(SessionMask.All.ToEventKeywords())))); + EventChannel channel = unchecked((EventChannel)metadata.Descriptor.Channel); return IsEnabledCommon(enable, currentLevel, currentMatchAnyKeyword, eventLevel, eventKeywords, channel); } @@ -4449,7 +4458,7 @@ private static void RemoveReferencesToListenerInEventSources(EventListener liste { if (cur.m_Listener == listenerToRemove) { - CallDisableEventsIfNecessary(cur!, eventSource); + CallDisableEventsIfNecessary(cur, eventSource); } cur = cur.m_Next; diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Exceptions.NativeSinks.Internal.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Exceptions.NativeSinks.Internal.cs new file mode 100644 index 00000000000000..baf1e51a2aa016 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Exceptions.NativeSinks.Internal.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Diagnostics.Tracing +{ + internal sealed partial class NativeRuntimeEventSource : EventSource + { + [NonEvent] + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "NativeRuntimeEventSource_LogExceptionThrown", StringMarshalling = StringMarshalling.Utf16)] + private static unsafe partial void LogExceptionThrown(string exceptionTypeName, string exceptionMessage, IntPtr faultingIP, uint hresult, ushort flags, ushort ClrInstanceID); + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Exceptions.NativeSinks.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Exceptions.NativeSinks.cs new file mode 100644 index 00000000000000..fcb76f295a7ba0 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Exceptions.NativeSinks.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Threading; + +namespace System.Diagnostics.Tracing +{ + [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "NativeRuntimeEventSource is a special case where event methods don't use WriteEvent/WriteEventCore but still need to be instance methods.")] + internal sealed partial class NativeRuntimeEventSource : EventSource + { + [Event(80, Version = 1, Level = EventLevel.Error, Keywords = Keywords.ExceptionKeyword | Keywords.MonitoringKeyword)] + public void ExceptionThrown_V1(string ExceptionType, string ExceptionMessage, IntPtr ExceptionEIP, uint ExceptionHRESULT, ushort ExceptionFlags, ushort ClrInstanceID = DefaultClrInstanceId) + { +#if NATIVEAOT + if (!IsEnabled(EventLevel.Error, Keywords.ExceptionKeyword | Keywords.MonitoringKeyword)) + { + return; + } + LogExceptionThrown(ExceptionType, ExceptionMessage, ExceptionEIP, ExceptionHRESULT, ExceptionFlags, ClrInstanceID); +#else + // QCall not implemented elsewhere + throw new NotImplementedException(); +#endif + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.Internal.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.Internal.cs index 660d65b367e86a..870a12080ab499 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.Internal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.Internal.cs @@ -6,8 +6,6 @@ namespace System.Diagnostics.Tracing { - // This is part of the NativeRuntimeEventsource, which is the managed version of the Microsoft-Windows-DotNETRuntime provider. - // It contains the runtime specific interop to native event sinks. internal sealed partial class NativeRuntimeEventSource : EventSource { [NonEvent] diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs index 9c068cf56d8d77..f50ca10179dd5d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs @@ -7,15 +7,6 @@ namespace System.Diagnostics.Tracing { - // This is part of the NativeRuntimeEventsource, which is the managed version of the Microsoft-Windows-DotNETRuntime provider. - // It contains the handwritten implementation of threading events. - // The events here do not call into the typical WriteEvent* APIs unlike most EventSources because that results in the - // events to be forwarded to EventListeners twice, once directly from the managed WriteEvent API, and another time - // from the mechanism in NativeRuntimeEventSource.ProcessEvents that forwards native runtime events to EventListeners. - // To prevent this, these events call directly into QCalls provided by the runtime (refer to NativeRuntimeEventSource.cs) which call - // FireEtw* methods auto-generated from ClrEtwAll.man. This ensures that corresponding event sinks are being used - // for the native platform. - // For implementation of these events not supporting native sinks, refer to NativeRuntimeEventSource.Threading.cs. [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "NativeRuntimeEventSource is a special case where event methods don't use WriteEvent/WriteEventCore but still need to be instance methods.")] internal sealed partial class NativeRuntimeEventSource : EventSource { diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.cs index ad0a20495d0ca8..092cd3af35d078 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.cs @@ -8,12 +8,19 @@ namespace System.Diagnostics.Tracing { /// /// NativeRuntimeEventSource is an EventSource that represents the ETW/EventPipe events emitted by the native runtime. - /// Most of NativeRuntimeEventSource is auto-generated by scripts/genRuntimeEventSources.py based on the contents of the + /// Most of NativeRuntimeEventSource is auto-generated by NativeRuntimeEventSourceGenerator based on the contents of the /// Microsoft-Windows-DotNETRuntime provider and will throw a NotImplementedException without hand-written overloads of the Events. /// To have a runtime event be fired from the managed code, you need to add a managed definition for that event /// and call into the native runtime that invoke the appropriate native sinks for the platform (i.e. ETW, EventPipe, LTTng). - /// To see some examples of this, refer to NativeRuntimeEventSource.PortableThreadPool.NativeSinks.cs and NativeRuntimeEventSource.PortableThreadPool.cs. - /// Then, modify genRuntimeEventSources.py to skip over the event so that it doesn't generate the dummy method. + /// To see some examples of this, refer to NativeRuntimeEventSource.Threading.NativeSinks.cs and NativeRuntimeEventSource.Threading.cs. + /// Then, modify NativeRuntimeEventSourceGenerator.cs to skip over the event so that it doesn't generate the dummy method. + /// + /// The events in NativeRuntimeEventSource.*.NativeSinks.cs do not call into the typical WriteEvent* APIs unlike most EventSources because that results in the + /// events to be forwarded to EventListeners twice, once directly from the managed WriteEvent API, and another time + /// from the mechanism in NativeRuntimeEventSource.ProcessEvents that forwards native runtime events to EventListeners. + /// To prevent this, these events call directly into QCalls provided by the runtime in NativeRuntimeEventSource.*.NativeSinks.Internal.cs which call + /// FireEtw* methods auto-generated from ClrEtwAll.man. This ensures that corresponding event sinks are being used + /// for the native platform. /// [EventSource(Guid = "E13C0D23-CCBC-4E12-931B-D9CC2EEE27E4", Name = EventSourceName)] [EventSourceAutoGenerate] diff --git a/src/libraries/System.Private.CoreLib/src/System/Enum.cs b/src/libraries/System.Private.CoreLib/src/System/Enum.cs index aa17ad8a5149c3..cb345ebac766e0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Enum.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Enum.cs @@ -1002,7 +1002,7 @@ private static bool TryParseRareTypeByValueOrName( try { - result = (TUnderlying)ToObject(enumType, Convert.ChangeType(value.ToString(), underlyingType, CultureInfo.InvariantCulture)!); + result = (TUnderlying)ToObject(enumType, Convert.ChangeType(value.ToString(), underlyingType, CultureInfo.InvariantCulture)); return true; } catch (FormatException) diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.Android.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.Android.cs index d5e3fae3a9e2b4..23499bfc2bc5ff 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.Android.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.Android.cs @@ -15,6 +15,8 @@ public static partial class Environment private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOption _ /*option*/) { + // No need to validate if 'folder' is defined; GetSpecialFolder handles this check. + if (s_specialFolders == null) { Interlocked.CompareExchange(ref s_specialFolders, new Dictionary(), null); @@ -92,7 +94,9 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio return "/usr/share"; default: - return string.Empty; + if (!Enum.IsDefined(folder)) + throw new ArgumentOutOfRangeException(nameof(folder), folder, SR.Format(SR.Arg_EnumIllegalVal, folder)); + return null; } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs index 694310874e95de..9d7cf66b226dc8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs @@ -19,9 +19,9 @@ public static partial class Environment { private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOption option) { - // Get the path for the SpecialFolder - string path = GetFolderPathCoreWithoutValidation(folder) ?? string.Empty; - Debug.Assert(path != null); + // No need to validate if 'folder' is defined; GetSpecialFolder handles this check. + + string path = GetSpecialFolder(folder) ?? string.Empty; // If we didn't get one, or if we got one but we're not supposed to verify it, // or if we're supposed to verify it and it passes verification, return the path. @@ -46,7 +46,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio return path; } - private static string? GetFolderPathCoreWithoutValidation(SpecialFolder folder) + private static string? GetSpecialFolder(SpecialFolder folder) { // First handle any paths that involve only static paths, avoiding the overheads of getting user-local paths. // https://www.freedesktop.org/software/systemd/man/file-hierarchy.html @@ -143,8 +143,11 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio #endif } + if (!Enum.IsDefined(folder)) + throw new ArgumentOutOfRangeException(nameof(folder), folder, SR.Format(SR.Arg_EnumIllegalVal, folder)); + // No known path for the SpecialFolder - return string.Empty; + return null; } private static string GetXdgConfig(string home) diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.Win32.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.Win32.cs index 70069ba483e1b5..8e1a8e86014af7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.Win32.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.Win32.cs @@ -216,7 +216,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio // // The only SpecialFolderOption defines we have are equivalent to KnownFolderFlags. - string folderGuid; + ReadOnlySpan folderGuid; string? fallbackEnv = null; switch (folder) { @@ -224,8 +224,6 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio case SpecialFolder.System: // This assumes the system directory always exists and thus we don't need to do anything special for any SpecialFolderOption. return SystemDirectory; - default: - return string.Empty; // Map the SpecialFolder to the appropriate Guid case SpecialFolder.ApplicationData: @@ -374,6 +372,9 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio folderGuid = Interop.Shell32.KnownFolders.Windows; fallbackEnv = "windir"; break; + default: + Debug.Assert(!Enum.IsDefined(folder), $"Unexpected SpecialFolder value: {folder}. Please ensure all SpecialFolder enum values are handled in the switch statement."); + throw new ArgumentOutOfRangeException(nameof(folder), folder, SR.Format(SR.Arg_EnumIllegalVal, folder)); } Guid folderId = new Guid(folderGuid); diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.cs index 81cd182e7da155..11c712fc68d6c1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.cs @@ -148,15 +148,20 @@ public static string ExpandEnvironmentVariables(string name) return ExpandEnvironmentVariablesCore(name); } - public static string GetFolderPath(SpecialFolder folder) => GetFolderPath(folder, SpecialFolderOption.None); + public static string GetFolderPath(SpecialFolder folder) => GetFolderPathCore(folder, SpecialFolderOption.None); public static string GetFolderPath(SpecialFolder folder, SpecialFolderOption option) { - if (!Enum.IsDefined(folder)) - throw new ArgumentOutOfRangeException(nameof(folder), folder, SR.Format(SR.Arg_EnumIllegalVal, folder)); + // No need to validate if 'folder' is defined; GetFolderPathCore handles this check. - if (option != SpecialFolderOption.None && !Enum.IsDefined(option)) - throw new ArgumentOutOfRangeException(nameof(option), option, SR.Format(SR.Arg_EnumIllegalVal, option)); + if (option is not SpecialFolderOption.None and not SpecialFolderOption.Create and not SpecialFolderOption.DoNotVerify) + { + // Use a throw helper so that if 'option' is a constant, + // the JIT can inline this method and remove the validation check entirely. + Throw(option); + static void Throw(SpecialFolderOption option) => + throw new ArgumentOutOfRangeException(nameof(option), option, SR.Format(SR.Arg_EnumIllegalVal, option)); + } return GetFolderPathCore(folder, option); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.iOS.cs index 973790e0785a01..3464790bb489ee 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.iOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.iOS.cs @@ -20,6 +20,8 @@ public static partial class Environment private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOption _ /*option*/) { + // No need to validate if 'folder' is defined; GetSpecialFolder handles this check. + if (s_specialFolders == null) { Interlocked.CompareExchange(ref s_specialFolders, new Dictionary(), null); @@ -91,7 +93,9 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio return "/usr/share"; default: - return string.Empty; + if (!Enum.IsDefined(folder)) + throw new ArgumentOutOfRangeException(nameof(folder), folder, SR.Format(SR.Arg_EnumIllegalVal, folder)); + return null; } static string CombineSearchPath(NSSearchPathDirectory searchPath, string subdirectory) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs index 52b675806f94a4..d49348f4a7c1d8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs @@ -405,7 +405,7 @@ private static bool EnumEraNames(string localeName, CalendarId calendarId, Calen // So for other calendars, only return the latest era. if (calendarId != CalendarId.JAPAN && calendarId != CalendarId.JAPANESELUNISOLAR && eraNames?.Length > 0) { - eraNames = [eraNames![^1]]; + eraNames = [eraNames[^1]]; } return result; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index 7bc3ef949e9114..dca87b323f29b8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -625,15 +625,11 @@ private static CultureData CreateCultureWithInvariantData() invariant._iFirstDayOfWeek = 0; // first day of week invariant._iFirstWeekOfYear = 0; // first week of year - // all available calendar type(s). The first one is the default calendar - invariant._waCalendars = [CalendarId.GREGORIAN]; - - if (!GlobalizationMode.InvariantNoLoad) - { - // Store for specific data about each calendar - invariant._calendars = new CalendarData[CalendarData.MAX_CALENDARS]; - invariant._calendars[0] = CalendarData.Invariant; - } + // Calendar information is expensive size-wise, especially for AOT. + // CalendarData.Invariant is special cased in _waCalendars and _calendars + // accessors and gets initialized lazily. + // invariant._waCalendars + // invariant._calendars // Text information invariant._iReadingLayout = 0; @@ -658,8 +654,7 @@ private static CultureData CreateCultureWithInvariantData() /// Build our invariant information /// We need an invariant instance, which we build hard-coded /// - internal static CultureData Invariant => s_Invariant ??= CreateCultureWithInvariantData(); - private static CultureData? s_Invariant; + internal static CultureData Invariant => field ??= CreateCultureWithInvariantData(); // Cache of cultures we've already looked up private static volatile Dictionary? s_cachedCultures; @@ -829,7 +824,7 @@ private static string NormalizeCultureName(string name, out bool isNeutralName) private bool InitCompatibilityCultureData() { // for compatibility handle the deprecated ids: zh-chs, zh-cht - string cultureName = _sRealName!; + string cultureName = _sRealName; string fallbackCultureName; string realCultureName; @@ -932,7 +927,7 @@ internal string CultureName // Parent name (which may be a custom locale/culture) // Ask using the real name, so that we get parents of neutrals - internal string ParentName => _sParent ??= GetLocaleInfoCore(_sRealName!, LocaleStringData.ParentName); + internal string ParentName => _sParent ??= GetLocaleInfoCore(_sRealName, LocaleStringData.ParentName); // Localized pretty name for this locale (ie: Inglis (estados Unitos)) internal string DisplayName @@ -961,7 +956,7 @@ internal string DisplayName } } - return localizedDisplayName!; + return localizedDisplayName; } } @@ -1111,8 +1106,8 @@ internal string SpecificCultureName /// abbreviated windows language name (ie: enu) (non-standard, avoid this) /// internal string ThreeLetterWindowsLanguageName => _sAbbrevLang ??= GlobalizationMode.UseNls ? - NlsGetThreeLetterWindowsLanguageName(_sRealName!) : - IcuGetThreeLetterWindowsLanguageName(_sRealName!); + NlsGetThreeLetterWindowsLanguageName(_sRealName) : + IcuGetThreeLetterWindowsLanguageName(_sRealName); /// /// Localized name for this language @@ -1156,7 +1151,7 @@ internal int GeoId { if (_iGeoId == undef && !GlobalizationMode.Invariant) { - _iGeoId = GlobalizationMode.UseNls ? NlsGetLocaleInfo(LocaleNumberData.GeoId) : IcuGetGeoId(_sRealName!); + _iGeoId = GlobalizationMode.UseNls ? NlsGetLocaleInfo(LocaleNumberData.GeoId) : IcuGetGeoId(_sRealName); } return _iGeoId; } @@ -1233,8 +1228,8 @@ internal int KeyboardLayoutId /// Console fallback name (ie: locale to use for console apps for unicode-only locales) /// internal string SCONSOLEFALLBACKNAME => _sConsoleFallbackName ??= GlobalizationMode.UseNls ? - NlsGetConsoleFallbackName(_sRealName!) : - IcuGetConsoleFallbackName(_sRealName!); + NlsGetConsoleFallbackName(_sRealName) : + IcuGetConsoleFallbackName(_sRealName); /// /// grouping of digits @@ -1648,61 +1643,68 @@ internal CalendarId[] CalendarIds { get { - if (_waCalendars == null && !GlobalizationMode.Invariant) + if (_waCalendars == null) { - // We pass in an array of ints, and native side fills it up with count calendars. - // We then have to copy that list to a new array of the right size. - // Default calendar should be first - CalendarId[] calendars = new CalendarId[23]; - Debug.Assert(_sWindowsName != null, "[CultureData.CalendarIds] Expected _sWindowsName to be populated by already"); - - int count = CalendarData.GetCalendarsCore(_sWindowsName, _bUseOverrides, calendars); - - // See if we had a calendar to add. - if (count == 0) + if (GlobalizationMode.Invariant || IsInvariantCulture) { - // Failed for some reason, just grab Gregorian from Invariant - _waCalendars = Invariant._waCalendars!; + // We do this lazily as opposed in CreateCultureWithInvariantData to avoid introducing + // enum arrays into apps that otherwise wouldn't have them. This helps with size in AOT. + _waCalendars = [CalendarId.GREGORIAN]; } else { - // The OS may not return calendar 4 for zh-TW, but we've always allowed it. - // TODO: Is this hack necessary long-term? - if (_sWindowsName == "zh-TW") - { - bool found = false; + // We pass in an array of ints, and native side fills it up with count calendars. + // We then have to copy that list to a new array of the right size. + // Default calendar should be first + CalendarId[] calendars = new CalendarId[23]; + Debug.Assert(_sWindowsName != null, "[CultureData.CalendarIds] Expected _sWindowsName to be populated by already"); + + int count = CalendarData.GetCalendarsCore(_sWindowsName, _bUseOverrides, calendars); - // Do we need to insert calendar 4? - for (int i = 0; i < count; i++) + // See if we had a calendar to add. + if (count == 0) + { + // Failed for some reason, just use Gregorian + _waCalendars = Invariant.CalendarIds; + } + else + { + // The OS may not return calendar 4 for zh-TW, but we've always allowed it. + // TODO: Is this hack necessary long-term? + if (_sWindowsName == "zh-TW") { - // Stop if we found calendar four - if (calendars[i] == CalendarId.TAIWAN) + bool found = false; + + // Do we need to insert calendar 4? + for (int i = 0; i < count; i++) { - found = true; - break; + // Stop if we found calendar four + if (calendars[i] == CalendarId.TAIWAN) + { + found = true; + break; + } } - } - // If not found then insert it - if (!found) - { - // Insert it as the 2nd calendar - count++; - // Copy them from the 2nd position to the end, -1 for skipping 1st, -1 for one being added. - Array.Copy(calendars, 1, calendars, 2, 23 - 1 - 1); - calendars[1] = CalendarId.TAIWAN; + // If not found then insert it + if (!found) + { + // Insert it as the 2nd calendar + count++; + // Copy them from the 2nd position to the end, -1 for skipping 1st, -1 for one being added. + Array.Copy(calendars, 1, calendars, 2, 23 - 1 - 1); + calendars[1] = CalendarId.TAIWAN; + } } - } - - // It worked, remember the list - CalendarId[] temp = new CalendarId[count]; - Array.Copy(calendars, temp, count); - _waCalendars = temp; + // It worked, remember the list + CalendarId[] temp = new CalendarId[count]; + Array.Copy(calendars, temp, count); + _waCalendars = temp; + } } } - - return _waCalendars!; + return _waCalendars; } } @@ -1738,8 +1740,17 @@ internal CalendarData GetCalendar(CalendarId calendarId) // Make sure that calendar has data if (calendarData == null) { - Debug.Assert(_sWindowsName != null, "[CultureData.GetCalendar] Expected _sWindowsName to be populated by already"); - calendarData = new CalendarData(_sWindowsName, calendarId, _bUseOverrides); + if (calendarIndex == 0 && IsInvariantCulture) + { + // We do this lazily as opposed in CreateCultureWithInvariantData to avoid introducing + // invariant calendar data into apps that don't even need calendar. + calendarData = CalendarData.Invariant; + } + else + { + Debug.Assert(_sWindowsName != null, "[CultureData.GetCalendar] Expected _sWindowsName to be populated by already"); + calendarData = new CalendarData(_sWindowsName, calendarId, _bUseOverrides); + } _calendars[calendarIndex] = calendarData; } @@ -1819,7 +1830,7 @@ internal int ANSICodePage { if (_iDefaultAnsiCodePage == undef && !GlobalizationMode.Invariant) { - _iDefaultAnsiCodePage = GetAnsiCodePage(_sRealName!); + _iDefaultAnsiCodePage = GetAnsiCodePage(_sRealName); } return _iDefaultAnsiCodePage; } @@ -1834,7 +1845,7 @@ internal int OEMCodePage { if (_iDefaultOemCodePage == undef && !GlobalizationMode.Invariant) { - _iDefaultOemCodePage = GetOemCodePage(_sRealName!); + _iDefaultOemCodePage = GetOemCodePage(_sRealName); } return _iDefaultOemCodePage; } @@ -1849,7 +1860,7 @@ internal int MacCodePage { if (_iDefaultMacCodePage == undef && !GlobalizationMode.Invariant) { - _iDefaultMacCodePage = GetMacCodePage(_sRealName!); + _iDefaultMacCodePage = GetMacCodePage(_sRealName); } return _iDefaultMacCodePage; } @@ -1864,7 +1875,7 @@ internal int EBCDICCodePage { if (_iDefaultEbcdicCodePage == undef && !GlobalizationMode.Invariant) { - _iDefaultEbcdicCodePage = GetEbcdicCodePage(_sRealName!); + _iDefaultEbcdicCodePage = GetEbcdicCodePage(_sRealName); } return _iDefaultEbcdicCodePage; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs index 07161c81575326..c146f174ff1785 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs @@ -144,13 +144,13 @@ private static void AsyncLocalSetCurrentUICulture(AsyncLocalValueChangedArgs GlobalizationMode.Invariant ? SR.Argument_CultureNotSupportedInInvariantMode : SR.Argument_CultureNotSupported; @@ -377,7 +377,7 @@ public static CultureInfo CurrentCulture { Interlocked.CompareExchange(ref s_asyncLocalCurrentCulture, new AsyncLocal(AsyncLocalSetCurrentCulture), null); } - s_asyncLocalCurrentCulture!.Value = value; + s_asyncLocalCurrentCulture.Value = value; } } @@ -401,7 +401,7 @@ public static CultureInfo CurrentUICulture } // this one will set s_currentThreadUICulture too - s_asyncLocalCurrentUICulture!.Value = value; + s_asyncLocalCurrentUICulture.Value = value; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs index 547fbc212b0a36..4c721e939b447b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs @@ -57,15 +57,9 @@ public sealed class DateTimeFormatInfo : IFormatProvider, ICloneable // The culture name used to create this DTFI. private string? _name; - // The language name of the culture used to create this DTFI. - private string? _langName; - // CompareInfo usually used by the parser. private CompareInfo? _compareInfo; - // Culture matches current DTFI. mainly used for string comparisons during parsing. - private CultureInfo? _cultureInfo; - private string? amDesignator; private string? pmDesignator; @@ -141,8 +135,6 @@ public sealed class DateTimeFormatInfo : IFormatProvider, ICloneable private string[]? m_abbrevEraNames; private string[]? m_abbrevEnglishEraNames; - private CalendarId[]? optionalCalendars; - private const int DEFAULT_ALL_DATETIMES_SIZE = 132; // CultureInfo updates this @@ -155,9 +147,11 @@ public sealed class DateTimeFormatInfo : IFormatProvider, ICloneable private string CultureName => _name ??= _cultureData.CultureName; - private CultureInfo Culture => _cultureInfo ??= CultureInfo.GetCultureInfo(CultureName); + // Culture matches current DTFI. mainly used for string comparisons during parsing. + private CultureInfo Culture => field ??= CultureInfo.GetCultureInfo(CultureName); - private string LanguageName => _langName ??= _cultureData.TwoLetterISOLanguageName; + // The language name of the culture used to create this DTFI. + private string LanguageName => field ??= _cultureData.TwoLetterISOLanguageName; /// /// Create an array of string which contains the abbreviated day names. @@ -465,7 +459,7 @@ public Calendar Calendar } } - private CalendarId[] OptionalCalendars => optionalCalendars ??= _cultureData.CalendarIds; + private CalendarId[] OptionalCalendars => field ??= _cultureData.CalendarIds; /// /// Get the era value by parsing the name of the era. diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs index edc529fba01dda..e35168cbd5f75f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.cs @@ -39,7 +39,7 @@ private static string GetIcuLoadFailureMessage() { // These strings can't go into resources, because a resource lookup requires globalization, which requires ICU if (OperatingSystem.IsBrowser() || OperatingSystem.IsWasi() || OperatingSystem.IsAndroid() || - OperatingSystem.IsIOS() || OperatingSystem.IsTvOS() || OperatingSystem.IsWatchOS()) + OperatingSystem.IsIOS() || OperatingSystem.IsTvOS()) { return "Unable to load required ICU Globalization data. Please see https://aka.ms/dotnet-missing-libicu for more information"; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseLunisolarCalendar.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseLunisolarCalendar.cs index 85d544899fe061..fc759e0cfaf760 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseLunisolarCalendar.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseLunisolarCalendar.cs @@ -195,7 +195,7 @@ private static EraInfo[] TrimEras(EraInfo[] baseEras) // If we didn't copy any then something was wrong, just return base if (newIndex == 0) return baseEras; - Array.Resize(ref newEras!, newIndex); + Array.Resize(ref newEras, newIndex); return newEras; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.cs index 2488ab7824be71..0668940b1365ea 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.cs @@ -44,6 +44,11 @@ internal static bool TryNormalize(ReadOnlySpan source, Span destinat { CheckNormalizationForm(normalizationForm); + if (source.Overlaps(destination)) + { + ThrowHelper.ThrowArgumentException(ExceptionResource.InvalidOperation_SpanOverlappedOperation); + } + // In Invariant mode we assume all characters are normalized because we don't support any linguistic operations on strings. // If it's ASCII && one of the 4 main forms, then it's already normalized. if (GlobalizationMode.Invariant || Ascii.IsValid(source)) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/NumberFormatInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/NumberFormatInfo.cs index 8921b87b945361..7e41139b4bf6c5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/NumberFormatInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/NumberFormatInfo.cs @@ -39,7 +39,6 @@ namespace System.Globalization /// public sealed class NumberFormatInfo : IFormatProvider, ICloneable { - private static NumberFormatInfo? s_invariantInfo; internal static readonly string[] s_asciiDigits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]; internal static readonly int[] s_intArrayWithElement3 = [3]; @@ -204,7 +203,7 @@ private void VerifyWritable() /// supported and constant irrespective of the current culture. /// Used by FromString methods. /// - public static NumberFormatInfo InvariantInfo => s_invariantInfo ??= + public static NumberFormatInfo InvariantInfo => field ??= // Lazy create the invariant info. This cannot be done in a .cctor because exceptions can // be thrown out of a .cctor stack that will need this. CultureInfo.InvariantCulture.NumberFormat; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs index ef7490d413d49f..f95e54ba338d59 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs @@ -26,7 +26,6 @@ private enum Tristate : byte True = 2 } - private string? _listSeparator; private bool _isReadOnly; private readonly string _cultureName; @@ -124,13 +123,13 @@ internal void SetReadOnlyState(bool readOnly) /// public string ListSeparator { - get => _listSeparator ??= _cultureData.ListSeparator; + get => field ??= _cultureData.ListSeparator; set { ArgumentNullException.ThrowIfNull(value); VerifyWritable(); - _listSeparator = value; + field = value; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/File.cs b/src/libraries/System.Private.CoreLib/src/System/IO/File.cs index 46461a0d59bddd..e7c4e948d6c3ce 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/File.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/File.cs @@ -20,10 +20,9 @@ namespace System.IO public static partial class File { private const int ChunkSize = 8192; - private static Encoding? s_UTF8NoBOM; // UTF-8 without BOM and with error detection. Same as the default encoding for StreamWriter. - private static Encoding UTF8NoBOM => s_UTF8NoBOM ??= new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); + private static Encoding UTF8NoBOM => field ??= new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); internal const int DefaultBufferSize = 4096; diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringWriter.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringWriter.cs index 8fc4bb83cd086b..478d95fd347ac4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringWriter.cs @@ -12,8 +12,6 @@ namespace System.IO // the resulting sequence of characters to be presented as a string. public class StringWriter : TextWriter { - private static UnicodeEncoding? s_encoding; - private readonly StringBuilder _sb; private bool _isOpen; @@ -57,7 +55,7 @@ protected override void Dispose(bool disposing) } - public override Encoding Encoding => s_encoding ??= new UnicodeEncoding(false, false); + public override Encoding Encoding => field ??= new UnicodeEncoding(false, false); // Returns the underlying StringBuilder. This is either the StringBuilder // that was passed to the constructor, or the StringBuilder that was diff --git a/src/libraries/System.Private.CoreLib/src/System/Int128.cs b/src/libraries/System.Private.CoreLib/src/System/Int128.cs index 65380d43f3c739..bfc8e8c8bf0e25 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int128.cs @@ -1180,7 +1180,12 @@ public static Int128 Log2(Int128 value) return lower; } - internal static Int128 BigMul(Int128 left, Int128 right, out Int128 lower) + /// Produces the full product of two unsigned native integers. + /// The integer to multiply with . + /// The integer to multiply with . + /// The lower half of the full product. + /// The upper half of the full product. + public static Int128 BigMul(Int128 left, Int128 right, out Int128 lower) { // This follows the same logic as is used in `long Math.BigMul(long, long, out long)` diff --git a/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs b/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs index e10fa3ca90c581..4abd1b935f0eb5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs @@ -179,6 +179,24 @@ public static nint MinValue get => unchecked((nint)nint_t.MinValue); } + /// Produces the full product of two unsigned native integers. + /// The integer to multiply with . + /// The integer to multiply with . + /// The lower half of the full product. + /// The upper half of the full product. + public static nint BigMul(nint left, nint right, out nint lower) + { +#if TARGET_64BIT + Int128 result = long.BigMul(left, right); + lower = (nint)result.Lower; + return (nint)result.Upper; +#else + long result = Math.BigMul((int)left, (int)right); + lower = (int)result; + return (int)(result >>> 32); +#endif + } + public int CompareTo(object? value) { if (value is nint other) diff --git a/src/libraries/System.Private.CoreLib/src/System/Marvin.cs b/src/libraries/System.Private.CoreLib/src/System/Marvin.cs index 31c1b696a68017..dd87afa5caecdf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Marvin.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Marvin.cs @@ -25,6 +25,7 @@ internal static partial class Marvin /// /// Compute a Marvin hash and collapse it into a 32-bit hash. /// + [MethodImpl(MethodImplOptions.NoInlining)] public static int ComputeHash32(ref byte data, uint count, uint p0, uint p1) { // Control flow of this method generally flows top-to-bottom, trying to diff --git a/src/libraries/System.Private.CoreLib/src/System/Memory.cs b/src/libraries/System.Private.CoreLib/src/System/Memory.cs index a0da08ba9a8038..c8eac110cb5234 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Memory.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Memory.cs @@ -284,7 +284,7 @@ public Span Span { // Special-case string since it's the most common for ROM. - refToReturn = ref Unsafe.As(ref Unsafe.As(tmpObject).GetRawStringData()); + refToReturn = ref Unsafe.As(ref ((string)tmpObject).GetRawStringData()); lengthOfUnderlyingSpan = Unsafe.As(tmpObject).Length; } else if (RuntimeHelpers.ObjectHasComponentSize(tmpObject)) diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs b/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs index e22a12d24f6440..2062aa526cb386 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs @@ -272,6 +272,35 @@ internal static partial class Number // Optimizations using "TwoDigits" inspired by: // https://engineering.fb.com/2013/03/15/developer-tools/three-optimization-tips-for-c/ +#if MONO + // Workaround for a performance regression on Mono: https://github.com/dotnet/runtime/issues/111932 + private static readonly byte[] TwoDigitsCharsAsBytes = + MemoryMarshal.AsBytes("00010203040506070809" + + "10111213141516171819" + + "20212223242526272829" + + "30313233343536373839" + + "40414243444546474849" + + "50515253545556575859" + + "60616263646566676869" + + "70717273747576777879" + + "80818283848586878889" + + "90919293949596979899").ToArray(); + private static readonly byte[] TwoDigitsBytes = + ("00010203040506070809"u8 + + "10111213141516171819"u8 + + "20212223242526272829"u8 + + "30313233343536373839"u8 + + "40414243444546474849"u8 + + "50515253545556575859"u8 + + "60616263646566676869"u8 + + "70717273747576777879"u8 + + "80818283848586878889"u8 + + "90919293949596979899"u8).ToArray(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ref byte GetTwoDigitsBytesRef(bool useChars) => + ref MemoryMarshal.GetArrayDataReference(useChars ? TwoDigitsCharsAsBytes : TwoDigitsBytes); +#else private static ReadOnlySpan TwoDigitsCharsAsBytes => MemoryMarshal.AsBytes("00010203040506070809" + "10111213141516171819" + @@ -295,6 +324,12 @@ internal static partial class Number "80818283848586878889"u8 + "90919293949596979899"u8; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ref byte GetTwoDigitsBytesRef(bool useChars) => + ref MemoryMarshal.GetReference(useChars ? TwoDigitsCharsAsBytes : TwoDigitsBytes); +#endif + + public static unsafe string FormatDecimal(decimal value, ReadOnlySpan format, NumberFormatInfo info) { char fmt = ParseFormatSpecifier(format, out int digits); @@ -1572,7 +1607,7 @@ internal static unsafe void WriteTwoDigits(uint value, TChar* ptr) where Unsafe.CopyBlockUnaligned( ref *(byte*)ptr, - ref Unsafe.Add(ref MemoryMarshal.GetReference(typeof(TChar) == typeof(char) ? TwoDigitsCharsAsBytes : TwoDigitsBytes), (uint)sizeof(TChar) * 2 * value), + ref Unsafe.Add(ref GetTwoDigitsBytesRef(typeof(TChar) == typeof(char)), (uint)sizeof(TChar) * 2 * value), (uint)sizeof(TChar) * 2); } @@ -1588,7 +1623,7 @@ internal static unsafe void WriteFourDigits(uint value, TChar* ptr) where (value, uint remainder) = Math.DivRem(value, 100); - ref byte charsArray = ref MemoryMarshal.GetReference(typeof(TChar) == typeof(char) ? TwoDigitsCharsAsBytes : TwoDigitsBytes); + ref byte charsArray = ref GetTwoDigitsBytesRef(typeof(TChar) == typeof(char)); Unsafe.CopyBlockUnaligned( ref *(byte*)ptr, diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs index 498ccc82d7b702..a1f35d196bca50 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs @@ -389,12 +389,8 @@ private static int Log2SoftwareFallback(uint value) value |= value >> 08; value |= value >> 16; - // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check - return Unsafe.AddByteOffset( - // Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_1100_0100_1010_1100_1101_1101u - ref MemoryMarshal.GetReference(Log2DeBruijn), - // uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here - (IntPtr)(int)((value * 0x07C4ACDDu) >> 27)); + // Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_1100_0100_1010_1100_1101_1101u + return Log2DeBruijn[(int)((value * 0x07C4ACDDu) >> 27)]; } /// Returns the integer (ceiling) log of the specified value, base 2. diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.Extensions.cs index c85f47cea68b50..07ea8e13e8ff4f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.Extensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Plane.Extensions.cs @@ -11,13 +11,6 @@ public static partial class Vector /// The plane to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Vector4 AsVector4(this Plane value) - { -#if MONO - return Unsafe.As(ref value); -#else - return Unsafe.BitCast(value); -#endif - } + public static Vector4 AsVector4(this Plane value) => Unsafe.BitCast(value); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.Extensions.cs index e5e402880fb324..02086f9bc1bedb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.Extensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Quaternion.Extensions.cs @@ -11,13 +11,6 @@ public static partial class Vector /// The quaternion to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Vector4 AsVector4(this Quaternion value) - { -#if MONO - return Unsafe.As(ref value); -#else - return Unsafe.BitCast(value); -#endif - } + public static Vector4 AsVector4(this Quaternion value) => Unsafe.BitCast(value); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs index 32166a6f4ecedd..f80cba2809dc12 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs @@ -149,11 +149,7 @@ public static Vector As(this Vector vector) ThrowHelper.ThrowForUnsupportedNumericsVectorBaseType(); ThrowHelper.ThrowForUnsupportedNumericsVectorBaseType(); -#if MONO - return Unsafe.As, Vector>(ref vector); -#else return Unsafe.BitCast, Vector>(vector); -#endif } /// Reinterprets a as a new . diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs index 6aa93a2d4a47a8..b6d9fa2ef48356 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.Extensions.cs @@ -12,26 +12,12 @@ public static unsafe partial class Vector /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . - public static Plane AsPlane(this Vector4 value) - { -#if MONO - return Unsafe.As(ref value); -#else - return Unsafe.BitCast(value); -#endif - } + public static Plane AsPlane(this Vector4 value) => Unsafe.BitCast(value); /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . - public static Quaternion AsQuaternion(this Vector4 value) - { -#if MONO - return Unsafe.As(ref value); -#else - return Unsafe.BitCast(value); -#endif - } + public static Quaternion AsQuaternion(this Vector4 value) => Unsafe.BitCast(value); /// Reinterprets a as a new . /// The vector to reinterpret. diff --git a/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs b/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs index 61bd9314bd26ca..85e4feace8cd01 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs @@ -206,7 +206,7 @@ public ReadOnlySpan Span { // Special-case string since it's the most common for ROM. - refToReturn = ref Unsafe.As(ref Unsafe.As(tmpObject).GetRawStringData()); + refToReturn = ref Unsafe.As(ref ((string)tmpObject).GetRawStringData()); lengthOfUnderlyingSpan = Unsafe.As(tmpObject).Length; } else if (RuntimeHelpers.ObjectHasComponentSize(tmpObject)) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs index a1878467759b3d..ebb0093edfe219 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs @@ -341,7 +341,7 @@ public static Assembly LoadFile(string path) // Requestor assembly was loaded using loadFrom, so look for its dependencies // in the same folder as it. // Form the name of the assembly using the path of the assembly that requested its load. - AssemblyName requestedAssemblyName = new AssemblyName(args.Name!); + AssemblyName requestedAssemblyName = new AssemblyName(args.Name); string requestedAssemblyPath = Path.Combine(Path.GetDirectoryName(requestorPath)!, requestedAssemblyName.Name + ".dll"); #if CORECLR if (AssemblyLoadContext.IsTracingEnabled()) @@ -384,7 +384,7 @@ public static Assembly LoadFrom(string assemblyFile) { if (!s_loadFromHandlerSet) { - AssemblyLoadContext.AssemblyResolve += LoadFromResolveHandler!; + AssemblyLoadContext.AssemblyResolve += LoadFromResolveHandler; s_loadFromHandlerSet = true; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyName.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyName.cs index de95ea49016867..646772a3db0a9c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyName.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyName.cs @@ -376,7 +376,6 @@ internal static void PercentEncodeByte(byte ch, ref ValueStringBuilder vsb) HexConverter.ToCharsBuffer(ch, vsb.AppendSpan(2), 0, HexConverter.Casing.Upper); } - [field: AllowNull] private static SearchValues UnreservedReserved => field ??= SearchValues.Create("!#$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~"); private const int StackallocThreshold = 512; diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs index ab5f4132c23a0e..63a22060a16696 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs @@ -396,11 +396,11 @@ internal void CopyBack(Span dest, ReadOnlySpan copyOfParameter { Debug.Assert(copyOfParameters[i] != null); Debug.Assert(((RuntimeType)copyOfParameters[i]!.GetType()).IsNullableOfT); - dest![i] = RuntimeMethodHandle.ReboxFromNullable(copyOfParameters[i]); + dest[i] = RuntimeMethodHandle.ReboxFromNullable(copyOfParameters[i]); } else { - dest![i] = copyOfParameters[i]; + dest[i] = copyOfParameters[i]; } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs index d64ccd64a482e0..16c39c2b698d35 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs @@ -200,7 +200,7 @@ private static Module GetDynamicMethodsModule() AssemblyBuilderAccess.Run, AssemblyLoadContext.Default, null); // this always gets the internal module. - s_anonymouslyHostedDynamicMethodsModule = assembly.ManifestModule!; + s_anonymouslyHostedDynamicMethodsModule = assembly.ManifestModule; } return s_anonymouslyHostedDynamicMethodsModule; @@ -269,7 +269,7 @@ private void Init(string name, if (owner?.UnderlyingSystemType is RuntimeType rtOwner) { if (rtOwner.HasElementType || rtOwner.ContainsGenericParameters - || rtOwner.IsGenericParameter || rtOwner.IsInterface) + || rtOwner.IsGenericParameter || rtOwner.IsActualInterface) throw new ArgumentException(SR.Argument_InvalidTypeForDynamicMethod); _typeOwner = rtOwner; diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs index 02ec3a17b469ae..6bdbc966825e93 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs @@ -18,7 +18,6 @@ internal sealed partial class TypeBuilderInstantiation : TypeInfo private Type _genericType; private Type[] _typeArguments; #endregion - private string? _strFullQualName; internal Hashtable _hashtable; @@ -104,7 +103,7 @@ public override Type MakeArrayType(int rank) public override Assembly Assembly => _genericType.Assembly; public override RuntimeTypeHandle TypeHandle => throw new NotSupportedException(); - public override string? FullName => _strFullQualName ??= TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName); + public override string? FullName => field ??= TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName); public override string? Namespace => _genericType.Namespace; public override string? AssemblyQualifiedName => TypeNameBuilder.ToString(this, TypeNameBuilder.Format.AssemblyQualifiedName); [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2055:UnrecognizedReflectionPattern", @@ -162,22 +161,22 @@ public override Type? BaseType } } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] - protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); } + protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) { throw new NotSupportedException(SR.Format(SR.NotSupported_TypeBuilderInstantiation_ResolvingMembers, nameof(TypeBuilder.GetConstructor))); } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] - public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw new NotSupportedException(); } + public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw new NotSupportedException(SR.Format(SR.NotSupported_TypeBuilderInstantiation_ResolvingMembers, nameof(TypeBuilder.GetConstructor))); } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] - protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); } + protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(SR.Format(SR.NotSupported_TypeBuilderInstantiation_ResolvingMembers, nameof(TypeBuilder.GetMethod))); } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] - public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw new NotSupportedException(); } + public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw new NotSupportedException(SR.Format(SR.NotSupported_TypeBuilderInstantiation_ResolvingMembers, nameof(TypeBuilder.GetMethod))); } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] - public override FieldInfo GetField(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + public override FieldInfo GetField(string name, BindingFlags bindingAttr) { throw new NotSupportedException(SR.Format(SR.NotSupported_TypeBuilderInstantiation_ResolvingMembers, nameof(TypeBuilder.GetField))); } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] - public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(); } + public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(SR.Format(SR.NotSupported_TypeBuilderInstantiation_ResolvingMembers, nameof(TypeBuilder.GetField))); } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBaseInvoker.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBaseInvoker.cs index ed2b4cd220a3dc..1a75a10a7898cb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBaseInvoker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBaseInvoker.cs @@ -331,11 +331,11 @@ internal void CopyBack(object?[] dest, Span copyOfParameters, Span dest, Span copyOfParameters, Span< { Debug.Assert(copyOfParameters[i] != null); Debug.Assert(((RuntimeType)copyOfParameters[i]!.GetType()).IsNullableOfT); - dest![i] = RuntimeMethodHandle.ReboxFromNullable(copyOfParameters[i]); + dest[i] = RuntimeMethodHandle.ReboxFromNullable(copyOfParameters[i]); } else { - dest![i] = copyOfParameters[i]; + dest[i] = copyOfParameters[i]; } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/ModifiedFunctionPointerType.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/ModifiedFunctionPointerType.cs index 6971e1642d0683..0de9f152c6b5a1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/ModifiedFunctionPointerType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/ModifiedFunctionPointerType.cs @@ -28,7 +28,7 @@ public override Type GetFunctionPointerReturnType() Type Initialize() { Interlocked.CompareExchange(ref _returnType, GetTypeParameter(UnmodifiedType.GetFunctionPointerReturnType(), 0), null); - return _returnType!; + return _returnType; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/ModifiedHasElementType.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/ModifiedHasElementType.cs index 19df3af6f7944c..7bdc783102f7e6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/ModifiedHasElementType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/ModifiedHasElementType.cs @@ -26,7 +26,7 @@ internal ModifiedHasElementType(Type unmodifiedType, TypeSignature typeSignature Type Initialize() { Interlocked.CompareExchange(ref _elementType, GetTypeParameter(UnmodifiedType.GetElementType()!, 0), null); - return _elementType!; + return _elementType; } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/NullabilityInfoContext.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/NullabilityInfoContext.cs index e9b6f9e994ff3f..0f1932124201e3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/NullabilityInfoContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/NullabilityInfoContext.cs @@ -422,7 +422,7 @@ private void TryLoadGenericMetaTypeNullability(MemberInfo memberInfo, Nullabilit if (metaType != null) { - CheckGenericParameters(nullability, metaMember!, metaType, memberInfo.ReflectedType); + CheckGenericParameters(nullability, metaMember, metaType, memberInfo.ReflectedType); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeNameResolver.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeNameResolver.cs index 654c7ad3f08bd7..abedd32a7f8c71 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeNameResolver.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeNameResolver.cs @@ -74,7 +74,7 @@ internal partial struct TypeNameResolver do { nestingDepth++; - current = current.DeclaringType!; + current = current.DeclaringType; } while (current.IsNested); @@ -83,7 +83,7 @@ internal partial struct TypeNameResolver while (current.IsNested) { nestedTypeNames[--nestingDepth] = TypeName.Unescape(current.Name); - current = current.DeclaringType!; + current = current.DeclaringType; } return GetType(current.FullName, nestedTypeNames, typeName); diff --git a/src/libraries/System.Private.CoreLib/src/System/Resources/FastResourceComparer.cs b/src/libraries/System.Private.CoreLib/src/System/Resources/FastResourceComparer.cs index eedae239e7bf25..77341114c588ee 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Resources/FastResourceComparer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Resources/FastResourceComparer.cs @@ -24,7 +24,7 @@ public int GetHashCode(object key) public int GetHashCode([DisallowNull] string? key) { - return HashFunction(key!); + return HashFunction(key); } // This hash function MUST be publicly documented with the resource diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastCache.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastCache.cs index c5602eff0d2824..41effcee98dbef 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastCache.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastCache.cs @@ -140,7 +140,7 @@ private static ref CastCacheEntry Element(ref int tableData, int index) internal CastResult TryGet(nuint source, nuint target) { // table is always initialized and is not null. - return TryGet(_table!, source, target); + return TryGet(_table, source, target); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CompilerLoweringPreserveAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CompilerLoweringPreserveAttribute.cs new file mode 100644 index 00000000000000..98fc84544098dd --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CompilerLoweringPreserveAttribute.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class CompilerLoweringPreserveAttribute : Attribute + { + public CompilerLoweringPreserveAttribute() { } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ExtensionMarkerAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ExtensionMarkerAttribute.cs new file mode 100644 index 00000000000000..9b9242d92793b4 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ExtensionMarkerAttribute.cs @@ -0,0 +1,24 @@ +// 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.Runtime.CompilerServices +{ + /// + /// This attribute is used to mark extension members and associate them with a specific marker type (which provides detailed information about an extension block and its receiver parameter). + /// This attribute should not be used by developers in source code. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] + public sealed class ExtensionMarkerAttribute : Attribute + { + /// Initializes a new instance of the class. + /// The name of the marker type this extension member is associated with. + public ExtensionMarkerAttribute(string name) + => Name = name; + + /// The name of the marker type this extension member is associated with. + public string Name { get; } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/GenericCache.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/GenericCache.cs index 2b8bd8eea7a223..94d9ecdd73bf3f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/GenericCache.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/GenericCache.cs @@ -90,7 +90,7 @@ public GenericCache(int initialCacheSize, int maxCacheSize) // Initialize to the sentinel in DEBUG as if just flushed, to ensure the sentinel can be handled in Set. CreateCacheTable(initialCacheSize) ?? #endif - _sentinelTable!; + _sentinelTable; _lastFlushSize = initialCacheSize; } @@ -141,9 +141,8 @@ private static ref Entry Element(Entry[] table, int index) [MethodImpl(MethodImplOptions.AggressiveInlining)] internal bool TryGet(TKey key, out TValue? value) { - // table is always initialized and is not null. - Entry[] table = _table!; - int hash = key!.GetHashCode(); + Entry[] table = _table; + int hash = key.GetHashCode(); int index = HashToBucket(table, hash); for (int i = 0; i < BUCKET_SIZE;) { @@ -241,7 +240,7 @@ internal bool TryGet(TKey key, out TValue? value) internal void TrySet(TKey key, TValue value) { int bucket; - int hash = key!.GetHashCode(); + int hash = key.GetHashCode(); Entry[] table; do @@ -384,7 +383,7 @@ private void FlushCurrentCache() // with the writing of the table _lastFlushSize = lastSize; // flushing is just replacing the table with a sentinel. - _table = _sentinelTable!; + _table = _sentinelTable; } private bool MaybeReplaceCacheWithLarger(int size) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs index 6543046573bf3f..83e401940e4da1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs @@ -151,7 +151,15 @@ internal static bool CanPrimitiveWiden(CorElementType srcET, CorElementType dstE /// This method is intended for compiler use rather than use directly in code. T must be one of byte, sbyte, bool, char, short, ushort, int, uint, long, ulong, float, or double. [Intrinsic] public static ReadOnlySpan CreateSpan(RuntimeFieldHandle fldHandle) +#if NATIVEAOT + // We only support this intrinsic when it occurs within a well-defined IL sequence. + // If a call to this method occurs within the recognized sequence, codegen must expand the IL sequence completely. + // For any other purpose, the API is currently unsupported. + // We shortcut this here instead of in `GetSpanDataFrom` to avoid `typeof(T)` below marking T target of reflection. + => throw new PlatformNotSupportedException(); +#else => new ReadOnlySpan(ref Unsafe.As(ref GetSpanDataFrom(fldHandle, typeof(T).TypeHandle, out int length)), length); +#endif // The following intrinsics return true if input is a compile-time constant diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs index 3d97a654124205..0f8358c917fb49 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs @@ -404,6 +404,22 @@ public static bool IsAddressGreaterThan([AllowNull] ref readonly T left, [All // ret } + /// + /// Determines whether the memory address referenced by is greater than + /// or equal to the memory address referenced by . + /// + /// + /// This check is conceptually similar to "(void*)(&left) >= (void*)(&right)". + /// + [Intrinsic] + [NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsAddressGreaterThanOrEqualTo([AllowNull] ref readonly T left, [AllowNull] ref readonly T right) + where T : allows ref struct + { + return !IsAddressLessThan(in left, in right); + } + /// /// Determines whether the memory address referenced by is less than /// the memory address referenced by . @@ -428,6 +444,22 @@ public static bool IsAddressLessThan([AllowNull] ref readonly T left, [AllowN // ret } + /// + /// Determines whether the memory address referenced by is less than + /// or equal to the memory address referenced by . + /// + /// + /// This check is conceptually similar to "(void*)(&left) <= (void*)(&right)". + /// + [Intrinsic] + [NonVersionable] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsAddressLessThanOrEqualTo([AllowNull] ref readonly T left, [AllowNull] ref readonly T right) + where T : allows ref struct + { + return !IsAddressGreaterThan(in left, in right); + } + /// /// Initializes a block of memory at the given location with a given initial value. /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/ExceptionServices/ExceptionHandling.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/ExceptionServices/ExceptionHandling.cs index 116c94982f03d1..da598532381607 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/ExceptionServices/ExceptionHandling.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/ExceptionServices/ExceptionHandling.cs @@ -48,6 +48,10 @@ public static void SetUnhandledExceptionHandler(Func handler) /// event and then return. /// /// It will not raise the the handler registered with . + /// + /// This API is thread safe and can be called from multiple threads. However, only one thread + /// will trigger the event handlers, while other threads will wait indefinitely without raising + /// the event. /// public static void RaiseAppDomainUnhandledExceptionEvent(object exception) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CLong.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CLong.cs index 520d9e92b7d220..140e8cc1c319aa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CLong.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CLong.cs @@ -36,7 +36,7 @@ public CLong(int value) } /// - /// Constructs an instance from a native sized integer. + /// Constructs an instance from a native-sized integer. /// /// The integer value. /// is outside the range of the underlying storage type. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CULong.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CULong.cs index 13ee5a7e011023..2bb0ede6f72686 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CULong.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/CULong.cs @@ -36,7 +36,7 @@ public CULong(uint value) } /// - /// Constructs an instance from a native sized unsigned integer. + /// Constructs an instance from a native-sized unsigned integer. /// /// The integer value. /// is outside the range of the underlying storage type. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs index c607bbb05d5413..2945a99d9b8c44 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs +++ b/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); } } } @@ -778,7 +785,7 @@ public unsafe IntPtr GetOrCreateComInterfaceForObject(object instance, CreateCom ManagedObjectWrapperHolder managedObjectWrapper = _managedObjectWrapperTable.GetOrAdd(instance, static (c, state) => { - ManagedObjectWrapper* value = state.This!.CreateManagedObjectWrapper(c, state.flags); + ManagedObjectWrapper* value = state.This.CreateManagedObjectWrapper(c, state.flags); return new ManagedObjectWrapperHolder(value, c); }, new { This = this, flags }); @@ -1282,7 +1289,7 @@ private static void AddWrapperToReferenceTrackerHandleCache(NativeObjectWrapper private sealed class RcwCache { - private readonly Lock _lock = new Lock(useTrivialWaits: true); + private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); private readonly Dictionary _cache = []; /// @@ -1294,7 +1301,8 @@ private sealed class RcwCache /// The proxy object currently in the cache for or the proxy object owned by if no entry exists and the corresponding native wrapper. public (NativeObjectWrapper actualWrapper, object actualProxy) GetOrAddProxyForComInstance(IntPtr comPointer, NativeObjectWrapper wrapper, object comProxy) { - lock (_lock) + _lock.EnterWriteLock(); + try { Debug.Assert(wrapper.ProxyHandle.Target == comProxy); ref GCHandle rcwEntry = ref CollectionsMarshal.GetValueRefOrAddDefault(_cache, comPointer, out bool exists); @@ -1329,11 +1337,16 @@ private sealed class RcwCache // Return our target object. return (wrapper, comProxy); } + finally + { + _lock.ExitWriteLock(); + } } public object? FindProxyForComInstance(IntPtr comPointer) { - lock (_lock) + _lock.EnterReadLock(); + try { if (_cache.TryGetValue(comPointer, out GCHandle existingHandle)) { @@ -1350,11 +1363,16 @@ private sealed class RcwCache return null; } + finally + { + _lock.ExitReadLock(); + } } public void Remove(IntPtr comPointer, NativeObjectWrapper wrapper) { - lock (_lock) + _lock.EnterWriteLock(); + try { // TryGetOrCreateObjectForComInstanceInternal may have put a new entry into the cache // in the time between the GC cleared the contents of the GC handle but before the @@ -1369,6 +1387,10 @@ public void Remove(IntPtr comPointer, NativeObjectWrapper wrapper) cachedRef.Free(); } } + finally + { + _lock.ExitWriteLock(); + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Java/JavaMarshal.Unsupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Java/JavaMarshal.Unsupported.cs new file mode 100644 index 00000000000000..3914d81c2e6ab7 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Java/JavaMarshal.Unsupported.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; + +namespace System.Runtime.InteropServices.Java +{ + [CLSCompliant(false)] + [SupportedOSPlatform("android")] + public static partial class JavaMarshal + { + public static unsafe void Initialize(delegate* unmanaged markCrossReferences) + { + throw new PlatformNotSupportedException(); + } + + public static unsafe GCHandle CreateReferenceTrackingHandle(object obj, void* context) + { + throw new PlatformNotSupportedException(); + } + + public static unsafe void* GetContext(GCHandle obj) + { + throw new PlatformNotSupportedException(); + } + + public static unsafe void FinishCrossReferenceProcessing( + MarkCrossReferencesArgs* crossReferences, + ReadOnlySpan unreachableObjectHandles) + { + throw new PlatformNotSupportedException(); + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/LibraryImportAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/LibraryImportAttribute.cs index eaa95b7c260638..b5dd3804d58f34 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/LibraryImportAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/LibraryImportAttribute.cs @@ -18,9 +18,9 @@ namespace System.Runtime.InteropServices public #else #pragma warning disable CS0436 // Type conflicts with imported type - // Some assemblies that target downlevel have InternalsVisibleTo to their test assemblies. - // As this is only used in this repo and isn't a problem in shipping code, - // just disable the duplicate type warning. + // Some assemblies that target downlevel have InternalsVisibleTo to their test assemblies. + // As this is only used in this repo and isn't a problem in shipping code, + // just disable the duplicate type warning. internal #endif sealed class LibraryImportAttribute : Attribute diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Unix.cs index 7b206a00fce36d..64c541af07e992 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Unix.cs @@ -56,9 +56,9 @@ internal static unsafe void GetAnsiStringBytes(ReadOnlySpan chars, Span AllocHGlobal((nint)(uint)cb); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Windows.cs index 0781e40d4c6b55..6c9ef5c9f0bd1f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Windows.cs @@ -144,7 +144,7 @@ public static unsafe void FreeHGlobal(IntPtr hglobal) } } - public static unsafe IntPtr ReAllocHGlobal(IntPtr pv, IntPtr cb) + public static unsafe IntPtr ReAllocHGlobal(IntPtr pv, nint cb) { if (pv == IntPtr.Zero) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs index a2b30029b0216f..be6e089fc7b9bb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs @@ -351,7 +351,7 @@ public static unsafe int ReadInt32(IntPtr ptr, int ofs) [RequiresDynamicCode("Marshalling code for the object might not be available")] [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("ReadIntPtr(Object, Int32) may be unavailable in future releases.")] - public static IntPtr ReadIntPtr(object ptr, int ofs) + public static nint ReadIntPtr(object ptr, int ofs) { #if TARGET_64BIT return (nint)ReadInt64(ptr, ofs); @@ -360,7 +360,7 @@ public static IntPtr ReadIntPtr(object ptr, int ofs) #endif } - public static IntPtr ReadIntPtr(IntPtr ptr, int ofs) + public static nint ReadIntPtr(IntPtr ptr, int ofs) { #if TARGET_64BIT return (nint)ReadInt64(ptr, ofs); @@ -369,7 +369,7 @@ public static IntPtr ReadIntPtr(IntPtr ptr, int ofs) #endif } - public static IntPtr ReadIntPtr(IntPtr ptr) => ReadIntPtr(ptr, 0); + public static nint ReadIntPtr(IntPtr ptr) => ReadIntPtr(ptr, 0); public static unsafe long ReadInt64(IntPtr ptr, int ofs) { @@ -468,32 +468,28 @@ public static unsafe void WriteInt32(IntPtr ptr, int ofs, int val) public static void WriteInt32(IntPtr ptr, int val) => WriteInt32(ptr, 0, val); - public static void WriteIntPtr(IntPtr ptr, int ofs, IntPtr val) + public static void WriteIntPtr(IntPtr ptr, int ofs, nint val) { #if TARGET_64BIT WriteInt64(ptr, ofs, (long)val); #else // 32 -#pragma warning disable CA2020 // Prevent from behavioral change WriteInt32(ptr, ofs, (int)val); -#pragma warning restore CA2020 #endif } [RequiresDynamicCode("Marshalling code for the object might not be available")] [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("WriteIntPtr(Object, Int32, IntPtr) may be unavailable in future releases.")] - public static void WriteIntPtr(object ptr, int ofs, IntPtr val) + public static void WriteIntPtr(object ptr, int ofs, nint val) { #if TARGET_64BIT WriteInt64(ptr, ofs, (long)val); #else // 32 -#pragma warning disable CA2020 // Prevent from behavioral change WriteInt32(ptr, ofs, (int)val); -#pragma warning restore CA2020 #endif } - public static void WriteIntPtr(IntPtr ptr, IntPtr val) => WriteIntPtr(ptr, 0, val); + public static void WriteIntPtr(IntPtr ptr, nint val) => WriteIntPtr(ptr, 0, val); public static unsafe void WriteInt64(IntPtr ptr, int ofs, long val) { @@ -653,6 +649,63 @@ public static IntPtr GetHINSTANCE(Module m) return GetExceptionForHRInternal(errorCode, errorInfo); } + public static Exception? GetExceptionForHR(int errorCode, in Guid iid, IntPtr pUnk) + { + if (errorCode >= 0) + { + return null; + } + + return GetExceptionForHRInternal(errorCode, in iid, pUnk); + } + + private static unsafe Exception? GetExceptionForHRInternal(int errorCode, in Guid iid, IntPtr pUnk) + { + const IntPtr NoErrorInfo = -1; // Use -1 to indicate no error info available + + // Normally, we would check if the interface supports IErrorInfo first. However, + // built-in COM calls GetErrorInfo first to clear the error info, so we follow + // that pattern here. + IntPtr errorInfo = NoErrorInfo; + +#if TARGET_WINDOWS + Interop.OleAut32.GetErrorInfo(0, out errorInfo); + if (errorInfo == IntPtr.Zero) + { + errorInfo = NoErrorInfo; + } + + // If there is error info and we have a pointer to the interface, + // we check if it supports ISupportErrorInfo. + if (errorInfo != NoErrorInfo && pUnk != IntPtr.Zero) + { + Guid IID_ISupportErrorInfo = new(0xDF0B3D60, 0x548F, 0x101B, 0x8E, 0x65, 0x08, 0x00, 0x2B, 0x2B, 0xD1, 0x19); + int hr = QueryInterface(pUnk, in IID_ISupportErrorInfo, out IntPtr supportErrorInfo); + if (hr == 0) + { + // Check if the target interface is supported. + // ISupportErrorInfo.InterfaceSupportsErrorInfo slot + fixed (Guid* piid = &iid) + { + hr = ((delegate* unmanaged[MemberFunction])(*(*(void***)supportErrorInfo + 3)))(supportErrorInfo, piid); + } + Release(supportErrorInfo); + } + + // If ISupportErrorInfo isn't supported or the target interface doesn't support IErrorInfo, + // release the error info and mark it as NoErrorInfo to avoid querying for IErrorInfo again. + if (hr != 0) + { + Release(errorInfo); + errorInfo = NoErrorInfo; + } + } +#endif + + // If the error info is valid, its lifetime will be handled by GetExceptionForHRInternal(). + return GetExceptionForHRInternal(errorCode, errorInfo); + } + #if !CORECLR #pragma warning disable IDE0060 private static Exception? GetExceptionForHRInternal(int errorCode, IntPtr errorInfo) @@ -865,6 +918,14 @@ public static void ThrowExceptionForHR(int errorCode, IntPtr errorInfo) } } + public static void ThrowExceptionForHR(int errorCode, in Guid iid, IntPtr pUnk) + { + if (errorCode < 0) + { + throw GetExceptionForHR(errorCode, in iid, pUnk)!; + } + } + public static IntPtr SecureStringToBSTR(SecureString s) { if (s is null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ArrayMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ArrayMarshaller.cs index dc24c7918e90e1..54fbcbc210a0e4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ArrayMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ArrayMarshaller.cs @@ -58,7 +58,12 @@ public static ReadOnlySpan GetManagedValuesSource(T[]? managed) /// The unmanaged element count. /// The of unmanaged elements. public static Span GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements) - => new Span(unmanaged, numElements); + { + if (unmanaged is null) + return []; + + return new Span(unmanaged, numElements); + } /// /// Allocates memory for the managed representation of the array. @@ -89,7 +94,12 @@ public static Span GetManagedValuesDestination(T[]? managed) /// The unmanaged element count. /// The containing the unmanaged elements to marshal. public static ReadOnlySpan GetUnmanagedValuesSource(TUnmanagedElement* unmanagedValue, int numElements) - => new ReadOnlySpan(unmanagedValue, numElements); + { + if (unmanagedValue is null) + return []; + + return new ReadOnlySpan(unmanagedValue, numElements); + } /// /// Frees memory for the unmanaged array. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/PointerArrayMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/PointerArrayMarshaller.cs index 846879583d5ac4..d0a3dfae3e8db4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/PointerArrayMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/PointerArrayMarshaller.cs @@ -59,7 +59,12 @@ public static ReadOnlySpan GetManagedValuesSource(T*[]? managed) /// The unmanaged element count. /// The of unmanaged elements. public static Span GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements) - => new Span(unmanaged, numElements); + { + if (unmanaged is null) + return []; + + return new Span(unmanaged, numElements); + } /// /// Allocates memory for the managed representation of the array. @@ -90,7 +95,12 @@ public static Span GetManagedValuesDestination(T*[]? managed) /// The unmanaged element count. /// The containing the unmanaged elements to marshal. public static ReadOnlySpan GetUnmanagedValuesSource(TUnmanagedElement* unmanagedValue, int numElements) - => new ReadOnlySpan(unmanagedValue, numElements); + { + if (unmanagedValue is null) + return []; + + return new ReadOnlySpan(unmanagedValue, numElements); + } /// /// Frees memory for the unmanaged array. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ReadOnlySpanMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ReadOnlySpanMarshaller.cs index a3ee3ca7a960f2..6e9bd465da0abc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ReadOnlySpanMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ReadOnlySpanMarshaller.cs @@ -69,7 +69,12 @@ public static ReadOnlySpan GetManagedValuesSource(ReadOnlySpan managed) /// The number of elements that will be copied into the memory block. /// A span over the unmanaged memory that can contain the specified number of elements. public static Span GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements) - => new Span(unmanaged, numElements); + { + if (unmanaged == null) + return []; + + return new Span(unmanaged, numElements); + } } /// @@ -201,6 +206,9 @@ public ReadOnlySpan ToManaged() /// A span over unmanaged values of the array. public ReadOnlySpan GetUnmanagedValuesSource(int numElements) { + if (_unmanagedArray is null) + return []; + return new ReadOnlySpan(_unmanagedArray, numElements); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SafeHandleMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SafeHandleMarshaller.cs index 0e392d1535fd86..49a0e130561f74 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SafeHandleMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SafeHandleMarshaller.cs @@ -73,7 +73,7 @@ public ManagedToUnmanagedRef() // but it has never required them to be public. // We construct the handle now to ensure we don't cause an exception // before we are able to capture the unmanaged handle after the call. - _newHandle = Activator.CreateInstance()!; + _newHandle = Activator.CreateInstance(); } /// @@ -162,7 +162,7 @@ public ManagedToUnmanagedOut() // but it has never required them to be public. // We construct the handle now to ensure we don't cause an exception // before we are able to capture the unmanaged handle after the call. - _newHandle = Activator.CreateInstance()!; + _newHandle = Activator.CreateInstance(); } /// @@ -191,7 +191,7 @@ public void Free() // unnecessarily. if (!_initialized) { - _newHandle!.Dispose(); + _newHandle.Dispose(); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SpanMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SpanMarshaller.cs index dc9a22a8fb675a..2ff52a27e373cf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SpanMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SpanMarshaller.cs @@ -63,7 +63,12 @@ public static ReadOnlySpan GetManagedValuesSource(Span managed) /// The number of elements that will be copied into the memory block. /// A span over the unmanaged memory that can contain the specified number of elements. public static Span GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements) - => new Span(unmanaged, numElements); + { + if (unmanaged == null) + return []; + + return new Span(unmanaged, numElements); + } /// /// Allocates space to store the managed elements. @@ -94,7 +99,12 @@ public static Span GetManagedValuesDestination(Span managed) /// The number of elements in the unmanaged collection. /// A span over the native collection elements. public static ReadOnlySpan GetUnmanagedValuesSource(TUnmanagedElement* unmanaged, int numElements) - => new ReadOnlySpan(unmanaged, numElements); + { + if (unmanaged == null) + return []; + + return new ReadOnlySpan(unmanaged, numElements); + } /// /// Frees the allocated unmanaged memory. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.Unix.cs index 58e778f1c19585..6ac48537ad816f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.Unix.cs @@ -7,10 +7,9 @@ namespace System.Runtime.InteropServices { public static partial class RuntimeInformation { - private static string? s_osDescription; private static volatile int s_osArchPlusOne; - public static string OSDescription => s_osDescription ??= + public static string OSDescription => field ??= #if TARGET_ANDROID $"Android (API level {Environment.OSVersion.Version.Major})"; #elif TARGET_OSX diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/StandardOleMarshalObject.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/StandardOleMarshalObject.Windows.cs index 9dbd739fd6fd3f..40bae7bc9259bc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/StandardOleMarshalObject.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/StandardOleMarshalObject.Windows.cs @@ -5,6 +5,7 @@ namespace System.Runtime.InteropServices { + [ComVisible(true)] public class StandardOleMarshalObject : MarshalByRefObject, IMarshal { private static readonly Guid CLSID_StdMarshal = new Guid("00000017-0000-0000-c000-000000000046"); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs index ae6363f0f40979..f37e70545e9dcf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs @@ -5701,7 +5701,7 @@ internal Arm64() { } /// svint16_t svldnf1ub_s16(svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.H, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToInt16(byte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToInt16(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } // Load 8-bit data and zero-extend, non-faulting @@ -5710,7 +5710,7 @@ internal Arm64() { } /// svint32_t svldnf1ub_s32(svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToInt32(byte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToInt32(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } // Load 8-bit data and zero-extend, non-faulting @@ -5719,7 +5719,7 @@ internal Arm64() { } /// svint64_t svldnf1ub_s64(svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToInt64(byte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToInt64(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } // Load 8-bit data and zero-extend, non-faulting @@ -5728,7 +5728,7 @@ internal Arm64() { } /// svuint16_t svldnf1ub_u16(svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.H, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToUInt16(byte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToUInt16(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } // Load 8-bit data and zero-extend, non-faulting @@ -5737,7 +5737,7 @@ internal Arm64() { } /// svuint32_t svldnf1ub_u32(svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToUInt32(byte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToUInt32(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } // Load 8-bit data and zero-extend, non-faulting @@ -5746,7 +5746,7 @@ internal Arm64() { } /// svuint64_t svldnf1ub_u64(svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToUInt64(byte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToUInt64(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } /// @@ -5909,7 +5909,7 @@ internal Arm64() { } /// svint32_t svldnf1sh_s32(svbool_t pg, const int16_t *base) /// LDNF1SH Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToInt32(short* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToInt32(Vector mask, short* address) { throw new PlatformNotSupportedException(); } // Load 16-bit data and sign-extend, non-faulting @@ -5918,7 +5918,7 @@ internal Arm64() { } /// svint64_t svldnf1sh_s64(svbool_t pg, const int16_t *base) /// LDNF1SH Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToInt64(short* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToInt64(Vector mask, short* address) { throw new PlatformNotSupportedException(); } // Load 16-bit data and sign-extend, non-faulting @@ -5927,7 +5927,7 @@ internal Arm64() { } /// svuint32_t svldnf1sh_u32(svbool_t pg, const int16_t *base) /// LDNF1SH Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToUInt32(short* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToUInt32(Vector mask, short* address) { throw new PlatformNotSupportedException(); } // Load 16-bit data and sign-extend, non-faulting @@ -5936,7 +5936,7 @@ internal Arm64() { } /// svuint64_t svldnf1sh_u64(svbool_t pg, const int16_t *base) /// LDNF1SH Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToUInt64(short* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToUInt64(Vector mask, short* address) { throw new PlatformNotSupportedException(); } // Load 16-bit data and sign-extend, first-faulting @@ -6008,7 +6008,7 @@ internal Arm64() { } /// svint64_t svldnf1sw_s64(svbool_t pg, const int32_t *base) /// LDNF1SW Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorInt32NonFaultingSignExtendToInt64(int* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorInt32NonFaultingSignExtendToInt64(Vector mask, int* address) { throw new PlatformNotSupportedException(); } // Load 32-bit data and sign-extend, non-faulting @@ -6017,7 +6017,7 @@ internal Arm64() { } /// svuint64_t svldnf1sw_u64(svbool_t pg, const int32_t *base) /// LDNF1SW Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorInt32NonFaultingSignExtendToUInt64(int* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorInt32NonFaultingSignExtendToUInt64(Vector mask, int* address) { throw new PlatformNotSupportedException(); } // Load 32-bit data and sign-extend, first-faulting @@ -6059,61 +6059,61 @@ internal Arm64() { } /// svuint8_t svldnf1[_u8](svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(byte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorNonFaulting(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } /// /// svfloat64_t svldnf1[_f64](svbool_t pg, const float64_t *base) /// LDNF1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(double* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorNonFaulting(Vector mask, double* address) { throw new PlatformNotSupportedException(); } /// /// svint16_t svldnf1[_s16](svbool_t pg, const int16_t *base) /// LDNF1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(short* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorNonFaulting(Vector mask, short* address) { throw new PlatformNotSupportedException(); } /// /// svint32_t svldnf1[_s32](svbool_t pg, const int32_t *base) /// LDNF1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(int* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorNonFaulting(Vector mask, int* address) { throw new PlatformNotSupportedException(); } /// /// svint64_t svldnf1[_s64](svbool_t pg, const int64_t *base) /// LDNF1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(long* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorNonFaulting(Vector mask, long* address) { throw new PlatformNotSupportedException(); } /// /// svint8_t svldnf1[_s8](svbool_t pg, const int8_t *base) /// LDNF1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(sbyte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorNonFaulting(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } /// /// svfloat32_t svldnf1[_f32](svbool_t pg, const float32_t *base) /// LDNF1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(float* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorNonFaulting(Vector mask, float* address) { throw new PlatformNotSupportedException(); } /// /// svuint16_t svldnf1[_u16](svbool_t pg, const uint16_t *base) /// LDNF1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(ushort* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorNonFaulting(Vector mask, ushort* address) { throw new PlatformNotSupportedException(); } /// /// svuint32_t svldnf1[_u32](svbool_t pg, const uint32_t *base) /// LDNF1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(uint* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorNonFaulting(Vector mask, uint* address) { throw new PlatformNotSupportedException(); } /// /// svuint64_t svldnf1[_u64](svbool_t pg, const uint64_t *base) /// LDNF1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(ulong* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorNonFaulting(Vector mask, ulong* address) { throw new PlatformNotSupportedException(); } // Unextended load, non-temporal @@ -6185,7 +6185,7 @@ internal Arm64() { } /// svint16_t svldnf1sb_s16(svbool_t pg, const int8_t *base) /// LDNF1SB Zresult.H, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToInt16(sbyte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToInt16(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } // Load 8-bit data and sign-extend, non-faulting @@ -6194,7 +6194,7 @@ internal Arm64() { } /// svint32_t svldnf1sb_s32(svbool_t pg, const int8_t *base) /// LDNF1SB Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToInt32(sbyte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToInt32(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } // Load 8-bit data and sign-extend, non-faulting @@ -6203,7 +6203,7 @@ internal Arm64() { } /// svint64_t svldnf1sb_s64(svbool_t pg, const int8_t *base) /// LDNF1SB Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToInt64(sbyte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToInt64(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } // Load 8-bit data and sign-extend, non-faulting @@ -6212,7 +6212,7 @@ internal Arm64() { } /// svuint16_t svldnf1sb_u16(svbool_t pg, const int8_t *base) /// LDNF1SB Zresult.H, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToUInt16(sbyte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToUInt16(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } // Load 8-bit data and sign-extend, non-faulting @@ -6221,7 +6221,7 @@ internal Arm64() { } /// svuint32_t svldnf1sb_u32(svbool_t pg, const int8_t *base) /// LDNF1SB Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToUInt32(sbyte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToUInt32(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } // Load 8-bit data and sign-extend, non-faulting @@ -6230,7 +6230,7 @@ internal Arm64() { } /// svuint64_t svldnf1sb_u64(svbool_t pg, const int8_t *base) /// LDNF1SB Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToUInt64(sbyte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToUInt64(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } // Load 8-bit data and sign-extend, first-faulting @@ -6332,7 +6332,7 @@ internal Arm64() { } /// svint32_t svldnf1uh_s32(svbool_t pg, const uint16_t *base) /// LDNF1H Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToInt32(ushort* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToInt32(Vector mask, ushort* address) { throw new PlatformNotSupportedException(); } // Load 16-bit data and zero-extend, non-faulting @@ -6341,7 +6341,7 @@ internal Arm64() { } /// svint64_t svldnf1uh_s64(svbool_t pg, const uint16_t *base) /// LDNF1H Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToInt64(ushort* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToInt64(Vector mask, ushort* address) { throw new PlatformNotSupportedException(); } // Load 16-bit data and zero-extend, non-faulting @@ -6350,7 +6350,7 @@ internal Arm64() { } /// svuint32_t svldnf1uh_u32(svbool_t pg, const uint16_t *base) /// LDNF1H Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToUInt32(ushort* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToUInt32(Vector mask, ushort* address) { throw new PlatformNotSupportedException(); } // Load 16-bit data and zero-extend, non-faulting @@ -6359,7 +6359,7 @@ internal Arm64() { } /// svuint64_t svldnf1uh_u64(svbool_t pg, const uint16_t *base) /// LDNF1H Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToUInt64(ushort* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToUInt64(Vector mask, ushort* address) { throw new PlatformNotSupportedException(); } // Load 16-bit data and zero-extend, first-faulting @@ -6431,7 +6431,7 @@ internal Arm64() { } /// svint64_t svldnf1uw_s64(svbool_t pg, const uint32_t *base) /// LDNF1W Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorUInt32NonFaultingZeroExtendToInt64(uint* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorUInt32NonFaultingZeroExtendToInt64(Vector mask, uint* address) { throw new PlatformNotSupportedException(); } // Load 32-bit data and zero-extend, non-faulting @@ -6440,7 +6440,7 @@ internal Arm64() { } /// svuint64_t svldnf1uw_u64(svbool_t pg, const uint32_t *base) /// LDNF1W Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorUInt32NonFaultingZeroExtendToUInt64(uint* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector LoadVectorUInt32NonFaultingZeroExtendToUInt64(Vector mask, uint* address) { throw new PlatformNotSupportedException(); } // Load 32-bit data and zero-extend, first-faulting @@ -8831,6 +8831,54 @@ internal Arm64() { } /// public static void Scatter16BitNarrowing(Vector mask, Vector addresses, Vector data) { throw new PlatformNotSupportedException(); } + /// + /// void svst1h_scatter_[s32]index[_s32](svbool_t pg, int16_t *base, svint32_t indices, svint32_t data) + /// ST1H Zdata.S, Pg, [Xbase, Zindices.S, SXTW #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, short* address, Vector indices, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1h_scatter_[u32]index[_s32](svbool_t pg, int16_t *base, svuint32_t indices, svint32_t data) + /// ST1H Zdata.S, Pg, [Xbase, Zindices.S, UXTW #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, short* address, Vector indices, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1h_scatter_[s64]index[_s64](svbool_t pg, int16_t *base, svint64_t indices, svint64_t data) + /// ST1H Zdata.D, Pg, [Xbase, Zindices.D, LSL #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, short* address, Vector indices, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1h_scatter_[u64]index[_s64](svbool_t pg, int16_t *base, svuint64_t indices, svint64_t data) + /// ST1H Zdata.D, Pg, [Xbase, Zindices.D, LSL #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, short* address, Vector indices, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1h_scatter_[s32]index[_u32](svbool_t pg, uint16_t *base, svint32_t indices, svuint32_t data) + /// ST1H Zdata.S, Pg, [Xbase, Zindices.S, SXTW #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, ushort* address, Vector indices, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1h_scatter_[u32]index[_u32](svbool_t pg, uint16_t *base, svuint32_t indices, svuint32_t data) + /// ST1H Zdata.S, Pg, [Xbase, Zindices.S, UXTW #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, ushort* address, Vector indices, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1h_scatter_[s64]index[_u64](svbool_t pg, uint16_t *base, svint64_t indices, svuint64_t data) + /// ST1H Zdata.D, Pg, [Xbase, Zindices.D, LSL #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, ushort* address, Vector indices, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1h_scatter_[u64]index[_u64](svbool_t pg, uint16_t *base, svuint64_t indices, svuint64_t data) + /// ST1H Zdata.D, Pg, [Xbase, Zindices.D, LSL #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, ushort* address, Vector indices, Vector data) { throw new PlatformNotSupportedException(); } + // Truncate to 16 bits and store @@ -8897,6 +8945,30 @@ internal Arm64() { } /// public static void Scatter32BitNarrowing(Vector mask, Vector addresses, Vector data) { throw new PlatformNotSupportedException(); } + /// + /// void svst1w_scatter_[s64]index[_s64](svbool_t pg, int32_t *base, svint64_t indices, svint64_t data) + /// ST1W Zdata.D, Pg, [Xbase, Zindices.D, LSL #2] + /// + public static unsafe void Scatter32BitNarrowing(Vector mask, int* address, Vector indices, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1w_scatter_[u64]index[_s64](svbool_t pg, int32_t *base, svuint64_t indices, svint64_t data) + /// ST1W Zdata.D, Pg, [Xbase, Zindices.D, LSL #2] + /// + public static unsafe void Scatter32BitNarrowing(Vector mask, int* address, Vector indices, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1w_scatter_[s64]index[_u64](svbool_t pg, uint32_t *base, svint64_t indices, svuint64_t data) + /// ST1W Zdata.D, Pg, [Xbase, Zindices.D, LSL #2] + /// + public static unsafe void Scatter32BitNarrowing(Vector mask, uint* address, Vector indices, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1w_scatter_[u64]index[_u64](svbool_t pg, uint32_t *base, svuint64_t indices, svuint64_t data) + /// ST1W Zdata.D, Pg, [Xbase, Zindices.D, LSL #2] + /// + public static unsafe void Scatter32BitNarrowing(Vector mask, uint* address, Vector indices, Vector data) { throw new PlatformNotSupportedException(); } + // Truncate to 32 bits and store @@ -9005,6 +9077,81 @@ internal Arm64() { } public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, byte* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + // Non-truncating store + + /// + /// void svst1_scatter_[s64]offset[_f64](svbool_t pg, float64_t *base, svint64_t offsets, svfloat64_t data) + /// ST1D Zdata.D, Pg, [Xbase, Zoffsets.D] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, double* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1_scatter_[u64]offset[_f64](svbool_t pg, float64_t *base, svuint64_t offsets, svfloat64_t data) + /// ST1D Zdata.D, Pg, [Xbase, Zoffsets.D] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, double* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1_scatter_[s32]offset[_s32](svbool_t pg, int32_t *base, svint32_t offsets, svint32_t data) + /// ST1W Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, int* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1_scatter_[u32]offset[_s32](svbool_t pg, int32_t *base, svuint32_t offsets, svint32_t data) + /// ST1W Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, int* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1_scatter_[s64]offset[_s64](svbool_t pg, int64_t *base, svint64_t offsets, svint64_t data) + /// ST1D Zdata.D, Pg, [Xbase, Zoffsets.D] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, long* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1_scatter_[u64]offset[_s64](svbool_t pg, int64_t *base, svuint64_t offsets, svint64_t data) + /// ST1D Zdata.D, Pg, [Xbase, Zoffsets.D] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, long* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1_scatter_[s32]offset[_f32](svbool_t pg, float32_t *base, svint32_t offsets, svfloat32_t data) + /// ST1W Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, float* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1_scatter_[u32]offset[_f32](svbool_t pg, float32_t *base, svuint32_t offsets, svfloat32_t data) + /// ST1W Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, float* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1_scatter_[s32]offset[_u32](svbool_t pg, uint32_t *base, svint32_t offsets, svuint32_t data) + /// ST1W Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, uint* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1_scatter_[u32]offset[_u32](svbool_t pg, uint32_t *base, svuint32_t offsets, svuint32_t data) + /// ST1W Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, uint* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1_scatter_[s64]offset[_u64](svbool_t pg, uint64_t *base, svint64_t offsets, svuint64_t data) + /// ST1D Zdata.D, Pg, [Xbase, Zoffsets.D] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, ulong* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + /// + /// void svst1_scatter_[u64]offset[_u64](svbool_t pg, uint64_t *base, svuint64_t offsets, svuint64_t data) + /// ST1D Zdata.D, Pg, [Xbase, Zoffsets.D] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, ulong* address, Vector offsets, Vector data) { throw new PlatformNotSupportedException(); } + + // Write to the first-fault register /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs index 25f5aed8441596..bd5069e9366bdf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs @@ -5698,7 +5698,7 @@ internal Arm64() { } /// svint16_t svldnf1ub_s16(svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.H, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToInt16(byte* address) => LoadVectorByteNonFaultingZeroExtendToInt16(address); + public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToInt16(Vector mask, byte* address) => LoadVectorByteNonFaultingZeroExtendToInt16(mask, address); // Load 8-bit data and zero-extend, non-faulting @@ -5707,7 +5707,7 @@ internal Arm64() { } /// svint32_t svldnf1ub_s32(svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToInt32(byte* address) => LoadVectorByteNonFaultingZeroExtendToInt32(address); + public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToInt32(Vector mask, byte* address) => LoadVectorByteNonFaultingZeroExtendToInt32(mask, address); // Load 8-bit data and zero-extend, non-faulting @@ -5716,7 +5716,7 @@ internal Arm64() { } /// svint64_t svldnf1ub_s64(svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToInt64(byte* address) => LoadVectorByteNonFaultingZeroExtendToInt64(address); + public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToInt64(Vector mask, byte* address) => LoadVectorByteNonFaultingZeroExtendToInt64(mask, address); // Load 8-bit data and zero-extend, non-faulting @@ -5725,7 +5725,7 @@ internal Arm64() { } /// svuint16_t svldnf1ub_u16(svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.H, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToUInt16(byte* address) => LoadVectorByteNonFaultingZeroExtendToUInt16(address); + public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToUInt16(Vector mask, byte* address) => LoadVectorByteNonFaultingZeroExtendToUInt16(mask, address); // Load 8-bit data and zero-extend, non-faulting @@ -5734,7 +5734,7 @@ internal Arm64() { } /// svuint32_t svldnf1ub_u32(svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToUInt32(byte* address) => LoadVectorByteNonFaultingZeroExtendToUInt32(address); + public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToUInt32(Vector mask, byte* address) => LoadVectorByteNonFaultingZeroExtendToUInt32(mask, address); // Load 8-bit data and zero-extend, non-faulting @@ -5743,7 +5743,7 @@ internal Arm64() { } /// svuint64_t svldnf1ub_u64(svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToUInt64(byte* address) => LoadVectorByteNonFaultingZeroExtendToUInt64(address); + public static unsafe Vector LoadVectorByteNonFaultingZeroExtendToUInt64(Vector mask, byte* address) => LoadVectorByteNonFaultingZeroExtendToUInt64(mask, address); /// @@ -5904,7 +5904,7 @@ internal Arm64() { } /// svint32_t svldnf1sh_s32(svbool_t pg, const int16_t *base) /// LDNF1SH Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToInt32(short* address) => LoadVectorInt16NonFaultingSignExtendToInt32(address); + public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToInt32(Vector mask, short* address) => LoadVectorInt16NonFaultingSignExtendToInt32(mask, address); // Load 16-bit data and sign-extend, non-faulting @@ -5913,7 +5913,7 @@ internal Arm64() { } /// svint64_t svldnf1sh_s64(svbool_t pg, const int16_t *base) /// LDNF1SH Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToInt64(short* address) => LoadVectorInt16NonFaultingSignExtendToInt64(address); + public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToInt64(Vector mask, short* address) => LoadVectorInt16NonFaultingSignExtendToInt64(mask, address); // Load 16-bit data and sign-extend, non-faulting @@ -5922,7 +5922,7 @@ internal Arm64() { } /// svuint32_t svldnf1sh_u32(svbool_t pg, const int16_t *base) /// LDNF1SH Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToUInt32(short* address) => LoadVectorInt16NonFaultingSignExtendToUInt32(address); + public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToUInt32(Vector mask, short* address) => LoadVectorInt16NonFaultingSignExtendToUInt32(mask, address); // Load 16-bit data and sign-extend, non-faulting @@ -5931,7 +5931,7 @@ internal Arm64() { } /// svuint64_t svldnf1sh_u64(svbool_t pg, const int16_t *base) /// LDNF1SH Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToUInt64(short* address) => LoadVectorInt16NonFaultingSignExtendToUInt64(address); + public static unsafe Vector LoadVectorInt16NonFaultingSignExtendToUInt64(Vector mask, short* address) => LoadVectorInt16NonFaultingSignExtendToUInt64(mask, address); /// Load 16-bit data and sign-extend, first-faulting @@ -6003,7 +6003,7 @@ internal Arm64() { } /// svint64_t svldnf1sw_s64(svbool_t pg, const int32_t *base) /// LDNF1SW Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorInt32NonFaultingSignExtendToInt64(int* address) => LoadVectorInt32NonFaultingSignExtendToInt64(address); + public static unsafe Vector LoadVectorInt32NonFaultingSignExtendToInt64(Vector mask, int* address) => LoadVectorInt32NonFaultingSignExtendToInt64(mask, address); // Load 32-bit data and sign-extend, non-faulting @@ -6012,7 +6012,7 @@ internal Arm64() { } /// svuint64_t svldnf1sw_u64(svbool_t pg, const int32_t *base) /// LDNF1SW Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorInt32NonFaultingSignExtendToUInt64(int* address) => LoadVectorInt32NonFaultingSignExtendToUInt64(address); + public static unsafe Vector LoadVectorInt32NonFaultingSignExtendToUInt64(Vector mask, int* address) => LoadVectorInt32NonFaultingSignExtendToUInt64(mask, address); /// Load 32-bit data and sign-extend, first-faulting @@ -6054,61 +6054,61 @@ internal Arm64() { } /// svuint8_t svldnf1[_u8](svbool_t pg, const uint8_t *base) /// LDNF1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(byte* address) => LoadVectorNonFaulting(address); + public static unsafe Vector LoadVectorNonFaulting(Vector mask, byte* address) => LoadVectorNonFaulting(mask, address); /// /// svfloat64_t svldnf1[_f64](svbool_t pg, const float64_t *base) /// LDNF1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(double* address) => LoadVectorNonFaulting(address); + public static unsafe Vector LoadVectorNonFaulting(Vector mask, double* address) => LoadVectorNonFaulting(mask, address); /// /// svint16_t svldnf1[_s16](svbool_t pg, const int16_t *base) /// LDNF1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(short* address) => LoadVectorNonFaulting(address); + public static unsafe Vector LoadVectorNonFaulting(Vector mask, short* address) => LoadVectorNonFaulting(mask, address); /// /// svint32_t svldnf1[_s32](svbool_t pg, const int32_t *base) /// LDNF1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(int* address) => LoadVectorNonFaulting(address); + public static unsafe Vector LoadVectorNonFaulting(Vector mask, int* address) => LoadVectorNonFaulting(mask, address); /// /// svint64_t svldnf1[_s64](svbool_t pg, const int64_t *base) /// LDNF1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(long* address) => LoadVectorNonFaulting(address); + public static unsafe Vector LoadVectorNonFaulting(Vector mask, long* address) => LoadVectorNonFaulting(mask, address); /// /// svint8_t svldnf1[_s8](svbool_t pg, const int8_t *base) /// LDNF1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(sbyte* address) => LoadVectorNonFaulting(address); + public static unsafe Vector LoadVectorNonFaulting(Vector mask, sbyte* address) => LoadVectorNonFaulting(mask, address); /// /// svfloat32_t svldnf1[_f32](svbool_t pg, const float32_t *base) /// LDNF1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(float* address) => LoadVectorNonFaulting(address); + public static unsafe Vector LoadVectorNonFaulting(Vector mask, float* address) => LoadVectorNonFaulting(mask, address); /// /// svuint16_t svldnf1[_u16](svbool_t pg, const uint16_t *base) /// LDNF1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(ushort* address) => LoadVectorNonFaulting(address); + public static unsafe Vector LoadVectorNonFaulting(Vector mask, ushort* address) => LoadVectorNonFaulting(mask, address); /// /// svuint32_t svldnf1[_u32](svbool_t pg, const uint32_t *base) /// LDNF1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(uint* address) => LoadVectorNonFaulting(address); + public static unsafe Vector LoadVectorNonFaulting(Vector mask, uint* address) => LoadVectorNonFaulting(mask, address); /// /// svuint64_t svldnf1[_u64](svbool_t pg, const uint64_t *base) /// LDNF1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorNonFaulting(ulong* address) => LoadVectorNonFaulting(address); + public static unsafe Vector LoadVectorNonFaulting(Vector mask, ulong* address) => LoadVectorNonFaulting(mask, address); // Unextended load, non-temporal @@ -6180,7 +6180,7 @@ internal Arm64() { } /// svint16_t svldnf1sb_s16(svbool_t pg, const int8_t *base) /// LDNF1SB Zresult.H, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToInt16(sbyte* address) => LoadVectorSByteNonFaultingSignExtendToInt16(address); + public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToInt16(Vector mask, sbyte* address) => LoadVectorSByteNonFaultingSignExtendToInt16(mask, address); // Load 8-bit data and sign-extend, non-faulting @@ -6189,7 +6189,7 @@ internal Arm64() { } /// svint32_t svldnf1sb_s32(svbool_t pg, const int8_t *base) /// LDNF1SB Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToInt32(sbyte* address) => LoadVectorSByteNonFaultingSignExtendToInt32(address); + public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToInt32(Vector mask, sbyte* address) => LoadVectorSByteNonFaultingSignExtendToInt32(mask, address); // Load 8-bit data and sign-extend, non-faulting @@ -6198,7 +6198,7 @@ internal Arm64() { } /// svint64_t svldnf1sb_s64(svbool_t pg, const int8_t *base) /// LDNF1SB Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToInt64(sbyte* address) => LoadVectorSByteNonFaultingSignExtendToInt64(address); + public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToInt64(Vector mask, sbyte* address) => LoadVectorSByteNonFaultingSignExtendToInt64(mask, address); // Load 8-bit data and sign-extend, non-faulting @@ -6207,7 +6207,7 @@ internal Arm64() { } /// svuint16_t svldnf1sb_u16(svbool_t pg, const int8_t *base) /// LDNF1SB Zresult.H, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToUInt16(sbyte* address) => LoadVectorSByteNonFaultingSignExtendToUInt16(address); + public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToUInt16(Vector mask, sbyte* address) => LoadVectorSByteNonFaultingSignExtendToUInt16(mask, address); // Load 8-bit data and sign-extend, non-faulting @@ -6216,7 +6216,7 @@ internal Arm64() { } /// svuint32_t svldnf1sb_u32(svbool_t pg, const int8_t *base) /// LDNF1SB Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToUInt32(sbyte* address) => LoadVectorSByteNonFaultingSignExtendToUInt32(address); + public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToUInt32(Vector mask, sbyte* address) => LoadVectorSByteNonFaultingSignExtendToUInt32(mask, address); // Load 8-bit data and sign-extend, non-faulting @@ -6225,7 +6225,7 @@ internal Arm64() { } /// svuint64_t svldnf1sb_u64(svbool_t pg, const int8_t *base) /// LDNF1SB Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToUInt64(sbyte* address) => LoadVectorSByteNonFaultingSignExtendToUInt64(address); + public static unsafe Vector LoadVectorSByteNonFaultingSignExtendToUInt64(Vector mask, sbyte* address) => LoadVectorSByteNonFaultingSignExtendToUInt64(mask, address); /// Load 8-bit data and sign-extend, first-faulting @@ -6327,7 +6327,7 @@ internal Arm64() { } /// svint32_t svldnf1uh_s32(svbool_t pg, const uint16_t *base) /// LDNF1H Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToInt32(ushort* address) => LoadVectorUInt16NonFaultingZeroExtendToInt32(address); + public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToInt32(Vector mask, ushort* address) => LoadVectorUInt16NonFaultingZeroExtendToInt32(mask, address); // Load 16-bit data and zero-extend, non-faulting @@ -6336,7 +6336,7 @@ internal Arm64() { } /// svint64_t svldnf1uh_s64(svbool_t pg, const uint16_t *base) /// LDNF1H Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToInt64(ushort* address) => LoadVectorUInt16NonFaultingZeroExtendToInt64(address); + public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToInt64(Vector mask, ushort* address) => LoadVectorUInt16NonFaultingZeroExtendToInt64(mask, address); // Load 16-bit data and zero-extend, non-faulting @@ -6345,7 +6345,7 @@ internal Arm64() { } /// svuint32_t svldnf1uh_u32(svbool_t pg, const uint16_t *base) /// LDNF1H Zresult.S, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToUInt32(ushort* address) => LoadVectorUInt16NonFaultingZeroExtendToUInt32(address); + public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToUInt32(Vector mask, ushort* address) => LoadVectorUInt16NonFaultingZeroExtendToUInt32(mask, address); // Load 16-bit data and zero-extend, non-faulting @@ -6354,7 +6354,7 @@ internal Arm64() { } /// svuint64_t svldnf1uh_u64(svbool_t pg, const uint16_t *base) /// LDNF1H Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToUInt64(ushort* address) => LoadVectorUInt16NonFaultingZeroExtendToUInt64(address); + public static unsafe Vector LoadVectorUInt16NonFaultingZeroExtendToUInt64(Vector mask, ushort* address) => LoadVectorUInt16NonFaultingZeroExtendToUInt64(mask, address); /// @@ -6424,7 +6424,7 @@ internal Arm64() { } /// svint64_t svldnf1uw_s64(svbool_t pg, const uint32_t *base) /// LDNF1W Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorUInt32NonFaultingZeroExtendToInt64(uint* address) => LoadVectorUInt32NonFaultingZeroExtendToInt64(address); + public static unsafe Vector LoadVectorUInt32NonFaultingZeroExtendToInt64(Vector mask, uint* address) => LoadVectorUInt32NonFaultingZeroExtendToInt64(mask, address); // Load 32-bit data and zero-extend, non-faulting @@ -6433,7 +6433,7 @@ internal Arm64() { } /// svuint64_t svldnf1uw_u64(svbool_t pg, const uint32_t *base) /// LDNF1W Zresult.D, Pg/Z, [Xbase, #0, MUL VL] /// - public static unsafe Vector LoadVectorUInt32NonFaultingZeroExtendToUInt64(uint* address) => LoadVectorUInt32NonFaultingZeroExtendToUInt64(address); + public static unsafe Vector LoadVectorUInt32NonFaultingZeroExtendToUInt64(Vector mask, uint* address) => LoadVectorUInt32NonFaultingZeroExtendToUInt64(mask, address); /// @@ -8822,6 +8822,54 @@ internal Arm64() { } /// public static void Scatter16BitNarrowing(Vector mask, Vector addresses, Vector data) => Scatter16BitNarrowing(mask, addresses, data); + /// + /// void svst1h_scatter_[s32]index[_s32](svbool_t pg, int16_t *base, svint32_t indices, svint32_t data) + /// ST1H Zdata.S, Pg, [Xbase, Zindices.S, SXTW #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, short* address, Vector indices, Vector data) => Scatter16BitNarrowing(mask, address, indices, data); + + /// + /// void svst1h_scatter_[u32]index[_s32](svbool_t pg, int16_t *base, svuint32_t indices, svint32_t data) + /// ST1H Zdata.S, Pg, [Xbase, Zindices.S, UXTW #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, short* address, Vector indices, Vector data) => Scatter16BitNarrowing(mask, address, indices, data); + + /// + /// void svst1h_scatter_[s64]index[_s64](svbool_t pg, int16_t *base, svint64_t indices, svint64_t data) + /// ST1H Zdata.D, Pg, [Xbase, Zindices.D, LSL #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, short* address, Vector indices, Vector data) => Scatter16BitNarrowing(mask, address, indices, data); + + /// + /// void svst1h_scatter_[u64]index[_s64](svbool_t pg, int16_t *base, svuint64_t indices, svint64_t data) + /// ST1H Zdata.D, Pg, [Xbase, Zindices.D, LSL #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, short* address, Vector indices, Vector data) => Scatter16BitNarrowing(mask, address, indices, data); + + /// + /// void svst1h_scatter_[s32]index[_u32](svbool_t pg, uint16_t *base, svint32_t indices, svuint32_t data) + /// ST1H Zdata.S, Pg, [Xbase, Zindices.S, SXTW #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, ushort* address, Vector indices, Vector data) => Scatter16BitNarrowing(mask, address, indices, data); + + /// + /// void svst1h_scatter_[u32]index[_u32](svbool_t pg, uint16_t *base, svuint32_t indices, svuint32_t data) + /// ST1H Zdata.S, Pg, [Xbase, Zindices.S, UXTW #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, ushort* address, Vector indices, Vector data) => Scatter16BitNarrowing(mask, address, indices, data); + + /// + /// void svst1h_scatter_[s64]index[_u64](svbool_t pg, uint16_t *base, svint64_t indices, svuint64_t data) + /// ST1H Zdata.D, Pg, [Xbase, Zindices.D, LSL #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, ushort* address, Vector indices, Vector data) => Scatter16BitNarrowing(mask, address, indices, data); + + /// + /// void svst1h_scatter_[u64]index[_u64](svbool_t pg, uint16_t *base, svuint64_t indices, svuint64_t data) + /// ST1H Zdata.D, Pg, [Xbase, Zindices.D, LSL #1] + /// + public static unsafe void Scatter16BitNarrowing(Vector mask, ushort* address, Vector indices, Vector data) => Scatter16BitNarrowing(mask, address, indices, data); + // Truncate to 16 bits and store @@ -8888,6 +8936,30 @@ internal Arm64() { } /// public static void Scatter32BitNarrowing(Vector mask, Vector addresses, Vector data) => Scatter32BitNarrowing(mask, addresses, data); + /// + /// void svst1w_scatter_[s64]index[_s64](svbool_t pg, int32_t *base, svint64_t indices, svint64_t data) + /// ST1W Zdata.D, Pg, [Xbase, Zindices.D, LSL #2] + /// + public static unsafe void Scatter32BitNarrowing(Vector mask, int* address, Vector indices, Vector data) => Scatter32BitNarrowing(mask, address, indices, data); + + /// + /// void svst1w_scatter_[u64]index[_s64](svbool_t pg, int32_t *base, svuint64_t indices, svint64_t data) + /// ST1W Zdata.D, Pg, [Xbase, Zindices.D, LSL #2] + /// + public static unsafe void Scatter32BitNarrowing(Vector mask, int* address, Vector indices, Vector data) => Scatter32BitNarrowing(mask, address, indices, data); + + /// + /// void svst1w_scatter_[s64]index[_u64](svbool_t pg, uint32_t *base, svint64_t indices, svuint64_t data) + /// ST1W Zdata.D, Pg, [Xbase, Zindices.D, LSL #2] + /// + public static unsafe void Scatter32BitNarrowing(Vector mask, uint* address, Vector indices, Vector data) => Scatter32BitNarrowing(mask, address, indices, data); + + /// + /// void svst1w_scatter_[u64]index[_u64](svbool_t pg, uint32_t *base, svuint64_t indices, svuint64_t data) + /// ST1W Zdata.D, Pg, [Xbase, Zindices.D, LSL #2] + /// + public static unsafe void Scatter32BitNarrowing(Vector mask, uint* address, Vector indices, Vector data) => Scatter32BitNarrowing(mask, address, indices, data); + // Truncate to 32 bits and store @@ -8996,6 +9068,81 @@ internal Arm64() { } public static unsafe void Scatter8BitWithByteOffsetsNarrowing(Vector mask, byte* address, Vector offsets, Vector data) => Scatter8BitWithByteOffsetsNarrowing(mask, address, offsets, data); + // Non-truncating store + + /// + /// void svst1_scatter_[s64]offset[_f64](svbool_t pg, float64_t *base, svint64_t offsets, svfloat64_t data) + /// ST1D Zdata.D, Pg, [Xbase, Zoffsets.D] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, double* address, Vector offsets, Vector data) => Scatter(mask, address, offsets, data); + + /// + /// void svst1_scatter_[u64]offset[_f64](svbool_t pg, float64_t *base, svuint64_t offsets, svfloat64_t data) + /// ST1D Zdata.D, Pg, [Xbase, Zoffsets.D] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, double* address, Vector offsets, Vector data) => Scatter(mask, address, offsets, data); + + /// + /// void svst1_scatter_[s32]offset[_s32](svbool_t pg, int32_t *base, svint32_t offsets, svint32_t data) + /// ST1W Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, int* address, Vector offsets, Vector data) => Scatter(mask, address, offsets, data); + + /// + /// void svst1_scatter_[u32]offset[_s32](svbool_t pg, int32_t *base, svuint32_t offsets, svint32_t data) + /// ST1W Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, int* address, Vector offsets, Vector data) => Scatter(mask, address, offsets, data); + + /// + /// void svst1_scatter_[s64]offset[_s64](svbool_t pg, int64_t *base, svint64_t offsets, svint64_t data) + /// ST1D Zdata.D, Pg, [Xbase, Zoffsets.D] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, long* address, Vector offsets, Vector data) => Scatter(mask, address, offsets, data); + + /// + /// void svst1_scatter_[u64]offset[_s64](svbool_t pg, int64_t *base, svuint64_t offsets, svint64_t data) + /// ST1D Zdata.D, Pg, [Xbase, Zoffsets.D] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, long* address, Vector offsets, Vector data) => Scatter(mask, address, offsets, data); + + /// + /// void svst1_scatter_[s32]offset[_f32](svbool_t pg, float32_t *base, svint32_t offsets, svfloat32_t data) + /// ST1W Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, float* address, Vector offsets, Vector data) => Scatter(mask, address, offsets, data); + + /// + /// void svst1_scatter_[u32]offset[_f32](svbool_t pg, float32_t *base, svuint32_t offsets, svfloat32_t data) + /// ST1W Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, float* address, Vector offsets, Vector data) => Scatter(mask, address, offsets, data); + + /// + /// void svst1_scatter_[s32]offset[_u32](svbool_t pg, uint32_t *base, svint32_t offsets, svuint32_t data) + /// ST1W Zdata.S, Pg, [Xbase, Zoffsets.S, SXTW] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, uint* address, Vector offsets, Vector data) => Scatter(mask, address, offsets, data); + + /// + /// void svst1_scatter_[u32]offset[_u32](svbool_t pg, uint32_t *base, svuint32_t offsets, svuint32_t data) + /// ST1W Zdata.S, Pg, [Xbase, Zoffsets.S, UXTW] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, uint* address, Vector offsets, Vector data) => Scatter(mask, address, offsets, data); + + /// + /// void svst1_scatter_[s64]offset[_u64](svbool_t pg, uint64_t *base, svint64_t offsets, svuint64_t data) + /// ST1D Zdata.D, Pg, [Xbase, Zoffsets.D] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, ulong* address, Vector offsets, Vector data) => Scatter(mask, address, offsets, data); + + /// + /// void svst1_scatter_[u64]offset[_u64](svbool_t pg, uint64_t *base, svuint64_t offsets, svuint64_t data) + /// ST1D Zdata.D, Pg, [Xbase, Zoffsets.D] + /// + public static unsafe void ScatterWithByteOffsets(Vector mask, ulong* address, Vector offsets, Vector data) => Scatter(mask, address, offsets, data); + + // Write to the first-fault register /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs index 007620866ef41d..bcab1359869df7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs @@ -28,6 +28,46 @@ internal Arm64() { } public static new bool IsSupported { get => IsSupported; } } + + // Saturating absolute value + + /// + /// svint8_t svqabs[_s8]_m(svint8_t inactive, svbool_t pg, svint8_t op) + /// svint8_t svqabs[_s8]_x(svbool_t pg, svint8_t op) + /// svint8_t svqabs[_s8]_z(svbool_t pg, svint8_t op) + /// SQABS Ztied.B, Pg/M, Zop.B + /// SQABS Ztied.B, Pg/M, Ztied.B + /// + public static Vector AbsSaturate(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svqabs[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// svint16_t svqabs[_s16]_x(svbool_t pg, svint16_t op) + /// svint16_t svqabs[_s16]_z(svbool_t pg, svint16_t op) + /// SQABS Ztied.H, Pg/M, Zop.H + /// SQABS Ztied.H, Pg/M, Ztied.H + /// + public static Vector AbsSaturate(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqabs[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// svint32_t svqabs[_s32]_x(svbool_t pg, svint32_t op) + /// svint32_t svqabs[_s32]_z(svbool_t pg, svint32_t op) + /// SQABS Ztied.S, Pg/M, Zop.S + /// SQABS Ztied.S, Pg/M, Ztied.S + /// + public static Vector AbsSaturate(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqabs[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// svint64_t svqabs[_s64]_x(svbool_t pg, svint64_t op) + /// svint64_t svqabs[_s64]_z(svbool_t pg, svint64_t op) + /// SQABS Ztied.D, Pg/M, Zop.D + /// SQABS Ztied.D, Pg/M, Ztied.D + /// + public static Vector AbsSaturate(Vector value) { throw new PlatformNotSupportedException(); } + + // Absolute difference and accumulate /// @@ -426,7 +466,7 @@ internal Arm64() { } /// SADALP Ztied1.H, Pg/M, Zop2.B /// SADALP Ztied1.H, Pg/M, Zop2.B /// - public static Vector AddPairwiseWidening(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svint32_t svadalp[_s32]_m(svbool_t pg, svint32_t op1, svint16_t op2) @@ -435,7 +475,7 @@ internal Arm64() { } /// SADALP Ztied1.S, Pg/M, Zop2.H /// SADALP Ztied1.S, Pg/M, Zop2.H /// - public static Vector AddPairwiseWidening(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svint64_t svadalp[_s64]_m(svbool_t pg, svint64_t op1, svint32_t op2) @@ -444,7 +484,7 @@ internal Arm64() { } /// SADALP Ztied1.D, Pg/M, Zop2.S /// SADALP Ztied1.D, Pg/M, Zop2.S /// - public static Vector AddPairwiseWidening(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svuint16_t svadalp[_u16]_m(svbool_t pg, svuint16_t op1, svuint8_t op2) @@ -453,7 +493,7 @@ internal Arm64() { } /// UADALP Ztied1.H, Pg/M, Zop2.B /// UADALP Ztied1.H, Pg/M, Zop2.B /// - public static Vector AddPairwiseWidening(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svuint32_t svadalp[_u32]_m(svbool_t pg, svuint32_t op1, svuint16_t op2) @@ -462,7 +502,7 @@ internal Arm64() { } /// UADALP Ztied1.S, Pg/M, Zop2.H /// UADALP Ztied1.S, Pg/M, Zop2.H /// - public static Vector AddPairwiseWidening(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svuint64_t svadalp[_u64]_m(svbool_t pg, svuint64_t op1, svuint32_t op2) @@ -471,7 +511,135 @@ internal Arm64() { } /// UADALP Ztied1.D, Pg/M, Zop2.S /// UADALP Ztied1.D, Pg/M, Zop2.S /// - public static Vector AddPairwiseWidening(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Complex add with rotate + + /// + /// svuint8_t svcadd[_u8](svuint8_t op1, svuint8_t op2, uint64_t imm_rotation) + /// CADD Ztied1.B, Ztied1.B, Zop2.B, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svcadd[_s16](svint16_t op1, svint16_t op2, uint64_t imm_rotation) + /// CADD Ztied1.H, Ztied1.H, Zop2.H, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svcadd[_s32](svint32_t op1, svint32_t op2, uint64_t imm_rotation) + /// CADD Ztied1.S, Ztied1.S, Zop2.S, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svcadd[_s64](svint64_t op1, svint64_t op2, uint64_t imm_rotation) + /// CADD Ztied1.D, Ztied1.D, Zop2.D, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svcadd[_s8](svint8_t op1, svint8_t op2, uint64_t imm_rotation) + /// CADD Ztied1.B, Ztied1.B, Zop2.B, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svcadd[_u16](svuint16_t op1, svuint16_t op2, uint64_t imm_rotation) + /// CADD Ztied1.H, Ztied1.H, Zop2.H, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svcadd[_u32](svuint32_t op1, svuint32_t op2, uint64_t imm_rotation) + /// CADD Ztied1.S, Ztied1.S, Zop2.S, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svcadd[_u64](svuint64_t op1, svuint64_t op2, uint64_t imm_rotation) + /// CADD Ztied1.D, Ztied1.D, Zop2.D, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { 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 @@ -555,6 +723,32 @@ internal Arm64() { } /// public static new Vector AddSaturate(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + // Saturating complex add with rotate + + /// + /// svint16_t svqcadd[_s16](svint16_t op1, svint16_t op2, uint64_t imm_rotation) + /// SQCADD Ztied1.H, Ztied1.H, Zop2.H, #imm_rotation + /// + public static Vector AddSaturateRotateComplex(Vector op1, Vector op2, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqcadd[_s32](svint32_t op1, svint32_t op2, uint64_t imm_rotation) + /// SQCADD Ztied1.S, Ztied1.S, Zop2.S, #imm_rotation + /// + public static Vector AddSaturateRotateComplex(Vector op1, Vector op2, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqcadd[_s64](svint64_t op1, svint64_t op2, uint64_t imm_rotation) + /// SQCADD Ztied1.D, Ztied1.D, Zop2.D, #imm_rotation + /// + public static Vector AddSaturateRotateComplex(Vector op1, Vector op2, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svqcadd[_s8](svint8_t op1, svint8_t op2, uint64_t imm_rotation) + /// SQCADD Ztied1.B, Ztied1.B, Zop2.B, #imm_rotation + /// + public static Vector AddSaturateRotateComplex(Vector op1, Vector op2, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + // Saturating add with signed addend /// @@ -637,113 +831,73 @@ internal Arm64() { } /// svint16_t svaddwb[_s16](svint16_t op1, svint8_t op2) /// SADDWB Zresult.H, Zop1.H, Zop2.B /// - public static Vector AddWideLower(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svint32_t svaddwb[_s32](svint32_t op1, svint16_t op2) /// SADDWB Zresult.S, Zop1.S, Zop2.H /// - public static Vector AddWideLower(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svint64_t svaddwb[_s64](svint64_t op1, svint32_t op2) /// SADDWB Zresult.D, Zop1.D, Zop2.S /// - public static Vector AddWideLower(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svuint16_t svaddwb[_u16](svuint16_t op1, svuint8_t op2) /// UADDWB Zresult.H, Zop1.H, Zop2.B /// - public static Vector AddWideLower(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svuint32_t svaddwb[_u32](svuint32_t op1, svuint16_t op2) /// UADDWB Zresult.S, Zop1.S, Zop2.H /// - public static Vector AddWideLower(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svuint64_t svaddwb[_u64](svuint64_t op1, svuint32_t op2) /// UADDWB Zresult.D, Zop1.D, Zop2.S /// - public static Vector AddWideLower(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - // Add wide (top) - - /// - /// svint16_t svaddwt[_s16](svint16_t op1, svint8_t op2) - /// SADDWT Zresult.H, Zop1.H, Zop2.B - /// - public static Vector AddWideUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svint32_t svaddwt[_s32](svint32_t op1, svint16_t op2) - /// SADDWT Zresult.S, Zop1.S, Zop2.H - /// - public static Vector AddWideUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svint64_t svaddwt[_s64](svint64_t op1, svint32_t op2) - /// SADDWT Zresult.D, Zop1.D, Zop2.S - /// - public static Vector AddWideUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svuint16_t svaddwt[_u16](svuint16_t op1, svuint8_t op2) - /// UADDWT Zresult.H, Zop1.H, Zop2.B - /// - public static Vector AddWideUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svuint32_t svaddwt[_u32](svuint32_t op1, svuint16_t op2) - /// UADDWT Zresult.S, Zop1.S, Zop2.H - /// - public static Vector AddWideUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svuint64_t svaddwt[_u64](svuint64_t op1, svuint32_t op2) - /// UADDWT Zresult.D, Zop1.D, Zop2.S - /// - public static Vector AddWideUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - // Add long (bottom) + public static Vector AddWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svint16_t svaddlb[_s16](svint8_t op1, svint8_t op2) /// SADDLB Zresult.H, Zop1.B, Zop2.B /// - public static Vector AddWideningLower(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svint32_t svaddlb[_s32](svint16_t op1, svint16_t op2) /// SADDLB Zresult.S, Zop1.H, Zop2.H /// - public static Vector AddWideningLower(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svint64_t svaddlb[_s64](svint32_t op1, svint32_t op2) /// SADDLB Zresult.D, Zop1.S, Zop2.S /// - public static Vector AddWideningLower(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svuint16_t svaddlb[_u16](svuint8_t op1, svuint8_t op2) /// UADDLB Zresult.H, Zop1.B, Zop2.B /// - public static Vector AddWideningLower(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svuint32_t svaddlb[_u32](svuint16_t op1, svuint16_t op2) /// UADDLB Zresult.S, Zop1.H, Zop2.H /// - public static Vector AddWideningLower(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svuint64_t svaddlb[_u64](svuint32_t op1, svuint32_t op2) /// UADDLB Zresult.D, Zop1.S, Zop2.S /// - public static Vector AddWideningLower(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } // Add long (bottom + top) @@ -751,57 +905,93 @@ internal Arm64() { } /// svint16_t svaddlbt[_s16](svint8_t op1, svint8_t op2) /// SADDLBT Zresult.H, Zop1.B, Zop2.B /// - public static Vector AddWideningLowerUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEvenOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svint32_t svaddlbt[_s32](svint16_t op1, svint16_t op2) /// SADDLBT Zresult.S, Zop1.H, Zop2.H /// - public static Vector AddWideningLowerUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEvenOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svint64_t svaddlbt[_s64](svint32_t op1, svint32_t op2) /// SADDLBT Zresult.D, Zop1.S, Zop2.S /// - public static Vector AddWideningLowerUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningEvenOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Add wide (top) + + /// + /// svint16_t svaddwt[_s16](svint16_t op1, svint8_t op2) + /// SADDWT Zresult.H, Zop1.H, Zop2.B + /// + public static Vector AddWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svaddwt[_s32](svint32_t op1, svint16_t op2) + /// SADDWT Zresult.S, Zop1.S, Zop2.H + /// + public static Vector AddWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svaddwt[_s64](svint64_t op1, svint32_t op2) + /// SADDWT Zresult.D, Zop1.D, Zop2.S + /// + public static Vector AddWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svaddwt[_u16](svuint16_t op1, svuint8_t op2) + /// UADDWT Zresult.H, Zop1.H, Zop2.B + /// + public static Vector AddWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svaddwt[_u32](svuint32_t op1, svuint16_t op2) + /// UADDWT Zresult.S, Zop1.S, Zop2.H + /// + public static Vector AddWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - // Add long (top) + /// + /// svuint64_t svaddwt[_u64](svuint64_t op1, svuint32_t op2) + /// UADDWT Zresult.D, Zop1.D, Zop2.S + /// + public static Vector AddWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svint16_t svaddlt[_s16](svint8_t op1, svint8_t op2) /// SADDLT Zresult.H, Zop1.B, Zop2.B /// - public static Vector AddWideningUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svint32_t svaddlt[_s32](svint16_t op1, svint16_t op2) /// SADDLT Zresult.S, Zop1.H, Zop2.H /// - public static Vector AddWideningUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svint64_t svaddlt[_s64](svint32_t op1, svint32_t op2) /// SADDLT Zresult.D, Zop1.S, Zop2.S /// - public static Vector AddWideningUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svuint16_t svaddlt[_u16](svuint8_t op1, svuint8_t op2) /// UADDLT Zresult.H, Zop1.B, Zop2.B /// - public static Vector AddWideningUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svuint32_t svaddlt[_u32](svuint16_t op1, svuint16_t op2) /// UADDLT Zresult.S, Zop1.H, Zop2.H /// - public static Vector AddWideningUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } /// /// svuint64_t svaddlt[_u64](svuint32_t op1, svuint32_t op2) /// UADDLT Zresult.D, Zop1.S, Zop2.S /// - public static Vector AddWideningUpper(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + public static Vector AddWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } // Bitwise clear and exclusive OR @@ -1006,6 +1196,269 @@ internal Arm64() { } /// public static Vector BitwiseSelectRightInverted(Vector select, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + // Complex dot product + + /// + /// svint32_t svcdot[_s32](svint32_t op1, svint8_t op2, svint8_t op3, uint64_t imm_rotation) + /// CDOT Ztied1.S, Zop2.B, Zop3.B, #imm_rotation + /// + public static Vector DotProductRotateComplex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svcdot[_s64](svint64_t op1, svint16_t op2, svint16_t op3, uint64_t imm_rotation) + /// CDOT Ztied1.D, Zop2.H, Zop3.H, #imm_rotation + /// + public static Vector DotProductRotateComplex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svcdot_lane[_s32](svint32_t op1, svint8_t op2, svint8_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// CDOT Ztied1.S, Zop2.B, Zop3.B[imm_index], #imm_rotation + /// + public static Vector DotProductRotateComplexBySelectedIndex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte imm_index, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svcdot_lane[_s64](svint64_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// CDOT Ztied1.D, Zop2.H, Zop3.H[imm_index], #imm_rotation + /// + public static Vector DotProductRotateComplexBySelectedIndex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(1))] byte imm_index, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + // Up convert long (top) + + /// + /// svfloat64_t svcvtlt_f64[_f32]_m(svfloat64_t inactive, svbool_t pg, svfloat32_t op) + /// svfloat64_t svcvtlt_f64[_f32]_x(svbool_t pg, svfloat32_t op) + /// FCVTLT Ztied.D, Pg/M, Zop.S + /// FCVTLT Ztied.D, Pg/M, Ztied.S + /// + public static Vector ConvertToDoubleOdd(Vector value) { throw new PlatformNotSupportedException(); } + + // Down convert, rounding to odd + + /// + /// svfloat32_t svcvtx_f32[_f64]_m(svfloat32_t inactive, svbool_t pg, svfloat64_t op) + /// svfloat32_t svcvtx_f32[_f64]_x(svbool_t pg, svfloat64_t op) + /// svfloat32_t svcvtx_f32[_f64]_z(svbool_t pg, svfloat64_t op) + /// FCVTX Ztied.S, Pg/M, Zop.D + /// FCVTX Ztied.S, Pg/M, Ztied.D + /// + public static unsafe Vector ConvertToSingleEvenRoundToOdd(Vector value) { throw new PlatformNotSupportedException(); } + + // Halving add + + /// + /// svuint8_t svhadd[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhadd[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhadd[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHADD Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svhadd[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhadd[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhadd[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHADD Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svhadd[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhadd[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhadd[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHADD Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svhadd[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhadd[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhadd[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHADD Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svhadd[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhadd[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhadd[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHADD Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svhadd[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhadd[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhadd[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHADD Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svhadd[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhadd[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhadd[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHADD Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svhadd[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhadd[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhadd[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHADD Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Halving subtract + + /// + /// svuint8_t svhsub[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhsub[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhsub[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHSUBR Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svhsub[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhsub[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhsub[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHSUBR Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svhsub[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhsub[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhsub[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHSUBR Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svhsub[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhsub[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhsub[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHSUBR Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svhsub[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhsub[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhsub[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHSUBR Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svhsub[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhsub[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhsub[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHSUBR Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svhsub[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhsub[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhsub[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHSUBR Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svhsub[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhsub[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhsub[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHSUBR Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + 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 /// @@ -1104,8 +1557,1367 @@ internal Arm64() { } /// public static Vector InterleavingXorOddEven(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + // Base 2 logarithm as integer - // Rounding shift left + /// + /// svint32_t svlogb[_f32]_m(svint32_t inactive, svbool_t pg, svfloat32_t op) + /// svint32_t svlogb[_f32]_x(svbool_t pg, svfloat32_t op) + /// svint32_t svlogb[_f32]_z(svbool_t pg, svfloat32_t op) + /// FLOGB Ztied.S, Pg/M, Zop.S + /// FLOGB Ztied.S, Pg/M, Ztied.S + /// + public static Vector Log2(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svlogb[_f64]_m(svint64_t inactive, svbool_t pg, svfloat64_t op) + /// svint64_t svlogb[_f64]_x(svbool_t pg, svfloat64_t op) + /// svint64_t svlogb[_f64]_z(svbool_t pg, svfloat64_t op) + /// FLOGB Ztied.D, Pg/M, Zop.D + /// FLOGB Ztied.D, Pg/M, Ztied.D + /// + public static Vector Log2(Vector value) { throw new PlatformNotSupportedException(); } + + // Maximum number pairwise + + /// + /// svfloat64_t svmaxnmp[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmaxnmp[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMAXNMP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MaxNumberPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svmaxnmp[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmaxnmp[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMAXNMP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MaxNumberPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Maximum pairwise + + /// + /// svuint8_t svmaxp[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svmaxp[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UMAXP Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector MaxPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svmaxp[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmaxp[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMAXP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MaxPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svmaxp[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svmaxp[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// SMAXP Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector MaxPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmaxp[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svmaxp[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// SMAXP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MaxPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmaxp[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svmaxp[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// SMAXP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MaxPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svmaxp[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svmaxp[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// SMAXP Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector MaxPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svmaxp[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmaxp[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMAXP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MaxPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmaxp[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svmaxp[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UMAXP Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector MaxPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmaxp[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svmaxp[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UMAXP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MaxPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmaxp[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svmaxp[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UMAXP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MaxPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Minimum number pairwise + + /// + /// svfloat64_t svminnmp[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svminnmp[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMINNMP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MinNumberPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svminnmp[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svminnmp[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMINNMP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MinNumberPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Minimum pairwise + + /// + /// svuint8_t svminp[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svminp[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UMINP Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector MinPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svminp[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svminp[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMINP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MinPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svminp[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svminp[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// SMINP Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector MinPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svminp[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svminp[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// SMINP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MinPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svminp[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svminp[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// SMINP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MinPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svminp[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svminp[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// SMINP Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector MinPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svminp[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svminp[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMINP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MinPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svminp[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svminp[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UMINP Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector MinPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svminp[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svminp[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UMINP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MinPairwise(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svminp[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svminp[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UMINP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MinPairwise(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(); } + + // Complex multiply-add with rotate + + /// + /// svuint8_t svcmla[_u8](svuint8_t op1, svuint8_t op2, svuint8_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.B, Zop2.B, Zop3.B, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svcmla[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.H, Zop2.H, Zop3.H, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svcmla[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.S, Zop2.S, Zop3.S, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svcmla[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.D, Zop2.D, Zop3.D, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svcmla[_s8](svint8_t op1, svint8_t op2, svint8_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.B, Zop2.B, Zop3.B, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svcmla[_u16](svuint16_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.H, Zop2.H, Zop3.H, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svcmla[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.S, Zop2.S, Zop3.S, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svcmla[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.D, Zop2.D, Zop3.D, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + // Complex multiply-add with rotate + + /// + /// svint16_t svcmla_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// CMLA Ztied1.H, Zop2.H, Zop3.H[imm_index], #imm_rotation + /// + public static Vector MultiplyAddRotateComplexBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rightIndex, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svcmla_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// CMLA Ztied1.S, Zop2.S, Zop3.S[imm_index], #imm_rotation + /// + public static Vector MultiplyAddRotateComplexBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rightIndex, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svcmla_lane[_u16](svuint16_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// CMLA Ztied1.H, Zop2.H, Zop3.H[imm_index], #imm_rotation + /// + public static Vector MultiplyAddRotateComplexBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rightIndex, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svcmla_lane[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// CMLA Ztied1.S, Zop2.S, Zop3.S[imm_index], #imm_rotation + /// + public static Vector MultiplyAddRotateComplexBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rightIndex, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + // Saturating rounding doubling complex multiply-add high with rotate + + /// + /// svint16_t svqrdcmlah[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_rotation) + /// SQRDCMLAH Ztied1.H, Zop2.H, Zop3.H, #imm_rotation + /// + public static unsafe Vector MultiplyAddRoundedDoublingSaturateHighRotateComplex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqrdcmlah[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_rotation) + /// SQRDCMLAH Ztied1.S, Zop2.S, Zop3.S, #imm_rotation + /// + public static unsafe Vector MultiplyAddRoundedDoublingSaturateHighRotateComplex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqrdcmlah[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_rotation) + /// SQRDCMLAH Ztied1.D, Zop2.D, Zop3.D, #imm_rotation + /// + public static unsafe Vector MultiplyAddRoundedDoublingSaturateHighRotateComplex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svqrdcmlah[_s8](svint8_t op1, svint8_t op2, svint8_t op3, uint64_t imm_rotation) + /// SQRDCMLAH Ztied1.B, Zop2.B, Zop3.B, #imm_rotation + /// + public static unsafe Vector MultiplyAddRoundedDoublingSaturateHighRotateComplex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svqrdcmlah_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// SQRDCMLAH Ztied1.H, Zop2.H, Zop3.H[imm_index], #imm_rotation + /// + public static Vector MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte imm_index, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqrdcmlah_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// SQRDCMLAH Ztied1.S, Zop2.S, Zop3.S[imm_index], #imm_rotation + /// + public static Vector MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(1))] byte imm_index, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { 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(); } + + + // Saturating doubling multiply high with index + + /// + /// svint16_t svqdmulh_lane[_s16](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SQDMULH Zresult.H, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyDoublingBySelectedScalarSaturateHigh(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqdmulh_lane[_s32](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SQDMULH Zresult.S, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyDoublingBySelectedScalarSaturateHigh(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmulh_lane[_s64](svint64_t op1, svint64_t op2, uint64_t imm_index) + /// SQDMULH Zresult.D, Zop1.D, Zop2.D[imm_index] + /// + public static Vector MultiplyDoublingBySelectedScalarSaturateHigh(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply high + + /// + /// svint8_t svqdmulh[_s8](svint8_t op1, svint8_t op2) + /// SQDMULH Zresult.B, Zop1.B, Zop2.B + /// + public static Vector MultiplyDoublingSaturateHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svqdmulh[_s16](svint16_t op1, svint16_t op2) + /// SQDMULH Zresult.H, Zop1.H, Zop2.H + /// + public static Vector MultiplyDoublingSaturateHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqdmulh[_s32](svint32_t op1, svint32_t op2) + /// SQDMULH Zresult.S, Zop1.S, Zop2.S + /// + public static Vector MultiplyDoublingSaturateHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmulh[_s64](svint64_t op1, svint64_t op2) + /// SQDMULH Zresult.D, Zop1.D, Zop2.D + /// + public static Vector MultiplyDoublingSaturateHigh(Vector left, Vector right) { 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(); } + + + // Saturating doubling multiply-add long (bottom) + + /// + /// svint16_t svqdmlalb[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SQDMLALB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyDoublingWideningAndAddSaturateEven(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqdmlalb[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SQDMLALB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyDoublingWideningAndAddSaturateEven(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmlalb[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SQDMLALB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyDoublingWideningAndAddSaturateEven(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply-add long (bottom × top) + + /// + /// svint16_t svqdmlalbt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SQDMLALBT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyDoublingWideningAndAddSaturateEvenOdd(Vector addend, Vector leftEven, Vector rightOdd) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqdmlalbt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SQDMLALBT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyDoublingWideningAndAddSaturateEvenOdd(Vector addend, Vector leftEven, Vector rightOdd) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmlalbt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SQDMLALBT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyDoublingWideningAndAddSaturateEvenOdd(Vector addend, Vector leftEven, Vector rightOdd) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply-add long (top) + + /// + /// svint16_t svqdmlalt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SQDMLALT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyDoublingWideningAndAddSaturateOdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqdmlalt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SQDMLALT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyDoublingWideningAndAddSaturateOdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmlalt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SQDMLALT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyDoublingWideningAndAddSaturateOdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply-subtract long (bottom) + + /// + /// svint16_t svqdmlslb[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SQDMLSLB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateEven(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqdmlslb[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SQDMLSLB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateEven(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmlslb[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SQDMLSLB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateEven(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply-subtract long (bottom × top) + + /// + /// svint16_t svqdmlslbt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SQDMLSLBT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateEvenOdd(Vector minuend, Vector leftEven, Vector rightOdd) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqdmlslbt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SQDMLSLBT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateEvenOdd(Vector minuend, Vector leftEven, Vector rightOdd) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmlslbt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SQDMLSLBT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateEvenOdd(Vector minuend, Vector leftEven, Vector rightOdd) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply-subtract long (top) + + /// + /// svint16_t svqdmlslt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SQDMLSLT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateOdd(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqdmlslt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SQDMLSLT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateOdd(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmlslt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SQDMLSLT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateOdd(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply-add long with index (bottom) + + /// + /// svint32_t svqdmlalb_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SQDMLALB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmlalb_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SQDMLALB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply-add long with index (top) + + /// + /// svint32_t svqdmlalt_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SQDMLALT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmlalt_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SQDMLALT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply-subtract long with index (bottom) + + /// + /// svint32_t svqdmlslb_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SQDMLSLB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmlslb_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SQDMLSLB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply-subtract long (top) + + /// + /// svint32_t svqdmlslt_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SQDMLSLT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmlslt_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SQDMLSLT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply long (bottom) + + /// + /// svint16_t svqdmullb[_s16](svint8_t op1, svint8_t op2) + /// SQDMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyDoublingWideningSaturateEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqdmullb[_s32](svint16_t op1, svint16_t op2) + /// SQDMULLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyDoublingWideningSaturateEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmullb[_s64](svint32_t op1, svint32_t op2) + /// SQDMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyDoublingWideningSaturateEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply long with index (bottom) + + /// + /// svint32_t svqdmullb_lane[_s32](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SQDMULLB Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyDoublingWideningSaturateEvenBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmullb_lane[_s64](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SQDMULLB Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyDoublingWideningSaturateEvenBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply long (top) + + /// + /// svint16_t svqdmullt[_s16](svint8_t op1, svint8_t op2) + /// SQDMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyDoublingWideningSaturateOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqdmullt[_s32](svint16_t op1, svint16_t op2) + /// SQDMULLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyDoublingWideningSaturateOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmullt[_s64](svint32_t op1, svint32_t op2) + /// SQDMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyDoublingWideningSaturateOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Saturating doubling multiply long with index (top) + + /// + /// svint32_t svqdmullt_lane[_s32](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SQDMULLT Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyDoublingWideningSaturateOddBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqdmullt_lane[_s64](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SQDMULLT Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyDoublingWideningSaturateOddBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Saturating rounding doubling multiply high with index + + /// + /// svint16_t svqrdmulh_lane[_s16](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SQRDMULH Zresult.H, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyRoundedDoublingBySelectedScalarSaturateHigh(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqrdmulh_lane[_s32](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SQRDMULH Zresult.S, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyRoundedDoublingBySelectedScalarSaturateHigh(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqrdmulh_lane[_s64](svint64_t op1, svint64_t op2, uint64_t imm_index) + /// SQRDMULH Zresult.D, Zop1.D, Zop2.D[imm_index] + /// + public static Vector MultiplyRoundedDoublingBySelectedScalarSaturateHigh(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Saturating rounding doubling multiply-add high + + /// + /// svint8_t svqrdmlah[_s8](svint8_t op1, svint8_t op2, svint8_t op3) + /// SQRDMLAH Ztied1.B, Zop2.B, Zop3.B + /// + public static Vector MultiplyRoundedDoublingSaturateAndAddHigh(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svqrdmlah[_s16](svint16_t op1, svint16_t op2, svint16_t op3) + /// SQRDMLAH Ztied1.H, Zop2.H, Zop3.H + /// + public static Vector MultiplyRoundedDoublingSaturateAndAddHigh(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqrdmlah[_s32](svint32_t op1, svint32_t op2, svint32_t op3) + /// SQRDMLAH Ztied1.S, Zop2.S, Zop3.S + /// + public static Vector MultiplyRoundedDoublingSaturateAndAddHigh(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqrdmlah[_s64](svint64_t op1, svint64_t op2, svint64_t op3) + /// SQRDMLAH Ztied1.D, Zop2.D, Zop3.D + /// + public static Vector MultiplyRoundedDoublingSaturateAndAddHigh(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Saturating rounding doubling multiply-subtract high + + /// + /// svint8_t svqrdmlsh[_s8](svint8_t op1, svint8_t op2, svint8_t op3) + /// SQRDMLSH Ztied1.B, Zop2.B, Zop3.B + /// + public static Vector MultiplyRoundedDoublingSaturateAndSubtractHigh(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svqrdmlsh[_s16](svint16_t op1, svint16_t op2, svint16_t op3) + /// SQRDMLSH Ztied1.H, Zop2.H, Zop3.H + /// + public static Vector MultiplyRoundedDoublingSaturateAndSubtractHigh(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqrdmlsh[_s32](svint32_t op1, svint32_t op2, svint32_t op3) + /// SQRDMLSH Ztied1.S, Zop2.S, Zop3.S + /// + public static Vector MultiplyRoundedDoublingSaturateAndSubtractHigh(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqrdmlsh[_s64](svint64_t op1, svint64_t op2, svint64_t op3) + /// SQRDMLSH Ztied1.D, Zop2.D, Zop3.D + /// + public static Vector MultiplyRoundedDoublingSaturateAndSubtractHigh(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Saturating rounding doubling multiply-add high with index + + /// + /// svint16_t svqrdmlah_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SQRDMLAH Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqrdmlah_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SQRDMLAH Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqrdmlah_lane[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_index) + /// SQRDMLAH Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Saturating rounding doubling multiply-subtract high with index + + /// + /// svint16_t svqrdmlsh_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SQRDMLSH Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqrdmlsh_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SQRDMLSH Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqrdmlsh_lane[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_index) + /// SQRDMLSH Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Saturating rounding doubling multiply high + + /// + /// svint8_t svqrdmulh[_s8](svint8_t op1, svint8_t op2) + /// SQRDMULH Zresult.B, Zop1.B, Zop2.B + /// + public static Vector MultiplyRoundedDoublingSaturateHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svqrdmulh[_s16](svint16_t op1, svint16_t op2) + /// SQRDMULH Zresult.H, Zop1.H, Zop2.H + /// + public static Vector MultiplyRoundedDoublingSaturateHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqrdmulh[_s32](svint32_t op1, svint32_t op2) + /// SQRDMULH Zresult.S, Zop1.S, Zop2.S + /// + public static Vector MultiplyRoundedDoublingSaturateHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqrdmulh[_s64](svint64_t op1, svint64_t op2) + /// SQRDMULH Zresult.D, Zop1.D, Zop2.D + /// + public static Vector MultiplyRoundedDoublingSaturateHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Saturating negate + + /// + /// svint8_t svqneg[_s8]_m(svint8_t inactive, svbool_t pg, svint8_t op) + /// svint8_t svqneg[_s8]_x(svbool_t pg, svint8_t op) + /// svint8_t svqneg[_s8]_z(svbool_t pg, svint8_t op) + /// SQNEG Ztied.B, Pg/M, Zop.B + /// SQNEG Ztied.B, Pg/M, Ztied.B + /// + public static Vector NegateSaturate(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svqneg[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// svint16_t svqneg[_s16]_x(svbool_t pg, svint16_t op) + /// svint16_t svqneg[_s16]_z(svbool_t pg, svint16_t op) + /// SQNEG Ztied.H, Pg/M, Zop.H + /// SQNEG Ztied.H, Pg/M, Ztied.H + /// + public static Vector NegateSaturate(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqneg[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// svint32_t svqneg[_s32]_x(svbool_t pg, svint32_t op) + /// svint32_t svqneg[_s32]_z(svbool_t pg, svint32_t op) + /// SQNEG Ztied.S, Pg/M, Zop.S + /// SQNEG Ztied.S, Pg/M, Ztied.S + /// + public static Vector NegateSaturate(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqneg[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// svint64_t svqneg[_s64]_x(svbool_t pg, svint64_t op) + /// svint64_t svqneg[_s64]_z(svbool_t pg, svint64_t op) + /// SQNEG Ztied.D, Pg/M, Zop.D + /// SQNEG Ztied.D, Pg/M, Ztied.D + /// + public static Vector NegateSaturate(Vector value) { throw new PlatformNotSupportedException(); } + + // Reciprocal estimate + + /// + /// svuint32_t svrecpe[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// svuint32_t svrecpe[_u32]_x(svbool_t pg, svuint32_t op) + /// svuint32_t svrecpe[_u32]_z(svbool_t pg, svuint32_t op) + /// URECPE Ztied.S, Pg/M, Zop.S + /// URECPE Ztied.S, Pg/M, Ztied.S + /// + public static Vector ReciprocalEstimate(Vector value) { throw new PlatformNotSupportedException(); } + + // Reciprocal square root estimate + + /// + /// svuint32_t svrsqrte[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// svuint32_t svrsqrte[_u32]_x(svbool_t pg, svuint32_t op) + /// svuint32_t svrsqrte[_u32]_z(svbool_t pg, svuint32_t op) + /// URSQRTE Ztied.S, Pg/M, Zop.S + /// URSQRTE Ztied.S, Pg/M, Ztied.S + /// + public static Vector ReciprocalSqrtEstimate(Vector value) { throw new PlatformNotSupportedException(); } + + // Rounding shift left /// /// svint16_t svrshl[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) @@ -1503,12 +3315,6 @@ internal Arm64() { } // Saturating shift right narrow (bottom) - /// - /// svuint8_t svqshrnb[_n_u16](svuint16_t op1, uint64_t imm2) - /// UQSHRNB Zresult.B, Zop1.H, #imm2 - /// - public static Vector ShiftRightArithmeticNarrowingSaturateEven(Vector value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } - /// /// svint16_t svqshrnb[_n_s32](svint32_t op1, uint64_t imm2) /// SQSHRNB Zresult.H, Zop1.S, #imm2 @@ -1527,27 +3333,9 @@ internal Arm64() { } /// public static Vector ShiftRightArithmeticNarrowingSaturateEven(Vector value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } - /// - /// svuint16_t svqshrnb[_n_u32](svuint32_t op1, uint64_t imm2) - /// UQSHRNB Zresult.H, Zop1.S, #imm2 - /// - public static Vector ShiftRightArithmeticNarrowingSaturateEven(Vector value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } - - /// - /// svuint32_t svqshrnb[_n_u64](svuint64_t op1, uint64_t imm2) - /// UQSHRNB Zresult.S, Zop1.D, #imm2 - /// - public static Vector ShiftRightArithmeticNarrowingSaturateEven(Vector value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } - // Saturating shift right narrow (top) - /// - /// svuint8_t svqshrnt[_n_u16](svuint8_t even, svuint16_t op1, uint64_t imm2) - /// UQSHRNT Ztied.B, Zop1.H, #imm2 - /// - public static Vector ShiftRightArithmeticNarrowingSaturateOdd(Vector even, Vector value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } - /// /// svint16_t svqshrnt[_n_s32](svint16_t even, svint32_t op1, uint64_t imm2) /// SQSHRNT Ztied.H, Zop1.S, #imm2 @@ -1566,18 +3354,6 @@ internal Arm64() { } /// public static Vector ShiftRightArithmeticNarrowingSaturateOdd(Vector even, Vector value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } - /// - /// svuint16_t svqshrnt[_n_u32](svuint16_t even, svuint32_t op1, uint64_t imm2) - /// UQSHRNT Ztied.H, Zop1.S, #imm2 - /// - public static Vector ShiftRightArithmeticNarrowingSaturateOdd(Vector even, Vector value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } - - /// - /// svuint32_t svqshrnt[_n_u64](svuint32_t even, svuint64_t op1, uint64_t imm2) - /// UQSHRNT Ztied.S, Zop1.D, #imm2 - /// - public static Vector ShiftRightArithmeticNarrowingSaturateOdd(Vector even, Vector value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } - // Saturating shift right unsigned narrow (bottom) @@ -2038,6 +3814,481 @@ 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) + + /// + /// svuint8_t svsubhnb[_u16](svuint16_t op1, svuint16_t op2) + /// SUBHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector SubtractHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svsubhnb[_s32](svint32_t op1, svint32_t op2) + /// SUBHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector SubtractHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svsubhnb[_s64](svint64_t op1, svint64_t op2) + /// SUBHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector SubtractHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svsubhnb[_s16](svint16_t op1, svint16_t op2) + /// SUBHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector SubtractHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svsubhnb[_u32](svuint32_t op1, svuint32_t op2) + /// SUBHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector SubtractHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svsubhnb[_u64](svuint64_t op1, svuint64_t op2) + /// SUBHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector SubtractHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Subtract narrow high part (top) + + /// + /// svuint8_t svsubhnt[_u16](svuint8_t even, svuint16_t op1, svuint16_t op2) + /// SUBHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svsubhnt[_s32](svint16_t even, svint32_t op1, svint32_t op2) + /// SUBHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svsubhnt[_s64](svint32_t even, svint64_t op1, svint64_t op2) + /// SUBHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svsubhnt[_s16](svint8_t even, svint16_t op1, svint16_t op2) + /// SUBHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svsubhnt[_u32](svuint16_t even, svuint32_t op1, svuint32_t op2) + /// SUBHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svsubhnt[_u64](svuint32_t even, svuint64_t op1, svuint64_t op2) + /// SUBHNT Ztied.S, Zop1.D, Zop2.D + /// + 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 + + /// + /// svuint8_t svqsub[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svqsub[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svqsub[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UQSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UQSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UQSUBR Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// UQSUB Zresult.B, Zop1.B, Zop2.B + /// + public static new Vector SubtractSaturate(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svqsub[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svqsub[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svqsub[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SQSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SQSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SQSUBR Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// SQSUB Zresult.H, Zop1.H, Zop2.H + /// + public static new Vector SubtractSaturate(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svqsub[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svqsub[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svqsub[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SQSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SQSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SQSUBR Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// SQSUB Zresult.S, Zop1.S, Zop2.S + /// + public static new Vector SubtractSaturate(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svqsub[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svqsub[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svqsub[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SQSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SQSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SQSUBR Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// SQSUB Zresult.D, Zop1.D, Zop2.D + /// + public static new Vector SubtractSaturate(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svqsub[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svqsub[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svqsub[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SQSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SQSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SQSUBR Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// SQSUB Zresult.B, Zop1.B, Zop2.B + /// + public static new Vector SubtractSaturate(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svqsub[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svqsub[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svqsub[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UQSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UQSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UQSUBR Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// UQSUB Zresult.H, Zop1.H, Zop2.H + /// + public static new Vector SubtractSaturate(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svqsub[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svqsub[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svqsub[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UQSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UQSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UQSUBR Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// UQSUB Zresult.S, Zop1.S, Zop2.S + /// + public static new Vector SubtractSaturate(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svqsub[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svqsub[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svqsub[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UQSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UQSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UQSUBR Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// UQSUB Zresult.D, Zop1.D, Zop2.D + /// + public static new Vector SubtractSaturate(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Subtract wide (bottom) + + /// + /// svint16_t svsubwb[_s16](svint16_t op1, svint8_t op2) + /// SSUBWB Zresult.H, Zop1.H, Zop2.B + /// + public static Vector SubtractWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svsubwb[_s32](svint32_t op1, svint16_t op2) + /// SSUBWB Zresult.S, Zop1.S, Zop2.H + /// + public static Vector SubtractWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svsubwb[_s64](svint64_t op1, svint32_t op2) + /// SSUBWB Zresult.D, Zop1.D, Zop2.S + /// + public static Vector SubtractWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svsubwb[_u16](svuint16_t op1, svuint8_t op2) + /// USUBWB Zresult.H, Zop1.H, Zop2.B + /// + public static Vector SubtractWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svsubwb[_u32](svuint32_t op1, svuint16_t op2) + /// USUBWB Zresult.S, Zop1.S, Zop2.H + /// + public static Vector SubtractWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svsubwb[_u64](svuint64_t op1, svuint32_t op2) + /// USUBWB Zresult.D, Zop1.D, Zop2.S + /// + public static Vector SubtractWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Subtract long (bottom) + + /// + /// svint16_t svsublb[_s16](svint8_t op1, svint8_t op2) + /// SSUBLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector SubtractWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svsublb[_s32](svint16_t op1, svint16_t op2) + /// SSUBLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector SubtractWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svsublb[_s64](svint32_t op1, svint32_t op2) + /// SSUBLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector SubtractWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svsublb[_u16](svuint8_t op1, svuint8_t op2) + /// USUBLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector SubtractWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svsublb[_u32](svuint16_t op1, svuint16_t op2) + /// USUBLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector SubtractWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svsublb[_u64](svuint32_t op1, svuint32_t op2) + /// USUBLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector SubtractWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Subtract long (bottom - top) + + /// + /// svint16_t svsublbt[_s16](svint8_t op1, svint8_t op2) + /// SSUBLBT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector SubtractWideningEvenOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svsublbt[_s32](svint16_t op1, svint16_t op2) + /// SSUBLBT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector SubtractWideningEvenOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svsublbt[_s64](svint32_t op1, svint32_t op2) + /// SSUBLBT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector SubtractWideningEvenOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Subtract wide (top) + + /// + /// svint16_t svsubwt[_s16](svint16_t op1, svint8_t op2) + /// SSUBWT Zresult.H, Zop1.H, Zop2.B + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svsubwt[_s32](svint32_t op1, svint16_t op2) + /// SSUBWT Zresult.S, Zop1.S, Zop2.H + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svsubwt[_s64](svint64_t op1, svint32_t op2) + /// SSUBWT Zresult.D, Zop1.D, Zop2.S + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svsubwt[_u16](svuint16_t op1, svuint8_t op2) + /// USUBWT Zresult.H, Zop1.H, Zop2.B + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svsubwt[_u32](svuint32_t op1, svuint16_t op2) + /// USUBWT Zresult.S, Zop1.S, Zop2.H + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svsubwt[_u64](svuint64_t op1, svuint32_t op2) + /// USUBWT Zresult.D, Zop1.D, Zop2.S + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Subtract long (top) + + /// + /// svint16_t svsublt[_s16](svint8_t op1, svint8_t op2) + /// SSUBLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svsublt[_s32](svint16_t op1, svint16_t op2) + /// SSUBLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svsublt[_s64](svint32_t op1, svint32_t op2) + /// SSUBLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svsublt[_u16](svuint8_t op1, svuint8_t op2) + /// USUBLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svsublt[_u32](svuint16_t op1, svuint16_t op2) + /// USUBLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svsublt[_u64](svuint32_t op1, svuint32_t op2) + /// USUBLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Subtract long (top - bottom) + + /// + /// svint16_t svsubltb[_s16](svint8_t op1, svint8_t op2) + /// SSUBLTB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector SubtractWideningOddEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svsubltb[_s32](svint16_t op1, svint16_t op2) + /// SSUBLTB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector SubtractWideningOddEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svsubltb[_s64](svint32_t op1, svint32_t op2) + /// SSUBLTB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector SubtractWideningOddEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Bit vector table lookups /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs index 464a763d78c6bd..815909fa63c7fc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs @@ -28,6 +28,46 @@ internal Arm64() { } public static new bool IsSupported { get => IsSupported; } } + + // Saturating absolute value + + /// + /// svint8_t svqabs[_s8]_m(svint8_t inactive, svbool_t pg, svint8_t op) + /// svint8_t svqabs[_s8]_x(svbool_t pg, svint8_t op) + /// svint8_t svqabs[_s8]_z(svbool_t pg, svint8_t op) + /// SQABS Ztied.B, Pg/M, Zop.B + /// SQABS Ztied.B, Pg/M, Ztied.B + /// + public static Vector AbsSaturate(Vector value) => AbsSaturate(value); + + /// + /// svint16_t svqabs[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// svint16_t svqabs[_s16]_x(svbool_t pg, svint16_t op) + /// svint16_t svqabs[_s16]_z(svbool_t pg, svint16_t op) + /// SQABS Ztied.H, Pg/M, Zop.H + /// SQABS Ztied.H, Pg/M, Ztied.H + /// + public static Vector AbsSaturate(Vector value) => AbsSaturate(value); + + /// + /// svint32_t svqabs[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// svint32_t svqabs[_s32]_x(svbool_t pg, svint32_t op) + /// svint32_t svqabs[_s32]_z(svbool_t pg, svint32_t op) + /// SQABS Ztied.S, Pg/M, Zop.S + /// SQABS Ztied.S, Pg/M, Ztied.S + /// + public static Vector AbsSaturate(Vector value) => AbsSaturate(value); + + /// + /// svint64_t svqabs[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// svint64_t svqabs[_s64]_x(svbool_t pg, svint64_t op) + /// svint64_t svqabs[_s64]_z(svbool_t pg, svint64_t op) + /// SQABS Ztied.D, Pg/M, Zop.D + /// SQABS Ztied.D, Pg/M, Ztied.D + /// + public static Vector AbsSaturate(Vector value) => AbsSaturate(value); + + // Absolute difference and accumulate /// @@ -425,7 +465,7 @@ internal Arm64() { } /// SADALP Ztied1.H, Pg/M, Zop2.B /// SADALP Ztied1.H, Pg/M, Zop2.B /// - public static Vector AddPairwiseWidening(Vector left, Vector right) => AddPairwiseWidening(left, right); + public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) => AddPairwiseWideningAndAdd(left, right); /// /// svint32_t svadalp[_s32]_m(svbool_t pg, svint32_t op1, svint16_t op2) @@ -434,7 +474,7 @@ internal Arm64() { } /// SADALP Ztied1.S, Pg/M, Zop2.H /// SADALP Ztied1.S, Pg/M, Zop2.H /// - public static Vector AddPairwiseWidening(Vector left, Vector right) => AddPairwiseWidening(left, right); + public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) => AddPairwiseWideningAndAdd(left, right); /// /// svint64_t svadalp[_s64]_m(svbool_t pg, svint64_t op1, svint32_t op2) @@ -443,7 +483,7 @@ internal Arm64() { } /// SADALP Ztied1.D, Pg/M, Zop2.S /// SADALP Ztied1.D, Pg/M, Zop2.S /// - public static Vector AddPairwiseWidening(Vector left, Vector right) => AddPairwiseWidening(left, right); + public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) => AddPairwiseWideningAndAdd(left, right); /// /// svuint16_t svadalp[_u16]_m(svbool_t pg, svuint16_t op1, svuint8_t op2) @@ -452,7 +492,7 @@ internal Arm64() { } /// UADALP Ztied1.H, Pg/M, Zop2.B /// UADALP Ztied1.H, Pg/M, Zop2.B /// - public static Vector AddPairwiseWidening(Vector left, Vector right) => AddPairwiseWidening(left, right); + public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) => AddPairwiseWideningAndAdd(left, right); /// /// svuint32_t svadalp[_u32]_m(svbool_t pg, svuint32_t op1, svuint16_t op2) @@ -461,7 +501,7 @@ internal Arm64() { } /// UADALP Ztied1.S, Pg/M, Zop2.H /// UADALP Ztied1.S, Pg/M, Zop2.H /// - public static Vector AddPairwiseWidening(Vector left, Vector right) => AddPairwiseWidening(left, right); + public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) => AddPairwiseWideningAndAdd(left, right); /// /// svuint64_t svadalp[_u64]_m(svbool_t pg, svuint64_t op1, svuint32_t op2) @@ -470,7 +510,134 @@ internal Arm64() { } /// UADALP Ztied1.D, Pg/M, Zop2.S /// UADALP Ztied1.D, Pg/M, Zop2.S /// - public static Vector AddPairwiseWidening(Vector left, Vector right) => AddPairwiseWidening(left, right); + public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) => AddPairwiseWideningAndAdd(left, right); + + // Complex add with rotate + + /// + /// svuint8_t svcadd[_u8](svuint8_t op1, svuint8_t op2, uint64_t imm_rotation) + /// CADD Ztied1.B, Ztied1.B, Zop2.B, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddRotateComplex(left, right, rotation); + + /// + /// svint16_t svcadd[_s16](svint16_t op1, svint16_t op2, uint64_t imm_rotation) + /// CADD Ztied1.H, Ztied1.H, Zop2.H, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddRotateComplex(left, right, rotation); + + /// + /// svint32_t svcadd[_s32](svint32_t op1, svint32_t op2, uint64_t imm_rotation) + /// CADD Ztied1.S, Ztied1.S, Zop2.S, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddRotateComplex(left, right, rotation); + + /// + /// svint64_t svcadd[_s64](svint64_t op1, svint64_t op2, uint64_t imm_rotation) + /// CADD Ztied1.D, Ztied1.D, Zop2.D, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddRotateComplex(left, right, rotation); + + /// + /// svint8_t svcadd[_s8](svint8_t op1, svint8_t op2, uint64_t imm_rotation) + /// CADD Ztied1.B, Ztied1.B, Zop2.B, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddRotateComplex(left, right, rotation); + + /// + /// svuint16_t svcadd[_u16](svuint16_t op1, svuint16_t op2, uint64_t imm_rotation) + /// CADD Ztied1.H, Ztied1.H, Zop2.H, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddRotateComplex(left, right, rotation); + + /// + /// svuint32_t svcadd[_u32](svuint32_t op1, svuint32_t op2, uint64_t imm_rotation) + /// CADD Ztied1.S, Ztied1.S, Zop2.S, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddRotateComplex(left, right, rotation); + + /// + /// svuint64_t svcadd[_u64](svuint64_t op1, svuint64_t op2, uint64_t imm_rotation) + /// CADD Ztied1.D, Ztied1.D, Zop2.D, #imm_rotation + /// + public static Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddRotateComplex(left, right, rotation); + + // 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 @@ -555,6 +722,33 @@ internal Arm64() { } /// public static new Vector AddSaturate(Vector left, Vector right) => AddSaturate(left, right); + // Saturating complex add with rotate + + /// + /// svint16_t svqcadd[_s16](svint16_t op1, svint16_t op2, uint64_t imm_rotation) + /// SQCADD Ztied1.H, Ztied1.H, Zop2.H, #imm_rotation + /// + public static Vector AddSaturateRotateComplex(Vector op1, Vector op2, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddSaturateRotateComplex(op1, op2, rotation); + + /// + /// svint32_t svqcadd[_s32](svint32_t op1, svint32_t op2, uint64_t imm_rotation) + /// SQCADD Ztied1.S, Ztied1.S, Zop2.S, #imm_rotation + /// + public static Vector AddSaturateRotateComplex(Vector op1, Vector op2, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddSaturateRotateComplex(op1, op2, rotation); + + /// + /// svint64_t svqcadd[_s64](svint64_t op1, svint64_t op2, uint64_t imm_rotation) + /// SQCADD Ztied1.D, Ztied1.D, Zop2.D, #imm_rotation + /// + public static Vector AddSaturateRotateComplex(Vector op1, Vector op2, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddSaturateRotateComplex(op1, op2, rotation); + + /// + /// svint8_t svqcadd[_s8](svint8_t op1, svint8_t op2, uint64_t imm_rotation) + /// SQCADD Ztied1.B, Ztied1.B, Zop2.B, #imm_rotation + /// + public static Vector AddSaturateRotateComplex(Vector op1, Vector op2, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddSaturateRotateComplex(op1, op2, rotation); + + // Saturating add with signed addend /// @@ -637,113 +831,73 @@ internal Arm64() { } /// svint16_t svaddwb[_s16](svint16_t op1, svint8_t op2) /// SADDWB Zresult.H, Zop1.H, Zop2.B /// - public static Vector AddWideLower(Vector left, Vector right) => AddWideLower(left, right); + public static Vector AddWideningEven(Vector left, Vector right) => AddWideningEven(left, right); /// /// svint32_t svaddwb[_s32](svint32_t op1, svint16_t op2) /// SADDWB Zresult.S, Zop1.S, Zop2.H /// - public static Vector AddWideLower(Vector left, Vector right) => AddWideLower(left, right); + public static Vector AddWideningEven(Vector left, Vector right) => AddWideningEven(left, right); /// /// svint64_t svaddwb[_s64](svint64_t op1, svint32_t op2) /// SADDWB Zresult.D, Zop1.D, Zop2.S /// - public static Vector AddWideLower(Vector left, Vector right) => AddWideLower(left, right); + public static Vector AddWideningEven(Vector left, Vector right) => AddWideningEven(left, right); /// /// svuint16_t svaddwb[_u16](svuint16_t op1, svuint8_t op2) /// UADDWB Zresult.H, Zop1.H, Zop2.B /// - public static Vector AddWideLower(Vector left, Vector right) => AddWideLower(left, right); + public static Vector AddWideningEven(Vector left, Vector right) => AddWideningEven(left, right); /// /// svuint32_t svaddwb[_u32](svuint32_t op1, svuint16_t op2) /// UADDWB Zresult.S, Zop1.S, Zop2.H /// - public static Vector AddWideLower(Vector left, Vector right) => AddWideLower(left, right); + public static Vector AddWideningEven(Vector left, Vector right) => AddWideningEven(left, right); /// /// svuint64_t svaddwb[_u64](svuint64_t op1, svuint32_t op2) /// UADDWB Zresult.D, Zop1.D, Zop2.S /// - public static Vector AddWideLower(Vector left, Vector right) => AddWideLower(left, right); - - // Add wide (top) - - /// - /// svint16_t svaddwt[_s16](svint16_t op1, svint8_t op2) - /// SADDWT Zresult.H, Zop1.H, Zop2.B - /// - public static Vector AddWideUpper(Vector left, Vector right) => AddWideUpper(left, right); - - /// - /// svint32_t svaddwt[_s32](svint32_t op1, svint16_t op2) - /// SADDWT Zresult.S, Zop1.S, Zop2.H - /// - public static Vector AddWideUpper(Vector left, Vector right) => AddWideUpper(left, right); - - /// - /// svint64_t svaddwt[_s64](svint64_t op1, svint32_t op2) - /// SADDWT Zresult.D, Zop1.D, Zop2.S - /// - public static Vector AddWideUpper(Vector left, Vector right) => AddWideUpper(left, right); - - /// - /// svuint16_t svaddwt[_u16](svuint16_t op1, svuint8_t op2) - /// UADDWT Zresult.H, Zop1.H, Zop2.B - /// - public static Vector AddWideUpper(Vector left, Vector right) => AddWideUpper(left, right); - - /// - /// svuint32_t svaddwt[_u32](svuint32_t op1, svuint16_t op2) - /// UADDWT Zresult.S, Zop1.S, Zop2.H - /// - public static Vector AddWideUpper(Vector left, Vector right) => AddWideUpper(left, right); - - /// - /// svuint64_t svaddwt[_u64](svuint64_t op1, svuint32_t op2) - /// UADDWT Zresult.D, Zop1.D, Zop2.S - /// - public static Vector AddWideUpper(Vector left, Vector right) => AddWideUpper(left, right); - - // Add long (bottom) + public static Vector AddWideningEven(Vector left, Vector right) => AddWideningEven(left, right); /// /// svint16_t svaddlb[_s16](svint8_t op1, svint8_t op2) /// SADDLB Zresult.H, Zop1.B, Zop2.B /// - public static Vector AddWideningLower(Vector left, Vector right) => AddWideningLower(left, right); + public static Vector AddWideningEven(Vector left, Vector right) => AddWideningEven(left, right); /// /// svint32_t svaddlb[_s32](svint16_t op1, svint16_t op2) /// SADDLB Zresult.S, Zop1.H, Zop2.H /// - public static Vector AddWideningLower(Vector left, Vector right) => AddWideningLower(left, right); + public static Vector AddWideningEven(Vector left, Vector right) => AddWideningEven(left, right); /// /// svint64_t svaddlb[_s64](svint32_t op1, svint32_t op2) /// SADDLB Zresult.D, Zop1.S, Zop2.S /// - public static Vector AddWideningLower(Vector left, Vector right) => AddWideningLower(left, right); + public static Vector AddWideningEven(Vector left, Vector right) => AddWideningEven(left, right); /// /// svuint16_t svaddlb[_u16](svuint8_t op1, svuint8_t op2) /// UADDLB Zresult.H, Zop1.B, Zop2.B /// - public static Vector AddWideningLower(Vector left, Vector right) => AddWideningLower(left, right); + public static Vector AddWideningEven(Vector left, Vector right) => AddWideningEven(left, right); /// /// svuint32_t svaddlb[_u32](svuint16_t op1, svuint16_t op2) /// UADDLB Zresult.S, Zop1.H, Zop2.H /// - public static Vector AddWideningLower(Vector left, Vector right) => AddWideningLower(left, right); + public static Vector AddWideningEven(Vector left, Vector right) => AddWideningEven(left, right); /// /// svuint64_t svaddlb[_u64](svuint32_t op1, svuint32_t op2) /// UADDLB Zresult.D, Zop1.S, Zop2.S /// - public static Vector AddWideningLower(Vector left, Vector right) => AddWideningLower(left, right); + public static Vector AddWideningEven(Vector left, Vector right) => AddWideningEven(left, right); // Add long (bottom + top) @@ -751,57 +905,93 @@ internal Arm64() { } /// svint16_t svaddlbt[_s16](svint8_t op1, svint8_t op2) /// SADDLBT Zresult.H, Zop1.B, Zop2.B /// - public static Vector AddWideningLowerUpper(Vector left, Vector right) => AddWideningLowerUpper(left, right); + public static Vector AddWideningEvenOdd(Vector left, Vector right) => AddWideningEvenOdd(left, right); /// /// svint32_t svaddlbt[_s32](svint16_t op1, svint16_t op2) /// SADDLBT Zresult.S, Zop1.H, Zop2.H /// - public static Vector AddWideningLowerUpper(Vector left, Vector right) => AddWideningLowerUpper(left, right); + public static Vector AddWideningEvenOdd(Vector left, Vector right) => AddWideningEvenOdd(left, right); /// /// svint64_t svaddlbt[_s64](svint32_t op1, svint32_t op2) /// SADDLBT Zresult.D, Zop1.S, Zop2.S /// - public static Vector AddWideningLowerUpper(Vector left, Vector right) => AddWideningLowerUpper(left, right); + public static Vector AddWideningEvenOdd(Vector left, Vector right) => AddWideningEvenOdd(left, right); + + // Add wide (top) + + /// + /// svint16_t svaddwt[_s16](svint16_t op1, svint8_t op2) + /// SADDWT Zresult.H, Zop1.H, Zop2.B + /// + public static Vector AddWideningOdd(Vector left, Vector right) => AddWideningOdd(left, right); + + /// + /// svint32_t svaddwt[_s32](svint32_t op1, svint16_t op2) + /// SADDWT Zresult.S, Zop1.S, Zop2.H + /// + public static Vector AddWideningOdd(Vector left, Vector right) => AddWideningOdd(left, right); + + /// + /// svint64_t svaddwt[_s64](svint64_t op1, svint32_t op2) + /// SADDWT Zresult.D, Zop1.D, Zop2.S + /// + public static Vector AddWideningOdd(Vector left, Vector right) => AddWideningOdd(left, right); + + /// + /// svuint16_t svaddwt[_u16](svuint16_t op1, svuint8_t op2) + /// UADDWT Zresult.H, Zop1.H, Zop2.B + /// + public static Vector AddWideningOdd(Vector left, Vector right) => AddWideningOdd(left, right); + + /// + /// svuint32_t svaddwt[_u32](svuint32_t op1, svuint16_t op2) + /// UADDWT Zresult.S, Zop1.S, Zop2.H + /// + public static Vector AddWideningOdd(Vector left, Vector right) => AddWideningOdd(left, right); - // Add long (top) + /// + /// svuint64_t svaddwt[_u64](svuint64_t op1, svuint32_t op2) + /// UADDWT Zresult.D, Zop1.D, Zop2.S + /// + public static Vector AddWideningOdd(Vector left, Vector right) => AddWideningOdd(left, right); /// /// svint16_t svaddlt[_s16](svint8_t op1, svint8_t op2) /// SADDLT Zresult.H, Zop1.B, Zop2.B /// - public static Vector AddWideningUpper(Vector left, Vector right) => AddWideningUpper(left, right); + public static Vector AddWideningOdd(Vector left, Vector right) => AddWideningOdd(left, right); /// /// svint32_t svaddlt[_s32](svint16_t op1, svint16_t op2) /// SADDLT Zresult.S, Zop1.H, Zop2.H /// - public static Vector AddWideningUpper(Vector left, Vector right) => AddWideningUpper(left, right); + public static Vector AddWideningOdd(Vector left, Vector right) => AddWideningOdd(left, right); /// /// svint64_t svaddlt[_s64](svint32_t op1, svint32_t op2) /// SADDLT Zresult.D, Zop1.S, Zop2.S /// - public static Vector AddWideningUpper(Vector left, Vector right) => AddWideningUpper(left, right); + public static Vector AddWideningOdd(Vector left, Vector right) => AddWideningOdd(left, right); /// /// svuint16_t svaddlt[_u16](svuint8_t op1, svuint8_t op2) /// UADDLT Zresult.H, Zop1.B, Zop2.B /// - public static Vector AddWideningUpper(Vector left, Vector right) => AddWideningUpper(left, right); + public static Vector AddWideningOdd(Vector left, Vector right) => AddWideningOdd(left, right); /// /// svuint32_t svaddlt[_u32](svuint16_t op1, svuint16_t op2) /// UADDLT Zresult.S, Zop1.H, Zop2.H /// - public static Vector AddWideningUpper(Vector left, Vector right) => AddWideningUpper(left, right); + public static Vector AddWideningOdd(Vector left, Vector right) => AddWideningOdd(left, right); /// /// svuint64_t svaddlt[_u64](svuint32_t op1, svuint32_t op2) /// UADDLT Zresult.D, Zop1.S, Zop2.S /// - public static Vector AddWideningUpper(Vector left, Vector right) => AddWideningUpper(left, right); + public static Vector AddWideningOdd(Vector left, Vector right) => AddWideningOdd(left, right); // Bitwise clear and exclusive OR @@ -1006,6 +1196,269 @@ internal Arm64() { } /// public static Vector BitwiseSelectRightInverted(Vector select, Vector left, Vector right) => BitwiseSelectRightInverted(select, left, right); + // Complex dot product + + /// + /// svint32_t svcdot[_s32](svint32_t op1, svint8_t op2, svint8_t op3, uint64_t imm_rotation) + /// CDOT Ztied1.S, Zop2.B, Zop3.B, #imm_rotation + /// + public static Vector DotProductRotateComplex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => DotProductRotateComplex(op1, op2, op3, rotation); + + /// + /// svint64_t svcdot[_s64](svint64_t op1, svint16_t op2, svint16_t op3, uint64_t imm_rotation) + /// CDOT Ztied1.D, Zop2.H, Zop3.H, #imm_rotation + /// + public static Vector DotProductRotateComplex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => DotProductRotateComplex(op1, op2, op3, rotation); + + /// + /// svint32_t svcdot_lane[_s32](svint32_t op1, svint8_t op2, svint8_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// CDOT Ztied1.S, Zop2.B, Zop3.B[imm_index], #imm_rotation + /// + public static Vector DotProductRotateComplexBySelectedIndex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte imm_index, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => DotProductRotateComplexBySelectedIndex(op1, op2, op3, imm_index, rotation); + + /// + /// svint64_t svcdot_lane[_s64](svint64_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// CDOT Ztied1.D, Zop2.H, Zop3.H[imm_index], #imm_rotation + /// + public static Vector DotProductRotateComplexBySelectedIndex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(1))] byte imm_index, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => DotProductRotateComplexBySelectedIndex(op1, op2, op3, imm_index, rotation); + + // Up convert long (top) + + /// + /// svfloat64_t svcvtlt_f64[_f32]_m(svfloat64_t inactive, svbool_t pg, svfloat32_t op) + /// svfloat64_t svcvtlt_f64[_f32]_x(svbool_t pg, svfloat32_t op) + /// FCVTLT Ztied.D, Pg/M, Zop.S + /// FCVTLT Ztied.D, Pg/M, Ztied.S + /// + public static Vector ConvertToDoubleOdd(Vector value) => ConvertToDoubleOdd(value); + + // Down convert, rounding to odd + + /// + /// svfloat32_t svcvtx_f32[_f64]_m(svfloat32_t inactive, svbool_t pg, svfloat64_t op) + /// svfloat32_t svcvtx_f32[_f64]_x(svbool_t pg, svfloat64_t op) + /// svfloat32_t svcvtx_f32[_f64]_z(svbool_t pg, svfloat64_t op) + /// FCVTX Ztied.S, Pg/M, Zop.D + /// FCVTX Ztied.S, Pg/M, Ztied.D + /// + public static Vector ConvertToSingleEvenRoundToOdd(Vector value) => ConvertToSingleEvenRoundToOdd(value); + + // Halving add + + /// + /// svuint8_t svhadd[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhadd[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhadd[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHADD Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svint16_t svhadd[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhadd[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhadd[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHADD Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svint32_t svhadd[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhadd[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhadd[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHADD Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svint64_t svhadd[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhadd[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhadd[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHADD Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svint8_t svhadd[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhadd[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhadd[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHADD Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svuint16_t svhadd[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhadd[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhadd[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHADD Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svuint32_t svhadd[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhadd[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhadd[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHADD Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svuint64_t svhadd[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhadd[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhadd[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHADD Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + // Halving subtract + + /// + /// svuint8_t svhsub[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhsub[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhsub[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHSUBR Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svint16_t svhsub[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhsub[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhsub[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHSUBR Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svint32_t svhsub[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhsub[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhsub[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHSUBR Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svint64_t svhsub[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhsub[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhsub[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHSUBR Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svint8_t svhsub[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhsub[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhsub[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHSUBR Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svuint16_t svhsub[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhsub[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhsub[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHSUBR Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svuint32_t svhsub[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhsub[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhsub[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHSUBR Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svuint64_t svhsub[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhsub[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhsub[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHSUBR Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + 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 /// @@ -1104,8 +1557,1391 @@ internal Arm64() { } /// public static Vector InterleavingXorOddEven(Vector even, Vector left, Vector right) => InterleavingXorOddEven(even, left, right); + // Base 2 logarithm as integer - // Rounding shift left + /// + /// svint32_t svlogb[_f32]_m(svint32_t inactive, svbool_t pg, svfloat32_t op) + /// svint32_t svlogb[_f32]_x(svbool_t pg, svfloat32_t op) + /// svint32_t svlogb[_f32]_z(svbool_t pg, svfloat32_t op) + /// FLOGB Ztied.S, Pg/M, Zop.S + /// FLOGB Ztied.S, Pg/M, Ztied.S + /// + public static Vector Log2(Vector value) => Log2(value); + + /// + /// svint64_t svlogb[_f64]_m(svint64_t inactive, svbool_t pg, svfloat64_t op) + /// svint64_t svlogb[_f64]_x(svbool_t pg, svfloat64_t op) + /// svint64_t svlogb[_f64]_z(svbool_t pg, svfloat64_t op) + /// FLOGB Ztied.D, Pg/M, Zop.D + /// FLOGB Ztied.D, Pg/M, Ztied.D + /// + public static Vector Log2(Vector value) => Log2(value); + + // Maximum number pairwise + + /// + /// svfloat64_t svmaxnmp[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmaxnmp[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMAXNMP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMAXNMP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MaxNumberPairwise(Vector left, Vector right) => MaxNumberPairwise(left, right); + + /// + /// svfloat32_t svmaxnmp[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmaxnmp[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMAXNMP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMAXNMP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MaxNumberPairwise(Vector left, Vector right) => MaxNumberPairwise(left, right); + + // Maximum pairwise + + /// + /// svuint8_t svmaxp[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svmaxp[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UMAXP Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UMAXP Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector MaxPairwise(Vector left, Vector right) => MaxPairwise(left, right); + + /// + /// svfloat64_t svmaxp[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmaxp[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMAXP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMAXP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MaxPairwise(Vector left, Vector right) => MaxPairwise(left, right); + + /// + /// svint16_t svmaxp[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svmaxp[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// SMAXP Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SMAXP Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector MaxPairwise(Vector left, Vector right) => MaxPairwise(left, right); + + /// + /// svint32_t svmaxp[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svmaxp[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// SMAXP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SMAXP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MaxPairwise(Vector left, Vector right) => MaxPairwise(left, right); + + /// + /// svint64_t svmaxp[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svmaxp[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// SMAXP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SMAXP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MaxPairwise(Vector left, Vector right) => MaxPairwise(left, right); + + /// + /// svint8_t svmaxp[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svmaxp[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// SMAXP Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SMAXP Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector MaxPairwise(Vector left, Vector right) => MaxPairwise(left, right); + + /// + /// svfloat32_t svmaxp[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmaxp[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMAXP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMAXP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MaxPairwise(Vector left, Vector right) => MaxPairwise(left, right); + + /// + /// svuint16_t svmaxp[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svmaxp[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UMAXP Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UMAXP Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector MaxPairwise(Vector left, Vector right) => MaxPairwise(left, right); + + /// + /// svuint32_t svmaxp[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svmaxp[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UMAXP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UMAXP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MaxPairwise(Vector left, Vector right) => MaxPairwise(left, right); + + /// + /// svuint64_t svmaxp[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svmaxp[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UMAXP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UMAXP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MaxPairwise(Vector left, Vector right) => MaxPairwise(left, right); + + // Minimum number pairwise + + /// + /// svfloat64_t svminnmp[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svminnmp[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMINNMP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMINNMP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MinNumberPairwise(Vector left, Vector right) => MinNumberPairwise(left, right); + + /// + /// svfloat32_t svminnmp[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svminnmp[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMINNMP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMINNMP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MinNumberPairwise(Vector left, Vector right) => MinNumberPairwise(left, right); + + // Minimum pairwise + + /// + /// svuint8_t svminp[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svminp[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UMINP Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UMINP Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector MinPairwise(Vector left, Vector right) => MinPairwise(left, right); + + /// + /// svfloat64_t svminp[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svminp[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMINP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMINP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MinPairwise(Vector left, Vector right) => MinPairwise(left, right); + + /// + /// svint16_t svminp[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svminp[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// SMINP Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SMINP Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector MinPairwise(Vector left, Vector right) => MinPairwise(left, right); + + /// + /// svint32_t svminp[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svminp[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// SMINP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SMINP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MinPairwise(Vector left, Vector right) => MinPairwise(left, right); + + /// + /// svint64_t svminp[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svminp[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// SMINP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SMINP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MinPairwise(Vector left, Vector right) => MinPairwise(left, right); + + /// + /// svint8_t svminp[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svminp[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// SMINP Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SMINP Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector MinPairwise(Vector left, Vector right) => MinPairwise(left, right); + + /// + /// svfloat32_t svminp[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svminp[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMINP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMINP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MinPairwise(Vector left, Vector right) => MinPairwise(left, right); + + /// + /// svuint16_t svminp[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svminp[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UMINP Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UMINP Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector MinPairwise(Vector left, Vector right) => MinPairwise(left, right); + + /// + /// svuint32_t svminp[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svminp[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UMINP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UMINP Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector MinPairwise(Vector left, Vector right) => MinPairwise(left, right); + + /// + /// svuint64_t svminp[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svminp[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UMINP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UMINP Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector MinPairwise(Vector left, Vector right) => MinPairwise(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); + + // Complex multiply-add with rotate + + /// + /// svuint8_t svcmla[_u8](svuint8_t op1, svuint8_t op2, svuint8_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.B, Zop2.B, Zop3.B, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplex(addend, left, right, rotation); + + /// + /// svint16_t svcmla[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.H, Zop2.H, Zop3.H, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplex(addend, left, right, rotation); + + /// + /// svint32_t svcmla[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.S, Zop2.S, Zop3.S, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplex(addend, left, right, rotation); + + /// + /// svint64_t svcmla[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.D, Zop2.D, Zop3.D, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplex(addend, left, right, rotation); + + /// + /// svint8_t svcmla[_s8](svint8_t op1, svint8_t op2, svint8_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.B, Zop2.B, Zop3.B, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplex(addend, left, right, rotation); + + /// + /// svuint16_t svcmla[_u16](svuint16_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.H, Zop2.H, Zop3.H, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplex(addend, left, right, rotation); + + /// + /// svuint32_t svcmla[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.S, Zop2.S, Zop3.S, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplex(addend, left, right, rotation); + + /// + /// svuint64_t svcmla[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3, uint64_t imm_rotation) + /// CMLA Ztied1.D, Zop2.D, Zop3.D, #imm_rotation + /// + public static Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplex(addend, left, right, rotation); + + // Complex multiply-add with rotate + + /// + /// svint16_t svcmla_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// CMLA Ztied1.H, Zop2.H, Zop3.H[imm_index], #imm_rotation + /// + public static Vector MultiplyAddRotateComplexBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rightIndex, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplexBySelectedScalar(addend, left, right, rightIndex, rotation); + + /// + /// svint32_t svcmla_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// CMLA Ztied1.S, Zop2.S, Zop3.S[imm_index], #imm_rotation + /// + public static Vector MultiplyAddRotateComplexBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rightIndex, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplexBySelectedScalar(addend, left, right, rightIndex, rotation); + + /// + /// svuint16_t svcmla_lane[_u16](svuint16_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// CMLA Ztied1.H, Zop2.H, Zop3.H[imm_index], #imm_rotation + /// + public static Vector MultiplyAddRotateComplexBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rightIndex, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplexBySelectedScalar(addend, left, right, rightIndex, rotation); + + /// + /// svuint32_t svcmla_lane[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// CMLA Ztied1.S, Zop2.S, Zop3.S[imm_index], #imm_rotation + /// + public static Vector MultiplyAddRotateComplexBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rightIndex, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplexBySelectedScalar(addend, left, right, rightIndex, rotation); + + // Saturating rounding doubling complex multiply-add high with rotate + + /// + /// svint16_t svqrdcmlah[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_rotation) + /// SQRDCMLAH Ztied1.H, Zop2.H, Zop3.H, #imm_rotation + /// + public static Vector MultiplyAddRoundedDoublingSaturateHighRotateComplex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRoundedDoublingSaturateHighRotateComplex(op1, op2, op3, rotation); + + /// + /// svint32_t svqrdcmlah[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_rotation) + /// SQRDCMLAH Ztied1.S, Zop2.S, Zop3.S, #imm_rotation + /// + public static Vector MultiplyAddRoundedDoublingSaturateHighRotateComplex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRoundedDoublingSaturateHighRotateComplex(op1, op2, op3, rotation); + + /// + /// svint64_t svqrdcmlah[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_rotation) + /// SQRDCMLAH Ztied1.D, Zop2.D, Zop3.D, #imm_rotation + /// + public static Vector MultiplyAddRoundedDoublingSaturateHighRotateComplex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRoundedDoublingSaturateHighRotateComplex(op1, op2, op3, rotation); + + /// + /// svint8_t svqrdcmlah[_s8](svint8_t op1, svint8_t op2, svint8_t op3, uint64_t imm_rotation) + /// SQRDCMLAH Ztied1.B, Zop2.B, Zop3.B, #imm_rotation + /// + public static Vector MultiplyAddRoundedDoublingSaturateHighRotateComplex(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRoundedDoublingSaturateHighRotateComplex(op1, op2, op3, rotation); + + /// + /// svint16_t svqrdcmlah_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// SQRDCMLAH Ztied1.H, Zop2.H, Zop3.H[imm_index], #imm_rotation + /// + public static Vector MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte imm_index, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(op1, op2, op3, imm_index, rotation); + + /// + /// svint32_t svqrdcmlah_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index, uint64_t imm_rotation) + /// SQRDCMLAH Ztied1.S, Zop2.S, Zop3.S[imm_index], #imm_rotation + /// + public static Vector MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(Vector op1, Vector op2, Vector op3, [ConstantExpected(Min = 0, Max = (byte)(1))] byte imm_index, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(op1, op2, op3, imm_index, rotation); + + + // 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); + + + // Saturating doubling multiply high with index + + /// + /// svint16_t svqdmulh_lane[_s16](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SQDMULH Zresult.H, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyDoublingBySelectedScalarSaturateHigh(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingBySelectedScalarSaturateHigh(left, right, rightIndex); + + /// + /// svint32_t svqdmulh_lane[_s32](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SQDMULH Zresult.S, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyDoublingBySelectedScalarSaturateHigh(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingBySelectedScalarSaturateHigh(left, right, rightIndex); + + /// + /// svint64_t svqdmulh_lane[_s64](svint64_t op1, svint64_t op2, uint64_t imm_index) + /// SQDMULH Zresult.D, Zop1.D, Zop2.D[imm_index] + /// + public static Vector MultiplyDoublingBySelectedScalarSaturateHigh(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingBySelectedScalarSaturateHigh(left, right, rightIndex); + + + // Saturating doubling multiply high + + /// + /// svint8_t svqdmulh[_s8](svint8_t op1, svint8_t op2) + /// SQDMULH Zresult.B, Zop1.B, Zop2.B + /// + public static Vector MultiplyDoublingSaturateHigh(Vector left, Vector right) => MultiplyDoublingSaturateHigh(left, right); + + /// + /// svint16_t svqdmulh[_s16](svint16_t op1, svint16_t op2) + /// SQDMULH Zresult.H, Zop1.H, Zop2.H + /// + public static Vector MultiplyDoublingSaturateHigh(Vector left, Vector right) => MultiplyDoublingSaturateHigh(left, right); + + /// + /// svint32_t svqdmulh[_s32](svint32_t op1, svint32_t op2) + /// SQDMULH Zresult.S, Zop1.S, Zop2.S + /// + public static Vector MultiplyDoublingSaturateHigh(Vector left, Vector right) => MultiplyDoublingSaturateHigh(left, right); + + /// + /// svint64_t svqdmulh[_s64](svint64_t op1, svint64_t op2) + /// SQDMULH Zresult.D, Zop1.D, Zop2.D + /// + public static Vector MultiplyDoublingSaturateHigh(Vector left, Vector right) => MultiplyDoublingSaturateHigh(left, right); + + + // 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); + + + // Saturating doubling multiply-add long (bottom) + + /// + /// svint16_t svqdmlalb[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SQDMLALB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyDoublingWideningAndAddSaturateEven(Vector addend, Vector left, Vector right) => MultiplyDoublingWideningAndAddSaturateEven(addend, left, right); + + /// + /// svint32_t svqdmlalb[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SQDMLALB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyDoublingWideningAndAddSaturateEven(Vector addend, Vector left, Vector right) => MultiplyDoublingWideningAndAddSaturateEven(addend, left, right); + + /// + /// svint64_t svqdmlalb[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SQDMLALB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyDoublingWideningAndAddSaturateEven(Vector addend, Vector left, Vector right) => MultiplyDoublingWideningAndAddSaturateEven(addend, left, right); + + + // Saturating doubling multiply-add long (bottom × top) + + /// + /// svint16_t svqdmlalbt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SQDMLALBT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyDoublingWideningAndAddSaturateEvenOdd(Vector addend, Vector leftEven, Vector rightOdd) => MultiplyDoublingWideningAndAddSaturateEvenOdd(addend, leftEven, rightOdd); + + /// + /// svint32_t svqdmlalbt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SQDMLALBT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyDoublingWideningAndAddSaturateEvenOdd(Vector addend, Vector leftEven, Vector rightOdd) => MultiplyDoublingWideningAndAddSaturateEvenOdd(addend, leftEven, rightOdd); + + /// + /// svint64_t svqdmlalbt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SQDMLALBT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyDoublingWideningAndAddSaturateEvenOdd(Vector addend, Vector leftEven, Vector rightOdd) => MultiplyDoublingWideningAndAddSaturateEvenOdd(addend, leftEven, rightOdd); + + + // Saturating doubling multiply-add long (top) + + /// + /// svint16_t svqdmlalt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SQDMLALT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyDoublingWideningAndAddSaturateOdd(Vector addend, Vector left, Vector right) => MultiplyDoublingWideningAndAddSaturateOdd(addend, left, right); + + /// + /// svint32_t svqdmlalt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SQDMLALT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyDoublingWideningAndAddSaturateOdd(Vector addend, Vector left, Vector right) => MultiplyDoublingWideningAndAddSaturateOdd(addend, left, right); + + /// + /// svint64_t svqdmlalt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SQDMLALT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyDoublingWideningAndAddSaturateOdd(Vector addend, Vector left, Vector right) => MultiplyDoublingWideningAndAddSaturateOdd(addend, left, right); + + + // Saturating doubling multiply-subtract long (bottom) + + /// + /// svint16_t svqdmlslb[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SQDMLSLB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateEven(Vector minuend, Vector left, Vector right) => MultiplyDoublingWideningAndSubtractSaturateEven(minuend, left, right); + + /// + /// svint32_t svqdmlslb[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SQDMLSLB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateEven(Vector minuend, Vector left, Vector right) => MultiplyDoublingWideningAndSubtractSaturateEven(minuend, left, right); + + /// + /// svint64_t svqdmlslb[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SQDMLSLB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateEven(Vector minuend, Vector left, Vector right) => MultiplyDoublingWideningAndSubtractSaturateEven(minuend, left, right); + + + // Saturating doubling multiply-subtract long (bottom × top) + + /// + /// svint16_t svqdmlslbt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SQDMLSLBT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateEvenOdd(Vector minuend, Vector leftEven, Vector rightOdd) => MultiplyDoublingWideningAndSubtractSaturateEvenOdd(minuend, leftEven, rightOdd); + + /// + /// svint32_t svqdmlslbt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SQDMLSLBT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateEvenOdd(Vector minuend, Vector leftEven, Vector rightOdd) => MultiplyDoublingWideningAndSubtractSaturateEvenOdd(minuend, leftEven, rightOdd); + + /// + /// svint64_t svqdmlslbt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SQDMLSLBT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateEvenOdd(Vector minuend, Vector leftEven, Vector rightOdd) => MultiplyDoublingWideningAndSubtractSaturateEvenOdd(minuend, leftEven, rightOdd); + + + // Saturating doubling multiply-subtract long (top) + + /// + /// svint16_t svqdmlslt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SQDMLSLT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateOdd(Vector minuend, Vector left, Vector right) => MultiplyDoublingWideningAndSubtractSaturateOdd(minuend, left, right); + + /// + /// svint32_t svqdmlslt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SQDMLSLT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateOdd(Vector minuend, Vector left, Vector right) => MultiplyDoublingWideningAndSubtractSaturateOdd(minuend, left, right); + + /// + /// svint64_t svqdmlslt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SQDMLSLT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyDoublingWideningAndSubtractSaturateOdd(Vector minuend, Vector left, Vector right) => MultiplyDoublingWideningAndSubtractSaturateOdd(minuend, left, right); + + + // Saturating doubling multiply-add long with index (bottom) + + /// + /// svint32_t svqdmlalb_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SQDMLALB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven(addend, left, right, rightIndex); + + /// + /// svint64_t svqdmlalb_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SQDMLALB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven(addend, left, right, rightIndex); + + + // Saturating doubling multiply-add long with index (top) + + /// + /// svint32_t svqdmlalt_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SQDMLALT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd(addend, left, right, rightIndex); + + /// + /// svint64_t svqdmlalt_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SQDMLALT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd(addend, left, right, rightIndex); + + + // Saturating doubling multiply-subtract long with index (bottom) + + /// + /// svint32_t svqdmlslb_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SQDMLSLB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven(minuend, left, right, rightIndex); + + /// + /// svint64_t svqdmlslb_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SQDMLSLB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven(minuend, left, right, rightIndex); + + + // Saturating doubling multiply-subtract long (top) + + /// + /// svint32_t svqdmlslt_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SQDMLSLT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd(minuend, left, right, rightIndex); + + /// + /// svint64_t svqdmlslt_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SQDMLSLT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd(minuend, left, right, rightIndex); + + + // Saturating doubling multiply long (bottom) + + /// + /// svint16_t svqdmullb[_s16](svint8_t op1, svint8_t op2) + /// SQDMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyDoublingWideningSaturateEven(Vector left, Vector right) => MultiplyDoublingWideningSaturateEven(left, right); + + /// + /// svint32_t svqdmullb[_s32](svint16_t op1, svint16_t op2) + /// SQDMULLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyDoublingWideningSaturateEven(Vector left, Vector right) => MultiplyDoublingWideningSaturateEven(left, right); + + /// + /// svint64_t svqdmullb[_s64](svint32_t op1, svint32_t op2) + /// SQDMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyDoublingWideningSaturateEven(Vector left, Vector right) => MultiplyDoublingWideningSaturateEven(left, right); + + + // Saturating doubling multiply long with index (bottom) + + /// + /// svint32_t svqdmullb_lane[_s32](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SQDMULLB Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyDoublingWideningSaturateEvenBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingWideningSaturateEvenBySelectedScalar(left, right, rightIndex); + + /// + /// svint64_t svqdmullb_lane[_s64](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SQDMULLB Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyDoublingWideningSaturateEvenBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingWideningSaturateEvenBySelectedScalar(left, right, rightIndex); + + + // Saturating doubling multiply long (top) + + /// + /// svint16_t svqdmullt[_s16](svint8_t op1, svint8_t op2) + /// SQDMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyDoublingWideningSaturateOdd(Vector left, Vector right) => MultiplyDoublingWideningSaturateOdd(left, right); + + /// + /// svint32_t svqdmullt[_s32](svint16_t op1, svint16_t op2) + /// SQDMULLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyDoublingWideningSaturateOdd(Vector left, Vector right) => MultiplyDoublingWideningSaturateOdd(left, right); + + /// + /// svint64_t svqdmullt[_s64](svint32_t op1, svint32_t op2) + /// SQDMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyDoublingWideningSaturateOdd(Vector left, Vector right) => MultiplyDoublingWideningSaturateOdd(left, right); + + + // Saturating doubling multiply long with index (top) + + /// + /// svint32_t svqdmullt_lane[_s32](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SQDMULLT Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyDoublingWideningSaturateOddBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingWideningSaturateOddBySelectedScalar(left, right, rightIndex); + + /// + /// svint64_t svqdmullt_lane[_s64](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SQDMULLT Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyDoublingWideningSaturateOddBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyDoublingWideningSaturateOddBySelectedScalar(left, right, rightIndex); + + + // Saturating rounding doubling multiply high with index + + /// + /// svint16_t svqrdmulh_lane[_s16](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SQRDMULH Zresult.H, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyRoundedDoublingBySelectedScalarSaturateHigh(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyRoundedDoublingBySelectedScalarSaturateHigh(left, right, rightIndex); + + /// + /// svint32_t svqrdmulh_lane[_s32](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SQRDMULH Zresult.S, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyRoundedDoublingBySelectedScalarSaturateHigh(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyRoundedDoublingBySelectedScalarSaturateHigh(left, right, rightIndex); + + /// + /// svint64_t svqrdmulh_lane[_s64](svint64_t op1, svint64_t op2, uint64_t imm_index) + /// SQRDMULH Zresult.D, Zop1.D, Zop2.D[imm_index] + /// + public static Vector MultiplyRoundedDoublingBySelectedScalarSaturateHigh(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyRoundedDoublingBySelectedScalarSaturateHigh(left, right, rightIndex); + + + // Saturating rounding doubling multiply-add high + + /// + /// svint8_t svqrdmlah[_s8](svint8_t op1, svint8_t op2, svint8_t op3) + /// SQRDMLAH Ztied1.B, Zop2.B, Zop3.B + /// + public static Vector MultiplyRoundedDoublingSaturateAndAddHigh(Vector addend, Vector left, Vector right) => MultiplyRoundedDoublingSaturateAndAddHigh(addend, left, right); + + /// + /// svint16_t svqrdmlah[_s16](svint16_t op1, svint16_t op2, svint16_t op3) + /// SQRDMLAH Ztied1.H, Zop2.H, Zop3.H + /// + public static Vector MultiplyRoundedDoublingSaturateAndAddHigh(Vector addend, Vector left, Vector right) => MultiplyRoundedDoublingSaturateAndAddHigh(addend, left, right); + + /// + /// svint32_t svqrdmlah[_s32](svint32_t op1, svint32_t op2, svint32_t op3) + /// SQRDMLAH Ztied1.S, Zop2.S, Zop3.S + /// + public static Vector MultiplyRoundedDoublingSaturateAndAddHigh(Vector addend, Vector left, Vector right) => MultiplyRoundedDoublingSaturateAndAddHigh(addend, left, right); + + /// + /// svint64_t svqrdmlah[_s64](svint64_t op1, svint64_t op2, svint64_t op3) + /// SQRDMLAH Ztied1.D, Zop2.D, Zop3.D + /// + public static Vector MultiplyRoundedDoublingSaturateAndAddHigh(Vector addend, Vector left, Vector right) => MultiplyRoundedDoublingSaturateAndAddHigh(addend, left, right); + + + // Saturating rounding doubling multiply-subtract high + + /// + /// svint8_t svqrdmlsh[_s8](svint8_t op1, svint8_t op2, svint8_t op3) + /// SQRDMLSH Ztied1.B, Zop2.B, Zop3.B + /// + public static Vector MultiplyRoundedDoublingSaturateAndSubtractHigh(Vector minuend, Vector left, Vector right) => MultiplyRoundedDoublingSaturateAndSubtractHigh(minuend, left, right); + + /// + /// svint16_t svqrdmlsh[_s16](svint16_t op1, svint16_t op2, svint16_t op3) + /// SQRDMLSH Ztied1.H, Zop2.H, Zop3.H + /// + public static Vector MultiplyRoundedDoublingSaturateAndSubtractHigh(Vector minuend, Vector left, Vector right) => MultiplyRoundedDoublingSaturateAndSubtractHigh(minuend, left, right); + + /// + /// svint32_t svqrdmlsh[_s32](svint32_t op1, svint32_t op2, svint32_t op3) + /// SQRDMLSH Ztied1.S, Zop2.S, Zop3.S + /// + public static Vector MultiplyRoundedDoublingSaturateAndSubtractHigh(Vector minuend, Vector left, Vector right) => MultiplyRoundedDoublingSaturateAndSubtractHigh(minuend, left, right); + + /// + /// svint64_t svqrdmlsh[_s64](svint64_t op1, svint64_t op2, svint64_t op3) + /// SQRDMLSH Ztied1.D, Zop2.D, Zop3.D + /// + public static Vector MultiplyRoundedDoublingSaturateAndSubtractHigh(Vector minuend, Vector left, Vector right) => MultiplyRoundedDoublingSaturateAndSubtractHigh(minuend, left, right); + + + // Saturating rounding doubling multiply-add high with index + + /// + /// svint16_t svqrdmlah_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SQRDMLAH Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh(addend, left, right, rightIndex); + + /// + /// svint32_t svqrdmlah_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SQRDMLAH Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh(addend, left, right, rightIndex); + + /// + /// svint64_t svqrdmlah_lane[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_index) + /// SQRDMLAH Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh(addend, left, right, rightIndex); + + + // Saturating rounding doubling multiply-subtract high with index + + /// + /// svint16_t svqrdmlsh_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SQRDMLSH Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh(minuend, left, right, rightIndex); + + /// + /// svint32_t svqrdmlsh_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SQRDMLSH Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh(minuend, left, right, rightIndex); + + /// + /// svint64_t svqrdmlsh_lane[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_index) + /// SQRDMLSH Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh(minuend, left, right, rightIndex); + + + // Saturating rounding doubling multiply high + + /// + /// svint8_t svqrdmulh[_s8](svint8_t op1, svint8_t op2) + /// SQRDMULH Zresult.B, Zop1.B, Zop2.B + /// + public static Vector MultiplyRoundedDoublingSaturateHigh(Vector left, Vector right) => MultiplyRoundedDoublingSaturateHigh(left, right); + + /// + /// svint16_t svqrdmulh[_s16](svint16_t op1, svint16_t op2) + /// SQRDMULH Zresult.H, Zop1.H, Zop2.H + /// + public static Vector MultiplyRoundedDoublingSaturateHigh(Vector left, Vector right) => MultiplyRoundedDoublingSaturateHigh(left, right); + + /// + /// svint32_t svqrdmulh[_s32](svint32_t op1, svint32_t op2) + /// SQRDMULH Zresult.S, Zop1.S, Zop2.S + /// + public static Vector MultiplyRoundedDoublingSaturateHigh(Vector left, Vector right) => MultiplyRoundedDoublingSaturateHigh(left, right); + + /// + /// svint64_t svqrdmulh[_s64](svint64_t op1, svint64_t op2) + /// SQRDMULH Zresult.D, Zop1.D, Zop2.D + /// + public static Vector MultiplyRoundedDoublingSaturateHigh(Vector left, Vector right) => MultiplyRoundedDoublingSaturateHigh(left, right); + + + // Saturating negate + + /// + /// svint8_t svqneg[_s8]_m(svint8_t inactive, svbool_t pg, svint8_t op) + /// svint8_t svqneg[_s8]_x(svbool_t pg, svint8_t op) + /// svint8_t svqneg[_s8]_z(svbool_t pg, svint8_t op) + /// SQNEG Ztied.B, Pg/M, Zop.B + /// SQNEG Ztied.B, Pg/M, Ztied.B + /// + public static Vector NegateSaturate(Vector value) => NegateSaturate(value); + + /// + /// svint16_t svqneg[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// svint16_t svqneg[_s16]_x(svbool_t pg, svint16_t op) + /// svint16_t svqneg[_s16]_z(svbool_t pg, svint16_t op) + /// SQNEG Ztied.H, Pg/M, Zop.H + /// SQNEG Ztied.H, Pg/M, Ztied.H + /// + public static Vector NegateSaturate(Vector value) => NegateSaturate(value); + + /// + /// svint32_t svqneg[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// svint32_t svqneg[_s32]_x(svbool_t pg, svint32_t op) + /// svint32_t svqneg[_s32]_z(svbool_t pg, svint32_t op) + /// SQNEG Ztied.S, Pg/M, Zop.S + /// SQNEG Ztied.S, Pg/M, Ztied.S + /// + public static Vector NegateSaturate(Vector value) => NegateSaturate(value); + + /// + /// svint64_t svqneg[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// svint64_t svqneg[_s64]_x(svbool_t pg, svint64_t op) + /// svint64_t svqneg[_s64]_z(svbool_t pg, svint64_t op) + /// SQNEG Ztied.D, Pg/M, Zop.D + /// SQNEG Ztied.D, Pg/M, Ztied.D + /// + public static Vector NegateSaturate(Vector value) => NegateSaturate(value); + + // Reciprocal estimate + + /// + /// svuint32_t svrecpe[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// svuint32_t svrecpe[_u32]_x(svbool_t pg, svuint32_t op) + /// svuint32_t svrecpe[_u32]_z(svbool_t pg, svuint32_t op) + /// URECPE Ztied.S, Pg/M, Zop.S + /// URECPE Ztied.S, Pg/M, Ztied.S + /// + public static Vector ReciprocalEstimate(Vector value) => ReciprocalEstimate(value); + + // Reciprocal square root estimate + + /// + /// svuint32_t svrsqrte[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// svuint32_t svrsqrte[_u32]_x(svbool_t pg, svuint32_t op) + /// svuint32_t svrsqrte[_u32]_z(svbool_t pg, svuint32_t op) + /// URSQRTE Ztied.S, Pg/M, Zop.S + /// URSQRTE Ztied.S, Pg/M, Ztied.S + /// + public static Vector ReciprocalSqrtEstimate(Vector value) => ReciprocalSqrtEstimate(value); + + // Rounding shift left /// /// svint16_t svrshl[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) @@ -1503,12 +3339,6 @@ internal Arm64() { } // Saturating shift right narrow (bottom) - /// - /// svuint8_t svqshrnb[_n_u16](svuint16_t op1, uint64_t imm2) - /// UQSHRNB Zresult.B, Zop1.H, #imm2 - /// - public static Vector ShiftRightArithmeticNarrowingSaturateEven(Vector value, [ConstantExpected] byte count) => ShiftRightArithmeticNarrowingSaturateEven(value, count); - /// /// svint16_t svqshrnb[_n_s32](svint32_t op1, uint64_t imm2) /// SQSHRNB Zresult.H, Zop1.S, #imm2 @@ -1527,27 +3357,9 @@ internal Arm64() { } /// public static Vector ShiftRightArithmeticNarrowingSaturateEven(Vector value, [ConstantExpected] byte count) => ShiftRightArithmeticNarrowingSaturateEven(value, count); - /// - /// svuint16_t svqshrnb[_n_u32](svuint32_t op1, uint64_t imm2) - /// UQSHRNB Zresult.H, Zop1.S, #imm2 - /// - public static Vector ShiftRightArithmeticNarrowingSaturateEven(Vector value, [ConstantExpected] byte count) => ShiftRightArithmeticNarrowingSaturateEven(value, count); - - /// - /// svuint32_t svqshrnb[_n_u64](svuint64_t op1, uint64_t imm2) - /// UQSHRNB Zresult.S, Zop1.D, #imm2 - /// - public static Vector ShiftRightArithmeticNarrowingSaturateEven(Vector value, [ConstantExpected] byte count) => ShiftRightArithmeticNarrowingSaturateEven(value, count); - // Saturating shift right narrow (top) - /// - /// svuint8_t svqshrnt[_n_u16](svuint8_t even, svuint16_t op1, uint64_t imm2) - /// UQSHRNT Ztied.B, Zop1.H, #imm2 - /// - public static Vector ShiftRightArithmeticNarrowingSaturateOdd(Vector even, Vector value, [ConstantExpected] byte count) => ShiftRightArithmeticNarrowingSaturateOdd(even, value, count); - /// /// svint16_t svqshrnt[_n_s32](svint16_t even, svint32_t op1, uint64_t imm2) /// SQSHRNT Ztied.H, Zop1.S, #imm2 @@ -1566,18 +3378,6 @@ internal Arm64() { } /// public static Vector ShiftRightArithmeticNarrowingSaturateOdd(Vector even, Vector value, [ConstantExpected] byte count) => ShiftRightArithmeticNarrowingSaturateOdd(even, value, count); - /// - /// svuint16_t svqshrnt[_n_u32](svuint16_t even, svuint32_t op1, uint64_t imm2) - /// UQSHRNT Ztied.H, Zop1.S, #imm2 - /// - public static Vector ShiftRightArithmeticNarrowingSaturateOdd(Vector even, Vector value, [ConstantExpected] byte count) => ShiftRightArithmeticNarrowingSaturateOdd(even, value, count); - - /// - /// svuint32_t svqshrnt[_n_u64](svuint32_t even, svuint64_t op1, uint64_t imm2) - /// UQSHRNT Ztied.S, Zop1.D, #imm2 - /// - public static Vector ShiftRightArithmeticNarrowingSaturateOdd(Vector even, Vector value, [ConstantExpected] byte count) => ShiftRightArithmeticNarrowingSaturateOdd(even, value, count); - // Saturating shift right unsigned narrow (bottom) @@ -2038,6 +3838,481 @@ 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) + + /// + /// svuint8_t svsubhnb[_u16](svuint16_t op1, svuint16_t op2) + /// SUBHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector SubtractHighNarrowingEven(Vector left, Vector right) => SubtractHighNarrowingEven(left, right); + + /// + /// svint16_t svsubhnb[_s32](svint32_t op1, svint32_t op2) + /// SUBHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector SubtractHighNarrowingEven(Vector left, Vector right) => SubtractHighNarrowingEven(left, right); + + /// + /// svint32_t svsubhnb[_s64](svint64_t op1, svint64_t op2) + /// SUBHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector SubtractHighNarrowingEven(Vector left, Vector right) => SubtractHighNarrowingEven(left, right); + + /// + /// svint8_t svsubhnb[_s16](svint16_t op1, svint16_t op2) + /// SUBHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector SubtractHighNarrowingEven(Vector left, Vector right) => SubtractHighNarrowingEven(left, right); + + /// + /// svuint16_t svsubhnb[_u32](svuint32_t op1, svuint32_t op2) + /// SUBHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector SubtractHighNarrowingEven(Vector left, Vector right) => SubtractHighNarrowingEven(left, right); + + /// + /// svuint32_t svsubhnb[_u64](svuint64_t op1, svuint64_t op2) + /// SUBHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector SubtractHighNarrowingEven(Vector left, Vector right) => SubtractHighNarrowingEven(left, right); + + + // Subtract narrow high part (top) + + /// + /// svuint8_t svsubhnt[_u16](svuint8_t even, svuint16_t op1, svuint16_t op2) + /// SUBHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractHighNarrowingOdd(even, left, right); + + /// + /// svint16_t svsubhnt[_s32](svint16_t even, svint32_t op1, svint32_t op2) + /// SUBHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractHighNarrowingOdd(even, left, right); + + /// + /// svint32_t svsubhnt[_s64](svint32_t even, svint64_t op1, svint64_t op2) + /// SUBHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractHighNarrowingOdd(even, left, right); + + /// + /// svint8_t svsubhnt[_s16](svint8_t even, svint16_t op1, svint16_t op2) + /// SUBHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractHighNarrowingOdd(even, left, right); + + /// + /// svuint16_t svsubhnt[_u32](svuint16_t even, svuint32_t op1, svuint32_t op2) + /// SUBHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractHighNarrowingOdd(even, left, right); + + /// + /// svuint32_t svsubhnt[_u64](svuint32_t even, svuint64_t op1, svuint64_t op2) + /// SUBHNT Ztied.S, Zop1.D, Zop2.D + /// + 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 + + /// + /// svuint8_t svqsub[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svqsub[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svqsub[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UQSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UQSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UQSUBR Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// UQSUB Zresult.B, Zop1.B, Zop2.B + /// + public static new Vector SubtractSaturate(Vector left, Vector right) => SubtractSaturate(left, right); + + /// + /// svint16_t svqsub[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svqsub[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svqsub[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SQSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SQSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SQSUBR Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// SQSUB Zresult.H, Zop1.H, Zop2.H + /// + public static new Vector SubtractSaturate(Vector left, Vector right) => SubtractSaturate(left, right); + + /// + /// svint32_t svqsub[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svqsub[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svqsub[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SQSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SQSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SQSUBR Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// SQSUB Zresult.S, Zop1.S, Zop2.S + /// + public static new Vector SubtractSaturate(Vector left, Vector right) => SubtractSaturate(left, right); + + /// + /// svint64_t svqsub[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svqsub[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svqsub[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SQSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SQSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SQSUBR Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// SQSUB Zresult.D, Zop1.D, Zop2.D + /// + public static new Vector SubtractSaturate(Vector left, Vector right) => SubtractSaturate(left, right); + + /// + /// svint8_t svqsub[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svqsub[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svqsub[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SQSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SQSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SQSUBR Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// SQSUB Zresult.B, Zop1.B, Zop2.B + /// + public static new Vector SubtractSaturate(Vector left, Vector right) => SubtractSaturate(left, right); + + /// + /// svuint16_t svqsub[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svqsub[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svqsub[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UQSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UQSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UQSUBR Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// UQSUB Zresult.H, Zop1.H, Zop2.H + /// + public static new Vector SubtractSaturate(Vector left, Vector right) => SubtractSaturate(left, right); + + /// + /// svuint32_t svqsub[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svqsub[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svqsub[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UQSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UQSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UQSUBR Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// UQSUB Zresult.S, Zop1.S, Zop2.S + /// + public static new Vector SubtractSaturate(Vector left, Vector right) => SubtractSaturate(left, right); + + /// + /// svuint64_t svqsub[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svqsub[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svqsub[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UQSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UQSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UQSUBR Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// UQSUB Zresult.D, Zop1.D, Zop2.D + /// + public static new Vector SubtractSaturate(Vector left, Vector right) => SubtractSaturate(left, right); + + + // Subtract wide (bottom) + + /// + /// svint16_t svsubwb[_s16](svint16_t op1, svint8_t op2) + /// SSUBWB Zresult.H, Zop1.H, Zop2.B + /// + public static Vector SubtractWideningEven(Vector left, Vector right) => SubtractWideningEven(left, right); + + /// + /// svint32_t svsubwb[_s32](svint32_t op1, svint16_t op2) + /// SSUBWB Zresult.S, Zop1.S, Zop2.H + /// + public static Vector SubtractWideningEven(Vector left, Vector right) => SubtractWideningEven(left, right); + + /// + /// svint64_t svsubwb[_s64](svint64_t op1, svint32_t op2) + /// SSUBWB Zresult.D, Zop1.D, Zop2.S + /// + public static Vector SubtractWideningEven(Vector left, Vector right) => SubtractWideningEven(left, right); + + /// + /// svuint16_t svsubwb[_u16](svuint16_t op1, svuint8_t op2) + /// USUBWB Zresult.H, Zop1.H, Zop2.B + /// + public static Vector SubtractWideningEven(Vector left, Vector right) => SubtractWideningEven(left, right); + + /// + /// svuint32_t svsubwb[_u32](svuint32_t op1, svuint16_t op2) + /// USUBWB Zresult.S, Zop1.S, Zop2.H + /// + public static Vector SubtractWideningEven(Vector left, Vector right) => SubtractWideningEven(left, right); + + /// + /// svuint64_t svsubwb[_u64](svuint64_t op1, svuint32_t op2) + /// USUBWB Zresult.D, Zop1.D, Zop2.S + /// + public static Vector SubtractWideningEven(Vector left, Vector right) => SubtractWideningEven(left, right); + + + // Subtract long (bottom) + + /// + /// svint16_t svsublb[_s16](svint8_t op1, svint8_t op2) + /// SSUBLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector SubtractWideningEven(Vector left, Vector right) => SubtractWideningEven(left, right); + + /// + /// svint32_t svsublb[_s32](svint16_t op1, svint16_t op2) + /// SSUBLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector SubtractWideningEven(Vector left, Vector right) => SubtractWideningEven(left, right); + + /// + /// svint64_t svsublb[_s64](svint32_t op1, svint32_t op2) + /// SSUBLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector SubtractWideningEven(Vector left, Vector right) => SubtractWideningEven(left, right); + + /// + /// svuint16_t svsublb[_u16](svuint8_t op1, svuint8_t op2) + /// USUBLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector SubtractWideningEven(Vector left, Vector right) => SubtractWideningEven(left, right); + + /// + /// svuint32_t svsublb[_u32](svuint16_t op1, svuint16_t op2) + /// USUBLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector SubtractWideningEven(Vector left, Vector right) => SubtractWideningEven(left, right); + + /// + /// svuint64_t svsublb[_u64](svuint32_t op1, svuint32_t op2) + /// USUBLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector SubtractWideningEven(Vector left, Vector right) => SubtractWideningEven(left, right); + + + // Subtract long (bottom - top) + + /// + /// svint16_t svsublbt[_s16](svint8_t op1, svint8_t op2) + /// SSUBLBT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector SubtractWideningEvenOdd(Vector left, Vector right) => SubtractWideningEvenOdd(left, right); + + /// + /// svint32_t svsublbt[_s32](svint16_t op1, svint16_t op2) + /// SSUBLBT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector SubtractWideningEvenOdd(Vector left, Vector right) => SubtractWideningEvenOdd(left, right); + + /// + /// svint64_t svsublbt[_s64](svint32_t op1, svint32_t op2) + /// SSUBLBT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector SubtractWideningEvenOdd(Vector left, Vector right) => SubtractWideningEvenOdd(left, right); + + + // Subtract wide (top) + + /// + /// svint16_t svsubwt[_s16](svint16_t op1, svint8_t op2) + /// SSUBWT Zresult.H, Zop1.H, Zop2.B + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) => SubtractWideningOdd(left, right); + + /// + /// svint32_t svsubwt[_s32](svint32_t op1, svint16_t op2) + /// SSUBWT Zresult.S, Zop1.S, Zop2.H + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) => SubtractWideningOdd(left, right); + + /// + /// svint64_t svsubwt[_s64](svint64_t op1, svint32_t op2) + /// SSUBWT Zresult.D, Zop1.D, Zop2.S + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) => SubtractWideningOdd(left, right); + + /// + /// svuint16_t svsubwt[_u16](svuint16_t op1, svuint8_t op2) + /// USUBWT Zresult.H, Zop1.H, Zop2.B + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) => SubtractWideningOdd(left, right); + + /// + /// svuint32_t svsubwt[_u32](svuint32_t op1, svuint16_t op2) + /// USUBWT Zresult.S, Zop1.S, Zop2.H + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) => SubtractWideningOdd(left, right); + + /// + /// svuint64_t svsubwt[_u64](svuint64_t op1, svuint32_t op2) + /// USUBWT Zresult.D, Zop1.D, Zop2.S + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) => SubtractWideningOdd(left, right); + + + // Subtract long (top) + + /// + /// svint16_t svsublt[_s16](svint8_t op1, svint8_t op2) + /// SSUBLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) => SubtractWideningOdd(left, right); + + /// + /// svint32_t svsublt[_s32](svint16_t op1, svint16_t op2) + /// SSUBLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) => SubtractWideningOdd(left, right); + + /// + /// svint64_t svsublt[_s64](svint32_t op1, svint32_t op2) + /// SSUBLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) => SubtractWideningOdd(left, right); + + /// + /// svuint16_t svsublt[_u16](svuint8_t op1, svuint8_t op2) + /// USUBLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) => SubtractWideningOdd(left, right); + + /// + /// svuint32_t svsublt[_u32](svuint16_t op1, svuint16_t op2) + /// USUBLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) => SubtractWideningOdd(left, right); + + /// + /// svuint64_t svsublt[_u64](svuint32_t op1, svuint32_t op2) + /// USUBLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector SubtractWideningOdd(Vector left, Vector right) => SubtractWideningOdd(left, right); + + + // Subtract long (top - bottom) + + /// + /// svint16_t svsubltb[_s16](svint8_t op1, svint8_t op2) + /// SSUBLTB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector SubtractWideningOddEven(Vector left, Vector right) => SubtractWideningOddEven(left, right); + + /// + /// svint32_t svsubltb[_s32](svint16_t op1, svint16_t op2) + /// SSUBLTB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector SubtractWideningOddEven(Vector left, Vector right) => SubtractWideningOddEven(left, right); + + /// + /// svint64_t svsubltb[_s64](svint32_t op1, svint32_t op2) + /// SSUBLTB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector SubtractWideningOddEven(Vector left, Vector right) => SubtractWideningOddEven(left, right); + + // Bit vector table lookups /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.Numerics.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.Numerics.cs index 1cfbc41de7ce22..0ccc17eb0e85c1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.Numerics.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.Numerics.cs @@ -53,53 +53,25 @@ public static partial class Vector128 /// The vector to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Plane AsPlane(this Vector128 value) - { -#if MONO - return Unsafe.As, Plane>(ref value); -#else - return Unsafe.BitCast, Plane>(value); -#endif - } + public static Plane AsPlane(this Vector128 value) => Unsafe.BitCast, Plane>(value); /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Quaternion AsQuaternion(this Vector128 value) - { -#if MONO - return Unsafe.As, Quaternion>(ref value); -#else - return Unsafe.BitCast, Quaternion>(value); -#endif - } + public static Quaternion AsQuaternion(this Vector128 value) => Unsafe.BitCast, Quaternion>(value); /// Reinterprets a as a new . /// The plane to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Vector128 AsVector128(this Plane value) - { -#if MONO - return Unsafe.As>(ref value); -#else - return Unsafe.BitCast>(value); -#endif - } + public static Vector128 AsVector128(this Plane value) => Unsafe.BitCast>(value); /// Reinterprets a as a new . /// The quaternion to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Vector128 AsVector128(this Quaternion value) - { -#if MONO - return Unsafe.As>(ref value); -#else - return Unsafe.BitCast>(value); -#endif - } + public static Vector128 AsVector128(this Quaternion value) => Unsafe.BitCast>(value); /// Reinterprets a as a new with the new elements zeroed. /// The vector to reinterpret. @@ -117,14 +89,7 @@ public static Vector128 AsVector128(this Quaternion value) /// The vector to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Vector128 AsVector128(this Vector4 value) - { -#if MONO - return Unsafe.As>(ref value); -#else - return Unsafe.BitCast>(value); -#endif - } + public static Vector128 AsVector128(this Vector4 value) => Unsafe.BitCast>(value); /// Reinterprets a as a new . /// The type of the elements in the vector. @@ -196,14 +161,7 @@ public static Vector3 AsVector3(this Vector128 value) /// The vector to reinterpret. /// reinterpreted as a new . [Intrinsic] - public static Vector4 AsVector4(this Vector128 value) - { -#if MONO - return Unsafe.As, Vector4>(ref value); -#else - return Unsafe.BitCast, Vector4>(value); -#endif - } + public static Vector4 AsVector4(this Vector128 value) => Unsafe.BitCast, Vector4>(value); /// Reinterprets a as a new . /// The type of the elements in the vector. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs index 90d8770baf7309..6aac6ab0314a74 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs @@ -177,11 +177,7 @@ public static Vector128 As(this Vector128 vector) ThrowHelper.ThrowForUnsupportedIntrinsicsVector128BaseType(); ThrowHelper.ThrowForUnsupportedIntrinsicsVector128BaseType(); -#if MONO - return Unsafe.As, Vector128>(ref vector); -#else return Unsafe.BitCast, Vector128>(vector); -#endif } /// Reinterprets a as a new . diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs index 8f8580a1fb11c9..397b6428656ec3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs @@ -171,11 +171,7 @@ public static Vector256 As(this Vector256 vector) ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType(); ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType(); -#if MONO - return Unsafe.As, Vector256>(ref vector); -#else return Unsafe.BitCast, Vector256>(vector); -#endif } /// Reinterprets a as a new . diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs index 29b10dba0310aa..85b780a3271b66 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs @@ -170,11 +170,7 @@ public static Vector512 As(this Vector512 vector) ThrowHelper.ThrowForUnsupportedIntrinsicsVector512BaseType(); ThrowHelper.ThrowForUnsupportedIntrinsicsVector512BaseType(); -#if MONO - return Unsafe.As, Vector512>(ref vector); -#else return Unsafe.BitCast, Vector512>(vector); -#endif } /// Reinterprets a as a new . diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs index 5c49722a1fa36b..b4bf35654517bd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs @@ -170,11 +170,7 @@ public static Vector64 As(this Vector64 vector) ThrowHelper.ThrowForUnsupportedIntrinsicsVector64BaseType(); ThrowHelper.ThrowForUnsupportedIntrinsicsVector64BaseType(); -#if MONO - return Unsafe.As, Vector64>(ref vector); -#else return Unsafe.BitCast, Vector64>(vector); -#endif } /// Reinterprets a as a new . diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs index d4ab9e7a3092eb..7816d79a680d6d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs @@ -15,7 +15,7 @@ namespace System.Runtime.Loader { public partial class AssemblyLoadContext { - // Keep in sync with MonoManagedAssemblyLoadContextInternalState in object-internals.h + // Keep in sync with MonoAssemblyLoadContextInternalState in object-internals.h private enum InternalState { /// @@ -42,7 +42,7 @@ private enum InternalState #region private data members // If you modify this field, you must also update the // AssemblyLoadContextBaseObject structure in object.h - // and MonoManagedAssemblyLoadContext in object-internals.h + // and MonoAssemblyLoadContext in object-internals.h // Contains the reference to VM's representation of the AssemblyLoadContext private readonly IntPtr _nativeAssemblyLoadContext; @@ -530,7 +530,7 @@ private static void SetCurrentContextualReflectionContext(AssemblyLoadContext? v { Interlocked.CompareExchange?>(ref s_asyncLocalCurrent, new AsyncLocal(), null); } - s_asyncLocalCurrent!.Value = value; // Remove ! when compiler specially-recognizes CompareExchange for nullability + s_asyncLocalCurrent.Value = value; } /// Enter scope using this AssemblyLoadContext for ContextualReflection @@ -604,9 +604,9 @@ public void Dispose() #if !NATIVEAOT // This method is invoked by the VM when using the host-provided assembly load context // implementation. - private static RuntimeAssembly? Resolve(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName) + private static RuntimeAssembly? Resolve(IntPtr gchAssemblyLoadContext, AssemblyName assemblyName) { - AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target)!; + AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchAssemblyLoadContext).Target)!; return context.ResolveUsingLoad(assemblyName); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Versioning/PlatformAttributes.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Versioning/PlatformAttributes.cs index 85fbeb604c669c..86f621c82023b0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Versioning/PlatformAttributes.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Versioning/PlatformAttributes.cs @@ -134,14 +134,32 @@ public UnsupportedOSPlatformAttribute(string platformName, string? message) : ba #endif sealed class ObsoletedOSPlatformAttribute : OSPlatformAttribute { + /// + /// Initializes a new instance of the class with the specified platform name. + /// + /// The name of the platform where the API was obsoleted. public ObsoletedOSPlatformAttribute(string platformName) : base(platformName) { } + + /// + /// Initializes a new instance of the class with the specified platform name and message. + /// + /// The name of the platform where the API was obsoleted. + /// The message that explains the obsolescence. public ObsoletedOSPlatformAttribute(string platformName, string? message) : base(platformName) { Message = message; } + + /// + /// Gets the message that explains the obsolescence. + /// public string? Message { get; } + + /// + /// Gets or sets the URL that provides more information about the obsolescence. + /// public string? Url { get; set; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index c243053aead38f..933e84836c4ce1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -93,6 +93,25 @@ public override MemberInfo[] GetDefaultMembers() return members ?? Array.Empty(); } + private static bool IsFullNameRoundtripCompatible(RuntimeType runtimeType) + { + // We exclude the types that contain generic parameters because their names cannot be round-tripped. + // We allow generic type definitions (and their refs, ptrs, and arrays) because their names can be round-tripped. + // Theoretically generic types instantiated with generic type definitions can be round-tripped, e.g. List`1. + // But these kind of types are useless, rare, and hard to identity. We would need to recursively examine all the + // generic arguments with the same criteria. We will exclude them unless we see a real user scenario. + Type rootElementType = runtimeType.GetRootElementType(); + if (!rootElementType.IsGenericTypeDefinition && rootElementType.ContainsGenericParameters) + return false; + + // Exclude function pointer; it requires a grammar update and parsing support for Type.GetType() and friends. + // See https://learn.microsoft.com/dotnet/framework/reflection-and-codedom/specifying-fully-qualified-type-names. + if (rootElementType.IsFunctionPointer) + return false; + + return true; + } + public override Type? GetElementType() => RuntimeTypeHandle.GetElementType(this); public override string? GetEnumName(object value) @@ -278,7 +297,7 @@ public override bool IsAssignableFrom([NotNullWhen(true)] Type? c) if (c.IsSubclassOf(this)) return true; - if (IsInterface) + if (IsActualInterface) { return c.ImplementInterface(this); } @@ -667,7 +686,7 @@ public override bool IsAssignableFrom([NotNullWhen(true)] Type? c) object? state = null; MethodBase? invokeMethod = null; - try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs!, modifiers, culture, namedParams, out state); } + try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); } catch (MissingMethodException) { } if (invokeMethod == null) @@ -692,7 +711,7 @@ public override bool IsAssignableFrom([NotNullWhen(true)] Type? c) // `class G3 where T:U where U:Stream`: typeof(G3<,>).GetGenericArguments()[0].BaseType is Object (!) private RuntimeType? GetBaseType() { - if (IsInterface) + if (IsActualInterface) return null; if (RuntimeTypeHandle.IsGenericVariable(this)) @@ -705,7 +724,7 @@ public override bool IsAssignableFrom([NotNullWhen(true)] Type? c) { RuntimeType constraint = (RuntimeType)constraints[i]; - if (constraint.IsInterface) + if (constraint.IsActualInterface) continue; if (constraint.IsGenericParameter) diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiByteSearchValues.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiByteSearchValues.cs index a3562f8c98a7d6..acd4c10e87df1e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiByteSearchValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiByteSearchValues.cs @@ -18,9 +18,9 @@ internal sealed class AsciiByteSearchValues : SearchValues values) { - // Despite the name being Ascii, this type may be used with non-ASCII values on ARM. - // See IndexOfAnyAsciiSearcher.CanUseUniqueLowNibbleSearch. - Debug.Assert(Ascii.IsValid(values) || (AdvSimd.IsSupported && TUniqueLowNibble.Value)); + // Despite the name being Ascii, this type may be used with non-ASCII values on ARM or WASM. + // See comments in IndexOfAnyAsciiSearcher.CanUseUniqueLowNibbleSearch. + Debug.Assert(Ascii.IsValid(values) || (TUniqueLowNibble.Value && (AdvSimd.IsSupported || PackedSimd.IsSupported))); if (TUniqueLowNibble.Value) { diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiCharSearchValues.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiCharSearchValues.cs index 175c2737b9a7ec..981e4a7266b7a8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiCharSearchValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/AsciiCharSearchValues.cs @@ -19,9 +19,10 @@ internal sealed class AsciiCharSearchValues : public AsciiCharSearchValues(ReadOnlySpan values) { - // Despite the name being Ascii, this type may be used with non-ASCII values on ARM. - // See IndexOfAnyAsciiSearcher.CanUseUniqueLowNibbleSearch. - Debug.Assert(Ascii.IsValid(values) || (AdvSimd.IsSupported && TUniqueLowNibble.Value)); + // Despite the name being Ascii, this type may be used with non-ASCII values on ARM or WASM. + // See comments in IndexOfAnyAsciiSearcher.CanUseUniqueLowNibbleSearch. + Debug.Assert(Ascii.IsValid(values) || (TUniqueLowNibble.Value && (AdvSimd.IsSupported || PackedSimd.IsSupported))); + Debug.Assert(!values.ContainsAnyInRange((char)byte.MaxValue, char.MaxValue)); if (TUniqueLowNibble.Value) { diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/IndexOfAnyAsciiSearcher.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/IndexOfAnyAsciiSearcher.cs index 7f8393f483179e..3808fb037410c9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/IndexOfAnyAsciiSearcher.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/IndexOfAnyAsciiSearcher.cs @@ -321,7 +321,7 @@ private static TResult IndexOfAnyCores into a Vector256 is cheap compared to the lookup, we can effectively double the throughput. // If the input length is a multiple of 32, don't consume the last 32 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, searchSpaceLength - (2 * Vector256.Count)); do @@ -374,7 +374,7 @@ private static TResult IndexOfAnyCores into a Vector128 is cheap compared to the lookup, we can effectively double the throughput. // If the input length is a multiple of 16, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, searchSpaceLength - (2 * Vector128.Count)); do @@ -453,7 +453,7 @@ public static int LastIndexOfAny(ref // As packing two Vector256s into a Vector256 is cheap compared to the lookup, we can effectively double the throughput. // If the input length is a multiple of 32, don't consume the last 32 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressGreaterThan" is used instead of "!IsAddressLessThan". + // ">" instead of ">=" above, and why "IsAddressGreaterThan" is used instead of "IsAddressGreaterThanOrEqualTo". ref short twoVectorsAfterStart = ref Unsafe.Add(ref searchSpace, 2 * Vector256.Count); do @@ -504,7 +504,7 @@ public static int LastIndexOfAny(ref // As packing two Vector128s into a Vector128 is cheap compared to the lookup, we can effectively double the throughput. // If the input length is a multiple of 16, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressGreaterThan" is used instead of "!IsAddressLessThan". + // ">" instead of ">=" above, and why "IsAddressGreaterThan" is used instead of "IsAddressGreaterThanOrEqualTo". ref short twoVectorsAfterStart = ref Unsafe.Add(ref searchSpace, 2 * Vector128.Count); do @@ -604,7 +604,7 @@ private static TResult IndexOfAnyCore" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref byte vectorAwayFromEnd = ref Unsafe.Add(ref searchSpace, searchSpaceLength - Vector256.Count); do @@ -653,7 +653,7 @@ private static TResult IndexOfAnyCore" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref byte vectorAwayFromEnd = ref Unsafe.Add(ref searchSpace, searchSpaceLength - Vector128.Count); do @@ -729,7 +729,7 @@ public static int LastIndexOfAny(ref byte searchSpac // Process the input in chunks of 32 bytes. // If the input length is a multiple of 32, don't consume the last 32 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressGreaterThan" is used instead of "!IsAddressLessThan". + // ">" instead of ">=" above, and why "IsAddressGreaterThan" is used instead of "IsAddressGreaterThanOrEqualTo". ref byte vectorAfterStart = ref Unsafe.Add(ref searchSpace, Vector256.Count); do @@ -778,7 +778,7 @@ public static int LastIndexOfAny(ref byte searchSpac // Process the input in chunks of 16 bytes. // If the input length is a multiple of 16, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressGreaterThan" is used instead of "!IsAddressLessThan". + // ">" instead of ">=" above, and why "IsAddressGreaterThan" is used instead of "IsAddressGreaterThanOrEqualTo". ref byte vectorAfterStart = ref Unsafe.Add(ref searchSpace, Vector128.Count); do @@ -876,7 +876,7 @@ private static TResult IndexOfAnyCore(ref byte // Process the input in chunks of 32 bytes. // If the input length is a multiple of 32, don't consume the last 32 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref byte vectorAwayFromEnd = ref Unsafe.Add(ref searchSpace, searchSpaceLength - Vector256.Count); do @@ -928,7 +928,7 @@ private static TResult IndexOfAnyCore(ref byte // Process the input in chunks of 16 bytes. // If the input length is a multiple of 16, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref byte vectorAwayFromEnd = ref Unsafe.Add(ref searchSpace, searchSpaceLength - Vector128.Count); do @@ -1004,7 +1004,7 @@ public static int LastIndexOfAny(ref byte searchSpace, int searchSpace // Process the input in chunks of 32 bytes. // If the input length is a multiple of 32, don't consume the last 32 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressGreaterThan" is used instead of "!IsAddressLessThan". + // ">" instead of ">=" above, and why "IsAddressGreaterThan" is used instead of "IsAddressGreaterThanOrEqualTo". ref byte vectorAfterStart = ref Unsafe.Add(ref searchSpace, Vector256.Count); do @@ -1056,7 +1056,7 @@ public static int LastIndexOfAny(ref byte searchSpace, int searchSpace // Process the input in chunks of 16 bytes. // If the input length is a multiple of 16, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressGreaterThan" is used instead of "!IsAddressLessThan". + // ">" instead of ">=" above, and why "IsAddressGreaterThan" is used instead of "IsAddressGreaterThanOrEqualTo". ref byte vectorAfterStart = ref Unsafe.Add(ref searchSpace, Vector128.Count); do diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticMap.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticMap.cs index 9a4e3dd0b735b2..0b09377b503e17 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticMap.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticMap.cs @@ -626,7 +626,7 @@ private static int LastIndexOfAnyVectorizedAvx512(ref char sea } } - if (!Unsafe.IsAddressGreaterThan(ref cur, ref lastStartVector)) + if (Unsafe.IsAddressLessThanOrEqualTo(ref cur, ref lastStartVector)) { if (Unsafe.AreSame(ref cur, ref searchSpace)) { @@ -715,7 +715,7 @@ private static int LastIndexOfAnyVectorized(ref char searchSpa } } - if (!Unsafe.IsAddressGreaterThan(ref cur, ref lastStartVectorAvx2)) + if (Unsafe.IsAddressLessThanOrEqualTo(ref cur, ref lastStartVectorAvx2)) { if (Unsafe.AreSame(ref cur, ref searchSpace)) { @@ -757,7 +757,7 @@ private static int LastIndexOfAnyVectorized(ref char searchSpa } } - if (!Unsafe.IsAddressGreaterThan(ref cur, ref lastStartVector)) + if (Unsafe.IsAddressLessThanOrEqualTo(ref cur, ref lastStartVector)) { if (Unsafe.AreSame(ref cur, ref searchSpace)) { diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/AsciiStringSearchValuesTeddyBase.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/AsciiStringSearchValuesTeddyBase.cs index 1a0c3d80863aec..b764e3a22d81ee 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/AsciiStringSearchValuesTeddyBase.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/AsciiStringSearchValuesTeddyBase.cs @@ -91,7 +91,7 @@ namespace System.Buffers // // For an alternative description of the algorithm, see // https://github.com/BurntSushi/aho-corasick/blob/8d735471fc12f0ca570cead8e17342274fae6331/src/packed/teddy/README.md - // Has an O(i * m) worst-case, with the expected time closer to O(n) for good bucket distributions. + // Has an O(i * m) worst-case, with the expected time closer to O(i) for good bucket distributions. internal abstract class AsciiStringSearchValuesTeddyBase : StringSearchValuesRabinKarp where TBucketized : struct, SearchValues.IRuntimeConst where TStartCaseSensitivity : struct, ICaseSensitivity // Refers to the characters being matched by Teddy diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/AhoCorasickNode.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/AhoCorasickNode.cs index 9f408d2a8ee215..d2f2d9de6f07cf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/AhoCorasickNode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/AhoCorasickNode.cs @@ -41,7 +41,7 @@ public readonly bool TryGetChild(char c, out int index) if (children.GetType() == typeof(int[])) { - int[] table = Unsafe.As(children); + int[] table = (int[])children; if (c < (uint)table.Length) { index = table[c]; diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/RabinKarp.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/RabinKarp.cs index d8970655cb31b7..086061ffe01641 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/RabinKarp.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/RabinKarp.cs @@ -142,7 +142,7 @@ private readonly int IndexOfAnyCore(ReadOnlySpan span) } } - if (!Unsafe.IsAddressLessThan(ref current, ref end)) + if (Unsafe.IsAddressGreaterThanOrEqualTo(ref current, ref end)) { break; } diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/StringSearchValuesHelper.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/StringSearchValuesHelper.cs index 15a608cce70db6..ff420480438c5e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/StringSearchValuesHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/StringSearchValuesHelper.cs @@ -6,6 +6,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; using System.Text; namespace System.Buffers @@ -270,12 +271,31 @@ public static bool Equals(ref char matchStart, ref readonly Single else { Debug.Assert(state.Value.Length is 2 or 3); - Debug.Assert(matchStart == state.Value[0], "This should only be called after the first character has been checked"); - // We know that the candidate is 2 or 3 characters long, and that the first character has already been checked. - // We only have to to check whether the last 2 characters also match. ref byte matchByteStart = ref Unsafe.As(ref matchStart); - return Unsafe.ReadUnaligned(ref Unsafe.Add(ref matchByteStart, state.SecondReadByteOffset)) == state.Value32_1; + + if (AdvSimd.IsSupported) + { + // See comments on SingleStringSearchValuesPackedThreeChars.CanSkipAnchorMatchVerification. + // When running on Arm64, this helper is also used to confirm vectorized anchor matches. + // We do so because we're using UnzipEven when packing inputs, which may produce false positive anchor matches. + // When called from SingleStringSearchValuesThreeChars (non-packed), we could skip to the else branch instead. + Debug.Assert(matchStart == state.Value[0] || (matchStart & 0xFF) == state.Value[0]); + + uint differentBits = Unsafe.ReadUnaligned(ref matchByteStart) - state.Value32_0; + differentBits |= Unsafe.ReadUnaligned(ref Unsafe.Add(ref matchByteStart, state.SecondReadByteOffset)) - state.Value32_1; + return differentBits == 0; + } + else + { + // Otherwise, this path is not used when confirming vectorized anchor matches. + // It's only used as part of the scalar search loop, which always checks that the first character matches before calling this helper. + // We know that the candidate is 2 or 3 characters long, and that the first character has already been checked. + // We only have to to check whether the last 2 characters also match. + Debug.Assert(matchStart == state.Value[0], "This should only be called after the first character has been checked"); + + return Unsafe.ReadUnaligned(ref Unsafe.Add(ref matchByteStart, state.SecondReadByteOffset)) == state.Value32_1; + } } } } @@ -319,13 +339,32 @@ public static bool Equals(ref char matchStart, ref readonly Single else { Debug.Assert(state.Value.Length is 2 or 3); - Debug.Assert(TransformInput(matchStart) == state.Value[0], "This should only be called after the first character has been checked"); - // We know that the candidate is 2 or 3 characters long, and that the first character has already been checked. - // We only have to to check whether the last 2 characters also match. const uint CaseMask = ~0x200020u; ref byte matchByteStart = ref Unsafe.As(ref matchStart); - return (Unsafe.ReadUnaligned(ref Unsafe.Add(ref matchByteStart, state.SecondReadByteOffset)) & CaseMask) == state.Value32_1; + + if (AdvSimd.IsSupported) + { + // See comments on SingleStringSearchValuesPackedThreeChars.CanSkipAnchorMatchVerification. + // When running on Arm64, this helper is also used to confirm vectorized anchor matches. + // We do so because we're using UnzipEven when packing inputs, which may produce false positive anchor matches. + // When called from SingleStringSearchValuesThreeChars (non-packed), we could skip to the else branch instead. + Debug.Assert(TransformInput((char)(matchStart & 0xFF)) == state.Value[0]); + + uint differentBits = (Unsafe.ReadUnaligned(ref matchByteStart) & CaseMask) - state.Value32_0; + differentBits |= (Unsafe.ReadUnaligned(ref Unsafe.Add(ref matchByteStart, state.SecondReadByteOffset)) & CaseMask) - state.Value32_1; + return differentBits == 0; + } + else + { + // Otherwise, this path is not used when confirming vectorized anchor matches. + // It's only used as part of the scalar search loop, which always checks that the first character matches before calling this helper. + // We know that the candidate is 2 or 3 characters long, and that the first character has already been checked. + // We only have to to check whether the last 2 characters also match. + Debug.Assert(TransformInput(matchStart) == state.Value[0], "This should only be called after the first character has been checked"); + + return (Unsafe.ReadUnaligned(ref Unsafe.Add(ref matchByteStart, state.SecondReadByteOffset)) & CaseMask) == state.Value32_1; + } } } } @@ -392,7 +431,6 @@ public static bool Equals(ref char matchStart, ref readonly Single else { Debug.Assert(state.Value.Length is 2 or 3); - Debug.Assert((matchStart & ~0x20) == (state.Value[0] & ~0x20)); ref byte matchByteStart = ref Unsafe.As(ref matchStart); uint differentBits = (Unsafe.ReadUnaligned(ref matchByteStart) & state.ToUpperMask32_0) - state.Value32_0; diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/TeddyHelper.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/TeddyHelper.cs index b73302a287eece..064838c98cf361 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/TeddyHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/Helpers/TeddyHelper.cs @@ -207,11 +207,15 @@ public static (Vector512 Result, Vector512 Prev0, Vector512 Pr return (result, match0, match1); } - // Read two Vector512 and concatenate their lower bytes together into a single Vector512. - // On X86, characters above 32767 are turned into 0, but we account for that by not using Teddy if any of the string values contain a 0. + /// + /// Read two and concatenate their lower bytes together into a single . + /// + /// + /// On X86, characters above 32767 are turned into 0, but we account for that by not using Teddy if any of the string values contain a 0. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [CompExactlyDependsOn(typeof(Sse2))] - [CompExactlyDependsOn(typeof(AdvSimd))] + [CompExactlyDependsOn(typeof(AdvSimd.Arm64))] public static Vector128 LoadAndPack16AsciiChars(ref char source) { Vector128 source0 = Vector128.LoadUnsafe(ref source); @@ -221,9 +225,9 @@ public static Vector128 LoadAndPack16AsciiChars(ref char source) { return Sse2.PackUnsignedSaturate(source0.AsInt16(), source1.AsInt16()); } - else if (AdvSimd.IsSupported) + else if (AdvSimd.Arm64.IsSupported) { - return AdvSimd.ExtractNarrowingSaturateUpper(AdvSimd.ExtractNarrowingSaturateLower(source0), source1); + return AdvSimd.Arm64.UnzipEven(source0.AsByte(), source1.AsByte()); } else { @@ -233,8 +237,12 @@ public static Vector128 LoadAndPack16AsciiChars(ref char source) } } - // Read two Vector512 and concatenate their lower bytes together into a single Vector512. - // Characters above 32767 are turned into 0, but we account for that by not using Teddy if any of the string values contain a 0. + /// + /// Read two and concatenate their lower bytes together into a single . + /// + /// + /// On X86, characters above 32767 are turned into 0, but we account for that by not using Teddy if any of the string values contain a 0. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [CompExactlyDependsOn(typeof(Avx2))] public static Vector256 LoadAndPack32AsciiChars(ref char source) @@ -247,8 +255,12 @@ public static Vector256 LoadAndPack32AsciiChars(ref char source) return PackedSpanHelpers.FixUpPackedVector256Result(packed); } - // Read two Vector512 and concatenate their lower bytes together into a single Vector512. - // Characters above 32767 are turned into 0, but we account for that by not using Teddy if any of the string values contain a 0. + /// + /// Read two and concatenate their lower bytes together into a single . + /// + /// + /// On X86, characters above 32767 are turned into 0, but we account for that by not using Teddy if any of the string values contain a 0. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [CompExactlyDependsOn(typeof(Avx512BW))] public static Vector512 LoadAndPack64AsciiChars(ref char source) diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/SingleStringSearchValuesPackedThreeChars.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/SingleStringSearchValuesPackedThreeChars.cs new file mode 100644 index 00000000000000..5c1d64bf9b0dfb --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/SingleStringSearchValuesPackedThreeChars.cs @@ -0,0 +1,417 @@ +// 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.Generic; +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using System.Runtime.Intrinsics.X86; +using static System.Buffers.StringSearchValuesHelper; + +namespace System.Buffers +{ + /// + /// Same as , but using packed comparisons similar to . + /// + internal sealed class SingleStringSearchValuesPackedThreeChars : StringSearchValuesBase + where TValueLength : struct, IValueLength + where TCaseSensitivity : struct, ICaseSensitivity + { + private const byte CaseConversionMask = unchecked((byte)~0x20); + + private readonly SingleValueState _valueState; + private readonly nint _minusValueTailLength; + private readonly nuint _ch2ByteOffset; + private readonly nuint _ch3ByteOffset; + private readonly byte _ch1; + private readonly byte _ch2; + private readonly byte _ch3; + + private static bool IgnoreCase => typeof(TCaseSensitivity) != typeof(CaseSensitive); + + // If the value is short (ValueLengthLessThan4 => 2 or 3 characters), the anchors already represent the whole value. + // With case-sensitive comparisons, we've therefore already confirmed the match, so we can skip doing so here. + // With case-insensitive comparisons, we applied a mask to the input, so while the anchors likely matched, we can't be sure. + // If the value is composed of only ASCII letters, masking the input can't produce false positives, so we can also skip the verification step. + // We only do this when running on X86 and not ARM64, as the latter uses UnzipEven when packing inputs, which may produce false positive anchor matches. + // We use that instead of ExtractNarrowingSaturate because it allows for higher searching throughput. + private static bool CanSkipAnchorMatchVerification + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => + Sse2.IsSupported && + typeof(TValueLength) == typeof(ValueLengthLessThan4) && + (typeof(TCaseSensitivity) == typeof(CaseSensitive) || typeof(TCaseSensitivity) == typeof(CaseInsensitiveAsciiLetters)); + } + + public SingleStringSearchValuesPackedThreeChars(HashSet? uniqueValues, string value, int ch2Offset, int ch3Offset) : base(uniqueValues) + { + Debug.Assert(Sse2.IsSupported || AdvSimd.Arm64.IsSupported); + + // We could have more than one entry in 'uniqueValues' if this value is an exact prefix of all the others. + Debug.Assert(value.Length > 1); + Debug.Assert(ch3Offset == 0 || ch3Offset > ch2Offset); + Debug.Assert(value[0] <= byte.MaxValue && value[ch2Offset] <= byte.MaxValue && value[ch3Offset] <= byte.MaxValue); + + _valueState = new SingleValueState(value, IgnoreCase); + _minusValueTailLength = -(value.Length - 1); + + _ch1 = (byte)value[0]; + _ch2 = (byte)value[ch2Offset]; + _ch3 = (byte)value[ch3Offset]; + + if (IgnoreCase) + { + _ch1 &= CaseConversionMask; + _ch2 &= CaseConversionMask; + _ch3 &= CaseConversionMask; + } + + _ch2ByteOffset = (nuint)ch2Offset * 2; + _ch3ByteOffset = (nuint)ch3Offset * 2; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal override int IndexOfAnyMultiString(ReadOnlySpan span) => + IndexOf(ref MemoryMarshal.GetReference(span), span.Length); + + private int IndexOf(ref char searchSpace, int searchSpaceLength) + { + ref char searchSpaceStart = ref searchSpace; + + nint searchSpaceMinusValueTailLength = searchSpaceLength + _minusValueTailLength; + + nuint ch2ByteOffset = _ch2ByteOffset; + nuint ch3ByteOffset = _ch3ByteOffset; + + if (Vector512.IsHardwareAccelerated && Avx512BW.IsSupported && searchSpaceMinusValueTailLength - Vector512.Count >= 0) + { + Vector512 ch1 = Vector512.Create(_ch1); + Vector512 ch2 = Vector512.Create(_ch2); + Vector512 ch3 = Vector512.Create(_ch3); + + ref char lastSearchSpace = ref Unsafe.Add(ref searchSpace, searchSpaceMinusValueTailLength - Vector512.Count); + + while (true) + { + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector512.Count); + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector512.Count + (int)(_ch2ByteOffset / sizeof(char))); + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector512.Count + (int)(_ch3ByteOffset / sizeof(char))); + + // Find which starting positions likely contain a match (likely match all 3 anchor characters). + Vector512 result = GetComparisonResult(ref searchSpace, ch2ByteOffset, ch3ByteOffset, ch1, ch2, ch3); + + if (result != Vector512.Zero) + { + goto CandidateFound; + } + + LoopFooter: + // We haven't found a match. Update the input position and check if we've reached the end. + searchSpace = ref Unsafe.Add(ref searchSpace, Vector512.Count); + + if (Unsafe.IsAddressGreaterThan(ref searchSpace, ref lastSearchSpace)) + { + if (Unsafe.AreSame(ref searchSpace, ref Unsafe.Add(ref lastSearchSpace, Vector512.Count))) + { + return -1; + } + + // We have fewer than 64 characters remaining. Adjust the input position such that we will do one last loop iteration. + searchSpace = ref lastSearchSpace; + } + + continue; + + CandidateFound: + // We found potential matches, but they may be false-positives, so we must verify each one. + if (TryMatch(ref searchSpaceStart, searchSpaceLength, ref searchSpace, PackedSpanHelpers.FixUpPackedVector512Result(result).ExtractMostSignificantBits(), out int offset)) + { + return offset; + } + goto LoopFooter; + } + } + else if (Vector256.IsHardwareAccelerated && Avx2.IsSupported && searchSpaceMinusValueTailLength - Vector256.Count >= 0) + { + Vector256 ch1 = Vector256.Create(_ch1); + Vector256 ch2 = Vector256.Create(_ch2); + Vector256 ch3 = Vector256.Create(_ch3); + + ref char lastSearchSpace = ref Unsafe.Add(ref searchSpace, searchSpaceMinusValueTailLength - Vector256.Count); + + while (true) + { + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector256.Count); + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector256.Count + (int)(_ch2ByteOffset / sizeof(char))); + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector256.Count + (int)(_ch3ByteOffset / sizeof(char))); + + // Find which starting positions likely contain a match (likely match all 3 anchor characters). + Vector256 result = GetComparisonResult(ref searchSpace, ch2ByteOffset, ch3ByteOffset, ch1, ch2, ch3); + + if (result != Vector256.Zero) + { + goto CandidateFound; + } + + LoopFooter: + searchSpace = ref Unsafe.Add(ref searchSpace, Vector256.Count); + + if (Unsafe.IsAddressGreaterThan(ref searchSpace, ref lastSearchSpace)) + { + if (Unsafe.AreSame(ref searchSpace, ref Unsafe.Add(ref lastSearchSpace, Vector256.Count))) + { + return -1; + } + + // We have fewer than 32 characters remaining. Adjust the input position such that we will do one last loop iteration. + searchSpace = ref lastSearchSpace; + } + + continue; + + CandidateFound: + // We found potential matches, but they may be false-positives, so we must verify each one. + if (TryMatch(ref searchSpaceStart, searchSpaceLength, ref searchSpace, PackedSpanHelpers.FixUpPackedVector256Result(result).ExtractMostSignificantBits(), out int offset)) + { + return offset; + } + goto LoopFooter; + } + } + else if ((Sse2.IsSupported || AdvSimd.Arm64.IsSupported) && searchSpaceMinusValueTailLength - Vector128.Count >= 0) + { + Vector128 ch1 = Vector128.Create(_ch1); + Vector128 ch2 = Vector128.Create(_ch2); + Vector128 ch3 = Vector128.Create(_ch3); + + ref char lastSearchSpace = ref Unsafe.Add(ref searchSpace, searchSpaceMinusValueTailLength - Vector128.Count); + + while (true) + { + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector128.Count); + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector128.Count + (int)(_ch2ByteOffset / sizeof(char))); + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector128.Count + (int)(_ch3ByteOffset / sizeof(char))); + + // Find which starting positions likely contain a match (likely match all 3 anchor characters). + Vector128 result = GetComparisonResult(ref searchSpace, ch2ByteOffset, ch3ByteOffset, ch1, ch2, ch3); + + if (result != Vector128.Zero) + { + goto CandidateFound; + } + + LoopFooter: + searchSpace = ref Unsafe.Add(ref searchSpace, Vector128.Count); + + if (Unsafe.IsAddressGreaterThan(ref searchSpace, ref lastSearchSpace)) + { + if (Unsafe.AreSame(ref searchSpace, ref Unsafe.Add(ref lastSearchSpace, Vector128.Count))) + { + return -1; + } + + // We have fewer than 16 characters remaining. Adjust the input position such that we will do one last loop iteration. + searchSpace = ref lastSearchSpace; + } + + continue; + + CandidateFound: + // We found potential matches, but they may be false-positives, so we must verify each one. + if (TryMatch(ref searchSpaceStart, searchSpaceLength, ref searchSpace, result.ExtractMostSignificantBits(), out int offset)) + { + return offset; + } + goto LoopFooter; + } + } + + char valueHead = _valueState.Value.GetRawStringData(); + + for (nint i = 0; i < searchSpaceMinusValueTailLength; i++) + { + ref char cur = ref Unsafe.Add(ref searchSpace, i); + + // CaseInsensitiveUnicode doesn't support single-character transformations, so we skip checking the first character first. + if ((typeof(TCaseSensitivity) == typeof(CaseInsensitiveUnicode) || TCaseSensitivity.TransformInput(cur) == valueHead) && + TCaseSensitivity.Equals(ref cur, in _valueState)) + { + return (int)i; + } + } + + return -1; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [CompExactlyDependsOn(typeof(Sse2))] + [CompExactlyDependsOn(typeof(AdvSimd.Arm64))] + private static Vector128 GetComparisonResult(ref char searchSpace, nuint ch2ByteOffset, nuint ch3ByteOffset, Vector128 ch1, Vector128 ch2, Vector128 ch3) + { + // Load 3 vectors from the input. + // One from the current search space, the other two at an offset based on the distance of those characters from the first one. + if (typeof(TCaseSensitivity) == typeof(CaseSensitive)) + { + Vector128 cmpCh1 = Vector128.Equals(ch1, LoadPacked128(ref searchSpace, 0)); + Vector128 cmpCh2 = Vector128.Equals(ch2, LoadPacked128(ref searchSpace, ch2ByteOffset)); + Vector128 cmpCh3 = Vector128.Equals(ch3, LoadPacked128(ref searchSpace, ch3ByteOffset)); + // AND all 3 together to get a mask of possible match positions that match in at least 3 places. + return (cmpCh1 & cmpCh2 & cmpCh3).AsByte(); + } + else + { + // For each, AND the value with ~0x20 so that letters are uppercased. + // For characters that aren't ASCII letters, this may produce wrong results, but only false-positives. + // We will take care of those in the verification step if the other characters also indicate a possible match. + Vector128 caseConversion = Vector128.Create(CaseConversionMask); + + Vector128 cmpCh1 = Vector128.Equals(ch1, LoadPacked128(ref searchSpace, 0) & caseConversion); + Vector128 cmpCh2 = Vector128.Equals(ch2, LoadPacked128(ref searchSpace, ch2ByteOffset) & caseConversion); + Vector128 cmpCh3 = Vector128.Equals(ch3, LoadPacked128(ref searchSpace, ch3ByteOffset) & caseConversion); + // AND all 3 together to get a mask of possible match positions that likely match in at least 3 places. + return (cmpCh1 & cmpCh2 & cmpCh3).AsByte(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [CompExactlyDependsOn(typeof(Avx2))] + private static Vector256 GetComparisonResult(ref char searchSpace, nuint ch2ByteOffset, nuint ch3ByteOffset, Vector256 ch1, Vector256 ch2, Vector256 ch3) + { + // See comments in 'GetComparisonResult' for Vector128 above. + // This method is the same, but operates on 32 input characters at a time. + if (typeof(TCaseSensitivity) == typeof(CaseSensitive)) + { + Vector256 cmpCh1 = Vector256.Equals(ch1, LoadPacked256(ref searchSpace, 0)); + Vector256 cmpCh2 = Vector256.Equals(ch2, LoadPacked256(ref searchSpace, ch2ByteOffset)); + Vector256 cmpCh3 = Vector256.Equals(ch3, LoadPacked256(ref searchSpace, ch3ByteOffset)); + return (cmpCh1 & cmpCh2 & cmpCh3).AsByte(); + } + else + { + Vector256 caseConversion = Vector256.Create(CaseConversionMask); + + Vector256 cmpCh1 = Vector256.Equals(ch1, LoadPacked256(ref searchSpace, 0) & caseConversion); + Vector256 cmpCh2 = Vector256.Equals(ch2, LoadPacked256(ref searchSpace, ch2ByteOffset) & caseConversion); + Vector256 cmpCh3 = Vector256.Equals(ch3, LoadPacked256(ref searchSpace, ch3ByteOffset) & caseConversion); + return (cmpCh1 & cmpCh2 & cmpCh3).AsByte(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [CompExactlyDependsOn(typeof(Avx512BW))] + private static Vector512 GetComparisonResult(ref char searchSpace, nuint ch2ByteOffset, nuint ch3ByteOffset, Vector512 ch1, Vector512 ch2, Vector512 ch3) + { + // See comments in 'GetComparisonResult' for Vector128 above. + // This method is the same, but operates on 64 input characters at a time. + if (typeof(TCaseSensitivity) == typeof(CaseSensitive)) + { + Vector512 cmpCh1 = Vector512.Equals(ch1, LoadPacked512(ref searchSpace, 0)); + Vector512 cmpCh2 = Vector512.Equals(ch2, LoadPacked512(ref searchSpace, ch2ByteOffset)); + Vector512 cmpCh3 = Vector512.Equals(ch3, LoadPacked512(ref searchSpace, ch3ByteOffset)); + return (cmpCh1 & cmpCh2 & cmpCh3).AsByte(); + } + else + { + Vector512 caseConversion = Vector512.Create(CaseConversionMask); + + Vector512 cmpCh1 = Vector512.Equals(ch1, LoadPacked512(ref searchSpace, 0) & caseConversion); + Vector512 cmpCh2 = Vector512.Equals(ch2, LoadPacked512(ref searchSpace, ch2ByteOffset) & caseConversion); + Vector512 cmpCh3 = Vector512.Equals(ch3, LoadPacked512(ref searchSpace, ch3ByteOffset) & caseConversion); + return (cmpCh1 & cmpCh2 & cmpCh3).AsByte(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool TryMatch(ref char searchSpaceStart, int searchSpaceLength, ref char searchSpace, uint mask, out int offsetFromStart) + { + // 'mask' encodes the input positions where at least 3 characters likely matched. + // Verify each one to see if we've found a match, otherwise return back to the vectorized loop. + do + { + int bitPos = BitOperations.TrailingZeroCount(mask); + + ref char matchRef = ref Unsafe.Add(ref searchSpace, bitPos); + + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref matchRef, _valueState.Value.Length); + + if (CanSkipAnchorMatchVerification || TCaseSensitivity.Equals(ref matchRef, in _valueState)) + { + offsetFromStart = (int)((nuint)Unsafe.ByteOffset(ref searchSpaceStart, ref matchRef) / sizeof(char)); + return true; + } + + mask = BitOperations.ResetLowestSetBit(mask); + } + while (mask != 0); + + offsetFromStart = 0; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool TryMatch(ref char searchSpaceStart, int searchSpaceLength, ref char searchSpace, ulong mask, out int offsetFromStart) + { + // 'mask' encodes the input positions where at least 3 characters likely matched. + // Verify each one to see if we've found a match, otherwise return back to the vectorized loop. + do + { + int bitPos = BitOperations.TrailingZeroCount(mask); + + ref char matchRef = ref Unsafe.Add(ref searchSpace, bitPos); + + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref matchRef, _valueState.Value.Length); + + if (CanSkipAnchorMatchVerification || TCaseSensitivity.Equals(ref matchRef, in _valueState)) + { + offsetFromStart = (int)((nuint)Unsafe.ByteOffset(ref searchSpaceStart, ref matchRef) / sizeof(char)); + return true; + } + + mask = BitOperations.ResetLowestSetBit(mask); + } + while (mask != 0); + + offsetFromStart = 0; + return false; + } + + internal override bool ContainsCore(string value) => HasUniqueValues + ? base.ContainsCore(value) + : _valueState.Value.Equals(value, IgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); + + internal override string[] GetValues() => HasUniqueValues + ? base.GetValues() + : [_valueState.Value]; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [CompExactlyDependsOn(typeof(Sse2))] + [CompExactlyDependsOn(typeof(AdvSimd.Arm64))] + private static Vector128 LoadPacked128(ref char searchSpace, nuint byteOffset) + { + Vector128 input0 = Vector128.LoadUnsafe(ref Unsafe.AddByteOffset(ref searchSpace, byteOffset)); + Vector128 input1 = Vector128.LoadUnsafe(ref Unsafe.AddByteOffset(ref searchSpace, byteOffset + (uint)Vector128.Count)); + + return Sse2.IsSupported + ? Sse2.PackUnsignedSaturate(input0.AsInt16(), input1.AsInt16()) + : AdvSimd.Arm64.UnzipEven(input0.AsByte(), input1.AsByte()); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [CompExactlyDependsOn(typeof(Avx2))] + private static Vector256 LoadPacked256(ref char searchSpace, nuint byteOffset) => + Avx2.PackUnsignedSaturate( + Vector256.LoadUnsafe(ref Unsafe.AddByteOffset(ref searchSpace, byteOffset)).AsInt16(), + Vector256.LoadUnsafe(ref Unsafe.AddByteOffset(ref searchSpace, byteOffset + (uint)Vector256.Count)).AsInt16()); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [CompExactlyDependsOn(typeof(Avx512BW))] + private static Vector512 LoadPacked512(ref char searchSpace, nuint byteOffset) => + Avx512BW.PackUnsignedSaturate( + Vector512.LoadUnsafe(ref Unsafe.AddByteOffset(ref searchSpace, byteOffset)).AsInt16(), + Vector512.LoadUnsafe(ref Unsafe.AddByteOffset(ref searchSpace, byteOffset + (uint)Vector512.Count)).AsInt16()); + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/SingleStringSearchValuesThreeChars.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/SingleStringSearchValuesThreeChars.cs index c005173b67e143..9640f9040b630e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/SingleStringSearchValuesThreeChars.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/SingleStringSearchValuesThreeChars.cs @@ -43,13 +43,10 @@ private static bool CanSkipAnchorMatchVerification (typeof(TCaseSensitivity) == typeof(CaseSensitive) || typeof(TCaseSensitivity) == typeof(CaseInsensitiveAsciiLetters)); } - public SingleStringSearchValuesThreeChars(HashSet? uniqueValues, string value) : base(uniqueValues) + public SingleStringSearchValuesThreeChars(HashSet? uniqueValues, string value, int ch2Offset, int ch3Offset) : base(uniqueValues) { // We could have more than one entry in 'uniqueValues' if this value is an exact prefix of all the others. Debug.Assert(value.Length > 1); - - CharacterFrequencyHelper.GetSingleStringMultiCharacterOffsets(value, IgnoreCase, out int ch2Offset, out int ch3Offset); - Debug.Assert(ch3Offset == 0 || ch3Offset > ch2Offset); _valueState = new SingleValueState(value, IgnoreCase); @@ -61,6 +58,8 @@ public SingleStringSearchValuesThreeChars(HashSet? uniqueValues, string if (IgnoreCase) { + Debug.Assert(char.IsAscii((char)_ch1) && char.IsAscii((char)_ch2) && char.IsAscii((char)_ch3)); + _ch1 &= CaseConversionMask; _ch2 &= CaseConversionMask; _ch3 &= CaseConversionMask; @@ -99,8 +98,8 @@ private int IndexOf(ref char searchSpace, int searchSpaceLength) while (true) { ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector512.Count); - ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector512.Count + (int)(_ch2ByteOffset / 2)); - ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector512.Count + (int)(_ch3ByteOffset / 2)); + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector512.Count + (int)(_ch2ByteOffset / sizeof(char))); + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector512.Count + (int)(_ch3ByteOffset / sizeof(char))); // Find which starting positions likely contain a match (likely match all 3 anchor characters). Vector512 result = GetComparisonResult(ref searchSpace, ch2ByteOffset, ch3ByteOffset, ch1, ch2, ch3); @@ -147,8 +146,8 @@ private int IndexOf(ref char searchSpace, int searchSpaceLength) while (true) { ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector256.Count); - ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector256.Count + (int)(_ch2ByteOffset / 2)); - ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector256.Count + (int)(_ch3ByteOffset / 2)); + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector256.Count + (int)(_ch2ByteOffset / sizeof(char))); + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector256.Count + (int)(_ch3ByteOffset / sizeof(char))); // Find which starting positions likely contain a match (likely match all 3 anchor characters). Vector256 result = GetComparisonResult(ref searchSpace, ch2ByteOffset, ch3ByteOffset, ch1, ch2, ch3); @@ -194,8 +193,8 @@ private int IndexOf(ref char searchSpace, int searchSpaceLength) while (true) { ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector128.Count); - ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector128.Count + (int)(_ch2ByteOffset / 2)); - ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector128.Count + (int)(_ch3ByteOffset / 2)); + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector128.Count + (int)(_ch2ByteOffset / sizeof(char))); + ValidateReadPosition(ref searchSpaceStart, searchSpaceLength, ref searchSpace, Vector128.Count + (int)(_ch3ByteOffset / sizeof(char))); // Find which starting positions likely contain a match (likely match all 3 anchor characters). Vector128 result = GetComparisonResult(ref searchSpace, ch2ByteOffset, ch3ByteOffset, ch1, ch2, ch3); @@ -281,7 +280,7 @@ private static Vector128 GetComparisonResult(ref char searchSpace, nuint c private static Vector256 GetComparisonResult(ref char searchSpace, nuint ch2ByteOffset, nuint ch3ByteOffset, Vector256 ch1, Vector256 ch2, Vector256 ch3) { // See comments in 'GetComparisonResult' for Vector128 above. - // This method is the same, but operates on 32 input characters at a time. + // This method is the same, but operates on 16 input characters at a time. if (typeof(TCaseSensitivity) == typeof(CaseSensitive)) { Vector256 cmpCh1 = Vector256.Equals(ch1, Vector256.LoadUnsafe(ref searchSpace)); @@ -304,7 +303,7 @@ private static Vector256 GetComparisonResult(ref char searchSpace, nuint c private static Vector512 GetComparisonResult(ref char searchSpace, nuint ch2ByteOffset, nuint ch3ByteOffset, Vector512 ch1, Vector512 ch2, Vector512 ch3) { // See comments in 'GetComparisonResult' for Vector128 above. - // This method is the same, but operates on 64 input characters at a time. + // This method is the same, but operates on 32 input characters at a time. if (typeof(TCaseSensitivity) == typeof(CaseSensitive)) { Vector512 cmpCh1 = Vector512.Equals(ch1, Vector512.LoadUnsafe(ref searchSpace)); @@ -339,7 +338,7 @@ private bool TryMatch(ref char searchSpaceStart, int searchSpaceLength, ref char if (CanSkipAnchorMatchVerification || TCaseSensitivity.Equals(ref matchRef, in _valueState)) { - offsetFromStart = (int)((nuint)Unsafe.ByteOffset(ref searchSpaceStart, ref matchRef) / 2); + offsetFromStart = (int)((nuint)Unsafe.ByteOffset(ref searchSpaceStart, ref matchRef) / sizeof(char)); return true; } @@ -379,7 +378,6 @@ private bool TryMatch(ref char searchSpaceStart, int searchSpaceLength, ref char return false; } - internal override bool ContainsCore(string value) => HasUniqueValues ? base.ContainsCore(value) : _valueState.Value.Equals(value, IgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); diff --git a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/StringSearchValues.cs b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/StringSearchValues.cs index 42ae98a2b440ce..05db4d2f96bf73 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/StringSearchValues.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SearchValues/Strings/StringSearchValues.cs @@ -417,29 +417,51 @@ private static SearchValues CreateForSingleValue( { if (!ignoreCase) { - return new SingleStringSearchValuesThreeChars(uniqueValues, value); + return CreateSingleValuesThreeChars(value, uniqueValues); } if (asciiLettersOnly) { - return new SingleStringSearchValuesThreeChars(uniqueValues, value); + return CreateSingleValuesThreeChars(value, uniqueValues); } if (allAscii) { - return new SingleStringSearchValuesThreeChars(uniqueValues, value); + return CreateSingleValuesThreeChars(value, uniqueValues); } // SingleStringSearchValuesThreeChars doesn't have logic to handle non-ASCII case conversion, so we require that anchor characters are ASCII. // Right now we're always selecting the first character as one of the anchors, and we need at least two. if (char.IsAscii(value[0]) && value.AsSpan(1).ContainsAnyInRange((char)0, (char)127)) { - return new SingleStringSearchValuesThreeChars(uniqueValues, value); + return CreateSingleValuesThreeChars(value, uniqueValues); } return null; } + private static SearchValues CreateSingleValuesThreeChars( + string value, + HashSet? uniqueValues) + where TValueLength : struct, IValueLength + where TCaseSensitivity : struct, ICaseSensitivity + { + CharacterFrequencyHelper.GetSingleStringMultiCharacterOffsets(value, ignoreCase: typeof(TCaseSensitivity) != typeof(CaseSensitive), out int ch2Offset, out int ch3Offset); + + if (CanUsePackedImpl(value[0]) && CanUsePackedImpl(value[ch2Offset]) && CanUsePackedImpl(value[ch3Offset])) + { + return new SingleStringSearchValuesPackedThreeChars(uniqueValues, value, ch2Offset, ch3Offset); + } + + return new SingleStringSearchValuesThreeChars(uniqueValues, value, ch2Offset, ch3Offset); + + // Unlike with PackedSpanHelpers (Sse2 only), we are also using this approach on ARM64. + // We use PackUnsignedSaturate on X86 and UnzipEven on ARM, so the set of allowed characters differs slightly (we can't use it for \0 and \xFF on X86). + static bool CanUsePackedImpl(char c) => + PackedSpanHelpers.PackedIndexOfIsSupported ? PackedSpanHelpers.CanUsePackedIndexOf(c) : + (AdvSimd.Arm64.IsSupported && c <= byte.MaxValue); + } + private static void AnalyzeValues( ReadOnlySpan values, ref bool ignoreCase, diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Packed.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Packed.cs index 52eb1b0b2bedce..70f03605d66a32 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Packed.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Packed.cs @@ -156,7 +156,7 @@ public static bool Contains(ref short searchSpace, short value, int length) // Process the input in chunks of 64 characters (2 * Vector512). // If the input length is a multiple of 64, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector512.Count)); do @@ -205,7 +205,7 @@ public static bool Contains(ref short searchSpace, short value, int length) // Process the input in chunks of 32 characters (2 * Vector256). // If the input length is a multiple of 32, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector256.Count)); do @@ -263,7 +263,7 @@ public static bool Contains(ref short searchSpace, short value, int length) // Process the input in chunks of 16 characters (2 * Vector128). // If the input length is a multiple of 16, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector128.Count)); do @@ -355,7 +355,7 @@ private static int IndexOf(ref short searchSpace, short va // Process the input in chunks of 64 characters (2 * Vector512). // If the input length is a multiple of 64, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector512.Count)); do @@ -404,7 +404,7 @@ private static int IndexOf(ref short searchSpace, short va // Process the input in chunks of 32 characters (2 * Vector256). // If the input length is a multiple of 32, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector256.Count)); do @@ -464,7 +464,7 @@ private static int IndexOf(ref short searchSpace, short va // Process the input in chunks of 16 characters (2 * Vector128). // If the input length is a multiple of 16, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector128.Count)); do @@ -565,7 +565,7 @@ private static int IndexOfAny(ref short searchSpace, short // Process the input in chunks of 64 characters (2 * Vector512). // If the input length is a multiple of 64, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector512.Count)); do @@ -617,7 +617,7 @@ private static int IndexOfAny(ref short searchSpace, short // Process the input in chunks of 32 characters (2 * Vector256). // If the input length is a multiple of 32, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector256.Count)); do @@ -678,7 +678,7 @@ private static int IndexOfAny(ref short searchSpace, short // Process the input in chunks of 16 characters (2 * Vector128). // If the input length is a multiple of 16, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector128.Count)); do @@ -781,7 +781,7 @@ private static int IndexOfAny(ref short searchSpace, short value0, sho // Process the input in chunks of 64 characters (2 * Vector512). // If the input length is a multiple of 64, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector512.Count)); do @@ -834,7 +834,7 @@ private static int IndexOfAny(ref short searchSpace, short value0, sho // Process the input in chunks of 32 characters (2 * Vector256). // If the input length is a multiple of 32, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector256.Count)); do @@ -896,7 +896,7 @@ private static int IndexOfAny(ref short searchSpace, short value0, sho // Process the input in chunks of 16 characters (2 * Vector128). // If the input length is a multiple of 16, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector128.Count)); do @@ -980,7 +980,7 @@ private static int IndexOfAnyInRange(ref short searchSpace, short lowI // Process the input in chunks of 64 characters (2 * Vector512). // If the input length is a multiple of 64, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector512.Count)); do @@ -1030,7 +1030,7 @@ private static int IndexOfAnyInRange(ref short searchSpace, short lowI // Process the input in chunks of 32 characters (2 * Vector256). // If the input length is a multiple of 32, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector256.Count)); do @@ -1091,7 +1091,7 @@ private static int IndexOfAnyInRange(ref short searchSpace, short lowI // Process the input in chunks of 16 characters (2 * Vector128). // If the input length is a multiple of 16, don't consume the last 16 characters in this loop. // Let the fallback below handle it instead. This is why the condition is - // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "!IsAddressGreaterThan". + // ">" instead of ">=" above, and why "IsAddressLessThan" is used instead of "IsAddressLessThanOrEqualTo". ref short twoVectorsAwayFromEnd = ref Unsafe.Add(ref searchSpace, length - (2 * Vector128.Count)); do diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs index c29adea608902a..cf8e536c5fded1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs @@ -1383,7 +1383,7 @@ internal static bool NonPackedContainsValueType(ref T searchSpace, T value, i currentSearchSpace = ref Unsafe.Add(ref currentSearchSpace, Vector512.Count); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the last vector in the search space. if ((uint)length % Vector512.Count != 0) @@ -1414,7 +1414,7 @@ internal static bool NonPackedContainsValueType(ref T searchSpace, T value, i return true; } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the last vector in the search space. if ((uint)length % Vector256.Count != 0) @@ -1444,7 +1444,7 @@ internal static bool NonPackedContainsValueType(ref T searchSpace, T value, i return true; } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the first vector in the search space. if ((uint)length % Vector128.Count != 0) @@ -1574,7 +1574,7 @@ internal static int NonPackedIndexOfValueType(ref TValue searc currentSearchSpace = ref Unsafe.Add(ref currentSearchSpace, Vector512.Count); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the last vector in the search space. if ((uint)length % Vector512.Count != 0) @@ -1605,7 +1605,7 @@ internal static int NonPackedIndexOfValueType(ref TValue searc return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the last vector in the search space. if ((uint)length % Vector256.Count != 0) @@ -1635,7 +1635,7 @@ internal static int NonPackedIndexOfValueType(ref TValue searc return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the first vector in the search space. if ((uint)length % Vector128.Count != 0) @@ -1800,7 +1800,7 @@ internal static int NonPackedIndexOfAnyValueType(ref TValue se return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the last vector in the search space. if ((uint)length % Vector512.Count != 0) @@ -1832,7 +1832,7 @@ internal static int NonPackedIndexOfAnyValueType(ref TValue se return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the last vector in the search space. if ((uint)length % Vector256.Count != 0) @@ -1864,7 +1864,7 @@ internal static int NonPackedIndexOfAnyValueType(ref TValue se return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the first vector in the search space. if ((uint)length % Vector128.Count != 0) @@ -2007,7 +2007,7 @@ internal static int NonPackedIndexOfAnyValueType(ref TValue se return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the last vector in the search space. if ((uint)length % Vector512.Count != 0) @@ -2039,7 +2039,7 @@ internal static int NonPackedIndexOfAnyValueType(ref TValue se return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the last vector in the search space. if ((uint)length % Vector256.Count != 0) @@ -2071,7 +2071,7 @@ internal static int NonPackedIndexOfAnyValueType(ref TValue se return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the first vector in the search space. if ((uint)length % Vector128.Count != 0) @@ -2164,7 +2164,7 @@ private static int IndexOfAnyValueType(ref TValue searchSpace, return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the last vector in the search space. if ((uint)length % Vector512.Count != 0) @@ -2198,7 +2198,7 @@ private static int IndexOfAnyValueType(ref TValue searchSpace, return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the last vector in the search space. if ((uint)length % Vector256.Count != 0) @@ -2232,7 +2232,7 @@ private static int IndexOfAnyValueType(ref TValue searchSpace, return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the first vector in the search space. if ((uint)length % Vector128.Count != 0) @@ -2328,7 +2328,7 @@ private static int IndexOfAnyValueType(ref TValue searchSpace, return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the last vector in the search space. if ((uint)length % Vector512.Count != 0) @@ -2363,7 +2363,7 @@ private static int IndexOfAnyValueType(ref TValue searchSpace, return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the last vector in the search space. if ((uint)length % Vector256.Count != 0) @@ -2398,7 +2398,7 @@ private static int IndexOfAnyValueType(ref TValue searchSpace, return ComputeFirstIndex(ref searchSpace, ref currentSearchSpace, equals); } - while (!Unsafe.IsAddressGreaterThan(ref currentSearchSpace, ref oneVectorAwayFromEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentSearchSpace, ref oneVectorAwayFromEnd)); // If any elements remain, process the first vector in the search space. if ((uint)length % Vector128.Count != 0) diff --git a/src/libraries/System.Private.CoreLib/src/System/StartupHookProvider.cs b/src/libraries/System.Private.CoreLib/src/System/StartupHookProvider.cs index 5a5a6db49d8585..eaf92e10beb5c4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/StartupHookProvider.cs +++ b/src/libraries/System.Private.CoreLib/src/System/StartupHookProvider.cs @@ -161,7 +161,7 @@ private static void CallStartupHook(StartupHookNameOrPath startupHook) catch (Exception assemblyLoadException) { throw new ArgumentException( - SR.Format(SR.Argument_StartupHookAssemblyLoadFailed, startupHook.Path ?? startupHook.AssemblyName!.ToString()), + SR.Format(SR.Argument_StartupHookAssemblyLoadFailed, startupHook.Path ?? startupHook.AssemblyName.ToString()), assemblyLoadException); } diff --git a/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs b/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs index f9261106b34c73..458aa815cd6560 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs +++ b/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/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs b/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs index 8c4d5f786c597d..46738b2c59bafe 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs @@ -924,7 +924,7 @@ private static string JoinCore(ReadOnlySpan separator, IEnumerable v { if (values.GetType() == typeof(List)) // avoid accidentally bypassing a derived type's reimplementation of IEnumerable { - return JoinCore(separator, CollectionsMarshal.AsSpan(Unsafe.As>(values))); + return JoinCore(separator, CollectionsMarshal.AsSpan((List)values)); } if (values is string?[] valuesArray) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIEncoding.cs b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIEncoding.cs index 3aae57e98ef6c1..c33c8fd9090514 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIEncoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIEncoding.cs @@ -88,7 +88,7 @@ public override unsafe int GetByteCount(char[] chars, int index, int count) ThrowHelper.ThrowArgumentOutOfRangeException((index < 0) ? ExceptionArgument.index : ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); } - if (chars!.Length - index < count) + if (chars.Length - index < count) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.chars, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer); } @@ -113,7 +113,7 @@ public override unsafe int GetByteCount(string chars) fixed (char* pChars = chars) { - return GetByteCountCommon(pChars, chars!.Length); + return GetByteCountCommon(pChars, chars.Length); } } @@ -222,12 +222,12 @@ public override unsafe int GetBytes(string chars, int charIndex, int charCount, resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); } - if (chars!.Length - charIndex < charCount) + if (chars.Length - charIndex < charCount) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.chars, ExceptionResource.ArgumentOutOfRange_IndexCount); } - if ((uint)byteIndex > bytes!.Length) + if ((uint)byteIndex > bytes.Length) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.byteIndex, ExceptionResource.ArgumentOutOfRange_IndexMustBeLessOrEqual); } @@ -270,12 +270,12 @@ public override unsafe int GetBytes(char[] chars, int charIndex, int charCount, resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); } - if (chars!.Length - charIndex < charCount) + if (chars.Length - charIndex < charCount) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.chars, ExceptionResource.ArgumentOutOfRange_IndexCount); } - if ((uint)byteIndex > bytes!.Length) + if ((uint)byteIndex > bytes.Length) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.byteIndex, ExceptionResource.ArgumentOutOfRange_IndexMustBeLessOrEqual); } @@ -448,7 +448,7 @@ public override unsafe int GetCharCount(byte[] bytes, int index, int count) ThrowHelper.ThrowArgumentOutOfRangeException((index < 0) ? ExceptionArgument.index : ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); } - if (bytes!.Length - index < count) + if (bytes.Length - index < count) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.bytes, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer); } @@ -561,12 +561,12 @@ public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount, resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); } - if (bytes!.Length - byteIndex < byteCount) + if (bytes.Length - byteIndex < byteCount) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.bytes, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer); } - if ((uint)charIndex > (uint)chars!.Length) + if ((uint)charIndex > (uint)chars.Length) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.charIndex, ExceptionResource.ArgumentOutOfRange_IndexMustBeLessOrEqual); } @@ -738,7 +738,7 @@ public override unsafe string GetString(byte[] bytes, int byteIndex, int byteCou resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); } - if (bytes!.Length - byteIndex < byteCount) + if (bytes.Length - byteIndex < byteCount) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.bytes, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.Equality.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.Equality.cs index 77c3d8de92fb23..3814ba3fe622b3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.Equality.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.Equality.cs @@ -83,7 +83,7 @@ private static bool Equals(ref TLeft left, ref TRight ri currentRightSearchSpace = ref Unsafe.Add(ref currentRightSearchSpace, Vector512.Count); currentLeftSearchSpace = ref Unsafe.Add(ref currentLeftSearchSpace, Vector512.Count); } - while (!Unsafe.IsAddressGreaterThan(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); // If any elements remain, process the last vector in the search space. if (length % (uint)Vector512.Count != 0) @@ -113,7 +113,7 @@ private static bool Equals(ref TLeft left, ref TRight ri currentRightSearchSpace = ref Unsafe.Add(ref currentRightSearchSpace, Vector256.Count); currentLeftSearchSpace = ref Unsafe.Add(ref currentLeftSearchSpace, Vector256.Count); } - while (!Unsafe.IsAddressGreaterThan(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); // If any elements remain, process the last vector in the search space. if (length % (uint)Vector256.Count != 0) @@ -147,7 +147,7 @@ private static bool Equals(ref TLeft left, ref TRight ri currentRightSearchSpace = ref Unsafe.Add(ref currentRightSearchSpace, (uint)Vector128.Count); currentLeftSearchSpace = ref Unsafe.Add(ref currentLeftSearchSpace, TLoader.Count128); } - while (!Unsafe.IsAddressGreaterThan(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); // If any elements remain, process the last vector in the search space. if (length % (uint)Vector128.Count != 0) @@ -274,7 +274,7 @@ private static bool EqualsIgnoreCase(ref TLeft left, ref currentRightSearchSpace = ref Unsafe.Add(ref currentRightSearchSpace, (uint)Vector512.Count); currentLeftSearchSpace = ref Unsafe.Add(ref currentLeftSearchSpace, TLoader.Count512); } - while (!Unsafe.IsAddressGreaterThan(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); // If any elements remain, process the last vector in the search space. if (length % (uint)Vector512.Count != 0) @@ -346,7 +346,7 @@ private static bool EqualsIgnoreCase(ref TLeft left, ref currentRightSearchSpace = ref Unsafe.Add(ref currentRightSearchSpace, (uint)Vector256.Count); currentLeftSearchSpace = ref Unsafe.Add(ref currentLeftSearchSpace, TLoader.Count256); } - while (!Unsafe.IsAddressGreaterThan(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); // If any elements remain, process the last vector in the search space. if (length % (uint)Vector256.Count != 0) @@ -419,7 +419,7 @@ private static bool EqualsIgnoreCase(ref TLeft left, ref currentRightSearchSpace = ref Unsafe.Add(ref currentRightSearchSpace, (uint)Vector128.Count); currentLeftSearchSpace = ref Unsafe.Add(ref currentLeftSearchSpace, TLoader.Count128); } - while (!Unsafe.IsAddressGreaterThan(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); + while (Unsafe.IsAddressLessThanOrEqualTo(ref currentRightSearchSpace, ref oneVectorAwayFromRightEnd)); // If any elements remain, process the last vector in the search space. if (length % (uint)Vector128.Count != 0) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs index e60a5eca24b1c7..77e490b03c5b68 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs @@ -1110,7 +1110,7 @@ internal void ThrowBytesOverflow(EncoderNLS? encoder, bool nothingEncoded) } // If we didn't throw, we are in convert and have to remember our flushing - encoder!.ClearMustFlush(); + encoder.ClearMustFlush(); } [DoesNotReturn] @@ -1139,7 +1139,7 @@ internal void ThrowCharsOverflow(DecoderNLS? decoder, bool nothingDecoded) } // If we didn't throw, we are in convert and have to remember our flushing - decoder!.ClearMustFlush(); + decoder.ClearMustFlush(); } internal sealed class DefaultEncoder : Encoder diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs index e129b5284bcb2a..4992ce77626646 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs @@ -206,12 +206,12 @@ public override unsafe int GetBytes(char[] chars, int charIndex, int charCount, resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); } - if (chars!.Length - charIndex < charCount) + if (chars.Length - charIndex < charCount) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.chars, ExceptionResource.ArgumentOutOfRange_IndexCount); } - if ((uint)byteIndex > bytes!.Length) + if ((uint)byteIndex > bytes.Length) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.byteIndex, ExceptionResource.ArgumentOutOfRange_IndexMustBeLessOrEqual); } @@ -268,12 +268,12 @@ public override unsafe int GetBytes(string s, int charIndex, int charCount, byte resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); } - if (s!.Length - charIndex < charCount) + if (s.Length - charIndex < charCount) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.s, ExceptionResource.ArgumentOutOfRange_IndexCount); } - if ((uint)byteIndex > bytes!.Length) + if ((uint)byteIndex > bytes.Length) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.byteIndex, ExceptionResource.ArgumentOutOfRange_IndexMustBeLessOrEqual); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.cs index 992a9f6bdcbab1..9bcbf9390df28f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.cs @@ -287,7 +287,7 @@ internal static bool UInt64OrdinalIgnoreCaseAscii(ulong valueA, ulong valueB) internal static bool AllCharsInVectorAreAscii(TVector vec) where TVector : struct, ISimdVector { - return (vec & TVector.Create(unchecked((ushort)~0x007F))).Equals(TVector.Zero); + return (vec & TVector.Create(unchecked((ushort)~0x007F))) == TVector.Zero; } #endif } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs index 3f74b53818ffcb..81b47297b83e1e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs @@ -192,25 +192,23 @@ public static float Exchange(ref float location1, float value) public static double Exchange(ref double location1, double value) => Unsafe.BitCast(Exchange(ref Unsafe.As(ref location1), Unsafe.BitCast(value))); - /// Sets a platform-specific handle or pointer to a specified value and returns the original value, as an atomic operation. + /// Sets a native-sized signed integer to a specified value and returns the original value, as an atomic operation. /// The variable to set to the specified value. /// The value to which the parameter is set. /// The original value of . /// The address of location1 is a null pointer. [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IntPtr Exchange(ref IntPtr location1, IntPtr value) + public static nint Exchange(ref nint location1, nint value) { -#pragma warning disable CA2020 // Prevent from behavioral change #if TARGET_64BIT - return (IntPtr)Interlocked.Exchange(ref Unsafe.As(ref location1), (long)value); + return (nint)Exchange(ref Unsafe.As(ref location1), (long)value); #else - return (IntPtr)Exchange(ref Unsafe.As(ref location1), (int)value); + return (nint)Exchange(ref Unsafe.As(ref location1), (int)value); #endif -#pragma warning restore CA2020 } - /// Sets a platform-specific handle or pointer to a specified value and returns the original value, as an atomic operation. + /// Sets a native-sized unsigned integer to a specified value and returns the original value, as an atomic operation. /// The variable to set to the specified value. /// The value to which the parameter is set. /// The original value of . @@ -218,12 +216,12 @@ public static IntPtr Exchange(ref IntPtr location1, IntPtr value) [Intrinsic] [CLSCompliant(false)] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UIntPtr Exchange(ref UIntPtr location1, UIntPtr value) + public static nuint Exchange(ref nuint location1, nuint value) { #if TARGET_64BIT - return (UIntPtr)Interlocked.Exchange(ref Unsafe.As(ref location1), (long)value); + return (nuint)Exchange(ref Unsafe.As(ref location1), (long)value); #else - return (UIntPtr)Exchange(ref Unsafe.As(ref location1), (int)value); + return (nuint)Exchange(ref Unsafe.As(ref location1), (int)value); #endif } @@ -441,40 +439,38 @@ public static float CompareExchange(ref float location1, float value, float comp public static double CompareExchange(ref double location1, double value, double comparand) => Unsafe.BitCast(CompareExchange(ref Unsafe.As(ref location1), Unsafe.BitCast(value), Unsafe.BitCast(comparand))); - /// Compares two platform-specific handles or pointers for equality and, if they are equal, replaces the first one. - /// The destination , whose value is compared with the value of and possibly replaced by . - /// The that replaces the destination value if the comparison results in equality. - /// The that is compared to the value at . + /// Compares two native-sized signed integers for equality and, if they are equal, replaces the first one. + /// The destination, whose value is compared with the value of and possibly replaced by . + /// The value that replaces the destination value if the comparison results in equality. + /// The value that is compared to the value at . /// The original value in . /// The address of is a null pointer. [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IntPtr CompareExchange(ref IntPtr location1, IntPtr value, IntPtr comparand) + public static nint CompareExchange(ref nint location1, nint value, nint comparand) { -#pragma warning disable CA2020 // Prevent from behavioral change #if TARGET_64BIT - return (IntPtr)Interlocked.CompareExchange(ref Unsafe.As(ref location1), (long)value, (long)comparand); + return (nint)CompareExchange(ref Unsafe.As(ref location1), (long)value, (long)comparand); #else - return (IntPtr)CompareExchange(ref Unsafe.As(ref location1), (int)value, (int)comparand); + return (nint)CompareExchange(ref Unsafe.As(ref location1), (int)value, (int)comparand); #endif -#pragma warning restore CA2020 } - /// Compares two platform-specific handles or pointers for equality and, if they are equal, replaces the first one. - /// The destination , whose value is compared with the value of and possibly replaced by . - /// The that replaces the destination value if the comparison results in equality. - /// The that is compared to the value at . + /// Compares two native-sized unsigned integers for equality and, if they are equal, replaces the first one. + /// The destination, whose value is compared with the value of and possibly replaced by . + /// The value that replaces the destination value if the comparison results in equality. + /// The value that is compared to the value at . /// The original value in . /// The address of is a null pointer. [Intrinsic] [CLSCompliant(false)] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UIntPtr CompareExchange(ref UIntPtr location1, UIntPtr value, UIntPtr comparand) + public static nuint CompareExchange(ref nuint location1, nuint value, nuint comparand) { #if TARGET_64BIT - return (UIntPtr)Interlocked.CompareExchange(ref Unsafe.As(ref location1), (long)value, (long)comparand); + return (nuint)CompareExchange(ref Unsafe.As(ref location1), (long)value, (long)comparand); #else - return (UIntPtr)CompareExchange(ref Unsafe.As(ref location1), (int)value, (int)comparand); + return (nuint)CompareExchange(ref Unsafe.As(ref location1), (int)value, (int)comparand); #endif } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ManualResetEventSlim.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ManualResetEventSlim.cs index 78f83a11bf66b0..54b6596d6a4c94 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ManualResetEventSlim.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ManualResetEventSlim.cs @@ -508,7 +508,7 @@ public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) // We spin briefly before falling back to allocating and/or waiting on a true event. - uint startTime = 0; + long startTime = 0; bool bNeedTimeoutAdjustment = false; int realMillisecondsTimeout = millisecondsTimeout; // this will be adjusted if necessary. @@ -520,7 +520,7 @@ public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) // period of time. The timeout adjustments only take effect when and if we actually // decide to block in the kernel below. - startTime = TimeoutHelper.GetTime(); + startTime = Environment.TickCount64; bNeedTimeoutAdjustment = true; } @@ -558,7 +558,8 @@ public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) // update timeout (delays in wait commencement are due to spinning and/or spurious wakeups from other waits being canceled) if (bNeedTimeoutAdjustment) { - realMillisecondsTimeout = TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout); + // TimeoutHelper.UpdateTimeOut returns a long but the value is capped as millisecondsTimeout is an int. + realMillisecondsTimeout = (int)TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout); if (realMillisecondsTimeout <= 0) return false; } diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/PortableThreadPool.Browser.Threads.Mono.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.Browser.Threads.cs similarity index 100% rename from src/mono/System.Private.CoreLib/src/System/Threading/PortableThreadPool.Browser.Threads.Mono.cs rename to src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.Browser.Threads.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs index 37a13598e1657f..070b4e2c99d940 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs @@ -348,7 +348,7 @@ internal bool NotifyWorkItemComplete(object? threadLocalCompletionCountObject, i { Debug.Assert(threadLocalCompletionCountObject != null); - NotifyWorkItemProgress(threadLocalCompletionCountObject!, currentTimeMs); + NotifyWorkItemProgress(threadLocalCompletionCountObject, currentTimeMs); return !WorkerThread.ShouldStopProcessingWorkNow(this); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.Windows.cs index 2e0d8b4eeae789..b464a5ed81e8b6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Semaphore.Windows.cs @@ -193,7 +193,7 @@ private static OpenExistingResult OpenExistingWorker( private int ReleaseCore(int releaseCount) { - if (!Interop.Kernel32.ReleaseSemaphore(SafeWaitHandle!, releaseCount, out int previousCount)) + if (!Interop.Kernel32.ReleaseSemaphore(SafeWaitHandle, releaseCount, out int previousCount)) throw new SemaphoreFullException(); return previousCount; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs index bab6bbd332b19a..bae72e8311816b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs @@ -178,7 +178,7 @@ public void Wait() if (OperatingSystem.IsWasi()) throw new PlatformNotSupportedException(); // TODO remove with https://github.com/dotnet/runtime/pull/107185 #endif // Call wait with infinite timeout - Wait(Timeout.Infinite, CancellationToken.None); + WaitCore(Timeout.Infinite, CancellationToken.None); } /// @@ -198,7 +198,7 @@ public void Wait(CancellationToken cancellationToken) if (OperatingSystem.IsWasi()) throw new PlatformNotSupportedException(); // TODO remove with https://github.com/dotnet/runtime/pull/107185 #endif // Call wait with infinite timeout - Wait(Timeout.Infinite, cancellationToken); + WaitCore(Timeout.Infinite, cancellationToken); } /// @@ -211,8 +211,7 @@ public void Wait(CancellationToken cancellationToken) /// true if the current thread successfully entered the ; /// otherwise, false. /// is a negative - /// number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater - /// than . + /// number other than -1 milliseconds, which represents an infinite time-out. [UnsupportedOSPlatform("browser")] public bool Wait(TimeSpan timeout) { @@ -221,14 +220,14 @@ public bool Wait(TimeSpan timeout) #endif // Validate the timeout long totalMilliseconds = (long)timeout.TotalMilliseconds; - if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) + if (totalMilliseconds < -1) { throw new ArgumentOutOfRangeException( - nameof(timeout), timeout, SR.SemaphoreSlim_Wait_TimeoutWrong); + nameof(timeout), timeout, SR.SemaphoreSlim_Wait_TimeSpanTimeoutWrong); } // Call wait with the timeout milliseconds - return Wait((int)timeout.TotalMilliseconds, CancellationToken.None); + return WaitCore(totalMilliseconds, CancellationToken.None); } /// @@ -244,8 +243,7 @@ public bool Wait(TimeSpan timeout) /// true if the current thread successfully entered the ; /// otherwise, false. /// is a negative - /// number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater - /// than . + /// number other than -1 milliseconds, which represents an infinite time-out. /// was canceled. [UnsupportedOSPlatform("browser")] public bool Wait(TimeSpan timeout, CancellationToken cancellationToken) @@ -255,14 +253,14 @@ public bool Wait(TimeSpan timeout, CancellationToken cancellationToken) #endif // Validate the timeout long totalMilliseconds = (long)timeout.TotalMilliseconds; - if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) + if (totalMilliseconds < -1) { throw new ArgumentOutOfRangeException( - nameof(timeout), timeout, SR.SemaphoreSlim_Wait_TimeoutWrong); + nameof(timeout), timeout, SR.SemaphoreSlim_Wait_TimeSpanTimeoutWrong); } // Call wait with the timeout milliseconds - return Wait((int)timeout.TotalMilliseconds, cancellationToken); + return WaitCore(totalMilliseconds, cancellationToken); } /// @@ -281,7 +279,7 @@ public bool Wait(int millisecondsTimeout) #if TARGET_WASI if (OperatingSystem.IsWasi()) throw new PlatformNotSupportedException(); // TODO remove with https://github.com/dotnet/runtime/pull/107185 #endif - return Wait(millisecondsTimeout, CancellationToken.None); + return WaitCore(millisecondsTimeout, CancellationToken.None); } /// @@ -302,10 +300,6 @@ public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) #if TARGET_WASI if (OperatingSystem.IsWasi()) throw new PlatformNotSupportedException(); // TODO remove with https://github.com/dotnet/runtime/pull/107185 #endif - CheckDispose(); -#if FEATURE_WASM_MANAGED_THREADS - Thread.AssureBlockingPossible(); -#endif if (millisecondsTimeout < -1) { @@ -313,6 +307,26 @@ public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) nameof(millisecondsTimeout), millisecondsTimeout, SR.SemaphoreSlim_Wait_TimeoutWrong); } + return WaitCore(millisecondsTimeout, cancellationToken); + } + + /// + /// Blocks the current thread until it can enter the , + /// using a 32-bit unsigned integer to measure the time interval, + /// while observing a . + /// + /// The number of milliseconds to wait, or to + /// wait indefinitely. + /// The to observe. + /// true if the current thread successfully entered the ; otherwise, false. + /// was canceled. + [UnsupportedOSPlatform("browser")] + private bool WaitCore(long millisecondsTimeout, CancellationToken cancellationToken) + { + CheckDispose(); +#if FEATURE_WASM_MANAGED_THREADS + Thread.AssureBlockingPossible(); +#endif cancellationToken.ThrowIfCancellationRequested(); // Perf: Check the stack timeout parameter before checking the volatile count @@ -322,10 +336,10 @@ public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) return false; } - uint startTime = 0; + long startTime = 0; if (millisecondsTimeout != Timeout.Infinite && millisecondsTimeout > 0) { - startTime = TimeoutHelper.GetTime(); + startTime = Environment.TickCount64; } bool waitSuccessful = false; @@ -368,7 +382,7 @@ public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) if (m_asyncHead is not null) { Debug.Assert(m_asyncTail is not null, "tail should not be null if head isn't"); - asyncWaitTask = WaitAsync(millisecondsTimeout, cancellationToken); + asyncWaitTask = WaitAsyncCore(millisecondsTimeout, cancellationToken); } // There are no async waiters, so we can proceed with normal synchronous waiting. else @@ -449,12 +463,12 @@ public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) /// The CancellationToken to observe. /// true if the monitor received a signal, false if the timeout expired [UnsupportedOSPlatform("browser")] - private bool WaitUntilCountOrTimeout(int millisecondsTimeout, uint startTime, CancellationToken cancellationToken) + private bool WaitUntilCountOrTimeout(long millisecondsTimeout, long startTime, CancellationToken cancellationToken) { #if TARGET_WASI if (OperatingSystem.IsWasi()) throw new PlatformNotSupportedException(); // TODO remove with https://github.com/dotnet/runtime/pull/107185 #endif - int remainingWaitMilliseconds = Timeout.Infinite; + int monitorWaitMilliseconds = Timeout.Infinite; // Wait on the monitor as long as the count is zero while (m_currentCount == 0) @@ -462,17 +476,32 @@ private bool WaitUntilCountOrTimeout(int millisecondsTimeout, uint startTime, Ca // If cancelled, we throw. Trying to wait could lead to deadlock. cancellationToken.ThrowIfCancellationRequested(); + // Since Monitor.Wait will handle the actual wait and it accepts an int timeout, + // we may need to cap the timeout to int.MaxValue. + bool timeoutIsCapped = false; if (millisecondsTimeout != Timeout.Infinite) { - remainingWaitMilliseconds = TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout); + long remainingWaitMilliseconds = TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout); if (remainingWaitMilliseconds <= 0) { // The thread has expires its timeout return false; } + if (remainingWaitMilliseconds <= int.MaxValue) + { + monitorWaitMilliseconds = (int)remainingWaitMilliseconds; + } + else + { + timeoutIsCapped = true; + monitorWaitMilliseconds = int.MaxValue; + } } - // ** the actual wait ** - bool waitSuccessful = Monitor.Wait(m_lockObjAndDisposed, remainingWaitMilliseconds); + + + // The actual wait. If the timeout was capped and waitSuccessful is false, it doesn't imply + // a timeout, we are just limited by Monitor.Wait's maximum timeout value. + bool waitSuccessful = Monitor.Wait(m_lockObjAndDisposed, monitorWaitMilliseconds); // This waiter has woken up and this needs to be reflected in the count of waiters pulsed to wake. Since we // don't have thread-specific pulse state, there is not enough information to tell whether this thread woke up @@ -485,7 +514,7 @@ private bool WaitUntilCountOrTimeout(int millisecondsTimeout, uint startTime, Ca --m_countOfWaitersPulsedToWake; } - if (!waitSuccessful) + if (!timeoutIsCapped && !waitSuccessful) { return false; } @@ -500,7 +529,7 @@ private bool WaitUntilCountOrTimeout(int millisecondsTimeout, uint startTime, Ca /// A task that will complete when the semaphore has been entered. public Task WaitAsync() { - return WaitAsync(Timeout.Infinite, default); + return WaitAsyncCore(Timeout.Infinite, default); } /// @@ -516,7 +545,7 @@ public Task WaitAsync() /// public Task WaitAsync(CancellationToken cancellationToken) { - return WaitAsync(Timeout.Infinite, cancellationToken); + return WaitAsyncCore(Timeout.Infinite, cancellationToken); } /// @@ -537,7 +566,7 @@ public Task WaitAsync(CancellationToken cancellationToken) /// public Task WaitAsync(int millisecondsTimeout) { - return WaitAsync(millisecondsTimeout, default); + return WaitAsyncCore(millisecondsTimeout, default); } /// @@ -562,7 +591,16 @@ public Task WaitAsync(int millisecondsTimeout) /// public Task WaitAsync(TimeSpan timeout) { - return WaitAsync(timeout, default); + // Validate the timeout + long totalMilliseconds = (long)timeout.TotalMilliseconds; + if (totalMilliseconds < -1) + { + throw new ArgumentOutOfRangeException( + nameof(timeout), timeout, SR.SemaphoreSlim_Wait_TimeSpanTimeoutWrong); + } + + // Call wait with the timeout milliseconds + return WaitAsyncCore(totalMilliseconds, default); } /// @@ -588,14 +626,14 @@ public Task WaitAsync(TimeSpan timeout, CancellationToken cancellationToke { // Validate the timeout long totalMilliseconds = (long)timeout.TotalMilliseconds; - if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) + if (totalMilliseconds < -1) { throw new ArgumentOutOfRangeException( - nameof(timeout), timeout, SR.SemaphoreSlim_Wait_TimeoutWrong); + nameof(timeout), timeout, SR.SemaphoreSlim_Wait_TimeSpanTimeoutWrong); } // Call wait with the timeout milliseconds - return WaitAsync((int)timeout.TotalMilliseconds, cancellationToken); + return WaitAsyncCore(totalMilliseconds, cancellationToken); } /// @@ -618,14 +656,34 @@ public Task WaitAsync(TimeSpan timeout, CancellationToken cancellationToke /// public Task WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken) { - CheckDispose(); - if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException( nameof(millisecondsTimeout), millisecondsTimeout, SR.SemaphoreSlim_Wait_TimeoutWrong); } + return WaitAsyncCore(millisecondsTimeout, cancellationToken); + } + + /// + /// Asynchronously waits to enter the , + /// using a 32-bit unsigned integer to measure the time interval, + /// while observing a . + /// + /// + /// The number of milliseconds to wait, or to wait indefinitely. + /// + /// The to observe. + /// + /// A task that will complete with a result of true if the current thread successfully entered + /// the , otherwise with a result of false. + /// + /// The current instance has already been + /// disposed. + private Task WaitAsyncCore(long millisecondsTimeout, CancellationToken cancellationToken) + { + CheckDispose(); + // Bail early for cancellation if (cancellationToken.IsCancellationRequested) return Task.FromCanceled(cancellationToken); @@ -716,12 +774,14 @@ private bool RemoveAsyncWaiter(TaskNode task) /// The timeout. /// The cancellation token. /// The task to return to the caller. - private async Task WaitUntilCountOrTimeoutAsync(TaskNode asyncWaiter, int millisecondsTimeout, CancellationToken cancellationToken) + private async Task WaitUntilCountOrTimeoutAsync(TaskNode asyncWaiter, long millisecondsTimeout, CancellationToken cancellationToken) { Debug.Assert(asyncWaiter is not null, "Waiter should have been constructed"); Debug.Assert(Monitor.IsEntered(m_lockObjAndDisposed), "Requires the lock be held"); - await ((Task)asyncWaiter.WaitAsync(TimeSpan.FromMilliseconds(millisecondsTimeout), cancellationToken)).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); + await ((Task)asyncWaiter.WaitAsync( + TimeSpan.FromMilliseconds(millisecondsTimeout), + cancellationToken)).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); if (cancellationToken.IsCancellationRequested) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/SpinLock.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/SpinLock.cs index c0eba40cb428af..d50709ce2e5fc5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/SpinLock.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/SpinLock.cs @@ -287,10 +287,10 @@ private void ContinueTryEnter(int millisecondsTimeout, ref bool lockTaken) nameof(millisecondsTimeout), millisecondsTimeout, SR.SpinLock_TryEnter_ArgumentOutOfRange); } - uint startTime = 0; + long startTime = 0; if (millisecondsTimeout != Timeout.Infinite && millisecondsTimeout != 0) { - startTime = TimeoutHelper.GetTime(); + startTime = Environment.TickCount64; } if (IsThreadOwnerTrackingEnabled) @@ -404,7 +404,7 @@ private void DecrementWaiters() /// /// ContinueTryEnter for the thread tracking mode enabled /// - private void ContinueTryEnterWithThreadTracking(int millisecondsTimeout, uint startTime, ref bool lockTaken) + private void ContinueTryEnterWithThreadTracking(int millisecondsTimeout, long startTime, ref bool lockTaken) { Debug.Assert(IsThreadOwnerTrackingEnabled); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/SpinWait.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/SpinWait.cs index 1922f67f93d04c..4246a33191d10b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/SpinWait.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/SpinWait.cs @@ -315,7 +315,7 @@ public static bool SpinUntil(Func condition, int millisecondsTimeout) uint startTime = 0; if (millisecondsTimeout != 0 && millisecondsTimeout != Timeout.Infinite) { - startTime = TimeoutHelper.GetTime(); + startTime = (uint)Environment.TickCount; } SpinWait spinner = default; while (!condition()) @@ -329,7 +329,7 @@ public static bool SpinUntil(Func condition, int millisecondsTimeout) if (millisecondsTimeout != Timeout.Infinite && spinner.NextSpinWillYield) { - if (millisecondsTimeout <= (TimeoutHelper.GetTime() - startTime)) + if (millisecondsTimeout <= (uint)Environment.TickCount - startTime) { return false; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs index 1e96a5905b29e2..e9be1f3d76ba7e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs @@ -61,8 +61,6 @@ public class Task : Task /// A cached task for default(TResult). internal static readonly Task s_defaultResultTask = TaskCache.CreateCacheableTask(default); - private static TaskFactory? s_Factory; - // The value itself, if set. internal TResult? m_result; @@ -474,9 +472,7 @@ internal TResult GetResultCore(bool waitCompletionNotification) /// the default constructor on the factory type. /// public static new TaskFactory Factory => - Volatile.Read(ref s_Factory) ?? - Interlocked.CompareExchange(ref s_Factory, new TaskFactory(), null) ?? - s_Factory; + field ?? Interlocked.CompareExchange(ref field, new(), null) ?? field; /// /// Evaluates the value selector of the Task which is passed in as an object and stores the result. diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs index a5c503b2ac0594..ce9a638c03fd19 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs @@ -6024,8 +6024,25 @@ public static Task WhenAll(params Task[] tasks) /// /// /// The array contained a null task. - public static Task WhenAll(params ReadOnlySpan tasks) => - tasks.Length != 0 ? new WhenAllPromise(tasks) : CompletedTask; +        public static Task WhenAll(params ReadOnlySpan tasks) + { + switch (tasks.Length) + { + case 0: + return CompletedTask; + + case 1: + Task t = tasks[0]; + if (t is null) + { + ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks); + } + return t; + + default: + return new WhenAllPromise(tasks); + } + } /// A Task that gets completed when all of its constituent tasks complete. private sealed class WhenAllPromise : Task, ITaskCompletionAction diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs index 9539b7182eba9b..36937252a18314 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs @@ -586,7 +586,7 @@ public void SetCompressedStack(CompressedStack stack) public static long VolatileRead(ref long address) => Volatile.Read(ref address); [Obsolete(Obsoletions.ThreadVolatileReadWriteMessage, DiagnosticId = Obsoletions.ThreadVolatileReadWriteDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] - public static IntPtr VolatileRead(ref IntPtr address) => Volatile.Read(ref address); + public static nint VolatileRead(ref nint address) => Volatile.Read(ref address); [Obsolete(Obsoletions.ThreadVolatileReadWriteMessage, DiagnosticId = Obsoletions.ThreadVolatileReadWriteDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] [return: NotNullIfNotNull(nameof(address))] @@ -613,7 +613,7 @@ public void SetCompressedStack(CompressedStack stack) [Obsolete(Obsoletions.ThreadVolatileReadWriteMessage, DiagnosticId = Obsoletions.ThreadVolatileReadWriteDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] [CLSCompliant(false)] - public static UIntPtr VolatileRead(ref UIntPtr address) => Volatile.Read(ref address); + public static nuint VolatileRead(ref nuint address) => Volatile.Read(ref address); [Obsolete(Obsoletions.ThreadVolatileReadWriteMessage, DiagnosticId = Obsoletions.ThreadVolatileReadWriteDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] public static void VolatileWrite(ref byte address, byte value) => Volatile.Write(ref address, value); @@ -631,7 +631,7 @@ public void SetCompressedStack(CompressedStack stack) public static void VolatileWrite(ref long address, long value) => Volatile.Write(ref address, value); [Obsolete(Obsoletions.ThreadVolatileReadWriteMessage, DiagnosticId = Obsoletions.ThreadVolatileReadWriteDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] - public static void VolatileWrite(ref IntPtr address, IntPtr value) => Volatile.Write(ref address, value); + public static void VolatileWrite(ref nint address, nint value) => Volatile.Write(ref address, value); [Obsolete(Obsoletions.ThreadVolatileReadWriteMessage, DiagnosticId = Obsoletions.ThreadVolatileReadWriteDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] public static void VolatileWrite([NotNullIfNotNull(nameof(value))] ref object? address, object? value) => Volatile.Write(ref address, value); @@ -657,7 +657,7 @@ public void SetCompressedStack(CompressedStack stack) [Obsolete(Obsoletions.ThreadVolatileReadWriteMessage, DiagnosticId = Obsoletions.ThreadVolatileReadWriteDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] [CLSCompliant(false)] - public static void VolatileWrite(ref UIntPtr address, UIntPtr value) => Volatile.Write(ref address, value); + public static void VolatileWrite(ref nuint address, nuint value) => Volatile.Write(ref address, value); /// /// Manages functionality required to support members of dealing with thread-local data diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadLocal.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadLocal.cs index 0f0eafe3fe0683..a67c7325ae983f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadLocal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadLocal.cs @@ -349,7 +349,7 @@ private void SetValueSlow(T value, LinkedSlotVolatile[]? slotArray) // If the slot array is not big enough to hold this ID, increase the table size. if (id >= slotArray.Length) { - GrowTable(ref slotArray!, id + 1); + GrowTable(ref slotArray, id + 1); Debug.Assert(ts_finalizationHelper != null, "Should have been initialized when this thread's slot array was created."); ts_finalizationHelper.SlotArray = slotArray; ts_slotArray = slotArray; diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.Threads.Mono.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.Threads.cs similarity index 100% rename from src/mono/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.Threads.Mono.cs rename to src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.Threads.cs diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPool.Wasi.Mono.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Wasi.cs similarity index 100% rename from src/mono/System.Private.CoreLib/src/System/Threading/ThreadPool.Wasi.Mono.cs rename to src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Wasi.cs diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Threads.Mono.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Threads.cs similarity index 100% rename from src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Threads.Mono.cs rename to src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Threads.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs index fc2a36d7bf1ecf..99455d29b80c00 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs @@ -1841,8 +1841,8 @@ public static bool QueueUserWorkItem(WaitCallback callBack, object? state) ExecutionContext? context = ExecutionContext.Capture(); object tpcallBack = (context == null || context.IsDefault) ? - new QueueUserWorkItemCallbackDefaultContext(callBack!, state) : - (object)new QueueUserWorkItemCallback(callBack!, state, context); + new QueueUserWorkItemCallbackDefaultContext(callBack, state) : + (object)new QueueUserWorkItemCallback(callBack, state, context); s_workQueue.Enqueue(tpcallBack, forceGlobal: true); @@ -1859,8 +1859,8 @@ public static bool QueueUserWorkItem(Action callBack, TState sta ExecutionContext? context = ExecutionContext.Capture(); object tpcallBack = (context == null || context.IsDefault) ? - new QueueUserWorkItemCallbackDefaultContext(callBack!, state) : - (object)new QueueUserWorkItemCallback(callBack!, state, context); + new QueueUserWorkItemCallbackDefaultContext(callBack, state) : + (object)new QueueUserWorkItemCallback(callBack, state, context); s_workQueue.Enqueue(tpcallBack, forceGlobal: !preferLocal); @@ -1888,12 +1888,12 @@ public static bool UnsafeQueueUserWorkItem(Action callBack, TSta ThrowHelper.ThrowUnexpectedStateForKnownCallback(state); } - UnsafeQueueUserWorkItemInternal((object)state!, preferLocal); + UnsafeQueueUserWorkItemInternal((object)state, preferLocal); return true; } s_workQueue.Enqueue( - new QueueUserWorkItemCallbackDefaultContext(callBack!, state), forceGlobal: !preferLocal); + new QueueUserWorkItemCallbackDefaultContext(callBack, state), forceGlobal: !preferLocal); return true; } @@ -1905,7 +1905,7 @@ public static bool UnsafeQueueUserWorkItem(WaitCallback callBack, object? state) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callBack); } - object tpcallBack = new QueueUserWorkItemCallbackDefaultContext(callBack!, state); + object tpcallBack = new QueueUserWorkItemCallbackDefaultContext(callBack, state); s_workQueue.Enqueue(tpcallBack, forceGlobal: true); @@ -1925,7 +1925,7 @@ public static bool UnsafeQueueUserWorkItem(IThreadPoolWorkItem callBack, bool pr ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.callBack); } - UnsafeQueueUserWorkItemInternal(callBack!, preferLocal); + UnsafeQueueUserWorkItemInternal(callBack, preferLocal); return true; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/TimeoutHelper.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/TimeoutHelper.cs index b17d38d44d7131..37500c4dfa5e82 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/TimeoutHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/TimeoutHelper.cs @@ -6,42 +6,29 @@ namespace System.Threading { /// - /// A helper class to capture a start time using as a time in milliseconds. - /// Also updates a given timeout by subtracting the current time from the start time. + /// A helper class to update a given timeout by subtracting the current time from the start time. /// internal static class TimeoutHelper { - /// - /// Returns as a start time in milliseconds as a . - /// rolls over from positive to negative every ~25 days, then ~25 days to back to positive again. - /// is used to ignore the sign and double the range to 50 days. - /// - public static uint GetTime() - { - return (uint)Environment.TickCount; - } - /// /// Helper function to measure and update the elapsed time /// /// The first time (in milliseconds) observed when the wait started /// The original wait timeout in milliseconds - /// The new wait time in milliseconds, or -1 if the time expired - public static int UpdateTimeOut(uint startTime, int originalWaitMillisecondsTimeout) + /// The new wait time in milliseconds + public static long UpdateTimeOut(long startTime, long originalWaitMillisecondsTimeout) { // The function must be called in case the time out is not infinite Debug.Assert(originalWaitMillisecondsTimeout != Timeout.Infinite); - uint elapsedMilliseconds = (GetTime() - startTime); + ulong elapsedMilliseconds = (ulong)(Environment.TickCount64 - startTime); - // Check the elapsed milliseconds is greater than max int because this property is uint - if (elapsedMilliseconds > int.MaxValue) + if (elapsedMilliseconds > long.MaxValue) { return 0; } - // Subtract the elapsed time from the current wait time - int currentWaitTimeout = originalWaitMillisecondsTimeout - (int)elapsedMilliseconds; + long currentWaitTimeout = originalWaitMillisecondsTimeout - (long)elapsedMilliseconds; if (currentWaitTimeout <= 0) { return 0; diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/TimerQueue.Wasi.Mono.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/TimerQueue.Wasi.cs similarity index 100% rename from src/mono/System.Private.CoreLib/src/System/Threading/TimerQueue.Wasi.Mono.cs rename to src/libraries/System.Private.CoreLib/src/System/Threading/TimerQueue.Wasi.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Volatile.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Volatile.cs index e7d2cb04096376..f8a9a562b24d63 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Volatile.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Volatile.cs @@ -107,17 +107,17 @@ public static void Write(ref long location, long value) => #endregion #region IntPtr - private struct VolatileIntPtr { public volatile IntPtr Value; } + private struct VolatileIntPtr { public volatile nint Value; } [Intrinsic] [NonVersionable] - public static IntPtr Read(ref readonly IntPtr location) => - Unsafe.As(ref Unsafe.AsRef(in location)).Value; + public static nint Read(ref readonly nint location) => + Unsafe.As(ref Unsafe.AsRef(in location)).Value; [Intrinsic] [NonVersionable] - public static void Write(ref IntPtr location, IntPtr value) => - Unsafe.As(ref location).Value = value; + public static void Write(ref nint location, nint value) => + Unsafe.As(ref location).Value = value; #endregion #region SByte @@ -197,19 +197,19 @@ public static void Write(ref ulong location, ulong value) => #endregion #region UIntPtr - private struct VolatileUIntPtr { public volatile UIntPtr Value; } + private struct VolatileUIntPtr { public volatile nuint Value; } [CLSCompliant(false)] [Intrinsic] [NonVersionable] - public static UIntPtr Read(ref readonly UIntPtr location) => - Unsafe.As(ref Unsafe.AsRef(in location)).Value; + public static nuint Read(ref readonly nuint location) => + Unsafe.As(ref Unsafe.AsRef(in location)).Value; [CLSCompliant(false)] [Intrinsic] [NonVersionable] - public static void Write(ref UIntPtr location, UIntPtr value) => - Unsafe.As(ref location).Value = value; + public static void Write(ref nuint location, nuint value) => + Unsafe.As(ref location).Value = value; #endregion #region T diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/WaitHandle.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/WaitHandle.Windows.cs index d4d01971437637..26ab6b4278b2bf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/WaitHandle.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/WaitHandle.Windows.cs @@ -49,20 +49,46 @@ private static unsafe int WaitForMultipleObjectsIgnoringSyncContext(IntPtr* pHan Thread currentThread = Thread.CurrentThread; currentThread.SetWaitSleepJoinState(); -#if NATIVEAOT - int result; - if (reentrantWait) + long startTime = 0; + if (millisecondsTimeout != -1) { - Debug.Assert(!waitAll); - result = RuntimeImports.RhCompatibleReentrantWaitAny(false, millisecondsTimeout, numHandles, pHandles); + startTime = Environment.TickCount64; } - else + + int result; + while (true) { - result = (int)Interop.Kernel32.WaitForMultipleObjectsEx((uint)numHandles, (IntPtr)pHandles, waitAll ? Interop.BOOL.TRUE : Interop.BOOL.FALSE, (uint)millisecondsTimeout, Interop.BOOL.FALSE); - } +#if NATIVEAOT + if (reentrantWait) + { + Debug.Assert(!waitAll); + result = RuntimeImports.RhCompatibleReentrantWaitAny(true, millisecondsTimeout, numHandles, pHandles); + } + else + { + result = (int)Interop.Kernel32.WaitForMultipleObjectsEx((uint)numHandles, (IntPtr)pHandles, waitAll ? Interop.BOOL.TRUE : Interop.BOOL.FALSE, (uint)millisecondsTimeout, Interop.BOOL.TRUE); + } #else - int result = (int)Interop.Kernel32.WaitForMultipleObjectsEx((uint)numHandles, (IntPtr)pHandles, waitAll ? Interop.BOOL.TRUE : Interop.BOOL.FALSE, (uint)millisecondsTimeout, Interop.BOOL.FALSE); + result = (int)Interop.Kernel32.WaitForMultipleObjectsEx((uint)numHandles, (IntPtr)pHandles, waitAll ? Interop.BOOL.TRUE : Interop.BOOL.FALSE, (uint)millisecondsTimeout, Interop.BOOL.TRUE); #endif + + if (result != Interop.Kernel32.WAIT_IO_COMPLETION) + break; + + // Handle APC completion by adjusting timeout and retrying + if (millisecondsTimeout != -1) + { + long currentTime = Environment.TickCount64; + long elapsed = currentTime - startTime; + if (elapsed >= millisecondsTimeout) + { + result = Interop.Kernel32.WAIT_TIMEOUT; + break; + } + millisecondsTimeout -= (int)elapsed; + startTime = currentTime; + } + } currentThread.ClearWaitSleepJoinState(); if (result == Interop.Kernel32.WAIT_FAILED) @@ -102,8 +128,35 @@ private static int SignalAndWaitCore(IntPtr handleToSignal, IntPtr handleToWaitO { Debug.Assert(millisecondsTimeout >= -1); - int ret = (int)Interop.Kernel32.SignalObjectAndWait(handleToSignal, handleToWaitOn, (uint)millisecondsTimeout, Interop.BOOL.FALSE); + long startTime = 0; + if (millisecondsTimeout != -1) + { + startTime = Environment.TickCount64; + } + + // Signal the object and wait for the first time + int ret = (int)Interop.Kernel32.SignalObjectAndWait(handleToSignal, handleToWaitOn, (uint)millisecondsTimeout, Interop.BOOL.TRUE); + + // Handle APC completion by retrying with WaitForSingleObjectEx (without signaling again) + while (ret == Interop.Kernel32.WAIT_IO_COMPLETION) + { + if (millisecondsTimeout != -1) + { + long currentTime = Environment.TickCount64; + long elapsed = currentTime - startTime; + if (elapsed >= millisecondsTimeout) + { + ret = Interop.Kernel32.WAIT_TIMEOUT; + break; + } + millisecondsTimeout -= (int)elapsed; + startTime = currentTime; + } + + // For retries, only wait on the handle (don't signal again) + ret = (int)Interop.Kernel32.WaitForSingleObjectEx(handleToWaitOn, (uint)millisecondsTimeout, Interop.BOOL.TRUE); + } if (ret == Interop.Kernel32.WAIT_FAILED) { ThrowWaitFailedException(Interop.Kernel32.GetLastError()); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Win32ThreadPoolNativeOverlapped.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Win32ThreadPoolNativeOverlapped.cs index 51464f5931e28e..5200cbe6a76514 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Win32ThreadPoolNativeOverlapped.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Win32ThreadPoolNativeOverlapped.cs @@ -216,7 +216,7 @@ internal static unsafe void CompleteWithCallback(uint errorCode, uint bytesWritt private static unsafe void OnExecutionContextCallback(object? state) { Debug.Assert(state != null); - ExecutionContextCallbackArgs args = (ExecutionContextCallbackArgs)state!; + ExecutionContextCallbackArgs args = (ExecutionContextCallbackArgs)state; uint errorCode = args._errorCode; uint bytesWritten = args._bytesWritten; diff --git a/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs b/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs index 90c8b2163d91f6..0a73f505159a26 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs @@ -608,6 +608,18 @@ internal static void ThrowFormatException_BadFormatSpecifier() throw new FormatException(SR.Argument_BadFormatSpecifier); } + [DoesNotReturn] + internal static void ThrowFormatException_BadHexChar() + { + throw new FormatException(SR.Format_BadHexChar); + } + + [DoesNotReturn] + internal static void ThrowFormatException_BadHexLength() + { + throw new FormatException(SR.Format_BadHexLength); + } + [DoesNotReturn] internal static void ThrowFormatException_NeedSingleChar() { diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs b/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs index e249332ecd106a..861a8b8eac0836 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs @@ -15,16 +15,10 @@ namespace System // to 100 nanoseconds. While this maps well into units of time such as hours // and days, any periods longer than that aren't representable in a nice fashion. // For instance, a month can be between 28 and 31 days, while a year - // can contain 365 or 366 days. A decade can have between 1 and 3 leap-years, + // can contain 365 or 366 days. A decade can have between 1 and 3 leap years, // depending on when you map the TimeSpan into the calendar. This is why // we do not provide Years() or Months(). // - // Note: System.TimeSpan needs to interop with the WinRT structure - // type Windows::Foundation:TimeSpan. These types are currently binary-compatible in - // memory so no custom marshalling is required. If at any point the implementation - // details of this type should change, or new fields added, we need to remember to add - // an appropriate custom ILMarshaler to keep WInRT interop scenarios enabled. - // [Serializable] public readonly struct TimeSpan : IComparable, diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeZone.cs b/src/libraries/System.Private.CoreLib/src/System/TimeZone.cs index f8796313cc1cf5..107a8052f253dc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeZone.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeZone.cs @@ -15,19 +15,8 @@ public abstract class TimeZone private static volatile TimeZone? currentTimeZone; // Private object for locking instead of locking on a public type for SQL reliability work. - private static object? s_InternalSyncObject; - private static object InternalSyncObject - { - get - { - if (s_InternalSyncObject == null) - { - object o = new object(); - Interlocked.CompareExchange(ref s_InternalSyncObject, o, null); - } - return s_InternalSyncObject; - } - } + private static object InternalSyncObject => + field ?? Interlocked.CompareExchange(ref field, new object(), null) ?? field; protected TimeZone() { diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.Android.cs b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.Android.cs index 2f6d4c9e56e63d..004dadae0f2603 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.Android.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.Android.cs @@ -227,10 +227,10 @@ public AndroidTzData() // On Android, time zone data is found in tzdata // Based on https://github.com/mono/mono/blob/main/mcs/class/corlib/System/TimeZoneInfo.Android.cs // Also follows the locations found at the bottom of https://github.com/aosp-mirror/platform_bionic/blob/master/libc/tzcode/bionic.cpp - string[] tzFileDirList = new string[] {GetApexTimeDataRoot() + "/etc/tz/", // Android 10+, TimeData module where the updates land + ReadOnlySpan tzFileDirList = [ GetApexTimeDataRoot() + "/etc/tz/", // Android 10+, TimeData module where the updates land GetApexRuntimeRoot() + "/etc/tz/", // Android 10+, Fallback location if the above isn't found or corrupted Environment.GetEnvironmentVariable("ANDROID_DATA") + "/misc/zoneinfo/", - Environment.GetEnvironmentVariable("ANDROID_ROOT") + DefaultTimeZoneDirectory}; + Environment.GetEnvironmentVariable("ANDROID_ROOT") + DefaultTimeZoneDirectory ]; foreach (var tzFileDir in tzFileDirList) { string tzFilePath = Path.Combine(tzFileDir, TimeZoneFileName); diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs index 9963885aad5aa7..dabd4380406dd1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs @@ -2009,17 +2009,17 @@ private static TimeZoneInfoResult TryGetTimeZone(string id, bool dstDisabled, ou TimeZoneInfo? zone = null; if (value!._equivalentZones == null) { - zone = new TimeZoneInfo(id, value!._baseUtcOffset, value!._displayName, value!._standardDisplayName, - value!._daylightDisplayName, value!._adjustmentRules, dstDisabled && value!._supportsDaylightSavingTime, idIsIana); - value!._equivalentZones = new List(); - lock (value!._equivalentZones) + zone = new TimeZoneInfo(id, value._baseUtcOffset, value._displayName, value._standardDisplayName, + value._daylightDisplayName, value._adjustmentRules, dstDisabled && value._supportsDaylightSavingTime, idIsIana); + value._equivalentZones = new List(); + lock (value._equivalentZones) { - value!._equivalentZones.Add(zone); + value._equivalentZones.Add(zone); } } else { - foreach (TimeZoneInfo tzi in value!._equivalentZones) + foreach (TimeZoneInfo tzi in value._equivalentZones) { if (tzi.Id == id) { @@ -2029,11 +2029,11 @@ private static TimeZoneInfoResult TryGetTimeZone(string id, bool dstDisabled, ou } if (zone == null) { - zone = new TimeZoneInfo(id, value!._baseUtcOffset, value!._displayName, value!._standardDisplayName, - value!._daylightDisplayName, value!._adjustmentRules, dstDisabled && value!._supportsDaylightSavingTime, idIsIana); - lock (value!._equivalentZones) + zone = new TimeZoneInfo(id, value._baseUtcOffset, value._displayName, value._standardDisplayName, + value._daylightDisplayName, value._adjustmentRules, dstDisabled && value._supportsDaylightSavingTime, idIsIana); + lock (value._equivalentZones) { - value!._equivalentZones.Add(zone); + value._equivalentZones.Add(zone); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.Helpers.cs b/src/libraries/System.Private.CoreLib/src/System/Type.Helpers.cs index e508fc1027742f..9b9fb68afc0a64 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.Helpers.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.Helpers.cs @@ -137,7 +137,7 @@ public virtual Type[] FindInterfaces(TypeFilter filter, object? filterCriteria) for (int i = 0; i < c.Length; i++) { if (c[i] is Type t) - ret[cnt++] = t!; + ret[cnt++] = t; } return ret; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index 7efaed70149168..6020b6848a7d5f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -33,7 +33,7 @@ public bool IsInterface { #if !MONO if (this is RuntimeType rt) - return rt.IsInterface; + return rt.IsActualInterface; #endif return (GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface; } @@ -724,11 +724,9 @@ public override int GetHashCode() public static Type? ReflectionOnlyGetType(string typeName, bool throwIfNotFound, bool ignoreCase) => throw new PlatformNotSupportedException(SR.PlatformNotSupported_ReflectionOnly); public static Binder DefaultBinder => - s_defaultBinder ?? - Interlocked.CompareExchange(ref s_defaultBinder, new DefaultBinder(), null) ?? - s_defaultBinder; - - private static Binder? s_defaultBinder; + field ?? + Interlocked.CompareExchange(ref field, new DefaultBinder(), null) ?? + field; public static readonly char Delimiter = '.'; public static readonly Type[] EmptyTypes = Array.Empty(); diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs index b6b4e59bb5545d..b76e5a04f5ce11 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs @@ -1365,7 +1365,12 @@ static uint SubtractDivisor(Span left, ReadOnlySpan right, ulong q) return lower; } - internal static UInt128 BigMul(UInt128 left, UInt128 right, out UInt128 lower) + /// Produces the full product of two unsigned native integers. + /// The integer to multiply with . + /// The integer to multiply with . + /// The lower half of the full product. + /// The upper half of the full product. + public static UInt128 BigMul(UInt128 left, UInt128 right, out UInt128 lower) { // Adaptation of algorithm for multiplication // of 32-bit unsigned integers described diff --git a/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs b/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs index 7ab359b04199bc..d940ababf1c149 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs @@ -175,6 +175,24 @@ public static nuint MinValue get => unchecked((nuint)nuint_t.MinValue); } + /// Produces the full product of two unsigned native integers. + /// The integer to multiply with . + /// The integer to multiply with . + /// The lower half of the full product. + /// The upper half of the full product. + public static nuint BigMul(nuint left, nuint right, out nuint lower) + { +#if TARGET_64BIT + UInt128 result = ulong.BigMul(left, right); + lower = (nuint)result.Lower; + return (nuint)result.Upper; +#else + ulong result = uint.BigMul((uint)left, (uint)right); + lower = (uint)result; + return (uint)(result >>> 32); +#endif + } + public int CompareTo(object? value) { if (value is nuint other) diff --git a/src/libraries/System.Private.DataContractSerialization/System.Private.DataContractSerialization.slnx b/src/libraries/System.Private.DataContractSerialization/System.Private.DataContractSerialization.slnx index 6816b9480f5027..05932b6adc70dc 100644 --- a/src/libraries/System.Private.DataContractSerialization/System.Private.DataContractSerialization.slnx +++ b/src/libraries/System.Private.DataContractSerialization/System.Private.DataContractSerialization.slnx @@ -1,22 +1,1088 @@ + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Private.DataContractSerialization/src/System.Private.DataContractSerialization.csproj b/src/libraries/System.Private.DataContractSerialization/src/System.Private.DataContractSerialization.csproj index a828163c5921a5..efaa83e6f67ea7 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System.Private.DataContractSerialization.csproj +++ b/src/libraries/System.Private.DataContractSerialization/src/System.Private.DataContractSerialization.csproj @@ -154,27 +154,27 @@ ReferenceOutputAssembly="false" SetTargetFramework="TargetFramework=netstandard2.0" OutputItemType="Analyzer" /> - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ClassDataContract.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ClassDataContract.cs index f76e4f0eebd14e..5c334f24e708a8 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ClassDataContract.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ClassDataContract.cs @@ -586,8 +586,6 @@ internal bool RequiresMemberAccessForWrite(SecurityException? securityException) private sealed class ClassDataContractCriticalHelper : DataContract.DataContractCriticalHelper { - private static Type[]? s_serInfoCtorArgs; - private ClassDataContract? _baseContract; private List? _members; private MethodInfo? _onSerializing, _onSerialized; @@ -1275,7 +1273,7 @@ internal override DataContractDictionary? KnownDataContracts internal XmlDictionaryString?[]? ChildElementNamespaces { get; set; } - private static Type[] SerInfoCtorArgs => s_serInfoCtorArgs ??= new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }; + private static Type[] SerInfoCtorArgs => field ??= new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }; internal readonly struct Member { diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/CodeGenerator.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/CodeGenerator.cs index 8366258cc00d8b..3c49ba5a0d061b 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/CodeGenerator.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/CodeGenerator.cs @@ -94,8 +94,7 @@ internal static MethodInfo GetInvokeMethod(Type delegateType) private Type _delegateType = null!; // initialized in BeginMethod - private static Module? s_serializationModule; - private static Module SerializationModule => s_serializationModule ??= typeof(CodeGenerator).Module; // could to be replaced by different dll that has SkipVerification set to false + private static Module SerializationModule => field ??= typeof(CodeGenerator).Module; // could to be replaced by different dll that has SkipVerification set to false private DynamicMethod _dynamicMethod = null!; // initialized in BeginMethod diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContract.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContract.cs index 371dd171255648..9f41125199f554 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContract.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContract.cs @@ -21,6 +21,9 @@ namespace System.Runtime.Serialization.DataContracts { + /// + /// Represents a data contract that defines serialization and deserialization behavior for types. + /// public abstract class DataContract { internal const string SerializerTrimmerWarning = "Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the " + @@ -46,6 +49,9 @@ internal DataContract(DataContractCriticalHelper helper) _ns = helper.Namespace; } + /// + /// Gets the contract type name for this data contract. + /// public virtual string? ContractType => null; internal MethodInfo? ParseMethod => _helper.ParseMethod; @@ -190,24 +196,36 @@ internal virtual object ReadXmlElement(XmlReaderDelegator xmlReader, XmlObjectSe throw new InvalidDataContractException(SR.Format(SR.UnexpectedContractType, DataContract.GetClrTypeFullName(GetType()), DataContract.GetClrTypeFullName(UnderlyingType))); } + /// + /// Gets a value indicating whether the data contract represents a value type. + /// public virtual bool IsValueType { get => _helper.IsValueType; internal set => _helper.IsValueType = value; } + /// + /// Gets a value indicating whether the data contract is serialized by reference. + /// public virtual bool IsReference { get => _helper.IsReference; internal set => _helper.IsReference = value; } + /// + /// Gets the XML qualified name for the data contract. + /// public virtual XmlQualifiedName XmlName { get => _helper.XmlName; internal set => _helper.XmlName = value; } + /// + /// Gets the base data contract for this data contract. + /// public virtual DataContract? BaseContract { [RequiresDynamicCode(DataContract.SerializerAOTWarning)] @@ -316,7 +334,6 @@ internal class DataContractCriticalHelper [DynamicallyAccessedMembers(ClassDataContract.DataContractPreserveMemberTypes)] private readonly Type _underlyingType; - private Type? _originalUnderlyingType; private bool _isValueType; private GenericInfo? _genericInfo; private XmlQualifiedName _xmlName = null!; // XmlName is always set in concrete ctors set except for the "invalid" CollectionDataContract @@ -949,7 +966,7 @@ internal DataContractCriticalHelper( [DynamicallyAccessedMembers(ClassDataContract.DataContractPreserveMemberTypes)] internal Type UnderlyingType => _underlyingType; - internal Type OriginalUnderlyingType => _originalUnderlyingType ??= GetDataContractOriginalType(_underlyingType); + internal Type OriginalUnderlyingType => field ??= GetDataContractOriginalType(_underlyingType); internal virtual bool IsBuiltInDataContract => false; diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContractSet.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContractSet.cs index 58176b6dc52ccd..1a1819be2bcc64 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContractSet.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContractSet.cs @@ -18,7 +18,6 @@ public sealed class DataContractSet private Dictionary? _processedContracts; private readonly ISerializationSurrogateProvider? _surrogateProvider; private readonly ISerializationSurrogateProvider2? _extendedSurrogateProvider; - private Hashtable? _surrogateData; private DataContractDictionary? _knownTypesForObject; private readonly List? _referencedTypes; private readonly List? _referencedCollectionTypes; @@ -61,7 +60,7 @@ public DataContractSet(DataContractSet dataContractSet) public Dictionary ProcessedContracts => _processedContracts ??= new Dictionary(); - public Hashtable SurrogateData => _surrogateData ??= new Hashtable(); + public Hashtable SurrogateData => field ??= new Hashtable(); public DataContractDictionary? KnownTypesForObject { diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataMember.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataMember.cs index 5c07f7d8265e1e..e655439ed92fb1 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataMember.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataMember.cs @@ -88,11 +88,8 @@ internal DataMember? ConflictingMember set => _helper.ConflictingMember = value; } - private FastInvokerBuilder.Getter? _getter; - internal FastInvokerBuilder.Getter Getter => _getter ??= FastInvokerBuilder.CreateGetter(MemberInfo); - - private FastInvokerBuilder.Setter? _setter; - internal FastInvokerBuilder.Setter Setter => _setter ??= FastInvokerBuilder.CreateSetter(MemberInfo); + internal FastInvokerBuilder.Getter Getter => field ??= FastInvokerBuilder.CreateGetter(MemberInfo); + internal FastInvokerBuilder.Setter Setter => field ??= FastInvokerBuilder.CreateSetter(MemberInfo); private sealed class CriticalHelper { diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ExportOptions.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ExportOptions.cs index 8034f326ea09ec..9ab6f35c32bee8 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ExportOptions.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ExportOptions.cs @@ -15,8 +15,6 @@ namespace System.Runtime.Serialization /// public class ExportOptions { - private Collection? _knownTypes; - /// /// Gets or sets a serialization surrogate provider. /// @@ -25,6 +23,6 @@ public class ExportOptions /// /// Gets the collection of types that may be encountered during serialization or deserialization. /// - public Collection KnownTypes => _knownTypes ??= new Collection(); + public Collection KnownTypes => field ??= new Collection(); } } diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Globals.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Globals.cs index 65e88a4ac221b4..060e7f9964be83 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Globals.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Globals.cs @@ -23,299 +23,86 @@ internal static partial class Globals /// internal const BindingFlags ScanAllMembers = BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; - private static XmlQualifiedName? s_idQualifiedName; - internal static XmlQualifiedName IdQualifiedName => - s_idQualifiedName ??= new XmlQualifiedName(Globals.IdLocalName, Globals.SerializationNamespace); - - private static XmlQualifiedName? s_refQualifiedName; - internal static XmlQualifiedName RefQualifiedName => - s_refQualifiedName ??= new XmlQualifiedName(Globals.RefLocalName, Globals.SerializationNamespace); - - private static Type? s_typeOfObject; - internal static Type TypeOfObject => - s_typeOfObject ??= typeof(object); - - private static Type? s_typeOfValueType; - internal static Type TypeOfValueType => - s_typeOfValueType ??= typeof(ValueType); - - private static Type? s_typeOfArray; - internal static Type TypeOfArray => - s_typeOfArray ??= typeof(Array); - - private static Type? s_typeOfString; - internal static Type TypeOfString => - s_typeOfString ??= typeof(string); - - private static Type? s_typeOfInt; - internal static Type TypeOfInt => - s_typeOfInt ??= typeof(int); - - private static Type? s_typeOfULong; - internal static Type TypeOfULong => - s_typeOfULong ??= typeof(ulong); - - private static Type? s_typeOfVoid; - internal static Type TypeOfVoid => - s_typeOfVoid ??= typeof(void); - - private static Type? s_typeOfByteArray; - internal static Type TypeOfByteArray => - s_typeOfByteArray ??= typeof(byte[]); - - private static Type? s_typeOfTimeSpan; - internal static Type TypeOfTimeSpan => - s_typeOfTimeSpan ??= typeof(TimeSpan); - - private static Type? s_typeOfGuid; - internal static Type TypeOfGuid => - s_typeOfGuid ??= typeof(Guid); - - private static Type? s_typeOfDateTimeOffset; - internal static Type TypeOfDateTimeOffset => - s_typeOfDateTimeOffset ??= typeof(DateTimeOffset); - - private static Type? s_typeOfDateTimeOffsetAdapter; - internal static Type TypeOfDateTimeOffsetAdapter => - s_typeOfDateTimeOffsetAdapter ??= typeof(DateTimeOffsetAdapter); - - private static Type? s_typeOfMemoryStream; - internal static Type TypeOfMemoryStream => - s_typeOfMemoryStream ??= typeof(MemoryStream); - - private static Type? s_typeOfMemoryStreamAdapter; - internal static Type TypeOfMemoryStreamAdapter => - s_typeOfMemoryStreamAdapter ??= typeof(MemoryStreamAdapter); - - private static Type? s_typeOfUri; - internal static Type TypeOfUri => - s_typeOfUri ??= typeof(Uri); - - private static Type? s_typeOfTypeEnumerable; - internal static Type TypeOfTypeEnumerable => - s_typeOfTypeEnumerable ??= typeof(IEnumerable); - - private static Type? s_typeOfStreamingContext; - internal static Type TypeOfStreamingContext => - s_typeOfStreamingContext ??= typeof(StreamingContext); - - private static Type? s_typeOfISerializable; - internal static Type TypeOfISerializable => - s_typeOfISerializable ??= typeof(ISerializable); - - private static Type? s_typeOfIDeserializationCallback; - internal static Type TypeOfIDeserializationCallback => - s_typeOfIDeserializationCallback ??= typeof(IDeserializationCallback); - + internal static XmlQualifiedName IdQualifiedName => field ??= new XmlQualifiedName(Globals.IdLocalName, Globals.SerializationNamespace); + internal static XmlQualifiedName RefQualifiedName => field ??= new XmlQualifiedName(Globals.RefLocalName, Globals.SerializationNamespace); + internal static Type TypeOfObject => field ??= typeof(object); + internal static Type TypeOfValueType => field ??= typeof(ValueType); + internal static Type TypeOfArray => field ??= typeof(Array); + internal static Type TypeOfString => field ??= typeof(string); + internal static Type TypeOfInt => field ??= typeof(int); + internal static Type TypeOfULong => field ??= typeof(ulong); + internal static Type TypeOfVoid => field ??= typeof(void); + internal static Type TypeOfByteArray => field ??= typeof(byte[]); + internal static Type TypeOfTimeSpan => field ??= typeof(TimeSpan); + internal static Type TypeOfGuid => field ??= typeof(Guid); + internal static Type TypeOfDateTimeOffset => field ??= typeof(DateTimeOffset); + internal static Type TypeOfDateTimeOffsetAdapter => field ??= typeof(DateTimeOffsetAdapter); + internal static Type TypeOfMemoryStream => field ??= typeof(MemoryStream); + internal static Type TypeOfMemoryStreamAdapter => field ??= typeof(MemoryStreamAdapter); + internal static Type TypeOfUri => field ??= typeof(Uri); + internal static Type TypeOfTypeEnumerable => field ??= typeof(IEnumerable); + internal static Type TypeOfStreamingContext => field ??= typeof(StreamingContext); + internal static Type TypeOfISerializable => field ??= typeof(ISerializable); + internal static Type TypeOfIDeserializationCallback => field ??= typeof(IDeserializationCallback); #pragma warning disable SYSLIB0050 // IObjectReference is obsolete - private static Type? s_typeOfIObjectReference; - internal static Type TypeOfIObjectReference => - s_typeOfIObjectReference ??= typeof(IObjectReference); + internal static Type TypeOfIObjectReference => field ??= typeof(IObjectReference); #pragma warning restore SYSLIB0050 - - private static Type? s_typeOfXmlFormatClassWriterDelegate; - internal static Type TypeOfXmlFormatClassWriterDelegate => - s_typeOfXmlFormatClassWriterDelegate ??= typeof(XmlFormatClassWriterDelegate); - - private static Type? s_typeOfXmlFormatCollectionWriterDelegate; - internal static Type TypeOfXmlFormatCollectionWriterDelegate => - s_typeOfXmlFormatCollectionWriterDelegate ??= typeof(XmlFormatCollectionWriterDelegate); - - private static Type? s_typeOfXmlFormatClassReaderDelegate; - internal static Type TypeOfXmlFormatClassReaderDelegate => - s_typeOfXmlFormatClassReaderDelegate ??= typeof(XmlFormatClassReaderDelegate); - - private static Type? s_typeOfXmlFormatCollectionReaderDelegate; - internal static Type TypeOfXmlFormatCollectionReaderDelegate => - s_typeOfXmlFormatCollectionReaderDelegate ??= typeof(XmlFormatCollectionReaderDelegate); - - private static Type? s_typeOfXmlFormatGetOnlyCollectionReaderDelegate; - internal static Type TypeOfXmlFormatGetOnlyCollectionReaderDelegate => - s_typeOfXmlFormatGetOnlyCollectionReaderDelegate ??= typeof(XmlFormatGetOnlyCollectionReaderDelegate); - - private static Type? s_typeOfKnownTypeAttribute; - internal static Type TypeOfKnownTypeAttribute => - s_typeOfKnownTypeAttribute ??= typeof(KnownTypeAttribute); - - private static Type? s_typeOfDataContractAttribute; - internal static Type TypeOfDataContractAttribute => - s_typeOfDataContractAttribute ??= typeof(DataContractAttribute); - - private static Type? s_typeOfDataMemberAttribute; - internal static Type TypeOfDataMemberAttribute => - s_typeOfDataMemberAttribute ??= typeof(DataMemberAttribute); - - private static Type? s_typeOfEnumMemberAttribute; - internal static Type TypeOfEnumMemberAttribute => - s_typeOfEnumMemberAttribute ??= typeof(EnumMemberAttribute); - - private static Type? s_typeOfCollectionDataContractAttribute; - internal static Type TypeOfCollectionDataContractAttribute => - s_typeOfCollectionDataContractAttribute ??= typeof(CollectionDataContractAttribute); - - private static Type? s_typeOfOptionalFieldAttribute; - internal static Type TypeOfOptionalFieldAttribute => - s_typeOfOptionalFieldAttribute ??= typeof(OptionalFieldAttribute); - - private static Type? s_typeOfObjectArray; - internal static Type TypeOfObjectArray => - s_typeOfObjectArray ??= typeof(object[]); - - private static Type? s_typeOfOnSerializingAttribute; - internal static Type TypeOfOnSerializingAttribute => - s_typeOfOnSerializingAttribute ??= typeof(OnSerializingAttribute); - - private static Type? s_typeOfOnSerializedAttribute; - internal static Type TypeOfOnSerializedAttribute => - s_typeOfOnSerializedAttribute ??= typeof(OnSerializedAttribute); - - private static Type? s_typeOfOnDeserializingAttribute; - internal static Type TypeOfOnDeserializingAttribute => - s_typeOfOnDeserializingAttribute ??= typeof(OnDeserializingAttribute); - - private static Type? s_typeOfOnDeserializedAttribute; - internal static Type TypeOfOnDeserializedAttribute => - s_typeOfOnDeserializedAttribute ??= typeof(OnDeserializedAttribute); - - private static Type? s_typeOfFlagsAttribute; - internal static Type TypeOfFlagsAttribute => - s_typeOfFlagsAttribute ??= typeof(FlagsAttribute); - - private static Type? s_typeOfIXmlSerializable; - internal static Type TypeOfIXmlSerializable => - s_typeOfIXmlSerializable ??= typeof(IXmlSerializable); - - private static Type? s_typeOfXmlSchemaProviderAttribute; - internal static Type TypeOfXmlSchemaProviderAttribute => - s_typeOfXmlSchemaProviderAttribute ??= typeof(XmlSchemaProviderAttribute); - - private static Type? s_typeOfXmlRootAttribute; - internal static Type TypeOfXmlRootAttribute => - s_typeOfXmlRootAttribute ??= typeof(XmlRootAttribute); - - private static Type? s_typeOfXmlQualifiedName; - internal static Type TypeOfXmlQualifiedName => - s_typeOfXmlQualifiedName ??= typeof(XmlQualifiedName); - - private static Type? s_typeOfXmlSchemaType; - internal static Type TypeOfXmlSchemaType => - s_typeOfXmlSchemaType ??= typeof(XmlSchemaType); - - private static Type? s_typeOfIExtensibleDataObject; - internal static Type TypeOfIExtensibleDataObject => - s_typeOfIExtensibleDataObject ??= typeof(IExtensibleDataObject); - - private static Type? s_typeOfExtensionDataObject; - internal static Type TypeOfExtensionDataObject => - s_typeOfExtensionDataObject ??= typeof(ExtensionDataObject); - - private static Type? s_typeOfISerializableDataNode; - internal static Type TypeOfISerializableDataNode => - s_typeOfISerializableDataNode ??= typeof(ISerializableDataNode); - - private static Type? s_typeOfClassDataNode; - internal static Type TypeOfClassDataNode => - s_typeOfClassDataNode ??= typeof(ClassDataNode); - - private static Type? s_typeOfCollectionDataNode; - internal static Type TypeOfCollectionDataNode => - s_typeOfCollectionDataNode ??= typeof(CollectionDataNode); - - private static Type? s_typeOfXmlDataNode; - internal static Type TypeOfXmlDataNode => - s_typeOfXmlDataNode ??= typeof(XmlDataNode); - - private static Type? s_typeOfNullable; - internal static Type TypeOfNullable => - s_typeOfNullable ??= typeof(Nullable<>); - - private static Type? s_typeOfReflectionPointer; - internal static Type TypeOfReflectionPointer => - s_typeOfReflectionPointer ??= typeof(System.Reflection.Pointer); - - private static Type? s_typeOfIDictionaryGeneric; - internal static Type TypeOfIDictionaryGeneric => - s_typeOfIDictionaryGeneric ??= typeof(IDictionary<,>); - - private static Type? s_typeOfIDictionary; - internal static Type TypeOfIDictionary => - s_typeOfIDictionary ??= typeof(IDictionary); - - private static Type? s_typeOfIListGeneric; - internal static Type TypeOfIListGeneric => - s_typeOfIListGeneric ??= typeof(IList<>); - - private static Type? s_typeOfIList; - internal static Type TypeOfIList => - s_typeOfIList ??= typeof(IList); - - private static Type? s_typeOfICollectionGeneric; - internal static Type TypeOfICollectionGeneric => - s_typeOfICollectionGeneric ??= typeof(ICollection<>); - - private static Type? s_typeOfICollection; - internal static Type TypeOfICollection => - s_typeOfICollection ??= typeof(ICollection); - - private static Type? s_typeOfIEnumerableGeneric; - internal static Type TypeOfIEnumerableGeneric => - s_typeOfIEnumerableGeneric ??= typeof(IEnumerable<>); - - private static Type? s_typeOfIEnumerable; - internal static Type TypeOfIEnumerable => - s_typeOfIEnumerable ??= typeof(IEnumerable); - - private static Type? s_typeOfIEnumeratorGeneric; - internal static Type TypeOfIEnumeratorGeneric => - s_typeOfIEnumeratorGeneric ??= typeof(IEnumerator<>); - - private static Type? s_typeOfIEnumerator; - internal static Type TypeOfIEnumerator => - s_typeOfIEnumerator ??= typeof(IEnumerator); - - private static Type? s_typeOfKeyValuePair; - internal static Type TypeOfKeyValuePair => - s_typeOfKeyValuePair ??= typeof(KeyValuePair<,>); - - private static Type? s_typeOfKeyValue; - internal static Type TypeOfKeyValue => - s_typeOfKeyValue ??= typeof(KeyValue<,>); - - private static Type? s_typeOfIDictionaryEnumerator; - internal static Type TypeOfIDictionaryEnumerator => - s_typeOfIDictionaryEnumerator ??= typeof(IDictionaryEnumerator); - - private static Type? s_typeOfDictionaryEnumerator; - internal static Type TypeOfDictionaryEnumerator => - s_typeOfDictionaryEnumerator ??= typeof(CollectionDataContract.DictionaryEnumerator); - - private static Type? s_typeOfGenericDictionaryEnumerator; - internal static Type TypeOfGenericDictionaryEnumerator => - s_typeOfGenericDictionaryEnumerator ??= typeof(CollectionDataContract.GenericDictionaryEnumerator<,>); - - private static Type? s_typeOfDictionaryGeneric; - internal static Type TypeOfDictionaryGeneric => - s_typeOfDictionaryGeneric ??= typeof(Dictionary<,>); - - private static Type? s_typeOfHashtable; + internal static Type TypeOfXmlFormatClassWriterDelegate => field ??= typeof(XmlFormatClassWriterDelegate); + internal static Type TypeOfXmlFormatCollectionWriterDelegate => field ??= typeof(XmlFormatCollectionWriterDelegate); + internal static Type TypeOfXmlFormatClassReaderDelegate => field ??= typeof(XmlFormatClassReaderDelegate); + internal static Type TypeOfXmlFormatCollectionReaderDelegate => field ??= typeof(XmlFormatCollectionReaderDelegate); + internal static Type TypeOfXmlFormatGetOnlyCollectionReaderDelegate => field ??= typeof(XmlFormatGetOnlyCollectionReaderDelegate); + internal static Type TypeOfKnownTypeAttribute => field ??= typeof(KnownTypeAttribute); + internal static Type TypeOfDataContractAttribute => field ??= typeof(DataContractAttribute); + internal static Type TypeOfDataMemberAttribute => field ??= typeof(DataMemberAttribute); + internal static Type TypeOfEnumMemberAttribute => field ??= typeof(EnumMemberAttribute); + internal static Type TypeOfCollectionDataContractAttribute => field ??= typeof(CollectionDataContractAttribute); + internal static Type TypeOfOptionalFieldAttribute => field ??= typeof(OptionalFieldAttribute); + internal static Type TypeOfObjectArray => field ??= typeof(object[]); + internal static Type TypeOfOnSerializingAttribute => field ??= typeof(OnSerializingAttribute); + internal static Type TypeOfOnSerializedAttribute => field ??= typeof(OnSerializedAttribute); + internal static Type TypeOfOnDeserializingAttribute => field ??= typeof(OnDeserializingAttribute); + internal static Type TypeOfOnDeserializedAttribute => field ??= typeof(OnDeserializedAttribute); + internal static Type TypeOfFlagsAttribute => field ??= typeof(FlagsAttribute); + internal static Type TypeOfIXmlSerializable => field ??= typeof(IXmlSerializable); + internal static Type TypeOfXmlSchemaProviderAttribute => field ??= typeof(XmlSchemaProviderAttribute); + internal static Type TypeOfXmlRootAttribute => field ??= typeof(XmlRootAttribute); + internal static Type TypeOfXmlQualifiedName => field ??= typeof(XmlQualifiedName); + internal static Type TypeOfXmlSchemaType => field ??= typeof(XmlSchemaType); + internal static Type TypeOfIExtensibleDataObject => field ??= typeof(IExtensibleDataObject); + internal static Type TypeOfExtensionDataObject => field ??= typeof(ExtensionDataObject); + internal static Type TypeOfISerializableDataNode => field ??= typeof(ISerializableDataNode); + internal static Type TypeOfClassDataNode => field ??= typeof(ClassDataNode); + internal static Type TypeOfCollectionDataNode => field ??= typeof(CollectionDataNode); + internal static Type TypeOfXmlDataNode => field ??= typeof(XmlDataNode); + internal static Type TypeOfNullable => field ??= typeof(Nullable<>); + internal static Type TypeOfReflectionPointer => field ??= typeof(System.Reflection.Pointer); + internal static Type TypeOfIDictionaryGeneric => field ??= typeof(IDictionary<,>); + internal static Type TypeOfIDictionary => field ??= typeof(IDictionary); + internal static Type TypeOfIListGeneric => field ??= typeof(IList<>); + internal static Type TypeOfIList => field ??= typeof(IList); + internal static Type TypeOfICollectionGeneric => field ??= typeof(ICollection<>); + internal static Type TypeOfICollection => field ??= typeof(ICollection); + internal static Type TypeOfIEnumerableGeneric => field ??= typeof(IEnumerable<>); + internal static Type TypeOfIEnumerable => field ??= typeof(IEnumerable); + internal static Type TypeOfIEnumeratorGeneric => field ??= typeof(IEnumerator<>); + internal static Type TypeOfIEnumerator => field ??= typeof(IEnumerator); + internal static Type TypeOfKeyValuePair => field ??= typeof(KeyValuePair<,>); + internal static Type TypeOfKeyValue => field ??= typeof(KeyValue<,>); + internal static Type TypeOfIDictionaryEnumerator => field ??= typeof(IDictionaryEnumerator); + internal static Type TypeOfDictionaryEnumerator => field ??= typeof(CollectionDataContract.DictionaryEnumerator); + internal static Type TypeOfGenericDictionaryEnumerator => field ??= typeof(CollectionDataContract.GenericDictionaryEnumerator<,>); + internal static Type TypeOfDictionaryGeneric => field ??= typeof(Dictionary<,>); internal static Type TypeOfHashtable { [RequiresDynamicCode(DataContract.SerializerAOTWarning)] [RequiresUnreferencedCode(DataContract.SerializerTrimmerWarning)] - get => s_typeOfHashtable ??= TypeOfDictionaryGeneric.MakeGenericType(TypeOfObject, TypeOfObject); + get => field ??= TypeOfDictionaryGeneric.MakeGenericType(TypeOfObject, TypeOfObject); } - private static Type? s_typeOfXmlElement; - internal static Type TypeOfXmlElement => - s_typeOfXmlElement ??= typeof(XmlElement); - - private static Type? s_typeOfXmlNodeArray; - internal static Type TypeOfXmlNodeArray => - s_typeOfXmlNodeArray ??= typeof(XmlNode[]); - - private static Type? s_typeOfDBNull; - internal static Type TypeOfDBNull => - s_typeOfDBNull ??= typeof(DBNull); + internal static Type TypeOfXmlElement => field ??= typeof(XmlElement); + internal static Type TypeOfXmlNodeArray => field ??= typeof(XmlNode[]); + internal static Type TypeOfDBNull => field ??= typeof(DBNull); [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicFields)] private static Type? s_typeOfSchemaDefinedType; @@ -329,13 +116,8 @@ internal static Type TypeOfHashtable internal static Type TypeOfSchemaDefinedEnum => s_typeOfSchemaDefinedEnum ??= typeof(SchemaDefinedEnum); - private static MemberInfo? s_schemaMemberInfoPlaceholder; - internal static MemberInfo SchemaMemberInfoPlaceholder => - s_schemaMemberInfoPlaceholder ??= TypeOfSchemaDefinedType.GetField(nameof(SchemaDefinedType._xmlName), BindingFlags.NonPublic | BindingFlags.Instance)!; - - private static Uri? s_dataContractXsdBaseNamespaceUri; - internal static Uri DataContractXsdBaseNamespaceUri => - s_dataContractXsdBaseNamespaceUri ??= new Uri(DataContractXsdBaseNamespace); + internal static MemberInfo SchemaMemberInfoPlaceholder => field ??= TypeOfSchemaDefinedType.GetField(nameof(SchemaDefinedType._xmlName), BindingFlags.NonPublic | BindingFlags.Instance)!; + internal static Uri DataContractXsdBaseNamespaceUri => field ??= new Uri(DataContractXsdBaseNamespace); public const bool DefaultIsRequired = false; public const bool DefaultEmitDefaultValue = true; diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/DataContractJsonSerializer.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/DataContractJsonSerializer.cs index 5072642b0087b2..8c86f0a3713e01 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/DataContractJsonSerializer.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/DataContractJsonSerializer.cs @@ -206,11 +206,20 @@ private XmlDictionaryString RootName // These Get/Set methods mirror the extensions that were added to DCS in the early days of Core, which allowed // using a slimmed-down surrogate on both NetFx and Core via type-forwarding mechanisms. That's why these are // a pair of methods instead of making the property itself public. + + /// + /// Gets the current serialization surrogate provider. + /// + /// The current instance, or if no provider is set. public ISerializationSurrogateProvider? GetSerializationSurrogateProvider() { return SerializationSurrogateProvider; } + /// + /// Sets the serialization surrogate provider. + /// + /// The to use for serialization, or to remove the current provider. public void SetSerializationSurrogateProvider(ISerializationSurrogateProvider? provider) { SerializationSurrogateProvider = provider; diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/JsonFormatGeneratorStatics.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/JsonFormatGeneratorStatics.cs index ff78bb15130c66..297cd6929df553 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/JsonFormatGeneratorStatics.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/JsonFormatGeneratorStatics.cs @@ -18,10 +18,6 @@ public static class JsonFormatGeneratorStatics private static PropertyInfo? s_collectionItemNameProperty; - private static ConstructorInfo? s_extensionDataObjectCtor; - - private static PropertyInfo? s_extensionDataProperty; - private static MethodInfo? s_getItemContractMethod; private static MethodInfo? s_getJsonDataContractMethod; @@ -54,8 +50,6 @@ public static class JsonFormatGeneratorStatics private static ConstructorInfo? s_serializationExceptionCtor; - private static Type[]? s_serInfoCtorArgs; - private static MethodInfo? s_throwDuplicateMemberExceptionMethod; private static MethodInfo? s_throwMissingRequiredMembersMethod; @@ -113,11 +107,9 @@ public static PropertyInfo CollectionItemNameProperty } } - public static ConstructorInfo ExtensionDataObjectCtor => s_extensionDataObjectCtor ?? - (s_extensionDataObjectCtor = - typeof(ExtensionDataObject).GetConstructor(Globals.ScanAllMembers, Type.EmptyTypes))!; + public static ConstructorInfo ExtensionDataObjectCtor => field ??= typeof(ExtensionDataObject).GetConstructor(Globals.ScanAllMembers, Type.EmptyTypes)!; - public static PropertyInfo ExtensionDataProperty => s_extensionDataProperty ??= typeof(IExtensibleDataObject).GetProperty("ExtensionData")!; + public static PropertyInfo ExtensionDataProperty => field ??= typeof(IExtensibleDataObject).GetProperty("ExtensionData")!; public static MethodInfo GetCurrentMethod { @@ -319,7 +311,7 @@ public static ConstructorInfo SerializationExceptionCtor return s_serializationExceptionCtor; } } - public static Type[] SerInfoCtorArgs => s_serInfoCtorArgs ??= new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }; + public static Type[] SerInfoCtorArgs => field ??= new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }; public static MethodInfo ThrowDuplicateMemberExceptionMethod { get diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs index 1c05bf37fde453..3733783c3b3800 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs @@ -871,32 +871,15 @@ internal static XmlSchemaAny ISerializableWildcardElement } } - private static XmlQualifiedName? s_anytypeQualifiedName; - internal static XmlQualifiedName AnytypeQualifiedName => s_anytypeQualifiedName ??= new XmlQualifiedName(Globals.AnyTypeLocalName, Globals.SchemaNamespace); - - private static XmlQualifiedName? s_stringQualifiedName; - internal static XmlQualifiedName StringQualifiedName => s_stringQualifiedName ??= new XmlQualifiedName(Globals.StringLocalName, Globals.SchemaNamespace); - - private static XmlQualifiedName? s_defaultEnumBaseTypeName; - internal static XmlQualifiedName DefaultEnumBaseTypeName => s_defaultEnumBaseTypeName ??= new XmlQualifiedName(Globals.IntLocalName, Globals.SchemaNamespace); - - private static XmlQualifiedName? s_enumerationValueAnnotationName; - internal static XmlQualifiedName EnumerationValueAnnotationName => s_enumerationValueAnnotationName ??= new XmlQualifiedName(Globals.EnumerationValueLocalName, Globals.SerializationNamespace); - - private static XmlQualifiedName? s_surrogateDataAnnotationName; - internal static XmlQualifiedName SurrogateDataAnnotationName => s_surrogateDataAnnotationName ??= new XmlQualifiedName(Globals.SurrogateDataLocalName, Globals.SerializationNamespace); - - private static XmlQualifiedName? s_defaultValueAnnotation; - internal static XmlQualifiedName DefaultValueAnnotation => s_defaultValueAnnotation ??= new XmlQualifiedName(Globals.DefaultValueLocalName, Globals.SerializationNamespace); - - private static XmlQualifiedName? s_actualTypeAnnotationName; - internal static XmlQualifiedName ActualTypeAnnotationName => s_actualTypeAnnotationName ??= new XmlQualifiedName(Globals.ActualTypeLocalName, Globals.SerializationNamespace); - - private static XmlQualifiedName? s_isDictionaryAnnotationName; - internal static XmlQualifiedName IsDictionaryAnnotationName => s_isDictionaryAnnotationName ??= new XmlQualifiedName(Globals.IsDictionaryLocalName, Globals.SerializationNamespace); - - private static XmlQualifiedName? s_isValueTypeName; - internal static XmlQualifiedName IsValueTypeName => s_isValueTypeName ??= new XmlQualifiedName(Globals.IsValueTypeLocalName, Globals.SerializationNamespace); + internal static XmlQualifiedName AnytypeQualifiedName => field ??= new XmlQualifiedName(Globals.AnyTypeLocalName, Globals.SchemaNamespace); + internal static XmlQualifiedName StringQualifiedName => field ??= new XmlQualifiedName(Globals.StringLocalName, Globals.SchemaNamespace); + internal static XmlQualifiedName DefaultEnumBaseTypeName => field ??= new XmlQualifiedName(Globals.IntLocalName, Globals.SchemaNamespace); + internal static XmlQualifiedName EnumerationValueAnnotationName => field ??= new XmlQualifiedName(Globals.EnumerationValueLocalName, Globals.SerializationNamespace); + internal static XmlQualifiedName SurrogateDataAnnotationName => field ??= new XmlQualifiedName(Globals.SurrogateDataLocalName, Globals.SerializationNamespace); + internal static XmlQualifiedName DefaultValueAnnotation => field ??= new XmlQualifiedName(Globals.DefaultValueLocalName, Globals.SerializationNamespace); + internal static XmlQualifiedName ActualTypeAnnotationName => field ??= new XmlQualifiedName(Globals.ActualTypeLocalName, Globals.SerializationNamespace); + internal static XmlQualifiedName IsDictionaryAnnotationName => field ??= new XmlQualifiedName(Globals.IsDictionaryLocalName, Globals.SerializationNamespace); + internal static XmlQualifiedName IsValueTypeName => field ??= new XmlQualifiedName(Globals.IsValueTypeLocalName, Globals.SerializationNamespace); // Property is not stored in a local because XmlSchemaAttribute is mutable. // The schema export process should not expose objects that may be modified later. diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlFormatGeneratorStatics.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlFormatGeneratorStatics.cs index 1d18543b4c0946..399e530eaff868 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlFormatGeneratorStatics.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlFormatGeneratorStatics.cs @@ -68,11 +68,9 @@ internal static MethodInfo WriteNamespaceDeclMethod } } - private static PropertyInfo? s_extensionDataProperty; - internal static PropertyInfo ExtensionDataProperty => s_extensionDataProperty ??= typeof(IExtensibleDataObject).GetProperty("ExtensionData")!; + internal static PropertyInfo ExtensionDataProperty => field ??= typeof(IExtensibleDataObject).GetProperty("ExtensionData")!; - private static MethodInfo? s_boxPointer; - internal static MethodInfo BoxPointer => s_boxPointer ??= typeof(Pointer).GetMethod("Box")!; + internal static MethodInfo BoxPointer => field ??= typeof(Pointer).GetMethod("Box")!; private static ConstructorInfo? s_dictionaryEnumeratorCtor; internal static ConstructorInfo DictionaryEnumeratorCtor @@ -188,8 +186,7 @@ internal static MethodInfo OnDeserializationMethod } } - private static MethodInfo? s_unboxPointer; - internal static MethodInfo UnboxPointer => s_unboxPointer ??= typeof(Pointer).GetMethod("Unbox")!; + internal static MethodInfo UnboxPointer => field ??= typeof(Pointer).GetMethod("Unbox")!; private static PropertyInfo? s_nodeTypeProperty; internal static PropertyInfo NodeTypeProperty @@ -205,11 +202,9 @@ internal static PropertyInfo NodeTypeProperty } } - private static ConstructorInfo? s_serializationExceptionCtor; - internal static ConstructorInfo SerializationExceptionCtor => s_serializationExceptionCtor ??= typeof(SerializationException).GetConstructor(new Type[] { typeof(string) })!; + internal static ConstructorInfo SerializationExceptionCtor => field ??= typeof(SerializationException).GetConstructor(new Type[] { typeof(string) })!; - private static ConstructorInfo? s_extensionDataObjectCtor; - internal static ConstructorInfo ExtensionDataObjectCtor => s_extensionDataObjectCtor ??= typeof(ExtensionDataObject).GetConstructor(Globals.ScanAllMembers, Type.EmptyTypes)!; + internal static ConstructorInfo ExtensionDataObjectCtor => field ??= typeof(ExtensionDataObject).GetConstructor(Globals.ScanAllMembers, Type.EmptyTypes)!; private static ConstructorInfo? s_hashtableCtor; internal static ConstructorInfo HashtableCtor @@ -912,8 +907,7 @@ internal static FieldInfo MemberNamesField } } - private static MethodInfo? s_extensionDataSetExplicitMethodInfo; - internal static MethodInfo ExtensionDataSetExplicitMethodInfo => s_extensionDataSetExplicitMethodInfo ??= typeof(IExtensibleDataObject).GetMethod(Globals.ExtensionDataSetMethod)!; + internal static MethodInfo ExtensionDataSetExplicitMethodInfo => field ??= typeof(IExtensibleDataObject).GetMethod(Globals.ExtensionDataSetMethod)!; private static PropertyInfo? s_childElementNamespacesProperty; internal static PropertyInfo ChildElementNamespacesProperty diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializer.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializer.cs index 778191ff35e67e..3dcd6c7886b417 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializer.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializer.cs @@ -471,8 +471,7 @@ internal static string GetTypeInfoError(string errorMessage, Type? type, Excepti } #pragma warning disable SYSLIB0050 // IFormatterConverter is obsolete - private static IFormatterConverter? s_formatterConverter; - internal static IFormatterConverter FormatterConverter => s_formatterConverter ??= new FormatterConverter(); + internal static IFormatterConverter FormatterConverter => field ??= new FormatterConverter(); #pragma warning restore SYSLIB0050 } } diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerReadContext.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerReadContext.cs index b04258f0da9903..aa67d42b32f239 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerReadContext.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerReadContext.cs @@ -19,17 +19,15 @@ namespace System.Runtime.Serialization internal class XmlObjectSerializerReadContext : XmlObjectSerializerContext { internal Attributes? attributes; - private HybridObjectCache? _deserializedObjects; private XmlSerializableReader? _xmlSerializableReader; - private XmlDocument? _xmlDocument; private Attributes? _attributesInXmlData; private XmlReaderDelegator? _extensionDataReader; private object? _getOnlyCollectionValue; private bool _isGetOnlyCollection; - private HybridObjectCache DeserializedObjects => _deserializedObjects ??= new HybridObjectCache(); + private HybridObjectCache DeserializedObjects => field ??= new HybridObjectCache(); - private XmlDocument Document => _xmlDocument ??= new XmlDocument(); + private XmlDocument Document => field ??= new XmlDocument(); internal override bool IsGetOnlyCollection { diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerWriteContext.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerWriteContext.cs index 150209bfba79b4..77871d386de520 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerWriteContext.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerWriteContext.cs @@ -25,7 +25,6 @@ internal class XmlObjectSerializerWriteContext : XmlObjectSerializerContext private ObjectReferenceStack _byValObjectsInScope; private XmlSerializableWriter? _xmlSerializableWriter; private const int depthToCheckCyclicReference = 512; - private ObjectToIdCache? _serializedObjects; private bool _isGetOnlyCollection; private readonly bool _unsafeTypeForwardingEnabled; protected bool serializeReadOnlyTypes; @@ -53,7 +52,7 @@ internal XmlObjectSerializerWriteContext(XmlObjectSerializer serializer, int max _unsafeTypeForwardingEnabled = true; } - protected ObjectToIdCache SerializedObjects => _serializedObjects ??= new ObjectToIdCache(); + protected ObjectToIdCache SerializedObjects => field ??= new ObjectToIdCache(); internal override bool IsGetOnlyCollection { diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlDictionary.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlDictionary.cs index 00d058c678e458..deeab58bd93119 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlDictionary.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlDictionary.cs @@ -15,12 +15,11 @@ namespace System.Xml { public class XmlDictionary : IXmlDictionary { - private static IXmlDictionary? s_empty; private readonly Dictionary _lookup; private XmlDictionaryString[]? _strings; private int _nextId; - public static IXmlDictionary Empty => s_empty ??= new EmptyDictionary(); + public static IXmlDictionary Empty => field ??= new EmptyDictionary(); public XmlDictionary() { diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlNodeWriter.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlNodeWriter.cs index 8d4042a9a719e5..8b3e53de4d5c42 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlNodeWriter.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlNodeWriter.cs @@ -14,9 +14,7 @@ namespace System.Xml { internal abstract class XmlNodeWriter { - private static XmlNodeWriter? s_nullNodeWriter; - - public static XmlNodeWriter Null => s_nullNodeWriter ??= new XmlNullNodeWriter(); + public static XmlNodeWriter Null => field ??= new XmlNullNodeWriter(); public abstract void Flush(); public virtual Task FlushAsync() diff --git a/src/libraries/System.Private.Uri/src/Resources/Strings.resx b/src/libraries/System.Private.Uri/src/Resources/Strings.resx index cd008a8cd20485..31b2a47b7ed81e 100644 --- a/src/libraries/System.Private.Uri/src/Resources/Strings.resx +++ b/src/libraries/System.Private.Uri/src/Resources/Strings.resx @@ -168,9 +168,6 @@ A derived type '{0}' has reported an invalid value for the Uri port '{1}'. - - Invalid URI: The Uri string is too long. - A derived type '{0}' is responsible for parsing this Uri instance. The base implementation must not be used. diff --git a/src/libraries/System.Private.Uri/src/System.Private.Uri.csproj b/src/libraries/System.Private.Uri/src/System.Private.Uri.csproj index 7ed53d0bfc45f2..3c0145ef05c8ef 100644 --- a/src/libraries/System.Private.Uri/src/System.Private.Uri.csproj +++ b/src/libraries/System.Private.Uri/src/System.Private.Uri.csproj @@ -6,15 +6,9 @@ - - - - - - + + + diff --git a/src/libraries/System.Private.Uri/src/System/IriHelper.cs b/src/libraries/System.Private.Uri/src/System/IriHelper.cs index 710437d82c9790..d26126c8d8c332 100644 --- a/src/libraries/System.Private.Uri/src/System/IriHelper.cs +++ b/src/libraries/System.Private.Uri/src/System/IriHelper.cs @@ -88,6 +88,8 @@ internal static bool CheckIsReserved(char ch, UriComponents component) // internal static unsafe string EscapeUnescapeIri(char* pInput, int start, int end, UriComponents component) { + Debug.Assert(end >= 0 && start >= 0 && start <= end); + int size = end - start; var dest = size <= Uri.StackallocThreshold ? new ValueStringBuilder(stackalloc char[Uri.StackallocThreshold]) diff --git a/src/libraries/System.Private.Uri/src/System/Uri.cs b/src/libraries/System.Private.Uri/src/System/Uri.cs index 0f4477e416e10c..d99f967aa97833 100644 --- a/src/libraries/System.Private.Uri/src/System/Uri.cs +++ b/src/libraries/System.Private.Uri/src/System/Uri.cs @@ -9,7 +9,6 @@ using System.Globalization; using System.Net; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Text; using System.Threading; @@ -17,7 +16,7 @@ namespace System { [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + [TypeForwardedFrom("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public partial class Uri : ISpanFormattable, IEquatable, ISerializable { public static readonly string UriSchemeFile = UriParser.FileUri.SchemeName; @@ -38,10 +37,9 @@ public partial class Uri : ISpanFormattable, IEquatable, ISerializable public static readonly string UriSchemeNetPipe = UriParser.NetPipeUri.SchemeName; public static readonly string SchemeDelimiter = "://"; - internal const int StackallocThreshold = 512; + private const int SchemeLengthLimit = 1024; - internal const int c_MaxUriBufferSize = 0xFFF0; - private const int c_MaxUriSchemeName = 1024; + internal const int StackallocThreshold = 512; // untouched user string unless string has unicode chars and iriparsing is enabled // or idn is on and we have unicode host or idn host @@ -60,86 +58,136 @@ public partial class Uri : ISpanFormattable, IEquatable, ISerializable [Flags] internal enum Flags : ulong { - Zero = 0x00000000, - - SchemeNotCanonical = 0x1, - UserNotCanonical = 0x2, - HostNotCanonical = 0x4, - PortNotCanonical = 0x8, - PathNotCanonical = 0x10, - QueryNotCanonical = 0x20, - FragmentNotCanonical = 0x40, - CannotDisplayCanonical = 0x7F, - - E_UserNotCanonical = 0x80, - E_HostNotCanonical = 0x100, - E_PortNotCanonical = 0x200, - E_PathNotCanonical = 0x400, - E_QueryNotCanonical = 0x800, - E_FragmentNotCanonical = 0x1000, - E_CannotDisplayCanonical = 0x1F80, - - - ShouldBeCompressed = 0x2000, - FirstSlashAbsent = 0x4000, - BackslashInPath = 0x8000, - - IndexMask = 0x0000FFFF, - HostTypeMask = 0x00070000, - HostNotParsed = 0x00000000, - IPv6HostType = 0x00010000, - IPv4HostType = 0x00020000, - DnsHostType = 0x00030000, - UncHostType = 0x00040000, - BasicHostType = 0x00050000, - UnusedHostType = 0x00060000, - UnknownHostType = 0x00070000, - - UserEscaped = 0x00080000, - AuthorityFound = 0x00100000, - HasUserInfo = 0x00200000, - LoopbackHost = 0x00400000, - NotDefaultPort = 0x00800000, - - UserDrivenParsing = 0x01000000, - CanonicalDnsHost = 0x02000000, - ErrorOrParsingRecursion = 0x04000000, // Used to signal a default parser error and also to confirm Port + Zero = 0, + + SchemeNotCanonical = 1UL << 0, + UserNotCanonical = 1UL << 1, + HostNotCanonical = 1UL << 2, + PortNotCanonical = 1UL << 3, + PathNotCanonical = 1UL << 4, + QueryNotCanonical = 1UL << 5, + FragmentNotCanonical = 1UL << 6, + CannotDisplayCanonical = SchemeNotCanonical | UserNotCanonical | HostNotCanonical | PortNotCanonical | PathNotCanonical | QueryNotCanonical | FragmentNotCanonical, + + E_UserNotCanonical = 1UL << 7, + E_HostNotCanonical = 1UL << 8, + E_PortNotCanonical = 1UL << 9, + E_PathNotCanonical = 1UL << 10, + E_QueryNotCanonical = 1UL << 11, + E_FragmentNotCanonical = 1UL << 12, + E_CannotDisplayCanonical = E_UserNotCanonical | E_HostNotCanonical | E_PortNotCanonical | E_PathNotCanonical | E_QueryNotCanonical | E_FragmentNotCanonical, + + ShouldBeCompressed = 1UL << 13, + FirstSlashAbsent = 1UL << 14, + BackslashInPath = 1UL << 15, + + IndexMask = 0xFFFFFFFF, // 32 bits + + HostTypeMask = 7 * (1UL << 32), + HostNotParsed = 0, + IPv6HostType = 1 * (1UL << 32), + IPv4HostType = 2 * (1UL << 32), + DnsHostType = 3 * (1UL << 32), + UncHostType = 4 * (1UL << 32), + BasicHostType = 5 * (1UL << 32), + UnusedHostType = 6 * (1UL << 32), + UnknownHostType = 7 * (1UL << 32), + + UserEscaped = 1UL << 35, + AuthorityFound = 1UL << 36, + HasUserInfo = 1UL << 37, + LoopbackHost = 1UL << 38, + NotDefaultPort = 1UL << 39, + + UserDrivenParsing = 1UL << 40, + CanonicalDnsHost = 1UL << 41, + ErrorOrParsingRecursion = 1UL << 42, // Used to signal a default parser error and also to confirm Port // and Host values in case of a custom user Parser - DosPath = 0x08000000, - UncPath = 0x10000000, - ImplicitFile = 0x20000000, - MinimalUriInfoSet = 0x40000000, - AllUriInfoSet = unchecked(0x80000000), - IdnHost = 0x100000000, - HasUnicode = 0x200000000, + DosPath = 1UL << 43, + UncPath = 1UL << 44, + ImplicitFile = 1UL << 45, + MinimalUriInfoSet = 1UL << 46, + AllUriInfoSet = 1UL << 47, + IdnHost = 1UL << 48, + HasUnicode = 1UL << 49, + // Is this component Iri canonical - UserIriCanonical = 0x8000000000, - PathIriCanonical = 0x10000000000, - QueryIriCanonical = 0x20000000000, - FragmentIriCanonical = 0x40000000000, - IriCanonical = 0x78000000000, - UnixPath = 0x100000000000, + UserIriCanonical = 1UL << 50, + PathIriCanonical = 1UL << 51, + QueryIriCanonical = 1UL << 52, + FragmentIriCanonical = 1UL << 53, + IriCanonical = UserIriCanonical | PathIriCanonical | QueryIriCanonical | FragmentIriCanonical, + UnixPath = 1UL << 54, /// /// Disables any validation/normalization past the authority. Fragments will always be empty. GetComponents will throw for Path/Query. /// - DisablePathAndQueryCanonicalization = 0x200000000000, + DisablePathAndQueryCanonicalization = 1UL << 55, /// /// Used to ensure that InitializeAndValidate is only called once per Uri instance and only from an override of InitializeAndValidate /// - CustomParser_ParseMinimalAlreadyCalled = 0x4000000000000000, + CustomParser_ParseMinimalAlreadyCalled = 1UL << 56, /// /// Used for asserting that certain methods are only called from the constructor to validate thread-safety assumptions /// - Debug_LeftConstructor = 0x8000000000000000 + Debug_LeftConstructor = 1UL << 57 } [Conditional("DEBUG")] private void DebugSetLeftCtor() { _flags |= Flags.Debug_LeftConstructor; + + AssertInvariants(); + } + + [Conditional("DEBUG")] + private void AssertInvariants() + { + Debug.Assert(InFact(Flags.MinimalUriInfoSet) == (_info is not null)); + + if (_info is UriInfo info) + { + Debug.Assert(IsAbsoluteUri); + + Offset offset = info.Offset; + + Debug.Assert(offset.Scheme >= 0); + Debug.Assert(offset.User >= 0 && offset.User >= offset.Scheme); + Debug.Assert(offset.Host >= 0 && offset.Host >= offset.User); + Debug.Assert(offset.Path >= 0); + Debug.Assert(offset.End >= 0 && offset.End >= offset.Path); + + if (InFact(Flags.AllUriInfoSet)) + { + Debug.Assert(offset.Path >= offset.Host); + Debug.Assert(offset.Query >= 0 && offset.Query >= offset.Path); + Debug.Assert(offset.Fragment >= 0 && offset.Fragment >= offset.Query); + Debug.Assert(offset.End >= offset.Fragment && offset.End <= _string.Length); + } + else + { + // If we have non-ASCII, we're about to continue with ParseRemaining. + // Between CreateUriInfo and the rest of ParseRemaining, the Path offset is pointing into the original string, + // while the Host offset is poining into the new _string. As such the Host offset may temporarily be > Path. + if (!InFact(Flags.HasUnicode)) + { + Debug.Assert(offset.Path >= offset.Host); + } + + Debug.Assert(offset.Query == 0); + Debug.Assert(offset.Fragment == 0); + } + } + else + { + if (IsAbsoluteUri && IriParsing) + { + Debug.Assert(Ascii.IsValid(_string)); + } + } } [Conditional("DEBUG")] @@ -170,17 +218,16 @@ public MoreInfo MoreInfo } }; - [StructLayout(LayoutKind.Sequential, Pack = 1)] private struct Offset { - public ushort Scheme; - public ushort User; - public ushort Host; + public int Scheme; + public int User; + public int Host; public ushort PortValue; - public ushort Path; - public ushort Query; - public ushort Fragment; - public ushort End; + public int Path; + public int Query; + public int Fragment; + public int End; }; private sealed class MoreInfo @@ -323,6 +370,7 @@ private UriInfo EnsureUriInfo() if ((cF & Flags.MinimalUriInfoSet) == 0) { CreateUriInfo(cF); + AssertInvariants(); } Debug.Assert(_info != null && (_flags & Flags.MinimalUriInfoSet) != 0); return _info; @@ -333,6 +381,7 @@ private void EnsureParseRemaining() if ((_flags & Flags.AllUriInfoSet) == 0) { ParseRemaining(); + AssertInvariants(); } } @@ -664,8 +713,6 @@ private static void GetCombinedString(Uri baseUri, string relativeStr, // Fatal case ParsingError.SchemeLimit: return new UriFormatException(SR.net_uri_SchemeLimit); - case ParsingError.SizeLimit: - return new UriFormatException(SR.net_uri_SizeLimit); case ParsingError.MustRootedPath: return new UriFormatException(SR.net_uri_MustRootedPath); // Derived class controllable @@ -903,7 +950,8 @@ public string[] Segments } else { - ArrayBuilder pathSegments = default; + var pathSegments = new ValueListBuilder(4); + int current = 0; while (current < path.Length) { @@ -912,10 +960,12 @@ public string[] Segments { next = path.Length - 1; } - pathSegments.Add(path.Substring(current, (next - current) + 1)); + pathSegments.Append(path.Substring(current, (next - current) + 1)); current = next + 1; } - segments = pathSegments.ToArray(); + + segments = pathSegments.AsSpan().ToArray(); + pathSegments.Dispose(); } return segments; @@ -1019,7 +1069,7 @@ private string GetLocalPath() } - ushort pathStart = (ushort)count; //save for optional Compress() call + int pathStart = count; // save for optional Compress() call UnescapeMode mode = (InFact(Flags.PathNotCanonical) && !IsImplicitFile) ? (UnescapeMode.Unescape | UnescapeMode.UnescapeAll) : UnescapeMode.CopyOnly; @@ -1263,7 +1313,7 @@ public string UserInfo // public static UriHostNameType CheckHostName(string? name) { - if (string.IsNullOrEmpty(name) || name.Length > short.MaxValue) + if (string.IsNullOrEmpty(name)) { return UriHostNameType.Unknown; } @@ -1911,9 +1961,6 @@ private static ParsingError ParseScheme(string uriString, ref Flags flags, ref U if (length == 0) return ParsingError.EmptyUriString; - if (length >= c_MaxUriBufferSize) - return ParsingError.SizeLimit; - // Fast path for valid http(s) schemes with no leading whitespace that are expected to be very common. if (uriString.StartsWith("https:", StringComparison.OrdinalIgnoreCase)) { @@ -2213,7 +2260,7 @@ private unsafe void CreateUriInfo(Flags cF) UriInfo info = new UriInfo(); // This will be revisited in ParseRemaining but for now just have it at least _string.Length - info.Offset.End = (ushort)_string.Length; + info.Offset.End = _string.Length; if (UserDrivenParsing) goto Done; @@ -2284,7 +2331,7 @@ private unsafe void CreateUriInfo(Flags cF) ) { //there is no Authority component defined - info.Offset.User = (ushort)(cF & Flags.IndexMask); + info.Offset.User = (int)(cF & Flags.IndexMask); info.Offset.Host = info.Offset.User; info.Offset.Path = info.Offset.User; cF &= ~Flags.IndexMask; @@ -2295,13 +2342,13 @@ private unsafe void CreateUriInfo(Flags cF) goto Done; } - info.Offset.User = (ushort)idx; + info.Offset.User = idx; //Basic Host Type does not have userinfo and port if (HostType == Flags.BasicHostType) { - info.Offset.Host = (ushort)idx; - info.Offset.Path = (ushort)(cF & Flags.IndexMask); + info.Offset.Host = idx; + info.Offset.Path = (int)(cF & Flags.IndexMask); cF &= ~Flags.IndexMask; goto Done; } @@ -2314,15 +2361,14 @@ private unsafe void CreateUriInfo(Flags cF) ++idx; } ++idx; - info.Offset.Host = (ushort)idx; + info.Offset.Host = idx; } else { - info.Offset.Host = (ushort)idx; + info.Offset.Host = idx; } //Now reload the end of the parsed host - idx = (int)(cF & Flags.IndexMask); //From now on we do not need IndexMask bits, and reuse the space for X_NotCanonical flags @@ -2336,7 +2382,7 @@ private unsafe void CreateUriInfo(Flags cF) } //Guessing this is a path start - info.Offset.Path = (ushort)idx; + info.Offset.Path = idx; // parse Port if any. The new spec allows a port after ':' to be empty (assuming default?) bool notEmpty = false; @@ -2346,7 +2392,7 @@ private unsafe void CreateUriInfo(Flags cF) // points to _originalUnicodeString and not _string if ((cF & Flags.HasUnicode) != 0) - info.Offset.End = (ushort)_originalUnicodeString.Length; + info.Offset.End = _originalUnicodeString.Length; if (idx < info.Offset.End) { @@ -2389,7 +2435,7 @@ private unsafe void CreateUriInfo(Flags cF) //not follow to canonical rules cF |= (Flags.PortNotCanonical | Flags.E_PortNotCanonical); } - info.Offset.Path = (ushort)idx; + info.Offset.Path = idx; } } } @@ -2583,9 +2629,6 @@ private unsafe void GetHostViaCustomSyntax() // ATTN: Check on whether recursion has not happened if (_info.Host is null) { - if (host.Length >= c_MaxUriBufferSize) - throw GetException(ParsingError.SizeLimit)!; - ParsingError err = ParsingError.None; Flags flags = _flags & ~Flags.HostTypeMask; @@ -2775,6 +2818,8 @@ private bool TryRecreateParts(scoped Span span, out int charsWritten, UriC private ReadOnlySpan RecreateParts(scoped ref ValueStringBuilder dest, string str, UriComponents parts, ushort nonCanonical, UriFormat formatAs) { + Debug.Assert(InFact(Flags.AllUriInfoSet)); + //Scheme and slashes if ((parts & UriComponents.Scheme) != 0) { @@ -3305,11 +3350,11 @@ private unsafe void ParseRemaining() } _info.Offset.Scheme = 0; - _info.Offset.User = (ushort)_string.Length; - _info.Offset.Host = (ushort)_string.Length; + _info.Offset.User = _string.Length; + _info.Offset.Host = _string.Length; } - _info.Offset.Path = (ushort)_string.Length; + _info.Offset.Path = _string.Length; idx = _info.Offset.Path; } @@ -3337,9 +3382,9 @@ private unsafe void ParseRemaining() } } - _info.Offset.Query = (ushort)idx; - _info.Offset.Fragment = (ushort)str.Length; // There is no fragment in DisablePathAndQueryCanonicalization mode - _info.Offset.End = (ushort)str.Length; + _info.Offset.Query = idx; + _info.Offset.Fragment = str.Length; // There is no fragment in DisablePathAndQueryCanonicalization mode + _info.Offset.End = str.Length; goto Done; } @@ -3381,12 +3426,6 @@ private unsafe void ParseRemaining() _string += EscapeUnescapeIri(_originalUnicodeString, offset, origIdx, UriComponents.Path); - if (_string.Length > ushort.MaxValue) - { - UriFormatException e = GetException(ParsingError.SizeLimit)!; - throw e; - } - length = _string.Length; // We need to be sure that there isn't a '?' separated from the path by spaces. if (_string == _originalUnicodeString) @@ -3517,12 +3556,6 @@ private unsafe void ParseRemaining() _string += EscapeUnescapeIri(_originalUnicodeString, offset, origIdx, UriComponents.Query); - if (_string.Length > ushort.MaxValue) - { - UriFormatException e = GetException(ParsingError.SizeLimit)!; - throw e; - } - length = _string.Length; // We need to be sure that there isn't a '#' separated from the query by spaces. if (_string == _originalUnicodeString) @@ -3532,7 +3565,7 @@ private unsafe void ParseRemaining() } } - _info.Offset.Query = (ushort)idx; + _info.Offset.Query = idx; fixed (char* str = _string) { @@ -3574,19 +3607,13 @@ private unsafe void ParseRemaining() _string += EscapeUnescapeIri(_originalUnicodeString, offset, origIdx, UriComponents.Fragment); - if (_string.Length > ushort.MaxValue) - { - UriFormatException e = GetException(ParsingError.SizeLimit)!; - throw e; - } - length = _string.Length; // we don't need to check _originalUnicodeString == _string because # is last part GetLengthWithoutTrailingSpaces(_string, ref length, idx); } } - _info.Offset.Fragment = (ushort)idx; + _info.Offset.Fragment = idx; fixed (char* str = _string) { @@ -3613,7 +3640,7 @@ private unsafe void ParseRemaining() } } } - _info.Offset.End = (ushort)idx; + _info.Offset.End = idx; Done: cF |= Flags.AllUriInfoSet; @@ -3774,7 +3801,7 @@ private static int ParseSchemeCheckImplicitFile(string uriString, ref ParsingErr return null; } - if (scheme.Length > c_MaxUriSchemeName) + if (scheme.Length > SchemeLengthLimit) { error = ParsingError.SchemeLimit; return null; @@ -3850,12 +3877,6 @@ private unsafe int CheckAuthorityHelper(char* pString, int idx, int length, { // Normalize user info newHost += IriHelper.EscapeUnescapeIri(pString, startInput, start + 1, UriComponents.UserInfo); - - if (newHost.Length > ushort.MaxValue) - { - err = ParsingError.SizeLimit; - return idx; - } } ++start; ch = pString[start]; @@ -3887,6 +3908,8 @@ private unsafe int CheckAuthorityHelper(char* pString, int idx, int length, else if (((syntaxFlags & UriSyntaxFlags.AllowDnsHost) != 0) && !IriParsingStatic(syntax) && DomainNameHelper.IsValid(new ReadOnlySpan(pString + start, end - start), iri: false, StaticNotAny(flags, Flags.ImplicitFile), out int domainNameLength)) { + Debug.Assert(!hasUnicode); + end = start + domainNameLength; // comes here if there are only ascii chars in host with original parsing and no Iri @@ -4418,7 +4441,11 @@ private unsafe void GetCanonicalPath(ref ValueStringBuilder dest, UriFormat form if (InFact(Flags.ShouldBeCompressed) && dest.Length - offset > 0) { // It will also convert back slashes if needed - dest.Length = offset + Compress(dest.RawChars.Slice(offset, dest.Length - offset), _syntax); + dest.Length = offset + UriHelper.Compress( + dest.RawChars.Slice(offset, dest.Length - offset), + _syntax.InFact(UriSyntaxFlags.ConvertPathSlashes), + _syntax.InFact(UriSyntaxFlags.CanonicalizeAsFilePath)); + if (dest[start] == '\\') dest[start] = '/'; @@ -4556,131 +4583,10 @@ private static unsafe void UnescapeOnly(char* pch, int start, ref int end, char private static void Compress(char[] dest, int start, ref int destLength, UriParser syntax) { - destLength = start + Compress(dest.AsSpan(start, destLength - start), syntax); - } - - // - // This will compress any "\" "/../" "/./" "///" "/..../" /XXX.../, etc found in the input - // - // The passed syntax controls whether to use aggressive compression or the one specified in RFC 2396 - // - private static int Compress(Span span, UriParser syntax) - { - if (syntax.InFact(UriSyntaxFlags.ConvertPathSlashes)) - { - span.Replace('\\', '/'); - } - - int slashCount = 0; - int lastSlash = 0; - int dotCount = 0; - int removeSegments = 0; - - for (int i = span.Length - 1; i >= 0; i--) - { - char ch = span[i]; - - // compress multiple '/' for file URI - if (ch == '/') - { - ++slashCount; - } - else - { - if (slashCount > 1) - { - // else preserve repeated slashes - lastSlash = i + 1; - } - slashCount = 0; - } - - if (ch == '.') - { - ++dotCount; - continue; - } - else if (dotCount != 0) - { - bool skipSegment = syntax.NotAny(UriSyntaxFlags.CanonicalizeAsFilePath) - && (dotCount > 2 || ch != '/'); - - // Cases: - // /./ = remove this segment - // /../ = remove this segment, mark next for removal - // /....x = DO NOT TOUCH, leave as is - // x.../ = DO NOT TOUCH, leave as is, except for V2 legacy mode - if (!skipSegment && ch == '/') - { - if ((lastSlash == i + dotCount + 1 // "/..../" - || (lastSlash == 0 && i + dotCount + 1 == span.Length)) // "/..." - && (dotCount <= 2)) - { - // /./ or /. or /../ or /.. - - // span.Remove(i + 1, dotCount + (lastSlash == 0 ? 0 : 1)); - lastSlash = i + 1 + dotCount + (lastSlash == 0 ? 0 : 1); - span.Slice(lastSlash).CopyTo(span.Slice(i + 1)); - span = span.Slice(0, span.Length - (lastSlash - i - 1)); - - lastSlash = i; - if (dotCount == 2) - { - // We have 2 dots in between like /../ or /.., - // Mark next segment for removal and remove this /../ or /.. - ++removeSegments; - } - dotCount = 0; - continue; - } - } - // .NET 4.5 no longer removes trailing dots in a path segment x.../ or x... - dotCount = 0; - - // Here all other cases go such as - // x.[..]y or /.[..]x or (/x.[...][/] && removeSegments !=0) - } - - // Now we may want to remove a segment because of previous /../ - if (ch == '/') - { - if (removeSegments != 0) - { - --removeSegments; - - span.Slice(lastSlash + 1).CopyTo(span.Slice(i + 1)); - span = span.Slice(0, span.Length - (lastSlash - i)); - } - lastSlash = i; - } - } - - if (span.Length != 0 && syntax.InFact(UriSyntaxFlags.CanonicalizeAsFilePath)) - { - if (slashCount <= 1) - { - if (removeSegments != 0 && span[0] != '/') - { - //remove first not rooted segment - lastSlash++; - span.Slice(lastSlash).CopyTo(span); - return span.Length - lastSlash; - } - else if (dotCount != 0) - { - // If final string starts with a segment looking like .[...]/ or .[...] - // then we remove this first segment - if (lastSlash == dotCount || (lastSlash == 0 && dotCount == span.Length)) - { - dotCount += lastSlash == 0 ? 0 : 1; - span.Slice(dotCount).CopyTo(span); - return span.Length - dotCount; - } - } - } - } - - return span.Length; + destLength = start + UriHelper.Compress( + dest.AsSpan(start, destLength - start), + syntax.InFact(UriSyntaxFlags.ConvertPathSlashes), + syntax.InFact(UriSyntaxFlags.CanonicalizeAsFilePath)); } // diff --git a/src/libraries/System.Private.Uri/src/System/UriEnumTypes.cs b/src/libraries/System.Private.Uri/src/System/UriEnumTypes.cs index 22ec5c99b47231..1a1c3eb5fef7f9 100644 --- a/src/libraries/System.Private.Uri/src/System/UriEnumTypes.cs +++ b/src/libraries/System.Private.Uri/src/System/UriEnumTypes.cs @@ -57,29 +57,28 @@ public enum UriFormat internal enum ParsingError { // looks good - None = 0, + None, // These first errors indicate that the Uri cannot be absolute, but may be relative. - BadFormat = 1, - BadScheme = 2, - BadAuthority = 3, - EmptyUriString = 4, - LastRelativeUriOkErrIndex = 4, + BadFormat, + BadScheme, + BadAuthority, + EmptyUriString, + LastErrorOkayForRelativeUris, // All higher error values are fatal, indicating that neither an absolute or relative // Uri could be generated. - SchemeLimit = 5, - SizeLimit = 6, - MustRootedPath = 7, + SchemeLimit, + MustRootedPath, // derived class controlled - BadHostName = 8, - NonEmptyHost = 9, // unix only - BadPort = 10, - BadAuthorityTerminator = 11, + BadHostName, + NonEmptyHost, // unix only + BadPort, + BadAuthorityTerminator, // The user requested only a relative Uri, but an absolute Uri was parsed. - CannotCreateRelative = 12 + CannotCreateRelative } [Flags] diff --git a/src/libraries/System.Private.Uri/src/System/UriExt.cs b/src/libraries/System.Private.Uri/src/System/UriExt.cs index e500f7bea22a09..e0d722b88b9c45 100644 --- a/src/libraries/System.Private.Uri/src/System/UriExt.cs +++ b/src/libraries/System.Private.Uri/src/System/UriExt.cs @@ -80,7 +80,7 @@ private void InitializeUri(ParsingError err, UriKind uriKind, out UriFormatExcep } } } - else if (err > ParsingError.LastRelativeUriOkErrIndex) + else if (err > ParsingError.LastErrorOkayForRelativeUris) { //This is a fatal error based solely on scheme name parsing _string = null!; // make it be invalid Uri @@ -104,7 +104,7 @@ private void InitializeUri(ParsingError err, UriKind uriKind, out UriFormatExcep { if ((err = PrivateParseMinimal()) != ParsingError.None) { - if (uriKind != UriKind.Absolute && err <= ParsingError.LastRelativeUriOkErrIndex) + if (uriKind != UriKind.Absolute && err <= ParsingError.LastErrorOkayForRelativeUris) { // RFC 3986 Section 5.4.2 - http:(relativeUri) may be considered a valid relative Uri. _syntax = null!; // convert to relative uri @@ -153,7 +153,7 @@ private void InitializeUri(ParsingError err, UriKind uriKind, out UriFormatExcep { // Can we still take it as a relative Uri? if (uriKind != UriKind.Absolute && err != ParsingError.None - && err <= ParsingError.LastRelativeUriOkErrIndex) + && err <= ParsingError.LastErrorOkayForRelativeUris) { _syntax = null!; // convert it to relative e = null; @@ -195,7 +195,7 @@ private void InitializeUri(ParsingError err, UriKind uriKind, out UriFormatExcep // If we encountered any parsing errors that indicate this may be a relative Uri, // and we'll allow relative Uri's, then create one. else if (err != ParsingError.None && uriKind != UriKind.Absolute - && err <= ParsingError.LastRelativeUriOkErrIndex) + && err <= ParsingError.LastErrorOkayForRelativeUris) { e = null; _flags &= (Flags.UserEscaped | Flags.HasUnicode); // the only flags that makes sense for a relative uri @@ -204,10 +204,6 @@ private void InitializeUri(ParsingError err, UriKind uriKind, out UriFormatExcep // Iri'ze and then normalize relative uris _string = EscapeUnescapeIri(_originalUnicodeString, 0, _originalUnicodeString.Length, (UriComponents)0); - if (_string.Length > ushort.MaxValue) - { - return; - } } } else @@ -772,7 +768,7 @@ private Uri(Flags flags, UriParser? uriParser, string uri) if (err != ParsingError.None) { // If it looks as a relative Uri, custom factory is ignored - if (uriKind != UriKind.Absolute && err <= ParsingError.LastRelativeUriOkErrIndex) + if (uriKind != UriKind.Absolute && err <= ParsingError.LastErrorOkayForRelativeUris) return new Uri((flags & Flags.UserEscaped), null, uriString); return null; diff --git a/src/libraries/System.Private.Uri/src/System/UriHelper.cs b/src/libraries/System.Private.Uri/src/System/UriHelper.cs index ad83c35b15bb3f..668a7344deac7a 100644 --- a/src/libraries/System.Private.Uri/src/System/UriHelper.cs +++ b/src/libraries/System.Private.Uri/src/System/UriHelper.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers; +using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; @@ -657,5 +658,162 @@ public static bool StripBidiControlCharacters(ReadOnlySpan strToClean, [No }); return true; } + + // This will compress any "\" "/../" "/./" "///" "/..../" /XXX.../, etc found in the input + // + // The passed options control whether to use aggressive compression or the one specified in RFC 2396 + public static int Compress(Span span, bool convertPathSlashes, bool canonicalizeAsFilePath) + { + if (span.IsEmpty) + { + return 0; + } + + if (convertPathSlashes) + { + span.Replace('\\', '/'); + } + + ValueListBuilder<(int Start, int Length)> removedSegments = default; + + int slashCount = 0; + int lastSlash = 0; + int dotCount = 0; + int removeSegments = 0; + + for (int i = span.Length - 1; i >= 0; i--) + { + char ch = span[i]; + + // compress multiple '/' for file URI + if (ch == '/') + { + ++slashCount; + } + else + { + if (slashCount > 1) + { + // else preserve repeated slashes + lastSlash = i + 1; + } + slashCount = 0; + } + + if (ch == '.') + { + ++dotCount; + continue; + } + else if (dotCount != 0) + { + bool skipSegment = canonicalizeAsFilePath && (dotCount > 2 || ch != '/'); + + // Cases: + // /./ = remove this segment + // /../ = remove this segment, mark next for removal + // /....x = DO NOT TOUCH, leave as is + // x.../ = DO NOT TOUCH, leave as is, except for V2 legacy mode + if (!skipSegment && ch == '/') + { + if ((lastSlash == i + dotCount + 1 // "/..../" + || (lastSlash == 0 && i + dotCount + 1 == span.Length)) // "/..." + && (dotCount <= 2)) + { + // /./ or /. or /../ or /.. + removedSegments.Append((i + 1, dotCount + (lastSlash == 0 ? 0 : 1))); + + lastSlash = i; + if (dotCount == 2) + { + // We have 2 dots in between like /../ or /.., + // Mark next segment for removal and remove this /../ or /.. + ++removeSegments; + } + dotCount = 0; + continue; + } + } + // .NET 4.5 no longer removes trailing dots in a path segment x.../ or x... + dotCount = 0; + + // Here all other cases go such as + // x.[..]y or /.[..]x or (/x.[...][/] && removeSegments !=0) + } + + // Now we may want to remove a segment because of previous /../ + if (ch == '/') + { + if (removeSegments != 0) + { + removeSegments--; + removedSegments.Append((i + 1, lastSlash - i)); + } + + lastSlash = i; + } + } + + if (canonicalizeAsFilePath) + { + if (slashCount <= 1) + { + if (removeSegments != 0 && span[0] != '/') + { + // remove first not rooted segment + removedSegments.Append((0, lastSlash + 1)); + } + else if (dotCount != 0) + { + // If final string starts with a segment looking like .[...]/ or .[...] + // then we remove this first segment + if (lastSlash == dotCount || (lastSlash == 0 && dotCount == span.Length)) + { + removedSegments.Append((0, dotCount + (lastSlash == 0 ? 0 : 1))); + } + } + } + } + + if (removedSegments.Length == 0) + { + return span.Length; + } + + // Merge any remaining segments. + // Write and read offsets are only ever the same for the first segment. + // Copying the first section would no-op anyway, so we start with the first removed segment. + int writeOffset = removedSegments[^1].Start; + int readOffset = writeOffset; + + for (int i = removedSegments.Length - 1; i >= 0; i--) + { + (int start, int length) = removedSegments[i]; + + Debug.Assert(start >= readOffset && length > 0 && start + length <= span.Length); + + if (readOffset != start) + { + Debug.Assert(readOffset > writeOffset); + + int segmentLength = start - readOffset; + span.Slice(readOffset, segmentLength).CopyTo(span.Slice(writeOffset)); + writeOffset += segmentLength; + } + + readOffset = start + length; + } + + if (readOffset != span.Length) + { + Debug.Assert(readOffset > writeOffset); + + span.Slice(readOffset).CopyTo(span.Slice(writeOffset)); + writeOffset += span.Length - readOffset; + } + + removedSegments.Dispose(); + return writeOffset; + } } } diff --git a/src/libraries/System.Private.Uri/tests/FunctionalTests/IriTest.cs b/src/libraries/System.Private.Uri/tests/FunctionalTests/IriTest.cs index d84a2d6acb07b8..d018c93750739d 100644 --- a/src/libraries/System.Private.Uri/tests/FunctionalTests/IriTest.cs +++ b/src/libraries/System.Private.Uri/tests/FunctionalTests/IriTest.cs @@ -25,8 +25,6 @@ public class IriTest "ja-jp" }; - private const int MaxUriLength = 0xFFF0 - 1; // 65519 - [Fact] public void Iri_Validate_LongUriWithQuery() { @@ -225,50 +223,50 @@ public void Iri_BidiCharacter_AfterEscapingBufferInitialized() [Fact] public void Iri_UnicodePlane0() { - EscapeUnescapeTestUnicodePlane(0x0, 0xFFFF, 1); + EscapeUnescapeTestUnicodePlane(0x0, 0xFFFF); } [Fact] public void Iri_UnicodePlane1() { - EscapeUnescapeTestUnicodePlane(0x10000, 0x1FFFF, 1); + EscapeUnescapeTestUnicodePlane(0x10000, 0x1FFFF); } [Fact] public void Iri_UnicodePlane2() { - EscapeUnescapeTestUnicodePlane(0x20000, 0x2FFFF, 1); + EscapeUnescapeTestUnicodePlane(0x20000, 0x2FFFF); } [Fact] public void Iri_UnicodePlane3_13() { - EscapeUnescapeTestUnicodePlane(0x30000, 0xDFFFF, 1); + EscapeUnescapeTestUnicodePlane(0x30000, 0xDFFFF); } [Fact] public void Iri_UnicodePlane14() { - EscapeUnescapeTestUnicodePlane(0xE0000, 0xEFFFF, 1); + EscapeUnescapeTestUnicodePlane(0xE0000, 0xEFFFF); } [Fact] public void Iri_UnicodePlane15_16() { - EscapeUnescapeTestUnicodePlane(0xF0000, 0x10FFFF, 1); + EscapeUnescapeTestUnicodePlane(0xF0000, 0x10FFFF); } - private void EscapeUnescapeTestUnicodePlane(int start, int end, int step) + private void EscapeUnescapeTestUnicodePlane(int start, int end) { - string input = GetUnicodeString(start, end, step); + string input = GetUnicodeString(start, end); VerifyUriNormalizationForEscapedCharacters(input); } - private static string GetUnicodeString(int start, int end, int step, int minLength = 1) + private static string GetUnicodeString(int start, int end, int minLength = 1) { StringBuilder sb = new StringBuilder(); - for (int i = start; i < end; i += step) + for (int i = start; i < end; i++) { if (i < 0xFFFF) { @@ -468,26 +466,15 @@ public void Iri_ValidateVeryLongInputString_Ctor() { string validUriStart = "http://host/q="; - string bigString1 = GetUnicodeString(0x1000, 0x1001, 1, MaxUriLength - validUriStart.Length); - string test = validUriStart + bigString1; - Assert.True(test.Length == MaxUriLength); + string bigString1 = new string('\u1000', 100_000); Uri u1 = new Uri(validUriStart + bigString1); Assert.True(u1.ToString().Length > bigString1.Length); - - try - { - string bigString2 = GetUnicodeString(0, MaxUriLength + 1, 1); - Uri u = new Uri(bigString2); - Assert.Fail("Expected UriFormatException: Uri too large"); - } - catch (FormatException) - { } } [Theory] - [InlineData(MaxUriLength)] - [InlineData(MaxUriLength + 1)] + [InlineData(65519)] + [InlineData(100_000)] [InlineData(10 + ushort.MaxValue)] public void Iri_ValidateVeryLongInputString_EscapeDataString(int length) { @@ -496,8 +483,8 @@ public void Iri_ValidateVeryLongInputString_EscapeDataString(int length) } [Theory] - [InlineData(MaxUriLength)] - [InlineData(MaxUriLength + 1)] + [InlineData(65519)] + [InlineData(100_000)] [InlineData(10 + ushort.MaxValue)] public void Iri_ValidateVeryLongInputString_EscapeUriString(int length) { @@ -569,89 +556,55 @@ public void Iri_AllForbiddenDecompositions_NonIdnPropertiesOk(string scheme, str Assert.Equal(scheme + "://" + host + "/", uri.AbsoluteUri); } - // The behavior here is slightly complicated in order to preserve compat in as many - // cases as possible. There are two limits imposed on the length of URI strings. - // The first, 65519, is specified in the documentation and is one of the first checks - // enforced on a URI. This limit is not enforced after expansion. - private const int InitialLengthLimit = MaxUriLength; - - // The second, 65535 (ushort.MaxValue) is only reachable via expansion as a result of - // percent encoding. Exceeding this value used to result in a hang, but now results in - // an exception. - private const int ExpandedLengthLimit = ushort.MaxValue; - - // In order to maximize compat, we have to allow a gap between the two maximum - // values. A URI that starts below 65519 but expands to be in the range [65519,65535) - // would have worked before this change, and so should continue to work despite - // exceeding limit (1). - public static IEnumerable Iri_ExpandingContents_TooLong + public static IEnumerable Iri_ExpandingContents_TestData { get { - // Validate a URI with an initial length less than InitialLengthLimit, and an expanded - // length that is greater than ExpandedLengthLimit. - // The total of len + const parts (15) + expanded unicode (2 * 9) after expansion should be - // just larger than ExpandedLengthLimit. - int len = ExpandedLengthLimit - 15 - (2 * 9) + 1; - yield return new object[] { @"test://" + new string('a', len) + new string('\uD800', 2) + "@8.8.8.8" }; // Userinfo - yield return new object[] { @"test://8.8.8.8?" + new string('a', len) + new string('\uD800', 2) }; // Query - yield return new object[] { @"test://8.8.8.8#" + new string('a', len) + new string('\uD800', 2) }; // Fragment - yield return new object[] { @"test://8.8.8.8/" + new string('a', len) + new string('\uD800', 2) }; // Path - - // Generate a string whose total length is just less than InitialLengthLimit - // but whose content expands to be dramatically larger than ExpandedLengthLimit. - len = InitialLengthLimit - 15; - yield return new object[] { @"test://" + new string('\uD800', len) + "@8.8.8.8" }; // Userinfo - yield return new object[] { @"test://8.8.8.8?" + new string('\uD800', len) }; // Fragment - yield return new object[] { @"test://8.8.8.8#" + new string('\uD800', len) }; // Query - yield return new object[] { @"test://8.8.8.8/" + new string('\uD800', len) }; // Path - - // Test the minimum length URI that will cause an expansion beyond ExpandedLengthLimit. - len = (ExpandedLengthLimit - 15) / 9 + 1; - yield return new object[] { @"test://" + new string('\uD800', len) + "@8.8.8.8" }; // Userinfo - yield return new object[] { @"test://8.8.8.8?" + new string('\uD800', len) }; // Fragment - yield return new object[] { @"test://8.8.8.8#" + new string('\uD800', len) }; // Query - yield return new object[] { @"test://8.8.8.8/" + new string('\uD800', len) }; // Path + foreach (int length in new[] { 1, 64_000, 66_000, 1_000_000 }) + { + yield return new object[] { @"test://" + new string('a', length) + new string('\uD800', 2) + "@8.8.8.8" }; // Userinfo + yield return new object[] { @"test://8.8.8.8?" + new string('a', length) + new string('\uD800', 2) }; // Query + yield return new object[] { @"test://8.8.8.8#" + new string('a', length) + new string('\uD800', 2) }; // Fragment + yield return new object[] { @"test://8.8.8.8/" + new string('a', length) + new string('\uD800', 2) }; // Path + + yield return new object[] { @"test://" + new string('\uD800', length) + "@8.8.8.8" }; // Userinfo + yield return new object[] { @"test://8.8.8.8?" + new string('\uD800', length) }; // Fragment + yield return new object[] { @"test://8.8.8.8#" + new string('\uD800', length) }; // Query + yield return new object[] { @"test://8.8.8.8/" + new string('\uD800', length) }; // Path + } } } [Theory] - [MemberData(nameof(Iri_ExpandingContents_TooLong))] - public static void Iri_ExpandingContents_ThrowsIfTooLong(string input) + [MemberData(nameof(Iri_ExpandingContents_TestData))] + public static void Iri_ExpandingContents_Accepted(string input) { - Assert.Throws(() => new Uri(input)); - Assert.False(Uri.TryCreate(input, UriKind.Absolute, out Uri _)); - } + var uri = new Uri(input); + PropertiesDoNotThrow(uri); - public static IEnumerable Iri_ExpandingContents_AllowedSize - { - get + Assert.True(Uri.TryCreate(input, UriKind.Absolute, out uri)); + PropertiesDoNotThrow(uri); + + Assert.True(Uri.TryCreate(input, new UriCreationOptions { DangerousDisablePathAndQueryCanonicalization = true }, out uri)); + PropertiesDoNotThrow(uri); + + static void PropertiesDoNotThrow(Uri uri) { - // Validate a URI with an initial length less than InitialLengthLimit, and an expanded - // length that is greater than InitialLengthLimit but less than ExpandedLengthLimit. - // The total of len + const parts (15) + expanded unicode (2 * 9) after expansion should be - // exactly the ExpandedLengthLimit. - int len = ExpandedLengthLimit - 15 - (2 * 9); - yield return new object[] { @"test://" + new string('a', len) + new string('\uD800', 2) + "@8.8.8.8" }; // Userinfo - yield return new object[] { @"test://8.8.8.8?" + new string('a', len) + new string('\uD800', 2) }; // Query - yield return new object[] { @"test://8.8.8.8#" + new string('a', len) + new string('\uD800', 2) }; // Fragment - yield return new object[] { @"test://8.8.8.8/" + new string('a', len) + new string('\uD800', 2) }; // Path - - // Validate the same behavior, but maximize the amount of expansion. - len = (ExpandedLengthLimit - 15) / 9; - yield return new object[] { @"test://" + new string('\uD800', len) + "@8.8.8.8" }; // Userinfo - yield return new object[] { @"test://8.8.8.8?" + new string('\uD800', len) }; // Fragment - yield return new object[] { @"test://8.8.8.8#" + new string('\uD800', len) }; // Query - yield return new object[] { @"test://8.8.8.8/" + new string('\uD800', len) }; // Path + Assert.NotNull(uri.Scheme); + Assert.NotNull(uri.UserInfo); + Assert.NotNull(uri.Host); + Assert.NotNull(uri.IdnHost); + Assert.NotNull(uri.Authority); + Assert.Equal(-1, uri.Port); + Assert.NotNull(uri.LocalPath); + Assert.NotNull(uri.AbsolutePath); + Assert.NotNull(uri.PathAndQuery); + Assert.NotNull(uri.Query); + Assert.NotNull(uri.Fragment); + Assert.NotNull(uri.AbsoluteUri); + Assert.NotNull(uri.Segments); + Assert.NotNull(uri.ToString()); } } - - [Theory] - [MemberData(nameof(Iri_ExpandingContents_AllowedSize))] - public static void Iri_ExpandingContents_DoesNotThrowIfSizeAllowed(string input) - { - new Uri(input); - Assert.True(Uri.TryCreate(input, UriKind.Absolute, out Uri _)); - } } } diff --git a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriBuilderTests.cs b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriBuilderTests.cs index b070957e834e21..5e35c4c1e146c7 100644 --- a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriBuilderTests.cs +++ b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriBuilderTests.cs @@ -97,7 +97,7 @@ public void Ctor_Uri_Null() [InlineData("http", null, "http", "")] [InlineData(null, "", "", "")] [InlineData(null, null, "", "")] - public void Ctor_String_String(string schemeName, string hostName, string expectedScheme, string expectedHost) + public void Ctor_String_String(string? schemeName, string? hostName, string expectedScheme, string expectedHost) { var uriBuilder = new UriBuilder(schemeName, hostName); VerifyUriBuilder(uriBuilder, expectedScheme, "", "", expectedHost, -1, "/", "", ""); @@ -116,7 +116,7 @@ public void Ctor_String_String(string schemeName, string hostName, string expect [InlineData("http", null, 180, "http", "")] [InlineData(null, "", -1, "", "")] [InlineData(null, null, 65535, "", "")] - public void Ctor_String_String_Int(string scheme, string host, int port, string expectedScheme, string expectedHost) + public void Ctor_String_String_Int(string? scheme, string? host, int port, string expectedScheme, string expectedHost) { var uriBuilder = new UriBuilder(scheme, host, port); VerifyUriBuilder(uriBuilder, expectedScheme, "", "", expectedHost, port, "/", "", ""); @@ -135,7 +135,7 @@ public void Ctor_String_String_Int(string scheme, string host, int port, string [InlineData("http", null, 180, @"path1\path2\", "http", "", "path1/path2/")] [InlineData(null, "", -1, "\u1234", "", "", "%E1%88%B4")] [InlineData(null, null, 65535, "\u1234\u2345", "", "", "%E1%88%B4%E2%8D%85")] - public void Ctor_String_String_Int_String(string schemeName, string hostName, int port, string pathValue, string expectedScheme, string expectedHost, string expectedPath) + public void Ctor_String_String_Int_String(string? schemeName, string? hostName, int port, string? pathValue, string expectedScheme, string expectedHost, string expectedPath) { var uriBuilder = new UriBuilder(schemeName, hostName, port, pathValue); VerifyUriBuilder(uriBuilder, expectedScheme, "", "", expectedHost, port, expectedPath, "", ""); @@ -153,7 +153,7 @@ public void Ctor_String_String_Int_String(string schemeName, string hostName, in [InlineData("http", null, 180, @"path1\path2\", "?\u1234#\u2345", "http", "", "path1/path2/", "?\u1234", "#\u2345")] [InlineData(null, "", -1, "\u1234", "", "", "", "%E1%88%B4", "", "")] [InlineData(null, null, 65535, "\u1234\u2345", null, "", "", "%E1%88%B4%E2%8D%85", "", "")] - public void Ctor_String_String_Int_String_String(string schemeName, string hostName, int port, string pathValue, string extraValue, string expectedScheme, string expectedHost, string expectedPath, string expectedQuery, string expectedFragment) + public void Ctor_String_String_Int_String_String(string? schemeName, string? hostName, int port, string? pathValue, string? extraValue, string expectedScheme, string expectedHost, string expectedPath, string expectedQuery, string expectedFragment) { var uriBuilder = new UriBuilder(schemeName, hostName, port, pathValue, extraValue); VerifyUriBuilder(uriBuilder, expectedScheme, "", "", expectedHost, port, expectedPath, expectedQuery, expectedFragment); @@ -171,7 +171,7 @@ public void Ctor_InvalidExtraValue_ThrowsArgumentException(string extraValue) [InlineData("https", "https")] [InlineData("", "")] [InlineData(null, "")] - public void Scheme_Get_Set(string value, string expected) + public void Scheme_Get_Set(string? value, string expected) { var uriBuilder = new UriBuilder("http://userinfo@domain/path?query#fragment"); uriBuilder.Scheme = value; @@ -196,7 +196,7 @@ public void InvalidScheme_ThrowsArgumentException(string schemeName) [InlineData("username", "username")] [InlineData("", "")] [InlineData(null, "")] - public void UserName_Get_Set(string value, string expected) + public void UserName_Get_Set(string? value, string expected) { var uriBuilder = new UriBuilder("http://userinfo@domain/path?query#fragment"); uriBuilder.UserName = value; @@ -212,7 +212,7 @@ public void UserName_Get_Set(string value, string expected) [InlineData("password", "password")] [InlineData("", "")] [InlineData(null, "")] - public void Password_Get_Set(string value, string expected) + public void Password_Get_Set(string? value, string expected) { var uriBuilder = new UriBuilder("http://userinfo1:PLACEHOLDER@domain/path?query#fragment"); uriBuilder.Password = value; @@ -227,7 +227,7 @@ public void Password_Get_Set(string value, string expected) [InlineData("host", "host")] [InlineData("", "")] [InlineData(null, "")] - public void Host_Get_Set(string value, string expected) + public void Host_Get_Set(string? value, string expected) { var uriBuilder = new UriBuilder("http://userinfo@domain/path?query#fragment"); uriBuilder.Host = value; @@ -264,7 +264,7 @@ public void InvalidPort_ThrowsArgumentOutOfRangeException(int portNumber) [InlineData(@"\path1\path2", "/path1/path2")] [InlineData("", "/")] [InlineData(null, "/")] - public void Path_Get_Set(string value, string expected) + public void Path_Get_Set(string? value, string expected) { var uriBuilder = new UriBuilder("http://userinfo@domain/path?query#fragment"); uriBuilder.Path = value; @@ -275,7 +275,7 @@ public void Path_Get_Set(string value, string expected) [InlineData("query", "?query")] [InlineData("", "")] [InlineData(null, "")] - public void Query_Get_Set(string value, string expected) + public void Query_Get_Set(string? value, string expected) { var uriBuilder = new UriBuilder(); uriBuilder.Query = value; @@ -306,7 +306,7 @@ public void Fragment_Get_Set_StartsWithPound(string value, string expected) [InlineData("fragment", "#fragment")] [InlineData("", "")] [InlineData(null, "")] - public void Fragment_Get_Set(string value, string expected) + public void Fragment_Get_Set(string? value, string expected) { var uriBuilder = new UriBuilder(); uriBuilder.Fragment = value; diff --git a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriEscapingTest.cs b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriEscapingTest.cs index 883f48a420e982..be427489dd9d63 100644 --- a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriEscapingTest.cs +++ b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriEscapingTest.cs @@ -303,9 +303,7 @@ static void ValidateUnescape(string input, string expectedOutput) [Fact] public void UriEscapeUnescapeDataString_LongInputs() { - // Test the no-longer-existing "c_MaxUriBufferSize" limit of 0xFFF0, - // as well as lengths longer than the max Uri length of ushort.MaxValue. - foreach (int length in new[] { 1, 0xFFF0, 0xFFF1, ushort.MaxValue + 10 }) + foreach (int length in new[] { 1, 64_000, 66_000, 1_000_000 }) { string unescaped = new string('s', length); string escaped = unescaped; @@ -411,9 +409,7 @@ public void UriEscapingUriString_FullIPv6Uri_NothingEscaped() public static IEnumerable UriEscapingUriString_Long_MemberData() { - // Test the no-longer-existing "c_MaxUriBufferSize" limit of 0xFFF0, - // as well as lengths longer than the max Uri length of ushort.MaxValue. - foreach (int length in new[] { 1, 0xFFF0, 0xFFF1, ushort.MaxValue + 10 }) + foreach (int length in new[] { 1, 64_000, 66_000, 1_000_000 }) { yield return new object[] { new string('s', length), string.Concat(Enumerable.Repeat("s", length)) }; yield return new object[] { new string('<', length), string.Concat(Enumerable.Repeat("%3C", length)) }; diff --git a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs index f3207c4a25bf8a..bf1a31d6c7927d 100644 --- a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs +++ b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Globalization; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Xunit; @@ -490,7 +491,7 @@ public static void TestMakeRelative() [InlineData("1.2.3.4", UriHostNameType.IPv4)] [InlineData(null, UriHostNameType.Unknown)] [InlineData("!@*(@#&*#$&*#", UriHostNameType.Unknown)] - public static void TestCheckHostName(string hostName, UriHostNameType expected) + public static void TestCheckHostName(string? hostName, UriHostNameType expected) { Assert.Equal(expected, Uri.CheckHostName(hostName)); } @@ -499,7 +500,7 @@ public static void TestCheckHostName(string hostName, UriHostNameType expected) [InlineData("http", true)] [InlineData(null, false)] [InlineData("!", false)] - public static void TestCheckSchemeName(string scheme, bool expected) + public static void TestCheckSchemeName(string? scheme, bool expected) { Assert.Equal(expected, Uri.CheckSchemeName(scheme)); } @@ -973,5 +974,32 @@ public static void IsLoopback() } } } + + [Fact] + [ActiveIssue("Manual only. This test takes a few minutes to execute.")] + public static async Task VeryLongInputs_ThrowOOM() + { + // This string will expand 6x when escaped (12 = 6x growth * 2 chars in the string) + string longString = string.Concat(Enumerable.Repeat("\uD83C\uDF49", int.MaxValue / 12)); + + Task userInfo = Task.Run(() => Test($"http://{longString}@host/path")); + Task path = Task.Run(() => Test($"http://host/{longString}")); + Task query = Task.Run(() => Test($"http://host/path?{longString}")); + Task fragment = Task.Run(() => Test($"http://host/path?foo=bar#{longString}")); + + await userInfo; + await path; + await query; + await fragment; + + static void Test(string uriString) + { + var uri = new Uri(uriString, UriKind.Absolute); + Assert.Throws(() => uri.AbsoluteUri); + + Assert.True(Uri.TryCreate(uriString, UriKind.Absolute, out uri)); + Assert.Throws(() => uri.AbsoluteUri); + } + } } } diff --git a/src/libraries/System.Private.Uri/tests/UnitTests/PathCompressionTests.cs b/src/libraries/System.Private.Uri/tests/UnitTests/PathCompressionTests.cs new file mode 100644 index 00000000000000..8950d452482ae8 --- /dev/null +++ b/src/libraries/System.Private.Uri/tests/UnitTests/PathCompressionTests.cs @@ -0,0 +1,149 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.PrivateUri.Tests +{ + public class PathCompressionTests + { + [Fact] + public void TestCompressRegressions() + { + const string Alphabet = "/.A"; + + var rng = new Random(42); + char[] buffer1 = new char[64]; + char[] buffer2 = new char[64]; + + for (int i = 0; i < 1_000_000; i++) + { + Span pathBuffer1 = buffer1.AsSpan(0, rng.Next(buffer1.Length)); + Span pathBuffer2 = buffer2.AsSpan(0, pathBuffer1.Length); + + rng.GetItems(Alphabet, pathBuffer1); + pathBuffer1.CopyTo(pathBuffer2); + + bool canonicalizeAsFilePath = rng.Next(2) == 0; + + int expectedNewLength = LegacyCompressImpl(pathBuffer1, canonicalizeAsFilePath); + int actualNewLength = UriHelper.Compress(pathBuffer2, convertPathSlashes: false, canonicalizeAsFilePath); + + Assert.Equal(pathBuffer1.Slice(0, expectedNewLength), pathBuffer2.Slice(0, actualNewLength)); + } + } + + private static int LegacyCompressImpl(Span span, bool canonicalizeAsFilePath) + { + int slashCount = 0; + int lastSlash = 0; + int dotCount = 0; + int removeSegments = 0; + + for (int i = span.Length - 1; i >= 0; i--) + { + char ch = span[i]; + + // compress multiple '/' for file URI + if (ch == '/') + { + ++slashCount; + } + else + { + if (slashCount > 1) + { + // else preserve repeated slashes + lastSlash = i + 1; + } + slashCount = 0; + } + + if (ch == '.') + { + ++dotCount; + continue; + } + else if (dotCount != 0) + { + bool skipSegment = canonicalizeAsFilePath && (dotCount > 2 || ch != '/'); + + // Cases: + // /./ = remove this segment + // /../ = remove this segment, mark next for removal + // /....x = DO NOT TOUCH, leave as is + // x.../ = DO NOT TOUCH, leave as is, except for V2 legacy mode + if (!skipSegment && ch == '/') + { + if ((lastSlash == i + dotCount + 1 // "/..../" + || (lastSlash == 0 && i + dotCount + 1 == span.Length)) // "/..." + && (dotCount <= 2)) + { + // /./ or /. or /../ or /.. + + // span.Remove(i + 1, dotCount + (lastSlash == 0 ? 0 : 1)); + lastSlash = i + 1 + dotCount + (lastSlash == 0 ? 0 : 1); + span.Slice(lastSlash).CopyTo(span.Slice(i + 1)); + span = span.Slice(0, span.Length - (lastSlash - i - 1)); + + lastSlash = i; + if (dotCount == 2) + { + // We have 2 dots in between like /../ or /.., + // Mark next segment for removal and remove this /../ or /.. + ++removeSegments; + } + dotCount = 0; + continue; + } + } + // .NET 4.5 no longer removes trailing dots in a path segment x.../ or x... + dotCount = 0; + + // Here all other cases go such as + // x.[..]y or /.[..]x or (/x.[...][/] && removeSegments !=0) + } + + // Now we may want to remove a segment because of previous /../ + if (ch == '/') + { + if (removeSegments != 0) + { + --removeSegments; + + span.Slice(lastSlash + 1).CopyTo(span.Slice(i + 1)); + span = span.Slice(0, span.Length - (lastSlash - i)); + } + lastSlash = i; + } + } + + if (span.Length != 0 && canonicalizeAsFilePath) + { + if (slashCount <= 1) + { + if (removeSegments != 0 && span[0] != '/') + { + //remove first not rooted segment + lastSlash++; + span.Slice(lastSlash).CopyTo(span); + return span.Length - lastSlash; + } + else if (dotCount != 0) + { + // If final string starts with a segment looking like .[...]/ or .[...] + // then we remove this first segment + if (lastSlash == dotCount || (lastSlash == 0 && dotCount == span.Length)) + { + dotCount += lastSlash == 0 ? 0 : 1; + span.Slice(dotCount).CopyTo(span); + return span.Length - dotCount; + } + } + } + } + + return span.Length; + } + } +} diff --git a/src/libraries/System.Private.Uri/tests/UnitTests/System.Private.Uri.Unit.Tests.csproj b/src/libraries/System.Private.Uri/tests/UnitTests/System.Private.Uri.Unit.Tests.csproj index e3f38a50e352fe..3bbbf28f1e087f 100644 --- a/src/libraries/System.Private.Uri/tests/UnitTests/System.Private.Uri.Unit.Tests.csproj +++ b/src/libraries/System.Private.Uri/tests/UnitTests/System.Private.Uri.Unit.Tests.csproj @@ -9,6 +9,7 @@ + @@ -17,9 +18,8 @@ - - + + + diff --git a/src/libraries/System.Private.Xml.Linq/System.Private.Xml.Linq.slnx b/src/libraries/System.Private.Xml.Linq/System.Private.Xml.Linq.slnx index c46f0f84004b38..e3792121cd0c45 100644 --- a/src/libraries/System.Private.Xml.Linq/System.Private.Xml.Linq.slnx +++ b/src/libraries/System.Private.Xml.Linq/System.Private.Xml.Linq.slnx @@ -1,43 +1,1130 @@ + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Private.Xml.Linq/src/System.Private.Xml.Linq.csproj b/src/libraries/System.Private.Xml.Linq/src/System.Private.Xml.Linq.csproj index 604a04488e3cd7..1d1a2acfd55003 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System.Private.Xml.Linq.csproj +++ b/src/libraries/System.Private.Xml.Linq/src/System.Private.Xml.Linq.csproj @@ -44,14 +44,14 @@ - - - - - - - - + + + + + + + + diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs index b96094746ea465..8b21982599f04b 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs @@ -75,7 +75,7 @@ public XNode? LastNode XText t = new XText(s); t.parent = this; t.next = t; - Interlocked.CompareExchange(ref content, t, s); + Interlocked.CompareExchange(ref content, t, s); } return (XNode)content; } diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNode.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNode.cs index 4039b9bdcfc387..5843fc5654019c 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNode.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNode.cs @@ -28,9 +28,6 @@ namespace System.Xml.Linq /// public abstract class XNode : XObject { - private static XNodeDocumentOrderComparer? s_documentOrderComparer; - private static XNodeEqualityComparer? s_equalityComparer; - internal XNode? next; internal XNode() { } @@ -77,12 +74,12 @@ public XNode? PreviousNode /// /// Gets a comparer that can compare the relative position of two nodes. /// - public static XNodeDocumentOrderComparer DocumentOrderComparer => s_documentOrderComparer ??= new XNodeDocumentOrderComparer(); + public static XNodeDocumentOrderComparer DocumentOrderComparer => field ??= new XNodeDocumentOrderComparer(); /// /// Gets a comparer that can compare two nodes for value equality. /// - public static XNodeEqualityComparer EqualityComparer => s_equalityComparer ??= new XNodeEqualityComparer(); + public static XNodeEqualityComparer EqualityComparer => field ??= new XNodeEqualityComparer(); /// /// Adds the specified content immediately after this node. The diff --git a/src/libraries/System.Private.Xml.Linq/tests/Properties/NamespaceAccessors.cs b/src/libraries/System.Private.Xml.Linq/tests/Properties/NamespaceAccessors.cs index 076e9df7de1708..3b2d78762ebe48 100644 --- a/src/libraries/System.Private.Xml.Linq/tests/Properties/NamespaceAccessors.cs +++ b/src/libraries/System.Private.Xml.Linq/tests/Properties/NamespaceAccessors.cs @@ -82,7 +82,7 @@ public void GetDefaultNamespaceDMLSanity() [InlineData("", "xml", "http://www.w3.org/XML/1998/namespace")] [InlineData("", "xmlns", "http://www.w3.org/2000/xmlns/")] [InlineData("", "X", null)] - public void NamespaceForPrefix(string xml, string prefix, string ns) + public void NamespaceForPrefix(string xml, string prefix, string? ns) { XNamespace NS = ns == null ? null : XNamespace.Get(ns); XElement e = XElement.Parse(xml); @@ -97,7 +97,7 @@ public void NamespaceForPrefix(string xml, string prefix, string ns) [Theory] [InlineData("", null, typeof(ArgumentNullException))] [InlineData("", "", typeof(ArgumentException))] - public void NamespaceForPrefixNull(string xml, string prefix, Type expectedException) + public void NamespaceForPrefixNull(string xml, string? prefix, Type expectedException) { XElement e = XElement.Parse(xml); Assert.Throws(expectedException, () => (e.FirstNode as XElement).GetNamespaceOfPrefix(prefix)); @@ -155,7 +155,7 @@ public void NamespaceForPrefixDMLSanity() [InlineData("", "xml", "http://www.w3.org/XML/1998/namespace")] [InlineData("", "xmlns", "http://www.w3.org/2000/xmlns/")] [InlineData("", null, "nonexisting")] - public void PrefixOfNamespace(string xml, string prefix, string ns) + public void PrefixOfNamespace(string xml, string? prefix, string ns) { XElement e = XElement.Parse(xml); string pref = (e.FirstNode as XElement).GetPrefixOfNamespace(XNamespace.Get(ns)); @@ -164,7 +164,7 @@ public void PrefixOfNamespace(string xml, string prefix, string ns) [Theory] [InlineData("", null)] - public void PrefixOfNamespaceNull(string xml, string ns) + public void PrefixOfNamespaceNull(string xml, string? ns) { XElement e = XElement.Parse(xml); Assert.Throws(() => (e.FirstNode as XElement).GetPrefixOfNamespace(ns)); diff --git a/src/libraries/System.Private.Xml/System.Private.Xml.slnx b/src/libraries/System.Private.Xml/System.Private.Xml.slnx index d3a8fb09abd8e1..ffc743e1732ce1 100644 --- a/src/libraries/System.Private.Xml/System.Private.Xml.slnx +++ b/src/libraries/System.Private.Xml/System.Private.Xml.slnx @@ -1,35 +1,1066 @@ + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj b/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj index bcf484009cfbd4..bd3f70ad7a344a 100644 --- a/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj +++ b/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj @@ -759,30 +759,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocument.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocument.cs index a7f9c855edfa00..c53b6a7b25be82 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocument.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocument.cs @@ -74,7 +74,6 @@ private static readonly (string key, int hash)[] s_nameTableSeeds = new[] private readonly XmlImplementation _implementation; private readonly DomNameTable _domNameTable; // hash table of XmlName private XmlLinkedNode? _lastChild; - private XmlNamedNodeMap? _entities; private Hashtable? _htElementIdMap; private Hashtable? _htElementIDAttrDecl; //key: id; object: the ArrayList of the elements that have the same id (connected or disconnected) private SchemaInfo? _schemaInfo; @@ -1090,8 +1089,8 @@ public override bool IsReadOnly internal XmlNamedNodeMap Entities { - get => _entities ??= new XmlNamedNodeMap(this); - set => _entities = value; + get => field ??= new XmlNamedNodeMap(this); + set => field = value; } internal bool IsLoading diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocumentType.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocumentType.cs index fffb34a10f47d4..8bffa0636e8162 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocumentType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocumentType.cs @@ -14,8 +14,6 @@ public class XmlDocumentType : XmlLinkedNode private readonly string? _systemId; private readonly string? _internalSubset; private bool _namespaces; - private XmlNamedNodeMap? _entities; - private XmlNamedNodeMap? _notations; // parsed DTD private SchemaInfo? _schemaInfo; @@ -76,10 +74,10 @@ public override bool IsReadOnly } // Gets the collection of XmlEntity nodes declared in the document type declaration. - public XmlNamedNodeMap Entities => _entities ??= new XmlNamedNodeMap(this); + public XmlNamedNodeMap Entities => field ??= new XmlNamedNodeMap(this); // Gets the collection of XmlNotation nodes present in the document type declaration. - public XmlNamedNodeMap Notations => _notations ??= new XmlNamedNodeMap(this); + public XmlNamedNodeMap Notations => field ??= new XmlNamedNodeMap(this); // // DOM Level 2 diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/ValidationState.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/ValidationState.cs index a877febf910fcb..f75d1a470629f9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/ValidationState.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/ValidationState.cs @@ -42,8 +42,7 @@ internal sealed class ValidationState public bool HasMatched; // whether the element has been verified correctly //For NFAs - private BitSet[]? _curPos; - public BitSet[] CurPos => _curPos ??= new BitSet[2]; + public BitSet[] CurPos => field ??= new BitSet[2]; //For all public BitSet? AllElementsSet; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchema.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchema.cs index c9c5e9df337479..3ea8ae0addb237 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchema.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchema.cs @@ -35,24 +35,16 @@ public class XmlSchema : XmlSchemaObject private bool _isPreprocessed; private bool _isRedefined; private int _errorCount; - private XmlSchemaObjectTable? _attributes; - private XmlSchemaObjectTable _attributeGroups = new XmlSchemaObjectTable(); - private XmlSchemaObjectTable _elements = new XmlSchemaObjectTable(); - private XmlSchemaObjectTable _types = new XmlSchemaObjectTable(); private readonly XmlSchemaObjectTable _groups = new XmlSchemaObjectTable(); private readonly XmlSchemaObjectTable _notations = new XmlSchemaObjectTable(); private readonly XmlSchemaObjectTable _identityConstraints = new XmlSchemaObjectTable(); private static int s_globalIdCounter = -1; - private ArrayList? _importedSchemas; - private ArrayList? _importedNamespaces; private int _schemaId = -1; //Not added to a set private Uri? _baseUri; private bool _isChameleon; private readonly Hashtable _ids = new Hashtable(); - private XmlDocument? _document; - private XmlNameTable? _nameTable; public XmlSchema() { } @@ -330,16 +322,16 @@ internal bool IsRedefined } [XmlIgnore] - public XmlSchemaObjectTable Attributes => _attributes ??= new XmlSchemaObjectTable(); + public XmlSchemaObjectTable Attributes => field ??= new XmlSchemaObjectTable(); [XmlIgnore] - public XmlSchemaObjectTable AttributeGroups => _attributeGroups ??= new XmlSchemaObjectTable(); + public XmlSchemaObjectTable AttributeGroups => field ??= new XmlSchemaObjectTable(); [XmlIgnore] - public XmlSchemaObjectTable SchemaTypes => _types ??= new XmlSchemaObjectTable(); + public XmlSchemaObjectTable SchemaTypes => field ??= new XmlSchemaObjectTable(); [XmlIgnore] - public XmlSchemaObjectTable Elements => _elements ??= new XmlSchemaObjectTable(); + public XmlSchemaObjectTable Elements => field ??= new XmlSchemaObjectTable(); [XmlAttribute("id", DataType = "ID")] public string? Id @@ -416,7 +408,7 @@ internal Hashtable Ids } [XmlIgnore] - internal XmlDocument Document => _document ??= new XmlDocument(); + internal XmlDocument Document => field ??= new XmlDocument(); [XmlIgnore] internal int ErrorCount @@ -518,11 +510,11 @@ internal override void AddAnnotation(XmlSchemaAnnotation annotation) _items.Add(annotation); } - internal XmlNameTable NameTable => _nameTable ??= new System.Xml.NameTable(); + internal XmlNameTable NameTable => field ??= new System.Xml.NameTable(); - internal ArrayList ImportedSchemas => _importedSchemas ??= new ArrayList(); + internal ArrayList ImportedSchemas => field ??= new ArrayList(); - internal ArrayList ImportedNamespaces => _importedNamespaces ??= new ArrayList(); + internal ArrayList ImportedNamespaces => field ??= new ArrayList(); internal static void GetExternalSchemasList(IList extList, XmlSchema schema) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaObject.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaObject.cs index 62c070ba593c44..96cbb48dc20d8b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaObject.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaObject.cs @@ -11,7 +11,6 @@ public abstract class XmlSchemaObject private int _lineNum; private int _linePos; private string? _sourceUri; - private XmlSerializerNamespaces? _namespaces; private XmlSchemaObject? _parent; //internal @@ -48,8 +47,8 @@ public XmlSchemaObject? Parent [XmlNamespaceDeclarations] public XmlSerializerNamespaces Namespaces { - get => _namespaces ??= new XmlSerializerNamespaces(); - set => _namespaces = value; + get => field ??= new XmlSerializerNamespaces(); + set => field = value; } internal virtual void OnAdd(XmlSchemaObjectCollection container, object? item) { } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs index db8d7a7396296c..3443437867a6e9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs @@ -56,20 +56,8 @@ public class XmlSchemaSet private XmlSchemaObjectTable? _typeExtensions; //Thread safety - private object? _internalSyncObject; - internal object InternalSyncObject - { - get - { - if (_internalSyncObject == null) - { - object o = new object(); - Interlocked.CompareExchange(ref _internalSyncObject, o, null); - } - - return _internalSyncObject; - } - } + internal object InternalSyncObject => + field ?? Interlocked.CompareExchange(ref field, new object(), null) ?? field; //Constructors diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ImportContext.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ImportContext.cs index 614f0b511ac14f..a58813263729f9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ImportContext.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ImportContext.cs @@ -16,9 +16,6 @@ namespace System.Xml.Serialization public class ImportContext { private readonly bool _shareTypes; - private SchemaObjectCache? _cache; // cached schema top-level items - private Hashtable? _mappings; // XmlSchema -> SerializableMapping, XmlSchemaSimpleType -> EnumMapping, XmlSchemaComplexType -> StructMapping - private Hashtable? _elements; // XmlSchemaElement -> ElementAccessor private CodeIdentifiers? _typeIdentifiers; public ImportContext(CodeIdentifiers? identifiers, bool shareTypes) @@ -29,11 +26,11 @@ public ImportContext(CodeIdentifiers? identifiers, bool shareTypes) internal ImportContext() : this(null, false) { } - internal SchemaObjectCache Cache => _cache ??= new SchemaObjectCache(); + internal SchemaObjectCache Cache => field ??= new SchemaObjectCache(); // cached schema top-level items - internal Hashtable Elements => _elements ??= new Hashtable(); + internal Hashtable Elements => field ??= new Hashtable(); // XmlSchemaElement -> ElementAccessor - internal Hashtable Mappings => _mappings ??= new Hashtable(); + internal Hashtable Mappings => field ??= new Hashtable(); // XmlSchema -> SerializableMapping, XmlSchemaSimpleType -> EnumMapping, XmlSchemaComplexType -> StructMapping public CodeIdentifiers TypeIdentifiers => _typeIdentifiers ??= new CodeIdentifiers(); @@ -50,19 +47,15 @@ public StringCollection Warnings internal sealed class SchemaObjectCache { - private Hashtable? _graph; - private Hashtable? _hash; - private Hashtable? _objectCache; - private StringCollection? _warnings; // UNDONE remove me soon, this is debug only code internal Hashtable looks = new Hashtable(); - private Hashtable Graph => _graph ??= new Hashtable(); + private Hashtable Graph => field ??= new Hashtable(); - private Hashtable Hash => _hash ??= new Hashtable(); + private Hashtable Hash => field ??= new Hashtable(); - private Hashtable ObjectCache => _objectCache ??= new Hashtable(); + private Hashtable ObjectCache => field ??= new Hashtable(); - internal StringCollection Warnings => _warnings ??= new StringCollection(); + internal StringCollection Warnings => field ??= new StringCollection(); internal XmlSchemaObject? AddItem(XmlSchemaObject? item, XmlQualifiedName? qname) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Mappings.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Mappings.cs index 0861f1d78f76bd..e9eb811cf3fffa 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Mappings.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Mappings.cs @@ -476,7 +476,6 @@ internal sealed class StructMapping : TypeMapping, INameScope private bool _isSequence; private NameTable? _elements; private NameTable? _attributes; - private CodeIdentifiers? _scope; [DisallowNull] internal StructMapping? BaseMapping @@ -577,8 +576,8 @@ internal bool IsOpenModel internal CodeIdentifiers Scope { - get => _scope ??= new CodeIdentifiers(); - set => _scope = value; + get => field ??= new CodeIdentifiers(); + set => field = value; } internal MemberMapping? FindDeclaringMapping(MemberMapping member, out StructMapping? declaringMapping, string? parent) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs index 6d3d27a55915a8..331d620f631a34 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs @@ -2387,7 +2387,6 @@ internal sealed class RecursionLimiter { private readonly int _maxDepth; private int _depth; - private WorkItems? _deferredWorkItems; internal RecursionLimiter() { @@ -2398,6 +2397,6 @@ internal RecursionLimiter() internal bool IsExceededLimit { get { return _depth > _maxDepth; } } internal int Depth { get { return _depth; } set { _depth = value; } } - internal WorkItems DeferredWorkItems => _deferredWorkItems ??= new WorkItems(); + internal WorkItems DeferredWorkItems => field ??= new WorkItems(); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemas.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemas.cs index 951a3906624b2d..7de7d8d58f7f63 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemas.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemas.cs @@ -21,10 +21,8 @@ namespace System.Xml.Serialization public class XmlSchemas : CollectionBase, IEnumerable { private XmlSchemaSet? _schemaSet; - private Hashtable? _references; private SchemaObjectCache? _cache; // cached schema top-level items private bool _shareTypes; - private Hashtable? _mergedSchemas; internal Hashtable delayedSchemas = new Hashtable(); private bool _isCompiled; private static volatile XmlSchema? s_xsd; @@ -57,9 +55,9 @@ public IList GetSchemas(string? ns) internal SchemaObjectCache Cache => _cache ??= new SchemaObjectCache(); - internal Hashtable MergedSchemas => _mergedSchemas ??= new Hashtable(); + internal Hashtable MergedSchemas => field ??= new Hashtable(); - internal Hashtable References => _references ??= new Hashtable(); + internal Hashtable References => field ??= new Hashtable(); internal XmlSchemaSet SchemaSet { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs index ff27357ebba28a..93e3889be7e24d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs @@ -2043,12 +2043,11 @@ public object CollectionItems internal sealed class XmlSerializationReaderCodeGen : XmlSerializationCodeGen { private readonly Hashtable _idNames = new Hashtable(); - private Hashtable? _enums; private readonly Hashtable _createMethods = new Hashtable(); private int _nextCreateMethodNumber; private int _nextIdNumber; - internal Hashtable Enums => _enums ??= new Hashtable(); + internal Hashtable Enums => field ??= new Hashtable(); private sealed class CreateCollectionInfo { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReaderILGen.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReaderILGen.cs index a017539611908c..6032b1ebc8cc13 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReaderILGen.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReaderILGen.cs @@ -23,10 +23,9 @@ internal sealed partial class XmlSerializationReaderILGen : XmlSerializationILGe private readonly Dictionary _idNames = new Dictionary(); // Mapping name->id_XXXNN field private readonly Dictionary _idNameFields = new Dictionary(); - private Dictionary? _enums; private int _nextIdNumber; - internal Dictionary Enums => _enums ??= new Dictionary(); + internal Dictionary Enums => field ??= new Dictionary(); private static readonly string[] s_checkTypeString = new string[] { "checkType" }; private static readonly Type[] s_boolType = new Type[] { typeof(bool) }; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILConstructAnalyzer.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILConstructAnalyzer.cs index 7346cadcd902e9..824156c3c5cb47 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILConstructAnalyzer.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlILConstructAnalyzer.cs @@ -54,7 +54,6 @@ internal sealed class XmlILConstructInfo : IQilAnnotation private bool _isNmspInScope, _mightHaveNmsp, _mightHaveAttrs, _mightHaveDupAttrs, _mightHaveNmspAfterAttrs; private XmlILConstructMethod _constrMeth; private XmlILConstructInfo? _parentInfo; - private ArrayList? _callersInfo; private bool _isReadOnly; private static volatile XmlILConstructInfo? s_default; @@ -359,7 +358,7 @@ public bool MightHaveDuplicateAttributes /// This annotation is only applicable to Function nodes. It contains a list of XmlILConstructInfo annotations /// for all QilInvoke nodes which call the annotated function. /// - public ArrayList CallersInfo => _callersInfo ??= new ArrayList(); + public ArrayList CallersInfo => field ??= new ArrayList(); /// /// Return name of this annotation. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Compiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Compiler.cs index 918dfa58a2cd7a..7c9b91a292df5d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Compiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Compiler.cs @@ -42,6 +42,7 @@ internal sealed class Compiler public int CurrentPrecedence; // Decreases by 1 with each import public XslNode? StartApplyTemplates; public RootLevel? Root; + [Obsolete(Obsoletions.XsltSettingsEnableScriptMessage, DiagnosticId = Obsoletions.XsltSettingsEnableScriptDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public Scripts Scripts; public Output Output = new Output(); public List ExternalPars = new List(); @@ -67,7 +68,9 @@ public Compiler(XsltSettings settings, bool debug, string? scriptAssemblyPath) ScriptAssemblyPath = scriptAssemblyPath; CompilerErrorColl = new CompilerErrorCollection(); +#pragma warning disable SYSLIB0062 // Scripts field is obsolete Scripts = new Scripts(this); +#pragma warning restore SYSLIB0062 } public CompilerErrorCollection Compile(object stylesheet, XmlResolver? xmlResolver, XmlResolver? origResolver, out QilExpression qil) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs index 4b7a35946a2864..5aa907f9325958 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs @@ -195,7 +195,9 @@ private QilExpression Compile(Compiler compiler) } // Create list of all early bound objects +#pragma warning disable SYSLIB0062 // Scripts field is obsolete Scripts.TrimSafeDictionary scriptClasses = compiler.Scripts.ScriptClasses; +#pragma warning restore SYSLIB0062 List ebTypes = new List(scriptClasses.Count); foreach (string key in scriptClasses.Keys) { @@ -261,10 +263,12 @@ private void CompileInitializationCode() } // Register all script namespaces +#pragma warning disable SYSLIB0062 // Scripts field is obsolete foreach (string scriptNs in _compiler.Scripts.ScriptClasses.Keys) { init = _f.Add(init, _f.InvokeCheckScriptNamespace(scriptNs)); } +#pragma warning restore SYSLIB0062 if (init.NodeType == QilNodeType.Add) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGeneratorEnv.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGeneratorEnv.cs index 30e32b4fe6169c..f0410142b8ca5a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGeneratorEnv.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGeneratorEnv.cs @@ -213,6 +213,7 @@ QilNode IXPathEnvironment.ResolveFunction(string prefix, string name, IList args) { // Unknown function. Can be script function or extension function funcFlags = XslFlags.AnyType; +#pragma warning disable SYSLIB0062 // XsltSettings.EnableScript is obsolete if (_compiler.Settings.EnableScript && ns != null) { XmlExtensionFunction? scrFunc = _compiler.Scripts.ResolveFunction(name, ns, args.Count, default(NullErrorHelper)); @@ -1175,6 +1176,7 @@ public XslFlags Function(string prefix, string name, IList args) } } funcFlags |= XslFlags.SideEffects; +#pragma warning restore SYSLIB0062 } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XsltLoader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XsltLoader.cs index 7148aacf2294df..16aed658c26b9e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XsltLoader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XsltLoader.cs @@ -1309,12 +1309,14 @@ private void LoadMsScript(NsDecl? stylesheetNsList) scriptNs ??= _compiler.CreatePhantomNamespace(); ParseStringAttribute(1, "language"); +#pragma warning disable SYSLIB0062 // XsltSettings.EnableScript is obsolete if (!_compiler.Settings.EnableScript) { _compiler.Scripts.ScriptClasses[scriptNs] = null; _input.SkipNode(); return; } +#pragma warning restore SYSLIB0062 throw new PlatformNotSupportedException(SR.CompilingScriptsNotSupported); // Not adding any scripts as script compilation is not available } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/Processor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/Processor.cs index 32af222ca8b7c9..b2c1254412ce50 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/Processor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/Processor.cs @@ -91,7 +91,6 @@ internal enum OutputResult #pragma warning restore 618 private readonly Hashtable _scriptExtensions; - private ArrayList? _numberList; // // Template lookup action // @@ -303,7 +302,7 @@ internal void ReleaseSharedStringBuilder() } #pragma warning restore CA1822 - internal ArrayList NumberList => _numberList ??= new ArrayList(); + internal ArrayList NumberList => field ??= new ArrayList(); internal IXsltDebugger? Debugger { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/RootAction.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/RootAction.cs index 338fc89fd409a8..e4925381fe629c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/RootAction.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/RootAction.cs @@ -83,9 +83,8 @@ internal sealed class RootAction : TemplateBaseAction private readonly Hashtable _attributeSetTable = new Hashtable(); private readonly Hashtable _decimalFormatTable = new Hashtable(); private List? _keyList; - private XsltOutput? _output; - internal XsltOutput Output => _output ??= new XsltOutput(); + internal XsltOutput Output => field ??= new XsltOutput(); /* * Compile diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XsltSettings.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XsltSettings.cs index f2cb3a4e0b9266..30ca53a9999403 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XsltSettings.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XsltSettings.cs @@ -39,6 +39,7 @@ public bool EnableDocumentFunction set { _enableDocumentFunction = value; } } + [Obsolete(Obsoletions.XsltSettingsEnableScriptMessage, DiagnosticId = Obsoletions.XsltSettingsEnableScriptDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public bool EnableScript { get { return _enableScript; } diff --git a/src/libraries/System.Private.Xml/tests/XmlResolver/System.Xml.XmlResolver.Tests/XmlPreloadedResolverGetEntity.cs b/src/libraries/System.Private.Xml/tests/XmlResolver/System.Xml.XmlResolver.Tests/XmlPreloadedResolverGetEntity.cs index 1747a9fee1788b..098e60462cefe1 100644 --- a/src/libraries/System.Private.Xml/tests/XmlResolver/System.Xml.XmlResolver.Tests/XmlPreloadedResolverGetEntity.cs +++ b/src/libraries/System.Private.Xml/tests/XmlResolver/System.Xml.XmlResolver.Tests/XmlPreloadedResolverGetEntity.cs @@ -89,19 +89,19 @@ public void XmlResolverGetKnownEntity() } [Fact] - public void XmlResolverGetEntityAsyncWithInvalidData() + public async Task XmlResolverGetEntityAsyncWithInvalidData() { var xmlResolver = new XmlPreloadedResolver(XmlKnownDtds.Xhtml10); - Assert.ThrowsAsync(() => xmlResolver.GetEntityAsync(null, null, null)); - Assert.ThrowsAsync(() => xmlResolver.GetEntityAsync(new Uri("https://DummyUri"), null, null)); - Assert.ThrowsAsync(() => + await Assert.ThrowsAsync(() => xmlResolver.GetEntityAsync(null, null, null)); + await Assert.ThrowsAsync(() => xmlResolver.GetEntityAsync(new Uri("https://DummyUri"), null, null)); + await Assert.ThrowsAsync(() => xmlResolver.GetEntityAsync(new Uri("-//W3C//ENTITIES Latin 1 for XHTML//EN", UriKind.RelativeOrAbsolute), null, typeof(string))); xmlResolver = new XmlPreloadedResolver(new XmlPreloadedResolver(), XmlKnownDtds.Xhtml10); - Assert.ThrowsAsync(() => + await Assert.ThrowsAsync(() => xmlResolver.GetEntityAsync(new Uri("https://DummyUri", UriKind.RelativeOrAbsolute), null, typeof(string))); - Assert.ThrowsAsync(() => + await Assert.ThrowsAsync(() => xmlResolver.GetEntityAsync(new Uri("-//W3C//ENTITIES Latin 1 for XHTML//EN", UriKind.RelativeOrAbsolute), null, typeof(TextReader))); } diff --git a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_AllowXmlAttributes.cs b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_AllowXmlAttributes.cs index 2d5ffe75de7f5a..b1050c8851651a 100644 --- a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_AllowXmlAttributes.cs +++ b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_AllowXmlAttributes.cs @@ -264,7 +264,7 @@ private XmlReader CreateReader(string xmlFile, XmlSchemaSet ss, bool allowXml) [InlineData("v1-1.xml", "v1.xsd", true, 0, 0, 2)] //[Variation(Desc = "v1.1.1- Custom XML namespace System.Xml.XmlSchemaTests in the set, particle has reference to custom attribute, allowXmlAttribute=false", Priority = 1, id = 1, Params = new object[] { "v1-1.xml", "v1.xsd", false, 0, 1, 2 })] [InlineData("v1-1.xml", "v1.xsd", false, 0, 1, 2)] - public void v1(string xmlFile, string xsdFile, bool allowXmlAttributes, int expectedWarningCount, int expectedErrorCount, int expectedSchemaSetCount) + public void v1(string xmlFile, string? xsdFile, bool allowXmlAttributes, int expectedWarningCount, int expectedErrorCount, int expectedSchemaSetCount) { Initialize(); XmlSchemaSet xss = new XmlSchemaSet(); diff --git a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_Imports.cs b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_Imports.cs index b878e2f5b89348..1997acdb459e36 100644 --- a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_Imports.cs +++ b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_Imports.cs @@ -27,7 +27,7 @@ public TC_SchemaSet_Imports(ITestOutputHelper output) //[Variation(Desc = "v1.1 - Import: A with NS imports B with no NS", Priority = 0, Params = new object[] { "import_v1_a.xsd", "include_v1_b.xsd", 2, null })] [InlineData("import_v1_a.xsd", "include_v1_b.xsd", 2, null)] [Theory] - public void v1(object param0, object param1, object param2, object param3) + public void v1(object param0, object param1, object param2, object? param3) { XmlSchemaSet sc = new XmlSchemaSet(); sc.XmlResolver = new XmlUrlResolver(); @@ -54,7 +54,7 @@ public void v1(object param0, object param1, object param2, object param3) //[Variation(Desc = "v2.1 - Import: Add B(ns-b) , then A(ns-a) which improts B (ns-b)", Priority = 1, Params = new object[] { "import_v2_a.xsd", "import_v2_b.xsd", 2, null, "ns-b" })] [InlineData("import_v2_a.xsd", "import_v2_b.xsd", 2, null, "ns-b")] [Theory] - public void v3(object param0, object param1, object param2, object param3, object param4) + public void v3(object param0, object param1, object param2, object? param3, object? param4) { XmlSchemaSet sc = new XmlSchemaSet(); sc.XmlResolver = new XmlUrlResolver(); @@ -527,7 +527,7 @@ public void v100() //[Variation(Desc = "v101.1 - Improt: A with NS imports B with no NS", Priority = 0, Params = new object[] { "import_v1_a.xsd", "include_v1_b.xsd", 2, null })] [InlineData("import_v1_a.xsd", "include_v1_b.xsd", 2, null)] [Theory] - public void v101(object param0, object param1, object param2, object param3) + public void v101(object param0, object param1, object param2, object? param3) { XmlSchemaSet sc = new XmlSchemaSet(); sc.XmlResolver = new XmlUrlResolver(); @@ -557,7 +557,7 @@ public void v101(object param0, object param1, object param2, object param3) //[Variation(Desc = "v102.1 - Import: Add B(ns-b) , then A(ns-a) which improts B (ns-b)", Priority = 1, Params = new object[] { "import_v2_a.xsd", "import_v2_b.xsd", 2, null, "ns-b" })] [InlineData("import_v2_a.xsd", "import_v2_b.xsd", 2, null, "ns-b")] [Theory] - public void v102(object param0, object param1, object param2, object param3, object param4) + public void v102(object param0, object param1, object param2, object? param3, object param4) { XmlSchemaSet sc = new XmlSchemaSet(); sc.XmlResolver = new XmlUrlResolver(); @@ -1225,7 +1225,7 @@ public void v120() //[Variation(Desc = "v201.1 - Improt: A with NS imports B with no NS", Priority = 0, Params = new object[] { "import_v1_a.xsd", "include_v1_b.xsd", 2, null })] [InlineData("import_v1_a.xsd", "include_v1_b.xsd", 2, null)] [Theory] - public void v201(object param0, object param1, object param2, object param3) + public void v201(object param0, object param1, object param2, object? param3) { XmlSchemaSet sc = new XmlSchemaSet(); sc.XmlResolver = new XmlUrlResolver(); @@ -1253,7 +1253,7 @@ public void v201(object param0, object param1, object param2, object param3) //[Variation(Desc = "v202.1 - Import: Add B(ns-b) , then A(ns-a) which improts B (ns-b)", Priority = 1, Params = new object[] { "import_v2_a.xsd", "import_v2_b.xsd", 2, null, "ns-b" })] [InlineData("import_v2_a.xsd", "import_v2_b.xsd", 2, null, "ns-b")] [Theory] - public void v202(object param0, object param1, object param2, object param3, object param4) + public void v202(object param0, object param1, object param2, object? param3, object param4) { XmlSchemaSet sc = new XmlSchemaSet(); sc.XmlResolver = new XmlUrlResolver(); diff --git a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaValidatorApi/ValidateAttribute.cs b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaValidatorApi/ValidateAttribute.cs index 9e4ad966f41936..5a7d8820e25154 100644 --- a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaValidatorApi/ValidateAttribute.cs +++ b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaValidatorApi/ValidateAttribute.cs @@ -26,7 +26,7 @@ public TCValidateAttribute(ITestOutputHelper output) : base(output) [Theory] [InlineData(null, "")] [InlineData("attr", null)] - public void PassNull_LocalName_NameSpace__Invalid(string localName, string nameSpace) + public void PassNull_LocalName_NameSpace__Invalid(string? localName, string? nameSpace) { XmlSchemaValidator val = CreateValidator(XSDFILE_VALIDATE_ATTRIBUTE); XmlSchemaInfo info = new XmlSchemaInfo(); diff --git a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaValidatorApi/ValidateAttribute_String.cs b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaValidatorApi/ValidateAttribute_String.cs index a3eeff42b26011..828f6a2133cd53 100644 --- a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaValidatorApi/ValidateAttribute_String.cs +++ b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaValidatorApi/ValidateAttribute_String.cs @@ -26,7 +26,7 @@ public TCValidateAttribute_String(ITestOutputHelper output) : base(output) [Theory] [InlineData(null, "")] [InlineData("attr", null)] - public void PassNull_LocalName_Namespace__Invalid(string localName, string nameSpace) + public void PassNull_LocalName_Namespace__Invalid(string? localName, string? nameSpace) { XmlSchemaValidator val = CreateValidator(XSDFILE_VALIDATE_ATTRIBUTE); XmlSchemaInfo info = new XmlSchemaInfo(); diff --git a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaValidatorApi/ValidateElement.cs b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaValidatorApi/ValidateElement.cs index 543c92c9ca4eb1..cc3217a910c776 100644 --- a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaValidatorApi/ValidateElement.cs +++ b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaValidatorApi/ValidateElement.cs @@ -242,7 +242,7 @@ public void CheckNoNamespaceSchemaLocationIs_UsedWhenSpecified_NotUsedWhenFlagIs [Theory] [InlineData(null)] [InlineData("false")] - public void CallWith_Null_False_XsiNil(string xsiNil) + public void CallWith_Null_False_XsiNil(string? xsiNil) { XmlSchemaValidator val; XmlSchemaInfo info = new XmlSchemaInfo(); diff --git a/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs b/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs index befb45d566b1a1..dfb044047e5961 100644 --- a/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs +++ b/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs @@ -3196,7 +3196,6 @@ public static void XmlMembersMapping_Soap_MultipleMembers_IsReturnValue() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/1395")] public static void Xml_TypeWithReadOnlyMyCollectionProperty() { var value = new TypeWithReadOnlyMyCollectionProperty(); @@ -3366,7 +3365,6 @@ public static void Xml_NookTypes() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DerivedTypeWithDifferentOverrides() { DerivedTypeWithDifferentOverrides value = new DerivedTypeWithDifferentOverrides() { Name1 = "Name1", Name2 = "Name2", Name3 = "Name3", Name4 = "Name4", Name5 = "Name5" }; @@ -3379,7 +3377,6 @@ public static void DerivedTypeWithDifferentOverrides() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DerivedTypeWithDifferentOverrides2() { DerivedTypeWithDifferentOverrides2 value = new DerivedTypeWithDifferentOverrides2() { Name1 = "Name1", Name2 = "Name2", Name3 = "Name3", Name4 = "Name4", Name5 = "Name5", Name6 = "Name6", Name7 = "Name7" }; diff --git a/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs b/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs index 0d94c9fb861b25..aa16bba3ec61f3 100644 --- a/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs +++ b/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs @@ -265,7 +265,6 @@ public static void Xml_ListRoot() // horizon that it's not worth the trouble. #if !XMLSERIALIZERGENERATORTESTS [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/74247", TestPlatforms.tvOS)] public static void Xml_ReadOnlyCollection() { ReadOnlyCollection roc = new ReadOnlyCollection(new string[] { "one", "two" }); @@ -287,7 +286,6 @@ public static void Xml_ReadOnlyCollection() [Theory] [MemberData(nameof(Xml_ImmutableCollections_MemberData))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/74247", TestPlatforms.tvOS)] public static void Xml_ImmutableCollections(Type type, object collection, Type createException, Type addException, string expectedXml, string exMsg = null) { XmlSerializer serializer; @@ -2309,8 +2307,7 @@ public static void Xml_TypeWithSpecialCharacterInStringMember() // loaded in the default ALC, which causes problems for this test. [SkipOnPlatform(TestPlatforms.Browser, "AssemblyDependencyResolver not supported in wasm")] #endif - [ActiveIssue("34072", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/96799", typeof(PlatformDetection), nameof(PlatformDetection.IsReadyToRunCompiled))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/34072", TestRuntimes.Mono)] public static void Xml_TypeInCollectibleALC() { ExecuteAndUnload("SerializableAssembly.dll", "SerializationTypes.SimpleType", out var weakRef); diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XslCompiledTransformApi/XsltSettings.cs b/src/libraries/System.Private.Xml/tests/Xslt/XslCompiledTransformApi/XsltSettings.cs index 17eec0aec40a7b..a14896236f8cd1 100644 --- a/src/libraries/System.Private.Xml/tests/Xslt/XslCompiledTransformApi/XsltSettings.cs +++ b/src/libraries/System.Private.Xml/tests/Xslt/XslCompiledTransformApi/XsltSettings.cs @@ -208,7 +208,9 @@ public void XsltSettings1_2(object param0, object param1, object param2, object _xsl.Load(_xslFile, xs, new XmlUrlResolver()); xs.EnableDocumentFunction = (bool)param5; +#pragma warning disable SYSLIB0062 // XsltSettings.EnableScript is obsolete xs.EnableScript = (bool)param6; +#pragma warning restore SYSLIB0062 _xsl.Load(_xslFile, xs, new XmlUrlResolver()); try diff --git a/src/libraries/System.Reflection.Context/Directory.Build.props b/src/libraries/System.Reflection.Context/Directory.Build.props index 798ccfd363e813..fc1d9fb498d24c 100644 --- a/src/libraries/System.Reflection.Context/Directory.Build.props +++ b/src/libraries/System.Reflection.Context/Directory.Build.props @@ -2,5 +2,6 @@ ECMA + false diff --git a/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj b/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj index bceb051a5fe15b..ab0a4b06a96bbb 100644 --- a/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj +++ b/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj @@ -2,7 +2,6 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.1;netstandard2.0 - false false true true diff --git a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Custom/CustomType.cs b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Custom/CustomType.cs index 95ee34ab4504b6..7edd10c45b0b48 100644 --- a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Custom/CustomType.cs +++ b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Custom/CustomType.cs @@ -11,8 +11,6 @@ namespace System.Reflection.Context.Custom { internal sealed class CustomType : ProjectingType { - private IEnumerable? _newProperties; - public CustomType(Type template, CustomReflectionContext context) : base(template, context.Projector) { @@ -282,6 +280,6 @@ public override MethodInfo[] GetMethods(BindingFlags bindingAttr) } } - private IEnumerable NewProperties => _newProperties ??= ReflectionContext.GetNewPropertiesForType(this); + private IEnumerable NewProperties => field ??= ReflectionContext.GetNewPropertiesForType(this); } } diff --git a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingType.cs b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingType.cs index bd7ef3ff90eaeb..379312698c3415 100644 --- a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingType.cs +++ b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingType.cs @@ -109,7 +109,7 @@ public override bool IsSecurityTransparent get { return _typeInfo.IsSecurityTransparent; } } -#if NET8_0_OR_GREATER +#if NET [Obsolete("Formatter-based serialization is obsolete and should not be used.", DiagnosticId = "SYSLIB0050", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public override bool IsSerializable diff --git a/src/libraries/System.Reflection.DispatchProxy/System.Reflection.DispatchProxy.slnx b/src/libraries/System.Reflection.DispatchProxy/System.Reflection.DispatchProxy.slnx index d6ed42fdf97de6..2ed97c462fdfb9 100644 --- a/src/libraries/System.Reflection.DispatchProxy/System.Reflection.DispatchProxy.slnx +++ b/src/libraries/System.Reflection.DispatchProxy/System.Reflection.DispatchProxy.slnx @@ -1,30 +1,498 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Reflection.DispatchProxy/src/System.Reflection.DispatchProxy.csproj b/src/libraries/System.Reflection.DispatchProxy/src/System.Reflection.DispatchProxy.csproj index 17c279ab521382..ec0746abe6f490 100644 --- a/src/libraries/System.Reflection.DispatchProxy/src/System.Reflection.DispatchProxy.csproj +++ b/src/libraries/System.Reflection.DispatchProxy/src/System.Reflection.DispatchProxy.csproj @@ -14,15 +14,15 @@ - - - - - - - - - + + + + + + + + + diff --git a/src/libraries/System.Reflection.Emit.ILGeneration/tests/CustomAttributeBuilderTests.cs b/src/libraries/System.Reflection.Emit.ILGeneration/tests/CustomAttributeBuilderTests.cs index cef38b3f9ac73d..a7fec8201c6dc8 100644 --- a/src/libraries/System.Reflection.Emit.ILGeneration/tests/CustomAttributeBuilderTests.cs +++ b/src/libraries/System.Reflection.Emit.ILGeneration/tests/CustomAttributeBuilderTests.cs @@ -886,7 +886,7 @@ public static void DynamicTypeInPropertyValues_ThrowsFileNotFoundExceptionOnCrea [InlineData(new string[] { nameof(TestAttribute.TestInt) }, new object[] { "TestString", 10 }, "namedFields, fieldValues")] [InlineData(new string[] { nameof(TestAttribute.TestInt), nameof(TestAttribute.TestStringField) }, new object[] { "TestString", 10 }, null)] [InlineData(new string[] { nameof(TestAttribute.TestStringField) }, new object[] { 10 }, null)] - public void NamedFieldAndFieldValuesDifferentLengths_ThrowsArgumentException(string[] fieldNames, object[] fieldValues, string paramName) + public void NamedFieldAndFieldValuesDifferentLengths_ThrowsArgumentException(string[] fieldNames, object[] fieldValues, string? paramName) { ConstructorInfo con = typeof(TestAttribute).GetConstructor(new Type[0]); FieldInfo[] namedFields = Helpers.GetFields(typeof(TestAttribute), fieldNames); @@ -1054,7 +1054,7 @@ public static void DynamicTypeInFieldValues_ThrowsFileNotFoundExceptionOnCreatio [InlineData(new string[] { nameof(TestAttribute.GetOnlyInt32) }, new object[] { "TestString" }, null)] [InlineData(new string[] { nameof(TestAttribute.GetOnlyString) }, new object[] { "TestString" }, null)] [InlineData(new string[] { nameof(TestAttribute.TestInt32) }, new object[] { "TestString" }, null)] - public void NamedPropertyAndPropertyValuesDifferentLengths_ThrowsArgumentException(string[] propertyNames, object[] propertyValues, string paramName) + public void NamedPropertyAndPropertyValuesDifferentLengths_ThrowsArgumentException(string[] propertyNames, object[] propertyValues, string? paramName) { ConstructorInfo con = typeof(TestAttribute).GetConstructor(new Type[0]); PropertyInfo[] namedProperties = Helpers.GetProperties(typeof(TestAttribute), propertyNames); diff --git a/src/libraries/System.Reflection.Emit.ILGeneration/tests/Label/LabelEquals.cs b/src/libraries/System.Reflection.Emit.ILGeneration/tests/Label/LabelEquals.cs index cb1579cf94ee77..0652a3720f26be 100644 --- a/src/libraries/System.Reflection.Emit.ILGeneration/tests/Label/LabelEquals.cs +++ b/src/libraries/System.Reflection.Emit.ILGeneration/tests/Label/LabelEquals.cs @@ -35,7 +35,7 @@ public void Equals_DifferentLabel_ReturnsFalse() [InlineData("label")] [InlineData(" ")] [InlineData(null)] - public void Equals_ObjectNotLabel_ReturnsFalse(object obj) + public void Equals_ObjectNotLabel_ReturnsFalse(object? obj) { Label label = new Label(); Assert.False(label.Equals(obj)); diff --git a/src/libraries/System.Reflection.Emit.ILGeneration/tests/SignatureHelper/SignatureHelperAddArgument.cs b/src/libraries/System.Reflection.Emit.ILGeneration/tests/SignatureHelper/SignatureHelperAddArgument.cs index d17e18c4130644..9fd85e63de64bd 100644 --- a/src/libraries/System.Reflection.Emit.ILGeneration/tests/SignatureHelper/SignatureHelperAddArgument.cs +++ b/src/libraries/System.Reflection.Emit.ILGeneration/tests/SignatureHelper/SignatureHelperAddArgument.cs @@ -36,7 +36,7 @@ public void AddArgument_Type_Bool(bool pinned, int expectedLength) [InlineData(new Type[] { typeof(int) }, null, 4)] [InlineData(null, new Type[] { typeof(Type) }, 4)] [InlineData(new Type[] { typeof(int) }, new Type[] { typeof(Type) }, 6)] - public void AddArgument_Type_TypeArray_TypeArray(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, int expectedLength) + public void AddArgument_Type_TypeArray_TypeArray(Type[]? requiredCustomModifiers, Type[]? optionalCustomModifiers, int expectedLength) { ModuleBuilder module = Helpers.DynamicModule(); SignatureHelper helper = SignatureHelper.GetFieldSigHelper(module); diff --git a/src/libraries/System.Reflection.Emit.Lightweight/tests/DynamicMethodCtor.cs b/src/libraries/System.Reflection.Emit.Lightweight/tests/DynamicMethodCtor.cs index 6844ffa0c8ee49..8dfd5b73751456 100644 --- a/src/libraries/System.Reflection.Emit.Lightweight/tests/DynamicMethodCtor.cs +++ b/src/libraries/System.Reflection.Emit.Lightweight/tests/DynamicMethodCtor.cs @@ -26,7 +26,7 @@ public class DynamicMethodctor1 [InlineData("method", typeof(string), new Type[] { typeof(char?) })] [InlineData("Method", typeof(string), new Type[] { typeof(GenericClass2<,>), typeof(GenericClass2<,>) })] [InlineData("Method", typeof(string), new Type[] { typeof(TestInterface) })] - public void String_Type_TypeArray_Module(string name, Type returnType, Type[] parameterTypes) + public void String_Type_TypeArray_Module(string name, Type? returnType, Type[]? parameterTypes) { Module module = typeof(TestClass).GetTypeInfo().Module; @@ -52,7 +52,7 @@ public void String_Type_TypeArray_Module(string name, Type returnType, Type[] pa [InlineData("Method", typeof(string), null, typeof(TestClass))] [InlineData("Method", typeof(string), new Type[] { typeof(int), typeof(string) }, typeof(TestClass))] [InlineData("", typeof(string), new Type[] { typeof(int), typeof(string) }, typeof(TestClass))] - public void String_Type_TypeArray_Type(string name, Type returnType, Type[] parameterTypes, Type owner) + public void String_Type_TypeArray_Type(string name, Type returnType, Type[]? parameterTypes, Type owner) { DynamicMethod method1 = new DynamicMethod(name, returnType, parameterTypes, owner); Helpers.VerifyMethod(method1, name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner.GetTypeInfo().Module); diff --git a/src/libraries/System.Reflection.Emit.Lightweight/tests/DynamicMethodToString.cs b/src/libraries/System.Reflection.Emit.Lightweight/tests/DynamicMethodToString.cs index e3592e9a0bbe62..8f5a0052df3c72 100644 --- a/src/libraries/System.Reflection.Emit.Lightweight/tests/DynamicMethodToString.cs +++ b/src/libraries/System.Reflection.Emit.Lightweight/tests/DynamicMethodToString.cs @@ -11,7 +11,7 @@ public class DynamicMethodToString [InlineData(typeof(string), new Type[] { typeof(string), typeof(int), typeof(TestClass) }, "System.String MethodName(System.String, Int32, System.Reflection.Emit.Tests.TestClass)")] [InlineData(typeof(string), new Type[] { typeof(GenericClass<>) }, "System.String MethodName(System.Reflection.Emit.Tests.GenericClass`1[T])")] [InlineData(null, null, "Void MethodName()")] - public void ToStringTest(Type returnType, Type[] parameterTypes, string expected) + public void ToStringTest(Type? returnType, Type[]? parameterTypes, string expected) { DynamicMethod method = new DynamicMethod("MethodName", returnType, parameterTypes, typeof(TestClass).GetTypeInfo().Module); Assert.Equal(expected, method.ToString()); diff --git a/src/libraries/System.Reflection.Emit/System.Reflection.Emit.slnx b/src/libraries/System.Reflection.Emit/System.Reflection.Emit.slnx index b640fc67602440..5a8c2c3121c113 100644 --- a/src/libraries/System.Reflection.Emit/System.Reflection.Emit.slnx +++ b/src/libraries/System.Reflection.Emit/System.Reflection.Emit.slnx @@ -52,6 +52,14 @@ + + + + + + + + @@ -76,6 +84,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -124,6 +180,14 @@ + + + + + + + + @@ -132,6 +196,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -149,6 +237,14 @@ + + + + + + + + @@ -157,6 +253,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -181,6 +333,22 @@ + + + + + + + + + + + + + + + + @@ -189,6 +357,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs index 9bb4d7613298a1..dd2219f54339b9 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs @@ -15,7 +15,6 @@ internal sealed class TypeBuilderImpl : TypeBuilder private readonly ModuleBuilderImpl _module; private readonly string _name; private readonly string? _namespace; - private string? _strFullName; [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] private Type? _typeParent; private readonly TypeBuilderImpl? _declaringType; @@ -600,7 +599,7 @@ public override Type GetGenericTypeDefinition() // You will never have to deal with a TypeBuilder if you are just referring to arrays. public override Type GetElementType() => throw new NotSupportedException(SR.NotSupported_DynamicModule); public override string? AssemblyQualifiedName => throw new NotSupportedException(); - public override string? FullName => _strFullName ??= TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName); + public override string? FullName => field ??= TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName); public override string? Namespace => _namespace; public override Assembly Assembly => _module.Assembly; public override Module Module => _module; diff --git a/src/libraries/System.Reflection.Emit/tests/GenericTypeParameterBuilder/GenericTyepParameterBuilderSetBaseTypeConstraint.cs b/src/libraries/System.Reflection.Emit/tests/GenericTypeParameterBuilder/GenericTyepParameterBuilderSetBaseTypeConstraint.cs index b29c41c681c475..6d104f75a082da 100644 --- a/src/libraries/System.Reflection.Emit/tests/GenericTypeParameterBuilder/GenericTyepParameterBuilderSetBaseTypeConstraint.cs +++ b/src/libraries/System.Reflection.Emit/tests/GenericTypeParameterBuilder/GenericTyepParameterBuilderSetBaseTypeConstraint.cs @@ -10,7 +10,7 @@ public class GenericTypeParameterBuilderSetBaseTypeConstraint [Theory] [InlineData(typeof(string), typeof(string))] [InlineData(null, typeof(object))] - public void SetBaseTypeConstraint(Type baseTypeConstraint, Type expectedBaseType) + public void SetBaseTypeConstraint(Type? baseTypeConstraint, Type expectedBaseType) { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Public); string[] typeParamNames = new string[] { "TFirst" }; diff --git a/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineEnum.cs b/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineEnum.cs index 4e1f762cae074d..942420c973583e 100644 --- a/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineEnum.cs +++ b/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineEnum.cs @@ -178,7 +178,7 @@ public void DefineEnum_EmptyName_ThrowsArgumentNullException(string name) [InlineData(TypeAttributes.NestedFamORAssem, null)] [InlineData(TypeAttributes.NestedPrivate, null)] [InlineData(TypeAttributes.NestedPublic, null)] - public void DefineEnum_IncorrectVisibilityAttributes_ThrowsArgumentException(TypeAttributes visibility, string paramName) + public void DefineEnum_IncorrectVisibilityAttributes_ThrowsArgumentException(TypeAttributes visibility, string? paramName) { ModuleBuilder module = Helpers.DynamicModule(); AssertExtensions.Throws(paramName, () => module.DefineEnum("Enum", visibility, typeof(int))); diff --git a/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderDefineEvent.cs b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderDefineEvent.cs index 05cda03a777379..0751512da510aa 100644 --- a/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderDefineEvent.cs +++ b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderDefineEvent.cs @@ -97,7 +97,7 @@ public void DefineEvent_TypeCreated_ThrowsInvalidOperationException() [InlineData("TestEvent", null, typeof(ArgumentNullException))] [InlineData("", typeof(int), typeof(ArgumentException))] [InlineData("\0TestEvent", typeof(int), typeof(ArgumentException))] - public void DefineEvent_Invalid(string name, Type eventType, Type exceptionType) + public void DefineEvent_Invalid(string? name, Type? eventType, Type exceptionType) { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public); type.DefineGenericParameters("T"); diff --git a/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderDefineNestedType.cs b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderDefineNestedType.cs index 188d273a558389..0cb627ca6b7f44 100644 --- a/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderDefineNestedType.cs +++ b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderDefineNestedType.cs @@ -160,7 +160,7 @@ public void DefineNestedType_LongName_ThrowsArgumentException() [InlineData((TypeAttributes)0x00040800, "attr")] [InlineData((TypeAttributes)(-1), null)] [InlineData((TypeAttributes)(-5000), "attr")] - public void DefineNestedType_InvalidAttributes_ThrowsArgumentException(TypeAttributes attributes, string paramName) + public void DefineNestedType_InvalidAttributes_ThrowsArgumentException(TypeAttributes attributes, string? paramName) { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Public); AssertExtensions.Throws(paramName, () => type.DefineNestedType("Name", attributes)); diff --git a/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderInstantiationErrorMessageTests.cs b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderInstantiationErrorMessageTests.cs new file mode 100644 index 00000000000000..0b910fcf3412ec --- /dev/null +++ b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderInstantiationErrorMessageTests.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Reflection.Emit.Tests +{ + public class TypeBuilderInstantiationErrorMessageTests + { + [Fact] + public void TypeBuilderInstantiation_ThrowsWithHelpfulMessage() + { + TypeBuilder type = Helpers.DynamicType(TypeAttributes.Public); + + type.DefineGenericParameters("T"); + + Type instantiatedType = type.MakeGenericType(typeof(string)); + + AssertThrowsWithHelpfulMessage(nameof(TypeBuilder.GetConstructor), () => instantiatedType.GetConstructor(Type.EmptyTypes)); + AssertThrowsWithHelpfulMessage(nameof(TypeBuilder.GetConstructor), () => instantiatedType.GetConstructors()); + AssertThrowsWithHelpfulMessage(nameof(TypeBuilder.GetMethod), () => instantiatedType.GetMethod("Test")); + AssertThrowsWithHelpfulMessage(nameof(TypeBuilder.GetMethod), () => instantiatedType.GetMethods()); + AssertThrowsWithHelpfulMessage(nameof(TypeBuilder.GetField), () => instantiatedType.GetField("_test")); + AssertThrowsWithHelpfulMessage(nameof(TypeBuilder.GetField), () => instantiatedType.GetFields()); + + static void AssertThrowsWithHelpfulMessage(string suggestedAlternative, TestDelegate code) + { + NotSupportedException ex = Assert.Throws(code); + Assert.Contains($"TypeBuilder.{suggestedAlternative}", ex.Message); + } + } +} \ No newline at end of file diff --git a/src/libraries/System.Reflection.Metadata/System.Reflection.Metadata.slnx b/src/libraries/System.Reflection.Metadata/System.Reflection.Metadata.slnx index 5def1af5edc193..80d6cea7e7e23d 100644 --- a/src/libraries/System.Reflection.Metadata/System.Reflection.Metadata.slnx +++ b/src/libraries/System.Reflection.Metadata/System.Reflection.Metadata.slnx @@ -92,6 +92,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -100,6 +140,22 @@ + + + + + + + + + + + + + + + + @@ -116,6 +172,22 @@ + + + + + + + + + + + + + + + + @@ -181,6 +253,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -189,6 +301,22 @@ + + + + + + + + + + + + + + + + @@ -205,6 +333,22 @@ + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.Manual.cs b/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.Manual.cs index 17093fb7e92161..e3c07e81e46b39 100644 --- a/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.Manual.cs +++ b/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.Manual.cs @@ -16,7 +16,7 @@ public readonly partial struct AssemblyReference } public partial class ImageFormatLimitationException : System.Exception { -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj b/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj index 5d7553f707ba53..18206a3e46f984 100644 --- a/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj +++ b/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj @@ -123,7 +123,7 @@ The System.Reflection.Metadata library is built-in as part of the shared framewo - + @@ -261,24 +261,19 @@ The System.Reflection.Metadata library is built-in as part of the shared framewo - + - - - - - - - - - - - - - + + + + + + + + diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/AssemblyNameInfo.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/AssemblyNameInfo.cs index 23edc3dde0048e..fc6047f562df02 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/AssemblyNameInfo.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/AssemblyNameInfo.cs @@ -60,7 +60,7 @@ internal AssemblyNameInfo(AssemblyNameParser.AssemblyNameParts parts) #else PublicKeyOrToken = parts._publicKeyOrToken is null ? default : parts._publicKeyOrToken.Length == 0 ? ImmutableArray.Empty - #if NET8_0_OR_GREATER + #if NET : Runtime.InteropServices.ImmutableCollectionsMarshal.AsImmutableArray(parts._publicKeyOrToken); #else : ImmutableArray.Create(parts._publicKeyOrToken); @@ -134,7 +134,7 @@ internal void AppendFullName(ref ValueStringBuilder vsb) byte[]? publicKeyOrToken = #if SYSTEM_PRIVATE_CORELIB PublicKeyOrToken; -#elif NET8_0_OR_GREATER +#elif NET !PublicKeyOrToken.IsDefault ? Runtime.InteropServices.ImmutableCollectionsMarshal.AsArray(PublicKeyOrToken) : null; #else !PublicKeyOrToken.IsDefault ? PublicKeyOrToken.ToArray() : null; @@ -203,7 +203,7 @@ public AssemblyName ToAssemblyName() /// Provided assembly name was invalid. public static AssemblyNameInfo Parse(ReadOnlySpan assemblyName) => TryParse(assemblyName, out AssemblyNameInfo? result) - ? result! + ? result : throw new ArgumentException(SR.InvalidAssemblyName, nameof(assemblyName)); /// diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/Encoding/BlobEncoders.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/Encoding/BlobEncoders.cs index 3ed78ab777a1bc..aeb6eae3bfb0df 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/Encoding/BlobEncoders.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/Encoding/BlobEncoders.cs @@ -424,6 +424,10 @@ public FieldTypeEncoder(BlobBuilder builder) Builder = builder; } + /// + /// Creates object that can be used to encode custom modifiers. + /// + /// A instance that can be used to encode custom modifiers. public CustomModifiersEncoder CustomModifiers() { return new CustomModifiersEncoder(Builder); diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/ImageFormatLimitationException.Serialization.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/ImageFormatLimitationException.Serialization.cs index ed6b2ab3e8eab8..10fc4899ac6f27 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/ImageFormatLimitationException.Serialization.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/ImageFormatLimitationException.Serialization.cs @@ -10,7 +10,7 @@ namespace System.Reflection.Metadata [Serializable] public partial class ImageFormatLimitationException : Exception { -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Internal/NamespaceCache.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Internal/NamespaceCache.cs index 6eddeadf9a5177..dbb85c1b56c6b7 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Internal/NamespaceCache.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Internal/NamespaceCache.cs @@ -207,7 +207,7 @@ private NamespaceDataBuilder SynthesizeNamespaceData(string fullName, NamespaceD { Debug.Assert(realChild.HasFullName); -#if NET8_0_OR_GREATER +#if NET int numberOfSegments = fullName.AsSpan().Count('.'); #else int numberOfSegments = 0; diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeName.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeName.cs index 5bae2f20dd557a..2e90ec5bb80548 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeName.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeName.cs @@ -194,7 +194,7 @@ public string FullName private void AppendFullName(ref ValueStringBuilder builder) { // This is a recursive method over potentially hostile input. Protection against DoS is offered - // via the [Try]Parse method and TypeNameParserOptions.MaxNodes property at construction time. + // via the [Try]Parse method and TypeNameParseOptions.MaxNodes property at construction time. // This FullName property getter and related methods assume that this TypeName instance has an // acceptable node count. // diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserOptions.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParseOptions.cs similarity index 98% rename from src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserOptions.cs rename to src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParseOptions.cs index 53d6f7f164275a..a15da53a5109da 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserOptions.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParseOptions.cs @@ -22,7 +22,7 @@ public int MaxNodes get => _maxNodes; set { -#if NET8_0_OR_GREATER +#if NET ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(value, 0, nameof(value)); #else if (value <= 0) diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserHelpers.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserHelpers.cs index 7428d05a39e22e..6772d490257486 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserHelpers.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserHelpers.cs @@ -15,7 +15,7 @@ internal static class TypeNameParserHelpers internal const int Pointer = -2; internal const int ByRef = -3; private const char EscapeCharacter = '\\'; -#if NET8_0_OR_GREATER +#if NET // Keep this in sync with GetFullTypeNameLength/NeedsEscaping private static readonly SearchValues s_endOfFullTypeNameDelimitersSearchValues = SearchValues.Create("[]&*,+\\"); #endif @@ -36,7 +36,7 @@ internal static int GetFullTypeNameLength(ReadOnlySpan input, out bool isN // input, that makes the total loop complexity potentially O(m * n^2), where // 'n' is adversary-controlled. To avoid DoS issues here, we'll loop manually. -#if NET8_0_OR_GREATER +#if NET int offset = input.IndexOfAny(s_endOfFullTypeNameDelimitersSearchValues); if (offset < 0) { diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserHelpersTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserHelpersTests.cs index bab040273028f1..eec36ea51ec4bd 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserHelpersTests.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserHelpersTests.cs @@ -102,7 +102,7 @@ public void IsBeginningOfGenericAgsHandlesAllCasesProperly(string input, bool ex [InlineData("A+B`1+C1`2+DD2`3+E", true, new int[] { 1, 3, 4, 5 }, 18)] [InlineData("Integer`2147483646+NoOverflow`1", true, new int[] { 18 }, 31)] [InlineData("Integer`2147483647+Overflow`1", true, new int[] { 18 }, 29)] - public void TryGetTypeNameInfoGetsAllTheInfo(string input, bool expectedResult, int[] expectedNestedNameLengths, int expectedTotalLength) + public void TryGetTypeNameInfoGetsAllTheInfo(string input, bool expectedResult, int[]? expectedNestedNameLengths, int expectedTotalLength) { List? nestedNameLengths = null; ReadOnlySpan span = input.AsSpan(); diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameTests.cs index abd0ec87059f7d..23e999955b3e49 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameTests.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameTests.cs @@ -942,7 +942,7 @@ static void Verify(Type type, TypeName typeName, bool ignoreCase) } } -#if NET8_0_OR_GREATER +#if NET [RequiresUnreferencedCode("The type might be removed")] [RequiresDynamicCode("Required by MakeArrayType")] #else diff --git a/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj b/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj index 18d037049bdc1e..023a04c4674856 100644 --- a/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj +++ b/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj @@ -3,7 +3,6 @@ $(NetCoreAppCurrent);$(NetFrameworkCurrent) true - false $(NoWarn);436;SYSLIB0037 diff --git a/src/libraries/System.Reflection.MetadataLoadContext/Directory.Build.props b/src/libraries/System.Reflection.MetadataLoadContext/Directory.Build.props new file mode 100644 index 00000000000000..760f934398477e --- /dev/null +++ b/src/libraries/System.Reflection.MetadataLoadContext/Directory.Build.props @@ -0,0 +1,6 @@ + + + + false + + diff --git a/src/libraries/System.Reflection.MetadataLoadContext/System.Reflection.MetadataLoadContext.slnx b/src/libraries/System.Reflection.MetadataLoadContext/System.Reflection.MetadataLoadContext.slnx index 8a8acb6ee5fca2..c62b8a444a6e90 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/System.Reflection.MetadataLoadContext.slnx +++ b/src/libraries/System.Reflection.MetadataLoadContext/System.Reflection.MetadataLoadContext.slnx @@ -1,37 +1,426 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj b/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj index 524c33fc8d2ac7..c155c10874a6f2 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj @@ -4,7 +4,6 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) System.Reflection true - false false true $(NoWarn);CA1865 diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs index 8e85330e19d26f..f67400930ece39 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs @@ -38,8 +38,7 @@ protected RoAssembly(MetadataLoadContext loader, int assemblyFileCount) protected abstract AssemblyNameData ComputeNameData(); private volatile AssemblyNameData? _lazyAssemblyNameData; - public sealed override string FullName => _lazyFullName ??= GetName().FullName; - private volatile string? _lazyFullName; + public sealed override string FullName => field ??= GetName().FullName; internal const string ThrowingMessageInRAF = "This member throws an exception for assemblies embedded in a single-file app"; @@ -195,7 +194,7 @@ public sealed override AssemblyName[] GetReferencedAssemblies() } // Serialization -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Constructors/RoConstructor.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Constructors/RoConstructor.cs index 22459dee2c3192..4054f3bab551d8 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Constructors/RoConstructor.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Constructors/RoConstructor.cs @@ -21,9 +21,8 @@ protected RoConstructor() { } public sealed override Type ReflectedType => DeclaringType; - public sealed override string Name => _lazyName ??= ComputeName(); + public sealed override string Name => field ??= ComputeName(); protected abstract string ComputeName(); - private volatile string? _lazyName; public sealed override Module Module => GetRoModule(); internal abstract RoModule GetRoModule(); @@ -65,9 +64,8 @@ protected RoConstructor() { } public sealed override ParameterInfo[] GetParameters() => GetParametersNoCopy().CloneArray(); internal RoParameter[] GetParametersNoCopy() => MethodSig.Parameters; - private MethodSig MethodSig => _lazyMethodSig ??= ComputeMethodSig(); + private MethodSig MethodSig => field ??= ComputeMethodSig(); protected abstract MethodSig ComputeMethodSig(); - private volatile MethodSig? _lazyMethodSig; public sealed override string ToString() => Loader.GetDisposedString() ?? this.ToString(ComputeMethodSigStrings()); protected abstract MethodSig ComputeMethodSigStrings(); diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/CustomAttributes/RoCustomAttributeData.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/CustomAttributes/RoCustomAttributeData.cs index 0921581bc4ccb6..2db22bd8cb26f8 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/CustomAttributes/RoCustomAttributeData.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/CustomAttributes/RoCustomAttributeData.cs @@ -12,13 +12,11 @@ internal abstract partial class RoCustomAttributeData : LeveledCustomAttributeDa { protected RoCustomAttributeData() { } - public sealed override Type AttributeType => _lazyAttributeType ??= ComputeAttributeType()!; + public sealed override Type AttributeType => field ??= ComputeAttributeType()!; protected abstract Type? ComputeAttributeType(); - private volatile Type? _lazyAttributeType; - public sealed override ConstructorInfo Constructor => _lazyConstructorInfo ??= ComputeConstructor(); + public sealed override ConstructorInfo Constructor => field ??= ComputeConstructor(); protected abstract ConstructorInfo ComputeConstructor(); - private volatile ConstructorInfo? _lazyConstructorInfo; public abstract override IList ConstructorArguments { get; } public abstract override IList NamedArguments { get; } diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Events/RoEvent.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Events/RoEvent.cs index 9fd2eaeac53393..30661e288c8654 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Events/RoEvent.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Events/RoEvent.cs @@ -32,9 +32,8 @@ protected RoEvent(RoInstantiationProviderType declaringType, Type reflectedType) public sealed override Type ReflectedType => _reflectedType; - public sealed override string Name => _lazyName ??= ComputeName(); + public sealed override string Name => field ??= ComputeName(); protected abstract string ComputeName(); - private volatile string? _lazyName; public sealed override Module Module => GetRoModule(); internal abstract RoModule GetRoModule(); @@ -50,9 +49,8 @@ protected RoEvent(RoInstantiationProviderType declaringType, Type reflectedType) private const EventAttributes EventAttributesSentinel = (EventAttributes)(-1); private volatile EventAttributes _lazyEventAttributes = EventAttributesSentinel; - public sealed override Type EventHandlerType => _lazyEventType ??= ComputeEventHandlerType(); + public sealed override Type EventHandlerType => field ??= ComputeEventHandlerType(); protected abstract Type ComputeEventHandlerType(); - private volatile Type? _lazyEventType; private RoMethod? GetRoAddMethod() => (_lazyAdder == Sentinels.RoMethod) ? (_lazyAdder = ComputeEventAddMethod()?.FilterInheritedAccessor()) : _lazyAdder; private RoMethod? GetRoRemoveMethod() => (_lazyRemover == Sentinels.RoMethod) ? (_lazyRemover = ComputeEventRemoveMethod()?.FilterInheritedAccessor()) : _lazyRemover; diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Fields/RoField.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Fields/RoField.cs index 0162946f31cf80..76a11c658bf837 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Fields/RoField.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Fields/RoField.cs @@ -34,9 +34,8 @@ protected RoField(RoInstantiationProviderType declaringType, Type reflectedType) public sealed override Type ReflectedType => _reflectedType; - public sealed override string Name => _lazyName ??= ComputeName(); + public sealed override string Name => field ??= ComputeName(); protected abstract string ComputeName(); - private volatile string? _lazyName; public sealed override Module Module => GetRoModule(); internal abstract RoModule GetRoModule(); diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/General/Helpers.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/General/Helpers.cs index 60263a0c6516f6..638a47e9bae1a6 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/General/Helpers.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/General/Helpers.cs @@ -12,7 +12,7 @@ namespace System.Reflection.TypeLoading { internal static class Helpers { -#if NET8_0_OR_GREATER +#if NET private static readonly SearchValues s_charsToEscape = SearchValues.Create("\\[]+*&,"); #else private static ReadOnlySpan s_charsToEscape => "\\[]+*&,".AsSpan(); @@ -125,7 +125,7 @@ public static bool TypeNameContainsTypeParserMetacharacters(this string identifi public static bool NeedsEscapingInTypeName(this char c) { -#if NET8_0_OR_GREATER +#if NET return s_charsToEscape.Contains(c); #else return s_charsToEscape.IndexOf(c) >= 0; diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Methods/RoMethod.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Methods/RoMethod.cs index 0ef99f8ec934ce..374b4c3048898f 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Methods/RoMethod.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Methods/RoMethod.cs @@ -29,9 +29,8 @@ protected RoMethod(Type reflectedType) public sealed override Type ReflectedType => _reflectedType; - public sealed override string Name => _lazyName ??= ComputeName(); + public sealed override string Name => field ??= ComputeName(); protected abstract string ComputeName(); - private volatile string? _lazyName; public sealed override Module Module => GetRoModule(); internal abstract RoModule GetRoModule(); @@ -90,9 +89,8 @@ public sealed override bool ContainsGenericParameters public sealed override ParameterInfo ReturnParameter => MethodSig.Return; internal RoParameter[] GetParametersNoCopy() => MethodSig.Parameters; - private MethodSig MethodSig => _lazyMethodSig ??= ComputeMethodSig(); + private MethodSig MethodSig => field ??= ComputeMethodSig(); protected abstract MethodSig ComputeMethodSig(); - private volatile MethodSig? _lazyMethodSig; public sealed override ICustomAttributeProvider ReturnTypeCustomAttributes => ReturnParameter; public sealed override Type ReturnType => ReturnParameter.ParameterType; diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/Ecma/EcmaModule.MetadataTables.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/Ecma/EcmaModule.MetadataTables.cs index 6463a72aabcc3a..fbc14ab264876c 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/Ecma/EcmaModule.MetadataTables.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/Ecma/EcmaModule.MetadataTables.cs @@ -36,38 +36,20 @@ private void EnsureTypeDefTableFullyFilled() } private bool _typeDefTableFullyFilled; // Only gets set true if EnsureTypeDefTableFullyFilled() fills the table. False negative just means some unnecessary work is done. - internal MetadataTable TypeRefTable - { - get - { - return _lazyTypeRefTable ?? - Interlocked.CompareExchange(ref _lazyTypeRefTable, CreateTable(TableIndex.TypeRef), null) ?? - _lazyTypeRefTable; - } - } - private volatile MetadataTable? _lazyTypeRefTable; + internal MetadataTable TypeRefTable => + field ?? + Interlocked.CompareExchange(ref field, CreateTable(TableIndex.TypeRef), null) ?? + field; - internal MetadataTable GenericParamTable - { - get - { - return _lazyGenericParamTable ?? - Interlocked.CompareExchange(ref _lazyGenericParamTable, CreateTable(TableIndex.GenericParam), null) ?? - _lazyGenericParamTable; - } - } - private volatile MetadataTable? _lazyGenericParamTable; + internal MetadataTable GenericParamTable => + field ?? + Interlocked.CompareExchange(ref field, CreateTable(TableIndex.GenericParam), null) ?? + field; - internal MetadataTable AssemblyRefTable - { - get - { - return _lazyAssemblyRefTable ?? - Interlocked.CompareExchange(ref _lazyAssemblyRefTable, CreateTable(TableIndex.AssemblyRef), null) ?? - _lazyAssemblyRefTable; - } - } - private volatile MetadataTable? _lazyAssemblyRefTable; + internal MetadataTable AssemblyRefTable => + field ?? + Interlocked.CompareExchange(ref field, CreateTable(TableIndex.AssemblyRef), null) ?? + field; private MetadataTable CreateTable(TableIndex tableIndex) where T : class { diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/RoModule.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/RoModule.cs index f236b209b3d25f..7a2982e7cb0733 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/RoModule.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/RoModule.cs @@ -72,7 +72,7 @@ public sealed override string Name public abstract override MethodInfo[] GetMethods(BindingFlags bindingFlags); protected abstract override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers); -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Parameters/RoFatMethodParameter.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Parameters/RoFatMethodParameter.cs index 35a341e2e7e6c1..71c718a2ab0176 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Parameters/RoFatMethodParameter.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Parameters/RoFatMethodParameter.cs @@ -19,9 +19,8 @@ protected RoFatMethodParameter(IRoMethodBase roMethodBase, int position, Type pa Debug.Assert(parameterType != null); } - public sealed override string? Name => _lazyName ??= ComputeName(); + public sealed override string? Name => field ??= ComputeName(); protected abstract string? ComputeName(); - private volatile string? _lazyName; public sealed override ParameterAttributes Attributes => (_lazyParameterAttributes == ParameterAttributesSentinel) ? (_lazyParameterAttributes = ComputeAttributes()) : _lazyParameterAttributes; protected abstract ParameterAttributes ComputeAttributes(); diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Properties/RoProperty.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Properties/RoProperty.cs index 68bbe696edadec..e4a0cafd49f409 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Properties/RoProperty.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Properties/RoProperty.cs @@ -33,9 +33,8 @@ protected RoProperty(RoInstantiationProviderType declaringType, Type reflectedTy public sealed override Type ReflectedType => _reflectedType; - public sealed override string Name => _lazyName ??= ComputeName(); + public sealed override string Name => field ??= ComputeName(); protected abstract string ComputeName(); - private volatile string? _lazyName; public sealed override Module Module => GetRoModule(); internal abstract RoModule GetRoModule(); diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/RuntimeTypeInfo.BindingFlags.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/RuntimeTypeInfo.BindingFlags.cs index 2bccecb7930715..c126af79b3a27c 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/RuntimeTypeInfo.BindingFlags.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/RuntimeTypeInfo.BindingFlags.cs @@ -204,9 +204,7 @@ private static bool NeedToSearchImmediateTypeOnly(BindingFlags bf) return true; } - private TypeComponentsCache Cache => _lazyCache ??= new TypeComponentsCache(this); - - private volatile TypeComponentsCache? _lazyCache; + private TypeComponentsCache Cache => field ??= new TypeComponentsCache(this); private const int GenericParameterCountAny = -1; } diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs index 1a5369f2f638d1..ed305fc921a093 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs @@ -105,21 +105,18 @@ public override Type[] GetFunctionPointerCallingConventions() protected internal abstract RoType[] GetGenericArgumentsNoCopy(); // Naming - public sealed override string Name => _lazyName ??= ComputeName(); + public sealed override string Name => field ??= ComputeName(); protected abstract string ComputeName(); internal string Call_ComputeName() => ComputeName(); - private volatile string? _lazyName; - public sealed override string? Namespace => _lazyNamespace ??= ComputeNamespace(); + public sealed override string? Namespace => field ??= ComputeNamespace(); protected abstract string? ComputeNamespace(); internal string? Call_ComputeNamespace() => ComputeNamespace(); - private volatile string? _lazyNamespace; - public sealed override string? FullName => _lazyFullName ??= ComputeFullName(); + public sealed override string? FullName => field ??= ComputeFullName(); protected abstract string? ComputeFullName(); internal string? Call_ComputeFullName() => ComputeFullName(); - private volatile string? _lazyFullName; - public override string? AssemblyQualifiedName => _lazyAssemblyQualifiedFullName ??= ComputeAssemblyQualifiedName(); + public override string? AssemblyQualifiedName => field ??= ComputeAssemblyQualifiedName(); private string? ComputeAssemblyQualifiedName() { string? fullName = FullName; @@ -128,7 +125,6 @@ public override Type[] GetFunctionPointerCallingConventions() string? assemblyName = Assembly.FullName; return fullName + ", " + assemblyName; } - private volatile string? _lazyAssemblyQualifiedFullName; // Assembly and module public sealed override Assembly Assembly => Module.Assembly; diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.JittedRuntimes.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.JittedRuntimes.cs index d483dd47c3c511..a92eb322b851df 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.JittedRuntimes.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/TestUtils.JittedRuntimes.cs @@ -16,7 +16,7 @@ public static Type Project(this Type type) if (type == null) return null; -#if NET8_0_OR_GREATER +#if NET // Function pointers don't support Type.GetType() so they can't be dynamically created. if (type.IsFunctionPointer) throw new NotSupportedException("Function pointers don't support Project()"); diff --git a/src/libraries/System.Resources.Extensions/Directory.Build.props b/src/libraries/System.Resources.Extensions/Directory.Build.props new file mode 100644 index 00000000000000..760f934398477e --- /dev/null +++ b/src/libraries/System.Resources.Extensions/Directory.Build.props @@ -0,0 +1,6 @@ + + + + false + + diff --git a/src/libraries/System.Resources.Extensions/System.Resources.Extensions.slnx b/src/libraries/System.Resources.Extensions/System.Resources.Extensions.slnx index 64917d06f2d487..709a278c88b423 100644 --- a/src/libraries/System.Resources.Extensions/System.Resources.Extensions.slnx +++ b/src/libraries/System.Resources.Extensions/System.Resources.Extensions.slnx @@ -100,6 +100,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -116,6 +156,22 @@ + + + + + + + + + + + + + + + + @@ -132,6 +188,22 @@ + + + + + + + + + + + + + + + + @@ -165,7 +237,7 @@ - + @@ -173,7 +245,7 @@ - + @@ -181,7 +253,7 @@ - + @@ -189,7 +261,7 @@ - + @@ -197,7 +269,7 @@ - + @@ -205,7 +277,7 @@ - + @@ -213,7 +285,39 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -237,6 +341,22 @@ + + + + + + + + + + + + + + + + @@ -253,6 +373,22 @@ + + + + + + + + + + + + + + + + @@ -278,6 +414,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.Resources.Extensions/src/System.Resources.Extensions.csproj b/src/libraries/System.Resources.Extensions/src/System.Resources.Extensions.csproj index 64a8ff083423f4..4dbcfda830cfab 100644 --- a/src/libraries/System.Resources.Extensions/src/System.Resources.Extensions.csproj +++ b/src/libraries/System.Resources.Extensions/src/System.Resources.Extensions.csproj @@ -4,7 +4,6 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true $(DefineConstants);RESOURCES_EXTENSIONS - false true false true @@ -81,6 +80,8 @@ System.Resources.Extensions.PreserializedResourceWriter Link="System\Diagnostics\CodeAnalysis\DynamicallyAccessedMemberTypes.cs" /> + diff --git a/src/libraries/System.Resources.Extensions/src/System/Resources/Extensions/BinaryFormat/BinaryFormattedObject.cs b/src/libraries/System.Resources.Extensions/src/System/Resources/Extensions/BinaryFormat/BinaryFormattedObject.cs index 56b18143815201..8d4f9ecdaa1916 100644 --- a/src/libraries/System.Resources.Extensions/src/System/Resources/Extensions/BinaryFormat/BinaryFormattedObject.cs +++ b/src/libraries/System.Resources.Extensions/src/System/Resources/Extensions/BinaryFormat/BinaryFormattedObject.cs @@ -33,8 +33,7 @@ internal sealed partial class BinaryFormattedObject }; private readonly Options _options; - private ITypeResolver? _typeResolver; - private ITypeResolver TypeResolver => _typeResolver ??= new DefaultTypeResolver(_options); + private ITypeResolver TypeResolver => field ??= new DefaultTypeResolver(_options); /// /// Creates by parsing . diff --git a/src/libraries/System.Resources.Extensions/tests/BinaryFormatTests/System.Resources.Extensions.BinaryFormat.Tests.csproj b/src/libraries/System.Resources.Extensions/tests/BinaryFormatTests/System.Resources.Extensions.BinaryFormat.Tests.csproj index c77f6e932d59a7..878fc8c4bf0371 100644 --- a/src/libraries/System.Resources.Extensions/tests/BinaryFormatTests/System.Resources.Extensions.BinaryFormat.Tests.csproj +++ b/src/libraries/System.Resources.Extensions/tests/BinaryFormatTests/System.Resources.Extensions.BinaryFormat.Tests.csproj @@ -18,6 +18,7 @@ + diff --git a/src/libraries/System.Resources.Writer/System.Resources.Writer.slnx b/src/libraries/System.Resources.Writer/System.Resources.Writer.slnx index fd96f4b93abea5..cc39b89226b061 100644 --- a/src/libraries/System.Resources.Writer/System.Resources.Writer.slnx +++ b/src/libraries/System.Resources.Writer/System.Resources.Writer.slnx @@ -1,29 +1,202 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Resources.Writer/src/System.Resources.Writer.csproj b/src/libraries/System.Resources.Writer/src/System.Resources.Writer.csproj index b2e3aeb636444c..32adc521f30791 100644 --- a/src/libraries/System.Resources.Writer/src/System.Resources.Writer.csproj +++ b/src/libraries/System.Resources.Writer/src/System.Resources.Writer.csproj @@ -19,9 +19,9 @@ - - - + + + diff --git a/src/libraries/System.Runtime.Caching/System.Runtime.Caching.slnx b/src/libraries/System.Runtime.Caching/System.Runtime.Caching.slnx index 4af3ab6e6239c5..c41fb61d63160a 100644 --- a/src/libraries/System.Runtime.Caching/System.Runtime.Caching.slnx +++ b/src/libraries/System.Runtime.Caching/System.Runtime.Caching.slnx @@ -18,6 +18,14 @@ + + + + + + + + @@ -44,6 +52,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -60,6 +100,22 @@ + + + + + + + + + + + + + + + + @@ -68,6 +124,14 @@ + + + + + + + + @@ -76,6 +140,22 @@ + + + + + + + + + + + + + + + + @@ -92,6 +172,14 @@ + + + + + + + + @@ -100,6 +188,22 @@ + + + + + + + + + + + + + + + + @@ -125,7 +229,31 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -157,6 +285,22 @@ + + + + + + + + + + + + + + + + @@ -165,6 +309,14 @@ + + + + + + + + @@ -173,6 +325,22 @@ + + + + + + + + + + + + + + + + @@ -189,6 +357,14 @@ + + + + + + + + @@ -197,6 +373,22 @@ + + + + + + + + + + + + + + + + @@ -214,6 +406,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/CacheItemPolicy.cs b/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/CacheItemPolicy.cs index 79e06d1243a5d2..179ebda6776e20 100644 --- a/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/CacheItemPolicy.cs +++ b/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/CacheItemPolicy.cs @@ -10,7 +10,6 @@ public class CacheItemPolicy { private DateTimeOffset _absExpiry; private TimeSpan _sldExpiry; - private Collection _changeMonitors; private CacheItemPriority _priority; private CacheEntryRemovedCallback _removedCallback; private CacheEntryUpdateCallback _updateCallback; @@ -21,7 +20,7 @@ public DateTimeOffset AbsoluteExpiration set { _absExpiry = value; } } - public Collection ChangeMonitors => _changeMonitors ??= new Collection(); + public Collection ChangeMonitors => field ??= new Collection(); public CacheItemPriority Priority { diff --git a/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching/HostFileChangeMonitorTest.cs b/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching/HostFileChangeMonitorTest.cs index c9d83355d6c1a6..a0bfb47b53c40e 100644 --- a/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching/HostFileChangeMonitorTest.cs +++ b/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching/HostFileChangeMonitorTest.cs @@ -30,14 +30,16 @@ using System; using System.Collections.Generic; +using System.Collections.Specialized; using System.IO; using System.Reflection; using System.Runtime.Caching; using System.Runtime.Caching.Hosting; using System.Text; - -using Xunit; +using System.Threading; +using System.Threading.Tasks; using MonoTests.Common; +using Xunit; namespace MonoTests.System.Runtime.Caching { @@ -84,7 +86,6 @@ public void Constructor_Exceptions() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/34497", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] public static void Constructor_MissingFiles_Handler() { HostFileChangeMonitor monitor; @@ -132,7 +133,6 @@ public static void Constructor_MissingFiles_Handler() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/34497", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] public void Constructor_Duplicates() { HostFileChangeMonitor monitor; @@ -148,9 +148,9 @@ public void Constructor_Duplicates() monitor.Dispose(); } - private static Tuple> SetupMonitoring() + private static Tuple> SetupMonitoring(string uniqueId) { - string testPath = Path.Combine(Path.GetTempPath(), "HostFileChangeMonitorTest", "Dispose_Calls_StopMonitoring"); + string testPath = Path.Combine(Path.GetTempPath(), "HostFileChangeMonitorTest", uniqueId); if (!Directory.Exists(testPath)) Directory.CreateDirectory(testPath); @@ -201,13 +201,12 @@ private static void CleanupMonitoring(Tuple> setup = null; try { - setup = SetupMonitoring(); + setup = SetupMonitoring(nameof(UniqueId)); FileInfo fi; var monitor = new HostFileChangeMonitor(setup.Item4); var sb = new StringBuilder(); @@ -247,5 +246,47 @@ public void UniqueId() CleanupMonitoring(setup); } } + + [OuterLoop] + [Fact] + public async Task Reasonable_Delay() + { + Tuple> setup = null; + try + { + setup = SetupMonitoring(nameof(Reasonable_Delay)); + + using var monitor = new HostFileChangeMonitor(setup.Item4); + var policy = new CacheItemPolicy + { + ChangeMonitors = { monitor } + }; + var config = new NameValueCollection(); + var mc = new PokerMemoryCache("MyCache", config); + + mc.Set("key", "value", policy); + + // Verify the cache item is set + Assert.Equal("value", mc["key"]); + + // Update the file dependency + File.WriteAllText(setup.Item2, "I am the first file. Updated."); + + // Wait for the monitor to detect the change - 5s should be more than enough + var stop = DateTime.UtcNow.AddMilliseconds(5000); + while (DateTime.UtcNow < stop) + { + if (!mc.Contains("key")) + break; + await Task.Delay(50); + } + + Assert.Null(mc["key"]); + } + finally + { + CleanupMonitoring(setup); + } + } } } diff --git a/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching/MemoryCacheTest.cs b/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching/MemoryCacheTest.cs index 5550b59c4d88ef..586ffeb75f55e2 100644 --- a/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching/MemoryCacheTest.cs +++ b/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching/MemoryCacheTest.cs @@ -72,7 +72,7 @@ public static bool SupportsPhysicalMemoryMonitor private bool IsFullFramework = RuntimeInformation.FrameworkDescription.StartsWith(".NET Framework", StringComparison.OrdinalIgnoreCase); - private PokerMemoryCache CreatePokerMemoryCache(string name, string throwOnDisposed) + private PokerMemoryCache CreatePokerMemoryCache(string name, string? throwOnDisposed) { if (throwOnDisposed == null) { @@ -259,7 +259,7 @@ public void ConstructorValues() } [Theory, InlineData("true"), InlineData("false"), InlineData(null)] - public void Indexer(string throwOnDisposed) + public void Indexer(string? throwOnDisposed) { var mc = CreatePokerMemoryCache("MyCache", throwOnDisposed); @@ -304,8 +304,7 @@ public void Indexer(string throwOnDisposed) } [Theory, InlineData("true"), InlineData("false"), InlineData(null)] - //[ActiveIssue("https://github.com/dotnet/runtime/issues/1429")] - public void Contains(string throwOnDisposed) + public void Contains(string? throwOnDisposed) { var mc = CreatePokerMemoryCache("MyCache", throwOnDisposed); @@ -402,7 +401,7 @@ public void CreateCacheEntryChangeMonitor() } [Theory, InlineData("true"), InlineData("false"), InlineData(null)] - public void AddOrGetExisting_String_Object_DateTimeOffset_String(string throwOnDisposed) + public void AddOrGetExisting_String_Object_DateTimeOffset_String(string? throwOnDisposed) { var mc = CreatePokerMemoryCache("MyCache", throwOnDisposed); @@ -676,7 +675,7 @@ public void AddOrGetExisting_CacheItem_CacheItemPolicy() } [Theory, InlineData("true"), InlineData("false"), InlineData(null)] - public void Set_String_Object_CacheItemPolicy_String(string throwOnDisposed) + public void Set_String_Object_CacheItemPolicy_String(string? throwOnDisposed) { var mc = CreatePokerMemoryCache("MyCache", throwOnDisposed); @@ -902,7 +901,7 @@ public void Set_CacheItem_CacheItemPolicy() } [Theory, InlineData("true"), InlineData("false"), InlineData(null)] - public void Remove(string throwOnDisposed) + public void Remove(string? throwOnDisposed) { var mc = CreatePokerMemoryCache("MyCache", throwOnDisposed); @@ -1011,7 +1010,7 @@ public void Remove(string throwOnDisposed) } [Theory, InlineData("true"), InlineData("false"), InlineData(null)] - public void GetValues(string throwOnDisposed) + public void GetValues(string? throwOnDisposed) { var mc = CreatePokerMemoryCache("MyCache", throwOnDisposed); @@ -1109,11 +1108,9 @@ public void ChangeMonitors() Assert.False(onChangedCalled); } - // Due to internal implementation details Trim has very few easily verifiable scenarios - // ActiveIssue: https://github.com/dotnet/runtime/issues/36488 - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArm64Process))] + [Theory] [InlineData("true"), InlineData("false"), InlineData(null)] - public void Trim(string throwOnDisposed) + public void Trim(string? throwOnDisposed) { var config = new NameValueCollection(); config["__MonoEmulateOneCPU"] = "true"; @@ -1197,11 +1194,6 @@ public void TestExpiredGetValues() [OuterLoop] // makes long wait [Fact] - // This little dance is needed to prevent this test from running against the OS-specific - // runtime binary on the wrong OS. Without it, this test will run for each 'TargetFramework' - // in the test csproj, and the non-windows framework will run against the non-windows library - // because 'netstandard' is still valid for windows execution. - [PlatformSpecific(TestPlatforms.Windows)] public void TestCacheSliding() { var config = new NameValueCollection(); @@ -1510,7 +1502,6 @@ public class MemoryCacheTestExpires4 public static bool SupportsPhysicalMemoryMonitor => MemoryCacheTest.SupportsPhysicalMemoryMonitor; [ConditionalFact(nameof(SupportsPhysicalMemoryMonitor))] - [SkipOnPlatform(TestPlatforms.LinuxBionic, "https://github.com/dotnet/runtime/issues/93106")] public async Task TestCacheShrink() { const int HEAP_RESIZE_THRESHOLD = 8192 + 2; @@ -1570,7 +1561,6 @@ public class MemoryCacheTestExpires5 public static bool SupportsPhysicalMemoryMonitor => MemoryCacheTest.SupportsPhysicalMemoryMonitor; [ConditionalFact(nameof(SupportsPhysicalMemoryMonitor))] - [SkipOnPlatform(TestPlatforms.LinuxBionic, "https://github.com/dotnet/runtime/issues/93106")] public async Task TestCacheExpiryOrdering() { var config = new NameValueCollection(); diff --git a/src/libraries/System.Runtime.CompilerServices.VisualC/System.Runtime.CompilerServices.VisualC.slnx b/src/libraries/System.Runtime.CompilerServices.VisualC/System.Runtime.CompilerServices.VisualC.slnx index f3f2915096eade..1e9970818f9a29 100644 --- a/src/libraries/System.Runtime.CompilerServices.VisualC/System.Runtime.CompilerServices.VisualC.slnx +++ b/src/libraries/System.Runtime.CompilerServices.VisualC/System.Runtime.CompilerServices.VisualC.slnx @@ -1,29 +1,170 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Runtime.CompilerServices.VisualC/src/System.Runtime.CompilerServices.VisualC.csproj b/src/libraries/System.Runtime.CompilerServices.VisualC/src/System.Runtime.CompilerServices.VisualC.csproj index a727319f7cf837..ba6f67bf757deb 100644 --- a/src/libraries/System.Runtime.CompilerServices.VisualC/src/System.Runtime.CompilerServices.VisualC.csproj +++ b/src/libraries/System.Runtime.CompilerServices.VisualC/src/System.Runtime.CompilerServices.VisualC.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/libraries/System.Runtime.CompilerServices.VisualC/tests/System/Runtime/CompilerServices/RequiredAttributeAttributeTests.cs b/src/libraries/System.Runtime.CompilerServices.VisualC/tests/System/Runtime/CompilerServices/RequiredAttributeAttributeTests.cs index e1788cd1426e78..36b045aac858ab 100644 --- a/src/libraries/System.Runtime.CompilerServices.VisualC/tests/System/Runtime/CompilerServices/RequiredAttributeAttributeTests.cs +++ b/src/libraries/System.Runtime.CompilerServices.VisualC/tests/System/Runtime/CompilerServices/RequiredAttributeAttributeTests.cs @@ -10,7 +10,7 @@ public class RequiredAttributeAttributeTests [Theory] [InlineData(null)] [InlineData(typeof(int))] - public void Ctor_RequiredContract(Type requiredContract) + public void Ctor_RequiredContract(Type? requiredContract) { var attribute = new RequiredAttributeAttribute(requiredContract); Assert.Equal(requiredContract, attribute.RequiredContract); diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/System.Runtime.InteropServices.JavaScript.slnx b/src/libraries/System.Runtime.InteropServices.JavaScript/System.Runtime.InteropServices.JavaScript.slnx index 12774d84f69a14..dcca71173e2e98 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/System.Runtime.InteropServices.JavaScript.slnx +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/System.Runtime.InteropServices.JavaScript.slnx @@ -52,6 +52,14 @@ + + + + + + + + @@ -60,6 +68,14 @@ + + + + + + + + @@ -92,6 +108,14 @@ + + + + + + + + @@ -100,6 +124,14 @@ + + + + + + + + @@ -133,6 +165,14 @@ + + + + + + + + @@ -141,6 +181,14 @@ + + + + + + + + @@ -181,6 +229,14 @@ + + + + + + + + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj index 4b637cee5f1743..9643ac9aed0f7f 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj @@ -3,7 +3,6 @@ $(NetCoreAppCurrent)-browser;$(NetCoreAppCurrent) true - false false diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs index 26645c6476f349..a75c897458d04c 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs @@ -283,8 +283,6 @@ public static unsafe JSFunctionBinding BindManagedFunction(string fullyQualified { var (assemblyName, nameSpace, shortClassName, methodName) = ParseFQN(fullyQualifiedName); - var dllName = assemblyName + ".dll"; - IntPtr monoMethod; Interop.Runtime.GetAssemblyExport( // FIXME: Pass UTF-16 through directly so C can work with it, doing the conversion @@ -292,7 +290,7 @@ public static unsafe JSFunctionBinding BindManagedFunction(string fullyQualified // I tested removing the UTF8 conversion from this specific call, but other parts // of startup I can't identify still pull in UTF16->UTF8 conversion, so it's not // worth it to do that yet. - Marshal.StringToCoTaskMemUTF8(dllName), + Marshal.StringToCoTaskMemUTF8(assemblyName), Marshal.StringToCoTaskMemUTF8(nameSpace), Marshal.StringToCoTaskMemUTF8(shortClassName), Marshal.StringToCoTaskMemUTF8(methodName), diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JavaScriptLibrary/JavaScriptLibrary.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JavaScriptLibrary/JavaScriptLibrary.csproj index 5d46e8e5fef624..5af33cc3b69b0e 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JavaScriptLibrary/JavaScriptLibrary.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JavaScriptLibrary/JavaScriptLibrary.csproj @@ -26,7 +26,7 @@ - + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj index c000f916e5ba29..c978c7bf0f49b1 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj @@ -47,13 +47,13 @@ - - - - + + + + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/HttpRequestMessageTest.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/HttpRequestMessageTest.cs index ca4dd337277de0..57a037b0d45ba1 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/HttpRequestMessageTest.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/HttpRequestMessageTest.cs @@ -298,7 +298,6 @@ public void Properties_SetOptionsAndGetTheirValue_NotSet_EnableStreamingResponse } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/113628", TestPlatforms.Browser)] public async Task HttpStreamingDisabledBy_WasmEnableStreamingResponse_InProject() { using var client = new HttpClient(); diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSExportTest.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSExportTest.cs index 2759cd89dfe47c..7e6364265b335b 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSExportTest.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSExportTest.cs @@ -438,7 +438,7 @@ public async Task InternalsVisibleToDoesntBreak() } [Fact] - public async void JSExportCompletedTaskReturnsResolvedPromise() + public async Task JSExportCompletedTaskReturnsResolvedPromise() { string result = await JavaScriptTestHelper.InvokeReturnCompletedTask(); Assert.Equal("resolved", result); diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceAndMethodsContext.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceAndMethodsContext.cs index e1ee7e6d535c98..107ee390e89330 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceAndMethodsContext.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceAndMethodsContext.cs @@ -20,11 +20,23 @@ internal sealed record ComInterfaceAndMethodsContext(ComInterfaceContext Interfa /// /// COM methods that require shadowing declarations on the derived interface. /// - public IEnumerable ShadowingMethods => Methods.Where(m => m.IsInheritedMethod && !m.IsHiddenOnDerivedInterface); + public IEnumerable ShadowingMethods => Methods.Where(m => m.IsInheritedMethod && !m.IsHiddenOnDerivedInterface && !m.IsExternallyDefined); /// /// COM methods that are declared on an interface the interface inherits from. /// public IEnumerable InheritedMethods => Methods.Where(m => m.IsInheritedMethod); + + /// + /// The size of the vtable for this interface, including the base interface methods and IUnknown methods. + /// + public int VTableSize => Methods.Length == 0 + ? IUnknownConstants.VTableSize + : 1 + Methods.Max(m => m.GenerationContext.VtableIndexData.Index); + + /// + /// The size of the vtable for the base interface, including it's base interface methods and IUnknown methods. + /// + public int BaseVTableSize => VTableSize - DeclaredMethods.Count(); } } diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs index b4bc49672185bf..c85104517d6c08 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs @@ -54,7 +54,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) var externalInterfaceSymbols = attributedInterfaces.SelectMany(static (data, ct) => { return ComInterfaceInfo.CreateInterfaceInfoForBaseInterfacesInOtherCompilations(data.Symbol); - }); + }).Collect().SelectMany(static (data, ct) => data.Distinct(ComInterfaceInfo.EqualityComparerForExternalIfaces.Instance)); var interfaceSymbolsWithoutDiagnostics = interfaceSymbolsToGenerateWithoutDiagnostics.Concat(externalInterfaceSymbols); @@ -84,11 +84,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) .SelectMany(static (data, ct) => { return ComMethodContext.CalculateAllMethods(data, ct); - }) - // Now that we've determined method offsets, we can remove all externally defined methods. - // We'll also filter out methods originally declared on externally defined base interfaces - // as we may not be able to emit them into our assembly. - .Where(context => !context.Method.OriginalDeclaringInterface.IsExternallyDefined); + }); // Now that we've determined method offsets, we can remove all externally defined interfaces. var interfaceContextsToGenerate = interfaceContexts.Where(context => !context.IsExternallyDefined); @@ -107,13 +103,20 @@ public void Initialize(IncrementalGeneratorInitializationContext context) return new ComMethodContext( data.Method, data.OwningInterface, - CalculateStubInformation(data.Method.MethodInfo.Syntax, symbolMap[data.Method.MethodInfo], data.Method.Index, env, data.OwningInterface.Info.Type, ct)); + CalculateStubInformation( + data.Method.MethodInfo.Syntax, + symbolMap[data.Method.MethodInfo], + data.Method.Index, + env, + data.OwningInterface.Info, + ct)); }).WithTrackingName(StepNames.CalculateStubInformation); var interfaceAndMethodsContexts = comMethodContexts .Collect() .Combine(interfaceContextsToGenerate.Collect()) - .SelectMany((data, ct) => GroupComContextsForInterfaceGeneration(data.Left, data.Right, ct)); + .SelectMany((data, ct) => + GroupComContextsForInterfaceGeneration(data.Left, data.Right, ct)); // Generate the code for the managed-to-unmanaged stubs. var managedToNativeInterfaceImplementations = interfaceAndMethodsContexts @@ -256,12 +259,22 @@ private static bool IsHResultLikeType(ManagedTypeInfo type) || typeName.Equals("hresult", StringComparison.OrdinalIgnoreCase); } - private static IncrementalMethodStubGenerationContext CalculateStubInformation(MethodDeclarationSyntax syntax, IMethodSymbol symbol, int index, StubEnvironment environment, ManagedTypeInfo owningInterface, CancellationToken ct) + /// + /// Calculates the shared information needed for both source-available and sourceless stub generation. + /// + private static IncrementalMethodStubGenerationContext CalculateSharedStubInformation( + IMethodSymbol symbol, + int index, + StubEnvironment environment, + ISignatureDiagnosticLocations diagnosticLocations, + ComInterfaceInfo owningInterfaceInfo, + CancellationToken ct) { ct.ThrowIfCancellationRequested(); INamedTypeSymbol? lcidConversionAttrType = environment.LcidConversionAttrType; INamedTypeSymbol? suppressGCTransitionAttrType = environment.SuppressGCTransitionAttrType; INamedTypeSymbol? unmanagedCallConvAttrType = environment.UnmanagedCallConvAttrType; + // Get any attributes of interest on the method AttributeData? lcidConversionAttr = null; AttributeData? suppressGCTransitionAttribute = null; @@ -282,8 +295,7 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M } } - var locations = new MethodSignatureDiagnosticLocations(syntax); - var generatorDiagnostics = new GeneratorDiagnosticsBag(new DiagnosticDescriptorProvider(), locations, SR.ResourceManager, typeof(FxResources.Microsoft.Interop.ComInterfaceGenerator.SR)); + var generatorDiagnostics = new GeneratorDiagnosticsBag(new DiagnosticDescriptorProvider(), diagnosticLocations, SR.ResourceManager, typeof(FxResources.Microsoft.Interop.ComInterfaceGenerator.SR)); if (lcidConversionAttr is not null) { @@ -293,8 +305,8 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M GeneratedComInterfaceCompilationData.TryGetGeneratedComInterfaceAttributeFromInterface(symbol.ContainingType, out var generatedComAttribute); var generatedComInterfaceAttributeData = GeneratedComInterfaceCompilationData.GetDataFromAttribute(generatedComAttribute); - // Create the stub. + // Create the stub. var signatureContext = SignatureContext.Create( symbol, DefaultMarshallingInfoParser.Create( @@ -349,7 +361,7 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M // Add the HRESULT return value in the native signature. // This element does not have any influence on the managed signature, so don't assign a managed index. ElementTypeInformation = returnSwappedSignatureElements.Add( - new TypePositionInfo(SpecialTypeInfo.Int32, new ManagedHResultExceptionMarshallingInfo()) + new TypePositionInfo(SpecialTypeInfo.Int32, new ManagedHResultExceptionMarshallingInfo(owningInterfaceInfo.InterfaceId)) { NativeIndex = TypePositionInfo.ReturnIndex }) @@ -387,10 +399,6 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M GeneratorDiagnostics.SizeOfInCollectionMustBeDefinedAtCallReturnValue); } - var containingSyntaxContext = new ContainingSyntaxContext(syntax); - - var methodSyntaxTemplate = new ContainingSyntax(new SyntaxTokenList(syntax.Modifiers.Where(static m => !m.IsKind(SyntaxKind.NewKeyword))).StripAccessibilityModifiers(), SyntaxKind.MethodDeclaration, syntax.Identifier, syntax.TypeParameterList); - ImmutableArray callConv = VirtualMethodPointerStubGenerator.GenerateCallConvSyntaxFromAttributes( suppressGCTransitionAttribute, unmanagedCallConvAttribute, @@ -398,10 +406,7 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M var declaringType = ManagedTypeInfo.CreateTypeInfoForTypeSymbol(symbol.ContainingType); - var virtualMethodIndexData = new VirtualMethodIndexData(index, ImplicitThisParameter: true, direction, true, ExceptionMarshalling.Com); - MarshallingInfo exceptionMarshallingInfo; - if (generatedComInterfaceAttributeData.ExceptionToUnmanagedMarshaller is null) { exceptionMarshallingInfo = new ComExceptionMarshalling(); @@ -418,19 +423,56 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M return new IncrementalMethodStubGenerationContext( signatureContext, - containingSyntaxContext, - methodSyntaxTemplate, - locations, + diagnosticLocations, callConv.ToSequenceEqualImmutableArray(SyntaxEquivalentComparer.Instance), - virtualMethodIndexData, + new VirtualMethodIndexData(index, ImplicitThisParameter: true, direction, true, ExceptionMarshalling.Com), exceptionMarshallingInfo, environment.EnvironmentFlags, - owningInterface, + owningInterfaceInfo.Type, declaringType, generatorDiagnostics.Diagnostics.ToSequenceEqualImmutableArray(), ComInterfaceDispatchMarshallingInfo.Instance); } + private static IncrementalMethodStubGenerationContext CalculateStubInformation(MethodDeclarationSyntax? syntax, IMethodSymbol symbol, int index, StubEnvironment environment, ComInterfaceInfo owningInterface, CancellationToken ct) + { + ISignatureDiagnosticLocations locations = syntax is null + ? NoneSignatureDiagnosticLocations.Instance + : new MethodSignatureDiagnosticLocations(syntax); + + var sourcelessStubInformation = CalculateSharedStubInformation( + symbol, + index, + environment, + locations, + owningInterface, + ct); + + if (syntax is null) + return sourcelessStubInformation; + + var containingSyntaxContext = new ContainingSyntaxContext(syntax); + var methodSyntaxTemplate = new ContainingSyntax( + new SyntaxTokenList(syntax.Modifiers.Where(static m => !m.IsKind(SyntaxKind.NewKeyword))).StripAccessibilityModifiers(), + SyntaxKind.MethodDeclaration, + syntax.Identifier, + syntax.TypeParameterList); + + return new SourceAvailableIncrementalMethodStubGenerationContext( + sourcelessStubInformation.SignatureContext, + containingSyntaxContext, + methodSyntaxTemplate, + locations, + sourcelessStubInformation.CallingConvention, + sourcelessStubInformation.VtableIndexData, + sourcelessStubInformation.ExceptionMarshallingInfo, + sourcelessStubInformation.EnvironmentFlags, + sourcelessStubInformation.TypeKeyOwner, + sourcelessStubInformation.DeclaringType, + sourcelessStubInformation.Diagnostics, + ComInterfaceDispatchMarshallingInfo.Instance); + } + private static MarshalDirection GetDirectionFromOptions(ComInterfaceOptions options) { if (options.HasFlag(ComInterfaceOptions.ManagedObjectWrapper | ComInterfaceOptions.ComObjectWrapper)) @@ -520,12 +562,12 @@ static bool MethodEquals(ComMethodContext a, ComMethodContext b) private static InterfaceDeclarationSyntax GenerateImplementationInterface(ComInterfaceAndMethodsContext interfaceGroup, CancellationToken _) { var definingType = interfaceGroup.Interface.Info.Type; - var shadowImplementations = interfaceGroup.InheritedMethods.Select(m => (Method: m, ManagedToUnmanagedStub: m.ManagedToUnmanagedStub)) + var shadowImplementations = interfaceGroup.InheritedMethods.Where(m => !m.IsExternallyDefined).Select(m => (Method: m, ManagedToUnmanagedStub: m.ManagedToUnmanagedStub)) .Where(p => p.ManagedToUnmanagedStub is GeneratedStubCodeContext) .Select(ctx => ((GeneratedStubCodeContext)ctx.ManagedToUnmanagedStub).Stub.Node .WithExplicitInterfaceSpecifier( ExplicitInterfaceSpecifier(ParseName(definingType.FullTypeName)))); - var inheritedStubs = interfaceGroup.InheritedMethods.Select(m => m.UnreachableExceptionStub); + var inheritedStubs = interfaceGroup.InheritedMethods.Where(m => !m.IsExternallyDefined).Select(m => m.UnreachableExceptionStub); return ImplementationInterfaceTemplate .AddBaseListTypes(SimpleBaseType(definingType.Syntax)) .WithMembers( @@ -661,7 +703,6 @@ private static InterfaceDeclarationSyntax GenerateImplementationVTable(ComInterf BlockSyntax fillBaseInterfaceSlots; - if (interfaceMethods.Interface.Base is null) { // If we don't have a base interface, we need to manually fill in the base iUnknown slots. @@ -740,7 +781,7 @@ private static InterfaceDeclarationSyntax GenerateImplementationVTable(ComInterf } else { - // NativeMemory.Copy(StrategyBasedComWrappers.DefaultIUnknownInteraceDetailsStrategy.GetIUnknownDerivedDetails(typeof().TypeHandle).ManagedVirtualMethodTable, vtable, (nuint)(sizeof(void*) * )); + // NativeMemory.Copy(StrategyBasedComWrappers.DefaultIUnknownInterfaceDetailsStrategy.GetIUnknownDerivedDetails(typeof().TypeHandle).ManagedVirtualMethodTable, vtable, (nuint)(sizeof(void*) * )); fillBaseInterfaceSlots = Block( MethodInvocationStatement( TypeSyntaxes.System_Runtime_InteropServices_NativeMemory, @@ -750,7 +791,7 @@ private static InterfaceDeclarationSyntax GenerateImplementationVTable(ComInterf TypeSyntaxes.StrategyBasedComWrappers .Dot(IdentifierName("DefaultIUnknownInterfaceDetailsStrategy")), IdentifierName("GetIUnknownDerivedDetails"), - Argument( //baseInterfaceTypeInfo.BaseInterface.FullTypeName)), + Argument( TypeOfExpression(ParseTypeName(interfaceMethods.Interface.Base.Info.Type.FullTypeName)) .Dot(IdentifierName("TypeHandle")))) .Dot(IdentifierName("ManagedVirtualMethodTable"))), @@ -767,7 +808,7 @@ private static InterfaceDeclarationSyntax GenerateImplementationVTable(ComInterf ParenthesizedExpression( BinaryExpression(SyntaxKind.MultiplyExpression, SizeOfExpression(PointerType(PredefinedType(Token(SyntaxKind.VoidKeyword)))), - LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(interfaceMethods.InheritedMethods.Count() + 3)))))))); + LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(interfaceMethods.BaseVTableSize)))))))); } var validDeclaredMethods = interfaceMethods.DeclaredMethods @@ -787,7 +828,7 @@ private static InterfaceDeclarationSyntax GenerateImplementationVTable(ComInterf IdentifierName($"{declaredMethodContext.MethodInfo.MethodName}_{declaredMethodContext.GenerationContext.VtableIndexData.Index}")), PrefixUnaryExpression( SyntaxKind.AddressOfExpression, - IdentifierName($"ABI_{declaredMethodContext.GenerationContext.StubMethodSyntaxTemplate.Identifier}"))))); + IdentifierName($"ABI_{((SourceAvailableIncrementalMethodStubGenerationContext)declaredMethodContext.GenerationContext).StubMethodSyntaxTemplate.Identifier}"))))); } return ImplementationInterfaceTemplate @@ -826,7 +867,7 @@ private static ClassDeclarationSyntax GenerateInterfaceInformation(ComInterfaceI EqualsValueClause( ImplicitObjectCreationExpression() .AddArgumentListArguments( - Argument(CreateEmbeddedDataBlobCreationStatement(context.InterfaceId.ToByteArray()))))) + Argument(ComInterfaceGeneratorHelpers.CreateEmbeddedDataBlobCreationStatement(context.InterfaceId.ToByteArray()))))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))); if (context.Options.HasFlag(ComInterfaceOptions.ManagedObjectWrapper)) @@ -858,20 +899,6 @@ private static ClassDeclarationSyntax GenerateInterfaceInformation(ComInterfaceI .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword)) .WithExpressionBody(ArrowExpressionClause(LiteralExpression(SyntaxKind.NullLiteralExpression))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))); - - - static ExpressionSyntax CreateEmbeddedDataBlobCreationStatement(ReadOnlySpan bytes) - { - var literals = new CollectionElementSyntax[bytes.Length]; - - for (int i = 0; i < bytes.Length; i++) - { - literals[i] = ExpressionElement(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(bytes[i]))); - } - - // [ ] - return CollectionExpression(SeparatedList(literals)); - } } } } diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGeneratorHelpers.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGeneratorHelpers.cs index 91a3a956a024bf..04516de9cccaf4 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGeneratorHelpers.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGeneratorHelpers.cs @@ -5,6 +5,9 @@ using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace Microsoft.Interop { @@ -32,5 +35,18 @@ public static IMarshallingGeneratorResolver GetGeneratorResolver(EnvironmentFlag (false, MarshalDirection.UnmanagedToManaged) => s_unmanagedToManagedEnabledMarshallingGeneratorResolver, _ => throw new UnreachableException(), }; + + public static ExpressionSyntax CreateEmbeddedDataBlobCreationStatement(ReadOnlySpan bytes) + { + var literals = new CollectionElementSyntax[bytes.Length]; + + for (int i = 0; i < bytes.Length; i++) + { + literals[i] = ExpressionElement(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(bytes[i]))); + } + + // [ ] + return CollectionExpression(SeparatedList(literals)); + } } } diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceInfo.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceInfo.cs index 0e5219065c8ab5..cbdffa67d62357 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceInfo.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceInfo.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Threading; using Microsoft.CodeAnalysis; @@ -10,7 +12,6 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using InterfaceInfo = (Microsoft.Interop.ComInterfaceInfo InterfaceInfo, Microsoft.CodeAnalysis.INamedTypeSymbol Symbol); using DiagnosticOrInterfaceInfo = Microsoft.Interop.DiagnosticOr<(Microsoft.Interop.ComInterfaceInfo InterfaceInfo, Microsoft.CodeAnalysis.INamedTypeSymbol Symbol)>; -using System.Diagnostics; namespace Microsoft.Interop { @@ -176,6 +177,13 @@ public static ImmutableArray CreateInterfaceInfoForBaseInterfaces return builder.ToImmutable(); } + internal sealed class EqualityComparerForExternalIfaces : IEqualityComparer<(ComInterfaceInfo InterfaceInfo, INamedTypeSymbol Symbol)> + { + public bool Equals((ComInterfaceInfo, INamedTypeSymbol) x, (ComInterfaceInfo, INamedTypeSymbol) y) => SymbolEqualityComparer.Default.Equals(x.Item2, y.Item2); + public int GetHashCode((ComInterfaceInfo, INamedTypeSymbol) obj) => SymbolEqualityComparer.Default.GetHashCode(obj.Item2); + public static readonly EqualityComparerForExternalIfaces Instance = new(); + } + private static bool IsInPartialContext(INamedTypeSymbol symbol, InterfaceDeclarationSyntax syntax, [NotNullWhen(false)] out DiagnosticInfo? diagnostic) { // Verify that the types the interface is declared in are marked partial. diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComMethodContext.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComMethodContext.cs index 42d0bb3691ead8..d2327e0cafdb34 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComMethodContext.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComMethodContext.cs @@ -21,8 +21,8 @@ namespace Microsoft.Interop internal sealed class ComMethodContext : IEquatable { /// - /// A partially constructed that does not have a generated for it yet. - /// can be constructed without a reference to an ISymbol, whereas the requires an ISymbol + /// A partially constructed that does not have a generated for it yet. + /// can be constructed without a reference to an ISymbol, whereas the requires an ISymbol /// /// /// The interface that originally declared the method in user code @@ -48,7 +48,7 @@ private record struct State( /// The partially constructed context /// The final owning interface of this method context /// The generation context for this method - public ComMethodContext(Builder builder, ComInterfaceContext owningInterface, IncrementalMethodStubGenerationContext generationContext) + public ComMethodContext(Builder builder, ComInterfaceContext owningInterface, IncrementalMethodStubGenerationContext? generationContext) { _state = new State(builder.OriginalDeclaringInterface, owningInterface, builder.MethodInfo, generationContext); } @@ -65,6 +65,8 @@ public ComMethodContext(Builder builder, ComInterfaceContext owningInterface, In public ComMethodInfo MethodInfo => _state.MethodInfo; + public bool IsExternallyDefined => _state.OriginalDeclaringInterface.IsExternallyDefined || _state.OwningInterface.IsExternallyDefined; + public IncrementalMethodStubGenerationContext GenerationContext => _state.GenerationContext; public bool IsInheritedMethod => OriginalDeclaringInterface != OwningInterface; @@ -77,12 +79,18 @@ public ComMethodContext(Builder builder, ComInterfaceContext owningInterface, In private GeneratedMethodContextBase CreateManagedToUnmanagedStub() { - if (GenerationContext.VtableIndexData.Direction is not (MarshalDirection.ManagedToUnmanaged or MarshalDirection.Bidirectional) || IsHiddenOnDerivedInterface) + if (GenerationContext.VtableIndexData.Direction is not (MarshalDirection.ManagedToUnmanaged or MarshalDirection.Bidirectional) + || IsHiddenOnDerivedInterface + || IsExternallyDefined) { return new SkippedStubContext(OriginalDeclaringInterface.Info.Type); } - var (methodStub, diagnostics) = VirtualMethodPointerStubGenerator.GenerateManagedToNativeStub(GenerationContext, ComInterfaceGeneratorHelpers.GetGeneratorResolver); - return new GeneratedStubCodeContext(GenerationContext.TypeKeyOwner, GenerationContext.ContainingSyntaxContext, new(methodStub), new(diagnostics)); + if (GenerationContext is not SourceAvailableIncrementalMethodStubGenerationContext sourceAvailableContext) + { + throw new InvalidOperationException("Cannot generate stubs for non-source available methods."); + } + var (methodStub, diagnostics) = VirtualMethodPointerStubGenerator.GenerateManagedToNativeStub(sourceAvailableContext, ComInterfaceGeneratorHelpers.GetGeneratorResolver); + return new GeneratedStubCodeContext(sourceAvailableContext.TypeKeyOwner, sourceAvailableContext.ContainingSyntaxContext, new(methodStub), new(diagnostics)); } private GeneratedMethodContextBase? _unmanagedToManagedStub; @@ -91,12 +99,18 @@ private GeneratedMethodContextBase CreateManagedToUnmanagedStub() private GeneratedMethodContextBase CreateUnmanagedToManagedStub() { - if (GenerationContext.VtableIndexData.Direction is not (MarshalDirection.UnmanagedToManaged or MarshalDirection.Bidirectional) || IsHiddenOnDerivedInterface) + if (GenerationContext.VtableIndexData.Direction is not (MarshalDirection.UnmanagedToManaged or MarshalDirection.Bidirectional) + || IsHiddenOnDerivedInterface + || IsExternallyDefined) { return new SkippedStubContext(GenerationContext.OriginalDefiningType); } - var (methodStub, diagnostics) = VirtualMethodPointerStubGenerator.GenerateNativeToManagedStub(GenerationContext, ComInterfaceGeneratorHelpers.GetGeneratorResolver); - return new GeneratedStubCodeContext(GenerationContext.OriginalDefiningType, GenerationContext.ContainingSyntaxContext, new(methodStub), new(diagnostics)); + if (GenerationContext is not SourceAvailableIncrementalMethodStubGenerationContext sourceAvailableContext) + { + throw new InvalidOperationException("Cannot generate stubs for non-source available methods."); + } + var (methodStub, diagnostics) = VirtualMethodPointerStubGenerator.GenerateNativeToManagedStub(sourceAvailableContext, ComInterfaceGeneratorHelpers.GetGeneratorResolver); + return new GeneratedStubCodeContext(sourceAvailableContext.OriginalDefiningType, sourceAvailableContext.ContainingSyntaxContext, new(methodStub), new(diagnostics)); } private MethodDeclarationSyntax? _unreachableExceptionStub; @@ -183,7 +197,7 @@ ImmutableArray AddMethods(ComInterfaceContext iface, IEnumerable methods = new(); // If we have a base interface, we should add the inherited methods to our list in vtable order if (iface.Base is not null) diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComMethodInfo.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComMethodInfo.cs index 7cb12ff08c308e..f58aa48301ff0d 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComMethodInfo.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComMethodInfo.cs @@ -17,7 +17,7 @@ namespace Microsoft.Interop /// internal sealed record ComMethodInfo { - public MethodDeclarationSyntax Syntax { get; init; } + public MethodDeclarationSyntax? Syntax { get; init; } public string MethodName { get; init; } public SequenceEqualImmutableArray Attributes { get; init; } public bool IsUserDefinedShadowingMethod { get; init; } @@ -94,7 +94,7 @@ private ComMethodInfo( if (ifaceContext.IsExternallyDefined) { return DiagnosticOr<(ComMethodInfo, IMethodSymbol)>.From(( - new ComMethodInfo(null!, method.Name, method.GetAttributes().Select(AttributeInfo.From).ToImmutableArray().ToSequenceEqual(), false), + new ComMethodInfo(null, method.Name, method.GetAttributes().Select(AttributeInfo.From).ToImmutableArray().ToSequenceEqual(), false), method)); } diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/IUnknownConstants.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/IUnknownConstants.cs new file mode 100644 index 00000000000000..e03567780b38ae --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/IUnknownConstants.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.Interop +{ + internal static class IUnknownConstants + { + public const int QueryInterfaceIndex = 0; + public const int AddRefIndex = 1; + public const int ReleaseIndex = 2; + public const int VTableSize = 3; + } +} diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/IncrementalMethodStubGenerationContext.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/IncrementalMethodStubGenerationContext.cs index 06ece904e3f2ef..d42b40e8d998b8 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/IncrementalMethodStubGenerationContext.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/IncrementalMethodStubGenerationContext.cs @@ -1,19 +1,29 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; -using System; namespace Microsoft.Interop { internal abstract record GeneratedMethodContextBase(ManagedTypeInfo OriginalDefiningType, SequenceEqualImmutableArray Diagnostics); - internal sealed record IncrementalMethodStubGenerationContext( + internal record IncrementalMethodStubGenerationContext( + SignatureContext SignatureContext, + ISignatureDiagnosticLocations DiagnosticLocation, + SequenceEqualImmutableArray CallingConvention, + VirtualMethodIndexData VtableIndexData, + MarshallingInfo ExceptionMarshallingInfo, + EnvironmentFlags EnvironmentFlags, + ManagedTypeInfo TypeKeyOwner, + ManagedTypeInfo DeclaringType, + SequenceEqualImmutableArray Diagnostics, + MarshallingInfo ManagedThisMarshallingInfo) : GeneratedMethodContextBase(DeclaringType, Diagnostics); + + internal sealed record SourceAvailableIncrementalMethodStubGenerationContext( SignatureContext SignatureContext, ContainingSyntaxContext ContainingSyntaxContext, ContainingSyntax StubMethodSyntaxTemplate, - MethodSignatureDiagnosticLocations DiagnosticLocation, + ISignatureDiagnosticLocations DiagnosticLocation, SequenceEqualImmutableArray CallingConvention, VirtualMethodIndexData VtableIndexData, MarshallingInfo ExceptionMarshallingInfo, @@ -21,5 +31,15 @@ internal sealed record IncrementalMethodStubGenerationContext( ManagedTypeInfo TypeKeyOwner, ManagedTypeInfo DeclaringType, SequenceEqualImmutableArray Diagnostics, - MarshallingInfo ManagedThisMarshallingInfo) : GeneratedMethodContextBase(DeclaringType, Diagnostics); + MarshallingInfo ManagedThisMarshallingInfo) : IncrementalMethodStubGenerationContext( + SignatureContext, + DiagnosticLocation, + CallingConvention, + VtableIndexData, + ExceptionMarshallingInfo, + EnvironmentFlags, + TypeKeyOwner, + DeclaringType, + Diagnostics, + ManagedThisMarshallingInfo); } diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/Marshallers/ManagedHResultExceptionGeneratorResolver.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/Marshallers/ManagedHResultExceptionGeneratorResolver.cs index 8f8254fa6f6251..583b1380bb901a 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/Marshallers/ManagedHResultExceptionGeneratorResolver.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/Marshallers/ManagedHResultExceptionGeneratorResolver.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; @@ -11,7 +12,7 @@ namespace Microsoft.Interop { - internal sealed record ManagedHResultExceptionMarshallingInfo : MarshallingInfo; + internal sealed record ManagedHResultExceptionMarshallingInfo(Guid InterfaceId) : MarshallingInfo; internal sealed class ManagedHResultExceptionGeneratorResolver : IMarshallingGeneratorResolver { @@ -37,7 +38,7 @@ private sealed class ManagedToUnmanagedMarshaller : IUnboundMarshallingGenerator public ManagedTypeInfo AsNativeType(TypePositionInfo info) => info.ManagedType; public IEnumerable Generate(TypePositionInfo info, StubCodeContext codeContext, StubIdentifierContext context) { - Debug.Assert(info.MarshallingAttributeInfo is ManagedHResultExceptionMarshallingInfo); + ManagedHResultExceptionMarshallingInfo marshallingInfo = (ManagedHResultExceptionMarshallingInfo)info.MarshallingAttributeInfo; if (context.CurrentStage != StubIdentifierContext.Stage.NotifyForSuccessfulInvoke) { @@ -46,11 +47,17 @@ public IEnumerable Generate(TypePositionInfo info, StubCodeCont (string managedIdentifier, _) = context.GetIdentifiers(info); - // Marshal.ThrowExceptionForHR(); + // Marshal.ThrowExceptionForHR(, new(), ); yield return MethodInvocationStatement( TypeSyntaxes.System_Runtime_InteropServices_Marshal, IdentifierName("ThrowExceptionForHR"), - Argument(IdentifierName(managedIdentifier))); + Argument(IdentifierName(managedIdentifier)), + Argument(ImplicitObjectCreationExpression( + ArgumentList( + SingletonSeparatedList( + Argument(ComInterfaceGeneratorHelpers.CreateEmbeddedDataBlobCreationStatement(marshallingInfo.InterfaceId.ToByteArray())))), + initializer: null)), + Argument(CastExpression(TypeSyntaxes.System_IntPtr, IdentifierName(VirtualMethodPointerStubGenerator.NativeThisParameterIdentifier)))); } public SignatureBehavior GetNativeSignatureBehavior(TypePositionInfo info) => SignatureBehavior.NativeType; diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodPointerStubGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodPointerStubGenerator.cs index a56644cef13f58..fb7df8530364f2 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodPointerStubGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodPointerStubGenerator.cs @@ -16,12 +16,12 @@ namespace Microsoft.Interop { internal static class VirtualMethodPointerStubGenerator { - private const string NativeThisParameterIdentifier = "__this"; - private const string VirtualMethodTableIdentifier = "__vtable"; - private const string VirtualMethodTarget = "__target"; + internal const string NativeThisParameterIdentifier = "__this"; + internal const string VirtualMethodTableIdentifier = "__vtable"; + internal const string VirtualMethodTarget = "__target"; public static (MethodDeclarationSyntax, ImmutableArray) GenerateManagedToNativeStub( - IncrementalMethodStubGenerationContext methodStub, + SourceAvailableIncrementalMethodStubGenerationContext methodStub, Func generatorResolverCreator) { var diagnostics = new GeneratorDiagnosticsBag(new DiagnosticDescriptorProvider(), methodStub.DiagnosticLocation, SR.ResourceManager, typeof(FxResources.Microsoft.Interop.ComInterfaceGenerator.SR)); @@ -128,7 +128,7 @@ private static MethodDeclarationSyntax PrintGeneratedSource( private const string ManagedThisParameterIdentifier = "@this"; public static (MethodDeclarationSyntax, ImmutableArray) GenerateNativeToManagedStub( - IncrementalMethodStubGenerationContext methodStub, + SourceAvailableIncrementalMethodStubGenerationContext methodStub, Func generatorResolverCreator) { var diagnostics = new GeneratorDiagnosticsBag(new DiagnosticDescriptorProvider(), methodStub.DiagnosticLocation, SR.ResourceManager, typeof(FxResources.Microsoft.Interop.ComInterfaceGenerator.SR)); @@ -174,7 +174,7 @@ public static (MethodDeclarationSyntax, ImmutableArray) Generate methodStub.Diagnostics.Array.AddRange(diagnostics.Diagnostics)); } - private static ImmutableArray AddManagedToUnmanagedImplicitThis(IncrementalMethodStubGenerationContext methodStub) + private static ImmutableArray AddManagedToUnmanagedImplicitThis(SourceAvailableIncrementalMethodStubGenerationContext methodStub) { ImmutableArray originalElements = methodStub.SignatureContext.ElementTypeInformation; @@ -232,7 +232,7 @@ private static ImmutableArray AddUnmanagedToManagedImplicitEle } public static BlockSyntax GenerateVirtualMethodTableSlotAssignments( - IEnumerable vtableMethods, + IEnumerable vtableMethods, string vtableIdentifier, Func generatorResolverCreator) { diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs index 9328c0e7d6e56e..e46ab33137dab4 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs @@ -62,7 +62,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) // Calculate all of information to generate both managed-to-unmanaged and unmanaged-to-managed stubs // for each method. - IncrementalValuesProvider generateStubInformation = methodsToGenerate + IncrementalValuesProvider generateStubInformation = methodsToGenerate .Combine(context.CreateStubEnvironmentProvider()) .Select(static (data, ct) => new { @@ -89,7 +89,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) context.RegisterConcatenatedSyntaxOutputs(generateManagedToNativeStub.Select((data, ct) => data.Item1), "ManagedToNativeStubs.g.cs"); // Filter the list of all stubs to only the stubs that requested unmanaged-to-managed stub generation. - IncrementalValuesProvider nativeToManagedStubContexts = + IncrementalValuesProvider nativeToManagedStubContexts = generateStubInformation .Where(data => data.VtableIndexData.Direction is MarshalDirection.UnmanagedToManaged or MarshalDirection.Bidirectional); @@ -195,7 +195,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) }; } - private static IncrementalMethodStubGenerationContext CalculateStubInformation(MethodDeclarationSyntax syntax, IMethodSymbol symbol, StubEnvironment environment, CancellationToken ct) + private static SourceAvailableIncrementalMethodStubGenerationContext CalculateStubInformation(MethodDeclarationSyntax syntax, IMethodSymbol symbol, StubEnvironment environment, CancellationToken ct) { ct.ThrowIfCancellationRequested(); INamedTypeSymbol? lcidConversionAttrType = environment.Compilation.GetTypeByMetadataName(TypeNames.LCIDConversionAttribute); @@ -306,7 +306,7 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M MarshallingInfo exceptionMarshallingInfo = CreateExceptionMarshallingInfo(virtualMethodIndexAttr, symbol, environment.Compilation, generatorDiagnostics, virtualMethodIndexData); - return new IncrementalMethodStubGenerationContext( + return new SourceAvailableIncrementalMethodStubGenerationContext( signatureContext, containingSyntaxContext, methodSyntaxTemplate, @@ -363,7 +363,7 @@ private static MarshallingInfo CreateExceptionMarshallingInfo(AttributeData virt } private static (MemberDeclarationSyntax, ImmutableArray) GenerateManagedToNativeStub( - IncrementalMethodStubGenerationContext methodStub) + SourceAvailableIncrementalMethodStubGenerationContext methodStub) { var (stub, diagnostics) = VirtualMethodPointerStubGenerator.GenerateManagedToNativeStub(methodStub, VtableIndexStubGeneratorHelpers.GetGeneratorResolver); @@ -376,7 +376,7 @@ private static (MemberDeclarationSyntax, ImmutableArray) Generat } private static (MemberDeclarationSyntax, ImmutableArray) GenerateNativeToManagedStub( - IncrementalMethodStubGenerationContext methodStub) + SourceAvailableIncrementalMethodStubGenerationContext methodStub) { var (stub, diagnostics) = VirtualMethodPointerStubGenerator.GenerateNativeToManagedStub(methodStub, VtableIndexStubGeneratorHelpers.GetGeneratorResolver); @@ -433,7 +433,7 @@ private static MemberDeclarationSyntax GenerateNativeInterfaceMetadata(Containin .AddAttributeLists(AttributeList(SingletonSeparatedList(Attribute(NameSyntaxes.System_Runtime_InteropServices_DynamicInterfaceCastableImplementationAttribute))))); } - private static MemberDeclarationSyntax GeneratePopulateVTableMethod(IGrouping vtableMethods) + private static MemberDeclarationSyntax GeneratePopulateVTableMethod(IGrouping vtableMethods) { ContainingSyntaxContext containingSyntax = vtableMethods.Key.AddContainingSyntax(NativeTypeContainingSyntax); diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf index ca5736a7ac3338..c2b34b5ad4c2eb 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf @@ -394,7 +394,7 @@ The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} - The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + Typ {0} zadaný jako GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller není přístupný přes generovaný kód. Typ musí mít přístupnost alespoň „internal“. {1} @@ -439,7 +439,7 @@ Marshalling a generic delegate is not supported. Consider using a function pointer instead. - Marshalling a generic delegate is not supported. Consider using a function pointer instead. + Zařazování obecného delegáta není podporováno. Zvažte místo toho použití ukazatele na funkci. @@ -624,7 +624,7 @@ The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. - The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + Typ zadaný jako GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshacak není platným zařazovacím typem. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf index 0464ceb4f52908..bdfd8aee1ec7bf 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf @@ -394,7 +394,7 @@ The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} - The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + Der generierte Code kann nicht auf den Typ „{0}“, der als „GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller“ angegeben ist, zugreifen. Der Typ muss über mindestens interne Zugriffsmöglichkeiten („internal“) verfügen. {1} @@ -439,7 +439,7 @@ Marshalling a generic delegate is not supported. Consider using a function pointer instead. - Marshalling a generic delegate is not supported. Consider using a function pointer instead. + Das Marshalling für eine generische Stellvertretung wird nicht unterstützt. Ziehen Sie stattdessen die Verwendung eines Funktionszeigers in Betracht. @@ -624,7 +624,7 @@ The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. - The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + Der als „GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller“ angegebene Typ ist kein gültiger Marshallertyp. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf index 78f6c864bd2c7c..6949c57d1513fe 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf @@ -394,7 +394,7 @@ The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} - The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + El código generado no puede acceder al tipo "{0}" especificado como "GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller". El tipo debe tener al menos accesibilidad "interna". {1} @@ -439,7 +439,7 @@ Marshalling a generic delegate is not supported. Consider using a function pointer instead. - Marshalling a generic delegate is not supported. Consider using a function pointer instead. + No se admite la serialización de un delegado genérico. Considere la posibilidad de usar un puntero de función en su lugar. @@ -624,7 +624,7 @@ The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. - The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + El tipo especificado como "GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller" no es un tipo de serializador válido. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf index 851915b7c461f1..b4df96b4d24f6b 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf @@ -394,7 +394,7 @@ The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} - The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + Le type « {0} » spécifié en tant que « GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarsalloer » n’est pas accessible par le code généré. Le type doit avoir au moins une accessibilité « interne ». {1} @@ -439,7 +439,7 @@ Marshalling a generic delegate is not supported. Consider using a function pointer instead. - Marshalling a generic delegate is not supported. Consider using a function pointer instead. + Le marshaling d’un délégué générique n’est pas pris en charge. Envisagez plutôt d’utiliser un pointeur de fonction. @@ -624,7 +624,7 @@ The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. - The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + Le type spécifié en tant que « GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarsfecteur » n’est pas un type de marshaleur valide. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf index 270815e73e3d87..eb201d34ef39ff 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf @@ -394,7 +394,7 @@ The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} - The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + Il tipo '{0}' specificato come 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' non è accessibile dal codice generato. Il tipo deve avere almeno accessibilità "interna". {1} @@ -439,7 +439,7 @@ Marshalling a generic delegate is not supported. Consider using a function pointer instead. - Marshalling a generic delegate is not supported. Consider using a function pointer instead. + Il marshalling di un delegato generico non è supportato. Valutare invece se utilizzare un puntatore funzione. @@ -624,7 +624,7 @@ The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. - The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + Il tipo specificato come 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' non è un tipo di marshaller valido. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf index 4cb1edec15b8b2..e36ce66ee7c9bc 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf @@ -394,7 +394,7 @@ The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} - The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' として指定された型 '{0}' には、生成されたコードからアクセスできません。この型には少なくともアクセシビリティ 'internal' が必要です。{1} @@ -439,7 +439,7 @@ Marshalling a generic delegate is not supported. Consider using a function pointer instead. - Marshalling a generic delegate is not supported. Consider using a function pointer instead. + 汎用デリゲートのマーシャリングはサポートされていません。代わりに関数ポインターの使用を検討してください。 @@ -624,7 +624,7 @@ The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. - The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' として指定された型は、有効なマーシャラー型ではありません。 diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf index 65e400e79266c6..1699af9d6f5ac1 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf @@ -394,7 +394,7 @@ The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} - The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + 생성된 코드에서 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller'로 지정된 '{0}' 형식에 액세스할 수 없습니다. 형식에는 최소한 'internal' 접근성이 있어야 합니다. {1} @@ -439,7 +439,7 @@ Marshalling a generic delegate is not supported. Consider using a function pointer instead. - Marshalling a generic delegate is not supported. Consider using a function pointer instead. + 제네릭 대리자를 마샬링할 수 없습니다. 대신 함수 포인터를 사용하는 것이 좋습니다. @@ -624,7 +624,7 @@ The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. - The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller'로 지정된 형식은 유효한 마샬러 형식이 아닙니다. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf index 7f967eef2035ef..aeaf8022c4fe82 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf @@ -394,7 +394,7 @@ The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} - The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + Wygenerowany kod nie ma dostępu do typu „{0}” określonego jako „GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshainger”. Typ musi mieć co najmniej ułatwienia dostępu „wewnętrzne”. {1} @@ -439,7 +439,7 @@ Marshalling a generic delegate is not supported. Consider using a function pointer instead. - Marshalling a generic delegate is not supported. Consider using a function pointer instead. + Marshalling ogólnego delegata nie jest obsługiwane. Zamiast tego rozważ użycie wskaźnika funkcji. @@ -624,7 +624,7 @@ The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. - The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + Typ określony jako „GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshainger” nie jest prawidłowym typem marshaller. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf index 6c089e67e988cb..4d81c5beee2c1e 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf @@ -394,7 +394,7 @@ The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} - The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + O tipo '{0}' especificado como 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' não é acessível por meio de código gerado. O tipo deve ter pelo menos acessibilidade ''interna''. {1} @@ -439,7 +439,7 @@ Marshalling a generic delegate is not supported. Consider using a function pointer instead. - Marshalling a generic delegate is not supported. Consider using a function pointer instead. + Não há suporte para marshalling de um delegado genérico. Considere usar um ponteiro de função. @@ -624,7 +624,7 @@ The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. - The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + O tipo especificado como 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' não é um tipo de marshaller válido. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf index dfcbf026ca6fa8..8ff2566fb34986 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf @@ -394,7 +394,7 @@ The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} - The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + Тип "{0}", указанный как "GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller", недоступен для сгенерированного кода. Тип должен обеспечивать уровень доступности хотя бы на уровне "internal". {1} @@ -439,7 +439,7 @@ Marshalling a generic delegate is not supported. Consider using a function pointer instead. - Marshalling a generic delegate is not supported. Consider using a function pointer instead. + Маршализация делегата общего назначения не поддерживается. Рассмотрите возможность использования вместо этого указателя на функцию. @@ -624,7 +624,7 @@ The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. - The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + Указан тип "GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller", недопустимый для маршализатора. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf index 433862bb328a8c..49b5dce9f93459 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf @@ -394,7 +394,7 @@ The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} - The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + Oluşturulan kodla 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' olarak belirtilen '{0}' türüne erişilemez. Tür, en azından 'internal' erişilebilirlik özelliğine sahip olmalıdır. {1} @@ -439,7 +439,7 @@ Marshalling a generic delegate is not supported. Consider using a function pointer instead. - Marshalling a generic delegate is not supported. Consider using a function pointer instead. + Genel bir temsilcinin sıralanması desteklenmiyor. Bunun yerine bir işlev işaretçisi kullanmayı değerlendirin. @@ -624,7 +624,7 @@ The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. - The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' olarak belirtilen tür, geçerli bir sıralama türü değil. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf index 9e56d56f6d8b53..d88eb2fcf95f5e 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf @@ -394,7 +394,7 @@ The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} - The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + 生成的代码无法访问指定为 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' 的类型“{0}”。该类型必须至少具有 "internal" 可访问性。{1} @@ -439,7 +439,7 @@ Marshalling a generic delegate is not supported. Consider using a function pointer instead. - Marshalling a generic delegate is not supported. Consider using a function pointer instead. + 不支持封送泛型委托。请考虑改用函数指针。 @@ -624,7 +624,7 @@ The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. - The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + 指定为 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' 的类型不是有效的封送程序类型。 diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf index 10d642ed5dacc0..be8453ca5e1396 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf @@ -394,7 +394,7 @@ The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} - The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + 指定為 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' 的類型 '{0}' 不是有效的封送處理器類型。類型必須至少具有 'internal' 可存取性。{1} @@ -439,7 +439,7 @@ Marshalling a generic delegate is not supported. Consider using a function pointer instead. - Marshalling a generic delegate is not supported. Consider using a function pointer instead. + 不支援封送一般委派。請考慮改用函式指標。 @@ -624,7 +624,7 @@ The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. - The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + 指定為 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' 的類型不是有效的封送處理器類型。 diff --git a/src/libraries/System.Runtime.InteropServices/gen/DownlevelLibraryImportGenerator/DownlevelLibraryImportGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/DownlevelLibraryImportGenerator/DownlevelLibraryImportGenerator.cs index b734647bf6965c..9c58a7f319364c 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/DownlevelLibraryImportGenerator/DownlevelLibraryImportGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/DownlevelLibraryImportGenerator/DownlevelLibraryImportGenerator.cs @@ -375,7 +375,7 @@ private static AttributeSyntax CreateForwarderDllImport(LibraryImportData target NameEqualsSyntax name = NameEquals(nameof(DllImportAttribute.CharSet)); ExpressionSyntax value = MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, - ParseTypeName(typeof(CharSet).FullName), + AliasQualifiedName("global", IdentifierName(typeof(CharSet).FullName)), IdentifierName(nameof(CharSet.Unicode))); newAttributeArgs.Add(AttributeArgument(name, null, value)); } diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomMarshallerAttributeAnalyzer.cs b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomMarshallerAttributeAnalyzer.cs index 493e206e3c423e..588a2ff4407f57 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomMarshallerAttributeAnalyzer.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomMarshallerAttributeAnalyzer.cs @@ -645,7 +645,7 @@ public void AnalyzeAttribute(OperationAnalysisContext context) if (attr.Operation is IObjectCreationOperation attrCreation && attrCreation.Type.Equals(_customMarshallerAttribute, SymbolEqualityComparer.Default)) { - INamedTypeSymbol entryType = (INamedTypeSymbol)context.ContainingSymbol!; + INamedTypeSymbol entryType = (INamedTypeSymbol)context.ContainingSymbol; IArgumentOperation? managedTypeArgument = attrCreation.GetArgumentByOrdinal(0); if (managedTypeArgument.Value.IsNullLiteralOperation()) { diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/NativeMarshallingAttributeAnalyzer.cs b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/NativeMarshallingAttributeAnalyzer.cs index 4001706b8d04ed..951913fb8a4296 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/NativeMarshallingAttributeAnalyzer.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/NativeMarshallingAttributeAnalyzer.cs @@ -93,12 +93,12 @@ public void AnalyzeAttribute(OperationAnalysisContext context) DiagnosticReporter diagnosticFactory = DiagnosticReporter.CreateForLocation(marshallerEntryPointTypeArgument.Value.Syntax.GetLocation(), context.ReportDiagnostic); diagnosticFactory.CreateAndReportDiagnostic( MarshallerEntryPointTypeMustBeNonNullRule, - GetSymbolType(context.ContainingSymbol!).ToDisplayString()); + GetSymbolType(context.ContainingSymbol).ToDisplayString()); } if (marshallerEntryPointTypeArgument.Value is ITypeOfOperation typeOfOp) { AnalyzeManagedTypeMarshallingInfo( - GetSymbolType(context.ContainingSymbol!), + GetSymbolType(context.ContainingSymbol), DiagnosticReporter.CreateForLocation(((TypeOfExpressionSyntax)typeOfOp.Syntax).Type.GetLocation(), context.ReportDiagnostic), (INamedTypeSymbol?)typeOfOp.TypeOperand); } diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/LibraryImportGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/LibraryImportGenerator.cs index 4ced83dc3bf5db..eeca7bccf74ac2 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/LibraryImportGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/LibraryImportGenerator.cs @@ -533,7 +533,7 @@ static ExpressionSyntax CreateEnumExpressionSyntax(T value) where T : Enum { return MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, - IdentifierName(typeof(T).FullName), + AliasQualifiedName("global", IdentifierName(typeof(T).FullName)), IdentifierName(value.ToString())); } } diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ElementsMarshalling.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ElementsMarshalling.cs index 6e1b1d44ba616c..f21125e297aa7e 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ElementsMarshalling.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ElementsMarshalling.cs @@ -39,7 +39,6 @@ protected ElementsMarshalling(IElementsMarshallingCollectionSource collectionSou /// /// public StatementSyntax GenerateClearUnmanagedDestination(StubIdentifierContext context) - { // .Clear(); return MethodInvocationStatement( @@ -284,7 +283,7 @@ public override StatementSyntax GenerateMarshalStatement(StubIdentifierContext c statements.Add(GenerateContentsMarshallingStatement( context, MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, - IdentifierName(MarshallerHelpers.GetManagedSpanIdentifier(CollectionSource.TypeInfo, context)), + IdentifierName(managedSpanIdentifier), IdentifierName("Length")), elementMarshaller, StubIdentifierContext.Stage.Marshal)); @@ -295,7 +294,6 @@ public override StatementSyntax GenerateUnmarshalStatement(StubIdentifierContext { string managedSpanIdentifier = MarshallerHelpers.GetManagedSpanIdentifier(CollectionSource.TypeInfo, context); string nativeSpanIdentifier = MarshallerHelpers.GetNativeSpanIdentifier(CollectionSource.TypeInfo, context); - string numElementsIdentifier = MarshallerHelpers.GetNumElementsIdentifier(CollectionSource.TypeInfo, context); // ReadOnlySpan = // Span = @@ -311,7 +309,9 @@ public override StatementSyntax GenerateUnmarshalStatement(StubIdentifierContext CollectionSource.GetManagedValuesDestination(context)), GenerateContentsMarshallingStatement( context, - IdentifierName(numElementsIdentifier), + MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, + IdentifierName(nativeSpanIdentifier), + IdentifierName("Length")), elementMarshaller, StubIdentifierContext.Stage.UnmarshalCapture, StubIdentifierContext.Stage.Unmarshal)); } @@ -356,7 +356,9 @@ public override StatementSyntax GenerateManagedToUnmanagedByValueOutUnmarshalSta unmanagedValuesDeclaration, GenerateContentsMarshallingStatement( context, - IdentifierName(numElementsIdentifier), + MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, + IdentifierName(managedSpanIdentifier), + IdentifierName("Length")), elementMarshaller, StubIdentifierContext.Stage.UnmarshalCapture, StubIdentifierContext.Stage.Unmarshal)); } @@ -460,7 +462,9 @@ public override StatementSyntax GenerateUnmanagedToManagedByValueOutMarshalState managedValuesDestination, GenerateContentsMarshallingStatement( context, - IdentifierName(numElementsIdentifier), + MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, + IdentifierName(nativeSpanIdentifier), + IdentifierName("Length")), new FreeAlwaysOwnedOriginalValueGenerator(elementMarshaller), stagesToGenerate)); } diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MethodSignatureDiagnosticLocations.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MethodSignatureDiagnosticLocations.cs index 2705493f9155aa..f874103ec9e45d 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MethodSignatureDiagnosticLocations.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MethodSignatureDiagnosticLocations.cs @@ -42,6 +42,15 @@ public interface ISignatureDiagnosticLocations DiagnosticInfo CreateDiagnosticInfo(DiagnosticDescriptor descriptor, GeneratorDiagnostic diagnostic); } + public class NoneSignatureDiagnosticLocations : ISignatureDiagnosticLocations + { + public static readonly NoneSignatureDiagnosticLocations Instance = new(); + public DiagnosticInfo CreateDiagnosticInfo(DiagnosticDescriptor descriptor, GeneratorDiagnostic diagnostic) + { + return diagnostic.ToDiagnosticInfo(descriptor, Location.None, string.Empty); + } + } + public sealed record MethodSignatureDiagnosticLocations(string MethodIdentifier, ImmutableArray ManagedParameterLocations, Location FallbackLocation) : ISignatureDiagnosticLocations { public MethodSignatureDiagnosticLocations(MethodDeclarationSyntax syntax) diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypePositionInfo.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypePositionInfo.cs index f3b6b790ec4d49..14fa3a62d559ab 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypePositionInfo.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypePositionInfo.cs @@ -96,7 +96,7 @@ public static TypePositionInfo CreateForParameter(IParameterSymbol paramSymbol, ByValueContentsMarshalKind = byValueContentsMarshalKind, ByValueMarshalAttributeLocations = (inLocation, outLocation), ScopedKind = paramSymbol.ScopedKind, - IsExplicitThis = ((ParameterSyntax)paramSymbol.DeclaringSyntaxReferences[0].GetSyntax()).Modifiers.Any(SyntaxKind.ThisKeyword) + IsExplicitThis = ((ParameterSyntax?)paramSymbol.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax())?.Modifiers.Any(SyntaxKind.ThisKeyword) ?? false }; return typeInfo; diff --git a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs index 2a1f06362dc16e..593a42224208d8 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -1068,6 +1068,7 @@ public static void FreeHGlobal(System.IntPtr hglobal) { } public static int GetExceptionCode() { throw null; } public static System.Exception? GetExceptionForHR(int errorCode) { throw null; } public static System.Exception? GetExceptionForHR(int errorCode, System.IntPtr errorInfo) { throw null; } + public static System.Exception? GetExceptionForHR(int errorCode, in System.Guid iid, System.IntPtr pUnk) { throw null; } public static System.IntPtr GetExceptionPointers() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Marshalling code for the delegate might not be available. Use the GetFunctionPointerForDelegate overload instead.")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -1208,6 +1209,7 @@ public static void StructureToPtr(object structure, System.IntPtr ptr, bool fDel public static void StructureToPtr([System.Diagnostics.CodeAnalysis.DisallowNullAttribute] T structure, System.IntPtr ptr, bool fDeleteOld) { } public static void ThrowExceptionForHR(int errorCode) { } public static void ThrowExceptionForHR(int errorCode, System.IntPtr errorInfo) { } + public static void ThrowExceptionForHR(int errorCode, in System.Guid iid, System.IntPtr pUnk) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public static System.IntPtr UnsafeAddrOfPinnedArrayElement(System.Array arr, int index) { throw null; } public static System.IntPtr UnsafeAddrOfPinnedArrayElement(T[] arr, int index) { throw null; } diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/ComInterfaceGenerator.Tests.csproj b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/ComInterfaceGenerator.Tests.csproj index 4c953e51ddb7a8..30ca8dd99aff38 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/ComInterfaceGenerator.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/ComInterfaceGenerator.Tests.csproj @@ -2,6 +2,8 @@ $(NetCoreAppCurrent) + + $(TargetRid) true true true @@ -15,7 +17,7 @@ - + diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/CrossAssemblyInheritanceTests.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/CrossAssemblyInheritanceTests.cs new file mode 100644 index 00000000000000..14f916718fcd9d --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/CrossAssemblyInheritanceTests.cs @@ -0,0 +1,256 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Linq; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; +using SharedTypes.ComInterfaces; +using Xunit; + +namespace ComInterfaceGenerator.Tests +{ + public partial class CrossAssemblyInheritanceTests + { + [GeneratedComClass] + [Guid("e0c6b35f-1234-4567-8901-123456789abc")] + internal partial class DerivedExternalBaseImpl : IDerivedExternalBase + { + private int _value = 10; + + public int GetInt() => _value; + public void SetInt(int x) => _value = x; + public string GetName() => "DerivedExternalBase"; + } + + [GeneratedComClass] + [Guid("e0c6b35f-1234-4567-8901-123456789abd")] + internal partial class DerivedExternalBase2Impl : IDerivedExternalBase2 + { + private int _value = 20; + + public int GetInt() => _value; + public void SetInt(int x) => _value = x; + public string GetName() => "DerivedExternalBase2"; + } + + [GeneratedComClass] + [Guid("e0c6b35f-1234-4567-8901-123456789abe")] + internal partial class DerivedFromExternalDerivedImpl : IDerivedFromExternalDerived + { + private int _value = 30; + private bool _boolValue = true; + + public int GetInt() => _value; + public void SetInt(int x) => _value = x; + public bool GetBool() => _boolValue; + public void SetBool(bool x) => _boolValue = x; + public string GetName() => "DerivedFromExternalDerived"; + } + + [GeneratedComClass] + [Guid("e0c6b35f-1234-4567-8901-123456789abf")] + internal partial class DerivedFromDerivedExternalDerivedImpl : IDerivedFromDerivedExternalDerived + { + private int _value = 40; + private bool _boolValue = false; + private float _floatValue = 3.14f; + + public int GetInt() => _value; + public void SetInt(int x) => _value = x; + public bool GetBool() => _boolValue; + public void SetBool(bool x) => _boolValue = x; + public string GetName() => "DerivedFromDerivedExternalDerived"; + public float GetFloat() => _floatValue; + } + + [Fact] + public void IDerivedExternalBase_CanCallMethods() + { + var implementation = new DerivedExternalBaseImpl(); + var comWrappers = new StrategyBasedComWrappers(); + var nativeObj = comWrappers.GetOrCreateComInterfaceForObject(implementation, CreateComInterfaceFlags.None); + var managedObj = comWrappers.GetOrCreateObjectForComInstance(nativeObj, CreateObjectFlags.None); + + var externalBase = (IExternalBase)managedObj; + Assert.Equal(10, externalBase.GetInt()); + externalBase.SetInt(15); + Assert.Equal(15, externalBase.GetInt()); + + var derivedExternalBase = (IDerivedExternalBase)managedObj; + Assert.Equal(15, derivedExternalBase.GetInt()); + Assert.Equal("DerivedExternalBase", derivedExternalBase.GetName()); + } + + [Fact] + public void IDerivedExternalBase2_CanCallMethods() + { + var implementation = new DerivedExternalBase2Impl(); + var comWrappers = new StrategyBasedComWrappers(); + var nativeObj = comWrappers.GetOrCreateComInterfaceForObject(implementation, CreateComInterfaceFlags.None); + var managedObj = comWrappers.GetOrCreateObjectForComInstance(nativeObj, CreateObjectFlags.None); + + // Test as base interface + var externalBase = (IExternalBase)managedObj; + Assert.Equal(20, externalBase.GetInt()); + externalBase.SetInt(25); + Assert.Equal(25, externalBase.GetInt()); + + // Test as derived interface + var derivedExternalBase2 = (IDerivedExternalBase2)managedObj; + Assert.Equal(25, derivedExternalBase2.GetInt()); + Assert.Equal("DerivedExternalBase2", derivedExternalBase2.GetName()); + } + + [Fact] + public void IDerivedFromExternalDerived_CanCallMethods() + { + var implementation = new DerivedFromExternalDerivedImpl(); + var comWrappers = new StrategyBasedComWrappers(); + var nativeObj = comWrappers.GetOrCreateComInterfaceForObject(implementation, CreateComInterfaceFlags.None); + var managedObj = comWrappers.GetOrCreateObjectForComInstance(nativeObj, CreateObjectFlags.None); + + var externalBase = (IExternalBase)managedObj; + Assert.Equal(30, externalBase.GetInt()); + externalBase.SetInt(35); + Assert.Equal(35, externalBase.GetInt()); + + var externalDerived = (IExternalDerived)managedObj; + Assert.Equal(35, externalDerived.GetInt()); + Assert.True(externalDerived.GetBool()); + externalDerived.SetBool(false); + Assert.False(externalDerived.GetBool()); + + var derivedFromExternalDerived = (IDerivedFromExternalDerived)managedObj; + Assert.Equal(35, derivedFromExternalDerived.GetInt()); + Assert.False(derivedFromExternalDerived.GetBool()); + Assert.Equal("DerivedFromExternalDerived", derivedFromExternalDerived.GetName()); + } + + [Fact] + public void IDerivedFromDerivedExternalDerived_CanCallMethods() + { + var implementation = new DerivedFromDerivedExternalDerivedImpl(); + var comWrappers = new StrategyBasedComWrappers(); + var nativeObj = comWrappers.GetOrCreateComInterfaceForObject(implementation, CreateComInterfaceFlags.None); + var managedObj = comWrappers.GetOrCreateObjectForComInstance(nativeObj, CreateObjectFlags.None); + + var externalBase = (IExternalBase)managedObj; + Assert.Equal(40, externalBase.GetInt()); + externalBase.SetInt(45); + Assert.Equal(45, externalBase.GetInt()); + + var externalDerived = (IExternalDerived)managedObj; + Assert.Equal(45, externalDerived.GetInt()); + Assert.False(externalDerived.GetBool()); + externalDerived.SetBool(true); + Assert.True(externalDerived.GetBool()); + + var derivedFromExternalDerived = (IDerivedFromExternalDerived)managedObj; + Assert.Equal(45, derivedFromExternalDerived.GetInt()); + Assert.True(derivedFromExternalDerived.GetBool()); + Assert.Equal("DerivedFromDerivedExternalDerived", derivedFromExternalDerived.GetName()); + + var derivedFromDerivedExternalDerived = (IDerivedFromDerivedExternalDerived)managedObj; + Assert.Equal(45, derivedFromDerivedExternalDerived.GetInt()); + Assert.True(derivedFromDerivedExternalDerived.GetBool()); + Assert.Equal("DerivedFromDerivedExternalDerived", derivedFromDerivedExternalDerived.GetName()); + Assert.Equal(3.14f, derivedFromDerivedExternalDerived.GetFloat()); + } + + [Fact] + public unsafe void MultipleInterfacesDerivedFromSameBase_ShareCommonVTableLayout() + { + IIUnknownDerivedDetails baseDetails = StrategyBasedComWrappers.DefaultIUnknownInterfaceDetailsStrategy + .GetIUnknownDerivedDetails(typeof(IExternalBase).TypeHandle); + + IIUnknownDerivedDetails derived1Details = StrategyBasedComWrappers.DefaultIUnknownInterfaceDetailsStrategy + .GetIUnknownDerivedDetails(typeof(IDerivedExternalBase).TypeHandle); + + IIUnknownDerivedDetails derived2Details = StrategyBasedComWrappers.DefaultIUnknownInterfaceDetailsStrategy + .GetIUnknownDerivedDetails(typeof(IDerivedExternalBase2).TypeHandle); + + var numBaseMethods = typeof(IExternalBase).GetMethods().Length; + var numPointersToCompare = 3 + numBaseMethods; // IUnknown (3) + base methods + + // Both derived interfaces should have the same base vtable layout + var baseVTable = new ReadOnlySpan(baseDetails.ManagedVirtualMethodTable, numPointersToCompare); + var derived1BaseVTable = new ReadOnlySpan(derived1Details.ManagedVirtualMethodTable, numPointersToCompare); + var derived2BaseVTable = new ReadOnlySpan(derived2Details.ManagedVirtualMethodTable, numPointersToCompare); + + Assert.True(baseVTable.SequenceEqual(derived1BaseVTable), + "IDerivedExternalBase should have consistent base vtable layout"); + Assert.True(baseVTable.SequenceEqual(derived2BaseVTable), + "IDerivedExternalBase2 should have consistent base vtable layout"); + Assert.True(derived1BaseVTable.SequenceEqual(derived2BaseVTable), + "Both derived interfaces should have identical base vtable layouts"); + } + + [Fact] + public unsafe void CrossAssemblyInheritance_VTableLayoutIsCorrect() + { + IIUnknownDerivedDetails baseInterfaceDetails = StrategyBasedComWrappers.DefaultIUnknownInterfaceDetailsStrategy + .GetIUnknownDerivedDetails(typeof(IExternalBase).TypeHandle); + + IIUnknownDerivedDetails derivedInterfaceDetails = StrategyBasedComWrappers.DefaultIUnknownInterfaceDetailsStrategy + .GetIUnknownDerivedDetails(typeof(IDerivedExternalBase).TypeHandle); + + var numBaseMethods = typeof(IExternalBase).GetMethods().Length; + var numPointersToCompare = 3 + numBaseMethods; + + // The first part of the vtable should match between base and derived + var expectedBaseVTable = new ReadOnlySpan(baseInterfaceDetails.ManagedVirtualMethodTable, numPointersToCompare); + var actualDerivedVTable = new ReadOnlySpan(derivedInterfaceDetails.ManagedVirtualMethodTable, numPointersToCompare); + + Assert.True(expectedBaseVTable.SequenceEqual(actualDerivedVTable), + "Base interface methods should have the same vtable entries in derived interface"); + } + + [Fact] + public unsafe void IDerivedFromDerivedExternalDerived_VTableLayoutIsCorrect() + { + var baseDetails = StrategyBasedComWrappers.DefaultIUnknownInterfaceDetailsStrategy + .GetIUnknownDerivedDetails(typeof(IExternalBase).TypeHandle); + var externalDerivedDetails = StrategyBasedComWrappers.DefaultIUnknownInterfaceDetailsStrategy + .GetIUnknownDerivedDetails(typeof(IExternalDerived).TypeHandle); + var derivedFromExternalDerivedDetails = StrategyBasedComWrappers.DefaultIUnknownInterfaceDetailsStrategy + .GetIUnknownDerivedDetails(typeof(IDerivedFromExternalDerived).TypeHandle); + var deepDerivedDetails = StrategyBasedComWrappers.DefaultIUnknownInterfaceDetailsStrategy + .GetIUnknownDerivedDetails(typeof(IDerivedFromDerivedExternalDerived).TypeHandle); + + var baseMethods = typeof(IExternalBase).GetMethods().Length; + var baseVTableSize = 3 + baseMethods; + + var baseVTable = new ReadOnlySpan(baseDetails.ManagedVirtualMethodTable, baseVTableSize); + var externalDerivedBaseVTable = new ReadOnlySpan(externalDerivedDetails.ManagedVirtualMethodTable, baseVTableSize); + var derivedFromExternalDerivedBaseVTable = new ReadOnlySpan(derivedFromExternalDerivedDetails.ManagedVirtualMethodTable, baseVTableSize); + var deepDerivedBaseVTable = new ReadOnlySpan(deepDerivedDetails.ManagedVirtualMethodTable, baseVTableSize); + + Assert.True(baseVTable.SequenceEqual(externalDerivedBaseVTable), + "IExternalDerived should have consistent base vtable layout"); + Assert.True(baseVTable.SequenceEqual(derivedFromExternalDerivedBaseVTable), + "IDerivedFromExternalDerived should have consistent base vtable layout"); + Assert.True(baseVTable.SequenceEqual(deepDerivedBaseVTable), + "IDerivedFromDerivedExternalDerived should have consistent base vtable layout"); + + var externalDerivedMethods = typeof(IExternalDerived).GetMethods().Length; + var externalDerivedVTableSize = 3 + externalDerivedMethods; + + var externalDerivedVTable = new ReadOnlySpan(externalDerivedDetails.ManagedVirtualMethodTable, externalDerivedVTableSize); + var derivedFromExternalDerivedIntermediateVTable = new ReadOnlySpan(derivedFromExternalDerivedDetails.ManagedVirtualMethodTable, externalDerivedVTableSize); + var deepDerivedIntermediateVTable = new ReadOnlySpan(deepDerivedDetails.ManagedVirtualMethodTable, externalDerivedVTableSize); + + Assert.True(externalDerivedVTable.SequenceEqual(derivedFromExternalDerivedIntermediateVTable), + "IDerivedFromExternalDerived should have consistent IExternalDerived vtable layout"); + Assert.True(externalDerivedVTable.SequenceEqual(deepDerivedIntermediateVTable), + "IDerivedFromDerivedExternalDerived should have consistent IExternalDerived vtable layout"); + + var derivedFromExternalDerivedMethods = typeof(IDerivedFromExternalDerived).GetMethods().Length; + var derivedFromExternalDerivedVTableSize = 3 + derivedFromExternalDerivedMethods; + var derivedFromExternalDerivedVTable = new ReadOnlySpan(derivedFromExternalDerivedDetails.ManagedVirtualMethodTable, derivedFromExternalDerivedVTableSize); + var deepDerivedVTable = new ReadOnlySpan(deepDerivedDetails.ManagedVirtualMethodTable, derivedFromExternalDerivedVTableSize); + Assert.True(derivedFromExternalDerivedVTable.SequenceEqual(deepDerivedVTable), + "IDerivedFromDerivedExternalDerived should have consistent IDerivedFromExternalDerived vtable layout"); + } + } +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/IDerivedTests.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/IDerivedTests.cs index e457a287748bc3..476db4b2cdd285 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/IDerivedTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/IDerivedTests.cs @@ -13,6 +13,56 @@ namespace ComInterfaceGenerator.Tests { public partial class IDerivedTests { + [GeneratedComInterface] + [Guid("7F0DB364-3C04-4487-9193-4BB05DC7B654")] + internal partial interface IDerivedFromSharedType2 : SharedTypes.ComInterfaces.IGetAndSetInt + { + int GetTwoTimesInt(); + } + + [GeneratedComInterface] + [Guid("7F0DB364-3C04-4487-9194-4BB05DC7B654")] +#pragma warning disable SYSLIB1230 // Specifying 'GeneratedComInterfaceAttribute' on an interface that has a base interface defined in another assembly is not supported + internal partial interface IDerivedFromSharedType : SharedTypes.ComInterfaces.IGetAndSetInt +#pragma warning restore SYSLIB1230 + { + int GetIntPlusOne(); + } + + [GeneratedComClass] + [Guid("7F0DB364-3C04-4487-9195-4BB05DC7B654")] + internal partial class DerivedFromSharedTypeImpl : IDerivedFromSharedType, IDerivedFromSharedType2 + { + int _value = 42; + + public int GetInt() => _value; + public int GetIntPlusOne() => _value + 1; + public int GetTwoTimesInt() => _value * 2; + public void SetInt(int value) { _value = value; } + } + + [Fact] + public unsafe void TypesDerivedFromSharedTypeHaveCorrectVTableSize() + { + var managedSourceObject = new DerivedFromSharedTypeImpl(); + var cw = new StrategyBasedComWrappers(); + var nativeObj = cw.GetOrCreateComInterfaceForObject(managedSourceObject, CreateComInterfaceFlags.None); + object managedObj = cw.GetOrCreateObjectForComInstance(nativeObj, CreateObjectFlags.None); + IGetAndSetInt getAndSetInt = (IGetAndSetInt)managedObj; + IDerivedFromSharedType derivedFromSharedType = (IDerivedFromSharedType)managedObj; + IDerivedFromSharedType2 derivedFromSharedType2 = (IDerivedFromSharedType2)managedObj; + + Assert.Equal(42, getAndSetInt.GetInt()); + Assert.Equal(42, derivedFromSharedType.GetInt()); + Assert.Equal(42, derivedFromSharedType2.GetInt()); + + getAndSetInt.SetInt(100); + Assert.Equal(100, getAndSetInt.GetInt()); + Assert.Equal(101, derivedFromSharedType.GetIntPlusOne()); + Assert.Equal(200, derivedFromSharedType2.GetTwoTimesInt()); + } + + [Fact] public unsafe void DerivedInterfaceTypeProvidesBaseInterfaceUnmanagedToManagedMembers() { @@ -36,16 +86,16 @@ public unsafe void DerivedInterfaceTypeProvidesBaseInterfaceUnmanagedToManagedMe public unsafe void CallBaseInterfaceMethod_EnsureQiCalledOnce() { var cw = new SingleQIComWrapper(); - var derivedImpl = new DerivedImpl(); + var derivedImpl = new Derived(); var nativeObj = cw.GetOrCreateComInterfaceForObject(derivedImpl, CreateComInterfaceFlags.None); var obj = cw.GetOrCreateObjectForComInstance(nativeObj, CreateObjectFlags.None); IDerived iface = (IDerived)obj; - Assert.Equal(3, iface.GetInt()); + Assert.Equal(0, iface.GetInt()); iface.SetInt(5); Assert.Equal(5, iface.GetInt()); - Assert.Equal("myName", iface.GetName()); + Assert.Equal("hello", iface.GetName()); iface.SetName("updated"); Assert.Equal("updated", iface.GetName()); @@ -58,22 +108,6 @@ public unsafe void CallBaseInterfaceMethod_EnsureQiCalledOnce() Assert.Equal(1, countQi.QiCallCount); } - [GeneratedComClass] - partial class DerivedImpl : IDerived - { - int data = 3; - string myName = "myName"; - public void DoThingWithString(string name) => throw new NotImplementedException(); - - public int GetInt() => data; - - public string GetName() => myName; - - public void SetInt(int n) => data = n; - - public void SetName(string name) => myName = name; - } - /// /// Used to ensure that QI is only called once when calling base methods on a derived COM interface /// diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/INullArrayTests.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/INullArrayTests.cs new file mode 100644 index 00000000000000..dc92cc43ff2529 --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/INullArrayTests.cs @@ -0,0 +1,206 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; +using SharedTypes.ComInterfaces; +using SharedTypes; +using Xunit; +using System.Runtime.CompilerServices; + +namespace ComInterfaceGenerator.Tests +{ + /// + /// Tests for edge cases involving null arrays when their length parameters are non-zero. + /// This addresses https://github.com/dotnet/runtime/issues/118135 + /// + public unsafe partial class INullArrayTests + { + private static INullArrayCases CreateTestInterface() + { + INullArrayCases originalObject = new INullArrayCasesImpl(); + ComWrappers cw = new StrategyBasedComWrappers(); + nint ptr = cw.GetOrCreateComInterfaceForObject(originalObject, CreateComInterfaceFlags.None); + object obj = cw.GetOrCreateObjectForComInstance(ptr, CreateObjectFlags.None); + return (INullArrayCases)obj; + } + + [Theory] + [InlineData(0)] + [InlineData(10)] + [InlineData(int.MaxValue)] + public void SingleNullArray_DoesNotCrash(int length) + { + var testInterface = CreateTestInterface(); + + // Should not throw or crash + testInterface.SingleNullArrayWithLength(length, null); + } + + [Fact] + public void SingleNullArray_WithValidArray_WorksNormally() + { + var testInterface = CreateTestInterface(); + int[] array = new int[5]; + + testInterface.SingleNullArrayWithLength(5, array); + + Assert.Equal(new int[] { 0, 2, 4, 6, 8 }, array); + } + + [Fact] + public void MultipleArrays_SomeNull_DoesNotCrash() + { + var testInterface = CreateTestInterface(); + int[] array1 = new int[3]; + int[] array3 = new int[3]; + + testInterface.MultipleArraysSharedLength(3, array1, null, array3); + + Assert.Equal(new int[] { 0, 1, 2 }, array1); + Assert.Equal(new int[] { 0, 100, 200 }, array3); + } + + [Fact] + public void MultipleArrays_AllNull_DoesNotCrash() + { + var testInterface = CreateTestInterface(); + + testInterface.MultipleArraysSharedLength(5, null, null, null); + } + + [Theory] + [InlineData(0)] + [InlineData(10)] + [InlineData(int.MaxValue)] + public void NonBlittableArray_Null_DoesNotCrash(int length) + { + var testInterface = CreateTestInterface(); + + testInterface.NonBlittableNullArray(length, null); + } + + [Fact] + public void NonBlittableArray_ValidArray_WorksNormally() + { + var testInterface = CreateTestInterface(); + var array = new IntStructWrapper[3]; + + testInterface.NonBlittableNullArray(3, array); + + Assert.Equal(0, array[0].Value); + Assert.Equal(3, array[1].Value); + Assert.Equal(6, array[2].Value); + } + + [Theory] + [InlineData(0)] + [InlineData(10)] + [InlineData(int.MaxValue)] + public void SpanNull_DoesNotCrash(int length) + { + var testInterface = CreateTestInterface(); + + Span span = new Span(null, 0); + testInterface.SpanNullCase(length, ref span); + Assert.True(default == span); + } + + [Fact] + public void SpanValid_WorksNormally() + { + var testInterface = CreateTestInterface(); + + var span = new Span(new int[5]); + testInterface.SpanNullCase(5, ref span); + + Assert.Equal(0, span[0]); + Assert.Equal(5, span[1]); + Assert.Equal(10, span[2]); + Assert.Equal(15, span[3]); + Assert.Equal(20, span[4]); + } + + [Theory] + [InlineData(0)] + [InlineData(10)] + [InlineData(int.MaxValue)] + public void SpanNonBlittable_Null_DoesNotCrash(int length) + { + var testInterface = CreateTestInterface(); + Span span = new Span(null, 0); + testInterface.SpanNonBlittableNullCase(length, ref span); + Assert.True(default == span); + } + + [Fact] + public void SpanNonBlittable_Valid_WorksNormally() + { + var testInterface = CreateTestInterface(); + + var span = new Span(new IntStructWrapper[3]); + testInterface.SpanNonBlittableNullCase(3, ref span); + + Assert.Equal(0, span[0].Value); + Assert.Equal(7, span[1].Value); + Assert.Equal(14, span[2].Value); + } + + [Theory] + [InlineData(0)] + [InlineData(10)] + [InlineData(int.MaxValue)] + public void InputOnlyArray_Null_DoesNotCrash(int length) + { + var testInterface = CreateTestInterface(); + + testInterface.InOnlyNullArray(length, null); + } + + [Theory] + [InlineData(0)] + [InlineData(10)] + [InlineData(int.MaxValue)] + public void OutputOnlyArray_Null_DoesNotCrash(int length) + { + var testInterface = CreateTestInterface(); + + testInterface.OutOnlyNullArray(length, null); + } + + [Fact] + public void OutputOnlyArray_Valid_WorksNormally() + { + var testInterface = CreateTestInterface(); + var array = new int[3]; + + testInterface.OutOnlyNullArray(3, array); + + Assert.Equal(new int[] { 1000, 1001, 1002 }, array); + } + + [Theory] + [InlineData(0)] + [InlineData(10)] + [InlineData(int.MaxValue)] + public void ReferenceArray_Null_DoesNotCrash(int length) + { + var testInterface = CreateTestInterface(); + + testInterface.ReferenceArrayNullCase(length, null); + } + + [Fact] + public void ReferenceArray_ValidArray_WorksNormally() + { + var testInterface = CreateTestInterface(); + string[] array = new string[3]; + + testInterface.ReferenceArrayNullCase(3, array); + + Assert.Equal(new string[] { "Item 0", "Item 1", "Item 2" }, array); + } + } +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/Interfaces/IDerivedAcrossAssembly.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/Interfaces/IDerivedAcrossAssembly.cs new file mode 100644 index 00000000000000..89db66843c4dc9 --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/Interfaces/IDerivedAcrossAssembly.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; +using SharedTypes.ComInterfaces; + +[GeneratedComInterface(StringMarshalling = StringMarshalling.Utf16)] +[Guid("da8eed10-f3f4-42c3-86de-04f2dc56514e")] +#pragma warning disable SYSLIB1230 // Specifying 'GeneratedComInterfaceAttribute' on an interface that has a base interface defined in another assembly is not supported +internal partial interface IDerivedExternalBase : IExternalBase +#pragma warning restore SYSLIB1230 +{ + string GetName(); +} + +[GeneratedComInterface(StringMarshalling = StringMarshalling.Utf16)] +[Guid("c3d3990e-5b05-4a9b-adc4-58c521700ece")] +#pragma warning disable SYSLIB1230 // Specifying 'GeneratedComInterfaceAttribute' on an interface that has a base interface defined in another assembly is not supported +internal partial interface IDerivedExternalBase2 : IExternalBase +#pragma warning restore SYSLIB1230 +{ + string GetName(); +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/Interfaces/IDerivedFromDerivedAcrossAssembly.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/Interfaces/IDerivedFromDerivedAcrossAssembly.cs new file mode 100644 index 00000000000000..e28b68bd4cc033 --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/Interfaces/IDerivedFromDerivedAcrossAssembly.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; +using SharedTypes.ComInterfaces; + +[GeneratedComInterface(StringMarshalling = StringMarshalling.Utf16)] +[Guid("f252bddd-aac0-4004-acfd-b39f73fb9791")] +#pragma warning disable SYSLIB1230 // Specifying 'GeneratedComInterfaceAttribute' on an interface that has a base interface defined in another assembly is not supported +internal partial interface IDerivedFromExternalDerived : IExternalDerived +#pragma warning restore SYSLIB1230 +{ + string GetName(); +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/Interfaces/IDerivedFromDerivedExternalDerived.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/Interfaces/IDerivedFromDerivedExternalDerived.cs new file mode 100644 index 00000000000000..5cd88d06b2a93f --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/Interfaces/IDerivedFromDerivedExternalDerived.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; +using SharedTypes.ComInterfaces; + +[GeneratedComInterface(StringMarshalling = StringMarshalling.Utf16)] +[Guid("b158aaf2-85a3-40e7-805f-5797580a05f2")] +#pragma warning disable SYSLIB1230 // Specifying 'GeneratedComInterfaceAttribute' on an interface that has a base interface defined in another assembly is not supported +internal partial interface IDerivedFromDerivedExternalDerived : IDerivedFromExternalDerived +#pragma warning restore SYSLIB1230 +{ + float GetFloat(); +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/TargetSignatureTests.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/TargetSignatureTests.cs index 7c0ead99ba5f44..ea4c4c5904a2f2 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/TargetSignatureTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/TargetSignatureTests.cs @@ -8,8 +8,10 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.Testing; +using Microsoft.CodeAnalysis.Text; using Microsoft.Interop; using Xunit; @@ -317,7 +319,7 @@ public partial interface IComInterface using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; - + [GeneratedComInterface] [Guid("0A617667-4961-4F90-B74F-6DC368E9817A")] partial interface {|#1:IComInterface2|} : IComInterface @@ -342,6 +344,74 @@ await VerifyInvocationWithMultipleProjectsAsync( VerifyCS.DiagnosticWithArguments(GeneratorDiagnostics.BaseInterfaceDefinedInOtherAssembly, "IComInterface2", "IComInterface").WithLocation(1).WithSeverity(DiagnosticSeverity.Warning)); } + [Fact] + public async Task ComInterfacesInheritingFromTheSameInterfaceAcrossCompilationsCalculatesCorrectVTableIndex() + { + string baseSource = $$""" + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + using System.Runtime.InteropServices.Marshalling; + + [GeneratedComInterface] + [Guid("0A617667-4961-4F90-B74F-6DC368E98179")] + public partial interface IComInterface + { + void Method(); + } + """; + + string derivedSource = $$""" + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + using System.Runtime.InteropServices.Marshalling; + + [GeneratedComInterface] + [Guid("0A617667-4961-4F90-B74F-6DC368E9817A")] + internal partial interface {|#1:IComInterface2|} : IComInterface + { + void DerivedMethod(); + } + + [GeneratedComInterface] + [Guid("0951f7b7-a700-4de4-930e-0b1fbc4684a9")] + internal partial interface {|#2:IComInterface3|} : IComInterface + { + void DerivedMethod(); + } + """; + + await VerifyInvocationWithMultipleProjectsAsync( + derivedSource, + baseSource, + "IComInterface2", + "DerivedMethod", + (newComp, _) => + { + // Validate VTable sizes for interfaces inheriting from the same base + // IUnknown has 3 methods, IComInterface adds 1 method = 4 total + // Both IComInterface2 and IComInterface3 inherit from IComInterface and add 1 method each = 5 total + ValidateInterface("IComInterface2", 5); + ValidateInterface("IComInterface3", 5); + + void ValidateInterface(string name, int expectedVTableSize) + { + INamedTypeSymbol? userDefinedInterface = newComp.Assembly.GetTypeByMetadataName(name); + Assert.NotNull(userDefinedInterface); + ITypeSymbol vtableType = new ComInterfaceImplementationLocator().FindVTableStructType(newComp, userDefinedInterface); + int actualVTableSize = vtableType.GetMembers().OfType().Count(); + + if (expectedVTableSize != actualVTableSize) + { + Assert.Fail($"VTable size mismatch for {name}. Expected: {expectedVTableSize}, Actual: {actualVTableSize}. VTable structure:\n{vtableType.DeclaringSyntaxReferences[0].GetSyntax().SyntaxTree.GetText()}"); + } + + Assert.Equal(expectedVTableSize, actualVTableSize); + } + }, + VerifyCS.DiagnosticWithArguments(GeneratorDiagnostics.BaseInterfaceDefinedInOtherAssembly, "IComInterface2", "IComInterface").WithLocation(1).WithSeverity(DiagnosticSeverity.Warning), + VerifyCS.DiagnosticWithArguments(GeneratorDiagnostics.BaseInterfaceDefinedInOtherAssembly, "IComInterface3", "IComInterface").WithLocation(2).WithSeverity(DiagnosticSeverity.Warning)); + } + [Fact] public async Task ComInterfaceInheritingAcrossCompilationsChainInBaseCalculatesCorrectVTableIndex() { @@ -369,7 +439,7 @@ public partial interface IComInterface2 : IComInterface using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; - + [GeneratedComInterface] [Guid("0A617667-4961-4F90-B74F-6DC368E9817A")] partial interface {|#1:IComInterface3|} : IComInterface2 @@ -446,6 +516,84 @@ await VerifyInvocationWithMultipleProjectsAsync( VerifyCS.DiagnosticWithArguments(GeneratorDiagnostics.BaseInterfaceDefinedInOtherAssembly, "IComInterface2", "IComInterface").WithLocation(1).WithSeverity(DiagnosticSeverity.Warning)); } + [Fact] + public async Task ComInterfaceDeepInheritanceChainCalculatesCorrectVTableSizes() + { + string baseSource = $$""" + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + using System.Runtime.InteropServices.Marshalling; + + [GeneratedComInterface] + [Guid("0A617667-4961-4F90-B74F-6DC368E98179")] + public partial interface IComInterface + { + void BaseMethod(); + } + + [GeneratedComInterface] + [Guid("0A617667-4961-4F90-B74F-6DC368E98178")] + public partial interface IComInterface2 : IComInterface + { + void MiddleMethod(); + } + """; + + string derivedSource = $$""" + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + using System.Runtime.InteropServices.Marshalling; + + [GeneratedComInterface] + [Guid("0A617667-4961-4F90-B74F-6DC368E9817A")] + partial interface {|#1:IComInterface3|} : IComInterface2 + { + void DerivedMethod(); + } + + [GeneratedComInterface] + [Guid("0A617667-4961-4F90-B74F-6DC368E9817B")] + partial interface IComInterface4 : IComInterface3 + { + void DeepDerivedMethod(); + } + """; + + await VerifyInvocationWithMultipleProjectsAsync( + derivedSource, + baseSource, + "IComInterface4", + "DeepDerivedMethod", + (newComp, _) => + { + // Validate VTable sizes for deep inheritance chain + // IUnknown has 3 methods (QueryInterface=0, AddRef=1, Release=2) + // IComInterface: IUnknown (3) + BaseMethod (1) = 4 total + // IComInterface2: IComInterface (4) + MiddleMethod (1) = 5 total + // IComInterface3: IComInterface2 (5) + DerivedMethod (1) = 6 total + // IComInterface4: IComInterface3 (6) + DeepDerivedMethod (1) = 7 total + + ValidateInterface("IComInterface3", 6); + ValidateInterface("IComInterface4", 7); + + void ValidateInterface(string name, int expectedVTableSize) + { + INamedTypeSymbol? userDefinedInterface = newComp.Assembly.GetTypeByMetadataName(name); + Assert.NotNull(userDefinedInterface); + ITypeSymbol vtableType = new ComInterfaceImplementationLocator().FindVTableStructType(newComp, userDefinedInterface); + int actualVTableSize = vtableType.GetMembers().OfType().Count(); + + if (expectedVTableSize != actualVTableSize) + { + Assert.Fail($"VTable size mismatch for {name}. Expected: {expectedVTableSize}, Actual: {actualVTableSize}. VTable structure:\n{vtableType.DeclaringSyntaxReferences[0].GetSyntax().SyntaxTree.GetText()}"); + } + + Assert.Equal(expectedVTableSize, actualVTableSize); + } + }, + VerifyCS.DiagnosticWithArguments(GeneratorDiagnostics.BaseInterfaceDefinedInOtherAssembly, "IComInterface3", "IComInterface2").WithLocation(1).WithSeverity(DiagnosticSeverity.Warning)); + } + private static async Task VerifyInvocationWithMultipleProjectsAsync( string thisSource, string baseSource, @@ -581,6 +729,14 @@ public INamedTypeSymbol FindImplementationInterface(Compilation compilation, INa return (INamedTypeSymbol)iUnknownDerivedAttribute.AttributeClass!.TypeArguments[1]; } + + public ITypeSymbol FindVTableStructType(Compilation compilation, INamedTypeSymbol userDefinedInterface) + { + INamedTypeSymbol? implementationInterface = FindImplementationInterface(compilation, userDefinedInterface); + var vtableField = implementationInterface.GetMembers("Vtable").OfType().SingleOrDefault(); + Assert.NotNull(vtableField); + return vtableField.Type; + } } } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IArrayOfStatelessElements.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IArrayOfStatelessElements.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IArrayOfStatelessElements.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IArrayOfStatelessElements.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IBool.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IBool.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IBool.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IBool.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/ICustomStringMarshallingUtf16.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/ICustomStringMarshallingUtf16.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/ICustomStringMarshallingUtf16.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/ICustomStringMarshallingUtf16.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IDerived.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IDerived.cs similarity index 73% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IDerived.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IDerived.cs index f6cd4ff8afc55b..50ee6fbe2c2add 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IDerived.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IDerived.cs @@ -18,6 +18,15 @@ internal partial interface IDerived : IGetAndSetInt internal new const string IID = "7F0DB364-3C04-4487-9193-4BB05DC7B654"; } + [GeneratedComInterface] + [Guid("D38D8B40-54A4-4685-B048-D04E215E6A93")] + internal partial interface IDerivedBool : IBool + { + void SetName([MarshalUsing(typeof(Utf16StringMarshaller))] string name); + + [return: MarshalUsing(typeof(Utf16StringMarshaller))] + string GetName(); + } [GeneratedComClass] internal partial class Derived : GetAndSetInt, IDerived diff --git a/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IDerivedDerived.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IDerivedDerived.cs new file mode 100644 index 00000000000000..d5b6d4ee4850d9 --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IDerivedDerived.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; + +namespace SharedTypes.ComInterfaces +{ + [GeneratedComInterface] + [Guid(IID)] + internal partial interface IDerivedDerived : IDerived + { + void SetFloat(float name); + + float GetFloat(); + + internal new const string IID = "7F0DB364-3C04-4487-9193-4BB05DC7B654"; + } + + [GeneratedComClass] + internal partial class DerivedDerived : Derived, IDerivedDerived + { + float _data = 0; + public float GetFloat() => _data; + public void SetFloat(float name) => _data = name; + } +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IEmpty.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IEmpty.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IEmpty.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IEmpty.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IEnumUnknown.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IEnumUnknown.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IEnumUnknown.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IEnumUnknown.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IFloat.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IFloat.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IFloat.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IFloat.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IGetAndSetInt.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IGetAndSetInt.cs similarity index 99% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IGetAndSetInt.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IGetAndSetInt.cs index 3f1b18f34e9beb..42dbca1c0adbd4 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IGetAndSetInt.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IGetAndSetInt.cs @@ -17,6 +17,7 @@ internal partial interface IGetAndSetInt public const string IID = "2c3f9903-b586-46b1-881b-adfce9af47b1"; } + [GeneratedComClass] internal partial class GetAndSetInt : IGetAndSetInt { diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IGetIntArray.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IGetIntArray.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IGetIntArray.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IGetIntArray.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IHide.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IHide.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IHide.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IHide.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IInt.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IInt.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IInt.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IInt.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IIntArray.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IIntArray.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IIntArray.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IIntArray.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IInterface.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IInterface.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IInterface.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IInterface.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IJaggedIntArray.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IJaggedIntArray.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IJaggedIntArray.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IJaggedIntArray.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/INullArrayCases.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/INullArrayCases.cs new file mode 100644 index 00000000000000..ffa0f79bf06252 --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/INullArrayCases.cs @@ -0,0 +1,170 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; + +namespace SharedTypes.ComInterfaces +{ + [GeneratedComInterface] + [Guid("F8A2C5D1-9B7E-4A3C-8F5D-2E1B9C4A7F6E")] + internal partial interface INullArrayCases + { + // Basic case: single null array with non-zero length + void SingleNullArrayWithLength( + int length, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), In, Out] int[]? array); + + // Multiple arrays sharing same length, some null, some not + void MultipleArraysSharedLength( + int length, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), In, Out] int[]? array1, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), In, Out] int[]? array2, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), In, Out] int[]? array3); + + // Non-blittable types with null arrays + void NonBlittableNullArray( + int length, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), In, Out] IntStructWrapper[]? array); + + // Different parameter directions + void InOnlyNullArray( + int length, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), In] int[]? array); + + void OutOnlyNullArray( + int length, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Out] int[]? array); + + // Reference arrays with null (different from value type arrays) + void ReferenceArrayNullCase( + int length, + [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 0), In, Out] string[]? array); + + // Span with null cases (ContiguousCollectionMarshaller) + void SpanNullCase( + int length, + [MarshalUsing(CountElementName = nameof(length))] ref Span span); + + // Span with non-blittable types + void SpanNonBlittableNullCase( + int length, + [MarshalUsing(CountElementName = nameof(length))] ref Span span); + } + + [GeneratedComClass] + internal partial class INullArrayCasesImpl : INullArrayCases + { + public void SingleNullArrayWithLength(int length, int[]? array) + { + // Should handle null array gracefully regardless of length + if (array != null) + { + for (int i = 0; i < Math.Min(length, array.Length); i++) + { + array[i] = i * 2; + } + } + } + + public void MultipleArraysSharedLength(int length, int[]? array1, int[]? array2, int[]? array3) + { + // Should only process non-null arrays + if (array1 != null) + { + for (int i = 0; i < length; i++) + { + array1[i] = i; + } + } + if (array2 != null) + { + for (int i = 0; i < length; i++) + { + array2[i] = i * 10; + } + } + if (array3 != null) + { + for (int i = 0; i < length; i++) + { + array3[i] = i * 100; + } + } + } + + public void NonBlittableNullArray(int length, IntStructWrapper[]? array) + { + if (array != null) + { + for (int i = 0; i < length; i++) + { + array[i] = new IntStructWrapper { Value = i * 3 }; + } + } + } + + public void InOnlyNullArray(int length, int[]? array) + { + // Input-only: just read from array if not null + if (array != null) + { + int sum = 0; + for (int i = 0; i < length; i++) + { + sum += array[i]; + } + // Could store sum somewhere, but for test we just ensure no crash + } + } + + public void OutOnlyNullArray(int length, int[]? array) + { + // Output-only: write to array if not null + if (array != null) + { + for (int i = 0; i < length; i++) + { + array[i] = i + 1000; + } + } + } + + public void ReferenceArrayNullCase(int length, string[]? array) + { + if (array != null) + { + for (int i = 0; i < length; i++) + { + array[i] = $"Item {i}"; + } + } + } + + public void SpanNullCase(int length, ref Span span) + { + // Should handle empty/default span gracefully regardless of length + if (!span.IsEmpty) + { + for (int i = 0; i < length; i++) + { + span[i] = i * 5; + } + } + } + + public void SpanNonBlittableNullCase(int length, ref Span span) + { + // Should handle empty/default span gracefully regardless of length + if (!span.IsEmpty) + { + for (int i = 0; i < length; i++) + { + span[i] = new IntStructWrapper { Value = i * 7 }; + } + } + } + } +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IPointProvider.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IPointProvider.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IPointProvider.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IPointProvider.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IRefStrings.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IRefStrings.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IRefStrings.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IRefStrings.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/ISafeHandles.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/ISafeHandles.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/ISafeHandles.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/ISafeHandles.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulAllShapes.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulAllShapes.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulAllShapes.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulAllShapes.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulCallerAllocatedBuffer.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulCallerAllocatedBuffer.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulCallerAllocatedBuffer.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulCallerAllocatedBuffer.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulCollectionAllShapes.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulCollectionAllShapes.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulCollectionAllShapes.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulCollectionAllShapes.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulCollectionBlittableElement.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulCollectionBlittableElement.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulCollectionBlittableElement.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulCollectionBlittableElement.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulCollectionPinnableReference.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulCollectionPinnableReference.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulCollectionPinnableReference.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulCollectionPinnableReference.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulCollectionStatelessElement.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulCollectionStatelessElement.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulCollectionStatelessElement.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulCollectionStatelessElement.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulFinallyMarshalling.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulFinallyMarshalling.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulFinallyMarshalling.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulFinallyMarshalling.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulMarshalling.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulMarshalling.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulMarshalling.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulMarshalling.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulPinnedMarshalling.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulPinnedMarshalling.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulPinnedMarshalling.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatefulPinnedMarshalling.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessAllShapes.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessAllShapes.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessAllShapes.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessAllShapes.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCallerAllocateBufferMarshalling.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessCallerAllocateBufferMarshalling.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCallerAllocateBufferMarshalling.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessCallerAllocateBufferMarshalling.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCollectionAllShapes.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessCollectionAllShapes.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCollectionAllShapes.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessCollectionAllShapes.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCollectionBlittableElement.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessCollectionBlittableElement.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCollectionBlittableElement.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessCollectionBlittableElement.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCollectionCallerAllocatedBuffer.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessCollectionCallerAllocatedBuffer.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCollectionCallerAllocatedBuffer.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessCollectionCallerAllocatedBuffer.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCollectionPinnableReference.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessCollectionPinnableReference.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCollectionPinnableReference.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessCollectionPinnableReference.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCollectionStatelessElement.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessCollectionStatelessElement.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCollectionStatelessElement.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessCollectionStatelessElement.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessFinallyMarshalling.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessFinallyMarshalling.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessFinallyMarshalling.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessFinallyMarshalling.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessMarshalling.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessMarshalling.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessMarshalling.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessMarshalling.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessPinnableCollectionBlittableElements.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessPinnableCollectionBlittableElements.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessPinnableCollectionBlittableElements.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessPinnableCollectionBlittableElements.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessPinnedMarshalling.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessPinnedMarshalling.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessPinnedMarshalling.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStatelessPinnedMarshalling.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStringMarshallingOverride.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStringMarshallingOverride.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStringMarshallingOverride.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStringMarshallingOverride.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStringMarshallingOverrideDerived.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStringMarshallingOverrideDerived.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStringMarshallingOverrideDerived.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IStringMarshallingOverrideDerived.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/ISystem.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/ISystem.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/ISystem.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/ISystem.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IUTF16Marshalling.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IUTF16Marshalling.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IUTF16Marshalling.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IUTF16Marshalling.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IUTF8Marshalling.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IUTF8Marshalling.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IUTF8Marshalling.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/IUTF8Marshalling.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/ManagedComMethodFailureException.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/ManagedComMethodFailureException.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/ManagedComMethodFailureException.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/ManagedComMethodFailureException.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/MarshallingFails/ICollectionMarshallingFails.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/ICollectionMarshallingFails.cs similarity index 85% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/MarshallingFails/ICollectionMarshallingFails.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/ICollectionMarshallingFails.cs index 1c6513607d9056..0d331441e7dd9d 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/MarshallingFails/ICollectionMarshallingFails.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/ICollectionMarshallingFails.cs @@ -26,7 +26,7 @@ public void Set( } [GeneratedComClass] - internal partial class ICollectionMarshallingFailsImpl : ICollectionMarshallingFails + internal partial class ICollectionMarshallingFailsImpl : ICollectionMarshallingFails, ISupportErrorInfo { int[] _data = new[] { 1, 2, 3, 4, 5, 6, 7, 8 }; public int[] Get(out int size) @@ -43,5 +43,14 @@ public void Set(int[] value, int size) _data = new int[size]; value.CopyTo(_data, 0); } + + int ISupportErrorInfo.InterfaceSupportsErrorInfo(in Guid riid) + { + if (riid == typeof(ICollectionMarshallingFails).GUID) + { + return 0; // S_OK + } + return 1; // S_FALSE + } } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/MarshallingFails/IJaggedIntArrayMarshallingFails.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/IJaggedIntArrayMarshallingFails.cs similarity index 91% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/MarshallingFails/IJaggedIntArrayMarshallingFails.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/IJaggedIntArrayMarshallingFails.cs index 4da8802dff4079..1a4eda0dca222f 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/MarshallingFails/IJaggedIntArrayMarshallingFails.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/IJaggedIntArrayMarshallingFails.cs @@ -43,7 +43,7 @@ void Set( } [GeneratedComClass] - internal partial class IJaggedIntArrayMarshallingFailsImpl : IJaggedIntArrayMarshallingFails + internal partial class IJaggedIntArrayMarshallingFailsImpl : IJaggedIntArrayMarshallingFails, ISupportErrorInfo { int[][] _data = new int[][] { new int[] { 1, 2, 3 }, new int[] { 4, 5 }, new int[] { 6, 7, 8, 9 } }; int[] _widths = new int[] { 3, 2, 4 }; @@ -76,5 +76,14 @@ public void Set(int[][] array, int[] widths, int length) _data = array; _widths = widths; } + + int ISupportErrorInfo.InterfaceSupportsErrorInfo(in Guid riid) + { + if (riid == typeof(IJaggedIntArrayMarshallingFails).GUID) + { + return 0; // S_OK + } + return 1; // S_FALSE + } } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/MarshallingFails/IStringArrayMarshallingFails.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/IStringArrayMarshallingFails.cs similarity index 92% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/MarshallingFails/IStringArrayMarshallingFails.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/IStringArrayMarshallingFails.cs index 77afe03c85fddb..5492f147b137e2 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/MarshallingFails/IStringArrayMarshallingFails.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/IStringArrayMarshallingFails.cs @@ -28,7 +28,7 @@ internal partial interface IStringArrayMarshallingFails /// Implements IStringArrayMarshallingFails. /// [GeneratedComClass] - internal partial class IStringArrayMarshallingFailsImpl : IStringArrayMarshallingFails + internal partial class IStringArrayMarshallingFailsImpl : IStringArrayMarshallingFails, ISupportErrorInfo { public static string[] StartingStrings { get; } = new string[] { "Hello", "World", "Lorem", "Ipsum", "Dolor", "Sample", "Text", ".Net", "Interop", "string" }; private string[] _strings = StartingStrings; @@ -40,6 +40,15 @@ internal partial class IStringArrayMarshallingFailsImpl : IStringArrayMarshallin public void RefParam([MarshalUsing(ConstantElementCount = 10)] ref string[] value) => value[0] = _strings[0]; [return: MarshalUsing(ConstantElementCount = 10)] public string[] ReturnValue() => _strings; + + int ISupportErrorInfo.InterfaceSupportsErrorInfo(in Guid riid) + { + if (riid == typeof(IStringArrayMarshallingFails).GUID) + { + return 0; // S_OK + } + return 1; // S_FALSE + } } /// diff --git a/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/ISupportErrorInfo.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/ISupportErrorInfo.cs new file mode 100644 index 00000000000000..b34a824ab394b3 --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/ISupportErrorInfo.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; + +namespace SharedTypes.ComInterfaces.MarshallingFails +{ + [GeneratedComInterface] + [Guid("DF0B3D60-548F-101B-8E65-08002B2BD119")] + internal partial interface ISupportErrorInfo + { + [PreserveSig] + int InterfaceSupportsErrorInfo(in Guid riid); + } +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/MarshallingFails/MarshallingFailureException.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/MarshallingFailureException.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/MarshallingFails/MarshallingFailureException.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/MarshallingFailureException.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/MarshallingFails/ThrowOn4thElementMarshalled.cs b/src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/ThrowOn4thElementMarshalled.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/MarshallingFails/ThrowOn4thElementMarshalled.cs rename to src/libraries/System.Runtime.InteropServices/tests/Common/ComInterfaces/MarshallingFails/ThrowOn4thElementMarshalled.cs diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.Tests/ArrayTests.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.Tests/ArrayTests.cs index c0d7398b039c12..019dce5bc61dc6 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.Tests/ArrayTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.Tests/ArrayTests.cs @@ -112,6 +112,33 @@ public static partial BoolStruct[] NegateBools( [LibraryImport(NativeExportsNE_Binary, EntryPoint = "return_duplicate_int_ptr_array")] [return: MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] public static unsafe partial int*[] ReturnDuplicate(int*[] values, int numValues); + + // Null array edge case methods + [LibraryImport(NativeExportsNE_Binary, EntryPoint = "null_array_blittable_byval")] + public static partial int NullArrayBlittableByVal(int[] array, int length); + + [LibraryImport(NativeExportsNE_Binary, EntryPoint = "null_array_blittable_in")] + public static partial int NullArrayBlittableIn(in int[] array, int length); + + [LibraryImport(NativeExportsNE_Binary, EntryPoint = "null_array_blittable_ref")] + public static partial int NullArrayBlittableRef([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ref int[] array, int length); + + [LibraryImport(NativeExportsNE_Binary, EntryPoint = "null_array_blittable_out")] + public static partial int NullArrayBlittableOut(int length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] out int[] array); + + [LibraryImport(NativeExportsNE_Binary, EntryPoint = "null_array_nonblittable_byval")] + [return: MarshalAs(UnmanagedType.U1)] + public static partial bool NullArrayNonBlittableByVal(BoolStruct[] array, int length); + + [LibraryImport(NativeExportsNE_Binary, EntryPoint = "null_array_nonblittable_in")] + [return: MarshalAs(UnmanagedType.U1)] + public static partial bool NullArrayNonBlittableIn(in BoolStruct[] array, int length); + + [LibraryImport(NativeExportsNE_Binary, EntryPoint = "null_array_nonblittable_ref")] + public static partial void NullArrayNonBlittableRef([MarshalUsing(CountElementName = "length")] ref BoolStruct[] array, int length); + + [LibraryImport(NativeExportsNE_Binary, EntryPoint = "null_array_nonblittable_out")] + public static partial void NullArrayNonBlittableOut(int length, [MarshalUsing(CountElementName = "length")] out BoolStruct[] array); } } @@ -836,5 +863,198 @@ private static string ReverseChars(string value) Array.Reverse(chars); return new string(chars); } + + [Fact] + public void NullArrayBlittable_ByVal_WithNonZeroLength() + { + // Test null array with non-zero length parameter - should not crash + int[] nullArray = null; + int result = NativeExportsNE.Arrays.NullArrayBlittableByVal(nullArray, 5); + Assert.Equal(-1, result); // Native method should return -1 for null array + } + + [Fact] + public void NullArrayBlittable_ByVal_WithZeroLength() + { + // Test null array with zero length parameter - should work normally + int[] nullArray = null; + int result = NativeExportsNE.Arrays.NullArrayBlittableByVal(nullArray, 0); + Assert.Equal(-1, result); // Native method should return -1 for null array + } + + [Fact] + public void NullArrayBlittable_In_WithNonZeroLength() + { + // Test null array with 'in' parameter and non-zero length + int[] nullArray = null; + int result = NativeExportsNE.Arrays.NullArrayBlittableIn(nullArray, 3); + Assert.Equal(-1, result); // Native method should return -1 for null array + } + + [Fact] + public void NullArrayBlittable_In_WithZeroLength() + { + // Test null array with 'in' parameter and zero length + int[] nullArray = null; + int result = NativeExportsNE.Arrays.NullArrayBlittableIn(nullArray, 0); + Assert.Equal(-1, result); // Native method should return -1 for null array + } + + [Fact] + public void NullArrayBlittable_Ref_WithNonZeroLength() + { + // Test null array with 'ref' parameter and non-zero length + int[] nullArray = null; + int result = NativeExportsNE.Arrays.NullArrayBlittableRef(ref nullArray, 4); + Assert.Equal(-1, result); // Native method should return -1 for null array + Assert.Null(nullArray); // Array should remain null + } + + [Fact] + public void NullArrayBlittable_Ref_WithZeroLength() + { + // Test null array with 'ref' parameter and zero length + int[] nullArray = null; + int result = NativeExportsNE.Arrays.NullArrayBlittableRef(ref nullArray, 0); + Assert.Equal(-1, result); // Native method should return -1 for null array + Assert.Null(nullArray); // Array should remain null + } + + [Fact] + public void NullArrayBlittable_Out_WithNonZeroLength() + { + // Test 'out' parameter that should set array to null with non-zero length + int result = NativeExportsNE.Arrays.NullArrayBlittableOut(3, out int[] array); + Assert.Equal(0, result); // Native method should return 0 when setting null + Assert.Null(array); // Array should be null + } + + [Fact] + public void NullArrayBlittable_Out_WithZeroLength() + { + // Test 'out' parameter that should set array to null with zero length + int result = NativeExportsNE.Arrays.NullArrayBlittableOut(0, out int[] array); + Assert.Equal(0, result); // Native method should return 0 when setting null + Assert.Null(array); // Array should be null + } + + [Fact] + public void NullArrayNonBlittable_ByVal_WithNonZeroLength() + { + // Test null array with non-blittable elements and non-zero length + BoolStruct[] nullArray = null; + bool result = NativeExportsNE.Arrays.NullArrayNonBlittableByVal(nullArray, 2); + Assert.False(result); // Native method should return false for null array + } + + [Fact] + public void NullArrayNonBlittable_ByVal_WithZeroLength() + { + // Test null array with non-blittable elements and zero length + BoolStruct[] nullArray = null; + bool result = NativeExportsNE.Arrays.NullArrayNonBlittableByVal(nullArray, 0); + Assert.False(result); // Native method should return false for null array + } + + [Fact] + public void NullArrayNonBlittable_In_WithNonZeroLength() + { + // Test null array with 'in' parameter, non-blittable elements, and non-zero length + BoolStruct[] nullArray = null; + bool result = NativeExportsNE.Arrays.NullArrayNonBlittableIn(nullArray, 1); + Assert.False(result); // Native method should return false for null array + } + + [Fact] + public void NullArrayNonBlittable_In_WithZeroLength() + { + // Test null array with 'in' parameter, non-blittable elements, and zero length + BoolStruct[] nullArray = null; + bool result = NativeExportsNE.Arrays.NullArrayNonBlittableIn(nullArray, 0); + Assert.False(result); // Native method should return false for null array + } + + [Fact] + public void NullArrayNonBlittable_Ref_WithNonZeroLength() + { + // Test null array with 'ref' parameter, non-blittable elements, and non-zero length + BoolStruct[] nullArray = null; + NativeExportsNE.Arrays.NullArrayNonBlittableRef(ref nullArray, 2); + Assert.Null(nullArray); // Array should remain null + } + + [Fact] + public void NullArrayNonBlittable_Ref_WithZeroLength() + { + // Test null array with 'ref' parameter, non-blittable elements, and zero length + BoolStruct[] nullArray = null; + NativeExportsNE.Arrays.NullArrayNonBlittableRef(ref nullArray, 0); + Assert.Null(nullArray); // Array should remain null + } + + [Fact] + public void NullArrayNonBlittable_Out_WithNonZeroLength() + { + // Test 'out' parameter that should set array to null with non-zero length + NativeExportsNE.Arrays.NullArrayNonBlittableOut(1, out BoolStruct[] array); + Assert.Null(array); // Array should be null + } + + [Fact] + public void NullArrayNonBlittable_Out_WithZeroLength() + { + // Test 'out' parameter that should set array to null with zero length + NativeExportsNE.Arrays.NullArrayNonBlittableOut(0, out BoolStruct[] array); + Assert.Null(array); // Array should be null + } + + [Fact] + public void ValidArrayBlittable_WithNullArrayMethods() + { + // Test that valid arrays work correctly with our null array methods + int[] validArray = new[] { 1, 2, 3, 4, 5 }; + + // Test ByVal with valid array + int result = NativeExportsNE.Arrays.NullArrayBlittableByVal(validArray, validArray.Length); + Assert.Equal(15, result); // Sum should be 1+2+3+4+5 = 15 + + // Test In with valid array + result = NativeExportsNE.Arrays.NullArrayBlittableIn(validArray, validArray.Length); + Assert.Equal(15, result); // Sum should be 1+2+3+4+5 = 15 + + // Test Ref with valid array + result = NativeExportsNE.Arrays.NullArrayBlittableRef(ref validArray, validArray.Length); + Assert.Equal(15, result); // Sum should be 1+2+3+4+5 = 15 + Assert.NotNull(validArray); // Array should still be valid + } + + [Fact] + public void ValidArrayNonBlittable_WithNullArrayMethods() + { + // Test that valid arrays work correctly with our null array non-blittable methods + BoolStruct[] validArray = new[] + { + new BoolStruct { b1 = true, b2 = true, b3 = true }, + new BoolStruct { b1 = true, b2 = true, b3 = true } + }; + + // Test ByVal with valid array - should return true since all fields are true + bool result = NativeExportsNE.Arrays.NullArrayNonBlittableByVal(validArray, validArray.Length); + Assert.True(result); + + // Test In with valid array - should return true since all fields are true + result = NativeExportsNE.Arrays.NullArrayNonBlittableIn(validArray, validArray.Length); + Assert.True(result); + + // Test with array containing false values + BoolStruct[] mixedArray = new[] + { + new BoolStruct { b1 = true, b2 = true, b3 = true }, + new BoolStruct { b1 = true, b2 = false, b3 = true } // b2 is false + }; + + result = NativeExportsNE.Arrays.NullArrayNonBlittableByVal(mixedArray, mixedArray.Length); + Assert.False(result); // Should return false due to b2 being false + } } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.Tests/LibraryImportGenerator.Tests.csproj b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.Tests/LibraryImportGenerator.Tests.csproj index 47c6ab7ff8ed22..8e99f4edd9dc0c 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.Tests/LibraryImportGenerator.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.Tests/LibraryImportGenerator.Tests.csproj @@ -1,6 +1,8 @@ $(NetCoreAppCurrent) + + $(TargetRid) true true true diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CodeSnippets.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CodeSnippets.cs index 56eb1d52dbe1ee..3228bfc44ed64f 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CodeSnippets.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CodeSnippets.cs @@ -1438,5 +1438,93 @@ public Native(S s) public static string TypeUsage(string attr) => MarshalUsingParametersAndModifiers("S", "Marshaller", attr); } + + public const string ImproperCollectionWithMarshalUsingOnElements = """ + using System; + using System.Collections.Generic; + using System.Runtime.InteropServices; + using System.Runtime.InteropServices.Marshalling; + + class MyList + { + } + + class NotMyList {} + + class Example + { + public int Value; + } + + internal static partial class PInvoke + { + [LibraryImport("NativeLibrary", EntryPoint = "ProcessExample")] + public static partial int ProcessExample([MarshalUsing(typeof(ListMarshaller<,>), CountElementName = nameof(exampleCount)), MarshalUsing(typeof(ExampleMarshaller), ElementIndirectionDepth = 1)] MyList examples, ref int exampleCount); + } + + [ContiguousCollectionMarshaller] + [CustomMarshaller(typeof(MyList<>), MarshalMode.Default, typeof(ListMarshaller<,>.Marshaller))] + public unsafe static class ListMarshaller where TUnmanagedElement : unmanaged + { + public static class Marshaller + { + public static byte* AllocateContainerForUnmanagedElements(NotMyList managed, out int numElements) + { + numElements = default; + return default; + } + + public static ReadOnlySpan GetManagedValuesSource(NotMyList managed) + => default; + + public static Span GetUnmanagedValuesDestination(byte* unmanaged, int numElements) + => new Span((TUnmanagedElement*)unmanaged, numElements); + + public static List AllocateContainerForManagedElements(byte* unmanaged, int length) + => new List(length); + + public static Span GetManagedValuesDestination(NotMyList managed) + => default; + + public static ReadOnlySpan GetUnmanagedValuesSource(byte* nativeValue, int numElements) + => new ReadOnlySpan((TUnmanagedElement*)nativeValue, numElements); + + public static void Free(byte* unmanaged) + => NativeMemory.Free(unmanaged); + } + } + + [CustomMarshaller(typeof(Example), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToNative))] + [CustomMarshaller(typeof(Example), MarshalMode.ManagedToUnmanagedOut, typeof(ManagedToNativeOutFinally))] + static class ExampleMarshaller + { + public static class ManagedToNativeOutFinally + { + public static Example ConvertToManagedFinally(int managed) + { + return default; + } + + public static void Free(int unmanaged) + { + } + } + + public struct ManagedToNative + { + Example managed; + + public static int BufferSize => sizeof(int); + + public void FromManaged(Example managed, Span buffer) => this.managed = managed; + + public int ToUnmanaged() => managed.Value; + + public void OnInvoked() { } + + public void Free() { } + } + } + """; } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CompileFails.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CompileFails.cs index 605cd6b80386c5..952f8ef2890c81 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CompileFails.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CompileFails.cs @@ -57,6 +57,9 @@ public static IEnumerable CodeSnippetsToCompile() // Not LibraryImportAttribute yield return new object[] { ID(), CodeSnippets.UserDefinedPrefixedAttributes, Array.Empty() }; + // Bug: https://github.com/dotnet/runtime/issues/117448 + // yield return new[] { ID(), CodeSnippets.ImproperCollectionWithMarshalUsingOnElements }; + // No explicit marshalling for char or string yield return new object[] { ID(), CodeSnippets.BasicParametersAndModifiers(), new[] { diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulLinearCollectionShapeValidation.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulLinearCollectionShapeValidation.cs index e798e184b6bf76..bbc42b2f7a01de 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulLinearCollectionShapeValidation.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulLinearCollectionShapeValidation.cs @@ -22,9 +22,9 @@ public async Task ModeThatUsesManagedToUnmanagedShape_Missing_AllMethods_Reports { string source = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof({|#0:MarshallerType<>|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof({|#1:MarshallerType<>|}))] [ContiguousCollectionMarshaller] @@ -35,9 +35,9 @@ struct MarshallerType string fixedSource = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof(MarshallerType<>))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof(MarshallerType<>))] [ContiguousCollectionMarshaller] @@ -47,7 +47,7 @@ public void FromManaged(ManagedType managed) { throw new System.NotImplementedException(); } - + public nint ToUnmanaged() { throw new System.NotImplementedException(); @@ -88,9 +88,9 @@ public async Task ModeThatUsesManagedToUnmanagedShape_Missing_ContainerMethods_R { string source = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof({|#0:MarshallerType<>|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof({|#1:MarshallerType<>|}))] [ContiguousCollectionMarshaller] @@ -104,9 +104,9 @@ public void Free() {} string fixedSource = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof(MarshallerType<>))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof(MarshallerType<>))] [ContiguousCollectionMarshaller] @@ -115,12 +115,12 @@ struct MarshallerType public void FromManaged(ManagedType m) {} public nint ToUnmanaged() => default; public void Free() {} - + public System.ReadOnlySpan GetManagedValuesSource() { throw new System.NotImplementedException(); } - + public System.Span GetUnmanagedValuesDestination() { throw new System.NotImplementedException(); @@ -141,9 +141,9 @@ public async Task ModeThatUsesManagedToUnmanagedShape_Missing_GetManagedValuesSo string source = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof({|#0:MarshallerType<>|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof({|#1:MarshallerType<>|}))] [ContiguousCollectionMarshaller] @@ -159,9 +159,9 @@ public void Free() {} string fixedSource = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof(MarshallerType<>))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof(MarshallerType<>))] [ContiguousCollectionMarshaller] @@ -192,9 +192,9 @@ public async Task ModeThatUsesManagedToUnmanagedShape_Missing_GetUnmanagedValues string source = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof({|#0:MarshallerType<>|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof({|#1:MarshallerType<>|}))] [ContiguousCollectionMarshaller] @@ -210,9 +210,9 @@ public void Free() {} string fixedSource = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof(MarshallerType<>))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof(MarshallerType<>))] [ContiguousCollectionMarshaller] @@ -222,7 +222,7 @@ public void FromManaged(ManagedType m) {} public nint ToUnmanaged() => default; public void Free() {} public ReadOnlySpan GetManagedValuesSource() => default; - + public Span GetUnmanagedValuesDestination() { throw new NotImplementedException(); @@ -243,9 +243,9 @@ public async Task ModeThatUsesManagedToUnmanagedShape_DoesNotReportDiagnostic() string source = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof(MarshallerType<>))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof(MarshallerType<>))] [ContiguousCollectionMarshaller] @@ -270,9 +270,9 @@ public async Task ModeThatUsesManagedToUnmanagedShape_InvalidCollectionElementTy string source = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof({|#0:MarshallerType<>|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof({|#1:MarshallerType<>|}))] [ContiguousCollectionMarshaller] @@ -297,9 +297,9 @@ public async Task ModeThatUsesUnmanagedToManagedShape_Missing_AllMethods_Reports { string source = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof({|#0:MarshallerType<>|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof({|#1:MarshallerType<>|}))] [ContiguousCollectionMarshaller] @@ -310,9 +310,9 @@ struct MarshallerType string fixedSource = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof(MarshallerType<>))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof(MarshallerType<>))] [ContiguousCollectionMarshaller] @@ -327,17 +327,17 @@ public ManagedType ToManaged() { throw new System.NotImplementedException(); } - + public System.ReadOnlySpan GetUnmanagedValuesSource(int numElements) { throw new System.NotImplementedException(); } - + public System.Span GetManagedValuesDestination(int numElements) { throw new System.NotImplementedException(); } - + public void Free() { throw new System.NotImplementedException(); @@ -363,9 +363,9 @@ public async Task ModeThatUsesUnmanagedToManagedShape_Missing_ContainerMethods_R { string source = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof({|#0:MarshallerType<>|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof({|#1:MarshallerType<>|}))] [ContiguousCollectionMarshaller] @@ -379,9 +379,9 @@ public void Free() {} string fixedSource = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof(MarshallerType<>))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof(MarshallerType<>))] [ContiguousCollectionMarshaller] @@ -390,12 +390,12 @@ struct MarshallerType public void FromUnmanaged(int f) {} public ManagedType ToManaged() => default; public void Free() {} - + public System.ReadOnlySpan GetUnmanagedValuesSource(int numElements) { throw new System.NotImplementedException(); } - + public System.Span GetManagedValuesDestination(int numElements) { throw new System.NotImplementedException(); @@ -416,9 +416,9 @@ public async Task ModeThatUsesUnmanagedToManagedShape_Missing_GetUnmanagedValues string source = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof({|#0:MarshallerType<>|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof({|#1:MarshallerType<>|}))] [ContiguousCollectionMarshaller] @@ -434,9 +434,9 @@ public void Free() {} string fixedSource = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof(MarshallerType<>))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof(MarshallerType<>))] [ContiguousCollectionMarshaller] @@ -467,9 +467,9 @@ public async Task ModeThatUsesUnmanagedToManagedShape_Missing_GetManagedValuesDe string source = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof({|#0:MarshallerType<>|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof({|#1:MarshallerType<>|}))] [ContiguousCollectionMarshaller] @@ -485,9 +485,9 @@ public void Free() {} string fixedSource = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof(MarshallerType<>))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof(MarshallerType<>))] [ContiguousCollectionMarshaller] @@ -497,7 +497,7 @@ public void FromUnmanaged(int f) {} public ManagedType ToManaged() => default; public void Free() {} public ReadOnlySpan GetUnmanagedValuesSource(int numElements) => default; - + public Span GetManagedValuesDestination(int numElements) { throw new NotImplementedException(); @@ -518,9 +518,9 @@ public async Task ModeThatUsesUnmanagedToManagedShape_DoesNotReportDiagnostic() string source = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof(MarshallerType<>))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof(MarshallerType<>))] [ContiguousCollectionMarshaller] @@ -544,9 +544,9 @@ public async Task ModeThatUsesUnmanagedToManagedShape_InvalidCollectionElementTy string source = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof({|#0:MarshallerType<>|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof({|#1:MarshallerType<>|}))] [ContiguousCollectionMarshaller] @@ -572,9 +572,9 @@ public async Task CallerAllocatedBuffer_NoBufferSize_ReportsDiagnostic() string source = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof({|#0:MarshallerType<>|}))] [ContiguousCollectionMarshaller] struct MarshallerType @@ -590,9 +590,9 @@ public void Free() {} string fixedSource = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof(MarshallerType<>))] [ContiguousCollectionMarshaller] struct MarshallerType @@ -602,6 +602,7 @@ public void FromManaged(ManagedType m, Span buffer) {} public void Free() {} public ReadOnlySpan GetManagedValuesSource() => default; public Span GetUnmanagedValuesDestination() => default; + public static int BufferSize { get @@ -624,9 +625,9 @@ public async Task ModeThatUsesBidirectionalShape_DoesNotReportDiagnostic() string source = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedRef, typeof({|#0:MarshallerType<>|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedRef, typeof({|#1:MarshallerType<>|}))] [ContiguousCollectionMarshaller] @@ -653,9 +654,9 @@ public async Task ModeThatUsesBidirectionalShape_MismatchedManagedElementTypes_R string source = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedRef, typeof({|#0:MarshallerType<>|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedRef, typeof({|#1:MarshallerType<>|}))] [ContiguousCollectionMarshaller] @@ -684,7 +685,7 @@ public async Task ModeThatUsesBidirectionalShape_ArrayTarget_DoesNotReportDiagno string source = """ using System; using System.Runtime.InteropServices.Marshalling; - + [CustomMarshaller(typeof(CustomMarshallerAttribute.GenericPlaceholder[]), MarshalMode.ManagedToUnmanagedRef, typeof({|#0:MarshallerType<,>|}))] [CustomMarshaller(typeof(CustomMarshallerAttribute.GenericPlaceholder[]), MarshalMode.UnmanagedToManagedRef, typeof({|#1:MarshallerType<,>|}))] [ContiguousCollectionMarshaller] diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulValueShapeValidation.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulValueShapeValidation.cs index cb2c5d8caf10ec..89aeba8c926e5d 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulValueShapeValidation.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulValueShapeValidation.cs @@ -23,9 +23,9 @@ public async Task ModeThatUsesManagedToUnmanagedShape_Missing_AllMethods_Reports { string source = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof({|#0:MarshallerType|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof({|#1:MarshallerType|}))] struct MarshallerType @@ -35,9 +35,9 @@ struct MarshallerType string fixedSource = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof(MarshallerType))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof(MarshallerType))] struct MarshallerType @@ -75,9 +75,9 @@ public async Task ModeThatUsesUnmanagedToManagedShape_Missing_AllMethods_Reports { string source = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof({|#0:MarshallerType|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof({|#1:MarshallerType|}))] struct MarshallerType @@ -87,9 +87,9 @@ struct MarshallerType string fixedSource = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof(MarshallerType))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof(MarshallerType))] struct MarshallerType @@ -127,9 +127,9 @@ public async Task Overloaded_FromUnmanaged_ReportsDiagnostic() { string source = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof({|#0:MarshallerType|}))] struct MarshallerType { @@ -150,9 +150,9 @@ public async Task ModeThatUsesBidirectionalShape_Missing_AllMethods_ReportsDiagn { string source = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedRef, typeof({|#0:MarshallerType|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedRef, typeof({|#1:MarshallerType|}))] struct MarshallerType @@ -162,9 +162,9 @@ struct MarshallerType string fixedSource = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedRef, typeof(MarshallerType))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedRef, typeof(MarshallerType))] struct MarshallerType @@ -183,12 +183,12 @@ public void FromUnmanaged(nint unmanaged) { throw new System.NotImplementedException(); } - + public ManagedType ToManaged() { throw new System.NotImplementedException(); } - + public void Free() { throw new System.NotImplementedException(); @@ -216,9 +216,9 @@ public async Task ModeThatUsesBidirectionalShape_MismatchedUnmanagedTypes_Report { string source = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedRef, typeof({|#0:MarshallerType|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedRef, typeof({|#1:MarshallerType|}))] struct MarshallerType @@ -242,9 +242,9 @@ public async Task ModeThatUsesBidirectionalShape_DoesNotReportDiagnostic() { string source = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedRef, typeof(MarshallerType))] [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedRef, typeof(MarshallerType))] struct MarshallerType @@ -266,9 +266,9 @@ public async Task ModeThatUsesElementMode_ReportsDiagnostic() { string source = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ElementIn, typeof({|#0:MarshallerType|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.ElementRef, typeof({|#1:MarshallerType|}))] [CustomMarshaller(typeof(ManagedType), MarshalMode.ElementOut, typeof({|#2:MarshallerType|}))] @@ -294,9 +294,9 @@ public async Task DefaultMode_Missing_AllMethods_ReportsDiagnostic() { string source = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.Default, typeof({|#0:MarshallerType|}))] struct MarshallerType { @@ -305,9 +305,9 @@ struct MarshallerType string fixedSource = """ using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.Default, typeof(MarshallerType))] struct MarshallerType { @@ -315,7 +315,7 @@ public void FromManaged(ManagedType managed) { throw new System.NotImplementedException(); } - + public nint ToUnmanaged() { throw new System.NotImplementedException(); @@ -325,12 +325,12 @@ public void FromUnmanaged(nint unmanaged) { throw new System.NotImplementedException(); } - + public ManagedType ToManaged() { throw new System.NotImplementedException(); } - + public void Free() { throw new System.NotImplementedException(); @@ -354,9 +354,9 @@ public async Task CallerAllocatedBuffer_NoBufferSize_ReportsDiagnostic() string source = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof({|#0:MarshallerType|}))] struct MarshallerType { @@ -371,9 +371,9 @@ public void Free() {} string fixedSource = """ using System; using System.Runtime.InteropServices.Marshalling; - + class ManagedType {} - + [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof({|#0:MarshallerType|}))] struct MarshallerType { @@ -382,6 +382,7 @@ public void FromManaged(ManagedType m, Span b) {} public int ToUnmanaged() => default; public void Free() {} + public static int BufferSize { get diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessLinearCollectionShapeValidation.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessLinearCollectionShapeValidation.cs index b60bb78f2acc2b..fec16b2bc7ff7c 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessLinearCollectionShapeValidation.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessLinearCollectionShapeValidation.cs @@ -614,6 +614,7 @@ static class MarshallerType public static ReadOnlySpan GetManagedValuesSource(ManagedType m) => default; public static Span GetUnmanagedValuesDestination(nint unmanaged, int numElements) => default; + public static int BufferSize { get diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessValueShapeValidation.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessValueShapeValidation.cs index 35c90af32f81b2..7d94afb9985f79 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessValueShapeValidation.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessValueShapeValidation.cs @@ -363,6 +363,7 @@ class ManagedType {} static class MarshallerType { public static nint ConvertToUnmanaged(ManagedType m, Span b) => default; + public static int BufferSize { get diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj index 31369aaca2a4a3..acb1d91dae2d82 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System.Runtime.InteropServices.Tests.csproj @@ -160,6 +160,7 @@ + diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ArrayWithOffsetTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ArrayWithOffsetTests.cs index 34002d533071f6..7dc89847607acb 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ArrayWithOffsetTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ArrayWithOffsetTests.cs @@ -43,7 +43,7 @@ public void Ctor_MultidimensionalArray_ThrowsArgumentException() [InlineData(null, 1)] [InlineData(new int[] { 1 }, 5)] [InlineData(new int[] { 2 }, -1)] - public void Ctor_InvalidOffset_ThrowsIndexOutOfRangeException(object array, int offset) + public void Ctor_InvalidOffset_ThrowsIndexOutOfRangeException(object? array, int offset) { Assert.Throws(() => new ArrayWithOffset(array, offset)); } diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/BStrWrapperTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/BStrWrapperTests.cs index 6115d945a7d5a9..3d02b60da14405 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/BStrWrapperTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/BStrWrapperTests.cs @@ -10,7 +10,7 @@ public class BStrWrapperTests [Theory] [InlineData(null)] [InlineData("Value")] - public void Ctor_StringValue(string value) + public void Ctor_StringValue(string? value) { var wrapper = new BStrWrapper(value); Assert.Equal(value, wrapper.WrappedObject); @@ -19,7 +19,7 @@ public void Ctor_StringValue(string value) [Theory] [InlineData(null)] [InlineData("Value")] - public void Ctor_ObjectValue(object value) + public void Ctor_ObjectValue(object? value) { var wrapper = new BStrWrapper(value); Assert.Equal(value, wrapper.WrappedObject); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/CoClassAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/CoClassAttributeTests.cs index 6fa062a6c6f02c..6f3b6a5c5dc3ca 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/CoClassAttributeTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/CoClassAttributeTests.cs @@ -10,7 +10,7 @@ public class CoClassAttributeTests [Theory] [InlineData(null)] [InlineData(typeof(int))] - public void Ctor_CoClass(Type coClass) + public void Ctor_CoClass(Type? coClass) { var attribute = new CoClassAttribute(coClass); Assert.Equal(coClass, attribute.CoClass); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComAliasNameAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComAliasNameAttributeTests.cs index 19f9a20bd00a98..cfe2c38c5f0a56 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComAliasNameAttributeTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComAliasNameAttributeTests.cs @@ -26,7 +26,7 @@ public void Exists() [InlineData(null)] [InlineData("")] [InlineData("value")] - public void Ctor_Alias(string alias) + public void Ctor_Alias(string? alias) { var attribute = new ComAliasNameAttribute(alias); Assert.Equal(alias, attribute.Value); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComDefaultInterfaceAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComDefaultInterfaceAttributeTests.cs index 71e7848b6c27e5..0d8c930ea8bb14 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComDefaultInterfaceAttributeTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComDefaultInterfaceAttributeTests.cs @@ -10,7 +10,7 @@ public class ComDefaultInterfaceAttributeTests [Theory] [InlineData(null)] [InlineData(typeof(int))] - public void Ctor_DefaultInterface(Type defaultInterface) + public void Ctor_DefaultInterface(Type? defaultInterface) { var attribute = new ComDefaultInterfaceAttribute(defaultInterface); Assert.Equal(defaultInterface, attribute.Value); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComEventInterfaceAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComEventInterfaceAttributeTests.cs index 1bef996153287c..2fe79c8fa686b1 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComEventInterfaceAttributeTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComEventInterfaceAttributeTests.cs @@ -10,7 +10,7 @@ public class ComEventInterfaceAttributeTests [Theory] [InlineData(null, null)] [InlineData(typeof(int), typeof(string))] - public void Ctor_DefaultInterface(Type sourceInterface, Type eventProvider) + public void Ctor_DefaultInterface(Type? sourceInterface, Type? eventProvider) { var attribute = new ComEventInterfaceAttribute(sourceInterface, eventProvider); Assert.Equal(sourceInterface, attribute.SourceInterface); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComSourceInterfacesAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComSourceInterfacesAttributeTests.cs index 7b98247864f192..88b59aa6d2becc 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComSourceInterfacesAttributeTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComSourceInterfacesAttributeTests.cs @@ -10,7 +10,7 @@ public class ComSourceInterfacesAttributeTests [Theory] [InlineData(null)] [InlineData("SourceInterfaces")] - public void Ctor_SourceInterfaces(string sourceInterfaces) + public void Ctor_SourceInterfaces(string? sourceInterfaces) { var attribute = new ComSourceInterfacesAttribute(sourceInterfaces); Assert.Equal(sourceInterfaces, attribute.Value); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComVariantMarshallerTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComVariantMarshallerTests.cs index 4a9163d824588e..cb0760b7caec2b 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComVariantMarshallerTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ComVariantMarshallerTests.cs @@ -34,7 +34,7 @@ public void DBNull_Marshals_To_Null() [InlineData(null, VarEnum.VT_EMPTY)] // Null strings are _not_ BSTRs, compare to BStrWrapper. [InlineData("", VarEnum.VT_BSTR)] [InlineData("Hello", VarEnum.VT_BSTR)] - public void String_Marshals_To_BStr(string value, VarEnum expected) + public void String_Marshals_To_BStr(string? value, VarEnum expected) { ComVariant variant = ComVariantMarshaller.ConvertToUnmanaged(value); Assert.Equal(expected, variant.VarType); @@ -46,7 +46,7 @@ public void String_Marshals_To_BStr(string value, VarEnum expected) [InlineData(null)] [InlineData("")] [InlineData("Hello")] - public void BStrWrapper_Marshals_To_BStr(string value) + public void BStrWrapper_Marshals_To_BStr(string? value) { ComVariant variant = ComVariantMarshaller.ConvertToUnmanaged(new BStrWrapper(value)); Assert.Equal(VarEnum.VT_BSTR, variant.VarType); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/DefaultParameterValueAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/DefaultParameterValueAttributeTests.cs index 68255c14ef24a2..aa92527269cd27 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/DefaultParameterValueAttributeTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/DefaultParameterValueAttributeTests.cs @@ -14,7 +14,7 @@ public class DefaultParameterValueAttributeTests [InlineData(5.0f)] [InlineData("ExpectedValue")] [InlineData(null)] - public static void Ctor_Value(object value) + public static void Ctor_Value(object? value) { var attribute = new DefaultParameterValueAttribute(value); Assert.Equal(value, attribute.Value); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/DllImportAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/DllImportAttributeTests.cs index f664314669609f..fd55e737f77ca3 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/DllImportAttributeTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/DllImportAttributeTests.cs @@ -10,7 +10,7 @@ public class DllImportAttributeTests [Theory] [InlineData(null)] [InlineData("DllName")] - public void Ctor_SourceInterfaces(string dllName) + public void Ctor_SourceInterfaces(string? dllName) { var attribute = new DllImportAttribute(dllName); Assert.Equal(dllName, attribute.Value); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GuidAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GuidAttributeTests.cs index f5b3ea83123296..9d906e3d2a20d1 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GuidAttributeTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/GuidAttributeTests.cs @@ -10,7 +10,7 @@ public class GuidAttributeTests [Theory] [InlineData(null)] [InlineData("Guid")] - public void Ctor_Guid(string guid) + public void Ctor_Guid(string? guid) { var attribute = new GuidAttribute(guid); Assert.Equal(guid, attribute.Value); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/HandleCollectorTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/HandleCollectorTests.cs index 979867bc1efd7f..252049e9dbc795 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/HandleCollectorTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/HandleCollectorTests.cs @@ -15,7 +15,7 @@ public class HandleCollectorTests [InlineData(null, 0)] [InlineData("", 10)] [InlineData("InitialThreshold", int.MaxValue)] - public void Ctor_Name_InitialThreshold(string name, int initialThreshold) + public void Ctor_Name_InitialThreshold(string? name, int initialThreshold) { var handleCollector = new HandleCollector(name, initialThreshold); Assert.Equal(0, handleCollector.Count); @@ -28,7 +28,7 @@ public void Ctor_Name_InitialThreshold(string name, int initialThreshold) [InlineData(null, 0, 0)] [InlineData("", 10, 15)] [InlineData("InitialThreshold", 1, 2)] - public void Ctor_Name_InitialThreshold_MaximumThreshold(string name, int initialThreshold, int maximumThreshold) + public void Ctor_Name_InitialThreshold_MaximumThreshold(string? name, int initialThreshold, int maximumThreshold) { var handleCollector = new HandleCollector(name, initialThreshold, maximumThreshold); Assert.Equal(0, handleCollector.Count); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/HandleRefTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/HandleRefTests.cs index d5a6f2aa7df8a9..a14152b0cf3db6 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/HandleRefTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/HandleRefTests.cs @@ -20,7 +20,7 @@ public void Ctor_Default() [Theory] [InlineData(null, 0)] [InlineData("Wrapper", 1337)] - public void Ctor_Wrapper_Handle(object wrapper, int handle) + public void Ctor_Wrapper_Handle(object? wrapper, int handle) { var handleRef = new HandleRef(wrapper, (IntPtr)handle); Assert.Same(wrapper, handleRef.Wrapper); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ImportedFromTypeLibAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ImportedFromTypeLibAttributeTests.cs index 463b98487cbbc1..671ed27d0d7b0d 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ImportedFromTypeLibAttributeTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ImportedFromTypeLibAttributeTests.cs @@ -10,7 +10,7 @@ public class ImportedFromTypeLibAttributeTests [Theory] [InlineData(null)] [InlineData("Value")] - public void Ctor_TlbFile(string tlbFile) + public void Ctor_TlbFile(string? tlbFile) { var attribute = new ImportedFromTypeLibAttribute(tlbFile); Assert.Equal(tlbFile, attribute.Value); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/LibraryImportAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/LibraryImportAttributeTests.cs index 1ebda2c88832a8..20088c05261e66 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/LibraryImportAttributeTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/LibraryImportAttributeTests.cs @@ -10,7 +10,7 @@ public class LibraryImportAttributeTests [Theory] [InlineData(null)] [InlineData("LibraryName")] - public void Ctor(string libraryName) + public void Ctor(string? libraryName) { var attribute = new LibraryImportAttribute(libraryName); Assert.Equal(libraryName, attribute.LibraryName); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ManagedToNativeComInteropStubAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ManagedToNativeComInteropStubAttributeTests.cs index 70b375d5a1dc5c..4701562db44b01 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ManagedToNativeComInteropStubAttributeTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ManagedToNativeComInteropStubAttributeTests.cs @@ -10,7 +10,7 @@ public class ManagedToNativeComInteropStubAttributeTests [Theory] [InlineData(null, null)] [InlineData(typeof(int), "MethodName")] - public void Ctor_ClassType_MethodName(Type classType, string methodName) + public void Ctor_ClassType_MethodName(Type? classType, string? methodName) { var attribute = new ManagedToNativeComInteropStubAttribute(classType, methodName); Assert.Equal(classType, attribute.ClassType); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/BindToMonikerTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/BindToMonikerTests.cs index 1a4cfea3326138..87f5b83dc914bc 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/BindToMonikerTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/BindToMonikerTests.cs @@ -19,7 +19,7 @@ public void BindToMoniker_Unix_ThrowsPlatformNotSupportedException() [InlineData(null)] [InlineData("")] [InlineData("invalidName")] - public void BindToMoniker_InvalidArgument_ThrowsAnyException(string monikerName) + public void BindToMoniker_InvalidArgument_ThrowsAnyException(string? monikerName) { Assert.ThrowsAny(() => Marshal.BindToMoniker(monikerName)); } diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/ThrowExceptionForHRTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/ThrowExceptionForHRTests.cs index 68c87a4b8effb3..faa057cdc9d7ef 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/ThrowExceptionForHRTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/ThrowExceptionForHRTests.cs @@ -3,12 +3,13 @@ using System.Collections.Generic; using System.Reflection; +using System.Runtime.InteropServices.Marshalling; using Xunit; namespace System.Runtime.InteropServices.Tests { [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsNotNativeAot))] - public class ThrowExceptionForHRTests + public partial class ThrowExceptionForHRTests { [Theory] [ActiveIssue("https://github.com/mono/mono/issues/15093", TestRuntimes.Mono)] @@ -36,7 +37,7 @@ public void ThrowExceptionForHR_NoErrorInfo_ReturnsValidException(int errorCode) string sourceMaybe = "System.Private.CoreLib"; // If the ThrowExceptionForHR is inlined by the JIT, the source could be the test assembly - Assert.Contains(ex.Source, new string[]{ sourceMaybe, Assembly.GetExecutingAssembly().GetName().Name }); + Assert.Contains(ex.Source, new string[] { sourceMaybe, Assembly.GetExecutingAssembly().GetName().Name }); Assert.Contains(nameof(ThrowExceptionForHR_NoErrorInfo_ReturnsValidException), ex.StackTrace); Assert.Contains(nameof(Marshal.ThrowExceptionForHR), ex.TargetSite.Name); } @@ -77,7 +78,7 @@ public void ThrowExceptionForHR_ErrorInfo_ReturnsValidException(int errorCode, I string sourceMaybe = "System.Private.CoreLib"; // If the ThrowExceptionForHR is inlined by the JIT, the source could be the test assembly - Assert.Contains(ex.Source, new string[]{ sourceMaybe, Assembly.GetExecutingAssembly().GetName().Name }); + Assert.Contains(ex.Source, new string[] { sourceMaybe, Assembly.GetExecutingAssembly().GetName().Name }); Assert.Contains(nameof(ThrowExceptionForHR_ErrorInfo_ReturnsValidException), ex.StackTrace); Assert.Contains(nameof(Marshal.ThrowExceptionForHR), ex.TargetSite.Name); } @@ -94,6 +95,38 @@ public void ThrowExceptionForHR_InvalidHR_Nop(int errorCode) Marshal.ThrowExceptionForHR(errorCode, IntPtr.Zero); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltInComEnabled))] + public void ThrowExceptionForHR_BasedOnISupportErrorInfo() + { + var comWrappers = new StrategyBasedComWrappers(); + Guid iid = new Guid("999b8152-1e6f-4166-8b35-ac89475e96fa"); + var obj = new ConditionallySupportErrorInfo(iid); + IntPtr pUnk = comWrappers.GetOrCreateComInterfaceForObject(obj, CreateComInterfaceFlags.None); + try + { + var exception = new InvalidOperationException(); + ClearCurrentIErrorInfo(); + + // Set the error info for the current thread to the exception. + _ = Marshal.GetHRForException(exception); + + // The HResult from the IErrorInfo is used because the ISupportErrorInfo interface returned S_OK for the provided iid. + Assert.IsType(Marshal.GetExceptionForHR(new ArgumentException().HResult, iid, pUnk)); + + // Set the error info for the current thread to the exception. + _ = Marshal.GetHRForException(exception); + + var otherIid = new Guid("65af44f4-fd4f-4a35-a6f5-a0c66878fa75"); + + // The HResult from the IErrorInfo is ignored because the ISupportErrorInfo interface returned S_FALSE for the provided otherIid. + Assert.IsType(Marshal.GetExceptionForHR(new ArgumentException().HResult, otherIid, pUnk)); + } + finally + { + Marshal.Release(pUnk); + } + } + private static void ClearCurrentIErrorInfo() { // Ensure that if the thread's current IErrorInfo @@ -101,5 +134,22 @@ private static void ClearCurrentIErrorInfo() // to interpreting the HRESULT. Marshal.GetExceptionForHR(unchecked((int)0x80040001)); } + + [GeneratedComClass] + internal sealed partial class ConditionallySupportErrorInfo(Guid iid) : ISupportErrorInfo + { + public int InterfaceSupportsErrorInfo(in Guid riid) + { + return iid == riid ? 0 : 1; // S_OK or S_FALSE + } + } + + [GeneratedComInterface] + [Guid("DF0B3D60-548F-101B-8E65-08002B2BD119")] + internal partial interface ISupportErrorInfo + { + [PreserveSig] + int InterfaceSupportsErrorInfo(in Guid riid); + } } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ProgIdAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ProgIdAttributeTests.cs index b61fa92d7eb8a4..12817ba34e0510 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ProgIdAttributeTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/ProgIdAttributeTests.cs @@ -19,7 +19,7 @@ public void Exists() [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltInComEnabled))] [InlineData(null)] [InlineData("ProgId")] - public void Ctor_ProgId(string progId) + public void Ctor_ProgId(string? progId) { var attribute = new ProgIdAttribute(progId); Assert.Equal(progId, attribute.Value); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/StandardOleMarshalObjectTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/StandardOleMarshalObjectTests.cs new file mode 100644 index 00000000000000..a09ca6a14c9595 --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/StandardOleMarshalObjectTests.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Runtime.InteropServices.Tests +{ + [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltInComEnabled))] + public class StandardOleMarshalObjectTests + { + private static readonly Guid IID_IDispatch = new Guid("00020400-0000-0000-C000-000000000046"); + [Fact] + public void CanGetIDispatchOfDerivedObject() + { + IntPtr disp = Marshal.GetIDispatchForObject(new DerivedObject()); + Assert.NotEqual(IntPtr.Zero, disp); + Marshal.Release(disp); + } + + [Fact] + public void CanQueryInterfaceForIDispatchOfDerivedObject() + { + IntPtr unk = Marshal.GetIUnknownForObject(new DerivedObject()); + Assert.NotEqual(IntPtr.Zero, unk); + + int hr = Marshal.QueryInterface(unk, IID_IDispatch, out IntPtr disp); + Assert.Equal(0, hr); + Assert.NotEqual(IntPtr.Zero, disp); + + Marshal.Release(disp); + Marshal.Release(unk); + } + + [ComVisible(true)] + public sealed class DerivedObject : StandardOleMarshalObject + { + } + } +} \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/TypeIdentifierAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/TypeIdentifierAttributeTests.cs index c2c9d56c5408f2..d58df203a04951 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/TypeIdentifierAttributeTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/TypeIdentifierAttributeTests.cs @@ -18,7 +18,7 @@ public void Ctor_Default() [Theory] [InlineData(null, null)] [InlineData("scope", "identifier")] - public void Ctor_Scope_Identifier(string scope, string identifier) + public void Ctor_Scope_Identifier(string? scope, string? identifier) { var attribute = new TypeIdentifierAttribute(scope, identifier); Assert.Equal(scope, attribute.Scope); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/UnknownWrapperTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/UnknownWrapperTests.cs index ba50559dc11a76..d2cb84945ca066 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/UnknownWrapperTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/UnknownWrapperTests.cs @@ -11,7 +11,7 @@ public class UnknownWrapperTests [InlineData(null)] [InlineData(1)] [InlineData("Value")] - public void Ctor_Value(object value) + public void Ctor_Value(object? value) { var wrapper = new UnknownWrapper(value); Assert.Equal(value, wrapper.WrappedObject); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/VariantWrapperTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/VariantWrapperTests.cs index 2100c665b5a811..f07af78ceae77a 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/VariantWrapperTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/VariantWrapperTests.cs @@ -11,7 +11,7 @@ public class VariantWrappedTests [InlineData(null)] [InlineData(1)] [InlineData("Value")] - public void Ctor_Value(object value) + public void Ctor_Value(object? value) { var wrapper = new VariantWrapper(value); Assert.Equal(value, wrapper.WrappedObject); diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/Arrays.cs b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/Arrays.cs index dea37b2a7e27df..fe30dd7a0033a6 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/Arrays.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/Arrays.cs @@ -440,5 +440,128 @@ public static void NegateBoolStructsOut2D( *numValues = newStrings.Count; return res; } + + // Null array edge case methods for LibraryImportGenerator tests + [UnmanagedCallersOnly(EntryPoint = "null_array_blittable_byval")] + public static int NullArrayBlittableByVal(int* array, int length) + { + if (array == null) + { + return -1; + } + + // If not null, sum the array elements + int sum = 0; + for (int i = 0; i < length; i++) + { + sum += array[i]; + } + return sum; + } + + [UnmanagedCallersOnly(EntryPoint = "null_array_blittable_in")] + public static int NullArrayBlittableIn(int** array, int length) + { + if (*array == null) + { + return -1; + } + + // If not null, sum the array elements + int sum = 0; + for (int i = 0; i < length; i++) + { + sum += (*array)[i]; + } + return sum; + } + + [UnmanagedCallersOnly(EntryPoint = "null_array_blittable_ref")] + public static int NullArrayBlittableRef(int** array, int length) + { + if (*array == null) + { + return -1; + } + + // If not null, sum the array elements + int sum = 0; + for (int i = 0; i < length; i++) + { + sum += (*array)[i]; + } + return sum; + } + + [UnmanagedCallersOnly(EntryPoint = "null_array_blittable_out")] + public static int NullArrayBlittableOut(int length, int** array) + { + // Always set the output array to null for testing purposes + *array = null; + return 0; + } + + [UnmanagedCallersOnly(EntryPoint = "null_array_nonblittable_byval")] + [DNNE.C99DeclCode("struct bool_struct;")] + public static byte NullArrayNonBlittableByVal([DNNE.C99Type("struct bool_struct*")] BoolStructMarshaller.BoolStructNative* array, int length) + { + if (array == null) + { + return 0; // false + } + + // If not null, check if all members are true + for (int i = 0; i < length; i++) + { + BoolStruct managed = BoolStructMarshaller.ConvertToManaged(array[i]); + if (!managed.b1 || !managed.b2 || !managed.b3) + { + return 0; // false + } + } + return 1; // true + } + + [UnmanagedCallersOnly(EntryPoint = "null_array_nonblittable_in")] + [DNNE.C99DeclCode("struct bool_struct;")] + public static byte NullArrayNonBlittableIn([DNNE.C99Type("struct bool_struct**")] BoolStructMarshaller.BoolStructNative** array, int length) + { + if (*array == null) + { + return 0; // false + } + + // If not null, check if all members are true + for (int i = 0; i < length; i++) + { + BoolStruct managed = BoolStructMarshaller.ConvertToManaged((*array)[i]); + if (!managed.b1 || !managed.b2 || !managed.b3) + { + return 0; // false + } + } + return 1; // true + } + + [UnmanagedCallersOnly(EntryPoint = "null_array_nonblittable_ref")] + [DNNE.C99DeclCode("struct bool_struct;")] + public static void NullArrayNonBlittableRef([DNNE.C99Type("struct bool_struct**")] BoolStructMarshaller.BoolStructNative** array, int length) + { + // For testing purposes, just check if array is null and leave it as is + if (*array == null) + { + return; + } + + // If not null, we could do some operation, but for null testing we'll just return + } + + [UnmanagedCallersOnly(EntryPoint = "null_array_nonblittable_out")] + [DNNE.C99DeclCode("struct bool_struct;")] + public static void NullArrayNonBlittableOut(int length, [DNNE.C99Type("struct bool_struct**")] BoolStructMarshaller.BoolStructNative** array) + { + // Always set the output array to null for testing purposes + *array = null; + } } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/NativeExports.csproj b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/NativeExports.csproj index 5f4996e2f699af..f34b39521b7ac5 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/NativeExports.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/NativeExports.csproj @@ -20,7 +20,7 @@ - + diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/BaseInterfaces/IBaseDifferentAssembly.cs b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/BaseInterfaces/IBaseDifferentAssembly.cs new file mode 100644 index 00000000000000..0a02d9e1c6bc1b --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/BaseInterfaces/IBaseDifferentAssembly.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; + +namespace SharedTypes.ComInterfaces +{ + [GeneratedComInterface] + [Guid(IID)] + public partial interface IExternalBase + { + public int GetInt(); + public void SetInt(int x); + public const string IID = "2c3f9903-b586-46b1-881b-adfce9af47b1"; + } +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/BaseInterfaces/IDerivedDifferentAssembly.cs b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/BaseInterfaces/IDerivedDifferentAssembly.cs new file mode 100644 index 00000000000000..bb3d6b431b3210 --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/BaseInterfaces/IDerivedDifferentAssembly.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; + +namespace SharedTypes.ComInterfaces +{ + [GeneratedComInterface] + [Guid(IID)] + public partial interface IExternalDerived : IExternalBase + { + [return: MarshalAs(UnmanagedType.Bool)] + bool GetBool(); + public void SetBool([MarshalAs(UnmanagedType.Bool)] bool x); + new public const string IID = "594DF2B9-66CE-490D-9D05-34646675B188"; + } +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/SharedTypes.csproj b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/SharedTypes.csproj index 790a5e3f05a366..c68eadac7ca4b4 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/SharedTypes.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/SharedTypes.csproj @@ -11,8 +11,6 @@ - - diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index a36182d8a1d0cd..a4fd8d42365efd 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -5348,12 +5348,12 @@ internal Arm64() { } public static unsafe System.Numerics.Vector LoadVector128AndReplicateToVector(System.Numerics.Vector mask, ushort* address) { throw null; } public static unsafe System.Numerics.Vector LoadVector128AndReplicateToVector(System.Numerics.Vector mask, uint* address) { throw null; } public static unsafe System.Numerics.Vector LoadVector128AndReplicateToVector(System.Numerics.Vector mask, ulong* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorByteNonFaultingZeroExtendToInt16(byte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorByteNonFaultingZeroExtendToInt32(byte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorByteNonFaultingZeroExtendToInt64(byte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorByteNonFaultingZeroExtendToUInt16(byte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorByteNonFaultingZeroExtendToUInt32(byte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorByteNonFaultingZeroExtendToUInt64(byte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorByteNonFaultingZeroExtendToInt16(System.Numerics.Vector mask, byte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorByteNonFaultingZeroExtendToInt32(System.Numerics.Vector mask, byte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorByteNonFaultingZeroExtendToInt64(System.Numerics.Vector mask, byte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorByteNonFaultingZeroExtendToUInt16(System.Numerics.Vector mask, byte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorByteNonFaultingZeroExtendToUInt32(System.Numerics.Vector mask, byte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorByteNonFaultingZeroExtendToUInt64(System.Numerics.Vector mask, byte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendFirstFaulting(System.Numerics.Vector mask, byte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendFirstFaulting(System.Numerics.Vector mask, byte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendFirstFaulting(System.Numerics.Vector mask, byte* address) { throw null; } @@ -5366,10 +5366,10 @@ internal Arm64() { } public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendToUInt16(System.Numerics.Vector mask, byte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendToUInt32(System.Numerics.Vector mask, byte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendToUInt64(System.Numerics.Vector mask, byte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorInt16NonFaultingSignExtendToInt32(short* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorInt16NonFaultingSignExtendToInt64(short* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorInt16NonFaultingSignExtendToUInt32(short* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorInt16NonFaultingSignExtendToUInt64(short* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorInt16NonFaultingSignExtendToInt32(System.Numerics.Vector mask, short* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorInt16NonFaultingSignExtendToInt64(System.Numerics.Vector mask, short* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorInt16NonFaultingSignExtendToUInt32(System.Numerics.Vector mask, short* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorInt16NonFaultingSignExtendToUInt64(System.Numerics.Vector mask, short* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, short* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, short* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, short* address) { throw null; } @@ -5378,22 +5378,22 @@ internal Arm64() { } public static unsafe System.Numerics.Vector LoadVectorInt16SignExtendToInt64(System.Numerics.Vector mask, short* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorInt16SignExtendToUInt32(System.Numerics.Vector mask, short* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorInt16SignExtendToUInt64(System.Numerics.Vector mask, short* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorInt32NonFaultingSignExtendToInt64(int* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorInt32NonFaultingSignExtendToUInt64(int* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorInt32NonFaultingSignExtendToInt64(System.Numerics.Vector mask, int* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorInt32NonFaultingSignExtendToUInt64(System.Numerics.Vector mask, int* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorInt32SignExtendFirstFaulting(System.Numerics.Vector mask, int* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorInt32SignExtendFirstFaulting(System.Numerics.Vector mask, int* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorInt32SignExtendToInt64(System.Numerics.Vector mask, int* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorInt32SignExtendToUInt64(System.Numerics.Vector mask, int* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorNonFaulting(byte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorNonFaulting(double* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorNonFaulting(short* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorNonFaulting(int* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorNonFaulting(long* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorNonFaulting(sbyte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorNonFaulting(float* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorNonFaulting(ushort* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorNonFaulting(uint* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorNonFaulting(ulong* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorNonFaulting(System.Numerics.Vector mask, byte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorNonFaulting(System.Numerics.Vector mask, double* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorNonFaulting(System.Numerics.Vector mask, short* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorNonFaulting(System.Numerics.Vector mask, int* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorNonFaulting(System.Numerics.Vector mask, long* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorNonFaulting(System.Numerics.Vector mask, sbyte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorNonFaulting(System.Numerics.Vector mask, float* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorNonFaulting(System.Numerics.Vector mask, ushort* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorNonFaulting(System.Numerics.Vector mask, uint* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorNonFaulting(System.Numerics.Vector mask, ulong* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorNonTemporal(System.Numerics.Vector mask, byte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorNonTemporal(System.Numerics.Vector mask, double* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorNonTemporal(System.Numerics.Vector mask, short* address) { throw null; } @@ -5414,12 +5414,12 @@ internal Arm64() { } public static unsafe System.Numerics.Vector LoadVectorFirstFaulting(System.Numerics.Vector mask, ushort* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorFirstFaulting(System.Numerics.Vector mask, uint* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorFirstFaulting(System.Numerics.Vector mask, ulong* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorSByteNonFaultingSignExtendToInt16(sbyte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorSByteNonFaultingSignExtendToInt32(sbyte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorSByteNonFaultingSignExtendToInt64(sbyte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorSByteNonFaultingSignExtendToUInt16(sbyte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorSByteNonFaultingSignExtendToUInt32(sbyte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorSByteNonFaultingSignExtendToUInt64(sbyte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorSByteNonFaultingSignExtendToInt16(System.Numerics.Vector mask, sbyte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorSByteNonFaultingSignExtendToInt32(System.Numerics.Vector mask, sbyte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorSByteNonFaultingSignExtendToInt64(System.Numerics.Vector mask, sbyte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorSByteNonFaultingSignExtendToUInt16(System.Numerics.Vector mask, sbyte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorSByteNonFaultingSignExtendToUInt32(System.Numerics.Vector mask, sbyte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorSByteNonFaultingSignExtendToUInt64(System.Numerics.Vector mask, sbyte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, sbyte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, sbyte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, sbyte* address) { throw null; } @@ -5432,10 +5432,10 @@ internal Arm64() { } public static unsafe System.Numerics.Vector LoadVectorSByteSignExtendToUInt16(System.Numerics.Vector mask, sbyte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorSByteSignExtendToUInt32(System.Numerics.Vector mask, sbyte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorSByteSignExtendToUInt64(System.Numerics.Vector mask, sbyte* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorUInt16NonFaultingZeroExtendToInt32(ushort* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorUInt16NonFaultingZeroExtendToInt64(ushort* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorUInt16NonFaultingZeroExtendToUInt32(ushort* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorUInt16NonFaultingZeroExtendToUInt64(ushort* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorUInt16NonFaultingZeroExtendToInt32(System.Numerics.Vector mask, ushort* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorUInt16NonFaultingZeroExtendToInt64(System.Numerics.Vector mask, ushort* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorUInt16NonFaultingZeroExtendToUInt32(System.Numerics.Vector mask, ushort* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorUInt16NonFaultingZeroExtendToUInt64(System.Numerics.Vector mask, ushort* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorUInt16ZeroExtendFirstFaulting(System.Numerics.Vector mask, ushort* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorUInt16ZeroExtendFirstFaulting(System.Numerics.Vector mask, ushort* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorUInt16ZeroExtendFirstFaulting(System.Numerics.Vector mask, ushort* address) { throw null; } @@ -5444,8 +5444,8 @@ internal Arm64() { } public static unsafe System.Numerics.Vector LoadVectorUInt16ZeroExtendToInt64(System.Numerics.Vector mask, ushort* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorUInt16ZeroExtendToUInt32(System.Numerics.Vector mask, ushort* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorUInt16ZeroExtendToUInt64(System.Numerics.Vector mask, ushort* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorUInt32NonFaultingZeroExtendToInt64(uint* address) { throw null; } - public static unsafe System.Numerics.Vector LoadVectorUInt32NonFaultingZeroExtendToUInt64(uint* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorUInt32NonFaultingZeroExtendToInt64(System.Numerics.Vector mask, uint* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorUInt32NonFaultingZeroExtendToUInt64(System.Numerics.Vector mask, uint* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorUInt32ZeroExtendFirstFaulting(System.Numerics.Vector mask, uint* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorUInt32ZeroExtendFirstFaulting(System.Numerics.Vector mask, uint* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorUInt32ZeroExtendToInt64(System.Numerics.Vector mask, uint* address) { throw null; } @@ -5766,7 +5766,15 @@ internal Arm64() { } // public static void Scatter16BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } public static void Scatter16BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } // public static void Scatter16BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } - public static void Scatter16BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitNarrowing(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitNarrowing(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitNarrowing(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitNarrowing(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitNarrowing(System.Numerics.Vector mask, ushort* address, System.Numerics.Vector indices, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitNarrowing(System.Numerics.Vector mask, ushort* address, System.Numerics.Vector indices, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitNarrowing(System.Numerics.Vector mask, ushort* address, System.Numerics.Vector indices, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter16BitNarrowing(System.Numerics.Vector mask, ushort* address, System.Numerics.Vector indices, System.Numerics.Vector data) { throw null; } public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, short* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, short* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, short* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } @@ -5775,8 +5783,12 @@ internal Arm64() { } public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, ushort* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, ushort* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } public static unsafe void Scatter16BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, ushort* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } - public static void Scatter32BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } - public static void Scatter32BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter32BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter32BitNarrowing(System.Numerics.Vector mask, System.Numerics.Vector addresses, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter32BitNarrowing(System.Numerics.Vector mask, int* address, System.Numerics.Vector indices, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter32BitNarrowing(System.Numerics.Vector mask, int* address, System.Numerics.Vector indices, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter32BitNarrowing(System.Numerics.Vector mask, uint* address, System.Numerics.Vector indices, System.Numerics.Vector data) { throw null; } + public static unsafe void Scatter32BitNarrowing(System.Numerics.Vector mask, uint* address, System.Numerics.Vector indices, System.Numerics.Vector data) { throw null; } public static unsafe void Scatter32BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, int* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } public static unsafe void Scatter32BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, int* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } public static unsafe void Scatter32BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, uint* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } @@ -5793,6 +5805,18 @@ internal Arm64() { } public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, byte* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, byte* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } public static unsafe void Scatter8BitWithByteOffsetsNarrowing(System.Numerics.Vector mask, byte* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void ScatterWithByteOffsets(System.Numerics.Vector mask, double* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void ScatterWithByteOffsets(System.Numerics.Vector mask, double* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void ScatterWithByteOffsets(System.Numerics.Vector mask, int* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void ScatterWithByteOffsets(System.Numerics.Vector mask, int* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void ScatterWithByteOffsets(System.Numerics.Vector mask, long* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void ScatterWithByteOffsets(System.Numerics.Vector mask, long* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void ScatterWithByteOffsets(System.Numerics.Vector mask, float* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void ScatterWithByteOffsets(System.Numerics.Vector mask, float* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void ScatterWithByteOffsets(System.Numerics.Vector mask, uint* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void ScatterWithByteOffsets(System.Numerics.Vector mask, uint* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void ScatterWithByteOffsets(System.Numerics.Vector mask, ulong* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } + public static unsafe void ScatterWithByteOffsets(System.Numerics.Vector mask, ulong* address, System.Numerics.Vector offsets, System.Numerics.Vector data) { throw null; } public static void SetFfr(System.Numerics.Vector value) { throw null; } public static void SetFfr(System.Numerics.Vector value) { throw null; } public static void SetFfr(System.Numerics.Vector value) { throw null; } @@ -6079,6 +6103,10 @@ internal Arm64() { } public static new bool IsSupported { get { throw null; } } } + public static System.Numerics.Vector AbsSaturate(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AbsSaturate(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AbsSaturate(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AbsSaturate(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector AbsoluteDifferenceAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AbsoluteDifferenceAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AbsoluteDifferenceAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -6147,13 +6175,32 @@ internal Arm64() { } public static System.Numerics.Vector AddPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AddPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddPairwiseWidening(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddPairwiseWidening(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddPairwiseWidening(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddPairwiseWidening(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddPairwiseWidening(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddPairwiseWidening(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 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 AddPairwiseWideningAndAdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRotateComplex(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddRotateComplex(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddRotateComplex(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddRotateComplex(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddRotateComplex(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddRotateComplex(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddRotateComplex(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddRotateComplex(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { 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; } @@ -6162,6 +6209,10 @@ internal Arm64() { } 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; } + public static System.Numerics.Vector AddSaturateRotateComplex(System.Numerics.Vector op1, System.Numerics.Vector op2, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddSaturateRotateComplex(System.Numerics.Vector op1, System.Numerics.Vector op2, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddSaturateRotateComplex(System.Numerics.Vector op1, System.Numerics.Vector op2, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddSaturateRotateComplex(System.Numerics.Vector op1, System.Numerics.Vector op2, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } public static System.Numerics.Vector AddSaturateWithSignedAddend(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AddSaturateWithSignedAddend(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AddSaturateWithSignedAddend(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -6170,33 +6221,33 @@ internal Arm64() { } public static System.Numerics.Vector AddSaturateWithUnsignedAddend(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AddSaturateWithUnsignedAddend(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AddSaturateWithUnsignedAddend(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideLower(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideLower(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideLower(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideLower(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideLower(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideLower(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningLower(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningLower(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningLower(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningLower(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningLower(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningLower(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningLowerUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningLowerUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningLowerUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector AddWideningUpper(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEvenOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEvenOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningEvenOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector BitwiseClearXor(System.Numerics.Vector xor, System.Numerics.Vector value, System.Numerics.Vector mask) { throw null; } public static System.Numerics.Vector BitwiseClearXor(System.Numerics.Vector xor, System.Numerics.Vector value, System.Numerics.Vector mask) { throw null; } public static System.Numerics.Vector BitwiseClearXor(System.Numerics.Vector xor, System.Numerics.Vector value, System.Numerics.Vector mask) { throw null; } @@ -6229,6 +6280,36 @@ 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 ConvertToDoubleOdd(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToSingleEvenRoundToOdd(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector DotProductRotateComplex(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector DotProductRotateComplex(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector DotProductRotateComplexBySelectedIndex(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte imm_index, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector DotProductRotateComplexBySelectedIndex(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3, [ConstantExpected(Min = 0, Max = (byte)(1))] byte imm_index, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { 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; } + 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; } + 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 FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector InterleavingXorEvenOdd(System.Numerics.Vector odd, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector InterleavingXorEvenOdd(System.Numerics.Vector odd, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector InterleavingXorEvenOdd(System.Numerics.Vector odd, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -6245,6 +6326,204 @@ 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 Log2(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Log2(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MaxNumberPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxNumberPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinNumberPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinNumberPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinPairwise(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinPairwise(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 MultiplyAddRotateComplex(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplex(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplex(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplex(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplex(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplex(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplex(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplex(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplexBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rightIndex, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplexBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rightIndex, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplexBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rightIndex, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplexBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rightIndex, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { 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 MultiplyDoublingBySelectedScalarSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingBySelectedScalarSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingBySelectedScalarSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndAddSaturateEven(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndAddSaturateEven(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndAddSaturateEven(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndAddSaturateEvenOdd(System.Numerics.Vector addend, System.Numerics.Vector leftEven, System.Numerics.Vector rightOdd) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndAddSaturateEvenOdd(System.Numerics.Vector addend, System.Numerics.Vector leftEven, System.Numerics.Vector rightOdd) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndAddSaturateEvenOdd(System.Numerics.Vector addend, System.Numerics.Vector leftEven, System.Numerics.Vector rightOdd) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndAddSaturateOdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndAddSaturateOdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndAddSaturateOdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndSubtractSaturateEven(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndSubtractSaturateEven(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndSubtractSaturateEven(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndSubtractSaturateEvenOdd(System.Numerics.Vector minuend, System.Numerics.Vector leftEven, System.Numerics.Vector rightOdd) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndSubtractSaturateEvenOdd(System.Numerics.Vector minuend, System.Numerics.Vector leftEven, System.Numerics.Vector rightOdd) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndSubtractSaturateEvenOdd(System.Numerics.Vector minuend, System.Numerics.Vector leftEven, System.Numerics.Vector rightOdd) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndSubtractSaturateOdd(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndSubtractSaturateOdd(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningAndSubtractSaturateOdd(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningSaturateEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningSaturateEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningSaturateEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningSaturateEvenBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningSaturateEvenBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningSaturateOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningSaturateOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningSaturateOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningSaturateOddBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyDoublingWideningSaturateOddBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingBySelectedScalarSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingBySelectedScalarSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingBySelectedScalarSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateAndAddHigh(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateAndAddHigh(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateAndAddHigh(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateAndAddHigh(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateAndSubtractHigh(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateAndSubtractHigh(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateAndSubtractHigh(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateAndSubtractHigh(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyRoundedDoublingSaturateHigh(System.Numerics.Vector left, System.Numerics.Vector right) { 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 MultiplyAddRoundedDoublingSaturateHighRotateComplex(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRoundedDoublingSaturateHighRotateComplex(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRoundedDoublingSaturateHighRotateComplex(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRoundedDoublingSaturateHighRotateComplex(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3, [ConstantExpected(Min = 0, Max = (byte)(3))] byte imm_index, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3, [ConstantExpected(Min = 0, Max = (byte)(1))] byte imm_index, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector NegateSaturate(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector NegateSaturate(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector NegateSaturate(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector NegateSaturate(System.Numerics.Vector value) { 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 ReciprocalEstimate(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ReciprocalSqrtEstimate(System.Numerics.Vector value) { 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; } @@ -6305,18 +6584,12 @@ internal Arm64() { } public static System.Numerics.Vector ShiftRightArithmeticAdd(System.Numerics.Vector addend, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightArithmeticAdd(System.Numerics.Vector addend, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightArithmeticAdd(System.Numerics.Vector addend, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } - public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateEven(System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateEven(System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateEven(System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateEven(System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } - public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateEven(System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } - public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateEven(System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } - public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateOdd(System.Numerics.Vector even, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateOdd(System.Numerics.Vector even, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateOdd(System.Numerics.Vector even, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateOdd(System.Numerics.Vector even, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } - public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateOdd(System.Numerics.Vector even, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } - public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateOdd(System.Numerics.Vector even, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateUnsignedEven(System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateUnsignedEven(System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightArithmeticNarrowingSaturateUnsignedEven(System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } @@ -6385,7 +6658,73 @@ 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 VectorTableLookup((System.Numerics.Vector data1, System.Numerics.Vector data2) table, System.Numerics.Vector indices) { 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; } + 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; } + 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 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 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; } + 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; } + 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 System.Numerics.Vector SubtractWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEvenOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEvenOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningEvenOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractWideningOdd(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 SubtractWideningOddEven(System.Numerics.Vector left, System.Numerics.Vector right) { 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; } 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/libraries/System.Runtime.Loader/tests/AssemblyResolutionDowngradeTest.cs b/src/libraries/System.Runtime.Loader/tests/AssemblyResolutionDowngradeTest.cs new file mode 100644 index 00000000000000..f0f7de9c208fa6 --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/AssemblyResolutionDowngradeTest.cs @@ -0,0 +1,250 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO; +using System.Reflection; +using Microsoft.DotNet.RemoteExecutor; +using Xunit; + +namespace System.Runtime.Loader.Tests +{ + public class AssemblyResolutionDowngradeTest : FileCleanupTestBase + { + private const string TestAssemblyName = "System.Runtime.Loader.Test.VersionDowngrade"; + + /// + /// Test that AppDomain.AssemblyResolve can resolve a higher version request with a lower version assembly. + /// This tests the scenario where code requests assembly version 3.0.0 but the resolver provides 1.0.0. + /// + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void AppDomainAssemblyResolve_CanDowngradeVersion() + { + RemoteExecutor.Invoke(() => { + string assemblyV1Path = GetTestAssemblyPath("System.Runtime.Loader.Test.AssemblyVersion1"); + + bool resolverCalled = false; + + ResolveEventHandler handler = (sender, args) => + { + Assert.Same(AppDomain.CurrentDomain, sender); + Assert.NotNull(args); + Assert.NotNull(args.Name); + + var requestedName = new AssemblyName(args.Name); + if (requestedName.Name == TestAssemblyName) + { + resolverCalled = true; + // Request is for version 3.0, but we return version 1.0 (downgrade) + Assert.Equal(new Version(3, 0, 0, 0), requestedName.Version); + return Assembly.LoadFile(assemblyV1Path); + } + return null; + }; + + AppDomain.CurrentDomain.AssemblyResolve += handler; + + try + { + // Request version 3.0.0 but expect to get 1.0.0 via downgrade + var requestedAssemblyName = new AssemblyName($"{TestAssemblyName}, Version=3.0.0.0"); + Assembly resolvedAssembly = Assembly.Load(requestedAssemblyName); + + Assert.NotNull(resolvedAssembly); + Assert.True(resolverCalled, "Assembly resolver should have been called"); + + // Verify we got the 1.0.0 assembly (downgrade successful) + Assert.Equal(new Version(1, 0, 0, 0), resolvedAssembly.GetName().Version); + + // Verify the assembly works as expected + Type testType = resolvedAssembly.GetType("System.Runtime.Loader.Tests.VersionTestClass"); + Assert.NotNull(testType); + + string version = (string)testType.GetMethod("GetVersion").Invoke(null, null); + Assert.Equal("1.0.0", version); + } + finally + { + AppDomain.CurrentDomain.AssemblyResolve -= handler; + } + }).Dispose(); + } + + /// + /// Test that AssemblyLoadContext.Resolving event can resolve a higher version request with a lower version assembly. + /// + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void AssemblyLoadContextResolving_CanDowngradeVersion() + { + RemoteExecutor.Invoke(() => { + string assemblyV1Path = GetTestAssemblyPath("System.Runtime.Loader.Test.AssemblyVersion1"); + + bool resolverCalled = false; + + Func handler = (context, name) => + { + if (name.Name == TestAssemblyName) + { + resolverCalled = true; + // Request is for version 3.0, but we return version 1.0 (downgrade) + Assert.Equal(new Version(3, 0, 0, 0), name.Version); + return context.LoadFromAssemblyPath(assemblyV1Path); + } + return null; + }; + + AssemblyLoadContext.Default.Resolving += handler; + + try + { + // Request version 3.0.0 but expect to get 1.0.0 via downgrade + var requestedAssemblyName = new AssemblyName($"{TestAssemblyName}, Version=3.0.0.0"); + Assembly resolvedAssembly = AssemblyLoadContext.Default.LoadFromAssemblyName(requestedAssemblyName); + + Assert.NotNull(resolvedAssembly); + Assert.True(resolverCalled, "Assembly resolver should have been called"); + + // Verify we got the 1.0.0 assembly (downgrade successful) + Assert.Equal(new Version(1, 0, 0, 0), resolvedAssembly.GetName().Version); + + // Verify the assembly works as expected + Type testType = resolvedAssembly.GetType("System.Runtime.Loader.Tests.VersionTestClass"); + Assert.NotNull(testType); + + string version = (string)testType.GetMethod("GetVersion").Invoke(null, null); + Assert.Equal("1.0.0", version); + } + finally + { + AssemblyLoadContext.Default.Resolving -= handler; + } + }).Dispose(); + } + + /// + /// Test that a custom AssemblyLoadContext.Load override can resolve a higher version request with a lower version assembly. + /// + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void CustomAssemblyLoadContextLoad_CanDowngradeVersion() + { + RemoteExecutor.Invoke(() => { + string assemblyV1Path = GetTestAssemblyPath("System.Runtime.Loader.Test.AssemblyVersion1"); + + var customContext = new DowngradeAssemblyLoadContext(assemblyV1Path); + + // Request version 3.0.0 but expect to get 1.0.0 via downgrade + var requestedAssemblyName = new AssemblyName($"{TestAssemblyName}, Version=3.0.0.0"); + Assembly resolvedAssembly = customContext.LoadFromAssemblyName(requestedAssemblyName); + + Assert.NotNull(resolvedAssembly); + Assert.True(customContext.LoadCalled, "Custom Load method should have been called"); + + // Verify we got the 1.0.0 assembly (downgrade successful) + Assert.Equal(new Version(1, 0, 0, 0), resolvedAssembly.GetName().Version); + + // Verify the assembly works as expected + Type testType = resolvedAssembly.GetType("System.Runtime.Loader.Tests.VersionTestClass"); + Assert.NotNull(testType); + + string version = (string)testType.GetMethod("GetVersion").Invoke(null, null); + Assert.Equal("1.0.0", version); + + // Verify that the correct ALC loaded the assembly + Assert.Equal(customContext, AssemblyLoadContext.GetLoadContext(resolvedAssembly)); + }).Dispose(); + } + + /// + /// Test that normal runtime resolution (without extension mechanisms) will NOT allow downgrades. + /// This test verifies the baseline behavior that downgrades only work via extension mechanisms. + /// Note: On Mono, downgrades are allowed even in normal resolution, so this test behaves differently. + /// + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void NormalResolution_CannotDowngradeVersion() + { + RemoteExecutor.Invoke(() => { + string assemblyV1Path = GetTestAssemblyPath("System.Runtime.Loader.Test.AssemblyVersion1"); + + // First, load the version 1.0.0 assembly into the default context + Assembly loadedV1 = AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyV1Path); + Assert.Equal(new Version(1, 0, 0, 0), loadedV1.GetName().Version); + + // Now try to load version 3.0.0 + var requestedAssemblyName = new AssemblyName($"{TestAssemblyName}, Version=3.0.0.0"); + + if (PlatformDetection.IsMonoRuntime) + { + // On Mono, normal resolution allows downgrades, so this should succeed + // and return the already-loaded 1.0.0 assembly + Assembly resolvedAssembly = AssemblyLoadContext.Default.LoadFromAssemblyName(requestedAssemblyName); + Assert.NotNull(resolvedAssembly); + Assert.Equal(new Version(1, 0, 0, 0), resolvedAssembly.GetName().Version); + Assert.Same(loadedV1, resolvedAssembly); + } + else + { + // On CoreCLR, normal resolution should NOT automatically + // downgrade to the already-loaded 1.0.0 version, it should fail + Assert.Throws(() => + AssemblyLoadContext.Default.LoadFromAssemblyName(requestedAssemblyName)); + } + }).Dispose(); + } + + private static string GetTestAssemblyPath(string assemblyProject) + { + // Map project names to actual embedded resource names + string resourceName = assemblyProject switch + { + "System.Runtime.Loader.Test.AssemblyVersion1" => "System.Runtime.Loader.Tests.AssemblyVersion1.dll", + _ => throw new ArgumentException($"Unknown test assembly project: {assemblyProject}") + }; + + // Extract the embedded assembly to a temporary file + string tempPath = Path.Combine(Path.GetTempPath(), $"{assemblyProject}_{Guid.NewGuid()}.dll"); + + using (Stream resourceStream = typeof(AssemblyResolutionDowngradeTest).Assembly.GetManifestResourceStream(resourceName)) + { + if (resourceStream is null) + { + throw new FileNotFoundException($"Could not find embedded resource: {resourceName}"); + } + + using (FileStream fileStream = File.Create(tempPath)) + { + resourceStream.CopyTo(fileStream); + } + } + + return tempPath; + } + + /// + /// Custom AssemblyLoadContext that can downgrade version requests. + /// + private class DowngradeAssemblyLoadContext : AssemblyLoadContext + { + private readonly string _downgradePath; + + public bool LoadCalled { get; private set; } + + public DowngradeAssemblyLoadContext(string downgradePath) : base("DowngradeContext") + { + _downgradePath = downgradePath; + } + + protected override Assembly Load(AssemblyName assemblyName) + { + LoadCalled = true; + + if (assemblyName.Name == TestAssemblyName) + { + // Request is for version 3.0, but we return version 1.0 (downgrade) + Assert.Equal(new Version(3, 0, 0, 0), assemblyName.Version); + return LoadFromAssemblyPath(_downgradePath); + } + + return null; + } + } + } +} \ No newline at end of file diff --git a/src/libraries/System.Runtime.Loader/tests/LoaderLinkTest.cs b/src/libraries/System.Runtime.Loader/tests/LoaderLinkTest.cs index ff0f1b694c0bc6..069cc8c481a8c6 100644 --- a/src/libraries/System.Runtime.Loader/tests/LoaderLinkTest.cs +++ b/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/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs b/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs index 4f5e6265135795..e00166fa0be8de 100644 --- a/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs +++ b/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/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Test.AssemblyVersion1/System.Runtime.Loader.Test.AssemblyVersion1.csproj b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Test.AssemblyVersion1/System.Runtime.Loader.Test.AssemblyVersion1.csproj new file mode 100644 index 00000000000000..b50eb00e2e5a54 --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Test.AssemblyVersion1/System.Runtime.Loader.Test.AssemblyVersion1.csproj @@ -0,0 +1,13 @@ + + + $(NetCoreAppCurrent);netstandard2.0 + 1.0.0.0 + 1.0.0.0 + 1.0.0 + System.Runtime.Loader.Test.VersionDowngrade + false + + + + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Test.AssemblyVersion1/VersionTestClass.cs b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Test.AssemblyVersion1/VersionTestClass.cs new file mode 100644 index 00000000000000..5e6d347447ca4d --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Test.AssemblyVersion1/VersionTestClass.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.Loader.Tests +{ + public class VersionTestClass + { + public static string GetVersion() + => typeof(VersionTestClass).Assembly.GetName().Version?.ToString(3) ?? "Unknown"; + } +} \ No newline at end of file diff --git a/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj index 921723bdc304ed..f9f54c521f0240 100644 --- a/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj +++ b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj @@ -30,6 +30,7 @@ + @@ -50,6 +51,7 @@ + diff --git a/src/libraries/System.Runtime.Numerics/System.Runtime.Numerics.slnx b/src/libraries/System.Runtime.Numerics/System.Runtime.Numerics.slnx index 75912c188420c8..6d025293d5cb41 100644 --- a/src/libraries/System.Runtime.Numerics/System.Runtime.Numerics.slnx +++ b/src/libraries/System.Runtime.Numerics/System.Runtime.Numerics.slnx @@ -1,29 +1,210 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj b/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj index 2f97470cd33b28..2dbaaebf1bc046 100644 --- a/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj +++ b/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj @@ -40,9 +40,9 @@ - - - + + + diff --git a/src/libraries/System.Runtime.Serialization.Formatters/System.Runtime.Serialization.Formatters.slnx b/src/libraries/System.Runtime.Serialization.Formatters/System.Runtime.Serialization.Formatters.slnx index 2739977a659471..c1810ab5845f53 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/System.Runtime.Serialization.Formatters.slnx +++ b/src/libraries/System.Runtime.Serialization.Formatters/System.Runtime.Serialization.Formatters.slnx @@ -52,6 +52,14 @@ + + + + + + + + @@ -164,6 +172,22 @@ + + + + + + + + + + + + + + + + @@ -172,6 +196,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -188,6 +236,22 @@ + + + + + + + + + + + + + + + + @@ -204,6 +268,22 @@ + + + + + + + + + + + + + + + + @@ -220,6 +300,22 @@ + + + + + + + + + + + + + + + + @@ -236,6 +332,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -285,7 +405,7 @@ - + @@ -413,6 +533,22 @@ + + + + + + + + + + + + + + + + @@ -421,6 +557,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -437,6 +597,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -445,6 +629,22 @@ + + + + + + + + + + + + + + + + @@ -461,6 +661,22 @@ + + + + + + + + + + + + + + + + @@ -477,6 +693,22 @@ + + + + + + + + + + + + + + + + @@ -502,6 +734,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.Runtime.Serialization.Json/System.Runtime.Serialization.Json.slnx b/src/libraries/System.Runtime.Serialization.Json/System.Runtime.Serialization.Json.slnx index f1987ebcbe4bca..6268fc44f008f6 100644 --- a/src/libraries/System.Runtime.Serialization.Json/System.Runtime.Serialization.Json.slnx +++ b/src/libraries/System.Runtime.Serialization.Json/System.Runtime.Serialization.Json.slnx @@ -1,40 +1,1138 @@ + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Runtime.Serialization.Json/ref/System.Runtime.Serialization.Json.csproj b/src/libraries/System.Runtime.Serialization.Json/ref/System.Runtime.Serialization.Json.csproj index 350ad3eebfc99d..b51e286c803e54 100644 --- a/src/libraries/System.Runtime.Serialization.Json/ref/System.Runtime.Serialization.Json.csproj +++ b/src/libraries/System.Runtime.Serialization.Json/ref/System.Runtime.Serialization.Json.csproj @@ -1,4 +1,5 @@ + $(NetCoreAppCurrent) @@ -10,6 +11,8 @@ + + diff --git a/src/libraries/System.Runtime.Serialization.Json/src/System.Runtime.Serialization.Json.csproj b/src/libraries/System.Runtime.Serialization.Json/src/System.Runtime.Serialization.Json.csproj index 53fc3732f892f8..9b4597500919bf 100644 --- a/src/libraries/System.Runtime.Serialization.Json/src/System.Runtime.Serialization.Json.csproj +++ b/src/libraries/System.Runtime.Serialization.Json/src/System.Runtime.Serialization.Json.csproj @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Runtime.Serialization.Json/tests/DataContractJsonSerializer.cs b/src/libraries/System.Runtime.Serialization.Json/tests/DataContractJsonSerializer.cs index 5de787c502988b..e118d3681607cd 100644 --- a/src/libraries/System.Runtime.Serialization.Json/tests/DataContractJsonSerializer.cs +++ b/src/libraries/System.Runtime.Serialization.Json/tests/DataContractJsonSerializer.cs @@ -1395,7 +1395,6 @@ public static void DCJS_EmptyString_Throws() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCJS_ClassWithDatetimeOffsetTypeProperty() { var value = new TypeWithDateTimeOffsetTypeProperty() { ModifiedTime = new DateTimeOffset(new DateTime(2013, 1, 2, 3, 4, 5, 6, DateTimeKind.Utc)) }; @@ -1464,7 +1463,6 @@ public static void DCJS_TypeWithGenericDictionaryAsKnownType() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCJS_TypeWithKnownTypeAttributeAndInterfaceMember() { TypeWithKnownTypeAttributeAndInterfaceMember value = new TypeWithKnownTypeAttributeAndInterfaceMember(); @@ -1476,7 +1474,6 @@ public static void DCJS_TypeWithKnownTypeAttributeAndInterfaceMember() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCJS_TypeWithKnownTypeAttributeAndListOfInterfaceMember() { TypeWithKnownTypeAttributeAndListOfInterfaceMember value = new TypeWithKnownTypeAttributeAndListOfInterfaceMember(); @@ -2600,7 +2597,6 @@ public static void DCJS_VerifyDateTimeForFormatStringDCJsonSerSetting() } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCJS_VerifyDateTimeForFormatStringDCJsonSerSettings() { var jsonTypes = new JsonTypes(); diff --git a/src/libraries/System.Runtime.Serialization.Primitives/System.Runtime.Serialization.Primitives.slnx b/src/libraries/System.Runtime.Serialization.Primitives/System.Runtime.Serialization.Primitives.slnx index 1573fe008547fa..ea035a6ac62420 100644 --- a/src/libraries/System.Runtime.Serialization.Primitives/System.Runtime.Serialization.Primitives.slnx +++ b/src/libraries/System.Runtime.Serialization.Primitives/System.Runtime.Serialization.Primitives.slnx @@ -76,6 +76,14 @@ + + + + + + + + @@ -157,6 +165,14 @@ + + + + + + + + diff --git a/src/libraries/System.Runtime.Serialization.Primitives/src/System.Runtime.Serialization.Primitives.csproj b/src/libraries/System.Runtime.Serialization.Primitives/src/System.Runtime.Serialization.Primitives.csproj index ca2ed33befc50b..05444a78a2dfca 100644 --- a/src/libraries/System.Runtime.Serialization.Primitives/src/System.Runtime.Serialization.Primitives.csproj +++ b/src/libraries/System.Runtime.Serialization.Primitives/src/System.Runtime.Serialization.Primitives.csproj @@ -22,8 +22,8 @@ - - + + diff --git a/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/ContractNamespaceAttributeTests.cs b/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/ContractNamespaceAttributeTests.cs index dd120902df3d6b..cbcdef118ff120 100644 --- a/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/ContractNamespaceAttributeTests.cs +++ b/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/ContractNamespaceAttributeTests.cs @@ -11,7 +11,7 @@ public class ContractNamespaceAttributeTests [InlineData(null)] [InlineData("")] [InlineData("contractNamespace")] - public void Ctor_String(string contractNamespace) + public void Ctor_String(string? contractNamespace) { var attribute = new ContractNamespaceAttribute(contractNamespace); Assert.Equal(contractNamespace, attribute.ContractNamespace); @@ -22,7 +22,7 @@ public void Ctor_String(string contractNamespace) [InlineData(null)] [InlineData("")] [InlineData("value")] - public void ClrNamespace_Set_GetReturnsExpected(string value) + public void ClrNamespace_Set_GetReturnsExpected(string? value) { var attribute = new ContractNamespaceAttribute("contractNamespace") { ClrNamespace = value }; Assert.Equal(value, attribute.ClrNamespace); diff --git a/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/DataContractAttributeTests.cs b/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/DataContractAttributeTests.cs index 0186b053cd7501..368e26fcbfc542 100644 --- a/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/DataContractAttributeTests.cs +++ b/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/DataContractAttributeTests.cs @@ -33,7 +33,7 @@ public void IsReference_Set_GetReturnsExpected(bool value) [InlineData(null)] [InlineData("")] [InlineData("value")] - public void Name_Set_GetReturnsExpected(string value) + public void Name_Set_GetReturnsExpected(string? value) { var attribute = new DataContractAttribute() { Name = value }; Assert.Equal(value, attribute.Name); @@ -44,7 +44,7 @@ public void Name_Set_GetReturnsExpected(string value) [InlineData(null)] [InlineData("")] [InlineData("value")] - public void Namespace_Set_GetReturnsExpected(string value) + public void Namespace_Set_GetReturnsExpected(string? value) { var attribute = new DataContractAttribute() { Namespace = value }; Assert.Equal(value, attribute.Namespace); diff --git a/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/DataMemberAttributeTests.cs b/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/DataMemberAttributeTests.cs index 556f7bb06090dd..21050880c1e866 100644 --- a/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/DataMemberAttributeTests.cs +++ b/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/DataMemberAttributeTests.cs @@ -40,7 +40,7 @@ public void IsRequired_Set_GetReturnsExpected(bool value) [InlineData(null)] [InlineData("")] [InlineData("value")] - public void Name_Set_GetReturnsExpected(string value) + public void Name_Set_GetReturnsExpected(string? value) { var attribute = new DataMemberAttribute() { Name = value }; Assert.Equal(value, attribute.Name); diff --git a/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/EnumMemberAttributeTests.cs b/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/EnumMemberAttributeTests.cs index 179d9614393026..7649192737b7fe 100644 --- a/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/EnumMemberAttributeTests.cs +++ b/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/EnumMemberAttributeTests.cs @@ -19,7 +19,7 @@ public void Ctor_Default() [InlineData(null)] [InlineData("")] [InlineData("value")] - public void Value_Set_GetReturnsExpected(string value) + public void Value_Set_GetReturnsExpected(string? value) { var attribute = new EnumMemberAttribute() { Value = value }; Assert.Equal(value, attribute.Value); diff --git a/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/KnownTypeAttributeTests.cs b/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/KnownTypeAttributeTests.cs index b02b2e48e55a10..c5159af8ca7e95 100644 --- a/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/KnownTypeAttributeTests.cs +++ b/src/libraries/System.Runtime.Serialization.Primitives/tests/System/Runtime/Serialization/KnownTypeAttributeTests.cs @@ -11,7 +11,7 @@ public class KnownTypeAttributeTests [InlineData(null)] [InlineData("")] [InlineData("value")] - public void Ctor_String(string methodName) + public void Ctor_String(string? methodName) { var attribute = new KnownTypeAttribute(methodName); Assert.Equal(methodName, attribute.MethodName); @@ -21,7 +21,7 @@ public void Ctor_String(string methodName) [Theory] [InlineData(null)] [InlineData(typeof(int))] - public void Ctor_Type(Type type) + public void Ctor_Type(Type? type) { var attribute = new KnownTypeAttribute(type); Assert.Null(attribute.MethodName); diff --git a/src/libraries/System.Runtime.Serialization.Schema/Directory.Build.props b/src/libraries/System.Runtime.Serialization.Schema/Directory.Build.props index 7d407028f6632b..6fa3721eb042af 100644 --- a/src/libraries/System.Runtime.Serialization.Schema/Directory.Build.props +++ b/src/libraries/System.Runtime.Serialization.Schema/Directory.Build.props @@ -5,5 +5,6 @@ true browser;wasi;ios;tvos;maccatalyst + false diff --git a/src/libraries/System.Runtime.Serialization.Schema/src/System.Runtime.Serialization.Schema.csproj b/src/libraries/System.Runtime.Serialization.Schema/src/System.Runtime.Serialization.Schema.csproj index 7c65f69b104fb1..86bf7835337ec8 100644 --- a/src/libraries/System.Runtime.Serialization.Schema/src/System.Runtime.Serialization.Schema.csproj +++ b/src/libraries/System.Runtime.Serialization.Schema/src/System.Runtime.Serialization.Schema.csproj @@ -2,7 +2,6 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum) - false true Provides support for importing and exporting xsd schemas for DataContractSerializer. diff --git a/src/libraries/System.Runtime.Serialization.Schema/src/System/Runtime/Serialization/Schema/ImportGlobals.cs b/src/libraries/System.Runtime.Serialization.Schema/src/System/Runtime/Serialization/Schema/ImportGlobals.cs index 59392aed8b04f1..0cc9bfb7da1b17 100644 --- a/src/libraries/System.Runtime.Serialization.Schema/src/System/Runtime/Serialization/Schema/ImportGlobals.cs +++ b/src/libraries/System.Runtime.Serialization.Schema/src/System/Runtime/Serialization/Schema/ImportGlobals.cs @@ -84,30 +84,14 @@ internal static class ImportGlobals public const string ValueNameProperty = "ValueName"; public const string ValueProperty = "Value"; - private static Uri? s_dataContractXsdBaseNamespaceUri; - internal static Uri DataContractXsdBaseNamespaceUri => s_dataContractXsdBaseNamespaceUri ??= new Uri(DataContractXsdBaseNamespace); - - private static XmlQualifiedName? s_idQualifiedName; - internal static XmlQualifiedName IdQualifiedName => s_idQualifiedName ??= new XmlQualifiedName(ImportGlobals.IdLocalName, ImportGlobals.SerializationNamespace); - - private static XmlQualifiedName? s_refQualifiedName; - internal static XmlQualifiedName RefQualifiedName => s_refQualifiedName ??= new XmlQualifiedName(ImportGlobals.RefLocalName, ImportGlobals.SerializationNamespace); - - private static Type? s_typeOfXmlElement; - internal static Type TypeOfXmlElement => s_typeOfXmlElement ??= typeof(XmlElement); - - private static Type? s_typeOfXmlNodeArray; - internal static Type TypeOfXmlNodeArray => s_typeOfXmlNodeArray ??= typeof(XmlNode[]); - - private static Type? s_typeOfXmlQualifiedName; - internal static Type TypeOfXmlQualifiedName => s_typeOfXmlQualifiedName ??= typeof(XmlQualifiedName); - - private static Type? s_typeOfXmlSchemaProviderAttribute; - internal static Type TypeOfXmlSchemaProviderAttribute => s_typeOfXmlSchemaProviderAttribute ??= typeof(XmlSchemaProviderAttribute); - - private static Type? s_typeOfXmlSchemaType; - internal static Type TypeOfXmlSchemaType => s_typeOfXmlSchemaType ??= typeof(XmlSchemaType); - + internal static Uri DataContractXsdBaseNamespaceUri => field ??= new Uri(DataContractXsdBaseNamespace); + internal static XmlQualifiedName IdQualifiedName => field ??= new XmlQualifiedName(ImportGlobals.IdLocalName, ImportGlobals.SerializationNamespace); + internal static XmlQualifiedName RefQualifiedName => field ??= new XmlQualifiedName(ImportGlobals.RefLocalName, ImportGlobals.SerializationNamespace); + internal static Type TypeOfXmlElement => field ??= typeof(XmlElement); + internal static Type TypeOfXmlNodeArray => field ??= typeof(XmlNode[]); + internal static Type TypeOfXmlQualifiedName => field ??= typeof(XmlQualifiedName); + internal static Type TypeOfXmlSchemaProviderAttribute => field ??= typeof(XmlSchemaProviderAttribute); + internal static Type TypeOfXmlSchemaType => field ??= typeof(XmlSchemaType); public const string SerializationSchema = @" diff --git a/src/libraries/System.Runtime.Serialization.Schema/src/System/Runtime/Serialization/Schema/ImportOptions.cs b/src/libraries/System.Runtime.Serialization.Schema/src/System/Runtime/Serialization/Schema/ImportOptions.cs index 0e8fab9d0df5b9..b6fe6ce44729e2 100644 --- a/src/libraries/System.Runtime.Serialization.Schema/src/System/Runtime/Serialization/Schema/ImportOptions.cs +++ b/src/libraries/System.Runtime.Serialization.Schema/src/System/Runtime/Serialization/Schema/ImportOptions.cs @@ -16,10 +16,6 @@ namespace System.Runtime.Serialization /// public class ImportOptions { - private ICollection? _referencedTypes; - private ICollection? _referencedCollectionTypes; - private IDictionary? _namespaces; - /// /// Gets or sets a instance that provides the means to check whether particular options for a target language are supported. /// @@ -57,16 +53,16 @@ public class ImportOptions /// /// Gets a dictionary that contains the mapping of data contract namespaces to the CLR namespaces that must be used to generate code during an import operation. /// - public IDictionary Namespaces => _namespaces ??= new Dictionary(); + public IDictionary Namespaces => field ??= new Dictionary(); /// /// Gets a collection of types that represents data contract collections that should be referenced when generating code for collections, such as lists or dictionaries of items. /// - public ICollection ReferencedCollectionTypes => _referencedCollectionTypes ??= new List(); + public ICollection ReferencedCollectionTypes => field ??= new List(); /// /// Gets a containing types referenced in generated code. /// - public ICollection ReferencedTypes => _referencedTypes ??= new List(); + public ICollection ReferencedTypes => field ??= new List(); } } diff --git a/src/libraries/System.Runtime.Serialization.Schema/src/System/Runtime/Serialization/Schema/XsdDataContractImporter.cs b/src/libraries/System.Runtime.Serialization.Schema/src/System/Runtime/Serialization/Schema/XsdDataContractImporter.cs index 5e9eba22fbf18c..43beae4cea959f 100644 --- a/src/libraries/System.Runtime.Serialization.Schema/src/System/Runtime/Serialization/Schema/XsdDataContractImporter.cs +++ b/src/libraries/System.Runtime.Serialization.Schema/src/System/Runtime/Serialization/Schema/XsdDataContractImporter.cs @@ -358,8 +358,7 @@ private bool InternalCanImport(XmlSchemaSet schemas, ICollection s_actualTypeAnnotationName ??= new XmlQualifiedName(ImportGlobals.ActualTypeLocalName, ImportGlobals.SerializationNamespace); + internal static XmlQualifiedName ActualTypeAnnotationName => field ??= new XmlQualifiedName(ImportGlobals.ActualTypeLocalName, ImportGlobals.SerializationNamespace); internal static XmlQualifiedName ImportActualType(XmlSchemaAnnotation? annotation, XmlQualifiedName defaultTypeName, XmlQualifiedName typeName) { diff --git a/src/libraries/System.Runtime.Serialization.Schema/tests/System/Runtime/Serialization/Schema/RoundTripTest.cs b/src/libraries/System.Runtime.Serialization.Schema/tests/System/Runtime/Serialization/Schema/RoundTripTest.cs index f1a852b3a510ab..61e1425ffd06fd 100644 --- a/src/libraries/System.Runtime.Serialization.Schema/tests/System/Runtime/Serialization/Schema/RoundTripTest.cs +++ b/src/libraries/System.Runtime.Serialization.Schema/tests/System/Runtime/Serialization/Schema/RoundTripTest.cs @@ -22,8 +22,8 @@ public RoundTripTest(ITestOutputHelper output) } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoRuntime), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsAppleMobile))] + // Passes on some wasm, but not all? Seems to have both passed and failed on the same browser/wasm/OS/Mono-CoreCLR combo in the same pipeline? How does that happen? Is this trimming related? + [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming))] public void RountTripTest() { // AppContext SetSwitch seems to be unreliable in the unit test case. So let's not rely on it @@ -81,7 +81,6 @@ public void RountTripTest() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))] public void RoundTripXmlSerializableWithSpecialAttributesTest() { XsdDataContractExporter exporter = new XsdDataContractExporter(); diff --git a/src/libraries/System.Runtime.Serialization.Xml/System.Runtime.Serialization.Xml.slnx b/src/libraries/System.Runtime.Serialization.Xml/System.Runtime.Serialization.Xml.slnx index 108a9881a0b0e4..7037559f50f29c 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/System.Runtime.Serialization.Xml.slnx +++ b/src/libraries/System.Runtime.Serialization.Xml/System.Runtime.Serialization.Xml.slnx @@ -1,43 +1,1162 @@ + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Runtime.Serialization.Xml/ref/System.Runtime.Serialization.Xml.cs b/src/libraries/System.Runtime.Serialization.Xml/ref/System.Runtime.Serialization.Xml.cs index 23a8d3be3f34ab..067047c302b3af 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/ref/System.Runtime.Serialization.Xml.cs +++ b/src/libraries/System.Runtime.Serialization.Xml/ref/System.Runtime.Serialization.Xml.cs @@ -94,8 +94,8 @@ public DataContractSerializerSettings() { } public partial class ExportOptions { public ExportOptions() { } + public System.Runtime.Serialization.ISerializationSurrogateProvider? DataContractSurrogate { get { throw null; } set { } } public System.Collections.ObjectModel.Collection KnownTypes { get { throw null; } } - public ISerializationSurrogateProvider? DataContractSurrogate { get { throw null; } set { throw null; } } } public sealed partial class ExtensionDataObject { @@ -207,6 +207,98 @@ public void Export(System.Type type) { } public System.Xml.XmlQualifiedName GetSchemaTypeName(System.Type type) { throw null; } } } +namespace System.Runtime.Serialization.DataContracts +{ + public abstract partial class DataContract + { + internal const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes DataContractPreserveMemberTypes = + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods | + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors | + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties; + + internal DataContract() { } + public virtual System.Runtime.Serialization.DataContracts.DataContract? BaseContract { [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed."), System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] get { throw null; } } + public virtual string? ContractType { get { throw null; } } + public virtual System.Collections.ObjectModel.ReadOnlyCollection DataMembers { get { throw null; } } + public virtual bool IsBuiltInDataContract { get { throw null; } } + public virtual bool IsISerializable { get { throw null; } } + public virtual bool IsReference { get { throw null; } } + public virtual bool IsValueType { get { throw null; } } + public virtual System.Collections.Generic.Dictionary? KnownDataContracts { [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed."), System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] get { throw null; } } + public virtual System.Type OriginalUnderlyingType { get { throw null; } } + public virtual System.Xml.XmlDictionaryString? TopLevelElementName { get { throw null; } } + public virtual System.Xml.XmlDictionaryString? TopLevelElementNamespace { get { throw null; } } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(DataContractPreserveMemberTypes)] + public virtual System.Type UnderlyingType { get { throw null; } } + public virtual System.Xml.XmlQualifiedName XmlName { get { throw null; } } + public sealed override bool Equals(object? obj) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] + public virtual System.Xml.XmlQualifiedName GetArrayTypeName(bool isNullable) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] + public static System.Runtime.Serialization.DataContracts.DataContract? GetBuiltInDataContract(string name, string ns) { throw null; } + public override int GetHashCode() { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] + public static System.Xml.XmlQualifiedName GetXmlName(System.Type type) { throw null; } + public virtual bool IsDictionaryLike([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? keyName, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? valueName, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? itemName) { throw null; } + } + public sealed partial class DataContractSet + { + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] + public DataContractSet(System.Runtime.Serialization.DataContracts.DataContractSet dataContractSet) { } + public DataContractSet(System.Runtime.Serialization.ISerializationSurrogateProvider? dataContractSurrogate, System.Collections.Generic.IEnumerable? referencedTypes, System.Collections.Generic.IEnumerable? referencedCollectionTypes) { } + public System.Collections.Generic.Dictionary Contracts { get { throw null; } } + public System.Collections.Generic.Dictionary? KnownTypesForObject { get { throw null; } } + public System.Collections.Generic.Dictionary ProcessedContracts { get { throw null; } } + public System.Collections.Hashtable SurrogateData { get { throw null; } } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] + public System.Runtime.Serialization.DataContracts.DataContract GetDataContract(System.Type type) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] + public System.Runtime.Serialization.DataContracts.DataContract? GetDataContract(System.Xml.XmlQualifiedName key) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] + public System.Type? GetReferencedType(System.Xml.XmlQualifiedName xmlName, System.Runtime.Serialization.DataContracts.DataContract dataContract, out System.Runtime.Serialization.DataContracts.DataContract? referencedContract, out object[]? genericParameters, bool? supportGenericTypes = default(bool?)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] + public System.Collections.Generic.List ImportSchemaSet(System.Xml.Schema.XmlSchemaSet schemaSet, System.Collections.Generic.IEnumerable elements, bool importXmlDataType) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] + public void ImportSchemaSet(System.Xml.Schema.XmlSchemaSet schemaSet, System.Collections.Generic.IEnumerable? typeNames, bool importXmlDataType) { } + } + public sealed partial class DataMember + { + internal DataMember() { } + public bool EmitDefaultValue { get { throw null; } } + public bool IsNullable { get { throw null; } } + public bool IsRequired { get { throw null; } } + public System.Runtime.Serialization.DataContracts.DataContract MemberTypeContract { [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed."), System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] get { throw null; } } + public string Name { get { throw null; } } + public long Order { get { throw null; } } + } + public sealed partial class XmlDataContract : System.Runtime.Serialization.DataContracts.DataContract + { + internal XmlDataContract() { } + public override string? ContractType { get { throw null; } } + public bool HasRoot { get { throw null; } } + public bool IsAnonymous { get { throw null; } } + public override bool IsBuiltInDataContract { get { throw null; } } + public bool IsTopLevelElementNullable { get { throw null; } } + public bool IsTypeDefinedOnImport { get { throw null; } set { } } + public new bool IsValueType { get { throw null; } set { } } + public override System.Collections.Generic.Dictionary? KnownDataContracts { [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed."), System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] get { throw null; } } + public override System.Xml.XmlDictionaryString? TopLevelElementName { get { throw null; } } + public override System.Xml.XmlDictionaryString? TopLevelElementNamespace { get { throw null; } } + public System.Xml.Schema.XmlSchemaType? XsdType { get { throw null; } } + } +} namespace System.Xml { public partial interface IFragmentCapableXmlDictionaryWriter @@ -456,6 +548,7 @@ public abstract partial class XmlDictionaryWriter : System.Xml.XmlWriter { protected XmlDictionaryWriter() { } public virtual bool CanCanonicalize { get { throw null; } } + public override void Close() { } public static System.Xml.XmlDictionaryWriter CreateBinaryWriter(System.IO.Stream stream) { throw null; } public static System.Xml.XmlDictionaryWriter CreateBinaryWriter(System.IO.Stream stream, System.Xml.IXmlDictionary? dictionary) { throw null; } public static System.Xml.XmlDictionaryWriter CreateBinaryWriter(System.IO.Stream stream, System.Xml.IXmlDictionary? dictionary, System.Xml.XmlBinaryWriterSession? session) { throw null; } @@ -466,6 +559,7 @@ protected XmlDictionaryWriter() { } public static System.Xml.XmlDictionaryWriter CreateTextWriter(System.IO.Stream stream) { throw null; } public static System.Xml.XmlDictionaryWriter CreateTextWriter(System.IO.Stream stream, System.Text.Encoding encoding) { throw null; } public static System.Xml.XmlDictionaryWriter CreateTextWriter(System.IO.Stream stream, System.Text.Encoding encoding, bool ownsStream) { throw null; } + protected override void Dispose(bool disposing) { } public virtual void EndCanonicalization() { } public virtual void StartCanonicalization(System.IO.Stream stream, bool includeComments, string[]? inclusivePrefixes) { } public virtual void WriteArray(string? prefix, string localName, string? namespaceUri, bool[] array, int offset, int count) { } @@ -514,96 +608,3 @@ public virtual void WriteXmlnsAttribute(string? prefix, string namespaceUri) { } public virtual void WriteXmlnsAttribute(string? prefix, System.Xml.XmlDictionaryString namespaceUri) { } } } -namespace System.Runtime.Serialization.DataContracts -{ - public abstract partial class DataContract - { - internal const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes DataContractPreserveMemberTypes = - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods | - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors | - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties; - - internal DataContract(DataContractCriticalHelper helper) { } - - public virtual DataContract? BaseContract { [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] get { throw null; } } - public virtual string? ContractType { get { throw null; } } - public virtual bool IsBuiltInDataContract { get { throw null; } } - public virtual bool IsISerializable { get { throw null; } } - public virtual bool IsReference { get { throw null; } } - public virtual bool IsValueType { get { throw null; } } - public virtual System.Collections.Generic.Dictionary? KnownDataContracts { [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] get { throw null; } } - public virtual System.Collections.ObjectModel.ReadOnlyCollection DataMembers { get { throw null; } } - public virtual Type OriginalUnderlyingType { get { throw null; } } - public virtual System.Xml.XmlQualifiedName XmlName { get { throw null; } } - [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(DataContract.DataContractPreserveMemberTypes)] - public virtual Type UnderlyingType { get { throw null; } } - public virtual System.Xml.XmlDictionaryString? TopLevelElementName { get { throw null; } } - public virtual System.Xml.XmlDictionaryString? TopLevelElementNamespace { get { throw null; } } - - [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] - public static DataContract? GetBuiltInDataContract(string name, string ns) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] - public static System.Xml.XmlQualifiedName GetXmlName(Type type) { throw null; } - - [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] - public virtual System.Xml.XmlQualifiedName GetArrayTypeName(bool isNullable) { throw null; } - public virtual bool IsDictionaryLike([Diagnostics.CodeAnalysis.NotNullWhen(true)] out string? keyName, [Diagnostics.CodeAnalysis.NotNullWhen(true)] out string? valueName, [Diagnostics.CodeAnalysis.NotNullWhen(true)] out string? itemName) { throw null; } - } - internal abstract partial class DataContractCriticalHelper { } - public sealed partial class DataContractSet - { - [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] - public DataContractSet(DataContractSet dataContractSet) { throw null; } - public DataContractSet(ISerializationSurrogateProvider? dataContractSurrogate, System.Collections.Generic.IEnumerable? referencedTypes, System.Collections.Generic.IEnumerable? referencedCollectionTypes) { throw null; } - - public System.Collections.Generic.Dictionary Contracts { get { throw null; } } - public System.Collections.Generic.Dictionary? KnownTypesForObject { get { throw null; } } - public System.Collections.Generic.Dictionary ProcessedContracts { get { throw null; } } - public System.Collections.Hashtable SurrogateData { get { throw null; } } - - [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] - public DataContract GetDataContract(Type type) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] - public DataContract? GetDataContract(System.Xml.XmlQualifiedName key) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] - public Type? GetReferencedType(System.Xml.XmlQualifiedName xmlName, DataContract dataContract, out DataContract? referencedContract, out object[]? genericParameters, bool? supportGenericTypes = null) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] - public void ImportSchemaSet(System.Xml.Schema.XmlSchemaSet schemaSet, System.Collections.Generic.IEnumerable? typeNames, bool importXmlDataType) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] - public System.Collections.Generic.List ImportSchemaSet(System.Xml.Schema.XmlSchemaSet schemaSet, System.Collections.Generic.IEnumerable elements, bool importXmlDataType) { throw null; } - } - public sealed partial class DataMember - { - internal DataMember() { } - - public bool EmitDefaultValue { get { throw null; } } - public bool IsNullable { get { throw null; } } - public bool IsRequired { get { throw null; } } - public DataContract MemberTypeContract { [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved.")] get { throw null; } } - public string Name { get { throw null; } } - public long Order { get { throw null; } } - } - public sealed partial class XmlDataContract : DataContract - { - internal XmlDataContract(Type type) : base(default) { } - - public bool HasRoot { get { throw null; } } - public bool IsAnonymous { get { throw null; } } - public bool IsTopLevelElementNullable { get { throw null; } } - public bool IsTypeDefinedOnImport { get { throw null; } set { throw null; } } - public new bool IsValueType { get { throw null; } set { throw null; } } - public System.Xml.Schema.XmlSchemaType? XsdType { get { throw null; } } - } -} diff --git a/src/libraries/System.Runtime.Serialization.Xml/ref/System.Runtime.Serialization.Xml.csproj b/src/libraries/System.Runtime.Serialization.Xml/ref/System.Runtime.Serialization.Xml.csproj index 2cd9d7f0f77528..11c432217afb13 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/ref/System.Runtime.Serialization.Xml.csproj +++ b/src/libraries/System.Runtime.Serialization.Xml/ref/System.Runtime.Serialization.Xml.csproj @@ -9,6 +9,7 @@ + diff --git a/src/libraries/System.Runtime.Serialization.Xml/src/System.Runtime.Serialization.Xml.csproj b/src/libraries/System.Runtime.Serialization.Xml/src/System.Runtime.Serialization.Xml.csproj index 23e761675c05c8..c039cd53d89e48 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/src/System.Runtime.Serialization.Xml.csproj +++ b/src/libraries/System.Runtime.Serialization.Xml/src/System.Runtime.Serialization.Xml.csproj @@ -7,9 +7,10 @@ - - - + + + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/System.Runtime.Serialization.Xml.Canonicalization.csproj b/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/System.Runtime.Serialization.Xml.Canonicalization.Tests.csproj similarity index 100% rename from src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/System.Runtime.Serialization.Xml.Canonicalization.csproj rename to src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/System.Runtime.Serialization.Xml.Canonicalization.Tests.csproj diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/TestsConfig.xml b/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/TestsConfig.xml index c8ef97b0c9e6ff..563032a6243a52 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/TestsConfig.xml +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/TestsConfig.xml @@ -98,18 +98,18 @@ - - + + - - + + - - + + @@ -130,18 +130,18 @@ - + - + - + @@ -150,7 +150,7 @@ - + @@ -159,7 +159,7 @@ - + @@ -168,7 +168,7 @@ - + @@ -177,7 +177,7 @@ - + @@ -186,7 +186,7 @@ - + @@ -195,7 +195,7 @@ - + @@ -204,7 +204,7 @@ - + @@ -213,7 +213,7 @@ - + @@ -222,7 +222,7 @@ - + @@ -231,7 +231,7 @@ - + @@ -240,7 +240,7 @@ - + @@ -249,7 +249,7 @@ - + diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/XmlCanonicalizationTest.cs b/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/XmlCanonicalizationTest.cs index d8db0ea42ff757..ec65d0f3a614ac 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/XmlCanonicalizationTest.cs +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/Canonicalization/XmlCanonicalizationTest.cs @@ -258,7 +258,7 @@ public static void ReaderWriter_C14N_DifferentReadersWriters() Encoding encoding = Encoding.GetEncoding((string)input.Arguments[1].Value); bool mustSupportV14N = input.Arguments[2].Value == "true"; - string baselineFileName = "ReaderWriter_C14N_BaselineXML_OnlyLF.xml"; + string baselineFileName = "baselines/ReaderWriter_C14N_BaselineXML_OnlyLF.xml"; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; @@ -324,7 +324,7 @@ public static void ReaderWriter_C14N_DifferentReadersWriters() } else { - sb.Append($" {prefix}:{localName}=\"{2}\" xmlns:{value}=\"{namespaceUri}\""); + sb.Append($" {prefix}:{localName}=\"{value}\" xmlns:{prefix}=\"{namespaceUri}\""); } } sb.Append(">Hello world"); diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs b/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs index 7f5599020944f7..8fdfbacfd90582 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs @@ -35,7 +35,6 @@ static DataContractSerializerTests() } #endif [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_DateTimeOffsetAsRoot() { // Assume that UTC offset doesn't change more often than once in the day 2013-01-02 @@ -1094,7 +1093,6 @@ public static void DCS_WithListOfXElement() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_DerivedTypeWithDifferentOverrides() { var x = new DerivedTypeWithDifferentOverrides() { Name1 = "Name1", Name2 = "Name2", Name3 = "Name3", Name4 = "Name4", Name5 = "Name5" }; @@ -1122,7 +1120,7 @@ public static void DCS_TypeNamesWithSpecialCharacters() // loaded in the default ALC, which causes problems for this test. [SkipOnPlatform(TestPlatforms.Browser, "AssemblyDependencyResolver not supported in wasm")] #endif - [ActiveIssue("34072", TestRuntimes.Mono)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/34072", TestRuntimes.Mono)] public static void DCS_TypeInCollectibleALC() { ExecuteAndUnload("SerializableAssembly.dll", "SerializationTypes.SimpleType", makeCollection: false, out var weakRef); @@ -1141,7 +1139,7 @@ public static void DCS_TypeInCollectibleALC() // loaded in the default ALC, which causes problems for this test. [SkipOnPlatform(TestPlatforms.Browser, "AssemblyDependencyResolver not supported in wasm")] #endif - [ActiveIssue("34072", TestRuntimes.Mono)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/34072", TestRuntimes.Mono)] public static void DCS_CollectionTypeInCollectibleALC() { ExecuteAndUnload("SerializableAssembly.dll", "SerializationTypes.SimpleType", makeCollection: true, out var weakRef); @@ -1374,7 +1372,6 @@ public static void DCS_EnumFlags() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_SerializeClassThatImplementsInterface() { ClassImplementsInterface value = new ClassImplementsInterface() { ClassID = "ClassID", DisplayName = "DisplayName", Id = "Id", IsLoaded = true }; @@ -1529,7 +1526,6 @@ public static void DCS_KnownTypesThroughConstructor() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_DuplicatedKnownTypesWithAdapterThroughConstructor() { //Constructor# 5 @@ -1657,7 +1653,6 @@ public static void DCS_TypeWithUriTypeProperty() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_TypeWithDatetimeOffsetTypeProperty() { var value = new TypeWithDateTimeOffsetTypeProperty() { ModifiedTime = new DateTimeOffset(new DateTime(2013, 1, 2, 3, 4, 5, 6, DateTimeKind.Utc)) }; @@ -1876,7 +1871,6 @@ public static void DCS_TypeWithGenericDictionaryAsKnownType() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_TypeWithKnownTypeAttributeAndInterfaceMember() { TypeWithKnownTypeAttributeAndInterfaceMember value = new TypeWithKnownTypeAttributeAndInterfaceMember(); @@ -1888,7 +1882,6 @@ public static void DCS_TypeWithKnownTypeAttributeAndInterfaceMember() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_TypeWithKnownTypeAttributeAndListOfInterfaceMember() { TypeWithKnownTypeAttributeAndListOfInterfaceMember value = new TypeWithKnownTypeAttributeAndListOfInterfaceMember(); @@ -1987,7 +1980,6 @@ public static void DCS_GenericTypeWithNestedGenerics() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_DuplicatedKeyDateTimeOffset() { DateTimeOffset value = new DateTimeOffset(new DateTime(2013, 1, 2, 3, 4, 5, 6, DateTimeKind.Utc).AddMinutes(7)); @@ -2735,7 +2727,6 @@ public static void DCS_NonGenericDictionaryOfStringInt32() #endregion [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_BasicRoundTripResolveDTOTypes() { ObjectContainer instance = new ObjectContainer(new DTOContainer()); @@ -2971,7 +2962,6 @@ private static void DCS_BasicRoundTripResolvePrimitiveTypes(string baseline) /// Resolver is plugged in and resolves the primitive types. Verify resolver called during ser and deser /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_BasicRoundTripResolvePrimitiveTypes_NotNetFramework() { string baseline = @"<_data i:type=""a:PrimitiveContainer_foo"" xmlns:a=""http://www.default.com"">false25506553579228162514264337593543950335-19999-12-31T23:59:59.9999999-792281625142643375935439503354bc848b1-a541-40bf-8aa9-dd6ccb6d0e5610005E-3241.7976931348623157E+308-1.7976931348623157E+3089999-12-31T23:59:59.9999999Z0NaN

-INF

INF01E-45-3.4028235E+38P10675199DT2H48M5.4775807S3.4028235E+38http://www.microsoft.com/NaN-INFINFb:WCF02147483647-214748364809223372036854775807-92233720368547758080127-128032767-32768abc06553500429496729500184467440737095516150AQIDBA==<_data2 i:type=""a:PrimitiveContainer_foo"" xmlns:a=""http://www.default.com"">false25506553579228162514264337593543950335-19999-12-31T23:59:59.9999999-792281625142643375935439503354bc848b1-a541-40bf-8aa9-dd6ccb6d0e5610005E-3241.7976931348623157E+308-1.7976931348623157E+3089999-12-31T23:59:59.9999999Z0NaN

-INF

INF01E-45-3.4028235E+38P10675199DT2H48M5.4775807S3.4028235E+38http://www.microsoft.com/NaN-INFINFb:WCF02147483647-214748364809223372036854775807-92233720368547758080127-128032767-32768abc06553500429496729500184467440737095516150AQIDBA==
"; @@ -3217,7 +3207,6 @@ public static void DCS_BasicPerSerializerRoundTripAndCompare_IObjectRef() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_BasicPerSerializerRoundTripAndCompare_SampleTypes() { string assemblyName = typeof(DataContractSerializerTests).Assembly.FullName; @@ -3858,7 +3847,6 @@ public static void DCS_BasicPerSerializerRoundTripAndCompare_SelfRefCycles() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_BasicPerSerializerRoundTripAndCompare_EnumStruct() { string assemblyName = typeof(DataContractSerializerTests).Assembly.FullName; @@ -3942,7 +3930,6 @@ public static void DCS_BasicPerSerializerRoundTripAndCompare_EnumStruct() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_BasicPerSerializerRoundTripAndCompare_EnumStruct_NotNetFramework() { TestObjectInObjectContainerWithSimpleResolver(new SerializationTestTypes.AllTypes(), "<_data i:type=\"a:SerializationTestTypes.AllTypes***\" xmlns:a=\"http://schemas.datacontract.org/2004/07/SerializationTestTypes.AllTypes***\">false25506553579228162514264337593543950335redred-10001-01-01T00:00:00-792281625142643375935439503355642b5d2-87c3-a724-2390-997062f3f7a210005E-3241.7976931348623157E+308-1.7976931348623157E+3089999-12-31T23:59:59.9999999Z0NaN

-INF

INF01E-45-3.4028235E+38P10675199DT2H48M5.4775807S3.4028235E+38http://www.microsoft.com/NaNData-INFINFb:WCF02147483647-214748364809223372036854775807-92233720368547758080127-128032767-32768abc06553500429496729500184467440737095516150<_data2 i:type=\"a:SerializationTestTypes.AllTypes***\" xmlns:a=\"http://schemas.datacontract.org/2004/07/SerializationTestTypes.AllTypes***\">false25506553579228162514264337593543950335redred-10001-01-01T00:00:00-792281625142643375935439503355642b5d2-87c3-a724-2390-997062f3f7a210005E-3241.7976931348623157E+308-1.7976931348623157E+3089999-12-31T23:59:59.9999999Z0NaN

-INF

INF01E-45-3.4028235E+38P10675199DT2H48M5.4775807S3.4028235E+38http://www.microsoft.com/NaNData-INFINFb:WCF02147483647-214748364809223372036854775807-92233720368547758080127-128032767-32768abc06553500429496729500184467440737095516150
"); @@ -4040,9 +4027,10 @@ public static void DCS_KnownSerializableTypes_Stack() } [Fact] - [ActiveIssue("No issue filed yet. Turns out, CultureInfo is not serialzable, even if it is included in s_knownSerializableTypeInfos")] + [ActiveIssue("https://github.com/dotnet/runtime/issues/118358")] public static void DCS_KnownSerializableTypes_CultureInfo() { + // Turns out, CultureInfo is not serialzable, even if it is included in s_knownSerializableTypeInfos CultureInfo ci = new CultureInfo("pl"); Assert.StrictEqual(ci, DataContractSerializerHelper.SerializeAndDeserialize(ci, "", null, null, true)); } @@ -4083,7 +4071,6 @@ public static void DCS_KnownSerializableTypes_Tuples() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_TypeWithVirtualGenericProperty() { var value1 = new TypeWithVirtualGenericProperty() { Value = 1 }; @@ -4123,7 +4110,6 @@ public static void DCS_MyPersonSurrogate() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/85690", TestPlatforms.Wasi)] public static void DCS_FileStreamSurrogate() { using (var testFile = TempFile.Create()) @@ -4190,9 +4176,7 @@ public static void DCS_SampleICollectionTExplicitWithoutDC() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsWasi))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoRuntime), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsAppleMobile))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming))] public static void DCS_MemoryStream_Serialize_UsesBuiltInAdapter() { ValidateObject( @@ -4251,9 +4235,7 @@ static void ValidateObject(MemoryStream original, string expectedXml, byte[] exp } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsWasi))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoRuntime), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsAppleMobile))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming))] public static void DCS_MemoryStream_Deserialize_CompatibleWithFullFramework() { // The payloads in this test were generated by a Full Framework application. @@ -4405,7 +4387,6 @@ public static void DCS_ValidateExceptionOnUnspecifiedRootSerializationType() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_TypeWithCollectionAndDateTimeOffset() { // Adding offsetMinutes so the DateTime component in serialized strings are time-zone independent @@ -4421,7 +4402,6 @@ public static void DCS_TypeWithCollectionAndDateTimeOffset() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)] public static void DCS_TypeWithCollectionAndDateTimeOffset_ListIsNull() { // Adding offsetMinutes so the DateTime component in serialized strings are time-zone independent diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializerStressTests.cs b/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializerStressTests.cs index 694460ebb0b419..c091ce99ab60cb 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializerStressTests.cs +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializerStressTests.cs @@ -10,7 +10,6 @@ public static partial class DataContractSerializerTests { [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/34962", TestRuntimes.Mono)] public static void DCS_MyPersonSurrogate_Stress() { // This test is to verify a bug fix made in ObjectToIdCache.cs. diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/SerializationTypes.RuntimeOnly.cs b/src/libraries/System.Runtime.Serialization.Xml/tests/SerializationTypes.RuntimeOnly.cs index 1e09b903fa7e1b..a79c8f5bab2058 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/SerializationTypes.RuntimeOnly.cs +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/SerializationTypes.RuntimeOnly.cs @@ -4315,7 +4315,7 @@ public MyArgumentException(string message, string paramName) : base(message) _paramName = paramName; } -#if NET8_0_OR_GREATER +#if NET [Obsolete("Exception..ctor(SerializationInfo, StreamingContext) is obsolete.", DiagnosticId = "SYSLIB0051")] #endif protected MyArgumentException(SerializationInfo info, StreamingContext context) : base(info, context) { @@ -4334,7 +4334,7 @@ internal set } } -#if NET8_0_OR_GREATER +#if NET [Obsolete("Exception.GetObjectData is obsolete.", DiagnosticId = "SYSLIB0051")] #endif public override void GetObjectData(SerializationInfo info, StreamingContext context) diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/SerializationTypes.cs b/src/libraries/System.Runtime.Serialization.Xml/tests/SerializationTypes.cs index 158078cd60afed..74f2019d453034 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/SerializationTypes.cs +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/SerializationTypes.cs @@ -750,8 +750,7 @@ public class TypeWithSchemaFormInXmlAttribute public class CustomDocument { - private XmlDocument? _doc; - public XmlDocument Document => _doc ??= new XmlDocument(); + public XmlDocument Document => field ??= new XmlDocument(); [XmlAnyElement] public XmlNode[] Items diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/XmlDictionaryWriterTest.cs b/src/libraries/System.Runtime.Serialization.Xml/tests/XmlDictionaryWriterTest.cs index 59e6be759b4a09..8cd8f01e9f22e8 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/XmlDictionaryWriterTest.cs +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/XmlDictionaryWriterTest.cs @@ -495,7 +495,6 @@ void AssertBytesWritten(Action action, XmlBinaryNodeType no } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/85013", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsMonoAOT))] public static void XmlBaseWriter_WriteString() { const byte Chars8Text = 152; diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/XsdDataContractExporterTests/ExporterApiTests.cs b/src/libraries/System.Runtime.Serialization.Xml/tests/XsdDataContractExporterTests/ExporterApiTests.cs index 32d4a70533b514..e2005c37fc9f6b 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/XsdDataContractExporterTests/ExporterApiTests.cs +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/XsdDataContractExporterTests/ExporterApiTests.cs @@ -87,9 +87,7 @@ public static IEnumerable CanExport_MemberData() } [Theory] - [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsWasi))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoRuntime), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsAppleMobile))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming))] [MemberData(nameof(Export_MemberData))] public void Export(string testname, Action export, Action schemaCheck = null) { diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/XsdDataContractExporterTests/ExporterTypesTests.cs b/src/libraries/System.Runtime.Serialization.Xml/tests/XsdDataContractExporterTests/ExporterTypesTests.cs index 9dab40e4793b72..cfd6fa1bf8fbb5 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/XsdDataContractExporterTests/ExporterTypesTests.cs +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/XsdDataContractExporterTests/ExporterTypesTests.cs @@ -80,8 +80,7 @@ public static IEnumerable GetDynamicallyVersionedTypesTestNegativeData } [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.DataSetXmlSerializationIsSupported))] - [SkipOnPlatform(TestPlatforms.Browser, "Inconsistent and unpredictable results.")] // TODO - Why does 'TypeWithReadWriteCollectionAndNoCtorOnCollection' only cause an exception sometimes, but not all the time? What's special about wasm here? - [ActiveIssue("https://github.com/dotnet/runtime/issues/82967", TestPlatforms.Wasi)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/82967", TestPlatforms.Browser | TestPlatforms.Wasi)] [InlineData(typeof(NoDataContractWithoutParameterlessConstructor), typeof(InvalidDataContractException), @"Type 'System.Runtime.Serialization.Xml.XsdDataContractExporterTests.ExporterTypesTests+NoDataContractWithoutParameterlessConstructor' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. Alternatively, you can ensure that the type is public and has a parameterless constructor - all public members of the type will then be serialized, and no attributes will be required.")] [InlineData(typeof(DataContractWithInvalidMember), typeof(InvalidDataContractException), @"Type 'System.Runtime.Serialization.Xml.XsdDataContractExporterTests.ExporterTypesTests+NoDataContractWithoutParameterlessConstructor' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. Alternatively, you can ensure that the type is public and has a parameterless constructor - all public members of the type will then be serialized, and no attributes will be required.")] [InlineData(typeof(SerializableWithInvalidMember), typeof(InvalidDataContractException), @"Type 'System.Runtime.Serialization.Xml.XsdDataContractExporterTests.ExporterTypesTests+NoDataContractWithoutParameterlessConstructor' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. Alternatively, you can ensure that the type is public and has a parameterless constructor - all public members of the type will then be serialized, and no attributes will be required.")] diff --git a/src/libraries/System.Runtime/System.Runtime.slnx b/src/libraries/System.Runtime/System.Runtime.slnx index b7ef24259dc56a..542b3f1bdfc3c8 100644 --- a/src/libraries/System.Runtime/System.Runtime.slnx +++ b/src/libraries/System.Runtime/System.Runtime.slnx @@ -52,6 +52,14 @@ + + + + + + + + @@ -108,6 +116,14 @@ + + + + + + + + @@ -116,6 +132,22 @@ + + + + + + + + + + + + + + + + @@ -124,6 +156,14 @@ + + + + + + + + @@ -148,6 +188,22 @@ + + + + + + + + + + + + + + + + @@ -196,6 +252,14 @@ + + + + + + + + @@ -204,6 +268,14 @@ + + + + + + + + @@ -237,7 +309,7 @@ - + @@ -309,6 +381,14 @@ + + + + + + + + @@ -317,6 +397,22 @@ + + + + + + + + + + + + + + + + @@ -325,6 +421,14 @@ + + + + + + + + @@ -349,6 +453,22 @@ + + + + + + + + + + + + + + + + @@ -357,6 +477,22 @@ + + + + + + + + + + + + + + + + @@ -365,6 +501,14 @@ + + + + + + + + @@ -373,6 +517,14 @@ + + + + + + + + @@ -381,6 +533,14 @@ + + + + + + + + @@ -406,6 +566,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 8ba41f11d65e45..3a7a51a58f4971 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -1294,7 +1294,9 @@ public static partial class Convert public static object? ChangeType(object? value, System.TypeCode typeCode, System.IFormatProvider? provider) { throw null; } public static byte[] FromBase64CharArray(char[] inArray, int offset, int length) { throw null; } public static byte[] FromBase64String(string s) { throw null; } + public static byte[] FromHexString(System.ReadOnlySpan utf8Source) { throw null; } public static byte[] FromHexString(System.ReadOnlySpan chars) { throw null; } + public static System.Buffers.OperationStatus FromHexString(System.ReadOnlySpan utf8Source, System.Span destination, out int bytesConsumed, out int bytesWritten) { throw null; } public static System.Buffers.OperationStatus FromHexString(System.ReadOnlySpan source, System.Span destination, out int charsConsumed, out int bytesWritten) { throw null; } public static byte[] FromHexString(string s) { throw null; } public static System.Buffers.OperationStatus FromHexString(string source, System.Span destination, out int charsConsumed, out int bytesWritten) { throw null; } @@ -1738,7 +1740,9 @@ public static partial class Convert public static bool TryFromBase64Chars(System.ReadOnlySpan chars, System.Span bytes, out int bytesWritten) { throw null; } public static bool TryFromBase64String(string s, System.Span bytes, out int bytesWritten) { throw null; } public static bool TryToBase64Chars(System.ReadOnlySpan bytes, System.Span chars, out int charsWritten, System.Base64FormattingOptions options = System.Base64FormattingOptions.None) { throw null; } + public static bool TryToHexString(System.ReadOnlySpan source, System.Span utf8Destination, out int bytesWritten) { throw null; } public static bool TryToHexString(System.ReadOnlySpan source, System.Span destination, out int charsWritten) { throw null; } + public static bool TryToHexStringLower(System.ReadOnlySpan source, System.Span utf8Destination, out int bytesWritten) { throw null; } public static bool TryToHexStringLower(System.ReadOnlySpan source, System.Span destination, out int charsWritten) { throw null; } } public delegate TOutput Converter(TInput input) where TInput : allows ref struct where TOutput : allows ref struct; @@ -3574,6 +3578,7 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep static int System.Numerics.INumberBase.Radix { get { throw null; } } public static System.Int128 Zero { get { throw null; } } public static System.Int128 Abs(System.Int128 value) { throw null; } + public static System.Int128 BigMul(System.Int128 left, System.Int128 right, out System.Int128 lower) { throw null; } public static System.Int128 Clamp(System.Int128 value, System.Int128 min, System.Int128 max) { throw null; } public int CompareTo(System.Int128 value) { throw null; } public int CompareTo(object? value) { throw null; } @@ -4189,6 +4194,7 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep static nint System.Numerics.ISignedNumber.NegativeOne { get { throw null; } } public static nint Abs(nint value) { throw null; } public static nint Add(nint pointer, int offset) { throw null; } + public static nint BigMul(nint left, nint right, out nint lower) { throw null; } public static nint Clamp(nint value, nint min, nint max) { throw null; } public int CompareTo(nint value) { throw null; } public int CompareTo(object? value) { throw null; } @@ -6823,6 +6829,7 @@ public TypeUnloadedException(string? message, System.Exception? innerException) static System.UInt128 System.Numerics.IMultiplicativeIdentity.MultiplicativeIdentity { get { throw null; } } static int System.Numerics.INumberBase.Radix { get { throw null; } } public static System.UInt128 Zero { get { throw null; } } + public static System.UInt128 BigMul(System.UInt128 left, System.UInt128 right, out System.UInt128 lower) { throw null; } public static System.UInt128 Clamp(System.UInt128 value, System.UInt128 min, System.UInt128 max) { throw null; } public int CompareTo(object? value) { throw null; } public int CompareTo(System.UInt128 value) { throw null; } @@ -7443,6 +7450,7 @@ public TypeUnloadedException(string? message, System.Exception? innerException) static int System.Numerics.INumberBase.Radix { get { throw null; } } static nuint System.Numerics.INumberBase.Zero { get { throw null; } } public static nuint Add(nuint pointer, int offset) { throw null; } + public static nuint BigMul(nuint left, nuint right, out nuint lower) { throw null; } public static nuint Clamp(nuint value, nuint min, nuint max) { throw null; } public int CompareTo(object? value) { throw null; } public int CompareTo(nuint value) { throw null; } @@ -8552,7 +8560,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)] @@ -8885,7 +8893,8 @@ public sealed partial class DoesNotReturnIfAttribute : System.Attribute public DoesNotReturnIfAttribute(bool parameterValue) { } public bool ParameterValue { get { throw null; } } } - [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Field | System.AttributeTargets.GenericParameter | System.AttributeTargets.Interface | System.AttributeTargets.Method | System.AttributeTargets.Parameter | System.AttributeTargets.Property | System.AttributeTargets.ReturnValue | System.AttributeTargets.Struct, Inherited=false)] + [System.Runtime.CompilerServices.CompilerLoweringPreserveAttribute] + [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Field | System.AttributeTargets.GenericParameter | System.AttributeTargets.Interface | System.AttributeTargets.Method | System.AttributeTargets.Parameter | System.AttributeTargets.Property | System.AttributeTargets.ReturnValue | System.AttributeTargets.Struct, Inherited = false)] public sealed partial class DynamicallyAccessedMembersAttribute : System.Attribute { public DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes memberTypes) { } @@ -8894,6 +8903,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, @@ -9023,6 +9033,7 @@ public RequiresAssemblyFilesAttribute(string message) { } public sealed partial class RequiresDynamicCodeAttribute : System.Attribute { public RequiresDynamicCodeAttribute(string message) { } + public bool ExcludeStatics { get; set; } public string Message { get { throw null; } } public string? Url { get { throw null; } set { } } } @@ -9030,6 +9041,7 @@ public RequiresDynamicCodeAttribute(string message) { } public sealed partial class RequiresUnreferencedCodeAttribute : System.Attribute { public RequiresUnreferencedCodeAttribute(string message) { } + public bool ExcludeStatics { get; set; } public string Message { get { throw null; } } public string? Url { get { throw null; } set { } } } @@ -13265,6 +13277,11 @@ public enum CompilationRelaxations { NoStringInterning = 8, } + [System.AttributeUsageAttribute(System.AttributeTargets.Class, Inherited = false)] + public sealed class CompilerLoweringPreserveAttribute : System.Attribute + { + public CompilerLoweringPreserveAttribute() { } + } [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Method | System.AttributeTargets.Module)] public partial class CompilationRelaxationsAttribute : System.Attribute { @@ -13478,6 +13495,13 @@ public sealed partial class ExtensionAttribute : System.Attribute { public ExtensionAttribute() { } } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Struct | System.AttributeTargets.Enum | System.AttributeTargets.Method | System.AttributeTargets.Property | System.AttributeTargets.Field | System.AttributeTargets.Event | System.AttributeTargets.Interface | System.AttributeTargets.Delegate, Inherited = false)] + public sealed partial class ExtensionMarkerAttribute : System.Attribute + { + public ExtensionMarkerAttribute(string name) { } + public string Name { get { throw null; } } + } [System.AttributeUsageAttribute(System.AttributeTargets.Field)] public sealed partial class FixedAddressValueTypeAttribute : System.Attribute { @@ -14012,7 +14036,9 @@ public static void InitBlockUnaligned(ref byte startAddress, byte value, uint by [System.CLSCompliantAttribute(false)] public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount) { } public static bool IsAddressGreaterThan([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; } + public static bool IsAddressGreaterThanOrEqualTo([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; } public static bool IsAddressLessThan([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; } + public static bool IsAddressLessThanOrEqualTo([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; } public static bool IsNullRef(ref readonly T source) where T : allows ref struct { throw null; } public static ref T NullRef() where T : allows ref struct { throw null; } public static T ReadUnaligned(scoped ref readonly byte source) where T : allows ref struct { throw null; } diff --git a/src/libraries/System.Runtime/tests/System.Diagnostics.Debug.Tests/DebuggerDisplayAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Diagnostics.Debug.Tests/DebuggerDisplayAttributeTests.cs index 2d531adca9f4b8..1a941c77c7c938 100644 --- a/src/libraries/System.Runtime/tests/System.Diagnostics.Debug.Tests/DebuggerDisplayAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Diagnostics.Debug.Tests/DebuggerDisplayAttributeTests.cs @@ -11,7 +11,7 @@ public class DebuggerDisplayAttributeTests [InlineData(null)] [InlineData("")] [InlineData("Value")] - public void Ctor_Value(string value) + public void Ctor_Value(string? value) { var attribute = new DebuggerDisplayAttribute(value); Assert.Equal(string.Empty, attribute.Name); @@ -24,7 +24,7 @@ public void Ctor_Value(string value) [Theory] [InlineData(null)] [InlineData("Name")] - public void Name_Set_GetReturnsExpected(string name) + public void Name_Set_GetReturnsExpected(string? name) { var attribute = new DebuggerDisplayAttribute("Value") { Name = name }; Assert.Equal(name, attribute.Name); @@ -33,7 +33,7 @@ public void Name_Set_GetReturnsExpected(string name) [Theory] [InlineData(null)] [InlineData("Type")] - public void Type_Set_GetReturnsExpected(string type) + public void Type_Set_GetReturnsExpected(string? type) { var attribute = new DebuggerDisplayAttribute("Value") { Type = type }; Assert.Equal(type, attribute.Type); @@ -58,7 +58,7 @@ public void Target_SetNull_ThrowsArgumentNullException() [Theory] [InlineData(null)] [InlineData("TargetTypeName")] - public void TargetTypeName_Set_GetReturnsExpected(string targetTypeName) + public void TargetTypeName_Set_GetReturnsExpected(string? targetTypeName) { var attribute = new DebuggerDisplayAttribute("Value") { TargetTypeName = targetTypeName }; Assert.Equal(targetTypeName, attribute.TargetTypeName); diff --git a/src/libraries/System.Runtime/tests/System.Diagnostics.Debug.Tests/DebuggerTypeProxyAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Diagnostics.Debug.Tests/DebuggerTypeProxyAttributeTests.cs index 411c4e9d095059..9128a1045ed757 100644 --- a/src/libraries/System.Runtime/tests/System.Diagnostics.Debug.Tests/DebuggerTypeProxyAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Diagnostics.Debug.Tests/DebuggerTypeProxyAttributeTests.cs @@ -10,7 +10,7 @@ public class DebuggerTypeProxyAttributeTests [Theory] [InlineData(null)] [InlineData("TypeName")] - public void Ctor_TypeName(string typeName) + public void Ctor_TypeName(string? typeName) { var attribute = new DebuggerTypeProxyAttribute(typeName); Assert.Equal(typeName, attribute.ProxyTypeName); @@ -54,7 +54,7 @@ public void Target_SetNull_ThrowsArgumentNullException() [Theory] [InlineData(null)] [InlineData("TargetTypeName")] - public void TargetTypeName_Set_GetReturnsExpected(string targetTypeName) + public void TargetTypeName_Set_GetReturnsExpected(string? targetTypeName) { var attribute = new DebuggerTypeProxyAttribute("TypeName") { TargetTypeName = targetTypeName }; Assert.Equal(targetTypeName, attribute.TargetTypeName); diff --git a/src/libraries/System.Runtime/tests/System.Diagnostics.Debug.Tests/DebuggerVisualizerAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Diagnostics.Debug.Tests/DebuggerVisualizerAttributeTests.cs index ee67bbab078492..f39a8070921179 100644 --- a/src/libraries/System.Runtime/tests/System.Diagnostics.Debug.Tests/DebuggerVisualizerAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Diagnostics.Debug.Tests/DebuggerVisualizerAttributeTests.cs @@ -10,7 +10,7 @@ public class DebuggerVisualizerAttributeTests [Theory] [InlineData(null)] [InlineData("VisualizerTypeName")] - public void Ctor_VisualizerTypeName(string visualizerTypeName) + public void Ctor_VisualizerTypeName(string? visualizerTypeName) { var attribute = new DebuggerVisualizerAttribute(visualizerTypeName); Assert.Equal(visualizerTypeName, attribute.VisualizerTypeName); @@ -22,7 +22,7 @@ public void Ctor_VisualizerTypeName(string visualizerTypeName) [Theory] [InlineData(null, null)] [InlineData("VisualizerTypeName", "VisualizerObjectSourceTypeName")] - public void Ctor_VisualizerTypeName_VisualizerObjectSourceTypeName(string visualizerTypeName, string visualizerObjectSourceTypeName) + public void Ctor_VisualizerTypeName_VisualizerObjectSourceTypeName(string? visualizerTypeName, string? visualizerObjectSourceTypeName) { var attribute = new DebuggerVisualizerAttribute(visualizerTypeName, visualizerObjectSourceTypeName); Assert.Equal(visualizerTypeName, attribute.VisualizerTypeName); @@ -34,7 +34,7 @@ public void Ctor_VisualizerTypeName_VisualizerObjectSourceTypeName(string visual [Theory] [InlineData(null, typeof(int))] [InlineData("VisualizerTypeName", typeof(DebuggerVisualizerAttributeTests))] - public void Ctor_VisualizerTypeName_VisualizerObjectSourceType(string visualizerTypeName, Type visualizerObjectSourceType) + public void Ctor_VisualizerTypeName_VisualizerObjectSourceType(string? visualizerTypeName, Type visualizerObjectSourceType) { var attribute = new DebuggerVisualizerAttribute(visualizerTypeName, visualizerObjectSourceType); Assert.Equal(visualizerTypeName, attribute.VisualizerTypeName); @@ -70,7 +70,7 @@ public void Ctor_VisualizerType_VisualizerObjectSourceType(Type visualizerType, [Theory] [InlineData(typeof(string), null)] [InlineData(typeof(DebuggerVisualizerAttributeTests), "VisualizerObjectSourceTypeName")] - public void Ctor_VisualizerType_VisualizerObjectSourceTypeName(Type visualizerType, string visualizerObjectSourceTypeName) + public void Ctor_VisualizerType_VisualizerObjectSourceTypeName(Type visualizerType, string? visualizerObjectSourceTypeName) { var attribute = new DebuggerVisualizerAttribute(visualizerType, visualizerObjectSourceTypeName); Assert.Equal(visualizerType.AssemblyQualifiedName, attribute.VisualizerTypeName); diff --git a/src/libraries/System.Runtime/tests/System.Diagnostics.Tools.Tests/System/CodeDom/Compiler/GeneratedCodeAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Diagnostics.Tools.Tests/System/CodeDom/Compiler/GeneratedCodeAttributeTests.cs index 4eec33dc065695..40144596ec99cb 100644 --- a/src/libraries/System.Runtime/tests/System.Diagnostics.Tools.Tests/System/CodeDom/Compiler/GeneratedCodeAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Diagnostics.Tools.Tests/System/CodeDom/Compiler/GeneratedCodeAttributeTests.cs @@ -10,7 +10,7 @@ public class GeneratedCodeAttributeTests [Theory] [InlineData(null, null)] [InlineData("Tool", "Version")] - public void TestConstructor(string tool, string version) + public void TestConstructor(string? tool, string? version) { GeneratedCodeAttribute gca = new GeneratedCodeAttribute(tool, version); diff --git a/src/libraries/System.Runtime/tests/System.Diagnostics.Tools.Tests/System/Diagnostics/CodeAnalysis/SuppressMessageAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Diagnostics.Tools.Tests/System/Diagnostics/CodeAnalysis/SuppressMessageAttributeTests.cs index 91a32840ba83a8..d3fe7900580c56 100644 --- a/src/libraries/System.Runtime/tests/System.Diagnostics.Tools.Tests/System/Diagnostics/CodeAnalysis/SuppressMessageAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Diagnostics.Tools.Tests/System/Diagnostics/CodeAnalysis/SuppressMessageAttributeTests.cs @@ -12,7 +12,7 @@ public class SuppressMessageAttributeTests [InlineData("", "", "", "", "", "")] [InlineData(null, null, null, null, null, null)] [InlineData("", null, "Justification", null, "Scope", "")] - public void TestConstructor(string category, string id, string justification, string messageId, string scope, string target) + public void TestConstructor(string? category, string? id, string? justification, string? messageId, string? scope, string? target) { SuppressMessageAttribute sma = new SuppressMessageAttribute(category, id) { diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/GetStringComparerTests.cs b/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/GetStringComparerTests.cs index 0735620db91af1..19337e915d1bf5 100644 --- a/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/GetStringComparerTests.cs +++ b/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/GetStringComparerTests.cs @@ -32,7 +32,7 @@ public void GetStringComparer_Invalid() [InlineData("abc", "ABC", "en-US", CompareOptions.OrdinalIgnoreCase, 0, 0)] [InlineData("Cot\u00E9", "cot\u00E9", "fr-FR", CompareOptions.IgnoreCase, 0, 0)] [InlineData("cot\u00E9", "c\u00F4te", "fr-FR", CompareOptions.None, 1, -1)] - public static void Compare(string x, string y, string cultureName, CompareOptions options, int expectedNls, int expectedICU) + public static void Compare(string? x, string? y, string cultureName, CompareOptions options, int expectedNls, int expectedICU) { int expected = PlatformDetection.IsNlsGlobalization ? expectedNls : expectedICU; StringComparer comparer = new CultureInfo(cultureName).CompareInfo.GetStringComparer(options); diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/Normalization/StringNormalizationTests.cs b/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/Normalization/StringNormalizationTests.cs index bba0ddb088d462..d2b35b018a3fac 100644 --- a/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/Normalization/StringNormalizationTests.cs +++ b/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/Normalization/StringNormalizationTests.cs @@ -126,6 +126,11 @@ public void Normalize_Invalid() AssertExtensions.Throws("strInput", () => "\uD800\uD800".Normalize()); // Invalid surrogate pair AssertExtensions.Throws("source", () => "\uD800\uD800".AsSpan().TryNormalize(destination, out int charsWritten)); // Invalid surrogate pair + + char[] overlappingDestination = new char[5] { 'a', 'b', 'c', 'd', 'e' }; + Assert.Throws(() => overlappingDestination.AsSpan().TryNormalize(overlappingDestination.AsSpan(), out int charsWritten, NormalizationForm.FormC)); + Assert.Throws(() => overlappingDestination.AsSpan(0, 3).TryNormalize(overlappingDestination.AsSpan(), out int charsWritten, NormalizationForm.FormC)); + Assert.Throws(() => overlappingDestination.AsSpan(4).TryNormalize(overlappingDestination.AsSpan(), out int charsWritten, NormalizationForm.FormC)); } [Fact] diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CultureInfo/CultureInfoCurrentCulture.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CultureInfo/CultureInfoCurrentCulture.cs index c13c8446ffa89c..914b505081a769 100644 --- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CultureInfo/CultureInfoCurrentCulture.cs +++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CultureInfo/CultureInfoCurrentCulture.cs @@ -149,7 +149,7 @@ public void CurrentCulture_BasedOnLangEnvVar(string langEnvVar, string expectedC [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData("")] [InlineData(null)] - public void CurrentCulture_DefaultWithNoLang(string langEnvVar) + public void CurrentCulture_DefaultWithNoLang(string? langEnvVar) { var psi = new ProcessStartInfo(); TestEnvironment.ClearGlobalizationEnvironmentVars(psi.Environment); diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CultureInfo/CultureInfoGetFormat.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CultureInfo/CultureInfoGetFormat.cs index 2636285e87938b..2d067a09b5dc3a 100644 --- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CultureInfo/CultureInfoGetFormat.cs +++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CultureInfo/CultureInfoGetFormat.cs @@ -11,7 +11,7 @@ public class CultureInfoGetFormat [InlineData(typeof(NumberFormatInfo), typeof(NumberFormatInfo))] [InlineData(typeof(DateTimeFormatInfo), typeof(DateTimeFormatInfo))] [InlineData(typeof(string), null)] - public void GetFormat(Type formatType, Type expectedFormatType) + public void GetFormat(Type formatType, Type? expectedFormatType) { object format = new CultureInfo("en-US").GetFormat(formatType); if (expectedFormatType == null) diff --git a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/Directory/CreateDirectory.cs b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/Directory/CreateDirectory.cs index 7ed023adca957b..44fce575b9cd58 100644 --- a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/Directory/CreateDirectory.cs +++ b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/Directory/CreateDirectory.cs @@ -3,14 +3,13 @@ using System.Linq; using Microsoft.DotNet.RemoteExecutor; -using Microsoft.DotNet.XUnitExtensions; using Xunit; namespace System.IO.Tests { public class Directory_CreateDirectory : FileSystemTest { - public static TheoryData ReservedDeviceNames = IOInputs.GetReservedDeviceNames().ToTheoryData(); + public static TheoryData ReservedDeviceNames = IOInputs.GetReservedDeviceNames().ToTheoryData(); #region Utilities public virtual DirectoryInfo Create(string path) diff --git a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/DisabledFileLockingTests/DisabledFileLockingSwitchTests.cs b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/DisabledFileLockingTests/DisabledFileLockingSwitchTests.cs index 8b83bae43f2f65..06495b535242fb 100644 --- a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/DisabledFileLockingTests/DisabledFileLockingSwitchTests.cs +++ b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/DisabledFileLockingTests/DisabledFileLockingSwitchTests.cs @@ -9,7 +9,6 @@ namespace System.IO.Tests public class DisabledFileLockingSwitchTests { [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951", typeof(PlatformDetection), nameof(PlatformDetection.IsSingleFile))] public static void ConfigSwitchIsHonored() { Assert.Equal(OperatingSystem.IsWindows(), PlatformDetection.IsFileLockingEnabled); diff --git a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/DisabledFileLockingTests/System.IO.FileSystem.DisabledFileLocking.Tests.csproj b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/DisabledFileLockingTests/System.IO.FileSystem.DisabledFileLocking.Tests.csproj index 614de3d1ce979f..99ff042de2e779 100644 --- a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/DisabledFileLockingTests/System.IO.FileSystem.DisabledFileLocking.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/DisabledFileLockingTests/System.IO.FileSystem.DisabledFileLocking.Tests.csproj @@ -24,6 +24,7 @@ + diff --git a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/File/AppendAllBytesAsync.cs b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/File/AppendAllBytesAsync.cs index 89ef9b63f665de..00d591fdc7f232 100644 --- a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/File/AppendAllBytesAsync.cs +++ b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/File/AppendAllBytesAsync.cs @@ -24,10 +24,10 @@ public async Task NullParametersAsync() } [Fact] - public void NonExistentPathAsync() + public async Task NonExistentPathAsync() { - Assert.ThrowsAsync(() => File.AppendAllBytesAsync(Path.Combine(TestDirectory, GetTestFileName(), GetTestFileName()), new byte[0])); - Assert.ThrowsAsync(() => File.AppendAllBytesAsync(Path.Combine(TestDirectory, GetTestFileName(), GetTestFileName()), ReadOnlyMemory.Empty)); + await Assert.ThrowsAsync(async () => await File.AppendAllBytesAsync(Path.Combine(TestDirectory, GetTestFileName(), GetTestFileName()), new byte[0])); + await Assert.ThrowsAsync(async () => await File.AppendAllBytesAsync(Path.Combine(TestDirectory, GetTestFileName(), GetTestFileName()), ReadOnlyMemory.Empty)); } [Fact] diff --git a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/File/ChangeExtension.cs b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/File/ChangeExtension.cs index cb4156cd44a764..983290ab52d81d 100644 --- a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/File/ChangeExtension.cs +++ b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/File/ChangeExtension.cs @@ -15,7 +15,7 @@ public class File_ChangeExtension : FileSystemTest [InlineData("filename.tmp", "...", "filename...")] [InlineData("filename.tmp", null, "filename")] [InlineData("filename.tmp.doc", ".tmp", "filename.tmp.tmp")] - public void ValidExtensions(string original, string newExtension, string expected) + public void ValidExtensions(string? original, string? newExtension, string? expected) { string newPath = Path.ChangeExtension(original, newExtension); Assert.Equal(expected, newPath); diff --git a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/FileSystemTest.cs b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/FileSystemTest.cs index e64022e95c2bb4..0c89d585c5ff01 100644 --- a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/FileSystemTest.cs +++ b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/FileSystemTest.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Diagnostics; -using Microsoft.DotNet.XUnitExtensions; using Xunit; namespace System.IO.Tests @@ -23,15 +22,15 @@ public abstract partial class FileSystemTest : FileCleanupTestBase public static TheoryData PathsWithInvalidColons = TestData.PathsWithInvalidColons; public static TheoryData PathsWithInvalidCharacters = TestData.PathsWithInvalidCharacters; public static TheoryData TrailingCharacters = TestData.TrailingCharacters; - public static TheoryData ValidPathComponentNames = IOInputs.GetValidPathComponentNames().ToTheoryData(); - public static TheoryData SimpleWhiteSpace = IOInputs.GetSimpleWhiteSpace().ToTheoryData(); - public static TheoryData WhiteSpace = IOInputs.GetWhiteSpace().ToTheoryData(); - public static TheoryData UncPathsWithoutShareName = IOInputs.GetUncPathsWithoutShareName().ToTheoryData(); - public static TheoryData PathsWithReservedDeviceNames = IOInputs.GetPathsWithReservedDeviceNames().ToTheoryData(); - public static TheoryData PathsWithColons = IOInputs.GetPathsWithColons().ToTheoryData(); - public static TheoryData PathsWithComponentLongerThanMaxComponent = IOInputs.GetPathsWithComponentLongerThanMaxComponent().ToTheoryData(); - public static TheoryData ControlWhiteSpace = IOInputs.GetControlWhiteSpace().ToTheoryData(); - public static TheoryData NonControlWhiteSpace = IOInputs.GetNonControlWhiteSpace().ToTheoryData(); + public static TheoryData ValidPathComponentNames = IOInputs.GetValidPathComponentNames().ToTheoryData(); + public static TheoryData SimpleWhiteSpace = IOInputs.GetSimpleWhiteSpace().ToTheoryData(); + public static TheoryData WhiteSpace = IOInputs.GetWhiteSpace().ToTheoryData(); + public static TheoryData UncPathsWithoutShareName = IOInputs.GetUncPathsWithoutShareName().ToTheoryData(); + public static TheoryData PathsWithReservedDeviceNames = IOInputs.GetPathsWithReservedDeviceNames().ToTheoryData(); + public static TheoryData PathsWithColons = IOInputs.GetPathsWithColons().ToTheoryData(); + public static TheoryData PathsWithComponentLongerThanMaxComponent = IOInputs.GetPathsWithComponentLongerThanMaxComponent().ToTheoryData(); + public static TheoryData ControlWhiteSpace = IOInputs.GetControlWhiteSpace().ToTheoryData(); + public static TheoryData NonControlWhiteSpace = IOInputs.GetNonControlWhiteSpace().ToTheoryData(); public static TheoryData TrailingSeparators { diff --git a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/System.IO.FileSystem.Tests.csproj b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/System.IO.FileSystem.Tests.csproj index 77100193a31e2a..86eda9fae42586 100644 --- a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/System.IO.FileSystem.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/System.IO.FileSystem.Tests.csproj @@ -244,6 +244,7 @@ + diff --git a/src/libraries/System.Runtime/tests/System.IO.Tests/IndentedTextWriter.cs b/src/libraries/System.Runtime/tests/System.IO.Tests/IndentedTextWriter.cs index 11b9ad7b82a193..93df41dc7f7afc 100644 --- a/src/libraries/System.Runtime/tests/System.IO.Tests/IndentedTextWriter.cs +++ b/src/libraries/System.Runtime/tests/System.IO.Tests/IndentedTextWriter.cs @@ -378,7 +378,7 @@ public static void Indent_RoundtripsAndAffectsOutput(int indent) [InlineData("")] [InlineData("space")] [InlineData(" ")] - public static void TabString_UsesProvidedString(string tabString) + public static void TabString_UsesProvidedString(string? tabString) { var sb = new StringBuilder(); var sw = new StringWriter(sb); diff --git a/src/libraries/System.Runtime/tests/System.IO.Tests/MemoryStream/MemoryStreamTests.cs b/src/libraries/System.Runtime/tests/System.IO.Tests/MemoryStream/MemoryStreamTests.cs index ae2961f111a2dd..23d4b88c3da8d2 100644 --- a/src/libraries/System.Runtime/tests/System.IO.Tests/MemoryStream/MemoryStreamTests.cs +++ b/src/libraries/System.Runtime/tests/System.IO.Tests/MemoryStream/MemoryStreamTests.cs @@ -95,16 +95,11 @@ from bufferContext in (10, 0), (10, 5), (10, 10), - (Array.MaxLength, 0), - (Array.MaxLength, Array.MaxLength) } select new object[] {mode, bufferContext.bufferSize, bufferContext.origin}; - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] + [Theory] [MemberData(nameof(MemoryStream_PositionOverflow_Throws_MemberData))] - [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS, "https://github.com/dotnet/runtime/issues/92467")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/100225", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoRuntime), nameof(PlatformDetection.IsWindows), nameof(PlatformDetection.IsX64Process))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/100558", TestPlatforms.Linux)] public void MemoryStream_SeekOverflow_Throws(SeekMode mode, int bufferSize, int origin) { byte[] buffer = new byte[bufferSize]; diff --git a/src/libraries/System.Runtime/tests/System.IO.UnmanagedMemoryStream.Tests/Uma.ReadWriteStructArray.cs b/src/libraries/System.Runtime/tests/System.IO.UnmanagedMemoryStream.Tests/Uma.ReadWriteStructArray.cs index f84cd74c9ab702..e493909dc68c92 100644 --- a/src/libraries/System.Runtime/tests/System.IO.UnmanagedMemoryStream.Tests/Uma.ReadWriteStructArray.cs +++ b/src/libraries/System.Runtime/tests/System.IO.UnmanagedMemoryStream.Tests/Uma.ReadWriteStructArray.cs @@ -115,6 +115,7 @@ public static void UmaReadWriteStructArrayGenericIntStruct_Valid() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/117166", TestPlatforms.Browser)] public static void UmaReadWriteGenericStringStructArray_ThrowsArgumentException() { const int capacity = 100; diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyNameTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyNameTests.cs index f5225adc18b783..a9d4c2f12b7013 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyNameTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyNameTests.cs @@ -90,7 +90,7 @@ public void Ctor_String_Public_Key(string name, string expectedName) [InlineData(" \t \r \n ", typeof(FileLoadException))] [InlineData("aa, culture=en-en, culture=en-en", typeof(FileLoadException))] [InlineData("MyAssemblyName, PublicKey=00000000000000000400000000000000, PublicKeyToken=b77a5c561934e089", typeof(FileLoadException))] - public void Ctor_String_Invalid(string assemblyName, Type exceptionType) + public void Ctor_String_Invalid(string? assemblyName, Type exceptionType) { Assert.Throws(exceptionType, () => new AssemblyName(assemblyName)); } @@ -409,7 +409,7 @@ public void GetPublicKeyToken_CurrentlyExecutingAssembly() [InlineData("", "")] [InlineData(" name ", " name ")] [InlineData("\tname\t", "\tname\t")] - public void Name_Set(string name, string expectedName) + public void Name_Set(string? name, string? expectedName) { AssemblyName assemblyName = new AssemblyName("MyAssemblyName"); assemblyName.Name = name; @@ -421,7 +421,7 @@ public void Name_Set(string name, string expectedName) [MemberData(nameof(Names_TestDataRequiresEscaping))] [InlineData(null, "")] [InlineData("", "")] - public void Name_Set_FullName(string name, string expectedName) + public void Name_Set_FullName(string? name, string expectedName) { AssemblyName assemblyName = new AssemblyName("MyAssemblyName"); assemblyName.Name = name; diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs index eff32bc09ffe5f..f3bd40bff2b862 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs @@ -844,8 +844,7 @@ public void AssemblyLoadFromBytesNeg() } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsAssemblyLoadingSupported), nameof(PlatformDetection.HasAssemblyFiles))] - [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.MacCatalyst, "Symbols are in a different location on iOS/tvOS/MacCatalyst")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951", TestPlatforms.Android)] + [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.MacCatalyst | TestPlatforms.Android, "Symbols are in a different location on mobile platforms")] public void AssemblyLoadFromBytesWithSymbols() { Assembly assembly = typeof(AssemblyTests).Assembly; diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/CustomAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/CustomAttributeTests.cs index c3c7f3c465e413..e850c30f723a14 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/CustomAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/CustomAttributeTests.cs @@ -275,5 +275,14 @@ public void BoxedEnumAttributes() Assert.Equal(typeof(EnumForArrays[]), att.B3.GetType()); Assert.Equal(EnumForArrays.Two, ((EnumForArrays[])att.B3)[0]); } + + [Fact] + public void SystemObject_GetCustomAttributes_InheritanceConsistency() + { + Type objectType = typeof(object); + object[] attributesWithoutInherit = objectType.GetCustomAttributes(inherit: false); + object[] attributesWithInherit = objectType.GetCustomAttributes(inherit: true); + Assert.Equal(attributesWithoutInherit.Length, attributesWithInherit.Length); + } } } diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs index d1c1f63d830e0a..b65efe98b431e7 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/DefaultBinderTests.cs @@ -182,7 +182,7 @@ public static void InvokeWithNamedParametersOutOfOrder() [Theory] [InlineData("")] [InlineData(null)] - public static void InvokeWithCreateInstance(string name) + public static void InvokeWithCreateInstance(string? name) { Assert.IsType(typeof(Sample).InvokeMember(name, BindingFlags.CreateInstance, null, null, null)); } diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/FieldInfoTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/FieldInfoTests.cs index d8c6425f3b1a72..b2d76725e99396 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/FieldInfoTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/FieldInfoTests.cs @@ -777,7 +777,7 @@ struct Inner [InlineData(long.MaxValue)] [InlineData(byte.MaxValue)] [InlineData(null)] - public static void SetValueDirect_GetValueDirectRoundDataTest(object value) + public static void SetValueDirect_GetValueDirectRoundDataTest(object? value) { FieldData testField = new FieldData { inner = new Inner() { field = -1 } }; FieldInfo innerFieldInfo = typeof(FieldData).GetField(nameof(FieldData.inner)); diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/MethodInfoTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/MethodInfoTests.cs index 5e791cc2d6dd0d..9a102cec6b5c4d 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/MethodInfoTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/MethodInfoTests.cs @@ -162,7 +162,7 @@ public void CreateDelegate_ValueTypeParameters() [Theory] [InlineData(typeof(MI_BaseClass), nameof(MI_BaseClass.VirtualMethod), null, typeof(ArgumentNullException))] [InlineData(typeof(MI_BaseClass), nameof(MI_BaseClass.VirtualMethod), typeof(Delegate_Void_Int), typeof(ArgumentException))] - public void CreateDelegate_Invalid(Type type, string name, Type delegateType, Type exceptionType) + public void CreateDelegate_Invalid(Type type, string name, Type? delegateType, Type exceptionType) { MethodInfo methodInfo = GetMethod(type, name); Assert.Throws(exceptionType, () => methodInfo.CreateDelegate(delegateType)); diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/ParameterInfoTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/ParameterInfoTests.cs index 7fcf2f896d8f00..2a68eab6e2743c 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/ParameterInfoTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/ParameterInfoTests.cs @@ -312,7 +312,7 @@ public void IsIn(Type type, string name, int index, bool expected) [InlineData(typeof(ParameterInfoMetadata), "MethodWithDefaultNullableDateTime", 0, null)] [InlineData(typeof(ParameterInfoMetadata), "MethodWithEnum", 0, AttributeTargets.All)] [InlineData(typeof(ParameterInfoMetadata), "MethodWithNullableEnum", 0, (int)AttributeTargets.All)] - public void DefaultValue(Type type, string name, int index, object expected) + public void DefaultValue(Type type, string name, int index, object? expected) { ParameterInfo parameterInfo = GetParameterInfo(type, name, index); Assert.Equal(expected, parameterInfo.DefaultValue); @@ -320,7 +320,7 @@ public void DefaultValue(Type type, string name, int index, object expected) [Theory] [InlineData(typeof(ParameterInfoMetadata), "MethodWithDefaultDateTime", 0, null)] - public void DefaultValue_broken_on_NETFX(Type type, string name, int index, object expected) + public void DefaultValue_broken_on_NETFX(Type type, string name, int index, object? expected) { ParameterInfo parameterInfo = GetParameterInfo(type, name, index); Assert.Equal(expected, parameterInfo.DefaultValue); diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/TypeInfoTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/TypeInfoTests.cs index 231c6f1119bcdf..08b9699a0fa1f3 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/TypeInfoTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/TypeInfoTests.cs @@ -76,7 +76,7 @@ public void DeclaredEvents(Type type, string name, bool exists, string eventHand [InlineData(typeof(TI_SubClass), nameof(TI_SubClass.s_field), true, typeof(string), false)] [InlineData(typeof(TI_SubClass), nameof(TI_SubClass.s_readonlyField), true, typeof(string), false)] [InlineData(typeof(TI_SubClass), nameof(TI_SubClass.s_volatileField), true, typeof(string), false)] - public void DeclaredFields(Type type, string name, bool exists, Type fieldType, bool isPrivate) + public void DeclaredFields(Type type, string name, bool exists, Type? fieldType, bool isPrivate) { IEnumerable fields = type.GetTypeInfo().DeclaredFields.Select(fieldInfo => fieldInfo.Name); FieldInfo declaredFieldInfo = type.GetTypeInfo().GetDeclaredField(name); @@ -395,7 +395,7 @@ public void GenericTypeParameters(Type type, string[] expected, string[] baseExp [InlineData(10, nameof(IntEnum.Enum10))] [InlineData(45, nameof(IntEnum.Enum45))] [InlineData(8, null)] - public void GetEnumName(object value, string expected) + public void GetEnumName(object value, string? expected) { Assert.Equal(expected, typeof(IntEnum).GetTypeInfo().GetEnumName(value)); } @@ -595,7 +595,7 @@ public void IsInstanceOfType(Type type, object o, bool expected) [InlineData(typeof(uint[]), typeof(int[]), true)] [InlineData(typeof(IList), typeof(int[]), true)] [InlineData(typeof(IList), typeof(int[]), true)] - public void IsAssignable(Type type, Type c, bool expected) + public void IsAssignable(Type type, Type? c, bool expected) { Assert.Equal(expected, type.GetTypeInfo().IsAssignableFrom(c)); Assert.Equal(expected, type.GetTypeInfo().IsAssignableFrom(c?.GetTypeInfo())); @@ -1114,7 +1114,7 @@ public void GetDeclaredNestedType_NullName_ThrowsArgumentNullException() [InlineData(typeof(TI_BaseClass), null)] [InlineData(typeof(string[]), typeof(string))] [InlineData(typeof(int[]), typeof(int))] - public void GetElementType(Type type, Type expected) + public void GetElementType(Type type, Type? expected) { Assert.Equal(expected, type.GetTypeInfo().GetElementType()); } @@ -1317,6 +1317,14 @@ public void FullName() Assert.NotNull(t.GetMethod("ListTypeParam").ReturnType.GetTypeInfo().FullName); } + [Fact] + public static void FullName_FunctionPointers_ReturnsExpected() + { + Assert.Null(typeof(delegate*).FullName); + Assert.Null(typeof(delegate**).FullName); + Assert.Null(typeof(delegate***).FullName); + } + [Fact] public void Guid() { @@ -1490,6 +1498,14 @@ public void Namespace(Type type, string expected) Assert.Equal(expected, type.GetTypeInfo().Namespace); } + [Fact] + public static void Namespace_FunctionPointers_ReturnsNull() + { + Assert.Null(typeof(delegate*).Namespace); + Assert.Null(typeof(delegate**).Namespace); + Assert.Null(typeof(delegate***).Namespace); + } + [Theory] [InlineData(typeof(TI_BaseClass), false)] [InlineData(typeof(PublicEnum), false)] diff --git a/src/libraries/System.Runtime/tests/System.Runtime.CompilerServices.Unsafe.Tests/UnsafeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.CompilerServices.Unsafe.Tests/UnsafeTests.cs index 3d45fe2fbe0527..b5bec7f9357f62 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.CompilerServices.Unsafe.Tests/UnsafeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.CompilerServices.Unsafe.Tests/UnsafeTests.cs @@ -805,6 +805,25 @@ public static unsafe void RefIsAddressGreaterThan() Assert.False(Unsafe.IsAddressGreaterThan(ref Unsafe.AsRef(null), ref Unsafe.AsRef(null))); } + [Fact] + public static unsafe void RefIsAddressGreaterThanOrEqualTo() + { + int[] a = new int[2]; + + Assert.True(Unsafe.IsAddressGreaterThanOrEqualTo(ref a[0], ref a[0])); + Assert.False(Unsafe.IsAddressGreaterThanOrEqualTo(ref a[0], ref a[1])); + Assert.True(Unsafe.IsAddressGreaterThanOrEqualTo(ref a[1], ref a[0])); + Assert.True(Unsafe.IsAddressGreaterThanOrEqualTo(ref a[1], ref a[1])); + + // The following tests ensure that we're using unsigned comparison logic + + Assert.False(Unsafe.IsAddressGreaterThanOrEqualTo(ref Unsafe.AsRef((void*)(1)), ref Unsafe.AsRef((void*)(-1)))); + Assert.True(Unsafe.IsAddressGreaterThanOrEqualTo(ref Unsafe.AsRef((void*)(-1)), ref Unsafe.AsRef((void*)(1)))); + Assert.True(Unsafe.IsAddressGreaterThanOrEqualTo(ref Unsafe.AsRef((void*)(int.MinValue)), ref Unsafe.AsRef((void*)(int.MaxValue)))); + Assert.False(Unsafe.IsAddressGreaterThanOrEqualTo(ref Unsafe.AsRef((void*)(int.MaxValue)), ref Unsafe.AsRef((void*)(int.MinValue)))); + Assert.True(Unsafe.IsAddressGreaterThanOrEqualTo(ref Unsafe.AsRef(null), ref Unsafe.AsRef(null))); + } + [Fact] public static unsafe void RefIsAddressLessThan() { @@ -824,6 +843,25 @@ public static unsafe void RefIsAddressLessThan() Assert.False(Unsafe.IsAddressLessThan(ref Unsafe.AsRef(null), ref Unsafe.AsRef(null))); } + [Fact] + public static unsafe void RefIsAddressLessThanOrEqualTo() + { + int[] a = new int[2]; + + Assert.True(Unsafe.IsAddressLessThanOrEqualTo(ref a[0], ref a[0])); + Assert.True(Unsafe.IsAddressLessThanOrEqualTo(ref a[0], ref a[1])); + Assert.False(Unsafe.IsAddressLessThanOrEqualTo(ref a[1], ref a[0])); + Assert.True(Unsafe.IsAddressLessThanOrEqualTo(ref a[1], ref a[1])); + + // The following tests ensure that we're using unsigned comparison logic + + Assert.True(Unsafe.IsAddressLessThanOrEqualTo(ref Unsafe.AsRef((void*)(1)), ref Unsafe.AsRef((void*)(-1)))); + Assert.False(Unsafe.IsAddressLessThanOrEqualTo(ref Unsafe.AsRef((void*)(-1)), ref Unsafe.AsRef((void*)(1)))); + Assert.False(Unsafe.IsAddressLessThanOrEqualTo(ref Unsafe.AsRef((void*)(int.MinValue)), ref Unsafe.AsRef((void*)(int.MaxValue)))); + Assert.True(Unsafe.IsAddressLessThanOrEqualTo(ref Unsafe.AsRef((void*)(int.MaxValue)), ref Unsafe.AsRef((void*)(int.MinValue)))); + Assert.True(Unsafe.IsAddressLessThanOrEqualTo(ref Unsafe.AsRef(null), ref Unsafe.AsRef(null))); + } + [Fact] public static unsafe void ReadUnaligned_ByRef_Int32() { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs index 643971e0163962..196eaa6a633534 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.FromHexString.cs @@ -35,21 +35,52 @@ public static void CompleteValueRange() private static void TestSequence(byte[] expected, string actual) { - byte[] fromResult = Convert.FromHexString(actual); - Assert.Equal(expected, fromResult); - - Span tryResult = new byte[actual.Length / 2]; - Assert.Equal(OperationStatus.Done, Convert.FromHexString(actual, tryResult, out int consumed, out int written)); - Assert.Equal(fromResult.Length, written); - Assert.Equal(actual.Length, consumed); - AssertExtensions.SequenceEqual(expected.AsSpan(), tryResult); + TestSequenceString(expected, actual); + TestSequenceUtf16(expected, actual); + TestSequenceUtf8(expected, Encoding.UTF8.GetBytes(actual)); + + static void TestSequenceString(byte[] expected, string actual) + { + byte[] fromResult = Convert.FromHexString(actual); + Assert.Equal(expected, fromResult); + + Span tryResult = new byte[actual.Length / 2]; + Assert.Equal(OperationStatus.Done, Convert.FromHexString(actual, tryResult, out int consumed, out int written)); + Assert.Equal(fromResult.Length, written); + Assert.Equal(actual.Length, consumed); + AssertExtensions.SequenceEqual(expected.AsSpan(), tryResult); + } + + static void TestSequenceUtf16(byte[] expected, ReadOnlySpan actual) + { + byte[] fromResult = Convert.FromHexString(actual); + Assert.Equal(expected, fromResult); + + Span tryResult = new byte[actual.Length / 2]; + Assert.Equal(OperationStatus.Done, Convert.FromHexString(actual, tryResult, out int consumed, out int written)); + Assert.Equal(fromResult.Length, written); + Assert.Equal(actual.Length, consumed); + AssertExtensions.SequenceEqual(expected.AsSpan(), tryResult); + } + + static void TestSequenceUtf8(byte[] expected, ReadOnlySpan actual) + { + byte[] fromResult = Convert.FromHexString(actual); + Assert.Equal(expected, fromResult); + + Span tryResult = new byte[actual.Length / 2]; + Assert.Equal(OperationStatus.Done, Convert.FromHexString(actual, tryResult, out int consumed, out int written)); + Assert.Equal(fromResult.Length, written); + Assert.Equal(actual.Length, consumed); + AssertExtensions.SequenceEqual(expected.AsSpan(), tryResult); + } } [Fact] public static void InvalidInputString_Null() { - AssertExtensions.Throws("s", () => Convert.FromHexString(null)); - AssertExtensions.Throws("source", () => Convert.FromHexString(null, default, out _, out _)); + AssertExtensions.Throws("s", () => Convert.FromHexString((string)null)); + AssertExtensions.Throws("source", () => Convert.FromHexString((string)null, default, out _, out _)); } [Theory] @@ -67,30 +98,55 @@ public static void InvalidInputString_FormatException_Or_FalseResult(string inva Span buffer = stackalloc byte[invalidInput.Length / 2]; Assert.Equal(OperationStatus.InvalidData, Convert.FromHexString(invalidInput.AsSpan(), buffer, out _, out _)); + Assert.Equal(OperationStatus.InvalidData, Convert.FromHexString(Encoding.UTF8.GetBytes(invalidInput), buffer, out _, out _)); } [Fact] public static void ZeroLength() { Assert.Same(Array.Empty(), Convert.FromHexString(string.Empty)); + Assert.Same(Array.Empty(), Convert.FromHexString(ReadOnlySpan.Empty)); + Assert.Same(Array.Empty(), Convert.FromHexString(ReadOnlySpan.Empty)); OperationStatus convertResult = Convert.FromHexString(string.Empty, Span.Empty, out int consumed, out int written); Assert.Equal(OperationStatus.Done, convertResult); Assert.Equal(0, written); Assert.Equal(0, consumed); + + convertResult = Convert.FromHexString(ReadOnlySpan.Empty, Span.Empty, out consumed, out written); + + Assert.Equal(OperationStatus.Done, convertResult); + Assert.Equal(0, written); + Assert.Equal(0, consumed); + + convertResult = Convert.FromHexString(ReadOnlySpan.Empty, Span.Empty, out consumed, out written); + + Assert.Equal(OperationStatus.Done, convertResult); + Assert.Equal(0, written); + Assert.Equal(0, consumed); } [Fact] public static void ToHexFromHexRoundtrip() { const int loopCount = 50; + Span buffer = stackalloc char[loopCount * 2]; Span bufferLower = stackalloc char[loopCount * 2]; + + Span bufferUtf8 = stackalloc byte[loopCount * 2]; + Span bufferUtf8Lower = stackalloc byte[loopCount * 2]; + for (int i = 1; i < loopCount; i++) { byte[] data = Security.Cryptography.RandomNumberGenerator.GetBytes(i); + string hex = Convert.ToHexString(data); + string hexLower = hex.ToLowerInvariant(); + + byte[] hexUtf8 = Encoding.UTF8.GetBytes(hex); + byte[] hexLowerUtf8 = Encoding.UTF8.GetBytes(hexLower); Span currentBuffer = buffer.Slice(0, i * 2); bool tryHex = Convert.TryToHexString(data, currentBuffer, out int written); @@ -101,8 +157,20 @@ public static void ToHexFromHexRoundtrip() Span currentBufferLower = bufferLower.Slice(0, i * 2); tryHex = Convert.TryToHexStringLower(data, currentBufferLower, out written); Assert.True(tryHex); - AssertExtensions.SequenceEqual(hex.ToLowerInvariant().AsSpan(), currentBufferLower); - Assert.Equal(hex.Length, written); + AssertExtensions.SequenceEqual(hexLower.AsSpan(), currentBufferLower); + Assert.Equal(hexLower.Length, written); + + Span currentBufferUtf8 = bufferUtf8.Slice(0, i * 2); + tryHex = Convert.TryToHexString(data, currentBufferUtf8, out written); + Assert.True(tryHex); + AssertExtensions.SequenceEqual(hexUtf8.AsSpan(), currentBufferUtf8); + Assert.Equal(hexUtf8.Length, written); + + Span currentBufferLowerUtf8 = bufferUtf8Lower.Slice(0, i * 2); + tryHex = Convert.TryToHexStringLower(data, currentBufferLowerUtf8, out written); + Assert.True(tryHex); + AssertExtensions.SequenceEqual(hexLowerUtf8.AsSpan(), currentBufferLowerUtf8); + Assert.Equal(hexLowerUtf8.Length, written); TestSequence(data, hex); TestSequence(data, hex.ToLowerInvariant()); @@ -134,6 +202,18 @@ public static void TooShortDestination() Assert.Equal(OperationStatus.DestinationTooSmall, result); Assert.Equal(destinationSize * 2, charsConsumed); Assert.Equal(destinationSize, bytesWritten); + + result = Convert.FromHexString(hex.AsSpan(), destination, out charsConsumed, out bytesWritten); + + Assert.Equal(OperationStatus.DestinationTooSmall, result); + Assert.Equal(destinationSize * 2, charsConsumed); + Assert.Equal(destinationSize, bytesWritten); + + result = Convert.FromHexString(Encoding.UTF8.GetBytes(hex), destination, out int bytesConsumed, out bytesWritten); + + Assert.Equal(OperationStatus.DestinationTooSmall, result); + Assert.Equal(destinationSize * 2, bytesConsumed); + Assert.Equal(destinationSize, bytesWritten); } [Fact] @@ -141,11 +221,23 @@ public static void TooLongDestination() { string hex = Convert.ToHexString([255, 255, 255]); byte[] buffer = new byte[100]; - var status = Convert.FromHexString(hex, buffer, out int charsConsumed, out int bytesWritten); + OperationStatus status = Convert.FromHexString(hex, buffer, out int charsConsumed, out int bytesWritten); + + Assert.Equal(OperationStatus.Done, status); + Assert.Equal(hex.Length, charsConsumed); + Assert.Equal(hex.Length / 2, bytesWritten); + + status = Convert.FromHexString(hex.AsSpan(), buffer, out charsConsumed, out bytesWritten); Assert.Equal(OperationStatus.Done, status); Assert.Equal(hex.Length, charsConsumed); Assert.Equal(hex.Length / 2, bytesWritten); + + status = Convert.FromHexString(Encoding.UTF8.GetBytes(hex), buffer, out int bytesConsumed, out bytesWritten); + + Assert.Equal(OperationStatus.Done, status); + Assert.Equal(hex.Length, bytesConsumed); + Assert.Equal(hex.Length / 2, bytesWritten); } [Fact] @@ -153,23 +245,47 @@ public static void ExactDestination() { string hex = "ffffff"; byte[] buffer = new byte[3]; - var status = Convert.FromHexString(hex, buffer, out int charsConsumed, out int bytesWritten); + OperationStatus status = Convert.FromHexString(hex, buffer, out int charsConsumed, out int bytesWritten); + + Assert.Equal(OperationStatus.Done, status); + Assert.Equal(hex.Length, charsConsumed); + Assert.Equal(hex.Length / 2, bytesWritten); + + status = Convert.FromHexString(hex.AsSpan(), buffer, out charsConsumed, out bytesWritten); Assert.Equal(OperationStatus.Done, status); Assert.Equal(hex.Length, charsConsumed); Assert.Equal(hex.Length / 2, bytesWritten); + + status = Convert.FromHexString(Encoding.UTF8.GetBytes(hex), buffer, out int bytesConsumed, out bytesWritten); + + Assert.Equal(OperationStatus.Done, status); + Assert.Equal(hex.Length, bytesConsumed); + Assert.Equal(hex.Length / 2, bytesWritten); } [Fact] public static void ExactDestination_TrailingCharacter() { - string hex = "fffff"; + string hex = "fffff"; byte[] buffer = new byte[2]; - var status = Convert.FromHexString(hex, buffer, out int charsConsumed, out int bytesWritten); + OperationStatus status = Convert.FromHexString(hex, buffer, out int charsConsumed, out int bytesWritten); + + Assert.Equal(OperationStatus.NeedMoreData, status); + Assert.Equal(hex.Length - 1, charsConsumed); + Assert.Equal(hex.Length / 2, bytesWritten); + + status = Convert.FromHexString(hex.AsSpan(), buffer, out charsConsumed, out bytesWritten); Assert.Equal(OperationStatus.NeedMoreData, status); Assert.Equal(hex.Length - 1, charsConsumed); Assert.Equal(hex.Length / 2, bytesWritten); + + status = Convert.FromHexString(Encoding.UTF8.GetBytes(hex), buffer, out int bytesConsumed, out bytesWritten); + + Assert.Equal(OperationStatus.NeedMoreData, status); + Assert.Equal(hex.Length - 1, bytesConsumed); + Assert.Equal(hex.Length / 2, bytesWritten); } [Fact] diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.ToHexString.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.ToHexString.cs index 1e65504b55c929..cc18466c0e161f 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.ToHexString.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Convert.ToHexString.cs @@ -19,6 +19,11 @@ public static void KnownByteSequence() Assert.True(Convert.TryToHexString(inputBytes, output, out int charsWritten)); Assert.Equal(12, charsWritten); Assert.Equal("000102FDFEFF", output.ToString()); + + Span outputUtf8 = stackalloc byte[12]; + Assert.True(Convert.TryToHexString(inputBytes, outputUtf8, out int bytesWritten)); + Assert.Equal(12, bytesWritten); + Assert.Equal("000102FDFEFF", Encoding.UTF8.GetString(outputUtf8)); } [Fact] @@ -31,6 +36,11 @@ public static void KnownByteSequenceLower() Assert.True(Convert.TryToHexStringLower(inputBytes, output, out int charsWritten)); Assert.Equal(12, charsWritten); Assert.Equal("000102fdfeff", output.ToString()); + + Span outputUtf8 = stackalloc byte[12]; + Assert.True(Convert.TryToHexStringLower(inputBytes, outputUtf8, out int bytesWritten)); + Assert.Equal(12, bytesWritten); + Assert.Equal("000102fdfeff", Encoding.UTF8.GetString(outputUtf8)); } [Fact] @@ -51,6 +61,11 @@ public static void CompleteValueRange() Assert.True(Convert.TryToHexString(values, output, out int charsWritten)); Assert.Equal(512, charsWritten); Assert.Equal(excepted, output.ToString()); + + Span outputUtf8 = stackalloc byte[512]; + Assert.True(Convert.TryToHexString(values, outputUtf8, out int bytesWritten)); + Assert.Equal(512, bytesWritten); + Assert.Equal(excepted, Encoding.UTF8.GetString(outputUtf8)); } [Fact] @@ -71,6 +86,11 @@ public static void CompleteValueRangeLower() Assert.True(Convert.TryToHexStringLower(values, output, out int charsWritten)); Assert.Equal(512, charsWritten); Assert.Equal(excepted, output.ToString()); + + Span outputUtf8 = stackalloc byte[512]; + Assert.True(Convert.TryToHexStringLower(values, outputUtf8, out int bytesWritten)); + Assert.Equal(512, bytesWritten); + Assert.Equal(excepted, Encoding.UTF8.GetString(outputUtf8)); } [Fact] @@ -80,12 +100,17 @@ public static void ZeroLength() Assert.Same(string.Empty, Convert.ToHexString(inputBytes, 0, 0)); Assert.Same(string.Empty, Convert.ToHexStringLower(inputBytes, 0, 0)); - int charsWritten; Span output = stackalloc char[12]; - Assert.True(Convert.TryToHexString(default, output, out charsWritten)); + Assert.True(Convert.TryToHexString(default, output, out int charsWritten)); Assert.Equal(0, charsWritten); Assert.True(Convert.TryToHexStringLower(default, output, out charsWritten)); Assert.Equal(0, charsWritten); + + Span outputUtf8 = stackalloc byte[12]; + Assert.True(Convert.TryToHexString(default, outputUtf8, out int bytesWritten)); + Assert.Equal(0, bytesWritten); + Assert.True(Convert.TryToHexStringLower(default, outputUtf8, out bytesWritten)); + Assert.Equal(0, bytesWritten); } [Fact] @@ -101,16 +126,26 @@ public static void InvalidInputBuffer() public static void InvalidOutputBuffer() { byte[] inputBytes = new byte[] { 0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF }; - int charsWritten; + Span output = stackalloc char[11]; - Assert.False(Convert.TryToHexString(inputBytes, default, out charsWritten)); + Assert.False(Convert.TryToHexString(inputBytes, Span.Empty, out int charsWritten)); Assert.Equal(0, charsWritten); Assert.False(Convert.TryToHexString(inputBytes, output, out charsWritten)); Assert.Equal(0, charsWritten); - Assert.False(Convert.TryToHexStringLower(inputBytes, default, out charsWritten)); + Assert.False(Convert.TryToHexStringLower(inputBytes, Span.Empty, out charsWritten)); Assert.Equal(0, charsWritten); Assert.False(Convert.TryToHexStringLower(inputBytes, output, out charsWritten)); Assert.Equal(0, charsWritten); + + Span outputUtf8 = stackalloc byte[11]; + Assert.False(Convert.TryToHexString(inputBytes, Span.Empty, out int bytesWritten)); + Assert.Equal(0, bytesWritten); + Assert.False(Convert.TryToHexString(inputBytes, outputUtf8, out bytesWritten)); + Assert.Equal(0, bytesWritten); + Assert.False(Convert.TryToHexStringLower(inputBytes, Span.Empty, out bytesWritten)); + Assert.Equal(0, bytesWritten); + Assert.False(Convert.TryToHexStringLower(inputBytes, outputUtf8, out bytesWritten)); + Assert.Equal(0, bytesWritten); } [Fact] @@ -138,15 +173,20 @@ public static void InvalidLength() [Fact] public static unsafe void InputTooLarge() { - AssertExtensions.Throws("bytes", () => Convert.ToHexString(new ReadOnlySpan((void*)0, Int32.MaxValue))); - AssertExtensions.Throws("bytes", () => Convert.ToHexStringLower(new ReadOnlySpan((void*)0, Int32.MaxValue))); + AssertExtensions.Throws("bytes", () => Convert.ToHexString(new ReadOnlySpan((void*)0, int.MaxValue))); + AssertExtensions.Throws("bytes", () => Convert.ToHexStringLower(new ReadOnlySpan((void*)0, int.MaxValue))); - int charsWritten; - Span output = new Span((void*)0, Int32.MaxValue); - Assert.False(Convert.TryToHexString(new ReadOnlySpan((void*)0, Int32.MaxValue), output, out charsWritten)); + Span output = new Span((void*)0, int.MaxValue); + Assert.False(Convert.TryToHexString(new ReadOnlySpan((void*)0, int.MaxValue), output, out int charsWritten)); Assert.Equal(0, charsWritten); - Assert.False(Convert.TryToHexStringLower(new ReadOnlySpan((void*)0, Int32.MaxValue), output, out charsWritten)); + Assert.False(Convert.TryToHexStringLower(new ReadOnlySpan((void*)0, int.MaxValue), output, out charsWritten)); Assert.Equal(0, charsWritten); + + Span outputUtf8 = new Span((void*)0, int.MaxValue); + Assert.False(Convert.TryToHexString(new ReadOnlySpan((void*)0, int.MaxValue), outputUtf8, out int bytesWritten)); + Assert.Equal(0, bytesWritten); + Assert.False(Convert.TryToHexStringLower(new ReadOnlySpan((void*)0, int.MaxValue), outputUtf8, out bytesWritten)); + Assert.Equal(0, bytesWritten); } public static IEnumerable ToHexStringTestData() @@ -197,6 +237,11 @@ public static unsafe void TryToHexString(byte[] input, string expected) Assert.True(Convert.TryToHexString(input, output, out int charsWritten)); Assert.Equal(expected.Length, charsWritten); Assert.Equal(expected, output.ToString()); + + Span outputUtf8 = new byte[expected.Length]; + Assert.True(Convert.TryToHexString(input, outputUtf8, out int bytesWritten)); + Assert.Equal(expected.Length, bytesWritten); + Assert.Equal(expected, Encoding.UTF8.GetString(outputUtf8)); } @@ -216,6 +261,11 @@ public static unsafe void TryToHexStringLower(byte[] input, string expected) Assert.True(Convert.TryToHexStringLower(input, output, out int charsWritten)); Assert.Equal(expected.Length, charsWritten); Assert.Equal(expected.ToLower(), output.ToString()); + + Span outputUtf8 = new byte[expected.Length]; + Assert.True(Convert.TryToHexStringLower(input, outputUtf8, out int bytesWritten)); + Assert.Equal(expected.Length, bytesWritten); + Assert.Equal(expected.ToLower(), Encoding.UTF8.GetString(outputUtf8)); } } } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Environment.ProcessorCount.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Environment.ProcessorCount.cs index 1628d8b826f602..b440df84835954 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Environment.ProcessorCount.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Environment.ProcessorCount.cs @@ -72,7 +72,7 @@ public void ProcessorCount_Windows_MatchesGetSystemInfo() [InlineData(2000, 0, " 17 ")] [InlineData(0, 0, "3")] public static unsafe void ProcessorCount_Windows_RespectsJobCpuRateAndConfigurationSetting( - ushort maxRate, ushort minRate, string procCountConfig) + ushort maxRate, ushort minRate, string? procCountConfig) { IntPtr hJob = IntPtr.Zero; PROCESS_INFORMATION processInfo = default; diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/IO/PathTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/IO/PathTests.cs index b248728a79da0a..a701eea79f47ea 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/IO/PathTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/IO/PathTests.cs @@ -24,7 +24,7 @@ public class PathTests : PathTestsBase InlineData("dir/file.t", "exe", "dir/file.exe"), InlineData("dir/file.exe", "t", "dir/file.t"), InlineData("dir/file", "exe", "dir/file.exe")] - public void ChangeExtension(string path, string newExtension, string expected) + public void ChangeExtension(string? path, string? newExtension, string? expected) { if (expected != null) expected = expected.Replace('/', Path.DirectorySeparatorChar); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/OperatingSystemTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/OperatingSystemTests.cs index a5a8636008a3cf..89715afadead85 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/OperatingSystemTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/OperatingSystemTests.cs @@ -198,7 +198,6 @@ private static void TestIsOSPlatform(string currentOSName, Func currentOSC { "IsMacCatalyst", OperatingSystem.IsMacCatalyst() }, { "IsMacOS", OperatingSystem.IsMacOS() }, { "IsTvOS", OperatingSystem.IsTvOS() }, - { "IsWatchOS", OperatingSystem.IsWatchOS() }, { "IsWindows", OperatingSystem.IsWindows() }, { "IsWasi", OperatingSystem.IsWasi() }, }; diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ActivatorTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ActivatorTests.cs index f706210d4fa9bb..f281cf8e905ae2 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ActivatorTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ActivatorTests.cs @@ -8,6 +8,7 @@ using System.IO; using System.Reflection; using System.Reflection.Emit; +using System.Runtime.InteropServices; using System.Runtime.Remoting; using Microsoft.DotNet.RemoteExecutor; using Xunit; @@ -94,6 +95,28 @@ public void CreateInstance_NonPublicTypeWithPrivateDefaultConstructor_Success() Assert.Equal(-1, c2.Property); } + // Add attribute to avoid unused field warning + [StructLayout(LayoutKind.Sequential)] + ref struct RSNoCtor + { + public int Value; + } + + ref struct RSCtor + { + public int Value; + public RSCtor() => Value = 10; + } + + [Fact] + public void CreateInstance_ByRefTypeAsGenericParameter_Success() + { + Assert.Equal(0, Activator.CreateInstance>().Length); + Assert.Equal(0, Activator.CreateInstance>().Length); + Assert.Equal(0, Activator.CreateInstance().Value); + Assert.Equal(10, Activator.CreateInstance().Value); + } + [Fact] public void CreateInstance_PublicOnlyTypeWithPrivateDefaultConstructor_ThrowsMissingMethodException() { @@ -318,17 +341,15 @@ public void CreateInstance_AbstractClass_ThrowsMissingMemberException(Type type) [Theory] [InlineData(typeof(TypedReference))] [InlineData(typeof(RuntimeArgumentHandle))] + [InlineData(typeof(Span))] + [InlineData(typeof(ReadOnlySpan))] + [InlineData(typeof(RSNoCtor))] + [InlineData(typeof(RSCtor))] public void CreateInstance_BoxedByRefType_ThrowsNotSupportedException(Type type) { Assert.Throws(() => Activator.CreateInstance(type)); } - [Fact] - public void CreateInstance_Span_ThrowsNotSupportedException() - { - CreateInstance_BoxedByRefType_ThrowsNotSupportedException(typeof(Span)); - } - [Fact] public void CreateInstance_InterfaceType_ThrowsMissingMemberException() { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/AppContext/AppContextTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/AppContext/AppContextTests.cs index 6cf9ce9ac7f995..22d0118e11b7c1 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/AppContext/AppContextTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/AppContext/AppContextTests.cs @@ -12,7 +12,7 @@ public partial class AppContextTests [InlineData("AppContext_Case1", 123)] [InlineData("AppContext_Case2", "")] [InlineData("AppContext_Case3", null)] - public void AppContext_GetSetDataTest(string dataKey, object value) + public void AppContext_GetSetDataTest(string dataKey, object? value) { // Set data AppContext.SetData(dataKey, value); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArgumentNullExceptionTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArgumentNullExceptionTests.cs index 9705f44c55c14a..81551e69e4d125 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArgumentNullExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArgumentNullExceptionTests.cs @@ -66,7 +66,7 @@ public static unsafe void ThrowIfNull_NonNull_DoesntThrow() [InlineData(null)] [InlineData("")] [InlineData("name")] - public static unsafe void ThrowIfNull_Null_ThrowsArgumentNullException(string paramName) + public static unsafe void ThrowIfNull_Null_ThrowsArgumentNullException(string? paramName) { AssertExtensions.Throws(paramName, () => ArgumentNullException.ThrowIfNull((object)null, paramName)); AssertExtensions.Throws(paramName, () => ArgumentNullException.ThrowIfNull((void*)null, paramName)); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArrayTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArrayTests.cs index 8290a03428897d..96856a698c8888 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArrayTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ArrayTests.cs @@ -369,7 +369,7 @@ public static IEnumerable BinarySearch_SZArray_TestData() [InlineData(new char[] { '\0' }, 0, 1, null, null, -1)] [InlineData(new float[] { 0 }, 0, 1, null, null, -1)] [InlineData(new double[] { 0 }, 0, 1, null, null, -1)] - public static void BinarySearch_Array(Array array, int index, int length, object value, IComparer comparer, int expected) + public static void BinarySearch_Array(Array array, int index, int length, object? value, IComparer? comparer, int expected) { bool isDefaultComparer = comparer == null || comparer == Comparer.Default; if (index == array.GetLowerBound(0) && length == array.Length) @@ -3220,7 +3220,7 @@ public static void IStructuralEquatable_GetHashCode_NullComparer_ThrowsArgumentN [InlineData(new int[] { 1, 2, 3, 4, 5 }, 7, new int[] { 1, 2, 3, 4, 5, default(int), default(int) })] [InlineData(new int[] { 1, 2, 3, 4, 5 }, 3, new int[] { 1, 2, 3 })] [InlineData(null, 3, new int[] { default(int), default(int), default(int) })] - public static void Resize(int[] array, int newSize, int[] expected) + public static void Resize(int[]? array, int newSize, int[] expected) { int[] testArray = array; Array.Resize(ref testArray, newSize); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/BooleanTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/BooleanTests.cs index 835f038afd74de..69fa8752df5821 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/BooleanTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/BooleanTests.cs @@ -124,7 +124,7 @@ public void ToString_Invoke_ReturnsExpected(bool value, string expected) [InlineData(false, false, 0)] [InlineData(false, true, -1)] [InlineData(false, null, 1)] - public void CompareTo_Other_ReturnsExpected(bool b, object obj, int expected) + public void CompareTo_Other_ReturnsExpected(bool b, object? obj, int expected) { if (obj is bool boolValue) { @@ -155,7 +155,7 @@ public void CompareTo_ObjectNotBool_ThrowsArgumentException(bool b, object obj) [InlineData(false, "0", false)] [InlineData(false, "False", false)] [InlineData(false, null, false)] - public void Equals_Other_ReturnsExpected(bool b1, object obj, bool expected) + public void Equals_Other_ReturnsExpected(bool b1, object? obj, bool expected) { if (obj is bool boolValue) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ByteTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ByteTests.cs index 0325507355adae..d95fd2c3d8666f 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ByteTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ByteTests.cs @@ -43,7 +43,7 @@ public static void MinValue() [InlineData((byte)234, (byte)235, -1)] [InlineData((byte)234, byte.MaxValue, -1)] [InlineData((byte)234, null, 1)] - public void CompareTo_Other_ReturnsExpected(byte i, object value, int expected) + public void CompareTo_Other_ReturnsExpected(byte i, object? value, int expected) { if (value is byte byteValue) { @@ -68,7 +68,7 @@ public void CompareTo_ObjectNotByte_ThrowsArgumentException(object value) [InlineData((byte)78, null, false)] [InlineData((byte)78, "78", false)] [InlineData((byte)78, 78, false)] - public static void EqualsTest(byte b, object obj, bool expected) + public static void EqualsTest(byte b, object? obj, bool expected) { if (obj is byte b2) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/CharTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/CharTests.cs index d43482bfce4bae..65112375551d3f 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/CharTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/CharTests.cs @@ -17,7 +17,7 @@ public class CharTests [InlineData('h', 'a', 1)] [InlineData('h', 'z', -1)] [InlineData('h', null, 1)] - public void CompareTo_Other_ReturnsExpected(char c, object value, int expected) + public void CompareTo_Other_ReturnsExpected(char c, object? value, int expected) { if (value is char charValue) { @@ -154,7 +154,7 @@ public static void ConvertToUtf32_Char_Char_Invalid() [InlineData('a', (int)'a', false)] [InlineData('a', "a", false)] [InlineData('a', null, false)] - public static void EqualsTest(char c, object obj, bool expected) + public static void EqualsTest(char c, object? obj, bool expected) { if (obj is char) { @@ -1019,7 +1019,7 @@ public static void Parse(string s, char expected) [InlineData("\\u0135", typeof(FormatException))] [InlineData("\u01356", typeof(FormatException))] [InlineData("\ud801\udc01", typeof(FormatException))] // Surrogate pair - public static void Parse_Invalid(string s, Type exceptionType) + public static void Parse_Invalid(string? s, Type exceptionType) { char c; Assert.False(char.TryParse(s, out c)); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DateTimeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DateTimeTests.cs index 2d31b68544abba..8eca865c38f95f 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DateTimeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DateTimeTests.cs @@ -1339,7 +1339,7 @@ public static void Parse_InvalidArguments_Throws() [Theory] [InlineData(null)] [InlineData("")] - public static void TryParse_NullOrEmptyString_ReturnsFalse(string input) + public static void TryParse_NullOrEmptyString_ReturnsFalse(string? input) { Assert.False(DateTime.TryParse(input, out DateTime result)); Assert.False(DateTime.TryParse(input, new MyFormatter(), DateTimeStyles.None, out result)); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/ConstantExpectedAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/ConstantExpectedAttributeTests.cs index 390955277f71fb..f74426ce594281 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/ConstantExpectedAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/ConstantExpectedAttributeTests.cs @@ -22,7 +22,7 @@ public void TestConstructor() [InlineData(10000)] [InlineData(0.5f)] [InlineData(null)] - public void TestSetMin(object min) + public void TestSetMin(object? min) { var attr = new ConstantExpectedAttribute { @@ -38,7 +38,7 @@ public void TestSetMin(object min) [InlineData(10000)] [InlineData(0.5f)] [InlineData(null)] - public void TestSetMax(object max) + public void TestSetMax(object? max) { var attr = new ConstantExpectedAttribute { @@ -55,7 +55,7 @@ public void TestSetMax(object max) [InlineData(null, null)] [InlineData(10, 0)] [InlineData(10, "https://dot.net")] - public void TestSetMinAndMax(object min, object max) + public void TestSetMinAndMax(object? min, object? max) { var attr = new ConstantExpectedAttribute { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/DynamicDependencyAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/DynamicDependencyAttributeTests.cs index c81a220659a522..d82b7c9798cc51 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/DynamicDependencyAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/DynamicDependencyAttributeTests.cs @@ -13,7 +13,7 @@ public class DynamicDependencyAttributeTests [InlineData("Foo()")] [InlineData(null)] [InlineData("")] - public void TestConstructorSignature(string memberSignature) + public void TestConstructorSignature(string? memberSignature) { var dda = new DynamicDependencyAttribute(memberSignature); @@ -29,7 +29,7 @@ public void TestConstructorSignature(string memberSignature) [InlineData("Foo()", typeof(string))] [InlineData(null, null)] [InlineData("", typeof(void))] - public void TestConstructorSignatureType(string memberSignature, Type type) + public void TestConstructorSignatureType(string? memberSignature, Type? type) { var dda = new DynamicDependencyAttribute(memberSignature, type); @@ -45,7 +45,7 @@ public void TestConstructorSignatureType(string memberSignature, Type type) [InlineData("Foo()", "System.String", "System.Runtime")] [InlineData(null, null, null)] [InlineData("", "", "")] - public void TestConstructorSignatureTypeNameAssemblyName(string memberSignature, string typeName, string assemblyName) + public void TestConstructorSignatureTypeNameAssemblyName(string? memberSignature, string? typeName, string? assemblyName) { var dda = new DynamicDependencyAttribute(memberSignature, typeName, assemblyName); @@ -61,7 +61,7 @@ public void TestConstructorSignatureTypeNameAssemblyName(string memberSignature, [InlineData(DynamicallyAccessedMemberTypes.PublicMethods, typeof(string))] [InlineData(DynamicallyAccessedMemberTypes.None, null)] [InlineData(DynamicallyAccessedMemberTypes.All, typeof(void))] - public void TestConstructorMemberTypes(DynamicallyAccessedMemberTypes memberTypes, Type type) + public void TestConstructorMemberTypes(DynamicallyAccessedMemberTypes memberTypes, Type? type) { var dda = new DynamicDependencyAttribute(memberTypes, type); @@ -77,7 +77,7 @@ public void TestConstructorMemberTypes(DynamicallyAccessedMemberTypes memberType [InlineData(DynamicallyAccessedMemberTypes.PublicMethods, "System.String", "System.Runtime")] [InlineData(DynamicallyAccessedMemberTypes.None, null, null)] [InlineData(DynamicallyAccessedMemberTypes.All, "", "")] - public void TestConstructorMemberTypesTypeNameAssemblyName(DynamicallyAccessedMemberTypes memberTypes, string typeName, string assemblyName) + public void TestConstructorMemberTypesTypeNameAssemblyName(DynamicallyAccessedMemberTypes memberTypes, string? typeName, string? assemblyName) { var dda = new DynamicDependencyAttribute(memberTypes, typeName, assemblyName); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/ExperimentalAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/ExperimentalAttributeTests.cs index 4088037a54ac33..66d0a3ed7ba817 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/ExperimentalAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/ExperimentalAttributeTests.cs @@ -26,7 +26,7 @@ public void TestConstructor(string expected) [InlineData(null)] [InlineData("")] [InlineData("https://contoso.com/obsoletion-warnings/{0}")] - public void TestSetUrlFormat(string urlFormat) + public void TestSetUrlFormat(string? urlFormat) { var attr = new ExperimentalAttribute("diagnosticId") { @@ -41,7 +41,7 @@ public void TestSetUrlFormat(string urlFormat) [InlineData(null)] [InlineData("")] [InlineData("This is an experimental feature")] - public void TestSetMessage(string message) + public void TestSetMessage(string? message) { var attribute = new ExperimentalAttribute("diagnosticId") { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/RequiresAssemblyFilesAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/RequiresAssemblyFilesAttributeTests.cs index 6dd40bf5b3de42..89fa0471568904 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/RequiresAssemblyFilesAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/RequiresAssemblyFilesAttributeTests.cs @@ -20,7 +20,7 @@ public void TestConstructor() [InlineData("Message")] [InlineData("")] [InlineData(null)] - public void TestSetMessage(string message) + public void TestSetMessage(string? message) { var attr = new RequiresAssemblyFilesAttribute(message); @@ -32,7 +32,7 @@ public void TestSetMessage(string message) [InlineData("https://dot.net")] [InlineData("")] [InlineData(null)] - public void TestSetUrl(string url) + public void TestSetUrl(string? url) { var attr = new RequiresAssemblyFilesAttribute() { @@ -53,7 +53,7 @@ public void TestSetUrl(string url) [InlineData(null, "https://dot.net")] [InlineData(null, "")] [InlineData(null, null)] - public void TestSetMessageAndUrl(string message, string url) + public void TestSetMessageAndUrl(string? message, string? url) { var attr = new RequiresAssemblyFilesAttribute(message) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/RequiresDynamicCodeAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/RequiresDynamicCodeAttributeTests.cs index a9cbc6f6942ec0..e63f6c0f8f4ca8 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/RequiresDynamicCodeAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/RequiresDynamicCodeAttributeTests.cs @@ -20,7 +20,7 @@ public void TestConstructor() [InlineData("https://dot.net")] [InlineData("")] [InlineData(null)] - public void TestSetUrl(string url) + public void TestSetUrl(string? url) { var attr = new RequiresDynamicCodeAttribute("User Message") { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttributeTests.cs index 62424692f1dc2c..237f0acf5bafe8 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttributeTests.cs @@ -20,7 +20,7 @@ public void TestConstructor() [InlineData("https://dot.net")] [InlineData("")] [InlineData(null)] - public void TestSetUrl(string url) + public void TestSetUrl(string? url) { var attr = new RequiresUnreferencedCodeAttribute("User Message") { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttributeTests.cs index a63d9c34ec2502..d4d31192e374bc 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttributeTests.cs @@ -12,7 +12,7 @@ public class UnconditionalSuppressMessageAttributeTests [InlineData("", "", "", "", "", "")] [InlineData(null, null, null, null, null, null)] [InlineData("", null, "Justification", null, "Scope", "")] - public void TestConstructor(string category, string id, string justification, string messageId, string scope, string target) + public void TestConstructor(string? category, string? id, string? justification, string? messageId, string? scope, string? target) { var usma = new UnconditionalSuppressMessageAttribute(category, id) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DoubleTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DoubleTests.cs index a236858cff20d1..ac1bf4abf4e863 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DoubleTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DoubleTests.cs @@ -59,7 +59,7 @@ public static void CompareTo_ObjectNotDouble_ThrowsArgumentException(object valu [InlineData(double.NegativeInfinity, double.PositiveInfinity, -1)] [InlineData(double.PositiveInfinity, double.PositiveInfinity, 0)] [InlineData(double.PositiveInfinity, double.NegativeInfinity, 1)] - public static void CompareTo_Other_ReturnsExpected(double d1, object value, int expected) + public static void CompareTo_Other_ReturnsExpected(double d1, object? value, int expected) { if (value is double d2) { @@ -131,7 +131,7 @@ public static void Epsilon() [InlineData(double.NaN, -double.NaN, true)] [InlineData(789.0, 789.0f, false)] [InlineData(789.0, "789", false)] - public static void EqualsTest(double d1, object value, bool expected) + public static void EqualsTest(double d1, object? value, bool expected) { if (value is double d2) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/EnumTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/EnumTests.cs index b3fddb6bac4c18..4c73475742a497 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/EnumTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/EnumTests.cs @@ -294,7 +294,7 @@ public static void Parse_NonExistentValue_IncludedInErrorMessage(string value) [InlineData((sbyte)2, "Two")] [InlineData(sbyte.MaxValue, "Max")] [InlineData((sbyte)3, null)] - public void GetName_InvokeSByteEnum_ReturnsExpected(object value, string expected) + public void GetName_InvokeSByteEnum_ReturnsExpected(object value, string? expected) { TestGetName(typeof(SByteEnum), value, expected); if (!(value is SByteEnum enumValue)) @@ -314,7 +314,7 @@ public void GetName_InvokeSByteEnum_ReturnsExpected(object value, string expecte [InlineData((byte)2, "Two")] [InlineData(byte.MaxValue, "Max")] [InlineData((byte)3, null)] - public void GetName_InvokeByteEnum_ReturnsExpected(object value, string expected) + public void GetName_InvokeByteEnum_ReturnsExpected(object value, string? expected) { TestGetName(typeof(ByteEnum), value, expected); if (!(value is ByteEnum enumValue)) @@ -334,7 +334,7 @@ public void GetName_InvokeByteEnum_ReturnsExpected(object value, string expected [InlineData((short)2, "Two")] [InlineData(short.MaxValue, "Max")] [InlineData((short)3, null)] - public void GetName_InvokeInt16Enum_ReturnsExpected(object value, string expected) + public void GetName_InvokeInt16Enum_ReturnsExpected(object value, string? expected) { TestGetName(typeof(Int16Enum), value, expected); if (!(value is Int16Enum enumValue)) @@ -354,7 +354,7 @@ public void GetName_InvokeInt16Enum_ReturnsExpected(object value, string expecte [InlineData((ushort)2, "Two")] [InlineData(ushort.MaxValue, "Max")] [InlineData((ushort)3, null)] - public void GetName_InvokeUInt16Enum_ReturnsExpected(object value, string expected) + public void GetName_InvokeUInt16Enum_ReturnsExpected(object value, string? expected) { TestGetName(typeof(UInt16Enum), value, expected); if (!(value is UInt16Enum enumValue)) @@ -374,7 +374,7 @@ public void GetName_InvokeUInt16Enum_ReturnsExpected(object value, string expect [InlineData(2, "Two")] [InlineData(int.MaxValue, "Max")] [InlineData(3, null)] - public void GetName_InvokeInt32Enum_ReturnsExpected(object value, string expected) + public void GetName_InvokeInt32Enum_ReturnsExpected(object value, string? expected) { TestGetName(typeof(Int32Enum), value, expected); if (!(value is Int32Enum enumValue)) @@ -394,7 +394,7 @@ public void GetName_InvokeInt32Enum_ReturnsExpected(object value, string expecte [InlineData((uint)2, "Two")] [InlineData(uint.MaxValue, "Max")] [InlineData((uint)3, null)] - public void GetName_InvokeUInt32Enum_ReturnsExpected(object value, string expected) + public void GetName_InvokeUInt32Enum_ReturnsExpected(object value, string? expected) { TestGetName(typeof(UInt32Enum), value, expected); if (!(value is UInt32Enum enumValue)) @@ -414,7 +414,7 @@ public void GetName_InvokeUInt32Enum_ReturnsExpected(object value, string expect [InlineData((long)2, "Two")] [InlineData(long.MaxValue, "Max")] [InlineData((long)3, null)] - public void GetName_InvokeInt64Enum_ReturnsExpected(object value, string expected) + public void GetName_InvokeInt64Enum_ReturnsExpected(object value, string? expected) { TestGetName(typeof(Int64Enum), value, expected); if (!(value is Int64Enum enumValue)) @@ -434,7 +434,7 @@ public void GetName_InvokeInt64Enum_ReturnsExpected(object value, string expecte [InlineData(2UL, "Two")] [InlineData(ulong.MaxValue, "Max")] [InlineData(3UL, null)] - public void GetName_InvokeUInt64Enum_ReturnsExpected(object value, string expected) + public void GetName_InvokeUInt64Enum_ReturnsExpected(object value, string? expected) { TestGetName(typeof(UInt64Enum), value, expected); if (!(value is UInt64Enum enumValue)) @@ -524,7 +524,7 @@ public void GetName_InvalidValue_ThrowsArgumentException(object value) [InlineData(typeof(SByteEnum), unchecked((int)(0xffffff80u)), "Min")] [InlineData(typeof(SByteEnum), (char)1, "One")] [InlineData(typeof(SByteEnum), SimpleEnum.Red, "One")] // API doesn't care if you pass in a completely different enum - public static void GetName_NonIntegralTypes_ReturnsExpected(Type enumType, object value, string expected) + public static void GetName_NonIntegralTypes_ReturnsExpected(Type enumType, object value, string? expected) { // Despite what MSDN says, GetName() does not require passing in the exact integral type. // For the purposes of comparison: diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ExceptionTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ExceptionTests.cs index 885b5a1ce0433d..a95402e20d3708 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ExceptionTests.cs @@ -107,9 +107,8 @@ public static void Exception_TargetSite_Rethrow() Assert.Equal(nameof(ThrowException), ex.TargetSite.Name); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.HasAssemblyFiles))] [ActiveIssue("https://github.com/mono/mono/issues/15140", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951", TestPlatforms.Android)] public static void ThrowStatementDoesNotResetExceptionStackLineSameMethod() { (string, string, int) rethrownExceptionStackFrame = (null, null, 0); @@ -137,10 +136,9 @@ private static (string, string, int) ThrowAndRethrowSameMethod(out (string, stri } } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArm64Process))] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArm64Process), nameof(PlatformDetection.HasAssemblyFiles))] // [ActiveIssue(https://github.com/dotnet/runtime/issues/1871)] can't use ActiveIssue for archs [ActiveIssue("https://github.com/mono/mono/issues/15141", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951", TestPlatforms.Android)] public static void ThrowStatementDoesNotResetExceptionStackLineOtherMethod() { (string, string, int) rethrownExceptionStackFrame = (null, null, 0); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int128Tests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int128Tests.cs index 4bb3f0a73a5494..ab94d43f1355aa 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int128Tests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int128Tests.cs @@ -562,5 +562,29 @@ public static void Runtime75416() Int128 b = (Int128.MaxValue - 10) * -100; Assert.Equal(b, +1100); } + + public static IEnumerable BigMul_TestData() + { + yield return new object[] { (Int128)0, (Int128)0, "0000000000000000000000000000000000000000000000000000000000000000" }; + yield return new object[] { (Int128)0, (Int128)1, "0000000000000000000000000000000000000000000000000000000000000000" }; + yield return new object[] { (Int128)1, (Int128)0, "0000000000000000000000000000000000000000000000000000000000000000" }; + yield return new object[] { (Int128)2, (Int128)3, "0000000000000000000000000000000000000000000000000000000000000006" }; + yield return new object[] { (Int128)3, (Int128)(-2), "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA" }; + yield return new object[] { (Int128)(-1), (Int128)(-1), "0000000000000000000000000000000000000000000000000000000000000001" }; + yield return new object[] { (Int128)(-1), Int128.MinValue, "0000000000000000000000000000000080000000000000000000000000000000" }; + yield return new object[] { (Int128)1, Int128.MinValue, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80000000000000000000000000000000" }; + yield return new object[] { new Int128(0x7DD8FD06E61C42C7, 0x23B8308969A5D354), new Int128(0x23B8308969A5D354, 0x7DD8FD06E61C42C7), "118F366A0AEB79CDF61A2AD689A481BFBA9B9B874C9A440EB340AA067592EE4C" }; + yield return new object[] { new Int128(0x6DACB8FC835F41B5, 0xD26F1073812D6446), new Int128(0xD26F1073812D6446, 0x6DACB8FC835F41B5), "EC7A8BB31D6035AD30FC0550485D053B65FB0FB7A7D5A47F27742486E387AB7E" }; + yield return new object[] { new Int128(0xE990583BA9EAB3D8, 0x13CF93153370AB0B), new Int128(0x13CF93153370AB0B, 0xE990583BA9EAB3D8), "FE43855FCCDA31540755B833730F08FFD0B8FE2FF36A55181A45864AC9B70248" }; + yield return new object[] { new Int128(0xA85EB0478871B06C, 0xCC423B382BE5BB37), new Int128(0xCC423B382BE5BB37, 0xA85EB0478871B06C), "11B61855830A65CB4078E0668A2FEF9970B49ACA239DE4CFA363C1FE50E7CB34" }; + } + + [Theory] + [MemberData(nameof(BigMul_TestData))] + public static void BigMul(Int128 a, Int128 b, string result) + { + Int128 upper = Int128.BigMul(a, b, out Int128 lower); + Assert.Equal(result, $"{upper:X32}{lower:X32}"); + } } } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int16Tests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int16Tests.cs index 60414f96e1a8b6..4601ac9dad7965 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int16Tests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int16Tests.cs @@ -52,7 +52,7 @@ public static void MinValue() [InlineData((short)-234, (short)234, -1)] [InlineData((short)-234, (short)-432, 1)] [InlineData((short)234, null, 1)] - public void CompareTo_Other_ReturnsExpected(short i, object value, int expected) + public void CompareTo_Other_ReturnsExpected(short i, object? value, int expected) { if (value is short shortValue) { @@ -81,7 +81,7 @@ public void CompareTo_ObjectNotShort_ThrowsArgumentException(object value) [InlineData((short)789, null, false)] [InlineData((short)789, "789", false)] [InlineData((short)789, 789, false)] - public static void EqualsTest(short i1, object obj, bool expected) + public static void EqualsTest(short i1, object? obj, bool expected) { if (obj is short) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int32Tests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int32Tests.cs index c170548369cd2c..d1b9c154aefc97 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int32Tests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int32Tests.cs @@ -52,7 +52,7 @@ public static void MinValue() [InlineData(-234, 234, -1)] [InlineData(-234, -432, 1)] [InlineData(234, null, 1)] - public void CompareTo_Other_ReturnsExpected(int i, object value, int expected) + public void CompareTo_Other_ReturnsExpected(int i, object? value, int expected) { if (value is int intValue) { @@ -81,7 +81,7 @@ public void CompareTo_ObjectNotInt_ThrowsArgumentException(object value) [InlineData(789, null, false)] [InlineData(789, "789", false)] [InlineData(789, (long)789, false)] - public static void EqualsTest(int i1, object obj, bool expected) + public static void EqualsTest(int i1, object? obj, bool expected) { if (obj is int) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int64Tests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int64Tests.cs index 2e2af6716ef343..7e755afd985834 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int64Tests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int64Tests.cs @@ -53,7 +53,7 @@ public static void MinValue() [InlineData((long)-234, (long)234, -1)] [InlineData((long)-234, (long)-432, 1)] [InlineData((long)234, null, 1)] - public void CompareTo_Other_ReturnsExpected(long i, object value, int expected) + public void CompareTo_Other_ReturnsExpected(long i, object? value, int expected) { if (value is long longValue) { @@ -82,7 +82,7 @@ public void CompareTo_ObjectNotLong_ThrowsArgumentException(object value) [InlineData((long)789, null, false)] [InlineData((long)789, "789", false)] [InlineData((long)789, 789, false)] - public static void EqualsTest(long i1, object obj, bool expected) + public static void EqualsTest(long i1, object? obj, bool expected) { if (obj is long) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IntPtrTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IntPtrTests.cs index 9b2d96e9797fea..0016d974ab1737 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IntPtrTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IntPtrTests.cs @@ -13,6 +13,7 @@ namespace System.Tests { public static class IntPtrTests { + private static unsafe bool Is32Bit => sizeof(void*) == 4; private static unsafe bool Is64Bit => sizeof(void*) == 8; [Fact] @@ -111,7 +112,7 @@ public static IEnumerable Equals_TestData() [Theory] [MemberData(nameof(Equals_TestData))] - public static void EqualsTest(nint value, object obj, bool expected) + public static void EqualsTest(nint value, object? obj, bool expected) { if (obj is nint other) { @@ -245,7 +246,7 @@ public static void MinValue() [InlineData(-234, 234, -1)] [InlineData(-234, -432, 1)] [InlineData(234, null, 1)] - public static void CompareTo_Other_ReturnsExpected(int l, object value, int expected) + public static void CompareTo_Other_ReturnsExpected(int l, object? value, int expected) { nint i = l; if (value is int intValue) @@ -1074,5 +1075,43 @@ public static void ToString_C_EmptyPercentGroup_Success() [MemberData(nameof(ToString_TestData))] public static void TryFormat(nint i, string format, IFormatProvider provider, string expected) => NumberFormatTestHelper.TryFormatNumberTest(i, format, provider, expected); + + [ConditionalTheory(nameof(Is32Bit))] + [InlineData(0, 0, "0000000000000000")] + [InlineData(0, 1, "0000000000000000")] + [InlineData(1, 0, "0000000000000000")] + [InlineData(2, 3, "0000000000000006")] + [InlineData(3, -2, "FFFFFFFFFFFFFFFA")] + [InlineData(-1, -1, "0000000000000001")] + [InlineData(-1, int.MinValue, "0000000080000000")] + [InlineData(1, int.MinValue, "FFFFFFFF80000000")] + [InlineData(0x19E3BD39, 0x69A5D354, "0AAF2DC48A6D11B4")] + [InlineData(0x7CA0BE4B, -0x7ED29BBA, "C2425AAB1C785482")] + [InlineData(-0x56154C28, 0x3370AB0B, "EEB3DEFEC9B70248")] + [InlineData(-0x778E4F94, -0x541A44C9, "2746F6B050E7CB34")] + public static void BigMul32(int a, int b, string result) + { + nint upper = nint.BigMul(a, b, out nint lower); + Assert.Equal(result, $"{upper:X8}{lower:X8}"); + } + + [ConditionalTheory(nameof(Is64Bit))] + [InlineData(0L, 0L, "00000000000000000000000000000000")] + [InlineData(0L, 1L, "00000000000000000000000000000000")] + [InlineData(1L, 0L, "00000000000000000000000000000000")] + [InlineData(2L, 3L, "00000000000000000000000000000006")] + [InlineData(3L, -2L, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA")] + [InlineData(-1L, -1L, "00000000000000000000000000000001")] + [InlineData(-1L, long.MinValue, "00000000000000008000000000000000")] + [InlineData(1L, long.MinValue, "FFFFFFFFFFFFFFFF8000000000000000")] + [InlineData(0x7DD8FD06E61C42C7, 0x23B8308969A5D354, "118F366A0AEB79CDB340AA067592EE4C")] + [InlineData(0x6DACB8FC835F41B5, -0x2D90EF8C7ED29BBA, "EC7A8BB31D6035AD27742486E387AB7E")] + [InlineData(-0x166FA7C456154C28, 0x13CF93153370AB0B, "FE43855FCCDA31541A45864AC9B70248")] + [InlineData(-0x57A14FB8778E4F94, -0x33BDC4C7D41A44C9, "11B61855830A65CBA363C1FE50E7CB34")] + public static void BigMul64(long a, long b, string result) + { + nint upper = nint.BigMul((nint)a, (nint)b, out nint lower); + Assert.Equal(result, $"{upper:X16}{lower:X16}"); + } } } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/NullableTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/NullableTests.cs index 5e6f268915cca4..4f3efc786e4623 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/NullableTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/NullableTests.cs @@ -83,7 +83,7 @@ public static void ExplicitCast_T() [InlineData(typeof(int?), typeof(int))] [InlineData(typeof(int), null)] [InlineData(typeof(G), null)] - public static void GetUnderlyingType(Type nullableType, Type expected) + public static void GetUnderlyingType(Type nullableType, Type? expected) { Assert.Equal(expected, Nullable.GetUnderlyingType(nullableType)); } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ObsoleteAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ObsoleteAttributeTests.cs index 32cc0ccbabb763..4d74c084567aca 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ObsoleteAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ObsoleteAttributeTests.cs @@ -21,7 +21,7 @@ public static void Ctor_Default() [InlineData(null, null)] [InlineData("", "BCL0006")] [InlineData("message", "")] - public void Ctor_String_Id(string message, string id) + public void Ctor_String_Id(string? message, string? id) { var attribute = new ObsoleteAttribute(message) { DiagnosticId = id }; Assert.Equal(message, attribute.Message); @@ -34,7 +34,7 @@ public void Ctor_String_Id(string message, string id) [InlineData(null, true, "")] [InlineData("", false, null)] [InlineData("message", true, "https://aka.ms/obsolete/{0}")] - public void Ctor_String_Bool_Url(string message, bool error, string url) + public void Ctor_String_Bool_Url(string? message, bool error, string? url) { var attribute = new ObsoleteAttribute(message, error) { UrlFormat = url }; Assert.Equal(message, attribute.Message); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyCompanyAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyCompanyAttributeTests.cs index b685373ea0b538..87295bd34d0abb 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyCompanyAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyCompanyAttributeTests.cs @@ -11,7 +11,7 @@ public class AssemblyCompanyAttributeTests [InlineData(null)] [InlineData("")] [InlineData("company")] - public void Ctor_String(string company) + public void Ctor_String(string? company) { var attribute = new AssemblyCompanyAttribute(company); Assert.Equal(company, attribute.Company); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyConfigurationAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyConfigurationAttributeTests.cs index 9041709da4acd1..6a8988c52b37e7 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyConfigurationAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyConfigurationAttributeTests.cs @@ -11,7 +11,7 @@ public class AssemblyConfigurationAttributeTests [InlineData(null)] [InlineData("")] [InlineData("configuration")] - public void Ctor_String(string configuration) + public void Ctor_String(string? configuration) { var attribute = new AssemblyConfigurationAttribute(configuration); Assert.Equal(configuration, attribute.Configuration); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyCopyrightAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyCopyrightAttributeTests.cs index 3142407a0e7067..bb3788bfe378f1 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyCopyrightAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyCopyrightAttributeTests.cs @@ -11,7 +11,7 @@ public class AssemblyCopyrightAttributeTests [InlineData(null)] [InlineData("")] [InlineData("copyright")] - public void Ctor_String(string copyright) + public void Ctor_String(string? copyright) { var attribute = new AssemblyCopyrightAttribute(copyright); Assert.Equal(copyright, attribute.Copyright); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyCultureAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyCultureAttributeTests.cs index 86aeb5f6a026c0..e921ad78ef3df8 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyCultureAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyCultureAttributeTests.cs @@ -11,7 +11,7 @@ public class AssemblyCultureAttributeTests [InlineData(null)] [InlineData("")] [InlineData("Czech")] - public void Ctor_String(string culture) + public void Ctor_String(string? culture) { var attribute = new AssemblyCultureAttribute(culture); Assert.Equal(culture, attribute.Culture); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyDefaultAliasAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyDefaultAliasAttributeTests.cs index 94f7d03f31a9ad..7167083ed41ec5 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyDefaultAliasAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyDefaultAliasAttributeTests.cs @@ -11,7 +11,7 @@ public class AssemblyDefaultAliasAttributeTests [InlineData(null)] [InlineData("")] [InlineData("defaultAlias")] - public void Ctor_String(string defaultAlias) + public void Ctor_String(string? defaultAlias) { var attribute = new AssemblyDefaultAliasAttribute(defaultAlias); Assert.Equal(defaultAlias, attribute.DefaultAlias); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyDescriptionAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyDescriptionAttributeTests.cs index efa97cf0917565..00b0cfc799891b 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyDescriptionAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyDescriptionAttributeTests.cs @@ -11,7 +11,7 @@ public class AssemblyDescriptionAttributeTests [InlineData(null)] [InlineData("")] [InlineData("description")] - public void Ctor_String(string description) + public void Ctor_String(string? description) { var attribute = new AssemblyDescriptionAttribute(description); Assert.Equal(description, attribute.Description); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyInformationalVersionAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyInformationalVersionAttributeTests.cs index 83ca8d4e07038a..026d3a00ca8c8e 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyInformationalVersionAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyInformationalVersionAttributeTests.cs @@ -12,7 +12,7 @@ public class AssemblyInformationalVersionAttributeTests [InlineData("")] [InlineData("version")] [InlineData("3.4.5.6.7")] - public void Ctor_String(string informationalVersion) + public void Ctor_String(string? informationalVersion) { var attribute = new AssemblyInformationalVersionAttribute(informationalVersion); Assert.Equal(informationalVersion, attribute.InformationalVersion); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyKeyFileAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyKeyFileAttributeTests.cs index 84ffd312fe20b3..5b1062293f3305 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyKeyFileAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyKeyFileAttributeTests.cs @@ -12,7 +12,7 @@ public class AssemblyKeyFileAttributeTests [InlineData("")] [InlineData("keyFile")] [InlineData("KeyFile.snk")] - public void Ctor_String(string keyFile) + public void Ctor_String(string? keyFile) { var attribute = new AssemblyKeyFileAttribute(keyFile); Assert.Equal(keyFile, attribute.KeyFile); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyKeyNameAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyKeyNameAttributeTests.cs index e4decff7790ea6..099638767a6000 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyKeyNameAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyKeyNameAttributeTests.cs @@ -11,7 +11,7 @@ public class AssemblyKeyNameAttributeTests [InlineData(null)] [InlineData("")] [InlineData("keyName")] - public void Ctor_String(string keyName) + public void Ctor_String(string? keyName) { var attribute = new AssemblyKeyNameAttribute(keyName); Assert.Equal(keyName, attribute.KeyName); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyMetadataAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyMetadataAttributeTests.cs index 5a80e97444117c..d87d9109f91ef0 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyMetadataAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyMetadataAttributeTests.cs @@ -11,7 +11,7 @@ public class AssemblyMetadataAttributeTests [InlineData(null, null)] [InlineData("", "")] [InlineData("key", "value")] - public void Ctor_String_String(string key, string value) + public void Ctor_String_String(string? key, string? value) { var attribute = new AssemblyMetadataAttribute(key, value); Assert.Equal(key, attribute.Key); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyProductAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyProductAttributeTests.cs index 2787e74d3ebb14..6f83daee9662d3 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyProductAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyProductAttributeTests.cs @@ -12,7 +12,7 @@ public class AssemblyProductAttributeTests [InlineData("")] [InlineData("product")] [InlineData(".NET Core")] - public void Ctor_String(string product) + public void Ctor_String(string? product) { var attribute = new AssemblyProductAttribute(product); Assert.Equal(product, attribute.Product); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblySignatureKeyAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblySignatureKeyAttributeTests.cs index 94a1ba0c44995b..0dbf27ab5253e5 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblySignatureKeyAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblySignatureKeyAttributeTests.cs @@ -11,7 +11,7 @@ public class AssemblySignatureKeyAttributeTests [InlineData(null, null)] [InlineData("", "")] [InlineData("publicKey", "countersignature")] - public void Ctor_String_String(string publicKey, string countersignature) + public void Ctor_String_String(string? publicKey, string? countersignature) { var attribute = new AssemblySignatureKeyAttribute(publicKey, countersignature); Assert.Equal(publicKey, attribute.PublicKey); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyTitleAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyTitleAttributeTests.cs index bb9f8c28157359..ef3fb0129b913c 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyTitleAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyTitleAttributeTests.cs @@ -11,7 +11,7 @@ public class AssemblyTitleAttributeTests [InlineData(null)] [InlineData("")] [InlineData("title")] - public void Ctor_String(string title) + public void Ctor_String(string? title) { var attribute = new AssemblyTitleAttribute(title); Assert.Equal(title, attribute.Title); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyTrademarkAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyTrademarkAttributeTests.cs index bce1353d9f0a51..1e178f89633eda 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyTrademarkAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyTrademarkAttributeTests.cs @@ -11,7 +11,7 @@ public class AssemblyTrademarkAttributeTests [InlineData(null)] [InlineData("")] [InlineData("trademark")] - public void Ctor_String(string trademark) + public void Ctor_String(string? trademark) { var attribute = new AssemblyTrademarkAttribute(trademark); Assert.Equal(trademark, attribute.Trademark); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyVersionAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyVersionAttributeTests.cs index c79b9c9c49f0b8..844c00491af841 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyVersionAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/AssemblyVersionAttributeTests.cs @@ -12,7 +12,7 @@ public class AssemblyVersionAttributeTests [InlineData("")] [InlineData("version")] [InlineData("5.6.7.8.9")] - public void Ctor_String(string version) + public void Ctor_String(string? version) { var attribute = new AssemblyVersionAttribute(version); Assert.Equal(version, attribute.Version); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/DefaultMemberAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/DefaultMemberAttributeTests.cs index f0cc50bdbd2a92..5502b2e503267a 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/DefaultMemberAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/DefaultMemberAttributeTests.cs @@ -11,7 +11,7 @@ public class DefaultMemberAttributeTests [InlineData(null)] [InlineData("")] [InlineData("configuration")] - public void Ctor_String(string memberName) + public void Ctor_String(string? memberName) { var attribute = new DefaultMemberAttribute(memberName); Assert.Equal(memberName, attribute.MemberName); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/NullabilityInfoContextTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/NullabilityInfoContextTests.cs index aad27ed900cfaa..25e80df1fa867e 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/NullabilityInfoContextTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/NullabilityInfoContextTests.cs @@ -896,12 +896,12 @@ public void NullablePublicOnlyStringTypeTest(string methodName, NullabilityState [SkipOnMono("Nullability attributes trimmed on Mono")] public void NullablePublicOnlyOtherTypesTest() { - Type type = typeof(Type); - FieldInfo privateNullableField = type.GetField("s_defaultBinder", flags)!; + FieldInfo privateNullableField = typeof(AppDomain).GetField("s_domain", flags)!; NullabilityInfo info = nullabilityContext.Create(privateNullableField); Assert.Equal(NullabilityState.Unknown, info.ReadState); Assert.Equal(NullabilityState.Unknown, info.WriteState); + Type type = typeof(Type); MethodInfo internalNotNullableMethod = type.GetMethod("GetRootElementType", flags)!; info = nullabilityContext.Create(internalNotNullableMethod.ReturnParameter); Assert.Equal(NullabilityState.NotNull, info.ReadState); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/ObfuscationAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/ObfuscationAttributeTests.cs index 589f0906cb1c70..05ca5573642442 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/ObfuscationAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/ObfuscationAttributeTests.cs @@ -45,7 +45,7 @@ public void Exclude_Set_GetReturnsExpected(bool value) [InlineData(null)] [InlineData("")] [InlineData("feature")] - public void Feature_Set_GetReturnsExpected(string value) + public void Feature_Set_GetReturnsExpected(string? value) { var attribute = new ObfuscationAttribute { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/StrongNameKeyPairTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/StrongNameKeyPairTests.cs index 10cf716f583303..54fc76d0e8a1d0 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/StrongNameKeyPairTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Reflection/StrongNameKeyPairTests.cs @@ -45,7 +45,7 @@ public void Ctor_NullKeyPairFile_ThrowsPlatformNotSupportedException() [InlineData(null)] [InlineData("")] [InlineData("keyPairContainer")] - public void Ctor_String_ThrowsPlatformNotSupportedException(string keyPairContainer) + public void Ctor_String_ThrowsPlatformNotSupportedException(string? keyPairContainer) { Assert.Throws(() => new StrongNameKeyPair(keyPairContainer)); } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/AttributesTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/AttributesTests.cs index bb7539a4e357e5..e80943edf58551 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/AttributesTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/AttributesTests.cs @@ -235,6 +235,15 @@ public static void RefSafetyRulesAttributeTests(int version) Assert.Equal(version, attr.Version); } + [Theory] + [InlineData("1")] + [InlineData("2")] + public static void ExtensionMarkerAttributeTests(string name) + { + var attr = new ExtensionMarkerAttribute(name); + Assert.Equal(name, attr.Name); + } + [Fact] public static void ReferenceAssemblyAttributeTests() { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/Serialization/StreamingContextTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/Serialization/StreamingContextTests.cs index 489e9cd2c74900..6afc053c0b8217 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/Serialization/StreamingContextTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/Serialization/StreamingContextTests.cs @@ -30,7 +30,7 @@ public void Ctor_StreamingContextStates(StreamingContextStates state) [InlineData(StreamingContextStates.All, null)] [InlineData((StreamingContextStates)0, "")] [InlineData((StreamingContextStates)(-1), "context")] - public void Ctor_StreamingContextStates_Object(StreamingContextStates state, object additional) + public void Ctor_StreamingContextStates_Object(StreamingContextStates state, object? additional) { var context = new StreamingContext(state, additional); Assert.Equal(state, context.State); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/Versioning/RequiresPreviewFeaturesAttributeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/Versioning/RequiresPreviewFeaturesAttributeTests.cs index 1751b90a576905..ed9c7dab5d54d5 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/Versioning/RequiresPreviewFeaturesAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/Versioning/RequiresPreviewFeaturesAttributeTests.cs @@ -25,7 +25,7 @@ public static void Ctor_Default() [InlineData(null)] [InlineData("")] [InlineData("message")] - public void Ctor_String_Message(string message) + public void Ctor_String_Message(string? message) { var attribute = new RequiresPreviewFeaturesAttribute(message); Assert.Same(message, attribute.Message); @@ -36,7 +36,7 @@ public void Ctor_String_Message(string message) [InlineData(null, "")] [InlineData("", null)] [InlineData("message", "https://aka.ms/preview-features/")] - public void Ctor_String_Url(string message, string url) + public void Ctor_String_Url(string? message, string? url) { var attribute = new RequiresPreviewFeaturesAttribute(message) { Url = url }; Assert.Same(message, attribute.Message); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SByteTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SByteTests.cs index 7b92f123fd498e..effc332bc5b93d 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SByteTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SByteTests.cs @@ -48,7 +48,7 @@ public static void MinValue() [InlineData((sbyte)-114, sbyte.MaxValue, -1)] [InlineData(sbyte.MaxValue, sbyte.MaxValue, 0)] [InlineData((sbyte)114, null, 1)] - public void CompareTo_Other_ReturnsExpected(sbyte i, object value, int expected) + public void CompareTo_Other_ReturnsExpected(sbyte i, object? value, int expected) { if (value is sbyte sbyteValue) { @@ -77,7 +77,7 @@ public void CompareTo_ObjectNotSByte_ThrowsArgumentException(object value) [InlineData((sbyte)78, null, false)] [InlineData((sbyte)78, "78", false)] [InlineData((sbyte)78, 78, false)] - public static void EqualsTest(sbyte i1, object obj, bool expected) + public static void EqualsTest(sbyte i1, object? obj, bool expected) { if (obj is sbyte) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SingleTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SingleTests.cs index a7152e5ab00efb..fc8f547f15ea45 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SingleTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SingleTests.cs @@ -56,7 +56,7 @@ public static void CompareTo_ObjectNotFloat_ThrowsArgumentException(object value [InlineData(float.NegativeInfinity, float.PositiveInfinity, -1)] [InlineData(float.PositiveInfinity, float.PositiveInfinity, 0)] [InlineData(float.PositiveInfinity, float.NegativeInfinity, 1)] - public static void CompareTo_Other_ReturnsExpected(float f1, object value, int expected) + public static void CompareTo_Other_ReturnsExpected(float f1, object? value, int expected) { if (value is float f2) { @@ -128,7 +128,7 @@ public static void Epsilon() [InlineData(float.NaN, -float.NaN, true)] [InlineData(789.0f, 789.0, false)] [InlineData(789.0f, "789", false)] - public static void EqualsTest(float f1, object value, bool expected) + public static void EqualsTest(float f1, object? value, bool expected) { if (value is float f2) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/String.SplitTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/String.SplitTests.cs index 1cda74cfda28d6..317695b20493b0 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/String.SplitTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/String.SplitTests.cs @@ -571,7 +571,7 @@ public static void SplitCharSeparator(string value, char separator, int count, S [InlineData(" a b ", null, 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries, new[] { "a b" })] [InlineData(" a b ", "", 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries, new[] { "a b" })] [InlineData(" a b ", " ", 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries, new[] { "a", "b" })] - public static void SplitStringSeparator(string value, string separator, int count, StringSplitOptions options, string[] expected) + public static void SplitStringSeparator(string value, string? separator, int count, StringSplitOptions options, string[] expected) { Assert.Equal(expected, value.Split(separator, count, options)); Assert.Equal(expected, value.Split(new[] { separator }, count, options)); @@ -638,7 +638,7 @@ public static void SplitNullCharArraySeparator_BindsToCharArrayOverload() [InlineData(" a b ", null, 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries, new[] { "a", "b" })] [InlineData(" a b ", new char[0], 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries, new[] { "a", "b" })] [InlineData(" a b ", new char[] { ' ' }, 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries, new[] { "a", "b" })] - public static void SplitCharArraySeparator(string value, char[] separators, int count, StringSplitOptions options, string[] expected) + public static void SplitCharArraySeparator(string value, char[]? separators, int count, StringSplitOptions options, string[] expected) { Assert.Equal(expected, value.Split(separators, count, options)); Assert.Equal(expected, value.Split(ToStringArray(separators), count, options)); @@ -697,7 +697,7 @@ public static void SplitCharArraySeparator(string value, char[] separators, int [InlineData(" a b ", null, 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries, new[] { "a", "b" })] [InlineData(" a b ", new string[0], 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries, new[] { "a", "b" })] [InlineData(" a b ", new string[] { " " }, 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries, new[] { "a", "b" })] - public static void SplitStringArraySeparator(string value, string[] separators, int count, StringSplitOptions options, string[] expected) + public static void SplitStringArraySeparator(string value, string[]? separators, int count, StringSplitOptions options, string[] expected) { Assert.Equal(expected, value.Split(separators, count, options)); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/StringTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/StringTests.cs index 990e55f1d09a5c..4d7258fb4c0985 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/StringTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/StringTests.cs @@ -993,7 +993,6 @@ public static IEnumerable NonRandomizedGetHashCode_EquivalentForString [Theory] [MemberData(nameof(NonRandomizedGetHashCode_EquivalentForStringAndSpan_MemberData))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/116815", TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.MacCatalyst)] public static void NonRandomizedGetHashCode_EquivalentForStringAndSpan(int charValueLimit, bool ignoreCase) { // This is testing internal API. If that API changes, this test will need to be updated. diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/StringBuilderReplaceTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/StringBuilderReplaceTests.cs index c4752d17682896..54ebfca0141029 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/StringBuilderReplaceTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/StringBuilderReplaceTests.cs @@ -25,7 +25,7 @@ public abstract class StringBuilderReplaceTests [InlineData("aaaabbbbccccdddd", "aaaabbbbccccdddd", "", 16, 0, "aaaabbbbccccdddd")] [InlineData("aaaabbbbccccdddd", "aaaabbbbccccdddde", "", 0, 16, "aaaabbbbccccdddd")] [InlineData("aaaaaaaaaaaaaaaa", "a", "b", 0, 16, "bbbbbbbbbbbbbbbb")] - public void Replace_StringBuilder(string value, string oldValue, string newValue, int startIndex, int count, string expected) + public void Replace_StringBuilder(string value, string oldValue, string? newValue, int startIndex, int count, string expected) { StringBuilder builder; if (startIndex == 0 && count == value.Length) diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/StringBuilderTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/StringBuilderTests.cs index 5671c6d3614e57..27a9a02eded2f9 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/StringBuilderTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/StringBuilderTests.cs @@ -70,7 +70,7 @@ public static void Ctor_Int_Int_Invalid() [InlineData("Hello")] [InlineData("")] [InlineData(null)] - public static void Ctor_String(string value) + public static void Ctor_String(string? value) { var builder = new StringBuilder(value); @@ -83,7 +83,7 @@ public static void Ctor_String(string value) [InlineData("Hello")] [InlineData("")] [InlineData(null)] - public static void Ctor_String_Int(string value) + public static void Ctor_String_Int(string? value) { var builder = new StringBuilder(value, 42); @@ -105,7 +105,7 @@ public static void Ctor_String_Int_NegativeCapacity_ThrowsArgumentOutOfRangeExce [InlineData("Hello", 2, 3)] [InlineData("", 0, 0)] [InlineData(null, 0, 0)] - public static void Ctor_String_Int_Int_Int(string value, int startIndex, int length) + public static void Ctor_String_Int_Int_Int(string? value, int startIndex, int length) { var builder = new StringBuilder(value, startIndex, length, 42); @@ -384,7 +384,7 @@ public static void Append_Long_NoSpareCapacity_ThrowsArgumentOutOfRangeException [InlineData("", "g", "g")] [InlineData("Hello", "", "Hello")] [InlineData("Hello", null, "Hello")] - public static void Append_Object(string original, object value, string expected) + public static void Append_Object(string original, object? value, string expected) { var builder = new StringBuilder(original); builder.Append(value); @@ -562,7 +562,7 @@ public static void Append_Char_NoSpareCapacity_ThrowsArgumentOutOfRangeException [InlineData("", new char[] { 'a' }, 0, "")] [InlineData("Hello", new char[0], 0, "Hello")] [InlineData("Hello", null, 0, "Hello")] - public static unsafe void Append_CharPointer(string original, char[] charArray, int valueCount, string expected) + public static unsafe void Append_CharPointer(string original, char[]? charArray, int valueCount, string expected) { _ = charArray; // https://github.com/xunit/xunit/issues/1969 fixed (char* value = charArray) @@ -613,7 +613,7 @@ public static unsafe void Append_CharPointer_NoSpareCapacity_ThrowsArgumentOutOf [InlineData("Hello", "g", 0, 0, "Hello")] [InlineData("Hello", "", 0, 0, "Hello")] [InlineData("Hello", null, 0, 0, "Hello")] - public static void Append_String(string original, string value, int startIndex, int count, string expected) + public static void Append_String(string original, string? value, int startIndex, int count, string expected) { StringBuilder builder; if (startIndex == 0 && count == (value?.Length ?? 0)) @@ -673,7 +673,7 @@ public static void Append_String_NoSpareCapacity_ThrowsArgumentOutOfRangeExcepti [InlineData("Hello", new char[] { 'e' }, 0, 0, "Hello")] [InlineData("Hello", new char[0], 0, 0, "Hello")] [InlineData("Hello", null, 0, 0, "Hello")] - public static void Append_CharArray(string original, char[] value, int startIndex, int charCount, string expected) + public static void Append_CharArray(string original, char[]? value, int startIndex, int charCount, string expected) { StringBuilder builder; if (startIndex == 0 && charCount == (value?.Length ?? 0)) @@ -1355,7 +1355,7 @@ public static void Insert_Float_Invalid() [InlineData("Hello", 5, "def", "Hellodef")] [InlineData("Hello", 0, "", "Hello")] [InlineData("Hello", 0, null, "Hello")] - public static void Insert_Object(string original, int index, object value, string expected) + public static void Insert_Object(string original, int index, object? value, string expected) { var builder = new StringBuilder(original); builder.Insert(index, value); @@ -1544,7 +1544,7 @@ public static void Insert_SByte_Invalid() [InlineData("Hello", 0, null, 1, "Hello")] [InlineData("Hello", 3, "abc", 2, "Helabcabclo")] [InlineData("Hello", 5, "def", 2, "Hellodefdef")] - public static void Insert_String_Count(string original, int index, string value, int count, string expected) + public static void Insert_String_Count(string original, int index, string? value, int count, string expected) { StringBuilder builder; if (count == 1) @@ -1590,7 +1590,7 @@ public static void Insert_String_Count_Invalid() [InlineData("Hello", 3, new char[] { 'a', 'b', 'c' }, 1, 1, "Helblo")] [InlineData("Hello", 3, new char[] { 'a', 'b', 'c' }, 1, 2, "Helbclo")] [InlineData("Hello", 3, new char[] { 'a', 'b', 'c' }, 0, 2, "Helablo")] - public static void Insert_CharArray(string original, int index, char[] value, int startIndex, int charCount, string expected) + public static void Insert_CharArray(string original, int index, char[]? value, int startIndex, int charCount, string expected) { StringBuilder builder; if (startIndex == 0 && charCount == (value?.Length ?? 0)) @@ -1836,7 +1836,7 @@ private sealed class NullToStringObject [InlineData("", "123")] [InlineData(" ", "1 2 3")] [InlineData(", ", "1, 2, 3")] - public static void AppendJoin_TestStringSeparators(string separator, string expected) + public static void AppendJoin_TestStringSeparators(string? separator, string expected) { var values = new object[] { 1, 2, 3 }; var stringValues = new string[] { "1", "2", "3" }; @@ -1859,7 +1859,7 @@ private static StringBuilder CreateBuilderWithNoSpareCapacity() [InlineData("", new object[] { "", "" })] [InlineData(" ", new object[] { })] [InlineData(", ", new object[] { "" })] - public static void AppendJoin_NoValues_NoSpareCapacity_DoesNotThrow(string separator, object[] values) + public static void AppendJoin_NoValues_NoSpareCapacity_DoesNotThrow(string? separator, object[] values) { var stringValues = Array.ConvertAll(values, _ => _?.ToString()); var enumerable = values.Select(_ => _); @@ -1884,7 +1884,7 @@ public static void AppendJoin_NoValues_NoSpareCapacity_DoesNotThrow(string separ [InlineData(" ", new object[] { " " })] [InlineData(" ", new object[] { null, null })] [InlineData(" ", new object[] { "", "" })] - public static void AppendJoin_NoSpareCapacity_ThrowsArgumentOutOfRangeException(string separator, object[] values) + public static void AppendJoin_NoSpareCapacity_ThrowsArgumentOutOfRangeException(string? separator, object[] values) { var builder = new StringBuilder(0, 5); builder.Append("Hello"); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/TimeZoneInfoTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/TimeZoneInfoTests.cs index dfeed3d52eb99d..15520e03f56431 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/TimeZoneInfoTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/TimeZoneInfoTests.cs @@ -57,7 +57,7 @@ static TimeZoneInfoTests() // Name abbreviations, if available, are used instead public static IEnumerable Platform_TimeZoneNamesTestData() { - if (PlatformDetection.IsBrowser || (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform && (PlatformDetection.IsMacCatalyst || PlatformDetection.IsiOS || PlatformDetection.IstvOS))) + if (PlatformDetection.IsBrowser) return new TheoryData { { TimeZoneInfo.FindSystemTimeZoneById(s_strPacific), "(UTC-08:00) America/Los_Angeles", null, "PST", "PDT", null }, @@ -68,7 +68,7 @@ public static IEnumerable Platform_TimeZoneNamesTestData() { s_NewfoundlandTz, "(UTC-03:30) America/St_Johns", null, "NST", "NDT", null }, { s_catamarcaTz, "(UTC-03:00) America/Argentina/Catamarca", null, "-03", "-02", null } }; - else if (PlatformDetection.IsHybridGlobalizationOnApplePlatform && (PlatformDetection.IsMacCatalyst || PlatformDetection.IsiOS || PlatformDetection.IstvOS)) + else if (PlatformDetection.IsAppleMobile) return new TheoryData { { TimeZoneInfo.FindSystemTimeZoneById(s_strPacific), "(UTC-08:00) America/Los_Angeles", null, "Pacific Standard Time", "Pacific Daylight Time", "Pacific Summer Time" }, @@ -93,7 +93,7 @@ public static IEnumerable Platform_TimeZoneNamesTestData() return new TheoryData { { TimeZoneInfo.FindSystemTimeZoneById(s_strPacific), "(UTC-08:00) Pacific Time (Los Angeles)", null, "Pacific Standard Time", "Pacific Daylight Time", "Pacific Summer Time" }, - { TimeZoneInfo.FindSystemTimeZoneById(s_strSydney), "(UTC+10:00) Eastern Australia Time (Sydney)", null, "Australian Eastern Standard Time", "Australian Eastern Daylight Time", null }, + { TimeZoneInfo.FindSystemTimeZoneById(s_strSydney), "(UTC+10:00) Eastern Australia Time (Sydney)", "(UTC+10:00) Australian Eastern Time (Sydney)", "Australian Eastern Standard Time", "Australian Eastern Daylight Time", null }, { TimeZoneInfo.FindSystemTimeZoneById(s_strPerth), "(UTC+08:00) Australian Western Standard Time (Perth)", null, "Australian Western Standard Time", "Australian Western Daylight Time", null }, { TimeZoneInfo.FindSystemTimeZoneById(s_strIran), "(UTC+03:30) Iran Time", "(UTC+03:30) Iran Standard Time (Tehran)", "Iran Standard Time", "Iran Daylight Time", "Iran Summer Time" }, { s_NewfoundlandTz, "(UTC-03:30) Newfoundland Time (St. John’s)", null, "Newfoundland Standard Time", "Newfoundland Daylight Time", null }, @@ -2732,6 +2732,7 @@ public static void FijiTimeZoneTest() [ConditionalFact] [ActiveIssue("https://github.com/dotnet/runtime/issues/64111", TestPlatforms.Linux)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/117731", TestPlatforms.Android)] public static void NoBackwardTimeZones() { if (OperatingSystem.IsAndroid() && !OperatingSystem.IsAndroidVersionAtLeast(26)) diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Type/TypeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Type/TypeTests.cs index 221b03f1050ead..e800d331b0bf66 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Type/TypeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Type/TypeTests.cs @@ -509,6 +509,29 @@ public void GetTypeByName_ValidType_ReturnsExpected(string typeName, Type expect Assert.Equal(expectedType, Type.GetType(typeName.ToLower(), throwOnError: false, ignoreCase: true)); } + public static IEnumerable GetTypeByName_InvalidElementType() + { + Type expectedException = PlatformDetection.IsMonoRuntime + ? typeof(ArgumentException) // https://github.com/dotnet/runtime/issues/45033 + : typeof(TypeLoadException); + + yield return new object[] { "System.Int32&&", expectedException, true }; + yield return new object[] { "System.Int32&*", expectedException, true }; + yield return new object[] { "System.Int32&[]", expectedException, true }; + yield return new object[] { "System.Int32&[*]", expectedException, true }; + yield return new object[] { "System.Int32&[,]", expectedException, true }; + + // https://github.com/dotnet/runtime/issues/45033 + if (!PlatformDetection.IsMonoRuntime) + { + yield return new object[] { "..Outside`1", expectedException, false }; + yield return new object[] { ".Outside`1+.Inside`1", expectedException, false }; + + yield return new object[] { "System.Void[]", expectedException, true }; + yield return new object[] { "System.TypedReference[]", expectedException, true }; + } + } + [Theory] [InlineData("system.nullable`1[system.int32]", typeof(TypeLoadException), false)] [InlineData("System.NonExistingType", typeof(TypeLoadException), false)] @@ -517,15 +540,7 @@ public void GetTypeByName_ValidType_ReturnsExpected(string typeName, Type expect [InlineData("Outside`2", typeof(TypeLoadException), false)] [InlineData("Outside`1[System.Boolean, System.Int32]", typeof(ArgumentException), true)] [InlineData(".System.Int32", typeof(TypeLoadException), false)] - [InlineData("..Outside`1", typeof(TypeLoadException), false)] - [InlineData(".Outside`1+.Inside`1", typeof(TypeLoadException), false)] - [InlineData("System.Int32&&", typeof(TypeLoadException), true)] - [InlineData("System.Int32&*", typeof(TypeLoadException), true)] - [InlineData("System.Int32&[]", typeof(TypeLoadException), true)] - [InlineData("System.Int32&[*]", typeof(TypeLoadException), true)] - [InlineData("System.Int32&[,]", typeof(TypeLoadException), true)] - [InlineData("System.Void[]", typeof(TypeLoadException), true)] - [InlineData("System.TypedReference[]", typeof(TypeLoadException), true)] + [MemberData(nameof(GetTypeByName_InvalidElementType))] public void GetTypeByName_Invalid(string typeName, Type expectedException, bool alwaysThrowsException) { if (!alwaysThrowsException) @@ -584,7 +599,7 @@ public void Delimiter() [InlineData(typeof(ushort), TypeCode.UInt16)] [InlineData(typeof(uint), TypeCode.UInt32)] [InlineData(typeof(ulong), TypeCode.UInt64)] - public void GetTypeCode_ValidType_ReturnsExpected(Type t, TypeCode typeCode) + public void GetTypeCode_ValidType_ReturnsExpected(Type? t, TypeCode typeCode) { Assert.Equal(typeCode, Type.GetTypeCode(t)); } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt128Tests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt128Tests.cs index d37f1d2a2c7bf6..a5d8716a2ecf2b 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt128Tests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt128Tests.cs @@ -496,5 +496,26 @@ public static void Runtime75416() UInt128 b = (UInt128Tests_GenericMath.Int128MaxValue - 10u) * (UInt128)(Int128)(-100); Assert.Equal(b, 1100u); } + + public static IEnumerable BigMul_TestData() + { + yield return new object[] { (UInt128)0, (UInt128)0, "0000000000000000000000000000000000000000000000000000000000000000" }; + yield return new object[] { (UInt128)0, (UInt128)1, "0000000000000000000000000000000000000000000000000000000000000000" }; + yield return new object[] { (UInt128)1, (UInt128)0, "0000000000000000000000000000000000000000000000000000000000000000" }; + yield return new object[] { (UInt128)2, (UInt128)3, "0000000000000000000000000000000000000000000000000000000000000006" }; + yield return new object[] { UInt128.MaxValue, (UInt128)2, "00000000000000000000000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" }; + yield return new object[] { UInt128.MaxValue, (UInt128)1, "00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" }; + yield return new object[] { UInt128.MaxValue, UInt128.MaxValue, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE00000000000000000000000000000001" }; + yield return new object[] { UInt128.MaxValue, (UInt128)3, "00000000000000000000000000000002FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD" }; + yield return new object[] { new UInt128(0xE8FAF08929B46BB5, 0x26B442D59782BA17), new UInt128(0x26B442D59782BA17, 0xE8FAF08929B46BB5), "23394CF891529663F897F2180AA9D1F6EA183EE8D7CCD26D1EB6255F4A612F43" }; + } + + [Theory] + [MemberData(nameof(BigMul_TestData))] + public static void BigMul(UInt128 a, UInt128 b, string result) + { + UInt128 upper = UInt128.BigMul(a, b, out UInt128 lower); + Assert.Equal(result, $"{upper:X32}{lower:X32}"); + } } } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt16Tests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt16Tests.cs index 6ddf7c3bfbaab1..bc5ffd25435887 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt16Tests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt16Tests.cs @@ -43,7 +43,7 @@ public static void MinValue() [InlineData((ushort)234, (ushort)456, -1)] [InlineData((ushort)234, ushort.MaxValue, -1)] [InlineData((ushort)234, null, 1)] - public void CompareTo_Other_ReturnsExpected(ushort i, object value, int expected) + public void CompareTo_Other_ReturnsExpected(ushort i, object? value, int expected) { if (value is ushort ushortValue) { @@ -68,7 +68,7 @@ public void CompareTo_ObjectNotUshort_ThrowsArgumentException(object value) [InlineData((ushort)789, null, false)] [InlineData((ushort)789, "789", false)] [InlineData((ushort)789, 789, false)] - public static void EqualsTest(ushort i1, object obj, bool expected) + public static void EqualsTest(ushort i1, object? obj, bool expected) { if (obj is ushort) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt32Tests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt32Tests.cs index c2f80bba01dda7..ade9fe7664bec6 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt32Tests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt32Tests.cs @@ -44,7 +44,7 @@ public static void MinValue() [InlineData((uint)234, (uint)456, -1)] [InlineData((uint)234, uint.MaxValue, -1)] [InlineData((uint)234, null, 1)] - public void CompareTo_Other_ReturnsExpected(uint i, object value, int expected) + public void CompareTo_Other_ReturnsExpected(uint i, object? value, int expected) { if (value is uint uintValue) { @@ -69,7 +69,7 @@ public void CompareTo_ObjectNotUint_ThrowsArgumentException(object value) [InlineData((uint)789, null, false)] [InlineData((uint)789, "789", false)] [InlineData((uint)789, 789, false)] - public static void EqualsTest(uint i1, object obj, bool expected) + public static void EqualsTest(uint i1, object? obj, bool expected) { if (obj is uint) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt64Tests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt64Tests.cs index 27efe49e48289e..2ef2bc24f5a3ef 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt64Tests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt64Tests.cs @@ -44,7 +44,7 @@ public static void MinValue() [InlineData((ulong)234, (ulong)456, -1)] [InlineData((ulong)234, ulong.MaxValue, -1)] [InlineData((ulong)234, null, 1)] - public void CompareTo_Other_ReturnsExpected(ulong i, object value, int expected) + public void CompareTo_Other_ReturnsExpected(ulong i, object? value, int expected) { if (value is ulong ulongValue) { @@ -69,7 +69,7 @@ public void CompareTo_ObjectNotUlong_ThrowsArgumentException(object value) [InlineData((ulong)789, null, false)] [InlineData((ulong)789, "789", false)] [InlineData((ulong)789, 789, false)] - public static void EqualsTest(ulong i1, object obj, bool expected) + public static void EqualsTest(ulong i1, object? obj, bool expected) { if (obj is ulong i2) { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UIntPtrTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UIntPtrTests.cs index 6978b9e44eb590..8308860583f80b 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UIntPtrTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UIntPtrTests.cs @@ -13,6 +13,7 @@ namespace System.Tests { public static class UIntPtrTests { + private static unsafe bool Is32Bit => sizeof(void*) == 4; private static unsafe bool Is64Bit => sizeof(void*) == 8; [Fact] @@ -108,7 +109,7 @@ public static IEnumerable Equals_TestData() [Theory] [MemberData(nameof(Equals_TestData))] - public static void EqualsTest(nuint value, object obj, bool expected) + public static void EqualsTest(nuint value, object? obj, bool expected) { if (obj is nuint other) { @@ -231,7 +232,7 @@ public static void MinValue() [InlineData(234u, 456u, -1)] [InlineData(234u, uint.MaxValue, -1)] [InlineData(234u, null, 1)] - public static void CompareTo_Other_ReturnsExpected(uint i0, object value, int expected) + public static void CompareTo_Other_ReturnsExpected(uint i0, object? value, int expected) { nuint i = i0; if (value is uint uintValue) @@ -608,5 +609,37 @@ public static void Parse_Utf8Span_InvalidUtf8() [MemberData(nameof(ToString_TestData))] public static void TryFormat(nuint i, string format, IFormatProvider provider, string expected) => NumberFormatTestHelper.TryFormatNumberTest(i, format, provider, expected); + + [ConditionalTheory(nameof(Is32Bit))] + [InlineData(0U, 0U, "0000000000000000")] + [InlineData(0U, 1U, "0000000000000000")] + [InlineData(1U, 0U, "0000000000000000")] + [InlineData(2U, 3U, "0000000000000006")] + [InlineData(uint.MaxValue, 2U, "00000001FFFFFFFE")] + [InlineData(uint.MaxValue, 1U, "00000000FFFFFFFF")] + [InlineData(uint.MaxValue, uint.MaxValue, "FFFFFFFE00000001")] + [InlineData(uint.MaxValue, 3U, "00000002FFFFFFFD")] + [InlineData(0x29B46BB5U, 0x9782BA17U, "18AEB7774A612F43")] + public static void BigMul32(uint a, uint b, string result) + { + nuint upper = nuint.BigMul(a, b, out nuint lower); + Assert.Equal(result, $"{upper:X8}{lower:X8}"); + } + + [ConditionalTheory(nameof(Is64Bit))] + [InlineData(0U, 0U, "00000000000000000000000000000000")] + [InlineData(0U, 1U, "00000000000000000000000000000000")] + [InlineData(1U, 0U, "00000000000000000000000000000000")] + [InlineData(2U, 3U, "00000000000000000000000000000006")] + [InlineData(ulong.MaxValue, 2, "0000000000000001FFFFFFFFFFFFFFFE")] + [InlineData(ulong.MaxValue, 1, "0000000000000000FFFFFFFFFFFFFFFF")] + [InlineData(ulong.MaxValue, ulong.MaxValue, "FFFFFFFFFFFFFFFE0000000000000001")] + [InlineData(ulong.MaxValue, 3, "0000000000000002FFFFFFFFFFFFFFFD")] + [InlineData(0xE8FAF08929B46BB5, 0x26B442D59782BA17, "23394CF8915296631EB6255F4A612F43")] + public static void BigMul64(ulong a, ulong b, string result) + { + nuint upper = nuint.BigMul((nuint)a, (nuint)b, out nuint lower); + Assert.Equal(result, $"{upper:X16}{lower:X16}"); + } } } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Uri.CreateStringTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Uri.CreateStringTests.cs index 2db37efa943d5c..2665f554b77fc3 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Uri.CreateStringTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Uri.CreateStringTests.cs @@ -11,7 +11,6 @@ namespace System.Tests public class UriCreateStringTests { private static readonly bool s_isWindowsSystem = PlatformDetection.IsWindows; - public static readonly string s_longString = new string('a', 65520 + 1); public static IEnumerable OriginalString_AbsoluteUri_ToString_TestData() { @@ -482,7 +481,7 @@ public void Scheme_Authority_IdnHost(string uriString, string scheme, string use }); } - public static IEnumerable Path_Query_Fragment_TestData() + public static IEnumerable Path_Query_Fragment_TestData_Core() { // Http yield return new object[] { "http://host", "/", "", "" }; @@ -802,6 +801,46 @@ public static IEnumerable Path_Query_Fragment_TestData() yield return new object[] { "file://C:/abc/def/../ghi", "C:/abc/ghi", "", "" }; } + public static IEnumerable Path_Query_Fragment_TestData() + { + foreach (object[] data in Path_Query_Fragment_TestData_Core()) + { + string uriString = (string)data[0]; + string path = (string)data[1]; + string query = (string)data[2]; + string fragment = (string)data[3]; + + yield return new object[] { uriString, path, query, fragment }; + yield return new object[] { new string(' ', 100_000) + uriString, path, query, fragment }; + + string longString = new string('^', 100_000); + string escaped = Uri.EscapeDataString(longString); + + int fragmentOffset = uriString.IndexOf('#'); + + if (fragmentOffset >= 0) + { + ReadOnlySpan beforeFragment = uriString.AsSpan(0, fragmentOffset); + ReadOnlySpan sourceFragment = uriString.AsSpan(fragmentOffset + 1); + yield return new object[] { $"{beforeFragment}#{longString}{sourceFragment}", path, query, $"#{escaped}{fragment.AsSpan(1)}" }; + } + + if (!string.IsNullOrEmpty(query) && uriString.IndexOf('?') is int queryOffset && queryOffset >= 0 && (fragmentOffset < 0 || fragmentOffset > queryOffset)) + { + ReadOnlySpan beforeQuery = uriString.AsSpan(0, queryOffset); + ReadOnlySpan sourceQuery = uriString.AsSpan(queryOffset + 1); + yield return new object[] { $"{beforeQuery}?{longString}{sourceQuery}", path, $"?{escaped}{query.AsSpan(1)}", fragment }; + } + + if (uriString.StartsWith("http://", StringComparison.OrdinalIgnoreCase) && !uriString.Contains('@')) + { + ReadOnlySpan remainder = uriString.AsSpan("http://".Length); + + yield return new object[] { $"http://{longString}@{remainder}", path, query, fragment }; + } + } + } + [Theory] [MemberData(nameof(Path_Query_Fragment_TestData))] public void Path_Query_Fragment(string uriString, string path, string query, string fragment) @@ -1028,8 +1067,6 @@ public void Create_String_InvalidUriKind_ThrowsArgumentException() public static IEnumerable Create_String_Invalid_TestData() { - yield return new object[] { s_longString, UriKind.Absolute }; // UriString is longer than 66520 characters - // Invalid scheme yield return new object[] { "", UriKind.Absolute }; yield return new object[] { " \t \r \n \x0009 \x000A \x000D ", UriKind.Absolute }; @@ -1050,6 +1087,7 @@ public static IEnumerable Create_String_Invalid_TestData() yield return new object[] { "http~://domain.com", UriKind.Absolute }; yield return new object[] { "http#://domain.com", UriKind.Absolute }; yield return new object[] { new string('a', 1025) + "://domain.com", UriKind.Absolute }; // Scheme is longer than 1024 characters + yield return new object[] { new string('a', 100_000), UriKind.Absolute }; // Invalid userinfo yield return new object[] { @"http://use\rinfo@host", UriKind.Absolute }; diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Uri.CreateUriTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Uri.CreateUriTests.cs index 7d5ffe6e9279af..79ea08c9fccc65 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Uri.CreateUriTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Uri.CreateUriTests.cs @@ -101,8 +101,23 @@ public static IEnumerable Create_Uri_TestData() yield return new object[] { "http://hostold/", "http://host/path/page", UriKind.Absolute, "http://host/path/page" }; } + public static IEnumerable Create_Uri_WithExtraWhiteSpace_TestData() + { + foreach (object[] testData in Create_Uri_TestData()) + { + string uriString1 = (string)testData[0]; + string uriString2 = (string)testData[1]; + UriKind uriKind = (UriKind)testData[2]; + string expectedUriString = (string)testData[3]; + + yield return new object[] { uriString1, uriString2, uriKind, expectedUriString }; + yield return new object[] { $"{new string(' ', 100_000)}{uriString1}", uriString2, uriKind, expectedUriString }; + yield return new object[] { uriString1, $"{new string(' ', 100_000)}{uriString2}", uriKind, expectedUriString }; + } + } + [Theory] - [MemberData(nameof(Create_Uri_TestData))] + [MemberData(nameof(Create_Uri_WithExtraWhiteSpace_TestData))] public void Create_Uri(string uriString1, string uriString2, UriKind uriKind, string expectedUriString) { Uri baseUri = new Uri(uriString1, UriKind.Absolute); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Uri.MethodsTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Uri.MethodsTests.cs index 9c6963215ae4bb..7b42936a154ca2 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Uri.MethodsTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Uri.MethodsTests.cs @@ -161,7 +161,7 @@ public void CheckHostName(string name, UriHostNameType expected) [InlineData("!", false)] [InlineData("", false)] [InlineData(null, false)] - public void CheckSchemeName(string schemeName, bool expected) + public void CheckSchemeName(string? schemeName, bool expected) { Assert.Equal(expected, Uri.CheckSchemeName(schemeName)); } @@ -272,7 +272,7 @@ public void IsWellFormedOriginalString(string uriString, bool expected) [InlineData("file://C:/directory/filename", UriKind.RelativeOrAbsolute, false)] [InlineData("http:\\host/path/file", UriKind.RelativeOrAbsolute, false)] [InlineData(null, UriKind.RelativeOrAbsolute, false)] - public void IsWellFormedUriString(string uriString, UriKind uriKind, bool expected) + public void IsWellFormedUriString(string? uriString, UriKind uriKind, bool expected) { Assert.Equal(expected, Uri.IsWellFormedUriString(uriString, uriKind)); } @@ -443,7 +443,7 @@ public void EscapeUriString_InvalidSurrogatePairs() public void EscapeUriString_Long_Success() { string s; - const int LongCount = 65520 + 1; + const int LongCount = 100_000; s = new string('a', LongCount); Assert.Equal(s, Uri.EscapeUriString(s)); diff --git a/src/libraries/System.Runtime/tests/System.Threading.Tasks.Extensions.Tests/PoolingAsyncValueTaskMethodBuilderTests.cs b/src/libraries/System.Runtime/tests/System.Threading.Tasks.Extensions.Tests/PoolingAsyncValueTaskMethodBuilderTests.cs index 62a6406c309b62..ce987a024f5b72 100644 --- a/src/libraries/System.Runtime/tests/System.Threading.Tasks.Extensions.Tests/PoolingAsyncValueTaskMethodBuilderTests.cs +++ b/src/libraries/System.Runtime/tests/System.Threading.Tasks.Extensions.Tests/PoolingAsyncValueTaskMethodBuilderTests.cs @@ -514,7 +514,7 @@ static async ValueTask ValueTaskAsync(int i) [InlineData(null)] [InlineData("1")] [InlineData("100")] - public void PoolingAsyncValueTasksBuilder_ObjectsPooled(string limitEnvVar) + public void PoolingAsyncValueTasksBuilder_ObjectsPooled(string? limitEnvVar) { // Use RemoteExecutor to launch a process with the right environment variables set var psi = new ProcessStartInfo(); diff --git a/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/System.Runtime.CompilerServices/AsyncTaskMethodBuilderTests.cs b/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/System.Runtime.CompilerServices/AsyncTaskMethodBuilderTests.cs index 4364e917eeac7a..102262dea7bd5f 100644 --- a/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/System.Runtime.CompilerServices/AsyncTaskMethodBuilderTests.cs +++ b/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/System.Runtime.CompilerServices/AsyncTaskMethodBuilderTests.cs @@ -386,7 +386,7 @@ public static void TaskMethodBuilderDecimal_DoesntUseCompletedCache() [Theory] [InlineData((string)null, true)] [InlineData("test", false)] - public static void TaskMethodBuilderRef_UsesCompletedCache(string result, bool shouldBeCached) + public static void TaskMethodBuilderRef_UsesCompletedCache(string? result, bool shouldBeCached) { TaskMethodBuilderT_UsesCompletedCache(result, shouldBeCached); } diff --git a/src/libraries/System.Security.AccessControl/System.Security.AccessControl.slnx b/src/libraries/System.Security.AccessControl/System.Security.AccessControl.slnx index de11291d4a4cb9..e7be8297b8c542 100644 --- a/src/libraries/System.Security.AccessControl/System.Security.AccessControl.slnx +++ b/src/libraries/System.Security.AccessControl/System.Security.AccessControl.slnx @@ -1,36 +1,370 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Security.AccessControl/src/System.Security.AccessControl.csproj b/src/libraries/System.Security.AccessControl/src/System.Security.AccessControl.csproj index 7d87c658a3b1c5..39045c0d3f76a1 100644 --- a/src/libraries/System.Security.AccessControl/src/System.Security.AccessControl.csproj +++ b/src/libraries/System.Security.AccessControl/src/System.Security.AccessControl.csproj @@ -88,15 +88,15 @@ - - - - - - - - - + + + + + + + + + diff --git a/src/libraries/System.Security.Claims/System.Security.Claims.slnx b/src/libraries/System.Security.Claims/System.Security.Claims.slnx index 6c57d2dc102902..936f7742d232d0 100644 --- a/src/libraries/System.Security.Claims/System.Security.Claims.slnx +++ b/src/libraries/System.Security.Claims/System.Security.Claims.slnx @@ -1,29 +1,226 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj b/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj index 4376906dbbc4bf..81fefd4bf4bc39 100644 --- a/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj +++ b/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj @@ -17,10 +17,10 @@ - - - - + + + + diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/System.Security.Cryptography.Cng.Tests.csproj b/src/libraries/System.Security.Cryptography.Cng/tests/System.Security.Cryptography.Cng.Tests.csproj index 045b1640017a19..e7ba206ca0c53d 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/System.Security.Cryptography.Cng.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.Cng/tests/System.Security.Cryptography.Cng.Tests.csproj @@ -37,6 +37,8 @@ + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Security.Cryptography.Cose/tests/TestKeyRing.cs b/src/libraries/System.Security.Cryptography.Cose/tests/TestKeyRing.cs index ede7573f555ba9..734c4373e94785 100644 --- a/src/libraries/System.Security.Cryptography.Cose/tests/TestKeyRing.cs +++ b/src/libraries/System.Security.Cryptography.Cose/tests/TestKeyRing.cs @@ -91,7 +91,7 @@ private static MLDsa CreateMLDsa(MLDsaAlgorithm algorithm, bool includePrivateKe if (includePrivateKey) { - return MLDsa.ImportMLDsaSecretKey(algorithm, nistKey.SecretKey); + return MLDsa.ImportMLDsaPrivateKey(algorithm, nistKey.PrivateKey); } else { diff --git a/src/libraries/System.Security.Cryptography.Csp/tests/RSAImportExportCspBlobTests.cs b/src/libraries/System.Security.Cryptography.Csp/tests/RSAImportExportCspBlobTests.cs index b35db7a2b3cf74..a81c84af511833 100644 --- a/src/libraries/System.Security.Cryptography.Csp/tests/RSAImportExportCspBlobTests.cs +++ b/src/libraries/System.Security.Cryptography.Csp/tests/RSAImportExportCspBlobTests.cs @@ -108,7 +108,7 @@ public static void RSAParametersToBlob_PublicOnly() Exponent = TestData.RSA1024Params.Exponent, }; - ImportExport.AssertKeyEquals(expected, exported); + RSATestHelpers.AssertKeyEquals(expected, exported); } [Fact] @@ -135,7 +135,7 @@ public static void RSAParametersToBlob_PublicPrivate() RSAParameters expected = TestData.RSA1024Params; - ImportExport.AssertKeyEquals(expected, exported); + RSATestHelpers.AssertKeyEquals(expected, exported); } } } diff --git a/src/libraries/System.Security.Cryptography.Csp/tests/System.Security.Cryptography.Csp.Tests.csproj b/src/libraries/System.Security.Cryptography.Csp/tests/System.Security.Cryptography.Csp.Tests.csproj index dfdc82fc4f8782..b5882c229b8c32 100644 --- a/src/libraries/System.Security.Cryptography.Csp/tests/System.Security.Cryptography.Csp.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.Csp/tests/System.Security.Cryptography.Csp.Tests.csproj @@ -32,6 +32,10 @@ Link="CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\KeyGeneration.cs" /> + + + PlatformDetection.IsNotSymCryptOpenSsl; } public partial class ECDsaFactory diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/tests/RsaOpenSslTests.cs b/src/libraries/System.Security.Cryptography.OpenSsl/tests/RsaOpenSslTests.cs index 6dc3413eef657c..2c3498ce8716d9 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/tests/RsaOpenSslTests.cs +++ b/src/libraries/System.Security.Cryptography.OpenSsl/tests/RsaOpenSslTests.cs @@ -103,7 +103,7 @@ public static void VerifyParameterCtor() { using (RSA rsa = new RSAOpenSsl(TestData.RSA1032Parameters)) { - ImportExport.AssertKeyEquals(TestData.RSA1032Parameters, rsa.ExportParameters(true)); + RSATestHelpers.AssertKeyEquals(TestData.RSA1032Parameters, rsa.ExportParameters(true)); } } } diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/tests/System.Security.Cryptography.OpenSsl.Tests.csproj b/src/libraries/System.Security.Cryptography.OpenSsl/tests/System.Security.Cryptography.OpenSsl.Tests.csproj index 95c91ee0bcbe08..244693109ed8a0 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/tests/System.Security.Cryptography.OpenSsl.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.OpenSsl/tests/System.Security.Cryptography.OpenSsl.Tests.csproj @@ -28,6 +28,8 @@ Link="CommonTest\System\Security\Cryptography\AlgorithmImplementations\EC\EccTestData.cs" /> + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.csproj b/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.csproj index 864dfd189a6b4d..d042e9d4d20dde 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.csproj +++ b/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.netcoreapp.cs b/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.netstandard21.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.netcoreapp.cs rename to src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.netstandard21.cs index e5b3bb8a4129dd..a28c452a5beeb9 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.netcoreapp.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.netstandard21.cs @@ -16,8 +16,12 @@ public sealed partial class CmsSigner { public CmsSigner(System.Security.Cryptography.Pkcs.SubjectIdentifierType signerIdentifierType, System.Security.Cryptography.X509Certificates.X509Certificate2? certificate, System.Security.Cryptography.AsymmetricAlgorithm? privateKey) { } [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] - public CmsSigner(System.Security.Cryptography.Pkcs.SubjectIdentifierType signerIdentifierType, System.Security.Cryptography.X509Certificates.X509Certificate2? certificate, System.Security.Cryptography.SlhDsa? privateKey) { } + public CmsSigner(System.Security.Cryptography.Pkcs.SubjectIdentifierType signerIdentifierType, System.Security.Cryptography.X509Certificates.X509Certificate2? certificate, System.Security.Cryptography.CompositeMLDsa? privateKey) { } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] + public CmsSigner(System.Security.Cryptography.Pkcs.SubjectIdentifierType signerIdentifierType, System.Security.Cryptography.X509Certificates.X509Certificate2? certificate, System.Security.Cryptography.MLDsa? privateKey) { } public CmsSigner(System.Security.Cryptography.Pkcs.SubjectIdentifierType signerIdentifierType, System.Security.Cryptography.X509Certificates.X509Certificate2? certificate, System.Security.Cryptography.RSA? privateKey, System.Security.Cryptography.RSASignaturePadding? signaturePadding) { } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] + public CmsSigner(System.Security.Cryptography.Pkcs.SubjectIdentifierType signerIdentifierType, System.Security.Cryptography.X509Certificates.X509Certificate2? certificate, System.Security.Cryptography.SlhDsa? privateKey) { } public System.Security.Cryptography.AsymmetricAlgorithm? PrivateKey { get { throw null; } set { } } public System.Security.Cryptography.RSASignaturePadding? SignaturePadding { get { throw null; } set { } } } diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.cs index ba2df743228e23..9d61159b6d6d14 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.cs @@ -84,6 +84,8 @@ public override byte[] GetSubjectKeyIdentifier(X509Certificate2 certificate) if (typeof(T) == typeof(DSA) && Internal.Cryptography.Helpers.IsDSASupported) return (T?)(object?)certificate.GetDSAPrivateKey(); #endif + if (typeof(T) == typeof(MLDsa) && MLDsa.IsSupported) + return (T?)(object?)certificate.GetMLDsaPrivateKey(); if (typeof(T) == typeof(SlhDsa) && SlhDsa.IsSupported) return (T?)(object?)certificate.GetSlhDsaPrivateKey(); diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.cs index c0720f65dad7b4..b3d61c823af70e 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.cs @@ -150,6 +150,8 @@ public sealed override byte[] GetSubjectKeyIdentifier(X509Certificate2 certifica return (T)(object)new ECDsaCng(cngKey); if (typeof(T) == typeof(DSA)) return (T)(object)new DSACng(cngKey); + if (typeof(T) == typeof(MLDsa)) + return (T)(object)new MLDsaCng(cngKey); if (typeof(T) == typeof(SlhDsa)) throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(SlhDsa))); diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs index c8f229368942ef..d2184523ec40f0 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs @@ -52,7 +52,7 @@ internal static HashAlgorithmName GetDigestAlgorithm(string? oidValue, bool forV case Oids.Sha512: case Oids.RsaPkcs1Sha512 when forVerification: return HashAlgorithmName.SHA512; -#if NET8_0_OR_GREATER +#if NET case Oids.Sha3_256: case Oids.RsaPkcs1Sha3_256 when forVerification: return HashAlgorithmName.SHA3_256; diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj b/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj index cc3bd8acb8999d..59e67ad0997f38 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj @@ -589,6 +589,7 @@ System.Security.Cryptography.Pkcs.EnvelopedCms + diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.ECDsa.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.ECDsa.cs index 4f3a76b44b2293..9934804a89bce5 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.ECDsa.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.ECDsa.cs @@ -17,7 +17,7 @@ static partial void PrepareRegistrationECDsa(Dictionary lo lookup.Add(Oids.ECDsaWithSha256, new ECDsaCmsSignature(Oids.ECDsaWithSha256, HashAlgorithmName.SHA256)); lookup.Add(Oids.ECDsaWithSha384, new ECDsaCmsSignature(Oids.ECDsaWithSha384, HashAlgorithmName.SHA384)); lookup.Add(Oids.ECDsaWithSha512, new ECDsaCmsSignature(Oids.ECDsaWithSha512, HashAlgorithmName.SHA512)); -#if NET8_0_OR_GREATER +#if NET lookup.Add(Oids.ECDsaWithSha3_256, new ECDsaCmsSignature(Oids.ECDsaWithSha3_256, HashAlgorithmName.SHA3_256)); lookup.Add(Oids.ECDsaWithSha3_384, new ECDsaCmsSignature(Oids.ECDsaWithSha3_384, HashAlgorithmName.SHA3_384)); lookup.Add(Oids.ECDsaWithSha3_512, new ECDsaCmsSignature(Oids.ECDsaWithSha3_512, HashAlgorithmName.SHA3_512)); @@ -137,7 +137,7 @@ protected override bool Sign( Oids.Sha256 => Oids.ECDsaWithSha256, Oids.Sha384 => Oids.ECDsaWithSha384, Oids.Sha512 => Oids.ECDsaWithSha512, -#if NET8_0_OR_GREATER +#if NET Oids.Sha3_256 => Oids.ECDsaWithSha3_256, Oids.Sha3_384 => Oids.ECDsaWithSha3_384, Oids.Sha3_512 => Oids.ECDsaWithSha3_512, diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.MLDsa.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.MLDsa.cs new file mode 100644 index 00000000000000..e7f70c18dd9d51 --- /dev/null +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.MLDsa.cs @@ -0,0 +1,118 @@ +// 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.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Security.Cryptography.X509Certificates; + +namespace System.Security.Cryptography.Pkcs +{ + internal partial class CmsSignature + { + static partial void PrepareRegistrationMLDsa(Dictionary lookup) + { + lookup.Add(Oids.MLDsa44, new MLDsaCmsSignature(Oids.MLDsa44)); + lookup.Add(Oids.MLDsa65, new MLDsaCmsSignature(Oids.MLDsa65)); + lookup.Add(Oids.MLDsa87, new MLDsaCmsSignature(Oids.MLDsa87)); + } + + private sealed class MLDsaCmsSignature : CmsSignature + { + private string _signatureAlgorithm; + + internal MLDsaCmsSignature(string signatureAlgorithm) + { + _signatureAlgorithm = signatureAlgorithm; + } + + protected override bool VerifyKeyType(object key) => key is MLDsa; + internal override bool NeedsHashedMessage => false; + + internal override RSASignaturePadding? SignaturePadding => null; + + internal override bool VerifySignature( +#if NET || NETSTANDARD2_1 + ReadOnlySpan valueHash, + ReadOnlyMemory signature, +#else + byte[] valueHash, + byte[] signature, +#endif + string? digestAlgorithmOid, + ReadOnlyMemory? signatureParameters, + X509Certificate2 certificate) + { + if (signatureParameters.HasValue) + { + throw new CryptographicException( + SR.Format(SR.Cryptography_UnknownAlgorithmIdentifier, _signatureAlgorithm)); + } + + MLDsa? publicKey = certificate.GetMLDsaPublicKey(); + + if (publicKey is null) + { + return false; + } + + using (publicKey) + { + return publicKey.VerifyData( + valueHash, +#if NET || NETSTANDARD2_1 + signature.Span +#else + signature +#endif + ); + } + } + + protected override bool Sign( +#if NET || NETSTANDARD2_1 + ReadOnlySpan dataHash, +#else + byte[] dataHash, +#endif + string? hashAlgorithmOid, + X509Certificate2 certificate, + object? key, + bool silent, + [NotNullWhen(true)] out string? signatureAlgorithm, + [NotNullWhen(true)] out byte[]? signatureValue, + out byte[]? signatureParameters) + { + signatureParameters = null; + signatureAlgorithm = _signatureAlgorithm; + + using (GetSigningKey(key, certificate, silent, static cert => cert.GetMLDsaPublicKey(), out MLDsa? signingKey)) + { + if (signingKey is null) + { + signatureValue = null; + return false; + } + + // Don't pool because we will likely return this buffer to the caller. + byte[] signature = new byte[signingKey.Algorithm.SignatureSizeInBytes]; + signingKey.SignData(dataHash, signature); + + if (key != null) + { + using (MLDsa certKey = certificate.GetMLDsaPublicKey()!) + { + if (!certKey.VerifyData(dataHash, signature)) + { + signatureValue = null; + return false; + } + } + } + + signatureValue = signature; + return true; + } + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs index 44c20006bfd6f7..557f7c94e4e4f8 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs @@ -20,7 +20,7 @@ static partial void PrepareRegistrationRsa(Dictionary look lookup.Add(Oids.RsaPkcs1Sha256, new RSAPkcs1CmsSignature(Oids.RsaPkcs1Sha256, HashAlgorithmName.SHA256)); lookup.Add(Oids.RsaPkcs1Sha384, new RSAPkcs1CmsSignature(Oids.RsaPkcs1Sha384, HashAlgorithmName.SHA384)); lookup.Add(Oids.RsaPkcs1Sha512, new RSAPkcs1CmsSignature(Oids.RsaPkcs1Sha512, HashAlgorithmName.SHA512)); -#if NET8_0_OR_GREATER +#if NET lookup.Add(Oids.RsaPkcs1Sha3_256, new RSAPkcs1CmsSignature(Oids.RsaPkcs1Sha3_256, HashAlgorithmName.SHA3_256)); lookup.Add(Oids.RsaPkcs1Sha3_384, new RSAPkcs1CmsSignature(Oids.RsaPkcs1Sha3_384, HashAlgorithmName.SHA3_384)); lookup.Add(Oids.RsaPkcs1Sha3_512, new RSAPkcs1CmsSignature(Oids.RsaPkcs1Sha3_512, HashAlgorithmName.SHA3_512)); diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.cs index f4546932eae69f..fec172dab43ecb 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.cs @@ -21,12 +21,14 @@ static CmsSignature() PrepareRegistrationRsa(s_lookup); PrepareRegistrationDsa(s_lookup); PrepareRegistrationECDsa(s_lookup); + PrepareRegistrationMLDsa(s_lookup); PrepareRegistrationSlhDsa(s_lookup); } static partial void PrepareRegistrationRsa(Dictionary lookup); static partial void PrepareRegistrationDsa(Dictionary lookup); static partial void PrepareRegistrationECDsa(Dictionary lookup); + static partial void PrepareRegistrationMLDsa(Dictionary lookup); static partial void PrepareRegistrationSlhDsa(Dictionary lookup); internal abstract RSASignaturePadding? SignaturePadding { get; } diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSigner.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSigner.cs index 8c71bbac1c8267..312e25dc1affc5 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSigner.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSigner.cs @@ -111,6 +111,16 @@ public CmsSigner(SubjectIdentifierType signerIdentifierType, X509Certificate2? c { } +#if NET || NETSTANDARD2_1 + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public +#else + private +#endif + CmsSigner(SubjectIdentifierType signerIdentifierType, X509Certificate2? certificate, MLDsa? privateKey) + : this(signerIdentifierType, certificate, privateKey, signaturePadding: null) + { + } #if NET || NETSTANDARD2_1 [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] @@ -123,6 +133,18 @@ public CmsSigner(SubjectIdentifierType signerIdentifierType, X509Certificate2? c { } +#if NET || NETSTANDARD2_1 + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public +#else + private +#endif + CmsSigner(SubjectIdentifierType signerIdentifierType, X509Certificate2? certificate, CompositeMLDsa? privateKey) + : this(signerIdentifierType, certificate, privateKey, signaturePadding: null) + { + throw new PlatformNotSupportedException(); + } + /// /// Initializes a new instance of the CmsSigner class with a specified signer /// certificate, subject identifier type, private key object, and RSA signature padding. @@ -193,7 +215,7 @@ private CmsSigner( Certificate = certificate; DigestAlgorithm = s_defaultAlgorithm.CopyOid(); - Debug.Assert(privateKey is null or AsymmetricAlgorithm or SlhDsa); + Debug.Assert(privateKey is null or AsymmetricAlgorithm or MLDsa or SlhDsa); _privateKey = (IDisposable?)privateKey; _signaturePadding = signaturePadding; @@ -371,36 +393,8 @@ internal SignerInfoAsn Sign( if (SignerIdentifierType == SubjectIdentifierType.NoSignature) { - // The behavior of this scenario should match Windows which currently does not - // implement PQC. So we do a best effort determination of whether the algorithm - // is a pure algorithm and throw if so. This is subject to change once Windows - // implements PQC. - string? keyAlgorithm = null; - if (Certificate != null) - { - try - { - keyAlgorithm = Certificate.GetKeyAlgorithm(); - } - catch (CryptographicException) - { - } - } - - if (keyAlgorithm != null) - { - CmsSignature? processor = CmsSignature.ResolveAndVerifyKeyType(keyAlgorithm, _privateKey, SignaturePadding); - if (processor?.NeedsHashedMessage == false) - { - throw new CryptographicException(SR.Cryptography_Cms_CertificateDoesNotSupportNoSignature); - } - } - - ReadOnlyMemory messageToSign = - GetMessageToSign(shouldHash: true, data, contentTypeOid, out newSignerInfo.SignedAttributes); - signatureAlgorithm = Oids.NoSignature; - signatureValue = messageToSign; + signatureValue = GetMessageToSign(shouldHash: true, data, contentTypeOid, out newSignerInfo.SignedAttributes); signed = true; } else diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/Certificates.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/Certificates.cs index 1d8c682cdcdd0e..ade7d2cce59345 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/Certificates.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/Certificates.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.Generic; using System.Linq; using System.Security.Cryptography.SLHDsa.Tests; +using System.Security.Cryptography.Tests; using Test.Cryptography; namespace System.Security.Cryptography.Pkcs.Tests @@ -35,12 +37,14 @@ internal static class Certificates public static readonly CertLoader RsaOaep2048_Sha256Parameters = new CertLoaderFromRawData(RawData.RsaOaep2048_Sha256ParametersCert, RawData.RsaOaep2048_Sha256ParametersPfx, "1111"); public static readonly CertLoader RsaOaep2048_NoParameters = new CertLoaderFromRawData(RawData.RsaOaep2048_NoParametersCert, RawData.RsaOaep2048_NoParametersPfx, "1111"); public static readonly CertLoader SlhDsaSha2_128s_Ietf = new CertLoaderFromRawData(SlhDsaTestData.IetfSlhDsaSha2_128sCertificate, SlhDsaTestData.IetfSlhDsaSha2_128sCertificatePfx, "PLACEHOLDER"); - public static readonly CertLoader[] SlhDsaGeneratedCerts = LoadSlhDsaCerts(); + public static readonly CertLoader[] SlhDsaGeneratedCerts = [..SlhDsaTestData.GeneratedKeyInfosRaw.Select(info => new CertLoaderFromRawData(info.Certificate, info.SelfSignedCertificatePfx, info.EncryptionPassword))]; - private static CertLoader[] LoadSlhDsaCerts() => - SlhDsaTestData.GeneratedKeyInfosRaw - .Select(info => new CertLoaderFromRawData(info.Certificate, info.SelfSignedCertificatePfx, info.EncryptionPassword)) - .ToArray(); + public static readonly Dictionary MLDsaIetf = new() + { + { MLDsaAlgorithm.MLDsa44, new CertLoaderFromRawData(MLDsaTestsData.IetfMLDsa44.Certificate, MLDsaTestsData.IetfMLDsa44.Pfx_Seed, "PLACEHOLDER") }, + { MLDsaAlgorithm.MLDsa65, new CertLoaderFromRawData(MLDsaTestsData.IetfMLDsa65.Certificate, MLDsaTestsData.IetfMLDsa65.Pfx_Seed, "PLACEHOLDER") }, + { MLDsaAlgorithm.MLDsa87, new CertLoaderFromRawData(MLDsaTestsData.IetfMLDsa87.Certificate, MLDsaTestsData.IetfMLDsa87.Pfx_Seed, "PLACEHOLDER") }, + }; // Note: the raw data is its own (nested) class to avoid problems with static field initialization ordering. private static class RawData diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs8PrivateKeyInfoTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs8PrivateKeyInfoTests.cs index d688ac3a9c97d7..c1e21e5f86ee6d 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs8PrivateKeyInfoTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs8PrivateKeyInfoTests.cs @@ -334,7 +334,7 @@ public static void NullAlgorithm() [InlineData("0....0")] [InlineData("0.0...0")] [InlineData("potato")] - public static void InvalidAlgorithmId(string oidValue) + public static void InvalidAlgorithmId(string? oidValue) { Pkcs8PrivateKeyInfo info = new Pkcs8PrivateKeyInfo( new Oid(oidValue, "friendly name"), diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/Rfc3161/TimestampTokenTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/Rfc3161/TimestampTokenTests.cs index 7c570de2ca6c7b..f0a1161992f9b0 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/Rfc3161/TimestampTokenTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/Rfc3161/TimestampTokenTests.cs @@ -341,7 +341,7 @@ public static void CertMismatchIssuerAndSerialV1( public static void MatchV2( X509IncludeOption includeOption, SigningCertificateOption v2Option, - string hashAlgName) + string? hashAlgName) { CustomBuild_CertMatch( Certificates.ValidLookingTsaCert, @@ -361,7 +361,7 @@ public static void MatchV2( [InlineData(X509IncludeOption.None, "SHA1")] [InlineData(X509IncludeOption.WholeChain, "SHA384")] [InlineData(X509IncludeOption.None, "SHA384")] - public static void CertHashMismatchV2(X509IncludeOption includeOption, string hashAlgName) + public static void CertHashMismatchV2(X509IncludeOption includeOption, string? hashAlgName) { CustomBuild_CertMismatch( Certificates.ValidLookingTsaCert, @@ -417,7 +417,7 @@ public static void CertMismatchIssuerAndSerialV2( X509IncludeOption includeOption, SigningCertificateOption v2Option, SubjectIdentifierType identifierType, - string hashAlgName) + string? hashAlgName) { CustomBuild_CertMismatch( Certificates.ValidLookingTsaCert, @@ -514,7 +514,7 @@ public static void CertMatchV1AndV2( X509IncludeOption includeOption, SigningCertificateOption v1Option, SigningCertificateOption v2Option, - string hashAlgName) + string? hashAlgName) { CustomBuild_CertMatch( Certificates.ValidLookingTsaCert, @@ -561,7 +561,7 @@ public static void CertMismatchV1OrV2( SigningCertificateOption v1Option, SigningCertificateOption v2Option, SubjectIdentifierType identifierType, - string hashAlgName) + string? hashAlgName) { CustomBuild_CertMismatch( Certificates.ValidLookingTsaCert, diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.cs index 0ae8dbd8572be0..59a8be63676579 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.cs @@ -1,11 +1,11 @@ // 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; using System.Collections.Generic; using System.Linq; using System.Runtime.Versioning; using System.Security.Cryptography.SLHDsa.Tests; +using System.Security.Cryptography.Tests; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.Xml; using Test.Cryptography; @@ -15,6 +15,9 @@ namespace System.Security.Cryptography.Pkcs.Tests { public static partial class SignedCmsTests { + // TODO: Windows does not support draft 10 PKCS#8 format yet. Remove this and use MLDsa.IsSupported when it does. + public static bool SupportsDraft10Pkcs8 => MLDsa.IsSupported && !PlatformDetection.IsWindows; + [Fact] public static void DefaultStateBehavior() { @@ -461,47 +464,19 @@ public static void SignNoisyWithNoCertificate_NotSupported( [InlineData(SubjectIdentifierType.SubjectKeyIdentifier, true)] public static void AddFirstSigner_RSA(SubjectIdentifierType identifierType, bool detached) { - ContentInfo contentInfo = new ContentInfo(new byte[] { 9, 8, 7, 6, 5 }); - SignedCms cms = new SignedCms(contentInfo, detached); - - using (X509Certificate2 signerCert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey()) - { - CmsSigner signer = new CmsSigner(identifierType, signerCert); - cms.ComputeSignature(signer); - } - - Assert.Same(contentInfo.Content, cms.ContentInfo.Content); - Assert.Single(cms.SignerInfos); - Assert.Single(cms.Certificates); - - int expectedVersion = identifierType == SubjectIdentifierType.SubjectKeyIdentifier ? 3 : 1; - Assert.Equal(expectedVersion, cms.Version); - - SignerInfo firstSigner = cms.SignerInfos[0]; - Assert.Equal(identifierType, firstSigner.SignerIdentifier.Type); - Assert.NotNull(firstSigner.Certificate); - Assert.NotSame(cms.Certificates[0], firstSigner.Certificate); - Assert.Equal(cms.Certificates[0], firstSigner.Certificate); - - cms.CheckSignature(true); - byte[] encoded = cms.Encode(); - - cms = new SignedCms(); - cms.Decode(encoded); - Assert.Single(cms.SignerInfos); - Assert.Single(cms.Certificates); - Assert.Equal(expectedVersion, cms.Version); - Assert.Equal(identifierType, cms.SignerInfos[0].SignerIdentifier.Type); - Assert.Equal(firstSigner.Certificate, cms.SignerInfos[0].Certificate); - - if (detached) - { - Assert.Throws(() => cms.CheckSignature(true)); - cms = new SignedCms(contentInfo, detached); - cms.Decode(encoded); - } - - cms.CheckSignature(true); + AssertAddFirstSigner( + identifierType, + detached, + cms => + { + using (X509Certificate2 signerCert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey()) + { + CmsSigner signer = new CmsSigner(identifierType, signerCert); + cms.ComputeSignature(signer); + } + }, + firstSigner => { /* No additional asserts */ }, + roundtrippedFirstSigner => { /* No additional asserts */ }); } [Fact] @@ -542,62 +517,41 @@ public static void AddSignerWithNegativeSerial() [SkipOnPlatform(PlatformSupport.MobileAppleCrypto, "DSA is not available")] public static void AddFirstSigner_DSA(SubjectIdentifierType identifierType, bool detached) { - ContentInfo contentInfo = new ContentInfo(new byte[] { 9, 8, 7, 6, 5 }); - SignedCms cms = new SignedCms(contentInfo, detached); - - using (X509Certificate2 signerCert = Certificates.Dsa1024.TryGetCertificateWithPrivateKey()) - { - CmsSigner signer = new CmsSigner(identifierType, signerCert); - signer.IncludeOption = X509IncludeOption.EndCertOnly; - // Best compatibility for DSA is SHA-1 (FIPS 186-2) - signer.DigestAlgorithm = new Oid(Oids.Sha1, Oids.Sha1); - cms.ComputeSignature(signer); - } - - Assert.Single(cms.SignerInfos); - Assert.Single(cms.Certificates); - - int expectedVersion = identifierType == SubjectIdentifierType.SubjectKeyIdentifier ? 3 : 1; - Assert.Equal(expectedVersion, cms.Version); - - SignerInfo firstSigner = cms.SignerInfos[0]; - Assert.Equal(identifierType, firstSigner.SignerIdentifier.Type); - Assert.NotNull(firstSigner.Certificate); - Assert.NotSame(cms.Certificates[0], firstSigner.Certificate); - Assert.Equal(cms.Certificates[0], firstSigner.Certificate); - #if NET - byte[] signature = firstSigner.GetSignature(); - Assert.NotEmpty(signature); - // DSA PKIX signature format is a DER SEQUENCE. - Assert.Equal(0x30, signature[0]); + byte[]? signature = null; #endif - cms.CheckSignature(true); - byte[] encoded = cms.Encode(); - - cms = new SignedCms(); - cms.Decode(encoded); - - Assert.Single(cms.SignerInfos); - Assert.Single(cms.Certificates); - Assert.Equal(expectedVersion, cms.Version); - Assert.Equal(identifierType, cms.SignerInfos[0].SignerIdentifier.Type); - Assert.Equal(firstSigner.Certificate, cms.SignerInfos[0].Certificate); - + AssertAddFirstSigner( + identifierType, + detached, + cms => + { + using (X509Certificate2 signerCert = Certificates.Dsa1024.TryGetCertificateWithPrivateKey()) + { + CmsSigner signer = new CmsSigner(identifierType, signerCert); + signer.IncludeOption = X509IncludeOption.EndCertOnly; + // Best compatibility for DSA is SHA-1 (FIPS 186-2) + signer.DigestAlgorithm = new Oid(Oids.Sha1, Oids.Sha1); + cms.ComputeSignature(signer); + } + }, + firstSigner => + { #if NET - byte[] sig2 = cms.SignerInfos[0].GetSignature(); - Assert.Equal(signature, sig2); + // Store signature for comparison after roundtrip. + signature = firstSigner.GetSignature(); + Assert.NotEmpty(signature); + // DSA PKIX signature format is a DER SEQUENCE. + Assert.Equal(0x30, signature[0]); #endif - - if (detached) - { - Assert.Throws(() => cms.CheckSignature(true)); - cms = new SignedCms(contentInfo, detached); - cms.Decode(encoded); - } - - cms.CheckSignature(true); + }, + roundtrippedFirstSigner => + { +#if NET + byte[] sig2 = roundtrippedFirstSigner.GetSignature(); + Assert.Equal(signature, sig2); +#endif + }); } [Theory] @@ -614,64 +568,43 @@ public static void AddFirstSigner_DSA(SubjectIdentifierType identifierType, bool [InlineData(SubjectIdentifierType.SubjectKeyIdentifier, true, Oids.Sha512)] public static void AddFirstSigner_ECDSA(SubjectIdentifierType identifierType, bool detached, string digestOid) { - ContentInfo contentInfo = new ContentInfo(new byte[] { 9, 8, 7, 6, 5 }); - SignedCms cms = new SignedCms(contentInfo, detached); - - using (X509Certificate2 signerCert = Certificates.ECDsaP256Win.TryGetCertificateWithPrivateKey()) - { - CmsSigner signer = new CmsSigner(identifierType, signerCert); - signer.IncludeOption = X509IncludeOption.EndCertOnly; - signer.DigestAlgorithm = new Oid(digestOid, digestOid); - cms.ComputeSignature(signer); - } - - Assert.Single(cms.SignerInfos); - Assert.Single(cms.Certificates); - - int expectedVersion = identifierType == SubjectIdentifierType.SubjectKeyIdentifier ? 3 : 1; - Assert.Equal(expectedVersion, cms.Version); - - SignerInfo firstSigner = cms.SignerInfos[0]; - Assert.Equal(identifierType, firstSigner.SignerIdentifier.Type); - Assert.NotNull(firstSigner.Certificate); - Assert.NotSame(cms.Certificates[0], firstSigner.Certificate); - Assert.Equal(cms.Certificates[0], firstSigner.Certificate); - #if NET - byte[] signature = firstSigner.GetSignature(); - Assert.NotEmpty(signature); - // ECDSA PKIX signature format is a DER SEQUENCE. - Assert.Equal(0x30, signature[0]); - - // ECDSA Oids are all under 1.2.840.10045.4. - Assert.StartsWith("1.2.840.10045.4.", firstSigner.SignatureAlgorithm.Value); + byte[]? signature = null; #endif - cms.CheckSignature(true); - byte[] encoded = cms.Encode(); - - cms = new SignedCms(); - cms.Decode(encoded); - - Assert.Single(cms.SignerInfos); - Assert.Single(cms.Certificates); - Assert.Equal(expectedVersion, cms.Version); - Assert.Equal(identifierType, cms.SignerInfos[0].SignerIdentifier.Type); - Assert.Equal(firstSigner.Certificate, cms.SignerInfos[0].Certificate); - + AssertAddFirstSigner( + identifierType, + detached, + cms => + { + using (X509Certificate2 signerCert = Certificates.ECDsaP256Win.TryGetCertificateWithPrivateKey()) + { + CmsSigner signer = new CmsSigner(identifierType, signerCert); + signer.IncludeOption = X509IncludeOption.EndCertOnly; + signer.DigestAlgorithm = new Oid(digestOid, digestOid); + cms.ComputeSignature(signer); + } + }, + firstSigner => + { #if NET - byte[] sig2 = cms.SignerInfos[0].GetSignature(); - Assert.Equal(signature, sig2); + // Store signature for comparison after roundtrip. + signature = firstSigner.GetSignature(); + Assert.NotEmpty(signature); + // ECDSA PKIX signature format is a DER SEQUENCE. + Assert.Equal(0x30, signature[0]); + + // ECDSA Oids are all under 1.2.840.10045.4. + Assert.StartsWith("1.2.840.10045.4.", firstSigner.SignatureAlgorithm.Value); #endif - - if (detached) - { - Assert.Throws(() => cms.CheckSignature(true)); - cms = new SignedCms(contentInfo, detached); - cms.Decode(encoded); - } - - cms.CheckSignature(true); + }, + roundtrippedFirstSigner => + { +#if NET + byte[] sig2 = roundtrippedFirstSigner.GetSignature(); + Assert.Equal(signature, sig2); +#endif + }); } public static IEnumerable AddFirstSignerSlhDsaTestData => @@ -692,19 +625,102 @@ from SlhDsaTestData.SlhDsaGeneratedKeyInfo info in SlhDsaTestData.GeneratedKeyIn [MemberData(nameof(AddFirstSignerSlhDsaTestData))] public static void AddFirstSigner_SlhDsa(SubjectIdentifierType identifierType, bool detached, string digestOid, SlhDsaTestData.SlhDsaGeneratedKeyInfo info) { - ContentInfo contentInfo = new ContentInfo(new byte[] { 9, 8, 7, 6, 5 }); - SignedCms cms = new SignedCms(contentInfo, detached); + byte[]? signature = null; - CertLoader loader = Certificates.SlhDsaGeneratedCerts.Single(cert => cert.CerData.SequenceEqual(info.Certificate)); - using (X509Certificate2 signerCert = loader.TryGetCertificateWithPrivateKey()) + AssertAddFirstSigner( + identifierType, + detached, + cms => + { + CertLoader loader = Certificates.SlhDsaGeneratedCerts.Single(cert => cert.CerData.SequenceEqual(info.Certificate)); + using (X509Certificate2 signerCert = loader.TryGetCertificateWithPrivateKey()) + { + CmsSigner signer = new CmsSigner(identifierType, signerCert); + signer.IncludeOption = X509IncludeOption.EndCertOnly; + signer.DigestAlgorithm = new Oid(digestOid, digestOid); + cms.ComputeSignature(signer); + } + }, + firstSigner => + { + // Store signature for comparison after roundtrip. + signature = firstSigner.GetSignature(); + Assert.NotEmpty(signature); + + // SLH-DSA Oids are all under 2.16.840.1.101.3.4.3. + Assert.StartsWith("2.16.840.1.101.3.4.3.", firstSigner.SignatureAlgorithm.Value); + }, + roundtrippedFirstSigner => + { + byte[] sig2 = roundtrippedFirstSigner.GetSignature(); + Assert.Equal(signature, sig2); + }); + } + + public static IEnumerable AddFirstSignerMLDsaTestData => + from sit in new[] { SubjectIdentifierType.IssuerAndSerialNumber, SubjectIdentifierType.SubjectKeyIdentifier } + from detached in new[] { false, true } + from data in new (MLDsaAlgorithm algorithm, string hashAlgorithm)[] { - CmsSigner signer = new CmsSigner(identifierType, signerCert); - signer.IncludeOption = X509IncludeOption.EndCertOnly; - signer.DigestAlgorithm = new Oid(digestOid, digestOid); - cms.ComputeSignature(signer); + (MLDsaAlgorithm.MLDsa44, Oids.Shake128), + (MLDsaAlgorithm.MLDsa65, Oids.Sha512), + (MLDsaAlgorithm.MLDsa87, Oids.Shake256), } + select new object[] { sit, detached, data.hashAlgorithm, data.algorithm }; + + [ConditionalTheory(nameof(SupportsDraft10Pkcs8))] + [MemberData(nameof(AddFirstSignerMLDsaTestData))] + public static void AddFirstSigner_MLDsa(SubjectIdentifierType identifierType, bool detached, string digestOid, MLDsaAlgorithm algorithm) + { + byte[]? signature = null; + + AssertAddFirstSigner( + identifierType, + detached, + cms => + { + using (X509Certificate2 signerCert = Certificates.MLDsaIetf[algorithm].TryGetCertificateWithPrivateKey()) + { + CmsSigner signer = new CmsSigner(identifierType, signerCert); + signer.IncludeOption = X509IncludeOption.EndCertOnly; + signer.DigestAlgorithm = new Oid(digestOid, digestOid); + cms.ComputeSignature(signer); + } + }, + firstSigner => + { + // Store signature for comparison after roundtrip. + signature = firstSigner.GetSignature(); + Assert.NotEmpty(signature); + + // ML-DSA Oids are all under 2.16.840.1.101.3.4.3. + Assert.StartsWith("2.16.840.1.101.3.4.3.", firstSigner.SignatureAlgorithm.Value); + }, + roundtrippedFirstSigner => + { + byte[] sig2 = roundtrippedFirstSigner.GetSignature(); + Assert.Equal(signature, sig2); + }); + } + + private static void AssertAddFirstSigner( + SubjectIdentifierType identifierType, + bool detached, + Action signCms, + Action assertFirstSigner, + Action assertRoundtrippedFirstSigner) + { + ContentInfo contentInfo = new ContentInfo(new byte[] { 9, 8, 7, 6, 5 }); + SignedCms cms = new SignedCms(contentInfo, detached); + signCms(cms); + + Assert.Same(contentInfo.Content, cms.ContentInfo.Content); Assert.Single(cms.SignerInfos); + + // Currently the test assumes only a single certificate is added. + // If this assertion fails in newly added tests, update the provided signing + // callback to use EndCertOnly. Assert.Single(cms.Certificates); int expectedVersion = identifierType == SubjectIdentifierType.SubjectKeyIdentifier ? 3 : 1; @@ -716,11 +732,7 @@ public static void AddFirstSigner_SlhDsa(SubjectIdentifierType identifierType, b Assert.NotSame(cms.Certificates[0], firstSigner.Certificate); Assert.Equal(cms.Certificates[0], firstSigner.Certificate); - byte[] signature = firstSigner.GetSignature(); - Assert.NotEmpty(signature); - - // SLH-DSA Oids are all under 2.16.840.1.101.3.4.3. - Assert.StartsWith("2.16.840.1.101.3.4.3.", firstSigner.SignatureAlgorithm.Value); + assertFirstSigner(firstSigner); cms.CheckSignature(true); byte[] encoded = cms.Encode(); @@ -734,8 +746,7 @@ public static void AddFirstSigner_SlhDsa(SubjectIdentifierType identifierType, b Assert.Equal(identifierType, cms.SignerInfos[0].SignerIdentifier.Type); Assert.Equal(firstSigner.Certificate, cms.SignerInfos[0].Certificate); - byte[] sig2 = cms.SignerInfos[0].GetSignature(); - Assert.Equal(signature, sig2); + assertRoundtrippedFirstSigner(cms.SignerInfos[0]); if (detached) { @@ -1490,7 +1501,7 @@ public static void CheckSignature_Pkcs1_Sha1_Declared_Sha256WithRsa() [InlineData(" 1.1", "010100", null)] [InlineData("1.1 ", "010100", null)] [InlineData("1 1", "010100", null)] - public static void SignIdentifiedContent_BadOid(string oidValueIn, string contentHex, string oidValueOut) + public static void SignIdentifiedContent_BadOid(string? oidValueIn, string contentHex, string? oidValueOut) { SignedCms signedCms = new SignedCms( new ContentInfo(new Oid(oidValueIn, "Some Friendly Name"), contentHex.HexToByteArray())); @@ -1688,21 +1699,6 @@ public static void Decode_CanDecodeWithAttributeCertificate() cms.CheckSignature(verifySignatureOnly: true); } - [ConditionalFact(typeof(SlhDsa), nameof(SlhDsa.IsSupported))] - public static void ComputeSignature_SlhDsa_NoSignature() - { - ContentInfo contentInfo = new ContentInfo(new byte[] { 9, 8, 7, 6, 5 }); - SignedCms cms = new SignedCms(contentInfo, false); - using (X509Certificate2 cert = Certificates.SlhDsaSha2_128s_Ietf.GetCertificate()) - { - CmsSigner cmsSigner = new CmsSigner(SubjectIdentifierType.NoSignature, cert); - - AssertExtensions.ThrowsContains( - () => cms.ComputeSignature(cmsSigner), - "SignatureIdentifierType.NoSignature is not valid with the provided certificate."); - } - } - // Ed25519 certificate from https://datatracker.ietf.org/doc/html/rfc8410#section-10.2 private const string UnknownAlgorithmCert = """ @@ -1748,11 +1744,26 @@ public static void ComputeSignature_UnknownAlgorithm_NoSignature() } [Fact] - public static void ComputeSignature_NoSignature_DefaultDigest() + public static void ComputeSignature_Rsa_NoSignature_DefaultDigest() { - // A certificate shouldn't really be required here, but on .NET Framework - // it will encounter throw a NullReferenceException. - using X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.GetCertificate(); + ComputeSignature_NoSignature_DefaultDigest(Certificates.RSAKeyTransferCapi1.GetCertificate); + } + + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + public static void ComputeSignature_MLDsa_NoSignature_DefaultDigest() + { + ComputeSignature_NoSignature_DefaultDigest(Certificates.MLDsaIetf[MLDsaAlgorithm.MLDsa65].GetCertificate); + } + + [ConditionalFact(typeof(SlhDsa), nameof(SlhDsa.IsSupported))] + public static void ComputeSignature_SlhDsa_NoSignature_DefaultDigest() + { + ComputeSignature_NoSignature_DefaultDigest(Certificates.SlhDsaSha2_128s_Ietf.GetCertificate); + } + + private static void ComputeSignature_NoSignature_DefaultDigest(Func getCert) + { + using X509Certificate2 cert = getCert(); byte[] message = "Hello World!"u8.ToArray(); SignedCms cms = new SignedCms(new ContentInfo(message)); @@ -1762,8 +1773,7 @@ public static void ComputeSignature_NoSignature_DefaultDigest() cms.ComputeSignature(signer); - FrameworkName fwkName = new FrameworkName(AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName); - bool defaultHashIsSha1 = PlatformDetection.IsNetFramework && fwkName.Version <= new Version(4, 7, 0); + bool defaultHashIsSha1 = IsNetFramework471OrLower; byte[] expectedMessageHash = Convert.FromBase64String( defaultHashIsSha1 ? "Lve95gjOVATpfV8EL5X4nxwjKHE=" // Sha1 @@ -1791,5 +1801,105 @@ private static void CheckNoSignature(byte[] encoded, bool badOid=false) cms.CheckHash(); } } + + [ConditionalFact(nameof(SupportsDraft10Pkcs8))] + public static void ComputeSignature_MLDsa_DefaultDigest() + { +#if !NETFRAMEWORK + // Test signer with public certificate and private key + AssertSignerHasCorrectDefaultDigest( + useSigner => + { + using (X509Certificate2 cert = Certificates.MLDsaIetf[MLDsaAlgorithm.MLDsa65].GetCertificate()) + using (MLDsa key = MLDsa.ImportMLDsaPrivateSeed(MLDsaAlgorithm.MLDsa65, MLDsaTestsData.IetfMLDsa65.PrivateSeed)) + { + useSigner(new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, cert, key)); + } + }); + + // Test signer with private certificate + AssertSignerHasCorrectDefaultDigest( + useSigner => + { + using (X509Certificate2 cert = Certificates.MLDsaIetf[MLDsaAlgorithm.MLDsa65].TryGetCertificateWithPrivateKey()) + { + useSigner(new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, cert, (MLDsa?)null)); + } + }); +#endif + + // Test signer with private certificate + AssertSignerHasCorrectDefaultDigest( + useSigner => + { + using (X509Certificate2 cert = Certificates.MLDsaIetf[MLDsaAlgorithm.MLDsa65].TryGetCertificateWithPrivateKey()) + { + useSigner(new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, cert)); + } + }); + } + + [ConditionalFact(typeof(SlhDsa), nameof(SlhDsa.IsSupported))] + public static void ComputeSignature_SlhDsa_DefaultDigest() + { +#if !NETFRAMEWORK + // Test signer with public certificate and private key + AssertSignerHasCorrectDefaultDigest( + useSigner => + { + using (X509Certificate2 cert = Certificates.SlhDsaSha2_128s_Ietf.GetCertificate()) + using (SlhDsa key = SlhDsa.ImportSlhDsaPrivateKey(SlhDsaAlgorithm.SlhDsaSha2_128s, SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue)) + { + useSigner(new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, cert, key)); + } + }); + + // Test signer with private certificate + AssertSignerHasCorrectDefaultDigest( + useSigner => + { + using (X509Certificate2 cert = Certificates.SlhDsaSha2_128s_Ietf.TryGetCertificateWithPrivateKey()) + { + useSigner(new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, cert, (SlhDsa?)null)); + } + }); +#endif + + // Test signer with private certificate + AssertSignerHasCorrectDefaultDigest( + useSigner => + { + using (X509Certificate2 cert = Certificates.SlhDsaSha2_128s_Ietf.TryGetCertificateWithPrivateKey()) + { + useSigner(new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, cert)); + } + }); + } + + private static void AssertSignerHasCorrectDefaultDigest(Action> test) + { + // DigestAlgorithm property on new signer has correct default value + test(static signer => Assert.Equal(DefaultHashForPlatform.Value, signer.DigestAlgorithm.Value)); + + // Signer signs with correct digest value + test( + static signer => + { + byte[] message = "Hello World!"u8.ToArray(); + SignedCms cms = new SignedCms(new ContentInfo(message)); + + cms.ComputeSignature(signer); + + Assert.Equal(DefaultHashForPlatform.Value, cms.SignerInfos[0].DigestAlgorithm.Value); + + // Assert.NoThrow + cms.SignerInfos[0].CheckSignature(verifySignatureOnly: true); + }); + } + + private static bool IsNetFramework471OrLower { get; } = + PlatformDetection.IsNetFramework && new FrameworkName(AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName).Version <= new Version(4, 7, 1); + + private static Oid DefaultHashForPlatform = IsNetFramework471OrLower ? new Oid(Oids.Sha1, Oids.Sha1) : new Oid(Oids.Sha256, Oids.Sha256); } } diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.netcoreapp.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.netcoreapp.cs index faa41a19c7cb8b..b1a9683c401d58 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.netcoreapp.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.netcoreapp.cs @@ -5,9 +5,8 @@ using System.Formats.Asn1; using System.Linq; using System.Security.Cryptography.SLHDsa.Tests; +using System.Security.Cryptography.Tests; using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Text.Unicode; using Test.Cryptography; using Xunit; @@ -104,6 +103,16 @@ public static void SignCmsUsingExplicitECDsaP521Key() } } + [ConditionalFact(nameof(SupportsDraft10Pkcs8))] + public static void SignCmsUsingExplicitMLDsaKey() + { + using (X509Certificate2 cert = Certificates.MLDsaIetf[MLDsaAlgorithm.MLDsa65].TryGetCertificateWithPrivateKey()) + using (MLDsa key = cert.GetMLDsaPrivateKey()) + { + VerifyWithExplicitPrivateKey(cert, key); + } + } + [ConditionalFact(typeof(SlhDsa), nameof(SlhDsa.IsSupported))] public static void SignCmsUsingExplicitSlhDsaKey() { @@ -152,6 +161,30 @@ public static void CounterSignCmsUsingExplicitECDsaKeyForFirstSignerAndRSAForCou } } + [ConditionalFact(nameof(SupportsDraft10Pkcs8))] + public static void CounterSignCmsUsingExplicitECDsaKeyForFirstSignerAndMLDsaForCounterSignature() + { + using (X509Certificate2 cert = Certificates.ECDsaP256Win.TryGetCertificateWithPrivateKey()) + using (ECDsa key = cert.GetECDsaPrivateKey()) + using (X509Certificate2 counterSignerCert = Certificates.MLDsaIetf[MLDsaAlgorithm.MLDsa65].TryGetCertificateWithPrivateKey()) + using (MLDsa counterSignerKey = counterSignerCert.GetMLDsaPrivateKey()) + { + VerifyCounterSignatureWithExplicitPrivateKey(cert, key, counterSignerCert, counterSignerKey); + } + } + + [ConditionalFact(nameof(SupportsDraft10Pkcs8))] + public static void CounterSignCmsUsingExplicitMLDsaKeyForFirstSignerAndRSAForCounterSignature() + { + using (X509Certificate2 cert = Certificates.MLDsaIetf[MLDsaAlgorithm.MLDsa65].TryGetCertificateWithPrivateKey()) + using (MLDsa key = cert.GetMLDsaPrivateKey()) + using (X509Certificate2 counterSignerCert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey()) + using (RSA counterSignerKey = counterSignerCert.GetRSAPrivateKey()) + { + VerifyCounterSignatureWithExplicitPrivateKey(cert, key, counterSignerCert, counterSignerKey); + } + } + [ConditionalFact(typeof(SlhDsa), nameof(SlhDsa.IsSupported))] public static void CounterSignCmsUsingExplicitECDsaKeyForFirstSignerAndSlhDsaForCounterSignature() { @@ -226,6 +259,38 @@ public static void SignCmsUsingEDCSaCertAndRSAaKeyThrows() } } + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + public static void SignCmsUsingECDsaCertAndMLDsaKeyThrows() + { + byte[] content = { 9, 8, 7, 6, 5 }; + + ContentInfo contentInfo = new ContentInfo(content); + SignedCms cms = new SignedCms(contentInfo, detached: false); + + using (X509Certificate2 cert = Certificates.ECDsaP256Win.GetCertificate()) + using (MLDsa key = MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa65)) + { + CmsSigner signer = new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, cert, key); + Assert.Throws(() => cms.ComputeSignature(signer)); + } + } + + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + public static void SignCmsUsingMLDsaCertAndRSAKeyThrows() + { + byte[] content = { 9, 8, 7, 6, 5 }; + + ContentInfo contentInfo = new ContentInfo(content); + SignedCms cms = new SignedCms(contentInfo, detached: false); + + using (X509Certificate2 cert = Certificates.MLDsaIetf[MLDsaAlgorithm.MLDsa65].GetCertificate()) + using (RSA key = RSA.Create()) + { + CmsSigner signer = new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, cert, key); + Assert.Throws(() => cms.ComputeSignature(signer)); + } + } + [ConditionalFact(typeof(SlhDsa), nameof(SlhDsa.IsSupported))] public static void SignCmsUsingECDsaCertAndSlhDsaKeyThrows() { @@ -309,6 +374,22 @@ public static void SignCmsUsingECDsaCertWithNotMatchingKeyThrows() } } + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + public static void SignCmsUsingMLDsaCertWithNotMatchingKeyThrows() + { + byte[] content = { 9, 8, 7, 6, 5 }; + + ContentInfo contentInfo = new ContentInfo(content); + SignedCms cms = new SignedCms(contentInfo, detached: false); + + using (X509Certificate2 cert = Certificates.MLDsaIetf[MLDsaAlgorithm.MLDsa65].GetCertificate()) + using (MLDsa key = MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa65)) + { + CmsSigner signer = new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, cert, key); + Assert.Throws(() => cms.ComputeSignature(signer)); + } + } + [ConditionalFact(typeof(SlhDsa), nameof(SlhDsa.IsSupported))] public static void SignCmsUsingSlhDsaCertWithNotMatchingKeyThrows() { @@ -556,23 +637,37 @@ public static void AddSigner_ECDSA_EphemeralKey() } } + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + public static void AddSigner_MLDsa_EphemeralKey() + { + using (MLDsa MLDsa = MLDsa.ImportMLDsaPrivateSeed(MLDsaAlgorithm.MLDsa65, MLDsaTestsData.IetfMLDsa65.PrivateSeed)) + using (X509Certificate2 publicCertificate = Certificates.MLDsaIetf[MLDsaAlgorithm.MLDsa65].GetCertificate()) + using (X509Certificate2 certWithEphemeralKey = publicCertificate.CopyWithPrivateKey(MLDsa)) + { + ContentInfo content = new ContentInfo(new byte[] { 1, 2, 3 }); + SignedCms cms = new SignedCms(content, false); + CmsSigner signer = new CmsSigner(certWithEphemeralKey) + { + IncludeOption = X509IncludeOption.EndCertOnly + }; + cms.ComputeSignature(signer); + } + } + [ConditionalFact(typeof(SlhDsa), nameof(SlhDsa.IsSupported))] public static void AddSigner_SlhDsa_EphemeralKey() { - using (SlhDsa slhDsa = SlhDsa.ImportSlhDsaSecretKey(SlhDsaAlgorithm.SlhDsaSha2_128s, SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue)) + using (SlhDsa slhDsa = SlhDsa.ImportSlhDsaPrivateKey(SlhDsaAlgorithm.SlhDsaSha2_128s, SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue)) using (X509Certificate2 publicCertificate = Certificates.SlhDsaSha2_128s_Ietf.GetCertificate()) - using (X509Certificate2 certificateWithKey = Certificates.SlhDsaSha2_128s_Ietf.TryGetCertificateWithPrivateKey(exportable: true)) + using (X509Certificate2 certWithEphemeralKey = publicCertificate.CopyWithPrivateKey(slhDsa)) { - using (X509Certificate2 certWithEphemeralKey = publicCertificate.CopyWithPrivateKey(slhDsa)) + ContentInfo content = new ContentInfo(new byte[] { 1, 2, 3 }); + SignedCms cms = new SignedCms(content, false); + CmsSigner signer = new CmsSigner(certWithEphemeralKey) { - ContentInfo content = new ContentInfo(new byte[] { 1, 2, 3 }); - SignedCms cms = new SignedCms(content, false); - CmsSigner signer = new CmsSigner(certWithEphemeralKey) - { - IncludeOption = X509IncludeOption.EndCertOnly - }; - cms.ComputeSignature(signer); - } + IncludeOption = X509IncludeOption.EndCertOnly + }; + cms.ComputeSignature(signer); } } @@ -717,6 +812,40 @@ public static void CreateSignature_Ecdsa_ThrowsWithRsaSignaturePadding() } } + [ConditionalFact(nameof(SupportsDraft10Pkcs8))] + public static void CreateSignature_MLDsa_ThrowsWithRsaSignaturePadding() + { + ContentInfo content = new ContentInfo(new byte[] { 1, 2, 3 }); + SignedCms cms = new SignedCms(content); + + using (X509Certificate2 cert = Certificates.MLDsaIetf[MLDsaAlgorithm.MLDsa65].TryGetCertificateWithPrivateKey()) + { + CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, cert, null, RSASignaturePadding.Pss); + Assert.ThrowsAny(() => cms.ComputeSignature(signer)); + } + } + + [ConditionalTheory(typeof(MLDsa), nameof(MLDsa.IsSupported))] + [InlineData(Oids.RsaPkcs1Sha256)] + public static void ComputeSignature_MLDsa_ThrowsWithUnsupportedHash(string hashAlgorithm) + { + ContentInfo content = new ContentInfo(new byte[] { 1, 2, 3 }); + SignedCms cms = new SignedCms(content); + + MLDsa MLDsa = + MLDsa.ImportMLDsaPrivateSeed( + MLDsaAlgorithm.MLDsa65, + MLDsaTestsData.IetfMLDsa65.PrivateSeed); + + using (MLDsa) + using (X509Certificate2 cert = Certificates.MLDsaIetf[MLDsaAlgorithm.MLDsa65].GetCertificate()) + { + CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, cert); + signer.DigestAlgorithm = new Oid(hashAlgorithm, null); + Assert.Throws(() => cms.ComputeSignature(signer)); + } + } + [ConditionalFact(typeof(SlhDsa), nameof(SlhDsa.IsSupported))] public static void CreateSignature_SlhDsa_ThrowsWithRsaSignaturePadding() { @@ -738,7 +867,7 @@ public static void ComputeSignature_SlhDsa_ThrowsWithUnsupportedHash(string hash SignedCms cms = new SignedCms(content); SlhDsa slhDsa = - SlhDsa.ImportSlhDsaSecretKey( + SlhDsa.ImportSlhDsaPrivateKey( SlhDsaAlgorithm.SlhDsaSha2_128s, SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue); @@ -891,6 +1020,33 @@ public static void ComputeSignature_Ecdsa_Sha3_Roundtrip(string hashAlgorithm) } } + [ConditionalTheory(nameof(SupportsDraft10Pkcs8))] + [InlineData(Oids.Sha3_256)] + [InlineData(Oids.Sha3_384)] + [InlineData(Oids.Sha3_512)] + public static void ComputeSignature_MLDsa_Roundtrip(string hashAlgorithm) + { + ContentInfo content = new ContentInfo(new byte[] { 1, 2, 3 }); + SignedCms cms = new SignedCms(content); + byte[] cmsBytes; + + using (X509Certificate2 cert = Certificates.MLDsaIetf[MLDsaAlgorithm.MLDsa65].TryGetCertificateWithPrivateKey()) + { + CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, cert); + signer.DigestAlgorithm = new Oid(hashAlgorithm, null); + + cms.ComputeSignature(signer); + cmsBytes = cms.Encode(); + cms = new SignedCms(); + cms.Decode(cmsBytes); + cms.CheckSignature(true); // Assert.NoThrow + Assert.Single(cms.SignerInfos); + + SignerInfo signerInfo = cms.SignerInfos[0]; + Assert.Equal(hashAlgorithm, signerInfo.DigestAlgorithm.Value); + } + } + [ConditionalTheory(typeof(SlhDsa), nameof(SlhDsa.IsSupported))] [InlineData(Oids.Sha3_256)] [InlineData(Oids.Sha3_384)] @@ -1010,17 +1166,6 @@ public static void ExistingDocument_Ecdsa_Sha256_FromNetFX() Assert.Equal(Oids.EcPublicKey, signerInfo.SignatureAlgorithm.Value); } - private delegate CmsSigner CreateSignerFunc(SubjectIdentifierType sit, X509Certificate2 cert, TKey key); - private static CreateSignerFunc CreateAsymmetricAlgorithmSigner = (sit, cert, key) => - { - return new CmsSigner(sit, cert, key); - }; - - private static CreateSignerFunc CreateSlhDsaSigner = (sit, cert, key) => - { - return new CmsSigner(sit, cert, key); - }; - private static void VerifyWithExplicitPrivateKey(X509Certificate2 cert, object key) { using (var pubCert = new X509Certificate2(cert.RawData)) @@ -1082,6 +1227,7 @@ private static CmsSigner CreateCmsSigner(SubjectIdentifierType sit, X509Certific { AsymmetricAlgorithm asymmetricKey => new CmsSigner(sit, cert, asymmetricKey), SlhDsa slhDsaKey => new CmsSigner(sit, cert, slhDsaKey), + MLDsa mldsaKey => new CmsSigner(sit, cert, mldsaKey), _ => throw new NotSupportedException($"Unsupported key type: {key.GetType().Name}"), }; } diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsWholeDocumentTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsWholeDocumentTests.cs index b1df0a8abaa3fa..f3adf2c9af4cf7 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsWholeDocumentTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsWholeDocumentTests.cs @@ -617,6 +617,116 @@ public static void ReadRsaPkcs1DoubleCounterSigned() cms.CheckHash(); } + [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] + public static void ReadMLDsaDocument() + { + SignedCms cms = new SignedCms(); + cms.Decode(SignedDocuments.MLDsa65_Sha256_SignedDocument); + + Assert.Equal(1, cms.Version); + + ContentInfo contentInfo = cms.ContentInfo; + + Assert.Equal("1.2.840.113549.1.7.1", contentInfo.ContentType.Value); + AssertExtensions.SequenceEqual("Hello World!"u8, contentInfo.Content); + + X509Certificate2Collection certs = cms.Certificates; + Assert.Single(certs); + + X509Certificate2 topLevelCert = certs[0]; + Assert.Equal("LAMPS WG", topLevelCert.GetNameInfo(X509NameType.SimpleName, false)); + + Assert.Equal( + new DateTimeOffset(2020, 2, 3, 4, 32, 10, TimeSpan.Zero), + new DateTimeOffset(topLevelCert.NotBefore)); + + Assert.Equal( + new DateTimeOffset(2040, 1, 29, 4, 32, 10, TimeSpan.Zero), + new DateTimeOffset(topLevelCert.NotAfter)); + + SignerInfoCollection signers = cms.SignerInfos; + Assert.Single(signers); + + SignerInfo signer = signers[0]; + Assert.Equal(1, signer.Version); + Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, signer.SignerIdentifier.Type); + + X509IssuerSerial issuerSerial = (X509IssuerSerial)signer.SignerIdentifier.Value; + Assert.Equal(topLevelCert.IssuerName.Name, issuerSerial.IssuerName); + Assert.Equal("159FFE6F22FD5CC42C524DF6FD5E28D0DE38F34E", issuerSerial.SerialNumber); + Assert.Equal("2.16.840.1.101.3.4.2.1", signer.DigestAlgorithm.Value); +#if NET + Assert.Equal("2.16.840.1.101.3.4.3.18", signer.SignatureAlgorithm.Value); +#endif + + CryptographicAttributeObjectCollection signedAttrs = signer.SignedAttributes; + Assert.Equal(4, signedAttrs.Count); + + Assert.Equal("1.2.840.113549.1.9.3", signedAttrs[0].Oid.Value); + Assert.Equal("1.2.840.113549.1.9.5", signedAttrs[1].Oid.Value); + Assert.Equal("1.2.840.113549.1.9.4", signedAttrs[2].Oid.Value); + Assert.Equal("1.2.840.113549.1.9.15", signedAttrs[3].Oid.Value); + + Assert.Equal(1, signedAttrs[0].Values.Count); + Assert.Equal(1, signedAttrs[1].Values.Count); + Assert.Equal(1, signedAttrs[2].Values.Count); + Assert.Equal(1, signedAttrs[3].Values.Count); + + Pkcs9ContentType contentTypeAttr = (Pkcs9ContentType)signedAttrs[0].Values[0]; + Assert.Equal("1.2.840.113549.1.7.1", contentTypeAttr.ContentType.Value); + + Pkcs9SigningTime signingTimeAttr = (Pkcs9SigningTime)signedAttrs[1].Values[0]; + Assert.Equal( + new DateTimeOffset(2025, 7, 26, 21, 52, 13, TimeSpan.Zero), + new DateTimeOffset(signingTimeAttr.SigningTime)); + + Pkcs9MessageDigest messageDigestAttr = (Pkcs9MessageDigest)signedAttrs[2].Values[0]; + Assert.Equal( + "7F83B1657FF1FC53B92DC18148A1D65DFC2D4B1FA3D677284ADDD200126D9069", + messageDigestAttr.MessageDigest.ByteArrayToHex()); + + Assert.IsType(signedAttrs[3].Values[0]); +#if !NET + Assert.NotSame(signedAttrs[3].Oid, signedAttrs[3].Values[0].Oid); +#endif + Assert.Equal( + "306A300B060960864801650304012A300B0609608648016503040116300B0609" + + "608648016503040102300A06082A864886F70D0307300E06082A864886F70D03" + + "0202020080300D06082A864886F70D0302020140300706052B0E030207300D06" + + "082A864886F70D0302020128", + signedAttrs[3].Values[0].RawData.ByteArrayToHex()); + +#if NET + // Long signature so just check the end + AssertExtensions.TrueExpression( + signer.GetSignature().ByteArrayToHex().EndsWith("0A134051558694BB000000000000000000000C131A20252D")); +#endif + + CryptographicAttributeObjectCollection unsignedAttrs = signer.UnsignedAttributes; + Assert.Empty(unsignedAttrs); + + SignerInfoCollection counterSigners = signer.CounterSignerInfos; + Assert.Empty(counterSigners); + + X509Certificate2 signerCertificate = signer.Certificate; + Assert.Equal( + "CN=LAMPS WG, O=IETF", + signerCertificate.SubjectName.Name); + + // CheckHash always throws for certificate-based signers. + Assert.Throws(() => signer.CheckHash()); + + // Assert.NoThrows + signer.CheckSignature(true); + + // Since there are no NoSignature signers the document CheckHash will succeed. + // Assert.NoThrows + cms.CheckHash(); + + // Assert.NoThrows + cms.CheckSignature(true); + } + [ConditionalFact(typeof(SlhDsa), nameof(SlhDsa.IsSupported))] public static void ReadSlhDsaDocument() { diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs index 1caf361c5b1290..13b828946b6345 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs @@ -1823,6 +1823,175 @@ internal static class SignedDocuments "77A5BF5851350C96F01142696CC1391632CB95C3370220017FD4D9329F00" + "1EC74210CD34CAEE3878B2302602DB7930347E104679734291").HexToByteArray(); + // produced with + // echo -n "Hello World!" | openssl cms -sign -signer ietfcert.pfx -md sha256 -nodetach -outform DER + internal static readonly byte[] MLDsa65_Sha256_SignedDocument = Convert.FromBase64String( + """ + MIIkEAYJKoZIhvcNAQcCoIIkATCCI/0CAQExDTALBglghkgBZQMEAgEwGwYJKoZIhvcNAQcBoA4E + DEhlbGxvIFdvcmxkIaCCFZEwghWNMIIIiqADAgECAhQVn/5vIv1cxCxSTfb9XijQ3jjzTjALBglg + hkgBZQMEAxIwIjENMAsGA1UEChMESUVURjERMA8GA1UEAxMITEFNUFMgV0cwHhcNMjAwMjAzMDQz + MjEwWhcNNDAwMTI5MDQzMjEwWjAiMQ0wCwYDVQQKEwRJRVRGMREwDwYDVQQDEwhMQU1QUyBXRzCC + B7IwCwYJYIZIAWUDBAMSA4IHoQBIaD2Rl44x6z3duLBHNILSuIpfYllJ/Y9YpWHmlr1MJ9BbONuy + 7fAeZk79gb4eqJNojOaKotUcWVj4u8brTonuZ9LAMglU1XISyscin/HW6vA5KL1RUR+NiNhHc2x9 + 4nMNWXjlQQcTFgl4hncRv1U5oL/Ew1DCvlcrrw7i4vsWzP6ggCjZmsSa67dZN93OERzati//POqL + oiM9Hlb7xcWh5ybeY/rdKvAWsRkXf6PZcaLZJ3Fz/OVbZ3Ra8LfCHVl9vrk+ajLzQcSaWovp6CUI + jR8qpFFV1siuFTZ+TrADuP33hRBxlJc5+f/wkCPq9FEE0qhKRZBu7UZxpE3CjSeYe7Vd9p6ehWH2 + GoCnJplQOGX+2bfucqjhehnECBRPSymv73Axw6bYVxYQtCyfQhJFqI8ZfhaBKwMRWbZblofls+k0 + xSJa6Yp5unPSs5nXNRDv+tGeU7hFDwuo/OEBL9mNJgp0qqoT+uJJoAaxw09boLiC8mN4Ii+zbyKD + wkPw/+tfG7QUoKcNVePUCla2y8iK4fA7eyiC2Y3uoo4UXJ3t/Y6vHO8u2UqLBQ+JZPRtHqDQwqQ+ + Ddphgq2/T27RdbZ0IleFm/IvOkF+zx+diTF7XlOdWHrxa54TE+BFFP+mS6iz/yuDIfiBHLP7AiyP + ZE5wpLgKL7/uYEq7c3kJHqjmxcdN/AKDZmtAwHk4cAKCBKE2v12pVo63mNNJA4vbDBHgNEXnhHy1 + Bpx1zyisYBx3mdlYIQ3byyJuUa/vnx3kewc4c9bT+XRWvt4IUILnSimLLNSPSzCTFV82bI+mAcav + hY36MsCEkbKimIf5AzWUml1u2qZ5iCo6lda/bZcKIh9LnT2MvzhK+BqsleKzKU4EeJrINyel3ARV + n5avQdigU1Fv7u68UnRutqsoGeCRCHENg18BH6YwZYcq0zTVzf+ysjEFB+kvyZOuMX2pf08wnNrw + 9n7ZnZAhVXYIOEn5U7JG1/7bP9tnZ5hQpa1ATmQUf7fPT2rt3QWvtLg0lo0f6IAUlg3OXZQiNlJu + EqR41p5fvmlwMQswjAaEUBjPx7KrQwoTprGse7AszLs9kRrC8RBoYT++Apv9zgLPXNOJUO1yyDlE + 7fvHVhWvh/hkwFHzxVRWxUEoY6QMBtHatWK9/wVxuNPDkXu9MAiAu6XpmCOblfqRt9ZBbU85izrb + zTCYPtNZK02e99Qjb9APUNmKpTojWsQXJyD3fZYXJnKYDP6P96WnAng+3CujGyJZAVoRL8f0aKnC + +UZAOQAtMO9ni0y3mLwRYha/epp8GLoDt7WP0HUV0xFQSdNhS+egfnRDAHUN8dLFh1M4kFnq/D14 + XM3THAdki+3AOlw7itRtBk1ZwT1XN0cp/E4pU2LipRkSBFMEKLwVIq+ij/X+FlXjBMpbyMJ60ODG + o53U3yiVbBSzjMk2gs7+QCu9XoLSnEZOROtdN7SPxWjf4Mxujha66gXlE1WQ8ZKU5z6DZ7AhbbuB + UDC53lWRPwgDnEI1HFnlUV3Vr44ImhXmJej23uY5OGxGSX16JjKId03lgafelim0G0QkFB+Xj7gz + Egjv3sPG4N45vFcGPz3NbEcDc8CIkeopy8fMbWSDuIiQg6zoaqe1Gxws/m4q0Y2Xzjb7xW6kL66X + 5qesEUhkR4w2bfHrseexGpCYUE/Vl1vfH0nccAArY8Fzmp0mP7rUBz9qn2wrivS0wzKhA6DP+l3u + stBiyjwhX9NgAmvnxRZPSkQk73SUiATWb0ZIdzLIICx5VHhke06nHWJ8CGAkzKNUpB8Id7OPGbN3 + StIJXI2lOwaeIcdq4tIAfhZxntQAgNM099pS6fWlmQQ5yvCDqVuDPwKtEKCMGm0PJgwAcoW9Si9H + cDpa70ZSh9JTsYrCJRQxYhD/VmgUsQ+HopPW8ZnTw5WZkNDBJotPUNX5/O+78je9DCi4AYLWZZdB + 8U8Qv7shu6EqtiCqI5b1bAaGtOqQF5kCJCFrL+itdsSpFI7vmoajY1pqp3vB3Ptvulmnff2pt1MN + wMqGSMjZc3OOAbq48ItJBehKpGQb1gJBDNl1ICZfLyMfKzXhXrL6BNK9lNWnerrx4OFhAQqZAIf1 + tG6piLK8BRL9oPqSPa3WxFxTAdCUg2cyZbWrLhD0ulIPa7rVZKXD1eJ72wgPfSDhMpajGBlUw5xk + nJQ+vhffXB96rgqP4SbEd1haXU1kig0Ai2r16M0xvmmpKW1PP9Je2G8iHkuT9l9ZKZZ1M2JLkjV1 + DDBwdVC1hTbRCacTHFpbvkpXFVZ8ElNK7HZgdh7rufriiRx3RYm4DlZq1Vfd73NnGWtyJ+qYcO8J + 3f7HnWuTGaaHm1IF12v3q6Ws8zr7WdF/xU5oOD1r5aCOm2baU9zeAIuylLhYK9EyzcxJlZ/bwh5S + chiAyK0DUsefA6Q7vYTEzf3GxSkAXh582aNJpxaKNVabpd6oGJaNWpFGa9bmTiC/YkFxmK/E6Bwo + 3XftQCgjI5i1L73oa8hPR1uQFnEM4qq8EaBrTbrJAewWzzZco/LVOBOUimk6D5PnnEbKXVptyj0o + ylCtGL0T/KVQWd2bGF95+cRxlqToGyEEvEYKBR4C8uhET6NCMEAwDgYDVR0PAQH/BAQDAgGGMA8G + A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFBsFY+PNM0YUnIyevPI7Ck5akA7qMAsGCWCGSAFlAwQD + EgOCDO4AEYFoaKkMZpNL27HRnFOmpdwwU1/23MhmmyQoSukxDppXx5GHArX6ScYzvkddVJLZ1+6j + kUJoGakmmrWU9DSUK038u6WoPczTU7569u/dZglyHo7nORQAtEfleD00qmzd8Y2t/7DK4KPImf4P + 9jvmBakzblLuNeuy7i+7ZM2qXOTLNh6EnHrO7cHvRAnS98EIu2GN0F6mNDfdoDlsCAmggwN3dRQn + C0N15g/5Y5/qpGrcJpgSKCr+F8FvmxiboxLqVjwgIOMe97TlvaKC4QISR5kZd/FIXTD+0iDKE+hH + Ho+8i7K5UjXhrje21I/MBOoAuqgDqdSJ9yCv5GlYx41AExMmVzoScxfEH4fTCr9l9WbHuLGBOA6b + yQjNwe+s7rJCRvKsPiE5exg3t5psm+5kikVM/LF8byTAFSX/xWunmGXzP0XV8lTcnxs5SFpeZOsd + T6Azyg1WudQdi59wukmSGK59Va+5e0eybK9mb03qeQ4IMKQnBSin3V3Q917Z0Ec4pxvYvWVZ8rLg + 3jee32e2V2vizQuJ4hvVcMUz54mYym/r+ZvWejtb2Shd/6PMitt5j2cwa9Bb6ilXZcDwcRjInaJo + WsCf1tzI78IUKzI9FyEnuw7oV9IUhITDpqQPeFMIypJo9iThMd6koGLvf890pzJVcRktcVNPXA+/ + 49pxETiuA+V+lZ77qU62xlbwAb4WrMsTUCDzsePlbXGZM8LRH/juWexD4dVYR8wa23WQK5ap8D06 + RA3IrmiAuQp/UoFgXoh7kDLa/Dpwpk6UdKYDKfCySCrO484YCoRR1uiadJu6Usf9e63xh9HSA0fm + ra/MDqWvsfDo2kIyIfdInf71JPXANLUpL0c3qA+HyrZWmzrsTODwGcSwnbDZC3VZ8VJeU23AZlIs + tlVxluTohGy+DkTX16AztSjOZzrbWt1kQ5TnqfbhfJYM/ehUmsLL3+buYw96wijn5JrShnIb1Bh/ + yaOpyRRtLz7PXEVfiz5okHduT4AJskFLYSclSMw+La+9DrSdT5644vFEEGLMyRKGJZSgCwz/UaTs + 4zZZTSZ00+ytZU2KHgXQsuzGEGUMFr/v4qT1f1eq8xpM/5ElTZnqvReHP/RA4NIfVp5+bYBgKCa/ + 99QiPxJCwwXGetuhxqsJVzQFsksw+tCbvVI+xXNkKofAwT5osMyVMToyqPi5Hx96KVOAryZyVxSA + tAsKyMAz/FPYHdEZVRLHhbbWrQVg/Lgv00LIox8U6Dz7cKGYKDm7pdgqdxIeW3KgQTxdUOAQqDE4 + 3LmG4Jg+kOjTzsp7UAaDoGvpZOYMbCdc4jPJA0wQmVo5loIIpSqK1+534O8APf5vOTpZPCyPs4xQ + R6qjk0FTExH95ZMlEGZVP3t/7pKcaV35QGWJWLpX9LE55NZAw72WMp32Uxqvy5P9bLK8HJQJ68fM + QB7liIsx7M9LyHDuW7hdGF77e4PkmxfznjNUo6uto6HW3SxkeXF0077rnqG0qjh07k5sZuqnW1aa + 9bDlURxfbffKpKc3S+P7/SX2VR9Ltg5isJAe1t2z6AuUvxmGkGF1xl38cvB+5KEF2+PBFGY2CUbm + UoX0bXGoDEuv1ki6ig8oMb0hYPdFENK5dwEIlw+HUVDglVkODFza+etoL2KRLuIF2etwVswBKNO+ + gc26jmPjZqpxrx1K3FdbhZf2A13Ut34i0sDYZoGLUQr6Z/5/7fvELjrFn8GD+RbFP0dgcXlLDFnv + OzNlktIrKQl3TOJQh15gyBnhijq/TxJTnX/ZlLMDFBbhNnqPzxgkGy5fxquKqIIo5MX6Udq9IrtG + Oxo34xy8nQpHpFnD2IF472dqN6+VhPUfFk8p+9VBVZ/KGZ686jKjdmFA/TvM5G6hepc6J3KlBalj + ZFL6DtZT4doXJ4XNkBtgUQszkSJuHXpqkS085eCUMpZOIs11TrCzRPnKYc2CsBku2rfTxGFCRMIV + Hv/JieVtwyH0wCl7Rnz9o0URTeNuZMUFFkZhfu1+okweBgBpVboja7bsjH9tywsM34rWHArVCYcj + OnFoAB5KHp86rsMNybVqES7Exlf+ZXtIDxrwtC9gyTQpN657EfDoH6FKKktRF4pswhhLBhLaowku + Qj5MU/udjgq88ZoqIghsUMcxNEof2NLYH6tSJVoOoIxlbutnwN4QaMZhNvR2etPQi2ZVHKlDKLfo + /JTJsCvf1HLtcN1A4nB1c6Gr+qsvwgxA6FeAYBVYPdUZVwkBpAceAQzydUQ3G24OXrZLvXOfTcQq + jzbHcXswadh8NocVKFvVQJHEgLZI+sACfyIffWyZOXcIP7kd0QG/fHN5j539MovbPXf3lI4xA00T + Bacna3JjCS55F1zg7USiYin2+baCNmJXqcCepppzzu93M6MbHa7SEtZ9H7vu18vY/2r0EB3bzIJM + CJ6L45yCMEbSiiKwj2rEBdEUySA0m0Syh7QWTftrPcwE86j2NaI+Up8Yqf+fz9hwAeR/nPfQiLAr + 8F6dgsk8V9YJ1dbc7Fc4QKY/Mqa376I4eOkB42IYlTw4G+OEefygYHE41v5ea+A27M6RLpe1w+O3 + lvNtAEUVefGKptbkX2o9+CDbwjf3txAMjjKwbDjrT56F/uVKp8IVSEoQ2SSk9xQXZ5IHKeLdUsuZ + 3DlaxxSTcTLiSaKi68uTmilV18mu7JGVu5kxOpOFdFkyp3GJzASidllobNYEWbgwUVGbehcn01qn + 7VCAgzq6odVIHBHbus/umHmI/3cT0viWvvzFRc+VsSrywHa7/mW69L6Mi7TVGOTVT6EgEswvq46Y + 1MdfxFQCPJBqz5s5DeuG+KTZs9rJsvNYSFi4OkFqI7Kftpa1kd3mFGZmuhujdZxUGeda/6luOfds + qW4yES2dcjg604/lNUAZQo/STZ5pvk9GEdG93ODtmfgNly0DfvD6nHCv9MKFcBrZ7JSfGGvG/we7 + 0WsXyiYJHLJbyzgeZz5ZWDXpVdCXVsTRYorUK1FQpBqI0IEdrpRhFzNEQYgVjCRjVEwChDDBK6p4 + kbfJo9Pt7NhIOoRkEBWvqPdHOA2x/QwyT+pUM84DqD8P30MgHoP2CFQVKBqL/VG+jl5pWzsH1ftz + T6orwfTO6xgYMV3l+v1v7tb2PRmjnhsa7i4Bb7u+HumryOo4b4vdsyS2Hxv/tmwt+SRgK2Wo/ZV8 + 4vyrBYbM4UtfqT1qc0WB3kinnZ7kq9F40IdIq4envOvOT9bJXNTzVkslgcK/g/dEfFK1Acx1qqer + G08ReBf05FYXZrDyZ/1dtdqseuQc6TKHCL60Xt0vFUM8xEQkqbXL+Op9Jok/Vo/R6zhBJ0XkIQGF + ruiLHLTR6OobHnPcegbqZogA4ZRNv9pNCk9Hw6YLNxw/quoRHBLpKX5POcqLqdtuuNFzIM7/1Ocz + wbUCPdPR+JT2HaFclCcPe+5HAjkfxOREMrjzTgIybMof+mcBaX1SY6X/Tro/PiDRcRf+ODzA8oe+ + czJ3pBtK53ljWzA6pyel6uGGRU36YmpORK6OMWvsQx2RSwbVIrQF5NVL2VJvqK7tstras6Fr2X/M + 8jUWntaIeoA2c5bGByXdAkdWS/GqKMMitKFiVLZtyfzFgvp7U83F8kKrER8MkeaRDBgOKpFmmS4w + nZnn65g8K1fr7pukiuYsFBkXFH9iAUuUXm3mu0dp0vcMKM5bK9PS06G9B9qh46iOBJqtiubkbO8K + UTRIXU8+yf+qwVjSzx+mOlU7C5T4TeqLn1XotVkHg0RifzHypOx3J5n5n53stuew+Ku9IVT6v9lQ + JM/xHN3Z6MfxqQahR6l5eCpRcd2qLzqO+ChN2zy8dSDsTc4aMEfibL3hVo3Ho7wcgSG1jrOrZfXw + iRG/BSE710shRmpg0CALmf/w1CvFGqKJjRHEn1Q5u15/liU2w02heYvi1e8n16ww1MwVHlscuUVb + l2l8d3ZMLMBkrFE94au4pDXgoWZd+9ybDXy1Xthc1OK0+0Fv7miyIkhfwYEb3V6KnE3K3Er+qhWq + +9+PK1J/gGLRcL8jUTjFDjpTBO8ZAotO1EfJ6De8b6BfmtpErY3LohcMmPSxxgTv2rzdMBy5Zcfq + YnQPTgR1v+637afnEvlUN17+teXOe1sJhPDFrgFsmZiPBAKIpXMN6Sdd0yPGxXQS7Dc6SbcIhCnt + uI+jvXTzLmR4mWXocSnHuxZPfuY06iPgAV2bv3DMQlCGXqko6jgGl+PV61MVABxToTfB7JUP1E6L + ta1IEfgQWEU5+B+BrUIcPwMdvAN2xr52EiP2Y5EKnt0RQ+O3lCLmaKaWpDBgV8Icj5qnpViyuGnN + aveA+LwQQ1GxtNQRZZ7Mz+f4EfhSeYWZBjtIZnJ4e4O8U3N00gAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAABg0PExwgMYIONTCCDjECAQEwOjAiMQ0wCwYDVQQKEwRJRVRGMREwDwYDVQQDEwhMQU1QUyBX + RwIUFZ/+byL9XMQsUk32/V4o0N44804wCwYJYIZIAWUDBAIBoIHkMBgGCSqGSIb3DQEJAzELBgkq + hkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTI1MDcyNjIxNTIxM1owLwYJKoZIhvcNAQkEMSIEIH+D + sWV/8fxTuS3BgUih1l38LUsfo9Z3KErd0gASbZBpMHkGCSqGSIb3DQEJDzFsMGowCwYJYIZIAWUD + BAEqMAsGCWCGSAFlAwQBFjALBglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCA + MA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMAsGCWCGSAFlAwQDEgSCDO1B + HRj/PxK/AyCcl3roqEPVygicxOS54X2WN6JlYAphs6Pd1rnTpNd5V8xhH6RqtW2M7/UwSPxsGVmb + avr9pVt35pxWvS4PIdwMiBiuI4sktzkp1DXtMaOuJUgUAaeCR+cAGhoWSPF4JHh78oVX6lS5T4Cp + vpNwdb/i6DMawWfhS2KFdlt9L5RSeDtFpxqo//uYgeDjh6rbYW75Fr9EAdrizorRxXE0Jp4J0mYR + Ab5IukUQR3dG05YPPtBsxdqjOc1L+ZgrxS6XOKUJFAgyAwRogMOYaycdo7OMJQmOrPrHkPa9Glgu + SA45G+7SpcyYEnejZ2rPfw/+Mea6gIfqg1kqGXrAu+EZgkf6pElX1j7IqD4ox4S33jVQP6AHLiqZ + XzuBweftQpZUb0MxQSfSwkHIWyKL8QMJ5clrmCTz5ywWXrhFnOwaFA1c0T9LTpcrFpqcjiyW5Ztt + ZtAbW671VjhN5A8HGIpC5g0dJBkqEq+qZn7G2G9iGF3h3XtbkRaafxvkHw0CfmOCr0WV60VyPwuJ + 5YUlBaaZryyJGWPhUo/ty7ab0bYEPdk8SDlNeX8Em/kYBYMCRQfT9yetsFZvhR3AVUzMbBIvBwxJ + oFDZ5m3J3BbkJQ/kMvGx3n3nkWwW9SL3nQxZ/uWbKJsRmrdtJ5WYIs8pF9SwI0cHQ+16UdSin5hW + GnmgU+RmOkiMx8H1PSfFeC1GJ+ZkBZXye+0s8li6Z2RXBbFkGnQqky1393EFoJsw2GsmJdHh88QS + 2TSy+6lBD8HHGDVtMme/nHQYyEjoGZmTFLCyb/OUEGGuBFssYgPiXABHqAfIcP18EAsM/pt87K0s + qkGtA+0XOf4NdGEpw2m9zE8Xrum/mJD/p0UDhkH4txonj2X7TT3HJJIwx/gRSZmif/YrbcYpyf0W + /V0hyEPUbAl4UxFyFS4lwHYf1d7RaCOwSW7tyRw81zYXU7RAyPA4X1W3yklrQv6dTqczos+7O6d8 + +mTPMf59RL1UAZT5yhunVsZFnWYPfY4MPvEykvzqU0TcXDxgjeCjb6FagUmasDIbPWSA0K4iBudT + J8JsqR0sZ086gtOh1h323/iUYoq2fMqapMIIQpdpr6w72jSY4Sl9p5ctEJzqeF8VrvM1bDmMD9s9 + /zUpzK1IecXeLIQ4/9KVCuk55u6uK99+CdkfWbocXx3M95PIhz+7pQEDK/P74XSKWitigKLkZ48Z + n0R4ao9ZQAkyMAAIbL4+b7E9PfGHaz4OISr1/09Czc0w8/IDqJNqvEkcKzzKymrjoEUUh1py0YBA + r5ynL8J4tc38Ic+xHFEUUcOWVauLUOW/dV0iIbxwEfeQpGMyQ4KieZD2fvEigEDP0NyUbCfTsRmw + 92ttQD9yApKiaQe/n8HDjmJJ4qUjj8Q96VVJEAOTJ9NIZSmPNNW0FJ9WA0zxpnpIwNT+DpThu/Kv + xeBZFR8Uf6f5F6Nly7CLYi7QwhElGp7eDLfZdvVeYHzD0hNPB3SVMHOzdvpbTAmXodya7cwwKJRU + hno2DxDgldYDIhfbCrh34zaPPHR2afqOCUdR21Cfbh4jfOwxpheGk5vKND4luXlpwjOY5RNIE0kT + ZVDOQyHJal99u4rb17m1qCgIi8g72+0iQU8xZEMeRTA+gnYlUCPy6rBTggynzb6sRIQt5NOpgxZF + YYUOsiAr1NxX8RZH56RSVSk1jhIjrbQ4QKIscj7i1Csu0otU/bYm5znZnvGzleJqu4q/Fdo0EEoV + eZpszXzPU7LarZX7gl5YGc5yvyf5CQq3DALWT/J83XsW7/94edGbjxOeXYtD2CUw0D0eOSjV/dR2 + K8Bwpbaf6H8Qus77CMt0zWAUZnaWtP+sNjbLQA6W/EBpxDlDY/IklnJK+AxHdMXMzBZZSnbOtt7m + EOO3Sb65/Gy4HS4U3KuiOend+df5q4CbagtG7oNiLGlkIy+RJ0dm3GHoeAhFtCyx3e+V4ap9/Z89 + 5N8C44830s8LRYusQgiBptAXq5XCfU0NtxPJXf0xnkN7dZAmPrX8PmP51PrKdoA66p/PEkvzWSSQ + zGz+b2odJYyjfjIiurnPRigBN/o2I/om3tj70fdJuh1A6SbD/p0P5r+9dhc8L/SRfsuUKAS19XCj + 8lTAYGKs+w0yD1FQ0C+Z2W3Y3BkB7jtSE2mYBUCe0dccFBe60H5ByDg5xEvG+TjOJqBJ7WTBGPKq + 8z2wDAFbXumowE8c6uVVZiJLMhEjG6XPlPczFsXjuDBqhSri8FhSwUD+I/7w+zDKf688gzD+2QV2 + v5rOKGoHb1iwV9FaQ82ZSnbMG+YKM5s+4FKJ/2YRsDJDfhqaY3JRRViLMvj/NPFPdtqGrhVZP0rd + 1VQsw9Y2/mF6IXAZz1UbE9Du5Qb9thA+a6ujov6aqQTQuYLZbhjfc8NQUubB5W760UtvXVx1wm2f + Xb+94ROVIRwKe5THx1jtPabIAgh/1qcaKpNvmzoZxowhSruDu4k6WVWkUCYh8UMt/byDvQpA5idS + 7VnxkeEqy95pH6txHYg77pBbUKGMWolwp4axQEbpr3YIXtP6/ONxqFfOg/b+R2jPfRS3Rn4iIumH + RtAh2PbJeIH8NxLOQ7ZfmTf3+d4ctgawjQLXW/yPItj2Rp8rXocHpEfMBN5sAkc3AgKoGB18Fbrt + rh5GYKABvB5aaoGudRj1nfYRDO3HmVxJywWuV2pLgr3Jo4yqrTXQJ3CkPQskXs/ebeUtTJD5vwxO + oo/9keKjRaC8SzoG4PDnflgN/a7a0vwFvVWmOnfwshMFvpvbVL/GW37I47Nf+RGZ58jyTDjhF5nM + 2t38dBvjMVoEaFUHbil/anRVKF4fvtEs21jOUB+A3yZrAJIrQAM+J1qwzIT3wdmulFreTJ2EnbRw + lwz0QoSlA6E3GR8jZgc8eGYFUVOGU174ZrbFjiUp7qKtQ7r2vDjOTn940Eza3jC5vGi9O1iV5Ybz + C6TtwGfpodpf4sDsDH428rkgiap1dvZm1Q4mWw8NJXM93++gy0dnGXr4ODCR75HmQN2XVeHpkYjG + L0EbtWyBxd/+IWNOyg849yKlBE3o06mmMChA9rmsrAGEPfq5LfI1cmA1KAzYqlGASQgAQOWTBJfZ + 9Z3JtbbBQ0zd/Q+eE+VDlqh0BY2bwfKmSjO9PzmMWbo5sp5JM4kSd0yh41e12XT08cQBYpSApNcH + 24cVapZ/k3bRG6e1dP8j+hbGIBHWhjn+ZFh1hRabu8zGhp5ULk9TLuYRmUq8S3YvPwIjoFShNkAC + k2UQ5spzZWBual9o2Qg4RqWWbqRxNRK95FhlrTGPpizgcPKb3UKFfdFtef5bmeETY/gwP0l8yjJa + 72v9Lx2EhmnD/Y4Z/n0G4rkSDXigfGC8wI+YusijSkSkzqmygf275RndfRQfKGiR9guwC77QaiYZ + vh6TU+F3wIeEpfiCjoVAbjS/xpaCxdoKrhEHdNr1s3z4W5Lu0dkBpA0Ccexs6krvTc59frf1sL4G + OW/vdzgjJPSGuHcS1PffPBnD+ETZrlvvsiNH6OnwCu6XjD4j4HtML646Iz+2upTFOhgzd0jmLX4v + eNjXgb+epelbUQdl4//sNxZUxS6lpK5xTpgVy35yhFe7UVWd4Uaq6EbMC9bcwS2lSZpWqPylw97K + LDmMSK0VZulufoPnloKGJj+lll/uxeUJCaE5M6q8lTjp80stEL+umjcOH55TtL/EcE94x7Chb0mz + zaJfxGcbLgCI6sxOlwrXgWVm8xaD69j2VjLtsUtSuUqKh5suaN5qMdcsUxc5r9bv42MmqclNF92H + aSLzrEvrDmwJdQyjyCIi2BEDQ/kRV264Y7gskeUfSzwVsWA7OEle/udpqTMFStUyOnCnHDLLf9k1 + 0hz3n7m9z6n/uP/0Y2ioYw/15A/+pxBC/cPVMVSs4EjtB68oYtCwVuG3OJGCQCGuJv2lf2uWJZ0b + fs/qHsC+IGlvGvmv+b1aTTJMCIe7Xr1+HYziCHePDoOozzNGUOnRfkxzQYw3128lV/1wNV7tYneX + mnegvdrEuBNtbo+njoSWSXyAS5NR5die6UlUqxVuv+0WMRXO2afLKDuNUeYRCapvFBGDtlEsPDfg + WgLJrhGWLu/6Z1OVkNqCyMqlnNK6uofsfin2DMXw/pOFBiZcq/mgvyGFN79E1sM/N3GLNlF0tvsm + WqVykwXnUxKA2gocjrFKLlWUluD2AFaYuwWOgq1EFVd+0xDZSCDZkd0AlnvRQZgayvvQb6C5NpZR + VEGfn2+pkbR3DgFCW9zwbCwieHG/4FiTNoYkBXNqR+uXKrHCKeyXxIO7A23Uxn2rWcxL+xIKEQ8R + NDpZdpalrcHS4Q0SG0RosLw8WW+XydjdAykvSKjpIk2UquIKE0BRVYaUuwAAAAAAAAAAAAAMExog + JS0= + """); + // produced with // echo -n "Hello World!" | openssl cms -sign -signer ietfcert.pfx -md sha256 -nodetach -outform DER internal static readonly byte[] SlhDsa_Sha256_SignedDocument = Convert.FromBase64String( diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs index 3881441e1594eb..8b5160ba843caf 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs @@ -619,46 +619,22 @@ public static void AddCounterSigner_DuplicateCert_RSA() [InlineData(SubjectIdentifierType.SubjectKeyIdentifier)] public static void AddCounterSigner_RSA(SubjectIdentifierType identifierType) { - SignedCms cms = new SignedCms(); - cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber); - Assert.Single(cms.Certificates); - - SignerInfo firstSigner = cms.SignerInfos[0]; - Assert.Empty(firstSigner.CounterSignerInfos); - Assert.Empty(firstSigner.UnsignedAttributes); - - using (X509Certificate2 signerCert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey()) - { - CmsSigner signer = new CmsSigner(identifierType, signerCert); - firstSigner.ComputeCounterSignature(signer); - } - - Assert.Empty(firstSigner.CounterSignerInfos); - Assert.Empty(firstSigner.UnsignedAttributes); - - SignerInfo firstSigner2 = cms.SignerInfos[0]; - Assert.Single(firstSigner2.CounterSignerInfos); - Assert.Single(firstSigner2.UnsignedAttributes); - - SignerInfo counterSigner = firstSigner2.CounterSignerInfos[0]; - - Assert.Equal(identifierType, counterSigner.SignerIdentifier.Type); - - // On .NET Framework there will be two attributes, because Windows emits the - // content-type attribute even for counter-signers. - int expectedCount = 1; -#if NETFRAMEWORK - expectedCount = 2; -#endif - Assert.Equal(expectedCount, counterSigner.SignedAttributes.Count); - Assert.Equal(Oids.MessageDigest, counterSigner.SignedAttributes[expectedCount - 1].Oid.Value); - - Assert.NotEqual(firstSigner2.Certificate, counterSigner.Certificate); - Assert.Equal(2, cms.Certificates.Count); - - counterSigner.CheckSignature(true); - firstSigner2.CheckSignature(true); - cms.CheckSignature(true); + AssertAddCounterSigner( + identifierType, + signer => + { + using (X509Certificate2 signerCert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey()) + { + CmsSigner counterSigner = new CmsSigner(identifierType, signerCert); + signer.ComputeCounterSignature(counterSigner); + } + }, + (cms, counterSigner) => + { + counterSigner.CheckSignature(true); + cms.SignerInfos[0].CheckSignature(true); + cms.CheckSignature(true); + }); } [Fact] @@ -703,60 +679,33 @@ public static void AddCounterSignerToUnsortedAttributeSignature() [SkipOnPlatform(PlatformSupport.MobileAppleCrypto, "DSA is not available")] public static void AddCounterSigner_DSA() { - SignedCms cms = new SignedCms(); - cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber); - Assert.Single(cms.Certificates); - - SignerInfo firstSigner = cms.SignerInfos[0]; - Assert.Empty(firstSigner.CounterSignerInfos); - Assert.Empty(firstSigner.UnsignedAttributes); - - using (X509Certificate2 signerCert = Certificates.Dsa1024.TryGetCertificateWithPrivateKey()) - { - CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, signerCert); - signer.IncludeOption = X509IncludeOption.EndCertOnly; - // Best compatibility for DSA is SHA-1 (FIPS 186-2) - signer.DigestAlgorithm = new Oid(Oids.Sha1, Oids.Sha1); - firstSigner.ComputeCounterSignature(signer); - } - - Assert.Empty(firstSigner.CounterSignerInfos); - Assert.Empty(firstSigner.UnsignedAttributes); - - SignerInfo firstSigner2 = cms.SignerInfos[0]; - Assert.Single(firstSigner2.CounterSignerInfos); - Assert.Single(firstSigner2.UnsignedAttributes); - - Assert.Single(cms.SignerInfos); - Assert.Equal(2, cms.Certificates.Count); - - SignerInfo counterSigner = firstSigner2.CounterSignerInfos[0]; - - Assert.Equal(1, counterSigner.Version); - - // On .NET Framework there will be two attributes, because Windows emits the - // content-type attribute even for counter-signers. - int expectedCount = 1; -#if NETFRAMEWORK - expectedCount = 2; -#endif - Assert.Equal(expectedCount, counterSigner.SignedAttributes.Count); - Assert.Equal(Oids.MessageDigest, counterSigner.SignedAttributes[expectedCount - 1].Oid.Value); - - Assert.NotEqual(firstSigner2.Certificate, counterSigner.Certificate); - Assert.Equal(2, cms.Certificates.Count); - + AssertAddCounterSigner( + SubjectIdentifierType.IssuerAndSerialNumber, + signer => + { + using (X509Certificate2 signerCert = Certificates.Dsa1024.TryGetCertificateWithPrivateKey()) + { + CmsSigner counterSigner = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, signerCert); + counterSigner.IncludeOption = X509IncludeOption.EndCertOnly; + // Best compatibility for DSA is SHA-1 (FIPS 186-2) + counterSigner.DigestAlgorithm = new Oid(Oids.Sha1, Oids.Sha1); + signer.ComputeCounterSignature(counterSigner); + } + }, + (cms, counterSigner) => + { #if NET - byte[] signature = counterSigner.GetSignature(); - Assert.NotEmpty(signature); - // DSA PKIX signature format is a DER SEQUENCE. - Assert.Equal(0x30, signature[0]); + byte[] signature = counterSigner.GetSignature(); + Assert.NotEmpty(signature); + // DSA PKIX signature format is a DER SEQUENCE. + Assert.Equal(0x30, signature[0]); #endif - cms.CheckSignature(true); - byte[] encoded = cms.Encode(); - cms.Decode(encoded); - cms.CheckSignature(true); + cms.CheckSignature(true); + byte[] encoded = cms.Encode(); + cms.Decode(encoded); + cms.CheckSignature(true); + }); } [ConditionalTheory(typeof(SignatureSupport), nameof(SignatureSupport.SupportsRsaSha1Signatures))] @@ -771,63 +720,35 @@ public static void AddCounterSigner_DSA() [InlineData(SubjectIdentifierType.SubjectKeyIdentifier, Oids.Sha512)] public static void AddCounterSigner_ECDSA(SubjectIdentifierType identifierType, string digestOid) { - SignedCms cms = new SignedCms(); - cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber); - Assert.Single(cms.Certificates); - - SignerInfo firstSigner = cms.SignerInfos[0]; - Assert.Empty(firstSigner.CounterSignerInfos); - Assert.Empty(firstSigner.UnsignedAttributes); - - using (X509Certificate2 signerCert = Certificates.ECDsaP256Win.TryGetCertificateWithPrivateKey()) - { - CmsSigner signer = new CmsSigner(identifierType, signerCert); - signer.IncludeOption = X509IncludeOption.EndCertOnly; - signer.DigestAlgorithm = new Oid(digestOid, digestOid); - firstSigner.ComputeCounterSignature(signer); - } - - Assert.Empty(firstSigner.CounterSignerInfos); - Assert.Empty(firstSigner.UnsignedAttributes); - - SignerInfo firstSigner2 = cms.SignerInfos[0]; - Assert.Single(firstSigner2.CounterSignerInfos); - Assert.Single(firstSigner2.UnsignedAttributes); - - Assert.Single(cms.SignerInfos); - Assert.Equal(2, cms.Certificates.Count); - - SignerInfo counterSigner = firstSigner2.CounterSignerInfos[0]; - - int expectedVersion = identifierType == SubjectIdentifierType.IssuerAndSerialNumber ? 1 : 3; - Assert.Equal(expectedVersion, counterSigner.Version); - - // On .NET Framework there will be two attributes, because Windows emits the - // content-type attribute even for counter-signers. - int expectedCount = 1; -#if NETFRAMEWORK - expectedCount = 2; -#endif - Assert.Equal(expectedCount, counterSigner.SignedAttributes.Count); - Assert.Equal(Oids.MessageDigest, counterSigner.SignedAttributes[expectedCount - 1].Oid.Value); - - Assert.NotEqual(firstSigner2.Certificate, counterSigner.Certificate); - Assert.Equal(2, cms.Certificates.Count); - + AssertAddCounterSigner( + identifierType, + signer => + { + using (X509Certificate2 signerCert = Certificates.ECDsaP256Win.TryGetCertificateWithPrivateKey()) + { + CmsSigner counterSigner = new CmsSigner(identifierType, signerCert); + counterSigner.IncludeOption = X509IncludeOption.EndCertOnly; + counterSigner.DigestAlgorithm = new Oid(digestOid, digestOid); + signer.ComputeCounterSignature(counterSigner); + } + }, + (cms, counterSigner) => + { #if NET - byte[] signature = counterSigner.GetSignature(); - Assert.NotEmpty(signature); - // DSA PKIX signature format is a DER SEQUENCE. - Assert.Equal(0x30, signature[0]); + byte[] signature = counterSigner.GetSignature(); + Assert.NotEmpty(signature); + // DSA PKIX signature format is a DER SEQUENCE. + Assert.Equal(0x30, signature[0]); - // ECDSA Oids are all under 1.2.840.10045.4. - Assert.StartsWith("1.2.840.10045.4.", counterSigner.SignatureAlgorithm.Value); + // ECDSA Oids are all under 1.2.840.10045.4. + Assert.StartsWith("1.2.840.10045.4.", counterSigner.SignatureAlgorithm.Value); #endif - cms.CheckSignature(true); - byte[] encoded = cms.Encode(); - cms.Decode(encoded); - cms.CheckSignature(true); + cms.CheckSignature(true); + byte[] encoded = cms.Encode(); + cms.Decode(encoded); + cms.CheckSignature(true); + }); } public static IEnumerable AddCounterSignerSlhDsaTestData => @@ -849,6 +770,85 @@ from SlhDsaTestData.SlhDsaGeneratedKeyInfo info in SlhDsaTestData.GeneratedKeyIn [ConditionalTheory(nameof(SlhDsaAndRsaSha1SignaturesSupported))] [MemberData(nameof(AddCounterSignerSlhDsaTestData))] public static void AddCounterSigner_SlhDsa(SubjectIdentifierType identifierType, string digestOid, SlhDsaTestData.SlhDsaGeneratedKeyInfo info) + { + AssertAddCounterSigner( + identifierType, + signer => + { + CertLoader loader = Certificates.SlhDsaGeneratedCerts.Single(cert => cert.CerData.SequenceEqual(info.Certificate)); + using (X509Certificate2 signerCert = loader.TryGetCertificateWithPrivateKey()) + { + CmsSigner counterSigner = new CmsSigner(identifierType, signerCert); + counterSigner.IncludeOption = X509IncludeOption.EndCertOnly; + counterSigner.DigestAlgorithm = new Oid(digestOid, digestOid); + signer.ComputeCounterSignature(counterSigner); + } + }, + (cms, counterSigner) => + { + byte[] signature = counterSigner.GetSignature(); + Assert.NotEmpty(signature); + + // SLH-DSA Oids are all under 2.16.840.1.101.3.4.3. + Assert.StartsWith("2.16.840.1.101.3.4.3.", counterSigner.SignatureAlgorithm.Value); + + cms.CheckSignature(true); + byte[] encoded = cms.Encode(); + cms.Decode(encoded); + cms.CheckSignature(true); + }); + } + + public static IEnumerable AddCounterSignerMLDsaTestData => + from sit in new[] { SubjectIdentifierType.IssuerAndSerialNumber, SubjectIdentifierType.SubjectKeyIdentifier } + from data in new (MLDsaAlgorithm algorithm, string hashAlgorithm)[] + { + (MLDsaAlgorithm.MLDsa44, Oids.Shake128), + (MLDsaAlgorithm.MLDsa65, Oids.Sha512), + (MLDsaAlgorithm.MLDsa87, Oids.Shake256), + } + select new object[] { sit, data.hashAlgorithm, data.algorithm }; + + // TODO: Windows does not support draft 10 PKCS#8 format yet. Remove this and use MLDsa.IsSupported when it does. + private static bool SupportsDraft10Pkcs8 => MLDsa.IsSupported && !PlatformDetection.IsWindows; + + public static bool MLDsaAndRsaSha1SignaturesSupported => SignatureSupport.SupportsRsaSha1Signatures && SupportsDraft10Pkcs8; + + [ConditionalTheory(nameof(MLDsaAndRsaSha1SignaturesSupported))] + [MemberData(nameof(AddCounterSignerMLDsaTestData))] + public static void AddCounterSigner_MLDsa(SubjectIdentifierType identifierType, string digestOid, MLDsaAlgorithm algorithm) + { + AssertAddCounterSigner( + identifierType, + signer => + { + using (X509Certificate2 signerCert = Certificates.MLDsaIetf[algorithm].TryGetCertificateWithPrivateKey()) + { + CmsSigner counterSigner = new CmsSigner(identifierType, signerCert); + counterSigner.IncludeOption = X509IncludeOption.EndCertOnly; + counterSigner.DigestAlgorithm = new Oid(digestOid, digestOid); + signer.ComputeCounterSignature(counterSigner); + } + }, + (cms, counterSigner) => + { + byte[] signature = counterSigner.GetSignature(); + Assert.NotEmpty(signature); + + // ML-DSA Oids are all under 2.16.840.1.101.3.4.3. + Assert.StartsWith("2.16.840.1.101.3.4.3.", counterSigner.SignatureAlgorithm.Value); + + cms.CheckSignature(true); + byte[] encoded = cms.Encode(); + cms.Decode(encoded); + cms.CheckSignature(true); + }); + } + + private static void AssertAddCounterSigner( + SubjectIdentifierType identifierType, + Action counterSignSigner, + Action assertCounterSigner) { SignedCms cms = new SignedCms(); cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber); @@ -858,14 +858,7 @@ public static void AddCounterSigner_SlhDsa(SubjectIdentifierType identifierType, Assert.Empty(firstSigner.CounterSignerInfos); Assert.Empty(firstSigner.UnsignedAttributes); - CertLoader loader = Certificates.SlhDsaGeneratedCerts.Single(cert => cert.CerData.SequenceEqual(info.Certificate)); - using (X509Certificate2 signerCert = loader.TryGetCertificateWithPrivateKey()) - { - CmsSigner signer = new CmsSigner(identifierType, signerCert); - signer.IncludeOption = X509IncludeOption.EndCertOnly; - signer.DigestAlgorithm = new Oid(digestOid, digestOid); - firstSigner.ComputeCounterSignature(signer); - } + counterSignSigner(firstSigner); Assert.Empty(firstSigner.CounterSignerInfos); Assert.Empty(firstSigner.UnsignedAttributes); @@ -894,16 +887,7 @@ public static void AddCounterSigner_SlhDsa(SubjectIdentifierType identifierType, Assert.NotEqual(firstSigner2.Certificate, counterSigner.Certificate); Assert.Equal(2, cms.Certificates.Count); - byte[] signature = counterSigner.GetSignature(); - Assert.NotEmpty(signature); - - // SLH-DSA Oids are all under 2.16.840.1.101.3.4.3. - Assert.StartsWith("2.16.840.1.101.3.4.3.", counterSigner.SignatureAlgorithm.Value); - - cms.CheckSignature(true); - byte[] encoded = cms.Encode(); - cms.Decode(encoded); - cms.CheckSignature(true); + assertCounterSigner(cms, counterSigner); } [ConditionalFact(typeof(SignatureSupport), nameof(SignatureSupport.SupportsRsaSha1Signatures))] diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/System.Security.Cryptography.Pkcs.Tests.csproj b/src/libraries/System.Security.Cryptography.Pkcs/tests/System.Security.Cryptography.Pkcs.Tests.csproj index a7e844895504ab..ee52068c8a26ce 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/System.Security.Cryptography.Pkcs.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/System.Security.Cryptography.Pkcs.Tests.csproj @@ -6,6 +6,10 @@ $(NoWarn);SYSLIB5006 + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CryptoSignedXmlRecursionException.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CryptoSignedXmlRecursionException.cs index 773341fe2f5c75..459816dd26be76 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CryptoSignedXmlRecursionException.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CryptoSignedXmlRecursionException.cs @@ -20,7 +20,7 @@ public class CryptoSignedXmlRecursionException : XmlException public CryptoSignedXmlRecursionException() : base() { } public CryptoSignedXmlRecursionException(string message) : base(message) { } public CryptoSignedXmlRecursionException(string message, Exception inner) : base(message, inner) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedKey.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedKey.cs index b4646648f50fcd..ed21cbb5d46551 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedKey.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedKey.cs @@ -8,34 +8,30 @@ namespace System.Security.Cryptography.Xml { public sealed class EncryptedKey : EncryptedType { - private string? _recipient; - private string? _carriedKeyName; - private ReferenceList? _referenceList; - public EncryptedKey() { } [AllowNull] public string Recipient { - get => _recipient ??= string.Empty; // an unspecified value for an XmlAttribute is string.Empty + get => field ??= string.Empty; // an unspecified value for an XmlAttribute is string.Empty set { - _recipient = value; + field = value; _cachedXml = null; } } public string? CarriedKeyName { - get { return _carriedKeyName; } + get => field; set { - _carriedKeyName = value; + field = value; _cachedXml = null; } } - public ReferenceList ReferenceList => _referenceList ??= new ReferenceList(); + public ReferenceList ReferenceList => field ??= new ReferenceList(); public void AddReference(DataReference dataReference) { diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedReference.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedReference.cs index a65053b711fdc0..6b8bc562617a56 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedReference.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedReference.cs @@ -10,7 +10,6 @@ public abstract class EncryptedReference { private string _uri; private string? _referenceType; - private TransformChain? _transformChain; internal XmlElement? _cachedXml; protected EncryptedReference() : this(string.Empty, new TransformChain()) @@ -44,10 +43,10 @@ public string Uri public TransformChain TransformChain { - get => _transformChain ??= new TransformChain(); + get => field ??= new TransformChain(); set { - _transformChain = value; + field = value; _cachedXml = null; } } diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedType.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedType.cs index 29aa30afacfec7..77d2ad8f85848f 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedType.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedType.cs @@ -13,9 +13,7 @@ public abstract class EncryptedType private string? _mimeType; private string? _encoding; private EncryptionMethod? _encryptionMethod; - private CipherData? _cipherData; private EncryptionPropertyCollection? _props; - private KeyInfo? _keyInfo; internal XmlElement? _cachedXml; [MemberNotNullWhen(true, nameof(_cachedXml))] @@ -70,8 +68,8 @@ public virtual string? Encoding [AllowNull] public KeyInfo KeyInfo { - get => _keyInfo ??= new KeyInfo(); - set => _keyInfo = value; + get => field ??= new KeyInfo(); + set => field = value; } public virtual EncryptionMethod? EncryptionMethod @@ -93,13 +91,13 @@ public void AddProperty(EncryptionProperty ep) public virtual CipherData CipherData { - get => _cipherData ??= new CipherData(); + get => field ??= new CipherData(); set { if (value == null) throw new ArgumentNullException(nameof(value)); - _cipherData = value; + field = value; _cachedXml = null; } } diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedXml.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedXml.cs index 706c112f2e9e44..bdbea9731e876d 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedXml.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedXml.cs @@ -69,7 +69,6 @@ public class EncryptedXml private PaddingMode _padding; private CipherMode _mode; private Encoding _encoding; - private string? _recipient; private int _xmlDsigSearchDepthCounter; private int _xmlDsigSearchDepth; @@ -172,8 +171,8 @@ public Encoding Encoding [AllowNull] public string Recipient { - get => _recipient ??= string.Empty; // an unspecified value for an XmlAttribute is string.Empty - set => _recipient = value; + get => field ??= string.Empty; // an unspecified value for an XmlAttribute is string.Empty + set => field = value; } // diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXml.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXml.cs index f42e5293d17347..57e2a81c56baed 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXml.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXml.cs @@ -45,9 +45,6 @@ public class SignedXml private const string XmlDsigMoreHMACSHA512Url = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha512"; private const string XmlDsigMoreHMACRIPEMD160Url = "http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160"; - // defines the XML encryption processing rules - private EncryptedXml? _exml; - // // public constant Url identifiers most frequently used within the XML Signature classes // @@ -177,8 +174,8 @@ public EncryptedXml EncryptedXml { [UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode", Justification = "ctors are marked as RDC")] [UnconditionalSuppressMessage("ILLink", "IL2026:RequiresUnreferencedCode", Justification = "ctors are marked as RUC")] - get => _exml ??= new EncryptedXml(_containingDocument!); // default processing rules - set => _exml = value; + get => field ??= new EncryptedXml(_containingDocument!); // default processing rules + set => field = value; } public Signature Signature diff --git a/src/libraries/System.Security.Cryptography/System.Security.Cryptography.slnx b/src/libraries/System.Security.Cryptography/System.Security.Cryptography.slnx index 987a1c3c14244c..741432d88afe2c 100644 --- a/src/libraries/System.Security.Cryptography/System.Security.Cryptography.slnx +++ b/src/libraries/System.Security.Cryptography/System.Security.Cryptography.slnx @@ -68,6 +68,14 @@ + + + + + + + + @@ -84,6 +92,22 @@ + + + + + + + + + + + + + + + + @@ -100,6 +124,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -108,6 +164,14 @@ + + + + + + + + @@ -116,6 +180,14 @@ + + + + + + + + @@ -124,6 +196,14 @@ + + + + + + + + @@ -156,6 +236,22 @@ + + + + + + + + + + + + + + + + @@ -189,6 +285,14 @@ + + + + + + + + @@ -197,6 +301,14 @@ + + + + + + + + @@ -213,6 +325,22 @@ + + + + + + + + + + + + + + + + @@ -229,6 +357,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -237,6 +413,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -261,6 +469,22 @@ + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs index 43a2cc487c6468..9ce2245d0d13e5 100644 --- a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs +++ b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs @@ -335,13 +335,14 @@ public CngAlgorithm(string algorithm) { } public static System.Security.Cryptography.CngAlgorithm MD5 { get { throw null; } } [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.CngAlgorithm MLDsa { get { throw null; } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.CngAlgorithm MLKem { get { throw null; } } public static System.Security.Cryptography.CngAlgorithm Rsa { get { throw null; } } public static System.Security.Cryptography.CngAlgorithm Sha1 { get { throw null; } } public static System.Security.Cryptography.CngAlgorithm Sha256 { get { throw null; } } public static System.Security.Cryptography.CngAlgorithm Sha384 { get { throw null; } } public static System.Security.Cryptography.CngAlgorithm Sha512 { get { throw null; } } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] + public static System.Security.Cryptography.CngAlgorithm SlhDsa { get { throw null; } } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Security.Cryptography.CngAlgorithm? other) { throw null; } public override int GetHashCode() { throw null; } @@ -359,9 +360,10 @@ public CngAlgorithmGroup(string algorithmGroup) { } public static System.Security.Cryptography.CngAlgorithmGroup ECDsa { get { throw null; } } [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.CngAlgorithmGroup MLDsa { get { throw null; } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.CngAlgorithmGroup MLKem { get { throw null; } } public static System.Security.Cryptography.CngAlgorithmGroup Rsa { get { throw null; } } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] + public static System.Security.Cryptography.CngAlgorithmGroup SlhDsa { get { throw null; } } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Security.Cryptography.CngAlgorithmGroup? other) { throw null; } public override int GetHashCode() { throw null; } @@ -436,11 +438,8 @@ public CngKeyBlobFormat(string format) { } public string Format { get { throw null; } } public static System.Security.Cryptography.CngKeyBlobFormat GenericPrivateBlob { get { throw null; } } public static System.Security.Cryptography.CngKeyBlobFormat GenericPublicBlob { get { throw null; } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.CngKeyBlobFormat MLKemPrivateBlob { get { throw null; } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.CngKeyBlobFormat MLKemPrivateSeedBlob { get { throw null; } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.CngKeyBlobFormat MLKemPublicBlob { get { throw null; } } public static System.Security.Cryptography.CngKeyBlobFormat OpaqueTransportBlob { get { throw null; } } public static System.Security.Cryptography.CngKeyBlobFormat Pkcs8PrivateBlob { get { throw null; } } @@ -569,7 +568,11 @@ protected CompositeMLDsa(System.Security.Cryptography.CompositeMLDsaAlgorithm al public void Dispose() { } protected virtual void Dispose(bool disposing) { } public byte[] ExportCompositeMLDsaPrivateKey() { throw null; } + public int ExportCompositeMLDsaPrivateKey(System.Span destination) { throw null; } + protected abstract int ExportCompositeMLDsaPrivateKeyCore(System.Span destination); public byte[] ExportCompositeMLDsaPublicKey() { throw null; } + public int ExportCompositeMLDsaPublicKey(System.Span destination) { throw null; } + protected abstract int ExportCompositeMLDsaPublicKeyCore(System.Span destination); public byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } public byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } public byte[] ExportEncryptedPkcs8PrivateKey(string password, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } @@ -581,7 +584,9 @@ protected virtual void Dispose(bool disposing) { } public byte[] ExportSubjectPublicKeyInfo() { throw null; } public string ExportSubjectPublicKeyInfoPem() { throw null; } public static System.Security.Cryptography.CompositeMLDsa GenerateKey(System.Security.Cryptography.CompositeMLDsaAlgorithm algorithm) { throw null; } + public static System.Security.Cryptography.CompositeMLDsa ImportCompositeMLDsaPrivateKey(System.Security.Cryptography.CompositeMLDsaAlgorithm algorithm, byte[] source) { throw null; } public static System.Security.Cryptography.CompositeMLDsa ImportCompositeMLDsaPrivateKey(System.Security.Cryptography.CompositeMLDsaAlgorithm algorithm, System.ReadOnlySpan source) { throw null; } + public static System.Security.Cryptography.CompositeMLDsa ImportCompositeMLDsaPublicKey(System.Security.Cryptography.CompositeMLDsaAlgorithm algorithm, byte[] source) { throw null; } public static System.Security.Cryptography.CompositeMLDsa ImportCompositeMLDsaPublicKey(System.Security.Cryptography.CompositeMLDsaAlgorithm algorithm, System.ReadOnlySpan source) { throw null; } public static System.Security.Cryptography.CompositeMLDsa ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.ReadOnlySpan source) { throw null; } public static System.Security.Cryptography.CompositeMLDsa ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.ReadOnlySpan source) { throw null; } @@ -598,18 +603,16 @@ protected virtual void Dispose(bool disposing) { } public static System.Security.Cryptography.CompositeMLDsa ImportSubjectPublicKeyInfo(System.ReadOnlySpan source) { throw null; } public static bool IsAlgorithmSupported(System.Security.Cryptography.CompositeMLDsaAlgorithm algorithm) { throw null; } public byte[] SignData(byte[] data, byte[]? context = null) { throw null; } + public int SignData(System.ReadOnlySpan data, System.Span destination, System.ReadOnlySpan context = default(System.ReadOnlySpan)) { throw null; } + protected abstract int SignDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.Span destination); public bool TryExportCompositeMLDsaPrivateKey(System.Span destination, out int bytesWritten) { throw null; } - protected abstract bool TryExportCompositeMLDsaPrivateKeyCore(System.ReadOnlySpan destination, out int bytesWritten); public bool TryExportCompositeMLDsaPublicKey(System.Span destination, out int bytesWritten) { throw null; } - protected abstract bool TryExportCompositeMLDsaPublicKeyCore(System.ReadOnlySpan destination, out int bytesWritten); public bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } public bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } public bool TryExportEncryptedPkcs8PrivateKey(string password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } public bool TryExportPkcs8PrivateKey(System.Span destination, out int bytesWritten) { throw null; } protected abstract bool TryExportPkcs8PrivateKeyCore(System.Span destination, out int bytesWritten); public bool TryExportSubjectPublicKeyInfo(System.Span destination, out int bytesWritten) { throw null; } - public bool TrySignData(System.ReadOnlySpan data, System.Span destination, out int bytesWritten, System.ReadOnlySpan context = default(System.ReadOnlySpan)) { throw null; } - protected abstract bool TrySignDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.Span destination, out int bytesWritten); public bool VerifyData(byte[] data, byte[] signature, byte[]? context = null) { throw null; } public bool VerifyData(System.ReadOnlySpan data, System.ReadOnlySpan signature, System.ReadOnlySpan context = default(System.ReadOnlySpan)) { throw null; } protected abstract bool VerifyDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.ReadOnlySpan signature); @@ -645,6 +648,18 @@ internal CompositeMLDsaAlgorithm() { } public static bool operator !=(System.Security.Cryptography.CompositeMLDsaAlgorithm? left, System.Security.Cryptography.CompositeMLDsaAlgorithm? right) { throw null; } public override string ToString() { throw null; } } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] + public sealed partial class CompositeMLDsaCng : System.Security.Cryptography.CompositeMLDsa + { + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public CompositeMLDsaCng(System.Security.Cryptography.CngKey key) : base (default(System.Security.Cryptography.CompositeMLDsaAlgorithm)) { } + protected override int ExportCompositeMLDsaPrivateKeyCore(System.Span destination) { throw null; } + protected override int ExportCompositeMLDsaPublicKeyCore(System.Span destination) { throw null; } + public System.Security.Cryptography.CngKey GetKey() { throw null; } + protected override int SignDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.Span destination) { throw null; } + protected override bool TryExportPkcs8PrivateKeyCore(System.Span destination, out int bytesWritten) { throw null; } + protected override bool VerifyDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.ReadOnlySpan signature) { throw null; } + } public partial class CryptoConfig { public CryptoConfig() { } @@ -1932,9 +1947,9 @@ public void ExportMLDsaPrivateSeed(System.Span destination) { } public byte[] ExportMLDsaPublicKey() { throw null; } public void ExportMLDsaPublicKey(System.Span destination) { } protected abstract void ExportMLDsaPublicKeyCore(System.Span destination); - public byte[] ExportMLDsaSecretKey() { throw null; } - public void ExportMLDsaSecretKey(System.Span destination) { } - protected abstract void ExportMLDsaSecretKeyCore(System.Span destination); + public byte[] ExportMLDsaPrivateKey() { throw null; } + public void ExportMLDsaPrivateKey(System.Span destination) { } + protected abstract void ExportMLDsaPrivateKeyCore(System.Span destination); public byte[] ExportPkcs8PrivateKey() { throw null; } public string ExportPkcs8PrivateKeyPem() { throw null; } public byte[] ExportSubjectPublicKeyInfo() { throw null; } @@ -1949,19 +1964,26 @@ public void ExportMLDsaSecretKey(System.Span destination) { } public static System.Security.Cryptography.MLDsa ImportFromEncryptedPem(string source, string password) { throw null; } public static System.Security.Cryptography.MLDsa ImportFromPem(System.ReadOnlySpan source) { throw null; } public static System.Security.Cryptography.MLDsa ImportFromPem(string source) { throw null; } + public static System.Security.Cryptography.MLDsa ImportMLDsaPrivateKey(System.Security.Cryptography.MLDsaAlgorithm algorithm, byte[] source) { throw null; } + public static System.Security.Cryptography.MLDsa ImportMLDsaPrivateKey(System.Security.Cryptography.MLDsaAlgorithm algorithm, System.ReadOnlySpan source) { throw null; } public static System.Security.Cryptography.MLDsa ImportMLDsaPrivateSeed(System.Security.Cryptography.MLDsaAlgorithm algorithm, byte[] source) { throw null; } public static System.Security.Cryptography.MLDsa ImportMLDsaPrivateSeed(System.Security.Cryptography.MLDsaAlgorithm algorithm, System.ReadOnlySpan source) { throw null; } public static System.Security.Cryptography.MLDsa ImportMLDsaPublicKey(System.Security.Cryptography.MLDsaAlgorithm algorithm, byte[] source) { throw null; } public static System.Security.Cryptography.MLDsa ImportMLDsaPublicKey(System.Security.Cryptography.MLDsaAlgorithm algorithm, System.ReadOnlySpan source) { throw null; } - public static System.Security.Cryptography.MLDsa ImportMLDsaSecretKey(System.Security.Cryptography.MLDsaAlgorithm algorithm, byte[] source) { throw null; } - public static System.Security.Cryptography.MLDsa ImportMLDsaSecretKey(System.Security.Cryptography.MLDsaAlgorithm algorithm, System.ReadOnlySpan source) { throw null; } public static System.Security.Cryptography.MLDsa ImportPkcs8PrivateKey(byte[] source) { throw null; } public static System.Security.Cryptography.MLDsa ImportPkcs8PrivateKey(System.ReadOnlySpan source) { throw null; } public static System.Security.Cryptography.MLDsa ImportSubjectPublicKeyInfo(byte[] source) { throw null; } public static System.Security.Cryptography.MLDsa ImportSubjectPublicKeyInfo(System.ReadOnlySpan source) { throw null; } public byte[] SignData(byte[] data, byte[]? context = null) { throw null; } - public void SignData(System.ReadOnlySpan data, System.Span destination, System.ReadOnlySpan context = default(System.ReadOnlySpan)) { throw null; } + public void SignData(System.ReadOnlySpan data, System.Span destination, System.ReadOnlySpan context = default(System.ReadOnlySpan)) { } protected abstract void SignDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.Span destination); + public byte[] SignMu(byte[] externalMu) { throw null; } + public byte[] SignMu(System.ReadOnlySpan externalMu) { throw null; } + public void SignMu(System.ReadOnlySpan externalMu, System.Span destination) { } + protected abstract void SignMuCore(System.ReadOnlySpan externalMu, System.Span destination); + public byte[] SignPreHash(byte[] hash, string hashAlgorithmOid, byte[]? context = null) { throw null; } + public void SignPreHash(System.ReadOnlySpan hash, System.Span destination, string hashAlgorithmOid, System.ReadOnlySpan context = default(System.ReadOnlySpan)) { } + protected abstract void SignPreHashCore(System.ReadOnlySpan hash, System.ReadOnlySpan context, string hashAlgorithmOid, System.Span destination); public bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } public bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } public bool TryExportEncryptedPkcs8PrivateKey(string password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } @@ -1971,6 +1993,12 @@ public void ExportMLDsaSecretKey(System.Span destination) { } public bool VerifyData(byte[] data, byte[] signature, byte[]? context = null) { throw null; } public bool VerifyData(System.ReadOnlySpan data, System.ReadOnlySpan signature, System.ReadOnlySpan context = default(System.ReadOnlySpan)) { throw null; } protected abstract bool VerifyDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.ReadOnlySpan signature); + public bool VerifyMu(byte[] externalMu, byte[] signature) { throw null; } + public bool VerifyMu(System.ReadOnlySpan externalMu, System.ReadOnlySpan signature) { throw null; } + protected abstract bool VerifyMuCore(System.ReadOnlySpan externalMu, System.ReadOnlySpan signature); + public bool VerifyPreHash(byte[] hash, byte[] signature, string hashAlgorithmOid, byte[]? context = null) { throw null; } + public bool VerifyPreHash(System.ReadOnlySpan hash, System.ReadOnlySpan signature, string hashAlgorithmOid, System.ReadOnlySpan context = default(System.ReadOnlySpan)) { throw null; } + protected abstract bool VerifyPreHashCore(System.ReadOnlySpan hash, System.ReadOnlySpan context, string hashAlgorithmOid, System.ReadOnlySpan signature); } [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public sealed partial class MLDsaAlgorithm : System.IEquatable @@ -1979,10 +2007,11 @@ internal MLDsaAlgorithm() { } public static System.Security.Cryptography.MLDsaAlgorithm MLDsa44 { get { throw null; } } public static System.Security.Cryptography.MLDsaAlgorithm MLDsa65 { get { throw null; } } public static System.Security.Cryptography.MLDsaAlgorithm MLDsa87 { get { throw null; } } + public int MuSizeInBytes { get { throw null; } } public string Name { get { throw null; } } + public int PrivateKeySizeInBytes { get { throw null; } } public int PrivateSeedSizeInBytes { get { throw null; } } public int PublicKeySizeInBytes { get { throw null; } } - public int SecretKeySizeInBytes { get { throw null; } } public int SignatureSizeInBytes { get { throw null; } } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Security.Cryptography.MLDsaAlgorithm? other) { throw null; } @@ -1996,14 +2025,18 @@ public sealed partial class MLDsaCng : System.Security.Cryptography.MLDsa { [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] public MLDsaCng(System.Security.Cryptography.CngKey key) : base (default(System.Security.Cryptography.MLDsaAlgorithm)) { } - public System.Security.Cryptography.CngKey Key { get { throw null; } } protected override void Dispose(bool disposing) { } + protected override void ExportMLDsaPrivateKeyCore(System.Span destination) { } protected override void ExportMLDsaPrivateSeedCore(System.Span destination) { } protected override void ExportMLDsaPublicKeyCore(System.Span destination) { } - protected override void ExportMLDsaSecretKeyCore(System.Span destination) { } + public System.Security.Cryptography.CngKey GetKey() { throw null; } protected override void SignDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.Span destination) { } + protected override void SignMuCore(System.ReadOnlySpan externalMu, System.Span destination) { } + protected override void SignPreHashCore(System.ReadOnlySpan hash, System.ReadOnlySpan context, string hashAlgorithmOid, System.Span destination) { } protected override bool TryExportPkcs8PrivateKeyCore(System.Span destination, out int bytesWritten) { throw null; } protected override bool VerifyDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.ReadOnlySpan signature) { throw null; } + protected override bool VerifyMuCore(System.ReadOnlySpan externalMu, System.ReadOnlySpan signature) { throw null; } + protected override bool VerifyPreHashCore(System.ReadOnlySpan hash, System.ReadOnlySpan context, string hashAlgorithmOid, System.ReadOnlySpan signature) { throw null; } } [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public sealed partial class MLDsaOpenSsl : System.Security.Cryptography.MLDsa @@ -2017,14 +2050,17 @@ public sealed partial class MLDsaOpenSsl : System.Security.Cryptography.MLDsa public MLDsaOpenSsl(System.Security.Cryptography.SafeEvpPKeyHandle pkeyHandle) : base (default(System.Security.Cryptography.MLDsaAlgorithm)) { } protected override void Dispose(bool disposing) { } public System.Security.Cryptography.SafeEvpPKeyHandle DuplicateKeyHandle() { throw null; } + protected override void ExportMLDsaPrivateKeyCore(System.Span destination) { } protected override void ExportMLDsaPrivateSeedCore(System.Span destination) { } protected override void ExportMLDsaPublicKeyCore(System.Span destination) { } - protected override void ExportMLDsaSecretKeyCore(System.Span destination) { } protected override void SignDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.Span destination) { } + protected override void SignMuCore(System.ReadOnlySpan externalMu, System.Span destination) { } + protected override void SignPreHashCore(System.ReadOnlySpan hash, System.ReadOnlySpan context, string hashAlgorithmOid, System.Span destination) { } protected override bool TryExportPkcs8PrivateKeyCore(System.Span destination, out int bytesWritten) { throw null; } protected override bool VerifyDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.ReadOnlySpan signature) { throw null; } + protected override bool VerifyMuCore(System.ReadOnlySpan externalMu, System.ReadOnlySpan signature) { throw null; } + protected override bool VerifyPreHashCore(System.ReadOnlySpan hash, System.ReadOnlySpan context, string hashAlgorithmOid, System.ReadOnlySpan signature) { throw null; } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public abstract partial class MLKem : System.IDisposable { protected MLKem(System.Security.Cryptography.MLKemAlgorithm algorithm) { } @@ -2044,47 +2080,75 @@ public void ExportDecapsulationKey(System.Span destination) { } public byte[] ExportEncapsulationKey() { throw null; } public void ExportEncapsulationKey(System.Span destination) { } protected abstract void ExportEncapsulationKeyCore(System.Span destination); + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public byte[] ExportEncryptedPkcs8PrivateKey(string password, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public string ExportEncryptedPkcs8PrivateKeyPem(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public string ExportEncryptedPkcs8PrivateKeyPem(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public string ExportEncryptedPkcs8PrivateKeyPem(string password, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public byte[] ExportPkcs8PrivateKey() { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public string ExportPkcs8PrivateKeyPem() { throw null; } public byte[] ExportPrivateSeed() { throw null; } public void ExportPrivateSeed(System.Span destination) { } protected abstract void ExportPrivateSeedCore(System.Span destination); + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public byte[] ExportSubjectPublicKeyInfo() { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public string ExportSubjectPublicKeyInfoPem() { throw null; } public static System.Security.Cryptography.MLKem GenerateKey(System.Security.Cryptography.MLKemAlgorithm algorithm) { throw null; } public static System.Security.Cryptography.MLKem ImportDecapsulationKey(System.Security.Cryptography.MLKemAlgorithm algorithm, byte[] source) { throw null; } public static System.Security.Cryptography.MLKem ImportDecapsulationKey(System.Security.Cryptography.MLKemAlgorithm algorithm, System.ReadOnlySpan source) { throw null; } public static System.Security.Cryptography.MLKem ImportEncapsulationKey(System.Security.Cryptography.MLKemAlgorithm algorithm, byte[] source) { throw null; } public static System.Security.Cryptography.MLKem ImportEncapsulationKey(System.Security.Cryptography.MLKemAlgorithm algorithm, System.ReadOnlySpan source) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.MLKem ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.ReadOnlySpan source) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.MLKem ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.ReadOnlySpan source) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.MLKem ImportEncryptedPkcs8PrivateKey(string password, byte[] source) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.MLKem ImportFromEncryptedPem(System.ReadOnlySpan source, System.ReadOnlySpan passwordBytes) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.MLKem ImportFromEncryptedPem(System.ReadOnlySpan source, System.ReadOnlySpan password) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.MLKem ImportFromEncryptedPem(string source, byte[] passwordBytes) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.MLKem ImportFromEncryptedPem(string source, string password) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.MLKem ImportFromPem(System.ReadOnlySpan source) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.MLKem ImportFromPem(string source) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.MLKem ImportPkcs8PrivateKey(byte[] source) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.MLKem ImportPkcs8PrivateKey(System.ReadOnlySpan source) { throw null; } public static System.Security.Cryptography.MLKem ImportPrivateSeed(System.Security.Cryptography.MLKemAlgorithm algorithm, byte[] source) { throw null; } public static System.Security.Cryptography.MLKem ImportPrivateSeed(System.Security.Cryptography.MLKemAlgorithm algorithm, System.ReadOnlySpan source) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.MLKem ImportSubjectPublicKeyInfo(byte[] source) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.MLKem ImportSubjectPublicKeyInfo(System.ReadOnlySpan source) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public bool TryExportEncryptedPkcs8PrivateKey(string password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public bool TryExportPkcs8PrivateKey(System.Span destination, out int bytesWritten) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] protected abstract bool TryExportPkcs8PrivateKeyCore(System.Span destination, out int bytesWritten); + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public bool TryExportSubjectPublicKeyInfo(System.Span destination, out int bytesWritten) { throw null; } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public sealed partial class MLKemAlgorithm : System.IEquatable { internal MLKemAlgorithm() { } @@ -2104,7 +2168,6 @@ internal MLKemAlgorithm() { } public static bool operator !=(System.Security.Cryptography.MLKemAlgorithm? left, System.Security.Cryptography.MLKemAlgorithm? right) { throw null; } public override string ToString() { throw null; } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public sealed partial class MLKemCng : System.Security.Cryptography.MLKem { [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] @@ -2118,7 +2181,6 @@ protected override void ExportPrivateSeedCore(System.Span destination) { } public System.Security.Cryptography.CngKey GetKey() { throw null; } protected override bool TryExportPkcs8PrivateKeyCore(System.Span destination, out int bytesWritten) { throw null; } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public sealed partial class MLKemOpenSsl : System.Security.Cryptography.MLKem { [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] @@ -3025,12 +3087,12 @@ protected virtual void Dispose(bool disposing) { } public string ExportEncryptedPkcs8PrivateKeyPem(string password, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } public byte[] ExportPkcs8PrivateKey() { throw null; } public string ExportPkcs8PrivateKeyPem() { throw null; } + public byte[] ExportSlhDsaPrivateKey() { throw null; } + public void ExportSlhDsaPrivateKey(System.Span destination) { } + protected abstract void ExportSlhDsaPrivateKeyCore(System.Span destination); public byte[] ExportSlhDsaPublicKey() { throw null; } public void ExportSlhDsaPublicKey(System.Span destination) { } protected abstract void ExportSlhDsaPublicKeyCore(System.Span destination); - public byte[] ExportSlhDsaSecretKey() { throw null; } - public void ExportSlhDsaSecretKey(System.Span destination) { } - protected abstract void ExportSlhDsaSecretKeyCore(System.Span destination); public byte[] ExportSubjectPublicKeyInfo() { throw null; } public string ExportSubjectPublicKeyInfoPem() { throw null; } public static System.Security.Cryptography.SlhDsa GenerateKey(System.Security.Cryptography.SlhDsaAlgorithm algorithm) { throw null; } @@ -3045,10 +3107,10 @@ public void ExportSlhDsaSecretKey(System.Span destination) { } public static System.Security.Cryptography.SlhDsa ImportFromPem(string source) { throw null; } public static System.Security.Cryptography.SlhDsa ImportPkcs8PrivateKey(byte[] source) { throw null; } public static System.Security.Cryptography.SlhDsa ImportPkcs8PrivateKey(System.ReadOnlySpan source) { throw null; } + public static System.Security.Cryptography.SlhDsa ImportSlhDsaPrivateKey(System.Security.Cryptography.SlhDsaAlgorithm algorithm, byte[] source) { throw null; } + public static System.Security.Cryptography.SlhDsa ImportSlhDsaPrivateKey(System.Security.Cryptography.SlhDsaAlgorithm algorithm, System.ReadOnlySpan source) { throw null; } public static System.Security.Cryptography.SlhDsa ImportSlhDsaPublicKey(System.Security.Cryptography.SlhDsaAlgorithm algorithm, byte[] source) { throw null; } public static System.Security.Cryptography.SlhDsa ImportSlhDsaPublicKey(System.Security.Cryptography.SlhDsaAlgorithm algorithm, System.ReadOnlySpan source) { throw null; } - public static System.Security.Cryptography.SlhDsa ImportSlhDsaSecretKey(System.Security.Cryptography.SlhDsaAlgorithm algorithm, byte[] source) { throw null; } - public static System.Security.Cryptography.SlhDsa ImportSlhDsaSecretKey(System.Security.Cryptography.SlhDsaAlgorithm algorithm, System.ReadOnlySpan source) { throw null; } public static System.Security.Cryptography.SlhDsa ImportSubjectPublicKeyInfo(byte[] source) { throw null; } public static System.Security.Cryptography.SlhDsa ImportSubjectPublicKeyInfo(System.ReadOnlySpan source) { throw null; } public byte[] SignData(byte[] data, byte[]? context = null) { throw null; } @@ -3075,8 +3137,8 @@ public sealed partial class SlhDsaAlgorithm : System.IEquatable destination) { } + protected override void ExportSlhDsaPublicKeyCore(System.Span destination) { } + public System.Security.Cryptography.CngKey GetKey() { throw null; } + protected override void SignDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.Span destination) { } + protected override void SignPreHashCore(System.ReadOnlySpan hash, System.ReadOnlySpan context, string hashAlgorithmOid, System.Span destination) { } + protected override bool TryExportPkcs8PrivateKeyCore(System.Span destination, out int bytesWritten) { throw null; } + protected override bool VerifyDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.ReadOnlySpan signature) { throw null; } + protected override bool VerifyPreHashCore(System.ReadOnlySpan hash, System.ReadOnlySpan context, string hashAlgorithmOid, System.ReadOnlySpan signature) { throw null; } + } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public sealed partial class SlhDsaOpenSsl : System.Security.Cryptography.SlhDsa { [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] @@ -3109,10 +3185,11 @@ public sealed partial class SlhDsaOpenSsl : System.Security.Cryptography.SlhDsa public SlhDsaOpenSsl(System.Security.Cryptography.SafeEvpPKeyHandle pkeyHandle) : base (default(System.Security.Cryptography.SlhDsaAlgorithm)) { } protected override void Dispose(bool disposing) { } public System.Security.Cryptography.SafeEvpPKeyHandle DuplicateKeyHandle() { throw null; } + protected override void ExportSlhDsaPrivateKeyCore(System.Span destination) { } protected override void ExportSlhDsaPublicKeyCore(System.Span destination) { } - protected override void ExportSlhDsaSecretKeyCore(System.Span destination) { } protected override void SignDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.Span destination) { } protected override void SignPreHashCore(System.ReadOnlySpan hash, System.ReadOnlySpan context, string hashAlgorithmOid, System.Span destination) { } + protected override bool TryExportPkcs8PrivateKeyCore(System.Span destination, out int bytesWritten) { throw null; } protected override bool VerifyDataCore(System.ReadOnlySpan data, System.ReadOnlySpan context, System.ReadOnlySpan signature) { throw null; } protected override bool VerifyPreHashCore(System.ReadOnlySpan hash, System.ReadOnlySpan context, string hashAlgorithmOid, System.ReadOnlySpan signature) { throw null; } } @@ -3287,6 +3364,8 @@ namespace System.Security.Cryptography.X509Certificates [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public sealed partial class CertificateRequest { + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] + public CertificateRequest(System.Security.Cryptography.X509Certificates.X500DistinguishedName subjectName, System.Security.Cryptography.CompositeMLDsa key) { } public CertificateRequest(System.Security.Cryptography.X509Certificates.X500DistinguishedName subjectName, System.Security.Cryptography.ECDsa key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { } [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public CertificateRequest(System.Security.Cryptography.X509Certificates.X500DistinguishedName subjectName, System.Security.Cryptography.MLDsa key) { } @@ -3295,6 +3374,8 @@ public CertificateRequest(System.Security.Cryptography.X509Certificates.X500Dist public CertificateRequest(System.Security.Cryptography.X509Certificates.X500DistinguishedName subjectName, System.Security.Cryptography.SlhDsa key) { } public CertificateRequest(System.Security.Cryptography.X509Certificates.X500DistinguishedName subjectName, System.Security.Cryptography.X509Certificates.PublicKey publicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { } public CertificateRequest(System.Security.Cryptography.X509Certificates.X500DistinguishedName subjectName, System.Security.Cryptography.X509Certificates.PublicKey publicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding? rsaSignaturePadding = null) { } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] + public CertificateRequest(string subjectName, System.Security.Cryptography.CompositeMLDsa key) { } public CertificateRequest(string subjectName, System.Security.Cryptography.ECDsa key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { } [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public CertificateRequest(string subjectName, System.Security.Cryptography.MLDsa key) { } @@ -3376,6 +3457,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 { } } @@ -3400,6 +3482,8 @@ public sealed partial class PublicKey { public PublicKey(System.Security.Cryptography.AsymmetricAlgorithm key) { } [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006")] + public PublicKey(System.Security.Cryptography.CompositeMLDsa key) { } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006")] public PublicKey(System.Security.Cryptography.MLDsa key) { } [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public PublicKey(System.Security.Cryptography.MLKem key) { } @@ -3413,6 +3497,9 @@ public PublicKey(System.Security.Cryptography.SlhDsa key) { } public System.Security.Cryptography.Oid Oid { get { throw null; } } public static System.Security.Cryptography.X509Certificates.PublicKey CreateFromSubjectPublicKeyInfo(System.ReadOnlySpan source, out int bytesRead) { throw null; } public byte[] ExportSubjectPublicKeyInfo() { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public System.Security.Cryptography.CompositeMLDsa? GetCompositeMLDsaPublicKey() { throw null; } [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] @@ -3740,6 +3827,8 @@ public X509Certificate2(string fileName, string? password, System.Security.Crypt public System.Security.Cryptography.X509Certificates.X500DistinguishedName SubjectName { get { throw null; } } public string Thumbprint { get { throw null; } } public int Version { get { throw null; } } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] + public System.Security.Cryptography.X509Certificates.X509Certificate2 CopyWithPrivateKey(System.Security.Cryptography.CompositeMLDsa privateKey) { throw null; } public System.Security.Cryptography.X509Certificates.X509Certificate2 CopyWithPrivateKey(System.Security.Cryptography.ECDiffieHellman privateKey) { throw null; } [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public System.Security.Cryptography.X509Certificates.X509Certificate2 CopyWithPrivateKey(System.Security.Cryptography.MLDsa privateKey) { throw null; } @@ -3764,6 +3853,10 @@ public X509Certificate2(string fileName, string? password, System.Security.Crypt public static System.Security.Cryptography.X509Certificates.X509ContentType GetCertContentType(System.ReadOnlySpan rawData) { throw null; } [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static System.Security.Cryptography.X509Certificates.X509ContentType GetCertContentType(string fileName) { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] + public System.Security.Cryptography.CompositeMLDsa? GetCompositeMLDsaPrivateKey() { throw null; } + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] + public System.Security.Cryptography.CompositeMLDsa? GetCompositeMLDsaPublicKey() { throw null; } public System.Security.Cryptography.ECDiffieHellman? GetECDiffieHellmanPrivateKey() { throw null; } public System.Security.Cryptography.ECDiffieHellman? GetECDiffieHellmanPublicKey() { throw null; } [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] @@ -4166,6 +4259,8 @@ public abstract partial class X509SignatureGenerator protected X509SignatureGenerator() { } public System.Security.Cryptography.X509Certificates.PublicKey PublicKey { get { throw null; } } protected abstract System.Security.Cryptography.X509Certificates.PublicKey BuildPublicKey(); + [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] + public static System.Security.Cryptography.X509Certificates.X509SignatureGenerator CreateForCompositeMLDsa(System.Security.Cryptography.CompositeMLDsa key) { throw null; } public static System.Security.Cryptography.X509Certificates.X509SignatureGenerator CreateForECDsa(System.Security.Cryptography.ECDsa key) { throw null; } [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Security.Cryptography.X509Certificates.X509SignatureGenerator CreateForMLDsa(System.Security.Cryptography.MLDsa key) { throw null; } diff --git a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.csproj b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.csproj index 0ac11594442a03..bc4ef53fe9a8bc 100644 --- a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.csproj +++ b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.csproj @@ -1,4 +1,5 @@ + $(NetCoreAppCurrent) $(NoWarn);SYSLIB0026 @@ -16,5 +17,7 @@ + + diff --git a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx index d6a1cb9bd20260..c62f5dac36b581 100644 --- a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx @@ -141,14 +141,14 @@ The specified private seed is not the correct length for the ML-KEM algorithm. - - The public key is not the correct size for the indicated algorithm. + + The specified mu value is not the correct length for the ML-DSA algorithm. - - The secret key is not the correct size for the indicated algorithm. + + The private key is not the correct size for the indicated algorithm. - - The private key is too short for the indicated algorithm. + + The public key is not the correct size for the indicated algorithm. The private seed is not the correct size for the indicated algorithm. @@ -327,6 +327,9 @@ The specified CipherMode '{0}' is not supported. + + Composite signature generation failed due to an error in one or both of the components. + Concurrent operations from multiple threads on this type are not supported. @@ -411,6 +414,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. @@ -567,9 +573,6 @@ The specified EVP_PKEY handle is not a known ML-DSA algorithm. - - The current instance does not contain a secret key. - The specified PKCS#8 key contains a seed that does not match the expanded key. @@ -588,6 +591,9 @@ The contents do not contain a PEM with a '{0}' label, or the content is malformed. + + The current instance does not contain a private key. + The key contents are not retrievable. diff --git a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj index 310a4395a91e06..b7ef41c439c00f 100644 --- a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj +++ b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj @@ -1,9 +1,9 @@ - + + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-unix;$(NetCoreAppCurrent)-android;$(NetCoreAppCurrent)-osx;$(NetCoreAppCurrent)-ios;$(NetCoreAppCurrent)-tvos;$(NetCoreAppCurrent)-browser;$(NetCoreAppCurrent) true $(DefineConstants);INTERNAL_ASYMMETRIC_IMPLEMENTATIONS;SYSTEM_SECURITY_CRYPTOGRAPHY - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-unix;$(NetCoreAppCurrent)-android;$(NetCoreAppCurrent)-osx;$(NetCoreAppCurrent)-ios;$(NetCoreAppCurrent)-tvos;$(NetCoreAppCurrent)-browser;$(NetCoreAppCurrent) $(NoWarn);CA5350;CA5351;CA5379;CA5384;SYSLIB0026 $(NoWarn);CS0809 @@ -382,8 +382,10 @@ Link="Common\System\Security\Cryptography\CompositeMLDsa.cs" /> - + + + + + + @@ -607,6 +616,7 @@ + @@ -691,7 +701,6 @@ - @@ -823,6 +832,8 @@ Link="Common\Interop\Browser\Interop.Libraries.cs" /> + + @@ -1023,6 +1035,12 @@ Link="Common\System\IO\PersistedFiles.Names.Unix.cs" /> + + + + @@ -1193,6 +1212,8 @@ Link="Common\Microsoft\Win32\SafeHandles\SafeEvpMdCtxHandle.Unix.cs" /> + + + + + + + + + @@ -1982,6 +2019,7 @@ + @@ -2005,25 +2043,25 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - + diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AsymmetricAlgorithmHelpers.Der.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AsymmetricAlgorithmHelpers.Der.cs index 13900be4fcfb9a..ab44810b0dcb50 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AsymmetricAlgorithmHelpers.Der.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AsymmetricAlgorithmHelpers.Der.cs @@ -11,80 +11,6 @@ namespace System.Security.Cryptography // internal static partial class AsymmetricAlgorithmHelpers { - /// - /// Convert Ieee1363 format of (r, s) to Der format - /// - public static byte[] ConvertIeee1363ToDer(ReadOnlySpan input) - { - AsnWriter writer = WriteIeee1363ToDer(input); - return writer.Encode(); - } - - internal static bool TryConvertIeee1363ToDer( - ReadOnlySpan input, - Span destination, - out int bytesWritten) - { - AsnWriter writer = WriteIeee1363ToDer(input); - return writer.TryEncode(destination, out bytesWritten); - } - - private static AsnWriter WriteIeee1363ToDer(ReadOnlySpan input) - { - Debug.Assert(input.Length % 2 == 0); - Debug.Assert(input.Length > 1); - - // Input is (r, s), each of them exactly half of the array. - // Output is the DER encoded value of SEQUENCE(INTEGER(r), INTEGER(s)). - int halfLength = input.Length / 2; - - AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - writer.PushSequence(); - writer.WriteKeyParameterInteger(input.Slice(0, halfLength)); - writer.WriteKeyParameterInteger(input.Slice(halfLength, halfLength)); - writer.PopSequence(); - return writer; - } - - /// - /// Convert Der format of (r, s) to Ieee1363 format - /// - public static byte[] ConvertDerToIeee1363(ReadOnlySpan input, int fieldSizeBits) - { - int fieldSizeBytes = BitsToBytes(fieldSizeBits); - int encodedSize = 2 * fieldSizeBytes; - byte[] response = new byte[encodedSize]; - - ConvertDerToIeee1363(input, fieldSizeBits, response); - return response; - } - - internal static int ConvertDerToIeee1363(ReadOnlySpan input, int fieldSizeBits, Span destination) - { - int fieldSizeBytes = BitsToBytes(fieldSizeBits); - int encodedSize = 2 * fieldSizeBytes; - - Debug.Assert(destination.Length >= encodedSize); - - try - { - AsnValueReader reader = new AsnValueReader(input, AsnEncodingRules.DER); - AsnValueReader sequenceReader = reader.ReadSequence(); - reader.ThrowIfNotEmpty(); - ReadOnlySpan rDer = sequenceReader.ReadIntegerBytes(); - ReadOnlySpan sDer = sequenceReader.ReadIntegerBytes(); - sequenceReader.ThrowIfNotEmpty(); - - CopySignatureField(rDer, destination.Slice(0, fieldSizeBytes)); - CopySignatureField(sDer, destination.Slice(fieldSizeBytes, fieldSizeBytes)); - return encodedSize; - } - catch (AsnContentException e) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); - } - } - /// /// Converts IeeeP1363 format to the specified signature format /// @@ -124,30 +50,6 @@ internal static byte[] ConvertSignatureToIeeeP1363( } } - private static void CopySignatureField(ReadOnlySpan signatureField, Span response) - { - if (signatureField.Length > response.Length) - { - if (signatureField.Length != response.Length + 1 || - signatureField[0] != 0 || - signatureField[1] <= 0x7F) - { - // The only way this should be true is if the value required a zero-byte-pad. - Debug.Fail($"A signature field was longer ({signatureField.Length}) than expected ({response.Length})"); - throw new CryptographicException(); - } - - signatureField = signatureField.Slice(1); - } - - // If the field is too short then it needs to be prepended - // with zeroes in the response. Since the array was already - // zeroed out, just figure out where we need to start copying. - int writeOffset = response.Length - signatureField.Length; - response.Slice(0, writeOffset).Clear(); - signatureField.CopyTo(response.Slice(writeOffset)); - } - internal static byte[]? ConvertSignatureToIeeeP1363( this DSA dsa, DSASignatureFormat currentFormat, diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Cng.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Cng.NotSupported.cs index dac7973d4871fd..7148d243f1c220 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Cng.NotSupported.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Cng.NotSupported.cs @@ -396,26 +396,32 @@ public sealed partial class MLDsaCng : MLDsa private static partial MLDsaAlgorithm AlgorithmFromHandle(CngKey key, out CngKey duplicateKey) => throw new PlatformNotSupportedException(); - public partial CngKey Key => - throw new PlatformNotSupportedException(); + public partial CngKey GetKey() => + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); protected override void ExportMLDsaPrivateSeedCore(Span destination) => - throw new PlatformNotSupportedException(); + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); protected override void ExportMLDsaPublicKeyCore(Span destination) => - throw new PlatformNotSupportedException(); + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); - protected override void ExportMLDsaSecretKeyCore(Span destination) => - throw new PlatformNotSupportedException(); + protected override void ExportMLDsaPrivateKeyCore(Span destination) => + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); protected override void SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) => - throw new PlatformNotSupportedException(); + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + + protected override void SignPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) => - throw new PlatformNotSupportedException(); + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => - throw new PlatformNotSupportedException(); + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + + protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); } public sealed partial class MLKemCng : MLKem @@ -460,4 +466,25 @@ protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); } } + + public sealed partial class CompositeMLDsaCng : CompositeMLDsa + { + public partial CngKey GetKey() => + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + + protected override int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) => + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + + protected override int ExportCompositeMLDsaPrivateKeyCore(Span destination) => + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + + protected override int ExportCompositeMLDsaPublicKeyCore(Span destination) => + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + + protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) => + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + + protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithm.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithm.cs index 2adf7190b28905..b3d6c19dd0d703 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithm.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithm.cs @@ -216,9 +216,19 @@ public static CngAlgorithm Sha512 /// A new object that specifies the Module-Lattice-Based Key-Encapsulation /// Mechanism (ML-KEM). /// - [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static CngAlgorithm MLKem => field ??= new CngAlgorithm("ML-KEM"); // BCRYPT_MLKEM_ALGORITHM + /// + /// Gets a new object that specifies the Stateless Hash-Based Digital Signature + /// Algorithm (SLH-DSA). + /// + /// + /// A new object that specifies the Stateless Hash-Based Digital Signature + /// Algorithm (SLH-DSA). + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static CngAlgorithm SlhDsa => field ??= new CngAlgorithm("SLH-DSA"); // BCRYPT_SLHDSA_ALGORITHM + private static CngAlgorithm? s_ecdh; private static CngAlgorithm? s_ecdhp256; private static CngAlgorithm? s_ecdhp384; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithmGroup.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithmGroup.cs index 94c41f31785cfd..819184aa0e25f8 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithmGroup.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithmGroup.cs @@ -144,10 +144,20 @@ public static CngAlgorithmGroup Rsa /// /// An object that specifies the ML-KEM family of algorithms. /// - [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static CngAlgorithmGroup MLKem => field ??= new CngAlgorithmGroup("MLKEM"); // NCRYPT_MLKEM_ALGORITHM_GROUP + /// + /// Gets a object that specifies the Stateless Hash-Based Digital Signature + /// Algorithm (SLH-DSA) family of algorithms. + /// + /// + /// An object that specifies the SLH-DSA family of algorithms. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static CngAlgorithmGroup SlhDsa => + field ??= new CngAlgorithmGroup("SLHDSA"); // NCRYPT_SLHDSA_ALGORITHM_GROUP + private static CngAlgorithmGroup? s_dh; private static CngAlgorithmGroup? s_dsa; private static CngAlgorithmGroup? s_ecdh; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngHelpers.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngHelpers.cs index a28da92a91a1ed..a3bf82a0c53d72 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngHelpers.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngHelpers.cs @@ -17,21 +17,6 @@ internal static partial class CngHelpers { private static readonly CngKeyBlobFormat s_cipherKeyBlobFormat = new CngKeyBlobFormat(Interop.NCrypt.NCRYPT_CIPHER_KEY_BLOB); - internal static SafeNCryptProviderHandle OpenStorageProvider(this CngProvider provider) - { - string providerName = provider.Provider; - SafeNCryptProviderHandle providerHandle; - ErrorCode errorCode = Interop.NCrypt.NCryptOpenStorageProvider(out providerHandle, providerName, 0); - - if (errorCode != ErrorCode.ERROR_SUCCESS) - { - providerHandle.Dispose(); - throw errorCode.ToCryptographicException(); - } - - return providerHandle; - } - /// /// Retrieve a well-known CNG dword property. (Note: .NET Framework compat: this helper likes to return special values /// rather than throw exceptions for missing or ill-formatted property values. Only use it for well-known properties that diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyBlobFormat.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyBlobFormat.cs index 3274a260836067..7210031f566e0b 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyBlobFormat.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyBlobFormat.cs @@ -190,7 +190,6 @@ public static CngKeyBlobFormat GenericPublicBlob /// /// The value identified by this blob format is "MLKEMPUBLICBLOB". /// - [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static CngKeyBlobFormat MLKemPublicBlob => field ??= new CngKeyBlobFormat("MLKEMPUBLICBLOB"); /// @@ -204,7 +203,6 @@ public static CngKeyBlobFormat GenericPublicBlob /// /// The value identified by this blob format is "MLKEMPRIVATEBLOB". /// - [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static CngKeyBlobFormat MLKemPrivateBlob => field ??= new CngKeyBlobFormat("MLKEMPRIVATEBLOB"); /// @@ -218,7 +216,6 @@ public static CngKeyBlobFormat GenericPublicBlob /// /// The value identified by this blob format is "MLKEMPRIVATESEEDBLOB". /// - [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static CngKeyBlobFormat MLKemPrivateSeedBlob => field ??= new CngKeyBlobFormat("MLKEMPRIVATESEEDBLOB"); public static CngKeyBlobFormat OpaqueTransportBlob diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CompositeMLDsaImplementation.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CompositeMLDsaImplementation.OpenSsl.cs new file mode 100644 index 00000000000000..7d6c5fe0cac78a --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CompositeMLDsaImplementation.OpenSsl.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + internal sealed partial class CompositeMLDsaImplementation : CompositeMLDsa + { + private CompositeMLDsaImplementation(CompositeMLDsaAlgorithm algorithm) + : base(algorithm) + { + throw new PlatformNotSupportedException(); + } + + internal static partial bool SupportsAny() => CompositeMLDsaManaged.SupportsAny(); + + internal static partial bool IsAlgorithmSupportedImpl(CompositeMLDsaAlgorithm algorithm) => + CompositeMLDsaManaged.IsAlgorithmSupportedImpl(algorithm); + + internal static partial CompositeMLDsa GenerateKeyImpl(CompositeMLDsaAlgorithm algorithm) => + CompositeMLDsaManaged.GenerateKeyImpl(algorithm); + + internal static partial CompositeMLDsa ImportCompositeMLDsaPublicKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => + CompositeMLDsaManaged.ImportCompositeMLDsaPublicKeyImpl(algorithm, source); + + internal static partial CompositeMLDsa ImportCompositeMLDsaPrivateKeyImpl(CompositeMLDsaAlgorithm algorithm, ReadOnlySpan source) => + CompositeMLDsaManaged.ImportCompositeMLDsaPrivateKeyImpl(algorithm, source); + + protected override int SignDataCore(ReadOnlySpan data, ReadOnlySpan context, Span destination) => + throw new PlatformNotSupportedException(); + + protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => + throw new PlatformNotSupportedException(); + + protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out int bytesWritten) => + throw new PlatformNotSupportedException(); + + protected override int ExportCompositeMLDsaPublicKeyCore(Span destination) => + throw new PlatformNotSupportedException(); + + protected override int ExportCompositeMLDsaPrivateKeyCore(Span destination) => + throw new PlatformNotSupportedException(); + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSAWrapper.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSAWrapper.cs index 6bd9a94d81b781..80a13790cad274 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSAWrapper.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSAWrapper.cs @@ -150,10 +150,6 @@ public override byte[] ExportEncryptedPkcs8PrivateKey( public override byte[] ExportSubjectPublicKeyInfo() => _wrapped.ExportSubjectPublicKeyInfo(); - public override bool Equals(object? obj) => _wrapped.Equals(obj); - - public override int GetHashCode() => _wrapped.GetHashCode(); - public override string ToString() => _wrapped.ToString()!; protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanWrapper.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanWrapper.cs index b355ccab0a305a..d267b727b71c2d 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanWrapper.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanWrapper.cs @@ -152,10 +152,6 @@ public override byte[] ExportEncryptedPkcs8PrivateKey( public override byte[] ExportSubjectPublicKeyInfo() => _wrapped.ExportSubjectPublicKeyInfo(); - public override bool Equals(object? obj) => _wrapped.Equals(obj); - - public override int GetHashCode() => _wrapped.GetHashCode(); - public override string ToString() => _wrapped.ToString()!; private static ECDiffieHellmanPublicKey Unwrap(ECDiffieHellmanPublicKey otherPartyPublicKey) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaWrapper.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaWrapper.cs index c1733c98e7580d..bb9cadd9b8524a 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaWrapper.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaWrapper.cs @@ -175,10 +175,6 @@ public override bool TrySignHash(ReadOnlySpan hash, Span destination public override bool VerifyHash(ReadOnlySpan hash, ReadOnlySpan signature) => _wrapped.VerifyHash(hash, signature); - public override bool Equals(object? obj) => _wrapped.Equals(obj); - - public override int GetHashCode() => _wrapped.GetHashCode(); - public override string ToString() => _wrapped.ToString()!; protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/EccKeyFormatHelper.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/EccKeyFormatHelper.cs new file mode 100644 index 00000000000000..daa8b514bca86d --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/EccKeyFormatHelper.cs @@ -0,0 +1,822 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers; +using System.Collections; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Formats.Asn1; +using System.Runtime.InteropServices; +using System.Security.Cryptography.Asn1; + +namespace System.Security.Cryptography +{ + internal static partial class EccKeyFormatHelper + { + // This is the same limit that OpenSSL 1.0.2-1.1.1 has, + // there's no real point reading anything bigger than this (for now). + private const int MaxFieldBitSize = 661; + + private static readonly string[] s_validOids = + { + Oids.EcPublicKey, + }; + + internal static void ReadSubjectPublicKeyInfo( + ReadOnlySpan source, + out int bytesRead, + out ECParameters key) + { + KeyFormatHelper.ReadSubjectPublicKeyInfo( + s_validOids, + source, + FromECPublicKey, + out bytesRead, + out key); + } + + internal static ReadOnlyMemory ReadSubjectPublicKeyInfo( + ReadOnlyMemory source, + out int bytesRead) + { + return KeyFormatHelper.ReadSubjectPublicKeyInfo( + s_validOids, + source, + out bytesRead); + } + + internal static void ReadEncryptedPkcs8( + ReadOnlySpan source, + ReadOnlySpan password, + out int bytesRead, + out ECParameters key) + { + KeyFormatHelper.ReadEncryptedPkcs8( + s_validOids, + source, + password, + FromECPrivateKey, + out bytesRead, + out key); + } + + internal static void ReadEncryptedPkcs8( + ReadOnlySpan source, + ReadOnlySpan passwordBytes, + out int bytesRead, + out ECParameters key) + { + KeyFormatHelper.ReadEncryptedPkcs8( + s_validOids, + source, + passwordBytes, + FromECPrivateKey, + out bytesRead, + out key); + } + + internal static unsafe ECParameters FromECPrivateKey(ReadOnlySpan key, out int bytesRead) + { + try + { + AsnDecoder.ReadEncodedValue( + key, + AsnEncodingRules.BER, + out _, + out _, + out int firstValueLength); + + fixed (byte* ptr = &MemoryMarshal.GetReference(key)) + { + using (MemoryManager manager = new PointerMemoryManager(ptr, firstValueLength)) + { + AlgorithmIdentifierAsn algId = default; + FromECPrivateKey(manager.Memory, algId, out ECParameters ret); + bytesRead = firstValueLength; + return ret; + } + } + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void FromECPrivateKey( + ReadOnlyMemory keyData, + in AlgorithmIdentifierAsn algId, + out ECParameters ret) + { + ECPrivateKey key = ECPrivateKey.Decode(keyData, AsnEncodingRules.BER); + FromECPrivateKey(key, algId, out ret); + } + + internal static void FromECPrivateKey( + ECPrivateKey key, + in AlgorithmIdentifierAsn algId, + out ECParameters ret) + { + ValidateParameters(key.Parameters, algId); + + if (key.Version != 1) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + byte[]? x = null; + byte[]? y = null; + + if (key.PublicKey is not null) + { + GetECPointFromUncompressedPublicKey(key.PublicKey.Value.Span, key.PrivateKey.Length, out x, out y); + } + + ECDomainParameters domainParameters; + + if (key.Parameters != null) + { + domainParameters = key.Parameters.Value; + } + else + { + domainParameters = ECDomainParameters.Decode(algId.Parameters!.Value, AsnEncodingRules.DER); + } + + Debug.Assert((x == null) == (y == null)); + + ret = new ECParameters + { + Curve = GetCurve(domainParameters), + Q = new ECPoint + { + X = x, + Y = y, + }, + D = key.PrivateKey.ToArray(), + }; + + ret.Validate(); + } + + internal static void FromECPublicKey( + ReadOnlyMemory key, + in AlgorithmIdentifierAsn algId, + out ECParameters ret) + { + if (algId.Parameters == null) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + ReadOnlySpan publicKeyBytes = key.Span; + + if (publicKeyBytes.Length == 0) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + // Implementation limitation. + // 04 (Uncompressed ECPoint) is almost always used. + if (publicKeyBytes[0] != 0x04) + { + throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); + } + + // https://www.secg.org/sec1-v2.pdf, 2.3.4, #3 (M has length 2 * CEIL(log2(q)/8) + 1) + if ((publicKeyBytes.Length & 0x01) != 1) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + int fieldWidth = publicKeyBytes.Length / 2; + + ECDomainParameters domainParameters = ECDomainParameters.Decode( + algId.Parameters.Value, + AsnEncodingRules.DER); + + ret = new ECParameters + { + Curve = GetCurve(domainParameters), + Q = + { + X = publicKeyBytes.Slice(1, fieldWidth).ToArray(), + Y = publicKeyBytes.Slice(1 + fieldWidth).ToArray(), + }, + }; + + ret.Validate(); + } + + private static void ValidateParameters(ECDomainParameters? keyParameters, in AlgorithmIdentifierAsn algId) + { + // At least one is required + if (keyParameters == null && algId.Parameters == null) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + // If they are both specified they must match. + if (keyParameters != null && algId.Parameters != null) + { + ReadOnlySpan algIdParameters = algId.Parameters.Value.Span; + + // X.509 SubjectPublicKeyInfo specifies DER encoding. + // RFC 5915 specifies DER encoding for EC Private Keys. + // So we can compare as DER. + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + keyParameters.Value.Encode(writer); + + if (!writer.EncodedValueEquals(algIdParameters)) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + } + } + + private static ECCurve GetCurve(ECDomainParameters domainParameters) + { + if (domainParameters.Specified.HasValue) + { + return GetSpecifiedECCurve(domainParameters.Specified.Value); + } + + if (domainParameters.Named == null) + { + throw new CryptographicException(SR.Cryptography_ECC_NamedCurvesOnly); + } + + Oid curveOid = domainParameters.Named switch { + Oids.secp256r1 => Oids.secp256r1Oid, + Oids.secp384r1 => Oids.secp384r1Oid, + Oids.secp521r1 => Oids.secp521r1Oid, + _ => new Oid(domainParameters.Named, null) + }; + + return ECCurve.CreateFromOid(curveOid); + } + + private static ECCurve GetSpecifiedECCurve(SpecifiedECDomain specifiedParameters) + { + try + { + return GetSpecifiedECCurveCore(specifiedParameters); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static ECCurve GetSpecifiedECCurveCore(SpecifiedECDomain specifiedParameters) + { + // sec1-v2 C.3: + // + // Versions 1, 2, and 3 are defined. + // 1 is just data, 2 and 3 mean that a seed is required (with different reasons for why, + // but they're human-reasons, not technical ones). + if (specifiedParameters.Version < 1 || specifiedParameters.Version > 3) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + if (specifiedParameters.Version > 1 && !specifiedParameters.Curve.Seed.HasValue) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + byte[] primeOrPoly; + bool prime; + + switch (specifiedParameters.FieldID.FieldType) + { + case Oids.EcPrimeField: + prime = true; + AsnReader primeReader = new AsnReader(specifiedParameters.FieldID.Parameters, AsnEncodingRules.BER); + ReadOnlySpan primeValue = primeReader.ReadIntegerBytes().Span; + primeReader.ThrowIfNotEmpty(); + + if (primeValue[0] == 0) + { + primeValue = primeValue.Slice(1); + } + + if (primeValue.Length > (MaxFieldBitSize / 8)) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + primeOrPoly = primeValue.ToArray(); + break; + case Oids.EcChar2Field: + prime = false; + AsnReader char2Reader = new AsnReader(specifiedParameters.FieldID.Parameters, AsnEncodingRules.BER); + AsnReader innerReader = char2Reader.ReadSequence(); + char2Reader.ThrowIfNotEmpty(); + + // Characteristic-two ::= SEQUENCE + // { + // m INTEGER, -- Field size + // basis CHARACTERISTIC-TWO.&id({BasisTypes}), + // parameters CHARACTERISTIC-TWO.&Type({BasisTypes}{@basis}) + // } + + if (!innerReader.TryReadInt32(out int m) || m > MaxFieldBitSize || m < 0) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + int k1; + int k2 = -1; + int k3 = -1; + + switch (innerReader.ReadObjectIdentifier()) + { + case Oids.EcChar2TrinomialBasis: + // Trinomial ::= INTEGER + if (!innerReader.TryReadInt32(out k1) || k1 >= m || k1 < 1) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + break; + case Oids.EcChar2PentanomialBasis: + // Pentanomial ::= SEQUENCE + // { + // k1 INTEGER, -- k1 > 0 + // k2 INTEGER, -- k2 > k1 + // k3 INTEGER -- k3 > k2 + // } + AsnReader pentanomialReader = innerReader.ReadSequence(); + + if (!pentanomialReader.TryReadInt32(out k1) || + !pentanomialReader.TryReadInt32(out k2) || + !pentanomialReader.TryReadInt32(out k3) || + k1 < 1 || + k2 <= k1 || + k3 <= k2 || + k3 >= m) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + pentanomialReader.ThrowIfNotEmpty(); + + break; + default: + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + innerReader.ThrowIfNotEmpty(); + + BitArray poly = new BitArray(m + 1); + poly.Set(m, true); + poly.Set(k1, true); + poly.Set(0, true); + + if (k2 > 0) + { + poly.Set(k2, true); + poly.Set(k3, true); + } + + primeOrPoly = new byte[(m + 7) / 8]; + poly.CopyTo(primeOrPoly, 0); + Array.Reverse(primeOrPoly); + break; + default: + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + ECCurve curve; + + if (prime) + { + curve = new ECCurve + { + CurveType = ECCurve.ECCurveType.PrimeShortWeierstrass, + Prime = primeOrPoly, + }; + } + else + { + curve = new ECCurve + { + CurveType = ECCurve.ECCurveType.Characteristic2, + Polynomial = primeOrPoly, + }; + } + + curve.A = specifiedParameters.Curve.A.ToUnsignedIntegerBytes(primeOrPoly.Length); + curve.B = specifiedParameters.Curve.B.ToUnsignedIntegerBytes(primeOrPoly.Length); + curve.Order = specifiedParameters.Order.ToUnsignedIntegerBytes(primeOrPoly.Length); + + ReadOnlySpan baseSpan = specifiedParameters.Base.Span; + + // We only understand the uncompressed point encoding, but that's almost always what's used. + if (baseSpan[0] != 0x04 || baseSpan.Length != 2 * primeOrPoly.Length + 1) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + curve.G.X = baseSpan.Slice(1, primeOrPoly.Length).ToArray(); + curve.G.Y = baseSpan.Slice(1 + primeOrPoly.Length).ToArray(); + + if (specifiedParameters.Cofactor.HasValue) + { + curve.Cofactor = specifiedParameters.Cofactor.Value.ToUnsignedIntegerBytes(); + } + + return curve; + } + + internal static AsnWriter WriteSubjectPublicKeyInfo(ECParameters ecParameters) + { + ecParameters.Validate(); + + // Since the public key format for EC keys is not ASN.1, + // write the SPKI structure manually. + + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + + // SubjectPublicKeyInfo + writer.PushSequence(); + + // algorithm + WriteAlgorithmIdentifier(ecParameters, writer); + + // subjectPublicKey + WriteUncompressedPublicKey(ecParameters, writer); + + writer.PopSequence(); + return writer; + } + + private static AsnWriter WriteAlgorithmIdentifier(in ECParameters ecParameters) + { + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + WriteAlgorithmIdentifier(ecParameters, writer); + return writer; + } + + private static void WriteAlgorithmIdentifier(in ECParameters ecParameters, AsnWriter writer) + { + writer.PushSequence(); + + writer.WriteObjectIdentifier(Oids.EcPublicKey); + WriteEcParameters(ecParameters, writer); + + writer.PopSequence(); + } + + internal static AsnWriter WritePkcs8PrivateKey(ECParameters ecParameters, AttributeAsn[]? attributes = null) + { + ecParameters.Validate(); + + if (ecParameters.D == null) + { + throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey); + } + + // Don't need the domain parameters because they're contained in the algId. + AsnWriter ecPrivateKey = WriteEcPrivateKey(ecParameters, includeDomainParameters: false); + AsnWriter algorithmIdentifier = WriteAlgorithmIdentifier(ecParameters); + AsnWriter? attributeWriter = WritePrivateKeyInfoAttributes(attributes); + + return KeyFormatHelper.WritePkcs8(algorithmIdentifier, ecPrivateKey, attributeWriter); + } + + [return: NotNullIfNotNull(nameof(attributes))] + private static AsnWriter? WritePrivateKeyInfoAttributes(AttributeAsn[]? attributes) + { + if (attributes == null) + return null; + + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + Asn1Tag tag = new Asn1Tag(TagClass.ContextSpecific, 0); + writer.PushSetOf(tag); + + for (int i = 0; i < attributes.Length; i++) + { + attributes[i].Encode(writer); + } + + writer.PopSetOf(tag); + return writer; + } + + private static void WriteEcParameters(ECParameters ecParameters, AsnWriter writer) + { + if (ecParameters.Curve.IsNamed) + { + Oid oid = ecParameters.Curve.Oid; + + // On Windows the FriendlyName is populated in places where the Value mightn't be. + if (string.IsNullOrEmpty(oid.Value)) + { + Debug.Assert(oid.FriendlyName != null); + oid = Oid.FromFriendlyName(oid.FriendlyName, OidGroup.All); + } + + writer.WriteObjectIdentifier(oid.Value!); + } + else if (ecParameters.Curve.IsExplicit) + { + Debug.Assert(ecParameters.Curve.IsPrime || ecParameters.Curve.IsCharacteristic2); + WriteSpecifiedECDomain(ecParameters, writer); + } + else + { + throw new CryptographicException( + SR.Format(SR.Cryptography_CurveNotSupported, ecParameters.Curve.CurveType.ToString())); + } + } + + private static void WriteSpecifiedECDomain(ECParameters ecParameters, AsnWriter writer) + { + int m; + int k1; + int k2; + int k3; + m = k1 = k2 = k3 = -1; + + if (ecParameters.Curve.IsCharacteristic2) + { + DetermineChar2Parameters(ecParameters, ref m, ref k1, ref k2, ref k3); + } + + // SpecifiedECDomain + writer.PushSequence(); + { + // version + // We don't know if the seed (if present) is verifiably random (2). + // We also don't know if the base point is verifiably random (3). + // So just be version 1. + writer.WriteInteger(1); + + // fieldId + writer.PushSequence(); + { + if (ecParameters.Curve.IsPrime) + { + writer.WriteObjectIdentifier(Oids.EcPrimeField); + writer.WriteIntegerUnsigned(ecParameters.Curve.Prime); + } + else + { + Debug.Assert(ecParameters.Curve.IsCharacteristic2); + + // id + writer.WriteObjectIdentifier(Oids.EcChar2Field); + + // Parameters (Characteristic-two) + writer.PushSequence(); + { + // m + writer.WriteInteger(m); + + if (k3 > 0) + { + writer.WriteObjectIdentifier(Oids.EcChar2PentanomialBasis); + + writer.PushSequence(); + { + writer.WriteInteger(k1); + writer.WriteInteger(k2); + writer.WriteInteger(k3); + + writer.PopSequence(); + } + } + else + { + Debug.Assert(k2 < 0); + Debug.Assert(k1 > 0); + + writer.WriteObjectIdentifier(Oids.EcChar2TrinomialBasis); + writer.WriteInteger(k1); + } + + writer.PopSequence(); + } + } + + writer.PopSequence(); + } + + // curve + WriteCurve(ecParameters.Curve, writer); + + // base + WriteUncompressedBasePoint(ecParameters, writer); + + // order + writer.WriteIntegerUnsigned(ecParameters.Curve.Order); + + // cofactor + if (ecParameters.Curve.Cofactor != null) + { + writer.WriteIntegerUnsigned(ecParameters.Curve.Cofactor); + } + + // hash is omitted. + + writer.PopSequence(); + } + } + + private static void DetermineChar2Parameters( + in ECParameters ecParameters, + ref int m, + ref int k1, + ref int k2, + ref int k3) + { + byte[] polynomial = ecParameters.Curve.Polynomial!; + int lastIndex = polynomial.Length - 1; + + // The most significant byte needs a set bit, and the least significant bit must be set. + if (polynomial[0] == 0 || (polynomial[lastIndex] & 1) != 1) + { + throw new CryptographicException(SR.Cryptography_InvalidECCharacteristic2Curve); + } + + for (int localBitIndex = 7; localBitIndex >= 0; localBitIndex--) + { + int test = 1 << localBitIndex; + + if ((polynomial[0] & test) == test) + { + m = checked(8 * lastIndex + localBitIndex); + } + } + + // Find the other set bits. Since we've already found m and 0, there is either + // one remaining (trinomial) or 3 (pentanomial). + for (int inverseIndex = 0; inverseIndex < polynomial.Length; inverseIndex++) + { + int forwardIndex = lastIndex - inverseIndex; + byte val = polynomial[forwardIndex]; + + for (int localBitIndex = 0; localBitIndex < 8; localBitIndex++) + { + int test = 1 << localBitIndex; + + if ((val & test) == test) + { + int bitIndex = 8 * inverseIndex + localBitIndex; + + if (bitIndex == 0) + { + // The bottom bit is always set, it's not considered a parameter. + } + else if (bitIndex == m) + { + break; + } + else if (k1 < 0) + { + k1 = bitIndex; + } + else if (k2 < 0) + { + k2 = bitIndex; + } + else if (k3 < 0) + { + k3 = bitIndex; + } + else + { + // More than pentanomial. + throw new CryptographicException(SR.Cryptography_InvalidECCharacteristic2Curve); + } + } + } + } + + if (k3 > 0) + { + // Pentanomial + } + else if (k2 > 0) + { + // There is no quatranomial + throw new CryptographicException(SR.Cryptography_InvalidECCharacteristic2Curve); + } + else if (k1 > 0) + { + // Trinomial + } + else + { + // No smaller bases exist + throw new CryptographicException(SR.Cryptography_InvalidECCharacteristic2Curve); + } + } + + private static void WriteCurve(in ECCurve curve, AsnWriter writer) + { + writer.PushSequence(); + WriteFieldElement(curve.A!, writer); + WriteFieldElement(curve.B!, writer); + + if (curve.Seed != null) + { + writer.WriteBitString(curve.Seed); + } + + writer.PopSequence(); + } + + private static void WriteFieldElement(byte[] fieldElement, AsnWriter writer) + { + int start = 0; + + while (start < fieldElement.Length - 1 && fieldElement[start] == 0) + { + start++; + } + + writer.WriteOctetString(fieldElement.AsSpan(start)); + } + + private static void WriteUncompressedBasePoint(in ECParameters ecParameters, AsnWriter writer) + { + int basePointLength = ecParameters.Curve.G.X!.Length * 2 + 1; + + // A NIST P-521 G will be at most 133 bytes (NIST 186-4 defines G.) + // 256 should be plenty for all but very atypical uses. + const int MaxStackAllocSize = 256; + Span basePointBytes = stackalloc byte[MaxStackAllocSize]; + byte[]? rented = null; + + if (basePointLength > MaxStackAllocSize) + { + basePointBytes = rented = CryptoPool.Rent(basePointLength); + } + + basePointBytes[0] = 0x04; + ecParameters.Curve.G.X.CopyTo(basePointBytes.Slice(1)); + ecParameters.Curve.G.Y.CopyTo(basePointBytes.Slice(1 + ecParameters.Curve.G.X.Length)); + + writer.WriteOctetString(basePointBytes.Slice(0, basePointLength)); + + if (rented is not null) + { + // G contains public EC parameters that are not sensitive. + CryptoPool.Return(rented, clearSize: 0); + } + } + + private static void WriteUncompressedPublicKey(in ECParameters ecParameters, AsnWriter writer) + { + WriteUncompressedPublicKey(ecParameters.Q.X!, ecParameters.Q.Y!, writer); + } + + internal static AsnWriter WriteECPrivateKey(in ECParameters ecParameters) + { + return WriteEcPrivateKey(ecParameters, includeDomainParameters: true); + } + + private static AsnWriter WriteEcPrivateKey(in ECParameters ecParameters, bool includeDomainParameters) + { + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + + // ECPrivateKey + writer.PushSequence(); + + // version 1 + writer.WriteInteger(1); + + // privateKey + writer.WriteOctetString(ecParameters.D); + + // domainParameters + if (includeDomainParameters) + { + Asn1Tag explicit0 = new Asn1Tag(TagClass.ContextSpecific, 0, isConstructed: true); + writer.PushSequence(explicit0); + + WriteEcParameters(ecParameters, writer); + + writer.PopSequence(explicit0); + } + + // publicKey + if (ecParameters.Q.X != null) + { + Debug.Assert(ecParameters.Q.Y != null); + Asn1Tag explicit1 = new Asn1Tag(TagClass.ContextSpecific, 1, isConstructed: true); + writer.PushSequence(explicit1); + + WriteUncompressedPublicKey(ecParameters, writer); + + writer.PopSequence(explicit1); + } + + writer.PopSequence(); + return writer; + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Helpers.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Helpers.cs index 8c1b0c4de9ae56..02a16e23a31ab5 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Helpers.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Helpers.cs @@ -469,19 +469,51 @@ internal static void ThrowIfPasswordContainsNullCharacter(string? password) internal static bool IsSlhDsaOid(string? oid) => SlhDsaAlgorithm.GetAlgorithmFromOid(oid) is not null; - public delegate TResult SlhDsaPreHashFuncCallback( + internal delegate TResult PreHashFuncCallback( TKey key, ReadOnlySpan encodedMessage, TSignature signatureBuffer) where TSignature : allows ref struct; + /// + /// Encodes the message for ML-DSA pre-hash signing. + /// Algorithm is described in FIPS 205: Algorithm 23. + /// + internal static TResult MLDsaPreHash( + ReadOnlySpan hash, + ReadOnlySpan context, + ReadOnlySpan hashAlgorithmOid, + TKey key, + TSignature signatureBuffer, + PreHashFuncCallback callback) + where TSignature : allows ref struct + => MLDsaSlhDsaPreHash(hash, context, hashAlgorithmOid, key, signatureBuffer, callback); + + /// + /// Encodes the message for SLH-DSA pre-hash signing. + /// Algorithm is described in FIPS 204: Algorithm 4. + /// internal static TResult SlhDsaPreHash( ReadOnlySpan hash, ReadOnlySpan context, ReadOnlySpan hashAlgorithmOid, TKey key, TSignature signatureBuffer, - SlhDsaPreHashFuncCallback callback) + PreHashFuncCallback callback) + where TSignature : allows ref struct + => MLDsaSlhDsaPreHash(hash, context, hashAlgorithmOid, key, signatureBuffer, callback); + + /// + /// Encodes the message for ML-DSA and SLH-DSA pre-hash signing. + /// Algorithm is described in FIPS 204: Algorithm 4 and equivalent algorithm in FIPS 205: Algorithm 23. + /// + private static TResult MLDsaSlhDsaPreHash( + ReadOnlySpan hash, + ReadOnlySpan context, + ReadOnlySpan hashAlgorithmOid, + TKey key, + TSignature signatureBuffer, + PreHashFuncCallback callback) where TSignature : allows ref struct { // The OIDs for the algorithms above have max length 11. We'll just round up for a conservative initial estimate. diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/KeyBlobHelpers.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/KeyBlobHelpers.cs new file mode 100644 index 00000000000000..22c10081c26107 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/KeyBlobHelpers.cs @@ -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. + +using System.Numerics; + +namespace System.Security.Cryptography +{ + internal static partial class KeyBlobHelpers + { + internal static byte[] ToUnsignedIntegerBytes(this ReadOnlyMemory memory, int length) + { + if (memory.Length == length) + { + return memory.ToArray(); + } + + ReadOnlySpan span = memory.Span; + + if (memory.Length == length + 1) + { + if (span[0] == 0) + { + return span.Slice(1).ToArray(); + } + } + + if (span.Length > length) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + byte[] target = new byte[length]; + span.CopyTo(target.AsSpan(length - span.Length)); + return target; + } + + internal static byte[] ExportKeyParameter(this BigInteger value, int length) + { + byte[] target = new byte[length]; + + if (value.TryWriteBytes(target, out int bytesWritten, isUnsigned: true, isBigEndian: true)) + { + if (bytesWritten < length) + { + Buffer.BlockCopy(target, 0, target, length - bytesWritten, bytesWritten); + target.AsSpan(0, length - bytesWritten).Clear(); + } + + return target; + } + + throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaImplementation.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaImplementation.OpenSsl.cs index 89ee47691b827b..fe4a5e8cfda541 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaImplementation.OpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaImplementation.OpenSsl.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using Internal.Cryptography; namespace System.Security.Cryptography { @@ -11,13 +12,13 @@ internal sealed partial class MLDsaImplementation : MLDsa private SafeEvpPKeyHandle _key = null!; private readonly bool _hasSeed; - private readonly bool _hasSecretKey; + private readonly bool _hasPrivateKey; private MLDsaImplementation( MLDsaAlgorithm algorithm, SafeEvpPKeyHandle key, bool hasSeed, - bool hasSecretKey) + bool hasPrivateKey) : base(algorithm) { Debug.Assert(key is not null); @@ -26,7 +27,7 @@ private MLDsaImplementation( _key = key; _hasSeed = hasSeed; - _hasSecretKey = hasSecretKey; + _hasPrivateKey = hasPrivateKey; } protected override void Dispose(bool disposing) @@ -45,6 +46,27 @@ internal static partial bool SupportsAny() => Interop.Crypto.EvpPKeyMLDsaAlgs.MLDsa65 != null || Interop.Crypto.EvpPKeyMLDsaAlgs.MLDsa87 != null; + internal static partial bool IsAlgorithmSupported(MLDsaAlgorithm algorithm) + { + if (algorithm == MLDsaAlgorithm.MLDsa44) + { + return Interop.Crypto.EvpPKeyMLDsaAlgs.MLDsa44 != null; + } + else if (algorithm == MLDsaAlgorithm.MLDsa65) + { + return Interop.Crypto.EvpPKeyMLDsaAlgs.MLDsa65 != null; + } + else if (algorithm == MLDsaAlgorithm.MLDsa87) + { + return Interop.Crypto.EvpPKeyMLDsaAlgs.MLDsa87 != null; + } + else + { + Debug.Fail($"Unexpected algorithm: {algorithm}"); + return false; + } + } + internal SafeEvpPKeyHandle DuplicateHandle() { return _key.DuplicateHandle(); @@ -56,14 +78,42 @@ protected override void SignDataCore(ReadOnlySpan data, ReadOnlySpan protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => Interop.Crypto.MLDsaVerifyPure(_key, data, context, signature); + protected override void SignPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => + Helpers.MLDsaPreHash( + hash, + context, + hashAlgorithmOid, + _key, + destination, + static (key, encodedMessage, destination) => + { + Interop.Crypto.MLDsaSignPreEncoded(key, encodedMessage, destination); + return true; + }); + + protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => + Helpers.MLDsaPreHash( + hash, + context, + hashAlgorithmOid, + _key, + signature, + static (key, encodedMessage, signature) => Interop.Crypto.MLDsaVerifyPreEncoded(key, encodedMessage, signature)); + + protected override void SignMuCore(ReadOnlySpan externalMu, Span destination) => + Interop.Crypto.MLDsaSignExternalMu(_key, externalMu, destination); + + protected override bool VerifyMuCore(ReadOnlySpan externalMu, ReadOnlySpan signature) => + Interop.Crypto.MLDsaVerifyExternalMu(_key, externalMu, signature); + protected override void ExportMLDsaPublicKeyCore(Span destination) => Interop.Crypto.MLDsaExportPublicKey(_key, destination); - protected override void ExportMLDsaSecretKeyCore(Span destination) + protected override void ExportMLDsaPrivateKeyCore(Span destination) { - if (!_hasSecretKey) + if (!_hasPrivateKey) { - throw new CryptographicException(SR.Cryptography_MLDsaNoSecretKey); + throw new CryptographicException(SR.Cryptography_NoPrivateKeyAvailable); } Interop.Crypto.MLDsaExportSecretKey(_key, destination); @@ -84,7 +134,7 @@ protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out return MLDsaPkcs8.TryExportPkcs8PrivateKey( this, _hasSeed, - _hasSecretKey, + _hasPrivateKey, destination, out bytesWritten); } @@ -92,28 +142,28 @@ protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out internal static partial MLDsaImplementation GenerateKeyImpl(MLDsaAlgorithm algorithm) { SafeEvpPKeyHandle key = Interop.Crypto.MLDsaGenerateKey(algorithm.Name, ReadOnlySpan.Empty); - return new MLDsaImplementation(algorithm, key, hasSeed: true, hasSecretKey: true); + return new MLDsaImplementation(algorithm, key, hasSeed: true, hasPrivateKey: true); } internal static partial MLDsaImplementation ImportPublicKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) { Debug.Assert(source.Length == algorithm.PublicKeySizeInBytes, $"Public key was expected to be {algorithm.PublicKeySizeInBytes} bytes, but was {source.Length} bytes."); SafeEvpPKeyHandle key = Interop.Crypto.EvpPKeyFromData(algorithm.Name, source, privateKey: false); - return new MLDsaImplementation(algorithm, key, hasSeed: false, hasSecretKey: false); + return new MLDsaImplementation(algorithm, key, hasSeed: false, hasPrivateKey: false); } - internal static partial MLDsaImplementation ImportSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) + internal static partial MLDsaImplementation ImportPrivateKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) { - Debug.Assert(source.Length == algorithm.SecretKeySizeInBytes, $"Secret key was expected to be {algorithm.SecretKeySizeInBytes} bytes, but was {source.Length} bytes."); + Debug.Assert(source.Length == algorithm.PrivateKeySizeInBytes, $"Private key was expected to be {algorithm.PrivateKeySizeInBytes} bytes, but was {source.Length} bytes."); SafeEvpPKeyHandle key = Interop.Crypto.EvpPKeyFromData(algorithm.Name, source, privateKey: true); - return new MLDsaImplementation(algorithm, key, hasSeed: false, hasSecretKey: true); + return new MLDsaImplementation(algorithm, key, hasSeed: false, hasPrivateKey: true); } internal static partial MLDsaImplementation ImportSeed(MLDsaAlgorithm algorithm, ReadOnlySpan source) { Debug.Assert(source.Length == algorithm.PrivateSeedSizeInBytes, $"Seed was expected to be {algorithm.PrivateSeedSizeInBytes} bytes, but was {source.Length} bytes."); SafeEvpPKeyHandle key = Interop.Crypto.MLDsaGenerateKey(algorithm.Name, source); - return new MLDsaImplementation(algorithm, key, hasSeed: true, hasSecretKey: true); + return new MLDsaImplementation(algorithm, key, hasSeed: true, hasPrivateKey: true); } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaOpenSsl.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaOpenSsl.NotSupported.cs index e28ff314915001..d5f1a57e144459 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaOpenSsl.NotSupported.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaOpenSsl.NotSupported.cs @@ -11,7 +11,7 @@ private static partial MLDsaAlgorithm AlgorithmFromHandle( SafeEvpPKeyHandle pkeyHandle, out SafeEvpPKeyHandle upRefHandle, out bool hasSeed, - out bool hasSecretKey) + out bool hasPrivateKey) { throw new PlatformNotSupportedException(); } @@ -40,13 +40,37 @@ protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) + { + Debug.Fail("Caller should have checked platform availability."); + throw new PlatformNotSupportedException(); + } + + protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) + { + Debug.Fail("Caller should have checked platform availability."); + throw new PlatformNotSupportedException(); + } + + protected override void SignMuCore(ReadOnlySpan externalMu, Span destination) + { + Debug.Fail("Caller should have checked platform availability."); + throw new PlatformNotSupportedException(); + } + + protected override bool VerifyMuCore(ReadOnlySpan externalMu, ReadOnlySpan signature) + { + Debug.Fail("Caller should have checked platform availability."); + throw new PlatformNotSupportedException(); + } + protected override void ExportMLDsaPublicKeyCore(Span destination) { Debug.Fail("Caller should have checked platform availability."); throw new PlatformNotSupportedException(); } - protected override void ExportMLDsaSecretKeyCore(Span destination) + protected override void ExportMLDsaPrivateKeyCore(Span destination) { Debug.Fail("Caller should have checked platform availability."); throw new PlatformNotSupportedException(); diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaOpenSsl.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaOpenSsl.OpenSsl.cs index fb39868c21d33f..da46f0a20bc2f4 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaOpenSsl.OpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaOpenSsl.OpenSsl.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.Versioning; +using Internal.Cryptography; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography @@ -20,7 +21,7 @@ private static partial MLDsaAlgorithm AlgorithmFromHandle( SafeEvpPKeyHandle pkeyHandle, out SafeEvpPKeyHandle upRefHandle, out bool hasSeed, - out bool hasSecretKey) + out bool hasPrivateKey) { ArgumentNullException.ThrowIfNull(pkeyHandle); @@ -36,7 +37,7 @@ private static partial MLDsaAlgorithm AlgorithmFromHandle( Interop.Crypto.PalMLDsaAlgorithmId mldsaId = Interop.Crypto.MLDsaGetPalId( upRefHandle, out hasSeed, - out hasSecretKey); + out hasPrivateKey); switch (mldsaId) { @@ -76,16 +77,48 @@ protected override void SignDataCore(ReadOnlySpan data, ReadOnlySpan protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => Interop.Crypto.MLDsaVerifyPure(_key, data, context, signature); + /// + protected override void SignPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => + Helpers.MLDsaPreHash( + hash, + context, + hashAlgorithmOid, + _key, + destination, + static (key, encodedMessage, destination) => + { + Interop.Crypto.MLDsaSignPreEncoded(key, encodedMessage, destination); + return true; + }); + + /// + protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => + Helpers.MLDsaPreHash( + hash, + context, + hashAlgorithmOid, + _key, + signature, + static (key, encodedMessage, signature) => Interop.Crypto.MLDsaVerifyPreEncoded(key, encodedMessage, signature)); + + /// + protected override void SignMuCore(ReadOnlySpan externalMu, Span destination) => + Interop.Crypto.MLDsaSignExternalMu(_key, externalMu, destination); + + /// + protected override bool VerifyMuCore(ReadOnlySpan externalMu, ReadOnlySpan signature) => + Interop.Crypto.MLDsaVerifyExternalMu(_key, externalMu, signature); + /// protected override void ExportMLDsaPublicKeyCore(Span destination) => Interop.Crypto.MLDsaExportPublicKey(_key, destination); /// - protected override void ExportMLDsaSecretKeyCore(Span destination) + protected override void ExportMLDsaPrivateKeyCore(Span destination) { - if (!_hasSecretKey) + if (!_hasPrivateKey) { - throw new CryptographicException(SR.Cryptography_MLDsaNoSecretKey); + throw new CryptographicException(SR.Cryptography_NoPrivateKeyAvailable); } Interop.Crypto.MLDsaExportSecretKey(_key, destination); @@ -108,7 +141,7 @@ protected override bool TryExportPkcs8PrivateKeyCore(Span destination, out return MLDsaPkcs8.TryExportPkcs8PrivateKey( this, _hasSeed, - _hasSecretKey, + _hasPrivateKey, destination, out bytesWritten); } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaOpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaOpenSsl.cs index add13a5621e672..03c24a90fa4b1d 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaOpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLDsaOpenSsl.cs @@ -25,7 +25,7 @@ public sealed partial class MLDsaOpenSsl : MLDsa { private SafeEvpPKeyHandle _key; private bool _hasSeed; - private bool _hasSecretKey; + private bool _hasPrivateKey; /// /// Initializes a new instance of the class from an existing OpenSSL key @@ -52,18 +52,18 @@ public sealed partial class MLDsaOpenSsl : MLDsa [UnsupportedOSPlatform("tvos")] [UnsupportedOSPlatform("windows")] public MLDsaOpenSsl(SafeEvpPKeyHandle pkeyHandle) - : base(AlgorithmFromHandle(pkeyHandle, out SafeEvpPKeyHandle upRefHandle, out bool hasSeed, out bool hasSecretKey)) + : base(AlgorithmFromHandle(pkeyHandle, out SafeEvpPKeyHandle upRefHandle, out bool hasSeed, out bool hasPrivateKey)) { _key = upRefHandle; _hasSeed = hasSeed; - _hasSecretKey = hasSecretKey; + _hasPrivateKey = hasPrivateKey; } private static partial MLDsaAlgorithm AlgorithmFromHandle( SafeEvpPKeyHandle pkeyHandle, out SafeEvpPKeyHandle upRefHandle, out bool hasSeed, - out bool hasSecretKey); + out bool hasPrivateKey); /// /// Gets a representation of the cryptographic key. diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLKemOpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLKemOpenSsl.cs index 2cc2f37afbbb26..85829d67b4ba5b 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLKemOpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MLKemOpenSsl.cs @@ -20,7 +20,6 @@ namespace System.Security.Cryptography /// cryptographic libraries. /// /// - [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public sealed partial class MLKemOpenSsl : MLKem { private readonly SafeEvpPKeyHandle _key; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs index e653c0fc268361..e9454c4f76a7f6 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs @@ -929,36 +929,15 @@ public virtual unsafe void ImportRSAPrivateKey(ReadOnlySpan source, out in out _, out int firstValueLength); - fixed (byte* ptr = &MemoryMarshal.GetReference(source)) - { - using (MemoryManager manager = new PointerMemoryManager(ptr, firstValueLength)) - { - ReadOnlyMemory firstValue = manager.Memory; - int localRead = firstValue.Length; - - AlgorithmIdentifierAsn ignored = default; - RSAKeyFormatHelper.FromPkcs1PrivateKey(firstValue, ignored, out RSAParameters rsaParameters); - - fixed (byte* dPin = rsaParameters.D) - fixed (byte* pPin = rsaParameters.P) - fixed (byte* qPin = rsaParameters.Q) - fixed (byte* dpPin = rsaParameters.DP) - fixed (byte* dqPin = rsaParameters.DQ) - fixed (byte* qInvPin = rsaParameters.InverseQ) + RSAKeyFormatHelper.FromPkcs1PrivateKey( + source.Slice(0, firstValueLength), + rsaParameters => { - try - { - ImportParameters(rsaParameters); - } - finally - { - ClearPrivateParameters(rsaParameters); - } - } + ImportParameters(rsaParameters); + return true; + }); - bytesRead = localRead; - } - } + bytesRead = firstValueLength; } catch (AsnContentException e) { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAWrapper.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAWrapper.cs index 3debf421e6022d..719e8518a35de6 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAWrapper.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAWrapper.cs @@ -215,10 +215,6 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } - public override bool Equals(object? obj) => _wrapped.Equals(obj); - - public override int GetHashCode() => _wrapped.GetHashCode(); - public override string ToString() => _wrapped.ToString()!; } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SlhDsaImplementation.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SlhDsaImplementation.OpenSsl.cs index 773d7b5eb5ee29..37a9c776e2c16d 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SlhDsaImplementation.OpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SlhDsaImplementation.OpenSsl.cs @@ -91,7 +91,7 @@ protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan< protected override void ExportSlhDsaPublicKeyCore(Span destination) => Interop.Crypto.SlhDsaExportPublicKey(_key, destination); - protected override void ExportSlhDsaSecretKeyCore(Span destination) => + protected override void ExportSlhDsaPrivateKeyCore(Span destination) => Interop.Crypto.SlhDsaExportSecretKey(_key, destination); internal static partial SlhDsaImplementation ImportPublicKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) @@ -104,9 +104,9 @@ internal static partial SlhDsaImplementation ImportPublicKey(SlhDsaAlgorithm alg internal static partial SlhDsaImplementation ImportPkcs8PrivateKeyValue(SlhDsaAlgorithm algorithm, ReadOnlySpan source) => throw new PlatformNotSupportedException(); - internal static partial SlhDsaImplementation ImportSecretKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) + internal static partial SlhDsaImplementation ImportPrivateKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) { - Debug.Assert(source.Length == algorithm.SecretKeySizeInBytes, $"Secret key was expected to be {algorithm.SecretKeySizeInBytes} bytes, but was {source.Length} bytes."); + Debug.Assert(source.Length == algorithm.PrivateKeySizeInBytes, $"Private key was expected to be {algorithm.PrivateKeySizeInBytes} bytes, but was {source.Length} bytes."); SafeEvpPKeyHandle key = Interop.Crypto.EvpPKeyFromData(algorithm.Name, source, privateKey: true); return new SlhDsaImplementation(algorithm, key); } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SlhDsaOpenSsl.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SlhDsaOpenSsl.NotSupported.cs index ae0a6ef5a8df88..402b9b5e31cab1 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SlhDsaOpenSsl.NotSupported.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SlhDsaOpenSsl.NotSupported.cs @@ -54,7 +54,7 @@ protected override void ExportSlhDsaPublicKeyCore(Span destination) throw new PlatformNotSupportedException(); } - protected override void ExportSlhDsaSecretKeyCore(Span destination) + protected override void ExportSlhDsaPrivateKeyCore(Span destination) { Debug.Fail("Caller should have checked platform availability."); throw new PlatformNotSupportedException(); diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SlhDsaOpenSsl.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SlhDsaOpenSsl.OpenSsl.cs index 36db28b7b8b175..52df64baf0b8c6 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SlhDsaOpenSsl.OpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SlhDsaOpenSsl.OpenSsl.cs @@ -111,7 +111,7 @@ protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan< protected override void ExportSlhDsaPublicKeyCore(Span destination) => Interop.Crypto.SlhDsaExportPublicKey(_key, destination); - protected override void ExportSlhDsaSecretKeyCore(Span destination) => + protected override void ExportSlhDsaPrivateKeyCore(Span destination) => Interop.Crypto.SlhDsaExportSecretKey(_key, destination); } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateHelpers.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateHelpers.Windows.cs new file mode 100644 index 00000000000000..dbb1edb37943b1 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateHelpers.Windows.cs @@ -0,0 +1,170 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Runtime.InteropServices; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; + +namespace System.Security.Cryptography.X509Certificates +{ + internal static partial class CertificateHelpers + { + private static partial CryptographicException GetExceptionForLastError() => + Marshal.GetLastPInvokeError().ToCryptographicException(); + + private static partial CertificatePal CopyFromRawBytes(CertificatePal certificate) => + (CertificatePal)CertificatePal.FromBlob(certificate.RawData, SafePasswordHandle.InvalidHandle, X509KeyStorageFlags.PersistKeySet); + + private static partial SafeNCryptKeyHandle CreateSafeNCryptKeyHandle(IntPtr handle, SafeHandle parentHandle) => + new SafeNCryptKeyHandle(handle, parentHandle); + + private static partial int GuessKeySpec( + CngProvider provider, + string keyName, + bool machineKey, + CngAlgorithmGroup? algorithmGroup) + { + if (provider == CngProvider.MicrosoftSoftwareKeyStorageProvider || + provider == CngProvider.MicrosoftSmartCardKeyStorageProvider) + { + // Well-known CNG providers, keySpec is 0. + return 0; + } + + try + { + CngKeyOpenOptions options = machineKey ? CngKeyOpenOptions.MachineKey : CngKeyOpenOptions.None; + + using (CngKey.Open(keyName, provider, options)) + { + // It opened with keySpec 0, so use keySpec 0. + return 0; + } + } + catch (CryptographicException) + { + // While NTE_BAD_KEYSET is what we generally expect here for RSA, on Windows 7 + // PROV_DSS produces NTE_BAD_PROV_TYPE, and PROV_DSS_DH produces NTE_NO_KEY. + // + // So we'll just try the CAPI fallback for any error code, and see what happens. + + CspParameters cspParameters = new CspParameters + { + ProviderName = provider.Provider, + KeyContainerName = keyName, + Flags = CspProviderFlags.UseExistingKey, + KeyNumber = (int)KeyNumber.Signature, + }; + + if (machineKey) + { + cspParameters.Flags |= CspProviderFlags.UseMachineKeyStore; + } + + if (TryGuessKeySpec(cspParameters, algorithmGroup, out int keySpec)) + { + return keySpec; + } + + throw; + } + } + + private static bool TryGuessKeySpec( + CspParameters cspParameters, + CngAlgorithmGroup? algorithmGroup, + out int keySpec) + { + if (algorithmGroup == CngAlgorithmGroup.Rsa) + { + return TryGuessRsaKeySpec(cspParameters, out keySpec); + } + + if (algorithmGroup == CngAlgorithmGroup.Dsa) + { + return TryGuessDsaKeySpec(cspParameters, out keySpec); + } + + keySpec = 0; + return false; + } + + private static bool TryGuessRsaKeySpec(CspParameters cspParameters, out int keySpec) + { + // Try the AT_SIGNATURE spot in each of the 4 RSA provider type values, + // ideally one of them will work. + const int PROV_RSA_FULL = 1; + const int PROV_RSA_SIG = 2; + const int PROV_RSA_SCHANNEL = 12; + const int PROV_RSA_AES = 24; + + // These are ordered in terms of perceived likeliness, given that the key + // is AT_SIGNATURE. + ReadOnlySpan provTypes = + [ + PROV_RSA_FULL, + PROV_RSA_AES, + PROV_RSA_SCHANNEL, + + // Nothing should be PROV_RSA_SIG, but if everything else has failed, + // just try this last thing. + PROV_RSA_SIG, + ]; + + foreach (int provType in provTypes) + { + cspParameters.ProviderType = provType; + + try + { + using (new RSACryptoServiceProvider(cspParameters)) + { + keySpec = cspParameters.KeyNumber; + return true; + } + } + catch (CryptographicException) + { + } + } + + Debug.Fail("RSA key did not open with KeyNumber 0 or AT_SIGNATURE"); + keySpec = 0; + return false; + } + + private static bool TryGuessDsaKeySpec(CspParameters cspParameters, out int keySpec) + { + const int PROV_DSS = 3; + const int PROV_DSS_DH = 13; + + ReadOnlySpan provTypes = + [ + PROV_DSS_DH, + PROV_DSS, + ]; + + foreach (int provType in provTypes) + { + cspParameters.ProviderType = provType; + + try + { + using (new DSACryptoServiceProvider(cspParameters)) + { + keySpec = cspParameters.KeyNumber; + return true; + } + } + catch (CryptographicException) + { + } + } + + Debug.Fail("DSA key did not open with KeyNumber 0 or AT_SIGNATURE"); + keySpec = 0; + return false; + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.PrivateKey.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.PrivateKey.cs index 867e3dc2de406f..89a528e5b121ad 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.PrivateKey.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.PrivateKey.cs @@ -192,48 +192,7 @@ public ICertificatePal CopyWithPrivateKey(ECDiffieHellman ecdh) } } - public ICertificatePal CopyWithPrivateKey(MLDsa privateKey) - { - if (privateKey is MLDsaCng mldsaCng) - { - CngKey key = mldsaCng.Key; - - ICertificatePal? clone = CopyWithPersistedCngKey(key); - - if (clone != null) - { - return clone; - } - } - - if (privateKey is MLDsaImplementation mldsaImplementation) - { - using (CngKey clonedKey = mldsaImplementation.CreateEphemeralCng()) - { - return CopyWithEphemeralKey(clonedKey); - } - } - - // MLDsaCng and third-party implementations can be copied by exporting the PKCS#8 and importing it into - // a new MLDsaCng. An alternative to PKCS#8 would be to try the private seed and fall back to secret key, - // but that potentially requires two calls and wouldn't allow implementations to do anything smarter internally. - // Blobs may also be an option for MLDsaCng, but for now we will stick with PKCS#8. - byte[] exportedPkcs8 = privateKey.ExportPkcs8PrivateKey(); - - using (PinAndClear.Track(exportedPkcs8)) - using (MLDsaCng clonedKey = MLDsaCng.ImportPkcs8PrivateKey(exportedPkcs8, out _)) - { - CngKey clonedCngKey = clonedKey.Key; - - if (clonedCngKey.AlgorithmGroup != CngAlgorithmGroup.MLDsa) - { - Debug.Fail($"{nameof(MLDsaCng)} should only give ML-DSA keys."); - throw new CryptographicException(); - } - - return CopyWithEphemeralKey(clonedCngKey); - } - } + public ICertificatePal CopyWithPrivateKey(MLDsa privateKey) => CertificateHelpers.CopyWithPrivateKey(this, privateKey); public ICertificatePal CopyWithPrivateKey(MLKem privateKey) { @@ -288,365 +247,6 @@ public ICertificatePal CopyWithPrivateKey(RSA rsa) } } - private T? GetPrivateKey(Func createCsp, Func createCng) - where T : class, IDisposable - { - using (SafeCertContextHandle certContext = GetCertContext()) - { - SafeNCryptKeyHandle? ncryptKey = TryAcquireCngPrivateKey(certContext, out CngKeyHandleOpenOptions cngHandleOptions); - if (ncryptKey != null) - { - CngKey cngKey = CngKey.OpenNoDuplicate(ncryptKey, cngHandleOptions); - T? result = createCng(cngKey); - - // Dispose of cngKey if its ownership did not transfer to the underlying algorithm. - if (result is null) - { - cngKey.Dispose(); - } - - return result; - } - } - - CspParameters? cspParameters = GetPrivateKeyCsp(); - if (cspParameters == null) - return null; - - if (cspParameters.ProviderType == 0) - { - // ProviderType being 0 signifies that this is actually a CNG key, not a CAPI key. Crypt32.dll stuffs the CNG Key Storage Provider - // name into CRYPT_KEY_PROV_INFO->ProviderName, and the CNG key name into CRYPT_KEY_PROV_INFO->KeyContainerName. - - string keyStorageProvider = cspParameters.ProviderName!; - string keyName = cspParameters.KeyContainerName!; - CngKey cngKey = CngKey.Open(keyName, new CngProvider(keyStorageProvider)); - return createCng(cngKey); - } - else - { - // ProviderType being non-zero signifies that this is a CAPI key. - // We never want to stomp over certificate private keys. - cspParameters.Flags |= CspProviderFlags.UseExistingKey; - return createCsp(cspParameters); - } - } - - private static SafeNCryptKeyHandle? TryAcquireCngPrivateKey( - SafeCertContextHandle certificateContext, - out CngKeyHandleOpenOptions handleOptions) - { - Debug.Assert(certificateContext != null); - Debug.Assert(!certificateContext.IsClosed && !certificateContext.IsInvalid); - - IntPtr privateKeyPtr; - - // If the certificate has a key handle without a key prov info, return the - // ephemeral key - if (!certificateContext.HasPersistedPrivateKey) - { - int cbData = IntPtr.Size; - - if (Interop.Crypt32.CertGetCertificateContextProperty( - certificateContext, - Interop.Crypt32.CertContextPropId.CERT_NCRYPT_KEY_HANDLE_PROP_ID, - out privateKeyPtr, - ref cbData)) - { - handleOptions = CngKeyHandleOpenOptions.EphemeralKey; - return new SafeNCryptKeyHandle(privateKeyPtr, certificateContext); - } - } - - bool freeKey = true; - SafeNCryptKeyHandle? privateKey = null; - handleOptions = CngKeyHandleOpenOptions.None; - try - { - int keySpec = 0; - if (!Interop.crypt32.CryptAcquireCertificatePrivateKey( - certificateContext, - Interop.Crypt32.CryptAcquireCertificatePrivateKeyFlags.CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, - IntPtr.Zero, - out privateKey, - out keySpec, - out freeKey)) - { - - // The documentation for CryptAcquireCertificatePrivateKey says that freeKey - // should already be false if "key acquisition fails", and it can be presumed - // that privateKey was set to 0. But, just in case: - freeKey = false; - privateKey?.SetHandleAsInvalid(); - return null; - } - - // It is very unlikely that Windows will tell us !freeKey other than when reporting failure, - // because we set neither CRYPT_ACQUIRE_CACHE_FLAG nor CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, which are - // currently the only two success situations documented. However, any !freeKey response means the - // key's lifetime is tied to that of the certificate, so re-register the handle as a child handle - // of the certificate. - if (!freeKey && privateKey != null && !privateKey.IsInvalid) - { - var newKeyHandle = new SafeNCryptKeyHandle(privateKey.DangerousGetHandle(), certificateContext); - privateKey.SetHandleAsInvalid(); - privateKey = newKeyHandle; - freeKey = true; - } - - return privateKey; - } - catch - { - // If we aren't supposed to free the key, and we're not returning it, - // just tell the SafeHandle to not free itself. - if (privateKey != null && !freeKey) - { - privateKey.SetHandleAsInvalid(); - } - - throw; - } - } - - // - // Returns the private key referenced by a store certificate. Note that despite the return type being declared "CspParameters", - // the key can actually be a CNG key. To distinguish, examine the ProviderType property. If it is 0, this key is a CNG key with - // the various properties of CspParameters being "repurposed" into storing CNG info. - // - // This is a behavior this method inherits directly from the Crypt32 CRYPT_KEY_PROV_INFO semantics. - // - // It would have been nice not to let this ugliness escape out of this helper method. But X509Certificate2.ToString() calls this - // method too so we cannot just change it without breaking its output. - // - private CspParameters? GetPrivateKeyCsp() - { - int cbData = 0; - if (!Interop.Crypt32.CertGetCertificateContextProperty(_certContext, Interop.Crypt32.CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, null, ref cbData)) - { - int dwErrorCode = Marshal.GetLastPInvokeError(); - if (dwErrorCode == ErrorCode.CRYPT_E_NOT_FOUND) - return null; - throw dwErrorCode.ToCryptographicException(); - } - - unsafe - { - byte[] privateKey = new byte[cbData]; - fixed (byte* pPrivateKey = privateKey) - { - if (!Interop.Crypt32.CertGetCertificateContextProperty(_certContext, Interop.Crypt32.CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, privateKey, ref cbData)) - throw Marshal.GetLastPInvokeError().ToCryptographicException(); - Interop.Crypt32.CRYPT_KEY_PROV_INFO* pKeyProvInfo = (Interop.Crypt32.CRYPT_KEY_PROV_INFO*)pPrivateKey; - - CspParameters cspParameters = new CspParameters(); - cspParameters.ProviderName = Marshal.PtrToStringUni((IntPtr)(pKeyProvInfo->pwszProvName)); - cspParameters.KeyContainerName = Marshal.PtrToStringUni((IntPtr)(pKeyProvInfo->pwszContainerName)); - cspParameters.ProviderType = pKeyProvInfo->dwProvType; - cspParameters.KeyNumber = pKeyProvInfo->dwKeySpec; - cspParameters.Flags = (CspProviderFlags)((pKeyProvInfo->dwFlags & Interop.Crypt32.CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET) == Interop.Crypt32.CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET ? CspProviderFlags.UseMachineKeyStore : 0); - return cspParameters; - } - } - } - - private unsafe CertificatePal? CopyWithPersistedCngKey(CngKey cngKey) - { - if (string.IsNullOrEmpty(cngKey.KeyName)) - { - return null; - } - - // Make a new pal from bytes. - CertificatePal pal = (CertificatePal)FromBlob(RawData, SafePasswordHandle.InvalidHandle, X509KeyStorageFlags.PersistKeySet); - - CngProvider provider = cngKey.Provider!; - string keyName = cngKey.KeyName; - bool machineKey = cngKey.IsMachineKey; - - // CAPI RSA_SIGN keys won't open correctly under CNG without the key number being specified, so - // check to see if we can figure out what key number it needs to re-open. - int keySpec = GuessKeySpec(provider, keyName, machineKey, cngKey.AlgorithmGroup); - - Interop.Crypt32.CRYPT_KEY_PROV_INFO keyProvInfo = default; - - fixed (char* keyNamePtr = cngKey.KeyName) - fixed (char* provNamePtr = cngKey.Provider!.Provider) - { - keyProvInfo.pwszContainerName = keyNamePtr; - keyProvInfo.pwszProvName = provNamePtr; - keyProvInfo.dwFlags = machineKey ? Interop.Crypt32.CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET : 0; - keyProvInfo.dwKeySpec = keySpec; - - if (!Interop.Crypt32.CertSetCertificateContextProperty( - pal._certContext, - Interop.Crypt32.CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, - Interop.Crypt32.CertSetPropertyFlags.None, - &keyProvInfo)) - { - Exception e = Marshal.GetLastPInvokeError().ToCryptographicException(); - pal.Dispose(); - throw e; - } - } - - return pal; - } - - private static int GuessKeySpec( - CngProvider provider, - string keyName, - bool machineKey, - CngAlgorithmGroup? algorithmGroup) - { - if (provider == CngProvider.MicrosoftSoftwareKeyStorageProvider || - provider == CngProvider.MicrosoftSmartCardKeyStorageProvider) - { - // Well-known CNG providers, keySpec is 0. - return 0; - } - - try - { - CngKeyOpenOptions options = machineKey ? CngKeyOpenOptions.MachineKey : CngKeyOpenOptions.None; - - using (CngKey.Open(keyName, provider, options)) - { - // It opened with keySpec 0, so use keySpec 0. - return 0; - } - } - catch (CryptographicException) - { - // While NTE_BAD_KEYSET is what we generally expect here for RSA, on Windows 7 - // PROV_DSS produces NTE_BAD_PROV_TYPE, and PROV_DSS_DH produces NTE_NO_KEY. - // - // So we'll just try the CAPI fallback for any error code, and see what happens. - - CspParameters cspParameters = new CspParameters - { - ProviderName = provider.Provider, - KeyContainerName = keyName, - Flags = CspProviderFlags.UseExistingKey, - KeyNumber = (int)KeyNumber.Signature, - }; - - if (machineKey) - { - cspParameters.Flags |= CspProviderFlags.UseMachineKeyStore; - } - - int keySpec; - - if (TryGuessKeySpec(cspParameters, algorithmGroup, out keySpec)) - { - return keySpec; - } - - throw; - } - } - - private static bool TryGuessKeySpec( - CspParameters cspParameters, - CngAlgorithmGroup? algorithmGroup, - out int keySpec) - { - if (algorithmGroup == CngAlgorithmGroup.Rsa) - { - return TryGuessRsaKeySpec(cspParameters, out keySpec); - } - - if (algorithmGroup == CngAlgorithmGroup.Dsa) - { - return TryGuessDsaKeySpec(cspParameters, out keySpec); - } - - keySpec = 0; - return false; - } - - private static bool TryGuessRsaKeySpec(CspParameters cspParameters, out int keySpec) - { - // Try the AT_SIGNATURE spot in each of the 4 RSA provider type values, - // ideally one of them will work. - const int PROV_RSA_FULL = 1; - const int PROV_RSA_SIG = 2; - const int PROV_RSA_SCHANNEL = 12; - const int PROV_RSA_AES = 24; - - // These are ordered in terms of perceived likeliness, given that the key - // is AT_SIGNATURE. - int[] provTypes = - { - PROV_RSA_FULL, - PROV_RSA_AES, - PROV_RSA_SCHANNEL, - - // Nothing should be PROV_RSA_SIG, but if everything else has failed, - // just try this last thing. - PROV_RSA_SIG, - }; - - foreach (int provType in provTypes) - { - cspParameters.ProviderType = provType; - - try - { - using (new RSACryptoServiceProvider(cspParameters)) - { - { - keySpec = cspParameters.KeyNumber; - return true; - } - } - } - catch (CryptographicException) - { - } - } - - Debug.Fail("RSA key did not open with KeyNumber 0 or AT_SIGNATURE"); - keySpec = 0; - return false; - } - - private static bool TryGuessDsaKeySpec(CspParameters cspParameters, out int keySpec) - { - const int PROV_DSS = 3; - const int PROV_DSS_DH = 13; - - int[] provTypes = - { - PROV_DSS_DH, - PROV_DSS, - }; - - foreach (int provType in provTypes) - { - cspParameters.ProviderType = provType; - - try - { - using (new DSACryptoServiceProvider(cspParameters)) - { - { - keySpec = cspParameters.KeyNumber; - return true; - } - } - } - catch (CryptographicException) - { - } - } - - Debug.Fail("DSA key did not open with KeyNumber 0 or AT_SIGNATURE"); - keySpec = 0; - return false; - } - private unsafe CertificatePal? CopyWithPersistedCapiKey(CspKeyContainerInfo keyContainerInfo) { if (string.IsNullOrEmpty(keyContainerInfo.KeyContainerName)) @@ -682,39 +282,14 @@ private static bool TryGuessDsaKeySpec(CspParameters cspParameters, out int keyS return pal; } - private CertificatePal CopyWithEphemeralKey(CngKey cngKey) + private T? GetPrivateKey(Func createCsp, Func createCng) + where T : class, IDisposable { - Debug.Assert(string.IsNullOrEmpty(cngKey.KeyName)); - - // Handle makes a copy of the handle. This is required given that CertSetCertificateContextProperty accepts a SafeHandle - // and transfers ownership of the handle to the certificate. We can't transfer that ownership out of the cngKey, as it's - // owned by the caller, so we make a copy (using Handle rather than HandleNoDuplicate). - using (SafeNCryptKeyHandle handle = cngKey.Handle) - { - // Make a new pal from bytes. - CertificatePal pal = (CertificatePal)FromBlob(RawData, SafePasswordHandle.InvalidHandle, X509KeyStorageFlags.PersistKeySet); - try - { - if (!Interop.Crypt32.CertSetCertificateContextProperty( - pal._certContext, - Interop.Crypt32.CertContextPropId.CERT_NCRYPT_KEY_HANDLE_PROP_ID, - Interop.Crypt32.CertSetPropertyFlags.CERT_SET_PROPERTY_INHIBIT_PERSIST_FLAG, - handle)) - { - throw Marshal.GetLastPInvokeError().ToCryptographicException(); - } - - // The value was transferred to the certificate. - handle.SetHandleAsInvalid(); - - return pal; - } - catch - { - pal.Dispose(); - throw; - } - } + return CertificateHelpers.GetPrivateKey(this, createCsp, createCng); } + + private CertificatePal? CopyWithPersistedCngKey(CngKey cngKey) => CertificateHelpers.CopyWithPersistedCngKey(this, cngKey); + + private CertificatePal CopyWithEphemeralKey(CngKey cngKey) => CertificateHelpers.CopyWithEphemeralKey(this, cngKey); } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs index 1910b44f397b76..e99cc60db45cc9 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs @@ -418,7 +418,7 @@ public void AppendPrivateKeyInfo(StringBuilder sb) CspKeyContainerInfo? cspKeyContainerInfo = null; try { - CspParameters? parameters = GetPrivateKeyCsp(); + CspParameters? parameters = CertificateHelpers.GetPrivateKeyCsp(_certContext); if (parameters != null) { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateRequest.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateRequest.cs index 28d07f1e26d075..3b021b2e6ead09 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateRequest.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateRequest.cs @@ -291,6 +291,54 @@ public CertificateRequest( PublicKey = _generator.PublicKey; } + /// + /// Create a CertificateRequest for the specified subject name and Composite ML-DSA key. + /// + /// + /// The parsed representation of the subject name for the certificate or certificate request. + /// + /// + /// A Composite ML-DSA key whose public key material will be included in the certificate or certificate request. + /// This key will be used as a private key if is called. + /// + /// + /// or is . + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public CertificateRequest( + string subjectName, + CompositeMLDsa key) + { + ArgumentNullException.ThrowIfNull(subjectName); + ArgumentNullException.ThrowIfNull(key); + + throw new PlatformNotSupportedException(); + } + + /// + /// Create a CertificateRequest for the specified subject name and Composite ML-DSA key. + /// + /// + /// The parsed representation of the subject name for the certificate or certificate request. + /// + /// + /// A Composite ML-DSA key whose public key material will be included in the certificate or certificate request. + /// This key will be used as a private key if is called. + /// + /// + /// or is . + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public CertificateRequest( + X500DistinguishedName subjectName, + CompositeMLDsa key) + { + ArgumentNullException.ThrowIfNull(subjectName); + ArgumentNullException.ThrowIfNull(key); + + throw new PlatformNotSupportedException(); + } + /// /// Create a CertificateRequest for the specified subject name, encoded public key, and hash algorithm. /// diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/PublicKey.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/PublicKey.cs index 5acedece549abb..fd9c92a2f77ca8 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/PublicKey.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/PublicKey.cs @@ -108,6 +108,23 @@ public PublicKey(SlhDsa key) : this(key.ExportSubjectPublicKeyInfo()) { } + /// + /// Initializes a new instance of the class + /// using SubjectPublicKeyInfo from an . + /// + /// + /// An key to obtain the SubjectPublicKeyInfo from. + /// + /// + /// The SubjectPublicKeyInfo could not be decoded. The + /// must return a + /// valid ASN.1-DER encoded X.509 SubjectPublicKeyInfo. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId)] + public PublicKey(CompositeMLDsa key) : this(key.ExportSubjectPublicKeyInfo()) + { + } + private PublicKey(byte[] subjectPublicKeyInfo) { DecodeSubjectPublicKeyInfo( @@ -394,6 +411,29 @@ public static PublicKey CreateFromSubjectPublicKeyInfo(ReadOnlySpan source ? EncodeSubjectPublicKeyInfo().Encode(SlhDsa.ImportSubjectPublicKeyInfo) : null; + /// + /// Gets the public key, or + /// if the key is not a Composite ML-DSA key. + /// + /// + /// The public key, or if the key is not a Composite ML-DSA key. + /// + /// + /// The object represents a Composite ML-DSA public key, but the platform does not support the algorithm. + /// + /// + /// The key contents are corrupt or could not be read successfully. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + [UnsupportedOSPlatform("browser")] + public CompositeMLDsa? GetCompositeMLDsaPublicKey() + { + if (CompositeMLDsaAlgorithm.GetAlgorithmFromOid(_oid.Value) is null) + return null; + + return EncodeSubjectPublicKeyInfo().Encode(CompositeMLDsa.ImportSubjectPublicKeyInfo); + } + internal AsnWriter EncodeSubjectPublicKeyInfo() { SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs index ecd9cd58095cf8..d2b9b688e5d449 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs @@ -865,12 +865,16 @@ public X509Certificate2 CopyWithPrivateKey(MLKem privateKey) throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); } - byte[] pk1 = publicKey.ExportEncapsulationKey(); - byte[] pk2 = privateKey.ExportEncapsulationKey(); - - if (!pk1.AsSpan().SequenceEqual(pk2)) + using (CryptoPoolLease pk1 = CryptoPoolLease.Rent(publicKey.Algorithm.EncapsulationKeySizeInBytes, skipClear: true)) + using (CryptoPoolLease pk2 = CryptoPoolLease.Rent(publicKey.Algorithm.EncapsulationKeySizeInBytes, skipClear: true)) { - throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); + publicKey.ExportEncapsulationKey(pk1.Span); + privateKey.ExportEncapsulationKey(pk2.Span); + + if (!pk1.Span.SequenceEqual(pk2.Span)) + { + throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); + } } } @@ -966,12 +970,16 @@ public X509Certificate2 CopyWithPrivateKey(MLDsa privateKey) throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); } - byte[] pk1 = publicKey.ExportMLDsaPublicKey(); - byte[] pk2 = privateKey.ExportMLDsaPublicKey(); - - if (pk1.Length != pk2.Length || !pk1.AsSpan().SequenceEqual(pk2)) + using (CryptoPoolLease pk1 = CryptoPoolLease.Rent(publicKey.Algorithm.PublicKeySizeInBytes, skipClear: true)) + using (CryptoPoolLease pk2 = CryptoPoolLease.Rent(publicKey.Algorithm.PublicKeySizeInBytes, skipClear: true)) { - throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); + publicKey.ExportMLDsaPublicKey(pk1.Span); + privateKey.ExportMLDsaPublicKey(pk2.Span); + + if (!pk1.Span.SequenceEqual(pk2.Span)) + { + throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); + } } } @@ -1058,10 +1066,17 @@ public X509Certificate2 CopyWithPrivateKey(SlhDsa privateKey) throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); } - byte[] pk1 = publicKey.ExportSlhDsaPublicKey(); - byte[] pk2 = privateKey.ExportSlhDsaPublicKey(); + const int MaxPublicKeySize = 64; + Debug.Assert(publicKey.Algorithm.PublicKeySizeInBytes <= MaxPublicKeySize); + + Span publicKeysBuffer = stackalloc byte[MaxPublicKeySize * 2]; + Span pk1 = publicKeysBuffer.Slice(0, publicKey.Algorithm.PublicKeySizeInBytes); + Span pk2 = publicKeysBuffer.Slice(pk1.Length, publicKey.Algorithm.PublicKeySizeInBytes); + + publicKey.ExportSlhDsaPublicKey(pk1); + privateKey.ExportSlhDsaPublicKey(pk2); - if (!pk1.AsSpan().SequenceEqual(pk2)) + if (!pk1.SequenceEqual(pk2)) { throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); } @@ -1071,6 +1086,108 @@ public X509Certificate2 CopyWithPrivateKey(SlhDsa privateKey) return new X509Certificate2(pal); } + /// + /// Gets the public key from this certificate. + /// + /// + /// The public key, or if this certificate does not have a Composite ML-DSA public key. + /// + /// + /// The certificate has a Composite ML-DSA public key, but the platform does not support Composite ML-DSA. + /// + /// + /// The public key was invalid, or otherwise could not be imported. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public CompositeMLDsa? GetCompositeMLDsaPublicKey() + { + if (CompositeMLDsaAlgorithm.GetAlgorithmFromOid(GetKeyAlgorithm()) is null) + { + return null; + } + + Debug.Assert(!OperatingSystem.IsBrowser()); + return PublicKey.GetCompositeMLDsaPublicKey(); + } + + /// + /// Gets the private key from this certificate. + /// + /// + /// The private key, or if this certificate does not have a Composite ML-DSA private key. + /// + /// + /// Retrieving a Composite ML-DSA private key from a certificate is not supported on this platform. + /// + /// + /// An error occurred accessing the private key. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public CompositeMLDsa? GetCompositeMLDsaPrivateKey() + { + if (CompositeMLDsaAlgorithm.GetAlgorithmFromOid(GetKeyAlgorithm()) is null) + { + return null; + } + + throw new PlatformNotSupportedException(); + } + + /// + /// Combines a private key with a certificate containing the associated public key into a + /// new instance that can access the private key. + /// + /// + /// The Composite ML-DSA private key that corresponds to the Composite ML-DSA public key in this certificate. + /// + /// + /// A new certificate with the property set to . + /// The current certificate isn't modified. + /// + /// + /// is . + /// + /// + /// The specified private key doesn't match the public key for this certificate. + /// + /// + /// The certificate already has an associated private key. + /// + /// + /// Combining a certificate and a Composite ML-DSA private key is not supported on this platform. + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public X509Certificate2 CopyWithPrivateKey(CompositeMLDsa privateKey) + { + ArgumentNullException.ThrowIfNull(privateKey); + + if (HasPrivateKey) + throw new InvalidOperationException(SR.Cryptography_Cert_AlreadyHasPrivateKey); + + using (CompositeMLDsa? publicKey = GetCompositeMLDsaPublicKey()) + { + if (publicKey is null) + { + throw new ArgumentException(SR.Cryptography_PrivateKey_WrongAlgorithm); + } + + if (publicKey.Algorithm != privateKey.Algorithm) + { + throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); + } + + byte[] pk1 = publicKey.ExportCompositeMLDsaPublicKey(); + byte[] pk2 = privateKey.ExportCompositeMLDsaPublicKey(); + + if (!pk1.SequenceEqual(pk2)) + { + throw new ArgumentException(SR.Cryptography_PrivateKey_DoesNotMatch, nameof(privateKey)); + } + } + + throw new PlatformNotSupportedException(); + } + /// /// Creates a new X509 certificate from the file contents of an RFC 7468 PEM-encoded /// certificate and private key. diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SignatureGenerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SignatureGenerator.cs index 3d4e1b9763eed6..065330f56864d6 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SignatureGenerator.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SignatureGenerator.cs @@ -74,5 +74,25 @@ public static X509SignatureGenerator CreateForSlhDsa(SlhDsa key) return new SlhDsaX509SignatureGenerator(key); } + + /// + /// Creates a signature generator for Composite ML-DSA signatures using the specified key. + /// + /// + /// The private key. + /// + /// + /// An object for Composite ML-DSA signatures. + /// + /// + /// is . + /// + [Experimental(Experimentals.PostQuantumCryptographyDiagId, UrlFormat = Experimentals.SharedUrlFormat)] + public static X509SignatureGenerator CreateForCompositeMLDsa(CompositeMLDsa key) + { + ArgumentNullException.ThrowIfNull(key); + + throw new PlatformNotSupportedException(); + } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SubjectAlternativeNameExtension.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SubjectAlternativeNameExtension.cs index c6781214acc9c9..61dd5c2a8ed252 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SubjectAlternativeNameExtension.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SubjectAlternativeNameExtension.cs @@ -9,33 +9,57 @@ namespace System.Security.Cryptography.X509Certificates { + /// + /// Represents the Subject Alternative Name X.509 Extension (2.5.29.17). + /// public sealed class X509SubjectAlternativeNameExtension : X509Extension { private List? _decoded; + /// + /// Initializes a new instance of the class. + /// public X509SubjectAlternativeNameExtension() : base(Oids.SubjectAltNameOid) { _decoded = new List(0); } + /// + /// Initializes a new instance of the class from an encoded representation of the extension and an optional critical marker. + /// + /// The encoded data to use to create the extension. + /// if the extension is critical; otherwise, . The default is . public X509SubjectAlternativeNameExtension(byte[] rawData, bool critical = false) : base(Oids.SubjectAltNameOid, rawData, critical) { _decoded = Decode(RawData); } + /// + /// Initializes a new instance of the class from an encoded representation of the extension and an optional critical marker. + /// + /// The encoded data to use to create the extension. + /// if the extension is critical; otherwise, . The default is . public X509SubjectAlternativeNameExtension(ReadOnlySpan rawData, bool critical = false) : base(Oids.SubjectAltNameOid, rawData, critical) { _decoded = Decode(RawData); } + /// + /// Copies the extension properties of the specified object. + /// + /// The object whose extension properties to copy. public override void CopyFrom(AsnEncodedData asnEncodedData) { base.CopyFrom(asnEncodedData); _decoded = null; } + /// + /// Enumerates the alternative name entries with a DNS Name type identifier. + /// + /// An enumerable collection of alternative names with DNS Name type identifiers. public IEnumerable EnumerateDnsNames() { List decoded = (_decoded ??= Decode(RawData)); @@ -54,6 +78,10 @@ private static IEnumerable EnumerateDnsNames(List decode } } + /// + /// Enumerates the alternative name entries with an IP Address type identifier. + /// + /// An enumerable collection of alternative names with IP Address type identifiers. public IEnumerable EnumerateIPAddresses() { List decoded = (_decoded ??= Decode(RawData)); diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Unix.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Unix.cs index 77c32104f2d575..c6fe568486c0bf 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Unix.cs @@ -25,7 +25,7 @@ public bool ExplicitCurvesSupported { get { - if (PlatformDetection.IsApplePlatform || PlatformDetection.IsAzureLinux) + if (PlatformDetection.IsApplePlatform || PlatformDetection.IsSymCryptOpenSsl) { return false; } diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Unix.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Unix.cs index cec7aac4895ab5..11ea1c6d2d84fc 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Unix.cs @@ -25,7 +25,7 @@ public bool ExplicitCurvesSupported { get { - if (PlatformDetection.IsApplePlatform || PlatformDetection.IsAzureLinux) + if (PlatformDetection.IsApplePlatform || PlatformDetection.IsSymCryptOpenSsl) { return false; } diff --git a/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs b/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs index 882e7b6372de6f..460b81c9435727 100644 --- a/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HKDFTests.cs @@ -14,8 +14,8 @@ public abstract class HKDFTests protected abstract byte[] Expand(HashAlgorithmName hash, byte[] prk, int outputLength, byte[] info); protected abstract byte[] DeriveKey(HashAlgorithmName hash, byte[] ikm, int outputLength, byte[] salt, byte[] info); - internal static bool MD5Supported => !PlatformDetection.IsBrowser && !PlatformDetection.IsAzureLinux; - internal static bool EmptyKeysSupported => !PlatformDetection.IsAzureLinux; + internal static bool MD5Supported => !PlatformDetection.IsBrowser && !PlatformDetection.IsSymCryptOpenSsl; + internal static bool EmptyKeysSupported => !PlatformDetection.IsSymCryptOpenSsl; [Theory] [MemberData(nameof(GetHkdfTestCases))] diff --git a/src/libraries/System.Security.Cryptography/tests/HmacMD5Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacMD5Tests.cs index 1099b65976a2cf..740310b5b0aa28 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacMD5Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacMD5Tests.cs @@ -14,7 +14,7 @@ public class HmacMD5Tests : Rfc2202HmacTests { public sealed class Traits : IHmacTrait { - public static bool IsSupported => !PlatformDetection.IsAzureLinux && !PlatformDetection.IsBrowser; + public static bool IsSupported => !PlatformDetection.IsSymCryptOpenSsl && !PlatformDetection.IsBrowser; public static int HashSizeInBytes => HMACMD5.HashSizeInBytes; } diff --git a/src/libraries/System.Security.Cryptography/tests/KmacTestDriver.cs b/src/libraries/System.Security.Cryptography/tests/KmacTestDriver.cs index 4d7c10b317add9..50b79114590131 100644 --- a/src/libraries/System.Security.Cryptography/tests/KmacTestDriver.cs +++ b/src/libraries/System.Security.Cryptography/tests/KmacTestDriver.cs @@ -95,7 +95,7 @@ public abstract class KmacTestDriver public static bool IsSupported => TKmacTrait.IsSupported; public static bool IsNotSupported => !IsSupported; public static KeySizes? PlatformKeySizeRequirements { get; } = - PlatformDetection.IsOpenSslSupported && !PlatformDetection.IsAzureLinux ? new KeySizes(4, 512, 1) : null; + PlatformDetection.IsOpenSslSupported && !PlatformDetection.IsSymCryptOpenSsl ? new KeySizes(4, 512, 1) : null; public static int? PlatformMaxOutputSize { get; } = PlatformDetection.IsOpenSslSupported ? 0xFFFFFF / 8 : null; public static int? PlatformMaxCustomizationStringSize { get; } = PlatformDetection.IsOpenSslSupported ? 512 : null; diff --git a/src/libraries/System.Security.Cryptography/tests/MLDsaOpenSslTests.Unix.cs b/src/libraries/System.Security.Cryptography/tests/MLDsaOpenSslTests.Unix.cs index 8ad67d9a8963dc..1a714242ab7bba 100644 --- a/src/libraries/System.Security.Cryptography/tests/MLDsaOpenSslTests.Unix.cs +++ b/src/libraries/System.Security.Cryptography/tests/MLDsaOpenSslTests.Unix.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Test.Cryptography; using Xunit; namespace System.Security.Cryptography.Tests @@ -20,7 +21,7 @@ protected override MLDsa ImportPrivateSeed(MLDsaAlgorithm algorithm, ReadOnlySpa return new MLDsaOpenSsl(key); } - protected override MLDsa ImportSecretKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) + protected override MLDsa ImportPrivateKey(MLDsaAlgorithm algorithm, ReadOnlySpan source) { using SafeEvpPKeyHandle key = Interop.Crypto.EvpPKeyFromData(algorithm.Name, source, privateKey: true); return new MLDsaOpenSsl(key); @@ -119,8 +120,8 @@ private static void VerifyInstanceIsUsable(MLDsaOpenSsl mldsa) byte[] seed = mldsa.ExportMLDsaPrivateSeed(); Assert.Equal(mldsa.Algorithm.PrivateSeedSizeInBytes, seed.Length); - byte[] secretKey = mldsa.ExportMLDsaSecretKey(); - Assert.Equal(mldsa.Algorithm.SecretKeySizeInBytes, secretKey.Length); + byte[] privateKey = mldsa.ExportMLDsaPrivateKey(); + Assert.Equal(mldsa.Algorithm.PrivateKeySizeInBytes, privateKey.Length); // usable byte[] data = [ 1, 2, 3 ]; @@ -128,6 +129,11 @@ private static void VerifyInstanceIsUsable(MLDsaOpenSsl mldsa) byte[] signature = new byte[MLDsaAlgorithm.MLDsa44.SignatureSizeInBytes]; mldsa.SignData(data, signature, context); ExerciseSuccessfulVerify(mldsa, data, signature, context); + + byte[] hash = HashInfo.Sha256.GetHash(data); + signature.AsSpan().Fill(0); + mldsa.SignPreHash(hash.AsSpan(), signature, HashInfo.Sha256.Oid, context); + ExerciseSuccessfulVerifyPreHash(mldsa, HashInfo.Sha256.Oid, hash, signature, context); } } } diff --git a/src/libraries/System.Security.Cryptography/tests/RSACreateTests.cs b/src/libraries/System.Security.Cryptography/tests/RSACreateTests.cs index 8847051e6998d9..f5fc62b87c7e5f 100644 --- a/src/libraries/System.Security.Cryptography/tests/RSACreateTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/RSACreateTests.cs @@ -66,7 +66,7 @@ private static void CreateWithParameters(RSAParameters parameters) exportedPrivate = rsa.ExportParameters(true); } - ImportExport.AssertKeyEquals(parameters, exportedPrivate); + RSATestHelpers.AssertKeyEquals(parameters, exportedPrivate); } [Fact] diff --git a/src/libraries/System.Security.Cryptography/tests/SlhDsaOpenSslTests.cs b/src/libraries/System.Security.Cryptography/tests/SlhDsaOpenSslTests.cs index f1f959cd1719e0..07c45a3c12ad29 100644 --- a/src/libraries/System.Security.Cryptography/tests/SlhDsaOpenSslTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/SlhDsaOpenSslTests.cs @@ -75,7 +75,7 @@ public void SlhDsaOpenSsl_DuplicateKeyHandleLifetime() private static void VerifyInstanceIsUsable(SlhDsaOpenSsl slhDsa) { - _ = slhDsa.ExportSlhDsaSecretKey(); // does not throw + _ = slhDsa.ExportSlhDsaPrivateKey(); // does not throw // usable byte[] data = [1, 2, 3]; @@ -97,7 +97,7 @@ protected override SlhDsa ImportSlhDsaPublicKey(SlhDsaAlgorithm algorithm, ReadO return new SlhDsaOpenSsl(key); } - protected override SlhDsa ImportSlhDsaSecretKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) + protected override SlhDsa ImportSlhDsaPrivateKey(SlhDsaAlgorithm algorithm, ReadOnlySpan source) { using SafeEvpPKeyHandle key = Interop.Crypto.EvpPKeyFromData(algorithm.Name, source, privateKey: true); return new SlhDsaOpenSsl(key); diff --git a/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj b/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj index 6b8fd48ffe8652..12bdec3a60f84f 100644 --- a/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj +++ b/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj @@ -271,8 +271,22 @@ Link="CommonTest\System\Security\Cryptography\AlgorithmImplementations\AES\AesFactory.cs" /> + + + + + + + + + + + + + (() => certKey.SignData([1, 2, 3])); - } - - // Cert with private key - using (X509Certificate2 cert = LoadMLDsaIetfCertificateWithPrivateKey()) - using (MLDsa? certKey = GetMLDsaPublicKey(cert)) - { - Assert.NotNull(certKey); - byte[] publicKey = certKey.ExportMLDsaPublicKey(); - AssertExtensions.SequenceEqual(MLDsaTestsData.IetfMLDsa44.PublicKey, publicKey); - - // Verify the key is not actually private - Assert.ThrowsAny(() => certKey.SignData([1, 2, 3])); - } - } - - [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] - public static void GetMLDsaPrivateKeyTest() - { - // Cert without private key - using (X509Certificate2 cert = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) - { - using (MLDsa? certKey = GetMLDsaPrivateKey(cert)) - { - Assert.Null(certKey); - } - } - - // Cert with private key - using (X509Certificate2 certWithPrivateKey = LoadMLDsaIetfCertificateWithPrivateKey()) - { - using (MLDsa? certKey = GetMLDsaPrivateKey(certWithPrivateKey)) - { - Assert.NotNull(certKey); - - // Verify the key is actually private - byte[] privateSeed = certKey.ExportMLDsaPrivateSeed(); - AssertExtensions.SequenceEqual( - MLDsaTestsData.IetfMLDsa44.PrivateSeed, - privateSeed); - } - } - } - - [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] - public static void CheckCopyWithPrivateKey_MLDSA() - { - using (MLDsa privKey = MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa65)) - { - CertificateRequest req = new CertificateRequest($"CN={nameof(CheckCopyWithPrivateKey_MLDSA)}", privKey); - DateTimeOffset now = DateTimeOffset.UtcNow; - - X509Certificate2 pubOnly = req.Create( - req.SubjectName, - X509SignatureGenerator.CreateForMLDsa(privKey), - now.AddMinutes(-10), - now.AddMinutes(10), - new byte[] { 2, 4, 6, 8, 9, 7, 5, 3, 1 }); - - using (pubOnly) - using (X509Certificate2 wrongAlg = X509CertificateLoader.LoadCertificate(TestData.CertWithEnhancedKeyUsage)) - { - CheckCopyWithPrivateKey( - pubOnly, - wrongAlg, - privKey, - [ - () => MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa44), - () => MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa65), - () => MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa87), - ], - (cert, key) => cert.CopyWithPrivateKey(key), - cert => cert.GetMLDsaPublicKey(), - cert => cert.GetMLDsaPrivateKey(), - (priv, pub) => - { - byte[] data = new byte[RandomNumberGenerator.GetInt32(97)]; - RandomNumberGenerator.Fill(data); - - byte[] signature = priv.SignData(data); - Assert.True(pub.VerifyData(data, signature)); - }); - } - } - } - - [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] - public static void CheckCopyWithPrivateKey_MLDsa_OtherMLDsa_SecretKey() - { - using (X509Certificate2 pubOnly = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) - { - using (MLDsaTestImplementation publicMLDsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44)) - { - Exception e = new Exception("no secret key"); - - // The private key can be retrieved directly or from PKCS#8. If the seed is not available, - // it should fall back to the secret key. - publicMLDsa.TryExportPkcs8PrivateKeyHook = (_, out _) => throw e; - publicMLDsa.ExportMLDsaSecretKeyHook = _ => throw e; - publicMLDsa.ExportMLDsaPrivateSeedHook = _ => throw new CryptographicException("Should signal to try secret key"); - publicMLDsa.ExportMLDsaPublicKeyHook = (Span destination) => - MLDsaTestsData.IetfMLDsa44.PublicKey.CopyTo(destination); - - Assert.Same(e, AssertExtensions.Throws(() => CopyWithPrivateKey_MLDsa(pubOnly, publicMLDsa))); - } - - MLDsaTestImplementation privateMLDsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44); - privateMLDsa.ExportMLDsaPrivateSeedHook = _ => throw new CryptographicException("Should signal to try secret key"); ; - privateMLDsa.ExportMLDsaPublicKeyHook = (Span destination) => - MLDsaTestsData.IetfMLDsa44.PublicKey.CopyTo(destination); - privateMLDsa.ExportMLDsaSecretKeyHook = (Span destination) => - MLDsaTestsData.IetfMLDsa44.SecretKey.CopyTo(destination); - - privateMLDsa.TryExportPkcs8PrivateKeyHook = (dest, out written) => - { - if (MLDsaTestsData.IetfMLDsa44.Pkcs8PrivateKey_Seed.AsSpan().TryCopyTo(dest)) - { - written = MLDsaTestsData.IetfMLDsa44.Pkcs8PrivateKey_Seed.Length; - return true; - } - - written = 0; - return false; - }; - - using (X509Certificate2 privCert = CopyWithPrivateKey_MLDsa(pubOnly, privateMLDsa)) - { - AssertExtensions.TrueExpression(privCert.HasPrivateKey); - - using (MLDsa certPrivateMLDsa = GetMLDsaPrivateKey(privCert)) - { - byte[] secretKey = certPrivateMLDsa.ExportMLDsaSecretKey(); - AssertExtensions.SequenceEqual( - MLDsaTestsData.IetfMLDsa44.SecretKey, - secretKey); - - privateMLDsa.Dispose(); - privateMLDsa.ExportMLDsaPrivateSeedHook = _ => Assert.Fail(); - privateMLDsa.ExportMLDsaPublicKeyHook = _ => Assert.Fail(); - privateMLDsa.ExportMLDsaSecretKeyHook = _ => Assert.Fail(); - privateMLDsa.TryExportPkcs8PrivateKeyHook = (_, out w) => { Assert.Fail(); w = 0; return false; }; - - // Ensure the key is actual a clone - secretKey = certPrivateMLDsa.ExportMLDsaSecretKey(); - AssertExtensions.SequenceEqual( - MLDsaTestsData.IetfMLDsa44.SecretKey, - secretKey); - } - } - } - } - - [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] - public static void CheckCopyWithPrivateKey_MLDsa_OtherMLDsa_PrivateSeed() - { - using (X509Certificate2 pubOnly = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) - { - using (MLDsaTestImplementation publicMLDsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44)) - { - Exception e = new Exception("no secret key"); - - // The private seed can be retrieved directly or from PKCS#8 - publicMLDsa.TryExportPkcs8PrivateKeyHook = (_, out _) => throw e; - publicMLDsa.ExportMLDsaPrivateSeedHook = _ => throw e; - publicMLDsa.ExportMLDsaPublicKeyHook = (Span destination) => - MLDsaTestsData.IetfMLDsa44.PublicKey.CopyTo(destination); - - Assert.Same(e, AssertExtensions.Throws(() => CopyWithPrivateKey_MLDsa(pubOnly, publicMLDsa))); - } - - MLDsaTestImplementation privateMLDsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44); - privateMLDsa.ExportMLDsaPublicKeyHook = (Span destination) => - MLDsaTestsData.IetfMLDsa44.PublicKey.CopyTo(destination); - privateMLDsa.ExportMLDsaPrivateSeedHook = (Span destination) => - MLDsaTestsData.IetfMLDsa44.PrivateSeed.CopyTo(destination); - - privateMLDsa.TryExportPkcs8PrivateKeyHook = (dest, out written) => - { - if (MLDsaTestsData.IetfMLDsa44.Pkcs8PrivateKey_Seed.AsSpan().TryCopyTo(dest)) - { - written = MLDsaTestsData.IetfMLDsa44.Pkcs8PrivateKey_Seed.Length; - return true; - } - - written = 0; - return false; - }; - - using (X509Certificate2 privCert = CopyWithPrivateKey_MLDsa(pubOnly, privateMLDsa)) - { - AssertExtensions.TrueExpression(privCert.HasPrivateKey); - - using (MLDsa certPrivateMLDsa = GetMLDsaPrivateKey(privCert)) - { - byte[] secretKey = certPrivateMLDsa.ExportMLDsaPrivateSeed(); - AssertExtensions.SequenceEqual( - MLDsaTestsData.IetfMLDsa44.PrivateSeed, - secretKey); - - privateMLDsa.Dispose(); - privateMLDsa.ExportMLDsaPublicKeyHook = _ => Assert.Fail(); - privateMLDsa.ExportMLDsaPrivateSeedHook = _ => Assert.Fail(); - privateMLDsa.TryExportPkcs8PrivateKeyHook = (_, out w) => { Assert.Fail(); w = 0; return false; }; - - // Ensure the key is actual a clone - secretKey = certPrivateMLDsa.ExportMLDsaPrivateSeed(); - AssertExtensions.SequenceEqual( - MLDsaTestsData.IetfMLDsa44.PrivateSeed, - secretKey); - } - } - } - } - - [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] - public static void CheckCopyWithPrivateKey_MLDsa_OtherMLDsa_WrongPkcs8() - { - using (X509Certificate2 ietfCert = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) - using (RSA rsa = RSA.Create()) - using (MLDsaTestImplementation keyThatExportsRsaPkcs8 = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44)) - { - keyThatExportsRsaPkcs8.ExportMLDsaPublicKeyHook = MLDsaTestsData.IetfMLDsa44.PublicKey.CopyTo; - keyThatExportsRsaPkcs8.ExportMLDsaPrivateSeedHook = MLDsaTestsData.IetfMLDsa44.PrivateSeed.CopyTo; - - // Export RSA PKCS#8 - keyThatExportsRsaPkcs8.TryExportPkcs8PrivateKeyHook = rsa.TryExportPkcs8PrivateKey; - - if (PlatformDetection.IsWindows) - { - // Only Windows uses PKCS#8 for pairing key to cert. - AssertExtensions.Throws(() => ietfCert.CopyWithPrivateKey(keyThatExportsRsaPkcs8)); - } - else - { - // Assert.NoThrow - using (ietfCert.CopyWithPrivateKey(keyThatExportsRsaPkcs8)) { } - } - } - } - - [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] - public static void CheckCopyWithPrivateKey_MLDsa_OtherMLDsa_MalformedPkcs8() - { - using (X509Certificate2 ietfCert = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) - using (MLDsaTestImplementation keyThatExportsMalformedPkcs8 = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44)) - { - keyThatExportsMalformedPkcs8.ExportMLDsaPublicKeyHook = MLDsaTestsData.IetfMLDsa44.PublicKey.CopyTo; - keyThatExportsMalformedPkcs8.ExportMLDsaPrivateSeedHook = MLDsaTestsData.IetfMLDsa44.PrivateSeed.CopyTo; - - // Export malformed PKCS#8 - keyThatExportsMalformedPkcs8.TryExportPkcs8PrivateKeyHook = - (dest, out written) => - { - written = 0; - return true; - }; - - if (PlatformDetection.IsWindows) - { - // Only Windows uses PKCS#8 for pairing key to cert. - AssertExtensions.Throws(() => ietfCert.CopyWithPrivateKey(keyThatExportsMalformedPkcs8)); - } - else - { - // Assert.NoThrow - using (ietfCert.CopyWithPrivateKey(keyThatExportsMalformedPkcs8)) { } - } - } - } - - [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] - [PlatformSpecific(TestPlatforms.Windows)] - public static void AssociatePersistedKey_CNG_MLDsa() - { - const string KeyName = nameof(AssociatePersistedKey_CNG_MLDsa); - - CngKey cngKey = null; - byte[] signature = new byte[MLDsaAlgorithm.MLDsa44.SignatureSizeInBytes]; - - try - { - CngKeyCreationParameters creationParameters = new CngKeyCreationParameters() - { - ExportPolicy = CngExportPolicies.None, - Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider, - KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey, - }; - - CngProperty parameterSet = MLDsaTestHelpers.GetCngProperty(MLDsaAlgorithm.MLDsa44); - creationParameters.Parameters.Add(parameterSet); - - cngKey = CngKey.Create(CngAlgorithm.MLDsa, KeyName, creationParameters); - - using (MLDsaCng mldsaCng = new MLDsaCng(cngKey)) - { - CertificateRequest request = new CertificateRequest( - new X500DistinguishedName($"CN={KeyName}"), - mldsaCng); - - DateTimeOffset now = DateTimeOffset.UtcNow; - - using (X509Certificate2 cert = request.CreateSelfSigned(now, now.AddDays(1))) - using (MLDsa mldsa = cert.GetMLDsaPrivateKey()) - { - mldsa.SignData("test"u8, signature); - Assert.True(mldsaCng.VerifyData("test"u8, signature)); - } - } - - // Some certs have disposed, did they delete the key? - using (CngKey stillPersistedKey = CngKey.Open(KeyName, CngProvider.MicrosoftSoftwareKeyStorageProvider)) - using (MLDsaCng mldsa = new MLDsaCng(stillPersistedKey)) - { - mldsa.SignData("test"u8, signature); - } - } - finally - { - cngKey?.Delete(); - } - } - - [ConditionalFact(typeof(MLDsa), nameof(MLDsa.IsSupported))] - [PlatformSpecific(TestPlatforms.Windows)] - public static void AssociateEphemeralKey_CNG_MLDsa() - { - CngKeyCreationParameters creationParameters = new CngKeyCreationParameters(); - CngProperty parameterSet = MLDsaTestHelpers.GetCngProperty(MLDsaAlgorithm.MLDsa44); - creationParameters.Parameters.Add(parameterSet); - creationParameters.ExportPolicy = CngExportPolicies.AllowPlaintextExport; - - byte[] signature = new byte[MLDsaAlgorithm.MLDsa44.SignatureSizeInBytes]; - - using (CngKey ephemeralCngKey = CngKey.Create(CngAlgorithm.MLDsa, keyName: null, creationParameters)) - { - using (MLDsaCng mldsaCng = new MLDsaCng(ephemeralCngKey)) - { - CertificateRequest request = new CertificateRequest( - new X500DistinguishedName($"CN=EphemeralMLDsaKey"), - mldsaCng); - - DateTimeOffset now = DateTimeOffset.UtcNow; - - using (X509Certificate2 cert = request.CreateSelfSigned(now, now.AddDays(1))) - using (MLDsa mldsa = cert.GetMLDsaPrivateKey()) - { - mldsa.SignData("test"u8, signature); - Assert.True(mldsaCng.VerifyData("test"u8, signature)); - } - - // Run a few iterations to catch nondeterministic use-after-dispose issues - for (int i = 0; i < 5; i++) - { - using (X509Certificate2 cert = request.CreateSelfSigned(now, now.AddDays(1))) { } - } - - mldsaCng.SignData("test"u8, signature); - } - - // Some certs have disposed, did they delete the key? - using (MLDsaCng mldsa = new MLDsaCng(ephemeralCngKey)) - { - mldsa.SignData("test"u8, signature); - } - } - } - private static partial Func CopyWithPrivateKey_MLKem => (cert, key) => cert.CopyWithPrivateKey(key); @@ -1095,13 +715,13 @@ public static void AssociateEphemeralKey_CNG_MLDsa() private static partial Func GetMLKemPrivateKey => cert => cert.GetMLKemPrivateKey(); - private static Func CopyWithPrivateKey_MLDsa => + private static partial Func CopyWithPrivateKey_MLDsa => (cert, key) => cert.CopyWithPrivateKey(key); - private static Func GetMLDsaPublicKey => + private static partial Func GetMLDsaPublicKey => cert => cert.GetMLDsaPublicKey(); - private static Func GetMLDsaPrivateKey => + private static partial Func GetMLDsaPrivateKey => cert => cert.GetMLDsaPrivateKey(); private static partial Func CopyWithPrivateKey_SlhDsa => @@ -1123,12 +743,5 @@ private static partial void CheckCopyWithPrivateKey( Func getPrivateKey, Action keyProver) where TKey : class, IDisposable; - - private static X509Certificate2 LoadMLDsaIetfCertificateWithPrivateKey() - { - using (X509Certificate2 cert = X509CertificateLoader.LoadCertificate(MLDsaTestsData.IetfMLDsa44.Certificate)) - using (MLDsa? privateKey = MLDsa.ImportMLDsaPrivateSeed(MLDsaAlgorithm.MLDsa44, MLDsaTestsData.IetfMLDsa44.PrivateSeed)) - return cert.CopyWithPrivateKey(privateKey); - } } } diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs index 5587a21a70c95a..99b9b3587532ef 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ChainTests.cs @@ -288,13 +288,13 @@ public static void SystemTrustCertificateWithCustomRootTrust(bool addCertificate // Check some known conditions. - if (PlatformDetection.UsesAppleCrypto) + if (OperatingSystem.IsLinux() || PlatformDetection.IsApplePlatform26OrLater) { - Assert.Equal(3, chain.ChainElements.Count); + Assert.Equal(2, chain.ChainElements.Count); } - else if (OperatingSystem.IsLinux()) + else if (PlatformDetection.IsApplePlatform) { - Assert.Equal(2, chain.ChainElements.Count); + Assert.Equal(3, chain.ChainElements.Count); } } } @@ -344,6 +344,8 @@ public static void BuildChainCustomTrustStore( chainTest.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; chainTest.ChainPolicy.ExtraStore.Add(issuerCert); + X509ChainStatusFlags allowedFlags = X509ChainStatusFlags.NoError; + switch (testArguments) { case BuildChainCustomTrustStoreTestArguments.TrustedIntermediateUntrustedRoot: @@ -361,6 +363,9 @@ public static void BuildChainCustomTrustStore( chainHolder.DisposeChainElements(); chainTest.ChainPolicy.CustomTrustStore.Remove(rootCert); chainTest.ChainPolicy.TrustMode = X509ChainTrustMode.System; + chainTest.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; + chainTest.ChainPolicy.ExtraStore.Add(rootCert); + allowedFlags |= X509ChainStatusFlags.UntrustedRoot; break; default: throw new InvalidDataException(); @@ -368,7 +373,11 @@ public static void BuildChainCustomTrustStore( Assert.Equal(chainBuildsSuccessfully, chainTest.Build(endCert)); Assert.Equal(3, chainTest.ChainElements.Count); - Assert.Equal(chainFlags, chainTest.AllStatusFlags()); + + X509ChainStatusFlags actualFlags = chainTest.AllStatusFlags(); + actualFlags &= ~allowedFlags; + + Assert.Equal(chainFlags, actualFlags); } } @@ -1169,12 +1178,12 @@ public static void BuildChainForCertificateSignedWithDisallowedKey() chain.ChainPolicy.ExtraStore.Add(intermediateCert); Assert.False(chain.Build(cert)); - if (PlatformDetection.IsAndroid) + if (PlatformDetection.IsAndroid || PlatformDetection.IsApplePlatform26OrLater) { // Android always validates trust as part of building a path, // so violations comes back as PartialChain with no elements + // Apple 26 no longer block these SKIs since the roots are no longer trusted at all and are expired. Assert.Equal(X509ChainStatusFlags.PartialChain, chain.AllStatusFlags()); - Assert.Equal(0, chain.ChainElements.Count); } else { diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CollectionTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CollectionTests.cs index a9ac4e821539a1..cb53f557be2e24 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CollectionTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CollectionTests.cs @@ -1805,7 +1805,7 @@ public static void ExportPkcs12_Pkcs12ExportPbeParameters_ArgValidation() [InlineData((PbeEncryptionAlgorithm)(-1), nameof(HashAlgorithmName.SHA1))] public static void ExportPkcs12_PbeParameters_ArgValidation( PbeEncryptionAlgorithm encryptionAlgorithm, - string hashAlgorithm) + string? hashAlgorithm) { X509Certificate2Collection collection = []; PbeParameters badParameters = new(encryptionAlgorithm, new HashAlgorithmName(hashAlgorithm), 1); diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ExportTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ExportTests.cs index 70eb3214bf858c..c526790a90432c 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ExportTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ExportTests.cs @@ -1,9 +1,7 @@ // 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.Generic; using System.Formats.Asn1; -using System.Linq; using System.Security.Cryptography.Tests; using System.Security.Cryptography.Dsa.Tests; using System.Security.Cryptography.EcDsa.Tests; @@ -276,7 +274,7 @@ public static void ExportPkcs12_Pkcs12ExportPbeParameters_ArgValidation() [InlineData((PbeEncryptionAlgorithm)(-1), nameof(HashAlgorithmName.SHA1))] public static void ExportPkcs12_PbeParameters_ArgValidation( PbeEncryptionAlgorithm encryptionAlgorithm, - string hashAlgorithm) + string? hashAlgorithm) { using (X509Certificate2 cert = new(TestData.PfxData, TestData.PfxDataPassword)) { @@ -370,7 +368,7 @@ public static void ExportPkcs12_MLKem_Roundtrip(MLKemAlgorithm algorithm) PbeParameters pbeParameters = new(PbeEncryptionAlgorithm.Aes256Cbc, HashAlgorithmName.SHA256, 32); - using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword)) + using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, X509KeyStorageFlags.Exportable)) { byte[] pkcs12 = cert.ExportPkcs12(pbeParameters, password); (int certs, int keys) = VerifyPkcs12( @@ -382,7 +380,7 @@ public static void ExportPkcs12_MLKem_Roundtrip(MLKemAlgorithm algorithm) Assert.Equal(1, certs); Assert.Equal(1, keys); - using (X509Certificate2 reLoaded = X509CertificateLoader.LoadPkcs12(pkcs12, password)) + using (X509Certificate2 reLoaded = X509CertificateLoader.LoadPkcs12(pkcs12, password, X509KeyStorageFlags.Exportable)) using (MLKem kem = reLoaded.GetMLKemPrivateKey()) { Assert.NotNull(kem); @@ -392,15 +390,14 @@ public static void ExportPkcs12_MLKem_Roundtrip(MLKemAlgorithm algorithm) } } - [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.SupportsDraft10Pkcs8))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/116463", TestPlatforms.Windows)] + [ConditionalTheory(typeof(MLDsa), nameof(MLDsa.IsSupported))] [MemberData(nameof(MLDsaTestsData.IetfMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))] public static void ExportPkcs12_MLDsa_Generated_Roundtrip(MLDsaKeyInfo info) { string password = info.EncryptionPassword; PbeParameters pbeParameters = info.EncryptionParameters; - using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(info.Pfx_Seed, password)) + using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(info.Pfx_Seed, password, X509KeyStorageFlags.Exportable)) { byte[] pkcs12 = cert.ExportPkcs12(pbeParameters, password); (int certs, int keys) = VerifyPkcs12( @@ -412,15 +409,15 @@ public static void ExportPkcs12_MLDsa_Generated_Roundtrip(MLDsaKeyInfo info) Assert.Equal(1, certs); Assert.Equal(1, keys); - using (X509Certificate2 reLoaded = X509CertificateLoader.LoadPkcs12(pkcs12, password)) + using (X509Certificate2 reLoaded = X509CertificateLoader.LoadPkcs12(pkcs12, password, X509KeyStorageFlags.Exportable)) using (MLDsa mldsa = reLoaded.GetMLDsaPrivateKey()) { Assert.NotNull(mldsa); Assert.Equal(info.Algorithm, mldsa.Algorithm); AssertExtensions.SequenceEqual(info.Certificate, reLoaded.RawData); - byte[] actualSecretKey = mldsa.ExportMLDsaSecretKey(); - AssertExtensions.SequenceEqual(info.SecretKey, actualSecretKey); + byte[] actualPrivateKey = mldsa.ExportMLDsaPrivateKey(); + AssertExtensions.SequenceEqual(info.PrivateKey, actualPrivateKey); } } } @@ -433,7 +430,7 @@ public static void ExportPkcs12_SlhDsa_Ietf_Roundtrip() PbeParameters pbeParameters = new(PbeEncryptionAlgorithm.Aes256Cbc, HashAlgorithmName.SHA256, 32); - using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, password)) + using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, password, X509KeyStorageFlags.Exportable)) { byte[] pkcs12 = cert.ExportPkcs12(pbeParameters, password); (int certs, int keys) = VerifyPkcs12( @@ -445,12 +442,12 @@ public static void ExportPkcs12_SlhDsa_Ietf_Roundtrip() Assert.Equal(1, certs); Assert.Equal(1, keys); - using (X509Certificate2 reLoaded = X509CertificateLoader.LoadPkcs12(pkcs12, password)) + using (X509Certificate2 reLoaded = X509CertificateLoader.LoadPkcs12(pkcs12, password, X509KeyStorageFlags.Exportable)) using (SlhDsa slhDsa = reLoaded.GetSlhDsaPrivateKey()) { Assert.NotNull(slhDsa); Assert.Equal(SlhDsaAlgorithm.SlhDsaSha2_128s, slhDsa.Algorithm); - AssertExtensions.SequenceEqual(SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue, slhDsa.ExportSlhDsaSecretKey()); + AssertExtensions.SequenceEqual(SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue, slhDsa.ExportSlhDsaPrivateKey()); } } } @@ -462,7 +459,7 @@ public static void ExportPkcs12_SlhDsa_Generated_Roundtrip(SlhDsaTestData.SlhDsa string password = info.EncryptionPassword; PbeParameters pbeParameters = new(PbeEncryptionAlgorithm.Aes256Cbc, HashAlgorithmName.SHA256, 32); - using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(info.SelfSignedCertificatePfx, password)) + using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(info.SelfSignedCertificatePfx, password, X509KeyStorageFlags.Exportable)) { byte[] pkcs12 = cert.ExportPkcs12(pbeParameters, password); (int certs, int keys) = VerifyPkcs12( @@ -474,12 +471,12 @@ public static void ExportPkcs12_SlhDsa_Generated_Roundtrip(SlhDsaTestData.SlhDsa Assert.Equal(1, certs); Assert.Equal(1, keys); - using (X509Certificate2 reLoaded = X509CertificateLoader.LoadPkcs12(pkcs12, password)) + using (X509Certificate2 reLoaded = X509CertificateLoader.LoadPkcs12(pkcs12, password, X509KeyStorageFlags.Exportable)) using (SlhDsa slhDsa = reLoaded.GetSlhDsaPrivateKey()) { Assert.NotNull(slhDsa); Assert.Equal(info.Algorithm, slhDsa.Algorithm); - AssertExtensions.SequenceEqual(info.SecretKey, slhDsa.ExportSlhDsaSecretKey()); + AssertExtensions.SequenceEqual(info.PrivateKey, slhDsa.ExportSlhDsaPrivateKey()); AssertExtensions.SequenceEqual(info.Certificate, reLoaded.RawData); } } diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxIterationCountTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxIterationCountTests.cs index 1f65016841437a..052fb216f66d82 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxIterationCountTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxIterationCountTests.cs @@ -64,6 +64,7 @@ public void Import_IterationCountLimitExceeded_Throws(string name, string passwo Assert.Contains(FwlinkId, ce.Message); } + [ActiveIssue("https://github.com/dotnet/runtime/issues/62547", TestPlatforms.Android)] [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] [MemberData(nameof(GetCertsWith_IterationCountExceedingDefaultLimit_MemberData))] public void ImportWithPasswordOrFileName_IterationCountLimitExceeded(string name, string password, bool usesPbes2, byte[] blob, long iterationCount, bool usesRC2) diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxTests.cs index 922b33c02dab0d..e3569082aad981 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxTests.cs @@ -3,12 +3,8 @@ using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Security.Cryptography.SLHDsa.Tests; using System.Security.Cryptography.Tests; -using System.Text; -using Microsoft.DotNet.RemoteExecutor; -using Microsoft.DotNet.XUnitExtensions; using Test.Cryptography; using Xunit; @@ -394,7 +390,7 @@ public static void ReadMLKem512PrivateKey_Seed_Pfx(X509KeyStorageFlags keyStorag byte[] pfxBytes = MLKemTestData.IetfMlKem512PrivateKeySeedPfx; string pfxPassword = MLKemTestData.EncryptedPrivateKeyPassword; - using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags)) + using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags | X509KeyStorageFlags.Exportable)) using (MLKem kem = cert.GetMLKemPrivateKey()) { Assert.NotNull(kem); @@ -411,7 +407,7 @@ public static void ReadMLKem512PrivateKey_ExpandedKey_Pfx(X509KeyStorageFlags ke byte[] pfxBytes = MLKemTestData.IetfMlKem512PrivateKeyExpandedKeyPfx; string pfxPassword = MLKemTestData.EncryptedPrivateKeyPassword; - using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags)) + using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags | X509KeyStorageFlags.Exportable)) using (MLKem kem = cert.GetMLKemPrivateKey()) { Assert.NotNull(kem); @@ -431,7 +427,7 @@ public static void ReadMLKem512PrivateKey_Both_Pfx(X509KeyStorageFlags keyStorag byte[] pfxBytes = MLKemTestData.IetfMlKem512PrivateKeyBothPfx; string pfxPassword = MLKemTestData.EncryptedPrivateKeyPassword; - using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags)) + using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags | X509KeyStorageFlags.Exportable)) using (MLKem kem = cert.GetMLKemPrivateKey()) { Assert.NotNull(kem); @@ -451,7 +447,7 @@ public static void ReadMLKem768PrivateKey_Seed_Pfx(X509KeyStorageFlags keyStorag byte[] pfxBytes = MLKemTestData.IetfMlKem768PrivateKeySeedPfx; string pfxPassword = MLKemTestData.EncryptedPrivateKeyPassword; - using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags)) + using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags | X509KeyStorageFlags.Exportable)) using (MLKem kem = cert.GetMLKemPrivateKey()) { Assert.NotNull(kem); @@ -468,7 +464,7 @@ public static void ReadMLKem768PrivateKey_ExpandedKey_Pfx(X509KeyStorageFlags ke byte[] pfxBytes = MLKemTestData.IetfMlKem768PrivateKeyExpandedKeyPfx; string pfxPassword = MLKemTestData.EncryptedPrivateKeyPassword; - using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags)) + using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags | X509KeyStorageFlags.Exportable)) using (MLKem kem = cert.GetMLKemPrivateKey()) { Assert.NotNull(kem); @@ -488,7 +484,7 @@ public static void ReadMLKem768PrivateKey_Both_Pfx(X509KeyStorageFlags keyStorag byte[] pfxBytes = MLKemTestData.IetfMlKem768PrivateKeyBothPfx; string pfxPassword = MLKemTestData.EncryptedPrivateKeyPassword; - using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags)) + using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags | X509KeyStorageFlags.Exportable)) using (MLKem kem = cert.GetMLKemPrivateKey()) { Assert.NotNull(kem); @@ -508,7 +504,7 @@ public static void ReadMLKem1024PrivateKey_Seed_Pfx(X509KeyStorageFlags keyStora byte[] pfxBytes = MLKemTestData.IetfMlKem1024PrivateKeySeedPfx; string pfxPassword = MLKemTestData.EncryptedPrivateKeyPassword; - using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags)) + using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags | X509KeyStorageFlags.Exportable)) using (MLKem kem = cert.GetMLKemPrivateKey()) { Assert.NotNull(kem); @@ -525,7 +521,7 @@ public static void ReadMLKem1024PrivateKey_ExpandedKey_Pfx(X509KeyStorageFlags k byte[] pfxBytes = MLKemTestData.IetfMlKem1024PrivateKeyExpandedKeyPfx; string pfxPassword = MLKemTestData.EncryptedPrivateKeyPassword; - using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags)) + using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags | X509KeyStorageFlags.Exportable)) using (MLKem kem = cert.GetMLKemPrivateKey()) { Assert.NotNull(kem); @@ -545,7 +541,7 @@ public static void ReadMLKem1024PrivateKey_Both_Pfx(X509KeyStorageFlags keyStora byte[] pfxBytes = MLKemTestData.IetfMlKem1024PrivateKeyBothPfx; string pfxPassword = MLKemTestData.EncryptedPrivateKeyPassword; - using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags)) + using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags | X509KeyStorageFlags.Exportable)) using (MLKem kem = cert.GetMLKemPrivateKey()) { Assert.NotNull(kem); @@ -670,8 +666,7 @@ from ietfVectorWrapped in MLDsaTestsData.IetfMLDsaAlgorithms from ietfVector in ietfVectorWrapped select new object[] { storageFlag, ietfVector }; - [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.SupportsDraft10Pkcs8))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/116463", TestPlatforms.Windows)] + [ConditionalTheory(typeof(MLDsa), nameof(MLDsa.IsSupported))] [MemberData(nameof(ReadMLDsa_Pfx_Ietf_Data))] public static void ReadMLDsa512PrivateKey_Seed_Pfx(X509KeyStorageFlags keyStorageFlags, MLDsaKeyInfo info) { @@ -679,19 +674,24 @@ public static void ReadMLDsa512PrivateKey_Seed_Pfx(X509KeyStorageFlags keyStorag string pfxPassword = info.EncryptionPassword; using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags)) - using (MLDsa mldsa = cert.GetMLDsaPrivateKey()) + using (MLDsa pubKey = cert.GetMLDsaPublicKey()) + using (MLDsa privKey = cert.GetMLDsaPrivateKey()) { - Assert.NotNull(mldsa); - Assert.Equal(info.Algorithm, mldsa.Algorithm); Assert.Equal("CN=LAMPS WG, O=IETF", cert.Subject); - byte[] seed = mldsa.ExportMLDsaPrivateSeed(); - AssertExtensions.SequenceEqual(info.PrivateSeed, seed); + Assert.NotNull(pubKey); + Assert.NotNull(privKey); + + AssertExtensions.SequenceEqual(info.PublicKey, pubKey.ExportMLDsaPublicKey()); + + byte[] data = [42]; + byte[] sig = privKey.SignData(data); + + AssertExtensions.TrueExpression(pubKey.VerifyData(data, sig)); } } - [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.SupportsDraft10Pkcs8))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/116463", TestPlatforms.Windows)] + [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.SupportsExportingPrivateKeyPkcs8))] [MemberData(nameof(ReadMLDsa_Pfx_Ietf_Data))] public static void ReadMLDsa512PrivateKey_ExpandedKey_Pfx(X509KeyStorageFlags keyStorageFlags, MLDsaKeyInfo info) { @@ -699,20 +699,24 @@ public static void ReadMLDsa512PrivateKey_ExpandedKey_Pfx(X509KeyStorageFlags ke string pfxPassword = info.EncryptionPassword; using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags)) - using (MLDsa mldsa = cert.GetMLDsaPrivateKey()) + using (MLDsa pubKey = cert.GetMLDsaPublicKey()) + using (MLDsa privKey = cert.GetMLDsaPrivateKey()) { - Assert.NotNull(mldsa); - Assert.Equal(info.Algorithm, mldsa.Algorithm); Assert.Equal("CN=LAMPS WG, O=IETF", cert.Subject); - Assert.Throws(() => mldsa.ExportMLDsaPrivateSeed()); - byte[] secretKey = mldsa.ExportMLDsaSecretKey(); - AssertExtensions.SequenceEqual(info.SecretKey, secretKey); + Assert.NotNull(pubKey); + Assert.NotNull(privKey); + + AssertExtensions.SequenceEqual(info.PublicKey, pubKey.ExportMLDsaPublicKey()); + + byte[] data = [42]; + byte[] sig = privKey.SignData(data); + + AssertExtensions.TrueExpression(pubKey.VerifyData(data, sig)); } } - [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.SupportsDraft10Pkcs8))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/116463", TestPlatforms.Windows)] + [ConditionalTheory(typeof(MLDsa), nameof(MLDsa.IsSupported))] [MemberData(nameof(ReadMLDsa_Pfx_Ietf_Data))] public static void ReadMLDsa512PrivateKey_Both_Pfx(X509KeyStorageFlags keyStorageFlags, MLDsaKeyInfo info) { @@ -720,17 +724,20 @@ public static void ReadMLDsa512PrivateKey_Both_Pfx(X509KeyStorageFlags keyStorag string pfxPassword = info.EncryptionPassword; using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags)) - using (MLDsa mldsa = cert.GetMLDsaPrivateKey()) + using (MLDsa pubKey = cert.GetMLDsaPublicKey()) + using (MLDsa privKey = cert.GetMLDsaPrivateKey()) { - Assert.NotNull(mldsa); - Assert.Equal(info.Algorithm, mldsa.Algorithm); Assert.Equal("CN=LAMPS WG, O=IETF", cert.Subject); - byte[] seed = mldsa.ExportMLDsaPrivateSeed(); - AssertExtensions.SequenceEqual(info.PrivateSeed.AsSpan(), seed.AsSpan()); + Assert.NotNull(pubKey); + Assert.NotNull(privKey); + + AssertExtensions.SequenceEqual(info.PublicKey, pubKey.ExportMLDsaPublicKey()); - byte[] sk = mldsa.ExportMLDsaSecretKey(); - AssertExtensions.SequenceEqual(info.SecretKey, sk); + byte[] data = [42]; + byte[] sig = privKey.SignData(data); + + AssertExtensions.TrueExpression(pubKey.VerifyData(data, sig)); } } @@ -776,13 +783,20 @@ public static void ReadSlhDsa_Pfx_Ietf(X509KeyStorageFlags keyStorageFlags) string pfxPassword = "PLACEHOLDER"; using (X509Certificate2 cert = X509CertificateLoader.LoadPkcs12(pfxBytes, pfxPassword, keyStorageFlags)) - using (SlhDsa slhDsa = cert.GetSlhDsaPrivateKey()) + using (SlhDsa pubKey = cert.GetSlhDsaPublicKey()) + using (SlhDsa privKey = cert.GetSlhDsaPrivateKey()) { - Assert.NotNull(slhDsa); - Assert.Equal(SlhDsaAlgorithm.SlhDsaSha2_128s, slhDsa.Algorithm); - // Note this display string is reversed from the one in the IETF example but equivalent. Assert.Equal("O=Bogus SLH-DSA-SHA2-128s CA, L=Paris, C=FR", cert.Subject); - AssertExtensions.SequenceEqual(SlhDsaTestData.IetfSlhDsaSha2_128sPrivateKeyValue, slhDsa.ExportSlhDsaSecretKey()); + + Assert.NotNull(pubKey); + Assert.NotNull(privKey); + + AssertExtensions.SequenceEqual(SlhDsaTestData.IetfSlhDsaSha2_128sPublicKeyValue, pubKey.ExportSlhDsaPublicKey()); + + byte[] data = [42]; + byte[] sig = privKey.SignData(data); + + AssertExtensions.TrueExpression(pubKey.VerifyData(data, sig)); } } diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/X509Certificate2PemTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/X509Certificate2PemTests.cs index a1e35ee0df9cc0..7c247857a6d2dd 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/X509Certificate2PemTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/X509Certificate2PemTests.cs @@ -368,12 +368,12 @@ public static void CreateFromPem_MLKem_Pkcs8_Success() ), ]; - foreach((string CertificatePem, string PrivateKeyPem, string Thumbprint) in cases) + foreach((string certificatePem, string privateKeyPem, string thumbprint) in cases) { - using (X509Certificate2 cert = X509Certificate2.CreateFromPem(CertificatePem, PrivateKeyPem)) + using (X509Certificate2 cert = X509Certificate2.CreateFromPem(certificatePem, privateKeyPem)) { - Assert.Equal(Thumbprint, cert.GetCertHashString(HashAlgorithmName.SHA256)); - AssertKeysMatch(PrivateKeyPem, cert.GetMLKemPrivateKey); + Assert.Equal(thumbprint, cert.GetCertHashString(HashAlgorithmName.SHA256)); + AssertKeysMatch(privateKeyPem, cert.GetMLKemPrivateKey); } } } @@ -430,15 +430,15 @@ public static void CreateFromEncryptedPem_MLKem_Pkcs8_Success() ), ]; - foreach((string CertificatePem, string PrivateKeyPem, string Thumbprint) in cases) + foreach((string certificatePem, string privateKeyPem, string thumbprint) in cases) { using (X509Certificate2 cert = X509Certificate2.CreateFromEncryptedPem( - CertificatePem, - PrivateKeyPem, + certificatePem, + privateKeyPem, MLKemTestData.EncryptedPrivateKeyPassword)) { - Assert.Equal(Thumbprint, cert.GetCertHashString(HashAlgorithmName.SHA256)); - AssertKeysMatch(PrivateKeyPem, cert.GetMLKemPrivateKey, MLKemTestData.EncryptedPrivateKeyPassword); + Assert.Equal(thumbprint, cert.GetCertHashString(HashAlgorithmName.SHA256)); + AssertKeysMatch(privateKeyPem, cert.GetMLKemPrivateKey, MLKemTestData.EncryptedPrivateKeyPassword); } } } @@ -495,12 +495,12 @@ public static void CreateFromPem_MLDsa_Pkcs8_Success() ), ]; - foreach ((string CertificatePem, string PrivateKeyPem, string Thumbprint) in cases) + foreach ((string certificatePem, string privateKeyPem, string thumbprint) in cases) { - using (X509Certificate2 cert = X509Certificate2.CreateFromPem(CertificatePem, PrivateKeyPem)) + using (X509Certificate2 cert = X509Certificate2.CreateFromPem(certificatePem, privateKeyPem)) { - Assert.Equal(Thumbprint, cert.GetCertHashString(HashAlgorithmName.SHA256)); - AssertKeysMatch(PrivateKeyPem, cert.GetMLDsaPrivateKey); + Assert.Equal(thumbprint, cert.GetCertHashString(HashAlgorithmName.SHA256)); + AssertKeysMatch(privateKeyPem, cert.GetMLDsaPrivateKey); } } } @@ -557,15 +557,15 @@ public static void CreateFromEncryptedPem_MLDsa_Pkcs8_Success() ), ]; - foreach ((string CertificatePem, string PrivateKeyPem, string Thumbprint) in cases) + foreach ((string certificatePem, string privateKeyPem, string thumbprint) in cases) { using (X509Certificate2 cert = X509Certificate2.CreateFromEncryptedPem( - CertificatePem, - PrivateKeyPem, + certificatePem, + privateKeyPem, "PLACEHOLDER")) { - Assert.Equal(Thumbprint, cert.GetCertHashString(HashAlgorithmName.SHA256)); - AssertKeysMatch(PrivateKeyPem, cert.GetMLDsaPrivateKey, "PLACEHOLDER"); + Assert.Equal(thumbprint, cert.GetCertHashString(HashAlgorithmName.SHA256)); + AssertKeysMatch(privateKeyPem, cert.GetMLDsaPrivateKey, "PLACEHOLDER"); } } } diff --git a/src/libraries/System.Security.Permissions/System.Security.Permissions.slnx b/src/libraries/System.Security.Permissions/System.Security.Permissions.slnx index e9265948767136..1faf7851898eab 100644 --- a/src/libraries/System.Security.Permissions/System.Security.Permissions.slnx +++ b/src/libraries/System.Security.Permissions/System.Security.Permissions.slnx @@ -93,7 +93,7 @@ - + @@ -101,7 +101,7 @@ - + @@ -109,7 +109,7 @@ - + @@ -117,7 +117,7 @@ - + @@ -125,7 +125,7 @@ - + @@ -133,7 +133,9 @@ - + + + diff --git a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs index 5d2fc5fabc8b31..f6cf6ec74ef5d9 100644 --- a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs +++ b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs @@ -676,7 +676,7 @@ public static void RevertPermitOnly() { } public partial class HostProtectionException : System.SystemException { public HostProtectionException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -2061,7 +2061,7 @@ public Hash(System.Reflection.Assembly assembly) { } public static System.Security.Policy.Hash CreateSHA1(byte[] sha1) { throw null; } public static System.Security.Policy.Hash CreateSHA256(byte[] sha256) { throw null; } public byte[] GenerateHash(System.Security.Cryptography.HashAlgorithm hashAlg) { throw null; } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -2131,7 +2131,7 @@ public PermissionRequestEvidence(System.Security.PermissionSet request, System.S public partial class PolicyException : System.SystemException { public PolicyException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.netcoreapp.cs b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.netcoreapp.cs index f3e0de569038cb..bd8c4172ec54f2 100644 --- a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.netcoreapp.cs +++ b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.netcoreapp.cs @@ -6,9 +6,7 @@ namespace System.Xaml.Permissions { -#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] -#endif public sealed partial class XamlLoadPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission { public XamlLoadPermission(System.Collections.Generic.IEnumerable allowedAccess) { } diff --git a/src/libraries/System.Security.Permissions/src/System/Security/HostProtectionException.cs b/src/libraries/System.Security.Permissions/src/System/Security/HostProtectionException.cs index 455e045198c419..c8f860ac5bc169 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/HostProtectionException.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/HostProtectionException.cs @@ -48,7 +48,7 @@ public HostProtectionException(string message, HostProtectionResource protectedR DemandedResources = demandedResources; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -85,7 +85,7 @@ public override string ToString() return sb.ToString(); } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Hash.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Hash.cs index 85c7aa64d90dd1..2c5b1f79f6166b 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Hash.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Hash.cs @@ -17,7 +17,7 @@ public Hash(System.Reflection.Assembly assembly) { } public static Hash CreateSHA1(byte[] sha1) { return default(Hash); } public static Hash CreateSHA256(byte[] sha256) { return default(Hash); } public byte[] GenerateHash(HashAlgorithm hashAlg) { return null; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyException.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyException.cs index 0c80cbc66509b9..5da2875ea6b152 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyException.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyException.cs @@ -11,7 +11,7 @@ namespace System.Security.Policy public partial class PolicyException : System.SystemException { public PolicyException() { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Security.Permissions/src/System/Security/XmlSyntaxException.cs b/src/libraries/System.Security.Permissions/src/System/Security/XmlSyntaxException.cs index b942716638c78f..b90268f100c0a8 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/XmlSyntaxException.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/XmlSyntaxException.cs @@ -14,7 +14,7 @@ public XmlSyntaxException(int lineNumber) { } public XmlSyntaxException(int lineNumber, string message) { } public XmlSyntaxException(string message) { } public XmlSyntaxException(string message, Exception inner) { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif private XmlSyntaxException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/libraries/System.Security.Principal.Windows/System.Security.Principal.Windows.slnx b/src/libraries/System.Security.Principal.Windows/System.Security.Principal.Windows.slnx index 74b48a9429e3c4..0b5d5476cc7cf5 100644 --- a/src/libraries/System.Security.Principal.Windows/System.Security.Principal.Windows.slnx +++ b/src/libraries/System.Security.Principal.Windows/System.Security.Principal.Windows.slnx @@ -1,32 +1,322 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Security.Principal.Windows/src/System.Security.Principal.Windows.csproj b/src/libraries/System.Security.Principal.Windows/src/System.Security.Principal.Windows.csproj index 14896f075d72aa..d215472e0caced 100644 --- a/src/libraries/System.Security.Principal.Windows/src/System.Security.Principal.Windows.csproj +++ b/src/libraries/System.Security.Principal.Windows/src/System.Security.Principal.Windows.csproj @@ -143,13 +143,13 @@ - - - - - - - + + + + + + + diff --git a/src/libraries/System.ServiceModel.Syndication/Directory.Build.props b/src/libraries/System.ServiceModel.Syndication/Directory.Build.props new file mode 100644 index 00000000000000..760f934398477e --- /dev/null +++ b/src/libraries/System.ServiceModel.Syndication/Directory.Build.props @@ -0,0 +1,6 @@ + + + + false + + diff --git a/src/libraries/System.ServiceModel.Syndication/src/System.ServiceModel.Syndication.csproj b/src/libraries/System.ServiceModel.Syndication/src/System.ServiceModel.Syndication.csproj index 29a05a68ef6492..c5f32e4efda4cb 100644 --- a/src/libraries/System.ServiceModel.Syndication/src/System.ServiceModel.Syndication.csproj +++ b/src/libraries/System.ServiceModel.Syndication/src/System.ServiceModel.Syndication.csproj @@ -2,7 +2,6 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) - false true false true diff --git a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Atom10FeedFormatter.cs b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Atom10FeedFormatter.cs index 2a152cb395ca28..966fd0feaf097b 100644 --- a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Atom10FeedFormatter.cs +++ b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Atom10FeedFormatter.cs @@ -573,11 +573,11 @@ private static TextSyndicationContent ReadTextContentFromHelper(XmlReader reader private static string AsString(DateTimeOffset dateTime) { -#if NET8_0_OR_GREATER +#if NET if (dateTime.TotalOffsetMinutes == 0) #else if (dateTime.Offset == TimeSpan.Zero) -#endif // NET8_0_OR_GREATER +#endif // NET { return dateTime.ToUniversalTime().ToString(Rfc3339UTCDateTimeFormat, CultureInfo.InvariantCulture); } diff --git a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Rss20FeedFormatter.cs b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Rss20FeedFormatter.cs index 3515a3fca5276c..f8788e4b4cff7b 100644 --- a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Rss20FeedFormatter.cs +++ b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Rss20FeedFormatter.cs @@ -174,11 +174,11 @@ protected virtual void WriteItems(XmlWriter writer, IEnumerable private static string AsString(DateTimeOffset dateTime) { -#if NET8_0_OR_GREATER +#if NET if (dateTime.TotalOffsetMinutes == 0) #else if (dateTime.Offset == TimeSpan.Zero) -#endif // NET8_0_OR_GREATER +#endif // NET { return dateTime.ToUniversalTime().ToString(Rfc822OutputUtcDateTimeFormat, CultureInfo.InvariantCulture); } diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/InlineCategoriesDocumentTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/InlineCategoriesDocumentTests.cs index 071a74d94a5254..7e821de655e2f9 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/InlineCategoriesDocumentTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/InlineCategoriesDocumentTests.cs @@ -131,7 +131,7 @@ public void CreateCategory_Invoke_ReturnsExpected() [InlineData("name", "http://www.w3.org/2000/xmlns/", "value", "version")] [InlineData("type", "ns", "value", "version")] [InlineData("name", "http://www.w3.org/2001/XMLSchema-instance", "value", "version")] - public void TryParseAttribute_Invoke_ReturnsFalse(string name, string ns, string value, string version) + public void TryParseAttribute_Invoke_ReturnsFalse(string? name, string? ns, string? value, string? version) { var document = new InlineCategoriesDocumentSubclass(); Assert.False(document.TryParseAttributeEntryPoint(name, ns, value, version)); @@ -146,7 +146,7 @@ public static IEnumerable TryParseElement_TestData() [Theory] [MemberData(nameof(TryParseElement_TestData))] - public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version) + public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string? version) { var document = new InlineCategoriesDocumentSubclass(); Assert.False(document.TryParseElementEntryPoint(reader, version)); @@ -156,7 +156,7 @@ public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteAttributeExtensions_Invoke_ReturnsExpected(string version) + public void WriteAttributeExtensions_Invoke_ReturnsExpected(string? version) { var document = new InlineCategoriesDocumentSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => document.WriteAttributeExtensionsEntryPoint(writer, version)); @@ -178,7 +178,7 @@ public void WriteAttributeExtensions_NullWriter_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteElementExtensions_Invoke_ReturnsExpected(string version) + public void WriteElementExtensions_Invoke_ReturnsExpected(string? version) { var document = new InlineCategoriesDocumentSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => document.WriteElementExtensionsEntryPoint(writer, version)); diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/ReferencedCategoriesDocumentTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/ReferencedCategoriesDocumentTests.cs index a06d9bee7216d0..dda7ac070f8d9a 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/ReferencedCategoriesDocumentTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/ReferencedCategoriesDocumentTests.cs @@ -124,7 +124,7 @@ public void Categories_SetNullItem_ThrowsArgumentNullException() [InlineData("name", "http://www.w3.org/2000/xmlns/", "value", "version")] [InlineData("type", "ns", "value", "version")] [InlineData("name", "http://www.w3.org/2001/XMLSchema-instance", "value", "version")] - public void TryParseAttribute_Invoke_ReturnsFalse(string name, string ns, string value, string version) + public void TryParseAttribute_Invoke_ReturnsFalse(string? name, string? ns, string? value, string? version) { var document = new ReferencedCategoriesDocumentSubclass(); Assert.False(document.TryParseAttributeEntryPoint(name, ns, value, version)); @@ -139,7 +139,7 @@ public static IEnumerable TryParseElement_TestData() [Theory] [MemberData(nameof(TryParseElement_TestData))] - public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version) + public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string? version) { var document = new ReferencedCategoriesDocumentSubclass(); Assert.False(document.TryParseElementEntryPoint(reader, version)); @@ -149,7 +149,7 @@ public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteAttributeExtensions_Invoke_ReturnsExpected(string version) + public void WriteAttributeExtensions_Invoke_ReturnsExpected(string? version) { var document = new ReferencedCategoriesDocumentSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => document.WriteAttributeExtensionsEntryPoint(writer, version)); @@ -171,7 +171,7 @@ public void WriteAttributeExtensions_NullWriter_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteElementExtensions_Invoke_ReturnsExpected(string version) + public void WriteElementExtensions_Invoke_ReturnsExpected(string? version) { var document = new ReferencedCategoriesDocumentSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => document.WriteElementExtensionsEntryPoint(writer, version)); diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/ResourceCollectionInfoTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/ResourceCollectionInfoTests.cs index b301dadedabd05..86ef9cd52f7249 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/ResourceCollectionInfoTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/ResourceCollectionInfoTests.cs @@ -248,7 +248,7 @@ public void CreateReferencedCategoriesDocument_Invoke_ReturnsExpected() [InlineData("name", "http://www.w3.org/2000/xmlns/", "value", "version")] [InlineData("type", "ns", "value", "version")] [InlineData("name", "http://www.w3.org/2001/XMLSchema-instance", "value", "version")] - public void TryParseAttribute_Invoke_ReturnsFalse(string name, string ns, string value, string version) + public void TryParseAttribute_Invoke_ReturnsFalse(string? name, string? ns, string? value, string? version) { var collectionInfo = new ResourceCollectionInfoSubclass(); Assert.False(collectionInfo.TryParseAttributeEntryPoint(name, ns, value, version)); @@ -273,7 +273,7 @@ public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteAttributeExtensions_Invoke_ReturnsExpected(string version) + public void WriteAttributeExtensions_Invoke_ReturnsExpected(string? version) { var collectionInfo = new ResourceCollectionInfoSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => collectionInfo.WriteAttributeExtensionsEntryPoint(writer, version)); @@ -295,7 +295,7 @@ public void WriteAttributeExtensions_NullWriter_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteElementExtensions_Invoke_ReturnsExpected(string version) + public void WriteElementExtensions_Invoke_ReturnsExpected(string? version) { var collectionInfo = new ResourceCollectionInfoSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => collectionInfo.WriteElementExtensionsEntryPoint(writer, version)); diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/ServiceDocumentTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/ServiceDocumentTests.cs index bc39ffaba44a63..226b53c045e068 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/ServiceDocumentTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/ServiceDocumentTests.cs @@ -102,7 +102,7 @@ public void Workspaces_SetNullItem_ThrowsArgumentNullException() [InlineData("name", "http://www.w3.org/2000/xmlns/", "value", "version")] [InlineData("type", "ns", "value", "version")] [InlineData("name", "http://www.w3.org/2001/XMLSchema-instance", "value", "version")] - public void TryParseAttribute_Invoke_ReturnsFalse(string name, string ns, string value, string version) + public void TryParseAttribute_Invoke_ReturnsFalse(string? name, string? ns, string? value, string? version) { var document = new ServiceDocumentSubclass(); Assert.False(document.TryParseAttributeEntryPoint(name, ns, value, version)); @@ -117,7 +117,7 @@ public static IEnumerable TryParseElement_TestData() [Theory] [MemberData(nameof(TryParseElement_TestData))] - public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version) + public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string? version) { var document = new ServiceDocumentSubclass(); Assert.False(document.TryParseElementEntryPoint(reader, version)); @@ -127,7 +127,7 @@ public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteAttributeExtensions_Invoke_ReturnsExpected(string version) + public void WriteAttributeExtensions_Invoke_ReturnsExpected(string? version) { var document = new ServiceDocumentSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => document.WriteAttributeExtensionsEntryPoint(writer, version)); @@ -149,7 +149,7 @@ public void WriteAttributeExtensions_NullWriter_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteElementExtensions_Invoke_ReturnsExpected(string version) + public void WriteElementExtensions_Invoke_ReturnsExpected(string? version) { var document = new ServiceDocumentSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => document.WriteElementExtensionsEntryPoint(writer, version)); diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationCategoryTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationCategoryTests.cs index a7ca29f8b99e62..693fd704decfca 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationCategoryTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationCategoryTests.cs @@ -26,7 +26,7 @@ public void Ctor_Default() [InlineData(null)] [InlineData("")] [InlineData("name")] - public void Ctor_String(string name) + public void Ctor_String(string? name) { var category = new SyndicationCategory(name); Assert.Empty(category.AttributeExtensions); @@ -40,7 +40,7 @@ public void Ctor_String(string name) [InlineData(null, null, null)] [InlineData("", "", "")] [InlineData("name", "scheme", "label")] - public void Ctor_String_String_String(string name, string scheme, string label) + public void Ctor_String_String_String(string? name, string? scheme, string? label) { var category = new SyndicationCategory(name, scheme, label); Assert.Empty(category.AttributeExtensions); @@ -130,7 +130,7 @@ public void Clone_Empty_ReturnsExpected() [InlineData("name", "http://www.w3.org/2000/xmlns/", "value", "version")] [InlineData("type", "ns", "value", "version")] [InlineData("name", "http://www.w3.org/2001/XMLSchema-instance", "value", "version")] - public void TryParseAttribute_Invoke_ReturnsFalse(string name, string ns, string value, string version) + public void TryParseAttribute_Invoke_ReturnsFalse(string? name, string? ns, string? value, string? version) { var category = new SyndicationCategorySubclass(); Assert.False(category.TryParseAttributeEntryPoint(name, ns, value, version)); @@ -145,7 +145,7 @@ public static IEnumerable TryParseElement_TestData() [Theory] [MemberData(nameof(TryParseElement_TestData))] - public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version) + public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string? version) { var category = new SyndicationCategorySubclass(); Assert.False(category.TryParseElementEntryPoint(reader, version)); @@ -155,7 +155,7 @@ public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteAttributeExtensions_Invoke_ReturnsExpected(string version) + public void WriteAttributeExtensions_Invoke_ReturnsExpected(string? version) { var category = new SyndicationCategorySubclass(); CompareHelper.AssertEqualWriteOutput("", writer => category.WriteAttributeExtensionsEntryPoint(writer, version)); @@ -177,7 +177,7 @@ public void WriteAttributeExtensions_NullWriter_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteElementExtensions_Invoke_ReturnsExpected(string version) + public void WriteElementExtensions_Invoke_ReturnsExpected(string? version) { var category = new SyndicationCategorySubclass(); CompareHelper.AssertEqualWriteOutput("", writer => category.WriteElementExtensionsEntryPoint(writer, version)); diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationContentTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationContentTests.cs index 9b07ba9340e6b2..6cbc3325791338 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationContentTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationContentTests.cs @@ -89,7 +89,7 @@ public void WriteTo_NullWriter_ThrowsArgumentNullException() [Theory] [InlineData(null)] [InlineData("")] - public void WriteTo_EmptyOrNullName_ThrowsArgumentException(string outerElementName) + public void WriteTo_EmptyOrNullName_ThrowsArgumentException(string? outerElementName) { var content = new SyndicationContentSubclass(); using (var stringWriter = new StringWriter()) @@ -103,7 +103,7 @@ public void WriteTo_EmptyOrNullName_ThrowsArgumentException(string outerElementN [InlineData(null)] [InlineData("")] [InlineData("content")] - public void CreateHtmlContent_Invoke_ReturnsExpected(string content) + public void CreateHtmlContent_Invoke_ReturnsExpected(string? content) { TextSyndicationContent syndicationContent = SyndicationContent.CreateHtmlContent(content); Assert.Empty(syndicationContent.AttributeExtensions); @@ -115,7 +115,7 @@ public void CreateHtmlContent_Invoke_ReturnsExpected(string content) [InlineData(null)] [InlineData("")] [InlineData("content")] - public void CreatePlainContent_Invoke_ReturnsExpected(string content) + public void CreatePlainContent_Invoke_ReturnsExpected(string? content) { TextSyndicationContent syndicationContent = SyndicationContent.CreatePlaintextContent(content); Assert.Empty(syndicationContent.AttributeExtensions); @@ -127,7 +127,7 @@ public void CreatePlainContent_Invoke_ReturnsExpected(string content) [InlineData(null)] [InlineData("")] [InlineData("content")] - public void CreateXhtmlContent_Invoke_ReturnsExpected(string content) + public void CreateXhtmlContent_Invoke_ReturnsExpected(string? content) { TextSyndicationContent syndicationContent = SyndicationContent.CreateXhtmlContent(content); Assert.Empty(syndicationContent.AttributeExtensions); diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationElementExtensionCollectionTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationElementExtensionCollectionTests.cs index a8b352822cfc7a..09608540635763 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationElementExtensionCollectionTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationElementExtensionCollectionTests.cs @@ -164,7 +164,7 @@ public void ReadElementExtensions_Invoke_ReturnsExpected() [InlineData("SyndicationElementExtensionCollectionTests.extensionobject", "http://schemas.datacontract.org/2004/07/System.ServiceModel.Syndication.Tests")] [InlineData("SyndicationElementExtensionCollectionTests.ExtensionObject", "http://schemas.datacontract.org/2004/07/system.servicemodel.syndication.tests")] [InlineData("SyndicationElementExtensionCollectionTests.ExtensionObject", "System.ServiceModel.Syndication.Tests")] - public void ReadElementExtensions_NoSuchObject_ReturnsEmpty(string name, string ns) + public void ReadElementExtensions_NoSuchObject_ReturnsEmpty(string name, string? ns) { SyndicationElementExtensionCollection elementExtensions = new SyndicationCategory().ElementExtensions; elementExtensions.Add(new ExtensionObject { Value = 10 }); diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationElementExtensionTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationElementExtensionTests.cs index e7d57bb2c2d214..4bbe2269b9cf53 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationElementExtensionTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationElementExtensionTests.cs @@ -104,7 +104,7 @@ public void Ctor_DataContractExtension_XmlObjectSerializer(XmlObjectSerializer s [InlineData(null, "outerNamespace")] [InlineData("outerName", "")] [InlineData("outerName", "outerNamespace")] - public void Ctor_String_String_Object(string outerName, string outerNamespace) + public void Ctor_String_String_Object(string? outerName, string? outerNamespace) { var extensionObject = new ExtensionObject { Value = 10 }; @@ -134,7 +134,7 @@ public void Ctor_String_String_Object(string outerName, string outerNamespace) [InlineData(null, "outerNamespace")] [InlineData("outerName", "")] [InlineData("outerName", "outerNamespace")] - public void Ctor_String_String_Object_XmlObjectSerializer(string outerName, string outerNamespace) + public void Ctor_String_String_Object_XmlObjectSerializer(string? outerName, string? outerNamespace) { var extensionObject = new ExtensionObject { Value = 10 }; diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationFeedTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationFeedTests.cs index 280929d010f955..67c30bd13eaf66 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationFeedTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationFeedTests.cs @@ -28,7 +28,7 @@ public static IEnumerable Ctor_Items_TestData() [Theory] [InlineData(null)] [MemberData(nameof(Ctor_Items_TestData))] - public void Ctor_Items(IEnumerable items) + public void Ctor_Items(IEnumerable? items) { var feed = new SyndicationFeed(items); VerifySyndicationFeed(feed, null, null, null, null, default, items); @@ -313,7 +313,7 @@ public void CreatePerson_Invoke_ReturnsExpected() [InlineData("name", "http://www.w3.org/2000/xmlns/", "value", "version")] [InlineData("type", "ns", "value", "version")] [InlineData("name", "http://www.w3.org/2001/XMLSchema-instance", "value", "version")] - public void TryParseAttribute_Invoke_ReturnsFalse(string name, string ns, string value, string version) + public void TryParseAttribute_Invoke_ReturnsFalse(string? name, string? ns, string? value, string? version) { var feed = new SyndicationFeedSubclass(); Assert.False(feed.TryParseAttributeEntryPoint(name, ns, value, version)); @@ -328,7 +328,7 @@ public static IEnumerable TryParseElement_TestData() [Theory] [MemberData(nameof(TryParseElement_TestData))] - public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version) + public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string? version) { var feed = new SyndicationFeedSubclass(); Assert.False(feed.TryParseElementEntryPoint(reader, version)); @@ -338,7 +338,7 @@ public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteAttributeExtensions_Invoke_ReturnsExpected(string version) + public void WriteAttributeExtensions_Invoke_ReturnsExpected(string? version) { var feed = new SyndicationFeedSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => feed.WriteAttributeExtensionsEntryPoint(writer, version)); @@ -360,7 +360,7 @@ public void WriteAttributeExtensions_NullWriter_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteElementExtensions_Invoke_ReturnsExpected(string version) + public void WriteElementExtensions_Invoke_ReturnsExpected(string? version) { var feed = new SyndicationFeedSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => feed.WriteElementExtensionsEntryPoint(writer, version)); diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationItemTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationItemTests.cs index e5f8f7842d8bde..3076afebb46083 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationItemTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationItemTests.cs @@ -506,7 +506,7 @@ public void CreatePerson_Invoke_ReturnsExpected() [InlineData("name", "http://www.w3.org/2000/xmlns/", "value", "version")] [InlineData("type", "ns", "value", "version")] [InlineData("name", "http://www.w3.org/2001/XMLSchema-instance", "value", "version")] - public void TryParseAttribute_Invoke_ReturnsFalse(string name, string ns, string value, string version) + public void TryParseAttribute_Invoke_ReturnsFalse(string? name, string? ns, string? value, string? version) { var item = new SyndicationItemSubclass(); Assert.False(item.TryParseAttributeEntryPoint(name, ns, value, version)); @@ -537,7 +537,7 @@ public static IEnumerable TryParseElement_TestData() [Theory] [MemberData(nameof(TryParseElement_TestData))] - public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version) + public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string? version) { var item = new SyndicationItemSubclass(); Assert.False(item.TryParseElementEntryPoint(reader, version)); @@ -547,7 +547,7 @@ public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteAttributeExtensions_Invoke_ReturnsExpected(string version) + public void WriteAttributeExtensions_Invoke_ReturnsExpected(string? version) { var item = new SyndicationItemSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => item.WriteAttributeExtensionsEntryPoint(writer, version)); @@ -569,7 +569,7 @@ public void WriteAttributeExtensions_NullWriter_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteElementExtensions_Invoke_ReturnsExpected(string version) + public void WriteElementExtensions_Invoke_ReturnsExpected(string? version) { var item = new SyndicationItemSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => item.WriteElementExtensionsEntryPoint(writer, version)); diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationLinkTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationLinkTests.cs index 6ed01307e0cfa4..13ddf7b9508a16 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationLinkTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationLinkTests.cs @@ -319,7 +319,7 @@ public void GetAbsoluteUri_Invoke_ReturnsExpected(SyndicationLink link, Uri expe [InlineData("name", "http://www.w3.org/2000/xmlns/", "value", "version")] [InlineData("type", "ns", "value", "version")] [InlineData("name", "http://www.w3.org/2001/XMLSchema-instance", "value", "version")] - public void TryParseAttribute_Invoke_ReturnsFalse(string name, string ns, string value, string version) + public void TryParseAttribute_Invoke_ReturnsFalse(string? name, string? ns, string? value, string? version) { var link = new SyndicationLinkSubclass(); Assert.False(link.TryParseAttributeEntryPoint(name, ns, value, version)); @@ -334,7 +334,7 @@ public static IEnumerable TryParseElement_TestData() [Theory] [MemberData(nameof(TryParseElement_TestData))] - public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version) + public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string? version) { var link = new SyndicationLinkSubclass(); Assert.False(link.TryParseElementEntryPoint(reader, version)); @@ -344,7 +344,7 @@ public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteAttributeExtensions_Invoke_ReturnsExpected(string version) + public void WriteAttributeExtensions_Invoke_ReturnsExpected(string? version) { var link = new SyndicationLinkSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => link.WriteAttributeExtensionsEntryPoint(writer, version)); @@ -366,7 +366,7 @@ public void WriteAttributeExtensions_NullWriter_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteElementExtensions_Invoke_ReturnsExpected(string version) + public void WriteElementExtensions_Invoke_ReturnsExpected(string? version) { var link = new SyndicationLinkSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => link.WriteElementExtensionsEntryPoint(writer, version)); diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationPersonTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationPersonTests.cs index 0e1f1c84091f62..3a91e08ceaa71e 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationPersonTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/SyndicationPersonTests.cs @@ -26,7 +26,7 @@ public void Ctor_Default() [InlineData(null)] [InlineData("")] [InlineData("email")] - public void Ctor_String(string email) + public void Ctor_String(string? email) { var person = new SyndicationPerson(email); Assert.Empty(person.AttributeExtensions); @@ -40,7 +40,7 @@ public void Ctor_String(string email) [InlineData(null, null, null)] [InlineData("", "", "")] [InlineData("email", "name", "uri")] - public void Ctor_String_String_String(string email, string name, string uri) + public void Ctor_String_String_String(string? email, string? name, string? uri) { var person = new SyndicationPerson(email, name, uri); Assert.Empty(person.AttributeExtensions); @@ -130,7 +130,7 @@ public void Clone_Empty_ReturnsExpected() [InlineData("name", "http://www.w3.org/2000/xmlns/", "value", "version")] [InlineData("type", "ns", "value", "version")] [InlineData("name", "http://www.w3.org/2001/XMLSchema-instance", "value", "version")] - public void TryParseAttribute_Invoke_ReturnsFalse(string name, string ns, string value, string version) + public void TryParseAttribute_Invoke_ReturnsFalse(string? name, string? ns, string? value, string? version) { var person = new SyndicationPersonSubclass(); Assert.False(person.TryParseAttributeEntryPoint(name, ns, value, version)); @@ -145,7 +145,7 @@ public static IEnumerable TryParseElement_TestData() [Theory] [MemberData(nameof(TryParseElement_TestData))] - public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version) + public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string? version) { var person = new SyndicationPersonSubclass(); Assert.False(person.TryParseElementEntryPoint(reader, version)); @@ -155,7 +155,7 @@ public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteAttributeExtensions_Invoke_ReturnsExpected(string version) + public void WriteAttributeExtensions_Invoke_ReturnsExpected(string? version) { var person = new SyndicationPersonSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => person.WriteAttributeExtensionsEntryPoint(writer, version)); @@ -177,7 +177,7 @@ public void WriteAttributeExtensions_NullWriter_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteElementExtensions_Invoke_ReturnsExpected(string version) + public void WriteElementExtensions_Invoke_ReturnsExpected(string? version) { var person = new SyndicationPersonSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => person.WriteElementExtensionsEntryPoint(writer, version)); diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/TextSyndicationContentTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/TextSyndicationContentTests.cs index 1473201dfd3dd5..40f892dd0c8a79 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/TextSyndicationContentTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/TextSyndicationContentTests.cs @@ -12,7 +12,7 @@ public class TextSyndicationContentTests [InlineData(null)] [InlineData("")] [InlineData("text")] - public void Ctor_String(string text) + public void Ctor_String(string? text) { var content = new TextSyndicationContent(text); Assert.Empty(content.AttributeExtensions); @@ -24,7 +24,7 @@ public void Ctor_String(string text) [InlineData(null, TextSyndicationContentKind.Html, "html")] [InlineData("", TextSyndicationContentKind.Plaintext, "text")] [InlineData("text", TextSyndicationContentKind.XHtml, "xhtml")] - public void Ctor_String_TextSyndicationContentKind(string text, TextSyndicationContentKind textKind, string type) + public void Ctor_String_TextSyndicationContentKind(string? text, TextSyndicationContentKind textKind, string type) { var content = new TextSyndicationContent(text, textKind); Assert.Empty(content.AttributeExtensions); diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/WorkspaceTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/WorkspaceTests.cs index 78e30ffea3b39a..0759c1c0489d03 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/WorkspaceTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/WorkspaceTests.cs @@ -134,7 +134,7 @@ public void CreateResoureCollection_Invoke_ReturnsExpected() [InlineData("name", "http://www.w3.org/2000/xmlns/", "value", "version")] [InlineData("type", "ns", "value", "version")] [InlineData("name", "http://www.w3.org/2001/XMLSchema-instance", "value", "version")] - public void TryParseAttribute_Invoke_ReturnsFalse(string name, string ns, string value, string version) + public void TryParseAttribute_Invoke_ReturnsFalse(string? name, string? ns, string? value, string? version) { var workspace = new WorkspaceSubclass(); Assert.False(workspace.TryParseAttributeEntryPoint(name, ns, value, version)); @@ -159,7 +159,7 @@ public void TryParseElement_Invoke_ReturnsFalse(XmlReader reader, string version [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteAttributeExtensions_Invoke_ReturnsExpected(string version) + public void WriteAttributeExtensions_Invoke_ReturnsExpected(string? version) { var workspace = new WorkspaceSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => workspace.WriteAttributeExtensionsEntryPoint(writer, version)); @@ -181,7 +181,7 @@ public void WriteAttributeExtensions_NullWriter_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("version")] - public void WriteElementExtensions_Invoke_ReturnsExpected(string version) + public void WriteElementExtensions_Invoke_ReturnsExpected(string? version) { var workspace = new WorkspaceSubclass(); CompareHelper.AssertEqualWriteOutput("", writer => workspace.WriteElementExtensionsEntryPoint(writer, version)); diff --git a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/XmlSyndicationContentTests.cs b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/XmlSyndicationContentTests.cs index 72653c47447200..57658c1639b9c0 100644 --- a/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/XmlSyndicationContentTests.cs +++ b/src/libraries/System.ServiceModel.Syndication/tests/System/ServiceModel/Syndication/XmlSyndicationContentTests.cs @@ -65,7 +65,7 @@ public void Ctor_NullReader_ThrowsArgumentNullException() [InlineData(null)] [InlineData("")] [InlineData("text/html")] - public void Ctor_Type_SyndicationElementExtension(string type) + public void Ctor_Type_SyndicationElementExtension(string? type) { var extension = new SyndicationElementExtension(new ExtensionObject { Value = 10 }); var content = new XmlSyndicationContent(type, extension); diff --git a/src/libraries/System.ServiceProcess.ServiceController/System.ServiceProcess.ServiceController.slnx b/src/libraries/System.ServiceProcess.ServiceController/System.ServiceProcess.ServiceController.slnx index 22eaa92bfd096c..ea5ccb15e09234 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/System.ServiceProcess.ServiceController.slnx +++ b/src/libraries/System.ServiceProcess.ServiceController/System.ServiceProcess.ServiceController.slnx @@ -1,34 +1,418 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs b/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs index a4223cd161fc17..431c536b91f235 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs @@ -152,7 +152,7 @@ public enum SessionChangeReason public partial class TimeoutException : System.SystemException { public TimeoutException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/TimeoutException.cs b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/TimeoutException.cs index fa3c5092354158..1abd0d33c85881 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/TimeoutException.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/TimeoutException.cs @@ -28,7 +28,7 @@ public TimeoutException(string? message, Exception? innerException) HResult = ServiceControllerTimeout; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Speech/Directory.Build.props b/src/libraries/System.Speech/Directory.Build.props index d43c87c09cb684..6611932df4426a 100644 --- a/src/libraries/System.Speech/Directory.Build.props +++ b/src/libraries/System.Speech/Directory.Build.props @@ -3,5 +3,6 @@ MicrosoftShared windows + false \ No newline at end of file diff --git a/src/libraries/System.Speech/src/Internal/ObjectToken/RegistryDataKey.cs b/src/libraries/System.Speech/src/Internal/ObjectToken/RegistryDataKey.cs index 1acdb786aaca1f..a4aba4f2b5e872 100644 --- a/src/libraries/System.Speech/src/Internal/ObjectToken/RegistryDataKey.cs +++ b/src/libraries/System.Speech/src/Internal/ObjectToken/RegistryDataKey.cs @@ -484,12 +484,13 @@ private static string GetFirstKeyAndParseRemainder(ref string registryPath) private static RegistryKey RegKeyFromRootPath(string rootPath) { - RegistryKey[] roots = new RegistryKey[] { + ReadOnlySpan roots = + [ Registry.ClassesRoot, Registry.LocalMachine, Registry.CurrentUser, Registry.CurrentConfig - }; + ]; foreach (RegistryKey key in roots) { diff --git a/src/libraries/System.Speech/src/Internal/Synthesis/AudioException.cs b/src/libraries/System.Speech/src/Internal/Synthesis/AudioException.cs index 207e5d0557dd4d..b3b0880c4c24f3 100644 --- a/src/libraries/System.Speech/src/Internal/Synthesis/AudioException.cs +++ b/src/libraries/System.Speech/src/Internal/Synthesis/AudioException.cs @@ -17,7 +17,7 @@ internal AudioException(Interop.WinMM.MMSYSERR errorCode) : base(string.Format(S { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Speech/src/System.Speech.csproj b/src/libraries/System.Speech/src/System.Speech.csproj index f06f73fd105f8b..61723c53f0b3a5 100644 --- a/src/libraries/System.Speech/src/System.Speech.csproj +++ b/src/libraries/System.Speech/src/System.Speech.csproj @@ -15,7 +15,6 @@ $(NoWarn);CS1591 true - false true true true diff --git a/src/libraries/System.Text.Encoding.CodePages/System.Text.Encoding.CodePages.slnx b/src/libraries/System.Text.Encoding.CodePages/System.Text.Encoding.CodePages.slnx index 7ec59fd0826a33..1c420aed94a103 100644 --- a/src/libraries/System.Text.Encoding.CodePages/System.Text.Encoding.CodePages.slnx +++ b/src/libraries/System.Text.Encoding.CodePages/System.Text.Encoding.CodePages.slnx @@ -1,31 +1,274 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System.Text.Encoding.CodePages.csproj b/src/libraries/System.Text.Encoding.CodePages/src/System.Text.Encoding.CodePages.csproj index f425fd1deb0019..7bcf0ad07a5a16 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System.Text.Encoding.CodePages.csproj +++ b/src/libraries/System.Text.Encoding.CodePages/src/System.Text.Encoding.CodePages.csproj @@ -81,11 +81,11 @@ System.Text.CodePagesEncodingProvider - - - - - + + + + + diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/DBCSCodePageEncoding.cs b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/DBCSCodePageEncoding.cs index 8bd9670e356bfc..ae3cdfbb6b4a89 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/DBCSCodePageEncoding.cs +++ b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/DBCSCodePageEncoding.cs @@ -225,19 +225,8 @@ protected virtual unsafe void CleanUpEndBytes(char* chars) } // Private object for locking instead of locking on a public type for SQL reliability work. - private static object? s_InternalSyncObject; - private static object InternalSyncObject - { - get - { - if (s_InternalSyncObject == null) - { - object o = new object(); - Interlocked.CompareExchange(ref s_InternalSyncObject, o, null); - } - return s_InternalSyncObject; - } - } + private static object InternalSyncObject => + field ?? Interlocked.CompareExchange(ref field, new object(), null) ?? field; // Read in our best fit table protected override unsafe void ReadBestFitTable() diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/DecoderBestFitFallback.cs b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/DecoderBestFitFallback.cs index 90eb8b958e3e4e..66aff6b17a675f 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/DecoderBestFitFallback.cs +++ b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/DecoderBestFitFallback.cs @@ -47,19 +47,8 @@ internal sealed class InternalDecoderBestFitFallbackBuffer : DecoderFallbackBuff private readonly InternalDecoderBestFitFallback _oFallback; // Private object for locking instead of locking on a public type for SQL reliability work. - private static object? s_InternalSyncObject; - private static object InternalSyncObject - { - get - { - if (s_InternalSyncObject == null) - { - object o = new object(); - Interlocked.CompareExchange(ref s_InternalSyncObject, o, null); - } - return s_InternalSyncObject; - } - } + private static object InternalSyncObject => + field ?? Interlocked.CompareExchange(ref field, new object(), null) ?? field; // Constructor public InternalDecoderBestFitFallbackBuffer(InternalDecoderBestFitFallback fallback) diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/EncoderBestFitFallback.cs b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/EncoderBestFitFallback.cs index 1342edf8b15c49..2aa7cf75910a92 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/EncoderBestFitFallback.cs +++ b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/EncoderBestFitFallback.cs @@ -47,19 +47,8 @@ internal sealed class InternalEncoderBestFitFallbackBuffer : EncoderFallbackBuff private int _iSize; // Private object for locking instead of locking on a public type for SQL reliability work. - private static object? s_InternalSyncObject; - private static object InternalSyncObject - { - get - { - if (s_InternalSyncObject == null) - { - object o = new object(); - Interlocked.CompareExchange(ref s_InternalSyncObject, o, null); - } - return s_InternalSyncObject; - } - } + private static object InternalSyncObject => + field ?? Interlocked.CompareExchange(ref field, new object(), null) ?? field; // Constructor public InternalEncoderBestFitFallbackBuffer(InternalEncoderBestFitFallback fallback) diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/SBCSCodePageEncoding.cs b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/SBCSCodePageEncoding.cs index 184f88b8e656b0..5fda8e1215bf37 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/SBCSCodePageEncoding.cs +++ b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/SBCSCodePageEncoding.cs @@ -129,19 +129,8 @@ protected override unsafe void LoadManagedCodePage() } // Private object for locking instead of locking on a public type for SQL reliability work. - private static object? s_InternalSyncObject; - private static object InternalSyncObject - { - get - { - if (s_InternalSyncObject == null) - { - object o = new object(); - Interlocked.CompareExchange(ref s_InternalSyncObject, o, null); - } - return s_InternalSyncObject; - } - } + private static object InternalSyncObject => + field ?? Interlocked.CompareExchange(ref field, new object(), null) ?? field; // Read in our best fit table protected override unsafe void ReadBestFitTable() diff --git a/src/libraries/System.Text.Encodings.Web/System.Text.Encodings.Web.slnx b/src/libraries/System.Text.Encodings.Web/System.Text.Encodings.Web.slnx index 5ed34628476684..cdf191872d268d 100644 --- a/src/libraries/System.Text.Encodings.Web/System.Text.Encodings.Web.slnx +++ b/src/libraries/System.Text.Encodings.Web/System.Text.Encodings.Web.slnx @@ -1,29 +1,234 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Text.Encodings.Web/src/System.Text.Encodings.Web.csproj b/src/libraries/System.Text.Encodings.Web/src/System.Text.Encodings.Web.csproj index fea0b9e7df62f0..d37d1bcfeb791d 100644 --- a/src/libraries/System.Text.Encodings.Web/src/System.Text.Encodings.Web.csproj +++ b/src/libraries/System.Text.Encodings.Web/src/System.Text.Encodings.Web.csproj @@ -60,11 +60,11 @@ System.Text.Encodings.Web.JavaScriptEncoder - - - - - + + + + + diff --git a/src/libraries/System.Text.Json/System.Text.Json.slnx b/src/libraries/System.Text.Json/System.Text.Json.slnx index d9b773c4d63777..533699a28b0e73 100644 --- a/src/libraries/System.Text.Json/System.Text.Json.slnx +++ b/src/libraries/System.Text.Json/System.Text.Json.slnx @@ -1,66 +1,882 @@ + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index 0554df8190e778..cea226f6fadf40 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -156,7 +156,7 @@ public void Reset() { } public partial class JsonException : System.Exception { public JsonException() { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -169,7 +169,7 @@ public JsonException(string? message, string? path, long? lineNumber, long? byte public long? LineNumber { get { throw null; } } public override string Message { get { throw null; } } public string? Path { get { throw null; } } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif @@ -256,6 +256,11 @@ public static partial class JsonSerializer [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Pipelines.PipeReader utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Pipelines.PipeReader utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Pipelines.PipeReader utf8Json, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] @@ -263,6 +268,14 @@ public static partial class JsonSerializer public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] + public static System.Collections.Generic.IAsyncEnumerable DeserializeAsyncEnumerable(System.IO.Pipelines.PipeReader utf8Json, bool topLevelValues, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] + public static System.Collections.Generic.IAsyncEnumerable DeserializeAsyncEnumerable(System.IO.Pipelines.PipeReader utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Collections.Generic.IAsyncEnumerable DeserializeAsyncEnumerable(System.IO.Pipelines.PipeReader utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, bool topLevelValues, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Collections.Generic.IAsyncEnumerable DeserializeAsyncEnumerable(System.IO.Pipelines.PipeReader utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Collections.Generic.IAsyncEnumerable DeserializeAsyncEnumerable(System.IO.Stream utf8Json, bool topLevelValues, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] @@ -271,6 +284,10 @@ public static partial class JsonSerializer public static System.Collections.Generic.IAsyncEnumerable DeserializeAsyncEnumerable(System.IO.Stream utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Pipelines.PipeReader utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Pipelines.PipeReader utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj index dc2e4d28e75f03..e10aaaa3992b1d 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj @@ -20,6 +20,7 @@ + diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs index bbf2e3846a6bcd..5a4559e186b6df 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs @@ -12,10 +12,8 @@ public static partial class JsonMetadataServices public static System.Text.Json.Serialization.JsonConverter HalfConverter { get { throw null; } } public static System.Text.Json.Serialization.JsonConverter TimeOnlyConverter { get { throw null; } } -#if NET public static System.Text.Json.Serialization.JsonConverter Int128Converter { get { throw null; } } [System.CLSCompliantAttribute(false)] public static System.Text.Json.Serialization.JsonConverter UInt128Converter { get { throw null; } } -#endif } } diff --git a/src/libraries/System.Text.Json/src/Resources/Strings.resx b/src/libraries/System.Text.Json/src/Resources/Strings.resx index 906b4bc2b5c5b9..9aef3d3e90ab99 100644 --- a/src/libraries/System.Text.Json/src/Resources/Strings.resx +++ b/src/libraries/System.Text.Json/src/Resources/Strings.resx @@ -830,10 +830,13 @@ Duplicate property '{0}' encountered during deserialization of type '{1}'. - + Duplicate property '{0}' encountered during deserialization. Duplicate properties not allowed during deserialization. - + + PipeReader.ReadAsync was canceled. + + \ No newline at end of file diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index ae01e453ad574c..e8106e1f215008 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -88,6 +88,7 @@ The System.Text.Json library is built-in as part of the shared framework in .NET + @@ -137,10 +138,12 @@ The System.Text.Json library is built-in as part of the shared framework in .NET + + @@ -159,6 +162,7 @@ The System.Text.Json library is built-in as part of the shared framework in .NET + @@ -294,7 +298,7 @@ The System.Text.Json library is built-in as part of the shared framework in .NET - + @@ -350,6 +354,7 @@ The System.Text.Json library is built-in as part of the shared framework in .NET + @@ -403,29 +408,27 @@ The System.Text.Json library is built-in as part of the shared framework in .NET - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.cs index ca840028bdf975..bf0d5170468773 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.cs @@ -694,29 +694,7 @@ internal bool TryGetValue(int index, out Guid value) ReadOnlySpan data = _utf8Json.Span; ReadOnlySpan segment = data.Slice(row.Location, row.SizeOrLength); - if (segment.Length > JsonConstants.MaximumEscapedGuidLength) - { - value = default; - return false; - } - - // Segment needs to be unescaped - if (row.HasComplexChildren) - { - return JsonReaderHelper.TryGetEscapedGuid(segment, out value); - } - - Debug.Assert(segment.IndexOf(JsonConstants.BackSlash) == -1); - - if (segment.Length == JsonConstants.MaximumFormatGuidLength - && Utf8Parser.TryParse(segment, out Guid tmp, out _, 'D')) - { - value = tmp; - return true; - } - - value = default; - return false; + return JsonReaderHelper.TryGetValue(segment, row.HasComplexChildren, out value); } internal string GetRawValueAsString(int index) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/JsonException.cs b/src/libraries/System.Text.Json/src/System/Text/Json/JsonException.cs index d3301362fcc1a8..8d8f2b349f5097 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/JsonException.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/JsonException.cs @@ -85,7 +85,7 @@ public JsonException() : base() { } /// /// Thrown when is . /// -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif @@ -107,7 +107,7 @@ protected JsonException(SerializationInfo info, StreamingContext context) : base /// /// The that holds the serialized object data about the exception being thrown. /// The that contains contextual information about the source or destination. -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.cs index 46c5b240b8c0db..7b836147cc58cc 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.cs @@ -299,7 +299,7 @@ public static void ValidateInt32MaxArrayLength(uint length) } } -#if !NET8_0_OR_GREATER +#if !NET public static bool HasAllSet(this BitArray bitArray) { for (int i = 0; i < bitArray.Count; i++) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs index 54dfdd3c0c9934..4721b3d02aafbc 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonArray.cs @@ -162,7 +162,7 @@ private void InitializeFromSpan(ReadOnlySpan items) { List list = new(items.Length); -#if NET8_0_OR_GREATER +#if NET list.AddRange(items); #else foreach (JsonNode? item in items) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.To.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.To.cs index fd86c0b19a31bc..97215bae51c85c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.To.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonNode.To.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Threading; - namespace System.Text.Json.Nodes { public abstract partial class JsonNode @@ -44,14 +42,14 @@ public override string ToString() // Special case for string; don't quote it. if (this is JsonValue) { - if (this is JsonValuePrimitive jsonString) - { - return jsonString.Value; - } - - if (this is JsonValueOfElement { Value.ValueKind: JsonValueKind.String } jsonElement) + switch (this) { - return jsonElement.Value.GetString()!; + case JsonValuePrimitive jsonString: + return jsonString.Value; + case JsonValueOfElement { Value.ValueKind: JsonValueKind.String } jsonElement: + return jsonElement.Value.GetString()!; + case JsonValueOfJsonString jsonValueOfJsonString: + return jsonValueOfJsonString.GetValue()!; } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonObject.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonObject.cs index ebab8d554de25e..be00902ce449f4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonObject.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonObject.cs @@ -267,14 +267,14 @@ internal void SetItem(string propertyName, JsonNode? value) OrderedDictionary dict = Dictionary; if ( -#if NET10_0_OR_GREATER - !dict.TryAdd(propertyName, value, out int index) -#else +#if NET9_0 !dict.TryAdd(propertyName, value) +#else + !dict.TryAdd(propertyName, value, out int index) #endif ) { -#if !NET10_0_OR_GREATER +#if NET9_0 int index = dict.IndexOf(propertyName); #endif Debug.Assert(index >= 0); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonValueOfJsonPrimitive.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonValueOfJsonPrimitive.cs new file mode 100644 index 00000000000000..78f1f1af55853f --- /dev/null +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Nodes/JsonValueOfJsonPrimitive.cs @@ -0,0 +1,318 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers; +using System.Buffers.Text; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Text.Encodings.Web; + +namespace System.Text.Json.Nodes +{ + internal static class JsonValueOfJsonPrimitive + { + internal static JsonValue CreatePrimitiveValue(ref Utf8JsonReader reader, JsonNodeOptions options) + { + switch (reader.TokenType) + { + case JsonTokenType.False: + case JsonTokenType.True: + return new JsonValueOfJsonBool(reader.GetBoolean(), options); + case JsonTokenType.String: + byte[] buffer = new byte[reader.ValueLength]; + ReadOnlyMemory utf8String = buffer.AsMemory(0, reader.CopyString(buffer)); + return new JsonValueOfJsonString(utf8String, options); + case JsonTokenType.Number: + byte[] numberValue = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan.ToArray(); + return new JsonValueOfJsonNumber(numberValue, options); + default: + Debug.Fail("Only primitives allowed."); + ThrowHelper.ThrowJsonException(); + return null!; // Unreachable, but required for compilation. + } + } + } + + internal sealed class JsonValueOfJsonString : JsonValue + { + private readonly ReadOnlyMemory _value; + + internal JsonValueOfJsonString(ReadOnlyMemory utf8String, JsonNodeOptions? options) + : base(options) + { + _value = utf8String; + } + + internal override JsonNode DeepCloneCore() => new JsonValueOfJsonString(_value, Options); + private protected override JsonValueKind GetValueKindCore() => JsonValueKind.String; + + public override void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? options = null) + { + ArgumentNullException.ThrowIfNull(writer); + + writer.WriteStringValue(_value.Span); + } + + public override T GetValue() + { + if (!TryGetValue(out T? value)) + { + ThrowHelper.ThrowInvalidOperationException_NodeUnableToConvertElement(JsonValueKind.String, typeof(T)); + } + + return value; + } + + public override bool TryGetValue([NotNullWhen(true)] out T? value) + where T : default + { + if (typeof(T) == typeof(JsonElement)) + { + value = (T)(object)JsonWriterHelper.WriteString(_value.Span, static serialized => JsonElement.Parse(serialized)); + return true; + } + + if (typeof(T) == typeof(string)) + { + string? result = JsonReaderHelper.TranscodeHelper(_value.Span); + + Debug.Assert(result != null); + value = (T)(object)result; + return true; + } + + bool success; + + if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(DateTime?)) + { + success = JsonReaderHelper.TryGetValue(_value.Span, isEscaped: false, out DateTime result); + value = (T)(object)result; + return success; + } + + if (typeof(T) == typeof(DateTimeOffset) || typeof(T) == typeof(DateTimeOffset?)) + { + success = JsonReaderHelper.TryGetValue(_value.Span, isEscaped: false, out DateTimeOffset result); + value = (T)(object)result; + return success; + } + + if (typeof(T) == typeof(Guid) || typeof(T) == typeof(Guid?)) + { + success = JsonReaderHelper.TryGetValue(_value.Span, isEscaped: false, out Guid result); + value = (T)(object)result; + return success; + } + + if (typeof(T) == typeof(char) || typeof(T) == typeof(char?)) + { + string? result = JsonReaderHelper.TranscodeHelper(_value.Span); + + Debug.Assert(result != null); + if (result.Length == 1) + { + value = (T)(object)result[0]; + return true; + } + } + + value = default!; + return false; + } + } + + internal sealed class JsonValueOfJsonBool : JsonValue + { + private readonly bool _value; + + private JsonValueKind ValueKind => _value ? JsonValueKind.True : JsonValueKind.False; + + internal JsonValueOfJsonBool(bool value, JsonNodeOptions? options) + : base(options) + { + _value = value; + } + + public override void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? options = null) => writer.WriteBooleanValue(_value); + internal override JsonNode DeepCloneCore() => new JsonValueOfJsonBool(_value, Options); + private protected override JsonValueKind GetValueKindCore() => ValueKind; + + public override T GetValue() + { + if (!TryGetValue(out T? value)) + { + ThrowHelper.ThrowInvalidOperationException_NodeUnableToConvertElement(_value ? JsonValueKind.True : JsonValueKind.False, typeof(T)); + } + + return value; + } + + public override bool TryGetValue([NotNullWhen(true)] out T? value) + where T : default + { + if (typeof(T) == typeof(JsonElement)) + { + value = (T)(object)JsonElement.Parse(_value ? JsonConstants.TrueValue : JsonConstants.FalseValue); + return true; + } + + if (typeof(T) == typeof(bool) || typeof(T) == typeof(bool?)) + { + value = (T)(object)_value; + return true; + } + + value = default!; + return false; + } + } + + internal sealed class JsonValueOfJsonNumber : JsonValue + { + // This can be optimized to store the decimal point position and the exponent so that + // conversion to different numeric types can be done without parsing the string again. + // Utf8Parser uses an internal ref struct, Number.NumberBuffer, which is really the + // same functionality that we would want here. + private readonly byte[] _value; + + internal JsonValueOfJsonNumber(byte[] number, JsonNodeOptions? options) + : base(options) + { + _value = number; + } + + internal override JsonNode DeepCloneCore() => new JsonValueOfJsonNumber(_value, Options); + private protected override JsonValueKind GetValueKindCore() => JsonValueKind.Number; + + public override T GetValue() + { + if (!TryGetValue(out T? value)) + { + ThrowHelper.ThrowInvalidOperationException_NodeUnableToConvertElement(JsonValueKind.Number, typeof(T)); + } + + return value; + } + + public override bool TryGetValue([NotNullWhen(true)] out T? value) + where T : default + { + if (typeof(T) == typeof(JsonElement)) + { + value = (T)(object)JsonElement.Parse(_value); + return true; + } + + bool success; + + if (typeof(T) == typeof(int) || typeof(T) == typeof(int?)) + { + success = Utf8Parser.TryParse(_value, out int result, out int consumed) && + consumed == _value.Length; + + value = (T)(object)result; + return success; + } + + if (typeof(T) == typeof(long) || typeof(T) == typeof(long?)) + { + success = Utf8Parser.TryParse(_value, out long result, out int consumed) && + consumed == _value.Length; + + value = (T)(object)result; + return success; + } + + if (typeof(T) == typeof(double) || typeof(T) == typeof(double?)) + { + success = Utf8Parser.TryParse(_value, out double result, out int consumed) && + consumed == _value.Length; + + value = (T)(object)result; + return success; + } + + if (typeof(T) == typeof(short) || typeof(T) == typeof(short?)) + { + success = Utf8Parser.TryParse(_value, out short result, out int consumed) && + consumed == _value.Length; + + value = (T)(object)result; + return success; + } + + if (typeof(T) == typeof(decimal) || typeof(T) == typeof(decimal?)) + { + success = Utf8Parser.TryParse(_value, out decimal result, out int consumed) && + consumed == _value.Length; + + value = (T)(object)result; + return success; + } + + if (typeof(T) == typeof(byte) || typeof(T) == typeof(byte?)) + { + success = Utf8Parser.TryParse(_value, out byte result, out int consumed) && + consumed == _value.Length; + + value = (T)(object)result; + return success; + } + + if (typeof(T) == typeof(float) || typeof(T) == typeof(float?)) + { + success = Utf8Parser.TryParse(_value, out float result, out int consumed) && + consumed == _value.Length; + + value = (T)(object)result; + return success; + } + + if (typeof(T) == typeof(uint) || typeof(T) == typeof(uint?)) + { + success = Utf8Parser.TryParse(_value, out uint result, out int consumed) && + consumed == _value.Length; + + value = (T)(object)result; + return success; + } + + if (typeof(T) == typeof(ushort) || typeof(T) == typeof(ushort?)) + { + success = Utf8Parser.TryParse(_value, out ushort result, out int consumed) && + consumed == _value.Length; + + value = (T)(object)result; + return success; + } + + if (typeof(T) == typeof(ulong) || typeof(T) == typeof(ulong?)) + { + success = Utf8Parser.TryParse(_value, out ulong result, out int consumed) && + consumed == _value.Length; + + value = (T)(object)result; + return success; + } + + if (typeof(T) == typeof(sbyte) || typeof(T) == typeof(sbyte?)) + { + success = Utf8Parser.TryParse(_value, out sbyte result, out int consumed) && + consumed == _value.Length; + + value = (T)(object)result; + return success; + } + + value = default!; + return false; + } + + public override void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? options = null) + { + ArgumentNullException.ThrowIfNull(writer); + + writer.WriteNumberValue(_value); + } + } +} diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs index a50c91c9452913..4a22e0410dacc3 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs @@ -13,7 +13,7 @@ public JsonReaderException(string message, long lineNumber, long bytePositionInL { } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif private JsonReaderException(SerializationInfo info, StreamingContext context) : base(info, context) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.Unescaping.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.Unescaping.cs index 60768cab4d44dc..bc684782277bdf 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.Unescaping.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.Unescaping.cs @@ -321,7 +321,7 @@ public static int TranscodeHelper(ReadOnlySpan utf8Unescaped, Span d public static void ValidateUtf8(ReadOnlySpan utf8Buffer) { -#if NET8_0_OR_GREATER +#if NET if (!Utf8.IsValid(utf8Buffer)) { throw ThrowHelper.GetInvalidOperationException_ReadInvalidUTF8(); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs index 3c748e8fbb988b..036429f9922a0d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs @@ -12,7 +12,7 @@ namespace System.Text.Json internal static partial class JsonReaderHelper { private const string SpecialCharacters = ". '/\"[]()\t\n\r\f\b\\\u0085\u2028\u2029"; -#if NET8_0_OR_GREATER +#if NET private static readonly SearchValues s_specialCharacters = SearchValues.Create(SpecialCharacters); public static bool ContainsSpecialCharacters(this ReadOnlySpan text) => @@ -31,7 +31,7 @@ public static (int, int) CountNewLines(ReadOnlySpan data) { newLines = 1; data = data.Slice(0, lastLineFeedIndex); -#if NET8_0_OR_GREATER +#if NET newLines += data.Count(JsonConstants.LineFeed); #else int pos; @@ -175,6 +175,33 @@ public static bool TryGetEscapedDateTimeOffset(ReadOnlySpan source, out Da return false; } + public static bool TryGetValue(ReadOnlySpan segment, bool isEscaped, out Guid value) + { + if (segment.Length > JsonConstants.MaximumEscapedGuidLength) + { + value = default; + return false; + } + + // Segment needs to be unescaped + if (isEscaped) + { + return TryGetEscapedGuid(segment, out value); + } + + Debug.Assert(segment.IndexOf(JsonConstants.BackSlash) == -1); + + if (segment.Length == JsonConstants.MaximumFormatGuidLength + && Utf8Parser.TryParse(segment, out Guid tmp, out _, 'D')) + { + value = tmp; + return true; + } + + value = default; + return false; + } + public static bool TryGetEscapedGuid(ReadOnlySpan source, out Guid value) { Debug.Assert(source.Length <= JsonConstants.MaximumEscapedGuidLength); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs index 5d59810e106b4d..b7f2e7edd9fea6 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs @@ -1351,31 +1351,10 @@ internal bool TryGetGuidCore(out Guid value) } else { - if (ValueSpan.Length > JsonConstants.MaximumEscapedGuidLength) - { - value = default; - return false; - } - span = ValueSpan; } - if (ValueIsEscaped) - { - return JsonReaderHelper.TryGetEscapedGuid(span, out value); - } - - Debug.Assert(span.IndexOf(JsonConstants.BackSlash) == -1); - - if (span.Length == JsonConstants.MaximumFormatGuidLength - && Utf8Parser.TryParse(span, out Guid tmp, out _, 'D')) - { - value = tmp; - return true; - } - - value = default; - return false; + return JsonReaderHelper.TryGetValue(span, ValueIsEscaped, out value); } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Schema/JsonSchemaExporter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Schema/JsonSchemaExporter.cs index 4f1de1a514b4b0..f528f3564524a9 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Schema/JsonSchemaExporter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Schema/JsonSchemaExporter.cs @@ -347,17 +347,30 @@ JsonSchema CompleteSchema(ref GenerationState state, JsonSchema schema) { if (schema.Ref is null) { - // A schema is marked as nullable if either - // 1. We have a schema for a property where either the getter or setter are marked as nullable. - // 2. We have a schema for a reference type, unless we're explicitly treating null-oblivious types as non-nullable. - bool isNullableSchema = propertyInfo != null - ? propertyInfo.IsGetNullable || propertyInfo.IsSetNullable - : typeInfo.CanBeNull && !parentPolymorphicTypeIsNonNullable && !state.ExporterOptions.TreatNullObliviousAsNonNullable; - - if (isNullableSchema) + if (IsNullableSchema(state.ExporterOptions)) { schema.MakeNullable(); } + + bool IsNullableSchema(JsonSchemaExporterOptions options) + { + // A schema is marked as nullable if either: + // 1. We have a schema for a property where either the getter or setter are marked as nullable. + // 2. We have a schema for a Nullable type. + // 3. We have a schema for a reference type, unless we're explicitly treating null-oblivious types as non-nullable. + + if (propertyInfo is not null) + { + return propertyInfo.IsGetNullable || propertyInfo.IsSetNullable; + } + + if (typeInfo.IsNullable) + { + return true; + } + + return !typeInfo.Type.IsValueType && !parentPolymorphicTypeIsNonNullable && !options.TreatNullObliviousAsNonNullable; + } } if (state.ExporterOptions.TransformSchemaNode != null) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Node/JsonValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Node/JsonValueConverter.cs index bf3e26482a4413..ff7608298514d7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Node/JsonValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Node/JsonValueConverter.cs @@ -43,23 +43,7 @@ public override void Write(Utf8JsonWriter writer, JsonValue? value, JsonSerializ internal static JsonValue ReadNonNullPrimitiveValue(ref Utf8JsonReader reader, JsonNodeOptions options) { Debug.Assert(reader.TokenType is JsonTokenType.String or JsonTokenType.False or JsonTokenType.True or JsonTokenType.Number); - - switch (reader.TokenType) - { - case JsonTokenType.String: - return JsonValue.Create(reader.GetString()!, options); - case JsonTokenType.False: - return JsonValue.Create(false, options); - case JsonTokenType.True: - return JsonValue.Create(true, options); - case JsonTokenType.Number: - // We can't infer CLR type for the number, so we parse it as a JsonElement. - JsonElement element = JsonElement.ParseValue(ref reader); - return JsonValue.CreateFromElement(ref element, options)!; - default: - Debug.Fail("Unexpected token type for primitive value."); - throw new JsonException(); - } + return JsonValueOfJsonPrimitive.CreatePrimitiveValue(ref reader, options); } internal override JsonSchema? GetSchema(JsonNumberHandling _) => JsonSchema.CreateTrueSchema(); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs index d6e1d6cbd3a301..93f64da6c31d1f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs @@ -553,6 +553,13 @@ private static EnumFieldInfo[] ResolveEnumFields(JsonNamingPolicy? namingPolicy) enumFields[i] = new EnumFieldInfo(key, kind, originalName, jsonName); } + if (s_isFlagsEnum) + { + // Perform topological sort for flags enums to ensure values that are supersets of other values come first. + // This is important for flags enums to ensure proper parsing and formatting. + enumFields = TopologicalSortEnumFields(enumFields); + } + return enumFields; } @@ -659,6 +666,52 @@ static bool ConflictsWith(EnumFieldInfo current, EnumFieldInfo other) } } + /// + /// Performs a topological sort on enum fields to ensure values that are supersets of other values come first. + /// + private static EnumFieldInfo[] TopologicalSortEnumFields(EnumFieldInfo[] enumFields) + { + if (enumFields.Length <= 1) + { + return enumFields; + } + + var indices = new (int negativePopCount, int index)[enumFields.Length]; + for (int i = 0; i < enumFields.Length; i++) + { + // We want values with more bits set to come first so negate the pop count. + // Keep the index as a second comparand so that sorting stability is preserved. + indices[i] = (-PopCount(enumFields[i].Key), i); + } + + Array.Sort(indices); + + var sortedFields = new EnumFieldInfo[enumFields.Length]; + for (int i = 0; i < indices.Length; i++) + { + // extract the index from the sorted tuple + int index = indices[i].index; + sortedFields[i] = enumFields[index]; + } + + return sortedFields; + } + + private static int PopCount(ulong value) + { +#if NET + return (int)ulong.PopCount(value); +#else + int count = 0; + while (value != 0) + { + value &= value - 1; + count++; + } + return count; +#endif + } + private enum EnumFieldNameKind { Default = 0, diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/VersionConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/VersionConverter.cs index 5f3757bb8ae926..4a8af165f731d2 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/VersionConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/VersionConverter.cs @@ -87,7 +87,7 @@ public override void Write(Utf8JsonWriter writer, Version? value, JsonSerializer } #if NET -#if NET8_0_OR_GREATER +#if NET Span span = stackalloc byte[MaximumVersionLength]; #else Span span = stackalloc char[MaximumVersionLength]; @@ -110,7 +110,7 @@ internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, Version va ArgumentNullException.ThrowIfNull(value); #if NET -#if NET8_0_OR_GREATER +#if NET Span span = stackalloc byte[MaximumVersionLength]; #else Span span = stackalloc char[MaximumVersionLength]; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/IReadBufferState.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/IReadBufferState.cs new file mode 100644 index 00000000000000..5847bea2a1bd55 --- /dev/null +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/IReadBufferState.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Text.Json.Serialization +{ + internal interface IReadBufferState : IDisposable + where TReadBufferState : struct, IReadBufferState + { + public abstract bool IsFinalBlock { get; } + +#if DEBUG + // Used for Debug.Assert's + public abstract ReadOnlySequence Bytes { get; } +#endif + + public abstract ValueTask ReadAsync( + TStream utf8Json, + CancellationToken cancellationToken, + bool fillBuffer = true); + + public abstract void Read(TStream utf8Json); + + public abstract void Advance(long bytesConsumed); + + // This would normally be implemented as returning a Utf8JsonReader, but this pattern hits a limitation + // in mono aot that is not trivial to fix. For now use the alternative pattern of returning via an out + // argument. Tracking issue: https://github.com/dotnet/runtime/issues/118697 + public abstract void GetReader(JsonReaderState jsonReaderState, out Utf8JsonReader reader); + } +} diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Helpers.cs index af8c95ff889c48..43a57196f9fb53 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Helpers.cs @@ -1,9 +1,11 @@ // 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.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; +using System.Text.Json.Serialization.Converters; using System.Text.Json.Serialization.Metadata; namespace System.Text.Json @@ -139,5 +141,42 @@ static void ThrowUnableToCastValue(object? value) return (T?)value; } + + private static JsonTypeInfo> GetOrAddListTypeInfoForRootLevelValueMode(JsonTypeInfo elementTypeInfo) + { + if (elementTypeInfo._asyncEnumerableRootLevelValueTypeInfo != null) + { + return (JsonTypeInfo>)elementTypeInfo._asyncEnumerableRootLevelValueTypeInfo; + } + + var converter = new RootLevelListConverter(elementTypeInfo); + var listTypeInfo = new JsonTypeInfo>(converter, elementTypeInfo.Options) + { + ElementTypeInfo = elementTypeInfo, + }; + + listTypeInfo.EnsureConfigured(); + elementTypeInfo._asyncEnumerableRootLevelValueTypeInfo = listTypeInfo; + return listTypeInfo; + } + + private static JsonTypeInfo> GetOrAddListTypeInfoForArrayMode(JsonTypeInfo elementTypeInfo) + { + if (elementTypeInfo._asyncEnumerableArrayTypeInfo != null) + { + return (JsonTypeInfo>)elementTypeInfo._asyncEnumerableArrayTypeInfo; + } + + var converter = new ListOfTConverter, T>(); + var listTypeInfo = new JsonTypeInfo>(converter, elementTypeInfo.Options) + { + CreateObject = static () => new List(), + ElementTypeInfo = elementTypeInfo, + }; + + listTypeInfo.EnsureConfigured(); + elementTypeInfo._asyncEnumerableArrayTypeInfo = listTypeInfo; + return listTypeInfo; + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Pipe.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Pipe.cs new file mode 100644 index 00000000000000..4cfe7acb0b14ab --- /dev/null +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Pipe.cs @@ -0,0 +1,366 @@ +// 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.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO.Pipelines; +using System.Runtime.CompilerServices; +using System.Text.Json.Serialization; +using System.Text.Json.Serialization.Metadata; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Text.Json +{ + public static partial class JsonSerializer + { + /// + /// Reads the UTF-8 encoded text representing a single JSON value into a . + /// The PipeReader will be read to completion. + /// + /// The type to deserialize the JSON value into. + /// A representation of the JSON value. + /// JSON data to parse. + /// Options to control the behavior during reading. + /// + /// The that can be used to cancel the read operation. + /// + /// + /// is . + /// + /// + /// The JSON is invalid, + /// is not compatible with the JSON, + /// or when there is remaining data in the PipeReader. + /// + /// + /// There is no compatible + /// for or its serializable members. + /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] + [RequiresDynamicCode(SerializationRequiresDynamicCodeMessage)] + public static ValueTask DeserializeAsync( + PipeReader utf8Json, + JsonSerializerOptions? options = null, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(utf8Json, nameof(utf8Json)); + + JsonTypeInfo jsonTypeInfo = GetTypeInfo(options); + return jsonTypeInfo.DeserializeAsync(utf8Json, cancellationToken); + } + + /// + /// Reads the UTF-8 encoded text representing a single JSON value into a . + /// The PipeReader will be read to completion. + /// + /// The type to deserialize the JSON value into. + /// A representation of the JSON value. + /// JSON data to parse. + /// Metadata about the type to convert. + /// + /// The that can be used to cancel the read operation. + /// + /// + /// or is . + /// + /// + /// The JSON is invalid, + /// is not compatible with the JSON, + /// or when there is remaining data in the PipeReader. + /// + public static ValueTask DeserializeAsync( + PipeReader utf8Json, + JsonTypeInfo jsonTypeInfo, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(utf8Json, nameof(utf8Json)); + ArgumentNullException.ThrowIfNull(jsonTypeInfo, nameof(jsonTypeInfo)); + + jsonTypeInfo.EnsureConfigured(); + return jsonTypeInfo.DeserializeAsync(utf8Json, cancellationToken); + } + + /// + /// Reads the UTF-8 encoded text representing a single JSON value into an instance specified by the . + /// The PipeReader will be read to completion. + /// + /// A representation of the JSON value. + /// JSON data to parse. + /// Metadata about the type to convert. + /// + /// The that can be used to cancel the read operation. + /// + /// + /// or is . + /// + /// + /// The JSON is invalid, + /// or when there is remaining data in the PipeReader. + /// + public static ValueTask DeserializeAsync( + PipeReader utf8Json, + JsonTypeInfo jsonTypeInfo, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(utf8Json, nameof(utf8Json)); + ArgumentNullException.ThrowIfNull(jsonTypeInfo, nameof(jsonTypeInfo)); + + jsonTypeInfo.EnsureConfigured(); + return jsonTypeInfo.DeserializeAsObjectAsync(utf8Json, cancellationToken); + } + + /// + /// Reads the UTF-8 encoded text representing a single JSON value into a . + /// The PipeReader will be read to completion. + /// + /// A representation of the JSON value. + /// JSON data to parse. + /// The type of the object to convert to and return. + /// A metadata provider for serializable types. + /// + /// The that can be used to cancel the read operation. + /// + /// + /// , , or is . + /// + /// + /// The JSON is invalid, + /// the is not compatible with the JSON, + /// or when there is remaining data in the PipeReader. + /// + /// + /// There is no compatible + /// for or its serializable members. + /// + /// + /// The method on the provided + /// did not return a compatible for . + /// + public static ValueTask DeserializeAsync( + PipeReader utf8Json, + Type returnType, + JsonSerializerContext context, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(utf8Json, nameof(utf8Json)); + ArgumentNullException.ThrowIfNull(returnType, nameof(returnType)); + ArgumentNullException.ThrowIfNull(context, nameof(context)); + + JsonTypeInfo jsonTypeInfo = GetTypeInfo(context, returnType); + return jsonTypeInfo.DeserializeAsObjectAsync(utf8Json, cancellationToken); + } + + /// + /// Reads the UTF-8 encoded text representing a single JSON value into a . + /// The PipeReader will be read to completion. + /// + /// A representation of the JSON value. + /// JSON data to parse. + /// The type of the object to convert to and return. + /// Options to control the behavior during reading. + /// + /// The that can be used to cancel the read operation. + /// + /// + /// or is . + /// + /// + /// The JSON is invalid, + /// the is not compatible with the JSON, + /// or when there is remaining data in the PipeReader. + /// + /// + /// There is no compatible + /// for or its serializable members. + /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] + [RequiresDynamicCode(SerializationRequiresDynamicCodeMessage)] + public static ValueTask DeserializeAsync( + PipeReader utf8Json, + Type returnType, + JsonSerializerOptions? options = null, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(utf8Json, nameof(utf8Json)); + ArgumentNullException.ThrowIfNull(returnType, nameof(returnType)); + + JsonTypeInfo jsonTypeInfo = GetTypeInfo(options, returnType); + return jsonTypeInfo.DeserializeAsObjectAsync(utf8Json, cancellationToken); + } + + /// + /// Wraps the UTF-8 encoded text into an + /// that can be used to deserialize root-level JSON arrays in a streaming manner. + /// + /// The element type to deserialize asynchronously. + /// An representation of the provided JSON array. + /// JSON data to parse. + /// Options to control the behavior during reading. + /// The that can be used to cancel the read operation. + /// + /// is . + /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] + [RequiresDynamicCode(SerializationRequiresDynamicCodeMessage)] + public static IAsyncEnumerable DeserializeAsyncEnumerable( + PipeReader utf8Json, + JsonSerializerOptions? options = null, + CancellationToken cancellationToken = default) + { + return DeserializeAsyncEnumerable(utf8Json, topLevelValues: false, options, cancellationToken); + } + + /// + /// Wraps the UTF-8 encoded text into an + /// that can be used to deserialize root-level JSON arrays in a streaming manner. + /// + /// The element type to deserialize asynchronously. + /// An representation of the provided JSON array. + /// JSON data to parse. + /// Metadata about the element type to convert. + /// The that can be used to cancel the read operation. + /// + /// or is . + /// + public static IAsyncEnumerable DeserializeAsyncEnumerable( + PipeReader utf8Json, + JsonTypeInfo jsonTypeInfo, + CancellationToken cancellationToken = default) + { + return DeserializeAsyncEnumerable(utf8Json, jsonTypeInfo, topLevelValues: false, cancellationToken); + } + + /// + /// Wraps the UTF-8 encoded text into an + /// that can be used to deserialize sequences of JSON values in a streaming manner. + /// + /// The element type to deserialize asynchronously. + /// An representation of the provided JSON sequence. + /// JSON data to parse. + /// Metadata about the element type to convert. + /// Whether to deserialize from a sequence of top-level JSON values. + /// The that can be used to cancel the read operation. + /// + /// or is . + /// + /// + /// When is set to , treats the PipeReader as a sequence of + /// whitespace separated top-level JSON values and attempts to deserialize each value into . + /// When is set to , treats the PipeReader as a JSON array and + /// attempts to serialize each element into . + /// + public static IAsyncEnumerable DeserializeAsyncEnumerable( + PipeReader utf8Json, + JsonTypeInfo jsonTypeInfo, + bool topLevelValues, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(utf8Json, nameof(utf8Json)); + ArgumentNullException.ThrowIfNull(jsonTypeInfo, nameof(jsonTypeInfo)); + + jsonTypeInfo.EnsureConfigured(); + return DeserializeAsyncEnumerableCore(utf8Json, jsonTypeInfo, topLevelValues, cancellationToken); + } + + /// + /// Wraps the UTF-8 encoded text into an + /// that can be used to deserialize sequences of JSON values in a streaming manner. + /// + /// The element type to deserialize asynchronously. + /// An representation of the provided JSON sequence. + /// JSON data to parse. + /// to deserialize from a sequence of top-level JSON values, or to deserialize from a single top-level array. + /// Options to control the behavior during reading. + /// The that can be used to cancel the read operation. + /// + /// is . + /// + /// + /// When is set to , treats the PipeReader as a sequence of + /// whitespace separated top-level JSON values and attempts to deserialize each value into . + /// When is set to , treats the PipeReader as a JSON array and + /// attempts to serialize each element into . + /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] + [RequiresDynamicCode(SerializationRequiresDynamicCodeMessage)] + public static IAsyncEnumerable DeserializeAsyncEnumerable( + PipeReader utf8Json, + bool topLevelValues, + JsonSerializerOptions? options = null, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(utf8Json, nameof(utf8Json)); + + JsonTypeInfo jsonTypeInfo = GetTypeInfo(options); + return DeserializeAsyncEnumerableCore(utf8Json, jsonTypeInfo, topLevelValues, cancellationToken); + } + + private static IAsyncEnumerable DeserializeAsyncEnumerableCore( + PipeReader utf8Json, + JsonTypeInfo jsonTypeInfo, + bool topLevelValues, + CancellationToken cancellationToken) + { + Debug.Assert(jsonTypeInfo.IsConfigured); + + JsonTypeInfo> listTypeInfo; + JsonReaderOptions readerOptions = jsonTypeInfo.Options.GetReaderOptions(); + if (topLevelValues) + { + listTypeInfo = GetOrAddListTypeInfoForRootLevelValueMode(jsonTypeInfo); + readerOptions.AllowMultipleValues = true; + } + else + { + listTypeInfo = GetOrAddListTypeInfoForArrayMode(jsonTypeInfo); + } + + return CreateAsyncEnumerableFromArray(utf8Json, listTypeInfo, readerOptions, cancellationToken); + + static async IAsyncEnumerable CreateAsyncEnumerableFromArray( + PipeReader utf8Json, + JsonTypeInfo> listTypeInfo, + JsonReaderOptions readerOptions, + [EnumeratorCancellation] CancellationToken cancellationToken) + { + Debug.Assert(listTypeInfo.IsConfigured); + + ReadStack readStack = default; + readStack.Initialize(listTypeInfo, supportContinuation: true); + JsonReaderState jsonReaderState = new(readerOptions); + PipeReadBufferState bufferState = new(utf8Json); + + try + { + bool success; + do + { + bufferState = await bufferState.ReadAsync(utf8Json, cancellationToken, fillBuffer: false).ConfigureAwait(false); + success = listTypeInfo.ContinueDeserialize( + ref bufferState, + ref jsonReaderState, + ref readStack, + out List? _); + + if (readStack.Current.ReturnValue is { } returnValue) + { + var list = (List)returnValue; + foreach (T? item in list) + { + yield return item; + } + + list.Clear(); + } + } while (!success); + } + finally + { + bufferState.Dispose(); + } + } + } + } +} diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs index 005fb7c9de3943..4ad3daa45d7cda 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs @@ -7,7 +7,6 @@ using System.IO; using System.Runtime.CompilerServices; using System.Text.Json.Serialization; -using System.Text.Json.Serialization.Converters; using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; @@ -486,16 +485,16 @@ public static partial class JsonSerializer ReadStack readStack = default; readStack.Initialize(listTypeInfo, supportContinuation: true); JsonReaderState jsonReaderState = new(readerOptions); - // Note: The ReadBufferState ctor rents pooled buffers. - ReadBufferState bufferState = new(listTypeInfo.Options.DefaultBufferSize); + // Note: The StreamReadBufferState ctor rents pooled buffers. + StreamReadBufferState bufferState = new StreamReadBufferState(listTypeInfo.Options.DefaultBufferSize); try { bool success; do { - bufferState = await bufferState.ReadFromStreamAsync(utf8Json, cancellationToken, fillBuffer: false).ConfigureAwait(false); - success = listTypeInfo.ContinueDeserialize( + bufferState = await bufferState.ReadAsync(utf8Json, cancellationToken, fillBuffer: false).ConfigureAwait(false); + success = listTypeInfo.ContinueDeserialize( ref bufferState, ref jsonReaderState, ref readStack, @@ -519,43 +518,6 @@ public static partial class JsonSerializer bufferState.Dispose(); } } - - static JsonTypeInfo> GetOrAddListTypeInfoForArrayMode(JsonTypeInfo elementTypeInfo) - { - if (elementTypeInfo._asyncEnumerableArrayTypeInfo != null) - { - return (JsonTypeInfo>)elementTypeInfo._asyncEnumerableArrayTypeInfo; - } - - var converter = new ListOfTConverter, T>(); - var listTypeInfo = new JsonTypeInfo>(converter, elementTypeInfo.Options) - { - CreateObject = static () => new List(), - ElementTypeInfo = elementTypeInfo, - }; - - listTypeInfo.EnsureConfigured(); - elementTypeInfo._asyncEnumerableArrayTypeInfo = listTypeInfo; - return listTypeInfo; - } - - static JsonTypeInfo> GetOrAddListTypeInfoForRootLevelValueMode(JsonTypeInfo elementTypeInfo) - { - if (elementTypeInfo._asyncEnumerableRootLevelValueTypeInfo != null) - { - return (JsonTypeInfo>)elementTypeInfo._asyncEnumerableRootLevelValueTypeInfo; - } - - var converter = new RootLevelListConverter(elementTypeInfo); - var listTypeInfo = new JsonTypeInfo>(converter, elementTypeInfo.Options) - { - ElementTypeInfo = elementTypeInfo, - }; - - listTypeInfo.EnsureConfigured(); - elementTypeInfo._asyncEnumerableRootLevelValueTypeInfo = listTypeInfo; - return listTypeInfo; - } } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs index c6485d6863b18a..10e6db00dca22b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs @@ -1043,6 +1043,7 @@ internal JsonPropertyInfo CreatePropertyUsingReflection(Type propertyType, Type? // Untyped, root-level deserialization methods internal abstract object? DeserializeAsObject(ref Utf8JsonReader reader, ref ReadStack state); + internal abstract ValueTask DeserializeAsObjectAsync(PipeReader utf8Json, CancellationToken cancellationToken); internal abstract ValueTask DeserializeAsObjectAsync(Stream utf8Json, CancellationToken cancellationToken); internal abstract object? DeserializeAsObject(Stream utf8Json); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.ReadHelper.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.ReadHelper.cs index 3ea5e94b8ce9cb..b8e99b30bf9ae0 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.ReadHelper.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.ReadHelper.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.IO.Pipelines; using System.Threading; using System.Threading.Tasks; @@ -22,22 +23,21 @@ public partial class JsonTypeInfo return result; } - internal async ValueTask DeserializeAsync(Stream utf8Json, CancellationToken cancellationToken) + internal async ValueTask DeserializeAsync(TStream utf8Json, TReadBufferState bufferState, CancellationToken cancellationToken) + where TReadBufferState : struct, IReadBufferState { Debug.Assert(IsConfigured); JsonSerializerOptions options = Options; ReadStack readStack = default; readStack.Initialize(this, supportContinuation: true); var jsonReaderState = new JsonReaderState(options.GetReaderOptions()); - // Note: The ReadBufferState ctor rents pooled buffers. - ReadBufferState bufferState = new(options.DefaultBufferSize); try { while (true) { - bufferState = await bufferState.ReadFromStreamAsync(utf8Json, cancellationToken).ConfigureAwait(false); - bool success = ContinueDeserialize( + bufferState = await bufferState.ReadAsync(utf8Json, cancellationToken).ConfigureAwait(false); + bool success = ContinueDeserialize( ref bufferState, ref jsonReaderState, ref readStack, @@ -55,6 +55,19 @@ public partial class JsonTypeInfo } } + internal ValueTask DeserializeAsync(Stream utf8Json, CancellationToken cancellationToken) + { + // Note: The ReadBufferState ctor rents pooled buffers. + StreamReadBufferState bufferState = new StreamReadBufferState(Options.DefaultBufferSize); + return DeserializeAsync(utf8Json, bufferState, cancellationToken); + } + + internal ValueTask DeserializeAsync(PipeReader utf8Json, CancellationToken cancellationToken) + { + PipeReadBufferState bufferState = new(utf8Json); + return DeserializeAsync(utf8Json, bufferState, cancellationToken); + } + internal T? Deserialize(Stream utf8Json) { Debug.Assert(IsConfigured); @@ -63,14 +76,14 @@ public partial class JsonTypeInfo readStack.Initialize(this, supportContinuation: true); var jsonReaderState = new JsonReaderState(options.GetReaderOptions()); // Note: The ReadBufferState ctor rents pooled buffers. - ReadBufferState bufferState = new(options.DefaultBufferSize); + StreamReadBufferState bufferState = new StreamReadBufferState(options.DefaultBufferSize); try { while (true) { - bufferState.ReadFromStream(utf8Json); - bool success = ContinueDeserialize( + bufferState.Read(utf8Json); + bool success = ContinueDeserialize( ref bufferState, ref jsonReaderState, ref readStack, @@ -101,29 +114,47 @@ public partial class JsonTypeInfo internal sealed override async ValueTask DeserializeAsObjectAsync(Stream utf8Json, CancellationToken cancellationToken) { - T? result = await DeserializeAsync(utf8Json, cancellationToken).ConfigureAwait(false); + // Note: The ReadBufferState ctor rents pooled buffers. + StreamReadBufferState bufferState = new StreamReadBufferState(Options.DefaultBufferSize); + T? result = await DeserializeAsync(utf8Json, bufferState, cancellationToken).ConfigureAwait(false); + return result; + } + + internal sealed override async ValueTask DeserializeAsObjectAsync(PipeReader utf8Json, CancellationToken cancellationToken) + { + T? result = await DeserializeAsync(utf8Json, bufferState: new PipeReadBufferState(utf8Json), cancellationToken).ConfigureAwait(false); return result; } internal sealed override object? DeserializeAsObject(Stream utf8Json) => Deserialize(utf8Json); - internal bool ContinueDeserialize( - ref ReadBufferState bufferState, + internal bool ContinueDeserialize( + ref TReadBufferState bufferState, ref JsonReaderState jsonReaderState, ref ReadStack readStack, out T? value) + where TReadBufferState : struct, IReadBufferState { - var reader = new Utf8JsonReader(bufferState.Bytes, bufferState.IsFinalBlock, jsonReaderState); - bool success = EffectiveConverter.ReadCore(ref reader, out value, Options, ref readStack); + bufferState.GetReader(jsonReaderState, out Utf8JsonReader reader); + + try + { + bool success = EffectiveConverter.ReadCore(ref reader, out value, Options, ref readStack); - Debug.Assert(reader.BytesConsumed <= bufferState.Bytes.Length); - Debug.Assert(!bufferState.IsFinalBlock || reader.AllowMultipleValues || reader.BytesConsumed == bufferState.Bytes.Length, - "The reader should have thrown if we have remaining bytes."); +#if DEBUG + Debug.Assert(reader.BytesConsumed <= bufferState.Bytes.Length); + Debug.Assert(!bufferState.IsFinalBlock || reader.AllowMultipleValues || reader.BytesConsumed == bufferState.Bytes.Length, + "The reader should have thrown if we have remaining bytes."); +#endif - bufferState.AdvanceBuffer((int)reader.BytesConsumed); - jsonReaderState = reader.CurrentState; - return success; + jsonReaderState = reader.CurrentState; + return success; + } + finally + { + bufferState.Advance(reader.BytesConsumed); + } } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.WriteHelpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.WriteHelpers.cs index 3f5965f5b7775d..6dcbdb5746fa4e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.WriteHelpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.WriteHelpers.cs @@ -64,10 +64,11 @@ internal Task SerializeAsync(Stream utf8Json, CancellationToken cancellationToken, object? rootValueBoxed = null) { + PooledByteBufferWriter writer = new PooledByteBufferWriter(Options.DefaultBufferSize, utf8Json); // Value chosen as 90% of the default buffer used in PooledByteBufferWriter. // This is a tradeoff between likelihood of needing to grow the array vs. utilizing most of the buffer - int flushThreshold = (int)(Options.DefaultBufferSize * JsonSerializer.FlushThreshold); - return SerializeAsync(new PooledByteBufferWriter(Options.DefaultBufferSize, utf8Json), rootValue, flushThreshold, cancellationToken, rootValueBoxed); + int flushThreshold = (int)(writer.Capacity * JsonSerializer.FlushThreshold); + return SerializeAsync(writer, rootValue, flushThreshold, cancellationToken, rootValueBoxed); } internal Task SerializeAsync(PipeWriter utf8Json, @@ -199,7 +200,7 @@ rootValue is not null && if (state.PendingTask is not null) { // Exceptions should only be propagated by the resuming converter -#if NET8_0_OR_GREATER +#if NET await state.PendingTask.ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); #else try diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/PipeReadBufferState.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/PipeReadBufferState.cs new file mode 100644 index 00000000000000..45bb1d85351770 --- /dev/null +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/PipeReadBufferState.cs @@ -0,0 +1,153 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers; +using System.Diagnostics; +using System.IO.Pipelines; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Text.Json.Serialization +{ + [StructLayout(LayoutKind.Auto)] + internal struct PipeReadBufferState : IReadBufferState + { + private readonly PipeReader _utf8Json; + + private ReadOnlySequence _sequence = ReadOnlySequence.Empty; + private bool _isFinalBlock; + private bool _isFirstBlock = true; + private int _unsuccessfulReadBytes; + + public PipeReadBufferState(PipeReader utf8Json) + { + _utf8Json = utf8Json; + } + + public readonly bool IsFinalBlock => _isFinalBlock; + +#if DEBUG + public readonly ReadOnlySequence Bytes => _sequence; +#endif + + public void Advance(long bytesConsumed) + { + _unsuccessfulReadBytes = 0; + if (bytesConsumed == 0) + { + long leftOver = _sequence.Length; + // Cap at int.MaxValue as PipeReader.ReadAtLeastAsync uses an int as the minimum size argument. + _unsuccessfulReadBytes = (int)Math.Min(int.MaxValue, leftOver * 2); + } + + _utf8Json.AdvanceTo(_sequence.Slice(bytesConsumed).Start, _sequence.End); + _sequence = ReadOnlySequence.Empty; + } + + /// + /// Read from the PipeReader until either our buffer limit is filled or we hit EOF. + /// Calling ReadCore is relatively expensive, so we minimize the number of times + /// we need to call it. + /// + public async ValueTask ReadAsync(PipeReader utf8Json, CancellationToken cancellationToken, bool fillBuffer = true) + { + Debug.Assert(_sequence.Equals(ReadOnlySequence.Empty), "ReadAsync should only be called when the buffer is empty."); + + // Since mutable structs don't work well with async state machines, + // make all updates on a copy which is returned once complete. + PipeReadBufferState bufferState = this; + + int minBufferSize = _unsuccessfulReadBytes > 0 ? _unsuccessfulReadBytes : 0; + ReadResult readResult = await _utf8Json.ReadAtLeastAsync(minBufferSize, cancellationToken).ConfigureAwait(false); + + bufferState._sequence = readResult.Buffer; + bufferState._isFinalBlock = readResult.IsCompleted; + bufferState.ProcessReadBytes(); + + if (readResult.IsCanceled) + { + ThrowHelper.ThrowOperationCanceledException_PipeReadCanceled(); + } + + return bufferState; + } + + public void Read(PipeReader utf8Json) => throw new NotImplementedException(); + + public void GetReader(JsonReaderState jsonReaderState, out Utf8JsonReader reader) + { + if (_sequence.IsSingleSegment) + { + reader = new Utf8JsonReader( +#if NET + _sequence.FirstSpan, +#else + _sequence.First.Span, +#endif + IsFinalBlock, jsonReaderState); + } + else + { + reader = new Utf8JsonReader(_sequence, IsFinalBlock, jsonReaderState); + } + } + + private void ProcessReadBytes() + { + if (_isFirstBlock) + { + _isFirstBlock = false; + + // Handle the UTF-8 BOM if present + if (_sequence.Length > 0) + { + if (_sequence.First.Length >= JsonConstants.Utf8Bom.Length) + { + if (_sequence.First.Span.StartsWith(JsonConstants.Utf8Bom)) + { + _sequence = _sequence.Slice((byte)JsonConstants.Utf8Bom.Length); + } + } + else + { + // BOM spans multiple segments + SequencePosition pos = _sequence.Start; + int matched = 0; + while (matched < JsonConstants.Utf8Bom.Length && _sequence.TryGet(ref pos, out ReadOnlyMemory mem, advance: true)) + { + ReadOnlySpan span = mem.Span; + for (int i = 0; i < span.Length && matched < JsonConstants.Utf8Bom.Length; i++, matched++) + { + if (span[i] != JsonConstants.Utf8Bom[matched]) + { + matched = 0; + break; + } + } + } + + if (matched == JsonConstants.Utf8Bom.Length) + { + _sequence = _sequence.Slice(JsonConstants.Utf8Bom.Length); + } + } + } + } + } + + public void Dispose() + { + if (_sequence.Equals(ReadOnlySequence.Empty)) + { + return; + } + + // If we have a sequence, that likely means an Exception was thrown during deserialization. + // We should make sure to call AdvanceTo so that future reads on the PipeReader can be done without throwing. + // We'll advance to the start of the sequence as we don't know how many bytes were consumed. + _utf8Json.AdvanceTo(_sequence.Start); + _sequence = ReadOnlySequence.Empty; + } + } +} diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/StreamReadBufferState.cs similarity index 84% rename from src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs rename to src/libraries/System.Text.Json/src/System/Text/Json/Serialization/StreamReadBufferState.cs index 449fe5270d3989..65573c58bf7f04 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/StreamReadBufferState.cs @@ -11,7 +11,7 @@ namespace System.Text.Json.Serialization { [StructLayout(LayoutKind.Auto)] - internal struct ReadBufferState : IDisposable + internal struct StreamReadBufferState : IReadBufferState { private byte[] _buffer; private byte _offset; // Read bytes offset typically used when skipping the UTF-8 BOM. @@ -35,13 +35,13 @@ internal struct ReadBufferState : IDisposable // The counter is reset to zero whenever the JSON reader has been advanced successfully. // // The threshold is set to 5 unsuccessful reads. This is a relatively conservative threshold - // but should still make fallback unlikely in most scenaria. It should ensure that fallback + // but should still make fallback unlikely in most scenarios. It should ensure that fallback // isn't triggered in null or boolean tokens even in the worst-case scenario where they are // streamed one byte at a time. private const int UnsuccessfulReadCountThreshold = 5; private int _unsuccessfulReadCount; - public ReadBufferState(int initialBufferSize) + public StreamReadBufferState(int initialBufferSize) { _buffer = ArrayPool.Shared.Rent(Math.Max(initialBufferSize, JsonConstants.Utf8Bom.Length)); _maxCount = _count = _offset = 0; @@ -51,26 +51,27 @@ public ReadBufferState(int initialBufferSize) public readonly bool IsFinalBlock => _isFinalBlock; - public readonly ReadOnlySpan Bytes => _buffer.AsSpan(_offset, _count); +#if DEBUG + public readonly ReadOnlySequence Bytes => new(_buffer.AsMemory(_offset, _count)); +#endif /// /// Read from the stream until either our buffer is filled or we hit EOF. /// Calling ReadCore is relatively expensive, so we minimize the number of times /// we need to call it. /// - public readonly async ValueTask ReadFromStreamAsync( - Stream utf8Json, + public readonly async ValueTask ReadAsync(Stream stream, CancellationToken cancellationToken, bool fillBuffer = true) { // Since mutable structs don't work well with async state machines, // make all updates on a copy which is returned once complete. - ReadBufferState bufferState = this; + StreamReadBufferState bufferState = this; int minBufferCount = fillBuffer || _unsuccessfulReadCount > UnsuccessfulReadCountThreshold ? bufferState._buffer.Length : 0; do { - int bytesRead = await utf8Json.ReadAsync(bufferState._buffer.AsMemory(bufferState._count), cancellationToken).ConfigureAwait(false); + int bytesRead = await stream.ReadAsync(bufferState._buffer.AsMemory(bufferState._count), cancellationToken).ConfigureAwait(false); if (bytesRead == 0) { @@ -91,11 +92,11 @@ public readonly async ValueTask ReadFromStreamAsync( /// Calling ReadCore is relatively expensive, so we minimize the number of times /// we need to call it. /// - public void ReadFromStream(Stream utf8Json) + public void Read(Stream stream) { do { - int bytesRead = utf8Json.Read( + int bytesRead = stream.Read( #if NET _buffer.AsSpan(_count)); #else @@ -118,12 +119,14 @@ public void ReadFromStream(Stream utf8Json) /// /// Advances the buffer in anticipation of a subsequent read operation. /// - public void AdvanceBuffer(int bytesConsumed) + public void Advance(long bytesConsumed) { Debug.Assert(bytesConsumed <= _count); - _unsuccessfulReadCount = bytesConsumed == 0 ? _unsuccessfulReadCount + 1 : 0; - _count -= bytesConsumed; + int bytesConsumedInt = (int)bytesConsumed; + + _unsuccessfulReadCount = bytesConsumedInt == 0 ? _unsuccessfulReadCount + 1 : 0; + _count -= bytesConsumedInt; if (!_isFinalBlock) { @@ -136,7 +139,7 @@ public void AdvanceBuffer(int bytesConsumed) byte[] newBuffer = ArrayPool.Shared.Rent((_buffer.Length < (int.MaxValue / 2)) ? _buffer.Length * 2 : int.MaxValue); // Copy the unprocessed data to the new buffer while shifting the processed bytes. - Buffer.BlockCopy(oldBuffer, _offset + bytesConsumed, newBuffer, 0, _count); + Buffer.BlockCopy(oldBuffer, _offset + bytesConsumedInt, newBuffer, 0, _count); _buffer = newBuffer; _maxCount = _count; @@ -147,13 +150,21 @@ public void AdvanceBuffer(int bytesConsumed) else if (_count != 0) { // Shift the processed bytes to the beginning of buffer to make more room. - Buffer.BlockCopy(_buffer, _offset + bytesConsumed, _buffer, 0, _count); + Buffer.BlockCopy(_buffer, _offset + bytesConsumedInt, _buffer, 0, _count); } } _offset = 0; } + public void GetReader(JsonReaderState jsonReaderState, out Utf8JsonReader reader) + { + reader = new Utf8JsonReader( + _buffer.AsSpan(_offset, _count), + IsFinalBlock, + jsonReaderState); + } + private void ProcessReadBytes() { if (_count > _maxCount) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs index bc812b96fadff9..3292e7602c94b1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs @@ -979,6 +979,12 @@ public static void ThrowOperationCanceledException_PipeWriteCanceled() throw new OperationCanceledException(SR.PipeWriterCanceled); } + [DoesNotReturn] + public static void ThrowOperationCanceledException_PipeReadCanceled() + { + throw new OperationCanceledException(SR.PipeReaderCanceled); + } + [DoesNotReturn] public static void ThrowInvalidOperationException_PipeWriterDoesNotImplementUnflushedBytes(PipeWriter pipeWriter) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs index 8844132888beee..6f824283412159 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -4,6 +4,7 @@ using System.Buffers; using System.Diagnostics; using System.Runtime.CompilerServices; +using System.Text.Encodings.Web; using System.Text.Unicode; namespace System.Text.Json @@ -253,13 +254,13 @@ internal static void ValidateNumber(ReadOnlySpan utf8FormattedNumber) } } -#if !NET8_0_OR_GREATER +#if !NET private static readonly UTF8Encoding s_utf8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); #endif public static bool IsValidUtf8String(ReadOnlySpan bytes) { -#if NET8_0_OR_GREATER +#if NET return Utf8.IsValid(bytes); #else try @@ -322,5 +323,73 @@ internal static OperationStatus ToUtf8(ReadOnlySpan source, Span des } #endif } + + internal delegate T WriteCallback(ReadOnlySpan serializedValue); + + internal static T WriteString(ReadOnlySpan utf8Value, WriteCallback writeCallback) + { + int firstByteToEscape = JsonWriterHelper.NeedsEscaping(utf8Value, JavaScriptEncoder.Default); + + if (firstByteToEscape == -1) + { + int quotedLength = utf8Value.Length + 2; + byte[]? rented = null; + + try + { + Span quotedValue = quotedLength > JsonConstants.StackallocByteThreshold + ? (rented = ArrayPool.Shared.Rent(quotedLength)).AsSpan(0, quotedLength) + : stackalloc byte[JsonConstants.StackallocByteThreshold].Slice(0, quotedLength); + + quotedValue[0] = JsonConstants.Quote; + utf8Value.CopyTo(quotedValue.Slice(1)); + quotedValue[quotedValue.Length - 1] = JsonConstants.Quote; + + return writeCallback(quotedValue); + } + finally + { + if (rented != null) + { + ArrayPool.Shared.Return(rented); + } + } + } + else + { + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8Value.Length); + + int length = checked(2 + JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstByteToEscape)); + byte[]? rented = null; + + try + { + scoped Span escapedValue; + + if (length > JsonConstants.StackallocByteThreshold) + { + rented = ArrayPool.Shared.Rent(length); + escapedValue = rented; + } + else + { + escapedValue = stackalloc byte[JsonConstants.StackallocByteThreshold]; + } + + escapedValue[0] = JsonConstants.Quote; + JsonWriterHelper.EscapeString(utf8Value, escapedValue.Slice(1), firstByteToEscape, JavaScriptEncoder.Default, out int written); + escapedValue[1 + written] = JsonConstants.Quote; + + return writeCallback(escapedValue.Slice(0, written + 2)); + } + finally + { + if (rented != null) + { + ArrayPool.Shared.Return(rented); + } + } + } + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs b/src/libraries/System.Text.Json/tests/Common/AsyncEnumerableTests.cs similarity index 82% rename from src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs rename to src/libraries/System.Text.Json/tests/Common/AsyncEnumerableTests.cs index fbc1619c6f9832..c7643371abbc4b 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs +++ b/src/libraries/System.Text.Json/tests/Common/AsyncEnumerableTests.cs @@ -13,8 +13,12 @@ namespace System.Text.Json.Serialization.Tests { - public static partial class StreamTests_DeserializeAsyncEnumerable + public abstract partial class AsyncEnumerableTests : SerializerTests { + public AsyncEnumerableTests(JsonSerializerWrapper serializerWrapper) : base(serializerWrapper) + { + } + [Theory] [InlineData(0, 1)] [InlineData(1, 1)] @@ -23,7 +27,7 @@ public static partial class StreamTests_DeserializeAsyncEnumerable [InlineData(1000, 1)] [InlineData(1000, 1000)] [InlineData(1000, 32000)] - public static async Task DeserializeAsyncEnumerable_ReadSimpleObjectAsync(int count, int bufferSize) + public async Task DeserializeAsyncEnumerable_ReadSimpleObjectAsync(int count, int bufferSize) { JsonSerializerOptions options = new JsonSerializerOptions { @@ -33,7 +37,7 @@ public static async Task DeserializeAsyncEnumerable_ReadSimpleObjectAsync(int co using var stream = new MemoryStream(GenerateJsonArray(count)); int callbackCount = 0; - await foreach (SimpleTestClass item in JsonSerializer.DeserializeAsyncEnumerable(stream, options)) + await foreach (SimpleTestClass item in Serializer.DeserializeAsyncEnumerable(stream, options)) { Assert.Equal(callbackCount, item.MyInt32); @@ -62,7 +66,7 @@ static byte[] GenerateJsonArray(int count) [Theory] [MemberData(nameof(GetAsyncEnumerableSources))] - public static async Task DeserializeAsyncEnumerable_ReadSourceAsync(IEnumerable source, int bufferSize, DeserializeAsyncEnumerableOverload overload) + public async Task DeserializeAsyncEnumerable_ReadSourceAsync(IEnumerable source, int bufferSize, DeserializeAsyncEnumerableOverload overload) { JsonSerializerOptions options = new JsonSerializerOptions { @@ -80,7 +84,7 @@ public static async Task DeserializeAsyncEnumerable_ReadSourceAsync(IE [Theory] [InlineData(DeserializeAsyncEnumerableOverload.JsonSerializerOptions)] [InlineData(DeserializeAsyncEnumerableOverload.JsonTypeInfo)] - public static async Task DeserializeAsyncEnumerable_ShouldStreamPartialData(DeserializeAsyncEnumerableOverload overload) + public async Task DeserializeAsyncEnumerable_ShouldStreamPartialData(DeserializeAsyncEnumerableOverload overload) { string json = JsonSerializer.Serialize(Enumerable.Range(0, 100)); @@ -107,13 +111,13 @@ public static async Task DeserializeAsyncEnumerable_ShouldStreamPartialData(Dese [InlineData(5)] [InlineData(100)] [InlineData(1000)] - public static async Task DeserializeAsyncEnumerable_Object_TopLevelValues(int count) + public async Task DeserializeAsyncEnumerable_Object_TopLevelValues(int count) { JsonSerializerOptions options = new() { DefaultBufferSize = 1 }; string json = GenerateJsonTopLevelValues(count); using var stream = new Utf8MemoryStream(json); - IAsyncEnumerable asyncEnumerable = JsonSerializer.DeserializeAsyncEnumerable(stream, topLevelValues:true, options); + IAsyncEnumerable asyncEnumerable = Serializer.DeserializeAsyncEnumerable(stream, topLevelValues:true, options); int i = 0; await foreach (SimpleTestClass item in asyncEnumerable) @@ -148,13 +152,13 @@ static string GenerateJsonTopLevelValues(int count) [InlineData(5)] [InlineData(100)] [InlineData(1000)] - public static async Task DeserializeAsyncEnumerable_Array_TopLevelValues(int count) + public async Task DeserializeAsyncEnumerable_Array_TopLevelValues(int count) { JsonSerializerOptions options = new() { DefaultBufferSize = 1 }; string json = GenerateJsonTopLevelValues(count); using var stream = new Utf8MemoryStream(json); - IAsyncEnumerable?> asyncEnumerable = JsonSerializer.DeserializeAsyncEnumerable?>(stream, topLevelValues:true, options); + IAsyncEnumerable?> asyncEnumerable = Serializer.DeserializeAsyncEnumerable?>(stream, topLevelValues:true, options); int i = 0; await foreach (List? item in asyncEnumerable) @@ -192,12 +196,12 @@ static string GenerateJsonTopLevelValues(int count) } [Fact] - public static async Task DeserializeAsyncEnumerable_TopLevelValues_TrailingData_ThrowsJsonException() + public async Task DeserializeAsyncEnumerable_TopLevelValues_TrailingData_ThrowsJsonException() { JsonSerializerOptions options = new() { DefaultBufferSize = 1 }; using var stream = new Utf8MemoryStream("""[] [1] [1,2,3] """); - IAsyncEnumerable> asyncEnumerable = JsonSerializer.DeserializeAsyncEnumerable>(stream, topLevelValues:true, options); + IAsyncEnumerable> asyncEnumerable = Serializer.DeserializeAsyncEnumerable>(stream, topLevelValues:true, options); await using var asyncEnumerator = asyncEnumerable.GetAsyncEnumerator(); await Assert.ThrowsAnyAsync(async () => @@ -209,7 +213,7 @@ await Assert.ThrowsAnyAsync(async () => [Theory] [InlineData(DeserializeAsyncEnumerableOverload.JsonSerializerOptions)] [InlineData(DeserializeAsyncEnumerableOverload.JsonTypeInfo)] - public static async Task DeserializeAsyncEnumerable_ShouldTolerateCustomQueueConverters(DeserializeAsyncEnumerableOverload overload) + public async Task DeserializeAsyncEnumerable_ShouldTolerateCustomQueueConverters(DeserializeAsyncEnumerableOverload overload) { const int expectedCount = 20; @@ -258,30 +262,22 @@ private class DegenerateQueueConverter : JsonConverter> } } - [Fact] - public static void DeserializeAsyncEnumerable_NullArgument_ThrowsArgumentNullException() - { - AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: null)); - AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: null, jsonTypeInfo: ResolveJsonTypeInfo())); - AssertExtensions.Throws("jsonTypeInfo", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: new MemoryStream(), jsonTypeInfo: null)); - } - [Theory] [InlineData("42")] [InlineData("\"\"")] [InlineData("{}")] - public static async Task DeserializeAsyncEnumerable_NotARootLevelJsonArray_ThrowsJsonException(string json) + public async Task DeserializeAsyncEnumerable_NotARootLevelJsonArray_ThrowsJsonException(string json) { using var utf8Json = new Utf8MemoryStream(json); { - IAsyncEnumerable asyncEnumerable = JsonSerializer.DeserializeAsyncEnumerable(utf8Json); + IAsyncEnumerable asyncEnumerable = Serializer.DeserializeAsyncEnumerable(utf8Json); await using IAsyncEnumerator enumerator = asyncEnumerable.GetAsyncEnumerator(); await Assert.ThrowsAsync(async () => await enumerator.MoveNextAsync()); } { - IAsyncEnumerable asyncEnumerable = JsonSerializer.DeserializeAsyncEnumerable(utf8Json, ResolveJsonTypeInfo()); + IAsyncEnumerable asyncEnumerable = Serializer.DeserializeAsyncEnumerable(utf8Json, ResolveJsonTypeInfo()); await using IAsyncEnumerator enumerator = asyncEnumerable.GetAsyncEnumerator(); await Assert.ThrowsAsync(async () => await enumerator.MoveNextAsync()); } @@ -290,7 +286,7 @@ public static async Task DeserializeAsyncEnumerable_NotARootLevelJsonArray_Throw [Theory] [InlineData(DeserializeAsyncEnumerableOverload.JsonSerializerOptions)] [InlineData(DeserializeAsyncEnumerableOverload.JsonTypeInfo)] - public static async Task DeserializeAsyncEnumerable_CancellationToken_ThrowsOnCancellation(DeserializeAsyncEnumerableOverload overload) + public async Task DeserializeAsyncEnumerable_CancellationToken_ThrowsOnCancellation(DeserializeAsyncEnumerableOverload overload) { JsonSerializerOptions options = new JsonSerializerOptions { @@ -314,7 +310,7 @@ await Assert.ThrowsAsync(async () => [Theory] [InlineData(DeserializeAsyncEnumerableOverload.JsonSerializerOptions)] [InlineData(DeserializeAsyncEnumerableOverload.JsonTypeInfo)] - public static async Task DeserializeAsyncEnumerable_EnumeratorWithCancellationToken_ThrowsOnCancellation(DeserializeAsyncEnumerableOverload overload) + public async Task DeserializeAsyncEnumerable_EnumeratorWithCancellationToken_ThrowsOnCancellation(DeserializeAsyncEnumerableOverload overload) { JsonSerializerOptions options = new JsonSerializerOptions { @@ -338,7 +334,7 @@ await Assert.ThrowsAsync(async () => [Theory] [InlineData(5, 1024)] [InlineData(5, 1024 * 1024)] - public static async Task DeserializeAsyncEnumerable_SlowStreamWithLargeStrings(int totalStrings, int stringLength) + public async Task DeserializeAsyncEnumerable_SlowStreamWithLargeStrings(int totalStrings, int stringLength) { var options = new JsonSerializerOptions { @@ -347,7 +343,7 @@ public static async Task DeserializeAsyncEnumerable_SlowStreamWithLargeStrings(i using var stream = new SlowStream(GenerateJsonCharacters()); string expectedElement = stringLength.ToString(CultureInfo.InvariantCulture); - IAsyncEnumerable asyncEnumerable = JsonSerializer.DeserializeAsyncEnumerable(stream, options); + IAsyncEnumerable asyncEnumerable = Serializer.DeserializeAsyncEnumerable(stream, options); await foreach (string? value in asyncEnumerable) { @@ -393,16 +389,16 @@ public static IEnumerable GetAsyncEnumerableSources() public enum DeserializeAsyncEnumerableOverload { JsonSerializerOptions, JsonTypeInfo }; - private static IAsyncEnumerable DeserializeAsyncEnumerableWrapper(Stream stream, JsonSerializerOptions options = null, CancellationToken cancellationToken = default, DeserializeAsyncEnumerableOverload overload = DeserializeAsyncEnumerableOverload.JsonSerializerOptions) + private IAsyncEnumerable DeserializeAsyncEnumerableWrapper(Stream stream, JsonSerializerOptions options = null, CancellationToken cancellationToken = default, DeserializeAsyncEnumerableOverload overload = DeserializeAsyncEnumerableOverload.JsonSerializerOptions) { return overload switch { - DeserializeAsyncEnumerableOverload.JsonTypeInfo => JsonSerializer.DeserializeAsyncEnumerable(stream, ResolveJsonTypeInfo(options), cancellationToken), - DeserializeAsyncEnumerableOverload.JsonSerializerOptions or _ => JsonSerializer.DeserializeAsyncEnumerable(stream, options, cancellationToken), + DeserializeAsyncEnumerableOverload.JsonTypeInfo => Serializer.DeserializeAsyncEnumerable(stream, ResolveJsonTypeInfo(options), cancellationToken), + DeserializeAsyncEnumerableOverload.JsonSerializerOptions or _ => Serializer.DeserializeAsyncEnumerable(stream, options, cancellationToken), }; } - private static JsonTypeInfo ResolveJsonTypeInfo(JsonSerializerOptions? options = null) + internal static JsonTypeInfo ResolveJsonTypeInfo(JsonSerializerOptions? options = null) { return (JsonTypeInfo)ResolveJsonTypeInfo(typeof(T), options); } @@ -451,7 +447,11 @@ private sealed class StringLengthConverter : JsonConverter { public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - Debug.Assert(!reader.ValueIsEscaped && !reader.HasValueSequence); + Debug.Assert(!reader.ValueIsEscaped); + if (reader.HasValueSequence) + { + return reader.ValueSequence.Length.ToString(CultureInfo.InvariantCulture); + } return reader.ValueSpan.Length.ToString(CultureInfo.InvariantCulture); } diff --git a/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Enumerable.cs b/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Enumerable.cs index b4a65b5d818974..3650a21ffdd791 100644 --- a/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Enumerable.cs +++ b/src/libraries/System.Text.Json/tests/Common/JsonCreationHandlingTests.Enumerable.cs @@ -11,6 +11,8 @@ namespace System.Text.Json.Serialization.Tests; +#pragma warning disable xUnit2027 // Comparison of sets to linear containers have undefined results + public abstract partial class JsonCreationHandlingTests : SerializerTests { [Fact] diff --git a/src/libraries/System.Text.Json/tests/Common/JsonSchemaExporterTests.TestTypes.cs b/src/libraries/System.Text.Json/tests/Common/JsonSchemaExporterTests.TestTypes.cs index 2433c4c74c796b..f528edc06f1ee8 100644 --- a/src/libraries/System.Text.Json/tests/Common/JsonSchemaExporterTests.TestTypes.cs +++ b/src/libraries/System.Text.Json/tests/Common/JsonSchemaExporterTests.TestTypes.cs @@ -121,6 +121,18 @@ public static IEnumerable GetTestDataCore() } """); + yield return new TestData( + Value: 42, + AdditionalValues: [null], + ExpectedJsonSchema: """{"type":["integer","null"]}""", + Options: new() { TreatNullObliviousAsNonNullable = true }); + + yield return new TestData( + Value: DateTimeOffset.MinValue, + AdditionalValues: [null], + ExpectedJsonSchema: """{"type":["string","null"],"format":"date-time"}""", + Options: new() { TreatNullObliviousAsNonNullable = true }); + // User-defined POCOs yield return new TestData( Value: new() { String = "string", StringNullable = "string", Int = 42, Double = 3.14, Boolean = true }, diff --git a/src/libraries/System.Text.Json/tests/Common/JsonSerializerWrapper.cs b/src/libraries/System.Text.Json/tests/Common/JsonSerializerWrapper.cs index cf0dc76b243966..ab5ab8d66aa81a 100644 --- a/src/libraries/System.Text.Json/tests/Common/JsonSerializerWrapper.cs +++ b/src/libraries/System.Text.Json/tests/Common/JsonSerializerWrapper.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.IO; using System.Text.Json.Serialization.Metadata; +using System.Threading; using System.Threading.Tasks; namespace System.Text.Json.Serialization.Tests @@ -46,6 +48,28 @@ public abstract partial class JsonSerializerWrapper public abstract Task DeserializeWrapper(string json, Type type, JsonSerializerContext context); + public abstract IAsyncEnumerable DeserializeAsyncEnumerable( + Stream utf8Json, + JsonSerializerOptions options = null, + CancellationToken cancellationToken = default); + + public abstract IAsyncEnumerable DeserializeAsyncEnumerable( + Stream utf8Json, + JsonTypeInfo jsonTypeInfo, + CancellationToken cancellationToken = default); + + public abstract IAsyncEnumerable DeserializeAsyncEnumerable( + Stream utf8Json, + JsonTypeInfo jsonTypeInfo, + bool topLevelValues, + CancellationToken cancellationToken = default); + + public abstract IAsyncEnumerable DeserializeAsyncEnumerable( + Stream utf8Json, + bool topLevelValues, + JsonSerializerOptions? options = null, + CancellationToken cancellationToken = default); + public virtual JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions? options = null, bool mutable = false) { options ??= DefaultOptions; diff --git a/src/libraries/System.Text.Json/tests/Common/PipeJsonSerializerWrapper.cs b/src/libraries/System.Text.Json/tests/Common/PipeJsonSerializerWrapper.cs new file mode 100644 index 00000000000000..478081974b64b6 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/Common/PipeJsonSerializerWrapper.cs @@ -0,0 +1,107 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers; +using System.IO.Pipelines; +using System.Text.Json.Serialization.Metadata; +using System.Threading.Tasks; + +namespace System.Text.Json.Serialization.Tests +{ + /// + /// Base class for abstracting System.IO.Pipelines JsonSerializer method families. + /// + public abstract partial class PipeJsonSerializerWrapper : StreamingJsonSerializerWrapper + { + public abstract Task SerializeWrapper(PipeWriter stream, object value, Type inputType, JsonSerializerOptions? options = null); + public abstract Task SerializeWrapper(PipeWriter stream, T value, JsonSerializerOptions? options = null); + public abstract Task SerializeWrapper(PipeWriter stream, object value, Type inputType, JsonSerializerContext context); + public abstract Task SerializeWrapper(PipeWriter stream, T value, JsonTypeInfo jsonTypeInfo); + public abstract Task SerializeWrapper(PipeWriter stream, object value, JsonTypeInfo jsonTypeInfo); + public abstract Task DeserializeWrapper(PipeReader utf8Json, Type returnType, JsonSerializerOptions? options = null); + public abstract Task DeserializeWrapper(PipeReader utf8Json, JsonSerializerOptions? options = null); + public abstract Task DeserializeWrapper(PipeReader utf8Json, Type returnType, JsonSerializerContext context); + public abstract Task DeserializeWrapper(PipeReader utf8Json, JsonTypeInfo jsonTypeInfo); + public abstract Task DeserializeWrapper(PipeReader utf8Json, JsonTypeInfo jsonTypeInfo); + + public override async Task SerializeWrapper(object value, Type inputType, JsonSerializerOptions options = null) + { + Pipe pipe = new Pipe(); + await SerializeWrapper(pipe.Writer, value, inputType, options); + ReadResult result = await pipe.Reader.ReadAsync(); + return Encoding.UTF8.GetString(result.Buffer.ToArray()); + } + + public override async Task SerializeWrapper(T value, JsonSerializerOptions options = null) + { + Pipe pipe = new Pipe(); + await SerializeWrapper(pipe.Writer, value, options); + ReadResult result = await pipe.Reader.ReadAsync(); + return Encoding.UTF8.GetString(result.Buffer.ToArray()); + } + + public override async Task SerializeWrapper(object value, Type inputType, JsonSerializerContext context) + { + Pipe pipe = new Pipe(); + await SerializeWrapper(pipe.Writer, value, inputType, context); + ReadResult result = await pipe.Reader.ReadAsync(); + return Encoding.UTF8.GetString(result.Buffer.ToArray()); + } + + public override async Task SerializeWrapper(T value, JsonTypeInfo jsonTypeInfo) + { + Pipe pipe = new Pipe(); + await SerializeWrapper(pipe.Writer, value, jsonTypeInfo); + ReadResult result = await pipe.Reader.ReadAsync(); + return Encoding.UTF8.GetString(result.Buffer.ToArray()); + } + + public override async Task SerializeWrapper(object value, JsonTypeInfo jsonTypeInfo) + { + Pipe pipe = new Pipe(); + await SerializeWrapper(pipe.Writer, value, jsonTypeInfo); + ReadResult result = await pipe.Reader.ReadAsync(); + return Encoding.UTF8.GetString(result.Buffer.ToArray()); + } + + public override async Task DeserializeWrapper(string json, JsonSerializerOptions options = null) + { + Pipe pipe = new Pipe(); + await pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes(json)); + pipe.Writer.Complete(); + return await DeserializeWrapper(pipe.Reader, options); + } + + public override async Task DeserializeWrapper(string json, Type returnType, JsonSerializerOptions options = null) + { + Pipe pipe = new Pipe(); + await pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes(json)); + pipe.Writer.Complete(); + return await DeserializeWrapper(pipe.Reader, returnType, options); + } + + public override async Task DeserializeWrapper(string json, JsonTypeInfo jsonTypeInfo) + { + Pipe pipe = new Pipe(); + await pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes(json)); + pipe.Writer.Complete(); + return await DeserializeWrapper(pipe.Reader, jsonTypeInfo); + } + + public override async Task DeserializeWrapper(string json, JsonTypeInfo jsonTypeInfo) + { + Pipe pipe = new Pipe(); + await pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes(json)); + pipe.Writer.Complete(); + return await DeserializeWrapper(pipe.Reader, jsonTypeInfo); + } + + public override async Task DeserializeWrapper(string json, Type returnType, JsonSerializerContext context) + { + Pipe pipe = new Pipe(); + await pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes(json)); + pipe.Writer.Complete(); + return await DeserializeWrapper(pipe.Reader, returnType, context); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonSchemaExporterTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonSchemaExporterTests.cs index 322d71d4541edd..01558bb3658642 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonSchemaExporterTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonSchemaExporterTests.cs @@ -41,6 +41,7 @@ public sealed partial class JsonSchemaExporterTests_SourceGen() [JsonSerializable(typeof(ReadOnlyMemory))] [JsonSerializable(typeof(DateTime))] [JsonSerializable(typeof(DateTimeOffset))] + [JsonSerializable(typeof(DateTimeOffset?))] [JsonSerializable(typeof(TimeSpan))] #if NET [JsonSerializable(typeof(DateOnly))] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonSerializerWrapper.SourceGen.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonSerializerWrapper.SourceGen.cs index 23aa7621fdde87..bfe273959c1abb 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonSerializerWrapper.SourceGen.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonSerializerWrapper.SourceGen.cs @@ -1,10 +1,12 @@ // 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.Generic; using System.IO; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; using System.Text.Json.Serialization.Tests; +using System.Threading; using System.Threading.Tasks; namespace System.Text.Json.SourceGeneration.Tests @@ -66,6 +68,26 @@ private JsonSerializerOptions GetOptions(JsonSerializerOptions? options = null) return options; } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default) + { + return JsonSerializer.DeserializeAsyncEnumerable(utf8Json, GetOptions(options), cancellationToken); + } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) + { + return JsonSerializer.DeserializeAsyncEnumerable(utf8Json, jsonTypeInfo, cancellationToken); + } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, bool topLevelValues, CancellationToken cancellationToken = default) + { + return JsonSerializer.DeserializeAsyncEnumerable(utf8Json, jsonTypeInfo, topLevelValues, cancellationToken); + } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, bool topLevelValues, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) + { + return JsonSerializer.DeserializeAsyncEnumerable(utf8Json, topLevelValues, GetOptions(options), cancellationToken); + } } internal sealed class AsyncStreamSerializerWrapper : StreamingJsonSerializerWrapper @@ -136,5 +158,25 @@ private JsonSerializerOptions GetOptions(JsonSerializerOptions? options = null) return options; } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default) + { + return JsonSerializer.DeserializeAsyncEnumerable(utf8Json, GetOptions(options), cancellationToken); + } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) + { + return JsonSerializer.DeserializeAsyncEnumerable(utf8Json, jsonTypeInfo, cancellationToken); + } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, bool topLevelValues, CancellationToken cancellationToken = default) + { + return JsonSerializer.DeserializeAsyncEnumerable(utf8Json, jsonTypeInfo, topLevelValues, cancellationToken); + } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, bool topLevelValues, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) + { + return JsonSerializer.DeserializeAsyncEnumerable(utf8Json, topLevelValues, GetOptions(options), cancellationToken); + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/CompilationHelper.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/CompilationHelper.cs index 7f56065297f171..37f6c74e172c0d 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/CompilationHelper.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/CompilationHelper.cs @@ -829,7 +829,7 @@ internal static void AssertEqualDiagnosticMessages( internal static void AssertMaxSeverity(this IEnumerable diagnostics, DiagnosticSeverity maxSeverity) { - Assert.Empty(diagnostics.Where(diagnostic => diagnostic.Severity > maxSeverity)); + Assert.DoesNotContain(diagnostics, diagnostic => diagnostic.Severity > maxSeverity); } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonDocumentTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonDocumentTests.cs index 4657992d53f03b..73babaa84b4ade 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonDocumentTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonDocumentTests.cs @@ -1861,7 +1861,7 @@ public static void CheckInvalidString() [InlineData("\"hello\" ", "hello")] [InlineData(" null ", (string)null)] [InlineData("\"\\u0033\\u0031\"", "31")] - public static void ReadString(string json, string expectedValue) + public static void ReadString(string json, string? expectedValue) { using (JsonDocument doc = JsonDocument.Parse(json)) { diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonValueTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonValueTests.cs index 0719fa58414a59..83a51a3b3a7aaa 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonValueTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonValueTests.cs @@ -1,11 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Buffers; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; +using System.Text.Json.Tests; using Xunit; namespace System.Text.Json.Nodes.Tests @@ -263,6 +265,68 @@ public static void FromElement_ToElement(string json, string expected) } } + [Theory] + [InlineData("\"A\"", "A")] + [InlineData("\"AB\"", "AB")] + [InlineData("\"A\\u0022\"", "A\"")] // ValueEquals compares unescaped values + public static void DeserializePrimitive_ToElement_String(string json, string expected) + { + DoTest(json, expected); + + // Test long strings + string padding = new string('P', 256); + DoTest(json[0] + padding + json.Substring(1), padding + expected); + + static void DoTest(string json, string expected) + { + JsonValue value = JsonSerializer.Deserialize(json); + JsonElement element = value.GetValue(); + + AssertExtensions.TrueExpression(element.ValueEquals(expected)); + + bool success = value.TryGetValue(out element); + Assert.True(success); + AssertExtensions.TrueExpression(element.ValueEquals(expected)); + } + } + + [Fact] + public static void DeserializePrimitive_ToElement_Bool() + { + // true + JsonValue value = JsonSerializer.Deserialize("true"); + + JsonElement element = value.GetValue(); + Assert.Equal(JsonValueKind.True, element.ValueKind); + + bool success = value.TryGetValue(out element); + Assert.True(success); + Assert.Equal(JsonValueKind.True, element.ValueKind); + + // false + value = JsonSerializer.Deserialize("false"); + + element = value.GetValue(); + Assert.Equal(JsonValueKind.False, element.ValueKind); + + success = value.TryGetValue(out element); + Assert.True(success); + Assert.Equal(JsonValueKind.False, element.ValueKind); + } + + [Fact] + public static void DeserializePrimitive_ToElement_Number() + { + JsonValue value = JsonSerializer.Deserialize("42"); + + JsonElement element = value.GetValue(); + Assert.Equal(42, element.GetInt32()); + + bool success = value.TryGetValue(out element); + Assert.True(success); + Assert.Equal(42, element.GetInt32()); + } + [Theory] [InlineData("42")] [InlineData("\"AB\"")] @@ -309,6 +373,26 @@ public static void WriteTo() Assert.Equal(Json, json); } + [Theory] + [InlineData("\"A\"")] + [InlineData("\"AB\"")] + [InlineData("\"A\\u0022\"")] + [InlineData("42")] + [InlineData("true")] + [InlineData("false")] + public static void DeserializePrimitive_WriteTo(string json) + { + byte[] utf8Json = Encoding.UTF8.GetBytes(json); + JsonValue value = JsonSerializer.Deserialize(utf8Json); + + var buffer = new ArrayBufferWriter(json.Length); + using Utf8JsonWriter writer = new Utf8JsonWriter(buffer); + value.WriteTo(writer); + writer.Flush(); + + AssertExtensions.SequenceEqual(utf8Json, buffer.WrittenSpan); + } + [Fact] public static void DeepCloneNotTrimmable() { @@ -547,24 +631,27 @@ private class Student [Theory] [MemberData(nameof(GetPrimitiveTypes))] - public static void PrimitiveTypes_ReturnExpectedTypeKind(T value, JsonValueKind expectedKind) + public static void PrimitiveTypes_ReturnExpectedTypeKind(WrappedT wrapped, JsonValueKind expectedKind) { + T value = wrapped.Value; JsonNode node = JsonValue.Create(value); Assert.Equal(expectedKind, node.GetValueKind()); } [Theory] [MemberData(nameof(GetPrimitiveTypes))] - public static void PrimitiveTypes_EqualThemselves(T value, JsonValueKind _) + public static void PrimitiveTypes_EqualThemselves(WrappedT wrapped, JsonValueKind _) { + T value = wrapped.Value; JsonNode node = JsonValue.Create(value); Assert.True(JsonNode.DeepEquals(node, node)); } [Theory] [MemberData(nameof(GetPrimitiveTypes))] - public static void PrimitiveTypes_EqualClonedValue(T value, JsonValueKind _) + public static void PrimitiveTypes_EqualClonedValue(WrappedT wrapped, JsonValueKind _) { + T value = wrapped.Value; JsonNode node = JsonValue.Create(value); JsonNode clone = node.DeepClone(); @@ -575,8 +662,9 @@ public static void PrimitiveTypes_EqualClonedValue(T value, JsonValueKind _) [Theory] [MemberData(nameof(GetPrimitiveTypes))] - public static void PrimitiveTypes_EqualDeserializedValue(T value, JsonValueKind _) + public static void PrimitiveTypes_EqualDeserializedValue(WrappedT wrapped, JsonValueKind _) { + T value = wrapped.Value; JsonNode node = JsonValue.Create(value); JsonNode clone = JsonSerializer.Deserialize(node.ToJsonString()); @@ -585,6 +673,100 @@ public static void PrimitiveTypes_EqualDeserializedValue(T value, JsonValueKi Assert.True(JsonNode.DeepEquals(clone, node)); } + [Theory] + [MemberData(nameof(GetPrimitiveTypes))] + public static void PrimitiveTypes_DeepEquals_DifferentRepresentations(WrappedT wrapped, JsonValueKind _) + { + T value = wrapped.Value; + string json = JsonSerializer.Serialize(value); + JsonNode node = JsonSerializer.Deserialize(json); + JsonNode other = JsonSerializer.Deserialize($"[{json}]")[0]; // JsonValueOfElement + + Assert.True(JsonNode.DeepEquals(other, other)); + Assert.True(JsonNode.DeepEquals(node, other)); + Assert.True(JsonNode.DeepEquals(other, node)); + } + + [Theory] + [MemberData(nameof(GetPrimitiveTypes))] + public static void PrimitiveTypes_EqualClonedValue_DeserializedValue(WrappedT wrapped, JsonValueKind _) + { + T value = wrapped.Value; + string json = JsonSerializer.Serialize(value); + JsonNode node = JsonSerializer.Deserialize(json); + JsonNode clone = node.DeepClone(); + + Assert.True(JsonNode.DeepEquals(clone, clone)); + Assert.True(JsonNode.DeepEquals(node, clone)); + Assert.True(JsonNode.DeepEquals(clone, node)); + } + + private static readonly HashSet s_convertibleTypes = + [ + // True/False + typeof(bool), typeof(bool?), + + // Number + typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint), + typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal), + + typeof(byte?), typeof(sbyte?), typeof(short?), typeof(ushort?), typeof(int?), typeof(uint?), + typeof(long?), typeof(ulong?), typeof(float?), typeof(double?), typeof(decimal?), + + // String + typeof(char), typeof(char?), + typeof(string), + typeof(DateTimeOffset), typeof(DateTimeOffset?), + typeof(DateTime), typeof(DateTime?), + typeof(Guid), typeof(Guid?), + ]; + + [Theory] + [MemberData(nameof(GetPrimitiveTypes))] + public static void PrimitiveTypes_Conversion(WrappedT wrapped, JsonValueKind _) + { + T value = wrapped.Value; + string json = JsonSerializer.Serialize(value); + bool canGetValue = s_convertibleTypes.Contains(typeof(T)); + + JsonValue jsonValue = JsonSerializer.Deserialize(json)!; + AssertExtensions.TrueExpression(jsonValue.TryGetValue(out T unused) == canGetValue); + + if (canGetValue) + { + // Assert no throw + jsonValue.GetValue(); + } + else + { + Assert.Throws(() => jsonValue.GetValue()); + } + + JsonValue jsonNode = (JsonValue)JsonSerializer.Deserialize(json)!; + AssertExtensions.TrueExpression(jsonNode.TryGetValue(out unused) == canGetValue); + + // Ensure the eager evaluation code path also produces the same result + jsonNode = (JsonValue)JsonSerializer.Deserialize(json, new JsonSerializerOptions { AllowDuplicateProperties = false })!; + AssertExtensions.TrueExpression(jsonNode.TryGetValue(out unused) == canGetValue); + } + + [Theory] + [MemberData(nameof(GetPrimitiveTypes))] + public static void PrimitiveTypes_ReadOnlySequence(WrappedT wrapped, JsonValueKind _) + { + T value = wrapped.Value; + + byte[] jsonBytes = JsonSerializer.SerializeToUtf8Bytes(value); + ReadOnlySequence seq = BufferFactory.Create([jsonBytes.AsMemory(0, 1), jsonBytes.AsMemory(1, jsonBytes.Length - 1)]); + Utf8JsonReader reader = new Utf8JsonReader(seq); + JsonValue jsonValueFromSequence = JsonSerializer.Deserialize(ref reader)!; + + string jsonString = JsonSerializer.Serialize(value); + JsonValue jsonValueFromString = JsonSerializer.Deserialize(jsonString)!; + + AssertExtensions.TrueExpression(JsonNode.DeepEquals(jsonValueFromString, jsonValueFromSequence)); + } + public static IEnumerable GetPrimitiveTypes() { yield return Wrap(false, JsonValueKind.False); @@ -592,23 +774,37 @@ public static IEnumerable GetPrimitiveTypes() yield return Wrap((bool?)false, JsonValueKind.False); yield return Wrap((bool?)true, JsonValueKind.True); yield return Wrap((byte)42, JsonValueKind.Number); + yield return Wrap((byte?)42, JsonValueKind.Number); yield return Wrap((sbyte)42, JsonValueKind.Number); + yield return Wrap((sbyte?)42, JsonValueKind.Number); yield return Wrap((short)42, JsonValueKind.Number); + yield return Wrap((short?)42, JsonValueKind.Number); yield return Wrap((ushort)42, JsonValueKind.Number); + yield return Wrap((ushort?)42, JsonValueKind.Number); yield return Wrap(42, JsonValueKind.Number); yield return Wrap((int?)42, JsonValueKind.Number); yield return Wrap((uint)42, JsonValueKind.Number); + yield return Wrap((uint?)42, JsonValueKind.Number); yield return Wrap((long)42, JsonValueKind.Number); + yield return Wrap((long?)42, JsonValueKind.Number); yield return Wrap((ulong)42, JsonValueKind.Number); + yield return Wrap((ulong?)42, JsonValueKind.Number); yield return Wrap(42.0f, JsonValueKind.Number); + yield return Wrap((float?)42.0f, JsonValueKind.Number); yield return Wrap(42.0, JsonValueKind.Number); + yield return Wrap((double?)42.0, JsonValueKind.Number); yield return Wrap(42.0m, JsonValueKind.Number); + yield return Wrap((decimal?)42.0m, JsonValueKind.Number); yield return Wrap('A', JsonValueKind.String); yield return Wrap((char?)'A', JsonValueKind.String); yield return Wrap("A", JsonValueKind.String); + yield return Wrap("A\u0041", JsonValueKind.String); // \u0041 == A + yield return Wrap("A\u0022", JsonValueKind.String); // \u0022 == " yield return Wrap(new byte[] { 1, 2, 3 }, JsonValueKind.String); yield return Wrap(new DateTimeOffset(2024, 06, 20, 10, 29, 0, TimeSpan.Zero), JsonValueKind.String); + yield return Wrap((DateTimeOffset?)new DateTimeOffset(2024, 06, 20, 10, 29, 0, TimeSpan.Zero), JsonValueKind.String); yield return Wrap(new DateTime(2024, 06, 20, 10, 29, 0), JsonValueKind.String); + yield return Wrap((DateTime?)new DateTime(2024, 06, 20, 10, 29, 0), JsonValueKind.String); yield return Wrap(Guid.Empty, JsonValueKind.String); yield return Wrap((Guid?)Guid.Empty, JsonValueKind.String); yield return Wrap(new Uri("http://example.com"), JsonValueKind.String); @@ -624,7 +820,94 @@ public static IEnumerable GetPrimitiveTypes() yield return Wrap(new DateOnly(2024, 06, 20), JsonValueKind.String); yield return Wrap(new TimeOnly(10, 29), JsonValueKind.String); #endif - static object[] Wrap(T value, JsonValueKind expectedKind) => [value, expectedKind]; + static object[] Wrap(T value, JsonValueKind expectedKind) => [new WrappedT { Value = value }, expectedKind]; + } + + public class WrappedT + { + public T Value; + + public override string ToString() => Value?.ToString(); + } + + [Theory] + [InlineData("\"string\"")] + [InlineData("42.0")] + [InlineData("true")] + [InlineData("false")] + public static void PrimitiveTypes_ConverterThrows(string json) + { + JsonSerializerOptions opts = new JsonSerializerOptions + { + Converters = { new ThrowingConverter() } + }; + + JsonValue jsonValue = JsonSerializer.Deserialize(json, opts); + + Assert.False(jsonValue.TryGetValue(out DummyClass unused)); + Assert.Throws(() => jsonValue.GetValue()); } + + private sealed class ThrowingConverter : JsonConverter + { + public override DummyClass Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new JsonException(); + + public override void Write(Utf8JsonWriter writer, DummyClass value, JsonSerializerOptions options) => Assert.Fail(); + } + + [Theory] + [InlineData("\"string\"")] + [InlineData("42.0")] + [InlineData("true")] + [InlineData("false")] + public static void PrimitiveTypes_ConverterReturnsNull(string json) + { + JsonSerializerOptions opts = new JsonSerializerOptions + { + Converters = { new NullConverter() } + }; + + JsonValue jsonValue = JsonSerializer.Deserialize(json, opts); + + Assert.False(jsonValue.TryGetValue(out DummyClass unused)); + Assert.Throws(() => jsonValue.GetValue()); + } + + private sealed class NullConverter : JsonConverter + { + public override DummyClass Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => null; + + public override void Write(Utf8JsonWriter writer, DummyClass value, JsonSerializerOptions options) => Assert.Fail(); + } + + [Theory] + [InlineData("\"string\"")] + [InlineData("42.0")] + [InlineData("true")] + [InlineData("false")] + public static void PrimitiveTypes_NoTypeInfo(string json) + { + JsonSerializerOptions opts = new JsonSerializerOptions + { + TypeInfoResolver = new ExcludeType_TypeInfoResolver(typeof(DummyClass)) + }; + + JsonValue jsonValue = JsonSerializer.Deserialize(json, opts); + + Assert.False(jsonValue.TryGetValue(out DummyClass unused)); + Assert.Throws(() => jsonValue.GetValue()); + } + + private class ExcludeType_TypeInfoResolver(Type excludeType) : IJsonTypeInfoResolver + { + private static readonly DefaultJsonTypeInfoResolver _defaultResolver = new DefaultJsonTypeInfoResolver(); + + public Type ExcludeType { get; } = excludeType; + + public JsonTypeInfo? GetTypeInfo(Type type, JsonSerializerOptions options) => + type == ExcludeType ? null : _defaultResolver.GetTypeInfo(type, options); + } + + private record DummyClass; } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/ToStringTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/ToStringTests.cs index 9fd937fadddcc4..eed98a1da6ef02 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/ToStringTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/ToStringTests.cs @@ -26,6 +26,10 @@ public static void NodeToString_StringValuesNotQuoted() node = JsonValue.Create("Hello"); json = node.ToString(); Assert.Equal("Hello", json); + + node = JsonSerializer.Deserialize("\"Hello\""); + json = node.ToString(); + Assert.Equal("Hello", json); } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonPropertyTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonPropertyTests.cs index 7642aa43b294ee..881af3f439d74e 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonPropertyTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonPropertyTests.cs @@ -96,7 +96,7 @@ private static void AssertContents(string expectedValue, ArrayBufferWriter [InlineData("hello")] [InlineData("")] [InlineData(null)] - public static void NameEquals_InvalidInstance_Throws(string text) + public static void NameEquals_InvalidInstance_Throws(string? text) { string ErrorMessage = new InvalidOperationException().Message; JsonProperty prop = default; diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/AsyncEnumerableTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/AsyncEnumerableTests.cs new file mode 100644 index 00000000000000..ffc48053c081e8 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/AsyncEnumerableTests.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Pipelines; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace System.Text.Json.Serialization.Tests +{ + public class AsyncEnumerableTests_AsyncStream : AsyncEnumerableTests + { + public AsyncEnumerableTests_AsyncStream() : base(JsonSerializerWrapper.AsyncStreamSerializer) { } + + [Fact] + public void DeserializeAsyncEnumerable_NullArgument_ThrowsArgumentNullException() + { + AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: (Stream?)null)); + AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: (Stream?)null, jsonTypeInfo: ResolveJsonTypeInfo())); + AssertExtensions.Throws("jsonTypeInfo", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: new MemoryStream(), jsonTypeInfo: null)); + } + } + + public class AsyncEnumerableTests_AsyncPipeSerializer : AsyncEnumerableTests + { + public AsyncEnumerableTests_AsyncPipeSerializer() : base(JsonSerializerWrapper.AsyncPipeSerializer) { } + + [Fact] + public void DeserializeAsyncEnumerable_NullArgument_ThrowsArgumentNullException() + { + AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: (PipeReader?)null)); + AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: (PipeReader?)null, jsonTypeInfo: ResolveJsonTypeInfo())); + AssertExtensions.Throws("jsonTypeInfo", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: new Pipe().Reader, jsonTypeInfo: null)); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CollectionTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CollectionTests.cs index 73c4ed6f661c9b..f8050941dadb21 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CollectionTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CollectionTests.cs @@ -29,4 +29,9 @@ public sealed partial class CollectionTestsDynamic_Pipe : CollectionTests { public CollectionTestsDynamic_Pipe() : base(JsonSerializerWrapper.AsyncPipeSerializer) { } } + + public sealed partial class CollectionTestsDynamic_PipeWithSmallBuffer : CollectionTests + { + public CollectionTestsDynamic_PipeWithSmallBuffer() : base(JsonSerializerWrapper.AsyncPipeSerializerWithSmallBuffer) { } + } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.cs index 42fdc3549e5500..e4f0a01895261e 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.cs @@ -251,7 +251,7 @@ private sealed class InvalidJsonConverterFactory : JsonConverterFactory [InlineData(typeof(JsonStringEnumConverter), null)] [InlineData(typeof(InvalidJsonConverterFactory), null)] [InlineData(typeof(TestFactory), null)] - public static void JsonConverter_TypeProperty_ReturnsExpectedResult(Type converterType, Type expectedType) + public static void JsonConverter_TypeProperty_ReturnsExpectedResult(Type converterType, Type? expectedType) { var converter = (JsonConverter)Activator.CreateInstance(converterType)!; Assert.Equal(expectedType, converter.Type); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/EnumConverterTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/EnumConverterTests.cs index aecc33a26760b1..fa5bc9ae5f24c0 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/EnumConverterTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/EnumConverterTests.cs @@ -1257,5 +1257,41 @@ public enum EnumWithVaryingNamingPolicies A, b, } + + [Fact] + public static void EnumWithOverlappingBitsTests() + { + JsonSerializerOptions options = new() { Converters = { new JsonStringEnumConverter() } }; + + EnumWithOverlappingBits e1 = EnumWithOverlappingBits.BITS01 | EnumWithOverlappingBits.BIT3; + string json1 = JsonSerializer.Serialize(e1, options); + Assert.Equal("\"BITS01, BIT3\"", json1); + + EnumWithOverlappingBits2 e2 = EnumWithOverlappingBits2.BITS01 | EnumWithOverlappingBits2.BIT3; + string json2 = JsonSerializer.Serialize(e2, options); + Assert.Equal("\"BITS01, BIT3\"", json2); + } + + [Flags] + public enum EnumWithOverlappingBits + { + UNKNOWN = 0, + BIT0 = 1, + BIT1 = 2, + BIT2 = 4, + BIT3 = 8, + BITS01 = 3, + } + + [Flags] + public enum EnumWithOverlappingBits2 + { + UNKNOWN = 0, + BIT0 = 1, + // direct option for bit 1 missing + BIT2 = 4, + BIT3 = 8, + BITS01 = 3, + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/InvalidTypeTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/InvalidTypeTests.cs index 244a7229cd7fd5..728a2b99851e09 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/InvalidTypeTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/InvalidTypeTests.cs @@ -42,6 +42,11 @@ public class InvalidTypeTests_Pipe : InvalidTypeTests public InvalidTypeTests_Pipe() : base(JsonSerializerWrapper.AsyncPipeSerializer) { } } + public class InvalidTypeTests_PipeWithSmallBuffer : InvalidTypeTests + { + public InvalidTypeTests_PipeWithSmallBuffer() : base(JsonSerializerWrapper.AsyncPipeSerializerWithSmallBuffer) { } + } + public abstract class InvalidTypeTests { private JsonSerializerWrapper Serializer { get; } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonCreationHandlingTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonCreationHandlingTests.cs index 573638913ae381..b901cd079599cb 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonCreationHandlingTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonCreationHandlingTests.cs @@ -27,4 +27,9 @@ public sealed class JsonCreationHandlingTests_Pipe : JsonCreationHandlingTests { public JsonCreationHandlingTests_Pipe() : base(JsonSerializerWrapper.AsyncPipeSerializer) { } } + + public sealed class JsonCreationHandlingTests_PipeWithSmallBuffer : JsonCreationHandlingTests + { + public JsonCreationHandlingTests_PipeWithSmallBuffer() : base(JsonSerializerWrapper.AsyncPipeSerializerWithSmallBuffer) { } + } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonSerializerApiValidation.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonSerializerApiValidation.cs index 1ed08df56d62c0..587893e7392b71 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonSerializerApiValidation.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonSerializerApiValidation.cs @@ -55,6 +55,11 @@ public class JsonSerializerApiValidation_Pipe : JsonSerializerApiValidation { public JsonSerializerApiValidation_Pipe() : base(JsonSerializerWrapper.AsyncPipeSerializer) { } } + + public class JsonSerializerApiValidation_PipeWithSmallBuffer : JsonSerializerApiValidation + { + public JsonSerializerApiValidation_PipeWithSmallBuffer() : base(JsonSerializerWrapper.AsyncPipeSerializerWithSmallBuffer) { } + } } /// diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonSerializerWrapper.Reflection.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonSerializerWrapper.Reflection.cs index 972aef40796120..e811d951f02cc5 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonSerializerWrapper.Reflection.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonSerializerWrapper.Reflection.cs @@ -10,6 +10,7 @@ using System.Runtime.CompilerServices; using System.Text.Json.Nodes; using System.Text.Json.Serialization.Metadata; +using System.Threading; using System.Threading.Tasks; using Xunit; @@ -34,7 +35,8 @@ protected JsonSerializerWrapper() public static JsonSerializerWrapper DocumentSerializer { get; } = new DocumentSerializerWrapper(); public static JsonSerializerWrapper ElementSerializer { get; } = new ElementSerializerWrapper(); public static JsonSerializerWrapper NodeSerializer { get; } = new NodeSerializerWrapper(); - public static JsonSerializerWrapper AsyncPipeSerializer { get; } = new AsyncPipelinesSerializerWrapper(); + public static PipeJsonSerializerWrapper AsyncPipeSerializer { get; } = new AsyncPipelinesSerializerWrapper(); + public static PipeJsonSerializerWrapper AsyncPipeSerializerWithSmallBuffer { get; } = new AsyncPipelinesSerializerWrapper(forceSmallBufferInOptions: true); private class SpanSerializerWrapper : JsonSerializerWrapper { @@ -95,6 +97,11 @@ public override Task DeserializeWrapper(string json, JsonTypeInfo jsonTy { return Task.FromResult(JsonSerializer.Deserialize(json.AsSpan(), jsonTypeInfo)); } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, bool topLevelValues, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, bool topLevelValues, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); } private class StringSerializerWrapper : JsonSerializerWrapper @@ -151,6 +158,11 @@ public override Task DeserializeWrapper(string value, JsonTypeInfo jsonT { return Task.FromResult(JsonSerializer.Deserialize(value, jsonTypeInfo)); } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, bool topLevelValues, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, bool topLevelValues, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); } private class AsyncStreamSerializerWrapper : StreamingJsonSerializerWrapper @@ -223,6 +235,26 @@ public override async Task DeserializeWrapper(Stream utf8Json, Type retu { return await JsonSerializer.DeserializeAsync(ResolveReadStream(utf8Json), returnType, context); } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default) + { + return JsonSerializer.DeserializeAsyncEnumerable(ResolveReadStream(utf8Json), ResolveOptionsInstance(options), cancellationToken); + } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) + { + return JsonSerializer.DeserializeAsyncEnumerable(ResolveReadStream(utf8Json), jsonTypeInfo, cancellationToken); + } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, bool topLevelValues, CancellationToken cancellationToken = default) + { + return JsonSerializer.DeserializeAsyncEnumerable(ResolveReadStream(utf8Json), jsonTypeInfo, topLevelValues, cancellationToken); + } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, bool topLevelValues, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) + { + return JsonSerializer.DeserializeAsyncEnumerable(ResolveReadStream(utf8Json), topLevelValues, ResolveOptionsInstance(options), cancellationToken); + } } private class SyncStreamSerializerWrapper : StreamingJsonSerializerWrapper @@ -305,6 +337,11 @@ public override Task DeserializeWrapper(Stream utf8Json, Type returnType object result = JsonSerializer.Deserialize(ResolveReadStream(utf8Json), returnType, context); return Task.FromResult(result); } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, bool topLevelValues, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, bool topLevelValues, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); } private class ReaderWriterSerializerWrapper : JsonSerializerWrapper @@ -394,6 +431,11 @@ public override Task DeserializeWrapper(string json, Type type, JsonSeri Utf8JsonReader reader = new(Encoding.UTF8.GetBytes(json), OptionsHelpers.GetReaderOptions(context?.Options)); return Task.FromResult(JsonSerializer.Deserialize(ref reader, type, context)); } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, bool topLevelValues, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, bool topLevelValues, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); } private class DocumentSerializerWrapper : JsonSerializerWrapper @@ -505,6 +547,11 @@ public override Task DeserializeWrapper(string json, Type type, JsonSeri using JsonDocument document = JsonDocument.Parse(json, OptionsHelpers.GetDocumentOptions(context?.Options)); return Task.FromResult(document.Deserialize(type, context)); } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, bool topLevelValues, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, bool topLevelValues, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); } private class ElementSerializerWrapper : JsonSerializerWrapper @@ -579,6 +626,11 @@ public override Task DeserializeWrapper(string json, Type type, JsonSeri using JsonDocument document = JsonDocument.Parse(json, OptionsHelpers.GetDocumentOptions(context?.Options)); return Task.FromResult(document.RootElement.Deserialize(type, context)); } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, bool topLevelValues, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, bool topLevelValues, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); } private class NodeSerializerWrapper : JsonSerializerWrapper @@ -710,6 +762,11 @@ public override Task DeserializeWrapper(string json, Type type, JsonSeri JsonNode node = JsonNode.Parse(json, OptionsHelpers.GetNodeOptions(context?.Options), OptionsHelpers.GetDocumentOptions(context?.Options)); return Task.FromResult(node.Deserialize(type, context)); } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, bool topLevelValues, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, bool topLevelValues, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); } private static class OptionsHelpers @@ -885,67 +942,92 @@ private int ReadExactlyFromSource(byte[] buffer, int offset, int count) public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException(); } - // TODO: Deserialize to use PipeReader overloads once implemented - private class AsyncPipelinesSerializerWrapper : StreamingJsonSerializerWrapper + private class AsyncPipelinesSerializerWrapper : PipeJsonSerializerWrapper { + private readonly bool _forceSmallBufferInOptions; + public override JsonSerializerOptions DefaultOptions => JsonSerializerOptions.Default; public override bool SupportsNullValueOnDeserialize => true; public override bool IsAsyncSerializer => true; + public AsyncPipelinesSerializerWrapper(bool forceSmallBufferInOptions = false) + { + _forceSmallBufferInOptions = forceSmallBufferInOptions; + } + + private JsonSerializerOptions? ResolveOptionsInstance(JsonSerializerOptions? options) + => _forceSmallBufferInOptions ? JsonSerializerOptionsSmallBufferMapper.ResolveOptionsInstanceWithSmallBuffer(options) : options; + public override async Task DeserializeWrapper(string json, JsonSerializerOptions options = null) { - return await JsonSerializer.DeserializeAsync(new MemoryStream(Encoding.UTF8.GetBytes(json)), options); + Pipe pipe = new Pipe(new PipeOptions(pauseWriterThreshold: 0)); + await pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes(json)); + pipe.Writer.Complete(); + return await JsonSerializer.DeserializeAsync(pipe.Reader, ResolveOptionsInstance(options)); } + public override async Task DeserializeWrapper(string json, Type type, JsonSerializerOptions options = null) { - return await JsonSerializer.DeserializeAsync(new MemoryStream(Encoding.UTF8.GetBytes(json)), type, options); + Pipe pipe = new Pipe(new PipeOptions(pauseWriterThreshold: 0)); + await pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes(json)); + pipe.Writer.Complete(); + return await JsonSerializer.DeserializeAsync(pipe.Reader, type, ResolveOptionsInstance(options)); } public override async Task DeserializeWrapper(string json, JsonTypeInfo jsonTypeInfo) { - return await JsonSerializer.DeserializeAsync(new MemoryStream(Encoding.UTF8.GetBytes(json)), jsonTypeInfo); + Pipe pipe = new Pipe(new PipeOptions(pauseWriterThreshold: 0)); + await pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes(json)); + pipe.Writer.Complete(); + return await JsonSerializer.DeserializeAsync(pipe.Reader, jsonTypeInfo); } public override async Task DeserializeWrapper(string value, JsonTypeInfo jsonTypeInfo) { - return await JsonSerializer.DeserializeAsync(new MemoryStream(Encoding.UTF8.GetBytes(value)), jsonTypeInfo); + Pipe pipe = new Pipe(new PipeOptions(pauseWriterThreshold: 0)); + await pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes(value)); + pipe.Writer.Complete(); + return await JsonSerializer.DeserializeAsync(pipe.Reader, jsonTypeInfo); } public override async Task DeserializeWrapper(string json, Type type, JsonSerializerContext context) { - return await JsonSerializer.DeserializeAsync(new MemoryStream(Encoding.UTF8.GetBytes(json)), type, context); + Pipe pipe = new Pipe(new PipeOptions(pauseWriterThreshold: 0)); + await pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes(json)); + pipe.Writer.Complete(); + return await JsonSerializer.DeserializeAsync(pipe.Reader, type, context); } - public override Task DeserializeWrapper(Stream utf8Json, Type returnType, JsonSerializerOptions? options = null) + public override Task DeserializeWrapper(PipeReader utf8Json, Type returnType, JsonSerializerOptions? options = null) { - return JsonSerializer.DeserializeAsync(utf8Json, returnType, options).AsTask(); + return JsonSerializer.DeserializeAsync(utf8Json, returnType, ResolveOptionsInstance(options)).AsTask(); } - public override Task DeserializeWrapper(Stream utf8Json, JsonSerializerOptions? options = null) + public override Task DeserializeWrapper(PipeReader utf8Json, JsonSerializerOptions? options = null) { - return JsonSerializer.DeserializeAsync(utf8Json, options).AsTask(); + return JsonSerializer.DeserializeAsync(utf8Json, ResolveOptionsInstance(options)).AsTask(); } - public override Task DeserializeWrapper(Stream utf8Json, Type returnType, JsonSerializerContext context) + public override Task DeserializeWrapper(PipeReader utf8Json, Type returnType, JsonSerializerContext context) { return JsonSerializer.DeserializeAsync(utf8Json, returnType, context).AsTask(); } - public override Task DeserializeWrapper(Stream utf8Json, JsonTypeInfo jsonTypeInfo) + public override Task DeserializeWrapper(PipeReader utf8Json, JsonTypeInfo jsonTypeInfo) { return JsonSerializer.DeserializeAsync(utf8Json, jsonTypeInfo).AsTask(); } - public override Task DeserializeWrapper(Stream utf8Json, JsonTypeInfo jsonTypeInfo) + public override Task DeserializeWrapper(PipeReader utf8Json, JsonTypeInfo jsonTypeInfo) { return JsonSerializer.DeserializeAsync(utf8Json, jsonTypeInfo).AsTask(); } public override async Task SerializeWrapper(object value, Type inputType, JsonSerializerOptions options = null) { - Pipe pipe = new Pipe(); - await JsonSerializer.SerializeAsync(pipe.Writer, value, inputType, options); + Pipe pipe = new Pipe(new PipeOptions(pauseWriterThreshold: 0)); + await JsonSerializer.SerializeAsync(pipe.Writer, value, inputType, ResolveOptionsInstance(options)); ReadResult result = await pipe.Reader.ReadAsync(); string stringResult = Encoding.UTF8.GetString(result.Buffer.ToArray()); @@ -955,8 +1037,8 @@ public override async Task SerializeWrapper(object value, Type inputType public override async Task SerializeWrapper(T value, JsonSerializerOptions options = null) { - Pipe pipe = new Pipe(); - await JsonSerializer.SerializeAsync(pipe.Writer, value, options); + Pipe pipe = new Pipe(new PipeOptions(pauseWriterThreshold: 0)); + await JsonSerializer.SerializeAsync(pipe.Writer, value, ResolveOptionsInstance(options)); ReadResult result = await pipe.Reader.ReadAsync(); string stringResult = Encoding.UTF8.GetString(result.Buffer.ToArray()); @@ -966,7 +1048,7 @@ public override async Task SerializeWrapper(T value, JsonSerializerOp public override async Task SerializeWrapper(object value, Type inputType, JsonSerializerContext context) { - Pipe pipe = new Pipe(); + Pipe pipe = new Pipe(new PipeOptions(pauseWriterThreshold: 0)); await JsonSerializer.SerializeAsync(pipe.Writer, value, inputType, context); ReadResult result = await pipe.Reader.ReadAsync(); @@ -977,7 +1059,7 @@ public override async Task SerializeWrapper(object value, Type inputType public override async Task SerializeWrapper(T value, JsonTypeInfo jsonTypeInfo) { - Pipe pipe = new Pipe(); + Pipe pipe = new Pipe(new PipeOptions(pauseWriterThreshold: 0)); await JsonSerializer.SerializeAsync(pipe.Writer, value, jsonTypeInfo); ReadResult result = await pipe.Reader.ReadAsync(); @@ -988,7 +1070,7 @@ public override async Task SerializeWrapper(T value, JsonTypeInfo public override async Task SerializeWrapper(object value, JsonTypeInfo jsonTypeInfo) { - Pipe pipe = new Pipe(); + Pipe pipe = new Pipe(new PipeOptions(pauseWriterThreshold: 0)); await JsonSerializer.SerializeAsync(pipe.Writer, value, jsonTypeInfo); ReadResult result = await pipe.Reader.ReadAsync(); @@ -997,12 +1079,97 @@ public override async Task SerializeWrapper(object value, JsonTypeInfo j return stringResult; } + public override async Task SerializeWrapper(PipeWriter utf8Json, object value, Type inputType, JsonSerializerOptions? options = null) + { + try + { + await JsonSerializer.SerializeAsync(utf8Json, value, inputType, ResolveOptionsInstance(options)); + } + finally + { + await utf8Json.FlushAsync(); + } + } + + public override async Task SerializeWrapper(PipeWriter utf8Json, T value, JsonSerializerOptions? options = null) + { + try + { + await JsonSerializer.SerializeAsync(utf8Json, value, ResolveOptionsInstance(options)); + } + finally + { + await utf8Json.FlushAsync(); + } + } + + public override async Task SerializeWrapper(PipeWriter utf8Json, object value, Type inputType, JsonSerializerContext context) + { + try + { + await JsonSerializer.SerializeAsync(utf8Json, value, inputType, context); + } + finally + { + await utf8Json.FlushAsync(); + } + } + + public override async Task SerializeWrapper(PipeWriter utf8Json, T value, JsonTypeInfo jsonTypeInfo) + { + try + { + await JsonSerializer.SerializeAsync(utf8Json, value, jsonTypeInfo); + } + finally + { + await utf8Json.FlushAsync(); + } + } + + public override async Task SerializeWrapper(PipeWriter utf8Json, object value, JsonTypeInfo jsonTypeInfo) + { + try + { + await JsonSerializer.SerializeAsync(utf8Json, value, jsonTypeInfo); + } + finally + { + await utf8Json.FlushAsync(); + } + } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default) + { + var pipeReader = PipeReader.Create(utf8Json, new StreamPipeReaderOptions(leaveOpen: true, bufferSize: ResolveOptionsInstance(options)?.DefaultBufferSize ?? -1)); + return JsonSerializer.DeserializeAsyncEnumerable(pipeReader, ResolveOptionsInstance(options), cancellationToken); + } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) + { + var pipeReader = PipeReader.Create(utf8Json, new StreamPipeReaderOptions(leaveOpen: true, bufferSize: jsonTypeInfo.Options.DefaultBufferSize)); + return JsonSerializer.DeserializeAsyncEnumerable(pipeReader, jsonTypeInfo, cancellationToken); + } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, JsonTypeInfo jsonTypeInfo, bool topLevelValues, CancellationToken cancellationToken = default) + { + var pipeReader = PipeReader.Create(utf8Json, new StreamPipeReaderOptions(leaveOpen: true, bufferSize: jsonTypeInfo.Options.DefaultBufferSize)); + return JsonSerializer.DeserializeAsyncEnumerable(pipeReader, jsonTypeInfo, topLevelValues, cancellationToken); + } + + public override IAsyncEnumerable DeserializeAsyncEnumerable(Stream utf8Json, bool topLevelValues, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) + { + var pipeReader = PipeReader.Create(utf8Json, new StreamPipeReaderOptions(leaveOpen: true, bufferSize: ResolveOptionsInstance(options)?.DefaultBufferSize ?? -1)); + return JsonSerializer.DeserializeAsyncEnumerable(pipeReader, topLevelValues, ResolveOptionsInstance(options), cancellationToken); + } + public override async Task SerializeWrapper(Stream stream, object value, Type inputType, JsonSerializerOptions? options = null) { - var writer = PipeWriter.Create(stream); + PipeWriter writer = PipeWriter.Create(stream, + new StreamPipeWriterOptions(minimumBufferSize: ResolveOptionsInstance(options)?.DefaultBufferSize ?? -1, leaveOpen: true)); try { - await JsonSerializer.SerializeAsync(writer, value, inputType, options); + await JsonSerializer.SerializeAsync(writer, value, inputType, ResolveOptionsInstance(options)); } finally { @@ -1012,10 +1179,11 @@ public override async Task SerializeWrapper(Stream stream, object value, Type in public override async Task SerializeWrapper(Stream stream, T value, JsonSerializerOptions? options = null) { - var writer = PipeWriter.Create(stream); + PipeWriter writer = PipeWriter.Create(stream, + new StreamPipeWriterOptions(minimumBufferSize: ResolveOptionsInstance(options)?.DefaultBufferSize ?? -1, leaveOpen: true)); try { - await JsonSerializer.SerializeAsync(writer, value, options); + await JsonSerializer.SerializeAsync(writer, value, ResolveOptionsInstance(options)); } finally { @@ -1025,7 +1193,7 @@ public override async Task SerializeWrapper(Stream stream, T value, JsonSeria public override async Task SerializeWrapper(Stream stream, object value, Type inputType, JsonSerializerContext context) { - var writer = PipeWriter.Create(stream); + PipeWriter writer = PipeWriter.Create(stream, new StreamPipeWriterOptions(leaveOpen: true)); try { await JsonSerializer.SerializeAsync(writer, value, inputType, context); @@ -1038,7 +1206,7 @@ public override async Task SerializeWrapper(Stream stream, object value, Type in public override async Task SerializeWrapper(Stream stream, T value, JsonTypeInfo jsonTypeInfo) { - var writer = PipeWriter.Create(stream); + PipeWriter writer = PipeWriter.Create(stream, new StreamPipeWriterOptions(leaveOpen: true)); try { await JsonSerializer.SerializeAsync(writer, value, jsonTypeInfo); @@ -1051,7 +1219,7 @@ public override async Task SerializeWrapper(Stream stream, T value, JsonTypeI public override async Task SerializeWrapper(Stream stream, object value, JsonTypeInfo jsonTypeInfo) { - var writer = PipeWriter.Create(stream); + PipeWriter writer = PipeWriter.Create(stream, new StreamPipeWriterOptions(leaveOpen: true)); try { await JsonSerializer.SerializeAsync(writer, value, jsonTypeInfo); @@ -1061,6 +1229,38 @@ public override async Task SerializeWrapper(Stream stream, object value, JsonTyp await writer.FlushAsync(); } } + + public override Task DeserializeWrapper(Stream utf8Json, Type returnType, JsonSerializerOptions? options = null) + { + var pipeReader = PipeReader.Create(utf8Json, + new StreamPipeReaderOptions(leaveOpen: true, bufferSize: ResolveOptionsInstance(options)?.DefaultBufferSize ?? -1)); + return JsonSerializer.DeserializeAsync(pipeReader, returnType, ResolveOptionsInstance(options)).AsTask(); + } + + public override Task DeserializeWrapper(Stream utf8Json, JsonSerializerOptions? options = null) + { + var pipeReader = PipeReader.Create(utf8Json, + new StreamPipeReaderOptions(leaveOpen: true, bufferSize: ResolveOptionsInstance(options)?.DefaultBufferSize ?? -1)); + return JsonSerializer.DeserializeAsync(pipeReader, ResolveOptionsInstance(options)).AsTask(); + } + + public override Task DeserializeWrapper(Stream utf8Json, Type returnType, JsonSerializerContext context) + { + var pipeReader = PipeReader.Create(utf8Json, new StreamPipeReaderOptions(leaveOpen: true)); + return JsonSerializer.DeserializeAsync(pipeReader, returnType, context).AsTask(); + } + + public override Task DeserializeWrapper(Stream utf8Json, JsonTypeInfo jsonTypeInfo) + { + var pipeReader = PipeReader.Create(utf8Json, new StreamPipeReaderOptions(leaveOpen: true)); + return JsonSerializer.DeserializeAsync(pipeReader, jsonTypeInfo).AsTask(); + } + + public override Task DeserializeWrapper(Stream utf8Json, JsonTypeInfo jsonTypeInfo) + { + var pipeReader = PipeReader.Create(utf8Json, new StreamPipeReaderOptions(leaveOpen: true)); + return JsonSerializer.DeserializeAsync(pipeReader, jsonTypeInfo).AsTask(); + } } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/NumberHandlingTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/NumberHandlingTests.cs index 5613dda7793354..b5cb5381b07f3a 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/NumberHandlingTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/NumberHandlingTests.cs @@ -47,6 +47,11 @@ public class NumberHandlingTests_Pipe : NumberHandlingTests_OverloadSpecific public NumberHandlingTests_Pipe() : base(JsonSerializerWrapper.AsyncPipeSerializer) { } } + public class NumberHandlingTests_PipeWithSmallBuffer : NumberHandlingTests_OverloadSpecific + { + public NumberHandlingTests_PipeWithSmallBuffer() : base(JsonSerializerWrapper.AsyncPipeSerializerWithSmallBuffer) { } + } + public abstract class NumberHandlingTests_OverloadSpecific { private JsonSerializerWrapper Serializer { get; } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Pipe.ReadTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Pipe.ReadTests.cs new file mode 100644 index 00000000000000..16b22784a4c928 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Pipe.ReadTests.cs @@ -0,0 +1,147 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO.Pipelines; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Text.Json.Serialization.Tests +{ + public partial class PipeTests + { + [Fact] + public async Task ReadNullArgumentFail() + { + await Assert.ThrowsAsync(async () => await JsonSerializer.DeserializeAsync((PipeReader)null)); + await Assert.ThrowsAsync(async () => await JsonSerializer.DeserializeAsync((PipeReader)null, (Type)null)); + await Assert.ThrowsAsync(async () => await JsonSerializer.DeserializeAsync((PipeReader)null, typeof(string))); + await Assert.ThrowsAsync(async () => await JsonSerializer.DeserializeAsync(new Pipe().Reader, (Type)null)); + } + + [Fact] + public async Task CompleteWriterThrowsJsonExceptionDuringDeserialize() + { + Pipe pipe = new Pipe(); + PipeWriter writer = pipe.Writer; + PipeReader reader = pipe.Reader; + + // Write incomplete JSON and complete the writer (simulate disconnection) + await writer.WriteAsync(Encoding.UTF8.GetBytes("{\"Value\": 42, \"Text\": \"Hello")); + + Task readTask = Serializer.DeserializeWrapper(reader); + + writer.Complete(); // Complete without closing the JSON + + // Attempt to deserialize should fail with JsonException due to incomplete JSON + await Assert.ThrowsAsync(() => readTask); + + reader.Complete(); + } + + [Fact] + public async Task CompleteWriterWithExceptionThrowsExceptionDuringDeserialize() + { + Pipe pipe = new Pipe(); + PipeWriter writer = pipe.Writer; + PipeReader reader = pipe.Reader; + + // Write incomplete JSON and complete the writer (simulate disconnection) + await writer.WriteAsync(Encoding.UTF8.GetBytes("{\"Value\": 42, \"Text\": \"Hello")); + + Task readTask = Serializer.DeserializeWrapper(reader); + + writer.Complete(new Exception()); + + // Attempt to deserialize should fail with Exception due to Pipe completed with exception + await Assert.ThrowsAsync(() => readTask); + + reader.Complete(); + } + + [Fact] + public async Task CancellationTokenPassedToDeserializeAsyncWorks() + { + // Setup pipe + Pipe pipe = new Pipe(); + PipeWriter writer = pipe.Writer; + PipeReader reader = pipe.Reader; + + // Write partial JSON data + await writer.WriteAsync(Encoding.UTF8.GetBytes("{\"Value\":")); + + // Create a cancellation token source and cancel after starting deserialization + using CancellationTokenSource cts = new CancellationTokenSource(); + + // Start the deserializer task with the cancellation token + Task deserializeTask = JsonSerializer.DeserializeAsync(reader, cancellationToken: cts.Token).AsTask(); + + // Cancel the token immediately + cts.Cancel(); + + // Verify that the operation was canceled + await Assert.ThrowsAnyAsync(() => deserializeTask); + + // Clean up + writer.Complete(); + reader.Complete(); + } + + [Fact] + public async Task CancelPendingReadThrows() + { + Pipe pipe = new Pipe(); + Task readTask = Serializer.DeserializeWrapper(pipe.Reader); + pipe.Reader.CancelPendingRead(); + + OperationCanceledException ex = await Assert.ThrowsAsync(async () => await readTask); + Assert.Equal("PipeReader.ReadAsync was canceled.", ex.Message); + + // Clean up + pipe.Writer.Complete(); + pipe.Reader.Complete(); + } + + [Fact] + public async Task DeserializeRelievesBackpressureWhileProcessing() + { + Pipe pipe = new Pipe(new PipeOptions(pauseWriterThreshold: 10, resumeWriterThreshold: 5)); + + // First write will experience backpressure + ValueTask writeTask = pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes("\"123456789")); + Assert.False(writeTask.IsCompleted); + + Task deserializeTask = Serializer.DeserializeWrapper(pipe.Reader); + + // DeserializeAsync should start processing the data and relieve backpressure + await writeTask; + + // Technically these writes could experience backpressure, but since the deserializer is reading in a loop + // it'd be difficult to reliably observe the backpressure. + // Do a couple writes that "would" experience backpressure, if there wasn't a reader, to verify that the deserializer + // is processing the data. + await pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes("1234567890")); + + await pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes("123456789\"")); + + pipe.Writer.Complete(); + + Assert.Equal("1234567891234567890123456789", await deserializeTask); + + pipe.Reader.Complete(); + } + + [Theory] + [InlineData(1)] + [InlineData(2)] + [InlineData(3)] + public async Task MultiSegmentBOMIsHandled(int segmentSize) + { + byte[] data = [..Encoding.UTF8.GetPreamble(), ..Encoding.UTF8.GetBytes("123456789")]; + + PipeReader reader = PipeReader.Create(JsonTestHelper.GetSequence(data, segmentSize)); + int result = await Serializer.DeserializeWrapper(reader); + Assert.Equal(123456789, result); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/PipeTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/PipeTests.cs new file mode 100644 index 00000000000000..19e37b2972f226 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/PipeTests.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Text.Json.Serialization.Tests +{ + public abstract partial class PipeTests + { + public sealed class PipeTests_Async : PipeTests + { + public PipeTests_Async() : base(JsonSerializerWrapper.AsyncPipeSerializer) { } + } + + public sealed class PipeTests_AsyncWithSmallBuffer : PipeTests + { + public PipeTests_AsyncWithSmallBuffer() : base(JsonSerializerWrapper.AsyncPipeSerializerWithSmallBuffer) { } + } + + /// + /// The System Under Test for the test suite. + /// + private PipeJsonSerializerWrapper Serializer { get; } + + public PipeTests(PipeJsonSerializerWrapper serializer) + { + Serializer = serializer; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/PolymorphicTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/PolymorphicTests.cs index 861522b881d79b..33707fb41c0eca 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/PolymorphicTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/PolymorphicTests.cs @@ -61,6 +61,11 @@ public class PolymorphicTests_Pipe : PolymorphicTests public PolymorphicTests_Pipe() : base(JsonSerializerWrapper.AsyncPipeSerializer) { } } + public class PolymorphicTests_PipeWithSmallBuffer : PolymorphicTests + { + public PolymorphicTests_PipeWithSmallBuffer() : base(JsonSerializerWrapper.AsyncPipeSerializerWithSmallBuffer) { } + } + public abstract partial class PolymorphicTests : SerializerTests { public PolymorphicTests(JsonSerializerWrapper serializer) : base(serializer) diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/ReadValueTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/ReadValueTests.cs index fd74be8191817e..75495a030646e2 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/ReadValueTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/ReadValueTests.cs @@ -40,7 +40,7 @@ public static void NullJsonThrows() ArgumentNullException ex = Assert.Throws(() => JsonSerializer.Deserialize(json: (string)null, returnType: typeof(string))); Assert.Contains("json", ex.Message); - ex = Assert.Throws(() => JsonSerializer.DeserializeAsync(utf8Json: null, returnType: null)); + ex = Assert.Throws(() => JsonSerializer.DeserializeAsync(utf8Json: (Stream?)null, returnType: null)); Assert.Contains("utf8Json", ex.Message); } @@ -385,7 +385,7 @@ public class SimpleTypeWithArray [InlineData("true", typeof(bool), true)] [InlineData("false", typeof(bool), false)] [InlineData("\"my string\"", typeof(string), "my string")] - public static void Primitives(string jsonString, Type type, object expected) + public static void Primitives(string jsonString, Type type, object? expected) { byte[] utf8 = Encoding.UTF8.GetBytes(jsonString); @@ -406,7 +406,7 @@ public static void Primitives(string jsonString, Type type, object expected) [InlineData("true", typeof(bool), true)] [InlineData("false", typeof(bool), false)] [InlineData("\"my string\"", typeof(string), "my string")] - public static void PrimitivesMultiSegment(string jsonString, Type type, object expected) + public static void PrimitivesMultiSegment(string jsonString, Type type, object? expected) { byte[] utf8 = Encoding.UTF8.GetBytes(jsonString); ReadOnlySequence sequence = JsonTestHelper.CreateSegments(utf8); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/ReferenceHandlerTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/ReferenceHandlerTests.cs index d793d4cbd47e75..366d9c0d840403 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/ReferenceHandlerTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/ReferenceHandlerTests.cs @@ -34,4 +34,9 @@ public sealed class ReferenceHandlerTestsDynamic_IgnoreCycles_Pipe : ReferenceHa { public ReferenceHandlerTestsDynamic_IgnoreCycles_Pipe() : base(JsonSerializerWrapper.AsyncPipeSerializer) { } } + + public sealed class ReferenceHandlerTestsDynamic_IgnoreCycles_PipeWithSmallBuffer : ReferenceHandlerTests_IgnoreCycles + { + public ReferenceHandlerTestsDynamic_IgnoreCycles_PipeWithSmallBuffer() : base(JsonSerializerWrapper.AsyncPipeSerializerWithSmallBuffer) { } + } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/RequiredKeywordTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/RequiredKeywordTests.cs index 969f5d17c6063c..42dfbe331f8607 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/RequiredKeywordTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/RequiredKeywordTests.cs @@ -57,4 +57,9 @@ public class RequiredKeywordTests_Pipe : RequiredKeywordTests { public RequiredKeywordTests_Pipe() : base(JsonSerializerWrapper.AsyncPipeSerializer) { } } + + public class RequiredKeywordTests_PipeWithSmallBuffer : RequiredKeywordTests + { + public RequiredKeywordTests_PipeWithSmallBuffer() : base(JsonSerializerWrapper.AsyncPipeSerializerWithSmallBuffer) { } + } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.Collections.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.Collections.cs index 8c7639a1bda8e6..350fb234f15ac9 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.Collections.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.Collections.cs @@ -369,11 +369,11 @@ public ImmutableStructWithStrings( [InlineData("}")] [InlineData("[")] [InlineData("]")] - public void DeserializeDictionaryStartsWithInvalidJson(string json) + public async Task DeserializeDictionaryStartsWithInvalidJson(string json) { foreach (Type type in CollectionTestTypes.DictionaryTypes()) { - Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.WriteTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.WriteTests.cs index 22572f9a8fd98a..dc4fb82befbc08 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.WriteTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.WriteTests.cs @@ -131,15 +131,12 @@ private async Task WriteAsync(TestStream stream) // We should have more than one write called due to the large byte count. if (Serializer.IsAsyncSerializer) { - Assert.InRange(stream.TestAsyncWriteCount, 1, int.MaxValue); + Assert.InRange(stream.TestAsyncWriteCount, 2, int.MaxValue); } else { - Assert.InRange(stream.TestWriteCount, 1, int.MaxValue); + Assert.InRange(stream.TestWriteCount, 2, int.MaxValue); } - - // We don't auto-flush. - Assert.Equal(0, stream.TestFlushCount); } private async Task ReadAsync(TestStream stream) @@ -155,7 +152,7 @@ private async Task ReadAsync(TestStream stream) Assert.InRange(stream.TestRequestedReadBytesCount, 551368, int.MaxValue); // We should have more than one read called due to the large byte count. - Assert.InRange(stream.TestReadCount, 1, int.MaxValue); + Assert.InRange(stream.TestReadCount, 2, int.MaxValue); // We don't auto-flush. Assert.Equal(0, stream.TestFlushCount); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/StreamTests.ChunkedReaderStream.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/StreamTests.ChunkedReaderStream.cs index 50919f203c7821..8446561e0c267c 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/StreamTests.ChunkedReaderStream.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/StreamTests.ChunkedReaderStream.cs @@ -54,7 +54,7 @@ public override int Read(byte[] buffer, int offset, int count) int bytesToCopy = Math.Min(count, currentChunk.Length - currentChunkOffset); Buffer.BlockCopy(currentChunk, currentChunkOffset, buffer, offset, bytesToCopy); - if (bytesToCopy < count) + if (bytesToCopy < count || currentChunk.Length - currentChunkOffset == bytesToCopy) { MoveToNextChunk(); } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/StreamTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/StreamTests.cs index 90da21670a23d0..03a44d32b25790 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/StreamTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/StreamTests.cs @@ -18,6 +18,11 @@ public sealed class StreamTests_Sync : StreamTests public StreamTests_Sync() : base(JsonSerializerWrapper.SyncStreamSerializer) { } } + public sealed class PipeTests_Async : StreamTests + { + public PipeTests_Async() : base(JsonSerializerWrapper.AsyncPipeSerializer) { } + } + public abstract partial class StreamTests { /// diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/UnmappedMemberHandlingTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/UnmappedMemberHandlingTests.cs index 5c59342f3c779c..7b3dac7983df19 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/UnmappedMemberHandlingTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/UnmappedMemberHandlingTests.cs @@ -17,4 +17,9 @@ public sealed partial class UnmappedMemberHandlingTests_Pipe : UnmappedMemberHan { public UnmappedMemberHandlingTests_Pipe() : base(JsonSerializerWrapper.AsyncPipeSerializer) { } } + + public sealed partial class UnmappedMemberHandlingTests_PipeWithSmallBuffer : UnmappedMemberHandlingTests + { + public UnmappedMemberHandlingTests_PipeWithSmallBuffer() : base(JsonSerializerWrapper.AsyncPipeSerializerWithSmallBuffer) { } + } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/WriteValueTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/WriteValueTests.cs index 4ef060d1658286..78828487f3457c 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/WriteValueTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/WriteValueTests.cs @@ -3,6 +3,7 @@ using System.IO; using System.Text.Encodings.Web; +using System.Threading.Tasks; using Xunit; namespace System.Text.Json.Serialization.Tests @@ -22,7 +23,7 @@ public static void NullWriterThrows() } [Fact] - public async static void NullInputTypeThrows() + public async static Task NullInputTypeThrows() { ArgumentException ex; Utf8JsonWriter writer = new Utf8JsonWriter(new MemoryStream()); @@ -44,7 +45,7 @@ public async static void NullInputTypeThrows() } [Fact] - public async static void NullValueWithValueTypeThrows() + public async static Task NullValueWithValueTypeThrows() { JsonException ex; @@ -63,7 +64,7 @@ public async static void NullValueWithValueTypeThrows() } [Fact] - public async static void NullValueWithNullableSuccess() + public async static Task NullValueWithNullableSuccess() { byte[] nullUtf8Literal = "null"u8.ToArray(); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj index c2017a91ef1316..f69d73da47c723 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);$(NetFrameworkCurrent) @@ -36,6 +36,7 @@ + @@ -77,6 +78,7 @@ + @@ -143,6 +145,7 @@ + @@ -180,7 +183,9 @@ + + @@ -225,7 +230,6 @@ - @@ -272,7 +276,7 @@ - + diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonReaderTests.TryGet.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonReaderTests.TryGet.cs index b4ea57a41297c5..6195032db8082b 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonReaderTests.TryGet.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonReaderTests.TryGet.cs @@ -1005,7 +1005,7 @@ public static void InvalidConversion() [InlineData("[\"\\u0030\\u0031\\u0032\\u0033\\u0034\\u0035\", \"\\u0000\\u002B\", \"a\\u005C\\u0072b\", \"a\\\\u005C\\u0072b\", \"a\\u008E\\u008Fb\", \"a\\uD803\\uDE6Db\", \"a\\uD834\\uDD1Eb\", \"a\\\\uD834\\\\uDD1Eb\"]")] [InlineData("{\"message\":\"Hello /a/b/c \\/ \\r\\b\\n\\f\\t\\/\"}")] [InlineData(null)] // Large randomly generated string - public static void TestingGetString(string jsonString) + public static void TestingGetString(string? jsonString) { if (jsonString == null) { diff --git a/src/libraries/System.Text.RegularExpressions/System.Text.RegularExpressions.slnx b/src/libraries/System.Text.RegularExpressions/System.Text.RegularExpressions.slnx index 74c6f8e3f5f17c..caf98d67833730 100644 --- a/src/libraries/System.Text.RegularExpressions/System.Text.RegularExpressions.slnx +++ b/src/libraries/System.Text.RegularExpressions/System.Text.RegularExpressions.slnx @@ -84,6 +84,14 @@ + + + + + + + + @@ -92,6 +100,14 @@ + + + + + + + + @@ -108,6 +124,14 @@ + + + + + + + + @@ -124,6 +148,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -132,6 +180,14 @@ + + + + + + + + @@ -140,6 +196,22 @@ + + + + + + + + + + + + + + + + @@ -156,6 +228,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -172,6 +268,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -188,6 +308,22 @@ + + + + + + + + + + + + + + + + @@ -204,6 +340,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -237,6 +397,14 @@ + + + + + + + + @@ -245,6 +413,14 @@ + + + + + + + + @@ -261,6 +437,22 @@ + + + + + + + + + + + + + + + + @@ -269,6 +461,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -277,6 +493,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -285,6 +533,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -301,6 +621,22 @@ + + + + + + + + + + + + + + + + @@ -317,6 +653,22 @@ + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs index 931b7976199f31..455d79571799e9 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs +++ b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs @@ -302,42 +302,104 @@ private static string GetTimeoutExpression(int matchTimeout) => "Regex.InfiniteMatchTimeout" : $"TimeSpan.FromMilliseconds({matchTimeout.ToString(CultureInfo.InvariantCulture)})"; + private const string IsBoundary = nameof(IsBoundary); + private const string IsECMABoundary = nameof(IsECMABoundary); + private const string IsWordChar = nameof(IsWordChar); + private const string IsBoundaryWordChar = nameof(IsBoundaryWordChar); + private const string IsPostWordCharBoundary = nameof(IsPostWordCharBoundary); + private const string IsPreWordCharBoundary = nameof(IsPreWordCharBoundary); + private const string IsECMABoundaryWordChar = nameof(IsECMABoundaryWordChar); + private const string WordCategoriesMask = nameof(WordCategoriesMask); + private const string WordCharBitmap = nameof(WordCharBitmap); + + private static void AddWordCharHelpersSupport(Dictionary requiredHelpers) + { + const string WordCharHelpersSupport = nameof(WordCharHelpersSupport); + if (!requiredHelpers.ContainsKey(WordCharHelpersSupport)) + { + requiredHelpers.Add(WordCharHelpersSupport, + [ + "/// Provides a mask of Unicode categories that combine to form [\\w].", + $"private const int {WordCategoriesMask} =", + " 1 << (int)UnicodeCategory.UppercaseLetter |", + " 1 << (int)UnicodeCategory.LowercaseLetter |", + " 1 << (int)UnicodeCategory.TitlecaseLetter |", + " 1 << (int)UnicodeCategory.ModifierLetter |", + " 1 << (int)UnicodeCategory.OtherLetter |", + " 1 << (int)UnicodeCategory.NonSpacingMark |", + " 1 << (int)UnicodeCategory.DecimalDigitNumber |", + " 1 << (int)UnicodeCategory.ConnectorPunctuation;", + "", + "/// Gets a bitmap for whether each character 0 through 127 is in [\\w]", + $"private static ReadOnlySpan {WordCharBitmap} => new byte[]", + "{", + " 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03,", + " 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x07", + "};", + ]); + } + } + /// Adds the IsWordChar helper to the required helpers collection. private static void AddIsWordCharHelper(Dictionary requiredHelpers) { - const string IsWordChar = nameof(IsWordChar); if (!requiredHelpers.ContainsKey(IsWordChar)) { requiredHelpers.Add(IsWordChar, [ - "/// Determines whether the character is part of the [\\w] set.", - "[MethodImpl(MethodImplOptions.AggressiveInlining)]", - "internal static bool IsWordChar(char ch)", - "{", - " // Mask of Unicode categories that combine to form [\\w]", - " const int WordCategoriesMask =", - " 1 << (int)UnicodeCategory.UppercaseLetter |", - " 1 << (int)UnicodeCategory.LowercaseLetter |", - " 1 << (int)UnicodeCategory.TitlecaseLetter |", - " 1 << (int)UnicodeCategory.ModifierLetter |", - " 1 << (int)UnicodeCategory.OtherLetter |", - " 1 << (int)UnicodeCategory.NonSpacingMark |", - " 1 << (int)UnicodeCategory.DecimalDigitNumber |", - " 1 << (int)UnicodeCategory.ConnectorPunctuation;", - "", - " // Bitmap for whether each character 0 through 127 is in [\\w]", - " ReadOnlySpan ascii = new byte[]", - " {", - " 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03,", - " 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x07", - " };", - "", - " // If the char is ASCII, look it up in the bitmap. Otherwise, query its Unicode category.", - " int chDiv8 = ch >> 3;", - " return (uint)chDiv8 < (uint)ascii.Length ?", - " (ascii[chDiv8] & (1 << (ch & 0x7))) != 0 :", - " (WordCategoriesMask & (1 << (int)CharUnicodeInfo.GetUnicodeCategory(ch))) != 0;", - "}", + $"/// Determines whether the character is part of the [\\w] set.", + $"[MethodImpl(MethodImplOptions.AggressiveInlining)]", + $"internal static bool {IsWordChar}(char ch)", + $"{{", + $" // If the char is ASCII, look it up in the bitmap. Otherwise, query its Unicode category.", + $" ReadOnlySpan ascii = {WordCharBitmap};", + $" int chDiv8 = ch >> 3;", + $" return (uint)chDiv8 < (uint)ascii.Length ?", + $" (ascii[chDiv8] & (1 << (ch & 0x7))) != 0 :", + $" ({WordCategoriesMask} & (1 << (int)CharUnicodeInfo.GetUnicodeCategory(ch))) != 0;", + $"}}", + ]); + + AddWordCharHelpersSupport(requiredHelpers); + } + } + + /// Adds the IsBoundary helper to the required helpers collection. + private static void AddIsBoundaryWordCharHelper(Dictionary requiredHelpers) + { + if (!requiredHelpers.ContainsKey(IsBoundaryWordChar)) + { + requiredHelpers.Add(IsBoundaryWordChar, + [ + $"/// Determines whether the specified index is a boundary word character.", + $"/// This is the same as \\w plus U+200C ZERO WIDTH NON-JOINER and U+200D ZERO WIDTH JOINER.", + $"[MethodImpl(MethodImplOptions.AggressiveInlining)]", + $"internal static bool {IsBoundaryWordChar}(char ch)", + $"{{", + $" ReadOnlySpan ascii = {WordCharBitmap};", + $" int chDiv8 = ch >> 3;", + $" return (uint)chDiv8 < (uint)ascii.Length ?", + $" (ascii[chDiv8] & (1 << (ch & 0x7))) != 0 :", + $" (({WordCategoriesMask} & (1 << (int)CharUnicodeInfo.GetUnicodeCategory(ch))) != 0) || (ch is '\u200C' or '\u200D');", + $"}}", + ]); + + AddWordCharHelpersSupport(requiredHelpers); + } + } + + /// Adds the IsECMABoundary helper to the required helpers collection. + private static void AddIsECMABoundaryWordCharHelper(Dictionary requiredHelpers) + { + if (!requiredHelpers.ContainsKey(IsECMABoundaryWordChar)) + { + requiredHelpers.Add(IsECMABoundaryWordChar, + [ + $"/// Determines whether the specified index is a boundary (ECMAScript) word character.", + $"[MethodImpl(MethodImplOptions.AggressiveInlining)]", + $"internal static bool {IsECMABoundaryWordChar}(char ch) =>", + $" char.IsAsciiLetterOrDigit(ch) ||", + $" ch is '_' or '\\u0130'; // latin capital letter I with dot above", ]); } } @@ -345,7 +407,6 @@ private static void AddIsWordCharHelper(Dictionary requiredHel /// Adds the IsBoundary helper to the required helpers collection. private static void AddIsBoundaryHelper(Dictionary requiredHelpers, bool checkOverflow) { - const string IsBoundary = nameof(IsBoundary); if (!requiredHelpers.ContainsKey(IsBoundary)) { string uncheckedKeyword = checkOverflow ? "unchecked" : ""; @@ -353,24 +414,62 @@ private static void AddIsBoundaryHelper(Dictionary requiredHel [ $"/// Determines whether the specified index is a boundary.", $"[MethodImpl(MethodImplOptions.AggressiveInlining)]", - $"internal static bool IsBoundary(ReadOnlySpan inputSpan, int index)", + $"internal static bool {IsBoundary}(ReadOnlySpan inputSpan, int index)", + $"{{", + $" int indexMinus1 = index - 1;", + $" return {uncheckedKeyword}((uint)indexMinus1 < (uint)inputSpan.Length && {IsBoundaryWordChar}(inputSpan[indexMinus1])) !=", + $" {uncheckedKeyword}((uint)index < (uint)inputSpan.Length && {IsBoundaryWordChar}(inputSpan[index]));", + $"}}", + ]); + + AddIsBoundaryWordCharHelper(requiredHelpers); + } + } + + /// Adds the IsPreWordCharBoundary helper to the required helpers collection. + private static void AddIsPreWordCharBoundaryHelper(Dictionary requiredHelpers, bool checkOverflow) + { + if (!requiredHelpers.ContainsKey(IsPreWordCharBoundary)) + { + string uncheckedKeyword = checkOverflow ? "unchecked" : ""; + requiredHelpers.Add(IsPreWordCharBoundary, + [ + $"/// Determines whether the specified index is a boundary.", + $"/// This variant is only employed when the subsequent character will separately be validated as a word character.", + $"[MethodImpl(MethodImplOptions.AggressiveInlining)]", + $"internal static bool {IsPreWordCharBoundary}(ReadOnlySpan inputSpan, int index)", $"{{", $" int indexMinus1 = index - 1;", - $" return {uncheckedKeyword}((uint)indexMinus1 < (uint)inputSpan.Length && IsBoundaryWordChar(inputSpan[indexMinus1])) !=", - $" {uncheckedKeyword}((uint)index < (uint)inputSpan.Length && IsBoundaryWordChar(inputSpan[index]));", - $"", - $" static bool IsBoundaryWordChar(char ch) => IsWordChar(ch) || (ch == '\\u200C' | ch == '\\u200D');", + $" return {uncheckedKeyword}((uint)indexMinus1 >= (uint)inputSpan.Length || !{IsBoundaryWordChar}(inputSpan[indexMinus1]));", $"}}", ]); - AddIsWordCharHelper(requiredHelpers); + AddIsBoundaryWordCharHelper(requiredHelpers); + } + } + + /// Adds the IsPostWordCharBoundary helper to the required helpers collection. + private static void AddIsPostWordCharBoundaryHelper(Dictionary requiredHelpers, bool checkOverflow) + { + if (!requiredHelpers.ContainsKey(IsPostWordCharBoundary)) + { + string uncheckedKeyword = checkOverflow ? "unchecked" : ""; + requiredHelpers.Add(IsPostWordCharBoundary, + [ + $"/// Determines whether the specified index is a boundary.", + $"/// This variant is only employed when the previous character has already been validated as a word character.", + $"[MethodImpl(MethodImplOptions.AggressiveInlining)]", + $"internal static bool {IsPostWordCharBoundary}(ReadOnlySpan inputSpan, int index) =>", + $" {uncheckedKeyword}((uint)index >= (uint)inputSpan.Length || !{IsBoundaryWordChar}(inputSpan[index]));", + ]); + + AddIsBoundaryWordCharHelper(requiredHelpers); } } /// Adds the IsECMABoundary helper to the required helpers collection. private static void AddIsECMABoundaryHelper(Dictionary requiredHelpers, bool checkOverflow) { - const string IsECMABoundary = nameof(IsECMABoundary); if (!requiredHelpers.ContainsKey(IsECMABoundary)) { string uncheckedKeyword = checkOverflow ? "unchecked" : ""; @@ -378,18 +477,15 @@ private static void AddIsECMABoundaryHelper(Dictionary require [ $"/// Determines whether the specified index is a boundary (ECMAScript).", $"[MethodImpl(MethodImplOptions.AggressiveInlining)]", - $"internal static bool IsECMABoundary(ReadOnlySpan inputSpan, int index)", + $"internal static bool {IsECMABoundary}(ReadOnlySpan inputSpan, int index)", $"{{", $" int indexMinus1 = index - 1;", - $" return {uncheckedKeyword}((uint)indexMinus1 < (uint)inputSpan.Length && IsECMAWordChar(inputSpan[indexMinus1])) !=", - $" {uncheckedKeyword}((uint)index < (uint)inputSpan.Length && IsECMAWordChar(inputSpan[index]));", - $"", - $" static bool IsECMAWordChar(char ch) =>", - $" char.IsAsciiLetterOrDigit(ch) ||", - $" ch == '_' ||", - $" ch == '\\u0130'; // latin capital letter I with dot above", + $" return {uncheckedKeyword}((uint)indexMinus1 < (uint)inputSpan.Length && {IsECMABoundaryWordChar}(inputSpan[indexMinus1])) !=", + $" {uncheckedKeyword}((uint)index < (uint)inputSpan.Length && {IsECMABoundaryWordChar}(inputSpan[index]));", $"}}", ]); + + AddIsECMABoundaryWordCharHelper(requiredHelpers); } } @@ -403,13 +499,15 @@ private static string EmitSearchValuesOrLiteral(ReadOnlySpan chars, Dictio // - There are only 4 or 5 characters in the needle and they're all ASCII. return chars.Length > 5 || RegexCharClass.IsAscii(chars) - ? EmitSearchValues(chars.ToArray(), requiredHelpers) + ? EmitSearchValues(chars, requiredHelpers) : Literal(chars.ToString()); } /// Adds a SearchValues instance declaration to the required helpers collection. - private static string EmitSearchValues(char[] chars, Dictionary requiredHelpers, string? fieldName = null) + private static string EmitSearchValues(ReadOnlySpan charsSpan, Dictionary requiredHelpers, string? fieldName = null) { + char[] chars = charsSpan.ToArray(); + Array.Sort(chars); if (fieldName is null) @@ -3175,20 +3273,33 @@ void EmitBoundary(RegexNode node) { Debug.Assert(node.Kind is RegexNodeKind.Boundary or RegexNodeKind.NonBoundary or RegexNodeKind.ECMABoundary or RegexNodeKind.NonECMABoundary, $"Unexpected kind: {node.Kind}"); + string negation = node.Kind is RegexNodeKind.Boundary or RegexNodeKind.ECMABoundary ? "!" : ""; + string call; - if (node.Kind is RegexNodeKind.Boundary or RegexNodeKind.NonBoundary) - { - call = node.Kind is RegexNodeKind.Boundary ? - $"!{HelpersTypeName}.IsBoundary" : - $"{HelpersTypeName}.IsBoundary"; - AddIsBoundaryHelper(requiredHelpers, checkOverflow); - } - else + switch (node.Kind) { - call = node.Kind is RegexNodeKind.ECMABoundary ? - $"!{HelpersTypeName}.IsECMABoundary" : - $"{HelpersTypeName}.IsECMABoundary"; - AddIsECMABoundaryHelper(requiredHelpers, checkOverflow); + case RegexNodeKind.Boundary or RegexNodeKind.NonBoundary: + if (node.IsKnownPrecededByWordChar()) + { + call = $"{negation}{HelpersTypeName}.{IsPostWordCharBoundary}"; + AddIsPostWordCharBoundaryHelper(requiredHelpers, checkOverflow); + } + else if (node.IsKnownSucceededByWordChar()) + { + call = $"{negation}{HelpersTypeName}.{IsPreWordCharBoundary}"; + AddIsPreWordCharBoundaryHelper(requiredHelpers, checkOverflow); + } + else + { + call = $"{negation}{HelpersTypeName}.{IsBoundary}"; + AddIsBoundaryHelper(requiredHelpers, checkOverflow); + } + break; + + default: + call = $"{negation}{HelpersTypeName}.{IsECMABoundary}"; + AddIsECMABoundaryHelper(requiredHelpers, checkOverflow); + break; } using (EmitBlock(writer, $"if ({call}(inputSpan, pos{(sliceStaticPos > 0 ? $" + {sliceStaticPos}" : "")}))")) @@ -3719,15 +3830,6 @@ void EmitLazy(RegexNode node) return; } - // We should only be here if the lazy loop isn't atomic due to an ancestor, as the optimizer should - // in such a case have lowered the loop's upper bound to its lower bound, at which point it would - // have been handled by the above delegation to EmitLoop. However, if the optimizer missed doing so, - // this loop could still be considered atomic by ancestor by its parent nodes, in which case we want - // to make sure the code emitted here conforms (e.g. doesn't leave any state erroneously on the stack). - // So, we assert it's not atomic, but still handle that case. - bool isAtomic = rm.Analysis.IsAtomicByAncestor(node); - Debug.Assert(!isAtomic, "An atomic lazy should have had its upper bound lowered to its lower bound."); - // We might loop any number of times. In order to ensure this loop and subsequent code sees sliceStaticPos // the same regardless, we always need it to contain the same value, and the easiest such value is 0. // So, we transfer sliceStaticPos to pos, and ensure that any path out of here has sliceStaticPos as 0. @@ -3750,7 +3852,8 @@ void EmitLazy(RegexNode node) { startingPos = ReserveName("lazyloop_starting_pos"); sawEmpty = ReserveName("lazyloop_empty_seen"); - writer.WriteLine($"int {startingPos} = pos, {sawEmpty} = 0; // the lazy loop may match empty iterations"); + additionalDeclarations.Add($"int {startingPos} = 0, {sawEmpty} = 0;"); + writer.WriteLine($"{startingPos} = {sawEmpty} = 0; // the lazy loop may match empty iterations"); } // If the min count is 0, start out by jumping right to what's after the loop. Backtracking @@ -3762,247 +3865,245 @@ void EmitLazy(RegexNode node) writer.WriteLine(); // Iteration body - MarkLabel(body, emitSemicolon: isAtomic); + MarkLabel(body, emitSemicolon: false); // In case iterations are backtracked through and unwound, we need to store the current position (so that // matching can resume from that location), the current crawl position if captures are possible (so that // we can uncapture back to that position), and both the starting position from the iteration we're leaving // and whether we've seen an empty iteration (if iterations may be empty). Since there can be multiple // iterations, this state needs to be stored on to the backtracking stack. - if (!isAtomic) + + int stackCookie = CreateStackCookie(); + int entriesPerIteration = + 1/*pos*/ + + (iterationMayBeEmpty ? 2/*startingPos+sawEmpty*/ : 0) + + (expressionHasCaptures ? 1/*Crawlpos*/ : 0) + + (stackCookie != 0 ? 1 : 0); + EmitStackPush(stackCookie, + expressionHasCaptures && iterationMayBeEmpty ? ["pos", startingPos!, sawEmpty!, "base.Crawlpos()"] : + iterationMayBeEmpty ? ["pos", startingPos!, sawEmpty!] : + expressionHasCaptures ? ["pos", "base.Crawlpos()"] : + ["pos"]); + + if (iterationMayBeEmpty) { - int stackCookie = CreateStackCookie(); - int entriesPerIteration = - 1/*pos*/ + - (iterationMayBeEmpty ? 2/*startingPos+sawEmpty*/ : 0) + - (expressionHasCaptures ? 1/*Crawlpos*/ : 0) + - (stackCookie != 0 ? 1 : 0); - EmitStackPush(stackCookie, - expressionHasCaptures && iterationMayBeEmpty ? ["pos", startingPos!, sawEmpty!, "base.Crawlpos()"] : - iterationMayBeEmpty ? ["pos", startingPos!, sawEmpty!] : - expressionHasCaptures ? ["pos", "base.Crawlpos()"] : - ["pos"]); + // We need to store the current pos so we can compare it against pos after the iteration, in order to + // determine whether the iteration was empty. + writer.WriteLine($"{startingPos} = pos;"); + } - if (iterationMayBeEmpty) - { - // We need to store the current pos so we can compare it against pos after the iteration, in order to - // determine whether the iteration was empty. - writer.WriteLine($"{startingPos} = pos;"); - } + // Proactively increase the number of iterations. We do this prior to the match rather than once + // we know it's successful, because we need to decrement it as part of a failed match when + // backtracking; it's thus simpler to just always decrement it as part of a failed match, even + // when initially greedily matching the loop, which then requires we increment it before trying. + writer.WriteLine($"{iterationCount}++;"); - // Proactively increase the number of iterations. We do this prior to the match rather than once - // we know it's successful, because we need to decrement it as part of a failed match when - // backtracking; it's thus simpler to just always decrement it as part of a failed match, even - // when initially greedily matching the loop, which then requires we increment it before trying. - writer.WriteLine($"{iterationCount}++;"); + // Last but not least, we need to set the doneLabel that a failed match of the body will jump to. + // Such an iteration match failure may or may not fail the whole operation, depending on whether + // we've already matched the minimum required iterations, so we need to jump to a location that + // will make that determination. + string iterationFailedLabel = ReserveName("LazyLoopIterationNoMatch"); + doneLabel = iterationFailedLabel; - // Last but not least, we need to set the doneLabel that a failed match of the body will jump to. - // Such an iteration match failure may or may not fail the whole operation, depending on whether - // we've already matched the minimum required iterations, so we need to jump to a location that - // will make that determination. - string iterationFailedLabel = ReserveName("LazyLoopIterationNoMatch"); - doneLabel = iterationFailedLabel; + // Finally, emit the child. + Debug.Assert(sliceStaticPos == 0); + writer.WriteLine(); + EmitNode(child); + writer.WriteLine(); + TransferSliceStaticPosToPos(); // ensure sliceStaticPos remains 0 + if (doneLabel == iterationFailedLabel) + { + doneLabel = originalDoneLabel; + } - // Finally, emit the child. - Debug.Assert(sliceStaticPos == 0); - writer.WriteLine(); - EmitNode(child); - writer.WriteLine(); - TransferSliceStaticPosToPos(); // ensure sliceStaticPos remains 0 - if (doneLabel == iterationFailedLabel) + // Loop condition. Continue iterating if we've not yet reached the minimum. We just successfully + // matched an iteration, so the only reason we'd need to forcefully loop around again is if the + // minimum were at least 2. + if (minIterations >= 2) + { + writer.WriteLine($"// The lazy loop requires a minimum of {minIterations} iterations. If that many haven't yet matched, loop now."); + using (EmitBlock(writer, $"if ({CountIsLessThan(iterationCount, minIterations)})")) { - doneLabel = originalDoneLabel; + Goto(body); } + } - // Loop condition. Continue iterating if we've not yet reached the minimum. We just successfully - // matched an iteration, so the only reason we'd need to forcefully loop around again is if the - // minimum were at least 2. - if (minIterations >= 2) + if (iterationMayBeEmpty) + { + // If the last iteration was empty, we need to prevent further iteration from this point + // unless we backtrack out of this iteration. + writer.WriteLine("// If the iteration successfully matched zero-length input, record that an empty iteration was seen."); + using (EmitBlock(writer, $"if (pos == {startingPos})")) { - writer.WriteLine($"// The lazy loop requires a minimum of {minIterations} iterations. If that many haven't yet matched, loop now."); - using (EmitBlock(writer, $"if ({CountIsLessThan(iterationCount, minIterations)})")) - { - Goto(body); - } + writer.WriteLine($"{sawEmpty} = 1; // true"); } + writer.WriteLine(); + } - if (iterationMayBeEmpty) + // We matched the next iteration. Jump to the subsequent code. + Goto(endLoop); + writer.WriteLine(); + + // Now handle what happens when an iteration fails (and since a lazy loop only executes an iteration + // when it's required to satisfy the loop by definition of being lazy, the loop is failing). We need + // to reset state to what it was before just that iteration started. That includes resetting pos and + // clearing out any captures from that iteration. + writer.WriteLine("// The lazy loop iteration failed to match."); + MarkLabel(iterationFailedLabel, emitSemicolon: false); + if (doneLabel != originalDoneLabel || !GotoWillExitMatch(originalDoneLabel)) // we don't need to back anything out if we're about to exit TryMatchAtCurrentPosition anyway. + { + // Fail this loop iteration, including popping state off the backtracking stack that was pushed + // on as part of the failing iteration. + writer.WriteLine($"{iterationCount}--;"); + if (expressionHasCaptures) { - // If the last iteration was empty, we need to prevent further iteration from this point - // unless we backtrack out of this iteration. - writer.WriteLine("// If the iteration successfully matched zero-length input, record that an empty iteration was seen."); - using (EmitBlock(writer, $"if (pos == {startingPos})")) - { - writer.WriteLine($"{sawEmpty} = 1; // true"); - } - writer.WriteLine(); + EmitUncaptureUntil(StackPop()); } + EmitStackPop(stackCookie, iterationMayBeEmpty ? + [sawEmpty!, startingPos!, "pos"] : + ["pos"]); + SliceInputSpan(); - // We matched the next iteration. Jump to the subsequent code. - Goto(endLoop); - writer.WriteLine(); - - // Now handle what happens when an iteration fails (and since a lazy loop only executes an iteration - // when it's required to satisfy the loop by definition of being lazy, the loop is failing). We need - // to reset state to what it was before just that iteration started. That includes resetting pos and - // clearing out any captures from that iteration. - writer.WriteLine("// The lazy loop iteration failed to match."); - MarkLabel(iterationFailedLabel, emitSemicolon: false); - if (doneLabel != originalDoneLabel || !GotoWillExitMatch(originalDoneLabel)) // we don't need to back anything out if we're about to exit TryMatchAtCurrentPosition anyway. + // If the loop's child doesn't backtrack, then this loop has failed. + // If the loop's child does backtrack, we need to backtrack back into the previous iteration if there was one. + if (doneLabel == originalDoneLabel) { - // Fail this loop iteration, including popping state off the backtracking stack that was pushed - // on as part of the failing iteration. - writer.WriteLine($"{iterationCount}--;"); - if (expressionHasCaptures) - { - EmitUncaptureUntil(StackPop()); - } - EmitStackPop(stackCookie, iterationMayBeEmpty ? - [sawEmpty!, startingPos!, "pos"] : - ["pos"]); - SliceInputSpan(); - - // If the loop's child doesn't backtrack, then this loop has failed. - // If the loop's child does backtrack, we need to backtrack back into the previous iteration if there was one. - if (doneLabel == originalDoneLabel) - { - // Since the only reason we'd end up revisiting previous iterations of the lazy loop is if the child had backtracking constructs - // we'd backtrack into, and the child doesn't, the whole loop is failed and done. If we successfully processed any iterations, - // we thus need to pop all of the state we pushed onto the stack for those iterations, as we're exiting out to the parent who - // will expect the stack to be cleared of any child state. - Debug.Assert(entriesPerIteration >= 1); - writer.WriteLine(entriesPerIteration > 1 ? - $"stackpos -= {iterationCount} * {entriesPerIteration};" : - $"stackpos -= {iterationCount};"); - } - else + // Since the only reason we'd end up revisiting previous iterations of the lazy loop is if the child had backtracking constructs + // we'd backtrack into, and the child doesn't, the whole loop is failed and done. If we successfully processed any iterations, + // we thus need to pop all of the state we pushed onto the stack for those iterations, as we're exiting out to the parent who + // will expect the stack to be cleared of any child state. + Debug.Assert(entriesPerIteration >= 1); + writer.WriteLine(entriesPerIteration > 1 ? + $"stackpos -= {iterationCount} * {entriesPerIteration};" : + $"stackpos -= {iterationCount};"); + } + else + { + // The child has backtracking constructs. If we have no successful iterations previously processed, just bail. + // If we do have successful iterations previously processed, however, we need to backtrack back into the last one. + using (EmitBlock(writer, $"if ({iterationCount} > 0)")) { - // The child has backtracking constructs. If we have no successful iterations previously processed, just bail. - // If we do have successful iterations previously processed, however, we need to backtrack back into the last one. - using (EmitBlock(writer, $"if ({iterationCount} > 0)")) + writer.WriteLine($"// The lazy loop matched at least one iteration; backtrack into the last one."); + if (iterationMayBeEmpty) { - writer.WriteLine($"// The lazy loop matched at least one iteration; backtrack into the last one."); - if (iterationMayBeEmpty) - { - // If we saw empty, it must have been in the most recent iteration, as we wouldn't have - // allowed additional iterations after one that was empty. Thus, we reset it back to - // false prior to backtracking / undoing that iteration. - writer.WriteLine($"{sawEmpty} = 0; // false"); - } - Goto(doneLabel); + // If we saw empty, it must have been in the most recent iteration, as we wouldn't have + // allowed additional iterations after one that was empty. Thus, we reset it back to + // false prior to backtracking / undoing that iteration. + writer.WriteLine($"{sawEmpty} = 0; // false"); } - writer.WriteLine(); + Goto(doneLabel); } + writer.WriteLine(); } - Goto(originalDoneLabel); - writer.WriteLine(); + } + Goto(originalDoneLabel); + writer.WriteLine(); - MarkLabel(endLoop, emitSemicolon: false); - - // If the lazy loop is not atomic, then subsequent code may backtrack back into this lazy loop, either - // causing it to add additional iterations, or backtracking into existing iterations and potentially - // unwinding them. We need to do a timeout check, and then determine whether to branch back to add more - // iterations (if we haven't hit the loop's maximum iteration count and haven't seen an empty iteration) - // or unwind by branching back to the last backtracking location. Either way, we need a dedicated - // backtracking section that a subsequent construct will see as its backtracking target. - - // We need to ensure that some state (e.g. iteration count) is persisted if we're backtracked to. - // We also need to push the current position, so that subsequent iterations pick up at the right - // point (and subsequent expressions are almost certain to have changed the current pos). However, - // if we're not inside of a loop, the other local's used for this construct are sufficient, as nothing - // else will overwrite them between now and when backtracking occurs. If, however, we are inside - // of another loop, then any number of iterations might have such state that needs to be stored, - // and thus it needs to be pushed on to the backtracking stack. - bool isInLoop = rm.Analysis.IsInLoop(node); - stackCookie = CreateStackCookie(); - EmitStackPush(stackCookie, - !isInLoop ? (expressionHasCaptures ? ["pos", "base.Crawlpos()"] : ["pos"]) : - iterationMayBeEmpty ? (expressionHasCaptures ? ["pos", iterationCount, startingPos!, sawEmpty!, "base.Crawlpos()"] : ["pos", iterationCount, startingPos!, sawEmpty!]) : - expressionHasCaptures ? ["pos", iterationCount, "base.Crawlpos()"] : - ["pos", iterationCount]); + MarkLabel(endLoop, emitSemicolon: false); - string skipBacktrack = ReserveName("LazyLoopSkipBacktrack"); - Goto(skipBacktrack); - writer.WriteLine(); + // If the lazy loop is not atomic, then subsequent code may backtrack back into this lazy loop, either + // causing it to add additional iterations, or backtracking into existing iterations and potentially + // unwinding them. We need to do a timeout check, and then determine whether to branch back to add more + // iterations (if we haven't hit the loop's maximum iteration count and haven't seen an empty iteration) + // or unwind by branching back to the last backtracking location. Either way, we need a dedicated + // backtracking section that a subsequent construct will see as its backtracking target. + + // We need to ensure that some state (e.g. iteration count) is persisted if we're backtracked to. + // We also need to push the current position, so that subsequent iterations pick up at the right + // point (and subsequent expressions are almost certain to have changed the current pos). However, + // if we're not inside of a loop, the other local's used for this construct are sufficient, as nothing + // else will overwrite them between now and when backtracking occurs. If, however, we are inside + // of another loop, then any number of iterations might have such state that needs to be stored, + // and thus it needs to be pushed on to the backtracking stack. + bool isInLoop = rm.Analysis.IsInLoop(node); + stackCookie = CreateStackCookie(); + EmitStackPush(stackCookie, + !isInLoop ? (expressionHasCaptures ? ["pos", "base.Crawlpos()"] : ["pos"]) : + iterationMayBeEmpty ? (expressionHasCaptures ? ["pos", iterationCount, startingPos!, sawEmpty!, "base.Crawlpos()"] : ["pos", iterationCount, startingPos!, sawEmpty!]) : + expressionHasCaptures ? ["pos", iterationCount, "base.Crawlpos()"] : + ["pos", iterationCount]); - // Emit a backtracking section that checks the timeout, restores the loop's state, and jumps to - // the appropriate label. - string backtrack = ReserveName($"LazyLoopBacktrack"); - MarkLabel(backtrack, emitSemicolon: false); + string skipBacktrack = ReserveName("LazyLoopSkipBacktrack"); + Goto(skipBacktrack); + writer.WriteLine(); - // We're backtracking. Check the timeout. - EmitTimeoutCheckIfNeeded(writer, rm); + // Emit a backtracking section that checks the timeout, restores the loop's state, and jumps to + // the appropriate label. + string backtrack = ReserveName($"LazyLoopBacktrack"); + MarkLabel(backtrack, emitSemicolon: false); - if (expressionHasCaptures) + // We're backtracking. Check the timeout. + EmitTimeoutCheckIfNeeded(writer, rm); + + if (expressionHasCaptures) + { + EmitUncaptureUntil(StackPop()); + } + EmitStackPop(stackCookie, + !isInLoop ? ["pos"] : + iterationMayBeEmpty ? [sawEmpty!, startingPos!, iterationCount, "pos"] : + [iterationCount, "pos"]); + SliceInputSpan(); + + // Determine where to branch, either back to the lazy loop body to add an additional iteration, + // or to the last backtracking label. + if (maxIterations != int.MaxValue || iterationMayBeEmpty) + { + FinishEmitBlock clause; + + writer.WriteLine(); + if (maxIterations == int.MaxValue) { - EmitUncaptureUntil(StackPop()); + // If the last iteration matched empty, backtrack. + writer.WriteLine("// If the last iteration matched empty, don't continue lazily iterating. Instead, backtrack."); + clause = EmitBlock(writer, $"if ({sawEmpty} != 0)"); } - EmitStackPop(stackCookie, - !isInLoop ? ["pos"] : - iterationMayBeEmpty ? [sawEmpty!, startingPos!, iterationCount, "pos"] : - [iterationCount, "pos"]); - SliceInputSpan(); - - // Determine where to branch, either back to the lazy loop body to add an additional iteration, - // or to the last backtracking label. - if (maxIterations != int.MaxValue || iterationMayBeEmpty) + else if (iterationMayBeEmpty) + { + // If the last iteration matched empty or if we've reached our upper bound, backtrack. + writer.WriteLine($"// If the upper bound {maxIterations} has already been reached, or if the last"); + writer.WriteLine($"// iteration matched empty, don't continue lazily iterating. Instead, backtrack."); + clause = EmitBlock(writer, $"if ({CountIsGreaterThanOrEqualTo(iterationCount, maxIterations)} || {sawEmpty} != 0)"); + } + else { - FinishEmitBlock clause; + // If we've reached our upper bound, backtrack. + writer.WriteLine($"// If the upper bound {maxIterations} has already been reached,"); + writer.WriteLine($"// don't continue lazily iterating. Instead, backtrack."); + clause = EmitBlock(writer, $"if ({CountIsGreaterThanOrEqualTo(iterationCount, maxIterations)})"); + } - writer.WriteLine(); - if (maxIterations == int.MaxValue) - { - // If the last iteration matched empty, backtrack. - writer.WriteLine("// If the last iteration matched empty, don't continue lazily iterating. Instead, backtrack."); - clause = EmitBlock(writer, $"if ({sawEmpty} != 0)"); - } - else if (iterationMayBeEmpty) - { - // If the last iteration matched empty or if we've reached our upper bound, backtrack. - writer.WriteLine($"// If the upper bound {maxIterations} has already been reached, or if the last"); - writer.WriteLine($"// iteration matched empty, don't continue lazily iterating. Instead, backtrack."); - clause = EmitBlock(writer, $"if ({CountIsGreaterThanOrEqualTo(iterationCount, maxIterations)} || {sawEmpty} != 0)"); - } - else + using (clause) + { + // We're backtracking, which could either be to something prior to the lazy loop or to something + // inside of the lazy loop. If it's to something inside of the lazy loop, then either the loop + // will eventually succeed or we'll eventually end up unwinding back through the iterations all + // the way back to the loop not matching at all, in which case the state we first pushed on at the + // beginning of the !isAtomic section will get popped off. But if here we're instead going to jump + // to something prior to the lazy loop, then we need to pop off that state here. + if (doneLabel == originalDoneLabel) { - // If we've reached our upper bound, backtrack. - writer.WriteLine($"// If the upper bound {maxIterations} has already been reached,"); - writer.WriteLine($"// don't continue lazily iterating. Instead, backtrack."); - clause = EmitBlock(writer, $"if ({CountIsGreaterThanOrEqualTo(iterationCount, maxIterations)})"); + EmitAdd(writer, "stackpos", -entriesPerIteration); } - using (clause) + if (iterationMayBeEmpty) { - // We're backtracking, which could either be to something prior to the lazy loop or to something - // inside of the lazy loop. If it's to something inside of the lazy loop, then either the loop - // will eventually succeed or we'll eventually end up unwinding back through the iterations all - // the way back to the loop not matching at all, in which case the state we first pushed on at the - // beginning of the !isAtomic section will get popped off. But if here we're instead going to jump - // to something prior to the lazy loop, then we need to pop off that state here. - if (doneLabel == originalDoneLabel) - { - EmitAdd(writer, "stackpos", -entriesPerIteration); - } - - if (iterationMayBeEmpty) - { - // If we saw empty, it must have been in the most recent iteration, as we wouldn't have - // allowed additional iterations after one that was empty. Thus, we reset it back to - // false prior to backtracking / undoing that iteration. - writer.WriteLine($"{sawEmpty} = 0; // false"); - } - - Goto(doneLabel); + // If we saw empty, it must have been in the most recent iteration, as we wouldn't have + // allowed additional iterations after one that was empty. Thus, we reset it back to + // false prior to backtracking / undoing that iteration. + writer.WriteLine($"{sawEmpty} = 0; // false"); } + + Goto(doneLabel); } + } - // Otherwise, try to match another iteration. - Goto(body); - writer.WriteLine(); + // Otherwise, try to match another iteration. + Goto(body); + writer.WriteLine(); - doneLabel = backtrack; - MarkLabel(skipBacktrack); - } + doneLabel = backtrack; + MarkLabel(skipBacktrack); } // Emits the code to handle a loop (repeater) with a fixed number of iterations. @@ -4080,13 +4181,6 @@ void EmitSingleCharRepeater(RegexNode node, bool emitLengthCheck = true) } else { - // if ((uint)(sliceStaticPos + iterations - 1) >= (uint)slice.Length) goto doneLabel; - if (emitLengthCheck) - { - EmitSpanLengthCheck(iterations); - writer.WriteLine(); - } - // If we're able to vectorize the search, do so. Otherwise, fall back to a loop. // For the loop, we're validating that each char matches the target node. // For Contains{Any}, we're looking for the first thing that _doesn't_ match the target node, @@ -4095,13 +4189,26 @@ void EmitSingleCharRepeater(RegexNode node, bool emitLengthCheck = true) { string containsExpr = indexOfExpr.Replace("IndexOf", "Contains"); - using (EmitBlock(writer, $"if ({sliceSpan}.Slice({sliceStaticPos}, {iterations}).{containsExpr})")) + string condition = $"{sliceSpan}.Slice({sliceStaticPos}, {iterations}).{containsExpr}"; + if (emitLengthCheck) + { + condition = $"{SpanLengthCheck(iterations)} || {condition}"; + } + + using (EmitBlock(writer, $"if ({condition})")) { Goto(doneLabel); } } else { + // if ((uint)(sliceStaticPos + iterations - 1) >= (uint)slice.Length) goto doneLabel; + if (emitLengthCheck) + { + EmitSpanLengthCheck(iterations); + writer.WriteLine(); + } + string repeaterSpan = "repeaterSlice"; // As this repeater doesn't wrap arbitrary node emits, this shouldn't conflict with anything writer.WriteLine($"ReadOnlySpan {repeaterSpan} = {sliceSpan}.Slice({sliceStaticPos}, {iterations});"); @@ -5525,23 +5632,104 @@ private static string DescribeCapture(int capNum, RegexMethod rm) } /// Gets a textual description of what characters match a set. - private static string DescribeSet(string charClass) => - charClass switch + private static string DescribeSet(string charClass) + { + string? description = charClass switch { RegexCharClass.AnyClass => "any character", - RegexCharClass.DigitClass => "a Unicode digit", + RegexCharClass.AsciiLetterClass => "an ASCII letter", + RegexCharClass.AsciiLetterOrDigitClass => "an ASCII letter or digit", RegexCharClass.ECMASpaceClass => "a whitespace character (ECMA)", RegexCharClass.ECMAWordClass => "a word character (ECMA)", + RegexCharClass.HexDigitClass => "a hexadecimal digit", + RegexCharClass.HexDigitLowerClass => "a lowercase hexadecimal digit", + RegexCharClass.HexDigitUpperClass => "an uppercase hexadecimal digit", + RegexCharClass.LetterClass => "a Unicode letter", + RegexCharClass.LetterOrDigitClass => "a Unicode letter or digit", + RegexCharClass.NotAsciiLetterClass => "any character other than an ASCII letter", + RegexCharClass.NotAsciiLetterOrDigitClass => "any character other than an ASCII letter or digit", + RegexCharClass.NotControlClass => "any character other than a Unicode control character", RegexCharClass.NotDigitClass => "any character other than a Unicode digit", RegexCharClass.NotECMASpaceClass => "any character other than a whitespace character (ECMA)", RegexCharClass.NotECMAWordClass => "any character other than a word character (ECMA)", + RegexCharClass.NotHexDigitClass => "any character other than a hexadecimal digit", + RegexCharClass.NotHexDigitLowerClass => "any character other than a lowercase hexadecimal digit", + RegexCharClass.NotHexDigitUpperClass => "any character other than an uppercase hexadecimal digit", + RegexCharClass.NotLetterClass => "any character other than a Unicode letter", + RegexCharClass.NotLetterOrDigitClass => "any character other than a Unicode letter or digit", + RegexCharClass.NotLowerClass => "any character other than a Unicode lowercase letter", + RegexCharClass.NotNumberClass => "any character other than a Unicode number", + RegexCharClass.NotPunctuationClass => "any character other than a Unicode punctuation character", + RegexCharClass.NotSeparatorClass => "any character other than a Unicode separator", RegexCharClass.NotSpaceClass => "any character other than a whitespace character", + RegexCharClass.NotSymbolClass => "any character other than a Unicode symbol", + RegexCharClass.NotUpperClass => "any character other than a Unicode uppercase letter", RegexCharClass.NotWordClass => "any character other than a word character", + RegexCharClass.NumberClass => "a Unicode number", + RegexCharClass.PunctuationClass => "a Unicode punctuation character", + RegexCharClass.SeparatorClass => "a Unicode separator", RegexCharClass.SpaceClass => "a whitespace character", + RegexCharClass.SymbolClass => "a Unicode symbol", RegexCharClass.WordClass => "a word character", - _ => $"a character in the set {RegexCharClass.DescribeSet(charClass)}", + _ => null, }; + if (description is not null) + { + return description; + } + + Span categories = stackalloc UnicodeCategory[1]; + if (RegexCharClass.TryGetOnlyCategories(charClass, categories, out int numCategories, out bool negatedCategories) && + numCategories == 1) + { + ReadOnlySpan categoryDescriptions = + [ + "a Unicode uppercase letter", // UppercaseLetter = 0, + "a Unicode lowercase letter", // LowercaseLetter = 1, + "a Unicode titlecase letter", // TitlecaseLetter = 2, + "a Unicode modifier letter", // ModifierLetter = 3, + null, // OtherLetter = 4, + "a Unicode non-spacing mark", // NonSpacingMark = 5, + "a Unicode spacing-combining mark", // SpacingCombiningMark = 6, + "a Unicode enclosing mark", // EnclosingMark = 7, + "a Unicode digit", // DecimalDigitNumber = 8, + "a Unicode letter number", // LetterNumber = 9, + null, // OtherNumber = 10, + "a Unicode space separator", // SpaceSeparator = 11, + "a Unicode line separator", // LineSeparator = 12, + "a Unicode paragraph separator", // ParagraphSeparator = 13, + "a Unicode control character", // Control = 14, + "a Unicode format character", // Format = 15, + "a Unicode surrogate character", // Surrogate = 16, + "a Unicode private-use character", // PrivateUse = 17, + "a Unicode connector punctuation character", // ConnectorPunctuation = 18, + "a Unicode dash punctuation character", // DashPunctuation = 19, + "a Unicode open punctuation character", // OpenPunctuation = 20, + "a Unicode close punctuation character", // ClosePunctuation = 21, + "a Unicode initial quote punctuation character", // InitialQuotePunctuation = 22, + "a Unicode final quote punctuation character", // FinalQuotePunctuation = 23, + null, // OtherPunctuation = 24, + "a Unicode math symbol", // MathSymbol = 25, + "a Unicode currency symbol", // CurrencySymbol = 26, + "a Unicode modifier symbol", // ModifierSymbol = 27, + null, // OtherSymbol = 28, + "an unassigned Unicode code point", // OtherNotAssigned = 29, + ]; + + int cat = (int)categories[0]; + if ((uint)cat < (uint)categoryDescriptions.Length && + (description = categoryDescriptions[cat]) is not null) + { + return negatedCategories ? + $"any character other than {description}" : + description; + } + } + + return $"a character in the set {RegexCharClass.DescribeSet(charClass)}"; + } + /// Writes a textual description of the node tree fit for rending in source. /// The writer to which the description should be written. /// The node being written. @@ -5625,9 +5813,8 @@ private static string DescribeLoop(RegexNode node, RegexMethod rm) _ when node.M == node.N => "exactly", RegexNodeKind.Oneloopatomic or RegexNodeKind.Notoneloopatomic or RegexNodeKind.Setloopatomic => "atomically", RegexNodeKind.Oneloop or RegexNodeKind.Notoneloop or RegexNodeKind.Setloop => "greedily", - RegexNodeKind.Onelazy or RegexNodeKind.Notonelazy or RegexNodeKind.Setlazy => "lazily", - RegexNodeKind.Loop => rm.Analysis.IsAtomicByAncestor(node) ? "greedily and atomically" : "greedily", - _ /* RegexNodeKind.Lazyloop */ => rm.Analysis.IsAtomicByAncestor(node) ? "lazily and atomically" : "lazily", + RegexNodeKind.Loop => rm.Analysis.IsAtomicByAncestor(node) ? "atomically" : "greedily", + _ => "lazily", // Onelazy or Notonelazy or Setlazy or Lazyloop }; string bounds = diff --git a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.cs b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.cs index ff82d4344aa685..98e3f1ac35c036 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.cs +++ b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.cs @@ -31,9 +31,13 @@ public partial class RegexGenerator : IIncrementalGenerator [ "// ", "#nullable enable", +#if DEBUG "#pragma warning disable CS0162 // Unreachable code", "#pragma warning disable CS0164 // Unreferenced label", "#pragma warning disable CS0219 // Variable assigned but never used", +#else + "#pragma warning disable", +#endif ]; internal record struct CompilationData(bool AllowUnsafe, bool CheckOverflow, LanguageVersion LanguageVersion); diff --git a/src/libraries/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj b/src/libraries/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj index 86353b31b5d7b7..c666e4b99edb8a 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj +++ b/src/libraries/System.Text.RegularExpressions/src/System.Text.RegularExpressions.csproj @@ -104,17 +104,17 @@ - - - - - - + + + + + + - - - - + + + + diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.cs index c8179c064a9adb..8a078fddce62ad 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.cs @@ -30,7 +30,6 @@ public partial class Regex : ISerializable protected internal string[]? capslist; // if captures are sparse or named captures are used, this is the sorted list of names protected internal int capsize; // the size of the capture array - private WeakReference? _replref; // cached parsed replacement pattern private volatile RegexRunner? _runner; // cached runner #if DEBUG @@ -396,9 +395,9 @@ public int GroupNumberFromName(string name) /// A weak reference to a regex replacement, lazily initialized. internal WeakReference RegexReplacementWeakReference => - _replref ?? - Interlocked.CompareExchange(ref _replref, new WeakReference(null), null) ?? - _replref; + field ?? + Interlocked.CompareExchange(ref field, new WeakReference(null), null) ?? + field; [Obsolete(Obsoletions.RegexExtensibilityImplMessage, DiagnosticId = Obsoletions.RegexExtensibilityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCharClass.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCharClass.cs index 53fda5090fe6a7..3a2098692598de 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCharClass.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCharClass.cs @@ -51,10 +51,13 @@ internal sealed partial class RegexCharClass internal const string SpaceClass = "\u0000\u0000\u0001\u0064"; // \s internal const string NotSpaceClass = "\u0000\u0000\u0001\uFF9C"; // \S + internal const string NegatedSpaceClass = "\u0001\0\u0001d"; // [^\s] internal const string WordClass = "\u0000\u0000\u000A\u0000\u0002\u0004\u0005\u0003\u0001\u0006\u0009\u0013\u0000"; // \w internal const string NotWordClass = "\u0000\u0000\u000A\u0000\uFFFE\uFFFC\uFFFB\uFFFD\uFFFF\uFFFA\uFFF7\uFFED\u0000"; // \W + internal const string NegatedWordClass = "\u0001\0\n\0\u0002\u0004\u0005\u0003\u0001\u0006\t\u0013\0"; // [^\w] internal const string DigitClass = "\u0000\u0000\u0001\u0009"; // \d internal const string NotDigitClass = "\u0000\u0000\u0001\uFFF7"; // \D + internal const string NegatedDigitClass = "\u0001\0\u0001\t"; // [^\d] internal const string ControlClass = "\0\0\u0001\u000f"; // \p{Cc} internal const string NotControlClass = "\0\0\u0001\ufff1"; // \P{Cc} internal const string LetterClass = "\0\0\a\0\u0002\u0004\u0005\u0003\u0001\0"; // \p{L} @@ -363,6 +366,23 @@ public bool Negate public void AddChar(char c) => AddRange(c, c); + public void AddNotChar(char c) + { + if (c == 0) + { + AddRange((char)1, LastChar); + } + else if (c == LastChar) + { + AddRange((char)0, (char)(LastChar - 1)); + } + else + { + AddRange((char)0, (char)(c - 1)); + AddRange((char)(c + 1), LastChar); + } + } + /// /// Adds a regex char class /// @@ -923,6 +943,43 @@ public static bool MayOverlap(string set1, string set2) return false; } + // If both sets are composed of only Unicode categories, we can compare most cases fairly easily. + Span categories1 = stackalloc UnicodeCategory[16], categories2 = stackalloc UnicodeCategory[16]; + if (TryGetOnlyCategories(set1, categories1, out int numCategories1, out bool negated1) && + TryGetOnlyCategories(set2, categories2, out int numCategories2, out bool negated2)) + { + // Check for the case of the sets being negated versions of the same single category, + // e.g. \d and \D, in which case they don't overlap. + if (numCategories1 == 1 && numCategories2 == 1 && + categories1[0] == categories2[0] && + negated1 != negated2) + { + return false; + } + + // Otherwise, if either is negated, just assume they may overlap. + if (negated1 || negated2) + { + return true; + } + + // Check if any category is the same between the two. We've limited the number of elements in the spans + // to a small number, so we just do the easy thing of comparing the full product. + foreach (UnicodeCategory cat1 in categories1.Slice(0, numCategories1)) + { + foreach (UnicodeCategory cat2 in categories2.Slice(0, numCategories2)) + { + if (cat1 == cat2) + { + return true; + } + } + } + + // If we got here, the two sets are disjoint. + return false; + } + // If set2 can be easily enumerated (e.g. no unicode categories), then enumerate it and // check if any of its members are in set1. Otherwise, the same for set1. if (CanEasilyEnumerateSetContents(set2)) @@ -939,8 +996,16 @@ public static bool MayOverlap(string set1, string set2) return true; static bool KnownDistinctSets(string set1, string set2) => - (set1 == SpaceClass || set1 == ECMASpaceClass) && - (set2 == DigitClass || set2 == WordClass || set2 == ECMADigitClass || set2 == ECMAWordClass); + // Because of how the set strings are constructed, these known distinct sets aren't handled by our + // more general UnicodeCategory logic. + set1 switch + { + SpaceClass => set2 is NotSpaceClass or DigitClass or WordClass, + ECMASpaceClass => set2 is NotECMASpaceClass or ECMADigitClass or ECMAWordClass, + WordClass => set2 is NotWordClass, + ECMAWordClass => set2 is NotECMAWordClass, + _ => false, + }; static bool MayOverlapByEnumeration(string set1, string set2) { @@ -1227,6 +1292,55 @@ public static bool IsWordChar(char ch) (WordCategoriesMask & (1 << (int)CharUnicodeInfo.GetUnicodeCategory(ch))) != 0; } + /// Determines whether the characters that match the specified set are known to all be word characters. + public static bool IsKnownWordClassSubset(string set) + { + // Check for common sets that we know to be subsets of \w. + if (set is + WordClass or DigitClass or LetterClass or LetterOrDigitClass or + AsciiLetterClass or AsciiLetterOrDigitClass or + HexDigitClass or HexDigitUpperClass or HexDigitLowerClass) + { + return true; + } + + // Check for sets composed of Unicode categories that are part of \w. + Span categories = stackalloc UnicodeCategory[16]; + if (TryGetOnlyCategories(set, categories, out int numCategories, out bool negated) && !negated) + { + foreach (UnicodeCategory cat in categories.Slice(0, numCategories)) + { + if (!IsWordCategory(cat)) + { + return false; + } + } + + return true; + } + + // If we can enumerate every character in the set quickly, do so, checking to see whether they're all in \w. + if (CanEasilyEnumerateSetContents(set)) + { + for (int i = SetStartIndex; i < SetStartIndex + set[SetLengthIndex]; i += 2) + { + int curSetEnd = set[i + 1]; + for (int c = set[i]; c < curSetEnd; c++) + { + if (!CharInClass((char)c, WordClass)) + { + return false; + } + } + } + + return true; + } + + // Unlikely to be a subset of \w, and we don't know for sure. + return false; + } + /// Determines whether a character is considered a word character for the purposes of testing a word character boundary. public static bool IsBoundaryWordChar(char ch) { @@ -1243,10 +1357,13 @@ public static bool IsBoundaryWordChar(char ch) int chDiv8 = ch >> 3; return (uint)chDiv8 < (uint)ascii.Length ? (ascii[chDiv8] & (1 << (ch & 0x7))) != 0 : - ((WordCategoriesMask & (1 << (int)CharUnicodeInfo.GetUnicodeCategory(ch))) != 0 || + (IsWordCategory(CharUnicodeInfo.GetUnicodeCategory(ch)) || (ch == ZeroWidthJoiner | ch == ZeroWidthNonJoiner)); } + private static bool IsWordCategory(UnicodeCategory category) => + (WordCategoriesMask & (1 << (int)category)) != 0; + /// Determines whether the 'a' and 'b' values differ by only a single bit, setting that bit in 'mask'. /// This isn't specific to RegexCharClass; it's just a convenient place to host it. public static bool DifferByOneBit(char a, char b, out int mask) @@ -2038,6 +2155,7 @@ public static string DescribeChar(char ch) => '\f' => "\\f", '\n' => "\\n", '\\' => "\\\\", + '-' => "\\-", >= ' ' and <= '~' => ch.ToString(), _ => $"\\u{(uint)ch:X4}" }; diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs index c1948b957f9390..f4b6c25f227b90 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs @@ -20,7 +20,6 @@ namespace System.Text.RegularExpressions [RequiresDynamicCode("Compiling a RegEx requires dynamic code.")] internal abstract class RegexCompiler { -#pragma warning disable CS9264 // nullability of `field`: https://github.com/dotnet/csharplang/issues/8425 private static FieldInfo RuntextstartField => field ??= RegexRunnerField("runtextstart"); private static FieldInfo RuntextposField => field ??= RegexRunnerField("runtextpos"); private static FieldInfo RuntrackposField => field ??= RegexRunnerField("runtrackpos"); @@ -36,6 +35,8 @@ internal abstract class RegexCompiler private static MethodInfo MatchLengthMethod => field ??= RegexRunnerMethod("MatchLength"); private static MethodInfo MatchIndexMethod => field ??= RegexRunnerMethod("MatchIndex"); private static MethodInfo IsBoundaryMethod => field ??= typeof(RegexRunner).GetMethod("IsBoundary", BindingFlags.NonPublic | BindingFlags.Static, [typeof(ReadOnlySpan), typeof(int)])!; + private static MethodInfo IsPreWordCharBoundaryMethod => field ??= typeof(RegexRunner).GetMethod("IsPreWordCharBoundary", BindingFlags.NonPublic | BindingFlags.Static, [typeof(ReadOnlySpan), typeof(int)])!; + private static MethodInfo IsPostWordCharBoundaryMethod => field ??= typeof(RegexRunner).GetMethod("IsPostWordCharBoundary", BindingFlags.NonPublic | BindingFlags.Static, [typeof(ReadOnlySpan), typeof(int)])!; private static MethodInfo IsWordCharMethod => field ??= RegexRunnerMethod("IsWordChar"); private static MethodInfo IsECMABoundaryMethod => field ??= typeof(RegexRunner).GetMethod("IsECMABoundary", BindingFlags.NonPublic | BindingFlags.Static, [typeof(ReadOnlySpan), typeof(int)])!; private static MethodInfo CrawlposMethod => field ??= RegexRunnerMethod("Crawlpos"); @@ -103,7 +104,6 @@ internal abstract class RegexCompiler private static MethodInfo MathMinIntIntMethod => field ??= typeof(Math).GetMethod("Min", [typeof(int), typeof(int)])!; private static MethodInfo MemoryMarshalGetArrayDataReferenceSearchValuesMethod => field ??= typeof(MemoryMarshal).GetMethod("GetArrayDataReference", [Type.MakeGenericMethodParameter(0).MakeArrayType()])!.MakeGenericMethod(typeof(SearchValues))!; private static MethodInfo UnsafeAsMethod => field ??= typeof(Unsafe).GetMethod("As", [typeof(object)])!; -#pragma warning restore CS9264 // Note: // Single-range helpers like IsAsciiLetterLower, IsAsciiLetterUpper, IsAsciiDigit, and IsBetween aren't used here, as the IL generated for those @@ -3052,25 +3052,41 @@ void EmitBoundary(RegexNode node) } switch (node.Kind) { - case RegexNodeKind.Boundary: - Call(IsBoundaryMethod); - BrfalseFar(doneLabel); - break; - - case RegexNodeKind.NonBoundary: - Call(IsBoundaryMethod); - BrtrueFar(doneLabel); - break; + case RegexNodeKind.Boundary or RegexNodeKind.NonBoundary: + if (node.IsKnownPrecededByWordChar()) + { + Call(IsPostWordCharBoundaryMethod); + } + else if (node.IsKnownSucceededByWordChar()) + { + Call(IsPreWordCharBoundaryMethod); + } + else + { + Call(IsBoundaryMethod); + } - case RegexNodeKind.ECMABoundary: - Call(IsECMABoundaryMethod); - BrfalseFar(doneLabel); + if (node.Kind is RegexNodeKind.Boundary) + { + BrfalseFar(doneLabel); + } + else + { + BrtrueFar(doneLabel); + } break; default: - Debug.Assert(node.Kind == RegexNodeKind.NonECMABoundary); Call(IsECMABoundaryMethod); - BrtrueFar(doneLabel); + + if (node.Kind is RegexNodeKind.ECMABoundary) + { + BrfalseFar(doneLabel); + } + else + { + BrtrueFar(doneLabel); + } break; } } @@ -3737,7 +3753,7 @@ node.Kind is RegexNodeKind.Setlazy && // startingPos = slice.IndexOf(literal); Ldloc(slice); - EmitIndexOf(node, useLast: false, negate: false); + EmitIndexOf(literal2, useLast: false, negate: false); Stloc(startingPos); // if (startingPos < 0) goto doneLabel; @@ -3850,15 +3866,6 @@ void EmitLazy(RegexNode node) return; } - // We should only be here if the lazy loop isn't atomic due to an ancestor, as the optimizer should - // in such a case have lowered the loop's upper bound to its lower bound, at which point it would - // have been handled by the above delegation to EmitLoop. However, if the optimizer missed doing so, - // this loop could still be considered atomic by ancestor by its parent nodes, in which case we want - // to make sure the code emitted here conforms (e.g. doesn't leave any state erroneously on the stack). - // So, we assert it's not atomic, but still handle that case. - bool isAtomic = analysis.IsAtomicByAncestor(node); - Debug.Assert(!isAtomic, "An atomic lazy should have had its upper bound lowered to its lower bound."); - // We might loop any number of times. In order to ensure this loop and subsequent code sees sliceStaticPos // the same regardless, we always need it to contain the same value, and the easiest such value is 0. // So, we transfer sliceStaticPos to pos, and ensure that any path out of here has sliceStaticPos as 0. @@ -3904,299 +3911,297 @@ void EmitLazy(RegexNode node) // we can uncapture back to that position), and both the starting position from the iteration we're leaving // and whether we've seen an empty iteration (if iterations may be empty). Since there can be multiple // iterations, this state needs to be stored on to the backtracking stack. - if (!isAtomic) + + // base.runstack[stackpos++] = pos; + // base.runstack[stackpos++] = startingPos; + // base.runstack[stackpos++] = sawEmpty; + // base.runstack[stackpos++] = base.Crawlpos(); + int entriesPerIteration = 1/*pos*/ + (iterationMayBeEmpty ? 2/*startingPos+sawEmpty*/ : 0) + (expressionHasCaptures ? 1/*Crawlpos*/ : 0); + EmitStackResizeIfNeeded(entriesPerIteration); + EmitStackPush(() => Ldloc(pos)); + if (iterationMayBeEmpty) { - // base.runstack[stackpos++] = pos; - // base.runstack[stackpos++] = startingPos; - // base.runstack[stackpos++] = sawEmpty; - // base.runstack[stackpos++] = base.Crawlpos(); - int entriesPerIteration = 1/*pos*/ + (iterationMayBeEmpty ? 2/*startingPos+sawEmpty*/ : 0) + (expressionHasCaptures ? 1/*Crawlpos*/ : 0); - EmitStackResizeIfNeeded(entriesPerIteration); - EmitStackPush(() => Ldloc(pos)); - if (iterationMayBeEmpty) - { - EmitStackPush(() => Ldloc(startingPos!)); - EmitStackPush(() => Ldloc(sawEmpty!)); - } - if (expressionHasCaptures) - { - EmitStackPush(() => { Ldthis(); Call(CrawlposMethod); }); - } + EmitStackPush(() => Ldloc(startingPos!)); + EmitStackPush(() => Ldloc(sawEmpty!)); + } + if (expressionHasCaptures) + { + EmitStackPush(() => { Ldthis(); Call(CrawlposMethod); }); + } - if (iterationMayBeEmpty) - { - // We need to store the current pos so we can compare it against pos after the iteration, in order to - // determine whether the iteration was empty. - // startingPos = pos; - Ldloc(pos); - Stloc(startingPos!); - } + if (iterationMayBeEmpty) + { + // We need to store the current pos so we can compare it against pos after the iteration, in order to + // determine whether the iteration was empty. + // startingPos = pos; + Ldloc(pos); + Stloc(startingPos!); + } - // Proactively increase the number of iterations. We do this prior to the match rather than once - // we know it's successful, because we need to decrement it as part of a failed match when - // backtracking; it's thus simpler to just always decrement it as part of a failed match, even - // when initially greedily matching the loop, which then requires we increment it before trying. - // iterationCount++; - Ldloc(iterationCount); - Ldc(1); - Add(); - Stloc(iterationCount); + // Proactively increase the number of iterations. We do this prior to the match rather than once + // we know it's successful, because we need to decrement it as part of a failed match when + // backtracking; it's thus simpler to just always decrement it as part of a failed match, even + // when initially greedily matching the loop, which then requires we increment it before trying. + // iterationCount++; + Ldloc(iterationCount); + Ldc(1); + Add(); + Stloc(iterationCount); - // Last but not least, we need to set the doneLabel that a failed match of the body will jump to. - // Such an iteration match failure may or may not fail the whole operation, depending on whether - // we've already matched the minimum required iterations, so we need to jump to a location that - // will make that determination. - Label iterationFailedLabel = DefineLabel(); - doneLabel = iterationFailedLabel; + // Last but not least, we need to set the doneLabel that a failed match of the body will jump to. + // Such an iteration match failure may or may not fail the whole operation, depending on whether + // we've already matched the minimum required iterations, so we need to jump to a location that + // will make that determination. + Label iterationFailedLabel = DefineLabel(); + doneLabel = iterationFailedLabel; - // Finally, emit the child. - Debug.Assert(sliceStaticPos == 0); - EmitNode(child); - TransferSliceStaticPosToPos(); // ensure sliceStaticPos remains 0 - if (doneLabel == iterationFailedLabel) - { - doneLabel = originalDoneLabel; - } + // Finally, emit the child. + Debug.Assert(sliceStaticPos == 0); + EmitNode(child); + TransferSliceStaticPosToPos(); // ensure sliceStaticPos remains 0 + if (doneLabel == iterationFailedLabel) + { + doneLabel = originalDoneLabel; + } - // Loop condition. Continue iterating if we've not yet reached the minimum. We just successfully - // matched an iteration, so the only reason we'd need to forcefully loop around again is if the - // minimum were at least 2. - if (minIterations >= 2) - { - // if (iterationCount < minIterations) goto body; - Ldloc(iterationCount); - Ldc(minIterations); - BltFar(body); - } + // Loop condition. Continue iterating if we've not yet reached the minimum. We just successfully + // matched an iteration, so the only reason we'd need to forcefully loop around again is if the + // minimum were at least 2. + if (minIterations >= 2) + { + // if (iterationCount < minIterations) goto body; + Ldloc(iterationCount); + Ldc(minIterations); + BltFar(body); + } - if (iterationMayBeEmpty) - { - // If the last iteration was empty, we need to prevent further iteration from this point - // unless we backtrack out of this iteration. - // if (pos == startingPos) sawEmpty = 1; // true - Label skipSawEmptySet = DefineLabel(); - Ldloc(pos); - Ldloc(startingPos!); - Bne(skipSawEmptySet); - Ldc(1); - Stloc(sawEmpty!); - MarkLabel(skipSawEmptySet); - } + if (iterationMayBeEmpty) + { + // If the last iteration was empty, we need to prevent further iteration from this point + // unless we backtrack out of this iteration. + // if (pos == startingPos) sawEmpty = 1; // true + Label skipSawEmptySet = DefineLabel(); + Ldloc(pos); + Ldloc(startingPos!); + Bne(skipSawEmptySet); + Ldc(1); + Stloc(sawEmpty!); + MarkLabel(skipSawEmptySet); + } - // We matched the next iteration. Jump to the subsequent code. - // goto endLoop; - BrFar(endLoop); + // We matched the next iteration. Jump to the subsequent code. + // goto endLoop; + BrFar(endLoop); - // Now handle what happens when an iteration fails (and since a lazy loop only executes an iteration - // when it's required to satisfy the loop by definition of being lazy, the loop is failing). We need - // to reset state to what it was before just that iteration started. That includes resetting pos and - // clearing out any captures from that iteration. - MarkLabel(iterationFailedLabel); + // Now handle what happens when an iteration fails (and since a lazy loop only executes an iteration + // when it's required to satisfy the loop by definition of being lazy, the loop is failing). We need + // to reset state to what it was before just that iteration started. That includes resetting pos and + // clearing out any captures from that iteration. + MarkLabel(iterationFailedLabel); - // Fail this loop iteration, including popping state off the backtracking stack that was pushed - // on as part of the failing iteration. + // Fail this loop iteration, including popping state off the backtracking stack that was pushed + // on as part of the failing iteration. - // iterationCount--; - Ldloc(iterationCount); - Ldc(1); - Sub(); - Stloc(iterationCount); + // iterationCount--; + Ldloc(iterationCount); + Ldc(1); + Sub(); + Stloc(iterationCount); - // poppedCrawlPos = base.runstack[--stackpos]; - // while (base.Crawlpos() > poppedCrawlPos) base.Uncapture(); - // sawEmpty = base.runstack[--stackpos]; - // startingPos = base.runstack[--stackpos]; - // pos = base.runstack[--stackpos]; - // slice = inputSpan.Slice(pos); - EmitUncaptureUntilPopped(); - if (iterationMayBeEmpty) - { - EmitStackPop(); - Stloc(sawEmpty!); - EmitStackPop(); - Stloc(startingPos!); - } + // poppedCrawlPos = base.runstack[--stackpos]; + // while (base.Crawlpos() > poppedCrawlPos) base.Uncapture(); + // sawEmpty = base.runstack[--stackpos]; + // startingPos = base.runstack[--stackpos]; + // pos = base.runstack[--stackpos]; + // slice = inputSpan.Slice(pos); + EmitUncaptureUntilPopped(); + if (iterationMayBeEmpty) + { EmitStackPop(); - Stloc(pos); - SliceInputSpan(); + Stloc(sawEmpty!); + EmitStackPop(); + Stloc(startingPos!); + } + EmitStackPop(); + Stloc(pos); + SliceInputSpan(); - // If the loop's child doesn't backtrack, then this loop has failed. - // If the loop's child does backtrack, we need to backtrack back into the previous iteration if there was one. - if (doneLabel == originalDoneLabel) - { - // Since the only reason we'd end up revisiting previous iterations of the lazy loop is if the child had backtracking constructs - // we'd backtrack into, and the child doesn't, the whole loop is failed and done. If we successfully processed any iterations, - // we thus need to pop all of the state we pushed onto the stack for those iterations, as we're exiting out to the parent who - // will expect the stack to be cleared of any child state. - - // stackpos -= iterationCount * entriesPerIteration; - Debug.Assert(entriesPerIteration >= 1); - Ldloc(stackpos); - Ldloc(iterationCount); - if (entriesPerIteration > 1) - { - Ldc(entriesPerIteration); - Mul(); - } - Sub(); - Stloc(stackpos); + // If the loop's child doesn't backtrack, then this loop has failed. + // If the loop's child does backtrack, we need to backtrack back into the previous iteration if there was one. + if (doneLabel == originalDoneLabel) + { + // Since the only reason we'd end up revisiting previous iterations of the lazy loop is if the child had backtracking constructs + // we'd backtrack into, and the child doesn't, the whole loop is failed and done. If we successfully processed any iterations, + // we thus need to pop all of the state we pushed onto the stack for those iterations, as we're exiting out to the parent who + // will expect the stack to be cleared of any child state. - // goto originalDoneLabel; - BrFar(originalDoneLabel); - } - else + // stackpos -= iterationCount * entriesPerIteration; + Debug.Assert(entriesPerIteration >= 1); + Ldloc(stackpos); + Ldloc(iterationCount); + if (entriesPerIteration > 1) { - // The child has backtracking constructs. If we have no successful iterations previously processed, just bail. - // If we do have successful iterations previously processed, however, we need to backtrack back into the last one. + Ldc(entriesPerIteration); + Mul(); + } + Sub(); + Stloc(stackpos); - // if (iterationCount == 0) goto originalDoneLabel; - Ldloc(iterationCount); - Ldc(0); - BeqFar(originalDoneLabel); + // goto originalDoneLabel; + BrFar(originalDoneLabel); + } + else + { + // The child has backtracking constructs. If we have no successful iterations previously processed, just bail. + // If we do have successful iterations previously processed, however, we need to backtrack back into the last one. - if (iterationMayBeEmpty) - { - // If we saw empty, it must have been in the most recent iteration, as we wouldn't have - // allowed additional iterations after one that was empty. Thus, we reset it back to - // false prior to backtracking / undoing that iteration. - Ldc(0); - Stloc(sawEmpty!); - } + // if (iterationCount == 0) goto originalDoneLabel; + Ldloc(iterationCount); + Ldc(0); + BeqFar(originalDoneLabel); - // goto doneLabel; - BrFar(doneLabel); + if (iterationMayBeEmpty) + { + // If we saw empty, it must have been in the most recent iteration, as we wouldn't have + // allowed additional iterations after one that was empty. Thus, we reset it back to + // false prior to backtracking / undoing that iteration. + Ldc(0); + Stloc(sawEmpty!); } - MarkLabel(endLoop); + // goto doneLabel; + BrFar(doneLabel); + } - // If the lazy loop is not atomic, then subsequent code may backtrack back into this lazy loop, either - // causing it to add additional iterations, or backtracking into existing iterations and potentially - // unwinding them. We need to do a timeout check, and then determine whether to branch back to add more - // iterations (if we haven't hit the loop's maximum iteration count and haven't seen an empty iteration) - // or unwind by branching back to the last backtracking location. Either way, we need a dedicated - // backtracking section that a subsequent construct will see as its backtracking target. - // We need to ensure that some state (e.g. iteration count) is persisted if we're backtracked to. - // If we're not inside of a loop, the local's used for this construct are sufficient, as nothing - // else will overwrite them between now and when backtracking occurs. If, however, we are inside - // of another loop, then any number of iterations might have such state that needs to be stored, - // and thus it needs to be pushed on to the backtracking stack. - // base.runstack[stackpos++] = pos; - // base.runstack[stackpos++] = iterationCount; - // base.runstack[stackpos++] = startingPos; - // base.runstack[stackpos++] = sawEmpty; - bool isInLoop = analysis.IsInLoop(node); - EmitStackResizeIfNeeded(1 + (isInLoop ? 1 + (iterationMayBeEmpty ? 2 : 0) : 0) + (expressionHasCaptures ? 1 : 0)); - EmitStackPush(() => Ldloc(pos)); - if (isInLoop) - { - EmitStackPush(() => Ldloc(iterationCount)); - if (iterationMayBeEmpty) - { - EmitStackPush(() => Ldloc(startingPos!)); - EmitStackPush(() => Ldloc(sawEmpty!)); - } - } - if (expressionHasCaptures) + MarkLabel(endLoop); + + // If the lazy loop is not atomic, then subsequent code may backtrack back into this lazy loop, either + // causing it to add additional iterations, or backtracking into existing iterations and potentially + // unwinding them. We need to do a timeout check, and then determine whether to branch back to add more + // iterations (if we haven't hit the loop's maximum iteration count and haven't seen an empty iteration) + // or unwind by branching back to the last backtracking location. Either way, we need a dedicated + // backtracking section that a subsequent construct will see as its backtracking target. + // We need to ensure that some state (e.g. iteration count) is persisted if we're backtracked to. + // If we're not inside of a loop, the local's used for this construct are sufficient, as nothing + // else will overwrite them between now and when backtracking occurs. If, however, we are inside + // of another loop, then any number of iterations might have such state that needs to be stored, + // and thus it needs to be pushed on to the backtracking stack. + // base.runstack[stackpos++] = pos; + // base.runstack[stackpos++] = iterationCount; + // base.runstack[stackpos++] = startingPos; + // base.runstack[stackpos++] = sawEmpty; + bool isInLoop = analysis.IsInLoop(node); + EmitStackResizeIfNeeded(1 + (isInLoop ? 1 + (iterationMayBeEmpty ? 2 : 0) : 0) + (expressionHasCaptures ? 1 : 0)); + EmitStackPush(() => Ldloc(pos)); + if (isInLoop) + { + EmitStackPush(() => Ldloc(iterationCount)); + if (iterationMayBeEmpty) { - EmitStackPush(() => { Ldthis(); Call(CrawlposMethod); }); + EmitStackPush(() => Ldloc(startingPos!)); + EmitStackPush(() => Ldloc(sawEmpty!)); } + } + if (expressionHasCaptures) + { + EmitStackPush(() => { Ldthis(); Call(CrawlposMethod); }); + } - Label skipBacktrack = DefineLabel(); - BrFar(skipBacktrack); + Label skipBacktrack = DefineLabel(); + BrFar(skipBacktrack); - // Emit a backtracking section that checks the timeout, restores the loop's state, and jumps to - // the appropriate label. - Label backtrack = DefineLabel(); - MarkLabel(backtrack); + // Emit a backtracking section that checks the timeout, restores the loop's state, and jumps to + // the appropriate label. + Label backtrack = DefineLabel(); + MarkLabel(backtrack); - // We're backtracking. Check the timeout. - EmitTimeoutCheckIfNeeded(); + // We're backtracking. Check the timeout. + EmitTimeoutCheckIfNeeded(); - // int poppedCrawlPos = base.runstack[--stackpos]; - // while (base.Crawlpos() > poppedCrawlPos) base.Uncapture(); - EmitUncaptureUntilPopped(); + // int poppedCrawlPos = base.runstack[--stackpos]; + // while (base.Crawlpos() > poppedCrawlPos) base.Uncapture(); + EmitUncaptureUntilPopped(); - if (isInLoop) + if (isInLoop) + { + // sawEmpty = base.runstack[--stackpos]; + // startingPos = base.runstack[--stackpos]; + // iterationCount = base.runstack[--stackpos]; + // pos = base.runstack[--stackpos]; + if (iterationMayBeEmpty) { - // sawEmpty = base.runstack[--stackpos]; - // startingPos = base.runstack[--stackpos]; - // iterationCount = base.runstack[--stackpos]; - // pos = base.runstack[--stackpos]; - if (iterationMayBeEmpty) - { - EmitStackPop(); - Stloc(sawEmpty!); - EmitStackPop(); - Stloc(startingPos!); - } EmitStackPop(); - Stloc(iterationCount); + Stloc(sawEmpty!); + EmitStackPop(); + Stloc(startingPos!); } EmitStackPop(); - Stloc(pos); - SliceInputSpan(); + Stloc(iterationCount); + } + EmitStackPop(); + Stloc(pos); + SliceInputSpan(); - // Determine where to branch, either back to the lazy loop body to add an additional iteration, - // or to the last backtracking label. + // Determine where to branch, either back to the lazy loop body to add an additional iteration, + // or to the last backtracking label. - Label jumpToDone = DefineLabel(); + Label jumpToDone = DefineLabel(); - if (iterationMayBeEmpty) - { - // if (sawEmpty != 0) - // { - // sawEmpty = 0; - // goto doneLabel; - // } - Label sawEmptyZero = DefineLabel(); - Ldloc(sawEmpty!); - Ldc(0); - Beq(sawEmptyZero); + if (iterationMayBeEmpty) + { + // if (sawEmpty != 0) + // { + // sawEmpty = 0; + // goto doneLabel; + // } + Label sawEmptyZero = DefineLabel(); + Ldloc(sawEmpty!); + Ldc(0); + Beq(sawEmptyZero); - // We saw empty, and it must have been in the most recent iteration, as we wouldn't have - // allowed additional iterations after one that was empty. Thus, we reset it back to - // false prior to backtracking / undoing that iteration. - Ldc(0); - Stloc(sawEmpty!); + // We saw empty, and it must have been in the most recent iteration, as we wouldn't have + // allowed additional iterations after one that was empty. Thus, we reset it back to + // false prior to backtracking / undoing that iteration. + Ldc(0); + Stloc(sawEmpty!); - Br(jumpToDone); - MarkLabel(sawEmptyZero); - } + Br(jumpToDone); + MarkLabel(sawEmptyZero); + } - if (maxIterations != int.MaxValue) - { - // if (iterationCount >= maxIterations) goto doneLabel; - Ldloc(iterationCount); - Ldc(maxIterations); - Bge(jumpToDone); - } + if (maxIterations != int.MaxValue) + { + // if (iterationCount >= maxIterations) goto doneLabel; + Ldloc(iterationCount); + Ldc(maxIterations); + Bge(jumpToDone); + } - // goto body; - BrFar(body); + // goto body; + BrFar(body); - MarkLabel(jumpToDone); + MarkLabel(jumpToDone); - // We're backtracking, which could either be to something prior to the lazy loop or to something - // inside of the lazy loop. If it's to something inside of the lazy loop, then either the loop - // will eventually succeed or we'll eventually end up unwinding back through the iterations all - // the way back to the loop not matching at all, in which case the state we first pushed on at the - // beginning of the !isAtomic section will get popped off. But if here we're instead going to jump - // to something prior to the lazy loop, then we need to pop off that state here. - if (doneLabel == originalDoneLabel) - { - // stackpos -= entriesPerIteration; - Ldloc(stackpos); - Ldc(entriesPerIteration); - Sub(); - Stloc(stackpos); - } + // We're backtracking, which could either be to something prior to the lazy loop or to something + // inside of the lazy loop. If it's to something inside of the lazy loop, then either the loop + // will eventually succeed or we'll eventually end up unwinding back through the iterations all + // the way back to the loop not matching at all, in which case the state we first pushed on at the + // beginning of the !isAtomic section will get popped off. But if here we're instead going to jump + // to something prior to the lazy loop, then we need to pop off that state here. + if (doneLabel == originalDoneLabel) + { + // stackpos -= entriesPerIteration; + Ldloc(stackpos); + Ldc(entriesPerIteration); + Sub(); + Stloc(stackpos); + } - // goto done; - BrFar(doneLabel); + // goto done; + BrFar(doneLabel); - doneLabel = backtrack; - MarkLabel(skipBacktrack); - } + doneLabel = backtrack; + MarkLabel(skipBacktrack); } // Emits the code to handle a loop (repeater) with a fixed number of iterations. diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs index f8fef4984b9663..20dac81c48d75c 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs @@ -8,6 +8,7 @@ namespace System.Text.RegularExpressions { + [RequiresDynamicCode("Compiling a RegEx requires dynamic code.")] internal sealed class RegexLWCGCompiler : RegexCompiler { /// @@ -31,7 +32,6 @@ internal sealed class RegexLWCGCompiler : RegexCompiler private static int s_regexCount; /// The top-level driver. Initializes everything then calls the Generate* methods. - [RequiresDynamicCode("Compiling a RegEx requires dynamic code.")] public RegexRunnerFactory? FactoryInstanceFromCode(string pattern, RegexTree regexTree, RegexOptions options, bool hasTimeout) { if (!regexTree.Root.SupportsCompilation(out _)) @@ -67,7 +67,6 @@ internal sealed class RegexLWCGCompiler : RegexCompiler } /// Begins the definition of a new method (no args) with a specified return value. - [RequiresDynamicCode("Compiling a RegEx requires dynamic code.")] private DynamicMethod DefineDynamicMethod(string methname, Type? returntype, Type hostType, Type[] paramTypes) { // We're claiming that these are static methods, but really they are instance methods. diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexNode.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexNode.cs index b81599c77ee787..3dce343ea8867a 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexNode.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexNode.cs @@ -154,7 +154,15 @@ private void MakeRep(RegexNodeKind kind, int min, int max) N = max; } - private void MakeLoopAtomic() + /// Converts this loop node to be atomic. + /// + /// If a loop is atomic by construction, e.g. it's at the end of the pattern + /// or its parent is an atomic group, there's no backtracking into it, which means it does its full + /// initial processing and then stops. For an eager loop, that means consuming as much as possible, + /// but for a lazy loop, that means consuming as little as possible. Thus, if this is true, a lazy + /// loop should lower its max iteration count to its min iteration count. + /// + private void MakeLoopAtomic(bool noBacktrackingByPosition = false) { switch (Kind) { @@ -165,11 +173,15 @@ private void MakeLoopAtomic() break; case RegexNodeKind.Onelazy or RegexNodeKind.Notonelazy or RegexNodeKind.Setlazy: - // For lazy, we not only change the Type, we also lower the max number of iterations - // to the minimum number of iterations, creating a repeater, as they should end up - // matching as little as possible. + // For lazy, we not only change the Type, if we're at the end of the pattern, + // we also lower the max number of iterations to the minimum number of iterations, + // creating a repeater, as they should end up matching as little as possible. Kind += RegexNodeKind.Oneloopatomic - RegexNodeKind.Onelazy; - N = M; + if (noBacktrackingByPosition) + { + N = M; + } + if (N == 0) { // If moving the max to be the same as the min dropped it to 0, there's no @@ -189,6 +201,34 @@ private void MakeLoopAtomic() } break; + case RegexNodeKind.Loop: + if (Parent is not { Kind: RegexNodeKind.Atomic }) + { + RegexNode loopAsChild = new(RegexNodeKind.Loop, Options, M, N); + Kind = RegexNodeKind.Atomic; + M = N = 0; + loopAsChild.AddChild(Child(0)); + ReplaceChild(0, loopAsChild); + } + break; + + case RegexNodeKind.Lazyloop: + if (noBacktrackingByPosition) + { + N = M; + } + + if (N != 0) + { + // A lazy loop that becomes atomic gets treated the same as a greedy loop, + // so we can share the same logic. + goto case RegexNodeKind.Loop; + } + + Kind = RegexNodeKind.Empty; + Children = null; + break; + default: Debug.Fail($"Unexpected type: {Kind}"); break; @@ -336,7 +376,7 @@ internal RegexNode FinalOptimize() // Only apply optimization when LTR to avoid needing additional code for the much rarer RTL case. // Also only apply these optimizations when not using NonBacktracking, as these optimizations are // all about avoiding things that are impactful for the backtracking engines but nops for non-backtracking. - if ((Options & (RegexOptions.RightToLeft | RegexOptions.NonBacktracking)) == 0) + if ((rootNode.Options & (RegexOptions.RightToLeft | RegexOptions.NonBacktracking)) == 0) { // Optimization: eliminate backtracking for loops. // For any single-character loop (Oneloop, Notoneloop, Setloop), see if we can automatically convert @@ -411,10 +451,9 @@ internal RegexNode FinalOptimize() private void EliminateEndingBacktracking() { if (!StackHelper.TryEnsureSufficientExecutionStack() || - (Options & (RegexOptions.RightToLeft | RegexOptions.NonBacktracking)) != 0) + (Options & RegexOptions.NonBacktracking) != 0) { // If we can't recur further, just stop optimizing. - // We haven't done the work to validate this is correct for RTL. // And NonBacktracking doesn't support atomic groups and doesn't have backtracking to be eliminated. return; } @@ -423,6 +462,12 @@ private void EliminateEndingBacktracking() RegexNode node = this; while (true) { + // In general we don't care too much about RightToLeft performance, as it's rarely used as a top-level option, + // and thus haven't done the work to either implement or vet these optimizations for RTL. + // However, it's also used to implement lookbehinds, and so where possible we still want to optimize + // when we can do so easily. Most of these cases are appropriately trivial. + bool rtl = (node.Options & RegexOptions.RightToLeft) != 0; + switch (node.Kind) { // {One/Notone/Set}loops can be upgraded to {One/Notone/Set}loopatomic nodes, e.g. [abc]* => (?>[abc]*). @@ -430,7 +475,7 @@ private void EliminateEndingBacktracking() // or even empty nodes. case RegexNodeKind.Oneloop or RegexNodeKind.Notoneloop or RegexNodeKind.Setloop: case RegexNodeKind.Onelazy or RegexNodeKind.Notonelazy or RegexNodeKind.Setlazy: - node.MakeLoopAtomic(); + node.MakeLoopAtomic(noBacktrackingByPosition: true); break; // Just because a particular node is atomic doesn't mean all its descendants are. @@ -448,10 +493,10 @@ private void EliminateEndingBacktracking() // an Atomic one if its grandparent is already Atomic. // e.g. [xyz](?:abc|def) => [xyz](?>abc|def) case RegexNodeKind.Capture: - case RegexNodeKind.Concatenate: + case RegexNodeKind.Concatenate when !rtl: RegexNode existingChild = node.Child(node.ChildCount() - 1); if ((existingChild.Kind is RegexNodeKind.Alternate or RegexNodeKind.BackreferenceConditional or RegexNodeKind.ExpressionConditional or RegexNodeKind.Loop or RegexNodeKind.Lazyloop) && - (node.Parent is null || node.Parent.Kind != RegexNodeKind.Atomic)) // validate grandparent isn't atomic + node.Parent is not { Kind: RegexNodeKind.Atomic }) // validate grandparent isn't atomic { var atomic = new RegexNode(RegexNodeKind.Atomic, existingChild.Options); atomic.AddChild(existingChild); @@ -489,24 +534,31 @@ private void EliminateEndingBacktracking() // e.g. (?:abc*)* => (?:ab(?>c*))* // e.g. (abc*?)+? => (ab){1} case RegexNodeKind.Lazyloop: - node.N = node.M; - goto case RegexNodeKind.Loop; case RegexNodeKind.Loop: { - if (node.N == 1) + // Make the loop atomic, if it isn't already. This entails changing node to instead be an Atomic node + // that has the {Lazy}Loop as its child. If the parent of the loop is already Atomic, this will be a nop. + node.MakeLoopAtomic(noBacktrackingByPosition: true); + Debug.Assert(node.Kind is RegexNodeKind.Atomic or RegexNodeKind.Empty or RegexNodeKind.Loop or RegexNodeKind.Lazyloop); + + if (node.Kind is RegexNodeKind.Atomic) { - // If the loop has a max iteration count of 1 (e.g. it's an optional node), - // there's no possibility for conflict between multiple iterations, so - // we can process it. node = node.Child(0); - continue; + Debug.Assert(node.Kind is RegexNodeKind.Loop or RegexNodeKind.Lazyloop); } - RegexNode? loopDescendent = node.FindLastExpressionInLoopForAutoAtomic(); - if (loopDescendent != null) + if (node.Kind is RegexNodeKind.Loop or RegexNodeKind.Lazyloop) { - node = loopDescendent; - continue; // loop around to process node + if (node.N == 1 || CanBeMadeAtomic(node.Child(0), node.Child(0), iterateNullableSubsequent: false, allowLazy: false)) + { + // If the loop has a max iteration count of 1 (e.g. it's an optional node), + // there's no possibility for conflict between multiple iterations, so + // we can process it. Or, if the node can be made atomic with itself as a subsequent + // node (which is logically what happens when there are multiple iterations), we can also + // recur into its child. + node = node.Child(0); + continue; + } } } break; @@ -635,7 +687,7 @@ private RegexNode ReduceAtomic() case RegexNodeKind.Onelazy: case RegexNodeKind.Notonelazy: case RegexNodeKind.Setlazy: - child.MakeLoopAtomic(); + child.MakeLoopAtomic(noBacktrackingByPosition: true); return child; // Alternations have a variety of possible optimizations that can be applied @@ -738,6 +790,11 @@ private RegexNode ReduceAtomic() start = endExclusive; } + // Force a re-reduction if we know we've exposed new opportunities that'll be handled. + reordered |= + child.ChildCount() == 2 && + (child.Child(0).Kind is RegexNodeKind.Empty || child.Child(1).Kind is RegexNodeKind.Empty); // can be transformed into a ? or ?? + // If anything was reordered, there may be new optimization opportunities inside // of the alternation, so reduce it again. if (reordered) @@ -751,7 +808,9 @@ private RegexNode ReduceAtomic() // For everything else, try to reduce ending backtracking of the last contained expression. default: child.EliminateEndingBacktracking(); - return atomic; + return child.Kind == RegexNodeKind.Empty ? + child : // if the child became empty, then the atomic node isn't needed + atomic; } } @@ -839,8 +898,7 @@ private RegexNode ReduceLoops() // If the Loop or Lazyloop now only has one child node and its a Set, One, or Notone, // reduce to just Setloop/lazy, Oneloop/lazy, or Notoneloop/lazy. The parser will - // generally have only produced the latter, but other reductions could have exposed - // this. + // generally have only produced the latter, but other reductions could have exposed this. if (u.ChildCount() == 1) { RegexNode child = u.Child(0); @@ -852,6 +910,30 @@ private RegexNode ReduceLoops() child.MakeRep(u.Kind == RegexNodeKind.Lazyloop ? RegexNodeKind.Onelazy : RegexNodeKind.Oneloop, u.M, u.N); u = child; break; + + case RegexNodeKind.Empty: + // A loop around an empty is itself empty, regardless of iteration counts. + u = child; + break; + + case RegexNodeKind.PositiveLookaround when ContainsKind(child, [RegexNodeKind.Capture]) is false: + case RegexNodeKind.NegativeLookaround or + RegexNodeKind.Beginning or RegexNodeKind.Start or + RegexNodeKind.Bol or RegexNodeKind.Eol or + RegexNodeKind.End or RegexNodeKind.EndZ or + RegexNodeKind.Boundary or RegexNodeKind.ECMABoundary or + RegexNodeKind.NonBoundary or RegexNodeKind.NonECMABoundary: + // A loop around (most) zero-width assertions can also be reduced. If it has a lower bound of 0, + // then it's either asserting something or not, and is thus useless and replaceable by empty. + // If it has a lower bound > 0, then the contents are still needed, but the loop isn't, since + // it's non-consuming and thus any more repetitions than 1 are redundant. The one zero-width assertion + // that can't be handled in this way is a PositiveLookaround, because it might contain capture groups + // with captures that must persist past the lookaround (in contrast, negative lookarounds undo all + // captures); if it were to be removed, it could affect both subsequent backreferences as well as access + // to capture information in the resulting Match. Thus, we can only transform a PositiveLookaround in + // this manner if it doesn't contain any captures. + u = u.M == 0 ? new RegexNode(RegexNodeKind.Empty, Options) : child; + break; } } @@ -914,6 +996,17 @@ private RegexNode ReduceSet() case RegexCharClass.NotSpaceSpaceClass: Str = RegexCharClass.AnyClass; break; + + // Different ways of saying \D, \S, \W + case RegexCharClass.NegatedDigitClass: // [^\d] + Str = RegexCharClass.NotDigitClass; + break; + case RegexCharClass.NegatedSpaceClass: // [^\s] + Str = RegexCharClass.NotSpaceClass; + break; + case RegexCharClass.NegatedWordClass: // [^\w] + Str = RegexCharClass.NotWordClass; + break; } return this; @@ -944,6 +1037,22 @@ private RegexNode ReduceAlternation() if (node.Kind == RegexNodeKind.Alternate) { node = RemoveRedundantEmptiesAndNothings(node); + + // If the alternation is actually just a ? or ?? in disguise, transform it accordingly. + // (a|) becomes a? + // (|a) becomes a?? + // Such "optional" nodes are processed more efficiently, including being able to be better coalesced with surrounding nodes. + if (node.Kind is RegexNodeKind.Alternate && node.ChildCount() == 2) + { + if (node.Child(1).Kind is RegexNodeKind.Empty) + { + node = node.Child(0).MakeQuantifier(lazy: false, min: 0, max: 1); + } + else if (node.Child(0).Kind is RegexNodeKind.Empty) + { + node = node.Child(1).MakeQuantifier(lazy: true, min: 0, max: 1); + } + } } } } @@ -994,7 +1103,7 @@ void ReduceSingleLetterAndNestedAlternations() } j--; } - else if (at.Kind is RegexNodeKind.Set or RegexNodeKind.One) + else if (at.Kind is RegexNodeKind.Set or RegexNodeKind.One or RegexNodeKind.Notone) { // Cannot merge sets if L or I options differ, or if either are negated. optionsAt = at.Options & (RegexOptions.RightToLeft | RegexOptions.IgnoreCase); @@ -1017,7 +1126,7 @@ void ReduceSingleLetterAndNestedAlternations() break; } - // The last node was a Set or a One, we're a Set or One and our options are the same. + // The last node was a Set/One/Notone, we're a Set/One/Notone, and our options are the same. // Merge the two nodes. j--; prev = children[j]; @@ -1028,6 +1137,11 @@ void ReduceSingleLetterAndNestedAlternations() prevCharClass = new RegexCharClass(); prevCharClass.AddChar(prev.Ch); } + else if (prev.Kind == RegexNodeKind.Notone) + { + prevCharClass = new RegexCharClass(); + prevCharClass.AddNotChar(prev.Ch); + } else { prevCharClass = RegexCharClass.Parse(prev.Str!); @@ -1037,6 +1151,10 @@ void ReduceSingleLetterAndNestedAlternations() { prevCharClass.AddChar(at.Ch); } + else if (at.Kind == RegexNodeKind.Notone) + { + prevCharClass.AddNotChar(at.Ch); + } else { RegexCharClass atCharClass = RegexCharClass.Parse(at.Str!); @@ -1778,6 +1896,16 @@ static bool CanCombineCounts(int nodeMin, int nodeMax, int nextMin, int nextMax) currentNode.MakeRep(RegexNodeKind.Oneloop, 2, 2); next++; continue; + + // Coalescing identical anchors (e.g. \b\b). These don't need to become loops, as they collapse to a single anchor. + case RegexNodeKind.Beginning or RegexNodeKind.Start or + RegexNodeKind.End or RegexNodeKind.EndZ or + RegexNodeKind.Bol or RegexNodeKind.Eol or + RegexNodeKind.Boundary or RegexNodeKind.NonBoundary or + RegexNodeKind.ECMABoundary or RegexNodeKind.NonECMABoundary + when nextNode.Kind == currentNode.Kind: + next++; + continue; } } @@ -1807,12 +1935,6 @@ private void FindAndMakeLoopsAtomic() return; } - if ((Options & RegexOptions.RightToLeft) != 0) - { - // RTL is so rare, we don't need to spend additional time/code optimizing for it. - return; - } - // For all node types that have children, recur into each of those children. int childCount = ChildCount(); if (childCount != 0) @@ -1839,38 +1961,18 @@ private void FindAndMakeLoopsAtomic() static void ProcessNode(RegexNode node, RegexNode subsequent) { - if (!StackHelper.TryEnsureSufficientExecutionStack()) + if (!StackHelper.TryEnsureSufficientExecutionStack() || + (node.Options & RegexOptions.RightToLeft) != 0) { // If we can't recur further, just stop optimizing. + // And RTL is so rare, we don't need to spend additional time/code optimizing for it. return; } // Skip down the node past irrelevant nodes. - while (true) + while (node.Kind is RegexNodeKind.Capture or RegexNodeKind.Concatenate) { - // We can always recur into captures and into the last node of concatenations. - if (node.Kind is RegexNodeKind.Capture or RegexNodeKind.Concatenate) - { - node = node.Child(node.ChildCount() - 1); - continue; - } - - // For loops with at least one guaranteed iteration, we can recur into them, but - // we need to be careful not to just always do so; the ending node of a loop can only - // be made atomic if what comes after the loop but also the beginning of the loop are - // compatible for the optimization. - if (node.Kind == RegexNodeKind.Loop) - { - RegexNode? loopDescendent = node.FindLastExpressionInLoopForAutoAtomic(); - if (loopDescendent != null) - { - node = loopDescendent; - continue; - } - } - - // Can't skip any further. - break; + node = node.Child(node.ChildCount() - 1); } // If the node can be changed to atomic based on what comes after it, do so. @@ -1905,6 +2007,66 @@ static void ProcessNode(RegexNode node, RegexNode subsequent) node.MakeLoopAtomic(); break; + case RegexNodeKind.Loop when CanBeMadeAtomic(node, subsequent, iterateNullableSubsequent: true, allowLazy: false): + case RegexNodeKind.Lazyloop when CanBeMadeAtomic(node, subsequent, iterateNullableSubsequent: false, allowLazy: true): + // General loops and lazy loops can also be made atomic, but we need to be very careful in doing so. Making such loops + // atomic means wrapping them in an atomic group, and children of these loops can look up through their ancestry, see + // such an atomic group, and then decide to alter their behavior because backtracking isn't possible. For example, if + // a developer writes the pattern (?>(abcd*?)+)e, it is safe for that inner lazy char loop to see that nothing can + // backtrack into it, such that the lazy loop can match the minimum possible, such that the loop evaporates entirely, + // and it becomes (?>(abc)+)e. Thus, given a pattern like (abcd*?)+e, even though the outer loop can be made atomic, + // because the beginning/end of the loop don't overlap with each other or with their successor, we can't just wrap it + // in an atomic block, because that would then trigger the nested loop to behave incorrectly. We can address this in + // multiple ways, such as by tagging Atomic nodes we introduce as being different from ones originally part of the pattern, + // and then having children treat them differently when looking at their ancestors, or we can address it by only introducing + // such an atomic node when we can see it's safe for the children. For now, this does the latter, and to be conservative, + // it allowlists a small known set of children types. + RegexNode loopChild = node.Child(0); + while (loopChild.Kind is RegexNodeKind.Capture or RegexNodeKind.Concatenate) + { + loopChild = loopChild.Child(loopChild.ChildCount() - 1); + } + + if (loopChild.Kind is + RegexNodeKind.Boundary or RegexNodeKind.ECMABoundary or + RegexNodeKind.Multi or + RegexNodeKind.One or RegexNodeKind.Notone or RegexNodeKind.Set) + { + // For types on the allow list, we can make the loop itself atomic. + node.MakeLoopAtomic(); + } + else if (node.Kind is RegexNodeKind.Loop or RegexNodeKind.Lazyloop) + { + // For everything else, we can't make the loop itself atomic, but we can + // possibly continue to make children of the loop atomic. + goto case RegexNodeKind.Loop; + } + break; + + // For all other loops, we may not be able to make them atomic, but we might still be able to make a node + // they end with be atomic. If the loop has a max iteration count of 1, then we don't need to worry about it + // following itself and can simply examine its child. If it has a max iteration count greater than 1, then + // we can examine its child iff its child could be made atomic against itself. + case RegexNodeKind.Loop: + { + RegexNode child = node.Child(0); + if (node.N == 1 || CanBeMadeAtomic(child, child, iterateNullableSubsequent: false, allowLazy: false)) + { + ProcessNode(child, subsequent); + } + } + break; + + case RegexNodeKind.Lazyloop: + { + RegexNode child = node.Child(0); + if (node.N == 1 || CanBeMadeAtomic(child, child, iterateNullableSubsequent: false, allowLazy: true)) + { + ProcessNode(child, subsequent); + } + } + break; + case RegexNodeKind.Alternate or RegexNodeKind.BackreferenceConditional or RegexNodeKind.ExpressionConditional: // In the case of alternation, we can't change the alternation node itself // based on what comes after it (at least not with more complicated analysis @@ -1927,72 +2089,120 @@ static void ProcessNode(RegexNode node, RegexNode subsequent) } } - /// - /// Recurs into the last expression of a loop node, looking to see if it can find a node - /// that could be made atomic _assuming_ the conditions exist for it with the loop's ancestors. - /// - /// The found node that should be explored further for auto-atomicity; null if it doesn't exist. - private RegexNode? FindLastExpressionInLoopForAutoAtomic() + /// Optimizations for positive and negative lookaheads/behinds. + private RegexNode ReduceLookaround() { - RegexNode node = this; + Debug.Assert(Kind is RegexNodeKind.PositiveLookaround or RegexNodeKind.NegativeLookaround); + Debug.Assert(ChildCount() == 1); - Debug.Assert(node.Kind is RegexNodeKind.Loop or RegexNodeKind.Lazyloop); + // Captures inside of negative lookarounds are undone after the lookaround. Thus, if there's nothing + // inside of the negative lookaround that needs that capture group (namely a backreference), we can + // remove the capture. + if (Kind is RegexNodeKind.NegativeLookaround && ContainsKind(Child(0), [RegexNodeKind.Backreference, RegexNodeKind.BackreferenceConditional]) is false) + { + if (RemoveCaptures(this, 0)) + { + // If we removed captures, we may have changed the structure of the tree in a way that exposed more + // optimization possibility, so re-reduce the children. + ReplaceChild(0, Child(0)); + } - // Start by looking at the loop's sole child. - node = node.Child(0); + static bool RemoveCaptures(RegexNode parent, int nodeIndex) + { + RegexNode node = parent.Child(nodeIndex); - // Skip past captures. - while (node.Kind == RegexNodeKind.Capture) - { - node = node.Child(0); + if (node.Kind is RegexNodeKind.Capture) + { + parent.ReplaceChild(nodeIndex, node.Child(0)); + RemoveCaptures(parent, nodeIndex); + return true; + } + + bool changesMade = false; + if (StackHelper.TryEnsureSufficientExecutionStack()) + { + int childCount = node.ChildCount(); + for (int i = 0; i < childCount; i++) + { + changesMade |= RemoveCaptures(node, i); + } + } + + return changesMade; + } } - // If the loop's body is a concatenate, we can skip to its last child iff that - // last child doesn't conflict with the first child, since this whole concatenation - // could be repeated, such that the first node ends up following the last. For - // example, in the expression (a+[def])*, the last child is [def] and the first is - // a+, which can't possibly overlap with [def]. In contrast, if we had (a+[ade])*, - // [ade] could potentially match the starting 'a'. - if (node.Kind == RegexNodeKind.Concatenate) + // A lookaround is a zero-width atomic assertion. + // As it's atomic, nothing will backtrack into it, and we can + // eliminate any ending backtracking from it. + EliminateEndingBacktracking(); + + RegexNode child = Child(0); + + // A positive lookahead that wraps a zero-width assertion is useless wrapping and can be removed. + // Similarly, a positive lookaround wrapped around an empty can be reduced simply to Empty. + // A developer typically doesn't write this, but rather it evolves due to optimizations resulting in empty. + if (Kind is RegexNodeKind.PositiveLookaround) + { + if (((Options & RegexOptions.RightToLeft) == 0 && IsZeroWidthAssertion(child.Kind)) || + child.Kind is RegexNodeKind.Empty) + { + return child; + } + } + else if (Kind is RegexNodeKind.NegativeLookaround) { - int concatCount = node.ChildCount(); - RegexNode lastConcatChild = node.Child(concatCount - 1); - if (CanBeMadeAtomic(lastConcatChild, node.Child(0), iterateNullableSubsequent: false, allowLazy: false)) + // A negative lookaround wrapped around an empty child, i.e. (?!), is + // sometimes used as a way to insert a guaranteed no-match into the expression, + // often as part of a conditional. We can reduce it to simply Nothing. + if (child.Kind is RegexNodeKind.Empty) { - return lastConcatChild; + Kind = RegexNodeKind.Nothing; + Children = null; } } - // Otherwise, the loop has nothing that can participate in auto-atomicity. - return null; + return this; } - /// Optimizations for positive and negative lookaheads/behinds. - private RegexNode ReduceLookaround() + private static bool IsZeroWidthAssertion(RegexNodeKind kind) => kind is + RegexNodeKind.PositiveLookaround or RegexNodeKind.NegativeLookaround or + RegexNodeKind.Beginning or RegexNodeKind.Start or + RegexNodeKind.Bol or RegexNodeKind.Eol or + RegexNodeKind.End or RegexNodeKind.EndZ or + RegexNodeKind.Boundary or RegexNodeKind.ECMABoundary or + RegexNodeKind.NonBoundary or RegexNodeKind.NonECMABoundary or + RegexNodeKind.UpdateBumpalong; + + /// Gets whether the node contains any of the specified kinds anywhere in its tree. + /// if it does, if it does't, and if it can't be determined. + private static bool? ContainsKind(RegexNode node, ReadOnlySpan kinds) { - Debug.Assert(Kind is RegexNodeKind.PositiveLookaround or RegexNodeKind.NegativeLookaround); - Debug.Assert(ChildCount() == 1); - - // A lookaround is a zero-width atomic assertion. - // As it's atomic, nothing will backtrack into it, and we can - // eliminate any ending backtracking from it. - EliminateEndingBacktracking(); - - // A positive lookaround wrapped around an empty is a nop, and we can reduce it - // to simply Empty. A developer typically doesn't write this, but rather it evolves - // due to optimizations resulting in empty. + foreach (RegexNodeKind kind in kinds) + { + if (node.Kind == kind) + { + return true; + } + } - // A negative lookaround wrapped around an empty child, i.e. (?!), is - // sometimes used as a way to insert a guaranteed no-match into the expression, - // often as part of a conditional. We can reduce it to simply Nothing. + if (!StackHelper.TryEnsureSufficientExecutionStack()) + { + // If we can't recur further, just stop optimizing. We need to return null to signal + // that the result can't be trusted. + return null; + } - if (Child(0).Kind == RegexNodeKind.Empty) + int childCount = node.ChildCount(); + for (int i = 0; i < childCount; i++) { - Kind = Kind == RegexNodeKind.PositiveLookaround ? RegexNodeKind.Empty : RegexNodeKind.Nothing; - Children = null; + if (ContainsKind(node.Child(i), kinds) is true) + { + return true; + } } - return this; + return false; } /// Optimizations for backreference conditionals. @@ -2060,6 +2270,12 @@ private static bool CanBeMadeAtomic(RegexNode node, RegexNode subsequent, bool i return false; } + // Skip down past irrelevant nodes. + while (node.Kind is RegexNodeKind.Capture or RegexNodeKind.Concatenate) + { + node = node.Child(node.ChildCount() - 1); + } + // In most case, we'll simply check the node against whatever subsequent is. However, in case // subsequent ends up being a loop with a min bound of 0, we'll also need to evaluate the node // against whatever comes after subsequent. In that case, we'll walk the tree to find the @@ -2067,17 +2283,27 @@ private static bool CanBeMadeAtomic(RegexNode node, RegexNode subsequent, bool i while (true) { // Skip the successor down to the closest node that's guaranteed to follow it. - int childCount; - while ((childCount = subsequent.ChildCount()) > 0) + while (true) { - Debug.Assert(subsequent.Kind != RegexNodeKind.Group); switch (subsequent.Kind) { + // Concatenate, capture, and atomic do not impact what comes at the beginning of their children, + // so we can skip down to the first child. case RegexNodeKind.Concatenate: case RegexNodeKind.Capture: case RegexNodeKind.Atomic: - case RegexNodeKind.PositiveLookaround when (subsequent.Options & RegexOptions.RightToLeft) == 0: // only lookaheads, not lookbehinds (represented as RTL PositiveLookaround nodes) + + // Similarly, as long as a loop is guaranteed to iterate at least once, we can skip down to the child, + // as whatever starts it is guaranteed to come after the predecessor. case RegexNodeKind.Loop or RegexNodeKind.Lazyloop when subsequent.M > 0: + + // Positive lookaheads can also be skipped through. The lookahead logically comes after the predecessor, + // and even though it's zero width, we don't need to look at whatever comes after the lookahead, because + // the lookahead ends up overlapping with its successor. If the node is disjoint from the lookahead, then + // it's also disjoint from the intersection of the lookahead and the lookahead's successor, since the + // intersection can only narrow the possible set of characters that need to be considered for overlap with + // the predecessor node. + case RegexNodeKind.PositiveLookaround when (subsequent.Options & RegexOptions.RightToLeft) == 0: subsequent = subsequent.Child(0); continue; } @@ -2098,10 +2324,11 @@ private static bool CanBeMadeAtomic(RegexNode node, RegexNode subsequent, bool i // only a yes branch, we'd need to also check whatever comes after the conditional). It doesn't apply to // backreference conditionals, as the condition itself is unknown statically and could overlap with the // loop being considered for atomicity. + int childCount = subsequent.ChildCount(); switch (subsequent.Kind) { case RegexNodeKind.Alternate: - case RegexNodeKind.ExpressionConditional when childCount == 3: // condition, yes, and no branch + case RegexNodeKind.ExpressionConditional when childCount is 3: // condition, yes, and no branch for (int i = 0; i < childCount; i++) { if (!CanBeMadeAtomic(node, subsequent.Child(i), iterateNullableSubsequent, allowLazy: false)) @@ -2112,9 +2339,8 @@ private static bool CanBeMadeAtomic(RegexNode node, RegexNode subsequent, bool i return true; } - // If this node is a {one/notone/set}loop, see if it overlaps with its successor in the concatenation. - // If it doesn't, then we can upgrade it to being a {one/notone/set}loopatomic. - // Doing so avoids unnecessary backtracking. + // If this node is a loop, see if it overlaps with its successor in the concatenation. + // If it doesn't, then we can upgrade it to being atomic to avoid unnecessary backtracking. switch (node.Kind) { case RegexNodeKind.Oneloop: @@ -2130,15 +2356,15 @@ private static bool CanBeMadeAtomic(RegexNode node, RegexNode subsequent, bool i case RegexNodeKind.Multi when node.Ch != subsequent.Str![0]: case RegexNodeKind.End: case RegexNodeKind.EndZ or RegexNodeKind.Eol when node.Ch != '\n': + case RegexNodeKind.Boundary when node.M > 0 && RegexCharClass.IsBoundaryWordChar(node.Ch): + case RegexNodeKind.NonBoundary when node.M > 0 && !RegexCharClass.IsBoundaryWordChar(node.Ch): + case RegexNodeKind.ECMABoundary when node.M > 0 && RegexCharClass.IsECMAWordChar(node.Ch): + case RegexNodeKind.NonECMABoundary when node.M > 0 && !RegexCharClass.IsECMAWordChar(node.Ch): return true; case RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic when subsequent.M == 0 && node.Ch != subsequent.Ch: case RegexNodeKind.Notonelazy or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic when subsequent.M == 0 && node.Ch == subsequent.Ch: case RegexNodeKind.Setlazy or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic when subsequent.M == 0 && !RegexCharClass.CharInClass(node.Ch, subsequent.Str!): - case RegexNodeKind.Boundary when node.M > 0 && RegexCharClass.IsBoundaryWordChar(node.Ch): - case RegexNodeKind.NonBoundary when node.M > 0 && !RegexCharClass.IsBoundaryWordChar(node.Ch): - case RegexNodeKind.ECMABoundary when node.M > 0 && RegexCharClass.IsECMAWordChar(node.Ch): - case RegexNodeKind.NonECMABoundary when node.M > 0 && !RegexCharClass.IsECMAWordChar(node.Ch): // The loop can be made atomic based on this subsequent node, but we'll need to evaluate the next one as well. break; @@ -2177,14 +2403,61 @@ private static bool CanBeMadeAtomic(RegexNode node, RegexNode subsequent, bool i case RegexNodeKind.Multi when !RegexCharClass.CharInClass(subsequent.Str![0], node.Str!): case RegexNodeKind.End: case RegexNodeKind.EndZ or RegexNodeKind.Eol when !RegexCharClass.CharInClass('\n', node.Str!): + case RegexNodeKind.Boundary when node.M > 0 && RegexCharClass.IsKnownWordClassSubset(node.Str!): + case RegexNodeKind.NonBoundary when node.M > 0 && node.Str is RegexCharClass.NotWordClass or RegexCharClass.NotDigitClass: + case RegexNodeKind.ECMABoundary when node.M > 0 && node.Str is RegexCharClass.ECMAWordClass or RegexCharClass.ECMADigitClass: + case RegexNodeKind.NonECMABoundary when node.M > 0 && node.Str is RegexCharClass.NotECMAWordClass or RegexCharClass.NotDigitClass: return true; case RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic when subsequent.M == 0 && !RegexCharClass.CharInClass(subsequent.Ch, node.Str!): case RegexNodeKind.Setlazy or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic when subsequent.M == 0 && !RegexCharClass.MayOverlap(node.Str!, subsequent.Str!): - case RegexNodeKind.Boundary when node.M > 0 && node.Str is RegexCharClass.WordClass or RegexCharClass.DigitClass: - case RegexNodeKind.NonBoundary when node.M > 0 && node.Str is RegexCharClass.NotWordClass or RegexCharClass.NotDigitClass: - case RegexNodeKind.ECMABoundary when node.M > 0 && node.Str is RegexCharClass.ECMAWordClass or RegexCharClass.ECMADigitClass: - case RegexNodeKind.NonECMABoundary when node.M > 0 && node.Str is RegexCharClass.NotECMAWordClass or RegexCharClass.NotDigitClass: + // The loop can be made atomic based on this subsequent node, but we'll need to evaluate the next one as well. + break; + + default: + return false; + } + break; + + case RegexNodeKind.Loop: + case RegexNodeKind.Lazyloop when allowLazy: + // With single character loops (e.g. OneLoop, NotOneLoop, SetLoop), we only need to prove there's no overlap between + // what that single character could be and what comes next. For arbitrary loops, we have more to prove. First, we need + // to understand what the loop can possibly start with and what it can possibly end with (with a single character loop, + // those are the same things), and we need to ensure that there's no overlap between those two sets; otherwise, a second + // iteration of a loop could end up giving back characters that could be consumed by the previous iteration. Second, we need + // to ensure that neither the starting set nor the ending set overlaps with what could possibly come after it, for the same reason. + RegexNode loopChild = node.Child(0); + if (RegexPrefixAnalyzer.FindFirstCharClass(loopChild) is not string loopStartingSet || + RegexPrefixAnalyzer.FindLastCharClass(loopChild) is not string loopEndingSet || + (node.N > 1 && RegexCharClass.MayOverlap(loopStartingSet, loopEndingSet))) + { + return false; + } + + bool CharInStartingOrEndingSet(char ch) => + RegexCharClass.CharInClass(ch, loopStartingSet) || RegexCharClass.CharInClass(ch, loopEndingSet); + + bool MayOverlapStartingOrEndingSet(string set) => + RegexCharClass.MayOverlap(set, loopStartingSet) || RegexCharClass.MayOverlap(set, loopEndingSet); + + switch (subsequent.Kind) + { + case RegexNodeKind.One when !CharInStartingOrEndingSet(subsequent.Ch): + case RegexNodeKind.Set when !MayOverlapStartingOrEndingSet(subsequent.Str!): + case RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic when subsequent.M > 0 && !CharInStartingOrEndingSet(subsequent.Ch): + case RegexNodeKind.Setlazy or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic when subsequent.M > 0 && !MayOverlapStartingOrEndingSet(subsequent.Str!): + case RegexNodeKind.Multi when !CharInStartingOrEndingSet(subsequent.Str![0]): + case RegexNodeKind.End: + case RegexNodeKind.EndZ or RegexNodeKind.Eol when !CharInStartingOrEndingSet('\n'): + case RegexNodeKind.Boundary when node.M > 0 && RegexCharClass.IsKnownWordClassSubset(loopStartingSet) && RegexCharClass.IsKnownWordClassSubset(loopEndingSet): + case RegexNodeKind.NonBoundary when node.M > 0 && (loopStartingSet is RegexCharClass.NotWordClass or RegexCharClass.NotDigitClass) && (loopEndingSet is RegexCharClass.NotWordClass or RegexCharClass.NotDigitClass): + case RegexNodeKind.ECMABoundary when node.M > 0 && (loopStartingSet is RegexCharClass.ECMAWordClass or RegexCharClass.ECMADigitClass) && (loopEndingSet is RegexCharClass.ECMAWordClass or RegexCharClass.ECMADigitClass): + case RegexNodeKind.NonECMABoundary when node.M > 0 && (loopStartingSet is RegexCharClass.NotECMAWordClass or RegexCharClass.NotDigitClass) && (loopEndingSet is RegexCharClass.NotECMAWordClass or RegexCharClass.NotDigitClass): + return true; + + case RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic when subsequent.M == 0 && !CharInStartingOrEndingSet(subsequent.Ch): + case RegexNodeKind.Setlazy or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic when subsequent.M == 0 && !MayOverlapStartingOrEndingSet(subsequent.Str!): // The loop can be made atomic based on this subsequent node, but we'll need to evaluate the next one as well. break; @@ -2248,6 +2521,55 @@ private static bool CanBeMadeAtomic(RegexNode node, RegexNode subsequent, bool i } } + /// Gets whether this node is known to be immediately preceded by a word character. + public bool IsKnownPrecededByWordChar() => IsKnownPrecededOrSucceededByWordChar(false); + + /// Gets whether this node is known to be immediately succeeded by a word character. + public bool IsKnownSucceededByWordChar() => IsKnownPrecededOrSucceededByWordChar(true); + + private bool IsKnownPrecededOrSucceededByWordChar(bool succeeded) + { + RegexNode node = this; + Debug.Assert(node.Kind is not RegexNodeKind.Concatenate, "The existing logic assumes that the node itself isn't a concatenation."); + + // As in CanBeMadeAtomic, conservatively walk up through a limited set of constructs to the next concatenation. + while (true) + { + if ((node.Options & RegexOptions.RightToLeft) != 0 || + node.Parent is not RegexNode parent) + { + return false; + } + + switch (parent.Kind) + { + case RegexNodeKind.Atomic: + case RegexNodeKind.Alternate: + case RegexNodeKind.Capture: + node = parent; + continue; + + case RegexNodeKind.Concatenate: + var peers = (List)parent.Children!; + int index = peers.IndexOf(node) + (succeeded ? 1 : -1); + if ((uint)index < (uint)peers.Count) + { + // Now that we've found the concatenation, build a set that represents the characters that could come + // before or after this node, depending on whether we're looking for a preceding or succeeding word character. + return + RegexPrefixAnalyzer.FindFirstOrLastCharClass(peers[index], findFirst: succeeded) is string set && + RegexCharClass.IsKnownWordClassSubset(set); + } + + node = parent; + continue; + + default: + return false; + } + } + } + /// Computes a min bound on the required length of any string that could possibly match. /// The min computed length. If the result is 0, there is no minimum we can enforce. /// @@ -2572,25 +2894,10 @@ public bool TryGetOrdinalCaseInsensitiveString(int childIndex, int exclusiveChil // Skip over empty nodes, as they're pure nops. They would ideally have been optimized away, // but can still remain in some situations. } - else if (consumeZeroWidthNodes && - // anchors - child.Kind is RegexNodeKind.Beginning or - RegexNodeKind.Bol or - RegexNodeKind.Start or - // boundaries - RegexNodeKind.Boundary or - RegexNodeKind.ECMABoundary or - RegexNodeKind.NonBoundary or - RegexNodeKind.NonECMABoundary or - // lookarounds - RegexNodeKind.NegativeLookaround or - RegexNodeKind.PositiveLookaround or - // logic - RegexNodeKind.UpdateBumpalong) + else if (consumeZeroWidthNodes && IsZeroWidthAssertion(child.Kind)) { - // Skip over zero-width nodes that might be reasonable at the beginning of or within a substring. - // We can only do these if consumeZeroWidthNodes is true, as otherwise we'd be producing a string that - // may not fully represent the semantics of this portion of the pattern. + // Skip over zero-width nodes. We can only do these if consumeZeroWidthNodes is true, as otherwise we'd + // be producing a string that may not fully represent the semantics of this portion of the pattern. } else { diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParseException.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParseException.cs index fad385a183aaca..e9523dbd986a4a 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParseException.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParseException.cs @@ -32,7 +32,7 @@ internal RegexParseException(RegexParseError error, int offset, string message) Offset = offset; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexPrefixAnalyzer.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexPrefixAnalyzer.cs index 6be7fdda3fc948..40a6affed70314 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexPrefixAnalyzer.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexPrefixAnalyzer.cs @@ -895,13 +895,22 @@ static int GetRangeLength((char LowInclusive, char HighInclusive) range, bool ne }); /// - /// Computes a character class for the first character in tree. This uses a more robust algorithm - /// than is used by TryFindFixedLiterals and thus can find starting sets it couldn't. For example, + /// Computes a character class for the first character in the node. + /// + /// + /// This uses a more robust algorithm than is used by TryFindFixedLiterals and thus can find starting sets it couldn't. For example, /// fixed literals won't find the starting set for a*b, as the a isn't guaranteed and the b is at a /// variable position, but this will find [ab] as it's instead looking for anything that under any /// circumstance could possibly start a match. + /// + public static string? FindFirstCharClass(RegexNode root) => FindFirstOrLastCharClass(root, findFirst: true); + + /// + /// Computes a character class for the last character in the node. /// - public static string? FindFirstCharClass(RegexNode root) + public static string? FindLastCharClass(RegexNode root) => FindFirstOrLastCharClass(root, findFirst: false); + + public static string? FindFirstOrLastCharClass(RegexNode root, bool findFirst) { // Explore the graph, adding found chars into a result set, which is lazily initialized so that // we can initialize it to a parsed set if we discover one first (this is helpful not just for allocation @@ -913,7 +922,7 @@ static int GetRangeLength((char LowInclusive, char HighInclusive) range, bool ne // whole pattern was nullable such that it could match an empty string, in which case we // can't make any statements about what begins a match. RegexCharClass? cc = null; - return TryFindFirstCharClass(root, ref cc) == true ? + return TryFindFirstOrLastCharClass(root, findFirst, ref cc) == true ? cc!.ToStringClass() : null; @@ -930,7 +939,7 @@ static int GetRangeLength((char LowInclusive, char HighInclusive) range, bool ne // it's zero-width (e.g. empty, a lookaround, an anchor, etc.) or it could be zero-width // (e.g. a loop with a min bound of 0). A concatenation processing a child that returns // null needs to keep processing the next child. - static bool? TryFindFirstCharClass(RegexNode node, ref RegexCharClass? cc) + static bool? TryFindFirstOrLastCharClass(RegexNode node, bool findFirst, ref RegexCharClass? cc) { if (!StackHelper.TryEnsureSufficientExecutionStack()) { @@ -992,7 +1001,8 @@ static int GetRangeLength((char LowInclusive, char HighInclusive) range, bool ne if (cc is null || cc.CanMerge) { cc ??= new RegexCharClass(); - cc.AddChar(node.Str![(node.Options & RegexOptions.RightToLeft) != 0 ? node.Str.Length - 1 : 0]); + bool firstChar = findFirst == ((node.Options & RegexOptions.RightToLeft) == 0); + cc.AddChar(node.Str![firstChar ? 0 : node.Str.Length - 1]); return true; } return false; @@ -1019,14 +1029,14 @@ static int GetRangeLength((char LowInclusive, char HighInclusive) range, bool ne // Groups. These don't contribute anything of their own, and are just pass-throughs to their children. case RegexNodeKind.Atomic: case RegexNodeKind.Capture: - return TryFindFirstCharClass(node.Child(0), ref cc); + return TryFindFirstOrLastCharClass(node.Child(0), findFirst, ref cc); // Loops. Like groups, these are mostly pass-through: if the child fails, then the whole operation needs // to fail, and if the child is nullable, then the loop is as well. However, if the child succeeds but // the loop has a lower bound of 0, then the loop is still nullable. case RegexNodeKind.Loop: case RegexNodeKind.Lazyloop: - return TryFindFirstCharClass(node.Child(0), ref cc) switch + return TryFindFirstOrLastCharClass(node.Child(0), findFirst, ref cc) switch { false => false, null => null, @@ -1040,12 +1050,26 @@ static int GetRangeLength((char LowInclusive, char HighInclusive) range, bool ne case RegexNodeKind.Concatenate: { int childCount = node.ChildCount(); - for (int i = 0; i < childCount; i++) + if (findFirst) + { + for (int i = 0; i < childCount; i++) + { + bool? childResult = TryFindFirstOrLastCharClass(node.Child(i), findFirst, ref cc); + if (childResult != null) + { + return childResult; + } + } + } + else { - bool? childResult = TryFindFirstCharClass(node.Child(i), ref cc); - if (childResult != null) + for (int i = childCount - 1; i >= 0; i--) { - return childResult; + bool? childResult = TryFindFirstOrLastCharClass(node.Child(i), findFirst, ref cc); + if (childResult != null) + { + return childResult; + } } } return null; @@ -1060,7 +1084,7 @@ static int GetRangeLength((char LowInclusive, char HighInclusive) range, bool ne bool anyChildWasNull = false; for (int i = 0; i < childCount; i++) { - bool? childResult = TryFindFirstCharClass(node.Child(i), ref cc); + bool? childResult = TryFindFirstOrLastCharClass(node.Child(i), findFirst, ref cc); if (childResult is null) { anyChildWasNull = true; @@ -1078,7 +1102,7 @@ static int GetRangeLength((char LowInclusive, char HighInclusive) range, bool ne case RegexNodeKind.BackreferenceConditional: case RegexNodeKind.ExpressionConditional: int branchStart = node.Kind is RegexNodeKind.BackreferenceConditional ? 0 : 1; - return (TryFindFirstCharClass(node.Child(branchStart), ref cc), TryFindFirstCharClass(node.Child(branchStart + 1), ref cc)) switch + return (TryFindFirstOrLastCharClass(node.Child(branchStart), findFirst, ref cc), TryFindFirstOrLastCharClass(node.Child(branchStart + 1), findFirst, ref cc)) switch { (false, _) or (_, false) => false, (null, _) or (_, null) => null, @@ -1330,8 +1354,6 @@ private static RegexNodeKind FindLeadingOrTrailingAnchor(RegexNode node, bool le case RegexNodeKind.Start: case RegexNodeKind.EndZ: case RegexNodeKind.End: - case RegexNodeKind.Boundary: - case RegexNodeKind.ECMABoundary: // Return any anchor found. return node.Kind; @@ -1365,6 +1387,7 @@ private static RegexNodeKind FindLeadingOrTrailingAnchor(RegexNode node, bool le { case RegexNodeKind.Empty or RegexNodeKind.NegativeLookaround: case RegexNodeKind.PositiveLookaround when ((node.Options | tmpChild.Options) & RegexOptions.RightToLeft) != 0: + case RegexNodeKind.Boundary or RegexNodeKind.ECMABoundary or RegexNodeKind.NonBoundary or RegexNodeKind.NonECMABoundary: // Skip over zero-width assertions. continue; diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexRunner.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexRunner.cs index f07f0c821d0fb0..2e699c8e85a8d4 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexRunner.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexRunner.cs @@ -418,6 +418,21 @@ internal static bool IsBoundary(ReadOnlySpan inputSpan, int index) ((uint)index < (uint)inputSpan.Length && RegexCharClass.IsBoundaryWordChar(inputSpan[index])); } + /// Determines whether the specified index is a boundary.", + /// This variant is only employed when the subsequent character will separately be validated as a word character.", + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool IsPreWordCharBoundary(ReadOnlySpan inputSpan, int index) + { + int indexMinus1 = index - 1; + return (uint)indexMinus1 >= (uint)inputSpan.Length || !RegexCharClass.IsBoundaryWordChar(inputSpan[indexMinus1]); + } + + /// Determines whether the specified index is a boundary. + /// This variant is only employed when the previous character has already been validated as a word character. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool IsPostWordCharBoundary(ReadOnlySpan inputSpan, int index) => + (uint)index >= (uint)inputSpan.Length || !RegexCharClass.IsBoundaryWordChar(inputSpan[index]); + /// Called to determine a char's inclusion in the \w set. internal static bool IsWordChar(char ch) => RegexCharClass.IsWordChar(ch); diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/CharSetSolver.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/CharSetSolver.cs index d4240f61c1c320..e1af700b8db8ef 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/CharSetSolver.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/CharSetSolver.cs @@ -18,9 +18,6 @@ internal sealed class CharSetSolver : ISolver /// BDD for each ASCII character that returns true for that one character. /// This cache is shared amongst all CharSetSolver instances and is accessed in a thread-safe manner. private static readonly BDD?[] s_asciiCache = new BDD[128]; - /// BDD that returns true for every non-ASCII character. - /// This instance is shared amongst all CharSetSolver instances and is accessed in a thread-safe manner. - private static BDD? s_nonAscii; /// Cache of BDD instances created by this solver. /// @@ -38,12 +35,6 @@ internal sealed class CharSetSolver : ISolver /// private readonly Dictionary<(int op, BDD a, BDD? b), BDD> _operationCache = new(); // op is BooleanOperation; using int to reuse generic instantiation with _bddCache - /// Gets a BDD that contains every non-ASCII character. - public BDD NonAscii => - s_nonAscii ?? - Interlocked.CompareExchange(ref s_nonAscii, CreateBDDFromRange('\x80', '\uFFFF'), null) ?? - s_nonAscii; - /// Creates a BDD that contains only the specified character. public BDD CreateBDDFromChar(char c) { diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/SymbolicRegexBuilder.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/SymbolicRegexBuilder.cs index e33940b979707f..c71441a24a00a3 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/SymbolicRegexBuilder.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/SymbolicRegexBuilder.cs @@ -24,32 +24,15 @@ internal sealed class SymbolicRegexBuilder where TSet : IComparable, internal readonly SymbolicRegexNode _anyStar; internal readonly SymbolicRegexNode _anyStarLazy; - private SymbolicRegexNode? _epsilon; - internal SymbolicRegexNode Epsilon => _epsilon ??= SymbolicRegexNode.CreateEpsilon(this); - - private SymbolicRegexNode? _beginningAnchor; - internal SymbolicRegexNode BeginningAnchor => _beginningAnchor ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.BeginningAnchor); - - private SymbolicRegexNode? _endAnchor; - internal SymbolicRegexNode EndAnchor => _endAnchor ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.EndAnchor); - - private SymbolicRegexNode? _endAnchorZ; - internal SymbolicRegexNode EndAnchorZ => _endAnchorZ ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.EndAnchorZ); - - private SymbolicRegexNode? _endAnchorZReverse; - internal SymbolicRegexNode EndAnchorZReverse => _endAnchorZReverse ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.EndAnchorZReverse); - - private SymbolicRegexNode? _bolAnchor; - internal SymbolicRegexNode BolAnchor => _bolAnchor ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.BOLAnchor); - - private SymbolicRegexNode? _eolAnchor; - internal SymbolicRegexNode EolAnchor => _eolAnchor ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.EOLAnchor); - - private SymbolicRegexNode? _wbAnchor; - internal SymbolicRegexNode BoundaryAnchor => _wbAnchor ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.BoundaryAnchor); - - private SymbolicRegexNode? _nwbAnchor; - internal SymbolicRegexNode NonBoundaryAnchor => _nwbAnchor ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.NonBoundaryAnchor); + internal SymbolicRegexNode Epsilon => field ??= SymbolicRegexNode.CreateEpsilon(this); + internal SymbolicRegexNode BeginningAnchor => field ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.BeginningAnchor); + internal SymbolicRegexNode EndAnchor => field ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.EndAnchor); + internal SymbolicRegexNode EndAnchorZ => field ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.EndAnchorZ); + internal SymbolicRegexNode EndAnchorZReverse => field ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.EndAnchorZReverse); + internal SymbolicRegexNode BolAnchor => field ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.BOLAnchor); + internal SymbolicRegexNode EolAnchor => field ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.EOLAnchor); + internal SymbolicRegexNode BoundaryAnchor => field ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.BoundaryAnchor); + internal SymbolicRegexNode NonBoundaryAnchor => field ??= SymbolicRegexNode.CreateAnchor(this, SymbolicRegexNodeKind.NonBoundaryAnchor); internal TSet _wordLetterForBoundariesSet; internal TSet _newLineSet; diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/UnicodeCategoryConditions.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/UnicodeCategoryConditions.cs index 6ad4f5a526c4be..f8679bd76b051b 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/UnicodeCategoryConditions.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/UnicodeCategoryConditions.cs @@ -15,8 +15,6 @@ internal static class UnicodeCategoryConditions /// Array containing lazily-initialized BDDs per defined UnicodeCategory value. private static readonly BDD?[] s_categories = new BDD[UnicodeCategoryValueCount]; - /// Lazily-initialized BDD for \s. - private static volatile BDD? s_whiteSpace; /// Lazily-initialized BDD for \w. private static volatile BDD? s_wordLetter; /// Lazily-initialized BDD for \b. @@ -39,9 +37,9 @@ public static BDD GetCategory(UnicodeCategory category) => /// Gets a that represents the \s character class. public static BDD WhiteSpace => - s_whiteSpace ?? - Interlocked.CompareExchange(ref s_whiteSpace, BDD.Deserialize(UnicodeCategoryRanges.SerializedWhitespaceBDD), null) ?? - s_whiteSpace; + field ?? + Interlocked.CompareExchange(ref field, BDD.Deserialize(UnicodeCategoryRanges.SerializedWhitespaceBDD), null) ?? + field; /// Gets a that represents the \w character class. /// \w is the union of the 8 categories: 0,1,2,3,4,5,8,18 diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/GeneratedRegexAttributeTests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/GeneratedRegexAttributeTests.cs index 1997be9e66d5aa..b353211e5ef8d4 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/GeneratedRegexAttributeTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/GeneratedRegexAttributeTests.cs @@ -12,7 +12,7 @@ public class GeneratedRegexAttributeTests [InlineData(null, RegexOptions.None, Timeout.Infinite)] [InlineData("", (RegexOptions)12345, -2)] [InlineData("a.*b", RegexOptions.Compiled | RegexOptions.CultureInvariant, 1)] - public void Ctor_Roundtrips(string pattern, RegexOptions options, int matchTimeoutMilliseconds) + public void Ctor_Roundtrips(string? pattern, RegexOptions options, int matchTimeoutMilliseconds) { GeneratedRegexAttribute a; diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Tests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Tests.cs index df8858c9813833..01553e0659b850 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Tests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Tests.cs @@ -93,6 +93,55 @@ public static IEnumerable Match_MemberData() yield return (@"(?:(?!(b)b)\1a)*", "babababa", RegexOptions.None, 0, 8, true, string.Empty); yield return (@"(.*?)a(?!(a+)b\2c)\2(.*)", "baaabaac", RegexOptions.None, 0, 8, false, string.Empty); yield return (@"(?!(abc))+\w\w\w", "abcdef", RegexOptions.None, 0, 6, true, "bcd"); + yield return (@"a+(?!c)", "aaab", RegexOptions.None, 0, 4, true, "aaa"); + yield return (@"a+(?!c)", "aaac", RegexOptions.None, 0, 4, true, "aa"); + yield return (@"a*(?!c)", "aaab", RegexOptions.None, 0, 4, true, "aaa"); + yield return (@"a{2,5}(?!c)", "aaaaac", RegexOptions.None, 0, 6, true, "aaaa"); + yield return (@"a+?(?!c)", "aaab", RegexOptions.None, 0, 4, true, "a"); + yield return (@"a*?(?!c)", "aaab", RegexOptions.None, 0, 4, true, ""); + yield return (@"a{2,5}?(?!c)", "aaaaab", RegexOptions.None, 0, 6, true, "aa"); + yield return (@"[ab]*(?!x)", "ababc", RegexOptions.None, 0, 5, true, "abab"); + yield return (@"a+(?=b)(?!c)", "aabx", RegexOptions.None, 0, 4, true, "aa"); + yield return (@"a+?(?=b)(?!c)", "aabx", RegexOptions.None, 0, 4, true, "aa"); + + // Zero-width positive lookahead assertion + yield return (@"(?=(abc))?\1", "abc", RegexOptions.None, 0, 3, true, "abc"); + yield return (@"(?=(abc))+\1", "abc", RegexOptions.None, 0, 3, true, "abc"); + yield return (@"(?=(abc))*\1", "abc", RegexOptions.None, 0, 3, true, "abc"); + yield return (@"^.*?(?=.)b", "ab", RegexOptions.None, 0, 2, true, "ab"); + yield return (@".*?(?=.)b", "ab", RegexOptions.None, 0, 2, true, "ab"); + yield return (@"^(?>.*?)(?=.)b", "ab", RegexOptions.None, 0, 2, false, ""); + yield return (@"(?>.*?)(?=.)b", "ab", RegexOptions.None, 0, 2, true, "b"); + yield return (@"a+(?=b)", "aaab", RegexOptions.None, 0, 4, true, "aaa"); + yield return (@"a+(?=b)", "aaabc", RegexOptions.None, 0, 5, true, "aaa"); + yield return (@"a*(?=b)", "aaab", RegexOptions.None, 0, 4, true, "aaa"); + yield return (@"a{2,5}(?=b)", "aaaaab", RegexOptions.None, 0, 6, true, "aaaaa"); + yield return (@"a+?(?=b)", "aaab", RegexOptions.None, 0, 4, true, "aaa"); + yield return (@"a*?(?=b)", "aaab", RegexOptions.None, 0, 4, true, "aaa"); + yield return (@"a{2,5}?(?=b)", "aaaaab", RegexOptions.None, 0, 6, true, "aaaaa"); + yield return (@"a+b+(?=c)", "aabbbc", RegexOptions.None, 0, 6, true, "aabbb"); + yield return (@"a+?b+(?=c)", "aabbbc", RegexOptions.None, 0, 6, true, "aabbb"); + yield return (@"a+b+?(?=c)", "aabbbc", RegexOptions.None, 0, 6, true, "aabbb"); + yield return (@"[ab]+(?=c)", "ababc", RegexOptions.None, 0, 5, true, "abab"); + yield return (@"[ab]+?(?=c)", "ababc", RegexOptions.None, 0, 5, true, "abab"); + yield return (@"\w+(?=\b)", "hello world", RegexOptions.None, 0, 11, true, "hello"); + yield return (@"\w+?(?=\b)", "hello world", RegexOptions.None, 0, 11, true, "hello"); + yield return (@"(?>a+)(?=b)", "aaab", RegexOptions.None, 0, 4, true, "aaa"); + yield return (@"(?>a*)(?=b)", "aaab", RegexOptions.None, 0, 4, true, "aaa"); + yield return (@"(?>a{2,5})(?=b)", "aaaaab", RegexOptions.None, 0, 6, true, "aaaaa"); + yield return (@"a*(?=a)", "aaa", RegexOptions.None, 0, 3, true, "aa"); + yield return (@"a*?(?=a)", "aaa", RegexOptions.None, 0, 3, true, ""); + yield return (@"a+(?=a*b)ab", "aaaab", RegexOptions.None, 0, 5, true, "aaaab"); + yield return (@"a+?(?=a*b)ab", "aaaab", RegexOptions.None, 0, 5, true, "aaaab"); + yield return (@"(a+)+(?=b)", "aaab", RegexOptions.None, 0, 4, true, "aaa"); + yield return (@"(a+?)+(?=b)", "aaab", RegexOptions.None, 0, 4, true, "aaa"); + yield return (@"(a+)+?(?=b)", "aaab", RegexOptions.None, 0, 4, true, "aaa"); + yield return (@"(a+|b+)(?=c)", "aaac", RegexOptions.None, 0, 4, true, "aaa"); + yield return (@"(a+?|b+?)(?=c)", "aaac", RegexOptions.None, 0, 4, true, "aaa"); + yield return (@"(a+)(?=\1b)", "aaaaaab", RegexOptions.None, 0, 7, true, "aaa"); + yield return (@"(a+?)(?=\1b)", "aaaaaab", RegexOptions.None, 0, 7, true, "aaa"); + yield return (@"[A-Z]+(?=b)", "AAAb", RegexOptions.IgnoreCase, 0, 4, true, "AAA"); + yield return (@"[A-Z]+?(?=b)", "AAAb", RegexOptions.IgnoreCase, 0, 4, true, "AAA"); // Zero-width positive lookbehind assertion yield return (@"(\w){6}(?<=XXX)def", "abcXXXdef", RegexOptions.None, 0, 9, true, "abcXXXdef"); @@ -121,6 +170,21 @@ public static IEnumerable Match_MemberData() yield return (@"(\w)*?3(?<=33)$", "1233", RegexOptions.None, 0, 4, true, "1233"); yield return (@"(?=(\d))4\1", "44", RegexOptions.None, 0, 2, true, "44"); yield return (@"(?=(\d))4\1", "43", RegexOptions.None, 0, 2, false, ""); + yield return (@"(?<=()??)a", "a", RegexOptions.None, 0, 1, true, "a"); + yield return (@"(?<=()*?)a", "a", RegexOptions.None, 0, 1, true, "a"); + yield return (@"(?<=(){0,100}?)a", "a", RegexOptions.None, 0, 1, true, "a"); + yield return (@"(? Match_MemberData() yield return (@"(abc)\w(?[0-9]+)3" // The last 3 causes the match to fail, since the non backtracking subexpression does not give up the last digit it matched @@ -260,6 +329,20 @@ public static IEnumerable Match_MemberData() yield return (@"(b|a|aa)((?:aa)+?)+?$", "aaaaaaaa", RegexOptions.None, 0, 8, true, "aaaaaaaa"); yield return (@"(|a|aa)(((?:aa)+?)+?|aaaaab)\w$", "aaaaaabc", RegexOptions.None, 0, 8, true, "aaaaaabc"); + // Nested loops + yield return (@"(abcd*)+e", "abcde", RegexOptions.None, 0, 5, true, "abcde"); + yield return (@"(abcd*?)+e", "abcde", RegexOptions.None, 0, 5, true, "abcde"); + yield return (@"(abcd*)+?e", "abcde", RegexOptions.None, 0, 5, true, "abcde"); + yield return (@"(abcd*?)+?e", "abcde", RegexOptions.None, 0, 5, true, "abcde"); + yield return (@"(?:m(?:((e)?)??)|a)\b", "you m you", RegexOptions.None, 0, 9, true, "m"); + yield return (@"(?:m(?:((e)?)??)|a)\b", "you me you", RegexOptions.None, 0, 10, true, "me"); + yield return (@"(?:m(?:((e)?)??)|a)\b", "you a you", RegexOptions.None, 0, 9, true, "a"); + yield return (@"(?:m(?:((e)?)??)|a)\b", "you and you", RegexOptions.None, 0, 11, false, ""); + yield return (@"(?:m(?:|(e)?)|a)\b", "you m you", RegexOptions.None, 0, 9, true, "m"); + yield return (@"(?:m(?:|(e)?)|a)\b", "you me you", RegexOptions.None, 0, 10, true, "me"); + yield return (@"(?:m(?:|(e)?)|a)\b", "you a you", RegexOptions.None, 0, 9, true, "a"); + yield return (@"(?:m(?:|(e)?)|a)\b", "you and you", RegexOptions.None, 0, 11, false, ""); + // Testing selected FindOptimizations finds the right prefix yield return (@"(^|a+)bc", " aabc", RegexOptions.None, 0, 5, true, "aabc"); yield return (@"(^|($|a+))bc", " aabc", RegexOptions.None, 0, 5, true, "aabc"); @@ -1238,7 +1321,7 @@ private async Task Match_TestThatTimeoutHappens(RegexEngine engine) } string input = new string(chars); - Regex re = await RegexHelpers.GetRegexAsync(engine, @"a.{20}^", RegexOptions.None, TimeSpan.FromMilliseconds(10)); + Regex re = await RegexHelpers.GetRegexAsync(engine, @"a.{20}^", RegexOptions.None, TimeSpan.FromMilliseconds(1)); Assert.Throws(() => { re.Match(input); }); } diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorOutputTests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorOutputTests.cs index e8896708277097..314f47595f217e 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorOutputTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorOutputTests.cs @@ -367,25 +367,8 @@ file static class Utilities [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool IsWordChar(char ch) { - // Mask of Unicode categories that combine to form [\w] - const int WordCategoriesMask = - 1 << (int)UnicodeCategory.UppercaseLetter | - 1 << (int)UnicodeCategory.LowercaseLetter | - 1 << (int)UnicodeCategory.TitlecaseLetter | - 1 << (int)UnicodeCategory.ModifierLetter | - 1 << (int)UnicodeCategory.OtherLetter | - 1 << (int)UnicodeCategory.NonSpacingMark | - 1 << (int)UnicodeCategory.DecimalDigitNumber | - 1 << (int)UnicodeCategory.ConnectorPunctuation; - - // Bitmap for whether each character 0 through 127 is in [\w] - ReadOnlySpan ascii = new byte[] - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, - 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x07 - }; - // If the char is ASCII, look it up in the bitmap. Otherwise, query its Unicode category. + ReadOnlySpan ascii = WordCharBitmap; int chDiv8 = ch >> 3; return (uint)chDiv8 < (uint)ascii.Length ? (ascii[chDiv8] & (1 << (ch & 0x7))) != 0 : @@ -454,6 +437,24 @@ internal static int ValidateStackCookie(int expected, int actual) } return actual; } + + /// Provides a mask of Unicode categories that combine to form [\w]. + private const int WordCategoriesMask = + 1 << (int)UnicodeCategory.UppercaseLetter | + 1 << (int)UnicodeCategory.LowercaseLetter | + 1 << (int)UnicodeCategory.TitlecaseLetter | + 1 << (int)UnicodeCategory.ModifierLetter | + 1 << (int)UnicodeCategory.OtherLetter | + 1 << (int)UnicodeCategory.NonSpacingMark | + 1 << (int)UnicodeCategory.DecimalDigitNumber | + 1 << (int)UnicodeCategory.ConnectorPunctuation; + + /// Gets a bitmap for whether each character 0 through 127 is in [\w] + private static ReadOnlySpan WordCharBitmap => new byte[] + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, + 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x07 + }; } } """ @@ -789,7 +790,7 @@ partial class C /// [A-Za-z]+
/// Explanation:
/// - /// ○ Match a character in the set [A-Za-z] atomically at least once.
+ /// ○ Match an ASCII letter atomically at least once.
///
///
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Text.RegularExpressions.Generator", "%VERSION%")] @@ -863,7 +864,7 @@ private bool TryFindNextPossibleStartingPosition(ReadOnlySpan inputSpan) // Empty matches aren't possible. if ((uint)pos < (uint)inputSpan.Length) { - // The pattern begins with a character in the set [A-Za-z]. + // The pattern begins with an ASCII letter. // Find the next occurrence. If it can't be found, there's no match. int i = inputSpan.Slice(pos).IndexOfAny(Utilities.s_asciiLetters); if (i >= 0) @@ -887,7 +888,7 @@ private bool TryMatchAtCurrentPosition(ReadOnlySpan inputSpan) int matchStart = pos; ReadOnlySpan slice = inputSpan.Slice(pos); - // Match a character in the set [A-Za-z] atomically at least once. + // Match an ASCII letter atomically at least once. { int iteration = slice.IndexOfAnyExcept(Utilities.s_asciiLetters); if (iteration < 0) diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/UpgradeToGeneratedRegexAnalyzerTests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/UpgradeToGeneratedRegexAnalyzerTests.cs index 1d87d6c6cc0009..c019531af8f9cf 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/UpgradeToGeneratedRegexAnalyzerTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/UpgradeToGeneratedRegexAnalyzerTests.cs @@ -86,7 +86,9 @@ public async Task TopLevelStatements(InvocationType invocationType) string test = @"using System.Text.RegularExpressions; var isMatch = [|" + ConstructRegexInvocation(invocationType, pattern: "\"\"") + @"|]" + isMatchInvocation + ";"; string fixedCode = @"using System.Text.RegularExpressions; -var isMatch = MyRegex().IsMatch(""""); partial class Program +var isMatch = MyRegex().IsMatch(""""); + +partial class Program { [GeneratedRegex("""")] private static partial Regex MyRegex(); @@ -552,7 +554,7 @@ public static IEnumerable MixedConstantTestData() foreach (InvocationType invocationType in new[] { InvocationType.Constructor, InvocationType.StaticMethods }) { string isMatchInvocation = invocationType == InvocationType.Constructor ? @".IsMatch("""")" : string.Empty; - + // Test both pattern and options as field constants (both should be preserved) yield return new object[] { @"using System.Text.RegularExpressions; @@ -685,7 +687,7 @@ public static IEnumerable StaticFieldConstantTestData() foreach (InvocationType invocationType in new[] { InvocationType.Constructor, InvocationType.StaticMethods }) { string isMatchInvocation = invocationType == InvocationType.Constructor ? @".IsMatch("""")" : string.Empty; - + // Test static field constants (should be preserved) yield return new object[] { @"using System.Text.RegularExpressions; @@ -1095,7 +1097,9 @@ public async Task TopLevelStatements_MultipleSourceFiles() }, FixedState = { - Sources = { "public class C { }", @"var r = MyRegex(); partial class Program + Sources = { "public class C { }", @"var r = MyRegex(); + +partial class Program { [System.Text.RegularExpressions.GeneratedRegex("""")] private static partial System.Text.RegularExpressions.Regex MyRegex(); diff --git a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/RegexCharClassTests.cs b/src/libraries/System.Text.RegularExpressions/tests/UnitTests/RegexCharClassTests.cs index 41a51d93497a96..b9156c52d2293f 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/RegexCharClassTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/UnitTests/RegexCharClassTests.cs @@ -28,6 +28,7 @@ public class RegexCharClassTests [InlineData(@"[\p{IsGreek}]", @"[\u0370-\u03FF]")] [InlineData(@"[\0-ad-\uFFFF]", @"[^bc]")] [InlineData(@"[\0-ad-\uFFFF-[a-d]]", @"[\0-ad-\uFFFF-[a-d]]")] + [InlineData(@"[- _,|]", @"[ ,\-_|]")] public void DescribeSet(string set, string expected) { RegexNode setNode = RegexParser.Parse($"{set}", RegexOptions.None, CultureInfo.InvariantCulture).Root.Child(0); diff --git a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/RegexFindOptimizationsTests.cs b/src/libraries/System.Text.RegularExpressions/tests/UnitTests/RegexFindOptimizationsTests.cs index c1030f86b11f1a..856f3d85d52627 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/RegexFindOptimizationsTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/UnitTests/RegexFindOptimizationsTests.cs @@ -34,7 +34,7 @@ public class RegexFindOptimizationsTests [InlineData(@"(?=^)abc", 0, (int)FindNextStartingPositionMode.LeadingAnchor_LeftToRight_Beginning)] [InlineData(@"(?=.*$)abc", 0, (int)FindNextStartingPositionMode.LeadingString_LeftToRight)] [InlineData(@"(?=^)abc", (int)RegexOptions.RightToLeft, (int)FindNextStartingPositionMode.LeadingString_RightToLeft)] - [InlineData(@"abc(?=^)", (int)RegexOptions.RightToLeft, (int)FindNextStartingPositionMode.LeadingString_RightToLeft)] + [InlineData(@"abc(?=^)", (int)RegexOptions.RightToLeft, (int)FindNextStartingPositionMode.LeadingAnchor_RightToLeft_Beginning)] [InlineData(@"(?(?>(?>(?>))))", "")] [InlineData("(?>(?>(?>(?>(?!)))))", "(?!)")] [InlineData("(?=(?>))", "")] + // Lookaround reduction + [InlineData("(?!(abc))", "(?!abc)")] + [InlineData("(?!a(b*)c)", "(?!ab*c)")] + [InlineData("(?!a((((b))))c)", "(?!abc)")] + [InlineData(@"(?=(?=(?=abc)))", @"(?=abc)")] + [InlineData(@"(?=(?<=(?=abc)))", @"(?<=(?=abc))")] + [InlineData(@"(?=\G)abc", @"\Gabc")] + [InlineData(@"(?=^)abc", @"^abc")] + [InlineData(@"(?=\b)abc", @"\babc")] + [InlineData(@"abc(?=\z)", @"abc\z")] + [InlineData(@"abc(?=\Z)", @"abc\Z")] + [InlineData(@"abc(?=\A)", @"abc\A")] + [InlineData(@"abc(?=$)", @"abc$")] + [InlineData(@"a*(?=b)bcd", @"(?>a*)(?=b)bcd")] + [InlineData(@"a*(?=b)a", @"(?>a*)(?=b)a")] + [InlineData(@"a+(?=\b)a", @"(?>a+)(?=\b)a")] + [InlineData(@"(?=(?!abc))", @"(?!abc)")] + [InlineData(@"(?=(?:abc))", @"(?=abc)")] + [InlineData(@"(?!((?:a)b(?:c)))", @"(?!abc)")] + [InlineData(@"(?=abc|abd)", @"(?=ab[cd])")] + [InlineData(@"(?!abc|abd)", @"(?!ab[cd])")] + [InlineData(@"(?.*)\n")] + [InlineData(@".*\n+", @"(?>.*)(?>\n+)")] + [InlineData(@"(?((?=a))b)", @"(?((?=a))b|)")] + [InlineData(@"(?((?!a))b)", @"(?((?!a))b|)")] // Alternation reduction [InlineData("a|b", "[ab]")] [InlineData("a|b|c|d|e|g|h|z", "[a-eghz]")] [InlineData("a|b|c|def|g|h", "(?>[a-c]|def|[gh])")] + [InlineData("a|[^a]", @"[\s\S]")] + [InlineData(".|\n", @"[\s\S]")] + [InlineData(".|\n|a", @"[\s\S]")] + [InlineData("abc|.|\n|def", @"abc|[\s\S]|def")] [InlineData("this|that|there|then|those", "th(?>is|at|ere|en|ose)")] [InlineData("^this|^that|^there|^then|^those", "^th(?>is|at|ere|en|ose)")] [InlineData("\bthis|\bthat|\bthere|\bthen|\bthose", "\bth(?>is|at|ere|en|ose)")] @@ -270,6 +319,21 @@ public class RegexReductionTests [InlineData("abcd|aefg", "a(?>bcd|efg)")] [InlineData("abcd|abc|ab|a", "a(?>bcd|bc|b|)")] [InlineData("^abcd|^abce", "^(?:abc[de])")] + [InlineData("abc|", "(?:abc)?")] + [InlineData("a|", "a?")] + [InlineData("(?:abc|)d", "(?>(?:abc)?)d")] + [InlineData("(?:a|)a", "a{1,2}")] + [InlineData("(?:a|)a*", "a*")] + [InlineData("a+(?:a|)", "a+")] + [InlineData(@"ab*(?=c)", @"a(?>b*)(?=c)")] + [InlineData(@"\d+(?=\D)", @"(?>\d+)(?=\D)")] + [InlineData(@"\D+(?=\d)", @"(?>\D+)(?=\d)")] + [InlineData(@"\s+(?=\S)", @"(?>\s+)(?=\S)")] + [InlineData(@"\S+(?=\s)", @"(?>\S+)(?=\s)")] + [InlineData(@"[^\n]+(?=\n)", @"(?>[^\n]+)(?=\n)")] + [InlineData(@"[a-f]+(?=[^a-f])", @"(?>[a-f]+)(?=[^a-f])")] + [InlineData(@"[0-9]*(?=[^0-9])", @"(?>[0-9]*)(?=[^0-9])")] + [InlineData(@"a*(?=b)(?=bc)", @"(?>a*)(?=b)(?=bc)")] // [InlineData("abcde|abcdef", "abcde(?>|f)")] // TODO https://github.com/dotnet/runtime/issues/66031: Need to reorganize optimizations to avoid an extra Empty being left at the end of the tree [InlineData("abcdef|abcde", "abcde(?>f|)")] [InlineData("abcdef|abcdeg|abcdeh|abcdei|abcdej|abcdek|abcdel", "abcde[f-l]")] @@ -338,9 +402,30 @@ public class RegexReductionTests [InlineData("(a+)b", "((?>a+))b")] [InlineData("a*(?:bcd|efg)", "(?>a*)(?:bcd|efg)")] [InlineData("\\w+\\b", "(?>\\w+)\\b")] + [InlineData("\\w+\\ba", "(?>\\w+)\\ba")] + [InlineData("\\w+\\b\\w", "(?>\\w+)\\b\\w")] [InlineData("\\d+\\b", "(?>\\d+)\\b")] [InlineData("\\W+\\B", "(?>\\W+)\\B")] + [InlineData("\\W+\\B#", "(?>\\W+)\\B#")] + [InlineData("\\W+\\B\\W", "(?>\\W+)\\B\\W")] [InlineData("\\D+\\B", "(?>\\D+)\\B")] + [InlineData(@"[0-9]+\b", @"(?>[0-9]+)\b")] + [InlineData(@"[a-z]+\b", @"(?>[a-z]+)\b")] + [InlineData(@"[A-Z]+\b", @"(?>[A-Z]+)\b")] + [InlineData(@"[a-zA-Z]+\b", @"(?>[a-zA-Z]+)\b")] + [InlineData(@"[a-fA-F0-9]+\b", @"(?>[a-fA-F0-9]+)\b")] + [InlineData(@"[A-F0-9]+\b", @"(?>[A-F0-9]+)\b")] + [InlineData(@"[a-f0-9]+\b", @"(?>[a-f0-9]+)\b")] + [InlineData(@"[\p{L}\d]+\b", @"(?>[\p{L}\d]+)\b")] + [InlineData(@"[\p{L}\p{Mn}]+\b", @"(?>[\p{L}\p{Mn}]+)\b")] + [InlineData(@"\d+\D", @"(?>\d+)\D")] + [InlineData(@"\D+\d", @"(?>\D+)\d")] + [InlineData(@"\s+\S", @"(?>\s+)\S")] + [InlineData(@"\S+\s", @"(?>\S+)\s")] + [InlineData(@"\w+\W", @"(?>\w+)\W")] + [InlineData(@"\W+\w", @"(?>\W+)\w")] + [InlineData(@"\p{C}+\p{L}", @"(?>\p{C}+)\p{L}")] + [InlineData(@"[\p{C}\p{L}]+[\p{N}\p{M}\p{S}\p{Z}]", @"(?>[\p{C}\p{L}]+)[\p{N}\p{M}\p{S}\p{Z}]")] [InlineData("(?:abc*|def*)g", "(?:ab(?>c*)|de(?>f*))g")] [InlineData("(?:a[ce]*|b*)g", "(?:a(?>[ce]*)|(?>b*))g")] [InlineData("(?:a[ce]*|b*)c", "(?:a[ce]*|(?>b*))c")] @@ -352,6 +437,23 @@ public class RegexReductionTests [InlineData("(\\w[bcd]\\s*)*fg", "(\\w[bcd](?>\\s*))*fg")] [InlineData(@"\b(\w+)\b", @"\b((?>\w+))\b")] [InlineData(@"\b(?:\w+)\b ", @"\b(?>\w+)\b ")] + [InlineData("(abc)*", "(?>(abc)*)")] + [InlineData("(abc)*?", "")] + [InlineData("(abc)+d", "(?>(abc)+)d")] + [InlineData("(abc)*d", "(?>(abc)*)d")] + [InlineData("(abc?)*?d", "(ab(?>c?))*?d")] + [InlineData("(ab*c)*d", "(?>(a(?>b*)c)*)d")] + [InlineData("(aba)?d", "(?>(aba)?)d")] + // Anchors + [InlineData(@"\b\b", @"\b")] + [InlineData(@"\b\b\b\b\b", @"\b")] + [InlineData(@"\B\B", @"\B")] + [InlineData(@"^^", @"^")] + [InlineData(@"$", @"$")] + [InlineData(@"\Z\Z", @"\Z")] + [InlineData(@"\z\z", @"\z")] + [InlineData(@"\G\G", @"\G")] + [InlineData(@"\A\A", @"\A")] // Nothing handling [InlineData(@"\wabc(?!)def", "(?!)")] [InlineData(@"\wabc(?!)def|ghi(?!)", "(?!)")] @@ -486,6 +588,42 @@ public void PatternsReduceIdentically(string actual, string expected) [InlineData(@"\d*\b", @"(?>\d*)\b")] [InlineData(@"\W*\B", @"(?>\W*)\B")] [InlineData(@"\D*\B", @"(?>\D*)\B")] + [InlineData(@"\b[a-z ]+\b", @"\b(?>[a-z ]+)\b")] + [InlineData(@"\b[\p{L}\p{Mn}a]+\b", @"\b(?>[\p{L}\p{Mn}a]+)\b")] + [InlineData(@"\b[\p{C}]+\b", @"\b(?>[\p{C}]+)\b")] + [InlineData("(aba)*d", "(?>(aba)*)d")] + [InlineData("(dba)*d", "(?>(dba)*)d")] + [InlineData("(abc?)*?d", "(?>(ab(?>c?))*)d")] + [InlineData("(aba)+d", "(?>(aba)+)d")] + [InlineData("(abc*)*d", "(?>(ab(?>c*))*)d")] + [InlineData(@"a*?(?=b)", @"(?>a*?)(?=b)")] + [InlineData(@"a+?(?=b)", @"(?>a+?)(?=b)")] + [InlineData(@"a{1,3}?(?=b)", @"(?>a{1,3}?)(?=b)")] + [InlineData(@"[ab]*(?=a)", @"(?>[ab]*)(?=a)")] + [InlineData(@"\w*(?=\b)", @"(?>\w*)(?=\b)")] + [InlineData(@".*(?=\b)", @"(?>.*)(?=\b)")] + [InlineData(@".*(?=^)", @"(?>.*)(?=^)")] + [InlineData(@"a*(?<=a)", @"(?>a*)(?<=a)")] + [InlineData(@"a+(?<=a)", @"(?>a+)(?<=a)")] + [InlineData(@"\d*(?<=\d)", @"(?>\d*)(?<=\d)")] + [InlineData(@"[ab]*?(?!a)", @"(?>[ab]*?)(?!a)")] + // Lookaround reduction + [InlineData("(?=(abc))", "(?=abc)")] + [InlineData("(?=a(b*)c)", "(?=ab*c)")] + [InlineData("(?=a((((b))))c)", "(?=abc)")] + [InlineData(@"a*(?=a)", @"(?>a*)(?=a)")] + [InlineData(@"a*(?!b)b", @"(?>a*)(?!b)b")] + [InlineData(@"a*(?a*)(?a*)(?<=b)cde")] + [InlineData(@"a*(?=)a", @"(?>a*)(?=)a")] + [InlineData(@"(?<=(ab))", @"(?<=ab)")] + [InlineData(@"(?=(ab|ac))", @"(?=a[bc])")] + [InlineData(@"(?<=(ab|ac))", @"(?<=a[bc])")] + [InlineData(@"(?=ab)|ac", @"a(?=b|c)")] + [InlineData(@"(?=ab)c", @"a(?=bc)")] + [InlineData(@"(?!ab)c", @"a(?!bc)")] + [InlineData(@"(?=a)(?=b)", @"(?=ab)")] + [InlineData(@"(?!ab)(?!ac)", @"(?!a[bc])")] // Loops inside alternation constructs [InlineData("(abc*|def)chi", "(ab(?>c*)|def)chi")] [InlineData("(abc|def*)fhi", "(abc|de(?>f*))fhi")] @@ -500,6 +638,15 @@ public void PatternsReduceIdentically(string actual, string expected) [InlineData("a*(?(xyz)bcd)", "(?>a*)(?(xyz)bcd)")] // Different prefixes on alternation branches [InlineData("^abcd|$abce", "^abcd|^abce")] + // Zero-width assertions in non-removable loops + [InlineData("a(?=abc)+b", "ab")] + [InlineData("a(?<=abc)+b", "ab")] + [InlineData("a(? + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Threading.AccessControl/src/System.Threading.AccessControl.csproj b/src/libraries/System.Threading.AccessControl/src/System.Threading.AccessControl.csproj index 490a39f7b2f8c1..65bda6f20c5da2 100644 --- a/src/libraries/System.Threading.AccessControl/src/System.Threading.AccessControl.csproj +++ b/src/libraries/System.Threading.AccessControl/src/System.Threading.AccessControl.csproj @@ -68,11 +68,11 @@ System.Security.AccessControl.SemaphoreSecurity - - - - - + + + + + diff --git a/src/libraries/System.Threading.AccessControl/tests/EventWaitHandleAclTests.cs b/src/libraries/System.Threading.AccessControl/tests/EventWaitHandleAclTests.cs index 61cd59035b780d..08c4ffa1b9bd00 100644 --- a/src/libraries/System.Threading.AccessControl/tests/EventWaitHandleAclTests.cs +++ b/src/libraries/System.Threading.AccessControl/tests/EventWaitHandleAclTests.cs @@ -26,7 +26,7 @@ public void EventWaitHandle_Create_NullSecurity() [Theory] [InlineData(null)] [InlineData("")] - public void EventWaitHandle_Create_NameMultipleNew(string name) + public void EventWaitHandle_Create_NameMultipleNew(string? name) { EventWaitHandleSecurity security = GetBasicEventWaitHandleSecurity(); diff --git a/src/libraries/System.Threading.AccessControl/tests/MutexAclTests.cs b/src/libraries/System.Threading.AccessControl/tests/MutexAclTests.cs index 3f90570f68dffb..9354f74fa43f14 100644 --- a/src/libraries/System.Threading.AccessControl/tests/MutexAclTests.cs +++ b/src/libraries/System.Threading.AccessControl/tests/MutexAclTests.cs @@ -21,7 +21,7 @@ public void Mutex_Create_NullSecurity() [Theory] [InlineData(null)] [InlineData("")] - public void Mutex_Create_NameMultipleNew(string name) + public void Mutex_Create_NameMultipleNew(string? name) { MutexSecurity security = GetBasicMutexSecurity(); diff --git a/src/libraries/System.Threading.AccessControl/tests/SemaphoreAclTests.cs b/src/libraries/System.Threading.AccessControl/tests/SemaphoreAclTests.cs index ab3b171d0c53a9..3c085bad3459bb 100644 --- a/src/libraries/System.Threading.AccessControl/tests/SemaphoreAclTests.cs +++ b/src/libraries/System.Threading.AccessControl/tests/SemaphoreAclTests.cs @@ -46,7 +46,7 @@ public void Semaphore_Create_InvalidCounts(int initialCount, int maximumCount) [Theory] [InlineData(null)] [InlineData("")] - public void Semaphore_Create_NameMultipleNew(string name) + public void Semaphore_Create_NameMultipleNew(string? name) { SemaphoreSecurity security = GetBasicSemaphoreSecurity(); bool expectedCreatedNew = true; diff --git a/src/libraries/System.Threading.Channels/System.Threading.Channels.slnx b/src/libraries/System.Threading.Channels/System.Threading.Channels.slnx index d2efdf1d8ffe29..ddebde2143d51d 100644 --- a/src/libraries/System.Threading.Channels/System.Threading.Channels.slnx +++ b/src/libraries/System.Threading.Channels/System.Threading.Channels.slnx @@ -76,6 +76,14 @@ + + + + + + + + @@ -100,6 +108,22 @@ + + + + + + + + + + + + + + + + @@ -165,6 +189,14 @@ + + + + + + + + @@ -189,6 +221,14 @@ + + + + + + + + diff --git a/src/libraries/System.Threading.Channels/ref/System.Threading.Channels.netstandard21.cs b/src/libraries/System.Threading.Channels/ref/System.Threading.Channels.netstandard21.cs index c591bf9888138f..f454c70a23fe32 100644 --- a/src/libraries/System.Threading.Channels/ref/System.Threading.Channels.netstandard21.cs +++ b/src/libraries/System.Threading.Channels/ref/System.Threading.Channels.netstandard21.cs @@ -8,7 +8,7 @@ namespace System.Threading.Channels { public partial class ChannelClosedException : System.InvalidOperationException { -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Threading.Channels/src/System.Threading.Channels.csproj b/src/libraries/System.Threading.Channels/src/System.Threading.Channels.csproj index 1d8a85a73e0259..67fe73b57cd42d 100644 --- a/src/libraries/System.Threading.Channels/src/System.Threading.Channels.csproj +++ b/src/libraries/System.Threading.Channels/src/System.Threading.Channels.csproj @@ -51,16 +51,16 @@ System.Threading.Channel<T> - - - - - - + + + + + + - + diff --git a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/ChannelClosedException.netcoreapp.cs b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/ChannelClosedException.netstandard21.cs similarity index 96% rename from src/libraries/System.Threading.Channels/src/System/Threading/Channels/ChannelClosedException.netcoreapp.cs rename to src/libraries/System.Threading.Channels/src/System/Threading/Channels/ChannelClosedException.netstandard21.cs index 03c846a15a7706..72ef50727c30e8 100644 --- a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/ChannelClosedException.netcoreapp.cs +++ b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/ChannelClosedException.netstandard21.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NET8_0_OR_GREATER +#if NET using System.ComponentModel; #endif using System.Runtime.Serialization; @@ -15,7 +15,7 @@ public partial class ChannelClosedException : InvalidOperationException /// Initializes a new instance of the class with serialized data. /// The object that holds the serialized object data. /// The contextual information about the source or destination. -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/DefaultPartitionedRateLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/DefaultPartitionedRateLimiter.cs index 5c58a1de5970dd..9cb08a5defa7f4 100644 --- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/DefaultPartitionedRateLimiter.cs +++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/DefaultPartitionedRateLimiter.cs @@ -57,7 +57,7 @@ private async Task RunTimer() try { await Heartbeat().ConfigureAwait( -#if NET8_0_OR_GREATER +#if NET ConfigureAwaitOptions.SuppressThrowing #else false diff --git a/src/libraries/System.Threading.Tasks.Dataflow/System.Threading.Tasks.Dataflow.slnx b/src/libraries/System.Threading.Tasks.Dataflow/System.Threading.Tasks.Dataflow.slnx index 36f230ea193450..ae6e016c34f570 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/System.Threading.Tasks.Dataflow.slnx +++ b/src/libraries/System.Threading.Tasks.Dataflow/System.Threading.Tasks.Dataflow.slnx @@ -1,37 +1,394 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.csproj b/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.csproj index 077aa17e391f27..c9de2b40640016 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.csproj +++ b/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.netcoreapp.cs b/src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.netstandard21.cs similarity index 100% rename from src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.netcoreapp.cs rename to src/libraries/System.Threading.Tasks.Dataflow/ref/System.Threading.Tasks.Dataflow.netstandard21.cs diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.IAsyncEnumerable.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.netstandard21.cs similarity index 100% rename from src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.IAsyncEnumerable.cs rename to src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.netstandard21.cs diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/TransformManyBlock.IAsyncEnumerable.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/TransformManyBlock.netstandard21.cs similarity index 100% rename from src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/TransformManyBlock.IAsyncEnumerable.cs rename to src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/TransformManyBlock.netstandard21.cs diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/DataflowEtwProvider.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/DataflowEtwProvider.cs index 7c01b09ed6dcf4..2f17ecf0cc8441 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/DataflowEtwProvider.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/DataflowEtwProvider.cs @@ -102,7 +102,7 @@ internal void TaskLaunchedForMessageHandling( } [Event(TASKLAUNCHED_EVENTID, Level = EventLevel.Informational)] -#if !NET8_0_OR_GREATER +#if !NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif @@ -161,7 +161,7 @@ internal enum BlockCompletionReason } [Event(BLOCKCOMPLETED_EVENTID, Level = EventLevel.Informational)] -#if !NET8_0_OR_GREATER +#if !NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj b/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj index 21e1af10705020..4993c7c3480e7e 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj @@ -23,12 +23,12 @@ System.Threading.Tasks.Dataflow.WriteOnceBlock<T> + - @@ -42,7 +42,7 @@ System.Threading.Tasks.Dataflow.WriteOnceBlock<T> - @@ -76,15 +76,15 @@ System.Threading.Tasks.Dataflow.WriteOnceBlock<T> - - - - - - - - - + + + + + + + + + diff --git a/src/libraries/System.Threading.Tasks.Parallel/System.Threading.Tasks.Parallel.slnx b/src/libraries/System.Threading.Tasks.Parallel/System.Threading.Tasks.Parallel.slnx index 981d6321d2711d..a867c7a2766ddd 100644 --- a/src/libraries/System.Threading.Tasks.Parallel/System.Threading.Tasks.Parallel.slnx +++ b/src/libraries/System.Threading.Tasks.Parallel/System.Threading.Tasks.Parallel.slnx @@ -1,30 +1,274 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj b/src/libraries/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj index 32d0f7c8cf6a3f..ec479f8055b9d1 100644 --- a/src/libraries/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj +++ b/src/libraries/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj @@ -6,11 +6,13 @@ true false + $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) true $(DefineConstants);FEATURE_WASM_MANAGED_THREADS + @@ -21,13 +23,13 @@ - - - - - - - + + + + + + + diff --git a/src/libraries/System.Threading/tests/MutexTests.cs b/src/libraries/System.Threading/tests/MutexTests.cs index 345831191e5066..b52ec093baf367 100644 --- a/src/libraries/System.Threading/tests/MutexTests.cs +++ b/src/libraries/System.Threading/tests/MutexTests.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; +using System.Runtime.Versioning; using System.Threading.Tasks; using Microsoft.DotNet.RemoteExecutor; using Xunit; @@ -250,11 +251,16 @@ public void MutualExclusionTest() public void Ctor_InvalidNames_Unix() { AssertExtensions.Throws("name", null, () => new Mutex(new string('a', 1000), options: default)); + Assert.Throws(() => new Mutex("Foo/Bar", options: default)); + AssertExtensions.Throws("name", null, () => new Mutex("Foo\\Bar", options: default)); + AssertExtensions.Throws("name", null, () => new Mutex("Foo\\Bar", options: new NamedWaitHandleOptions { CurrentSessionOnly = false })); + Assert.Throws(() => new Mutex("Global\\Foo/Bar", options: new NamedWaitHandleOptions { CurrentSessionOnly = false })); + Assert.Throws(() => new Mutex("Global\\Foo\\Bar", options: new NamedWaitHandleOptions { CurrentSessionOnly = false })); } [Theory] [MemberData(nameof(GetValidNames))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/117760",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] public void Ctor_ValidName(string name) { bool createdNew; @@ -336,7 +342,7 @@ public void Ctor_TryCreateGlobalMutexTest_Uwp(bool currentUserOnly, bool current [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [MemberData(nameof(GetValidNames))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/117760",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] public void OpenExisting(string name) { Mutex resultHandle; @@ -369,7 +375,7 @@ public void OpenExisting_InvalidNames() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/117760",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] public void OpenExisting_UnavailableName() { string name = Guid.NewGuid().ToString("N"); @@ -406,7 +412,7 @@ public void NamedWaitHandleOptionsTest() [Theory] [MemberData(nameof(NamePrefixes_MemberData))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/117760",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] public void NameOptionsApiCompatibilityTest(string namePrefix) { string name = Guid.NewGuid().ToString("N"); @@ -468,7 +474,7 @@ public static IEnumerable NamePrefixAndOptionsCompatibilityTest_Member [Theory] [MemberData(nameof(NamePrefixAndOptionsCompatibilityTest_MemberData))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/117760",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] public void NamePrefixAndOptionsCompatibilityTest(bool currentUserOnly, bool currentSessionOnly, string namePrefix) { string name = namePrefix + Guid.NewGuid().ToString("N"); @@ -500,7 +506,7 @@ public static IEnumerable NameNamespaceTests_MemberData() [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoNorServerCore))] // Windows Nano Server and Server Core apparently use the same namespace for the Local\ and Global\ prefixes [MemberData(nameof(NameNamespaceTests_MemberData))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/117760",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] public void NameNamespaceTest( bool create_currentUserOnly, bool create_currentSessionOnly, @@ -615,7 +621,7 @@ public static IEnumerable AbandonExisting_MemberData() [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [MemberData(nameof(AbandonExisting_MemberData))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/117760",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] public void AbandonExisting( string name, WaitHandleWaitType waitType, @@ -871,7 +877,7 @@ private static void IncrementValueInFileNTimes(Mutex mutex, string fileName, int [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [ActiveIssue("https://github.com/dotnet/runtime/issues/96191", TestPlatforms.Browser)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/117760",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] public void NamedMutex_ThreadExitDisposeRaceTest() { var mutexName = Guid.NewGuid().ToString("N"); @@ -933,7 +939,7 @@ public void NamedMutex_ThreadExitDisposeRaceTest() } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/114951",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/117760",platforms: TestPlatforms.Android, runtimes: TestRuntimes.CoreCLR)] public void NamedMutex_DisposeWhenLockedRaceTest() { var mutexName = Guid.NewGuid().ToString("N"); @@ -971,9 +977,118 @@ public void NamedMutex_DisposeWhenLockedRaceTest() } } + [ConditionalFact(nameof(IsCrossProcessNamedMutexSupported))] + [PlatformSpecific(TestPlatforms.AnyUnix)] + public void NamedMutex_OtherEvent_NotCompatible() + { + using Mutex m = new Mutex(Guid.NewGuid().ToString("N"), options: default); + using ManualResetEvent mre = new(false); + + Assert.Throws(() => WaitHandle.WaitAny(new WaitHandle[] { m, mre }, 0)); + } + + private const string GlobalSharedMemoryDirectory = $"/tmp/.dotnet/shm/global"; + private const UnixFileMode AllUsersRwx = + UnixFileMode.UserRead + | UnixFileMode.UserWrite + | UnixFileMode.UserExecute + | UnixFileMode.GroupRead + | UnixFileMode.GroupWrite + | UnixFileMode.GroupExecute + | UnixFileMode.OtherRead + | UnixFileMode.OtherWrite + | UnixFileMode.OtherExecute; + + [ConditionalFact(nameof(IsCrossProcessNamedMutexSupported))] + [PlatformSpecific(TestPlatforms.AnyUnix)] + [UnsupportedOSPlatform("windows")] + public void NamedMutex_InvalidSharedMemoryHeaderVersion() + { + string name = Guid.NewGuid().ToString("N"); + string path = $"{GlobalSharedMemoryDirectory}/{name}"; + + Directory.CreateDirectory(GlobalSharedMemoryDirectory, AllUsersRwx); + using (FileStream fs = new(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096)) + using (BinaryWriter bw = new(fs)) + { + bw.Write((byte)1); // Write the shared memory type (mutex) + bw.Write((byte)2); // Write an invalid version number + // Make the file large enough for a valid named mutex file and divisible by page size (it should always be under one page). + fs.SetLength(Environment.SystemPageSize); + + // Try opening a mutex when we still have the file locked. + Assert.Throws(() => new Mutex($"Global\\{name}", new NamedWaitHandleOptions { CurrentSessionOnly = false, CurrentUserOnly = false })); + } + } + + [ConditionalFact(nameof(IsCrossProcessNamedMutexSupported))] + [PlatformSpecific(TestPlatforms.AnyUnix)] + [UnsupportedOSPlatform("windows")] + public void NamedMutex_SharedMemoryFileAlreadyOpen() + { + string name = Guid.NewGuid().ToString("N"); + string path = $"{GlobalSharedMemoryDirectory}/{name}"; + + Directory.CreateDirectory(GlobalSharedMemoryDirectory, AllUsersRwx); + // Take an exclusive file lock of the global shared memory file. + using (FileStream fs = new(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096)) + using (BinaryWriter bw = new(fs)) + { + bw.Write((byte)1); // Write the shared memory type (mutex) + bw.Write((byte)1); // Write valid version number + // Make the file large enough for a valid named mutex file and divisible by page size (it should always be under one page). + fs.SetLength(Environment.SystemPageSize); + + // Try opening a mutex when we still have the file locked. + Assert.Throws(() => new Mutex($"Global\\{name}", new NamedWaitHandleOptions { CurrentSessionOnly = false, CurrentUserOnly = false })); + } + } + + [ConditionalFact(nameof(IsCrossProcessNamedMutexSupported))] + [PlatformSpecific(TestPlatforms.AnyUnix)] + [UnsupportedOSPlatform("windows")] + public void NamedMutex_InvalidSharedMemoryHeaderKind() + { + string name = Guid.NewGuid().ToString("N"); + string path = $"{GlobalSharedMemoryDirectory}/{name}"; + + Directory.CreateDirectory(GlobalSharedMemoryDirectory, AllUsersRwx); + using (FileStream fs = new(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096)) + using (BinaryWriter bw = new(fs)) + { + bw.Write((byte)2); // Write the shared memory type (invalid) + bw.Write((byte)1); // Write a version number + // Make the file large enough for a valid named mutex file and divisible by page size (it should always be under one page). + fs.SetLength(Environment.SystemPageSize); + // Try opening a mutex when we still have the file locked. + Assert.Throws(() => new Mutex($"Global\\{name}", new NamedWaitHandleOptions { CurrentSessionOnly = false, CurrentUserOnly = false })); + } + } + + [ConditionalFact(nameof(IsCrossProcessNamedMutexSupported))] + [PlatformSpecific(TestPlatforms.AnyUnix)] + [UnsupportedOSPlatform("windows")] + public void NamedMutex_TooSmallSharedMemoryFile() + { + string name = Guid.NewGuid().ToString("N"); + string path = $"{GlobalSharedMemoryDirectory}/{name}"; + + Directory.CreateDirectory(GlobalSharedMemoryDirectory, AllUsersRwx); + using (FileStream fs = new(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096)) + using (BinaryWriter bw = new(fs)) + { + bw.Write((byte)1); // Write the shared memory type (mutex) + bw.Write((byte)1); // Write a valid version number + // Make the file large enough for a valid named mutex file but not divisible by page size. + fs.SetLength(Environment.SystemPageSize - 1); + // Try opening a mutex when we still have the file locked. + Assert.Throws(() => new Mutex($"Global\\{name}", new NamedWaitHandleOptions { CurrentSessionOnly = false, CurrentUserOnly = false })); + } + } + public static TheoryData GetValidNames() { - var names = new TheoryData() { Guid.NewGuid().ToString("N") }; + var names = new TheoryData() { Guid.NewGuid().ToString("N") }; // Windows native named mutexes and in-proc named mutexes support very long (1000+ char) names. // Non-Windows cross-process named mutexes are emulated using file system. It imposes limit diff --git a/src/libraries/System.Threading/tests/SemaphoreSlimTests.cs b/src/libraries/System.Threading/tests/SemaphoreSlimTests.cs index faac4d9cf9f85b..7bdc0fdb60500a 100644 --- a/src/libraries/System.Threading/tests/SemaphoreSlimTests.cs +++ b/src/libraries/System.Threading/tests/SemaphoreSlimTests.cs @@ -60,6 +60,7 @@ public static void RunSemaphoreSlimTest1_Wait() RunSemaphoreSlimTest1_Wait_Helper(10, 10, 10, true, null); RunSemaphoreSlimTest1_Wait_Helper(1, 10, 10, true, null); RunSemaphoreSlimTest1_Wait_Helper(0, 10, 10, false, null); + RunSemaphoreSlimTest1_Wait_Helper(1, 10, TimeSpan.FromMilliseconds(uint.MaxValue), true, null); } [Fact] @@ -67,8 +68,6 @@ public static void RunSemaphoreSlimTest1_Wait_NegativeCases() { // Invalid timeout RunSemaphoreSlimTest1_Wait_Helper(10, 10, -10, true, typeof(ArgumentOutOfRangeException)); - RunSemaphoreSlimTest1_Wait_Helper - (10, 10, new TimeSpan(0, 0, int.MaxValue), true, typeof(ArgumentOutOfRangeException)); } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] @@ -87,6 +86,8 @@ public static void RunSemaphoreSlimTest1_WaitAsync() RunSemaphoreSlimTest1_WaitAsync_Helper(10, 10, 10, true, null); RunSemaphoreSlimTest1_WaitAsync_Helper(1, 10, 10, true, null); RunSemaphoreSlimTest1_WaitAsync_Helper(0, 10, 10, false, null); + RunSemaphoreSlimTest1_WaitAsync_Helper(1, 10, TimeSpan.FromMilliseconds(uint.MaxValue), true, null); + RunSemaphoreSlimTest1_WaitAsync_Helper(1, 10, TimeSpan.MaxValue, true, null); } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] @@ -95,8 +96,6 @@ public static void RunSemaphoreSlimTest1_WaitAsync_NegativeCases() { // Invalid timeout RunSemaphoreSlimTest1_WaitAsync_Helper(10, 10, -10, true, typeof(ArgumentOutOfRangeException)); - RunSemaphoreSlimTest1_WaitAsync_Helper - (10, 10, new TimeSpan(0, 0, int.MaxValue), true, typeof(ArgumentOutOfRangeException)); RunSemaphoreSlimTest1_WaitAsync2(); } diff --git a/src/libraries/System.Transactions.Local/System.Transactions.Local.slnx b/src/libraries/System.Transactions.Local/System.Transactions.Local.slnx index 392e347447f297..c6260171db8a84 100644 --- a/src/libraries/System.Transactions.Local/System.Transactions.Local.slnx +++ b/src/libraries/System.Transactions.Local/System.Transactions.Local.slnx @@ -1,33 +1,1106 @@ + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Transactions.Local/src/System.Transactions.Local.csproj b/src/libraries/System.Transactions.Local/src/System.Transactions.Local.csproj index 60b30c5328717c..fb9e5552476c99 100644 --- a/src/libraries/System.Transactions.Local/src/System.Transactions.Local.csproj +++ b/src/libraries/System.Transactions.Local/src/System.Transactions.Local.csproj @@ -109,20 +109,20 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionManager.cs b/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionManager.cs index e88772583be0f2..b98f51e538188a 100644 --- a/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionManager.cs +++ b/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionManager.cs @@ -279,13 +279,8 @@ internal static IsolationLevel DefaultIsolationLevel } } - - private static DefaultSettingsSection? s_defaultSettings; - private static DefaultSettingsSection DefaultSettings => s_defaultSettings ??= DefaultSettingsSection.GetSection(); - - - private static MachineSettingsSection? s_machineSettings; - private static MachineSettingsSection MachineSettings => s_machineSettings ??= MachineSettingsSection.GetSection(); + private static DefaultSettingsSection DefaultSettings => field ??= DefaultSettingsSection.GetSection(); + private static MachineSettingsSection MachineSettings => field ??= MachineSettingsSection.GetSection(); private static bool s_defaultTimeoutValidated; private static long s_defaultTimeoutTicks; diff --git a/src/libraries/System.Transactions.Local/tests/AsyncTransactionScopeTests.cs b/src/libraries/System.Transactions.Local/tests/AsyncTransactionScopeTests.cs index ff5c050292fcff..c8470d61419659 100644 --- a/src/libraries/System.Transactions.Local/tests/AsyncTransactionScopeTests.cs +++ b/src/libraries/System.Transactions.Local/tests/AsyncTransactionScopeTests.cs @@ -437,7 +437,7 @@ public void AsyncTSTest(int variation) [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(true, false, null)] [InlineData(true, true, null)] - public void AsyncTSAndDependantClone(bool requiresNew, bool synchronizeScope, string txId) + public void AsyncTSAndDependantClone(bool requiresNew, bool synchronizeScope, string? txId) { string txId1 = null; string txId2 = null; @@ -527,7 +527,7 @@ public void AsyncTSAndDependantClone(bool requiresNew, bool synchronizeScope, st [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(true, false, null)] [InlineData(true, true, null)] - public void NestedAsyncTSAndDependantClone(bool parentrequiresNew, bool childRequiresNew, string txId) + public void NestedAsyncTSAndDependantClone(bool parentrequiresNew, bool childRequiresNew, string? txId) { string txId1; string txId2; diff --git a/src/libraries/System.Web.HttpUtility/System.Web.HttpUtility.slnx b/src/libraries/System.Web.HttpUtility/System.Web.HttpUtility.slnx index bc85167d09289b..222b9827e56995 100644 --- a/src/libraries/System.Web.HttpUtility/System.Web.HttpUtility.slnx +++ b/src/libraries/System.Web.HttpUtility/System.Web.HttpUtility.slnx @@ -1,35 +1,298 @@ + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Web.HttpUtility/src/System.Web.HttpUtility.csproj b/src/libraries/System.Web.HttpUtility/src/System.Web.HttpUtility.csproj index 6795e3db21c61b..decd8da944a344 100644 --- a/src/libraries/System.Web.HttpUtility/src/System.Web.HttpUtility.csproj +++ b/src/libraries/System.Web.HttpUtility/src/System.Web.HttpUtility.csproj @@ -17,9 +17,9 @@ - - - + + + diff --git a/src/libraries/System.Web.HttpUtility/tests/HttpUtility/HttpUtilityTest.cs b/src/libraries/System.Web.HttpUtility/tests/HttpUtility/HttpUtilityTest.cs index fb4494072cba6c..5fd9f488da4999 100644 --- a/src/libraries/System.Web.HttpUtility/tests/HttpUtility/HttpUtilityTest.cs +++ b/src/libraries/System.Web.HttpUtility/tests/HttpUtility/HttpUtilityTest.cs @@ -57,7 +57,7 @@ public class HttpUtilityTest [Theory] [InlineData(null, null)] [MemberData(nameof(HtmlAttributeEncodeData))] - public void HtmlAttributeEncode(string expected, string input) + public void HtmlAttributeEncode(string? expected, string? input) { Assert.Equal(expected, HttpUtility.HtmlAttributeEncode(input)); } @@ -74,7 +74,7 @@ public void HtmlAttributeEncode_TextWriter_null() [Theory] [InlineData("", null)] [MemberData(nameof(HtmlAttributeEncodeData))] - public void HtmlAttributeEncode_TextWriter(string expected, string input) + public void HtmlAttributeEncode_TextWriter(string expected, string? input) { var sw = new StringWriter(); HttpUtility.HtmlAttributeEncode(input, sw); @@ -261,7 +261,7 @@ private sealed class NullToString [InlineData(2, "2")] [InlineData("", "")] [InlineData(null, null)] - public void HtmlEncode(object decoded, string encoded) + public void HtmlEncode(object? decoded, string? encoded) { if (decoded is string s) { @@ -635,7 +635,7 @@ public static IEnumerable UrlEncodeData [Theory] [InlineData(null, null)] [MemberData(nameof(UrlEncodeData))] - public void UrlEncode(string decoded, string encoded) + public void UrlEncode(string? decoded, string? encoded) { Assert.Equal(encoded, HttpUtility.UrlEncode(decoded)); } @@ -781,7 +781,7 @@ public void UrlEncodeUnicodeToBytes(string decoded, string encoded) [InlineData("mailto:user@example.net", "mailto:user@example.net")] [InlineData("http://example\u200E.net/", "http://example%e2%80%8e.net/")] [InlineData("http://ex ample\u200E.net/", "http://ex%20ample%e2%80%8e.net/")] - public void UrlPathEncode(string decoded, string encoded) + public void UrlPathEncode(string? decoded, string? encoded) { Assert.Equal(encoded, HttpUtility.UrlPathEncode(decoded)); } diff --git a/src/libraries/System.Windows.Extensions/Directory.Build.props b/src/libraries/System.Windows.Extensions/Directory.Build.props index e7e8cb9ac081be..1de3e8042fb855 100644 --- a/src/libraries/System.Windows.Extensions/Directory.Build.props +++ b/src/libraries/System.Windows.Extensions/Directory.Build.props @@ -3,5 +3,6 @@ Open windows + false \ No newline at end of file diff --git a/src/libraries/System.Windows.Extensions/System.Windows.Extensions.slnx b/src/libraries/System.Windows.Extensions/System.Windows.Extensions.slnx index a1ff20ddf35242..b67b7ac19b5070 100644 --- a/src/libraries/System.Windows.Extensions/System.Windows.Extensions.slnx +++ b/src/libraries/System.Windows.Extensions/System.Windows.Extensions.slnx @@ -77,7 +77,7 @@ - + @@ -85,7 +85,7 @@ - + @@ -93,7 +93,7 @@ - + @@ -101,7 +101,9 @@ - + + + diff --git a/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.cs b/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.cs index b3c5b73533c532..7f19175122174a 100644 --- a/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.cs +++ b/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.cs @@ -11,7 +11,7 @@ public partial class SoundPlayer : System.ComponentModel.Component, System.Runti { public SoundPlayer() { } public SoundPlayer(System.IO.Stream? stream) { } -#if NET8_0_OR_GREATER +#if NET [System.ObsoleteAttribute("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj b/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj index 609bc2999afc44..d55312a08d6c53 100644 --- a/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj +++ b/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj @@ -4,7 +4,6 @@ $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum) $(TargetFrameworks);$(NetCoreAppPrevious)-windows;$(NetCoreAppPrevious) true - false false true Provides miscellaneous Windows-specific types diff --git a/src/libraries/System.Windows.Extensions/src/System/Media/SoundPlayer.cs b/src/libraries/System.Windows.Extensions/src/System/Media/SoundPlayer.cs index 3b3f21c1a1b5e1..cf0189a9b47c30 100644 --- a/src/libraries/System.Windows.Extensions/src/System/Media/SoundPlayer.cs +++ b/src/libraries/System.Windows.Extensions/src/System/Media/SoundPlayer.cs @@ -61,7 +61,7 @@ public SoundPlayer(Stream? stream) : this() _stream = stream; } -#if NET8_0_OR_GREATER +#if NET [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [EditorBrowsable(EditorBrowsableState.Never)] #endif diff --git a/src/libraries/System.Windows.Extensions/src/System/Media/SystemSounds.cs b/src/libraries/System.Windows.Extensions/src/System/Media/SystemSounds.cs index a5042fc0242026..8ccaa446976d34 100644 --- a/src/libraries/System.Windows.Extensions/src/System/Media/SystemSounds.cs +++ b/src/libraries/System.Windows.Extensions/src/System/Media/SystemSounds.cs @@ -5,35 +5,10 @@ namespace System.Media { public static class SystemSounds { - private static SystemSound? s_asterisk; - private static SystemSound? s_beep; - private static SystemSound? s_exclamation; - private static SystemSound? s_hand; - private static SystemSound? s_question; - - public static SystemSound Asterisk - { - get => s_asterisk ??= new SystemSound(Interop.User32.MB_ICONASTERISK); - } - - public static SystemSound Beep - { - get => s_beep ??= new SystemSound(Interop.User32.MB_OK); - } - - public static SystemSound Exclamation - { - get => s_exclamation ??= new SystemSound(Interop.User32.MB_ICONEXCLAMATION); - } - - public static SystemSound Hand - { - get => s_hand ??= new SystemSound(Interop.User32.MB_ICONHAND); - } - - public static SystemSound Question - { - get => s_question ??= new SystemSound(Interop.User32.MB_ICONQUESTION); - } + public static SystemSound Asterisk => field ??= new SystemSound(Interop.User32.MB_ICONASTERISK); + public static SystemSound Beep => field ??= new SystemSound(Interop.User32.MB_OK); + public static SystemSound Exclamation => field ??= new SystemSound(Interop.User32.MB_ICONEXCLAMATION); + public static SystemSound Hand => field ??= new SystemSound(Interop.User32.MB_ICONHAND); + public static SystemSound Question => field ??= new SystemSound(Interop.User32.MB_ICONQUESTION); } } diff --git a/src/libraries/System.Windows.Extensions/tests/System/Media/SoundPlayerTests.cs b/src/libraries/System.Windows.Extensions/tests/System/Media/SoundPlayerTests.cs index 815b7bf479b4fb..8622866a3f95ba 100644 --- a/src/libraries/System.Windows.Extensions/tests/System/Media/SoundPlayerTests.cs +++ b/src/libraries/System.Windows.Extensions/tests/System/Media/SoundPlayerTests.cs @@ -67,7 +67,7 @@ public void Ctor_String(string soundLocation) [Theory] [InlineData(null)] [InlineData("")] - public void Ctor_NullOrEmptyString_ThrowsArgumentException(string soundLocation) + public void Ctor_NullOrEmptyString_ThrowsArgumentException(string? soundLocation) { AssertExtensions.Throws("path", null, () => new SoundPlayer(soundLocation)); } @@ -372,7 +372,7 @@ public void SoundLocation_SetValid_Success(string soundLocation) [Theory] [InlineData(null)] [InlineData("")] - public void SoundLocation_SetNullOrEmpty_ThrowsArgumentException(string soundLocation) + public void SoundLocation_SetNullOrEmpty_ThrowsArgumentException(string? soundLocation) { var player = new SoundPlayer() { SoundLocation = soundLocation }; Assert.Equal("", player.SoundLocation); @@ -423,7 +423,7 @@ public void Stream_SetValid_Success(Stream stream) [Theory] [InlineData(null)] [InlineData("tag")] - public void Tag_Set_GetReturnsExpected(object value) + public void Tag_Set_GetReturnsExpected(object? value) { var player = new SoundPlayer { Tag = value }; Assert.Equal(value, player.Tag); diff --git a/src/libraries/System.Xml.ReaderWriter/System.Xml.ReaderWriter.slnx b/src/libraries/System.Xml.ReaderWriter/System.Xml.ReaderWriter.slnx index 52984cb6636748..7acc17fa775ce7 100644 --- a/src/libraries/System.Xml.ReaderWriter/System.Xml.ReaderWriter.slnx +++ b/src/libraries/System.Xml.ReaderWriter/System.Xml.ReaderWriter.slnx @@ -1,34 +1,1008 @@ + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs b/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs index aa881c6a805c8a..b839aba44ee077 100644 --- a/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs +++ b/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs @@ -2942,6 +2942,7 @@ public XsltSettings() { } public XsltSettings(bool enableDocumentFunction, bool enableScript) { } public static System.Xml.Xsl.XsltSettings Default { get { throw null; } } public bool EnableDocumentFunction { get { throw null; } set { } } + [System.ObsoleteAttribute("XSLT Script blocks are not supported.", DiagnosticId = "SYSLIB0062", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public bool EnableScript { get { throw null; } set { } } public static System.Xml.Xsl.XsltSettings TrustedXslt { get { throw null; } } } diff --git a/src/libraries/System.Xml.ReaderWriter/src/System.Xml.ReaderWriter.csproj b/src/libraries/System.Xml.ReaderWriter/src/System.Xml.ReaderWriter.csproj index 51b5b60bb9bfc9..7a37dfda67fad9 100644 --- a/src/libraries/System.Xml.ReaderWriter/src/System.Xml.ReaderWriter.csproj +++ b/src/libraries/System.Xml.ReaderWriter/src/System.Xml.ReaderWriter.csproj @@ -8,8 +8,9 @@ - - + + + \ No newline at end of file diff --git a/src/libraries/System.Xml.XDocument/System.Xml.XDocument.slnx b/src/libraries/System.Xml.XDocument/System.Xml.XDocument.slnx index dfd9bd0f8f7590..4e10e6a1aebfdc 100644 --- a/src/libraries/System.Xml.XDocument/System.Xml.XDocument.slnx +++ b/src/libraries/System.Xml.XDocument/System.Xml.XDocument.slnx @@ -1,37 +1,1024 @@ + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Xml.XDocument/src/System.Xml.XDocument.csproj b/src/libraries/System.Xml.XDocument/src/System.Xml.XDocument.csproj index 97942db9d60ef6..ae56bcdfc79c15 100644 --- a/src/libraries/System.Xml.XDocument/src/System.Xml.XDocument.csproj +++ b/src/libraries/System.Xml.XDocument/src/System.Xml.XDocument.csproj @@ -8,9 +8,10 @@ - - - + + + + \ No newline at end of file diff --git a/src/libraries/System.Xml.XPath.XDocument/System.Xml.XPath.XDocument.slnx b/src/libraries/System.Xml.XPath.XDocument/System.Xml.XPath.XDocument.slnx index fd1086980a9404..5adce387dc21f6 100644 --- a/src/libraries/System.Xml.XPath.XDocument/System.Xml.XPath.XDocument.slnx +++ b/src/libraries/System.Xml.XPath.XDocument/System.Xml.XPath.XDocument.slnx @@ -1,38 +1,1032 @@ + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Xml.XPath.XDocument/src/System.Xml.XPath.XDocument.csproj b/src/libraries/System.Xml.XPath.XDocument/src/System.Xml.XPath.XDocument.csproj index 3b58b100a3a4ae..935a14e960532c 100644 --- a/src/libraries/System.Xml.XPath.XDocument/src/System.Xml.XPath.XDocument.csproj +++ b/src/libraries/System.Xml.XPath.XDocument/src/System.Xml.XPath.XDocument.csproj @@ -12,9 +12,9 @@ - - - + + + \ No newline at end of file diff --git a/src/libraries/System.Xml.XPath/System.Xml.XPath.slnx b/src/libraries/System.Xml.XPath/System.Xml.XPath.slnx index 62a985e95d154a..13095c72020b04 100644 --- a/src/libraries/System.Xml.XPath/System.Xml.XPath.slnx +++ b/src/libraries/System.Xml.XPath/System.Xml.XPath.slnx @@ -1,35 +1,1016 @@ + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Xml.XPath/src/System.Xml.XPath.csproj b/src/libraries/System.Xml.XPath/src/System.Xml.XPath.csproj index 629bfd44ac5a2c..699a22846c437c 100644 --- a/src/libraries/System.Xml.XPath/src/System.Xml.XPath.csproj +++ b/src/libraries/System.Xml.XPath/src/System.Xml.XPath.csproj @@ -7,8 +7,8 @@ - - + + \ No newline at end of file diff --git a/src/libraries/System.Xml.XmlSerializer/System.Xml.XmlSerializer.slnx b/src/libraries/System.Xml.XmlSerializer/System.Xml.XmlSerializer.slnx index e8869ec061e50e..d620a0742b2dfe 100644 --- a/src/libraries/System.Xml.XmlSerializer/System.Xml.XmlSerializer.slnx +++ b/src/libraries/System.Xml.XmlSerializer/System.Xml.XmlSerializer.slnx @@ -1,39 +1,1016 @@ + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Xml.XmlSerializer/src/System.Xml.XmlSerializer.csproj b/src/libraries/System.Xml.XmlSerializer/src/System.Xml.XmlSerializer.csproj index ed03ce357ec17b..4d607a5fedd83c 100644 --- a/src/libraries/System.Xml.XmlSerializer/src/System.Xml.XmlSerializer.csproj +++ b/src/libraries/System.Xml.XmlSerializer/src/System.Xml.XmlSerializer.csproj @@ -7,8 +7,9 @@ - - + + + \ No newline at end of file diff --git a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml index 4317f49799c665..a0d092eccf48b3 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml +++ b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml @@ -1,6 +1,210 @@  + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorByteNonFaultingZeroExtendToInt16(System.Byte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorByteNonFaultingZeroExtendToInt32(System.Byte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorByteNonFaultingZeroExtendToInt64(System.Byte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorByteNonFaultingZeroExtendToUInt16(System.Byte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorByteNonFaultingZeroExtendToUInt32(System.Byte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorByteNonFaultingZeroExtendToUInt64(System.Byte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorInt16NonFaultingSignExtendToInt32(System.Int16*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorInt16NonFaultingSignExtendToInt64(System.Int16*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorInt16NonFaultingSignExtendToUInt32(System.Int16*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorInt16NonFaultingSignExtendToUInt64(System.Int16*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorInt32NonFaultingSignExtendToInt64(System.Int32*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorInt32NonFaultingSignExtendToUInt64(System.Int32*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorNonFaulting(System.Byte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorNonFaulting(System.Double*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorNonFaulting(System.Int16*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorNonFaulting(System.Int32*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorNonFaulting(System.Int64*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorNonFaulting(System.SByte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorNonFaulting(System.Single*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorNonFaulting(System.UInt16*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorNonFaulting(System.UInt32*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorNonFaulting(System.UInt64*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorSByteNonFaultingSignExtendToInt16(System.SByte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorSByteNonFaultingSignExtendToInt32(System.SByte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorSByteNonFaultingSignExtendToInt64(System.SByte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorSByteNonFaultingSignExtendToUInt16(System.SByte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorSByteNonFaultingSignExtendToUInt32(System.SByte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorSByteNonFaultingSignExtendToUInt64(System.SByte*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorUInt16NonFaultingZeroExtendToInt32(System.UInt16*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorUInt16NonFaultingZeroExtendToInt64(System.UInt16*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorUInt16NonFaultingZeroExtendToUInt32(System.UInt16*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorUInt16NonFaultingZeroExtendToUInt64(System.UInt16*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorUInt32NonFaultingZeroExtendToInt64(System.UInt32*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + + + CP0002 + M:System.Runtime.Intrinsics.Arm.Sve.LoadVectorUInt32NonFaultingZeroExtendToUInt64(System.UInt32*) + net9.0/System.Runtime.Intrinsics.dll + net10.0/System.Runtime.Intrinsics.dll + CP0002 M:System.Runtime.Intrinsics.Arm.Sve.PrefetchBytes(System.Numerics.Vector{System.Byte},System.Void*,System.Runtime.Intrinsics.Arm.SvePrefetchType) @@ -25,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/libraries/oob-ref.proj b/src/libraries/oob-ref.proj deleted file mode 100644 index 33f580285a5fc6..00000000000000 --- a/src/libraries/oob-ref.proj +++ /dev/null @@ -1,17 +0,0 @@ - - - - $(NetCoreAppCurrent) - - true - - - - - - - - diff --git a/src/libraries/sendtohelixhelp.proj b/src/libraries/sendtohelixhelp.proj index 87d3c1d371f808..29ed70e4ff171a 100644 --- a/src/libraries/sendtohelixhelp.proj +++ b/src/libraries/sendtohelixhelp.proj @@ -220,8 +220,8 @@ $(HelixCommand) dotnet dev-certs https && - - $(HelixCommand) powershell -command "New-SelfSignedCertificate -FriendlyName 'ASP.NET Core HTTPS development certificate' -DnsName @('localhost') -Subject 'CN = localhost' -KeyAlgorithm RSA -KeyLength 2048 -HashAlgorithm sha256 -CertStoreLocation 'Cert:\CurrentUser\My' -TextExtension @('2.5.29.37={text}1.3.6.1.5.5.7.3.1','1.3.6.1.4.1.311.84.1.1={hex}02','2.5.29.19={text}') -KeyUsage DigitalSignature,KeyEncipherment" && + + $(HelixCommand) powershell -command "dotnet dev-certs https --export-path devcerts.pfx --password PLACEHOLDER %3B $pw = ConvertTo-SecureString PLACEHOLDER -AsPlainText -Force %3B Import-PfxCertificate -FilePath devcerts.pfx -Password $pw -CertStoreLocation Cert:\LocalMachine\Root " && true diff --git a/src/libraries/sfx-gen.proj b/src/libraries/sfx-gen.proj index 6c3e0143766759..1b3bdf6c104c8d 100644 --- a/src/libraries/sfx-gen.proj +++ b/src/libraries/sfx-gen.proj @@ -4,6 +4,7 @@ netstandard2.0 true + true diff --git a/src/libraries/sfx-ref.proj b/src/libraries/sfx-ref.proj deleted file mode 100644 index b1a3916acf4e18..00000000000000 --- a/src/libraries/sfx-ref.proj +++ /dev/null @@ -1,20 +0,0 @@ - - - - $(NetCoreAppCurrent)-$(TargetOS) - - true - - - - - - - - - - diff --git a/src/libraries/sfx-src.proj b/src/libraries/sfx-src.proj index 934f31e43ffb6c..8da1f3b306c227 100644 --- a/src/libraries/sfx-src.proj +++ b/src/libraries/sfx-src.proj @@ -4,6 +4,7 @@ $(NetCoreAppCurrent)-$(TargetOS) true + true diff --git a/src/libraries/sfx.proj b/src/libraries/sfx.proj index 0e1bf0ca01cf7b..3b808ecbe7d741 100644 --- a/src/libraries/sfx.proj +++ b/src/libraries/sfx.proj @@ -2,12 +2,10 @@ $(NetCoreAppCurrent)-$(TargetOS) + true - - diff --git a/src/libraries/sfx.slnx b/src/libraries/sfx.slnx new file mode 100644 index 00000000000000..b12ca216e1bc6f --- /dev/null +++ b/src/libraries/sfx.slnx @@ -0,0 +1,2612 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/shims/Directory.Build.props b/src/libraries/shims/Directory.Build.props index a325502afbf5fc..6a4bed745695b1 100644 --- a/src/libraries/shims/Directory.Build.props +++ b/src/libraries/shims/Directory.Build.props @@ -21,6 +21,7 @@ true + \shims diff --git a/src/libraries/shims/stubs/Directory.Build.props b/src/libraries/shims/stubs/Directory.Build.props index 60dcac3da5543e..954023037abfbf 100644 --- a/src/libraries/shims/stubs/Directory.Build.props +++ b/src/libraries/shims/stubs/Directory.Build.props @@ -30,7 +30,7 @@ - + diff --git a/src/libraries/slngen.proj b/src/libraries/slngen.proj index c06b8c0e403b6e..aa88a104f26ffd 100644 --- a/src/libraries/slngen.proj +++ b/src/libraries/slngen.proj @@ -1,4 +1,5 @@ + .cmd .sh @@ -10,6 +11,8 @@ + + + + + DestinationFiles="%(SolutionFile.ProjFilePath)" + Condition="'%(SolutionFile.Filename)' != 'sfx'" /> - + @@ -41,4 +48,5 @@ SlnFilePath="%(RelativeDir)%(Filename).sln" /> + diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 5641c763c36977..0438f60445292c 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -40,11 +40,6 @@ - - - - - @@ -224,29 +219,14 @@ - + - - - - - + + - - - - - - - - - - - - @@ -349,6 +329,11 @@ + + + + + @@ -526,6 +511,7 @@ + @@ -585,9 +571,10 @@ - + + @@ -607,15 +594,31 @@ - + - + + + + + + + + + + + + + + + + + - + @@ -278,6 +278,12 @@ + + + + + + diff --git a/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs b/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs index 21eba8223fd0f9..77a4ac8b75d107 100644 --- a/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs @@ -4,6 +4,7 @@ using System.Diagnostics.Tracing; using System.Runtime; using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; namespace System { @@ -149,6 +150,20 @@ public static void ReRegisterForFinalize(object obj) _ReRegisterForFinalize(obj); } + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = nameof(Finalize))] + private static extern void CallFinalize(object o); + private static void GuardedFinalize(object o) + { + try + { + CallFinalize(o); + } + catch (Exception ex) when (ExceptionHandling.IsHandledByGlobalHandler(ex)) + { + // the handler returned "true" means the exception is now "handled" and we should continue. + } + } + [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern long GetTotalMemory(bool forceFullCollection); diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/TypeNameResolver.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/TypeNameResolver.Mono.cs index 252ff469956a85..67b335835511a8 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/TypeNameResolver.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/TypeNameResolver.Mono.cs @@ -18,7 +18,6 @@ internal unsafe ref partial struct TypeNameResolver private Func? _typeResolver; private bool _throwOnError; private bool _ignoreCase; - private bool _extensibleParser; private ref StackCrawlMark _stackMark; [RequiresUnreferencedCode("The type might be removed")] @@ -28,7 +27,6 @@ internal unsafe ref partial struct TypeNameResolver Func? typeResolver, bool throwOnError, bool ignoreCase, - bool extensibleParser, ref StackCrawlMark stackMark) { ArgumentNullException.ThrowIfNull(typeName); @@ -54,7 +52,6 @@ internal unsafe ref partial struct TypeNameResolver _typeResolver = typeResolver, _throwOnError = throwOnError, _ignoreCase = ignoreCase, - _extensibleParser = extensibleParser, _stackMark = ref stackMark }.Resolve(parsed); } @@ -144,16 +141,7 @@ internal unsafe ref partial struct TypeNameResolver if (_ignoreCase) bindingFlags |= BindingFlags.IgnoreCase; - if (type is RuntimeType rt) - { - // Compat: Non-extensible parser allows ambiguous matches with ignore case lookup - bool ignoreAmbiguousMatch = !_extensibleParser && _ignoreCase; - type = rt.GetNestedType(nestedTypeNames[i], bindingFlags, ignoreAmbiguousMatch); - } - else - { - type = type.GetNestedType(nestedTypeNames[i], bindingFlags); - } + type = type.GetNestedType(nestedTypeNames[i], bindingFlags); if (type is null) { diff --git a/src/mono/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs index f02c580e2645f9..57db6533e5d04a 100644 --- a/src/mono/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs @@ -140,26 +140,26 @@ public void StartProfileOptimization(string? profile) return context.ResolveSatelliteAssembly(new AssemblyName(assemblyName)); } - private static AssemblyLoadContext GetAssemblyLoadContext(IntPtr gchManagedAssemblyLoadContext) + private static AssemblyLoadContext GetAssemblyLoadContext(IntPtr gchAssemblyLoadContext) { AssemblyLoadContext context; // This check exists because the function can be called early in startup, before the default ALC is initialized - if (gchManagedAssemblyLoadContext == IntPtr.Zero) + if (gchAssemblyLoadContext == IntPtr.Zero) context = Default; else - context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target)!; + context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchAssemblyLoadContext).Target)!; return context; } - private static void MonoResolveUnmanagedDll(string unmanagedDllName, IntPtr gchManagedAssemblyLoadContext, ref IntPtr dll) + private static void MonoResolveUnmanagedDll(string unmanagedDllName, IntPtr gchAssemblyLoadContext, ref IntPtr dll) { - AssemblyLoadContext context = GetAssemblyLoadContext(gchManagedAssemblyLoadContext); + AssemblyLoadContext context = GetAssemblyLoadContext(gchAssemblyLoadContext); dll = context.LoadUnmanagedDll(unmanagedDllName); } - private static void MonoResolveUnmanagedDllUsingEvent(string unmanagedDllName, Assembly assembly, IntPtr gchManagedAssemblyLoadContext, ref IntPtr dll) + private static void MonoResolveUnmanagedDllUsingEvent(string unmanagedDllName, Assembly assembly, IntPtr gchAssemblyLoadContext, ref IntPtr dll) { - AssemblyLoadContext context = GetAssemblyLoadContext(gchManagedAssemblyLoadContext); + AssemblyLoadContext context = GetAssemblyLoadContext(gchAssemblyLoadContext); dll = context.GetResolvedUnmanagedDll(assembly, unmanagedDllName); } diff --git a/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs b/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs index facb38aada7135..db853759e2d2bb 100644 --- a/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs @@ -679,17 +679,21 @@ private ListBuilder GetFieldCandidates(string? name, BindingFlags bin return candidates; } - private ListBuilder GetNestedTypeCandidates(string? name, BindingFlags bindingAttr, bool allowPrefixLookup) + private ListBuilder GetNestedTypeCandidates(string? fullname, BindingFlags bindingAttr, bool allowPrefixLookup) { + bool prefixLookup; bindingAttr &= ~BindingFlags.Static; - FilterHelper(bindingAttr, ref name, allowPrefixLookup, out bool prefixLookup, out _, out MemberListType listType); + string? name, ns; + MemberListType listType; + SplitName(fullname, out name, out ns); + FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out _, out listType); RuntimeType[] cache = GetNestedTypes_internal(name, bindingAttr, listType); ListBuilder candidates = new ListBuilder(cache.Length); for (int i = 0; i < cache.Length; i++) { RuntimeType nestedClass = cache[i]; - if (FilterApplyType(nestedClass, bindingAttr, name, prefixLookup, null)) + if (FilterApplyType(nestedClass, bindingAttr, name, prefixLookup, ns)) { candidates.Add(nestedClass); } @@ -1000,39 +1004,33 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] - internal Type? GetNestedType([MaybeNull] string name, BindingFlags bindingAttr, bool ignoreAmbiguousMatch) + public override Type? GetNestedType(string fullname, BindingFlags bindingAttr) { - ArgumentNullException.ThrowIfNull(name); + ArgumentNullException.ThrowIfNull(fullname); bindingAttr &= ~BindingFlags.Static; - FilterHelper(bindingAttr, ref name, out _, out MemberListType listType); + string? name, ns; + MemberListType listType; + SplitName(fullname, out name, out ns); + FilterHelper(bindingAttr, ref name, out _, out listType); RuntimeType[] cache = GetNestedTypes_internal(name, bindingAttr, listType); RuntimeType? match = null; for (int i = 0; i < cache.Length; i++) { RuntimeType nestedType = cache[i]; - if (FilterApplyType(nestedType, bindingAttr, name, false, null)) + if (FilterApplyType(nestedType, bindingAttr, name, false, ns)) { if (match != null) throw ThrowHelper.GetAmbiguousMatchException(match); match = nestedType; - - if (ignoreAmbiguousMatch) - break; } } return match; } - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] - public override Type? GetNestedType(string name, BindingFlags bindingAttr) - { - return GetNestedType(name, bindingAttr, ignoreAmbiguousMatch: false); - } - [DynamicallyAccessedMembers(GetAllMembers)] public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { @@ -1321,6 +1319,8 @@ protected override bool IsValueTypeImpl() return res; } + internal bool IsActualInterface => IsInterface; + // Returns true for actual value types only, ignoring generic parameter constraints. internal bool IsActualValueType => RuntimeTypeHandle.IsValueType(this); @@ -2270,7 +2270,7 @@ internal void GetPacking(out int packing, out int size) public override string ToString() { - return getFullName(false, false); + return getFullName(false, false)!; } [MethodImplAttribute(MethodImplOptions.InternalCall)] @@ -2296,8 +2296,16 @@ public override MethodBase? DeclaringMethod [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void GetGenericArgumentsInternal(QCallTypeHandle type, ObjectHandleOnStack res, bool runtimeArray); - internal string getFullName(bool full_name, bool assembly_qualified) + internal string? getFullName(bool full_name, bool assembly_qualified) { + // If full name or assembly qualified name is requested, + // ensure that the type is compatible with full name round-tripping. + if ((full_name || assembly_qualified) + && !IsFullNameRoundtripCompatible(this)) + { + return null; + } + var this_type = this; string? res = null; getFullName(new QCallTypeHandle(ref this_type), ObjectHandleOnStack.Create(ref res), full_name, assembly_qualified); @@ -2428,11 +2436,15 @@ public override string Name [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void GetNamespace(QCallTypeHandle type, ObjectHandleOnStack res); - public override string Namespace + public override string? Namespace { get { - var this_type = this; + Type type = GetRootElementType(); + if (type.IsFunctionPointer) + return null; + + var this_type = (RuntimeType)type; string? res = null; GetNamespace(new QCallTypeHandle(ref this_type), ObjectHandleOnStack.Create(ref res)); return res!; @@ -2443,11 +2455,6 @@ public override string? FullName { get { - // See https://github.com/mono/mono/issues/18180 and - // https://github.com/dotnet/runtime/blob/69e114c1abf91241a0eeecf1ecceab4711b8aa62/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs#L1505-L1509 - if (ContainsGenericParameters && !GetRootElementType().IsGenericTypeDefinition) - return null; - string? fullName; TypeCache? cache = Cache; if ((fullName = cache.full_name) == null) diff --git a/src/mono/System.Private.CoreLib/src/System/Type.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Type.Mono.cs index 5740704b764651..3fc4f6082c9b28 100644 --- a/src/mono/System.Private.CoreLib/src/System/Type.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Type.Mono.cs @@ -30,7 +30,7 @@ internal IntPtr GetUnderlyingNativeHandle() public static Type? GetType(string typeName, bool throwOnError, bool ignoreCase) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return GetType(typeName, null, null, throwOnError, ignoreCase, false, ref stackMark); + return RuntimeType.GetType(typeName, throwOnError, ignoreCase, ref stackMark); } [RequiresUnreferencedCode("The type might be removed")] @@ -38,7 +38,7 @@ internal IntPtr GetUnderlyingNativeHandle() public static Type? GetType(string typeName, bool throwOnError) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return GetType(typeName, null, null, throwOnError, false, false, ref stackMark); + return RuntimeType.GetType(typeName, throwOnError, false, ref stackMark); } [RequiresUnreferencedCode("The type might be removed")] @@ -46,7 +46,7 @@ internal IntPtr GetUnderlyingNativeHandle() public static Type? GetType(string typeName) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return GetType(typeName, null, null, false, false, false, ref stackMark); + return RuntimeType.GetType(typeName, false, false, ref stackMark); } [RequiresUnreferencedCode("The type might be removed")] @@ -54,7 +54,7 @@ internal IntPtr GetUnderlyingNativeHandle() public static Type? GetType(string typeName, Func? assemblyResolver, Func? typeResolver) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return GetType(typeName, assemblyResolver, typeResolver, false, false, true, ref stackMark); + return GetType(typeName, assemblyResolver, typeResolver, false, false, ref stackMark); } [RequiresUnreferencedCode("The type might be removed")] @@ -62,7 +62,7 @@ internal IntPtr GetUnderlyingNativeHandle() public static Type? GetType(string typeName, Func? assemblyResolver, Func? typeResolver, bool throwOnError) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return GetType(typeName, assemblyResolver, typeResolver, throwOnError, false, true, ref stackMark); + return GetType(typeName, assemblyResolver, typeResolver, throwOnError, false, ref stackMark); } [RequiresUnreferencedCode("The type might be removed")] @@ -70,13 +70,13 @@ internal IntPtr GetUnderlyingNativeHandle() public static Type? GetType(string typeName, Func? assemblyResolver, Func? typeResolver, bool throwOnError, bool ignoreCase) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, true, ref stackMark); + return GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark); } [RequiresUnreferencedCode("The type might be removed")] - private static Type? GetType(string typeName, Func? assemblyResolver, Func? typeResolver, bool throwOnError, bool ignoreCase, bool extensibleParser, ref StackCrawlMark stackMark) + private static Type? GetType(string typeName, Func? assemblyResolver, Func? typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark) { - return TypeNameResolver.GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, extensibleParser, ref stackMark); + return TypeNameResolver.GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark); } public static Type? GetTypeFromHandle(RuntimeTypeHandle handle) diff --git a/src/mono/browser/README.md b/src/mono/browser/README.md index ca9e5893a50f39..99db810abc6de7 100644 --- a/src/mono/browser/README.md +++ b/src/mono/browser/README.md @@ -228,6 +228,36 @@ They are handy to quickly disassemble functions and inspect webassembly module s There is also the [wa-edit](https://github.com/radekdoulik/wa-info#wa-edit) tool, which is now used to prototype improved warm startup. +## Properties That Trigger Relinking + +### What is Relinking? + +Relinking is the process of rebuilding the native WebAssembly runtime (`dotnet.native.js`, `dotnet.native.wasm`, etc.) with updated or trimmed content, often resulting in a smaller or more optimized output. This is necessary when certain configuration properties or source changes require regeneration of the native artifacts. + +### Properties That Trigger Relinking in `browser.proj` + +The following MSBuild properties will trigger a relinking (full rebuild of native artifacts) during the browser/wasm build process: + +- **`WasmBuildNative`** - `/p:WasmBuildNative=true` - Forces a fresh build of the native runtime components. +- **`WasmRelinkNative`** - `/p:WasmRelinkNative=true` - Explicitly requests relinking, even if not otherwise required by other property changes. +- **`RunAOTCompilation`** - `/p:RunAOTCompilation=true` - Enables Ahead-of-Time (AOT) compilation. Changing this requires relinking to produce the correct output. +- **`WasmEnableExceptionHandling`** - `/p:WasmEnableExceptionHandling=true` - Changes exception handling mechanisms in the native runtime. +- **`EnableDiagnostics`** - `/p:EnableDiagnostics=true` - Enables or disables diagnostic features in the native runtime. +- **`WasmProfilers`** - `/p:WasmProfilers=...` - Changes profiler configuration in the native runtime. +- **`EmccMaximumHeapSize`** - `/p:EmccMaximumHeapSize=...` - Controls memory layout configuration. +- **`EmccInitialHeapSize`** - `/p:EmccInitialHeapSize=...` - Controls memory layout together with `EmccMaximumHeapSize`. Heap size configuration applies only for browser scenarios. +- **`WasmBuildArgs`** - Any change to arguments passed via `/p:WasmBuildArgs=...` (such as enabling/disabling additional features or options) will trigger a relink. +- **Configuration/Target Architecture** - Changing `/p:Configuration=Debug|Release` or `/p:RuntimeIdentifier=browser-wasm`, etc., can require relinking for correct native output. + +#### Notes + +- Relinking ensures that the produced WebAssembly binaries reflect the current set of build options and runtime features. +- For incremental developer workflows, minimizing unnecessary relinks speeds up build times. +- The relink process is managed by MSBuild targets in `browser.proj`—refer to that file for the most up-to-date logic. +- Source changes to native code (C/C++/Emscripten sources) in `src/mono/browser` or dependent directories will naturally trigger a relink. + +For questions or advanced scenarios, see the [WebAssembly build instructions](../../../docs/workflow/building/libraries/webassembly-instructions.md). + ## Upgrading Emscripten Bumping Emscripten version involves these steps: diff --git a/src/mono/browser/browser.proj b/src/mono/browser/browser.proj index a5a763d1f34d8f..b0a14f621b2b99 100644 --- a/src/mono/browser/browser.proj +++ b/src/mono/browser/browser.proj @@ -320,6 +320,7 @@ + <_EmccPropsJson> true - - - - - diff --git a/src/mono/browser/debugger/BrowserDebugHost/DebugProxyHost.cs b/src/mono/browser/debugger/BrowserDebugHost/DebugProxyHost.cs index 9129c61c9c3088..ec1143218a99ba 100644 --- a/src/mono/browser/debugger/BrowserDebugHost/DebugProxyHost.cs +++ b/src/mono/browser/debugger/BrowserDebugHost/DebugProxyHost.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -43,7 +44,8 @@ public static Task RunFirefoxServerLoopAsync(ProxyOptions options, string[] args public static async Task RunDevToolsProxyAsync(ProxyOptions options, string[] args, ILoggerFactory loggerFactory, CancellationToken token) { string proxyUrl = $"http://127.0.0.1:{options.DevToolsProxyPort}"; - IWebHost host = new WebHostBuilder() + IHost host = new HostBuilder().ConfigureWebHost(webHostBuilder => + webHostBuilder .UseSetting("UseIISIntegration", false.ToString()) .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) @@ -51,7 +53,6 @@ public static async Task RunDevToolsProxyAsync(ProxyOptions options, string[] ar .ConfigureServices(services => { services.AddSingleton(loggerFactory); - services.AddLogging(configure => configure.AddSimpleConsole().AddFilter(null, LogLevel.Information)); services.AddSingleton(Options.Create(options)); services.AddRouting(); }) @@ -60,7 +61,7 @@ public static async Task RunDevToolsProxyAsync(ProxyOptions options, string[] ar config.AddCommandLine(args); }) .UseUrls(proxyUrl) - .Build(); + ).Build(); if (token.CanBeCanceled) token.Register(async () => await host.StopAsync()); diff --git a/src/mono/browser/debugger/BrowserDebugHost/Program.cs b/src/mono/browser/debugger/BrowserDebugHost/Program.cs index e1c7d01652b619..281bae1600edee 100644 --- a/src/mono/browser/debugger/BrowserDebugHost/Program.cs +++ b/src/mono/browser/debugger/BrowserDebugHost/Program.cs @@ -7,6 +7,8 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Logging.Console; #nullable enable @@ -23,16 +25,24 @@ public static async Task Main(string[] args) using ILoggerFactory loggerFactory = LoggerFactory.Create(builder => { - builder.AddSimpleConsole(options => - { - options.TimestampFormat = "[HH:mm:ss] "; - }) - .AddFilter("DevToolsProxy", LogLevel.Information) - .AddFilter("FirefoxMonoProxy", LogLevel.Information) - .AddFilter(null, LogLevel.Warning); + builder + .AddConsole(options => options.FormatterName = "messageOnly") // Emit messages as expected by DebugProxyLauncher.cs + .AddConsoleFormatter() + .AddFilter("Microsoft.Hosting.Lifetime", LogLevel.Information) + .AddFilter("DevToolsProxy", LogLevel.Information) + .AddFilter("FirefoxMonoProxy", LogLevel.Information) + .AddFilter(null, LogLevel.Warning); }); await DebugProxyHost.RunDebugProxyAsync(options, args, loggerFactory, CancellationToken.None); } } + + public class MessageOnlyFormatter : ConsoleFormatter + { + public MessageOnlyFormatter() : base("messageOnly") { } + + public override void Write(in LogEntry logEntry, IExternalScopeProvider? scopeProvider, TextWriter textWriter) + => textWriter.WriteLine(logEntry.Formatter(logEntry.State, logEntry.Exception)); + } } diff --git a/src/mono/browser/runtime/invoke-cs.ts b/src/mono/browser/runtime/invoke-cs.ts index 3b7a869e8661c3..89da4c4c04b0e2 100644 --- a/src/mono/browser/runtime/invoke-cs.ts +++ b/src/mono/browser/runtime/invoke-cs.ts @@ -123,7 +123,8 @@ function bind_fn_0V (closure: BindingClosure) { // call C# side invoke_sync_jsexport(method, args); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; @@ -147,7 +148,8 @@ function bind_fn_1V (closure: BindingClosure) { // call C# side invoke_sync_jsexport(method, args); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; @@ -175,7 +177,8 @@ function bind_fn_1R (closure: BindingClosure) { const js_result = res_converter(args); return js_result; } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; @@ -208,7 +211,8 @@ function bind_fn_1RA (closure: BindingClosure) { return promise; } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; @@ -238,7 +242,8 @@ function bind_fn_2R (closure: BindingClosure) { const js_result = res_converter(args); return js_result; } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; @@ -273,7 +278,8 @@ function bind_fn_2RA (closure: BindingClosure) { return promise; } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; @@ -325,7 +331,8 @@ function bind_fn (closure: BindingClosure) { } return js_result; } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; diff --git a/src/mono/browser/runtime/loader/config.ts b/src/mono/browser/runtime/loader/config.ts index f882b2b1e192ea..8f5cf705b1d8fa 100644 --- a/src/mono/browser/runtime/loader/config.ts +++ b/src/mono/browser/runtime/loader/config.ts @@ -56,12 +56,18 @@ function deep_merge_resources (target: Assets, source: Assets): Assets { if (target === source) return target; const providedResources: Assets = { ...source }; + if (providedResources.coreAssembly !== undefined) { + providedResources.coreAssembly = [...(target.coreAssembly || []), ...(providedResources.coreAssembly || [])]; + } if (providedResources.assembly !== undefined) { providedResources.assembly = [...(target.assembly || []), ...(providedResources.assembly || [])]; } if (providedResources.lazyAssembly !== undefined) { providedResources.lazyAssembly = [...(target.lazyAssembly || []), ...(providedResources.lazyAssembly || [])]; } + if (providedResources.corePdb !== undefined) { + providedResources.corePdb = [...(target.corePdb || []), ...(providedResources.corePdb || [])]; + } if (providedResources.pdb !== undefined) { providedResources.pdb = [...(target.pdb || []), ...(providedResources.pdb || [])]; } @@ -216,15 +222,6 @@ export function normalizeConfig () { config.environmentVariables!["LANG"] = `${config.applicationCulture}.UTF-8`; } - if (config.debugLevel !== 0 && globalThis.window?.document?.querySelector("script[src*='aspnetcore-browser-refresh']")) { - if (!config.environmentVariables["DOTNET_MODIFIABLE_ASSEMBLIES"]) { - config.environmentVariables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug"; - } - if (!config.environmentVariables["__ASPNETCORE_BROWSER_TOOLS"]) { - config.environmentVariables["__ASPNETCORE_BROWSER_TOOLS"] = "true"; - } - } - runtimeHelpers.diagnosticTracing = loaderHelpers.diagnosticTracing = !!config.diagnosticTracing; runtimeHelpers.waitForDebugger = config.waitForDebugger; diff --git a/src/mono/browser/runtime/managed-exports.ts b/src/mono/browser/runtime/managed-exports.ts index 472c47708c4739..159b250d58f1e0 100644 --- a/src/mono/browser/runtime/managed-exports.ts +++ b/src/mono/browser/runtime/managed-exports.ts @@ -74,7 +74,8 @@ export function call_entry_point (main_assembly_name: string, program_args: stri return promise; } finally { - Module.stackRestore(sp); // synchronously + // synchronously + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); } } @@ -90,7 +91,8 @@ export function load_satellite_assembly (dll: Uint8Array): void { marshal_array_to_cs(arg1, dll, MarshalerType.Byte); invoke_sync_jsexport(managedExports.LoadSatelliteAssembly, args); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } @@ -109,7 +111,8 @@ export function load_lazy_assembly (dll: Uint8Array, pdb: Uint8Array | null): vo marshal_array_to_cs(arg2, pdb, MarshalerType.Byte); invoke_sync_jsexport(managedExports.LoadLazyAssembly, args); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } @@ -132,7 +135,8 @@ export function release_js_owned_object_by_gc_handle (gc_handle: GCHandle) { invoke_async_jsexport(runtimeHelpers.ioThreadTID, managedExports.ReleaseJSOwnedObjectByGCHandle, args, size); } } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } @@ -157,7 +161,8 @@ export function complete_task (holder_gc_handle: GCHandle, error?: any, data?: a } invoke_async_jsexport(runtimeHelpers.ioThreadTID, managedExports.CompleteTask, args, size); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } @@ -203,7 +208,8 @@ export function call_delegate (callback_gc_handle: GCHandle, arg1_js: any, arg2_ return res_converter(res); } } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } @@ -223,7 +229,8 @@ export function get_managed_stack_trace (exception_gc_handle: GCHandle) { const res = get_arg(args, 1); return marshal_string_to_js(res); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } @@ -341,7 +348,8 @@ export function bind_assembly_exports (assemblyName: string): Promise { } return promise; } finally { - Module.stackRestore(sp); // synchronously + // synchronously + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); } } diff --git a/src/mono/browser/runtime/memory.ts b/src/mono/browser/runtime/memory.ts index 0f9f751854de17..3497f05b8b99bc 100644 --- a/src/mono/browser/runtime/memory.ts +++ b/src/mono/browser/runtime/memory.ts @@ -6,7 +6,7 @@ import WasmEnableThreads from "consts:wasmEnableThreads"; import { MemOffset, NumberOrPointer } from "./types/internal"; import { VoidPtr, CharPtr } from "./types/emscripten"; import cwraps, { I52Error } from "./cwraps"; -import { Module, mono_assert, runtimeHelpers } from "./globals"; +import { loaderHelpers, Module, mono_assert, runtimeHelpers } from "./globals"; import { utf8ToString } from "./strings"; import { mono_log_warn, mono_log_error } from "./logging"; @@ -327,7 +327,8 @@ export function withStackAlloc (bytesWanted: number, f: (pt try { return f(ptr, ud1, ud2, ud3); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } diff --git a/src/mono/browser/runtime/rollup.config.js b/src/mono/browser/runtime/rollup.config.js index 1966e3dfc7bb9f..36cf88de8dd85c 100644 --- a/src/mono/browser/runtime/rollup.config.js +++ b/src/mono/browser/runtime/rollup.config.js @@ -173,7 +173,7 @@ const loaderConfig = { banner, intro: "/*! bundlerFriendlyImports */", plugins, - sourcemap: true, + sourcemap: isDebug ? true : "hidden", sourcemapPathTransform, } ], diff --git a/src/mono/browser/runtime/startup.ts b/src/mono/browser/runtime/startup.ts index 083071124f6d2c..0bfa9466553abc 100644 --- a/src/mono/browser/runtime/startup.ts +++ b/src/mono/browser/runtime/startup.ts @@ -611,7 +611,7 @@ export function mono_wasm_load_runtime (): void { debugLevel = 0 + debugLevel; } } - if (!loaderHelpers.isDebuggingSupported() || !runtimeHelpers.config.resources!.pdb) { + if (!loaderHelpers.isDebuggingSupported() || !(runtimeHelpers.config.resources!.corePdb || runtimeHelpers.config.resources!.pdb)) { debugLevel = 0; } diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 2517ffe86d89d1..7f79cb409cd3fb 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -17,8 +17,6 @@ .cmd .sh \" - python3 - python coreclr $(LibPrefix)$(CoreClrLibName)$(LibSuffix) monosgen-2.0 @@ -118,14 +116,6 @@ GeneratePathProperty="true" /> - - - $([MSBuild]::NormalizePath('$(PkgMicrosoft_NET_Runtime_Emscripten_3_1_56_Python_win-x64)', 'tools', 'python')) - - <_MonoCMakeArgs Include="-DENABLE_WERROR=1"/> @@ -252,8 +242,7 @@ set EMSDK_PATH=%CURRENT_SCRIPT:~0,-1%\ set EMSDK_PYTHON=%EMSDK_PATH%python\python.exe set DOTNET_EMSCRIPTEN_LLVM_ROOT=%EMSDK_PATH%bin\ -set DOTNET_EMSCRIPTEN_NODE_JS=%EMSDK_PATH%node\bin\node -set DOTNET_EMSCRIPTEN_NODE_PATH=%EMSDK_PATH%node\bin\ +set DOTNET_EMSCRIPTEN_NODE_JS=%EMSDK_PATH%node\bin\node.exe set DOTNET_EMSCRIPTEN_BINARYEN_ROOT=%EMSDK_PATH% @@ -271,7 +260,6 @@ FROZEN_CACHE = bool(os.getenv('EM_FROZEN_CACHE', 'True')) COMPILER_ENGINE = NODE_JS JS_ENGINES = [NODE_JS] - setlocal EnableDelayedExpansion && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env$(ScriptExt)'))" && !EMSDK_PYTHON! @@ -761,7 +749,9 @@ JS_ENGINES = [NODE_JS] <_MonoCMakeBuildCommand Condition="'$(_MonoUseNinja)' != 'true'">$(_MonoCMakeBuildCommand) --parallel $([System.Environment]::ProcessorCount) <_MonoCMakeBuildCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(HostOS)' != 'windows'">@(_MonoBuildEnv, ' ') $(_MonoCMakeBuildCommand) <_MonoCMakeBuildCommand Condition="'$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" $(_CompilerTargetArch) && cd /D "$(MonoObjDir)" && @(_MonoBuildEnv, ' ') $(_MonoCMakeBuildCommand) - <_MonoCMakeBuildCommand Condition="('$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true') and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && $(_MonoCMakeBuildCommand) + <_MonoCMakeBuildCommand Condition="'$(TargetsBrowser)' == 'true' and '$(HostOS)' != 'windows'">bash -c 'source $(_EmsdkEnvScriptPath) 2>&1 && $(_MonoCMakeBuildCommand)' + <_MonoCMakeBuildCommand Condition="'$(TargetsBrowser)' == 'true' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && call "$(_EmsdkEnvScriptPath)" && $(_MonoCMakeBuildCommand) + <_MonoCMakeBuildCommand Condition="'$(TargetsWasi)' == 'true' and '$(HostOS)' == 'windows'">call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && $(_MonoCMakeBuildCommand) @@ -963,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')) + + @@ -985,13 +983,14 @@ JS_ENGINES = [NODE_JS] + <_MonoSkipInitCompiler Condition="'$(AotHostArchitecture)' != '$(BuildArchitecture)'">false <_MonoSkipInitCompiler Condition="'$(CrossBuild)' == 'true'">false <_MonoAotCrossOffsetsToolPath>$(MonoProjectRoot)mono\offsets\offsets-tool.py - <_MonoAotCrossOffsetsCommand Condition="'$(MonoUseCrossTool)' == 'true'">$(PythonCmd) $(_MonoAotCrossOffsetsToolPath) @(MonoAotCrossOffsetsToolParams, ' ') + <_MonoAotCrossOffsetsCommand Condition="'$(MonoUseCrossTool)' == 'true'">$(_PythonCmd) $(_MonoAotCrossOffsetsToolPath) @(MonoAotCrossOffsetsToolParams, ' ') <_MonoAotCMakeConfigureCommand>cmake @(MonoAOTCMakeArgs, ' ') $(MonoCMakeExtraArgs) "$(MonoProjectRoot.TrimEnd('\/'))" <_MonoAotCMakeConfigureCommand Condition="'$(_MonoSkipInitCompiler)' != 'true' and '$(HostOS)' != 'windows'">sh -c 'build_arch="$(_CompilerTargetArch)" ROOTFS_DIR="$(MonoCrossDir)" compiler="$(MonoCCompiler)" . "$(RepositoryEngineeringCommonDir)native/init-compiler.sh" && @(_MonoAotBuildEnv, ' ') $(_MonoAotCMakeConfigureCommand)' <_MonoAotCMakeConfigureCommand Condition="'$(_MonoSkipInitCompiler)' == 'true' and '$(HostOS)' != 'windows'">$(_MonoAOTCCOption) $(_MonoAOTCXXOption) @(_MonoAotBuildEnv, ' ') $(_MonoAotCMakeConfigureCommand) @@ -1140,13 +1139,13 @@ JS_ENGINES = [NODE_JS] <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.release.framework') and !Exists('$(MonoObjDir)out\lib\Mono.release.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.release.framework\Mono.release"> $(RuntimeBinDir)\Mono.release.framework\Mono - <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.release.framework') and Exists('$(MonoObjDir)out\lib\Mono.release.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.release.framework\Versions\Current\Mono.release"> + <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.release.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.release.framework\Versions\Current\Mono.release"> $(RuntimeBinDir)\Mono.release.framework\Mono - <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.release.framework') and !Exists('$(MonoObjDir)out\lib\Mono.release.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.release.framework\Mono.release.dwarf"> + <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.release.framework\Mono.release.dwarf') and !Exists('$(MonoObjDir)out\lib\Mono.release.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.release.framework\Mono.release.dwarf"> $(RuntimeBinDir)\Mono.release.framework\Mono.dwarf - <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.release.framework') and Exists('$(MonoObjDir)out\lib\Mono.release.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.release.framework\Versions\Current\Mono.release.dwarf"> + <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.release.framework\Versions\Current\Mono.release.dwarf')" Include="$(MonoObjDir)out\lib\Mono.release.framework\Versions\Current\Mono.release.dwarf"> $(RuntimeBinDir)\Mono.release.framework\Mono.dwarf <_MonoRuntimeArtifacts Condition="'$(MonoComponentsStatic)' != 'true' and Exists('$(MonoObjDir)out\lib\Mono.debug.framework')" Include="@(_MonoRuntimeComponentsSharedFilePath)"> @@ -1155,25 +1154,25 @@ JS_ENGINES = [NODE_JS] <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.debug.framework') and !Exists('$(MonoObjDir)out\lib\Mono.debug.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.debug.framework\Mono.debug"> $(RuntimeBinDir)\Mono.debug.framework\Mono - <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.debug.framework') and Exists('$(MonoObjDir)out\lib\Mono.debug.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.debug.framework\Versions\Current\Mono.debug"> + <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.debug.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.debug.framework\Versions\Current\Mono.debug"> $(RuntimeBinDir)\Mono.debug.framework\Mono - <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.debug.framework') and !Exists('$(MonoObjDir)out\lib\Mono.debug.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.debug.framework\Mono.debug.dwarf"> + <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.debug.framework\Mono.debug.dwarf') and !Exists('$(MonoObjDir)out\lib\Mono.debug.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.debug.framework\Mono.debug.dwarf"> $(RuntimeBinDir)\Mono.debug.framework\Mono.dwarf - <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.debug.framework') and Exists('$(MonoObjDir)out\lib\Mono.debug.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.debug.framework\Versions\Current\Mono.debug.dwarf"> + <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.debug.framework\Versions\Current\Mono.debug.dwarf')" Include="$(MonoObjDir)out\lib\Mono.debug.framework\Versions\Current\Mono.debug.dwarf"> $(RuntimeBinDir)\Mono.debug.framework\Mono.dwarf <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.release.framework') and !Exists('$(MonoObjDir)out\lib\Mono.release.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.release.framework\Info.plist"> $(RuntimeBinDir)\Mono.release.framework\Info.plist - <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.release.framework') and Exists('$(MonoObjDir)out\lib\Mono.release.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.release.framework\Versions\Current\Resources\Info.plist"> + <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.release.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.release.framework\Versions\Current\Resources\Info.plist"> $(RuntimeBinDir)\Mono.release.framework\Info.plist <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.debug.framework') and !Exists('$(MonoObjDir)out\lib\Mono.debug.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.debug.framework\Info.plist"> $(RuntimeBinDir)\Mono.debug.framework\Info.plist - <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.debug.framework') and Exists('$(MonoObjDir)out\lib\Mono.debug.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.debug.framework\Versions\Current\Resources\Info.plist"> + <_MonoRuntimeArtifacts Condition="Exists('$(MonoObjDir)out\lib\Mono.debug.framework\Versions')" Include="$(MonoObjDir)out\lib\Mono.debug.framework\Versions\Current\Resources\Info.plist"> $(RuntimeBinDir)\Mono.debug.framework\Info.plist <_MonoRuntimeBuildArtifacts Include="$(MonoObjDir)\build\**" /> diff --git a/src/mono/mono/arch/s390x/s390x-codegen.h b/src/mono/mono/arch/s390x/s390x-codegen.h index e5679d9c18087e..d28b9a6e2fe60f 100644 --- a/src/mono/mono/arch/s390x/s390x-codegen.h +++ b/src/mono/mono/arch/s390x/s390x-codegen.h @@ -139,38 +139,38 @@ typedef enum { } S390SpecialRegister; typedef enum { - s390_VR0 = 0, - s390_VR1 = 1, - s390_VR2 = 2, - s390_VR3 = 3, - s390_VR4 = 4, - s390_VR5 = 5, - s390_VR6 = 6, - s390_VR7 = 7, - s390_VR8 = 8, - s390_VR9 = 9, - s390_VR10 = 10, - s390_VR11 = 11, - s390_VR12 = 12, - s390_VR13 = 13, - s390_VR14 = 14, - s390_VR15 = 15, - s390_VR16 = 16, - s390_VR17 = 17, - s390_VR18 = 18, - s390_VR19 = 19, - s390_VR20 = 20, - s390_VR21 = 21, - s390_VR22 = 22, - s390_VR23 = 23, - s390_VR24 = 24, - s390_VR25 = 25, - s390_VR26 = 26, - s390_VR27 = 27, - s390_VR28 = 28, - s390_VR29 = 29, - s390_VR30 = 30, - s390_VR31 = 31, + s390_vr0 = 0, + s390_vr1 = 1, + s390_vr2 = 2, + s390_vr3 = 3, + s390_vr4 = 4, + s390_vr5 = 5, + s390_vr6 = 6, + s390_vr7 = 7, + s390_vr8 = 8, + s390_vr9 = 9, + s390_vr10 = 10, + s390_vr11 = 11, + s390_vr12 = 12, + s390_vr13 = 13, + s390_vr14 = 14, + s390_vr15 = 15, + s390_vr16 = 16, + s390_vr17 = 17, + s390_vr18 = 18, + s390_vr19 = 19, + s390_vr20 = 20, + s390_vr21 = 21, + s390_vr22 = 22, + s390_vr23 = 23, + s390_vr24 = 24, + s390_vr25 = 25, + s390_vr26 = 26, + s390_vr27 = 27, + s390_vr28 = 28, + s390_vr29 = 29, + s390_vr30 = 30, + s390_vr31 = 31, s390_VR_NREG = 32, } s390_VR_Reg_No; @@ -943,14 +943,7 @@ typedef struct { s390_emit16(c, ((i) & 0xffff)); \ } while (0) -#define S390_SIY(c,opc,s1,p1,m2) do \ -{ \ - s390_emit16(c, ((opc & 0xff00) | m2)); \ - s390_emit32(c, ((s1) << 24 | (((p2) & 0xfffff) << 8) | \ - (opc & 0xff))); \ -} while (0) - -#define S390_SIY_1(c,opc,d1,b1,i2) do \ +#define S390_SIY(c,opc,d1,b1,i2) do \ { \ s390_emit16(c, ((opc & 0xff00) | i2)); \ s390_emit32(c, ((b1) << 28 | (((d1) & 0xfff) << 16) | \ @@ -1005,7 +998,7 @@ typedef struct { #define S390_VRIa(c,opc,v1,i2,m3) do \ { \ - char rxb = (((v1) > 15) << 7); \ + char rxb = (((v1) > 15) << 3); \ int vr1 = ((v1) % 16); \ s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4)); \ s390_emit16(c, (i2)); \ @@ -1014,7 +1007,7 @@ typedef struct { #define S390_VRIb(c,opc,v1,i2,i3,m4) do \ { \ - char rxb = (((v1) > 15) << 7); \ + char rxb = (((v1) > 15) << 3); \ int vr1 = ((v1) % 16); \ s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4)); \ s390_emit16(c, (((i2) << 8) | (i3))); \ @@ -1023,18 +1016,17 @@ typedef struct { #define S390_VRIc(c,opc,v1,v3,i2,m4) do \ { \ - char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6) | \ - (((v3) > 15) << 5); \ + char rxb = (((v1) > 15) << 3) | (((v3) > 15) << 2); \ int vr1 = ((v1) % 16), vr3 = ((v3) % 16); \ s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr3)); \ - s390_emit16(c, (v4)); \ + s390_emit16(c, (i2)); \ s390_emit16(c, (((m4) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \ } while (0) #define S390_VRId(c,opc,v1,v2,v3,i4,m5) do \ { \ - char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6) | \ - (((v3) > 15) << 5); \ + char rxb = (((v1) > 15) << 3) | (((v2) > 15) << 2) | \ + (((v3) > 15) << 1); \ int vr1 = ((v1) % 16), vr2 = ((v2) % 16), vr3 = ((v3) % 16); \ s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2)); \ s390_emit16(c, (vr3 << 12) | (i2)); \ @@ -1043,7 +1035,7 @@ typedef struct { #define S390_VRIe(c,opc,v1,v2,i3,m4,m5) do \ { \ - char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6); \ + char rxb = (((v1) > 15) << 3) | (((v2) > 15) << 2); \ int vr1 = ((v1) % 16), vr2 = ((v2) % 16); \ s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2)); \ s390_emit16(c, ((i2) << 8) | (m5)); \ @@ -1052,7 +1044,7 @@ typedef struct { #define S390_VRRa(c,opc,v1,v2,m3,m4,m5) do \ { \ - char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6); \ + char rxb = (((v1) > 15) << 3) | (((v2) > 15) << 2); \ int vr1 = ((v1) % 16), vr2 = ((v2) % 16); \ s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2)); \ s390_emit16(c, ((m5) << 4) | (m4)); \ @@ -1061,48 +1053,49 @@ typedef struct { #define S390_VRRb(c,opc,v1,v2,v3,m4,m5) do \ { \ - char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6) | \ - (((v3) > 15) << 5); \ + char rxb = (((v1) > 15) << 3) | (((v2) > 15) << 2) | \ + (((v3) > 15) << 1); \ int vr1 = ((v1) % 16), vr2 = ((v2) % 16), vr3 = ((v3) % 16); \ s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2)); \ - s390_emit16(c, (vr3 << 12) | ((m5) << 4) | (m4)); \ - s390_emit16(c, (((m3) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \ + s390_emit16(c, (vr3 << 12) | ((m5) << 4)); \ + s390_emit16(c, (((m4) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \ } while (0) -#define S390_VRRc(c,opc,v1,v2,m3,m4,m5) do \ +#define S390_VRRc(c,opc,v1,v2,v3,m4,m5,m6) do \ { \ - char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6) | \ - (((v3) > 15) << 5); \ + char rxb = (((v1) > 15) << 3) | (((v2) > 15) << 2) | \ + (((v3) > 15) << 1); \ int vr1 = ((v1) % 16), vr2 = ((v2) % 16), vr3 = ((v3) % 16); \ s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2)); \ - s390_emit16(c, ((vr3 << 12)| (m5) << 4)); \ + s390_emit16(c, ((vr3 << 12)| ((m6) << 4) | (m5))); \ s390_emit16(c, (((m4) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \ } while (0) #define S390_VRRd(c,opc,v1,v2,v3,v4,m5,m6) do \ { \ - char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6) | \ + char rxb = (((v1) > 15) << 3) | (((v2) > 15) << 2) | \ (((v3) > 15) << 5) | (((v4) > 15) << 4); \ int vr1 = ((v1) % 16), vr2 = ((v2) % 16), \ - vr3 = ((v3) % 16); vr4 = ((v4) % 16); \ + vr3 = ((v3) % 16), vr4 = ((v4) % 16); \ s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2)); \ s390_emit16(c, ((vr3 << 12)| ((m6) << 8)) | ((m5) << 4)); \ s390_emit16(c, ((vr4 << 12) | ((rxb) << 8) | ((opc) & 0xff))); \ } while (0) -#define S390_VRRe(c,opc,v1,v2,v3,m4,m5,m6) do \ +#define S390_VRRe(c,opc,v1,v2,v3,v4,m5,m6) do \ { \ - char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6) | \ - (((v3) > 15) << 5); \ - int vr1 = ((v1) % 16), vr2 = ((v2) % 16), vr3 = ((v3) % 16); \ - s390_emit16(c, ((opc) & 0xff00) | ((v1) << 4) | ((v2))); \ - s390_emit16(c, (((v3) << 12)| ((m6) << 8)) | (m5)); \ - s390_emit16(c, (((m4) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \ + char rxb = (((v1) > 15) << 3) | (((v2) > 15) << 2) | \ + (((v3) > 15) << 1) | ((v4) > 15); \ + int vr1 = ((v1) % 16), vr2 = ((v2) % 16), vr3 = ((v3) % 16), \ + vr4 = ((v4) % 16); \ + s390_emit16(c, ((opc) & 0xff00) | ((vr1) << 4) | ((vr2))); \ + s390_emit16(c, (((vr3) << 12)| ((m6) << 8)) | (m5)); \ + s390_emit16(c, (((vr4) << 12) | ((rxb) << 8) | ((opc) & 0xff)));\ } while (0) #define S390_VRRf(c,opc,v1,r2) do \ { \ - char rxb = (((v1) > 15) << 7); \ + char rxb = (((v1) > 15) << 3); \ s390_emit16(c, ((opc) & 0xff00) | ((v1) << 4) | ((v2))); \ s390_emit16(c, ((r2) << 12)| ((r3) << r8) | (m5)); \ s390_emit16(c, (((rxb) << 8) | ((opc) & 0xff))); \ @@ -1110,7 +1103,7 @@ typedef struct { #define S390_VRSa(c,opc,v1,v3,b2,d2,m4) do \ { \ - char rxb = (((v1) > 15) << 7) | (((v3) > 15) << 6); \ + char rxb = (((v1) > 15) << 3) | (((v3) > 15) << 2); \ int vr1 = ((v1) % 16), vr3 = ((v3) % 16); \ s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr3)); \ s390_emit16(c, ((b2) << 12)| (d2)); \ @@ -1119,7 +1112,7 @@ typedef struct { #define S390_VRSb(c,opc,v1,r3,b2,d2,m4) do \ { \ - char rxb = (((v1) > 15) << 7); \ + char rxb = (((v1) > 15) << 3); \ int vr1 = (v1) % 16; \ s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | ((r3))); \ s390_emit16(c, ((b2) << 12)| (d2)); \ @@ -1128,7 +1121,7 @@ typedef struct { #define S390_VRSc(c,opc,r1,v3,b2,d2,m4) do \ { \ - char rxb = (((v1) > 15) << 7); \ + char rxb = (((v3) > 15) << 3); \ int vr3 = (v3) % 16; \ s390_emit16(c, ((opc) & 0xff00) | ((r1) << 4) | (vr3)); \ s390_emit16(c, ((b2) << 12)| (d2)); \ @@ -1137,7 +1130,7 @@ typedef struct { #define S390_VRV(c,opc,v1,v2,b2,d2,m3) do \ { \ - char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6); \ + char rxb = (((v1) > 15) << 3) | (((v2) > 15) << 2); \ int vr1 = ((v1) % 16), vr2 = ((v3) % 16); \ s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2)); \ s390_emit16(c, ((b2) << 12)| (d2)); \ @@ -1146,7 +1139,7 @@ typedef struct { #define S390_VRX(c,opc,v1,x2,b2,d2,m3) do \ { \ - char rxb = ((v1) > 15) << 7; \ + char rxb = ((v1) > 15) << 3; \ int vr1 = (v1) % 16; \ s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | ((x2))); \ s390_emit16(c, ((b2) << 12)| (d2)); \ @@ -1167,7 +1160,7 @@ typedef struct { #define s390_aghik(c, r1, r3, v) S390_RIE_1(c, 0xecd9, r1, r3, v) #define s390_agr(c, r1, r2) S390_RRE(c, 0xb908, r1, r2) #define s390_agrk(c, r1, r2, r3) S390_RRF_1(c, 0xb9e8, r1, r2, r3) -#define s390_agsi(c, r, v) S390_SIY(c, 0xeb7a, r v) +#define s390_agsi(c, r, v, i) S390_SIY(c, 0xeb7a, r, v, i) #define s390_ahhhr(c, r1, r2, r3) S390_RRF_1(c, 0xb9c8, r1, r2, r3) #define s390_ahhlr(c, r1, r2, r3) S390_RRF_1(c, 0xb9d8, r1, r2, r3) #define s390_ahi(c, r, v) S390_RI(c, 0xa7a, r, v) @@ -1187,13 +1180,13 @@ typedef struct { #define s390_alghsik(c, r1, r3, v) S390_RIE_1(c, 0xecdb, r1, r3, v) #define s390_algr(c, r1, r2) S390_RRE(c, 0xb90a, r1, r2) #define s390_algrk(c, r1, r2, r3) S390_RRF_1(c, 0xb9ea, r1, r2, r3) -#define s390_algsi(c, d1, b1, i2) S390_SIY_1(c, 0xeb7e, d1, b1, i2) +#define s390_algsi(c, d1, b1, i2) S390_SIY(c, 0xeb7e, d1, b1, i2) #define s390_alhhhr(c, r1, r2, r3) S390_RRF_1(c, 0xb9ca, r1, r2, r3) #define s390_alhhlr(c, r1, r2, r3) S390_RRF_1(c, 0xb9da, r1, r2, r3) #define s390_alhsik(c, r1, r3, v) S390_RIE_1(c, 0xecda, r1, r3, v) #define s390_alr(c, r1, r2) S390_RR(c, 0x1e, r1, r2) #define s390_alrk(c, r1, r2) S390_RRF(c, 0xb9fa, r1, r2) -#define s390_alsi(c, d1, b1, i2) S390_SIY_1(c, 0xeb6e, d1, b1, i2) +#define s390_alsi(c, d1, b1, i2) S390_SIY(c, 0xeb6e, d1, b1, i2) #define s390_alsih(c, r, v) S390_RIL_1(c, 0xcca, r, v) #define s390_alsihn(c, r, v) S390_RIL_1(c, 0xccb, r, v) #define s390_aly(c, r, x, b, d) S390_RXY(c, 0xe35e, r, x, b, d) @@ -1569,8 +1562,164 @@ typedef struct { #define s390_tmlh(c, r, m) S390_RI(c, 0xa70, r, m) #define s390_tmll(c, r, m) S390_RI(c, 0xa71, r, m) #define s390_tm(c, b, d, v) S390_SI(c, 0x91, b, d, v) +#define s390_trap2(code) S390_E(code, 0x01ff) +#define s390_vab(c, v1, v2, v3) S390_VRRc(c, 0xe7f3, v1, v2, v3, 0, 0, 0) +#define s390_vah(c, v1, v2, v3) S390_VRRc(c, 0xe7f3, v1, v2, v3, 1, 0, 0) +#define s390_vaf(c, v1, v2, v3) S390_VRRc(c, 0xe7f3, v1, v2, v3, 2, 0, 0) +#define s390_vag(c, v1, v2, v3) S390_VRRc(c, 0xe7f3, v1, v2, v3, 3, 0, 0) +#define s390_vaq(c, v1, v2, v3) S390_VRRc(c, 0xe7f3, v1, v2, v3, 4, 0, 0) +#define s390_vceqb(c, v1, v2, v3) S390_VRRb(c, 0xe7f8, v1, v2, v3, 0, 0) +#define s390_vceqh(c, v1, v2, v3) S390_VRRb(c, 0xe7f8, v1, v2, v3, 1, 0) +#define s390_vceqf(c, v1, v2, v3) S390_VRRb(c, 0xe7f8, v1, v2, v3, 2, 0) +#define s390_vceqg(c, v1, v2, v3) S390_VRRb(c, 0xe7f8, v1, v2, v3, 3, 0) +#define s390_vceqbs(c, v1, v2, v3) S390_VRRb(c, 0xe7f8, v1, v2, v3, 0, 1) +#define s390_vceqhs(c, v1, v2, v3) S390_VRRb(c, 0xe7f8, v1, v2, v3, 1, 1) +#define s390_vceqfs(c, v1, v2, v3) S390_VRRb(c, 0xe7f8, v1, v2, v3, 2, 1) +#define s390_vceqgs(c, v1, v2, v3) S390_VRRb(c, 0xe7f8, v1, v2, v3, 3, 1) +#define s390_vchb(c, v1, v2, v3) S390_VRRb(c, 0xe7fb, v1, v2, v3, 0, 0) +#define s390_vchh(c, v1, v2, v3) S390_VRRb(c, 0xe7fb, v1, v2, v3, 1, 0) +#define s390_vchf(c, v1, v2, v3) S390_VRRb(c, 0xe7fb, v1, v2, v3, 2, 0) +#define s390_vchg(c, v1, v2, v3) S390_VRRb(c, 0xe7fb, v1, v2, v3, 3, 0) +#define s390_vchbs(c, v1, v2, v3) S390_VRRb(c, 0xe7fb, v1, v2, v3, 0, 1) +#define s390_vchhs(c, v1, v2, v3) S390_VRRb(c, 0xe7fb, v1, v2, v3, 1, 1) +#define s390_vchfs(c, v1, v2, v3) S390_VRRb(c, 0xe7fb, v1, v2, v3, 2, 1) +#define s390_vchgs(c, v1, v2, v3) S390_VRRb(c, 0xe7fb, v1, v2, v3, 3, 1) +#define s390_vchlb(c, v1, v2, v3) S390_VRRb(c, 0xe7f9, v1, v2, v3, 0, 0) +#define s390_vchlh(c, v1, v2, v3) S390_VRRb(c, 0xe7f9, v1, v2, v3, 1, 0) +#define s390_vchlf(c, v1, v2, v3) S390_VRRb(c, 0xe7f9, v1, v2, v3, 2, 0) +#define s390_vchlg(c, v1, v2, v3) S390_VRRb(c, 0xe7f9, v1, v2, v3, 3, 0) +#define s390_vchlbs(c, v1, v2, v3) S390_VRRb(c, 0xe7f9, v1, v2, v3, 0, 1) +#define s390_vchlhs(c, v1, v2, v3) S390_VRRb(c, 0xe7f9, v1, v2, v3, 1, 1) +#define s390_vchlfs(c, v1, v2, v3) S390_VRRb(c, 0xe7f9, v1, v2, v3, 2, 1) +#define s390_vchlgs(c, v1, v2, v3) S390_VRRb(c, 0xe7f9, v1, v2, v3, 3, 1) +#define s390_vecb(c, v1, v2) S390_VRRa(c, 0xe7db, v1, v2, 0, 0, 0) +#define s390_vech(c, v1, v2) S390_VRRa(c, 0xe7db, v1, v2, 1, 0, 0) +#define s390_vecf(c, v1, v2) S390_VRRa(c, 0xe7db, v1, v2, 2, 0, 0) +#define s390_vecg(c, v1, v2) S390_VRRa(c, 0xe7db, v1, v2, 3, 0, 0) +#define s390_veclb(c, v1, v2) S390_VRRa(c, 0xe7d9, v1, v2, 0, 0, 0) +#define s390_veclh(c, v1, v2) S390_VRRa(c, 0xe7d9, v1, v2, 1, 0, 0) +#define s390_veclf(c, v1, v2) S390_VRRa(c, 0xe7d9, v1, v2, 2, 0, 0) +#define s390_veclg(c, v1, v2) S390_VRRa(c, 0xe7d9, v1, v2, 3, 0, 0) +#define s390_vfasb(c, v1, v2, v3) S390_VRRc(c, 0xe7e3, v1, v2, v3, 2, 0, 0) +#define s390_vfadb(c, v1, v2, v3) S390_VRRc(c, 0xe7e3, v1, v2, v3, 3, 0, 0) +#define s390_vfcesb(c, v1, v2, v3) S390_VRRc(c, 0xe7e8, v1, v2, v3, 2, 0, 0) +#define s390_vfcedb(c, v1, v2, v3) S390_VRRc(c, 0xe7e8, v1, v2, v3, 3, 0, 0) +#define s390_vfcesbs(c, v1, v2, v3) S390_VRRc(c, 0xe7e8, v1, v2, v3, 2, 0, 1) +#define s390_vfcedbs(c, v1, v2, v3) S390_VRRc(c, 0xe7e8, v1, v2, v3, 3, 0, 1) +#define s390_vfchsb(c, v1, v2, v3) S390_VRRc(c, 0xe7eb, v1, v2, v3, 2, 0, 0) +#define s390_vfchdb(c, v1, v2, v3) S390_VRRc(c, 0xe7eb, v1, v2, v3, 3, 0, 0) +#define s390_vfchsbs(c, v1, v2, v3) S390_VRRc(c, 0xe7eb, v1, v2, v3, 2, 0, 1) +#define s390_vfchdbs(c, v1, v2, v3) S390_VRRc(c, 0xe7eb, v1, v2, v3, 3, 0, 1) +#define s390_vfchesb(c, v1, v2, v3) S390_VRRc(c, 0xe7ea, v1, v2, v3, 2, 0, 0) +#define s390_vfchedb(c, v1, v2, v3) S390_VRRc(c, 0xe7ea, v1, v2, v3, 3, 0, 0) +#define s390_vfchesbs(c, v1, v2, v3) S390_VRRc(c, 0xe7ea, v1, v2, v3, 2, 0, 1) +#define s390_vfchedbs(c, v1, v2, v3) S390_VRRc(c, 0xe7ea, v1, v2, v3, 3, 0, 1) +#define s390_vfdsb(c, v1, v2, v3) S390_VRRc(c, 0xe7e5, v1, v2, v3, 2, 0, 0) +#define s390_vfddb(c, v1, v2, v3) S390_VRRc(c, 0xe7e5, v1, v2, v3, 3, 0, 0) +#define s390_vfisb(c, v1, v2, m4, m5) S390_VRRa(c, 0xe7c7, v1, v2, 2, m4, m5) +#define s390_vfidb(c, v1, v2, m4, m5) S390_VRRa(c, 0xe7c7, v1, v2, 3, m4, m5) +#define s390_vfmsb(c, v1, v2, v3) S390_VRRc(c, 0xe7e7, v1, v2, v3, 2, 0, 0) +#define s390_vfmdb(c, v1, v2, v3) S390_VRRc(c, 0xe7e7, v1, v2, v3, 3, 0, 0) +#define s390_vfmaxsb(c, v1, v2, v3, m6) S390_VRRc(c, 0xe7ef, v1, v2, v3, 2, 0, m6) +#define s390_vfmaxdb(c, v1, v2, v3, m6) S390_VRRc(c, 0xe7ef, v1, v2, v3, 3, 0, m6) +#define s390_vfminsb(c, v1, v2, v3, m6) S390_VRRc(c, 0xe7ee, v1, v2, v3, 2, 0, m6) +#define s390_vfmindb(c, v1, v2, v3, m6) S390_VRRc(c, 0xe7ee, v1, v2, v3, 3, 0, m6) +#define s390_vfpsosb(c, v1, v2, m5) S390_VRRa(c, 0xe7cc, v1, v2, 2, 0, m5) +#define s390_vfpsodb(c, v1, v2, m5) S390_VRRa(c, 0xe7cc, v1, v2, 3, 0, m5) +#define s390_vfssb(c, v1, v2, v3) S390_VRRc(c, 0xe7e2, v1, v2, v3, 2, 0, 0) +#define s390_vfsdb(c, v1, v2, v3) S390_VRRc(c, 0xe7e2, v1, v2, v3, 3, 0, 0) +#define s390_vfsqsb(c, v1, v2) S390_VRRa(c, 0xe7ce, v1, v2, 2, 0, 0) +#define s390_vfsqdb(c, v1, v2) S390_VRRa(c, 0xe7ce, v1, v2, 3, 0, 0) +#define s390_vgbm(c, v1, i2) S390_VRIa(c, 0xe744, v1, i2, 0) +#define s390_vgmb(c, v1, i2, i3) S390_VRIb(c, 0xe746, v1, i2, i3, 0) +#define s390_vgmh(c, v1, i2, i3) S390_VRIb(c, 0xe746, v1, i2, i3, 1) +#define s390_vgmf(c, v1, i2, i3) S390_VRIb(c, 0xe746, v1, i2, i3, 2) +#define s390_vgmg(c, v1, i2, i3) S390_VRIb(c, 0xe746, v1, i2, i3, 3) +#define s390_vmlb(c, v1, v2, v3) S390_VRRc(c, 0xe7a2, v1, v2, v3, 0, 0, 0) +#define s390_vmlhw(c, v1, v2, v3) S390_VRRc(c, 0xe7a2, v1, v2, v3, 1, 0, 0) +#define s390_vmlf(c, v1, v2, v3) S390_VRRc(c, 0xe7a2, v1, v2, v3, 2, 0, 0) +#define s390_vmnb(c, v1, v2, v3) S390_VRRc(c, 0xe7fe, v1, v2, v3, 0, 0, 0) +#define s390_vmnh(c, v1, v2, v3) S390_VRRc(c, 0xe7fe, v1, v2, v3, 1, 0, 0) +#define s390_vmnf(c, v1, v2, v3) S390_VRRc(c, 0xe7fe, v1, v2, v3, 2, 0, 0) +#define s390_vmng(c, v1, v2, v3) S390_VRRc(c, 0xe7fe, v1, v2, v3, 3, 0, 0) +#define s390_vmnlb(c, v1, v2, v3) S390_VRRc(c, 0xe7fc, v1, v2, v3, 0, 0, 0) +#define s390_vmnlh(c, v1, v2, v3) S390_VRRc(c, 0xe7fc, v1, v2, v3, 1, 0, 0) +#define s390_vmnlf(c, v1, v2, v3) S390_VRRc(c, 0xe7fc, v1, v2, v3, 2, 0, 0) +#define s390_vmnlg(c, v1, v2, v3) S390_VRRc(c, 0xe7fc, v1, v2, v3, 3, 0, 0) +#define s390_vmxb(c, v1, v2, v3) S390_VRRc(c, 0xe7ff, v1, v2, v3, 0, 0, 0) +#define s390_vmxh(c, v1, v2, v3) S390_VRRc(c, 0xe7ff, v1, v2, v3, 1, 0, 0) +#define s390_vmxf(c, v1, v2, v3) S390_VRRc(c, 0xe7ff, v1, v2, v3, 2, 0, 0) +#define s390_vmxg(c, v1, v2, v3) S390_VRRc(c, 0xe7ff, v1, v2, v3, 3, 0, 0) +#define s390_vmxlb(c, v1, v2, v3) S390_VRRc(c, 0xe7fd, v1, v2, v3, 0, 0, 0) +#define s390_vmxlh(c, v1, v2, v3) S390_VRRc(c, 0xe7fd, v1, v2, v3, 1, 0, 0) +#define s390_vmxlf(c, v1, v2, v3) S390_VRRc(c, 0xe7fd, v1, v2, v3, 2, 0, 0) +#define s390_vmxlg(c, v1, v2, v3) S390_VRRc(c, 0xe7fd, v1, v2, v3, 3, 0, 0) +#define s390_vn(c, v1, v2, v3) S390_VRRc(c, 0xe768, v1, v2, v3, 0, 0, 0) +#define s390_vnc(c, v1, v2, v3) S390_VRRc(c, 0xe769, v1, v2, v3, 0, 0, 0) +#define s390_vnn(c, v1, v2, v3) S390_VRRc(c, 0xe76e, v1, v2, v3, 0, 0, 0) +#define s390_vno(c, v1, v2, v3) S390_VRRc(c, 0xe76b, v1, v2, v3, 0, 0, 0) +#define s390_vo(c, v1, v2, v3) S390_VRRc(c, 0xe76a, v1, v2, v3, 0, 0, 0) +#define s390_vl(c, v, x, b, d) S390_VRX(c, 0xe706, v, x, b, d, 0) +#define s390_vlcb(c, v1, v2) S390_VRRa(c, 0xe7de, v1, v2, 0, 0, 0) +#define s390_vlch(c, v1, v2) S390_VRRa(c, 0xe7de, v1, v2, 1, 0, 0) +#define s390_vlcf(c, v1, v2) S390_VRRa(c, 0xe7de, v1, v2, 2, 0, 0) +#define s390_vlcg(c, v1, v2) S390_VRRa(c, 0xe7de, v1, v2, 3, 0, 0) +#define s390_vleg(c, v, d, x, b, m) S390_VRX(c, 0xe702, v, x, b, d, m) +#define s390_vleib(c, v1, i2, m3) S390_VRIa(c, 0xe740, v1, i2, m3) +#define s390_vleih(c, v1, i2, m3) S390_VRIa(c, 0xe741, v1, i2, m3) +#define s390_vleif(c, v1, i2, m3) S390_VRIa(c, 0xe743, v1, i2, m3) +#define s390_vleig(c, v1, i2, m3) S390_VRIa(c, 0xe742, v1, i2, m3) +#define s390_vlgvb(c, r1, v2, d3, b4) S390_VRSc(c, 0xe721, r1, v2, d3, b4, 0) +#define s390_vlgvh(c, r1, v2, d3, b4) S390_VRSc(c, 0xe721, r1, v2, d3, b4, 1) +#define s390_vlgvf(c, r1, v2, d3, b4) S390_VRSc(c, 0xe721, r1, v2, d3, b4, 2) +#define s390_vlgvg(c, r1, v2, d3, b4) S390_VRSc(c, 0xe721, r1, v2, d3, b4, 3) #define s390_vlm(c, v1, v2, b, d, m) S390_VRSa(c, 0xe736, v1, v2, b, d, m) +#define s390_vlpb(c, v1, v2) S390_VRRa(c, 0xe7df, v1, v2, 0, 0, 0) +#define s390_vlph(c, v1, v2) S390_VRRa(c, 0xe7df, v1, v2, 1, 0, 0) +#define s390_vlpf(c, v1, v2) S390_VRRa(c, 0xe7df, v1, v2, 2, 0, 0) +#define s390_vlpg(c, v1, v2) S390_VRRa(c, 0xe7df, v1, v2, 3, 0, 0) +#define s390_vlr(c, v1, v2) S390_VRRa(c,0xe756, v1, v2, 0, 0, 0) +#define s390_vlvgb(c, v1, r2, d3, b4) S390_VRSb(c, 0xe722, v1, r2, d3, b4, 0) +#define s390_vlvgh(c, v1, r2, d3, b4) S390_VRSb(c, 0xe722, v1, r2, d3, b4, 1) +#define s390_vlvgf(c, v1, r2, d3, b4) S390_VRSb(c, 0xe722, v1, r2, d3, b4, 2) +#define s390_vlvgg(c, v1, r2, d3, b4) S390_VRSb(c, 0xe722, v1, r2, d3, b4, 3) +#define s390_vperm(c, v1, v2, v3, v4) S390_VRRe(c, 0xe78c, v1, v2, v3, v4, 0, 0); +#define s390_vpkh(c, v1, v2, v3) S390_VRRc(c, 0xe794, v1, v2, v3, 1, 0, 0) +#define s390_vpkf(c, v1, v2, v3) S390_VRRc(c, 0xe794, v1, v2, v3, 2, 0, 0) +#define s390_vpkg(c, v1, v2, v3) S390_VRRc(c, 0xe794, v1, v2, v3, 3, 0, 0) +#define s390_vrepb(c, v1, v3, i2) S390_VRIc(c, 0xe74d, v1 ,v3, i2, 0) +#define s390_vreph(c, v1, v3, i2) S390_VRIc(c, 0xe74d, v1 ,v3, i2, 1) +#define s390_vrepf(c, v1, v3, i2) S390_VRIc(c, 0xe74d, v1 ,v3, i2, 2) +#define s390_vrepg(c, v1, v3, i2) S390_VRIc(c, 0xe74d, v1 ,v3, i2, 3) +#define s390_vrepib(c, v1, i2) S390_VRIa(c, 0xe745, v1, i2, 0) +#define s390_vrepih(c, v1, i2) S390_VRIa(c, 0xe745, v1, i2, 1) +#define s390_vrepif(c, v1, i2) S390_VRIa(c, 0xe745, v1, i2, 2) +#define s390_vrepig(c, v1, i2) S390_VRIa(c, 0xe745, v1, i2, 3) +#define s390_vsb(c, v1, v2, v3) S390_VRRc(c, 0xe7f7, v1, v2, v3, 0, 0, 0) +#define s390_vsh(c, v1, v2, v3) S390_VRRc(c, 0xe7f7, v1, v2, v3, 1, 0, 0) +#define s390_vsf(c, v1, v2, v3) S390_VRRc(c, 0xe7f7, v1, v2, v3, 2, 0, 0) +#define s390_vsg(c, v1, v2, v3) S390_VRRc(c, 0xe7f7, v1, v2, v3, 3, 0, 0) +#define s390_vsq(c, v1, v2, v3) S390_VRRc(c, 0xe7f7, v1, v2, v3, 4, 0, 0) +#define s390_vst(c, v, x, b, d) S390_VRX(c,0xe70e, v, x, b, d, 0) +#define s390_vsteg(c, v, d, x, b, m) S390_VRX(c, 0xe70a, v, x, b, d, m) #define s390_vstm(c, v1, v2, b, d, m) S390_VRSa(c, 0xe73e, v1, v2, b, d, m) +#define s390_vsumb(c, v1, v2, v3) S390_VRRc(c, 0xe764, v1, v2, v3, 0, 0, 0) +#define s390_vsumh(c, v1, v2, v3) S390_VRRc(c, 0xe764, v1, v2, v3, 1, 0, 0) +#define s390_vsumqf(c, v1, v2, v3) S390_VRRc(c, 0xe767, v1, v2, v3, 2, 0, 0) +#define s390_vsumqg(c, v1, v2, v3) S390_VRRc(c, 0xe767, v1, v2, v3, 3, 0, 0) +#define s390_vuplb(c, v1, v2) S390_VRRa(c, 0xe7d6, v1, v2, 0, 0, 0) +#define s390_vuplhw(c, v1, v2) S390_VRRa(c, 0xe7d6, v1, v2, 1, 0, 0) +#define s390_vuplf(c, v1, v2) S390_VRRa(c, 0xe7d6, v1, v2, 2, 0, 0) +#define s390_vupllb(c, v1, v2) S390_VRRa(c, 0xe7d4, v1, v2, 0, 0, 0) +#define s390_vupllh(c, v1, v2) S390_VRRa(c, 0xe7d4, v1, v2, 1, 0, 0) +#define s390_vupllf(c, v1, v2) S390_VRRa(c, 0xe7d4, v1, v2, 2, 0, 0) +#define s390_vuplhb(c, v1, v2) S390_VRRa(c, 0xe7d5, v1, v2, 0, 0, 0) +#define s390_vuplhh(c, v1, v2) S390_VRRa(c, 0xe7d5, v1, v2, 1, 0, 0) +#define s390_vuplhf(c, v1, v2) S390_VRRa(c, 0xe7d5, v1, v2, 2, 0, 0) +#define s390_vuphb(c, v1, v2) S390_VRRa(c, 0xe7d7, v1, v2, 0, 0, 0) +#define s390_vuphh(c, v1, v2) S390_VRRa(c, 0xe7d7, v1, v2, 1, 0, 0) +#define s390_vuphf(c, v1, v2) S390_VRRa(c, 0xe7d7, v1, v2, 2, 0, 0) +#define s390_vx(c, v1, v2, v3) S390_VRRc(c, 0xe76d, v1, v2, v3, 0, 0, 0) #define s390_x(c, r, x, b, d) S390_RX(c, 0x57, r, x, b, d) #define s390_xihf(c, r, v) S390_RIL_1(c, 0xc06, r, v) #define s390_xilf(c, r, v) S390_RIL_1(c, 0xc07, r, v) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index ea283037a11df2..3cd51abf6f6bfc 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -4140,7 +4140,7 @@ jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo) if (assembly) { DebuggerTlsData *tls; tls = (DebuggerTlsData *)mono_native_tls_get_value (debugger_tls_id); - if (!CHECK_ICORDBG (TRUE) || tls->invoke == NULL) { + if (!CHECK_ICORDBG (TRUE) || !tls || tls->invoke == NULL) { process_profiler_event (EVENT_KIND_ASSEMBLY_LOAD, assembly); } else { mono_dbg_assembly_load (prof, assembly); //send later diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index c0d0a85bd3a270..4da928f956a79f 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -355,6 +355,14 @@ ep_rt_atomic_dec_int64_t (volatile int64_t *value) return (int64_t)mono_atomic_dec_i64 ((volatile gint64 *)value); } +static +inline +int64_t +ep_rt_atomic_compare_exchange_int64_t (volatile int64_t *target, int64_t expected, int64_t value) +{ + return (int64_t)(mono_atomic_cas_i64 ((volatile gint64 *)(target), (gint64)(value), (gint64)(expected))); +} + static inline size_t diff --git a/src/mono/mono/metadata/class-init.c b/src/mono/mono/metadata/class-init.c index 6b8daf900f7494..52f108fc7cc9a0 100644 --- a/src/mono/mono/metadata/class-init.c +++ b/src/mono/mono/metadata/class-init.c @@ -317,6 +317,13 @@ mono_class_setup_fields (MonoClass *klass) if (explicit_size) instance_size += real_size; + if (explicit_size && real_size != 0 && m_class_is_inlinearray (klass)) { + if (mono_get_runtime_callbacks ()->mono_class_set_deferred_type_load_failure_callback) + mono_get_runtime_callbacks ()->mono_class_set_deferred_type_load_failure_callback (klass, "Inline array must not have explicit size."); + else + mono_class_set_type_load_failure (klass, "Inline array must not have explicit size."); + } + /* * This function can recursively call itself. * Prevent infinite recursion by using a list in TLS. diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index 5fa79bcca9c6e7..ba56a62ad6b818 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -889,6 +889,7 @@ typedef struct { MonoClass *threadabortexception_class; MonoClass *thread_class; MonoClass *internal_thread_class; + MonoClass *gc_class; MonoClass *autoreleasepool_class; MonoClass *mono_method_message_class; MonoClass *field_info_class; diff --git a/src/mono/mono/metadata/domain.c b/src/mono/mono/metadata/domain.c index 967e33f28df61c..13bb7a408564f7 100644 --- a/src/mono/mono/metadata/domain.c +++ b/src/mono/mono/metadata/domain.c @@ -238,6 +238,9 @@ mono_init_internal (const char *root_domain_name) /* There is only one thread class */ mono_defaults.internal_thread_class = mono_defaults.thread_class; + mono_defaults.gc_class = mono_class_load_from_name ( + mono_defaults.corlib, "System", "GC"); + #if defined(HOST_DARWIN) mono_defaults.autoreleasepool_class = mono_class_try_load_from_name ( mono_defaults.corlib, "System.Threading", "AutoreleasePool"); diff --git a/src/mono/mono/metadata/gc.c b/src/mono/mono/metadata/gc.c index 9c49d2803cd95a..7065b6fe85fabd 100644 --- a/src/mono/mono/metadata/gc.c +++ b/src/mono/mono/metadata/gc.c @@ -81,9 +81,8 @@ static gboolean finalizer_thread_exited; static MonoCoopCond exited_cond; static MonoInternalThread *gc_thread; -#ifndef HOST_WASM -static RuntimeInvokeFunction finalize_runtime_invoke; -#endif + +static MonoMethod *finalize_helper; /* * This must be a GHashTable, since these objects can't be finalized @@ -280,31 +279,14 @@ mono_gc_run_finalize (void *obj, void *data) return; } - - /* - * To avoid the locking plus the other overhead of mono_runtime_invoke_checked (), - * create and precompile a wrapper which calls the finalize method using - * a CALLVIRT. - */ if (mono_log_finalizers) g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Compiling finalizer.", o_name, o); -#ifndef HOST_WASM - if (!finalize_runtime_invoke) { - MonoMethod *finalize_method = mono_class_get_method_from_name_checked (mono_defaults.object_class, "Finalize", 0, 0, error); + if (!finalize_helper) { + finalize_helper = mono_class_get_method_from_name_checked (mono_defaults.gc_class, "GuardedFinalize", 1, 0, error); mono_error_assert_ok (error); - MonoMethod *invoke = mono_marshal_get_runtime_invoke (finalize_method, TRUE); - - finalize_runtime_invoke = (RuntimeInvokeFunction)mono_compile_method_checked (invoke, error); - mono_error_assert_ok (error); /* expect this not to fail */ } - RuntimeInvokeFunction runtime_invoke = finalize_runtime_invoke; -#endif - - mono_runtime_class_init_full (o->vtable, error); - goto_if_nok (error, unhandled_error); - if (G_UNLIKELY (MONO_GC_FINALIZE_INVOKE_ENABLED ())) { MONO_GC_FINALIZE_INVOKE ((unsigned long)o, mono_object_get_size_internal (o), o_ns, o_name); @@ -315,23 +297,15 @@ mono_gc_run_finalize (void *obj, void *data) MONO_PROFILER_RAISE (gc_finalizing_object, (o)); -#ifdef HOST_WASM - MonoMethod* finalizer = mono_class_get_finalizer (o->vtable->klass); - if (finalizer) { // null finalizers work fine when using the vcall invoke as Object has an empty one - gpointer params [1]; - params [0] = NULL; - mono_runtime_try_invoke (finalizer, o, params, &exc, error); - } -#else - runtime_invoke (o, NULL, &exc, NULL); -#endif + gpointer params [1]; + params [0] = o; + mono_runtime_try_invoke (finalize_helper, NULL, params, &exc, error); MONO_PROFILER_RAISE (gc_finalized_object, (o)); if (mono_log_finalizers) g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Returned from finalizer.", o_name, o); -unhandled_error: if (!is_ok (error)) exc = (MonoObject*)mono_error_convert_to_exception (error); if (exc) diff --git a/src/mono/mono/metadata/loader-internals.h b/src/mono/mono/metadata/loader-internals.h index c9a340f928b7b2..2f422904e691b7 100644 --- a/src/mono/mono/metadata/loader-internals.h +++ b/src/mono/mono/metadata/loader-internals.h @@ -264,7 +264,7 @@ static inline MonoGCHandle mono_alc_get_gchandle_for_resolving (MonoAssemblyLoadContext *alc) { /* for the default ALC, pass NULL to ask for the Default ALC - see - * AssemblyLoadContext.GetAssemblyLoadContext(IntPtr gchManagedAssemblyLoadContext) - which + * AssemblyLoadContext.GetAssemblyLoadContext(IntPtr gchAssemblyLoadContext) - which * will create the managed ALC object if it hasn't been created yet */ if (alc->gchandle == mono_alc_get_default ()->gchandle) diff --git a/src/mono/mono/metadata/object-internals.h b/src/mono/mono/metadata/object-internals.h index e464c87b9e3b72..a25b69923a8181 100644 --- a/src/mono/mono/metadata/object-internals.h +++ b/src/mono/mono/metadata/object-internals.h @@ -1462,7 +1462,7 @@ typedef struct { typedef enum { ALIVE = 0, UNLOADING = 1 -} MonoManagedAssemblyLoadContextInternalState; +} MonoAssemblyLoadContextInternalState; typedef struct { diff --git a/src/mono/mono/metadata/reflection.c b/src/mono/mono/metadata/reflection.c index ea3d4bb282787e..192a030a80ce50 100644 --- a/src/mono/mono/metadata/reflection.c +++ b/src/mono/mono/metadata/reflection.c @@ -2728,9 +2728,8 @@ reflection_bind_generic_method_parameters (MonoMethod *method, MonoArrayHandle t tmp_context.method_inst = ginst; inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, error); - mono_error_assert_ok (error); - if (!mono_verifier_is_method_valid_generic_instantiation (inflated)) { + if (!is_ok(error) || !inflated || !mono_verifier_is_method_valid_generic_instantiation (inflated)) { mono_error_set_argument (error, NULL, "Invalid generic arguments"); return NULL; } diff --git a/src/mono/mono/mini/CMakeLists.txt b/src/mono/mono/mini/CMakeLists.txt index a2b3bdae9a72c0..23b8d15bf708f1 100644 --- a/src/mono/mono/mini/CMakeLists.txt +++ b/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/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 033ef0d96b94b3..67c4daaa835ca9 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -4977,7 +4977,7 @@ add_full_aot_wrappers (MonoAotCompile *acfg) add_method (acfg, get_runtime_invoke_sig (csig)); /* runtime-invoke used by finalizers */ - add_method (acfg, get_runtime_invoke (acfg, get_method_nofail (mono_defaults.object_class, "Finalize", 0, 0), TRUE)); + add_method (acfg, get_runtime_invoke (acfg, get_method_nofail (mono_defaults.gc_class, "GuardedFinalize", 1, 0), FALSE)); /* This is used by mono_runtime_capture_context () */ method = mono_get_context_capture_method (); diff --git a/src/mono/mono/mini/cpu-s390x.mdesc b/src/mono/mono/mini/cpu-s390x.mdesc index 8e699367ecc155..74959cb5a1dcb3 100644 --- a/src/mono/mono/mini/cpu-s390x.mdesc +++ b/src/mono/mono/mini/cpu-s390x.mdesc @@ -472,3 +472,171 @@ s390_cij: len:24 s390_cij_un: src1:i len:24 s390_cgij: len:24 s390_cgij_un: len:24 + +insert_i1: dest:x src1:x src2:i len:12 +insert_i2: dest:x src1:x src2:i len:12 +insert_i4: dest:x src1:x src2:i len:12 +insert_i8: dest:x src1:x src2:i len:12 +insert_r4: dest:x src1:x src2:f clob:1 len:12 +insert_r8: dest:x src1:x src2:f clob:1 len:12 + +extract_i1: dest:i src1:x len:6 +extract_i2: dest:i src1:x len:6 +extract_i4: dest:i src1:x len:6 +extract_i8: dest:i src1:x len:6 +extract_r4: dest:f src1:x len:12 +extract_r8: dest:f src1:x len:12 + +xextract_i1: dest:i src1:x src2:i len:6 +xextract_i2: dest:i src1:x src2:i len:6 +xextract_i4: dest:i src1:x src2:i len:6 +xextract_i8: dest:i src1:x src2:i len:6 +xextract_r4: dest:f src1:x src2:i len:10 +xextract_r8: dest:f src1:x src2:i len:10 + +expand_i1: dest:x src1:i len:12 +expand_i2: dest:x src1:i len:12 +expand_i4: dest:x src1:i len:12 +expand_i8: dest:x src1:i len:12 +expand_r4: dest:x src1:f len:18 +expand_r8: dest:x src1:f len:16 + +xones: dest:x len:6 +xmove: dest:x src1:x len:6 +xzero: dest:x len:6 +loadx_membase: dest:x src1:b len:26 +storex_membase: dest:b src1:x len:26 +s390_vab: dest:x src1:x src2:x len:6 +s390_vah: dest:x src1:x src2:x len:6 +s390_vaf: dest:x src1:x src2:x len:6 +s390_vag: dest:x src1:x src2:x len:6 +s390_vfasb: dest:x src1:x src2:x len:6 +s390_vfadb: dest:x src1:x src2:x len:6 +s390_vsb: dest:x src1:x src2:x len:6 +s390_vsh: dest:x src1:x src2:x len:6 +s390_vsf: dest:x src1:x src2:x len:6 +s390_vsg: dest:x src1:x src2:x len:6 +s390_vfssb: dest:x src1:x src2:x len:6 +s390_vfsdb: dest:x src1:x src2:x len:6 +s390_vx: dest:x src1:x src2:x len:6 +s390_vo: dest:x src1:x src2:x len:6 +s390_vno: dest:x src1:x src2:x len:6 +s390_vn: dest:x src1:x src2:x len:6 +vector_andnot: dest:x src1:x src2:x len:6 +s390_vnn: dest:x src1:x src2:x len:6 +s390_vmlb: dest:x src1:x src2:x len:6 +s390_vmlhw: dest:x src1:x src2:x len:6 +s390_vmlf: dest:x src1:x src2:x len:6 +s390_vfmsb: dest:x src1:x src2:x len:6 +s390_vfmdb: dest:x src1:x src2:x len:6 +s390_vfdsb: dest:x src1:x src2:x len:6 +s390_vfddb: dest:x src1:x src2:x len:6 +s390_vmxb: dest:x src1:x src2:x len:6 +s390_vmxh: dest:x src1:x src2:x len:6 +s390_vmxf: dest:x src1:x src2:x len:6 +s390_vmxg: dest:x src1:x src2:x len:6 +s390_vmnb: dest:x src1:x src2:x len:6 +s390_vmnh: dest:x src1:x src2:x len:6 +s390_vmnf: dest:x src1:x src2:x len:6 +s390_vmng: dest:x src1:x src2:x len:6 +s390_vmxlb: dest:x src1:x src2:x len:6 +s390_vmxlh: dest:x src1:x src2:x len:6 +s390_vmxlf: dest:x src1:x src2:x len:6 +s390_vmxlg: dest:x src1:x src2:x len:6 +s390_vfmaxsb: dest:x src1:x src2:x len:6 +s390_vfmaxdb: dest:x src1:x src2:x len:6 +s390_vmnlb: dest:x src1:x src2:x len:6 +s390_vmnlh: dest:x src1:x src2:x len:6 +s390_vmnlf: dest:x src1:x src2:x len:6 +s390_vmnlg: dest:x src1:x src2:x len:6 +s390_vfminsb: dest:x src1:x src2:x len:6 +s390_vfmindb: dest:x src1:x src2:x len:6 +s390_vsumb: dest:x src1:x src2:x len:6 +s390_vsumh: dest:x src1:x src2:x len:6 +s390_vsumqf: dest:x src1:x src2:x len:6 +s390_vsumqg: dest:x src1:x src2:x len:6 +s390_vperm: dest:x src1:x src2:x len:6 +s390_vrepib: dest:x len:6 +s390_vrepih: dest:x len:6 +s390_vrepif: dest:x len:6 +s390_vrepig: dest:x len:6 +s390_vceqbs: dest:x src1:x src2:x len:6 +s390_vceqhs: dest:x src1:x src2:x len:6 +s390_vceqfs: dest:x src1:x src2:x len:6 +s390_vceqgs: dest:x src1:x src2:x len:6 +s390_vceqb: dest:x src1:x src2:x len:6 +s390_vceqh: dest:x src1:x src2:x len:6 +s390_vceqf: dest:x src1:x src2:x len:6 +s390_vceqg: dest:x src1:x src2:x len:6 +s390_vfcesbs: dest:x src1:x src2:x len:6 +s390_vfcedbs: dest:x src1:x src2:x len:6 +s390_vfchsbs: dest:x src1:x src2:x len:6 +s390_vfchdbs: dest:x src1:x src2:x len:6 +s390_vfcesb: dest:x src1:x src2:x len:6 +s390_vfcedb: dest:x src1:x src2:x len:6 +s390_vfchsb: dest:x src1:x src2:x len:6 +s390_vfchdb: dest:x src1:x src2:x len:6 +s390_vgmb: dest:x src1:i src2:i len:6 +s390_vgmh: dest:x src1:i src2:i len:6 +s390_vgmf: dest:x src1:i src2:i len:6 +s390_vgmg: dest:x src1:i src2:i len:6 +s390_vecb: dest:x src1:x len:6 +s390_vech: dest:x src1:x len:6 +s390_vecf: dest:x src1:x len:6 +s390_vecg: dest:x src1:x len:6 +s390_veclb: dest:x src1:x len:6 +s390_veclh: dest:x src1:x len:6 +s390_veclf: dest:x src1:x len:6 +s390_veclg: dest:x src1:x len:6 +s390_vchbs: dest:x src1:x src2:x len:6 +s390_vchhs: dest:x src1:x src2:x len:6 +s390_vchfs: dest:x src1:x src2:x len:6 +s390_vchgs: dest:x src1:x src2:x len:6 +s390_vchb: dest:x src1:x src2:x len:6 +s390_vchh: dest:x src1:x src2:x len:6 +s390_vchf: dest:x src1:x src2:x len:6 +s390_vchg: dest:x src1:x src2:x len:6 +s390_vfsqsb: dest:x src1:x len:6 +s390_vfsqdb: dest:x src1:x len:6 +s390_vchlbs: dest:x src1:x src2:x len:6 +s390_vchlhs: dest:x src1:x src2:x len:6 +s390_vchlfs: dest:x src1:x src2:x len:6 +s390_vchlgs: dest:x src1:x src2:x len:6 +s390_vchlb: dest:x src1:x src2:x len:6 +s390_vchlh: dest:x src1:x src2:x len:6 +s390_vchlf: dest:x src1:x src2:x len:6 +s390_vchlg: dest:x src1:x src2:x len:6 +s390_vfchesbs: dest:x src1:x src2:x len:6 +s390_vfchedbs: dest:x src1:x src2:x len:6 +s390_vfchesb: dest:x src1:x src2:x len:6 +s390_vfchedb: dest:x src1:x src2:x len:6 +s390_vlpb: dest:x src1:x len:6 +s390_vlph: dest:x src1:x len:6 +s390_vlpf: dest:x src1:x len:6 +s390_vlpg: dest:x src1:x len:6 +s390_vflpdb: dest:x src1:x len:6 +s390_vflpsb: dest:x src1:x len:6 +s390_vflcdb: dest:x src1:x len:6 +s390_vflcsb: dest:x src1:x len:6 +s390_vpkh: dest:x src1:x src2:x len:6 +s390_vpkf: dest:x src1:x src2:x len:6 +s390_vpkg: dest:x src1:x src2:x len:6 +s390_vlcb: dest:x src1:x len:6 +s390_vlch: dest:x src1:x len:6 +s390_vlcf: dest:x src1:x len:6 +s390_vlcg: dest:x src1:x len:6 +s390_vuplb: dest:x src1:x len:6 +s390_vuplhw: dest:x src1:x len:6 +s390_vuplf: dest:x src1:x len:6 +s390_vupllb: dest:x src1:x len:6 +s390_vupllh: dest:x src1:x len:6 +s390_vupllf: dest:x src1:x len:6 +s390_vuphb: dest:x src1:x len:6 +s390_vuphh: dest:x src1:x len:6 +s390_vuphf: dest:x src1:x len:6 +s390_vuplhb: dest:x src1:x len:6 +s390_vuplhh: dest:x src1:x len:6 +s390_vuplhf: dest:x src1:x len:6 +s390_vfisb: dest:x src1:x len:6 +s390_vfidb: dest:x src1:x len:6 +xconst: dest:x len:18 diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 68c301ea889a06..f3cc76774ce8ea 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -985,6 +985,48 @@ stackval_to_data (MonoType *type, stackval *val, void *data, gboolean pinvoke) } } +static void +stackval_to_data_sign_ext (MonoType *type, stackval *val, void *data, gboolean pinvoke) +{ + switch (type->type) { + case MONO_TYPE_I1: { + mono_i *p = (mono_i*)data; + *p = (mono_i)((gint8)val->data.i); + break; + } + case MONO_TYPE_U1: { + mono_u *p = (mono_u*)data; + *p = (mono_u)((guint8)val->data.i); + break; + } + case MONO_TYPE_I2: { + mono_i *p = (mono_i*)data; + *p = (mono_i)((gint16)val->data.i); + break; + } + case MONO_TYPE_U2: { + mono_u *p = (mono_u*)data; + *p = (mono_u)((guint16)val->data.i); + break; + } +#if SIZEOF_VOID_P == 8 + case MONO_TYPE_I4: { + mono_i *p = (mono_i*)data; + *p = (mono_i)(val->data.i); + break; + } + case MONO_TYPE_U4: { + mono_u *p = (mono_u*)data; + *p = (mono_u)((guint32)val->data.i); + break; + } +#endif + default: + stackval_to_data (type, val, data, pinvoke); + break; + } +} + typedef struct { MonoException *ex; MonoContext *ctx; @@ -1651,7 +1693,7 @@ interp_frame_arg_to_data (MonoInterpFrameHandle frame, MonoMethodSignature *sig, // If index == -1, we finished executing an InterpFrame and the result is at retval. if (index == -1) - stackval_to_data (sig->ret, iframe->retval, data, sig->pinvoke && !sig->marshalling_disabled); + stackval_to_data_sign_ext (sig->ret, iframe->retval, data, sig->pinvoke && !sig->marshalling_disabled); else if (sig->hasthis && index == 0) *(gpointer*)data = iframe->stack->data.p; else @@ -2353,8 +2395,17 @@ interp_entry (InterpEntryData *data) // The return value is at the bottom of the stack, after the locals space type = rmethod->rtype; - if (type->type != MONO_TYPE_VOID) - stackval_to_data (type, frame.stack, data->res, FALSE); + if (type->type != MONO_TYPE_VOID) { + // interp entry is called either from a interp_in wrapper or a gsharedvt_in_sig wrapper + // interp_in wrappers always return intptr (they are more aggresively shared) while the + // gsharedvt_in_sig wrapper returns the actual type. This check follows the logic in + // interp_create_method_pointer_llvmonly and interp_create_method_pointer so we do the + // return sign extension only when called from the interp_in wrapper. + if (!mono_llvm_only || sig->param_count > MAX_INTERP_ENTRY_ARGS) + stackval_to_data_sign_ext (type, frame.stack, data->res, FALSE); + else + stackval_to_data (type, frame.stack, data->res, FALSE); + } } static void diff --git a/src/mono/mono/mini/interp/simd-methods.def b/src/mono/mono/mini/interp/simd-methods.def index 581c907419e2bc..cde14690f727aa 100644 --- a/src/mono/mono/mini/interp/simd-methods.def +++ b/src/mono/mono/mini/interp/simd-methods.def @@ -23,6 +23,7 @@ SIMD_METHOD(op_UnaryNegation) SIMD_METHOD(op_UnsignedRightShift) SIMD_METHOD(Abs) +SIMD_METHOD(AddSaturate) SIMD_METHOD(AndNot) SIMD_METHOD(As) SIMD_METHOD(AsByte) @@ -70,6 +71,7 @@ SIMD_METHOD(Max) SIMD_METHOD(Min) SIMD_METHOD(OnesComplement) SIMD_METHOD(Round) +SIMD_METHOD(SubtractSaturate) SIMD_METHOD(ShiftLeft) SIMD_METHOD(ShiftRightArithmetic) SIMD_METHOD(ShiftRightLogical) diff --git a/src/mono/mono/mini/interp/transform-simd.c b/src/mono/mono/mini/interp/transform-simd.c index 9f30126531f505..6f689433361847 100644 --- a/src/mono/mono/mini/interp/transform-simd.c +++ b/src/mono/mono/mini/interp/transform-simd.c @@ -148,6 +148,7 @@ static guint16 sri_packedsimd_methods [] = { static guint16 packedsimd_alias_methods [] = { SN_Abs, SN_Add, + SN_AddSaturate, SN_AndNot, SN_BitwiseAnd, SN_BitwiseOr, @@ -175,6 +176,7 @@ static guint16 packedsimd_alias_methods [] = { SN_Store, SN_StoreUnsafe, SN_Subtract, + SN_SubtractSaturate, SN_Sqrt, SN_SquareRoot, SN_Truncate, @@ -1256,8 +1258,10 @@ emit_sri_packedsimd (TransformData *td, MonoMethod *cmethod, MonoMethodSignature cmethod_name = "Store"; break; case SN_Add: + case SN_AddSaturate: case SN_AndNot: case SN_Subtract: + case SN_SubtractSaturate: case SN_Ceiling: case SN_ConvertToSingle: case SN_Floor: diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 11912e096cdcbe..266c658ba1563b 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -2139,6 +2139,16 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas return TRUE; } } + } else if (in_corlib && !strcmp (klass_name_space, "System") && (!strcmp (klass_name, "BitConverter"))) { + if (!strcmp (tm, "DoubleToInt64Bits") || !strcmp (tm, "DoubleToUInt64Bits")) { + *op = MINT_MOV_8; + } else if (!strcmp (tm, "Int32BitsToSingle") || !strcmp (tm, "UInt32BitsToSingle")) { + *op = MINT_MOV_4; + } else if (!strcmp (tm, "Int64BitsToDouble") || !strcmp (tm, "UInt64BitsToDouble")) { + *op = MINT_MOV_8; + } else if (!strcmp (tm, "SingleToInt32Bits") || !strcmp (tm, "SingleToUInt32Bits")) { + *op = MINT_MOV_4; + } } else if (in_corlib && !strcmp (klass_name_space, "System.Runtime.CompilerServices") && !strcmp (klass_name, "Unsafe")) { if (!strcmp (tm, "AddByteOffset")) #if SIZEOF_VOID_P == 4 @@ -2156,6 +2166,72 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas return TRUE; } else if (!strcmp (tm, "AreSame")) { *op = MINT_CEQ_P; + } else if (!strcmp (tm, "BitCast")) { + MonoGenericContext *ctx = mono_method_get_context (target_method); + g_assert (ctx); + g_assert (ctx->method_inst); + g_assert (ctx->method_inst->type_argc == 2); + g_assert (csignature->param_count == 1); + + // We explicitly do not handle gsharedvt as it is meant as a slow fallback strategy + // instead we fallback to the managed implementation which will do the right things + + MonoType *tfrom = ctx->method_inst->type_argv [0]; + MonoType *tto = ctx->method_inst->type_argv [1]; + tfrom = mini_get_underlying_type (tfrom); + tto = mini_get_underlying_type (tto); + + // The underlying API always throws for reference type inputs, so we + // fallback to the managed implementation to let that handling occur + + if (MONO_TYPE_IS_REFERENCE (tfrom) || MONO_TYPE_IS_REFERENCE (tto)) { + return FALSE; + } + + MonoClass *tto_klass = mono_class_from_mono_type_internal (tto); + + // The same applies for when the type sizes do not match, as this will always throw + // and so its not an expected case and we can fallback to the managed implementation + + int tfrom_align, tto_align; + gint32 size = mono_type_size (tfrom, &tfrom_align); + if (size != mono_type_size (tto, &tto_align)) { + return FALSE; + } + g_assert (size < G_MAXUINT16); + + // We have several different move opcodes to handle the data depending on the + // source and target types, so detect and optimize the most common ones falling + // back to what is effectively `ReadUnaligned(ref As(ref source))` + // for anything that can't be special cased as potentially zero-cost move. + + if (m_class_is_enumtype (tto_klass)) { + tto = mono_class_enum_basetype_internal (tto_klass); + } + + int mov_op = interp_get_mov_for_type (mono_mint_type (tto), TRUE); + + if (mov_op == MINT_MOV_VT ) { + if (size <= 4) { + *op = MINT_MOV_4; + } else if (size <= 8) { + *op = MINT_MOV_8; + } else { + td->sp--; + interp_add_ins (td, MINT_MOV_VT); + interp_ins_set_sreg (td->last_ins, td->sp [0].var); + push_type_vt (td, tto_klass, size); + interp_ins_set_dreg (td->last_ins, td->sp [-1].var); + td->last_ins->data [0] = GINT32_TO_UINT16 (size); + td->ip += 5; + return TRUE; + } + } else { + if (size < 4) + return FALSE; + + *op = mov_op; + } } else if (!strcmp (tm, "ByteOffset")) { #if SIZEOF_VOID_P == 4 interp_add_ins (td, MINT_SUB_I4); @@ -3394,6 +3470,12 @@ interp_realign_simd_params (TransformData *td, StackInfo *sp_params, int num_arg td->last_ins->data [0] = GINT_TO_UINT16 (sp_params [i].offset + prev_offset); td->last_ins->data [1] = offset_amount; td->last_ins->data [2] = GINT_TO_UINT16 (get_stack_size (td, sp_params + i, num_args - i)); + + // The stack move applies to all arguments starting at this one. Because we push + // simd valuetypes in aligned fashion on the execution stack, the offset between two + // simd values will be a multiple of simd alignment. This means that if this arg is + // correctly aligned, all following args will be aligned as well. + return; } } } diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index f5654ed3b82613..6ec87adc090b77 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -750,6 +750,11 @@ MONO_RESTORE_WARNING } } else if (mini_class_is_simd (cfg, tfrom_klass) && mini_class_is_simd (cfg, tto_klass)) { #if TARGET_SIZEOF_VOID_P == 8 || defined(TARGET_WASM) +#if defined(TARGET_WIN32) && defined(TARGET_AMD64) + if (!COMPILE_LLVM (cfg)) + // FIXME: Fix the register allocation for SIMD on Windows x64 + return NULL; +#endif opcode = OP_XCAST; tto_stack = STACK_VTYPE; #else diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 91e7b446a5316a..f4e661edd4eea2 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -3732,6 +3732,45 @@ handle_delegate_ctor (MonoCompile *cfg, MonoClass *klass, MonoInst *target, Mono return obj; } +static MonoInst* +mono_emit_cached_localloc (MonoCompile *cfg, int cache_index, int new_size) +{ + g_assert (cache_index < (int)G_N_ELEMENTS (cfg->localloc_cache)); + MonoCachedLocallocInfo *info = &cfg->localloc_cache [cache_index]; + + // Create var or update the size. All locallocs will be patched to the max size after IR code emit ends. + if (info->alloc_size == 0) { + info->addr_var = mono_compile_create_var (cfg, mono_get_int_type (), OP_LOCAL); + info->alloc_size = new_size; + } else if (info->alloc_size < new_size) { + info->alloc_size = new_size; + } + + int cache_dreg = info->addr_var->dreg; + MonoInst* ins; + MonoBasicBlock *done_bb; + + NEW_BBLOCK (cfg, done_bb); + + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, cache_dreg, 0); + MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBNE_UN, done_bb); + + // If we have no localloc-ed memory, allocate it now and save it in the cache + MONO_INST_NEW (cfg, ins, OP_LOCALLOC_IMM); + ins->dreg = alloc_preg (cfg); + ins->inst_imm = new_size; + MONO_ADD_INS (cfg->cbb, ins); + + info->localloc_ins = g_slist_append (info->localloc_ins, ins); + + MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, cache_dreg, ins->dreg); + + // Return the value from the cache + MONO_START_BB (cfg, done_bb); + EMIT_NEW_UNALU (cfg, ins, OP_MOVE, alloc_preg (cfg), cache_dreg); + return ins; +} + /* * handle_constrained_gsharedvt_call: * @@ -3865,20 +3904,12 @@ handle_constrained_gsharedvt_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMe /* Pass an array of bools which signal whenever the corresponding argument is a gsharedvt ref type */ if (has_gsharedvt) { - MONO_INST_NEW (cfg, ins, OP_LOCALLOC_IMM); - ins->dreg = alloc_preg (cfg); - ins->inst_imm = fsig->param_count; - MONO_ADD_INS (cfg->cbb, ins); - is_gsharedvt_ins = ins; + is_gsharedvt_ins = mono_emit_cached_localloc (cfg, 0, fsig->param_count); } else { EMIT_NEW_PCONST (cfg, is_gsharedvt_ins, 0); } /* Pass the arguments using a localloc-ed array using the format expected by runtime_invoke () */ - MONO_INST_NEW (cfg, ins, OP_LOCALLOC_IMM); - ins->dreg = alloc_preg (cfg); - ins->inst_imm = fsig->param_count * sizeof (target_mgreg_t); - MONO_ADD_INS (cfg->cbb, ins); - args_ins = ins; + args_ins = mono_emit_cached_localloc (cfg, 1, fsig->param_count * sizeof (target_mgreg_t)); for (int i = 0; i < fsig->param_count; ++i) { int addr_reg; @@ -12335,8 +12366,25 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b cfg->cbb = init_localsbb; emit_init_local (cfg, i, header->locals [i], init_locals); } + + // Patch all locallocs using the cache to allocate the max used size. + for (int i = 0; i < 2; i++) { + MonoCachedLocallocInfo *info = &cfg->localloc_cache [i]; + if (info->alloc_size != 0) { + MONO_EMIT_NEW_PCONST (cfg, info->addr_var->dreg, NULL); + GSList *p = info->localloc_ins; + while (p != NULL) { + MonoInst *localloc_ins = (MonoInst*)p->data; + localloc_ins->inst_imm = info->alloc_size; + p = p->next; + } + g_slist_free (info->localloc_ins); + info->localloc_ins = NULL; + } + } } + if (cfg->init_ref_vars && cfg->method == method) { /* Emit initialization for ref vars */ // FIXME: Avoid duplication initialization for IL locals. diff --git a/src/mono/mono/mini/mini-arm.c b/src/mono/mono/mini/mini-arm.c index 9cab61db1cbc3b..206987c4b17d0b 100644 --- a/src/mono/mono/mini/mini-arm.c +++ b/src/mono/mono/mini/mini-arm.c @@ -2108,7 +2108,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) if (cfg->gsharedvt && mini_is_gsharedvt_variable_type (t)) continue; - /* inst->backend.is_pinvoke indicates native sized value types, this is used by the + /* inst->backend.is_pinvoke indicates native-sized value types, this is used by the * pinvoke wrappers when they call functions returning structure */ if (ins->backend.is_pinvoke && MONO_TYPE_ISSTRUCT (t) && t->type != MONO_TYPE_TYPEDBYREF) { size = mono_class_native_size (mono_class_from_mono_type_internal (t), &ualign); diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index f65c45313ea71f..ef4e76ef314215 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -4203,8 +4203,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) guint32 val; arm_ldrx (code, ARMREG_IP1, info_var->inst_basereg, GTMREG_TO_INT (info_var->inst_offset)); - /* Add the bp_tramp_offset */ - val = ((bp_tramp_offset / 4) * sizeof (target_mgreg_t)) + MONO_STRUCT_OFFSET (SeqPointInfo, bp_addrs); + val = (bp_tramp_offset * sizeof (target_mgreg_t)) + MONO_STRUCT_OFFSET (SeqPointInfo, bp_addrs); /* Load the info->bp_addrs [bp_tramp_offset], which is either 0 or the address of the bp trampoline */ code = emit_ldrx (code, ARMREG_IP1, ARMREG_IP1, val); /* Skip the load if its 0 */ @@ -6876,9 +6875,7 @@ mono_arch_set_breakpoint (MonoJitInfo *ji, guint8 *ip) if (enable_ptrauth) NOT_IMPLEMENTED; - g_assert (native_offset % 4 == 0); - g_assert (info->bp_addrs [native_offset / 4] == 0); - info->bp_addrs [native_offset / 4] = (guint8*)mini_get_breakpoint_trampoline (); + info->bp_addrs [native_offset] = (guint8*)mini_get_breakpoint_trampoline (); } else { /* ip points to an ldrx */ code += 4; @@ -6901,8 +6898,7 @@ mono_arch_clear_breakpoint (MonoJitInfo *ji, guint8 *ip) if (enable_ptrauth) NOT_IMPLEMENTED; - g_assert (native_offset % 4 == 0); - info->bp_addrs [native_offset / 4] = NULL; + info->bp_addrs [native_offset] = NULL; } else { /* ip points to an ldrx */ code += 4; @@ -6970,7 +6966,7 @@ mono_arch_get_seq_point_info (guint8 *code) ji = mini_jit_info_table_find (code); g_assert (ji); - info = g_malloc0 (sizeof (SeqPointInfo) + (ji->code_size / 4) * sizeof(guint8*)); + info = g_malloc0 (sizeof (SeqPointInfo) + ji->code_size * sizeof(guint8*)); info->ss_tramp_addr = &ss_trampoline; diff --git a/src/mono/mono/mini/mini-codegen.c b/src/mono/mono/mini/mini-codegen.c index 210c1619f629bb..e0f1576ab7944c 100644 --- a/src/mono/mono/mini/mini-codegen.c +++ b/src/mono/mono/mini/mini-codegen.c @@ -141,12 +141,10 @@ static void mono_regstate_assign (MonoRegState *rs) { #ifdef MONO_ARCH_USE_SHARED_FP_SIMD_BANK - /* The regalloc may fail if fp and simd logical regbanks share the same physical reg bank and - * if the values here are not the same. - */ - g_assert(regbank_callee_regs [MONO_REG_SIMD] == regbank_callee_regs [MONO_REG_DOUBLE]); + /* fp and simd logical banks may share the same physical reg bank with unequal overlapping registers */ + g_assert((regbank_callee_regs [MONO_REG_SIMD] & regbank_callee_regs[MONO_REG_DOUBLE]) == regbank_callee_regs [MONO_REG_DOUBLE]); + g_assert(regbank_size [MONO_REG_SIMD] >= regbank_size [MONO_REG_DOUBLE]); g_assert(regbank_callee_saved_regs [MONO_REG_SIMD] == regbank_callee_saved_regs [MONO_REG_DOUBLE]); - g_assert(regbank_size [MONO_REG_SIMD] == regbank_size [MONO_REG_DOUBLE]); #endif if (rs->next_vreg > rs->vassign_size) { @@ -221,7 +219,8 @@ mono_regstate_alloc_general (MonoRegState *rs, regmask_t allow, int bank) if (mirrored_bank == -1) return i; - rs->free_mask [mirrored_bank] = rs->free_mask [bank]; + rs->free_mask [mirrored_bank] = (((MONO_ARCH_CALLEE_FREGS & MONO_ARCH_CALLEE_XREGS) & rs->free_mask [bank]) + |((MONO_ARCH_CALLEE_FREGS ^ MONO_ARCH_CALLEE_XREGS) & rs->free_mask [mirrored_bank])); return i; } } @@ -240,7 +239,8 @@ mono_regstate_free_general (MonoRegState *rs, int reg, int bank) mirrored_bank = get_mirrored_bank (bank); if (mirrored_bank == -1) return; - rs->free_mask [mirrored_bank] = rs->free_mask [bank]; + rs->free_mask [mirrored_bank] = (((MONO_ARCH_CALLEE_FREGS & MONO_ARCH_CALLEE_XREGS) & rs->free_mask [bank]) + |((MONO_ARCH_CALLEE_FREGS ^ MONO_ARCH_CALLEE_XREGS) & rs->free_mask [mirrored_bank])); rs->symbolic [mirrored_bank][reg] = 0; } } @@ -649,7 +649,7 @@ mono_print_ins_index_strbuf (int i, MonoInst *ins) g_string_append_printf (sbuf, " [B%d]", ins->inst_true_bb->block_num); else g_string_append_printf (sbuf, " [T:B%d F:B%d]", ins->inst_true_bb->block_num, - ins->inst_false_bb->block_num); + ins->inst_false_bb->block_num); break; case OP_LIVERANGE_START: case OP_LIVERANGE_END: @@ -1081,8 +1081,8 @@ assign_reg (MonoCompile *cfg, MonoRegState *rs, int reg, int hreg, int bank) /* Make sure the other logical reg bank that this bank shares * a single hard reg bank knows that this hard reg is not free. */ - rs->free_mask [mirrored_bank] = rs->free_mask [bank]; - + rs->free_mask [mirrored_bank] = (((MONO_ARCH_CALLEE_FREGS & MONO_ARCH_CALLEE_XREGS) & rs->free_mask [bank]) + |((MONO_ARCH_CALLEE_FREGS ^ MONO_ARCH_CALLEE_XREGS) & rs->free_mask [mirrored_bank])); /* Mark the other logical bank that the this bank shares * a single hard reg bank with as mirrored. */ @@ -1566,7 +1566,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb) val = rs->vassign [ins->dreg]; if (is_soft_reg (ins->dreg, bank) && (val >= 0) && (!(regmask (val) & dreg_mask))) { /* DREG is already allocated to a register needed for sreg1 */ - spill_vreg (cfg, bb, tmp, ins, ins->dreg, 0); + spill_vreg (cfg, bb, tmp, ins, ins->dreg, 0); } } diff --git a/src/mono/mono/mini/mini-ops.h b/src/mono/mono/mini/mini-ops.h index fe0f4bcdffb763..1971c7286ec86c 100644 --- a/src/mono/mono/mini/mini-ops.h +++ b/src/mono/mono/mini/mini-ops.h @@ -121,7 +121,6 @@ MINI_OP(OP_STORER8_MEMBASE_REG, "storer8_membase_reg", IREG, FREG, NONE) #if defined(TARGET_X86) || defined(TARGET_AMD64) MINI_OP(OP_STOREX_MEMBASE_REG, "storex_membase_reg", IREG, XREG, NONE) -MINI_OP(OP_STOREX_ALIGNED_MEMBASE_REG, "storex_aligned_membase_reg", IREG, XREG, NONE) MINI_OP(OP_STOREX_NTA_MEMBASE_REG, "storex_nta_membase_reg", IREG, XREG, NONE) #endif @@ -149,8 +148,9 @@ MINI_OP(OP_LOADR8_MEMBASE,"loadr8_membase", FREG, IREG, NONE) /* klass must be set to a simd class */ MINI_OP(OP_LOADX_MEMBASE, "loadx_membase", XREG, IREG, NONE) -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_S390X) MINI_OP(OP_LOADX_ALIGNED_MEMBASE, "loadx_aligned_membase", XREG, IREG, NONE) +MINI_OP(OP_STOREX_ALIGNED_MEMBASE_REG, "storex_aligned_membase_reg", IREG, XREG, NONE) #endif MINI_OP(OP_LOADV_MEMBASE, "loadv_membase", VREG, IREG, NONE) @@ -1049,8 +1049,6 @@ MINI_OP(OP_CVTPS2PD, "cvtps2pd", XREG, XREG, NONE) MINI_OP(OP_CVTTPD2DQ, "cvttpd2dq", XREG, XREG, NONE) MINI_OP(OP_CVTTPS2DQ, "cvttps2dq", XREG, XREG, NONE) -MINI_OP(OP_VECTOR_IABS, "vector_integer_abs", XREG, XREG, NONE) -MINI_OP(OP_VECTOR_ANDN, "vector_andnot", XREG, XREG, XREG) /* sse 1 */ /* inst_c1 is target type */ @@ -1498,6 +1496,139 @@ MINI_OP(OP_S390_CIJ, "s390_cij", IREG, NONE, NONE) MINI_OP(OP_S390_CLIJ, "s390_cij_un", IREG, IREG, NONE) MINI_OP(OP_S390_CGIJ, "s390_cgij", LREG, NONE, NONE) MINI_OP(OP_S390_CLGIJ, "s390_cgij_un", LREG, NONE, NONE) +MINI_OP(OP_S390_VAB, "s390_vab", XREG, XREG, XREG) +MINI_OP(OP_S390_VAH, "s390_vah", XREG, XREG, XREG) +MINI_OP(OP_S390_VAF, "s390_vaf", XREG, XREG, XREG) +MINI_OP(OP_S390_VAG, "s390_vag", XREG, XREG, XREG) +MINI_OP(OP_S390_VFASB, "s390_vfasb", XREG, XREG, XREG) +MINI_OP(OP_S390_VFADB, "s390_vfadb", XREG, XREG, XREG) +MINI_OP(OP_S390_VSB, "s390_vsb", XREG, XREG, XREG) +MINI_OP(OP_S390_VSH, "s390_vsh", XREG, XREG, XREG) +MINI_OP(OP_S390_VSF, "s390_vsf", XREG, XREG, XREG) +MINI_OP(OP_S390_VSG, "s390_vsg", XREG, XREG, XREG) +MINI_OP(OP_S390_VFSSB, "s390_vfssb", XREG, XREG, XREG) +MINI_OP(OP_S390_VFSDB, "s390_vfsdb", XREG, XREG, XREG) +MINI_OP(OP_S390_VMLB, "s390_vmlb", XREG, XREG, XREG) +MINI_OP(OP_S390_VMLHW, "s390_vmlhw", XREG, XREG, XREG) +MINI_OP(OP_S390_VMLF, "s390_vmlf", XREG, XREG, XREG) +MINI_OP(OP_S390_VFMSB, "s390_vfmsb", XREG, XREG, XREG) +MINI_OP(OP_S390_VFMDB, "s390_vfmdb", XREG, XREG, XREG) +MINI_OP(OP_S390_VFDSB, "s390_vfdsb", XREG, XREG, XREG) +MINI_OP(OP_S390_VFDDB, "s390_vfddb", XREG, XREG, XREG) +MINI_OP(OP_S390_VMXB, "s390_vmxb", XREG, XREG, XREG) +MINI_OP(OP_S390_VMXH, "s390_vmxh", XREG, XREG, XREG) +MINI_OP(OP_S390_VMXF, "s390_vmxf", XREG, XREG, XREG) +MINI_OP(OP_S390_VMXG, "s390_vmxg", XREG, XREG, XREG) +MINI_OP(OP_S390_VFMAXSB, "s390_vfmaxsb", XREG, XREG, XREG) +MINI_OP(OP_S390_VFMAXDB, "s390_vfmaxdb", XREG, XREG, XREG) +MINI_OP(OP_S390_VMNB, "s390_vmnb", XREG, XREG, XREG) +MINI_OP(OP_S390_VMNH, "s390_vmnh", XREG, XREG, XREG) +MINI_OP(OP_S390_VMNF, "s390_vmnf", XREG, XREG, XREG) +MINI_OP(OP_S390_VMNG, "s390_vmng", XREG, XREG, XREG) +MINI_OP(OP_S390_VFMINSB, "s390_vfminsb", XREG, XREG, XREG) +MINI_OP(OP_S390_VFMINDB, "s390_vfmindb", XREG, XREG, XREG) +MINI_OP(OP_S390_VMXLB, "s390_vmxlb", XREG, XREG, XREG) +MINI_OP(OP_S390_VMXLH, "s390_vmxlh", XREG, XREG, XREG) +MINI_OP(OP_S390_VMXLF, "s390_vmxlf", XREG, XREG, XREG) +MINI_OP(OP_S390_VMXLG, "s390_vmxlg", XREG, XREG, XREG) +MINI_OP(OP_S390_VMNLB, "s390_vmnlb", XREG, XREG, XREG) +MINI_OP(OP_S390_VMNLH, "s390_vmnlh", XREG, XREG, XREG) +MINI_OP(OP_S390_VMNLF, "s390_vmnlf", XREG, XREG, XREG) +MINI_OP(OP_S390_VMNLG, "s390_vmnlg", XREG, XREG, XREG) +MINI_OP(OP_S390_VO, "s390_vo", XREG, XREG, XREG) +MINI_OP(OP_S390_VNO, "s390_vno", XREG, XREG, XREG) +MINI_OP(OP_S390_VX, "s390_vx", XREG, XREG, XREG) +MINI_OP(OP_S390_VN, "s390_vn", XREG, XREG, XREG) +MINI_OP(OP_S390_VNN, "s390_vnn", XREG, XREG, XREG) +MINI_OP(OP_S390_VSUMB, "s390_vsumb", XREG, XREG, XREG) +MINI_OP(OP_S390_VSUMH, "s390_vsumh", XREG, XREG, XREG) +MINI_OP(OP_S390_VSUMQF, "s390_vsumqf", XREG, XREG, XREG) +MINI_OP(OP_S390_VSUMQG, "s390_vsumqg", XREG, XREG, XREG) +MINI_OP(OP_S390_VPERM, "s390_vperm", XREG, XREG, XREG) +MINI_OP(OP_S390_VREPIB, "s390_vrepib", XREG, NONE, NONE) +MINI_OP(OP_S390_VREPIH, "s390_vrepih", XREG, NONE, NONE) +MINI_OP(OP_S390_VREPIF, "s390_vrepif", XREG, NONE, NONE) +MINI_OP(OP_S390_VREPIG, "s390_vrepig", XREG, NONE, NONE) +MINI_OP(OP_S390_VFSQSB, "s390_vfsqsb", XREG, XREG, NONE) +MINI_OP(OP_S390_VFSQDB, "s390_vfsqdb", XREG, XREG, NONE) +MINI_OP(OP_S390_VFCESBS, "s390_vfcesbs", XREG, XREG, XREG) +MINI_OP(OP_S390_VFCEDBS, "s390_vfcedbs", XREG, XREG, XREG) +MINI_OP(OP_S390_VFCHSBS, "s390_vfchsbs", XREG, XREG, XREG) +MINI_OP(OP_S390_VFCHDBS, "s390_vfchdbs", XREG, XREG, XREG) +MINI_OP(OP_S390_VFCESB, "s390_vfcesb", XREG, XREG, XREG) +MINI_OP(OP_S390_VFCEDB, "s390_vfcedb", XREG, XREG, XREG) +MINI_OP(OP_S390_VFCHSB, "s390_vfchsb", XREG, XREG, XREG) +MINI_OP(OP_S390_VFCHDB, "s390_vfchdb", XREG, XREG, XREG) +MINI_OP(OP_S390_VCEQBS, "s390_vceqbs", XREG, XREG, XREG) +MINI_OP(OP_S390_VCEQHS, "s390_vceqhs", XREG, XREG, XREG) +MINI_OP(OP_S390_VCEQFS, "s390_vceqfs", XREG, XREG, XREG) +MINI_OP(OP_S390_VCEQGS, "s390_vceqgs", XREG, XREG, XREG) +MINI_OP(OP_S390_VCEQB, "s390_vceqb", XREG, XREG, XREG) +MINI_OP(OP_S390_VCEQH, "s390_vceqh", XREG, XREG, XREG) +MINI_OP(OP_S390_VCEQF, "s390_vceqf", XREG, XREG, XREG) +MINI_OP(OP_S390_VCEQG, "s390_vceqg", XREG, XREG, XREG) +MINI_OP(OP_S390_VGMB, "s390_vgmb", XREG, IREG, IREG) +MINI_OP(OP_S390_VGMH, "s390_vgmh", XREG, IREG, IREG) +MINI_OP(OP_S390_VGMF, "s390_vgmf", XREG, IREG, IREG) +MINI_OP(OP_S390_VGMG, "s390_vgmg", XREG, IREG, IREG) +MINI_OP(OP_S390_VECB, "s390_vecb", XREG, XREG, NONE) +MINI_OP(OP_S390_VECF, "s390_vecf", XREG, XREG, NONE) +MINI_OP(OP_S390_VECH, "s390_vech", XREG, XREG, NONE) +MINI_OP(OP_S390_VECG, "s390_vecg", XREG, XREG, NONE) +MINI_OP(OP_S390_VECLB, "s390_veclb", XREG, XREG, NONE) +MINI_OP(OP_S390_VECLF, "s390_veclf", XREG, XREG, NONE) +MINI_OP(OP_S390_VECLH, "s390_veclh", XREG, XREG, NONE) +MINI_OP(OP_S390_VECLG, "s390_veclg", XREG, XREG, NONE) +MINI_OP(OP_S390_VCHBS, "s390_vchbs", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHHS, "s390_vchhs", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHFS, "s390_vchfs", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHGS, "s390_vchgs", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHB, "s390_vchb", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHH, "s390_vchh", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHF, "s390_vchf", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHG, "s390_vchg", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHLBS, "s390_vchlbs", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHLHS, "s390_vchlhs", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHLFS, "s390_vchlfs", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHLGS, "s390_vchlgs", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHLB, "s390_vchlb", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHLH, "s390_vchlh", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHLF, "s390_vchlf", XREG, XREG, XREG) +MINI_OP(OP_S390_VCHLG, "s390_vchlg", XREG, XREG, XREG) +MINI_OP(OP_S390_VFCHESBS, "s390_vfchesbs", XREG, XREG, XREG) +MINI_OP(OP_S390_VFCHEDBS, "s390_vfchedbs", XREG, XREG, XREG) +MINI_OP(OP_S390_VFCHESB, "s390_vfchesb", XREG, XREG, XREG) +MINI_OP(OP_S390_VFCHEDB, "s390_vfchedb", XREG, XREG, XREG) +MINI_OP(OP_S390_VLPB, "s390_vlpb", XREG, XREG, NONE) +MINI_OP(OP_S390_VLPH, "s390_vlph", XREG, XREG, NONE) +MINI_OP(OP_S390_VLPF, "s390_vlpf", XREG, XREG, NONE) +MINI_OP(OP_S390_VLPG, "s390_vlpg", XREG, XREG, NONE) +MINI_OP(OP_S390_VFLPDB, "s390_vflpdb", XREG, XREG, NONE) +MINI_OP(OP_S390_VFLPSB, "s390_vflpsb", XREG, XREG, NONE) +MINI_OP(OP_S390_VFLCDB, "s390_vflcdb", XREG, XREG, NONE) +MINI_OP(OP_S390_VFLCSB, "s390_vflcsb", XREG, XREG, NONE) +MINI_OP(OP_S390_VPKH, "s390_vpkh", XREG, XREG, XREG) +MINI_OP(OP_S390_VPKF, "s390_vpkf", XREG, XREG, XREG) +MINI_OP(OP_S390_VPKG, "s390_vpkg", XREG, XREG, XREG) +MINI_OP(OP_S390_VLCB, "s390_vlcb", XREG, XREG, NONE) +MINI_OP(OP_S390_VLCH, "s390_vlch", XREG, XREG, NONE) +MINI_OP(OP_S390_VLCF, "s390_vlcf", XREG, XREG, NONE) +MINI_OP(OP_S390_VLCG, "s390_vlcg", XREG, XREG, NONE) +MINI_OP(OP_S390_VUPHB, "s390_vuphb", XREG, XREG, NONE) +MINI_OP(OP_S390_VUPHH, "s390_vuphh", XREG, XREG, NONE) +MINI_OP(OP_S390_VUPHF, "s390_vuphf", XREG, XREG, NONE) +MINI_OP(OP_S390_VUPLB, "s390_vuplb", XREG, XREG, NONE) +MINI_OP(OP_S390_VUPLHW, "s390_vuplhw", XREG, XREG, NONE) +MINI_OP(OP_S390_VUPLF, "s390_vuplf", XREG, XREG, NONE) +MINI_OP(OP_S390_VUPLHB, "s390_vuplhb", XREG, XREG, NONE) +MINI_OP(OP_S390_VUPLHH, "s390_vuplhh", XREG, XREG, NONE) +MINI_OP(OP_S390_VUPLHF, "s390_vuplhf", XREG, XREG, NONE) +MINI_OP(OP_S390_VUPLLB, "s390_vupllb", XREG, XREG, NONE) +MINI_OP(OP_S390_VUPLLH, "s390_vupllh", XREG, XREG, NONE) +MINI_OP(OP_S390_VUPLLF, "s390_vupllf", XREG, XREG, NONE) +MINI_OP(OP_S390_VFISB, "s390_vfidb", XREG, XREG, NONE) +MINI_OP(OP_S390_VFIDB, "s390_vfisb", XREG, XREG, NONE) +MINI_OP(OP_S390_XCOMPARE_XEXTRACT, "s390_xcompare_xextract", IREG, XREG, XREG) #endif #if defined(TARGET_ARM64) @@ -1862,7 +1993,6 @@ MINI_OP(OP_SIMD_LOAD_SCALAR_R8, "simd_load_scalar_r8", XREG, IREG, NONE) MINI_OP(OP_SIMD_STORE, "simd_store", NONE, XREG, XREG) #if defined(TARGET_ARM64) || defined(TARGET_AMD64) || defined(TARGET_WASM) -MINI_OP(OP_ONES_COMPLEMENT, "ones_complement", XREG, XREG, NONE) MINI_OP(OP_CVT_FP_UI, "convert_fp_to_ui", XREG, XREG, NONE) MINI_OP(OP_CVT_FP_SI, "convert_fp_to_si", XREG, XREG, NONE) MINI_OP(OP_CVT_FP_UI_SCALAR, "convert_fp_to_ui_scalar", XREG, XREG, NONE) @@ -1872,11 +2002,20 @@ MINI_OP(OP_CVT_SI_FP, "convert_si_to_fp", XREG, XREG, NONE) MINI_OP(OP_CVT_UI_FP_SCALAR, "convert_ui_to_fp_scalar", XREG, XREG, NONE) MINI_OP(OP_CVT_SI_FP_SCALAR, "convert_si_to_fp_scalar", XREG, XREG, NONE) /* inst_c1 is one of the MONO_TYPE_ constants */ -MINI_OP(OP_NEGATION, "negate", XREG, XREG, NONE) MINI_OP(OP_NEGATION_SCALAR, "negate_scalar", XREG, XREG, NONE) +#endif // TARGET_ARM64 || TARGET_AMD64 || TARGET_WASM + +#if defined(TARGET_ARM64) || defined(TARGET_AMD64) || defined(TARGET_WASM) || defined(TARGET_S390X) +MINI_OP(OP_NEGATION, "negate", XREG, XREG, NONE) +MINI_OP(OP_ONES_COMPLEMENT, "ones_complement", XREG, XREG, NONE) /* Select bits from src2/src3 using src1 */ MINI_OP3(OP_BSL, "bitwise_select", XREG, XREG, XREG, XREG) -#endif // TARGET_ARM64 || TARGET_AMD64 || TARGET_WASM +#endif + +#if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_WASM) || defined(TARGET_S390X) +MINI_OP(OP_VECTOR_ANDN, "vector_andnot", XREG, XREG, XREG) +MINI_OP(OP_VECTOR_IABS, "vector_integer_abs", XREG, XREG, NONE) +#endif #if defined(TARGET_RISCV64) || defined(TARGET_RISCV32) MINI_OP(OP_RISCV_EXC_BEQ, "riscv_exc_beq", NONE, IREG, IREG) diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 55645dd51efb46..468534bc16ba41 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -4496,7 +4496,7 @@ init_class (MonoClass *klass) } #endif -#ifdef TARGET_ARM64 +#if defined(TARGET_ARM64) || defined(TARGET_S390X) if (!strcmp (m_class_get_name_space (klass), "System.Numerics")) { if (!strcmp (name, "Vector2") || !strcmp (name, "Vector3") ||!strcmp (name, "Vector4") || !strcmp (name, "Quaternion") || !strcmp (name, "Plane")) mono_class_set_is_simd_type (klass, TRUE); @@ -5363,7 +5363,7 @@ mono_precompile_assembly (MonoAssembly *ass, void *user_data) mono_error_cleanup (error); /* FIXME don't swallow the error */ continue; } - if (strcmp (method->name, "Finalize") == 0) { + if (strcmp (method->name, "GuardedFinalize") == 0) { invoke = mono_marshal_get_runtime_invoke (method, FALSE); mono_compile_method_checked (invoke, error); mono_error_assert_ok (error); diff --git a/src/mono/mono/mini/mini-s390x.c b/src/mono/mono/mini/mini-s390x.c index 3419a29768c707..5a52747b34739e 100644 --- a/src/mono/mono/mini/mini-s390x.c +++ b/src/mono/mono/mini/mini-s390x.c @@ -19,6 +19,17 @@ #define MAX_ARCH_DELEGATE_PARAMS 10 +#define NEW_SIMD_INS(cfg,ins,dest,op,d,s1,s2) do { \ + MONO_INST_NEW ((cfg), (dest), (op)); \ + (dest)->cil_code = (ins)->cil_code; \ + (dest)->dreg = d; \ + (dest)->sreg1 = s1; \ + (dest)->sreg2 = s2; \ + (dest)->type = STACK_VTYPE; \ + (dest)->klass = ins->klass; \ + mono_bblock_insert_before_ins (bb, ins, (dest)); \ + } while (0) + #define EMIT_COND_BRANCH(ins,cond) \ { \ if (ins->inst_true_bb->native_offset) { \ @@ -1595,7 +1606,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) continue; /*--------------------------------------------------*/ - /* inst->backend.is_pinvoke indicates native sized */ + /* inst->backend.is_pinvoke indicates native-sized */ /* value types this is used by the pinvoke wrappers */ /* when they call functions returning structure */ /*--------------------------------------------------*/ @@ -2177,6 +2188,441 @@ mono_arch_peephole_pass_2 (MonoCompile *cfg, MonoBasicBlock *bb) /*========================= End of Function ========================*/ +static int +simd_type_to_sub_op (int t) +{ + switch (t) { + case MONO_TYPE_I1: + case MONO_TYPE_U1: + return OP_S390_VSB; + case MONO_TYPE_I2: + case MONO_TYPE_U2: + return OP_S390_VSH; + case MONO_TYPE_I4: + case MONO_TYPE_U4: + return OP_S390_VSF; + case MONO_TYPE_I8: + case MONO_TYPE_U8: + case MONO_TYPE_I: + case MONO_TYPE_U: + return OP_S390_VSG; + case MONO_TYPE_R4: + return OP_S390_VFSSB; + case MONO_TYPE_R8: + return OP_S390_VFSDB; + default: + g_assert_not_reached (); + return -1; + } +} + +static int +simd_type_to_add_op (int t) +{ + switch (t) { + case MONO_TYPE_I1: + case MONO_TYPE_U1: + return OP_S390_VAB; + case MONO_TYPE_I2: + case MONO_TYPE_U2: + return OP_S390_VAH; + case MONO_TYPE_I4: + case MONO_TYPE_U4: + return OP_S390_VAF; + case MONO_TYPE_I8: + case MONO_TYPE_U8: + case MONO_TYPE_I: + case MONO_TYPE_U: + return OP_S390_VAG; + case MONO_TYPE_R4: + return OP_S390_VFASB; + case MONO_TYPE_R8: + return OP_S390_VFADB; + default: + g_assert_not_reached (); + return -1; + } +} + +static int +simd_type_to_mul_op (int t) +{ + switch (t) { + case MONO_TYPE_I1: + case MONO_TYPE_U1: + return OP_S390_VMLB; + case MONO_TYPE_I2: + case MONO_TYPE_U2: + return OP_S390_VMLHW; + case MONO_TYPE_I4: + case MONO_TYPE_U4: + return OP_S390_VMLF; + case MONO_TYPE_R4: + return OP_S390_VFMSB; + case MONO_TYPE_R8: + return OP_S390_VFMDB; + default: + g_assert_not_reached (); + return -1; + } +} + +static int +simd_type_to_max_op (int t) +{ + switch (t) { + case MONO_TYPE_I1: + return OP_S390_VMXB; + case MONO_TYPE_U1: + return OP_S390_VMXLB; + case MONO_TYPE_I2: + return OP_S390_VMXH; + case MONO_TYPE_U2: + return OP_S390_VMXLH; + case MONO_TYPE_I4: + return OP_S390_VMXF; + case MONO_TYPE_U4: + return OP_S390_VMXLF; + case MONO_TYPE_I8: + case MONO_TYPE_I: + return OP_S390_VMXG; + case MONO_TYPE_U8: + case MONO_TYPE_U: + return OP_S390_VMXLG; + case MONO_TYPE_R4: + return OP_S390_VFMAXSB; + case MONO_TYPE_R8: + return OP_S390_VFMAXDB; + default: + g_assert_not_reached (); + return -1; + } +} + +static int +simd_type_to_min_op (int t) +{ + switch (t) { + case MONO_TYPE_I1: + return OP_S390_VMNB; + case MONO_TYPE_U1: + return OP_S390_VMNLB; + case MONO_TYPE_I2: + return OP_S390_VMNH; + case MONO_TYPE_U2: + return OP_S390_VMNLH; + case MONO_TYPE_I4: + return OP_S390_VMNF; + case MONO_TYPE_U4: + return OP_S390_VMNLF; + case MONO_TYPE_I8: + case MONO_TYPE_I: + return OP_S390_VMNG; + case MONO_TYPE_U8: + case MONO_TYPE_U: + return OP_S390_VMNLG; + case MONO_TYPE_R4: + return OP_S390_VFMINSB; + case MONO_TYPE_R8: + return OP_S390_VFMINDB; + default: + g_assert_not_reached (); + return -1; + } +} + +static int +simd_type_to_comp_any_all_op (int t) +{ + switch (t) { + case MONO_TYPE_I1: + case MONO_TYPE_U1: + return OP_S390_VCEQBS; + case MONO_TYPE_I2: + case MONO_TYPE_U2: + return OP_S390_VCEQHS; + case MONO_TYPE_I4: + case MONO_TYPE_U4: + return OP_S390_VCEQFS; + case MONO_TYPE_I: + case MONO_TYPE_U: + case MONO_TYPE_I8: + case MONO_TYPE_U8: + return OP_S390_VCEQGS; + case MONO_TYPE_R4: + return OP_S390_VFCESBS; + case MONO_TYPE_R8: + return OP_S390_VFCEDBS; + default: + g_assert_not_reached (); + return -1; + } +} + +static int +simd_type_to_comp_op (int t) +{ + switch (t) { + case MONO_TYPE_I1: + case MONO_TYPE_U1: + return OP_S390_VCEQB; + case MONO_TYPE_I2: + case MONO_TYPE_U2: + return OP_S390_VCEQH; + case MONO_TYPE_I4: + case MONO_TYPE_U4: + return OP_S390_VCEQF; + case MONO_TYPE_I: + case MONO_TYPE_U: + case MONO_TYPE_I8: + case MONO_TYPE_U8: + return OP_S390_VCEQG; + case MONO_TYPE_R4: + return OP_S390_VFCESB; + case MONO_TYPE_R8: + return OP_S390_VFCEDB; + default: + g_assert_not_reached (); + return -1; + } +} + +static int +simd_type_to_gt_any_all_op (int t) +{ + switch (t) { + case MONO_TYPE_I1: + return OP_S390_VCHBS; + case MONO_TYPE_U1: + return OP_S390_VCHLBS; + case MONO_TYPE_I2: + return OP_S390_VCHHS; + case MONO_TYPE_U2: + return OP_S390_VCHLHS; + case MONO_TYPE_I4: + return OP_S390_VCHFS; + case MONO_TYPE_U4: + return OP_S390_VCHLFS; + case MONO_TYPE_I: + case MONO_TYPE_I8: + return OP_S390_VCHGS; + case MONO_TYPE_U: + case MONO_TYPE_U8: + return OP_S390_VCHLGS; + case MONO_TYPE_R4: + return OP_S390_VFCHSBS; + case MONO_TYPE_R8: + return OP_S390_VFCHDBS; + default: + g_assert_not_reached (); + return -1; + } +} + +static int +simd_type_to_gt_op (int t) +{ + switch (t) { + case MONO_TYPE_I1: + return OP_S390_VCHB; + case MONO_TYPE_U1: + return OP_S390_VCHLB; + case MONO_TYPE_I2: + return OP_S390_VCHH; + case MONO_TYPE_U2: + return OP_S390_VCHLH; + case MONO_TYPE_I4: + return OP_S390_VCHF; + case MONO_TYPE_U4: + return OP_S390_VCHLF; + case MONO_TYPE_I: + case MONO_TYPE_I8: + return OP_S390_VCHG; + case MONO_TYPE_U: + case MONO_TYPE_U8: + return OP_S390_VCHLG; + case MONO_TYPE_R4: + return OP_S390_VFCHSB; + case MONO_TYPE_R8: + return OP_S390_VFCHDB; + default: + g_assert_not_reached (); + return -1; + } +} + +static int +simd_type_to_ge_fp_any_all_op (int t) +{ + switch(t) { + case MONO_TYPE_R4: + return OP_S390_VFCHESBS; + case MONO_TYPE_R8: + return OP_S390_VFCHEDBS; + default: + g_assert_not_reached (); + return -1; + } +} + +static int +simd_type_to_ge_fp_op (int t) +{ + switch(t) { + case MONO_TYPE_R4: + return OP_S390_VFCHESB; + case MONO_TYPE_R8: + return OP_S390_VFCHEDB; + default: + g_assert_not_reached (); + return -1; + } +} + + +static int +simd_type_to_extract_int_op (int t, int q) +{ + switch (t){ + case SIMD_EXTR_ARE_ALL_SET:{ + switch (q){ + case CMP_LT: + case CMP_GT: + case CMP_GT_UN: + case CMP_LT_UN: + case CMP_EQ: + return OP_CEQ; + case CMP_GE: + case CMP_LE: + case CMP_GE_UN: + case CMP_LE_UN: + return OP_ICGT_UN; + default: + g_assert_not_reached(); + return -1; + } + } + case SIMD_EXTR_IS_ANY_SET:{ + switch (q){ + case CMP_GT: + case CMP_LT: + case CMP_GT_UN: + case CMP_LT_UN: + case CMP_EQ: + return OP_ICLE; + case CMP_GE: + case CMP_LE: + case CMP_GE_UN: + case CMP_LE_UN: + return OP_ICNEQ; + default: + g_assert_not_reached(); + return -1; + } + } + default: + g_assert_not_reached (); + return -1; + } +} + +static int +simd_type_to_extract_fp_op (int t, int q) +{ + switch (t){ + case SIMD_EXTR_ARE_ALL_SET:{ + switch (q){ + case CMP_LT: + case CMP_GT: + case CMP_GT_UN: + case CMP_LT_UN: + case CMP_EQ: + case CMP_GE: + case CMP_LE: + case CMP_GE_UN: + case CMP_LE_UN: + return OP_ICEQ; + default: + g_assert_not_reached(); + return -1; + } + } + case SIMD_EXTR_IS_ANY_SET:{ + switch (q){ + case CMP_GT: + case CMP_LT: + case CMP_GT_UN: + case CMP_LT_UN: + case CMP_EQ: + case CMP_GE: + case CMP_LE: + case CMP_GE_UN: + case CMP_LE_UN: + return OP_ICLE; + default: + g_assert_not_reached(); + return -1; + } + } + default: + g_assert_not_reached (); + return -1; + } +} + +static int +simd_type_to_abs_op (int t) +{ + switch (t) { + case MONO_TYPE_I1: + case MONO_TYPE_U1: + return OP_S390_VLPB; + case MONO_TYPE_I2: + case MONO_TYPE_U2: + return OP_S390_VLPH; + case MONO_TYPE_I4: + case MONO_TYPE_U4: + return OP_S390_VLPF; + case MONO_TYPE_I8: + case MONO_TYPE_U8: + return OP_S390_VLPG; + default: + g_assert_not_reached (); + return -1; + } +} + +static int +simd_type_to_negate_op (int t) +{ + switch (t) { + case MONO_TYPE_I1: + case MONO_TYPE_U1: + return OP_S390_VLCB; + case MONO_TYPE_I2: + case MONO_TYPE_U2: + return OP_S390_VLCH; + case MONO_TYPE_I4: + case MONO_TYPE_U4: + return OP_S390_VLCF; + case MONO_TYPE_R4: + return OP_S390_VFLCSB; + case MONO_TYPE_I8: + case MONO_TYPE_U8: + return OP_S390_VLCG; + case MONO_TYPE_R8: + return OP_S390_VFLCDB; + default: + g_assert_not_reached (); + return -1; + } +} + +static bool +type_is_float (int t){ + return (t == MONO_TYPE_R4 || t == MONO_TYPE_R8); +} + /** * * @brief Architecture-specific lowering pass processing @@ -2190,7 +2636,8 @@ mono_arch_peephole_pass_2 (MonoCompile *cfg, MonoBasicBlock *bb) void mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) { - MonoInst *ins, *next; + MonoInst *ins, *next, *temp_ins; + int temp; MONO_BB_FOR_EACH_INS_SAFE (bb, next, ins) { switch (ins->opcode) { @@ -2212,6 +2659,204 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) /* This is created by the memcpy code which ignores is_inst_imm */ mono_decompose_op_imm (cfg, bb, ins); break; + case OP_XBINOP:{ + switch(ins->inst_c0){ + case OP_IADD: + ins->opcode = GINT_TO_OPCODE (simd_type_to_add_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case OP_ISUB: + ins->opcode = GINT_TO_OPCODE (simd_type_to_sub_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case OP_IMUL: + ins->opcode = GINT_TO_OPCODE (simd_type_to_mul_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case OP_IMAX_UN: + case OP_IMAX: + ins->opcode = GINT_TO_OPCODE (simd_type_to_max_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case OP_IMIN_UN: + case OP_IMIN: + ins->opcode = GINT_TO_OPCODE (simd_type_to_min_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case OP_FADD: + ins->opcode = GINT_TO_OPCODE (simd_type_to_add_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case OP_FSUB: + ins->opcode = GINT_TO_OPCODE (simd_type_to_sub_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case OP_FMUL: + ins->opcode = GINT_TO_OPCODE (simd_type_to_mul_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case OP_FDIV: + ins->opcode = ins->inst_c1 == MONO_TYPE_R4 ? OP_S390_VFDSB : OP_S390_VFDDB; + break; + case OP_FMIN: + ins->opcode = GINT_TO_OPCODE (simd_type_to_min_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case OP_FMAX: + ins->opcode = GINT_TO_OPCODE (simd_type_to_max_op (GTMREG_TO_INT (ins->inst_c1))); + break; + default: + g_assert_not_reached (); + break; + } + break; + } + case OP_XBINOP_FORCEINT:{ + switch (ins->inst_c0) { + case XBINOP_FORCEINT_AND: + ins->opcode = OP_S390_VN; + break; + case XBINOP_FORCEINT_OR: + ins->opcode = OP_S390_VO; + break; + case XBINOP_FORCEINT_XOR: + ins->opcode = OP_S390_VX; + break; + default: + g_assert_not_reached (); + break; + } + break; + } + case OP_XCAST:{ + ins->opcode = OP_XMOVE; + break; + } + case OP_XCOMPARE_FP:{ + switch (ins->inst_c0){ + case CMP_EQ: + ins->opcode = GINT_TO_OPCODE (simd_type_to_comp_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case CMP_LT_UN: + case CMP_LT: + temp = ins->sreg1; + ins->sreg1 = ins->sreg2; + ins->sreg2 = temp; + case CMP_GT_UN: + case CMP_GT: + ins->opcode = GINT_TO_OPCODE (simd_type_to_gt_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case CMP_LE_UN: + case CMP_LE: + temp = ins->sreg1; + ins->sreg1 = ins->sreg2; + ins->sreg2 = temp; + case CMP_GE_UN: + case CMP_GE: + ins->opcode = GINT_TO_OPCODE (simd_type_to_ge_fp_op (GTMREG_TO_INT (ins->inst_c1))); + break; + default: + g_assert_not_reached (); + break; + } + break; + } + case OP_XCOMPARE:{ + switch (ins->inst_c0){ + case CMP_EQ: + ins->opcode = GINT_TO_OPCODE (simd_type_to_comp_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case CMP_LT: + case CMP_LT_UN: + temp = ins->sreg1; + ins->sreg1 = ins->sreg2; + ins->sreg2 = temp; + case CMP_GT: + case CMP_GT_UN: + ins->opcode = GINT_TO_OPCODE (simd_type_to_gt_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case CMP_GE: + case CMP_GE_UN: + temp = ins->sreg1; + ins->sreg1 = ins->sreg2; + ins->sreg2 = temp; + case CMP_LE: + case CMP_LE_UN:{ + NEW_SIMD_INS (cfg, ins, temp_ins, GINT_TO_OPCODE (simd_type_to_gt_op (GTMREG_TO_INT (ins->inst_c1))), ins->dreg, ins->sreg1, ins->sreg2); + NEW_SIMD_INS (cfg, ins, temp_ins, OP_S390_VNO, ins->dreg, ins->dreg, ins->dreg); + NULLIFY_INS (ins); + break; + } + default: + g_assert_not_reached (); + break; + } + break; + } + case OP_S390_XCOMPARE_XEXTRACT:{ + guint32 temp_reg = alloc_ireg(cfg); + if (!type_is_float(GTMREG_TO_INT(ins->inst_c1))){ + switch (ins->inst_c0 >> 4){ + case CMP_EQ: + NEW_SIMD_INS (cfg, ins, temp_ins, GINT_TO_OPCODE (simd_type_to_comp_any_all_op (GTMREG_TO_INT (ins->inst_c1))), temp_reg, ins->sreg1, ins->sreg2); + break; + case CMP_LT: + case CMP_LT_UN: + case CMP_GE: + case CMP_GE_UN: + temp = ins->sreg1; + ins->sreg1 = ins->sreg2; + ins->sreg2 = temp; + case CMP_GT: + case CMP_GT_UN: + case CMP_LE: + case CMP_LE_UN: + NEW_SIMD_INS (cfg, ins, temp_ins, GINT_TO_OPCODE (simd_type_to_gt_any_all_op (GTMREG_TO_INT (ins->inst_c1))), temp_reg, ins->sreg1, ins->sreg2); + break; + default: + g_assert_not_reached (); + break; + } + } + else { + switch (ins->inst_c0 >> 4){ + case CMP_EQ: + NEW_SIMD_INS (cfg, ins, temp_ins, GINT_TO_OPCODE (simd_type_to_comp_any_all_op (GTMREG_TO_INT (ins->inst_c1))), temp_reg, ins->sreg1, ins->sreg2); + break; + case CMP_LT_UN: + case CMP_LT: + temp = ins->sreg1; + ins->sreg1 = ins->sreg2; + ins->sreg2 = temp; + case CMP_GT_UN: + case CMP_GT: + NEW_SIMD_INS (cfg, ins, temp_ins, GINT_TO_OPCODE (simd_type_to_gt_any_all_op (GTMREG_TO_INT (ins->inst_c1))), temp_reg, ins->sreg1, ins->sreg2); + break; + case CMP_LE_UN: + case CMP_LE: + temp = ins->sreg1; + ins->sreg1 = ins->sreg2; + ins->sreg2 = temp; + case CMP_GE_UN: + case CMP_GE: + NEW_SIMD_INS (cfg, ins, temp_ins, GINT_TO_OPCODE (simd_type_to_ge_fp_any_all_op (GTMREG_TO_INT (ins->inst_c1))), temp_reg, ins->sreg1, ins->sreg2); + break; + default: + g_assert_not_reached (); + break; + } + } + if(!type_is_float(GTMREG_TO_INT(ins->inst_c1))){ + NEW_SIMD_INS (cfg, ins, temp_ins, GINT_TO_OPCODE (simd_type_to_extract_int_op (GTMREG_TO_INT (ins->inst_c0 & 0x0f), GTMREG_TO_INT (ins->inst_c0 >> 4))), ins->dreg, -1, -1); + NULLIFY_INS(ins); + } + else { + NEW_SIMD_INS (cfg, ins, temp_ins, GINT_TO_OPCODE (simd_type_to_extract_fp_op (GTMREG_TO_INT (ins->inst_c0 & 0x0f), GTMREG_TO_INT (ins->inst_c0 >> 4))), ins->dreg, -1, -1); + NULLIFY_INS(ins); + } + } + break; + case OP_VECTOR_IABS: + ins->opcode = GINT_TO_OPCODE (simd_type_to_abs_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case OP_NEGATION: + ins->opcode = GINT_TO_OPCODE (simd_type_to_negate_op (GTMREG_TO_INT (ins->inst_c1))); + break; + case OP_ONES_COMPLEMENT: + ins->opcode = OP_S390_VNO; + ins->sreg2 = ins->sreg1; + break; default: break; } @@ -4834,605 +5479,520 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) bb->spill_slot_defs = g_slist_prepend_mempool (cfg->mempool, bb->spill_slot_defs, ins); break; #ifdef MONO_ARCH_SIMD_INTRINSICS - case OP_ADDPS: - s390x_addps (code, ins->sreg1, ins->sreg2); + case OP_XCONST: + S390_SET (code, s390_r13, ins->inst_p0); + s390_vl(code, ins->dreg, 0, s390_r13, 0); break; - case OP_DIVPS: - s390x_divps (code, ins->sreg1, ins->sreg2); + /* TO-DO: provide an alignment hint for the vector loads and stores*/ + case OP_LOADX_ALIGNED_MEMBASE: + case OP_LOADX_MEMBASE: + S390_LONG_VEC(code, vl, vl, ins->dreg, ins->inst_offset, 0, ins->inst_basereg); break; - case OP_MULPS: - s390x_mulps (code, ins->sreg1, ins->sreg2); + case OP_STOREX_ALIGNED_MEMBASE_REG: + case OP_STOREX_MEMBASE: + S390_LONG_VEC(code, vst, vst, ins->sreg1, ins->inst_offset,0, ins->inst_destbasereg); break; - case OP_SUBPS: - s390x_subps (code, ins->sreg1, ins->sreg2); + case OP_S390_VN: + s390_vn (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_MAXPS: - s390x_maxps (code, ins->sreg1, ins->sreg2); + case OP_S390_VNN: + s390_vnn (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_MINPS: - s390x_minps (code, ins->sreg1, ins->sreg2); + case OP_VECTOR_ANDN: + s390_vnc (code, ins->dreg, ins->sreg2, ins->sreg1); break; - case OP_COMPPS: - g_assert (ins->inst_c0 >= 0 && ins->inst_c0 <= 7); - s390x_cmpps_imm (code, ins->sreg1, ins->sreg2, ins->inst_c0); + case OP_S390_VO: + s390_vo (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_ANDPS: - s390x_andps (code, ins->sreg1, ins->sreg2); + case OP_S390_VNO: + s390_vno (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_ANDNPS: - s390x_andnps (code, ins->sreg1, ins->sreg2); + case OP_S390_VX: + s390_vx (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_ORPS: - s390x_orps (code, ins->sreg1, ins->sreg2); + case OP_S390_VAB: + s390_vab (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_XORPS: - s390x_xorps (code, ins->sreg1, ins->sreg2); + case OP_S390_VAH: + s390_vah (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_SQRTPS: - s390x_sqrtps (code, ins->dreg, ins->sreg1); + case OP_S390_VAF: + s390_vaf (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_RSQRTPS: - s390x_rsqrtps (code, ins->dreg, ins->sreg1); + case OP_S390_VAG: + s390_vag (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_RCPPS: - s390x_rcpps (code, ins->dreg, ins->sreg1); + case OP_S390_VFASB: + s390_vfasb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_ADDSUBPS: - s390x_addsubps (code, ins->sreg1, ins->sreg2); + case OP_S390_VFADB: + s390_vfadb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_HADDPS: - s390x_haddps (code, ins->sreg1, ins->sreg2); + case OP_S390_VSB: + s390_vsb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_HSUBPS: - s390x_hsubps (code, ins->sreg1, ins->sreg2); + case OP_S390_VSH: + s390_vsh (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_DUPPS_HIGH: - s390x_movshdup (code, ins->dreg, ins->sreg1); + case OP_S390_VSF: + s390_vsf (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_DUPPS_LOW: - s390x_movsldup (code, ins->dreg, ins->sreg1); + case OP_S390_VSG: + s390_vsg (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PSHUFLEW_HIGH: - g_assert (ins->inst_c0 >= 0 && ins->inst_c0 <= 0xFF); - s390x_pshufhw_imm (code, ins->dreg, ins->sreg1, ins->inst_c0); + case OP_S390_VFSSB: + s390_vfssb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PSHUFLEW_LOW: - g_assert (ins->inst_c0 >= 0 && ins->inst_c0 <= 0xFF); - s390x_pshuflw_imm (code, ins->dreg, ins->sreg1, ins->inst_c0); + case OP_S390_VFSDB: + s390_vfsdb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PSHUFLED: - g_assert (ins->inst_c0 >= 0 && ins->inst_c0 <= 0xFF); - s390x_pshufd_imm (code, ins->dreg, ins->sreg1, ins->inst_c0); + case OP_S390_VMLB: + s390_vmlb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_SHUFPS: - g_assert (ins->inst_c0 >= 0 && ins->inst_c0 <= 0xFF); - s390x_shufps_imm (code, ins->sreg1, ins->sreg2, ins->inst_c0); + case OP_S390_VMLHW: + s390_vmlhw (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_SHUFPD: - g_assert (ins->inst_c0 >= 0 && ins->inst_c0 <= 0x3); - s390x_shufpd_imm (code, ins->sreg1, ins->sreg2, ins->inst_c0); + case OP_S390_VMLF: + s390_vmlf (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_ADDPD: - s390x_addpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VFMSB: + s390_vfmsb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_DIVPD: - s390x_divpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VFMDB: + s390_vfmdb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_MULPD: - s390x_mulpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VFDSB: + s390_vfdsb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_SUBPD: - s390x_subpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VFDDB: + s390_vfddb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_MAXPD: - s390x_maxpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VSUMB: + s390_vsumb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_MINPD: - s390x_minpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VSUMH: + s390_vsumh (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_COMPPD: - g_assert (ins->inst_c0 >= 0 && ins->inst_c0 <= 7); - s390x_cmppd_imm (code, ins->sreg1, ins->sreg2, ins->inst_c0); + case OP_S390_VSUMQF: + s390_vsumqf (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_ANDPD: - s390x_andpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VSUMQG: + s390_vsumqg (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_ANDNPD: - s390x_andnpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VMXB: + s390_vmxb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_ORPD: - s390x_orpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VMXH: + s390_vmxh (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_XORPD: - s390x_xorpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VMXF: + s390_vmxf (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_SQRTPD: - s390x_sqrtpd (code, ins->dreg, ins->sreg1); + case OP_S390_VMXG: + s390_vmxg (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_ADDSUBPD: - s390x_addsubpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VFMAXSB: + /* The max function used here is Java Math.Max() */ + s390_vfmaxsb (code, ins->dreg, ins->sreg1, ins->sreg2, 1); break; - case OP_HADDPD: - s390x_haddpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VFMAXDB: + s390_vfmaxdb (code, ins->dreg, ins->sreg1, ins->sreg2, 1); break; - case OP_HSUBPD: - s390x_hsubpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VMXLB: + s390_vmxlb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_DUPPD: - s390x_movddup (code, ins->dreg, ins->sreg1); + case OP_S390_VMXLH: + s390_vmxlh (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_EXTRACT_MASK: - s390x_pmovmskb (code, ins->dreg, ins->sreg1); + case OP_S390_VMXLF: + s390_vmxlf (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PAND: - s390x_pand (code, ins->sreg1, ins->sreg2); + case OP_S390_VMXLG: + s390_vmxlg (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_POR: - s390x_por (code, ins->sreg1, ins->sreg2); + case OP_S390_VMNB: + s390_vmnb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PXOR: - s390x_pxor (code, ins->sreg1, ins->sreg2); + case OP_S390_VMNH: + s390_vmnh (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PADDB: - s390x_paddb (code, ins->sreg1, ins->sreg2); + case OP_S390_VMNF: + s390_vmnf (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PADDW: - s390x_paddw (code, ins->sreg1, ins->sreg2); + case OP_S390_VMNG: + s390_vmng (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PADDD: - s390x_paddd (code, ins->sreg1, ins->sreg2); + case OP_S390_VFMINSB: + /* The min function used here is Java Math.Min() */ + s390_vfminsb (code, ins->dreg, ins->sreg1, ins->sreg2, 1); break; - case OP_PADDQ: - s390x_paddq (code, ins->sreg1, ins->sreg2); + case OP_S390_VFMINDB: + s390_vfmindb (code, ins->dreg, ins->sreg1, ins->sreg2, 1); break; - - case OP_PSUBB: - s390x_psubb (code, ins->sreg1, ins->sreg2); + case OP_S390_VMNLB: + s390_vmnlb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PSUBW: - s390x_psubw (code, ins->sreg1, ins->sreg2); + case OP_S390_VMNLH: + s390_vmnlh (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PSUBD: - s390x_psubd (code, ins->sreg1, ins->sreg2); + case OP_S390_VMNLF: + s390_vmnlf (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PSUBQ: - s390x_psubq (code, ins->sreg1, ins->sreg2); + case OP_S390_VMNLG: + s390_vmnlg (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PMAXB_UN: - s390x_pmaxub (code, ins->sreg1, ins->sreg2); + case OP_S390_VREPIB: + s390_vrepib (code, ins->dreg, ins->inst_c1); break; - case OP_PMAXW_UN: - s390x_pmaxuw (code, ins->sreg1, ins->sreg2); + case OP_S390_VREPIH: + s390_vrepih (code, ins->dreg, ins->inst_c1); break; - case OP_PMAXD_UN: - s390x_pmaxud (code, ins->sreg1, ins->sreg2); + case OP_S390_VREPIF: + s390_vrepif (code, ins->dreg, ins->inst_c1); break; - - case OP_PMAXB: - s390x_pmaxsb (code, ins->sreg1, ins->sreg2); + case OP_S390_VREPIG: + s390_vrepig (code, ins->dreg, ins->inst_c1); break; - case OP_PMAXW: - s390x_pmaxsw (code, ins->sreg1, ins->sreg2); + case OP_S390_VCEQBS: + s390_vceqbs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PMAXD: - s390x_pmaxsd (code, ins->sreg1, ins->sreg2); + case OP_S390_VCEQB: + s390_vceqb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PAVGB_UN: - s390x_pavgb (code, ins->sreg1, ins->sreg2); + case OP_S390_VCEQHS: + s390_vceqhs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PAVGW_UN: - s390x_pavgw (code, ins->sreg1, ins->sreg2); + case OP_S390_VCEQH: + s390_vceqh (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PMINB_UN: - s390x_pminub (code, ins->sreg1, ins->sreg2); + case OP_S390_VCEQFS: + s390_vceqfs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PMINW_UN: - s390x_pminuw (code, ins->sreg1, ins->sreg2); + case OP_S390_VCEQF: + s390_vceqf (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PMIND_UN: - s390x_pminud (code, ins->sreg1, ins->sreg2); + case OP_S390_VCEQGS: + s390_vceqgs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PMINB: - s390x_pminsb (code, ins->sreg1, ins->sreg2); + case OP_S390_VCEQG: + s390_vceqg (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PMINW: - s390x_pminsw (code, ins->sreg1, ins->sreg2); + case OP_S390_VFCESBS: + s390_vfcesbs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PMIND: - s390x_pminsd (code, ins->sreg1, ins->sreg2); + case OP_S390_VFCESB: + s390_vfcesb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PCMPEQB: - s390x_pcmpeqb (code, ins->sreg1, ins->sreg2); + case OP_S390_VFCEDBS: + s390_vfcedbs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PCMPEQW: - s390x_pcmpeqw (code, ins->sreg1, ins->sreg2); + case OP_S390_VFCEDB: + s390_vfcedb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PCMPEQD: - s390x_pcmpeqd (code, ins->sreg1, ins->sreg2); + case OP_S390_VFCHSBS: + s390_vfchsbs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PCMPEQQ: - s390x_pcmpeqq (code, ins->sreg1, ins->sreg2); + case OP_S390_VFCHSB: + s390_vfchsb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PCMPGTB: - s390x_pcmpgtb (code, ins->sreg1, ins->sreg2); + case OP_S390_VFCHDBS: + s390_vfchdbs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PCMPGTW: - s390x_pcmpgtw (code, ins->sreg1, ins->sreg2); + case OP_S390_VFCHDB: + s390_vfchdb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PCMPGTD: - s390x_pcmpgtd (code, ins->sreg1, ins->sreg2); + case OP_S390_VFCHESBS: + s390_vfchesbs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PCMPGTQ: - s390x_pcmpgtq (code, ins->sreg1, ins->sreg2); + case OP_S390_VFCHESB: + s390_vfchesb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PSUM_ABS_DIFF: - s390x_psadbw (code, ins->sreg1, ins->sreg2); + case OP_S390_VFCHEDBS: + s390_vfchedbs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_UNPACK_LOWB: - s390x_punpcklbw (code, ins->sreg1, ins->sreg2); + case OP_S390_VFCHEDB: + s390_vfchedb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_UNPACK_LOWW: - s390x_punpcklwd (code, ins->sreg1, ins->sreg2); + case OP_S390_VGMB: + s390_vgmb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_UNPACK_LOWD: - s390x_punpckldq (code, ins->sreg1, ins->sreg2); + case OP_S390_VGMH: + s390_vgmh (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_UNPACK_LOWQ: - s390x_punpcklqdq (code, ins->sreg1, ins->sreg2); + case OP_S390_VGMF: + s390_vgmf (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_UNPACK_LOWPS: - s390x_unpcklps (code, ins->sreg1, ins->sreg2); + case OP_S390_VGMG: + s390_vgmg (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_UNPACK_LOWPD: - s390x_unpcklpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VECB: + s390_vecb (code, ins->dreg, ins->sreg1); break; - - case OP_UNPACK_HIGHB: - s390x_punpckhbw (code, ins->sreg1, ins->sreg2); + case OP_S390_VECH: + s390_vech (code, ins->dreg, ins->sreg1); break; - case OP_UNPACK_HIGHW: - s390x_punpckhwd (code, ins->sreg1, ins->sreg2); + case OP_S390_VECF: + s390_vecf (code, ins->dreg, ins->sreg1); break; - case OP_UNPACK_HIGHD: - s390x_punpckhdq (code, ins->sreg1, ins->sreg2); + case OP_S390_VECG: + s390_vecg (code, ins->dreg, ins->sreg1); break; - case OP_UNPACK_HIGHQ: - s390x_punpckhqdq (code, ins->sreg1, ins->sreg2); + case OP_S390_VECLB: + s390_veclb (code, ins->dreg, ins->sreg1); break; - case OP_UNPACK_HIGHPS: - s390x_unpckhps (code, ins->sreg1, ins->sreg2); + case OP_S390_VECLH: + s390_veclh (code, ins->dreg, ins->sreg1); break; - case OP_UNPACK_HIGHPD: - s390x_unpckhpd (code, ins->sreg1, ins->sreg2); + case OP_S390_VECLF: + s390_veclf (code, ins->dreg, ins->sreg1); break; - - case OP_PACKW: - s390x_packsswb (code, ins->sreg1, ins->sreg2); + case OP_S390_VECLG: + s390_veclg (code, ins->dreg, ins->sreg1); break; - case OP_PACKD: - s390x_packssdw (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHBS: + s390_vchbs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PACKW_UN: - s390x_packuswb (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHHS: + s390_vchhs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PACKD_UN: - s390x_packusdw (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHFS: + s390_vchfs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PADDB_SAT_UN: - s390x_paddusb (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHGS: + s390_vchgs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PSUBB_SAT_UN: - s390x_psubusb (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHB: + s390_vchb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PADDW_SAT_UN: - s390x_paddusw (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHH: + s390_vchh (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PSUBW_SAT_UN: - s390x_psubusw (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHF: + s390_vchf (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PADDB_SAT: - s390x_paddsb (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHG: + s390_vchg (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PSUBB_SAT: - s390x_psubsb (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHLBS: + s390_vchlbs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PADDW_SAT: - s390x_paddsw (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHLHS: + s390_vchlhs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PSUBW_SAT: - s390x_psubsw (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHLFS: + s390_vchlfs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PMULW: - s390x_pmullw (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHLGS: + s390_vchlgs (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PMULD: - s390x_pmulld (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHLB: + s390_vchlb (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PMULQ: - s390x_pmuludq (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHLH: + s390_vchlh (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PMULW_HIGH_UN: - s390x_pmulhuw (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHLF: + s390_vchlf (code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_PMULW_HIGH: - s390x_pmulhw (code, ins->sreg1, ins->sreg2); + case OP_S390_VCHLG: + s390_vchlg (code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_PSHRW: - s390x_psrlw_reg_imm (code, ins->dreg, ins->inst_imm); + case OP_S390_VLPB: + s390_vlpb (code, ins->dreg, ins->sreg1); break; - case OP_PSHRW_REG: - s390x_psrlw (code, ins->dreg, ins->sreg2); + case OP_S390_VLPH: + s390_vlph (code, ins->dreg, ins->sreg1); break; - - case OP_PSARW: - s390x_psraw_reg_imm (code, ins->dreg, ins->inst_imm); + case OP_S390_VLPF: + s390_vlpf (code, ins->dreg, ins->sreg1); break; - case OP_PSARW_REG: - s390x_psraw (code, ins->dreg, ins->sreg2); + case OP_S390_VLPG: + s390_vlpg (code, ins->dreg, ins->sreg1); break; - - case OP_PSHLW: - s390x_psllw_reg_imm (code, ins->dreg, ins->inst_imm); + case OP_S390_VFLPDB: + s390_vfpsodb (code, ins->dreg, ins->sreg1, 2); break; - case OP_PSHLW_REG: - s390x_psllw (code, ins->dreg, ins->sreg2); + case OP_S390_VFLPSB: + s390_vfpsosb (code, ins->dreg, ins->sreg1, 2); break; - - case OP_PSHRD: - s390x_psrld_reg_imm (code, ins->dreg, ins->inst_imm); + case OP_S390_VFLCDB: + s390_vfpsodb (code, ins->dreg, ins->sreg1, 0); break; - case OP_PSHRD_REG: - s390x_psrld (code, ins->dreg, ins->sreg2); + case OP_S390_VFLCSB: + s390_vfpsosb (code, ins->dreg, ins->sreg1, 0); break; - - case OP_PSARD: - s390x_psrad_reg_imm (code, ins->dreg, ins->inst_imm); + case OP_INSERT_I1: + if (ins->dreg != ins->sreg1) + s390_vlr (code, ins->dreg, ins->sreg1); + s390_vlvgb (code, ins->dreg, ins->sreg2, 0, GTMREG_TO_UINT32 (ins->inst_c0)); + break; + case OP_INSERT_I2: + if (ins->dreg != ins->sreg1) + s390_vlr (code, ins->dreg, ins->sreg1); + s390_vlvgh (code, ins->dreg, ins->sreg2, 0, GTMREG_TO_UINT32 (ins->inst_c0)); break; - case OP_PSARD_REG: - s390x_psrad (code, ins->dreg, ins->sreg2); + case OP_INSERT_I4: + if (ins->dreg != ins->sreg1) + s390_vlr (code, ins->dreg, ins->sreg1); + s390_vlvgf (code, ins->dreg, ins->sreg2, 0, GTMREG_TO_UINT32 (ins->inst_c0)); break; - - case OP_PSHLD: - s390x_pslld_reg_imm (code, ins->dreg, ins->inst_imm); + case OP_INSERT_I8: + if (ins->dreg != ins->sreg1) + s390_vlr (code, ins->dreg, ins->sreg1); + s390_vlvgg (code, ins->dreg, ins->sreg2, 0, GTMREG_TO_UINT32 (ins->inst_c0)); break; - case OP_PSHLD_REG: - s390x_pslld (code, ins->dreg, ins->sreg2); + case OP_INSERT_R4: + s390_vlgvf (code, s390_r13, ins->sreg2, 0, 0); + s390_vlvgf (code, ins->dreg, s390_r13, 0, GTMREG_TO_UINT32 (ins->inst_c0)); break; - - case OP_PSHRQ: - s390x_psrlq_reg_imm (code, ins->dreg, ins->inst_imm); + case OP_INSERT_R8: + s390_vlgvg (code, s390_r13, ins->sreg2, 0, 0); + s390_vlvgg (code, ins->dreg, s390_r13, 0, GTMREG_TO_UINT32 (ins->inst_c0)); break; - case OP_PSHRQ_REG: - s390x_psrlq (code, ins->dreg, ins->sreg2); + case OP_EXTRACT_I1: + s390_vlgvb (code, ins->dreg, ins->sreg1, 0, GTMREG_TO_UINT32 (ins->inst_c0)); break; - - /*TODO: This is appart of the sse spec but not added - case OP_PSARQ: - s390x_psraq_reg_imm (code, ins->dreg, ins->inst_imm); + case OP_EXTRACT_I2: + s390_vlgvh (code, ins->dreg, ins->sreg1, 0, GTMREG_TO_UINT32 (ins->inst_c0)); break; - case OP_PSARQ_REG: - s390x_psraq (code, ins->dreg, ins->sreg2); + case OP_EXTRACT_I4: + s390_vlgvf (code, ins->dreg, ins->sreg1, 0, GTMREG_TO_UINT32 (ins->inst_c0)); break; - */ - - case OP_PSHLQ: - s390x_psllq_reg_imm (code, ins->dreg, ins->inst_imm); + case OP_EXTRACT_I8: + s390_vlgvg (code, ins->dreg, ins->sreg1, 0, GTMREG_TO_UINT32 (ins->inst_c0)); break; - case OP_PSHLQ_REG: - s390x_psllq (code, ins->dreg, ins->sreg2); + case OP_EXTRACT_R4: + s390_vlgvf (code, s390_r13, ins->sreg1, 0, GTMREG_TO_UINT32 (ins->inst_c0)); + s390_vlvgf (code, ins->dreg, s390_r13, 0, 0); break; - case OP_CVTDQ2PD: - s390x_cvtdq2pd (code, ins->dreg, ins->sreg1); + case OP_EXTRACT_R8: + s390_vlgvg (code, s390_r13, ins->sreg1, 0, GTMREG_TO_UINT32 (ins->inst_c0)); + s390_ldgr (code, ins->dreg, s390_r13); break; - case OP_CVTDQ2PS: - s390x_cvtdq2ps (code, ins->dreg, ins->sreg1); + case OP_XEXTRACT_I1: + s390_vlgvb (code, ins->dreg, ins->sreg1, ins->sreg2, 0); break; - case OP_CVTPD2DQ: - s390x_cvtpd2dq (code, ins->dreg, ins->sreg1); + case OP_XEXTRACT_I2: + s390_vlgvh (code, ins->dreg, ins->sreg1, ins->sreg2, 0); break; - case OP_CVTPD2PS: - s390x_cvtpd2ps (code, ins->dreg, ins->sreg1); + case OP_XEXTRACT_I4: + s390_vlgvf (code, ins->dreg, ins->sreg1, ins->sreg2, 0); break; - case OP_CVTPS2DQ: - s390x_cvtps2dq (code, ins->dreg, ins->sreg1); + case OP_XEXTRACT_I8: + s390_vlgvg (code, ins->dreg, ins->sreg1, ins->sreg2, 0); break; - case OP_CVTPS2PD: - s390x_cvtps2pd (code, ins->dreg, ins->sreg1); + case OP_XEXTRACT_R4: + s390_vlgvf (code, s390_r13, ins->sreg1, ins->sreg2, 0); + s390_ldgr (code, ins->dreg, s390_r13); break; - case OP_CVTTPD2DQ: - s390x_cvttpd2dq (code, ins->dreg, ins->sreg1); + case OP_XEXTRACT_R8: + s390_vlgvg (code, s390_r13, ins->sreg1, ins->sreg2, 0); + s390_ldgr (code, ins->dreg, s390_r13); break; - case OP_CVTTPS2DQ: - s390x_cvttps2dq (code, ins->dreg, ins->sreg1); + case OP_EXPAND_I1: + s390_vlvgb (code, ins->dreg, ins->sreg1, 0, GTMREG_TO_UINT32 (ins->inst_c0)); + s390_vrepb (code, ins->dreg, ins->dreg, 0); break; - - case OP_ICONV_TO_X: - amd64_movd_xreg_reg_size (code, ins->dreg, ins->sreg1, 4); + case OP_EXPAND_I2: + s390_vlvgh (code, ins->dreg, ins->sreg1, 0, GTMREG_TO_UINT32 (ins->inst_c0)); + s390_vreph (code, ins->dreg, ins->dreg, 0); break; - case OP_EXTRACT_I4: - amd64_movd_reg_xreg_size (code, ins->dreg, ins->sreg1, 4); + case OP_EXPAND_I4: + s390_vlvgf (code, ins->dreg, ins->sreg1, 0, GTMREG_TO_UINT32 (ins->inst_c0)); + s390_vrepf (code, ins->dreg, ins->dreg, 0); break; - case OP_EXTRACT_I8: - if (ins->inst_c0) { - amd64_movhlps (code, MONO_ARCH_FP_SCRATCH_REG, ins->sreg1); - amd64_movd_reg_xreg_size (code, ins->dreg, MONO_ARCH_FP_SCRATCH_REG, 8); - } else { - amd64_movd_reg_xreg_size (code, ins->dreg, ins->sreg1, 8); - } + case OP_EXPAND_I8: + s390_vlvgg (code, ins->dreg, ins->sreg1, 0, GTMREG_TO_UINT32 (ins->inst_c0)); + s390_vrepg (code, ins->dreg, ins->dreg, 0); break; - case OP_EXTRACT_I1: - case OP_EXTRACT_U1: - amd64_movd_reg_xreg_size (code, ins->dreg, ins->sreg1, 4); - if (ins->inst_c0) - amd64_shift_reg_imm (code, X86_SHR, ins->dreg, ins->inst_c0 * 8); - amd64_widen_reg (code, ins->dreg, ins->dreg, ins->inst_c1 == OP_EXTRACT_I1, FALSE); + case OP_EXPAND_R4: + s390_vlgvf (code, s390_r13, ins->sreg1, 0, 0); + s390_vlvgf (code, ins->dreg, s390_r13, 0, GTMREG_TO_UINT32 (ins->inst_c0)); + s390_vrepf (code, ins->dreg, ins->dreg, 0); break; - case OP_EXTRACT_I2: - case OP_EXTRACT_U2: - /*amd64_movd_reg_xreg_size (code, ins->dreg, ins->sreg1, 4); - if (ins->inst_c0) - amd64_shift_reg_imm_size (code, X86_SHR, ins->dreg, 16, 4);*/ - s390x_pextrw_imm (code, ins->dreg, ins->sreg1, ins->inst_c0); - amd64_widen_reg_size (code, ins->dreg, ins->dreg, ins->inst_c1 == OP_EXTRACT_I2, TRUE, 4); + case OP_EXPAND_R8: + s390_lgdr (code, s390_r13, ins->sreg1); + s390_vlvgg (code, ins->dreg, s390_r13, 0, GTMREG_TO_UINT32 (ins->inst_c0)); + s390_vrepg (code, ins->dreg, ins->dreg, 0); break; - case OP_EXTRACT_R8: - if (ins->inst_c0) - amd64_movhlps (code, ins->dreg, ins->sreg1); - else - s390x_movsd (code, ins->dreg, ins->sreg1); + case OP_S390_VPKH: + s390_vpkh ( code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_INSERT_I2: - s390x_pinsrw_imm (code, ins->sreg1, ins->sreg2, ins->inst_c0); - break; - case OP_EXTRACTX_U2: - s390x_pextrw_imm (code, ins->dreg, ins->sreg1, ins->inst_c0); - break; - case OP_INSERTX_U1_SLOW: - /*sreg1 is the extracted ireg (scratch) - /sreg2 is the to be inserted ireg (scratch) - /dreg is the xreg to receive the value*/ - - /*clear the bits from the extracted word*/ - amd64_alu_reg_imm (code, X86_AND, ins->sreg1, ins->inst_c0 & 1 ? 0x00FF : 0xFF00); - /*shift the value to insert if needed*/ - if (ins->inst_c0 & 1) - amd64_shift_reg_imm_size (code, X86_SHL, ins->sreg2, 8, 4); - /*join them together*/ - amd64_alu (code, X86_OR, ins->sreg1, ins->sreg2); - s390x_pinsrw_imm (code, ins->dreg, ins->sreg1, ins->inst_c0 / 2); - break; - case OP_INSERTX_I4_SLOW: - s390x_pinsrw_imm (code, ins->dreg, ins->sreg2, ins->inst_c0 * 2); - amd64_shift_reg_imm (code, X86_SHR, ins->sreg2, 16); - s390x_pinsrw_imm (code, ins->dreg, ins->sreg2, ins->inst_c0 * 2 + 1); - break; - case OP_INSERTX_I8_SLOW: - amd64_movd_xreg_reg_size(code, MONO_ARCH_FP_SCRATCH_REG, ins->sreg2, 8); - if (ins->inst_c0) - amd64_movlhps (code, ins->dreg, MONO_ARCH_FP_SCRATCH_REG); - else - s390x_movsd (code, ins->dreg, MONO_ARCH_FP_SCRATCH_REG); + case OP_S390_VPKF: + s390_vpkf ( code, ins->dreg, ins->sreg1, ins->sreg2); break; - - case OP_INSERTX_R4_SLOW: - switch (ins->inst_c0) { - case 0: - s390x_movss (code, ins->dreg, ins->sreg2); - break; - case 1: - s390x_pshufd_imm (code, ins->dreg, ins->dreg, mono_simd_shuffle_mask(1, 0, 2, 3)); - s390x_movss (code, ins->dreg, ins->sreg2); - s390x_pshufd_imm (code, ins->dreg, ins->dreg, mono_simd_shuffle_mask(1, 0, 2, 3)); - break; - case 2: - s390x_pshufd_imm (code, ins->dreg, ins->dreg, mono_simd_shuffle_mask(2, 1, 0, 3)); - s390x_movss (code, ins->dreg, ins->sreg2); - s390x_pshufd_imm (code, ins->dreg, ins->dreg, mono_simd_shuffle_mask(2, 1, 0, 3)); - break; - case 3: - s390x_pshufd_imm (code, ins->dreg, ins->dreg, mono_simd_shuffle_mask(3, 1, 2, 0)); - s390x_movss (code, ins->dreg, ins->sreg2); - s390x_pshufd_imm (code, ins->dreg, ins->dreg, mono_simd_shuffle_mask(3, 1, 2, 0)); - break; - } + case OP_S390_VPKG: + s390_vpkg ( code, ins->dreg, ins->sreg1, ins->sreg2); break; - case OP_INSERTX_R8_SLOW: - if (ins->inst_c0) - amd64_movlhps (code, ins->dreg, ins->sreg2); - else - s390x_movsd (code, ins->dreg, ins->sreg2); + case OP_S390_VLCB: + s390_vlcb (code, ins->dreg, ins->sreg1); break; - case OP_STOREX_MEMBASE_REG: - case OP_STOREX_MEMBASE: - s390x_movups_membase_reg (code, ins->dreg, ins->inst_offset, ins->sreg1); + case OP_S390_VLCH: + s390_vlch (code, ins->dreg, ins->sreg1); break; - case OP_LOADX_MEMBASE: - s390x_movups_reg_membase (code, ins->dreg, ins->sreg1, ins->inst_offset); + case OP_S390_VLCF: + s390_vlcf (code, ins->dreg, ins->sreg1); break; - case OP_LOADX_ALIGNED_MEMBASE: - s390x_movaps_reg_membase (code, ins->dreg, ins->sreg1, ins->inst_offset); + case OP_S390_VLCG: + s390_vlcg (code, ins->dreg, ins->sreg1); break; - case OP_STOREX_ALIGNED_MEMBASE_REG: - s390x_movaps_membase_reg (code, ins->dreg, ins->inst_offset, ins->sreg1); + case OP_S390_VUPLB: + s390_vuplb (code, ins->dreg, ins->sreg1); break; - case OP_STOREX_NTA_MEMBASE_REG: - s390x_movntps_reg_membase (code, ins->dreg, ins->sreg1, ins->inst_offset); + case OP_S390_VUPLHW: + s390_vuplhw (code, ins->dreg, ins->sreg1); break; - case OP_PREFETCH_MEMBASE: - s390x_prefetch_reg_membase (code, ins->backend.arg_info, ins->sreg1, ins->inst_offset); + case OP_S390_VUPLF: + s390_vuplf (code, ins->dreg, ins->sreg1); break; - - case OP_XMOVE: - /*FIXME the peephole pass should have killed this*/ - if (ins->dreg != ins->sreg1) - s390x_movaps (code, ins->dreg, ins->sreg1); + case OP_S390_VUPLLB: + s390_vupllb (code, ins->dreg, ins->sreg1); break; - case OP_XZERO: - s390x_pxor (code, ins->dreg, ins->dreg); + case OP_S390_VUPLLH: + s390_vupllh (code, ins->dreg, ins->sreg1); break; - case OP_ICONV_TO_R4_RAW: - amd64_movd_xreg_reg_size (code, ins->dreg, ins->sreg1, 4); + case OP_S390_VUPLLF: + s390_vupllf (code, ins->dreg, ins->sreg1); break; - - case OP_FCONV_TO_R8_X: - s390x_movsd (code, ins->dreg, ins->sreg1); + case OP_S390_VUPHB: + s390_vuphb (code, ins->dreg, ins->sreg1); break; - - case OP_XCONV_R8_TO_I4: - s390x_cvttsd2si_reg_xreg_size (code, ins->dreg, ins->sreg1, 4); - switch (ins->backend.source_opcode) { - case OP_FCONV_TO_I1: - amd64_widen_reg (code, ins->dreg, ins->dreg, TRUE, FALSE); - break; - case OP_FCONV_TO_U1: - amd64_widen_reg (code, ins->dreg, ins->dreg, FALSE, FALSE); - break; - case OP_FCONV_TO_I2: - amd64_widen_reg (code, ins->dreg, ins->dreg, TRUE, TRUE); - break; - case OP_FCONV_TO_U2: - amd64_widen_reg (code, ins->dreg, ins->dreg, FALSE, TRUE); - break; - } + case OP_S390_VUPHH: + s390_vuphh (code, ins->dreg, ins->sreg1); break; - - case OP_EXPAND_I2: - s390x_pinsrw_imm (code, ins->dreg, ins->sreg1, 0); - s390x_pinsrw_imm (code, ins->dreg, ins->sreg1, 1); - s390x_pshufd_imm (code, ins->dreg, ins->dreg, 0); + case OP_S390_VUPHF: + s390_vuphf (code, ins->dreg, ins->sreg1); break; - case OP_EXPAND_I4: - amd64_movd_xreg_reg_size (code, ins->dreg, ins->sreg1, 4); - s390x_pshufd_imm (code, ins->dreg, ins->dreg, 0); + case OP_S390_VUPLHB: + s390_vuplhb (code, ins->dreg, ins->sreg1); break; - case OP_EXPAND_I8: - amd64_movd_xreg_reg_size (code, ins->dreg, ins->sreg1, 8); - s390x_pshufd_imm (code, ins->dreg, ins->dreg, 0x44); + case OP_S390_VUPLHH: + s390_vuplhh (code, ins->dreg, ins->sreg1); break; - case OP_EXPAND_R4: - s390x_movsd (code, ins->dreg, ins->sreg1); - s390x_pshufd_imm (code, ins->dreg, ins->dreg, 0); + case OP_S390_VUPLHF: + s390_vuplhf (code, ins->dreg, ins->sreg1); break; - case OP_EXPAND_R8: - s390x_movsd (code, ins->dreg, ins->sreg1); - s390x_pshufd_imm (code, ins->dreg, ins->dreg, 0x44); + case OP_S390_VFISB: + s390_vfisb (code, ins->dreg, ins->sreg1, 0, ins->inst_c0); + break; + case OP_S390_VFIDB: + s390_vfidb (code, ins->dreg, ins->sreg1, 0, ins->inst_c0); + break; + case OP_S390_VFSQSB: + s390_vfsqsb (code, ins->dreg, ins->sreg1); + break; + case OP_S390_VFSQDB: + s390_vfsqdb (code, ins->dreg, ins->sreg1); + break; + case OP_XONES: + s390_vgbm (code, ins->dreg, 0xffff); + break; + case OP_XMOVE: + if (ins->dreg != ins->sreg1) + s390_vlr(code, ins->dreg, ins->sreg1); + break; + case OP_XZERO: + s390_vgbm (code, ins->dreg, 0); break; #endif default: diff --git a/src/mono/mono/mini/mini-s390x.h b/src/mono/mono/mini/mini-s390x.h index 5f622938821b94..82b2f411f4d439 100644 --- a/src/mono/mono/mini/mini-s390x.h +++ b/src/mono/mono/mini/mini-s390x.h @@ -83,7 +83,9 @@ struct SeqPointInfo { #define MONO_ARCH_HAVE_SETUP_RESUME_FROM_SIGNAL_HANDLER_CTX 1 #define MONO_ARCH_HAVE_UNWIND_BACKTRACE 1 #define MONO_ARCH_FLOAT32_SUPPORTED 1 - +#define MONO_ARCH_SIMD_INTRINSICS 1 +#define MONO_ARCH_NEED_SIMD_BANK 1 +#define MONO_ARCH_USE_SHARED_FP_SIMD_BANK 1 #define S390_STACK_ALIGNMENT 8 #define S390_FIRST_ARG_REG s390_r2 #define S390_LAST_ARG_REG s390_r6 @@ -147,9 +149,9 @@ struct SeqPointInfo { /*-----------------------------------------------*/ /* SIMD Related Definitions */ /*-----------------------------------------------*/ - +/* f0 overlaps with v0 and vr16 is used internally */ #define MONO_MAX_XREGS 31 -#define MONO_ARCH_CALLEE_XREGS 0x0 +#define MONO_ARCH_CALLEE_XREGS 0xFFFFFFFE #define MONO_ARCH_CALLEE_SAVED_XREGS 0x0 // Does the ABI have a volatile non-parameter register, so tailcall @@ -293,6 +295,21 @@ s390_patch_addr (guchar *code, guint64 target) s390_##op (loc, r, 0, s390_r13, 0); \ } +#define S390_LONG_VEC(loc, opy, op, r, off, ix, br) \ + if (s390_is_imm12(off)) { \ + s390_##opy (loc, r, ix, br, off); \ + } else { \ + if (ix == 0) { \ + S390_SET(loc, s390_r13, off); \ + s390_la (loc, s390_r13, s390_r13, br, 0); \ + } else { \ + s390_la (loc, s390_r13, ix, br, 0); \ + S390_SET (loc, s390_r0, off); \ + s390_agr (loc, s390_r13, s390_r0); \ + } \ + s390_##op (loc, r, 0, s390_r13, 0); \ + } + #define S390_SET_MASK(loc, dr, v) \ do { \ if (s390_is_imm16 (v)) { \ diff --git a/src/mono/mono/mini/mini-wasm.c b/src/mono/mono/mini/mini-wasm.c index c9d5521a8b6708..be863e82f73f30 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -799,7 +799,7 @@ mini_wasm_is_scalar_vtype (MonoType *type, MonoType **etype) } else if (MONO_TYPE_ISSTRUCT (t)) { if (!mini_wasm_is_scalar_vtype (t, etype)) return FALSE; - } else if (!((MONO_TYPE_IS_PRIMITIVE (t) || MONO_TYPE_IS_REFERENCE (t) || MONO_TYPE_IS_POINTER (t)))) { + } else if (!(MONO_TYPE_IS_PRIMITIVE (t) || MONO_TYPE_IS_REFERENCE (t) || MONO_TYPE_IS_POINTER (t))) { return FALSE; } else { if (etype) @@ -807,10 +807,12 @@ mini_wasm_is_scalar_vtype (MonoType *type, MonoType **etype) } } - if (etype) { - if (!(*etype)) - *etype = mono_get_int32_type (); + // empty struct + if (nfields == 0 && etype) { + *etype = m_class_get_byval_arg (mono_defaults.sbyte_class); } + g_assert (!etype || *etype); + return TRUE; } diff --git a/src/mono/mono/mini/mini.c b/src/mono/mono/mini/mini.c index 5f82961fe6c722..6c8bb702be93d1 100644 --- a/src/mono/mono/mini/mini.c +++ b/src/mono/mono/mini/mini.c @@ -1039,7 +1039,7 @@ mono_allocate_stack_slots2 (MonoCompile *cfg, gboolean backward, guint32 *stack_ if (cfg->gsharedvt && mini_is_gsharedvt_variable_type (t)) continue; - /* inst->backend.is_pinvoke indicates native sized value types, this is used by the + /* inst->backend.is_pinvoke indicates native-sized value types, this is used by the * pinvoke wrappers when they call functions returning structures */ if (inst->backend.is_pinvoke && MONO_TYPE_ISSTRUCT (t) && t->type != MONO_TYPE_TYPEDBYREF) { size = mono_class_native_size (mono_class_from_mono_type_internal (t), &align); @@ -1348,7 +1348,7 @@ mono_allocate_stack_slots (MonoCompile *cfg, gboolean backward, guint32 *stack_s if (cfg->gsharedvt && mini_is_gsharedvt_variable_type (t)) continue; - /* inst->backend.is_pinvoke indicates native sized value types, this is used by the + /* inst->backend.is_pinvoke indicates native-sized value types, this is used by the * pinvoke wrappers when they call functions returning structures */ if (inst->backend.is_pinvoke && MONO_TYPE_ISSTRUCT (t) && t->type != MONO_TYPE_TYPEDBYREF) { size = mono_class_native_size (mono_class_from_mono_type_internal (t), &align); diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 26ebd7f90fdf6b..65b38b751e8c45 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -64,6 +64,12 @@ typedef struct SeqPointInfo SeqPointInfo; #include "mono/metadata/callspec.h" #include "mono/metadata/icall-signatures.h" +/* we use runtime checks to fallback to scalar ops for/ + * older z/Architectures + */ +#ifdef TARGET_S390X +#include +#endif /* * The mini code should not have any compile time dependencies on the GC being used, so the same object file from mini/ * can be linked into both mono and mono-sgen. @@ -1306,6 +1312,12 @@ typedef enum { #define vreg_is_ref(cfg, vreg) (GINT_TO_UINT32(vreg) < (cfg)->vreg_is_ref_len ? (cfg)->vreg_is_ref [(vreg)] : 0) #define vreg_is_mp(cfg, vreg) (GINT_TO_UINT32(vreg) < (cfg)->vreg_is_mp_len ? (cfg)->vreg_is_mp [(vreg)] : 0) +typedef struct { + MonoInst* addr_var; + int alloc_size; + GSList* localloc_ins; +} MonoCachedLocallocInfo; + /* * Control Flow Graph and compilation unit information */ @@ -1661,6 +1673,8 @@ typedef struct { gboolean *clause_is_dead; + MonoCachedLocallocInfo localloc_cache [2]; + /* Stats */ int stat_allocate_var; int stat_locals_stack_size; @@ -3007,6 +3021,11 @@ mini_safepoints_enabled (void) static inline gboolean mini_class_is_simd (MonoCompile *cfg, MonoClass *klass) { +#ifdef TARGET_S390X + /* vector facility was introduced in z13 */ + if (!mono_hwcap_s390x_has_vec) + return FALSE; +#endif #ifdef MONO_ARCH_SIMD_INTRINSICS if (!(((cfg)->opt & MONO_OPT_SIMD) && m_class_is_simd_type (klass))) return FALSE; diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index da2f83be0d5571..ebe0637605fe5a 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -406,7 +406,7 @@ emit_simd_ins_for_binary_op (MonoCompile *cfg, MonoClass *klass, MonoMethodSigna if (type_enum_is_float (arg_type)) { instc0 = OP_FMUL; } else { -#ifdef TARGET_ARM64 +#if defined(TARGET_ARM64) || defined(TARGET_S390X) if (!COMPILE_LLVM (cfg) && (arg_type == MONO_TYPE_I8 || arg_type == MONO_TYPE_U8 || arg_type == MONO_TYPE_I || arg_type == MONO_TYPE_U)) return NULL; #endif @@ -448,7 +448,7 @@ emit_simd_ins_for_binary_op (MonoCompile *cfg, MonoClass *klass, MonoMethodSigna static MonoInst* emit_simd_ins_for_unary_op (MonoCompile *cfg, MonoClass *klass, MonoMethodSignature *fsig, MonoInst **args, MonoTypeEnum arg_type, int id) { -#if defined(TARGET_ARM64) || defined(TARGET_AMD64) || defined(TARGET_WASM) +#if defined(TARGET_ARM64) || defined(TARGET_AMD64) || defined(TARGET_WASM) || defined(TARGET_S390X) int op = -1; switch (id){ case SN_Negate: @@ -557,6 +557,12 @@ emit_xequal (MonoCompile *cfg, MonoClass *klass, MonoTypeEnum element_type, Mono } else { return emit_simd_ins (cfg, klass, OP_XEQUAL, arg1->dreg, arg2->dreg); } +#elif defined(TARGET_S390X) + MonoInst* ret = emit_simd_ins (cfg, mono_defaults.boolean_class, OP_S390_XCOMPARE_XEXTRACT, arg1->dreg, arg2->dreg); + ret->inst_c0 = SIMD_EXTR_ARE_ALL_SET; + ret->inst_c0 |= ((((gint64)CMP_EQ) << 4) & 0xf0); + ret->inst_c1 = element_type; + return ret; #else MonoInst *ins = emit_simd_ins (cfg, klass, OP_XEQUAL, arg1->dreg, arg2->dreg); if (!COMPILE_LLVM (cfg)) @@ -686,6 +692,88 @@ get_xconst_int_elem (MonoCompile *cfg, MonoInst *ins, MonoTypeEnum etype, int in } } +#ifdef TARGET_S390X +static int type_to_extract_op (MonoTypeEnum type); + +static int +lower_xcompare_op (int intrinsic_id, MonoTypeEnum etype) +{ + gboolean is_unsigned = type_enum_is_unsigned (etype); + + switch (intrinsic_id) { + case SN_GreaterThan: + case SN_GreaterThanAll: + case SN_GreaterThanAny: + return is_unsigned ? CMP_GT_UN : CMP_GT; + break; + case SN_GreaterThanOrEqual: + case SN_GreaterThanOrEqualAll: + case SN_GreaterThanOrEqualAny: + return is_unsigned ? CMP_GE_UN : CMP_GE; + break; + case SN_LessThan: + case SN_LessThanAll: + case SN_LessThanAny: + return is_unsigned ? CMP_LT_UN : CMP_LT; + break; + case SN_LessThanOrEqual: + case SN_LessThanOrEqualAll: + case SN_LessThanOrEqualAny: + return is_unsigned ? CMP_LE_UN : CMP_LE; + break; + default: + g_assert_not_reached (); + } +} + +static MonoInst* +emit_sum_vector (MonoCompile *cfg, MonoType *vector_type, MonoTypeEnum element_type, MonoInst *arg) +{ + MonoClass *vector_class = mono_class_from_mono_type_internal (vector_type); + int op = -1; + MonoInst *tmp = emit_xzero (cfg, vector_class); + MonoInst *ins = arg; + int index = -1; + switch (element_type) { + case MONO_TYPE_R4: + return NULL; + break; + case MONO_TYPE_R8: + return NULL; + break; + case MONO_TYPE_I1: + case MONO_TYPE_U1: + ins = emit_simd_ins (cfg, vector_class, OP_S390_VSUMB, ins->dreg,tmp->dreg); + ins = emit_simd_ins (cfg, vector_class, OP_S390_VSUMQF, ins->dreg,tmp->dreg); + index = 16; + break; + case MONO_TYPE_I2: + case MONO_TYPE_U2: + ins = emit_simd_ins (cfg, vector_class, OP_S390_VSUMH, ins->dreg,tmp->dreg); + ins = emit_simd_ins (cfg, vector_class, OP_S390_VSUMQF, ins->dreg,tmp->dreg); + index = 8; + break; + case MONO_TYPE_I4: + case MONO_TYPE_U4: + ins = emit_simd_ins (cfg, vector_class, OP_S390_VSUMQF, ins->dreg,tmp->dreg); + index = 4; + break; + case MONO_TYPE_I: + case MONO_TYPE_U: + case MONO_TYPE_I8: + case MONO_TYPE_U8: + ins = emit_simd_ins (cfg, vector_class, OP_S390_VSUMQG, ins->dreg,tmp->dreg); + index = 2; + break; + default: + return NULL; + } + op = type_to_extract_op(element_type); + ins = emit_simd_ins (cfg, vector_class, op, ins->dreg,-1); + ins->inst_c0 = index - 1; + return ins; +} +#endif #ifdef TARGET_ARM64 static int type_to_extract_op (MonoTypeEnum type); static MonoType* get_vector_t_elem_type (MonoType *vector_type); @@ -1473,7 +1561,7 @@ emit_vector_create_scalar ( if (COMPILE_LLVM (cfg)) { opcode = is_unsafe ? OP_CREATE_SCALAR_UNSAFE : OP_CREATE_SCALAR; } else { -#ifdef TARGET_AMD64 +#if defined(TARGET_AMD64) || defined(TARGET_S390X) MonoInst *ins; ins = emit_xzero (cfg, vklass); @@ -1819,12 +1907,12 @@ emit_dot (MonoCompile *cfg, MonoClass *klass, MonoType *vector_type, MonoTypeEnu #if defined(TARGET_WASM) if (!COMPILE_LLVM (cfg) && (arg0_type == MONO_TYPE_I8 || arg0_type == MONO_TYPE_U8)) return NULL; -#elif defined(TARGET_ARM64) +#elif defined(TARGET_ARM64) || defined(TARGET_S390X) if (!COMPILE_LLVM (cfg) && (arg0_type == MONO_TYPE_I8 || arg0_type == MONO_TYPE_U8 || arg0_type == MONO_TYPE_I || arg0_type == MONO_TYPE_U)) return NULL; #endif -#if defined(TARGET_ARM64) || defined(TARGET_WASM) +#if defined(TARGET_ARM64) || defined(TARGET_WASM) || defined(TARGET_S390X) MonoInst *pairwise_multiply = emit_simd_ins (cfg, klass, OP_XBINOP, sreg1, sreg2); pairwise_multiply->inst_c0 = type_enum_is_float (arg0_type) ? OP_FMUL : OP_IMUL; pairwise_multiply->inst_c1 = arg0_type; @@ -1939,7 +2027,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return NULL; // FIXME: This limitation could be removed once everything here are supported by mini JIT on arm64 -#ifdef TARGET_ARM64 +#if defined(TARGET_ARM64) || defined(TARGET_S390X) if (!COMPILE_LLVM (cfg)) { if (vector_size != 128) return NULL; @@ -2022,6 +2110,14 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } else { return emit_simd_ins_for_sig (cfg, klass, OP_VECTOR_IABS, -1, arg0_type, fsig, args); } +#elif defined(TARGET_S390X) + if (type_enum_is_float(arg0_type)) { + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; + return emit_simd_ins_for_sig (cfg, klass, arg0_type == MONO_TYPE_R8 ? OP_S390_VFLPDB : OP_S390_VFLPSB, -1, arg0_type, fsig, args); + } else { + return emit_simd_ins_for_sig (cfg, klass, OP_VECTOR_IABS, -1, arg0_type, fsig, args); + } #else return NULL; #endif @@ -2041,7 +2137,14 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi if (!is_element_type_primitive (fsig->params [0]) || !is_element_type_primitive (fsig->params [1])) return NULL; -#ifndef TARGET_ARM64 +#if defined(TARGET_S390X) + if (!mono_hwcap_s390x_has_ve1 && arg0_type == MONO_TYPE_R4) + return NULL; + if (!mono_hwcap_s390x_has_ve1 && ((id == SN_Max) || (id == SN_Min) || (id == SN_MaxNative) || (id == SN_MinNative)) && (arg0_type == MONO_TYPE_R8)) + return NULL; +#endif + +#if !defined(TARGET_ARM64) && !defined(TARGET_S390X) if (((id == SN_Max) || (id == SN_Min)) && type_enum_is_float(arg0_type)) return NULL; #endif @@ -2055,7 +2158,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi if (!is_element_type_primitive (fsig->params [0]) || !(MONO_TYPE_IS_VECTOR_PRIMITIVE (fsig->params [1]) || is_element_type_primitive (fsig->params [1]))) return NULL; - +#if defined(TARGET_S390X) + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; +#endif return emit_simd_ins_for_binary_op (cfg, klass, fsig, args, arg0_type, id); } case SN_Multiply: { @@ -2076,7 +2182,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return NULL; } else if (!(is_element_type_primitive (fsig->params [0]) && is_element_type_primitive (fsig->params [1]))) return NULL; - +#if defined(TARGET_S390X) + if (!mono_hwcap_s390x_has_ve1 && (vector_inner_type == MONO_TYPE_R4)) + return NULL; +#endif return emit_simd_ins_for_binary_op (cfg, klass, fsig, args, vector_inner_type, id); } case SN_AndNot: { @@ -2084,7 +2193,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return NULL; #ifdef TARGET_ARM64 return emit_simd_ins_for_sig (cfg, klass, OP_ARM64_BIC, -1, arg0_type, fsig, args); -#elif defined(TARGET_AMD64) || defined(TARGET_WASM) +#elif defined(TARGET_AMD64) || defined(TARGET_WASM) || defined(TARGET_S390X) /* Swap lhs and rhs because Vector128 needs lhs & !rhs whereas SSE2 does !lhs & rhs */ MonoInst *tmp = args[0]; @@ -2104,13 +2213,17 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi int add_op; if (type_enum_is_float (arg0_type)) { +#if defined(TARGET_S390X) + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; +#endif mul_op = OP_FMUL; add_op = OP_FADD; } else { mul_op = OP_IMUL; add_op = OP_IADD; -#ifdef TARGET_ARM64 +#if defined(TARGET_ARM64) || defined(TARGET_S390X) if (!COMPILE_LLVM (cfg) && (arg0_type == MONO_TYPE_I8 || arg0_type == MONO_TYPE_U8 || arg0_type == MONO_TYPE_I || arg0_type == MONO_TYPE_U)) return NULL; #endif @@ -2179,6 +2292,18 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi int ceil_or_floor = id == SN_Ceiling ? 10 : 9; return emit_simd_ins_for_sig (cfg, klass, OP_SSE41_ROUNDP, ceil_or_floor, arg0_type, fsig, args); +#elif defined(TARGET_S390X) + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; + int ceil_or_floor = id == SN_Ceiling ? 6 : 7; + switch (arg0_type){ + case MONO_TYPE_R4: + return emit_simd_ins_for_sig (cfg, klass, OP_S390_VFISB, ceil_or_floor, arg0_type, fsig, args); + case MONO_TYPE_R8: + return emit_simd_ins_for_sig (cfg, klass, OP_S390_VFIDB, ceil_or_floor, arg0_type, fsig, args); + default: + g_assert_not_reached (); + } #else return NULL; #endif @@ -2187,9 +2312,9 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi if (!is_element_type_primitive (fsig->params [0])) return NULL; -#if defined(TARGET_ARM64) || defined(TARGET_AMD64) || defined(TARGET_WASM) +#if defined(TARGET_ARM64) || defined(TARGET_AMD64) || defined(TARGET_WASM) || defined(TARGET_S390X) -#if defined(TARGET_AMD64) +#if defined(TARGET_AMD64) || defined(TARGET_S390X) if (!COMPILE_LLVM (cfg)) { MonoInst *val1 = emit_simd_ins (cfg, klass, OP_XBINOP_FORCEINT, args [0]->dreg, args [1]->dreg); val1->inst_c0 = XBINOP_FORCEINT_AND; @@ -2325,7 +2450,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi MonoClass *vklass = mono_class_from_mono_type_internal(fsig->ret); return emit_vector_create_broadcast (cfg, vklass, etype, args [0]); } else if (is_create_from_half_vectors_overload (fsig)) { -#if defined(TARGET_AMD64) +#if defined(TARGET_AMD64) || defined(TARGET_S390X) // Require Vector64 SIMD support if (!COMPILE_LLVM (cfg)) return NULL; @@ -2360,6 +2485,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return emit_vector_create_scalar (cfg, vklass, etype, args [0], is_unsafe); } case SN_Dot: { +#if defined(TARGET_S390X) + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; +#endif return emit_dot (cfg, klass, fsig->params [0], arg0_type, args [0]->dreg, args [1]->dreg); } case SN_Equals: @@ -2368,6 +2497,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi if (!is_element_type_primitive (fsig->params [0])) return NULL; MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); +#ifdef TARGET_S390X + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; +#endif if (id == SN_Equals) return emit_xcompare (cfg, klass, arg0_type, args [0], args [1]); @@ -2382,10 +2515,19 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi } } } else { +#ifndef TARGET_S390X MonoInst* cmp = emit_xcompare (cfg, arg_class, arg0_type, args [0], args [1]); MonoInst* ret = emit_simd_ins (cfg, mono_defaults.boolean_class, OP_XEXTRACT, cmp->dreg, -1); ret->inst_c0 = (id == SN_EqualsAll) ? SIMD_EXTR_ARE_ALL_SET : SIMD_EXTR_IS_ANY_SET; ret->inst_c1 = mono_class_value_size (klass, NULL); +#else + /* we need XCOMPARE(_FP), SIMD_EXTR_ARE_ALL/ANY_SET and CMP_* ops in the same ins to emit correct*/ + /* load on condition instructions */ + MonoInst* ret = emit_simd_ins (cfg, mono_defaults.boolean_class, OP_S390_XCOMPARE_XEXTRACT, args [0]->dreg, args [1]->dreg); + ret->inst_c0 = (id == SN_EqualsAll) ? SIMD_EXTR_ARE_ALL_SET : SIMD_EXTR_IS_ANY_SET; + ret->inst_c0 |= ((((gint64)CMP_EQ) << 4) & 0xf0); + ret->inst_c1 = arg0_type; +#endif return ret; } g_assert_not_reached (); @@ -2517,6 +2659,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return emit_simd_ins_for_sig (cfg, klass, OP_SSE_MOVMSK, -1, type, fsig, args); #endif + return NULL; } case SN_GetElement: { int elems; @@ -2606,7 +2749,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return NULL; int op = id == SN_GetLower ? OP_XLOWER : OP_XUPPER; -#ifdef TARGET_AMD64 +#if defined(TARGET_AMD64) || defined(TARGET_S390X) if (!COMPILE_LLVM (cfg)) /* These return a Vector64 */ return NULL; @@ -2619,7 +2762,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_LessThanOrEqual: { if (!is_element_type_primitive (fsig->params [0])) return NULL; - +#ifdef TARGET_S390X + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; +#endif return emit_xcompare_for_intrinsic (cfg, klass, id, arg0_type, args [0], args [1]); } case SN_GreaterThanAll: @@ -2636,7 +2782,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi g_assert (fsig->param_count == 2 && fsig->ret->type == MONO_TYPE_BOOLEAN && mono_metadata_type_equal (fsig->params [0], fsig->params [1])); - +#ifdef TARGET_S390X + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; +#endif gboolean is_all = FALSE; switch (id) { case SN_GreaterThanAll: @@ -2666,10 +2815,20 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return emit_not_xequal (cfg, arg_class, arg0_type, cmp, zero); } } else { +#ifndef TARGET_S390X MonoInst* cmp = emit_xcompare_for_intrinsic (cfg, arg_class, id, arg0_type, args [0], args [1]); MonoInst* ret = emit_simd_ins (cfg, mono_defaults.boolean_class, OP_XEXTRACT, cmp->dreg, -1); ret->inst_c0 = is_all ? SIMD_EXTR_ARE_ALL_SET : SIMD_EXTR_IS_ANY_SET; ret->inst_c1 = mono_class_value_size (klass, NULL); +#else + /* we need XCOMPARE(_FP), SIMD_EXTR_ARE_ALL/ANY_SET and CMP_* ops in the same ins to emit correct*/ + /* load on condition instructions */ + MonoInst* ret = emit_simd_ins (cfg, mono_defaults.boolean_class, OP_S390_XCOMPARE_XEXTRACT, args[0]->dreg, args[1]->dreg); + int temp = lower_xcompare_op(id, arg0_type); + ret->inst_c0 = is_all ? SIMD_EXTR_ARE_ALL_SET : SIMD_EXTR_IS_ANY_SET; + ret->inst_c0 |= ((temp << 4) & 0xf0); + ret->inst_c1 = arg0_type; +#endif return ret; } } @@ -2733,8 +2892,12 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return NULL; if (!type_enum_is_float(arg0_type)) return emit_xzero (cfg, klass); +#ifdef TARGET_S390X + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; +#endif int op = -1; -#if defined(TARGET_ARM64) || defined(TARGET_AMD64) || defined(TARGET_WASM) +#if defined(TARGET_ARM64) || defined(TARGET_AMD64) || defined(TARGET_WASM) || defined(TARGET_S390X) op = OP_ONES_COMPLEMENT; #endif if (op == -1) @@ -2755,7 +2918,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return emit_xones (cfg, klass); } } - +#ifdef TARGET_S390X + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; +#endif MonoInst *arg0 = args [0]; MonoClass *op_klass = klass; @@ -2783,6 +2949,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_IsPositiveInfinity: { if (!is_element_type_primitive (fsig->params [0])) return NULL; +#ifdef TARGET_S390X + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; +#endif if (arg0_type == MONO_TYPE_R4) { guint32 value[4]; @@ -2860,6 +3030,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_IsZero: { if (!is_element_type_primitive (fsig->params [0])) return NULL; +#ifdef TARGET_S390X + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; +#endif return emit_xcompare (cfg, klass, arg0_type, args [0], emit_xzero (cfg, klass)); } case SN_Narrow: { @@ -2983,6 +3157,19 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi return emit_simd_ins_for_sig (cfg, klass, OP_WASM_EXTRACT_NARROW, -1, -1, fsig, args); } + return NULL; +#elif defined(TARGET_S390X) + switch (arg0_type) { + case MONO_TYPE_I2: + case MONO_TYPE_U2: + return emit_simd_ins_for_sig (cfg, klass, OP_S390_VPKH, -1, -1, fsig, args); + case MONO_TYPE_I4: + case MONO_TYPE_U4: + return emit_simd_ins_for_sig (cfg, klass, OP_S390_VPKF, -1, -1, fsig, args); + case MONO_TYPE_I8: + case MONO_TYPE_U8: + return emit_simd_ins_for_sig (cfg, klass, OP_S390_VPKG, -1, -1, fsig, args); + } return NULL; #else return NULL; @@ -2992,6 +3179,10 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_OnesComplement: { if (!is_element_type_primitive (fsig->params [0])) return NULL; +#ifdef TARGET_S390X + if (!mono_hwcap_s390x_has_ve1 && (id == SN_Negate) && (arg0_type == MONO_TYPE_R4)) + return NULL; +#endif return emit_simd_ins_for_unary_op (cfg, klass, fsig, args, arg0_type, id); } case SN_Shuffle: { @@ -3140,7 +3331,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi case SN_Sum: { if (!is_element_type_primitive (fsig->params [0])) return NULL; -#if defined(TARGET_ARM64) || defined(TARGET_AMD64) || defined(TARGET_WASM) +#if defined(TARGET_ARM64) || defined(TARGET_AMD64) || defined(TARGET_WASM) || defined(TARGET_S390X) return emit_sum_vector (cfg, fsig->params [0], arg0_type, args [0]); #else return NULL; @@ -3157,6 +3348,12 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi int instc0 = arg0_type == MONO_TYPE_R4 ? INTRINS_SIMD_SQRT_R4 : INTRINS_SIMD_SQRT_R8; return emit_simd_ins_for_sig (cfg, klass, OP_XOP_X_X, instc0, arg0_type, fsig, args); +#elif defined(TARGET_S390X) + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; + + int instc0 = arg0_type == MONO_TYPE_R4 ? OP_S390_VFSQSB : OP_S390_VFSQDB; + return emit_simd_ins_for_sig (cfg, klass, instc0, 0, arg0_type, fsig, args); #else return NULL; #endif @@ -3240,7 +3437,7 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi MONO_EMIT_NEW_COND_EXC (cfg, GE_UN, "ArgumentOutOfRangeException"); gboolean use_xextract; -#ifdef TARGET_AMD64 +#if defined(TARGET_AMD64) || defined(TARGET_S390X) use_xextract = FALSE; #else use_xextract = type_to_width_log2 (arg0_type) == 3; @@ -3314,13 +3511,50 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi #elif defined(TARGET_AMD64) // FIXME: return NULL; +#elif defined(TARGET_S390X) + if (id == SN_WidenLower) { + switch (arg0_type){ + case MONO_TYPE_I1: + return emit_simd_ins (cfg, klass, OP_S390_VUPHB, args[0]->dreg, -1); + case MONO_TYPE_U1: + return emit_simd_ins (cfg, klass, OP_S390_VUPLHB, args[0]->dreg, -1); + case MONO_TYPE_I2: + return emit_simd_ins (cfg, klass, OP_S390_VUPHH, args[0]->dreg, -1); + case MONO_TYPE_U2: + return emit_simd_ins (cfg, klass, OP_S390_VUPLHH, args[0]->dreg, -1); + case MONO_TYPE_I4: + return emit_simd_ins (cfg, klass, OP_S390_VUPHF, args[0]->dreg, -1); + case MONO_TYPE_U4: + return emit_simd_ins (cfg, klass, OP_S390_VUPLHF, args[0]->dreg, -1); + default: + return NULL; + } + } + else { + switch (arg0_type){ + case MONO_TYPE_I1: + return emit_simd_ins (cfg, klass, OP_S390_VUPLB, args[0]->dreg, -1); + case MONO_TYPE_U1: + return emit_simd_ins (cfg, klass, OP_S390_VUPLLB, args[0]->dreg, -1); + case MONO_TYPE_I2: + return emit_simd_ins (cfg, klass, OP_S390_VUPLHW, args[0]->dreg, -1); + case MONO_TYPE_U2: + return emit_simd_ins (cfg, klass, OP_S390_VUPLLH, args[0]->dreg, -1); + case MONO_TYPE_I4: + return emit_simd_ins (cfg, klass, OP_S390_VUPLF, args[0]->dreg, -1); + case MONO_TYPE_U4: + return emit_simd_ins (cfg, klass, OP_S390_VUPLLF, args[0]->dreg, -1); + default: + return NULL; + } + } #else return NULL; #endif } case SN_WithLower: case SN_WithUpper: { -#ifdef TARGET_AMD64 +#if defined(TARGET_AMD64) || defined(TARGET_S390X) if (!COMPILE_LLVM (cfg)) /* These return a Vector64 */ return NULL; @@ -3468,7 +3702,7 @@ emit_sri_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f return NULL; #endif -#ifdef TARGET_AMD64 +#if defined(TARGET_AMD64) || defined(TARGET_S390X) if (!COMPILE_LLVM (cfg) && (size != 16)) return NULL; if (size != 16) @@ -3489,6 +3723,50 @@ emit_sri_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f g_assert (sizeof (buf) >= size); memset (buf, 0, sizeof (buf)); +#ifdef TARGET_S390X + /* we directly emit vrepi*/ + if (etype->type != MONO_TYPE_R4 && etype->type != MONO_TYPE_R8) { + switch (etype->type) { + case MONO_TYPE_I1: + case MONO_TYPE_U1: + return emit_simd_ins_for_sig (cfg, klass, OP_S390_VREPIB, etype->type, 1, fsig, args); + case MONO_TYPE_I2: + case MONO_TYPE_U2: + return emit_simd_ins_for_sig (cfg, klass, OP_S390_VREPIH, etype->type, 1, fsig, args); + case MONO_TYPE_I4: + case MONO_TYPE_U4: + return emit_simd_ins_for_sig (cfg, klass, OP_S390_VREPIF, etype->type, 1, fsig, args); + case MONO_TYPE_I: + case MONO_TYPE_U: + case MONO_TYPE_I8: + case MONO_TYPE_U8: + return emit_simd_ins_for_sig (cfg, klass, OP_S390_VREPIG, etype->type, 1, fsig, args); + default: + g_assert_not_reached (); + } + } + switch (etype->type){ + case MONO_TYPE_R4:{ + float *value = (float*)buf; + + for (int i = 0; i < len; ++i) { + value [i] = 1.0f; + } + + return emit_xconst_v128 (cfg, klass, (guint8*)value); + } + case MONO_TYPE_R8:{ + double *value = (double*)buf; + + for (int i = 0; i < len; ++i) { + value [i] = 1.0; + } + + return emit_xconst_v128 (cfg, klass, (guint8*)value); + } + } +#else + switch (etype->type) { case MONO_TYPE_I1: case MONO_TYPE_U1: { @@ -3559,6 +3837,7 @@ emit_sri_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f default: g_assert_not_reached (); } +#endif } case SN_op_Addition: case SN_op_BitwiseAnd: @@ -3570,6 +3849,10 @@ emit_sri_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f if (fsig->param_count != 2 ) return NULL; arg0_type = fsig->param_count > 0 ? get_underlying_type (fsig->params [0]) : MONO_TYPE_VOID; +#ifdef TARGET_S390X + if (!mono_hwcap_s390x_has_ve1 && arg0_type == MONO_TYPE_R4) + return NULL; +#endif return emit_simd_ins_for_binary_op (cfg, klass, fsig, args, arg0_type, id); } @@ -3578,6 +3861,10 @@ emit_sri_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f if (fsig->param_count != 2 ) return NULL; MonoClass *arg_class = mono_class_from_mono_type_internal (fsig->params [0]); +#ifdef TARGET_S390X + if (!mono_hwcap_s390x_has_ve1 && (arg0_type == MONO_TYPE_R4)) + return NULL; +#endif switch (id) { case SN_op_Equality: return emit_xequal (cfg, arg_class, arg0_type, args [0], args [1]); case SN_op_Inequality: return emit_not_xequal (cfg, arg_class, arg0_type, args [0], args [1]); @@ -3588,6 +3875,10 @@ emit_sri_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f case SN_op_UnaryNegation: if (fsig->param_count != 1 ) return NULL; +#if defined(TARGET_S390X) + if (!mono_hwcap_s390x_has_ve1 && (id == SN_op_UnaryNegation) && (arg0_type == MONO_TYPE_R4)) + return NULL; +#endif return emit_simd_ins_for_unary_op (cfg, klass, fsig, args, arg0_type, id); case SN_op_UnaryPlus: if (fsig->param_count != 1) @@ -3678,6 +3969,11 @@ emit_vector_2_3_4 (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f return NULL; #endif +#ifdef TARGET_S390X + if (!mono_hwcap_s390x_has_ve1) + return NULL; +#endif + if (!(cfg->opt & MONO_OPT_SIMD)) return NULL; @@ -3979,6 +4275,9 @@ emit_vector_2_3_4 (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f ins = emit_simd_ins (cfg, klass, OP_XOP_X_X, args [0]->dreg, -1); ins->inst_c0 = (IntrinsicId)INTRINS_SIMD_SQRT_R4; return ins; +#elif defined(TARGET_S390X) + ins = emit_simd_ins (cfg, klass, OP_S390_VFSQSB, args [0]->dreg, -1); + return ins; #else return NULL; #endif @@ -6643,6 +6942,11 @@ static MonoInst* emit_simd_intrinsics (const char *class_ns, const char *class_name, MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args) { MonoInst *ins; +#ifdef TARGET_S390X + /* vector facility was introduced in z13 */ + if (!mono_hwcap_s390x_has_vec) + return NULL; +#endif if (cfg->opt & MONO_OPT_SIMD) { ins = arch_emit_simd_intrinsics (class_ns, class_name, cfg, cmethod, fsig, args); @@ -6713,25 +7017,33 @@ mono_emit_common_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSi * for function arguments. When using SIMD intrinsics arguments optimized into OP_ARG needs to be decomposed * into correspondig SIMD LOADX/STOREX instructions. */ -#if defined(TARGET_WIN32) && defined(TARGET_AMD64) +#if (defined(TARGET_WIN32) && defined(TARGET_AMD64)) || defined(TARGET_S390X) static gboolean decompose_vtype_opt_uses_simd_intrinsics (MonoCompile *cfg, MonoInst *ins) { - if (cfg->uses_simd_intrinsics) - return TRUE; + switch (ins->opcode) { + case OP_XCALL: + case OP_XCALL_REG: + case OP_XCALL_MEMBASE: + return FALSE; + } + + if (cfg->uses_simd_intrinsics) + return TRUE; + + switch (ins->opcode) { + case OP_XMOVE: + case OP_XZERO: + case OP_XPHI: + case OP_LOADX_MEMBASE: + case OP_LOADX_ALIGNED_MEMBASE: + case OP_STOREX_MEMBASE: + case OP_STOREX_ALIGNED_MEMBASE_REG: + return TRUE; + default: + return FALSE; + } - switch (ins->opcode) { - case OP_XMOVE: - case OP_XZERO: - case OP_XPHI: - case OP_LOADX_MEMBASE: - case OP_LOADX_ALIGNED_MEMBASE: - case OP_STOREX_MEMBASE: - case OP_STOREX_ALIGNED_MEMBASE_REG: - return TRUE; - default: - return FALSE; - } } static void diff --git a/src/mono/mono/offsets/offsets-tool.py b/src/mono/mono/offsets/offsets-tool.py index c91f96f4cfd68f..05fe89fc6297b0 100644 --- a/src/mono/mono/offsets/offsets-tool.py +++ b/src/mono/mono/offsets/offsets-tool.py @@ -373,11 +373,7 @@ def gen (self): outfile = self.args.outfile validate_outfile = self.args.validate_outfile target = self.target - - if validate_outfile: - f = ComparableFile () - else: - f = open (outfile, 'w') + f = ComparableFile () f.write ("#ifndef USED_CROSS_COMPILER_OFFSETS\n") if target.arch_define: @@ -435,9 +431,18 @@ def gen (self): f.write ("#endif //USED_CROSS_COMPILER_OFFSETS check\n") f.close () - if validate_outfile and f.compare (outfile): - print ("Offsets file has changed.", file=sys.stderr) - f.dump (outfile + ".new") + if os.path.isfile (outfile): + if f.compare (outfile): + if validate_outfile: + print ("Offsets file has changed, writing new offsets to " + outfile + ".new", file=sys.stderr) + f.dump (outfile + ".new") + else: + print ("Offsets file has changed, updating " + outfile) + f.dump (outfile) + else: + print ("Offsets file is up to date, no changes to " + outfile) + else: + f.dump (outfile) tool = OffsetsTool () tool.parse_args () diff --git a/src/mono/mono/sgen/sgen-los.c b/src/mono/mono/sgen/sgen-los.c index e39eade5922f45..e72f5d42103a32 100644 --- a/src/mono/mono/sgen/sgen-los.c +++ b/src/mono/mono/sgen/sgen-los.c @@ -125,6 +125,12 @@ mword sgen_los_memory_usage = 0; /* Total memory used by the LOS allocator */ mword sgen_los_memory_usage_total = 0; +#ifdef HOST_WASM +const gboolean sgen_los_enable_sections_allocator = 0; +#else +const gboolean sgen_los_enable_sections_allocator = 1; +#endif + static LOSSection *los_sections = NULL; static LOSFreeChunks *los_fast_free_lists [LOS_NUM_FAST_SIZES]; /* 0 is for larger sizes */ static mword los_num_objects = 0; @@ -156,6 +162,9 @@ los_consistency_check (void) int i; mword memory_usage = 0; + if (!sgen_los_enable_sections_allocator) + return; + FOREACH_LOS_OBJECT_NO_LOCK (obj) { mword obj_size = sgen_los_object_size (obj); char *end = obj->data + obj_size; @@ -400,6 +409,11 @@ sgen_los_free_object (LOSObject *obj) sgen_free_os_memory ((gpointer)SGEN_ALIGN_DOWN_TO ((mword)obj, pagesize), size, SGEN_ALLOC_HEAP, MONO_MEM_ACCOUNT_SGEN_LOS); sgen_los_memory_usage_total -= size; sgen_memgov_release_space (size, SPACE_LOS); + } else if (!sgen_los_enable_sections_allocator) { + size += sizeof (LOSObject); + sgen_free_os_memory (obj, size, SGEN_ALLOC_HEAP, MONO_MEM_ACCOUNT_SGEN_LOS); + sgen_los_memory_usage_total -= size; + sgen_memgov_release_space (size, SPACE_LOS); } else { free_los_section_memory (obj, size + sizeof (LOSObject)); #ifdef LOS_CONSISTENCY_CHECKS @@ -461,6 +475,27 @@ sgen_los_alloc_large_inner (GCVTable vtable, size_t size) obj = randomize_los_object_start (obj, obj_size, alloc_size, pagesize); } } + } else if (!sgen_los_enable_sections_allocator) { + size_t alloc_size = size + sizeof (LOSObject); +#ifndef SGEN_HAVE_OVERLAPPING_CARDS + // While other objects can't be allocated after the los object (in a memory sharing a card with the los object), + // we could still have wbarrier roots allocated there, since they don't have alignment requirement. This means that + // clearing a card from this object would prevent scanning of refs in the wbarrier roots. + alloc_size = SGEN_ALIGN_UP_TO (alloc_size, CARD_SIZE_IN_BYTES); +#endif + if (sgen_memgov_try_alloc_space (alloc_size, SPACE_LOS)) { +#ifndef SGEN_HAVE_OVERLAPPING_CARDS + // If we don't use the shadow card table, having a card map to 2 different los objects is invalid + // because once we scan the first object we could clear the card, leading to failure to detect refs + // in the second object. We prevent this by aligning the los object to the card size. + int alignment = CARD_SIZE_IN_BYTES; +#else + int alignment = SGEN_ALLOC_ALIGN; +#endif + obj = (LOSObject *)sgen_alloc_os_memory_aligned (alloc_size, alignment, (SgenAllocFlags)(SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE), NULL, MONO_MEM_ACCOUNT_SGEN_LOS); + if (obj) + sgen_los_memory_usage_total += alloc_size; + } } else { obj = get_los_section_memory (size + sizeof (LOSObject)); if (obj) diff --git a/src/mono/mono/sgen/sgen-protocol.c b/src/mono/mono/sgen/sgen-protocol.c index 7c7543cd4292c8..7cfca07f14da8b 100644 --- a/src/mono/mono/sgen/sgen-protocol.c +++ b/src/mono/mono/sgen/sgen-protocol.c @@ -169,8 +169,7 @@ close_binary_protocol_file (void) #if defined(HOST_WIN32) CloseHandle (binary_protocol_file); #elif defined(HAVE_UNISTD_H) - while (close (binary_protocol_file) == -1 && errno == EINTR) - ; + close (binary_protocol_file); #endif binary_protocol_file = invalid_file_value; } diff --git a/src/mono/mono/utils/checked-build.c b/src/mono/mono/utils/checked-build.c index 20bc248f6ecf66..49abd9df9f4f50 100644 --- a/src/mono/mono/utils/checked-build.c +++ b/src/mono/mono/utils/checked-build.c @@ -501,7 +501,7 @@ check_mempool_owner_eq (MonoMemPoolOwner a, MonoMemPoolOwner b) return a.image == b.image && a.image_set == b.image_set; } -// Say image X "references" image Y if X either contains Y in its modules field, or X’s "references" field contains an +// Say image X "references" image Y if X either contains Y in its modules field, or X's "references" field contains an // assembly whose image is Y. // Say image X transitively references image Y if there is any chain of images-referencing-images which leads from X to Y. // Once the mempools for two pointers have been looked up, there are four possibilities: @@ -677,7 +677,7 @@ check_image_set_may_reference_image_set (MonoImageSet *from, MonoImageSet *to) return valid; // All items in "to" were found in "from" } -// Case 4. Image FROM points to ImageSet TO: FROM transitively references *ALL* of the “images” listed in TO +// Case 4. Image FROM points to ImageSet TO: FROM transitively references *ALL* of the "images" listed in TO static gboolean check_image_may_reference_image_set (MonoImage *from, MonoImageSet *to) { diff --git a/src/mono/mono/utils/mono-hwcap-s390x.c b/src/mono/mono/utils/mono-hwcap-s390x.c index ddc828bbc046a0..7f735066e238b8 100644 --- a/src/mono/mono/utils/mono-hwcap-s390x.c +++ b/src/mono/mono/utils/mono-hwcap-s390x.c @@ -157,6 +157,7 @@ mono_hwcap_arch_init (void) mono_hwcap_s390x_has_fpe = facs.fpe; mono_hwcap_s390x_has_vec = facs.vec; + mono_hwcap_s390x_has_ve1 = facs.ve1; mono_hwcap_s390x_has_mlt = facs.multi; mono_hwcap_s390x_has_ia = facs.ia; mono_hwcap_s390x_has_gie = facs.gie; diff --git a/src/mono/mono/utils/mono-hwcap-vars.h b/src/mono/mono/utils/mono-hwcap-vars.h index 98f4eb29115e83..391910a919c76e 100644 --- a/src/mono/mono/utils/mono-hwcap-vars.h +++ b/src/mono/mono/utils/mono-hwcap-vars.h @@ -54,6 +54,7 @@ MONO_HWCAP_VAR(riscv_has_stdext_v) #elif defined (TARGET_S390X) MONO_HWCAP_VAR(s390x_has_fpe) +MONO_HWCAP_VAR(s390x_has_ve1) MONO_HWCAP_VAR(s390x_has_vec) MONO_HWCAP_VAR(s390x_has_mlt) MONO_HWCAP_VAR(s390x_has_ia) diff --git a/src/mono/monoaotcross.proj b/src/mono/monoaotcross.proj index b31f88314f2ba0..0830b7c7892ec2 100644 --- a/src/mono/monoaotcross.proj +++ b/src/mono/monoaotcross.proj @@ -22,6 +22,15 @@ + + + <_SupportOS>android, browser, wasi + <_SupportOS Condition="$([MSBuild]::IsOSPlatform('OSX'))">$(_SupportOS), tvos, ios, maccatalyst + + + + + false + + linux-x86_64 + darwin-x86_64 + windows-x86_64 + $(ANDROID_NDK_ROOT)\toolchains\llvm\prebuilt\$(NdkToolchainPrebuiltOS)\bin\clang + Publish $(_ReadRuntimeComponentsManifestTargetName); @@ -35,6 +41,11 @@ _AndroidGenerateAppBundle; _AfterAndroidBuild + + $(AndroidBuildDependsOn); + CopyNativeBinary; + _CopyAotSymbols + <_CommonTargetsDir Condition="'$(_CommonTargetsDir)' == ''">$([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), '..', '..', 'common')) diff --git a/src/mono/msbuild/android/build/AndroidBuild.targets b/src/mono/msbuild/android/build/AndroidBuild.targets index 56dd94a5983986..be673d57eed15b 100644 --- a/src/mono/msbuild/android/build/AndroidBuild.targets +++ b/src/mono/msbuild/android/build/AndroidBuild.targets @@ -34,7 +34,7 @@ $([MSBuild]::NormalizeDirectory($(PublishDir))) - $([MSBuild]::NormalizeDirectory('$(OutDir)', 'Bundle')) + $([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle')) $(AndroidBundleDir) @@ -184,10 +184,10 @@ a list of direct pinvokes otherwise the runtime will crash --> - - - - + + + + @@ -202,8 +202,8 @@ AsOptions="$(_AsOptions)" Assemblies="@(_AotInputAssemblies)" CompilerBinaryPath="$(_CompilerBinaryPath)" - DirectPInvokes="@(DirectPInvokes)" - DirectPInvokeLists="@(DirectPInvokeLists)" + DirectPInvokes="@(DirectPInvoke)" + DirectPInvokeLists="@(DirectPInvokeList)" EnableUnmanagedCallersOnlyMethodsExport="$(_EnableUnmanagedCallersOnlyMethodsExport)" IntermediateOutputPath="$(_MobileIntermediateOutputPath)" LdName="$(_LdName)" @@ -239,6 +239,7 @@ We are using a private property to determine the target runtime, we should instead unify the resolution with Apple targets instead, (see: https://github.com/dotnet/runtime/issues/111923) --> <_RuntimeFlavor>Mono <_RuntimeFlavor Condition="'$(UseMonoRuntime)' == 'false' and '$(UseNativeAOTRuntime)' != 'true'">CoreCLR + <_RuntimeFlavor Condition="'$(UseNativeAOTRuntime)' == 'true'">nativeaot + diff --git a/src/mono/msbuild/apple/build/AppleBuild.targets b/src/mono/msbuild/apple/build/AppleBuild.targets index c686768b27621a..17dd0f47455fb9 100644 --- a/src/mono/msbuild/apple/build/AppleBuild.targets +++ b/src/mono/msbuild/apple/build/AppleBuild.targets @@ -84,6 +84,7 @@ <_CommonLinkerArgs Include="-lswiftCore" /> <_CommonLinkerArgs Include="-lswiftFoundation" /> <_CommonLinkerArgs Include="-framework Foundation" /> + <_CommonLinkerArgs Include="-framework Network" /> <_CommonLinkerArgs Include="-framework Security" /> <_CommonLinkerArgs Include="-framework CryptoKit" /> <_CommonLinkerArgs Include="-framework UIKit" /> @@ -321,6 +322,7 @@ EnableAppSandbox="$(EnableAppSandbox)" ExcludeFromAppDir="@(_ExcludeFromAppDir)" ExtraLinkerArguments="@(ExtraAppLinkerArgs)" + EnvironmentVariables="@(EnvironmentVariables)" ForceAOT="$(RunAOTCompilation)" ForceInterpreter="$(MonoForceInterpreter)" GenerateCMakeProject="$(GenerateCMakeProject)" diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.props b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.props index 81db8cce4adb79..df683130079f51 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.props +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.props @@ -37,6 +37,7 @@ Copyright (c) .NET Foundation. All rights reserved. $(StaticWebAssetsAdditionalPublishProperties);BuildProjectReferences=false;ResolveAssemblyReferencesFindRelatedSatellites=true $(StaticWebAssetsAdditionalPublishPropertiesToRemove);NoBuild;RuntimeIdentifier true + true diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets index b934bf4260d58c..b8c831e44c1516 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets @@ -12,7 +12,17 @@ Copyright (c) .NET Foundation. All rights reserved. - <_UseBlazorDevServer>$(RunArguments.Contains('blazor-devserver.dll').ToString().ToLower()) + <_UseBlazorDevServer>$(RunArguments.Contains('blazor-devserver.dll').ToString().ToLower()) + + <_TargetingNET80OrLater>false + <_TargetingNET90OrLater>false + <_TargetingNET100OrLater>false + <_TargetingNET80OrLater Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and $([MSBuild]::VersionGreaterThanOrEquals('$(TargetFrameworkVersion)', '8.0'))">true + <_TargetingNET90OrLater Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and $([MSBuild]::VersionGreaterThanOrEquals('$(TargetFrameworkVersion)', '9.0'))">true + <_TargetingNET100OrLater Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and $([MSBuild]::VersionGreaterThanOrEquals('$(TargetFrameworkVersion)', '10.0'))">true + + Baseline;AddMethodToExistingType;AddStaticFieldToExistingType;NewTypeDefinition;ChangeCustomAttributes + Baseline;AddMethodToExistingType;AddStaticFieldToExistingType;NewTypeDefinition;ChangeCustomAttributes;AddInstanceFieldToExistingType;GenericAddMethodToExistingType;GenericUpdateMethod;UpdateParameters;GenericAddFieldToExistingType $(DOTNET_HOST_PATH) @@ -24,7 +34,8 @@ Copyright (c) .NET Foundation. All rights reserved. <_RunWorkingDirectory Condition="'$(_RunWorkingDirectory)' != '' and !$([System.IO.Path]::IsPathRooted($(_RunWorkingDirectory)))">$([System.IO.Path]::Combine($(MSBuildProjectDirectory), $(_RunWorkingDirectory))) <_RuntimeConfigJsonPath>$([MSBuild]::NormalizePath($(_RunWorkingDirectory), '$(AssemblyName).runtimeconfig.json')) - exec "$([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost.dll'))" --use-staticwebassets --runtime-config "$(_RuntimeConfigJsonPath)" $(WasmHostArguments) + <_RunExtraArguments Condition="'$(WasmEnableThreads)' == 'true'">--apply-cop-headers + exec "$([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost.dll'))" --use-staticwebassets --runtime-config "$(_RuntimeConfigJsonPath)" $(_RunExtraArguments) $(WasmHostArguments) $(_RunWorkingDirectory) @@ -169,12 +180,6 @@ Copyright (c) .NET Foundation. All rights reserved. - <_TargetingNET80OrLater>false - <_TargetingNET90OrLater>false - <_TargetingNET80OrLater Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and $([MSBuild]::VersionGreaterThanOrEquals('$(TargetFrameworkVersion)', '8.0'))">true - <_TargetingNET90OrLater Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and $([MSBuild]::VersionGreaterThanOrEquals('$(TargetFrameworkVersion)', '9.0'))">true - <_TargetingNET100OrLater Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and $([MSBuild]::VersionGreaterThanOrEquals('$(TargetFrameworkVersion)', '10.0'))">true - <_BlazorCacheBootResources>$(BlazorCacheBootResources) <_BlazorCacheBootResources Condition="'$(_BlazorCacheBootResources)' == '' and '$(_TargetingNET100OrLater)' != 'true'">true <_BlazorCacheBootResources Condition="'$(_BlazorCacheBootResources)' == ''">false @@ -222,7 +227,7 @@ Copyright (c) .NET Foundation. All rights reserved. $(OutputPath)$(PublishDirName)\ - + diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.Wasi.targets.in b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.Wasi.targets.in index 609b21b7547815..b4391df7984962 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.Wasi.targets.in +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.Wasi.targets.in @@ -10,4 +10,8 @@ $(WasiNativeWorkloadAvailable) + + + + diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in index 303dfeb1d4b008..1bdbee059b653c 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in @@ -49,22 +49,21 @@ - - <_WasmPropertiesDifferFromRuntimePackThusNativeBuildNeeded Condition=" + + <_WasmNativeWorkloadNeeded Condition=" '$(WasmEnableSIMD)' == 'false' or '$(WasmEnableExceptionHandling)' == 'false' or '$(InvariantTimezone)' == 'true' or - ('$(_UsingBlazorOrWasmSdk)' != 'true' and '$(InvariantGlobalization)' == 'true') or - '$(WasmNativeStrip)' == 'false'">true - - - - <_WasmNativeWorkloadNeeded Condition=" - '$(_WasmPropertiesDifferFromRuntimePackThusNativeBuildNeeded)' == 'true' or + '$(WasmNativeStrip)' == 'false' or + '$(WasmNativeDebugSymbols)' == 'true' or + '$(WasmSingleFileBundle)' == 'false' or + '$(EnableDiagnostics)' == 'true' or + '$(WasmProfilers)' != '' or '$(RunAOTCompilation)' == 'true' or '$(WasmBuildNative)' == 'true' or '$(WasmGenerateAppBundle)' == 'true' or '$(_UsingBlazorOrWasmSdk)' != 'true' or + '$(EmccInitialHeapSize)' != '' or '$(EmccMaximumHeapSize)' != '' " >true false diff --git a/src/mono/sample/wasm/blazor-frame/blazor-frame.diff b/src/mono/sample/wasm/blazor-frame/blazor-frame.diff index a5318678e99abd..2f1980132c36ee 100644 --- a/src/mono/sample/wasm/blazor-frame/blazor-frame.diff +++ b/src/mono/sample/wasm/blazor-frame/blazor-frame.diff @@ -41,10 +41,10 @@ diff -urw blazor/Program.cs blazor/Program.cs diff -urw blazor/blazor.csproj blazor/blazor.csproj --- a/blazor/blazor.csproj 2024-01-22 16:01:30 +++ b/blazor/blazor.csproj 2024-01-23 12:04:59 -@@ -4,6 +4,8 @@ - net10.0 +@@ -8,6 +8,8 @@ enable enable + true + blazor-template/ + true @@ -59,9 +59,9 @@ diff -urw blazor/wwwroot/index.html blazor/wwwroot/index.html blazor - + + - @@ -23,10 +23,11 @@
@@ -70,8 +70,8 @@ diff -urw blazor/wwwroot/index.html blazor/wwwroot/index.html + Reload 🗙
-- -+ +- ++ + diff --git a/src/mono/sample/wasm/browser-bench/README.md b/src/mono/sample/wasm/browser-bench/README.md index f9e1fcf0a5f440..fa5e13fd332097 100644 --- a/src/mono/sample/wasm/browser-bench/README.md +++ b/src/mono/sample/wasm/browser-bench/README.md @@ -26,6 +26,18 @@ To run the benchmark with blazor startup measurements, set `BlazorStartup` prope > dotnet build /t:RunSample /p:BlazorStartup=true +### How to check that the startup patches are up to date + +To check that the startup measurements work, build the repo first like + + > ./build.sh -bl -os browser -c Release -subset mono+libs+packs + +in the repository root and then try to run the bench with startup measurements like + + > ./dotnet.sh build -c Release /t:RunSample /p:BlazorStartup=true /p:BrowserStartup=true src/mono/sample/wasm/browser-bench + +When the patches are out of date, the build will fail and the benchmark will not run. + ### Additional build arguments The benchmark project is built in a separate process, so to pass additional msbuild arguments, use `BuildAdditionalArgs` property, like: diff --git a/src/mono/sample/wasm/browser-frame/browser-frame.diff b/src/mono/sample/wasm/browser-frame/browser-frame.diff index a709abb5d609e2..7c5cdb55601019 100644 --- a/src/mono/sample/wasm/browser-frame/browser-frame.diff +++ b/src/mono/sample/wasm/browser-frame/browser-frame.diff @@ -14,9 +14,9 @@ diff -ru browser-frame/wwwroot/index.html browser-frame/wwwroot/index.html --- a/browser-frame/wwwroot/index.html 2024-03-07 09:00:37 +++ b/browser-frame/wwwroot/index.html 2024-03-05 15:38:42 @@ -8,6 +8,7 @@ - - - + + + + diff --git a/src/mono/wasi/README.md b/src/mono/wasi/README.md index d1eee899863167..1c2f8a2dc01b71 100644 --- a/src/mono/wasi/README.md +++ b/src/mono/wasi/README.md @@ -42,6 +42,35 @@ you will need to separately download a WASI SDK from https://github.com/WebAssem - `InvariantGlobalization` - remove globalization support, decrease the publish size. - More details can be found at https://github.com/dotnet/runtime/blob/main/src/mono/wasm/build/WasmApp.Common.targets and https://github.com/dotnet/runtime/blob/main/src/mono/wasi/build/WasiApp.targets +## Properties That Trigger Relinking + +### What is Relinking? + +Relinking in WASI builds refers to regenerating the native WASI runtime artifacts (such as `dotnet.native.wasi`, etc.) to reflect changes in configuration, features, or source. This process is essential for producing correct, optimized binaries for WASI environments. + +### Properties That Trigger Relinking in `wasi.proj` + +The following MSBuild properties will trigger a relinking during the WASI build process: + +- **`WasiBuildNative`** - `/p:WasiBuildNative=true` - Forces a rebuild of all native WASI binaries, regardless of detected changes. +- **`WasiRelinkNative`** - `/p:WasiRelinkNative=true` - Explicitly requests relinking of native WASI artifacts. +- **`RunAOTCompilation`** - `/p:RunAOTCompilation=true` - Enables AOT compilation for WASI. Changing this property requires relinking for correct WASI output. +- **`WasmSingleFileBundle`** - `/p:WasmSingleFileBundle=true` - Bundles all assets into the `.wasm` file, requiring native relinking. +- **`EnableDiagnostics`** - `/p:EnableDiagnostics=true` - Enables or disables diagnostic features in the native runtime. +- **`WasmProfilers`** - `/p:WasmProfilers=...` - Changes profiler configuration in the native runtime. +- **`WasmEnableSIMD`** - `/p:WasmEnableSIMD=true` - Enables or disables SIMD instruction support. +- **`WasiBuildArgs`** - Any change to `/p:WasiBuildArgs=...` (custom build flags or feature toggles) can trigger a relink. +- **Configuration/Target Architecture** - Changing `/p:Configuration=Debug|Release` or `/p:RuntimeIdentifier=wasi-wasm`, etc., may require relinking. + +#### Notes + +- Correct relinking ensures WASI binaries are up-to-date and accurately reflect the intended configuration. +- Avoid unnecessary relinking for faster incremental builds. +- The relink logic is defined in `wasi.proj` and supporting MSBuild files. +- Source changes to native sources in `src/mono/wasi` or related directories will always trigger a relink. + +For more detailed WASI build and configuration guidance, see the [WASI build documentation](../../../docs/workflow/building/libraries/webassembly-instructions.md). + ## How it works The mechanism for executing .NET code in a WASI runtime environment is equivalent to how `dotnet.wasm` executes .NET code in a browser environment. That is, it runs the Mono interpreter to execute .NET bytecode that has been built in the normal way. It should also work with AOT but this is not yet attempted. diff --git a/src/mono/wasi/wasi.proj b/src/mono/wasi/wasi.proj index 35c4275e184173..219737950f9ad1 100644 --- a/src/mono/wasi/wasi.proj +++ b/src/mono/wasi/wasi.proj @@ -165,7 +165,8 @@ { "identity": "WasmSingleFileBundle", "defaultValueInRuntimePack": "$(WasmSingleFileBundle)" }, { "identity": "EnableDiagnostics", "defaultValueInRuntimePack": "$(EnableDiagnostics)" }, { "identity": "WasmProfilers", "defaultValueInRuntimePack": "$(WasmProfilers)" }, - { "identity": "WasmEnableSIMD", "defaultValueInRuntimePack": "$(WasmEnableSIMD)" } + { "identity": "WasmEnableSIMD", "defaultValueInRuntimePack": "$(WasmEnableSIMD)" }, + { "identity": "RunAOTCompilation", "defaultValueInRuntimePack": "$(RunAOTCompilation)" } ] } } diff --git a/src/mono/wasm/Wasm.Build.Tests/AspNetCore/SignalRClientTests.cs b/src/mono/wasm/Wasm.Build.Tests/AspNetCore/SignalRClientTests.cs deleted file mode 100644 index 30f3073de9af20..00000000000000 --- a/src/mono/wasm/Wasm.Build.Tests/AspNetCore/SignalRClientTests.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit; - -#nullable enable - -namespace Wasm.Build.Tests.AspNetCore; - -public class SignalRClientTests : SignalRTestsBase -{ - public SignalRClientTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) - : base(output, buildContext) - { - } - - [ActiveIssue("https://github.com/dotnet/runtime/issues/106807")] - [ConditionalTheory(typeof(BuildTestBase), nameof(IsWorkloadWithMultiThreadingForDefaultFramework))] - [InlineData(Configuration.Debug, "LongPolling")] - [InlineData(Configuration.Release, "LongPolling")] - [InlineData(Configuration.Debug, "WebSockets")] - [InlineData(Configuration.Release, "WebSockets")] - public async Task SignalRPassMessageWasmBrowser(Configuration config, string transport) => - await SignalRPassMessage("wasmclient", config, transport); -} diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/MiscTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/MiscTests.cs index b8eaf4afcb4b0e..8b851af3586cdf 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/MiscTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/MiscTests.cs @@ -66,14 +66,14 @@ public void DefaultTemplate_AOT_InProjectFile(Configuration config) : "true"; ProjectInfo info = CopyTestAsset(config, aot: true, TestAsset.BlazorBasicTestApp, "blz_aot_prj_file", extraProperties: extraProperties); - // No relinking, no AOT - BlazorBuild(info, config); + // build relinks + BlazorBuild(info, config, isNativeBuild: true); // will aot BlazorPublish(info, config, new PublishOptions(UseCache: false, AOT: true)); // build again - BlazorBuild(info, config, new BuildOptions(UseCache: false)); + BlazorBuild(info, config, new BuildOptions(UseCache: false), isNativeBuild: true); } [Fact] diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/SignalRClientTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/SignalRClientTests.cs deleted file mode 100644 index f48472f9b96467..00000000000000 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/SignalRClientTests.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit; - -#nullable enable - -namespace Wasm.Build.Tests.Blazor; - -public class SignalRClientTests : SignalRTestsBase -{ - public SignalRClientTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) - : base(output, buildContext) - { - } - - [ConditionalTheory(typeof(BuildTestBase), nameof(IsWorkloadWithMultiThreadingForDefaultFramework))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/100445")] // to be fixed by: "https://github.com/dotnet/aspnetcore/issues/54365" - [InlineData(Configuration.Debug, "LongPolling")] - [InlineData(Configuration.Release, "LongPolling")] - [InlineData(Configuration.Debug, "WebSockets")] - [InlineData(Configuration.Release, "WebSockets")] - public async Task SignalRPassMessageBlazor(Configuration config, string transport) => - await SignalRPassMessage("blazorclient", config, transport); -} - diff --git a/src/mono/wasm/Wasm.Build.Tests/BuildPublishTests.cs b/src/mono/wasm/Wasm.Build.Tests/BuildPublishTests.cs index 375b77d3501701..41d7fdb6388fec 100644 --- a/src/mono/wasm/Wasm.Build.Tests/BuildPublishTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/BuildPublishTests.cs @@ -55,7 +55,7 @@ public async Task BuildThenPublishWithAOT(Configuration config, bool aot) ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "build_publish"); bool isPublish = false; - (_, string output) = BuildProject(info, config, new BuildOptions(Label: "first_build", AOT: aot)); + (_, string output) = BuildProject(info, config, new BuildOptions(Label: "first_build", AOT: aot), isNativeBuild: aot); BuildPaths paths = GetBuildPaths(config, forPublish: isPublish); IDictionary pathsDict = @@ -63,10 +63,10 @@ public async Task BuildThenPublishWithAOT(Configuration config, bool aot) string mainDll = $"{info.ProjectName}.dll"; var firstBuildStat = StatFiles(pathsDict); - Assert.False(firstBuildStat["pinvoke.o"].Exists); + Assert.True(firstBuildStat["pinvoke.o"].Exists); Assert.False(firstBuildStat[$"{mainDll}.bc"].Exists); - - CheckOutputForNativeBuild(expectAOT: false, expectRelinking: isPublish, info.ProjectName, output); + + CheckOutputForNativeBuild(expectAOT: false, expectRelinking: isPublish || aot, info.ProjectName, output); if (!_buildContext.TryGetBuildFor(info, out BuildResult? result)) throw new XunitException($"Test bug: could not get the build result in the cache"); @@ -88,7 +88,7 @@ public async Task BuildThenPublishWithAOT(Configuration config, bool aot) IDictionary publishStat = StatFiles(pathsDict); Assert.True(publishStat["pinvoke.o"].Exists); Assert.True(publishStat[$"{mainDll}.bc"].Exists); - CheckOutputForNativeBuild(expectAOT: true, expectRelinking: isPublish, info.ProjectName, output); + CheckOutputForNativeBuild(expectAOT: true, expectRelinking: isPublish || aot, info.ProjectName, output); // source maps are created for build but not for publish, make sure CompareStat won't expect them in publish: pathsDict["dotnet.js.map"] = (pathsDict["dotnet.js.map"].fullPath, unchanged: false); @@ -98,11 +98,11 @@ public async Task BuildThenPublishWithAOT(Configuration config, bool aot) // second build isPublish = false; - (_, output) = BuildProject(info, config, new BuildOptions(Label: "second_build", UseCache: false, AOT: aot)); + (_, output) = BuildProject(info, config, new BuildOptions(Label: "second_build", UseCache: false, AOT: aot), isNativeBuild: aot); var secondBuildStat = StatFiles(pathsDict); // no relinking, or AOT - CheckOutputForNativeBuild(expectAOT: false, expectRelinking: isPublish, info.ProjectName, output); + CheckOutputForNativeBuild(expectAOT: false, expectRelinking: isPublish || aot, info.ProjectName, output); // no native files changed pathsDict.UpdateTo(unchanged: true); diff --git a/src/mono/wasm/Wasm.Build.Tests/DllImportTests.cs b/src/mono/wasm/Wasm.Build.Tests/DllImportTests.cs index 8f5dfcf0d9b7e3..dac78c679157ce 100644 --- a/src/mono/wasm/Wasm.Build.Tests/DllImportTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/DllImportTests.cs @@ -23,7 +23,7 @@ public DllImportTests(ITestOutputHelper output, SharedBuildPerTestClassFixture b [Theory] [BuildAndRun(aot: false)] - public async void NativeLibraryWithVariadicFunctions(Configuration config, bool aot) + public async Task NativeLibraryWithVariadicFunctions(Configuration config, bool aot) { ProjectInfo info = PrepareProjectForVariadicFunction(config, aot, "variadic"); ReplaceFile(Path.Combine("Common", "Program.cs"), Path.Combine(BuildEnvironment.TestAssetsPath, "EntryPoints", "PInvoke", "VariadicFunctions.cs")); @@ -43,7 +43,7 @@ public async void NativeLibraryWithVariadicFunctions(Configuration config, bool [Theory] [BuildAndRun()] - public async void DllImportWithFunctionPointersCompilesWithoutWarning(Configuration config, bool aot) + public async Task DllImportWithFunctionPointersCompilesWithoutWarning(Configuration config, bool aot) { ProjectInfo info = PrepareProjectForVariadicFunction(config, aot, "fnptr"); ReplaceFile(Path.Combine("Common", "Program.cs"), Path.Combine(BuildEnvironment.TestAssetsPath, "EntryPoints", "PInvoke", "DllImportNoWarning.cs")); @@ -62,7 +62,7 @@ public async void DllImportWithFunctionPointersCompilesWithoutWarning(Configurat [Theory] [BuildAndRun()] - public async void DllImportWithFunctionPointers_ForVariadicFunction_CompilesWithWarning(Configuration config, bool aot) + public async Task DllImportWithFunctionPointers_ForVariadicFunction_CompilesWithWarning(Configuration config, bool aot) { ProjectInfo info = PrepareProjectForVariadicFunction(config, aot, "fnptr_variadic"); ReplaceFile(Path.Combine("Common", "Program.cs"), Path.Combine(BuildEnvironment.TestAssetsPath, "EntryPoints", "PInvoke", "DllImportWarning.cs")); @@ -81,7 +81,7 @@ public async void DllImportWithFunctionPointers_ForVariadicFunction_CompilesWith [Theory] [BuildAndRun()] - public async void DllImportWithFunctionPointers_WarningsAsMessages(Configuration config, bool aot) + public async Task DllImportWithFunctionPointers_WarningsAsMessages(Configuration config, bool aot) { string extraProperties = "$(MSBuildWarningsAsMessage);WASM0001"; ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "fnptr", extraProperties: extraProperties); @@ -117,7 +117,7 @@ public void UnmanagedCallback_WithFunctionPointers_CompilesWithWarnings(Configur "with.per.iod", "with🚀unicode#" } })] - public async void CallIntoLibrariesWithNonAlphanumericCharactersInTheirNames(Configuration config, bool aot, string[] libraryNames) + public async Task CallIntoLibrariesWithNonAlphanumericCharactersInTheirNames(Configuration config, bool aot, string[] libraryNames) { var extraItems = @""; string extraProperties = aot ? string.Empty : "true"; diff --git a/src/mono/wasm/Wasm.Build.Tests/MemoryTests.cs b/src/mono/wasm/Wasm.Build.Tests/MemoryTests.cs index 1b0697d7704483..50283071f30bde 100644 --- a/src/mono/wasm/Wasm.Build.Tests/MemoryTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/MemoryTests.cs @@ -20,7 +20,6 @@ public MemoryTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buil { } - // ActiveIssue: https://github.com/dotnet/runtime/issues/104618 [Fact, TestCategory("no-workload")] public async Task AllocateLargeHeapThenRepeatedlyInterop_NoWorkload() => await AllocateLargeHeapThenRepeatedlyInterop(); diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/FlagsChangeRebuildTest.cs b/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/FlagsChangeRebuildTest.cs index 76c55cf22287d2..2b1403b78e54d7 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/FlagsChangeRebuildTest.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/FlagsChangeRebuildTest.cs @@ -4,6 +4,7 @@ using System.IO; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Wasm.Build.Tests; using Xunit; using Xunit.Abstractions; @@ -29,7 +30,7 @@ public FlagsChangeRebuildTests(ITestOutputHelper output, SharedBuildPerTestClass [Theory] [MemberData(nameof(FlagsChangesForNativeRelinkingData), parameters: /*aot*/ false)] [MemberData(nameof(FlagsChangesForNativeRelinkingData), parameters: /*aot*/ true)] - public async void ExtraEmccFlagsSetButNoRealChange(Configuration config, bool aot, string extraCFlags, string extraLDFlags) + public async Task ExtraEmccFlagsSetButNoRealChange(Configuration config, bool aot, string extraCFlags, string extraLDFlags) { ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "rebuild_flags"); BuildPaths paths = await FirstNativeBuildAndRun(info, config, aot, requestNativeRelink: true, invariant: false); diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/NoopNativeRebuildTest.cs b/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/NoopNativeRebuildTest.cs index dada93b41b0701..00c6c25ecf6ed0 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/NoopNativeRebuildTest.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/NoopNativeRebuildTest.cs @@ -3,6 +3,7 @@ using System.Linq; using Wasm.Build.Tests; +using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; @@ -19,7 +20,7 @@ public NoopNativeRebuildTest(ITestOutputHelper output, SharedBuildPerTestClassFi [Theory] [MemberData(nameof(NativeBuildData))] - public async void NoOpRebuildForNativeBuilds(Configuration config, bool aot, bool nativeRelink, bool invariant) + public async Task NoOpRebuildForNativeBuilds(Configuration config, bool aot, bool nativeRelink, bool invariant) { ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "rebuild_noop"); BuildPaths paths = await FirstNativeBuildAndRun(info, config, aot, nativeRelink, invariant); diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/OptimizationFlagChangeTests.cs b/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/OptimizationFlagChangeTests.cs index 1a06d0f6309c12..0bc203214df016 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/OptimizationFlagChangeTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/OptimizationFlagChangeTests.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using Wasm.Build.Tests; using Xunit; using Xunit.Abstractions; @@ -29,7 +30,7 @@ public OptimizationFlagChangeTests(ITestOutputHelper output, SharedBuildPerTestC [Theory] [MemberData(nameof(FlagsOnlyChangeData), parameters: /*aot*/ false)] [MemberData(nameof(FlagsOnlyChangeData), parameters: /*aot*/ true)] - public async void OptimizationFlagChange(Configuration config, bool aot, string cflags, string ldflags) + public async Task OptimizationFlagChange(Configuration config, bool aot, string cflags, string ldflags) { ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "rebuild_flags"); // force _WasmDevel=false, so we don't get -O0 but -O2 diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/ReferenceNewAssemblyRebuildTest.cs b/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/ReferenceNewAssemblyRebuildTest.cs index 7f39761591054c..bc9d6a4cb5a59d 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/ReferenceNewAssemblyRebuildTest.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/ReferenceNewAssemblyRebuildTest.cs @@ -4,6 +4,7 @@ using System; using System.IO; using System.Linq; +using System.Threading.Tasks; using Wasm.Build.Tests; using Xunit; using Xunit.Abstractions; @@ -21,7 +22,7 @@ public ReferenceNewAssemblyRebuildTest(ITestOutputHelper output, SharedBuildPerT [Theory] [MemberData(nameof(NativeBuildData))] - public async void ReferenceNewAssembly(Configuration config, bool aot, bool nativeRelink, bool invariant) + public async Task ReferenceNewAssembly(Configuration config, bool aot, bool nativeRelink, bool invariant) { ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "rebuild_tasks"); BuildPaths paths = await FirstNativeBuildAndRun(info, config, aot, nativeRelink, invariant); diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/SimpleSourceChangeRebuildTest.cs b/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/SimpleSourceChangeRebuildTest.cs index e7207e26600664..342fb537cf3ba6 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/SimpleSourceChangeRebuildTest.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeRebuildTests/SimpleSourceChangeRebuildTest.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; +using System.Threading.Tasks; using Wasm.Build.Tests; using Xunit; using Xunit.Abstractions; @@ -20,7 +21,7 @@ public SimpleSourceChangeRebuildTest(ITestOutputHelper output, SharedBuildPerTes [Theory] [MemberData(nameof(NativeBuildData))] - public async void SimpleStringChangeInSource(Configuration config, bool aot, bool nativeRelink, bool invariant) + public async Task SimpleStringChangeInSource(Configuration config, bool aot, bool nativeRelink, bool invariant) { ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "rebuild_simple"); BuildPaths paths = await FirstNativeBuildAndRun(info, config, aot, nativeRelink, invariant); diff --git a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs index bd1b23f3a88764..83824e78b04a6b 100644 --- a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs @@ -45,7 +45,7 @@ public void UnmanagedStructAndMethodIn_SameAssembly_WithoutDisableRuntimeMarshal [Theory] [BuildAndRun()] - public async void UnmanagedStructAndMethodIn_SameAssembly_WithDisableRuntimeMarshallingAttribute_ConsideredBlittable + public async Task UnmanagedStructAndMethodIn_SameAssembly_WithDisableRuntimeMarshallingAttribute_ConsideredBlittable (Configuration config, bool aot) { ProjectInfo info = PrepreProjectForBlittableTests( @@ -93,7 +93,7 @@ private ProjectInfo PrepreProjectForBlittableTests(Configuration config, bool ao [Theory] [MemberData(nameof(SeparateAssemblyWithDisableMarshallingAttributeTestData), parameters: Configuration.Debug)] [MemberData(nameof(SeparateAssemblyWithDisableMarshallingAttributeTestData), parameters: Configuration.Release)] - public async void UnmanagedStructsAreConsideredBlittableFromDifferentAssembly + public async Task UnmanagedStructsAreConsideredBlittableFromDifferentAssembly (Configuration config, bool aot, bool libraryHasAttribute, bool appHasAttribute, bool expectSuccess) { string extraProperties = aot ? string.Empty : "true"; @@ -132,7 +132,7 @@ public async void UnmanagedStructsAreConsideredBlittableFromDifferentAssembly [Theory] [BuildAndRun()] - public async void UnmanagedCallback_InFileType(Configuration config, bool aot) + public async Task UnmanagedCallback_InFileType(Configuration config, bool aot) { ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "cb_filetype"); string programRelativePath = Path.Combine("Common", "Program.cs"); @@ -151,7 +151,7 @@ public async void UnmanagedCallback_InFileType(Configuration config, bool aot) [Theory] [BuildAndRun()] - public async void UnmanagedCallersOnly_Namespaced(Configuration config, bool aot) + public async Task UnmanagedCallersOnly_Namespaced(Configuration config, bool aot) { ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "cb_namespace"); string programRelativePath = Path.Combine("Common", "Program.cs"); @@ -276,7 +276,7 @@ public void IcallWithOverloadedParametersAndEnum(Configuration config, bool aot) [Theory] [BuildAndRun(parameters: new object[] { "tr_TR.UTF-8" })] - public async void BuildNativeInNonEnglishCulture(Configuration config, bool aot, string culture) + public async Task BuildNativeInNonEnglishCulture(Configuration config, bool aot, string culture) { // Check that we can generate interp tables in non-english cultures // Prompted by https://github.com/dotnet/runtime/issues/71149 @@ -351,12 +351,12 @@ private async Task EnsureWasmAbiRulesAreFollowed(Configuration config, bool aot) [Theory] [BuildAndRun(aot: true, config: Configuration.Release)] - public async void EnsureWasmAbiRulesAreFollowedInAOT(Configuration config, bool aot) => + public async Task EnsureWasmAbiRulesAreFollowedInAOT(Configuration config, bool aot) => await EnsureWasmAbiRulesAreFollowed(config, aot); [Theory] [BuildAndRun(aot: false)] - public async void EnsureWasmAbiRulesAreFollowedInInterpreter(Configuration config, bool aot) => + public async Task EnsureWasmAbiRulesAreFollowedInInterpreter(Configuration config, bool aot) => await EnsureWasmAbiRulesAreFollowed(config, aot); [Theory] @@ -373,7 +373,7 @@ public void EnsureComInteropCompilesInAOT(Configuration config, bool aot) [Theory] [BuildAndRun(aot: false)] - public async void UCOWithSpecialCharacters(Configuration config, bool aot) + public async Task UCOWithSpecialCharacters(Configuration config, bool aot) { var extraProperties = "true"; var extraItems = @""; diff --git a/src/mono/wasm/Wasm.Build.Tests/SatelliteAssembliesTests.cs b/src/mono/wasm/Wasm.Build.Tests/SatelliteAssembliesTests.cs index c74a21b82d86bc..140e63c326433d 100644 --- a/src/mono/wasm/Wasm.Build.Tests/SatelliteAssembliesTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/SatelliteAssembliesTests.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; @@ -32,7 +33,7 @@ public SatelliteAssembliesTests(ITestOutputHelper output, SharedBuildPerTestClas [MemberData(nameof(SatelliteAssemblyTestData), parameters: new object[] { /*aot*/ false, /*relinking*/ false })] [MemberData(nameof(SatelliteAssemblyTestData), parameters: new object[] { /*aot*/ false, /*relinking*/ true })] [MemberData(nameof(SatelliteAssemblyTestData), parameters: new object[] { /*aot*/ true, /*relinking*/ false })] - public async void ResourcesFromMainAssembly(Configuration config, bool aot, bool nativeRelink, string? argCulture) + public async Task ResourcesFromMainAssembly(Configuration config, bool aot, bool nativeRelink, string? argCulture) { string prefix = $"sat_asm_from_main_asm"; string extraProperties = (nativeRelink ? $"true" : string.Empty) @@ -57,8 +58,8 @@ public async void ResourcesFromMainAssembly(Configuration config, bool aot, bool [Theory] [MemberData(nameof(SatelliteAssemblyTestData), parameters: new object[] { /*aot*/ false, /*relinking*/ false })] [MemberData(nameof(SatelliteAssemblyTestData), parameters: new object[] { /*aot*/ false, /*relinking*/ true })] - [MemberData(nameof(SatelliteAssemblyTestData), parameters: new object[] { /*aot*/ true, /*relinking*/ false })] - public async void ResourcesFromProjectReference(Configuration config, bool aot, bool nativeRelink, string? argCulture) + [MemberData(nameof(SatelliteAssemblyTestData), parameters: new object[] { /*aot*/ true, /*relinking*/ true })] + public async Task ResourcesFromProjectReference(Configuration config, bool aot, bool nativeRelink, string? argCulture) { string prefix = $"SatelliteAssemblyFromProjectRef"; string extraProperties = $"{(nativeRelink ? "true" : "false")}" @@ -110,7 +111,7 @@ public void CheckThatSatelliteAssembliesAreNotAOTed(Configuration config, bool a // sanity check, in case we change file extensions Assert.Contains($"{info.ProjectName}.dll.bc", bitCodeFileNames); - Assert.Empty(bitCodeFileNames.Where(file => file.EndsWith(".resources.dll.bc"))); + Assert.DoesNotContain(bitCodeFileNames, file => file.EndsWith(".resources.dll.bc")); } #pragma warning restore xUnit1026 diff --git a/src/mono/wasm/Wasm.Build.Tests/SignalRTestsBase.cs b/src/mono/wasm/Wasm.Build.Tests/SignalRTestsBase.cs deleted file mode 100644 index 5987db9992f1bc..00000000000000 --- a/src/mono/wasm/Wasm.Build.Tests/SignalRTestsBase.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Collections.Generic; -using System.Collections.Specialized; -using Wasm.Build.Tests; -using Xunit.Abstractions; -using Xunit; -#nullable enable - -namespace Wasm.Build.Tests; - -public class SignalRTestsBase : WasmTemplateTestsBase -{ - public SignalRTestsBase(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) - : base(output, buildContext) - { - } - - protected async Task SignalRPassMessage(string staticWebAssetBasePath, Configuration config, string transport) - { - TestAsset asset = new() { Name = "WasmBasicTestApp", RunnableProjectSubPath = "AspNetCoreServer" }; - ProjectInfo info = CopyTestAsset(config, false, asset, "SignalRClientTests"); - PublishProject(info, config, new PublishOptions(RuntimeType: RuntimeVariant.MultiThreaded, AssertAppBundle: false)); - - var result = await RunForPublishWithWebServer(new BrowserRunOptions( - Configuration: config, - ServerEnvironment: new Dictionary { ["ASPNETCORE_ENVIRONMENT"] = "Development" }, - BrowserPath: staticWebAssetBasePath, - BrowserQueryString: new NameValueCollection { - { "transport", transport}, - { "message", "ping" } - })); - - string testOutput = string.Join("\n", result.TestOutput) ?? ""; - Assert.NotEmpty(testOutput); - // check sending and receiving threadId - string threadIdUsedForSending = GetThreadOfAction(testOutput, @"SignalRPassMessages was sent by CurrentManagedThreadId=(\d+)", "signalR message was sent"); - string threadIdUsedForReceiving = GetThreadOfAction(testOutput, @"ReceiveMessage from server on CurrentManagedThreadId=(\d+)", "signalR message was received"); - string consoleOutput = string.Join("\n", result.ConsoleOutput); - Assert.True("1" != threadIdUsedForSending || "1" != threadIdUsedForReceiving, - $"Expected to send/receive with signalR in non-UI threads, instead only CurrentManagedThreadId=1 was used. ConsoleOutput: {consoleOutput}."); - } - - private string GetThreadOfAction(string testOutput, string pattern, string actionDescription) - { - Match match = Regex.Match(testOutput, pattern); - Assert.True(match.Success, $"Expected to find a log that {actionDescription}. TestOutput: {testOutput}."); - return match.Groups[1].Value ?? ""; - } -} diff --git a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs index 679d645130f3b1..65f0f39b92a567 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs @@ -72,7 +72,6 @@ void AddTestData(bool runOutsideProjectDirectory) [Theory, TestCategory("no-fingerprinting")] [MemberData(nameof(TestDataForAppBundleDir))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/108107")] public async Task RunWithDifferentAppBundleLocations(bool runOutsideProjectDirectory, string extraProperties) => await BrowserRunTwiceWithAndThenWithoutBuildAsync(Configuration.Release, extraProperties, runOutsideProjectDirectory); @@ -83,13 +82,25 @@ private async Task BrowserRunTwiceWithAndThenWithoutBuildAsync(Configuration con UpdateBrowserMainJs(); string workingDir = runOutsideProjectDirectory ? BuildEnvironment.TmpPath : _projectDir; + string projectFilePath = info.ProjectFilePath; + if (runOutsideProjectDirectory) + { + // When running outside, the project is in a subdirectory of workingDir + string? directoryName = Path.GetDirectoryName(projectFilePath); + if (directoryName == null) + throw new InvalidOperationException($"Invalid project file path: {projectFilePath}"); + + string projectDirName = Path.GetFileName(directoryName); + string projectFileName = Path.GetFileName(projectFilePath); + projectFilePath = Path.Combine(projectDirName, projectFileName); + } { using var runCommand = new RunCommand(s_buildEnv, _testOutput) .WithWorkingDirectory(workingDir); await using var runner = new BrowserRunner(_testOutput); - var page = await runner.RunAsync(runCommand, $"run --no-silent -c {config} --project \"{info.ProjectName}.csproj\" --forward-console"); + var page = await runner.RunAsync(runCommand, $"run --no-silent -c {config} --project \"{projectFilePath}\" --forward-console"); await runner.WaitForExitMessageAsync(TimeSpan.FromMinutes(2)); Assert.Contains("Hello, Browser!", string.Join(Environment.NewLine, runner.OutputLines)); } @@ -99,7 +110,7 @@ private async Task BrowserRunTwiceWithAndThenWithoutBuildAsync(Configuration con .WithWorkingDirectory(workingDir); await using var runner = new BrowserRunner(_testOutput); - var page = await runner.RunAsync(runCommand, $"run --no-silent -c {config} --no-build --project \"{info.ProjectName}.csproj\" --forward-console"); + var page = await runner.RunAsync(runCommand, $"run --no-silent -c {config} --no-build --project \"{projectFilePath}\" --forward-console"); await runner.WaitForExitMessageAsync(TimeSpan.FromMinutes(2)); Assert.Contains("Hello, Browser!", string.Join(Environment.NewLine, runner.OutputLines)); } @@ -288,7 +299,7 @@ void AssertFile(string suffix) [Theory] [InlineData(false)] [InlineData(true)] - public async void LibraryModeBuild(bool useWasmSdk) + public async Task LibraryModeBuild(bool useWasmSdk) { var config = Configuration.Release; ProjectInfo info = CopyTestAsset(config, aot: false, TestAsset.LibraryModeTestApp, "libraryMode"); diff --git a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs index 4d1b08ac1e1d6b..1f26c39fe47a6a 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs @@ -21,7 +21,8 @@ namespace Wasm.Build.Tests; public class WasmTemplateTestsBase : BuildTestBase { private readonly WasmSdkBasedProjectProvider _provider; - private readonly string _extraBuildArgsPublish = "-p:CompressionEnabled=false"; + private readonly string _extraBuildArgsBuild = "-p:WasmEnableHotReload=false"; + private readonly string _extraBuildArgsPublish = "-p:CompressionEnabled=false -p:WasmEnableHotReload=false"; protected readonly PublishOptions _defaultPublishOptions; protected readonly BuildOptions _defaultBuildOptions; protected const string DefaultRuntimeAssetsRelativePath = "./_framework/"; @@ -31,7 +32,7 @@ public WasmTemplateTestsBase(ITestOutputHelper output, SharedBuildPerTestClassFi { _provider = GetProvider(); _defaultPublishOptions = new PublishOptions(ExtraMSBuildArgs: _extraBuildArgsPublish); - _defaultBuildOptions = new BuildOptions(); + _defaultBuildOptions = new BuildOptions(ExtraMSBuildArgs: _extraBuildArgsBuild); } private Dictionary browserProgramReplacements = new Dictionary @@ -162,7 +163,13 @@ public virtual (string projectDir, string buildOutput) BuildProject( BuildOptions buildOptions, bool? isNativeBuild = null, bool? wasmFingerprintDotnetJs = null) => - BuildProjectCore(info, configuration, buildOptions, isNativeBuild, wasmFingerprintDotnetJs); + BuildProjectCore( + info, + configuration, + buildOptions with { ExtraMSBuildArgs = $"{_extraBuildArgsBuild} {buildOptions.ExtraMSBuildArgs}" }, + isNativeBuild, + wasmFingerprintDotnetJs + ); private (string projectDir, string buildOutput) BuildProjectCore( ProjectInfo info, diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmBuildAppBase.cs b/src/mono/wasm/Wasm.Build.Tests/WasmBuildAppBase.cs index 7836ff1a15b3be..f04e7b61d05ee9 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmBuildAppBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmBuildAppBase.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; @@ -22,7 +23,7 @@ public WasmBuildAppBase(ITestOutputHelper output, SharedBuildPerTestClassFixture { } - protected async void TestMain(string projectName, + protected async Task TestMain(string projectName, string programText, Configuration config, bool aot, diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmBuildAppTest.cs b/src/mono/wasm/Wasm.Build.Tests/WasmBuildAppTest.cs index 996d3a490651b1..63636c98581806 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmBuildAppTest.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmBuildAppTest.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; +using System.Threading.Tasks; using System.Linq; using Xunit; using Xunit.Abstractions; @@ -20,16 +21,16 @@ public WasmBuildAppTest(ITestOutputHelper output, SharedBuildPerTestClassFixture [Theory] [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ true })] [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ false })] - public void TopLevelMain(Configuration config, bool aot) - => TestMain("top_level", + public async Task TopLevelMain(Configuration config, bool aot) + => await TestMain("top_level", @"System.Console.WriteLine(""Hello, World!""); return await System.Threading.Tasks.Task.FromResult(42);", config, aot); [Theory] [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ true })] [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ false })] - public void AsyncMain(Configuration config, bool aot) - => TestMain("async_main", @" + public async Task AsyncMain(Configuration config, bool aot) + => await TestMain("async_main", @" using System; using System.Threading.Tasks; @@ -44,8 +45,8 @@ public static async Task Main() [Theory] [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ true })] [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ false })] - public void NonAsyncMain(Configuration config, bool aot) - => TestMain("non_async_main", @" + public async Task NonAsyncMain(Configuration config, bool aot) + => await TestMain("non_async_main", @" using System; using System.Threading.Tasks; @@ -59,8 +60,8 @@ public static int Main() [Theory] [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ false })] - public void ExceptionFromMain(Configuration config, bool aot) - => TestMain("main_exception", """ + public async Task ExceptionFromMain(Configuration config, bool aot) + => await TestMain("main_exception", """ using System; using System.Threading.Tasks; @@ -84,21 +85,21 @@ public static int Main() [Theory] [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ true })] - public void Bug49588_RegressionTest_AOT(Configuration config, bool aot) - => TestMain("bug49588_aot", s_bug49588_ProgramCS, config, aot); + public async Task Bug49588_RegressionTest_AOT(Configuration config, bool aot) + => await TestMain("bug49588_aot", s_bug49588_ProgramCS, config, aot); [Theory] [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ false })] - public void Bug49588_RegressionTest_NativeRelinking(Configuration config, bool aot) - => TestMain("bug49588_native_relinking", s_bug49588_ProgramCS, config, aot, + public async Task Bug49588_RegressionTest_NativeRelinking(Configuration config, bool aot) + => await TestMain("bug49588_native_relinking", s_bug49588_ProgramCS, config, aot, extraArgs: "-p:WasmBuildNative=true", isNativeBuild: true); [Theory] [BuildAndRun] [ActiveIssue("https://github.com/dotnet/runtime/issues/97449")] - public void PropertiesFromRuntimeConfigJson(Configuration config, bool aot) - => TestMain("runtime_config_json", + public async Task PropertiesFromRuntimeConfigJson(Configuration config, bool aot) + => await TestMain("runtime_config_json", @" using System; using System.Runtime.CompilerServices; @@ -121,8 +122,8 @@ public void PropertiesFromRuntimeConfigJson(Configuration config, bool aot) [Theory] [BuildAndRun] [ActiveIssue("https://github.com/dotnet/runtime/issues/97449")] - public void PropertiesFromCsproj(Configuration config, bool aot) - => TestMain("csproj_properties", + public async Task PropertiesFromCsproj(Configuration config, bool aot) + => await TestMain("csproj_properties", @" using System; using System.Runtime.CompilerServices; diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmNativeDefaultsTests.cs b/src/mono/wasm/Wasm.Build.Tests/WasmNativeDefaultsTests.cs index d2c7a16d314e0c..32d14d3dc85f7e 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmNativeDefaultsTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmNativeDefaultsTests.cs @@ -28,6 +28,7 @@ public static TheoryData SettingDiffere ("InvariantTimezone", false), ("InvariantGlobalization", false), // ("WasmNativeStrip", true) -- tested separately because it has special handling in targets + // ("RunAOTCompilation", false) -- tested separately as it changes build behavior significantly }; TheoryData data = new(); diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmRunOutOfAppBundleTests.cs b/src/mono/wasm/Wasm.Build.Tests/WasmRunOutOfAppBundleTests.cs index 5a4a82d2142836..44139413690e49 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmRunOutOfAppBundleTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmRunOutOfAppBundleTests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.IO; +using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; @@ -16,7 +17,7 @@ public WasmRunOutOfAppBundleTests(ITestOutputHelper output, SharedBuildPerTestCl [Theory] [BuildAndRun] - public async void RunOutOfAppBundle(Configuration config, bool aot) + public async Task RunOutOfAppBundle(Configuration config, bool aot) { ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "outofappbundle"); UpdateFile(Path.Combine("Common", "Program.cs"), s_mainReturns42); diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmSIMDTests.cs b/src/mono/wasm/Wasm.Build.Tests/WasmSIMDTests.cs index d4008d6af8ecca..7f034effcf21dc 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmSIMDTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmSIMDTests.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; @@ -26,7 +27,7 @@ public WasmSIMDTests(ITestOutputHelper output, SharedBuildPerTestClassFixture bu [Theory] [MemberData(nameof(MainMethodSimdTestData), parameters: new object[] { /*aot*/ false, /* simd */ true })] - public async void Build_NoAOT_ShouldNotRelink(Configuration config, bool aot, bool simd) + public async Task Build_NoAOT_ShouldNotRelink(Configuration config, bool aot, bool simd) { ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "build_with_workload_no_aot"); UpdateFile(Path.Combine("Common", "Program.cs"), s_simdProgramText); @@ -49,7 +50,7 @@ public async void Build_NoAOT_ShouldNotRelink(Configuration config, bool aot, bo [MemberData(nameof(MainMethodSimdTestData), parameters: new object[] { /*aot*/ true, /* simd */ true })] [MemberData(nameof(MainMethodSimdTestData), parameters: new object[] { /*aot*/ false, /* simd */ true })] [MemberData(nameof(MainMethodSimdTestData), parameters: new object[] { /*aot*/ true, /* simd */ false })] - public async void PublishSIMD_AOT(Configuration config, bool aot, bool simd) + public async Task PublishSIMD_AOT(Configuration config, bool aot, bool simd) { ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "simd_publish"); UpdateFile(Path.Combine("Common", "Program.cs"), s_simdProgramText); diff --git a/src/mono/wasm/build/WasmApp.Common.targets b/src/mono/wasm/build/WasmApp.Common.targets index 8d96474284200b..4c36374a657ce3 100644 --- a/src/mono/wasm/build/WasmApp.Common.targets +++ b/src/mono/wasm/build/WasmApp.Common.targets @@ -240,7 +240,8 @@ dotnet <_RuntimeConfigJsonPath>$([MSBuild]::NormalizePath($(_AppBundleDirForRunCommand), '$(AssemblyName).runtimeconfig.json')) - exec "$([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost.dll'))" --runtime-config "$(_RuntimeConfigJsonPath)" $(WasmHostArguments) + <_RunExtraArguments Condition="'$(WasmEnableThreads)' == 'true'">--apply-cop-headers + exec "$([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost.dll'))" --runtime-config "$(_RuntimeConfigJsonPath)" $(_RunExtraArguments) $(WasmHostArguments) $(_AppBundleDirForRunCommand) diff --git a/src/mono/wasm/host/BrowserHost.cs b/src/mono/wasm/host/BrowserHost.cs index 9e27a169eccb3b..f56de7172317cb 100644 --- a/src/mono/wasm/host/BrowserHost.cs +++ b/src/mono/wasm/host/BrowserHost.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using System.Web; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.WebAssembly.AppHost.DevServer; using Microsoft.WebAssembly.Diagnostics; @@ -80,7 +81,7 @@ private async Task RunAsync(ILoggerFactory loggerFactory, CancellationToken toke ? aspnetUrls.Split(';', StringSplitOptions.RemoveEmptyEntries) : new string[] { $"http://127.0.0.1:{_args.CommonConfig.HostProperties.WebServerPort}", "https://127.0.0.1:0" }; - (ServerURLs serverURLs, IWebHost host) = await StartWebServerAsync(_args, + (ServerURLs serverURLs, IHost host) = await StartWebServerAsync(_args, urls, token); @@ -100,7 +101,7 @@ private async Task RunAsync(ILoggerFactory loggerFactory, CancellationToken toke await host.WaitForShutdownAsync(token); } - private async Task<(ServerURLs, IWebHost)> StartWebServerAsync(BrowserArguments args, string[] urls, CancellationToken token) + private async Task<(ServerURLs, IHost)> StartWebServerAsync(BrowserArguments args, string[] urls, CancellationToken token) { Func? onConsoleConnected = null; if (args.ForwardConsoleOutput ?? false) @@ -117,16 +118,16 @@ private async Task RunAsync(ILoggerFactory loggerFactory, CancellationToken toke } // Otherwise for old template, use web server - WebServerOptions webServerOptions = CreateWebServerOptions(urls, args.CommonConfig.AppPath, onConsoleConnected); + WebServerOptions webServerOptions = CreateWebServerOptions(args, urls, onConsoleConnected); return await WebServer.StartAsync(webServerOptions, _logger, token); } - private static WebServerOptions CreateWebServerOptions(string[] urls, string appPath, Func? onConsoleConnected) => new + private static WebServerOptions CreateWebServerOptions(BrowserArguments args, string[] urls, Func? onConsoleConnected) => new ( OnConsoleConnected: onConsoleConnected, - ContentRootPath: Path.GetFullPath(appPath), + ContentRootPath: Path.GetFullPath(args.CommonConfig.AppPath), WebServerUseCors: true, - WebServerUseCrossOriginPolicy: true, + WebServerUseCrossOriginPolicy: args.CommonConfig.ApplyCopHeaders, Urls: urls ); @@ -147,17 +148,17 @@ private static DevServerOptions CreateDevServerOptions(BrowserArguments args, st var staticWebAssetsPath = Path.ChangeExtension(mainAssemblyPath, staticWebAssetsV2Extension); if (File.Exists(staticWebAssetsPath)) { - devServerOptions = CreateDevServerOptions(urls, staticWebAssetsPath, endpointsManifest, onConsoleConnected); + devServerOptions = CreateDevServerOptions(args, urls, staticWebAssetsPath, endpointsManifest, onConsoleConnected); } else { staticWebAssetsPath = Path.ChangeExtension(mainAssemblyPath, staticWebAssetsV1Extension); if (File.Exists(staticWebAssetsPath)) - devServerOptions = CreateDevServerOptions(urls, staticWebAssetsPath, endpointsManifest, onConsoleConnected); + devServerOptions = CreateDevServerOptions(args, urls, staticWebAssetsPath, endpointsManifest, onConsoleConnected); } if (devServerOptions == null) - devServerOptions = CreateDevServerOptions(urls, mainAssemblyPath, endpointsManifest, onConsoleConnected); + devServerOptions = CreateDevServerOptions(args, urls, mainAssemblyPath, endpointsManifest, onConsoleConnected); } else { @@ -169,7 +170,7 @@ private static DevServerOptions CreateDevServerOptions(BrowserArguments args, st var endpointsManifest = FindFirstFileWithExtension(appPath, ".staticwebassets.endpoints.json"); if (staticWebAssetsPath != null) - devServerOptions = CreateDevServerOptions(urls, staticWebAssetsPath, endpointsManifest, onConsoleConnected); + devServerOptions = CreateDevServerOptions(args, urls, staticWebAssetsPath, endpointsManifest, onConsoleConnected); if (devServerOptions == null) throw new CommandLineException($"Please, provide mainAssembly in hostProperties of runtimeconfig. Alternatively leave the static web assets manifest ('*{staticWebAssetsV2Extension}') in the build output directory '{appPath}' ."); @@ -178,13 +179,13 @@ private static DevServerOptions CreateDevServerOptions(BrowserArguments args, st return devServerOptions; } - private static DevServerOptions CreateDevServerOptions(string[] urls, string staticWebAssetsPath, string? endpointsManifest, Func? onConsoleConnected) => new + private static DevServerOptions CreateDevServerOptions(BrowserArguments args, string[] urls, string staticWebAssetsPath, string? endpointsManifest, Func? onConsoleConnected) => new ( OnConsoleConnected: onConsoleConnected, StaticWebAssetsPath: staticWebAssetsPath, StaticWebAssetsEndpointsPath: endpointsManifest, WebServerUseCors: true, - WebServerUseCrossOriginPolicy: true, + WebServerUseCrossOriginPolicy: args.CommonConfig.ApplyCopHeaders, Urls: urls ); diff --git a/src/mono/wasm/host/CommonConfiguration.cs b/src/mono/wasm/host/CommonConfiguration.cs index dc676a7919537b..2dd050ace4ec33 100644 --- a/src/mono/wasm/host/CommonConfiguration.cs +++ b/src/mono/wasm/host/CommonConfiguration.cs @@ -23,6 +23,7 @@ internal sealed class CommonConfiguration public IEnumerable HostArguments { get; init; } public bool Silent { get; private set; } = true; public bool UseStaticWebAssets { get; private set; } + public bool ApplyCopHeaders { get; private set; } public string? RuntimeConfigPath { get; private set; } private string? hostArg; @@ -46,7 +47,8 @@ private CommonConfiguration(string[] args) { "runtime-config|r=", "runtimeconfig.json path for the app", v => RuntimeConfigPath = v }, { "extra-host-arg=", "Extra argument to be passed to the host", hostArgsList.Add }, { "no-silent", "Verbose output from WasmAppHost", _ => Silent = false }, - { "use-staticwebassets", "Use static web assets, needed for projects targeting WebAssembly SDK", _ => UseStaticWebAssets = true } + { "use-staticwebassets", "Use static web assets, needed for projects targeting WebAssembly SDK", _ => UseStaticWebAssets = true }, + { "apply-cop-headers", "Apply COOP/COEP headers, required for multi-threaded apps", _ => ApplyCopHeaders = true } }; RemainingArgs = options.Parse(args); diff --git a/src/mono/wasm/host/DevServer/DevServer.cs b/src/mono/wasm/host/DevServer/DevServer.cs index 9a5a079cee695e..5b12529f009afd 100644 --- a/src/mono/wasm/host/DevServer/DevServer.cs +++ b/src/mono/wasm/host/DevServer/DevServer.cs @@ -17,11 +17,12 @@ namespace Microsoft.WebAssembly.AppHost.DevServer; internal static class DevServer { - internal static async Task<(ServerURLs, IWebHost)> StartAsync(DevServerOptions options, ILogger logger, CancellationToken token) + internal static async Task<(ServerURLs, IHost)> StartAsync(DevServerOptions options, ILogger logger, CancellationToken token) { TaskCompletionSource realUrlsAvailableTcs = new(); - IWebHostBuilder builder = new WebHostBuilder() + IHostBuilder builder = new HostBuilder().ConfigureWebHost(webHostBuilder => + webHostBuilder .UseConfiguration(ConfigureHostConfiguration(options)) .UseKestrel() .UseStaticWebAssets() @@ -47,10 +48,10 @@ internal static class DevServer services.AddSingleton(realUrlsAvailableTcs); services.AddRouting(); }) - .UseUrls(options.Urls); + .UseUrls(options.Urls)); - IWebHost? host = builder.Build(); + IHost? host = builder.Build(); await host.StartAsync(token); if (token.CanBeCanceled) diff --git a/src/mono/wasm/host/WebServer.cs b/src/mono/wasm/host/WebServer.cs index 22534567d2e3f8..dfdc4e840451dd 100644 --- a/src/mono/wasm/host/WebServer.cs +++ b/src/mono/wasm/host/WebServer.cs @@ -21,11 +21,12 @@ namespace Microsoft.WebAssembly.AppHost; public class WebServer { - internal static async Task<(ServerURLs, IWebHost)> StartAsync(WebServerOptions options, ILogger logger, CancellationToken token) + internal static async Task<(ServerURLs, IHost)> StartAsync(WebServerOptions options, ILogger logger, CancellationToken token) { TaskCompletionSource realUrlsAvailableTcs = new(); - IWebHostBuilder builder = new WebHostBuilder() + IHostBuilder builder = new HostBuilder().ConfigureWebHost(webHostBuilder => + webHostBuilder .UseKestrel() .UseStartup() .ConfigureLogging(logging => @@ -49,12 +50,12 @@ public class WebServer services.AddSingleton(realUrlsAvailableTcs); services.AddRouting(); }) - .UseUrls(options.Urls); + .UseUrls(options.Urls)); if (options.ContentRootPath != null) builder.UseContentRoot(options.ContentRootPath); - IWebHost? host = builder.Build(); + IHost? host = builder.Build(); await host.StartAsync(token); if (token.CanBeCanceled) diff --git a/src/mono/wasm/templates/templates/browser/browser.0.csproj b/src/mono/wasm/templates/templates/browser/browser.0.csproj index e6debf4cd7fab3..dcc64ab68df696 100644 --- a/src/mono/wasm/templates/templates/browser/browser.0.csproj +++ b/src/mono/wasm/templates/templates/browser/browser.0.csproj @@ -6,6 +6,6 @@ - + diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs index c8d85406412f8e..f7f50858f7c3c3 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs @@ -5,10 +5,12 @@ using System; using System.Text.Json; using System.Runtime.InteropServices.JavaScript; +using System.Diagnostics.CodeAnalysis; public partial class LazyLoadingTest { [JSExport] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "LazyLibrary.Foo", "LazyLibrary")] public static void Run() { // System.Text.Json is marked as lazy loaded in the csproj ("BlazorWebAssemblyLazyLoad"), this method can be called only after the assembly is lazy loaded diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj b/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj index bd3c5a2643952f..e0896482e58925 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj @@ -20,11 +20,13 @@ + + diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js index 050206bdd42bd9..90595ef290f8e3 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js @@ -209,9 +209,16 @@ try { } await INTERNAL.loadLazyAssembly(`Json${lazyAssemblyExtension}`); + exports.LazyLoadingTest.Run(); + await INTERNAL.loadLazyAssembly(`LazyLibrary${lazyAssemblyExtension}`); + const { LazyLibrary } = await getAssemblyExports("LazyLibrary"); + const resLazy = LazyLibrary.Foo.Bar(); + exit(resLazy == 42 ? 0 : 1); + } + else { + exports.LazyLoadingTest.Run(); + exit(0); } - exports.LazyLoadingTest.Run(); - exit(0); break; case "LibraryInitializerTest": exit(0); diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/LazyLibrary/LazyLibrary.cs b/src/mono/wasm/testassets/WasmBasicTestApp/LazyLibrary/LazyLibrary.cs new file mode 100644 index 00000000000000..a10afc9fd393c1 --- /dev/null +++ b/src/mono/wasm/testassets/WasmBasicTestApp/LazyLibrary/LazyLibrary.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices.JavaScript; + +[assembly:System.Runtime.Versioning.SupportedOSPlatform("browser")] + +namespace LazyLibrary; + +public partial class Foo +{ + [JSExport] + public static int Bar() + { + Console.WriteLine("Hello from Foo.Bar!"); + return 42; + } +} diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/LazyLibrary/LazyLibrary.csproj b/src/mono/wasm/testassets/WasmBasicTestApp/LazyLibrary/LazyLibrary.csproj new file mode 100644 index 00000000000000..7861a9e9795585 --- /dev/null +++ b/src/mono/wasm/testassets/WasmBasicTestApp/LazyLibrary/LazyLibrary.csproj @@ -0,0 +1,8 @@ + + + net10.0 + browser-wasm + Library + true + + diff --git a/src/native/containers/dn-simdhash-ght-compatible.c b/src/native/containers/dn-simdhash-ght-compatible.c index 41b6f3d5403430..1a3cd566f55c1e 100644 --- a/src/native/containers/dn-simdhash-ght-compatible.c +++ b/src/native/containers/dn-simdhash-ght-compatible.c @@ -69,9 +69,9 @@ dn_simdhash_ght_replaced (dn_simdhash_ght_data data, void * old_key, void * new_ static unsigned int dn_simdhash_ght_default_hash (const void * key) { - // You might think we should avalanche the key bits but in my testing, it doesn't help. - // Right now the default hash function is rarely used anyway - return (unsigned int)(size_t)key; + // You might think we should avalanche the key bits but in my testing, it doesn't help. + // Right now the default hash function is rarely used anyway + return (unsigned int)(size_t)key; } static int32_t @@ -87,6 +87,8 @@ dn_simdhash_ght_new ( ) { dn_simdhash_ght_t *hash = dn_simdhash_new_internal(&DN_SIMDHASH_T_META, DN_SIMDHASH_T_VTABLE, capacity, allocator); + if (!hash) + return NULL; // Most users of dn_simdhash_ght are passing a custom comparer, and always doing an indirect call ends up being faster // than conditionally doing a fast inline check when there's no comparer set. Somewhat counter-intuitive, but true // on both x64 and arm64. Probably due to the smaller code size and reduced branch predictor pressure. @@ -107,6 +109,8 @@ dn_simdhash_ght_new_full ( ) { dn_simdhash_ght_t *hash = dn_simdhash_new_internal(&DN_SIMDHASH_T_META, DN_SIMDHASH_T_VTABLE, capacity, allocator); + if (!hash) + return NULL; if (!hash_func) hash_func = dn_simdhash_ght_default_hash; if (!key_equal_func) @@ -133,7 +137,14 @@ dn_simdhash_ght_insert_replace ( dn_simdhash_insert_result ok = DN_SIMDHASH_TRY_INSERT_INTERNAL(hash, key, key_hash, value, imode); if (ok == DN_SIMDHASH_INSERT_NEED_TO_GROW) { - dn_simdhash_buffers_t old_buffers = dn_simdhash_ensure_capacity_internal(hash, dn_simdhash_capacity(hash) + 1); + uint8_t grow_ok; + dn_simdhash_buffers_t old_buffers = dn_simdhash_ensure_capacity_internal(hash, dn_simdhash_capacity(hash) + 1, &grow_ok); + // The ghashtable API doesn't have a way to signal failure, so just assert that we didn't fail to grow + dn_simdhash_assert(grow_ok); + // Don't attempt to insert after a failed grow (it's possible to get here because dn_simdhash_assert is configurable) + if (!grow_ok) + return; + if (old_buffers.buckets) { DN_SIMDHASH_REHASH_INTERNAL(hash, old_buffers); dn_simdhash_free_buffers(old_buffers); @@ -151,11 +162,51 @@ dn_simdhash_ght_insert_replace ( case DN_SIMDHASH_INSERT_KEY_ALREADY_PRESENT: case DN_SIMDHASH_INSERT_NEED_TO_GROW: default: - assert(0); + dn_simdhash_assert(!"Internal error in dn_simdhash_ght_insert_replace"); return; } } +dn_simdhash_add_result +dn_simdhash_ght_try_insert ( + dn_simdhash_ght_t *hash, + void *key, void *value, + dn_simdhash_insert_mode mode +) +{ + check_self(hash); + uint32_t key_hash = DN_SIMDHASH_KEY_HASHER(DN_SIMDHASH_GET_DATA(hash), key); + + dn_simdhash_insert_result ok = DN_SIMDHASH_TRY_INSERT_INTERNAL(hash, key, key_hash, value, mode); + if (ok == DN_SIMDHASH_INSERT_NEED_TO_GROW) { + uint8_t grow_ok; + dn_simdhash_buffers_t old_buffers = dn_simdhash_ensure_capacity_internal(hash, dn_simdhash_capacity(hash) + 1, &grow_ok); + if (!grow_ok) + return DN_SIMDHASH_OUT_OF_MEMORY; + + if (old_buffers.buckets) { + DN_SIMDHASH_REHASH_INTERNAL(hash, old_buffers); + dn_simdhash_free_buffers(old_buffers); + } + ok = DN_SIMDHASH_TRY_INSERT_INTERNAL(hash, key, key_hash, value, mode); + } + + switch (ok) { + case DN_SIMDHASH_INSERT_OK_ADDED_NEW: + hash->count++; + return DN_SIMDHASH_ADD_INSERTED; + case DN_SIMDHASH_INSERT_OK_OVERWROTE_EXISTING: + return DN_SIMDHASH_ADD_OVERWROTE; + case DN_SIMDHASH_INSERT_KEY_ALREADY_PRESENT: + return DN_SIMDHASH_ADD_FAILED; + + case DN_SIMDHASH_INSERT_NEED_TO_GROW: + default: + dn_simdhash_assert(!"Internal error in dn_simdhash_ght_insert_replace"); + return DN_SIMDHASH_INTERNAL_ERROR; + } +} + void * dn_simdhash_ght_get_value_or_default ( dn_simdhash_ght_t *hash, void * key diff --git a/src/native/containers/dn-simdhash-ght-compatible.h b/src/native/containers/dn-simdhash-ght-compatible.h index 76f25ae09946c1..c11147bd35c2b4 100644 --- a/src/native/containers/dn-simdhash-ght-compatible.h +++ b/src/native/containers/dn-simdhash-ght-compatible.h @@ -38,6 +38,13 @@ dn_simdhash_ght_get_value_or_default ( dn_simdhash_ght_t *hash, void * key ); +dn_simdhash_add_result +dn_simdhash_ght_try_insert ( + dn_simdhash_ght_t *hash, + void *key, void *value, + dn_simdhash_insert_mode mode +); + #ifdef __cplusplus } #endif // __cplusplus diff --git a/src/native/containers/dn-simdhash-specialization-declarations.h b/src/native/containers/dn-simdhash-specialization-declarations.h index 97dc6fe32d2310..bde49893337d29 100644 --- a/src/native/containers/dn-simdhash-specialization-declarations.h +++ b/src/native/containers/dn-simdhash-specialization-declarations.h @@ -52,10 +52,10 @@ DN_SIMDHASH_T_PTR DN_SIMDHASH_NEW (uint32_t capacity, dn_allocator_t *allocator); #endif -uint8_t +dn_simdhash_add_result DN_SIMDHASH_TRY_ADD (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, DN_SIMDHASH_VALUE_T value); -uint8_t +dn_simdhash_add_result DN_SIMDHASH_TRY_ADD_WITH_HASH (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, uint32_t key_hash, DN_SIMDHASH_VALUE_T value); // result is an optional parameter that will be set to the value of the item if it was found. diff --git a/src/native/containers/dn-simdhash-specialization.h b/src/native/containers/dn-simdhash-specialization.h index 7614a690f5c080..408a70a713ee26 100644 --- a/src/native/containers/dn-simdhash-specialization.h +++ b/src/native/containers/dn-simdhash-specialization.h @@ -305,17 +305,6 @@ DN_SIMDHASH_FIND_VALUE_INTERNAL (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, return NULL; } -typedef enum dn_simdhash_insert_mode { - // Ensures that no matching key exists in the hash, then adds the key/value pair - DN_SIMDHASH_INSERT_MODE_ENSURE_UNIQUE, - // If a matching key exists in the hash, overwrite its value but leave the key alone - DN_SIMDHASH_INSERT_MODE_OVERWRITE_VALUE, - // If a matching key exists in the hash, overwrite both the key and the value - DN_SIMDHASH_INSERT_MODE_OVERWRITE_KEY_AND_VALUE, - // Do not scan for existing matches before adding the new key/value pair. - DN_SIMDHASH_INSERT_MODE_REHASHING, -} dn_simdhash_insert_mode; - static void do_overwrite ( DN_SIMDHASH_T_PTR hash, uint32_t bucket_index, bucket_t *bucket_address, int index_in_bucket, @@ -444,7 +433,7 @@ DN_SIMDHASH_NEW (uint32_t capacity, dn_allocator_t *allocator) } #endif -uint8_t +dn_simdhash_add_result DN_SIMDHASH_TRY_ADD (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, DN_SIMDHASH_VALUE_T value) { check_self(hash); @@ -453,14 +442,18 @@ DN_SIMDHASH_TRY_ADD (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, DN_SIMDHASH_ return DN_SIMDHASH_TRY_ADD_WITH_HASH(hash, key, key_hash, value); } -uint8_t +dn_simdhash_add_result DN_SIMDHASH_TRY_ADD_WITH_HASH (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, uint32_t key_hash, DN_SIMDHASH_VALUE_T value) { check_self(hash); dn_simdhash_insert_result ok = DN_SIMDHASH_TRY_INSERT_INTERNAL(hash, key, key_hash, value, DN_SIMDHASH_INSERT_MODE_ENSURE_UNIQUE); if (ok == DN_SIMDHASH_INSERT_NEED_TO_GROW) { - dn_simdhash_buffers_t old_buffers = dn_simdhash_ensure_capacity_internal(hash, dn_simdhash_capacity(hash) + 1); + uint8_t grow_ok; + dn_simdhash_buffers_t old_buffers = dn_simdhash_ensure_capacity_internal(hash, dn_simdhash_capacity(hash) + 1, &grow_ok); + if (!grow_ok) + return DN_SIMDHASH_OUT_OF_MEMORY; + if (old_buffers.buckets) { DN_SIMDHASH_REHASH_INTERNAL(hash, old_buffers); dn_simdhash_free_buffers(old_buffers); @@ -471,18 +464,19 @@ DN_SIMDHASH_TRY_ADD_WITH_HASH (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, ui switch (ok) { case DN_SIMDHASH_INSERT_OK_ADDED_NEW: hash->count++; - return 1; + return DN_SIMDHASH_ADD_INSERTED; case DN_SIMDHASH_INSERT_OK_OVERWROTE_EXISTING: // This shouldn't happen dn_simdhash_assert(!"Overwrote an existing item while adding"); - return 1; + return DN_SIMDHASH_INTERNAL_ERROR; case DN_SIMDHASH_INSERT_KEY_ALREADY_PRESENT: - return 0; + return DN_SIMDHASH_ADD_FAILED; case DN_SIMDHASH_INSERT_NEED_TO_GROW: - // We should always have enough space after growing once. + dn_simdhash_assert(!"After growing there was no space for a new item"); + return DN_SIMDHASH_INTERNAL_ERROR; default: dn_simdhash_assert(!"Failed to add a new item but there was no existing item"); - return 0; + return DN_SIMDHASH_INTERNAL_ERROR; } } diff --git a/src/native/containers/dn-simdhash-specializations.h b/src/native/containers/dn-simdhash-specializations.h index 9533edfc5f3d1f..e899b9ed38270e 100644 --- a/src/native/containers/dn-simdhash-specializations.h +++ b/src/native/containers/dn-simdhash-specializations.h @@ -61,7 +61,7 @@ typedef struct dn_simdhash_str_key dn_simdhash_str_key; typedef struct dn_ptrpair_t { - void *first, *second; + void *first, *second; } dn_ptrpair_t; #define DN_SIMDHASH_T dn_simdhash_ptrpair_ptr diff --git a/src/native/containers/dn-simdhash-string-ptr.c b/src/native/containers/dn-simdhash-string-ptr.c index c3a93ceac9cdba..d917f3386c440e 100644 --- a/src/native/containers/dn-simdhash-string-ptr.c +++ b/src/native/containers/dn-simdhash-string-ptr.c @@ -83,8 +83,8 @@ dn_simdhash_string_ptr_try_remove (dn_simdhash_string_ptr_t *hash, const char *k void dn_simdhash_string_ptr_foreach (dn_simdhash_string_ptr_t *hash, dn_simdhash_string_ptr_foreach_func func, void *user_data) { - assert(hash); - assert(func); + dn_simdhash_assert(hash); + dn_simdhash_assert(func); dn_simdhash_buffers_t buffers = hash->buffers; BEGIN_SCAN_PAIRS(buffers, key_address, value_address) diff --git a/src/native/containers/dn-simdhash.c b/src/native/containers/dn-simdhash.c index 24ea919f8ae365..f29d42b81e9ca8 100644 --- a/src/native/containers/dn-simdhash.c +++ b/src/native/containers/dn-simdhash.c @@ -167,7 +167,9 @@ dn_simdhash_new_internal (dn_simdhash_meta_t *meta, dn_simdhash_vtable_t vtable, { const size_t size = sizeof(dn_simdhash_t) + meta->data_size; dn_simdhash_t *result = (dn_simdhash_t *)dn_allocator_alloc(allocator, size); - dn_simdhash_assert(result); + if (!result) + return NULL; + memset(result, 0, size); dn_simdhash_assert(meta); @@ -178,7 +180,12 @@ dn_simdhash_new_internal (dn_simdhash_meta_t *meta, dn_simdhash_vtable_t vtable, result->vtable = vtable; result->buffers.allocator = allocator; - dn_simdhash_ensure_capacity_internal(result, compute_adjusted_capacity(capacity)); + uint8_t alloc_ok; + dn_simdhash_ensure_capacity_internal(result, compute_adjusted_capacity(capacity), &alloc_ok); + if (!alloc_ok) { + dn_allocator_free(allocator, result); + return NULL; + } return result; } @@ -205,9 +212,12 @@ dn_simdhash_free_buffers (dn_simdhash_buffers_t buffers) } dn_simdhash_buffers_t -dn_simdhash_ensure_capacity_internal (dn_simdhash_t *hash, uint32_t capacity) +dn_simdhash_ensure_capacity_internal (dn_simdhash_t *hash, uint32_t capacity, uint8_t *ok) { dn_simdhash_assert(hash); + dn_simdhash_assert(ok); + *ok = 0; + size_t bucket_count = (capacity + hash->meta->bucket_capacity - 1) / hash->meta->bucket_capacity; // FIXME: Only apply this when capacity == 0? if (bucket_count < DN_SIMDHASH_MIN_BUCKET_COUNT) @@ -225,6 +235,8 @@ dn_simdhash_ensure_capacity_internal (dn_simdhash_t *hash, uint32_t capacity) dn_simdhash_buffers_t result = { 0, }; if (bucket_count <= hash->buffers.buckets_length) { dn_simdhash_assert(value_count <= hash->buffers.values_length); + // We didn't grow but we also didn't fail, so we set ok to 1. + *ok = 1; return result; } @@ -235,9 +247,26 @@ dn_simdhash_ensure_capacity_internal (dn_simdhash_t *hash, uint32_t capacity) capacity, value_count ); */ + + // pad buckets allocation by the width of one vector so we can align it + size_t buckets_size_bytes = (bucket_count * hash->meta->bucket_size_bytes) + DN_SIMDHASH_VECTOR_WIDTH, + values_size_bytes = value_count * hash->meta->value_size; + + // If either of these allocations fail all we can do is return a default-initialized buffers_t, which will + // result in the caller not freeing anything and seeing an ok of 0, so they can tell the grow failed. + // This should leave the hash in a well-formed state and if they try to grow later it might work. + void *new_buckets = dn_allocator_alloc(hash->buffers.allocator, buckets_size_bytes); + if (!new_buckets) + return result; + + void *new_values = dn_allocator_alloc(hash->buffers.allocator, values_size_bytes); + if (!new_values) { + dn_allocator_free(hash->buffers.allocator, new_buckets); + return result; + } + // Store old buffers so caller can rehash and then free them result = hash->buffers; - size_t grow_at_count = value_count; grow_at_count *= 100; grow_at_count /= DN_SIMDHASH_SIZING_PERCENTAGE; @@ -245,13 +274,6 @@ dn_simdhash_ensure_capacity_internal (dn_simdhash_t *hash, uint32_t capacity) hash->buffers.buckets_length = (uint32_t)bucket_count; hash->buffers.values_length = (uint32_t)value_count; - // pad buckets allocation by the width of one vector so we can align it - size_t buckets_size_bytes = (bucket_count * hash->meta->bucket_size_bytes) + DN_SIMDHASH_VECTOR_WIDTH, - values_size_bytes = value_count * hash->meta->value_size; - - void *new_buckets = dn_allocator_alloc(hash->buffers.allocator, buckets_size_bytes), - *new_values = dn_allocator_alloc(hash->buffers.allocator, values_size_bytes); - dn_simdhash_assert(new_buckets); dn_simdhash_assert(new_values); @@ -268,6 +290,8 @@ dn_simdhash_ensure_capacity_internal (dn_simdhash_t *hash, uint32_t capacity) // Skip this for performance; memset is especially slow in wasm // memset(hash->buffers.values, 0, values_size_bytes); + *ok = 1; + return result; } @@ -301,7 +325,7 @@ dn_simdhash_count (dn_simdhash_t *hash) uint32_t dn_simdhash_overflow_count (dn_simdhash_t *hash) { - assert(hash); + dn_simdhash_assert(hash); uint32_t result = 0; for (uint32_t bucket_index = 0; bucket_index < hash->buffers.buckets_length; bucket_index++) { uint8_t *suffixes = ((uint8_t *)hash->buffers.buckets) + (bucket_index * hash->meta->bucket_size_bytes); @@ -311,14 +335,16 @@ dn_simdhash_overflow_count (dn_simdhash_t *hash) return result; } -void +uint8_t dn_simdhash_ensure_capacity (dn_simdhash_t *hash, uint32_t capacity) { dn_simdhash_assert(hash); capacity = compute_adjusted_capacity(capacity); - dn_simdhash_buffers_t old_buffers = dn_simdhash_ensure_capacity_internal(hash, capacity); + uint8_t result; + dn_simdhash_buffers_t old_buffers = dn_simdhash_ensure_capacity_internal(hash, capacity, &result); if (old_buffers.buckets) { hash->vtable.rehash(hash, old_buffers); dn_simdhash_free_buffers(old_buffers); } + return result; } diff --git a/src/native/containers/dn-simdhash.h b/src/native/containers/dn-simdhash.h index af1afd8a910c7f..13bcb9ec828e4b 100644 --- a/src/native/containers/dn-simdhash.h +++ b/src/native/containers/dn-simdhash.h @@ -52,11 +52,32 @@ typedef struct dn_simdhash_t dn_simdhash_t; typedef struct dn_simdhash_meta_t { // type metadata for generic implementation + // NOTE: key_size and value_size are not used consistently by every part of the implementation, + // a specialization is still strongly typed based on its KEY_T and VALUE_T. But they need to match. uint32_t bucket_capacity, bucket_size_bytes, key_size, value_size, // Allocate this many bytes of extra data inside the dn_simdhash_t data_size; } dn_simdhash_meta_t; +typedef enum dn_simdhash_insert_mode { + // Ensures that no matching key exists in the hash, then adds the key/value pair + DN_SIMDHASH_INSERT_MODE_ENSURE_UNIQUE, + // If a matching key exists in the hash, overwrite its value but leave the key alone + DN_SIMDHASH_INSERT_MODE_OVERWRITE_VALUE, + // If a matching key exists in the hash, overwrite both the key and the value + DN_SIMDHASH_INSERT_MODE_OVERWRITE_KEY_AND_VALUE, + // Do not scan for existing matches before adding the new key/value pair. + DN_SIMDHASH_INSERT_MODE_REHASHING, +} dn_simdhash_insert_mode; + +typedef enum dn_simdhash_add_result { + DN_SIMDHASH_INTERNAL_ERROR = -2, + DN_SIMDHASH_OUT_OF_MEMORY = -1, + DN_SIMDHASH_ADD_FAILED = 0, + DN_SIMDHASH_ADD_INSERTED = 1, + DN_SIMDHASH_ADD_OVERWROTE = 2, +} dn_simdhash_add_result; + typedef enum dn_simdhash_insert_result { DN_SIMDHASH_INSERT_OK_ADDED_NEW, DN_SIMDHASH_INSERT_OK_OVERWROTE_EXISTING, @@ -139,8 +160,9 @@ dn_simdhash_free_buffers (dn_simdhash_buffers_t buffers); // If a resize happens, this will allocate new buffers and return the old ones. // It is your responsibility to rehash and then free the old buffers. +// If growing failed due to an out of memory condition *ok will be 0, otherwise it will be 1. dn_simdhash_buffers_t -dn_simdhash_ensure_capacity_internal (dn_simdhash_t *hash, uint32_t capacity); +dn_simdhash_ensure_capacity_internal (dn_simdhash_t *hash, uint32_t capacity, uint8_t *ok); // Erases the contents of the table, but does not shrink it. void @@ -161,8 +183,9 @@ uint32_t dn_simdhash_overflow_count (dn_simdhash_t *hash); // Automatically resizes the table if it is too small to hold the requested number -// of items. Will not shrink the table if it is already bigger. -void +// of items. Will not shrink the table if it is already bigger. Returns whether +// the operation was successful - 0 indicates allocation failure. +uint8_t dn_simdhash_ensure_capacity (dn_simdhash_t *hash, uint32_t capacity); #ifdef __cplusplus diff --git a/src/native/containers/simdhash-benchmark/run-benchmark.ps1 b/src/native/containers/simdhash-benchmark/run-benchmark.ps1 index 9417d16c505cbf..1a4221b9ad0b75 100755 --- a/src/native/containers/simdhash-benchmark/run-benchmark.ps1 +++ b/src/native/containers/simdhash-benchmark/run-benchmark.ps1 @@ -1,2 +1,2 @@ -cl /GS- /O2 /std:c17 ./*.c ../dn-simdhash-u32-ptr.c ../dn-simdhash.c ../dn-vector.c ../dn-simdhash-string-ptr.c /DNO_CONFIG_H /DSIZEOF_VOID_P=8 /DNDEBUG /Fe:all-measurements.exe +cl /GS- /O2 /std:c17 ./*.c ../dn-simdhash-u32-ptr.c ../dn-simdhash.c ../dn-vector.c ../dn-simdhash-string-ptr.c ../dn-simdhash-ght-compatible.c /DNO_CONFIG_H /DSIZEOF_VOID_P=8 /DNDEBUG /Fe:all-measurements.exe ./all-measurements.exe diff --git a/src/native/corehost/CMakeLists.txt b/src/native/corehost/CMakeLists.txt index 5ce72395e49f7f..02ed291648817b 100644 --- a/src/native/corehost/CMakeLists.txt +++ b/src/native/corehost/CMakeLists.txt @@ -83,6 +83,8 @@ add_library(fxr_resolver INTERFACE) target_sources(fxr_resolver INTERFACE fxr_resolver.cpp) target_include_directories(fxr_resolver INTERFACE fxr) +add_compile_definitions(RAPIDJSON_HAS_CXX17) + if ((NOT DEFINED CLR_CMAKE_USE_SYSTEM_RAPIDJSON) OR (NOT CLR_CMAKE_USE_SYSTEM_RAPIDJSON)) include_directories(${CLR_SRC_NATIVE_DIR}/external/) endif() diff --git a/src/native/corehost/apphost/standalone/hostfxr_resolver.cpp b/src/native/corehost/apphost/standalone/hostfxr_resolver.cpp index e3f10e2b21dcfd..0fd8bc01269130 100644 --- a/src/native/corehost/apphost/standalone/hostfxr_resolver.cpp +++ b/src/native/corehost/apphost/standalone/hostfxr_resolver.cpp @@ -121,6 +121,7 @@ hostfxr_resolver_t::hostfxr_resolver_t(const pal::string_t& app_root) else if (!pal::is_path_fully_qualified(m_fxr_path)) { // We should always be loading hostfxr from an absolute path + trace::error(_X("Path to %s must be fully qualified: [%s]"), LIBFXR_NAME, m_fxr_path.c_str()); m_status_code = StatusCode::CoreHostLibMissingFailure; } else if (pal::load_library(&m_fxr_path, &m_hostfxr_dll)) diff --git a/src/native/corehost/apphost/static/CMakeLists.txt b/src/native/corehost/apphost/static/CMakeLists.txt index 30118f679da387..c37e523cf148bd 100644 --- a/src/native/corehost/apphost/static/CMakeLists.txt +++ b/src/native/corehost/apphost/static/CMakeLists.txt @@ -17,6 +17,8 @@ add_subdirectory(../../hostmisc hostmisc) configure_file(${CLR_SRC_NATIVE_DIR}/corehost/configure.h.in ${GENERATED_INCLUDE_DIR}/corehost/configure.h) target_include_directories(hostmisc_interface INTERFACE ${GENERATED_INCLUDE_DIR}/corehost) +add_compile_definitions(RAPIDJSON_HAS_CXX17) + if ((NOT DEFINED CLR_CMAKE_USE_SYSTEM_RAPIDJSON) OR (NOT CLR_CMAKE_USE_SYSTEM_RAPIDJSON)) include_directories(${CLR_SRC_NATIVE_DIR}/external/) endif() @@ -166,10 +168,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 +207,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/native/corehost/build.sh b/src/native/corehost/build.sh index b7df4cc8212148..63c3b6d996e4a7 100755 --- a/src/native/corehost/build.sh +++ b/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/native/corehost/comhost/clsidmap.cpp b/src/native/corehost/comhost/clsidmap.cpp index 001649765f662e..af18abd8b2db92 100644 --- a/src/native/corehost/comhost/clsidmap.cpp +++ b/src/native/corehost/comhost/clsidmap.cpp @@ -102,7 +102,7 @@ namespace json_parser_t json; if (!json.parse_raw_data(reinterpret_cast(data), size, _X(""))) { - trace::error(_X("Embedded .clsidmap format is invalid")); + trace::error(_X("Embedded .clsidmap is invalid.\n %s"), json.get_error_message().c_str()); throw HResultException{ StatusCode::InvalidConfigFile }; } @@ -180,7 +180,7 @@ namespace json_parser_t json; if (!json.parse_file(map_file_name)) { - trace::error(_X("File .clsidmap format is invalid")); + trace::error(_X("File .clsidmap [%s] is invalid.\n %s"), map_file_name.c_str(), json.get_error_message().c_str()); throw HResultException{ StatusCode::InvalidConfigFile }; } diff --git a/src/native/corehost/corehost.cpp b/src/native/corehost/corehost.cpp index c186318d5f3cbb..aeae151be08770 100644 --- a/src/native/corehost/corehost.cpp +++ b/src/native/corehost/corehost.cpp @@ -212,10 +212,7 @@ int exe_start(const int argc, const pal::char_t* argv[]) // Obtain the entrypoints. int rc = fxr.status_code(); if (rc != StatusCode::Success) - { - trace::error(_X("Failed to resolve %s [%s]. Error code: 0x%x"), LIBFXR_NAME, fxr.fxr_path().empty() ? _X("not found") : fxr.fxr_path().c_str(), rc); return rc; - } #if defined(FEATURE_APPHOST) if (bundle_marker_t::is_bundle()) diff --git a/src/native/corehost/fxr/command_line.cpp b/src/native/corehost/fxr/command_line.cpp index 6ed0d48fffcd55..b23f6f4bb1677d 100644 --- a/src/native/corehost/fxr/command_line.cpp +++ b/src/native/corehost/fxr/command_line.cpp @@ -164,17 +164,6 @@ namespace trace::verbose(_X("Application '%s' is not a managed executable."), app_candidate.c_str()); if (!exec_mode) { - // Check if this is a non-managed file with directory separator that exists - // This should show a specific error instead of routing to CLI - bool has_dir_separator = app_candidate.find(DIR_SEPARATOR) != pal::string_t::npos; - if (has_dir_separator) - { - if (pal::file_exists(app_candidate)) - { - trace::error(_X("The application '%s' is not a managed .dll."), app_candidate.c_str()); - return StatusCode::InvalidArgFailure; - } - } // Route to CLI. return StatusCode::AppArgNotRunnable; } @@ -291,7 +280,7 @@ int command_line::parse_args_for_sdk_command( return parse_args(host_info, 1, argc, argv, false, host_mode_t::muxer, new_argoff, app_candidate, opts); } -void command_line::print_muxer_info(const pal::string_t &dotnet_root, const pal::string_t &global_json_path, bool skip_sdk_info_output) +void command_line::print_muxer_info(const pal::string_t &dotnet_root, const sdk_resolver::global_file_info &global_json, bool skip_sdk_info_output) { pal::string_t commit = _STRINGIFY(REPO_COMMIT_HASH); trace::println(_X("\n") @@ -333,9 +322,32 @@ void command_line::print_muxer_info(const pal::string_t &dotnet_root, const pal: } trace::println(_X("\n") - _X("global.json file:\n") - _X(" %s"), - global_json_path.empty() ? _X("Not found") : global_json_path.c_str()); + _X("global.json file:")); + switch (global_json.state) + { + case sdk_resolver::global_file_info::state::not_found: + trace::println(_X(" Not found")); + break; + case sdk_resolver::global_file_info::state::valid: + trace::println(_X(" %s"), global_json.path.c_str()); + break; + case sdk_resolver::global_file_info::state::invalid_json: + case sdk_resolver::global_file_info::state::invalid_data: + case sdk_resolver::global_file_info::state::__invalid_data_no_fallback: + trace::println(_X(" Invalid [%s]"), global_json.path.c_str()); + if (!global_json.error_message.empty()) + { + trace::println(_X(" %s"), global_json.error_message.c_str()); + } + if (global_json.state != sdk_resolver::global_file_info::state::__invalid_data_no_fallback) + { + trace::println(_X(" Invalid global.json is ignored for SDK resolution.")); + } + break; + case sdk_resolver::global_file_info::state::__last: + assert(false && "Unexpected __last state"); + break; + } trace::println(_X("\n") _X("Learn more:\n") diff --git a/src/native/corehost/fxr/command_line.h b/src/native/corehost/fxr/command_line.h index 935e66800870e5..979694b44e9a7d 100644 --- a/src/native/corehost/fxr/command_line.h +++ b/src/native/corehost/fxr/command_line.h @@ -8,6 +8,8 @@ #include #include +#include "sdk_resolver.h" + enum class known_options { additional_probing_path, @@ -59,7 +61,7 @@ namespace command_line // skip_sdk_info_output indicates whether or not to skip any information that the SDK would have // already printed. Related: https://github.com/dotnet/sdk/issues/33697 - void print_muxer_info(const pal::string_t &dotnet_root, const pal::string_t &global_json_path, bool skip_sdk_info_output); + void print_muxer_info(const pal::string_t &dotnet_root, const sdk_resolver::global_file_info& global_json, bool skip_sdk_info_output); void print_muxer_usage(bool is_sdk_present); }; diff --git a/src/native/corehost/fxr/fx_muxer.cpp b/src/native/corehost/fxr/fx_muxer.cpp index 36fec3d9ec00a1..cef02fd75a4a9f 100644 --- a/src/native/corehost/fxr/fx_muxer.cpp +++ b/src/native/corehost/fxr/fx_muxer.cpp @@ -1103,7 +1103,7 @@ int fx_muxer_t::handle_cli( } else if (pal::strcasecmp(_X("--info"), argv[1]) == 0) { - command_line::print_muxer_info(host_info.dotnet_root, resolver.global_file_path(), false /*skip_sdk_info_output*/); + command_line::print_muxer_info(host_info.dotnet_root, resolver.global_file(), false /*skip_sdk_info_output*/); return StatusCode::Success; } @@ -1160,7 +1160,7 @@ int fx_muxer_t::handle_cli( if (pal::strcasecmp(_X("--info"), argv[1]) == 0) { - command_line::print_muxer_info(host_info.dotnet_root, resolver.global_file_path(), result == 0 /*skip_sdk_info_output*/); + command_line::print_muxer_info(host_info.dotnet_root, resolver.global_file(), result == 0 /*skip_sdk_info_output*/); } return result; diff --git a/src/native/corehost/fxr/hostfxr.cpp b/src/native/corehost/fxr/hostfxr.cpp index 98c2ae26a14f92..1b3438c05b4d28 100644 --- a/src/native/corehost/fxr/hostfxr.cpp +++ b/src/native/corehost/fxr/hostfxr.cpp @@ -173,15 +173,29 @@ enum class hostfxr_resolve_sdk2_result_key_t : int32_t resolved_sdk_dir = 0, global_json_path = 1, requested_version = 2, + global_json_state = 3, }; typedef void (HOSTFXR_CALLTYPE *hostfxr_resolve_sdk2_result_fn)( hostfxr_resolve_sdk2_result_key_t key, const pal::char_t* value); +namespace +{ + const pal::char_t *GlobalJsonStates[] = + { + _X("not_found"), + _X("valid"), + _X("invalid_json"), + _X("invalid_data"), + _X("__invalid_data_no_fallback"), + }; + static_assert((sizeof(GlobalJsonStates) / sizeof(*GlobalJsonStates)) == static_cast(sdk_resolver::global_file_info::state::__last), "Invalid state count"); +} + // // Determines the directory location of the SDK accounting for -// global.json and multi-level lookup policy. +// global.json. // // Invoked via MSBuild SDK resolver to locate SDK props and targets // from an msbuild other than the one bundled by the CLI. @@ -192,13 +206,12 @@ typedef void (HOSTFXR_CALLTYPE *hostfxr_resolve_sdk2_result_fn)( // sub-folders. Pass the directory of a dotnet executable to // mimic how that executable would search in its own directory. // It is also valid to pass nullptr or empty, in which case -// multi-level lookup can still search other locations if -// it has not been disabled by the user's environment. +// only paths from any found global.json will be searched. // // working_dir // The directory where the search for global.json (which can // control the resolved SDK version) starts and proceeds -// upwards. +// upwards. If nullptr or empty, global.json search is disabled. // // flags // Bitwise flags that influence resolution. @@ -228,6 +241,10 @@ typedef void (HOSTFXR_CALLTYPE *hostfxr_resolve_sdk2_result_fn)( // value will hold the requested version. This will occur for // both resolution success and failure. // +// The result will be invoked with global_json_state key and +// the value will hold one of: not_found, valid, invalid_json, +// invalid_data. +// // Return value: // 0 on success, otherwise failure // 0x8000809b - SDK could not be resolved (SdkResolveFailure) @@ -273,11 +290,11 @@ SHARED_API int32_t HOSTFXR_CALLTYPE hostfxr_resolve_sdk2( resolved_sdk_dir.c_str()); } - if (!resolver.global_file_path().empty()) + if (resolver.global_file().is_data_used() && !resolver.global_file().path.empty()) { result( hostfxr_resolve_sdk2_result_key_t::global_json_path, - resolver.global_file_path().c_str()); + resolver.global_file().path.c_str()); } if (!resolver.get_requested_version().is_empty()) @@ -287,6 +304,10 @@ SHARED_API int32_t HOSTFXR_CALLTYPE hostfxr_resolve_sdk2( resolver.get_requested_version().as_str().c_str()); } + result( + hostfxr_resolve_sdk2_result_key_t::global_json_state, + GlobalJsonStates[static_cast(resolver.global_file().state)]); + return !resolved_sdk_dir.empty() ? StatusCode::Success : StatusCode::SdkResolveFailure; @@ -623,7 +644,12 @@ SHARED_API int32_t HOSTFXR_CALLTYPE hostfxr_resolve_frameworks_for_runtime_confi const runtime_config_t::settings_t override_settings; app->parse_runtime_config(runtime_config, _X(""), override_settings); - const runtime_config_t app_config = app->get_runtime_config(); + const runtime_config_t& app_config = app->get_runtime_config(); + if (!app_config.is_valid()) + { + trace::error(_X("Invalid runtimeconfig.json [%s]"), app_config.get_path().c_str()); + return StatusCode::InvalidConfigFile; + } // Resolve frameworks for framework-dependent apps. // Self-contained apps assume the framework is next to the app, so we just treat it as success. diff --git a/src/native/corehost/fxr/install_info.cpp b/src/native/corehost/fxr/install_info.cpp index 64eb5490903174..bf7103ed31f33c 100644 --- a/src/native/corehost/fxr/install_info.cpp +++ b/src/native/corehost/fxr/install_info.cpp @@ -6,29 +6,47 @@ #include "trace.h" #include "utils.h" +#include +#include + bool install_info::print_environment(const pal::char_t* leading_whitespace) { - bool found_any = false; - - const pal::char_t* fmt = _X("%s%-17s [%s]"); - pal::string_t value; - if (pal::getenv(DOTNET_ROOT_ENV_VAR, &value)) - { - found_any = true; - trace::println(fmt, leading_whitespace, DOTNET_ROOT_ENV_VAR, value.c_str()); - } - - for (uint32_t i = 0; i < static_cast(pal::architecture::__last); ++i) + // Enumerate environment variables and filter for DOTNET_ + std::vector> env_vars; + bool found_complus_var = false; + pal::enumerate_environment_variables([&](const pal::char_t* name, const pal::char_t* value) { - pal::string_t env_var = get_dotnet_root_env_var_for_arch(static_cast(i)); - if (pal::getenv(env_var.c_str(), &value)) + // Check if the environment variable starts with DOTNET_ +#if defined(TARGET_WINDOWS) + // Environment variables are case-insensitive on Windows + auto comp_func = pal::strncasecmp; +#else + auto comp_func = pal::strncmp; +#endif + if (comp_func(name, _X("DOTNET_"), STRING_LENGTH("DOTNET_")) == 0) { - found_any = true; - trace::println(fmt, leading_whitespace, env_var.c_str(), value.c_str()); + env_vars.push_back(std::make_pair(name, value)); } + else if (!found_complus_var && comp_func(name, _X("COMPlus_"), STRING_LENGTH("COMPlus_")) == 0) + { + found_complus_var = true; + } + }); + + // Sort for consistent output + std::sort(env_vars.begin(), env_vars.end()); + + // Print all relevant environment variables + const pal::char_t* fmt = _X("%s%-40s [%s]"); + for (const auto& env_var : env_vars) + { + trace::println(fmt, leading_whitespace, env_var.first.c_str(), env_var.second.c_str()); } - return found_any; + if (found_complus_var) + trace::println(_X("%sDetected COMPlus_* environment variable(s). Consider transitioning to DOTNET_* equivalent."), leading_whitespace); + + return env_vars.size() > 0 || found_complus_var; } bool install_info::try_get_install_location(pal::architecture arch, pal::string_t& out_install_location, bool* out_is_registered) diff --git a/src/native/corehost/fxr/sdk_resolver.cpp b/src/native/corehost/fxr/sdk_resolver.cpp index f70ee651720a7d..d3063a3db3d5a7 100644 --- a/src/native/corehost/fxr/sdk_resolver.cpp +++ b/src/native/corehost/fxr/sdk_resolver.cpp @@ -26,25 +26,21 @@ namespace _X("latestMinor"), _X("latestMajor"), }; -} - -sdk_resolver::sdk_resolver(bool allow_prerelease) - : sdk_resolver({}, sdk_roll_forward_policy::latest_major, allow_prerelease) -{ -} -sdk_resolver::sdk_resolver(fx_ver_t version, sdk_roll_forward_policy roll_forward, bool allow_prerelease) - : requested_version(std::move(version)) - , roll_forward(roll_forward) - , allow_prerelease(allow_prerelease) - , has_custom_paths(false) -{ + int get_feature_band(const fx_ver_t& version) + { + // SDK versions encode both the feature band and patch version in the SemVer patch version. + // They have the form x.y.znn, where z is the feature band and nn is the patch version. + // To get the feature band, we divide the SemVer patch by 100 + return version.get_patch() / 100; + } } -const pal::string_t& sdk_resolver::global_file_path() const -{ - return global_file; -} +sdk_resolver::sdk_resolver(bool allow_prerelease) + : roll_forward{sdk_roll_forward_policy::latest_major} + , allow_prerelease{allow_prerelease} + , has_custom_paths{false} +{ } const fx_ver_t& sdk_resolver::get_requested_version() const { @@ -121,7 +117,7 @@ std::vector sdk_resolver::get_search_paths(const pal::string_t& d else { // Use custom paths specified in the global.json - pal::string_t json_dir = get_directory(global_file); + pal::string_t json_dir = get_directory(global_json.path); for (const pal::string_t& path : paths) { if (path == _X("$host$")) @@ -166,10 +162,10 @@ void sdk_resolver::print_resolution_error(const pal::string_t& dotnet_root, cons main_error_prefix, requested.c_str()); - bool has_global_file = !global_file.empty(); + bool has_global_file = global_json.is_data_used(); if (has_global_file) { - trace::error(_X("global.json file: %s"), global_file.c_str()); + trace::error(_X("global.json file: %s"), global_json.path.c_str()); if (has_custom_paths) { trace::error(_X(" Search paths:")); @@ -188,7 +184,7 @@ void sdk_resolver::print_resolution_error(const pal::string_t& dotnet_root, cons trace::error(_X("")); if (has_global_file) { - trace::error(_X("Install the [%s] .NET SDK or update [%s] to match an installed SDK."), requested.c_str(), global_file.c_str()); + trace::error(_X("Install the [%s] .NET SDK or update [%s] to match an installed SDK."), requested.c_str(), global_json.path.c_str()); } else { @@ -200,7 +196,7 @@ void sdk_resolver::print_resolution_error(const pal::string_t& dotnet_root, cons trace::error(_X("%s%s"), main_error_prefix, no_sdk_message); if (has_custom_paths && paths.empty()) { - trace::error(_X("%sEmpty search paths specified in global.json file: %s"), main_error_prefix, global_file.c_str()); + trace::error(_X("%sEmpty search paths specified in global.json file: %s"), main_error_prefix, global_json.path.c_str()); } } @@ -237,14 +233,27 @@ sdk_resolver sdk_resolver::from_nearest_global_file(const pal::string_t& cwd, bo { sdk_resolver resolver{ allow_prerelease }; - if (!resolver.parse_global_file(find_nearest_global_file(cwd))) + pal::string_t global_file_path = find_nearest_global_file(cwd); + + if (global_file_path.empty()) + { + resolver.global_json.state = global_file_info::state::not_found; + } + else { - // Fall back to a default SDK resolver - resolver = sdk_resolver{ allow_prerelease }; + global_file_info global_file = resolver.parse_global_file(global_file_path); + if (!global_file.is_data_used()) + { + // Fall back to a default SDK resolver + resolver = sdk_resolver{ allow_prerelease }; - trace::warning( - _X("Ignoring SDK settings in global.json: the latest installed .NET SDK (%s prereleases) will be used"), - resolver.allow_prerelease ? _X("including") : _X("excluding")); + trace::verbose(_X("Invalid global.json [%s]:\n %s"), global_file.path.c_str(), global_file.error_message.c_str()); + trace::warning( + _X("Ignoring SDK settings in global.json: the latest installed .NET SDK (%s prereleases) will be used"), + resolver.allow_prerelease ? _X("including") : _X("excluding")); + } + + resolver.global_json = std::move(global_file); } // If the requested version is a prerelease, always allow prerelease versions @@ -312,22 +321,27 @@ pal::string_t sdk_resolver::find_nearest_global_file(const pal::string_t& cwd) return {}; } -bool sdk_resolver::parse_global_file(pal::string_t global_file_path) +sdk_resolver::global_file_info sdk_resolver::parse_global_file(const pal::string_t& global_file_path) { + global_file_info ret; if (global_file_path.empty()) { // Missing global.json is treated as success (use default resolver) - return true; + ret.state = global_file_info::state::not_found; + return ret; } trace::verbose(_X("--- Resolving SDK information from global.json [%s]"), global_file_path.c_str()); + ret.path = global_file_path; // After we're done parsing `global_file_path`, none of its contents will be referenced // from the data private to json_parser_t; it's safe to declare it on the stack. json_parser_t json; if (!json.parse_file(global_file_path)) { - return false; + ret.error_message = json.get_error_message(); + ret.state = global_file_info::state::invalid_json; + return ret; } const auto& sdk = json.document().FindMember(_X("sdk")); @@ -335,13 +349,16 @@ bool sdk_resolver::parse_global_file(pal::string_t global_file_path) { // Missing SDK is treated as success (use default resolver) trace::verbose(_X("Value 'sdk' is missing or null in [%s]"), global_file_path.c_str()); - return true; + ret.state = global_file_info::state::valid; + return ret; } + ret.state = global_file_info::state::invalid_data; + if (!sdk->value.IsObject()) { - trace::warning(_X("Expected a JSON object for the 'sdk' value in [%s]"), global_file_path.c_str()); - return false; + ret.error_message = _X("Expected a JSON object for the 'sdk' value"); + return ret; } const auto& version_value = sdk->value.FindMember(_X("version")); @@ -353,18 +370,14 @@ bool sdk_resolver::parse_global_file(pal::string_t global_file_path) { if (!version_value->value.IsString()) { - trace::warning(_X("Expected a string for the 'sdk/version' value in [%s]"), global_file_path.c_str()); - return false; + ret.error_message = _X("Expected a string for the 'sdk/version' value"); + return ret; } if (!fx_ver_t::parse(version_value->value.GetString(), &requested_version, false)) { - trace::warning( - _X("Version '%s' is not valid for the 'sdk/version' value in [%s]"), - version_value->value.GetString(), - global_file_path.c_str() - ); - return false; + ret.error_message = utils::format_string(_X("Version '%s' is not valid for the 'sdk/version' value"), version_value->value.GetString()); + return ret; } // The default policy when a version is specified is 'patch' @@ -380,30 +393,22 @@ bool sdk_resolver::parse_global_file(pal::string_t global_file_path) { if (!roll_forward_value->value.IsString()) { - trace::warning(_X("Expected a string for the 'sdk/rollForward' value in [%s]"), global_file_path.c_str()); - return false; + ret.error_message = _X("Expected a string for the 'sdk/rollForward' value"); + return ret; } roll_forward = to_policy(roll_forward_value->value.GetString()); if (roll_forward == sdk_roll_forward_policy::unsupported) { - trace::warning( - _X("The roll-forward policy '%s' is not supported for the 'sdk/rollForward' value in [%s]"), - roll_forward_value->value.GetString(), - global_file_path.c_str() - ); - return false; + ret.error_message = utils::format_string(_X("The roll-forward policy '%s' is not supported for the 'sdk/rollForward' value"), roll_forward_value->value.GetString()); + return ret; } // All policies other than 'latestMajor' require a version to operate if (roll_forward != sdk_roll_forward_policy::latest_major && requested_version.is_empty()) { - trace::warning( - _X("The roll-forward policy '%s' requires a 'sdk/version' value in [%s]"), - roll_forward_value->value.GetString(), - global_file_path.c_str() - ); - return false; + ret.error_message = utils::format_string(_X("The roll-forward policy '%s' requires a 'sdk/version' value"), roll_forward_value->value.GetString()); + return ret; } } @@ -416,8 +421,8 @@ bool sdk_resolver::parse_global_file(pal::string_t global_file_path) { if (!allow_prerelease_value->value.IsBool()) { - trace::warning(_X("Expected a boolean for the 'sdk/allowPrerelease' value in [%s]"), global_file_path.c_str()); - return false; + ret.error_message = _X("Expected a boolean for the 'sdk/allowPrerelease' value"); + return ret; } allow_prerelease = allow_prerelease_value->value.GetBool(); @@ -434,8 +439,8 @@ bool sdk_resolver::parse_global_file(pal::string_t global_file_path) { if (!paths_value->value.IsArray()) { - trace::warning(_X("Expected an array for 'sdk/paths' value in [%s]"), global_file_path.c_str()); - return false; + ret.error_message = _X("Expected an array for 'sdk/paths' value"); + return ret; } has_custom_paths = true; @@ -459,15 +464,25 @@ bool sdk_resolver::parse_global_file(pal::string_t global_file_path) { if (!error_message_value->value.IsString()) { - trace::warning(_X("Expected a string for the 'sdk/errorMessage' value in [%s]"), global_file_path.c_str()); - return false; + ret.error_message = _X("Expected a string for the 'sdk/errorMessage' value"); + return ret; } error_message = error_message_value->value.GetString(); } - global_file = std::move(global_file_path); - return true; + // SDK feature bands start at 1, so a version with a feature band < 1 is not a valid version. + // We want to provide an error message, but we should still use the settings in the global.json + // and not fall back to the default resolver. + if (!requested_version.is_empty() && get_feature_band(requested_version) < 1) + { + ret.error_message = utils::format_string(_X("Version '%s' is not valid for the 'sdk/version' value. SDK feature bands start at 1 - for example, %d.%d.100"), requested_version.as_str().c_str(), requested_version.get_major(), requested_version.get_minor()); + ret.state = global_file_info::state::__invalid_data_no_fallback; + return ret; + } + + ret.state = global_file_info::state::valid; + return ret; } bool sdk_resolver::matches_policy(const fx_ver_t& current) const @@ -487,8 +502,8 @@ bool sdk_resolver::matches_policy(const fx_ver_t& current) const return true; } - int requested_feature = requested_version.get_patch() / 100; - int current_feature = current.get_patch() / 100; + int requested_feature = get_feature_band(requested_version); + int current_feature = get_feature_band(current); int requested_minor = requested_version.get_minor(); int current_minor = current.get_minor(); @@ -543,7 +558,7 @@ bool sdk_resolver::is_better_match(const fx_ver_t& current, const fx_ver_t& prev is_policy_use_latest() || (current.get_major() == previous.get_major() && current.get_minor() == previous.get_minor() && - (current.get_patch() / 100) == (previous.get_patch() / 100))) + (get_feature_band(current) == get_feature_band(previous)))) { // Accept the later of the versions // This will also handle stable and prerelease comparisons diff --git a/src/native/corehost/fxr/sdk_resolver.h b/src/native/corehost/fxr/sdk_resolver.h index d8724acd03b5b4..73a81407a4da72 100644 --- a/src/native/corehost/fxr/sdk_resolver.h +++ b/src/native/corehost/fxr/sdk_resolver.h @@ -34,10 +34,29 @@ enum class sdk_roll_forward_policy class sdk_resolver { public: - explicit sdk_resolver(bool allow_prerelease = true); - sdk_resolver(fx_ver_t version, sdk_roll_forward_policy roll_forward, bool allow_prerelease); + struct global_file_info + { + enum class state + { + not_found, + valid, + invalid_json, + invalid_data, + // Invalid data that doesn't fall back to default resolution. If we are able to remove the fallback + // and just fail on invalid data, this should be removed and invalid_data used instead. + __invalid_data_no_fallback, + __last + }; + + state state; + pal::string_t path; + pal::string_t error_message; - const pal::string_t& global_file_path() const; + // Whether or not the global.json is actually used for resolution. + bool is_data_used() const { return state == state::valid || state == state::__invalid_data_no_fallback; } + }; + + const global_file_info& global_file() const { return global_json; } const fx_ver_t& get_requested_version() const; @@ -54,10 +73,11 @@ class sdk_resolver bool allow_prerelease = true); private: + explicit sdk_resolver(bool allow_prerelease = true); static sdk_roll_forward_policy to_policy(const pal::string_t& name); static const pal::char_t* to_policy_name(sdk_roll_forward_policy policy); static pal::string_t find_nearest_global_file(const pal::string_t& cwd); - bool parse_global_file(pal::string_t global_file_path); + global_file_info parse_global_file(const pal::string_t& global_file_path); bool matches_policy(const fx_ver_t& current) const; bool is_better_match(const fx_ver_t& current, const fx_ver_t& previous) const; bool exact_match_preferred() const; @@ -66,7 +86,7 @@ class sdk_resolver // Returns true and sets sdk_path/resolved_version if a matching SDK was found bool resolve_sdk_path_and_version(const pal::string_t& dir, pal::string_t& sdk_path, fx_ver_t& resolved_version) const; - pal::string_t global_file; + global_file_info global_json; fx_ver_t requested_version; sdk_roll_forward_policy roll_forward; bool allow_prerelease; diff --git a/src/native/corehost/fxr/standalone/hostpolicy_resolver.cpp b/src/native/corehost/fxr/standalone/hostpolicy_resolver.cpp index ff68220193d47b..be784c61a693a5 100644 --- a/src/native/corehost/fxr/standalone/hostpolicy_resolver.cpp +++ b/src/native/corehost/fxr/standalone/hostpolicy_resolver.cpp @@ -27,11 +27,10 @@ namespace { trace::verbose(_X("--- Resolving %s version from deps json [%s]"), LIBHOSTPOLICY_NAME, deps_json.c_str()); - pal::string_t retval; json_parser_t json; if (!json.parse_file(deps_json)) { - return retval; + return {}; } // Look up the root package instead of the "runtime" package because we can't do a full rid resolution. @@ -43,13 +42,13 @@ namespace if (utils::starts_with(lib_name, prefix, false)) { // Extract the version information that occurs after '/' - retval = lib_name.substr(utils::strlen(prefix)); - break; + pal::string_t version = lib_name.substr(utils::strlen(prefix)); + trace::verbose(_X("Resolved version %s from dependency manifest file [%s]"), version.c_str(), deps_json.c_str()); + return version; } } - trace::verbose(_X("Resolved version %s from dependency manifest file [%s]"), retval.c_str(), deps_json.c_str()); - return retval; + return {}; } /** diff --git a/src/native/corehost/fxr_resolver.cpp b/src/native/corehost/fxr_resolver.cpp index 0d1cbddf9deb5c..dbc1d625f8a14c 100644 --- a/src/native/corehost/fxr_resolver.cpp +++ b/src/native/corehost/fxr_resolver.cpp @@ -93,7 +93,6 @@ bool fxr_resolver::try_get_path( bool search_app_relative = (search & search_location_app_relative) != 0 && app_relative_dotnet_root != nullptr && !app_relative_dotnet_root->empty(); bool search_env = (search & search_location_environment_variable) != 0; bool search_global = (search & search_location_global) != 0; - pal::string_t default_install_location; pal::string_t dotnet_root_env_var_name; if (search_app_relative && pal::fullpath(app_relative_dotnet_root)) { @@ -111,10 +110,11 @@ bool fxr_resolver::try_get_path( } else if (search_global) { - if (pal::get_dotnet_self_registered_dir(&default_install_location) || pal::get_default_installation_dir(&default_install_location)) + pal::string_t global_install_location; + if (pal::get_dotnet_self_registered_dir(&global_install_location) || pal::get_default_installation_dir(&global_install_location)) { - trace::info(_X("Using global install location [%s] as runtime location."), default_install_location.c_str()); - out_dotnet_root->assign(default_install_location); + trace::info(_X("Using global install location [%s] as runtime location."), global_install_location.c_str()); + out_dotnet_root->assign(global_install_location); } else { @@ -130,35 +130,7 @@ bool fxr_resolver::try_get_path( return get_latest_fxr(std::move(fxr_dir), out_fxr_path); // Failed to find hostfxr - if (trace::is_enabled()) - { - trace::verbose(_X("The required library %s could not be found. Search location options [0x%x]"), LIBFXR_NAME, search); - if (search_app_local) - trace::verbose(_X(" app-local: [%s]"), root_path.c_str()); - - if (search_app_relative) - trace::verbose(_X(" app-relative: [%s]"), app_relative_dotnet_root->c_str()); - - if (search_env) - trace::verbose(_X(" environment variable: [%s]"), dotnet_root_env_var_name.c_str()); - - if (search_global) - { - if (default_install_location.empty()) - { - pal::get_dotnet_self_registered_dir(&default_install_location); - } - if (default_install_location.empty()) - { - pal::get_default_installation_dir(&default_install_location); - } - - pal::string_t self_registered_config_location = pal::get_dotnet_self_registered_config_location(get_current_arch()); - trace::verbose(_X(" global install location [%s]\n self-registered config location [%s]"), - default_install_location.c_str(), - self_registered_config_location.c_str()); - } - } + trace::verbose(_X("The required library %s could not be found. Search location options [0x%x]"), LIBFXR_NAME, search); pal::string_t host_path; pal::get_own_executable_path(&host_path); @@ -187,6 +159,66 @@ bool fxr_resolver::try_get_path( } } + pal::string_t searched_locations = _X("The following locations were searched:"); + if (search_app_local && !root_path.empty()) + { + searched_locations.append(_X("\n Application directory:\n ")); + searched_locations.append(root_path); + } + + if (search_app_relative) + { + searched_locations.append(_X("\n App-relative location:\n ")); + searched_locations.append(*app_relative_dotnet_root); + } + + if (search_env) + { + searched_locations.append(_X("\n Environment variable:\n ")); + if (dotnet_root_env_var_name.empty()) + { + searched_locations.append(get_dotnet_root_env_var_for_arch(get_current_arch())); + searched_locations.append(_X(" = \n ")); + searched_locations.append(DOTNET_ROOT_ENV_VAR _X(" = ")); + } + else + { + searched_locations.append(dotnet_root_env_var_name); + searched_locations.append(_X(" = ")); + searched_locations.append(*out_dotnet_root); + } + } + + // Global locations are only searched if environment variables are not set + if (search_global && dotnet_root_env_var_name.empty()) + { + searched_locations.append(_X("\n Registered location:\n ")); + searched_locations.append(pal::get_dotnet_self_registered_config_location(get_current_arch())); + + pal::string_t self_registered_dir; + if (pal::get_dotnet_self_registered_dir(&self_registered_dir) && !self_registered_dir.empty()) + { + searched_locations.append(_X(" = ")); + searched_locations.append(self_registered_dir); + } + else + { + searched_locations.append(_X(" = ")); + } + + // Default install location is only searched if self-registered location is not set + if (self_registered_dir.empty()) + { + pal::string_t default_install_location; + pal::get_default_installation_dir(&default_install_location); + searched_locations.append(_X("\n Default location:\n ")); + searched_locations.append(default_install_location); + } + } + + location.append(_X("\n\n")); + location.append(searched_locations); + trace::error( MISSING_RUNTIME_ERROR_FORMAT, INSTALL_NET_ERROR_MESSAGE, diff --git a/src/native/corehost/hostmisc/pal.h b/src/native/corehost/hostmisc/pal.h index 484aedef68fba2..84b3698af0cced 100644 --- a/src/native/corehost/hostmisc/pal.h +++ b/src/native/corehost/hostmisc/pal.h @@ -17,6 +17,7 @@ #include #include #include +#include #if defined(_WIN32) @@ -159,6 +160,12 @@ namespace pal inline int str_vprintf(char_t* buffer, size_t count, const char_t* format, va_list vl) { return ::_vsnwprintf_s(buffer, count, _TRUNCATE, format, vl); } inline int strlen_vprintf(const char_t* format, va_list vl) { return ::_vscwprintf(format, vl); } + template + int str_printf(char_t* buffer, size_t count, const char_t* format, Args&&... args) { return ::_snwprintf_s(buffer, count, _TRUNCATE, format, std::forward(args)...); } + + template + inline int strlen_printf(const char_t* format, Args&&... args) { return ::_scwprintf(format, std::forward(args)...); } + inline const string_t strerror(int errnum) { // Windows does not provide strerrorlen to get the actual error length. @@ -230,6 +237,12 @@ namespace pal inline int str_vprintf(char_t* str, size_t size, const char_t* format, va_list vl) { return ::vsnprintf(str, size, format, vl); } inline int strlen_vprintf(const char_t* format, va_list vl) { return ::vsnprintf(nullptr, 0, format, vl); } + template + int str_printf(char_t* buffer, size_t size, const char_t* format, Args&&... args) { return ::snprintf(buffer, size, format, std::forward(args)...); } + + template + inline int strlen_printf(const char_t* format, Args&&... args) { return ::snprintf(nullptr, 0, format, std::forward(args)...); } + inline const string_t strerror(int errnum) { return ::strerror(errnum); } inline size_t pal_utf8string(const string_t& str, char* out_buffer, size_t buffer_len) @@ -305,6 +318,7 @@ namespace pal bool get_module_path(dll_t mod, string_t* recv); bool get_current_module(dll_t* mod); bool getenv(const char_t* name, string_t* recv); + void enumerate_environment_variables(const std::function callback); bool get_default_servicing_directory(string_t* recv); enum class architecture diff --git a/src/native/corehost/hostmisc/pal.unix.cpp b/src/native/corehost/hostmisc/pal.unix.cpp index 6a0922ff84159b..4a6197f541c4eb 100644 --- a/src/native/corehost/hostmisc/pal.unix.cpp +++ b/src/native/corehost/hostmisc/pal.unix.cpp @@ -957,6 +957,24 @@ bool pal::getenv(const pal::char_t* name, pal::string_t* recv) return (recv->length() > 0); } +extern char **environ; +void pal::enumerate_environment_variables(const std::function callback) +{ + if (environ == nullptr) + return; + + for (char **env = environ; *env != nullptr; ++env) + { + const char* current = *env; + const char* separator = ::strchr(current, '='); + if (separator != nullptr && separator != current) + { + pal::string_t name(current, separator - current); + callback(name.c_str(), separator + 1); + } + } +} + bool pal::fullpath(pal::string_t* path, bool skip_error_logging) { return realpath(path, skip_error_logging); diff --git a/src/native/corehost/hostmisc/pal.windows.cpp b/src/native/corehost/hostmisc/pal.windows.cpp index 2b9c88bd72f1e2..4561fef00d6543 100644 --- a/src/native/corehost/hostmisc/pal.windows.cpp +++ b/src/native/corehost/hostmisc/pal.windows.cpp @@ -714,6 +714,28 @@ bool pal::getenv(const char_t* name, string_t* recv) return true; } +void pal::enumerate_environment_variables(const std::function callback) +{ + LPWCH env_strings = ::GetEnvironmentStringsW(); + if (env_strings == nullptr) + return; + + LPWCH current = env_strings; + while (*current != L'\0') + { + LPWCH eq_ptr = ::wcschr(current, L'='); + if (eq_ptr != nullptr && eq_ptr != current) + { + pal::string_t name(current, eq_ptr - current); + callback(name.c_str(), eq_ptr + 1); + } + + current += pal::strlen(current) + 1; // Move to next string + } + + ::FreeEnvironmentStringsW(env_strings); +} + int pal::xtoi(const char_t* input) { return ::_wtoi(input); diff --git a/src/native/corehost/hostmisc/trace.cpp b/src/native/corehost/hostmisc/trace.cpp index 70b36ebd3a42c3..77f88d0f1dd5cd 100644 --- a/src/native/corehost/hostmisc/trace.cpp +++ b/src/native/corehost/hostmisc/trace.cpp @@ -12,13 +12,13 @@ #define TRACE_VERBOSITY_INFO 3 #define TRACE_VERBOSITY_VERBOSE 4 -// g_trace_verbosity is used to encode COREHOST_TRACE and COREHOST_TRACE_VERBOSITY to selectively control output of +// g_trace_verbosity is used to encode DOTNET_HOST_TRACE and DOTNET_HOST_TRACE_VERBOSITY to selectively control output of // trace::warn(), trace::info(), and trace::verbose() -// COREHOST_TRACE=0 COREHOST_TRACE_VERBOSITY=N/A implies g_trace_verbosity = 0. // Trace "disabled". error() messages will be produced. -// COREHOST_TRACE=1 COREHOST_TRACE_VERBOSITY=4 or unset implies g_trace_verbosity = 4. // Trace "enabled". verbose(), info(), warn() and error() messages will be produced -// COREHOST_TRACE=1 COREHOST_TRACE_VERBOSITY=3 implies g_trace_verbosity = 3. // Trace "enabled". info(), warn() and error() messages will be produced -// COREHOST_TRACE=1 COREHOST_TRACE_VERBOSITY=2 implies g_trace_verbosity = 2. // Trace "enabled". warn() and error() messages will be produced -// COREHOST_TRACE=1 COREHOST_TRACE_VERBOSITY=1 implies g_trace_verbosity = 1. // Trace "enabled". error() messages will be produced +// DOTNET_HOST_TRACE=0 DOTNET_HOST_TRACE_VERBOSITY=N/A implies g_trace_verbosity = 0. // Trace "disabled". error() messages will be produced. +// DOTNET_HOST_TRACE=1 DOTNET_HOST_TRACE_VERBOSITY=4 or unset implies g_trace_verbosity = 4. // Trace "enabled". verbose(), info(), warn() and error() messages will be produced +// DOTNET_HOST_TRACE=1 DOTNET_HOST_TRACE_VERBOSITY=3 implies g_trace_verbosity = 3. // Trace "enabled". info(), warn() and error() messages will be produced +// DOTNET_HOST_TRACE=1 DOTNET_HOST_TRACE_VERBOSITY=2 implies g_trace_verbosity = 2. // Trace "enabled". warn() and error() messages will be produced +// DOTNET_HOST_TRACE=1 DOTNET_HOST_TRACE_VERBOSITY=1 implies g_trace_verbosity = 1. // Trace "enabled". error() messages will be produced static int g_trace_verbosity = 0; static FILE * g_trace_file = nullptr; thread_local static trace::error_writer_fn g_error_writer = nullptr; @@ -52,16 +52,35 @@ namespace }; spin_lock g_trace_lock; + + template + bool get_host_env_var(const pal::char_t (&name)[NameLen], pal::string_t* value) + { + assert(name[NameLen - 1] == _X('\0')); // name is expected to be null-terminated + + // DOTNET_HOST_* takes precedence + constexpr size_t dotnet_host_prefix_len = STRING_LENGTH("DOTNET_HOST_"); + pal::char_t dotnet_host_name[dotnet_host_prefix_len + NameLen]; + pal::snwprintf(dotnet_host_name, ARRAY_SIZE(dotnet_host_name), _X("DOTNET_HOST_%s"), name); + if (pal::getenv(dotnet_host_name, value)) + return true; + + // COREHOST_* for backwards compatibility + constexpr size_t corehost_prefix_len = STRING_LENGTH("COREHOST_"); + pal::char_t corehost_name[corehost_prefix_len + NameLen]; + pal::snwprintf(corehost_name, ARRAY_SIZE(corehost_name), _X("COREHOST_%s"), name); + return pal::getenv(corehost_name, value); + } } // -// Turn on tracing for the corehost based on "COREHOST_TRACE" & "COREHOST_TRACEFILE" env. +// Turn on tracing for the corehost based on "DOTNET_HOST_TRACE" & "DOTNET_HOST_TRACEFILE" env. // void trace::setup() { // Read trace environment variable pal::string_t trace_str; - if (!pal::getenv(_X("COREHOST_TRACE"), &trace_str)) + if (!get_host_env_var(_X("TRACE"), &trace_str)) { return; } @@ -91,7 +110,7 @@ bool trace::enable() std::lock_guard lock(g_trace_lock); g_trace_file = stderr; // Trace to stderr by default - if (pal::getenv(_X("COREHOST_TRACEFILE"), &tracefile_str)) + if (get_host_env_var(_X("TRACEFILE"), &tracefile_str)) { if (pal::is_directory(tracefile_str)) { @@ -122,7 +141,7 @@ bool trace::enable() } pal::string_t trace_str; - if (!pal::getenv(_X("COREHOST_TRACE_VERBOSITY"), &trace_str)) + if (!get_host_env_var(_X("TRACE_VERBOSITY"), &trace_str)) { g_trace_verbosity = TRACE_VERBOSITY_VERBOSE; // Verbose trace by default } @@ -134,7 +153,7 @@ bool trace::enable() if (file_open_error) { - trace::error(_X("Unable to open COREHOST_TRACEFILE=%s for writing"), tracefile_str.c_str()); + trace::error(_X("Unable to open specified trace file for writing: %s"), tracefile_str.c_str()); } return true; } diff --git a/src/native/corehost/hostmisc/utils.cpp b/src/native/corehost/hostmisc/utils.cpp index dd351434a2da9a..a48cd2d39f9bd0 100644 --- a/src/native/corehost/hostmisc/utils.cpp +++ b/src/native/corehost/hostmisc/utils.cpp @@ -52,18 +52,21 @@ bool utils::ends_with(const pal::string_t& value, const pal::char_t* suffix, siz void append_path(pal::string_t* path1, const pal::char_t* path2) { - if (pal::is_path_rooted(path2)) + if (pal::strlen(path2) == 0) + return; + + if (path1->empty()) { path1->assign(path2); + return; } - else + + if (path1->back() != DIR_SEPARATOR && path2[0] != DIR_SEPARATOR) { - if (!path1->empty() && path1->back() != DIR_SEPARATOR) - { - path1->push_back(DIR_SEPARATOR); - } - path1->append(path2); + path1->push_back(DIR_SEPARATOR); } + + path1->append(path2); } pal::string_t strip_executable_ext(const pal::string_t& filename) @@ -357,23 +360,33 @@ pal::string_t get_dotnet_root_env_var_for_arch(pal::architecture arch) bool get_dotnet_root_from_env(pal::string_t* dotnet_root_env_var_name, pal::string_t* recv) { - *dotnet_root_env_var_name = get_dotnet_root_env_var_for_arch(get_current_arch()); - if (get_file_path_from_env(dotnet_root_env_var_name->c_str(), recv)) + pal::string_t env_var_name = get_dotnet_root_env_var_for_arch(get_current_arch()); + if (get_file_path_from_env(env_var_name.c_str(), recv)) + { + *dotnet_root_env_var_name = env_var_name; return true; + } #if defined(WIN32) if (pal::is_running_in_wow64()) { - *dotnet_root_env_var_name = _X("DOTNET_ROOT(x86)"); - if (get_file_path_from_env(dotnet_root_env_var_name->c_str(), recv)) + if (get_file_path_from_env(_X("DOTNET_ROOT(x86)"), recv)) + { + *dotnet_root_env_var_name = _X("DOTNET_ROOT(x86)"); return true; + } } #endif // If no architecture-specific environment variable was set // fallback to the default DOTNET_ROOT. - *dotnet_root_env_var_name = DOTNET_ROOT_ENV_VAR; - return get_file_path_from_env(dotnet_root_env_var_name->c_str(), recv); + if (get_file_path_from_env(DOTNET_ROOT_ENV_VAR, recv)) + { + *dotnet_root_env_var_name = DOTNET_ROOT_ENV_VAR; + return true; + } + + return false; } /** diff --git a/src/native/corehost/hostmisc/utils.h b/src/native/corehost/hostmisc/utils.h index 124eb1100775fe..98674cc5007449 100644 --- a/src/native/corehost/hostmisc/utils.h +++ b/src/native/corehost/hostmisc/utils.h @@ -69,6 +69,15 @@ namespace utils { return starts_with(value, prefix, L - 1, match_case); } + + template + pal::string_t format_string(const pal::char_t* format, Args&&... args) + { + int len = pal::strlen_printf(format, std::forward(args)...) + 1; + std::vector buffer(len); + pal::str_printf(&buffer[0], len, format, std::forward(args)...); + return pal::string_t(buffer.data(), buffer.size() - 1); + } } pal::string_t strip_executable_ext(const pal::string_t& filename); @@ -76,7 +85,11 @@ pal::string_t get_directory(const pal::string_t& path); pal::string_t strip_file_ext(const pal::string_t& path); pal::string_t get_filename(const pal::string_t& path); pal::string_t get_filename_without_ext(const pal::string_t& path); + +// Concatenate path1 and path2 into path1, ensuring there is a directory separator. +// This does not check for rooted paths or make any attempt to root the returned path. void append_path(pal::string_t* path1, const pal::char_t* path2); + bool file_exists_in_dir(const pal::string_t& dir, const pal::char_t* file_name, pal::string_t* out_file_path); bool coreclr_exists_in_dir(const pal::string_t& candidate); void remove_trailing_dir_separator(pal::string_t* dir); diff --git a/src/native/corehost/hostpolicy/deps_entry.cpp b/src/native/corehost/hostpolicy/deps_entry.cpp index 981d86305e6921..1d294d7266b435 100644 --- a/src/native/corehost/hostpolicy/deps_entry.cpp +++ b/src/native/corehost/hostpolicy/deps_entry.cpp @@ -23,22 +23,23 @@ static pal::string_t normalize_dir_separator(const pal::string_t& path) // ----------------------------------------------------------------------------- // Given a "base" directory, determine the resolved path for this file. // -// * If this file exists within the single-file bundle candidate is -// the full-path to the extracted file. +// * If this file exists within the single-file bundle: +// - if extracted, candidate is the full-path to the extracted file. +// - if not extracted, candidate is empty. // * Otherwise, candidate is the full local path of the file. // // Parameters: // base - The base directory to look for the relative path of this entry -// ietf_dir - If this is a resource asset, the IETF intermediate directory -// str - (out parameter) If the method returns true, contains the file path for this deps entry +// relative_path - Relative path of to look for this entry +// str - (out) If the method returns true, contains the file path for this deps entry // search_options - Flags to instruct where to look for this deps entry -// found_in_bundle - (out parameter) True if the candidate is located within the single-file bundle. +// found_in_bundle - (out) True if the candidate is located within the single-file bundle and not extracted. // // Returns: // If the file exists in the path relative to the "base" directory within the // single-file or on disk. -bool deps_entry_t::to_path(const pal::string_t& base, const pal::string_t& ietf_dir, pal::string_t* str, uint32_t search_options, bool &found_in_bundle) const +static bool to_path(const pal::string_t& base, const pal::string_t& relative_path, pal::string_t* str, uint32_t search_options, bool &found_in_bundle) { pal::string_t& candidate = *str; @@ -51,17 +52,11 @@ bool deps_entry_t::to_path(const pal::string_t& base, const pal::string_t& ietf_ return false; } - pal::string_t normalized_path = normalize_dir_separator(asset.relative_path); - // Reserve space for the path below - candidate.reserve(base.length() + ietf_dir.length() + normalized_path.length() + 3); + candidate.reserve(base.length() + relative_path.length() + 2); // +2 for directory separator and null terminator - bool look_in_base = search_options & deps_entry_t::search_options::look_in_base; bool look_in_bundle = search_options & deps_entry_t::search_options::look_in_bundle; bool is_servicing = search_options & deps_entry_t::search_options::is_servicing; - pal::string_t file_path = look_in_base ? get_filename(normalized_path) : normalized_path; - pal::string_t sub_path = ietf_dir; - append_path(&sub_path, file_path.c_str()); assert(!is_servicing || !look_in_bundle); @@ -71,45 +66,44 @@ bool deps_entry_t::to_path(const pal::string_t& base, const pal::string_t& ietf_ if (app->has_base(base)) { - // If sub_path is found in the single-file bundle, + // If relative_path is found in the single-file bundle, // app::locate() will set candidate to the full-path to the assembly extracted out to disk. bool extracted_to_disk = false; - if (app->locate(sub_path, candidate, extracted_to_disk)) + if (app->locate(relative_path, candidate, extracted_to_disk)) { found_in_bundle = !extracted_to_disk; - trace::verbose(_X(" %s found in bundle [%s] %s"), sub_path.c_str(), candidate.c_str(), extracted_to_disk ? _X("(extracted)") : _X("")); + trace::verbose(_X(" %s found in bundle [%s] %s"), relative_path.c_str(), candidate.c_str(), extracted_to_disk ? _X("(extracted)") : _X("")); return true; } else { - trace::verbose(_X(" %s not found in bundle"), sub_path.c_str()); + trace::verbose(_X(" %s not found in bundle"), relative_path.c_str()); } } else { trace::verbose(_X(" %s not searched in bundle base path %s doesn't match bundle base %s."), - sub_path.c_str(), base.c_str(), app->base_path().c_str()); + relative_path.c_str(), base.c_str(), app->base_path().c_str()); } } candidate.assign(base); - append_path(&candidate, sub_path.c_str()); + append_path(&candidate, relative_path.c_str()); - const pal::char_t* query_type = look_in_base ? _X("Local") : _X("Relative"); if (search_options & deps_entry_t::search_options::file_existence) { if (!pal::file_exists(candidate)) { - trace::verbose(_X(" %s path query did not exist %s"), query_type, candidate.c_str()); + trace::verbose(_X(" Does not exist: %s"), candidate.c_str()); candidate.clear(); return false; } - trace::verbose(_X(" %s path query exists %s"), query_type, candidate.c_str()); + trace::verbose(_X(" Exists: %s"), candidate.c_str()); } else { - trace::verbose(_X(" %s path query %s (skipped file existence check)"), query_type, candidate.c_str()); + trace::verbose(_X(" Skipped file existence check: %s"), candidate.c_str()); } // If a file is resolved to the servicing directory, mark it as disabled in the bundle. @@ -123,9 +117,9 @@ bool deps_entry_t::to_path(const pal::string_t& base, const pal::string_t& ietf_ assert(!app->has_base(base)); assert(!found_in_bundle); - if (app->disable(sub_path)) + if (app->disable(relative_path)) { - trace::verbose(_X(" %s disabled in bundle because of servicing override %s"), sub_path.c_str(), candidate.c_str()); + trace::verbose(_X(" %s disabled in bundle because of servicing override %s"), relative_path.c_str(), candidate.c_str()); } } @@ -139,37 +133,54 @@ bool deps_entry_t::to_path(const pal::string_t& base, const pal::string_t& ietf_ // base - The base directory to look for the relative path of this entry // str - If the method returns true, contains the file path for this deps entry // search_options - Flags to instruct where to look for this deps entry -// look_in_bundle - Whether to look within the single-file bundle +// found_in_bundle - Whether the asset was found in the single-file bundle // // Returns: // If the file exists in the path relative to the "base" directory. // bool deps_entry_t::to_dir_path(const pal::string_t& base, pal::string_t* str, uint32_t search_options, bool& found_in_bundle) const { - pal::string_t ietf_dir; - - if (asset_type == asset_types::resources) + pal::string_t relative_path = normalize_dir_separator(asset.local_path); + if (relative_path.empty()) { - pal::string_t pal_relative_path = normalize_dir_separator(asset.relative_path); + relative_path = normalize_dir_separator(asset.relative_path); + if (library_type != _X("runtimepack")) // runtimepack assets set the path to the local path + { + pal::string_t file_name = get_filename(relative_path); - // Resources are represented as "lib///" in the deps.json. - // The is the "directory" in the pal_relative_path below, so extract it. - ietf_dir = get_directory(pal_relative_path); + // Compute the expected relative path for this asset. + // resource: / + // runtime/native: + if (asset_type == asset_types::resources) + { + // Resources are represented as "lib///" in the deps.json. + // The is the "directory" in the relative_path below, so extract it. + pal::string_t ietf_dir = get_directory(relative_path); - // get_directory returns with DIR_SEPARATOR appended that we need to remove. - remove_trailing_dir_separator(&ietf_dir); + // get_directory returns with DIR_SEPARATOR appended that we need to remove. + assert(ietf_dir.back() == DIR_SEPARATOR); + remove_trailing_dir_separator(&ietf_dir); - // Extract IETF code from "lib//" - ietf_dir = get_filename(ietf_dir); + // Extract IETF code from "lib//" + ietf_dir = get_filename(ietf_dir); - trace::verbose(_X("Detected a resource asset, will query dir/ietf-tag/resource base: %s ietf: %s asset: %s"), - base.c_str(), ietf_dir.c_str(), asset.name.c_str()); - } + trace::verbose(_X(" Detected a resource asset, will query // base: %s ietf: %s asset: %s"), + base.c_str(), ietf_dir.c_str(), asset.name.c_str()); + + relative_path = ietf_dir; + append_path(&relative_path, file_name.c_str()); + } + else + { + relative_path = std::move(file_name); + } + } + trace::verbose(_X(" Computed relative path: %s"), relative_path.c_str()); + } - search_options |= deps_entry_t::search_options::look_in_base; search_options &= ~deps_entry_t::search_options::is_servicing; - return to_path(base, ietf_dir, str, search_options, found_in_bundle); + return to_path(base, relative_path, str, search_options, found_in_bundle); } // ----------------------------------------------------------------------------- @@ -184,11 +195,10 @@ bool deps_entry_t::to_dir_path(const pal::string_t& base, pal::string_t* str, ui // Returns: // If the file exists in the path relative to the "base" directory. // -bool deps_entry_t::to_rel_path(const pal::string_t& base, pal::string_t* str, uint32_t search_options) const +bool deps_entry_t::to_package_path(const pal::string_t& base, pal::string_t* str, uint32_t search_options) const { bool found_in_bundle; - search_options &= ~deps_entry_t::search_options::look_in_base; - bool result = to_path(base, _X(""), str, search_options, found_in_bundle); + bool result = to_path(base, normalize_dir_separator(asset.relative_path), str, search_options, found_in_bundle); assert(!found_in_bundle); return result; } @@ -205,7 +215,7 @@ bool deps_entry_t::to_rel_path(const pal::string_t& base, pal::string_t* str, ui // Returns: // If the file exists in the path relative to the "base" directory. // -bool deps_entry_t::to_full_path(const pal::string_t& base, pal::string_t* str, uint32_t search_options) const +bool deps_entry_t::to_library_package_path(const pal::string_t& base, pal::string_t* str, uint32_t search_options) const { str->clear(); @@ -228,5 +238,5 @@ bool deps_entry_t::to_full_path(const pal::string_t& base, pal::string_t* str, u } search_options &= ~deps_entry_t::search_options::look_in_bundle; - return to_rel_path(new_base, str, search_options); + return to_package_path(new_base, str, search_options); } diff --git a/src/native/corehost/hostpolicy/deps_entry.h b/src/native/corehost/hostpolicy/deps_entry.h index ae769f799f43bc..0f1996ca632cc7 100644 --- a/src/native/corehost/hostpolicy/deps_entry.h +++ b/src/native/corehost/hostpolicy/deps_entry.h @@ -12,18 +12,23 @@ struct deps_asset_t { - deps_asset_t() : deps_asset_t(_X(""), _X(""), version_t(), version_t()) { } + deps_asset_t() : deps_asset_t(_X(""), _X(""), version_t(), version_t(), _X("")) { } deps_asset_t(const pal::string_t& name, const pal::string_t& relative_path, const version_t& assembly_version, const version_t& file_version) + : deps_asset_t(name, relative_path, assembly_version, file_version, _X("")) { } + + deps_asset_t(const pal::string_t& name, const pal::string_t& relative_path, const version_t& assembly_version, const version_t& file_version, const pal::string_t& local_path) : name(name) , relative_path(get_replaced_char(relative_path, _X('\\'), _X('/'))) // Deps file does not follow spec. It uses '\\', should use '/' , assembly_version(assembly_version) - , file_version(file_version) { } + , file_version(file_version) + , local_path(local_path.empty() ? pal::string_t() : get_replaced_char(local_path, _X('\\'), _X('/'))) { } pal::string_t name; pal::string_t relative_path; version_t assembly_version; version_t file_version; + pal::string_t local_path; }; struct deps_entry_t @@ -39,7 +44,7 @@ struct deps_entry_t enum search_options : uint32_t { none = 0x0, - look_in_base = 0x1, // Search entry as a relative path + // unused = 0x1, look_in_bundle = 0x2, // Look for entry within the single-file bundle is_servicing = 0x4, // Whether the base directory is the core-servicing directory file_existence = 0x8, // Check for entry file existence @@ -64,17 +69,10 @@ struct deps_entry_t bool to_dir_path(const pal::string_t& base, pal::string_t* str, uint32_t search_options, bool& found_in_bundle) const; // Given a "base" dir, yield the relative path in the package layout or servicing directory. - bool to_rel_path(const pal::string_t& base, pal::string_t* str, uint32_t search_options) const; + bool to_package_path(const pal::string_t& base, pal::string_t* str, uint32_t search_options) const; // Given a "base" dir, yield the relative path with package name/version in the package layout or servicing location. - bool to_full_path(const pal::string_t& base, pal::string_t* str, uint32_t search_options) const; - -private: - // Given a "base" dir, yield the filepath within this directory or relative to this directory based on "look_in_base" - // flag in "search_options". - // Returns a path within the single-file bundle, or a file on disk, - bool to_path(const pal::string_t& base, const pal::string_t& ietf_code, pal::string_t* str, uint32_t search_options, bool & found_in_bundle) const; - + bool to_library_package_path(const pal::string_t& base, pal::string_t* str, uint32_t search_options) const; }; #endif // __DEPS_ENTRY_H_ diff --git a/src/native/corehost/hostpolicy/deps_format.cpp b/src/native/corehost/hostpolicy/deps_format.cpp index 7a58f12bb067f2..2c263e7a406fbd 100644 --- a/src/native/corehost/hostpolicy/deps_format.cpp +++ b/src/native/corehost/hostpolicy/deps_format.cpp @@ -166,12 +166,13 @@ void deps_json_t::reconcile_libraries_with_targets( if (trace::is_enabled()) { - trace::info(_X(" Entry %zu for asset name: %s, relpath: %s, assemblyVersion %s, fileVersion %s"), + trace::info(_X(" Entry %zu for asset name: %s, relpath: %s, assemblyVersion %s, fileVersion %s, localPath %s"), m_deps_entries[i].size(), entry.asset.name.c_str(), entry.asset.relative_path.c_str(), entry.asset.assembly_version.as_str().c_str(), - entry.asset.file_version.as_str().c_str()); + entry.asset.file_version.as_str().c_str(), + entry.asset.local_path.empty() ? _X("(not set)") : entry.asset.local_path.c_str()); } m_deps_entries[i].push_back(std::move(entry)); @@ -405,31 +406,34 @@ void deps_json_t::process_runtime_targets(const json_parser_t::value_t& json, co version_t assembly_version, file_version; - const pal::string_t& assembly_version_str = get_optional_property(file.value, _X("assemblyVersion")); + pal::string_t assembly_version_str = get_optional_property(file.value, _X("assemblyVersion")); if (!assembly_version_str.empty()) { version_t::parse(assembly_version_str, &assembly_version); } - const pal::string_t& file_version_str = get_optional_property(file.value, _X("fileVersion")); + pal::string_t file_version_str = get_optional_property(file.value, _X("fileVersion")); if (!file_version_str.empty()) { version_t::parse(file_version_str, &file_version); } + pal::string_t local_path = get_optional_path(file.value, _X("localPath")); + pal::string_t file_name{file.name.GetString()}; - deps_asset_t asset(get_filename_without_ext(file_name), file_name, assembly_version, file_version); + deps_asset_t asset(get_filename_without_ext(file_name), file_name, assembly_version, file_version, local_path); const auto& rid = file.value[_X("rid")].GetString(); if (trace::is_enabled()) { - trace::info(_X(" %s asset: %s rid=%s assemblyVersion=%s fileVersion=%s"), + trace::info(_X(" %s asset: %s rid=%s assemblyVersion=%s fileVersion=%s localPath=%s"), deps_entry_t::s_known_asset_types[asset_type_index], asset.relative_path.c_str(), rid, asset.assembly_version.as_str().c_str(), - asset.file_version.as_str().c_str()); + asset.file_version.as_str().c_str(), + asset.local_path.empty() ? _X("(not set)") : asset.local_path.c_str()); } assets.libs[package.name.GetString()][asset_type_index].rid_assets[rid].push_back(asset); @@ -464,27 +468,30 @@ void deps_json_t::process_targets(const json_parser_t::value_t& json, const pal: { version_t assembly_version, file_version; - const pal::string_t& assembly_version_str = get_optional_property(file.value, _X("assemblyVersion")); + pal::string_t assembly_version_str = get_optional_property(file.value, _X("assemblyVersion")); if (assembly_version_str.length() > 0) { version_t::parse(assembly_version_str, &assembly_version); } - const pal::string_t& file_version_str = get_optional_property(file.value, _X("fileVersion")); + pal::string_t file_version_str = get_optional_property(file.value, _X("fileVersion")); if (file_version_str.length() > 0) { version_t::parse(file_version_str, &file_version); } + pal::string_t local_path = get_optional_path(file.value, _X("localPath")); + pal::string_t file_name{file.name.GetString()}; - deps_asset_t asset(get_filename_without_ext(file_name), file_name, assembly_version, file_version); + deps_asset_t asset(get_filename_without_ext(file_name), file_name, assembly_version, file_version, local_path); if (trace::is_enabled()) { - trace::info(_X(" %s assemblyVersion=%s fileVersion=%s"), + trace::info(_X(" %s assemblyVersion=%s fileVersion=%s localPath=%s"), asset.relative_path.c_str(), asset.assembly_version.as_str().c_str(), - asset.file_version.as_str().c_str()); + asset.file_version.as_str().c_str(), + asset.local_path.empty() ? _X("(not set)") : asset.local_path.c_str()); } asset_files.push_back(std::move(asset)); @@ -587,7 +594,10 @@ void deps_json_t::load(bool is_framework_dependent, std::functionc_str()); return true; @@ -340,9 +340,11 @@ bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::str } else { - // Non-rid assets, lookup in the published dir. + // Look up assets relative to the deps directory if (entry.to_dir_path(deps_dir, candidate, search_options | deps_entry_t::search_options::look_in_bundle, found_in_bundle)) { + // Bundles are expected to be RID-specific themselves, so RID-specific assets are not expected to be found in the bundle. + assert(!entry.is_rid_specific || !found_in_bundle); trace::verbose(_X(" Probed deps dir and matched '%s'"), candidate->c_str()); return true; } @@ -352,7 +354,7 @@ bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::str } else { - if (entry.to_full_path(config.probe_dir, candidate, search_options | (config.is_servicing() ? deps_entry_t::search_options::is_servicing : 0))) + if (entry.to_library_package_path(config.probe_dir, candidate, search_options | (config.is_servicing() ? deps_entry_t::search_options::is_servicing : 0))) { trace::verbose(_X(" Probed package dir and matched '%s'"), candidate->c_str()); return true; @@ -431,8 +433,8 @@ bool deps_resolver_t::resolve_tpa_list( return true; } - trace::info(_X("Processing TPA for deps entry [%s, %s, %s] with fx level: %d"), - entry.library_name.c_str(), entry.library_version.c_str(), entry.asset.relative_path.c_str(), fx_level); + trace::info(_X("Processing TPA for deps entry [%s, %s, %s, local_path: %s] with fx level: %d"), + entry.library_name.c_str(), entry.library_version.c_str(), entry.asset.relative_path.c_str(), entry.asset.local_path.empty() ? _X("") : entry.asset.local_path.c_str(), fx_level); pal::string_t resolved_path; @@ -779,8 +781,8 @@ bool deps_resolver_t::resolve_probe_dirs( return true; } - trace::verbose(_X("Processing native/culture for deps entry [%s, %s, %s]"), - entry.library_name.c_str(), entry.library_version.c_str(), entry.asset.relative_path.c_str()); + trace::verbose(_X("Processing native/culture for deps entry [%s, %s, %s, local_path: %s]"), + entry.library_name.c_str(), entry.library_version.c_str(), entry.asset.relative_path.c_str(), entry.asset.local_path.empty() ? _X("") : entry.asset.local_path.c_str()); bool found_in_bundle = false; if (probe_deps_entry(entry, deps_dir, fx_level, &candidate, found_in_bundle)) diff --git a/src/native/corehost/hostpolicy/hostpolicy_context.cpp b/src/native/corehost/hostpolicy/hostpolicy_context.cpp index b562d0e09ae408..e513472211f01b 100644 --- a/src/native/corehost/hostpolicy/hostpolicy_context.cpp +++ b/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) { @@ -222,7 +224,7 @@ int hostpolicy_context_t::initialize(const hostpolicy_init_t &hostpolicy_init, c // otherwise fail early. if (!bundle::info_t::is_single_file_bundle()) { - trace::error(_X("Could not resolve CoreCLR path. For more details, enable tracing by setting COREHOST_TRACE environment variable to 1")); + trace::error(_X("Could not resolve CoreCLR path. For more details, enable tracing by setting DOTNET_HOST_TRACE environment variable to 1")); return StatusCode::CoreClrResolveFailure; } diff --git a/src/native/corehost/json_parser.cpp b/src/native/corehost/json_parser.cpp index 7d6e8a9dd4f840..362c4d6b53c0e3 100644 --- a/src/native/corehost/json_parser.cpp +++ b/src/native/corehost/json_parser.cpp @@ -66,15 +66,16 @@ bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t get_line_column_from_offset(data, size, offset, &line, &column); - trace::error(_X("A JSON parsing exception occurred in [%s], offset %zu (line %d, column %d): %s"), - context.c_str(), offset, line, column, - rapidjson::GetParseError_En(m_document.GetParseError())); + m_parse_error = utils::format_string(_X("JSON parsing exception: %s [offset %zu: line %d, column %d]"), + rapidjson::GetParseError_En(m_document.GetParseError()), + offset, line, column + ); return false; } if (!m_document.IsObject()) { - trace::error(_X("Expected a JSON object in [%s]"), context.c_str()); + m_parse_error = _X("Expected a JSON object"); return false; } diff --git a/src/native/corehost/json_parser.h b/src/native/corehost/json_parser.h index eb0b5d19a67963..0ef5e66575f474 100644 --- a/src/native/corehost/json_parser.h +++ b/src/native/corehost/json_parser.h @@ -9,7 +9,7 @@ #define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0 // see https://github.com/Tencent/rapidjson/issues/1448 -// including windows.h on purpose to provoke a compile time problem as GetObject is a +// including windows.h on purpose to provoke a compile time problem as GetObject is a // macro that gets defined when windows.h is included #ifdef _WIN32 #define NOMINMAX @@ -35,6 +35,7 @@ class json_parser_t { using document_t = rapidjson::GenericDocument; const document_t& document() const { return m_document; } + const pal::string_t& get_error_message() const { return m_parse_error; } bool parse_raw_data(char* data, int64_t size, const pal::string_t& context); bool parse_file(const pal::string_t& path); @@ -56,6 +57,9 @@ class json_parser_t { // If a json file is parsed from a single-file bundle, the following fields represents // the location of this json file within the bundle. const bundle::location_t* m_bundle_location; + + // Error message from parsing + pal::string_t m_parse_error; }; #endif // __JSON_PARSER_H__ diff --git a/src/native/corehost/runtime_config.cpp b/src/native/corehost/runtime_config.cpp index 04081ddbbea482..c833610358a3fd 100644 --- a/src/native/corehost/runtime_config.cpp +++ b/src/native/corehost/runtime_config.cpp @@ -188,7 +188,7 @@ bool runtime_config_t::parse_opts(const json_parser_t::value_t& opts) m_is_framework_dependent = true; fx_reference_t fx_out; - if (!parse_framework(framework->value, fx_out)) + if (!parse_framework(framework->value, /*name_and_version_only*/ false, fx_out)) { return false; } @@ -201,7 +201,7 @@ bool runtime_config_t::parse_opts(const json_parser_t::value_t& opts) { m_is_framework_dependent = true; - if (!read_framework_array(iter->value, m_frameworks)) + if (!read_framework_array(iter->value, /*name_and_version_only*/ false, m_frameworks)) { return false; } @@ -216,7 +216,7 @@ bool runtime_config_t::parse_opts(const json_parser_t::value_t& opts) return false; } - if (!read_framework_array(includedFrameworks->value, m_included_frameworks, /*name_and_version_only*/ true)) + if (!read_framework_array(includedFrameworks->value, /*name_and_version_only*/ true, m_included_frameworks)) { return false; } @@ -241,7 +241,7 @@ namespace } } -bool runtime_config_t::parse_framework(const json_parser_t::value_t& fx_obj, fx_reference_t& fx_out, bool name_and_version_only) +bool runtime_config_t::parse_framework(const json_parser_t::value_t& fx_obj, bool name_and_version_only, fx_reference_t& fx_out) { if (!name_and_version_only) { @@ -249,27 +249,37 @@ bool runtime_config_t::parse_framework(const json_parser_t::value_t& fx_obj, fx_ } const auto& fx_name = fx_obj.FindMember(_X("name")); - if (fx_name != fx_obj.MemberEnd()) + if (fx_name == fx_obj.MemberEnd()) { - fx_out.set_fx_name(fx_name->value.GetString()); + using string_buffer_t = rapidjson::GenericStringBuffer; + string_buffer_t sb; + rapidjson::Writer writer{sb}; + fx_obj.Accept(writer); + + trace::error(_X("No framework name specified: %s"), sb.GetString()); + return false; } + fx_out.set_fx_name(fx_name->value.GetString()); + const auto& fx_ver = fx_obj.FindMember(_X("version")); - if (fx_ver != fx_obj.MemberEnd()) + if (fx_ver == fx_obj.MemberEnd()) { - fx_out.set_fx_version(fx_ver->value.GetString()); - - // Release version should prefer release versions, unless the rollForwardToPrerelease is set - // in which case no preference should be applied. - if (!name_and_version_only && !fx_out.get_fx_version_number().is_prerelease() && !m_roll_forward_to_prerelease) - { - fx_out.set_prefer_release(true); - } + trace::error(_X("Framework '%s' is missing a version."), fx_out.get_fx_name().c_str()); + return false; } + fx_out.set_fx_version(fx_ver->value.GetString()); + if (name_and_version_only) - { return true; + + // Release version should prefer release versions, unless the rollForwardToPrerelease is set + // in which case no preference should be applied. + if (!fx_out.get_fx_version_number().is_prerelease() && !m_roll_forward_to_prerelease) + { + fx_out.set_prefer_release(true); } const auto& roll_forward = fx_obj.FindMember(_X("rollForward")); @@ -357,25 +367,13 @@ bool runtime_config_t::ensure_dev_config_parsed() return true; } -bool runtime_config_t::read_framework_array(const json_parser_t::value_t& frameworks_json, fx_reference_vector_t& frameworks_out, bool name_and_version_only) +bool runtime_config_t::read_framework_array(const json_parser_t::value_t& frameworks_json, bool name_and_version_only, fx_reference_vector_t& frameworks_out) { - bool rc = true; - for (const auto& fx_json : frameworks_json.GetArray()) { fx_reference_t fx_out; - rc = parse_framework(fx_json, fx_out, name_and_version_only); - if (!rc) - { - break; - } - - if (fx_out.get_fx_name().length() == 0) - { - trace::verbose(_X("No framework name specified.")); - rc = false; - break; - } + if (!parse_framework(fx_json, name_and_version_only, fx_out)) + return false; if (std::find_if( frameworks_out.begin(), @@ -384,14 +382,13 @@ bool runtime_config_t::read_framework_array(const json_parser_t::value_t& framew != frameworks_out.end()) { trace::verbose(_X("Framework %s already specified."), fx_out.get_fx_name().c_str()); - rc = false; - break; + return false; } frameworks_out.push_back(fx_out); } - return rc; + return true; } bool runtime_config_t::ensure_parsed() @@ -412,6 +409,7 @@ bool runtime_config_t::ensure_parsed() json_parser_t json; if (!json.parse_file(m_path)) { + trace::error(_X("Failed to parse file [%s]. %s"), m_path.c_str(), json.get_error_message().c_str()); return false; } diff --git a/src/native/corehost/runtime_config.h b/src/native/corehost/runtime_config.h index 820684460d2748..c345f2d0163a14 100644 --- a/src/native/corehost/runtime_config.h +++ b/src/native/corehost/runtime_config.h @@ -79,8 +79,8 @@ class runtime_config_t // If set to true, all versions (including pre-release) are considered even if starting from a release framework reference. bool m_roll_forward_to_prerelease; - bool parse_framework(const json_parser_t::value_t& fx_obj, fx_reference_t& fx_out, bool name_and_version_only = false); - bool read_framework_array(const json_parser_t::value_t& frameworks, fx_reference_vector_t& frameworks_out, bool name_and_version_only = false); + bool parse_framework(const json_parser_t::value_t& fx_obj, bool name_and_version_only, fx_reference_t& fx_out); + bool read_framework_array(const json_parser_t::value_t& frameworks, bool name_and_version_only, fx_reference_vector_t& frameworks_out); bool mark_specified_setting(specified_setting setting); }; diff --git a/src/native/eventpipe/ds-eventpipe-protocol.c b/src/native/eventpipe/ds-eventpipe-protocol.c index 4f5e6daf299d5a..bac8ee6df9932c 100644 --- a/src/native/eventpipe/ds-eventpipe-protocol.c +++ b/src/native/eventpipe/ds-eventpipe-protocol.c @@ -920,7 +920,7 @@ eventpipe_protocol_helper_collect_tracing ( payload->serialization_format, payload->rundown_keyword, payload->stackwalk_requested, - payload->session_type == EP_SESSION_TYPE_IPCSTREAM ? ds_ipc_stream_get_stream_ref (stream) : NULL, + ds_ipc_stream_get_stream_ref (stream), NULL, NULL, user_events_data_fd); diff --git a/src/native/eventpipe/ds-ipc-pal-namedpipe.c b/src/native/eventpipe/ds-ipc-pal-namedpipe.c index 2444cb763c6496..0da47f5c772b14 100644 --- a/src/native/eventpipe/ds-ipc-pal-namedpipe.c +++ b/src/native/eventpipe/ds-ipc-pal-namedpipe.c @@ -213,7 +213,7 @@ ds_ipc_poll ( handles [i] = poll_handles_data [i].ipc->overlap.hEvent; if (handles [i] == INVALID_HANDLE_VALUE) { // Invalid handle, wait will fail. Signal error - poll_handles_data [i].events = DS_IPC_POLL_EVENTS_ERR; + poll_handles_data [i].events = IPC_POLL_EVENTS_ERR; } } else { // CLIENT @@ -238,7 +238,7 @@ ds_ipc_poll ( handles [i] = poll_handles_data [i].stream->overlap.hEvent; break; case ERROR_PIPE_NOT_CONNECTED: - poll_handles_data [i].events = (uint8_t)DS_IPC_POLL_EVENTS_HANGUP; + poll_handles_data [i].events = (uint8_t)IPC_POLL_EVENTS_HANGUP; result = -1; ep_raise_error (); default: @@ -288,7 +288,7 @@ ds_ipc_poll ( // check if we abandoned something DWORD abandonedIndex = wait - WAIT_ABANDONED_0; if (abandonedIndex > 0 || abandonedIndex < (poll_handles_data_len - 1)) { - poll_handles_data [abandonedIndex].events = (uint8_t)DS_IPC_POLL_EVENTS_HANGUP; + poll_handles_data [abandonedIndex].events = (uint8_t)IPC_POLL_EVENTS_HANGUP; result = -1; ep_raise_error (); } else { @@ -325,20 +325,20 @@ ds_ipc_poll ( if (!success) { DWORD error = GetLastError(); if (error == ERROR_PIPE_NOT_CONNECTED || error == ERROR_BROKEN_PIPE) { - poll_handles_data [index].events = (uint8_t)DS_IPC_POLL_EVENTS_HANGUP; + poll_handles_data [index].events = (uint8_t)IPC_POLL_EVENTS_HANGUP; } else { if (callback) callback ("Client connection error", error); - poll_handles_data [index].events = (uint8_t)DS_IPC_POLL_EVENTS_ERR; + poll_handles_data [index].events = (uint8_t)IPC_POLL_EVENTS_ERR; result = -1; ep_raise_error (); } } else { - poll_handles_data [index].events = (uint8_t)DS_IPC_POLL_EVENTS_SIGNALED; + poll_handles_data [index].events = (uint8_t)IPC_POLL_EVENTS_SIGNALED; } } else { // SERVER - poll_handles_data [index].events = (uint8_t)DS_IPC_POLL_EVENTS_SIGNALED; + poll_handles_data [index].events = (uint8_t)IPC_POLL_EVENTS_SIGNALED; } result = 1; @@ -694,7 +694,7 @@ ipc_stream_read_func ( DWORD error = GetLastError (); if (error == ERROR_IO_PENDING) { // if we're waiting infinitely, only make one syscall - if (timeout_ms == DS_IPC_TIMEOUT_INFINITE) { + if (timeout_ms == IPC_TIMEOUT_INFINITE) { DS_ENTER_BLOCKING_PAL_SECTION; success = GetOverlappedResult ( ipc_stream->pipe, // pipe @@ -765,7 +765,7 @@ ipc_stream_write_func ( DWORD error = GetLastError (); if (error == ERROR_IO_PENDING) { // if we're waiting infinitely, only make one syscall - if (timeout_ms == DS_IPC_TIMEOUT_INFINITE) { + if (timeout_ms == IPC_TIMEOUT_INFINITE) { DS_ENTER_BLOCKING_PAL_SECTION; success = GetOverlappedResult ( ipc_stream->pipe, // pipe @@ -834,12 +834,24 @@ ipc_stream_close_func (void *object) return ds_ipc_stream_close (ipc_stream, NULL); } +static +IpcPollEvents +ipc_stream_poll_func ( + void *object, + uint32_t timeout_ms) +{ + EP_ASSERT (!"ipc_stream_poll_func needs to be implemented for NamedPipes"); + // TODO: Implement ipc_stream_poll_func for NamedPipes + return IPC_POLL_EVENTS_UNKNOWN; +} + static IpcStreamVtable ipc_stream_vtable = { ipc_stream_free_func, ipc_stream_read_func, ipc_stream_write_func, ipc_stream_flush_func, - ipc_stream_close_func }; + ipc_stream_close_func, + ipc_stream_poll_func }; static DiagnosticsIpcStream * diff --git a/src/native/eventpipe/ds-ipc-pal-socket.c b/src/native/eventpipe/ds-ipc-pal-socket.c index 4a16fb5f81f253..c668c0851f070d 100644 --- a/src/native/eventpipe/ds-ipc-pal-socket.c +++ b/src/native/eventpipe/ds-ipc-pal-socket.c @@ -420,9 +420,7 @@ ipc_socket_close (ds_ipc_socket_t s) #ifdef HOST_WIN32 result_close = closesocket (s); #else - do { - result_close = close (s); - } while (ipc_retry_syscall (result_close)); + result_close = close (s); #endif DS_EXIT_BLOCKING_PAL_SECTION; return result_close; @@ -588,7 +586,7 @@ ipc_socket_connect ( // the server hasn't called `accept`, so no need to check for timeout or connect error. #if defined(DS_IPC_PAL_AF_INET) || defined(DS_IPC_PAL_AF_INET6) - if (timeout_ms != DS_IPC_TIMEOUT_INFINITE) { + if (timeout_ms != IPC_TIMEOUT_INFINITE) { // Set socket to none blocking. ipc_socket_set_blocking (s, false); } @@ -601,7 +599,7 @@ ipc_socket_connect ( DS_EXIT_BLOCKING_PAL_SECTION; #if defined(DS_IPC_PAL_AF_INET) || defined(DS_IPC_PAL_AF_INET6) - if (timeout_ms != DS_IPC_TIMEOUT_INFINITE) { + if (timeout_ms != IPC_TIMEOUT_INFINITE) { if (result_connect == DS_IPC_SOCKET_ERROR) { if (ipc_get_last_error () == DS_IPC_SOCKET_ERROR_WOULDBLOCK) { ds_ipc_pollfd_t pfd; @@ -627,7 +625,7 @@ ipc_socket_connect ( } } - if (timeout_ms != DS_IPC_TIMEOUT_INFINITE) { + if (timeout_ms != IPC_TIMEOUT_INFINITE) { // Reset socket to blocking. int last_error = ipc_get_last_error (); ipc_socket_set_blocking (s, true); @@ -1146,15 +1144,15 @@ ds_ipc_poll ( // check for hangup first because a closed socket // will technically meet the requirements for POLLIN // i.e., a call to recv/read won't block - poll_handles_data [i].events = (uint8_t)DS_IPC_POLL_EVENTS_HANGUP; + poll_handles_data [i].events = (uint8_t)IPC_POLL_EVENTS_HANGUP; } else if ((poll_fds [i].revents & (POLLERR|POLLNVAL))) { if (callback) callback ("Poll error", (uint32_t)poll_fds [i].revents); - poll_handles_data [i].events = (uint8_t)DS_IPC_POLL_EVENTS_ERR; + poll_handles_data [i].events = (uint8_t)IPC_POLL_EVENTS_ERR; } else if (poll_fds [i].revents & (POLLIN|POLLPRI)) { - poll_handles_data [i].events = (uint8_t)DS_IPC_POLL_EVENTS_SIGNALED; + poll_handles_data [i].events = (uint8_t)IPC_POLL_EVENTS_SIGNALED; } else { - poll_handles_data [i].events = (uint8_t)DS_IPC_POLL_EVENTS_UNKNOWN; + poll_handles_data [i].events = (uint8_t)IPC_POLL_EVENTS_UNKNOWN; if (callback) callback ("unknown poll response", (uint32_t)poll_fds [i].revents); } @@ -1401,7 +1399,7 @@ ipc_stream_read_func ( DiagnosticsIpcStream *ipc_stream = (DiagnosticsIpcStream *)object; ssize_t total_bytes_read = 0; - if (timeout_ms != DS_IPC_TIMEOUT_INFINITE) { + if (timeout_ms != IPC_TIMEOUT_INFINITE) { ds_ipc_pollfd_t pfd; pfd.fd = ipc_stream->client_socket; pfd.events = POLLIN; @@ -1445,7 +1443,7 @@ ipc_stream_write_func ( DiagnosticsIpcStream *ipc_stream = (DiagnosticsIpcStream *)object; ssize_t total_bytes_written = 0; - if (timeout_ms != DS_IPC_TIMEOUT_INFINITE) { + if (timeout_ms != IPC_TIMEOUT_INFINITE) { ds_ipc_pollfd_t pfd; pfd.fd = ipc_stream->client_socket; pfd.events = POLLOUT; @@ -1489,12 +1487,24 @@ ipc_stream_close_func (void *object) return ds_ipc_stream_close (ipc_stream, NULL); } +static +IpcPollEvents +ipc_stream_poll_func ( + void *object, + uint32_t timeout_ms) +{ + EP_ASSERT (object != NULL); + DiagnosticsIpcStream *ipc_stream = (DiagnosticsIpcStream *)object; + return ds_ipc_stream_poll (ipc_stream, timeout_ms); +} + static IpcStreamVtable ipc_stream_vtable = { ipc_stream_free_func, ipc_stream_read_func, ipc_stream_write_func, ipc_stream_flush_func, - ipc_stream_close_func }; + ipc_stream_close_func, + ipc_stream_poll_func }; static DiagnosticsIpcStream * @@ -1668,6 +1678,44 @@ ds_ipc_stream_to_string ( return (result > 0 && result < (int32_t)buffer_len) ? result : 0; } +IpcPollEvents +ds_ipc_stream_poll ( + DiagnosticsIpcStream *ipc_stream, + uint32_t timeout_ms) +{ + EP_ASSERT (ipc_stream != NULL); + + if (ipc_stream->client_socket == DS_IPC_INVALID_SOCKET) + return IPC_POLL_EVENTS_HANGUP; + + ds_ipc_pollfd_t pfd; + pfd.fd = ipc_stream->client_socket; + pfd.events = POLLIN | POLLPRI | POLLOUT; + + int result_poll; + result_poll = ipc_poll_fds (&pfd, 1, timeout_ms); + + if (result_poll < 0) + return IPC_POLL_EVENTS_ERR; + + if (result_poll == 0) + return IPC_POLL_EVENTS_NONE; + + if (pfd.revents == 0) + return IPC_POLL_EVENTS_NONE; + + if (pfd.revents & POLLHUP) + return IPC_POLL_EVENTS_HANGUP; + + if (pfd.revents & (POLLERR | POLLNVAL)) + return IPC_POLL_EVENTS_ERR; + + if (pfd.revents & (POLLIN | POLLPRI | POLLOUT)) + return IPC_POLL_EVENTS_SIGNALED; + + return IPC_POLL_EVENTS_UNKNOWN; +} + #endif /* ENABLE_PERFTRACING */ #ifndef DS_INCLUDE_SOURCE_FILES diff --git a/src/native/eventpipe/ds-ipc-pal-types.h b/src/native/eventpipe/ds-ipc-pal-types.h index d623fb22e400c1..7b75e998b3f0e4 100644 --- a/src/native/eventpipe/ds-ipc-pal-types.h +++ b/src/native/eventpipe/ds-ipc-pal-types.h @@ -22,21 +22,12 @@ typedef struct _DiagnosticsIpcStream DiagnosticsIpcStream; * Diagnostics IPC PAL Enums. */ -typedef enum { - DS_IPC_POLL_EVENTS_NONE = 0x00, // no events - DS_IPC_POLL_EVENTS_SIGNALED = 0x01, // ready for use - DS_IPC_POLL_EVENTS_HANGUP = 0x02, // connection remotely closed - DS_IPC_POLL_EVENTS_ERR = 0x04, // error - DS_IPC_POLL_EVENTS_UNKNOWN = 0x80 // unknown state -} DiagnosticsIpcPollEvents; - typedef enum { DS_IPC_CONNECTION_MODE_CONNECT, DS_IPC_CONNECTION_MODE_LISTEN } DiagnosticsIpcConnectionMode; #define DS_IPC_MAX_TO_STRING_LEN 128 -#define DS_IPC_TIMEOUT_INFINITE (uint32_t)-1 #define DS_IPC_POLL_TIMEOUT_FALLOFF_FACTOR (float)1.25 #define DS_IPC_POLL_TIMEOUT_MIN_MS (uint32_t)10 diff --git a/src/native/eventpipe/ds-ipc-pal-websocket.c b/src/native/eventpipe/ds-ipc-pal-websocket.c index 97eb89025a468a..a50fa1bfd4fb11 100644 --- a/src/native/eventpipe/ds-ipc-pal-websocket.c +++ b/src/native/eventpipe/ds-ipc-pal-websocket.c @@ -248,11 +248,11 @@ ds_ipc_poll ( int client_socket = poll_handles_data [i].stream->client_socket; int pending = ds_rt_websocket_poll (client_socket); if (pending < 0){ - poll_handles_data [i].events = (uint8_t)DS_IPC_POLL_EVENTS_ERR; + poll_handles_data [i].events = (uint8_t)IPC_POLL_EVENTS_ERR; return 1; } if (pending > 0){ - poll_handles_data [i].events = (uint8_t)DS_IPC_POLL_EVENTS_SIGNALED; + poll_handles_data [i].events = (uint8_t)IPC_POLL_EVENTS_SIGNALED; return 1; } } @@ -425,12 +425,24 @@ ipc_stream_close_func (void *object) return ds_ipc_stream_close (ipc_stream, NULL); } +static +IpcPollEvents +ipc_stream_poll_func ( + void *object, + uint32_t timeout_ms) +{ + EP_ASSERT (!"ipc_stream_poll_func needs to be implemented for WebSockets"); + // TODO: Implement ipc_stream_poll_func for WebSockets + return IPC_POLL_EVENTS_UNKNOWN; +} + static IpcStreamVtable ipc_stream_vtable = { ipc_stream_free_func, ipc_stream_read_func, ipc_stream_write_func, ipc_stream_flush_func, - ipc_stream_close_func }; + ipc_stream_close_func, + ipc_stream_poll_func }; static DiagnosticsIpcStream * diff --git a/src/native/eventpipe/ds-ipc-pal.h b/src/native/eventpipe/ds-ipc-pal.h index 362ea3925f92ba..3761099fb4ba66 100644 --- a/src/native/eventpipe/ds-ipc-pal.h +++ b/src/native/eventpipe/ds-ipc-pal.h @@ -140,5 +140,10 @@ ds_ipc_stream_to_string ( ep_char8_t *buffer, uint32_t buffer_len); +IpcPollEvents +ds_ipc_stream_poll ( + DiagnosticsIpcStream *ipc_stream, + uint32_t timeout_ms); + #endif /* ENABLE_PERFTRACING */ #endif /* __DIAGNOSTICS_IPC_PAL_H__ */ diff --git a/src/native/eventpipe/ds-ipc.c b/src/native/eventpipe/ds-ipc.c index 6527d5bbce706d..cb2b051cb9ed20 100644 --- a/src/native/eventpipe/ds-ipc.c +++ b/src/native/eventpipe/ds-ipc.c @@ -122,7 +122,7 @@ inline uint32_t ipc_stream_factory_get_next_timeout (uint32_t current_timeout_ms) { - if (current_timeout_ms == DS_IPC_TIMEOUT_INFINITE) + if (current_timeout_ms == IPC_TIMEOUT_INFINITE) return DS_IPC_POLL_TIMEOUT_MIN_MS; else return (current_timeout_ms >= DS_IPC_POLL_TIMEOUT_MAX_MS) ? @@ -361,7 +361,7 @@ ds_ipc_stream_factory_get_next_available_stream (ds_ipc_error_callback_func call DiagnosticsIpcStream *stream = NULL; - uint32_t poll_timeout_ms = DS_IPC_TIMEOUT_INFINITE; + uint32_t poll_timeout_ms = IPC_TIMEOUT_INFINITE; bool connect_success = true; uint32_t poll_attempts = 0; @@ -382,7 +382,7 @@ ds_ipc_stream_factory_get_next_available_stream (ds_ipc_error_callback_func call } DN_VECTOR_PTR_FOREACH_END; poll_timeout_ms = connect_success ? - DS_IPC_TIMEOUT_INFINITE : + IPC_TIMEOUT_INFINITE : ipc_stream_factory_get_next_timeout (poll_timeout_ms); int32_t ret_val; @@ -392,7 +392,7 @@ ds_ipc_stream_factory_get_next_available_stream (ds_ipc_error_callback_func call ipc_log_poll_handles (&ipc_poll_handles); ret_val = ds_ipc_poll (dn_vector_data_t (&ipc_poll_handles, DiagnosticsIpcPollHandle), dn_vector_size (&ipc_poll_handles), poll_timeout_ms, callback); } else { - if (poll_timeout_ms == DS_IPC_TIMEOUT_INFINITE) + if (poll_timeout_ms == IPC_TIMEOUT_INFINITE) poll_timeout_ms = DS_IPC_POLL_TIMEOUT_MAX_MS; DS_LOG_DEBUG_1 ("ds_ipc_stream_factory_get_next_available_stream - Nothing to poll, sleeping using timeout: %dms.", poll_timeout_ms); ep_rt_thread_sleep ((uint64_t)poll_timeout_ms * NUM_NANOSECONDS_IN_1_MS); @@ -406,13 +406,13 @@ ds_ipc_stream_factory_get_next_available_stream (ds_ipc_error_callback_func call DN_VECTOR_FOREACH_BEGIN (DiagnosticsIpcPollHandle, ipc_poll_handle, &ipc_poll_handles) { DiagnosticsPort *port = (DiagnosticsPort *)ipc_poll_handle.user_data; switch (ipc_poll_handle.events) { - case DS_IPC_POLL_EVENTS_HANGUP: + case IPC_POLL_EVENTS_HANGUP: EP_ASSERT (port != NULL); ds_port_reset_vcall (port, callback); DS_LOG_INFO_2 ("ds_ipc_stream_factory_get_next_available_stream - HUP :: Poll attempt: %d, connection %d hung up. Connect is reset.", poll_attempts, connection_id); poll_timeout_ms = DS_IPC_POLL_TIMEOUT_MIN_MS; break; - case DS_IPC_POLL_EVENTS_SIGNALED: + case IPC_POLL_EVENTS_SIGNALED: EP_ASSERT (port != NULL); if (!stream) { // only use first signaled stream; will get others on subsequent calls stream = ds_port_get_connected_stream_vcall (port, callback); @@ -422,12 +422,12 @@ ds_ipc_stream_factory_get_next_available_stream (ds_ipc_error_callback_func call } DS_LOG_DEBUG_2 ("ds_ipc_stream_factory_get_next_available_stream - SIG :: Poll attempt: %d, connection %d signalled.", poll_attempts, connection_id); break; - case DS_IPC_POLL_EVENTS_ERR: + case IPC_POLL_EVENTS_ERR: ds_port_reset_vcall ((DiagnosticsPort *)ipc_poll_handle.user_data, callback); DS_LOG_INFO_2 ("ds_ipc_stream_factory_get_next_available_stream - ERR :: Poll attempt: %d, connection %d errored. Connection is reset.", poll_attempts, connection_id); saw_error = true; break; - case DS_IPC_POLL_EVENTS_NONE: + case IPC_POLL_EVENTS_NONE: DS_LOG_INFO_2 ("ds_ipc_stream_factory_get_next_available_stream - NON :: Poll attempt: %d, connection %d had no events.", poll_attempts, connection_id); break; default: @@ -444,7 +444,7 @@ ds_ipc_stream_factory_get_next_available_stream (ds_ipc_error_callback_func call if (!stream && saw_error) { // Some errors can cause the poll to return instantly, we want to delay if we see an error to avoid // runaway CPU usage. - if (poll_timeout_ms == DS_IPC_TIMEOUT_INFINITE) + if (poll_timeout_ms == IPC_TIMEOUT_INFINITE) poll_timeout_ms = DS_IPC_POLL_TIMEOUT_MAX_MS; DS_LOG_DEBUG_1 ("ds_ipc_stream_factory_get_next_available_stream - Saw error, sleeping using timeout: %dms.", poll_timeout_ms); ep_rt_thread_sleep ((uint64_t)poll_timeout_ms * NUM_NANOSECONDS_IN_1_MS); diff --git a/src/native/eventpipe/ep-event.c b/src/native/eventpipe/ep-event.c index 62934f40b2cb9e..6fa146c395bd13 100644 --- a/src/native/eventpipe/ep-event.c +++ b/src/native/eventpipe/ep-event.c @@ -72,6 +72,7 @@ ep_event_alloc ( instance->level = level; instance->need_stack = need_stack; instance->enabled_mask = 0; + instance->metadata_written_mask = 0; if (metadata != NULL) { instance->metadata = ep_rt_byte_array_alloc (metadata_len); @@ -102,6 +103,30 @@ ep_event_free (EventPipeEvent *ep_event) ep_rt_object_free (ep_event); } +bool +ep_event_update_metadata_written_mask ( + EventPipeEvent *ep_event, + uint64_t session_mask, + bool enable) +{ + EP_ASSERT (ep_event != NULL); + EP_ASSERT (session_mask != 0); + + int64_t expected_value; + int64_t previous_value; + + do { + expected_value = ep_rt_volatile_load_int64_t (&ep_event->metadata_written_mask); + if (((expected_value & session_mask) != 0) == enable) + return false; // Already set to the desired state. + + int64_t new_value = enable ? (expected_value | session_mask) : (expected_value & ~session_mask); + previous_value = ep_rt_atomic_compare_exchange_int64_t (&ep_event->metadata_written_mask, expected_value, new_value); + } while (previous_value != expected_value); + + return true; +} + #endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ #endif /* ENABLE_PERFTRACING */ diff --git a/src/native/eventpipe/ep-event.h b/src/native/eventpipe/ep-event.h index 82be8799334773..292c7917fbe264 100644 --- a/src/native/eventpipe/ep-event.h +++ b/src/native/eventpipe/ep-event.h @@ -26,6 +26,9 @@ struct _EventPipeEvent_Internal { uint64_t keywords; // The ith bit is 1 iff the event is enabled for the ith session. volatile int64_t enabled_mask; + // The ith bit is 1 iff the event metadata has been written for the ith session. + // Currently, bits are only enabled in user_events sessions. + volatile int64_t metadata_written_mask; // Metadata uint8_t *metadata; // The provider that contains the event. @@ -51,6 +54,7 @@ struct _EventPipeEvent { EP_DEFINE_GETTER(EventPipeEvent *, event, uint64_t, keywords) EP_DEFINE_GETTER_REF(EventPipeEvent *, event, volatile int64_t *, enabled_mask) EP_DEFINE_SETTER(EventPipeEvent *, event, int64_t, enabled_mask) +EP_DEFINE_GETTER_REF(EventPipeEvent *, event, volatile int64_t *, metadata_written_mask) EP_DEFINE_GETTER(EventPipeEvent *, event, uint8_t *, metadata) EP_DEFINE_GETTER(EventPipeEvent *, event, EventPipeProvider *, provider) EP_DEFINE_GETTER(EventPipeEvent *, event, uint32_t, event_id) @@ -92,5 +96,22 @@ ep_event_alloc ( void ep_event_free (EventPipeEvent * ep_event); +static +inline +bool +ep_event_was_metadata_written ( + const EventPipeEvent *ep_event, + uint64_t session_mask) +{ + EP_ASSERT (ep_event != NULL); + return ((ep_rt_volatile_load_int64_t (ep_event_get_metadata_written_mask_cref (ep_event)) & session_mask) != 0); +} + +bool +ep_event_update_metadata_written_mask ( + EventPipeEvent *ep_event, + uint64_t session_mask, + bool enable); + #endif /* ENABLE_PERFTRACING */ #endif /* __EVENTPIPE_EVENT_H__ */ diff --git a/src/native/eventpipe/ep-ipc-pal-types.h b/src/native/eventpipe/ep-ipc-pal-types.h index a353b8a3c104c8..574654fd64bfc3 100644 --- a/src/native/eventpipe/ep-ipc-pal-types.h +++ b/src/native/eventpipe/ep-ipc-pal-types.h @@ -11,5 +11,19 @@ #include "ep-ipc-pal-types-forward.h" +/* + * Shared Diagnostics/EventPipe IPC PAL Enums. + */ + +typedef enum { + IPC_POLL_EVENTS_NONE = 0x00, // no events + IPC_POLL_EVENTS_SIGNALED = 0x01, // ready for use + IPC_POLL_EVENTS_HANGUP = 0x02, // connection remotely closed + IPC_POLL_EVENTS_ERR = 0x04, // error + IPC_POLL_EVENTS_UNKNOWN = 0x80 // unknown state +} IpcPollEvents; + +#define IPC_TIMEOUT_INFINITE (uint32_t)-1 + #endif /* ENABLE_PERFTRACING */ #endif /* __EVENTPIPE_IPC_PAL_TYPES_H__ */ diff --git a/src/native/eventpipe/ep-ipc-stream.h b/src/native/eventpipe/ep-ipc-stream.h index eeb615675de4dc..633edfa976dc83 100644 --- a/src/native/eventpipe/ep-ipc-stream.h +++ b/src/native/eventpipe/ep-ipc-stream.h @@ -21,6 +21,7 @@ typedef bool (*IpcStreamReadFunc)(void *object, uint8_t *buffer, uint32_t bytes_ typedef bool (*IpcStreamWriteFunc)(void *object, const uint8_t *buffer, uint32_t bytes_to_write, uint32_t *bytes_written, uint32_t timeout_ms); typedef bool (*IpcStreamFlushFunc)(void *object); typedef bool (*IpcStreamCloseFunc)(void *object); +typedef IpcPollEvents (*IpcStreamPollFunc)(void *object, uint32_t timeout_ms); struct _IpcStreamVtable { IpcStreamFreeFunc free_func; @@ -28,6 +29,7 @@ struct _IpcStreamVtable { IpcStreamWriteFunc write_func; IpcStreamFlushFunc flush_func; IpcStreamCloseFunc close_func; + IpcStreamPollFunc poll_func; }; #if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_IPC_STREAM_GETTER_SETTER) || defined(DS_IMPL_IPC_PAL_NAMEDPIPE_GETTER_SETTER) || defined(DS_IMPL_IPC_PAL_SOCKET_GETTER_SETTER) @@ -77,5 +79,8 @@ ep_ipc_stream_flush_vcall (IpcStream *ipc_stream); bool ep_ipc_stream_close_vcall (IpcStream *ipc_stream); +IpcPollEvents +ep_ipc_stream_poll_vcall (IpcStream *ipc_stream, uint32_t timeout_ms); + #endif /* ENABLE_PERFTRACING */ #endif /* __EVENTPIPE_IPC_STREAM_H__ */ diff --git a/src/native/eventpipe/ep-provider.c b/src/native/eventpipe/ep-provider.c index 7a2fd1cb533834..2a2bd2510b21e3 100644 --- a/src/native/eventpipe/ep-provider.c +++ b/src/native/eventpipe/ep-provider.c @@ -35,12 +35,16 @@ provider_prepare_callback_data ( // _Requires_lock_held (ep) static void -provider_refresh_all_events (EventPipeProvider *provider); +provider_refresh_all_events ( + EventPipeProvider *provider, + uint64_t session_mask); // _Requires_lock_held (ep) static void -provider_refresh_event_state (EventPipeEvent *ep_event); +provider_refresh_event_state ( + EventPipeEvent *ep_event, + uint64_t session_mask); // Compute the enabled bit mask, the ith bit is 1 iff an event with the // given (provider, keywords, eventLevel) is enabled for the ith session. @@ -96,7 +100,9 @@ provider_prepare_callback_data ( static void -provider_refresh_all_events (EventPipeProvider *provider) +provider_refresh_all_events ( + EventPipeProvider *provider, + uint64_t session_mask) { EP_ASSERT (provider != NULL); @@ -105,7 +111,7 @@ provider_refresh_all_events (EventPipeProvider *provider) EP_ASSERT (provider->event_list != NULL); DN_LIST_FOREACH_BEGIN (EventPipeEvent *, current_event, provider->event_list) { - provider_refresh_event_state (current_event); + provider_refresh_event_state (current_event, session_mask); } DN_LIST_FOREACH_END; ep_requires_lock_held (); @@ -114,7 +120,9 @@ provider_refresh_all_events (EventPipeProvider *provider) static void -provider_refresh_event_state (EventPipeEvent *ep_event) +provider_refresh_event_state ( + EventPipeEvent *ep_event, + uint64_t session_mask) { EP_ASSERT (ep_event != NULL); @@ -129,6 +137,11 @@ provider_refresh_event_state (EventPipeEvent *ep_event) int64_t enable_mask = provider_compute_event_enable_mask (config, provider, ep_event); ep_event_set_enabled_mask (ep_event, enable_mask); + // If session_mask is not zero, that session is being enabled/disabled. + // We need to unset the metadata_written_mask for this session. + if (session_mask != 0) + ep_event_update_metadata_written_mask (ep_event, session_mask, false); + ep_requires_lock_held (); return; } @@ -277,7 +290,7 @@ ep_provider_add_event ( // Take the config lock before inserting a new event. EP_LOCK_ENTER (section1) ep_raise_error_if_nok_holding_lock (dn_list_push_back (provider->event_list, instance), section1); - provider_refresh_event_state (instance); + provider_refresh_event_state (instance, 0); EP_LOCK_EXIT (section1) ep_on_exit: @@ -323,7 +336,7 @@ provider_set_config ( provider->keywords = keywords_for_all_sessions; provider->provider_level = level_for_all_sessions; - provider_refresh_all_events (provider); + provider_refresh_all_events (provider, session_mask); provider_prepare_callback_data (provider, provider->keywords, provider->provider_level, filter_data, callback_data, session_id); ep_requires_lock_held (); @@ -352,7 +365,7 @@ provider_unset_config ( provider->keywords = keywords_for_all_sessions; provider->provider_level = level_for_all_sessions; - provider_refresh_all_events (provider); + provider_refresh_all_events (provider, session_mask); provider_prepare_callback_data (provider, provider->keywords, provider->provider_level, filter_data, callback_data, (EventPipeSessionID)0); ep_requires_lock_held (); @@ -517,7 +530,7 @@ provider_add_event ( ep_raise_error_if_nok (instance != NULL); ep_raise_error_if_nok (dn_list_push_back (provider->event_list, instance)); - provider_refresh_event_state (instance); + provider_refresh_event_state (instance, 0); ep_on_exit: ep_requires_lock_held (); diff --git a/src/native/eventpipe/ep-rt.h b/src/native/eventpipe/ep-rt.h index 5e04d25d4dda68..ef28cb5147240c 100644 --- a/src/native/eventpipe/ep-rt.h +++ b/src/native/eventpipe/ep-rt.h @@ -79,6 +79,10 @@ static int64_t ep_rt_atomic_dec_int64_t (volatile int64_t *value); +static +int64_t +ep_rt_atomic_compare_exchange_int64_t (volatile int64_t *target, int64_t expected, int64_t value); + static size_t ep_rt_atomic_compare_exchange_size_t (volatile size_t *target, size_t expected, size_t value); diff --git a/src/native/eventpipe/ep-session.c b/src/native/eventpipe/ep-session.c index ac9cf1d7e36320..4340fada3de059 100644 --- a/src/native/eventpipe/ep-session.c +++ b/src/native/eventpipe/ep-session.c @@ -9,7 +9,9 @@ #include "ep-config.h" #include "ep-event.h" #include "ep-file.h" +#include "ep-ipc-stream.h" #include "ep-session.h" +#include "ep-stream.h" #include "ep-event-payload.h" #include "ep-rt.h" @@ -76,6 +78,10 @@ session_tracepoint_write_event ( ep_rt_thread_handle_t event_thread, EventPipeStackContents *stack); +static +bool +session_is_stream_connection_closed (IpcStream *stream); + /* * EventPipeSession. */ @@ -91,7 +97,7 @@ EP_RT_DEFINE_THREAD_FUNC (streaming_thread) ep_rt_thread_params_t *thread_params = (ep_rt_thread_params_t *)data; EventPipeSession *const session = (EventPipeSession *)thread_params->thread_params; - if (session->session_type != EP_SESSION_TYPE_IPCSTREAM && session->session_type != EP_SESSION_TYPE_FILESTREAM) + if (!ep_session_type_uses_streaming_thread (session->session_type)) return 1; if (!thread_params->thread || !ep_rt_thread_has_started (thread_params->thread)) @@ -100,28 +106,44 @@ EP_RT_DEFINE_THREAD_FUNC (streaming_thread) session->streaming_thread = thread_params->thread; bool success = true; - ep_rt_wait_event_handle_t *wait_event = ep_session_get_wait_event (session); ep_rt_volatile_store_uint32_t (&session->started, 1); EP_GCX_PREEMP_ENTER - while (ep_session_get_streaming_enabled (session)) { - bool events_written = false; - if (!ep_session_write_all_buffers_to_file (session, &events_written)) { - success = false; - break; - } + if (ep_session_type_uses_buffer_manager (session->session_type)) { + ep_rt_wait_event_handle_t *wait_event = ep_session_get_wait_event (session); + while (ep_session_get_streaming_enabled (session)) { + bool events_written = false; + if (!ep_session_write_all_buffers_to_file (session, &events_written)) { + success = false; + break; + } + + if (!events_written) { + // No events were available, sleep until more are available + ep_rt_wait_event_wait (wait_event, EP_INFINITE_WAIT, false); + } - if (!events_written) { - // No events were available, sleep until more are available - ep_rt_wait_event_wait (wait_event, EP_INFINITE_WAIT, false); + // Wait until it's time to sample again. + const uint32_t timeout_ns = 100000000; // 100 msec. + ep_rt_thread_sleep (timeout_ns); } + } else if (session->session_type == EP_SESSION_TYPE_USEREVENTS) { + // In a user events session we only monitor the stream to stop the session if it closes. + while (ep_session_get_streaming_enabled (session)) { + EP_ASSERT (session->stream != NULL); + if (session_is_stream_connection_closed (session->stream)) { + success = false; + break; + } - // Wait until it's time to sample again. - const uint32_t timeout_ns = 100000000; // 100 msec. - ep_rt_thread_sleep (timeout_ns); + // Wait until it's time to poll again. + const uint32_t timeout_ns = 100000000; // 100 msec. + ep_rt_thread_sleep (timeout_ns); + } + } else { + EP_UNREACHABLE ("Unsupported session type for streaming thread."); } - session->streaming_thread = NULL; ep_rt_wait_event_set (&session->rt_thread_shutdown_event); EP_GCX_PREEMP_EXIT @@ -159,19 +181,19 @@ void session_create_streaming_thread (EventPipeSession *session) { EP_ASSERT (session != NULL); - EP_ASSERT (session->session_type == EP_SESSION_TYPE_IPCSTREAM || session->session_type == EP_SESSION_TYPE_FILESTREAM); + EP_ASSERT (ep_session_type_uses_streaming_thread (session->session_type)); ep_requires_lock_held (); ep_session_set_streaming_enabled (session, true); ep_rt_wait_event_alloc (&session->rt_thread_shutdown_event, true, false); if (!ep_rt_wait_event_is_valid (&session->rt_thread_shutdown_event)) - EP_UNREACHABLE ("Unable to create stream flushing thread shutdown event."); + EP_UNREACHABLE ("Unable to create streaming thread shutdown event."); #ifndef PERFTRACING_DISABLE_THREADS ep_rt_thread_id_t thread_id = ep_rt_uint64_t_to_thread_id_t (0); if (!ep_rt_thread_create ((void *)streaming_thread, (void *)session, EP_THREAD_TYPE_SESSION, &thread_id)) - EP_UNREACHABLE ("Unable to create stream flushing thread."); + EP_UNREACHABLE ("Unable to create streaming thread."); #else ep_session_inc_ref (session); ep_rt_volatile_store_uint32_t (&session->started, 1); @@ -183,18 +205,19 @@ static void session_disable_streaming_thread (EventPipeSession *session) { - EP_ASSERT (session->session_type == EP_SESSION_TYPE_IPCSTREAM || session->session_type == EP_SESSION_TYPE_FILESTREAM); + EP_ASSERT (ep_session_type_uses_streaming_thread (session->session_type)); EP_ASSERT (ep_session_get_streaming_enabled (session)); EP_ASSERT (!ep_rt_process_detach ()); - EP_ASSERT (session->buffer_manager != NULL); + EP_ASSERT (!ep_session_type_uses_buffer_manager (session->session_type) || session->buffer_manager != NULL); // The streaming thread will watch this value and exit // when profiling is disabled. ep_session_set_streaming_enabled (session, false); // Thread could be waiting on the event that there is new data to read. - ep_rt_wait_event_set (ep_buffer_manager_get_rt_wait_event_ref (session->buffer_manager)); + if (ep_session_type_uses_buffer_manager (session->session_type)) + ep_rt_wait_event_set (ep_buffer_manager_get_rt_wait_event_ref (session->buffer_manager)); // Wait for the streaming thread to clean itself up. ep_rt_wait_event_handle_t *rt_thread_shutdown_event = &session->rt_thread_shutdown_event; @@ -202,6 +225,15 @@ session_disable_streaming_thread (EventPipeSession *session) ep_rt_wait_event_free (rt_thread_shutdown_event); } +static +bool +session_is_stream_connection_closed (IpcStream *stream) +{ + EP_ASSERT (stream != NULL); + IpcPollEvents poll_event = ep_ipc_stream_poll_vcall (stream, IPC_TIMEOUT_INFINITE); + return poll_event == IPC_POLL_EVENTS_HANGUP || poll_event == IPC_POLL_EVENTS_ERR; +} + /* * session_user_events_tracepoints_init * @@ -282,6 +314,8 @@ ep_session_alloc ( instance->rundown_keyword = rundown_keyword; instance->synchronous_callback = sync_callback; instance->callback_additional_data = callback_additional_data; + instance->user_events_data_fd = -1; + instance->stream = NULL; // Hard coded 10MB for now, we'll probably want to make // this configurable later. @@ -320,6 +354,7 @@ ep_session_alloc ( case EP_SESSION_TYPE_USEREVENTS: // With the user_events_data file, register tracepoints for each provider's tracepoint configurations ep_raise_error_if_nok (session_user_events_tracepoints_init (instance, user_events_data_fd)); + instance->stream = stream; break; default: @@ -550,7 +585,7 @@ ep_session_start_streaming (EventPipeSession *session) if (session->file != NULL) ep_file_initialize_file (session->file); - if (session->session_type == EP_SESSION_TYPE_IPCSTREAM || session->session_type == EP_SESSION_TYPE_FILESTREAM) + if (ep_session_type_uses_streaming_thread (session->session_type)) session_create_streaming_thread (session); if (session->session_type == EP_SESSION_TYPE_SYNCHRONOUS) { @@ -558,7 +593,7 @@ ep_session_start_streaming (EventPipeSession *session) EP_ASSERT (!ep_session_get_streaming_enabled (session)); } - if (session->session_type != EP_SESSION_TYPE_IPCSTREAM && session->session_type != EP_SESSION_TYPE_FILESTREAM) + if (!ep_session_type_uses_streaming_thread (session->session_type)) ep_rt_volatile_store_uint32_t_without_barrier (&session->started, 1); ep_requires_lock_held (); @@ -590,7 +625,7 @@ ep_session_disable (EventPipeSession *session) { EP_ASSERT (session != NULL); - if ((session->session_type == EP_SESSION_TYPE_IPCSTREAM || session->session_type == EP_SESSION_TYPE_FILESTREAM) && ep_session_get_streaming_enabled (session)) + if ((ep_session_type_uses_streaming_thread (session->session_type)) && ep_session_get_streaming_enabled (session)) session_disable_streaming_thread (session); if (session->session_type == EP_SESSION_TYPE_USEREVENTS) @@ -730,10 +765,11 @@ session_tracepoint_write_event ( return false; // Setup iovec array - const int max_non_parameter_iov = 8; + const int max_non_parameter_iov = 9; const int max_static_io_capacity = 30; // Should account for most events that use EventData structs struct iovec static_io[max_static_io_capacity]; struct iovec *io = static_io; + ssize_t io_bytes_to_write = 0; uint8_t *ep_event_data = ep_event_payload_get_data (ep_event_payload); uint32_t ep_event_data_len = ep_event_payload_get_event_data_len (ep_event_payload); @@ -752,12 +788,14 @@ session_tracepoint_write_event ( io[io_index].iov_base = (void *)&write_index; io[io_index].iov_len = sizeof(write_index); io_index++; + io_bytes_to_write += sizeof(write_index); // Version uint8_t version = 0x01; // Format V1 io[io_index].iov_base = &version; io[io_index].iov_len = sizeof(version); io_index++; + io_bytes_to_write += sizeof(version); // Truncated event id // For parity with EventSource, there shouldn't be any that need more than 16 bits. @@ -765,35 +803,55 @@ session_tracepoint_write_event ( io[io_index].iov_base = &truncated_event_id; io[io_index].iov_len = sizeof(truncated_event_id); io_index++; + io_bytes_to_write += sizeof(truncated_event_id); // Extension and payload relative locations (to be fixed up later) uint32_t extension_rel_loc = 0; io[io_index].iov_base = &extension_rel_loc; io[io_index].iov_len = sizeof(extension_rel_loc); io_index++; + io_bytes_to_write += sizeof(extension_rel_loc); uint32_t payload_rel_loc = 0; io[io_index].iov_base = &payload_rel_loc; io[io_index].iov_len = sizeof(payload_rel_loc); io_index++; + io_bytes_to_write += sizeof(payload_rel_loc); // Extension uint32_t extension_len = 0; - // Extension Event Metadata - uint32_t metadata_len = ep_event_get_metadata_len (ep_event); - uint8_t extension_metadata[1 + sizeof(uint32_t)]; - extension_metadata[0] = 0x01; // label - *(uint32_t*)&extension_metadata[1] = metadata_len; - io[io_index].iov_base = extension_metadata; - io[io_index].iov_len = sizeof(extension_metadata); - io_index++; - extension_len += sizeof(extension_metadata); + uint64_t session_mask = ep_session_get_mask (session); + bool should_write_metadata = !ep_event_was_metadata_written (ep_event, session_mask); + uint8_t extension_metadata[1 + sizeof(uint32_t)] = {0}; + if (should_write_metadata) { + EventPipeProvider *event_provider = ep_event_get_provider (ep_event); + const ep_char16_t *provider_name_utf16 = ep_provider_get_provider_name_utf16 (event_provider); + uint32_t provider_name_len = (uint32_t)ep_rt_utf16_string_len (provider_name_utf16); + uint32_t provider_name_size_bytes = (provider_name_len + 1) * sizeof (ep_char16_t); + uint32_t event_metadata_len = ep_event_get_metadata_len (ep_event); + uint32_t complete_metadata_len = provider_name_size_bytes + event_metadata_len; + + extension_metadata[0] = 0x01; // label + *(uint32_t*)&extension_metadata[1] = complete_metadata_len; + io[io_index].iov_base = extension_metadata; + io[io_index].iov_len = sizeof(extension_metadata); + io_index++; + extension_len += sizeof(extension_metadata); + io_bytes_to_write += sizeof(extension_metadata); - io[io_index].iov_base = (void *)ep_event_get_metadata (ep_event); - io[io_index].iov_len = metadata_len; - io_index++; - extension_len += metadata_len; + io[io_index].iov_base = (void *)provider_name_utf16; + io[io_index].iov_len = provider_name_size_bytes; + io_index++; + extension_len += provider_name_size_bytes; + io_bytes_to_write += provider_name_size_bytes; + + io[io_index].iov_base = (void *)ep_event_get_metadata (ep_event); + io[io_index].iov_len = event_metadata_len; + io_index++; + extension_len += event_metadata_len; + io_bytes_to_write += event_metadata_len; + } // Extension Activity IDs const int extension_activity_ids_max_len = 2 * (1 + EP_ACTIVITY_ID_SIZE); @@ -804,6 +862,7 @@ session_tracepoint_write_event ( io[io_index].iov_len = extension_activity_ids_len; io_index++; extension_len += extension_activity_ids_len; + io_bytes_to_write += extension_activity_ids_len; EP_ASSERT (io_index <= max_non_parameter_iov); @@ -815,6 +874,7 @@ session_tracepoint_write_event ( io[io_index].iov_len = ep_event_payload_size; io_index++; ep_event_payload_total_size += ep_event_payload_size; + io_bytes_to_write += ep_event_payload_size; } else { const EventData *event_data = ep_event_payload_get_event_data (ep_event_payload); for (uint32_t i = 0; i < ep_event_data_len; ++i) { @@ -823,6 +883,7 @@ session_tracepoint_write_event ( io[io_index].iov_len = ep_event_data_size; io_index++; ep_event_payload_total_size += ep_event_data_size; + io_bytes_to_write += ep_event_data_size; } } @@ -837,7 +898,9 @@ session_tracepoint_write_event ( payload_rel_loc = ep_event_payload_total_size << 16 | (extension_len & 0xFFFF); ssize_t bytes_written; - while ((bytes_written = writev(session->user_events_data_fd, (const struct iovec *)io, io_index) < 0) && errno == EINTR); + while (((bytes_written = writev(session->user_events_data_fd, (const struct iovec *)io, io_index)) < 0) && errno == EINTR); + if (should_write_metadata && (bytes_written == io_bytes_to_write)) + ep_event_update_metadata_written_mask (ep_event, session_mask, true); if (io != static_io) free (io); @@ -945,8 +1008,8 @@ ep_session_get_next_event (EventPipeSession *session) EP_ASSERT (session != NULL); ep_requires_lock_not_held (); - if (!session->buffer_manager) { - EP_ASSERT (!"Shouldn't call get_next_event on a synchronous session."); + if (!ep_session_type_uses_buffer_manager (session->session_type)) { + EP_ASSERT (!"Shouldn't call get_next_event on a session that doesn't use the buffer manager."); return NULL; } @@ -958,8 +1021,8 @@ ep_session_get_wait_event (EventPipeSession *session) { EP_ASSERT (session != NULL); - if (!session->buffer_manager) { - EP_ASSERT (!"Shouldn't call get_wait_event on a synchronous session."); + if (!ep_session_type_uses_buffer_manager (session->session_type)) { + EP_ASSERT (!"Shouldn't call get_wait_event on a session that doesn't use the buffer manager."); return NULL; } @@ -1032,6 +1095,12 @@ ep_session_type_uses_buffer_manager (EventPipeSessionType session_type) return (session_type != EP_SESSION_TYPE_SYNCHRONOUS && session_type != EP_SESSION_TYPE_USEREVENTS); } +bool +ep_session_type_uses_streaming_thread (EventPipeSessionType session_type) +{ + return (session_type == EP_SESSION_TYPE_IPCSTREAM || session_type == EP_SESSION_TYPE_FILESTREAM || session_type == EP_SESSION_TYPE_USEREVENTS); +} + #endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ #endif /* ENABLE_PERFTRACING */ diff --git a/src/native/eventpipe/ep-session.h b/src/native/eventpipe/ep-session.h index 56af80bf3438ed..0617a876287862 100644 --- a/src/native/eventpipe/ep-session.h +++ b/src/native/eventpipe/ep-session.h @@ -71,6 +71,9 @@ struct _EventPipeSession_Internal { volatile uint32_t ref_count; // The user_events_data file descriptor to register Tracepoints and write user_events to. int user_events_data_fd; + // The IPC continuation stream from initializing the session through the diagnostic server + // Currently only initialized for user_events sessions. + IpcStream *stream; }; #if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_SESSION_GETTER_SETTER) @@ -220,5 +223,8 @@ ep_session_has_started (EventPipeSession *session); bool ep_session_type_uses_buffer_manager (EventPipeSessionType session_type); +bool +ep_session_type_uses_streaming_thread (EventPipeSessionType session_type); + #endif /* ENABLE_PERFTRACING */ #endif /* __EVENTPIPE_SESSION_H__ */ diff --git a/src/native/eventpipe/ep-stream.c b/src/native/eventpipe/ep-stream.c index 76b0c3f0db20d5..cb31ddccef84cc 100644 --- a/src/native/eventpipe/ep-stream.c +++ b/src/native/eventpipe/ep-stream.c @@ -538,6 +538,18 @@ ep_ipc_stream_close_vcall (IpcStream *ipc_stream) return vtable->close_func (ipc_stream); } +IpcPollEvents +ep_ipc_stream_poll_vcall (IpcStream *ipc_stream, uint32_t timeout_ms) +{ + EP_ASSERT (ipc_stream != NULL); + + EP_ASSERT (ipc_stream->vtable != NULL); + IpcStreamVtable *vtable = ipc_stream->vtable; + + EP_ASSERT (vtable->poll_func != NULL); + return vtable->poll_func (ipc_stream, timeout_ms); +} + /* * IpcStreamWriter. */ diff --git a/src/native/external/llvm-libunwind/include/__libunwind_config.h b/src/native/external/llvm-libunwind/include/__libunwind_config.h index 35e5a73de03dc2..ec56ded7e2882f 100644 --- a/src/native/external/llvm-libunwind/include/__libunwind_config.h +++ b/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/native/external/rapidjson-version.txt b/src/native/external/rapidjson-version.txt index b6f5f9532a7dba..e3045b7d2075bb 100644 --- a/src/native/external/rapidjson-version.txt +++ b/src/native/external/rapidjson-version.txt @@ -1,6 +1,6 @@ -3f73edae00aba5b0112a80b4d41e6f1ff7d92a3d +24b5e7a8b27f42fa16b96fc70aade9106cf7102f -https://github.com/Tencent/rapidjson/commit/3f73edae00aba5b0112a80b4d41e6f1ff7d92a3d +https://github.com/Tencent/rapidjson/commit/24b5e7a8b27f42fa16b96fc70aade9106cf7102f Note: This library is not using a proper release lifecycle. v1.1.0 was the last version released in 2016. - Therefore, we are pointing to a random commit from 2024 rather than a version tag. + Therefore, we are pointing to a random commit from 2025 rather than a version tag. diff --git a/src/native/external/rapidjson/document.h b/src/native/external/rapidjson/document.h index 2cd9a70a60037f..4b2d723224833d 100644 --- a/src/native/external/rapidjson/document.h +++ b/src/native/external/rapidjson/document.h @@ -1033,7 +1033,7 @@ class GenericValue { return false; for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) { typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name); - if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value) + if (rhsMemberItr == rhs.MemberEnd() || (!(lhsMemberItr->value == rhsMemberItr->value))) return false; } return true; @@ -1042,7 +1042,7 @@ class GenericValue { if (data_.a.size != rhs.data_.a.size) return false; for (SizeType i = 0; i < data_.a.size; i++) - if ((*this)[i] != rhs[i]) + if (!((*this)[i] == rhs[i])) return false; return true; @@ -2445,13 +2445,14 @@ class GenericValue { data_.f.flags = kShortStringFlag; data_.ss.SetLength(s.length); str = data_.ss.str; + std::memmove(str, s, s.length * sizeof(Ch)); } else { data_.f.flags = kCopyStringFlag; data_.s.length = s.length; str = static_cast(allocator.Malloc((s.length + 1) * sizeof(Ch))); SetStringPointer(str); + std::memcpy(str, s, s.length * sizeof(Ch)); } - std::memcpy(str, s, s.length * sizeof(Ch)); str[s.length] = '\0'; } diff --git a/src/native/external/rapidjson/encodings.h b/src/native/external/rapidjson/encodings.h index 50ad18bdc08cd0..c453c0da312b17 100644 --- a/src/native/external/rapidjson/encodings.h +++ b/src/native/external/rapidjson/encodings.h @@ -177,10 +177,10 @@ struct UTF8 { template static bool Validate(InputStream& is, OutputStream& os) { -#define RAPIDJSON_COPY() os.Put(c = is.Take()) +#define RAPIDJSON_COPY() if (c != '\0') os.Put(c = is.Take()) #define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast(c)) & mask) != 0) #define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70) - Ch c; + Ch c = static_cast(-1); RAPIDJSON_COPY(); if (!(c & 0x80)) return true; diff --git a/src/native/external/rapidjson/internal/strtod.h b/src/native/external/rapidjson/internal/strtod.h index 55f0e380bfaa35..57c8418bd94045 100644 --- a/src/native/external/rapidjson/internal/strtod.h +++ b/src/native/external/rapidjson/internal/strtod.h @@ -134,7 +134,7 @@ inline bool StrtodDiyFp(const Ch* decimals, int dLen, int dExp, double* result) int i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999 for (; i < dLen; i++) { if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || - (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > Ch('5'))) + (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] >= Ch('5'))) break; significand = significand * 10u + static_cast(decimals[i] - Ch('0')); } diff --git a/src/native/external/rapidjson/rapidjson.h b/src/native/external/rapidjson/rapidjson.h index 5ea69479501a3b..247b8e68dbb609 100644 --- a/src/native/external/rapidjson/rapidjson.h +++ b/src/native/external/rapidjson/rapidjson.h @@ -268,7 +268,7 @@ # elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN // Detect with architecture macros -# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) +# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN # elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__) # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN diff --git a/src/native/external/rapidjson/reader.h b/src/native/external/rapidjson/reader.h index 55546601e29bdf..f7ef61024433a8 100644 --- a/src/native/external/rapidjson/reader.h +++ b/src/native/external/rapidjson/reader.h @@ -1584,7 +1584,7 @@ class GenericReader { // Parse frac = decimal-point 1*DIGIT int expFrac = 0; size_t decimalPosition; - if (Consume(s, '.')) { + if (!useNanOrInf && Consume(s, '.')) { decimalPosition = s.Length(); if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9'))) @@ -1631,7 +1631,7 @@ class GenericReader { // Parse exp = e [ minus / plus ] 1*DIGIT int exp = 0; - if (Consume(s, 'e') || Consume(s, 'E')) { + if (!useNanOrInf && (Consume(s, 'e') || Consume(s, 'E'))) { if (!useDouble) { d = static_cast(use64bit ? i64 : i); useDouble = true; diff --git a/src/native/external/zlib-ng-version.txt b/src/native/external/zlib-ng-version.txt index 198e16578e1f7d..ba420d4726af49 100644 --- a/src/native/external/zlib-ng-version.txt +++ b/src/native/external/zlib-ng-version.txt @@ -1,7 +1,7 @@ -v2.2.4 -860e4cff7917d93f54f5d7f0bc1d0e8b1a3cb988 +v2.2.5 +425439062b114a0f6cf625022c41d929c7e879f9 -https://github.com/zlib-ng/zlib-ng/releases/tag/2.2.4 +https://github.com/zlib-ng/zlib-ng/releases/tag/2.2.5 We have removed the following folders from our local copy as these files are not needed for our compilation: diff --git a/src/native/external/zlib-ng/.gitignore b/src/native/external/zlib-ng/.gitignore index 71b9e0747f88a8..0a81b3ade206da 100644 --- a/src/native/external/zlib-ng/.gitignore +++ b/src/native/external/zlib-ng/.gitignore @@ -103,3 +103,7 @@ gzread.c MinSizeRel RelWithDebInfo /_deps/googletest* + +# Test datasets +test/data/corpora/ +test/data/local/ diff --git a/src/native/external/zlib-ng/CMakeLists.txt b/src/native/external/zlib-ng/CMakeLists.txt index 367413062fc3da..571979eb4d6987 100644 --- a/src/native/external/zlib-ng/CMakeLists.txt +++ b/src/native/external/zlib-ng/CMakeLists.txt @@ -47,6 +47,15 @@ include(CMakeDependentOption) include(CMakePackageConfigHelpers) include(FeatureSummary) +# We need to enable C++ before trying to check for coverage +option(WITH_GTEST "Build gtest_zlib" ON) +option(WITH_FUZZERS "Build test/fuzz" OFF) +option(WITH_BENCHMARKS "Build test/benchmarks" OFF) + +if(WITH_GTEST OR WITH_FUZZERS OR WITH_BENCHMARKS) + enable_language(CXX) +endif() + include(cmake/detect-arch.cmake) include(cmake/detect-install-dirs.cmake) include(cmake/detect-coverage.cmake) @@ -79,9 +88,6 @@ option(WITH_GZFILEOP "Compile with support for gzFile related functions" ON) option(ZLIB_COMPAT "Compile with zlib compatible API" OFF) option(ZLIB_ENABLE_TESTS "Build test binaries" ON) option(ZLIBNG_ENABLE_TESTS "Test zlib-ng specific API" ON) -option(WITH_GTEST "Build gtest_zlib" ON) -option(WITH_FUZZERS "Build test/fuzz" OFF) -option(WITH_BENCHMARKS "Build test/benchmarks" OFF) option(WITH_BENCHMARK_APPS "Build application benchmarks" OFF) option(WITH_OPTIM "Build with optimisation" ON) option(WITH_REDUCED_MEM "Reduced memory usage for special cases (reduces performance)" OFF) @@ -362,6 +368,21 @@ if(MSVC) endif() endif() +# +# Additional flags for features checking +# +set(ADDITIONAL_CHECK_FLAGS ) +if(APPLE) + check_c_compiler_flag(-Werror=unguarded-availability HAVE_W_ERROR_UNGUARDED_AVAILABILITY) + if(HAVE_W_ERROR_UNGUARDED_AVAILABILITY) + set(ADDITIONAL_CHECK_FLAGS "${ADDITIONAL_CHECK_FLAGS} -Werror=unguarded-availability") + endif() + check_c_compiler_flag(-Werror=unguarded-availability-new HAVE_W_ERROR_UNGUARDED_AVAILABILITY_NEW) + if(HAVE_W_ERROR_UNGUARDED_AVAILABILITY_NEW) + set(ADDITIONAL_CHECK_FLAGS "${ADDITIONAL_CHECK_FLAGS} -Werror=unguarded-availability-new") + endif() +endif() + # # Check for standard/system includes # @@ -407,28 +428,42 @@ set(CMAKE_REQUIRED_DEFINITIONS) # clear variable # # Check for fseeko and other optional functions # +set(CMAKE_REQUIRED_FLAGS "${ADDITIONAL_CHECK_FLAGS}") check_function_exists(fseeko HAVE_FSEEKO) if(NOT HAVE_FSEEKO) add_definitions(-DNO_FSEEKO) endif() +set(CMAKE_REQUIRED_FLAGS) +set(CMAKE_REQUIRED_FLAGS "${ADDITIONAL_CHECK_FLAGS}") check_function_exists(strerror HAVE_STRERROR) if(NOT HAVE_STRERROR) add_definitions(-DNO_STRERROR) endif() +set(CMAKE_REQUIRED_FLAGS) -set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=200112L) +# +# Check for aligned memory allocation support: POSIX +# +set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=200112L -D_ISOC11_SOURCE=1) +set(CMAKE_REQUIRED_FLAGS "${ADDITIONAL_CHECK_FLAGS}") check_symbol_exists(posix_memalign stdlib.h HAVE_POSIX_MEMALIGN) if(HAVE_POSIX_MEMALIGN) add_definitions(-DHAVE_POSIX_MEMALIGN) endif() +set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_DEFINITIONS) -set(CMAKE_REQUIRED_DEFINITIONS -D_ISOC11_SOURCE=1) +# +# Check for aligned memory allocation support: C11 +# +set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=200112L -D_ISOC11_SOURCE=1) +set(CMAKE_REQUIRED_FLAGS "${ADDITIONAL_CHECK_FLAGS}") check_symbol_exists(aligned_alloc stdlib.h HAVE_ALIGNED_ALLOC) if(HAVE_ALIGNED_ALLOC) add_definitions(-DHAVE_ALIGNED_ALLOC) endif() +set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_DEFINITIONS) if(WITH_SANITIZER STREQUAL "Address") @@ -577,13 +612,6 @@ if(MSVC) add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) endif() -if(BASEARCH_X86_FOUND) - # FORCE_SSE2 option will only be shown if HAVE_SSE2_INTRIN is true - if("${ARCH}" MATCHES "i[3-6]86") - cmake_dependent_option(FORCE_SSE2 "Always assume CPU is SSE2 capable" OFF "HAVE_SSE2_INTRIN" OFF) - endif() -endif() - # # Enable deflate_quick at level 1 # @@ -902,6 +930,10 @@ if(WITH_OPTIM) endif() if(WITH_SSE2) check_sse2_intrinsics() + # FORCE_SSE2 option will only be shown if HAVE_SSE2_INTRIN is true + if("${ARCH}" MATCHES "i[3-6]86") + cmake_dependent_option(FORCE_SSE2 "Always assume CPU is SSE2 capable" OFF "HAVE_SSE2_INTRIN" OFF) + endif() if(HAVE_SSE2_INTRIN) add_definitions(-DX86_SSE2) set(SSE2_SRCS ${ARCHDIR}/chunkset_sse2.c ${ARCHDIR}/compare256_sse2.c ${ARCHDIR}/slide_hash_sse2.c) @@ -1064,6 +1096,12 @@ else() set(PC_INC_INSTALL_DIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") endif() +if(IS_ABSOLUTE "${CMAKE_INSTALL_BINDIR}") + set(PC_BIN_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}") +else() + set(PC_BIN_INSTALL_DIR "\${exec_prefix}/${CMAKE_INSTALL_BINDIR}") +endif() + if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}") set(PC_LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}") else() diff --git a/src/native/external/zlib-ng/Makefile.in b/src/native/external/zlib-ng/Makefile.in index 1493124bbf4267..2f89c56b060c7d 100644 --- a/src/native/external/zlib-ng/Makefile.in +++ b/src/native/external/zlib-ng/Makefile.in @@ -30,7 +30,7 @@ LDSHARED=$(CC) LDSHAREDFLAGS=-shared LDVERSIONSCRIPT= -VER=2.2.4 +VER=2.2.5 VER1=2 STATICLIB=$(LIBNAME1).a diff --git a/src/native/external/zlib-ng/arch/riscv/Makefile.in b/src/native/external/zlib-ng/arch/riscv/Makefile.in new file mode 100644 index 00000000000000..8f253066861414 --- /dev/null +++ b/src/native/external/zlib-ng/arch/riscv/Makefile.in @@ -0,0 +1,63 @@ +# Makefile for zlib-ng +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# Copyright (C) 2024 Hans Kristian Rosbach +# Copyright (C) 2025 Yin Tong , ByteDance +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= +SUFFIX= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +RVVFLAG= + +all: \ + riscv_features.o riscv_features.lo \ + adler32_rvv.o adler32_rvv.lo \ + chunkset_rvv.o chunkset_rvv.lo \ + compare256_rvv.o compare256_rvv.lo \ + slide_hash_rvv.o slide_hash_rvv.lo + +riscv_features.o: $(SRCDIR)/riscv_features.c + $(CC) $(CFLAGS) $(RVVFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/riscv_features.c + +riscv_features.lo: $(SRCDIR)/riscv_features.c + $(CC) $(SFLAGS) $(RVVFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/riscv_features.c + +adler32_rvv.o: $(SRCDIR)/adler32_rvv.c + $(CC) $(CFLAGS) $(RVVFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_rvv.c + +adler32_rvv.lo: $(SRCDIR)/adler32_rvv.c + $(CC) $(SFLAGS) $(RVVFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_rvv.c + +chunkset_rvv.o: $(SRCDIR)/chunkset_rvv.c + $(CC) $(CFLAGS) $(RVVFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_rvv.c + +chunkset_rvv.lo: $(SRCDIR)/chunkset_rvv.c + $(CC) $(SFLAGS) $(RVVFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_rvv.c + +compare256_rvv.o: $(SRCDIR)/compare256_rvv.c + $(CC) $(CFLAGS) $(RVVFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_rvv.c + +compare256_rvv.lo: $(SRCDIR)/compare256_rvv.c + $(CC) $(SFLAGS) $(RVVFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_rvv.c + +slide_hash_rvv.o: $(SRCDIR)/slide_hash_rvv.c + $(CC) $(CFLAGS) $(RVVFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_rvv.c + +slide_hash_rvv.lo: $(SRCDIR)/slide_hash_rvv.c + $(CC) $(SFLAGS) $(RVVFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_rvv.c + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: clean + rm -f Makefile diff --git a/src/native/external/zlib-ng/arch/riscv/chunkset_rvv.c b/src/native/external/zlib-ng/arch/riscv/chunkset_rvv.c index ee43bde2f71d81..e0915dfc9666e5 100644 --- a/src/native/external/zlib-ng/arch/riscv/chunkset_rvv.c +++ b/src/native/external/zlib-ng/arch/riscv/chunkset_rvv.c @@ -92,7 +92,7 @@ static inline uint8_t* CHUNKCOPY(uint8_t *out, uint8_t const *from, unsigned len from += align; len -= align; ptrdiff_t dist = out - from; - if (dist >= len) { + if (dist < 0 || dist >= len) { memcpy(out, from, len); out += len; from += len; diff --git a/src/native/external/zlib-ng/arch/s390/s390_functions.h b/src/native/external/zlib-ng/arch/s390/s390_functions.h index e6855cd7011cf4..2c43a50627fa1d 100644 --- a/src/native/external/zlib-ng/arch/s390/s390_functions.h +++ b/src/native/external/zlib-ng/arch/s390/s390_functions.h @@ -20,7 +20,7 @@ uint32_t crc32_s390_vx(uint32_t crc, const uint8_t *buf, size_t len); #ifdef DISABLE_RUNTIME_CPU_DETECTION # if defined(S390_CRC32_VX) && defined(__zarch__) && __ARCH__ >= 11 && defined(__VX__) # undef native_crc32 -# define native_crc32 = crc32_s390_vx +# define native_crc32 crc32_s390_vx # endif #endif diff --git a/src/native/external/zlib-ng/arch/x86/chunkset_avx512.c b/src/native/external/zlib-ng/arch/x86/chunkset_avx512.c index 9d28d33d5eccec..db8c1eb25e6420 100644 --- a/src/native/external/zlib-ng/arch/x86/chunkset_avx512.c +++ b/src/native/external/zlib-ng/arch/x86/chunkset_avx512.c @@ -98,6 +98,10 @@ static inline uint8_t* CHUNKCOPY(uint8_t *out, uint8_t const *from, unsigned len return out; } +/* MSVC compiler decompression bug when optimizing for size */ +#if defined(_MSC_VER) && _MSC_VER < 1943 +# pragma optimize("", off) +#endif static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t dist) { lut_rem_pair lut_rem = perm_idx_lut[dist - 3]; __m256i ret_vec; @@ -128,6 +132,9 @@ static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t return ret_vec; } +#if defined(_MSC_VER) && _MSC_VER < 1943 +# pragma optimize("", on) +#endif static inline void storehalfchunk(uint8_t *out, halfchunk_t *chunk) { _mm_storeu_si128((__m128i *)out, *chunk); diff --git a/src/native/external/zlib-ng/arch/x86/x86_features.c b/src/native/external/zlib-ng/arch/x86/x86_features.c index 9491a00730831f..5efb1787563e1a 100644 --- a/src/native/external/zlib-ng/arch/x86/x86_features.c +++ b/src/native/external/zlib-ng/arch/x86/x86_features.c @@ -86,19 +86,17 @@ void Z_INTERNAL x86_check_features(struct x86_cpu_features *features) { } if (maxbasic >= 7) { + // Reference: https://software.intel.com/sites/default/files/article/405250/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family.pdf cpuidex(7, 0, &eax, &ebx, &ecx, &edx); - // check BMI1 bit - // Reference: https://software.intel.com/sites/default/files/article/405250/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family.pdf - features->has_vpclmulqdq = ecx & 0x400; + // check BMI2 bit + features->has_bmi2 = ebx & 0x8; // check AVX2 bit if the OS supports saving YMM registers if (features->has_os_save_ymm) { features->has_avx2 = ebx & 0x20; } - features->has_bmi2 = ebx & 0x8; - // check AVX512 bits if the OS supports saving ZMM registers if (features->has_os_save_zmm) { features->has_avx512f = ebx & 0x00010000; @@ -112,6 +110,7 @@ void Z_INTERNAL x86_check_features(struct x86_cpu_features *features) { features->has_avx512_common = features->has_avx512f && features->has_avx512dq && features->has_avx512bw \ && features->has_avx512vl && features->has_bmi2; features->has_avx512vnni = ecx & 0x800; + features->has_vpclmulqdq = ecx & 0x400; } } } diff --git a/src/native/external/zlib-ng/arch/x86/x86_functions.h b/src/native/external/zlib-ng/arch/x86/x86_functions.h index fc62daeae15af6..a5c2d58da7124b 100644 --- a/src/native/external/zlib-ng/arch/x86/x86_functions.h +++ b/src/native/external/zlib-ng/arch/x86/x86_functions.h @@ -90,7 +90,7 @@ uint32_t crc32_vpclmulqdq(uint32_t crc32, const uint8_t *buf, size_t len); # undef native_longest_match_slow # define native_longest_match_slow longest_match_slow_sse2 # endif -#endif +# endif // X86 - SSSE3 # if defined(X86_SSSE3) && defined(__SSSE3__) # undef native_adler32 @@ -105,21 +105,20 @@ uint32_t crc32_vpclmulqdq(uint32_t crc32, const uint8_t *buf, size_t len); # undef native_adler32_fold_copy # define native_adler32_fold_copy adler32_fold_copy_sse42 # endif - // X86 - PCLMUL -#if defined(X86_PCLMULQDQ_CRC) && defined(__PCLMUL__) -# undef native_crc32 -# define native_crc32 crc32_pclmulqdq -# undef native_crc32_fold -# define native_crc32_fold crc32_fold_pclmulqdq -# undef native_crc32_fold_copy -# define native_crc32_fold_copy crc32_fold_pclmulqdq_copy -# undef native_crc32_fold_final -# define native_crc32_fold_final crc32_fold_pclmulqdq_final -# undef native_crc32_fold_reset -# define native_crc32_fold_reset crc32_fold_pclmulqdq_reset -#endif -// X86 - AVX +# if defined(X86_PCLMULQDQ_CRC) && defined(__PCLMUL__) +# undef native_crc32 +# define native_crc32 crc32_pclmulqdq +# undef native_crc32_fold +# define native_crc32_fold crc32_fold_pclmulqdq +# undef native_crc32_fold_copy +# define native_crc32_fold_copy crc32_fold_pclmulqdq_copy +# undef native_crc32_fold_final +# define native_crc32_fold_final crc32_fold_pclmulqdq_final +# undef native_crc32_fold_reset +# define native_crc32_fold_reset crc32_fold_pclmulqdq_reset +# endif +// X86 - AVX2 # if defined(X86_AVX2) && defined(__AVX2__) # undef native_adler32 # define native_adler32 adler32_avx2 @@ -142,7 +141,6 @@ uint32_t crc32_vpclmulqdq(uint32_t crc32, const uint8_t *buf, size_t len); # define native_longest_match_slow longest_match_slow_avx2 # endif # endif - // X86 - AVX512 (F,DQ,BW,Vl) # if defined(X86_AVX512) && defined(__AVX512F__) && defined(__AVX512DQ__) && defined(__AVX512BW__) && defined(__AVX512VL__) # undef native_adler32 diff --git a/src/native/external/zlib-ng/cmake/detect-arch.cmake b/src/native/external/zlib-ng/cmake/detect-arch.cmake index dfdc6013cea78b..f80ee4a05a72cf 100644 --- a/src/native/external/zlib-ng/cmake/detect-arch.cmake +++ b/src/native/external/zlib-ng/cmake/detect-arch.cmake @@ -22,7 +22,6 @@ elseif(CMAKE_CROSSCOMPILING) set(ARCH ${CMAKE_C_COMPILER_TARGET}) else() # Let preprocessor parse archdetect.c and raise an error containing the arch identifier - enable_language(C) try_run( run_result_unused compile_result_unused diff --git a/src/native/external/zlib-ng/cmake/detect-intrinsics.cmake b/src/native/external/zlib-ng/cmake/detect-intrinsics.cmake index b96ac0a4428a9f..e953346f3fb4b8 100644 --- a/src/native/external/zlib-ng/cmake/detect-intrinsics.cmake +++ b/src/native/external/zlib-ng/cmake/detect-intrinsics.cmake @@ -137,11 +137,15 @@ macro(check_avx512vnni_intrinsics) set(CMAKE_REQUIRED_FLAGS "${AVX512VNNIFLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}") check_c_source_compiles( "#include - __m512i f(__m512i x, __m512i y) { - __m512i z = _mm512_setzero_epi32(); - return _mm512_dpbusd_epi32(z, x, y); - } - int main(void) { return 0; }" + int main(void) { + const __m512i z512 = _mm512_setzero_si512(); + const __m256i z256 = _mm256_setzero_si256(); + volatile __m512i r512 = _mm512_dpbusd_epi32(z512, z512, z512); + volatile __m256i r256 = _mm256_dpbusd_epi32(z256, z256, z256); + (void)r512; + (void)r256; + return 0; + }" HAVE_AVX512VNNI_INTRIN ) set(CMAKE_REQUIRED_FLAGS) diff --git a/src/native/external/zlib-ng/cmake/toolchain-riscv-clang.cmake b/src/native/external/zlib-ng/cmake/toolchain-riscv-clang.cmake new file mode 100644 index 00000000000000..71fa7f4cf30ac7 --- /dev/null +++ b/src/native/external/zlib-ng/cmake/toolchain-riscv-clang.cmake @@ -0,0 +1,16 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR riscv64) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER clang) +set(CMAKE_C_COMPILER_TARGET riscv64-linux-gnu) +set(CMAKE_CXX_COMPILER clang++) +set(CMAKE_CXX_COMPILER_TARGET riscv64-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-riscv64 -cpu rv64,zba=true,zbb=true,zbc=true,zbs=true,v=true,vlen=512,elen=64,vext_spec=v1.0 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/src/native/external/zlib-ng/cmake/toolchain-riscv.cmake b/src/native/external/zlib-ng/cmake/toolchain-riscv.cmake index 9cf8fdb7fec2fd..241f2a7d711947 100644 --- a/src/native/external/zlib-ng/cmake/toolchain-riscv.cmake +++ b/src/native/external/zlib-ng/cmake/toolchain-riscv.cmake @@ -1,28 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR riscv64) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET riscv64-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET riscv64-linux-gnu) + set(CMAKE_CROSSCOMPILING TRUE) -set(CMAKE_SYSTEM_NAME "Linux") -set(CMAKE_SYSTEM_PROCESSOR "riscv64") +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-riscv64 -cpu rv64,zba=true,zbb=true,zbc=true,zbs=true,v=true,vlen=512,elen=64,vext_spec=v1.0 -L /usr/${CMAKE_C_COMPILER_TARGET}/) -# Avoid to use system path for cross-compile -set(CMAKE_FIND_USE_CMAKE_SYSTEM_PATH FALSE) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) -set(TOOLCHAIN_PATH "" CACHE STRING "The toolchain path.") -if(NOT TOOLCHAIN_PATH) - set(TOOLCHAIN_PATH ${CMAKE_SOURCE_DIR}/prebuilt-riscv-toolchain-qemu/riscv-clang) +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) -set(TOOLCHAIN_PREFIX "riscv64-unknown-linux-gnu-" CACHE STRING "The toolchain prefix.") -set(QEMU_PATH "" CACHE STRING "The qemu path.") -if(NOT QEMU_PATH) - set(QEMU_PATH ${CMAKE_SOURCE_DIR}/prebuilt-riscv-toolchain-qemu/riscv-qemu/bin/qemu-riscv64) +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) endif() - -# toolchain setting -set(CMAKE_C_COMPILER "${TOOLCHAIN_PATH}/bin/${TOOLCHAIN_PREFIX}clang") -set(CMAKE_CXX_COMPILER "${TOOLCHAIN_PATH}/bin/${TOOLCHAIN_PREFIX}clang++") - -# disable auto-vectorizer -add_compile_options(-fno-vectorize -fno-slp-vectorize) - -# emulator setting -set(QEMU_CPU_OPTION "rv64,zba=true,zbb=true,zbc=true,zbs=true,v=true,vlen=512,elen=64,vext_spec=v1.0") -set(CMAKE_CROSSCOMPILING_EMULATOR ${QEMU_PATH} -cpu ${QEMU_CPU_OPTION} -L ${TOOLCHAIN_PATH}/sysroot/) diff --git a/src/native/external/zlib-ng/configure b/src/native/external/zlib-ng/configure index 3487d092bc9dfe..832b42ac102835 100644 --- a/src/native/external/zlib-ng/configure +++ b/src/native/external/zlib-ng/configure @@ -98,6 +98,7 @@ buildaltivec=1 buildpower8=1 buildpower9=1 buildneon=1 +buildrvv=1 builddfltccdeflate=0 builddfltccinflate=0 buildcrc32vx=1 @@ -116,6 +117,7 @@ vpclmulflag="-mvpclmulqdq -mavx512f" xsaveflag="-mxsave" acleflag= neonflag= +rvvflag= armv6flag= noltoflag="-fno-lto" vgfmaflag="-march=z13" @@ -169,6 +171,7 @@ case "$1" in echo ' [--without-acle] Compiles without ARM C Language Extensions' | tee -a configure.log echo ' [--without-neon] Compiles without ARM Neon SIMD instruction set' | tee -a configure.log echo ' [--without-armv6] Compiles without ARMv6 SIMD instruction set' | tee -a configure.log + echo ' [--without-rvv] Compiles without RVV instruction set' | tee -a configure.log echo ' [--without-altivec] Compiles without PPC AltiVec support' | tee -a configure.log echo ' [--without-power8] Compiles without Power8 instruction set' | tee -a configure.log echo ' [--with-dfltcc-deflate] Use DEFLATE CONVERSION CALL instruction for compression on IBM Z' | tee -a configure.log @@ -202,6 +205,7 @@ case "$1" in --without-neon) buildneon=0; shift ;; --without-armv6) buildarmv6=0; shift ;; --without-altivec) buildaltivec=0 ; shift ;; + --without-rvv) buildrvv=0 ; shift ;; --without-power8) buildpower8=0 ; shift ;; --without-power9) buildpower9=0 ; shift ;; --with-dfltcc-deflate) builddfltccdeflate=1; shift ;; @@ -339,6 +343,8 @@ if test "$gcc" -eq 1 && ($cc $CFLAGS -c $test.c) >> configure.log 2>&1; then ARCH=powerpc64 ;; powerpc64le | ppc64le) ARCH=powerpc64le ;; + riscv64) + ARCH=riscv64 ;; esac CFLAGS="-O2 ${CFLAGS}" if test -n "${ARCHS}"; then @@ -628,6 +634,32 @@ fi echo >> configure.log +ADDITIONAL_CHECK_FLAGS="" + +# Check for -Werror=unguarded-availability compiler support +echo "" > test.c + cat > $test.c <> configure.log 2>&1; then + echo "Checking for -Werror=unguarded-availability... Yes." | tee -a configure.log + ADDITIONAL_CHECK_FLAGS="$ADDITIONAL_CHECK_FLAGS -Werror=unguarded-availability" +else + echo "Checking for -Werror=unguarded-availability... No." | tee -a configure.log +fi + +# Check for -Werror=unguarded-availability-new compiler support +echo "" > test.c + cat > $test.c <> configure.log 2>&1; then + echo "Checking for -Werror=unguarded-availability-new... Yes." | tee -a configure.log + ADDITIONAL_CHECK_FLAGS="$ADDITIONAL_CHECK_FLAGS -Werror=unguarded-availability-new" +else + echo "Checking for -Werror=unguarded-availability-new... No." | tee -a configure.log +fi + # check for version script support cat > $test.c <> configure.log cat > $test.c < int main(void) { void *ptr = 0; @@ -705,7 +738,7 @@ int main(void) { return ret; } EOF -if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then +if try $CC $CFLAGS $ADDITIONAL_CHECK_FLAGS -o $test $test.c $LDSHAREDLIBC; then echo "Checking for posix_memalign... Yes." | tee -a configure.log CFLAGS="${CFLAGS} -DHAVE_POSIX_MEMALIGN" SFLAGS="${SFLAGS} -DHAVE_POSIX_MEMALIGN" @@ -715,6 +748,7 @@ fi echo >> configure.log cat > $test.c < int main(void) { @@ -724,7 +758,7 @@ int main(void) { return 0; } EOF -if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then +if try $CC $CFLAGS $ADDITIONAL_CHECK_FLAGS -o $test $test.c $LDSHAREDLIBC; then echo "Checking for aligned_alloc... Yes." | tee -a configure.log CFLAGS="${CFLAGS} -DHAVE_ALIGNED_ALLOC" SFLAGS="${SFLAGS} -DHAVE_ALIGNED_ALLOC" @@ -739,7 +773,7 @@ cat > $test.c < int main() { return strlen(strerror(errno)); } EOF -if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then +if try $CC $CFLAGS $ADDITIONAL_CHECK_FLAGS -o $test $test.c $LDSHAREDLIBC; then echo "Checking for strerror... Yes." | tee -a configure.log else CFLAGS="${CFLAGS} -DNO_STRERROR" @@ -1106,11 +1140,15 @@ check_avx512vnni_intrinsics() { # Check whether compiler supports AVX512-VNNI intrinsics cat > $test.c << EOF #include -__m512i f(__m512i x, __m512i y) { - __m512i z = _mm512_setzero_epi32(); - return _mm512_dpbusd_epi32(z, x, y); +int main(void) { + const __m512i z512 = _mm512_setzero_si512(); + const __m256i z256 = _mm256_setzero_si256(); + volatile __m512i r512 = _mm512_dpbusd_epi32(z512, z512, z512); + volatile __m256i r256 = _mm256_dpbusd_epi32(z256, z256, z256); + (void)r512; + (void)r256; + return 0; } -int main(void) { return 0; } EOF if try ${CC} ${CFLAGS} ${avx512vnniflag} $test.c; then echo "Checking for AVX512VNNI intrinsics ... Yes." | tee -a configure.log @@ -1491,6 +1529,40 @@ EOF fi } +check_rvv_compiler_flag() { + cat > $test.c << EOF +int main() { return 0; } +EOF + if try $CC -c $CFLAGS -march=rv64gcv $test.c; then + echo "Check whether -march=rv64gcv works ... Yes." | tee -a configure.log + rvvflag="-march=rv64gcv" + else + echo "Check whether -march=rv64gcv works ... No." | tee -a configure.log + if try $CC -c $CFLAGS -march=rv64gc_zve64x $test.c; then + echo "Check whether -march=rv64gc_zve64x works ... Yes." | tee -a configure.log + rvvflag="-march=rv64gc_zve64x" + else + echo "Check whether -march=rv64gc_zve64x works ... No." | tee -a configure.log + rvvflag="" + fi + fi + + cat > $test.c << EOF +#include +int main(void) { + size_t vl = __riscv_vsetvlmax_e8m1(); + return vl; +} +EOF + if [ -n "$rvvflag" ] && try ${CC} ${CFLAGS} ${rvvflag} $test.c; then + echo "Checking for RISC-V Vector intrinsics ... Yes." | tee -a configure.log + HAVE_RVV_INTRIN=1 + else + echo "Checking for RISC-V Vector intrinsics ... No." | tee -a configure.log + HAVE_RVV_INTRIN=0 + fi +} + # Check whether to disable deflate_medium and deflate_quick if test $without_new_strategies -eq 1; then CFLAGS="${CFLAGS} -DNO_QUICK_STRATEGY -DNO_MEDIUM_STRATEGY" @@ -1847,6 +1919,29 @@ EOF fi fi ;; + riscv64) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=riscv64 + ARCHDIR=arch/riscv + + if test $without_optimizations -eq 0; then + if test $buildrvv -eq 1; then + check_rvv_compiler_flag + + if test $HAVE_RVV_INTRIN -eq 1; then + CFLAGS="${CFLAGS} -DRISCV_FEATURES -DRISCV_RVV" + SFLAGS="${SFLAGS} -DRISCV_FEATURES -DRISCV_RVV" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} riscv_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} riscv_features.lo" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_rvv.o chunkset_rvv.o compare256_rvv.o slide_hash_rvv.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_rvv.lo chunkset_rvv.lo compare256_rvv.lo slide_hash_rvv.lo" + + ARCH="${ARCH}+rvv" + fi + fi + fi + ;; s390x) [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=s390x ARCHDIR=arch/s390 @@ -2096,6 +2191,7 @@ sed < $SRCDIR/$ARCHDIR/Makefile.in " /^NOLTOFLAG *=/s#=.*#=$noltoflag# /^VGFMAFLAG *=/s#=.*#=$vgfmaflag# /^PPCFLAGS *=/s#=.*#=$vmxflag# +/^RVVFLAG *=/s#=.*#=$rvvflag# " > $ARCHDIR/Makefile # Append header files dependencies. diff --git a/src/native/external/zlib-ng/deflate.h b/src/native/external/zlib-ng/deflate.h index 4b79f8f43b2c83..02d68211a318d2 100644 --- a/src/native/external/zlib-ng/deflate.h +++ b/src/native/external/zlib-ng/deflate.h @@ -227,7 +227,7 @@ struct ALIGNED_(64) internal_state { # define max_insert_length max_lazy_match /* Insert new strings in the hash table only if the match length is not * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. + * max_insert_length is used only for compression levels <= 6. */ update_hash_cb update_hash; diff --git a/src/native/external/zlib-ng/deflate_medium.c b/src/native/external/zlib-ng/deflate_medium.c index 2aeebe2026bda8..ae7c737ecb117c 100644 --- a/src/native/external/zlib-ng/deflate_medium.c +++ b/src/native/external/zlib-ng/deflate_medium.c @@ -45,12 +45,10 @@ static void insert_match(deflate_state *s, struct match match) { if (UNLIKELY(s->lookahead <= (unsigned int)(match.match_length + WANT_MIN_MATCH))) return; - /* string at strstart already in table */ - match.strstart++; - match.match_length--; - /* matches that are not long enough we need to emit as literals */ - if (LIKELY(match.match_length < WANT_MIN_MATCH - 1)) { + if (LIKELY(match.match_length < WANT_MIN_MATCH)) { + match.strstart++; + match.match_length--; if (UNLIKELY(match.match_length > 0)) { if (match.strstart >= match.orgstart) { if (match.strstart + match.match_length - 1 >= match.orgstart) { @@ -65,18 +63,35 @@ static void insert_match(deflate_state *s, struct match match) { return; } - /* Insert into hash table. */ - if (LIKELY(match.strstart >= match.orgstart)) { - if (LIKELY(match.strstart + match.match_length - 1 >= match.orgstart)) { - insert_string(s, match.strstart, match.match_length); - } else { - insert_string(s, match.strstart, match.orgstart - match.strstart + 1); + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (match.match_length <= 16 * s->max_insert_length && s->lookahead >= WANT_MIN_MATCH) { + match.match_length--; /* string at strstart already in table */ + match.strstart++; + + if (LIKELY(match.strstart >= match.orgstart)) { + if (LIKELY(match.strstart + match.match_length - 1 >= match.orgstart)) { + insert_string(s, match.strstart, match.match_length); + } else { + insert_string(s, match.strstart, match.orgstart - match.strstart + 1); + } + } else if (match.orgstart < match.strstart + match.match_length) { + insert_string(s, match.orgstart, match.strstart + match.match_length - match.orgstart); } - } else if (match.orgstart < match.strstart + match.match_length) { - insert_string(s, match.orgstart, match.strstart + match.match_length - match.orgstart); + match.strstart += match.match_length; + match.match_length = 0; + } else { + match.strstart += match.match_length; + match.match_length = 0; + + if (match.strstart >= (STD_MIN_MATCH - 2)) + quick_insert_string(s, match.strstart + 2 - STD_MIN_MATCH); + + /* If lookahead < WANT_MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ } - match.strstart += match.match_length; - match.match_length = 0; } static void fizzle_matches(deflate_state *s, struct match *current, struct match *next) { diff --git a/src/native/external/zlib-ng/zlib-ng.h.in b/src/native/external/zlib-ng/zlib-ng.h.in index 93c7c86f26da87..71b41b6996d98a 100644 --- a/src/native/external/zlib-ng/zlib-ng.h.in +++ b/src/native/external/zlib-ng/zlib-ng.h.in @@ -48,11 +48,11 @@ extern "C" { #endif -#define ZLIBNG_VERSION "2.2.4" -#define ZLIBNG_VERNUM 0x020204F0L /* MMNNRRSM: major minor revision status modified */ +#define ZLIBNG_VERSION "2.2.5" +#define ZLIBNG_VERNUM 0x020205F0L /* MMNNRRSM: major minor revision status modified */ #define ZLIBNG_VER_MAJOR 2 #define ZLIBNG_VER_MINOR 2 -#define ZLIBNG_VER_REVISION 4 +#define ZLIBNG_VER_REVISION 5 #define ZLIBNG_VER_STATUS F /* 0=devel, 1-E=beta, F=Release (DEPRECATED) */ #define ZLIBNG_VER_STATUSH 0xF /* Hex values: 0=devel, 1-E=beta, F=Release */ #define ZLIBNG_VER_MODIFIED 0 /* non-zero if modified externally from zlib-ng */ diff --git a/src/native/external/zlib-ng/zlib.h.in b/src/native/external/zlib-ng/zlib.h.in index b8fa106ef1609e..46dce01df25412 100644 --- a/src/native/external/zlib-ng/zlib.h.in +++ b/src/native/external/zlib-ng/zlib.h.in @@ -49,11 +49,11 @@ extern "C" { #endif -#define ZLIBNG_VERSION "2.2.4" -#define ZLIBNG_VERNUM 0x020204F0L /* MMNNRRSM: major minor revision status modified */ +#define ZLIBNG_VERSION "2.2.5" +#define ZLIBNG_VERNUM 0x020205F0L /* MMNNRRSM: major minor revision status modified */ #define ZLIBNG_VER_MAJOR 2 #define ZLIBNG_VER_MINOR 2 -#define ZLIBNG_VER_REVISION 4 +#define ZLIBNG_VER_REVISION 5 #define ZLIBNG_VER_STATUS F /* 0=devel, 1-E=beta, F=Release (DEPRECATED) */ #define ZLIBNG_VER_STATUSH 0xF /* Hex values: 0=devel, 1-E=beta, F=Release */ #define ZLIBNG_VER_MODIFIED 0 /* non-zero if modified externally from zlib-ng */ diff --git a/src/native/external/zlib-ng/zlib.pc.cmakein b/src/native/external/zlib-ng/zlib.pc.cmakein index df8bf9f0514f1c..a5ff63cef46454 100644 --- a/src/native/external/zlib-ng/zlib.pc.cmakein +++ b/src/native/external/zlib-ng/zlib.pc.cmakein @@ -1,6 +1,7 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix} symbol_prefix=@ZLIB_SYMBOL_PREFIX@ +bindir=@PC_BIN_INSTALL_DIR@ libdir=@PC_LIB_INSTALL_DIR@ sharedlibdir=${libdir} includedir=@PC_INC_INSTALL_DIR@ diff --git a/src/native/external/zlib-ng/zlib.pc.in b/src/native/external/zlib-ng/zlib.pc.in index 45b35989b1cb41..25cc923ee16ee4 100644 --- a/src/native/external/zlib-ng/zlib.pc.in +++ b/src/native/external/zlib-ng/zlib.pc.in @@ -1,6 +1,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ symbol_prefix=@symbol_prefix@ +bindir=@bindir@ libdir=@libdir@ sharedlibdir=@sharedlibdir@ includedir=@includedir@ diff --git a/src/native/external/zlib-ng/zutil.c b/src/native/external/zlib-ng/zutil.c index 99818c3a7b9e04..5bab7f16bd5df0 100644 --- a/src/native/external/zlib-ng/zutil.c +++ b/src/native/external/zlib-ng/zutil.c @@ -21,7 +21,7 @@ z_const char * const PREFIX(z_errmsg)[10] = { }; const char PREFIX3(vstring)[] = - " zlib-ng 2.2.4"; + " zlib-ng 2.2.5"; #ifdef ZLIB_COMPAT const char * Z_EXPORT zlibVersion(void) { diff --git a/src/native/libs/CMakeLists.txt b/src/native/libs/CMakeLists.txt index c90e9b8a45ddc5..cf8b2b47fbd67b 100644 --- a/src/native/libs/CMakeLists.txt +++ b/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/native/libs/Common/pal_config.h.in b/src/native/libs/Common/pal_config.h.in index f64132cd449968..580cd68a574335 100644 --- a/src/native/libs/Common/pal_config.h.in +++ b/src/native/libs/Common/pal_config.h.in @@ -31,6 +31,7 @@ #cmakedefine01 HAVE_MNTINFO #cmakedefine01 HAVE_STATFS_FSTYPENAME #cmakedefine01 HAVE_STATVFS_FSTYPENAME +#cmakedefine01 HAVE_STATVFS_BASETYPE #cmakedefine01 HAVE_NON_LEGACY_STATFS #cmakedefine01 HAVE_STRCPY_S #cmakedefine01 HAVE_STRLCPY diff --git a/src/native/libs/System.Globalization.Native/entrypoints.c b/src/native/libs/System.Globalization.Native/entrypoints.c index f2db315ec5452e..b687ea837daac6 100644 --- a/src/native/libs/System.Globalization.Native/entrypoints.c +++ b/src/native/libs/System.Globalization.Native/entrypoints.c @@ -41,8 +41,6 @@ static const Entry s_globalizationNative[] = DllImportEntry(GlobalizationNative_GetSortHandle) DllImportEntry(GlobalizationNative_GetSortKey) DllImportEntry(GlobalizationNative_GetSortVersion) - DllImportEntry(GlobalizationNative_GetTimeZoneDisplayName) - DllImportEntry(GlobalizationNative_IanaIdToWindowsId) DllImportEntry(GlobalizationNative_IndexOf) DllImportEntry(GlobalizationNative_InitICUFunctions) DllImportEntry(GlobalizationNative_IsNormalized) @@ -54,7 +52,11 @@ static const Entry s_globalizationNative[] = #endif DllImportEntry(GlobalizationNative_NormalizeString) DllImportEntry(GlobalizationNative_StartsWith) +#ifndef __wasm__ + DllImportEntry(GlobalizationNative_GetTimeZoneDisplayName) + DllImportEntry(GlobalizationNative_IanaIdToWindowsId) DllImportEntry(GlobalizationNative_WindowsIdToIanaId) +#endif #if defined(APPLE_HYBRID_GLOBALIZATION) DllImportEntry(GlobalizationNative_ChangeCaseInvariantNative) DllImportEntry(GlobalizationNative_ChangeCaseNative) diff --git a/src/native/libs/System.IO.Compression.Native/CMakeLists.txt b/src/native/libs/System.IO.Compression.Native/CMakeLists.txt index cd5f4200d009c5..0adecdad88b0ac 100644 --- a/src/native/libs/System.IO.Compression.Native/CMakeLists.txt +++ b/src/native/libs/System.IO.Compression.Native/CMakeLists.txt @@ -36,6 +36,10 @@ set(NATIVECOMPRESSION_SOURCES pal_zlib.c ) +if (CLR_CMAKE_TARGET_WIN32 AND NOT CLR_CMAKE_TARGET_ARCH_I386) + list(APPEND NATIVECOMPRESSION_SOURCES "zlib_allocator_win.c") +endif() + if (NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_WASI) set (NATIVECOMPRESSION_SOURCES ${NATIVECOMPRESSION_SOURCES} diff --git a/src/native/libs/System.IO.Compression.Native/pal_zlib.c b/src/native/libs/System.IO.Compression.Native/pal_zlib.c index 5ef4c8c7c1a4b4..d932eb522e30ee 100644 --- a/src/native/libs/System.IO.Compression.Native/pal_zlib.c +++ b/src/native/libs/System.IO.Compression.Native/pal_zlib.c @@ -8,6 +8,9 @@ #ifdef _WIN32 #define c_static_assert(e) static_assert((e),"") #include "../Common/pal_utilities.h" + #if _WIN64 + #include + #endif #else #include "pal_utilities.h" #endif @@ -39,6 +42,11 @@ static int32_t Init(PAL_ZStream* stream) { z_stream* zStream = (z_stream*)calloc(1, sizeof(z_stream)); +#ifdef _WIN64 + zStream->zalloc = z_custom_calloc; + zStream->zfree = z_custom_cfree; +#endif + stream->internalState = zStream; if (zStream != NULL) diff --git a/src/native/libs/System.IO.Compression.Native/zlib_allocator.h b/src/native/libs/System.IO.Compression.Native/zlib_allocator.h new file mode 100644 index 00000000000000..cadd00bb5879c5 --- /dev/null +++ b/src/native/libs/System.IO.Compression.Native/zlib_allocator.h @@ -0,0 +1,8 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include // voidpf + +voidpf z_custom_calloc(voidpf opaque, unsigned items, unsigned size); + +void z_custom_cfree(voidpf opaque, voidpf ptr); diff --git a/src/native/libs/System.IO.Compression.Native/zlib_allocator_win.c b/src/native/libs/System.IO.Compression.Native/zlib_allocator_win.c new file mode 100644 index 00000000000000..239a46e0bfb64b --- /dev/null +++ b/src/native/libs/System.IO.Compression.Native/zlib_allocator_win.c @@ -0,0 +1,81 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include +#include +#include +#include /* _ASSERTE */ + +#include + +/* A custom allocator for zlib that uses a dedicated heap. + This provides better performance and avoids fragmentation + that can occur on Windows when using the default process heap. + */ + +// Gets the special heap we'll allocate from. +HANDLE GetZlibHeap() +{ + static HANDLE s_hPublishedHeap = NULL; + + // If already initialized, return immediately. + // We don't need a volatile read here since the publish is performed with release semantics. + if (s_hPublishedHeap != NULL) { return s_hPublishedHeap; } + + // Attempt to create a new heap. The heap will be dynamically sized. + HANDLE hNewHeap = HeapCreate(0, 0, 0); + + if (hNewHeap != NULL) + { + // We created a new heap. Attempt to publish it. + if (InterlockedCompareExchangePointer(&s_hPublishedHeap, hNewHeap, NULL) != NULL) + { + HeapDestroy(hNewHeap); // Somebody published before us. Destroy our heap. + hNewHeap = NULL; // Guard against accidental use later in the method. + } + } + else + { + // If we can't create a new heap, fall back to the process default heap. + InterlockedCompareExchangePointer(&s_hPublishedHeap, GetProcessHeap(), NULL); + } + + // Some thread - perhaps us, perhaps somebody else - published the heap. Return it. + // We don't need a volatile read here since the publish is performed with release semantics. + _ASSERTE(s_hPublishedHeap != NULL); + return s_hPublishedHeap; +} + +voidpf z_custom_calloc(opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + + SIZE_T cbRequested; + if (sizeof(items) + sizeof(size) <= sizeof(cbRequested)) + { + // multiplication can't overflow; no need for safeint + cbRequested = (SIZE_T)items * (SIZE_T)size; + } + else + { + // multiplication can overflow; go through safeint + if (FAILED(SIZETMult(items, size, &cbRequested))) { return NULL; } + } + + return HeapAlloc(GetZlibHeap(), 0, cbRequested); +} + +void z_custom_cfree(opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + if (ptr == NULL) { return; } // ok to free nullptr + + if (!HeapFree(GetZlibHeap(), 0, ptr)) { goto Fail; } + return; + +Fail: + __fastfail(FAST_FAIL_HEAP_METADATA_CORRUPTION); +} diff --git a/src/native/libs/System.IO.Ports.Native/pal_serial.c b/src/native/libs/System.IO.Ports.Native/pal_serial.c index f80d8655727239..221d12d041bbd0 100644 --- a/src/native/libs/System.IO.Ports.Native/pal_serial.c +++ b/src/native/libs/System.IO.Ports.Native/pal_serial.c @@ -44,7 +44,9 @@ int SystemIoPortsNative_SerialPortClose(intptr_t handle) // ignoring the error - best effort ioctl(fd, TIOCNXCL); - return close(fd); + int result = close(fd); + if (result < 0 && errno == EINTR) result = 0; // on all supported platforms, close(2) returning EINTR still means it was released + return result; } int32_t SystemIoPortsNative_Read(intptr_t fd, void* buffer, int32_t bufferSize) diff --git a/src/native/libs/System.Native/pal_io.c b/src/native/libs/System.Native/pal_io.c index 74bead7dc0ada9..23b226d74e0362 100644 --- a/src/native/libs/System.Native/pal_io.c +++ b/src/native/libs/System.Native/pal_io.c @@ -343,7 +343,9 @@ intptr_t SystemNative_Open(const char* path, int32_t flags, int32_t mode) int32_t SystemNative_Close(intptr_t fd) { - return close(ToFileDescriptor(fd)); + int result = close(ToFileDescriptor(fd)); + if (result < 0 && errno == EINTR) result = 0; // on all supported platforms, close(2) returning EINTR still means it was released + return result; } intptr_t SystemNative_Dup(intptr_t oldfd) diff --git a/src/native/libs/System.Native/pal_mount.c b/src/native/libs/System.Native/pal_mount.c index 758575e6954f33..386eba5ede1162 100644 --- a/src/native/libs/System.Native/pal_mount.c +++ b/src/native/libs/System.Native/pal_mount.c @@ -159,6 +159,14 @@ SystemNative_GetFileSystemTypeNameForMountPoint(const char* name, char* formatNa } SafeStringCopy(formatNameBuffer, Int32ToSizeT(bufferLength), stats.f_fstypename); *formatType = -1; +#elif HAVE_STATVFS_BASETYPE + if (bufferLength < _FSTYPSZ) // SunOS + { + errno = ERANGE; + result = -1; + } + SafeStringCopy(formatNameBuffer, Int32ToSizeT(bufferLength), stats.f_basetype); + *formatType = -1; #else SafeStringCopy(formatNameBuffer, Int32ToSizeT(bufferLength), ""); *formatType = (int64_t)(stats.f_type); diff --git a/src/native/libs/System.Native/pal_networkchange.c b/src/native/libs/System.Native/pal_networkchange.c index c3950890fdb59a..77fcc29ac1bdac 100644 --- a/src/native/libs/System.Native/pal_networkchange.c +++ b/src/native/libs/System.Native/pal_networkchange.c @@ -179,8 +179,6 @@ Error SystemNative_ReadEvents(intptr_t sock, NetworkChangeEvent onNetworkChange) { (void)sock; (void)onNetworkChange; - // unreachable - abort(); - return Error_EINVAL; + return Error_ENOTSUP; } #endif diff --git a/src/native/libs/System.Native/pal_process.c b/src/native/libs/System.Native/pal_process.c index fa5e522c36205e..ca982ebbf48a23 100644 --- a/src/native/libs/System.Native/pal_process.c +++ b/src/native/libs/System.Native/pal_process.c @@ -314,7 +314,11 @@ int32_t SystemNative_ForkAndExecProcess(const char* filename, sigfillset(&signal_set); pthread_sigmask(SIG_SETMASK, &signal_set, &old_signal_set); -#if HAVE_VFORK && !(defined(__APPLE__)) // We don't trust vfork on OS X right now. +// vfork on OS X is deprecated +// On Android, signal handlers between parent and child processes are shared with vfork, so when we reset +// the signal handlers during child startup, we end up incorrectly clearing also the ones for the parent. +#if HAVE_VFORK && !defined(__APPLE__) && !defined(TARGET_ANDROID) + // This platform has vfork(). vfork() is either a synonym for fork or provides shared memory // semantics. For a one gigabyte process, the expected performance gain of using shared memory // vfork() rather than fork() is 99.5% merely due to avoiding page faults as the kernel does not diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.c index c7933f73aaee29..a7fda9f371fbd5 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.c +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.c @@ -411,6 +411,9 @@ ARGS_NON_NULL_ALL static void FreeSSLStream(JNIEnv* env, SSLStream* sslStream) ReleaseGRef(env, sslStream->netOutBuffer); ReleaseGRef(env, sslStream->netInBuffer); ReleaseGRef(env, sslStream->appInBuffer); + + sslStream->managedContextCleanup(sslStream->managedContextHandle); + free(sslStream); } @@ -650,7 +653,7 @@ SSLStream* AndroidCryptoNative_SSLStreamCreateWithKeyStorePrivateKeyEntry(intptr } int32_t AndroidCryptoNative_SSLStreamInitialize( - SSLStream* sslStream, bool isServer, ManagedContextHandle managedContextHandle, STREAM_READER streamReader, STREAM_WRITER streamWriter, int32_t appBufferSize, char* peerHost) + SSLStream* sslStream, bool isServer, ManagedContextHandle managedContextHandle, STREAM_READER streamReader, STREAM_WRITER streamWriter, MANAGED_CONTEXT_CLEANUP managedContextCleanup, int32_t appBufferSize, char* peerHost) { abort_if_invalid_pointer_argument (sslStream); abort_unless(sslStream->sslContext != NULL, "sslContext is NULL in SSL stream"); @@ -706,6 +709,7 @@ int32_t AndroidCryptoNative_SSLStreamInitialize( sslStream->managedContextHandle = managedContextHandle; sslStream->streamReader = streamReader; sslStream->streamWriter = streamWriter; + sslStream->managedContextCleanup = managedContextCleanup; ret = SUCCESS; diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.h b/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.h index 2760a62d1e491d..000677d54f32f8 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.h +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.h @@ -11,6 +11,7 @@ typedef intptr_t ManagedContextHandle; typedef void (*STREAM_WRITER)(ManagedContextHandle, uint8_t*, int32_t); typedef int32_t (*STREAM_READER)(ManagedContextHandle, uint8_t*, int32_t*); +typedef void (*MANAGED_CONTEXT_CLEANUP)(ManagedContextHandle); typedef struct SSLStream { @@ -24,6 +25,7 @@ typedef struct SSLStream ManagedContextHandle managedContextHandle; STREAM_READER streamReader; STREAM_WRITER streamWriter; + MANAGED_CONTEXT_CLEANUP managedContextCleanup; } SSLStream; typedef struct ApplicationProtocolData_t ApplicationProtocolData; @@ -67,15 +69,16 @@ PALEXPORT SSLStream* AndroidCryptoNative_SSLStreamCreateWithKeyStorePrivateKeyEn /* Initialize an SSL context - - isServer : true if the context should be created in server mode - - streamReader : callback for reading data from the connection - - streamWriter : callback for writing data to the connection - - appBufferSize : initial buffer size for application data + - isServer : true if the context should be created in server mode + - streamReader : callback for reading data from the connection + - streamWriter : callback for writing data to the connection + - managedContextCleanup : callback for cleaning up the managed context + - appBufferSize : initial buffer size for application data Returns 1 on success, 0 otherwise */ PALEXPORT int32_t AndroidCryptoNative_SSLStreamInitialize( - SSLStream* sslStream, bool isServer, ManagedContextHandle managedContextHandle, STREAM_READER streamReader, STREAM_WRITER streamWriter, int32_t appBufferSize, char* peerHost); + SSLStream* sslStream, bool isServer, ManagedContextHandle managedContextHandle, STREAM_READER streamReader, STREAM_WRITER streamWriter, MANAGED_CONTEXT_CLEANUP managedContextCleanup, int32_t appBufferSize, char* peerHost); /* Set target host diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/CMakeLists.txt b/src/native/libs/System.Security.Cryptography.Native.Apple/CMakeLists.txt index bc333326b9837e..876a5c47e845ad 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/CMakeLists.txt +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/CMakeLists.txt @@ -21,6 +21,7 @@ set(NATIVECRYPTO_SOURCES pal_x509.c pal_x509chain.c pal_swiftbindings.o + pal_networkframework.m ) if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c b/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c index 5163aa5b121236..d968ed2e127cf3 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c @@ -23,6 +23,7 @@ #include "pal_x509.h" #include "pal_x509_macos.h" #include "pal_x509chain.h" +#include "pal_networkframework.h" static const Entry s_cryptoAppleNative[] = { @@ -62,7 +63,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) @@ -137,6 +137,14 @@ static const Entry s_cryptoAppleNative[] = DllImportEntry(AppleCryptoNative_X509StoreRemoveCertificate) DllImportEntry(AppleCryptoNative_Pbkdf2) DllImportEntry(AppleCryptoNative_X509GetSubjectSummary) + DllImportEntry(AppleCryptoNative_Init) + DllImportEntry(AppleCryptoNative_NwConnectionCreate) + DllImportEntry(AppleCryptoNative_NwConnectionStart) + DllImportEntry(AppleCryptoNative_NwFramerDeliverInput) + DllImportEntry(AppleCryptoNative_NwConnectionSend) + DllImportEntry(AppleCryptoNative_NwConnectionReceive) + DllImportEntry(AppleCryptoNative_NwConnectionCancel) + DllImportEntry(AppleCryptoNative_GetConnectionInfo) }; EXTERN_C const void* CryptoAppleResolveDllImport(const char* name); diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/extra_libs.cmake b/src/native/libs/System.Security.Cryptography.Native.Apple/extra_libs.cmake index d220db67479ac5..adeb619b299171 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/extra_libs.cmake +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/extra_libs.cmake @@ -2,7 +2,8 @@ macro(append_extra_cryptography_apple_libs NativeLibsExtra) find_library(COREFOUNDATION_LIBRARY CoreFoundation) find_library(SECURITY_LIBRARY Security) + find_library(NETWORK_LIBRARY Network) find_library(CRYPTOKIT_LIBRARY CryptoKit) - list(APPEND ${NativeLibsExtra} ${COREFOUNDATION_LIBRARY} ${SECURITY_LIBRARY} ${CRYPTOKIT_LIBRARY} -L/usr/lib/swift -lobjc -lswiftCore -lswiftFoundation) + list(APPEND ${NativeLibsExtra} ${COREFOUNDATION_LIBRARY} ${SECURITY_LIBRARY} ${NETWORK_LIBRARY} ${CRYPTOKIT_LIBRARY} -L/usr/lib/swift -lobjc -lswiftCore -lswiftFoundation) endmacro() diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_networkframework.h b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_networkframework.h new file mode 100644 index 00000000000000..c3bf1ca0181df6 --- /dev/null +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_networkframework.h @@ -0,0 +1,65 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#pragma once + +#include "pal_compiler.h" +#include +#include +#include +#include // for intptr_t + +#ifdef __OBJC__ +#import +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// Status update enumeration for TLS operations +typedef enum +{ + PAL_NwStatusUpdates_UnknownError = 0, + PAL_NwStatusUpdates_FramerStart = 1, + PAL_NwStatusUpdates_HandshakeFinished = 3, + PAL_NwStatusUpdates_ConnectionFailed = 4, + PAL_NwStatusUpdates_ConnectionCancelled = 103, + PAL_NwStatusUpdates_CertificateAvailable = 104, + + PAL_NwStatusUpdates_DebugLog = 200, +} PAL_NwStatusUpdates; + +// Error information structure +typedef struct +{ + int32_t errorCode; + int32_t errorDomain; + const char* errorMessage; +} PAL_NetworkFrameworkError; + +// Callback type definitions that match the implementation usage +typedef void (*StatusUpdateCallback)(void* context, PAL_NwStatusUpdates status, size_t data1, size_t data2, PAL_NetworkFrameworkError* error); +typedef int32_t (*WriteCallback)(void* context, uint8_t* buffer, uint64_t length); +typedef void (*CompletionCallback)(void* context, PAL_NetworkFrameworkError* error); +typedef void (*ReadCompletionCallback)(void* context, PAL_NetworkFrameworkError* error, const uint8_t* data, size_t length); +typedef void* (*ChallengeCallback)(void* context, CFArrayRef acceptableIssuers); + +// Initializes global state +PALEXPORT int32_t AppleCryptoNative_Init(StatusUpdateCallback statusFunc, WriteCallback writeFunc, ChallengeCallback challengeFunc); + +PALEXPORT nw_connection_t AppleCryptoNative_NwConnectionCreate(int32_t isServer, void* context, char* targetName, const uint8_t * alpnBuffer, int alpnLength, PAL_SslProtocol minTlsProtocol, PAL_SslProtocol maxTlsProtocol, uint32_t* cipherSuites, int cipherSuitesLength); +PALEXPORT int32_t AppleCryptoNative_NwConnectionStart(nw_connection_t connection, void* context); +PALEXPORT void AppleCryptoNative_NwConnectionSend(nw_connection_t connection, void* context, uint8_t* buffer, int length, CompletionCallback completionCallback); +PALEXPORT void AppleCryptoNative_NwConnectionReceive(nw_connection_t connection, void* context, uint32_t length, ReadCompletionCallback readCompletionCallback); +PALEXPORT void AppleCryptoNative_NwConnectionCancel(nw_connection_t connection); + +PALEXPORT int32_t AppleCryptoNative_NwFramerDeliverInput(nw_framer_t framer, void* context, const uint8_t* data, int dataLength, CompletionCallback completionCallback); + +PALEXPORT int32_t AppleCryptoNative_GetConnectionInfo(nw_connection_t connection, void* context, PAL_SslProtocol* pProtocol, uint16_t* pCipherSuiteOut, char* negotiatedAlpn, int32_t* negotiatedAlpnLength); + +#ifdef __cplusplus +} +#endif diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_networkframework.m b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_networkframework.m new file mode 100644 index 00000000000000..159fa373f1d88e --- /dev/null +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_networkframework.m @@ -0,0 +1,606 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// +// Network.framework requires an underlying network connection for TLS operations, +// but we need to perform TLS without an actual connection so that we can expose +// it as the SslStream abstraction. This implementation uses a workaround: we +// create a dummy UDP connection that will never be used. +// +// The trick works by layering a custom framer on top of this dummy connection, +// then adding TLS on top of the framer. The framer intercepts the raw TLS data +// and exposes it to SslStream, preventing it from ever reaching the underlying +// connection. +// + +#include "pal_networkframework.h" +#include +#include +#include + +static WriteCallback _writeFunc; +static StatusUpdateCallback _statusFunc; +static ChallengeCallback _challengeFunc; +static nw_protocol_definition_t _framerDefinition; +static nw_protocol_definition_t _tlsDefinition; +static dispatch_queue_t _tlsQueue; +static dispatch_queue_t _inputQueue; +static nw_endpoint_t _endpoint; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" + +#define LOG_IMPL_(context, isError, ...) \ + do { \ + char buff[256]; \ + snprintf(buff, sizeof(buff), __VA_ARGS__); \ + _statusFunc(context, PAL_NwStatusUpdates_DebugLog, (size_t)(buff), (size_t)(isError), NULL); \ + } while (0) + +#ifdef DEBUG +#define LOG_INFO(context, ...) LOG_IMPL_(context, 0, __VA_ARGS__) +#else +#define LOG_INFO(context, ...) do { (void)context; } while (0) +#endif + +#define LOG_ERROR(context, ...) LOG_IMPL_(context, 1, __VA_ARGS__) + +#define MANAGED_CONTEXT_KEY "GCHANDLE" + +static void* FramerGetManagedContext(nw_framer_t framer) +{ + void* ptr = NULL; + + if (__builtin_available(macOS 12.3, iOS 15.4, tvOS 15.4, watchOS 8.4, *)) + { + nw_protocol_options_t framer_options = nw_framer_copy_options(framer); + assert(framer_options != NULL); + + NSNumber* num = nw_framer_options_copy_object_value(framer_options, MANAGED_CONTEXT_KEY); + assert(num != NULL); + [num getValue:&ptr]; + [num release]; + + nw_release(framer_options); + } + + return ptr; +} + +static void FramerOptionsSetManagedContext(nw_protocol_options_t framer_options, void* context) +{ + if (__builtin_available(macOS 12.3, iOS 15.4, tvOS 15.4.0, watchOS 8.4, *)) + { + NSNumber *ref = [NSNumber numberWithLong:(long)context]; + nw_framer_options_set_object_value(framer_options, MANAGED_CONTEXT_KEY, ref); + [ref release]; + } +} + +static tls_protocol_version_t PalSslProtocolToTlsProtocolVersion(PAL_SslProtocol palProtocolId) +{ + switch (palProtocolId) + { + case PAL_SslProtocol_Tls13: + return tls_protocol_version_TLSv13; + case PAL_SslProtocol_Tls12: + return tls_protocol_version_TLSv12; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + case PAL_SslProtocol_Tls11: + return tls_protocol_version_TLSv11; + case PAL_SslProtocol_Tls10: + return tls_protocol_version_TLSv10; + case tls_protocol_version_DTLSv10: + default: + break; +#pragma clang diagnostic pop + } + + return (tls_protocol_version_t)0; +} + + +// Helper function to extract error information from nw_error_t +// Returns CFStringRef that needs to be released after use, or NULL if no CFString was created +static CFStringRef ExtractNetworkFrameworkError(nw_error_t error, PAL_NetworkFrameworkError* outError) +{ + if (error == NULL || outError == NULL) + { + if (outError != NULL) + { + outError->errorCode = 0; + outError->errorDomain = 0; + outError->errorMessage = NULL; + } + return NULL; + } + + outError->errorCode = nw_error_get_error_code(error); + nw_error_domain_t domain = nw_error_get_error_domain(error); + outError->errorDomain = (int32_t)domain; + + if (domain == nw_error_domain_posix) + { + outError->errorMessage = strerror(outError->errorCode); + return NULL; + } + + // Get error message from CoreFoundation error if available + CFStringRef descriptionToRelease = NULL; + CFErrorRef cfError = nw_error_copy_cf_error(error); + if (cfError != NULL) + { + CFStringRef description = CFErrorCopyDescription(cfError); + if (description != NULL) + { + outError->errorMessage = CFStringGetCStringPtr(description, kCFStringEncodingUTF8); + if (outError->errorMessage == NULL) + { + // If direct pointer access fails, we'll leave it as NULL + CFRelease(description); + } + else + { + // We got a direct pointer, so we need to keep the CFString alive + descriptionToRelease = description; + } + } + CFRelease(cfError); + } + else + { + outError->errorMessage = NULL; + } + + return descriptionToRelease; +} + +PALEXPORT nw_connection_t AppleCryptoNative_NwConnectionCreate(int32_t isServer, void* context, char* targetName, const uint8_t * alpnBuffer, int alpnLength, PAL_SslProtocol minTlsProtocol, PAL_SslProtocol maxTlsProtocol, uint32_t* cipherSuites, int cipherSuitesLength) +{ + if (isServer != 0) // the current implementation only supports client + return NULL; + + nw_parameters_t parameters = nw_parameters_create_secure_udp(NW_PARAMETERS_DISABLE_PROTOCOL, NW_PARAMETERS_DEFAULT_CONFIGURATION); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" + //return connection; + + nw_protocol_options_t tls_options = nw_tls_create_options(); + sec_protocol_options_t sec_options = nw_tls_copy_sec_protocol_options(tls_options); + if (targetName != NULL) + { + sec_protocol_options_set_tls_server_name(sec_options, targetName); + } + + tls_protocol_version_t version = PalSslProtocolToTlsProtocolVersion(minTlsProtocol); + if ((int)version != 0) + { + LOG_INFO(context, "Min TLS version: %d", version); + sec_protocol_options_set_min_tls_protocol_version(sec_options, version); + } + + version = PalSslProtocolToTlsProtocolVersion(maxTlsProtocol); + if ((int)version != 0) + { + LOG_INFO(context, "Max TLS version: %d", version); + sec_protocol_options_set_max_tls_protocol_version(sec_options, version); + } + + if (alpnBuffer != NULL) + { + int offset = 0; + while (offset < alpnLength) + { + uint8_t length = alpnBuffer[offset]; + const char* alpn = (const char*) &alpnBuffer[offset + 1]; + LOG_INFO(context, "Appending ALPN: %s", alpn); + sec_protocol_options_add_tls_application_protocol(sec_options, alpn); + offset += length + 2; + } + } + + if (cipherSuites != NULL && cipherSuitesLength > 0) + { + for (int i = 0; i < cipherSuitesLength; i++) + { + uint16_t cipherSuite = (uint16_t)cipherSuites[i]; + LOG_INFO(context, "Appending cipher suite: 0x%04x", cipherSuite); + sec_protocol_options_append_tls_ciphersuite(sec_options, cipherSuite); + } + } + + // Set up challenge block to detect when server requests client certificate + sec_protocol_options_set_challenge_block(sec_options, ^(sec_protocol_metadata_t metadata, sec_protocol_challenge_complete_t complete) + { + // Extract acceptable issuers from metadata + CFMutableArrayRef acceptableIssuers = NULL; + + if (metadata != NULL) + { + // Create array to hold distinguished names + acceptableIssuers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + // Access distinguished names from the metadata + sec_protocol_metadata_access_distinguished_names(metadata, ^(dispatch_data_t dn) + { + // Convert dispatch_data to CFData + const void* dnBytes = NULL; + size_t dnLength = 0; + dispatch_data_t contiguousDN = dispatch_data_create_map(dn, &dnBytes, &dnLength); + + if (dnBytes != NULL && dnLength > 0) + { + CFDataRef dnData = CFDataCreate(NULL, (const UInt8*)dnBytes, (CFIndex)dnLength); + if (dnData != NULL) + { + CFArrayAppendValue(acceptableIssuers, dnData); + CFRelease(dnData); + } + } + + if (contiguousDN != NULL) + { + dispatch_release(contiguousDN); + } + }); + } + + // Call the managed callback to get the client identity + void* identity = _challengeFunc(context, acceptableIssuers); + + // Clean up + CFRelease(acceptableIssuers); + + if (identity != NULL) + { + // Convert to sec_identity_t and set it + SecIdentityRef secIdentityRef = (SecIdentityRef)identity; + sec_identity_t sec_identity = sec_identity_create(secIdentityRef); + if (sec_identity != NULL) + { + complete(sec_identity); + sec_release(sec_identity); + } + + return; + } + + complete(NULL); + }, _tlsQueue); + + // we accept all certificates here and we will do validation later + sec_protocol_options_set_verify_block(sec_options, ^(sec_protocol_metadata_t metadata, sec_trust_t trust_ref, sec_protocol_verify_complete_t complete) + { + LOG_INFO(context, "Cert validation callback called"); + + SecTrustRef chain = sec_trust_copy_ref(trust_ref); + + _statusFunc(context, PAL_NwStatusUpdates_CertificateAvailable, (size_t)chain, 0, NULL); + + (void)metadata; + (void)trust_ref; + complete(true); + }, _tlsQueue); + + nw_release(sec_options); + + nw_protocol_options_t framer_options = nw_framer_create_options(_framerDefinition); + FramerOptionsSetManagedContext(framer_options, context); + + nw_protocol_stack_t protocol_stack = nw_parameters_copy_default_protocol_stack(parameters); + nw_protocol_stack_prepend_application_protocol(protocol_stack, framer_options); + nw_protocol_stack_prepend_application_protocol(protocol_stack, tls_options); + + nw_release(framer_options); + nw_release(protocol_stack); + nw_release(tls_options); + + nw_connection_t connection = nw_connection_create(_endpoint, parameters); + + nw_release(parameters); + + if (connection == NULL) + { + LOG_ERROR(context, "Failed to create Network Framework connection"); + return NULL; + } + + return connection; +} + +// This writes encrypted TLS frames to the safe handle. It is executed on NW Thread pool +static nw_framer_output_handler_t framer_output_handler = ^(nw_framer_t framer, nw_framer_message_t message, size_t message_length, bool is_complete) +{ + if (__builtin_available(macOS 12.3, iOS 15.4, tvOS 15.4, watchOS 2.0, *)) + { + void* context = FramerGetManagedContext(framer); + size_t size = message_length; + + nw_framer_parse_output(framer, 1, message_length, NULL, ^size_t(uint8_t *buffer, size_t buffer_length, bool is_complete2) + { + (_writeFunc)(context, buffer, buffer_length); + (void)is_complete2; + (void)message; + return buffer_length; + }); + } + else + { + assert(0); + } + (void)is_complete; +}; + +static nw_framer_stop_handler_t framer_stop_handler = ^bool(nw_framer_t framer) +{ + (void)framer; + return TRUE; +}; + +static nw_framer_cleanup_handler_t framer_cleanup_handler = ^(nw_framer_t framer) +{ + (void)framer; +}; + +// This is called when connection start to set up framer +static nw_framer_start_handler_t framer_start = ^nw_framer_start_result_t(nw_framer_t framer) +{ + assert(_statusFunc != NULL); + + void* context = FramerGetManagedContext(framer); + + // Notify managed code with framer reference so we can submit to it directly. + (_statusFunc)(context, PAL_NwStatusUpdates_FramerStart, (size_t)framer, 0, NULL); + + nw_framer_set_output_handler(framer, framer_output_handler); + + nw_framer_set_stop_handler(framer, framer_stop_handler); + nw_framer_set_cleanup_handler(framer, framer_cleanup_handler); + + return nw_framer_start_result_ready; +}; + + +// this takes encrypted input from underlying stream and feeds it to nw_connection. +PALEXPORT int32_t AppleCryptoNative_NwFramerDeliverInput(nw_framer_t framer, void* context, const uint8_t* buffer, int bufferLength, CompletionCallback completionCallback) +{ + assert(framer != NULL); + if (framer == NULL) + { + LOG_ERROR(context, "NwFramerDeliverInput called with NULL framer"); + return -1; + } + + nw_framer_message_t message = nw_framer_message_create(framer); + + // There is a race condition when connection can fail or be canceled and if it does we fail to create the message here. + if (message == NULL) + { + LOG_ERROR(context, "NwFramerDeliverInput failed to create message"); + return -1; + } + + nw_framer_async(framer, ^(void) + { + nw_framer_deliver_input(framer, buffer, (size_t)bufferLength, message, bufferLength > 0 ? FALSE : TRUE); + completionCallback(context, NULL); + nw_release(message); + }); + + return 0; +} + +// This starts TLS handshake. For client, it will produce ClientHello and call output handler (on thread pool) +// important part here is the context handler that will get asynchronous notifications about progress. +PALEXPORT int AppleCryptoNative_NwConnectionStart(nw_connection_t connection, void* context) +{ + if (connection == NULL) + { + LOG_ERROR(context, "NwConnectionStart called with NULL connection"); + return -1; + } + + nw_connection_set_state_changed_handler(connection, ^(nw_connection_state_t status, nw_error_t error) + { + PAL_NetworkFrameworkError errorInfo; + CFStringRef cfStringToRelease = ExtractNetworkFrameworkError(error, &errorInfo); + LOG_INFO(context, "Connection context changed: %d, errorCode: %d", (int)status, errorInfo.errorCode); + switch (status) + { + case nw_connection_state_preparing: + case nw_connection_state_waiting: + case nw_connection_state_failed: + { + if (errorInfo.errorCode != 0 || status == nw_connection_state_failed) + { + (_statusFunc)(context, PAL_NwStatusUpdates_ConnectionFailed, 0, 0, &errorInfo); + } + } + break; + case nw_connection_state_ready: + { + (_statusFunc)(context, PAL_NwStatusUpdates_HandshakeFinished, 0, 0, NULL); + } + break; + case nw_connection_state_cancelled: + { + (_statusFunc)(context, PAL_NwStatusUpdates_ConnectionCancelled, 0, 0, NULL); + } + break; + case nw_connection_state_invalid: + { + (_statusFunc)(context, PAL_NwStatusUpdates_UnknownError, 0, 0, NULL); + } + break; + } + + // Release CFString if we created one + if (cfStringToRelease != NULL) + { + CFRelease(cfStringToRelease); + } + }); + + nw_connection_set_queue(connection, _tlsQueue); + nw_connection_start(connection); + + return 0; +} + +// This will start connection cleanup +PALEXPORT void AppleCryptoNative_NwConnectionCancel(nw_connection_t connection) +{ + nw_connection_cancel(connection); +} + +// this is used by encrypt. We write plain text to the connection and it will be handound out encrypted via output handler +PALEXPORT void AppleCryptoNative_NwConnectionSend(nw_connection_t connection, void* context, uint8_t* buffer, int length, CompletionCallback completionCallback) +{ + dispatch_data_t data = dispatch_data_create(buffer, (size_t)length, _inputQueue, ^() + { + // we specify empty destructor instead of DISPATCH_DATA_DESTRUCTOR_DEFAULT to avoid creating + // an internal copy of the data. The caller ensures the buffer is valid until we call completionCallback. + }); + + nw_connection_send(connection, data, NW_CONNECTION_DEFAULT_MESSAGE_CONTEXT, FALSE, ^(nw_error_t error) + { + PAL_NetworkFrameworkError errorInfo; + CFStringRef cfStringToRelease = ExtractNetworkFrameworkError(error, &errorInfo); + completionCallback(context, error != NULL ? &errorInfo : NULL); + + // Release CFString if we created one + if (cfStringToRelease != NULL) + { + CFRelease(cfStringToRelease); + } + }); + + // Release our reference to dispatch_data - nw_connection_send retains it + dispatch_release(data); +} + +// This is used by decrypt. We feed data in via AppleCryptoNative_NwProcessInputData and we try to read from the connection. +PALEXPORT void AppleCryptoNative_NwConnectionReceive(nw_connection_t connection, void* context, uint32_t length, ReadCompletionCallback readCompletionCallback) +{ + nw_connection_receive(connection, 0, length, ^(dispatch_data_t content, nw_content_context_t ctx, bool is_complete, nw_error_t error) + { + PAL_NetworkFrameworkError errorInfo; + + if (error != NULL) + { + CFStringRef cfStringToRelease = ExtractNetworkFrameworkError(error, &errorInfo); + readCompletionCallback(context, &errorInfo, NULL, 0); + + // Release CFString if we created one + if (cfStringToRelease != NULL) + { + CFRelease(cfStringToRelease); + } + return; + } + + if (content != NULL) + { + const void *buffer; + size_t bufferLength; + dispatch_data_t tmp = dispatch_data_create_map(content, &buffer, &bufferLength); + readCompletionCallback(context, NULL, (const uint8_t*)buffer, bufferLength); + dispatch_release(tmp); + return; + } + + if (is_complete || content == NULL) + { + readCompletionCallback(context, NULL, NULL, 0); + return; + } + + (void)ctx; + }); +} + +// This wil get TLS details after handshake is finished +PALEXPORT int32_t AppleCryptoNative_GetConnectionInfo(nw_connection_t connection, void* context, PAL_SslProtocol* protocol, uint16_t* pCipherSuiteOut, char* negotiatedAlpn, int32_t* negotiatedAlpnLength) +{ + nw_protocol_metadata_t meta = nw_connection_copy_protocol_metadata(connection, _tlsDefinition); + + if (meta == NULL) + { + LOG_ERROR(context, "nw_connection_copy_protocol_metadata returned null"); + return -1; + } + + sec_protocol_metadata_t secMeta = nw_tls_copy_sec_protocol_metadata(meta); + + const char* alpn = sec_protocol_metadata_get_negotiated_protocol(secMeta); + if (alpn != NULL) + { + strcpy(negotiatedAlpn, alpn); + *negotiatedAlpnLength = (int32_t)strlen(alpn); + } + else + { + negotiatedAlpn[0] = '\0'; + *negotiatedAlpnLength = 0; + } + + tls_protocol_version_t version = sec_protocol_metadata_get_negotiated_tls_protocol_version(secMeta); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + switch (version) + { + case tls_protocol_version_TLSv10: + *protocol = PAL_SslProtocol_Tls10; + break; + case tls_protocol_version_TLSv11: + *protocol = PAL_SslProtocol_Tls11; + break; + case tls_protocol_version_TLSv12: + *protocol = PAL_SslProtocol_Tls12; + break; + case tls_protocol_version_TLSv13: + *protocol = PAL_SslProtocol_Tls13; + break; + case tls_protocol_version_DTLSv10: + case tls_protocol_version_DTLSv12: + default: + *protocol = PAL_SslProtocol_None; + break; + } +#pragma clang diagnostic pop + + *pCipherSuiteOut = sec_protocol_metadata_get_negotiated_tls_ciphersuite(secMeta); + + nw_release(meta); + sec_release(secMeta); + return 0; +} + +// this is called once to set everything up +PALEXPORT int32_t AppleCryptoNative_Init(StatusUpdateCallback statusFunc, WriteCallback writeFunc, ChallengeCallback challengeFunc) +{ + assert(statusFunc != NULL); + assert(writeFunc != NULL); + + if (__builtin_available(macOS 12.3, iOS 15.4, tvOS 15.4.0, watchOS 8.4, *)) + { + _writeFunc = writeFunc; + _statusFunc = statusFunc; + _challengeFunc = challengeFunc; + _framerDefinition = nw_framer_create_definition("com.dotnet.networkframework.tlsframer", + NW_FRAMER_CREATE_FLAGS_DEFAULT, framer_start); + _tlsDefinition = nw_protocol_copy_tls_definition(); + _tlsQueue = dispatch_queue_create("com.dotnet.networkframework.tlsqueue", NULL); + _inputQueue = _tlsQueue; + + // The endpoint values (127.0.0.1:42) are arbitrary - they just need to be + // syntactically and semantically valid since the connection is never established. + _endpoint = nw_endpoint_create_host("127.0.0.1", "42"); + + return 0; + } + + return 1; +} diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c index 2fba375bd423eb..2218fdaab5aeb0 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c +++ b/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/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h index 14b8d790970e8d..8a73e052717e4c 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h +++ b/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/native/libs/System.Security.Cryptography.Native.Apple/pal_x509chain.c b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509chain.c index 5f84bd898c3ac3..f513587203109a 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509chain.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509chain.c @@ -53,15 +53,20 @@ int32_t AppleCryptoNative_X509ChainEvaluate(SecTrustRef chain, return -3; } + // If the chain built successfully return 1. We pass in NULL for the CFError, since we don't care what it is. We use + // the SecTrustResultType for that. + if (SecTrustEvaluateWithError(chain, NULL)) + { + *pOSStatus = noErr; + return 1; + } + SecTrustResultType trustResult; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - *pOSStatus = SecTrustEvaluate(chain, &trustResult); -#pragma clang diagnostic pop + *pOSStatus = SecTrustGetTrustResult(chain, &trustResult); - // If any error is reported from the function or the trust result value indicates that - // otherwise was a failed chain build (vs an untrusted chain, etc) return failure and - // we'll throw in the managed layer. (but if we hit the "or" the message is "No error") + // If SecTrustGetTrustResult couldn't get the trust result, return an error. + // If the result is kSecTrustResultInvalid then that means you asked for the result before building a chain. + // This shouldn't happen but we shouldn't treat it as success, so it's also a fail. if (*pOSStatus != noErr || trustResult == kSecTrustResultInvalid) { return 0; diff --git a/src/native/libs/System.Security.Cryptography.Native/CMakeLists.txt b/src/native/libs/System.Security.Cryptography.Native/CMakeLists.txt index e8ba7c0d19c8fc..c875413edd321e 100644 --- a/src/native/libs/System.Security.Cryptography.Native/CMakeLists.txt +++ b/src/native/libs/System.Security.Cryptography.Native/CMakeLists.txt @@ -41,6 +41,7 @@ set(NATIVECRYPTO_SOURCES pal_evp_pkey_ecdsa.c pal_evp_pkey_eckey.c pal_evp_pkey_rsa.c + pal_evp_pkey_raw_signverify.c pal_evp_pkey_ml_dsa.c pal_evp_pkey_slh_dsa.c pal_hmac.c @@ -67,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 @@ -124,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/native/libs/System.Security.Cryptography.Native/entrypoints.c b/src/native/libs/System.Security.Cryptography.Native/entrypoints.c index 2eec9783488965..a16bbe9c135742 100644 --- a/src/native/libs/System.Security.Cryptography.Native/entrypoints.c +++ b/src/native/libs/System.Security.Cryptography.Native/entrypoints.c @@ -256,7 +256,11 @@ static const Entry s_cryptoNative[] = DllImportEntry(CryptoNative_MLDsaExportPublicKey) DllImportEntry(CryptoNative_MLDsaGenerateKey) DllImportEntry(CryptoNative_MLDsaGetPalId) + DllImportEntry(CryptoNative_MLDsaSignExternalMu) + DllImportEntry(CryptoNative_MLDsaSignPreEncoded) DllImportEntry(CryptoNative_MLDsaSignPure) + DllImportEntry(CryptoNative_MLDsaVerifyExternalMu) + DllImportEntry(CryptoNative_MLDsaVerifyPreEncoded) DllImportEntry(CryptoNative_MLDsaVerifyPure) DllImportEntry(CryptoNative_NewX509Stack) DllImportEntry(CryptoNative_ObjNid2Obj) diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index 7d0412823d9dab..47e4a3994a3932 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -168,6 +168,10 @@ c_static_assert(EVP_PKEY_PUBLIC_KEY == 134); #define OSSL_SIGNATURE_PARAM_CONTEXT_STRING "context-string" #endif +#ifndef OSSL_SIGNATURE_PARAM_MU +#define OSSL_SIGNATURE_PARAM_MU "mu" +#endif + #if defined FEATURE_DISTRO_AGNOSTIC_SSL || OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_3_0_RTM #include "apibridge_30_rev.h" #endif diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp.c b/src/native/libs/System.Security.Cryptography.Native/pal_evp.c index 1fcb0fc0058cea..6d707bb15edac5 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp.c @@ -10,31 +10,55 @@ #define SUCCESS 1 -static const EVP_MD* g_evpFetchMd5 = NULL; -static pthread_once_t g_evpFetch = PTHREAD_ONCE_INIT; - -static void EnsureFetchEvpMdAlgorithms(void) -{ - // This is called from a pthread_once - this method should not be called directly. - #ifdef NEED_OPENSSL_3_0 - if (API_EXISTS(EVP_MD_fetch)) - { - ERR_clear_error(); - - // Try to fetch an MD5 implementation that will work regardless if - // FIPS is enforced or not. - g_evpFetchMd5 = EVP_MD_fetch(NULL, "MD5", "-fips"); +#define BUILD_MD_FETCH(export, fn, name, query) \ + static const EVP_MD* g_evpFetch##export = NULL; \ + static pthread_once_t g_evpFetchInit##export = PTHREAD_ONCE_INIT; \ + static void EnsureFetchEvpMd##export(void) \ + { \ + if (API_EXISTS(EVP_MD_fetch)) \ + { \ + ERR_clear_error(); \ + g_evpFetch##export = EVP_MD_fetch(NULL, name, query); \ + } \ +\ + if (g_evpFetch##export == NULL) \ + { \ + g_evpFetch##export = fn(); \ + } \ + } \ + \ + const EVP_MD* export(void) \ + { \ + pthread_once(&g_evpFetchInit##export, EnsureFetchEvpMd##export); \ + return g_evpFetch##export; \ } +#define BUILD_MD_FETCH_LIGHTUP_SHA3(...) BUILD_MD_FETCH(__VA_ARGS__) +#else +#define BUILD_MD_FETCH(export, fn, name, query) \ + const EVP_MD* export(void) \ + { \ + return fn(); \ + } +#if HAVE_OPENSSL_SHA3 +#define BUILD_MD_FETCH_LIGHTUP_SHA3(export, fn, name, query) \ + const EVP_MD* export(void) \ + { \ + if (API_EXISTS(fn)) \ + { \ + return fn(); \ + } \ + \ + return NULL; \ + } +#else + const EVP_MD* export(void) \ + { \ + return NULL; \ + } +#endif #endif - // No error queue impact. - // If EVP_MD_fetch is unavailable, use the implicit loader. If it failed, use the implicit loader as a last resort. - if (g_evpFetchMd5 == NULL) - { - g_evpFetchMd5 = EVP_md5(); - } -} EVP_MD_CTX* CryptoNative_EvpMdCtxCreate(const EVP_MD* type) { @@ -291,100 +315,18 @@ int32_t CryptoNative_EvpMdSize(const EVP_MD* md) return EVP_MD_get_size(md); } -const EVP_MD* CryptoNative_EvpMd5(void) -{ - pthread_once(&g_evpFetch, EnsureFetchEvpMdAlgorithms); - return g_evpFetchMd5; -} - -const EVP_MD* CryptoNative_EvpSha1(void) -{ - // No error queue impact. - return EVP_sha1(); -} - -const EVP_MD* CryptoNative_EvpSha256(void) -{ - // No error queue impact. - return EVP_sha256(); -} - -const EVP_MD* CryptoNative_EvpSha384(void) -{ - // No error queue impact. - return EVP_sha384(); -} - -const EVP_MD* CryptoNative_EvpSha512(void) -{ - // No error queue impact. - return EVP_sha512(); -} - -const EVP_MD* CryptoNative_EvpSha3_256(void) -{ - // No error queue impact. -#if HAVE_OPENSSL_SHA3 - if (API_EXISTS(EVP_sha3_256)) - { - return EVP_sha3_256(); - } -#endif - - return NULL; -} - -const EVP_MD* CryptoNative_EvpSha3_384(void) -{ - // No error queue impact. -#if HAVE_OPENSSL_SHA3 - if (API_EXISTS(EVP_sha3_384)) - { - return EVP_sha3_384(); - } -#endif - - return NULL; -} - -const EVP_MD* CryptoNative_EvpSha3_512(void) -{ - // No error queue impact. -#if HAVE_OPENSSL_SHA3 - if (API_EXISTS(EVP_sha3_512)) - { - return EVP_sha3_512(); - } -#endif - - return NULL; -} - -const EVP_MD* CryptoNative_EvpShake128(void) -{ - // No error queue impact. -#if HAVE_OPENSSL_SHA3 - if (API_EXISTS(EVP_shake128)) - { - return EVP_shake128(); - } -#endif - - return NULL; -} - -const EVP_MD* CryptoNative_EvpShake256(void) -{ - // No error queue impact. -#if HAVE_OPENSSL_SHA3 - if (API_EXISTS(EVP_shake256)) - { - return EVP_shake256(); - } -#endif - - return NULL; -} +// MD5 should use a non-FIPS implementation if it is available. We should not fail +// to fetch MD5 even on a FIPS enforced system. +BUILD_MD_FETCH(CryptoNative_EvpMd5, EVP_md5, "MD5", "-fips") +BUILD_MD_FETCH(CryptoNative_EvpSha1, EVP_sha1, "SHA1", NULL) +BUILD_MD_FETCH(CryptoNative_EvpSha256, EVP_sha256, "SHA256", NULL) +BUILD_MD_FETCH(CryptoNative_EvpSha384, EVP_sha384, "SHA384", NULL) +BUILD_MD_FETCH(CryptoNative_EvpSha512, EVP_sha512, "SHA512", NULL) +BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpSha3_256, EVP_sha3_256, "SHA3-256", NULL) +BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpSha3_384, EVP_sha3_384, "SHA3-384", NULL) +BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpSha3_512, EVP_sha3_512, "SHA3-512", NULL) +BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpShake128, EVP_shake128, "SHAKE-128", NULL) +BUILD_MD_FETCH_LIGHTUP_SHA3(CryptoNative_EvpShake256, EVP_shake256, "SHAKE-256", NULL) int32_t CryptoNative_GetMaxMdSize(void) { diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_ml_dsa.c b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_ml_dsa.c index b8d7a032b2a475..49b280a2eb5289 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_ml_dsa.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_ml_dsa.c @@ -3,6 +3,7 @@ #include "pal_evp_pkey.h" #include "pal_evp_pkey_ml_dsa.h" +#include "pal_evp_pkey_raw_signverify.h" #include "pal_utilities.h" #include "openssl.h" #include @@ -119,11 +120,46 @@ int32_t CryptoNative_MLDsaSignPure(EVP_PKEY *pkey, uint8_t* context, int32_t contextLen, uint8_t* destination, int32_t destinationLen) { - assert(pkey); - assert(msgLen >= 0); - assert(contextLen >= 0); - assert(destination); assert(destinationLen >= 2420 /* ML-DSA-44 signature size */); + return CryptoNative_EvpPKeySignPure(pkey, extraHandle, msg, msgLen, context, contextLen, destination, destinationLen); +} + +int32_t CryptoNative_MLDsaVerifyPure(EVP_PKEY *pkey, + void* extraHandle, + uint8_t* msg, int32_t msgLen, + uint8_t* context, int32_t contextLen, + uint8_t* sig, int32_t sigLen) +{ + assert(sigLen >= 2420 /* ML-DSA-44 signature size */); + return CryptoNative_EvpPKeyVerifyPure(pkey, extraHandle, msg, msgLen, context, contextLen, sig, sigLen); +} + +int32_t CryptoNative_MLDsaSignPreEncoded(EVP_PKEY *pkey, + void* extraHandle, + uint8_t* msg, int32_t msgLen, + uint8_t* destination, int32_t destinationLen) +{ + assert(destinationLen >= 2420 /* ML-DSA-44 signature size */); + return CryptoNative_EvpPKeySignPreEncoded(pkey, extraHandle, msg, msgLen, destination, destinationLen); +} + +int32_t CryptoNative_MLDsaVerifyPreEncoded(EVP_PKEY *pkey, + void* extraHandle, + uint8_t* msg, int32_t msgLen, + uint8_t* sig, int32_t sigLen) +{ + assert(sigLen >= 2420 /* ML-DSA-44 signature size */); + return CryptoNative_EvpPKeyVerifyPreEncoded(pkey, extraHandle, msg, msgLen, sig, sigLen); +} + +int32_t CryptoNative_MLDsaSignExternalMu(EVP_PKEY* pKey, + void* extraHandle, + uint8_t* mu, int32_t muLen, + uint8_t* destination, int32_t destinationLen) +{ + assert(pKey); + assert(muLen >= 0); + assert(destination); #if defined(NEED_OPENSSL_3_0) && HAVE_OPENSSL_EVP_PKEY_SIGN_MESSAGE_INIT if (!API_EXISTS(EVP_PKEY_sign_message_init) || @@ -138,30 +174,29 @@ int32_t CryptoNative_MLDsaSignPure(EVP_PKEY *pkey, int ret = -1; - ctx = EvpPKeyCtxCreateFromPKey(pkey, extraHandle); + ctx = EvpPKeyCtxCreateFromPKey(pKey, extraHandle); + if (!ctx) { goto done; } - OSSL_PARAM contextParams[] = + int muYes = 1; + + OSSL_PARAM initParams[] = { - OSSL_PARAM_construct_end(), + OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_MU, &muYes), OSSL_PARAM_construct_end(), }; - if (context) - { - contextParams[0] = OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, (void*)context, Int32ToSizeT(contextLen)); - } - - if (EVP_PKEY_sign_message_init(ctx, NULL, contextParams) <= 0) + if (EVP_PKEY_sign_message_init(ctx, NULL, initParams) <= 0) { goto done; } size_t dstLen = Int32ToSizeT(destinationLen); - if (EVP_PKEY_sign(ctx, destination, &dstLen, msg, Int32ToSizeT(msgLen)) == 1) + + if (EVP_PKEY_sign(ctx, destination, &dstLen, mu, Int32ToSizeT(muLen)) == 1) { if (dstLen != Int32ToSizeT(destinationLen)) { @@ -180,29 +215,24 @@ int32_t CryptoNative_MLDsaSignPure(EVP_PKEY *pkey, if (ctx != NULL) EVP_PKEY_CTX_free(ctx); return ret; #else - (void)pkey; + (void)pKey; (void)extraHandle; - (void)msg; - (void)msgLen; - (void)context; - (void)contextLen; + (void)mu; + (void)muLen; (void)destination; (void)destinationLen; return -1; #endif } -int32_t CryptoNative_MLDsaVerifyPure(EVP_PKEY *pkey, - void* extraHandle, - uint8_t* msg, int32_t msgLen, - uint8_t* context, int32_t contextLen, - uint8_t* sig, int32_t sigLen) +int32_t CryptoNative_MLDsaVerifyExternalMu(EVP_PKEY* pKey, + void* extraHandle, + uint8_t* mu, int32_t muLen, + uint8_t* sig, int32_t sigLen) { - assert(pkey); - assert(msgLen >= 0); + assert(pKey); + assert(muLen >= 0); assert(sig); - assert(sigLen >= 2420 /* ML-DSA-44 signature size */); - assert(contextLen >= 0); #if defined(NEED_OPENSSL_3_0) && HAVE_OPENSSL_EVP_PKEY_SIGN_MESSAGE_INIT if (!API_EXISTS(EVP_PKEY_sign_message_init) || @@ -217,40 +247,36 @@ int32_t CryptoNative_MLDsaVerifyPure(EVP_PKEY *pkey, int ret = -1; - ctx = EvpPKeyCtxCreateFromPKey(pkey, extraHandle); + ctx = EvpPKeyCtxCreateFromPKey(pKey, extraHandle); + if (!ctx) { goto done; } - OSSL_PARAM contextParams[] = + int muYes = 1; + + OSSL_PARAM initParams[] = { - OSSL_PARAM_construct_end(), + OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_MU, &muYes), OSSL_PARAM_construct_end(), }; - if (context) - { - contextParams[0] = OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, (void*)context, Int32ToSizeT(contextLen)); - } - - if (EVP_PKEY_verify_message_init(ctx, NULL, contextParams) <= 0) + if (EVP_PKEY_verify_message_init(ctx, NULL, initParams) <= 0) { goto done; } - ret = EVP_PKEY_verify(ctx, sig, Int32ToSizeT(sigLen), msg, Int32ToSizeT(msgLen)) == 1; + ret = EVP_PKEY_verify(ctx, sig, Int32ToSizeT(sigLen), mu, Int32ToSizeT(muLen)) == 1; done: if (ctx != NULL) EVP_PKEY_CTX_free(ctx); return ret; #else - (void)pkey; + (void)pKey; (void)extraHandle; - (void)msg; - (void)msgLen; - (void)context; - (void)contextLen; + (void)mu; + (void)muLen; (void)sig; (void)sigLen; return -1; diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_ml_dsa.h b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_ml_dsa.h index dd70967193818b..03242c1e0f073a 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_ml_dsa.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_ml_dsa.h @@ -24,7 +24,7 @@ PALEXPORT EVP_PKEY* CryptoNative_MLDsaGenerateKey(const char* keyType, uint8_t* /* Sign a message using the provided ML-DSA key. -Returns 1 on success, 0 on a mismatched signature, -1 on error. +Returns 1 on success, 0 on signing failure, -1 on other error. */ PALEXPORT int32_t CryptoNative_MLDsaSignPure(EVP_PKEY *pkey, void* extraHandle, @@ -43,6 +43,46 @@ PALEXPORT int32_t CryptoNative_MLDsaVerifyPure(EVP_PKEY *pkey, uint8_t* context, int32_t contextLen, uint8_t* sig, int32_t sigLen); +/* +Sign an encoded message using the provided ML-DSA key. + +Returns 1 on success, 0 on signing failure, -1 on other error. +*/ +PALEXPORT int32_t CryptoNative_MLDsaSignPreEncoded(EVP_PKEY *pkey, + void* extraHandle, + uint8_t* msg, int32_t msgLen, + uint8_t* destination, int32_t destinationLen); + +/* +Verify an encoded message using the provided ML-DSA key. + +Returns 1 on a verified signature, 0 on a mismatched signature, -1 on error. +*/ +PALEXPORT int32_t CryptoNative_MLDsaVerifyPreEncoded(EVP_PKEY *pkey, + void* extraHandle, + uint8_t* msg, int32_t msgLen, + uint8_t* sig, int32_t sigLen); + +/* +Sign an externally produced signature mu with the provided ML-DSA key. + +Returns 1 on success, 0 on signing failure, -1 on other error. +*/ +PALEXPORT int32_t CryptoNative_MLDsaSignExternalMu(EVP_PKEY* pKey, + void* extraHandle, + uint8_t* mu, int32_t muLen, + uint8_t* destination, int32_t destinationLen); + +/* +Verifies an externally produced signature mu with the provided ML-DSA key. + +Returns 1 on success, 0 on mismatched signature, -1 on error. +*/ +PALEXPORT int32_t CryptoNative_MLDsaVerifyExternalMu(EVP_PKEY* pKey, + void* extraHandle, + uint8_t* mu, int32_t muLen, + uint8_t* sig, int32_t sigLen); + /* Export the secret key from the given ML-DSA key. */ diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_raw_signverify.c b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_raw_signverify.c new file mode 100644 index 00000000000000..29852282a2cdda --- /dev/null +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_raw_signverify.c @@ -0,0 +1,278 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "pal_evp_pkey.h" +#include "pal_evp_pkey_raw_signverify.h" +#include "pal_utilities.h" +#include "openssl.h" +#include + +int32_t CryptoNative_EvpPKeySignPure(EVP_PKEY *pkey, + void* extraHandle, + uint8_t* msg, int32_t msgLen, + uint8_t* context, int32_t contextLen, + uint8_t* destination, int32_t destinationLen) +{ + + assert(pkey); + assert(msgLen >= 0); + assert(contextLen >= 0); + assert(destination); + +#if defined(NEED_OPENSSL_3_0) && HAVE_OPENSSL_EVP_PKEY_SIGN_MESSAGE_INIT + if (!API_EXISTS(EVP_PKEY_sign_message_init) || + !API_EXISTS(EVP_PKEY_verify_message_init)) + { + return -1; + } + + ERR_clear_error(); + + EVP_PKEY_CTX* ctx = NULL; + + int ret = -1; + + ctx = EvpPKeyCtxCreateFromPKey(pkey, extraHandle); + if (!ctx) + { + goto done; + } + + OSSL_PARAM contextParams[] = + { + OSSL_PARAM_construct_end(), + OSSL_PARAM_construct_end(), + }; + + if (context) + { + contextParams[0] = OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, (void*)context, Int32ToSizeT(contextLen)); + } + + if (EVP_PKEY_sign_message_init(ctx, NULL, contextParams) <= 0) + { + goto done; + } + + size_t dstLen = Int32ToSizeT(destinationLen); + if (EVP_PKEY_sign(ctx, destination, &dstLen, msg, Int32ToSizeT(msgLen)) == 1) + { + if (dstLen != Int32ToSizeT(destinationLen)) + { + assert(false); // length mismatch + goto done; + } + + ret = 1; + } + else + { + ret = 0; + } + +done: + if (ctx != NULL) EVP_PKEY_CTX_free(ctx); + return ret; +#else + (void)pkey; + (void)extraHandle; + (void)msg; + (void)msgLen; + (void)context; + (void)contextLen; + (void)destination; + (void)destinationLen; + return -1; +#endif +} + +int32_t CryptoNative_EvpPKeyVerifyPure(EVP_PKEY *pkey, + void* extraHandle, + uint8_t* msg, int32_t msgLen, + uint8_t* context, int32_t contextLen, + uint8_t* sig, int32_t sigLen) +{ + assert(pkey); + assert(msgLen >= 0); + assert(sig); + assert(contextLen >= 0); + +#if defined(NEED_OPENSSL_3_0) && HAVE_OPENSSL_EVP_PKEY_SIGN_MESSAGE_INIT + if (!API_EXISTS(EVP_PKEY_sign_message_init) || + !API_EXISTS(EVP_PKEY_verify_message_init)) + { + return -1; + } + + ERR_clear_error(); + + EVP_PKEY_CTX* ctx = NULL; + + int ret = -1; + + ctx = EvpPKeyCtxCreateFromPKey(pkey, extraHandle); + if (!ctx) + { + goto done; + } + + OSSL_PARAM contextParams[] = + { + OSSL_PARAM_construct_end(), + OSSL_PARAM_construct_end(), + }; + + if (context) + { + contextParams[0] = OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, (void*)context, Int32ToSizeT(contextLen)); + } + + if (EVP_PKEY_verify_message_init(ctx, NULL, contextParams) <= 0) + { + goto done; + } + + ret = EVP_PKEY_verify(ctx, sig, Int32ToSizeT(sigLen), msg, Int32ToSizeT(msgLen)) == 1; + +done: + if (ctx != NULL) EVP_PKEY_CTX_free(ctx); + return ret; +#else + (void)pkey; + (void)extraHandle; + (void)msg; + (void)msgLen; + (void)context; + (void)contextLen; + (void)sig; + (void)sigLen; + return -1; +#endif +} + +int32_t CryptoNative_EvpPKeySignPreEncoded(EVP_PKEY *pkey, + void* extraHandle, + uint8_t* msg, int32_t msgLen, + uint8_t* destination, int32_t destinationLen) +{ + + assert(pkey); + assert(msgLen >= 0); + assert(destination); + +#if defined(NEED_OPENSSL_3_0) && HAVE_OPENSSL_EVP_PKEY_SIGN_MESSAGE_INIT + if (!API_EXISTS(EVP_PKEY_sign_message_init) || + !API_EXISTS(EVP_PKEY_verify_message_init)) + { + return -1; + } + + ERR_clear_error(); + + EVP_PKEY_CTX* ctx = NULL; + + int ret = -1; + + ctx = EvpPKeyCtxCreateFromPKey(pkey, extraHandle); + if (!ctx) + { + goto done; + } + + int messageEncoding = 0; + OSSL_PARAM messageEncodingParams[] = + { + OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_MESSAGE_ENCODING, &messageEncoding), + OSSL_PARAM_construct_end(), + }; + + if (EVP_PKEY_sign_message_init(ctx, NULL, messageEncodingParams) <= 0) + { + goto done; + } + + size_t dstLen = Int32ToSizeT(destinationLen); + if (EVP_PKEY_sign(ctx, destination, &dstLen, msg, Int32ToSizeT(msgLen)) == 1) + { + if (dstLen != Int32ToSizeT(destinationLen)) + { + assert(false); // length mismatch + goto done; + } + + ret = 1; + } + else + { + ret = 0; + } + +done: + if (ctx != NULL) EVP_PKEY_CTX_free(ctx); + return ret; +#else + (void)pkey; + (void)extraHandle; + (void)msg; + (void)msgLen; + (void)destination; + (void)destinationLen; + return -1; +#endif +} + +int32_t CryptoNative_EvpPKeyVerifyPreEncoded(EVP_PKEY *pkey, + void* extraHandle, + uint8_t* msg, int32_t msgLen, + uint8_t* sig, int32_t sigLen) +{ + assert(pkey); + assert(msgLen >= 0); + assert(sig); + +#if defined(NEED_OPENSSL_3_0) && HAVE_OPENSSL_EVP_PKEY_SIGN_MESSAGE_INIT + if (!API_EXISTS(EVP_PKEY_sign_message_init) || + !API_EXISTS(EVP_PKEY_verify_message_init)) + { + return -1; + } + + ERR_clear_error(); + + EVP_PKEY_CTX* ctx = NULL; + + int ret = -1; + + ctx = EvpPKeyCtxCreateFromPKey(pkey, extraHandle); + if (!ctx) + { + goto done; + } + + int messageEncoding = 0; + OSSL_PARAM messageEncodingParams[] = + { + OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_MESSAGE_ENCODING, &messageEncoding), + OSSL_PARAM_construct_end(), + }; + + if (EVP_PKEY_verify_message_init(ctx, NULL, messageEncodingParams) <= 0) + { + goto done; + } + + ret = EVP_PKEY_verify(ctx, sig, Int32ToSizeT(sigLen), msg, Int32ToSizeT(msgLen)) == 1; + +done: + if (ctx != NULL) EVP_PKEY_CTX_free(ctx); + return ret; +#else + (void)pkey; + (void)extraHandle; + (void)msg; + (void)msgLen; + (void)sig; + (void)sigLen; + return -1; +#endif +} diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_raw_signverify.h b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_raw_signverify.h new file mode 100644 index 00000000000000..fad34f72428a16 --- /dev/null +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_raw_signverify.h @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#pragma once + +int32_t CryptoNative_EvpPKeySignPure(EVP_PKEY *pkey, + void* extraHandle, + uint8_t* msg, int32_t msgLen, + uint8_t* context, int32_t contextLen, + uint8_t* destination, int32_t destinationLen); + +int32_t CryptoNative_EvpPKeyVerifyPure(EVP_PKEY *pkey, + void* extraHandle, + uint8_t* msg, int32_t msgLen, + uint8_t* context, int32_t contextLen, + uint8_t* sig, int32_t sigLen); + +int32_t CryptoNative_EvpPKeySignPreEncoded(EVP_PKEY *pkey, + void* extraHandle, + uint8_t* msg, int32_t msgLen, + uint8_t* destination, int32_t destinationLen); + +int32_t CryptoNative_EvpPKeyVerifyPreEncoded(EVP_PKEY *pkey, + void* extraHandle, + uint8_t* msg, int32_t msgLen, + uint8_t* sig, int32_t sigLen); diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_slh_dsa.c b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_slh_dsa.c index 5b2935674e4923..e5b362703e0d83 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_slh_dsa.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey_slh_dsa.c @@ -3,6 +3,7 @@ #include "pal_evp_pkey.h" #include "pal_evp_pkey_slh_dsa.h" +#include "pal_evp_pkey_raw_signverify.h" #include "pal_utilities.h" #include "openssl.h" #include @@ -56,78 +57,8 @@ int32_t CryptoNative_SlhDsaSignPure(EVP_PKEY *pkey, uint8_t* context, int32_t contextLen, uint8_t* destination, int32_t destinationLen) { - - assert(pkey); - assert(msgLen >= 0); - assert(contextLen >= 0); - assert(destination); assert(destinationLen >= 7856 /* SLH-DSA-SHA2-128s/SLH-DSA-SHAKE-128s signature size */); - -#if defined(NEED_OPENSSL_3_0) && HAVE_OPENSSL_EVP_PKEY_SIGN_MESSAGE_INIT - if (!API_EXISTS(EVP_PKEY_sign_message_init) || - !API_EXISTS(EVP_PKEY_verify_message_init)) - { - return -1; - } - - ERR_clear_error(); - - EVP_PKEY_CTX* ctx = NULL; - - int ret = -1; - - ctx = EvpPKeyCtxCreateFromPKey(pkey, extraHandle); - if (!ctx) - { - goto done; - } - - OSSL_PARAM contextParams[] = - { - OSSL_PARAM_construct_end(), - OSSL_PARAM_construct_end(), - }; - - if (context) - { - contextParams[0] = OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, (void*)context, Int32ToSizeT(contextLen)); - } - - if (EVP_PKEY_sign_message_init(ctx, NULL, contextParams) <= 0) - { - goto done; - } - - size_t dstLen = Int32ToSizeT(destinationLen); - if (EVP_PKEY_sign(ctx, destination, &dstLen, msg, Int32ToSizeT(msgLen)) == 1) - { - if (dstLen != Int32ToSizeT(destinationLen)) - { - assert(false); // length mismatch - goto done; - } - - ret = 1; - } - else - { - ret = 0; - } - -done: - if (ctx != NULL) EVP_PKEY_CTX_free(ctx); - return ret; -#else - (void)pkey; - (void)extraHandle; - (void)msg; - (void)msgLen; - (void)context; - (void)contextLen; - (void)destination; - (void)destinationLen; - return -1; -#endif + return CryptoNative_EvpPKeySignPure(pkey, extraHandle, msg, msgLen, context, contextLen, destination, destinationLen); } int32_t CryptoNative_SlhDsaVerifyPure(EVP_PKEY *pkey, @@ -136,63 +67,8 @@ int32_t CryptoNative_SlhDsaVerifyPure(EVP_PKEY *pkey, uint8_t* context, int32_t contextLen, uint8_t* sig, int32_t sigLen) { - assert(pkey); - assert(msgLen >= 0); - assert(sig); assert(sigLen >= 7856 /* SLH-DSA-SHA2-128s/SLH-DSA-SHAKE-128s signature size */); - assert(contextLen >= 0); - -#if defined(NEED_OPENSSL_3_0) && HAVE_OPENSSL_EVP_PKEY_SIGN_MESSAGE_INIT - if (!API_EXISTS(EVP_PKEY_sign_message_init) || - !API_EXISTS(EVP_PKEY_verify_message_init)) - { - return -1; - } - - ERR_clear_error(); - - EVP_PKEY_CTX* ctx = NULL; - - int ret = -1; - - ctx = EvpPKeyCtxCreateFromPKey(pkey, extraHandle); - if (!ctx) - { - goto done; - } - - OSSL_PARAM contextParams[] = - { - OSSL_PARAM_construct_end(), - OSSL_PARAM_construct_end(), - }; - - if (context) - { - contextParams[0] = OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, (void*)context, Int32ToSizeT(contextLen)); - } - - if (EVP_PKEY_verify_message_init(ctx, NULL, contextParams) <= 0) - { - goto done; - } - - ret = EVP_PKEY_verify(ctx, sig, Int32ToSizeT(sigLen), msg, Int32ToSizeT(msgLen)) == 1; - -done: - if (ctx != NULL) EVP_PKEY_CTX_free(ctx); - return ret; -#else - (void)pkey; - (void)extraHandle; - (void)msg; - (void)msgLen; - (void)context; - (void)contextLen; - (void)sig; - (void)sigLen; - return -1; -#endif + return CryptoNative_EvpPKeyVerifyPure(pkey, extraHandle, msg, msgLen, context, contextLen, sig, sigLen); } int32_t CryptoNative_SlhDsaSignPreEncoded(EVP_PKEY *pkey, @@ -200,71 +76,8 @@ int32_t CryptoNative_SlhDsaSignPreEncoded(EVP_PKEY *pkey, uint8_t* msg, int32_t msgLen, uint8_t* destination, int32_t destinationLen) { - - assert(pkey); - assert(msgLen >= 0); - assert(destination); assert(destinationLen >= 7856 /* SLH-DSA-SHA2-128s/SLH-DSA-SHAKE-128s signature size */); - -#if defined(NEED_OPENSSL_3_0) && HAVE_OPENSSL_EVP_PKEY_SIGN_MESSAGE_INIT - if (!API_EXISTS(EVP_PKEY_sign_message_init) || - !API_EXISTS(EVP_PKEY_verify_message_init)) - { - return -1; - } - - ERR_clear_error(); - - EVP_PKEY_CTX* ctx = NULL; - - int ret = -1; - - ctx = EvpPKeyCtxCreateFromPKey(pkey, extraHandle); - if (!ctx) - { - goto done; - } - - int messageEncoding = 0; - OSSL_PARAM contextParams[] = - { - OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_MESSAGE_ENCODING, &messageEncoding), - OSSL_PARAM_construct_end(), - }; - - if (EVP_PKEY_sign_message_init(ctx, NULL, contextParams) <= 0) - { - goto done; - } - - size_t dstLen = Int32ToSizeT(destinationLen); - if (EVP_PKEY_sign(ctx, destination, &dstLen, msg, Int32ToSizeT(msgLen)) == 1) - { - if (dstLen != Int32ToSizeT(destinationLen)) - { - assert(false); // length mismatch - goto done; - } - - ret = 1; - } - else - { - ret = 0; - } - -done: - if (ctx != NULL) EVP_PKEY_CTX_free(ctx); - return ret; -#else - (void)pkey; - (void)extraHandle; - (void)msg; - (void)msgLen; - (void)destination; - (void)destinationLen; - return -1; -#endif + return CryptoNative_EvpPKeySignPreEncoded(pkey, extraHandle, msg, msgLen, destination, destinationLen); } int32_t CryptoNative_SlhDsaVerifyPreEncoded(EVP_PKEY *pkey, @@ -272,56 +85,8 @@ int32_t CryptoNative_SlhDsaVerifyPreEncoded(EVP_PKEY *pkey, uint8_t* msg, int32_t msgLen, uint8_t* sig, int32_t sigLen) { - assert(pkey); - assert(msgLen >= 0); - assert(sig); assert(sigLen >= 7856 /* SLH-DSA-SHA2-128s/SLH-DSA-SHAKE-128s signature size */); - -#if defined(NEED_OPENSSL_3_0) && HAVE_OPENSSL_EVP_PKEY_SIGN_MESSAGE_INIT - if (!API_EXISTS(EVP_PKEY_sign_message_init) || - !API_EXISTS(EVP_PKEY_verify_message_init)) - { - return -1; - } - - ERR_clear_error(); - - EVP_PKEY_CTX* ctx = NULL; - - int ret = -1; - - ctx = EvpPKeyCtxCreateFromPKey(pkey, extraHandle); - if (!ctx) - { - goto done; - } - - int messageEncoding = 0; - OSSL_PARAM contextParams[] = - { - OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_MESSAGE_ENCODING, &messageEncoding), - OSSL_PARAM_construct_end(), - }; - - if (EVP_PKEY_verify_message_init(ctx, NULL, contextParams) <= 0) - { - goto done; - } - - ret = EVP_PKEY_verify(ctx, sig, Int32ToSizeT(sigLen), msg, Int32ToSizeT(msgLen)) == 1; - -done: - if (ctx != NULL) EVP_PKEY_CTX_free(ctx); - return ret; -#else - (void)pkey; - (void)extraHandle; - (void)msg; - (void)msgLen; - (void)sig; - (void)sigLen; - return -1; -#endif + return CryptoNative_EvpPKeyVerifyPreEncoded(pkey, extraHandle, msg, msgLen, sig, sigLen); } int32_t CryptoNative_SlhDsaExportSecretKey(const EVP_PKEY* pKey, uint8_t* destination, int32_t destinationLength) diff --git a/src/native/libs/build-native.proj b/src/native/libs/build-native.proj index 2b5dcac9ae4a41..32965c2e584c58 100644 --- a/src/native/libs/build-native.proj +++ b/src/native/libs/build-native.proj @@ -59,6 +59,8 @@ --> <_BuildNativeCompilerArg Condition="'$(BuildNativeCompiler)' != ''"> $(BuildNativeCompiler) <_BuildNativeUnixArgs>$(_BuildNativeArgs)$(_ProcessorCountArg)$(_PortableBuildArg)$(_CrossBuildArg)$(_BuildNativeCompilerArg)$(_KeepNativeSymbolsBuildArg)$(_CMakeArgs) $(Compiler) + <_BuildNativeBuildCommand>"$(MSBuildThisFileDirectory)build-native.sh" $(_BuildNativeUnixArgs) + <_BuildNativeBuildCommand Condition="'$(TargetsBrowser)' == 'true'">bash -c 'source "$(RepoRoot)src/mono/browser/emsdk/emsdk_env.sh" && $(_BuildNativeBuildCommand)' @@ -72,8 +74,8 @@ - - + + - - + + /// Gets an instance of the Exception contract for the target. ///
- public abstract IException Exception { get;} + public abstract IException Exception { get; } /// /// Gets an instance of the Loader contract for the target. /// @@ -68,7 +68,7 @@ public abstract class ContractRegistry ///
public abstract IRuntimeInfo RuntimeInfo { get; } /// - /// Gets an instance of the ECall contract for the target. + /// Gets an instance of the DebugInfo contract for the target. /// - public abstract IECall ECall { get; } + public abstract IDebugInfo DebugInfo { get; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/Extensions/ICodeVersionsExtensions.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/Extensions/ICodeVersionsExtensions.cs index e207e101606146..61a4f8a81f4c06 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/Extensions/ICodeVersionsExtensions.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/Extensions/ICodeVersionsExtensions.cs @@ -10,4 +10,22 @@ public static NativeCodeVersionHandle GetActiveNativeCodeVersion(this ICodeVersi ILCodeVersionHandle ilCodeVersionHandle = cv.GetActiveILCodeVersion(methodDesc); return cv.GetActiveNativeCodeVersionForILCodeVersion(methodDesc, ilCodeVersionHandle); } + + public static TargetCodePointer GetNativeCodeAnyVersion(this ICodeVersions cv, TargetPointer methodDesc) + { + foreach (ILCodeVersionHandle ilCodeVersionHandle in cv.GetILCodeVersions(methodDesc)) + { + foreach (NativeCodeVersionHandle nativeCodeVersionHandle in cv.GetNativeCodeVersions(methodDesc, ilCodeVersionHandle)) + { + if (cv.GetNativeCode(nativeCodeVersionHandle) != TargetCodePointer.Null) + { + return cv.GetNativeCode(nativeCodeVersionHandle); + } + } + } + return TargetCodePointer.Null; + } + + public static bool HasNativeCodeAnyVersion(this ICodeVersions cv, TargetPointer methodDesc) + => cv.GetNativeCodeAnyVersion(methodDesc) != TargetCodePointer.Null; } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ICodeVersions.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ICodeVersions.cs index 921d37583d8607..3817368120e7fc 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ICodeVersions.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ICodeVersions.cs @@ -16,6 +16,8 @@ public interface ICodeVersions : IContract public virtual IEnumerable GetILCodeVersions(TargetPointer methodDesc) => throw new NotImplementedException(); + public virtual IEnumerable GetNativeCodeVersions(TargetPointer methodDesc, ILCodeVersionHandle ilCodeVersionHandle) => throw new NotImplementedException(); + public virtual NativeCodeVersionHandle GetNativeCodeVersionForIP(TargetCodePointer ip) => throw new NotImplementedException(); public virtual NativeCodeVersionHandle GetActiveNativeCodeVersionForILCodeVersion(TargetPointer methodDesc, ILCodeVersionHandle ilCodeVersionHandle) => throw new NotImplementedException(); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IDebugInfo.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IDebugInfo.cs new file mode 100644 index 00000000000000..80a34bb8aef754 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IDebugInfo.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +namespace Microsoft.Diagnostics.DataContractReader.Contracts; + +[Flags] +public enum SourceTypes : uint +{ + /// + /// Indicates that no other options apply + /// + SourceTypeInvalid = 0x00, + /// + /// The stack is empty here + /// + StackEmpty = 0x01, + /// + /// The actual instruction of a call + /// + CallInstruction = 0x02, +} + +public readonly struct OffsetMapping +{ + public uint NativeOffset { get; init; } + public uint ILOffset { get; init; } + public SourceTypes SourceType { get; init; } +} + +public interface IDebugInfo : IContract +{ + static string IContract.Name { get; } = nameof(DebugInfo); + IEnumerable GetMethodNativeMap(TargetCodePointer pCode, bool preferUninstrumented, out uint codeOffset) => throw new NotImplementedException(); +} + +public readonly struct DebugInfo : IDebugInfo +{ + // Everything throws NotImplementedException +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IECall.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IECall.cs deleted file mode 100644 index 34e0965ed8145b..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IECall.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. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public interface IECall : IContract -{ - static string IContract.Name { get; } = nameof(ECall); - - TargetPointer MapTargetBackToMethodDesc(TargetCodePointer codePointer) => throw new NotImplementedException(); -} - -public readonly struct ECall : IECall -{ - // throws NotImplementedException for all methods -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IExecutionManager.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IExecutionManager.cs index 408d8e8f91846f..8a9653e17e7618 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IExecutionManager.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IExecutionManager.cs @@ -21,6 +21,7 @@ public interface IExecutionManager : IContract TargetCodePointer GetFuncletStartAddress(CodeBlockHandle codeInfoHandle) => throw new NotImplementedException(); TargetPointer GetUnwindInfo(CodeBlockHandle codeInfoHandle) => throw new NotImplementedException(); TargetPointer GetUnwindInfoBaseAddress(CodeBlockHandle codeInfoHandle) => throw new NotImplementedException(); + TargetPointer GetDebugInfo(CodeBlockHandle codeInfoHandle, out bool hasFlagByte) => throw new NotImplementedException(); // **Currently GetGCInfo only supports X86** void GetGCInfo(CodeBlockHandle codeInfoHandle, out TargetPointer gcInfo, out uint gcVersion) => throw new NotImplementedException(); TargetNUInt GetRelativeOffset(CodeBlockHandle codeInfoHandle) => throw new NotImplementedException(); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs index 38be405a5138a1..8822dfee7ba384 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs @@ -41,15 +41,6 @@ public enum ModuleFlags BeingUnloaded = 0x100000, } -public record struct ModuleLookupTables( - TargetPointer FieldDefToDesc, - TargetPointer ManifestModuleReferences, - TargetPointer MemberRefToDesc, - TargetPointer MethodDefToDesc, - TargetPointer TypeDefToMethodTable, - TargetPointer TypeRefToMethodTable, - TargetPointer MethodDefToILCodeVersioningState); - [Flags] public enum AssemblyIterationFlags { @@ -71,14 +62,25 @@ public enum AssemblyIterationFlags IncludeCollected = 0x00000080, // Include all collectible assemblies that have been collected } +public record struct ModuleLookupTables( + TargetPointer FieldDefToDesc, + TargetPointer ManifestModuleReferences, + TargetPointer MemberRefToDesc, + TargetPointer MethodDefToDesc, + TargetPointer TypeDefToMethodTable, + TargetPointer TypeRefToMethodTable, + TargetPointer MethodDefToILCodeVersioningState); + public interface ILoader : IContract { static string IContract.Name => nameof(Loader); - ModuleHandle GetModuleHandle(TargetPointer modulePointer) => throw new NotImplementedException(); - - IEnumerable GetModules(TargetPointer appDomain, AssemblyIterationFlags iterationFlags) => throw new NotImplementedException(); + ModuleHandle GetModuleHandleFromModulePtr(TargetPointer modulePointer) => throw new NotImplementedException(); + ModuleHandle GetModuleHandleFromAssemblyPtr(TargetPointer assemblyPointer) => throw new NotImplementedException(); + IEnumerable GetModuleHandles(TargetPointer appDomain, AssemblyIterationFlags iterationFlags) => throw new NotImplementedException(); TargetPointer GetRootAssembly() => throw new NotImplementedException(); + string GetAppDomainFriendlyName() => throw new NotImplementedException(); + TargetPointer GetModule(ModuleHandle handle) => throw new NotImplementedException(); TargetPointer GetAssembly(ModuleHandle handle) => throw new NotImplementedException(); TargetPointer GetPEAssembly(ModuleHandle handle) => throw new NotImplementedException(); bool TryGetLoadedImageContents(ModuleHandle handle, out TargetPointer baseAddress, out uint size, out uint imageFlags) => throw new NotImplementedException(); @@ -92,11 +94,16 @@ public interface ILoader : IContract string GetFileName(ModuleHandle handle) => throw new NotImplementedException(); TargetPointer GetLoaderAllocator(ModuleHandle handle) => throw new NotImplementedException(); TargetPointer GetILBase(ModuleHandle handle) => throw new NotImplementedException(); + TargetPointer GetAssemblyLoadContext(ModuleHandle handle) => throw new NotImplementedException(); ModuleLookupTables GetLookupTables(ModuleHandle handle) => throw new NotImplementedException(); - TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out TargetNUInt flags) => throw new NotImplementedException(); bool IsCollectible(ModuleHandle handle) => throw new NotImplementedException(); bool IsAssemblyLoaded(ModuleHandle handle) => throw new NotImplementedException(); + + TargetPointer GetGlobalLoaderAllocator() => throw new NotImplementedException(); + TargetPointer GetHighFrequencyHeap(TargetPointer loaderAllocatorPointer) => throw new NotImplementedException(); + TargetPointer GetLowFrequencyHeap(TargetPointer loaderAllocatorPointer) => throw new NotImplementedException(); + TargetPointer GetStubHeap(TargetPointer loaderAllocatorPointer) => throw new NotImplementedException(); } public readonly struct Loader : ILoader diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IRuntimeTypeSystem.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IRuntimeTypeSystem.cs index 51e7670e1789d4..d0f4476fbbca1a 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IRuntimeTypeSystem.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IRuntimeTypeSystem.cs @@ -100,16 +100,27 @@ public interface IRuntimeTypeSystem : IContract // True if the MethodTable represents a type that contains managed references bool ContainsGCPointers(TypeHandle typeHandle) => throw new NotImplementedException(); bool IsDynamicStatics(TypeHandle typeHandle) => throw new NotImplementedException(); - ushort GetNumMethods(TypeHandle typeHandle) => throw new NotImplementedException(); ushort GetNumInterfaces(TypeHandle typeHandle) => throw new NotImplementedException(); // Returns an ECMA-335 TypeDef table token for this type, or for its generic type definition if it is a generic instantiation uint GetTypeDefToken(TypeHandle typeHandle) => throw new NotImplementedException(); + ushort GetNumMethods(TypeHandle typeHandle) => throw new NotImplementedException(); // Returns the ECMA 335 TypeDef table Flags value (a bitmask of TypeAttributes) for this type, // or for its generic type definition if it is a generic instantiation uint GetTypeDefTypeAttributes(TypeHandle typeHandle) => throw new NotImplementedException(); + ushort GetNumInstanceFields(TypeHandle typeHandle) => throw new NotImplementedException(); + ushort GetNumStaticFields(TypeHandle typeHandle) => throw new NotImplementedException(); + ushort GetNumThreadStaticFields(TypeHandle typeHandle) => throw new NotImplementedException(); + TargetPointer GetFieldDescList(TypeHandle typeHandle) => throw new NotImplementedException(); + TargetPointer GetGCStaticsBasePointer(TypeHandle typeHandle) => throw new NotImplementedException(); + TargetPointer GetNonGCStaticsBasePointer(TypeHandle typeHandle) => throw new NotImplementedException(); + TargetPointer GetGCThreadStaticsBasePointer(TypeHandle typeHandle, TargetPointer threadPtr) => throw new NotImplementedException(); + TargetPointer GetNonGCThreadStaticsBasePointer(TypeHandle typeHandle, TargetPointer threadPtr) => throw new NotImplementedException(); + ReadOnlySpan GetInstantiation(TypeHandle typeHandle) => throw new NotImplementedException(); + public bool IsClassInited(TypeHandle typeHandle) => throw new NotImplementedException(); + public bool IsInitError(TypeHandle typeHandle) => throw new NotImplementedException(); bool IsGenericTypeDefinition(TypeHandle typeHandle) => throw new NotImplementedException(); bool HasTypeParam(TypeHandle typeHandle) => throw new NotImplementedException(); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IThread.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IThread.cs index 4966e8ac5b3290..09d796f0e0773a 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IThread.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IThread.cs @@ -48,6 +48,8 @@ public interface IThread : IContract ThreadStoreData GetThreadStoreData() => throw new NotImplementedException(); ThreadStoreCounts GetThreadCounts() => throw new NotImplementedException(); ThreadData GetThreadData(TargetPointer thread) => throw new NotImplementedException(); + TargetPointer IdToThread(uint id) => throw new NotImplementedException(); + TargetPointer GetThreadLocalStaticBase(TargetPointer threadPointer, TargetPointer tlsIndexPtr) => throw new NotImplementedException(); } public readonly struct Thread : IThread diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/CorDbHResults.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/CorDbHResults.cs new file mode 100644 index 00000000000000..089e49ee17591c --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/CorDbHResults.cs @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.Diagnostics.DataContractReader; + +public static class CorDbgHResults +{ + public const int CORDBG_E_READVIRTUAL_FAILURE = unchecked((int)0x80131c49); +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs index 9ab4b9ac7b0019..86fb2923186657 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs @@ -23,22 +23,30 @@ public enum DataType CodePointer, Thread, ThreadStore, + ThreadLocalData, + ThreadStaticsInfo, + InFlightTLSData, + TLSIndex, GCAllocContext, EEAllocContext, Exception, ExceptionInfo, RuntimeThreadLocals, + IdDispenser, Module, ModuleLookupMap, AppDomain, + SystemDomain, Assembly, LoaderAllocator, PEAssembly, + AssemblyBinder, PEImage, PEImageLayout, CGrowableSymbolStream, ProbeExtensionResult, MethodTable, + DynamicStaticsInfo, EEClass, ArrayClass, MethodTableAuxiliaryData, @@ -102,7 +110,8 @@ public enum DataType ArrayListBlock, EETypeHashTable, InstMethodHashTable, - ECHash, + EEJitManager, + PatchpointInfo, TransitionBlock, DebuggerEval, diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Target.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Target.cs index 72dbd5d03955ee..d691dd0eedd23e 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Target.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Target.cs @@ -55,14 +55,16 @@ public abstract class Target /// Read a pointer from the target in target endianness /// /// Address to start reading from - /// Pointer read from the target} + /// Pointer read from the target + /// Thrown when the read operation fails public abstract TargetPointer ReadPointer(ulong address); /// /// Read a code pointer from the target in target endianness /// /// Address to start reading from - /// Pointer read from the target} + /// Pointer read from the target + /// Thrown when the read operation fails public abstract TargetCodePointer ReadCodePointer(ulong address); /// @@ -70,20 +72,30 @@ public abstract class Target /// /// The address where to start reading /// Destination to copy the bytes, the number of bytes to read is the span length + /// Thrown when the read operation fails public abstract void ReadBuffer(ulong address, Span buffer); + /// + /// Write some bytes to the target + /// + /// The address where to start writing + /// Source of the bytes to write, the number of bytes to write is the span length + public abstract void WriteBuffer(ulong address, Span buffer); + /// /// Read a null-terminated UTF-8 string from the target /// /// Address to start reading from - /// String read from the target} + /// String read from the target + /// Thrown when the read operation fails public abstract string ReadUtf8String(ulong address); /// /// Read a null-terminated UTF-16 string from the target in target endianness /// /// Address to start reading from - /// String read from the target} + /// String read from the target + /// Thrown when the read operation fails public abstract string ReadUtf16String(ulong address); /// @@ -91,6 +103,7 @@ public abstract class Target /// /// Address to start reading from /// Value read from the target + /// Thrown when the read operation fails public abstract TargetNUInt ReadNUInt(ulong address); /// @@ -131,8 +144,25 @@ public abstract class Target /// Type of value to read /// Address to start reading from /// Value read from the target + /// Thrown when the read operation fails public abstract T Read(ulong address) where T : unmanaged, IBinaryInteger, IMinMaxValue; + /// + /// Read a value from the target in target endianness + /// + /// Type of value to read + /// Address to start reading from + /// True if read succeeds, false otherwise. + public abstract bool TryRead(ulong address, out T value) where T : unmanaged, IBinaryInteger, IMinMaxValue; + + /// + /// Write a value to the target in target endianness + /// + /// Type of value to write + /// Address to start writing to + /// Value to write + public abstract void Write(ulong address, T value) where T : unmanaged, IBinaryInteger, IMinMaxValue; + /// /// Read a target pointer from a span of bytes /// @@ -219,16 +249,16 @@ public readonly record struct FieldInfo /// /// The byte offset of the field in an instance of the type in the target process /// - public int Offset {get; init; } + public int Offset { get; init; } /// /// The well known data type of the field in the target process /// - public readonly DataType Type {get; init;} + public readonly DataType Type { get; init; } /// /// The name of the well known data type of the field in the target process, or null /// if the target data descriptor did not record a name /// - public readonly string? TypeName {get; init; } + public readonly string? TypeName { get; init; } } /// diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/VirtualReadException.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/VirtualReadException.cs new file mode 100644 index 00000000000000..99aa85b6fbd962 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/VirtualReadException.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader; + +/// +/// Exception thrown when a virtual memory read operation fails. +/// +public class VirtualReadException : Exception +{ + /// + /// Initializes a new instance of the class. + /// + public VirtualReadException() + { + HResult = CorDbgHResults.CORDBG_E_READVIRTUAL_FAILURE; + } + + /// + /// Initializes a new instance of the class with a specified error message. + /// + /// The message that describes the error. + public VirtualReadException(string message) : base(message) + { + HResult = CorDbgHResults.CORDBG_E_READVIRTUAL_FAILURE; + } + + /// + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference if no inner exception is specified. + public VirtualReadException(string message, Exception innerException) : base(message, innerException) + { + HResult = CorDbgHResults.CORDBG_E_READVIRTUAL_FAILURE; + } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs index 20b90d29a8f19d..e8a7e41e6a4afe 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs @@ -15,6 +15,7 @@ public static class Globals public const string GCThread = nameof(GCThread); public const string FeatureCOMInterop = nameof(FeatureCOMInterop); + public const string FeatureOnStackReplacement = nameof(FeatureOnStackReplacement); public const string ObjectToMethodTableUnmask = nameof(ObjectToMethodTableUnmask); public const string SOSBreakingChangeVersion = nameof(SOSBreakingChangeVersion); @@ -27,6 +28,10 @@ public static class Globals public const string MiniMetaDataBuffAddress = nameof(MiniMetaDataBuffAddress); public const string MiniMetaDataBuffMaxSize = nameof(MiniMetaDataBuffMaxSize); + public const string DacNotificationFlags = nameof(DacNotificationFlags); + public const string OffsetOfCurrentThreadInfo = nameof(OffsetOfCurrentThreadInfo); + public const string TlsIndexBase = nameof(TlsIndexBase); + public const string ThinlockThreadIdDispenser = nameof(ThinlockThreadIdDispenser); public const string StressLogEnabled = nameof(StressLogEnabled); public const string StressLogHasModuleTable = nameof(StressLogHasModuleTable); @@ -51,6 +56,12 @@ public static class Globals public const string ExecutionManagerCodeRangeMapAddress = nameof(ExecutionManagerCodeRangeMapAddress); public const string StubCodeBlockLast = nameof(StubCodeBlockLast); + public const string DefaultADID = nameof(DefaultADID); + public const string StaticsPointerMask = nameof(StaticsPointerMask); + public const string PtrArrayOffsetToDataArray = nameof(PtrArrayOffsetToDataArray); + public const string NumberOfTlsOffsetsNotUsedInNoncollectibleArray = nameof(NumberOfTlsOffsetsNotUsedInNoncollectibleArray); + public const string MaxClrNotificationArgs = nameof(MaxClrNotificationArgs); + public const string ClrNotificationArguments = nameof(ClrNotificationArguments); public const string PlatformMetadata = nameof(PlatformMetadata); public const string ProfilerControlBlock = nameof(ProfilerControlBlock); @@ -63,9 +74,6 @@ public static class Globals public const string OperatingSystem = nameof(OperatingSystem); public const string GCInfoVersion = nameof(GCInfoVersion); - - public const string FCallHashSize = nameof(FCallHashSize); - public const string FCallMethods = nameof(FCallMethods); } public static class FieldNames { diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/CodeVersions_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/CodeVersions_1.cs index 70fec695684029..29be26f871c9f7 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/CodeVersions_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/CodeVersions_1.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using Microsoft.Diagnostics.DataContractReader.Data; namespace Microsoft.Diagnostics.DataContractReader.Contracts; @@ -88,6 +89,32 @@ IEnumerable ICodeVersions.GetILCodeVersions(TargetPointer m } } + IEnumerable ICodeVersions.GetNativeCodeVersions(TargetPointer methodDesc, ILCodeVersionHandle ilCodeVersionHandle) + { + if (!ilCodeVersionHandle.IsValid) + yield break; + + if (!ilCodeVersionHandle.IsExplicit) + { + // if the ILCodeVersion is synthetic, then yield the synthetic NativeCodeVersion + NativeCodeVersionHandle provisionalHandle = NativeCodeVersionHandle.CreateSynthetic(methodDesc); + yield return provisionalHandle; + } + + // Iterate through versioning state nodes and return the active one, matching any IL code version + Contracts.IRuntimeTypeSystem rts = _target.Contracts.RuntimeTypeSystem; + MethodDescHandle md = rts.GetMethodDescHandle(methodDesc); + TargetNUInt ilVersionId = GetId(ilCodeVersionHandle); + IEnumerable nativeCodeVersions = FindNativeCodeVersionNodes( + rts, + md, + (codeVersion) => ilVersionId == codeVersion.ILVersionId); + foreach (NativeCodeVersionHandle nativeCodeVersion in nativeCodeVersions) + { + yield return nativeCodeVersion; + } + } + NativeCodeVersionHandle ICodeVersions.GetNativeCodeVersionForIP(TargetCodePointer ip) { // ExecutionManager::GetNativeCodeVersion(PCODE ip)) @@ -128,7 +155,7 @@ bool ICodeVersions.CodeVersionManagerSupportsMethod(TargetPointer methodDescAddr TypeHandle mt = rts.GetTypeHandle(mtAddr); TargetPointer modAddr = rts.GetModule(mt); ILoader loader = _target.Contracts.Loader; - ModuleHandle mod = loader.GetModuleHandle(modAddr); + ModuleHandle mod = loader.GetModuleHandleFromModulePtr(modAddr); ModuleFlags modFlags = loader.GetFlags(mod); if (modFlags.HasFlag(ModuleFlags.EditAndContinue)) return false; @@ -176,11 +203,11 @@ NativeCodeVersionHandle ICodeVersions.GetActiveNativeCodeVersionForILCodeVersion Contracts.IRuntimeTypeSystem rts = _target.Contracts.RuntimeTypeSystem; MethodDescHandle md = rts.GetMethodDescHandle(methodDesc); TargetNUInt ilVersionId = GetId(ilCodeVersionHandle); - return FindFirstCodeVersion(rts, md, (codeVersion) => + return FindNativeCodeVersionNodes(rts, md, (codeVersion) => { return (ilVersionId == codeVersion.ILVersionId) && ((NativeCodeVersionNodeFlags)codeVersion.Flags).HasFlag(NativeCodeVersionNodeFlags.IsActiveChild); - }); + }).FirstOrDefault(NativeCodeVersionHandle.Invalid); } TargetPointer ICodeVersions.GetGCStressCodeCopy(NativeCodeVersionHandle codeVersionHandle) @@ -224,18 +251,18 @@ private NativeCodeVersionHandle GetSpecificNativeCodeVersion(IRuntimeTypeSystem } // CodeVersionManager::GetNativeCodeVersion(PTR_MethodDesc, PCODE startAddress) - return FindFirstCodeVersion(rts, md, (codeVersion) => + return FindNativeCodeVersionNodes(rts, md, (codeVersion) => { return codeVersion.MethodDesc == md.Address && codeVersion.NativeCode == startAddress; - }); + }).FirstOrDefault(NativeCodeVersionHandle.Invalid); } - private NativeCodeVersionHandle FindFirstCodeVersion(IRuntimeTypeSystem rts, MethodDescHandle md, Func predicate) + private IEnumerable FindNativeCodeVersionNodes(IRuntimeTypeSystem rts, MethodDescHandle md, Func predicate) { // ImplicitCodeVersion stage of NativeCodeVersionIterator::Next() TargetPointer versioningStateAddr = rts.GetMethodDescVersioningState(md); if (versioningStateAddr == TargetPointer.Null) - return NativeCodeVersionHandle.Invalid; + yield break; Data.MethodDescVersioningState versioningState = _target.ProcessedData.GetOrAdd(versioningStateAddr); @@ -246,11 +273,11 @@ private NativeCodeVersionHandle FindFirstCodeVersion(IRuntimeTypeSystem rts, Met Data.NativeCodeVersionNode current = _target.ProcessedData.GetOrAdd(currentAddress); if (predicate(current)) { - return NativeCodeVersionHandle.CreateExplicit(currentAddress); + yield return NativeCodeVersionHandle.CreateExplicit(currentAddress); } currentAddress = current.Next; } - return NativeCodeVersionHandle.Invalid; + yield break; } private enum ILCodeVersionKind @@ -324,7 +351,7 @@ private TargetPointer GetILVersionStateAddress(TargetPointer module, uint method if (methodDefToken == (uint)EcmaMetadataUtils.TokenType.mdtMethodDef) return TargetPointer.Null; - ModuleHandle moduleHandle = _target.Contracts.Loader.GetModuleHandle(module); + ModuleHandle moduleHandle = _target.Contracts.Loader.GetModuleHandleFromModulePtr(module); TargetPointer ilCodeVersionTable = _target.Contracts.Loader.GetLookupTables(moduleHandle).MethodDefToILCodeVersioningState; TargetPointer ilVersionStateAddress = _target.Contracts.Loader.GetModuleLookupMapElement(ilCodeVersionTable, methodDefToken, out var _); return ilVersionStateAddress; diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ECallFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DebugInfo/DebugInfoFactory.cs similarity index 53% rename from src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ECallFactory.cs rename to src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DebugInfo/DebugInfoFactory.cs index 10e160aa764fe6..40072342b05892 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ECallFactory.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DebugInfo/DebugInfoFactory.cs @@ -3,14 +3,14 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts; -public sealed class ECallFactory : IContractFactory +public sealed class DebugInfoFactory : IContractFactory { - IECall IContractFactory.CreateContract(Target target, int version) + IDebugInfo IContractFactory.CreateContract(Target target, int version) { return version switch { - 1 => new ECall_1(target), - _ => default(ECall), + 1 => new DebugInfo_1(target), + _ => default(DebugInfo), }; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DebugInfo/DebugInfo_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DebugInfo/DebugInfo_1.cs new file mode 100644 index 00000000000000..a5ac95ca95847e --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DebugInfo/DebugInfo_1.cs @@ -0,0 +1,161 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using ILCompiler.Reflection.ReadyToRun; + +namespace Microsoft.Diagnostics.DataContractReader.Contracts; + +internal sealed class DebugInfo_1(Target target) : IDebugInfo +{ + private const uint DEBUG_INFO_BOUNDS_HAS_INSTRUMENTED_BOUNDS = 0xFFFFFFFF; + private const uint IL_OFFSET_BIAS = unchecked((uint)-3); + + [Flags] + internal enum ExtraDebugInfoFlags_1 : byte + { + // Debug info contains patchpoint information + EXTRA_DEBUG_INFO_PATCHPOINT = 0x01, + // Debug info contains rich information + EXTRA_DEBUG_INFO_RICH = 0x02, + } + + private readonly Target _target = target; + private readonly IExecutionManager _eman = target.Contracts.ExecutionManager; + + IEnumerable IDebugInfo.GetMethodNativeMap(TargetCodePointer pCode, bool preferUninstrumented, out uint codeOffset) + { + // Get the method's DebugInfo + if (_eman.GetCodeBlockHandle(pCode) is not CodeBlockHandle cbh) + throw new InvalidOperationException($"No CodeBlockHandle found for native code {pCode}."); + TargetPointer debugInfo = _eman.GetDebugInfo(cbh, out bool hasFlagByte); + + TargetCodePointer nativeCodeStart = _eman.GetStartAddress(cbh); + codeOffset = (uint)(CodePointerUtils.AddressFromCodePointer(pCode, _target) - CodePointerUtils.AddressFromCodePointer(nativeCodeStart, _target)); + + return RestoreBoundaries(debugInfo, hasFlagByte, preferUninstrumented); + } + + private IEnumerable RestoreBoundaries(TargetPointer debugInfo, bool hasFlagByte, bool preferUninstrumented) + { + if (hasFlagByte) + { + // Check flag byte and skip over any patchpoint info + ExtraDebugInfoFlags_1 flagByte = (ExtraDebugInfoFlags_1)_target.Read(debugInfo++); + + if (flagByte.HasFlag(ExtraDebugInfoFlags_1.EXTRA_DEBUG_INFO_PATCHPOINT)) + { + Data.PatchpointInfo patchpointInfo = _target.ProcessedData.GetOrAdd(debugInfo); + + if (_target.GetTypeInfo(DataType.PatchpointInfo).Size is not uint patchpointSize) + throw new InvalidOperationException("PatchpointInfo type size is not defined."); + debugInfo += patchpointSize + (patchpointInfo.LocalCount * sizeof(uint)); + + flagByte &= ~ExtraDebugInfoFlags_1.EXTRA_DEBUG_INFO_PATCHPOINT; + } + + if (flagByte.HasFlag(ExtraDebugInfoFlags_1.EXTRA_DEBUG_INFO_RICH)) + { + uint richDebugInfoSize = _target.Read(debugInfo); + debugInfo += 4; + debugInfo += richDebugInfoSize; + flagByte &= ~ExtraDebugInfoFlags_1.EXTRA_DEBUG_INFO_RICH; + } + + Debug.Assert(flagByte == 0); + } + + NativeReader nibbleNativeReader = new(new TargetStream(_target, debugInfo, 24 /*maximum size of 4 32bit ints compressed*/), _target.IsLittleEndian); + NibbleReader nibbleReader = new(nibbleNativeReader, 0); + + uint cbBounds = nibbleReader.ReadUInt(); + uint cbUninstrumentedBounds = 0; + if (cbBounds == DEBUG_INFO_BOUNDS_HAS_INSTRUMENTED_BOUNDS) + { + // This means we have instrumented bounds. + cbBounds = nibbleReader.ReadUInt(); + cbUninstrumentedBounds = nibbleReader.ReadUInt(); + } + uint _ /*cbVars*/ = nibbleReader.ReadUInt(); + + TargetPointer addrBounds = debugInfo + (uint)nibbleReader.GetNextByteOffset(); + // TargetPointer addrVars = addrBounds + cbBounds + cbUninstrumentedBounds; + + if (preferUninstrumented && cbUninstrumentedBounds != 0) + { + // If we have uninstrumented bounds, we will use them instead of the regular bounds. + addrBounds += cbBounds; + cbBounds = cbUninstrumentedBounds; + } + + if (cbBounds > 0) + { + NativeReader boundsNativeReader = new(new TargetStream(_target, addrBounds, cbBounds), _target.IsLittleEndian); + return DoBounds(boundsNativeReader); + } + + return Enumerable.Empty(); + } + + private static IEnumerable DoBounds(NativeReader nativeReader) + { + NibbleReader reader = new(nativeReader, 0); + + uint boundsEntryCount = reader.ReadUInt(); + Debug.Assert(boundsEntryCount > 0, "Expected at least one entry in bounds."); + + uint bitsForNativeDelta = reader.ReadUInt() + 1; // Number of bits needed for native deltas + uint bitsForILOffsets = reader.ReadUInt() + 1; // Number of bits needed for IL offsets + + uint bitsPerEntry = bitsForNativeDelta + bitsForILOffsets + 2; // 2 bits for source type + ulong bitsMeaningfulMask = (1UL << ((int)bitsPerEntry)) - 1; + int offsetOfActualBoundsData = reader.GetNextByteOffset(); + + uint bitsCollected = 0; + ulong bitTemp = 0; + uint curBoundsProcessed = 0; + + uint previousNativeOffset = 0; + + while (curBoundsProcessed < boundsEntryCount) + { + bitTemp |= ((uint)nativeReader[offsetOfActualBoundsData++]) << (int)bitsCollected; + bitsCollected += 8; + while (bitsCollected >= bitsPerEntry) + { + ulong mappingDataEncoded = bitsMeaningfulMask & bitTemp; + bitTemp >>= (int)bitsPerEntry; + bitsCollected -= bitsPerEntry; + + SourceTypes sourceType = (mappingDataEncoded & 0x3) switch + { + 0 => SourceTypes.SourceTypeInvalid, + 1 => SourceTypes.CallInstruction, + 2 => SourceTypes.StackEmpty, + 3 => SourceTypes.StackEmpty | SourceTypes.CallInstruction, + _ => throw new InvalidOperationException($"Unknown source type encoding: {mappingDataEncoded & 0x3}") + }; + + mappingDataEncoded >>= 2; + uint nativeOffsetDelta = (uint)(mappingDataEncoded & ((1UL << (int)bitsForNativeDelta) - 1)); + previousNativeOffset += nativeOffsetDelta; + uint nativeOffset = previousNativeOffset; + + mappingDataEncoded >>= (int)bitsForNativeDelta; + uint ilOffset = (uint)mappingDataEncoded + IL_OFFSET_BIAS; + + yield return new OffsetMapping() + { + NativeOffset = nativeOffset, + ILOffset = ilOffset, + SourceType = sourceType + }; + curBoundsProcessed++; + } + } + + } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ECall_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ECall_1.cs deleted file mode 100644 index 7c2cbe1414907e..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ECall_1.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -internal readonly struct ECall_1 : IECall -{ - private readonly Target _target; - - internal ECall_1(Target target) - { - _target = target; - } - - TargetPointer IECall.MapTargetBackToMethodDesc(TargetCodePointer codePointer) - { - if (codePointer == TargetCodePointer.Null) - return TargetPointer.Null; - - - TargetPointer pECHashTable = _target.ReadGlobalPointer(Constants.Globals.FCallMethods); - - TargetPointer pECHash = pECHashTable + (ulong)(FCallHash(codePointer) * _target.PointerSize); - TargetPointer ecHashAddr = _target.ReadPointer(pECHash); - - while (ecHashAddr != TargetPointer.Null) - { - Data.ECHash eCHash = _target.ProcessedData.GetOrAdd(ecHashAddr); - if (eCHash.Implementation == codePointer) - { - return eCHash.MethodDesc; - } - ecHashAddr = eCHash.Next; - } - - return TargetPointer.Null; // not found - } - - private uint FCallHash(TargetCodePointer codePointer) - { - // see FCallHash in ecall.cpp - uint hashBucketCount = _target.ReadGlobal(Constants.Globals.FCallHashSize); - return (uint)(codePointer.Value % hashBucketCount); - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.EEJitManager.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.EEJitManager.cs index 6a23be3be862d4..c62499cad64ef7 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.EEJitManager.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.EEJitManager.cs @@ -75,6 +75,30 @@ public override TargetPointer GetUnwindInfo(RangeSection rangeSection, TargetCod return _runtimeFunctions.GetRuntimeFunctionAddress(realCodeHeader.UnwindInfos, index); } + public override TargetPointer GetDebugInfo(RangeSection rangeSection, TargetCodePointer jittedCodeAddress, out bool hasFlagByte) + { + hasFlagByte = false; + if (rangeSection.IsRangeList) + return TargetPointer.Null; + if (rangeSection.Data == null) + throw new ArgumentException(nameof(rangeSection)); + + TargetPointer codeStart = FindMethodCode(rangeSection, jittedCodeAddress); + if (codeStart == TargetPointer.Null) + return TargetPointer.Null; + Debug.Assert(codeStart.Value <= jittedCodeAddress.Value); + + if (!GetRealCodeHeader(rangeSection, codeStart, out Data.RealCodeHeader? realCodeHeader)) + return TargetPointer.Null; + + bool featureOnStackReplacement = Target.ReadGlobal(Constants.Globals.FeatureOnStackReplacement) != 0; + Data.EEJitManager eeJitManager = Target.ProcessedData.GetOrAdd(rangeSection.Data.JitManager); + if (featureOnStackReplacement || eeJitManager.StoreRichDebugInfo) + hasFlagByte = true; + + return realCodeHeader.DebugInfo; + } + public override void GetGCInfo(RangeSection rangeSection, TargetCodePointer jittedCodeAddress, out TargetPointer gcInfo, out uint gcVersion) { gcInfo = TargetPointer.Null; diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.ReadyToRunJitManager.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.ReadyToRunJitManager.cs index bdbe99980c4107..166e85ca8945b3 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.ReadyToRunJitManager.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.ReadyToRunJitManager.cs @@ -70,6 +70,40 @@ public override TargetPointer GetUnwindInfo(RangeSection rangeSection, TargetCod return _runtimeFunctions.GetRuntimeFunctionAddress(r2rInfo.RuntimeFunctions, index); } + public override TargetPointer GetDebugInfo(RangeSection rangeSection, TargetCodePointer jittedCodeAddress, out bool hasFlagByte) + { + // ReadyToRun does not contain PatchpointInfo + hasFlagByte = false; + + // ReadyToRunJitManager::GetDebugInfo + Data.ReadyToRunInfo r2rInfo = GetReadyToRunInfo(rangeSection); + if (!GetRuntimeFunction(rangeSection, r2rInfo, jittedCodeAddress, out TargetPointer imageBase, out uint index)) + return TargetPointer.Null; + + index = AdjustRuntimeFunctionIndexForHotCold(r2rInfo, index); + index = AdjustRuntimeFunctionToMethodStart(r2rInfo, imageBase, index, out _); + + Data.ImageDataDirectory debugInfoData = Target.ProcessedData.GetOrAdd(r2rInfo.DebugInfoSection); + + ILCompiler.Reflection.ReadyToRun.NativeReader imageReader = new( + new TargetStream(Target, imageBase, debugInfoData.VirtualAddress + debugInfoData.Size), + Target.IsLittleEndian + ); + ILCompiler.Reflection.ReadyToRun.NativeArray debugInfoArray = new(imageReader, debugInfoData.VirtualAddress); + + int offset = 0; + if (!debugInfoArray.TryGetAt(index, ref offset)) + // If the index is not found in the debug info array, return null + return TargetPointer.Null; + + uint lookBack = 0; + uint debugInfoOffset = imageReader.DecodeUnsigned((uint)offset, ref lookBack); + if (lookBack != 0) + debugInfoOffset = (uint)offset - lookBack; + + return imageBase + debugInfoOffset; + } + public override void GetGCInfo(RangeSection rangeSection, TargetCodePointer jittedCodeAddress, out TargetPointer gcInfo, out uint gcVersion) { gcInfo = TargetPointer.Null; diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.cs index 6d9b993dcfff6c..7161eae75e3840 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.cs @@ -66,6 +66,7 @@ protected JitManager(Target target) public abstract bool GetMethodInfo(RangeSection rangeSection, TargetCodePointer jittedCodeAddress, [NotNullWhen(true)] out CodeBlock? info); public abstract TargetPointer GetUnwindInfo(RangeSection rangeSection, TargetCodePointer jittedCodeAddress); + public abstract TargetPointer GetDebugInfo(RangeSection rangeSection, TargetCodePointer jittedCodeAddress, out bool hasFlagByte); public abstract void GetGCInfo(RangeSection rangeSection, TargetCodePointer jittedCodeAddress, out TargetPointer gcInfo, out uint gcVersion); } @@ -230,6 +231,20 @@ TargetPointer IExecutionManager.GetUnwindInfoBaseAddress(CodeBlockHandle codeInf return range.Data.RangeBegin; } + TargetPointer IExecutionManager.GetDebugInfo(CodeBlockHandle codeInfoHandle, out bool hasFlagByte) + { + hasFlagByte = false; + if (!_codeInfos.TryGetValue(codeInfoHandle.Address, out CodeBlock? info)) + throw new InvalidOperationException($"{nameof(CodeBlock)} not found for {codeInfoHandle.Address}"); + + RangeSection range = RangeSection.Find(_target, _topRangeSectionMap, _rangeSectionMapLookup, codeInfoHandle.Address.Value); + if (range.Data == null) + return TargetPointer.Null; + + JitManager jitManager = GetJitManager(range.Data); + return jitManager.GetDebugInfo(range, codeInfoHandle.Address.Value, out hasFlagByte); + } + void IExecutionManager.GetGCInfo(CodeBlockHandle codeInfoHandle, out TargetPointer gcInfo, out uint gcVersion) { gcInfo = TargetPointer.Null; diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_1.cs index 2feda4180c2feb..551c664237096c 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_1.cs @@ -20,6 +20,7 @@ internal ExecutionManager_1(Target target, Data.RangeSectionMap topRangeSectionM public TargetCodePointer GetFuncletStartAddress(CodeBlockHandle codeInfoHandle) => _executionManagerCore.GetFuncletStartAddress(codeInfoHandle); public TargetPointer GetUnwindInfo(CodeBlockHandle codeInfoHandle) => _executionManagerCore.GetUnwindInfo(codeInfoHandle); public TargetPointer GetUnwindInfoBaseAddress(CodeBlockHandle codeInfoHandle) => _executionManagerCore.GetUnwindInfoBaseAddress(codeInfoHandle); + public TargetPointer GetDebugInfo(CodeBlockHandle codeInfoHandle, out bool hasFlagByte) => _executionManagerCore.GetDebugInfo(codeInfoHandle, out hasFlagByte); public void GetGCInfo(CodeBlockHandle codeInfoHandle, out TargetPointer gcInfo, out uint gcVersion) => _executionManagerCore.GetGCInfo(codeInfoHandle, out gcInfo, out gcVersion); public TargetNUInt GetRelativeOffset(CodeBlockHandle codeInfoHandle) => _executionManagerCore.GetRelativeOffset(codeInfoHandle); } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_2.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_2.cs index 356081e289b492..ab1fda5e329640 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_2.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_2.cs @@ -20,6 +20,7 @@ internal ExecutionManager_2(Target target, Data.RangeSectionMap topRangeSectionM public TargetCodePointer GetFuncletStartAddress(CodeBlockHandle codeInfoHandle) => _executionManagerCore.GetFuncletStartAddress(codeInfoHandle); public TargetPointer GetUnwindInfo(CodeBlockHandle codeInfoHandle) => _executionManagerCore.GetUnwindInfo(codeInfoHandle); public TargetPointer GetUnwindInfoBaseAddress(CodeBlockHandle codeInfoHandle) => _executionManagerCore.GetUnwindInfoBaseAddress(codeInfoHandle); + public TargetPointer GetDebugInfo(CodeBlockHandle codeInfoHandle, out bool hasFlagByte) => _executionManagerCore.GetDebugInfo(codeInfoHandle, out hasFlagByte); public void GetGCInfo(CodeBlockHandle codeInfoHandle, out TargetPointer gcInfo, out uint gcVersion) => _executionManagerCore.GetGCInfo(codeInfoHandle, out gcInfo, out gcVersion); public TargetNUInt GetRelativeOffset(CodeBlockHandle codeInfoHandle) => _executionManagerCore.GetRelativeOffset(codeInfoHandle); } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs index 9df2e7f91dfdb3..2d2562625e4688 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs @@ -44,15 +44,26 @@ internal Loader_1(Target target) _target = target; } - ModuleHandle ILoader.GetModuleHandle(TargetPointer modulePointer) + ModuleHandle ILoader.GetModuleHandleFromModulePtr(TargetPointer modulePointer) { if (modulePointer == TargetPointer.Null) throw new ArgumentNullException(nameof(modulePointer)); return new ModuleHandle(modulePointer); } + ModuleHandle ILoader.GetModuleHandleFromAssemblyPtr(TargetPointer assemblyPointer) + { + if (assemblyPointer == TargetPointer.Null) + throw new ArgumentNullException(nameof(assemblyPointer)); + + Data.Assembly assembly = _target.ProcessedData.GetOrAdd(assemblyPointer); + if (assembly.Module == TargetPointer.Null) + throw new InvalidOperationException("Assembly does not have a module associated with it."); + + return new ModuleHandle(assembly.Module); + } - IEnumerable ILoader.GetModules(TargetPointer appDomain, AssemblyIterationFlags iterationFlags) + IEnumerable ILoader.GetModuleHandles(TargetPointer appDomain, AssemblyIterationFlags iterationFlags) { if (appDomain == TargetPointer.Null) throw new ArgumentNullException(nameof(appDomain)); @@ -130,6 +141,20 @@ TargetPointer ILoader.GetRootAssembly() return appDomain.RootAssembly; } + string ILoader.GetAppDomainFriendlyName() + { + TargetPointer appDomainPointer = _target.ReadGlobalPointer(Constants.Globals.AppDomain); + Data.AppDomain appDomain = _target.ProcessedData.GetOrAdd(_target.ReadPointer(appDomainPointer)); + return appDomain.FriendlyName != TargetPointer.Null + ? _target.ReadUtf16String(appDomain.FriendlyName) + : string.Empty; + } + + TargetPointer ILoader.GetModule(ModuleHandle handle) + { + return handle.Address; + } + TargetPointer ILoader.GetAssembly(ModuleHandle handle) { Data.Module module = _target.ProcessedData.GetOrAdd(handle.Address); @@ -305,6 +330,15 @@ TargetPointer ILoader.GetILBase(ModuleHandle handle) return module.Base; } + TargetPointer ILoader.GetAssemblyLoadContext(ModuleHandle handle) + { + Data.Module module = _target.ProcessedData.GetOrAdd(handle.Address); + Data.PEAssembly peAssembly = _target.ProcessedData.GetOrAdd(module.PEAssembly); + Data.AssemblyBinder binder = _target.ProcessedData.GetOrAdd(peAssembly.AssemblyBinder); + Data.ObjectHandle objectHandle = _target.ProcessedData.GetOrAdd(binder.AssemblyLoadContext); + return objectHandle.Object; + } + ModuleLookupTables ILoader.GetLookupTables(ModuleHandle handle) { Data.Module module = _target.ProcessedData.GetOrAdd(handle.Address); @@ -363,4 +397,29 @@ bool ILoader.IsAssemblyLoaded(ModuleHandle handle) Data.Assembly assembly = _target.ProcessedData.GetOrAdd(module.Assembly); return assembly.Level >= ASSEMBLY_LEVEL_LOADED /* IsLoaded */; } + + TargetPointer ILoader.GetGlobalLoaderAllocator() + { + TargetPointer systemDomainPointer = _target.ReadGlobalPointer(Constants.Globals.SystemDomain); + Data.SystemDomain systemDomain = _target.ProcessedData.GetOrAdd(_target.ReadPointer(systemDomainPointer)); + return systemDomain.GlobalLoaderAllocator; + } + + TargetPointer ILoader.GetHighFrequencyHeap(TargetPointer loaderAllocatorPointer) + { + Data.LoaderAllocator loaderAllocator = _target.ProcessedData.GetOrAdd(loaderAllocatorPointer); + return loaderAllocator.HighFrequencyHeap; + } + + TargetPointer ILoader.GetLowFrequencyHeap(TargetPointer loaderAllocatorPointer) + { + Data.LoaderAllocator loaderAllocator = _target.ProcessedData.GetOrAdd(loaderAllocatorPointer); + return loaderAllocator.LowFrequencyHeap; + } + + TargetPointer ILoader.GetStubHeap(TargetPointer loaderAllocatorPointer) + { + Data.LoaderAllocator loaderAllocator = _target.ProcessedData.GetOrAdd(loaderAllocatorPointer); + return loaderAllocator.StubHeap; + } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubsFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubsFactory.cs index 2687e1d361fe96..c47d671ed5058d 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubsFactory.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubsFactory.cs @@ -17,6 +17,7 @@ IPrecodeStubs IContractFactory.CreateContract(Target target, int { 1 => new PrecodeStubs_1(target, precodeMachineDescriptor, codePointerFlags), 2 => new PrecodeStubs_2(target, precodeMachineDescriptor, codePointerFlags), + 3 => new PrecodeStubs_3(target, precodeMachineDescriptor, codePointerFlags), _ => default(PrecodeStubs), }; } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_1.cs index 1fec6033ad9e9f..d34699a6314f7e 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_1.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; +using Microsoft.Diagnostics.DataContractReader.Data; namespace Microsoft.Diagnostics.DataContractReader.Contracts; @@ -31,6 +32,77 @@ public static byte StubPrecodeData_GetType(Data.StubPrecodeData_1 stubPrecodeDat { return stubPrecodeData.Type; } + + internal static byte ReadPrecodeType(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) + { + if (precodeMachineDescriptor.ReadWidthOfPrecodeType!.Value == 1) + { + byte precodeType = target.Read(instrPointer + precodeMachineDescriptor.OffsetOfPrecodeType!.Value); + return (byte)(precodeType >> precodeMachineDescriptor.ShiftOfPrecodeType!.Value); + } + else if (precodeMachineDescriptor.ReadWidthOfPrecodeType!.Value == 2) + { + ushort precodeType = target.Read(instrPointer + precodeMachineDescriptor.OffsetOfPrecodeType!.Value); + return (byte)(precodeType >> precodeMachineDescriptor.ShiftOfPrecodeType!.Value); + } + else + { + throw new InvalidOperationException($"Invalid precode type width {precodeMachineDescriptor.ReadWidthOfPrecodeType}"); + } + } + + public static KnownPrecodeType? TryGetKnownPrecodeType(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) + { + return TryGetKnownPrecodeType_Impl(instrPointer, target, precodeMachineDescriptor); + } + + public static KnownPrecodeType? TryGetKnownPrecodeType_Impl(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) where TPrecodeStubsImplementation : IPrecodeStubsContractCommonApi where TStubPrecodeData : IData + { + // We get the precode type in two phases: + // 1. Read the precode type from the intruction address. + // 2. If it's "stub", look at the stub data and get the actual precode type - it could be stub, + // but it could also be a pinvoke precode or a ThisPtrRetBufPrecode + // precode.h Precode::GetType() + byte approxPrecodeType = ReadPrecodeType(instrPointer, target, precodeMachineDescriptor); + byte exactPrecodeType; + if (approxPrecodeType == precodeMachineDescriptor.StubPrecodeType) + { + // get the actual type from the StubPrecodeData + TStubPrecodeData stubPrecodeData = GetStubPrecodeData(instrPointer, target, precodeMachineDescriptor); + exactPrecodeType = TPrecodeStubsImplementation.StubPrecodeData_GetType(stubPrecodeData); + } + else + { + exactPrecodeType = approxPrecodeType; + } + + if (exactPrecodeType == precodeMachineDescriptor.StubPrecodeType) + { + return KnownPrecodeType.Stub; + } + else if (precodeMachineDescriptor.PInvokeImportPrecodeType is byte ndType && exactPrecodeType == ndType) + { + return KnownPrecodeType.PInvokeImport; + } + else if (precodeMachineDescriptor.FixupPrecodeType is byte fixupType && exactPrecodeType == fixupType) + { + return KnownPrecodeType.Fixup; + } + else if (precodeMachineDescriptor.ThisPointerRetBufPrecodeType is byte thisPtrRetBufType && exactPrecodeType == thisPtrRetBufType) + { + return KnownPrecodeType.ThisPtrRetBuf; + } + else + { + return null; + } + + static TStubPrecodeData GetStubPrecodeData(TargetPointer stubInstrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) + { + TargetPointer stubPrecodeDataAddress = stubInstrPointer + precodeMachineDescriptor.StubCodePageSize; + return target.ProcessedData.GetOrAdd(stubPrecodeDataAddress); + } + } } internal sealed class PrecodeStubs_1 : PrecodeStubsCommon diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_2.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_2.cs index 37d73a2df7b288..f62cb97b29c255 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_2.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_2.cs @@ -23,16 +23,22 @@ public static TargetPointer FixupPrecode_GetMethodDesc(TargetPointer instrPointe public static TargetPointer ThisPtrRetBufPrecode_GetMethodDesc(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) { - TargetPointer stubPrecodeDataAddress = instrPointer + precodeMachineDescriptor.StubCodePageSize; - Data.StubPrecodeData_2 stubPrecodeData = target.ProcessedData.GetOrAdd(stubPrecodeDataAddress); - Data.ThisPtrRetBufPrecodeData thisPtrRetBufPrecodeData = target.ProcessedData.GetOrAdd(stubPrecodeData.SecretParam); - return thisPtrRetBufPrecodeData.MethodDesc; + TargetPointer stubPrecodeDataAddress = instrPointer + precodeMachineDescriptor.StubCodePageSize; + Data.StubPrecodeData_2 stubPrecodeData = target.ProcessedData.GetOrAdd(stubPrecodeDataAddress); + Data.ThisPtrRetBufPrecodeData thisPtrRetBufPrecodeData = target.ProcessedData.GetOrAdd(stubPrecodeData.SecretParam); + return thisPtrRetBufPrecodeData.MethodDesc; } public static byte StubPrecodeData_GetType(Data.StubPrecodeData_2 stubPrecodeData) { return stubPrecodeData.Type; } + + public static KnownPrecodeType? TryGetKnownPrecodeType(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) + { + // Version 2 of this contract behaves just like version 1 other than the details that are abstracted away through the IPrecodeStubsContractCommonApi interface + return PrecodeStubs_1_Impl.TryGetKnownPrecodeType_Impl(instrPointer, target, precodeMachineDescriptor); + } } internal sealed class PrecodeStubs_2 : PrecodeStubsCommon diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_3.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_3.cs new file mode 100644 index 00000000000000..d9c52c907defee --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_3.cs @@ -0,0 +1,104 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics; + +namespace Microsoft.Diagnostics.DataContractReader.Contracts; + +internal struct PrecodeStubs_3_Impl : IPrecodeStubsContractCommonApi +{ + public static TargetPointer StubPrecode_GetMethodDesc(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) + { + // Version 3 of this contract behaves just like version 2 + return PrecodeStubs_2_Impl.StubPrecode_GetMethodDesc(instrPointer, target, precodeMachineDescriptor); + } + + public static TargetPointer FixupPrecode_GetMethodDesc(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) + { + // Version 3 of this contract behaves just like version 1 + return PrecodeStubs_1_Impl.FixupPrecode_GetMethodDesc(instrPointer, target, precodeMachineDescriptor); + } + + public static TargetPointer ThisPtrRetBufPrecode_GetMethodDesc(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) + { + // Version 3 of this contract behaves just like version 2 + return PrecodeStubs_2_Impl.ThisPtrRetBufPrecode_GetMethodDesc(instrPointer, target, precodeMachineDescriptor); + } + + public static byte StubPrecodeData_GetType(Data.StubPrecodeData_2 stubPrecodeData) + { + // Version 3 of this contract behaves just like version 2 + return PrecodeStubs_2_Impl.StubPrecodeData_GetType(stubPrecodeData); + } + + private static Data.StubPrecodeData_2 GetStubPrecodeData(TargetPointer stubInstrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) + { + TargetPointer stubPrecodeDataAddress = stubInstrPointer + precodeMachineDescriptor.StubCodePageSize; + return target.ProcessedData.GetOrAdd(stubPrecodeDataAddress); + } + + public static KnownPrecodeType? TryGetKnownPrecodeType(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor) + { + if (ReadBytesAndCompare(instrPointer, precodeMachineDescriptor.StubBytes!, precodeMachineDescriptor.StubIgnoredBytes!, target)) + { + // get the actual type from the StubPrecodeData + Data.StubPrecodeData_2 stubPrecodeData = GetStubPrecodeData(instrPointer, target, precodeMachineDescriptor); + byte exactPrecodeType = stubPrecodeData.Type; + if (exactPrecodeType == 0) + return null; + + if (exactPrecodeType == precodeMachineDescriptor.StubPrecodeType) + { + return KnownPrecodeType.Stub; + } + else if (precodeMachineDescriptor.PInvokeImportPrecodeType is byte compareByte1 && compareByte1 == exactPrecodeType) + { + return KnownPrecodeType.PInvokeImport; + } + else if (precodeMachineDescriptor.ThisPointerRetBufPrecodeType is byte compareByte2 && compareByte2 == exactPrecodeType) + { + return KnownPrecodeType.ThisPtrRetBuf; + } + else if (precodeMachineDescriptor.UMEntryPrecodeType is byte compareByte3 && compareByte3 == exactPrecodeType) + { + return KnownPrecodeType.UMEntry; + } + else if (precodeMachineDescriptor.InterpreterPrecodeType is byte compareByte4 && compareByte4 == exactPrecodeType) + { + return KnownPrecodeType.Interpreter; + } + else if (precodeMachineDescriptor.DynamicHelperPrecodeType is byte compareByte5 && compareByte5 == exactPrecodeType) + { + return KnownPrecodeType.DynamicHelper; + } + } + else if (ReadBytesAndCompare(instrPointer, precodeMachineDescriptor.FixupBytes!, precodeMachineDescriptor.FixupIgnoredBytes!, target)) + { + return KnownPrecodeType.Fixup; + } + return null; + + static bool ReadBytesAndCompare(TargetPointer instrAddress, byte[] expectedBytePattern, byte[] bytesToIgnore, Target target) + { + for (ulong i = 0; i < (ulong)expectedBytePattern.Length; i++) + { + if (bytesToIgnore[i] == 0) + { + byte targetBytePattern = target.Read(new TargetPointer((instrAddress.Value + (ulong)i))); + if (expectedBytePattern[i] != targetBytePattern) + { + return false; + } + } + } + + return true; + } + } +} + +internal sealed class PrecodeStubs_3 : PrecodeStubsCommon +{ + public PrecodeStubs_3(Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor, CodePointerFlags codePointerFlags) : base(target, precodeMachineDescriptor, codePointerFlags) { } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_Common.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_Common.cs index aeb97ab7a522cd..88c61ef14cb742 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_Common.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_Common.cs @@ -7,6 +7,17 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts; +internal enum KnownPrecodeType +{ + Stub = 1, + PInvokeImport, + Fixup, + ThisPtrRetBuf, + UMEntry, + Interpreter, + DynamicHelper +} + // Interface used to abstract behavior which may be different between multiple versions of the precode stub implementations internal interface IPrecodeStubsContractCommonApi { @@ -14,6 +25,7 @@ internal interface IPrecodeStubsContractCommonApi public static abstract TargetPointer ThisPtrRetBufPrecode_GetMethodDesc(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor); public static abstract TargetPointer FixupPrecode_GetMethodDesc(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor); public static abstract byte StubPrecodeData_GetType(TStubPrecodeData stubPrecodeData); + public static abstract KnownPrecodeType? TryGetKnownPrecodeType(TargetPointer instrPointer, Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor); } internal class PrecodeStubsCommon : IPrecodeStubs where TPrecodeStubsImplementation : IPrecodeStubsContractCommonApi where TStubPrecodeData : IData @@ -22,14 +34,6 @@ internal class PrecodeStubsCommon private readonly CodePointerFlags _codePointerFlags; internal readonly Data.PrecodeMachineDescriptor MachineDescriptor; - internal enum KnownPrecodeType - { - Stub = 1, - PInvokeImport, // also known as NDirectImport in the runtime - Fixup, - ThisPtrRetBuf, - } - internal abstract class ValidPrecode { public TargetPointer InstrPointer { get; } @@ -42,7 +46,6 @@ protected ValidPrecode(TargetPointer instrPointer, KnownPrecodeType precodeType) } internal abstract TargetPointer GetMethodDesc(Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor); - } internal class StubPrecode : ValidPrecode @@ -81,24 +84,6 @@ internal override TargetPointer GetMethodDesc(Target target, Data.PrecodeMachine private bool IsAlignedInstrPointer(TargetPointer instrPointer) => _target.IsAlignedToPointerSize(instrPointer); - private byte ReadPrecodeType(TargetPointer instrPointer) - { - if (MachineDescriptor.ReadWidthOfPrecodeType == 1) - { - byte precodeType = _target.Read(instrPointer + MachineDescriptor.OffsetOfPrecodeType); - return (byte)(precodeType >> MachineDescriptor.ShiftOfPrecodeType); - } - else if (MachineDescriptor.ReadWidthOfPrecodeType == 2) - { - ushort precodeType = _target.Read(instrPointer + MachineDescriptor.OffsetOfPrecodeType); - return (byte)(precodeType >> MachineDescriptor.ShiftOfPrecodeType); - } - else - { - throw new InvalidOperationException($"Invalid precode type width {MachineDescriptor.ReadWidthOfPrecodeType}"); - } - } - private TStubPrecodeData GetStubPrecodeData(TargetPointer stubInstrPointer) { TargetPointer stubPrecodeDataAddress = stubInstrPointer + MachineDescriptor.StubCodePageSize; @@ -107,44 +92,7 @@ private TStubPrecodeData GetStubPrecodeData(TargetPointer stubInstrPointer) private KnownPrecodeType? TryGetKnownPrecodeType(TargetPointer instrAddress) { - // We get the precode type in two phases: - // 1. Read the precode type from the intruction address. - // 2. If it's "stub", look at the stub data and get the actual precode type - it could be stub, - // but it could also be a pinvoke precode or a ThisPtrRetBufPrecode - // precode.h Precode::GetType() - byte approxPrecodeType = ReadPrecodeType(instrAddress); - byte exactPrecodeType; - if (approxPrecodeType == MachineDescriptor.StubPrecodeType) - { - // get the actual type from the StubPrecodeData - TStubPrecodeData stubPrecodeData = GetStubPrecodeData(instrAddress); - exactPrecodeType = TPrecodeStubsImplementation.StubPrecodeData_GetType(stubPrecodeData); - } - else - { - exactPrecodeType = approxPrecodeType; - } - - if (exactPrecodeType == MachineDescriptor.StubPrecodeType) - { - return KnownPrecodeType.Stub; - } - else if (MachineDescriptor.PInvokeImportPrecodeType is byte ndType && exactPrecodeType == ndType) - { - return KnownPrecodeType.PInvokeImport; - } - else if (MachineDescriptor.FixupPrecodeType is byte fixupType && exactPrecodeType == fixupType) - { - return KnownPrecodeType.Fixup; - } - else if (MachineDescriptor.ThisPointerRetBufPrecodeType is byte thisPtrRetBufType && exactPrecodeType == thisPtrRetBufType) - { - return KnownPrecodeType.ThisPtrRetBuf; - } - else - { - return null; - } + return TPrecodeStubsImplementation.TryGetKnownPrecodeType(instrAddress, _target, MachineDescriptor); } internal TargetPointer CodePointerReadableInstrPointer(TargetCodePointer codePointer) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs index 06772fbe3a71d3..9bb21f02365ce8 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs @@ -87,7 +87,13 @@ internal enum MethodDescChunkFlags : ushort // Has this chunk had its methods been determined eligible for tiered compilation or not DeterminedIsEligibleForTieredCompilation = 0x4000, // Is this chunk associated with a LoaderModule directly? If this flag is set, then the LoaderModule pointer is placed at the end of the chunk. - LoaderModuleAttachedToChunk = 0x8000, + LoaderModuleAttachedToChunk = 0x8000, + } + + internal enum MethodTableAuxiliaryFlags : uint + { + Initialized = 0x0001, + IsInitError = 0x0100, } internal struct MethodDesc @@ -331,6 +337,35 @@ public TypeHandle GetTypeHandle(TargetPointer typeHandlePointer) _ = _methodTables.TryAdd(methodTablePointer, trustedMethodTableF); return new TypeHandle(methodTablePointer); } + public TargetPointer GetModule(TypeHandle typeHandle) + { + if (typeHandle.IsMethodTable()) + { + return _methodTables[typeHandle.Address].Module; + } + else if (typeHandle.IsTypeDesc()) + { + if (HasTypeParam(typeHandle)) + { + return GetModule(GetTypeParam(typeHandle)); + } + else if (IsGenericVariable(typeHandle, out TargetPointer genericParamModule, out _)) + { + return genericParamModule; + } + else + { + System.Diagnostics.Debug.Assert(IsFunctionPointer(typeHandle, out _, out _)); + return TargetPointer.Null; + } + } + else + { + return TargetPointer.Null; + } + } + public TargetPointer GetCanonicalMethodTable(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : GetClassData(typeHandle).MethodTable; + public TargetPointer GetParentMethodTable(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : _methodTables[typeHandle.Address].ParentMethodTable; public uint GetBaseSize(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (uint)0 : _methodTables[typeHandle.Address].Flags.BaseSize; @@ -360,42 +395,13 @@ private Data.EEClass GetClassData(TypeHandle typeHandle) return _target.ProcessedData.GetOrAdd(clsPtr); } - public TargetPointer GetCanonicalMethodTable(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : GetClassData(typeHandle).MethodTable; - - public TargetPointer GetModule(TypeHandle typeHandle) - { - if (typeHandle.IsMethodTable()) - { - return _methodTables[typeHandle.Address].Module; - } - else if (typeHandle.IsTypeDesc()) - { - if (HasTypeParam(typeHandle)) - { - return GetModule(GetTypeParam(typeHandle)); - } - else if (IsGenericVariable(typeHandle, out TargetPointer genericParamModule, out _)) - { - return genericParamModule; - } - else - { - System.Diagnostics.Debug.Assert(IsFunctionPointer(typeHandle, out _, out _)); - return TargetPointer.Null; - } - } - else - { - return TargetPointer.Null; - } - } - - public TargetPointer GetParentMethodTable(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : _methodTables[typeHandle.Address].ParentMethodTable; public bool IsFreeObjectMethodTable(TypeHandle typeHandle) => FreeObjectMethodTablePointer == typeHandle.Address; public bool IsString(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[typeHandle.Address].Flags.IsString; public bool ContainsGCPointers(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[typeHandle.Address].Flags.ContainsGCPointers; + public bool IsDynamicStatics(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[typeHandle.Address].Flags.IsDynamicStatics; + public ushort GetNumInterfaces(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : _methodTables[typeHandle.Address].NumInterfaces; public uint GetTypeDefToken(TypeHandle typeHandle) { @@ -404,14 +410,69 @@ public uint GetTypeDefToken(TypeHandle typeHandle) MethodTable methodTable = _methodTables[typeHandle.Address]; return (uint)(methodTable.Flags.GetTypeDefRid() | ((int)TableIndex.TypeDef << 24)); } - public ushort GetNumMethods(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : GetClassData(typeHandle).NumMethods; + public uint GetTypeDefTypeAttributes(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (uint)0 : GetClassData(typeHandle).CorTypeAttr; + public ushort GetNumInstanceFields(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : GetClassData(typeHandle).NumInstanceFields; + public ushort GetNumStaticFields(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : GetClassData(typeHandle).NumStaticFields; + public ushort GetNumThreadStaticFields(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : GetClassData(typeHandle).NumThreadStaticFields; + public TargetPointer GetFieldDescList(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : GetClassData(typeHandle).FieldDescList; + private TargetPointer GetDynamicStaticsInfo(TypeHandle typeHandle) + { + if (!typeHandle.IsMethodTable()) + return default; - public ushort GetNumInterfaces(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : _methodTables[typeHandle.Address].NumInterfaces; + MethodTable methodTable = _methodTables[typeHandle.Address]; + if (!methodTable.Flags.IsDynamicStatics) + return default; + TargetPointer dynamicStaticsInfoSize = _target.GetTypeInfo(DataType.DynamicStaticsInfo).Size!.Value; + TargetPointer dynamicStaticsInfoAddr = methodTable.AuxiliaryData - dynamicStaticsInfoSize; + return dynamicStaticsInfoAddr; + } - public uint GetTypeDefTypeAttributes(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (uint)0 : GetClassData(typeHandle).CorTypeAttr; + private Data.ThreadStaticsInfo GetThreadStaticsInfo(TypeHandle typeHandle) + { + MethodTable methodTable = _methodTables[typeHandle.Address]; + TargetPointer threadStaticsInfoSize = _target.GetTypeInfo(DataType.ThreadStaticsInfo).Size!.Value; + TargetPointer threadStaticsInfoAddr = methodTable.AuxiliaryData - threadStaticsInfoSize; + Data.ThreadStaticsInfo threadStaticsInfo = _target.ProcessedData.GetOrAdd(threadStaticsInfoAddr); + return threadStaticsInfo; + } - public bool IsDynamicStatics(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[typeHandle.Address].Flags.IsDynamicStatics; + public TargetPointer GetGCThreadStaticsBasePointer(TypeHandle typeHandle, TargetPointer threadPtr) + { + if (!typeHandle.IsMethodTable()) + return TargetPointer.Null; + TargetPointer tlsIndexPtr = GetThreadStaticsInfo(typeHandle).GCTlsIndex; + Contracts.IThread threadContract = _target.Contracts.Thread; + return threadContract.GetThreadLocalStaticBase(threadPtr, tlsIndexPtr); + } + + public TargetPointer GetNonGCThreadStaticsBasePointer(TypeHandle typeHandle, TargetPointer threadPtr) + { + if (!typeHandle.IsMethodTable()) + return TargetPointer.Null; + TargetPointer tlsIndexPtr = GetThreadStaticsInfo(typeHandle).NonGCTlsIndex; + Contracts.IThread threadContract = _target.Contracts.Thread; + return threadContract.GetThreadLocalStaticBase(threadPtr, tlsIndexPtr); + } + + public TargetPointer GetGCStaticsBasePointer(TypeHandle typeHandle) + { + TargetPointer dynamicStaticsInfoAddr = GetDynamicStaticsInfo(typeHandle); + if (dynamicStaticsInfoAddr == TargetPointer.Null) + return TargetPointer.Null; + Data.DynamicStaticsInfo dynamicStaticsInfo = _target.ProcessedData.GetOrAdd(dynamicStaticsInfoAddr); + return dynamicStaticsInfo.GCStatics; + } + + public TargetPointer GetNonGCStaticsBasePointer(TypeHandle typeHandle) + { + TargetPointer dynamicStaticsInfoAddr = GetDynamicStaticsInfo(typeHandle); + if (dynamicStaticsInfoAddr == TargetPointer.Null) + return TargetPointer.Null; + Data.DynamicStaticsInfo dynamicStaticsInfo = _target.ProcessedData.GetOrAdd(dynamicStaticsInfoAddr); + return dynamicStaticsInfo.NonGCStatics; + } public ReadOnlySpan GetInstantiation(TypeHandle typeHandle) { @@ -425,6 +486,24 @@ public ReadOnlySpan GetInstantiation(TypeHandle typeHandle) return _target.ProcessedData.GetOrAdd(typeHandle.Address).TypeHandles; } + public bool IsClassInited(TypeHandle typeHandle) + { + if (!typeHandle.IsMethodTable()) + return false; + MethodTable methodTable = _methodTables[typeHandle.Address]; + MethodTableAuxiliaryData auxiliaryData = _target.ProcessedData.GetOrAdd(methodTable.AuxiliaryData); + return (auxiliaryData.Flags & (uint)MethodTableAuxiliaryFlags.Initialized) != 0; + } + + public bool IsInitError(TypeHandle typeHandle) + { + if (!typeHandle.IsMethodTable()) + return false; + MethodTable methodTable = _methodTables[typeHandle.Address]; + MethodTableAuxiliaryData auxiliaryData = _target.ProcessedData.GetOrAdd(methodTable.AuxiliaryData); + return (auxiliaryData.Flags & (uint)MethodTableAuxiliaryFlags.IsInitError) != 0; + } + private sealed class TypeInstantiation : IData { public static TypeInstantiation Create(Target target, TargetPointer address) => new TypeInstantiation(target, address); @@ -630,30 +709,27 @@ private ushort GetNumVtableSlots(TypeHandle typeHandle) } public MethodDescHandle GetMethodDescHandle(TargetPointer methodDescPointer) + => GetMethodDescHandle(methodDescPointer, validate: true); + + private MethodDescHandle GetMethodDescHandle(TargetPointer methodDescPointer, bool validate) { - // if we already validated this address, return a handle + // if we already have a method desc at this address, return a handle if (_methodDescs.ContainsKey(methodDescPointer)) { return new MethodDescHandle(methodDescPointer); } - // Check if we cached the underlying data already - if (_target.ProcessedData.TryGet(methodDescPointer, out Data.MethodDesc? methodDescData)) + + TargetPointer methodDescChunkPointer; + if (validate) { - // we already cached the data, we must have validated the address, create the representation struct for our use - TargetPointer mdescChunkPtr = _methodValidation.GetMethodDescChunkPointerThrowing(methodDescPointer, methodDescData); - // FIXME[cdac]: this isn't threadsafe - if (!_target.ProcessedData.TryGet(mdescChunkPtr, out Data.MethodDescChunk? methodDescChunkData)) + if (!_methodValidation.ValidateMethodDescPointer(methodDescPointer, out methodDescChunkPointer)) { - throw new InvalidOperationException("cached MethodDesc data but not its containing MethodDescChunk"); + throw new ArgumentException("Invalid method desc pointer", nameof(methodDescPointer)); } - MethodDesc validatedMethodDesc = new MethodDesc(_target, methodDescPointer, methodDescData, mdescChunkPtr, methodDescChunkData); - _ = _methodDescs.TryAdd(methodDescPointer, validatedMethodDesc); - return new MethodDescHandle(methodDescPointer); } - - if (!_methodValidation.ValidateMethodDescPointer(methodDescPointer, out TargetPointer methodDescChunkPointer)) + else { - throw new ArgumentException("Invalid method desc pointer", nameof(methodDescPointer)); + methodDescChunkPointer = _methodValidation.GetMethodDescChunkPointerThrowing(methodDescPointer, _target.ProcessedData.GetOrAdd(methodDescPointer)); } // ok, we validated it, cache the data and add the MethodDesc struct to the dictionary @@ -934,7 +1010,7 @@ bool IRuntimeTypeSystem.IsCollectibleMethod(MethodDescHandle methodDesc) { MethodDesc md = _methodDescs[methodDesc.Address]; TargetPointer loaderModuleAddr = GetLoaderModule(md); - ModuleHandle mod = _target.Contracts.Loader.GetModuleHandle(loaderModuleAddr); + ModuleHandle mod = _target.Contracts.Loader.GetModuleHandleFromModulePtr(loaderModuleAddr); return _target.Contracts.Loader.IsCollectible(mod); } @@ -998,7 +1074,9 @@ private IEnumerable GetIntroducedMethods(TypeHandle typeHandle // chunk.Count is the number of MethodDescs in the chunk - 1 for (int i = 0; i < chunk.Count + 1; i++) { - MethodDescHandle methodDescHandle = GetMethodDescHandle(methodDescPtr); + // Validation of some MethodDescs fails in heap dumps due to missing memory. + // Skipping validation should be okay as the pointers come from the target. + MethodDescHandle methodDescHandle = GetMethodDescHandle(methodDescPtr, validate: false); MethodDesc md = _methodDescs[methodDescHandle.Address]; methodDescPtr += md.Size; yield return methodDescHandle; @@ -1010,6 +1088,7 @@ private IEnumerable GetIntroducedMethods(TypeHandle typeHandle TargetPointer IRuntimeTypeSystem.GetMethodDescForSlot(TypeHandle typeHandle, ushort slot) { + // based on MethodTable::GetMethodDescForSlot_NoThrow if (!typeHandle.IsMethodTable()) throw new ArgumentException($"{nameof(typeHandle)} is not a MethodTable"); @@ -1020,15 +1099,20 @@ TargetPointer IRuntimeTypeSystem.GetMethodDescForSlot(TypeHandle typeHandle, ush if (pCode == TargetCodePointer.Null) { - // if pCode is null, we iterate through the method descs in the MT. - foreach (MethodDescHandle mdh in GetIntroducedMethods(typeHandle)) + while (canonMT.Address != TargetPointer.Null) { - MethodDesc md = _methodDescs[mdh.Address]; - if (md.Slot == slot) + // if pCode is null, we iterate through the method descs in the MT. + foreach (MethodDescHandle mdh in GetIntroducedMethods(canonMT)) { - return mdh.Address; + MethodDesc md = _methodDescs[mdh.Address]; + if (md.Slot == slot) + { + return mdh.Address; + } } + canonMT = GetTypeHandle(GetCanonicalMethodTable(GetTypeHandle(GetParentMethodTable(canonMT)))); } + Debug.Fail("We should never reach here, as there should always be a MethodDesc for a slot"); } return GetMethodDescForEntrypoint(pCode); @@ -1044,15 +1128,6 @@ private readonly TargetPointer GetMethodDescForEntrypoint(TargetCodePointer pCod return methodDescPtr; } - // FCall path, look up address in the FCall table - { - TargetPointer methodDescPtr = _target.Contracts.ECall.MapTargetBackToMethodDesc(pCode); - if (methodDescPtr != TargetPointer.Null) - { - return methodDescPtr; - } - } - // stub path, read address as a Precode and read MethodDesc from it { TargetPointer methodDescPtr = _target.Contracts.PrecodeStubs.GetMethodDescFromStubAddress(pCode); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/Context/AMD64/AMD64Unwinder.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/Context/AMD64/AMD64Unwinder.cs index 2459fa3225e6c4..404504cd79335a 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/Context/AMD64/AMD64Unwinder.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/Context/AMD64/AMD64Unwinder.cs @@ -1181,9 +1181,8 @@ public uint UnwindOpSlots() return new UnwindInfoHeader(unwindInfoAddress, headerValue); } - catch (InvalidOperationException) + catch (VirtualReadException) { - // InvalidOperationException thrown if failed to read memory return null; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/Context/Unwinder.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/Context/Unwinder.cs deleted file mode 100644 index 151614d1681182..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/Context/Unwinder.cs +++ /dev/null @@ -1,172 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; -using Microsoft.Diagnostics.DataContractReader.Contracts.StackWalkHelpers; -using System.Collections.Generic; -using System.Diagnostics; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; -internal static unsafe partial class Unwinder -{ - [LibraryImport("unwinder_cdac_arm64", EntryPoint = "arm64Unwind")] - private static partial int ARM64Unwind( - ref ARM64Context context, - delegate* unmanaged readFromTarget, - delegate* unmanaged getAllocatedBuffer, - delegate* unmanaged getStackWalkInfo, - delegate* unmanaged unwinderFail, - void* callbackContext); - - public static int ARM64Unwind( - ref ARM64Context context, - Target target) - { - using CallbackContext callbackContext = new(target); - - GCHandle handle = GCHandle.Alloc(callbackContext); - int ret = ARM64Unwind( - ref context, - &ReadFromTarget, - &GetAllocatedBuffer, - &GetStackWalkInfo, - &UnwinderFail, - GCHandle.ToIntPtr(handle).ToPointer()); - handle.Free(); - - return ret; - } - - [LibraryImport("unwinder_cdac_amd64", EntryPoint = "amd64Unwind")] - private static partial int AMD64Unwind( - ref AMD64Context context, - delegate* unmanaged readFromTarget, - delegate* unmanaged getAllocatedBuffer, - delegate* unmanaged getStackWalkInfo, - delegate* unmanaged unwinderFail, - void* callbackContext); - - public static int AMD64Unwind( - ref AMD64Context context, - Target target) - { - using CallbackContext callbackContext = new(target); - - GCHandle handle = GCHandle.Alloc(callbackContext); - int ret = AMD64Unwind( - ref context, - &ReadFromTarget, - &GetAllocatedBuffer, - &GetStackWalkInfo, - &UnwinderFail, - GCHandle.ToIntPtr(handle).ToPointer()); - handle.Free(); - - return ret; - } - - /// - /// Used to inject target into unwinder callbacks and track memory allocated for native unwinder. - /// - private sealed class CallbackContext(Target target) : IDisposable - { - private bool disposed; - public Target Target { get; } = target; - public List AllocatedRegions { get; } = []; - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - if (disposed) return; - - if (disposing) - { - foreach (IntPtr ptr in AllocatedRegions) - { - NativeMemory.Free(ptr.ToPointer()); - } - } - disposed = true; - } - } - - // ReadFromTarget allows the unwinder to read memory from the target process - // into an allocated buffer. This buffer is either allocated by the unwinder - // with its lifetime managed by the unwinder or allocated through GetAllocatedBuffer. - // In the latter case, the unwinder can only use the buffer for the duration of the - // unwind call. Once the call is over the cDAC will free all allocated buffers. - [UnmanagedCallersOnly] - private static unsafe int ReadFromTarget(ulong address, void* pBuffer, int bufferSize, void* context) - { - CallbackContext callbackContext = (CallbackContext)GCHandle.FromIntPtr((IntPtr)context).Target!; - Span span = new Span(pBuffer, bufferSize); - try - { - callbackContext.Target.ReadBuffer(address, span); - } - catch (InvalidOperationException) - { - // if the read fails, the unwinder behavior changes. Return failing HR instead of throwing - return -1; - } - return 0; - } - - // GetAllocatedBuffer allows the unwinder to allocate a buffer that will be freed - // once the unwinder call is complete. - // Freeing is handeled in the Dispose method of CallbackContext. - [UnmanagedCallersOnly] - private static unsafe int GetAllocatedBuffer(int bufferSize, void** ppBuffer, void* context) - { - CallbackContext callbackContext = (CallbackContext)GCHandle.FromIntPtr((IntPtr)context).Target!; - *ppBuffer = NativeMemory.Alloc((nuint)bufferSize); - callbackContext.AllocatedRegions.Add((IntPtr)(*ppBuffer)); - return 0; - } - - // cDAC version of GetRuntimeStackWalkInfo defined in codeman.cpp - // To maintain the same signature as the original function, this returns void. - // If the unwindInfoBase or funcEntry can not be found, both will be 0. - [UnmanagedCallersOnly] - private static unsafe void GetStackWalkInfo(ulong controlPC, void* pUnwindInfoBase, void* pFuncEntry, void* context) - { - if ((nuint)pUnwindInfoBase != 0) *(nuint*)pUnwindInfoBase = 0; - if ((nuint)pFuncEntry != 0) *(nuint*)pFuncEntry = 0; - - CallbackContext callbackContext = (CallbackContext)GCHandle.FromIntPtr((IntPtr)context).Target!; - - IExecutionManager eman = callbackContext.Target.Contracts.ExecutionManager; - try - { - if (eman.GetCodeBlockHandle(controlPC) is CodeBlockHandle cbh) - { - if ((nuint)pUnwindInfoBase != 0) - { - TargetPointer unwindInfoBase = eman.GetUnwindInfoBaseAddress(cbh); - *(nuint*)pUnwindInfoBase = (nuint)unwindInfoBase.Value; - } - if ((nuint)pFuncEntry != 0) - { - TargetPointer unwindInfo = eman.GetUnwindInfo(cbh); - *(nuint*)pFuncEntry = (nuint)unwindInfo.Value; - } - } - } - catch (System.Exception ex) - { - Console.WriteLine($"GetStackWalkInfo failed: {ex}"); - } - } - - [UnmanagedCallersOnly] - private static void UnwinderFail() - { - Debug.Fail("Native unwinder assertion failure."); - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs index 5d4885dca2fc79..7940f14b7faa7f 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs @@ -112,13 +112,22 @@ private TargetPointer GetFormatPointer(ulong formatOffset) return new TargetPointer(stressLog.ModuleOffset.Value + formatOffset); } - TargetPointer moduleTable = target.ReadGlobalPointer(Constants.Globals.StressLogModuleTable); + TargetPointer? moduleTable; + if (!target.TryReadGlobalPointer(Constants.Globals.StressLogModuleTable, out moduleTable)) + { + if (!target.TryReadGlobalPointer(Constants.Globals.StressLog, out TargetPointer? pStressLog)) + { + throw new InvalidOperationException("StressLogModuleTable is not set and StressLog is not available, but StressLogHasModuleTable is set to 1."); + } + Data.StressLog stressLog = target.ProcessedData.GetOrAdd(pStressLog.Value); + moduleTable = stressLog.Modules ?? throw new InvalidOperationException("StressLogModuleTable is not set and StressLog does not contain a ModuleTable offset, but StressLogHasModuleTable is set to 1."); + } uint moduleEntrySize = target.GetTypeInfo(DataType.StressLogModuleDesc).Size!.Value; uint maxModules = target.ReadGlobal(Constants.Globals.StressLogMaxModules); ulong cumulativeOffset = 0; for (uint i = 0; i < maxModules; ++i) { - Data.StressLogModuleDesc module = target.ProcessedData.GetOrAdd(moduleTable + i * moduleEntrySize); + Data.StressLogModuleDesc module = target.ProcessedData.GetOrAdd(moduleTable.Value + i * moduleEntrySize); ulong relativeOffset = formatOffset - cumulativeOffset; if (relativeOffset < module.Size.Value) { diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread_1.cs index f0587a674c3058..bc44a6f4d36984 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread_1.cs @@ -11,6 +11,14 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts; private readonly TargetPointer _threadStoreAddr; private readonly ulong _threadLinkOffset; + [Flags] + private enum TLSIndexType + { + NonCollectible = 0, // IndexOffset for this form of TLSIndex is scaled by sizeof(OBJECTREF) and used as an index into the array at ThreadLocalData::pNonCollectibleTlsArrayData to get the final address + Collectible = 1, // IndexOffset for this form of TLSIndex is scaled by sizeof(void*) and then added to ThreadLocalData::pCollectibleTlsArrayData to get the final address + DirectOnThreadLocalData = 2, // IndexOffset for this form of TLS index is an offset into the ThreadLocalData structure itself. This is used for very high performance scenarios, and scenario where the runtime native code needs to hold a TLS pointer to a managed TLS slot. Each one of these is hand-opted into this model. + }; + internal Thread_1(Target target, TargetPointer threadStore) { _target = target; @@ -68,6 +76,18 @@ ThreadData IThread.GetThreadData(TargetPointer threadPointer) GetThreadFromLink(thread.LinkNext)); } + // happens inside critical section + TargetPointer IThread.IdToThread(uint id) + { + TargetPointer idDispenserPtr = _target.ReadGlobalPointer(Constants.Globals.ThinlockThreadIdDispenser); + TargetPointer idDispenser = _target.ReadPointer(idDispenserPtr); + Data.IdDispenser idDispenserObj = _target.ProcessedData.GetOrAdd(idDispenser); + TargetPointer threadPtr = TargetPointer.Null; + if (id < idDispenserObj.HighestId) + threadPtr = _target.ReadPointer(idDispenserObj.IdToThread + (ulong)(id * _target.PointerSize)); + return threadPtr; + } + private TargetPointer GetThreadFromLink(TargetPointer threadLink) { if (threadLink == TargetPointer.Null) @@ -76,4 +96,62 @@ private TargetPointer GetThreadFromLink(TargetPointer threadLink) // Get the address of the thread containing the link return new TargetPointer(threadLink - _threadLinkOffset); } + + TargetPointer IThread.GetThreadLocalStaticBase(TargetPointer threadPointer, TargetPointer tlsIndexPtr) + { + // Get the thread's TLS base address + Data.Thread thread = _target.ProcessedData.GetOrAdd(threadPointer); + TargetPointer threadLocalDataPtr = thread.ThreadLocalDataPtr; + if (threadLocalDataPtr == TargetPointer.Null) + return TargetPointer.Null; + + Data.TLSIndex tlsIndex = _target.ProcessedData.GetOrAdd(tlsIndexPtr); + if (!tlsIndex.IsAllocated) + return TargetPointer.Null; + + TargetPointer threadLocalStaticBase = default; + Data.ThreadLocalData threadLocalData = _target.ProcessedData.GetOrAdd(threadLocalDataPtr); + int indexOffset = tlsIndex.IndexOffset; + int indexType = tlsIndex.IndexType; + switch ((TLSIndexType)indexType) + { + case TLSIndexType.NonCollectible: + int nonCollectibleCount = threadLocalData.NonCollectibleTlsDataCount; + // bounds check + if (nonCollectibleCount > indexOffset) + { + TargetPointer nonCollectibleArray = threadLocalData.NonCollectibleTlsArrayData; + int arrayIndex = indexOffset - _target.ReadGlobal(Constants.Globals.NumberOfTlsOffsetsNotUsedInNoncollectibleArray); + TargetPointer arrayStartAddress = nonCollectibleArray + _target.ReadGlobalPointer(Constants.Globals.PtrArrayOffsetToDataArray); + threadLocalStaticBase = _target.ReadPointer(arrayStartAddress + (ulong)(arrayIndex * _target.PointerSize)); + } + break; + case TLSIndexType.Collectible: + int collectibleCount = threadLocalData.CollectibleTlsDataCount; + if (collectibleCount > indexOffset) + { + TargetPointer collectibleArray = threadLocalData.CollectibleTlsArrayData; + threadLocalStaticBase = _target.ReadPointer(collectibleArray + (ulong)(indexOffset * _target.PointerSize)); + } + break; + case TLSIndexType.DirectOnThreadLocalData: + threadLocalStaticBase = threadLocalDataPtr; + break; + } + if (threadLocalStaticBase == TargetPointer.Null) + { + TargetPointer inFlightData = threadLocalData.InFlightData; + while (inFlightData != TargetPointer.Null) + { + Data.InflightTLSData inFlightTLSData = _target.ProcessedData.GetOrAdd(inFlightData); + if (inFlightTLSData.TlsIndex.TLSIndexRawIndex == tlsIndex.TLSIndexRawIndex) + { + threadLocalStaticBase = inFlightTLSData.TLSData.Object; + break; + } + inFlightData = inFlightTLSData.Next; + } + } + return threadLocalStaticBase; + } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/AppDomain.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/AppDomain.cs index a0df88ed1faa28..cd21ff7172abce 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/AppDomain.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/AppDomain.cs @@ -14,8 +14,10 @@ public AppDomain(Target target, TargetPointer address) RootAssembly = target.ReadPointer(address + (ulong)type.Fields[nameof(RootAssembly)].Offset); DomainAssemblyList = address + (ulong)type.Fields[nameof(DomainAssemblyList)].Offset; + FriendlyName = target.ReadPointer(address + (ulong)type.Fields[nameof(FriendlyName)].Offset); } public TargetPointer RootAssembly { get; init; } public TargetPointer DomainAssemblyList { get; init; } + public TargetPointer FriendlyName { get; init; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/AssemblyBinder.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/AssemblyBinder.cs new file mode 100644 index 00000000000000..2c13c5fe332a95 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/AssemblyBinder.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class AssemblyBinder : IData +{ + static AssemblyBinder IData.Create(Target target, TargetPointer address) => new AssemblyBinder(target, address); + public AssemblyBinder(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.AssemblyBinder); + AssemblyLoadContext = target.ReadPointer(address + (ulong)type.Fields[nameof(AssemblyLoadContext)].Offset); + } + public TargetPointer AssemblyLoadContext { get; init; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/DacEnumerableHash.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/DacEnumerableHash.cs index 98270f7019f7be..248eb1fcc74ad5 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/DacEnumerableHash.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/DacEnumerableHash.cs @@ -18,6 +18,7 @@ internal sealed class DacEnumerableHash { private const int SLOT_LENGTH = 0; private const int SKIP_SPECIAL_SLOTS = 3; + private const int END_SENTINEL = 0x1; private readonly Target _target; private readonly Target.TypeInfo _type; @@ -77,7 +78,7 @@ private uint GetLength() private static bool IsEndSentinel(TargetPointer value) { - return ((ulong)value & 0x1) == 0x1; + return ((ulong)value & END_SENTINEL) == END_SENTINEL; } private List ReadChain(TargetPointer chainElement) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/DynamicStaticsInfo.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/DynamicStaticsInfo.cs new file mode 100644 index 00000000000000..649c9ecdd881e3 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/DynamicStaticsInfo.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class DynamicStaticsInfo : IData +{ + static DynamicStaticsInfo IData.Create(Target target, TargetPointer address) => new DynamicStaticsInfo(target, address); + public DynamicStaticsInfo(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.DynamicStaticsInfo); + TargetPointer mask = target.ReadGlobalPointer(Constants.Globals.StaticsPointerMask); + GCStatics = target.ReadPointer(address + (ulong)type.Fields[nameof(GCStatics)].Offset) & mask; + NonGCStatics = target.ReadPointer(address + (ulong)type.Fields[nameof(NonGCStatics)].Offset) & mask; + } + public TargetPointer GCStatics { get; init; } + public TargetPointer NonGCStatics { get; init; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ECHash.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ECHash.cs deleted file mode 100644 index d64aaf65ea24eb..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ECHash.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.Diagnostics.DataContractReader.Data; - -internal sealed class ECHash : IData -{ - static ECHash IData.Create(Target target, TargetPointer address) => new ECHash(target, address); - public ECHash(Target target, TargetPointer address) - { - Target.TypeInfo type = target.GetTypeInfo(DataType.ECHash); - - Next = target.ReadPointer(address + (ulong)type.Fields[nameof(Next)].Offset); - Implementation = target.ReadCodePointer(address + (ulong)type.Fields[nameof(Implementation)].Offset); - MethodDesc = target.ReadPointer(address + (ulong)type.Fields[nameof(MethodDesc)].Offset); - } - - public TargetPointer Next { get; init; } - public TargetCodePointer Implementation { get; init; } - public TargetPointer MethodDesc { get; init; } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/EEClass.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/EEClass.cs index 2669984b62ce0a..b203760f644cae 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/EEClass.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/EEClass.cs @@ -15,6 +15,10 @@ public EEClass(Target target, TargetPointer address) NumMethods = target.Read(address + (ulong)type.Fields[nameof(NumMethods)].Offset); CorTypeAttr = target.Read(address + (ulong)type.Fields[nameof(CorTypeAttr)].Offset); InternalCorElementType = target.Read(address + (ulong)type.Fields[nameof(InternalCorElementType)].Offset); + NumInstanceFields = target.Read(address + (ulong)type.Fields[nameof(NumInstanceFields)].Offset); + NumStaticFields = target.Read(address + (ulong)type.Fields[nameof(NumStaticFields)].Offset); + NumThreadStaticFields = target.Read(address + (ulong)type.Fields[nameof(NumThreadStaticFields)].Offset); + FieldDescList = target.Read(address + (ulong)type.Fields[nameof(FieldDescList)].Offset); NumNonVirtualSlots = target.Read(address + (ulong)type.Fields[nameof(NumNonVirtualSlots)].Offset); } @@ -31,7 +35,10 @@ public EEClass(Target target, TargetPointer address) // Enums are the element type of their underlying type // ValueTypes which can exactly be represented as an element type are represented as such public byte InternalCorElementType { get; init; } - + public ushort NumInstanceFields { get; init; } + public ushort NumStaticFields { get; init; } + public ushort NumThreadStaticFields { get; init; } + public TargetPointer FieldDescList { get; init; } public ushort NumNonVirtualSlots { get; init; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/EEJitManager.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/EEJitManager.cs new file mode 100644 index 00000000000000..58eae2a2cf67d1 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/EEJitManager.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class EEJitManager : IData +{ + static EEJitManager IData.Create(Target target, TargetPointer address) => new EEJitManager(target, address); + public EEJitManager(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.EEJitManager); + + StoreRichDebugInfo = target.Read(address + (ulong)type.Fields[nameof(StoreRichDebugInfo)].Offset) != 0; + } + + public bool StoreRichDebugInfo { get; init; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/IdDispenser.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/IdDispenser.cs new file mode 100644 index 00000000000000..75806fa57e3748 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/IdDispenser.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class IdDispenser : IData +{ + static IdDispenser IData.Create(Target target, TargetPointer address) => new IdDispenser(target, address); + public IdDispenser(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.IdDispenser); + IdToThread = target.ReadPointer(address + (ulong)type.Fields[nameof(IdToThread)].Offset); + HighestId = target.Read(address + (ulong)type.Fields[nameof(HighestId)].Offset); + } + + public TargetPointer IdToThread { get; init; } + public uint HighestId { get; init; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageDataDirectory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageDataDirectory.cs index d3717f5eea481b..241cf6daabd540 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageDataDirectory.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ImageDataDirectory.cs @@ -14,7 +14,7 @@ public ImageDataDirectory(Target target, TargetPointer address) VirtualAddress = target.Read(address + (ulong)type.Fields[nameof(VirtualAddress)].Offset); Size = target.Read(address + (ulong)type.Fields[nameof(Size)].Offset); - } + } public uint VirtualAddress { get; } public uint Size { get; } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/InflightTLSData.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/InflightTLSData.cs new file mode 100644 index 00000000000000..4a1cad9672773d --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/InflightTLSData.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class InflightTLSData : IData +{ + static InflightTLSData IData.Create(Target target, TargetPointer address) => new InflightTLSData(target, address); + public InflightTLSData(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.InFlightTLSData); + Next = target.ReadPointer(address + (ulong)type.Fields[nameof(Next)].Offset); + TlsIndex = target.ProcessedData.GetOrAdd(address + (ulong)type.Fields[nameof(TlsIndex)].Offset); + TLSData = target.ProcessedData.GetOrAdd(target.ReadPointer(address + (ulong)type.Fields[nameof(TLSData)].Offset)); + } + public TargetPointer Next { get; init; } + public TLSIndex TlsIndex { get; init; } + public ObjectHandle TLSData { get; init; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/LoaderAllocator.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/LoaderAllocator.cs index 6a7ba15a630a8f..2a933ff2ace452 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/LoaderAllocator.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/LoaderAllocator.cs @@ -13,10 +13,16 @@ public LoaderAllocator(Target target, TargetPointer address) Target.TypeInfo type = target.GetTypeInfo(DataType.LoaderAllocator); ReferenceCount = target.Read(address + (ulong)type.Fields[nameof(ReferenceCount)].Offset); + HighFrequencyHeap = target.ReadPointer(address + (ulong)type.Fields[nameof(HighFrequencyHeap)].Offset); + LowFrequencyHeap = target.ReadPointer(address + (ulong)type.Fields[nameof(LowFrequencyHeap)].Offset); + StubHeap = target.ReadPointer(address + (ulong)type.Fields[nameof(StubHeap)].Offset); } public uint ReferenceCount { get; init; } + public TargetPointer HighFrequencyHeap { get; init; } + public TargetPointer LowFrequencyHeap { get; init; } + public TargetPointer StubHeap { get; init; } public bool IsAlive => ReferenceCount != 0; } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MethodTableAuxiliaryData.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MethodTableAuxiliaryData.cs index c181335f410c63..75b3109b4331e1 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MethodTableAuxiliaryData.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MethodTableAuxiliaryData.cs @@ -13,9 +13,11 @@ private MethodTableAuxiliaryData(Target target, TargetPointer address) LoaderModule = target.ReadPointer(address + (ulong)type.Fields[nameof(LoaderModule)].Offset); OffsetToNonVirtualSlots = target.Read(address + (ulong)type.Fields[nameof(OffsetToNonVirtualSlots)].Offset); + Flags = target.Read(address + (ulong)type.Fields[nameof(Flags)].Offset); } public TargetPointer LoaderModule { get; init; } public short OffsetToNonVirtualSlots { get; init; } + public uint Flags { get; init; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/PEAssembly.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/PEAssembly.cs index 675c281c417bcb..09a03cb527217a 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/PEAssembly.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/PEAssembly.cs @@ -13,7 +13,9 @@ public PEAssembly(Target target, TargetPointer address) Target.TypeInfo type = target.GetTypeInfo(DataType.PEAssembly); PEImage = target.ReadPointer(address + (ulong)type.Fields[nameof(PEImage)].Offset); + AssemblyBinder = target.ReadPointer(address + (ulong)type.Fields[nameof(AssemblyBinder)].Offset); } public TargetPointer PEImage { get; init; } + public TargetPointer AssemblyBinder { get; init; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/PatchpointInfo.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/PatchpointInfo.cs new file mode 100644 index 00000000000000..482174b7465406 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/PatchpointInfo.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class PatchpointInfo : IData +{ + static PatchpointInfo IData.Create(Target target, TargetPointer address) + => new PatchpointInfo(target, address); + + public PatchpointInfo(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.PatchpointInfo); + + LocalCount = target.Read(address + (ulong)type.Fields[nameof(LocalCount)].Offset); + } + + public uint LocalCount { get; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/PrecodeMachineDescriptor.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/PrecodeMachineDescriptor.cs index ebecc223955057..3e1ec015b41048 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/PrecodeMachineDescriptor.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/PrecodeMachineDescriptor.cs @@ -11,46 +11,93 @@ static PrecodeMachineDescriptor IData.Create(Target ta public PrecodeMachineDescriptor(Target target, TargetPointer address) { Target.TypeInfo type = target.GetTypeInfo(DataType.PrecodeMachineDescriptor); - OffsetOfPrecodeType = target.Read(address + (ulong)type.Fields[nameof(OffsetOfPrecodeType)].Offset); - ReadWidthOfPrecodeType = target.Read(address + (ulong)type.Fields[nameof(ReadWidthOfPrecodeType)].Offset); - ShiftOfPrecodeType = target.Read(address + (ulong)type.Fields[nameof(ShiftOfPrecodeType)].Offset); - InvalidPrecodeType = target.Read(address + (ulong)type.Fields[nameof(InvalidPrecodeType)].Offset); - StubPrecodeType = target.Read(address + (ulong)type.Fields[nameof(StubPrecodeType)].Offset); - if (type.Fields.ContainsKey(nameof(PInvokeImportPrecodeType))) + if (type.Fields.ContainsKey(nameof(OffsetOfPrecodeType))) { - PInvokeImportPrecodeType = target.Read(address + (ulong)type.Fields[nameof(PInvokeImportPrecodeType)].Offset); + OffsetOfPrecodeType = target.Read(address + (ulong)type.Fields[nameof(OffsetOfPrecodeType)].Offset); + ReadWidthOfPrecodeType = target.Read(address + (ulong)type.Fields[nameof(ReadWidthOfPrecodeType)].Offset); + ShiftOfPrecodeType = target.Read(address + (ulong)type.Fields[nameof(ShiftOfPrecodeType)].Offset); } else { - PInvokeImportPrecodeType = null; + OffsetOfPrecodeType = null; + ReadWidthOfPrecodeType = null; + ShiftOfPrecodeType = null; } - if (type.Fields.ContainsKey(nameof(FixupPrecodeType))) + InvalidPrecodeType = target.Read(address + (ulong)type.Fields[nameof(InvalidPrecodeType)].Offset); + StubPrecodeType = target.Read(address + (ulong)type.Fields[nameof(StubPrecodeType)].Offset); + + if (type.Fields.ContainsKey(nameof(FixupStubPrecodeSize))) { - FixupPrecodeType = target.Read(address + (ulong)type.Fields[nameof(FixupPrecodeType)].Offset); + FixupStubPrecodeSize = target.Read(address + (ulong)type.Fields[nameof(FixupStubPrecodeSize)].Offset); + FixupBytes = new byte[FixupStubPrecodeSize.Value]; + target.ReadBuffer(address + (ulong)type.Fields[nameof(FixupBytes)].Offset, FixupBytes); + FixupIgnoredBytes = new byte[FixupStubPrecodeSize.Value]; + target.ReadBuffer(address + (ulong)type.Fields[nameof(FixupIgnoredBytes)].Offset, FixupIgnoredBytes); } else { - FixupPrecodeType = null; + FixupStubPrecodeSize = null; + FixupBytes = null; + FixupIgnoredBytes = null; } - if (type.Fields.ContainsKey(nameof(ThisPointerRetBufPrecodeType))) + + if (type.Fields.ContainsKey(nameof(StubPrecodeSize))) { - ThisPointerRetBufPrecodeType = target.Read(address + (ulong)type.Fields[nameof(ThisPointerRetBufPrecodeType)].Offset); + StubPrecodeSize = target.Read(address + (ulong)type.Fields[nameof(FixupStubPrecodeSize)].Offset); + StubBytes = new byte[StubPrecodeSize.Value]; + target.ReadBuffer(address + (ulong)type.Fields[nameof(StubBytes)].Offset, StubBytes); + StubIgnoredBytes = new byte[StubPrecodeSize.Value]; + target.ReadBuffer(address + (ulong)type.Fields[nameof(StubIgnoredBytes)].Offset, StubIgnoredBytes); } else { - ThisPointerRetBufPrecodeType = null; + StubPrecodeSize = null; + FixupBytes = null; + FixupIgnoredBytes = null; } + + PInvokeImportPrecodeType = MaybeGetPrecodeType(target, address, nameof(PInvokeImportPrecodeType)); + FixupPrecodeType = MaybeGetPrecodeType(target, address, nameof(FixupPrecodeType)); + ThisPointerRetBufPrecodeType = MaybeGetPrecodeType(target, address, nameof(ThisPointerRetBufPrecodeType)); + InterpreterPrecodeType = MaybeGetPrecodeType(target, address, nameof(InterpreterPrecodeType)); + UMEntryPrecodeType = MaybeGetPrecodeType(target, address, nameof(UMEntryPrecodeType)); + DynamicHelperPrecodeType = MaybeGetPrecodeType(target, address, nameof(DynamicHelperPrecodeType)); + StubCodePageSize = target.Read(address + (ulong)type.Fields[nameof(StubCodePageSize)].Offset); + + static byte? MaybeGetPrecodeType(Target target, TargetPointer address, string fieldName) + { + if (target.GetTypeInfo(DataType.PrecodeMachineDescriptor).Fields.ContainsKey(fieldName)) + { + return target.Read(address + (ulong)target.GetTypeInfo(DataType.PrecodeMachineDescriptor).Fields[fieldName].Offset); + } + else + { + return null; + } + } } - public byte OffsetOfPrecodeType { get; init; } - public byte ReadWidthOfPrecodeType { get; init; } - public byte ShiftOfPrecodeType { get; init; } + public byte? OffsetOfPrecodeType { get; init; } // Not present for version 3 and above + public byte? ReadWidthOfPrecodeType { get; init; } // Not present for version 3 and above + public byte? ShiftOfPrecodeType { get; init; } // Not present for version 3 and above public byte InvalidPrecodeType { get; init; } public byte StubPrecodeType { get; init; } public byte? PInvokeImportPrecodeType { get; init; } public byte? FixupPrecodeType { get; init; } public byte? ThisPointerRetBufPrecodeType { get; init; } + public byte? FixupStubPrecodeSize { get; init; } // Present for version 3 and above + public byte[]? FixupBytes { get; init; } // Present for version 3 and above + public byte[]? FixupIgnoredBytes { get; init; } // Present for version 3 and above + + public byte? StubPrecodeSize { get; init; } // Present for version 3 and above + public byte[]? StubBytes { get; init; } // Present for version 3 and above + public byte[]? StubIgnoredBytes { get; init; } // Present for version 3 and above + + public byte? InterpreterPrecodeType { get; init; } // May be present for version 3 and above + public byte? UMEntryPrecodeType { get; init; } // May be present for version 3 and above + public byte? DynamicHelperPrecodeType { get; init; } // May be present for version 3 and above + public uint StubCodePageSize { get; init; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ReadyToRunInfo.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ReadyToRunInfo.cs index ed932946d195de..bce79429a10f19 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ReadyToRunInfo.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ReadyToRunInfo.cs @@ -30,6 +30,7 @@ public ReadyToRunInfo(Target target, TargetPointer address) : TargetPointer.Null; DelayLoadMethodCallThunks = target.ReadPointer(address + (ulong)type.Fields[nameof(DelayLoadMethodCallThunks)].Offset); + DebugInfoSection = target.ReadPointer(address + (ulong)type.Fields[nameof(DebugInfoSection)].Offset); // Map is from the composite info pointer (set to itself for non-multi-assembly composite images) EntryPointToMethodDescMap = CompositeInfo + (ulong)type.Fields[nameof(EntryPointToMethodDescMap)].Offset; @@ -46,5 +47,6 @@ public ReadyToRunInfo(Target target, TargetPointer address) public TargetPointer HotColdMap { get; } public TargetPointer DelayLoadMethodCallThunks { get; } + public TargetPointer DebugInfoSection { get; } public TargetPointer EntryPointToMethodDescMap { get; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/RealCodeHeader.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/RealCodeHeader.cs index f40998be18b114..70fbccc0b52a7b 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/RealCodeHeader.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/RealCodeHeader.cs @@ -12,12 +12,14 @@ public RealCodeHeader(Target target, TargetPointer address) { Target.TypeInfo type = target.GetTypeInfo(DataType.RealCodeHeader); MethodDesc = target.ReadPointer(address + (ulong)type.Fields[nameof(MethodDesc)].Offset); + DebugInfo = target.ReadPointer(address + (ulong)type.Fields[nameof(DebugInfo)].Offset); GCInfo = target.ReadPointer(address + (ulong)type.Fields[nameof(GCInfo)].Offset); NumUnwindInfos = target.Read(address + (ulong)type.Fields[nameof(NumUnwindInfos)].Offset); UnwindInfos = address + (ulong)type.Fields[nameof(UnwindInfos)].Offset; } public TargetPointer MethodDesc { get; init; } + public TargetPointer DebugInfo { get; init; } public TargetPointer GCInfo { get; init; } public uint NumUnwindInfos { get; init; } public TargetPointer UnwindInfos { get; init; } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/StressLog.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/StressLog.cs index 71f4c3ca20f5ac..b23eff5acda316 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/StressLog.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/StressLog.cs @@ -23,6 +23,9 @@ public StressLog(Target target, TargetPointer address) StartTimestamp = target.Read(address + (ulong)type.Fields[nameof(StartTimestamp)].Offset); ModuleOffset = target.ReadNUInt(address + (ulong)type.Fields[nameof(ModuleOffset)].Offset); + if (type.Fields.ContainsKey(nameof(Modules))) + Modules = target.ReadPointer(address + (ulong)type.Fields[nameof(Modules)].Offset); + Logs = target.ReadPointer(address + (ulong)type.Fields[nameof(Logs)].Offset); } @@ -42,5 +45,7 @@ public StressLog(Target target, TargetPointer address) public TargetNUInt ModuleOffset { get; init; } + public TargetPointer? Modules { get; init; } + public TargetPointer Logs { get; init; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/SystemDomain.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/SystemDomain.cs new file mode 100644 index 00000000000000..e3596be4def1bb --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/SystemDomain.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class SystemDomain : IData +{ + static SystemDomain IData.Create(Target target, TargetPointer address) => new SystemDomain(target, address); + public SystemDomain(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.SystemDomain); + GlobalLoaderAllocator = address + (ulong)type.Fields[nameof(GlobalLoaderAllocator)].Offset; + } + + public TargetPointer GlobalLoaderAllocator { get; init; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/TLSIndex.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/TLSIndex.cs new file mode 100644 index 00000000000000..6f76423fe7e364 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/TLSIndex.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class TLSIndex : IData +{ + static TLSIndex IData.Create(Target target, TargetPointer address) => new TLSIndex(target, address); + public TLSIndex(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.TLSIndex); + TLSIndexRawIndex = target.Read(address + (ulong)type.Fields[nameof(TLSIndexRawIndex)].Offset); + IndexOffset = (int)(TLSIndexRawIndex & 0xFFFFFF); + IndexType = (int)(TLSIndexRawIndex >> 24); + IsAllocated = (TLSIndexRawIndex != 0xFFFFFFFF); + } + public uint TLSIndexRawIndex { get; init; } + public int IndexOffset { get; init; } + public int IndexType { get; init; } + public bool IsAllocated { get; init; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Thread.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Thread.cs index 1d6c484b7b8f37..74d3cec867ed13 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Thread.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Thread.cs @@ -33,6 +33,7 @@ public Thread(Target target, TargetPointer address) // Address of the exception tracker ExceptionTracker = address + (ulong)type.Fields[nameof(ExceptionTracker)].Offset; + ThreadLocalDataPtr = target.ReadPointer(address + (ulong)type.Fields[nameof(ThreadLocalDataPtr)].Offset); } public uint Id { get; init; } @@ -45,4 +46,5 @@ public Thread(Target target, TargetPointer address) public ObjectHandle LastThrownObject { get; init; } public TargetPointer LinkNext { get; init; } public TargetPointer ExceptionTracker { get; init; } + public TargetPointer ThreadLocalDataPtr { get; init; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ThreadLocalData.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ThreadLocalData.cs new file mode 100644 index 00000000000000..6ea3ce3204b68b --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ThreadLocalData.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class ThreadLocalData : IData +{ + static ThreadLocalData IData.Create(Target target, TargetPointer address) => new ThreadLocalData(target, address); + public ThreadLocalData(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.ThreadLocalData); + CollectibleTlsArrayData = target.ReadPointer(address + (ulong)type.Fields[nameof(CollectibleTlsArrayData)].Offset); + NonCollectibleTlsArrayData = target.ReadPointer(address + (ulong)type.Fields[nameof(NonCollectibleTlsArrayData)].Offset); + CollectibleTlsDataCount = target.Read(address + (ulong)type.Fields[nameof(CollectibleTlsDataCount)].Offset); + NonCollectibleTlsDataCount = target.Read(address + (ulong)type.Fields[nameof(NonCollectibleTlsDataCount)].Offset); + InFlightData = target.ReadPointer(address + (ulong)type.Fields[nameof(InFlightData)].Offset); + } + public TargetPointer CollectibleTlsArrayData { get; init; } + public TargetPointer NonCollectibleTlsArrayData { get; init; } + public int CollectibleTlsDataCount { get; init; } + public int NonCollectibleTlsDataCount { get; init; } + public TargetPointer InFlightData { get; init; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ThreadStaticsInfo.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ThreadStaticsInfo.cs new file mode 100644 index 00000000000000..d7a00cb07333e4 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ThreadStaticsInfo.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Diagnostics.DataContractReader.Data; + +internal sealed class ThreadStaticsInfo : IData +{ + static ThreadStaticsInfo IData.Create(Target target, TargetPointer address) => new ThreadStaticsInfo(target, address); + public ThreadStaticsInfo(Target target, TargetPointer address) + { + Target.TypeInfo type = target.GetTypeInfo(DataType.ThreadStaticsInfo); + GCTlsIndex = address + (ulong)type.Fields[nameof(GCTlsIndex)].Offset; + NonGCTlsIndex = address + (ulong)type.Fields[nameof(NonGCTlsIndex)].Offset; + } + public TargetPointer GCTlsIndex { get; init; } + public TargetPointer NonGCTlsIndex { get; init; } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Microsoft.Diagnostics.DataContractReader.Contracts.csproj b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Microsoft.Diagnostics.DataContractReader.Contracts.csproj index de4256093c7601..b409a9d247839c 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Microsoft.Diagnostics.DataContractReader.Contracts.csproj +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Microsoft.Diagnostics.DataContractReader.Contracts.csproj @@ -18,4 +18,10 @@ + + + + + + diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/PrintfStressMessageFormatter.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/PrintfStressMessageFormatter.cs index 377a1f093b787d..8fa787d0b75d8f 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/PrintfStressMessageFormatter.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/PrintfStressMessageFormatter.cs @@ -112,7 +112,7 @@ private void FormatAsciiString(TargetPointer ptr, PaddingFormat paddingFormat, S { builder.Append(_target.ReadUtf8String(ptr).PadLeft(paddingFormat.Width, paddingFormat.FormatChar)); } - catch (InvalidOperationException) + catch (VirtualReadException) { builder.Append($"(#Could not read address of string at 0x{ptr.Value:x}#)"); } @@ -124,7 +124,7 @@ private void FormatUtf16String(TargetPointer ptr, PaddingFormat paddingFormat, S { builder.Append(_target.ReadUtf16String(ptr).PadLeft(paddingFormat.Width, paddingFormat.FormatChar)); } - catch (InvalidOperationException) + catch (VirtualReadException) { builder.Append($"(#Could not read address of string at 0x{ptr.Value:x}#)"); } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/RuntimeTypeSystemHelpers/MethodDescOptionalSlots.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/RuntimeTypeSystemHelpers/MethodDescOptionalSlots.cs index 81efb5b54115b6..028b58f27d1c0c 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/RuntimeTypeSystemHelpers/MethodDescOptionalSlots.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/RuntimeTypeSystemHelpers/MethodDescOptionalSlots.cs @@ -37,7 +37,7 @@ private static uint StartOffset(MethodClassification classification, Target targ // See MethodDesc::GetBaseSize and s_ClassificationSizeTable // sizeof(MethodDesc), mcIL // sizeof(FCallMethodDesc), mcFCall - // sizeof(NDirectMethodDesc), mcPInvoke + // sizeof(PInvokeMethodDesc), mcPInvoke // sizeof(EEImplMethodDesc), mcEEImpl // sizeof(ArrayMethodDesc), mcArray // sizeof(InstantiatedMethodDesc), mcInstantiated diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs index a3da176f1548c9..d979a8f7705727 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs @@ -40,7 +40,7 @@ public CachingContractRegistry(Target target, TryGetContractVersionDelegate tryG [typeof(IReJIT)] = new ReJITFactory(), [typeof(IStackWalk)] = new StackWalkFactory(), [typeof(IRuntimeInfo)] = new RuntimeInfoFactory(), - [typeof(IECall)] = new ECallFactory(), + [typeof(IDebugInfo)] = new DebugInfoFactory(), }; configureFactories?.Invoke(_factories); } @@ -59,7 +59,7 @@ public CachingContractRegistry(Target target, TryGetContractVersionDelegate tryG public override IReJIT ReJIT => GetContract(); public override IStackWalk StackWalk => GetContract(); public override IRuntimeInfo RuntimeInfo => GetContract(); - public override IECall ECall => GetContract(); + public override IDebugInfo DebugInfo => GetContract(); private TContract GetContract() where TContract : IContract { diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs index 11cef0bbaaf4f2..e5ae46693bc20e 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs @@ -32,8 +32,8 @@ private readonly struct Configuration } private readonly Configuration _config; - private readonly Reader _reader; + private readonly DataTargetDelegates _dataTargetDelegates; private readonly Dictionary _contracts = []; private readonly IReadOnlyDictionary _globals = new Dictionary(); private readonly Dictionary _knownTypes = []; @@ -43,6 +43,7 @@ private readonly struct Configuration public override DataCache ProcessedData { get; } public delegate int ReadFromTargetDelegate(ulong address, Span bufferToFill); + public delegate int WriteToTargetDelegate(ulong address, Span bufferToWrite); public delegate int GetTargetThreadContextDelegate(uint threadId, uint contextFlags, Span bufferToFill); /// @@ -56,18 +57,19 @@ private readonly struct Configuration public static bool TryCreate( ulong contractDescriptor, ReadFromTargetDelegate readFromTarget, + WriteToTargetDelegate writeToTarget, GetTargetThreadContextDelegate getThreadContext, [NotNullWhen(true)] out ContractDescriptorTarget? target) { - Reader reader = new Reader(readFromTarget, getThreadContext); + DataTargetDelegates dataTargetDelegates = new DataTargetDelegates(readFromTarget, writeToTarget, getThreadContext); if (TryReadContractDescriptor( contractDescriptor, - reader, + dataTargetDelegates, out Configuration config, out ContractDescriptorParser.ContractDescriptor? descriptor, out TargetPointer[] pointerData)) { - target = new ContractDescriptorTarget(config, descriptor!, pointerData, reader); + target = new ContractDescriptorTarget(config, descriptor!, pointerData, dataTargetDelegates); return true; } @@ -89,6 +91,7 @@ public static ContractDescriptorTarget Create( ContractDescriptorParser.ContractDescriptor contractDescriptor, TargetPointer[] globalPointerValues, ReadFromTargetDelegate readFromTarget, + WriteToTargetDelegate writeToTarget, GetTargetThreadContextDelegate getThreadContext, bool isLittleEndian, int pointerSize) @@ -97,15 +100,15 @@ public static ContractDescriptorTarget Create( new Configuration { IsLittleEndian = isLittleEndian, PointerSize = pointerSize }, contractDescriptor, globalPointerValues, - new Reader(readFromTarget, getThreadContext)); + new DataTargetDelegates(readFromTarget, writeToTarget, getThreadContext)); } - private ContractDescriptorTarget(Configuration config, ContractDescriptorParser.ContractDescriptor descriptor, TargetPointer[] pointerData, Reader reader) + private ContractDescriptorTarget(Configuration config, ContractDescriptorParser.ContractDescriptor descriptor, TargetPointer[] pointerData, DataTargetDelegates dataTargetDelegates) { Contracts = new CachingContractRegistry(this, this.TryGetContractVersion); ProcessedData = new DataCache(this); _config = config; - _reader = reader; + _dataTargetDelegates = dataTargetDelegates; _contracts = descriptor.Contracts ?? []; @@ -153,7 +156,7 @@ private ContractDescriptorTarget(Configuration config, ContractDescriptorParser. if (global.Indirect) { if (global.NumericValue.Value >= (ulong)pointerData.Length) - throw new InvalidOperationException($"Invalid pointer data index {global.NumericValue.Value}."); + throw new VirtualReadException($"Invalid pointer data index {global.NumericValue.Value}."); globalValues[name] = new GlobalValue { @@ -187,7 +190,7 @@ private struct GlobalValue // See docs/design/datacontracts/contract-descriptor.md private static bool TryReadContractDescriptor( ulong address, - Reader reader, + DataTargetDelegates dataTargetDelegates, out Configuration config, out ContractDescriptorParser.ContractDescriptor? descriptor, out TargetPointer[] pointerData) @@ -198,7 +201,7 @@ private static bool TryReadContractDescriptor( // Magic - uint64_t Span buffer = stackalloc byte[sizeof(ulong)]; - if (reader.ReadFromTarget(address, buffer) < 0) + if (dataTargetDelegates.ReadFromTarget(address, buffer) < 0) return false; address += sizeof(ulong); @@ -209,7 +212,7 @@ private static bool TryReadContractDescriptor( return false; // Flags - uint32_t - if (!TryRead(address, isLittleEndian, reader, out uint flags)) + if (!TryRead(address, isLittleEndian, dataTargetDelegates, out uint flags)) return false; address += sizeof(uint); @@ -220,19 +223,19 @@ private static bool TryReadContractDescriptor( config = new Configuration { IsLittleEndian = isLittleEndian, PointerSize = pointerSize }; // Descriptor size - uint32_t - if (!TryRead(address, config.IsLittleEndian, reader, out uint descriptorSize)) + if (!TryRead(address, config.IsLittleEndian, dataTargetDelegates, out uint descriptorSize)) return false; address += sizeof(uint); // Descriptor - char* - if (!TryReadPointer(address, config, reader, out TargetPointer descriptorAddr)) + if (!TryReadPointer(address, config, dataTargetDelegates, out TargetPointer descriptorAddr)) return false; address += (uint)pointerSize; // Pointer data count - uint32_t - if (!TryRead(address, config.IsLittleEndian, reader, out uint pointerDataCount)) + if (!TryRead(address, config.IsLittleEndian, dataTargetDelegates, out uint pointerDataCount)) return false; address += sizeof(uint); @@ -241,14 +244,14 @@ private static bool TryReadContractDescriptor( address += sizeof(uint); // Pointer data - uintptr_t* - if (!TryReadPointer(address, config, reader, out TargetPointer pointerDataAddr)) + if (!TryReadPointer(address, config, dataTargetDelegates, out TargetPointer pointerDataAddr)) return false; // Read descriptor Span descriptorBuffer = descriptorSize <= StackAllocByteThreshold ? stackalloc byte[(int)descriptorSize] : new byte[(int)descriptorSize]; - if (reader.ReadFromTarget(descriptorAddr.Value, descriptorBuffer) < 0) + if (dataTargetDelegates.ReadFromTarget(descriptorAddr.Value, descriptorBuffer) < 0) return false; descriptor = ContractDescriptorParser.ParseCompact(descriptorBuffer); @@ -259,7 +262,7 @@ private static bool TryReadContractDescriptor( pointerData = new TargetPointer[pointerDataCount]; for (int i = 0; i < pointerDataCount; i++) { - if (!TryReadPointer(pointerDataAddr.Value + (uint)(i * pointerSize), config, reader, out pointerData[i])) + if (!TryReadPointer(pointerDataAddr.Value + (uint)(i * pointerSize), config, dataTargetDelegates, out pointerData[i])) return false; } @@ -280,7 +283,7 @@ private static DataType GetDataType(string type) public override bool TryGetThreadContext(ulong threadId, uint contextFlags, Span buffer) { // Underlying API only supports 32-bit thread IDs, mask off top 32 bits - int hr = _reader.GetThreadContext((uint)(threadId & uint.MaxValue), contextFlags, buffer); + int hr = _dataTargetDelegates.GetThreadContext((uint)(threadId & uint.MaxValue), contextFlags, buffer); return hr == 0; } @@ -290,19 +293,36 @@ public override bool TryGetThreadContext(ulong threadId, uint contextFlags, Span /// Type of value to read /// Address to start reading from /// Value read from the target + /// Thrown when the read operation fails public override T Read(ulong address) { - if (!TryRead(address, _config.IsLittleEndian, _reader, out T value)) - throw new InvalidOperationException($"Failed to read {typeof(T)} at 0x{address:x8}."); + if (!TryRead(address, _config.IsLittleEndian, _dataTargetDelegates, out T value)) + throw new VirtualReadException($"Failed to read {typeof(T)} at 0x{address:x8}."); return value; } - private static bool TryRead(ulong address, bool isLittleEndian, Reader reader, out T value) where T : unmanaged, IBinaryInteger, IMinMaxValue + /// + /// Read a value from the target in target endianness + /// + /// Type of value to read + /// Address to start reading from + /// True if read succeeds, false otherwise. + public override bool TryRead(ulong address, out T value) + { + value = default; + if (!TryRead(address, _config.IsLittleEndian, _dataTargetDelegates, out T readValue)) + return false; + + value = readValue; + return true; + } + + private static bool TryRead(ulong address, bool isLittleEndian, DataTargetDelegates dataTargetDelegates, out T value) where T : unmanaged, IBinaryInteger, IMinMaxValue { value = default; Span buffer = stackalloc byte[sizeof(T)]; - if (reader.ReadFromTarget(address, buffer) < 0) + if (dataTargetDelegates.ReadFromTarget(address, buffer) < 0) return false; return isLittleEndian @@ -310,6 +330,30 @@ private static bool TryRead(ulong address, bool isLittleEndian, Reader reader : T.TryReadBigEndian(buffer, !IsSigned(), out value); } + /// + /// Write a value to the target in target endianness + /// + /// Type of value to write + /// Address to start writing to + public override void Write(ulong address, T value) + { + if (!TryWrite(address, _config.IsLittleEndian, _dataTargetDelegates, value)) + throw new InvalidOperationException($"Failed to write {typeof(T)} at 0x{address:x8}."); + } + + private static bool TryWrite(ulong address, bool isLittleEndian, DataTargetDelegates dataTargetDelegates, T value) where T : unmanaged, IBinaryInteger, IMinMaxValue + { + Span buffer = stackalloc byte[sizeof(T)]; + int bytesWritten = default; + bool success = isLittleEndian + ? value.TryWriteLittleEndian(buffer, out bytesWritten) + : value.TryWriteBigEndian(buffer, out bytesWritten); + if (!success || bytesWritten != buffer.Length || dataTargetDelegates.WriteToTarget(address, buffer) < 0) + return false; + + return true; + } + private static T Read(ReadOnlySpan bytes, bool isLittleEndian) where T : unmanaged, IBinaryInteger, IMinMaxValue { if (sizeof(T) != bytes.Length) @@ -330,12 +374,23 @@ private static T Read(ReadOnlySpan bytes, bool isLittleEndian) where T public override void ReadBuffer(ulong address, Span buffer) { if (!TryReadBuffer(address, buffer)) - throw new InvalidOperationException($"Failed to read {buffer.Length} bytes at 0x{address:x8}."); + throw new VirtualReadException($"Failed to read {buffer.Length} bytes at 0x{address:x8}."); } private bool TryReadBuffer(ulong address, Span buffer) { - return _reader.ReadFromTarget(address, buffer) >= 0; + return _dataTargetDelegates.ReadFromTarget(address, buffer) >= 0; + } + + public override void WriteBuffer(ulong address, Span buffer) + { + if (!TryWriteBuffer(address, buffer)) + throw new InvalidOperationException($"Failed to write {buffer.Length} bytes at 0x{address:x8}."); + } + + private bool TryWriteBuffer(ulong address, Span buffer) + { + return _dataTargetDelegates.WriteToTarget(address, buffer) >= 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -348,11 +403,11 @@ private static bool IsSigned() where T : struct, INumberBase, IMinMaxValue /// Read a pointer from the target in target endianness /// /// Address to start reading from - /// Pointer read from the target} + /// Pointer read from the target public override TargetPointer ReadPointer(ulong address) { - if (!TryReadPointer(address, _config, _reader, out TargetPointer pointer)) - throw new InvalidOperationException($"Failed to read pointer at 0x{address:x8}."); + if (!TryReadPointer(address, _config, _dataTargetDelegates, out TargetPointer pointer)) + throw new VirtualReadException($"Failed to read pointer at 0x{address:x8}."); return pointer; } @@ -380,7 +435,7 @@ public override TargetCodePointer ReadCodePointer(ulong address) { return new TargetCodePointer(Read(address)); } - throw new InvalidOperationException($"Failed to read code pointer at 0x{address:x8} because CodePointer size is not 4 or 8"); + throw new VirtualReadException($"Failed to read code pointer at 0x{address:x8} because CodePointer size is not 4 or 8"); } public void ReadPointers(ulong address, Span buffer) @@ -400,7 +455,7 @@ public void ReadPointers(ulong address, Span buffer) /// Read a null-terminated UTF-8 string from the target /// /// Address to start reading from - /// String read from the target} + /// String read from the target public override string ReadUtf8String(ulong address) { // Read characters until we find the null terminator @@ -425,7 +480,7 @@ public override string ReadUtf8String(ulong address) /// Read a null-terminated UTF-16 string from the target in target endianness /// /// Address to start reading from - /// String read from the target} + /// String read from the target public override string ReadUtf16String(ulong address) { // Read characters until we find the null terminator @@ -456,33 +511,33 @@ public override string ReadUtf16String(ulong address) /// Value read from the target public override TargetNUInt ReadNUInt(ulong address) { - if (!TryReadNUInt(address, _config, _reader, out ulong value)) - throw new InvalidOperationException($"Failed to read nuint at 0x{address:x8}."); + if (!TryReadNUInt(address, _config, _dataTargetDelegates, out ulong value)) + throw new VirtualReadException($"Failed to read nuint at 0x{address:x8}."); return new TargetNUInt(value); } - private static bool TryReadPointer(ulong address, Configuration config, Reader reader, out TargetPointer pointer) + private static bool TryReadPointer(ulong address, Configuration config, DataTargetDelegates dataTargetDelegates, out TargetPointer pointer) { pointer = TargetPointer.Null; - if (!TryReadNUInt(address, config, reader, out ulong value)) + if (!TryReadNUInt(address, config, dataTargetDelegates, out ulong value)) return false; pointer = new TargetPointer(value); return true; } - private static bool TryReadNUInt(ulong address, Configuration config, Reader reader, out ulong value) + private static bool TryReadNUInt(ulong address, Configuration config, DataTargetDelegates dataTargetDelegates, out ulong value) { value = 0; if (config.PointerSize == sizeof(uint) - && TryRead(address, config.IsLittleEndian, reader, out uint value32)) + && TryRead(address, config.IsLittleEndian, dataTargetDelegates, out uint value32)) { value = value32; return true; } else if (config.PointerSize == sizeof(ulong) - && TryRead(address, config.IsLittleEndian, reader, out ulong value64)) + && TryRead(address, config.IsLittleEndian, dataTargetDelegates, out ulong value64)) { value = value64; return true; @@ -596,7 +651,7 @@ public override TypeInfo GetTypeInfo(DataType type) public Target.TypeInfo GetTypeInfo(string type) { if (_types.TryGetValue(type, out Target.TypeInfo typeInfo)) - return typeInfo; + return typeInfo; DataType dataType = GetDataType(type); if (dataType is not DataType.Unknown) @@ -657,8 +712,9 @@ public void Clear() } } - private readonly struct Reader( + private readonly struct DataTargetDelegates( ReadFromTargetDelegate readFromTarget, + WriteToTargetDelegate writeToTarget, GetTargetThreadContextDelegate getThreadContext) { public int ReadFromTarget(ulong address, Span buffer) @@ -673,5 +729,9 @@ public int GetThreadContext(uint threadId, uint contextFlags, Span buffer) { return getThreadContext(threadId, contextFlags, buffer); } + public int WriteToTarget(ulong address, Span buffer) + { + return writeToTarget(address, buffer); + } } } diff --git a/src/native/managed/cdac/inc/cdac_reader.h b/src/native/managed/cdac/inc/cdac_reader.h index aa011df71487d7..b68471e77b4d7a 100644 --- a/src/native/managed/cdac/inc/cdac_reader.h +++ b/src/native/managed/cdac/inc/cdac_reader.h @@ -18,6 +18,7 @@ extern "C" int cdac_reader_init( uint64_t descriptor, int(*read_from_target)(uint64_t, uint8_t*, uint32_t, void*), + int(*write_to_target)(uint64_t, const uint8_t*, uint32_t, void*), int(*read_thread_context)(uint32_t, uint32_t, uint32_t, uint8_t*, void*), void* read_context, /*out*/ intptr_t* handle); diff --git a/src/native/managed/cdac/mscordaccore_universal/Entrypoints.cs b/src/native/managed/cdac/mscordaccore_universal/Entrypoints.cs index db02e3531875fd..d0db95a1e58ccb 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Entrypoints.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Entrypoints.cs @@ -16,8 +16,9 @@ internal static class Entrypoints private static unsafe int Init( ulong descriptor, delegate* unmanaged readFromTarget, + delegate* unmanaged writeToTarget, delegate* unmanaged readThreadContext, - void* readContext, + void* delegateContext, IntPtr* handle) { // TODO: [cdac] Better error code/details @@ -27,14 +28,21 @@ private static unsafe int Init( { fixed (byte* bufferPtr = buffer) { - return readFromTarget(address, bufferPtr, (uint)buffer.Length, readContext); + return readFromTarget(address, bufferPtr, (uint)buffer.Length, delegateContext); + } + }, + (address, buffer) => + { + fixed (byte* bufferPtr = buffer) + { + return writeToTarget(address, bufferPtr, (uint)buffer.Length, delegateContext); } }, (threadId, contextFlags, buffer) => { fixed (byte* bufferPtr = buffer) { - return readThreadContext(threadId, contextFlags, (uint)buffer.Length, bufferPtr, readContext); + return readThreadContext(threadId, contextFlags, (uint)buffer.Length, bufferPtr, delegateContext); } }, out ContractDescriptorTarget? target)) @@ -124,6 +132,14 @@ private static unsafe int CLRDataCreateInstanceImpl(Guid* pIID, IntPtr /*ICLRDat return dataTarget.ReadVirtual(address, bufferPtr, (uint)buffer.Length, &bytesRead); } }, + (address, buffer) => + { + fixed (byte* bufferPtr = buffer) + { + uint bytesWritten; + return dataTarget.WriteVirtual(address, bufferPtr, (uint)buffer.Length, &bytesWritten); + } + }, (threadId, contextFlags, bufferToFill) => { fixed (byte* bufferPtr = bufferToFill) diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataMethodInstance.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataMethodInstance.cs index 27cabfe18834b9..ae823df64d721a 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataMethodInstance.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataMethodInstance.cs @@ -2,7 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections; +using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; @@ -125,7 +128,87 @@ int IXCLRDataMethodInstance.GetTypeArgumentByIndex(uint index, void** typeArg) => _legacyImpl is not null ? _legacyImpl.GetTypeArgumentByIndex(index, typeArg) : HResults.E_NOTIMPL; int IXCLRDataMethodInstance.GetILOffsetsByAddress(ClrDataAddress address, uint offsetsLen, uint* offsetsNeeded, uint* ilOffsets) - => _legacyImpl is not null ? _legacyImpl.GetILOffsetsByAddress(address, offsetsLen, offsetsNeeded, ilOffsets) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + + try + { + TargetCodePointer pCode = address.ToTargetCodePointer(_target); + List map = _target.Contracts.DebugInfo.GetMethodNativeMap( + pCode, + preferUninstrumented: false, + out uint codeOffset).ToList(); + + uint hits = 0; + for (int i = 0; i < map.Count; i++) + { + bool isEpilog = map[i].ILOffset == unchecked((uint)-3); // -3 is used to indicate an epilog + bool lastValue = i == map.Count - 1; + uint nativeEndOffset = lastValue ? 0 : map[i + 1].NativeOffset; + if (codeOffset >= map[i].NativeOffset && (((isEpilog || lastValue) && nativeEndOffset == 0) || codeOffset < nativeEndOffset)) + { + if (hits < offsetsLen && ilOffsets is not null) + { + ilOffsets[hits] = map[i].ILOffset; + } + + hits++; + } + } + + if (offsetsNeeded is not null) + { + *offsetsNeeded = hits; + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + +#if DEBUG + if (_legacyImpl is not null) + { + int hrLocal; + + bool validateOffsetsNeeded = offsetsNeeded is not null; + uint localOffsetsNeeded = 0; + + bool validateIlOffsets = ilOffsets is not null; + uint[] localIlOffsets = new uint[offsetsLen]; + + fixed (uint* localIlOffsetsPtr = localIlOffsets) + { + hrLocal = _legacyImpl.GetILOffsetsByAddress( + address, + offsetsLen, + validateOffsetsNeeded ? &localOffsetsNeeded : null, + validateIlOffsets ? localIlOffsetsPtr : null); + } + + // DAC function returns odd failure codes it doesn't make sense to match directly + Debug.Assert(hrLocal == hr || (hrLocal < 0 && hr < 0), $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + + if (hr == HResults.S_OK) + { + if (validateOffsetsNeeded) + { + Debug.Assert(localOffsetsNeeded == *offsetsNeeded, $"cDAC: {*offsetsNeeded:x}, DAC: {localOffsetsNeeded:x}"); + } + + if (validateIlOffsets) + { + for (int i = 0; i < localIlOffsets.Length; i++) + { + Debug.Assert(localIlOffsets[i] == ilOffsets[i], $"cDAC: {localIlOffsets[i]:x}, DAC: {ilOffsets[i]:x}"); + } + } + } + } +#endif + + return hr; + } int IXCLRDataMethodInstance.GetAddressRangesByILOffset(uint ilOffset, uint rangesLen, uint* rangesNeeded, void* addressRanges) => _legacyImpl is not null ? _legacyImpl.GetAddressRangesByILOffset(ilOffset, rangesLen, rangesNeeded, addressRanges) : HResults.E_NOTIMPL; diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataModule.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataModule.cs index 45cf9a32bd5537..d000e9f67ad92c 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataModule.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/ClrDataModule.cs @@ -132,16 +132,16 @@ int IXCLRDataModule.GetFileName(uint bufLen, uint* nameLen, char* name) try { Contracts.ILoader contract = _target.Contracts.Loader; - Contracts.ModuleHandle handle = contract.GetModuleHandle(_address); + Contracts.ModuleHandle handle = contract.GetModuleHandleFromModulePtr(_address); string result = string.Empty; try { result = contract.GetPath(handle); } - catch (InvalidOperationException) + catch (VirtualReadException) { // The memory for the path may not be enumerated - for example, in triage dumps - // In this case, GetPath will throw InvalidOperationException + // In this case, GetPath will throw VirtualReadException } if (string.IsNullOrEmpty(result)) @@ -183,7 +183,7 @@ int IXCLRDataModule.GetFlags(uint* flags) try { Contracts.ILoader contract = _target.Contracts.Loader; - Contracts.ModuleHandle handle = contract.GetModuleHandle(_address); + Contracts.ModuleHandle handle = contract.GetModuleHandleFromModulePtr(_address); ModuleFlags moduleFlags = contract.GetFlags(handle); if ((moduleFlags & ModuleFlags.ReflectionEmit) != 0) @@ -225,7 +225,7 @@ int IXCLRDataModule.StartEnumExtents(ulong* handle) if (!_extentsSet) { Contracts.ILoader contract = _target.Contracts.Loader; - Contracts.ModuleHandle moduleHandle = contract.GetModuleHandle(_address); + Contracts.ModuleHandle moduleHandle = contract.GetModuleHandleFromModulePtr(_address); TargetPointer peAssembly = contract.GetPEAssembly(moduleHandle); if (peAssembly == 0) @@ -271,7 +271,7 @@ int IXCLRDataModule.EnumExtent(ulong* handle, /*CLRDATA_MODULE_EXTENT*/ void* ex try { Contracts.ILoader contract = _target.Contracts.Loader; - Contracts.ModuleHandle moduleHandle = contract.GetModuleHandle(_address); + Contracts.ModuleHandle moduleHandle = contract.GetModuleHandleFromModulePtr(_address); if (!_extentsSet) { @@ -347,7 +347,7 @@ private int DacPrivateRequestGetModuleData(uint inBufferSize, byte* inBuffer, ui Unsafe.InitBlock(getModuleData, 0, (uint)sizeof(DacpGetModuleData)); Contracts.ILoader contract = _target.Contracts.Loader; - Contracts.ModuleHandle moduleHandle = contract.GetModuleHandle(_address); + Contracts.ModuleHandle moduleHandle = contract.GetModuleHandleFromModulePtr(_address); TargetPointer peAssembly = contract.GetPEAssembly(moduleHandle); bool isReflectionEmit = (contract.GetFlags(moduleHandle) & ModuleFlags.ReflectionEmit) != 0; diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/ISOSDacInterface.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/ISOSDacInterface.cs index 73eb5aa3c24c5d..f2663d4363cce4 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/ISOSDacInterface.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/ISOSDacInterface.cs @@ -11,6 +11,15 @@ namespace Microsoft.Diagnostics.DataContractReader.Legacy; // See src/coreclr/inc/sospriv.idl #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value + +internal enum CLRDataOtherNotifyFlag +{ + CLRDATA_NOTIFY_ON_MODULE_LOAD = 0x1, + CLRDATA_NOTIFY_ON_MODULE_UNLOAD = 0x2, + CLRDATA_NOTIFY_ON_EXCEPTION = 0x4, + CLRDATA_NOTIFY_ON_EXCEPTION_CATCH_ENTER = 0x8 +} + internal struct DacpThreadStoreData { public int threadCount; @@ -24,6 +33,47 @@ internal struct DacpThreadStoreData public int fHostConfig; // Uses hosting flags defined above }; +internal enum DacpAppDomainDataStage : uint +{ + STAGE_CREATING, + STAGE_READYFORMANAGEDCODE, + STAGE_ACTIVE, + STAGE_OPEN, + STAGE_UNLOAD_REQUESTED, + STAGE_EXITING, + STAGE_EXITED, + STAGE_FINALIZING, + STAGE_FINALIZED, + STAGE_HANDLETABLE_NOACCESS, + STAGE_CLEARED, + STAGE_COLLECTED, + STAGE_CLOSED +}; + +internal struct DacpAppDomainData +{ + // The pointer to the AppDomain or SystemDomain. + // It's useful to keep this around in the structure + public ClrDataAddress AppDomainPtr; + public ClrDataAddress AppSecDesc; + public ClrDataAddress pLowFrequencyHeap; + public ClrDataAddress pHighFrequencyHeap; + public ClrDataAddress pStubHeap; + public ClrDataAddress DomainLocalBlock; + public ClrDataAddress pDomainLocalModules; + // The creation sequence number of this app domain (starting from 1) + public uint dwId; + public int AssemblyCount; + public int FailedAssemblyCount; + public DacpAppDomainDataStage appDomainStage; +}; + +internal struct DacpAppDomainStoreData +{ + public ClrDataAddress sharedDomain; + public ClrDataAddress systemDomain; + public int DomainCount; +}; internal struct DacpThreadData { public int corThreadId; @@ -128,6 +178,22 @@ internal struct DacpUsefulGlobalsData } #pragma warning restore CS0649 // Field is never assigned to, and will always have its default value +internal struct DacpMethodTableFieldData +{ + public ushort wNumInstanceFields; + public ushort wNumStaticFields; + public ushort wNumThreadStaticFields; + public ClrDataAddress FirstField; + public ushort wContextStaticOffset; + public ushort wContextStaticsSize; +}; + +internal enum MethodTableInitializationFlags +{ + MethodTableInitialized = 1, + MethodTableInitializationFailed = 2 +}; + internal struct DacpReJitData { // FIXME[cdac]: the C++ definition enum doesn't have an explicit underlying type or constant values for the flags @@ -194,7 +260,7 @@ internal unsafe partial interface ISOSDacInterface [PreserveSig] int GetAppDomainList(uint count, [In, Out, MarshalUsing(CountElementName = nameof(count))] ClrDataAddress[] values, uint* pNeeded); [PreserveSig] - int GetAppDomainData(ClrDataAddress addr, /*struct DacpAppDomainData*/ void* data); + int GetAppDomainData(ClrDataAddress addr, DacpAppDomainData* data); [PreserveSig] int GetAppDomainName(ClrDataAddress addr, uint count, char* name, uint* pNeeded); [PreserveSig] @@ -276,7 +342,7 @@ internal unsafe partial interface ISOSDacInterface [PreserveSig] int GetMethodTableSlot(ClrDataAddress mt, uint slot, ClrDataAddress* value); [PreserveSig] - int GetMethodTableFieldData(ClrDataAddress mt, /*struct DacpMethodTableFieldData*/ void* data); + int GetMethodTableFieldData(ClrDataAddress mt, DacpMethodTableFieldData* data); [PreserveSig] int GetMethodTableTransparencyData(ClrDataAddress mt, /*struct DacpMethodTableTransparencyData*/ void* data); @@ -587,7 +653,7 @@ internal unsafe partial interface ISOSDacInterface14 [PreserveSig] int GetThreadStaticBaseAddress(ClrDataAddress methodTable, ClrDataAddress thread, ClrDataAddress* nonGCStaticsAddress, ClrDataAddress* GCStaticsAddress); [PreserveSig] - int GetMethodTableInitializationFlags(ClrDataAddress methodTable, /*MethodTableInitializationFlags*/ int* initializationStatus); + int GetMethodTableInitializationFlags(ClrDataAddress methodTable, MethodTableInitializationFlags* initializationStatus); } [GeneratedComInterface] diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/IXCLRData.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/IXCLRData.cs index ae043ab996a5a4..e80aabc43f62bc 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/IXCLRData.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/IXCLRData.cs @@ -206,7 +206,7 @@ int GetRuntimeNameByAddress( int GetModuleByAddress(ClrDataAddress address, /*IXCLRDataModule*/ void** mod); [PreserveSig] - int StartEnumMethodInstancesByAddress(ulong address, /*IXCLRDataAppDomain*/ void* appDomain, ulong* handle); + int StartEnumMethodInstancesByAddress(ClrDataAddress address, /*IXCLRDataAppDomain*/ void* appDomain, ulong* handle); [PreserveSig] int EnumMethodInstanceByAddress(ulong* handle, out IXCLRDataMethodInstance? method); [PreserveSig] diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.IXCLRDataProcess.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.IXCLRDataProcess.cs index a51a20832f56ca..3f7a880196944e 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.IXCLRDataProcess.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.IXCLRDataProcess.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -10,8 +9,6 @@ using System.Runtime.InteropServices.Marshalling; using Microsoft.Diagnostics.DataContractReader.Contracts; using Microsoft.Diagnostics.DataContractReader.Contracts.Extensions; -using Microsoft.Diagnostics.DataContractReader.RuntimeTypeSystemHelpers; - namespace Microsoft.Diagnostics.DataContractReader.Legacy; @@ -146,6 +143,7 @@ internal class EnumMethodInstances public readonly TargetPointer _appDomain; private readonly ILoader _loader; private readonly IRuntimeTypeSystem _rts; + private readonly ICodeVersions _cv; public IEnumerator methodEnumerator = Enumerable.Empty().GetEnumerator(); public TargetPointer LegacyHandle { get; set; } = TargetPointer.Null; @@ -165,12 +163,13 @@ public EnumMethodInstances(Target target, TargetPointer methodDesc, TargetPointe _loader = _target.Contracts.Loader; _rts = _target.Contracts.RuntimeTypeSystem; + _cv = _target.Contracts.CodeVersions; } public int Start() { MethodDescHandle mainMD = _rts.GetMethodDescHandle(_mainMethodDesc); - if (!HasClassOrMethodInstantiation(mainMD) && !HasNativeCodeAnyVersion(mainMD)) + if (!HasClassOrMethodInstantiation(mainMD) && !_cv.HasNativeCodeAnyVersion(_mainMethodDesc)) { return HResults.S_FALSE; } @@ -203,7 +202,7 @@ private IEnumerable IterateMethodInstantiations(Contracts.Modu private IEnumerable IterateModules() { ILoader loader = _target.Contracts.Loader; - IEnumerable modules = loader.GetModules( + IEnumerable modules = loader.GetModuleHandles( _appDomain, AssemblyIterationFlags.IncludeLoaded | AssemblyIterationFlags.IncludeExecution); @@ -229,7 +228,7 @@ 4. Generic method on Generic type (There are N generic defining methods where N { // case 1 // no method or class instantiation, then it's not generic. - if (HasNativeCodeAnyVersion(mainMD)) + if (_cv.HasNativeCodeAnyVersion(_mainMethodDesc)) { yield return mainMD; } @@ -256,7 +255,7 @@ 4. Generic method on Generic type (There are N generic defining methods where N if (mainModule != _rts.GetModule(methodTypeHandle)) continue; if (mainMDToken != _rts.GetMethodToken(methodDesc)) continue; - if (HasNativeCodeAnyVersion(methodDesc)) + if (_cv.HasNativeCodeAnyVersion(methodDesc.Address)) { yield return methodDesc; } @@ -294,7 +293,7 @@ 4. Generic method on Generic type (There are N generic defining methods where N if (methodDescAddr == TargetPointer.Null) continue; MethodDescHandle methodDesc = _rts.GetMethodDescHandle(methodDescAddr); - if (HasNativeCodeAnyVersion(methodDesc)) + if (_cv.HasNativeCodeAnyVersion(methodDescAddr)) { yield return methodDesc; } @@ -307,26 +306,6 @@ 4. Generic method on Generic type (There are N generic defining methods where N } - private bool HasNativeCodeAnyVersion(MethodDescHandle mdHandle) - { - IRuntimeTypeSystem rts = _target.Contracts.RuntimeTypeSystem; - ICodeVersions cv = _target.Contracts.CodeVersions; - - TargetCodePointer pcode = rts.GetNativeCode(mdHandle); - - if (pcode == TargetCodePointer.Null) - { - // TODO(cdac): Fix this to check for any native code version - NativeCodeVersionHandle nativeCodeVersion = cv.GetActiveNativeCodeVersion(mdHandle.Address); - if (nativeCodeVersion.Valid) - { - pcode = cv.GetNativeCode(nativeCodeVersion); - } - } - - return pcode != TargetCodePointer.Null; - } - private bool HasClassOrMethodInstantiation(MethodDescHandle md) { return HasClassInstantiation(md) || HasMethodInstantiation(md); @@ -350,32 +329,47 @@ private bool HasMethodInstantiation(MethodDescHandle md) } } - int IXCLRDataProcess.StartEnumMethodInstancesByAddress(ulong address, /*IXCLRDataAppDomain*/ void* appDomain, ulong* handle) + int IXCLRDataProcess.StartEnumMethodInstancesByAddress(ClrDataAddress address, /*IXCLRDataAppDomain*/ void* appDomain, ulong* handle) { int hr = HResults.S_OK; *handle = 0; hr = HResults.S_FALSE; - int hrLocal = default; ulong handleLocal = default; +#if DEBUG + int hrLocal = default; if (_legacyProcess is not null) { hrLocal = _legacyProcess.StartEnumMethodInstancesByAddress(address, appDomain, &handleLocal); - if (hrLocal < 0) - return hrLocal; } +#endif - IExecutionManager eman = _target.Contracts.ExecutionManager; - if (eman.GetCodeBlockHandle(address) is CodeBlockHandle cbh && eman.GetMethodDesc(cbh) is TargetPointer methodDesc) + try { - EnumMethodInstances emi = new(_target, methodDesc, TargetPointer.Null); + TargetCodePointer methodAddr = address.ToTargetCodePointer(_target); - emi.LegacyHandle = handleLocal; + // ClrDataAccess::IsPossibleCodeAddress + // Does a trivial check on the readability of the address + bool isTriviallyReadable = _target.TryRead(methodAddr, out byte _); + if (!isTriviallyReadable) + throw new ArgumentException(); + + IExecutionManager eman = _target.Contracts.ExecutionManager; + if (eman.GetCodeBlockHandle(methodAddr) is CodeBlockHandle cbh && + eman.GetMethodDesc(cbh) is TargetPointer methodDesc) + { + EnumMethodInstances emi = new(_target, methodDesc, TargetPointer.Null); + emi.LegacyHandle = handleLocal; - GCHandle gcHandle = GCHandle.Alloc(emi); - *handle = (ulong)GCHandle.ToIntPtr(gcHandle).ToInt64(); - hr = emi.Start(); + GCHandle gcHandle = GCHandle.Alloc(emi); + *handle = (ulong)GCHandle.ToIntPtr(gcHandle).ToInt64(); + hr = emi.Start(); + } + } + catch (System.Exception ex) + { + hr = ex.HResult; } #if DEBUG @@ -396,15 +390,16 @@ int IXCLRDataProcess.EnumMethodInstanceByAddress(ulong* handle, out IXCLRDataMet if (gcHandle.Target is not EnumMethodInstances emi) return HResults.E_INVALIDARG; IXCLRDataMethodInstance? legacyMethod = null; + +#if DEBUG int hrLocal = default; if (_legacyProcess is not null) { ulong legacyHandle = emi.LegacyHandle; hrLocal = _legacyProcess.EnumMethodInstanceByAddress(&legacyHandle, out legacyMethod); emi.LegacyHandle = legacyHandle; - if (hrLocal < 0) - return hrLocal; } +#endif try { @@ -423,11 +418,12 @@ int IXCLRDataProcess.EnumMethodInstanceByAddress(ulong* handle, out IXCLRDataMet hr = ex.HResult; } - - if (legacyMethod is not null) +#if DEBUG + if (_legacyProcess is not null) { Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); } +#endif return hr; } @@ -440,12 +436,14 @@ int IXCLRDataProcess.EndEnumMethodInstancesByAddress(ulong handle) if (gcHandle.Target is not EnumMethodInstances emi) return HResults.E_INVALIDARG; gcHandle.Free(); +#if DEBUG if (_legacyProcess != null && emi.LegacyHandle != TargetPointer.Null) { int hrLocal = _legacyProcess.EndEnumMethodInstancesByAddress(emi.LegacyHandle); if (hrLocal < 0) return hrLocal; } +#endif return hr; } @@ -520,10 +518,77 @@ int IXCLRDataProcess.SetCodeNotifications( => _legacyProcess is not null ? _legacyProcess.SetCodeNotifications(numTokens, mods, singleMod, tokens, flags, singleFlags) : HResults.E_NOTIMPL; int IXCLRDataProcess.GetOtherNotificationFlags(uint* flags) - => _legacyProcess is not null ? _legacyProcess.GetOtherNotificationFlags(flags) : HResults.E_NOTIMPL; - + { + int hr = HResults.S_OK; + try + { + *flags = _target.Read(_target.ReadGlobalPointer(Constants.Globals.DacNotificationFlags)); + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacyProcess is not null) + { + uint flagsLocal; + int hrLocal = _legacyProcess.GetOtherNotificationFlags(&flagsLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + Debug.Assert(*flags == flagsLocal); + } +#endif + return hr; + } int IXCLRDataProcess.SetOtherNotificationFlags(uint flags) - => _legacyProcess is not null ? _legacyProcess.SetOtherNotificationFlags(flags) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + try + { + if ((flags & ~((uint)CLRDataOtherNotifyFlag.CLRDATA_NOTIFY_ON_MODULE_LOAD | + (uint)CLRDataOtherNotifyFlag.CLRDATA_NOTIFY_ON_MODULE_UNLOAD | + (uint)CLRDataOtherNotifyFlag.CLRDATA_NOTIFY_ON_EXCEPTION | + (uint)CLRDataOtherNotifyFlag.CLRDATA_NOTIFY_ON_EXCEPTION_CATCH_ENTER)) != 0) + { + hr = HResults.E_INVALIDARG; + } + else + { + TargetPointer dacNotificationFlags = _target.ReadGlobalPointer(Constants.Globals.DacNotificationFlags); + _target.Write(dacNotificationFlags, flags); + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacyProcess is not null) + { + int hrLocal = default; + uint flagsLocal = default; + // have to read the flags like this and not with GetOtherNotificationFlags + // because the legacy DAC cache will not be updated when we set the flags in cDAC + // so we need to verify without using the legacy DAC + hrLocal = HResults.S_OK; + try + { + flagsLocal = _target.Read(_target.ReadGlobalPointer(Constants.Globals.DacNotificationFlags)); + } + catch (System.Exception ex) + { + hrLocal = ex.HResult; + } + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(flags == flagsLocal); + } + // update the DAC cache + _legacyProcess.SetOtherNotificationFlags(flags); + } +#endif + return hr; + } int IXCLRDataProcess.StartEnumMethodDefinitionsByAddress(ClrDataAddress address, ulong* handle) => _legacyProcess is not null ? _legacyProcess.StartEnumMethodDefinitionsByAddress(address, handle) : HResults.E_NOTIMPL; diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs index b166959f107728..342c4849bfaf27 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs @@ -11,6 +11,7 @@ using Microsoft.Diagnostics.DataContractReader.Contracts; using Microsoft.Diagnostics.DataContractReader.Contracts.Extensions; +using Microsoft.Diagnostics.DataContractReader.Contracts.StackWalkHelpers; namespace Microsoft.Diagnostics.DataContractReader.Legacy; @@ -110,14 +111,209 @@ int ISOSDacInterface.GetAppDomainConfigFile(ClrDataAddress appDomain, int count, return hr; } - int ISOSDacInterface.GetAppDomainData(ClrDataAddress addr, void* data) - => _legacyImpl is not null ? _legacyImpl.GetAppDomainData(addr, data) : HResults.E_NOTIMPL; + int ISOSDacInterface.GetAppDomainData(ClrDataAddress addr, DacpAppDomainData* data) + { + int hr = HResults.S_OK; + try + { + if (addr == 0) + { + hr = HResults.E_INVALIDARG; + } + else + { + *data = default; + data->AppDomainPtr = addr; + TargetPointer systemDomainPointer = _target.ReadGlobalPointer(Constants.Globals.SystemDomain); + ClrDataAddress systemDomain = _target.ReadPointer(systemDomainPointer).ToClrDataAddress(_target); + Contracts.ILoader loader = _target.Contracts.Loader; + TargetPointer globalLoaderAllocator = loader.GetGlobalLoaderAllocator(); + data->pHighFrequencyHeap = loader.GetHighFrequencyHeap(globalLoaderAllocator).ToClrDataAddress(_target); + data->pLowFrequencyHeap = loader.GetLowFrequencyHeap(globalLoaderAllocator).ToClrDataAddress(_target); + data->pStubHeap = loader.GetStubHeap(globalLoaderAllocator).ToClrDataAddress(_target); + data->appDomainStage = DacpAppDomainDataStage.STAGE_OPEN; + if (addr != systemDomain) + { + TargetPointer pAppDomain = addr.ToTargetPointer(_target); + data->dwId = _target.ReadGlobal(Constants.Globals.DefaultADID); + + IEnumerable modules = loader.GetModuleHandles( + pAppDomain, + AssemblyIterationFlags.IncludeLoading | + AssemblyIterationFlags.IncludeLoaded | + AssemblyIterationFlags.IncludeExecution); + + foreach (Contracts.ModuleHandle module in modules) + { + if (loader.IsAssemblyLoaded(module)) + { + data->AssemblyCount++; + } + } + + IEnumerable failedModules = loader.GetModuleHandles( + pAppDomain, + AssemblyIterationFlags.IncludeFailedToLoad); + data->FailedAssemblyCount = failedModules.Count(); + } + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacyImpl is not null) + { + DacpAppDomainData dataLocal = default; + int hrLocal = _legacyImpl.GetAppDomainData(addr, &dataLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(data->AppDomainPtr == dataLocal.AppDomainPtr); + Debug.Assert(data->pHighFrequencyHeap == dataLocal.pHighFrequencyHeap); + Debug.Assert(data->pLowFrequencyHeap == dataLocal.pLowFrequencyHeap); + Debug.Assert(data->pStubHeap == dataLocal.pStubHeap); + Debug.Assert(data->DomainLocalBlock == dataLocal.DomainLocalBlock); + Debug.Assert(data->pDomainLocalModules == dataLocal.pDomainLocalModules); + Debug.Assert(data->dwId == dataLocal.dwId); + Debug.Assert(data->appDomainStage == dataLocal.appDomainStage); + Debug.Assert(data->AssemblyCount == dataLocal.AssemblyCount); + Debug.Assert(data->FailedAssemblyCount == dataLocal.FailedAssemblyCount); + } + } +#endif + return hr; + + } int ISOSDacInterface.GetAppDomainList(uint count, [In, MarshalUsing(CountElementName = "count"), Out] ClrDataAddress[] values, uint* pNeeded) - => _legacyImpl is not null ? _legacyImpl.GetAppDomainList(count, values, pNeeded) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + try + { + uint i = 0; + TargetPointer appDomainPointer = _target.ReadGlobalPointer(Constants.Globals.AppDomain); + TargetPointer appDomain = _target.ReadPointer(appDomainPointer); + + if (appDomain != TargetPointer.Null && values.Length > 0) + { + values[0] = appDomain.ToClrDataAddress(_target); + i = 1; + } + + if (pNeeded is not null) + { + *pNeeded = i; + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacyImpl is not null) + { + ClrDataAddress[] valuesLocal = new ClrDataAddress[count]; + uint neededLocal; + int hrLocal = _legacyImpl.GetAppDomainList(count, valuesLocal, &neededLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + Debug.Assert(pNeeded == null || *pNeeded == neededLocal); + if (values is not null && values.Length > 0 && valuesLocal.Length > 0) + { + Debug.Assert(values[0] == valuesLocal[0], $"cDAC: {values[0]:x}, DAC: {valuesLocal[0]:x}"); + } + } +#endif + return hr; + } int ISOSDacInterface.GetAppDomainName(ClrDataAddress addr, uint count, char* name, uint* pNeeded) - => _legacyImpl is not null ? _legacyImpl.GetAppDomainName(addr, count, name, pNeeded) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + try + { + ILoader loader = _target.Contracts.Loader; + string friendlyName = loader.GetAppDomainFriendlyName(); + TargetPointer systemDomainPtr = _target.ReadGlobalPointer(Constants.Globals.SystemDomain); + ClrDataAddress systemDomain = _target.ReadPointer(systemDomainPtr).ToClrDataAddress(_target); + if (addr == systemDomain || friendlyName == string.Empty) + { + if (pNeeded is not null) + { + *pNeeded = 1; + } + if (name is not null && count > 0) + { + name[0] = '\0'; // Set the first character to null terminator + } + } + else + { + if (pNeeded is not null) + { + *pNeeded = (uint)(friendlyName.Length + 1); // +1 for null terminator + } + + if (name is not null && count > 0) + { + OutputBufferHelpers.CopyStringToBuffer(name, count, pNeeded, friendlyName); + } + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacyImpl is not null) + { + uint neededLocal; + char[] nameLocal = new char[count]; + int hrLocal; + fixed (char* ptr = nameLocal) + { + hrLocal = _legacyImpl.GetAppDomainName(addr, count, ptr, &neededLocal); + } + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(pNeeded == null || *pNeeded == neededLocal); + Debug.Assert(name == null || new ReadOnlySpan(nameLocal, 0, (int)neededLocal - 1).SequenceEqual(new string(name))); + } + } +#endif + return hr; + } int ISOSDacInterface.GetAppDomainStoreData(void* data) - => _legacyImpl is not null ? _legacyImpl.GetAppDomainStoreData(data) : HResults.E_NOTIMPL; + { + DacpAppDomainStoreData* appDomainStoreData = (DacpAppDomainStoreData*)data; + int hr = HResults.S_OK; + try + { + appDomainStoreData->sharedDomain = 0; + TargetPointer systemDomainPtr = _target.ReadGlobalPointer(Constants.Globals.SystemDomain); + appDomainStoreData->systemDomain = _target.ReadPointer(systemDomainPtr).ToClrDataAddress(_target); + TargetPointer appDomainPtr = _target.ReadGlobalPointer(Constants.Globals.AppDomain); + appDomainStoreData->DomainCount = _target.ReadPointer(appDomainPtr) != 0 ? 1 : 0; + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + { + if (_legacyImpl is not null) + { + DacpAppDomainStoreData dataLocal = default; + int hrLocal = _legacyImpl.GetAppDomainStoreData(&dataLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + Debug.Assert(appDomainStoreData->sharedDomain == dataLocal.sharedDomain, $"cDAC: {appDomainStoreData->sharedDomain:x}, DAC: {dataLocal.sharedDomain:x}"); + Debug.Assert(appDomainStoreData->systemDomain == dataLocal.systemDomain, $"cDAC: {appDomainStoreData->systemDomain:x}, DAC: {dataLocal.systemDomain:x}"); + Debug.Assert(appDomainStoreData->DomainCount == dataLocal.DomainCount, $"cDAC: {appDomainStoreData->DomainCount}, DAC: {dataLocal.DomainCount}"); + } + } +#endif + return hr; + } int ISOSDacInterface.GetApplicationBase(ClrDataAddress appDomain, int count, char* appBase, uint* pNeeded) { // Method is not supported on CoreCLR @@ -157,7 +353,7 @@ int ISOSDacInterface.GetAssemblyList(ClrDataAddress addr, int count, [In, Marsha else { ILoader loader = _target.Contracts.Loader; - List modules = loader.GetModules( + List modules = loader.GetModuleHandles( appDomain, AssemblyIterationFlags.IncludeLoading | AssemblyIterationFlags.IncludeLoaded | @@ -225,8 +421,54 @@ int ISOSDacInterface.GetAssemblyList(ClrDataAddress addr, int count, [In, Marsha } int ISOSDacInterface.GetAssemblyLocation(ClrDataAddress assembly, int count, char* location, uint* pNeeded) => _legacyImpl is not null ? _legacyImpl.GetAssemblyLocation(assembly, count, location, pNeeded) : HResults.E_NOTIMPL; - int ISOSDacInterface.GetAssemblyModuleList(ClrDataAddress assembly, uint count, [In, MarshalUsing(CountElementName = "count"), Out] ClrDataAddress[] modules, uint* pNeeded) - => _legacyImpl is not null ? _legacyImpl.GetAssemblyModuleList(assembly, count, modules, pNeeded) : HResults.E_NOTIMPL; + int ISOSDacInterface.GetAssemblyModuleList(ClrDataAddress assembly, uint count, [In, MarshalUsing(CountElementName = "count"), Out] ClrDataAddress[]? modules, uint* pNeeded) + { + if (assembly == 0) + { + return HResults.E_INVALIDARG; + } + int hr = HResults.S_OK; + try + { + if (modules is not null && modules.Length > 0 && count > 0) + { + TargetPointer addr = assembly.ToTargetPointer(_target); + Contracts.ILoader loader = _target.Contracts.Loader; + Contracts.ModuleHandle handle = loader.GetModuleHandleFromAssemblyPtr(addr); + TargetPointer modulePointer = loader.GetModule(handle); + modules[0] = modulePointer.ToClrDataAddress(_target); + } + + if (pNeeded is not null) + { + *pNeeded = 1; + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + +#if DEBUG + if (_legacyImpl is not null) + { + ClrDataAddress[] modulesLocal = new ClrDataAddress[count]; + uint neededLocal; + int hrLocal = _legacyImpl.GetAssemblyModuleList(assembly, count, modulesLocal, &neededLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(pNeeded == null || *pNeeded == neededLocal); + if (modules is not null && modules.Length > 0) + { + Debug.Assert(modules[0] == modulesLocal[0], $"cDAC: {modules[0]:x}, DAC: {modulesLocal[0]:x}"); + } + } + } +#endif + return hr; + + } int ISOSDacInterface.GetAssemblyName(ClrDataAddress assembly, uint count, char* name, uint* pNeeded) => _legacyImpl is not null ? _legacyImpl.GetAssemblyName(assembly, count, name, pNeeded) : HResults.E_NOTIMPL; int ISOSDacInterface.GetCCWData(ClrDataAddress ccw, void* data) @@ -242,7 +484,34 @@ int ISOSDacInterface.GetCodeHeapList(ClrDataAddress jitManager, uint count, void int ISOSDacInterface.GetDacModuleHandle(void* phModule) => _legacyImpl is not null ? _legacyImpl.GetDacModuleHandle(phModule) : HResults.E_NOTIMPL; int ISOSDacInterface.GetDomainFromContext(ClrDataAddress context, ClrDataAddress* domain) - => _legacyImpl is not null ? _legacyImpl.GetDomainFromContext(context, domain) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + if (context == 0 || domain == null) + { + return HResults.E_INVALIDARG; + } + try + { + *domain = context; + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacyImpl is not null) + { + ClrDataAddress domainLocal; + int hrLocal = _legacyImpl.GetDomainFromContext(context, &domainLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(domainLocal == context, $"cDAC: {context:x}, DAC: {domainLocal:x}"); + } + } +#endif + return hr; + } int ISOSDacInterface.GetDomainLocalModuleData(ClrDataAddress addr, void* data) { // CoreCLR does not use domain local modules anymore @@ -399,8 +668,75 @@ int ISOSDacInterface.GetJitHelperFunctionName(ClrDataAddress ip, uint count, byt => _legacyImpl is not null ? _legacyImpl.GetJitHelperFunctionName(ip, count, name, pNeeded) : HResults.E_NOTIMPL; int ISOSDacInterface.GetJitManagerList(uint count, void* managers, uint* pNeeded) => _legacyImpl is not null ? _legacyImpl.GetJitManagerList(count, managers, pNeeded) : HResults.E_NOTIMPL; + + private bool IsJumpRel64(TargetPointer pThunk) + => 0x48 == _target.Read(pThunk) && + 0xB8 == _target.Read(pThunk + 1) && + 0xFF == _target.Read(pThunk + 10) && + 0xE0 == _target.Read(pThunk + 11); + + private TargetPointer DecodeJump64(TargetPointer pThunk) + { + Debug.Assert(IsJumpRel64(pThunk), "Expected a jump thunk"); + + return _target.ReadPointer(pThunk + 2); + } int ISOSDacInterface.GetJumpThunkTarget(void* ctx, ClrDataAddress* targetIP, ClrDataAddress* targetMD) - => _legacyImpl is not null ? _legacyImpl.GetJumpThunkTarget(ctx, targetIP, targetMD) : HResults.E_NOTIMPL; + { + if (ctx == null || targetIP == null || targetMD == null) + { + return HResults.E_INVALIDARG; + } + + int hr = HResults.S_OK; + try + { + // API is implemented for x64 only + if (_target.Contracts.RuntimeInfo.GetTargetArchitecture() == RuntimeInfoArchitecture.X64) + { + IPlatformAgnosticContext context = IPlatformAgnosticContext.GetContextForPlatform(_target); + + // Context is not stored in the target, but in our own process + context.FillFromBuffer(new Span(ctx, (int)context.Size)); + TargetPointer pThunk = context.InstructionPointer; + + if (IsJumpRel64(pThunk)) + { + *targetMD = 0; + *targetIP = DecodeJump64(pThunk).ToClrDataAddress(_target); + } + else + { + hr = HResults.E_FAIL; + } + } + else + { + hr = HResults.E_FAIL; + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + +#if DEBUG + if (_legacyImpl is not null) + { + ClrDataAddress targetIPLocal; + ClrDataAddress targetMDLocal; + int hrLocal = _legacyImpl.GetJumpThunkTarget(ctx, &targetIPLocal, &targetMDLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(*targetIP == targetIPLocal, $"cDAC: {*targetIP:x}, DAC: {targetIPLocal:x}"); + Debug.Assert(*targetMD == targetMDLocal, $"cDAC: {*targetMD:x}, DAC: {targetMDLocal:x}"); + } + } +#endif + + return hr; + } int ISOSDacInterface.GetMethodDescData(ClrDataAddress addr, ClrDataAddress ip, DacpMethodDescData* data, uint cRevertedRejitVersions, DacpReJitData* rgRevertedRejitData, uint* pcNeededRevertedRejitData) { if (addr == 0) @@ -743,7 +1079,7 @@ int ISOSDacInterface.GetMethodDescName(ClrDataAddress addr, uint count, char* na else { TargetPointer modulePtr = rtsContract.GetModule(rtsContract.GetTypeHandle(rtsContract.GetMethodTable(methodDescHandle))); - Contracts.ModuleHandle module = _target.Contracts.Loader.GetModuleHandle(modulePtr); + Contracts.ModuleHandle module = _target.Contracts.Loader.GetModuleHandleFromModulePtr(modulePtr); string modulePath = _target.Contracts.Loader.GetPath(module); ReadOnlySpan moduleSpan = modulePath.AsSpan(); char directorySeparator = (char)_target.ReadGlobal(Constants.Globals.DirectorySeparator); @@ -925,8 +1261,52 @@ int ISOSDacInterface.GetMethodTableData(ClrDataAddress mt, DacpMethodTableData* #endif return hr; } - int ISOSDacInterface.GetMethodTableFieldData(ClrDataAddress mt, void* data) - => _legacyImpl is not null ? _legacyImpl.GetMethodTableFieldData(mt, data) : HResults.E_NOTIMPL; + int ISOSDacInterface.GetMethodTableFieldData(ClrDataAddress mt, DacpMethodTableFieldData* data) + { + int hr = HResults.S_OK; + try + { + if (mt == 0 || data == null) + { + hr = HResults.E_INVALIDARG; + } + else + { + TargetPointer mtAddress = mt.ToTargetPointer(_target); + Contracts.IRuntimeTypeSystem rtsContract = _target.Contracts.RuntimeTypeSystem; + TypeHandle typeHandle = rtsContract.GetTypeHandle(mtAddress); + data->FirstField = rtsContract.GetFieldDescList(typeHandle).ToClrDataAddress(_target); + data->wNumInstanceFields = rtsContract.GetNumInstanceFields(typeHandle); + data->wNumStaticFields = rtsContract.GetNumStaticFields(typeHandle); + data->wNumThreadStaticFields = rtsContract.GetNumThreadStaticFields(typeHandle); + data->wContextStaticsSize = 0; + data->wContextStaticOffset = 0; + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + { + if (_legacyImpl is not null) + { + DacpMethodTableFieldData mtFieldDataLocal = default; + int hrLocal = _legacyImpl.GetMethodTableFieldData(mt, &mtFieldDataLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(data->wNumInstanceFields == mtFieldDataLocal.wNumInstanceFields); + Debug.Assert(data->wNumStaticFields == mtFieldDataLocal.wNumStaticFields); + Debug.Assert(data->wNumThreadStaticFields == mtFieldDataLocal.wNumThreadStaticFields); + Debug.Assert(data->wContextStaticOffset == mtFieldDataLocal.wContextStaticOffset); + Debug.Assert(data->wContextStaticsSize == mtFieldDataLocal.wContextStaticsSize); + } + } + } +#endif + return hr; + } int ISOSDacInterface.GetMethodTableForEEClass(ClrDataAddress eeClassReallyCanonMT, ClrDataAddress* value) { if (eeClassReallyCanonMT == 0 || value == null) @@ -1052,7 +1432,7 @@ int ISOSDacInterface.GetModuleData(ClrDataAddress moduleAddr, DacpModuleData* da try { Contracts.ILoader contract = _target.Contracts.Loader; - Contracts.ModuleHandle handle = contract.GetModuleHandle(moduleAddr.ToTargetPointer(_target)); + Contracts.ModuleHandle handle = contract.GetModuleHandleFromModulePtr(moduleAddr.ToTargetPointer(_target)); data->Address = moduleAddr; data->PEAssembly = moduleAddr; // Module address in .NET 9+ - correspondingly, SOS-DAC APIs for PE assemblies expect a module address @@ -1342,7 +1722,7 @@ int ISOSDacInterface.GetPEFileBase(ClrDataAddress addr, ClrDataAddress* peBase) try { Contracts.ILoader contract = _target.Contracts.Loader; - Contracts.ModuleHandle handle = contract.GetModuleHandle(addr.ToTargetPointer(_target)); + Contracts.ModuleHandle handle = contract.GetModuleHandleFromModulePtr(addr.ToTargetPointer(_target)); Contracts.ModuleFlags flags = contract.GetFlags(handle); if (!flags.HasFlag(Contracts.ModuleFlags.ReflectionEmit)) @@ -1381,7 +1761,7 @@ int ISOSDacInterface.GetPEFileName(ClrDataAddress addr, uint count, char* fileNa try { Contracts.ILoader contract = _target.Contracts.Loader; - Contracts.ModuleHandle handle = contract.GetModuleHandle(addr.ToTargetPointer(_target)); + Contracts.ModuleHandle handle = contract.GetModuleHandleFromModulePtr(addr.ToTargetPointer(_target)); string path = contract.GetPath(handle); // Return not implemented for empty paths for non-reflection emit assemblies (for example, loaded from memory) @@ -1535,7 +1915,33 @@ int ISOSDacInterface.GetThreadData(ClrDataAddress thread, DacpThreadData* data) return hr; } int ISOSDacInterface.GetThreadFromThinlockID(uint thinLockId, ClrDataAddress* pThread) - => _legacyImpl is not null ? _legacyImpl.GetThreadFromThinlockID(thinLockId, pThread) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + if (pThread == null) + hr = HResults.E_INVALIDARG; + try + { + TargetPointer threadPtr = _target.Contracts.Thread.IdToThread(thinLockId); + *pThread = threadPtr.ToClrDataAddress(_target); + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacyImpl is not null) + { + ClrDataAddress pThreadLocal; + int hrLocal = _legacyImpl.GetThreadFromThinlockID(thinLockId, &pThreadLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(*pThread == pThreadLocal); + } + } +#endif + return hr; + } int ISOSDacInterface.GetThreadLocalModuleData(ClrDataAddress thread, uint index, void* data) { // CoreCLR does not use thread local modules anymore @@ -1620,8 +2026,36 @@ int ISOSDacInterface.GetThreadStoreData(DacpThreadStoreData* data) } int ISOSDacInterface.GetTLSIndex(uint* pIndex) - => _legacyImpl is not null ? _legacyImpl.GetTLSIndex(pIndex) : HResults.E_NOTIMPL; + { + if (pIndex == null) + return HResults.E_INVALIDARG; + int hr = HResults.S_OK; + try + { + uint TlsIndexBase = _target.Read(_target.ReadGlobalPointer(Constants.Globals.TlsIndexBase)); + uint OffsetOfCurrentThreadInfo = _target.Read(_target.ReadGlobalPointer(Constants.Globals.OffsetOfCurrentThreadInfo)); + uint CombinedTlsIndex = TlsIndexBase + (OffsetOfCurrentThreadInfo << 16) + 0x80000000; + *pIndex = CombinedTlsIndex; + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacyImpl is not null) + { + uint indexLocal; + int hrLocal = _legacyImpl.GetTLSIndex(&indexLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK || hr == HResults.S_FALSE) + { + Debug.Assert(*pIndex == indexLocal); + } + } +#endif + return hr; + } int ISOSDacInterface.GetUsefulGlobals(DacpUsefulGlobalsData* data) { if (data == null) @@ -1750,7 +2184,48 @@ int ISOSDacInterface3.GetGCGlobalMechanisms(nuint* globalMechanisms) #region ISOSDacInterface4 int ISOSDacInterface4.GetClrNotification(ClrDataAddress[] arguments, int count, int* pNeeded) - => _legacyImpl4 is not null ? _legacyImpl4.GetClrNotification(arguments, count, pNeeded) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + uint MaxClrNotificationArgs = _target.ReadGlobal(Constants.Globals.MaxClrNotificationArgs); + try + { + *pNeeded = (int)MaxClrNotificationArgs; + TargetPointer basePtr = _target.ReadGlobalPointer(Constants.Globals.ClrNotificationArguments); + if (_target.ReadNUInt(basePtr).Value == 0) + { + hr = HResults.E_FAIL; + } + else + { + for (int i = 0; i < count && i < MaxClrNotificationArgs; i++) + { + arguments[i] = _target.ReadNUInt(basePtr.Value + (ulong)(i * _target.PointerSize)).Value; + } + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacyImpl4 is not null) + { + ClrDataAddress[] argumentsLocal = new ClrDataAddress[count]; + int neededLocal; + int hrLocal = _legacyImpl4.GetClrNotification(argumentsLocal, count, &neededLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(*pNeeded == neededLocal); + for (int i = 0; i < count && i < MaxClrNotificationArgs; i++) + { + Debug.Assert(arguments[i] == argumentsLocal[i]); + } + } + } +#endif + return hr; + } #endregion ISOSDacInterface4 #region ISOSDacInterface5 @@ -1765,7 +2240,46 @@ int ISOSDacInterface6.GetMethodTableCollectibleData(ClrDataAddress mt, /*struct #region ISOSDacInterface7 int ISOSDacInterface7.GetPendingReJITID(ClrDataAddress methodDesc, int* pRejitId) - => _legacyImpl7 is not null ? _legacyImpl7.GetPendingReJITID(methodDesc, pRejitId) : HResults.E_NOTIMPL; + { + if (methodDesc == 0 || pRejitId == null) + return HResults.E_INVALIDARG; + + int hr = HResults.S_OK; + try + { + Contracts.IReJIT rejitContract = _target.Contracts.ReJIT; + Contracts.ICodeVersions codeVersionsContract = _target.Contracts.CodeVersions; + TargetPointer methodDescPtr = methodDesc.ToTargetPointer(_target); + Contracts.ILCodeVersionHandle activeILCodeVersion = codeVersionsContract.GetActiveILCodeVersion(methodDescPtr); + + if (rejitContract.GetRejitState(activeILCodeVersion) == Contracts.RejitState.Requested) + { + *pRejitId = (int)rejitContract.GetRejitId(activeILCodeVersion).Value; + } + else + { + hr = HResults.S_FALSE; + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacyImpl7 is not null) + { + int rejitIdLocal; + int hrLocal = _legacyImpl7.GetPendingReJITID(methodDesc, &rejitIdLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(*pRejitId == rejitIdLocal); + } + } + +#endif + return hr; + } int ISOSDacInterface7.GetReJITInformation(ClrDataAddress methodDesc, int rejitId, /*struct DacpReJitData2*/ void* pRejitData) => _legacyImpl7 is not null ? _legacyImpl7.GetReJITInformation(methodDesc, rejitId, pRejitData) : HResults.E_NOTIMPL; int ISOSDacInterface7.GetProfilerModifiedILInformation(ClrDataAddress methodDesc, /*struct DacpProfilerILData*/ void* pILData) @@ -1791,7 +2305,40 @@ int ISOSDacInterface8.GetFinalizationFillPointersSvr(ClrDataAddress heapAddr, ui => _legacyImpl8 is not null ? _legacyImpl8.GetFinalizationFillPointersSvr(heapAddr, cFillPointers, pFinalizationFillPointers, pNeeded) : HResults.E_NOTIMPL; int ISOSDacInterface8.GetAssemblyLoadContext(ClrDataAddress methodTable, ClrDataAddress* assemblyLoadContext) - => _legacyImpl8 is not null ? _legacyImpl8.GetAssemblyLoadContext(methodTable, assemblyLoadContext) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + try + { + if (methodTable == 0 || assemblyLoadContext == null) + hr = HResults.E_INVALIDARG; + else + { + Contracts.IRuntimeTypeSystem rtsContract = _target.Contracts.RuntimeTypeSystem; + Contracts.ILoader loaderContract = _target.Contracts.Loader; + Contracts.TypeHandle methodTableHandle = rtsContract.GetTypeHandle(methodTable.ToTargetPointer(_target)); + Contracts.ModuleHandle moduleHandle = loaderContract.GetModuleHandleFromModulePtr(rtsContract.GetModule(methodTableHandle)); + TargetPointer alc = loaderContract.GetAssemblyLoadContext(moduleHandle); + *assemblyLoadContext = alc.ToClrDataAddress(_target); + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacyImpl8 is not null) + { + ClrDataAddress assemblyLoadContextLocal; + int hrLocal = _legacyImpl8.GetAssemblyLoadContext(methodTable, &assemblyLoadContextLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(*assemblyLoadContext == assemblyLoadContextLocal); + } + } +#endif + return hr; + } #endregion ISOSDacInterface8 #region ISOSDacInterface9 @@ -1855,11 +2402,143 @@ int ISOSDacInterface13.LockedFlush() #region ISOSDacInterface14 int ISOSDacInterface14.GetStaticBaseAddress(ClrDataAddress methodTable, ClrDataAddress* nonGCStaticsAddress, ClrDataAddress* GCStaticsAddress) - => _legacyImpl14 is not null ? _legacyImpl14.GetStaticBaseAddress(methodTable, nonGCStaticsAddress, GCStaticsAddress) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + if (nonGCStaticsAddress == null && GCStaticsAddress == null) + hr = HResults.E_POINTER; + else if (methodTable == 0) + hr = HResults.E_INVALIDARG; + else + { + try + { + Contracts.IRuntimeTypeSystem rtsContract = _target.Contracts.RuntimeTypeSystem; + Contracts.TypeHandle typeHandle = rtsContract.GetTypeHandle(methodTable.ToTargetPointer(_target)); + if (GCStaticsAddress != null) + *GCStaticsAddress = rtsContract.GetGCStaticsBasePointer(typeHandle).ToClrDataAddress(_target); + if (nonGCStaticsAddress != null) + *nonGCStaticsAddress = rtsContract.GetNonGCStaticsBasePointer(typeHandle).ToClrDataAddress(_target); + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + } +#if DEBUG + if (_legacyImpl14 is not null) + { + ClrDataAddress nonGCStaticsAddressLocal; + ClrDataAddress GCStaticsAddressLocal; + int hrLocal = _legacyImpl14.GetStaticBaseAddress(methodTable, &nonGCStaticsAddressLocal, &GCStaticsAddressLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + if (GCStaticsAddress != null) + Debug.Assert(*GCStaticsAddress == GCStaticsAddressLocal); + if (nonGCStaticsAddress != null) + Debug.Assert(*nonGCStaticsAddress == nonGCStaticsAddressLocal); + } + } +#endif + return hr; + } int ISOSDacInterface14.GetThreadStaticBaseAddress(ClrDataAddress methodTable, ClrDataAddress thread, ClrDataAddress* nonGCStaticsAddress, ClrDataAddress* GCStaticsAddress) - => _legacyImpl14 is not null ? _legacyImpl14.GetThreadStaticBaseAddress(methodTable, thread, nonGCStaticsAddress, GCStaticsAddress) : HResults.E_NOTIMPL; - int ISOSDacInterface14.GetMethodTableInitializationFlags(ClrDataAddress methodTable, /*MethodTableInitializationFlags*/ int* initializationStatus) - => _legacyImpl14 is not null ? _legacyImpl14.GetMethodTableInitializationFlags(methodTable, initializationStatus) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + if (nonGCStaticsAddress == null && GCStaticsAddress == null) + hr = HResults.E_POINTER; + else if (methodTable == 0 || thread == 0) + hr = HResults.E_INVALIDARG; + else + { + try + { + Contracts.IRuntimeTypeSystem rtsContract = _target.Contracts.RuntimeTypeSystem; + TargetPointer methodTablePtr = methodTable.ToTargetPointer(_target); + TargetPointer threadPtr = thread.ToTargetPointer(_target); + Contracts.TypeHandle typeHandle = rtsContract.GetTypeHandle(methodTablePtr); + ushort numThreadStaticFields = rtsContract.GetNumThreadStaticFields(typeHandle); + if (numThreadStaticFields == 0) + { + if (GCStaticsAddress != null) + *GCStaticsAddress = 0; + if (nonGCStaticsAddress != null) + *nonGCStaticsAddress = 0; + } + else + { + if (GCStaticsAddress != null) + *GCStaticsAddress = rtsContract.GetGCThreadStaticsBasePointer(typeHandle, threadPtr).ToClrDataAddress(_target); + if (nonGCStaticsAddress != null) + *nonGCStaticsAddress = rtsContract.GetNonGCThreadStaticsBasePointer(typeHandle, threadPtr).ToClrDataAddress(_target); + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + } +#if DEBUG + if (_legacyImpl14 is not null) + { + ClrDataAddress nonGCStaticsAddressLocal = default; + ClrDataAddress GCStaticsAddressLocal = default; + ClrDataAddress* nonGCStaticsAddressOrNull = nonGCStaticsAddress != null ? &nonGCStaticsAddressLocal : null; + ClrDataAddress* gcStaticsAddressOrNull = GCStaticsAddress != null ? &GCStaticsAddressLocal : null; + int hrLocal = _legacyImpl14.GetThreadStaticBaseAddress(methodTable, thread, nonGCStaticsAddressOrNull, gcStaticsAddressOrNull); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + if (nonGCStaticsAddress != null) + Debug.Assert(*nonGCStaticsAddress == nonGCStaticsAddressLocal); + if (GCStaticsAddress != null) + Debug.Assert(*GCStaticsAddress == GCStaticsAddressLocal); + } + } +#endif + return hr; + } + + int ISOSDacInterface14.GetMethodTableInitializationFlags(ClrDataAddress methodTable, MethodTableInitializationFlags* initializationStatus) + { + int hr = HResults.S_OK; + if (methodTable == 0) + hr = HResults.E_INVALIDARG; + else if (initializationStatus == null) + hr = HResults.E_POINTER; + + else + { + try + { + Contracts.IRuntimeTypeSystem rtsContract = _target.Contracts.RuntimeTypeSystem; + Contracts.TypeHandle methodTableHandle = rtsContract.GetTypeHandle(methodTable.ToTargetPointer(_target)); + *initializationStatus = (MethodTableInitializationFlags)0; + if (rtsContract.IsClassInited(methodTableHandle)) + *initializationStatus = MethodTableInitializationFlags.MethodTableInitialized; + if (rtsContract.IsInitError(methodTableHandle)) + *initializationStatus |= MethodTableInitializationFlags.MethodTableInitializationFailed; + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + } +#if DEBUG + if (_legacyImpl14 is not null) + { + MethodTableInitializationFlags initializationStatusLocal; + int hrLocal = _legacyImpl14.GetMethodTableInitializationFlags(methodTable, &initializationStatusLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK) + { + Debug.Assert(*initializationStatus == initializationStatusLocal); + } + } +#endif + return hr; + } + #endregion ISOSDacInterface14 #region ISOSDacInterface15 diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/SigFormat.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/SigFormat.cs index 69246f6b1e85f0..98ac68d98d0dde 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SigFormat.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SigFormat.cs @@ -179,7 +179,7 @@ private static unsafe void AddTypeString(Target target, uint typeDefToken = runtimeTypeSystem.GetTypeDefToken(th); TargetPointer modulePointer = target.Contracts.RuntimeTypeSystem.GetModule(th); - Contracts.ModuleHandle module = target.Contracts.Loader.GetModuleHandle(modulePointer); + Contracts.ModuleHandle module = target.Contracts.Loader.GetModuleHandleFromModulePtr(modulePointer); MetadataReader internalTypeMetadata = target.Contracts.EcmaMetadata.GetMetadata(module)!; TypeDefinition internalTypeDef = internalTypeMetadata.GetTypeDefinition((TypeDefinitionHandle)MetadataTokens.Handle((int)typeDefToken)); @@ -345,7 +345,7 @@ private static void AddType(Target target, StringBuilder stringBuilder, TypeHand case CorElementType.Class: uint typeDefToken = runtimeTypeSystem.GetTypeDefToken(typeHandle); TargetPointer modulePointer = target.Contracts.RuntimeTypeSystem.GetModule(typeHandle); - Contracts.ModuleHandle module = target.Contracts.Loader.GetModuleHandle(modulePointer); + Contracts.ModuleHandle module = target.Contracts.Loader.GetModuleHandleFromModulePtr(modulePointer); MetadataReader metadata = target.Contracts.EcmaMetadata.GetMetadata(module)!; TypeDefinition typeDef = metadata.GetTypeDefinition((TypeDefinitionHandle)MetadataTokens.Handle((int)typeDefToken)); string _namespace = metadata.GetString(typeDef.Namespace); @@ -390,7 +390,7 @@ private static void AddType(Target target, StringBuilder stringBuilder, TypeHand case CorElementType.MVar: case CorElementType.Var: runtimeTypeSystem.IsGenericVariable(typeHandle, out TargetPointer genericVariableModulePointer, out uint typeVarToken); - Contracts.ModuleHandle genericVariableModule = target.Contracts.Loader.GetModuleHandle(genericVariableModulePointer); + Contracts.ModuleHandle genericVariableModule = target.Contracts.Loader.GetModuleHandleFromModulePtr(genericVariableModulePointer); MetadataReader generatedVariableMetadata = target.Contracts.EcmaMetadata.GetMetadata(genericVariableModule)!; GenericParameter genericVariable = generatedVariableMetadata.GetGenericParameter((GenericParameterHandle)MetadataTokens.Handle((int)typeVarToken)); stringBuilder.Append(generatedVariableMetadata.GetString(genericVariable.Name)); diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/TypeNameBuilder.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/TypeNameBuilder.cs index 1688f34db24d15..d05f14803d5baa 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/TypeNameBuilder.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/TypeNameBuilder.cs @@ -119,7 +119,7 @@ public static void AppendMethodImpl(Target target, StringBuilder stringBuilder, } else { - module = loader.GetModuleHandle(runtimeTypeSystem.GetModule(th)); + module = loader.GetModuleHandleFromModulePtr(runtimeTypeSystem.GetModule(th)); MetadataReader reader = target.Contracts.EcmaMetadata.GetMetadata(module)!; MethodDefinition methodDef = reader.GetMethodDefinition(MetadataTokens.MethodDefinitionHandle((int)runtimeTypeSystem.GetMethodToken(method))); stringBuilder.Append(reader.GetString(methodDef.Name)); @@ -226,7 +226,7 @@ private static void AppendTypeCore(ref TypeNameBuilder tnb, Contracts.TypeHandle } else if (typeSystemContract.IsGenericVariable(typeHandle, out TargetPointer modulePointer, out uint genericParamToken)) { - Contracts.ModuleHandle module = tnb.Target.Contracts.Loader.GetModuleHandle(modulePointer); + Contracts.ModuleHandle module = tnb.Target.Contracts.Loader.GetModuleHandleFromModulePtr(modulePointer); MetadataReader reader = tnb.Target.Contracts.EcmaMetadata.GetMetadata(module)!; var handle = (GenericParameterHandle)MetadataTokens.Handle((int)genericParamToken); GenericParameter genericParam = reader.GetGenericParameter(handle); @@ -280,7 +280,7 @@ private static void AppendTypeCore(ref TypeNameBuilder tnb, Contracts.TypeHandle { // ...otherwise it's just a plain type def or an instantiated type uint typeDefToken = typeSystemContract.GetTypeDefToken(typeHandle); - Contracts.ModuleHandle moduleHandle = tnb.Target.Contracts.Loader.GetModuleHandle(typeSystemContract.GetModule(typeHandle)); + Contracts.ModuleHandle moduleHandle = tnb.Target.Contracts.Loader.GetModuleHandleFromModulePtr(typeSystemContract.GetModule(typeHandle)); if (MetadataTokens.EntityHandle((int)typeDefToken).IsNil) { tnb.AddName("(dynamicClass)"); @@ -311,7 +311,7 @@ private static void AppendTypeCore(ref TypeNameBuilder tnb, Contracts.TypeHandle { TargetPointer modulePtr = typeSystemContract.GetModule(typeHandle); - Contracts.ModuleHandle module = tnb.Target.Contracts.Loader.GetModuleHandle(modulePtr); + Contracts.ModuleHandle module = tnb.Target.Contracts.Loader.GetModuleHandleFromModulePtr(modulePtr); // NOTE: The DAC variant of assembly name generation is different than the runtime version. The DAC variant is simpler, and only uses SimpleName MetadataReader mr = tnb.Target.Contracts.EcmaMetadata.GetMetadata(module)!; diff --git a/src/native/managed/cdac/mscordaccore_universal/mscordaccore_universal.csproj b/src/native/managed/cdac/mscordaccore_universal/mscordaccore_universal.csproj index 23e689d16d9aa5..a9c40757f98657 100644 --- a/src/native/managed/cdac/mscordaccore_universal/mscordaccore_universal.csproj +++ b/src/native/managed/cdac/mscordaccore_universal/mscordaccore_universal.csproj @@ -31,18 +31,6 @@ - - - - - - - - - - - - diff --git a/src/native/managed/cdac/tests/CodeVersionsTests.cs b/src/native/managed/cdac/tests/CodeVersionsTests.cs index 570fa878270746..7ceaeea2433ef4 100644 --- a/src/native/managed/cdac/tests/CodeVersionsTests.cs +++ b/src/native/managed/cdac/tests/CodeVersionsTests.cs @@ -85,7 +85,7 @@ public static void AddCodeBlock(this Mock mock, MockCodeBlock public static void AddModule(this Mock mock, MockModule module) { Contracts.ModuleHandle handle = new Contracts.ModuleHandle(module.Address); - mock.Setup(l => l.GetModuleHandle(module.Address)).Returns(handle); + mock.Setup(l => l.GetModuleHandleFromModulePtr(module.Address)).Returns(handle); mock.Setup(l => l.GetLookupTables(handle)).Returns(new ModuleLookupTables() { MethodDefToILCodeVersioningState = module.MethodDefToILCodeVersioningStateAddress, }); @@ -145,7 +145,7 @@ internal Target CreateTarget( TestPlaceholderTarget target = new TestPlaceholderTarget( arch, - builder.Builder.GetReadContext().ReadFromTarget, + builder.Builder.GetMemoryContext().ReadFromTarget, builder.Types); IContractFactory cvfactory = new CodeVersionsFactory(); diff --git a/src/native/managed/cdac/tests/ContractDescriptor/ContractDescriptorBuilder.cs b/src/native/managed/cdac/tests/ContractDescriptor/ContractDescriptorBuilder.cs index 3b5d4de5972e96..cd15f10f0bebf6 100644 --- a/src/native/managed/cdac/tests/ContractDescriptor/ContractDescriptorBuilder.cs +++ b/src/native/managed/cdac/tests/ContractDescriptor/ContractDescriptorBuilder.cs @@ -178,7 +178,7 @@ public bool TryCreateTarget([NotNullWhen(true)] out ContractDescriptorTarget? ta if (_created) throw new InvalidOperationException("Context already created"); ulong contractDescriptorAddress = CreateDescriptorFragments(); - MockMemorySpace.ReadContext context = GetReadContext(); - return ContractDescriptorTarget.TryCreate(contractDescriptorAddress, context.ReadFromTarget, null, out target); + MockMemorySpace.MemoryContext memoryContext = GetMemoryContext(); + return ContractDescriptorTarget.TryCreate(contractDescriptorAddress, memoryContext.ReadFromTarget, memoryContext.WriteToTarget, null, out target); } } diff --git a/src/native/managed/cdac/tests/ContractDescriptor/TargetTests.cs b/src/native/managed/cdac/tests/ContractDescriptor/TargetTests.cs index 6ba88e9246e6e3..516c0d3237df49 100644 --- a/src/native/managed/cdac/tests/ContractDescriptor/TargetTests.cs +++ b/src/native/managed/cdac/tests/ContractDescriptor/TargetTests.cs @@ -183,6 +183,44 @@ public void ReadUtf8String(MockTarget.Architecture arch) Assert.Equal(expected, actual); } + [Theory] + [ClassData(typeof(MockTarget.StdArch))] + public void WriteValue(MockTarget.Architecture arch) + { + TargetTestHelpers targetTestHelpers = new(arch); + ContractDescriptorBuilder builder = new(targetTestHelpers); + uint expected = 0xdeadbeef; + ulong addr = 0x1000; + + MockMemorySpace.HeapFragment fragment = new() { Address = addr, Data = new byte[4] }; + builder.AddHeapFragment(fragment); + + bool success = builder.TryCreateTarget(out ContractDescriptorTarget? target); + Assert.True(success); + target.Write(addr, expected); + Assert.Equal(expected, target.Read(addr)); + } + + [Theory] + [ClassData(typeof(MockTarget.StdArch))] + public void WriteBuffer(MockTarget.Architecture arch) + { + TargetTestHelpers targetTestHelpers = new(arch); + ContractDescriptorBuilder builder = new(targetTestHelpers); + byte[] expected = new byte[] { 0xde, 0xad, 0xbe, 0xef }; + ulong addr = 0x1000; + + MockMemorySpace.HeapFragment fragment = new() { Address = addr, Data = new byte[4] }; + builder.AddHeapFragment(fragment); + + bool success = builder.TryCreateTarget(out ContractDescriptorTarget? target); + Assert.True(success); + target.WriteBuffer(addr, expected); + Span data = stackalloc byte[4]; + target.ReadBuffer(addr, data); + Assert.Equal(expected, data); + } + [Theory] [ClassData(typeof(MockTarget.StdArch))] public void ReadUtf16String(MockTarget.Architecture arch) diff --git a/src/native/managed/cdac/tests/DacStreamsTests.cs b/src/native/managed/cdac/tests/DacStreamsTests.cs index 01ea202342b467..c104a33bca325b 100644 --- a/src/native/managed/cdac/tests/DacStreamsTests.cs +++ b/src/native/managed/cdac/tests/DacStreamsTests.cs @@ -42,7 +42,7 @@ private static unsafe void DacStreamsContractHelper(MockTarget.Architecture arch builder = configure(builder); } - var target = new TestPlaceholderTarget(arch, builder.GetReadContext().ReadFromTarget, DacStreamsTypes, DacStreamsGlobals); + var target = new TestPlaceholderTarget(arch, builder.GetMemoryContext().ReadFromTarget, DacStreamsTypes, DacStreamsGlobals); target.SetContracts(Mock.Of( c => c.DacStreams == ((IContractFactory)new DacStreamsFactory()).CreateContract(target, 1))); diff --git a/src/native/managed/cdac/tests/ExecutionManager/ExecutionManagerTests.cs b/src/native/managed/cdac/tests/ExecutionManager/ExecutionManagerTests.cs index c64b8af35ea783..b4c858f5a6e573 100644 --- a/src/native/managed/cdac/tests/ExecutionManager/ExecutionManagerTests.cs +++ b/src/native/managed/cdac/tests/ExecutionManager/ExecutionManagerTests.cs @@ -14,7 +14,7 @@ public class ExecutionManagerTests private static Target CreateTarget(MockDescriptors.ExecutionManager emBuilder) { var arch = emBuilder.Builder.TargetTestHelpers.Arch; - TestPlaceholderTarget.ReadFromTargetDelegate reader = emBuilder.Builder.GetReadContext().ReadFromTarget; + TestPlaceholderTarget.ReadFromTargetDelegate reader = emBuilder.Builder.GetMemoryContext().ReadFromTarget; var target = new TestPlaceholderTarget(arch, reader, emBuilder.Types, emBuilder.Globals); IContractFactory emfactory = new ExecutionManagerFactory(); ContractRegistry reg = Mock.Of( diff --git a/src/native/managed/cdac/tests/ExecutionManager/HashMapTests.cs b/src/native/managed/cdac/tests/ExecutionManager/HashMapTests.cs index 5241913a11ee78..64818b01d7ae93 100644 --- a/src/native/managed/cdac/tests/ExecutionManager/HashMapTests.cs +++ b/src/native/managed/cdac/tests/ExecutionManager/HashMapTests.cs @@ -25,7 +25,7 @@ public void GetValue(MockTarget.Architecture arch) TargetPointer mapAddress = hashMap.CreateMap(entries); TargetPointer ptrMapAddress = hashMap.CreatePtrMap(entries); - Target target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetReadContext().ReadFromTarget, hashMap.Types, hashMap.Globals); + Target target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetMemoryContext().ReadFromTarget, hashMap.Types, hashMap.Globals); var lookup = HashMapLookup.Create(target); var ptrLookup = PtrHashMapLookup.Create(target); @@ -61,7 +61,7 @@ public void GetValue_Collision(MockTarget.Architecture arch) TargetPointer mapAddress = hashMap.CreateMap(entries); TargetPointer ptrMapAddress = hashMap.CreatePtrMap(entries); - Target target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetReadContext().ReadFromTarget, hashMap.Types, hashMap.Globals); + Target target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetMemoryContext().ReadFromTarget, hashMap.Types, hashMap.Globals); var lookup = HashMapLookup.Create(target); var ptrLookup = PtrHashMapLookup.Create(target); @@ -86,7 +86,7 @@ public void GetValue_NoMatch(MockTarget.Architecture arch) TargetPointer mapAddress = hashMap.CreateMap(entries); TargetPointer ptrMapAddress = hashMap.CreatePtrMap(entries); - Target target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetReadContext().ReadFromTarget, hashMap.Types, hashMap.Globals); + Target target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetMemoryContext().ReadFromTarget, hashMap.Types, hashMap.Globals); { var lookup = HashMapLookup.Create(target); diff --git a/src/native/managed/cdac/tests/ExecutionManager/NibbleMapTests.cs b/src/native/managed/cdac/tests/ExecutionManager/NibbleMapTests.cs index 44c2d879127b08..91205f830cddae 100644 --- a/src/native/managed/cdac/tests/ExecutionManager/NibbleMapTests.cs +++ b/src/native/managed/cdac/tests/ExecutionManager/NibbleMapTests.cs @@ -11,11 +11,11 @@ public class NibbleMapTestsBase { internal static Target CreateTarget(NibbleMapTestBuilderBase nibbleMapTestBuilder) { - MockMemorySpace.ReadContext readContext = new() + MockMemorySpace.MemoryContext memoryContext = new() { HeapFragments = new[] { nibbleMapTestBuilder.NibbleMapFragment } }; - return new TestPlaceholderTarget(nibbleMapTestBuilder.Arch, readContext.ReadFromTarget); + return new TestPlaceholderTarget(nibbleMapTestBuilder.Arch, memoryContext.ReadFromTarget); } } diff --git a/src/native/managed/cdac/tests/ExecutionManager/RangeSectionMapTests.cs b/src/native/managed/cdac/tests/ExecutionManager/RangeSectionMapTests.cs index c98267e76ded0c..5e06e1e86a9ab1 100644 --- a/src/native/managed/cdac/tests/ExecutionManager/RangeSectionMapTests.cs +++ b/src/native/managed/cdac/tests/ExecutionManager/RangeSectionMapTests.cs @@ -15,7 +15,7 @@ public class RangeSectionMapTests public void TestLookupFail(MockTarget.Architecture arch) { var builder = MockDescriptors.ExecutionManager.CreateRangeSection(arch); - var target = new TestPlaceholderTarget(arch, builder.GetReadContext().ReadFromTarget); + var target = new TestPlaceholderTarget(arch, builder.GetMemoryContext().ReadFromTarget); var rsla = RangeSectionMap.Create(target); @@ -33,7 +33,7 @@ public void TestLookupOne(MockTarget.Architecture arch) var length = 0x1000u; var value = 0x0a0a_0a0au; builder.InsertAddressRange(inputPC, length, value); - var target = new TestPlaceholderTarget(arch, builder.GetReadContext().ReadFromTarget); + var target = new TestPlaceholderTarget(arch, builder.GetMemoryContext().ReadFromTarget); var rsla = RangeSectionMap.Create(target); @@ -48,7 +48,7 @@ public void TestLookupOne(MockTarget.Architecture arch) public void TestGetIndexForLevel(MockTarget.Architecture arch) { // Exhaustively test GetIndexForLevel for all possible values of the byte for each level - var target = new TestPlaceholderTarget(arch, new MockMemorySpace.ReadContext().ReadFromTarget); + var target = new TestPlaceholderTarget(arch, new MockMemorySpace.MemoryContext().ReadFromTarget); var rsla = RangeSectionMap.Create(target); int numLevels = arch.Is64Bit ? 5 : 2; // the bits 0..effectiveRange - 1 are not handled the map and are irrelevant diff --git a/src/native/managed/cdac/tests/ExecutionManager/RuntimeFunctionTests.cs b/src/native/managed/cdac/tests/ExecutionManager/RuntimeFunctionTests.cs index fe256024de09af..9279a5e177ed2e 100644 --- a/src/native/managed/cdac/tests/ExecutionManager/RuntimeFunctionTests.cs +++ b/src/native/managed/cdac/tests/ExecutionManager/RuntimeFunctionTests.cs @@ -34,7 +34,7 @@ public void GetFunctionLength(MockTarget.Architecture arch, bool includeEndAddre uint[] entries = [0x100, 0x1f0, 0x1000, 0x2000, 0xa000]; TargetPointer addr = runtimeFunctions.AddRuntimeFunctions(entries); - Target target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetReadContext().ReadFromTarget, runtimeFunctions.Types); + Target target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetMemoryContext().ReadFromTarget, runtimeFunctions.Types); RuntimeFunctionLookup lookup = RuntimeFunctionLookup.Create(target); for (uint i = 0; i < entries.Length; i++) @@ -59,7 +59,7 @@ public void TryGetRuntimeFunctionIndexForAddress(MockTarget.Architecture arch) uint[] entries = [0x100, 0x1f0, 0x1000, 0x2000, 0xa000]; TargetPointer addr = runtimeFunctions.AddRuntimeFunctions(entries); - TestPlaceholderTarget target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetReadContext().ReadFromTarget, runtimeFunctions.Types); + TestPlaceholderTarget target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetMemoryContext().ReadFromTarget, runtimeFunctions.Types); ContractRegistry reg = Mock.Of( c => c.PlatformMetadata == new Mock().Object); target.SetContracts(reg); @@ -84,7 +84,7 @@ public void TryGetRuntimeFunctionIndexForAddress_NoMatch(MockTarget.Architecture uint[] entries = [0x100, 0x1f0]; TargetPointer addr = runtimeFunctions.AddRuntimeFunctions(entries); - TestPlaceholderTarget target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetReadContext().ReadFromTarget, runtimeFunctions.Types); + TestPlaceholderTarget target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetMemoryContext().ReadFromTarget, runtimeFunctions.Types); ContractRegistry reg = Mock.Of( c => c.PlatformMetadata == new Mock().Object); target.SetContracts(reg); diff --git a/src/native/managed/cdac/tests/LoaderTests.cs b/src/native/managed/cdac/tests/LoaderTests.cs index 2e13e784dccf8f..0cbb93e9481c77 100644 --- a/src/native/managed/cdac/tests/LoaderTests.cs +++ b/src/native/managed/cdac/tests/LoaderTests.cs @@ -28,7 +28,7 @@ public void GetPath(MockTarget.Architecture arch) TargetPointer moduleAddr = loader.AddModule(path: expected); TargetPointer moduleAddrEmptyPath = loader.AddModule(); - var target = new TestPlaceholderTarget(arch, builder.GetReadContext().ReadFromTarget, loader.Types); + var target = new TestPlaceholderTarget(arch, builder.GetMemoryContext().ReadFromTarget, loader.Types); target.SetContracts(Mock.Of( c => c.Loader == ((IContractFactory)new LoaderFactory()).CreateContract(target, 1))); @@ -36,12 +36,12 @@ public void GetPath(MockTarget.Architecture arch) ILoader contract = target.Contracts.Loader; Assert.NotNull(contract); { - Contracts.ModuleHandle handle = contract.GetModuleHandle(moduleAddr); + Contracts.ModuleHandle handle = contract.GetModuleHandleFromModulePtr(moduleAddr); string actual = contract.GetPath(handle); Assert.Equal(expected, actual); } { - Contracts.ModuleHandle handle = contract.GetModuleHandle(moduleAddrEmptyPath); + Contracts.ModuleHandle handle = contract.GetModuleHandleFromModulePtr(moduleAddrEmptyPath); string actual = contract.GetFileName(handle); Assert.Equal(string.Empty, actual); } @@ -62,7 +62,7 @@ public void GetFileName(MockTarget.Architecture arch) TargetPointer moduleAddr = loader.AddModule(fileName: expected); TargetPointer moduleAddrEmptyName = loader.AddModule(); - var target = new TestPlaceholderTarget(arch, builder.GetReadContext().ReadFromTarget, loader.Types); + var target = new TestPlaceholderTarget(arch, builder.GetMemoryContext().ReadFromTarget, loader.Types); target.SetContracts(Mock.Of( c => c.Loader == ((IContractFactory)new LoaderFactory()).CreateContract(target, 1))); @@ -70,12 +70,12 @@ public void GetFileName(MockTarget.Architecture arch) Contracts.ILoader contract = target.Contracts.Loader; Assert.NotNull(contract); { - Contracts.ModuleHandle handle = contract.GetModuleHandle(moduleAddr); + Contracts.ModuleHandle handle = contract.GetModuleHandleFromModulePtr(moduleAddr); string actual = contract.GetFileName(handle); Assert.Equal(expected, actual); } { - Contracts.ModuleHandle handle = contract.GetModuleHandle(moduleAddrEmptyName); + Contracts.ModuleHandle handle = contract.GetModuleHandleFromModulePtr(moduleAddrEmptyName); string actual = contract.GetFileName(handle); Assert.Equal(string.Empty, actual); } diff --git a/src/native/managed/cdac/tests/MethodDescTests.cs b/src/native/managed/cdac/tests/MethodDescTests.cs index a53d201acc2351..c53bf985574ac1 100644 --- a/src/native/managed/cdac/tests/MethodDescTests.cs +++ b/src/native/managed/cdac/tests/MethodDescTests.cs @@ -16,7 +16,7 @@ public class MethodDescTests private static Target CreateTarget(MockDescriptors.MethodDescriptors methodDescBuilder, Mock mockExecutionManager = null) { MockMemorySpace.Builder builder = methodDescBuilder.Builder; - var target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetReadContext().ReadFromTarget, methodDescBuilder.Types, methodDescBuilder.Globals); + var target = new TestPlaceholderTarget(builder.TargetTestHelpers.Arch, builder.GetMemoryContext().ReadFromTarget, methodDescBuilder.Types, methodDescBuilder.Globals); mockExecutionManager ??= new Mock(); target.SetContracts(Mock.Of( diff --git a/src/native/managed/cdac/tests/MethodTableTests.cs b/src/native/managed/cdac/tests/MethodTableTests.cs index fb92efe1fd530b..a3e52a592e6de2 100644 --- a/src/native/managed/cdac/tests/MethodTableTests.cs +++ b/src/native/managed/cdac/tests/MethodTableTests.cs @@ -21,7 +21,7 @@ private static void RTSContractHelper(MockTarget.Architecture arch, Action( c => c.RuntimeTypeSystem == ((IContractFactory)new RuntimeTypeSystemFactory()).CreateContract(target, 1))); diff --git a/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.ExecutionManager.cs b/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.ExecutionManager.cs index 35b99995868a71..85efb7fd191203 100644 --- a/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.ExecutionManager.cs +++ b/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.ExecutionManager.cs @@ -17,7 +17,7 @@ internal class ExecutionManager { public const ulong ExecutionManagerCodeRangeMapAddress = 0x000a_fff0; - const int RealCodeHeaderSize = 0x20; // must be big enough for the offsets of RealCodeHeader size in ExecutionManagerTestTarget, below + const int RealCodeHeaderSize = 0x28; // must be big enough for the offsets of RealCodeHeader size in ExecutionManagerTestTarget, below public struct AllocationRange { @@ -166,9 +166,9 @@ public void InsertAddressRange(TargetCodePointer start, uint length, ulong value } while (cur.Value < end); } - public MockMemorySpace.ReadContext GetReadContext() + public MockMemorySpace.MemoryContext GetMemoryContext() { - return _builder.GetReadContext(); + return _builder.GetMemoryContext(); } } @@ -232,6 +232,7 @@ public static RangeSectionMapTestBuilder CreateRangeSection(MockTarget.Architect Fields = [ new(nameof(Data.RealCodeHeader.MethodDesc), DataType.pointer), + new(nameof(Data.RealCodeHeader.DebugInfo), DataType.pointer), new(nameof(Data.RealCodeHeader.GCInfo), DataType.pointer), new(nameof(Data.RealCodeHeader.NumUnwindInfos), DataType.uint32), new(nameof(Data.RealCodeHeader.UnwindInfos), DataType.pointer), @@ -250,6 +251,7 @@ public static RangeSectionMapTestBuilder CreateRangeSection(MockTarget.Architect new(nameof(Data.ReadyToRunInfo.NumHotColdMap), DataType.uint32), new(nameof(Data.ReadyToRunInfo.HotColdMap), DataType.pointer), new(nameof(Data.ReadyToRunInfo.DelayLoadMethodCallThunks), DataType.pointer), + new(nameof(Data.ReadyToRunInfo.DebugInfoSection), DataType.pointer), new(nameof(Data.ReadyToRunInfo.EntryPointToMethodDescMap), DataType.Unknown, helpers.LayoutFields(MockDescriptors.HashMap.HashMapFields.Fields).Stride), ] }; @@ -430,6 +432,7 @@ public TargetCodePointer AddJittedMethod(JittedCodeRange jittedCodeRange, uint c Builder.TargetTestHelpers.WritePointer(chf.Slice(tyInfo.Fields[nameof(Data.RealCodeHeader.MethodDesc)].Offset, Builder.TargetTestHelpers.PointerSize), methodDescAddress); // fields are not used in the test, but we still need to write them + Builder.TargetTestHelpers.WritePointer(chf.Slice(tyInfo.Fields[nameof(Data.RealCodeHeader.DebugInfo)].Offset, Builder.TargetTestHelpers.PointerSize), TargetPointer.Null); Builder.TargetTestHelpers.WritePointer(chf.Slice(tyInfo.Fields[nameof(Data.RealCodeHeader.GCInfo)].Offset, Builder.TargetTestHelpers.PointerSize), TargetPointer.Null); Builder.TargetTestHelpers.Write(chf.Slice(tyInfo.Fields[nameof(Data.RealCodeHeader.NumUnwindInfos)].Offset, sizeof(uint)), 0u); Builder.TargetTestHelpers.WritePointer(chf.Slice(tyInfo.Fields[nameof(Data.RealCodeHeader.UnwindInfos)].Offset, Builder.TargetTestHelpers.PointerSize), TargetPointer.Null); diff --git a/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.cs b/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.cs index e6fdd8eb4e2ec2..2b4a634b46fe4c 100644 --- a/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.cs +++ b/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.cs @@ -42,6 +42,10 @@ internal record TypeFields new(nameof(Data.EEClass.CorTypeAttr), DataType.uint32), new(nameof(Data.EEClass.NumMethods), DataType.uint16), new(nameof(Data.EEClass.InternalCorElementType), DataType.uint8), + new(nameof(Data.EEClass.NumInstanceFields), DataType.uint16), + new(nameof(Data.EEClass.NumStaticFields), DataType.uint16), + new(nameof(Data.EEClass.NumThreadStaticFields), DataType.uint16), + new(nameof(Data.EEClass.FieldDescList), DataType.pointer), new(nameof(Data.EEClass.NumNonVirtualSlots), DataType.uint16), ] }; @@ -53,6 +57,7 @@ internal record TypeFields [ new(nameof(Data.MethodTableAuxiliaryData.LoaderModule), DataType.pointer), new(nameof(Data.MethodTableAuxiliaryData.OffsetToNonVirtualSlots), DataType.int16), + new(nameof(Data.MethodTableAuxiliaryData.Flags), DataType.uint32), ] }; @@ -189,6 +194,7 @@ internal record TypeFields new(nameof(Data.Thread.LastThrownObject), DataType.pointer), new(nameof(Data.Thread.LinkNext), DataType.pointer), new(nameof(Data.Thread.ExceptionTracker), DataType.pointer), + new(nameof(Data.Thread.ThreadLocalDataPtr), DataType.pointer), ] }; diff --git a/src/native/managed/cdac/tests/MockMemorySpace.cs b/src/native/managed/cdac/tests/MockMemorySpace.cs index f5125fba8b766b..db9b34e867600c 100644 --- a/src/native/managed/cdac/tests/MockMemorySpace.cs +++ b/src/native/managed/cdac/tests/MockMemorySpace.cs @@ -47,7 +47,7 @@ internal Span BorrowAddressRange(ulong address, int length) { foreach (var fragment in _heapFragments) { - if (address >= fragment.Address && address+(ulong)length <= fragment.Address + (ulong)fragment.Data.Length) + if (address >= fragment.Address && address + (ulong)length <= fragment.Address + (ulong)fragment.Data.Length) return fragment.Data.AsSpan((int)(address - fragment.Address), length); } throw new InvalidOperationException($"No fragment includes addresses from 0x{address:x} with length {length}"); @@ -83,9 +83,9 @@ public Builder AddHeapFragments(IEnumerable fragments) return this; } - internal ReadContext GetReadContext() + internal MemoryContext GetMemoryContext() { - ReadContext context = new ReadContext + MemoryContext context = new MemoryContext { HeapFragments = _heapFragments, }; @@ -124,9 +124,9 @@ public BumpAllocator CreateAllocator(ulong start, ulong end, int minAlign = 16) } // Used by ReadFromTarget to return the appropriate bytes - internal class ReadContext + internal class MemoryContext { - public IReadOnlyList HeapFragments { get; init; } + public IList HeapFragments { get; init; } internal int ReadFromTarget(ulong address, Span buffer) { @@ -173,5 +173,54 @@ internal int ReadFromTarget(ulong address, Span buffer) throw new InvalidOperationException($"Not enough data in fragment at {lastHeapFragment.Address:X} ('{lastHeapFragment.Name}') to read {buffer.Length} bytes at {address:X} (only {availableLength} bytes available)"); return -1; } + + internal int WriteToTarget(ulong address, Span buffer) + { + if (buffer.Length == 0) + return 0; + + if (address == 0) + return -1; + + bool partialWriteOccurred = false; + HeapFragment lastHeapFragment = default; + int availableLength = 0; + while (true) + { + bool tryAgain = false; + for (int i = 0; i < HeapFragments.Count; i++) + { + var fragment = HeapFragments[i]; + if (address >= fragment.Address && address < fragment.Address + (ulong)fragment.Data.Length) + { + int offset = (int)(address - fragment.Address); + availableLength = fragment.Data.Length - offset; + if (availableLength >= buffer.Length) + { + buffer.CopyTo(fragment.Data.AsSpan(offset, buffer.Length)); + HeapFragments[i] = fragment; // Update the fragment in the list + return 0; + } + else + { + lastHeapFragment = fragment; + partialWriteOccurred = true; + tryAgain = true; + buffer.Slice(0, availableLength).CopyTo(fragment.Data.AsSpan(offset, availableLength)); + HeapFragments[i] = fragment; // Update the fragment in the list + buffer = buffer.Slice(availableLength); + address = fragment.Address + (ulong)fragment.Data.Length; + break; + } + } + } + if (!tryAgain) + break; + } + + if (partialWriteOccurred) + throw new InvalidOperationException($"Not enough space in fragment at {lastHeapFragment.Address:X} ('{lastHeapFragment.Name}') to write {buffer.Length} bytes at {address:X} (only {availableLength} bytes available)"); + return -1; + } } } diff --git a/src/native/managed/cdac/tests/ObjectTests.cs b/src/native/managed/cdac/tests/ObjectTests.cs index 7df1b2b104942f..7ccc5960a96507 100644 --- a/src/native/managed/cdac/tests/ObjectTests.cs +++ b/src/native/managed/cdac/tests/ObjectTests.cs @@ -22,7 +22,7 @@ private static void ObjectContractHelper(MockTarget.Architecture arch, Action( c => c.Object == ((IContractFactory)new ObjectFactory()).CreateContract(target, 1) && c.RuntimeTypeSystem == ((IContractFactory)new RuntimeTypeSystemFactory()).CreateContract(target, 1))); diff --git a/src/native/managed/cdac/tests/PrecodeStubsTests.cs b/src/native/managed/cdac/tests/PrecodeStubsTests.cs index 0abc27271481ed..cbab72d9e3d729 100644 --- a/src/native/managed/cdac/tests/PrecodeStubsTests.cs +++ b/src/native/managed/cdac/tests/PrecodeStubsTests.cs @@ -348,7 +348,7 @@ public TargetCodePointer AddThisPtrRetBufPrecodeEntry(string name, PrecodeTestDe private static Target CreateTarget(PrecodeBuilder precodeBuilder) { var arch = precodeBuilder.Builder.TargetTestHelpers.Arch; - TestPlaceholderTarget.ReadFromTargetDelegate reader = precodeBuilder.Builder.GetReadContext().ReadFromTarget; + TestPlaceholderTarget.ReadFromTargetDelegate reader = precodeBuilder.Builder.GetMemoryContext().ReadFromTarget; // hack for this test put the precode machine descriptor at the same address as the PlatformMetadata (string Name, ulong Value)[] globals = [(Constants.Globals.PlatformMetadata, precodeBuilder.MachineDescriptorAddress)]; var target = new TestPlaceholderTarget(arch, reader, precodeBuilder.Types, globals); diff --git a/src/native/managed/cdac/tests/ReJITTests.cs b/src/native/managed/cdac/tests/ReJITTests.cs index 34b47914fd9776..c3140c9ccaffe7 100644 --- a/src/native/managed/cdac/tests/ReJITTests.cs +++ b/src/native/managed/cdac/tests/ReJITTests.cs @@ -20,7 +20,7 @@ internal static Target CreateTarget( MockReJIT builder, Mock mockCodeVersions = null) { - TestPlaceholderTarget target = new TestPlaceholderTarget(arch, builder.Builder.GetReadContext().ReadFromTarget, builder.Types, builder.Globals); + TestPlaceholderTarget target = new TestPlaceholderTarget(arch, builder.Builder.GetMemoryContext().ReadFromTarget, builder.Types, builder.Globals); mockCodeVersions ??= new Mock(); diff --git a/src/native/managed/cdac/tests/RuntimeInfoTests.cs b/src/native/managed/cdac/tests/RuntimeInfoTests.cs index 01130068d7001e..5dbf058dfdf775 100644 --- a/src/native/managed/cdac/tests/RuntimeInfoTests.cs +++ b/src/native/managed/cdac/tests/RuntimeInfoTests.cs @@ -16,7 +16,7 @@ internal static Target CreateTarget( (string Name, string Value)[] globalStrings) { MockMemorySpace.Builder builder = new MockMemorySpace.Builder(new TargetTestHelpers(arch)); - TestPlaceholderTarget target = new TestPlaceholderTarget(arch, builder.GetReadContext().ReadFromTarget, [], [], globalStrings); + TestPlaceholderTarget target = new TestPlaceholderTarget(arch, builder.GetMemoryContext().ReadFromTarget, [], [], globalStrings); IContractFactory runtimeInfoFactory = new RuntimeInfoFactory(); diff --git a/src/native/managed/cdac/tests/TestPlaceholderTarget.cs b/src/native/managed/cdac/tests/TestPlaceholderTarget.cs index d61e862d2ed7a4..c05125b483a4fc 100644 --- a/src/native/managed/cdac/tests/TestPlaceholderTarget.cs +++ b/src/native/managed/cdac/tests/TestPlaceholderTarget.cs @@ -81,8 +81,9 @@ public override TargetPointer ReadGlobalPointer(string name) public override void ReadBuffer(ulong address, Span buffer) { if (_dataReader(address, buffer) < 0) - throw new InvalidOperationException($"Failed to read {buffer.Length} bytes at 0x{address:x8}."); + throw new VirtualReadException($"Failed to read {buffer.Length} bytes at 0x{address:x8}."); } + public override void WriteBuffer(ulong address, Span buffer) => throw new NotImplementedException(); public override string ReadUtf8String(ulong address) => throw new NotImplementedException(); public override string ReadUtf16String(ulong address) @@ -161,7 +162,19 @@ public override bool TryReadGlobalString(string name, [NotNullWhen(true)] out st public override T Read(ulong address) => DefaultRead(address); -#region subclass reader helpers + public override bool TryRead(ulong address, out T value) + { + value = default; + if (!DefaultTryRead(address, out T readValue)) + return false; + + value = readValue; + return true; + } + + public override void Write(ulong address, T value) => throw new NotImplementedException(); + + #region subclass reader helpers /// /// Basic utility to read a value from memory, all the DefaultReadXXX methods call this. @@ -218,14 +231,14 @@ protected static bool IsSigned() where T : struct, INumberBase, IMinMaxVal protected T DefaultRead(ulong address) where T : unmanaged, IBinaryInteger, IMinMaxValue { if (!DefaultTryRead(address, out T value)) - throw new InvalidOperationException($"Failed to read {typeof(T)} at 0x{address:x8}."); + throw new VirtualReadException($"Failed to read {typeof(T)} at 0x{address:x8}."); return value; } - protected TargetPointer DefaultReadPointer (ulong address) + protected TargetPointer DefaultReadPointer(ulong address) { if (!DefaultTryReadPointer(address, out TargetPointer pointer)) - throw new InvalidOperationException($"Failed to read pointer at 0x{address:x8}."); + throw new VirtualReadException($"Failed to read pointer at 0x{address:x8}."); return pointer; } @@ -262,7 +275,7 @@ protected bool DefaultTryReadNUInt(ulong address, out ulong value) protected TargetNUInt DefaultReadNUInt(ulong address) { if (!DefaultTryReadNUInt(address, out ulong value)) - throw new InvalidOperationException($"Failed to read nuint at 0x{address:x8}."); + throw new VirtualReadException($"Failed to read nuint at 0x{address:x8}."); return new TargetNUInt(value); } @@ -271,7 +284,7 @@ protected TargetCodePointer DefaultReadCodePointer(ulong address) { return new TargetCodePointer(DefaultReadPointer(address)); } -#endregion subclass reader helpers + #endregion subclass reader helpers public override TargetPointer ReadPointerFromSpan(ReadOnlySpan bytes) => throw new NotImplementedException(); @@ -309,7 +322,8 @@ public T GetOrAdd(TargetPointer address) where T : Data.IData return constructed; bool found = TryGet(address, out result); - if (!found) { + if (!found) + { throw new InvalidOperationException($"Failed to add {typeof(T)} at 0x{address:x8}."); } return result!; diff --git a/src/native/managed/cdac/tests/ThreadTests.cs b/src/native/managed/cdac/tests/ThreadTests.cs index e6d5b26e67b68a..f8998c7766ab7b 100644 --- a/src/native/managed/cdac/tests/ThreadTests.cs +++ b/src/native/managed/cdac/tests/ThreadTests.cs @@ -13,7 +13,7 @@ public unsafe class ThreadTests private static Target CreateTarget(MockDescriptors.Thread thread) { MockTarget.Architecture arch = thread.Builder.TargetTestHelpers.Arch; - var target = new TestPlaceholderTarget(arch, thread.Builder.GetReadContext().ReadFromTarget, thread.Types, thread.Globals); + var target = new TestPlaceholderTarget(arch, thread.Builder.GetMemoryContext().ReadFromTarget, thread.Types, thread.Globals); target.SetContracts(Mock.Of( c => c.Thread == ((IContractFactory)new ThreadFactory()).CreateContract(target, 1))); return target; diff --git a/src/native/managed/cdac/tests/TypeDescTests.cs b/src/native/managed/cdac/tests/TypeDescTests.cs index 7508c83e481a01..9a79bacdb6be78 100644 --- a/src/native/managed/cdac/tests/TypeDescTests.cs +++ b/src/native/managed/cdac/tests/TypeDescTests.cs @@ -194,7 +194,7 @@ public void IsGenericVariable(MockTarget.Architecture arch) private static Target CreateTarget(MockDescriptors.RuntimeTypeSystem rtsBuilder) { - var target = new TestPlaceholderTarget(rtsBuilder.Builder.TargetTestHelpers.Arch, rtsBuilder.Builder.GetReadContext().ReadFromTarget, rtsBuilder.Types, rtsBuilder.Globals); + var target = new TestPlaceholderTarget(rtsBuilder.Builder.TargetTestHelpers.Arch, rtsBuilder.Builder.GetMemoryContext().ReadFromTarget, rtsBuilder.Types, rtsBuilder.Globals); target.SetContracts(Mock.Of( c => c.RuntimeTypeSystem == ((IContractFactory)new RuntimeTypeSystemFactory()).CreateContract(target, 1))); return target; diff --git a/src/native/minipal/CMakeLists.txt b/src/native/minipal/CMakeLists.txt index 78011d4779694a..f32281a56bb365 100644 --- a/src/native/minipal/CMakeLists.txt +++ b/src/native/minipal/CMakeLists.txt @@ -2,6 +2,7 @@ include(configure.cmake) set(SOURCES cpufeatures.c + memorybarrierprocesswide.c mutex.c guid.c random.c diff --git a/src/native/minipal/debugger.c b/src/native/minipal/debugger.c index 4fdef053a225a3..763f12079caabd 100644 --- a/src/native/minipal/debugger.c +++ b/src/native/minipal/debugger.c @@ -32,6 +32,7 @@ #include #define MINIPAL_DEBUGGER_PRESENT_CHECK #elif defined(__sun) +#include #include #include #include diff --git a/src/native/minipal/memorybarrierprocesswide.c b/src/native/minipal/memorybarrierprocesswide.c new file mode 100644 index 00000000000000..b2fcad9ef789c0 --- /dev/null +++ b/src/native/minipal/memorybarrierprocesswide.c @@ -0,0 +1,240 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef HOST_WINDOWS +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +#include +#include + +#define CHECK_MACH(_msg, machret) do { \ + if (machret != KERN_SUCCESS) \ + { \ + char _szError[1024]; \ + snprintf(_szError, ARRAY_SIZE(_szError), "%s: %u: %s", __FUNCTION__, __LINE__, _msg); \ + mach_error(_szError, machret); \ + abort(); \ + } \ + } while (false) + +#endif // __APPLE__ + +#ifdef __linux__ +#include +#include +#define membarrier(...) syscall(__NR_membarrier, __VA_ARGS__) +#undef HAVE_SYS_MEMBARRIER_H +#define HAVE_SYS_MEMBARRIER_H 1 +#elif HAVE_SYS_MEMBARRIER_H +#include +#endif + +#if HAVE_SYS_MEMBARRIER_H +static bool CanFlushUsingMembarrier(void) +{ +#ifdef TARGET_ANDROID + // Avoid calling membarrier on older Android versions where membarrier + // may be barred by seccomp causing the process to be killed. + int apiLevel = android_get_device_api_level(); + if (apiLevel < __ANDROID_API_Q__) + { + return false; + } +#endif + + // Starting with Linux kernel 4.14, process memory barriers can be generated + // using MEMBARRIER_CMD_PRIVATE_EXPEDITED. + + int mask = membarrier(MEMBARRIER_CMD_QUERY, 0, 0); + + if (mask >= 0 && + mask & MEMBARRIER_CMD_PRIVATE_EXPEDITED && + // Register intent to use the private expedited command. + membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0, 0) == 0) + { + return true; + } + + return false; +} + +// +// Tracks if the OS supports membarrier syscall +// +static bool s_flushUsingMemBarrier = false; +#endif // HAVE_SYS_MEMBARRIER_H + +#if !defined(HOST_APPLE) && !defined(HOST_WASM) +// Helper memory page used by the fallback path +static uint8_t* g_helperPage = NULL; + +// Mutex to make the fallback path thread safe +static pthread_mutex_t g_flushProcessWriteBuffersMutex; + +static size_t s_pageSize = 0; +#endif // !TARGET_APPLE && !HOST_WASM + +static bool s_initializedMemoryBarrierSuccessfullyInitialized = false; + +bool minipal_initialize_memory_barrier_process_wide(void) +{ + if (s_initializedMemoryBarrierSuccessfullyInitialized) + { + return true; + } + +#ifdef HOST_WASM + // browser/wasm is currently single threaded +#elif defined(HOST_APPLE) + // Apple platforms do not support membarrier, so we use a different mechanism +#else +#if HAVE_SYS_MEMBARRIER_H + if (CanFlushUsingMembarrier()) + { + s_flushUsingMemBarrier = true; + } + else +#endif // HAVE_SYS_MEMBARRIER_H + { + // Fallback implementation + assert(g_helperPage == NULL); + + int pageSize = sysconf( _SC_PAGE_SIZE ); + + s_pageSize = (size_t)((pageSize > 0) ? pageSize : 0x1000); + g_helperPage = (uint8_t*)(mmap(0, s_pageSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); + + if (g_helperPage == MAP_FAILED) + { + return false; + } + + // Verify that the s_helperPage is really aligned to the s_pageSize + assert((((size_t)g_helperPage) & (s_pageSize - 1)) == 0); + + // Locking the page ensures that it stays in memory during the two mprotect + // calls in the FlushProcessWriteBuffers below. If the page was unmapped between + // those calls, they would not have the expected effect of generating IPI. + int status = mlock(g_helperPage, s_pageSize); + + if (status != 0) + { + return false; + } + + status = pthread_mutex_init(&g_flushProcessWriteBuffersMutex, NULL); + if (status != 0) + { + munlock(g_helperPage, s_pageSize); + return false; + } + } +#endif // !HOST_WASM && !HOST_APPLE + + s_initializedMemoryBarrierSuccessfullyInitialized = true; + return true; +} + +// Flush write buffers of processors that are executing threads of the current process +void minipal_memory_barrier_process_wide(void) +{ + assert(s_initializedMemoryBarrierSuccessfullyInitialized); + +#ifdef HOST_WASM + // browser/wasm is currently single threaded +#elif defined(HOST_APPLE) + mach_msg_type_number_t cThreads; + thread_act_t *pThreads; + kern_return_t machret = task_threads(mach_task_self(), &pThreads, &cThreads); + CHECK_MACH("task_threads()", machret); + + uintptr_t sp; + uintptr_t registerValues[128]; + + // Iterate through each of the threads in the list. + for (mach_msg_type_number_t i = 0; i < cThreads; i++) + { + if (__builtin_available (macOS 10.14, iOS 12, tvOS 9, *)) + { + // Request the threads pointer values to force the thread to emit a memory barrier + size_t registers = 128; + machret = thread_get_register_pointer_values(pThreads[i], &sp, ®isters, registerValues); + } + else + { + // fallback implementation for older OS versions +#if defined(HOST_AMD64) + x86_thread_state64_t threadState; + mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; + machret = thread_get_state(pThreads[i], x86_THREAD_STATE64, (thread_state_t)&threadState, &count); +#elif defined(HOST_ARM64) + arm_thread_state64_t threadState; + mach_msg_type_number_t count = ARM_THREAD_STATE64_COUNT; + machret = thread_get_state(pThreads[i], ARM_THREAD_STATE64, (thread_state_t)&threadState, &count); +#else + #error Unexpected architecture +#endif + } + + if (machret == KERN_INSUFFICIENT_BUFFER_SIZE) + { + CHECK_MACH("thread_get_register_pointer_values()", machret); + } + + machret = mach_port_deallocate(mach_task_self(), pThreads[i]); + CHECK_MACH("mach_port_deallocate()", machret); + } + // Deallocate the thread list now we're done with it. + machret = vm_deallocate(mach_task_self(), (vm_address_t)pThreads, cThreads * sizeof(thread_act_t)); + CHECK_MACH("vm_deallocate()", machret); +#else // !HOST_APPLE && !HOST_WASM +#if HAVE_SYS_MEMBARRIER_H + if (s_flushUsingMemBarrier) + { + int status = membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0, 0); + assert(status == 0 && "Failed to flush using membarrier"); + } + else +#endif // !HAVE_SYS_MEMBARRIER_H + { + assert(g_helperPage != NULL); + + int status = pthread_mutex_lock(&g_flushProcessWriteBuffersMutex); + (void)status; // unused in release config + assert(status == 0 && "Failed to lock the flushProcessWriteBuffersMutex lock"); + + // causes the OS to issue IPI to flush TLBs on all processors. This also + // results in flushing the processor buffers. + // Changing a helper memory page protection from read / write to no access + status = mprotect(g_helperPage, s_pageSize, PROT_READ | PROT_WRITE); + assert(status == 0 && "Failed to change helper page protection to read / write"); + + // Ensure that the page is dirty before we change the protection so that + // we prevent the OS from skipping the global TLB flush. + __sync_add_and_fetch((size_t*)g_helperPage, 1); + + status = mprotect(g_helperPage, s_pageSize, PROT_NONE); + assert(status == 0 && "Failed to change helper page protection to no access"); + + status = pthread_mutex_unlock(&g_flushProcessWriteBuffersMutex); + assert(status == 0 && "Failed to unlock the flushProcessWriteBuffersMutex lock"); + } +#endif // !HOST_APPLE && !HOST_WASM +} +#else // !HOST_WINDOWS + +#include + +void minipal_memory_barrier_process_wide(void) +{ + FlushProcessWriteBuffers(); +} +#endif // !HOST_WINDOWS diff --git a/src/native/minipal/memorybarrierprocesswide.h b/src/native/minipal/memorybarrierprocesswide.h new file mode 100644 index 00000000000000..99a0d03922e6db --- /dev/null +++ b/src/native/minipal/memorybarrierprocesswide.h @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef HAVE_MINIPAL_MEMORY_H +#define HAVE_MINIPAL_MEMORY_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + + bool minipal_initialize_memory_barrier_process_wide(void); + void minipal_memory_barrier_process_wide(void); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // HAVE_MINIPAL_MEMORY_H diff --git a/src/native/minipal/thread.h b/src/native/minipal/thread.h index 7655f4bf2c7f88..48405dfb3195ae 100644 --- a/src/native/minipal/thread.h +++ b/src/native/minipal/thread.h @@ -69,6 +69,8 @@ static inline size_t minipal_get_current_thread_id(void) tid = (size_t)_lwp_self(); #elif defined(__HAIKU__) tid = (size_t)find_thread(NULL); +#elif defined(__sun) + tid = (size_t)pthread_self(); #else tid = (size_t)(void*)pthread_self(); #endif diff --git a/src/tasks/AndroidAppBuilder/AndroidAppBuilder.csproj b/src/tasks/AndroidAppBuilder/AndroidAppBuilder.csproj index 00b863c5ea59a4..5614e09c8b106d 100644 --- a/src/tasks/AndroidAppBuilder/AndroidAppBuilder.csproj +++ b/src/tasks/AndroidAppBuilder/AndroidAppBuilder.csproj @@ -5,6 +5,7 @@ true false enable + true $(NoWarn),CA1050,CA1850 diff --git a/src/tasks/AndroidAppBuilder/ApkBuilder.cs b/src/tasks/AndroidAppBuilder/ApkBuilder.cs index 21fd800c89681a..30e79a29dfdf8a 100644 --- a/src/tasks/AndroidAppBuilder/ApkBuilder.cs +++ b/src/tasks/AndroidAppBuilder/ApkBuilder.cs @@ -6,7 +6,9 @@ using System.IO; using System.IO.Compression; using System.Linq; +using System.Reflection.Metadata; using System.Text; +using System.Text.Json; using System.Text.RegularExpressions; using Microsoft.Android.Build; using Microsoft.Build.Framework; @@ -15,7 +17,8 @@ public enum RuntimeFlavorEnum { Mono, - CoreCLR + CoreCLR, + NativeAOT } public partial class ApkBuilder @@ -39,7 +42,6 @@ public partial class ApkBuilder public bool ForceAOT { get; set; } public bool ForceFullAOT { get; set; } public ITaskItem[] EnvironmentVariables { get; set; } = Array.Empty(); - public bool InvariantGlobalization { get; set; } public bool EnableRuntimeLogging { get; set; } public bool StaticLinkedRuntime { get; set; } public string[] RuntimeComponents { get; set; } = Array.Empty(); @@ -53,6 +55,7 @@ public partial class ApkBuilder private RuntimeFlavorEnum parsedRuntimeFlavor; private bool IsMono => parsedRuntimeFlavor == RuntimeFlavorEnum.Mono; private bool IsCoreCLR => parsedRuntimeFlavor == RuntimeFlavorEnum.CoreCLR; + private bool IsNativeAOT => parsedRuntimeFlavor == RuntimeFlavorEnum.NativeAOT; private TaskLoggingHelper logger; @@ -91,7 +94,8 @@ public ApkBuilder(TaskLoggingHelper logger) throw new ArgumentException($"ProjectName='{ProjectName}' should not not contain spaces."); } - if (string.IsNullOrEmpty(AndroidSdk)){ + if (string.IsNullOrEmpty(AndroidSdk)) + { AndroidSdk = Environment.GetEnvironmentVariable("ANDROID_SDK_ROOT"); } @@ -154,7 +158,7 @@ public ApkBuilder(TaskLoggingHelper logger) var assemblerFilesToLink = new StringBuilder(); var aotLibraryFiles = new List(); - if (!IsLibraryMode) + if (!(IsLibraryMode || IsNativeAOT)) { foreach (ITaskItem file in Assemblies) { @@ -244,7 +248,7 @@ public ApkBuilder(TaskLoggingHelper logger) { nativeLibraries = string.Join("\n ", NativeDependencies.Select(dep => dep)); } - else + else if (!IsNativeAOT) { string runtimeLib = ""; if (StaticLinkedRuntime && IsMono) @@ -325,72 +329,84 @@ public ApkBuilder(TaskLoggingHelper logger) nativeLibraries += $" libc++_static.a{Environment.NewLine}"; } } - - StringBuilder extraLinkerArgs = new StringBuilder(); - foreach (ITaskItem item in ExtraLinkerArguments) + string abi; + if (IsNativeAOT) { - extraLinkerArgs.AppendLine($" \"{item.ItemSpec}\""); + abi = AndroidProject.DetermineAbi(runtimeIdentifier); } - - if (StaticLinkedRuntime && IsCoreCLR) + else { - // Ensure global symbol references in the shared library are resolved to definitions in - // the same shared library. For the static linked runtime specifically, we need this for - // global functions in assembly for the linker to treat relative offsets to them as constant - extraLinkerArgs.AppendLine($" \"-Wl,-Bsymbolic\""); - } + StringBuilder extraLinkerArgs = new StringBuilder(); + foreach (ITaskItem item in ExtraLinkerArguments) + { + extraLinkerArgs.AppendLine($" \"{item.ItemSpec}\""); + } - nativeLibraries += assemblerFilesToLink.ToString(); + if (StaticLinkedRuntime && IsCoreCLR) + { + // Ensure global symbol references in the shared library are resolved to definitions in + // the same shared library. For the static linked runtime specifically, we need this for + // global functions in assembly for the linker to treat relative offsets to them as constant + extraLinkerArgs.AppendLine($" \"-Wl,-Bsymbolic\""); + } - string aotSources = assemblerFiles.ToString(); - string monodroidSource = IsCoreCLR ? - "monodroid-coreclr.c" : (IsLibraryMode) ? "monodroid-librarymode.c" : "monodroid.c"; - string runtimeInclude = string.Join(" ", runtimeHeaders.Select(h => $"\"{NormalizePathToUnix(h)}\"")); + nativeLibraries += assemblerFilesToLink.ToString(); - string cmakeLists = Utils.GetEmbeddedResource("CMakeLists-android.txt") - .Replace("%RuntimeInclude%", runtimeInclude) - .Replace("%NativeLibrariesToLink%", NormalizePathToUnix(nativeLibraries)) - .Replace("%MONODROID_SOURCE%", monodroidSource) - .Replace("%AotSources%", NormalizePathToUnix(aotSources)) - .Replace("%AotModulesSource%", string.IsNullOrEmpty(aotSources) ? "" : "modules.c") - .Replace("%APP_LINKER_ARGS%", extraLinkerArgs.ToString()); + string aotSources = assemblerFiles.ToString(); + string monodroidSource = IsCoreCLR ? + "monodroid-coreclr.c" : (IsLibraryMode) ? "monodroid-librarymode.c" : "monodroid.c"; + string runtimeInclude = string.Join(" ", runtimeHeaders.Select(h => $"\"{NormalizePathToUnix(h)}\"")); - var defines = new StringBuilder(); - if (ForceInterpreter) - { - defines.AppendLine("add_definitions(-DFORCE_INTERPRETER=1)"); - } - else if (ForceAOT) - { - defines.AppendLine("add_definitions(-DFORCE_AOT=1)"); - if (aotLibraryFiles.Count == 0) + string cmakeLists = Utils.GetEmbeddedResource("CMakeLists-android.txt") + .Replace("%RuntimeInclude%", runtimeInclude) + .Replace("%NativeLibrariesToLink%", NormalizePathToUnix(nativeLibraries)) + .Replace("%MONODROID_SOURCE%", monodroidSource) + .Replace("%AotSources%", NormalizePathToUnix(aotSources)) + .Replace("%AotModulesSource%", string.IsNullOrEmpty(aotSources) ? "" : "modules.c") + .Replace("%APP_LINKER_ARGS%", extraLinkerArgs.ToString()); + + var defines = new StringBuilder(); + if (ForceInterpreter) { - defines.AppendLine("add_definitions(-DSTATIC_AOT=1)"); + defines.AppendLine("add_definitions(-DFORCE_INTERPRETER=1)"); + } + else if (ForceAOT) + { + defines.AppendLine("add_definitions(-DFORCE_AOT=1)"); + if (aotLibraryFiles.Count == 0) + { + defines.AppendLine("add_definitions(-DSTATIC_AOT=1)"); + } } - } - if (ForceFullAOT) - { - defines.AppendLine("add_definitions(-DFULL_AOT=1)"); - } + if (ForceFullAOT) + { + defines.AppendLine("add_definitions(-DFULL_AOT=1)"); + } - if (!string.IsNullOrEmpty(DiagnosticPorts)) - { - defines.AppendLine("add_definitions(-DDIAGNOSTIC_PORTS=\"" + DiagnosticPorts + "\")"); - } + if (!string.IsNullOrEmpty(DiagnosticPorts)) + { + defines.AppendLine("add_definitions(-DDIAGNOSTIC_PORTS=\"" + DiagnosticPorts + "\")"); + } - cmakeLists = cmakeLists.Replace("%Defines%", defines.ToString()); + cmakeLists = cmakeLists.Replace("%Defines%", defines.ToString()); - File.WriteAllText(Path.Combine(OutputDir, "CMakeLists.txt"), cmakeLists); - File.WriteAllText(Path.Combine(OutputDir, monodroidSource), Utils.GetEmbeddedResource(monodroidSource)); + File.WriteAllText(Path.Combine(OutputDir, "CMakeLists.txt"), cmakeLists); - AndroidProject project = new AndroidProject("monodroid", runtimeIdentifier, AndroidNdk, logger); - project.GenerateCMake(OutputDir, MinApiLevel, StripDebugSymbols); - project.BuildCMake(OutputDir, StripDebugSymbols); + string monodroidContent = Utils.GetEmbeddedResource(monodroidSource); + if (IsCoreCLR) + { + monodroidContent = RenderMonodroidCoreClrTemplate(monodroidContent); + } + File.WriteAllText(Path.Combine(OutputDir, monodroidSource), monodroidContent); - // TODO: https://github.com/dotnet/runtime/issues/115717 + AndroidProject project = new AndroidProject("monodroid", runtimeIdentifier, AndroidNdk, logger); + project.GenerateCMake(OutputDir, MinApiLevel, StripDebugSymbols); + project.BuildCMake(OutputDir, StripDebugSymbols); + abi = project.Abi; - string abi = project.Abi; + // TODO: https://github.com/dotnet/runtime/issues/115717 + } // 2. Compile Java files @@ -424,11 +440,22 @@ public ApkBuilder(TaskLoggingHelper logger) envVariables += $"\t\tsetEnv(\"{name}\", \"{value}\");\n"; } - string jniLibraryName = (IsLibraryMode) ? ProjectName! : - (StaticLinkedRuntime && IsCoreCLR) ? "monodroid" : "System.Security.Cryptography.Native.Android"; + string jniLibraryName; + if (IsLibraryMode || IsNativeAOT) + jniLibraryName = ProjectName!; + else if (StaticLinkedRuntime && IsCoreCLR) + jniLibraryName = "monodroid"; + else + jniLibraryName = "System.Security.Cryptography.Native.Android"; + + List librariesToLoad = [jniLibraryName]; + if (!IsNativeAOT) + librariesToLoad.Add("monodroid"); + string monoRunner = Utils.GetEmbeddedResource("MonoRunner.java") .Replace("%EntryPointLibName%", Path.GetFileName(mainLibraryFileName)) - .Replace("%JNI_LIBRARY_NAME%", jniLibraryName) + .Replace("%LoadLibraryStatements%", + string.Join('\n', librariesToLoad.Select(l => $"System.loadLibrary(\"{l}\");"))) .Replace("%EnvVariables%", envVariables); File.WriteAllText(monoRunnerPath, monoRunner); @@ -464,7 +491,8 @@ public ApkBuilder(TaskLoggingHelper logger) Utils.RunProcess(logger, androidSdkHelper.AaptPath, $"package -f -m -F {apkFile} -A assets -M AndroidManifest.xml -I {androidJar} {debugModeArg}", workingDir: OutputDir); var dynamicLibs = new List(); - dynamicLibs.Add(Path.Combine(OutputDir, "monodroid", "libmonodroid.so")); + if (!IsNativeAOT) + dynamicLibs.Add(Path.Combine(OutputDir, "monodroid", "libmonodroid.so")); if (IsLibraryMode) { @@ -527,7 +555,6 @@ public ApkBuilder(TaskLoggingHelper logger) } // NOTE: we can run android-strip tool from NDK to shrink native binaries here even more. - File.Copy(dynamicLib, Path.Combine(OutputDir, destRelative), true); Utils.RunProcess(logger, androidSdkHelper.AaptPath, $"add {apkFile} {NormalizePathToUnix(destRelative)}", workingDir: OutputDir); } @@ -640,4 +667,79 @@ private static string NormalizePathToUnix(string path) [GeneratedRegex(@"\.(\d)")] private static partial Regex DotNumberRegex(); + + private string RenderMonodroidCoreClrTemplate(string monodroidContent) + { + // At the moment, we only set the AppContext properties, so it's all done here for simplicity. + // If we need to add more rendering logic, we can refactor this method later. + var appContextKeys = new StringBuilder(); + appContextKeys.AppendLine(" appctx_keys[0] = \"RUNTIME_IDENTIFIER\";"); + appContextKeys.AppendLine(" appctx_keys[1] = \"APP_CONTEXT_BASE_DIRECTORY\";"); + appContextKeys.AppendLine(" appctx_keys[2] = \"HOST_RUNTIME_CONTRACT\";"); + + var appContextValues = new StringBuilder(); + appContextValues.AppendLine(" appctx_values[0] = ANDROID_RUNTIME_IDENTIFIER;"); + appContextValues.AppendLine(" appctx_values[1] = g_bundle_path;"); + appContextValues.AppendLine(); + appContextValues.AppendLine(" char contract_str[19];"); // 0x + 16 hex digits + '\0' + appContextValues.AppendLine(" snprintf(contract_str, 19, \"0x%zx\", (size_t)(&g_host_contract));"); + appContextValues.AppendLine(" appctx_values[2] = contract_str;"); + appContextValues.AppendLine(); + + // Parse runtime config properties and add them to the AppContext keys and values. + Dictionary configProperties = ParseRuntimeConfigProperties(); + int hardwiredAppContextProperties = 3; // For the hardwired AppContext keys and values above. + int i = 0; + foreach ((string key, string value) in configProperties) + { + appContextKeys.AppendLine($" appctx_keys[{i + hardwiredAppContextProperties}] = \"{key}\";"); + appContextValues.AppendLine($" appctx_values[{i + hardwiredAppContextProperties}] = \"{value}\";"); + i++; + } + + // Replace the template placeholders. + string updatedContent = monodroidContent.Replace("%AppContextPropertyCount%", (configProperties.Count + hardwiredAppContextProperties).ToString()) + .Replace("%AppContextKeys%", appContextKeys.ToString().TrimEnd()) + .Replace("%AppContextValues%", appContextValues.ToString().TrimEnd()); + return updatedContent; + } + + private Dictionary ParseRuntimeConfigProperties() + { + // This method reads the binary runtimeconfig.bin file created by RuntimeConfigParserTask.ConvertDictionaryToBlob. + // The binary format is: compressed integer count, followed by count pairs of length-prefixed UTF8 strings (key, value). + // See src/tasks/MonoTargetsTasks/RuntimeConfigParser/RuntimeConfigParser.cs for the corresponding write logic. + + var configProperties = new Dictionary(); + string runtimeConfigPath = Path.Combine(AppDir ?? throw new InvalidOperationException("AppDir is not set"), "runtimeconfig.bin"); + + try + { + byte[] fileBytes = File.ReadAllBytes(runtimeConfigPath); + unsafe + { + fixed (byte* ptr = fileBytes) + { + var blobReader = new BlobReader(ptr, fileBytes.Length); + + // Read the compressed integer count + int count = blobReader.ReadCompressedInteger(); + + // Read each key-value pair + for (int i = 0; i < count; i++) + { + string key = blobReader.ReadSerializedString() ?? string.Empty; + string value = blobReader.ReadSerializedString() ?? string.Empty; + configProperties[key] = value; + } + } + } + } + catch (Exception ex) + { + logger.LogMessage(MessageImportance.High, $"Error while parsing runtime config at {runtimeConfigPath}: {ex.Message}"); + } + + return configProperties; + } } diff --git a/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java b/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java index f8938e9fff316c..c384a85066804b 100644 --- a/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java +++ b/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java @@ -34,8 +34,7 @@ public class MonoRunner extends Instrumentation { static { // loadLibrary triggers JNI_OnLoad in these libs - System.loadLibrary("%JNI_LIBRARY_NAME%"); - System.loadLibrary("monodroid"); + %LoadLibraryStatements% } static String testResultsDir; diff --git a/src/tasks/AndroidAppBuilder/Templates/monodroid-coreclr.c b/src/tasks/AndroidAppBuilder/Templates/monodroid-coreclr.c index f973a886c9555a..fed141345b8d25 100644 --- a/src/tasks/AndroidAppBuilder/Templates/monodroid-coreclr.c +++ b/src/tasks/AndroidAppBuilder/Templates/monodroid-coreclr.c @@ -98,23 +98,18 @@ bundle_executable_path (const char* executable, const char* bundle_path, const c } static bool -external_assembly_probe(const char* name, void** data, int64_t* size) +external_assembly_probe(const char* relative_assembly_path, void** data, int64_t* size) { if (g_mapped_files_count >= MAX_MAPPED_COUNT) { - LOG_ERROR("Too many mapped files, cannot map %s", name); + LOG_ERROR("Too many mapped files, cannot map %s", relative_assembly_path); return false; } - // Get just the file name - const char* pos = strrchr(name, '/'); - if (pos != NULL) - name = pos + 1; - // Look in the bundle path where the files were extracted char full_path[1024]; - size_t path_len = strlen(g_bundle_path) + strlen(name) + 1; // +1 for '/' - size_t res = snprintf(full_path, path_len + 1, "%s/%s", g_bundle_path, name); + size_t path_len = strlen(g_bundle_path) + strlen(relative_assembly_path) + 1; // +1 for '/' + size_t res = snprintf(full_path, path_len + 1, "%s/%s", g_bundle_path, relative_assembly_path); if (res < 0 || res != path_len) return false; @@ -137,7 +132,7 @@ external_assembly_probe(const char* name, void** data, int64_t* size) return false; } - LOG_INFO("Mapped %s -> %s", name, full_path); + LOG_INFO("Mapped %s -> %s", relative_assembly_path, full_path); g_mapped_files[g_mapped_files_count] = mapped; g_mapped_file_sizes[g_mapped_files_count] = size_local; g_mapped_files_count++; @@ -182,7 +177,7 @@ mono_droid_execute_assembly (const char* executable_path, void* coreclr_handle, return rv; } -#define PROPERTY_COUNT 3 +#define PROPERTY_COUNT %AppContextPropertyCount% static int mono_droid_runtime_init (const char* executable) @@ -207,17 +202,10 @@ mono_droid_runtime_init (const char* executable) g_host_contract.external_assembly_probe = &external_assembly_probe; const char* appctx_keys[PROPERTY_COUNT]; - appctx_keys[0] = "RUNTIME_IDENTIFIER"; - appctx_keys[1] = "APP_CONTEXT_BASE_DIRECTORY"; - appctx_keys[2] = "HOST_RUNTIME_CONTRACT"; +%AppContextKeys% const char* appctx_values[PROPERTY_COUNT]; - appctx_values[0] = ANDROID_RUNTIME_IDENTIFIER; - appctx_values[1] = g_bundle_path; - - char contract_str[19]; // 0x + 16 hex digits + '\0' - snprintf(contract_str, 19, "0x%zx", (size_t)(&g_host_contract)); - appctx_values[2] = contract_str; +%AppContextValues% LOG_INFO ("Calling coreclr_initialize"); int rv = coreclr_initialize ( diff --git a/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs new file mode 100644 index 00000000000000..37b23b7a06d65d --- /dev/null +++ b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs @@ -0,0 +1,430 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; +using System.Runtime; +using System; +using System.Runtime.CompilerServices; + +using JObject = nint; +using JString = nint; +using JObjectArray = nint; + +namespace MonoDroid.NativeAOT; + +#pragma warning disable IDE0060 // Remove unused parameter +internal static unsafe partial class MonoDroidExports +{ + // void Java_net_dot_MonoRunner_setEnv (JNIEnv* env, jobject thiz, jstring j_key, jstring j_value); + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) }, EntryPoint = "Java_net_dot_MonoRunner_setEnv")] + public static void SetEnv(JNIEnv* env, JObject thiz, JString j_key, JString j_value) + { + string? key = env->GetStringUTFChars(j_key); + string? value = env->GetStringUTFChars(j_value); + if (key != null && value != null) + Environment.SetEnvironmentVariable(key, value); + } + + // int Java_net_dot_MonoRunner_initRuntime (JNIEnv* env, jobject thiz, jstring j_files_dir, jstring j_entryPointLibName, long current_local_time); + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) }, EntryPoint = "Java_net_dot_MonoRunner_initRuntime")] + public static int InitRuntime(JNIEnv* env, JObject thiz, JString j_files_dir, JString j_entryPointLibName, long current_local_time) + { + // The NativeAOT runtime does not need to be initialized, but the crypto library does. + JavaVM* javaVM = env->GetJavaVM(); + AndroidCryptoNative_InitLibraryOnLoad(javaVM, null); + return 0; + } + + [LibraryImport("System.Security.Cryptography.Native.Android")] + internal static partial int AndroidCryptoNative_InitLibraryOnLoad(JavaVM* vm, void* reserved); + + // int Java_net_dot_MonoRunner_execEntryPoint (JNIEnv* env, jobject thiz, jstring j_entryPointLibName, jobjectArray j_args); + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) }, EntryPoint = "Java_net_dot_MonoRunner_execEntryPoint")] + public static int ExecEntryPoint(JNIEnv* env, JObject thiz, JString j_entryPointLibName, JObjectArray j_args) + { + return Program.Main(); + } + + // void Java_net_dot_MonoRunner_freeNativeResources (JNIEnv* env, jobject thiz); + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) }, EntryPoint = "Java_net_dot_MonoRunner_freeNativeResources")] + public static void FreeNativeResources(JNIEnv* env, JObject thiz) + { + // Placeholder for actual implementation + Console.WriteLine("FreeNativeResources start"); + } +} + + +[StructLayout(LayoutKind.Sequential)] +internal unsafe struct JNIEnv +{ + JNINativeInterface* NativeInterface; + public string? GetStringUTFChars(JString str) + { + fixed (JNIEnv* thisptr = &this) + { + byte* chars = NativeInterface->GetStringUTFChars(thisptr, str, out byte isCopy); + if (chars is null) + return null; + + string result = Marshal.PtrToStringUTF8((nint)chars); + if (isCopy != 0) + NativeInterface->ReleaseStringUTFChars(thisptr, str, chars); + + return result; + } + } + + public JavaVM* GetJavaVM() + { + fixed (JNIEnv* thisptr = &this) + { + JavaVM* vm; + int result = NativeInterface->GetJavaVM(thisptr, &vm); + if (result != 0) + return null; + + return vm; + } + } + + [StructLayout(LayoutKind.Sequential)] + unsafe struct JNINativeInterface + { + void* reserved0; + void* reserved1; + void* reserved2; + + void* reserved3; + void* GetVersion; + + void* DefineClass; + void* FindClass; + + void* FromReflectedMethod; + void* FromReflectedField; + + void* ToReflectedMethod; + + void* GetSuperclass; + void* IsAssignableFrom; + + void* ToReflectedField; + + void* Throw; + void* ThrowNew; + void* ExceptionOccurred; + void* ExceptionDescribe; + void* ExceptionClear; + void* FatalError; + + void* PushLocalFrame; + void* PopLocalFrame; + + void* NewGlobalRef; + void* DeleteGlobalRef; + void* DeleteLocalRef; + void* IsSameObject; + void* NewLocalRef; + void* EnsureLocalCapacity; + + void* AllocObject; + void* NewObject; + void* NewObjectV; + void* NewObjectA; + + void* GetObjectClass; + void* IsInstanceOf; + + void* GetMethodID; + + void* CallObjectMethod; + void* CallObjectMethodV; + void* CallObjectMethodA; + + void* CallBooleanMethod; + void* CallBooleanMethodV; + void* CallBooleanMethodA; + + void* CallByteMethod; + void* CallByteMethodV; + void* CallByteMethodA; + + void* CallCharMethod; + void* CallCharMethodV; + void* CallCharMethodA; + + void* CallShortMethod; + void* CallShortMethodV; + void* CallShortMethodA; + + void* CallIntMethod; + void* CallIntMethodV; + void* CallIntMethodA; + + void* CallLongMethod; + void* CallLongMethodV; + void* CallLongMethodA; + + void* CallFloatMethod; + void* CallFloatMethodV; + void* CallFloatMethodA; + + void* CallDoubleMethod; + void* CallDoubleMethodV; + void* CallDoubleMethodA; + + void* CallVoidMethod; + void* CallVoidMethodV; + void* CallVoidMethodA; + + void* CallNonvirtualObjectMethod; + void* CallNonvirtualObjectMethodV; + void* CallNonvirtualObjectMethodA; + + void* CallNonvirtualBooleanMethod; + void* CallNonvirtualBooleanMethodV; + void* CallNonvirtualBooleanMethodA; + + void* CallNonvirtualByteMethod; + void* CallNonvirtualByteMethodV; + void* CallNonvirtualByteMethodA; + + void* CallNonvirtualCharMethod; + void* CallNonvirtualCharMethodV; + void* CallNonvirtualCharMethodA; + + void* CallNonvirtualShortMethod; + void* CallNonvirtualShortMethodV; + void* CallNonvirtualShortMethodA; + + void* CallNonvirtualIntMethod; + void* CallNonvirtualIntMethodV; + void* CallNonvirtualIntMethodA; + + void* CallNonvirtualLongMethod; + void* CallNonvirtualLongMethodV; + void* CallNonvirtualLongMethodA; + + void* CallNonvirtualFloatMethod; + void* CallNonvirtualFloatMethodV; + void* CallNonvirtualFloatMethodA; + + void* CallNonvirtualDoubleMethod; + void* CallNonvirtualDoubleMethodV; + void* CallNonvirtualDoubleMethodA; + + void* CallNonvirtualVoidMethod; + void* CallNonvirtualVoidMethodV; + void* CallNonvirtualVoidMethodA; + + void* GetFieldID; + + void* GetObjectField; + void* GetBooleanField; + void* GetByteField; + void* GetCharField; + void* GetShortField; + void* GetIntField; + void* GetLongField; + void* GetFloatField; + void* GetDoubleField; + + void* SetObjectField; + void* SetBooleanField; + void* SetByteField; + void* SetCharField; + void* SetShortField; + void* SetIntField; + void* SetLongField; + void* SetFloatField; + void* SetDoubleField; + + void* GetStaticMethodID; + + void* CallStaticObjectMethod; + void* CallStaticObjectMethodV; + void* CallStaticObjectMethodA; + + void* CallStaticBooleanMethod; + void* CallStaticBooleanMethodV; + void* CallStaticBooleanMethodA; + + void* CallStaticByteMethod; + void* CallStaticByteMethodV; + void* CallStaticByteMethodA; + + void* CallStaticCharMethod; + void* CallStaticCharMethodV; + void* CallStaticCharMethodA; + + void* CallStaticShortMethod; + void* CallStaticShortMethodV; + void* CallStaticShortMethodA; + + void* CallStaticIntMethod; + void* CallStaticIntMethodV; + void* CallStaticIntMethodA; + + void* CallStaticLongMethod; + void* CallStaticLongMethodV; + void* CallStaticLongMethodA; + + void* CallStaticFloatMethod; + void* CallStaticFloatMethodV; + void* CallStaticFloatMethodA; + + void* CallStaticDoubleMethod; + void* CallStaticDoubleMethodV; + void* CallStaticDoubleMethodA; + + void* CallStaticVoidMethod; + void* CallStaticVoidMethodV; + void* CallStaticVoidMethodA; + + void* GetStaticFieldID; + void* GetStaticObjectField; + void* GetStaticBooleanField; + void* GetStaticByteField; + void* GetStaticCharField; + void* GetStaticShortField; + void* GetStaticIntField; + void* GetStaticLongField; + void* GetStaticFloatField; + void* GetStaticDoubleField; + + void* SetStaticObjectField; + void* SetStaticBooleanField; + void* SetStaticByteField; + void* SetStaticCharField; + void* SetStaticShortField; + void* SetStaticIntField; + void* SetStaticLongField; + void* SetStaticFloatField; + void* SetStaticDoubleField; + + void* NewString; + void* GetStringLength; + void* GetStringChars; + void* ReleaseStringChars; + + void* NewStringUTF; + delegate* unmanaged[Cdecl] GetStringUTFLength; + public delegate* unmanaged[Cdecl] GetStringUTFChars; + public delegate* unmanaged[Cdecl] ReleaseStringUTFChars; + + void* GetArrayLength; + + void* NewObjectArray; + void* GetObjectArrayElement; + void* SetObjectArrayElement; + + void* NewBooleanArray; + void* NewByteArray; + void* NewCharArray; + void* NewShortArray; + void* NewIntArray; + void* NewLongArray; + void* NewFloatArray; + void* NewDoubleArray; + + void* GetBooleanArrayElements; + void* GetByteArrayElements; + void* GetCharArrayElements; + void* GetShortArrayElements; + void* GetIntArrayElements; + void* GetLongArrayElements; + void* GetFloatArrayElements; + void* GetDoubleArrayElements; + + void* ReleaseBooleanArrayElements; + void* ReleaseByteArrayElements; + void* ReleaseCharArrayElements; + void* ReleaseShortArrayElements; + void* ReleaseIntArrayElements; + void* ReleaseLongArrayElements; + void* ReleaseFloatArrayElements; + void* ReleaseDoubleArrayElements; + + void* GetBooleanArrayRegion; + void* GetByteArrayRegion; + void* GetCharArrayRegion; + void* GetShortArrayRegion; + void* GetIntArrayRegion; + void* GetLongArrayRegion; + void* GetFloatArrayRegion; + void* GetDoubleArrayRegion; + + void* SetBooleanArrayRegion; + void* SetByteArrayRegion; + void* SetCharArrayRegion; + void* SetShortArrayRegion; + void* SetIntArrayRegion; + void* SetLongArrayRegion; + void* SetFloatArrayRegion; + void* SetDoubleArrayRegion; + + void* RegisterNatives; + void* UnregisterNatives; + + void* MonitorEnter; + void* MonitorExit; + + public delegate* unmanaged[Cdecl] GetJavaVM; + + void* GetStringRegion; + void* GetStringUTFRegion; + + void* GetPrimitiveArrayCritical; + void* ReleasePrimitiveArrayCritical; + + void* GetStringCritical; + void* ReleaseStringCritical; + + void* NewWeakGlobalRef; + void* DeleteWeakGlobalRef; + + void* ExceptionCheck; + + void* NewDirectByteBuffer; + void* GetDirectBufferAddress; + void* GetDirectBufferCapacity; + + /* New JNI 1.6 Features */ + + void* GetObjectRefType; + + /* Module Features */ + + void* GetModule; + + /* Virtual threads */ + + void* IsVirtualThread; + + /* Large UTF8 Support */ + + void* GetStringUTFLengthAsLong; + }; +} + +[StructLayout(LayoutKind.Sequential)] +internal unsafe struct JavaVM +{ + JNIInvokeInterface* InvokeInterface; + + [StructLayout(LayoutKind.Sequential)] + struct JNIInvokeInterface + { + void* reserved0; + void* reserved1; + void* reserved2; + void* DestroyJavaVM; + void* AttachCurrentThread; + void* DetachCurrentThread; + void* GetEnv; + void* AttachCurrentThreadAsDaemon; + } +} + +#pragma warning restore IDE0060 // Remove unused parameter diff --git a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs index 02b910406c35ed..34fa7cb1674cd8 100644 --- a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs +++ b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs @@ -63,6 +63,11 @@ public string TargetOS [Required] public ITaskItem[] Assemblies { get; set; } = Array.Empty(); + /// + /// The set of environment variables + /// + public ITaskItem[] EnvironmentVariables { get; set; } = Array.Empty(); + /// /// Additional linker arguments that apply to the app being built /// @@ -315,6 +320,12 @@ public override bool Execute() assemblerFilesToLink.Add(nativeDependency); } + List environmentVariables = new List(); + foreach (ITaskItem item in EnvironmentVariables) + { + environmentVariables.Add(item.ItemSpec); + } + List extraLinkerArgs = new List(); foreach (ITaskItem item in ExtraLinkerArguments) { @@ -339,7 +350,7 @@ public override bool Execute() if (GenerateXcodeProject) { XcodeProjectPath = generator.GenerateXCode(ProjectName, MainLibraryFileName, assemblerFiles, assemblerDataFiles, assemblerFilesToLink, extraLinkerArgs, excludes, - AppDir, binDir, MonoRuntimeHeaders, !shouldStaticLink, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, HybridGlobalization, Optimized, EnableRuntimeLogging, EnableAppSandbox, DiagnosticPorts, RuntimeComponents, NativeMainSource, targetRuntime, IsLibraryMode); + AppDir, binDir, MonoRuntimeHeaders, !shouldStaticLink, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, HybridGlobalization, Optimized, EnableRuntimeLogging, EnableAppSandbox, DiagnosticPorts, RuntimeComponents, environmentVariables, NativeMainSource, targetRuntime, IsLibraryMode); if (BuildAppBundle) { @@ -365,7 +376,7 @@ public override bool Execute() else if (GenerateCMakeProject) { generator.GenerateCMake(ProjectName, MainLibraryFileName, assemblerFiles, assemblerDataFiles, assemblerFilesToLink, extraLinkerArgs, excludes, - AppDir, binDir, MonoRuntimeHeaders, !shouldStaticLink, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, HybridGlobalization, Optimized, EnableRuntimeLogging, EnableAppSandbox, DiagnosticPorts, RuntimeComponents, NativeMainSource, targetRuntime, IsLibraryMode); + AppDir, binDir, MonoRuntimeHeaders, !shouldStaticLink, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, HybridGlobalization, Optimized, EnableRuntimeLogging, EnableAppSandbox, DiagnosticPorts, RuntimeComponents, environmentVariables, NativeMainSource, targetRuntime, IsLibraryMode); } return true; diff --git a/src/tasks/AppleAppBuilder/Templates/CMakeLists-librarymode.txt.template b/src/tasks/AppleAppBuilder/Templates/CMakeLists-librarymode.txt.template index bda7c7fb3a30be..c2d4e9c004cde4 100644 --- a/src/tasks/AppleAppBuilder/Templates/CMakeLists-librarymode.txt.template +++ b/src/tasks/AppleAppBuilder/Templates/CMakeLists-librarymode.txt.template @@ -61,6 +61,7 @@ target_link_libraries( %ProjectName% PRIVATE "-framework Foundation" + "-framework Network" "-framework Security" "-framework CryptoKit" "-framework UIKit" diff --git a/src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template b/src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template index 300f2fc5414f4b..850825f2039e0b 100644 --- a/src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template +++ b/src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template @@ -70,6 +70,7 @@ target_link_libraries( %ProjectName% PRIVATE "-framework Foundation" + "-framework Network" "-framework Security" "-framework CryptoKit" "-framework UIKit" diff --git a/src/tasks/AppleAppBuilder/Templates/runtime-coreclr.m b/src/tasks/AppleAppBuilder/Templates/runtime-coreclr.m index 582f041a44d3ee..12009b633f9ebd 100644 --- a/src/tasks/AppleAppBuilder/Templates/runtime-coreclr.m +++ b/src/tasks/AppleAppBuilder/Templates/runtime-coreclr.m @@ -96,6 +96,8 @@ setenv ("DOTNET_DiagnosticPorts", DIAGNOSTIC_PORTS, true); #endif +%EnvVariables% + char **managed_argv; int argi = get_managed_args (&managed_argv); @@ -112,7 +114,7 @@ res = snprintf (icu_dat_path, sizeof (icu_dat_path) - 1, "%s/%s", bundle, "icudt.dat"); #endif assert (res > 0); - + char pinvoke_override_addr [16]; sprintf (pinvoke_override_addr, "%p", &pinvoke_override); @@ -136,7 +138,7 @@ #endif }; - const char* executable = "Program.dll"; + const char* executable = "%EntryPointLibName%"; const char *executablePath = [[[[NSBundle mainBundle] executableURL] path] UTF8String]; unsigned int coreclr_domainId = 0; void *coreclr_handle = NULL; diff --git a/src/tasks/AppleAppBuilder/Xcode.cs b/src/tasks/AppleAppBuilder/Xcode.cs index 23ca12f580a36e..9e0f2e6b32602c 100644 --- a/src/tasks/AppleAppBuilder/Xcode.cs +++ b/src/tasks/AppleAppBuilder/Xcode.cs @@ -189,11 +189,12 @@ public string GenerateXCode( bool enableAppSandbox, string? diagnosticPorts, IEnumerable runtimeComponents, + IEnumerable environmentVariables, string? nativeMainSource = null, TargetRuntime targetRuntime = TargetRuntime.MonoVM, bool isLibraryMode = false) { - var cmakeDirectoryPath = GenerateCMake(projectName, entryPointLib, asmFiles, asmDataFiles, asmLinkFiles, extraLinkerArgs, excludes, workspace, binDir, monoInclude, preferDylibs, useConsoleUiTemplate, forceAOT, forceInterpreter, invariantGlobalization, hybridGlobalization, optimized, enableRuntimeLogging, enableAppSandbox, diagnosticPorts, runtimeComponents, nativeMainSource, targetRuntime, isLibraryMode); + var cmakeDirectoryPath = GenerateCMake(projectName, entryPointLib, asmFiles, asmDataFiles, asmLinkFiles, extraLinkerArgs, excludes, workspace, binDir, monoInclude, preferDylibs, useConsoleUiTemplate, forceAOT, forceInterpreter, invariantGlobalization, hybridGlobalization, optimized, enableRuntimeLogging, enableAppSandbox, diagnosticPorts, runtimeComponents, environmentVariables, nativeMainSource, targetRuntime, isLibraryMode); CreateXcodeProject(projectName, cmakeDirectoryPath); return Path.Combine(binDir, projectName, projectName + ".xcodeproj"); } @@ -262,6 +263,7 @@ public string GenerateCMake( bool enableAppSandbox, string? diagnosticPorts, IEnumerable runtimeComponents, + IEnumerable environmentVariables, string? nativeMainSource = null, TargetRuntime targetRuntime = TargetRuntime.MonoVM, bool isLibraryMode = false) @@ -545,11 +547,23 @@ public string GenerateCMake( File.WriteAllText(Path.Combine(binDir, "CMakeLists.txt"), cmakeLists); - if (needEntitlements) { + string envVariables = string.Empty; + foreach (var item in environmentVariables) + { + var split = item.Split('='); + if (split.Length == 2) + { + envVariables += $"\t\tsetenv (\"{split[0].Trim()}\", \"{split[1].Trim()}\", true);\n"; + } + } + + if (needEntitlements) + { var ent = new StringBuilder(); - foreach ((var key, var value) in entitlements) { - ent.AppendLine ($"{key}"); - ent.AppendLine (value); + foreach ((var key, var value) in entitlements) + { + ent.AppendLine($"{key}"); + ent.AppendLine(value); } string entitlementsTemplate = Utils.GetEmbeddedResource("app.entitlements.template"); File.WriteAllText(Path.Combine(binDir, "app.entitlements"), entitlementsTemplate.Replace("%Entitlements%", ent.ToString())); @@ -597,7 +611,8 @@ public string GenerateCMake( File.WriteAllText(Path.Combine(binDir, "runtime.m"), Utils.GetEmbeddedResource("runtime-coreclr.m") .Replace("//%APPLE_RUNTIME_IDENTIFIER%", RuntimeIdentifier) - .Replace("%EntryPointLibName%", Path.GetFileName(entryPointLib))); + .Replace("%EntryPointLibName%", Path.GetFileName(entryPointLib)) + .Replace("%EnvVariables%", envVariables)); } } diff --git a/src/tasks/Common/JoinedString.cs b/src/tasks/Common/JoinedString.cs index 947d4e0436066f..3eba1e814beb1e 100644 --- a/src/tasks/Common/JoinedString.cs +++ b/src/tasks/Common/JoinedString.cs @@ -118,7 +118,7 @@ public JoinedStringStreamWriter(string path, bool append) : base(path, append) NewLine = CompileTimeNewLine; } -#if NET8_0_OR_GREATER +#if NET #pragma warning disable CA1822 // Mark members as static #pragma warning disable IDE0060 // Remove unused parameter public void Write([InterpolatedStringHandlerArgument("")] StringSegmentStreamWriterHandler builder) @@ -147,7 +147,7 @@ public void WriteLine(IStringSegments list) } } -#if NET8_0_OR_GREATER +#if NET [InterpolatedStringHandler] internal ref struct StringSegmentStreamWriterHandler { diff --git a/src/tasks/LibraryBuilder/Templates/CMakeLists.txt.template b/src/tasks/LibraryBuilder/Templates/CMakeLists.txt.template index 2af12ae8cf85a0..d7d0406de4fe83 100644 --- a/src/tasks/LibraryBuilder/Templates/CMakeLists.txt.template +++ b/src/tasks/LibraryBuilder/Templates/CMakeLists.txt.template @@ -42,6 +42,7 @@ if(TARGETS_ANDROID) elseif(TARGETS_APPLE_MOBILE) set(MOBILE_SYSTEM_LIBS "-framework Foundation" + "-framework Network" "-framework Security" "-framework CryptoKit" "-framework UIKit" diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ArtifactWriter.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ArtifactWriter.cs new file mode 100644 index 00000000000000..331e8b28fb771f --- /dev/null +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ArtifactWriter.cs @@ -0,0 +1,59 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text.Json; +using System.Text.Json.Serialization.Metadata; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace Microsoft.NET.Sdk.WebAssembly; + +public static class ArtifactWriter +{ + public static bool PersistFileIfChanged(TaskLoggingHelper log, T manifest, string artifactPath, JsonTypeInfo serializer) + { + var data = JsonSerializer.SerializeToUtf8Bytes(manifest, serializer); + return PersistFileIfChanged(log, data, artifactPath); + } + + public static bool PersistFileIfChanged(TaskLoggingHelper log, byte[] data, string artifactPath) + { + var newHash = ComputeHash(data); + var fileExists = File.Exists(artifactPath); + var existingManifestHash = fileExists ? ComputeHash(artifactPath) : null; + + if (!fileExists) + { + log.LogMessage(MessageImportance.Low, $"Creating artifact because artifact file '{artifactPath}' does not exist."); + File.WriteAllBytes(artifactPath, data); + return true; + } + else if (!string.Equals(newHash, existingManifestHash, StringComparison.Ordinal)) + { + log.LogMessage(MessageImportance.Low, $"Updating artifact because artifact version '{newHash}' is different from existing artifact hash '{existingManifestHash}'."); + File.WriteAllBytes(artifactPath, data); + return true; + } + else + { + log.LogMessage(MessageImportance.Low, $"Skipping artifact updated because artifact version '{existingManifestHash}' has not changed."); + return false; + } + } + + private static string ComputeHash(string artifactPath) => ComputeHash(File.ReadAllBytes(artifactPath)); + + private static string ComputeHash(byte[] data) + { +#if NET6_0_OR_GREATER + var hash = SHA256.HashData(data); + return Convert.ToBase64String(hash); +#else + using var sha256 = SHA256.Create(); + return Convert.ToBase64String(sha256.ComputeHash(data)); +#endif + } +} diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs index 93ead55e48c113..86b52178de5ccb 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs @@ -87,7 +87,7 @@ public void WriteConfigToFile(BootJsonData config, string outputPath, string? ou output = $"export const config = /*json-start*/{output}/*json-end*/;"; } - File.WriteAllText(outputPath, output); + ArtifactWriter.PersistFileIfChanged(Log, Encoding.UTF8.GetBytes(output), outputPath); } private string ReplaceWithAssert(Regex regex, string content, string replacement, string errorMessage) diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs index 0e888b4bb7eec5..bc78ae7638e9fe 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs @@ -388,7 +388,7 @@ private void WriteBootConfig(string entryAssemblyName) endLineNumber: 0, endColumnNumber: 0, message: message, - string.Join(";", LazyLoadedAssemblies.Select(a => a.ItemSpec))); + string.Join(";", remainingLazyLoadAssemblies.Select(a => a.ItemSpec))); return; } diff --git a/src/tasks/MobileBuildTasks/Android/AndroidProject.cs b/src/tasks/MobileBuildTasks/Android/AndroidProject.cs index b482731671ac22..b3c3ab55ba85da 100644 --- a/src/tasks/MobileBuildTasks/Android/AndroidProject.cs +++ b/src/tasks/MobileBuildTasks/Android/AndroidProject.cs @@ -151,7 +151,7 @@ private static string GetHostOS() return "linux"; } - private static string DetermineAbi(string runtimeIdentifier) => + public static string DetermineAbi(string runtimeIdentifier) => runtimeIdentifier switch { "android-x86" => "x86", diff --git a/src/tasks/TestExclusionListTasks/TestExclusionListTasks.csproj b/src/tasks/TestExclusionListTasks/TestExclusionListTasks.csproj index ffc0d16e0ea031..87270cd0634dd8 100644 --- a/src/tasks/TestExclusionListTasks/TestExclusionListTasks.csproj +++ b/src/tasks/TestExclusionListTasks/TestExclusionListTasks.csproj @@ -6,6 +6,7 @@ false enable $(NoWarn),CA1050,CA1850 + true diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj b/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj index addcf203c6a2eb..77bdf6cafb6789 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj @@ -21,6 +21,7 @@ + diff --git a/src/tasks/installer.tasks/GenerateTestSharedFrameworkDepsFile.cs b/src/tasks/installer.tasks/GenerateTestSharedFrameworkDepsFile.cs index 7785a235d970f2..fd73972ce7ec86 100644 --- a/src/tasks/installer.tasks/GenerateTestSharedFrameworkDepsFile.cs +++ b/src/tasks/installer.tasks/GenerateTestSharedFrameworkDepsFile.cs @@ -50,12 +50,28 @@ public override bool Execute() ".xml" }; - var isAssemblyTofileNames = Directory.EnumerateFiles(SharedFrameworkDirectory) - .Where(file => !ignoredExtensions.Contains(Path.GetExtension(file))) - .ToLookup(file => IsManagedAssembly(file), file => Path.GetFileName(file)); + List runtimeFiles = []; + List nativeFiles = []; - var managedFileNames = isAssemblyTofileNames[true]; - var nativeFileNames = isAssemblyTofileNames[false]; + foreach (string filePath in Directory.EnumerateFiles(SharedFrameworkDirectory)) + { + if (ignoredExtensions.Contains(Path.GetExtension(filePath))) + continue; + + string fileName = Path.GetFileName(filePath); + string fileVersion = FileUtilities.GetFileVersion(filePath)?.ToString() ?? string.Empty; + Version assemblyVersion = FileUtilities.GetAssemblyName(filePath)?.Version; + if (assemblyVersion is null) + { + RuntimeFile nativeFile = new RuntimeFile(fileName, null, fileVersion); + nativeFiles.Add(nativeFile); + } + else + { + RuntimeFile runtimeFile = new RuntimeFile(fileName, assemblyVersion.ToString(), fileVersion); + runtimeFiles.Add(runtimeFile); + } + } var runtimeLibraries = new[] { @@ -64,8 +80,8 @@ public override bool Execute() name: sharedFxName, version: sharedFxVersion, hash: "hash", - runtimeAssemblyGroups: new[] { new RuntimeAssetGroup(string.Empty, managedFileNames.Select(f => $"runtimes/{rid}/lib/{tfm}/{f}")) }, - nativeLibraryGroups: new[] { new RuntimeAssetGroup(string.Empty, nativeFileNames.Select(f => $"runtimes/{rid}/native/{f}")) }, + runtimeAssemblyGroups: new[] { new RuntimeAssetGroup(string.Empty, runtimeFiles) }, + nativeLibraryGroups: new[] { new RuntimeAssetGroup(string.Empty, nativeFiles) }, resourceAssemblies: Enumerable.Empty(), dependencies: Enumerable.Empty(), serviceable: true) @@ -90,22 +106,6 @@ public override bool Execute() return !Log.HasLoggedErrors; } - private static bool IsManagedAssembly(string file) - { - bool result = false; - try - { - using (var peReader = new PEReader(File.OpenRead(file))) - { - result = peReader.HasMetadata && peReader.GetMetadataReader().IsAssembly; - } - } - catch (BadImageFormatException) - { } - - return result; - } - private static IEnumerable GetRuntimeFallbacks(string[] runtimeGraphFiles, string runtime) { RuntimeGraph runtimeGraph = RuntimeGraph.Empty; diff --git a/src/tests/Common/CLRTest.CrossGen.targets b/src/tests/Common/CLRTest.CrossGen.targets index 9f27f49c925194..2742228b6a598f 100644 --- a/src/tests/Common/CLRTest.CrossGen.targets +++ b/src/tests/Common/CLRTest.CrossGen.targets @@ -110,8 +110,7 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then done echo -o:"$__OutputFile" >> "$__ResponseFile" - ## Enable once #114504 is fixed - ## echo -O >> "$__ResponseFile" + echo -O >> "$__ResponseFile" echo --targetarch:$(TargetArchitecture) >> "$__ResponseFile" echo --targetos:$(TargetOS) >> "$__ResponseFile" echo --verify-type-and-field-layout >> "$__ResponseFile" diff --git a/src/tests/Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj b/src/tests/Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj index c8231d40e173e5..6bbebee74d7177 100644 --- a/src/tests/Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj +++ b/src/tests/Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj @@ -16,6 +16,7 @@ + diff --git a/src/tests/Common/CoreCLRTestLibrary/PlatformDetection.cs b/src/tests/Common/CoreCLRTestLibrary/PlatformDetection.cs index f07d33fe94cfa6..fcc4a267dd3caa 100644 --- a/src/tests/Common/CoreCLRTestLibrary/PlatformDetection.cs +++ b/src/tests/Common/CoreCLRTestLibrary/PlatformDetection.cs @@ -63,7 +63,7 @@ public static bool IsNonZeroLowerBoundArraySupported // These platforms have not had their infrastructure updated to support native test assets. public static bool PlatformDoesNotSupportNativeTestAssets => - OperatingSystem.IsIOS() || OperatingSystem.IsTvOS() || OperatingSystem.IsWatchOS() || OperatingSystem.IsAndroid() || OperatingSystem.IsBrowser() || OperatingSystem.IsWasi(); - public static bool IsAppleMobile => OperatingSystem.IsIOS() || OperatingSystem.IsTvOS() || OperatingSystem.IsWatchOS() || OperatingSystem.IsMacCatalyst(); + OperatingSystem.IsIOS() || OperatingSystem.IsTvOS() || OperatingSystem.IsAndroid() || OperatingSystem.IsBrowser() || OperatingSystem.IsWasi(); + public static bool IsAppleMobile => OperatingSystem.IsIOS() || OperatingSystem.IsTvOS() || OperatingSystem.IsMacCatalyst(); } } diff --git a/src/tests/Common/CoreCLRTestLibrary/Vectors.cs b/src/tests/Common/CoreCLRTestLibrary/Vectors.cs new file mode 100644 index 00000000000000..cf4c14934c6152 --- /dev/null +++ b/src/tests/Common/CoreCLRTestLibrary/Vectors.cs @@ -0,0 +1,115 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace TestLibrary +{ + public static class Vectors + { + public static void VectorToArray(ref T[] dst, Vector src) where T : struct + { + Span span = MemoryMarshal.AsBytes(dst.AsSpan()); + MemoryMarshal.Write(span, src); + } + + public static Vector GetRandomVector() + { + long vsize = Unsafe.SizeOf>(); + byte[] data = new byte[vsize]; + for (int i = 0; i < vsize; i++) + { + data[i] = TestLibrary.Generator.GetByte(); + } + return new Vector(data.AsSpan()); + } + + public static Vector GetRandomMask() + { + long vsize = Unsafe.SizeOf>(); + long tsize = Unsafe.SizeOf(); + + byte[] data = new byte[vsize]; + + long count = vsize / tsize; + for (int i = 0; i < count; i++) + { + data[i * tsize] |= (byte)(TestLibrary.Generator.GetByte() & 1); + } + + return new Vector(data.AsSpan()); + } + + public class PinnedVector where T : struct + { + private byte[] buf; + private GCHandle inHandle; + private ulong alignment; + + private void Alloc(T[] data, int alignment) + { + unsafe + { + int sizeOfinArray1 = data.Length * Unsafe.SizeOf(); + if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1) + { + throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}"); + } + + buf = new byte[alignment * 2]; + inHandle = GCHandle.Alloc(buf, GCHandleType.Pinned); + this.alignment = (ulong)alignment; + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(Ptr), ref Unsafe.As(ref data[0]), (uint)sizeOfinArray1); + } + } + + public PinnedVector(T[] data, int alignment) + { + Alloc(data, alignment); + } + + public PinnedVector(Vector inVector, int alignment) + { + long tsize = Unsafe.SizeOf(); + long vsize = Unsafe.SizeOf>(); + long count = vsize / tsize; + T[] data = new T[count]; + VectorToArray(ref data, inVector); + Alloc(data, alignment); + } + + public unsafe void* Ptr => Align((byte*)inHandle.AddrOfPinnedObject().ToPointer(), alignment); + + public void Dispose() + { + inHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + + public Vector Value + { + get + { + unsafe + { + return Unsafe.Read>(Ptr); + } + } + set + { + unsafe + { + Unsafe.Write(Ptr, value); + } + } + } + } + } +} \ No newline at end of file diff --git a/src/tests/Common/GenerateHWIntrinsicTests/Arm/AdvSimdTests.cs b/src/tests/Common/GenerateHWIntrinsicTests/Arm/AdvSimdTests.cs new file mode 100644 index 00000000000000..caf65435ac107a --- /dev/null +++ b/src/tests/Common/GenerateHWIntrinsicTests/Arm/AdvSimdTests.cs @@ -0,0 +1,2738 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +static class AdvSimdTests +{ + + public static (string templateFileName, Dictionary templateData)[] AdvSimdInputs = + { + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "(short)-TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "(sbyte)-TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "-TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Abs(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(short)-TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(sbyte)-TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "-TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Abs(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int16.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int32.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "SByte.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "Int16.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "Int32.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "SByte.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "-TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Abs(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Abs(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Add(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Add(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AddPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAddScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAddScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWidening(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWidening(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Byte_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int16_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int32_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_SByte_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_UInt16_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_UInt32_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Byte_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int16_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int32_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int64_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_SByte_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt16_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt32_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt64_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int64_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt64_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Add(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Add(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Add(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.Add(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Byte_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int16_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int16_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int32_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int32_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int64_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_SByte_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt16_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt16_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt32_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt32_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt64_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.And(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.And(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.And(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.And(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Ceiling_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Ceiling", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Ceiling(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Ceiling_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Ceiling", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Ceiling(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "CeilingScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CeilingScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Ceiling(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "CeilingScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CeilingScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Ceiling(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareTest(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareTest(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundAwayFromZero_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundAwayFromZero", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundAwayFromZero(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundAwayFromZero_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundAwayFromZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundAwayFromZero(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundAwayFromZeroScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundAwayFromZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToInt32RoundAwayFromZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToEven_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToEven(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToEven_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToEven(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToEvenScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToEvenScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToInt32RoundToEven(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToNegativeInfinity_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToNegativeInfinity", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToNegativeInfinity(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToNegativeInfinity_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToNegativeInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToNegativeInfinity(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToNegativeInfinityScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToNegativeInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToInt32RoundToNegativeInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToPositiveInfinity_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToPositiveInfinity", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToPositiveInfinity(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToPositiveInfinity_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToPositiveInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToPositiveInfinity(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToPositiveInfinityScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToPositiveInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToInt32RoundToPositiveInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToZero_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToZero", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToZero(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToZero_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToZero(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToZeroScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToInt32RoundToZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingle_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingle_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingle_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingle_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingleScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingleScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingleScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingleScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundAwayFromZero_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundAwayFromZero", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundAwayFromZero(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundAwayFromZero_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundAwayFromZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundAwayFromZero(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundAwayFromZeroScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundAwayFromZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt32RoundAwayFromZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToEven_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToEven(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToEven_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToEven(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToEvenScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToEvenScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt32RoundToEven(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToNegativeInfinity_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToNegativeInfinity", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToNegativeInfinity(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToNegativeInfinity_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToNegativeInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToNegativeInfinity(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToNegativeInfinityScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToNegativeInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt32RoundToNegativeInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToPositiveInfinity_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToPositiveInfinity", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToPositiveInfinity(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToPositiveInfinity_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToPositiveInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToPositiveInfinity(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToPositiveInfinityScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToPositiveInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt32RoundToPositiveInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToZero_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToZero", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToZero(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToZero_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToZero(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToZeroScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt32RoundToZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "DivideScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DivideScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Divide(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "DivideScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DivideScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_Byte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "8", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_Int16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "4", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_Int32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_SByte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "8", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_Single_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "2", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_UInt16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "4", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_UInt32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "2", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_Byte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "8", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_Int16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "4", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_Int32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_SByte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "8", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_Single_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "2", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_UInt16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "4", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_UInt32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "2", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Byte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_SByte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Single_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Byte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_SByte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Single_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.DoubleToInt64Bits(firstOp[ElementIndex]) != BitConverter.DoubleToInt64Bits(result)"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUnsigned(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUnsigned(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUnsigned(firstOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUnsignedUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUnsignedUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUnsignedUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Floor_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Floor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Floor(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Floor_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Floor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Floor(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "FloorScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FloorScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Floor(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "FloorScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FloorScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Floor(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAdd_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAdd_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddNegatedScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAddNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddNegatedScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAddNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtract_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtract_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractNegatedScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtractNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractNegatedScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtractNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertScalarTest.template", new Dictionary { ["TestName"] = "InsertScalar_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp[0], i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("InsertScalarTest.template", new Dictionary { ["TestName"] = "InsertScalar_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp[0], i) != result[i]"}), + ("InsertScalarTest.template", new Dictionary { ["TestName"] = "InsertScalar_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp[0], i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_Byte_15", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "15", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_SByte_15", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "15", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_Single_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i]))"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.SingleToInt32Bits(result3[i]))"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.SingleToInt32Bits(result3[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input4, ElementIndex, newData[3], i)) != BitConverter.SingleToInt32Bits(result4[i]))"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_Byte", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_Int16", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_Int32", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_SByte", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_Single", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[0]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_UInt16", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_UInt32", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Byte", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Int16", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Int32", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_SByte", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Single", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[0]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_UInt16", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_UInt32", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Byte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Double", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Int16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Int32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Int64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_SByte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Single", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_UInt16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_UInt32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_UInt64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Byte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Double", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Int16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Int32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Int64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_SByte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Single", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_UInt16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_UInt32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_UInt64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2] || result4[i] != input[i + 8 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2] || result4[i] != input[i + 8 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2] || result4[i] != input[i + 4 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2] || result4[i] != input[i + 4 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2] || result4[i] != input[i + 2 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2] || result4[i] != input[i + 2 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2] || result4[i] != input[i + 2 * 3]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipSByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipUShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipUInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipFloat", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipSByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipUShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipUInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipFloat", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipSByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipUShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipUInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipFloat", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Max(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Max(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumber_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumber_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumber(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumber(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Min(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Min(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumber_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumber_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumber(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumber(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[i], right[0])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[i], right[0])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_Int16_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_UInt16_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Int16_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Single_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Single_Vector128_Single_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_UInt16_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingByScalarSaturateHigh_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingByScalarSaturateHigh_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingByScalarSaturateHigh_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingByScalarSaturateHigh_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[0]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingSaturateHigh_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingSaturateHigh_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingSaturateHigh_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingSaturateHigh_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerAndAddSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerAndAddSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerAndSubtractSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerAndSubtractSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerByScalarAndAddSaturate_Vector64_Int16_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerByScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerByScalarAndAddSaturate_Vector64_Int32_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerByScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerByScalarAndSubtractSaturate_Vector64_Int16_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerByScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerByScalarAndSubtractSaturate_Vector64_Int32_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerByScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLowerByScalar_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLowerByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLowerByScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLowerByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[i], right[0]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpperByScalar_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpperByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpperByScalar(left, right[0], i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpperByScalar_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpperByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpperByScalar(left, right[0], i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpperByScalar(firstOp, secondOp[Imm], i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpperByScalar(firstOp, secondOp[Imm], i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpperByScalar(firstOp, secondOp[Imm], i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpperByScalar(firstOp, secondOp[Imm], i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperAndAddSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperAndAddSaturate(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperAndAddSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperAndAddSaturate(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperAndSubtractSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperAndSubtractSaturate(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperAndSubtractSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperAndSubtractSaturate(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperByScalarAndAddSaturate_Vector128_Int16_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperByScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndAddSaturate(firstOp, secondOp, thirdOp[0], i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperByScalarAndAddSaturate_Vector128_Int32_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperByScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndAddSaturate(firstOp, secondOp, thirdOp[0], i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperByScalarAndSubtractSaturate_Vector128_Int16_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperByScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(firstOp, secondOp, thirdOp[0], i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperByScalarAndSubtractSaturate_Vector128_Int32_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperByScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(firstOp, secondOp, thirdOp[0], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndAddSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndAddSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndAddSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndAddSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingByScalarSaturateHigh_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingByScalarSaturateHigh_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingByScalarSaturateHigh_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingByScalarSaturateHigh_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[0]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector64_Int16_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingSaturateHigh_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingSaturateHigh_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingSaturateHigh_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingSaturateHigh_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[i]) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalarBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[0], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalarBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[0], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "-firstOp[i] != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "-firstOp[i] != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "-firstOp[i] != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(-firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "-firstOp[i] != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "-firstOp[i] != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "-firstOp[i] != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(-firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int16.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int32.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "SByte.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "Int16.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "Int32.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "SByte.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(-firstOp[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(-firstOp[0]) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Not(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Not(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Not(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Not(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Or(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Or(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Or(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Or(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWideningUpper(left, right, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x409e8000"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedReciprocalEstimate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x409e8000"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedReciprocalEstimate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x400e8000"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedReciprocalSqrtEstimate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x400e8000"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedReciprocalSqrtEstimate(firstOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStep_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStep", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPReciprocalSqrtStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStep_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPReciprocalSqrtStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStep_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPReciprocalStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStep_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPReciprocalStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement32_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement32", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement32(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement32_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement32", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement32(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement32_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement32(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement32_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement32(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundAwayFromZero_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundAwayFromZero", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundAwayFromZero(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundAwayFromZero_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundAwayFromZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundAwayFromZero(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundAwayFromZeroScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundAwayFromZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundAwayFromZero(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundAwayFromZeroScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundAwayFromZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundAwayFromZero(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToNearest_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNearest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToNearest(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToNearest_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNearest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToNearest(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundToNearestScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNearestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToNearest(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundToNearestScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNearestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToNearest(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToNegativeInfinity_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNegativeInfinity", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToNegativeInfinity(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToNegativeInfinity_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNegativeInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToNegativeInfinity(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundToNegativeInfinityScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNegativeInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToNegativeInfinity(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundToNegativeInfinityScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNegativeInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToNegativeInfinity(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToPositiveInfinity_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToPositiveInfinity", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToPositiveInfinity(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToPositiveInfinity_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToPositiveInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToPositiveInfinity(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundToPositiveInfinityScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToPositiveInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToPositiveInfinity(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundToPositiveInfinityScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToPositiveInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToPositiveInfinity(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToZero_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToZero", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToZero(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToZero_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToZero(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToZeroScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToZero(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToZeroScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToZero(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRounded(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftArithmetic(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "32", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsertScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftLeftAndInsert(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsertScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftLeftAndInsert(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogical(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogical(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRounded(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRounded(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogical(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogical(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "32", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsertScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftRightAndInsert(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsertScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftRightAndInsert(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAddScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAddScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmetic(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAddScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAddScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAddScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAddScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogical(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogical(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "SqrtScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SqrtScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Sqrt(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "SqrtScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SqrtScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Sqrt(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Byte_15", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "15", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.DoubleToInt64Bits(firstOp[ElementIndex]) != BitConverter.DoubleToInt64Bits(result)"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_SByte_15", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "15", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Single_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "3", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Subtract(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Subtract(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Subtract(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Subtract(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Subtract(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.Subtract(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Byte_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int16_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int16_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int32_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int32_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int64_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_SByte_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt16_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt16_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt32_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt32_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt64_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), + ("VectorLookup_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookup2_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 40)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), + ("VectorLookup_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookup2_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 40)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), + ("VectorLookup_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookup3_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 60)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), + ("VectorLookup_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookup3_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 60)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), + ("VectorLookup_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookup4_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 80)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), + ("VectorLookup_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookup4_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 80)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), + ("VectorLookupExtension_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension2_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 40)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), + ("VectorLookupExtension_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension2_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 40)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), + ("VectorLookupExtension_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension3_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 60)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), + ("VectorLookupExtension_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension3_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 60)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), + ("VectorLookupExtension_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension4_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 80)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), + ("VectorLookupExtension_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension4_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 80)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Xor(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Xor(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Xor(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Xor(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}) + }; + + public static (string templateFileName, Dictionary templateData)[] AdvSimd_Arm64Inputs = + { + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "-TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Abs(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "Int64.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int16.MinValue", ["ValidateFirstResult"] = "Helpers.AbsSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int32.MinValue", ["ValidateFirstResult"] = "Helpers.AbsSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int64.MinValue", ["ValidateFirstResult"] = "Helpers.AbsSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "SByte.MinValue", ["ValidateFirstResult"] = "Helpers.AbsSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Abs(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteDifference(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Add(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AddPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AddPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AddPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AddPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.AddPairwise(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.AddPairwise(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Byte_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int16_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int32_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_SByte_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_UInt16_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_UInt32_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Byte_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int16_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int32_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int64_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_SByte_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt16_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt32_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt64_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Byte_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Byte_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int16_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int16_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int32_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int32_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int64_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_SByte_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_SByte_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt16_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt16_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt32_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt32_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt64_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Ceiling_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Ceiling", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Ceiling(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareTest(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareTestScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareTest(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareTestScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareTest(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareTestScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareTest(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToDouble_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ConvertToDouble(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToDouble_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ConvertToDouble(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToDouble_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ConvertToDouble(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToDoubleScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToDoubleScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ConvertToDouble(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToDoubleScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToDoubleScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ConvertToDouble(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToDoubleUpper_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToDoubleUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ConvertToDoubleUpper(firstOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundAwayFromZero_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundAwayFromZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToInt64RoundAwayFromZero(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundAwayFromZeroScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundAwayFromZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToInt64RoundAwayFromZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToEven_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToInt64RoundToEven(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToEvenScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToEvenScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToInt64RoundToEven(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToNegativeInfinity_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToNegativeInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToInt64RoundToNegativeInfinity(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToNegativeInfinityScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToNegativeInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToInt64RoundToNegativeInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToPositiveInfinity_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToPositiveInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToInt64RoundToPositiveInfinity(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToPositiveInfinityScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToPositiveInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToInt64RoundToPositiveInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToZero_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToInt64RoundToZero(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToZeroScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToInt64RoundToZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingleLower_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingleLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingleRoundToOddLower_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingleRoundToOddLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3FF9E427C7C5260FL)", ["ValidateIterResult"] = "0x3FCF213F != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingleRoundToOddUpper_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingleRoundToOddUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3FCF213E)",["NextValueOp2"] = "BitConverter.Int64BitsToDouble(0x3FF9E427C7C5260FL)", ["ValidateIterResult"] = "(i < 2 ? 0x3FCF213E : 0x3FCF213F) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingleUpper_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingleUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingleUpper(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundAwayFromZero_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundAwayFromZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToUInt64RoundAwayFromZero(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundAwayFromZeroScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundAwayFromZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt64RoundAwayFromZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToEven_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToUInt64RoundToEven(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToEvenScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToEvenScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt64RoundToEven(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToNegativeInfinity_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToNegativeInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToUInt64RoundToNegativeInfinity(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToNegativeInfinityScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToNegativeInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt64RoundToNegativeInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToPositiveInfinity_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToPositiveInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToUInt64RoundToPositiveInfinity(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToPositiveInfinityScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToPositiveInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt64RoundToPositiveInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToZero_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToUInt64RoundToZero(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToZeroScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt64RoundToZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Divide(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Int64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Double_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int64_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt64_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturateUnsigned(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturateUnsigned(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturateUnsigned(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Floor_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Floor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Floor(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAdd_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddByScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddByScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddByScalar_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddBySelectedScalar_Vector128_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddBySelectedScalar_Vector128_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddBySelectedScalar_Vector128_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalarBySelectedScalar_Vector64_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalarBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalarBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtract_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractByScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractByScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractByScalar_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractBySelectedScalar_Vector128_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractBySelectedScalar_Vector128_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractBySelectedScalar_Vector128_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalarBySelectedScalar_Vector64_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalarBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalarBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Byte_7_Vector64_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Byte_7_Vector128_Byte_15", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "15", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Int16_3_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Int16_3_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Int32_1_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Int32_1_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_SByte_7_Vector64_SByte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_SByte_7_Vector128_SByte_15", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "15", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Single_1_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Single_1_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_UInt16_3_Vector64_UInt16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_UInt16_3_Vector128_UInt16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_UInt32_1_Vector64_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_UInt32_1_Vector128_UInt32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Byte_15_Vector64_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex1"] = "15", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Byte_15_Vector128_Byte_15", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex1"] = "15", ["ElementIndex2"] = "15", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Double_1_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Int16_7_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Int16_7_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Int32_3_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Int32_3_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Int64_1_Vector128_Int64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_SByte_15_Vector64_SByte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex1"] = "15", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_SByte_15_Vector128_SByte_15", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex1"] = "15", ["ElementIndex2"] = "15", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Single_3_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Single_3_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_UInt16_7_Vector64_UInt16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_UInt16_7_Vector128_UInt16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_UInt32_3_Vector64_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_UInt32_3_Vector128_UInt32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_UInt64_1_Vector128_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Double", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[0]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_SByte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_UInt16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Int64_0", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "0", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i]))"}), + ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(BitConverter.DoubleToInt64Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.DoubleToInt64Bits(result1[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.DoubleToInt64Bits(result2[i]))"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_SByte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_UInt16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Int64_0", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "0", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.SingleToInt32Bits(result3[i]))"}), + ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(BitConverter.DoubleToInt64Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.DoubleToInt64Bits(result1[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.DoubleToInt64Bits(result2[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.DoubleToInt64Bits(result3[i]))"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_SByte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_UInt16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Int64_0", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "0", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.SingleToInt32Bits(result3[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input4, ElementIndex, newData[3], i)) != BitConverter.SingleToInt32Bits(result4[i]))"}), + ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(BitConverter.DoubleToInt64Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.DoubleToInt64Bits(result1[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.DoubleToInt64Bits(result2[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.DoubleToInt64Bits(result3[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input4, ElementIndex, newData[3], i)) != BitConverter.DoubleToInt64Bits(result4[i]))"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairScalarVector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairScalarVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.LoadPairScalar(firstOp, i) != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairScalarVector64_Single", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairScalarVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.LoadPairScalar(firstOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairScalarVector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairScalarVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.LoadPairScalar(firstOp, i) != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairScalarVector64NonTemporal_Int32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairScalarVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.LoadPairScalar(firstOp, i) != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairScalarVector64NonTemporal_Single", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairScalarVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.LoadPairScalar(firstOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairScalarVector64NonTemporal_UInt32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairScalarVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.LoadPairScalar(firstOp, i) != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_Double", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_Single", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_Byte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_Double", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_Int16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_Int32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_Int64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_SByte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_Single", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_UInt16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_UInt32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_UInt64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_Double", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_Single", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_Byte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_Double", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_Int16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_Int32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_Int64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_SByte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_Single", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_UInt16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_UInt32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_UInt64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 16]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 16]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 16] || result3[i] != input[i + 16 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 16] || result3[i] != input[i + 16 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 16] || result3[i] != input[i + 16 * 2] || result4[i] != input[i + 16 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 16] || result3[i] != input[i + 16 * 2] || result4[i] != input[i + 16 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2] || result4[i] != input[i + 8 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2] || result4[i] != input[i + 8 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2] || result4[i] != input[i + 4 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2] || result4[i] != input[i + 4 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2] || result4[i] != input[i + 2 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2] || result4[i] != input[i + 2 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2] || result4[i] != input[i + 4 * 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2] || result4[i] != input[i + 2 * 3]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipSByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipUShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipUInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipUInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipFloat", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipDouble", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipSByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipUShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipUInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipUInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipFloat", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipDouble", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipSByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipUShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipUInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipUInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipFloat", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipDouble", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Max(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumber_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumber(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxNumberAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwise_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumberPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumberPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Max(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Max(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Min(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumber_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumber(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinNumberAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwise_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumberPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumberPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Min(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Min(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(left[i], right[0])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingSaturateHighScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingSaturateHighScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningAndAddSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningAndAddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningAndAddSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningAndAddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningAndSubtractSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningAndSubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningAndSubtractSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningAndSubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtended_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtended_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtended_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedByScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(left[i], right[0])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedBySelectedScalar_Vector128_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(firstOp[i], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalarBySelectedScalar_Vector64_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(firstOp[0], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalarBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(firstOp[0], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalarBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(firstOp[0], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingSaturateHighScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingSaturateHighScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalarBySelectedScalar_Vector64_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(firstOp[0], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(-firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "-firstOp[i] != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "Int64.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int16.MinValue", ["ValidateFirstResult"] = "Helpers.NegateSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int32.MinValue", ["ValidateFirstResult"] = "Helpers.NegateSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int64.MinValue", ["ValidateFirstResult"] = "Helpers.NegateSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "SByte.MinValue", ["ValidateFirstResult"] = "Helpers.NegateSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "-firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0x4013d00000000000"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimateScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != 0x4013d00000000000", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimateScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != 0x409e8000", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalExponentScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalExponentScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != 0x4030000000000000", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalExponentScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalExponentScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != 0x41800000", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateIterResult"] = " BitConverter.DoubleToInt64Bits(result[i]) != 0x4001d00000000000"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimateScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != 0x4001d00000000000", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimateScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != 0x400e8000", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStep_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPReciprocalSqrtStepFused(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStepScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPReciprocalSqrtStepFused(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStepScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPReciprocalSqrtStepFused(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStep_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPReciprocalStepFused(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStepScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPReciprocalStepFused(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStepScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPReciprocalStepFused(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundAwayFromZero_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundAwayFromZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundAwayFromZero(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToNearest_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNearest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToNearest(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToNegativeInfinity_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNegativeInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToNegativeInfinity(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToPositiveInfinity_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToPositiveInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToPositiveInfinity(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToZero_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToZero(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_Int16_15", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "15", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_Int32_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "31", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_SByte_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "5", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "5", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "15", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "31", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "15", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "31", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "15", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "31", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "5", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sqrt_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Sqrt(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sqrt_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Sqrt(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sqrt_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Sqrt(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairScalar", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ConcatScalar(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairScalar", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConcatScalar(firstOp, secondOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairScalar", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ConcatScalar(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairScalarNonTemporal_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairScalarNonTemporal", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ConcatScalar(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairScalarNonTemporal_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairScalarNonTemporal", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConcatScalar(firstOp, secondOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairScalarNonTemporal_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairScalarNonTemporal", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ConcatScalar(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Subtract(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), + ("VectorLookup_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookup2_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 40)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), + ("VectorLookup_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookup2_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 40)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), + ("VectorLookup_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookup3_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 60)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), + ("VectorLookup_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookup3_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 60)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), + ("VectorLookup_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookup4_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 80)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), + ("VectorLookup_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookup4_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 80)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), + ("VectorLookupExtension_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension2_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 40)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), + ("VectorLookupExtension_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension2_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 40)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), + ("VectorLookupExtension_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension3_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 60)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), + ("VectorLookupExtension_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension3_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 60)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), + ("VectorLookupExtension_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension4_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 80)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), + ("VectorLookupExtension_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension4_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 80)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + }; + + public static (string templateFileName, Dictionary templateData)[] AesInputs = + { + ("AesBinOpTest.template", new Dictionary { ["TestName"] = "Decrypt_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "Decrypt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["KeySize"] = "16", ["Key"] = "{0xFF, 0xDD, 0xBB, 0x99, 0x77, 0x55, 0x33, 0x11, 0xEE, 0xCC, 0xAA, 0x88, 0x66, 0x44, 0x22, 0x00}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0x7C, 0x99, 0x02, 0x7C, 0x7C, 0x7C, 0xFE, 0x86, 0xE3, 0x7C, 0x7C, 0x97, 0xC9, 0x94, 0x7C, 0x7C}"}), + ("AesBinOpTest.template", new Dictionary { ["TestName"] = "Encrypt_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "Encrypt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["KeySize"] = "16", ["Key"] = "{0xFF, 0xDD, 0xBB, 0x99, 0x77, 0x55, 0x33, 0x11, 0xEE, 0xCC, 0xAA, 0x88, 0x66, 0x44, 0x22, 0x00}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xCA, 0xCA, 0xF5, 0xC4, 0xCA, 0x93, 0xEA, 0xCA, 0x82, 0x28, 0xCA, 0xCA, 0xC1, 0xCA, 0xCA, 0x1B}"}), + ("AesUnOpTest.template", new Dictionary { ["TestName"] = "InverseMixColumns_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "InverseMixColumns", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xA0, 0x0A, 0xE4, 0x4E, 0x28, 0x82, 0x6C, 0xC6, 0x55, 0x00, 0x77, 0x22, 0x11, 0x44, 0x33, 0x66}"}), + ("AesUnOpTest.template", new Dictionary { ["TestName"] = "MixColumns_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "MixColumns", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xAB, 0x01, 0xEF, 0x45, 0x23, 0x89, 0x67, 0xCD, 0xDD, 0x88, 0xFF, 0xAA, 0x99, 0xCC, 0xBB, 0xEE}"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_Int64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[0], right[0]) != result[1]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_UInt64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[0], right[0]) != result[1]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_Int64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[1], right[1]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[1], right[1]) != result[1]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_UInt64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[1], right[1]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[1], right[1]) != result[1]"}) + }; + + public static (string templateFileName, Dictionary templateData)[] DpInputs = + { + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "DotProduct_Vector64_Int32", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "DotProduct_Vector64_UInt32", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "DotProduct_Vector128_Int32", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "DotProduct_Vector128_UInt32", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * i) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector64_Int32_Vector64_SByte_1", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector64_Int32_Vector128_SByte_3", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector64_UInt32_Vector64_Byte_1", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector64_UInt32_Vector128_Byte_3", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector128_Int32_Vector64_SByte_1", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector128_Int32_Vector128_SByte_3", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector128_UInt32_Vector64_Byte_1", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector128_UInt32_Vector128_Byte_3", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), + }; + + public static (string templateFileName, Dictionary templateData)[] RdmInputs = + { + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndAddSaturateHigh_Vector64_Int16", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndAddSaturateHigh_Vector64_Int32", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndAddSaturateHigh_Vector128_Int16", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndAddSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndAddSaturateHigh_Vector128_Int32", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndAddSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh_Vector64_Int16", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh_Vector64_Int32", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh_Vector128_Int16", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh_Vector128_Int32", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), + }; + + public static (string templateFileName, Dictionary templateData)[] Rdm_Arm64Inputs = + { + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndAddSaturateHighScalar_Vector64_Int16", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndAddSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndAddSaturateHighScalar_Vector64_Int32", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndAddSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndSubtractSaturateHighScalar_Vector64_Int16", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndSubtractSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndSubtractSaturateHighScalar_Vector64_Int32", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndSubtractSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + }; + + public static (string templateFileName, Dictionary templateData)[] Sha1Inputs = + { + ("SecureHashUnOpTest.template", new Dictionary { ["TestName"] = "FixedRotate_Vector64_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "FixedRotate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "0x00112233", ["ExpectedResult"] = "{0xC004488C, 0x0, 0x0, 0x0}"}), + ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "HashUpdateChoose_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdateChoose", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x27A38C6D, 0xEFEFCA67, 0xDB4E8169, 0x73C91E71}"}), + ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "HashUpdateMajority_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdateMajority", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0xEC691B1D, 0xF21410C7, 0x9B52C9F6, 0x73C91E71}"}), + ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "HashUpdateParity_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdateParity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0xDAB2AF34, 0xFF990D18, 0xCB4F938C, 0x73C91E71}"}), + ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "ScheduleUpdate0_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate0", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x8899AABB, 0x8899AABB, 0xCCDDEEFF, 0xCCDDEEFF}"}), + ("SecureHashBinOpTest.template", new Dictionary { ["TestName"] = "ScheduleUpdate1_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate1", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["ExpectedResult"] = "{0x88888888, 0x88888888, 0x88888888, 0x11335577}"}), + }; + + public static (string templateFileName, Dictionary templateData)[] Sha256Inputs = + { + ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "HashUpdate1_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdate1", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x3D22118E, 0x987CA5FB, 0x54F4E477, 0xDFB50278}"}), + ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "HashUpdate2_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdate2", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0xFFD38634, 0x2A33F83F, 0x55A1BE45, 0x5002B4C4}"}), + ("SecureHashBinOpTest.template", new Dictionary { ["TestName"] = "ScheduleUpdate0_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate0", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["ExpectedResult"] = "{0x2E9FE839, 0x2E9FE839, 0x2E9FE839, 0xBFB0F94A}"}), + ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "ScheduleUpdate1_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate1", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x248F1BDF, 0x248F1BDF, 0xB303DDBA, 0xF74821FE}"}), + }; +} diff --git a/src/tests/Common/GenerateHWIntrinsicTests/Arm/BaseTests.cs b/src/tests/Common/GenerateHWIntrinsicTests/Arm/BaseTests.cs new file mode 100644 index 00000000000000..4e76a061ad6a75 --- /dev/null +++ b/src/tests/Common/GenerateHWIntrinsicTests/Arm/BaseTests.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +static class BaseTests +{ + public static (string templateFileName, Dictionary templateData)[] ArmBaseInputs = + { + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Int32", ["Isa"] = "ArmBase", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 31; (((uint)data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_UInt32", ["Isa"] = "ArmBase", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 31; ((data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Int32", ["Isa"] = "ArmBase", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_UInt32", ["Isa"] = "ArmBase", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), + }; + + public static (string templateFileName, Dictionary templateData)[] ArmBase_Arm64Inputs = + { + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Int32", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingSignCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 30; (((uint)data >> index) & 1) == (((uint)data >> 31) & 1); index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingSignCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 62; (((ulong)data >> index) & 1) == (((ulong)data >> 63) & 1); index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 63; (((ulong)data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_UInt64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "UInt64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 63; ((data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyHigh_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "MultiplyHigh", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "-TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "isUnexpectedResult = Helpers.MultiplyHigh(left, right) != result;" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyHigh_UInt64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "MultiplyHigh", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "isUnexpectedResult = Helpers.MultiplyHigh(left, right) != result;" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_UInt64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), + }; + + public static (string templateFileName, Dictionary templateData)[] Crc32Inputs = + { + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_Byte", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20", ["ValidateResult"] = "uint expectedResult = 0x169330BA; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_UInt16", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x2019", ["ValidateResult"] = "uint expectedResult = 0x1E4864D0; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_UInt32", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113", ["ValidateResult"] = "uint expectedResult = 0x219D9805; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_Byte", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20", ["ValidateResult"] = "uint expectedResult = 0x8D3F2270; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_UInt16", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x2019", ["ValidateResult"] = "uint expectedResult = 0x9F50ACBD; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_UInt32", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113", ["ValidateResult"] = "uint expectedResult = 0x78F34758; isUnexpectedResult = (expectedResult != result);" }), + }; + + public static (string templateFileName, Dictionary templateData)[] Crc32_Arm64Inputs = + { + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_UInt64", ["Isa"] = "Crc32.Arm64", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt64", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113110219UL", ["ValidateResult"] = "uint expectedResult = 0xEFAAAB74; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_UInt64", ["Isa"] = "Crc32.Arm64", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt64", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113110219UL", ["ValidateResult"] = "uint expectedResult = 0x6295C71A; isUnexpectedResult = (expectedResult != result);" }), + }; +} diff --git a/src/tests/Common/GenerateHWIntrinsicTests/Arm/Sve2Tests.cs b/src/tests/Common/GenerateHWIntrinsicTests/Arm/Sve2Tests.cs new file mode 100644 index 00000000000000..bfe40fee207c69 --- /dev/null +++ b/src/tests/Common/GenerateHWIntrinsicTests/Arm/Sve2Tests.cs @@ -0,0 +1,953 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +static class Sve2Tests +{ + public static (string templateFileName, Dictionary templateData)[] Sve2Inputs = + { + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsSaturate_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.AbsSaturate(firstOp[i])", ["GetIterResult"] = "Helpers.AbsSaturate(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsSaturate_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.AbsSaturate(firstOp[i])", ["GetIterResult"] = "Helpers.AbsSaturate(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsSaturate_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.AbsSaturate(firstOp[i])", ["GetIterResult"] = "Helpers.AbsSaturate(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsSaturate_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.AbsSaturate(firstOp[i])", ["GetIterResult"] = "Helpers.AbsSaturate(leftOp[i])"}), + + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(SByte) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["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"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["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"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["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"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(Byte) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["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"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["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"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), + + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddEven_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddEven", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddEven_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddEven", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddEven_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddEven", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddEven_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddEven", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddEven_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddEven", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddEven_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddEven", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i)"}), + + ("SveVecTernOpFirstArgTest.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddOdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddOdd", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddOdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddOdd", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddOdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddOdd", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddOdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddOdd", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddOdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddOdd", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddOdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddOdd", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i)"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningEven_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningEven(left, right, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AbsoluteDifferenceWideningEven(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningEven_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningEven", ["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.AbsoluteDifferenceWideningEven(left, right, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AbsoluteDifferenceWideningEven(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningEven_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningEven", ["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.AbsoluteDifferenceWideningEven(left, right, i) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AbsoluteDifferenceWideningEven(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningEven_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningEven(left, right, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AbsoluteDifferenceWideningEven(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningEven_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningEven(left, right, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AbsoluteDifferenceWideningEven(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningEven_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningEven(left, right, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AbsoluteDifferenceWideningEven(left, right, i)"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningOdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningOdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningOdd", ["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.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningOdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningOdd", ["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.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningOdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningOdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningOdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), + + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningEven_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningEven", ["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"] = "Helpers.AddCarryWideningEven(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddCarryWideningEven(first, second, third, i)"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningEven_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningEven", ["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"] = "Helpers.AddCarryWideningEven(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddCarryWideningEven(first, second, third, i)"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningOdd_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningOdd", ["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"] = "Helpers.AddCarryWideningOdd(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddCarryWideningOdd(first, second, third, i)"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningOdd_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningOdd", ["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"] = "Helpers.AddCarryWideningOdd(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddCarryWideningOdd(first, second, third, i)"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingEven", ["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.AddHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "(SByte) Helpers.AddHighNarrowingEven(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingEven", ["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.AddHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddHighNarrowingEven(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingEven", ["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.AddHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddHighNarrowingEven(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingEven", ["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.AddHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "(Byte) Helpers.AddHighNarrowingEven(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingEven", ["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.AddHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddHighNarrowingEven(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingEven", ["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.AddHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddHighNarrowingEven(left, right, i)"}), + + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingOdd", ["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.AddHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(SByte) Helpers.AddHighNarrowingOdd(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingOdd", ["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.AddHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddHighNarrowingOdd(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingOdd", ["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.AddHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddHighNarrowingOdd(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingOdd", ["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.AddHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(Byte) Helpers.AddHighNarrowingOdd(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingOdd", ["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.AddHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddHighNarrowingOdd(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingOdd", ["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.AddHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddHighNarrowingOdd(first, second, third, i)"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_float", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(Single) Helpers.AddPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_double", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(Double) Helpers.AddPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(SByte) Helpers.AddPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(Byte) Helpers.AddPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddPairwiseSve(left, right, i)"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddPairwiseWideningAndAdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWideningAndAdd", ["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.AddPairwiseWideningAndAdd(left, right, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddPairwiseWideningAndAdd(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddPairwiseWideningAndAdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWideningAndAdd", ["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.AddPairwiseWideningAndAdd(left, right, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddPairwiseWideningAndAdd(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddPairwiseWideningAndAdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWideningAndAdd", ["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.AddPairwiseWideningAndAdd(left, right, i) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddPairwiseWideningAndAdd(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddPairwiseWideningAndAdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddPairwiseWideningAndAdd(left, right, i)"}), + ("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.AddPairwiseWideningAndAdd(left, right, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddPairwiseWideningAndAdd(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.AddPairwiseWideningAndAdd(left, right, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddPairwiseWideningAndAdd(left, right, i)"}), + + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_sbyte_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["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()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_sbyte_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["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()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_short_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_short_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_int_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_int_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_long_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_long_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_byte_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["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()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_byte_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["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()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_ushort_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_ushort_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_uint_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_uint_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_ulong_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_AddRotateComplex_ulong_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + + ("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])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["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.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["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.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Byte) Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["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.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["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.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["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.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddSaturate(left[i], right[i])"}), + + ("SveVecImmBinOpVecTest.template", new Dictionary {["TestName"] = "Sve2_AddSaturateRotateComplex_sbyte_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddSaturateRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddSaturateRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary {["TestName"] = "Sve2_AddSaturateRotateComplex_sbyte_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddSaturateRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddSaturateRotateComplex(first, second, Imm)"}), + + ("SveVecImmBinOpVecTest.template", new Dictionary {["TestName"] = "Sve2_AddSaturateRotateComplex_short_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateRotateComplex", ["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()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddSaturateRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddSaturateRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary {["TestName"] = "Sve2_AddSaturateRotateComplex_short_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateRotateComplex", ["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()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddSaturateRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddSaturateRotateComplex(first, second, Imm)"}), + + ("SveVecImmBinOpVecTest.template", new Dictionary {["TestName"] = "Sve2_AddSaturateRotateComplex_int_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateRotateComplex", ["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()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddSaturateRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddSaturateRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary {["TestName"] = "Sve2_AddSaturateRotateComplex_int_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateRotateComplex", ["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()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddSaturateRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddSaturateRotateComplex(first, second, Imm)"}), + + ("SveVecImmBinOpVecTest.template", new Dictionary {["TestName"] = "Sve2_AddSaturateRotateComplex_long_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateRotateComplex", ["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()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddSaturateRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddSaturateRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary {["TestName"] = "Sve2_AddSaturateRotateComplex_long_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateRotateComplex", ["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()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ConvertFunc"] = "", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddSaturateRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddSaturateRotateComplex(first, second, Imm)"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithSignedAddend_byte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithSignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Byte) Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithSignedAddend_ushort_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithSignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithSignedAddend_uint_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithSignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithSignedAddend_ulong_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithSignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddSaturate(left[i], right[i])"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithUnsignedAddend_sbyte_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithUnsignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(SByte) Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithUnsignedAddend_short_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithUnsignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithUnsignedAddend_int_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithUnsignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithUnsignedAddend_long_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithUnsignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddSaturate(left[i], right[i])"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEven_short_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEven", ["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.AddWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddWidening(left[i], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEven_int_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEven", ["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.AddWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddWidening(left[i], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEven_long_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEven", ["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.AddWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddWidening(left[i], right[i * 2])",}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEven_ushort_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i * 2])!= result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddWidening(left[i], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEven_uint_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEven", ["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.AddWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddWidening(left[i], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEven_ulong_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEven", ["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.AddWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddWidening(left[i], right[i * 2])"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEven_short_sbyte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddWidening(left[i * 2], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEven_int_short_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEven", ["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.AddWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddWidening(left[i * 2], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEven_long_int_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEven", ["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.AddWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddWidening(left[i * 2], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEven_ushort_byte_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddWidening(left[i * 2], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEven_uint_ushort_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddWidening(left[i * 2], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEven_ulong_uint_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddWidening(left[i * 2], right[i * 2])"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEvenOdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddWidening(left[i * 2], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEvenOdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEvenOdd", ["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.AddWidening(left[i * 2], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddWidening(left[i * 2], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningEvenOdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningEvenOdd", ["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.AddWidening(left[i * 2], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddWidening(left[i * 2], right[i * 2 + 1])"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningOdd_short_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningOdd", ["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.AddWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddWidening(left[i], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningOdd_int_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningOdd", ["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.AddWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddWidening(left[i], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningOdd_long_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningOdd", ["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.AddWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddWidening(left[i], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningOdd_ushort_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddWidening(left[i], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningOdd_uint_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningOdd", ["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.AddWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddWidening(left[i], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningOdd_ulong_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningOdd", ["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.AddWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddWidening(left[i], right[i * 2 + 1])"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningOdd_short_sbyte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningOdd_int_short_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningOdd", ["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.AddWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningOdd_long_int_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningOdd", ["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.AddWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningOdd_ushort_byte_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningOdd_uint_ushort_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningOdd_ulong_uint_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1])"}), + + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(SByte) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["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] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Int16) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["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] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Int32) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Int64) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["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] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Byte) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(UInt16)(firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["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] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(UInt32)(firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["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] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(UInt64)(firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), + + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["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.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["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.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["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.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["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.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["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.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["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.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["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.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["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.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["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.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["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.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["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.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["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.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["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.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["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.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["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.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + + ("SveSimpleVecOpDiffRetTypeTest.template", new Dictionary {["TestName"] = "Sve2_ConvertToDoubleOdd_double_float", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ConvertToDoubleOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.ConvertToDouble(firstOp[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.ConvertToDouble(left[i * 2 + 1])"}), + + ("SveSimpleVecOpDiffRetTypeTest.template", new Dictionary {["TestName"] = "Sve2_ConvertToSingleEvenRoundToOdd_float_double", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ConvertToSingleEvenRoundToOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.ConvertToSingleEvenRoundToOdd(firstOp, i) != result[i]", ["GetIterResult"] = "Helpers.ConvertToSingleEvenRoundToOdd(left, i)"}), + + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplex_int_sbyte_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm)"}), + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplex_int_sbyte_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm)"}), + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplex_int_sbyte_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm)"}), + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplex_int_sbyte_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm)"}), + + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplex_long_short_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm)"}), + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplex_long_short_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm)"}), + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplex_long_short_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm)"}), + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplex_long_short_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplex(first[i], second, 4 * i, third, Imm)"}), + + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_0_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_0_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "1", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_0_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "2", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_0_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "3", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_1_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_1_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "1", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_1_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "2", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_1_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "3", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_2_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "2", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_2_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "2", ["Imm2"] = "1", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_2_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "2", ["Imm2"] = "2", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_2_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "2", ["Imm2"] = "3", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_3_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "3", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_3_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "3", ["Imm2"] = "1", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_3_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "3", ["Imm2"] = "2", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_int_sbyte_3_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "3", ["Imm2"] = "3", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_long_short_0_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_long_short_0_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "1", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_long_short_0_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "2", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_long_short_0_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "3", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_long_short_1_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "0", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_long_short_1_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "1", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_long_short_1_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "2", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + ("SveVecTernOpImm2Test.template", new Dictionary { ["TestName"] = "Sve2_DotProductRotateComplexBySelectedIndex_long_short_1_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "DotProductRotateComplexBySelectedIndex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "3", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(firstOp[i], secondOp, 4 * i, thirdOp, Imm1 * 4, Imm2) != result[i]", ["GetIterResult"] = "Helpers.DotProductRotateComplexBySelectedIndex(first[i], second, 4 * i, third, Imm1 * 4, Imm2)"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["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.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["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.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["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.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["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.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["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.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["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.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["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.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["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.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["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.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["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.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["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.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["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.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["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.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["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.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("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]"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["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.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["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.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["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.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["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.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["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.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), + ("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]"}), + + ("SveSimpleVecOpDiffRetTypeTest.template", new Dictionary { ["TestName"] = "Sve2_Log2_int_float", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Log2", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.Log2(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Log2(left[i])"}), + ("SveSimpleVecOpDiffRetTypeTest.template", new Dictionary { ["TestName"] = "Sve2_Log2_long_double", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Log2", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.Log2(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Log2(left[i])"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MaxNumberPairwise_float", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.MaxNumberPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MaxNumberPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MaxNumberPairwise_double", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.MaxNumberPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MaxNumberPairwiseSve(left, right, i)"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MaxPairwise_float", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.MaxPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MaxPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MaxPairwise_double", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.MaxPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MaxPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MaxPairwise_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MaxPairwise", ["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.MaxPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MaxPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MaxPairwise_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MaxPairwise", ["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.MaxPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MaxPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MaxPairwise_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MaxPairwise", ["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.MaxPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MaxPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MaxPairwise_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MaxPairwise", ["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.MaxPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MaxPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MaxPairwise_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MaxPairwise", ["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.MaxPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MaxPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MaxPairwise_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MaxPairwise", ["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.MaxPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MaxPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MaxPairwise_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MaxPairwise", ["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.MaxPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MaxPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MaxPairwise_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MaxPairwise", ["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.MaxPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MaxPairwiseSve(left, right, i)"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MinNumberPairwise_float", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.MinNumberPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MinNumberPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MinNumberPairwise_double", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.MinNumberPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MinNumberPairwiseSve(left, right, i)"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MinPairwise_float", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.MinPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MinPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MinPairwise_double", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.MinPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MinPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MinPairwise_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MinPairwise", ["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.MinPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MinPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MinPairwise_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MinPairwise", ["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.MinPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MinPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MinPairwise_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MinPairwise", ["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.MinPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MinPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MinPairwise_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MinPairwise", ["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.MinPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MinPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MinPairwise_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MinPairwise", ["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.MinPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MinPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MinPairwise_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MinPairwise", ["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.MinPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MinPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MinPairwise_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MinPairwise", ["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.MinPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MinPairwiseSve(left, right, i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MinPairwise_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MinPairwise", ["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.MinPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.MinPairwiseSve(left, right, 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])",}), + + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_sbyte_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_sbyte_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_sbyte_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_sbyte_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_short_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_short_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_short_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_short_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_int_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_int_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_int_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_int_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_long_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_long_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_long_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_long_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_byte_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_byte_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_byte_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_byte_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["Op4BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_ushort_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_ushort_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_ushort_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_ushort_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_uint_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_uint_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_uint_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_uint_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_ulong_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_ulong_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_ulong_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplex_ulong_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplex", ["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()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_0_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_0_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_0_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_0_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_1_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_1_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_1_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_1_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_2_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_2_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_2_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_2_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_3_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_3_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_3_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_short_3_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_int_0_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_int_0_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "0", ["Imm2"] = "1", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_int_0_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "0", ["Imm2"] = "2", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_int_0_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "0", ["Imm2"] = "3", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_int_1_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "1", ["Imm2"] = "0", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_int_1_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "1", ["Imm2"] = "1", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_int_1_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "1", ["Imm2"] = "2", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_int_1_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "1", ["Imm2"] = "3", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_0_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_0_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "0", ["Imm2"] = "1", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_0_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "0", ["Imm2"] = "2", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_0_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "0", ["Imm2"] = "3", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_1_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "1", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_1_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "1", ["Imm2"] = "1", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_1_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "1", ["Imm2"] = "2", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_1_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "1", ["Imm2"] = "3", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_2_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "2", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_2_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "2", ["Imm2"] = "1", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_2_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "2", ["Imm2"] = "2", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_2_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "2", ["Imm2"] = "3", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_3_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "3", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_3_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "3", ["Imm2"] = "1", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_3_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "3", ["Imm2"] = "2", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_ushort_3_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm1"] = "3", ["Imm2"] = "3", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_uint_0_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_uint_0_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm1"] = "0", ["Imm2"] = "1", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_uint_0_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm1"] = "0", ["Imm2"] = "2", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_uint_0_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm1"] = "0", ["Imm2"] = "3", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_uint_1_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm1"] = "1", ["Imm2"] = "0", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_uint_1_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm1"] = "1", ["Imm2"] = "1", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_uint_1_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm1"] = "1", ["Imm2"] = "2", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRotateComplexBySelectedScalar_uint_1_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm1"] = "1", ["Imm2"] = "3", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_sbyte_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_sbyte_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_sbyte_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_sbyte_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_short_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["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.getMaskUInt64()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_short_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["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.getMaskUInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_short_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["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.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_short_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["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.getMaskUInt64()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_int_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["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.getMaskUInt64()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_int_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["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.getMaskUInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_int_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["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.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_int_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["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.getMaskUInt64()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_long_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["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.getMaskUInt64()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_long_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["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.getMaskUInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_long_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["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.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplex_long_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplex", ["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.getMaskUInt64()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplex(first, second, third, Imm)"}), + + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_0_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_0_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "1", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_0_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "2", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_0_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "3", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_1_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_1_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "1", ["Imm2"] = "1", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_1_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "1", ["Imm2"] = "2", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_1_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "1", ["Imm2"] = "3", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_2_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "1", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_2_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "2", ["Imm2"] = "1", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_2_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "2", ["Imm2"] = "2", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_2_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "2", ["Imm2"] = "3", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_3_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "3", ["Imm2"] = "0", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_3_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "3", ["Imm2"] = "1", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_3_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "3", ["Imm2"] = "2", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_short_3_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm1"] = "3", ["Imm2"] = "3", ["InvalidImm1"] = "4", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_int_0_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_int_0_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "0", ["Imm2"] = "1", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_int_0_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "0", ["Imm2"] = "2", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_int_0_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "0", ["Imm2"] = "3", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_int_1_0", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "1", ["Imm2"] = "0", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_int_1_1", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "1", ["Imm2"] = "1", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_int_1_2", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "1", ["Imm2"] = "2", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar_int_1_3", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4BaseType"] = "Byte", ["Op5BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm1"] = "1", ["Imm2"] = "3", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + + ("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])"}), + + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingBySelectedScalarSaturateHigh_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingBySelectedScalarSaturateHigh_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingBySelectedScalarSaturateHigh_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm])"}), + + ("SveVecBinOpTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingSaturateHigh_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingSaturateHigh", ["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.MultiplyDoublingSaturateHigh(left[i], right[i])", ["GetIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingSaturateHigh_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingSaturateHigh", ["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.MultiplyDoublingSaturateHigh(left[i], right[i])", ["GetIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingSaturateHigh_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingSaturateHigh", ["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.MultiplyDoublingSaturateHigh(left[i], right[i])", ["GetIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingSaturateHigh_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingSaturateHigh", ["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.MultiplyDoublingSaturateHigh(left[i], right[i])", ["GetIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(leftOp[i], rightOp[i])"}), + + ("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])"}), + + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndAddSaturateEven_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndAddSaturateEven", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[i * 2])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndAddSaturateEven_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndAddSaturateEven", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[i * 2])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndAddSaturateEven_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndAddSaturateEven", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[i * 2])", ["ConvertFunc"] = ""}), + + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndAddSaturateEvenOdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndAddSaturateEvenOdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[i * 2 + 1])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndAddSaturateEvenOdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndAddSaturateEvenOdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[i * 2 + 1])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndAddSaturateEvenOdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndAddSaturateEvenOdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[i * 2 + 1])", ["ConvertFunc"] = ""}), + + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndAddSaturateOdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndAddSaturateOdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2 + 1], third[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2 + 1], third[i * 2 + 1])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndAddSaturateOdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndAddSaturateOdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2 + 1], third[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2 + 1], third[i * 2 + 1])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndAddSaturateOdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndAddSaturateOdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2 + 1], third[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2 + 1], third[i * 2 + 1])", ["ConvertFunc"] = ""}), + + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndSubtractSaturateEven_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndSubtractSaturateEven", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[i * 2])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndSubtractSaturateEven_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndSubtractSaturateEven", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[i * 2])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndSubtractSaturateEven_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndSubtractSaturateEven", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[i * 2])", ["ConvertFunc"] = ""}), + + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndSubtractSaturateEvenOdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndSubtractSaturateEvenOdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[i * 2 + 1])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndSubtractSaturateEvenOdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndSubtractSaturateEvenOdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[i * 2 + 1])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndSubtractSaturateEvenOdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndSubtractSaturateEvenOdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[i * 2 + 1])", ["ConvertFunc"] = ""}), + + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndSubtractSaturateOdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndSubtractSaturateOdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2 + 1], third[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2 + 1], third[i * 2 + 1])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndSubtractSaturateOdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndSubtractSaturateOdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2 + 1], third[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2 + 1], third[i * 2 + 1])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningAndSubtractSaturateOdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningAndSubtractSaturateOdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2 + 1], third[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2 + 1], third[i * 2 + 1])", ["ConvertFunc"] = ""}), + + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven", ["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()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[Imm])", ["ConvertFunc"] = ""}), + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningBySelectedScalarAndAddSaturateEven", ["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()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2], third[Imm])", ["ConvertFunc"] = ""}), + + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd", ["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()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2 + 1], third[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2 + 1], third[Imm])", ["ConvertFunc"] = ""}), + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningBySelectedScalarAndAddSaturateOdd", ["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()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2 + 1], third[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(first[i], second[i * 2 + 1], third[Imm])", ["ConvertFunc"] = ""}), + + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven", ["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()", ["Imm"] = "4", ["InvalidImm"] = "8", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[Imm])", ["ConvertFunc"] = ""}), + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateEven", ["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()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2], third[Imm])", ["ConvertFunc"] = ""}), + + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd", ["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()", ["Imm"] = "4", ["InvalidImm"] = "8", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2 + 1], third[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2 + 1], third[Imm])", ["ConvertFunc"] = ""}), + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningBySelectedScalarAndSubtractSaturateOdd", ["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()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2 + 1], third[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(first[i], second[i * 2 + 1], third[Imm])", ["ConvertFunc"] = ""}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingWideningSaturateEven_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningSaturateEven", ["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.MultiplyDoublingWideningSaturate(left[i * 2], right[i * 2])", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(leftOp[i * 2], rightOp[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingWideningSaturateEven_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningSaturateEven", ["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.MultiplyDoublingWideningSaturate(left[i * 2], right[i * 2])", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(leftOp[i * 2], rightOp[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingWideningSaturateEven_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningSaturateEven", ["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.MultiplyDoublingWideningSaturate(left[i * 2], right[i * 2])", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(leftOp[i * 2], rightOp[i * 2])"}), + + ("SveVecImmBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingWideningSaturateEvenBySelectedScalar_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningSaturateEvenBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[i * 2], right[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(leftOp[i * 2], rightOp[Imm])", ["ConvertFunc"] = ""}), + ("SveVecImmBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingWideningSaturateEvenBySelectedScalar_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningSaturateEvenBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[i * 2], right[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(leftOp[i * 2], rightOp[Imm])", ["ConvertFunc"] = ""}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingWideningSaturateOdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningSaturateOdd", ["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.MultiplyDoublingWideningSaturate(left[i * 2 + 1], right[i * 2 + 1])", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(leftOp[i * 2 + 1], rightOp[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingWideningSaturateOdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningSaturateOdd", ["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.MultiplyDoublingWideningSaturate(left[i * 2 + 1], right[i * 2 + 1])", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(leftOp[i * 2 + 1], rightOp[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingWideningSaturateOdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningSaturateOdd", ["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.MultiplyDoublingWideningSaturate(left[i * 2 + 1], right[i * 2 + 1])", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(leftOp[i * 2 + 1], rightOp[i * 2 + 1])"}), + + ("SveVecImmBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingWideningSaturateOddBySelectedScalar_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningSaturateOddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[i * 2 + 1], right[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(leftOp[i * 2 + 1], rightOp[Imm])", ["ConvertFunc"] = ""}), + ("SveVecImmBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_MultiplyDoublingWideningSaturateOddBySelectedScalar_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyDoublingWideningSaturateOddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[i * 2 + 1], right[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(leftOp[i * 2 + 1], rightOp[Imm])", ["ConvertFunc"] = ""}), + + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingBySelectedScalarSaturateHigh_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["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()", ["Imm"] = "4", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingBySelectedScalarSaturateHigh_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["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()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingBySelectedScalarSaturateHigh_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["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()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm])"}), + + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateAndAddHigh_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateAndAddHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(first[i], second[i], third[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(first[i], second[i], third[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateAndAddHigh_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateAndAddHigh", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(first[i], second[i], third[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(first[i], second[i], third[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateAndAddHigh_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateAndAddHigh", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(first[i], second[i], third[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(first[i], second[i], third[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateAndAddHigh_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateAndAddHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(first[i], second[i], third[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(first[i], second[i], third[i])", ["ConvertFunc"] = ""}), + + ("SveVecImmTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh", ["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()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = ""}), + ("SveVecImmTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh", ["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()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = ""}), + ("SveVecImmTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateBySelectedScalarAndAddHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = ""}), + + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateAndSubtractHigh_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateAndSubtractHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(first[i], second[i], third[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(first[i], second[i], third[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateAndSubtractHigh_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateAndSubtractHigh", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(first[i], second[i], third[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(first[i], second[i], third[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateAndSubtractHigh_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateAndSubtractHigh", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(first[i], second[i], third[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(first[i], second[i], third[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateAndSubtractHigh_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateAndSubtractHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(first[i], second[i], third[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(first[i], second[i], third[i])", ["ConvertFunc"] = ""}), + + ("SveVecImmTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh", ["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()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = ""}), + ("SveVecImmTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh", ["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()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = ""}), + ("SveVecImmTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateBySelectedScalarAndSubtractHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = ""}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateHigh_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateHigh", ["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.MultiplyRoundedDoublingSaturateHigh(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateHigh_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateHigh", ["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.MultiplyRoundedDoublingSaturateHigh(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateHigh_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateHigh", ["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.MultiplyRoundedDoublingSaturateHigh(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_MultiplyRoundedDoublingSaturateHigh_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyRoundedDoublingSaturateHigh", ["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.MultiplyRoundedDoublingSaturateHigh(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(leftOp[i], rightOp[i])"}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve2_NegateSaturate_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.NegateSaturate(firstOp[i])", ["GetIterResult"] = "Helpers.NegateSaturate(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve2_NegateSaturate_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.NegateSaturate(firstOp[i])", ["GetIterResult"] = "Helpers.NegateSaturate(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve2_NegateSaturate_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.NegateSaturate(firstOp[i])", ["GetIterResult"] = "Helpers.NegateSaturate(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve2_NegateSaturate_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.NegateSaturate(firstOp[i])", ["GetIterResult"] = "Helpers.NegateSaturate(leftOp[i])"}), + + ("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])"}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve2_ReciprocalEstimate_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.UnsignedReciprocalEstimate(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.UnsignedReciprocalEstimate(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve2_ReciprocalSqrtEstimate_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ReciprocalSqrtEstimate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.UnsignedReciprocalSqrtEstimate(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.UnsignedReciprocalSqrtEstimate(leftOp[i])"}), + + ("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])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRounded_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRounded", ["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] != (long) Helpers.SveShiftArithmeticRounded(left[i], right[i])", ["GetIterResult"] = "(long) Helpers.SveShiftArithmeticRounded(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRoundedSaturate_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRoundedSaturate", ["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.SveShiftArithmeticRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "(sbyte)Helpers.SveShiftArithmeticRoundedSaturate(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRoundedSaturate_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRoundedSaturate", ["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.SveShiftArithmeticRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "(short)Helpers.SveShiftArithmeticRoundedSaturate(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRoundedSaturate_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRoundedSaturate", ["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.SveShiftArithmeticRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "(int) Helpers.SveShiftArithmeticRoundedSaturate(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRoundedSaturate_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRoundedSaturate", ["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] != (long) Helpers.SveShiftArithmeticRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "(long) Helpers.SveShiftArithmeticRoundedSaturate(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticSaturate_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticSaturate", ["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.SveShiftArithmeticSaturate(left[i], right[i])", ["GetIterResult"] = "(sbyte)Helpers.SveShiftArithmeticSaturate(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticSaturate_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticSaturate", ["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.SveShiftArithmeticSaturate(left[i], right[i])", ["GetIterResult"] = "(short)Helpers.SveShiftArithmeticSaturate(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticSaturate_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticSaturate", ["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.SveShiftArithmeticSaturate(left[i], right[i])", ["GetIterResult"] = "(int) Helpers.SveShiftArithmeticSaturate(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticSaturate_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticSaturate", ["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] != (long) Helpers.SveShiftArithmeticSaturate(left[i], right[i])", ["GetIterResult"] = "(long) Helpers.SveShiftArithmeticSaturate(leftOp[i], rightOp[i])"}), + + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["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()", ["Imm"] = "12", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["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()", ["Imm"] = "23", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["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()", ["Imm"] = "63", ["InvalidImm"] = "64", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["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()", ["Imm"] = "9", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["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()", ["Imm"] = "17", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["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()", ["Imm"] = "45", ["InvalidImm"] = "64", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), + + ("SveVecBinOpDifferentTypesTest.template",new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturate_byte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturate(leftOp[i], rightOp[i])"}), + ("SveVecBinOpDifferentTypesTest.template",new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturate_ushort_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturate(leftOp[i], rightOp[i])"}), + ("SveVecBinOpDifferentTypesTest.template",new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturate_uint_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturate(leftOp[i], rightOp[i])"}), + ("SveVecBinOpDifferentTypesTest.template",new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturate_ulong_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturate(leftOp[i], rightOp[i])"}), + + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturateUnsigned_byte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "2", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)"}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturateUnsigned_ushort_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "14", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)"}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturateUnsigned_uint_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "19", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)"}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturateUnsigned_ulong_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "39", ["InvalidImm"] = "64", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)"}), + + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningEven_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)",}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningEven_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "10", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)",}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningEven_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "31", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)",}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningEven_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "2", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)",}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningEven_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "2", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)",}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningEven_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "2", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)",}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningOdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)",}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningOdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "15", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)",}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningOdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "23", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)",}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningOdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)",}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningOdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "13", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)",}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningOdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "20", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)",}), + + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLogicalRounded_byte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRounded(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRounded(left[i], right[i])",}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLogicalRounded_ushort_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRounded(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRounded(left[i], right[i])",}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLogicalRounded_uint_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRounded(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRounded(left[i], right[i])",}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLogicalRounded_ulong_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRounded(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRounded(left[i], right[i])",}), + + ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLogicalRoundedSaturate_byte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])",}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLogicalRoundedSaturate_ushort_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])",}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLogicalRoundedSaturate_uint_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])",}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLogicalRoundedSaturate_ulong_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])",}), + + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "4", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["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()", ["Imm"] = "15", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["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()", ["Imm"] = "22", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["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()", ["Imm"] = "40", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["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()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["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()", ["Imm"] = "29", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["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()", ["Imm"] = "54", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), + + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticAdd_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "4", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticAdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticAdd", ["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()", ["Imm"] = "15", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticAdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticAdd", ["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()", ["Imm"] = "22", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticAdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticAdd", ["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()", ["Imm"] = "40", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)",}), + + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "4", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "15", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "22", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "4", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "15", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "22", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateUnsignedEven_byte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "4", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateUnsignedEven_ushort_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "12", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateUnsignedEven_uint_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "27", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateUnsignedOdd_byte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "8", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateUnsignedOdd_ushort_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "15", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateUnsignedOdd_uint_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "12", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRounded_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "8", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRounded_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "8", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRounded_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "15", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRounded_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "12", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)",}), + + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedAdd_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "2", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedAdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["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()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedAdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["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()", ["Imm"] = "29", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedAdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["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()", ["Imm"] = "64", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)",}), + + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven_byte_short",["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven_ushort_int",["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven_uint_long",["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd_byte_short",["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd_ushort_int",["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd_uint_long",["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightLogicalAdd_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "2", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightLogicalAdd_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalAdd", ["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()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightLogicalAdd_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalAdd", ["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()", ["Imm"] = "29", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightLogicalAdd_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalAdd", ["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()", ["Imm"] = "64", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)",}), + + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingOdd", ["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.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingOdd", ["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.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRounded_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "2", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRounded_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRounded_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "29", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRounded_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "64", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)",}), + + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedAdd_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "2", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedAdd_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedAdd", ["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()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedAdd_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedAdd", ["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()", ["Imm"] = "29", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedAdd_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedAdd", ["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()", ["Imm"] = "64", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)",}), + + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingOdd", ["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.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingOdd", ["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.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingSaturateEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingSaturateEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingSaturateEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), + + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingSaturateOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["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_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)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i)"}), + + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingOdd", ["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.SubtractHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingOdd(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingOdd", ["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.SubtractHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingOdd(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingOdd", ["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.SubtractHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingOdd(first, second, third, i)"}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingOdd", ["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.SubtractHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingOdd(first, second, third, i)"}), + ("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])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturate_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturate", ["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(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturate_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturate", ["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(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturate_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturate", ["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(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), + ("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])"}), + + ("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])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_ushort_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["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_uint_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["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.SubtractWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_ulong_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["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.SubtractWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2])"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_short_sbyte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_int_short_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["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], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_long_int_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["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], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_ushort_byte_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_uint_ushort_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_ulong_uint_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2])"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEvenOdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEvenOdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEvenOdd", ["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], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEvenOdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEvenOdd", ["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], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2], right[i * 2 + 1])"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOdd_short_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOdd", ["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 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOdd_int_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOdd", ["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 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOdd_long_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOdd", ["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 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOdd_ushort_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOdd_uint_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOdd", ["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.SubtractWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOdd_ulong_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOdd", ["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.SubtractWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2 + 1])"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOdd_short_sbyte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOdd_int_short_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOdd", ["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 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOdd_long_int_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOdd", ["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 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOdd_ushort_byte_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOdd_uint_ushort_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2 + 1])"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOdd_ulong_uint_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2 + 1])"}), + + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOddEven_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["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_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])"}), + + ("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)"}), + ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(third[i] < (UInt64) RetElementCount * 2) ? ((third[i] < (UInt64) RetElementCount) ? (result[i] != first[third[i]]) : (result[i] != second[third[i]-(UInt64) RetElementCount])) : (result[i] != 0)"}), + ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_float_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["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)"}), + ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_double_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(third[i] < (UInt64) RetElementCount * 2) ? ((third[i] < (UInt64) RetElementCount) ? (result[i] != first[third[i]]) : (result[i] != second[third[i]-(UInt64) RetElementCount])) : (result[i] != 0)"}), + ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_sbyte_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["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_short_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["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_int_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["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)"}), + ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_long_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(third[i] < (UInt64) RetElementCount * 2) ? ((third[i] < (UInt64) RetElementCount) ? (result[i] != first[third[i]]) : (result[i] != second[third[i]-(UInt64) RetElementCount])) : (result[i] != 0)"}), + + ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["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()", ["ValidateEntry"] = "(third[i] < (Byte) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), + ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "(third[i] < (UInt16) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), + ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["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()", ["ValidateEntry"] = "(third[i] < (UInt32) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), + ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["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()", ["ValidateEntry"] = "(third[i] < (UInt64) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), + ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_float_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "(third[i] < (UInt32) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), + ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_double_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(third[i] < (UInt64) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), + ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_sbyte_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "(third[i] < (Byte) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), + ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_short_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "(third[i] < (UInt16) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), + ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_int_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "(third[i] < (UInt32) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), + ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_long_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(third[i] < (UInt64) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), + + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), + + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "8", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["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()", ["Imm"] = "12", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["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()", ["Imm"] = "26", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["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()", ["Imm"] = "55", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "3" , ["InvalidImm"] = "9" , ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["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()", ["Imm"] = "11", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["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()", ["Imm"] = "22", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), + ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["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()", ["Imm"] = "45", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), + }; +} diff --git a/src/tests/Common/GenerateHWIntrinsicTests/Arm/SveTests.cs b/src/tests/Common/GenerateHWIntrinsicTests/Arm/SveTests.cs new file mode 100644 index 00000000000000..d4937989a06688 --- /dev/null +++ b/src/tests/Common/GenerateHWIntrinsicTests/Arm/SveTests.cs @@ -0,0 +1,1702 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +static class SveTests +{ + public static (string templateFileName, Dictionary templateData)[] SveInputs = + { + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Abs(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Abs(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)-TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "(sbyte)Helpers.Abs(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)-TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "(short)Helpers.Abs(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "(int)Helpers.Abs(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(long)Helpers.Abs(firstOp[i]) != (long)result[i]", ["GetIterResult"] = "(long)Helpers.Abs(leftOp[i])"}), + + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareGreaterThan_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareGreaterThan_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareGreaterThanOrEqual_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareGreaterThanOrEqual_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareLessThan_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareLessThan_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareLessThanOrEqual_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareLessThanOrEqual_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + + ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(sbyte)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), + ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(short)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), + ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(int)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), + ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(long)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), + ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(byte)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), + ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(ushort)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), + ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(uint)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), + ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt64)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossRecursivePairwise(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0.0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossRecursivePairwise(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0.0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_long_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWideningLong(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_long_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWideningLong(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_long_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWideningULong(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWideningULong(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_float_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_double_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), + + ("SveVecBinOpTestScalarRet.template", new Dictionary { ["TestName"] = "Sve_AddSequentialAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSequentialAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateScalarResult"] = "result[0] != Helpers.AddSequentialAcross(left, right)"}), + ("SveVecBinOpTestScalarRet.template", new Dictionary { ["TestName"] = "Sve_AddSequentialAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSequentialAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateScalarResult"] = "result[0] != Helpers.AddSequentialAcross(left, right)"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), + + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_Compact_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compact", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.Compact(left, right))", ["GetVectorResult"] = "Helpers.Compact(left, right)",}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_Compact_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compact", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.Compact(left, right))", ["GetVectorResult"] = "Helpers.Compact(left, right)",}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_Compact_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compact", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.Compact(left, right))", ["GetVectorResult"] = "Helpers.Compact(left, right)",}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_Compact_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compact", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.Compact(left, right))", ["GetVectorResult"] = "Helpers.Compact(left, right)",}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_Compact_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compact", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.Compact(left, right))", ["GetVectorResult"] = "Helpers.Compact(left, right)",}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_Compact_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compact", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.Compact(left, right))", ["GetVectorResult"] = "Helpers.Compact(left, right)",}), + + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), + + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareUnordered_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareUnordered", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareUnordered(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareUnordered(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareUnordered_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareUnordered", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareUnordered(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareUnordered(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute16BitAddresses_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute16BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(left[i] + ((uint)right[i] * 2)) != result[i]", ["GetIterResult"] = "(left[i] + ((uint)right[i] * 2))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute16BitAddresses_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute16BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(left[i] + (right[i] * 2)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 2))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute16BitAddresses_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute16BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(left[i] + ((ulong)right[i] * 2)) != result[i]", ["GetIterResult"] = "(left[i] + ((ulong)right[i] * 2))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute16BitAddresses_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute16BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(left[i] + (right[i] * 2)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 2))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute32BitAddresses_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute32BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(left[i] + ((uint)right[i] * 4)) != result[i]", ["GetIterResult"] = "(left[i] + ((uint)right[i] * 4))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute32BitAddresses_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute32BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(left[i] + (right[i] * 4)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 4))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute32BitAddresses_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute32BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(left[i] + ((ulong)right[i] * 4)) != result[i]", ["GetIterResult"] = "(left[i] + ((ulong)right[i] * 4))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute32BitAddresses_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute32BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(left[i] + (right[i] * 4)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 4))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute64BitAddresses_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute64BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(left[i] + ((uint)right[i] * 8)) != result[i]", ["GetIterResult"] = "(left[i] + ((uint)right[i] * 8))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute64BitAddresses_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute64BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(left[i] + (right[i] * 8)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 8))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute64BitAddresses_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute64BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(left[i] + ((ulong)right[i] * 8)) != result[i]", ["GetIterResult"] = "(left[i] + ((ulong)right[i] * 8))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute64BitAddresses_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute64BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(left[i] + (right[i] * 8)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 8))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute8BitAddresses_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute8BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(left[i] + ((uint)right[i] * 1)) != result[i]", ["GetIterResult"] = "(left[i] + ((uint)right[i] * 1))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute8BitAddresses_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute8BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(left[i] + (right[i] * 1)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 1))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute8BitAddresses_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute8BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(left[i] + ((ulong)right[i] * 1)) != result[i]", ["GetIterResult"] = "(left[i] + ((ulong)right[i] * 1))"}), + ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute8BitAddresses_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute8BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(left[i] + (right[i] * 1)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 1))"}), + + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["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()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["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()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["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()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["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()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["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()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt32_int_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToInt32(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToInt32(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt32_int_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToInt32(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToInt32(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt64_long_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToInt64(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToInt64(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt64_long_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToInt64(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToInt64(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt32_uint_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToUInt32(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToUInt32(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt32_uint_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToUInt32(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToUInt32(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt64_ulong_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToUInt64(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToUInt64(left)"}), + ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt64_ulong_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToUInt64(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToUInt64(left)"}), + + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count16BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count16BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Int16)));",}), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count32BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count32BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Int32)));",}), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count64BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count64BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Int64)));",}), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count8BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count8BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Byte)));",}), + + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), + + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["NextValueOp3"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["NextValueOp3"] = "Helpers.getMaskSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "Helpers.getMaskInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "Helpers.getMaskInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "Helpers.getMaskInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), + + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), + + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["NextValueOp3"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["NextValueOp3"] = "Helpers.getMaskSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "Helpers.getMaskInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "Helpers.getMaskInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "Helpers.getMaskInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), + + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), + + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Divide_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Divide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Divide(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Divide(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Divide_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Divide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Divide(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Divide(left[i], right[i])"}), + + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProduct_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i)", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProduct_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i)", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProduct_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i)", ["ConvertFunc"] = ""}), + ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProduct_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i)", ["ConvertFunc"] = ""}), + + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProductBySelectedScalar_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProductBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm)", ["ConvertFunc"] = ""}), + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProductBySelectedScalar_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProductBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm)", ["ConvertFunc"] = ""}), + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProductBySelectedScalar_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProductBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm)", ["ConvertFunc"] = ""}), + ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProductBySelectedScalar_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProductBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm)", ["ConvertFunc"] = ""}), + + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplyAdd_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplyAdd_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + + ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddNegated_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddNegated_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplySubtract_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplySubtract_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + + ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractNegated_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractNegated_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskByte_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskByte", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskDouble_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskInt16_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskInt32_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskInt64_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskSByte_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskSByte", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskSingle_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskUInt16_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskUInt32_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskUInt64_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["ValidateIterResult"] = "result[i] != 0",}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskByte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskByte", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskDouble", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskInt16", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskSByte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskSByte", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskSingle", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskUInt16", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskUInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1Type"] = "SveMaskPattern"}), + ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskUInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1Type"] = "SveMaskPattern"}), + + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_ushort_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_short_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)16"}), + ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_ushort_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)58"}), + ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_short_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)123"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_ushort_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_short_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)54"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_ushort_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)32"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_short_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)17"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_ushort_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)56"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_short_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)123"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_ushort_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)99"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_short_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)254"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)230"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)23"}), + ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)22"}), + ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)99"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)16"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)101"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)165"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)82"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_uint_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)35"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_int_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)134"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)35"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)153"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_long_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_ulong_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)242"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_long_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)232"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)223"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_long_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)62"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)43"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)166"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)234"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)46"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_byte_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_sbyte_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_byte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_sbyte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_byte_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)51"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_sbyte_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)82"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_byte_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)236"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_sbyte_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)45"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_byte_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)34"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_sbyte_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)43"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_byte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)234"}), + ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_sbyte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)86"}), + + ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["InvalidImm"] = "16", ["Imm"] = "(Byte)11", ["ValidateIterResult"] = "result[i] != (Imm < Op1ElementCount ? firstOp[Imm] : 0)", ["GetIterResult"] = "(Single)(Imm < Op1ElementCount ? firstOp[Imm] : 0)"}), + ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["InvalidImm"] = "8", ["Imm"] = "(Byte)2", ["ValidateIterResult"] = "result[i] != (Imm < Op1ElementCount ? firstOp[Imm] : 0)", ["GetIterResult"] = "(Double)(Imm < Op1ElementCount ? firstOp[Imm] : 0)"}), + ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["InvalidImm"] = "64", ["Imm"] = "(Byte)47", ["ValidateIterResult"] = "result[i] != (Imm < Op1ElementCount ? firstOp[Imm] : 0)", ["GetIterResult"] = "(SByte)(Imm < Op1ElementCount ? firstOp[Imm] : 0)"}), + ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["InvalidImm"] = "32", ["Imm"] = "(Byte)30", ["ValidateIterResult"] = "result[i] != (Imm < Op1ElementCount ? firstOp[Imm] : 0)", ["GetIterResult"] = "(Int16)(Imm < Op1ElementCount ? firstOp[Imm] : 0)"}), + ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["InvalidImm"] = "16", ["Imm"] = "(Byte)4", ["ValidateIterResult"] = "result[i] != (Imm < Op1ElementCount ? firstOp[Imm] : 0)", ["GetIterResult"] = "(Int32)(Imm < Op1ElementCount ? firstOp[Imm] : 0)"}), + ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["InvalidImm"] = "8", ["Imm"] = "(Byte)5", ["ValidateIterResult"] = "result[i] != (Imm < Op1ElementCount ? firstOp[Imm] : 0)", ["GetIterResult"] = "(Int64)(Imm < Op1ElementCount ? firstOp[Imm] : 0)"}), + ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["InvalidImm"] = "64", ["Imm"] = "(Byte)17", ["ValidateIterResult"] = "result[i] != (Imm < Op1ElementCount ? firstOp[Imm] : 0)", ["GetIterResult"] = "(Byte)(Imm < Op1ElementCount ? firstOp[Imm] : 0)"}), + ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["InvalidImm"] = "32", ["Imm"] = "(Byte)25", ["ValidateIterResult"] = "result[i] != (Imm < Op1ElementCount ? firstOp[Imm] : 0)", ["GetIterResult"] = "(UInt16)(Imm < Op1ElementCount ? firstOp[Imm] : 0)"}), + ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["InvalidImm"] = "16", ["Imm"] = "(Byte)14", ["ValidateIterResult"] = "result[i] != (Imm < Op1ElementCount ? firstOp[Imm] : 0)", ["GetIterResult"] = "(UInt32)(Imm < Op1ElementCount ? firstOp[Imm] : 0)"}), + ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["InvalidImm"] = "8", ["Imm"] = "(Byte)1", ["ValidateIterResult"] = "result[i] != (Imm < Op1ElementCount ? firstOp[Imm] : 0)", ["GetIterResult"] = "(UInt64)(Imm < Op1ElementCount ? firstOp[Imm] : 0)"}), + + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), + + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForNextActiveElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForNextActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForNextActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForNextActiveElement(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForNextActiveElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForNextActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForNextActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForNextActiveElement(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForNextActiveElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForNextActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForNextActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForNextActiveElement(left, right)"}), + ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForNextActiveElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForNextActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForNextActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForNextActiveElement(left, right)"}), + + ("SveSimpleVecOpNarrowingTest.template", new Dictionary {["TestName"] = "Sve_FloatingPointExponentialAccelerator_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FloatingPointExponentialAccelerator", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPExponentialAccelerator(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FPExponentialAccelerator(leftOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveSimpleVecOpNarrowingTest.template", new Dictionary {["TestName"] = "Sve_FloatingPointExponentialAccelerator_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FloatingPointExponentialAccelerator", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPExponentialAccelerator(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FPExponentialAccelerator(leftOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_byte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_short_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_int_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_long_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_sbyte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_ushort_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_uint_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_ulong_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_float_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_double_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_byte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_short_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_int_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_long_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_sbyte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_ushort_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_uint_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_ulong_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_float_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_double_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), + ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_Byte_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_Double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_Int16_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_Int32_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_Int64_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_SByte_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_Single_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_UInt16_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_UInt32_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_UInt64_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + + ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_byte", ["VectorBaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()"}), + ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_short", ["VectorBaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()"}), + ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_int", ["VectorBaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()"}), + ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_long", ["VectorBaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()"}), + ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_sbyte", ["VectorBaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()"}), + ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_ushort", ["VectorBaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()"}), + ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_uint", ["VectorBaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()"}), + ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_ulong", ["VectorBaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()"}), + + // ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetSingle()"}), + // ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetInt32()"}), + // ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetDouble()"}), + ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + + // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()" ["NextValueBase"] = "TestLibrary.Generator.GetInt32()"}), + // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()" ["NextValueBase"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()" }), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + + // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()" ["NextValueBase"] = "TestLibrary.Generator.GetInt32()}), + // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()" ["NextValueBase"] = "TestLibrary.Generator.GetUInt32()}), + ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorInt32SignExtend_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorInt32SignExtend_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32SignExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32SignExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32SignExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32SignExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + + // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetInt32()"}), + // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + + // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetInt32()}), + // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + + ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()",}), + // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), + // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt32()}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + + ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorFirstFaulting_Bases_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Double", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetDouble()"}), + ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorFirstFaulting_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorFirstFaulting_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Single", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Single", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Double", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int64", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Double", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int64", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32SignExtendFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32SignExtendFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32SignExtendFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32SignExtendFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting_offsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting_offsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting_offsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting_offsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "(UInt16)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "(UInt16)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "(UInt16)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "(UInt16)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "(UInt16)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "(UInt16)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "(UInt16)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "(UInt16)"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "(UInt32)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "(UInt32)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "(UInt32)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "(UInt32)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "(UInt32)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "(UInt32)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "(UInt32)"}), + ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "(UInt32)"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), + ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = ""}), + + ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = ""}), + ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = ""}), + + ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), + ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), + ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), + ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), + ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), + ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "Helpers.getMaskSingle()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), + ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "Helpers.getMaskDouble()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), + ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), + ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), + ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), + + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingSignCount_byte_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingSignBits(leftOp[i])"}), + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingSignCount_ushort_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingSignBits(leftOp[i])"}), + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingSignCount_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingSignBits(leftOp[i])"}), + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingSignCount_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "((ulong)Helpers.CountLeadingSignBits(firstOp[i])) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingSignBits(leftOp[i])"}), + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_byte_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_ushort_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "((ulong)Helpers.CountLeadingZeroBits(firstOp[i])) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), + + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_float", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_double", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_sbyte", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_short", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_int", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_long", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_byte", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_ushort", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_uint", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_ulong", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_float", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["GetFfrType"] = "UInt32", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Cast"] = "(float*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_double", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["GetFfrType"] = "UInt64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Cast"] = "(double*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_sbyte", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["GetFfrType"] = "SByte", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Cast"] = "(sbyte*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_short", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["GetFfrType"] = "Int16", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Cast"] = "(short*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_int", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["GetFfrType"] = "Int32", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Cast"] = "(int*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_long", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["GetFfrType"] = "Int64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Cast"] = "(long*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_byte", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["GetFfrType"] = "Byte", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Cast"] = "(byte*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_ushort", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["GetFfrType"] = "UInt16", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Cast"] = "(ushort*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_uint", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["GetFfrType"] = "UInt32", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Cast"] = "(uint*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_ulong", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["GetFfrType"] = "UInt64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Cast"] = "(ulong*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendFirstFaulting_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendFirstFaulting_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendFirstFaulting_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendFirstFaulting_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["GetFfrType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["GetFfrType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendFirstFaulting_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendFirstFaulting_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), + + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt32SignExtendFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt32SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt32SignExtendFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt32SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), + + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendFirstFaulting_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendFirstFaulting_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendFirstFaulting_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendFirstFaulting_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendFirstFaulting_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendFirstFaulting_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), + + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt32ZeroExtendFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["GetFfrType"] = "Int64" , ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt32ZeroExtendFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), + + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_float", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_double", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_sbyte", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_short", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_int", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_long", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_byte", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_ushort", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_uint", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_ulong", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_float", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_double", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_sbyte", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_short", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_int", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_long", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_byte", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_ushort", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_uint", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_ulong", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveLoadNonFaultingMaskedUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorInt16NonFaultingSignExtendToInt32_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16NonFaultingSignExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["GetFfrType"] = "Int32", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]",}), + ("SveLoadNonFaultingMaskedUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorInt16NonFaultingSignExtendToInt64_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16NonFaultingSignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["GetFfrType"] = "Int64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]",}), + ("SveLoadNonFaultingMaskedUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorInt16NonFaultingSignExtendToUInt32_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16NonFaultingSignExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["GetFfrType"] = "UInt32", ["Cast"] = "", ["ValidateIterResult"] = "((uint)firstOp[i]) != result[i]",}), + ("SveLoadNonFaultingMaskedUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorInt16NonFaultingSignExtendToUInt64_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16NonFaultingSignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["GetFfrType"] = "UInt64", ["Cast"] = "", ["ValidateIterResult"] = "((ulong)firstOp[i]) != result[i]",}), + ("SveLoadNonFaultingMaskedUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorInt32NonFaultingSignExtendToInt64_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt32NonFaultingSignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["GetFfrType"] = "Int64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]",}), + ("SveLoadNonFaultingMaskedUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorInt32NonFaultingSignExtendToUInt64_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt32NonFaultingSignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["GetFfrType"] = "UInt64", ["Cast"] = "", ["ValidateIterResult"] = "((ulong)firstOp[i]) != result[i]",}), + ("SveLoadNonFaultingMaskedUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorSByteNonFaultingSignExtendToInt16_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteNonFaultingSignExtendToInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["GetFfrType"] = "Int16", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]",}), + ("SveLoadNonFaultingMaskedUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorSByteNonFaultingSignExtendToInt32_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteNonFaultingSignExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["GetFfrType"] = "Int32", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]",}), + ("SveLoadNonFaultingMaskedUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorSByteNonFaultingSignExtendToInt64_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteNonFaultingSignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["GetFfrType"] = "Int64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]",}), + ("SveLoadNonFaultingMaskedUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorSByteNonFaultingSignExtendToUInt16_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteNonFaultingSignExtendToUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["GetFfrType"] = "UInt16", ["Cast"] = "", ["ValidateIterResult"] = "((ushort)firstOp[i]) != result[i]",}), + ("SveLoadNonFaultingMaskedUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorSByteNonFaultingSignExtendToUInt32_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteNonFaultingSignExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["GetFfrType"] = "UInt32", ["Cast"] = "", ["ValidateIterResult"] = "((uint)firstOp[i]) != result[i]",}), + ("SveLoadNonFaultingMaskedUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorSByteNonFaultingSignExtendToUInt64_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteNonFaultingSignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["GetFfrType"] = "UInt64", ["Cast"] = "", ["ValidateIterResult"] = "((ulong)firstOp[i]) != result[i]",}), + + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(ulong)firstOp[i] != result[i]"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt32SignExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt32SignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt32SignExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt32SignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(ulong)firstOp[i] != result[i]"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendToInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendToUInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(ulong)firstOp[i] != result[i]"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendToInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendToUInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt32ZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt32ZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt32ZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt32ZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), + + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteNonFaultingZeroExtendToInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteNonFaultingZeroExtendToInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["GetFfrType"] = "Int16", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteNonFaultingZeroExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteNonFaultingZeroExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["GetFfrType"] = "Int32", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteNonFaultingZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteNonFaultingZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["GetFfrType"] = "Int64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteNonFaultingZeroExtendToUInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteNonFaultingZeroExtendToUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["GetFfrType"] = "UInt16", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteNonFaultingZeroExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteNonFaultingZeroExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["GetFfrType"] = "UInt32", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteNonFaultingZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteNonFaultingZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["GetFfrType"] = "UInt64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16NonFaultingZeroExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16NonFaultingZeroExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["GetFfrType"] = "Int32", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16NonFaultingZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16NonFaultingZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["GetFfrType"] = "Int64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16NonFaultingZeroExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16NonFaultingZeroExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["GetFfrType"] = "UInt32", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16NonFaultingZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16NonFaultingZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["GetFfrType"] = "UInt64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt32NonFaultingZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt32NonFaultingZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["GetFfrType"] = "Int64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadNonFaultingMaskedUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt32NonFaultingZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt32NonFaultingZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["GetFfrType"] = "UInt64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + + ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), + ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), + ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), + ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), + ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), + ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), + ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), + ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), + ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), + ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), + ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), + ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), + ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), + ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), + ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), + ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), + ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), + ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), + ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), + ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), + ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), + ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), + ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), + ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), + ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), + ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), + ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), + ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), + ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), + ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxNumber_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxNumber_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxNumberAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxNumberAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxNumberAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxNumberAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MinNumber_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MinNumber_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinNumberAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinNumberAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinNumberAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinNumberAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_0_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_0_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "1", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_0_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "2", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_0_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "3", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_1_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "0", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_1_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "1", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_1_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "2", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_1_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "3", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), + + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyExtended_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.MultiplyExtended(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyExtended(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyExtended_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.MultiplyExtended(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyExtended(left[i], right[i])"}), + + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["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()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["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()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["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()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["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()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["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()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "-firstOp[i] != result[i]", ["GetIterResult"] = "-leftOp[i]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "-firstOp[i] != result[i]", ["GetIterResult"] = "-leftOp[i]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)-TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "-firstOp[i] != result[i]", ["GetIterResult"] = "(sbyte)-leftOp[i]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)-TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "-firstOp[i] != result[i]", ["GetIterResult"] = "(short)-leftOp[i]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "-firstOp[i] != result[i]", ["GetIterResult"] = "(int)-leftOp[i]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(long)-firstOp[i] != (long)result[i]", ["GetIterResult"] = "(long)-leftOp[i]"}), + + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_uint_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(uint)Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "(uint)Helpers.BitCount(leftOp[i])"}), + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_ulong_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(ulong)Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "(ulong)Helpers.BitCount(leftOp[i])"}), + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_byte_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(byte)Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "(byte)Helpers.BitCount(leftOp[i])"}), + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_ushort_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(ushort)Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "(ushort)Helpers.BitCount(leftOp[i])"}), + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(uint)Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "(uint)Helpers.BitCount(leftOp[i])"}), + ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(ulong)Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "(ulong)Helpers.BitCount(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BitCount(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BitCount(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BitCount(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BitCount(leftOp[i])"}), + ("SvePrefetchTest.template", new Dictionary { ["TestName"] = "Sve_Prefetch16Bit", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Prefetch16Bit", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)18"}), + ("SvePrefetchTest.template", new Dictionary { ["TestName"] = "Sve_Prefetch32Bit", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Prefetch32Bit", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)20"}), + ("SvePrefetchTest.template", new Dictionary { ["TestName"] = "Sve_Prefetch64Bit", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Prefetch64Bit", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)87"}), + ("SvePrefetchTest.template", new Dictionary { ["TestName"] = "Sve_Prefetch8Bit", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Prefetch8Bit", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.LargestPowerOf2", ["InvalidImm"] = "(Byte)0", ["InvalidImm2"] = "(SveMaskPattern)35", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)12", ["Imm2"] = "SveMaskPattern.VectorCount1", ["InvalidImm"] = "(Byte)19", ["InvalidImm2"] = "(SveMaskPattern)37", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)5", ["Imm2"] = "SveMaskPattern.VectorCount2", ["InvalidImm"] = "(Byte)25", ["InvalidImm2"] = "(SveMaskPattern)46", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)7", ["Imm2"] = "SveMaskPattern.VectorCount3", ["InvalidImm"] = "(Byte)255", ["InvalidImm2"] = "(SveMaskPattern)50", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), + ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_vector_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "(Byte)10", ["Imm2"] = "SveMaskPattern.VectorCount4", ["InvalidImm"] = "(Byte)65", ["InvalidImm2"] = "(SveMaskPattern)90", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate((short)firstOp[i], (short)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2)))",}), + ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_vector_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "(Byte)1", ["Imm2"] = "SveMaskPattern.VectorCount5", ["InvalidImm"] = "(Byte)72", ["InvalidImm2"] = "(SveMaskPattern)35", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate((ushort)firstOp[i], (ushort)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2)))",}), + + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy32BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy32BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)1", ["Imm2"] = "SveMaskPattern.VectorCount6", ["InvalidImm"] = "(Byte)17", ["InvalidImm2"] = "(SveMaskPattern)32", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy32BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy32BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.VectorCount7", ["InvalidImm"] = "(Byte)19", ["InvalidImm2"] = "(SveMaskPattern)33", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy32BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy32BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)3", ["Imm2"] = "SveMaskPattern.VectorCount8", ["InvalidImm"] = "(Byte)25", ["InvalidImm2"] = "(SveMaskPattern)34", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy32BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy32BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)4", ["Imm2"] = "SveMaskPattern.VectorCount32", ["InvalidImm"] = "(Byte)26", ["InvalidImm2"] = "(SveMaskPattern)35", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), + ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy32BitElementCount_vector_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy32BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)5", ["Imm2"] = "SveMaskPattern.VectorCount64", ["InvalidImm"] = "(Byte)27", ["InvalidImm2"] = "(SveMaskPattern)36", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate((int)firstOp[i], (int)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2)))",}), + ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy32BitElementCount_vector_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy32BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)6", ["Imm2"] = "SveMaskPattern.VectorCount128", ["InvalidImm"] = "(Byte)18", ["InvalidImm2"] = "(SveMaskPattern)37", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate((uint)firstOp[i], (uint)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2)))",}), + + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy64BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy64BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)7", ["Imm2"] = "SveMaskPattern.VectorCount256", ["InvalidImm"] = "(Byte)34", ["InvalidImm2"] = "(SveMaskPattern)135", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy64BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy64BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)8", ["Imm2"] = "SveMaskPattern.LargestMultipleOf4", ["InvalidImm"] = "(Byte)35", ["InvalidImm2"] = "(SveMaskPattern)125", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy64BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy64BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)9", ["Imm2"] = "SveMaskPattern.LargestMultipleOf3", ["InvalidImm"] = "(Byte)36", ["InvalidImm2"] = "(SveMaskPattern)115", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy64BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy64BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)10", ["Imm2"] = "SveMaskPattern.All", ["InvalidImm"] = "(Byte)37", ["InvalidImm2"] = "(SveMaskPattern)145", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), + ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy64BitElementCount_vector_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy64BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)11", ["Imm2"] = "SveMaskPattern.VectorCount7", ["InvalidImm"] = "(Byte)38", ["InvalidImm2"] = "(SveMaskPattern)155", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate((long)firstOp[i], (long)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2)))",}), + ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy64BitElementCount_vector_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy64BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)12", ["Imm2"] = "SveMaskPattern.LargestPowerOf2", ["InvalidImm"] = "(Byte)39", ["InvalidImm2"] = "(SveMaskPattern)165", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate((ulong)firstOp[i], (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2)))",}), + + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy8BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy8BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)13", ["Imm2"] = "SveMaskPattern.VectorCount4", ["InvalidImm"] = "(Byte)89", ["InvalidImm2"] = "(SveMaskPattern)206", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy8BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy8BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)14", ["Imm2"] = "SveMaskPattern.LargestPowerOf2", ["InvalidImm"] = "(Byte)0", ["InvalidImm2"] = "(SveMaskPattern)207", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy8BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy8BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)15", ["Imm2"] = "SveMaskPattern.VectorCount6", ["InvalidImm"] = "(Byte)91", ["InvalidImm2"] = "(SveMaskPattern)208", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy8BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy8BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)16", ["Imm2"] = "SveMaskPattern.All", ["InvalidImm"] = "(Byte)92", ["InvalidImm2"] = "(SveMaskPattern)209", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), + + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_int_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_int_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_long_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_long_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_long_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_uint_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_uint_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_ulong_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_ulong_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_vector_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate(left[i], (short)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), + ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_vector_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate(left[i], (int)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), + ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_vector_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate(left[i], (long)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), + ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_vector_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate(left[i], (ushort)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), + ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_vector_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate(left[i], (uint)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), + ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_vector_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate(left[i], (ulong)(Helpers.NumberOfActiveElementsInMask(right)))", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], (ulong)(Helpers.NumberOfActiveElementsInMask(right)))"}), + + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy16BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy16BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)15", ["Imm2"] = "SveMaskPattern.VectorCount4", ["InvalidImm"] = "(Byte)98", ["InvalidImm2"] = "(SveMaskPattern)241", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy16BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy16BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)14", ["Imm2"] = "SveMaskPattern.All", ["InvalidImm"] = "(Byte)99", ["InvalidImm2"] = "(SveMaskPattern)242", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy16BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy16BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)13", ["Imm2"] = "SveMaskPattern.VectorCount256", ["InvalidImm"] = "(Byte)101", ["InvalidImm2"] = "(SveMaskPattern)243", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy16BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy16BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)12", ["Imm2"] = "SveMaskPattern.VectorCount32", ["InvalidImm"] = "(Byte)118", ["InvalidImm2"] = "(SveMaskPattern)50", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), + ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy16BitElementCount_vector_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy16BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "(Byte)11", ["Imm2"] = "SveMaskPattern.VectorCount4", ["InvalidImm"] = "(Byte)118", ["InvalidImm2"] = "(SveMaskPattern)60", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate((short)firstOp[i], (short)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2)))",}), + ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy16BitElementCount_vector_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy16BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "(Byte)10", ["Imm2"] = "SveMaskPattern.VectorCount64", ["InvalidImm"] = "(Byte)123", ["InvalidImm2"] = "(SveMaskPattern)70", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate((ushort)firstOp[i], (ushort)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2)))",}), + + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy32BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy32BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)9", ["Imm2"] = "SveMaskPattern.VectorCount5", ["InvalidImm"] = "(Byte)201", ["InvalidImm2"] = "(SveMaskPattern)80", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy32BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy32BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)8", ["Imm2"] = "SveMaskPattern.All", ["InvalidImm"] = "(Byte)202", ["InvalidImm2"] = "(SveMaskPattern)128", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy32BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy32BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)7", ["Imm2"] = "SveMaskPattern.LargestPowerOf2", ["InvalidImm"] = "(Byte)207", ["InvalidImm2"] = "(SveMaskPattern)255", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy32BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy32BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)6", ["Imm2"] = "SveMaskPattern.All", ["InvalidImm"] = "(Byte)220", ["InvalidImm2"] = "(SveMaskPattern)99", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), + ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy32BitElementCount_vector_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy32BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)5", ["Imm2"] = "SveMaskPattern.LargestMultipleOf4", ["InvalidImm"] = "(Byte)221", ["InvalidImm2"] = "(SveMaskPattern)76", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate((int)firstOp[i], (int)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2)))",}), + ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy32BitElementCount_vector_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy32BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)4", ["Imm2"] = "SveMaskPattern.LargestMultipleOf3", ["InvalidImm"] = "(Byte)240", ["InvalidImm2"] = "(SveMaskPattern)32", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate((uint)firstOp[i], (uint)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2)))",}), + + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy64BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy64BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)3", ["Imm2"] = "SveMaskPattern.VectorCount64", ["InvalidImm"] = "(Byte)241", ["InvalidImm2"] = "(SveMaskPattern)105", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy64BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy64BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.VectorCount4", ["InvalidImm"] = "(Byte)255", ["InvalidImm2"] = "(SveMaskPattern)108", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy64BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy64BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)1", ["Imm2"] = "SveMaskPattern.VectorCount6", ["InvalidImm"] = "(Byte)243", ["InvalidImm2"] = "(SveMaskPattern)109", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy64BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy64BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.LargestMultipleOf3", ["InvalidImm"] = "(Byte)19", ["InvalidImm2"] = "(SveMaskPattern)101", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), + ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy64BitElementCount_vector_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy64BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.LargestPowerOf2", ["InvalidImm"] = "(Byte)56", ["InvalidImm2"] = "(SveMaskPattern)109", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate((long)firstOp[i], (long)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2)))",}), + ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy64BitElementCount_vector_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy64BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.VectorCount8", ["InvalidImm"] = "(Byte)75", ["InvalidImm2"] = "(SveMaskPattern)154", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate((ulong)firstOp[i], (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2)))",}), + + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy8BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy8BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.VectorCount8", ["InvalidImm"] = "(Byte)100", ["InvalidImm2"] = "(SveMaskPattern)235", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy8BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy8BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.VectorCount4", ["InvalidImm"] = "(Byte)99", ["InvalidImm2"] = "(SveMaskPattern)123", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy8BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy8BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.VectorCount5", ["InvalidImm"] = "(Byte)98", ["InvalidImm2"] = "(SveMaskPattern)232", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy8BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy8BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.All", ["InvalidImm"] = "(Byte)97", ["InvalidImm2"] = "(SveMaskPattern)234", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), + + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_int_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_int_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_long_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_long_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_long_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_uint_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_uint_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_ulong_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_ulong_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), + ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_vector_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate(left[i], (short)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.AddSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), + ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_vector_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate(left[i], (int)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.AddSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), + ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_vector_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate(left[i], (long)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.AddSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), + ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_vector_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate(left[i], (ushort)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.AddSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), + ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_vector_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate(left[i], (uint)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.AddSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), + ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_vector_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate(left[i], (ulong)(Helpers.NumberOfActiveElementsInMask(right)))", ["GetIterResult"] = "Helpers.AddSaturate(left[i], (ulong)(Helpers.NumberOfActiveElementsInMask(right)))"}), + + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_Scale_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scale", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != Helpers.Scale(left[i], right[i])"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_Scale_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scale", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != Helpers.Scale(left[i], right[i])"}), + + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter_bases_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter_bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter_bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetDouble()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetDouble()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetSingle()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetSingle()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + + // ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["NarrowingType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + // ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["NarrowingType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4VectorType"] = "Vector", ["Op4BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["Op4VectorType"] = "Vector", ["Op4BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["Op4VectorType"] = "Vector", ["Op4BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["Op4VectorType"] = "Vector", ["Op4BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["Op4VectorType"] = "Vector", ["Op4BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["Op4VectorType"] = "Vector", ["Op4BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["Op4VectorType"] = "Vector", ["Op4BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["Op4VectorType"] = "Vector", ["Op4BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffsets_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffsets_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffsets_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffsets_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitNarrowing_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitNarrowing_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitNarrowing_indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["Op4VectorType"] = "Vector", ["Op4BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitNarrowing_indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["Op4VectorType"] = "Vector", ["Op4BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitNarrowing_indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["Op4VectorType"] = "Vector", ["Op4BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitNarrowing_indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["Op4VectorType"] = "Vector", ["Op4BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitWithByteOffsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitWithByteOffsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitWithByteOffsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitWithByteOffsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + + // ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitNarrowing_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["NarrowingType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitNarrowing_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), + // ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitNarrowing_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["NarrowingType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitNarrowing_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffsets_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffsets_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffsets_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffsets_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_ScatterWithByteOffsets_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ScatterWithByteOffsets", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetDouble()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_ScatterWithByteOffsets_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ScatterWithByteOffsets", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetDouble()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_ScatterWithByteOffsets_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ScatterWithByteOffsets", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_ScatterWithByteOffsets_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ScatterWithByteOffsets", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_ScatterWithByteOffsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ScatterWithByteOffsets", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_ScatterWithByteOffsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ScatterWithByteOffsets", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_ScatterWithByteOffsets_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ScatterWithByteOffsets", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetSingle()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_ScatterWithByteOffsets_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ScatterWithByteOffsets", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetSingle()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_ScatterWithByteOffsets_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ScatterWithByteOffsets", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_ScatterWithByteOffsets_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ScatterWithByteOffsets", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_ScatterWithByteOffsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ScatterWithByteOffsets", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_ScatterWithByteOffsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ScatterWithByteOffsets", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), + + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_sbyte_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(sbyte)Helpers.ShiftLeft((byte)left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "(sbyte)Helpers.ShiftLeft((byte)left[i], (ulong)right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_short_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(short)Helpers.ShiftLeft((ushort)left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "(short)Helpers.ShiftLeft((ushort)left[i], (ulong)right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(int)Helpers.ShiftLeft((uint)left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "(int)Helpers.ShiftLeft((uint)left[i], (ulong)right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(long)Helpers.ShiftLeft((ulong)left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "(long)Helpers.ShiftLeft((ulong)left[i], (ulong)right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], (ulong)right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], (ulong)right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], (ulong)right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_sbyte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(sbyte)Helpers.ShiftLeft((byte)left[i], right[(i * sizeof(byte)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "(sbyte)Helpers.ShiftLeft((byte)left[i], right[(i * sizeof(byte)) / sizeof(ulong)])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_short_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(short)Helpers.ShiftLeft((ushort)left[i], right[(i * sizeof(ushort)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "(short)Helpers.ShiftLeft((ushort)left[i], right[(i * sizeof(ushort)) / sizeof(ulong)])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(int)Helpers.ShiftLeft((uint)left[i], right[(i * sizeof(uint)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "(int)Helpers.ShiftLeft((uint)left[i], right[(i * sizeof(uint)) / sizeof(ulong)])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_byte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], right[(i * sizeof(byte)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], right[(i * sizeof(byte)) / sizeof(ulong)])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_ushort_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], right[(i * sizeof(ushort)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], right[(i * sizeof(ushort)) / sizeof(ulong)])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], right[(i * sizeof(uint)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], right[(i * sizeof(uint)) / sizeof(ulong)])"}), + + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_sbyte_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_short_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_sbyte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(sbyte)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(sbyte)) / sizeof(ulong)])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_short_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(short)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(short)) / sizeof(ulong)])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(int)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(int)) / sizeof(ulong)])"}), + + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve_ShiftRightArithmeticForDivide_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmeticForDivide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["InvalidImm"] = "0", ["Imm"] = "(Byte)8", ["ValidateIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)Imm) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)Imm)"}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve_ShiftRightArithmeticForDivide_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmeticForDivide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["InvalidImm"] = "0", ["Imm"] = "(Byte)14", ["ValidateIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)Imm) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)Imm)"}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve_ShiftRightArithmeticForDivide_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmeticForDivide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["InvalidImm"] = "0", ["Imm"] = "(Byte)22", ["ValidateIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)Imm) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)Imm)"}), + ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve_ShiftRightArithmeticForDivide_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmeticForDivide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["InvalidImm"] = "0", ["Imm"] = "(Byte)64", ["ValidateIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)Imm) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)Imm)"}), + + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[i])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_byte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(byte)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(byte)) / sizeof(ulong)])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_ushort_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(ushort)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(ushort)) / sizeof(ulong)])"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(uint)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(uint)) / sizeof(ulong)])"}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend16_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend16_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend32_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 32, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 32, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend8_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend8_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend8_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, false)"}), + + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningLower_short_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningLower_int_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningLower_long_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningUpper_short_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningUpper_int_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningUpper_long_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Sqrt_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.Sqrt(firstOp[i])", ["GetIterResult"] = "Helpers.Sqrt(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Sqrt_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.Sqrt(firstOp[i])", ["GetIterResult"] = "Helpers.Sqrt(leftOp[i])"}), + + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "0", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "2", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_4", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "4", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_6", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "1", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_5", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_7", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + + ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), + ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), + ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), + ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), + ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), + ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), + ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), + ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricSelectCoefficient_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricSelectCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricSelectCoefficient(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricSelectCoefficient(left[i], right[i]) : result[i]"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricSelectCoefficient_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricSelectCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricSelectCoefficient(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricSelectCoefficient(left[i], right[i]) : result[i]"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricStartingValue_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricStartingValue", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricStartingValue(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricStartingValue(left[i], right[i]) : result[i]"}), + ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricStartingValue_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricStartingValue", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricStartingValue(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricStartingValue(left[i], right[i]) : result[i]"}), + + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "(UInt32) (TestLibrary.Generator.GetUInt32() % (UInt32)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt32) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "(UInt64) (TestLibrary.Generator.GetUInt64() % (UInt64)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt64) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(Byte) (TestLibrary.Generator.GetByte() % (Byte) (Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (Byte) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "(UInt16) (TestLibrary.Generator.GetUInt16() % (UInt16)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt16) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(UInt32) (TestLibrary.Generator.GetUInt32() % (UInt32)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt32) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "(UInt64) (TestLibrary.Generator.GetUInt64() % (UInt64)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt64) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte) (TestLibrary.Generator.GetByte() % (Byte) (Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (Byte) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "(UInt16) (TestLibrary.Generator.GetUInt16() % (UInt16)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt16) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(UInt32) (TestLibrary.Generator.GetUInt32() % (UInt32)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt32) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "(UInt64) (TestLibrary.Generator.GetUInt64() % (UInt64)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt64) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend16_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend16_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(TestLibrary.Generator.GetUInt64() & 0x3FFFFFFFFFFFFFFF)", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend32_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(TestLibrary.Generator.GetUInt64() & 0x3FFFFFFFFFFFFFFF)", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 32, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 32, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend8_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend8_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend8_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(TestLibrary.Generator.GetUInt64() & 0x3FFFFFFFFFFFFFFF)", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, true)"}), + + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningLower_ushort_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningLower_uint_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningLower_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningUpper_ushort_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningUpper_uint_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningUpper_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_float_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_double_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_sbyte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_short_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_int_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_long_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_byte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_ushort_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_uint_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_ulong_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_float_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_double_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_sbyte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_short_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_int_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_long_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_byte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_ushort_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_uint_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_ulong_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), + + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + + ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), + ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), + ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), + ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), + ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), + ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), + ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), + ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), + ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), + ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), + ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), + ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), + ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), + ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), + ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), + ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), + ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), + ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), + ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), + ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), + ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), + ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), + ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), + ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), + ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), + ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), + ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), + ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), + ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), + ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), + + ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_short_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (SByte)first[i])"}), + ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_int_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (SByte)first[i])"}), + ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_int_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (Int16)first[i])"}), + ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_long_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (SByte)first[i])"}), + ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_long_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (Int16)first[i])"}), + ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_long_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (Int32)first[i])"}), + ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_ushort_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (Byte)first[i])"}), + ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_uint_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (Byte)first[i])"}), + ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_uint_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (UInt16)first[i])"}), + ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_ulong_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (Byte)first[i])"}), + ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_ulong_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (UInt16)first[i])"}), + ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (UInt32)first[i])"}), + + ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalEstimate_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.ReciprocalEstimate(firstOp[i])", ["GetIterResult"] = "Helpers.ReciprocalEstimate(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalEstimate_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.ReciprocalEstimate(firstOp[i])", ["GetIterResult"] = "Helpers.ReciprocalEstimate(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalExponent_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalExponent", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.ReciprocalExponent(firstOp[i])", ["GetIterResult"] = "Helpers.ReciprocalExponent(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalExponent_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalExponent", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.ReciprocalExponent(firstOp[i])", ["GetIterResult"] = "Helpers.ReciprocalExponent(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalSqrtEstimate_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalSqrtEstimate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.ReciprocalSqrtEstimate(firstOp[i])", ["GetIterResult"] = "Helpers.ReciprocalSqrtEstimate(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalSqrtEstimate_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalSqrtEstimate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.ReciprocalSqrtEstimate(firstOp[i])", ["GetIterResult"] = "Helpers.ReciprocalSqrtEstimate(leftOp[i])"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalSqrtStep_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalSqrtStep", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != Helpers.FPReciprocalSqrtStepFused(left[i], right[i])"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalSqrtStep_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalSqrtStep", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != Helpers.FPReciprocalSqrtStepFused(left[i], right[i])"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalStep_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != Helpers.FPReciprocalStepFused(left[i], right[i])"}), + ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalStep_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != Helpers.FPReciprocalStepFused(left[i], right[i])"}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement8_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement8(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement8(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement8_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement8(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement8(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement8_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement8(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement8(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement8_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement8(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement8(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement8_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement8(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement8(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement8_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement8(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement8(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement16_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement16(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement16(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement16_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement16(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement16(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement16_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement16(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement16(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement16_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement16(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement16(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement32_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement32(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement32(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement32_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement32(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement32(leftOp[i])"}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundAwayFromZero_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundAwayFromZero", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.RoundAwayFromZero(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundAwayFromZero(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundAwayFromZero_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundAwayFromZero", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.RoundAwayFromZero(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundAwayFromZero(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToNearest_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToNearest", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.RoundToNearest(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToNearest(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToNearest_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToNearest", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.RoundToNearest(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToNearest(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToNegativeInfinity_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToNegativeInfinity", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.RoundToNegativeInfinity(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToNegativeInfinity(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToNegativeInfinity_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToNegativeInfinity", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.RoundToNegativeInfinity(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToNegativeInfinity(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToPositiveInfinity_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToPositiveInfinity", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.RoundToPositiveInfinity(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToPositiveInfinity(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToPositiveInfinity_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToPositiveInfinity", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.RoundToPositiveInfinity(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToPositiveInfinity(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToZero_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToZero", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.RoundToZero(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToZero(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToZero_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToZero", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.RoundToZero(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToZero(leftOp[i])"}), + + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "SByte", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskSByte())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskSByte())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "Int16", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt16())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt16())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "Int32", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt32())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt32())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "Int64", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt64())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt64())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "Byte", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskByte())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskByte())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "UInt16", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt16())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt16())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "UInt32", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt32())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt32())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "UInt64", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt64())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt64())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), + + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "SByte", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskSByte())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskSByte())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "Int16", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt16())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt16())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "Int32", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt32())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt32())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "Int64", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt64())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt64())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "Byte", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskByte())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskByte())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "UInt16", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt16())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt16())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "UInt32", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt32())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt32())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "UInt64", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt64())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt64())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), + + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "SByte", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskSByte())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskSByte())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "Int16", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt16())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt16())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "Int32", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt32())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt32())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "Int64", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt64())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt64())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "Byte", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskByte())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskByte())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "UInt16", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt16())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt16())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "UInt32", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt32())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt32())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), + ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "UInt64", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt64())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt64())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), + + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), + }; +} diff --git a/src/tests/Common/GenerateHWIntrinsicTests/Arm/Templates.cs b/src/tests/Common/GenerateHWIntrinsicTests/Arm/Templates.cs new file mode 100644 index 00000000000000..cdf2f8340f7ac3 --- /dev/null +++ b/src/tests/Common/GenerateHWIntrinsicTests/Arm/Templates.cs @@ -0,0 +1,350 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +static class TestTemplates +{ + const string SimpleOpTest_ValidationLogic = @"if ({ValidateFirstResult}) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if ({ValidateRemainingResults}) + { + succeeded = false; + break; + } + } + }"; + + const string SimpleVecOpTest_ValidationLogic = @"for (var i = 0; i < RetElementCount; i++) + { + if ({ValidateIterResult}) + { + succeeded = false; + break; + } + }"; + + const string SimpleVecOpTest_ValidationLogicForNarrowing = @"for (var i = 0; i < Op1ElementCount; i++) + { + if ({ValidateIterResult}) + { + succeeded = false; + break; + } + }"; + + const string SimpleVecOpTest_VectorValidationLogic = @"succeeded = !({ValidateVectorResult});"; + + const string SimpleScalarOpTest_ValidationLogic = @"succeeded = !({ValidateScalarResult});"; + + const string SimpleTernVecOpTest_ValidationLogic = @"for (var i = 0; i < RetElementCount; i++) + { + if ({ValidateIterResult}) + { + succeeded = false; + break; + } + }"; + + + const string SimpleVecOpTest_ValidationLogicForCndSel = @"for (var i = 0; i < RetElementCount; i++) + { + {RetBaseType} iterResult = (mask[i] != 0) ? {GetIterResult} : falseVal[i]; + if (iterResult != result[i]) + { + succeeded = false; + break; + } + }"; + + const string SimpleVecOpTest_ValidationLogicForCndSelMask = @"for (var i = 0; i < RetElementCount; i++) + { + {RetBaseType} iterResult = ({GetIterResult} != 0) ? trueVal[i] : falseVal[i]; + if (iterResult != result[i]) + { + succeeded = false; + break; + } + }"; + + const string SimpleVecOpTest_ValidationLogicForCndSel_FalseValue = @"for (var i = 0; i < RetElementCount; i++) + { + {RetBaseType} iterResult = (mask[i] != 0) ? trueVal[i] : {GetIterResult}; + if (mask[i] != 0) + { + // Pick the trueValue + if (iterResult != result[i]) + { + succeeded = false; + break; + } + } + else + { + // For false, the values are merged with destination, and we do not know + // those contents would be, so skip verification for them. + } + }"; + + const string SimpleVecOpTest_ValidationLogicForCndSelForNarrowing = @"for (var i = 0; i < Op1ElementCount; i++) + { + {RetBaseType} iterResult = (mask[i] != 0) ? {GetIterResult} : falseVal[i]; + if ({ConvertFunc}(iterResult) != {ConvertFunc}(result[i])) + { + succeeded = false; + break; + } + }"; + + const string SimpleVecOpTest_ValidationLogicForCndSelForNarrowing_FalseValue = @"for (var i = 0; i < Op1ElementCount; i++) + { + {RetBaseType} iterResult = (mask[i] != 0) ? trueVal[i] : {GetIterResult}; + if (mask[i] != 0) + { + // Pick the trueValue + if ({ConvertFunc}(iterResult) != {ConvertFunc}(result[i])) + { + succeeded = false; + break; + } + } + else + { + // For false, the values are merged with destination, and we do not know + // those contents would be, so skip verification for them. + } + }"; + + + const string SimpleVecOpTest_VectorValidationLogicForCndSel = @" + + {RetBaseType}[] vectorResult = {GetVectorResult}; + {RetBaseType}[] maskedVectorResult = new {RetBaseType}[vectorResult.Length]; + + for (var i = 0; i < vectorResult.Length; i++) + { + maskedVectorResult[i] = (mask[i] != 0) ? vectorResult[i] : falseVal[i]; + } + + if (!result.SequenceEqual(maskedVectorResult)) + { + succeeded = false; + } + "; + + const string SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue = @" + { + {RetBaseType}[] vectorResult = {GetVectorResult}; + {RetBaseType}[] maskedVectorResult = new {RetBaseType}[vectorResult.Length]; + + for (var i = 0; i < vectorResult.Length; i++) + { + {RetBaseType} iterResult = (mask[i] != 0) ? trueVal[i] : vectorResult[i]; + if (mask[i] != 0) + { + // Pick the trueValue + if (iterResult != result[i]) + { + succeeded = false; + break; + } + } + else + { + // For false, the values are merged with destination, and we do not know + // those contents would be, so skip verification for them. + } + } + }"; + + const string SimpleTernVecOpTest_ValidationLogicForCndSel = @"for (var i = 0; i < RetElementCount; i++) + { + {RetBaseType} iterResult = (mask[i] != 0) ? {GetIterResult} : falseVal[i]; + if ({ConvertFunc}(iterResult) != {ConvertFunc}(result[i])) + { + succeeded = false; + break; + } + }"; + + const string SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue = @"for (var i = 0; i < RetElementCount; i++) + { + {RetBaseType} iterResult = (mask[i] != 0) ? trueVal[i] : {GetIterResult}; + if (mask[i] != 0) + { + // Pick the trueValue + if ({ConvertFunc}(iterResult) != {ConvertFunc}(result[i])) + { + succeeded = false; + break; + } + } + else + { + // For false, the values are merged with destination, and we do not know + // those contents would be, so skip verification for them. + } + }"; + + const string VecPairBinOpTest_ValidationLogic = @" + int index = 0; + int half = RetElementCount / 2; + for (var i = 0; i < RetElementCount; i+=2, index++) + { + if ({ValidateEntry}) + { + succeeded = false; + break; + } + }"; + + const string SveValidateForEachRetElementCount_ValidationLogic = @" + for (var i = 0; i < RetElementCount; i++) + { + if ({ValidateEntry}) + { + succeeded = false; + break; + } + }"; + + const string VecReduceUnOpTest_VectorValidationLogicForCndSel = @" + { + var hasFailed = (mask[0] != 0) ? ({ValidateReduceOpResult}): (falseVal[0] != result[0]); + + if (hasFailed) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + hasFailed = (mask[i] != 0) ? ({ValidateRemainingResults}) : (falseVal[i] != result[i]); + if (hasFailed) + { + succeeded = false; + break; + } + } + } + }"; + + const string VecReduceUnOpTest_VectorValidationLogicForCndSel_FalseValue = @" + { + var hasFailed = (mask[0] != 0) ? (trueVal[0] != result[0]): ({ValidateReduceOpResult}); + if (hasFailed) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + hasFailed = (mask[i] != 0) ? (trueVal[i] != result[i]) : ({ValidateRemainingResults}); + if (hasFailed) + { + succeeded = false; + break; + } + } + } + }"; + + const string VecReduceOpTest_ValidationLogic = @"if ({ValidateReduceOpResult}) + { + succeeded = false; + } + else + { + for (int i = 1; i < RetElementCount; i++) + { + if ({ValidateRemainingResults}) + { + succeeded = false; + break; + } + } + }"; + + const string SecureHashOpTest_ValidationLogic = @"{RetBaseType}[] expectedResult = new {RetBaseType}[]{ExpectedResult}; + + for (int i = 0; i < RetElementCount; i++) + { + if (result[i] != expectedResult[i]) + { + succeeded = false; + break; + } + }"; + + public static (string templateFileName, string outputTemplateName, Dictionary templateData)[] Templates = + { + ("_UnaryOpScalarTestTemplate.template", "DuplicateTest.template", new Dictionary { ["TemplateName"] = "Duplicate", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_ImmUnaryOpTestTemplate.template", "ImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_ImmUnaryOpTestTemplate.template", "VecImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_ImmTernaryOpTestTemplate.template", "ImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_ImmOpTestTemplate.template", "ImmOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_ImmBinaryOpTestTemplate.template", "ImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_ImmBinaryOpTestTemplate.template", "VecImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_BinaryOpTestTemplate.template", "SimpleBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_TernaryOpTestTemplate.template", "VecTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_ImmTernaryOpTestTemplate.template", "VecImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_ImmTernaryOpTestTemplate.template", "SimpleImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_UnaryOpTestTemplate.template", "SimpleUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_UnaryOpTestTemplate.template", "SimpleVecOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_BinaryOpTestTemplate.template", "VecPairBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecPairBinOpTest_ValidationLogic }), + ("_BinaryOp_SveTestTemplate.template", "SveVecPairBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecPairBinOpTest_ValidationLogic }), + ("_BinaryOp_SveTestTemplate.template", "SveVecBinaryOpValidateTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SveValidateForEachRetElementCount_ValidationLogic }), + ("_UnaryOpTestTemplate.template", "VecReduceUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecReduceOpTest_ValidationLogic }), + ("_BinaryOpTestTemplate.template", "VecBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_TernaryOpTestTemplate.template", "SimpleTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_UnaryOpTestTemplate.template", "SecureHashUnOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), + ("_BinaryOpTestTemplate.template", "SecureHashBinOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), + ("_TernaryOpTestTemplate.template", "SecureHashTernOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), + ("_SveUnaryOpTestTemplate.template", "SveSimpleVecOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveUnaryOpDifferentRetTypeTestTemplate.template", "SveSimpleVecOpDiffRetTypeTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveUnaryOpDifferentRetTypeTestTemplate.template", "SveSimpleVecOpNarrowingTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogicForNarrowing, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSelForNarrowing, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSelForNarrowing_FalseValue }), + ("_SveUnaryOpDifferentRetTypeTestTemplate.template", "SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), + ("_SveBinaryOpTestTemplate.template", "SveVecBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveBinaryOpTestTemplate.template", "SveVecBinOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), + ("_SveBinaryOpTestTemplate.template", "SveVecBinOpConvertTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveBinaryOpDifferentRetTypeTestTemplate.template", "SveVecBinOpDifferentRetType.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue}), + ("_SveMasklessBinaryOpTestTemplate.template", "SveVecBinOpTestScalarRet.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleScalarOpTest_ValidationLogic }), + ("_SveBinaryRetMaskOpTestTemplate.template", "SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue, ["TemplateValidationLogicForCndSelMask"] = SimpleVecOpTest_ValidationLogicForCndSelMask }), + ("_SveBinaryOpDifferentTypesTestTemplate.template", "SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveBinaryMaskOpTestTemplate.template", "SveMaskVecBinOpConvertTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveImmBinaryOpTestTemplate.template", "SveVecImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveImmBinaryOpTestTemplate.template", "SveVecImmBinOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), + ("_SveImmUnaryOpTestTemplate.template", "SveVecImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveTernOpTestTemplate.template", "SveVecTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveTernOpTestTemplate.template", "SveVecTernOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), + ("_SveTernOpFirstArgTestTemplate.template", "SveVecTernOpFirstArgTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveImmTernOpTestTemplate.template", "SveVecImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveImmTernOpTestTemplate.template", "SveVecImmTernOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), + ("_SveImm2TernOpTestTemplate.template", "SveVecImm2TernOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), + ("_SveTernOpMaskedOpTestTemplate.template", "SveVecTernOpMaskedTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveImmTernOpFirstArgTestTemplate.template", "SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveImm2TernOpTestTemplate.template", "SveVecTernOpImm2Test.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveImmBinaryOpDifferentRetTypeTestTemplate.template", "SveVecImmBinOpDifferentRetType.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveScalarBinOpTestTemplate.template", "SveScalarBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleScalarOpTest_ValidationLogic }), + ("_SveScalarTernOpTestTemplate.template", "SveScalarTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleScalarOpTest_ValidationLogic }), + ("_SveImm2UnaryOpTestTemplate.template", "SveVecImm2UnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_SveMinimalUnaryOpTestTemplate.template", "SveVecReduceUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecReduceOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = VecReduceUnOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = VecReduceUnOpTest_VectorValidationLogicForCndSel_FalseValue }), + ("_SveMasklessUnaryOpTestTemplate.template", "SveMasklessSimpleVecOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_SveVecAndScalarOpTest.template", "SveVecAndScalarOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic }), + ("_SveMasklessBinaryOpTestTemplate.template", "SveMasklessVecBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_SveStoreTemplate.template", "SveStoreTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_SveStoreTemplate.template", "SveStoreNarrowTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogicForNarrowing }), + ("_SveStoreTemplate.template", "SveStoreNonTemporalTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_SveTernaryOpValidateTestTemplate.template", "SveVecTernOpValidateTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SveValidateForEachRetElementCount_ValidationLogic }), + ("_SveBinaryOpTupleTestTemplate.template", "SveVecBinOpTupleTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SveValidateForEachRetElementCount_ValidationLogic }), + }; +} diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index b2a670dc6b83df..34dbc0aba3af50 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -11,7 +11,7 @@ // It executes automatically when building the relevant hwintrinsic test projects // // New tests can be generated from the template by adding an entry to the -// appropriate Inputs array below. +// appropriate Inputs array in Arm/*Tests.cs // // You can support a new Isa by creating a new array and adding a new // "ProcessInputs" call at the bottom of the script. @@ -22,5236 +22,80 @@ // * outputDirectory - This should be somewhere under the obj folder for the project and is where generated tests are written // * testListFileName - This should likewise be somewhere under the obj folder and is where the list of generated tests is written -const string SimpleOpTest_ValidationLogic = @"if ({ValidateFirstResult}) +class GenerateHWIntrinsicTests_Arm +{ + static void Main(string[] args) + { + string projectName = args[0]; + string templateDirectory = args[1]; + string outputDirectory = args[2]; + string testListFileName = args[3]; + + ProcessInputs("AdvSimd", AdvSimdTests.AdvSimdInputs); + ProcessInputs("AdvSimd.Arm64", AdvSimdTests.AdvSimd_Arm64Inputs); + ProcessInputs("Aes", AdvSimdTests.AesInputs); + ProcessInputs("ArmBase", BaseTests.ArmBaseInputs); + ProcessInputs("ArmBase.Arm64", BaseTests.ArmBase_Arm64Inputs); + ProcessInputs("Crc32", BaseTests.Crc32Inputs); + ProcessInputs("Crc32.Arm64", BaseTests.Crc32_Arm64Inputs); + ProcessInputs("Dp", AdvSimdTests.DpInputs); + ProcessInputs("Rdm", AdvSimdTests.RdmInputs); + ProcessInputs("Rdm.Arm64", AdvSimdTests.Rdm_Arm64Inputs); + ProcessInputs("Sha1", AdvSimdTests.Sha1Inputs); + ProcessInputs("Sha256", AdvSimdTests.Sha256Inputs); + ProcessInputs("Sha256", AdvSimdTests.Sha256Inputs); + ProcessInputs("Sve", SveTests.SveInputs); + ProcessInputs("Sve2", Sve2Tests.Sve2Inputs); + + void ProcessInputs(string groupName, (string templateFileName, Dictionary templateData)[] inputs) + { + if (!projectName.Equals($"{groupName}_r") && !projectName.Equals($"{groupName}_ro")) { - succeeded = false; + return; } - else - { - for (var i = 1; i < RetElementCount; i++) - { - if ({ValidateRemainingResults}) - { - succeeded = false; - break; - } - } - }"; - -const string SimpleVecOpTest_ValidationLogic = @"for (var i = 0; i < RetElementCount; i++) - { - if ({ValidateIterResult}) - { - succeeded = false; - break; - } - }"; -const string SimpleVecOpTest_ValidationLogicForNarrowing = @"for (var i = 0; i < Op1ElementCount; i++) - { - if ({ValidateIterResult}) - { - succeeded = false; - break; - } - }"; + Directory.CreateDirectory(outputDirectory); -const string SimpleVecOpTest_VectorValidationLogic = @"succeeded = !({ValidateVectorResult});"; - -const string SimpleScalarOpTest_ValidationLogic = @"succeeded = !({ValidateScalarResult});"; - -const string SimpleTernVecOpTest_ValidationLogic = @"for (var i = 0; i < RetElementCount; i++) + using (var testListFile = new StreamWriter(testListFileName, append: false)) { - if ({ValidateIterResult}) + foreach (var input in inputs) { - succeeded = false; - break; + ProcessInput(testListFile, groupName, input); } - }"; - - -const string SimpleVecOpTest_ValidationLogicForCndSel = @"for (var i = 0; i < RetElementCount; i++) - { - {RetBaseType} iterResult = (mask[i] != 0) ? {GetIterResult} : falseVal[i]; - if (iterResult != result[i]) - { - succeeded = false; - break; - } - }"; - -const string SimpleVecOpTest_ValidationLogicForCndSelMask = @"for (var i = 0; i < RetElementCount; i++) - { - {RetBaseType} iterResult = ({GetIterResult} != 0) ? trueVal[i] : falseVal[i]; - if (iterResult != result[i]) - { - succeeded = false; - break; - } - }"; - -const string SimpleVecOpTest_ValidationLogicForCndSel_FalseValue = @"for (var i = 0; i < RetElementCount; i++) - { - {RetBaseType} iterResult = (mask[i] != 0) ? trueVal[i] : {GetIterResult}; - if (mask[i] != 0) - { - // Pick the trueValue - if (iterResult != result[i]) - { - succeeded = false; - break; - } - } - else - { - // For false, the values are merged with destination, and we do not know - // those contents would be, so skip verification for them. - } - }"; - -const string SimpleVecOpTest_ValidationLogicForCndSelForNarrowing = @"for (var i = 0; i < Op1ElementCount; i++) - { - {RetBaseType} iterResult = (mask[i] != 0) ? {GetIterResult} : falseVal[i]; - if ({ConvertFunc}(iterResult) != {ConvertFunc}(result[i])) - { - succeeded = false; - break; - } - }"; - -const string SimpleVecOpTest_ValidationLogicForCndSelForNarrowing_FalseValue = @"for (var i = 0; i < Op1ElementCount; i++) - { - {RetBaseType} iterResult = (mask[i] != 0) ? trueVal[i] : {GetIterResult}; - if (mask[i] != 0) - { - // Pick the trueValue - if ({ConvertFunc}(iterResult) != {ConvertFunc}(result[i])) - { - succeeded = false; - break; - } - } - else - { - // For false, the values are merged with destination, and we do not know - // those contents would be, so skip verification for them. - } - }"; - - -const string SimpleVecOpTest_VectorValidationLogicForCndSel = @" - - {RetBaseType}[] vectorResult = {GetVectorResult}; - {RetBaseType}[] maskedVectorResult = new {RetBaseType}[vectorResult.Length]; - - for (var i = 0; i < vectorResult.Length; i++) - { - maskedVectorResult[i] = (mask[i] != 0) ? vectorResult[i] : falseVal[i]; - } - - if (!result.SequenceEqual(maskedVectorResult)) - { - succeeded = false; - } - "; - -const string SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue = @" - { - {RetBaseType}[] vectorResult = {GetVectorResult}; - {RetBaseType}[] maskedVectorResult = new {RetBaseType}[vectorResult.Length]; - - for (var i = 0; i < vectorResult.Length; i++) - { - {RetBaseType} iterResult = (mask[i] != 0) ? trueVal[i] : vectorResult[i]; - if (mask[i] != 0) - { - // Pick the trueValue - if (iterResult != result[i]) - { - succeeded = false; - break; - } - } - else - { - // For false, the values are merged with destination, and we do not know - // those contents would be, so skip verification for them. - } - } - }"; - -const string SimpleTernVecOpTest_ValidationLogicForCndSel = @"for (var i = 0; i < RetElementCount; i++) - { - {RetBaseType} iterResult = (mask[i] != 0) ? {GetIterResult} : falseVal[i]; - if ({ConvertFunc}(iterResult) != {ConvertFunc}(result[i])) - { - succeeded = false; - break; - } - }"; - -const string SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue = @"for (var i = 0; i < RetElementCount; i++) - { - {RetBaseType} iterResult = (mask[i] != 0) ? trueVal[i] : {GetIterResult}; - if (mask[i] != 0) - { - // Pick the trueValue - if ({ConvertFunc}(iterResult) != {ConvertFunc}(result[i])) - { - succeeded = false; - break; - } - } - else - { - // For false, the values are merged with destination, and we do not know - // those contents would be, so skip verification for them. - } - }"; - -const string VecPairBinOpTest_ValidationLogic = @" - int index = 0; - int half = RetElementCount / 2; - for (var i = 0; i < RetElementCount; i+=2, index++) - { - if ({ValidateEntry}) - { - succeeded = false; - break; - } - }"; - -const string SveValidateForEachRetElementCount_ValidationLogic = @" - for (var i = 0; i < RetElementCount; i++) - { - if ({ValidateEntry}) - { - succeeded = false; - break; - } - }"; - -const string VecReduceUnOpTest_VectorValidationLogicForCndSel = @" - { - var hasFailed = (mask[0] != 0) ? ({ValidateReduceOpResult}): (falseVal[0] != result[0]); - - if (hasFailed) - { - succeeded = false; - } - else - { - for (var i = 1; i < RetElementCount; i++) - { - hasFailed = (mask[i] != 0) ? ({ValidateRemainingResults}) : (falseVal[i] != result[i]); - if (hasFailed) - { - succeeded = false; - break; - } - } - } - }"; + } + } + void ProcessInput(StreamWriter testListFile, string groupName, (string templateFileName, Dictionary templateData) input) + { + var testName = input.templateData["TestName"]; + var fileName = Path.Combine(outputDirectory, $"{testName.Replace('_', '.')}.cs"); -const string VecReduceUnOpTest_VectorValidationLogicForCndSel_FalseValue = @" - { - var hasFailed = (mask[0] != 0) ? (trueVal[0] != result[0]): ({ValidateReduceOpResult}); - if (hasFailed) - { - succeeded = false; - } - else - { - for (var i = 1; i < RetElementCount; i++) - { - hasFailed = (mask[i] != 0) ? (trueVal[i] != result[i]) : ({ValidateRemainingResults}); - if (hasFailed) - { - succeeded = false; - break; - } - } - } - }"; + var matchingTemplate = TestTemplates.Templates.Where((t) => t.outputTemplateName.Equals(input.templateFileName)).SingleOrDefault(); + var template = string.Empty; -const string VecReduceOpTest_ValidationLogic = @"if ({ValidateReduceOpResult}) + if (matchingTemplate.templateFileName is null) { - succeeded = false; + string templateFileName = Path.Combine(templateDirectory, input.templateFileName); + template = File.ReadAllText(templateFileName); } else { - for (int i = 1; i < RetElementCount; i++) - { - if ({ValidateRemainingResults}) - { - succeeded = false; - break; - } - } - }"; - -const string SecureHashOpTest_ValidationLogic = @"{RetBaseType}[] expectedResult = new {RetBaseType}[]{ExpectedResult}; + string templateFileName = Path.Combine(templateDirectory, matchingTemplate.templateFileName); + template = File.ReadAllText(templateFileName); - for (int i = 0; i < RetElementCount; i++) - { - if (result[i] != expectedResult[i]) + foreach (var kvp in matchingTemplate.templateData) { - succeeded = false; - break; + template = template.Replace($"{{{kvp.Key}}}", kvp.Value); } - }"; - -(string templateFileName, string outputTemplateName, Dictionary templateData)[] Templates = new[] -{ - ("_UnaryOpScalarTestTemplate.template", "DuplicateTest.template", new Dictionary { ["TemplateName"] = "Duplicate", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_ImmUnaryOpTestTemplate.template", "ImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_ImmUnaryOpTestTemplate.template", "VecImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_ImmTernaryOpTestTemplate.template", "ImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_ImmOpTestTemplate.template", "ImmOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_ImmBinaryOpTestTemplate.template", "ImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_ImmBinaryOpTestTemplate.template", "VecImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_BinaryOpTestTemplate.template", "SimpleBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_TernaryOpTestTemplate.template", "VecTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_ImmTernaryOpTestTemplate.template", "VecImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_ImmTernaryOpTestTemplate.template", "SimpleImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_UnaryOpTestTemplate.template", "SimpleUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_UnaryOpTestTemplate.template", "SimpleVecOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_BinaryOpTestTemplate.template", "VecPairBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecPairBinOpTest_ValidationLogic }), - ("_BinaryOp_SveTestTemplate.template", "SveVecPairBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecPairBinOpTest_ValidationLogic }), - ("_BinaryOp_SveTestTemplate.template", "SveVecBinaryOpValidateTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SveValidateForEachRetElementCount_ValidationLogic }), - ("_UnaryOpTestTemplate.template", "VecReduceUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecReduceOpTest_ValidationLogic }), - ("_BinaryOpTestTemplate.template", "VecBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_TernaryOpTestTemplate.template", "SimpleTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_UnaryOpTestTemplate.template", "SecureHashUnOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), - ("_BinaryOpTestTemplate.template", "SecureHashBinOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), - ("_TernaryOpTestTemplate.template", "SecureHashTernOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), - ("_SveUnaryOpTestTemplate.template", "SveSimpleVecOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), - ("_SveUnaryOpDifferentRetTypeTestTemplate.template", "SveSimpleVecOpDiffRetTypeTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogicForNarrowing, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSelForNarrowing, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSelForNarrowing_FalseValue }), - ("_SveUnaryOpDifferentRetTypeTestTemplate.template", "SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), - ("_SveBinaryOpTestTemplate.template", "SveVecBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), - ("_SveBinaryOpTestTemplate.template", "SveVecBinOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), - ("_SveBinaryOpTestTemplate.template", "SveVecBinOpConvertTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), - ("_SveBinaryOpDifferentRetTypeTestTemplate.template", "SveVecBinOpDifferentRetType.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue}), - ("_SveMasklessBinaryOpTestTemplate.template", "SveVecBinOpTestScalarRet.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleScalarOpTest_ValidationLogic }), - ("_SveBinaryRetMaskOpTestTemplate.template", "SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue, ["TemplateValidationLogicForCndSelMask"] = SimpleVecOpTest_ValidationLogicForCndSelMask }), - ("_SveBinaryOpDifferentTypesTestTemplate.template", "SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), - ("_SveBinaryMaskOpTestTemplate.template", "SveMaskVecBinOpConvertTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), - ("_SveImmBinaryOpTestTemplate.template", "SveVecImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), - ("_SveImmBinaryOpTestTemplate.template", "SveVecImmBinOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), - ("_SveImmUnaryOpTestTemplate.template", "SveVecImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), - ("_SveTernOpTestTemplate.template", "SveVecTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), - ("_SveTernOpTestTemplate.template", "SveVecTernOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), - ("_SveTernOpFirstArgTestTemplate.template", "SveVecTernOpFirstArgTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), - ("_SveImmTernOpTestTemplate.template", "SveVecImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), - ("_SveImmTernOpTestTemplate.template", "SveVecImmTernOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), - ("_SveImm2TernOpTestTemplate.template", "SveVecImm2TernOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), - ("_SveTernOpMaskedOpTestTemplate.template", "SveVecTernOpMaskedTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), - ("_SveImmTernOpFirstArgTestTemplate.template", "SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), - ("_SveScalarBinOpTestTemplate.template", "SveScalarBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleScalarOpTest_ValidationLogic }), - ("_SveScalarTernOpTestTemplate.template", "SveScalarTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleScalarOpTest_ValidationLogic }), - ("_SveImm2UnaryOpTestTemplate.template", "SveVecImm2UnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_SveMinimalUnaryOpTestTemplate.template", "SveVecReduceUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecReduceOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = VecReduceUnOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = VecReduceUnOpTest_VectorValidationLogicForCndSel_FalseValue }), - ("_SveMasklessUnaryOpTestTemplate.template", "SveMasklessSimpleVecOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_SveVecAndScalarOpTest.template", "SveVecAndScalarOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic }), - ("_SveMasklessBinaryOpTestTemplate.template", "SveMasklessVecBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_SveStoreTemplate.template", "SveStoreTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_SveStoreTemplate.template", "SveStoreNarrowTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogicForNarrowing }), - ("_SveStoreTemplate.template", "SveStoreNonTemporalTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_SveTernaryOpValidateTestTemplate.template", "SveVecTernOpValidateTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SveValidateForEachRetElementCount_ValidationLogic }), - ("_SveBinaryOpTupleTestTemplate.template", "SveVecBinOpTupleTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SveValidateForEachRetElementCount_ValidationLogic }), -}; - -(string templateFileName, Dictionary templateData)[] AdvSimdInputs = new[] -{ - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "(short)-TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "(sbyte)-TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "-TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Abs(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(short)-TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(sbyte)-TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "-TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Abs(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int16.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int32.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "SByte.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "Int16.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "Int32.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "SByte.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "-TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Abs(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Abs(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Add(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Add(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AddPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAddScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAddScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWidening(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWidening(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Byte_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int16_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int32_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_SByte_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_UInt16_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_UInt32_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Byte_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int16_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int32_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int64_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_SByte_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt16_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt32_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt64_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int64_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt64_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Add(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Add(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Add(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.Add(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Byte_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int16_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int16_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int32_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int32_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int64_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_SByte_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt16_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt16_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt32_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt32_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt64_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.And(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.And(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.And(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.And(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Ceiling_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Ceiling", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Ceiling(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Ceiling_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Ceiling", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Ceiling(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "CeilingScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CeilingScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Ceiling(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "CeilingScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CeilingScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Ceiling(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareTest(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareTest(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundAwayFromZero_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundAwayFromZero", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundAwayFromZero(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundAwayFromZero_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundAwayFromZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundAwayFromZero(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundAwayFromZeroScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundAwayFromZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToInt32RoundAwayFromZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToEven_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToEven(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToEven_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToEven(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToEvenScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToEvenScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToInt32RoundToEven(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToNegativeInfinity_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToNegativeInfinity", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToNegativeInfinity(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToNegativeInfinity_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToNegativeInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToNegativeInfinity(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToNegativeInfinityScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToNegativeInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToInt32RoundToNegativeInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToPositiveInfinity_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToPositiveInfinity", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToPositiveInfinity(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToPositiveInfinity_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToPositiveInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToPositiveInfinity(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToPositiveInfinityScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToPositiveInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToInt32RoundToPositiveInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToZero_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToZero", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToZero(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToZero_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToInt32RoundToZero(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt32RoundToZeroScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt32RoundToZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToInt32RoundToZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingle_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingle_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingle_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingle_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingleScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingleScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingleScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingleScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundAwayFromZero_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundAwayFromZero", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundAwayFromZero(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundAwayFromZero_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundAwayFromZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundAwayFromZero(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundAwayFromZeroScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundAwayFromZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt32RoundAwayFromZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToEven_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToEven(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToEven_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToEven(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToEvenScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToEvenScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt32RoundToEven(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToNegativeInfinity_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToNegativeInfinity", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToNegativeInfinity(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToNegativeInfinity_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToNegativeInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToNegativeInfinity(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToNegativeInfinityScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToNegativeInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt32RoundToNegativeInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToPositiveInfinity_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToPositiveInfinity", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToPositiveInfinity(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToPositiveInfinity_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToPositiveInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToPositiveInfinity(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToPositiveInfinityScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToPositiveInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt32RoundToPositiveInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToZero_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToZero", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToZero(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToZero_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConvertToUInt32RoundToZero(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt32RoundToZeroScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt32RoundToZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt32RoundToZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "DivideScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DivideScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Divide(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "DivideScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DivideScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_Byte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "8", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_Int16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "4", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_Int32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_SByte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "8", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_Single_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "2", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_UInt16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "4", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_Vector128_UInt32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "2", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_Byte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "8", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_Int16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "4", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_Int32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_SByte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "8", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_Single_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "2", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_UInt16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "4", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_Vector128_UInt32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "2", ["ValidateIterResult"] = "firstOp[Imm] != result[i]"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Byte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_SByte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Single_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Byte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_SByte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Single_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.DoubleToInt64Bits(firstOp[ElementIndex]) != BitConverter.DoubleToInt64Bits(result)"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUnsigned(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUnsigned(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUnsigned(firstOp[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUnsignedUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUnsignedUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUnsignedUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingSaturateUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Floor_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Floor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Floor(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Floor_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Floor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Floor(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "FloorScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FloorScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Floor(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "FloorScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FloorScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Floor(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAdd_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAdd_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddNegatedScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAddNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddNegatedScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAddNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtract_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtract_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractNegatedScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtractNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractNegatedScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtractNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertScalarTest.template", new Dictionary { ["TestName"] = "InsertScalar_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp[0], i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("InsertScalarTest.template", new Dictionary { ["TestName"] = "InsertScalar_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp[0], i) != result[i]"}), - ("InsertScalarTest.template", new Dictionary { ["TestName"] = "InsertScalar_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp[0], i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_Byte_15", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "15", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_SByte_15", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "15", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_Single_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarTest.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x2_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i]))"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x3_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.SingleToInt32Bits(result3[i]))"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector64x4_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.SingleToInt32Bits(result3[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input4, ElementIndex, newData[3], i)) != BitConverter.SingleToInt32Bits(result4[i]))"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_Byte", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_Int16", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_Int32", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_SByte", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_Single", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[0]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_UInt16", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64_UInt32", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Byte", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Int16", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Int32", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_SByte", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Single", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[0]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_UInt16", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_UInt32", ["Isa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x2Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x2", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x3Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x3", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector64x4Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector64x4", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Byte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Double", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Int16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Int32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Int64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_SByte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Single", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_UInt16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_UInt32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_UInt64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Byte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Double", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Int16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Int32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Int64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_SByte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Single", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_UInt16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_UInt32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_UInt64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2] || result4[i] != input[i + 8 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2] || result4[i] != input[i + 8 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2] || result4[i] != input[i + 4 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2] || result4[i] != input[i + 4 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2] || result4[i] != input[i + 2 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2] || result4[i] != input[i + 2 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2] || result4[i] != input[i + 2 * 3]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipSByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipUShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipUInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector64AndUnzipFloat", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipSByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipUShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipUInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector64AndUnzipFloat", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipSByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipUShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipUInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector64AndUnzipFloat", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector64AndUnzip", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Max(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Max(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumber_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumber_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumber(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumber(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Min(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Min(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumber_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumber_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumber(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumber(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddByScalar_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector64_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAddBySelectedScalar_Vector128_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[i], right[0])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[i], right[0])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[0]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_Int16_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_UInt16_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector64_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Int16_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Single_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Single_Vector128_Single_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_UInt16_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLower_Vector64_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWidening(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndAdd_Vector64_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningLowerAndSubtract_Vector64_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpper_Vector128_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpper(firstOp, secondOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndAdd_Vector128_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndAdd(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalarWideningUpperAndSubtract_Vector128_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalarWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyByScalarWideningUpperAndSubtract(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingByScalarSaturateHigh_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingByScalarSaturateHigh_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingByScalarSaturateHigh_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingByScalarSaturateHigh_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[0]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingSaturateHigh_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingSaturateHigh_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingSaturateHigh_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingSaturateHigh_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerAndAddSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerAndAddSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerAndSubtractSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerAndSubtractSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerByScalarAndAddSaturate_Vector64_Int16_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerByScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerByScalarAndAddSaturate_Vector64_Int32_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerByScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerByScalarAndSubtractSaturate_Vector64_Int16_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerByScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerByScalarAndSubtractSaturate_Vector64_Int32_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerByScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningLowerBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLowerByScalar_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLowerByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLowerByScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLowerByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[i], right[0]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateLowerBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpperByScalar_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpperByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpperByScalar(left, right[0], i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpperByScalar_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpperByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpperByScalar(left, right[0], i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpperByScalar(firstOp, secondOp[Imm], i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpperByScalar(firstOp, secondOp[Imm], i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpperByScalar(firstOp, secondOp[Imm], i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateUpperBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningSaturateUpperByScalar(firstOp, secondOp[Imm], i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperAndAddSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperAndAddSaturate(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperAndAddSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperAndAddSaturate(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperAndSubtractSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperAndSubtractSaturate(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperAndSubtractSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperAndSubtractSaturate(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperByScalarAndAddSaturate_Vector128_Int16_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperByScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndAddSaturate(firstOp, secondOp, thirdOp[0], i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperByScalarAndAddSaturate_Vector128_Int32_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperByScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndAddSaturate(firstOp, secondOp, thirdOp[0], i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperByScalarAndSubtractSaturate_Vector128_Int16_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperByScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(firstOp, secondOp, thirdOp[0], i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperByScalarAndSubtractSaturate_Vector128_Int32_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperByScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(firstOp, secondOp, thirdOp[0], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndAddSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndAddSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndAddSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndAddSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningUpperBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(firstOp, secondOp, thirdOp[Imm], i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingByScalarSaturateHigh_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingByScalarSaturateHigh_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingByScalarSaturateHigh_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingByScalarSaturateHigh_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingByScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[0]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector64_Int16_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[i], secondOp[Imm]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingSaturateHigh_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingSaturateHigh_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingSaturateHigh_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingSaturateHigh_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[i], right[i]) != result[i]"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalarBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[0], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalarBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[0], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector64_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_UInt16_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_UInt16_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_UInt32_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractBySelectedScalar_Vector128_UInt32_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtractByScalar_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtractByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[0]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Negate(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Negate(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int16.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int32.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "SByte.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "Int16.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "Int32.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "SByte.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Negate(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Negate(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Not(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Not(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Not(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Not(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Or(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Or(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Or(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Or(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWideningUpper(left, right, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x409e8000"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedReciprocalEstimate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x409e8000"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedReciprocalEstimate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x400e8000"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedReciprocalSqrtEstimate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x400e8000"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedReciprocalSqrtEstimate(firstOp[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStep_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStep", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPReciprocalSqrtStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStep_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPReciprocalSqrtStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStep_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPReciprocalStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStep_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPReciprocalStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement16_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement16(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement32_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement32", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement32(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement32_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement32", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement32(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement32_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement32(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement32_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement32(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElement8_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ReverseElement8(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundAwayFromZero_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundAwayFromZero", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundAwayFromZero(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundAwayFromZero_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundAwayFromZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundAwayFromZero(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundAwayFromZeroScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundAwayFromZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundAwayFromZero(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundAwayFromZeroScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundAwayFromZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundAwayFromZero(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToNearest_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNearest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToNearest(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToNearest_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNearest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToNearest(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundToNearestScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNearestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToNearest(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundToNearestScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNearestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToNearest(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToNegativeInfinity_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNegativeInfinity", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToNegativeInfinity(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToNegativeInfinity_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNegativeInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToNegativeInfinity(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundToNegativeInfinityScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNegativeInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToNegativeInfinity(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundToNegativeInfinityScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNegativeInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToNegativeInfinity(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToPositiveInfinity_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToPositiveInfinity", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToPositiveInfinity(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToPositiveInfinity_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToPositiveInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToPositiveInfinity(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundToPositiveInfinityScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToPositiveInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToPositiveInfinity(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "RoundToPositiveInfinityScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToPositiveInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToPositiveInfinity(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToZero_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToZero", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToZero(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToZero_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToZero(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToZeroScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToZero(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToZeroScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.RoundToZero(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRounded(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftArithmetic(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsert_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "32", ["ValidateIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsertScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftLeftAndInsert(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftAndInsertScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftLeftAndInsert(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogical(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogical(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRounded(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRounded(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogical(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogical(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "4", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "8", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "16", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsert_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "32", ["ValidateIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsertScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftRightAndInsert(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightAndInsertScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightAndInsertScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftRightAndInsert(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAddScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAddScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmetic(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAddScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAddScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAddScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAddScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogical(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogical(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "SqrtScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SqrtScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Sqrt(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "SqrtScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SqrtScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Sqrt(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Byte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Int16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_SByte_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_UInt16_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Byte_15", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "15", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.DoubleToInt64Bits(firstOp[ElementIndex]) != BitConverter.DoubleToInt64Bits(result)"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Int16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Int32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_SByte_15", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "15", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_Single_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "3", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_UInt16_7", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "7", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_UInt32_3", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "3", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarTest.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x2_Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x3_Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector64x4_Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Float", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4UShort", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Short", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Subtract(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Subtract(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Subtract(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Subtract(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Subtract(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.Subtract(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Byte_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int16_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int16_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int32_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int32_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int64_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_SByte_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt16_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt16_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt32_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt32_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt64_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), - ("VectorLookup_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookup2_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 40)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), - ("VectorLookup_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookup2_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 40)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), - ("VectorLookup_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookup3_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 60)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), - ("VectorLookup_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookup3_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 60)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), - ("VectorLookup_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookup4_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 80)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), - ("VectorLookup_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookup4_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 80)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), - ("VectorLookupExtension_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension2_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 40)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), - ("VectorLookupExtension_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension2_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 40)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), - ("VectorLookupExtension_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension3_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 60)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), - ("VectorLookupExtension_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension3_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 60)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), - ("VectorLookupExtension_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension4_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 80)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), - ("VectorLookupExtension_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension4_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 80)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Xor(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Xor(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Xor(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Xor(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}) -}; - -(string templateFileName, Dictionary templateData)[] AdvSimd_Arm64Inputs = new[] -{ - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "-TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Abs(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AbsSaturate_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "Int64.MinValue", ["ValidateIterResult"] = "Helpers.AbsSaturate(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int16.MinValue", ["ValidateFirstResult"] = "Helpers.AbsSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int32.MinValue", ["ValidateFirstResult"] = "Helpers.AbsSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int64.MinValue", ["ValidateFirstResult"] = "Helpers.AbsSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "SByte.MinValue", ["ValidateFirstResult"] = "Helpers.AbsSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Abs(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteDifference(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Add(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcrossWidening_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcrossWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AddPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AddPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AddPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AddPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.AddPairwise(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.AddPairwise(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Byte_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int16_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int32_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_SByte_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_UInt16_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_UInt32_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Byte_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int16_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int32_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int64_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_SByte_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt16_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt32_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt64_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Byte_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Byte_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int16_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int16_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int32_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int32_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int64_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_SByte_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_SByte_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt16_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt16_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt32_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt32_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt64_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Ceiling_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Ceiling", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Ceiling(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareTest(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareTestScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareTest(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareTestScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareTest(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareTestScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareTest(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToDouble_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ConvertToDouble(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToDouble_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ConvertToDouble(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToDouble_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ConvertToDouble(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToDoubleScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToDoubleScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ConvertToDouble(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToDoubleScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToDoubleScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ConvertToDouble(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToDoubleUpper_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToDoubleUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ConvertToDoubleUpper(firstOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundAwayFromZero_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundAwayFromZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToInt64RoundAwayFromZero(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundAwayFromZeroScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundAwayFromZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToInt64RoundAwayFromZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToEven_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToInt64RoundToEven(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToEvenScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToEvenScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToInt64RoundToEven(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToNegativeInfinity_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToNegativeInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToInt64RoundToNegativeInfinity(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToNegativeInfinityScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToNegativeInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToInt64RoundToNegativeInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToPositiveInfinity_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToPositiveInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToInt64RoundToPositiveInfinity(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToPositiveInfinityScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToPositiveInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToInt64RoundToPositiveInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToZero_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToInt64RoundToZero(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToInt64RoundToZeroScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToInt64RoundToZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToInt64RoundToZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingleLower_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingleLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingle(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingleRoundToOddLower_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingleRoundToOddLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3FF9E427C7C5260FL)", ["ValidateIterResult"] = "0x3FCF213F != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingleRoundToOddUpper_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingleRoundToOddUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3FCF213E)",["NextValueOp2"] = "BitConverter.Int64BitsToDouble(0x3FF9E427C7C5260FL)", ["ValidateIterResult"] = "(i < 2 ? 0x3FCF213E : 0x3FCF213F) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ConvertToSingleUpper_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToSingleUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConvertToSingleUpper(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundAwayFromZero_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundAwayFromZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToUInt64RoundAwayFromZero(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundAwayFromZeroScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundAwayFromZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt64RoundAwayFromZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToEven_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToUInt64RoundToEven(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToEvenScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToEvenScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt64RoundToEven(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToNegativeInfinity_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToNegativeInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToUInt64RoundToNegativeInfinity(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToNegativeInfinityScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToNegativeInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt64RoundToNegativeInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToPositiveInfinity_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToPositiveInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToUInt64RoundToPositiveInfinity(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToPositiveInfinityScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToPositiveInfinityScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt64RoundToPositiveInfinity(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToZero_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConvertToUInt64RoundToZero(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ConvertToUInt64RoundToZeroScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ConvertToUInt64RoundToZeroScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Helpers.ConvertToUInt64RoundToZero(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Divide(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Int64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Double_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int64_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt64_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturateUnsigned(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturateUnsigned(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingSaturateUnsignedScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ExtractNarrowingSaturateUnsigned(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Floor_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Floor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Floor(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAdd_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddByScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddByScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddByScalar_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddBySelectedScalar_Vector128_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddBySelectedScalar_Vector128_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddBySelectedScalar_Vector128_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalarBySelectedScalar_Vector64_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalarBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalarBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtract_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractByScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractByScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractByScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractByScalar_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractBySelectedScalar_Vector128_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractBySelectedScalar_Vector128_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractBySelectedScalar_Vector128_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalarBySelectedScalar_Vector64_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalarBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalarBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Byte_7_Vector64_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Byte_7_Vector128_Byte_15", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "15", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Int16_3_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Int16_3_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Int32_1_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Int32_1_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_SByte_7_Vector64_SByte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_SByte_7_Vector128_SByte_15", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "15", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Single_1_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_Single_1_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_UInt16_3_Vector64_UInt16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_UInt16_3_Vector128_UInt16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_UInt32_1_Vector64_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector64_UInt32_1_Vector128_UInt32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Byte_15_Vector64_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex1"] = "15", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Byte_15_Vector128_Byte_15", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex1"] = "15", ["ElementIndex2"] = "15", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Double_1_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Int16_7_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Int16_7_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Int32_3_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Int32_3_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Int64_1_Vector128_Int64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_SByte_15_Vector64_SByte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex1"] = "15", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_SByte_15_Vector128_SByte_15", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex1"] = "15", ["ElementIndex2"] = "15", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Single_3_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_Single_3_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_UInt16_7_Vector64_UInt16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_UInt16_7_Vector128_UInt16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex1"] = "7", ["ElementIndex2"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_UInt32_3_Vector64_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_UInt32_3_Vector128_UInt32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex1"] = "3", ["ElementIndex2"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("InsertSelectedScalarTest.template", new Dictionary { ["TestName"] = "InsertSelectedScalar_Vector128_UInt64_1_Vector128_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "InsertSelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex1"] = "1", ["ElementIndex2"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex1, thirdOp[ElementIndex2], i) != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Double", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[0]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_SByte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_UInt16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Int64_0", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "0", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i])"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i]))"}), - ("LoadAndInsertScalarx2Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x2_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(BitConverter.DoubleToInt64Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.DoubleToInt64Bits(result1[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.DoubleToInt64Bits(result2[i]))"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_SByte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_UInt16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Int64_0", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "0", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i])"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.SingleToInt32Bits(result3[i]))"}), - ("LoadAndInsertScalarx3Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x3_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(BitConverter.DoubleToInt64Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.DoubleToInt64Bits(result1[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.DoubleToInt64Bits(result2[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.DoubleToInt64Bits(result3[i]))"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_SByte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "7", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_UInt16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "3", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Int64_0", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "0", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(Helpers.Insert(input1, ElementIndex, newData[0], i) != result1[i]) || (Helpers.Insert(input2, ElementIndex, newData[1], i) != result2[i]) || (Helpers.Insert(input3, ElementIndex, newData[2], i) != result3[i]) || (Helpers.Insert(input4, ElementIndex, newData[3], i) != result4[i])"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(BitConverter.SingleToInt32Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.SingleToInt32Bits(result1[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.SingleToInt32Bits(result2[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.SingleToInt32Bits(result3[i])) || (BitConverter.SingleToInt32Bits(Helpers.Insert(input4, ElementIndex, newData[3], i)) != BitConverter.SingleToInt32Bits(result4[i]))"}), - ("LoadAndInsertScalarx4Test.template", new Dictionary { ["TestName"] = "LoadAndInsertScalar_Vector128x4_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndInsertScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(BitConverter.DoubleToInt64Bits(Helpers.Insert(input1, ElementIndex, newData[0], i)) != BitConverter.DoubleToInt64Bits(result1[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input2, ElementIndex, newData[1], i)) != BitConverter.DoubleToInt64Bits(result2[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input3, ElementIndex, newData[2], i)) != BitConverter.DoubleToInt64Bits(result3[i])) || (BitConverter.DoubleToInt64Bits(Helpers.Insert(input4, ElementIndex, newData[3], i)) != BitConverter.DoubleToInt64Bits(result4[i]))"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadAndReplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[0] != result[i]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x2Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x2", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x3Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x3", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "LoadAndReplicateToVector128x4Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "LoadAndReplicateToVector128x4", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[0] || result2[i] != input[1] || result3[i] != input[2] || result4[i] != input[3]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairScalarVector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairScalarVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.LoadPairScalar(firstOp, i) != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairScalarVector64_Single", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairScalarVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.LoadPairScalar(firstOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairScalarVector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairScalarVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.LoadPairScalar(firstOp, i) != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairScalarVector64NonTemporal_Int32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairScalarVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.LoadPairScalar(firstOp, i) != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairScalarVector64NonTemporal_Single", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairScalarVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.LoadPairScalar(firstOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairScalarVector64NonTemporal_UInt32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairScalarVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.LoadPairScalar(firstOp, i) != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_Double", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_Single", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_Byte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_Double", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_Int16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_Int32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_Int64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_SByte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_Single", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_UInt16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_UInt32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector64NonTemporal_UInt64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector64NonTemporal", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_Double", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_Single", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_Byte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_Double", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_Int16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_Int32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_Int64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_SByte", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_Single", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_UInt16", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_UInt32", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadPairVectorTest.template", new Dictionary { ["TestName"] = "LoadPairVector128NonTemporal_UInt64", ["Isa"] = "AdvSimd.Arm64", ["Method"] = "LoadPairVector128NonTemporal", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 16]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 16]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 16] || result3[i] != input[i + 16 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 16] || result3[i] != input[i + 16 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 16] || result3[i] != input[i + 16 * 2] || result4[i] != input[i + 16 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 16] || result3[i] != input[i + 16 * 2] || result4[i] != input[i + 16 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2] || result4[i] != input[i + 8 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 8] || result3[i] != input[i + 8 * 2] || result4[i] != input[i + 8 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2] || result4[i] != input[i + 4 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2] || result4[i] != input[i + 4 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2] || result4[i] != input[i + 2 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2] || result4[i] != input[i + 2 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 4] || result3[i] != input[i + 4 * 2] || result4[i] != input[i + 4 * 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i] || result2[i] != input[i + 2] || result3[i] != input[i + 2 * 2] || result4[i] != input[i + 2 * 3]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipSByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipUShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipUInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipUInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipFloat", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx2Test.template", new Dictionary { ["TestName"] = "Load2xVector128AndUnzipDouble", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load2xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[(i * 2) + 1]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipSByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipUShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipUInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipUInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipFloat", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx3Test.template", new Dictionary { ["TestName"] = "Load3xVector128AndUnzipDouble", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load3xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[(i * 3) + 1] || result3[i] != input[(i * 3) + 2]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipSByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipUShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipUInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipUInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipFloat", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("LoadVectorx4Test.template", new Dictionary { ["TestName"] = "Load4xVector128AndUnzipDouble", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Load4xVector128AndUnzip", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[(i * 4) + 1] || result3[i] != input[(i * 4) + 2] || result4[i] != input[(i * 4) + 3]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Max(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumber_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumber(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxNumberAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwise_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumberPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumberPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Max(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Max(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Min(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumber_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumber(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinNumberAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwise_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumberPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumberPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Min(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Min(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyByScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(left[i], right[0])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyBySelectedScalar_Vector128_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingSaturateHighScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingSaturateHighScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingSaturateHigh(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningAndAddSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningAndAddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningAndAddSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningAndAddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningAndSubtractSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningAndSubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningAndSubtractSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningAndSubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningSaturateScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningSaturate(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndAddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndAddSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyDoublingWideningScalarBySelectedScalarAndSubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyDoublingWideningAndSubtractSaturate(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtended_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtended_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtended_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedByScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedByScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(left[i], right[0])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedBySelectedScalar_Vector128_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedBySelectedScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(firstOp[i], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalarBySelectedScalar_Vector64_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(firstOp[0], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalarBySelectedScalar_Vector64_Single_Vector64_Single_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(firstOp[0], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalarBySelectedScalar_Vector64_Single_Vector128_Single_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "3", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(firstOp[0], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingSaturateHighScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingSaturateHighScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingSaturateHigh(firstOp[0], secondOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalarBySelectedScalar_Vector64_Double_Vector128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalarBySelectedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(firstOp[0], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Negate(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "NegateSaturate_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "Int64.MinValue", ["ValidateIterResult"] = "Helpers.NegateSaturate(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int16.MinValue", ["ValidateFirstResult"] = "Helpers.NegateSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int32.MinValue", ["ValidateFirstResult"] = "Helpers.NegateSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "Int64.MinValue", ["ValidateFirstResult"] = "Helpers.NegateSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "SByte.MinValue", ["ValidateFirstResult"] = "Helpers.NegateSaturate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Negate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0x4013d00000000000"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimateScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != 0x4013d00000000000", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimateScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != 0x409e8000", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalExponentScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalExponentScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != 0x4030000000000000", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalExponentScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalExponentScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != 0x41800000", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateIterResult"] = " BitConverter.DoubleToInt64Bits(result[i]) != 0x4001d00000000000"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimateScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != 0x4001d00000000000", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimateScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != 0x400e8000", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStep_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPReciprocalSqrtStepFused(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStepScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPReciprocalSqrtStepFused(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStepScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPReciprocalSqrtStepFused(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStep_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPReciprocalStepFused(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStepScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPReciprocalStepFused(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStepScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPReciprocalStepFused(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundAwayFromZero_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundAwayFromZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundAwayFromZero(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToNearest_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNearest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToNearest(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToNegativeInfinity_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToNegativeInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToNegativeInfinity(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToPositiveInfinity_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToPositiveInfinity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToPositiveInfinity(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "RoundToZero_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "RoundToZero", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.RoundToZero(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_Int16_15", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "15", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_Int32_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "31", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_SByte_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "5", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "5", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "15", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "31", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "15", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "31", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "15", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "31", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "5", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sqrt_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Sqrt(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sqrt_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Sqrt(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sqrt_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Sqrt(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePair_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePair", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairScalar", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ConcatScalar(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairScalar", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConcatScalar(firstOp, secondOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairScalar", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ConcatScalar(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairScalarNonTemporal_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairScalarNonTemporal", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ConcatScalar(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairScalarNonTemporal_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairScalarNonTemporal", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ConcatScalar(firstOp, secondOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairScalarNonTemporal_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairScalarNonTemporal", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ConcatScalar(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Concat(firstOp, secondOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreBinOpTest.template", new Dictionary { ["TestName"] = "StorePairNonTemporal_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StorePairNonTemporal", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Concat(firstOp, secondOp, i) != result[i]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx2Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x2_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx3Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x3_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreSelectedScalarx4Test.template", new Dictionary { ["TestName"] = "StoreSelectedScalar_Vector128x4_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreSelectedScalar", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateResult"] = "input1[index] != result[0] || input2[index] != result[1] || input3[index] != result[2] || input4[index] != result[3]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx2Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "input1[i] != result[i * 2] || input2[i] != result[(i * 2) + 1]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx3Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "input1[i] != result[i * 3] || input2[i] != result[(i * 3) + 1] || input3[i] != result[(i * 3) + 2]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "StoreVectorAndZipx4Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "StoreVectorAndZip", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "input1[i] != result[i * 4] || input2[i] != result[(i * 4) + 1] || input3[i] != result[(i * 4) + 2] || input4[i] != result[(i * 4) + 3]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx2Test.template", new Dictionary { ["TestName"] = "Storex2Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx3Test.template", new Dictionary { ["TestName"] = "Storex3Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4UShort", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Short", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Float", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "float", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "float", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("StoreVectorx4Test.template", new Dictionary { ["TestName"] = "Storex4Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["Op1BaseType"] = "double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "double", ["LargestVectorSize"] = "16", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "input1[i] != result[i] || input2[i] != result[OpElementCount + i] || input3[i] != result[(OpElementCount * 2) + i] || input4[i] != result[(OpElementCount * 3) + i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Subtract(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), - ("VectorLookup_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookup2_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 40)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), - ("VectorLookup_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookup2_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 40)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), - ("VectorLookup_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookup3_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 60)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), - ("VectorLookup_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookup3_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 60)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), - ("VectorLookup_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookup4_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 80)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), - ("VectorLookup_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookup4_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 80)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, indices, table) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, indices, table) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), - ("VectorLookupExtension_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension2_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 40)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), - ("VectorLookupExtension_2Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension2_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 40)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), - ("VectorLookupExtension_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension3_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 60)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), - ("VectorLookupExtension_3Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension3_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 60)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), - ("VectorLookupExtension_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension4_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 80)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), - ("VectorLookupExtension_4Test.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension4_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp0"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 80)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, defaultValues, indices, table) != result[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), -}; - -(string templateFileName, Dictionary templateData)[] AesInputs = new[] -{ - ("AesBinOpTest.template", new Dictionary { ["TestName"] = "Decrypt_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "Decrypt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["KeySize"] = "16", ["Key"] = "{0xFF, 0xDD, 0xBB, 0x99, 0x77, 0x55, 0x33, 0x11, 0xEE, 0xCC, 0xAA, 0x88, 0x66, 0x44, 0x22, 0x00}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0x7C, 0x99, 0x02, 0x7C, 0x7C, 0x7C, 0xFE, 0x86, 0xE3, 0x7C, 0x7C, 0x97, 0xC9, 0x94, 0x7C, 0x7C}"}), - ("AesBinOpTest.template", new Dictionary { ["TestName"] = "Encrypt_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "Encrypt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["KeySize"] = "16", ["Key"] = "{0xFF, 0xDD, 0xBB, 0x99, 0x77, 0x55, 0x33, 0x11, 0xEE, 0xCC, 0xAA, 0x88, 0x66, 0x44, 0x22, 0x00}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xCA, 0xCA, 0xF5, 0xC4, 0xCA, 0x93, 0xEA, 0xCA, 0x82, 0x28, 0xCA, 0xCA, 0xC1, 0xCA, 0xCA, 0x1B}"}), - ("AesUnOpTest.template", new Dictionary { ["TestName"] = "InverseMixColumns_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "InverseMixColumns", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xA0, 0x0A, 0xE4, 0x4E, 0x28, 0x82, 0x6C, 0xC6, 0x55, 0x00, 0x77, 0x22, 0x11, 0x44, 0x33, 0x66}"}), - ("AesUnOpTest.template", new Dictionary { ["TestName"] = "MixColumns_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "MixColumns", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xAB, 0x01, 0xEF, 0x45, 0x23, 0x89, 0x67, 0xCD, 0xDD, 0x88, 0xFF, 0xAA, 0x99, 0xCC, 0xBB, 0xEE}"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_Int64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[0], right[0]) != result[1]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_UInt64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[0], right[0]) != result[1]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_Int64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[1], right[1]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[1], right[1]) != result[1]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_UInt64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[1], right[1]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[1], right[1]) != result[1]"}) -}; - -(string templateFileName, Dictionary templateData)[] ArmBaseInputs = new[] -{ - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Int32", ["Isa"] = "ArmBase", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 31; (((uint)data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_UInt32", ["Isa"] = "ArmBase", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 31; ((data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Int32", ["Isa"] = "ArmBase", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_UInt32", ["Isa"] = "ArmBase", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), -}; - -(string templateFileName, Dictionary templateData)[] ArmBase_Arm64Inputs = new[] -{ - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Int32", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingSignCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 30; (((uint)data >> index) & 1) == (((uint)data >> 31) & 1); index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingSignCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 62; (((ulong)data >> index) & 1) == (((ulong)data >> 63) & 1); index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 63; (((ulong)data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_UInt64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "UInt64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 63; ((data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyHigh_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "MultiplyHigh", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "-TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "isUnexpectedResult = Helpers.MultiplyHigh(left, right) != result;" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyHigh_UInt64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "MultiplyHigh", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "isUnexpectedResult = Helpers.MultiplyHigh(left, right) != result;" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_UInt64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), -}; - -(string templateFileName, Dictionary templateData)[] Crc32Inputs = new[] -{ - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_Byte", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20", ["ValidateResult"] = "uint expectedResult = 0x169330BA; isUnexpectedResult = (expectedResult != result);" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_UInt16", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x2019", ["ValidateResult"] = "uint expectedResult = 0x1E4864D0; isUnexpectedResult = (expectedResult != result);" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_UInt32", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113", ["ValidateResult"] = "uint expectedResult = 0x219D9805; isUnexpectedResult = (expectedResult != result);" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_Byte", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20", ["ValidateResult"] = "uint expectedResult = 0x8D3F2270; isUnexpectedResult = (expectedResult != result);" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_UInt16", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x2019", ["ValidateResult"] = "uint expectedResult = 0x9F50ACBD; isUnexpectedResult = (expectedResult != result);" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_UInt32", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113", ["ValidateResult"] = "uint expectedResult = 0x78F34758; isUnexpectedResult = (expectedResult != result);" }), -}; - -(string templateFileName, Dictionary templateData)[] Crc32_Arm64Inputs = new[] -{ - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_UInt64", ["Isa"] = "Crc32.Arm64", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt64", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113110219UL", ["ValidateResult"] = "uint expectedResult = 0xEFAAAB74; isUnexpectedResult = (expectedResult != result);" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_UInt64", ["Isa"] = "Crc32.Arm64", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt64", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113110219UL", ["ValidateResult"] = "uint expectedResult = 0x6295C71A; isUnexpectedResult = (expectedResult != result);" }), -}; - -(string templateFileName, Dictionary templateData)[] DpInputs = new[] -{ - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "DotProduct_Vector64_Int32", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "DotProduct_Vector64_UInt32", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "DotProduct_Vector128_Int32", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "DotProduct_Vector128_UInt32", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * i) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector64_Int32_Vector64_SByte_1", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector64_Int32_Vector128_SByte_3", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector64_UInt32_Vector64_Byte_1", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector64_UInt32_Vector128_Byte_3", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector128_Int32_Vector64_SByte_1", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector128_Int32_Vector128_SByte_3", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector128_UInt32_Vector64_Byte_1", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "DotProductBySelectedQuadruplet_Vector128_UInt32_Vector128_Byte_3", ["Isa"] = "Dp", ["LoadIsa"] = "AdvSimd", ["Method"] = "DotProductBySelectedQuadruplet", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.DotProduct(firstOp[i], secondOp, 4 * i, thirdOp, 4 * Imm) != result[i]"}), -}; - -(string templateFileName, Dictionary templateData)[] RdmInputs = new[] -{ - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndAddSaturateHigh_Vector64_Int16", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndAddSaturateHigh_Vector64_Int32", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndAddSaturateHigh_Vector128_Int16", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndAddSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndAddSaturateHigh_Vector128_Int32", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndAddSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh_Vector64_Int16", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh_Vector64_Int32", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh_Vector128_Int16", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh_Vector128_Int32", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndSubtractSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector128_Int16_Vector64_Int16_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector128_Int16_Vector128_Int16_7", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector128_Int32_Vector64_Int32_1", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), - ("VecImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh_Vector128_Int32_Vector128_Int32_3", ["Isa"] = "Rdm", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateIterResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[i], secondOp[i], thirdOp[Imm]) != result[i]"}), -}; - -(string templateFileName, Dictionary templateData)[] Rdm_Arm64Inputs = new[] -{ - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndAddSaturateHighScalar_Vector64_Int16", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndAddSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndAddSaturateHighScalar_Vector64_Int32", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndAddSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndSubtractSaturateHighScalar_Vector64_Int16", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndSubtractSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingAndSubtractSaturateHighScalar_Vector64_Int32", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingAndSubtractSaturateHighScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[0], secondOp[0], thirdOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndAddSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndAddSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh_Vector64_Int16_Vector64_Int16_3", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh_Vector64_Int16_Vector128_Int16_7", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh_Vector64_Int32_Vector64_Int32_1", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleImmTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh_Vector64_Int32_Vector128_Int32_3", ["Isa"] = "Rdm.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyRoundedDoublingScalarBySelectedScalarAndSubtractSaturateHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.MultiplyRoundedDoublingAndSubtractSaturateHigh(firstOp[0], secondOp[0], thirdOp[Imm]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), -}; - -(string templateFileName, Dictionary templateData)[] Sha1Inputs = new[] -{ - ("SecureHashUnOpTest.template", new Dictionary { ["TestName"] = "FixedRotate_Vector64_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "FixedRotate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "0x00112233", ["ExpectedResult"] = "{0xC004488C, 0x0, 0x0, 0x0}"}), - ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "HashUpdateChoose_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdateChoose", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x27A38C6D, 0xEFEFCA67, 0xDB4E8169, 0x73C91E71}"}), - ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "HashUpdateMajority_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdateMajority", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0xEC691B1D, 0xF21410C7, 0x9B52C9F6, 0x73C91E71}"}), - ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "HashUpdateParity_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdateParity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0xDAB2AF34, 0xFF990D18, 0xCB4F938C, 0x73C91E71}"}), - ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "ScheduleUpdate0_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate0", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x8899AABB, 0x8899AABB, 0xCCDDEEFF, 0xCCDDEEFF}"}), - ("SecureHashBinOpTest.template", new Dictionary { ["TestName"] = "ScheduleUpdate1_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate1", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["ExpectedResult"] = "{0x88888888, 0x88888888, 0x88888888, 0x11335577}"}), -}; - -(string templateFileName, Dictionary templateData)[] Sha256Inputs = new[] -{ - ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "HashUpdate1_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdate1", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x3D22118E, 0x987CA5FB, 0x54F4E477, 0xDFB50278}"}), - ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "HashUpdate2_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdate2", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0xFFD38634, 0x2A33F83F, 0x55A1BE45, 0x5002B4C4}"}), - ("SecureHashBinOpTest.template", new Dictionary { ["TestName"] = "ScheduleUpdate0_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate0", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["ExpectedResult"] = "{0x2E9FE839, 0x2E9FE839, 0x2E9FE839, 0xBFB0F94A}"}), - ("SecureHashTernOpTest.template", new Dictionary { ["TestName"] = "ScheduleUpdate1_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate1", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x248F1BDF, 0x248F1BDF, 0xB303DDBA, 0xF74821FE}"}), -}; - -(string templateFileName, Dictionary templateData)[] SveInputs = new[] -{ - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Abs(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Abs(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)-TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "(sbyte)Helpers.Abs(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)-TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "(short)Helpers.Abs(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "(int)Helpers.Abs(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(long)Helpers.Abs(firstOp[i]) != (long)result[i]", ["GetIterResult"] = "(long)Helpers.Abs(leftOp[i])"}), - - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareGreaterThan_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareGreaterThan_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareGreaterThanOrEqual_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareGreaterThanOrEqual_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareLessThan_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareLessThan_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareLessThanOrEqual_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary {["TestName"] = "Sve_AbsoluteCompareLessThanOrEqual_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveAbsoluteCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveAbsoluteCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - - ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(sbyte)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), - ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(short)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), - ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(int)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), - ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(long)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), - ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(byte)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), - ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(ushort)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), - ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(uint)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), - ("SveVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_AbsoluteDifference_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt64)Helpers.AbsoluteDifference(left[i], right[i])", ["ConvertFunc"] = ""}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), - - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossRecursivePairwise(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0.0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossRecursivePairwise(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0.0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_long_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWideningLong(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_long_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWideningLong(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_long_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWideningULong(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWideningULong(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - - ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), - ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_float_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), - ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_double_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), - ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), - - ("SveVecBinOpTestScalarRet.template", new Dictionary { ["TestName"] = "Sve_AddSequentialAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSequentialAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateScalarResult"] = "result[0] != Helpers.AddSequentialAcross(left, right)"}), - ("SveVecBinOpTestScalarRet.template", new Dictionary { ["TestName"] = "Sve_AddSequentialAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSequentialAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateScalarResult"] = "result[0] != Helpers.AddSequentialAcross(left, right)"}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), - - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_BitwiseClear_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.BitwiseClear(left[i], right[i])"}), - - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_BooleanNot_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "BooleanNot", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BooleanNot(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BooleanNot(leftOp[i])"}), - - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_Compact_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compact", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.Compact(left, right))", ["GetVectorResult"] = "Helpers.Compact(left, right)",}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_Compact_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compact", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.Compact(left, right))", ["GetVectorResult"] = "Helpers.Compact(left, right)",}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_Compact_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compact", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.Compact(left, right))", ["GetVectorResult"] = "Helpers.Compact(left, right)",}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_Compact_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compact", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.Compact(left, right))", ["GetVectorResult"] = "Helpers.Compact(left, right)",}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_Compact_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compact", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.Compact(left, right))", ["GetVectorResult"] = "Helpers.Compact(left, right)",}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_Compact_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compact", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.Compact(left, right))", ["GetVectorResult"] = "Helpers.Compact(left, right)",}), - - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareEqual_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SveCompareEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareGreaterThan_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary {["TestName"] = "Sve_CompareGreaterThanOrEqual_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareGreaterThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareLessThan_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SveCompareLessThan(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThan(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template",new Dictionary { ["TestName"] = "Sve_CompareLessThanOrEqual_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SveCompareLessThanOrEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareLessThanOrEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareNotEqualTo_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareNotEqualTo", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SveCompareNotEqual(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareNotEqual(leftOp[i], rightOp[i])", ["ConvertFunc"] = ""}), - - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareUnordered_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareUnordered", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.SveCompareUnordered(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareUnordered(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecBinRetMaskOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_CompareUnordered_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CompareUnordered", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.SveCompareUnordered(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SveCompareUnordered(leftOp[i], rightOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute16BitAddresses_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute16BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(left[i] + ((uint)right[i] * 2)) != result[i]", ["GetIterResult"] = "(left[i] + ((uint)right[i] * 2))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute16BitAddresses_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute16BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(left[i] + (right[i] * 2)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 2))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute16BitAddresses_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute16BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(left[i] + ((ulong)right[i] * 2)) != result[i]", ["GetIterResult"] = "(left[i] + ((ulong)right[i] * 2))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute16BitAddresses_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute16BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(left[i] + (right[i] * 2)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 2))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute32BitAddresses_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute32BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(left[i] + ((uint)right[i] * 4)) != result[i]", ["GetIterResult"] = "(left[i] + ((uint)right[i] * 4))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute32BitAddresses_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute32BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(left[i] + (right[i] * 4)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 4))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute32BitAddresses_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute32BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(left[i] + ((ulong)right[i] * 4)) != result[i]", ["GetIterResult"] = "(left[i] + ((ulong)right[i] * 4))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute32BitAddresses_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute32BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(left[i] + (right[i] * 4)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 4))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute64BitAddresses_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute64BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(left[i] + ((uint)right[i] * 8)) != result[i]", ["GetIterResult"] = "(left[i] + ((uint)right[i] * 8))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute64BitAddresses_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute64BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(left[i] + (right[i] * 8)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 8))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute64BitAddresses_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute64BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(left[i] + ((ulong)right[i] * 8)) != result[i]", ["GetIterResult"] = "(left[i] + ((ulong)right[i] * 8))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute64BitAddresses_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute64BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(left[i] + (right[i] * 8)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 8))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute8BitAddresses_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute8BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(left[i] + ((uint)right[i] * 1)) != result[i]", ["GetIterResult"] = "(left[i] + ((uint)right[i] * 1))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute8BitAddresses_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute8BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(left[i] + (right[i] * 1)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 1))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute8BitAddresses_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute8BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(left[i] + ((ulong)right[i] * 1)) != result[i]", ["GetIterResult"] = "(left[i] + ((ulong)right[i] * 1))"}), - ("SveMaskVecBinOpConvertTest.template", new Dictionary { ["TestName"] = "Sve_Compute8BitAddresses_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Compute8BitAddresses", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(left[i] + (right[i] * 1)) != result[i]", ["GetIterResult"] = "(left[i] + (right[i] * 1))"}), - - ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), - ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), - ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), - ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["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()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), - ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["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()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), - ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), - ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["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()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), - ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), - ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["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()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), - ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["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()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), - - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToDouble_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToDouble(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToDouble(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt32_int_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToInt32(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToInt32(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt32_int_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToInt32(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToInt32(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt64_long_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToInt64(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToInt64(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToInt64_long_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToInt64(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToInt64(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToSingle_float_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToSingle(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToSingle(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt32_uint_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToUInt32(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToUInt32(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt32_uint_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToUInt32(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToUInt32(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt64_ulong_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToUInt64(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToUInt64(left)"}), - ("SveSimpleVecOpDiffRetTypeTestVec.template", new Dictionary { ["TestName"] = "Sve_ConvertToUInt64_ulong_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConvertToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ConvertToUInt64(firstOp))", ["GetVectorResult"] = "Helpers.ConvertToUInt64(left)"}), - - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count16BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count16BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Int16)));",}), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count32BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count32BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Int32)));",}), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count64BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count64BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Int64)));",}), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count8BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count8BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Byte)));",}), - - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterMask_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakAfterMask(left, right)"}), - - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["NextValueOp3"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["NextValueOp3"] = "Helpers.getMaskSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "Helpers.getMaskInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "Helpers.getMaskInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakAfterPropagateMask_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakAfterPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "Helpers.getMaskInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakAfterPropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakAfterPropagateMask(first, second, third)"}), - - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforeMask_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforeMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforeMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakBeforeMask(left, right)"}), - - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["NextValueOp3"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["NextValueOp3"] = "Helpers.getMaskSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "Helpers.getMaskInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "Helpers.getMaskInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakBeforePropagateMask_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakBeforePropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "Helpers.getMaskInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakBeforePropagateMask(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.CreateBreakBeforePropagateMask(first, second, third)"}), - - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateBreakPropagateMask_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateBreakPropagateMask", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateBreakPropagateMask(left, right))", ["GetVectorResult"] = "Helpers.CreateBreakPropagateMask(left, right)"}), - - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), - ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Divide_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Divide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Divide(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Divide(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Divide_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Divide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Divide(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Divide(left[i], right[i])"}), - - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProduct_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i)", ["ConvertFunc"] = ""}), - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProduct_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i)", ["ConvertFunc"] = ""}), - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProduct_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i)", ["ConvertFunc"] = ""}), - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProduct_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProduct", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * i)", ["ConvertFunc"] = ""}), - - ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProductBySelectedScalar_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProductBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm)", ["ConvertFunc"] = ""}), - ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProductBySelectedScalar_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProductBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm)", ["ConvertFunc"] = ""}), - ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProductBySelectedScalar_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProductBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm)", ["ConvertFunc"] = ""}), - ("SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve_DotProductBySelectedScalar_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DotProductBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm) != result[i]", ["GetIterResult"] = "Helpers.DotProduct(first[i], second, 4 * i, third, 4 * Imm)", ["ConvertFunc"] = ""}), - - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplyAdd_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplyAdd_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - - ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - - ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddNegated_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddNegated_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplySubtract_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplySubtract_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - - ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - - ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractNegated_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractNegated_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - - ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskByte_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskByte", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["ValidateIterResult"] = "result[i] != 0",}), - ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskDouble_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["ValidateIterResult"] = "result[i] != 0",}), - ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskInt16_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["ValidateIterResult"] = "result[i] != 0",}), - ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskInt32_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["ValidateIterResult"] = "result[i] != 0",}), - ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskInt64_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["ValidateIterResult"] = "result[i] != 0",}), - ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskSByte_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskSByte", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["ValidateIterResult"] = "result[i] != 0",}), - ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskSingle_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["ValidateIterResult"] = "result[i] != 0",}), - ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskUInt16_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["ValidateIterResult"] = "result[i] != 0",}), - ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskUInt32_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["ValidateIterResult"] = "result[i] != 0",}), - ("SveSimpleNoOpTest.template", new Dictionary { ["TestName"] = "Sve_CreateFalseMaskUInt64_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateFalseMaskUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["ValidateIterResult"] = "result[i] != 0",}), - ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskByte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskByte", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1Type"] = "SveMaskPattern"}), - ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskDouble", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskDouble", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1Type"] = "SveMaskPattern"}), - ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskInt16", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1Type"] = "SveMaskPattern"}), - ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1Type"] = "SveMaskPattern"}), - ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1Type"] = "SveMaskPattern"}), - ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskSByte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskSByte", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1Type"] = "SveMaskPattern"}), - ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskSingle", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskSingle", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1Type"] = "SveMaskPattern"}), - ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskUInt16", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1Type"] = "SveMaskPattern"}), - ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskUInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1Type"] = "SveMaskPattern"}), - ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskUInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1Type"] = "SveMaskPattern"}), - - // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_ushort_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_short_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)16"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_ushort_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)58"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_short_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)123"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_ushort_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_short_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)54"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_ushort_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)32"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_short_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)17"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_ushort_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)56"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_short_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)123"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_ushort_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)99"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_short_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)254"}), - // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)230"}), - // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)23"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)22"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)99"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)16"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)101"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)165"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)82"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_uint_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)35"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_int_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)134"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)35"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)153"}), - // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_long_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_ulong_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)242"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_long_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)232"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)223"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_long_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)62"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)43"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)166"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)234"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)46"}), - // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_byte_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_sbyte_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_byte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_sbyte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_byte_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)51"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_sbyte_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)82"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_byte_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)236"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_sbyte_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)45"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_byte_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)34"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_sbyte_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)43"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_byte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)234"}), - ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_sbyte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)86"}), - - ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["InvalidImm"] = "16", ["Imm"] = "TestLibrary.Generator.GetByte() % 16", ["ValidateIterResult"] = "result[i] != (imm < Op1ElementCount ? firstOp[imm] : 0)", ["GetIterResult"] = "(Single)(imm < Op1ElementCount ? firstOp[imm] : 0)"}), - ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["InvalidImm"] = "8", ["Imm"] = "TestLibrary.Generator.GetByte() % 8", ["ValidateIterResult"] = "result[i] != (imm < Op1ElementCount ? firstOp[imm] : 0)", ["GetIterResult"] = "(Double)(imm < Op1ElementCount ? firstOp[imm] : 0)"}), - ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["InvalidImm"] = "64", ["Imm"] = "TestLibrary.Generator.GetByte() % 64", ["ValidateIterResult"] = "result[i] != (imm < Op1ElementCount ? firstOp[imm] : 0)", ["GetIterResult"] = "(SByte)(imm < Op1ElementCount ? firstOp[imm] : 0)"}), - ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["InvalidImm"] = "32", ["Imm"] = "TestLibrary.Generator.GetByte() % 32", ["ValidateIterResult"] = "result[i] != (imm < Op1ElementCount ? firstOp[imm] : 0)", ["GetIterResult"] = "(Int16)(imm < Op1ElementCount ? firstOp[imm] : 0)"}), - ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["InvalidImm"] = "16", ["Imm"] = "TestLibrary.Generator.GetByte() % 16", ["ValidateIterResult"] = "result[i] != (imm < Op1ElementCount ? firstOp[imm] : 0)", ["GetIterResult"] = "(Int32)(imm < Op1ElementCount ? firstOp[imm] : 0)"}), - ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["InvalidImm"] = "8", ["Imm"] = "TestLibrary.Generator.GetByte() % 8", ["ValidateIterResult"] = "result[i] != (imm < Op1ElementCount ? firstOp[imm] : 0)", ["GetIterResult"] = "(Int64)(imm < Op1ElementCount ? firstOp[imm] : 0)"}), - ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["InvalidImm"] = "64", ["Imm"] = "TestLibrary.Generator.GetByte() % 64", ["ValidateIterResult"] = "result[i] != (imm < Op1ElementCount ? firstOp[imm] : 0)", ["GetIterResult"] = "(Byte)(imm < Op1ElementCount ? firstOp[imm] : 0)"}), - ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["InvalidImm"] = "32", ["Imm"] = "TestLibrary.Generator.GetByte() % 32", ["ValidateIterResult"] = "result[i] != (imm < Op1ElementCount ? firstOp[imm] : 0)", ["GetIterResult"] = "(UInt16)(imm < Op1ElementCount ? firstOp[imm] : 0)"}), - ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["InvalidImm"] = "16", ["Imm"] = "TestLibrary.Generator.GetByte() % 16", ["ValidateIterResult"] = "result[i] != (imm < Op1ElementCount ? firstOp[imm] : 0)", ["GetIterResult"] = "(UInt32)(imm < Op1ElementCount ? firstOp[imm] : 0)"}), - ("SveVecImmUnOpTest.template", new Dictionary { ["TestName"] = "Sve_DuplicateSelectedScalarToVector_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "DuplicateSelectedScalarToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["InvalidImm"] = "8", ["Imm"] = "TestLibrary.Generator.GetByte() % 8", ["ValidateIterResult"] = "result[i] != (imm < Op1ElementCount ? firstOp[imm] : 0)", ["GetIterResult"] = "(UInt64)(imm < Op1ElementCount ? firstOp[imm] : 0)"}), - - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForFirstActiveElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForFirstActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForFirstActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForFirstActiveElement(left, right)"}), - - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForNextActiveElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForNextActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForNextActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForNextActiveElement(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForNextActiveElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForNextActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForNextActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForNextActiveElement(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForNextActiveElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForNextActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForNextActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForNextActiveElement(left, right)"}), - ("SveVecBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_CreateMaskForNextActiveElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateMaskForNextActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.CreateMaskForNextActiveElement(left, right))", ["GetVectorResult"] = "Helpers.CreateMaskForNextActiveElement(left, right)"}), - - ("SveSimpleVecOpDiffRetTypeTest.template", new Dictionary {["TestName"] = "Sve_FloatingPointExponentialAccelerator_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FloatingPointExponentialAccelerator", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPExponentialAccelerator(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FPExponentialAccelerator(leftOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveSimpleVecOpDiffRetTypeTest.template", new Dictionary {["TestName"] = "Sve_FloatingPointExponentialAccelerator_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FloatingPointExponentialAccelerator", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPExponentialAccelerator(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FPExponentialAccelerator(leftOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_byte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_short_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_int_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_long_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_sbyte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_ushort_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_uint_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_ulong_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_float_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractAfterLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractAfterLastActiveElement_double_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractAfterLastActiveElementScalar", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateScalarResult"] = "Helpers.ExtractAfterLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_byte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_short_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_int_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_long_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_sbyte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_ushort_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_uint_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_ulong_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_float_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i] != result[i]", ["GetIterResult"] = "Helpers.ExtractLastActiveElement(left, right)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ExtractLastActiveElement_double_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractLastActiveElementScalar", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateScalarResult"] = "Helpers.ExtractLastActiveElementScalar(left, right) != result",}), - ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_Byte_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_Double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_Int16_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_Int32_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_Int64_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_SByte_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_Single_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_UInt16_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_UInt32_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("SveExtractVectorTest.template", new Dictionary { ["TestName"] = "Sve_ExtractVector_UInt64_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ExtractVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_byte", ["VectorBaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_short", ["VectorBaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_int", ["VectorBaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_long", ["VectorBaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_sbyte", ["VectorBaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_ushort", ["VectorBaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_uint", ["VectorBaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()"}), - ("SveFfrTest.template", new Dictionary { ["TestName"] = "Sve_Ffr_ulong", ["VectorBaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()"}), - - // ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetSingle()"}), - // ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetInt32()"}), - // ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetDouble()"}), - ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVector_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - - // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()" ["NextValueBase"] = "TestLibrary.Generator.GetInt32()"}), - // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()" ["NextValueBase"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()" }), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - - // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()" ["NextValueBase"] = "TestLibrary.Generator.GetInt32()}), - // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()" ["NextValueBase"] = "TestLibrary.Generator.GetUInt32()}), - ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorInt32SignExtend_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorInt32SignExtend_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32SignExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32SignExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32SignExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32SignExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - - // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetInt32()"}), - // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorSByteSignExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - - // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetInt32()}), - // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - - ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()",}), - // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), - // ("SveGatherVectorVectorBases.template",new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt32()}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorIndices.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtend_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorFirstFaulting_Bases_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Double", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetDouble()"}), - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorFirstFaulting_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorFirstFaulting_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Single", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Single", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Double", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int64", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Double", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int64", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting_offsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32SignExtendFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32SignExtendFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32SignExtendFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32SignExtendFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting_offsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting_offsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting_offsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting_offsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt32WithByteOffsetsSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorSByteSignExtendFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "SByte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "(UInt16)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "(UInt16)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "(UInt16)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "(UInt16)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "(UInt16)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "(UInt16)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "(UInt16)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting_offsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "(UInt16)"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "(UInt32)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "(UInt32)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "(UInt32)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "(UInt32)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "(UInt32)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "(UInt32)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "(UInt32)"}), - ("SveGatherVectorByteOffsetFirstFaulting.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting_offsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32WithByteOffsetsZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "(UInt32)"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingIndices.template", new Dictionary { ["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorByteZeroExtendFirstFaulting_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorInt16SignExtendFirstFaulting_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt16ZeroExtendFirstFaulting_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetInt64()"}), - ("SveGatherVectorFirstFaultingVectorBases.template", new Dictionary {["TestName"] = "Sve_GatherVectorUInt32ZeroExtendFirstFaulting_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["ExtendedElementType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueBase"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsetFirstFaulting.template",new Dictionary { ["TestName"] = "Sve_GatherVectorWithByteOffsetFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsetFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = ""}), - - ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = ""}), - ("SveGatherVectorByteOffsets.template",new Dictionary {["TestName"] = "Sve_GatherVectorWithByteOffsets_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherVectorWithByteOffsets", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["ExtendedElementType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = ""}), - - ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), - ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "Helpers.getMaskSByte()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), - ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), - ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), - ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), - ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "Helpers.getMaskSingle()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), - ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "Helpers.getMaskDouble()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), - ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), - ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), - ("SveVecReduceToScalarBinOpTest.template", new Dictionary { ["TestName"] = "Sve_GetActiveElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GetActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "if (Helpers.MaskBothSet(left, right) != result) succeeded = false;",}), - - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingSignCount_byte_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingSignBits(leftOp[i])"}), - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingSignCount_ushort_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingSignBits(leftOp[i])"}), - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingSignCount_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingSignBits(leftOp[i])"}), - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingSignCount_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "((ulong)Helpers.CountLeadingSignBits(firstOp[i])) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingSignBits(leftOp[i])"}), - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_byte_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_ushort_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "((ulong)Helpers.CountLeadingZeroBits(firstOp[i])) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_LeadingZeroCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.CountLeadingZeroBits(leftOp[i])"}), - - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_float", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_double", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_sbyte", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_short", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_int", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_long", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_byte", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_ushort", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_uint", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector_ulong", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_float", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["GetFfrType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Cast"] = "(float*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_double", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["GetFfrType"] = "UInt64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["Cast"] = "(double*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_sbyte", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["GetFfrType"] = "SByte", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Cast"] = "(sbyte*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_short", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["GetFfrType"] = "Int16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Cast"] = "(short*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_int", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["GetFfrType"] = "Int32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Cast"] = "(int*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_long", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["GetFfrType"] = "Int64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Cast"] = "(long*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_byte", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["GetFfrType"] = "Byte", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Cast"] = "(byte*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_ushort", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["GetFfrType"] = "UInt16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Cast"] = "(ushort*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_uint", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["GetFfrType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Cast"] = "(uint*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonFaulting_ulong", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["GetFfrType"] = "UInt64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Cast"] = "(ulong*)", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendFirstFaulting_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendFirstFaulting_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendFirstFaulting_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendFirstFaulting_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["GetFfrType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["GetFfrType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["GetFfrType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendFirstFaulting_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendFirstFaulting_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), - - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt32SignExtendFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt32SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt32SignExtendFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt32SignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), - - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendFirstFaulting_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendFirstFaulting_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendFirstFaulting_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendFirstFaulting_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "SByte", ["GetFfrType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendFirstFaulting_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["GetFfrType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["GetFfrType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendFirstFaulting_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["GetFfrType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), - - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt32ZeroExtendFirstFaulting_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["GetFfrType"] = "Int64" , ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveLoadVectorFirstFaultingTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt32ZeroExtendFirstFaulting_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorUInt32ZeroExtendFirstFaulting", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["GetFfrType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), - - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_float", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_double", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_sbyte", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_short", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_int", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_long", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_byte", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_ushort", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_uint", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorNonTemporal_ulong", ["Isa"] = "Sve", ["Method"] = "LoadVectorNonTemporal", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_float", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_double", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_sbyte", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_short", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_int", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_long", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_byte", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_ushort", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_uint", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVector128AndReplicateToVector_ulong", ["Isa"] = "Sve", ["Method"] = "LoadVector128AndReplicateToVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveLoadNonFaultingUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorInt16NonFaultingSignExtendToInt32_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16NonFaultingSignExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["GetFfrType"] = "Int32", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]",}), - ("SveLoadNonFaultingUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorInt16NonFaultingSignExtendToInt64_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16NonFaultingSignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["GetFfrType"] = "Int64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]",}), - ("SveLoadNonFaultingUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorInt16NonFaultingSignExtendToUInt32_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16NonFaultingSignExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["GetFfrType"] = "UInt32", ["Cast"] = "", ["ValidateIterResult"] = "((uint)firstOp[i]) != result[i]",}), - ("SveLoadNonFaultingUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorInt16NonFaultingSignExtendToUInt64_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt16NonFaultingSignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["GetFfrType"] = "UInt64", ["Cast"] = "", ["ValidateIterResult"] = "((ulong)firstOp[i]) != result[i]",}), - ("SveLoadNonFaultingUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorInt32NonFaultingSignExtendToInt64_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt32NonFaultingSignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["GetFfrType"] = "Int64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]",}), - ("SveLoadNonFaultingUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorInt32NonFaultingSignExtendToUInt64_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorInt32NonFaultingSignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["GetFfrType"] = "UInt64", ["Cast"] = "", ["ValidateIterResult"] = "((ulong)firstOp[i]) != result[i]",}), - ("SveLoadNonFaultingUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorSByteNonFaultingSignExtendToInt16_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteNonFaultingSignExtendToInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["GetFfrType"] = "Int16", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]",}), - ("SveLoadNonFaultingUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorSByteNonFaultingSignExtendToInt32_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteNonFaultingSignExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["GetFfrType"] = "Int32", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]",}), - ("SveLoadNonFaultingUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorSByteNonFaultingSignExtendToInt64_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteNonFaultingSignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["GetFfrType"] = "Int64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]",}), - ("SveLoadNonFaultingUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorSByteNonFaultingSignExtendToUInt16_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteNonFaultingSignExtendToUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["GetFfrType"] = "UInt16", ["Cast"] = "", ["ValidateIterResult"] = "((ushort)firstOp[i]) != result[i]",}), - ("SveLoadNonFaultingUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorSByteNonFaultingSignExtendToUInt32_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteNonFaultingSignExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["GetFfrType"] = "UInt32", ["Cast"] = "", ["ValidateIterResult"] = "((uint)firstOp[i]) != result[i]",}), - ("SveLoadNonFaultingUnOpTest.template",new Dictionary {["TestName"] = "Sve_LoadVectorSByteNonFaultingSignExtendToUInt64_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "LoadVectorSByteNonFaultingSignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["GetFfrType"] = "UInt64", ["Cast"] = "", ["ValidateIterResult"] = "((ulong)firstOp[i]) != result[i]",}), - - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt16SignExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(ulong)firstOp[i] != result[i]"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt32SignExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt32SignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorInt32SignExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt32SignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(ulong)firstOp[i] != result[i]"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendToInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendToUInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorSByteSignExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(ulong)firstOp[i] != result[i]"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendToInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendToUInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16ZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt32ZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt32ZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveLoadVectorMaskedTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt32ZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt32ZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()"}), - - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteNonFaultingZeroExtendToInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteNonFaultingZeroExtendToInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["GetFfrType"] = "Int16", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteNonFaultingZeroExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteNonFaultingZeroExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["GetFfrType"] = "Int32", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteNonFaultingZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteNonFaultingZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["GetFfrType"] = "Int64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteNonFaultingZeroExtendToUInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteNonFaultingZeroExtendToUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["GetFfrType"] = "UInt16", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteNonFaultingZeroExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteNonFaultingZeroExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["GetFfrType"] = "UInt32", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorByteNonFaultingZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteNonFaultingZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["GetFfrType"] = "UInt64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16NonFaultingZeroExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16NonFaultingZeroExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["GetFfrType"] = "Int32", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16NonFaultingZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16NonFaultingZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["GetFfrType"] = "Int64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16NonFaultingZeroExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16NonFaultingZeroExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["GetFfrType"] = "UInt32", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt16NonFaultingZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16NonFaultingZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["GetFfrType"] = "UInt64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt32NonFaultingZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt32NonFaultingZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["GetFfrType"] = "Int64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadNonFaultingUnOpTest.template", new Dictionary { ["TestName"] = "Sve_LoadVectorUInt32NonFaultingZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt32NonFaultingZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["GetFfrType"] = "UInt64", ["Cast"] = "", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - - ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), - ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), - ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), - ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), - ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), - ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), - ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), - ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), - ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), - ("SveLoad2xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load2xVectorAndUnzip_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load2xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 2] || result2[i] != input[i * 2 + 1]"}), - ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), - ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), - ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), - ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), - ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), - ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), - ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), - ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), - ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), - ("SveLoad3xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load3xVectorAndUnzip_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load3xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 3] || result2[i] != input[i * 3 + 1] || result3[i] != input[i * 3 + 2]"}), - ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), - ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), - ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), - ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), - ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), - ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), - ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), - ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), - ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), - ("SveLoad4xVectorAndUnzipTest.template", new Dictionary { ["TestName"] = "Sve_Load4xVectorAndUnzip_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Load4xVectorAndUnzip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result1[i] != input[i * 4] || result2[i] != input[i * 4 + 1] || result3[i] != input[i * 4 + 2] || result4[i] != input[i * 4 + 3]"}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), - - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxNumber_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxNumber_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), - - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxNumberAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxNumberAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxNumberAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxNumberAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), - - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MinNumber_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MinNumber_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), - - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinNumberAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinNumberAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinNumberAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinNumberAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), - - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["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()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - - ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), - ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), - ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), - ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), - ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), - ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), - ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), - ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), - - ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_0_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "0", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), - ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_0_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "1", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), - ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_0_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "2", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), - ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_0_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "0", ["Imm2"] = "3", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), - ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_1_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "0", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), - ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_1_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "1", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), - ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_1_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "2", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), - ("SveVecImm2TernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplexBySelectedScalar_float_1_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplexBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm1"] = "1", ["Imm2"] = "3", ["InvalidImm1"] = "2", ["InvalidImm2"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplexBySelectedScalar(firstOp, secondOp, thirdOp, Imm1, Imm2))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplexBySelectedScalar(first, second, third, Imm1, Imm2)"}), - - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyExtended_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.MultiplyExtended(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyExtended(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyExtended_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.MultiplyExtended(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyExtended(left[i], right[i])"}), - - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["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()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["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()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["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()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["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()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplySubtract_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplySubtract", ["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()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Negate(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Negate(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)-TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]", ["GetIterResult"] = "(sbyte)Helpers.Negate(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)-TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]", ["GetIterResult"] = "(short)Helpers.Negate(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]", ["GetIterResult"] = "(int)Helpers.Negate(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(long)Helpers.Negate(firstOp[i]) != (long)result[i]", ["GetIterResult"] = "(long)Helpers.Negate(leftOp[i])"}), - - ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), - ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), - ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), - ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), - ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), - ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), - ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), - ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), - ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), - ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), - - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), - - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_uint_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(uint)Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "(uint)Helpers.BitCount(leftOp[i])"}), - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_ulong_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(ulong)Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "(ulong)Helpers.BitCount(leftOp[i])"}), - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_byte_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(byte)Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "(byte)Helpers.BitCount(leftOp[i])"}), - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_ushort_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(ushort)Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "(ushort)Helpers.BitCount(leftOp[i])"}), - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(uint)Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "(uint)Helpers.BitCount(leftOp[i])"}), - ("SveMasklessSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(ulong)Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "(ulong)Helpers.BitCount(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BitCount(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BitCount(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BitCount(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_PopCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PopCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.BitCount(leftOp[i])"}), - ("SvePrefetchTest.template", new Dictionary { ["TestName"] = "Sve_Prefetch16Bit", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Prefetch16Bit", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)18"}), - ("SvePrefetchTest.template", new Dictionary { ["TestName"] = "Sve_Prefetch32Bit", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Prefetch32Bit", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)20"}), - ("SvePrefetchTest.template", new Dictionary { ["TestName"] = "Sve_Prefetch64Bit", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Prefetch64Bit", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)87"}), - ("SvePrefetchTest.template", new Dictionary { ["TestName"] = "Sve_Prefetch8Bit", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Prefetch8Bit", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), - - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.LargestPowerOf2", ["InvalidImm"] = "(Byte)0", ["InvalidImm2"] = "(SveMaskPattern)35", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)12", ["Imm2"] = "SveMaskPattern.VectorCount1", ["InvalidImm"] = "(Byte)19", ["InvalidImm2"] = "(SveMaskPattern)37", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)5", ["Imm2"] = "SveMaskPattern.VectorCount2", ["InvalidImm"] = "(Byte)25", ["InvalidImm2"] = "(SveMaskPattern)46", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)7", ["Imm2"] = "SveMaskPattern.VectorCount3", ["InvalidImm"] = "(Byte)255", ["InvalidImm2"] = "(SveMaskPattern)50", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), - ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_vector_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "(Byte)10", ["Imm2"] = "SveMaskPattern.VectorCount4", ["InvalidImm"] = "(Byte)65", ["InvalidImm2"] = "(SveMaskPattern)90", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate((short)firstOp[i], (short)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2)))",}), - ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_vector_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "(Byte)1", ["Imm2"] = "SveMaskPattern.VectorCount5", ["InvalidImm"] = "(Byte)72", ["InvalidImm2"] = "(SveMaskPattern)35", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate((ushort)firstOp[i], (ushort)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2)))",}), - - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy32BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy32BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)1", ["Imm2"] = "SveMaskPattern.VectorCount6", ["InvalidImm"] = "(Byte)17", ["InvalidImm2"] = "(SveMaskPattern)32", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy32BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy32BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.VectorCount7", ["InvalidImm"] = "(Byte)19", ["InvalidImm2"] = "(SveMaskPattern)33", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy32BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy32BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)3", ["Imm2"] = "SveMaskPattern.VectorCount8", ["InvalidImm"] = "(Byte)25", ["InvalidImm2"] = "(SveMaskPattern)34", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy32BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy32BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)4", ["Imm2"] = "SveMaskPattern.VectorCount32", ["InvalidImm"] = "(Byte)26", ["InvalidImm2"] = "(SveMaskPattern)35", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), - ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy32BitElementCount_vector_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy32BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)5", ["Imm2"] = "SveMaskPattern.VectorCount64", ["InvalidImm"] = "(Byte)27", ["InvalidImm2"] = "(SveMaskPattern)36", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate((int)firstOp[i], (int)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2)))",}), - ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy32BitElementCount_vector_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy32BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)6", ["Imm2"] = "SveMaskPattern.VectorCount128", ["InvalidImm"] = "(Byte)18", ["InvalidImm2"] = "(SveMaskPattern)37", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate((uint)firstOp[i], (uint)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2)))",}), - - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy64BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy64BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)7", ["Imm2"] = "SveMaskPattern.VectorCount256", ["InvalidImm"] = "(Byte)34", ["InvalidImm2"] = "(SveMaskPattern)135", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy64BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy64BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)8", ["Imm2"] = "SveMaskPattern.LargestMultipleOf4", ["InvalidImm"] = "(Byte)35", ["InvalidImm2"] = "(SveMaskPattern)125", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy64BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy64BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)9", ["Imm2"] = "SveMaskPattern.LargestMultipleOf3", ["InvalidImm"] = "(Byte)36", ["InvalidImm2"] = "(SveMaskPattern)115", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy64BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy64BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)10", ["Imm2"] = "SveMaskPattern.All", ["InvalidImm"] = "(Byte)37", ["InvalidImm2"] = "(SveMaskPattern)145", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), - ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy64BitElementCount_vector_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy64BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)11", ["Imm2"] = "SveMaskPattern.VectorCount7", ["InvalidImm"] = "(Byte)38", ["InvalidImm2"] = "(SveMaskPattern)155", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate((long)firstOp[i], (long)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2)))",}), - ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy64BitElementCount_vector_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy64BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)12", ["Imm2"] = "SveMaskPattern.LargestPowerOf2", ["InvalidImm"] = "(Byte)39", ["InvalidImm2"] = "(SveMaskPattern)165", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate((ulong)firstOp[i], (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2)))",}), - - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy8BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy8BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)13", ["Imm2"] = "SveMaskPattern.VectorCount4", ["InvalidImm"] = "(Byte)89", ["InvalidImm2"] = "(SveMaskPattern)206", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy8BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy8BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)14", ["Imm2"] = "SveMaskPattern.LargestPowerOf2", ["InvalidImm"] = "(Byte)0", ["InvalidImm2"] = "(SveMaskPattern)207", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy8BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy8BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)15", ["Imm2"] = "SveMaskPattern.VectorCount6", ["InvalidImm"] = "(Byte)91", ["InvalidImm2"] = "(SveMaskPattern)208", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy8BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy8BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)16", ["Imm2"] = "SveMaskPattern.All", ["InvalidImm"] = "(Byte)92", ["InvalidImm2"] = "(SveMaskPattern)209", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), - - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_int_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_int_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_long_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_long_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_long_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_uint_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_uint_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_ulong_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_ulong_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.SubtractSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_vector_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate(left[i], (short)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), - ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_vector_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate(left[i], (int)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), - ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_vector_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate(left[i], (long)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), - ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_vector_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate(left[i], (ushort)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), - ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_vector_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate(left[i], (uint)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), - ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementByActiveElementCount_vector_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SubtractSaturate(left[i], (ulong)(Helpers.NumberOfActiveElementsInMask(right)))", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], (ulong)(Helpers.NumberOfActiveElementsInMask(right)))"}), - - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy16BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy16BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)15", ["Imm2"] = "SveMaskPattern.VectorCount4", ["InvalidImm"] = "(Byte)98", ["InvalidImm2"] = "(SveMaskPattern)241", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy16BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy16BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)14", ["Imm2"] = "SveMaskPattern.All", ["InvalidImm"] = "(Byte)99", ["InvalidImm2"] = "(SveMaskPattern)242", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy16BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy16BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)13", ["Imm2"] = "SveMaskPattern.VectorCount256", ["InvalidImm"] = "(Byte)101", ["InvalidImm2"] = "(SveMaskPattern)243", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy16BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy16BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)12", ["Imm2"] = "SveMaskPattern.VectorCount32", ["InvalidImm"] = "(Byte)118", ["InvalidImm2"] = "(SveMaskPattern)50", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), - ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy16BitElementCount_vector_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy16BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "(Byte)11", ["Imm2"] = "SveMaskPattern.VectorCount4", ["InvalidImm"] = "(Byte)118", ["InvalidImm2"] = "(SveMaskPattern)60", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate((short)firstOp[i], (short)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2)))",}), - ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy16BitElementCount_vector_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy16BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "(Byte)10", ["Imm2"] = "SveMaskPattern.VectorCount64", ["InvalidImm"] = "(Byte)123", ["InvalidImm2"] = "(SveMaskPattern)70", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate((ushort)firstOp[i], (ushort)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2)))",}), - - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy32BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy32BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)9", ["Imm2"] = "SveMaskPattern.VectorCount5", ["InvalidImm"] = "(Byte)201", ["InvalidImm2"] = "(SveMaskPattern)80", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy32BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy32BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)8", ["Imm2"] = "SveMaskPattern.All", ["InvalidImm"] = "(Byte)202", ["InvalidImm2"] = "(SveMaskPattern)128", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy32BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy32BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)7", ["Imm2"] = "SveMaskPattern.LargestPowerOf2", ["InvalidImm"] = "(Byte)207", ["InvalidImm2"] = "(SveMaskPattern)255", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy32BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy32BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)6", ["Imm2"] = "SveMaskPattern.All", ["InvalidImm"] = "(Byte)220", ["InvalidImm2"] = "(SveMaskPattern)99", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2))));",}), - ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy32BitElementCount_vector_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy32BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)5", ["Imm2"] = "SveMaskPattern.LargestMultipleOf4", ["InvalidImm"] = "(Byte)221", ["InvalidImm2"] = "(SveMaskPattern)76", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate((int)firstOp[i], (int)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2)))",}), - ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy32BitElementCount_vector_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy32BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)4", ["Imm2"] = "SveMaskPattern.LargestMultipleOf3", ["InvalidImm"] = "(Byte)240", ["InvalidImm2"] = "(SveMaskPattern)32", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate((uint)firstOp[i], (uint)(imm1 * Helpers.NumberOfElementsInVectorInt32(imm2)))",}), - - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy64BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy64BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)3", ["Imm2"] = "SveMaskPattern.VectorCount64", ["InvalidImm"] = "(Byte)241", ["InvalidImm2"] = "(SveMaskPattern)105", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy64BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy64BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.VectorCount4", ["InvalidImm"] = "(Byte)255", ["InvalidImm2"] = "(SveMaskPattern)108", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy64BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy64BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)1", ["Imm2"] = "SveMaskPattern.VectorCount6", ["InvalidImm"] = "(Byte)243", ["InvalidImm2"] = "(SveMaskPattern)109", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy64BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy64BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.LargestMultipleOf3", ["InvalidImm"] = "(Byte)19", ["InvalidImm2"] = "(SveMaskPattern)101", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2))));",}), - ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy64BitElementCount_vector_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy64BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.LargestPowerOf2", ["InvalidImm"] = "(Byte)56", ["InvalidImm2"] = "(SveMaskPattern)109", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate((long)firstOp[i], (long)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2)))",}), - ("SveVecImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy64BitElementCount_vector_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy64BitElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.VectorCount8", ["InvalidImm"] = "(Byte)75", ["InvalidImm2"] = "(SveMaskPattern)154", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate((ulong)firstOp[i], (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt64(imm2)))",}), - - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy8BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy8BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.VectorCount8", ["InvalidImm"] = "(Byte)100", ["InvalidImm2"] = "(SveMaskPattern)235", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy8BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy8BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.VectorCount4", ["InvalidImm"] = "(Byte)99", ["InvalidImm2"] = "(SveMaskPattern)123", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy8BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy8BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.VectorCount5", ["InvalidImm"] = "(Byte)98", ["InvalidImm2"] = "(SveMaskPattern)232", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), - ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementBy8BitElementCount_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementBy8BitElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.All", ["InvalidImm"] = "(Byte)97", ["InvalidImm2"] = "(SveMaskPattern)234", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.AddSaturate((ulong)data, (ulong)(imm1 * Helpers.NumberOfElementsInVectorInt8(imm2))));",}), - - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_int_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_int_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (int)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_long_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_long_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_long_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (long)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_uint_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_uint_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (uint)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_ulong_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskByte()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_ulong_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveSaturatingByActiveElementCount.template",new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateResult"] = "succeeded = (result == Helpers.AddSaturate(left, (ulong)Helpers.NumberOfActiveElementsInMask(right)));",}), - ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_vector_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "Helpers.getMaskInt16()", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate(left[i], (short)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.AddSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), - ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_vector_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "Helpers.getMaskInt32()", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate(left[i], (int)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.AddSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), - ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_vector_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "Helpers.getMaskInt64()", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate(left[i], (long)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.AddSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), - ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_vector_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "Helpers.getMaskUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate(left[i], (ushort)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.AddSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), - ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_vector_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "Helpers.getMaskUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate(left[i], (uint)Helpers.NumberOfActiveElementsInMask(right))", ["GetIterResult"] = "Helpers.AddSaturate(left[i], Helpers.NumberOfActiveElementsInMask(right))"}), - ("SveMasklessVecBinOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingIncrementByActiveElementCount_vector_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingIncrementByActiveElementCount", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "Helpers.getMaskUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.AddSaturate(left[i], (ulong)(Helpers.NumberOfActiveElementsInMask(right)))", ["GetIterResult"] = "Helpers.AddSaturate(left[i], (ulong)(Helpers.NumberOfActiveElementsInMask(right)))"}), - - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_Scale_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scale", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != Helpers.Scale(left[i], right[i])"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_Scale_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scale", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != Helpers.Scale(left[i], right[i])"}), - - ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter_bases_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()"}), - ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter_bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter_bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_double_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetDouble()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetDouble()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_float_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetSingle()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetSingle()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter_indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), - - // ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["NarrowingType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - // ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["NarrowingType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitNarrowing_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter16BitWithByteOffset_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter16BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitNarrowing_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitNarrowing_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitWithByteOffset_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitWithByteOffset_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitWithByteOffset_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter32BitWithByteOffset_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter32BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), - // ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitNarrowing_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["NarrowingType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()"}), - ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitNarrowing_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()"}), - // ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitNarrowing_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["NarrowingType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveScatterVectorBases.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitNarrowing_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["NarrowingType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_int_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt32()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt32()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_ulong_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), - ("SveScatterVectorOffsets.template", new Dictionary { ["TestName"] = "Sve_Scatter8BitWithByteOffset_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Scatter8BitWithByteOffsetsNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp4"] = "TestLibrary.Generator.GetUInt64()"}), - - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_sbyte_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(sbyte)Helpers.ShiftLeft((byte)left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "(sbyte)Helpers.ShiftLeft((byte)left[i], (ulong)right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_short_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(short)Helpers.ShiftLeft((ushort)left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "(short)Helpers.ShiftLeft((ushort)left[i], (ulong)right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(int)Helpers.ShiftLeft((uint)left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "(int)Helpers.ShiftLeft((uint)left[i], (ulong)right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(long)Helpers.ShiftLeft((ulong)left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "(long)Helpers.ShiftLeft((ulong)left[i], (ulong)right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], (ulong)right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], (ulong)right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], (ulong)right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_sbyte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(sbyte)Helpers.ShiftLeft((byte)left[i], right[(i * sizeof(byte)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "(sbyte)Helpers.ShiftLeft((byte)left[i], right[(i * sizeof(byte)) / sizeof(ulong)])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_short_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(short)Helpers.ShiftLeft((ushort)left[i], right[(i * sizeof(ushort)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "(short)Helpers.ShiftLeft((ushort)left[i], right[(i * sizeof(ushort)) / sizeof(ulong)])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(int)Helpers.ShiftLeft((uint)left[i], right[(i * sizeof(uint)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "(int)Helpers.ShiftLeft((uint)left[i], right[(i * sizeof(uint)) / sizeof(ulong)])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_byte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], right[(i * sizeof(byte)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], right[(i * sizeof(byte)) / sizeof(ulong)])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_ushort_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], right[(i * sizeof(ushort)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], right[(i * sizeof(ushort)) / sizeof(ulong)])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftLeftLogical_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftLeft(left[i], right[(i * sizeof(uint)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftLeft(left[i], right[(i * sizeof(uint)) / sizeof(ulong)])"}), - - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_sbyte_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_short_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_sbyte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(sbyte)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(sbyte)) / sizeof(ulong)])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_short_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(short)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(short)) / sizeof(ulong)])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightArithmetic_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(int)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(int)) / sizeof(ulong)])"}), - - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve_ShiftRightArithmeticForDivide_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmeticForDivide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["InvalidImm"] = "0", ["Imm"] = "(TestLibrary.Generator.GetByte() % 8) + 1", ["ValidateIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)imm) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)imm)"}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve_ShiftRightArithmeticForDivide_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmeticForDivide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["InvalidImm"] = "0", ["Imm"] = "(TestLibrary.Generator.GetByte() % 16) + 1", ["ValidateIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)imm) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)imm)"}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve_ShiftRightArithmeticForDivide_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmeticForDivide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["InvalidImm"] = "0", ["Imm"] = "(TestLibrary.Generator.GetByte() % 32) + 1", ["ValidateIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)imm) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)imm)"}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve_ShiftRightArithmeticForDivide_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightArithmeticForDivide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["InvalidImm"] = "0", ["Imm"] = "(TestLibrary.Generator.GetByte() % 64) + 1", ["ValidateIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)imm) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(firstOp[i], (ulong)imm)"}), - - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], (ulong)right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[i])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_byte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(byte)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(byte)) / sizeof(ulong)])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_ushort_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(ushort)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(ushort)) / sizeof(ulong)])"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve_ShiftRightLogical_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(uint)) / sizeof(ulong)]) != result[i]", ["GetIterResult"] = "Helpers.ShiftRight(left[i], right[(i * sizeof(uint)) / sizeof(ulong)])"}), - - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend16_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, false)"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend16_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, false)"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend32_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 32, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 32, false)"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend8_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, false)"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend8_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, false)"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend8_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, false)"}), - - ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningLower_short_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), - ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningLower_int_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), - ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningLower_long_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), - ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningUpper_short_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), - ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningUpper_int_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), - ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningUpper_long_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), - - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Sqrt_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.Sqrt(firstOp[i])", ["GetIterResult"] = "Helpers.Sqrt(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Sqrt_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.Sqrt(firstOp[i])", ["GetIterResult"] = "Helpers.Sqrt(leftOp[i])"}), - - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "0", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "2", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_4", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "4", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_6", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "1", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_5", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_7", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - - ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), - ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), - ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), - ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), - ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), - ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), - ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), - ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = ""}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_SubtractSaturate_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), - - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - - ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricSelectCoefficient_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricSelectCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricSelectCoefficient(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricSelectCoefficient(left[i], right[i]) : result[i]"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricSelectCoefficient_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricSelectCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricSelectCoefficient(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricSelectCoefficient(left[i], right[i]) : result[i]"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricStartingValue_float_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricStartingValue", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricStartingValue(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricStartingValue(left[i], right[i]) : result[i]"}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricStartingValue_double_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricStartingValue", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) && (Helpers.TrigonometricStartingValue(left[i], right[i]) != result[i])", ["GetIterResult"] = "((left[i] <= (Math.PI / 4)) && (left[i] > (-Math.PI / 4))) ? Helpers.TrigonometricStartingValue(left[i], right[i]) : result[i]"}), - - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipEven_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_UnzipOdd_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), - - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "(UInt32) (TestLibrary.Generator.GetUInt32() % (UInt32)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt32) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "(UInt64) (TestLibrary.Generator.GetUInt64() % (UInt64)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt64) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(Byte) (TestLibrary.Generator.GetByte() % (Byte) (Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (Byte) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "(UInt16) (TestLibrary.Generator.GetUInt16() % (UInt16)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt16) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(UInt32) (TestLibrary.Generator.GetUInt32() % (UInt32)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt32) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "(UInt64) (TestLibrary.Generator.GetUInt64() % (UInt64)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt64) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte) (TestLibrary.Generator.GetByte() % (Byte) (Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (Byte) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "(UInt16) (TestLibrary.Generator.GetUInt16() % (UInt16)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt16) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(UInt32) (TestLibrary.Generator.GetUInt32() % (UInt32)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt32) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_VectorTableLookup_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "(UInt64) (TestLibrary.Generator.GetUInt64() % (UInt64)(Op2ElementCount * 2))", ["ValidateEntry"] = "(right[i] < (UInt64) RetElementCount) ? (result[i] != left[right[i]]) : (result[i] != 0)"}), - - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend16_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, true)"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend16_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(TestLibrary.Generator.GetUInt64() & 0x3FFFFFFFFFFFFFFF)", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, true)"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend32_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(TestLibrary.Generator.GetUInt64() & 0x3FFFFFFFFFFFFFFF)", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 32, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 32, true)"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend8_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, true)"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend8_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, true)"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend8_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(TestLibrary.Generator.GetUInt64() & 0x3FFFFFFFFFFFFFFF)", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, true)"}), - - ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningLower_ushort_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), - ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningLower_uint_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), - ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningLower_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), - ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningUpper_ushort_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), - ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningUpper_uint_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), - ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningUpper_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), - - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_float_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_double_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_sbyte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_short_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_int_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_long_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_byte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_ushort_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_uint_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElement_ulong_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElement", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractAfterLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractAfterLastActiveElementAndReplicate_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractAfterLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractAfterLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_float_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_double_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_sbyte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_short_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_int_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_long_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_byte_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_ushort_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_uint_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElement(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveScalarTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElement_ulong_scalar", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElement", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateScalarResult"] = "Helpers.ConditionalExtractLastActiveElement(firstOp, secondOp, thirdOp) != result",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_ConditionalExtractLastActiveElementAndReplicate_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalExtractLastActiveElementAndReplicate", ["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()", ["ValidateIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(firstOp, secondOp, thirdOp)[i] != result[i]", ["GetIterResult"] = "Helpers.ConditionalExtractLastActiveElementAndReplicate(first, second, third)[i]", ["ConvertFunc"] = " ",}), - - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipHigh_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_ZipLow_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), - - ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreTest.template", new Dictionary { ["TestName"] = "Sve_StoreAndZip_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), - ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), - ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), - ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), - ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), - ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), - ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), - ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), - ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), - ("SveStoreAndZipTestx2.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx2_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i]))"}), - ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), - ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), - ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), - ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), - ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), - ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), - ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), - ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), - ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), - ("SveStoreAndZipTestx3.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx3_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i]))"}), - ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), - ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), - ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), - ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), - ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), - ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), - ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), - ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), - ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), - ("SveStoreAndZipTestx4.template", new Dictionary { ["TestName"] = "Sve_StoreAndZipx4_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreAndZip", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(maskArray[i] == 0 && (result[index] != 0 || result[index + 1] != 0 || result[index + 2] != 0 || result[index + 3] != 0)) || (maskArray[i] == 1 && (result[index] != first[i] || result[index + 1] != second[i] || result[index + 2] != third[i] || result[index + 3] != fourth[i]))"}), - - ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_short_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (SByte)first[i])"}), - ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_int_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (SByte)first[i])"}), - ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_int_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (Int16)first[i])"}), - ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_long_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (SByte)first[i])"}), - ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_long_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (Int16)first[i])"}), - ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_long_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (Int32)first[i])"}), - ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_ushort_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (Byte)first[i])"}), - ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_uint_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (Byte)first[i])"}), - ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_uint_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (UInt16)first[i])"}), - ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_ulong_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (Byte)first[i])"}), - ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_ulong_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (UInt16)first[i])"}), - ("SveStoreNarrowTest.template", new Dictionary { ["TestName"] = "Sve_StoreNarrow_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNarrowing", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != (UInt32)first[i])"}), - - ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - ("SveStoreNonTemporalTest.template", new Dictionary { ["TestName"] = "Sve_StoreNonTemporal_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "StoreNonTemporal", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(maskArray[i] == 0 && result[i] != 0) || (maskArray[i] == 1 && result[i] != first[i])"}), - - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalEstimate_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.ReciprocalEstimate(firstOp[i])", ["GetIterResult"] = "Helpers.ReciprocalEstimate(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalEstimate_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.ReciprocalEstimate(firstOp[i])", ["GetIterResult"] = "Helpers.ReciprocalEstimate(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalExponent_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalExponent", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.ReciprocalExponent(firstOp[i])", ["GetIterResult"] = "Helpers.ReciprocalExponent(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalExponent_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalExponent", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.ReciprocalExponent(firstOp[i])", ["GetIterResult"] = "Helpers.ReciprocalExponent(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalSqrtEstimate_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalSqrtEstimate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.ReciprocalSqrtEstimate(firstOp[i])", ["GetIterResult"] = "Helpers.ReciprocalSqrtEstimate(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalSqrtEstimate_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalSqrtEstimate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.ReciprocalSqrtEstimate(firstOp[i])", ["GetIterResult"] = "Helpers.ReciprocalSqrtEstimate(leftOp[i])"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalSqrtStep_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalSqrtStep", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != Helpers.FPReciprocalSqrtStepFused(left[i], right[i])"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalSqrtStep_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalSqrtStep", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != Helpers.FPReciprocalSqrtStepFused(left[i], right[i])"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalStep_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != Helpers.FPReciprocalStepFused(left[i], right[i])"}), - ("SveVecBinaryOpValidateTest.template", new Dictionary { ["TestName"] = "Sve_ReciprocalStep_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != Helpers.FPReciprocalStepFused(left[i], right[i])"}), - - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != firstOp[RetElementCount - i - 1]", ["GetIterResult"] = "leftOp[RetElementCount - i - 1]"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement8_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement8(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement8(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement8_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement8(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement8(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement8_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement8(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement8(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement8_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement8(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement8(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement8_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement8(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement8(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement8_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement8(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement8(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement16_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement16(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement16(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement16_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement16(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement16(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement16_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement16(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement16(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement16_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement16(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement16(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement32_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement32(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement32(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseElement32_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseElement32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElement32(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElement32(leftOp[i])"}), - - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundAwayFromZero_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundAwayFromZero", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.RoundAwayFromZero(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundAwayFromZero(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundAwayFromZero_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundAwayFromZero", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.RoundAwayFromZero(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundAwayFromZero(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToNearest_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToNearest", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.RoundToNearest(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToNearest(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToNearest_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToNearest", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.RoundToNearest(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToNearest(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToNegativeInfinity_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToNegativeInfinity", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.RoundToNegativeInfinity(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToNegativeInfinity(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToNegativeInfinity_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToNegativeInfinity", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.RoundToNegativeInfinity(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToNegativeInfinity(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToPositiveInfinity_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToPositiveInfinity", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.RoundToPositiveInfinity(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToPositiveInfinity(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToPositiveInfinity_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToPositiveInfinity", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.RoundToPositiveInfinity(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToPositiveInfinity(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToZero_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToZero", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.RoundToZero(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToZero(leftOp[i])"}), - ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_RoundToZero_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "RoundToZero", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.RoundToZero(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.RoundToZero(leftOp[i])"}), - - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "SByte", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskSByte())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskSByte())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "Int16", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt16())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt16())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "Int32", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt32())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt32())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "Int64", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt64())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt64())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "Byte", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskByte())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskByte())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "UInt16", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt16())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt16())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "UInt32", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt32())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt32())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestAnyTrue_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestAnyTrue", ["MaskBaseType"] = "UInt64", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt64())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt64())", ["ValidateEntry"] = "TestAnyTrue(op1, op2) != result"}), - - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "SByte", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskSByte())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskSByte())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "Int16", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt16())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt16())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "Int32", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt32())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt32())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "Int64", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt64())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt64())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "Byte", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskByte())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskByte())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "UInt16", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt16())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt16())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "UInt32", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt32())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt32())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestFirstTrue_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestFirstTrue", ["MaskBaseType"] = "UInt64", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt64())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt64())", ["ValidateEntry"] = "TestFirstTrue(op1, op2) != result"}), - - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "SByte", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskSByte())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskSByte())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "Int16", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt16())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt16())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "Int32", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt32())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt32())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "Int64", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt64())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskInt64())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "Byte", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskByte())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskByte())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "UInt16", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt16())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt16())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "UInt32", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt32())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt32())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), - ("SveTestTest.template", new Dictionary { ["TestName"] = "Sve_TestLastTrue_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TestLastTrue", ["MaskBaseType"] = "UInt64", ["Op1Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt64())", ["Op2Value"] = "Helpers.InitVector(_ => Helpers.getMaskUInt64())", ["ValidateEntry"] = "TestLastTrue(op1, op2) != result"}), - - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeEven_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index * 2] || result[i + 1] != right[index * 2]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), - ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "Sve_TransposeOdd_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index * 2 + 1] || result[i + 1] != right[index * 2 + 1]"}), -}; - -(string templateFileName, Dictionary templateData)[] Sve2Inputs = new[] -{ - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(SByte) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["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"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["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"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["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"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(Byte) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["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"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceAdd_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceAdd", ["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"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i])"}), - - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddEven_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddEven", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddEven_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddEven", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddEven_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddEven", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddEven_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddEven", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddEven_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddEven", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddEven_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddEven", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AbsoluteDifferenceWideningLowerAndAddEven(first, second, third, i)"}), - - ("SveVecTernOpFirstArgTest.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddOdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddOdd", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddOdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddOdd", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddOdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddOdd", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddOdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddOdd", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddOdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddOdd", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningLowerAndAddOdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningLowerAndAddOdd", ["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"] = "Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AbsoluteDifferenceWideningLowerAndAddOdd(first, second, third, i)"}), - - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningEven_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningEven(left, right, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AbsoluteDifferenceWideningEven(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningEven_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningEven", ["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.AbsoluteDifferenceWideningEven(left, right, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AbsoluteDifferenceWideningEven(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningEven_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningEven", ["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.AbsoluteDifferenceWideningEven(left, right, i) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AbsoluteDifferenceWideningEven(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningEven_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningEven(left, right, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AbsoluteDifferenceWideningEven(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningEven_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningEven(left, right, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AbsoluteDifferenceWideningEven(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningEven_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningEven(left, right, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AbsoluteDifferenceWideningEven(left, right, i)"}), - - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningOdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningOdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningOdd", ["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.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningOdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningOdd", ["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.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningOdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningOdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AbsoluteDifferenceWideningOdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}), - - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningEven_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningEven", ["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"] = "Helpers.AddCarryWideningEven(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddCarryWideningEven(first, second, third, i)"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningEven_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningEven", ["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"] = "Helpers.AddCarryWideningEven(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddCarryWideningEven(first, second, third, i)"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningOdd_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningOdd", ["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"] = "Helpers.AddCarryWideningOdd(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddCarryWideningOdd(first, second, third, i)"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddCarryWideningOdd_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningOdd", ["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"] = "Helpers.AddCarryWideningOdd(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddCarryWideningOdd(first, second, third, i)"}), - - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingEven", ["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.AddHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "(SByte) Helpers.AddHighNarrowingEven(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingEven", ["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.AddHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddHighNarrowingEven(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingEven", ["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.AddHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddHighNarrowingEven(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingEven", ["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.AddHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "(Byte) Helpers.AddHighNarrowingEven(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingEven", ["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.AddHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddHighNarrowingEven(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingEven", ["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.AddHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddHighNarrowingEven(left, right, i)"}), - - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingOdd", ["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.AddHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(SByte) Helpers.AddHighNarrowingOdd(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingOdd", ["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.AddHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddHighNarrowingOdd(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingOdd", ["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.AddHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddHighNarrowingOdd(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingOdd", ["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.AddHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(Byte) Helpers.AddHighNarrowingOdd(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingOdd", ["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.AddHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddHighNarrowingOdd(first, second, third, i)"}), - ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_AddHighNarrowingOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddHighNarrowingOdd", ["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.AddHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddHighNarrowingOdd(first, second, third, i)"}), - - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_float", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(Single) Helpers.AddPairwiseSve(left, right, i)"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_double", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(Double) Helpers.AddPairwiseSve(left, right, i)"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(SByte) Helpers.AddPairwiseSve(left, right, i)"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddPairwiseSve(left, right, i)"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddPairwiseSve(left, right, i)"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddPairwiseSve(left, right, i)"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(Byte) Helpers.AddPairwiseSve(left, right, i)"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddPairwiseSve(left, right, i)"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddPairwiseSve(left, right, i)"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddPairwise_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwise", ["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.AddPairwiseSve(left, right, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddPairwiseSve(left, right, i)"}), - - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddPairwiseWidening_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWidening", ["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.AddPairwiseWidening(left, right, i) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddPairwiseWidening(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddPairwiseWidening_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWidening", ["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.AddPairwiseWidening(left, right, i) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddPairwiseWidening(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddPairwiseWidening_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWidening", ["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.AddPairwiseWidening(left, right, i) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddPairwiseWidening(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddPairwiseWidening_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(left, right, i) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddPairwiseWidening(left, right, i)"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddPairwiseWidening_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWidening", ["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_AddPairwiseWidening_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWidening", ["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)"}), - - ("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])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["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.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["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.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Byte) Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["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.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["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.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["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.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddSaturate(left[i], right[i])"}), - - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithSignedAddend_byte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithSignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Byte) Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithSignedAddend_ushort_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithSignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithSignedAddend_uint_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithSignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithSignedAddend_ulong_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithSignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddSaturate(left[i], right[i])"}), - - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithUnsignedAddend_sbyte_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithUnsignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(SByte) Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithUnsignedAddend_short_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithUnsignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithUnsignedAddend_int_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithUnsignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddSaturate(left[i], right[i])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary {["TestName"] = "Sve2_AddSaturateWithUnsignedAddend_long_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturateWithUnsignedAddend", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddSaturate(left[i], right[i])"}), - - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideLower_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideLower", ["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.AddWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddWidening(left[i], right[i * 2])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideLower_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideLower", ["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.AddWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddWidening(left[i], right[i * 2])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideLower_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideLower", ["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.AddWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddWidening(left[i], right[i * 2])",}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideLower_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i * 2])!= result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddWidening(left[i], right[i * 2])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideLower_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideLower", ["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.AddWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddWidening(left[i], right[i * 2])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideLower_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideLower", ["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.AddWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddWidening(left[i], right[i * 2])"}), - - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideUpper_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideUpper", ["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.AddWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddWidening(left[i], right[i * 2 + 1])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideUpper_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideUpper", ["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.AddWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddWidening(left[i], right[i * 2 + 1])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideUpper_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideUpper", ["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.AddWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddWidening(left[i], right[i * 2 + 1])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideUpper_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddWidening(left[i], right[i * 2 + 1])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideUpper_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideUpper", ["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.AddWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddWidening(left[i], right[i * 2 + 1])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideUpper_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideUpper", ["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.AddWidening(left[i], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddWidening(left[i], right[i * 2 + 1])"}), - - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningLower_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddWidening(left[i * 2], right[i * 2])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningLower_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningLower", ["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.AddWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddWidening(left[i * 2], right[i * 2])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningLower_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningLower", ["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.AddWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddWidening(left[i * 2], right[i * 2])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningLower_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddWidening(left[i * 2], right[i * 2])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningLower_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddWidening(left[i * 2], right[i * 2])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningLower_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2], right[i * 2]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddWidening(left[i * 2], right[i * 2])"}), - - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningLowerUpper_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningLowerUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddWidening(left[i * 2], right[i * 2 + 1])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningLowerUpper_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningLowerUpper", ["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.AddWidening(left[i * 2], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddWidening(left[i * 2], right[i * 2 + 1])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningLowerUpper_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningLowerUpper", ["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.AddWidening(left[i * 2], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddWidening(left[i * 2], right[i * 2 + 1])"}), - - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningUpper_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningUpper_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningUpper", ["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.AddWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningUpper_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningUpper", ["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.AddWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(Int64) Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningUpper_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(UInt16) Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningUpper_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddWideningUpper_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1]) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddWidening(left[i * 2 + 1], right[i * 2 + 1])"}), - - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(SByte) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["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] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Int16) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["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] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Int32) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Int64) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["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] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Byte) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(UInt16)(firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["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] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(UInt32)(firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseClearXor_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["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] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(UInt64)(firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}), - - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["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.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["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.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["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.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["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.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelect_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelect", ["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.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["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.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["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.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["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.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["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.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectLeftInverted_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectLeftInverted", ["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.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectLeftInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["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.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["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.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["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.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["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.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["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.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[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]"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["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.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["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.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["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.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["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.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["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.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), - ("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]"}), - - ("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])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRounded_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRounded", ["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] != (long) Helpers.SveShiftArithmeticRounded(left[i], right[i])", ["GetIterResult"] = "(long) Helpers.SveShiftArithmeticRounded(leftOp[i], rightOp[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRoundedSaturate_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRoundedSaturate", ["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.SveShiftArithmeticRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "(sbyte)Helpers.SveShiftArithmeticRoundedSaturate(leftOp[i], rightOp[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRoundedSaturate_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRoundedSaturate", ["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.SveShiftArithmeticRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "(short)Helpers.SveShiftArithmeticRoundedSaturate(leftOp[i], rightOp[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRoundedSaturate_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRoundedSaturate", ["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.SveShiftArithmeticRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "(int) Helpers.SveShiftArithmeticRoundedSaturate(leftOp[i], rightOp[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRoundedSaturate_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRoundedSaturate", ["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] != (long) Helpers.SveShiftArithmeticRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "(long) Helpers.SveShiftArithmeticRoundedSaturate(leftOp[i], rightOp[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticSaturate_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticSaturate", ["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.SveShiftArithmeticSaturate(left[i], right[i])", ["GetIterResult"] = "(sbyte)Helpers.SveShiftArithmeticSaturate(leftOp[i], rightOp[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticSaturate_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticSaturate", ["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.SveShiftArithmeticSaturate(left[i], right[i])", ["GetIterResult"] = "(short)Helpers.SveShiftArithmeticSaturate(leftOp[i], rightOp[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticSaturate_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticSaturate", ["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.SveShiftArithmeticSaturate(left[i], right[i])", ["GetIterResult"] = "(int) Helpers.SveShiftArithmeticSaturate(leftOp[i], rightOp[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticSaturate_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticSaturate", ["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] != (long) Helpers.SveShiftArithmeticSaturate(left[i], right[i])", ["GetIterResult"] = "(long) Helpers.SveShiftArithmeticSaturate(leftOp[i], rightOp[i])"}), - - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["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()", ["Imm"] = "12", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["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()", ["Imm"] = "23", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["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()", ["Imm"] = "63", ["InvalidImm"] = "64", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["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()", ["Imm"] = "9", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["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()", ["Imm"] = "17", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLeftAndInsert_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftAndInsert", ["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()", ["Imm"] = "45", ["InvalidImm"] = "64", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftAndInsert(firstOp[i], secondOp[i], Imm)"}), - - ("SveVecBinOpDifferentTypesTest.template",new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturate_byte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturate(leftOp[i], rightOp[i])"}), - ("SveVecBinOpDifferentTypesTest.template",new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturate_ushort_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturate(leftOp[i], rightOp[i])"}), - ("SveVecBinOpDifferentTypesTest.template",new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturate_uint_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturate(leftOp[i], rightOp[i])"}), - ("SveVecBinOpDifferentTypesTest.template",new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturate_ulong_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturate(leftOp[i], rightOp[i])"}), - - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturateUnsigned_byte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "2", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)"}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturateUnsigned_ushort_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "14", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)"}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturateUnsigned_uint_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "19", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)"}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalSaturateUnsigned_ulong_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "39", ["InvalidImm"] = "64", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.SveShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm)"}), - - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningEven_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningEven_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "10", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningEven_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "31", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningEven_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "2", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningEven_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "2", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningEven_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "2", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i], Imm)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningOdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningOdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "15", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningOdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "23", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningOdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningOdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "13", ["InvalidImm"] = "16", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLeftLogicalWideningOdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLeftLogicalWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "20", ["InvalidImm"] = "32", ["ValidateIterResult"] = "result[i] != Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)", ["GetIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[2*i+1], Imm)",}), - - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLogicalRounded_byte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRounded(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRounded(left[i], right[i])",}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLogicalRounded_ushort_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRounded(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRounded(left[i], right[i])",}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLogicalRounded_uint_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRounded(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRounded(left[i], right[i])",}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftLogicalRounded_ulong_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRounded(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRounded(left[i], right[i])",}), - - ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLogicalRoundedSaturate_byte_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])",}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLogicalRoundedSaturate_ushort_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])",}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLogicalRoundedSaturate_uint_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])",}), - ("SveVecBinOpDifferentTypesTest.template", new Dictionary {["TestName"] = "Sve2_ShiftLogicalRoundedSaturate_ulong_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])", ["GetIterResult"] = "Helpers.SveShiftLogicalRoundedSaturate(left[i], right[i])",}), - - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "4", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["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()", ["Imm"] = "15", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["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()", ["Imm"] = "22", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["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()", ["Imm"] = "40", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["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()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["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()", ["Imm"] = "29", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightAndInsert_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightAndInsert", ["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()", ["Imm"] = "54", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightAndInsert(firstOp[i], secondOp[i], Imm)",}), - - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticAdd_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "4", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticAdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticAdd", ["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()", ["Imm"] = "15", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticAdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticAdd", ["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()", ["Imm"] = "22", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticAdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticAdd", ["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()", ["Imm"] = "40", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm)",}), - - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "4", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "15", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "22", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "4", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "15", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template", new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "22", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "4", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "15", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "22", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "4", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateOdd", ["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"] = "15", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateOdd", ["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"] = "22", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateUnsignedEven_byte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "4", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateUnsignedEven_ushort_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "12", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateUnsignedEven_uint_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "27", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateUnsignedOdd_byte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "8", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateUnsignedOdd_ushort_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "15", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticNarrowingSaturateUnsignedOdd_uint_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "12", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRounded_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "8", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRounded_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "8", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRounded_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "15", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRounded_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "12", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm)",}), - - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedAdd_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "2", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedAdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["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()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedAdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["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()", ["Imm"] = "29", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedAdd_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["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()", ["Imm"] = "64", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm)",}), - - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven_byte_short",["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven_ushort_int",["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven_uint_long",["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd_byte_short",["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd_ushort_int",["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd_uint_long",["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightLogicalAdd_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "2", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightLogicalAdd_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalAdd", ["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()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightLogicalAdd_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalAdd", ["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()", ["Imm"] = "29", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftRightLogicalAdd_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalAdd", ["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()", ["Imm"] = "64", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm)",}), - - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingOdd", ["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.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalNarrowingOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalNarrowingOdd", ["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.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRounded_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "2", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRounded_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRounded_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "29", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRounded_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "64", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm)",}), - - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedAdd_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "2", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedAdd_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedAdd", ["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()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedAdd_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedAdd", ["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()", ["Imm"] = "29", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedAdd_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedAdd", ["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()", ["Imm"] = "64", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm)",}), - - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingOdd", ["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.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingOdd", ["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.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), - - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingSaturateEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingSaturateEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - ("SveVecImmUnOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingSaturateEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateEven(firstOp[Helpers.NarrowIdx(i)], Imm, i)",}), - - ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingSaturateOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["Imm"] = "3", ["InvalidImm"] = "9", ["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_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)",}), - - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("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)"}), - ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(third[i] < (UInt64) RetElementCount * 2) ? ((third[i] < (UInt64) RetElementCount) ? (result[i] != first[third[i]]) : (result[i] != second[third[i]-(UInt64) RetElementCount])) : (result[i] != 0)"}), - ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_float_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["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)"}), - ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_double_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(third[i] < (UInt64) RetElementCount * 2) ? ((third[i] < (UInt64) RetElementCount) ? (result[i] != first[third[i]]) : (result[i] != second[third[i]-(UInt64) RetElementCount])) : (result[i] != 0)"}), - ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_sbyte_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["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_short_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["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_int_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["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)"}), - ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_long_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(third[i] < (UInt64) RetElementCount * 2) ? ((third[i] < (UInt64) RetElementCount) ? (result[i] != first[third[i]]) : (result[i] != second[third[i]-(UInt64) RetElementCount])) : (result[i] != 0)"}), - - ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["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()", ["ValidateEntry"] = "(third[i] < (Byte) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), - ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "(third[i] < (UInt16) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), - ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["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()", ["ValidateEntry"] = "(third[i] < (UInt32) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), - ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["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()", ["ValidateEntry"] = "(third[i] < (UInt64) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), - ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_float_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "(third[i] < (UInt32) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), - ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_double_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(third[i] < (UInt64) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), - ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_sbyte_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "(third[i] < (Byte) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), - ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_short_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "(third[i] < (UInt16) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), - ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_int_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "(third[i] < (UInt32) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), - ("SveVecTernOpValidateTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookupExtension_long_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "(third[i] < (UInt64) RetElementCount) ? (result[i] != second[third[i]]) : (result[i] != first[i])"}), - - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_Xor_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "Xor", ["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.Xor(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.Xor(firstOp[i], secondOp[i], thirdOp[i])",}), - - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["Imm"] = "8", ["InvalidImm"] = "9", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["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()", ["Imm"] = "12", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["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()", ["Imm"] = "26", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["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()", ["Imm"] = "55", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["Imm"] = "3" , ["InvalidImm"] = "9" , ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["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()", ["Imm"] = "11", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["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()", ["Imm"] = "22", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), - ("SveVecImmBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_XorRotateRight_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "XorRotateRight", ["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()", ["Imm"] = "45", ["InvalidImm"] = "65", ["ValidateIterResult"] = "result[i] != Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)", ["GetIterResult"] = "Helpers.XorRotateRight(firstOp[i], secondOp[i], Imm)",}), -}; - -string projectName = args[0]; -string templateDirectory = args[1]; -string outputDirectory = args[2]; -string testListFileName = args[3]; - -ProcessInputs("AdvSimd", AdvSimdInputs); -ProcessInputs("AdvSimd.Arm64", AdvSimd_Arm64Inputs); -ProcessInputs("Aes", AesInputs); -ProcessInputs("ArmBase", ArmBaseInputs); -ProcessInputs("ArmBase.Arm64", ArmBase_Arm64Inputs); -ProcessInputs("Crc32", Crc32Inputs); -ProcessInputs("Crc32.Arm64", Crc32_Arm64Inputs); -ProcessInputs("Dp", DpInputs); -ProcessInputs("Rdm", RdmInputs); -ProcessInputs("Rdm.Arm64", Rdm_Arm64Inputs); -ProcessInputs("Sha1", Sha1Inputs); -ProcessInputs("Sha256", Sha256Inputs); -ProcessInputs("Sve", SveInputs); -ProcessInputs("Sve2", Sve2Inputs); - -void ProcessInputs(string groupName, (string templateFileName, Dictionary templateData)[] inputs) -{ - if (!projectName.Equals($"{groupName}_r") && !projectName.Equals($"{groupName}_ro")) - { - return; - } - - Directory.CreateDirectory(outputDirectory); - - using (var testListFile = new StreamWriter(testListFileName, append: false)) - { - foreach (var input in inputs) - { - ProcessInput(testListFile, groupName, input); - } - } -} -void ProcessInput(StreamWriter testListFile, string groupName, (string templateFileName, Dictionary templateData) input) -{ - var testName = input.templateData["TestName"]; - var fileName = Path.Combine(outputDirectory, $"{testName.Replace('_', '.')}.cs"); - - var matchingTemplate = Templates.Where((t) => t.outputTemplateName.Equals(input.templateFileName)).SingleOrDefault(); - var template = string.Empty; + } - if (matchingTemplate.templateFileName is null) - { - string templateFileName = Path.Combine(templateDirectory, input.templateFileName); - template = File.ReadAllText(templateFileName); - } - else - { - string templateFileName = Path.Combine(templateDirectory, matchingTemplate.templateFileName); - template = File.ReadAllText(templateFileName); + foreach (var kvp in input.templateData) + { + template = template.Replace($"{{{kvp.Key}}}", kvp.Value); + } + template = template.Replace("namespace JIT.HardwareIntrinsics.Arm", $"namespace JIT.HardwareIntrinsics.Arm._{groupName}"); - foreach (var kvp in matchingTemplate.templateData) - { - template = template.Replace($"{{{kvp.Key}}}", kvp.Value); + testListFile.WriteLine(fileName); + File.WriteAllText(fileName, template); } } - - foreach (var kvp in input.templateData) - { - template = template.Replace($"{{{kvp.Key}}}", kvp.Value); - } - template = template.Replace("namespace JIT.HardwareIntrinsics.Arm", $"namespace JIT.HardwareIntrinsics.Arm._{groupName}"); - - testListFile.WriteLine(fileName); - File.WriteAllText(fileName, template); } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.csproj b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.csproj index 529ad9fd9418ed..85108a79d3c86d 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.csproj +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.csproj @@ -7,6 +7,11 @@ + + + + + diff --git a/src/tests/Common/XHarnessRunnerLibrary/RunnerEntryPoint.cs b/src/tests/Common/XHarnessRunnerLibrary/RunnerEntryPoint.cs index 90a8cc25dc5946..e2326154a13b3b 100644 --- a/src/tests/Common/XHarnessRunnerLibrary/RunnerEntryPoint.cs +++ b/src/tests/Common/XHarnessRunnerLibrary/RunnerEntryPoint.cs @@ -28,7 +28,7 @@ public static async Task RunTests( { entryPoint = new AndroidEntryPoint(new SimpleDevice(assemblyName), runTestsCallback, assemblyName, filter, testExclusionTable); } - if (OperatingSystem.IsMacCatalyst() || OperatingSystem.IsIOS() || OperatingSystem.IsTvOS() || OperatingSystem.IsWatchOS()) + if (OperatingSystem.IsMacCatalyst() || OperatingSystem.IsIOS() || OperatingSystem.IsTvOS()) { entryPoint = new AppleEntryPoint(new SimpleDevice(assemblyName), runTestsCallback, assemblyName, filter, testExclusionTable); } diff --git a/src/tests/CoreMangLib/system/delegate/miscellaneous/ClosedStatic.cs b/src/tests/CoreMangLib/system/delegate/miscellaneous/ClosedStatic.cs index b9c01d332235cf..84f231dcc02b03 100644 --- a/src/tests/CoreMangLib/system/delegate/miscellaneous/ClosedStatic.cs +++ b/src/tests/CoreMangLib/system/delegate/miscellaneous/ClosedStatic.cs @@ -8,7 +8,7 @@ public class Program { public int scale; - public Program(int scale) + private Program(int scale) { this.scale = scale; } diff --git a/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj new file mode 100644 index 00000000000000..15886021dd3d62 --- /dev/null +++ b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj @@ -0,0 +1,24 @@ + + + + Library + true + $(NetCoreAppCurrent) + lib$(MSBuildProjectName) + $(TargetName).so + 42 + true + true + true + + + + + + + + + + + + diff --git a/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs new file mode 100644 index 00000000000000..f8430023829079 --- /dev/null +++ b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +public class Program +{ + public static int Main() + { + string message = "Hello, Android!"; + Console.WriteLine(message); // logcat + // Test the linux-bionic cryptography library + Console.WriteLine(System.Security.Cryptography.SHA256.HashData(new byte[] {0x1, 0x2, 0x3})); + return 42; + } +} \ No newline at end of file diff --git a/src/tests/FunctionalTests/iOS/Simulator/CoreCLR.Interpreter/Program.cs b/src/tests/FunctionalTests/iOS/Simulator/CoreCLR.Interpreter/Program.cs new file mode 100644 index 00000000000000..7441f31337175b --- /dev/null +++ b/src/tests/FunctionalTests/iOS/Simulator/CoreCLR.Interpreter/Program.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; + +public static class Program +{ + [DllImport("__Internal")] + public static extern void mono_ios_set_summary(string value); + + public static async Task Main(string[] args) + { + mono_ios_set_summary($"Starting functional test"); + int result = RunInterpreter(); + Console.WriteLine("Done!"); + await Task.Delay(5000); + + return result; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public unsafe static int RunInterpreter() + { + return 42; + } +} diff --git a/src/tests/FunctionalTests/iOS/Simulator/CoreCLR.Interpreter/iOS.Simulator.CoreCLR.Interpreter.Test.csproj b/src/tests/FunctionalTests/iOS/Simulator/CoreCLR.Interpreter/iOS.Simulator.CoreCLR.Interpreter.Test.csproj new file mode 100644 index 00000000000000..fbf7c10bfd0f22 --- /dev/null +++ b/src/tests/FunctionalTests/iOS/Simulator/CoreCLR.Interpreter/iOS.Simulator.CoreCLR.Interpreter.Test.csproj @@ -0,0 +1,24 @@ + + + Exe + false + false + false + true + $(NetCoreAppCurrent) + iossimulator + iOS.Simulator.CoreCLR.Interpreter.Test.dll + false + 42 + + + + + + + + + + + + diff --git a/src/tests/GC/API/WeakReference/IsAlive.cs b/src/tests/GC/API/WeakReference/IsAlive.cs index db3a01040d4cf3..2aa125cf3a8eac 100644 --- a/src/tests/GC/API/WeakReference/IsAlive.cs +++ b/src/tests/GC/API/WeakReference/IsAlive.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// Tests WeakReference.IsAlive : IsAlive=true if GC has not occurred on the object +// Tests WeakReference.IsAlive : IsAlive=true if GC has not occurred on the object using System; @@ -11,35 +11,40 @@ public class Test_IsAlive { public static int[] array; - + public static WeakReference weak; + [MethodImplAttribute(MethodImplOptions.NoInlining)] public static void CreateArray() { array = new int[50]; + // Create the weak reference inside of CreateArray to prevent a dangling 'array' reference + // from surviving inside of TestEntryPoint. + weak = new WeakReference(array); } - + [MethodImplAttribute(MethodImplOptions.NoInlining)] public static void DestroyArray() { array = null; } - + [Fact] public static int TestEntryPoint() { CreateArray(); - WeakReference weak = new WeakReference(array); - bool ans1 = weak.IsAlive; Console.WriteLine(ans1); - - if(ans1==false) { // GC.Collect() has already occurred..under GCStress - Console.WriteLine("Test for WeakReference.IsAlive passed!"); - return 100; + if (ans1 != true) + { + // This should be impossible; it would indicate that either the array was collected while reachable from + // our static field, or that the WeakReference failed to track the array even though it's still alive. + Console.WriteLine("Test for WeakReference.IsAlive failed!"); + return 2; } - //else, do an expicit collect. + // Release our strong reference (via static field) so that the collector will no longer see array as reachable. DestroyArray(); + // Perform a blocking full collection which will hopefully collect the array. GC.Collect(); - + bool ans2 = weak.IsAlive; Console.WriteLine(ans2); diff --git a/src/tests/GC/Scenarios/Rootmem/rootmem.cs b/src/tests/GC/Scenarios/Rootmem/rootmem.cs index c2f27d70b29229..99a8ad98c8f9ec 100644 --- a/src/tests/GC/Scenarios/Rootmem/rootmem.cs +++ b/src/tests/GC/Scenarios/Rootmem/rootmem.cs @@ -80,7 +80,7 @@ public static int TestEntryPoint() return 1; } - public RootMem( int i ) + private RootMem( int i ) { if( i> 0) { diff --git a/src/tests/GC/Stress/Framework/ReliabilityFramework.cs b/src/tests/GC/Stress/Framework/ReliabilityFramework.cs index 3403e33e5091d8..30ee8893d2f4aa 100644 --- a/src/tests/GC/Stress/Framework/ReliabilityFramework.cs +++ b/src/tests/GC/Stress/Framework/ReliabilityFramework.cs @@ -51,8 +51,9 @@ public CustomAssemblyResolver() protected override Assembly Load(AssemblyName assemblyName) { string strPath; - if (assemblyName.Name.StartsWith("System.")) + if (assemblyName.Name.StartsWith("System.", StringComparison.Ordinal) || assemblyName.Name.StartsWith("Microsoft.", StringComparison.Ordinal)) { + // If the assembly is a framework assembly, we load it from the framework path. strPath = Path.Combine(_frameworkPath, assemblyName.Name + ".dll"); } else diff --git a/src/tests/Interop/COM/NETClients/IDispatch/Program.cs b/src/tests/Interop/COM/NETClients/IDispatch/Program.cs index 90a6ea994ebb63..4324913a5a1fb6 100644 --- a/src/tests/Interop/COM/NETClients/IDispatch/Program.cs +++ b/src/tests/Interop/COM/NETClients/IDispatch/Program.cs @@ -108,7 +108,7 @@ static void Validate_Double_In_ReturnAndUpdateByRef() static int GetErrorCodeFromHResult(int hresult) { - // https://msdn.microsoft.com/en-us/library/cc231198.aspx + // https://msdn.microsoft.com/library/cc231198.aspx return hresult & 0xffff; } @@ -116,7 +116,7 @@ static void Validate_Exception() { var dispatchTesting = (DispatchTesting)new DispatchTestingClass(); - int errorCode = 127; + int errorCode = 1127; string resultString = errorCode.ToString("x"); try { @@ -130,6 +130,19 @@ static void Validate_Exception() Assert.Equal(e.Message, resultString); } + try + { + Console.WriteLine($"Calling {nameof(DispatchTesting.TriggerException)} with {nameof(IDispatchTesting_Exception.DispLegacy)} {errorCode}..."); + dispatchTesting.TriggerException(IDispatchTesting_Exception.DispLegacy, errorCode); + Assert.Fail("DISP exception not thrown properly"); + } + catch (COMException e) + { + Assert.Equal(e.ErrorCode, errorCode); // The legacy DISP exception returns the error code unmodified. + Assert.Equal(e.HResult, errorCode); + Assert.Equal(e.Message, resultString); + } + try { Console.WriteLine($"Calling {nameof(DispatchTesting.TriggerException)} with {nameof(IDispatchTesting_Exception.HResult)} {errorCode}..."); diff --git a/src/tests/Interop/COM/NETServer/DispatchTesting.cs b/src/tests/Interop/COM/NETServer/DispatchTesting.cs index 66461b8c7e47f2..bf9b9d740e90ce 100644 --- a/src/tests/Interop/COM/NETServer/DispatchTesting.cs +++ b/src/tests/Interop/COM/NETServer/DispatchTesting.cs @@ -55,6 +55,7 @@ public void TriggerException(IDispatchTesting_Exception excep, int errorCode) switch (excep) { case IDispatchTesting_Exception.Disp: + case IDispatchTesting_Exception.DispLegacy: throw new Exception(); case IDispatchTesting_Exception.HResult: case IDispatchTesting_Exception.Int: diff --git a/src/tests/Interop/COM/NativeServer/DispatchTesting.h b/src/tests/Interop/COM/NativeServer/DispatchTesting.h index b4ee769ed8cb46..4c69174eec7e2e 100644 --- a/src/tests/Interop/COM/NativeServer/DispatchTesting.h +++ b/src/tests/Interop/COM/NativeServer/DispatchTesting.h @@ -240,6 +240,7 @@ class DispatchTesting : public UnknownImpl, public IDispatchTesting switch (excep) { case IDispatchTesting_Exception_Disp: + case IDispatchTesting_Exception_Disp_Legacy: return DISP_E_EXCEPTION; case IDispatchTesting_Exception_HResult: return HRESULT_FROM_WIN32(errorCode); @@ -457,11 +458,22 @@ class DispatchTesting : public UnknownImpl, public IDispatchTesting args[1] = &currArg->intVal; } - hr = TriggerException(static_cast(*args[0]), *args[1]); + IDispatchTesting_Exception kind = static_cast(*args[0]); + hr = TriggerException(kind, *args[1]); if (hr == DISP_E_EXCEPTION) { *puArgErr = 1; - pExcepInfo->scode = HRESULT_FROM_WIN32(*args[1]); + if (kind == IDispatchTesting_Exception_Disp_Legacy) + { + pExcepInfo->wCode = *args[1]; // Legacy exception code + pExcepInfo->scode = 0; + } + else + { + assert(kind == IDispatchTesting_Exception_Disp); + pExcepInfo->wCode = 0; + pExcepInfo->scode = HRESULT_FROM_WIN32(*args[1]); + } WCHAR buffer[ARRAY_SIZE(W("4294967295"))]; _snwprintf_s(buffer, ARRAY_SIZE(buffer), _TRUNCATE, W("%x"), *args[1]); diff --git a/src/tests/Interop/COM/ServerContracts/Server.Contracts.cs b/src/tests/Interop/COM/ServerContracts/Server.Contracts.cs index ae68bcf34a07bf..a697d0359a2b62 100644 --- a/src/tests/Interop/COM/ServerContracts/Server.Contracts.cs +++ b/src/tests/Interop/COM/ServerContracts/Server.Contracts.cs @@ -237,7 +237,8 @@ public interface IErrorMarshalTesting public enum IDispatchTesting_Exception { - Disp, + Disp, // scode + DispLegacy, // wCode HResult, Int, } diff --git a/src/tests/Interop/COM/ServerContracts/Server.Contracts.h b/src/tests/Interop/COM/ServerContracts/Server.Contracts.h index 9e8b256a73d3b3..b73c0c54b8b2f9 100644 --- a/src/tests/Interop/COM/ServerContracts/Server.Contracts.h +++ b/src/tests/Interop/COM/ServerContracts/Server.Contracts.h @@ -413,7 +413,8 @@ IErrorMarshalTesting : IUnknown enum IDispatchTesting_Exception { - IDispatchTesting_Exception_Disp, + IDispatchTesting_Exception_Disp, // scode + IDispatchTesting_Exception_Disp_Legacy, // wCode IDispatchTesting_Exception_HResult, IDispatchTesting_Exception_Int, }; diff --git a/src/tests/Interop/GCBridge/BridgeTest.csproj b/src/tests/Interop/GCBridge/BridgeTest.csproj index 0cba84d2c4b127..965f8371061bb7 100644 --- a/src/tests/Interop/GCBridge/BridgeTest.csproj +++ b/src/tests/Interop/GCBridge/BridgeTest.csproj @@ -3,8 +3,7 @@ true true - - true + true true diff --git a/src/tests/Interop/IDynamicInterfaceCastable/Program.cs b/src/tests/Interop/IDynamicInterfaceCastable/Program.cs index 73c84920352d15..94d56222a3675e 100644 --- a/src/tests/Interop/IDynamicInterfaceCastable/Program.cs +++ b/src/tests/Interop/IDynamicInterfaceCastable/Program.cs @@ -213,7 +213,7 @@ public class DynamicInterfaceCastable : IDynamicInterfaceCastable, IDirectlyImpl { private Dictionary interfaceToImplMap; - public DynamicInterfaceCastable(Dictionary interfaceToImplMap) + protected DynamicInterfaceCastable(Dictionary interfaceToImplMap) { this.interfaceToImplMap = interfaceToImplMap; } @@ -347,14 +347,20 @@ public RuntimeTypeHandle GetInterfaceImplementation(RuntimeTypeHandle interfaceT [ActiveIssue("https://github.com/dotnet/runtime/issues/55742", TestRuntimes.Mono)] public class Program { + class DynamicInterfaceCastable_ValidateBasicInterface : DynamicInterfaceCastable + { + public DynamicInterfaceCastable_ValidateBasicInterface() + : base(new Dictionary { + { typeof(ITest), typeof(ITestImpl) } + }) { } + } + [Fact] public static void ValidateBasicInterface() { Console.WriteLine($"Running {nameof(ValidateBasicInterface)}"); - object castableObj = new DynamicInterfaceCastable(new Dictionary { - { typeof(ITest), typeof(ITestImpl) } - }); + object castableObj = new DynamicInterfaceCastable_ValidateBasicInterface(); Console.WriteLine(" -- Validate cast"); @@ -365,7 +371,7 @@ public static void ValidateBasicInterface() Console.WriteLine(" -- Validate method call"); Assert.Same(castableObj, testObj.ReturnThis()); - Assert.Equal(typeof(DynamicInterfaceCastable), testObj.GetMyType()); + Assert.Equal(typeof(DynamicInterfaceCastable_ValidateBasicInterface), testObj.GetMyType()); Console.WriteLine(" -- Validate method call which calls methods using 'this'"); Assert.Equal(DynamicInterfaceCastable.ImplementedMethodReturnValue, testObj.CallImplemented(ImplementationToCall.Class)); @@ -379,16 +385,22 @@ public static void ValidateBasicInterface() Assert.Same(castableObj, func()); } + class DynamicInterfaceCastable_ValidateGenericInterface : DynamicInterfaceCastable + { + public DynamicInterfaceCastable_ValidateGenericInterface() + : base(new Dictionary { + { typeof(ITestGeneric), typeof(ITestGenericIntImpl) }, + { typeof(ITestGeneric), typeof(ITestGenericImpl) }, + { typeof(ITestGeneric), typeof(ITestGenericImpl) }, + }) { } + } + [Fact] public static void ValidateGenericInterface() { Console.WriteLine($"Running {nameof(ValidateGenericInterface)}"); - object castableObj = new DynamicInterfaceCastable(new Dictionary { - { typeof(ITestGeneric), typeof(ITestGenericIntImpl) }, - { typeof(ITestGeneric), typeof(ITestGenericImpl) }, - { typeof(ITestGeneric), typeof(ITestGenericImpl) }, - }); + object castableObj = new DynamicInterfaceCastable_ValidateGenericInterface(); Console.WriteLine(" -- Validate cast"); @@ -442,15 +454,21 @@ public static void ValidateGenericInterface() Assert.Equal(expectedStr, funcVar(expectedStr)); } + class DynamicInterfaceCastable_ValidateOverriddenInterface : DynamicInterfaceCastable + { + public DynamicInterfaceCastable_ValidateOverriddenInterface() + : base(new Dictionary { + { typeof(ITest), typeof(IOverrideTestImpl) }, + { typeof(IOverrideTest), typeof(IOverrideTestImpl) }, + }) { } + } + [Fact] public static void ValidateOverriddenInterface() { Console.WriteLine($"Running {nameof(ValidateOverriddenInterface)}"); - object castableObj = new DynamicInterfaceCastable(new Dictionary { - { typeof(ITest), typeof(IOverrideTestImpl) }, - { typeof(IOverrideTest), typeof(IOverrideTestImpl) }, - }); + object castableObj = new DynamicInterfaceCastable_ValidateOverriddenInterface(); Console.WriteLine(" -- Validate cast"); @@ -476,14 +494,20 @@ public static void ValidateOverriddenInterface() Assert.Equal(IOverrideTestImpl.GetMyTypeReturnValue, funcGetType()); } + class DynamicInterfaceCastable_ValidateNotImplemented : DynamicInterfaceCastable + { + public DynamicInterfaceCastable_ValidateNotImplemented() + : base(new Dictionary { + { typeof(ITest), typeof(ITestImpl) } + }) { } + } + [Fact] public static void ValidateNotImplemented() { Console.WriteLine($"Running {nameof(ValidateNotImplemented)}"); - object castableObj = new DynamicInterfaceCastable(new Dictionary { - { typeof(ITest), typeof(ITestImpl) } - }); + object castableObj = new DynamicInterfaceCastable_ValidateNotImplemented(); Assert.False(castableObj is INotImplemented, $"Should not be castable to {nameof(INotImplemented)} via is"); Assert.Null(castableObj as INotImplemented); @@ -491,15 +515,21 @@ public static void ValidateNotImplemented() Assert.Equal(string.Format(DynamicInterfaceCastableException.ErrorFormat, typeof(INotImplemented)), ex.Message); } + class DynamicInterfaceCastable_ValidateDirectlyImplemented : DynamicInterfaceCastable + { + public DynamicInterfaceCastable_ValidateDirectlyImplemented() + : base(new Dictionary { + { typeof(ITest), typeof(ITestImpl) }, + { typeof(IDirectlyImplemented), typeof(IDirectlyImplementedImpl) }, + }) { } + } + [Fact] public static void ValidateDirectlyImplemented() { Console.WriteLine($"Running {nameof(ValidateDirectlyImplemented)}"); - object castableObj = new DynamicInterfaceCastable(new Dictionary { - { typeof(ITest), typeof(ITestImpl) }, - { typeof(IDirectlyImplemented), typeof(IDirectlyImplementedImpl) }, - }); + object castableObj = new DynamicInterfaceCastable_ValidateDirectlyImplemented(); Console.WriteLine(" -- Validate cast"); Assert.True(castableObj is IDirectlyImplemented, $"Should be castable to {nameof(IDirectlyImplemented)} via is"); diff --git a/src/tests/JIT/Directed/StructABI/StructABI.c b/src/tests/JIT/Directed/StructABI/StructABI.c index 959ca9afda52d0..77d8d1ee8da156 100644 --- a/src/tests/JIT/Directed/StructABI/StructABI.c +++ b/src/tests/JIT/Directed/StructABI/StructABI.c @@ -221,6 +221,49 @@ struct Nested9 struct InlineArray4 Field2; }; +struct Issue80393_S_Doubles +{ + double f1; + double f3; +}; + +// We need to apply 1-byte packing to these structs to get the exact alignment we want, but we +// don't want to apply packing to the union or 2-doubles struct because it will change the natural +// alignment of the union and as a result alter which registers it's assigned to by clang, which +// won't match what CoreCLR does. +#pragma pack(push, 1) +struct Issue80393_F2 +{ + double value; +}; + +struct Issue80393_F2_Offset { + // 3 padding bytes to approximate C# FieldOffset of 3. + // This padding prevents the outer union from being treated as an HVA/HFA by clang for either arm32 or arm64. + char padding[3]; + struct Issue80393_F2 F2; +}; +#pragma pack(pop) + +union Issue80393_S { + struct Issue80393_S_Doubles f1_f3; + struct Issue80393_F2_Offset f2; +}; + +// NOTE: If investigating this in isolation, make sure you set -mfloat-abi=hard -mfpu=neon when building for arm32 +DLLEXPORT union Issue80393_S Issue80393_HFA(union Issue80393_S value) +{ + // Simply doing 'return value' like most of these other functions isn't enough to exercise everything, because + // depending on the calling convention it can turn the whole function into a no-op, where 'value' flows in + // via the same registers that the result flows out through. + union Issue80393_S result; + // Use the value argument as part of the result so we can tell whether it was passed in correctly, in addition + // to checking whether the return value was passed correctly back to C#. + result.f1_f3.f1 = 1.0 + value.f1_f3.f1; + result.f1_f3.f3 = 3.0 + value.f1_f3.f3; + return result; +} + DLLEXPORT struct SingleByte EchoSingleByte(struct SingleByte value) { return value; diff --git a/src/tests/JIT/Directed/StructABI/StructABI.cs b/src/tests/JIT/Directed/StructABI/StructABI.cs index 2f74d49e75853f..1f15db541ed664 100644 --- a/src/tests/JIT/Directed/StructABI/StructABI.cs +++ b/src/tests/JIT/Directed/StructABI/StructABI.cs @@ -668,8 +668,25 @@ public bool Equals(Nested9 other) } } +struct Issue80393_F2 +{ + public double value; +} + +[StructLayout(LayoutKind.Explicit)] +struct Issue80393_S +{ + [FieldOffset(0)] public double f1; + // This FieldOffset of 3 causes this struct to no longer be a HVA or HFA according to ARM32 or ARM64 ABI + [FieldOffset(3)] public Issue80393_F2 f2; + [FieldOffset(8)] public double f3; +} + public static partial class StructABI { + [DllImport("StructABILib")] + static extern Issue80393_S Issue80393_HFA(Issue80393_S value); + [DllImport("StructABILib")] static extern SingleByte EchoSingleByte(SingleByte value); @@ -1075,7 +1092,7 @@ static bool EchoSingleByteWrapper() SingleByte expectedSingleByte = SingleByte.Get(); SingleByte nativeSingleByte = EchoSingleByte(expectedSingleByte); SingleByte managedSingleByte = EchoSingleByteManaged(expectedSingleByte); - + if (!expectedSingleByte.Equals(nativeSingleByte)) { Console.WriteLine("Native call for EchoSingleByte failed"); @@ -1093,7 +1110,7 @@ static bool EchoSingleByteWrapper() nativeSingleByte = EchoSingleByte(expectedSingleByte2); managedSingleByte = EchoSingleByteManaged(expectedSingleByte2); - + if (!expectedSingleByte2.Equals(nativeSingleByte)) { Console.WriteLine("Native call for EchoSingleByte failed"); @@ -1115,7 +1132,7 @@ static bool EchoSingleLongWrapper() SingleLong expectedSingleLong = SingleLong.Get(); SingleLong nativeSingleLong = EchoSingleLong(expectedSingleLong); SingleLong managedSingleLong = EchoSingleLongManaged(expectedSingleLong); - + if (!expectedSingleLong.Equals(nativeSingleLong)) { Console.WriteLine("Native call for EchoSingleLong failed"); @@ -1133,7 +1150,7 @@ static bool EchoSingleLongWrapper() nativeSingleLong = EchoSingleLong(expectedSingleLong2); managedSingleLong = EchoSingleLongManaged(expectedSingleLong2); - + if (!expectedSingleLong2.Equals(nativeSingleLong)) { Console.WriteLine("Native call for EchoSingleByte failed"); @@ -1155,7 +1172,7 @@ static bool EchoSingleFloatWrapper() SingleFloat expectedSingleFloat = SingleFloat.Get(); SingleFloat nativeSingleFloat = EchoSingleFloat(expectedSingleFloat); SingleFloat managedSingleFloat = EchoSingleFloatManaged(expectedSingleFloat); - + if (!expectedSingleFloat.Equals(nativeSingleFloat)) { Console.WriteLine("Native call for EchoSingleFloat failed"); @@ -1173,7 +1190,7 @@ static bool EchoSingleFloatWrapper() nativeSingleFloat = EchoSingleFloat(expectedSingleFloat2); managedSingleFloat = EchoSingleFloatManaged(expectedSingleFloat2); - + if (!expectedSingleFloat2.Equals(nativeSingleFloat)) { Console.WriteLine("Native call for EchoSingleFloat failed"); @@ -1195,7 +1212,7 @@ static bool EchoSingleDoubleWrapper() SingleDouble expectedSingleDouble = SingleDouble.Get(); SingleDouble nativeSingleDouble = EchoSingleDouble(expectedSingleDouble); SingleDouble managedSingleDouble = EchoSingleDoubleManaged(expectedSingleDouble); - + if (!expectedSingleDouble.Equals(nativeSingleDouble)) { Console.WriteLine("Native call for EchoSingleDouble failed"); @@ -1213,7 +1230,7 @@ static bool EchoSingleDoubleWrapper() nativeSingleDouble = EchoSingleDouble(expectedSingleDouble2); managedSingleDouble = EchoSingleDoubleManaged(expectedSingleDouble2); - + if (!expectedSingleDouble2.Equals(nativeSingleDouble)) { Console.WriteLine("Native call for EchoSingleDouble failed"); @@ -1235,7 +1252,7 @@ static bool EchoByteAndFloatWrapper() ByteAndFloat expectedByteAndFloat = ByteAndFloat.Get(); ByteAndFloat nativeByteAndFloat = EchoByteAndFloat(expectedByteAndFloat); ByteAndFloat managedByteAndFloat = EchoByteAndFloatManaged(expectedByteAndFloat); - + if (!expectedByteAndFloat.Equals(nativeByteAndFloat)) { Console.WriteLine("Native call for EchoByteAndFloat failed"); @@ -1254,7 +1271,7 @@ static bool EchoByteAndFloatWrapper() nativeByteAndFloat = EchoByteAndFloat(expectedByteAndFloat2); managedByteAndFloat = EchoByteAndFloatManaged(expectedByteAndFloat2); - + if (!expectedByteAndFloat2.Equals(nativeByteAndFloat)) { Console.WriteLine("Native call for EchoByteAndFloat failed"); @@ -1276,7 +1293,7 @@ static bool EchoLongAndFloatWrapper() LongAndFloat expectedLongAndFloat = LongAndFloat.Get(); LongAndFloat nativeLongAndFloat = EchoLongAndFloat(expectedLongAndFloat); LongAndFloat managedLongAndFloat = EchoLongAndFloatManaged(expectedLongAndFloat); - + if (!expectedLongAndFloat.Equals(nativeLongAndFloat)) { Console.WriteLine("Native call for EchoLongAndFloat failed"); @@ -1295,7 +1312,7 @@ static bool EchoLongAndFloatWrapper() nativeLongAndFloat = EchoLongAndFloat(expectedLongAndFloat2); managedLongAndFloat = EchoLongAndFloatManaged(expectedLongAndFloat2); - + if (!expectedLongAndFloat2.Equals(nativeLongAndFloat)) { Console.WriteLine("Native call for EchoLongAndFloat failed"); @@ -1317,7 +1334,7 @@ static bool EchoByteAndDoubleWrapper() ByteAndDouble expectedByteAndDouble = ByteAndDouble.Get(); ByteAndDouble nativeByteAndDouble = EchoByteAndDouble(expectedByteAndDouble); ByteAndDouble managedByteAndDouble = EchoByteAndDoubleManaged(expectedByteAndDouble); - + if (!expectedByteAndDouble.Equals(nativeByteAndDouble)) { Console.WriteLine("Native call for EchoByteAndDouble failed"); @@ -1336,7 +1353,7 @@ static bool EchoByteAndDoubleWrapper() nativeByteAndDouble = EchoByteAndDouble(expectedByteAndDouble2); managedByteAndDouble = EchoByteAndDoubleManaged(expectedByteAndDouble2); - + if (!expectedByteAndDouble2.Equals(nativeByteAndDouble)) { Console.WriteLine("Native call for EchoByteAndDouble failed"); @@ -1358,7 +1375,7 @@ static bool EchoDoubleAndByteWrapper() DoubleAndByte expectedDoubleAndByte = DoubleAndByte.Get(); DoubleAndByte nativeDoubleAndByte = EchoDoubleAndByte(expectedDoubleAndByte); DoubleAndByte managedDoubleAndByte = EchoDoubleAndByteManaged(expectedDoubleAndByte); - + if (!expectedDoubleAndByte.Equals(nativeDoubleAndByte)) { Console.WriteLine("Native call for EchoDoubleAndByte failed"); @@ -1380,7 +1397,7 @@ static bool EchoPointerAndByteWrapper() PointerAndByte expectedPointerAndByte = PointerAndByte.Get(); PointerAndByte nativePointerAndByte = EchoPointerAndByte(expectedPointerAndByte); PointerAndByte managedPointerAndByte = EchoPointerAndByteManaged(expectedPointerAndByte); - + if (!expectedPointerAndByte.Equals(nativePointerAndByte)) { Console.WriteLine("Native call for EchoPointerAndByte failed"); @@ -1402,7 +1419,7 @@ static bool EchoByteAndPointerWrapper() ByteAndPointer expectedByteAndPointer = ByteAndPointer.Get(); ByteAndPointer nativeByteAndPointer = EchoByteAndPointer(expectedByteAndPointer); ByteAndPointer managedByteAndPointer = EchoByteAndPointerManaged(expectedByteAndPointer); - + if (!expectedByteAndPointer.Equals(nativeByteAndPointer)) { Console.WriteLine("Native call for EchoByteAndPointer failed"); @@ -1424,7 +1441,7 @@ static bool EchoByteFloatAndPointerWrapper() ByteFloatAndPointer expectedByteFloatAndPointer = ByteFloatAndPointer.Get(); ByteFloatAndPointer nativeByteFloatAndPointer = EchoByteFloatAndPointer(expectedByteFloatAndPointer); ByteFloatAndPointer managedByteFloatAndPointer = EchoByteFloatAndPointerManaged(expectedByteFloatAndPointer); - + if (!expectedByteFloatAndPointer.Equals(nativeByteFloatAndPointer)) { Console.WriteLine("Native call for EchoByteFloatAndPointer failed"); @@ -1446,7 +1463,7 @@ static bool EchoPointerFloatAndByteWrapper() PointerFloatAndByte expectedPointerFloatAndByte = PointerFloatAndByte.Get(); PointerFloatAndByte nativePointerFloatAndByte = EchoPointerFloatAndByte(expectedPointerFloatAndByte); PointerFloatAndByte managedPointerFloatAndByte = EchoPointerFloatAndByteManaged(expectedPointerFloatAndByte); - + if (!expectedPointerFloatAndByte.Equals(nativePointerFloatAndByte)) { Console.WriteLine("Native call for EchoPointerFloatAndByte failed"); @@ -1468,7 +1485,7 @@ static bool EchoShortIntFloatIntPtrWrapper() ShortIntFloatIntPtr expectedShortIntFloatIntPtr = ShortIntFloatIntPtr.Get(); ShortIntFloatIntPtr nativeShortIntFloatIntPtr = EchoShortIntFloatIntPtr(expectedShortIntFloatIntPtr); ShortIntFloatIntPtr managedShortIntFloatIntPtr = EchoShortIntFloatIntPtrManaged(expectedShortIntFloatIntPtr); - + if (!expectedShortIntFloatIntPtr.Equals(nativeShortIntFloatIntPtr)) { Console.WriteLine("Native call for EchoShortIntFloatIntPtr failed"); @@ -1490,7 +1507,7 @@ static bool EchoTwoLongsWrapper() TwoLongs expectedTwoLongs = TwoLongs.Get(); TwoLongs nativeTwoLongs = EchoTwoLongs(expectedTwoLongs); TwoLongs managedTwoLongs = EchoTwoLongsManaged(expectedTwoLongs); - + if (!expectedTwoLongs.Equals(nativeTwoLongs)) { Console.WriteLine("Native call for EchoTwoLongs failed"); @@ -1512,7 +1529,7 @@ static bool EchoTwoFloatsWrapper() TwoFloats expectedTwoFloats = TwoFloats.Get(); TwoFloats nativeTwoFloats = EchoTwoFloats(expectedTwoFloats); TwoFloats managedTwoFloats = EchoTwoFloatsManaged(expectedTwoFloats); - + if (!expectedTwoFloats.Equals(nativeTwoFloats)) { Console.WriteLine("Native call for EchoTwoFloats failed"); @@ -1534,7 +1551,7 @@ static bool EchoTwoDoublesWrapper() TwoDoubles expectedTwoDoubles = TwoDoubles.Get(); TwoDoubles nativeTwoDoubles = EchoTwoDoubles(expectedTwoDoubles); TwoDoubles managedTwoDoubles = EchoTwoDoublesManaged(expectedTwoDoubles); - + if (!expectedTwoDoubles.Equals(nativeTwoDoubles)) { Console.WriteLine("Native call for EchoTwoDoubles failed"); @@ -1556,7 +1573,7 @@ static bool EchoFourLongsWrapper() FourLongs expectedFourLongs = FourLongs.Get(); FourLongs nativeFourLongs = EchoFourLongs(expectedFourLongs); FourLongs managedFourLongs = EchoFourLongsManaged(expectedFourLongs); - + if (!expectedFourLongs.Equals(nativeFourLongs)) { Console.WriteLine("Native call for EchoFourLongs failed"); @@ -1578,7 +1595,7 @@ static bool EchoFourDoublesWrapper() FourDoubles expectedFourDoubles = FourDoubles.Get(); FourDoubles nativeFourDoubles = EchoFourDoubles(expectedFourDoubles); FourDoubles managedFourDoubles = EchoFourDoublesManaged(expectedFourDoubles); - + if (!expectedFourDoubles.Equals(nativeFourDoubles)) { Console.WriteLine("Native call for EchoFourDoubles failed"); @@ -1600,7 +1617,7 @@ static bool EchoInlineArray1Wrapper() InlineArray1 expectedInlineArray1 = InlineArray1.Get(); InlineArray1 nativeInlineArray1 = EchoInlineArray1(expectedInlineArray1); InlineArray1 managedInlineArray1 = EchoInlineArray1Managed(expectedInlineArray1); - + if (!expectedInlineArray1.Equals(nativeInlineArray1)) { Console.WriteLine("Native call for EchoInlineArray1 failed"); @@ -1622,7 +1639,7 @@ static bool EchoInlineArray2Wrapper() InlineArray2 expectedInlineArray2 = InlineArray2.Get(); InlineArray2 nativeInlineArray2 = EchoInlineArray2(expectedInlineArray2); InlineArray2 managedInlineArray2 = EchoInlineArray2Managed(expectedInlineArray2); - + if (!expectedInlineArray2.Equals(nativeInlineArray2)) { Console.WriteLine("Native call for EchoInlineArray2 failed"); @@ -1644,7 +1661,7 @@ static bool EchoInlineArray3Wrapper() InlineArray3 expectedInlineArray3 = InlineArray3.Get(); InlineArray3 nativeInlineArray3 = EchoInlineArray3(expectedInlineArray3); InlineArray3 managedInlineArray3 = EchoInlineArray3Managed(expectedInlineArray3); - + if (!expectedInlineArray3.Equals(nativeInlineArray3)) { Console.WriteLine("Native call for EchoInlineArray3 failed"); @@ -1666,7 +1683,7 @@ static bool EchoInlineArray4Wrapper() InlineArray4 expectedInlineArray4 = InlineArray4.Get(); InlineArray4 nativeInlineArray4 = EchoInlineArray4(expectedInlineArray4); InlineArray4 managedInlineArray4 = EchoInlineArray4Managed(expectedInlineArray4); - + if (!expectedInlineArray4.Equals(nativeInlineArray4)) { Console.WriteLine("Native call for EchoInlineArray4 failed"); @@ -1688,7 +1705,7 @@ static bool EchoInlineArray5Wrapper() InlineArray5 expectedInlineArray5 = InlineArray5.Get(); InlineArray5 nativeInlineArray5 = EchoInlineArray5(expectedInlineArray5); InlineArray5 managedInlineArray5 = EchoInlineArray5Managed(expectedInlineArray5); - + if (!expectedInlineArray5.Equals(nativeInlineArray5)) { Console.WriteLine("Native call for EchoInlineArray5 failed"); @@ -1710,7 +1727,7 @@ static bool EchoInlineArray6Wrapper() InlineArray6 expectedInlineArray6 = InlineArray6.Get(); InlineArray6 nativeInlineArray6 = EchoInlineArray6(expectedInlineArray6); InlineArray6 managedInlineArray6 = EchoInlineArray6Managed(expectedInlineArray6); - + if (!expectedInlineArray6.Equals(nativeInlineArray6)) { Console.WriteLine("Native call for EchoInlineArray6 failed"); @@ -1732,7 +1749,7 @@ static bool EchoNested1Wrapper() Nested1 expectedNested1 = Nested1.Get(); Nested1 nativeNested1 = EchoNested1(expectedNested1); Nested1 managedNested1 = EchoNested1Managed(expectedNested1); - + if (!expectedNested1.Equals(nativeNested1)) { Console.WriteLine("Native call for EchoNested1 failed"); @@ -1754,7 +1771,7 @@ static bool EchoNested2Wrapper() Nested2 expectedNested2 = Nested2.Get(); Nested2 nativeNested2 = EchoNested2(expectedNested2); Nested2 managedNested2 = EchoNested2Managed(expectedNested2); - + if (!expectedNested2.Equals(nativeNested2)) { Console.WriteLine("Native call for EchoNested2 failed"); @@ -1776,7 +1793,7 @@ static bool EchoNested3Wrapper() Nested3 expectedNested3 = Nested3.Get(); Nested3 nativeNested3 = EchoNested3(expectedNested3); Nested3 managedNested3 = EchoNested3Managed(expectedNested3); - + if (!expectedNested3.Equals(nativeNested3)) { Console.WriteLine("Native call for EchoNested3 failed"); @@ -1798,7 +1815,7 @@ static bool EchoNested4Wrapper() Nested4 expectedNested4 = Nested4.Get(); Nested4 nativeNested4 = EchoNested4(expectedNested4); Nested4 managedNested4 = EchoNested4Managed(expectedNested4); - + if (!expectedNested4.Equals(nativeNested4)) { Console.WriteLine("Native call for EchoNested4 failed"); @@ -1820,7 +1837,7 @@ static bool EchoNested5Wrapper() Nested5 expectedNested5 = Nested5.Get(); Nested5 nativeNested5 = EchoNested5(expectedNested5); Nested5 managedNested5 = EchoNested5Managed(expectedNested5); - + if (!expectedNested5.Equals(nativeNested5)) { Console.WriteLine("Native call for EchoNested5 failed"); @@ -1842,7 +1859,7 @@ static bool EchoNested6Wrapper() Nested6 expectedNested6 = Nested6.Get(); Nested6 nativeNested6 = EchoNested6(expectedNested6); Nested6 managedNested6 = EchoNested6Managed(expectedNested6); - + if (!expectedNested6.Equals(nativeNested6)) { Console.WriteLine("Native call for EchoNested6 failed"); @@ -1864,7 +1881,7 @@ static bool EchoNested7Wrapper() Nested7 expectedNested7 = Nested7.Get(); Nested7 nativeNested7 = EchoNested7(expectedNested7); Nested7 managedNested7 = EchoNested7Managed(expectedNested7); - + if (!expectedNested7.Equals(nativeNested7)) { Console.WriteLine("Native call for EchoNested7 failed"); @@ -1886,7 +1903,7 @@ static bool EchoNested8Wrapper() Nested8 expectedNested8 = Nested8.Get(); Nested8 nativeNested8 = EchoNested8(expectedNested8); Nested8 managedNested8 = EchoNested8Managed(expectedNested8); - + if (!expectedNested8.Equals(nativeNested8)) { Console.WriteLine("Native call for EchoNested8 failed"); @@ -1908,7 +1925,7 @@ static bool EchoNested9Wrapper() Nested9 expectedNested9 = Nested9.Get(); Nested9 nativeNested9 = EchoNested9(expectedNested9); Nested9 managedNested9 = EchoNested9Managed(expectedNested9); - + if (!expectedNested9.Equals(nativeNested9)) { Console.WriteLine("Native call for EchoNested9 failed"); @@ -1973,7 +1990,7 @@ static bool NotEnoughRegistersSysV2Wrapper() static bool NotEnoughRegistersSysV3Wrapper() { bool ok = true; - + DoubleAndByte expectedNotEnoughRegistersSysV3 = DoubleAndByte.Get(); DoubleAndByte nativeNotEnoughRegistersSysV3 = NotEnoughRegistersSysV3(1, 2, 3, 4, 5, 6, expectedNotEnoughRegistersSysV3); DoubleAndByte managedNotEnoughRegistersSysV3 = NotEnoughRegistersSysV3Managed(1, 2, 3, 4, 5, 6, expectedNotEnoughRegistersSysV3); @@ -2042,7 +2059,7 @@ static bool NotEnoughRegistersSysV5Wrapper() static bool NotEnoughRegistersSysV6Wrapper() { bool ok = true; - + DoubleAndByte expectedNotEnoughRegistersSysV6 = DoubleAndByte.Get(); DoubleAndByte nativeNotEnoughRegistersSysV6 = NotEnoughRegistersSysV6(1.0d, 2.0d, 3.0d, 4.0d, 5.0d, 6.0d, 7.0d, 8.0d, expectedNotEnoughRegistersSysV6); DoubleAndByte managedNotEnoughRegistersSysV6 = NotEnoughRegistersSysV6Managed(1.0d, 2.0d, 3.0d, 4.0d, 5.0d, 6.0d, 7.0d, 8.0d, expectedNotEnoughRegistersSysV6); @@ -2154,11 +2171,27 @@ static bool EnoughRegistersSysV4Wrapper() return ok; } + static bool Issue80393Wrapper() + { + bool ok = true; + Issue80393_S s = default; + s.f1 = 1.0d; + s.f3 = 1.0d; + Issue80393_S ret = Issue80393_HFA(s); + + if (!ret.f1.Equals(2.0d) || !ret.f3.Equals(4.0d)) { + Console.WriteLine($"Issue80393_HFA failed. Retval: f1={ret.f1} f3={ret.f3}"); + ok = false; + } + + return ok; + } + [Fact] public static int TestEntryPoint() { var ok = true; - + if (!EchoSingleByteWrapper()) ok = false; if (!EchoSingleLongWrapper()) ok = false; if (!EchoSingleFloatWrapper()) ok = false; @@ -2202,7 +2235,8 @@ public static int TestEntryPoint() if (!EnoughRegistersSysV2Wrapper()) ok = false; if (!EnoughRegistersSysV3Wrapper()) ok = false; if (!EnoughRegistersSysV4Wrapper()) ok = false; - + if (!Issue80393Wrapper()) ok = false; + return ok ? 100 : -1; } } diff --git a/src/tests/JIT/Directed/lifetime/lifetime2.cs b/src/tests/JIT/Directed/lifetime/lifetime2.cs deleted file mode 100644 index 1567dbd3210ddb..00000000000000 --- a/src/tests/JIT/Directed/lifetime/lifetime2.cs +++ /dev/null @@ -1,212 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// - -// Testing JIT handling and GC reporting of liveness of GC variable - -using System; -using System.Collections.Generic; -using Xunit; - -public class Test_lifetime2 -{ - public static int aExists; - public static int bExists; - private abstract class A - { - } - private class B : A - { - public B() - { - aExists++; - } - ~B() - { - aExists--; - Console.WriteLine("~B"); - } - - public void F() - { - Console.WriteLine("B.F"); - } - } - private class C : B - { - public C() - { - bExists++; - } - ~C() - { - bExists--; - Console.WriteLine("~C"); - } - - public void G() - { - Console.WriteLine("C.G"); - } - } - private static int f1() - { - B a = new B(); - a.F(); - - Console.WriteLine(); - Console.WriteLine("testcase f1-1"); - if (aExists != 1) - { - Console.WriteLine("f1-1 failed"); - return -1; - } - - GC.KeepAlive(a); - a = null; - GC.Collect(); - GC.WaitForPendingFinalizers(); - - Console.WriteLine(); - Console.WriteLine("testcase f1-2"); - if (aExists != 0) - { - Console.WriteLine("f1-2 failed"); - return -1; - } - - C b = new C(); - b.G(); - - Console.WriteLine(); - Console.WriteLine("testcase f1-3"); - if ((aExists != 1) || (bExists != 1)) - { - Console.WriteLine("f1-3 failed"); - return -1; - } - - GC.KeepAlive(b); - b = null; - GC.Collect(); - GC.WaitForPendingFinalizers(); - - Console.WriteLine(); - Console.WriteLine("testcase f1-4"); - if ((aExists != 0) || (bExists != 0)) - { - Console.WriteLine("f1-4 failed"); - return -1; - } - return 100; - } - private static int f2() - { - B a = new B(); - { - C b = new C(); - b.G(); - b = null; - } - GC.Collect(); - GC.WaitForPendingFinalizers(); - - a.F(); - Console.WriteLine(); - Console.WriteLine("testcase f2-1"); - if ((aExists != 1) || (bExists != 0)) - { - Console.WriteLine("f2-1 failed"); - return -1; - } - - GC.KeepAlive(a); - a = null; - GC.Collect(); - GC.WaitForPendingFinalizers(); - Console.WriteLine(); - Console.WriteLine("testcase f2-2"); - if (aExists != 0) - { - Console.WriteLine("f2-2 failed"); - return -1; - } - return 100; - } - private static int f3() - { - C b = new C(); - b = null; - GC.Collect(); - GC.WaitForPendingFinalizers(); - Console.WriteLine(); - Console.WriteLine("testcase f3"); - if (aExists != 0) - { - Console.WriteLine("f3 failed"); - return -1; - } - b = null; - return 100; - } - private static int f4() - { - B a = new B(); - a.F(); - C b = new C(); - b.G(); - - Console.WriteLine(); - Console.WriteLine("testcase f4"); - if ((aExists != 2) || (bExists != 1)) - { - Console.WriteLine("f4 failed"); - return -1; - } - - GC.KeepAlive(a); - GC.KeepAlive(b); - return 100; - } - - private static int f5() - { - Console.WriteLine(); - Console.WriteLine("testcase f5"); - if ((aExists != 0) || (bExists != 0)) - { - Console.WriteLine("f5 failed"); - return -1; - } - return 100; - } - - [Fact] - public static int TestEntryPoint() - { - if (f1() != 100) - return -1; - CleanGC(); - if (f2() != 100) - return -1; - CleanGC(); - if (f3() != 100) - return -1; - CleanGC(); - if (f4() != 100) - return -1; - CleanGC(); - if (f5() != 100) - return -1; - CleanGC(); - - Console.WriteLine("PASSED"); - return 100; - } - - private static void CleanGC() - { - GC.Collect(); - GC.WaitForPendingFinalizers(); - } -} diff --git a/src/tests/JIT/Directed/lifetime/lifetime2.csproj b/src/tests/JIT/Directed/lifetime/lifetime2.csproj deleted file mode 100644 index 0e79bac317c9b6..00000000000000 --- a/src/tests/JIT/Directed/lifetime/lifetime2.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - - true - - 1 - - - None - True - True - true - - - - - diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Directory.Build.targets b/src/tests/JIT/HardwareIntrinsics/Arm/Directory.Build.targets index eca47c9c796adc..4db5737b9632bf 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Directory.Build.targets +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Directory.Build.targets @@ -9,7 +9,7 @@ diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 113cf09a85a2be..ab0388d112bb92 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -29,10556 +29,7509 @@ public static Vector InitVector(Func f) return new Vector(arr); } - public static byte[] CreateMaskForFirstActiveElement(byte[] mask, byte[] srcMask) + public static T[] CreateMaskForFirstActiveElement(T[] mask, T[] srcMask) + where T : unmanaged, IBinaryInteger { - var count = srcMask.Length; - var result = new byte[count]; - Array.Copy(srcMask, 0, result, 0, count); - for (var i = 0; i < count; i++) + int count = srcMask.Length; + T[] result = new T[count]; + Array.Copy(srcMask, result, count); + + for (int i = 0; i < count; i++) { - if (mask[i] != 0) + if (mask[i] != T.Zero) { - result[i] = 1; + result[i] = T.One; return result; } } + return result; } - public static short[] CreateMaskForFirstActiveElement(short[] mask, short[] srcMask) + public static int LastActiveElement(T[] v) where T : INumber { - var count = srcMask.Length; - var result = new short[count]; - Array.Copy(srcMask, 0, result, 0, count); - for (var i = 0; i < count; i++) + for (int i = v.Length - 1; i >= 0; i--) { - if (mask[i] != 0) + if (v[i] != T.Zero) { - result[i] = 1; - return result; + return i; } } - return result; + return -1; } - public static int[] CreateMaskForFirstActiveElement(int[] mask, int[] srcMask) + public static T[] CreateMaskForNextActiveElement(T[] mask, T[] srcMask) where T : INumber { - var count = srcMask.Length; - var result = new int[count]; - Array.Copy(srcMask, 0, result, 0, count); - for (var i = 0; i < count; i++) + int count = srcMask.Length; + T[] result = new T[count]; + int start = LastActiveElement(srcMask) + 1; + + for (int i = start; i < count; i++) { - if (mask[i] != 0) + if (mask[i] != T.Zero) { - result[i] = 1; + result[i] = T.One; return result; } } + return result; } - public static long[] CreateMaskForFirstActiveElement(long[] mask, long[] srcMask) + public static T CountLeadingSignBits(T value) + where T : unmanaged, + INumber, + IBitwiseOperators, + IShiftOperators { - var count = srcMask.Length; - var result = new long[count]; - Array.Copy(srcMask, 0, result, 0, count); - for (var i = 0; i < count; i++) - { - if (mask[i] != 0) - { - result[i] = 1; - return result; - } - } - return result; + T shifted = value >> 1; + T xor = value ^ shifted; + + return CountLeadingZeroBits(xor) - T.One; } - public static sbyte[] CreateMaskForFirstActiveElement(sbyte[] mask, sbyte[] srcMask) + public static unsafe T CountLeadingZeroBits(T value) + where T : unmanaged, INumber, IBitwiseOperators { - var count = srcMask.Length; - var result = new sbyte[count]; - Array.Copy(srcMask, 0, result, 0, count); - for (var i = 0; i < count; i++) - { - if (mask[i] != 0) - { - result[i] = 1; - return result; - } - } - return result; + int bitSize = sizeof(T) * 8; + int highest = HighestSetBit(value); + + return T.CreateChecked(bitSize - (highest + 1)); } - public static ushort[] CreateMaskForFirstActiveElement(ushort[] mask, ushort[] srcMask) + public static unsafe int HighestSetBit(T value) + where T : unmanaged, INumber, IBitwiseOperators { - var count = srcMask.Length; - var result = new ushort[count]; - Array.Copy(srcMask, 0, result, 0, count); - for (var i = 0; i < count; i++) + ulong v = Convert.ToUInt64(value); + + for (int i = sizeof(T) * 8 - 1; i >= 0; i--) { - if (mask[i] != 0) + if ((v & (1UL << i)) != 0) { - result[i] = 1; - return result; + return i; } } - return result; + + return -1; } - public static uint[] CreateMaskForFirstActiveElement(uint[] mask, uint[] srcMask) + public static T BitCount(T value) + where T : unmanaged, INumber, IBitwiseOperators { - var count = srcMask.Length; - var result = new uint[count]; - Array.Copy(srcMask, 0, result, 0, count); - for (var i = 0; i < count; i++) + ulong bits = Convert.ToUInt64(value); + int count = 0; + + for (int i = 0; i < sizeof(ulong) * 8; i++) { - if (mask[i] != 0) - { - result[i] = 1; - return result; - } + if ((bits & (1UL << i)) != 0) + count++; } - return result; + + return T.CreateChecked(count); } + public static int BitCount(float op1) => BitCount(BitConverter.SingleToInt32Bits(op1)); + + public static long BitCount(double op1) => BitCount(BitConverter.DoubleToInt64Bits(op1)); - public static ulong[] CreateMaskForFirstActiveElement(ulong[] mask, ulong[] srcMask) + + public static T ReverseElementBits(T value) + where T : unmanaged, + INumber, + IBitwiseOperators, + IShiftOperators, + IComparisonOperators { - var count = srcMask.Length; - var result = new ulong[count]; - Array.Copy(srcMask, 0, result, 0, count); - for (var i = 0; i < count; i++) + T result = T.Zero; + T one = T.One; + int bitSize = Unsafe.SizeOf() * 8; + + for (int i = 0; i < bitSize; i++) { - if (mask[i] != 0) + if ((value & (one << i)) != T.Zero) { - result[i] = 1; - return result; + result |= (one << (bitSize - 1 - i)); } } + return result; } - public static int LastActiveElement(byte[] v) + public static T And(T op1, T op2) + where T : unmanaged, IBitwiseOperators + => op1 & op2; + + public static T BitwiseClear(T op1, T op2) + where T : unmanaged, IBitwiseOperators + => op1 & ~op2; + + public static T BitwiseSelect(T op1, T op2, T op3) + where T : unmanaged, + INumber, + IBitwiseOperators, + IShiftOperators, + IComparisonOperators { - for (var i = v.Length - 1; i >= 0; i--) + T result = T.Zero; + T one = T.One; + int bitSize = Unsafe.SizeOf() * 8; + + for (int i = 0; i < bitSize; i++) { - if (v[i] != 0) - { - return i; - } + T bit = one << i; + result |= ((op1 & bit) != T.Zero) + ? (op2 & bit) + : (op3 & bit); } - return -1; + + return result; } - public static int LastActiveElement(sbyte[] v) + public static T Not(T op1) + where T : unmanaged, IBitwiseOperators + => ~op1; + + public static T Or(T op1, T op2) + where T : unmanaged, IBitwiseOperators + => op1 | op2; + + public static T OrNot(T op1, T op2) + where T : unmanaged, IBitwiseOperators + => op1 | ~op2; + + public static T Xor(T op1, T op2) + where T : unmanaged, IBitwiseOperators + => op1 ^ op2; + + public static float And(float op1, float op2) => BitConverter.Int32BitsToSingle(And(BitConverter.SingleToInt32Bits(op1), BitConverter.SingleToInt32Bits(op2))); + + public static double And(double op1, double op2) => BitConverter.Int64BitsToDouble(And(BitConverter.DoubleToInt64Bits(op1), BitConverter.DoubleToInt64Bits(op2))); + + public static float BitwiseClear(float op1, float op2) => BitConverter.Int32BitsToSingle(BitwiseClear(BitConverter.SingleToInt32Bits(op1), BitConverter.SingleToInt32Bits(op2))); + + public static double BitwiseClear(double op1, double op2) => BitConverter.Int64BitsToDouble(BitwiseClear(BitConverter.DoubleToInt64Bits(op1), BitConverter.DoubleToInt64Bits(op2))); + + public static float BitwiseSelect(float op1, float op2, float op3) => BitConverter.Int32BitsToSingle(BitwiseSelect(BitConverter.SingleToInt32Bits(op1), BitConverter.SingleToInt32Bits(op2), BitConverter.SingleToInt32Bits(op3))); + + public static double BitwiseSelect(double op1, double op2, double op3) => BitConverter.Int64BitsToDouble(BitwiseSelect(BitConverter.DoubleToInt64Bits(op1), BitConverter.DoubleToInt64Bits(op2), BitConverter.DoubleToInt64Bits(op3))); + + public static float Not(float op1) => BitConverter.Int32BitsToSingle(~BitConverter.SingleToInt32Bits(op1)); + + public static double Not(double op1) => BitConverter.Int64BitsToDouble(~BitConverter.DoubleToInt64Bits(op1)); + + public static float Or(float op1, float op2) => BitConverter.Int32BitsToSingle(Or(BitConverter.SingleToInt32Bits(op1), BitConverter.SingleToInt32Bits(op2))); + + public static double Or(double op1, double op2) => BitConverter.Int64BitsToDouble(Or(BitConverter.DoubleToInt64Bits(op1), BitConverter.DoubleToInt64Bits(op2))); + + public static float OrNot(float op1, float op2) => BitConverter.Int32BitsToSingle(OrNot(BitConverter.SingleToInt32Bits(op1), BitConverter.SingleToInt32Bits(op2))); + + public static double OrNot(double op1, double op2) => BitConverter.Int64BitsToDouble(OrNot(BitConverter.DoubleToInt64Bits(op1), BitConverter.DoubleToInt64Bits(op2))); + + public static float Xor(float op1, float op2) => BitConverter.Int32BitsToSingle(Xor(BitConverter.SingleToInt32Bits(op1), BitConverter.SingleToInt32Bits(op2))); + + public static double Xor(double op1, double op2) => BitConverter.Int64BitsToDouble(Xor(BitConverter.DoubleToInt64Bits(op1), BitConverter.DoubleToInt64Bits(op2))); + + public static T CompareEqual(T left, T right) + where T : unmanaged, IBinaryNumber + => left == right ? T.AllBitsSet : T.Zero; + + public static T CompareGreaterThan(T left, T right) + where T : unmanaged, IBinaryNumber + => left > right ? T.AllBitsSet : T.Zero; + + public static T CompareGreaterThanOrEqual(T left, T right) + where T : unmanaged, IBinaryNumber + => left >= right ? T.AllBitsSet : T.Zero; + + public static T CompareLessThan(T left, T right) + where T : unmanaged, IBinaryNumber + => left < right ? T.AllBitsSet : T.Zero; + + public static T CompareLessThanOrEqual(T left, T right) + where T : unmanaged, IBinaryNumber + => left <= right ? T.AllBitsSet : T.Zero; + + public static T CompareTest(T left, T right) + where T : unmanaged, IBinaryNumber + => (left & right) != T.Zero ? T.AllBitsSet : T.Zero; + + public static double CompareEqual(double left, double right) { - for (var i = v.Length - 1; i >= 0; i--) + long result = 0; + + if (left == right) { - if (v[i] != 0) - { - return i; - } + result = -1; } - return -1; + + return BitConverter.Int64BitsToDouble(result); } - public static int LastActiveElement(short[] v) + public static float CompareEqual(float left, float right) { - for (var i = v.Length - 1; i >= 0; i--) + int result = 0; + + if (left == right) { - if (v[i] != 0) - { - return i; - } + result = -1; } - return -1; + + return BitConverter.Int32BitsToSingle(result); } - public static int LastActiveElement(ushort[] v) + public static double CompareGreaterThan(double left, double right) { - for (var i = v.Length - 1; i >= 0; i--) + long result = 0; + + if (left > right) { - if (v[i] != 0) - { - return i; - } + result = -1; } - return -1; + + return BitConverter.Int64BitsToDouble(result); } - public static int LastActiveElement(int[] v) + public static float CompareGreaterThan(float left, float right) { - for (var i = v.Length - 1; i >= 0; i--) + int result = 0; + + if (left > right) { - if (v[i] != 0) - { - return i; - } + result = -1; } - return -1; + + return BitConverter.Int32BitsToSingle(result); } - public static int LastActiveElement(uint[] v) + public static double CompareGreaterThanOrEqual(double left, double right) { - for (var i = v.Length - 1; i >= 0; i--) + long result = 0; + + if (left >= right) { - if (v[i] != 0) - { - return i; - } + result = -1; } - return -1; + + return BitConverter.Int64BitsToDouble(result); } - public static int LastActiveElement(long[] v) + public static float CompareGreaterThanOrEqual(float left, float right) { - for (var i = v.Length - 1; i >= 0; i--) + int result = 0; + + if (left >= right) { - if (v[i] != 0) - { - return i; - } + result = -1; } - return -1; + + return BitConverter.Int32BitsToSingle(result); } - public static int LastActiveElement(ulong[] v) + public static double CompareLessThan(double left, double right) { - for (var i = v.Length - 1; i >= 0; i--) + long result = 0; + + if (left < right) { - if (v[i] != 0) - { - return i; - } + result = -1; } - return -1; + + return BitConverter.Int64BitsToDouble(result); } - private static int LastActiveElement(float[] v) + public static float CompareLessThan(float left, float right) { - for (int i = v.Length - 1; i >= 0; i--) + int result = 0; + + if (left < right) { - if (Unsafe.BitCast(v[i]) != 0) - { - return i; - } + result = -1; } - return -1; + + return BitConverter.Int32BitsToSingle(result); } - private static int LastActiveElement(double[] v) + public static double CompareLessThanOrEqual(double left, double right) { - for (int i = v.Length - 1; i >= 0; i--) + long result = 0; + + if (left <= right) { - if (Unsafe.BitCast(v[i]) != 0) - { - return i; - } + result = -1; } - return -1; + + return BitConverter.Int64BitsToDouble(result); } - public static byte[] CreateMaskForNextActiveElement(byte[] mask, byte[] srcMask) + public static float CompareLessThanOrEqual(float left, float right) { - var count = srcMask.Length; - var result = new byte[count]; - for (var i = LastActiveElement(srcMask) + 1; i < count; i++) + int result = 0; + + if (left <= right) { - if (mask[i] != 0) - { - result[i] = 1; - return result; - } + result = -1; } - return result; + + return BitConverter.Int32BitsToSingle(result); } - public static ushort[] CreateMaskForNextActiveElement(ushort[] mask, ushort[] srcMask) + public static double CompareTest(double left, double right) { - var count = srcMask.Length; - var result = new ushort[count]; - for (var i = LastActiveElement(srcMask) + 1; i < count; i++) + long result = 0; + + if ((BitConverter.DoubleToInt64Bits(left) & BitConverter.DoubleToInt64Bits(right)) != 0) { - if (mask[i] != 0) - { - result[i] = 1; - return result; - } + result = -1; } - return result; + + return BitConverter.Int64BitsToDouble(result); } - public static uint[] CreateMaskForNextActiveElement(uint[] mask, uint[] srcMask) + public static float CompareTest(float left, float right) { - var count = srcMask.Length; - var result = new uint[count]; - for (var i = LastActiveElement(srcMask) + 1; i < count; i++) + int result = 0; + + if ((BitConverter.SingleToInt32Bits(left) & BitConverter.SingleToInt32Bits(right)) != 0) { - if (mask[i] != 0) - { - result[i] = 1; - return result; - } + result = -1; } - return result; + + return BitConverter.Int32BitsToSingle(result); } - public static ulong[] CreateMaskForNextActiveElement(ulong[] mask, ulong[] srcMask) + public static double AbsoluteCompareGreaterThan(double left, double right) { - var count = srcMask.Length; - var result = new ulong[count]; - for (var i = LastActiveElement(srcMask) + 1; i < count; i++) + long result = 0; + + left = Math.Abs(left); + right = Math.Abs(right); + + if (left > right) { - if (mask[i] != 0) - { - result[i] = 1; - return result; - } + result = -1; } - return result; - } - public static sbyte CountLeadingSignBits(sbyte op1) - { - return (sbyte)(CountLeadingZeroBits((sbyte)((ulong)op1 ^ ((ulong)op1 >> 1))) - 1); + return BitConverter.Int64BitsToDouble(result); } - public static short CountLeadingSignBits(short op1) + public static float AbsoluteCompareGreaterThan(float left, float right) { - return (short)(CountLeadingZeroBits((short)((ulong)op1 ^ ((ulong)op1 >> 1))) - 1); - } + int result = 0; - public static int CountLeadingSignBits(int op1) - { - return (int)(CountLeadingZeroBits((int)((ulong)op1 ^ ((ulong)op1 >> 1))) - 1); - } + left = Math.Abs(left); + right = Math.Abs(right); - public static long CountLeadingSignBits(long op1) - { - return (long)(CountLeadingZeroBits((long)((ulong)op1 ^ ((ulong)op1 >> 1))) - 1); - } - - public static sbyte CountLeadingZeroBits(sbyte op1) - { - return (sbyte)(8 * sizeof(sbyte) - (HighestSetBit(op1) + 1)); - } - - private static int HighestSetBit(sbyte op1) - { - for (int i = 8 * sizeof(sbyte) - 1; i >= 0; i--) + if (left > right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - return i; - } + result = -1; } - return -1; + return BitConverter.Int32BitsToSingle(result); } - public static byte CountLeadingZeroBits(byte op1) + public static double AbsoluteCompareGreaterThanOrEqual(double left, double right) { - return (byte)(8 * sizeof(byte) - (HighestSetBit(op1) + 1)); - } + long result = 0; - private static int HighestSetBit(byte op1) - { - for (int i = 8 * sizeof(byte) - 1; i >= 0; i--) + left = Math.Abs(left); + right = Math.Abs(right); + + if (left >= right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - return i; - } + result = -1; } - return -1; + return BitConverter.Int64BitsToDouble(result); } - public static short CountLeadingZeroBits(short op1) + public static float AbsoluteCompareGreaterThanOrEqual(float left, float right) { - return (short)(8 * sizeof(short) - (HighestSetBit(op1) + 1)); - } + int result = 0; - private static int HighestSetBit(short op1) - { - for (int i = 8 * sizeof(short) - 1; i >= 0; i--) + left = Math.Abs(left); + right = Math.Abs(right); + + if (left >= right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - return i; - } + result = -1; } - return -1; + return BitConverter.Int32BitsToSingle(result); } - public static ushort CountLeadingZeroBits(ushort op1) + public static double AbsoluteCompareLessThan(double left, double right) { - return (ushort)(8 * sizeof(ushort) - (HighestSetBit(op1) + 1)); - } + long result = 0; - private static int HighestSetBit(ushort op1) - { - for (int i = 8 * sizeof(ushort) - 1; i >= 0; i--) + left = Math.Abs(left); + right = Math.Abs(right); + + if (left < right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - return i; - } + result = -1; } - return -1; + return BitConverter.Int64BitsToDouble(result); } - public static int CountLeadingZeroBits(int op1) + public static float AbsoluteCompareLessThan(float left, float right) { - return (int)(8 * sizeof(int) - (HighestSetBit(op1) + 1)); - } + int result = 0; - private static int HighestSetBit(int op1) - { - for (int i = 8 * sizeof(int) - 1; i >= 0; i--) + left = Math.Abs(left); + right = Math.Abs(right); + + if (left < right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - return i; - } + result = -1; } - return -1; + return BitConverter.Int32BitsToSingle(result); } - public static uint CountLeadingZeroBits(uint op1) + public static double AbsoluteCompareLessThanOrEqual(double left, double right) { - return (uint)(8 * sizeof(uint) - (HighestSetBit(op1) + 1)); - } + long result = 0; - private static int HighestSetBit(uint op1) - { - for (int i = 8 * sizeof(uint) - 1; i >= 0; i--) + left = Math.Abs(left); + right = Math.Abs(right); + + if (left <= right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - return i; - } + result = -1; } - return -1; + return BitConverter.Int64BitsToDouble(result); } - public static long CountLeadingZeroBits(long op1) + public static float AbsoluteCompareLessThanOrEqual(float left, float right) { - return (long)(8 * sizeof(long) - (HighestSetBit(op1) + 1)); - } + int result = 0; - private static int HighestSetBit(long op1) - { - for (int i = 8 * sizeof(long) - 1; i >= 0; i--) + left = Math.Abs(left); + right = Math.Abs(right); + + if (left <= right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - return i; - } + result = -1; } - return -1; + return BitConverter.Int32BitsToSingle(result); } - public static ulong CountLeadingZeroBits(ulong op1) - { - return (ulong)(8 * sizeof(ulong) - (HighestSetBit(op1) + 1)); - } - private static int HighestSetBit(ulong op1) + public static double SveAbsoluteCompareGreaterThan(double left, double right) { - for (int i = 8 * sizeof(ulong) - 1; i >= 0; i--) - { - if (((ulong)op1 & (1UL << i)) != 0) - { - return i; - } - } - - return -1; - } + long result = 0; - public static sbyte BitCount(sbyte op1) - { - int result = 0; + left = Math.Abs(left); + right = Math.Abs(right); - for (int i = 0; i < 8 * sizeof(sbyte); i++) + if (left > right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result + 1; - } + result = 1; } - return (sbyte)result; + return BitConverter.Int64BitsToDouble(result); } - public static byte BitCount(byte op1) + public static float SveAbsoluteCompareGreaterThan(float left, float right) { int result = 0; - for (int i = 0; i < 8 * sizeof(byte); i++) + left = Math.Abs(left); + right = Math.Abs(right); + + if (left > right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result + 1; - } + result = 1; } - return (byte)result; + return BitConverter.Int32BitsToSingle(result); } - public static short BitCount(short op1) + public static double SveAbsoluteCompareGreaterThanOrEqual(double left, double right) { - int result = 0; + long result = 0; + + left = Math.Abs(left); + right = Math.Abs(right); - for (int i = 0; i < 8 * sizeof(short); i++) + if (left >= right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result + 1; - } + result = 1; } - return (short)result; + return BitConverter.Int64BitsToDouble(result); } - public static ushort BitCount(ushort op1) + public static float SveAbsoluteCompareGreaterThanOrEqual(float left, float right) { int result = 0; - for (int i = 0; i < 8 * sizeof(ushort); i++) + left = Math.Abs(left); + right = Math.Abs(right); + + if (left >= right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result + 1; - } + result = 1; } - return (ushort)result; + return BitConverter.Int32BitsToSingle(result); } - public static int BitCount(int op1) + public static double SveAbsoluteCompareLessThan(double left, double right) { - int result = 0; + long result = 0; + + left = Math.Abs(left); + right = Math.Abs(right); - for (int i = 0; i < 8 * sizeof(int); i++) + if (left < right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result + 1; - } + result = 1; } - return (int)result; + return BitConverter.Int64BitsToDouble(result); } - public static uint BitCount(uint op1) + public static float SveAbsoluteCompareLessThan(float left, float right) { int result = 0; - for (int i = 0; i < 8 * sizeof(uint); i++) + left = Math.Abs(left); + right = Math.Abs(right); + + if (left < right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result + 1; - } + result = 1; } - return (uint)result; + return BitConverter.Int32BitsToSingle(result); } - public static long BitCount(long op1) + public static double SveAbsoluteCompareLessThanOrEqual(double left, double right) { - int result = 0; + long result = 0; - for (int i = 0; i < 8 * sizeof(long); i++) + left = Math.Abs(left); + right = Math.Abs(right); + + if (left <= right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result + 1; - } + result = 1; } - return (long)result; + return BitConverter.Int64BitsToDouble(result); } - public static ulong BitCount(ulong op1) + public static float SveAbsoluteCompareLessThanOrEqual(float left, float right) { int result = 0; - for (int i = 0; i < 8 * sizeof(ulong); i++) + left = Math.Abs(left); + right = Math.Abs(right); + + if (left <= right) { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result + 1; - } + result = 1; } - return (ulong)result; + return BitConverter.Int32BitsToSingle(result); } - public static int BitCount(float op1) => BitCount(BitConverter.SingleToInt32Bits(op1)); + public static double SveCompareEqual(double left, double right) => BitConverter.Int64BitsToDouble((left == right) ? 1 : 0); + public static float SveCompareEqual(float left, float right) => BitConverter.Int32BitsToSingle((left == right) ? 1 : 0); + public static T SveCompareEqual(T left, T right) + where T : INumber, IEqualityOperators + => left == right ? T.One : T.Zero; - public static long BitCount(double op1) => BitCount(BitConverter.DoubleToInt64Bits(op1)); + public static double SveCompareNotEqual(double left, double right) => BitConverter.Int64BitsToDouble((left != right) ? 1 : 0); + public static float SveCompareNotEqual(float left, float right) => BitConverter.Int32BitsToSingle((left != right) ? 1 : 0); + public static T SveCompareNotEqual(T left, T right) + where T : INumber, IEqualityOperators + => left != right ? T.One : T.Zero; - public static byte ReverseElementBits(byte op1) - { - byte val = (byte)op1; - byte result = 0; - const int bitsize = sizeof(byte) * 8; - const byte cst_one = 1; + public static double SveCompareGreaterThan(double left, double right) => BitConverter.Int64BitsToDouble((left > right) ? 1 : 0); + public static float SveCompareGreaterThan(float left, float right) => BitConverter.Int32BitsToSingle((left > right) ? 1 : 0); + public static T SveCompareGreaterThan(T left, T right) + where T : INumber, IComparisonOperators + => left > right ? T.One : T.Zero; - for (int i = 0; i < bitsize; i++) - { - if ((val & (cst_one << i)) != 0) - { - result |= (byte)(cst_one << (bitsize - 1 - i)); - } - } + public static double SveCompareGreaterThanOrEqual(double left, double right) => BitConverter.Int64BitsToDouble((left >= right) ? 1 : 0); + public static float SveCompareGreaterThanOrEqual(float left, float right) => BitConverter.Int32BitsToSingle((left >= right) ? 1 : 0); + public static T SveCompareGreaterThanOrEqual(T left, T right) + where T : INumber, IComparisonOperators + => left >= right ? T.One : T.Zero; - return (byte)result; - } + public static double SveCompareLessThan(double left, double right) => BitConverter.Int64BitsToDouble((left < right) ? 1 : 0); + public static float SveCompareLessThan(float left, float right) => BitConverter.Int32BitsToSingle((left < right) ? 1 : 0); + public static T SveCompareLessThan(T left, T right) + where T : INumber, IComparisonOperators + => left < right ? T.One : T.Zero; - public static short ReverseElementBits(short op1) - { - short val = (short)op1; - short result = 0; - const int bitsize = sizeof(short) * 8; - const short cst_one = 1; + public static double SveCompareLessThanOrEqual(double left, double right) => BitConverter.Int64BitsToDouble((left <= right) ? 1 : 0); + public static float SveCompareLessThanOrEqual(float left, float right) => BitConverter.Int32BitsToSingle((left <= right) ? 1 : 0); + public static T SveCompareLessThanOrEqual(T left, T right) + where T : INumber, IComparisonOperators + => left <= right ? T.One : T.Zero; - for (int i = 0; i < bitsize; i++) - { - if ((val & (cst_one << i)) != 0) - { - result |= (short)(cst_one << (bitsize - 1 - i)); - } - } + public static double SveCompareUnordered(double left, double right) => BitConverter.Int64BitsToDouble((double.IsNaN(left) || double.IsNaN(right)) ? 1 : 0); + public static float SveCompareUnordered(float left, float right) => BitConverter.Int32BitsToSingle((float.IsNaN(left) || float.IsNaN(right)) ? 1 : 0); - return (short)result; - } + public static byte Abs(sbyte value) => value < 0 ? (byte)-value : (byte)value; - public static int ReverseElementBits(int op1) - { - uint val = (uint)op1; - uint result = 0; - const int bitsize = sizeof(uint) * 8; - const uint cst_one = 1; + public static ushort Abs(short value) => value < 0 ? (ushort)-value : (ushort)value; - for (int i = 0; i < bitsize; i++) - { - if ((val & (cst_one << i)) != 0) - { - result |= (uint)(cst_one << (bitsize - 1 - i)); - } - } + public static uint Abs(int value) => value < 0 ? (uint)-value : (uint)value; - return (int)result; - } + public static ulong Abs(long value) => value < 0 ? (ulong)-value : (ulong)value; - public static long ReverseElementBits(long op1) - { - ulong val = (ulong)op1; - ulong result = 0; - const int bitsize = sizeof(ulong) * 8; - const ulong cst_one = 1; + public static float Abs(float value) => Math.Abs(value); - for (int i = 0; i < bitsize; i++) - { - if ((val & (cst_one << i)) != 0) - { - result |= (ulong)(cst_one << (bitsize - 1 - i)); - } - } + public static double Abs(double value) => Math.Abs(value); - return (long)result; - } + public static float Divide(float op1, float op2) => op1 / op2; - public static sbyte ReverseElementBits(sbyte op1) - { - byte val = (byte)op1; - byte result = 0; - const int bitsize = sizeof(byte) * 8; - const byte cst_one = 1; + public static double Divide(double op1, double op2) => op1 / op2; - for (int i = 0; i < bitsize; i++) - { - if ((val & (cst_one << i)) != 0) - { - result |= (byte)(cst_one << (bitsize - 1 - i)); - } - } + public static float Scale(float op1, int op2) => op1 * MathF.Pow((float)2.0, op2); - return (sbyte)result; - } + public static double Scale(double op1, long op2) => op1 * Math.Pow(2.0, op2); - public static ushort ReverseElementBits(ushort op1) - { - ushort val = (ushort)op1; - ushort result = 0; - const int bitsize = sizeof(ushort) * 8; - const ushort cst_one = 1; + public static float Sqrt(float value) => MathF.Sqrt(value); - for (int i = 0; i < bitsize; i++) - { - if ((val & (cst_one << i)) != 0) - { - result |= (ushort)(cst_one << (bitsize - 1 - i)); - } - } + public static double Sqrt(double value) => Math.Sqrt(value); - return (ushort)result; + public static T AbsoluteDifference(T op1, T op2) + where T : unmanaged, INumber, IComparisonOperators + { + return op1 < op2 ? op2 - op1 : op1 - op2; } - public static uint ReverseElementBits(uint op1) + public static T AbsoluteDifferenceAdd(T op1, T op2, T op3) + where T : unmanaged, INumber, IComparisonOperators { - uint val = (uint)op1; - uint result = 0; - const int bitsize = sizeof(uint) * 8; - const uint cst_one = 1; - - for (int i = 0; i < bitsize; i++) - { - if ((val & (cst_one << i)) != 0) - { - result |= (uint)(cst_one << (bitsize - 1 - i)); - } - } - - return (uint)result; + return op1 + AbsoluteDifference(op2, op3); } - public static ulong ReverseElementBits(ulong op1) - { - ulong val = (ulong)op1; - ulong result = 0; - const int bitsize = sizeof(ulong) * 8; - const ulong cst_one = 1; + public static ushort AbsoluteDifferenceWidening(sbyte op1, sbyte op2) => op1 < op2 ? (ushort)(op2 - op1) : (ushort)(op1 - op2); - for (int i = 0; i < bitsize; i++) - { - if ((val & (cst_one << i)) != 0) - { - result |= (ulong)(cst_one << (bitsize - 1 - i)); - } - } + public static ushort AbsoluteDifferenceWideningUpper(sbyte[] op1, sbyte[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - return (ulong)result; - } + public static short AbsoluteDifferenceWideningAndAdd(short op1, sbyte op2, sbyte op3) => (short)(op1 + (short)AbsoluteDifferenceWidening(op2, op3)); - public static sbyte And(sbyte op1, sbyte op2) => (sbyte)(op1 & op2); + public static short AbsoluteDifferenceWideningUpperAndAdd(short[] op1, sbyte[] op2, sbyte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static sbyte BitwiseClear(sbyte op1, sbyte op2) => (sbyte)(op1 & ~op2); + public static short AbsoluteDifferenceWideningLowerAndAddEven(short[] op1, sbyte[] op2, sbyte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i * 2], op3[i * 2]); - public static sbyte BitwiseSelect(sbyte op1, sbyte op2, sbyte op3) - { - ulong result = 0; + public static short AbsoluteDifferenceWideningLowerAndAddOdd(short[] op1, sbyte[] op2, sbyte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - for (int i = 0; i < 8 * sizeof(sbyte); i++) - { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result | ((ulong)op2 & (1UL << i)); - } - else - { - result = result | ((ulong)op3 & (1UL << i)); - } - } + public static short AbsoluteDifferenceWideningEven(sbyte[] op1, sbyte[] op2, int i) => (short)AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - return (sbyte)result; - } + public static short AbsoluteDifferenceWideningOdd(sbyte[] op1, sbyte[] op2, int i) => (short)AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); - public static sbyte Not(sbyte op1) => (sbyte)(~op1); + public static short AddAcrossWidening(sbyte[] op1) => Reduce(AddWidening, op1); - public static sbyte Or(sbyte op1, sbyte op2) => (sbyte)(op1 | op2); + public static long AddAcrossWideningLong(sbyte[] op1) => Reduce(AddWidening, op1); - public static sbyte OrNot(sbyte op1, sbyte op2) => (sbyte)(op1 | ~op2); + public static short AddPairwiseWidening(sbyte[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); - public static sbyte Xor(sbyte op1, sbyte op2) => (sbyte)(op1 ^ op2); + public static short AddPairwiseWideningAndAdd(short[] op1, sbyte[] op2, int i) => (short)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); - public static byte And(byte op1, byte op2) => (byte)(op1 & op2); + public static sbyte AddHighNarrowingEven(short[] op1, short[] op2, int i) + { + if (i % 2 == 0) + { + return (sbyte) ((op1[i / 2] + op2[i / 2]) >> (8 * sizeof(sbyte))); + } - public static byte BitwiseClear(byte op1, byte op2) => (byte)(op1 & ~op2); + return 0; + } - public static byte BitwiseSelect(byte op1, byte op2, byte op3) + public static sbyte AddHighNarrowingOdd(sbyte[] even, short[] op1, short[] op2, int i) { - ulong result = 0; - - for (int i = 0; i < 8 * sizeof(byte); i++) + if (i % 2 == 1) { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result | ((ulong)op2 & (1UL << i)); - } - else - { - result = result | ((ulong)op3 & (1UL << i)); - } + return (sbyte) ((op1[(i - 1) / 2] + op2[(i - 1) / 2]) >> (8 * sizeof(sbyte))); } - return (byte)result; + return even[i]; } - public static byte Not(byte op1) => (byte)(~op1); + public static unsafe U AddHighNarrowing(T op1, T op2) + where U : unmanaged, INumber + where T : unmanaged, INumber, IShiftOperators + => HighNarrowing(op1 + op2, round: false); - public static byte Or(byte op1, byte op2) => (byte)(op1 | op2); + public static sbyte AddHighNarrowingUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static byte OrNot(byte op1, byte op2) => (byte)(op1 | ~op2); + public static short AddRoundedHighNarrowingUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static byte Xor(byte op1, byte op2) => (byte)(op1 ^ op2); + public static short AddWidening(sbyte op1, sbyte op2) => (short)((short)op1 + (short)op2); - public static short And(short op1, short op2) => (short)(op1 & op2); + public static short AddWidening(short op1, sbyte op2) => (short)(op1 + op2); - public static short BitwiseClear(short op1, short op2) => (short)(op1 & ~op2); + public static long AddWidening(long op1, sbyte op2) => (long)(op1 + (long)op2); - public static short BitwiseSelect(short op1, short op2, short op3) - { - ulong result = 0; + public static short AddWideningUpper(sbyte[] op1, sbyte[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - for (int i = 0; i < 8 * sizeof(short); i++) - { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result | ((ulong)op2 & (1UL << i)); - } - else - { - result = result | ((ulong)op3 & (1UL << i)); - } - } + public static short AddWideningUpper(short[] op1, sbyte[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); - return (short)result; + public static T BooleanNot(T value) + where T : unmanaged, INumber, IComparisonOperators + { + return value == T.Zero ? T.One : T.Zero; } - public static short Not(short op1) => (short)(~op1); - - public static short Or(short op1, short op2) => (short)(op1 | op2); + public static sbyte ExtractNarrowing(short op1) => (sbyte)op1; - public static short OrNot(short op1, short op2) => (short)(op1 | ~op2); + public static sbyte ExtractNarrowingUpper(sbyte[] op1, short[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); - public static short Xor(short op1, short op2) => (short)(op1 ^ op2); + public static sbyte FusedAddHalving(sbyte op1, sbyte op2) => (sbyte)((ushort)((short)op1 + (short)op2) >> 1); - public static ushort And(ushort op1, ushort op2) => (ushort)(op1 & op2); + public static sbyte FusedAddRoundedHalving(sbyte op1, sbyte op2) => (sbyte)((ushort)((short)op1 + (short)op2 + 1) >> 1); - public static ushort BitwiseClear(ushort op1, ushort op2) => (ushort)(op1 & ~op2); + public static sbyte FusedSubtractHalving(sbyte op1, sbyte op2) => (sbyte)((ushort)((short)op1 - (short)op2) >> 1); - public static ushort BitwiseSelect(ushort op1, ushort op2, ushort op3) - { - ulong result = 0; + public static short MultiplyByScalarWideningUpper(sbyte[] op1, sbyte op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2); - for (int i = 0; i < 8 * sizeof(ushort); i++) - { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result | ((ulong)op2 & (1UL << i)); - } - else - { - result = result | ((ulong)op3 & (1UL << i)); - } - } + public static short MultiplyByScalarWideningUpperAndAdd(short[] op1, sbyte[] op2, sbyte op3, int i) => MultiplyAddWidening(op1[i], op2[i + op2.Length / 2], op3); - return (ushort)result; - } + public static short MultiplyByScalarWideningUpperAndSubtract(short[] op1, sbyte[] op2, sbyte op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3); - public static ushort Not(ushort op1) => (ushort)(~op1); + public static short MultiplyWidening(sbyte op1, sbyte op2) => (short)((short)op1 * (short)op2); - public static ushort Or(ushort op1, ushort op2) => (ushort)(op1 | op2); + public static short MultiplyWideningAndSubtract(short op1, sbyte op2, sbyte op3) => (short)(op1 - MultiplyWidening(op2, op3)); - public static ushort OrNot(ushort op1, ushort op2) => (ushort)(op1 | ~op2); + public static short MultiplyWideningUpper(sbyte[] op1, sbyte[] op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static ushort Xor(ushort op1, ushort op2) => (ushort)(op1 ^ op2); + public static short MultiplyWideningUpperAndAdd(short[] op1, sbyte[] op2, sbyte[] op3, int i) => MultiplyAddWidening(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static int And(int op1, int op2) => (int)(op1 & op2); + public static short MultiplyWideningUpperAndSubtract(short[] op1, sbyte[] op2, sbyte[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static int BitwiseClear(int op1, int op2) => (int)(op1 & ~op2); + public static N SubtractHighNarrowing(W op1, W op2) + where W : unmanaged, IBinaryInteger + where N : unmanaged, IBinaryInteger + => HighNarrowing(op1 - op2, round: false); - public static int BitwiseSelect(int op1, int op2, int op3) + public static N SubtractHighNarrowingUpper(N[] op1, W[] op2, W[] op3, int i) + where W : unmanaged, IBinaryInteger + where N : unmanaged, IBinaryInteger { - ulong result = 0; + if (i < op1.Length) + { + return op1[i]; + } + + return SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + } - for (int i = 0; i < 8 * sizeof(int); i++) + public static N SubtractRoundedHighNarrowingUpper(N[] op1, W[] op2, W[] op3, int i) + where W : unmanaged, IBinaryInteger + where N : unmanaged, IBinaryInteger + { + if (i < op1.Length) { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result | ((ulong)op2 & (1UL << i)); - } - else - { - result = result | ((ulong)op3 & (1UL << i)); - } + return op1[i]; } - return (int)result; + return SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); } - public static int Not(int op1) => (int)(~op1); + public static short SubtractWidening(sbyte op1, sbyte op2) => (short)((short)op1 - (short)op2); - public static int Or(int op1, int op2) => (int)(op1 | op2); + public static short SubtractWidening(short op1, sbyte op2) => (short)(op1 - op2); - public static int OrNot(int op1, int op2) => (int)(op1 | ~op2); + public static short SubtractWideningUpper(sbyte[] op1, sbyte[] op2, int i) => SubtractWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static int Xor(int op1, int op2) => (int)(op1 ^ op2); + public static short SubtractWideningUpper(short[] op1, sbyte[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); - public static uint And(uint op1, uint op2) => (uint)(op1 & op2); + public static short ZeroExtendWidening(sbyte op1) => (short)(ushort)op1; - public static uint BitwiseClear(uint op1, uint op2) => (uint)(op1 & ~op2); + public static short ZeroExtendWideningUpper(sbyte[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); - public static uint BitwiseSelect(uint op1, uint op2, uint op3) - { - ulong result = 0; + public static uint AbsoluteDifferenceWidening(short op1, short op2) => op1 < op2 ? (uint)(op2 - op1) : (uint)(op1 - op2); - for (int i = 0; i < 8 * sizeof(uint); i++) - { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result | ((ulong)op2 & (1UL << i)); - } - else - { - result = result | ((ulong)op3 & (1UL << i)); - } - } + public static uint AbsoluteDifferenceWideningUpper(short[] op1, short[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - return (uint)result; - } + public static int AbsoluteDifferenceWideningAndAdd(int op1, short op2, short op3) => (int)(op1 + (int)AbsoluteDifferenceWidening(op2, op3)); + + public static int AbsoluteDifferenceWideningUpperAndAdd(int[] op1, short[] op2, short[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + + public static int AbsoluteDifferenceWideningLowerAndAddEven(int[] op1, short[] op2, short[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i * 2], op3[i * 2]); + + 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 uint Not(uint op1) => (uint)(~op1); + public static int AbsoluteDifferenceWideningEven(short[] op1, short[] op2, int i) => (int)AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - public static uint Or(uint op1, uint op2) => (uint)(op1 | op2); + public static int AbsoluteDifferenceWideningOdd(short[] op1, short[] op2, int i) => (int)AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); - public static uint OrNot(uint op1, uint op2) => (uint)(op1 | ~op2); + public static int AddAcrossWidening(short[] op1) => Reduce(AddWidening, op1); - public static uint Xor(uint op1, uint op2) => (uint)(op1 ^ op2); + public static long AddAcrossWideningLong(short[] op1) => Reduce(AddWidening, op1); - public static long And(long op1, long op2) => (long)(op1 & op2); + public static int AddPairwiseWidening(short[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); - public static long BitwiseClear(long op1, long op2) => (long)(op1 & ~op2); + public static int AddPairwiseWideningAndAdd(int[] op1, short[] op2, int i) => (int)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); - public static long BitwiseSelect(long op1, long op2, long op3) + public static uint AddCarryWideningEven(uint[] op1, uint[] op2, uint[] op3, int i) { - ulong result = 0; + uint lsb; + ulong res; - for (int i = 0; i < 8 * sizeof(long); i++) + if ((i < 0) || (i >= op1.Length) || (i >= op2.Length) || (i >= op3.Length)) + { + throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); + } + + if (i % 2 == 0) { - if (((ulong)op1 & (1UL << i)) != 0) + if (i + 1 >= op2.Length) { - result = result | ((ulong)op2 & (1UL << i)); + throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range."); } - else + + lsb = op2[i + 1] & 1u; + res = (ulong)op1[i] + op3[i] + lsb; + return (uint)res; + } + else + { + if (((i - 1) < 0) || ((i - 1) >= op1.Length) || ((i - 1) >= op3.Length)) { - result = result | ((ulong)op3 & (1UL << i)); + throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); } - } - return (long)result; + lsb = op2[i] & 1u; + res = (ulong)op1[i - 1] + op3[i - 1] + lsb; + + // Shift result to get the carry bit + return (uint)(res >> 32); + } } - public static long Not(long op1) => (long)(~op1); + public static uint AddCarryWideningOdd(uint[] op1, uint[] op2, uint[] op3, int i) + { + uint lsb; + ulong res; - public static long Or(long op1, long op2) => (long)(op1 | op2); + if ((i < 0) || (i >= op1.Length) || (i >= op2.Length) || (i >= op3.Length)) + { + throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); + } - public static long OrNot(long op1, long op2) => (long)(op1 | ~op2); + if (i % 2 == 0) + { + if (((i + 1) >= op1.Length) || ((i + 1) >= op2.Length)) + { + throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range."); + } - public static long Xor(long op1, long op2) => (long)(op1 ^ op2); + lsb = op2[i + 1] & 1u; + res = (ulong)op1[i + 1] + op3[i] + lsb; + return (uint)res; + } + else + { + if (((i - 1) < 0) || ((i - 1) >= op3.Length)) + { + throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); + } - public static ulong And(ulong op1, ulong op2) => (ulong)(op1 & op2); + lsb = op2[i] & 1u; + res = (ulong)op1[i] + op3[i - 1] + lsb; - public static ulong BitwiseClear(ulong op1, ulong op2) => (ulong)(op1 & ~op2); + // Shift result to get the carry bit + return (uint)(res >> 32); + } + } - public static ulong BitwiseSelect(ulong op1, ulong op2, ulong op3) + public static unsafe U HighNarrowing(T op1, bool round) + where U : unmanaged, INumber + where T : unmanaged, INumber, IShiftOperators { - ulong result = 0; - - for (int i = 0; i < 8 * sizeof(ulong); i++) + T roundConst = T.Zero; + int shift = 8 * Unsafe.SizeOf(); + if (round) { - if (((ulong)op1 & (1UL << i)) != 0) - { - result = result | ((ulong)op2 & (1UL << i)); - } - else - { - result = result | ((ulong)op3 & (1UL << i)); - } + roundConst = T.One << (shift - 1); } - return (ulong)result; + return U.CreateChecked((op1 + roundConst) >> shift); } - public static ulong Not(ulong op1) => (ulong)(~op1); - - public static ulong Or(ulong op1, ulong op2) => (ulong)(op1 | op2); + public static short AddHighNarrowingEven(int[] op1, int[] op2, int i) + { + if (i % 2 == 0) + { + return (short) ((op1[i / 2] + op2[i / 2]) >> (8 * sizeof(short))); + } - public static ulong OrNot(ulong op1, ulong op2) => (ulong)(op1 | ~op2); + return 0; + } - public static ulong Xor(ulong op1, ulong op2) => (ulong)(op1 ^ op2); + public static short AddHighNarrowingOdd(short[] even, int[] op1, int[] op2, int i) + { + if (i % 2 == 1) + { + return (short) ((op1[(i - 1) / 2] + op2[(i - 1) / 2]) >> (8 * sizeof(short))); + } - public static float Not(float op1) => BitConverter.Int32BitsToSingle(~BitConverter.SingleToInt32Bits(op1)); + return even[i]; + } - public static double Not(double op1) => BitConverter.Int64BitsToDouble(~BitConverter.DoubleToInt64Bits(op1)); + public static short AddHighNarrowingUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static float And(float op1, float op2) => BitConverter.Int32BitsToSingle(And(BitConverter.SingleToInt32Bits(op1), BitConverter.SingleToInt32Bits(op2))); + public static int AddRoundedHighNarrowingUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static double And(double op1, double op2) => BitConverter.Int64BitsToDouble(And(BitConverter.DoubleToInt64Bits(op1), BitConverter.DoubleToInt64Bits(op2))); + public static int AddWidening(short op1, short op2) => (int)((int)op1 + (int)op2); - public static float BitwiseClear(float op1, float op2) => BitConverter.Int32BitsToSingle(BitwiseClear(BitConverter.SingleToInt32Bits(op1), BitConverter.SingleToInt32Bits(op2))); + public static int AddWidening(int op1, short op2) => (int)(op1 + op2); - public static double BitwiseClear(double op1, double op2) => BitConverter.Int64BitsToDouble(BitwiseClear(BitConverter.DoubleToInt64Bits(op1), BitConverter.DoubleToInt64Bits(op2))); + public static long AddWidening(long op1, short op2) => (long)(op1 + (long)op2); - public static float Or(float op1, float op2) => BitConverter.Int32BitsToSingle(Or(BitConverter.SingleToInt32Bits(op1), BitConverter.SingleToInt32Bits(op2))); + public static int AddWideningUpper(short[] op1, short[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static double Or(double op1, double op2) => BitConverter.Int64BitsToDouble(Or(BitConverter.DoubleToInt64Bits(op1), BitConverter.DoubleToInt64Bits(op2))); + public static int AddWideningUpper(int[] op1, short[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); - public static float OrNot(float op1, float op2) => BitConverter.Int32BitsToSingle(OrNot(BitConverter.SingleToInt32Bits(op1), BitConverter.SingleToInt32Bits(op2))); + public static short ExtractNarrowing(int op1) => (short)op1; - public static double OrNot(double op1, double op2) => BitConverter.Int64BitsToDouble(OrNot(BitConverter.DoubleToInt64Bits(op1), BitConverter.DoubleToInt64Bits(op2))); + public static short ExtractNarrowingUpper(short[] op1, int[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); - public static float Xor(float op1, float op2) => BitConverter.Int32BitsToSingle(Xor(BitConverter.SingleToInt32Bits(op1), BitConverter.SingleToInt32Bits(op2))); + public static short FusedAddHalving(short op1, short op2) => (short)((uint)((int)op1 + (int)op2) >> 1); - public static double Xor(double op1, double op2) => BitConverter.Int64BitsToDouble(Xor(BitConverter.DoubleToInt64Bits(op1), BitConverter.DoubleToInt64Bits(op2))); + public static short FusedAddRoundedHalving(short op1, short op2) => (short)((uint)((int)op1 + (int)op2 + 1) >> 1); - public static float BitwiseSelect(float op1, float op2, float op3) => BitConverter.Int32BitsToSingle(BitwiseSelect(BitConverter.SingleToInt32Bits(op1), BitConverter.SingleToInt32Bits(op2), BitConverter.SingleToInt32Bits(op3))); - public static double BitwiseSelect(double op1, double op2, double op3) => BitConverter.Int64BitsToDouble(BitwiseSelect(BitConverter.DoubleToInt64Bits(op1), BitConverter.DoubleToInt64Bits(op2), BitConverter.DoubleToInt64Bits(op3))); + public static short FusedSubtractHalving(short op1, short op2) => (short)((uint)((int)op1 - (int)op2) >> 1); - public static sbyte CompareEqual(sbyte left, sbyte right) + public static int Log2(float val) { - long result = 0; - - if (left == right) + if (float.IsNaN(val) || val <= 0) { - result = -1; + return int.MinValue; + } + if (float.IsInfinity(val)) + { + return int.MaxValue; } - return (sbyte)result; + double log2 = Math.Log(val, 2.0); + if (log2 >= int.MaxValue) return int.MaxValue; + if (log2 <= int.MinValue) return int.MinValue; + + return (int)Math.Floor(log2); } - public static sbyte CompareGreaterThan(sbyte left, sbyte right) - { - long result = 0; - - if (left > right) - { - result = -1; - } + public static int MultiplyByScalarWideningUpper(short[] op1, short op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2); - return (sbyte)result; - } + public static int MultiplyByScalarWideningUpperAndAdd(int[] op1, short[] op2, short op3, int i) => MultiplyAddWidening(op1[i], op2[i + op2.Length / 2], op3); - public static sbyte CompareGreaterThanOrEqual(sbyte left, sbyte right) - { - long result = 0; + public static int MultiplyByScalarWideningUpperAndSubtract(int[] op1, short[] op2, short op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3); - if (left >= right) - { - result = -1; - } + public static int MultiplyWidening(short op1, short op2) => (int)((int)op1 * (int)op2); - return (sbyte)result; - } + public static int MultiplyWideningAndSubtract(int op1, short op2, short op3) => (int)(op1 - MultiplyWidening(op2, op3)); - public static sbyte CompareLessThan(sbyte left, sbyte right) - { - long result = 0; + public static int MultiplyWideningUpper(short[] op1, short[] op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - if (left < right) - { - result = -1; - } + public static int MultiplyWideningUpperAndAdd(int[] op1, short[] op2, short[] op3, int i) => MultiplyAddWidening(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - return (sbyte)result; - } + public static int MultiplyWideningUpperAndSubtract(int[] op1, short[] op2, short[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static sbyte CompareLessThanOrEqual(sbyte left, sbyte right) - { - long result = 0; + public static short SubtractHighNarrowing(int op1, int op2) => HighNarrowing((int)(op1 - op2), round: false); - if (left <= right) - { - result = -1; - } + public static int SubtractHighNarrowingUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - return (sbyte)result; - } + public static short SubtractRoundedHighNarrowing(int op1, int op2) => HighNarrowing((int)(op1 - op2), round: true); - public static sbyte CompareTest(sbyte left, sbyte right) - { - long result = 0; + public static int SubtractRoundedHighNarrowingUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - if ((left & right) != 0) - { - result = -1; - } + public static int SubtractWidening(short op1, short op2) => (int)((int)op1 - (int)op2); - return (sbyte)result; - } + public static int SubtractWidening(int op1, short op2) => (int)(op1 - op2); - public static byte CompareEqual(byte left, byte right) - { - long result = 0; + public static int SubtractWideningUpper(short[] op1, short[] op2, int i) => SubtractWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - if (left == right) - { - result = -1; - } + public static int SubtractWideningUpper(int[] op1, short[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); - return (byte)result; - } + public static int ZeroExtendWidening(short op1) => (int)(uint)op1; - public static byte CompareGreaterThan(byte left, byte right) - { - long result = 0; + public static int ZeroExtendWideningUpper(short[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); - if (left > right) - { - result = -1; - } + public static ulong AbsoluteDifferenceWidening(int op1, int op2) => op1 < op2 ? (ulong)(op2 - op1) : (ulong)(op1 - op2); - return (byte)result; - } + public static ulong AbsoluteDifferenceWideningUpper(int[] op1, int[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static byte CompareGreaterThanOrEqual(byte left, byte right) - { - long result = 0; + public static long AbsoluteDifferenceWideningAndAdd(long op1, int op2, int op3) => (long)(op1 + (long)AbsoluteDifferenceWidening(op2, op3)); - if (left >= right) - { - result = -1; - } + public static long AbsoluteDifferenceWideningUpperAndAdd(long[] op1, int[] op2, int[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - return (byte)result; - } + public static long AbsoluteDifferenceWideningLowerAndAddEven(long[] op1, int[] op2, int[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i * 2], op3[i * 2]); - public static byte CompareLessThan(byte left, byte right) - { - long result = 0; + public static long AbsoluteDifferenceWideningLowerAndAddOdd(long[] op1, int[] op2, int[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - if (left < right) - { - result = -1; - } + public static long AbsoluteDifferenceWideningEven(int[] op1, int[] op2, int i) => (long)AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - return (byte)result; - } + public static long AbsoluteDifferenceWideningOdd(int[] op1, int[] op2, int i) => (long)AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); - public static byte CompareLessThanOrEqual(byte left, byte right) - { - long result = 0; + public static long AddAcrossWidening(int[] op1) => Reduce(AddWidening, op1); - if (left <= right) - { - result = -1; - } + public static long AddPairwiseWidening(int[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); - return (byte)result; - } + public static long AddPairwiseWideningAndAdd(long[] op1, int[] op2, int i) => (long)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); - public static byte CompareTest(byte left, byte right) + public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, int i) { - long result = 0; + ulong lsb; + ulong res; - if ((left & right) != 0) + if ((i < 0) || (i >= op1.Length) || (i >= op2.Length) || (i >= op3.Length)) { - result = -1; + throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); } - return (byte)result; - } - - public static short CompareEqual(short left, short right) - { - long result = 0; - - if (left == right) + if (i % 2 == 0) { - result = -1; + if ((i + 1) >= op2.Length) + { + throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); + } + + lsb = op2[i + 1] & 1UL; + res = op1[i] + op3[i] + lsb; + return res; } + else + { + if (((i - 1) < 0) || ((i - 1) >= op1.Length) || ((i - 1) >= op3.Length)) + { + throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); + } - return (short)result; - } + lsb = op2[i] & 1UL; - public static short CompareGreaterThan(short left, short right) - { - long result = 0; + // Look for an overflow in the addition to get the carry bit + ulong sum1 = op1[i - 1] + op3[i - 1]; + bool overflow1 = sum1 < op1[i - 1]; - if (left > right) - { - result = -1; - } + ulong sum2 = sum1 + lsb; + bool overflow2 = sum2 < sum1; - return (short)result; + return (overflow1 || overflow2) ? 1UL : 0UL; + } } - public static short CompareGreaterThanOrEqual(short left, short right) + public static ulong AddCarryWideningOdd(ulong[] op1, ulong[] op2, ulong[] op3, int i) { - long result = 0; + ulong lsb; + ulong res; - if (left >= right) + if ((i < 0) || (i >= op1.Length) || (i >= op2.Length) || (i >= op3.Length)) { - result = -1; + throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); } - return (short)result; - } - - public static short CompareLessThan(short left, short right) - { - long result = 0; - - if (left < right) + if (i % 2 == 0) { - result = -1; + if (((i + 1) >= op1.Length) || ((i + 1) >= op2.Length)) + { + throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range."); + } + + lsb = op2[i + 1] & 1UL; + res = op1[i + 1] + op3[i] + lsb; + return res; } + else + { + if (((i - 1) < 0) || ((i - 1) >= op3.Length)) + { + throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); + } - return (short)result; - } + lsb = op2[i] & 1UL; - public static short CompareLessThanOrEqual(short left, short right) - { - long result = 0; + // Look for an overflow in the addition to get the carry bit + ulong sum1 = op1[i] + op3[i - 1]; + bool overflow1 = sum1 < op1[i]; - if (left <= right) - { - result = -1; - } + ulong sum2 = sum1 + lsb; + bool overflow2 = sum2 < sum1; - return (short)result; + return (overflow1 || overflow2) ? 1UL : 0UL; + } } - public static short CompareTest(short left, short right) + public static int AddHighNarrowingEven(long[] op1, long[] op2, int i) { - long result = 0; - - if ((left & right) != 0) + if (i % 2 == 0) { - result = -1; + return (int) ((op1[i / 2] + op2[i / 2]) >> (8 * sizeof(int))); } - return (short)result; + return 0; } - public static ushort CompareEqual(ushort left, ushort right) + public static int AddHighNarrowingOdd(int[] even, long[] op1, long[] op2, int i) { - long result = 0; - - if (left == right) + if (i % 2 == 1) { - result = -1; + return (int) ((op1[(i - 1) / 2] + op2[(i - 1) / 2]) >> (8 * sizeof(int))); } - return (ushort)result; + return even[i]; } - public static ushort CompareGreaterThan(ushort left, ushort right) - { - long result = 0; - - if (left > right) - { - result = -1; - } + public static int AddHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - return (ushort)result; - } + public static long AddRoundedHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static ushort CompareGreaterThanOrEqual(ushort left, ushort right) - { - long result = 0; + public static long AddWidening(int op1, int op2) => (long)((long)op1 + (long)op2); - if (left >= right) - { - result = -1; - } + public static long AddWidening(long op1, int op2) => (long)(op1 + op2); - return (ushort)result; - } + public static long AddWideningUpper(int[] op1, int[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static ushort CompareLessThan(ushort left, ushort right) - { - long result = 0; + public static long AddWideningUpper(long[] op1, int[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); - if (left < right) - { - result = -1; - } + public static int ExtractNarrowing(long op1) => (int)op1; - return (ushort)result; - } + public static int ExtractNarrowingUpper(int[] op1, long[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); - public static ushort CompareLessThanOrEqual(ushort left, ushort right) - { - long result = 0; + public static int FusedAddHalving(int op1, int op2) => (int)((ulong)((long)op1 + (long)op2) >> 1); - if (left <= right) - { - result = -1; - } + public static int FusedAddRoundedHalving(int op1, int op2) => (int)((ulong)((long)op1 + (long)op2 + 1) >> 1); - return (ushort)result; - } + public static int FusedSubtractHalving(int op1, int op2) => (int)((ulong)((long)op1 - (long)op2) >> 1); - public static ushort CompareTest(ushort left, ushort right) + public static long Log2(double val) { - long result = 0; - - if ((left & right) != 0) + if (double.IsNaN(val) || val <= 0) { - result = -1; + return long.MinValue; + } + if (double.IsInfinity(val)) + { + return long.MaxValue; } - return (ushort)result; + double log2 = Math.Log(val, 2.0); + if (log2 >= long.MaxValue) return long.MaxValue; + if (log2 <= long.MinValue) return long.MinValue; + + return (long)Math.Floor(log2); } - public static int CompareEqual(int left, int right) - { - long result = 0; + public static long MultiplyByScalarWideningUpper(int[] op1, int op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2); - if (left == right) - { - result = -1; - } - - return (int)result; - } + public static long MultiplyByScalarWideningUpperAndAdd(long[] op1, int[] op2, int op3, int i) => MultiplyAddWidening(op1[i], op2[i + op2.Length / 2], op3); - public static int CompareGreaterThan(int left, int right) - { - long result = 0; + public static long MultiplyByScalarWideningUpperAndSubtract(long[] op1, int[] op2, int op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3); - if (left > right) - { - result = -1; - } + public static long MultiplyWidening(int op1, int op2) => (long)((long)op1 * (long)op2); - return (int)result; - } + public static long MultiplyWideningAndSubtract(long op1, int op2, int op3) => (long)(op1 - MultiplyWidening(op2, op3)); - public static int CompareGreaterThanOrEqual(int left, int right) - { - long result = 0; + public static long MultiplyWideningUpper(int[] op1, int[] op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - if (left >= right) - { - result = -1; - } + public static long MultiplyWideningUpperAndAdd(long[] op1, int[] op2, int[] op3, int i) => MultiplyAddWidening(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - return (int)result; - } + public static long MultiplyWideningUpperAndSubtract(long[] op1, int[] op2, int[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static int CompareLessThan(int left, int right) + public static T ShiftLeft(T op1, ulong op2) where T : INumber { - long result = 0; - - if (left < right) + T two = T.One + T.One; + for (ulong i = 0; (op1 != T.Zero) && (i < op2); i++) { - result = -1; + op1 *= two; } - return (int)result; + return op1; } - public static int CompareLessThanOrEqual(int left, int right) + public static T ShiftRight(T op1, ulong op2) where T : INumber { - long result = 0; - - if (left <= right) + T two = T.One + T.One; + for (ulong i = 0; (op1 != T.Zero) && (i < op2); i++) { - result = -1; + op1 /= two; } - return (int)result; + return op1; } - public static int CompareTest(int left, int right) + public static T SignExtend(T n, int numBits, bool zeroExtend) where T : struct, IComparable, IConvertible, IBinaryInteger { - long result = 0; + // Get the underlying integer value + long value = long.CreateTruncating(n); - if ((left & right) != 0) + // Mask to extract the lowest numBits + long mask = (1L << numBits) - 1; + long lowestBits = value & mask; + + // Sign extension for signed integers + long signBitMask = 1L << (numBits - 1); + if (!zeroExtend && ((lowestBits & signBitMask) != 0)) { - result = -1; + // If sign bit is set, it's a negative number + return (T)Convert.ChangeType(-((~lowestBits & mask) + 1), typeof(T)); } - - return (int)result; - } - - public static uint CompareEqual(uint left, uint right) - { - long result = 0; - - if (left == right) + else { - result = -1; + // If sign bit is not set, it's a positive number + return (T)Convert.ChangeType(lowestBits, typeof(T)); } - - return (uint)result; } - public static uint CompareGreaterThan(uint left, uint right) - { - long result = 0; + public static int SubtractHighNarrowing(long op1, long op2) => HighNarrowing((long)(op1 - op2), round: false); - if (left > right) - { - result = -1; - } + public static long SubtractHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - return (uint)result; - } + public static int SubtractRoundedHighNarrowing(long op1, long op2) => HighNarrowing((long)(op1 - op2), round: true); - public static uint CompareGreaterThanOrEqual(uint left, uint right) - { - long result = 0; + public static long SubtractRoundedHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - if (left >= right) - { - result = -1; - } + public static long SubtractWidening(int op1, int op2) => (long)((long)op1 - (long)op2); - return (uint)result; - } + public static long SubtractWidening(long op1, int op2) => (long)(op1 - op2); - public static uint CompareLessThan(uint left, uint right) - { - long result = 0; + public static long SubtractWideningUpper(int[] op1, int[] op2, int i) => SubtractWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - if (left < right) - { - result = -1; - } + public static long SubtractWideningUpper(long[] op1, int[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); - return (uint)result; - } + public static long ZeroExtendWidening(int op1) => (long)(ulong)op1; - public static uint CompareLessThanOrEqual(uint left, uint right) - { - long result = 0; + public static long ZeroExtendWideningUpper(int[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); - if (left <= right) - { - result = -1; - } + public static ushort AbsoluteDifferenceWidening(byte op1, byte op2) => op1 < op2 ? (ushort)(op2 - op1) : (ushort)(op1 - op2); - return (uint)result; - } + public static ushort AbsoluteDifferenceWideningUpper(byte[] op1, byte[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static uint CompareTest(uint left, uint right) - { - long result = 0; + public static ushort AbsoluteDifferenceWideningAndAdd(ushort op1, byte op2, byte op3) => (ushort)(op1 + (ushort)AbsoluteDifferenceWidening(op2, op3)); - if ((left & right) != 0) - { - result = -1; - } + public static ushort AbsoluteDifferenceWideningUpperAndAdd(ushort[] op1, byte[] op2, byte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - return (uint)result; - } + public static ushort AbsoluteDifferenceWideningLowerAndAddEven(ushort[] op1, byte[] op2, byte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i * 2], op3[i * 2]); - public static long CompareEqual(long left, long right) - { - long result = 0; + public static ushort AbsoluteDifferenceWideningLowerAndAddOdd(ushort[] op1, byte[] op2, byte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - if (left == right) - { - result = -1; - } + public static ushort AbsoluteDifferenceWideningEven(byte[] op1, byte[] op2, int i) => AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - return (long)result; - } + public static ushort AbsoluteDifferenceWideningOdd(byte[] op1, byte[] op2, int i) => AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); - public static long CompareGreaterThan(long left, long right) - { - long result = 0; + public static ushort AddAcrossWidening(byte[] op1) => Reduce(AddWidening, op1); - if (left > right) - { - result = -1; - } + public static ulong AddAcrossWideningULong(byte[] op1) => Reduce(AddWidening, op1); - return (long)result; - } + public static ushort AddPairwiseWidening(byte[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); - public static long CompareGreaterThanOrEqual(long left, long right) - { - long result = 0; + public static ushort AddPairwiseWideningAndAdd(ushort[] op1, byte[] op2, int i) => (ushort)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); - if (left >= right) + public static byte AddHighNarrowingEven(ushort[] op1, ushort[] op2, int i) + { + if (i % 2 == 0) { - result = -1; + return (byte) ((op1[i / 2] + op2[i / 2]) >> (8 * sizeof(byte))); } - return (long)result; + return 0; } - public static long CompareLessThan(long left, long right) + public static byte AddHighNarrowingOdd(byte[] even, ushort[] op1, ushort[] op2, int i) { - long result = 0; - - if (left < right) + if (i % 2 == 1) { - result = -1; + return (byte) ((op1[(i - 1) / 2] + op2[(i - 1) / 2]) >> (8 * sizeof(byte))); } - return (long)result; + return even[i]; } - public static long CompareLessThanOrEqual(long left, long right) - { - long result = 0; + public static byte AddHighNarrowingUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - if (left <= right) - { - result = -1; - } + public static ushort AddRoundedHighNarrowingUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - return (long)result; - } + public static ushort AddWidening(byte op1, byte op2) => (ushort)((ushort)op1 + (ushort)op2); - public static long CompareTest(long left, long right) - { - long result = 0; + public static ushort AddWidening(ushort op1, byte op2) => (ushort)(op1 + op2); - if ((left & right) != 0) - { - result = -1; - } + public static ulong AddWidening(ulong op1, byte op2) => (ulong)(op1 + (ulong)op2); - return (long)result; - } + public static ushort AddWideningUpper(byte[] op1, byte[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static ulong CompareEqual(ulong left, ulong right) - { - long result = 0; + public static ushort AddWideningUpper(ushort[] op1, byte[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); - if (left == right) - { - result = -1; - } + public static byte ExtractNarrowing(ushort op1) => (byte)op1; - return (ulong)result; - } + public static byte ExtractNarrowingUpper(byte[] op1, ushort[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); - public static ulong CompareGreaterThan(ulong left, ulong right) - { - long result = 0; + public static byte FusedAddHalving(byte op1, byte op2) => (byte)((ushort)((ushort)op1 + (ushort)op2) >> 1); - if (left > right) - { - result = -1; - } + public static byte FusedAddRoundedHalving(byte op1, byte op2) => (byte)((ushort)((ushort)op1 + (ushort)op2 + 1) >> 1); - return (ulong)result; - } + public static byte FusedSubtractHalving(byte op1, byte op2) => (byte)((ushort)((ushort)op1 - (ushort)op2) >> 1); - public static ulong CompareGreaterThanOrEqual(ulong left, ulong right) - { - long result = 0; + public static ushort MultiplyByScalarWideningUpper(byte[] op1, byte op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2); - if (left >= right) - { - result = -1; - } + public static ushort MultiplyByScalarWideningUpperAndAdd(ushort[] op1, byte[] op2, byte op3, int i) => MultiplyAddWidening(op1[i], op2[i + op2.Length / 2], op3); - return (ulong)result; - } + public static ushort MultiplyByScalarWideningUpperAndSubtract(ushort[] op1, byte[] op2, byte op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3); - public static ulong CompareLessThan(ulong left, ulong right) - { - long result = 0; + public static ushort MultiplyWidening(byte op1, byte op2) => (ushort)((ushort)op1 * (ushort)op2); - if (left < right) - { - result = -1; - } + public static ushort MultiplyWideningAndSubtract(ushort op1, byte op2, byte op3) => (ushort)(op1 - MultiplyWidening(op2, op3)); - return (ulong)result; - } + public static ushort MultiplyWideningUpper(byte[] op1, byte[] op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static ulong CompareLessThanOrEqual(ulong left, ulong right) - { - long result = 0; + public static ushort MultiplyWideningUpperAndAdd(ushort[] op1, byte[] op2, byte[] op3, int i) => MultiplyAddWidening(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - if (left <= right) - { - result = -1; - } + public static ushort MultiplyWideningUpperAndSubtract(ushort[] op1, byte[] op2, byte[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - return (ulong)result; - } + public static byte SubtractHighNarrowing(ushort op1, ushort op2) => HighNarrowing((ushort)(op1 - op2), round: false); - public static ulong CompareTest(ulong left, ulong right) - { - long result = 0; + public static ushort SubtractHighNarrowingUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - if ((left & right) != 0) - { - result = -1; - } + public static byte SubtractRoundedHighNarrowing(ushort op1, ushort op2) => HighNarrowing((ushort)(op1 - op2), round: true); - return (ulong)result; - } + public static ushort SubtractRoundedHighNarrowingUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static double AbsoluteCompareGreaterThan(double left, double right) - { - long result = 0; + public static ushort SubtractWidening(byte op1, byte op2) => (ushort)((ushort)op1 - (ushort)op2); - left = Math.Abs(left); - right = Math.Abs(right); + public static ushort SubtractWidening(ushort op1, byte op2) => (ushort)(op1 - op2); - if (left > right) - { - result = -1; - } + public static ushort SubtractWideningUpper(byte[] op1, byte[] op2, int i) => SubtractWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - return BitConverter.Int64BitsToDouble(result); - } + public static ushort SubtractWideningUpper(ushort[] op1, byte[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); - public static float AbsoluteCompareGreaterThan(float left, float right) - { - int result = 0; + public static ushort ZeroExtendWidening(byte op1) => (ushort)(ushort)op1; - left = Math.Abs(left); - right = Math.Abs(right); + public static ushort ZeroExtendWideningUpper(byte[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); - if (left > right) - { - result = -1; - } + public static uint AbsoluteDifferenceWidening(ushort op1, ushort op2) => op1 < op2 ? (uint)(op2 - op1) : (uint)(op1 - op2); - return BitConverter.Int32BitsToSingle(result); - } + public static uint AbsoluteDifferenceWideningUpper(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static double AbsoluteCompareGreaterThanOrEqual(double left, double right) - { - long result = 0; + public static uint AbsoluteDifferenceWideningAndAdd(uint op1, ushort op2, ushort op3) => (uint)(op1 + (uint)AbsoluteDifferenceWidening(op2, op3)); - left = Math.Abs(left); - right = Math.Abs(right); + public static uint AbsoluteDifferenceWideningUpperAndAdd(uint[] op1, ushort[] op2, ushort[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - if (left >= right) - { - result = -1; - } + public static uint AbsoluteDifferenceWideningLowerAndAddEven(uint[] op1, ushort[] op2, ushort[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i * 2], op3[i * 2]); - return BitConverter.Int64BitsToDouble(result); - } + 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 float AbsoluteCompareGreaterThanOrEqual(float left, float right) - { - int result = 0; + public static uint AbsoluteDifferenceWideningEven(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - left = Math.Abs(left); - right = Math.Abs(right); + public static uint AbsoluteDifferenceWideningOdd(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); - if (left >= right) - { - result = -1; - } + public static uint AddAcrossWidening(ushort[] op1) => Reduce(AddWidening, op1); - return BitConverter.Int32BitsToSingle(result); - } + public static ulong AddAcrossWideningULong(ushort[] op1) => Reduce(AddWidening, op1); - public static double AbsoluteCompareLessThan(double left, double right) - { - long result = 0; + public static uint AddPairwiseWidening(ushort[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); - left = Math.Abs(left); - right = Math.Abs(right); + public static uint AddPairwiseWideningAndAdd(uint[] op1, ushort[] op2, int i) => (uint)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); - if (left < right) + public static ushort AddHighNarrowingEven(uint[] op1, uint[] op2, int i) + { + if (i % 2 == 0) { - result = -1; + return (ushort) ((op1[i / 2] + op2[i / 2]) >> (8 * sizeof(ushort))); } - return BitConverter.Int64BitsToDouble(result); + return 0; } - public static float AbsoluteCompareLessThan(float left, float right) + public static ushort AddHighNarrowingOdd(ushort[] even, uint[] op1, uint[] op2, int i) { - int result = 0; - - left = Math.Abs(left); - right = Math.Abs(right); - - if (left < right) + if (i % 2 == 1) { - result = -1; + return (ushort) ((op1[(i - 1) / 2] + op2[(i - 1) / 2]) >> (8 * sizeof(ushort))); } - return BitConverter.Int32BitsToSingle(result); + return even[i]; } - public static double AbsoluteCompareLessThanOrEqual(double left, double right) - { - long result = 0; + public static ushort AddHighNarrowingUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - left = Math.Abs(left); - right = Math.Abs(right); + public static uint AddRoundedHighNarrowingUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - if (left <= right) - { - result = -1; - } + public static uint AddWidening(ushort op1, ushort op2) => (uint)((uint)op1 + (uint)op2); - return BitConverter.Int64BitsToDouble(result); - } + public static uint AddWidening(uint op1, ushort op2) => (uint)(op1 + op2); - public static float AbsoluteCompareLessThanOrEqual(float left, float right) - { - int result = 0; + public static ulong AddWidening(ulong op1, ushort op2) => (ulong)(op1 + (ulong)op2); - left = Math.Abs(left); - right = Math.Abs(right); + public static uint AddWideningUpper(ushort[] op1, ushort[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - if (left <= right) - { - result = -1; - } + public static uint AddWideningUpper(uint[] op1, ushort[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); - return BitConverter.Int32BitsToSingle(result); - } + public static ushort ExtractNarrowing(uint op1) => (ushort)op1; + public static ushort ExtractNarrowingUpper(ushort[] op1, uint[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); - public static double SveAbsoluteCompareGreaterThan(double left, double right) - { - long result = 0; + public static ushort FusedAddHalving(ushort op1, ushort op2) => (ushort)((uint)((uint)op1 + (uint)op2) >> 1); - left = Math.Abs(left); - right = Math.Abs(right); + public static ushort FusedAddRoundedHalving(ushort op1, ushort op2) => (ushort)((uint)((uint)op1 + (uint)op2 + 1) >> 1); - if (left > right) - { - result = 1; - } + public static ushort FusedSubtractHalving(ushort op1, ushort op2) => (ushort)((uint)((uint)op1 - (uint)op2) >> 1); - return BitConverter.Int64BitsToDouble(result); - } + public static uint MultiplyByScalarWideningUpper(ushort[] op1, ushort op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2); - public static float SveAbsoluteCompareGreaterThan(float left, float right) - { - int result = 0; + public static uint MultiplyByScalarWideningUpperAndAdd(uint[] op1, ushort[] op2, ushort op3, int i) => MultiplyAddWidening(op1[i], op2[i + op2.Length / 2], op3); - left = Math.Abs(left); - right = Math.Abs(right); + public static uint MultiplyByScalarWideningUpperAndSubtract(uint[] op1, ushort[] op2, ushort op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3); - if (left > right) - { - result = 1; - } + public static uint MultiplyWidening(ushort op1, ushort op2) => (uint)((uint)op1 * (uint)op2); - return BitConverter.Int32BitsToSingle(result); - } + public static uint MultiplyWideningAndSubtract(uint op1, ushort op2, ushort op3) => (uint)(op1 - MultiplyWidening(op2, op3)); - public static double SveAbsoluteCompareGreaterThanOrEqual(double left, double right) - { - long result = 0; + public static uint MultiplyWideningUpper(ushort[] op1, ushort[] op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - left = Math.Abs(left); - right = Math.Abs(right); + public static uint MultiplyWideningUpperAndAdd(uint[] op1, ushort[] op2, ushort[] op3, int i) => MultiplyAddWidening(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - if (left >= right) - { - result = 1; - } + public static uint MultiplyWideningUpperAndSubtract(uint[] op1, ushort[] op2, ushort[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - return BitConverter.Int64BitsToDouble(result); - } + public static ushort SubtractHighNarrowing(uint op1, uint op2) => HighNarrowing((uint)(op1 - op2), round: false); - public static float SveAbsoluteCompareGreaterThanOrEqual(float left, float right) - { - int result = 0; + public static uint SubtractHighNarrowingUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - left = Math.Abs(left); - right = Math.Abs(right); + public static ushort SubtractRoundedHighNarrowing(uint op1, uint op2) => HighNarrowing((uint)(op1 - op2), round: true); - if (left >= right) - { - result = 1; - } + public static uint SubtractRoundedHighNarrowingUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - return BitConverter.Int32BitsToSingle(result); - } + public static uint SubtractWidening(ushort op1, ushort op2) => (uint)((uint)op1 - (uint)op2); - public static double SveAbsoluteCompareLessThan(double left, double right) - { - long result = 0; + public static uint SubtractWidening(uint op1, ushort op2) => (uint)(op1 - op2); - left = Math.Abs(left); - right = Math.Abs(right); + public static uint SubtractWideningUpper(ushort[] op1, ushort[] op2, int i) => SubtractWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - if (left < right) - { - result = 1; - } + public static uint SubtractWideningUpper(uint[] op1, ushort[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); - return BitConverter.Int64BitsToDouble(result); - } + public static uint ZeroExtendWidening(ushort op1) => (uint)(uint)op1; - public static float SveAbsoluteCompareLessThan(float left, float right) - { - int result = 0; + public static uint ZeroExtendWideningUpper(ushort[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); - left = Math.Abs(left); - right = Math.Abs(right); + public static ulong AbsoluteDifferenceWidening(uint op1, uint op2) => op1 < op2 ? (ulong)(op2 - op1) : (ulong)(op1 - op2); - if (left < right) - { - result = 1; - } + public static ulong AbsoluteDifferenceWideningUpper(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - return BitConverter.Int32BitsToSingle(result); - } + public static ulong AbsoluteDifferenceWideningAndAdd(ulong op1, uint op2, uint op3) => (ulong)(op1 + (ulong)AbsoluteDifferenceWidening(op2, op3)); - public static double SveAbsoluteCompareLessThanOrEqual(double left, double right) - { - long result = 0; + public static ulong AbsoluteDifferenceWideningUpperAndAdd(ulong[] op1, uint[] op2, uint[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - left = Math.Abs(left); - right = Math.Abs(right); + public static ulong AbsoluteDifferenceWideningLowerAndAddEven(ulong[] op1, uint[] op2, uint[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i * 2], op3[i * 2]); - if (left <= right) + 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 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); + + public static ulong AddPairwiseWidening(uint[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); + + public static ulong AddPairwiseWideningAndAdd(ulong[] op1, uint[] op2, int i) => (ulong)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); + + public static uint AddHighNarrowingEven(ulong[] op1, ulong[] op2, int i) + { + if (i % 2 == 0) { - result = 1; + return (uint) ((op1[i / 2] + op2[i / 2]) >> (8 * sizeof(uint))); } - return BitConverter.Int64BitsToDouble(result); + return 0; } - public static float SveAbsoluteCompareLessThanOrEqual(float left, float right) + public static uint AddHighNarrowingOdd(uint[] even, ulong[] op1, ulong[] op2, int i) { - int result = 0; - - left = Math.Abs(left); - right = Math.Abs(right); - - if (left <= right) + if (i % 2 == 1) { - result = 1; + return (uint) ((op1[(i - 1) / 2] + op2[(i - 1) / 2]) >> (8 * sizeof(uint))); } - return BitConverter.Int32BitsToSingle(result); + return even[i]; } - public static double SveCompareEqual(double left, double right) => BitConverter.Int64BitsToDouble((left == right) ? 1 : 0); - public static float SveCompareEqual(float left, float right) => BitConverter.Int32BitsToSingle((left == right) ? 1 : 0); - public static sbyte SveCompareEqual(sbyte left, sbyte right) => (sbyte)((left == right) ? 1 : 0); - public static byte SveCompareEqual(byte left, byte right) => (byte)((left == right) ? 1 : 0); - public static short SveCompareEqual(short left, short right) => (short)((left == right) ? 1 : 0); - public static ushort SveCompareEqual(ushort left, ushort right) => (ushort)((left == right) ? 1 : 0); - public static int SveCompareEqual(int left, int right) => (int)((left == right) ? 1 : 0); - public static uint SveCompareEqual(uint left, uint right) => (uint)((left == right) ? 1 : 0); - public static long SveCompareEqual(long left, long right) => (long)((left == right) ? 1 : 0); - public static ulong SveCompareEqual(ulong left, ulong right) => (ulong)((left == right) ? 1 : 0); + public static uint AddHighNarrowingUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static double SveCompareNotEqual(double left, double right) => BitConverter.Int64BitsToDouble((left != right) ? 1 : 0); - public static float SveCompareNotEqual(float left, float right) => BitConverter.Int32BitsToSingle((left != right) ? 1 : 0); - public static sbyte SveCompareNotEqual(sbyte left, sbyte right) => (sbyte)((left != right) ? 1 : 0); - public static byte SveCompareNotEqual(byte left, byte right) => (byte)((left != right) ? 1 : 0); - public static short SveCompareNotEqual(short left, short right) => (short)((left != right) ? 1 : 0); - public static ushort SveCompareNotEqual(ushort left, ushort right) => (ushort)((left != right) ? 1 : 0); - public static int SveCompareNotEqual(int left, int right) => (int)((left != right) ? 1 : 0); - public static uint SveCompareNotEqual(uint left, uint right) => (uint)((left != right) ? 1 : 0); - public static long SveCompareNotEqual(long left, long right) => (long)((left != right) ? 1 : 0); - public static ulong SveCompareNotEqual(ulong left, ulong right) => (ulong)((left != right) ? 1 : 0); + public static ulong AddRoundedHighNarrowingUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static double SveCompareGreaterThan(double left, double right) => BitConverter.Int64BitsToDouble((left > right) ? 1 : 0); - public static float SveCompareGreaterThan(float left, float right) => BitConverter.Int32BitsToSingle((left > right) ? 1 : 0); - public static sbyte SveCompareGreaterThan(sbyte left, sbyte right) => (sbyte)((left > right) ? 1 : 0); - public static byte SveCompareGreaterThan(byte left, byte right) => (byte)((left > right) ? 1 : 0); - public static short SveCompareGreaterThan(short left, short right) => (short)((left > right) ? 1 : 0); - public static ushort SveCompareGreaterThan(ushort left, ushort right) => (ushort)((left > right) ? 1 : 0); - public static int SveCompareGreaterThan(int left, int right) => (int)((left > right) ? 1 : 0); - public static uint SveCompareGreaterThan(uint left, uint right) => (uint)((left > right) ? 1 : 0); - public static long SveCompareGreaterThan(long left, long right) => (long)((left > right) ? 1 : 0); - public static ulong SveCompareGreaterThan(ulong left, ulong right) => (ulong)((left > right) ? 1 : 0); + public static ulong AddWidening(uint op1, uint op2) => (ulong)((ulong)op1 + (ulong)op2); - public static double SveCompareGreaterThanOrEqual(double left, double right) => BitConverter.Int64BitsToDouble((left >= right) ? 1 : 0); - public static float SveCompareGreaterThanOrEqual(float left, float right) => BitConverter.Int32BitsToSingle((left >= right) ? 1 : 0); - public static sbyte SveCompareGreaterThanOrEqual(sbyte left, sbyte right) => (sbyte)((left >= right) ? 1 : 0); - public static byte SveCompareGreaterThanOrEqual(byte left, byte right) => (byte)((left >= right) ? 1 : 0); - public static short SveCompareGreaterThanOrEqual(short left, short right) => (short)((left >= right) ? 1 : 0); - public static ushort SveCompareGreaterThanOrEqual(ushort left, ushort right) => (ushort)((left >= right) ? 1 : 0); - public static int SveCompareGreaterThanOrEqual(int left, int right) => (int)((left >= right) ? 1 : 0); - public static uint SveCompareGreaterThanOrEqual(uint left, uint right) => (uint)((left >= right) ? 1 : 0); - public static long SveCompareGreaterThanOrEqual(long left, long right) => (long)((left >= right) ? 1 : 0); - public static ulong SveCompareGreaterThanOrEqual(ulong left, ulong right) => (ulong)((left >= right) ? 1 : 0); + public static ulong AddWidening(ulong op1, uint op2) => (ulong)(op1 + op2); - public static double SveCompareLessThan(double left, double right) => BitConverter.Int64BitsToDouble((left < right) ? 1 : 0); - public static float SveCompareLessThan(float left, float right) => BitConverter.Int32BitsToSingle((left < right) ? 1 : 0); - public static sbyte SveCompareLessThan(sbyte left, sbyte right) => (sbyte)((left < right) ? 1 : 0); - public static byte SveCompareLessThan(byte left, byte right) => (byte)((left < right) ? 1 : 0); - public static short SveCompareLessThan(short left, short right) => (short)((left < right) ? 1 : 0); - public static ushort SveCompareLessThan(ushort left, ushort right) => (ushort)((left < right) ? 1 : 0); - public static int SveCompareLessThan(int left, int right) => (int)((left < right) ? 1 : 0); - public static uint SveCompareLessThan(uint left, uint right) => (uint)((left < right) ? 1 : 0); - public static long SveCompareLessThan(long left, long right) => (long)((left < right) ? 1 : 0); - public static ulong SveCompareLessThan(ulong left, ulong right) => (ulong)((left < right) ? 1 : 0); + public static ulong AddWideningUpper(uint[] op1, uint[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static double SveCompareLessThanOrEqual(double left, double right) => BitConverter.Int64BitsToDouble((left <= right) ? 1 : 0); - public static float SveCompareLessThanOrEqual(float left, float right) => BitConverter.Int32BitsToSingle((left <= right) ? 1 : 0); - public static sbyte SveCompareLessThanOrEqual(sbyte left, sbyte right) => (sbyte)((left <= right) ? 1 : 0); - public static byte SveCompareLessThanOrEqual(byte left, byte right) => (byte)((left <= right) ? 1 : 0); - public static short SveCompareLessThanOrEqual(short left, short right) => (short)((left <= right) ? 1 : 0); - public static ushort SveCompareLessThanOrEqual(ushort left, ushort right) => (ushort)((left <= right) ? 1 : 0); - public static int SveCompareLessThanOrEqual(int left, int right) => (int)((left <= right) ? 1 : 0); - public static uint SveCompareLessThanOrEqual(uint left, uint right) => (uint)((left <= right) ? 1 : 0); - public static long SveCompareLessThanOrEqual(long left, long right) => (long)((left <= right) ? 1 : 0); - public static ulong SveCompareLessThanOrEqual(ulong left, ulong right) => (ulong)((left <= right) ? 1 : 0); + public static ulong AddWideningUpper(ulong[] op1, uint[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); - public static double SveCompareUnordered(double left, double right) => BitConverter.Int64BitsToDouble((double.IsNaN(left) || double.IsNaN(right)) ? 1 : 0); - public static float SveCompareUnordered(float left, float right) => BitConverter.Int32BitsToSingle((float.IsNaN(left) || float.IsNaN(right)) ? 1 : 0); + public static uint ExtractNarrowing(ulong op1) => (uint)op1; - public static double CompareEqual(double left, double right) - { - long result = 0; + public static uint ExtractNarrowingUpper(uint[] op1, ulong[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); - if (left == right) - { - result = -1; - } + public static uint FusedAddHalving(uint op1, uint op2) => (uint)((ulong)((ulong)op1 + (ulong)op2) >> 1); - return BitConverter.Int64BitsToDouble(result); + public static ulong FusedAddHalving(ulong op1, ulong op2) + { + ulong sum = op1 + op2; + bool carry = sum < op1; + return (sum >> 1) + (carry ? 1UL << 63 : 0); + } + public static long FusedAddHalving(long op1, long op2) + { + long sum = op1 + op2; + bool carry = sum < op1; + return (sum >> 1) + (carry ? 1L << 63 : 0); } - public static float CompareEqual(float left, float right) + public static long FusedSubtractHalving(long op1, long op2) { - int result = 0; + ulong uop1 = (ulong)op1; + ulong uop2 = (ulong)op2; - if (left == right) - { - result = -1; - } + ulong udiff = uop1 - uop2; + long sdiff = unchecked((long)udiff); - return BitConverter.Int32BitsToSingle(result); + return sdiff >> 1; } - public static double CompareGreaterThan(double left, double right) + public static ulong FusedSubtractHalving(ulong op1, ulong op2) { - long result = 0; + ulong diff = op1 - op2; + bool overflow = op1 < op2; + return (diff >> 1) + (overflow ? 1UL << 63 : 0); + } - if (left > right) - { - result = -1; - } - return BitConverter.Int64BitsToDouble(result); - } + public static uint FusedAddRoundedHalving(uint op1, uint op2) => (uint)((ulong)((ulong)op1 + (ulong)op2 + 1) >> 1); - public static float CompareGreaterThan(float left, float right) - { - int result = 0; + public static uint FusedSubtractHalving(uint op1, uint op2) => (uint)((ulong)((ulong)op1 - (ulong)op2) >> 1); - if (left > right) - { - result = -1; - } + public static ulong MultiplyByScalarWideningUpper(uint[] op1, uint op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2); - return BitConverter.Int32BitsToSingle(result); - } + public static ulong MultiplyByScalarWideningUpperAndAdd(ulong[] op1, uint[] op2, uint op3, int i) => MultiplyAddWidening(op1[i], op2[i + op2.Length / 2], op3); - public static double CompareGreaterThanOrEqual(double left, double right) - { - long result = 0; + public static ulong MultiplyByScalarWideningUpperAndSubtract(ulong[] op1, uint[] op2, uint op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3); - if (left >= right) - { - result = -1; - } + public static ulong MultiplyWidening(uint op1, uint op2) => (ulong)((ulong)op1 * (ulong)op2); - return BitConverter.Int64BitsToDouble(result); - } + public static ulong MultiplyWideningAndSubtract(ulong op1, uint op2, uint op3) => (ulong)(op1 - MultiplyWidening(op2, op3)); - public static float CompareGreaterThanOrEqual(float left, float right) - { - int result = 0; + public static ulong MultiplyWideningUpper(uint[] op1, uint[] op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - if (left >= right) - { - result = -1; - } + public static ulong MultiplyWideningUpperAndAdd(ulong[] op1, uint[] op2, uint[] op3, int i) => MultiplyAddWidening(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - return BitConverter.Int32BitsToSingle(result); - } + public static ulong MultiplyWideningUpperAndSubtract(ulong[] op1, uint[] op2, uint[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static double CompareLessThan(double left, double right) - { - long result = 0; + public static uint SubtractHighNarrowing(ulong op1, ulong op2) => HighNarrowing((ulong)(op1 - op2), round: false); - if (left < right) - { - result = -1; - } + public static ulong SubtractHighNarrowingUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - return BitConverter.Int64BitsToDouble(result); - } + public static uint SubtractRoundedHighNarrowing(ulong op1, ulong op2) => HighNarrowing((ulong)(op1 - op2), round: true); - public static float CompareLessThan(float left, float right) + public static ulong SubtractRoundedHighNarrowingUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + + public static ulong SubtractWidening(uint op1, uint op2) => (ulong)((ulong)op1 - (ulong)op2); + + public static ulong SubtractWidening(ulong op1, uint op2) => (ulong)(op1 - op2); + + public static ulong SubtractWideningUpper(uint[] op1, uint[] op2, int i) => SubtractWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + + public static ulong SubtractWideningUpper(ulong[] op1, uint[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); + + public static ulong ZeroExtendWidening(uint op1) => (ulong)(ulong)op1; + + public static ulong ZeroExtendWideningUpper(uint[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + + private static ulong Reduce(Func reduceOp, uint[] op1) { - int result = 0; + ulong acc = op1[0]; - if (left < right) + for (int i = 1; i < op1.Length; i++) { - result = -1; + acc = reduceOp(acc, op1[i]); } - return BitConverter.Int32BitsToSingle(result); + return acc; } - public static double CompareLessThanOrEqual(double left, double right) + public static double AddWidening(double op1, float op2) => (double)(op1 + (double)op2); + + + private static bool SignedSatQ(short val, out sbyte result) { - long result = 0; + bool saturated = false; - if (left <= right) + if (val > sbyte.MaxValue) { - result = -1; + result = sbyte.MaxValue; + saturated = true; + } + else if (val < sbyte.MinValue) + { + result = sbyte.MinValue; + saturated = true; + } + else + { + result = (sbyte)val; } - return BitConverter.Int64BitsToDouble(result); + return saturated; } - public static float CompareLessThanOrEqual(float left, float right) + private static bool UnsignedSatQ(short val, out byte result) { - int result = 0; + bool saturated = false; - if (left <= right) + if (val > byte.MaxValue) { - result = -1; + result = byte.MaxValue; + saturated = true; + } + else if (val < 0) + { + result = 0; + saturated = true; + } + else + { + result = (byte)val; } - return BitConverter.Int32BitsToSingle(result); + return saturated; } - public static double CompareTest(double left, double right) + private static bool UnsignedSatQ(ushort val, out byte result) { - long result = 0; + bool saturated = false; - if ((BitConverter.DoubleToInt64Bits(left) & BitConverter.DoubleToInt64Bits(right)) != 0) + if (val > byte.MaxValue) { - result = -1; + result = byte.MaxValue; + saturated = true; + } + else if (val < 0) + { + result = 0; + saturated = true; + } + else + { + result = (byte)val; } - return BitConverter.Int64BitsToDouble(result); + return saturated; } - public static float CompareTest(float left, float right) + private static bool SatQ(short val, out sbyte result, bool reinterpretAsUnsigned = false) { - int result = 0; + bool saturated; - if ((BitConverter.SingleToInt32Bits(left) & BitConverter.SingleToInt32Bits(right)) != 0) + if (reinterpretAsUnsigned) { - result = -1; + byte res; + saturated = UnsignedSatQ((ushort)val, out res); + result = (sbyte)res; + } + else + { + saturated = SignedSatQ(val, out result); } - return BitConverter.Int32BitsToSingle(result); + return saturated; } - public static byte Abs(sbyte value) => value < 0 ? (byte)-value : (byte)value; + private static bool SatQ(ushort val, out byte result) => UnsignedSatQ(val, out result); - public static ushort Abs(short value) => value < 0 ? (ushort)-value : (ushort)value; + public static sbyte ExtractNarrowingSaturate(short op1) + { + sbyte result; - public static uint Abs(int value) => value < 0 ? (uint)-value : (uint)value; + SatQ(op1, out result); - public static ulong Abs(long value) => value < 0 ? (ulong)-value : (ulong)value; + return result; + } - public static float Abs(float value) => Math.Abs(value); + public static sbyte ExtractNarrowingSaturateUpper(sbyte[] op1, short[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturate(op2[i - op1.Length]); - public static double Abs(double value) => Math.Abs(value); + public static byte ExtractNarrowingSaturate(ushort op1) + { + byte result; - public static float Divide(float op1, float op2) => op1 / op2; + SatQ(op1, out result); - public static double Divide(double op1, double op2) => op1 / op2; + return result; + } - public static float Scale(float op1, int op2) => op1 * MathF.Pow((float)2.0, op2); + public static byte ExtractNarrowingSaturateUpper(byte[] op1, ushort[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturate(op2[i - op1.Length]); - public static double Scale(double op1, long op2) => op1 * Math.Pow(2.0, op2); + public static byte ExtractNarrowingSaturateUnsigned(short op1) + { + byte result; - public static float Sqrt(float value) => MathF.Sqrt(value); + UnsignedSatQ(op1, out result); - public static double Sqrt(double value) => Math.Sqrt(value); + return result; + } - public static long AbsoluteDifference(long op1, long op2) => op1 < op2 ? (long)(op2 - op1) : (long)(op1 - op2); + public static byte ExtractNarrowingSaturateUnsignedUpper(byte[] op1, short[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturateUnsigned(op2[i - op1.Length]); - public static long AbsoluteDifferenceAdd(long op1, long op2, long op3) => (long)(op1 + AbsoluteDifference(op2, op3)); + private static (short val, bool ovf) MultiplyDoublingOvf(sbyte op1, sbyte op2, bool rounding, short op3, bool subOp) + { + short product = (short)((short)op1 * (short)op2); - public static byte AbsoluteDifference(sbyte op1, sbyte op2) => op1 < op2 ? (byte)(op2 - op1) : (byte)(op1 - op2); + bool dblOvf; + (product, dblOvf) = AddOvf(product, product); - public static sbyte AbsoluteDifferenceAdd(sbyte op1, sbyte op2, sbyte op3) => (sbyte)(op1 + AbsoluteDifference(op2, op3)); + bool addOvf; + short accum; - public static ushort AbsoluteDifference(short op1, short op2) => op1 < op2 ? (ushort)(op2 - op1) : (ushort)(op1 - op2); + if (subOp) + { + (accum, addOvf) = SubtractOvf(op3, product); + } + else + { + (accum, addOvf) = AddOvf(op3, product); + } - public static short AbsoluteDifferenceAdd(short op1, short op2, short op3) => (short)(op1 + AbsoluteDifference(op2, op3)); + short roundConst = 0; - public static uint AbsoluteDifference(int op1, int op2) => op1 < op2 ? (uint)(op2 - op1) : (uint)(op1 - op2); + if (rounding) + { + roundConst = (short)1 << (8 * sizeof(sbyte) - 1); + } - public static int AbsoluteDifferenceAdd(int op1, int op2, int op3) => (int)(op1 + AbsoluteDifference(op2, op3)); + bool rndOvf; + short result; - public static byte AbsoluteDifference(byte op1, byte op2) => op1 < op2 ? (byte)(op2 - op1) : (byte)(op1 - op2); + (result, rndOvf) = AddOvf(accum, roundConst); - public static byte AbsoluteDifferenceAdd(byte op1, byte op2, byte op3) => (byte)(op1 + AbsoluteDifference(op2, op3)); + return (result, addOvf ^ rndOvf ^ dblOvf); + } - public static ushort AbsoluteDifference(ushort op1, ushort op2) => op1 < op2 ? (ushort)(op2 - op1) : (ushort)(op1 - op2); + private static sbyte SaturateHigh(short val, bool ovf) + { + if (ovf) + { + return val < 0 ? sbyte.MaxValue : sbyte.MinValue; + } - public static ulong AbsoluteDifference(ulong op1, ulong op2) => op1 < op2 ? (ulong)(op2 - op1) : (ulong)(op1 - op2); + return (sbyte)UnsignedShift(val, (short)(-8 * sizeof(sbyte))); + } - public static ulong AbsoluteDifferenceAdd(ulong op1, ulong op2, ulong op3) => (ulong)(op1 + AbsoluteDifference(op2, op3)); + public static sbyte MultiplyDoublingSaturateHigh(sbyte op1, sbyte op2) + { + var (val, ovf) = MultiplyDoublingOvf(op1, op2, rounding: false, (short)0, subOp: false); - public static ushort AbsoluteDifferenceAdd(ushort op1, ushort op2, ushort op3) => (ushort)(op1 + AbsoluteDifference(op2, op3)); + return SaturateHigh(val, ovf); + } - public static uint AbsoluteDifference(uint op1, uint op2) => op1 < op2 ? (uint)(op2 - op1) : (uint)(op1 - op2); + public static sbyte MultiplyRoundedDoublingSaturateHigh(sbyte op1, sbyte op2) + { + var (val, ovf) = MultiplyDoublingOvf(op1, op2, rounding: true, (short)0, subOp: false); - public static uint AbsoluteDifferenceAdd(uint op1, uint op2, uint op3) => (uint)(op1 + AbsoluteDifference(op2, op3)); + return SaturateHigh(val, ovf); + } - public static ushort AbsoluteDifferenceWidening(sbyte op1, sbyte op2) => op1 < op2 ? (ushort)(op2 - op1) : (ushort)(op1 - op2); + public static short MultiplyDoublingWideningSaturate(sbyte op1, sbyte op2) + { + var (product, ovf) = MultiplyDoublingOvf(op1, op2, rounding: false, (short)0, subOp: false); - public static ushort AbsoluteDifferenceWideningUpper(sbyte[] op1, sbyte[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + if (ovf) + { + return product < 0 ? sbyte.MaxValue : sbyte.MinValue; + } - public static short AbsoluteDifferenceWideningAndAdd(short op1, sbyte op2, sbyte op3) => (short)(op1 + (short)AbsoluteDifferenceWidening(op2, op3)); + return product; + } - public static short AbsoluteDifferenceWideningUpperAndAdd(short[] op1, sbyte[] op2, sbyte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static sbyte MultiplyRoundedDoublingAndAddSaturateHigh(sbyte op1, sbyte op2, sbyte op3) + { + short addend = UnsignedShift((short)op1, (short)(8 * sizeof(sbyte))); - public static short AbsoluteDifferenceWideningLowerAndAddEven(short[] op1, sbyte[] op2, sbyte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i * 2], op3[i * 2]); - - 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 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); - - public static long AddAcrossWideningLong(sbyte[] op1) => Reduce(AddWidening, op1); - - public static short AddPairwiseWidening(sbyte[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); - - public static short AddPairwiseWideningAndAdd(short[] op1, sbyte[] op2, int i) => (short)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); + var (val, ovf) = MultiplyDoublingOvf(op2, op3, rounding: true, addend, subOp: false); - private static sbyte HighNarrowing(short op1, bool round) - { - ushort roundConst = 0; - if (round) - { - roundConst = (ushort)1 << (8 * sizeof(sbyte) - 1); - } - return (sbyte)(((ushort)op1 + roundConst) >> (8 * sizeof(sbyte))); + return SaturateHigh(val, ovf); } - public static sbyte AddHighNarrowingEven(short[] op1, short[] op2, int i) + public static sbyte MultiplyRoundedDoublingAndSubtractSaturateHigh(sbyte op1, sbyte op2, sbyte op3) { - if (i % 2 == 0) - { - return (sbyte) ((op1[i / 2] + op2[i / 2]) >> (8 * sizeof(sbyte))); - } + short minuend = UnsignedShift((short)op1, (short)(8 * sizeof(sbyte))); - return 0; + var (val, ovf) = MultiplyDoublingOvf(op2, op3, rounding: true, minuend, subOp: true); + + return SaturateHigh(val, ovf); } - public static sbyte AddHighNarrowingOdd(sbyte[] even, short[] op1, short[] op2, int i) + public static sbyte[] MultiplyAddRoundedDoublingSaturateHighRotateComplex(sbyte[] op1, sbyte[] op2, sbyte[] op3, byte rot) { - if (i % 2 == 1) + for (int i = 0; i < op1.Length; i += 2) { - return (sbyte) ((op1[(i - 1) / 2] + op2[(i - 1) / 2]) >> (8 * sizeof(sbyte))); + int real = i; + int img = i + 1; + (sbyte ans1, sbyte ans2) = rot switch + { + 0 => (MultiplyRoundedDoublingAndAddSaturateHigh(op1[real], op2[real], op3[real]), MultiplyRoundedDoublingAndAddSaturateHigh(op1[img], op2[real], op3[img])), + 1 => (MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[real], op2[img], op3[img]), MultiplyRoundedDoublingAndAddSaturateHigh(op1[img], op2[img], op3[real])), + 2 => (MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[real], op2[real], op3[real]), MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[img], op2[real], op3[img])), + 3 => (MultiplyRoundedDoublingAndAddSaturateHigh(op1[real], op2[img], op3[img]), MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[img], op2[img], op3[real])), + _ => (default, default) + }; + + op1[real] = ans1; + op1[img] = ans2; } - return even[i]; + return op1; } - public static sbyte AddHighNarrowing(short op1, short op2) => HighNarrowing((short)(op1 + op2), round: false); - - public static sbyte AddHighNarrowingUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - - public static sbyte AddRoundedHighNarrowing(short op1, short op2) => HighNarrowing((short)(op1 + op2), round: true); - - public static short AddRoundedHighNarrowingUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - - public static short AddWidening(sbyte op1, sbyte op2) => (short)((short)op1 + (short)op2); - - public static short AddWidening(short op1, sbyte op2) => (short)(op1 + op2); - - public static long AddWidening(long op1, sbyte op2) => (long)(op1 + (long)op2); - - public static short AddWideningUpper(sbyte[] op1, sbyte[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static short MultiplyDoublingWideningAndAddSaturate(short op1, sbyte op2, sbyte op3) => AddSaturate(op1, MultiplyDoublingWideningSaturate(op2, op3)); - public static short AddWideningUpper(short[] op1, sbyte[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); + public static short MultiplyDoublingWideningAndSubtractSaturate(short op1, sbyte op2, sbyte op3) => SubtractSaturate(op1, MultiplyDoublingWideningSaturate(op2, op3)); - public static sbyte BooleanNot(sbyte value) => (sbyte)(value == 0 ? 1 : 0); + public static short MultiplyDoublingWideningSaturateUpperByScalar(sbyte[] op1, sbyte op2, int i) => MultiplyDoublingWideningSaturate(op1[i + op1.Length / 2], op2); - public static byte BooleanNot(byte value) => (byte)(value == 0 ? 1 : 0); + public static short MultiplyDoublingWideningUpperByScalarAndAddSaturate(short[] op1, sbyte[] op2, sbyte op3, int i) => MultiplyDoublingWideningAndAddSaturate(op1[i], op2[i + op2.Length / 2], op3); - public static short BooleanNot(short value) => (short)(value == 0 ? 1 : 0); + public static short MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(short[] op1, sbyte[] op2, sbyte op3, int i) => MultiplyDoublingWideningAndSubtractSaturate(op1[i], op2[i + op2.Length / 2], op3); - public static ushort BooleanNot(ushort value) => (ushort)(value == 0 ? 1 : 0); + public static short MultiplyDoublingWideningSaturateUpper(sbyte[] op1, sbyte[] op2, int i) => MultiplyDoublingWideningSaturate(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static int BooleanNot(int value) => (int)(value == 0 ? 1 : 0); + public static short MultiplyDoublingWideningUpperAndAddSaturate(short[] op1, sbyte[] op2, sbyte[] op3, int i) => MultiplyDoublingWideningAndAddSaturate(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static uint BooleanNot(uint value) => (uint)(value == 0 ? 1 : 0); + public static short MultiplyDoublingWideningUpperAndSubtractSaturate(short[] op1, sbyte[] op2, sbyte[] op3, int i) => MultiplyDoublingWideningAndSubtractSaturate(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static long BooleanNot(long value) => (long)(value == 0 ? 1 : 0); + public static short ShiftLeftLogicalWidening(sbyte op1, byte op2) => UnsignedShift((short)op1, (short)op2); - public static ulong BooleanNot(ulong value) => (ulong)(value == 0 ? 1 : 0); + public static ushort ShiftLeftLogicalWidening(byte op1, byte op2) => UnsignedShift((ushort)op1, (short)op2); - public static sbyte ExtractNarrowing(short op1) => (sbyte)op1; + public static short ShiftLeftLogicalWideningUpper(sbyte[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); - public static sbyte ExtractNarrowingUpper(sbyte[] op1, short[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); + public static ushort ShiftLeftLogicalWideningUpper(byte[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); - public static sbyte FusedAddHalving(sbyte op1, sbyte op2) => (sbyte)((ushort)((short)op1 + (short)op2) >> 1); + public static sbyte ShiftRightArithmeticRoundedNarrowingSaturate(short op1, byte op2) + { + sbyte result; - public static sbyte FusedAddRoundedHalving(sbyte op1, sbyte op2) => (sbyte)((ushort)((short)op1 + (short)op2 + 1) >> 1); + SatQ(SignedShift(op1, (short)(-op2), rounding: true), out result); - public static sbyte FusedSubtractHalving(sbyte op1, sbyte op2) => (sbyte)((ushort)((short)op1 - (short)op2) >> 1); + return result; + } - public static short MultiplyByScalarWideningUpper(sbyte[] op1, sbyte op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2); + public static byte ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(short op1, byte op2) + { + byte result; - public static short MultiplyByScalarWideningUpperAndAdd(short[] op1, sbyte[] op2, sbyte op3, int i) => MultiplyWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3); + UnsignedSatQ(SignedShift(op1, (short)(-op2), rounding: true), out result); - public static short MultiplyByScalarWideningUpperAndSubtract(short[] op1, sbyte[] op2, sbyte op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3); + return result; + } - public static short MultiplyWidening(sbyte op1, sbyte op2) => (short)((short)op1 * (short)op2); + public static byte ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(byte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(op2[i - op1.Length], op3); - public static short MultiplyWideningAndAdd(short op1, sbyte op2, sbyte op3) => (short)(op1 + MultiplyWidening(op2, op3)); + public static sbyte ShiftRightArithmeticRoundedNarrowingSaturateUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightArithmeticRoundedNarrowingSaturate(op2[i - op1.Length], op3); - public static short MultiplyWideningAndSubtract(short op1, sbyte op2, sbyte op3) => (short)(op1 - MultiplyWidening(op2, op3)); + public static sbyte ShiftRightArithmeticNarrowingSaturate(short op1, byte op2) + { + sbyte result; - public static short MultiplyWideningUpper(sbyte[] op1, sbyte[] op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + SatQ(SignedShift(op1, (short)(-op2)), out result); - public static short MultiplyWideningUpperAndAdd(short[] op1, sbyte[] op2, sbyte[] op3, int i) => MultiplyWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + return result; + } - public static short MultiplyWideningUpperAndSubtract(short[] op1, sbyte[] op2, sbyte[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static byte ShiftRightArithmeticNarrowingSaturateUnsigned(short op1, byte op2) + { + byte result; - public static sbyte SubtractHighNarrowing(short op1, short op2) => HighNarrowing((short)(op1 - op2), round: false); + UnsignedSatQ(SignedShift(op1, (short)(-op2)), out result); - public static short SubtractHighNarrowingUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + return result; + } - public static sbyte SubtractRoundedHighNarrowing(short op1, short op2) => HighNarrowing((short)(op1 - op2), round: true); + public static byte ShiftRightArithmeticNarrowingSaturateUnsignedUpper(byte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightArithmeticNarrowingSaturateUnsigned(op2[i - op1.Length], op3); - public static short SubtractRoundedHighNarrowingUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + public static sbyte ShiftRightArithmeticNarrowingSaturateUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightArithmeticNarrowingSaturate(op2[i - op1.Length], op3); - public static short SubtractWidening(sbyte op1, sbyte op2) => (short)((short)op1 - (short)op2); + public static sbyte ShiftRightLogicalNarrowing(short op1, byte op2) => (sbyte)UnsignedShift(op1, (short)(-op2)); - public static short SubtractWidening(short op1, sbyte op2) => (short)(op1 - op2); + public static byte ShiftRightLogicalNarrowing(ushort op1, byte op2) => (byte)UnsignedShift(op1, (short)(-op2)); - public static short SubtractWideningUpper(sbyte[] op1, sbyte[] op2, int i) => SubtractWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static sbyte ShiftRightLogicalRoundedNarrowing(short op1, byte op2) => (sbyte)UnsignedShift(op1, (short)(-op2), rounding: true); - public static short SubtractWideningUpper(short[] op1, sbyte[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); + public static byte ShiftRightLogicalRoundedNarrowing(ushort op1, byte op2) => (byte)UnsignedShift(op1, (short)(-op2), rounding: true); - public static short ZeroExtendWidening(sbyte op1) => (short)(ushort)op1; + public static sbyte ShiftRightLogicalRoundedNarrowingUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); - public static short ZeroExtendWideningUpper(sbyte[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + public static byte ShiftRightLogicalRoundedNarrowingUpper(byte[] op1, ushort[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); - private static short Reduce(Func reduceOp, sbyte[] op1) + public static sbyte ShiftRightLogicalRoundedNarrowingSaturate(short op1, byte op2) { - short acc = op1[0]; + sbyte result; - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } + SatQ(UnsignedShift(op1, (short)(-op2), rounding: true), out result, reinterpretAsUnsigned: true); - return acc; + return result; } - private static long Reduce(Func reduceOp, sbyte[] op1) + public static byte ShiftRightLogicalRoundedNarrowingSaturate(ushort op1, byte op2) { - long acc = op1[0]; + byte result; - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } + SatQ(UnsignedShift(op1, (short)(-op2), rounding: true), out result); - return acc; + return result; } - public static uint AbsoluteDifferenceWidening(short op1, short op2) => op1 < op2 ? (uint)(op2 - op1) : (uint)(op1 - op2); + public static sbyte ShiftRightLogicalRoundedNarrowingSaturateUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); - public static uint AbsoluteDifferenceWideningUpper(short[] op1, short[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static byte ShiftRightLogicalRoundedNarrowingSaturateUpper(byte[] op1, ushort[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); - public static int AbsoluteDifferenceWideningAndAdd(int op1, short op2, short op3) => (int)(op1 + (int)AbsoluteDifferenceWidening(op2, op3)); + public static sbyte ShiftRightLogicalNarrowingUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); - public static int AbsoluteDifferenceWideningUpperAndAdd(int[] op1, short[] op2, short[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static byte ShiftRightLogicalNarrowingUpper(byte[] op1, ushort[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); - public static int AbsoluteDifferenceWideningLowerAndAddEven(int[] op1, short[] op2, short[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i * 2], op3[i * 2]); + public static sbyte ShiftRightLogicalNarrowingSaturate(short op1, byte op2) + { + sbyte result; - public static int AbsoluteDifferenceWideningLowerAndAddOdd(int[] op1, short[] op2, short[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); + SatQ(UnsignedShift(op1, (short)(-op2)), out result, reinterpretAsUnsigned: true); - public static int AbsoluteDifferenceWideningEven(short[] op1, short[] op2, int i) => (int) AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + return result; + } - public static int AbsoluteDifferenceWideningOdd(short[] op1, short[] op2, int i) => (int) AbsoluteDifferenceWidening(op1[(i*2) + 1], op2[(i*2) + 1]); + public static byte ShiftRightLogicalNarrowingSaturate(ushort op1, byte op2) + { + byte result; - public static int AddAcrossWidening(short[] op1) => Reduce(AddWidening, op1); + SatQ(UnsignedShift(op1, (short)(-op2)), out result); - public static long AddAcrossWideningLong(short[] op1) => Reduce(AddWidening, op1); + return result; + } - public static int AddPairwiseWidening(short[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); + public static sbyte ShiftRightLogicalNarrowingSaturateUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); - public static int AddPairwiseWideningAndAdd(int[] op1, short[] op2, int i) => (int)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); + public static byte ShiftRightLogicalNarrowingSaturateUpper(byte[] op1, ushort[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); - public static uint AddCarryWideningEven(uint[] op1, uint[] op2, uint[] op3, int i) + public static short SignExtendWidening(sbyte op1) => op1; + + public static short SignExtendWideningUpper(sbyte[] op1, int i) => SignExtendWidening(op1[i + op1.Length / 2]); + + private static bool SignedSatQ(int val, out short result) { - uint lsb; - ulong res; + bool saturated = false; - if ((i < 0) || (i >= op1.Length) || (i >= op2.Length) || (i >= op3.Length)) + if (val > short.MaxValue) { - throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); + result = short.MaxValue; + saturated = true; } - - if (i % 2 == 0) + else if (val < short.MinValue) { - if (i + 1 >= op2.Length) - { - throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range."); - } - - lsb = op2[i + 1] & 1u; - res = (ulong)op1[i] + op3[i] + lsb; - return (uint)res; + result = short.MinValue; + saturated = true; } else { - if (((i - 1) < 0) || ((i - 1) >= op1.Length) || ((i - 1) >= op3.Length)) - { - throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); - } - - lsb = op2[i] & 1u; - res = (ulong)op1[i - 1] + op3[i - 1] + lsb; - - // Shift result to get the carry bit - return (uint)(res >> 32); + result = (short)val; } + + return saturated; } - public static uint AddCarryWideningOdd(uint[] op1, uint[] op2, uint[] op3, int i) + private static bool UnsignedSatQ(int val, out ushort result) { - uint lsb; - ulong res; + bool saturated = false; - if ((i < 0) || (i >= op1.Length) || (i >= op2.Length) || (i >= op3.Length)) + if (val > ushort.MaxValue) { - throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); + result = ushort.MaxValue; + saturated = true; } - - if (i % 2 == 0) + else if (val < 0) { - if (((i + 1) >= op1.Length) || ((i + 1) >= op2.Length)) - { - throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range."); - } - - lsb = op2[i + 1] & 1u; - res = (ulong)op1[i + 1] + op3[i] + lsb; - return (uint)res; + result = 0; + saturated = true; } else { - if (((i - 1) < 0) || ((i - 1) >= op3.Length)) - { - throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); - } - - lsb = op2[i] & 1u; - res = (ulong)op1[i] + op3[i - 1] + lsb; - - // Shift result to get the carry bit - return (uint)(res >> 32); + result = (ushort)val; } - } + return saturated; + } - private static short HighNarrowing(int op1, bool round) + private static bool UnsignedSatQ(uint val, out ushort result) { - uint roundConst = 0; - if (round) + bool saturated = false; + + if (val > ushort.MaxValue) { - roundConst = (uint)1 << (8 * sizeof(short) - 1); + result = ushort.MaxValue; + saturated = true; } - return (short)(((uint)op1 + roundConst) >> (8 * sizeof(short))); - } - - public static short AddHighNarrowingEven(int[] op1, int[] op2, int i) - { - if (i % 2 == 0) + else if (val < 0) { - return (short) ((op1[i / 2] + op2[i / 2]) >> (8 * sizeof(short))); + result = 0; + saturated = true; + } + else + { + result = (ushort)val; } - return 0; - } - - public static short AddHighNarrowingOdd(short[] even, int[] op1, int[] op2, int i) + return saturated; + } + + private static bool SatQ(int val, out short result, bool reinterpretAsUnsigned = false) { - if (i % 2 == 1) + bool saturated; + + if (reinterpretAsUnsigned) { - return (short) ((op1[(i - 1) / 2] + op2[(i - 1) / 2]) >> (8 * sizeof(short))); + ushort res; + saturated = UnsignedSatQ((uint)val, out res); + result = (short)res; + } + else + { + saturated = SignedSatQ(val, out result); } - return even[i]; + return saturated; } - public static short AddHighNarrowing(int op1, int op2) => HighNarrowing((int)(op1 + op2), round: false); + private static bool SatQ(uint val, out ushort result) => UnsignedSatQ(val, out result); - public static short AddHighNarrowingUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + public static short ExtractNarrowingSaturate(int op1) + { + short result; - public static short AddRoundedHighNarrowing(int op1, int op2) => HighNarrowing((int)(op1 + op2), round: true); + SatQ(op1, out result); - public static int AddRoundedHighNarrowingUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + return result; + } - public static int AddWidening(short op1, short op2) => (int)((int)op1 + (int)op2); + public static short ExtractNarrowingSaturateUpper(short[] op1, int[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturate(op2[i - op1.Length]); - public static int AddWidening(int op1, short op2) => (int)(op1 + op2); + public static ushort ExtractNarrowingSaturate(uint op1) + { + ushort result; - public static long AddWidening(long op1, short op2) => (long)(op1 + (long)op2); + SatQ(op1, out result); - public static int AddWideningUpper(short[] op1, short[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + return result; + } - public static int AddWideningUpper(int[] op1, short[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); + public static ushort ExtractNarrowingSaturateUpper(ushort[] op1, uint[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturate(op2[i - op1.Length]); - public static short ExtractNarrowing(int op1) => (short)op1; + public static ushort ExtractNarrowingSaturateUnsigned(int op1) + { + ushort result; - public static short ExtractNarrowingUpper(short[] op1, int[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); + UnsignedSatQ(op1, out result); - public static short FusedAddHalving(short op1, short op2) => (short)((uint)((int)op1 + (int)op2) >> 1); + return result; + } - public static short FusedAddRoundedHalving(short op1, short op2) => (short)((uint)((int)op1 + (int)op2 + 1) >> 1); + public static ushort ExtractNarrowingSaturateUnsignedUpper(ushort[] op1, int[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturateUnsigned(op2[i - op1.Length]); - public static short FusedSubtractHalving(short op1, short op2) => (short)((uint)((int)op1 - (int)op2) >> 1); + private static (int val, bool ovf) MultiplyDoublingOvf(short op1, short op2, bool rounding, int op3, bool subOp) + { + int product = (int)((int)op1 * (int)op2); - public static int MultiplyByScalarWideningUpper(short[] op1, short op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2); + bool dblOvf; + (product, dblOvf) = AddOvf(product, product); - public static int MultiplyByScalarWideningUpperAndAdd(int[] op1, short[] op2, short op3, int i) => MultiplyWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3); + bool addOvf; + int accum; - public static int MultiplyByScalarWideningUpperAndSubtract(int[] op1, short[] op2, short op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3); + if (subOp) + { + (accum, addOvf) = SubtractOvf(op3, product); + } + else + { + (accum, addOvf) = AddOvf(op3, product); + } - public static int MultiplyWidening(short op1, short op2) => (int)((int)op1 * (int)op2); + int roundConst = 0; - public static int MultiplyWideningAndAdd(int op1, short op2, short op3) => (int)(op1 + MultiplyWidening(op2, op3)); + if (rounding) + { + roundConst = (int)1 << (8 * sizeof(short) - 1); + } - public static int MultiplyWideningAndSubtract(int op1, short op2, short op3) => (int)(op1 - MultiplyWidening(op2, op3)); + bool rndOvf; + int result; - public static int MultiplyWideningUpper(short[] op1, short[] op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + (result, rndOvf) = AddOvf(accum, roundConst); - public static int MultiplyWideningUpperAndAdd(int[] op1, short[] op2, short[] op3, int i) => MultiplyWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + return (result, addOvf ^ rndOvf ^ dblOvf); + } - public static int MultiplyWideningUpperAndSubtract(int[] op1, short[] op2, short[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + private static short SaturateHigh(int val, bool ovf) + { + if (ovf) + { + return val < 0 ? short.MaxValue : short.MinValue; + } - public static short SubtractHighNarrowing(int op1, int op2) => HighNarrowing((int)(op1 - op2), round: false); + return (short)UnsignedShift(val, (int)(-8 * sizeof(short))); + } - public static int SubtractHighNarrowingUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + public static short MultiplyDoublingSaturateHigh(short op1, short op2) + { + var (val, ovf) = MultiplyDoublingOvf(op1, op2, rounding: false, (int)0, subOp: false); - public static short SubtractRoundedHighNarrowing(int op1, int op2) => HighNarrowing((int)(op1 - op2), round: true); + return SaturateHigh(val, ovf); + } - public static int SubtractRoundedHighNarrowingUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + public static short MultiplyRoundedDoublingSaturateHigh(short op1, short op2) + { + var (val, ovf) = MultiplyDoublingOvf(op1, op2, rounding: true, (int)0, subOp: false); - public static int SubtractWidening(short op1, short op2) => (int)((int)op1 - (int)op2); + return SaturateHigh(val, ovf); + } - public static int SubtractWidening(int op1, short op2) => (int)(op1 - op2); + public static int MultiplyDoublingWideningSaturate(short op1, short op2) + { + var (product, ovf) = MultiplyDoublingOvf(op1, op2, rounding: false, (int)0, subOp: false); - public static int SubtractWideningUpper(short[] op1, short[] op2, int i) => SubtractWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + if (ovf) + { + return product < 0 ? short.MaxValue : short.MinValue; + } - public static int SubtractWideningUpper(int[] op1, short[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); + return product; + } - public static int ZeroExtendWidening(short op1) => (int)(uint)op1; + public static short MultiplyRoundedDoublingAndAddSaturateHigh(short op1, short op2, short op3) + { + int addend = UnsignedShift((int)op1, (int)(8 * sizeof(short))); - public static int ZeroExtendWideningUpper(short[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + var (val, ovf) = MultiplyDoublingOvf(op2, op3, rounding: true, addend, subOp: false); + + return SaturateHigh(val, ovf); + } - private static int Reduce(Func reduceOp, short[] op1) + public static short MultiplyRoundedDoublingAndSubtractSaturateHigh(short op1, short op2, short op3) { - int acc = op1[0]; + int minuend = UnsignedShift((int)op1, (int)(8 * sizeof(short))); - for (int i = 1; i < op1.Length; i++) + var (val, ovf) = MultiplyDoublingOvf(op2, op3, rounding: true, minuend, subOp: true); + + return SaturateHigh(val, ovf); + } + + public static short[] MultiplyAddRoundedDoublingSaturateHighRotateComplex(short[] op1, short[] op2, short[] op3, byte rot) + { + for (int i = 0; i < op1.Length; i += 2) { - acc = reduceOp(acc, op1[i]); + int real = i; + int img = i + 1; + (short ans1, short ans2) = rot switch + { + 0 => (MultiplyRoundedDoublingAndAddSaturateHigh(op1[real], op2[real], op3[real]), MultiplyRoundedDoublingAndAddSaturateHigh(op1[img], op2[real], op3[img])), + 1 => (MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[real], op2[img], op3[img]), MultiplyRoundedDoublingAndAddSaturateHigh(op1[img], op2[img], op3[real])), + 2 => (MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[real], op2[real], op3[real]), MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[img], op2[real], op3[img])), + 3 => (MultiplyRoundedDoublingAndAddSaturateHigh(op1[real], op2[img], op3[img]), MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[img], op2[img], op3[real])), + _ => (default, default) + }; + + op1[real] = ans1; + op1[img] = ans2; } - return acc; + return op1; } - private static long Reduce(Func reduceOp, short[] op1) + public static short[] MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(short[] op1, short[] op2, short[] op3, byte index, byte rot) { - long acc = op1[0]; - - for (int i = 1; i < op1.Length; i++) + for (int i = 0; i < op1.Length; i += 2) { - acc = reduceOp(acc, op1[i]); + int real = i; + int img = i + 1; + (short op3Real, short op3Img) = (op3[index * 2], op3[(index * 2) + 1]); + (short ans1, short ans2) = rot switch + { + 0 => (MultiplyRoundedDoublingAndAddSaturateHigh(op1[real], op2[real], op3Real), MultiplyRoundedDoublingAndAddSaturateHigh(op1[img], op2[real], op3Img)), + 1 => (MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[real], op2[img], op3Img), MultiplyRoundedDoublingAndAddSaturateHigh(op1[img], op2[img], op3Real)), + 2 => (MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[real], op2[real], op3Real), MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[img], op2[real], op3Img)), + 3 => (MultiplyRoundedDoublingAndAddSaturateHigh(op1[real], op2[img], op3Img), MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[img], op2[img], op3Real)), + _ => (default, default) + }; + + op1[real] = ans1; + op1[img] = ans2; } - return acc; + return op1; } - public static ulong AbsoluteDifferenceWidening(int op1, int op2) => op1 < op2 ? (ulong)(op2 - op1) : (ulong)(op1 - op2); + public static int MultiplyDoublingWideningAndAddSaturate(int op1, short op2, short op3) => AddSaturate(op1, MultiplyDoublingWideningSaturate(op2, op3)); - public static ulong AbsoluteDifferenceWideningUpper(int[] op1, int[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static int MultiplyDoublingWideningAndSubtractSaturate(int op1, short op2, short op3) => SubtractSaturate(op1, MultiplyDoublingWideningSaturate(op2, op3)); - public static long AbsoluteDifferenceWideningAndAdd(long op1, int op2, int op3) => (long)(op1 + (long)AbsoluteDifferenceWidening(op2, op3)); + public static int MultiplyDoublingWideningSaturateUpperByScalar(short[] op1, short op2, int i) => MultiplyDoublingWideningSaturate(op1[i + op1.Length / 2], op2); - public static long AbsoluteDifferenceWideningUpperAndAdd(long[] op1, int[] op2, int[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static int MultiplyDoublingWideningUpperByScalarAndAddSaturate(int[] op1, short[] op2, short op3, int i) => MultiplyDoublingWideningAndAddSaturate(op1[i], op2[i + op2.Length / 2], op3); - public static long AbsoluteDifferenceWideningLowerAndAddEven(long[] op1, int[] op2, int[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i * 2], op3[i * 2]); + public static int MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(int[] op1, short[] op2, short op3, int i) => MultiplyDoublingWideningAndSubtractSaturate(op1[i], op2[i + op2.Length / 2], op3); - 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 int MultiplyDoublingWideningSaturateUpper(short[] op1, short[] op2, int i) => MultiplyDoublingWideningSaturate(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static long AbsoluteDifferenceWideningEven(int[] op1, int[] op2, int i) => (long) AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static int MultiplyDoublingWideningUpperAndAddSaturate(int[] op1, short[] op2, short[] op3, int i) => MultiplyDoublingWideningAndAddSaturate(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static long AbsoluteDifferenceWideningOdd(int[] op1, int[] op2, int i) => (long) AbsoluteDifferenceWidening(op1[(i*2) + 1], op2[(i*2) + 1]); + public static int MultiplyDoublingWideningUpperAndSubtractSaturate(int[] op1, short[] op2, short[] op3, int i) => MultiplyDoublingWideningAndSubtractSaturate(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static long AddAcrossWidening(int[] op1) => Reduce(AddWidening, op1); + public static int ShiftLeftLogicalWidening(short op1, byte op2) => UnsignedShift((int)op1, (int)op2); - public static long AddPairwiseWidening(int[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); + public static uint ShiftLeftLogicalWidening(ushort op1, byte op2) => UnsignedShift((uint)op1, (int)op2); - public static long AddPairwiseWideningAndAdd(long[] op1, int[] op2, int i) => (long)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); + public static int ShiftLeftLogicalWideningUpper(short[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); - public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, int i) + public static uint ShiftLeftLogicalWideningUpper(ushort[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + + public static short ShiftRightArithmeticRoundedNarrowingSaturate(int op1, byte op2) { - ulong lsb; - ulong res; + short result; - if ((i < 0) || (i >= op1.Length) || (i >= op2.Length) || (i >= op3.Length)) - { - throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); - } + SatQ(SignedShift(op1, (int)(-op2), rounding: true), out result); - if (i % 2 == 0) - { - if ((i + 1) >= op2.Length) - { - throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range for op3."); - } + return result; + } - lsb = op2[i + 1] & 1UL; - res = op1[i] + op3[i] + lsb; - return res; - } - else - { - if (((i - 1) < 0) || ((i - 1) >= op1.Length) || ((i - 1) >= op3.Length)) - { - throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); - } + public static ushort ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(int op1, byte op2) + { + ushort result; - lsb = op2[i] & 1UL; + UnsignedSatQ(SignedShift(op1, (int)(-op2), rounding: true), out result); - // Look for an overflow in the addition to get the carry bit - ulong sum1 = op1[i - 1] + op3[i - 1]; - bool overflow1 = sum1 < op1[i - 1]; + return result; + } - ulong sum2 = sum1 + lsb; - bool overflow2 = sum2 < sum1; + public static ushort ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(ushort[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(op2[i - op1.Length], op3); - return (overflow1 || overflow2) ? 1UL : 0UL; - } + public static short ShiftRightArithmeticRoundedNarrowingSaturateUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightArithmeticRoundedNarrowingSaturate(op2[i - op1.Length], op3); + + public static short ShiftRightArithmeticNarrowingSaturate(int op1, byte op2) + { + short result; + + SatQ(SignedShift(op1, (int)(-op2)), out result); + + return result; } - public static ulong AddCarryWideningOdd(ulong[] op1, ulong[] op2, ulong[] op3, int i) + public static ushort ShiftRightArithmeticNarrowingSaturateUnsigned(int op1, byte op2) { - ulong lsb; - ulong res; + ushort result; - if ((i < 0) || (i >= op1.Length) || (i >= op2.Length) || (i >= op3.Length)) - { - throw new ArgumentOutOfRangeException(nameof(i), "Index i is out of range"); - } + UnsignedSatQ(SignedShift(op1, (int)(-op2)), out result); - if (i % 2 == 0) - { - if (((i + 1) >= op1.Length) || ((i + 1) >= op2.Length)) - { - throw new ArgumentOutOfRangeException(nameof(i), "Index i + 1 is out of range."); - } + return result; + } - lsb = op2[i + 1] & 1UL; - res = op1[i + 1] + op3[i] + lsb; - return res; - } - else - { - if (((i - 1) < 0) || ((i - 1) >= op3.Length)) - { - throw new ArgumentOutOfRangeException(nameof(i), "Index i - 1 is out of range."); - } + public static ushort ShiftRightArithmeticNarrowingSaturateUnsignedUpper(ushort[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightArithmeticNarrowingSaturateUnsigned(op2[i - op1.Length], op3); - lsb = op2[i] & 1UL; + public static short ShiftRightArithmeticNarrowingSaturateUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightArithmeticNarrowingSaturate(op2[i - op1.Length], op3); - // Look for an overflow in the addition to get the carry bit - ulong sum1 = op1[i] + op3[i - 1]; - bool overflow1 = sum1 < op1[i]; + public static short ShiftRightLogicalNarrowing(int op1, byte op2) => (short)UnsignedShift(op1, (int)(-op2)); - ulong sum2 = sum1 + lsb; - bool overflow2 = sum2 < sum1; + public static ushort ShiftRightLogicalNarrowing(uint op1, byte op2) => (ushort)UnsignedShift(op1, (int)(-op2)); - return (overflow1 || overflow2) ? 1UL : 0UL; - } - } + public static short ShiftRightLogicalRoundedNarrowing(int op1, byte op2) => (short)UnsignedShift(op1, (int)(-op2), rounding: true); - private static int HighNarrowing(long op1, bool round) - { - ulong roundConst = 0; - if (round) - { - roundConst = (ulong)1 << (8 * sizeof(int) - 1); - } - return (int)(((ulong)op1 + roundConst) >> (8 * sizeof(int))); - } + public static ushort ShiftRightLogicalRoundedNarrowing(uint op1, byte op2) => (ushort)UnsignedShift(op1, (int)(-op2), rounding: true); - public static int AddHighNarrowingEven(long[] op1, long[] op2, int i) - { - if (i % 2 == 0) - { - return (int) ((op1[i / 2] + op2[i / 2]) >> (8 * sizeof(int))); - } + public static short ShiftRightLogicalRoundedNarrowingUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); - return 0; - } + public static ushort ShiftRightLogicalRoundedNarrowingUpper(ushort[] op1, uint[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); - public static int AddHighNarrowingOdd(int[] even, long[] op1, long[] op2, int i) + public static short ShiftRightLogicalRoundedNarrowingSaturate(int op1, byte op2) { - if (i % 2 == 1) - { - return (int) ((op1[(i - 1) / 2] + op2[(i - 1) / 2]) >> (8 * sizeof(int))); - } - - return even[i]; - } + short result; - public static int AddHighNarrowing(long op1, long op2) => HighNarrowing((long)(op1 + op2), round: false); + SatQ(UnsignedShift(op1, (int)(-op2), rounding: true), out result, reinterpretAsUnsigned: true); - public static int AddHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + return result; + } - public static int AddRoundedHighNarrowing(long op1, long op2) => HighNarrowing((long)(op1 + op2), round: true); + public static ushort ShiftRightLogicalRoundedNarrowingSaturate(uint op1, byte op2) + { + ushort result; - public static long AddRoundedHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + SatQ(UnsignedShift(op1, (int)(-op2), rounding: true), out result); - public static long AddWidening(int op1, int op2) => (long)((long)op1 + (long)op2); + return result; + } - public static long AddWidening(long op1, int op2) => (long)(op1 + op2); + public static short ShiftRightLogicalRoundedNarrowingSaturateUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); - public static long AddWideningUpper(int[] op1, int[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static ushort ShiftRightLogicalRoundedNarrowingSaturateUpper(ushort[] op1, uint[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); - public static long AddWideningUpper(long[] op1, int[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); + public static short ShiftRightLogicalNarrowingUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); - public static int ExtractNarrowing(long op1) => (int)op1; + public static ushort ShiftRightLogicalNarrowingUpper(ushort[] op1, uint[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); - public static int ExtractNarrowingUpper(int[] op1, long[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); + public static short ShiftRightLogicalNarrowingSaturate(int op1, byte op2) + { + short result; - public static int FusedAddHalving(int op1, int op2) => (int)((ulong)((long)op1 + (long)op2) >> 1); + SatQ(UnsignedShift(op1, (int)(-op2)), out result, reinterpretAsUnsigned: true); - public static int FusedAddRoundedHalving(int op1, int op2) => (int)((ulong)((long)op1 + (long)op2 + 1) >> 1); + return result; + } - public static int FusedSubtractHalving(int op1, int op2) => (int)((ulong)((long)op1 - (long)op2) >> 1); + public static ushort ShiftRightLogicalNarrowingSaturate(uint op1, byte op2) + { + ushort result; - public static long MultiplyByScalarWideningUpper(int[] op1, int op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2); + SatQ(UnsignedShift(op1, (int)(-op2)), out result); - public static long MultiplyByScalarWideningUpperAndAdd(long[] op1, int[] op2, int op3, int i) => MultiplyWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3); + return result; + } - public static long MultiplyByScalarWideningUpperAndSubtract(long[] op1, int[] op2, int op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3); + public static short ShiftRightLogicalNarrowingSaturateUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); - public static long MultiplyWidening(int op1, int op2) => (long)((long)op1 * (long)op2); + public static ushort ShiftRightLogicalNarrowingSaturateUpper(ushort[] op1, uint[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); - public static long MultiplyWideningAndAdd(long op1, int op2, int op3) => (long)(op1 + MultiplyWidening(op2, op3)); + public static int SignExtendWidening(short op1) => op1; - public static long MultiplyWideningAndSubtract(long op1, int op2, int op3) => (long)(op1 - MultiplyWidening(op2, op3)); + public static int SignExtendWideningUpper(short[] op1, int i) => SignExtendWidening(op1[i + op1.Length / 2]); - public static long MultiplyWideningUpper(int[] op1, int[] op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + private static bool SignedSatQ(long val, out int result) + { + bool saturated = false; - public static long MultiplyWideningUpperAndAdd(long[] op1, int[] op2, int[] op3, int i) => MultiplyWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + if (val > int.MaxValue) + { + result = int.MaxValue; + saturated = true; + } + else if (val < int.MinValue) + { + result = int.MinValue; + saturated = true; + } + else + { + result = (int)val; + } - public static long MultiplyWideningUpperAndSubtract(long[] op1, int[] op2, int[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + return saturated; + } - public static T ShiftLeft(T op1, ulong op2) where T : INumber + private static bool UnsignedSatQ(long val, out uint result) { - T two = T.One + T.One; - for (ulong i = 0; (op1 != T.Zero) && (i < op2); i++) + bool saturated = false; + + if (val > uint.MaxValue) { - op1 *= two; + result = uint.MaxValue; + saturated = true; + } + else if (val < 0) + { + result = 0; + saturated = true; + } + else + { + result = (uint)val; } - return op1; + return saturated; } - public static T ShiftRight(T op1, ulong op2) where T : INumber + private static bool UnsignedSatQ(ulong val, out uint result) { - T two = T.One + T.One; - for (ulong i = 0; (op1 != T.Zero) && (i < op2); i++) + bool saturated = false; + + if (val > uint.MaxValue) { - op1 /= two; + result = uint.MaxValue; + saturated = true; + } + else if (val < 0) + { + result = 0; + saturated = true; + } + else + { + result = (uint)val; } - return op1; + return saturated; } - public static T SignExtend(T n, int numBits, bool zeroExtend) where T : struct, IComparable, IConvertible + private static bool SatQ(long val, out int result, bool reinterpretAsUnsigned = false) { - // Get the underlying integer value - dynamic value = Convert.ChangeType(n, typeof(long)); - - // Mask to extract the lowest numBits - long mask = (1L << numBits) - 1; - long lowestBits = value & mask; + bool saturated; - // Sign extension for signed integers - long signBitMask = 1L << (numBits - 1); - if (!zeroExtend && ((lowestBits & signBitMask) != 0)) + if (reinterpretAsUnsigned) { - // If sign bit is set, it's a negative number - return (T)Convert.ChangeType(-((~lowestBits & mask) + 1), typeof(T)); + uint res; + saturated = UnsignedSatQ((ulong)val, out res); + result = (int)res; } else { - // If sign bit is not set, it's a positive number - return (T)Convert.ChangeType(lowestBits, typeof(T)); + saturated = SignedSatQ(val, out result); } - } - public static int SubtractHighNarrowing(long op1, long op2) => HighNarrowing((long)(op1 - op2), round: false); + return saturated; + } - public static long SubtractHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + private static bool SatQ(ulong val, out uint result) => UnsignedSatQ(val, out result); - public static int SubtractRoundedHighNarrowing(long op1, long op2) => HighNarrowing((long)(op1 - op2), round: true); + public static int ExtractNarrowingSaturate(long op1) + { + int result; - public static long SubtractRoundedHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + SatQ(op1, out result); - public static long SubtractWidening(int op1, int op2) => (long)((long)op1 - (long)op2); + return result; + } - public static long SubtractWidening(long op1, int op2) => (long)(op1 - op2); + public static int ExtractNarrowingSaturateUpper(int[] op1, long[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturate(op2[i - op1.Length]); - public static long SubtractWideningUpper(int[] op1, int[] op2, int i) => SubtractWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static uint ExtractNarrowingSaturate(ulong op1) + { + uint result; - public static long SubtractWideningUpper(long[] op1, int[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); + SatQ(op1, out result); - public static long ZeroExtendWidening(int op1) => (long)(ulong)op1; + return result; + } - public static long ZeroExtendWideningUpper(int[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + public static uint ExtractNarrowingSaturateUpper(uint[] op1, ulong[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturate(op2[i - op1.Length]); - private static long Reduce(Func reduceOp, int[] op1) + public static uint ExtractNarrowingSaturateUnsigned(long op1) { - long acc = op1[0]; + uint result; - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } + UnsignedSatQ(op1, out result); - return acc; + return result; } - public static ushort AbsoluteDifferenceWidening(byte op1, byte op2) => op1 < op2 ? (ushort)(op2 - op1) : (ushort)(op1 - op2); - - public static ushort AbsoluteDifferenceWideningUpper(byte[] op1, byte[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - - public static ushort AbsoluteDifferenceWideningAndAdd(ushort op1, byte op2, byte op3) => (ushort)(op1 + (ushort)AbsoluteDifferenceWidening(op2, op3)); + public static uint ExtractNarrowingSaturateUnsignedUpper(uint[] op1, long[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturateUnsigned(op2[i - op1.Length]); - public static ushort AbsoluteDifferenceWideningUpperAndAdd(ushort[] op1, byte[] op2, byte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + private static (long val, bool ovf) MultiplyDoublingOvf(int op1, int op2, bool rounding, long op3, bool subOp) + { + long product = (long)((long)op1 * (long)op2); - public static ushort AbsoluteDifferenceWideningLowerAndAddEven(ushort[] op1, byte[] op2, byte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i * 2], op3[i * 2]); + bool dblOvf; + (product, dblOvf) = AddOvf(product, product); - public static ushort AbsoluteDifferenceWideningLowerAndAddOdd(ushort[] op1, byte[] op2, byte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); + bool addOvf; + long accum; - public static ushort AbsoluteDifferenceWideningEven(byte[] op1, byte[] op2, int i) => AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + if (subOp) + { + (accum, addOvf) = SubtractOvf(op3, product); + } + else + { + (accum, addOvf) = AddOvf(op3, product); + } - public static ushort AbsoluteDifferenceWideningOdd(byte[] op1, byte[] op2, int i) => AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); + long roundConst = 0; - public static ushort AddAcrossWidening(byte[] op1) => Reduce(AddWidening, op1); + if (rounding) + { + roundConst = (long)1 << (8 * sizeof(int) - 1); + } - public static ulong AddAcrossWideningULong(byte[] op1) => Reduce(AddWidening, op1); + bool rndOvf; + long result; - public static ushort AddPairwiseWidening(byte[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); + (result, rndOvf) = AddOvf(accum, roundConst); - public static ushort AddPairwiseWideningAndAdd(ushort[] op1, byte[] op2, int i) => (ushort)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); + return (result, addOvf ^ rndOvf ^ dblOvf); + } - private static byte HighNarrowing(ushort op1, bool round) + private static int SaturateHigh(long val, bool ovf) { - ushort roundConst = 0; - if (round) + if (ovf) { - roundConst = (ushort)1 << (8 * sizeof(byte) - 1); + return val < 0 ? int.MaxValue : int.MinValue; } - return (byte)(((ushort)op1 + roundConst) >> (8 * sizeof(byte))); + + return (int)UnsignedShift(val, (long)(-8 * sizeof(int))); } - public static byte AddHighNarrowingEven(ushort[] op1, ushort[] op2, int i) + public static int MultiplyDoublingSaturateHigh(int op1, int op2) { - if (i % 2 == 0) - { - return (byte) ((op1[i / 2] + op2[i / 2]) >> (8 * sizeof(byte))); - } + var (val, ovf) = MultiplyDoublingOvf(op1, op2, rounding: false, (long)0, subOp: false); - return 0; + return SaturateHigh(val, ovf); } - public static byte AddHighNarrowingOdd(byte[] even, ushort[] op1, ushort[] op2, int i) + public static int MultiplyRoundedDoublingSaturateHigh(int op1, int op2) { - if (i % 2 == 1) - { - return (byte) ((op1[(i - 1) / 2] + op2[(i - 1) / 2]) >> (8 * sizeof(byte))); - } + var (val, ovf) = MultiplyDoublingOvf(op1, op2, rounding: true, (long)0, subOp: false); - return even[i]; + return SaturateHigh(val, ovf); } - public static byte AddHighNarrowing(ushort op1, ushort op2) => HighNarrowing((ushort)(op1 + op2), round: false); - - public static byte AddHighNarrowingUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - - public static byte AddRoundedHighNarrowing(ushort op1, ushort op2) => HighNarrowing((ushort)(op1 + op2), round: true); + public static long MultiplyDoublingWideningSaturate(int op1, int op2) + { + var (product, ovf) = MultiplyDoublingOvf(op1, op2, rounding: false, (long)0, subOp: false); - public static ushort AddRoundedHighNarrowingUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + if (ovf) + { + return product < 0 ? int.MaxValue : int.MinValue; + } - public static ushort AddWidening(byte op1, byte op2) => (ushort)((ushort)op1 + (ushort)op2); + return product; + } - public static ushort AddWidening(ushort op1, byte op2) => (ushort)(op1 + op2); + public static int MultiplyRoundedDoublingAndAddSaturateHigh(int op1, int op2, int op3) + { + long addend = UnsignedShift((long)op1, (long)(8 * sizeof(int))); - public static ulong AddWidening(ulong op1, byte op2) => (ulong)(op1 + (ulong)op2); + var (val, ovf) = MultiplyDoublingOvf(op2, op3, rounding: true, addend, subOp: false); - public static ushort AddWideningUpper(byte[] op1, byte[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + return SaturateHigh(val, ovf); + } - public static ushort AddWideningUpper(ushort[] op1, byte[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); + public static int MultiplyRoundedDoublingAndSubtractSaturateHigh(int op1, int op2, int op3) + { + long minuend = UnsignedShift((long)op1, (long)(8 * sizeof(int))); - public static byte ExtractNarrowing(ushort op1) => (byte)op1; + var (val, ovf) = MultiplyDoublingOvf(op2, op3, rounding: true, minuend, subOp: true); - public static byte ExtractNarrowingUpper(byte[] op1, ushort[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); + return SaturateHigh(val, ovf); + } - public static byte FusedAddHalving(byte op1, byte op2) => (byte)((ushort)((ushort)op1 + (ushort)op2) >> 1); + public static int[] MultiplyAddRoundedDoublingSaturateHighRotateComplex(int[] op1, int[] op2, int[] op3, byte rot) + { + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; + (int ans1, int ans2) = rot switch + { + 0 => (MultiplyRoundedDoublingAndAddSaturateHigh(op1[real], op2[real], op3[real]), MultiplyRoundedDoublingAndAddSaturateHigh(op1[img], op2[real], op3[img])), + 1 => (MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[real], op2[img], op3[img]), MultiplyRoundedDoublingAndAddSaturateHigh(op1[img], op2[img], op3[real])), + 2 => (MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[real], op2[real], op3[real]), MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[img], op2[real], op3[img])), + 3 => (MultiplyRoundedDoublingAndAddSaturateHigh(op1[real], op2[img], op3[img]), MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[img], op2[img], op3[real])), + _ => (default, default) + }; - public static byte FusedAddRoundedHalving(byte op1, byte op2) => (byte)((ushort)((ushort)op1 + (ushort)op2 + 1) >> 1); + op1[real] = ans1; + op1[img] = ans2; + } - public static byte FusedSubtractHalving(byte op1, byte op2) => (byte)((ushort)((ushort)op1 - (ushort)op2) >> 1); + return op1; + } - public static ushort MultiplyByScalarWideningUpper(byte[] op1, byte op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2); + public static int[] MultiplyAddRoundedDoublingSaturateHighRotateComplexBySelectedScalar(int[] op1, int[] op2, int[] op3, byte index, byte rot) + { + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; + (int op3Real, int op3Img) = (op3[index * 2], op3[(index * 2) + 1]); + (int ans1, int ans2) = rot switch + { + 0 => (MultiplyRoundedDoublingAndAddSaturateHigh(op1[real], op2[real], op3Real), MultiplyRoundedDoublingAndAddSaturateHigh(op1[img], op2[real], op3Img)), + 1 => (MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[real], op2[img], op3Img), MultiplyRoundedDoublingAndAddSaturateHigh(op1[img], op2[img], op3Real)), + 2 => (MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[real], op2[real], op3Real), MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[img], op2[real], op3Img)), + 3 => (MultiplyRoundedDoublingAndAddSaturateHigh(op1[real], op2[img], op3Img), MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[img], op2[img], op3Real)), + _ => (default, default) + }; - public static ushort MultiplyByScalarWideningUpperAndAdd(ushort[] op1, byte[] op2, byte op3, int i) => MultiplyWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3); + op1[real] = ans1; + op1[img] = ans2; + } - public static ushort MultiplyByScalarWideningUpperAndSubtract(ushort[] op1, byte[] op2, byte op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3); + return op1; + } - public static ushort MultiplyWidening(byte op1, byte op2) => (ushort)((ushort)op1 * (ushort)op2); + public static long MultiplyDoublingWideningAndAddSaturate(long op1, int op2, int op3) => AddSaturate(op1, MultiplyDoublingWideningSaturate(op2, op3)); - public static ushort MultiplyWideningAndAdd(ushort op1, byte op2, byte op3) => (ushort)(op1 + MultiplyWidening(op2, op3)); + public static long MultiplyDoublingWideningAndSubtractSaturate(long op1, int op2, int op3) => SubtractSaturate(op1, MultiplyDoublingWideningSaturate(op2, op3)); - public static ushort MultiplyWideningAndSubtract(ushort op1, byte op2, byte op3) => (ushort)(op1 - MultiplyWidening(op2, op3)); + public static long MultiplyDoublingWideningSaturateUpperByScalar(int[] op1, int op2, int i) => MultiplyDoublingWideningSaturate(op1[i + op1.Length / 2], op2); - public static ushort MultiplyWideningUpper(byte[] op1, byte[] op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static long MultiplyDoublingWideningUpperByScalarAndAddSaturate(long[] op1, int[] op2, int op3, int i) => MultiplyDoublingWideningAndAddSaturate(op1[i], op2[i + op2.Length / 2], op3); - public static ushort MultiplyWideningUpperAndAdd(ushort[] op1, byte[] op2, byte[] op3, int i) => MultiplyWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static long MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(long[] op1, int[] op2, int op3, int i) => MultiplyDoublingWideningAndSubtractSaturate(op1[i], op2[i + op2.Length / 2], op3); - public static ushort MultiplyWideningUpperAndSubtract(ushort[] op1, byte[] op2, byte[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static long MultiplyDoublingWideningSaturateUpper(int[] op1, int[] op2, int i) => MultiplyDoublingWideningSaturate(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static byte SubtractHighNarrowing(ushort op1, ushort op2) => HighNarrowing((ushort)(op1 - op2), round: false); + public static long MultiplyDoublingWideningUpperAndAddSaturate(long[] op1, int[] op2, int[] op3, int i) => MultiplyDoublingWideningAndAddSaturate(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static ushort SubtractHighNarrowingUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + public static long MultiplyDoublingWideningUpperAndSubtractSaturate(long[] op1, int[] op2, int[] op3, int i) => MultiplyDoublingWideningAndSubtractSaturate(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static byte SubtractRoundedHighNarrowing(ushort op1, ushort op2) => HighNarrowing((ushort)(op1 - op2), round: true); + public static long MultiplyDoublingSaturateHigh(long op1, long op2) + { + return MultiplyDoublingSaturate(op1, op2, rounding: false, 0, subOp: false); + } - public static ushort SubtractRoundedHighNarrowingUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + public static long MultiplyRoundedDoublingSaturateHigh(long op1, long op2) + { + return MultiplyDoublingSaturate(op1, op2, rounding: true, 0, subOp: false); + } - public static ushort SubtractWidening(byte op1, byte op2) => (ushort)((ushort)op1 - (ushort)op2); + public static long MultiplyRoundedDoublingAndAddSaturateHigh(long op1, long op2, long op3) + { + return MultiplyDoublingSaturate(op2, op3, rounding: true, op1, subOp: false); + } - public static ushort SubtractWidening(ushort op1, byte op2) => (ushort)(op1 - op2); + public static long MultiplyRoundedDoublingAndSubtractSaturateHigh(long op1, long op2, long op3) + { + return MultiplyDoublingSaturate(op2, op3, rounding: true, op1, subOp: true); + } - public static ushort SubtractWideningUpper(byte[] op1, byte[] op2, int i) => SubtractWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + private static long MultiplyDoublingSaturate(long op1, long op2, bool rounding, long op3, bool subOp) + { + BigInteger a = new BigInteger(op1); + BigInteger b = new BigInteger(op2); + BigInteger c = new BigInteger(op3); - public static ushort SubtractWideningUpper(ushort[] op1, byte[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); + BigInteger result = a * b << 1; - public static ushort ZeroExtendWidening(byte op1) => (ushort)(ushort)op1; + int shift = 8 * sizeof(long); + c = c << shift; + if (subOp) + { + result = c - result; + } + else + { + result = c + result; + } - public static ushort ZeroExtendWideningUpper(byte[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + if (rounding) + { + result += new BigInteger(1) << (8 * sizeof(long) - 1); + } - private static ushort Reduce(Func reduceOp, byte[] op1) - { - ushort acc = op1[0]; + result = result >> shift; - for (int i = 1; i < op1.Length; i++) + if (result > long.MaxValue) { - acc = reduceOp(acc, op1[i]); + return long.MaxValue; + } + else if (result < long.MinValue) + { + return long.MinValue; } - return acc; + return long.CreateChecked(result); } - private static ulong Reduce(Func reduceOp, byte[] op1) + public static long[] MultiplyAddRoundedDoublingSaturateHighRotateComplex(long[] op1, long[] op2, long[] op3, byte rot) { - ulong acc = op1[0]; - - for (int i = 1; i < op1.Length; i++) + for (int i = 0; i < op1.Length; i += 2) { - acc = reduceOp(acc, op1[i]); + int real = i; + int img = i + 1; + (long ans1, long ans2) = rot switch + { + 0 => (MultiplyRoundedDoublingAndAddSaturateHigh(op1[real], op2[real], op3[real]), MultiplyRoundedDoublingAndAddSaturateHigh(op1[img], op2[real], op3[img])), + 1 => (MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[real], op2[img], op3[img]), MultiplyRoundedDoublingAndAddSaturateHigh(op1[img], op2[img], op3[real])), + 2 => (MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[real], op2[real], op3[real]), MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[img], op2[real], op3[img])), + 3 => (MultiplyRoundedDoublingAndAddSaturateHigh(op1[real], op2[img], op3[img]), MultiplyRoundedDoublingAndSubtractSaturateHigh(op1[img], op2[img], op3[real])), + _ => (default, default) + }; + + op1[real] = ans1; + op1[img] = ans2; } - return acc; + return op1; } - public static uint AbsoluteDifferenceWidening(ushort op1, ushort op2) => op1 < op2 ? (uint)(op2 - op1) : (uint)(op1 - op2); - - public static uint AbsoluteDifferenceWideningUpper(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - - public static uint AbsoluteDifferenceWideningAndAdd(uint op1, ushort op2, ushort op3) => (uint)(op1 + (uint)AbsoluteDifferenceWidening(op2, op3)); - - public static uint AbsoluteDifferenceWideningUpperAndAdd(uint[] op1, ushort[] op2, ushort[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - - public static uint AbsoluteDifferenceWideningLowerAndAddEven(uint[] op1, ushort[] op2, ushort[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i * 2], op3[i * 2]); - - 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 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); + public static long ShiftLeftLogicalWidening(int op1, byte op2) => UnsignedShift((long)op1, (long)op2); - public static ulong AddAcrossWideningULong(ushort[] op1) => Reduce(AddWidening, op1); + public static ulong ShiftLeftLogicalWidening(uint op1, byte op2) => UnsignedShift((ulong)op1, (long)op2); - public static uint AddPairwiseWidening(ushort[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); + public static long ShiftLeftLogicalWideningUpper(int[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); - public static uint AddPairwiseWideningAndAdd(uint[] op1, ushort[] op2, int i) => (uint)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); + public static ulong ShiftLeftLogicalWideningUpper(uint[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); - private static ushort HighNarrowing(uint op1, bool round) + public static int ShiftRightArithmeticRoundedNarrowingSaturate(long op1, byte op2) { - uint roundConst = 0; - if (round) - { - roundConst = (uint)1 << (8 * sizeof(ushort) - 1); - } - return (ushort)(((uint)op1 + roundConst) >> (8 * sizeof(ushort))); - } + int result; - public static ushort AddHighNarrowingEven(uint[] op1, uint[] op2, int i) - { - if (i % 2 == 0) - { - return (ushort) ((op1[i / 2] + op2[i / 2]) >> (8 * sizeof(ushort))); - } + SatQ(SignedShift(op1, (long)(-op2), rounding: true), out result); - return 0; + return result; } - public static ushort AddHighNarrowingOdd(ushort[] even, uint[] op1, uint[] op2, int i) + public static uint ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(long op1, byte op2) { - if (i % 2 == 1) - { - return (ushort) ((op1[(i - 1) / 2] + op2[(i - 1) / 2]) >> (8 * sizeof(ushort))); - } - - return even[i]; - } - - public static ushort AddHighNarrowing(uint op1, uint op2) => HighNarrowing((uint)(op1 + op2), round: false); - - public static ushort AddHighNarrowingUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + uint result; - public static ushort AddRoundedHighNarrowing(uint op1, uint op2) => HighNarrowing((uint)(op1 + op2), round: true); + UnsignedSatQ(SignedShift(op1, (long)(-op2), rounding: true), out result); - public static uint AddRoundedHighNarrowingUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + return result; + } - public static uint AddWidening(ushort op1, ushort op2) => (uint)((uint)op1 + (uint)op2); + public static uint ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(uint[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(op2[i - op1.Length], op3); - public static uint AddWidening(uint op1, ushort op2) => (uint)(op1 + op2); + public static int ShiftRightArithmeticRoundedNarrowingSaturateUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightArithmeticRoundedNarrowingSaturate(op2[i - op1.Length], op3); - public static ulong AddWidening(ulong op1, ushort op2) => (ulong)(op1 + (ulong)op2); + public static int ShiftRightArithmeticNarrowingSaturate(long op1, byte op2) + { + int result; - public static uint AddWideningUpper(ushort[] op1, ushort[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + SatQ(SignedShift(op1, (long)(-op2)), out result); - public static uint AddWideningUpper(uint[] op1, ushort[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); + return result; + } - public static ushort ExtractNarrowing(uint op1) => (ushort)op1; + public static uint ShiftRightArithmeticNarrowingSaturateUnsigned(long op1, byte op2) + { + uint result; - public static ushort ExtractNarrowingUpper(ushort[] op1, uint[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); + UnsignedSatQ(SignedShift(op1, (long)(-op2)), out result); - public static ushort FusedAddHalving(ushort op1, ushort op2) => (ushort)((uint)((uint)op1 + (uint)op2) >> 1); + return result; + } - public static ushort FusedAddRoundedHalving(ushort op1, ushort op2) => (ushort)((uint)((uint)op1 + (uint)op2 + 1) >> 1); + public static uint ShiftRightArithmeticNarrowingSaturateUnsignedUpper(uint[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightArithmeticNarrowingSaturateUnsigned(op2[i - op1.Length], op3); - public static ushort FusedSubtractHalving(ushort op1, ushort op2) => (ushort)((uint)((uint)op1 - (uint)op2) >> 1); + public static int ShiftRightArithmeticNarrowingSaturateUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightArithmeticNarrowingSaturate(op2[i - op1.Length], op3); - public static uint MultiplyByScalarWideningUpper(ushort[] op1, ushort op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2); + public static int ShiftRightLogicalNarrowing(long op1, byte op2) => (int)UnsignedShift(op1, (long)(-op2)); - public static uint MultiplyByScalarWideningUpperAndAdd(uint[] op1, ushort[] op2, ushort op3, int i) => MultiplyWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3); + public static uint ShiftRightLogicalNarrowing(ulong op1, byte op2) => (uint)UnsignedShift(op1, (long)(-op2)); - public static uint MultiplyByScalarWideningUpperAndSubtract(uint[] op1, ushort[] op2, ushort op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3); + public static int ShiftRightLogicalRoundedNarrowing(long op1, byte op2) => (int)UnsignedShift(op1, (long)(-op2), rounding: true); - public static uint MultiplyWidening(ushort op1, ushort op2) => (uint)((uint)op1 * (uint)op2); + public static uint ShiftRightLogicalRoundedNarrowing(ulong op1, byte op2) => (uint)UnsignedShift(op1, (long)(-op2), rounding: true); - public static uint MultiplyWideningAndAdd(uint op1, ushort op2, ushort op3) => (uint)(op1 + MultiplyWidening(op2, op3)); + public static int ShiftRightLogicalRoundedNarrowingUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); - public static uint MultiplyWideningAndSubtract(uint op1, ushort op2, ushort op3) => (uint)(op1 - MultiplyWidening(op2, op3)); + public static uint ShiftRightLogicalRoundedNarrowingUpper(uint[] op1, ulong[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); - public static uint MultiplyWideningUpper(ushort[] op1, ushort[] op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static int ShiftRightLogicalRoundedNarrowingSaturate(long op1, byte op2) + { + int result; - public static uint MultiplyWideningUpperAndAdd(uint[] op1, ushort[] op2, ushort[] op3, int i) => MultiplyWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + SatQ(UnsignedShift(op1, (long)(-op2), rounding: true), out result, reinterpretAsUnsigned: true); - public static uint MultiplyWideningUpperAndSubtract(uint[] op1, ushort[] op2, ushort[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + return result; + } - public static ushort SubtractHighNarrowing(uint op1, uint op2) => HighNarrowing((uint)(op1 - op2), round: false); + public static uint ShiftRightLogicalRoundedNarrowingSaturate(ulong op1, byte op2) + { + uint result; - public static uint SubtractHighNarrowingUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + SatQ(UnsignedShift(op1, (long)(-op2), rounding: true), out result); - public static ushort SubtractRoundedHighNarrowing(uint op1, uint op2) => HighNarrowing((uint)(op1 - op2), round: true); + return result; + } - public static uint SubtractRoundedHighNarrowingUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + public static int ShiftRightLogicalRoundedNarrowingSaturateUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); - public static uint SubtractWidening(ushort op1, ushort op2) => (uint)((uint)op1 - (uint)op2); + public static uint ShiftRightLogicalRoundedNarrowingSaturateUpper(uint[] op1, ulong[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); - public static uint SubtractWidening(uint op1, ushort op2) => (uint)(op1 - op2); + public static int ShiftRightLogicalNarrowingUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); - public static uint SubtractWideningUpper(ushort[] op1, ushort[] op2, int i) => SubtractWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static uint ShiftRightLogicalNarrowingUpper(uint[] op1, ulong[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); - public static uint SubtractWideningUpper(uint[] op1, ushort[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); + public static int ShiftRightLogicalNarrowingSaturate(long op1, byte op2) + { + int result; - public static uint ZeroExtendWidening(ushort op1) => (uint)(uint)op1; + SatQ(UnsignedShift(op1, (long)(-op2)), out result, reinterpretAsUnsigned: true); - public static uint ZeroExtendWideningUpper(ushort[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + return result; + } - private static uint Reduce(Func reduceOp, ushort[] op1) + public static uint ShiftRightLogicalNarrowingSaturate(ulong op1, byte op2) { - uint acc = op1[0]; + uint result; - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } + SatQ(UnsignedShift(op1, (long)(-op2)), out result); - return acc; + return result; } - private static ulong Reduce(Func reduceOp, ushort[] op1) + private static long GetShift(long shift, long size, bool shiftSat) { - ulong acc = op1[0]; - - for (int i = 1; i < op1.Length; i++) + if (shiftSat) { - acc = reduceOp(acc, op1[i]); + // SVE shifts are saturated to element size + shift = (int)ShiftSat(shift, size); } - - return acc; + else + { + // NEON shifts are truncated to bottom byte + shift = (sbyte)shift; + } + return shift; } - public static ulong AbsoluteDifferenceWidening(uint op1, uint op2) => op1 < op2 ? (ulong)(op2 - op1) : (ulong)(op1 - op2); - - public static ulong AbsoluteDifferenceWideningUpper(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static long ShiftSat(long shift, long size) + { + if (shift > size + 1) + { + return size + 1; + } + else if (shift < -(size + 1)) + { + return -(size + 1); + } - public static ulong AbsoluteDifferenceWideningAndAdd(ulong op1, uint op2, uint op3) => (ulong)(op1 + (ulong)AbsoluteDifferenceWidening(op2, op3)); + return shift; + } - public static ulong AbsoluteDifferenceWideningUpperAndAdd(ulong[] op1, uint[] op2, uint[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static int ShiftRightLogicalNarrowingSaturateUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); - public static ulong AbsoluteDifferenceWideningLowerAndAddEven(ulong[] op1, uint[] op2, uint[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[i * 2], op3[i * 2]); + public static uint ShiftRightLogicalNarrowingSaturateUpper(uint[] op1, ulong[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); - public static ulong AbsoluteDifferenceWideningLowerAndAddOdd(ulong[] op1, uint[] op2, uint[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); + public static long SignExtendWidening(int op1) => op1; - public static ulong AbsoluteDifferenceWideningEven(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static long SignExtendWideningUpper(int[] op1, int i) => SignExtendWidening(op1[i + op1.Length / 2]); - public static ulong AbsoluteDifferenceWideningOdd(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[(i*2) + 1], op2[(i*2) + 1]); + public static sbyte ShiftArithmetic(sbyte op1, sbyte op2) => SignedShift(op1, op2); - public static ulong AddAcrossWidening(uint[] op1) => Reduce(AddWidening, op1); + public static sbyte ShiftArithmeticRounded(sbyte op1, sbyte op2) => SignedShift(op1, op2, rounding: true); - public static ulong AddPairwiseWidening(uint[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); + public static sbyte ShiftArithmeticSaturate(sbyte op1, sbyte op2) => SignedShift(op1, op2, saturating: true); - public static ulong AddPairwiseWideningAndAdd(ulong[] op1, uint[] op2, int i) => (ulong)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); + public static sbyte ShiftArithmeticRoundedSaturate(sbyte op1, sbyte op2) => SignedShift(op1, op2, rounding: true, saturating: true); - private static uint HighNarrowing(ulong op1, bool round) + private static sbyte SignedShift(sbyte op1, sbyte op2, bool rounding = false, bool saturating = false, bool shiftSat = false) { - ulong roundConst = 0; - if (round) + int shift = (int)GetShift(op2, 8, shiftSat); + + sbyte rndCns = 0; + + if (rounding) { - roundConst = (ulong)1 << (8 * sizeof(uint) - 1); + bool ovf; + + (rndCns, ovf) = ShiftOvf((sbyte)1, -shift - 1); + + if (ovf) + { + return 0; + } } - return (uint)(((ulong)op1 + roundConst) >> (8 * sizeof(uint))); - } - public static uint AddHighNarrowingEven(ulong[] op1, ulong[] op2, int i) - { - if (i % 2 == 0) + sbyte result; + + bool addOvf; + + (result, addOvf) = AddOvf(op1, rndCns); + + if (addOvf) { - return (uint) ((op1[i / 2] + op2[i / 2]) >> (8 * sizeof(uint))); + result = (sbyte)ShiftOvf((byte)result, shift).val; } + else + { + bool shiftOvf; - return 0; + (result, shiftOvf) = ShiftOvf(result, shift); + + if (saturating) + { + if (shiftOvf) + { + result = op2 < 0 ? sbyte.MinValue : sbyte.MaxValue; + } + } + } + + return result; } - public static uint AddHighNarrowingOdd(uint[] even, ulong[] op1, ulong[] op2, int i) + public static T[] ShiftAndInsert(T[] op1, T op2) { - if (i % 2 == 1) + T nextValue = op2; + + for (int i = 0; i < op1.Length; i++) { - return (uint) ((op1[(i - 1) / 2] + op2[(i - 1) / 2]) >> (8 * sizeof(uint))); + (op1[i], nextValue) = (nextValue, op1[i]); } - return even[i]; + return op1; } - public static uint AddHighNarrowing(ulong op1, ulong op2) => HighNarrowing((ulong)(op1 + op2), round: false); + public static sbyte ShiftLeftLogical(sbyte op1, byte op2) => UnsignedShift(op1, (sbyte)op2); - public static uint AddHighNarrowingUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + public static byte ShiftLeftLogical(byte op1, byte op2) => UnsignedShift(op1, (sbyte)op2); - public static uint AddRoundedHighNarrowing(ulong op1, ulong op2) => HighNarrowing((ulong)(op1 + op2), round: true); + public static sbyte ShiftLeftLogicalSaturate(sbyte op1, byte op2) => SignedShift(op1, (sbyte)op2, saturating: true); - public static ulong AddRoundedHighNarrowingUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + public static byte ShiftLeftLogicalSaturate(byte op1, byte op2) => UnsignedShift(op1, (sbyte)op2, saturating: true); - public static ulong AddWidening(uint op1, uint op2) => (ulong)((ulong)op1 + (ulong)op2); + public static byte ShiftLeftLogicalSaturateUnsigned(sbyte op1, byte op2) => (byte)UnsignedShift(op1, (sbyte)op2, saturating: true); - public static ulong AddWidening(ulong op1, uint op2) => (ulong)(op1 + op2); + public static sbyte ShiftLogical(sbyte op1, sbyte op2) => UnsignedShift(op1, op2); - public static ulong AddWideningUpper(uint[] op1, uint[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static byte ShiftLogical(byte op1, sbyte op2) => UnsignedShift(op1, op2); - public static ulong AddWideningUpper(ulong[] op1, uint[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); + public static byte ShiftLogicalRounded(byte op1, sbyte op2) => UnsignedShift(op1, op2, rounding: true); - public static uint ExtractNarrowing(ulong op1) => (uint)op1; + public static sbyte ShiftLogicalRounded(sbyte op1, sbyte op2) => UnsignedShift(op1, op2, rounding: true); - public static uint ExtractNarrowingUpper(uint[] op1, ulong[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); + public static byte ShiftLogicalRoundedSaturate(byte op1, sbyte op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); - public static uint FusedAddHalving(uint op1, uint op2) => (uint)((ulong)((ulong)op1 + (ulong)op2) >> 1); + public static sbyte ShiftLogicalRoundedSaturate(sbyte op1, sbyte op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); - public static uint FusedAddRoundedHalving(uint op1, uint op2) => (uint)((ulong)((ulong)op1 + (ulong)op2 + 1) >> 1); + public static sbyte ShiftLogicalSaturate(sbyte op1, sbyte op2) => UnsignedShift(op1, op2, saturating: true); - public static uint FusedSubtractHalving(uint op1, uint op2) => (uint)((ulong)((ulong)op1 - (ulong)op2) >> 1); + public static byte ShiftLogicalSaturate(byte op1, sbyte op2) => UnsignedShift(op1, op2, saturating: true); - public static ulong MultiplyByScalarWideningUpper(uint[] op1, uint op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2); + public static sbyte ShiftRightArithmetic(sbyte op1, byte op2) => SignedShift(op1, (sbyte)(-op2)); - public static ulong MultiplyByScalarWideningUpperAndAdd(ulong[] op1, uint[] op2, uint op3, int i) => MultiplyWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3); + public static sbyte ShiftRightArithmeticAdd(sbyte op1, sbyte op2, byte op3) => (sbyte)(op1 + ShiftRightArithmetic(op2, op3)); - public static ulong MultiplyByScalarWideningUpperAndSubtract(ulong[] op1, uint[] op2, uint op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3); + public static sbyte ShiftRightArithmeticRounded(sbyte op1, byte op2) => SignedShift(op1, (sbyte)(-op2), rounding: true); - public static ulong MultiplyWidening(uint op1, uint op2) => (ulong)((ulong)op1 * (ulong)op2); + public static sbyte ShiftRightArithmeticRoundedAdd(sbyte op1, sbyte op2, byte op3) => (sbyte)(op1 + ShiftRightArithmeticRounded(op2, op3)); - public static ulong MultiplyWideningAndAdd(ulong op1, uint op2, uint op3) => (ulong)(op1 + MultiplyWidening(op2, op3)); + public static sbyte ShiftRightLogical(sbyte op1, byte op2) => UnsignedShift(op1, (sbyte)(-op2)); - public static ulong MultiplyWideningAndSubtract(ulong op1, uint op2, uint op3) => (ulong)(op1 - MultiplyWidening(op2, op3)); + public static byte ShiftRightLogical(byte op1, byte op2) => UnsignedShift(op1, (sbyte)(-op2)); - public static ulong MultiplyWideningUpper(uint[] op1, uint[] op2, int i) => MultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static sbyte ShiftRightLogicalAdd(sbyte op1, sbyte op2, byte op3) => (sbyte)(op1 + ShiftRightLogical(op2, op3)); - public static ulong MultiplyWideningUpperAndAdd(ulong[] op1, uint[] op2, uint[] op3, int i) => MultiplyWideningAndAdd(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static byte ShiftRightLogicalAdd(byte op1, byte op2, byte op3) => (byte)(op1 + ShiftRightLogical(op2, op3)); - public static ulong MultiplyWideningUpperAndSubtract(ulong[] op1, uint[] op2, uint[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static sbyte ShiftRightLogicalRounded(sbyte op1, byte op2) => UnsignedShift(op1, (sbyte)(-op2), rounding: true); - public static uint SubtractHighNarrowing(ulong op1, ulong op2) => HighNarrowing((ulong)(op1 - op2), round: false); + public static byte ShiftRightLogicalRounded(byte op1, byte op2) => UnsignedShift(op1, (sbyte)(-op2), rounding: true); - public static ulong SubtractHighNarrowingUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + public static sbyte ShiftRightLogicalRoundedAdd(sbyte op1, sbyte op2, byte op3) => (sbyte)(op1 + ShiftRightLogicalRounded(op2, op3)); - public static uint SubtractRoundedHighNarrowing(ulong op1, ulong op2) => HighNarrowing((ulong)(op1 - op2), round: true); + public static byte ShiftRightLogicalRoundedAdd(byte op1, byte op2, byte op3) => (byte)(op1 + ShiftRightLogicalRounded(op2, op3)); - public static ulong SubtractRoundedHighNarrowingUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); + private static byte UnsignedShift(byte op1, sbyte op2, bool rounding = false, bool saturating = false, bool shiftSat = false) + { + int shift = (int)GetShift(op2, 8, shiftSat); - public static ulong SubtractWidening(uint op1, uint op2) => (ulong)((ulong)op1 - (ulong)op2); + byte rndCns = 0; - public static ulong SubtractWidening(ulong op1, uint op2) => (ulong)(op1 - op2); + if (rounding) + { + bool ovf; - public static ulong SubtractWideningUpper(uint[] op1, uint[] op2, int i) => SubtractWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + (rndCns, ovf) = ShiftOvf((byte)1, -shift - 1); - public static ulong SubtractWideningUpper(ulong[] op1, uint[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); + if (ovf) + { + return 0; + } + } - public static ulong ZeroExtendWidening(uint op1) => (ulong)(ulong)op1; + (byte result, bool addOvf) = AddOvf(op1, rndCns); - public static ulong ZeroExtendWideningUpper(uint[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + bool shiftOvf; - private static ulong Reduce(Func reduceOp, uint[] op1) - { - ulong acc = op1[0]; + (result, shiftOvf) = ShiftOvf(result, shift); - for (int i = 1; i < op1.Length; i++) + if (addOvf) { - acc = reduceOp(acc, op1[i]); + byte shiftedCarry = ShiftOvf((byte)1, 8 * sizeof(byte) + shift).val; + result = (byte)(result | shiftedCarry); } - return acc; - } + if (saturating) + { + if (shiftOvf) + { + result = byte.MaxValue; + } + } - public static double AddWidening(double op1, float op2) => (double)(op1 + (double)op2); + return result; + } + private static sbyte UnsignedShift(sbyte op1, sbyte op2, bool rounding = false, bool saturating = false) => (sbyte)UnsignedShift((byte)op1, op2, rounding, saturating); - private static bool SignedSatQ(short val, out sbyte result) + private static (sbyte val, bool ovf) AddOvf(sbyte op1, sbyte op2) { - bool saturated = false; + sbyte result = (sbyte)(op1 + op2); - if (val > sbyte.MaxValue) - { - result = sbyte.MaxValue; - saturated = true; - } - else if (val < sbyte.MinValue) + bool ovf = false; + + if ((op1 > 0) && (op2 > 0)) { - result = sbyte.MinValue; - saturated = true; + ovf = (result < 0); } - else + else if ((op1 < 0) && (op2 < 0)) { - result = (sbyte)val; + ovf = (result > 0); } - return saturated; + return (result, ovf); } - private static bool UnsignedSatQ(short val, out byte result) + private static (sbyte val, bool ovf) AddOvf(sbyte op1, byte op2) { - bool saturated = false; + sbyte result = (sbyte)(op1 + (sbyte)op2); - if (val > byte.MaxValue) - { - result = byte.MaxValue; - saturated = true; - } - else if (val < 0) - { - result = 0; - saturated = true; - } - else - { - result = (byte)val; - } + bool ovf = (result < op1); - return saturated; + return (result, ovf); } - private static bool UnsignedSatQ(ushort val, out byte result) + private static (byte val, bool ovf) AddOvf(byte op1, sbyte op2) { - bool saturated = false; + byte result = (byte)(op1 + (byte)op2); - if (val > byte.MaxValue) - { - result = byte.MaxValue; - saturated = true; - } - else if (val < 0) + bool ovf; + + if (op2 < 0) { - result = 0; - saturated = true; + ovf = (result > op1); } else { - result = (byte)val; + ovf = (result < op1); } - return saturated; + return (result, ovf); } - private static bool SatQ(short val, out sbyte result, bool reinterpretAsUnsigned = false) + private static (byte val, bool ovf) AddOvf(byte op1, byte op2) { - bool saturated; + byte result = (byte)(op1 + op2); - if (reinterpretAsUnsigned) - { - byte res; - saturated = UnsignedSatQ((ushort)val, out res); - result = (sbyte)res; - } - else - { - saturated = SignedSatQ(val, out result); - } + bool ovf = (result < op1); - return saturated; + return (result, ovf); } - private static bool SatQ(ushort val, out byte result) => UnsignedSatQ(val, out result); - - public static sbyte ExtractNarrowingSaturate(short op1) + private static (sbyte val, bool ovf) SubtractOvf(sbyte op1, sbyte op2) { - sbyte result; + sbyte result = (sbyte)(op1 - op2); - SatQ(op1, out result); + bool ovf; - return result; - } + if (op2 < 0) + { + ovf = (result < op1); + } + else + { + ovf = (result > op1); + } - public static sbyte ExtractNarrowingSaturateUpper(sbyte[] op1, short[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturate(op2[i - op1.Length]); + return (result, ovf); + } - public static byte ExtractNarrowingSaturate(ushort op1) + private static (byte val, bool ovf) SubtractOvf(byte op1, byte op2) { - byte result; + byte result = (byte)(op1 - op2); - SatQ(op1, out result); + bool ovf = (op1 < op2); - return result; + return (result, ovf); } - public static byte ExtractNarrowingSaturateUpper(byte[] op1, ushort[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturate(op2[i - op1.Length]); + public static sbyte AbsSaturate(sbyte op1) => op1 < 0 ? NegateSaturate(op1) : op1; - public static byte ExtractNarrowingSaturateUnsigned(short op1) + public static sbyte AddSaturate(sbyte op1, sbyte op2) { - byte result; - - UnsignedSatQ(op1, out result); - - return result; + var (result, ovf) = AddOvf(op1, op2); + return ovf ? (result > 0 ? sbyte.MinValue : sbyte.MaxValue) : result; } - public static byte ExtractNarrowingSaturateUnsignedUpper(byte[] op1, short[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturateUnsigned(op2[i - op1.Length]); - - private static (short val, bool ovf) MultiplyDoublingOvf(sbyte op1, sbyte op2, bool rounding, short op3, bool subOp) + public static sbyte AddSaturate(sbyte op1, byte op2) { - short product = (short)((short)op1 * (short)op2); - - bool dblOvf; - (product, dblOvf) = AddOvf(product, product); - - bool addOvf; - short accum; - - if (subOp) - { - (accum, addOvf) = SubtractOvf(op3, product); - } - else - { - (accum, addOvf) = AddOvf(op3, product); - } - - short roundConst = 0; - - if (rounding) - { - roundConst = (short)1 << (8 * sizeof(sbyte) - 1); - } - - bool rndOvf; - short result; - - (result, rndOvf) = AddOvf(accum, roundConst); - - return (result, addOvf ^ rndOvf ^ dblOvf); + var (result, ovf) = AddOvf(op1, op2); + return ovf ? sbyte.MaxValue : result; } - private static sbyte SaturateHigh(short val, bool ovf) + public static byte AddSaturate(byte op1, sbyte op2) { - if (ovf) - { - return val < 0 ? sbyte.MaxValue : sbyte.MinValue; - } - - return (sbyte)UnsignedShift(val, (short)(-8 * sizeof(sbyte))); + var (result, ovf) = AddOvf(op1, op2); + return ovf ? (result < op1 ? byte.MaxValue : byte.MinValue) : result; } - public static sbyte MultiplyDoublingSaturateHigh(sbyte op1, sbyte op2) + public static byte AddSaturate(byte op1, byte op2) { - var (val, ovf) = MultiplyDoublingOvf(op1, op2, rounding: false, (short)0, subOp: false); - - return SaturateHigh(val, ovf); + var (result, ovf) = AddOvf(op1, op2); + return ovf ? byte.MaxValue : result; } - public static sbyte MultiplyRoundedDoublingSaturateHigh(sbyte op1, sbyte op2) + public static sbyte[] AddSaturateRotateComplex(sbyte[] op1, sbyte[] op2, byte rot) { - var (val, ovf) = MultiplyDoublingOvf(op1, op2, rounding: true, (short)0, subOp: false); + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; - return SaturateHigh(val, ovf); + if (rot == 0) + { + op1[real] = SubtractSaturate(op1[real], op2[img]); + op1[img] = AddSaturate(op1[img], op2[real]); + } + else + { + op1[real] = AddSaturate(op1[real], op2[img]); + op1[img] = SubtractSaturate(op1[img], op2[real]); + } + } + + return op1; } - public static short MultiplyDoublingWideningSaturate(sbyte op1, sbyte op2) + public static double AddSequentialAcross(double[] op1, double[] op2, double[] mask = null) { - var (product, ovf) = MultiplyDoublingOvf(op1, op2, rounding: false, (short)0, subOp: false); + // If mask isn't provided, default to all true + mask = mask ?? Enumerable.Repeat(1.0, op1.Length).ToArray(); + double result = op1[0]; - if (ovf) + for (int i = 0; i < op1.Length; i++) { - return product < 0 ? sbyte.MaxValue : sbyte.MinValue; + if (mask[i] != 0.0) + { + result += op2[i]; + } } - return product; + return result; } - public static sbyte MultiplyRoundedDoublingAndAddSaturateHigh(sbyte op1, sbyte op2, sbyte op3) + public static float AddSequentialAcross(float[] op1, float[] op2, float[] mask = null) { - short addend = UnsignedShift((short)op1, (short)(8 * sizeof(sbyte))); + // If mask isn't provided, default to all true + mask = mask ?? Enumerable.Repeat((float)1.0, op1.Length).ToArray(); + float result = op1[0]; - var (val, ovf) = MultiplyDoublingOvf(op2, op3, rounding: true, addend, subOp: false); + for (int i = 0; i < op1.Length; i++) + { + if (mask[i] != 0.0) + { + result += op2[i]; + } + } - return SaturateHigh(val, ovf); + return result; } - public static sbyte MultiplyRoundedDoublingAndSubtractSaturateHigh(sbyte op1, sbyte op2, sbyte op3) - { - short minuend = UnsignedShift((short)op1, (short)(8 * sizeof(sbyte))); + public static sbyte NegateSaturate(sbyte op1) => SubtractSaturate((sbyte)0, op1); - var (val, ovf) = MultiplyDoublingOvf(op2, op3, rounding: true, minuend, subOp: true); + public static sbyte SubtractSaturate(sbyte op1, sbyte op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? (result > 0 ? sbyte.MinValue : sbyte.MaxValue) : result; + } - return SaturateHigh(val, ovf); + public static byte SubtractSaturate(byte op1, byte op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? byte.MinValue : result; } - public static short MultiplyDoublingWideningAndAddSaturate(short op1, sbyte op2, sbyte op3) => AddSaturate(op1, MultiplyDoublingWideningSaturate(op2, op3)); + public static short ShiftArithmetic(short op1, short op2) => SignedShift(op1, op2); - public static short MultiplyDoublingWideningAndSubtractSaturate(short op1, sbyte op2, sbyte op3) => SubtractSaturate(op1, MultiplyDoublingWideningSaturate(op2, op3)); + public static short ShiftArithmeticRounded(short op1, short op2) => SignedShift(op1, op2, rounding: true); - public static short MultiplyDoublingWideningSaturateUpperByScalar(sbyte[] op1, sbyte op2, int i) => MultiplyDoublingWideningSaturate(op1[i + op1.Length / 2], op2); + public static short ShiftArithmeticSaturate(short op1, short op2) => SignedShift(op1, op2, saturating: true); - public static short MultiplyDoublingWideningUpperByScalarAndAddSaturate(short[] op1, sbyte[] op2, sbyte op3, int i) => MultiplyDoublingWideningAndAddSaturate(op1[i], op2[i + op2.Length / 2], op3); + public static short ShiftArithmeticRoundedSaturate(short op1, short op2) => SignedShift(op1, op2, rounding: true, saturating: true); - public static short MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(short[] op1, sbyte[] op2, sbyte op3, int i) => MultiplyDoublingWideningAndSubtractSaturate(op1[i], op2[i + op2.Length / 2], op3); + private static short SignedShift(short op1, short op2, bool rounding = false, bool saturating = false, bool shiftSat = false) + { + int shift = (int)GetShift(op2, 16, shiftSat); - public static short MultiplyDoublingWideningSaturateUpper(sbyte[] op1, sbyte[] op2, int i) => MultiplyDoublingWideningSaturate(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + short rndCns = 0; - public static short MultiplyDoublingWideningUpperAndAddSaturate(short[] op1, sbyte[] op2, sbyte[] op3, int i) => MultiplyDoublingWideningAndAddSaturate(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + if (rounding) + { + bool ovf; - public static short MultiplyDoublingWideningUpperAndSubtractSaturate(short[] op1, sbyte[] op2, sbyte[] op3, int i) => MultiplyDoublingWideningAndSubtractSaturate(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + (rndCns, ovf) = ShiftOvf((short)1, -shift - 1); - public static short ShiftLeftLogicalWidening(sbyte op1, byte op2) => UnsignedShift((short)op1, (short)op2); + if (ovf) + { + return 0; + } + } - public static ushort ShiftLeftLogicalWidening(byte op1, byte op2) => UnsignedShift((ushort)op1, (short)op2); + short result; - public static short ShiftLeftLogicalWideningUpper(sbyte[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + bool addOvf; - public static ushort ShiftLeftLogicalWideningUpper(byte[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + (result, addOvf) = AddOvf(op1, rndCns); - public static sbyte ShiftRightArithmeticRoundedNarrowingSaturate(short op1, byte op2) - { - sbyte result; + if (addOvf) + { + result = (short)ShiftOvf((ushort)result, shift).val; + } + else + { + bool shiftOvf; - SatQ(SignedShift(op1, (short)(-op2), rounding: true), out result); + (result, shiftOvf) = ShiftOvf(result, shift); + + if (saturating) + { + if (shiftOvf) + { + result = op1 < 0 ? short.MinValue : short.MaxValue; + } + } + } return result; } - public static byte ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(short op1, byte op2) - { - byte result; + public static short ShiftLeftLogical(short op1, byte op2) => UnsignedShift(op1, (short)op2); - UnsignedSatQ(SignedShift(op1, (short)(-op2), rounding: true), out result); + public static ushort ShiftLeftLogical(ushort op1, byte op2) => UnsignedShift(op1, (short)op2); - return result; - } + public static short ShiftLeftLogicalSaturate(short op1, byte op2) => SignedShift(op1, (short)op2, saturating: true); - public static byte ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(byte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + public static ushort ShiftLeftLogicalSaturate(ushort op1, byte op2) => UnsignedShift(op1, (short)op2, saturating: true); - public static sbyte ShiftRightArithmeticRoundedNarrowingSaturateUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightArithmeticRoundedNarrowingSaturate(op2[i - op1.Length], op3); + public static ushort ShiftLeftLogicalSaturateUnsigned(short op1, byte op2) => (ushort)UnsignedShift(op1, (short)op2, saturating: true); - public static sbyte ShiftRightArithmeticNarrowingSaturate(short op1, byte op2) - { - sbyte result; + public static short ShiftLogical(short op1, short op2) => UnsignedShift(op1, op2); - SatQ(SignedShift(op1, (short)(-op2)), out result); + public static ushort ShiftLogical(ushort op1, short op2) => UnsignedShift(op1, op2); - return result; - } + public static ushort ShiftLogicalRounded(ushort op1, short op2) => UnsignedShift(op1, op2, rounding: true); - public static byte ShiftRightArithmeticNarrowingSaturateUnsigned(short op1, byte op2) - { - byte result; + public static short ShiftLogicalRounded(short op1, short op2) => UnsignedShift(op1, op2, rounding: true); - UnsignedSatQ(SignedShift(op1, (short)(-op2)), out result); + public static ushort ShiftLogicalRoundedSaturate(ushort op1, short op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); - return result; - } + public static short ShiftLogicalRoundedSaturate(short op1, short op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); - public static byte ShiftRightArithmeticNarrowingSaturateUnsignedUpper(byte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightArithmeticNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + public static short ShiftLogicalSaturate(short op1, short op2) => UnsignedShift(op1, op2, saturating: true); - public static sbyte ShiftRightArithmeticNarrowingSaturateUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightArithmeticNarrowingSaturate(op2[i - op1.Length], op3); + public static ushort ShiftLogicalSaturate(ushort op1, short op2) => UnsignedShift(op1, op2, saturating: true); - public static sbyte ShiftRightLogicalNarrowing(short op1, byte op2) => (sbyte)UnsignedShift(op1, (short)(-op2)); + public static short ShiftRightArithmetic(short op1, byte op2) => SignedShift(op1, (short)(-op2)); - public static byte ShiftRightLogicalNarrowing(ushort op1, byte op2) => (byte)UnsignedShift(op1, (short)(-op2)); + public static short ShiftRightArithmeticAdd(short op1, short op2, byte op3) => (short)(op1 + ShiftRightArithmetic(op2, op3)); - public static sbyte ShiftRightLogicalRoundedNarrowing(short op1, byte op2) => (sbyte)UnsignedShift(op1, (short)(-op2), rounding: true); + public static short ShiftRightArithmeticRounded(short op1, byte op2) => SignedShift(op1, (short)(-op2), rounding: true); - public static byte ShiftRightLogicalRoundedNarrowing(ushort op1, byte op2) => (byte)UnsignedShift(op1, (short)(-op2), rounding: true); + public static short ShiftRightArithmeticRoundedAdd(short op1, short op2, byte op3) => (short)(op1 + ShiftRightArithmeticRounded(op2, op3)); - public static sbyte ShiftRightLogicalRoundedNarrowingUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + public static short ShiftRightLogical(short op1, byte op2) => UnsignedShift(op1, (short)(-op2)); - public static byte ShiftRightLogicalRoundedNarrowingUpper(byte[] op1, ushort[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + public static ushort ShiftRightLogical(ushort op1, byte op2) => UnsignedShift(op1, (short)(-op2)); - public static sbyte ShiftRightLogicalRoundedNarrowingSaturate(short op1, byte op2) - { - sbyte result; + public static short ShiftRightLogicalAdd(short op1, short op2, byte op3) => (short)(op1 + ShiftRightLogical(op2, op3)); - SatQ(UnsignedShift(op1, (short)(-op2), rounding: true), out result, reinterpretAsUnsigned: true); + public static ushort ShiftRightLogicalAdd(ushort op1, ushort op2, byte op3) => (ushort)(op1 + ShiftRightLogical(op2, op3)); - return result; - } + public static short ShiftRightLogicalRounded(short op1, byte op2) => UnsignedShift(op1, (short)(-op2), rounding: true); - public static byte ShiftRightLogicalRoundedNarrowingSaturate(ushort op1, byte op2) - { - byte result; + public static ushort ShiftRightLogicalRounded(ushort op1, byte op2) => UnsignedShift(op1, (short)(-op2), rounding: true); - SatQ(UnsignedShift(op1, (short)(-op2), rounding: true), out result); + public static short ShiftRightLogicalRoundedAdd(short op1, short op2, byte op3) => (short)(op1 + ShiftRightLogicalRounded(op2, op3)); - return result; - } + public static ushort ShiftRightLogicalRoundedAdd(ushort op1, ushort op2, byte op3) => (ushort)(op1 + ShiftRightLogicalRounded(op2, op3)); - public static sbyte ShiftRightLogicalRoundedNarrowingSaturateUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + private static ushort UnsignedShift(ushort op1, short op2, bool rounding = false, bool saturating = false, bool shiftSat = false) + { + int shift = (int)GetShift(op2, 16, shiftSat); - public static byte ShiftRightLogicalRoundedNarrowingSaturateUpper(byte[] op1, ushort[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + ushort rndCns = 0; - public static sbyte ShiftRightLogicalNarrowingUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + if (rounding) + { + bool ovf; - public static byte ShiftRightLogicalNarrowingUpper(byte[] op1, ushort[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + (rndCns, ovf) = ShiftOvf((ushort)1, -shift - 1); - public static sbyte ShiftRightLogicalNarrowingSaturate(short op1, byte op2) - { - sbyte result; + if (ovf) + { + return 0; + } + } - SatQ(UnsignedShift(op1, (short)(-op2)), out result, reinterpretAsUnsigned: true); + (ushort result, bool addOvf) = AddOvf(op1, rndCns); - return result; - } + bool shiftOvf; - public static byte ShiftRightLogicalNarrowingSaturate(ushort op1, byte op2) - { - byte result; + (result, shiftOvf) = ShiftOvf(result, shift); - SatQ(UnsignedShift(op1, (short)(-op2)), out result); + if (addOvf) + { + ushort shiftedCarry = ShiftOvf((ushort)1, 8 * sizeof(ushort) + shift).val; + result = (ushort)(result | shiftedCarry); + } + + if (saturating) + { + if (shiftOvf) + { + result = ushort.MaxValue; + } + } return result; } - public static sbyte ShiftRightLogicalNarrowingSaturateUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); - - public static byte ShiftRightLogicalNarrowingSaturateUpper(byte[] op1, ushort[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); - - public static short SignExtendWidening(sbyte op1) => op1; - - public static short SignExtendWideningUpper(sbyte[] op1, int i) => SignExtendWidening(op1[i + op1.Length / 2]); + private static short UnsignedShift(short op1, short op2, bool rounding = false, bool saturating = false) => (short)UnsignedShift((ushort)op1, op2, rounding, saturating); - private static bool SignedSatQ(int val, out short result) + private static (short val, bool ovf) AddOvf(short op1, short op2) { - bool saturated = false; + short result = (short)(op1 + op2); - if (val > short.MaxValue) - { - result = short.MaxValue; - saturated = true; - } - else if (val < short.MinValue) + bool ovf = false; + + if ((op1 > 0) && (op2 > 0)) { - result = short.MinValue; - saturated = true; + ovf = (result < 0); } - else + else if ((op1 < 0) && (op2 < 0)) { - result = (short)val; + ovf = (result > 0); } - return saturated; + return (result, ovf); } - private static bool UnsignedSatQ(int val, out ushort result) + private static (short val, bool ovf) AddOvf(short op1, ushort op2) { - bool saturated = false; + short result = (short)(op1 + (short)op2); - if (val > ushort.MaxValue) - { - result = ushort.MaxValue; - saturated = true; - } - else if (val < 0) - { - result = 0; - saturated = true; - } - else - { - result = (ushort)val; - } + bool ovf = (result < op1); - return saturated; + return (result, ovf); } - private static bool UnsignedSatQ(uint val, out ushort result) + private static (ushort val, bool ovf) AddOvf(ushort op1, short op2) { - bool saturated = false; + ushort result = (ushort)(op1 + (ushort)op2); - if (val > ushort.MaxValue) - { - result = ushort.MaxValue; - saturated = true; - } - else if (val < 0) + bool ovf; + + if (op2 < 0) { - result = 0; - saturated = true; + ovf = (result > op1); } else { - result = (ushort)val; + ovf = (result < op1); } - return saturated; + return (result, ovf); } - private static bool SatQ(int val, out short result, bool reinterpretAsUnsigned = false) + private static (ushort val, bool ovf) AddOvf(ushort op1, ushort op2) { - bool saturated; + ushort result = (ushort)(op1 + op2); - if (reinterpretAsUnsigned) + bool ovf = (result < op1); + + return (result, ovf); + } + + private static (short val, bool ovf) SubtractOvf(short op1, short op2) + { + short result = (short)(op1 - op2); + + bool ovf; + + if (op2 < 0) { - ushort res; - saturated = UnsignedSatQ((uint)val, out res); - result = (short)res; + ovf = (result < op1); } else { - saturated = SignedSatQ(val, out result); + ovf = (result > op1); } - return saturated; + return (result, ovf); } - private static bool SatQ(uint val, out ushort result) => UnsignedSatQ(val, out result); - - public static short ExtractNarrowingSaturate(int op1) + private static (ushort val, bool ovf) SubtractOvf(ushort op1, ushort op2) { - short result; + ushort result = (ushort)(op1 - op2); - SatQ(op1, out result); + bool ovf = (op1 < op2); - return result; + return (result, ovf); } - public static short ExtractNarrowingSaturateUpper(short[] op1, int[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturate(op2[i - op1.Length]); + public static short AbsSaturate(short op1) => op1 < 0 ? NegateSaturate(op1) : op1; - public static ushort ExtractNarrowingSaturate(uint op1) + public static short AddSaturate(short op1, short op2) { - ushort result; + var (result, ovf) = AddOvf(op1, op2); + return ovf ? (result > 0 ? short.MinValue : short.MaxValue) : result; + } - SatQ(op1, out result); + public static short AddSaturate(short op1, ushort op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? short.MaxValue : result; + } - return result; + public static ushort AddSaturate(ushort op1, short op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? (result < op1 ? ushort.MaxValue : ushort.MinValue) : result; } - public static ushort ExtractNarrowingSaturateUpper(ushort[] op1, uint[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturate(op2[i - op1.Length]); + public static ushort AddSaturate(ushort op1, ushort op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? ushort.MaxValue : result; + } - public static ushort ExtractNarrowingSaturateUnsigned(int op1) + public static short[] AddSaturateRotateComplex(short[] op1, short[] op2, byte rot) { - ushort result; + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; - UnsignedSatQ(op1, out result); + if (rot == 0) + { + op1[real] = SubtractSaturate(op1[real], op2[img]); + op1[img] = AddSaturate(op1[img], op2[real]); + } + else + { + op1[real] = AddSaturate(op1[real], op2[img]); + op1[img] = SubtractSaturate(op1[img], op2[real]); + } + } - return result; + return op1; } - public static ushort ExtractNarrowingSaturateUnsignedUpper(ushort[] op1, int[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturateUnsigned(op2[i - op1.Length]); + public static short NegateSaturate(short op1) => SubtractSaturate((short)0, op1); - private static (int val, bool ovf) MultiplyDoublingOvf(short op1, short op2, bool rounding, int op3, bool subOp) + public static short SubtractSaturate(short op1, short op2) { - int product = (int)((int)op1 * (int)op2); + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? (result > 0 ? short.MinValue : short.MaxValue) : result; + } - bool dblOvf; - (product, dblOvf) = AddOvf(product, product); + public static ushort SubtractSaturate(ushort op1, ushort op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? ushort.MinValue : result; + } - bool addOvf; - int accum; + public static int ShiftArithmetic(int op1, int op2) => SignedShift(op1, op2); - if (subOp) - { - (accum, addOvf) = SubtractOvf(op3, product); - } - else - { - (accum, addOvf) = AddOvf(op3, product); - } + public static int ShiftArithmeticRounded(int op1, int op2) => SignedShift(op1, op2, rounding: true); - int roundConst = 0; + public static int ShiftArithmeticSaturate(int op1, int op2) => SignedShift(op1, op2, saturating: true); + + public static int ShiftArithmeticRoundedSaturate(int op1, int op2) => SignedShift(op1, op2, rounding: true, saturating: true); + + private static int SignedShift(int op1, int op2, bool rounding = false, bool saturating = false, bool shiftSat = false) + { + int shift = (int)GetShift(op2, 32, shiftSat); + + int rndCns = 0; if (rounding) { - roundConst = (int)1 << (8 * sizeof(short) - 1); - } - - bool rndOvf; - int result; + bool ovf; - (result, rndOvf) = AddOvf(accum, roundConst); + (rndCns, ovf) = ShiftOvf((int)1, -shift - 1); - return (result, addOvf ^ rndOvf ^ dblOvf); - } - - private static short SaturateHigh(int val, bool ovf) - { - if (ovf) - { - return val < 0 ? short.MaxValue : short.MinValue; + if (ovf) + { + return 0; + } } - return (short)UnsignedShift(val, (int)(-8 * sizeof(short))); - } - - public static short MultiplyDoublingSaturateHigh(short op1, short op2) - { - var (val, ovf) = MultiplyDoublingOvf(op1, op2, rounding: false, (int)0, subOp: false); - - return SaturateHigh(val, ovf); - } - - public static short MultiplyRoundedDoublingSaturateHigh(short op1, short op2) - { - var (val, ovf) = MultiplyDoublingOvf(op1, op2, rounding: true, (int)0, subOp: false); + int result; - return SaturateHigh(val, ovf); - } + bool addOvf; - public static int MultiplyDoublingWideningSaturate(short op1, short op2) - { - var (product, ovf) = MultiplyDoublingOvf(op1, op2, rounding: false, (int)0, subOp: false); + (result, addOvf) = AddOvf(op1, rndCns); - if (ovf) + if (addOvf) { - return product < 0 ? short.MaxValue : short.MinValue; + result = (int)ShiftOvf((uint)result, shift).val; } + else + { + bool shiftOvf; - return product; - } - - public static short MultiplyRoundedDoublingAndAddSaturateHigh(short op1, short op2, short op3) - { - int addend = UnsignedShift((int)op1, (int)(8 * sizeof(short))); + (result, shiftOvf) = ShiftOvf(result, shift); - var (val, ovf) = MultiplyDoublingOvf(op2, op3, rounding: true, addend, subOp: false); + if (saturating) + { + if (shiftOvf) + { + result = op1 < 0 ? int.MinValue : int.MaxValue; + } + } + } - return SaturateHigh(val, ovf); + return result; } - public static short MultiplyRoundedDoublingAndSubtractSaturateHigh(short op1, short op2, short op3) - { - int minuend = UnsignedShift((int)op1, (int)(8 * sizeof(short))); - - var (val, ovf) = MultiplyDoublingOvf(op2, op3, rounding: true, minuend, subOp: true); + public static int ShiftLeftLogical(int op1, byte op2) => UnsignedShift(op1, (int)op2); - return SaturateHigh(val, ovf); - } + public static uint ShiftLeftLogical(uint op1, byte op2) => UnsignedShift(op1, (int)op2); - public static int MultiplyDoublingWideningAndAddSaturate(int op1, short op2, short op3) => AddSaturate(op1, MultiplyDoublingWideningSaturate(op2, op3)); + public static int ShiftLeftLogicalSaturate(int op1, byte op2) => SignedShift(op1, (int)op2, saturating: true); - public static int MultiplyDoublingWideningAndSubtractSaturate(int op1, short op2, short op3) => SubtractSaturate(op1, MultiplyDoublingWideningSaturate(op2, op3)); + public static uint ShiftLeftLogicalSaturate(uint op1, byte op2) => UnsignedShift(op1, (int)op2, saturating: true); - public static int MultiplyDoublingWideningSaturateUpperByScalar(short[] op1, short op2, int i) => MultiplyDoublingWideningSaturate(op1[i + op1.Length / 2], op2); + public static uint ShiftLeftLogicalSaturateUnsigned(int op1, byte op2) => (uint)UnsignedShift(op1, (int)op2, saturating: true); - public static int MultiplyDoublingWideningUpperByScalarAndAddSaturate(int[] op1, short[] op2, short op3, int i) => MultiplyDoublingWideningAndAddSaturate(op1[i], op2[i + op2.Length / 2], op3); + public static int ShiftLogical(int op1, int op2) => UnsignedShift(op1, op2); - public static int MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(int[] op1, short[] op2, short op3, int i) => MultiplyDoublingWideningAndSubtractSaturate(op1[i], op2[i + op2.Length / 2], op3); + public static uint ShiftLogical(uint op1, int op2) => UnsignedShift(op1, op2); - public static int MultiplyDoublingWideningSaturateUpper(short[] op1, short[] op2, int i) => MultiplyDoublingWideningSaturate(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static uint ShiftLogicalRounded(uint op1, int op2) => UnsignedShift(op1, op2, rounding: true); - public static int MultiplyDoublingWideningUpperAndAddSaturate(int[] op1, short[] op2, short[] op3, int i) => MultiplyDoublingWideningAndAddSaturate(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static int ShiftLogicalRounded(int op1, int op2) => UnsignedShift(op1, op2, rounding: true); - public static int MultiplyDoublingWideningUpperAndSubtractSaturate(int[] op1, short[] op2, short[] op3, int i) => MultiplyDoublingWideningAndSubtractSaturate(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static uint ShiftLogicalRoundedSaturate(uint op1, int op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); - public static int ShiftLeftLogicalWidening(short op1, byte op2) => UnsignedShift((int)op1, (int)op2); + public static int ShiftLogicalRoundedSaturate(int op1, int op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); - public static uint ShiftLeftLogicalWidening(ushort op1, byte op2) => UnsignedShift((uint)op1, (int)op2); + public static int ShiftLogicalSaturate(int op1, int op2) => UnsignedShift(op1, op2, saturating: true); - public static int ShiftLeftLogicalWideningUpper(short[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + public static uint ShiftLogicalSaturate(uint op1, int op2) => UnsignedShift(op1, op2, saturating: true); - public static uint ShiftLeftLogicalWideningUpper(ushort[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + public static int ShiftRightArithmetic(int op1, byte op2) => SignedShift(op1, (int)(-op2)); - public static short ShiftRightArithmeticRoundedNarrowingSaturate(int op1, byte op2) - { - short result; + public static int ShiftRightArithmeticAdd(int op1, int op2, byte op3) => (int)(op1 + ShiftRightArithmetic(op2, op3)); - SatQ(SignedShift(op1, (int)(-op2), rounding: true), out result); + public static int ShiftRightArithmeticRounded(int op1, byte op2) => SignedShift(op1, (int)(-op2), rounding: true); - return result; - } + public static int ShiftRightArithmeticRoundedAdd(int op1, int op2, byte op3) => (int)(op1 + ShiftRightArithmeticRounded(op2, op3)); - public static ushort ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(int op1, byte op2) - { - ushort result; + public static int ShiftRightLogical(int op1, byte op2) => UnsignedShift(op1, (int)(-op2)); - UnsignedSatQ(SignedShift(op1, (int)(-op2), rounding: true), out result); + public static uint ShiftRightLogical(uint op1, byte op2) => UnsignedShift(op1, (int)(-op2)); - return result; - } + public static int ShiftRightLogicalAdd(int op1, int op2, byte op3) => (int)(op1 + ShiftRightLogical(op2, op3)); - public static ushort ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(ushort[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + public static uint ShiftRightLogicalAdd(uint op1, uint op2, byte op3) => (uint)(op1 + ShiftRightLogical(op2, op3)); - public static short ShiftRightArithmeticRoundedNarrowingSaturateUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightArithmeticRoundedNarrowingSaturate(op2[i - op1.Length], op3); + public static int ShiftRightLogicalRounded(int op1, byte op2) => UnsignedShift(op1, (int)(-op2), rounding: true); - public static short ShiftRightArithmeticNarrowingSaturate(int op1, byte op2) - { - short result; + public static uint ShiftRightLogicalRounded(uint op1, byte op2) => UnsignedShift(op1, (int)(-op2), rounding: true); - SatQ(SignedShift(op1, (int)(-op2)), out result); + public static int ShiftRightLogicalRoundedAdd(int op1, int op2, byte op3) => (int)(op1 + ShiftRightLogicalRounded(op2, op3)); - return result; - } + public static uint ShiftRightLogicalRoundedAdd(uint op1, uint op2, byte op3) => (uint)(op1 + ShiftRightLogicalRounded(op2, op3)); - public static ushort ShiftRightArithmeticNarrowingSaturateUnsigned(int op1, byte op2) + private static uint UnsignedShift(uint op1, int op2, bool rounding = false, bool saturating = false, bool shiftSat = false) { - ushort result; - - UnsignedSatQ(SignedShift(op1, (int)(-op2)), out result); - - return result; - } - - public static ushort ShiftRightArithmeticNarrowingSaturateUnsignedUpper(ushort[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightArithmeticNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + int shift = (int)GetShift(op2, 32, shiftSat); - public static short ShiftRightArithmeticNarrowingSaturateUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightArithmeticNarrowingSaturate(op2[i - op1.Length], op3); + uint rndCns = 0; - public static short ShiftRightLogicalNarrowing(int op1, byte op2) => (short)UnsignedShift(op1, (int)(-op2)); + if (rounding) + { + bool ovf; - public static ushort ShiftRightLogicalNarrowing(uint op1, byte op2) => (ushort)UnsignedShift(op1, (int)(-op2)); + (rndCns, ovf) = ShiftOvf((uint)1, -shift - 1); - public static short ShiftRightLogicalRoundedNarrowing(int op1, byte op2) => (short)UnsignedShift(op1, (int)(-op2), rounding: true); + if (ovf) + { + return 0; + } + } - public static ushort ShiftRightLogicalRoundedNarrowing(uint op1, byte op2) => (ushort)UnsignedShift(op1, (int)(-op2), rounding: true); + (uint result, bool addOvf) = AddOvf(op1, rndCns); - public static short ShiftRightLogicalRoundedNarrowingUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + bool shiftOvf; - public static ushort ShiftRightLogicalRoundedNarrowingUpper(ushort[] op1, uint[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + (result, shiftOvf) = ShiftOvf(result, shift); - public static short ShiftRightLogicalRoundedNarrowingSaturate(int op1, byte op2) - { - short result; + if (addOvf) + { + uint shiftedCarry = ShiftOvf((uint)1, 8 * sizeof(uint) + shift).val; + result = (uint)(result | shiftedCarry); + } - SatQ(UnsignedShift(op1, (int)(-op2), rounding: true), out result, reinterpretAsUnsigned: true); + if (saturating) + { + if (shiftOvf) + { + result = uint.MaxValue; + } + } return result; } - public static ushort ShiftRightLogicalRoundedNarrowingSaturate(uint op1, byte op2) - { - ushort result; - - SatQ(UnsignedShift(op1, (int)(-op2), rounding: true), out result); - - return result; - } + private static int UnsignedShift(int op1, int op2, bool rounding = false, bool saturating = false) => (int)UnsignedShift((uint)op1, op2, rounding, saturating); - public static short ShiftRightLogicalRoundedNarrowingSaturateUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + private static (int val, bool ovf) AddOvf(int op1, int op2) + { + int result = (int)(op1 + op2); - public static ushort ShiftRightLogicalRoundedNarrowingSaturateUpper(ushort[] op1, uint[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + bool ovf = false; - public static short ShiftRightLogicalNarrowingUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + if ((op1 > 0) && (op2 > 0)) + { + ovf = (result < 0); + } + else if ((op1 < 0) && (op2 < 0)) + { + ovf = (result > 0); + } - public static ushort ShiftRightLogicalNarrowingUpper(ushort[] op1, uint[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + return (result, ovf); + } - public static short ShiftRightLogicalNarrowingSaturate(int op1, byte op2) + private static (int val, bool ovf) AddOvf(int op1, uint op2) { - short result; + int result = (int)(op1 + (int)op2); - SatQ(UnsignedShift(op1, (int)(-op2)), out result, reinterpretAsUnsigned: true); + bool ovf = (result < op1); - return result; + return (result, ovf); } - public static ushort ShiftRightLogicalNarrowingSaturate(uint op1, byte op2) + private static (uint val, bool ovf) AddOvf(uint op1, int op2) { - ushort result; + uint result = (uint)(op1 + (uint)op2); - SatQ(UnsignedShift(op1, (int)(-op2)), out result); + bool ovf; - return result; - } + if (op2 < 0) + { + ovf = (result > op1); + } + else + { + ovf = (result < op1); + } - public static short ShiftRightLogicalNarrowingSaturateUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); + return (result, ovf); + } - public static ushort ShiftRightLogicalNarrowingSaturateUpper(ushort[] op1, uint[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); + private static (uint val, bool ovf) AddOvf(uint op1, uint op2) + { + uint result = (uint)(op1 + op2); - public static int SignExtendWidening(short op1) => op1; + bool ovf = (result < op1); - public static int SignExtendWideningUpper(short[] op1, int i) => SignExtendWidening(op1[i + op1.Length / 2]); + return (result, ovf); + } - private static bool SignedSatQ(long val, out int result) + private static (int val, bool ovf) SubtractOvf(int op1, int op2) { - bool saturated = false; + int result = (int)(op1 - op2); - if (val > int.MaxValue) - { - result = int.MaxValue; - saturated = true; - } - else if (val < int.MinValue) + bool ovf; + + if (op2 < 0) { - result = int.MinValue; - saturated = true; + ovf = (result < op1); } else { - result = (int)val; + ovf = (result > op1); } - return saturated; + return (result, ovf); } - private static bool UnsignedSatQ(long val, out uint result) + private static (uint val, bool ovf) SubtractOvf(uint op1, uint op2) { - bool saturated = false; + uint result = (uint)(op1 - op2); - if (val > uint.MaxValue) - { - result = uint.MaxValue; - saturated = true; - } - else if (val < 0) - { - result = 0; - saturated = true; - } - else - { - result = (uint)val; - } + bool ovf = (op1 < op2); - return saturated; + return (result, ovf); } - private static bool UnsignedSatQ(ulong val, out uint result) + public static int AbsSaturate(int op1) => op1 < 0 ? NegateSaturate(op1) : op1; + + public static int AddSaturate(int op1, int op2) { - bool saturated = false; + var (result, ovf) = AddOvf(op1, op2); + return ovf ? (result > 0 ? int.MinValue : int.MaxValue) : result; + } - if (val > uint.MaxValue) - { - result = uint.MaxValue; - saturated = true; - } - else if (val < 0) - { - result = 0; - saturated = true; - } - else - { - result = (uint)val; - } + public static int AddSaturate(int op1, uint op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? int.MaxValue : result; + } - return saturated; + public static uint AddSaturate(uint op1, int op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? (result < op1 ? uint.MaxValue : uint.MinValue) : result; } - private static bool SatQ(long val, out int result, bool reinterpretAsUnsigned = false) + public static uint AddSaturate(uint op1, uint op2) { - bool saturated; + var (result, ovf) = AddOvf(op1, op2); + return ovf ? uint.MaxValue : result; + } - if (reinterpretAsUnsigned) - { - uint res; - saturated = UnsignedSatQ((ulong)val, out res); - result = (int)res; - } - else + public static int[] AddSaturateRotateComplex(int[] op1, int[] op2, byte rot) + { + for (int i = 0; i < op1.Length; i += 2) { - saturated = SignedSatQ(val, out result); + int real = i; + int img = i + 1; + + if (rot == 0) + { + op1[real] = SubtractSaturate(op1[real], op2[img]); + op1[img] = AddSaturate(op1[img], op2[real]); + } + else + { + op1[real] = AddSaturate(op1[real], op2[img]); + op1[img] = SubtractSaturate(op1[img], op2[real]); + } } - return saturated; + return op1; } - private static bool SatQ(ulong val, out uint result) => UnsignedSatQ(val, out result); + public static int NegateSaturate(int op1) => SubtractSaturate((int)0, op1); - public static int ExtractNarrowingSaturate(long op1) + public static int SubtractSaturate(int op1, int op2) { - int result; - - SatQ(op1, out result); - - return result; + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? (result > 0 ? int.MinValue : int.MaxValue) : result; } - public static int ExtractNarrowingSaturateUpper(int[] op1, long[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturate(op2[i - op1.Length]); - - public static uint ExtractNarrowingSaturate(ulong op1) + public static uint SubtractSaturate(uint op1, uint op2) { - uint result; - - SatQ(op1, out result); - - return result; + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? uint.MinValue : result; } - public static uint ExtractNarrowingSaturateUpper(uint[] op1, ulong[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturate(op2[i - op1.Length]); - - public static uint ExtractNarrowingSaturateUnsigned(long op1) - { - uint result; + public static long ShiftArithmetic(long op1, long op2) => SignedShift(op1, op2); - UnsignedSatQ(op1, out result); + public static long ShiftArithmeticRounded(long op1, long op2) => SignedShift(op1, op2, rounding: true); - return result; - } + public static long ShiftArithmeticSaturate(long op1, long op2) => SignedShift(op1, op2, saturating: true); - public static uint ExtractNarrowingSaturateUnsignedUpper(uint[] op1, long[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowingSaturateUnsigned(op2[i - op1.Length]); + public static long ShiftArithmeticRoundedSaturate(long op1, long op2) => SignedShift(op1, op2, rounding: true, saturating: true); - private static (long val, bool ovf) MultiplyDoublingOvf(int op1, int op2, bool rounding, long op3, bool subOp) + private static long SignedShift(long op1, long op2, bool rounding = false, bool saturating = false, bool shiftSat = false) { - long product = (long)((long)op1 * (long)op2); - - bool dblOvf; - (product, dblOvf) = AddOvf(product, product); + int shift = (int)GetShift(op2, 64, shiftSat); - bool addOvf; - long accum; + long rndCns = 0; - if (subOp) - { - (accum, addOvf) = SubtractOvf(op3, product); - } - else + if (rounding) { - (accum, addOvf) = AddOvf(op3, product); - } + bool ovf; - long roundConst = 0; + (rndCns, ovf) = ShiftOvf((long)1, -shift - 1); - if (rounding) - { - roundConst = (long)1 << (8 * sizeof(int) - 1); + if (ovf) + { + return 0; + } } - bool rndOvf; long result; - (result, rndOvf) = AddOvf(accum, roundConst); + bool addOvf; - return (result, addOvf ^ rndOvf ^ dblOvf); - } + (result, addOvf) = AddOvf(op1, rndCns); - private static int SaturateHigh(long val, bool ovf) - { - if (ovf) + if (addOvf) { - return val < 0 ? int.MaxValue : int.MinValue; + result = (long)ShiftOvf((ulong)result, shift).val; } + else + { + bool shiftOvf; - return (int)UnsignedShift(val, (long)(-8 * sizeof(int))); - } + (result, shiftOvf) = ShiftOvf(result, shift); - public static int MultiplyDoublingSaturateHigh(int op1, int op2) - { - var (val, ovf) = MultiplyDoublingOvf(op1, op2, rounding: false, (long)0, subOp: false); + if (saturating) + { + if (shiftOvf) + { + result = op1 < 0 ? long.MinValue : long.MaxValue; + } + } + } - return SaturateHigh(val, ovf); + return result; } - public static int MultiplyRoundedDoublingSaturateHigh(int op1, int op2) - { - var (val, ovf) = MultiplyDoublingOvf(op1, op2, rounding: true, (long)0, subOp: false); - - return SaturateHigh(val, ovf); - } + public static long ShiftLeftLogical(long op1, byte op2) => UnsignedShift(op1, (long)op2); - public static long MultiplyDoublingWideningSaturate(int op1, int op2) - { - var (product, ovf) = MultiplyDoublingOvf(op1, op2, rounding: false, (long)0, subOp: false); + public static ulong ShiftLeftLogical(ulong op1, byte op2) => UnsignedShift(op1, (long)op2); - if (ovf) - { - return product < 0 ? int.MaxValue : int.MinValue; - } + public static long ShiftLeftLogicalSaturate(long op1, byte op2) => SignedShift(op1, (long)op2, saturating: true); - return product; - } + public static ulong ShiftLeftLogicalSaturate(ulong op1, byte op2) => UnsignedShift(op1, (long)op2, saturating: true); - public static int MultiplyRoundedDoublingAndAddSaturateHigh(int op1, int op2, int op3) - { - long addend = UnsignedShift((long)op1, (long)(8 * sizeof(int))); + public static ulong ShiftLeftLogicalSaturateUnsigned(long op1, byte op2) => (ulong)UnsignedShift(op1, (long)op2, saturating: true); - var (val, ovf) = MultiplyDoublingOvf(op2, op3, rounding: true, addend, subOp: false); + public static long ShiftLogical(long op1, long op2) => UnsignedShift(op1, op2); - return SaturateHigh(val, ovf); - } + public static ulong ShiftLogical(ulong op1, long op2) => UnsignedShift(op1, op2); - public static int MultiplyRoundedDoublingAndSubtractSaturateHigh(int op1, int op2, int op3) - { - long minuend = UnsignedShift((long)op1, (long)(8 * sizeof(int))); + public static ulong ShiftLogicalRounded(ulong op1, long op2) => UnsignedShift(op1, op2, rounding: true); - var (val, ovf) = MultiplyDoublingOvf(op2, op3, rounding: true, minuend, subOp: true); + public static long ShiftLogicalRounded(long op1, long op2) => UnsignedShift(op1, op2, rounding: true); - return SaturateHigh(val, ovf); - } + public static ulong ShiftLogicalRoundedSaturate(ulong op1, long op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); - public static long MultiplyDoublingWideningAndAddSaturate(long op1, int op2, int op3) => AddSaturate(op1, MultiplyDoublingWideningSaturate(op2, op3)); + public static long ShiftLogicalRoundedSaturate(long op1, long op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); - public static long MultiplyDoublingWideningAndSubtractSaturate(long op1, int op2, int op3) => SubtractSaturate(op1, MultiplyDoublingWideningSaturate(op2, op3)); + public static long ShiftLogicalSaturate(long op1, long op2) => UnsignedShift(op1, op2, saturating: true); - public static long MultiplyDoublingWideningSaturateUpperByScalar(int[] op1, int op2, int i) => MultiplyDoublingWideningSaturate(op1[i + op1.Length / 2], op2); + public static ulong ShiftLogicalSaturate(ulong op1, long op2) => UnsignedShift(op1, op2, saturating: true); - public static long MultiplyDoublingWideningUpperByScalarAndAddSaturate(long[] op1, int[] op2, int op3, int i) => MultiplyDoublingWideningAndAddSaturate(op1[i], op2[i + op2.Length / 2], op3); + public static long ShiftRightArithmetic(long op1, byte op2) => SignedShift(op1, (long)(-op2)); - public static long MultiplyDoublingWideningUpperByScalarAndSubtractSaturate(long[] op1, int[] op2, int op3, int i) => MultiplyDoublingWideningAndSubtractSaturate(op1[i], op2[i + op2.Length / 2], op3); + public static long ShiftRightArithmeticAdd(long op1, long op2, byte op3) => (long)(op1 + ShiftRightArithmetic(op2, op3)); - public static long MultiplyDoublingWideningSaturateUpper(int[] op1, int[] op2, int i) => MultiplyDoublingWideningSaturate(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + public static long ShiftRightArithmeticRounded(long op1, byte op2) => SignedShift(op1, (long)(-op2), rounding: true); - public static long MultiplyDoublingWideningUpperAndAddSaturate(long[] op1, int[] op2, int[] op3, int i) => MultiplyDoublingWideningAndAddSaturate(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static long ShiftRightArithmeticRoundedAdd(long op1, long op2, byte op3) => (long)(op1 + ShiftRightArithmeticRounded(op2, op3)); - public static long MultiplyDoublingWideningUpperAndSubtractSaturate(long[] op1, int[] op2, int[] op3, int i) => MultiplyDoublingWideningAndSubtractSaturate(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static long ShiftRightLogical(long op1, byte op2) => UnsignedShift(op1, (long)(-op2)); - public static long ShiftLeftLogicalWidening(int op1, byte op2) => UnsignedShift((long)op1, (long)op2); + public static ulong ShiftRightLogical(ulong op1, byte op2) => UnsignedShift(op1, (long)(-op2)); - public static ulong ShiftLeftLogicalWidening(uint op1, byte op2) => UnsignedShift((ulong)op1, (long)op2); + public static long ShiftRightLogicalAdd(long op1, long op2, byte op3) => (long)(op1 + ShiftRightLogical(op2, op3)); - public static long ShiftLeftLogicalWideningUpper(int[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + public static ulong ShiftRightLogicalAdd(ulong op1, ulong op2, byte op3) => (ulong)(op1 + ShiftRightLogical(op2, op3)); - public static ulong ShiftLeftLogicalWideningUpper(uint[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + public static long ShiftRightLogicalRounded(long op1, byte op2) => UnsignedShift(op1, (long)(-op2), rounding: true); - public static int ShiftRightArithmeticRoundedNarrowingSaturate(long op1, byte op2) - { - int result; + public static ulong ShiftRightLogicalRounded(ulong op1, byte op2) => UnsignedShift(op1, (long)(-op2), rounding: true); - SatQ(SignedShift(op1, (long)(-op2), rounding: true), out result); + public static long ShiftRightLogicalRoundedAdd(long op1, long op2, byte op3) => (long)(op1 + ShiftRightLogicalRounded(op2, op3)); - return result; - } + public static ulong ShiftRightLogicalRoundedAdd(ulong op1, ulong op2, byte op3) => (ulong)(op1 + ShiftRightLogicalRounded(op2, op3)); - public static uint ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(long op1, byte op2) + private static ulong UnsignedShift(ulong op1, long op2, bool rounding = false, bool saturating = false, bool shiftSat = false) { - uint result; - - UnsignedSatQ(SignedShift(op1, (long)(-op2), rounding: true), out result); + int shift = (int)GetShift(op2, 64, shiftSat); - return result; - } + ulong rndCns = 0; - public static uint ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(uint[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + if (rounding) + { + bool ovf; - public static int ShiftRightArithmeticRoundedNarrowingSaturateUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightArithmeticRoundedNarrowingSaturate(op2[i - op1.Length], op3); + (rndCns, ovf) = ShiftOvf((ulong)1, -shift - 1); - public static int ShiftRightArithmeticNarrowingSaturate(long op1, byte op2) - { - int result; + if (ovf) + { + return 0; + } + } - SatQ(SignedShift(op1, (long)(-op2)), out result); + (ulong result, bool addOvf) = AddOvf(op1, rndCns); - return result; - } + bool shiftOvf; - public static uint ShiftRightArithmeticNarrowingSaturateUnsigned(long op1, byte op2) - { - uint result; + (result, shiftOvf) = ShiftOvf(result, shift); - UnsignedSatQ(SignedShift(op1, (long)(-op2)), out result); + if (addOvf) + { + ulong shiftedCarry = ShiftOvf((ulong)1, 8 * sizeof(ulong) + shift).val; + result = (ulong)(result | shiftedCarry); + } + + if (saturating) + { + if (shiftOvf) + { + result = ulong.MaxValue; + } + } return result; } - public static uint ShiftRightArithmeticNarrowingSaturateUnsignedUpper(uint[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightArithmeticNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + private static long UnsignedShift(long op1, long op2, bool rounding = false, bool saturating = false) => (long)UnsignedShift((ulong)op1, op2, rounding, saturating); - public static int ShiftRightArithmeticNarrowingSaturateUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightArithmeticNarrowingSaturate(op2[i - op1.Length], op3); + private static (long val, bool ovf) AddOvf(long op1, long op2) + { + long result = (long)(op1 + op2); - public static int ShiftRightLogicalNarrowing(long op1, byte op2) => (int)UnsignedShift(op1, (long)(-op2)); + bool ovf = false; - public static uint ShiftRightLogicalNarrowing(ulong op1, byte op2) => (uint)UnsignedShift(op1, (long)(-op2)); + if ((op1 > 0) && (op2 > 0)) + { + ovf = (result < 0); + } + else if ((op1 < 0) && (op2 < 0)) + { + ovf = (result > 0); + } - public static int ShiftRightLogicalRoundedNarrowing(long op1, byte op2) => (int)UnsignedShift(op1, (long)(-op2), rounding: true); + return (result, ovf); + } - public static uint ShiftRightLogicalRoundedNarrowing(ulong op1, byte op2) => (uint)UnsignedShift(op1, (long)(-op2), rounding: true); + private static (long val, bool ovf) AddOvf(long op1, ulong op2) + { + long result = (long)(op1 + (long)op2); - public static int ShiftRightLogicalRoundedNarrowingUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + bool ovf = (result < op1); - public static uint ShiftRightLogicalRoundedNarrowingUpper(uint[] op1, ulong[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + return (result, ovf); + } - public static int ShiftRightLogicalRoundedNarrowingSaturate(long op1, byte op2) + private static (ulong val, bool ovf) AddOvf(ulong op1, long op2) { - int result; + ulong result = (ulong)(op1 + (ulong)op2); - SatQ(UnsignedShift(op1, (long)(-op2), rounding: true), out result, reinterpretAsUnsigned: true); + bool ovf; - return result; + if (op2 < 0) + { + ovf = (result > op1); + } + else + { + ovf = (result < op1); + } + + return (result, ovf); } - public static uint ShiftRightLogicalRoundedNarrowingSaturate(ulong op1, byte op2) + private static (ulong val, bool ovf) AddOvf(ulong op1, ulong op2) { - uint result; + ulong result = (ulong)(op1 + op2); - SatQ(UnsignedShift(op1, (long)(-op2), rounding: true), out result); + bool ovf = (result < op1); - return result; + return (result, ovf); } - public static int ShiftRightLogicalRoundedNarrowingSaturateUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + private static (long val, bool ovf) SubtractOvf(long op1, long op2) + { + long result = (long)(op1 - op2); - public static uint ShiftRightLogicalRoundedNarrowingSaturateUpper(uint[] op1, ulong[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + bool ovf; - public static int ShiftRightLogicalNarrowingUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + if (op2 < 0) + { + ovf = (result < op1); + } + else + { + ovf = (result > op1); + } - public static uint ShiftRightLogicalNarrowingUpper(uint[] op1, ulong[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + return (result, ovf); + } - public static int ShiftRightLogicalNarrowingSaturate(long op1, byte op2) + private static (ulong val, bool ovf) SubtractOvf(ulong op1, ulong op2) { - int result; + ulong result = (ulong)(op1 - op2); - SatQ(UnsignedShift(op1, (long)(-op2)), out result, reinterpretAsUnsigned: true); + bool ovf = (op1 < op2); - return result; + return (result, ovf); } - public static uint ShiftRightLogicalNarrowingSaturate(ulong op1, byte op2) + public static long AbsSaturate(long op1) => op1 < 0 ? NegateSaturate(op1) : op1; + + public static long AddSaturate(long op1, long op2) { - uint result; + var (result, ovf) = AddOvf(op1, op2); + return ovf ? (result > 0 ? long.MinValue : long.MaxValue) : result; + } - SatQ(UnsignedShift(op1, (long)(-op2)), out result); + public static long AddSaturate(long op1, ulong op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? long.MaxValue : result; + } - return result; + public static ulong AddSaturate(ulong op1, long op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? (result < op1 ? ulong.MaxValue : ulong.MinValue) : result; } - private static long GetShift(long shift, long size, bool shiftSat) + public static ulong AddSaturate(ulong op1, ulong op2) { - if (shiftSat) - { - // SVE shifts are saturated to element size - shift = (int)ShiftSat(shift, size); - } - else - { - // NEON shifts are truncated to bottom byte - shift = (sbyte)shift; - } - return shift; + var (result, ovf) = AddOvf(op1, op2); + return ovf ? ulong.MaxValue : result; } - public static long ShiftSat(long shift, long size) + public static long[] AddSaturateRotateComplex(long[] op1, long[] op2, byte rot) { - if (shift > size + 1) - { - return size + 1; - } - else if (shift < -(size + 1)) + for (int i = 0; i < op1.Length; i += 2) { - return -(size + 1); + int real = i; + int img = i + 1; + + if (rot == 0) + { + op1[real] = SubtractSaturate(op1[real], op2[img]); + op1[img] = AddSaturate(op1[img], op2[real]); + } + else + { + op1[real] = AddSaturate(op1[real], op2[img]); + op1[img] = SubtractSaturate(op1[img], op2[real]); + } } - return shift; + return op1; } - public static int ShiftRightLogicalNarrowingSaturateUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); - - public static uint ShiftRightLogicalNarrowingSaturateUpper(uint[] op1, ulong[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); - - public static long SignExtendWidening(int op1) => op1; - - public static long SignExtendWideningUpper(int[] op1, int i) => SignExtendWidening(op1[i + op1.Length / 2]); - - public static sbyte ShiftArithmetic(sbyte op1, sbyte op2) => SignedShift(op1, op2); + public static long NegateSaturate(long op1) => SubtractSaturate((long)0, op1); - public static sbyte ShiftArithmeticRounded(sbyte op1, sbyte op2) => SignedShift(op1, op2, rounding: true); + public static long SubtractSaturate(long op1, long op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? (result > 0 ? long.MinValue : long.MaxValue) : result; + } - public static sbyte ShiftArithmeticSaturate(sbyte op1, sbyte op2) => SignedShift(op1, op2, saturating: true); + public static ulong SubtractSaturate(ulong op1, ulong op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? ulong.MinValue : result; + } - public static sbyte ShiftArithmeticRoundedSaturate(sbyte op1, sbyte op2) => SignedShift(op1, op2, rounding: true, saturating: true); - private static sbyte SignedShift(sbyte op1, sbyte op2, bool rounding = false, bool saturating = false, bool shiftSat = false) + private static (sbyte val, bool ovf) ShiftOvf(sbyte value, int shift) { - int shift = (int)GetShift(op2, 8, shiftSat); + sbyte result = value; - sbyte rndCns = 0; + bool ovf = false; + sbyte msb = 1; + msb = (sbyte)(msb << (8 * sizeof(sbyte) - 1)); - if (rounding) + for (int i = 0; i < shift; i++) { - bool ovf; + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } - (rndCns, ovf) = ShiftOvf((sbyte)1, -shift - 1); + for (int i = 0; i > shift; i--) + { + result >>= 1; + } - if (ovf) - { - return 0; - } + if ((value > 0) && (result < 0)) + { + ovf = true; } - sbyte result; + return (result, ovf); + } - bool addOvf; - (result, addOvf) = AddOvf(op1, rndCns); + private static (byte val, bool ovf) ShiftOvf(byte value, int shift) + { + byte result = value; - if (addOvf) + bool ovf = false; + byte msb = 1; + msb = (byte)(msb << (8 * sizeof(byte) - 1)); + + for (int i = 0; i < shift; i++) { - result = (sbyte)ShiftOvf((byte)result, shift).val; + ovf = ovf || ((result & msb) != 0); + result <<= 1; } - else - { - bool shiftOvf; - (result, shiftOvf) = ShiftOvf(result, shift); + for (int i = 0; i > shift; i--) + { + result >>= 1; + } - if (saturating) - { - if (shiftOvf) - { - result = op2 < 0 ? sbyte.MinValue : sbyte.MaxValue; - } - } + if ((value > 0) && (result < 0)) + { + ovf = true; } - return result; + return (result, ovf); } - public static T[] ShiftAndInsert(T[] op1, T op2) + + private static (short val, bool ovf) ShiftOvf(short value, int shift) { - T nextValue = op2; + short result = value; - for (int i = 0; i < op1.Length; i++) - { - (op1[i], nextValue) = (nextValue, op1[i]); - } + bool ovf = false; + short msb = 1; + msb = (short)(msb << (8 * sizeof(short) - 1)); - return op1; - } + for (int i = 0; i < shift; i++) + { + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } - public static sbyte ShiftLeftLogical(sbyte op1, byte op2) => UnsignedShift(op1, (sbyte)op2); + for (int i = 0; i > shift; i--) + { + result >>= 1; + } - public static byte ShiftLeftLogical(byte op1, byte op2) => UnsignedShift(op1, (sbyte)op2); + if ((value > 0) && (result < 0)) + { + ovf = true; + } - public static sbyte ShiftLeftLogicalSaturate(sbyte op1, byte op2) => SignedShift(op1, (sbyte)op2, saturating: true); + return (result, ovf); + } - public static byte ShiftLeftLogicalSaturate(byte op1, byte op2) => UnsignedShift(op1, (sbyte)op2, saturating: true); - public static byte ShiftLeftLogicalSaturateUnsigned(sbyte op1, byte op2) => (byte)UnsignedShift(op1, (sbyte)op2, saturating: true); + private static (ushort val, bool ovf) ShiftOvf(ushort value, int shift) + { + ushort result = value; - public static sbyte ShiftLogical(sbyte op1, sbyte op2) => UnsignedShift(op1, op2); + bool ovf = false; + ushort msb = 1; + msb = (ushort)(msb << (8 * sizeof(ushort) - 1)); - public static byte ShiftLogical(byte op1, sbyte op2) => UnsignedShift(op1, op2); + for (int i = 0; i < shift; i++) + { + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } - public static byte ShiftLogicalRounded(byte op1, sbyte op2) => UnsignedShift(op1, op2, rounding: true); + for (int i = 0; i > shift; i--) + { + result >>= 1; + } - public static sbyte ShiftLogicalRounded(sbyte op1, sbyte op2) => UnsignedShift(op1, op2, rounding: true); + if ((value > 0) && (result < 0)) + { + ovf = true; + } - public static byte ShiftLogicalRoundedSaturate(byte op1, sbyte op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); + return (result, ovf); + } - public static sbyte ShiftLogicalRoundedSaturate(sbyte op1, sbyte op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); - public static sbyte ShiftLogicalSaturate(sbyte op1, sbyte op2) => UnsignedShift(op1, op2, saturating: true); + private static (int val, bool ovf) ShiftOvf(int value, int shift) + { + int result = value; - public static byte ShiftLogicalSaturate(byte op1, sbyte op2) => UnsignedShift(op1, op2, saturating: true); + bool ovf = false; + int msb = 1; + msb = (int)(msb << (8 * sizeof(int) - 1)); - public static sbyte ShiftRightArithmetic(sbyte op1, byte op2) => SignedShift(op1, (sbyte)(-op2)); + for (int i = 0; i < shift; i++) + { + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } - public static sbyte ShiftRightArithmeticAdd(sbyte op1, sbyte op2, byte op3) => (sbyte)(op1 + ShiftRightArithmetic(op2, op3)); + for (int i = 0; i > shift; i--) + { + result >>= 1; + } - public static sbyte ShiftRightArithmeticRounded(sbyte op1, byte op2) => SignedShift(op1, (sbyte)(-op2), rounding: true); + if ((value > 0) && (result < 0)) + { + ovf = true; + } - public static sbyte ShiftRightArithmeticRoundedAdd(sbyte op1, sbyte op2, byte op3) => (sbyte)(op1 + ShiftRightArithmeticRounded(op2, op3)); + return (result, ovf); + } - public static sbyte ShiftRightLogical(sbyte op1, byte op2) => UnsignedShift(op1, (sbyte)(-op2)); - public static byte ShiftRightLogical(byte op1, byte op2) => UnsignedShift(op1, (sbyte)(-op2)); + private static (uint val, bool ovf) ShiftOvf(uint value, int shift) + { + uint result = value; - public static sbyte ShiftRightLogicalAdd(sbyte op1, sbyte op2, byte op3) => (sbyte)(op1 + ShiftRightLogical(op2, op3)); + bool ovf = false; + uint msb = 1; + msb = (uint)(msb << (8 * sizeof(uint) - 1)); - public static byte ShiftRightLogicalAdd(byte op1, byte op2, byte op3) => (byte)(op1 + ShiftRightLogical(op2, op3)); + for (int i = 0; i < shift; i++) + { + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } - public static sbyte ShiftRightLogicalRounded(sbyte op1, byte op2) => UnsignedShift(op1, (sbyte)(-op2), rounding: true); + for (int i = 0; i > shift; i--) + { + result >>= 1; + } - public static byte ShiftRightLogicalRounded(byte op1, byte op2) => UnsignedShift(op1, (sbyte)(-op2), rounding: true); + if ((value > 0) && (result < 0)) + { + ovf = true; + } - public static sbyte ShiftRightLogicalRoundedAdd(sbyte op1, sbyte op2, byte op3) => (sbyte)(op1 + ShiftRightLogicalRounded(op2, op3)); + return (result, ovf); + } - public static byte ShiftRightLogicalRoundedAdd(byte op1, byte op2, byte op3) => (byte)(op1 + ShiftRightLogicalRounded(op2, op3)); - private static byte UnsignedShift(byte op1, sbyte op2, bool rounding = false, bool saturating = false, bool shiftSat = false) + private static (long val, bool ovf) ShiftOvf(long value, int shift) { - int shift = (int)GetShift(op2, 8, shiftSat); + long result = value; - byte rndCns = 0; + bool ovf = false; + long msb = 1; + msb = (long)(msb << (8 * sizeof(long) - 1)); - if (rounding) + for (int i = 0; i < shift; i++) { - bool ovf; - - (rndCns, ovf) = ShiftOvf((byte)1, -shift - 1); - - if (ovf) - { - return 0; - } + ovf = ovf || ((result & msb) != 0); + result <<= 1; } - (byte result, bool addOvf) = AddOvf(op1, rndCns); - - bool shiftOvf; - - (result, shiftOvf) = ShiftOvf(result, shift); - - if (addOvf) + for (int i = 0; i > shift; i--) { - byte shiftedCarry = ShiftOvf((byte)1, 8 * sizeof(byte) + shift).val; - result = (byte)(result | shiftedCarry); + result >>= 1; } - if (saturating) + if ((value > 0) && (result < 0)) { - if (shiftOvf) - { - result = byte.MaxValue; - } + ovf = true; } - return result; + return (result, ovf); } - private static sbyte UnsignedShift(sbyte op1, sbyte op2, bool rounding = false, bool saturating = false) => (sbyte)UnsignedShift((byte)op1, op2, rounding, saturating); - private static (sbyte val, bool ovf) AddOvf(sbyte op1, sbyte op2) + private static (ulong val, bool ovf) ShiftOvf(ulong value, int shift) { - sbyte result = (sbyte)(op1 + op2); + ulong result = value; bool ovf = false; + ulong msb = 1; + msb = (ulong)(msb << (8 * sizeof(ulong) - 1)); - if ((op1 > 0) && (op2 > 0)) + for (int i = 0; i < shift; i++) { - ovf = (result < 0); + ovf = ovf || ((result & msb) != 0); + result <<= 1; } - else if ((op1 < 0) && (op2 < 0)) + + for (int i = 0; i > shift; i--) { - ovf = (result > 0); + result >>= 1; + } + + if ((value > 0) && (result < 0)) + { + ovf = true; } return (result, ovf); } - private static (sbyte val, bool ovf) AddOvf(sbyte op1, byte op2) + public static float AbsoluteDifference(float op1, float op2) => MathF.Abs(op1 - op2); + + public static float ConvertToSingleEvenRoundToOdd(double[] value, int i) { - sbyte result = (sbyte)(op1 + (sbyte)op2); + if (i % 2 == 0) + { + double val = value[i / 2]; + float floatVal = (float)val; - bool ovf = (result < op1); + float f = (float)val; - return (result, ovf); - } + // If val is NaN or Inf there’s nothing else to do + if (double.IsNaN(val) || double.IsInfinity(val)) + return f; - private static (byte val, bool ovf) AddOvf(byte op1, sbyte op2) - { - byte result = (byte)(op1 + (byte)op2); + // Detect the cases where the default cast rounded away from zero + if ((val > 0 && (double)f > val) || + (val < 0 && (double)f < val)) + { + // Move toward zero to get truncate() behaviour. + int bits = BitConverter.SingleToInt32Bits(f); + bits += (val > 0) ? -1 : +1; + f = BitConverter.Int32BitsToSingle(bits); + } - bool ovf; + // Round to odd, force the last bit of the mantissa to 1 if the conversion was inexact + if (val != (double)f) + { + int bits = BitConverter.SingleToInt32Bits(f); + bits |= 0x1; + f = BitConverter.Int32BitsToSingle(bits); + } - if (op2 < 0) - { - ovf = (result > op1); - } - else - { - ovf = (result < op1); + return f; } - return (result, ovf); + return 0f; } - private static (byte val, bool ovf) AddOvf(byte op1, byte op2) - { - byte result = (byte)(op1 + op2); + public static float FusedMultiplyAdd(float op1, float op2, float op3) => MathF.FusedMultiplyAdd(op2, op3, op1); - bool ovf = (result < op1); + public static float FusedMultiplyAddNegated(float op1, float op2, float op3) => MathF.FusedMultiplyAdd(-op2, op3, -op1); - return (result, ovf); - } + public static float FusedMultiplySubtract(float op1, float op2, float op3) => MathF.FusedMultiplyAdd(-op2, op3, op1); - private static (sbyte val, bool ovf) SubtractOvf(sbyte op1, sbyte op2) - { - sbyte result = (sbyte)(op1 - op2); + public static float FusedMultiplySubtractNegated(float op1, float op2, float op3) => MathF.FusedMultiplyAdd(op2, op3, -op1); - bool ovf; + public static float MaxNumber(float op1, float op2) => float.IsNaN(op1) ? op2 : (float.IsNaN(op2) ? op1 : MathF.Max(op1, op2)); - if (op2 < 0) - { - ovf = (result < op1); - } - else - { - ovf = (result > op1); - } + public static float MaxNumberPairwise(float[] op1, int i) => Pairwise(MaxNumber, op1, i); - return (result, ovf); - } + public static float MaxNumberPairwise(float[] op1, float[] op2, int i) => Pairwise(MaxNumber, op1, op2, i); - private static (byte val, bool ovf) SubtractOvf(byte op1, byte op2) - { - byte result = (byte)(op1 - op2); + public static float MaxNumberPairwiseSve(float[] op1, float[] op2, int i) => (i % 2 == 0) ? MaxNumber(op1[i], op1[i + 1]) : MaxNumber(op2[i - 1], op2[i]); - bool ovf = (op1 < op2); + public static float MaxPairwiseSve(float[] op1, float[] op2, int i) => (i % 2 == 0) ? Max(op1[i], op1[i + 1]) : Max(op2[i - 1], op2[i]); - return (result, ovf); - } + public static float MinNumber(float op1, float op2) => float.IsNaN(op1) ? op2 : (float.IsNaN(op2) ? op1 : MathF.Min(op1, op2)); - public static sbyte AbsSaturate(sbyte op1) => op1 < 0 ? NegateSaturate(op1) : op1; + public static float MinNumberPairwise(float[] op1, int i) => Pairwise(MinNumber, op1, i); - public static sbyte AddSaturate(sbyte op1, sbyte op2) - { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? (result > 0 ? sbyte.MinValue : sbyte.MaxValue) : result; - } + public static float MinNumberPairwise(float[] op1, float[] op2, int i) => Pairwise(MinNumber, op1, op2, i); - public static sbyte AddSaturate(sbyte op1, byte op2) - { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? sbyte.MaxValue : result; - } + public static float MinNumberPairwiseSve(float[] op1, float[] op2, int i) => (i % 2 == 0) ? MinNumber(op1[i], op1[i + 1]) : MinNumber(op2[i - 1], op2[i]); - public static byte AddSaturate(byte op1, sbyte op2) - { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? (result < op1 ? byte.MaxValue : byte.MinValue) : result; - } + public static float MinPairwiseSve(float[] op1, float[] op2, int i) => (i % 2 == 0) ? Min(op1[i], op1[i + 1]) : Min(op2[i - 1], op2[i]); - public static byte AddSaturate(byte op1, byte op2) + public static float[] MultiplyAddRotateComplex(float[] op1, float[] op2, float[] op3, byte imm) { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? byte.MaxValue : result; - } - - public static double AddSequentialAcross(double[] op1, double[] op2, double[] mask = null) - { - // If mask isn't provided, default to all true - mask = mask ?? Enumerable.Repeat(1.0, op1.Length).ToArray(); - double result = op1[0]; - - for (int i = 0; i < op1.Length; i++) + for (int i = 0; i < op1.Length; i += 2) { - if (mask[i] != 0.0) + int real = i; + int img = i + 1; + (float ans1, float ans2) = imm switch { - result += op2[i]; - } + 0 => (FusedMultiplyAdd(op1[real], op2[real], op3[real]), FusedMultiplyAdd(op1[img], op2[real], op3[img])), + 1 => (FusedMultiplySubtract(op1[real], op2[img], op3[img]), FusedMultiplyAdd(op1[img], op2[img], op3[real])), + 2 => (FusedMultiplySubtract(op1[real], op2[real], op3[real]), FusedMultiplySubtract(op1[img], op2[real], op3[img])), + 3 => (FusedMultiplyAdd(op1[real], op2[img], op3[img]), FusedMultiplySubtract(op1[img], op2[img], op3[real])), + _ => (0.0f, 0.0f) + }; + + op1[real] = ans1; + op1[img] = ans2; } - return result; + return op1; } - public static float AddSequentialAcross(float[] op1, float[] op2, float[] mask = null) + public static T[] MultiplyAddRotateComplex(T[] op1, T[] op2, T[] op3, byte imm) where T : INumber { - // If mask isn't provided, default to all true - mask = mask ?? Enumerable.Repeat((float)1.0, op1.Length).ToArray(); - float result = op1[0]; - - for (int i = 0; i < op1.Length; i++) + for (int i = 0; i < op1.Length; i += 2) { - if (mask[i] != 0.0) + int real = i; + int img = i + 1; + (T ans1, T ans2) = imm switch { - result += op2[i]; - } - } - - return result; - } + 0 => (op1[real] + op2[real] * op3[real], op1[img] + op2[real] * op3[img]), + 1 => (op1[real] - op2[img] * op3[img], op1[img] + op2[img] * op3[real]), + 2 => (op1[real] - op2[real] * op3[real], op1[img] - op2[real] * op3[img]), + 3 => (op1[real] + op2[img] * op3[img], op1[img] - op2[img] * op3[real]), + _ => (default, default) + }; - public static sbyte NegateSaturate(sbyte op1) => SubtractSaturate((sbyte)0, op1); + op1[real] = ans1; + op1[img] = ans2; + } - public static sbyte SubtractSaturate(sbyte op1, sbyte op2) - { - var (result, ovf) = SubtractOvf(op1, op2); - return ovf ? (result > 0 ? sbyte.MinValue : sbyte.MaxValue) : result; + return op1; } - public static byte SubtractSaturate(byte op1, byte op2) + public static float[] MultiplyAddRotateComplexBySelectedScalar(float[] op1, float[] op2, float[] op3, byte index, byte imm) { - var (result, ovf) = SubtractOvf(op1, op2); - return ovf ? byte.MinValue : result; - } - - public static short ShiftArithmetic(short op1, short op2) => SignedShift(op1, op2); - - public static short ShiftArithmeticRounded(short op1, short op2) => SignedShift(op1, op2, rounding: true); + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; + (float op3Real, float op3Img) = (op3[index * 2], op3[(index * 2) + 1]); + (float ans1, float ans2) = imm switch + { + 0 => (FusedMultiplyAdd(op1[real], op2[real], op3Real), FusedMultiplyAdd(op1[img], op2[real], op3Img)), + 1 => (FusedMultiplySubtract(op1[real], op2[img], op3Img), FusedMultiplyAdd(op1[img], op2[img], op3Real)), + 2 => (FusedMultiplySubtract(op1[real], op2[real], op3Real), FusedMultiplySubtract(op1[img], op2[real], op3Img)), + 3 => (FusedMultiplyAdd(op1[real], op2[img], op3Img), FusedMultiplySubtract(op1[img], op2[img], op3Real)), + _ => (0.0f, 0.0f) + }; - public static short ShiftArithmeticSaturate(short op1, short op2) => SignedShift(op1, op2, saturating: true); + op1[real] = ans1; + op1[img] = ans2; + } - public static short ShiftArithmeticRoundedSaturate(short op1, short op2) => SignedShift(op1, op2, rounding: true, saturating: true); + return op1; + } - private static short SignedShift(short op1, short op2, bool rounding = false, bool saturating = false, bool shiftSat = false) + public static T[] MultiplyAddRotateComplexBySelectedScalar(T[] op1, T[] op2, T[] op3, byte index, byte imm) where T : INumber { - int shift = (int)GetShift(op2, 16, shiftSat); - - short rndCns = 0; - - if (rounding) + for (int i = 0; i < op1.Length; i += 2) { - bool ovf; - - (rndCns, ovf) = ShiftOvf((short)1, -shift - 1); + int real = i; + int img = i + 1; + (T op3Real, T op3Img) = (op3[index * 2], op3[(index * 2) + 1]); + (T ans1, T ans2) = imm switch + { + 0 => (op1[real] + op2[real] * op3Real, op1[img] + op2[real] * op3Img), + 1 => (op1[real] - op2[img] * op3Img, op1[img] + op2[img] * op3Real), + 2 => (op1[real] - op2[real] * op3Real, op1[img] - op2[real] * op3Img), + 3 => (op1[real] + op2[img] * op3Img, op1[img] - op2[img] * op3Real), + _ => (default, default) + }; - if (ovf) - { - return 0; - } + op1[real] = ans1; + op1[img] = ans2; } - short result; + return op1; + } - bool addOvf; + public static float MultiplyExtended(float op1, float op2) + { + bool inf1 = float.IsInfinity(op1); + bool inf2 = float.IsInfinity(op2); - (result, addOvf) = AddOvf(op1, rndCns); + bool zero1 = (op1 == 0); + bool zero2 = (op2 == 0); - if (addOvf) + if ((inf1 && zero2) || (zero1 && inf2)) { - result = (short)ShiftOvf((ushort)result, shift).val; + return MathF.CopySign(2, (zero1 ? op2 : op1)); } else { - bool shiftOvf; - - (result, shiftOvf) = ShiftOvf(result, shift); - - if (saturating) - { - if (shiftOvf) - { - result = op1 < 0 ? short.MinValue : short.MaxValue; - } - } + return op1 * op2; } - - return result; } - public static short ShiftLeftLogical(short op1, byte op2) => UnsignedShift(op1, (short)op2); - - public static ushort ShiftLeftLogical(ushort op1, byte op2) => UnsignedShift(op1, (short)op2); - - public static short ShiftLeftLogicalSaturate(short op1, byte op2) => SignedShift(op1, (short)op2, saturating: true); - - public static ushort ShiftLeftLogicalSaturate(ushort op1, byte op2) => UnsignedShift(op1, (short)op2, saturating: true); - - public static ushort ShiftLeftLogicalSaturateUnsigned(short op1, byte op2) => (ushort)UnsignedShift(op1, (short)op2, saturating: true); - - public static short ShiftLogical(short op1, short op2) => UnsignedShift(op1, op2); - - public static ushort ShiftLogical(ushort op1, short op2) => UnsignedShift(op1, op2); - - public static ushort ShiftLogicalRounded(ushort op1, short op2) => UnsignedShift(op1, op2, rounding: true); - - public static short ShiftLogicalRounded(short op1, short op2) => UnsignedShift(op1, op2, rounding: true); - - public static ushort ShiftLogicalRoundedSaturate(ushort op1, short op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); - - public static short ShiftLogicalRoundedSaturate(short op1, short op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); - - public static short ShiftLogicalSaturate(short op1, short op2) => UnsignedShift(op1, op2, saturating: true); - - public static ushort ShiftLogicalSaturate(ushort op1, short op2) => UnsignedShift(op1, op2, saturating: true); - - public static short ShiftRightArithmetic(short op1, byte op2) => SignedShift(op1, (short)(-op2)); - - public static short ShiftRightArithmeticAdd(short op1, short op2, byte op3) => (short)(op1 + ShiftRightArithmetic(op2, op3)); - - public static short ShiftRightArithmeticRounded(short op1, byte op2) => SignedShift(op1, (short)(-op2), rounding: true); - - public static short ShiftRightArithmeticRoundedAdd(short op1, short op2, byte op3) => (short)(op1 + ShiftRightArithmeticRounded(op2, op3)); - - public static short ShiftRightLogical(short op1, byte op2) => UnsignedShift(op1, (short)(-op2)); - - public static ushort ShiftRightLogical(ushort op1, byte op2) => UnsignedShift(op1, (short)(-op2)); - - public static short ShiftRightLogicalAdd(short op1, short op2, byte op3) => (short)(op1 + ShiftRightLogical(op2, op3)); - - public static ushort ShiftRightLogicalAdd(ushort op1, ushort op2, byte op3) => (ushort)(op1 + ShiftRightLogical(op2, op3)); - - public static short ShiftRightLogicalRounded(short op1, byte op2) => UnsignedShift(op1, (short)(-op2), rounding: true); - - public static ushort ShiftRightLogicalRounded(ushort op1, byte op2) => UnsignedShift(op1, (short)(-op2), rounding: true); - - public static short ShiftRightLogicalRoundedAdd(short op1, short op2, byte op3) => (short)(op1 + ShiftRightLogicalRounded(op2, op3)); - - public static ushort ShiftRightLogicalRoundedAdd(ushort op1, ushort op2, byte op3) => (ushort)(op1 + ShiftRightLogicalRounded(op2, op3)); - - private static ushort UnsignedShift(ushort op1, short op2, bool rounding = false, bool saturating = false, bool shiftSat = false) + public static float TrigonometricMultiplyAddCoefficient(float op1, float op2, byte imm) { - int shift = (int)GetShift(op2, 16, shiftSat); - - ushort rndCns = 0; - - if (rounding) + int index = (op2 < 0) ? (imm + 8) : imm; + uint coeff = index switch { - bool ovf; - - (rndCns, ovf) = ShiftOvf((ushort)1, -shift - 1); - - if (ovf) - { - return 0; - } - } - - (ushort result, bool addOvf) = AddOvf(op1, rndCns); - - bool shiftOvf; + 0 => 0x3f800000, + 1 => 0xbe2aaaab, + 2 => 0x3c088886, + 3 => 0xb95008b9, + 4 => 0x36369d6d, + 5 => 0x00000000, + 6 => 0x00000000, + 7 => 0x00000000, + 8 => 0x3f800000, + 9 => 0xbf000000, + 10 => 0x3d2aaaa6, + 11 => 0xbab60705, + 12 => 0x37cd37cc, + 13 => 0x00000000, + 14 => 0x00000000, + 15 => 0x00000000, + _ => 0x00000000 + }; - (result, shiftOvf) = ShiftOvf(result, shift); + return MathF.FusedMultiplyAdd(op1, Math.Abs(op2), BitConverter.UInt32BitsToSingle(coeff)); + } - if (addOvf) - { - ushort shiftedCarry = ShiftOvf((ushort)1, 8 * sizeof(ushort) + shift).val; - result = (ushort)(result | shiftedCarry); - } + public static float TrigonometricSelectCoefficient(float op1, uint op2) + { + float result = ((op2 % 2) == 0) ? op1 : (float)1.0; + bool isNegative = (op2 & 0b10) == 0b10; - if (saturating) + if (isNegative != (result < 0)) { - if (shiftOvf) - { - result = ushort.MaxValue; - } + result *= -1; } return result; } - private static short UnsignedShift(short op1, short op2, bool rounding = false, bool saturating = false) => (short)UnsignedShift((ushort)op1, op2, rounding, saturating); - - private static (short val, bool ovf) AddOvf(short op1, short op2) + public static float TrigonometricStartingValue(float op1, uint op2) { - short result = (short)(op1 + op2); - - bool ovf = false; + float result = op1 * op1; - if ((op1 > 0) && (op2 > 0)) + if (float.IsNaN(result)) { - ovf = (result < 0); + return result; } - else if ((op1 < 0) && (op2 < 0)) + + if ((op2 % 2) == 1) { - ovf = (result > 0); + result *= -1; } - return (result, ovf); + return result; } - private static (short val, bool ovf) AddOvf(short op1, ushort op2) + public static float FPExponentialAccelerator(uint op1) { - short result = (short)(op1 + (short)op2); - - bool ovf = (result < op1); + uint index = op1 & 0b111111; + uint coeff = index switch + { + 0 => 0x000000, + 1 => 0x0164d2, + 2 => 0x02cd87, + 3 => 0x043a29, + 4 => 0x05aac3, + 5 => 0x071f62, + 6 => 0x08980f, + 7 => 0x0a14d5, + 8 => 0x0b95c2, + 9 => 0x0d1adf, + 10 => 0x0ea43a, + 11 => 0x1031dc, + 12 => 0x11c3d3, + 13 => 0x135a2b, + 14 => 0x14f4f0, + 15 => 0x16942d, + 16 => 0x1837f0, + 17 => 0x19e046, + 18 => 0x1b8d3a, + 19 => 0x1d3eda, + 20 => 0x1ef532, + 21 => 0x20b051, + 22 => 0x227043, + 23 => 0x243516, + 24 => 0x25fed7, + 25 => 0x27cd94, + 26 => 0x29a15b, + 27 => 0x2b7a3a, + 28 => 0x2d583f, + 29 => 0x2f3b79, + 30 => 0x3123f6, + 31 => 0x3311c4, + 32 => 0x3504f3, + 33 => 0x36fd92, + 34 => 0x38fbaf, + 35 => 0x3aff5b, + 36 => 0x3d08a4, + 37 => 0x3f179a, + 38 => 0x412c4d, + 39 => 0x4346cd, + 40 => 0x45672a, + 41 => 0x478d75, + 42 => 0x49b9be, + 43 => 0x4bec15, + 44 => 0x4e248c, + 45 => 0x506334, + 46 => 0x52a81e, + 47 => 0x54f35b, + 48 => 0x5744fd, + 49 => 0x599d16, + 50 => 0x5bfbb8, + 51 => 0x5e60f5, + 52 => 0x60ccdf, + 53 => 0x633f89, + 54 => 0x65b907, + 55 => 0x68396a, + 56 => 0x6ac0c7, + 57 => 0x6d4f30, + 58 => 0x6fe4ba, + 59 => 0x728177, + 60 => 0x75257d, + 61 => 0x77d0df, + 62 => 0x7a83b3, + 63 => 0x7d3e0c, + _ => 0x000000 + }; - return (result, ovf); + uint result = ((op1 & 0b11111111000000) << 17) | coeff; + return BitConverter.UInt32BitsToSingle(result); } - private static (ushort val, bool ovf) AddOvf(ushort op1, short op2) - { - ushort result = (ushort)(op1 + (ushort)op2); - - bool ovf; + public static float FPReciprocalStepFused(float op1, float op2) => FusedMultiplySubtract(2, op1, op2); - if (op2 < 0) - { - ovf = (result > op1); - } - else - { - ovf = (result < op1); - } + public static float FPReciprocalSqrtStepFused(float op1, float op2) => FusedMultiplySubtract(3, op1, op2) / 2; - return (result, ovf); - } + public static double AbsoluteDifference(double op1, double op2) => Math.Abs(op1 - op2); - private static (ushort val, bool ovf) AddOvf(ushort op1, ushort op2) - { - ushort result = (ushort)(op1 + op2); + public static double FusedMultiplyAdd(double op1, double op2, double op3) => Math.FusedMultiplyAdd(op2, op3, op1); - bool ovf = (result < op1); + public static double FusedMultiplyAddNegated(double op1, double op2, double op3) => Math.FusedMultiplyAdd(-op2, op3, -op1); - return (result, ovf); - } + public static double FusedMultiplySubtract(double op1, double op2, double op3) => Math.FusedMultiplyAdd(-op2, op3, op1); - private static (short val, bool ovf) SubtractOvf(short op1, short op2) - { - short result = (short)(op1 - op2); + public static double FusedMultiplySubtractNegated(double op1, double op2, double op3) => Math.FusedMultiplyAdd(op2, op3, -op1); - bool ovf; + public static double MaxNumber(double op1, double op2) => double.IsNaN(op1) ? op2 : (double.IsNaN(op2) ? op1 : Math.Max(op1, op2)); - if (op2 < 0) - { - ovf = (result < op1); - } - else - { - ovf = (result > op1); - } + public static double MaxNumberPairwise(double[] op1, int i) => Pairwise(MaxNumber, op1, i); - return (result, ovf); - } + public static double MaxNumberPairwise(double[] op1, double[] op2, int i) => Pairwise(MaxNumber, op1, op2, i); - private static (ushort val, bool ovf) SubtractOvf(ushort op1, ushort op2) - { - ushort result = (ushort)(op1 - op2); + public static double MaxPairwiseSve(double[] op1, double[] op2, int i) => (i % 2 == 0) ? Max(op1[i], op1[i + 1]) : Max(op2[i - 1], op2[i]); - bool ovf = (op1 < op2); + public static double MaxNumberPairwiseSve(double[] op1, double[] op2, int i) => (i % 2 == 0) ? MaxNumber(op1[i], op1[i + 1]) : MaxNumber(op2[i - 1], op2[i]); - return (result, ovf); - } + public static double MinNumber(double op1, double op2) => double.IsNaN(op1) ? op2 : (double.IsNaN(op2) ? op1 : Math.Min(op1, op2)); - public static short AbsSaturate(short op1) => op1 < 0 ? NegateSaturate(op1) : op1; + public static double MinNumberPairwise(double[] op1, int i) => Pairwise(MinNumber, op1, i); - public static short AddSaturate(short op1, short op2) - { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? (result > 0 ? short.MinValue : short.MaxValue) : result; - } + public static double MinNumberPairwise(double[] op1, double[] op2, int i) => Pairwise(MinNumber, op1, op2, i); - public static short AddSaturate(short op1, ushort op2) - { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? short.MaxValue : result; - } + public static double MinNumberPairwiseSve(double[] op1, double[] op2, int i) => (i % 2 == 0) ? MinNumber(op1[i], op1[i + 1]) : MinNumber(op2[i - 1], op2[i]); - public static ushort AddSaturate(ushort op1, short op2) - { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? (result < op1 ? ushort.MaxValue : ushort.MinValue) : result; - } + public static double MinPairwiseSve(double[] op1, double[] op2, int i) => (i % 2 == 0) ? Min(op1[i], op1[i + 1]) : Min(op2[i - 1], op2[i]); - public static ushort AddSaturate(ushort op1, ushort op2) + public static double[] MultiplyAddRotateComplex(double[] op1, double[] op2, double[] op3, byte imm) { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? ushort.MaxValue : result; - } + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; + (double ans1, double ans2) = imm switch + { + 0 => (FusedMultiplyAdd(op1[real], op2[real], op3[real]), FusedMultiplyAdd(op1[img], op2[real], op3[img])), + 1 => (FusedMultiplySubtract(op1[real], op2[img], op3[img]), FusedMultiplyAdd(op1[img], op2[img], op3[real])), + 2 => (FusedMultiplySubtract(op1[real], op2[real], op3[real]), FusedMultiplySubtract(op1[img], op2[real], op3[img])), + 3 => (FusedMultiplyAdd(op1[real], op2[img], op3[img]), FusedMultiplySubtract(op1[img], op2[img], op3[real])), + _ => (0.0, 0.0) + }; - public static short NegateSaturate(short op1) => SubtractSaturate((short)0, op1); + op1[real] = ans1; + op1[img] = ans2; + } - public static short SubtractSaturate(short op1, short op2) - { - var (result, ovf) = SubtractOvf(op1, op2); - return ovf ? (result > 0 ? short.MinValue : short.MaxValue) : result; + return op1; } - public static ushort SubtractSaturate(ushort op1, ushort op2) + public static double MultiplyExtended(double op1, double op2) { - var (result, ovf) = SubtractOvf(op1, op2); - return ovf ? ushort.MinValue : result; - } + bool inf1 = double.IsInfinity(op1); + bool inf2 = double.IsInfinity(op2); - public static int ShiftArithmetic(int op1, int op2) => SignedShift(op1, op2); + bool zero1 = (op1 == 0); + bool zero2 = (op2 == 0); - public static int ShiftArithmeticRounded(int op1, int op2) => SignedShift(op1, op2, rounding: true); + if ((inf1 && zero2) || (zero1 && inf2)) + { + return Math.CopySign(2, (zero1 ? op2 : op1)); + } + else + { + return op1 * op2; + } + } - public static int ShiftArithmeticSaturate(int op1, int op2) => SignedShift(op1, op2, saturating: true); + public static double TrigonometricMultiplyAddCoefficient(double op1, double op2, byte imm) + { + int index = (op2 < 0) ? (imm + 8) : imm; + ulong coeff = index switch + { + 0 => 0x3ff0000000000000, + 1 => 0xbfc5555555555543, + 2 => 0x3f8111111110f30c, + 3 => 0xbf2a01a019b92fc6, + 4 => 0x3ec71de351f3d22b, + 5 => 0xbe5ae5e2b60f7b91, + 6 => 0x3de5d8408868552f, + 7 => 0x0000000000000000, + 8 => 0x3ff0000000000000, + 9 => 0xbfe0000000000000, + 10 => 0x3fa5555555555536, + 11 => 0xbf56c16c16c13a0b, + 12 => 0x3efa01a019b1e8d8, + 13 => 0xbe927e4f7282f468, + 14 => 0x3e21ee96d2641b13, + 15 => 0xbda8f76380fbb401, + _ => 0x0000000000000000 + }; - public static int ShiftArithmeticRoundedSaturate(int op1, int op2) => SignedShift(op1, op2, rounding: true, saturating: true); + return Math.FusedMultiplyAdd(op1, Math.Abs(op2), BitConverter.UInt64BitsToDouble(coeff)); + } - private static int SignedShift(int op1, int op2, bool rounding = false, bool saturating = false, bool shiftSat = false) + public static double TrigonometricSelectCoefficient(double op1, ulong op2) { - int shift = (int)GetShift(op2, 32, shiftSat); - - int rndCns = 0; + double result = ((op2 % 2) == 0) ? op1 : 1.0; + bool isNegative = (op2 & 0b10) == 0b10; - if (rounding) + if (isNegative != (result < 0)) { - bool ovf; - - (rndCns, ovf) = ShiftOvf((int)1, -shift - 1); - - if (ovf) - { - return 0; - } + result *= -1; } - int result; - - bool addOvf; + return result; + } - (result, addOvf) = AddOvf(op1, rndCns); + public static double TrigonometricStartingValue(double op1, ulong op2) + { + double result = op1 * op1; - if (addOvf) + if (double.IsNaN(result)) { - result = (int)ShiftOvf((uint)result, shift).val; + return result; } - else + + if ((op2 % 2) == 1) { - bool shiftOvf; - - (result, shiftOvf) = ShiftOvf(result, shift); - - if (saturating) - { - if (shiftOvf) - { - result = op1 < 0 ? int.MinValue : int.MaxValue; - } - } - } + result *= -1; + } return result; } - public static int ShiftLeftLogical(int op1, byte op2) => UnsignedShift(op1, (int)op2); - - public static uint ShiftLeftLogical(uint op1, byte op2) => UnsignedShift(op1, (int)op2); - - public static int ShiftLeftLogicalSaturate(int op1, byte op2) => SignedShift(op1, (int)op2, saturating: true); - - public static uint ShiftLeftLogicalSaturate(uint op1, byte op2) => UnsignedShift(op1, (int)op2, saturating: true); - - public static uint ShiftLeftLogicalSaturateUnsigned(int op1, byte op2) => (uint)UnsignedShift(op1, (int)op2, saturating: true); - - public static int ShiftLogical(int op1, int op2) => UnsignedShift(op1, op2); - - public static uint ShiftLogical(uint op1, int op2) => UnsignedShift(op1, op2); - - public static uint ShiftLogicalRounded(uint op1, int op2) => UnsignedShift(op1, op2, rounding: true); - - public static int ShiftLogicalRounded(int op1, int op2) => UnsignedShift(op1, op2, rounding: true); - - public static uint ShiftLogicalRoundedSaturate(uint op1, int op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); - - public static int ShiftLogicalRoundedSaturate(int op1, int op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); - - public static int ShiftLogicalSaturate(int op1, int op2) => UnsignedShift(op1, op2, saturating: true); + public static double FPExponentialAccelerator(ulong op1) + { + ulong index = op1 & 0b111111; + ulong coeff = index switch + { + 0 => 0x0000000000000, + 1 => 0x02C9A3E778061, + 2 => 0x059B0D3158574, + 3 => 0x0874518759BC8, + 4 => 0x0B5586CF9890F, + 5 => 0x0E3EC32D3D1A2, + 6 => 0x11301D0125B51, + 7 => 0x1429AAEA92DE0, + 8 => 0x172B83C7D517B, + 9 => 0x1A35BEB6FCB75, + 10 => 0x1D4873168B9AA, + 11 => 0x2063B88628CD6, + 12 => 0x2387A6E756238, + 13 => 0x26B4565E27CDD, + 14 => 0x29E9DF51FDEE1, + 15 => 0x2D285A6E4030B, + 16 => 0x306FE0A31B715, + 17 => 0x33C08B26416FF, + 18 => 0x371A7373AA9CB, + 19 => 0x3A7DB34E59FF7, + 20 => 0x3DEA64C123422, + 21 => 0x4160A21F72E2A, + 22 => 0x44E086061892D, + 23 => 0x486A2B5C13CD0, + 24 => 0x4BFDAD5362A27, + 25 => 0x4F9B2769D2CA7, + 26 => 0x5342B569D4F82, + 27 => 0x56F4736B527DA, + 28 => 0x5AB07DD485429, + 29 => 0x5E76F15AD2148, + 30 => 0x6247EB03A5585, + 31 => 0x6623882552225, + 32 => 0x6A09E667F3BCD, + 33 => 0x6DFB23C651A2F, + 34 => 0x71F75E8EC5F74, + 35 => 0x75FEB564267C9, + 36 => 0x7A11473EB0187, + 37 => 0x7E2F336CF4E62, + 38 => 0x82589994CCE13, + 39 => 0x868D99B4492ED, + 40 => 0x8ACE5422AA0DB, + 41 => 0x8F1AE99157736, + 42 => 0x93737B0CDC5E5, + 43 => 0x97D829FDE4E50, + 44 => 0x9C49182A3F090, + 45 => 0xA0C667B5DE565, + 46 => 0xA5503B23E255D, + 47 => 0xA9E6B5579FDBF, + 48 => 0xAE89F995AD3AD, + 49 => 0xB33A2B84F15FB, + 50 => 0xB7F76F2FB5E47, + 51 => 0xBCC1E904BC1D2, + 52 => 0xC199BDD85529C, + 53 => 0xC67F12E57D14B, + 54 => 0xCB720DCEF9069, + 55 => 0xD072D4A07897C, + 56 => 0xD5818DCFBA487, + 57 => 0xDA9E603DB3285, + 58 => 0xDFC97337B9B5F, + 59 => 0xE502EE78B3FF6, + 60 => 0xEA4AFA2A490DA, + 61 => 0xEFA1BEE615A27, + 62 => 0xF50765B6E4540, + 63 => 0xFA7C1819E90D8, + _ => 0x0000000000000 + }; - public static uint ShiftLogicalSaturate(uint op1, int op2) => UnsignedShift(op1, op2, saturating: true); + ulong result = ((op1 & 0b11111111111000000) << 46) | coeff; + return BitConverter.UInt64BitsToDouble(result); + } - public static int ShiftRightArithmetic(int op1, byte op2) => SignedShift(op1, (int)(-op2)); + public static double FPReciprocalStepFused(double op1, double op2) => FusedMultiplySubtract(2, op1, op2); - public static int ShiftRightArithmeticAdd(int op1, int op2, byte op3) => (int)(op1 + ShiftRightArithmetic(op2, op3)); + public static double FPReciprocalSqrtStepFused(double op1, double op2) => FusedMultiplySubtract(3, op1, op2) / 2; - public static int ShiftRightArithmeticRounded(int op1, byte op2) => SignedShift(op1, (int)(-op2), rounding: true); + private static uint ReciprocalEstimate(uint a) + { + a = a * 2 + 1; - public static int ShiftRightArithmeticRoundedAdd(int op1, int op2, byte op3) => (int)(op1 + ShiftRightArithmeticRounded(op2, op3)); + uint b = (1 << 19) / a; + uint r = (b + 1) / 2; - public static int ShiftRightLogical(int op1, byte op2) => UnsignedShift(op1, (int)(-op2)); + return r; + } - public static uint ShiftRightLogical(uint op1, byte op2) => UnsignedShift(op1, (int)(-op2)); + private static uint ReciprocalSqrtEstimate(uint a) + { + if (a < 256) + { + a = a * 2 + 1; + } + else + { + a = (a >> 1) << 1; + a = (a + 1) * 2; + } - public static int ShiftRightLogicalAdd(int op1, int op2, byte op3) => (int)(op1 + ShiftRightLogical(op2, op3)); + uint b = 512; - public static uint ShiftRightLogicalAdd(uint op1, uint op2, byte op3) => (uint)(op1 + ShiftRightLogical(op2, op3)); + while (a * (b + 1) * (b + 1) < (1 << 28)) + { + b = b + 1; + } - public static int ShiftRightLogicalRounded(int op1, byte op2) => UnsignedShift(op1, (int)(-op2), rounding: true); + uint r = (b + 1) / 2; - public static uint ShiftRightLogicalRounded(uint op1, byte op2) => UnsignedShift(op1, (int)(-op2), rounding: true); + return r; + } - public static int ShiftRightLogicalRoundedAdd(int op1, int op2, byte op3) => (int)(op1 + ShiftRightLogicalRounded(op2, op3)); + public static double ReciprocalEstimate(double op1) => Math.ReciprocalEstimate(op1); - public static uint ShiftRightLogicalRoundedAdd(uint op1, uint op2, byte op3) => (uint)(op1 + ShiftRightLogicalRounded(op2, op3)); + public static float ReciprocalEstimate(float op1) => MathF.ReciprocalEstimate(op1); - private static uint UnsignedShift(uint op1, int op2, bool rounding = false, bool saturating = false, bool shiftSat = false) + public static double ReciprocalExponent(double op1) { - int shift = (int)GetShift(op2, 32, shiftSat); - - uint rndCns = 0; - - if (rounding) + if (double.IsNaN(op1)) { - bool ovf; - - (rndCns, ovf) = ShiftOvf((uint)1, -shift - 1); - - if (ovf) - { - return 0; - } + return double.NaN; } - (uint result, bool addOvf) = AddOvf(op1, rndCns); - - bool shiftOvf; - - (result, shiftOvf) = ShiftOvf(result, shift); + ulong bits = (ulong)BitConverter.DoubleToUInt64Bits(op1); + ulong exp = bits & 0x7FF0000000000000; - if (addOvf) + if (exp == 0) { - uint shiftedCarry = ShiftOvf((uint)1, 8 * sizeof(uint) + shift).val; - result = (uint)(result | shiftedCarry); + // Replace exponent with maximum exponent + bits ^= exp ^ 0x7FE0000000000000; } - - if (saturating) + else { - if (shiftOvf) - { - result = uint.MaxValue; - } + // Invert the exponent + bits ^= 0x7FF0000000000000; } - return result; - } + // Zero the fraction + bits &= 0xFFF0000000000000; - private static int UnsignedShift(int op1, int op2, bool rounding = false, bool saturating = false) => (int)UnsignedShift((uint)op1, op2, rounding, saturating); + return BitConverter.UInt64BitsToDouble(bits); + } - private static (int val, bool ovf) AddOvf(int op1, int op2) + public static float ReciprocalExponent(float op1) { - int result = (int)(op1 + op2); + if (float.IsNaN(op1)) + { + return float.NaN; + } - bool ovf = false; + uint bits = BitConverter.SingleToUInt32Bits(op1); + uint exp = bits & 0x7F800000; - if ((op1 > 0) && (op2 > 0)) + if (exp == 0) { - ovf = (result < 0); + // Replace exponent with maximum exponent + bits ^= exp ^ 0x7F000000; } - else if ((op1 < 0) && (op2 < 0)) + else { - ovf = (result > 0); + // Invert the exponent + bits ^= 0x7F800000; } - return (result, ovf); + // Zero the fraction + bits &= 0xFF800000; + + return BitConverter.UInt32BitsToSingle(bits); } - private static (int val, bool ovf) AddOvf(int op1, uint op2) + public static double ReciprocalSqrtEstimate(double op1) => Math.ReciprocalSqrtEstimate(op1); + + public static float ReciprocalSqrtEstimate(float op1) => MathF.ReciprocalSqrtEstimate(op1); + + private static uint ExtractBits(uint val, byte msbPos, byte lsbPos) { - int result = (int)(op1 + (int)op2); + uint andMask = 0; - bool ovf = (result < op1); + for (byte pos = lsbPos; pos <= msbPos; pos++) + { + andMask |= (uint)1 << pos; + } - return (result, ovf); + return (val & andMask) >> lsbPos; } - private static (uint val, bool ovf) AddOvf(uint op1, int op2) + public static uint UnsignedReciprocalEstimate(uint op1) { - uint result = (uint)(op1 + (uint)op2); + if ((op1 & 0x8000_0000u) == 0) + return 0xFFFF_FFFFu; - bool ovf; + uint idx = (op1 >> 23) & 0x1FFu; - if (op2 < 0) - { - ovf = (result > op1); - } - else - { - ovf = (result < op1); - } + uint estimate = ReciprocalEstimate(idx) & 0x1FFu; - return (result, ovf); + return estimate << 23; } - private static (uint val, bool ovf) AddOvf(uint op1, uint op2) + public static uint UnsignedReciprocalSqrtEstimate(uint op1) { - uint result = (uint)(op1 + op2); + if ((op1 & 0xC0000000u) == 0) + return 0xFFFFFFFFu; - bool ovf = (result < op1); + uint estimate = ReciprocalSqrtEstimate(ExtractBits(op1, 31, 23)) & 0x1FFu; - return (result, ovf); + return estimate << 23; } - private static (int val, bool ovf) SubtractOvf(int op1, int op2) - { - int result = (int)(op1 - op2); + public static T Add(T a, T b) where T : INumber => a + b; + public static T Subtract(T a, T b) where T : INumber => a - b; + public static T Multiply(T a, T b) where T : INumber => a * b; + public static T MultiplyAdd(T a, T b, T c) where T : INumber => a + b * c; + public static T MultiplySubtract(T a, T b, T c) where T : INumber => a - b * c; + public static T Max(T a, T b) where T : IComparisonOperators => a > b ? a : b; + public static T Min(T a, T b) where T : IComparisonOperators => a < b ? a : b; - bool ovf; + public static T AddPairwise(T[] array, int i) + where T : unmanaged, INumber + => Pairwise((a, b) => Add(a, b), array, i); - if (op2 < 0) - { - ovf = (result < op1); - } - else - { - ovf = (result > op1); - } + public static T AddPairwise(T[] array1, T[] array2, int i) + where T : unmanaged, INumber + => Pairwise((a, b) => Add(a, b), array1, array2, i); - return (result, ovf); - } + public static T AddPairwiseSve(T[] array1, T[] array2, int i) + where T : unmanaged, INumber + => PairwiseSve((a, b) => Add(a, b), array1, array2, i); - private static (uint val, bool ovf) SubtractOvf(uint op1, uint op2) + public static T[] AddRotateComplex(T[] op1, T[] op2, byte rot) where T : INumber { - uint result = (uint)(op1 - op2); + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; - bool ovf = (op1 < op2); + if (rot == 0) + { + op1[real] -= op2[img]; + op1[img] += op2[real]; + } + else + { + op1[real] += op2[img]; + op1[img] -= op2[real]; + } + } - return (result, ovf); + return op1; } - public static int AbsSaturate(int op1) => op1 < 0 ? NegateSaturate(op1) : op1; + public static T MaxPairwise(T[] array, int i) + where T : unmanaged, INumber, IComparisonOperators + => Pairwise((a, b) => Max(a, b), array, i); - public static int AddSaturate(int op1, int op2) - { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? (result > 0 ? int.MinValue : int.MaxValue) : result; - } + public static T MaxPairwise(T[] array1, T[] array2, int i) + where T : unmanaged, INumber, IComparisonOperators + => Pairwise((a, b) => Max(a, b), array1, array2, i); - public static int AddSaturate(int op1, uint op2) - { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? int.MaxValue : result; - } + public static T MaxPairwiseSve(T[] array1, T[] array2, int i) + where T : unmanaged, INumber, IComparisonOperators + => PairwiseSve((a, b) => Max(a, b), array1, array2, i); - public static uint AddSaturate(uint op1, int op2) - { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? (result < op1 ? uint.MaxValue : uint.MinValue) : result; - } + public static T MinPairwise(T[] array, int i) + where T : unmanaged, INumber, IComparisonOperators + => Pairwise((a, b) => Min(a, b), array, i); - public static uint AddSaturate(uint op1, uint op2) + public static T MinPairwise(T[] array1, T[] array2, int i) + where T : unmanaged, INumber, IComparisonOperators + => Pairwise((a, b) => Min(a, b), array1, array2, i); + + public static T MinPairwiseSve(T[] array1, T[] array2, int i) + where T : unmanaged, INumber, IComparisonOperators + => PairwiseSve((a, b) => Min(a, b), array1, array2, i); + + public static T Pairwise(Func pairOp, T[] op1, int i) + where T : unmanaged, INumber { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? uint.MaxValue : result; + int idx = 2 * i; + if (idx + 1 < op1.Length) + { + return pairOp(op1[idx], op1[idx + 1]); + } + return T.Zero; } - public static int NegateSaturate(int op1) => SubtractSaturate((int)0, op1); - - public static int SubtractSaturate(int op1, int op2) + public static T Pairwise(Func pairOp, T[] op1, T[] op2, int i) + where T : unmanaged, INumber { - var (result, ovf) = SubtractOvf(op1, op2); - return ovf ? (result > 0 ? int.MinValue : int.MaxValue) : result; + int idx = 2 * i; + if (idx + 1 < op1.Length) + { + return pairOp(op1[idx], op1[idx + 1]); + } + else + { + int offset = idx - op1.Length; + return pairOp(op2[offset], op2[offset + 1]); + } } - public static uint SubtractSaturate(uint op1, uint op2) + public static T PairwiseSve(Func op, T[] array1, T[] array2, int i) + where T : unmanaged, INumber { - var (result, ovf) = SubtractOvf(op1, op2); - return ovf ? uint.MinValue : result; + return (i % 2 == 0) + ? op(array1[i], array1[i + 1]) + : op(array2[i - 1], array2[i]); } - public static long ShiftArithmetic(long op1, long op2) => SignedShift(op1, op2); + public static T AddAcross(T[] values) + where T : unmanaged, INumber + => Reduce((a, b) => Add(a, b), values); - public static long ShiftArithmeticRounded(long op1, long op2) => SignedShift(op1, op2, rounding: true); + public static T AndAcross(T[] values) + where T : unmanaged, IBitwiseOperators + => Reduce((a, b) => And(a, b), values); - public static long ShiftArithmeticSaturate(long op1, long op2) => SignedShift(op1, op2, saturating: true); + public static T OrAcross(T[] values) + where T : unmanaged, IBitwiseOperators + => Reduce((a, b) => Or(a, b), values); - public static long ShiftArithmeticRoundedSaturate(long op1, long op2) => SignedShift(op1, op2, rounding: true, saturating: true); + public static T XorAcross(T[] values) + where T : unmanaged, IBitwiseOperators + => Reduce((a, b) => Xor(a, b), values); - private static long SignedShift(long op1, long op2, bool rounding = false, bool saturating = false, bool shiftSat = false) - { - int shift = (int)GetShift(op2, 64, shiftSat); + public static T MaxAcross(T[] values) + where T : unmanaged, IComparisonOperators + => Reduce((a, b) => Max(a, b), values); - long rndCns = 0; + public static T MinAcross(T[] values) + where T : unmanaged, IComparisonOperators + => Reduce((a, b) => Min(a, b), values); - if (rounding) + public static T Reduce(Func reducer, T[] values) + where T : unmanaged + { + T acc = values[0]; + for (int i = 1; i < values.Length; i++) { - bool ovf; - - (rndCns, ovf) = ShiftOvf((long)1, -shift - 1); - - if (ovf) - { - return 0; - } + acc = reducer(acc, values[i]); } - long result; - - bool addOvf; + return acc; + } - (result, addOvf) = AddOvf(op1, rndCns); + public static T Reduce(Func reducer, U[] values) + where T : unmanaged + where U : unmanaged + { + T acc = (T)Convert.ChangeType(values[0], typeof(T)); - if (addOvf) - { - result = (long)ShiftOvf((ulong)result, shift).val; - } - else + for (int i = 1; i < values.Length; i++) { - bool shiftOvf; - - (result, shiftOvf) = ShiftOvf(result, shift); - - if (saturating) - { - if (shiftOvf) - { - result = op1 < 0 ? long.MinValue : long.MaxValue; - } - } + acc = reducer(acc, values[i]); } - return result; + return acc; } - public static long ShiftLeftLogical(long op1, byte op2) => UnsignedShift(op1, (long)op2); - - public static ulong ShiftLeftLogical(ulong op1, byte op2) => UnsignedShift(op1, (long)op2); - - public static long ShiftLeftLogicalSaturate(long op1, byte op2) => SignedShift(op1, (long)op2, saturating: true); + public static float AddAcrossRecursivePairwise(float[] op1) => ReduceRecursivePairwise(Add, op1); - public static ulong ShiftLeftLogicalSaturate(ulong op1, byte op2) => UnsignedShift(op1, (long)op2, saturating: true); + private static float ReduceRecursivePairwise(Func reduceOp, float[] op1) + { + if (op1.Length == 2) + { + return reduceOp(op1[0], op1[1]); + } - public static ulong ShiftLeftLogicalSaturateUnsigned(long op1, byte op2) => (ulong)UnsignedShift(op1, (long)op2, saturating: true); + if (op1.Length % 2 != 0) + { + return float.NaN; + } - public static long ShiftLogical(long op1, long op2) => UnsignedShift(op1, op2); + float[] l = new float[op1.Length / 2]; + Array.Copy(op1, 0, l, 0, (op1.Length / 2)); + float l_reduced = ReduceRecursivePairwise(reduceOp, l); - public static ulong ShiftLogical(ulong op1, long op2) => UnsignedShift(op1, op2); + float[] r = new float[op1.Length / 2]; + Array.Copy(op1, (op1.Length / 2), r, 0, (op1.Length / 2)); + float r_reduced = ReduceRecursivePairwise(reduceOp, r); - public static ulong ShiftLogicalRounded(ulong op1, long op2) => UnsignedShift(op1, op2, rounding: true); + return reduceOp(l_reduced, r_reduced); + } - public static long ShiftLogicalRounded(long op1, long op2) => UnsignedShift(op1, op2, rounding: true); + public static double AddAcrossRecursivePairwise(double[] op1) => ReduceRecursivePairwise(Add, op1); - public static ulong ShiftLogicalRoundedSaturate(ulong op1, long op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); + private static double ReduceRecursivePairwise(Func reduceOp, double[] op1) + { + if (op1.Length == 2) + { + return reduceOp(op1[0], op1[1]); + } - public static long ShiftLogicalRoundedSaturate(long op1, long op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); + if (op1.Length % 2 != 0) + { + return double.NaN; + } - public static long ShiftLogicalSaturate(long op1, long op2) => UnsignedShift(op1, op2, saturating: true); + double[] l = new double[op1.Length / 2]; + Array.Copy(op1, 0, l, 0, (op1.Length / 2)); + double l_reduced = ReduceRecursivePairwise(reduceOp, l); - public static ulong ShiftLogicalSaturate(ulong op1, long op2) => UnsignedShift(op1, op2, saturating: true); + double[] r = new double[op1.Length / 2]; + Array.Copy(op1, (op1.Length / 2), r, 0, (op1.Length / 2)); + double r_reduced = ReduceRecursivePairwise(reduceOp, r); - public static long ShiftRightArithmetic(long op1, byte op2) => SignedShift(op1, (long)(-op2)); + return reduceOp(l_reduced, r_reduced); + } - public static long ShiftRightArithmeticAdd(long op1, long op2, byte op3) => (long)(op1 + ShiftRightArithmetic(op2, op3)); + public static float MaxNumberAcross(float[] op1) => Reduce(MaxNumber, op1); - public static long ShiftRightArithmeticRounded(long op1, byte op2) => SignedShift(op1, (long)(-op2), rounding: true); + public static float MinNumberAcross(float[] op1) => Reduce(MinNumber, op1); - public static long ShiftRightArithmeticRoundedAdd(long op1, long op2, byte op3) => (long)(op1 + ShiftRightArithmeticRounded(op2, op3)); + private struct poly128_t + { + public ulong lo; + public ulong hi; - public static long ShiftRightLogical(long op1, byte op2) => UnsignedShift(op1, (long)(-op2)); + public static poly128_t operator ^(poly128_t op1, poly128_t op2) + { + op1.lo ^= op2.lo; + op1.hi ^= op2.hi; - public static ulong ShiftRightLogical(ulong op1, byte op2) => UnsignedShift(op1, (long)(-op2)); + return op1; + } - public static long ShiftRightLogicalAdd(long op1, long op2, byte op3) => (long)(op1 + ShiftRightLogical(op2, op3)); + public static poly128_t operator <<(poly128_t val, int shiftAmount) + { + for (int i = 0; i < shiftAmount; i++) + { + val.hi <<= 1; - public static ulong ShiftRightLogicalAdd(ulong op1, ulong op2, byte op3) => (ulong)(op1 + ShiftRightLogical(op2, op3)); + if ((val.lo & 0x8000000000000000U) != 0) + { + val.hi |= 1; + } - public static long ShiftRightLogicalRounded(long op1, byte op2) => UnsignedShift(op1, (long)(-op2), rounding: true); + val.lo <<= 1; + } - public static ulong ShiftRightLogicalRounded(ulong op1, byte op2) => UnsignedShift(op1, (long)(-op2), rounding: true); + return val; + } - public static long ShiftRightLogicalRoundedAdd(long op1, long op2, byte op3) => (long)(op1 + ShiftRightLogicalRounded(op2, op3)); + public static implicit operator poly128_t(ulong lo) + { + poly128_t result = new poly128_t(); + result.lo = lo; + return result; + } - public static ulong ShiftRightLogicalRoundedAdd(ulong op1, ulong op2, byte op3) => (ulong)(op1 + ShiftRightLogicalRounded(op2, op3)); + public static explicit operator poly128_t(long lo) + { + poly128_t result = new poly128_t(); + result.lo = (ulong)lo; + return result; + } + } - private static ulong UnsignedShift(ulong op1, long op2, bool rounding = false, bool saturating = false, bool shiftSat = false) + private static ushort PolynomialMult(byte op1, byte op2) { - int shift = (int)GetShift(op2, 64, shiftSat); - - ulong rndCns = 0; + ushort result = default(ushort); + ushort extendedOp2 = (ushort)op2; - if (rounding) + for (int i = 0; i < 8 * sizeof(byte); i++) { - bool ovf; - - (rndCns, ovf) = ShiftOvf((ulong)1, -shift - 1); - - if (ovf) + if ((op1 & ((byte)1 << i)) != 0) { - return 0; + result = (ushort)(result ^ (extendedOp2 << i)); } } - (ulong result, bool addOvf) = AddOvf(op1, rndCns); - - bool shiftOvf; - - (result, shiftOvf) = ShiftOvf(result, shift); + return result; + } - if (addOvf) - { - ulong shiftedCarry = ShiftOvf((ulong)1, 8 * sizeof(ulong) + shift).val; - result = (ulong)(result | shiftedCarry); - } + private static short PolynomialMult(sbyte op1, sbyte op2) + { + short result = default(short); + short extendedOp2 = (short)op2; - if (saturating) + for (int i = 0; i < 8 * sizeof(sbyte); i++) { - if (shiftOvf) + if ((op1 & ((sbyte)1 << i)) != 0) { - result = ulong.MaxValue; + result = (short)(result ^ (extendedOp2 << i)); } } return result; } - private static long UnsignedShift(long op1, long op2, bool rounding = false, bool saturating = false) => (long)UnsignedShift((ulong)op1, op2, rounding, saturating); - - private static (long val, bool ovf) AddOvf(long op1, long op2) + private static ulong PolynomialMult(uint op1, uint op2) { - long result = (long)(op1 + op2); - - bool ovf = false; + ulong result = default(ulong); + ulong extendedOp2 = (ulong)op2; - if ((op1 > 0) && (op2 > 0)) - { - ovf = (result < 0); - } - else if ((op1 < 0) && (op2 < 0)) + for (int i = 0; i < 8 * sizeof(uint); i++) { - ovf = (result > 0); + if ((op1 & ((uint)1 << i)) != 0) + { + result = (ulong)(result ^ (extendedOp2 << i)); + } } - return (result, ovf); + return result; } - private static (long val, bool ovf) AddOvf(long op1, ulong op2) + private static poly128_t PolynomialMult(ulong op1, ulong op2) { - long result = (long)(op1 + (long)op2); + poly128_t result = default(poly128_t); + poly128_t extendedOp2 = (poly128_t)op2; - bool ovf = (result < op1); + for (int i = 0; i < 8 * sizeof(ulong); i++) + { + if ((op1 & ((ulong)1 << i)) != 0) + { + result = (poly128_t)(result ^ (extendedOp2 << i)); + } + } - return (result, ovf); + return result; } - private static (ulong val, bool ovf) AddOvf(ulong op1, long op2) + private static poly128_t PolynomialMult(long op1, long op2) { - ulong result = (ulong)(op1 + (ulong)op2); - - bool ovf; + poly128_t result = default(poly128_t); + poly128_t extendedOp2 = (poly128_t)op2; - if (op2 < 0) - { - ovf = (result > op1); - } - else + for (int i = 0; i < 8 * sizeof(long); i++) { - ovf = (result < op1); + if ((op1 & ((long)1 << i)) != 0) + { + result = (poly128_t)(result ^ (extendedOp2 << i)); + } } - return (result, ovf); + return result; } - private static (ulong val, bool ovf) AddOvf(ulong op1, ulong op2) + public static long MultiplyHigh(long op1, long op2) { - ulong result = (ulong)(op1 + op2); - - bool ovf = (result < op1); - - return (result, ovf); + ulong u0, v0, w0; + long u1, v1, w1, w2, t; + u0 = (ulong)op1 & 0xFFFFFFFF; + u1 = op1 >> 32; + v0 = (ulong)op2 & 0xFFFFFFFF; + v1 = op2 >> 32; + w0 = u0 * v0; + t = u1 * (long)v0 + (long)(w0 >> 32); + w1 = t & 0xFFFFFFFF; + w2 = t >> 32; + w1 = (long)u0 * v1 + w1; + return u1 * v1 + w2 + (w1 >> 32); } - private static (long val, bool ovf) SubtractOvf(long op1, long op2) + public static ulong MultiplyHigh(ulong op1, ulong op2) { - long result = (long)(op1 - op2); + ulong u0, v0, w0; + ulong u1, v1, w1, w2, t; + u0 = (ulong)op1 & 0xFFFFFFFF; + u1 = op1 >> 32; + v0 = (ulong)op2 & 0xFFFFFFFF; + v1 = op2 >> 32; + w0 = u0 * v0; + t = u1 * (ulong)v0 + (ulong)(w0 >> 32); + w1 = t & 0xFFFFFFFF; + w2 = t >> 32; + w1 = (ulong)u0 * v1 + w1; + return u1 * v1 + w2 + (w1 >> 32); + } - bool ovf; + public static byte PolynomialMultiply(byte op1, byte op2) => (byte)PolynomialMult(op1, op2); - if (op2 < 0) - { - ovf = (result < op1); - } - else - { - ovf = (result > op1); - } + public static ushort PolynomialMultiplyWidening(byte op1, byte op2) => PolynomialMult(op1, op2); - return (result, ovf); - } + public static ushort PolynomialMultiplyWideningUpper(byte[] op1, byte[] op2, int i) => PolynomialMultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - private static (ulong val, bool ovf) SubtractOvf(ulong op1, ulong op2) - { - ulong result = (ulong)(op1 - op2); + public static sbyte PolynomialMultiply(sbyte op1, sbyte op2) => (sbyte)PolynomialMult(op1, op2); - bool ovf = (op1 < op2); + public static short PolynomialMultiplyWidening(sbyte op1, sbyte op2) => PolynomialMult(op1, op2); - return (result, ovf); - } + public static short PolynomialMultiplyWideningUpper(sbyte[] op1, sbyte[] op2, int i) => PolynomialMultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - public static long AbsSaturate(long op1) => op1 < 0 ? NegateSaturate(op1) : op1; + public static ulong PolynomialMultiplyWideningLo64(ulong op1, ulong op2) => PolynomialMult(op1, op2).lo; - public static long AddSaturate(long op1, long op2) - { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? (result > 0 ? long.MinValue : long.MaxValue) : result; - } + public static long PolynomialMultiplyWideningLo64(long op1, long op2) => (long)PolynomialMult(op1, op2).lo; - public static long AddSaturate(long op1, ulong op2) - { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? long.MaxValue : result; - } + public static ulong PolynomialMultiplyWideningHi64(ulong op1, ulong op2) => PolynomialMult(op1, op2).hi; - public static ulong AddSaturate(ulong op1, long op2) - { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? (result < op1 ? ulong.MaxValue : ulong.MinValue) : result; - } + public static long PolynomialMultiplyWideningHi64(long op1, long op2) => (long)PolynomialMult(op1, op2).hi; - public static ulong AddSaturate(ulong op1, ulong op2) - { - var (result, ovf) = AddOvf(op1, op2); - return ovf ? ulong.MaxValue : result; - } + public static ulong PolynomialMultiplyWidening(uint op1, uint op2) => PolynomialMult(op1, op2); - public static long NegateSaturate(long op1) => SubtractSaturate((long)0, op1); + public static sbyte Concat(sbyte[] op1, sbyte[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - public static long SubtractSaturate(long op1, long op2) + public static sbyte ConcatScalar(sbyte[] op1, sbyte[] op2, int i) { - var (result, ovf) = SubtractOvf(op1, op2); - return ovf ? (result > 0 ? long.MinValue : long.MaxValue) : result; + return i switch + { + 0 => op1[0], + 1 => op2[0], + _ => 0 + }; } - public static ulong SubtractSaturate(ulong op1, ulong op2) - { - var (result, ovf) = SubtractOvf(op1, op2); - return ovf ? ulong.MinValue : result; - } + public static sbyte ExtractVector(sbyte[] op1, sbyte[] op2, int op3, int i) => Concat(op1, op2, op3 + i); + public static sbyte Insert(sbyte[] op1, int op2, sbyte op3, int i) => (op2 != i) ? op1[i] : op3; - private static (sbyte val, bool ovf) ShiftOvf(sbyte value, int shift) + public static byte Concat(byte[] op1, byte[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; + + public static byte ConcatScalar(byte[] op1, byte[] op2, int i) { - sbyte result = value; + return i switch + { + 0 => op1[0], + 1 => op2[0], + _ => 0 + }; + } - bool ovf = false; - sbyte msb = 1; - msb = (sbyte)(msb << (8 * sizeof(sbyte) - 1)); + public static byte ExtractVector(byte[] op1, byte[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - for (int i = 0; i < shift; i++) - { - ovf = ovf || ((result & msb) != 0); - result <<= 1; - } + public static byte Insert(byte[] op1, int op2, byte op3, int i) => (op2 != i) ? op1[i] : op3; - for (int i = 0; i > shift; i--) - { - result >>= 1; - } + public static short Concat(short[] op1, short[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - if ((value > 0) && (result < 0)) + public static short ConcatScalar(short[] op1, short[] op2, int i) + { + return i switch { - ovf = true; - } - - return (result, ovf); + 0 => op1[0], + 1 => op2[0], + _ => 0 + }; } + public static short ExtractVector(short[] op1, short[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - private static (byte val, bool ovf) ShiftOvf(byte value, int shift) - { - byte result = value; - - bool ovf = false; - byte msb = 1; - msb = (byte)(msb << (8 * sizeof(byte) - 1)); + public static short Insert(short[] op1, int op2, short op3, int i) => (op2 != i) ? op1[i] : op3; - for (int i = 0; i < shift; i++) - { - ovf = ovf || ((result & msb) != 0); - result <<= 1; - } + public static ushort Concat(ushort[] op1, ushort[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - for (int i = 0; i > shift; i--) + public static ushort ConcatScalar(ushort[] op1, ushort[] op2, int i) + { + return i switch { - result >>= 1; - } + 0 => op1[0], + 1 => op2[0], + _ => 0 + }; + } - if ((value > 0) && (result < 0)) - { - ovf = true; - } + public static ushort ExtractVector(ushort[] op1, ushort[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - return (result, ovf); - } + public static ushort Insert(ushort[] op1, int op2, ushort op3, int i) => (op2 != i) ? op1[i] : op3; + public static int Concat(int[] op1, int[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - private static (short val, bool ovf) ShiftOvf(short value, int shift) + public static int ConcatScalar(int[] op1, int[] op2, int i) { - short result = value; + return i switch + { + 0 => op1[0], + 1 => op2[0], + _ => 0 + }; + } - bool ovf = false; - short msb = 1; - msb = (short)(msb << (8 * sizeof(short) - 1)); + public static int ExtractVector(int[] op1, int[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - for (int i = 0; i < shift; i++) - { - ovf = ovf || ((result & msb) != 0); - result <<= 1; - } + public static int Insert(int[] op1, int op2, int op3, int i) => (op2 != i) ? op1[i] : op3; - for (int i = 0; i > shift; i--) - { - result >>= 1; - } + public static uint Concat(uint[] op1, uint[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - if ((value > 0) && (result < 0)) + public static uint ConcatScalar(uint[] op1, uint[] op2, int i) + { + return i switch { - ovf = true; - } - - return (result, ovf); + 0 => op1[0], + 1 => op2[0], + _ => 0 + }; } + public static uint ExtractVector(uint[] op1, uint[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - private static (ushort val, bool ovf) ShiftOvf(ushort value, int shift) - { - ushort result = value; + public static uint Insert(uint[] op1, int op2, uint op3, int i) => (op2 != i) ? op1[i] : op3; - bool ovf = false; - ushort msb = 1; - msb = (ushort)(msb << (8 * sizeof(ushort) - 1)); - - for (int i = 0; i < shift; i++) - { - ovf = ovf || ((result & msb) != 0); - result <<= 1; - } + public static long Concat(long[] op1, long[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - for (int i = 0; i > shift; i--) + public static long ConcatScalar(long[] op1, long[] op2, int i) + { + return i switch { - result >>= 1; - } + 0 => op1[0], + 1 => op2[0], + _ => 0 + }; + } - if ((value > 0) && (result < 0)) - { - ovf = true; - } + public static long ExtractVector(long[] op1, long[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - return (result, ovf); - } + public static long Insert(long[] op1, int op2, long op3, int i) => (op2 != i) ? op1[i] : op3; + public static ulong Concat(ulong[] op1, ulong[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - private static (int val, bool ovf) ShiftOvf(int value, int shift) + public static ulong ConcatScalar(ulong[] op1, ulong[] op2, int i) { - int result = value; + return i switch + { + 0 => op1[0], + 1 => op2[0], + _ => 0 + }; + } - bool ovf = false; - int msb = 1; - msb = (int)(msb << (8 * sizeof(int) - 1)); + public static ulong ExtractVector(ulong[] op1, ulong[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - for (int i = 0; i < shift; i++) - { - ovf = ovf || ((result & msb) != 0); - result <<= 1; - } + public static ulong Insert(ulong[] op1, int op2, ulong op3, int i) => (op2 != i) ? op1[i] : op3; - for (int i = 0; i > shift; i--) - { - result >>= 1; - } + public static float Concat(float[] op1, float[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - if ((value > 0) && (result < 0)) + public static float ConcatScalar(float[] op1, float[] op2, int i) + { + return i switch { - ovf = true; - } - - return (result, ovf); + 0 => op1[0], + 1 => op2[0], + _ => 0 + }; } + public static float ExtractVector(float[] op1, float[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - private static (uint val, bool ovf) ShiftOvf(uint value, int shift) - { - uint result = value; + public static float Insert(float[] op1, int op2, float op3, int i) => (op2 != i) ? op1[i] : op3; - bool ovf = false; - uint msb = 1; - msb = (uint)(msb << (8 * sizeof(uint) - 1)); + public static double Concat(double[] op1, double[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - for (int i = 0; i < shift; i++) + public static double ConcatScalar(double[] op1, double[] op2, int i) + { + return i switch { - ovf = ovf || ((result & msb) != 0); - result <<= 1; - } + 0 => op1[0], + 1 => op2[0], + _ => 0 + }; + } - for (int i = 0; i > shift; i--) - { - result >>= 1; - } + public static double ExtractVector(double[] op1, double[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - if ((value > 0) && (result < 0)) - { - ovf = true; - } + public static double Insert(double[] op1, int op2, double op3, int i) => (op2 != i) ? op1[i] : op3; - return (result, ovf); - } + public static int LoadPairScalar(int[] op1, int i) => (i == 0) ? op1[0] : (i == op1.Length / 2) ? op1[1] : (int)0; + public static uint LoadPairScalar(uint[] op1, int i) => (i == 0) ? op1[0] : (i == op1.Length / 2) ? op1[1] : (uint)0; - private static (long val, bool ovf) ShiftOvf(long value, int shift) - { - long result = value; + public static float LoadPairScalar(float[] op1, int i) => (i == 0) ? op1[0] : (i == op1.Length / 2) ? op1[1] : (float)0; - bool ovf = false; - long msb = 1; - msb = (long)(msb << (8 * sizeof(long) - 1)); + public static sbyte TableVectorExtension(int i, sbyte[] defaultValues, sbyte[] indices, params sbyte[][] table) + { + sbyte[] fullTable = table.SelectMany(x => x).ToArray(); + int index = indices[i]; - for (int i = 0; i < shift; i++) - { - ovf = ovf || ((result & msb) != 0); - result <<= 1; - } + if (index < 0 || index >= fullTable.Length) + return defaultValues[i]; - for (int i = 0; i > shift; i--) - { - result >>= 1; - } + return fullTable[index]; + } - if ((value > 0) && (result < 0)) - { - ovf = true; - } + public static sbyte TableVectorLookup(int i, sbyte[] indices, params sbyte[][] table) + { + sbyte[] zeros = new sbyte[indices.Length]; + Array.Fill(zeros, 0, 0, indices.Length); - return (result, ovf); + return TableVectorExtension(i, zeros, indices, table); } - - private static (ulong val, bool ovf) ShiftOvf(ulong value, int shift) + public static byte TableVectorExtension(int i, byte[] defaultValues, byte[] indices, params byte[][] table) { - ulong result = value; - - bool ovf = false; - ulong msb = 1; - msb = (ulong)(msb << (8 * sizeof(ulong) - 1)); + byte[] fullTable = table.SelectMany(x => x).ToArray(); + int index = indices[i]; - for (int i = 0; i < shift; i++) - { - ovf = ovf || ((result & msb) != 0); - result <<= 1; - } + if (index < 0 || index >= fullTable.Length) + return defaultValues[i]; - for (int i = 0; i > shift; i--) - { - result >>= 1; - } + return fullTable[index]; + } - if ((value > 0) && (result < 0)) - { - ovf = true; - } + public static byte TableVectorLookup(int i, byte[] indices, params byte[][] table) + { + byte[] zeros = new byte[indices.Length]; + Array.Fill(zeros, 0, 0, indices.Length); - return (result, ovf); + return TableVectorExtension(i, zeros, indices, table); } - public static float AbsoluteDifference(float op1, float op2) => MathF.Abs(op1 - op2); - - public static float FusedMultiplyAdd(float op1, float op2, float op3) => MathF.FusedMultiplyAdd(op2, op3, op1); + public static byte ShiftLeftAndInsert(byte left, byte right, byte shift) + { + byte mask = (byte)~(byte.MaxValue << shift); + byte value = (byte)(right << shift); + byte newval = (byte)(((byte)left & mask) | value); + return newval; + } - public static float FusedMultiplyAddNegated(float op1, float op2, float op3) => MathF.FusedMultiplyAdd(-op2, op3, -op1); + public static byte ShiftRightAndInsert(byte left, byte right, byte shift) + { + byte mask = (byte)~(byte.MaxValue >> shift); + byte value = (byte)(right >> shift); + byte newval = (byte)(((byte)left & mask) | value); + return newval; + } - public static float FusedMultiplySubtract(float op1, float op2, float op3) => MathF.FusedMultiplyAdd(-op2, op3, op1); + public static short ShiftLeftAndInsert(short left, short right, byte shift) + { + ushort mask = (ushort)~(ushort.MaxValue << shift); + ushort value = (ushort)(right << shift); + short newval = (short)(((ushort)left & mask) | value); + return newval; + } - public static float FusedMultiplySubtractNegated(float op1, float op2, float op3) => MathF.FusedMultiplyAdd(op2, op3, -op1); + public static short ShiftRightAndInsert(short left, short right, byte shift) + { + ushort mask = (ushort)~(ushort.MaxValue >> shift); + ushort value = (ushort)(right >> shift); + short newval = (short)(((ushort)left & mask) | value); + return newval; + } - public static float MaxNumber(float op1, float op2) => float.IsNaN(op1) ? op2 : (float.IsNaN(op2) ? op1 : MathF.Max(op1, op2)); + public static int ShiftLeftAndInsert(int left, int right, byte shift) + { + uint mask = (uint)~(uint.MaxValue << shift); + uint value = (uint)(right << shift); + int newval = (int)(((uint)left & mask) | value); + return newval; + } - public static float MaxNumberPairwise(float[] op1, int i) => Pairwise(MaxNumber, op1, i); + public static int ShiftRightAndInsert(int left, int right, byte shift) + { + uint mask = (uint)~(uint.MaxValue >> shift); + uint value = (uint)(right >> shift); + int newval = (int)(((uint)left & mask) | value); + return newval; + } - public static float MaxNumberPairwise(float[] op1, float[] op2, int i) => Pairwise(MaxNumber, op1, op2, i); + public static long ShiftLeftAndInsert(long left, long right, byte shift) + { + ulong mask = (ulong)~(ulong.MaxValue << shift); + ulong value = (ulong)(right << shift); + long newval = (long)(((ulong)left & mask) | value); + return newval; + } - public static float MinNumber(float op1, float op2) => float.IsNaN(op1) ? op2 : (float.IsNaN(op2) ? op1 : MathF.Min(op1, op2)); + public static long ShiftRightAndInsert(long left, long right, byte shift) + { + ulong mask = (ulong)~(ulong.MaxValue >> shift); + ulong value = (ulong)(right >> shift); + long newval = (long)(((ulong)left & mask) | value); + return newval; + } - public static float MinNumberPairwise(float[] op1, int i) => Pairwise(MinNumber, op1, i); + public static sbyte ShiftLeftAndInsert(sbyte left, sbyte right, byte shift) + { + byte mask = (byte)~(byte.MaxValue << shift); + byte value = (byte)(right << shift); + sbyte newval = (sbyte)(((byte)left & mask) | value); + return newval; + } - public static float MinNumberPairwise(float[] op1, float[] op2, int i) => Pairwise(MinNumber, op1, op2, i); + public static sbyte ShiftRightAndInsert(sbyte left, sbyte right, byte shift) + { + byte mask = (byte)~(byte.MaxValue >> shift); + byte value = (byte)(right >> shift); + sbyte newval = (sbyte)(((byte)left & mask) | value); + return newval; + } - public static float[] MultiplyAddRotateComplex(float[] op1, float[] op2, float[] op3, byte imm) + public static ushort ShiftLeftAndInsert(ushort left, ushort right, byte shift) { - for (int i = 0; i < op1.Length; i += 2) - { - int real = i; - int img = i + 1; - (float ans1, float ans2) = imm switch - { - 0 => (FusedMultiplyAdd(op1[real], op2[real], op3[real]), FusedMultiplyAdd(op1[img], op2[real], op3[img])), - 1 => (FusedMultiplySubtract(op1[real], op2[img], op3[img]), FusedMultiplyAdd(op1[img], op2[img], op3[real])), - 2 => (FusedMultiplySubtract(op1[real], op2[real], op3[real]), FusedMultiplySubtract(op1[img], op2[real], op3[img])), - 3 => (FusedMultiplyAdd(op1[real], op2[img], op3[img]), FusedMultiplySubtract(op1[img], op2[img], op3[real])), - _ => (0.0f, 0.0f) - }; - - op1[real] = ans1; - op1[img] = ans2; - } - - return op1; - } - - public static float[] MultiplyAddRotateComplexBySelectedScalar(float[] op1, float[] op2, float[] op3, byte index, byte imm) - { - for (int i = 0; i < op1.Length; i += 2) - { - int real = i; - int img = i + 1; - (float op3Real, float op3Img) = (op3[index * 2], op3[(index * 2) + 1]); - (float ans1, float ans2) = imm switch - { - 0 => (FusedMultiplyAdd(op1[real], op2[real], op3Real), FusedMultiplyAdd(op1[img], op2[real], op3Img)), - 1 => (FusedMultiplySubtract(op1[real], op2[img], op3Img), FusedMultiplyAdd(op1[img], op2[img], op3Real)), - 2 => (FusedMultiplySubtract(op1[real], op2[real], op3Real), FusedMultiplySubtract(op1[img], op2[real], op3Img)), - 3 => (FusedMultiplyAdd(op1[real], op2[img], op3Img), FusedMultiplySubtract(op1[img], op2[img], op3Real)), - _ => (0.0f, 0.0f) - }; - - op1[real] = ans1; - op1[img] = ans2; - } - - return op1; - } - - public static float MultiplyExtended(float op1, float op2) - { - bool inf1 = float.IsInfinity(op1); - bool inf2 = float.IsInfinity(op2); - - bool zero1 = (op1 == 0); - bool zero2 = (op2 == 0); - - if ((inf1 && zero2) || (zero1 && inf2)) - { - return MathF.CopySign(2, (zero1 ? op2 : op1)); - } - else - { - return op1 * op2; - } - } - - public static float TrigonometricMultiplyAddCoefficient(float op1, float op2, byte imm) - { - int index = (op2 < 0) ? (imm + 8) : imm; - uint coeff = index switch - { - 0 => 0x3f800000, - 1 => 0xbe2aaaab, - 2 => 0x3c088886, - 3 => 0xb95008b9, - 4 => 0x36369d6d, - 5 => 0x00000000, - 6 => 0x00000000, - 7 => 0x00000000, - 8 => 0x3f800000, - 9 => 0xbf000000, - 10 => 0x3d2aaaa6, - 11 => 0xbab60705, - 12 => 0x37cd37cc, - 13 => 0x00000000, - 14 => 0x00000000, - 15 => 0x00000000, - _ => 0x00000000 - }; - - return MathF.FusedMultiplyAdd(op1, Math.Abs(op2), BitConverter.UInt32BitsToSingle(coeff)); - } - - public static float TrigonometricSelectCoefficient(float op1, uint op2) - { - float result = ((op2 % 2) == 0) ? op1 : (float)1.0; - bool isNegative = (op2 & 0b10) == 0b10; - - if (isNegative != (result < 0)) - { - result *= -1; - } - - return result; - } - - public static float TrigonometricStartingValue(float op1, uint op2) - { - float result = op1 * op1; - - if (float.IsNaN(result)) - { - return result; - } - - if ((op2 % 2) == 1) - { - result *= -1; - } - - return result; - } - - public static float FPExponentialAccelerator(uint op1) - { - uint index = op1 & 0b111111; - uint coeff = index switch - { - 0 => 0x000000, - 1 => 0x0164d2, - 2 => 0x02cd87, - 3 => 0x043a29, - 4 => 0x05aac3, - 5 => 0x071f62, - 6 => 0x08980f, - 7 => 0x0a14d5, - 8 => 0x0b95c2, - 9 => 0x0d1adf, - 10 => 0x0ea43a, - 11 => 0x1031dc, - 12 => 0x11c3d3, - 13 => 0x135a2b, - 14 => 0x14f4f0, - 15 => 0x16942d, - 16 => 0x1837f0, - 17 => 0x19e046, - 18 => 0x1b8d3a, - 19 => 0x1d3eda, - 20 => 0x1ef532, - 21 => 0x20b051, - 22 => 0x227043, - 23 => 0x243516, - 24 => 0x25fed7, - 25 => 0x27cd94, - 26 => 0x29a15b, - 27 => 0x2b7a3a, - 28 => 0x2d583f, - 29 => 0x2f3b79, - 30 => 0x3123f6, - 31 => 0x3311c4, - 32 => 0x3504f3, - 33 => 0x36fd92, - 34 => 0x38fbaf, - 35 => 0x3aff5b, - 36 => 0x3d08a4, - 37 => 0x3f179a, - 38 => 0x412c4d, - 39 => 0x4346cd, - 40 => 0x45672a, - 41 => 0x478d75, - 42 => 0x49b9be, - 43 => 0x4bec15, - 44 => 0x4e248c, - 45 => 0x506334, - 46 => 0x52a81e, - 47 => 0x54f35b, - 48 => 0x5744fd, - 49 => 0x599d16, - 50 => 0x5bfbb8, - 51 => 0x5e60f5, - 52 => 0x60ccdf, - 53 => 0x633f89, - 54 => 0x65b907, - 55 => 0x68396a, - 56 => 0x6ac0c7, - 57 => 0x6d4f30, - 58 => 0x6fe4ba, - 59 => 0x728177, - 60 => 0x75257d, - 61 => 0x77d0df, - 62 => 0x7a83b3, - 63 => 0x7d3e0c, - _ => 0x000000 - }; - - uint result = ((op1 & 0b11111111000000) << 17) | coeff; - return BitConverter.UInt32BitsToSingle(result); - } - - public static float FPReciprocalStepFused(float op1, float op2) => FusedMultiplySubtract(2, op1, op2); - - public static float FPReciprocalSqrtStepFused(float op1, float op2) => FusedMultiplySubtract(3, op1, op2) / 2; - - public static double AbsoluteDifference(double op1, double op2) => Math.Abs(op1 - op2); - - public static double FusedMultiplyAdd(double op1, double op2, double op3) => Math.FusedMultiplyAdd(op2, op3, op1); - - public static double FusedMultiplyAddNegated(double op1, double op2, double op3) => Math.FusedMultiplyAdd(-op2, op3, -op1); - - public static double FusedMultiplySubtract(double op1, double op2, double op3) => Math.FusedMultiplyAdd(-op2, op3, op1); - - public static double FusedMultiplySubtractNegated(double op1, double op2, double op3) => Math.FusedMultiplyAdd(op2, op3, -op1); - - public static double MaxNumber(double op1, double op2) => double.IsNaN(op1) ? op2 : (double.IsNaN(op2) ? op1 : Math.Max(op1, op2)); - - public static double MaxNumberPairwise(double[] op1, int i) => Pairwise(MaxNumber, op1, i); - - public static double MaxNumberPairwise(double[] op1, double[] op2, int i) => Pairwise(MaxNumber, op1, op2, i); - - public static double MinNumber(double op1, double op2) => double.IsNaN(op1) ? op2 : (double.IsNaN(op2) ? op1 : Math.Min(op1, op2)); - - public static double MinNumberPairwise(double[] op1, int i) => Pairwise(MinNumber, op1, i); - - public static double MinNumberPairwise(double[] op1, double[] op2, int i) => Pairwise(MinNumber, op1, op2, i); - - public static double[] MultiplyAddRotateComplex(double[] op1, double[] op2, double[] op3, byte imm) - { - for (int i = 0; i < op1.Length; i += 2) - { - int real = i; - int img = i + 1; - (double ans1, double ans2) = imm switch - { - 0 => (FusedMultiplyAdd(op1[real], op2[real], op3[real]), FusedMultiplyAdd(op1[img], op2[real], op3[img])), - 1 => (FusedMultiplySubtract(op1[real], op2[img], op3[img]), FusedMultiplyAdd(op1[img], op2[img], op3[real])), - 2 => (FusedMultiplySubtract(op1[real], op2[real], op3[real]), FusedMultiplySubtract(op1[img], op2[real], op3[img])), - 3 => (FusedMultiplyAdd(op1[real], op2[img], op3[img]), FusedMultiplySubtract(op1[img], op2[img], op3[real])), - _ => (0.0, 0.0) - }; - - op1[real] = ans1; - op1[img] = ans2; - } - - return op1; - } - - public static double MultiplyExtended(double op1, double op2) - { - bool inf1 = double.IsInfinity(op1); - bool inf2 = double.IsInfinity(op2); - - bool zero1 = (op1 == 0); - bool zero2 = (op2 == 0); - - if ((inf1 && zero2) || (zero1 && inf2)) - { - return Math.CopySign(2, (zero1 ? op2 : op1)); - } - else - { - return op1 * op2; - } - } - - public static double TrigonometricMultiplyAddCoefficient(double op1, double op2, byte imm) - { - int index = (op2 < 0) ? (imm + 8) : imm; - ulong coeff = index switch - { - 0 => 0x3ff0000000000000, - 1 => 0xbfc5555555555543, - 2 => 0x3f8111111110f30c, - 3 => 0xbf2a01a019b92fc6, - 4 => 0x3ec71de351f3d22b, - 5 => 0xbe5ae5e2b60f7b91, - 6 => 0x3de5d8408868552f, - 7 => 0x0000000000000000, - 8 => 0x3ff0000000000000, - 9 => 0xbfe0000000000000, - 10 => 0x3fa5555555555536, - 11 => 0xbf56c16c16c13a0b, - 12 => 0x3efa01a019b1e8d8, - 13 => 0xbe927e4f7282f468, - 14 => 0x3e21ee96d2641b13, - 15 => 0xbda8f76380fbb401, - _ => 0x0000000000000000 - }; - - return Math.FusedMultiplyAdd(op1, Math.Abs(op2), BitConverter.UInt64BitsToDouble(coeff)); - } - - public static double TrigonometricSelectCoefficient(double op1, ulong op2) - { - double result = ((op2 % 2) == 0) ? op1 : 1.0; - bool isNegative = (op2 & 0b10) == 0b10; - - if (isNegative != (result < 0)) - { - result *= -1; - } - - return result; - } - - public static double TrigonometricStartingValue(double op1, ulong op2) - { - double result = op1 * op1; - - if (double.IsNaN(result)) - { - return result; - } - - if ((op2 % 2) == 1) - { - result *= -1; - } - - return result; - } - - public static double FPExponentialAccelerator(ulong op1) - { - ulong index = op1 & 0b111111; - ulong coeff = index switch - { - 0 => 0x0000000000000, - 1 => 0x02C9A3E778061, - 2 => 0x059B0D3158574, - 3 => 0x0874518759BC8, - 4 => 0x0B5586CF9890F, - 5 => 0x0E3EC32D3D1A2, - 6 => 0x11301D0125B51, - 7 => 0x1429AAEA92DE0, - 8 => 0x172B83C7D517B, - 9 => 0x1A35BEB6FCB75, - 10 => 0x1D4873168B9AA, - 11 => 0x2063B88628CD6, - 12 => 0x2387A6E756238, - 13 => 0x26B4565E27CDD, - 14 => 0x29E9DF51FDEE1, - 15 => 0x2D285A6E4030B, - 16 => 0x306FE0A31B715, - 17 => 0x33C08B26416FF, - 18 => 0x371A7373AA9CB, - 19 => 0x3A7DB34E59FF7, - 20 => 0x3DEA64C123422, - 21 => 0x4160A21F72E2A, - 22 => 0x44E086061892D, - 23 => 0x486A2B5C13CD0, - 24 => 0x4BFDAD5362A27, - 25 => 0x4F9B2769D2CA7, - 26 => 0x5342B569D4F82, - 27 => 0x56F4736B527DA, - 28 => 0x5AB07DD485429, - 29 => 0x5E76F15AD2148, - 30 => 0x6247EB03A5585, - 31 => 0x6623882552225, - 32 => 0x6A09E667F3BCD, - 33 => 0x6DFB23C651A2F, - 34 => 0x71F75E8EC5F74, - 35 => 0x75FEB564267C9, - 36 => 0x7A11473EB0187, - 37 => 0x7E2F336CF4E62, - 38 => 0x82589994CCE13, - 39 => 0x868D99B4492ED, - 40 => 0x8ACE5422AA0DB, - 41 => 0x8F1AE99157736, - 42 => 0x93737B0CDC5E5, - 43 => 0x97D829FDE4E50, - 44 => 0x9C49182A3F090, - 45 => 0xA0C667B5DE565, - 46 => 0xA5503B23E255D, - 47 => 0xA9E6B5579FDBF, - 48 => 0xAE89F995AD3AD, - 49 => 0xB33A2B84F15FB, - 50 => 0xB7F76F2FB5E47, - 51 => 0xBCC1E904BC1D2, - 52 => 0xC199BDD85529C, - 53 => 0xC67F12E57D14B, - 54 => 0xCB720DCEF9069, - 55 => 0xD072D4A07897C, - 56 => 0xD5818DCFBA487, - 57 => 0xDA9E603DB3285, - 58 => 0xDFC97337B9B5F, - 59 => 0xE502EE78B3FF6, - 60 => 0xEA4AFA2A490DA, - 61 => 0xEFA1BEE615A27, - 62 => 0xF50765B6E4540, - 63 => 0xFA7C1819E90D8, - _ => 0x0000000000000 - }; - - ulong result = ((op1 & 0b11111111111000000) << 46) | coeff; - return BitConverter.UInt64BitsToDouble(result); - } - - public static double FPReciprocalStepFused(double op1, double op2) => FusedMultiplySubtract(2, op1, op2); - - public static double FPReciprocalSqrtStepFused(double op1, double op2) => FusedMultiplySubtract(3, op1, op2) / 2; - - private static uint ReciprocalEstimate(uint a) - { - a = a * 2 + 1; - - uint b = (1 << 19) / a; - uint r = (b + 1) / 2; - - return r; - } - - private static uint ReciprocalSqrtEstimate(uint a) - { - if (a < 256) - { - a = a * 2 + 1; - } - else - { - a = (a >> 1) << 1; - a = (a + 1) * 2; - } - - uint b = 512; - - while (a * (b + 1) * (b + 1) < (1 << 28)) - { - b = b + 1; - } - - uint r = (b + 1) / 2; - - return r; - } - - public static double ReciprocalEstimate(double op1) => Math.ReciprocalEstimate(op1); - - public static float ReciprocalEstimate(float op1) => MathF.ReciprocalEstimate(op1); - - public static double ReciprocalExponent(double op1) - { - ulong bits = (ulong)BitConverter.DoubleToUInt64Bits(op1); - - // Invert the exponent - bits ^= 0x7FF0000000000000; - // Zero the fraction - bits &= 0xFFF0000000000000; - - return BitConverter.UInt64BitsToDouble(bits); - } - - public static float ReciprocalExponent(float op1) - { - uint bits = BitConverter.SingleToUInt32Bits(op1); - - // Invert the exponent - bits ^= 0x7F800000; - // Zero the fraction - bits &= 0xFF800000; - - return BitConverter.UInt32BitsToSingle(bits); - } - - public static double ReciprocalSqrtEstimate(double op1) => Math.ReciprocalSqrtEstimate(op1); - - public static float ReciprocalSqrtEstimate(float op1) => MathF.ReciprocalSqrtEstimate(op1); - - private static uint ExtractBits(uint val, byte msbPos, byte lsbPos) - { - uint andMask = 0; - - for (byte pos = lsbPos; pos <= msbPos; pos++) - { - andMask |= (uint)1 << pos; - } - - return (val & andMask) >> lsbPos; - } - - public static uint UnsignedReciprocalEstimate(uint op1) - { - uint result; - - if ((op1 & (1 << 31)) == 0) - { - result = ~0U; - } - else - { - uint estimate = ReciprocalEstimate(ExtractBits(op1, 31, 23)); - result = ExtractBits(estimate, 8, 0) << 31; - } - - return result; - } - - public static uint UnsignedReciprocalSqrtEstimate(uint op1) - { - uint result; - - if ((op1 & (3 << 30)) == 0) - { - result = ~0U; - } - else - { - uint estimate = ReciprocalSqrtEstimate(ExtractBits(op1, 31, 23)); - result = ExtractBits(estimate, 8, 0) << 31; - } - - return result; - } - - public static sbyte Add(sbyte op1, sbyte op2) => (sbyte)(op1 + op2); - - public static sbyte AddPairwise(sbyte[] op1, int i) => Pairwise(Add, op1, i); - - public static sbyte AddPairwise(sbyte[] op1, sbyte[] op2, int i) => Pairwise(Add, op1, op2, i); - - public static sbyte AddPairwiseSve(sbyte[] op1, sbyte[] op2, int i) - { - if (i % 2 == 0) - { - return (sbyte)(op1[i] + op1[i + 1]); - } - else - { - return (sbyte)(op2[i - 1] + op2[i]); - } - } - - public static sbyte Max(sbyte op1, sbyte op2) => Math.Max(op1, op2); - - public static sbyte MaxPairwise(sbyte[] op1, int i) => Pairwise(Max, op1, i); - - public static sbyte MaxPairwise(sbyte[] op1, sbyte[] op2, int i) => Pairwise(Max, op1, op2, i); - - public static sbyte Min(sbyte op1, sbyte op2) => Math.Min(op1, op2); - - public static sbyte MinPairwise(sbyte[] op1, int i) => Pairwise(Min, op1, i); - - public static sbyte MinPairwise(sbyte[] op1, sbyte[] op2, int i) => Pairwise(Min, op1, op2, i); - - public static sbyte Multiply(sbyte op1, sbyte op2) => (sbyte)(op1 * op2); - - public static sbyte MultiplyAdd(sbyte op1, sbyte op2, sbyte op3) => (sbyte)(op1 + (sbyte)(op2 * op3)); - - public static sbyte MultiplySubtract(sbyte op1, sbyte op2, sbyte op3) => (sbyte)(op1 - (sbyte)(op2 * op3)); - - public static sbyte Subtract(sbyte op1, sbyte op2) => (sbyte)(op1 - op2); - - private static sbyte Pairwise(Func pairOp, sbyte[] op1, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return 0; - } - } - - private static sbyte Pairwise(Func pairOp, sbyte[] op1, sbyte[] op2, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return pairOp(op2[2 * i - op1.Length], op2[2 * i + 1 - op1.Length]); - } - } - - public static byte Add(byte op1, byte op2) => (byte)(op1 + op2); - - public static byte AddPairwise(byte[] op1, int i) => Pairwise(Add, op1, i); - - public static byte AddPairwise(byte[] op1, byte[] op2, int i) => Pairwise(Add, op1, op2, i); - - public static byte AddPairwiseSve(byte[] op1, byte[] op2, int i) - { - if (i % 2 == 0) - { - return (byte)(op1[i] + op1[i + 1]); - } - else - { - return (byte)(op2[i - 1] + op2[i]); - } - } - public static byte Max(byte op1, byte op2) => Math.Max(op1, op2); - - public static byte MaxPairwise(byte[] op1, int i) => Pairwise(Max, op1, i); - - public static byte MaxPairwise(byte[] op1, byte[] op2, int i) => Pairwise(Max, op1, op2, i); - - public static byte Min(byte op1, byte op2) => Math.Min(op1, op2); - - public static byte MinPairwise(byte[] op1, int i) => Pairwise(Min, op1, i); - - public static byte MinPairwise(byte[] op1, byte[] op2, int i) => Pairwise(Min, op1, op2, i); - - public static byte Multiply(byte op1, byte op2) => (byte)(op1 * op2); - - public static byte MultiplyAdd(byte op1, byte op2, byte op3) => (byte)(op1 + (byte)(op2 * op3)); - - public static byte MultiplySubtract(byte op1, byte op2, byte op3) => (byte)(op1 - (byte)(op2 * op3)); - - public static byte Subtract(byte op1, byte op2) => (byte)(op1 - op2); - - private static byte Pairwise(Func pairOp, byte[] op1, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return 0; - } - } - - private static byte Pairwise(Func pairOp, byte[] op1, byte[] op2, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return pairOp(op2[2 * i - op1.Length], op2[2 * i + 1 - op1.Length]); - } - } - - public static short Add(short op1, short op2) => (short)(op1 + op2); - - public static short AddPairwise(short[] op1, int i) => Pairwise(Add, op1, i); - - public static short AddPairwise(short[] op1, short[] op2, int i) => Pairwise(Add, op1, op2, i); - - public static short AddPairwiseSve(short[] op1, short[] op2, int i) - { - if (i % 2 == 0) - { - return (short)(op1[i] + op1[i + 1]); - } - else - { - return (short)(op2[i - 1] + op2[i]); - } - } - - public static short AddPairwiseWidening(short[] op1, sbyte[] op2, int i) => (short)(op1[i] + (short)op2[i * 2] + (short)op2[i * 2 + 1]); - - public static short Max(short op1, short op2) => Math.Max(op1, op2); - - public static short MaxPairwise(short[] op1, int i) => Pairwise(Max, op1, i); - - public static short MaxPairwise(short[] op1, short[] op2, int i) => Pairwise(Max, op1, op2, i); - - public static short Min(short op1, short op2) => Math.Min(op1, op2); - - public static short MinPairwise(short[] op1, int i) => Pairwise(Min, op1, i); - - public static short MinPairwise(short[] op1, short[] op2, int i) => Pairwise(Min, op1, op2, i); - - public static short Multiply(short op1, short op2) => (short)(op1 * op2); - - public static short MultiplyAdd(short op1, short op2, short op3) => (short)(op1 + (short)(op2 * op3)); - - public static short MultiplySubtract(short op1, short op2, short op3) => (short)(op1 - (short)(op2 * op3)); - - public static short Subtract(short op1, short op2) => (short)(op1 - op2); - - private static short Pairwise(Func pairOp, short[] op1, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return 0; - } - } - - private static short Pairwise(Func pairOp, short[] op1, short[] op2, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return pairOp(op2[2 * i - op1.Length], op2[2 * i + 1 - op1.Length]); - } - } - - public static ushort Add(ushort op1, ushort op2) => (ushort)(op1 + op2); - - public static ushort AddPairwise(ushort[] op1, int i) => Pairwise(Add, op1, i); - - public static ushort AddPairwise(ushort[] op1, ushort[] op2, int i) => Pairwise(Add, op1, op2, i); - - public static ushort AddPairwiseSve(ushort[] op1, ushort[] op2, int i) - { - if (i % 2 == 0) - { - return (ushort)(op1[i] + op1[i + 1]); - } - else - { - return (ushort)(op2[i - 1] + op2[i]); - } - } - - public static ushort AddPairwiseWidening(ushort[] op1, byte[] op2, int i) => (ushort)(op1[i] + (ushort)op2[i * 2] + (ushort)op2[i * 2 + 1]); - - public static ushort Max(ushort op1, ushort op2) => Math.Max(op1, op2); - - public static ushort MaxPairwise(ushort[] op1, int i) => Pairwise(Max, op1, i); - - public static ushort MaxPairwise(ushort[] op1, ushort[] op2, int i) => Pairwise(Max, op1, op2, i); - - public static ushort Min(ushort op1, ushort op2) => Math.Min(op1, op2); - - public static ushort MinPairwise(ushort[] op1, int i) => Pairwise(Min, op1, i); - - public static ushort MinPairwise(ushort[] op1, ushort[] op2, int i) => Pairwise(Min, op1, op2, i); - - public static ushort Multiply(ushort op1, ushort op2) => (ushort)(op1 * op2); - - public static ushort MultiplyAdd(ushort op1, ushort op2, ushort op3) => (ushort)(op1 + (ushort)(op2 * op3)); - - public static ushort MultiplySubtract(ushort op1, ushort op2, ushort op3) => (ushort)(op1 - (ushort)(op2 * op3)); - - public static ushort Subtract(ushort op1, ushort op2) => (ushort)(op1 - op2); - - private static ushort Pairwise(Func pairOp, ushort[] op1, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return 0; - } - } - - private static ushort Pairwise(Func pairOp, ushort[] op1, ushort[] op2, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return pairOp(op2[2 * i - op1.Length], op2[2 * i + 1 - op1.Length]); - } - } - - public static int Add(int op1, int op2) => (int)(op1 + op2); - - public static int AddPairwise(int[] op1, int i) => Pairwise(Add, op1, i); - - public static int AddPairwise(int[] op1, int[] op2, int i) => Pairwise(Add, op1, op2, i); - - public static int AddPairwiseSve(int[] op1, int[] op2, int i) - { - if (i % 2 == 0) - { - return (int)(op1[i] + op1[i + 1]); - } - else - { - return (int)(op2[i - 1] + op2[i]); - } - } - - public static int AddPairwiseWidening(int[] op1, short[] op2, int i) => op1[i] + (int)op2[i * 2] + (int)op2[i * 2 + 1]; - - public static int Max(int op1, int op2) => Math.Max(op1, op2); - - public static int MaxPairwise(int[] op1, int i) => Pairwise(Max, op1, i); - - public static int MaxPairwise(int[] op1, int[] op2, int i) => Pairwise(Max, op1, op2, i); - - public static int Min(int op1, int op2) => Math.Min(op1, op2); - - public static int MinPairwise(int[] op1, int i) => Pairwise(Min, op1, i); - - public static int MinPairwise(int[] op1, int[] op2, int i) => Pairwise(Min, op1, op2, i); - - public static int Multiply(int op1, int op2) => (int)(op1 * op2); - - public static int MultiplyAdd(int op1, int op2, int op3) => (int)(op1 + (int)(op2 * op3)); - - public static int MultiplySubtract(int op1, int op2, int op3) => (int)(op1 - (int)(op2 * op3)); - - public static int Subtract(int op1, int op2) => (int)(op1 - op2); - - private static int Pairwise(Func pairOp, int[] op1, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return 0; - } - } - - private static int Pairwise(Func pairOp, int[] op1, int[] op2, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return pairOp(op2[2 * i - op1.Length], op2[2 * i + 1 - op1.Length]); - } - } - - public static uint Add(uint op1, uint op2) => (uint)(op1 + op2); - - public static uint AddPairwise(uint[] op1, int i) => Pairwise(Add, op1, i); - - public static uint AddPairwise(uint[] op1, uint[] op2, int i) => Pairwise(Add, op1, op2, i); - - public static uint AddPairwiseSve(uint[] op1, uint[] op2, int i) - { - if (i % 2 == 0) - { - return (uint)(op1[i] + op1[i + 1]); - } - else - { - return (uint)(op2[i - 1] + op2[i]); - } - } - - public static uint AddPairwiseWidening(uint[] op1, ushort[] op2, int i) => op1[i] + (uint)op2[i * 2] + (uint)op2[i * 2 + 1]; - - public static uint Max(uint op1, uint op2) => Math.Max(op1, op2); - - public static uint MaxPairwise(uint[] op1, int i) => Pairwise(Max, op1, i); - - public static uint MaxPairwise(uint[] op1, uint[] op2, int i) => Pairwise(Max, op1, op2, i); - - public static uint Min(uint op1, uint op2) => Math.Min(op1, op2); - - public static uint MinPairwise(uint[] op1, int i) => Pairwise(Min, op1, i); - - public static uint MinPairwise(uint[] op1, uint[] op2, int i) => Pairwise(Min, op1, op2, i); - - public static uint Multiply(uint op1, uint op2) => (uint)(op1 * op2); - - public static uint MultiplyAdd(uint op1, uint op2, uint op3) => (uint)(op1 + (uint)(op2 * op3)); - - public static uint MultiplySubtract(uint op1, uint op2, uint op3) => (uint)(op1 - (uint)(op2 * op3)); - - public static uint Subtract(uint op1, uint op2) => (uint)(op1 - op2); - - private static uint Pairwise(Func pairOp, uint[] op1, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return 0; - } - } - - private static uint Pairwise(Func pairOp, uint[] op1, uint[] op2, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return pairOp(op2[2 * i - op1.Length], op2[2 * i + 1 - op1.Length]); - } - } - - public static long Add(long op1, long op2) => (long)(op1 + op2); - - public static long AddPairwise(long[] op1, int i) => Pairwise(Add, op1, i); - - public static long AddPairwise(long[] op1, long[] op2, int i) => Pairwise(Add, op1, op2, i); - - public static long AddPairwiseSve(long[] op1, long[] op2, int i) - { - if (i % 2 == 0) - { - return (long)(op1[i] + op1[i + 1]); - } - else - { - return (long)(op2[i - 1] + op2[i]); - } - } - - public static long AddPairwiseWidening(long[] op1, int[] op2, int i) => op1[i] + (int)op2[i * 2] + (int)op2[i * 2 + 1]; - - public static long Max(long op1, long op2) => Math.Max(op1, op2); - - public static long MaxPairwise(long[] op1, int i) => Pairwise(Max, op1, i); - - public static long MaxPairwise(long[] op1, long[] op2, int i) => Pairwise(Max, op1, op2, i); - - public static long Min(long op1, long op2) => Math.Min(op1, op2); - - public static long MinPairwise(long[] op1, int i) => Pairwise(Min, op1, i); - - public static long MinPairwise(long[] op1, long[] op2, int i) => Pairwise(Min, op1, op2, i); - - public static long Multiply(long op1, long op2) => (long)(op1 * op2); - - public static long MultiplyAdd(long op1, long op2, long op3) => (long)(op1 + (long)(op2 * op3)); - - public static long MultiplySubtract(long op1, long op2, long op3) => (long)(op1 - (long)(op2 * op3)); - - public static long Subtract(long op1, long op2) => (long)(op1 - op2); - - private static long Pairwise(Func pairOp, long[] op1, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return 0; - } - } - - private static long Pairwise(Func pairOp, long[] op1, long[] op2, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return pairOp(op2[2 * i - op1.Length], op2[2 * i + 1 - op1.Length]); - } - } - - public static ulong Add(ulong op1, ulong op2) => (ulong)(op1 + op2); - - public static ulong AddPairwise(ulong[] op1, int i) => Pairwise(Add, op1, i); - - public static ulong AddPairwise(ulong[] op1, ulong[] op2, int i) => Pairwise(Add, op1, op2, i); - - public static ulong AddPairwiseSve(ulong[] op1, ulong[] op2, int i) - { - if (i % 2 == 0) - { - return (ulong)(op1[i] + op1[i + 1]); - } - else - { - return (ulong)(op2[i - 1] + op2[i]); - } - } - - public static ulong AddPairwiseWidening(ulong[] op1, uint[] op2, int i) => op1[i] + (ulong)op2[i * 2] + (ulong)op2[i * 2 + 1]; - - public static ulong Max(ulong op1, ulong op2) => Math.Max(op1, op2); - - public static ulong MaxPairwise(ulong[] op1, int i) => Pairwise(Max, op1, i); - - public static ulong MaxPairwise(ulong[] op1, ulong[] op2, int i) => Pairwise(Max, op1, op2, i); - - public static ulong Min(ulong op1, ulong op2) => Math.Min(op1, op2); - - public static ulong MinPairwise(ulong[] op1, int i) => Pairwise(Min, op1, i); - - public static ulong MinPairwise(ulong[] op1, ulong[] op2, int i) => Pairwise(Min, op1, op2, i); - - public static ulong Multiply(ulong op1, ulong op2) => (ulong)(op1 * op2); - - public static ulong MultiplyAdd(ulong op1, ulong op2, ulong op3) => (ulong)(op1 + (ulong)(op2 * op3)); - - public static ulong MultiplySubtract(ulong op1, ulong op2, ulong op3) => (ulong)(op1 - (ulong)(op2 * op3)); - - public static ulong Subtract(ulong op1, ulong op2) => (ulong)(op1 - op2); - - private static ulong Pairwise(Func pairOp, ulong[] op1, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return 0; - } - } - - private static ulong Pairwise(Func pairOp, ulong[] op1, ulong[] op2, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return pairOp(op2[2 * i - op1.Length], op2[2 * i + 1 - op1.Length]); - } - } - - public static float Add(float op1, float op2) => (float)(op1 + op2); - - public static float AddPairwise(float[] op1, int i) => Pairwise(Add, op1, i); - - public static float AddPairwise(float[] op1, float[] op2, int i) => Pairwise(Add, op1, op2, i); - - public static float AddPairwiseSve(float[] op1, float[] op2, int i) - { - if (i % 2 == 0) - { - return (float)(op1[i] + op1[i + 1]); - } - else - { - return (float)(op2[i - 1] + op2[i]); - } - } - - public static float[] AddRotateComplex(float[] op1, float[] op2, byte rot) - { - for (int i = 0; i < op1.Length; i += 2) - { - int real = i; - int img = i + 1; - - if (rot == 0) - { - op1[real] -= op2[img]; - op1[img] += op2[real]; - } - else - { - op1[real] += op2[img]; - op1[img] -= op2[real]; - } - } - - return op1; - } - - public static float Max(float op1, float op2) => Math.Max(op1, op2); - - public static float MaxPairwise(float[] op1, int i) => Pairwise(Max, op1, i); - - public static float MaxPairwise(float[] op1, float[] op2, int i) => Pairwise(Max, op1, op2, i); - - public static float Min(float op1, float op2) => Math.Min(op1, op2); - - public static float MinPairwise(float[] op1, int i) => Pairwise(Min, op1, i); - - public static float MinPairwise(float[] op1, float[] op2, int i) => Pairwise(Min, op1, op2, i); - - public static float Multiply(float op1, float op2) => (float)(op1 * op2); - - public static float MultiplyAdd(float op1, float op2, float op3) => (float)(op1 + (float)(op2 * op3)); - - public static float MultiplySubtract(float op1, float op2, float op3) => (float)(op1 - (float)(op2 * op3)); - - public static float Subtract(float op1, float op2) => (float)(op1 - op2); - - private static float Pairwise(Func pairOp, float[] op1, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return 0; - } - } - - private static float Pairwise(Func pairOp, float[] op1, float[] op2, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return pairOp(op2[2 * i - op1.Length], op2[2 * i + 1 - op1.Length]); - } - } - - public static double Add(double op1, double op2) => (double)(op1 + op2); - - public static double AddPairwise(double[] op1, int i) => Pairwise(Add, op1, i); - - public static double AddPairwise(double[] op1, double[] op2, int i) => Pairwise(Add, op1, op2, i); - - public static double AddPairwiseSve(double[] op1, double[] op2, int i) - { - if (i % 2 == 0) - { - return (double)(op1[i] + op1[i + 1]); - } - else - { - return (double)(op2[i - 1] + op2[i]); - } - } - - public static double[] AddRotateComplex(double[] op1, double[] op2, byte rot) - { - for (int i = 0; i < op1.Length; i += 2) - { - int real = i; - int img = i + 1; - - if (rot == 0) - { - op1[real] -= op2[img]; - op1[img] += op2[real]; - } - else - { - op1[real] += op2[img]; - op1[img] -= op2[real]; - } - } - - return op1; - } - - public static double Max(double op1, double op2) => Math.Max(op1, op2); - - public static double MaxPairwise(double[] op1, int i) => Pairwise(Max, op1, i); - - public static double MaxPairwise(double[] op1, double[] op2, int i) => Pairwise(Max, op1, op2, i); - - public static double Min(double op1, double op2) => Math.Min(op1, op2); - - public static double MinPairwise(double[] op1, int i) => Pairwise(Min, op1, i); - - public static double MinPairwise(double[] op1, double[] op2, int i) => Pairwise(Min, op1, op2, i); - - public static double Multiply(double op1, double op2) => (double)(op1 * op2); - - public static double MultiplyAdd(double op1, double op2, double op3) => (double)(op1 + (double)(op2 * op3)); - - public static double MultiplySubtract(double op1, double op2, double op3) => (double)(op1 - (double)(op2 * op3)); - - public static double Subtract(double op1, double op2) => (double)(op1 - op2); - - private static double Pairwise(Func pairOp, double[] op1, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return 0; - } - } - - private static double Pairwise(Func pairOp, double[] op1, double[] op2, int i) - { - if (2 * i + 1 < op1.Length) - { - return pairOp(op1[2 * i], op1[2 * i + 1]); - } - else - { - return pairOp(op2[2 * i - op1.Length], op2[2 * i + 1 - op1.Length]); - } - } - - public static sbyte Negate(sbyte op1) => (sbyte)(-op1); - - public static short Negate(short op1) => (short)(-op1); - - public static int Negate(int op1) => (int)(-op1); - - public static long Negate(long op1) => (long)(-op1); - - public static float Negate(float op1) => (float)(-op1); - - public static double Negate(double op1) => (double)(-op1); - - public static sbyte AddAcross(sbyte[] op1) => Reduce(Add, op1); - - public static sbyte AndAcross(sbyte[] op1) => Reduce(And, op1); - - public static sbyte MaxAcross(sbyte[] op1) => Reduce(Max, op1); - - public static sbyte MinAcross(sbyte[] op1) => Reduce(Min, op1); - - public static sbyte OrAcross(sbyte[] op1) => Reduce(Or, op1); - - public static sbyte XorAcross(sbyte[] op1) => Reduce(Xor, op1); - - private static sbyte Reduce(Func reduceOp, sbyte[] op1) - { - sbyte acc = op1[0]; - - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } - - return acc; - } - - public static byte AddAcross(byte[] op1) => Reduce(Add, op1); - - public static byte AndAcross(byte[] op1) => Reduce(And, op1); - - public static byte MaxAcross(byte[] op1) => Reduce(Max, op1); - - public static byte MinAcross(byte[] op1) => Reduce(Min, op1); - - public static byte OrAcross(byte[] op1) => Reduce(Or, op1); - - public static byte XorAcross(byte[] op1) => Reduce(Xor, op1); - - private static byte Reduce(Func reduceOp, byte[] op1) - { - byte acc = op1[0]; - - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } - - return acc; - } - - public static short AddAcross(short[] op1) => Reduce(Add, op1); - - public static short AndAcross(short[] op1) => Reduce(And, op1); - - public static short MaxAcross(short[] op1) => Reduce(Max, op1); - - public static short MinAcross(short[] op1) => Reduce(Min, op1); - - public static short OrAcross(short[] op1) => Reduce(Or, op1); - - public static short XorAcross(short[] op1) => Reduce(Xor, op1); - - private static short Reduce(Func reduceOp, short[] op1) - { - short acc = op1[0]; - - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } - - return acc; - } - - public static ushort AddAcross(ushort[] op1) => Reduce(Add, op1); - - public static ushort AndAcross(ushort[] op1) => Reduce(And, op1); - - public static ushort MaxAcross(ushort[] op1) => Reduce(Max, op1); - - public static ushort MinAcross(ushort[] op1) => Reduce(Min, op1); - - public static ushort OrAcross(ushort[] op1) => Reduce(Or, op1); - - public static ushort XorAcross(ushort[] op1) => Reduce(Xor, op1); - - private static ushort Reduce(Func reduceOp, ushort[] op1) - { - ushort acc = op1[0]; - - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } - - return acc; - } - - public static int AddAcross(int[] op1) => Reduce(Add, op1); - - public static int AndAcross(int[] op1) => Reduce(And, op1); - - public static int MaxAcross(int[] op1) => Reduce(Max, op1); - - public static int MinAcross(int[] op1) => Reduce(Min, op1); - - public static int OrAcross(int[] op1) => Reduce(Or, op1); - - public static int XorAcross(int[] op1) => Reduce(Xor, op1); - - private static int Reduce(Func reduceOp, int[] op1) - { - int acc = op1[0]; - - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } - - return acc; - } - - public static uint AddAcross(uint[] op1) => Reduce(Add, op1); - - public static uint AndAcross(uint[] op1) => Reduce(And, op1); - - public static uint MaxAcross(uint[] op1) => Reduce(Max, op1); - - public static uint MinAcross(uint[] op1) => Reduce(Min, op1); - - public static uint OrAcross(uint[] op1) => Reduce(Or, op1); - - public static uint XorAcross(uint[] op1) => Reduce(Xor, op1); - - private static uint Reduce(Func reduceOp, uint[] op1) - { - uint acc = op1[0]; - - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } - - return acc; - } - - public static long AddAcross(long[] op1) => Reduce(Add, op1); - - public static long AndAcross(long[] op1) => Reduce(And, op1); - - public static long MaxAcross(long[] op1) => Reduce(Max, op1); - - public static long MinAcross(long[] op1) => Reduce(Min, op1); - - public static long OrAcross(long[] op1) => Reduce(Or, op1); - - public static long XorAcross(long[] op1) => Reduce(Xor, op1); - - private static long Reduce(Func reduceOp, long[] op1) - { - long acc = op1[0]; - - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } - - return acc; - } - - public static ulong AddAcross(ulong[] op1) => Reduce(Add, op1); - - public static ulong AndAcross(ulong[] op1) => Reduce(And, op1); - - public static ulong MaxAcross(ulong[] op1) => Reduce(Max, op1); - - public static ulong MinAcross(ulong[] op1) => Reduce(Min, op1); - - public static ulong OrAcross(ulong[] op1) => Reduce(Or, op1); - - public static ulong XorAcross(ulong[] op1) => Reduce(Xor, op1); - - private static ulong Reduce(Func reduceOp, ulong[] op1) - { - ulong acc = op1[0]; - - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } - - return acc; - } - - public static float AddAcross(float[] op1) => Reduce(Add, op1); - - public static float MaxAcross(float[] op1) => Reduce(Max, op1); - - public static float MinAcross(float[] op1) => Reduce(Min, op1); - - private static float Reduce(Func reduceOp, float[] op1) - { - float acc = op1[0]; - - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } - - return acc; - } - - public static float AddAcrossRecursivePairwise(float[] op1) => ReduceRecursivePairwise(Add, op1); - - private static float ReduceRecursivePairwise(Func reduceOp, float[] op1) - { - if (op1.Length == 2) - { - return reduceOp(op1[0], op1[1]); - } - - if (op1.Length % 2 != 0) - { - return float.NaN; - } - - float[] l = new float[op1.Length / 2]; - Array.Copy(op1, 0, l, 0, (op1.Length / 2)); - float l_reduced = ReduceRecursivePairwise(reduceOp, l); - - float[] r = new float[op1.Length / 2]; - Array.Copy(op1, (op1.Length / 2), r, 0, (op1.Length / 2)); - float r_reduced = ReduceRecursivePairwise(reduceOp, r); - - return reduceOp(l_reduced, r_reduced); - } - - public static double AddAcross(double[] op1) => Reduce(Add, op1); - - public static double MaxAcross(double[] op1) => Reduce(Max, op1); - - public static double MinAcross(double[] op1) => Reduce(Min, op1); - - private static double Reduce(Func reduceOp, double[] op1) - { - double acc = op1[0]; - - for (int i = 1; i < op1.Length; i++) - { - acc = reduceOp(acc, op1[i]); - } - - return acc; - } - - public static double AddAcrossRecursivePairwise(double[] op1) => ReduceRecursivePairwise(Add, op1); - - private static double ReduceRecursivePairwise(Func reduceOp, double[] op1) - { - if (op1.Length == 2) - { - return reduceOp(op1[0], op1[1]); - } - - if (op1.Length % 2 != 0) - { - return double.NaN; - } - - double[] l = new double[op1.Length / 2]; - Array.Copy(op1, 0, l, 0, (op1.Length / 2)); - double l_reduced = ReduceRecursivePairwise(reduceOp, l); - - double[] r = new double[op1.Length / 2]; - Array.Copy(op1, (op1.Length / 2), r, 0, (op1.Length / 2)); - double r_reduced = ReduceRecursivePairwise(reduceOp, r); - - return reduceOp(l_reduced, r_reduced); - } - - public static float MaxNumberAcross(float[] op1) => Reduce(MaxNumber, op1); - - public static float MinNumberAcross(float[] op1) => Reduce(MinNumber, op1); - - private struct poly128_t - { - public ulong lo; - public ulong hi; - - public static poly128_t operator ^(poly128_t op1, poly128_t op2) - { - op1.lo ^= op2.lo; - op1.hi ^= op2.hi; - - return op1; - } - - public static poly128_t operator <<(poly128_t val, int shiftAmount) - { - for (int i = 0; i < shiftAmount; i++) - { - val.hi <<= 1; - - if ((val.lo & 0x8000000000000000U) != 0) - { - val.hi |= 1; - } - - val.lo <<= 1; - } - - return val; - } - - public static implicit operator poly128_t(ulong lo) - { - poly128_t result = new poly128_t(); - result.lo = lo; - return result; - } - - public static explicit operator poly128_t(long lo) - { - poly128_t result = new poly128_t(); - result.lo = (ulong)lo; - return result; - } - } - - private static ushort PolynomialMult(byte op1, byte op2) - { - ushort result = default(ushort); - ushort extendedOp2 = (ushort)op2; - - for (int i = 0; i < 8 * sizeof(byte); i++) - { - if ((op1 & ((byte)1 << i)) != 0) - { - result = (ushort)(result ^ (extendedOp2 << i)); - } - } - - return result; - } - - private static short PolynomialMult(sbyte op1, sbyte op2) - { - short result = default(short); - short extendedOp2 = (short)op2; - - for (int i = 0; i < 8 * sizeof(sbyte); i++) - { - if ((op1 & ((sbyte)1 << i)) != 0) - { - result = (short)(result ^ (extendedOp2 << i)); - } - } - - return result; - } - - private static poly128_t PolynomialMult(ulong op1, ulong op2) - { - poly128_t result = default(poly128_t); - poly128_t extendedOp2 = (poly128_t)op2; - - for (int i = 0; i < 8 * sizeof(ulong); i++) - { - if ((op1 & ((ulong)1 << i)) != 0) - { - result = (poly128_t)(result ^ (extendedOp2 << i)); - } - } - - return result; - } - - private static poly128_t PolynomialMult(long op1, long op2) - { - poly128_t result = default(poly128_t); - poly128_t extendedOp2 = (poly128_t)op2; - - for (int i = 0; i < 8 * sizeof(long); i++) - { - if ((op1 & ((long)1 << i)) != 0) - { - result = (poly128_t)(result ^ (extendedOp2 << i)); - } - } - - return result; - } - - public static long MultiplyHigh(long op1, long op2) - { - ulong u0, v0, w0; - long u1, v1, w1, w2, t; - u0 = (ulong)op1 & 0xFFFFFFFF; - u1 = op1 >> 32; - v0 = (ulong)op2 & 0xFFFFFFFF; - v1 = op2 >> 32; - w0 = u0 * v0; - t = u1 * (long)v0 + (long)(w0 >> 32); - w1 = t & 0xFFFFFFFF; - w2 = t >> 32; - w1 = (long)u0 * v1 + w1; - return u1 * v1 + w2 + (w1 >> 32); - } - - public static ulong MultiplyHigh(ulong op1, ulong op2) - { - ulong u0, v0, w0; - ulong u1, v1, w1, w2, t; - u0 = (ulong)op1 & 0xFFFFFFFF; - u1 = op1 >> 32; - v0 = (ulong)op2 & 0xFFFFFFFF; - v1 = op2 >> 32; - w0 = u0 * v0; - t = u1 * (ulong)v0 + (ulong)(w0 >> 32); - w1 = t & 0xFFFFFFFF; - w2 = t >> 32; - w1 = (ulong)u0 * v1 + w1; - return u1 * v1 + w2 + (w1 >> 32); - } - - public static byte PolynomialMultiply(byte op1, byte op2) => (byte)PolynomialMult(op1, op2); - - public static ushort PolynomialMultiplyWidening(byte op1, byte op2) => PolynomialMult(op1, op2); - - public static ushort PolynomialMultiplyWideningUpper(byte[] op1, byte[] op2, int i) => PolynomialMultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - - public static sbyte PolynomialMultiply(sbyte op1, sbyte op2) => (sbyte)PolynomialMult(op1, op2); - - public static short PolynomialMultiplyWidening(sbyte op1, sbyte op2) => PolynomialMult(op1, op2); - - public static short PolynomialMultiplyWideningUpper(sbyte[] op1, sbyte[] op2, int i) => PolynomialMultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); - - public static ulong PolynomialMultiplyWideningLo64(ulong op1, ulong op2) => PolynomialMult(op1, op2).lo; - - public static long PolynomialMultiplyWideningLo64(long op1, long op2) => (long)PolynomialMult(op1, op2).lo; - - public static ulong PolynomialMultiplyWideningHi64(ulong op1, ulong op2) => PolynomialMult(op1, op2).hi; - - public static long PolynomialMultiplyWideningHi64(long op1, long op2) => (long)PolynomialMult(op1, op2).hi; - - public static 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) - { - return i switch - { - 0 => op1[0], - 1 => op2[0], - _ => 0 - }; - } - - public static sbyte ExtractVector(sbyte[] op1, sbyte[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - - public static sbyte Insert(sbyte[] op1, int op2, sbyte op3, int i) => (op2 != i) ? op1[i] : op3; - - public static byte Concat(byte[] op1, byte[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - - public static byte ConcatScalar(byte[] op1, byte[] op2, int i) - { - return i switch - { - 0 => op1[0], - 1 => op2[0], - _ => 0 - }; - } - - public static byte ExtractVector(byte[] op1, byte[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - - public static byte Insert(byte[] op1, int op2, byte op3, int i) => (op2 != i) ? op1[i] : op3; - - public static short Concat(short[] op1, short[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - - public static short ConcatScalar(short[] op1, short[] op2, int i) - { - return i switch - { - 0 => op1[0], - 1 => op2[0], - _ => 0 - }; - } - - public static short ExtractVector(short[] op1, short[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - - public static short Insert(short[] op1, int op2, short op3, int i) => (op2 != i) ? op1[i] : op3; - - public static ushort Concat(ushort[] op1, ushort[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - - public static ushort ConcatScalar(ushort[] op1, ushort[] op2, int i) - { - return i switch - { - 0 => op1[0], - 1 => op2[0], - _ => 0 - }; - } - - public static ushort ExtractVector(ushort[] op1, ushort[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - - public static ushort Insert(ushort[] op1, int op2, ushort op3, int i) => (op2 != i) ? op1[i] : op3; - - public static int Concat(int[] op1, int[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - - public static int ConcatScalar(int[] op1, int[] op2, int i) - { - return i switch - { - 0 => op1[0], - 1 => op2[0], - _ => 0 - }; - } - - public static int ExtractVector(int[] op1, int[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - - public static int Insert(int[] op1, int op2, int op3, int i) => (op2 != i) ? op1[i] : op3; - - public static uint Concat(uint[] op1, uint[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - - public static uint ConcatScalar(uint[] op1, uint[] op2, int i) - { - return i switch - { - 0 => op1[0], - 1 => op2[0], - _ => 0 - }; - } - - public static uint ExtractVector(uint[] op1, uint[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - - public static uint Insert(uint[] op1, int op2, uint op3, int i) => (op2 != i) ? op1[i] : op3; - - public static long Concat(long[] op1, long[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - - public static long ConcatScalar(long[] op1, long[] op2, int i) - { - return i switch - { - 0 => op1[0], - 1 => op2[0], - _ => 0 - }; - } - - public static long ExtractVector(long[] op1, long[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - - public static long Insert(long[] op1, int op2, long op3, int i) => (op2 != i) ? op1[i] : op3; - - public static ulong Concat(ulong[] op1, ulong[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - - public static ulong ConcatScalar(ulong[] op1, ulong[] op2, int i) - { - return i switch - { - 0 => op1[0], - 1 => op2[0], - _ => 0 - }; - } - - public static ulong ExtractVector(ulong[] op1, ulong[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - - public static ulong Insert(ulong[] op1, int op2, ulong op3, int i) => (op2 != i) ? op1[i] : op3; - - public static float Concat(float[] op1, float[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - - public static float ConcatScalar(float[] op1, float[] op2, int i) - { - return i switch - { - 0 => op1[0], - 1 => op2[0], - _ => 0 - }; - } - - public static float ExtractVector(float[] op1, float[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - - public static float Insert(float[] op1, int op2, float op3, int i) => (op2 != i) ? op1[i] : op3; - - public static double Concat(double[] op1, double[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; - - public static double ConcatScalar(double[] op1, double[] op2, int i) - { - return i switch - { - 0 => op1[0], - 1 => op2[0], - _ => 0 - }; - } - - public static double ExtractVector(double[] op1, double[] op2, int op3, int i) => Concat(op1, op2, op3 + i); - - public static double Insert(double[] op1, int op2, double op3, int i) => (op2 != i) ? op1[i] : op3; - - public static int LoadPairScalar(int[] op1, int i) => (i == 0) ? op1[0] : (i == op1.Length / 2) ? op1[1] : (int)0; - - public static uint LoadPairScalar(uint[] op1, int i) => (i == 0) ? op1[0] : (i == op1.Length / 2) ? op1[1] : (uint)0; - - public static float LoadPairScalar(float[] op1, int i) => (i == 0) ? op1[0] : (i == op1.Length / 2) ? op1[1] : (float)0; - - public static sbyte TableVectorExtension(int i, sbyte[] defaultValues, sbyte[] indices, params sbyte[][] table) - { - sbyte[] fullTable = table.SelectMany(x => x).ToArray(); - int index = indices[i]; - - if (index < 0 || index >= fullTable.Length) - return defaultValues[i]; - - return fullTable[index]; - } - - public static sbyte TableVectorLookup(int i, sbyte[] indices, params sbyte[][] table) - { - sbyte[] zeros = new sbyte[indices.Length]; - Array.Fill(zeros, 0, 0, indices.Length); - - return TableVectorExtension(i, zeros, indices, table); - } - - public static byte TableVectorExtension(int i, byte[] defaultValues, byte[] indices, params byte[][] table) - { - byte[] fullTable = table.SelectMany(x => x).ToArray(); - int index = indices[i]; - - if (index < 0 || index >= fullTable.Length) - return defaultValues[i]; - - return fullTable[index]; - } - - public static byte TableVectorLookup(int i, byte[] indices, params byte[][] table) - { - byte[] zeros = new byte[indices.Length]; - Array.Fill(zeros, 0, 0, indices.Length); - - return TableVectorExtension(i, zeros, indices, table); - } - - public static byte ShiftLeftAndInsert(byte left, byte right, byte shift) - { - byte mask = (byte)~(byte.MaxValue << shift); - byte value = (byte)(right << shift); - byte newval = (byte)(((byte)left & mask) | value); - return newval; - } - - public static byte ShiftRightAndInsert(byte left, byte right, byte shift) - { - byte mask = (byte)~(byte.MaxValue >> shift); - byte value = (byte)(right >> shift); - byte newval = (byte)(((byte)left & mask) | value); - return newval; - } - - public static short ShiftLeftAndInsert(short left, short right, byte shift) - { - ushort mask = (ushort)~(ushort.MaxValue << shift); - ushort value = (ushort)(right << shift); - short newval = (short)(((ushort)left & mask) | value); - return newval; - } - - public static short ShiftRightAndInsert(short left, short right, byte shift) - { - ushort mask = (ushort)~(ushort.MaxValue >> shift); - ushort value = (ushort)(right >> shift); - short newval = (short)(((ushort)left & mask) | value); - return newval; - } - - public static int ShiftLeftAndInsert(int left, int right, byte shift) - { - uint mask = (uint)~(uint.MaxValue << shift); - uint value = (uint)(right << shift); - int newval = (int)(((uint)left & mask) | value); - return newval; - } - - public static int ShiftRightAndInsert(int left, int right, byte shift) - { - uint mask = (uint)~(uint.MaxValue >> shift); - uint value = (uint)(right >> shift); - int newval = (int)(((uint)left & mask) | value); - return newval; - } - - public static long ShiftLeftAndInsert(long left, long right, byte shift) - { - ulong mask = (ulong)~(ulong.MaxValue << shift); - ulong value = (ulong)(right << shift); - long newval = (long)(((ulong)left & mask) | value); - return newval; - } - - public static long ShiftRightAndInsert(long left, long right, byte shift) - { - ulong mask = (ulong)~(ulong.MaxValue >> shift); - ulong value = (ulong)(right >> shift); - long newval = (long)(((ulong)left & mask) | value); - return newval; - } - - public static sbyte ShiftLeftAndInsert(sbyte left, sbyte right, byte shift) - { - byte mask = (byte)~(byte.MaxValue << shift); - byte value = (byte)(right << shift); - sbyte newval = (sbyte)(((byte)left & mask) | value); - return newval; - } - - public static sbyte ShiftRightAndInsert(sbyte left, sbyte right, byte shift) - { - byte mask = (byte)~(byte.MaxValue >> shift); - byte value = (byte)(right >> shift); - sbyte newval = (sbyte)(((byte)left & mask) | value); - return newval; - } - - public static ushort ShiftLeftAndInsert(ushort left, ushort right, byte shift) - { - ushort mask = (ushort)~(ushort.MaxValue << shift); - ushort value = (ushort)(right << shift); - ushort newval = (ushort)(((ushort)left & mask) | value); - return newval; - } - - public static ushort ShiftRightAndInsert(ushort left, ushort right, byte shift) - { - ushort mask = (ushort)~(ushort.MaxValue >> shift); - ushort value = (ushort)(right >> shift); - ushort newval = (ushort)(((ushort)left & mask) | value); - return newval; - } - - public static uint ShiftLeftAndInsert(uint left, uint right, byte shift) - { - uint mask = (uint)~(uint.MaxValue << shift); - uint value = (uint)(right << shift); - uint newval = (uint)(((uint)left & mask) | value); - return newval; - } - - public static uint ShiftRightAndInsert(uint left, uint right, byte shift) - { - uint mask = (uint)~(uint.MaxValue >> shift); - uint value = (uint)(right >> shift); - uint newval = (uint)(((uint)left & mask) | value); - return newval; - } - - public static ulong ShiftLeftAndInsert(ulong left, ulong right, byte shift) - { - ulong mask = (ulong)~(ulong.MaxValue << shift); - ulong value = (ulong)(right << shift); - ulong newval = (ulong)(((ulong)left & mask) | value); - return newval; - } - - public static ulong ShiftRightAndInsert(ulong left, ulong right, byte shift) - { - ulong mask = (ulong)~(ulong.MaxValue >> shift); - ulong value = (ulong)(right >> shift); - ulong newval = (ulong)(((ulong)left & mask) | value); - return newval; - } - - public static double Ceiling(double op1) => Math.Ceiling(op1); - - public static double Floor(double op1) => Math.Floor(op1); - - public static double RoundAwayFromZero(double op1) => Math.Round(op1, MidpointRounding.AwayFromZero); - - public static double RoundToNearest(double op1) => Math.Round(op1, MidpointRounding.ToEven); - - public static double RoundToNegativeInfinity(double op1) => Math.Round(op1, MidpointRounding.ToNegativeInfinity); - - public static double RoundToPositiveInfinity(double op1) => Math.Round(op1, MidpointRounding.ToPositiveInfinity); - - public static double RoundToZero(double op1) => Math.Round(op1, MidpointRounding.ToZero); - - public static float Ceiling(float op1) => MathF.Ceiling(op1); - - public static float Floor(float op1) => MathF.Floor(op1); - - public static float RoundAwayFromZero(float op1) => MathF.Round(op1, MidpointRounding.AwayFromZero); - - public static float RoundToNearest(float op1) => MathF.Round(op1, MidpointRounding.ToEven); - - public static float RoundToNegativeInfinity(float op1) => MathF.Round(op1, MidpointRounding.ToNegativeInfinity); - - public static float RoundToPositiveInfinity(float op1) => MathF.Round(op1, MidpointRounding.ToPositiveInfinity); - - public static float RoundToZero(float op1) => MathF.Round(op1, MidpointRounding.ToZero); - - private static int ConvertToInt32(double op1) => (int)Math.Clamp(op1, int.MinValue, int.MaxValue); - - public static int[] ConvertToInt32(double[] op1) - { - int[] result = new int[op1.Length * 2]; - - for (int i = 0; i < op1.Length; i++) - { - int index = i * 2; - result[index] = ConvertToInt32(op1[i]); - if (op1[i] < 0) - { - // Sign-extend next lane with all ones - result[index + 1] = -1; - } - } - - return result; - } - - public static int[] ConvertToInt32(float[] op1) => Array.ConvertAll(op1, num => ConvertToInt32(num)); - - private static long ConvertToInt64(double op1) => (long)Math.Clamp(op1, long.MinValue, long.MaxValue); - - public static long[] ConvertToInt64(double[] op1) => Array.ConvertAll(op1, num => ConvertToInt64(num)); - - public static long[] ConvertToInt64(float[] op1) - { - long[] result = new long[op1.Length / 2]; - - for (int i = 0; i < result.Length; i++) - { - result[i] = ConvertToInt64(op1[i * 2]); - } - - return result; - } - - private static uint ConvertToUInt32(double op1) => (uint)Math.Clamp(op1, uint.MinValue, uint.MaxValue); - - public static uint[] ConvertToUInt32(double[] op1) - { - uint[] result = new uint[op1.Length * 2]; - - for (int i = 0; i < op1.Length; i++) - { - result[i * 2] = ConvertToUInt32(op1[i]); - } - - return result; - } - - public static uint[] ConvertToUInt32(float[] op1) => Array.ConvertAll(op1, num => ConvertToUInt32(num)); - - private static ulong ConvertToUInt64(double op1) => (ulong)Math.Clamp(op1, ulong.MinValue, ulong.MaxValue); - - public static ulong[] ConvertToUInt64(double[] op1) => Array.ConvertAll(op1, num => ConvertToUInt64(num)); - - public static ulong[] ConvertToUInt64(float[] op1) - { - ulong[] result = new ulong[op1.Length / 2]; - - for (int i = 0; i < result.Length; i++) - { - result[i] = ConvertToUInt64(op1[i * 2]); - } - - return result; - } - - public static Int32 ConvertToInt32RoundAwayFromZero(float op1) => ConvertToInt32(RoundAwayFromZero(op1)); - - public static Int32 ConvertToInt32RoundToEven(float op1) => ConvertToInt32(RoundToNearest(op1)); - - public static Int32 ConvertToInt32RoundToNegativeInfinity(float op1) => ConvertToInt32(RoundToNegativeInfinity(op1)); - - public static Int32 ConvertToInt32RoundToPositiveInfinity(float op1) => ConvertToInt32(RoundToPositiveInfinity(op1)); - - public static Int32 ConvertToInt32RoundToZero(float op1) => ConvertToInt32(RoundToZero(op1)); - - public static Int64 ConvertToInt64RoundAwayFromZero(double op1) => ConvertToInt64(RoundAwayFromZero(op1)); - - public static Int64 ConvertToInt64RoundToEven(double op1) => ConvertToInt64(RoundToNearest(op1)); - - public static Int64 ConvertToInt64RoundToNegativeInfinity(double op1) => ConvertToInt64(RoundToNegativeInfinity(op1)); - - public static Int64 ConvertToInt64RoundToPositiveInfinity(double op1) => ConvertToInt64(RoundToPositiveInfinity(op1)); - - public static Int64 ConvertToInt64RoundToZero(double op1) => ConvertToInt64(RoundToZero(op1)); - - public static UInt32 ConvertToUInt32RoundAwayFromZero(float op1) => ConvertToUInt32(RoundAwayFromZero(op1)); - - public static UInt32 ConvertToUInt32RoundToEven(float op1) => ConvertToUInt32(RoundToNearest(op1)); - - public static UInt32 ConvertToUInt32RoundToNegativeInfinity(float op1) => ConvertToUInt32(RoundToNegativeInfinity(op1)); - - public static UInt32 ConvertToUInt32RoundToPositiveInfinity(float op1) => ConvertToUInt32(RoundToPositiveInfinity(op1)); - - public static UInt32 ConvertToUInt32RoundToZero(float op1) => ConvertToUInt32(RoundToZero(op1)); - - public static UInt64 ConvertToUInt64RoundAwayFromZero(double op1) => ConvertToUInt64(RoundAwayFromZero(op1)); - - public static UInt64 ConvertToUInt64RoundToEven(double op1) => ConvertToUInt64(RoundToNearest(op1)); - - public static UInt64 ConvertToUInt64RoundToNegativeInfinity(double op1) => ConvertToUInt64(RoundToNegativeInfinity(op1)); - - public static UInt64 ConvertToUInt64RoundToPositiveInfinity(double op1) => ConvertToUInt64(RoundToPositiveInfinity(op1)); - - public static UInt64 ConvertToUInt64RoundToZero(double op1) => ConvertToUInt64(RoundToZero(op1)); - - public static float ConvertToSingle(int op1) => op1; - - public static float ConvertToSingle(uint op1) => op1; - - public static float ConvertToSingle(double op1) => (float)op1; - - public static float[] ConvertToSingle(double[] op1) - { - float[] result = new float[op1.Length * 2]; - - for (int i = 0; i < op1.Length; i++) - { - result[i * 2] = (float)op1[i]; - } - - return result; - } - - public static float[] ConvertToSingle(int[] op1) => Array.ConvertAll(op1, num => (float)num); - - public static float[] ConvertToSingle(long[] op1) - { - float[] result = new float[op1.Length * 2]; - - for (int i = 0; i < op1.Length; i++) - { - result[i * 2] = (float)op1[i]; - } - - return result; - } - - public static float[] ConvertToSingle(uint[] op1) => Array.ConvertAll(op1, num => (float)num); - - public static float[] ConvertToSingle(ulong[] op1) - { - float[] result = new float[op1.Length * 2]; - - for (int i = 0; i < op1.Length; i++) - { - result[i * 2] = (float)op1[i]; - } - - return result; - } - - public static float ConvertToSingleUpper(float[] op1, double[] op2, int i) => i < op1.Length ? op1[i] : ConvertToSingle(op2[i - op1.Length]); - - public static double ConvertToDouble(float op1) => op1; - - public static double ConvertToDouble(long op1) => op1; - - public static double ConvertToDouble(ulong op1) => op1; - - public static double[] ConvertToDouble(float[] op1) - { - double[] result = new double[op1.Length / 2]; - - for (int i = 0; i < result.Length; i++) - { - result[i] = op1[i * 2]; - } - - return result; - } - - public static double[] ConvertToDouble(int[] op1) - { - double[] result = new double[op1.Length / 2]; - - for (int i = 0; i < result.Length; i++) - { - result[i] = op1[i * 2]; - } - - return result; - } - - public static double[] ConvertToDouble(long[] op1) => Array.ConvertAll(op1, num => (double)num); - - public static double[] ConvertToDouble(uint[] op1) - { - double[] result = new double[op1.Length / 2]; - - for (int i = 0; i < result.Length; i++) - { - result[i] = op1[i * 2]; - } - - return result; - } - - public static double[] ConvertToDouble(ulong[] op1) => Array.ConvertAll(op1, num => (double)num); - - public static double ConvertToDoubleUpper(float[] op1, int i) => ConvertToDouble(op1[i + op1.Length / 2]); - - public static short ReverseElement8(short val) - { - ulong result = 0UL; - - int numberOfElements = (8 * sizeof(short)) / 8; - ulong elementMask = ((1UL << 8) - 1); - - for (int i = 0; i < numberOfElements; i++) - { - ulong element = ((ulong)val >> (8 * i)) & elementMask; - ulong reversedElement = element << (8 * (numberOfElements - 1 - i)); - result |= reversedElement; - } - - return (short)result; - } - - public static ushort ReverseElement8(ushort val) - { - ulong result = 0UL; - - int numberOfElements = (8 * sizeof(ushort)) / 8; - ulong elementMask = ((1UL << 8) - 1); - - for (int i = 0; i < numberOfElements; i++) - { - ulong element = ((ulong)val >> (8 * i)) & elementMask; - ulong reversedElement = element << (8 * (numberOfElements - 1 - i)); - result |= reversedElement; - } - - return (ushort)result; - } - - public static int ReverseElement8(int val) - { - ulong result = 0UL; - - int numberOfElements = (8 * sizeof(int)) / 8; - ulong elementMask = ((1UL << 8) - 1); - - for (int i = 0; i < numberOfElements; i++) - { - ulong element = ((ulong)val >> (8 * i)) & elementMask; - ulong reversedElement = element << (8 * (numberOfElements - 1 - i)); - result |= reversedElement; - } - - return (int)result; - } - - public static uint ReverseElement8(uint val) - { - ulong result = 0UL; - - int numberOfElements = (8 * sizeof(uint)) / 8; - ulong elementMask = ((1UL << 8) - 1); - - for (int i = 0; i < numberOfElements; i++) - { - ulong element = ((ulong)val >> (8 * i)) & elementMask; - ulong reversedElement = element << (8 * (numberOfElements - 1 - i)); - result |= reversedElement; - } - - return (uint)result; - } - - public static long ReverseElement8(long val) - { - ulong result = 0UL; - - int numberOfElements = (8 * sizeof(long)) / 8; - ulong elementMask = ((1UL << 8) - 1); - - for (int i = 0; i < numberOfElements; i++) - { - ulong element = ((ulong)val >> (8 * i)) & elementMask; - ulong reversedElement = element << (8 * (numberOfElements - 1 - i)); - result |= reversedElement; - } - - return (long)result; - } - - public static ulong ReverseElement8(ulong val) - { - ulong result = 0UL; - - int numberOfElements = (8 * sizeof(ulong)) / 8; - ulong elementMask = ((1UL << 8) - 1); - - for (int i = 0; i < numberOfElements; i++) - { - ulong element = ((ulong)val >> (8 * i)) & elementMask; - ulong reversedElement = element << (8 * (numberOfElements - 1 - i)); - result |= reversedElement; - } - - return (ulong)result; - } - - public static int ReverseElement16(int val) - { - ulong result = 0UL; - - int numberOfElements = (8 * sizeof(int)) / 16; - ulong elementMask = ((1UL << 16) - 1); - - for (int i = 0; i < numberOfElements; i++) - { - ulong element = ((ulong)val >> (16 * i)) & elementMask; - ulong reversedElement = element << (16 * (numberOfElements - 1 - i)); - result |= reversedElement; - } - - return (int)result; - } - - public static uint ReverseElement16(uint val) - { - ulong result = 0UL; - - int numberOfElements = (8 * sizeof(uint)) / 16; - ulong elementMask = ((1UL << 16) - 1); - - for (int i = 0; i < numberOfElements; i++) - { - ulong element = ((ulong)val >> (16 * i)) & elementMask; - ulong reversedElement = element << (16 * (numberOfElements - 1 - i)); - result |= reversedElement; - } - - return (uint)result; - } - - public static long ReverseElement16(long val) - { - ulong result = 0UL; - - int numberOfElements = (8 * sizeof(long)) / 16; - ulong elementMask = ((1UL << 16) - 1); - - for (int i = 0; i < numberOfElements; i++) - { - ulong element = ((ulong)val >> (16 * i)) & elementMask; - ulong reversedElement = element << (16 * (numberOfElements - 1 - i)); - result |= reversedElement; - } - - return (long)result; - } - - public static ulong ReverseElement16(ulong val) - { - ulong result = 0UL; - - int numberOfElements = (8 * sizeof(ulong)) / 16; - ulong elementMask = ((1UL << 16) - 1); - - for (int i = 0; i < numberOfElements; i++) - { - ulong element = ((ulong)val >> (16 * i)) & elementMask; - ulong reversedElement = element << (16 * (numberOfElements - 1 - i)); - result |= reversedElement; - } - - return (ulong)result; - } - - public static long ReverseElement32(long val) - { - ulong result = 0UL; - - int numberOfElements = (8 * sizeof(long)) / 32; - ulong elementMask = ((1UL << 32) - 1); - - for (int i = 0; i < numberOfElements; i++) - { - ulong element = ((ulong)val >> (32 * i)) & elementMask; - ulong reversedElement = element << (32 * (numberOfElements - 1 - i)); - result |= reversedElement; - } - - return (long)result; - } - - public static ulong ReverseElement32(ulong val) - { - ulong result = 0UL; - - int numberOfElements = (8 * sizeof(ulong)) / 32; - ulong elementMask = ((1UL << 32) - 1); - - for (int i = 0; i < numberOfElements; i++) - { - ulong element = ((ulong)val >> (32 * i)) & elementMask; - ulong reversedElement = element << (32 * (numberOfElements - 1 - i)); - result |= reversedElement; - } - - return (ulong)result; - } - - public static uint DotProduct(uint op1, byte[] op2, int s, byte[] op3, int t) - { - uint result = op1; - - for (int i = 0; i < 4; i++) - { - result += (uint)((uint)op2[s + i] * (uint)op3[t + i]); - } - - return result; - } - - public static int DotProduct(int op1, sbyte[] op2, int s, sbyte[] op3, int t) - { - int result = op1; - - for (int i = 0; i < 4; i++) - { - result += (int)((int)op2[s + i] * (int)op3[t + i]); - } - - return result; - } - - public static ulong DotProduct(ulong op1, ushort[] op2, int s, ushort[] op3, int t) - { - ulong result = op1; - - for (int i = 0; i < 4; i++) - { - result += (ulong)((ulong)op2[s + i] * (ulong)op3[t + i]); - } - - return result; - } - - public static long DotProduct(long op1, short[] op2, int s, short[] op3, int t) - { - long result = op1; - - for (int i = 0; i < 4; i++) - { - result += (long)((long)op2[s + i] * (long)op3[t + i]); - } - - return result; - } - - public static int WhileLessThanMask(int op1, int op2) - { - return (op1 < op2) ? 1 : 0; - } - - public static uint WhileLessThanMask(uint op1, uint op2) - { - return (uint)((op1 < op2) ? 1 : 0); - } - - public static long WhileLessThanMask(long op1, long op2) - { - return (op1 < op2) ? 1 : 0; - } - - public static ulong WhileLessThanMask(ulong op1, ulong op2) - { - return (ulong)((op1 < op2) ? 1 : 0); - } - - public static int WhileLessThanOrEqualMask(int op1, int op2) - { - return (op1 <= op2) ? 1 : 0; - } - - public static uint WhileLessThanOrEqualMask(uint op1, uint op2) - { - return (uint)((op1 <= op2) ? 1 : 0); - } - - public static long WhileLessThanOrEqualMask(long op1, long op2) - { - return (op1 <= op2) ? 1 : 0; - } - - public static ulong WhileLessThanOrEqualMask(ulong op1, ulong op2) - { - return (ulong)((op1 <= op2) ? 1 : 0); - } - - public static ulong MaskBothSet(byte[] op1, byte[] op2) - { - ulong acc = 0; - for (var i = 0; i < op1.Length; i++) - { - acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); - } - return acc; - } - - public static ulong MaskBothSet(sbyte[] op1, sbyte[] op2) - { - ulong acc = 0; - for (var i = 0; i < op1.Length; i++) - { - acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); - } - return acc; - } - - public static ulong MaskBothSet(short[] op1, short[] op2) - { - ulong acc = 0; - for (var i = 0; i < op1.Length; i++) - { - acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); - } - return acc; - } - - public static ulong MaskBothSet(ushort[] op1, ushort[] op2) - { - ulong acc = 0; - for (var i = 0; i < op1.Length; i++) - { - acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); - } - return acc; - } - - public static ulong MaskBothSet(int[] op1, int[] op2) - { - ulong acc = 0; - for (var i = 0; i < op1.Length; i++) - { - acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); - } - return acc; - } - - public static ulong MaskBothSet(uint[] op1, uint[] op2) - { - ulong acc = 0; - for (var i = 0; i < op1.Length; i++) - { - acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); - } - return acc; - } - - public static ulong MaskBothSet(long[] op1, long[] op2) - { - ulong acc = 0; - for (var i = 0; i < op1.Length; i++) - { - acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); - } - return acc; - } - - public static ulong MaskBothSet(ulong[] op1, ulong[] op2) - { - ulong acc = 0; - for (var i = 0; i < op1.Length; i++) - { - acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); - } - return acc; - } - - public static ulong MaskBothSet(float[] op1, float[] op2) - { - ulong acc = 0; - for (var i = 0; i < op1.Length; i++) - { - acc += (ulong)((op1[i] == 1) && (op2[i] == 1) ? 1 : 0); - } - return acc; - } - - public static ulong MaskBothSet(double[] op1, double[] op2) - { - ulong acc = 0; - for (var i = 0; i < op1.Length; i++) - { - acc += (ulong)((op1[i] == 1) && (op2[i] == 1) ? 1 : 0); - } - return acc; - } - - public static byte getMaskByte() - { - return (byte)(TestLibrary.Generator.GetByte() % 2); - } - - public static sbyte getMaskSByte() - { - return (sbyte)(TestLibrary.Generator.GetByte() % 2); - } - - public static short getMaskInt16() - { - return (short)(TestLibrary.Generator.GetUInt16() % 2); - } - - public static ushort getMaskUInt16() - { - return (ushort)(TestLibrary.Generator.GetUInt16() % 2); - } - - public static int getMaskInt32() - { - return (int)(TestLibrary.Generator.GetUInt32() % 2); - } - - public static uint getMaskUInt32() - { - return (uint)(TestLibrary.Generator.GetUInt32() % 2); - } - - public static long getMaskInt64() - { - return (long)(TestLibrary.Generator.GetUInt64() % 2); - } - - public static ulong getMaskUInt64() - { - return (ulong)(TestLibrary.Generator.GetUInt64() % 2); - } - - public static float getMaskSingle() - { - return (float)(TestLibrary.Generator.GetUInt32() % 2); - } - - public static double getMaskDouble() - { - return (double)(TestLibrary.Generator.GetUInt64() % 2); - } - - public static int MaskNumberOfElementsVector(int elems, SveMaskPattern pattern) - { - - switch (pattern) - { - // Returns elems, as this is always a power of 2. - case SveMaskPattern.LargestPowerOf2: - return elems; - - // Returns N if N elements can fit in the vector. Otherwise 0. - case SveMaskPattern.VectorCount1: - return elems >= 1 ? 1 : 0; - case SveMaskPattern.VectorCount2: - return elems >= 2 ? 2 : 0; - case SveMaskPattern.VectorCount3: - return elems >= 3 ? 3 : 0; - case SveMaskPattern.VectorCount4: - return elems >= 4 ? 4 : 0; - case SveMaskPattern.VectorCount5: - return elems >= 5 ? 5 : 0; - case SveMaskPattern.VectorCount6: - return elems >= 6 ? 6 : 0; - case SveMaskPattern.VectorCount7: - return elems >= 7 ? 7 : 0; - case SveMaskPattern.VectorCount8: - return elems >= 8 ? 8 : 0; - case SveMaskPattern.VectorCount16: - return elems >= 16 ? 16 : 0; - case SveMaskPattern.VectorCount32: - return elems >= 32 ? 32 : 0; - case SveMaskPattern.VectorCount64: - return elems >= 64 ? 64 : 0; - case SveMaskPattern.VectorCount128: - return elems >= 128 ? 128 : 0; - case SveMaskPattern.VectorCount256: - return elems >= 256 ? 256 : 0; - - // Number of elems rounded down to nearest multiple of 4 - case SveMaskPattern.LargestMultipleOf4: - return elems - (elems % 4); - - // Number of elems rounded down to nearest multiple of 3 - case SveMaskPattern.LargestMultipleOf3: - return elems - (elems % 3); - - case SveMaskPattern.All: - default: - return elems; - } - } - - public static int NumberOfElementsInVectorInt8(SveMaskPattern pattern) - { - return MaskNumberOfElementsVector(Unsafe.SizeOf>() / sizeof(byte), pattern); - } - - public static int NumberOfElementsInVectorInt16(SveMaskPattern pattern) - { - return MaskNumberOfElementsVector(Unsafe.SizeOf>() / sizeof(short), pattern); - } - - public static int NumberOfElementsInVectorInt32(SveMaskPattern pattern) - { - return MaskNumberOfElementsVector(Unsafe.SizeOf>() / sizeof(int), pattern); - } - - public static int NumberOfElementsInVectorInt64(SveMaskPattern pattern) - { - return MaskNumberOfElementsVector(Unsafe.SizeOf>() / sizeof(long), pattern); - } - - public static int NumberOfActiveElementsInMask(sbyte[] mask) - { - int acc = 0; - for (var i = 0; i < mask.Length; i++) - { - acc += (mask[i] == 1) ? 1 : 0; - } - return acc; - } - - public static int NumberOfActiveElementsInMask(short[] mask) - { - int acc = 0; - for (var i = 0; i < mask.Length; i++) - { - acc += (mask[i] == 1) ? 1 : 0; - } - return acc; - } - - public static int NumberOfActiveElementsInMask(int[] mask) - { - int acc = 0; - for (var i = 0; i < mask.Length; i++) - { - acc += (mask[i] == 1) ? 1 : 0; - } - return acc; - } - - public static int NumberOfActiveElementsInMask(long[] mask) - { - int acc = 0; - for (var i = 0; i < mask.Length; i++) - { - acc += (mask[i] == 1) ? 1 : 0; - } - return acc; - } - - public static int NumberOfActiveElementsInMask(byte[] mask) - { - int acc = 0; - for (var i = 0; i < mask.Length; i++) - { - acc += (mask[i] == 1) ? 1 : 0; - } - return acc; - } - - public static int NumberOfActiveElementsInMask(ushort[] mask) - { - int acc = 0; - for (var i = 0; i < mask.Length; i++) - { - acc += (mask[i] == 1) ? 1 : 0; - } - return acc; - } - - public static int NumberOfActiveElementsInMask(uint[] mask) - { - int acc = 0; - for (var i = 0; i < mask.Length; i++) - { - acc += (mask[i] == 1) ? 1 : 0; - } - return acc; - } - - public static int NumberOfActiveElementsInMask(ulong[] mask) - { - int acc = 0; - for (var i = 0; i < mask.Length; i++) - { - acc += (mask[i] == 1) ? 1 : 0; - } - return acc; - } - - public static double[] Compact(double[] op1, double[] op2) - { - double[] result = new double[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - - int i = 0; - for (int j = 0; j < op1.Length; j++) - { - if (op1[j] != 0) - { - result[i++] = op2[j]; - } - } - - return result; - } - - public static int[] Compact(int[] op1, int[] op2) - { - int[] result = new int[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - - int i = 0; - for (int j = 0; j < op1.Length; j++) - { - if (op1[j] != 0) - { - result[i++] = op2[j]; - } - } - - return result; - } - - public static long[] Compact(long[] op1, long[] op2) - { - long[] result = new long[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - - long i = 0; - for (int j = 0; j < op1.Length; j++) - { - if (op1[j] != 0) - { - result[i++] = op2[j]; - } - } - - return result; - } - - public static float[] Compact(float[] op1, float[] op2) - { - float[] result = new float[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - - int i = 0; - for (int j = 0; j < op1.Length; j++) - { - if (op1[j] != 0) - { - result[i++] = op2[j]; - } - } - - return result; - } - - public static uint[] Compact(uint[] op1, uint[] op2) - { - uint[] result = new uint[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - - int i = 0; - for (int j = 0; j < op1.Length; j++) - { - if (op1[j] != 0) - { - result[i++] = op2[j]; - } - } - - return result; - } - - public static ulong[] Compact(ulong[] op1, ulong[] op2) - { - ulong[] result = new ulong[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - - ulong i = 0; - for (int j = 0; j < op1.Length; j++) - { - if (op1[j] != 0) - { - result[i++] = op2[j]; - } - } - - return result; - } - - public static int LoadInt16FromByteArray(byte[] array, int offset) - { - int ret = 0; - for (int i = 1; i >= 0; i--) - { - ret = (ret << 8) + (int)array[offset + i]; - } - return ret; - } - - public static int LoadInt16FromByteArray(byte[] array, uint offset) - { - int ret = 0; - for (int i = 1; i >= 0; i--) - { - ret = (ret << 8) + (int)array[offset + i]; - } - return ret; - } - public static int LoadInt32FromByteArray(byte[] array, int offset) - { - int ret = 0; - for (int i = 3; i >= 0; i--) - { - ret = (ret << 8) + (int)array[offset + i]; - } - return ret; - } - - public static int LoadInt32FromByteArray(byte[] array, uint offset) - { - int ret = 0; - for (int i = 3; i >= 0; i--) - { - ret = (ret << 8) + (int)array[offset + i]; - } - return ret; - } - - public static long LoadInt64FromByteArray(byte[] array, long offset) - { - long ret = 0; - for (long i = 7; i >= 0; i--) - { - ret = (ret << 8) + (long)array[offset + i]; - } - return ret; - } - - public static long LoadInt64FromByteArray(byte[] array, ulong offset) - { - long ret = 0; - for (long i = 7; i >= 0; i--) - { - ret = (ret << 8) + (long)array[offset + (ulong)i]; - } - return ret; - } - - public static uint LoadUInt16FromByteArray(byte[] array, int offset) - { - uint ret = 0; - for (int i = 1; i >= 0; i--) - { - ret = (ret << 8) + (uint)array[offset + i]; - } - return ret; - } - - public static uint LoadUInt16FromByteArray(byte[] array, uint offset) - { - uint ret = 0; - for (int i = 1; i >= 0; i--) - { - ret = (ret << 8) + (uint)array[offset + i]; - } - return ret; - } - - public static uint LoadUInt32FromByteArray(byte[] array, int offset) - { - uint ret = 0; - for (int i = 3; i >= 0; i--) - { - ret = (ret << 8) + (uint)array[offset + i]; - } - return ret; - } - - public static uint LoadUInt32FromByteArray(byte[] array, uint offset) - { - uint ret = 0; - for (int i = 3; i >= 0; i--) - { - ret = (ret << 8) + (uint)array[offset + i]; - } - return ret; - } - - public static ulong LoadUInt64FromByteArray(byte[] array, long offset) - { - ulong ret = 0; - for (long i = 7; i >= 0; i--) - { - ret = (ret << 8) + (ulong)array[offset + i]; - } - return ret; - } - - public static ulong LoadUInt64FromByteArray(byte[] array, ulong offset) - { - ulong ret = 0; - for (long i = 7; i >= 0; i--) - { - ret = (ret << 8) + (ulong)array[offset + (ulong)i]; - } - return ret; - } - - public static float LoadSingleFromByteArray(byte[] array, int offset) - { - int ret = 0; - for (int i = 3; i >= 0; i--) - { - ret = (ret << 8) + (int)array[offset + i]; - } - return BitConverter.Int32BitsToSingle(ret); - } - - public static float LoadSingleFromByteArray(byte[] array, uint offset) - { - int ret = 0; - for (int i = 3; i >= 0; i--) - { - ret = (ret << 8) + (int)array[offset + i]; - } - return BitConverter.Int32BitsToSingle(ret); - } - - public static double LoadDoubleFromByteArray(byte[] array, long offset) - { - long ret = 0; - for (long i = 7; i >= 0; i--) - { - ret = (ret << 8) + (long)array[offset + i]; - } - return BitConverter.Int64BitsToDouble(ret); - } - - public static double LoadDoubleFromByteArray(byte[] array, ulong offset) - { - long ret = 0; - for (long i = 7; i >= 0; i--) - { - ret = (ret << 8) + (long)array[offset + (ulong)i]; - } - return BitConverter.Int64BitsToDouble(ret); - } - - public static Byte Splice(Byte[] first, Byte[] second, Byte[] maskArray, Int32 index) - { - int start = -1; - int end = -1; - - for (var i = 0; i < maskArray.Length; i++) - { - if (maskArray[i] != 0) - { - if (start == -1) - { - start = i; - } - end = i; - } - } - - if (start == -1) - { - return second[index]; - } - - var rangeSize = end - start + 1; - return (index < rangeSize) ? first[start + index] : second[index - rangeSize]; - } - - public static double Splice(double[] first, double[] second, double[] maskArray, Int32 index) - { - int start = -1; - int end = -1; - - for (var i = 0; i < maskArray.Length; i++) - { - if (Double.IsNaN(maskArray[i]) || maskArray[i] > 0.0d) - { - if (start == -1) - { - start = i; - } - end = i; - } - } - - if (start == -1) - { - return second[index]; - } - - var rangeSize = end - start + 1; - return (index < rangeSize) ? first[start + index] : second[index - rangeSize]; - } - - public static float Splice(float[] first, float[] second, float[] maskArray, Int32 index) - { - int start = -1; - int end = -1; - - for (var i = 0; i < maskArray.Length; i++) - { - if (maskArray[i] != 0.0f) - { - if (start == -1) - { - start = i; - } - end = i; - } - } - - if (start == -1) - { - return second[index]; - } - - var rangeSize = end - start + 1; - return (index < rangeSize) ? first[start + index] : second[index - rangeSize]; - } - - public static Int16 Splice(Int16[] first, Int16[] second, Int16[] maskArray, Int32 index) - { - int start = -1; - int end = -1; - - for (var i = 0; i < maskArray.Length; i++) - { - if (maskArray[i] != 0) - { - if (start == -1) - { - start = i; - } - end = i; - } - } - - if (start == -1) - { - return second[index]; - } - - var rangeSize = end - start + 1; - return (index < rangeSize) ? first[start + index] : second[index - rangeSize]; - } - - public static Int32 Splice(Int32[] first, Int32[] second, Int32[] maskArray, Int32 index) - { - int start = -1; - int end = -1; - - for (var i = 0; i < maskArray.Length; i++) - { - if (maskArray[i] != 0) - { - if (start == -1) - { - start = i; - } - end = i; - } - } - - if (start == -1) - { - return second[index]; - } - - var rangeSize = end - start + 1; - return (index < rangeSize) ? first[start + index] : second[index - rangeSize]; - } - - public static Int64 Splice(Int64[] first, Int64[] second, Int64[] maskArray, Int32 index) - { - int start = -1; - int end = -1; - - for (var i = 0; i < maskArray.Length; i++) - { - if (maskArray[i] != 0) - { - if (start == -1) - { - start = i; - } - end = i; - } - } - - if (start == -1) - { - return second[index]; - } - - var rangeSize = end - start + 1; - return (index < rangeSize) ? first[start + index] : second[index - rangeSize]; - } - - public static SByte Splice(SByte[] first, SByte[] second, SByte[] maskArray, Int32 index) - { - int start = -1; - int end = -1; - - for (var i = 0; i < maskArray.Length; i++) - { - if (maskArray[i] != 0) - { - if (start == -1) - { - start = i; - } - end = i; - } - } - - if (start == -1) - { - return second[index]; - } - - var rangeSize = end - start + 1; - return (index < rangeSize) ? first[start + index] : second[index - rangeSize]; - } - - public static UInt16 Splice(UInt16[] first, UInt16[] second, UInt16[] maskArray, Int32 index) - { - int start = -1; - int end = -1; - - for (var i = 0; i < maskArray.Length; i++) - { - if (maskArray[i] != 0) - { - if (start == -1) - { - start = i; - } - end = i; - } - } - - if (start == -1) - { - return second[index]; - } - - var rangeSize = end - start + 1; - return (index < rangeSize) ? first[start + index] : second[index - rangeSize]; - } - - public static UInt32 Splice(UInt32[] first, UInt32[] second, UInt32[] maskArray, Int32 index) - { - int start = -1; - int end = -1; - - for (var i = 0; i < maskArray.Length; i++) - { - if (maskArray[i] != 0) - { - if (start == -1) - { - start = i; - } - end = i; - } - } - - if (start == -1) - { - return second[index]; - } - - var rangeSize = end - start + 1; - return (index < rangeSize) ? first[start + index] : second[index - rangeSize]; - } - - public static ulong Splice(ulong[] first, ulong[] second, ulong[] maskArray, int index) - { - int start = -1; - int end = -1; - - for (var i = 0; i < maskArray.Length; i++) - { - if (maskArray[i] != 0) - { - if (start == -1) - { - start = i; - } - end = i; - } - } - - if (start == -1) - { - return second[index]; - } - - var rangeSize = end - start + 1; - return (index < rangeSize) ? first[start + index] : second[index - rangeSize]; - } - - public static T LastActive(T[] mask, T[] x) where T : IBinaryInteger - { - for (var i = mask.Length - 1; i >= 0; i--) - { - if (mask[i] != T.Zero) - { - return x[i]; - } - } - return T.Zero; - } - - public static T[] CreateBreakAfterMask(T[] mask, T[] op) where T : IBinaryInteger - { - var count = mask.Length; - var result = new T[count]; - var isBreakSet = false; - for (var i = 0; i < count; i++) - { - var isElementActive = op[i] != T.Zero; - if (mask[i] != T.Zero) - { - if (isBreakSet) - { - result[i] = T.Zero; - } - else - { - result[i] = T.One; - } - isBreakSet = isBreakSet || isElementActive; - } - else - { - result[i] = T.Zero; - } - } - return result; - } - - public static T[] CreateBreakAfterPropagateMask(T[] mask, T[] op1, T[] op2) where T : IBinaryInteger - { - var count = mask.Length; - var result = new T[count]; - var isLastActive = LastActive(mask, op1) != T.Zero; - for (var i = 0; i < count; i++) - { - if (mask[i] != T.Zero) - { - if (isLastActive) - { - result[i] = T.One; - } - else - { - result[i] = T.Zero; - } - isLastActive = isLastActive && (op2[i] == T.Zero); - } - else - { - result[i] = T.Zero; - } - } - return result; - } - - public static T[] CreateBreakBeforeMask(T[] mask, T[] op) where T : IBinaryInteger - { - var count = mask.Length; - var result = new T[count]; - var isBreakSet = false; - for (var i = 0; i < count; i++) - { - var isElementActive = op[i] != T.Zero; - if (mask[i] != T.Zero) - { - isBreakSet = isBreakSet || isElementActive; - if (isBreakSet) - { - result[i] = T.Zero; - } - else - { - result[i] = T.One; - } - } - else - { - result[i] = T.Zero; - } - } - return result; - } - - public static T[] CreateBreakBeforePropagateMask(T[] mask, T[] op1, T[] op2) where T : IBinaryInteger - { - var count = mask.Length; - var result = new T[count]; - var isLastActive = LastActive(mask, op1) != T.Zero; - for (var i = 0; i < count; i++) - { - if (mask[i] != T.Zero) - { - isLastActive = isLastActive && (op2[i] == T.Zero); - if (isLastActive) - { - result[i] = T.One; - } - else - { - result[i] = T.Zero; - } - } - else - { - result[i] = T.Zero; - } - } - return result; + ushort mask = (ushort)~(ushort.MaxValue << shift); + ushort value = (ushort)(right << shift); + ushort newval = (ushort)(((ushort)left & mask) | value); + return newval; } - private static T ConditionalSelectResult(T maskResult, T result, T falseResult) where T : INumberBase + public static ushort ShiftRightAndInsert(ushort left, ushort right, byte shift) { - return (maskResult != T.Zero) ? result : falseResult; + ushort mask = (ushort)~(ushort.MaxValue >> shift); + ushort value = (ushort)(right >> shift); + ushort newval = (ushort)(((ushort)left & mask) | value); + return newval; } - private static T ConditionalSelectTrueResult(T maskResult, T result, T trueResult) where T : INumberBase + public static uint ShiftLeftAndInsert(uint left, uint right, byte shift) { - return (maskResult != T.Zero) ? trueResult : result; + uint mask = (uint)~(uint.MaxValue << shift); + uint value = (uint)(right << shift); + uint newval = (uint)(((uint)left & mask) | value); + return newval; } - - private static TElem GetLoadVectorExpectedResultByIndex(int index, TElem[] mask, TMem[] data, TElem[] result) - where TMem : INumberBase - where TElem : INumberBase + public static uint ShiftRightAndInsert(uint left, uint right, byte shift) { - return (mask[index] == TElem.Zero) ? TElem.Zero : TElem.CreateTruncating(data[index]); + uint mask = (uint)~(uint.MaxValue >> shift); + uint value = (uint)(right >> shift); + uint newval = (uint)(((uint)left & mask) | value); + return newval; } - private static TElem GetLoadVectorExpectedResultByIndex(int index, TMem[] data, TElem[] result) - where TMem : INumberBase - where TElem : INumberBase + public static ulong ShiftLeftAndInsert(ulong left, ulong right, byte shift) { - TElem[] mask = new TElem[result.Length]; - Array.Fill(mask, TElem.One); + ulong mask = (ulong)~(ulong.MaxValue << shift); + ulong value = (ulong)(right << shift); + ulong newval = (ulong)(((ulong)left & mask) | value); + return newval; + } - return GetLoadVectorExpectedResultByIndex(index, mask, data, result); + public static ulong ShiftRightAndInsert(ulong left, ulong right, byte shift) + { + ulong mask = (ulong)~(ulong.MaxValue >> shift); + ulong value = (ulong)(right >> shift); + ulong newval = (ulong)(((ulong)left & mask) | value); + return newval; } - private static bool CheckLoadVectorBehaviorCore(TElem[] mask, TMem[] data, TElem[] result, Func map) - where TMem : INumberBase - where TElem : INumberBase + public static double Ceiling(double op1) => Math.Ceiling(op1); + + public static double Floor(double op1) => Math.Floor(op1); + + public static double RoundAwayFromZero(double op1) => Math.Round(op1, MidpointRounding.AwayFromZero); + + public static double RoundToNearest(double op1) => Math.Round(op1, MidpointRounding.ToEven); + + public static double RoundToNegativeInfinity(double op1) => Math.Round(op1, MidpointRounding.ToNegativeInfinity); + + public static double RoundToPositiveInfinity(double op1) => Math.Round(op1, MidpointRounding.ToPositiveInfinity); + + public static double RoundToZero(double op1) => Math.Round(op1, MidpointRounding.ToZero); + + public static float Ceiling(float op1) => MathF.Ceiling(op1); + + public static float Floor(float op1) => MathF.Floor(op1); + + public static float RoundAwayFromZero(float op1) => MathF.Round(op1, MidpointRounding.AwayFromZero); + + public static float RoundToNearest(float op1) => MathF.Round(op1, MidpointRounding.ToEven); + + public static float RoundToNegativeInfinity(float op1) => MathF.Round(op1, MidpointRounding.ToNegativeInfinity); + + public static float RoundToPositiveInfinity(float op1) => MathF.Round(op1, MidpointRounding.ToPositiveInfinity); + + public static float RoundToZero(float op1) => MathF.Round(op1, MidpointRounding.ToZero); + + private static int ConvertToInt32(double op1) => (int)Math.Clamp(op1, int.MinValue, int.MaxValue); + + public static int[] ConvertToInt32(double[] op1) { - for (var i = 0; i < data.Length; i++) + int[] result = new int[op1.Length * 2]; + + for (int i = 0; i < op1.Length; i++) { - TElem expectedResult = GetLoadVectorExpectedResultByIndex(i, mask, data, result); - expectedResult = map(i, expectedResult); - if (result[i] != expectedResult) + int index = i * 2; + result[index] = ConvertToInt32(op1[i]); + if (op1[i] < 0) { - return false; + // Sign-extend next lane with all ones + result[index + 1] = -1; } } - return true; + + return result; } - private static bool CheckLoadVectorBehaviorCore(TMem[] data, TElem[] result, Func map) - where TMem : INumberBase - where TElem : INumberBase + public static int[] ConvertToInt32(float[] op1) => Array.ConvertAll(op1, num => ConvertToInt32(num)); + + private static long ConvertToInt64(double op1) => (long)Math.Clamp(op1, long.MinValue, long.MaxValue); + + public static long[] ConvertToInt64(double[] op1) => Array.ConvertAll(op1, num => ConvertToInt64(num)); + + public static long[] ConvertToInt64(float[] op1) { - for (var i = 0; i < data.Length; i++) + long[] result = new long[op1.Length / 2]; + + for (int i = 0; i < result.Length; i++) { - TElem expectedResult = GetLoadVectorExpectedResultByIndex(i, data, result); - expectedResult = map(i, expectedResult); - if (result[i] != expectedResult) - { - return false; - } + result[i] = ConvertToInt64(op1[i * 2]); } - return true; - } - public static bool CheckLoadVectorBehavior(TElem[] mask, TMem[] data, TElem[] result) - where TMem : INumberBase, IConvertible - where TElem : INumberBase - { - return CheckLoadVectorBehaviorCore(mask, data, result, (_, loadResult) => loadResult); + return result; } - public static bool CheckLoadVectorBehavior(TMem[] data, TElem[] result) - where TMem : INumberBase, IConvertible - where TElem : INumberBase - { - return CheckLoadVectorBehaviorCore(data, result, (_, loadResult) => loadResult); - } + private static uint ConvertToUInt32(double op1) => (uint)Math.Clamp(op1, uint.MinValue, uint.MaxValue); - public static bool CheckLoadVectorBehavior(TElem[] maskOp, TMem[] data, TElem[] result, TElem[] falseOp) - where TMem : INumberBase, IConvertible - where TElem : INumberBase + public static uint[] ConvertToUInt32(double[] op1) { - return CheckLoadVectorBehaviorCore(data, result, (i, loadResult) => ConditionalSelectResult(maskOp[i], loadResult, falseOp[i])); - } + uint[] result = new uint[op1.Length * 2]; - private static T GetGatherVectorResultByIndex(int index, T[] mask, ExtendedElementT[] data, Index[] indices) - where T : INumberBase - where ExtendedElementT : INumberBase - where Index : IBinaryInteger - { - return (mask[index] == T.Zero) ? T.Zero : T.CreateTruncating(data[int.CreateChecked(indices[index])]); - } + for (int i = 0; i < op1.Length; i++) + { + result[i * 2] = ConvertToUInt32(op1[i]); + } - private static unsafe T GetGatherVectorBasesResultByIndex(int index, T[] mask, AddressT[] data) - where T : INumberBase - where AddressT : unmanaged, INumberBase - where ExtendedElementT : unmanaged, INumberBase - { - return (mask[index] == T.Zero) ? T.Zero : T.CreateTruncating(*(ExtendedElementT*)Unsafe.BitCast(data[index])); + return result; } - private static bool GetGatherVectorResultByByteOffset(int index, T[] mask, byte[] data, Offset[] offsets, T result) - where T : INumberBase - where ExtendedElementT : INumberBase - where Offset : IBinaryInteger + public static uint[] ConvertToUInt32(float[] op1) => Array.ConvertAll(op1, num => ConvertToUInt32(num)); + + private static ulong ConvertToUInt64(double op1) => (ulong)Math.Clamp(op1, ulong.MinValue, ulong.MaxValue); + + public static ulong[] ConvertToUInt64(double[] op1) => Array.ConvertAll(op1, num => ConvertToUInt64(num)); + + public static ulong[] ConvertToUInt64(float[] op1) { - if (mask[index] == T.Zero) + ulong[] result = new ulong[op1.Length / 2]; + + for (int i = 0; i < result.Length; i++) { - return result == T.Zero; + result[i] = ConvertToUInt64(op1[i * 2]); } - int offset = int.CreateChecked(offsets[index]); + return result; + } - if (typeof(ExtendedElementT) == typeof(Int16)) - { - return ExtendedElementT.CreateTruncating(result) == ExtendedElementT.CreateTruncating(LoadInt16FromByteArray(data, offset)); - } - else if (typeof(ExtendedElementT) == typeof(UInt16)) - { - return ExtendedElementT.CreateTruncating(result) == ExtendedElementT.CreateTruncating(LoadUInt16FromByteArray(data, offset)); - } - else if (typeof(ExtendedElementT) == typeof(int)) - { - return ExtendedElementT.CreateTruncating(result) == ExtendedElementT.CreateTruncating(LoadInt32FromByteArray(data, offset)); - } - else if (typeof(ExtendedElementT) == typeof(uint)) - { - return ExtendedElementT.CreateTruncating(result) == ExtendedElementT.CreateTruncating(LoadUInt32FromByteArray(data, offset)); - } - else if (typeof(ExtendedElementT) == typeof(long)) - { - return ExtendedElementT.CreateTruncating(result) == ExtendedElementT.CreateTruncating(LoadInt64FromByteArray(data, offset)); - } - else if (typeof(ExtendedElementT) == typeof(ulong)) - { - return ExtendedElementT.CreateTruncating(result) == ExtendedElementT.CreateTruncating(LoadUInt64FromByteArray(data, offset)); - } - else if (typeof(ExtendedElementT) == typeof(float)) - { - return BitConverter.SingleToInt32Bits((float)(object)result) == LoadInt32FromByteArray(data, offset); - } - else if (typeof(ExtendedElementT) == typeof(double)) - { - return BitConverter.DoubleToInt64Bits((double)(object)result) == LoadInt64FromByteArray(data, offset); - } - else + public static Int32 ConvertToInt32RoundAwayFromZero(float op1) => ConvertToInt32(RoundAwayFromZero(op1)); + + public static Int32 ConvertToInt32RoundToEven(float op1) => ConvertToInt32(RoundToNearest(op1)); + + public static Int32 ConvertToInt32RoundToNegativeInfinity(float op1) => ConvertToInt32(RoundToNegativeInfinity(op1)); + + public static Int32 ConvertToInt32RoundToPositiveInfinity(float op1) => ConvertToInt32(RoundToPositiveInfinity(op1)); + + public static Int32 ConvertToInt32RoundToZero(float op1) => ConvertToInt32(RoundToZero(op1)); + + public static Int64 ConvertToInt64RoundAwayFromZero(double op1) => ConvertToInt64(RoundAwayFromZero(op1)); + + public static Int64 ConvertToInt64RoundToEven(double op1) => ConvertToInt64(RoundToNearest(op1)); + + public static Int64 ConvertToInt64RoundToNegativeInfinity(double op1) => ConvertToInt64(RoundToNegativeInfinity(op1)); + + public static Int64 ConvertToInt64RoundToPositiveInfinity(double op1) => ConvertToInt64(RoundToPositiveInfinity(op1)); + + public static Int64 ConvertToInt64RoundToZero(double op1) => ConvertToInt64(RoundToZero(op1)); + + public static UInt32 ConvertToUInt32RoundAwayFromZero(float op1) => ConvertToUInt32(RoundAwayFromZero(op1)); + + public static UInt32 ConvertToUInt32RoundToEven(float op1) => ConvertToUInt32(RoundToNearest(op1)); + + public static UInt32 ConvertToUInt32RoundToNegativeInfinity(float op1) => ConvertToUInt32(RoundToNegativeInfinity(op1)); + + public static UInt32 ConvertToUInt32RoundToPositiveInfinity(float op1) => ConvertToUInt32(RoundToPositiveInfinity(op1)); + + public static UInt32 ConvertToUInt32RoundToZero(float op1) => ConvertToUInt32(RoundToZero(op1)); + + public static UInt64 ConvertToUInt64RoundAwayFromZero(double op1) => ConvertToUInt64(RoundAwayFromZero(op1)); + + public static UInt64 ConvertToUInt64RoundToEven(double op1) => ConvertToUInt64(RoundToNearest(op1)); + + public static UInt64 ConvertToUInt64RoundToNegativeInfinity(double op1) => ConvertToUInt64(RoundToNegativeInfinity(op1)); + + public static UInt64 ConvertToUInt64RoundToPositiveInfinity(double op1) => ConvertToUInt64(RoundToPositiveInfinity(op1)); + + public static UInt64 ConvertToUInt64RoundToZero(double op1) => ConvertToUInt64(RoundToZero(op1)); + + public static float ConvertToSingle(int op1) => op1; + + public static float ConvertToSingle(uint op1) => op1; + + public static float ConvertToSingle(double op1) => (float)op1; + + public static float[] ConvertToSingle(double[] op1) + { + float[] result = new float[op1.Length * 2]; + + for (int i = 0; i < op1.Length; i++) { - return false; + result[i * 2] = (float)op1[i]; } + + return result; } - private static bool CheckGatherVectorBehaviorCore(T[] mask, ExtendedElementT[] data, Index[] indices, T[] result, Func map) - where T : INumberBase - where ExtendedElementT : INumberBase - where Index : IBinaryInteger + public static float[] ConvertToSingle(int[] op1) => Array.ConvertAll(op1, num => (float)num); + + public static float[] ConvertToSingle(long[] op1) { - for (var i = 0; i < mask.Length; i++) + float[] result = new float[op1.Length * 2]; + + for (int i = 0; i < op1.Length; i++) { - T gatherResult = GetGatherVectorResultByIndex(i, mask, data, indices); - gatherResult = map(i, gatherResult); - if (result[i] != gatherResult) - { - return false; - } + result[i * 2] = (float)op1[i]; } - return true; + + return result; } - private static bool CheckGatherVectorBasesBehaviorCore(T[] mask, AddressT[] data, T[] result, Func map) - where T : INumberBase - where AddressT : unmanaged, INumberBase - where ExtendedElementT : unmanaged, INumberBase + public static float[] ConvertToSingle(uint[] op1) => Array.ConvertAll(op1, num => (float)num); + + public static float[] ConvertToSingle(ulong[] op1) { - for (var i = 0; i < mask.Length; i++) + float[] result = new float[op1.Length * 2]; + + for (int i = 0; i < op1.Length; i++) { - T gatherResult = GetGatherVectorBasesResultByIndex(i, mask, data); - gatherResult = map(i, gatherResult); - if (result[i] != gatherResult) - { - return false; - } + result[i * 2] = (float)op1[i]; } - return true; - } - public static bool CheckGatherVectorBehavior(T[] mask, ExtendedElementT[] data, Index[] indices, T[] result) - where T : INumberBase - where ExtendedElementT : INumberBase - where Index : IBinaryInteger - { - return CheckGatherVectorBehaviorCore(mask, data, indices, result, (_, gatherResult) => gatherResult); + return result; } - public static bool CheckGatherVectorConditionalSelectBehavior(T[] cndSelMask, T[] mask, ExtendedElementT[] data, Index[] indices, T[] cndSelFalse, T[] result) - where T : INumberBase - where ExtendedElementT : INumberBase - where Index : IBinaryInteger + public static float ConvertToSingleUpper(float[] op1, double[] op2, int i) => i < op1.Length ? op1[i] : ConvertToSingle(op2[i - op1.Length]); + + public static double ConvertToDouble(float op1) => op1; + + public static double ConvertToDouble(long op1) => op1; + + public static double ConvertToDouble(ulong op1) => op1; + + public static double[] ConvertToDouble(float[] op1) { - return CheckGatherVectorBehaviorCore(mask, data, indices, result, (i, gatherResult) => ConditionalSelectResult(cndSelMask[i], gatherResult, cndSelFalse[i])); + double[] result = new double[op1.Length / 2]; + + for (int i = 0; i < result.Length; i++) + { + result[i] = op1[i * 2]; + } + + return result; } - public static bool CheckGatherVectorConditionalSelectTrueBehavior(T[] cndSelMask, T[] mask, ExtendedElementT[] data, Index[] indices, T[] cndSelTrue, T[] result) - where T : INumberBase - where ExtendedElementT : INumberBase - where Index : IBinaryInteger + public static double[] ConvertToDouble(int[] op1) { - return CheckGatherVectorBehaviorCore(mask, data, indices, result, (i, gatherResult) => ConditionalSelectTrueResult(cndSelMask[i], gatherResult, cndSelTrue[i])); - } + double[] result = new double[op1.Length / 2]; + for (int i = 0; i < result.Length; i++) + { + result[i] = op1[i * 2]; + } - public static bool CheckGatherVectorBasesBehavior(T[] mask, AddressT[] data, T[] result) - where T : INumberBase - where AddressT : unmanaged, INumberBase - where ExtendedElementT : unmanaged, INumberBase - { - return CheckGatherVectorBasesBehaviorCore(mask, data, result, (_, gatherResult) => gatherResult); + return result; } - public static bool CheckGatherVectorBasesConditionalSelectBehavior(T[] cndSelMask, T[] mask, AddressT[] data, T[] cndSelFalse, T[] result) - where T : INumberBase - where AddressT : unmanaged, INumberBase - where ExtendedElementT : unmanaged, INumberBase + public static double[] ConvertToDouble(long[] op1) => Array.ConvertAll(op1, num => (double)num); + + public static double[] ConvertToDouble(uint[] op1) { - return CheckGatherVectorBasesBehaviorCore(mask, data, result, (i, gatherResult) => ConditionalSelectResult(cndSelMask[i], gatherResult, cndSelFalse[i])); + double[] result = new double[op1.Length / 2]; + + for (int i = 0; i < result.Length; i++) + { + result[i] = op1[i * 2]; + } + + return result; } - public static bool CheckGatherVectorBasesConditionalSelectTrueBehavior(T[] cndSelMask, T[] mask, AddressT[] data, T[] cndSelTrue, T[] result) - where T : INumberBase - where AddressT : unmanaged, INumberBase - where ExtendedElementT : unmanaged, INumberBase + public static double[] ConvertToDouble(ulong[] op1) => Array.ConvertAll(op1, num => (double)num); + + public static double ConvertToDoubleUpper(float[] op1, int i) => ConvertToDouble(op1[i + op1.Length / 2]); + + public static short ReverseElement8(short val) { - return CheckGatherVectorBasesBehaviorCore(mask, data, result, (i, gatherResult) => ConditionalSelectTrueResult(cndSelMask[i], gatherResult, cndSelTrue[i])); + ulong result = 0UL; + + int numberOfElements = (8 * sizeof(short)) / 8; + ulong elementMask = ((1UL << 8) - 1); + + for (int i = 0; i < numberOfElements; i++) + { + ulong element = ((ulong)val >> (8 * i)) & elementMask; + ulong reversedElement = element << (8 * (numberOfElements - 1 - i)); + result |= reversedElement; + } + + return (short)result; } - private static bool CheckFirstFaultingBehaviorCore(T[] result, Vector faultResult, Func checkIter) - where T : INumberBase - where TFault : INumberBase + public static ushort ReverseElement8(ushort val) { - bool hitFault = false; + ulong result = 0UL; - for (var i = 0; i < result.Length; i++) + int numberOfElements = (8 * sizeof(ushort)) / 8; + ulong elementMask = ((1UL << 8) - 1); + + for (int i = 0; i < numberOfElements; i++) { - if (hitFault) - { - if (faultResult[i] != TFault.Zero) - { - return false; - } - } - else - { - if (faultResult[i] == TFault.Zero) - { - // There has to be a valid value for the first element, so check it. - if (i == 0) - { - return false; - } - hitFault = true; - } - else - { - if (!checkIter(i)) - { - return false; - } - } - } + ulong element = ((ulong)val >> (8 * i)) & elementMask; + ulong reversedElement = element << (8 * (numberOfElements - 1 - i)); + result |= reversedElement; } - return true; + return (ushort)result; } - private static bool CheckFaultResultHasAtLeastOneZero(Vector faultResult) where T : INumberBase + public static int ReverseElement8(int val) { - for (var i = 0; i < Vector.Count; i++) + ulong result = 0UL; + + int numberOfElements = (8 * sizeof(int)) / 8; + ulong elementMask = ((1UL << 8) - 1); + + for (int i = 0; i < numberOfElements; i++) { - if (faultResult[i] == T.Zero) - { - return true; - } + ulong element = ((ulong)val >> (8 * i)) & elementMask; + ulong reversedElement = element << (8 * (numberOfElements - 1 - i)); + result |= reversedElement; } - return false; + + return (int)result; } - public static bool CheckLoadVectorFirstFaultingBehavior(TElem[] mask, TMem[] data, TElem[] result, Vector faultResult) - where TMem : INumberBase, IConvertible - where TElem : INumberBase - where TFault : INumberBase + public static uint ReverseElement8(uint val) { - // Checking first faulting behavior requires at least one zero to ensure we are testing the behavior. - if (!CheckFaultResultHasAtLeastOneZero(faultResult)) + ulong result = 0UL; + + int numberOfElements = (8 * sizeof(uint)) / 8; + ulong elementMask = ((1UL << 8) - 1); + + for (int i = 0; i < numberOfElements; i++) { - TestLibrary.TestFramework.LogInformation("Fault result requires at least one zero."); - return false; + ulong element = ((ulong)val >> (8 * i)) & elementMask; + ulong reversedElement = element << (8 * (numberOfElements - 1 - i)); + result |= reversedElement; } - var validElementCount = data.Length; - var hasFaulted = false; - var expectedFaultResult = - InitVector(i => - { - if (hasFaulted) - { - return TFault.Zero; - } + return (uint)result; + } - if (mask[i] == TElem.Zero) - { - return TFault.One; - } + public static long ReverseElement8(long val) + { + ulong result = 0UL; - if (i < validElementCount) - { - return TFault.One; - } + int numberOfElements = (8 * sizeof(long)) / 8; + ulong elementMask = ((1UL << 8) - 1); - hasFaulted = true; - return TFault.Zero; - }); - if (expectedFaultResult != faultResult) + for (int i = 0; i < numberOfElements; i++) { - TestLibrary.TestFramework.LogInformation($"Expected fault result: {expectedFaultResult}\nActual fault result: {faultResult}"); - return false; + ulong element = ((ulong)val >> (8 * i)) & elementMask; + ulong reversedElement = element << (8 * (numberOfElements - 1 - i)); + result |= reversedElement; } - return CheckFirstFaultingBehaviorCore(result, faultResult, i => GetLoadVectorExpectedResultByIndex(i, mask, data, result) == result[i]); + return (long)result; } - public static bool CheckGatherVectorFirstFaultingBehavior(T[] mask, ExtendedElementT[] data, Index[] indices, T[] result, Vector faultResult) - where T : INumberBase - where ExtendedElementT : INumberBase - where Index : IBinaryInteger - where TFault : INumberBase + public static ulong ReverseElement8(ulong val) { - // Checking first faulting behavior requires at least one zero to ensure we are testing the behavior. - if (!CheckFaultResultHasAtLeastOneZero(faultResult)) + ulong result = 0UL; + + int numberOfElements = (8 * sizeof(ulong)) / 8; + ulong elementMask = ((1UL << 8) - 1); + + for (int i = 0; i < numberOfElements; i++) { - TestLibrary.TestFramework.LogInformation("Fault result requires at least one zero."); - return false; + ulong element = ((ulong)val >> (8 * i)) & elementMask; + ulong reversedElement = element << (8 * (numberOfElements - 1 - i)); + result |= reversedElement; } - var hasFaulted = false; - var expectedFaultResult = - InitVector(i => - { - if (hasFaulted) - { - return TFault.Zero; - } + return (ulong)result; + } - if (mask[i] == T.Zero) - { - return TFault.One; - } + public static int ReverseElement16(int val) + { + ulong result = 0UL; - var index = int.CreateChecked(indices[i]); - if (index < 0 || index >= data.Length) - { - hasFaulted = true; - return TFault.Zero; - } - return TFault.One; - }); - if (expectedFaultResult != faultResult) + int numberOfElements = (8 * sizeof(int)) / 16; + ulong elementMask = ((1UL << 16) - 1); + + for (int i = 0; i < numberOfElements; i++) { - TestLibrary.TestFramework.LogInformation($"Expected fault result: {expectedFaultResult}\nActual fault result: {faultResult}"); - return false; + ulong element = ((ulong)val >> (16 * i)) & elementMask; + ulong reversedElement = element << (16 * (numberOfElements - 1 - i)); + result |= reversedElement; } - return CheckFirstFaultingBehaviorCore(result, faultResult, i => GetGatherVectorResultByIndex(i, mask, data, indices) == result[i]); + return (int)result; } - public static bool CheckGatherVectorBasesFirstFaultingBehavior(T[] mask, AddressT[] data, T[] result, Vector faultResult) - where T : INumberBase - where AddressT : unmanaged, INumberBase - where ExtendedElementT : unmanaged, INumberBase - where TFault : INumberBase + public static uint ReverseElement16(uint val) { - // Checking first faulting behavior requires at least one zero to ensure we are testing the behavior. - if (!CheckFaultResultHasAtLeastOneZero(faultResult)) + ulong result = 0UL; + + int numberOfElements = (8 * sizeof(uint)) / 16; + ulong elementMask = ((1UL << 16) - 1); + + for (int i = 0; i < numberOfElements; i++) { - TestLibrary.TestFramework.LogInformation("Fault result requires at least one zero."); - return false; + ulong element = ((ulong)val >> (16 * i)) & elementMask; + ulong reversedElement = element << (16 * (numberOfElements - 1 - i)); + result |= reversedElement; } - var hasFaulted = false; - var expectedFaultResult = - InitVector(i => - { - if (hasFaulted) - { - return TFault.Zero; - } + return (uint)result; + } - if (mask[i] == T.Zero) - { - return TFault.One; - } + public static long ReverseElement16(long val) + { + ulong result = 0UL; - if (data[i] == AddressT.Zero) - { - hasFaulted = true; - return TFault.Zero; - } - return TFault.One; - }); - if (expectedFaultResult != faultResult) + int numberOfElements = (8 * sizeof(long)) / 16; + ulong elementMask = ((1UL << 16) - 1); + + for (int i = 0; i < numberOfElements; i++) { - TestLibrary.TestFramework.LogInformation($"Expected fault result: {expectedFaultResult}\nActual fault result: {faultResult}"); - return false; + ulong element = ((ulong)val >> (16 * i)) & elementMask; + ulong reversedElement = element << (16 * (numberOfElements - 1 - i)); + result |= reversedElement; } - return CheckFirstFaultingBehaviorCore(result, faultResult, i => GetGatherVectorBasesResultByIndex(i, mask, data) == result[i]); + return (long)result; } - public static bool CheckGatherVectorWithByteOffsetFirstFaultingBehavior(T[] mask, byte[] data, Offset[] offsets, T[] result, Vector faultResult) - where T : INumberBase - where ExtendedElementT : INumberBase - where Offset : IBinaryInteger - where TFault : INumberBase + public static ulong ReverseElement16(ulong val) { - // Checking first faulting behavior requires at least one zero to ensure we are testing the behavior. - if (!CheckFaultResultHasAtLeastOneZero(faultResult)) + ulong result = 0UL; + + int numberOfElements = (8 * sizeof(ulong)) / 16; + ulong elementMask = ((1UL << 16) - 1); + + for (int i = 0; i < numberOfElements; i++) { - TestLibrary.TestFramework.LogInformation("Fault result requires at least one zero."); - return false; + ulong element = ((ulong)val >> (16 * i)) & elementMask; + ulong reversedElement = element << (16 * (numberOfElements - 1 - i)); + result |= reversedElement; } - var elemSize = Unsafe.SizeOf(); - var hasFaulted = false; - var expectedFaultResult = - InitVector(i => - { - if (hasFaulted) - { - return TFault.Zero; - } + return (ulong)result; + } - if (mask[i] == T.Zero) - { - return TFault.One; - } + public static long ReverseElement32(long val) + { + ulong result = 0UL; - var offset = int.CreateChecked(offsets[i]); - if (offset < 0 || (offset + elemSize) > data.Length) - { - hasFaulted = true; - return TFault.Zero; - } - return TFault.One; - }); - if (expectedFaultResult != faultResult) + int numberOfElements = (8 * sizeof(long)) / 32; + ulong elementMask = ((1UL << 32) - 1); + + for (int i = 0; i < numberOfElements; i++) { - TestLibrary.TestFramework.LogInformation($"Expected fault result: {expectedFaultResult}\nActual fault result: {faultResult}"); - return false; + ulong element = ((ulong)val >> (32 * i)) & elementMask; + ulong reversedElement = element << (32 * (numberOfElements - 1 - i)); + result |= reversedElement; } - return CheckFirstFaultingBehaviorCore(result, faultResult, i => GetGatherVectorResultByByteOffset(i, mask, data, offsets, result[i])); + return (long)result; } - public static T[] CreateBreakPropagateMask(T[] op1, T[] op2) where T : IBinaryInteger + public static ulong ReverseElement32(ulong val) { - var count = op1.Length; - var result = new T[count]; + ulong result = 0UL; - // embedded true mask - var mask = new T[count]; - for (var i = 0; i < count; i++) + int numberOfElements = (8 * sizeof(ulong)) / 32; + ulong elementMask = ((1UL << 32) - 1); + + for (int i = 0; i < numberOfElements; i++) { - mask[i] = T.One; + ulong element = ((ulong)val >> (32 * i)) & elementMask; + ulong reversedElement = element << (32 * (numberOfElements - 1 - i)); + result |= reversedElement; } - if (LastActive(mask, op1) != T.Zero) + return (ulong)result; + } + + public static uint DotProduct(uint op1, byte[] op2, int s, byte[] op3, int t) + { + uint result = op1; + + for (int i = 0; i < 4; i++) { - Array.Copy(op2, result, count); + result += (uint)((uint)op2[s + i] * (uint)op3[t + i]); } return result; } - private static byte ConditionalExtract(byte[] op1, byte op2, byte[] op3, bool after) + public static int DotProduct(int op1, sbyte[] op2, int s, sbyte[] op3, int t) { - int last = LastActiveElement(op1); - if (last < 0) - { - return op2; - } + int result = op1; - int pos = last; - if (after) + for (int i = 0; i < 4; i++) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + result += (int)((int)op2[s + i] * (int)op3[t + i]); } - return op3[pos]; + return result; } - private static byte[] ConditionalExtract(byte[] op1, byte[] op2, byte[] op3, bool after, bool replicate) + public static ulong DotProduct(ulong op1, ushort[] op2, int s, ushort[] op3, int t) { - int last = LastActiveElement(op1); - if (last < 0) + ulong result = op1; + + for (int i = 0; i < 4; i++) { - return op2; + result += (ulong)((ulong)op2[s + i] * (ulong)op3[t + i]); } - byte[] result = new byte[op1.Length]; - int pos = last; - if (after) + return result; + } + + public static long DotProduct(long op1, short[] op2, int s, short[] op3, int t) + { + long result = op1; + + for (int i = 0; i < 4; i++) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + result += (long)((long)op2[s + i] * (long)op3[t + i]); } - if (replicate) - { - Array.Fill(result, op3[pos]); + return result; + } + + public static int DotProductRotateComplex(int op1, sbyte[] op2, int s, sbyte[] op3, byte rotation) + { + int result = op1; + + int r1 = s; + int i1 = s + 1; + int r2 = s + 2; + int i2 = s + 3; + + switch (rotation) + { + case 0: + result += ((int)op2[r1] * (int)op3[r1]) - ((int)op2[i1] * (int)op3[i1]) + ((int)op2[r2] * (int)op3[r2]) - ((int)op2[i2] * (int)op3[i2]); + break; + case 1: + result += ((int)op2[r1] * (int)op3[i1]) + ((int)op2[i1] * (int)op3[r1]) + ((int)op2[r2] * (int)op3[i2]) + ((int)op2[i2] * (int)op3[r2]); + break; + case 2: + result += ((int)op2[r1] * (int)op3[r1]) + ((int)op2[i1] * (int)op3[i1]) + ((int)op2[r2] * (int)op3[r2]) + ((int)op2[i2] * (int)op3[i2]); + break; + case 3: + result += ((int)op2[r1] * (int)op3[i1]) - ((int)op2[i1] * (int)op3[r1]) + ((int)op2[r2] * (int)op3[i2]) - ((int)op2[i2] * (int)op3[r2]); + break; + default: + throw new ArgumentOutOfRangeException(nameof(rotation), "Invalid rotation value."); } - else - { - Array.Fill(result, 0, 0, op1.Length); - result[0] = op3[pos]; + + return result; + } + + public static int DotProductRotateComplexBySelectedIndex(int op1, sbyte[] op2, int s, sbyte[] op3, int immIndex, byte rotation) + { + int result = op1; + int r1 = s; + int i1 = s + 1; + int r2 = s + 2; + int i2 = s + 3; + + switch (rotation) + { + case 0: + result += ((int)op2[r1] * (int)op3[immIndex]) - ((int)op2[i1] * (int)op3[immIndex + 1]) + ((int)op2[r2] * (int)op3[immIndex + 2]) - ((int)op2[i2] * (int)op3[immIndex + 3]); + break; + case 1: + result += ((int)op2[r1] * (int)op3[immIndex + 1]) + ((int)op2[i1] * (int)op3[immIndex]) + ((int)op2[r2] * (int)op3[immIndex + 3]) + ((int)op2[i2] * (int)op3[immIndex + 2]); + break; + case 2: + result += ((int)op2[r1] * (int)op3[immIndex]) + ((int)op2[i1] * (int)op3[immIndex + 1]) + ((int)op2[r2] * (int)op3[immIndex + 2]) + ((int)op2[i2] * (int)op3[immIndex + 3]); + break; + case 3: + result += ((int)op2[r1] * (int)op3[immIndex + 1]) - ((int)op2[i1] * (int)op3[immIndex]) + ((int)op2[r2] * (int)op3[immIndex + 3]) - ((int)op2[i2] * (int)op3[immIndex + 2]); + break; + default: + throw new ArgumentOutOfRangeException(nameof(rotation), "Invalid rotation value."); } return result; } - public static byte ConditionalExtractAfterLastActiveElement(byte[] op1, byte op2, byte[] op3) + + public static long DotProductRotateComplex(long op1, short[] op2, int s, short[] op3, byte rotation) { - return ConditionalExtract(op1, op2, op3, /* after = */ true); + long result = op1; + + int r1 = s; + int i1 = s + 1; + int r2 = s + 2; + int i2 = s + 3; + + switch (rotation) + { + case 0: + result += ((long)op2[r1] * (long)op3[r1]) - ((long)op2[i1] * (long)op3[i1]) + ((long)op2[r2] * (long)op3[r2]) - ((long)op2[i2] * (long)op3[i2]); + break; + case 1: + result += ((long)op2[r1] * (long)op3[i1]) + ((long)op2[i1] * (long)op3[r1]) + ((long)op2[r2] * (long)op3[i2]) + ((long)op2[i2] * (long)op3[r2]); + break; + case 2: + result += ((long)op2[r1] * (long)op3[r1]) + ((long)op2[i1] * (long)op3[i1]) + ((long)op2[r2] * (long)op3[r2]) + ((long)op2[i2] * (long)op3[i2]); + break; + case 3: + result += ((long)op2[r1] * (long)op3[i1]) - ((long)op2[i1] * (long)op3[r1]) + ((long)op2[r2] * (long)op3[i2]) - ((long)op2[i2] * (long)op3[r2]); + break; + default: + throw new ArgumentOutOfRangeException(nameof(rotation), "Invalid rotation value."); + } + + return result; } - public static byte ConditionalExtractLastActiveElement(byte[] op1, byte op2, byte[] op3) + public static long DotProductRotateComplexBySelectedIndex(long op1, short[] op2, int s, short[] op3, int immIndex, byte rotation) { - return ConditionalExtract(op1, op2, op3, /* after = */ false); + long result = op1; + int r1 = s; + int i1 = s + 1; + int r2 = s + 2; + int i2 = s + 3; + + switch (rotation) + { + case 0: + result += ((long)op2[r1] * (long)op3[immIndex]) - ((long)op2[i1] * (long)op3[immIndex + 1]) + ((long)op2[r2] * (long)op3[immIndex + 2]) - ((long)op2[i2] * (long)op3[immIndex + 3]); + break; + case 1: + result += ((long)op2[r1] * (long)op3[immIndex + 1]) + ((long)op2[i1] * (long)op3[immIndex]) + ((long)op2[r2] * (long)op3[immIndex + 3]) + ((long)op2[i2] * (long)op3[immIndex + 2]); + break; + case 2: + result += ((long)op2[r1] * (long)op3[immIndex]) + ((long)op2[i1] * (long)op3[immIndex + 1]) + ((long)op2[r2] * (long)op3[immIndex + 2]) + ((long)op2[i2] * (long)op3[immIndex + 3]); + break; + case 3: + result += ((long)op2[r1] * (long)op3[immIndex + 1]) - ((long)op2[i1] * (long)op3[immIndex]) + ((long)op2[r2] * (long)op3[immIndex + 3]) - ((long)op2[i2] * (long)op3[immIndex + 2]); + break; + default: + throw new ArgumentOutOfRangeException(nameof(rotation), "Invalid rotation value."); + } + + return result; } - public static byte[] ConditionalExtractAfterLastActiveElement(byte[] op1, byte[] op2, byte[] op3) + public static int WhileLessThanMask(int op1, int op2) { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ false); + return (op1 < op2) ? 1 : 0; } - public static byte[] ConditionalExtractAfterLastActiveElementAndReplicate(byte[] op1, byte[] op2, byte[] op3) + public static uint WhileLessThanMask(uint op1, uint op2) { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ true); + return (uint)((op1 < op2) ? 1 : 0); } - public static byte[] ConditionalExtractLastActiveElement(byte[] op1, byte[] op2, byte[] op3) + public static long WhileLessThanMask(long op1, long op2) { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ false); + return (op1 < op2) ? 1 : 0; } - public static byte[] ConditionalExtractLastActiveElementAndReplicate(byte[] op1, byte[] op2, byte[] op3) + public static ulong WhileLessThanMask(ulong op1, ulong op2) { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ true); + return (ulong)((op1 < op2) ? 1 : 0); } - private static sbyte ConditionalExtract(sbyte[] op1, sbyte op2, sbyte[] op3, bool after) + public static int WhileLessThanOrEqualMask(int op1, int op2) { - int last = LastActiveElement(op1); - if (last < 0) - { - return op2; - } - - int pos = last; - if (after) - { - pos++; - if (pos == op1.Length) - { - pos = 0; - } - } - - return op3[pos]; + return (op1 <= op2) ? 1 : 0; } - private static sbyte[] ConditionalExtract(sbyte[] op1, sbyte[] op2, sbyte[] op3, bool after, bool replicate) + public static uint WhileLessThanOrEqualMask(uint op1, uint op2) { - int last = LastActiveElement(op1); - if (last < 0) - { - return op2; - } - - sbyte[] result = new sbyte[op1.Length]; - int pos = last; - if (after) - { - pos++; - if (pos == op1.Length) - { - pos = 0; - } - } - - if (replicate) - { - Array.Fill(result, op3[pos]); - } - else - { - Array.Fill(result, 0, 0, op1.Length); - result[0] = op3[pos]; - } - - return result; + return (uint)((op1 <= op2) ? 1 : 0); } - public static sbyte ConditionalExtractAfterLastActiveElement(sbyte[] op1, sbyte op2, sbyte[] op3) + public static long WhileLessThanOrEqualMask(long op1, long op2) { - return ConditionalExtract(op1, op2, op3, /* after = */ true); + return (op1 <= op2) ? 1 : 0; } - public static sbyte ConditionalExtractLastActiveElement(sbyte[] op1, sbyte op2, sbyte[] op3) + public static ulong WhileLessThanOrEqualMask(ulong op1, ulong op2) { - return ConditionalExtract(op1, op2, op3, /* after = */ false); + return (ulong)((op1 <= op2) ? 1 : 0); } - public static sbyte[] ConditionalExtractAfterLastActiveElement(sbyte[] op1, sbyte[] op2, sbyte[] op3) + public static ulong MaskBothSet(byte[] op1, byte[] op2) { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ false); + ulong acc = 0; + for (var i = 0; i < op1.Length; i++) + { + acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); + } + return acc; } - public static sbyte[] ConditionalExtractAfterLastActiveElementAndReplicate(sbyte[] op1, sbyte[] op2, sbyte[] op3) + public static ulong MaskBothSet(sbyte[] op1, sbyte[] op2) { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ true); + ulong acc = 0; + for (var i = 0; i < op1.Length; i++) + { + acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); + } + return acc; } - public static sbyte[] ConditionalExtractLastActiveElement(sbyte[] op1, sbyte[] op2, sbyte[] op3) + public static ulong MaskBothSet(short[] op1, short[] op2) { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ false); + ulong acc = 0; + for (var i = 0; i < op1.Length; i++) + { + acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); + } + return acc; } - public static sbyte[] ConditionalExtractLastActiveElementAndReplicate(sbyte[] op1, sbyte[] op2, sbyte[] op3) + public static ulong MaskBothSet(ushort[] op1, ushort[] op2) { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ true); + ulong acc = 0; + for (var i = 0; i < op1.Length; i++) + { + acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); + } + return acc; } - private static short ConditionalExtract(short[] op1, short op2, short[] op3, bool after) + public static ulong MaskBothSet(int[] op1, int[] op2) { - int last = LastActiveElement(op1); - if (last < 0) + ulong acc = 0; + for (var i = 0; i < op1.Length; i++) { - return op2; + acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); } + return acc; + } - int pos = last; - if (after) + public static ulong MaskBothSet(uint[] op1, uint[] op2) + { + ulong acc = 0; + for (var i = 0; i < op1.Length; i++) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); } - - return op3[pos]; + return acc; } - private static short[] ConditionalExtract(short[] op1, short[] op2, short[] op3, bool after, bool replicate) + public static ulong MaskBothSet(long[] op1, long[] op2) { - int last = LastActiveElement(op1); - if (last < 0) + ulong acc = 0; + for (var i = 0; i < op1.Length; i++) { - return op2; + acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); } + return acc; + } - short[] result = new short[op1.Length]; - int pos = last; - if (after) + public static ulong MaskBothSet(ulong[] op1, ulong[] op2) + { + ulong acc = 0; + for (var i = 0; i < op1.Length; i++) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + acc += (ulong)((op1[i] == 1 && op2[i] == 1) ? 1 : 0); } + return acc; + } - if (replicate) + public static ulong MaskBothSet(float[] op1, float[] op2) + { + ulong acc = 0; + for (var i = 0; i < op1.Length; i++) { - Array.Fill(result, op3[pos]); + acc += (ulong)((op1[i] == 1) && (op2[i] == 1) ? 1 : 0); } - else + return acc; + } + + public static ulong MaskBothSet(double[] op1, double[] op2) + { + ulong acc = 0; + for (var i = 0; i < op1.Length; i++) { - Array.Fill(result, 0, 0, op1.Length); - result[0] = op3[pos]; + acc += (ulong)((op1[i] == 1) && (op2[i] == 1) ? 1 : 0); } + return acc; + } - return result; + public static byte getMaskByte() + { + return (byte)(TestLibrary.Generator.GetByte() % 2); } - public static short ConditionalExtractAfterLastActiveElement(short[] op1, short op2, short[] op3) + public static sbyte getMaskSByte() { - return ConditionalExtract(op1, op2, op3, /* after = */ true); + return (sbyte)(TestLibrary.Generator.GetByte() % 2); } - public static short ConditionalExtractLastActiveElement(short[] op1, short op2, short[] op3) + public static short getMaskInt16() { - return ConditionalExtract(op1, op2, op3, /* after = */ false); + return (short)(TestLibrary.Generator.GetUInt16() % 2); } - public static short[] ConditionalExtractAfterLastActiveElement(short[] op1, short[] op2, short[] op3) + public static ushort getMaskUInt16() { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ false); + return (ushort)(TestLibrary.Generator.GetUInt16() % 2); } - public static short[] ConditionalExtractAfterLastActiveElementAndReplicate(short[] op1, short[] op2, short[] op3) + public static int getMaskInt32() { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ true); + return (int)(TestLibrary.Generator.GetUInt32() % 2); } - public static short[] ConditionalExtractLastActiveElement(short[] op1, short[] op2, short[] op3) + public static uint getMaskUInt32() { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ false); + return (uint)(TestLibrary.Generator.GetUInt32() % 2); } - public static short[] ConditionalExtractLastActiveElementAndReplicate(short[] op1, short[] op2, short[] op3) + public static long getMaskInt64() { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ true); + return (long)(TestLibrary.Generator.GetUInt64() % 2); } - private static ushort ConditionalExtract(ushort[] op1, ushort op2, ushort[] op3, bool after) + public static ulong getMaskUInt64() { - int last = LastActiveElement(op1); - if (last < 0) - { - return op2; - } + return (ulong)(TestLibrary.Generator.GetUInt64() % 2); + } - int pos = last; - if (after) - { - pos++; - if (pos == op1.Length) - { - pos = 0; - } - } + public static float getMaskSingle() + { + return (float)(TestLibrary.Generator.GetUInt32() % 2); + } - return op3[pos]; + public static double getMaskDouble() + { + return (double)(TestLibrary.Generator.GetUInt64() % 2); } - private static ushort[] ConditionalExtract(ushort[] op1, ushort[] op2, ushort[] op3, bool after, bool replicate) + public static int MaskNumberOfElementsVector(int elems, SveMaskPattern pattern) { - int last = LastActiveElement(op1); - if (last < 0) - { - return op2; - } - ushort[] result = new ushort[op1.Length]; - int pos = last; - if (after) + switch (pattern) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } - } + // Returns elems, as this is always a power of 2. + case SveMaskPattern.LargestPowerOf2: + return elems; - if (replicate) - { - Array.Fill(result, op3[pos]); - } - else - { - Array.Fill(result, 0, 0, op1.Length); - result[0] = op3[pos]; - } + // Returns N if N elements can fit in the vector. Otherwise 0. + case SveMaskPattern.VectorCount1: + return elems >= 1 ? 1 : 0; + case SveMaskPattern.VectorCount2: + return elems >= 2 ? 2 : 0; + case SveMaskPattern.VectorCount3: + return elems >= 3 ? 3 : 0; + case SveMaskPattern.VectorCount4: + return elems >= 4 ? 4 : 0; + case SveMaskPattern.VectorCount5: + return elems >= 5 ? 5 : 0; + case SveMaskPattern.VectorCount6: + return elems >= 6 ? 6 : 0; + case SveMaskPattern.VectorCount7: + return elems >= 7 ? 7 : 0; + case SveMaskPattern.VectorCount8: + return elems >= 8 ? 8 : 0; + case SveMaskPattern.VectorCount16: + return elems >= 16 ? 16 : 0; + case SveMaskPattern.VectorCount32: + return elems >= 32 ? 32 : 0; + case SveMaskPattern.VectorCount64: + return elems >= 64 ? 64 : 0; + case SveMaskPattern.VectorCount128: + return elems >= 128 ? 128 : 0; + case SveMaskPattern.VectorCount256: + return elems >= 256 ? 256 : 0; - return result; - } + // Number of elems rounded down to nearest multiple of 4 + case SveMaskPattern.LargestMultipleOf4: + return elems - (elems % 4); - public static ushort ConditionalExtractAfterLastActiveElement(ushort[] op1, ushort op2, ushort[] op3) - { - return ConditionalExtract(op1, op2, op3, /* after = */ true); - } + // Number of elems rounded down to nearest multiple of 3 + case SveMaskPattern.LargestMultipleOf3: + return elems - (elems % 3); - public static ushort ConditionalExtractLastActiveElement(ushort[] op1, ushort op2, ushort[] op3) - { - return ConditionalExtract(op1, op2, op3, /* after = */ false); + case SveMaskPattern.All: + default: + return elems; + } } - public static ushort[] ConditionalExtractAfterLastActiveElement(ushort[] op1, ushort[] op2, ushort[] op3) + public static int NumberOfElementsInVectorInt8(SveMaskPattern pattern) { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ false); + return MaskNumberOfElementsVector(Unsafe.SizeOf>() / sizeof(byte), pattern); } - public static ushort[] ConditionalExtractAfterLastActiveElementAndReplicate(ushort[] op1, ushort[] op2, ushort[] op3) + public static int NumberOfElementsInVectorInt16(SveMaskPattern pattern) { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ true); + return MaskNumberOfElementsVector(Unsafe.SizeOf>() / sizeof(short), pattern); } - public static ushort[] ConditionalExtractLastActiveElement(ushort[] op1, ushort[] op2, ushort[] op3) + public static int NumberOfElementsInVectorInt32(SveMaskPattern pattern) { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ false); + return MaskNumberOfElementsVector(Unsafe.SizeOf>() / sizeof(int), pattern); } - public static ushort[] ConditionalExtractLastActiveElementAndReplicate(ushort[] op1, ushort[] op2, ushort[] op3) + public static int NumberOfElementsInVectorInt64(SveMaskPattern pattern) { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ true); + return MaskNumberOfElementsVector(Unsafe.SizeOf>() / sizeof(long), pattern); } - private static int ConditionalExtract(int[] op1, int op2, int[] op3, bool after) + public static int NumberOfActiveElementsInMask(sbyte[] mask) { - int last = LastActiveElement(op1); - if (last < 0) + int acc = 0; + for (var i = 0; i < mask.Length; i++) { - return op2; + acc += (mask[i] == 1) ? 1 : 0; } + return acc; + } - int pos = last; - if (after) + public static int NumberOfActiveElementsInMask(short[] mask) + { + int acc = 0; + for (var i = 0; i < mask.Length; i++) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + acc += (mask[i] == 1) ? 1 : 0; } - - return op3[pos]; + return acc; } - private static int[] ConditionalExtract(int[] op1, int[] op2, int[] op3, bool after, bool replicate) + public static int NumberOfActiveElementsInMask(int[] mask) { - int last = LastActiveElement(op1); - if (last < 0) + int acc = 0; + for (var i = 0; i < mask.Length; i++) { - return op2; + acc += (mask[i] == 1) ? 1 : 0; } + return acc; + } - int[] result = new int[op1.Length]; - int pos = last; - if (after) + public static int NumberOfActiveElementsInMask(long[] mask) + { + int acc = 0; + for (var i = 0; i < mask.Length; i++) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + acc += (mask[i] == 1) ? 1 : 0; } + return acc; + } - if (replicate) - { - Array.Fill(result, op3[pos]); - } - else + public static int NumberOfActiveElementsInMask(byte[] mask) + { + int acc = 0; + for (var i = 0; i < mask.Length; i++) { - Array.Fill(result, 0, 0, op1.Length); - result[0] = op3[pos]; + acc += (mask[i] == 1) ? 1 : 0; } - - return result; + return acc; } - public static int ConditionalExtractAfterLastActiveElement(int[] op1, int op2, int[] op3) + public static int NumberOfActiveElementsInMask(ushort[] mask) { - return ConditionalExtract(op1, op2, op3, /* after = */ true); + int acc = 0; + for (var i = 0; i < mask.Length; i++) + { + acc += (mask[i] == 1) ? 1 : 0; + } + return acc; } - public static int ConditionalExtractLastActiveElement(int[] op1, int op2, int[] op3) + public static int NumberOfActiveElementsInMask(uint[] mask) { - return ConditionalExtract(op1, op2, op3, /* after = */ false); + int acc = 0; + for (var i = 0; i < mask.Length; i++) + { + acc += (mask[i] == 1) ? 1 : 0; + } + return acc; } - public static int[] ConditionalExtractAfterLastActiveElement(int[] op1, int[] op2, int[] op3) + public static int NumberOfActiveElementsInMask(ulong[] mask) { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ false); + int acc = 0; + for (var i = 0; i < mask.Length; i++) + { + acc += (mask[i] == 1) ? 1 : 0; + } + return acc; } - public static int[] ConditionalExtractAfterLastActiveElementAndReplicate(int[] op1, int[] op2, int[] op3) + public static double[] Compact(double[] op1, double[] op2) { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ true); - } + double[] result = new double[op1.Length]; + Array.Fill(result, 0, 0, op1.Length); - public static int[] ConditionalExtractLastActiveElement(int[] op1, int[] op2, int[] op3) - { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ false); - } + int i = 0; + for (int j = 0; j < op1.Length; j++) + { + if (op1[j] != 0) + { + result[i++] = op2[j]; + } + } - public static int[] ConditionalExtractLastActiveElementAndReplicate(int[] op1, int[] op2, int[] op3) - { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ true); + return result; } - private static uint ConditionalExtract(uint[] op1, uint op2, uint[] op3, bool after) + public static int[] Compact(int[] op1, int[] op2) { - int last = LastActiveElement(op1); - if (last < 0) - { - return op2; - } + int[] result = new int[op1.Length]; + Array.Fill(result, 0, 0, op1.Length); - int pos = last; - if (after) + int i = 0; + for (int j = 0; j < op1.Length; j++) { - pos++; - if (pos == op1.Length) + if (op1[j] != 0) { - pos = 0; + result[i++] = op2[j]; } } - return op3[pos]; + return result; } - private static uint[] ConditionalExtract(uint[] op1, uint[] op2, uint[] op3, bool after, bool replicate) + public static long[] Compact(long[] op1, long[] op2) { - int last = LastActiveElement(op1); - if (last < 0) - { - return op2; - } + long[] result = new long[op1.Length]; + Array.Fill(result, 0, 0, op1.Length); - uint[] result = new uint[op1.Length]; - int pos = last; - if (after) + long i = 0; + for (int j = 0; j < op1.Length; j++) { - pos++; - if (pos == op1.Length) + if (op1[j] != 0) { - pos = 0; + result[i++] = op2[j]; } } - if (replicate) - { - Array.Fill(result, op3[pos]); - } - else - { - Array.Fill(result, 0, 0, op1.Length); - result[0] = op3[pos]; - } - return result; } - public static uint ConditionalExtractAfterLastActiveElement(uint[] op1, uint op2, uint[] op3) + public static float[] Compact(float[] op1, float[] op2) { - return ConditionalExtract(op1, op2, op3, /* after = */ true); - } + float[] result = new float[op1.Length]; + Array.Fill(result, 0, 0, op1.Length); - public static uint ConditionalExtractLastActiveElement(uint[] op1, uint op2, uint[] op3) - { - return ConditionalExtract(op1, op2, op3, /* after = */ false); - } + int i = 0; + for (int j = 0; j < op1.Length; j++) + { + if (op1[j] != 0) + { + result[i++] = op2[j]; + } + } - public static uint[] ConditionalExtractAfterLastActiveElement(uint[] op1, uint[] op2, uint[] op3) - { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ false); + return result; } - public static uint[] ConditionalExtractAfterLastActiveElementAndReplicate(uint[] op1, uint[] op2, uint[] op3) + public static uint[] Compact(uint[] op1, uint[] op2) { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ true); - } + uint[] result = new uint[op1.Length]; + Array.Fill(result, 0, 0, op1.Length); - public static uint[] ConditionalExtractLastActiveElement(uint[] op1, uint[] op2, uint[] op3) - { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ false); - } + int i = 0; + for (int j = 0; j < op1.Length; j++) + { + if (op1[j] != 0) + { + result[i++] = op2[j]; + } + } - public static uint[] ConditionalExtractLastActiveElementAndReplicate(uint[] op1, uint[] op2, uint[] op3) - { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ true); + return result; } - private static long ConditionalExtract(long[] op1, long op2, long[] op3, bool after) + public static ulong[] Compact(ulong[] op1, ulong[] op2) { - int last = LastActiveElement(op1); - if (last < 0) - { - return op2; - } + ulong[] result = new ulong[op1.Length]; + Array.Fill(result, 0, 0, op1.Length); - int pos = last; - if (after) + ulong i = 0; + for (int j = 0; j < op1.Length; j++) { - pos++; - if (pos == op1.Length) + if (op1[j] != 0) { - pos = 0; + result[i++] = op2[j]; } } - return op3[pos]; + return result; } - private static long[] ConditionalExtract(long[] op1, long[] op2, long[] op3, bool after, bool replicate) + public static int LoadInt16FromByteArray(byte[] array, int offset) { - int last = LastActiveElement(op1); - if (last < 0) - { - return op2; - } - - long[] result = new long[op1.Length]; - int pos = last; - if (after) + int ret = 0; + for (int i = 1; i >= 0; i--) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + ret = (ret << 8) + (int)array[offset + i]; } + return ret; + } - if (replicate) + public static int LoadInt16FromByteArray(byte[] array, uint offset) + { + int ret = 0; + for (int i = 1; i >= 0; i--) { - Array.Fill(result, op3[pos]); + ret = (ret << 8) + (int)array[offset + i]; } - else + return ret; + } + public static int LoadInt32FromByteArray(byte[] array, int offset) + { + int ret = 0; + for (int i = 3; i >= 0; i--) { - Array.Fill(result, 0, 0, op1.Length); - result[0] = op3[pos]; + ret = (ret << 8) + (int)array[offset + i]; } - - return result; + return ret; } - public static long ConditionalExtractAfterLastActiveElement(long[] op1, long op2, long[] op3) + public static int LoadInt32FromByteArray(byte[] array, uint offset) { - return ConditionalExtract(op1, op2, op3, /* after = */ true); + int ret = 0; + for (int i = 3; i >= 0; i--) + { + ret = (ret << 8) + (int)array[offset + i]; + } + return ret; } - public static long ConditionalExtractLastActiveElement(long[] op1, long op2, long[] op3) + public static long LoadInt64FromByteArray(byte[] array, long offset) { - return ConditionalExtract(op1, op2, op3, /* after = */ false); + long ret = 0; + for (long i = 7; i >= 0; i--) + { + ret = (ret << 8) + (long)array[offset + i]; + } + return ret; } - public static long[] ConditionalExtractAfterLastActiveElement(long[] op1, long[] op2, long[] op3) + public static long LoadInt64FromByteArray(byte[] array, ulong offset) { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ false); + long ret = 0; + for (long i = 7; i >= 0; i--) + { + ret = (ret << 8) + (long)array[offset + (ulong)i]; + } + return ret; } - public static long[] ConditionalExtractAfterLastActiveElementAndReplicate(long[] op1, long[] op2, long[] op3) + public static uint LoadUInt16FromByteArray(byte[] array, int offset) { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ true); + uint ret = 0; + for (int i = 1; i >= 0; i--) + { + ret = (ret << 8) + (uint)array[offset + i]; + } + return ret; } - public static long[] ConditionalExtractLastActiveElement(long[] op1, long[] op2, long[] op3) + public static uint LoadUInt16FromByteArray(byte[] array, uint offset) { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ false); + uint ret = 0; + for (int i = 1; i >= 0; i--) + { + ret = (ret << 8) + (uint)array[offset + i]; + } + return ret; } - public static long[] ConditionalExtractLastActiveElementAndReplicate(long[] op1, long[] op2, long[] op3) + public static uint LoadUInt32FromByteArray(byte[] array, int offset) { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ true); + uint ret = 0; + for (int i = 3; i >= 0; i--) + { + ret = (ret << 8) + (uint)array[offset + i]; + } + return ret; } - public static ulong ConditionalExtractAfterLastActiveElement(ulong[] op1, ulong op2, ulong[] op3) + public static uint LoadUInt32FromByteArray(byte[] array, uint offset) { - return ConditionalExtract(op1, op2, op3, /* after = */ true); + uint ret = 0; + for (int i = 3; i >= 0; i--) + { + ret = (ret << 8) + (uint)array[offset + i]; + } + return ret; } - private static ulong ConditionalExtract(ulong[] op1, ulong op2, ulong[] op3, bool after) + public static ulong LoadUInt64FromByteArray(byte[] array, long offset) { - int last = LastActiveElement(op1); - if (last < 0) + ulong ret = 0; + for (long i = 7; i >= 0; i--) { - return op2; + ret = (ret << 8) + (ulong)array[offset + i]; } + return ret; + } - int pos = last; - if (after) + public static ulong LoadUInt64FromByteArray(byte[] array, ulong offset) + { + ulong ret = 0; + for (long i = 7; i >= 0; i--) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + ret = (ret << 8) + (ulong)array[offset + (ulong)i]; } - - return op3[pos]; + return ret; } - private static ulong[] ConditionalExtract(ulong[] op1, ulong[] op2, ulong[] op3, bool after, bool replicate) + public static float LoadSingleFromByteArray(byte[] array, int offset) { - int last = LastActiveElement(op1); - if (last < 0) + int ret = 0; + for (int i = 3; i >= 0; i--) { - return op2; + ret = (ret << 8) + (int)array[offset + i]; } + return BitConverter.Int32BitsToSingle(ret); + } - ulong[] result = new ulong[op1.Length]; - int pos = last; - if (after) + public static float LoadSingleFromByteArray(byte[] array, uint offset) + { + int ret = 0; + for (int i = 3; i >= 0; i--) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + ret = (ret << 8) + (int)array[offset + i]; } + return BitConverter.Int32BitsToSingle(ret); + } - if (replicate) - { - Array.Fill(result, op3[pos]); - } - else + public static double LoadDoubleFromByteArray(byte[] array, long offset) + { + long ret = 0; + for (long i = 7; i >= 0; i--) { - Array.Fill(result, 0, 0, op1.Length); - result[0] = op3[pos]; + ret = (ret << 8) + (long)array[offset + i]; } - - return result; + return BitConverter.Int64BitsToDouble(ret); } - public static ulong ConditionalExtractLastActiveElement(ulong[] op1, ulong op2, ulong[] op3) + public static double LoadDoubleFromByteArray(byte[] array, ulong offset) { - return ConditionalExtract(op1, op2, op3, /* after = */ false); + long ret = 0; + for (long i = 7; i >= 0; i--) + { + ret = (ret << 8) + (long)array[offset + (ulong)i]; + } + return BitConverter.Int64BitsToDouble(ret); } - public static ulong[] ConditionalExtractAfterLastActiveElement(ulong[] op1, ulong[] op2, ulong[] op3) + public static T Splice(T[] first, T[] second, T[] maskArray, int index) + where T : unmanaged, IEquatable { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ false); - } + int start = -1; + int end = -1; - public static ulong[] ConditionalExtractAfterLastActiveElementAndReplicate(ulong[] op1, ulong[] op2, ulong[] op3) - { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ true); - } + for (int i = 0; i < maskArray.Length; i++) + { + if (!maskArray[i].Equals(default)) + { + if (start == -1) + start = i; + end = i; + } + } - public static ulong[] ConditionalExtractLastActiveElement(ulong[] op1, ulong[] op2, ulong[] op3) - { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ false); + if (start == -1) + { + return second[index]; + } + + int rangeSize = end - start + 1; + return (index < rangeSize) + ? first[start + index] + : second[index - rangeSize]; } - public static ulong[] ConditionalExtractLastActiveElementAndReplicate(ulong[] op1, ulong[] op2, ulong[] op3) + public static T LastActive(T[] mask, T[] x) where T : IBinaryInteger { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ true); + for (var i = mask.Length - 1; i >= 0; i--) + { + if (mask[i] != T.Zero) + { + return x[i]; + } + } + return T.Zero; } - private static float ConditionalExtract(float[] op1, float op2, float[] op3, bool after) + public static T[] CreateBreakAfterMask(T[] mask, T[] op) where T : IBinaryInteger { - int last = LastActiveElement(op1); - if (last < 0) + var count = mask.Length; + var result = new T[count]; + var isBreakSet = false; + for (var i = 0; i < count; i++) { - return op2; + var isElementActive = op[i] != T.Zero; + if (mask[i] != T.Zero) + { + if (isBreakSet) + { + result[i] = T.Zero; + } + else + { + result[i] = T.One; + } + isBreakSet = isBreakSet || isElementActive; + } + else + { + result[i] = T.Zero; + } } + return result; + } - int pos = last; - if (after) + public static T[] CreateBreakAfterPropagateMask(T[] mask, T[] op1, T[] op2) where T : IBinaryInteger + { + var count = mask.Length; + var result = new T[count]; + var isLastActive = LastActive(mask, op1) != T.Zero; + for (var i = 0; i < count; i++) { - pos++; - if (pos == op1.Length) + if (mask[i] != T.Zero) { - pos = 0; + if (isLastActive) + { + result[i] = T.One; + } + else + { + result[i] = T.Zero; + } + isLastActive = isLastActive && (op2[i] == T.Zero); + } + else + { + result[i] = T.Zero; } } - - return op3[pos]; + return result; } - private static float[] ConditionalExtract(float[] op1, float[] op2, float[] op3, bool after, bool replicate) + public static T[] CreateBreakBeforeMask(T[] mask, T[] op) where T : IBinaryInteger { - int last = LastActiveElement(op1); - if (last < 0) + var count = mask.Length; + var result = new T[count]; + var isBreakSet = false; + for (var i = 0; i < count; i++) { - return op2; + var isElementActive = op[i] != T.Zero; + if (mask[i] != T.Zero) + { + isBreakSet = isBreakSet || isElementActive; + if (isBreakSet) + { + result[i] = T.Zero; + } + else + { + result[i] = T.One; + } + } + else + { + result[i] = T.Zero; + } } + return result; + } - float[] result = new float[op1.Length]; - int pos = last; - if (after) + public static T[] CreateBreakBeforePropagateMask(T[] mask, T[] op1, T[] op2) where T : IBinaryInteger + { + var count = mask.Length; + var result = new T[count]; + var isLastActive = LastActive(mask, op1) != T.Zero; + for (var i = 0; i < count; i++) { - pos++; - if (pos == op1.Length) + if (mask[i] != T.Zero) + { + isLastActive = isLastActive && (op2[i] == T.Zero); + if (isLastActive) + { + result[i] = T.One; + } + else + { + result[i] = T.Zero; + } + } + else { - pos = 0; + result[i] = T.Zero; } } - - if (replicate) - { - Array.Fill(result, op3[pos]); - } - else - { - Array.Fill(result, 0, 0, op1.Length); - result[0] = op3[pos]; - } - return result; } - public static float ConditionalExtractAfterLastActiveElement(float[] op1, float op2, float[] op3) + private static T ConditionalSelectResult(T maskResult, T result, T falseResult) where T : INumberBase { - return ConditionalExtract(op1, op2, op3, /* after = */ true); + return (maskResult != T.Zero) ? result : falseResult; } - public static float ConditionalExtractLastActiveElement(float[] op1, float op2, float[] op3) + private static T ConditionalSelectTrueResult(T maskResult, T result, T trueResult) where T : INumberBase { - return ConditionalExtract(op1, op2, op3, /* after = */ false); + return (maskResult != T.Zero) ? trueResult : result; } - public static float[] ConditionalExtractAfterLastActiveElement(float[] op1, float[] op2, float[] op3) - { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ false); - } - public static float[] ConditionalExtractAfterLastActiveElementAndReplicate(float[] op1, float[] op2, float[] op3) + private static TElem GetLoadVectorExpectedResultByIndex(int index, TElem[] mask, TMem[] data, TElem[] result) + where TMem : INumberBase + where TElem : INumberBase { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ true); + return (mask[index] == TElem.Zero) ? TElem.Zero : TElem.CreateTruncating(data[index]); } - public static float[] ConditionalExtractLastActiveElement(float[] op1, float[] op2, float[] op3) + private static TElem GetLoadVectorExpectedResultByIndex(int index, TMem[] data, TElem[] result) + where TMem : INumberBase + where TElem : INumberBase { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ false); - } + TElem[] mask = new TElem[result.Length]; + Array.Fill(mask, TElem.One); - public static float[] ConditionalExtractLastActiveElementAndReplicate(float[] op1, float[] op2, float[] op3) - { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ true); + return GetLoadVectorExpectedResultByIndex(index, mask, data, result); } - private static double ConditionalExtract(double[] op1, double op2, double[] op3, bool after) + private static bool CheckLoadVectorBehaviorCore(TElem[] mask, TMem[] data, TElem[] result, Func map) + where TMem : INumberBase + where TElem : INumberBase { - int last = LastActiveElement(op1); - if (last < 0) - { - return op2; - } - - int pos = last; - if (after) + for (var i = 0; i < data.Length; i++) { - pos++; - if (pos == op1.Length) + TElem expectedResult = GetLoadVectorExpectedResultByIndex(i, mask, data, result); + expectedResult = map(i, expectedResult); + if (result[i] != expectedResult) { - pos = 0; + return false; } } - - return op3[pos]; + return true; } - private static double[] ConditionalExtract(double[] op1, double[] op2, double[] op3, bool after, bool replicate) + private static bool CheckLoadVectorBehaviorCore(TMem[] data, TElem[] result, Func map) + where TMem : INumberBase + where TElem : INumberBase { - int last = LastActiveElement(op1); - if (last < 0) - { - return op2; - } - - double[] result = new double[op1.Length]; - int pos = last; - if (after) + for (var i = 0; i < data.Length; i++) { - pos++; - if (pos == op1.Length) + TElem expectedResult = GetLoadVectorExpectedResultByIndex(i, data, result); + expectedResult = map(i, expectedResult); + if (result[i] != expectedResult) { - pos = 0; + return false; } } - - if (replicate) - { - Array.Fill(result, op3[pos]); - } - else - { - Array.Fill(result, 0, 0, op1.Length); - result[0] = op3[pos]; - } - - return result; + return true; } - public static double ConditionalExtractAfterLastActiveElement(double[] op1, double op2, double[] op3) + public static bool CheckLoadVectorBehavior(TElem[] mask, TMem[] data, TElem[] result) + where TMem : INumberBase, IConvertible + where TElem : INumberBase { - return ConditionalExtract(op1, op2, op3, /* after = */ true); + return CheckLoadVectorBehaviorCore(mask, data, result, (_, loadResult) => loadResult); } - public static double ConditionalExtractLastActiveElement(double[] op1, double op2, double[] op3) + public static bool CheckLoadVectorBehavior(TMem[] data, TElem[] result) + where TMem : INumberBase, IConvertible + where TElem : INumberBase { - return ConditionalExtract(op1, op2, op3, /* after = */ false); + return CheckLoadVectorBehaviorCore(data, result, (_, loadResult) => loadResult); } - public static double[] ConditionalExtractAfterLastActiveElement(double[] op1, double[] op2, double[] op3) + public static bool CheckLoadVectorBehavior(TElem[] maskOp, TMem[] data, TElem[] result, TElem[] falseOp) + where TMem : INumberBase, IConvertible + where TElem : INumberBase { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ false); + return CheckLoadVectorBehaviorCore(data, result, (i, loadResult) => ConditionalSelectResult(maskOp[i], loadResult, falseOp[i])); } - public static double[] ConditionalExtractAfterLastActiveElementAndReplicate(double[] op1, double[] op2, double[] op3) + private static T GetGatherVectorResultByIndex(int index, T[] mask, ExtendedElementT[] data, Index[] indices) + where T : INumberBase + where ExtendedElementT : INumberBase + where Index : IBinaryInteger { - return ConditionalExtract(op1, op2, op3, /* after = */ true, /* replicate = */ true); + return (mask[index] == T.Zero) ? T.Zero : T.CreateTruncating(data[int.CreateChecked(indices[index])]); } - public static double[] ConditionalExtractLastActiveElement(double[] op1, double[] op2, double[] op3) + private static unsafe T GetGatherVectorBasesResultByIndex(int index, T[] mask, AddressT[] data) + where T : INumberBase + where AddressT : unmanaged, INumberBase + where ExtendedElementT : unmanaged, INumberBase { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ false); + return (mask[index] == T.Zero) ? T.Zero : T.CreateTruncating(*(ExtendedElementT*)Unsafe.BitCast(data[index])); } - public static double[] ConditionalExtractLastActiveElementAndReplicate(double[] op1, double[] op2, double[] op3) + private static bool GetGatherVectorResultByByteOffset(int index, T[] mask, byte[] data, Offset[] offsets, T result) + where T : INumberBase + where ExtendedElementT : INumberBase + where Offset : IBinaryInteger { - return ConditionalExtract(op1, op2, op3, /* after = */ false, /* replicate = */ true); + if (mask[index] == T.Zero) + { + return result == T.Zero; + } + + int offset = int.CreateChecked(offsets[index]); + + if (typeof(ExtendedElementT) == typeof(Int16)) + { + return ExtendedElementT.CreateTruncating(result) == ExtendedElementT.CreateTruncating(LoadInt16FromByteArray(data, offset)); + } + else if (typeof(ExtendedElementT) == typeof(UInt16)) + { + return ExtendedElementT.CreateTruncating(result) == ExtendedElementT.CreateTruncating(LoadUInt16FromByteArray(data, offset)); + } + else if (typeof(ExtendedElementT) == typeof(int)) + { + return ExtendedElementT.CreateTruncating(result) == ExtendedElementT.CreateTruncating(LoadInt32FromByteArray(data, offset)); + } + else if (typeof(ExtendedElementT) == typeof(uint)) + { + return ExtendedElementT.CreateTruncating(result) == ExtendedElementT.CreateTruncating(LoadUInt32FromByteArray(data, offset)); + } + else if (typeof(ExtendedElementT) == typeof(long)) + { + return ExtendedElementT.CreateTruncating(result) == ExtendedElementT.CreateTruncating(LoadInt64FromByteArray(data, offset)); + } + else if (typeof(ExtendedElementT) == typeof(ulong)) + { + return ExtendedElementT.CreateTruncating(result) == ExtendedElementT.CreateTruncating(LoadUInt64FromByteArray(data, offset)); + } + else if (typeof(ExtendedElementT) == typeof(float)) + { + return BitConverter.SingleToInt32Bits((float)(object)result) == LoadInt32FromByteArray(data, offset); + } + else if (typeof(ExtendedElementT) == typeof(double)) + { + return BitConverter.DoubleToInt64Bits((double)(object)result) == LoadInt64FromByteArray(data, offset); + } + else + { + return false; + } } - private static byte[] Extract(byte[] op1, byte[] op2, bool after) + private static bool CheckGatherVectorBehaviorCore(T[] mask, ExtendedElementT[] data, Index[] indices, T[] result, Func map) + where T : INumberBase + where ExtendedElementT : INumberBase + where Index : IBinaryInteger { - int pos = LastActiveElement(op1); - if (after) + for (var i = 0; i < mask.Length; i++) { - pos++; - if (pos == op1.Length) + T gatherResult = GetGatherVectorResultByIndex(i, mask, data, indices); + gatherResult = map(i, gatherResult); + if (result[i] != gatherResult) { - pos = 0; + return false; } } - - byte[] result = new byte[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - result[0] = op2[pos]; - - return result; + return true; } - private static byte ExtractScalar(byte[] op1, byte[] op2, bool after) + private static bool CheckGatherVectorBasesBehaviorCore(T[] mask, AddressT[] data, T[] result, Func map) + where T : INumberBase + where AddressT : unmanaged, INumberBase + where ExtendedElementT : unmanaged, INumberBase { - int pos = LastActiveElement(op1); - if (after) + for (var i = 0; i < mask.Length; i++) { - pos++; - if (pos == op1.Length) + T gatherResult = GetGatherVectorBasesResultByIndex(i, mask, data); + gatherResult = map(i, gatherResult); + if (result[i] != gatherResult) { - pos = 0; + return false; } } + return true; + } - return op2[pos]; + public static bool CheckGatherVectorBehavior(T[] mask, ExtendedElementT[] data, Index[] indices, T[] result) + where T : INumberBase + where ExtendedElementT : INumberBase + where Index : IBinaryInteger + { + return CheckGatherVectorBehaviorCore(mask, data, indices, result, (_, gatherResult) => gatherResult); + } + + public static bool CheckGatherVectorConditionalSelectBehavior(T[] cndSelMask, T[] mask, ExtendedElementT[] data, Index[] indices, T[] cndSelFalse, T[] result) + where T : INumberBase + where ExtendedElementT : INumberBase + where Index : IBinaryInteger + { + return CheckGatherVectorBehaviorCore(mask, data, indices, result, (i, gatherResult) => ConditionalSelectResult(cndSelMask[i], gatherResult, cndSelFalse[i])); + } + + public static bool CheckGatherVectorConditionalSelectTrueBehavior(T[] cndSelMask, T[] mask, ExtendedElementT[] data, Index[] indices, T[] cndSelTrue, T[] result) + where T : INumberBase + where ExtendedElementT : INumberBase + where Index : IBinaryInteger + { + return CheckGatherVectorBehaviorCore(mask, data, indices, result, (i, gatherResult) => ConditionalSelectTrueResult(cndSelMask[i], gatherResult, cndSelTrue[i])); } - public static byte[] ExtractAfterLastActiveElement(byte[] op1, byte[] op2) + + public static bool CheckGatherVectorBasesBehavior(T[] mask, AddressT[] data, T[] result) + where T : INumberBase + where AddressT : unmanaged, INumberBase + where ExtendedElementT : unmanaged, INumberBase { - return Extract(op1, op2, /* after = */ true); + return CheckGatherVectorBasesBehaviorCore(mask, data, result, (_, gatherResult) => gatherResult); } - public static byte ExtractAfterLastActiveElementScalar(byte[] op1, byte[] op2) + public static bool CheckGatherVectorBasesConditionalSelectBehavior(T[] cndSelMask, T[] mask, AddressT[] data, T[] cndSelFalse, T[] result) + where T : INumberBase + where AddressT : unmanaged, INumberBase + where ExtendedElementT : unmanaged, INumberBase { - return ExtractScalar(op1, op2, /* after = */ true); + return CheckGatherVectorBasesBehaviorCore(mask, data, result, (i, gatherResult) => ConditionalSelectResult(cndSelMask[i], gatherResult, cndSelFalse[i])); } - public static byte[] ExtractLastActiveElement(byte[] op1, byte[] op2) + public static bool CheckGatherVectorBasesConditionalSelectTrueBehavior(T[] cndSelMask, T[] mask, AddressT[] data, T[] cndSelTrue, T[] result) + where T : INumberBase + where AddressT : unmanaged, INumberBase + where ExtendedElementT : unmanaged, INumberBase { - return Extract(op1, op2, /* after = */ false); + return CheckGatherVectorBasesBehaviorCore(mask, data, result, (i, gatherResult) => ConditionalSelectTrueResult(cndSelMask[i], gatherResult, cndSelTrue[i])); } - public static byte ExtractLastActiveElementScalar(byte[] op1, byte[] op2) - { - return ExtractScalar(op1, op2, /* after = */ false); + private static bool CheckFirstFaultingBehaviorCore(T[] result, Vector faultResult, Func checkIter) + where T : INumberBase + where TFault : INumberBase + { + bool hitFault = false; + + for (var i = 0; i < result.Length; i++) + { + if (hitFault) + { + if (faultResult[i] != TFault.Zero) + { + return false; + } + } + else + { + if (faultResult[i] == TFault.Zero) + { + // There has to be a valid value for the first element, so check it. + if (i == 0) + { + return false; + } + hitFault = true; + } + else + { + if (!checkIter(i)) + { + return false; + } + } + } + } + + return true; } - private static short[] Extract(short[] op1, short[] op2, bool after) + private static bool CheckFaultResultHasAtLeastOneZero(Vector faultResult) where T : INumberBase { - int pos = LastActiveElement(op1); - if (after) + for (var i = 0; i < Vector.Count; i++) { - pos++; - if (pos == op1.Length) + if (faultResult[i] == T.Zero) { - pos = 0; + return true; } } - - short[] result = new short[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - result[0] = op2[pos]; - - return result; + return false; } - private static short ExtractScalar(short[] op1, short[] op2, bool after) + public static bool CheckLoadVectorFirstFaultingBehavior(TElem[] mask, TMem[] data, TElem[] result, Vector faultResult) + where TMem : INumberBase, IConvertible + where TElem : INumberBase + where TFault : INumberBase { - int pos = LastActiveElement(op1); - if (after) + // Checking first faulting behavior requires at least one zero to ensure we are testing the behavior. + if (!CheckFaultResultHasAtLeastOneZero(faultResult)) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + TestLibrary.TestFramework.LogInformation("Fault result requires at least one zero."); + return false; } - return op2[pos]; - } + var validElementCount = data.Length; + var hasFaulted = false; + var expectedFaultResult = + InitVector(i => + { + if (hasFaulted) + { + return TFault.Zero; + } - public static short[] ExtractAfterLastActiveElement(short[] op1, short[] op2) - { - return Extract(op1, op2, /* after = */ true); - } + if (mask[i] == TElem.Zero) + { + return TFault.One; + } - public static short ExtractAfterLastActiveElementScalar(short[] op1, short[] op2) - { - return ExtractScalar(op1, op2, /* after = */ true); - } + if (i < validElementCount) + { + return TFault.One; + } - public static short[] ExtractLastActiveElement(short[] op1, short[] op2) - { - return Extract(op1, op2, /* after = */ false); - } + hasFaulted = true; + return TFault.Zero; + }); + if (expectedFaultResult != faultResult) + { + TestLibrary.TestFramework.LogInformation($"Expected fault result: {expectedFaultResult}\nActual fault result: {faultResult}"); + return false; + } - public static short ExtractLastActiveElementScalar(short[] op1, short[] op2) - { - return ExtractScalar(op1, op2, /* after = */ false); + return CheckFirstFaultingBehaviorCore(result, faultResult, i => GetLoadVectorExpectedResultByIndex(i, mask, data, result) == result[i]); } - private static int[] Extract(int[] op1, int[] op2, bool after) + public static bool CheckGatherVectorFirstFaultingBehavior(T[] mask, ExtendedElementT[] data, Index[] indices, T[] result, Vector faultResult) + where T : INumberBase + where ExtendedElementT : INumberBase + where Index : IBinaryInteger + where TFault : INumberBase { - int pos = LastActiveElement(op1); - if (after) + // Checking first faulting behavior requires at least one zero to ensure we are testing the behavior. + if (!CheckFaultResultHasAtLeastOneZero(faultResult)) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + TestLibrary.TestFramework.LogInformation("Fault result requires at least one zero."); + return false; } - int[] result = new int[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - result[0] = op2[pos]; + var hasFaulted = false; + var expectedFaultResult = + InitVector(i => + { + if (hasFaulted) + { + return TFault.Zero; + } - return result; - } + if (mask[i] == T.Zero) + { + return TFault.One; + } - private static int ExtractScalar(int[] op1, int[] op2, bool after) - { - int pos = LastActiveElement(op1); - if (after) + var index = int.CreateChecked(indices[i]); + if (index < 0 || index >= data.Length) + { + hasFaulted = true; + return TFault.Zero; + } + return TFault.One; + }); + if (expectedFaultResult != faultResult) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + TestLibrary.TestFramework.LogInformation($"Expected fault result: {expectedFaultResult}\nActual fault result: {faultResult}"); + return false; } - return op2[pos]; - } - - public static int[] ExtractAfterLastActiveElement(int[] op1, int[] op2) - { - return Extract(op1, op2, /* after = */ true); + return CheckFirstFaultingBehaviorCore(result, faultResult, i => GetGatherVectorResultByIndex(i, mask, data, indices) == result[i]); } - public static int ExtractAfterLastActiveElementScalar(int[] op1, int[] op2) + public static bool CheckGatherVectorBasesFirstFaultingBehavior(T[] mask, AddressT[] data, T[] result, Vector faultResult) + where T : INumberBase + where AddressT : unmanaged, INumberBase + where ExtendedElementT : unmanaged, INumberBase + where TFault : INumberBase { - return ExtractScalar(op1, op2, /* after = */ true); - } + // Checking first faulting behavior requires at least one zero to ensure we are testing the behavior. + if (!CheckFaultResultHasAtLeastOneZero(faultResult)) + { + TestLibrary.TestFramework.LogInformation("Fault result requires at least one zero."); + return false; + } - public static int[] ExtractLastActiveElement(int[] op1, int[] op2) - { - return Extract(op1, op2, /* after = */ false); - } + var hasFaulted = false; + var expectedFaultResult = + InitVector(i => + { + if (hasFaulted) + { + return TFault.Zero; + } - public static int ExtractLastActiveElementScalar(int[] op1, int[] op2) - { - return ExtractScalar(op1, op2, /* after = */ false); - } + if (mask[i] == T.Zero) + { + return TFault.One; + } - private static long[] Extract(long[] op1, long[] op2, bool after) - { - int pos = LastActiveElement(op1); - if (after) + if (data[i] == AddressT.Zero) + { + hasFaulted = true; + return TFault.Zero; + } + return TFault.One; + }); + if (expectedFaultResult != faultResult) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + TestLibrary.TestFramework.LogInformation($"Expected fault result: {expectedFaultResult}\nActual fault result: {faultResult}"); + return false; } - long[] result = new long[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - result[0] = op2[pos]; - - return result; + return CheckFirstFaultingBehaviorCore(result, faultResult, i => GetGatherVectorBasesResultByIndex(i, mask, data) == result[i]); } - private static long ExtractScalar(long[] op1, long[] op2, bool after) + public static bool CheckGatherVectorWithByteOffsetFirstFaultingBehavior(T[] mask, byte[] data, Offset[] offsets, T[] result, Vector faultResult) + where T : INumberBase + where ExtendedElementT : INumberBase + where Offset : IBinaryInteger + where TFault : INumberBase { - int pos = LastActiveElement(op1); - if (after) + // Checking first faulting behavior requires at least one zero to ensure we are testing the behavior. + if (!CheckFaultResultHasAtLeastOneZero(faultResult)) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + TestLibrary.TestFramework.LogInformation("Fault result requires at least one zero."); + return false; } - return op2[pos]; - } + var elemSize = Unsafe.SizeOf(); + var hasFaulted = false; + var expectedFaultResult = + InitVector(i => + { + if (hasFaulted) + { + return TFault.Zero; + } - public static long[] ExtractAfterLastActiveElement(long[] op1, long[] op2) - { - return Extract(op1, op2, /* after = */ true); - } + if (mask[i] == T.Zero) + { + return TFault.One; + } - public static long ExtractAfterLastActiveElementScalar(long[] op1, long[] op2) - { - return ExtractScalar(op1, op2, /* after = */ true); - } + var offset = int.CreateChecked(offsets[i]); + if (offset < 0 || (offset + elemSize) > data.Length) + { + hasFaulted = true; + return TFault.Zero; + } + return TFault.One; + }); + if (expectedFaultResult != faultResult) + { + TestLibrary.TestFramework.LogInformation($"Expected fault result: {expectedFaultResult}\nActual fault result: {faultResult}"); + return false; + } - public static long[] ExtractLastActiveElement(long[] op1, long[] op2) - { - return Extract(op1, op2, /* after = */ false); + return CheckFirstFaultingBehaviorCore(result, faultResult, i => GetGatherVectorResultByByteOffset(i, mask, data, offsets, result[i])); } - public static long ExtractLastActiveElementScalar(long[] op1, long[] op2) + public static T[] CreateBreakPropagateMask(T[] op1, T[] op2) where T : IBinaryInteger { - return ExtractScalar(op1, op2, /* after = */ false); - } + var count = op1.Length; + var result = new T[count]; - private static sbyte[] Extract(sbyte[] op1, sbyte[] op2, bool after) - { - int pos = LastActiveElement(op1); - if (after) + // embedded true mask + var mask = new T[count]; + for (var i = 0; i < count; i++) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + mask[i] = T.One; + } + + if (LastActive(mask, op1) != T.Zero) + { + Array.Copy(op2, result, count); } - sbyte[] result = new sbyte[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - result[0] = op2[pos]; - return result; } - private static sbyte ExtractScalar(sbyte[] op1, sbyte[] op2, bool after) + public static T ConditionalExtract(T[] op1, T op2, T[] op3, bool after) where T : INumber { - int pos = LastActiveElement(op1); + int last = LastActiveElement(op1); + if (last < 0) + { + return op2; + } + + int pos = last; if (after) { pos++; @@ -10588,32 +7541,20 @@ private static sbyte ExtractScalar(sbyte[] op1, sbyte[] op2, bool after) } } - return op2[pos]; - } - - public static sbyte[] ExtractAfterLastActiveElement(sbyte[] op1, sbyte[] op2) - { - return Extract(op1, op2, /* after = */ true); - } - - public static sbyte ExtractAfterLastActiveElementScalar(sbyte[] op1, sbyte[] op2) - { - return ExtractScalar(op1, op2, /* after = */ true); - } - - public static sbyte[] ExtractLastActiveElement(sbyte[] op1, sbyte[] op2) - { - return Extract(op1, op2, /* after = */ false); + return op3[pos]; } - public static sbyte ExtractLastActiveElementScalar(sbyte[] op1, sbyte[] op2) + public static T[] ConditionalExtract(T[] op1, T[] op2, T[] op3, bool after, bool replicate) + where T : INumber { - return ExtractScalar(op1, op2, /* after = */ false); - } + int last = LastActiveElement(op1); + if (last < 0) + { + return op2; + } - private static ushort[] Extract(ushort[] op1, ushort[] op2, bool after) - { - int pos = LastActiveElement(op1); + T[] result = new T[op1.Length]; + int pos = last; if (after) { pos++; @@ -10623,49 +7564,38 @@ private static ushort[] Extract(ushort[] op1, ushort[] op2, bool after) } } - ushort[] result = new ushort[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - result[0] = op2[pos]; + if (replicate) + { + Array.Fill(result, op3[pos]); + } + else + { + Array.Fill(result, T.Zero); + result[0] = op3[pos]; + } return result; } - private static ushort ExtractScalar(ushort[] op1, ushort[] op2, bool after) - { - int pos = LastActiveElement(op1); - if (after) - { - pos++; - if (pos == op1.Length) - { - pos = 0; - } - } + public static T ConditionalExtractAfterLastActiveElement(T[] op1, T op2, T[] op3) where T : INumber + => ConditionalExtract(op1, op2, op3, after: true); - return op2[pos]; - } + public static T ConditionalExtractLastActiveElement(T[] op1, T op2, T[] op3) where T : INumber + => ConditionalExtract(op1, op2, op3, after: false); - public static ushort[] ExtractAfterLastActiveElement(ushort[] op1, ushort[] op2) - { - return Extract(op1, op2, /* after = */ true); - } + public static T[] ConditionalExtractAfterLastActiveElement(T[] op1, T[] op2, T[] op3) where T : INumber + => ConditionalExtract(op1, op2, op3, after: true, replicate: false); - public static ushort ExtractAfterLastActiveElementScalar(ushort[] op1, ushort[] op2) - { - return ExtractScalar(op1, op2, /* after = */ true); - } + public static T[] ConditionalExtractAfterLastActiveElementAndReplicate(T[] op1, T[] op2, T[] op3) where T : INumber + => ConditionalExtract(op1, op2, op3, after: true, replicate: true); - public static ushort[] ExtractLastActiveElement(ushort[] op1, ushort[] op2) - { - return Extract(op1, op2, /* after = */ false); - } + public static T[] ConditionalExtractLastActiveElement(T[] op1, T[] op2, T[] op3) where T : INumber + => ConditionalExtract(op1, op2, op3, after: false, replicate: false); - public static ushort ExtractLastActiveElementScalar(ushort[] op1, ushort[] op2) - { - return ExtractScalar(op1, op2, /* after = */ false); - } + public static T[] ConditionalExtractLastActiveElementAndReplicate(T[] op1, T[] op2, T[] op3) where T : INumber + => ConditionalExtract(op1, op2, op3, after: false, replicate: true); - private static uint[] Extract(uint[] op1, uint[] op2, bool after) + public static T[] Extract(T[] op1, T[] op2, bool after) where T : INumber { int pos = LastActiveElement(op1); if (after) @@ -10677,14 +7607,13 @@ private static uint[] Extract(uint[] op1, uint[] op2, bool after) } } - uint[] result = new uint[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); + T[] result = new T[op1.Length]; + Array.Fill(result, T.Zero); result[0] = op2[pos]; - return result; } - private static uint ExtractScalar(uint[] op1, uint[] op2, bool after) + public static T ExtractScalar(T[] op1, T[] op2, bool after) where T : INumber { int pos = LastActiveElement(op1); if (after) @@ -10699,224 +7628,213 @@ private static uint ExtractScalar(uint[] op1, uint[] op2, bool after) return op2[pos]; } - public static uint[] ExtractAfterLastActiveElement(uint[] op1, uint[] op2) + public static T[] ExtractAfterLastActiveElement(T[] op1, T[] op2) where T : INumber + => Extract(op1, op2, after: true); + + public static T ExtractAfterLastActiveElementScalar(T[] op1, T[] op2) where T : INumber + => ExtractScalar(op1, op2, after: true); + + public static T[] ExtractLastActiveElement(T[] op1, T[] op2) where T : INumber + => Extract(op1, op2, after: false); + + public static T ExtractLastActiveElementScalar(T[] op1, T[] op2) where T : INumber + => ExtractScalar(op1, op2, after: false); + + public static T BitwiseClearXor(T op1, T op2, T op3) where T : IBitwiseOperators { - return Extract(op1, op2, /* after = */ true); + return op1 ^ (op2 & ~op3); } - public static uint ExtractAfterLastActiveElementScalar(uint[] op1, uint[] op2) + public static T BitwiseSelectLeftInverted(T select, T left, T right) where T : IBitwiseOperators { - return ExtractScalar(op1, op2, /* after = */ true); + return (~left & select) | (right & ~select); } - public static uint[] ExtractLastActiveElement(uint[] op1, uint[] op2) + public static T BitwiseSelectRightInverted(T select, T left, T right) where T : IBitwiseOperators { - return Extract(op1, op2, /* after = */ false); + return (left & select) | (~right & ~select); } - public static uint ExtractLastActiveElementScalar(uint[] op1, uint[] op2) + public static T[] InterleavingXorEvenOdd(T[] odd, T[] left, T[] right) where T : IBinaryInteger { - return ExtractScalar(op1, op2, /* after = */ false); + for (int i = 0; i < odd.Length; i += 2) + { + odd[i] = left[i] ^ right[i + 1]; + } + return odd; } - private static ulong[] Extract(ulong[] op1, ulong[] op2, bool after) + public static T[] InterleavingXorOddEven(T[] even, T[] left, T[] right) where T : IBinaryInteger { - int pos = LastActiveElement(op1); - if (after) + for (int i = 0; i < even.Length; i += 2) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + even[i + 1] = left[i + 1] ^ right[i]; } - - ulong[] result = new ulong[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - result[0] = op2[pos]; - - return result; + return even; } - private static ulong ExtractScalar(ulong[] op1, ulong[] op2, bool after) + public static T[] SubtractBorrowWideningEven(T[] op1, T[] op2, T[] op3) + where T : unmanaged, IBinaryInteger { - int pos = LastActiveElement(op1); - if (after) + T[] result = new T[op1.Length]; + for (int i = 0; i < op1.Length; i += 2) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + 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 op2[pos]; + return result; } - public static ulong[] ExtractAfterLastActiveElement(ulong[] op1, ulong[] op2) + public static T[] SubtractBorrowWideningOdd(T[] op1, T[] op2, T[] op3) + where T : unmanaged, IBinaryInteger { - return Extract(op1, op2, /* after = */ true); - } + 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; + } - public static ulong ExtractAfterLastActiveElementScalar(ulong[] op1, ulong[] op2) - { - return ExtractScalar(op1, op2, /* after = */ true); + return result; } - public static ulong[] ExtractLastActiveElement(ulong[] op1, ulong[] op2) + public static sbyte SubtractHighNarrowingEven(short[] left, short[] right, int i) { - return Extract(op1, op2, /* after = */ false); - } + if (i % 2 == 0) + { + return (sbyte)((left[i / 2] - right[i / 2]) >> 8); + } - public static ulong ExtractLastActiveElementScalar(ulong[] op1, ulong[] op2) - { - return ExtractScalar(op1, op2, /* after = */ false); + return 0; } - private static float[] Extract(float[] op1, float[] op2, bool after) + public static short SubtractHighNarrowingEven(int[] left, int[] right, int i) { - int pos = LastActiveElement(op1); - if (after) + if (i % 2 == 0) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + return (short) ((left[i / 2] - right[i / 2]) >> 16); } - float[] result = new float[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - result[0] = op2[pos]; - - return result; + return 0; } - private static float ExtractScalar(float[] op1, float[] op2, bool after) + public static int SubtractHighNarrowingEven(long[] left, long[] right, int i) { - int pos = LastActiveElement(op1); - if (after) + if (i % 2 == 0) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + return (int) ((left[i / 2] - right[i / 2]) >> 32); } - return op2[pos]; + return 0; } - public static float[] ExtractAfterLastActiveElement(float[] op1, float[] op2) + public static byte SubtractHighNarrowingEven(ushort[] left, ushort[] right, int i) { - return Extract(op1, op2, /* after = */ true); - } + if (i % 2 == 0) + { + return (byte)((left[i / 2] - right[i / 2]) >> 8); + } - public static float ExtractAfterLastActiveElementScalar(float[] op1, float[] op2) - { - return ExtractScalar(op1, op2, /* after = */ true); + return 0; } - public static float[] ExtractLastActiveElement(float[] op1, float[] op2) + public static ushort SubtractHighNarrowingEven(uint[] left, uint[] right, int i) { - return Extract(op1, op2, /* after = */ false); - } + if (i % 2 == 0) + { + return (ushort)((left[i / 2] - right[i / 2]) >> 16); + } - public static float ExtractLastActiveElementScalar(float[] op1, float[] op2) - { - return ExtractScalar(op1, op2, /* after = */ false); + return 0; } - private static double[] Extract(double[] op1, double[] op2, bool after) + public static uint SubtractHighNarrowingEven(ulong[] left, ulong[] right, int i) { - int pos = LastActiveElement(op1); - if (after) + if (i % 2 == 0) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + return (uint)((left[i / 2] - right[i / 2]) >> 32); } - double[] result = new double[op1.Length]; - Array.Fill(result, 0, 0, op1.Length); - result[0] = op2[pos]; - - return result; + return 0; } - private static double ExtractScalar(double[] op1, double[] op2, bool after) + public static sbyte SubtractHighNarrowingOdd(sbyte[] even, short[] left, short[] right, int i) { - int pos = LastActiveElement(op1); - if (after) + if (i % 2 == 1) { - pos++; - if (pos == op1.Length) - { - pos = 0; - } + return (sbyte) ((left[i / 2] - right[i / 2]) >> 8); } - return op2[pos]; + return even[i]; } - public static double[] ExtractAfterLastActiveElement(double[] op1, double[] op2) + public static short SubtractHighNarrowingOdd(short[] even, int[] left, int[] right, int i) { - return Extract(op1, op2, /* after = */ true); - } + if (i % 2 == 1) + { + return (short) ((left[i / 2] - right[i / 2]) >> 16); + } - public static double ExtractAfterLastActiveElementScalar(double[] op1, double[] op2) - { - return ExtractScalar(op1, op2, /* after = */ true); + return even[i]; } - public static double[] ExtractLastActiveElement(double[] op1, double[] op2) + public static int SubtractHighNarrowingOdd(int[] even, long[] left, long[] right, int i) { - return Extract(op1, op2, /* after = */ false); - } + if (i % 2 == 1) + { + return (int) ((left[i / 2] - right[i / 2]) >> 32); + } - public static double ExtractLastActiveElementScalar(double[] op1, double[] op2) - { - return ExtractScalar(op1, op2, /* after = */ false); + return even[i]; } - public static T BitwiseClearXor(T op1, T op2, T op3) where T : IBitwiseOperators + public static byte SubtractHighNarrowingOdd(byte[] even, ushort[] left, ushort[] right, int i) { - return op1 ^ (op2 & ~op3); - } + if (i % 2 == 1) + { + return (byte)((left[i / 2] - right[i / 2]) >> 8); + } - public static T BitwiseSelect(T select, T left, T right) where T : IBitwiseOperators - { - return (left & select) | (right & ~select); + return even[i]; } - public static T BitwiseSelectLeftInverted(T select, T left, T right) where T : IBitwiseOperators + public static ushort SubtractHighNarrowingOdd(ushort[] even, uint[] left, uint[] right, int i) { - return (~left & select) | (right & ~select); - } + if (i % 2 == 1) + { + return (ushort)((left[i / 2] - right[i / 2]) >> 16); + } - public static T BitwiseSelectRightInverted(T select, T left, T right) where T : IBitwiseOperators - { - return (left & select) | (~right & ~select); + return even[i]; } - public static T[] InterleavingXorEvenOdd(T[] odd, T[] left, T[] right) where T : IBinaryInteger + public static uint SubtractHighNarrowingOdd(uint[] even, ulong[] left, ulong[] right, int i) { - for (int i = 0; i < odd.Length; i += 2) + if (i % 2 == 1) { - odd[i] = left[i] ^ right[i + 1]; + return (uint)((left[i / 2] - right[i / 2]) >> 32); } - return odd; + + return even[i]; } - public static T[] InterleavingXorOddEven(T[] even, T[] left, T[] right) where T : IBinaryInteger + public static (T sum, T carryOut) AddWithCarry(T a, T b, T carryIn) + where T : unmanaged, IBinaryInteger { - for (int i = 0; i < even.Length; i += 2) - { - even[i+1] = left[i+1] ^ right[i]; - } - return even; + T sum = a + b + carryIn; + T one = T.One; + T zero = T.Zero; + T carryOut = (sum < a || (sum == a && carryIn == one)) ? one : zero; + return (sum, carryOut); } public static T Xor(params T[] ops) where T : IBitwiseOperators @@ -11021,15 +7939,15 @@ public static T Odd(T even, T odd, int idx) where T : IBinaryInteger public static U ArithmeticShift(T value, int count, bool rounding = false, bool saturate = false) where T : IBinaryInteger - where U : IBinaryInteger + where U : IBinaryInteger, IMinMaxValue { - dynamic v = value; - dynamic shifted; + long v = long.CreateChecked(value); + long shifted; if (count > 0) { if (rounding) { - dynamic bias = 1L << (count - 1); + long bias = 1L << (count - 1); shifted = v >= 0 ? (v + bias) >> count : (v - bias) >> count; } @@ -11049,21 +7967,21 @@ public static U ArithmeticShift(T value, int count, bool rounding = false, if (saturate) { - dynamic min = typeof(U).GetField("MinValue", BindingFlags.Static | BindingFlags.Public).GetValue(null); - dynamic max = typeof(U).GetField("MaxValue", BindingFlags.Static | BindingFlags.Public).GetValue(null); + long min = long.CreateChecked(U.MinValue); + long max = long.CreateChecked(U.MaxValue); if (shifted < min) shifted = min; if (shifted > max) shifted = max; } - return (U)shifted; + return U.CreateTruncating(shifted); } public static U LogicalShift(T value, int count, bool rounding = false, bool saturate = false) where T : IBinaryInteger - where U : IBinaryInteger + where U : IBinaryInteger, IMinMaxValue { - ulong v = Convert.ToUInt64(value); - dynamic shifted; + ulong v = ulong.CreateTruncating(value); + ulong shifted; if (count > 0) { if (rounding) @@ -11088,109 +8006,209 @@ public static U LogicalShift(T value, int count, bool rounding = false, bo if (saturate) { - dynamic max = typeof(U).GetField("MaxValue", BindingFlags.Static | BindingFlags.Public).GetValue(null); + ulong max = ulong.CreateTruncating(U.MaxValue); if (shifted > max) shifted = max; } - return (U)shifted; + return U.CreateTruncating(shifted); } public static U ShiftRightArithmeticNarrowingSaturateEven(T op1, byte op2, int i) where T : IBinaryInteger - where U : IBinaryInteger, new() + where U : IBinaryInteger, IMinMaxValue, new() { return Even(ArithmeticShift(op1, op2, saturate: true), i); } public static U ShiftRightArithmeticNarrowingSaturateOdd(U op0, T op1, byte op2, int i) where T : IBinaryInteger - where U : IBinaryInteger + where U : IBinaryInteger, IMinMaxValue { return Odd(op0, ArithmeticShift(op1, op2, saturate: true), i); } public static U ShiftRightArithmeticNarrowingSaturateUnsignedEven(T op1, byte op2, int i) where T : IBinaryInteger - where U : IBinaryInteger, new() + where U : IBinaryInteger, IMinMaxValue, new() { return ShiftRightArithmeticNarrowingSaturateEven(op1, op2, i); } public static U ShiftRightArithmeticNarrowingSaturateUnsignedOdd(U op0, T op1, byte op2, int i) where T : IBinaryInteger - where U : IBinaryInteger + where U : IBinaryInteger, IMinMaxValue { return ShiftRightArithmeticNarrowingSaturateOdd(op0, op1, op2, i); } public static U ShiftRightArithmeticRoundedNarrowingSaturateEven(T val, byte shift, int i) where T : IBinaryInteger - where U : IBinaryInteger, new() + where U : IBinaryInteger, IMinMaxValue, new() { return Even(ArithmeticShift(val, shift, rounding: true, saturate: true), i); } public static U ShiftRightArithmeticRoundedNarrowingSaturateOdd(U even, T val, byte shift, int i) where T : IBinaryInteger - where U : IBinaryInteger + where U : IBinaryInteger, IMinMaxValue { return Odd(even, ArithmeticShift(val, shift, rounding: true, saturate: true), i); } public static U ShiftRightArithmeticRoundedNarrowingSaturateUnsignedEven(T val, byte shift, int i) where T : IBinaryInteger - where U : IBinaryInteger, new() + where U : IBinaryInteger, IMinMaxValue, new() { return ShiftRightArithmeticRoundedNarrowingSaturateEven(val, shift, i); } public static U ShiftRightArithmeticRoundedNarrowingSaturateUnsignedOdd(U even, T val, byte shift, int i) where T : IBinaryInteger - where U : IBinaryInteger, new() + where U : IBinaryInteger, IMinMaxValue, new() { return ShiftRightArithmeticRoundedNarrowingSaturateOdd(even, val, shift, i); } public static U ShiftRightLogicalNarrowingEven(T val, byte shift, int i) where T : IBinaryInteger - where U : IBinaryInteger, new() + where U : IBinaryInteger, IMinMaxValue, new() { return Even(LogicalShift(val, shift), i); } public static U ShiftRightLogicalNarrowingOdd(U even, T val, byte shift, int i) where T : IBinaryInteger - where U : IBinaryInteger + where U : IBinaryInteger, IMinMaxValue { return Odd(even, LogicalShift(val, shift), i); } public static U ShiftRightLogicalRoundedNarrowingEven(T val, byte shift, int i) where T : IBinaryInteger - where U : IBinaryInteger, new() + where U : IBinaryInteger, IMinMaxValue, new() { return Even(LogicalShift(val, shift, rounding: true), i); } public static U ShiftRightLogicalRoundedNarrowingOdd(U even, T val, byte shift, int i) where T : IBinaryInteger - where U : IBinaryInteger + where U : IBinaryInteger, IMinMaxValue { return Odd(even, LogicalShift(val, shift, rounding: true), i); } public static U ShiftRightLogicalRoundedNarrowingSaturateEven(T val, byte shift, int i) where T : IBinaryInteger - where U : IBinaryInteger, new() + where U : IBinaryInteger, IMinMaxValue, new() { return Even(LogicalShift(val, shift, rounding: true, saturate: true), i); } public static U ShiftRightLogicalRoundedNarrowingSaturateOdd(U even, T val, byte shift, int i) where T : IBinaryInteger - where U : IBinaryInteger + where U : IBinaryInteger, IMinMaxValue { 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 + { + W a = W.CreateChecked(op2); + W b = W.CreateChecked(op3); + W product = W.CreateTruncating(a * b); + return W.CreateTruncating(op1 + product); + } + + public static W MultiplySubtractWidening(W op1, N op2, N op3) + where W : IBinaryInteger + where N : IBinaryInteger + { + W a = W.CreateChecked(op2); + W b = W.CreateChecked(op3); + W product = W.CreateTruncating(a * b); + return W.CreateTruncating(op1 - product); + } + + public static N AddRoundedHighNarrowing(W op1, W op2) + where W : IBinaryInteger + where N : IBinaryInteger + { + int halfsize = default(N).GetByteCount() * 8; + ulong a = ulong.CreateChecked(op1); + ulong b = ulong.CreateChecked(op2); + ulong sum = a + b; + ulong bias = 1UL << (halfsize - 1); + ulong result = (sum + bias) >> halfsize; + return N.CreateTruncating(result); + } + + 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; + ulong a = ulong.CreateChecked(op1); + ulong b = ulong.CreateChecked(op2); + ulong sum = (ulong)a - (ulong)b; + ulong bias = 1UL << (halfsize - 1); + ulong result = (sum + bias) >> halfsize; + return N.CreateTruncating(result); + } + + 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/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadNonFaultingMaskedUnOpTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadNonFaultingMaskedUnOpTest.template new file mode 100644 index 00000000000000..ad454ae481aef4 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadNonFaultingMaskedUnOpTest.template @@ -0,0 +1,350 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\Arm\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Buffers; +using System.Numerics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using Xunit; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + [Fact] + public static void {TestName}() + { + var test = new LoadVectorFaultingMaskedUnOpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario_Load(); + + // Validates basic non faulting functionality + test.RunBasicScenario_LoadNonFaulting(); + + // Validates calling via reflection works + test.RunReflectionScenario_Load(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class LoadVectorFaultingMaskedUnOpTest__{TestName} + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({Op2BaseType}[] inArray1, {RetBaseType}[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); + int sizeOfInBounded = {RetVectorType}<{RetBaseType}>.Count / 2; + + if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfoutArray: {sizeOfoutArray}"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + this.inBounded = BoundedMemory.Allocate(sizeOfInBounded, PoisonPagePlacement.After); + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref inBounded.Span.GetPinnableReference(), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray1[0]), (uint)sizeOfInBounded); + } + + public BoundedMemory inBounded; + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {RetVectorType}<{RetBaseType}> _fld1; + public {RetBaseType}[] _outData; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._outData= new {RetBaseType}[RetElementCount]; + + // Randomise the output buffer to ensure that after the load operation, expected data is populated. + for (var i = 0; i < RetElementCount; i++) { testStruct._outData[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{RetBaseType}, byte>(ref testStruct._outData[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + return testStruct; + } + + public void RunStructFldScenario(LoadVectorFaultingMaskedUnOpTest__{TestName} testClass) + { + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); + + var result = {Isa}.{Method}(loadMask, ({Op2BaseType}*)testClass._dataTable.inArray1Ptr); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(loadMask, testClass._dataTable.inArray1Ptr, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<{RetVectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + private static readonly int Op2ElementCount = RetElementCount; + + private static {Op2BaseType}[] _data = new {Op2BaseType}[Op2ElementCount]; + + private static {Op1BaseType}[] _maskData = new {Op1BaseType}[Op1ElementCount]; + + private {Op1VectorType}<{RetBaseType}> _fld1; + + private {Op1VectorType}<{Op1BaseType}> _mask; + + private DataTable _dataTable; + + public LoadVectorFaultingMaskedUnOpTest__{TestName}() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueOp1}); } + 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 < Op2ElementCount; i++) { _data[i] = {NextValueOp2}; } + _dataTable = new DataTable(_data, new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); + + var result = {Isa}.{Method}( + loadMask, + ({Op2BaseType}*)(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(loadMask, _dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadNonFaulting() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadNonFaulting)); + + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); + + ref var op2Ref = ref _dataTable.inBounded.Span.GetPinnableReference(); + + Sve.SetFfr(Sve.CreateTrueMaskByte(SveMaskPattern.All)); + + var result = {Isa}.{Method}( + loadMask, + ({Op2BaseType}*)(Unsafe.AsPointer(ref op2Ref)) + ); + + var faultResult = Sve.GetFfr{GetFfrType}(); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateNonFaultingResult(loadMask, Unsafe.AsPointer(ref op2Ref), _dataTable.outArrayPtr, faultResult); + } + + public void RunBasicScenario_LoadMasked() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = {Isa}.{Method}( + _mask, + ({Op2BaseType}*)(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_mask, _dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof(Vector<{Op1BaseType}>), typeof({Op2BaseType}*) }) + .Invoke(null, new object[] { + loadMask, + Pointer.Box(_dataTable.inArray1Ptr, typeof({Op2BaseType}*)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(loadMask, _dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); + + _fld1 = {Isa}.{Method}(loadMask, ({Op2BaseType}*)_dataTable.inArray1Ptr); + + Unsafe.Write(_dataTable.outArrayPtr, _fld1); + ValidateResult(loadMask, _dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); + + var test = TestStruct.Create(); + test._fld1 = {Isa}.{Method}(loadMask, ({Op2BaseType}*)_dataTable.inArray1Ptr); + + Unsafe.Write(_dataTable.outArrayPtr, test._fld1); + ValidateResult(loadMask, _dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_Load(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult({Op1VectorType}<{Op1BaseType}> firstOp, void * secondOp, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] maskArray = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray = new {Op2BaseType}[Op2ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref maskArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray[0]), ref Unsafe.AsRef(secondOp), (uint)(sizeof({Op2BaseType}) * Op2ElementCount)); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)(sizeof({RetBaseType}) * RetElementCount)); + + ValidateResult(maskArray, inArray, outArray, method); + } + + private void ValidateResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {RetBaseType}[] result, [CallerMemberName] string method = "") + { + bool succeeded = Helpers.CheckLoadVectorBehavior(firstOp, secondOp, result); + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2BaseType}): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + + private void ValidateNonFaultingResult({Op1VectorType}<{Op1BaseType}> firstOp, void* secondOp, void* result, Vector<{GetFfrType}> faultResult, [CallerMemberName] string method = "") + { + {Op1BaseType}[] maskArray = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray = new {Op2BaseType}[Op2ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + {GetFfrType}[] faultArray = new {GetFfrType}[RetElementCount]; + + // Only read bytes mapping to half of the destination vector. The remaining elements are in the poison page. + // It would make inArray to contain elements that could read without a fault followed by zeros. + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref maskArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray[0]), ref Unsafe.AsRef(secondOp), ((uint){RetVectorType}<{RetBaseType}>.Count / 2) ); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + fixed({GetFfrType}* faultArrayPtr = &faultArray[0]) + { + Unsafe.Write(faultArrayPtr, faultResult); + } + + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + var expectedOut = ({RetBaseType})((i < (RetElementCount / 2)) ? inArray[i] : 0); + var expectedFault = ({GetFfrType}) ((i < (RetElementCount / 2)) ? 1 : 0); + + if ((outArray[i] != expectedOut) && (faultArray[i] != expectedFault) ) + { + succeeded = false; + break; + } + } + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadNonFaultingUnOpTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadNonFaultingUnOpTest.template deleted file mode 100644 index db2416974cdfd4..00000000000000 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadNonFaultingUnOpTest.template +++ /dev/null @@ -1,521 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/****************************************************************************** - * This file is auto-generated from a template file by the GenerateTests.csx * - * script in tests\src\JIT\HardwareIntrinsics\Arm\Shared. In order to make * - * changes, please update the corresponding template and run according to the * - * directions listed in the file. * - ******************************************************************************/ - -using System; -using System.Buffers; -using System.Numerics; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using Xunit; - -namespace JIT.HardwareIntrinsics.Arm -{ - public static partial class Program - { - [Fact] - public static void {TestName}() - { - var test = new LoadNonFaultingUnaryOpTest__{TestName}(); - - if (test.IsSupported) - { - // Validates basic functionality works - test.RunBasicScenario_Load(); - - // Validates basic functionality - test.RunBasicScenario_LoadNonFaulting(); - - // Validates calling via reflection works - test.RunReflectionScenario_Load(); - - // Validates passing an instance member of a class works - test.RunClassFldScenario(); - - // Validates passing the field of a local struct works - test.RunStructLclFldScenario(); - - // Validates passing an instance member of a struct works - test.RunStructFldScenario(); - - // Validates using inside ConditionalSelect with value falseValue - test.ConditionalSelect_FalseOp(); - - // Validates using inside ConditionalSelect with zero falseValue - test.ConditionalSelect_ZeroOp(); - } - else - { - // Validates we throw on unsupported hardware - test.RunUnsupportedScenario(); - } - - if (!test.Succeeded) - { - throw new Exception("One or more scenarios did not complete as expected."); - } - } - } - - public sealed unsafe class LoadNonFaultingUnaryOpTest__{TestName} - { - private struct DataTable - { - private byte[] inArray1; - private byte[] outArray; - - private GCHandle inHandle1; - private GCHandle outHandle; - - private ulong alignment; - - public DataTable({Op1BaseType}[] inArray1, {RetBaseType}[] outArray, int alignment) - { - int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); - int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); - // Choose size of bounded memory such that half of the vector would fall in accessible memory while the rest would in non-accessible one. - int sizeOfInBounded = {RetVectorType}<{RetBaseType}>.Count / 2; - - if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) - { - throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfoutArray: {sizeOfoutArray}"); - } - - this.inArray1 = new byte[alignment * 2]; - this.outArray = new byte[alignment * 2]; - - this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); - this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); - - this.alignment = (ulong)alignment; - this.inBounded = BoundedMemory.Allocate(sizeOfInBounded, PoisonPagePlacement.After); - - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); - Unsafe.CopyBlockUnaligned(ref inBounded.Span.GetPinnableReference(), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfInBounded); - } - - public BoundedMemory inBounded; - - public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); - public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); - - public void Dispose() - { - inHandle1.Free(); - outHandle.Free(); - } - - private static unsafe void* Align(byte* buffer, ulong expectedAlignment) - { - return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); - } - } - - private struct TestStruct - { - public {Op1VectorType}<{RetBaseType}> _fld1; - - public static TestStruct Create() - { - var testStruct = new TestStruct(); - - for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); - - return testStruct; - } - - public void RunStructFldScenario(LoadNonFaultingUnaryOpTest__{TestName} testClass) - { - var result = {Isa}.{Method}(({Op1BaseType}*)testClass._dataTable.inArray1Ptr); - - Unsafe.Write(testClass._dataTable.outArrayPtr, result); - testClass.ValidateResult(testClass._dataTable.inArray1Ptr, testClass._dataTable.outArrayPtr); - } - } - - private static readonly int LargestVectorSize = {LargestVectorSize}; - - private static readonly int Op1ElementCount = Unsafe.SizeOf<{RetVectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); - private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); - - private static {RetBaseType}[] _maskData = new {RetBaseType}[RetElementCount]; - private static {RetBaseType}[] _falseData = new {RetBaseType}[RetElementCount]; - private static {Op1BaseType}[] _data = new {Op1BaseType}[Op1ElementCount]; - - private {Op1VectorType}<{RetBaseType}> _fld1; - private {Op1VectorType}<{RetBaseType}> _mask; - private {Op1VectorType}<{RetBaseType}> _falseFld; - - private DataTable _dataTable; - - public LoadNonFaultingUnaryOpTest__{TestName}() - { - Succeeded = true; - - for (var i = 0; i < RetElementCount; i++) { _maskData[i] = ({RetBaseType})({NextValueOp1} % 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 < RetElementCount; i++) { _falseData[i] = ({RetBaseType})({NextValueOp1} % 50); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{RetBaseType}, byte>(ref _falseData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); - - for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; } - _dataTable = new DataTable(_data, new {RetBaseType}[RetElementCount], LargestVectorSize); - } - - public bool IsSupported => {Isa}.IsSupported; - - public bool Succeeded { get; set; } - - public void RunBasicScenario_Load() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - - var result = {Isa}.{Method}( - ({Op1BaseType}*)(_dataTable.inArray1Ptr) - ); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); - } - - public void RunBasicScenario_LoadNonFaulting() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadNonFaulting)); - - ref var op1Ref = ref _dataTable.inBounded.Span.GetPinnableReference(); - - Sve.SetFfr(Sve.CreateTrueMaskByte(SveMaskPattern.All)); - var result = {Isa}.{Method}(({Op1BaseType}*)(Unsafe.AsPointer(ref op1Ref))); - var faultResult = Sve.GetFfr{GetFfrType}(); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateNonFaultingResult(Unsafe.AsPointer(ref op1Ref), _dataTable.outArrayPtr, faultResult); - } - - public void RunReflectionScenario_Load() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - - var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}*) }) - .Invoke(null, new object[] { - Pointer.Box(_dataTable.inArray1Ptr, typeof({Op1BaseType}*)) - }); - - Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); - } - - public void RunClassFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - - _fld1 = {Isa}.{Method}(({Op1BaseType}*)_dataTable.inArray1Ptr); - - Unsafe.Write(_dataTable.outArrayPtr, _fld1); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); - } - - public void RunStructLclFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); - - var test = TestStruct.Create(); - test._fld1 = {Isa}.{Method}(({Op1BaseType}*)_dataTable.inArray1Ptr); - - Unsafe.Write(_dataTable.outArrayPtr, test._fld1); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); - } - - public void RunStructFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); - - var test = TestStruct.Create(); - test.RunStructFldScenario(this); - } - - public void ConditionalSelect_FalseOp() - { - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _dataTable.inArray1Ptr, _falseFld); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _dataTable.inArray1Ptr, _falseFld); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _dataTable.inArray1Ptr, _falseFld); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _dataTable.inArray1Ptr, _falseFld); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _dataTable.inArray1Ptr, _falseFld); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _dataTable.inArray1Ptr, _falseFld); - } - - public void ConditionalSelect_ZeroOp() - { - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _dataTable.inArray1Ptr, {Op1VectorType}<{RetBaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _dataTable.inArray1Ptr, {Op1VectorType}<{RetBaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _dataTable.inArray1Ptr, {Op1VectorType}<{RetBaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _dataTable.inArray1Ptr, {Op1VectorType}<{RetBaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _dataTable.inArray1Ptr, {Op1VectorType}<{RetBaseType}>.Zero); - - TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _dataTable.inArray1Ptr, {Op1VectorType}<{RetBaseType}>.Zero); - } - - [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}> mask, void* address, {Op1VectorType}<{RetBaseType}> falseOp) - { - var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(({Op1BaseType}*)address), falseOp); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateConditionalSelectResult_TrueValue(mask, address, falseOp, _dataTable.outArrayPtr); - } - - [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}> mask, void* address, {Op1VectorType}<{RetBaseType}> trueOp) - { - var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(({Op1BaseType}*)address)); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateConditionalSelectResult_FalseValue(mask, address, trueOp, _dataTable.outArrayPtr); - } - - public void RunUnsupportedScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); - - Succeeded = false; - - try - { - RunBasicScenario_Load(); - } - catch (PlatformNotSupportedException) - { - Succeeded = true; - } - } - - private void ValidateConditionalSelectResult_TrueValue({Op1VectorType}<{RetBaseType}> maskOp, void* leftOp, {Op1VectorType}<{RetBaseType}> falseOp, void* output, [CallerMemberName] string method = "") - { - {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; - {Op1BaseType}[] left = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] falseVal = new {RetBaseType}[RetElementCount]; - {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; - - Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref left[0]), ref Unsafe.AsRef(leftOp), (uint)Unsafe.SizeOf<{RetVectorType}<{Op1BaseType}>>()); - 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; - - for (var i = 0; i < RetElementCount; i++) - { - {RetBaseType} iterResult = (mask[i] != 0) ? (({RetBaseType})left[i]) : falseVal[i]; - if (iterResult != result[i]) - { - succeeded = false; - break; - } - } - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}*): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); - TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); - TestLibrary.TestFramework.LogInformation($" falseOp: ({string.Join(", ", falseVal)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - - private void ValidateConditionalSelectResult_FalseValue({Op1VectorType}<{RetBaseType}> maskOp, void* leftOp, {Op1VectorType}<{RetBaseType}> trueOp, void* output, [CallerMemberName] string method = "") - { - {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; - {Op1BaseType}[] left = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] trueVal = new {RetBaseType}[RetElementCount]; - {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; - - Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref left[0]), ref Unsafe.AsRef(leftOp), (uint)Unsafe.SizeOf<{RetVectorType}<{Op1BaseType}>>()); - 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; - - for (var i = 0; i < RetElementCount; i++) - { - {RetBaseType} iterResult = (mask[i] != 0) ? trueVal[i] : (({RetBaseType})left[i]); - if (mask[i] != 0) - { - if (iterResult != result[i]) - { - succeeded = false; - break; - } - } - } - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}*): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); - TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); - TestLibrary.TestFramework.LogInformation($" trueOp: ({string.Join(", ", trueVal)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - - private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, void* result, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; - - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateResult(inArray1, outArray, method); - } - - private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; - - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf<{RetVectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateResult(inArray, outArray, method); - } - - private void ValidateResult({Op1BaseType}[] firstOp, {RetBaseType}[] result, [CallerMemberName] string method = "") - { - bool succeeded = true; - - for (var i = 0; i < RetElementCount; i++) - { - if ({ValidateIterResult}) - { - succeeded = false; - break; - } - } - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - - private void ValidateZeroResult(void* firstOp, void* result, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; - - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf<{RetVectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateZeroResult(inArray, outArray, method); - } - - private void ValidateNonFaultingResult(void* firstOp, void* result, Vector<{GetFfrType}> faultResult, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; - {GetFfrType}[] faultArray = new {GetFfrType}[RetElementCount]; - - // Only read bytes mapping to half of the destination vector. The remaining elements are in the poison page. - // It would make inArray to contain elements that could read without a fault followed by zeros. - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), ref Unsafe.AsRef(firstOp), ((uint){RetVectorType}<{RetBaseType}>.Count / 2) ); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - fixed({GetFfrType}* faultArrayPtr = &faultArray[0]) - { - Unsafe.Write(faultArrayPtr, faultResult); - } - - bool succeeded = true; - - for (var i = 0; i < RetElementCount; i++) - { - var expectedOut = ({RetBaseType})((i < (RetElementCount / 2)) ? inArray[i] : 0); - var expectedFault = ({GetFfrType}) ((i < (RetElementCount / 2)) ? 1 : 0); - - if ((outArray[i] != expectedOut) && (faultArray[i] != expectedFault) ) - { - succeeded = false; - break; - } - } - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", inArray)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", outArray)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - Succeeded = false; - } - } - - private void ValidateZeroResult({Op1BaseType}[] firstOp, {RetBaseType}[] result, [CallerMemberName] string method = "") - { - bool succeeded = true; - - for (var i = 0; i < RetElementCount; i++) - { - if (result[i] != 0) - { - succeeded = false; - break; - } - } - - if (!succeeded) - { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; - } - } - } -} \ No newline at end of file diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpDifferentRetTypeTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpDifferentRetTypeTestTemplate.template index 2d2df308eb2e8e..ad9531b94c7f79 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpDifferentRetTypeTestTemplate.template +++ b/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/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImm2TernOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImm2TernOpTestTemplate.template index aaa8c0718bee08..b347522c05a587 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImm2TernOpTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImm2TernOpTestTemplate.template @@ -100,11 +100,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) { @@ -124,8 +124,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); @@ -150,8 +150,8 @@ namespace JIT.HardwareIntrinsics.Arm private struct TestStruct { public {Op1VectorType}<{Op1BaseType}> _fld1; - public {Op1VectorType}<{Op1BaseType}> _fld2; - public {Op1VectorType}<{Op1BaseType}> _fld3; + public {Op2VectorType}<{Op2BaseType}> _fld2; + public {Op3VectorType}<{Op3BaseType}> _fld3; public static TestStruct Create() { @@ -159,10 +159,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<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3VectorType}<{Op3BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>()); return testStruct; } @@ -179,20 +179,25 @@ 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}<{Op1BaseType}>>() / sizeof({Op2BaseType}); + private static readonly int Op3ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op3BaseType}); private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); private static readonly byte Imm1 = {Imm1}; private static readonly byte Imm2 = {Imm2}; - private static {Op1BaseType}[] _maskData = new {Op1BaseType}[Op1ElementCount]; + private static {RetBaseType}[] _maskData = new {Op1BaseType}[Op1ElementCount]; 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 {RetVectorType}<{RetBaseType}> _mask; private {Op1VectorType}<{Op1BaseType}> _fld1; - private {Op1VectorType}<{Op1BaseType}> _fld2; - private {Op1VectorType}<{Op1BaseType}> _fld3; - private {Op1VectorType}<{Op1BaseType}> _falseFld; + private {Op2VectorType}<{Op2BaseType}> _fld2; + private {Op3VectorType}<{Op3BaseType}> _fld3; + + private {RetVectorType}<{RetBaseType}> _trueFld; + private {RetVectorType}<{RetBaseType}> _falseFld; + private {RetVectorType}<{RetBaseType}> _fld2_retType; private DataTable _dataTable; @@ -200,19 +205,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 < Op1ElementCount; i++) { _maskData[i] = ({RetBaseType})({NextValueMask} % 2); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _mask), ref Unsafe.As<{RetBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); 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 < 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}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _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<{Op3VectorType}<{Op3BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _trueFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _fld2_retType), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{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); } @@ -226,8 +234,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<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr), {Imm1}, {Imm2} ); @@ -245,8 +253,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<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr), {InvalidImm1}, {Imm2} ); @@ -272,8 +280,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<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr), {Imm1}, {InvalidImm2} ); @@ -294,12 +302,14 @@ namespace JIT.HardwareIntrinsics.Arm { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); + {Op1VectorType}<{Op1BaseType}> loadMask1 = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); + {Op2VectorType}<{Op2BaseType}> loadMask2 = Sve.CreateTrueMask{Op2BaseType}(SveMaskPattern.All); + {Op3VectorType}<{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}(loadMask1, ({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.Load{Op2VectorType}(loadMask2, ({Op2BaseType}*)(_dataTable.inArray2Ptr)), + {LoadIsa}.Load{Op3VectorType}(loadMask3, ({Op3BaseType}*)(_dataTable.inArray3Ptr)), {Imm1}, {Imm2} ); @@ -312,11 +322,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), typeof(byte) }) + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof({Op3VectorType}<{Op3BaseType}>), typeof(byte), 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<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr), (byte){Imm1}, (byte){Imm2} }); @@ -330,8 +340,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<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); + var op3 = Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr); var result = {Isa}.{Method}(op1, op2, op3, {Imm1}, {Imm2}); Unsafe.Write(_dataTable.outArrayPtr, result); @@ -370,64 +380,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, _trueFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _trueFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _trueFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _trueFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _trueFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _trueFld); } 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, _fld2_retType); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _fld2_retType); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld2_retType); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld2_retType); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _fld2_retType); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld2_retType); } 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, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); } public void ConditionalSelect_FalseOp() @@ -436,19 +446,19 @@ 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({RetVectorType}<{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({RetVectorType}<{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({RetVectorType}<{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({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); } public void ConditionalSelect_ZeroOp() @@ -457,23 +467,23 @@ namespace JIT.HardwareIntrinsics.Arm ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, {RetVectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {RetVectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in FalseValue"); ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, {RetVectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {RetVectorType}<{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({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {Op3VectorType}<{Op3BaseType}> op3, {RetVectorType}<{RetBaseType}> falseOp) { var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3, {Imm1}, {Imm2}), falseOp); Unsafe.Write(_dataTable.outArrayPtr, result); @@ -481,7 +491,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({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {Op3VectorType}<{Op3BaseType}> op3, {RetVectorType}<{RetBaseType}> trueOp) { var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op1, op2, op3, {Imm1}, {Imm2})); Unsafe.Write(_dataTable.outArrayPtr, result); @@ -509,25 +519,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({RetVectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op2VectorType}<{Op2BaseType}> secondOp, {Op3VectorType}<{Op3BaseType}> thirdOp, {RetVectorType}<{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 {Op1BaseType}[Op1ElementCount]; {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}>, {Op2VectorType}<{Op2BaseType}>, {Op3VectorType}<{Op3BaseType}>): {method} failed:"); TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); TestLibrary.TestFramework.LogInformation($" first: ({string.Join(", ", first)})"); TestLibrary.TestFramework.LogInformation($" second: ({string.Join(", ", second)})"); @@ -539,27 +549,28 @@ 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({RetVectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op2VectorType}<{Op2BaseType}> secondOp, {Op3VectorType}<{Op3BaseType}> thirdOp, {RetVectorType}<{RetBaseType}> trueOp, 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}[] 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; {TemplateValidationLogicForCndSel_FalseValue} - + 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}>, {Op2VectorType}<{Op2BaseType}>, {Op3VectorType}<{Op3BaseType}>): {method} failed:"); TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); TestLibrary.TestFramework.LogInformation($" first: ({string.Join(", ", first)})"); TestLibrary.TestFramework.LogInformation($" second: ({string.Join(", ", second)})"); @@ -571,16 +582,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, {Op2VectorType}<{Op2BaseType}> op2, {Op3VectorType}<{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); @@ -589,19 +600,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<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(op3), (uint)Unsafe.SizeOf<{Op3VectorType}<{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; diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpDifferentRetTypeTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpDifferentRetTypeTestTemplate.template new file mode 100644 index 00000000000000..7daa1fbd1a7d4c --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpDifferentRetTypeTestTemplate.template @@ -0,0 +1,556 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics.Arm\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Linq; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using Xunit; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + [Fact] + public static void {TestName}() + { + var test = new {TemplateName}BinaryOpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + // 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(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + // Validates executing the test inside conditional, with op1 as falseValue + test.ConditionalSelect_Op1(); + + // Validates executing the test inside conditional, with op2 as falseValue + test.ConditionalSelect_Op2(); + + // Validates executing the test inside conditional, with op3 as falseValue + test.ConditionalSelect_FalseOp(); + + // Validates executing the test inside conditional, with op3 as zero + test.ConditionalSelect_ZeroOp(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class {TemplateName}BinaryOpTest__{TestName} + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({Op1BaseType}[] inArray1, {Op2BaseType}[] inArray2, {RetBaseType}[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfinArray2: {sizeOfinArray2}, sizeOfoutArray: {sizeOfoutArray}"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld1; + public {Op2VectorType}<{Op2BaseType}> _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + + return testStruct; + } + + public void RunStructFldScenario({TemplateName}BinaryOpTest__{TestName} testClass) + { + var result = {Isa}.{Method}(_fld1, _fld2, {Imm}); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + private static readonly byte Imm = {Imm}; + + private static {RetBaseType}[] _maskData = new {RetBaseType}[RetElementCount]; + private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount]; + + private {RetVectorType}<{RetBaseType}> _mask; + private {Op1VectorType}<{Op1BaseType}> _fld1; + private {Op2VectorType}<{Op2BaseType}> _fld2; + + private {RetVectorType}<{RetBaseType}> _trueFld; + private {RetVectorType}<{RetBaseType}> _falseFld; + + private DataTable _dataTable; + + public {TemplateName}BinaryOpTest__{TestName}() + { + Succeeded = true; + + for (var i = 0; i < RetElementCount; i++) { _maskData[i] = ({RetBaseType})({NextValueOp1} % 2); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _mask), ref Unsafe.As<{RetBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{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}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _trueFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + _dataTable = new DataTable(_data1, _data2, new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); + {Op2VectorType}<{Op2BaseType}> loadMask2 = Sve.CreateTrueMask{Op2BaseType}(SveMaskPattern.All); + + + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.Load{Op2VectorType}(loadMask2, ({Op2BaseType}*)(_dataTable.inArray2Ptr)), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + (byte){Imm} + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); + var result = {Isa}.{Method}(op1, op2, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunSameLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunSameLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray1Ptr); + var result = {Isa}.{Method}(op1, op2, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld1, _fld2, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunSameClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunSameClassFldScenario)); + + var _fld1_op2Base = Unsafe.As<{Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>>(ref _fld1); + + var result = {Isa}.{Method}(_fld1, _fld1_op2Base, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld1_op2Base, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld1, test._fld2, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void ConditionalSelect_Op1() + { + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask - operation in TrueValue"); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _trueFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in TrueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _trueFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in TrueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _trueFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask - operation in FalseValue"); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _trueFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in FalseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _trueFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in FalseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _trueFld); + } + + public void ConditionalSelect_Op2() + { + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_mask - operation in TrueValue"); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_zero - operation in TrueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_all - operation in TrueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_mask - operation in FalseValue"); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_zero - operation in FalseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_all - operation in FalseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _falseFld); + } + + + public void ConditionalSelect_FalseOp() + { + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in TrueValue"); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in TrueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in TrueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in FalseValue"); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in FalseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in FalseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _falseFld); + } + + public void ConditionalSelect_ZeroOp() + { + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in TrueValue"); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in TrueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in TrueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in FalseValue"); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in FalseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _fld2, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in FalseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, {RetVectorType}<{RetBaseType}>.Zero); + } + + [method: MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {RetVectorType}<{RetBaseType}> falseOp) + { + var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, Imm), falseOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateConditionalSelectResult_TrueValue(mask, op1, op2, falseOp, _dataTable.outArrayPtr); + } + + [method: MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {RetVectorType}<{RetBaseType}> trueOp) + { + var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op1, op2, Imm)); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateConditionalSelectResult_FalseValue(mask, op1, op2, trueOp, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateConditionalSelectResult_TrueValue({RetVectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> leftOp, {Op2VectorType}<{Op2BaseType}> rightOp, {RetVectorType}<{RetBaseType}> falseOp, void* output, [CallerMemberName] string method = "") + { + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; + {Op1BaseType}[] left = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] right = new {Op2BaseType}[Op2ElementCount]; + {RetBaseType}[] falseVal = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref left[0]), leftOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref right[0]), rightOp); + 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}>, {Op2VectorType}<{Op2BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" falseOp: ({string.Join(", ", falseVal)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + + private void ValidateConditionalSelectResult_FalseValue({RetVectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> leftOp, {Op2VectorType}<{Op2BaseType}> rightOp, {RetVectorType}<{RetBaseType}> trueOp, void* output, [CallerMemberName] string method = "") + { + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; + {Op1BaseType}[] left = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] right = new {Op2BaseType}[Op2ElementCount]; + {RetBaseType}[] trueVal = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref left[0]), leftOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref right[0]), rightOp); + 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; + + {TemplateValidationLogicForCndSel_FalseValue} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" trueOp: ({string.Join(", ", trueVal)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + + private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult({Op1BaseType}[] left, {Op2BaseType}[] right, {RetBaseType}[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + {TemplateValidationLogic} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation(string.Empty); + 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)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template index 4708815e3ba0e6..45907adb29e4ac 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template +++ b/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/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template index 9ce3a334f7d7ad..4117cecd4dde63 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template +++ b/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/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmUnaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmUnaryOpTestTemplate.template index 7b73bd5f3deb15..375e0d9effe0c2 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmUnaryOpTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmUnaryOpTestTemplate.template @@ -126,7 +126,6 @@ namespace JIT.HardwareIntrinsics.Arm private struct TestStruct { public {Op1VectorType}<{Op1BaseType}> _fld; - public byte _imm; public static TestStruct Create() { @@ -134,17 +133,16 @@ namespace JIT.HardwareIntrinsics.Arm for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - testStruct._imm = (byte)({Imm}); return testStruct; } public void RunStructFldScenario({TemplateName}UnaryOpTest__{TestName} testClass) { - var result = {Isa}.{Method}(_fld, _imm); + var result = {Isa}.{Method}(_fld, {Imm}); Unsafe.Write(testClass._dataTable.outArrayPtr, result); - testClass.ValidateResult(_fld, _imm, testClass._dataTable.outArrayPtr); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); } } @@ -152,7 +150,7 @@ namespace JIT.HardwareIntrinsics.Arm private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); - private static readonly byte Imm = (byte)({Imm}); + private static readonly byte Imm = {Imm}; private static {RetBaseType}[] _maskData = new {RetBaseType}[RetElementCount]; private static {Op1BaseType}[] _data = new {Op1BaseType}[Op1ElementCount]; @@ -189,11 +187,11 @@ namespace JIT.HardwareIntrinsics.Arm var result = {Isa}.{Method}( Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr), - Imm + {Imm} ); Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArrayPtr, Imm, _dataTable.outArrayPtr); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); } public void RunBasicScenario_UnsafeRead_InvalidImm() @@ -227,11 +225,11 @@ namespace JIT.HardwareIntrinsics.Arm var result = {Isa}.{Method}( {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArrayPtr)), - Imm + {Imm} ); Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArrayPtr, Imm, _dataTable.outArrayPtr); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); } public void RunReflectionScenario_UnsafeRead() @@ -241,11 +239,11 @@ namespace JIT.HardwareIntrinsics.Arm var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof(byte) }) .Invoke(null, new object[] { Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr), - Imm + (byte){Imm} }); Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); - ValidateResult(_dataTable.inArrayPtr, Imm, _dataTable.outArrayPtr); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); } public void RunLclVarScenario_UnsafeRead() @@ -253,20 +251,20 @@ namespace JIT.HardwareIntrinsics.Arm TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); var op = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr); - var result = {Isa}.{Method}(op, Imm); + var result = {Isa}.{Method}(op, {Imm}); Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(op, Imm, _dataTable.outArrayPtr); + ValidateResult(op, _dataTable.outArrayPtr); } public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = {Isa}.{Method}(_fld, Imm); + var result = {Isa}.{Method}(_fld, {Imm}); Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_fld, Imm, _dataTable.outArrayPtr); + ValidateResult(_fld, _dataTable.outArrayPtr); } public void RunStructLclFldScenario() @@ -274,10 +272,10 @@ namespace JIT.HardwareIntrinsics.Arm TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = {Isa}.{Method}(test._fld, test._imm); + var result = {Isa}.{Method}(test._fld, {Imm}); Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(test._fld, test._imm, _dataTable.outArrayPtr); + ValidateResult(test._fld, _dataTable.outArrayPtr); } public void RunStructFldScenario() @@ -354,7 +352,7 @@ namespace JIT.HardwareIntrinsics.Arm [method: MethodImpl(MethodImplOptions.AggressiveInlining)] private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op, {RetVectorType}<{RetBaseType}> falseOp) { - var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op, Imm), falseOp); + var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op, {Imm}), falseOp); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateConditionalSelectResult_TrueValue(mask, op, falseOp, Imm, _dataTable.outArrayPtr); } @@ -362,7 +360,7 @@ namespace JIT.HardwareIntrinsics.Arm [method: MethodImpl(MethodImplOptions.AggressiveInlining)] private void ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op, {RetVectorType}<{RetBaseType}> trueOp) { - var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op, Imm)); + var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op, {Imm})); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateConditionalSelectResult_FalseValue(mask, op, trueOp, Imm, _dataTable.outArrayPtr); } @@ -440,7 +438,7 @@ namespace JIT.HardwareIntrinsics.Arm } } - private void ValidateResult({Op1VectorType}<{Op1BaseType}> op, byte imm, void* result, [CallerMemberName] string method = "") + private void ValidateResult({Op1VectorType}<{Op1BaseType}> op, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount]; {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; @@ -448,10 +446,10 @@ namespace JIT.HardwareIntrinsics.Arm Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), op); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - ValidateResult(inArray, imm, outArray, method); + ValidateResult(inArray, outArray, method); } - private void ValidateResult(void* op, byte imm, void* result, [CallerMemberName] string method = "") + private void ValidateResult(void* op, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount]; {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; @@ -459,10 +457,10 @@ namespace JIT.HardwareIntrinsics.Arm Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), ref Unsafe.AsRef(op), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - ValidateResult(inArray, imm, outArray, method); + ValidateResult(inArray, outArray, method); } - private void ValidateResult({Op1BaseType}[] firstOp, byte imm, {RetBaseType}[] result, [CallerMemberName] string method = "") + private void ValidateResult({Op1BaseType}[] firstOp, {RetBaseType}[] result, [CallerMemberName] string method = "") { bool succeeded = true; @@ -472,7 +470,7 @@ namespace JIT.HardwareIntrinsics.Arm { TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, byte): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); - TestLibrary.TestFramework.LogInformation($" imm: ({string.Join(", ", imm)})"); + TestLibrary.TestFramework.LogInformation($" imm: ({string.Join(", ", Imm)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); TestLibrary.TestFramework.LogInformation(string.Empty); diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveTernOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveTernOpTestTemplate.template index 13343926763ced..bdce7267163799 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveTernOpTestTemplate.template +++ b/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/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpTestTemplate.template index 236831a88bf28a..d597ba4424fa1a 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpTestTemplate.template @@ -24,17 +24,13 @@ namespace JIT.HardwareIntrinsics.Arm public static void {TestName}() { var test = new {TemplateName}UnaryOpTest__{TestName}(); - if (test.IsSupported) { // Validates basic functionality works, using Unsafe.Read test.RunBasicScenario_UnsafeRead(); - if ({LoadIsa}.IsSupported) - { - // Validates basic functionality works, using Load - test.RunBasicScenario_Load(); - } + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); // Validates calling via reflection works, using Unsafe.Read test.RunReflectionScenario_UnsafeRead(); @@ -75,62 +71,14 @@ namespace JIT.HardwareIntrinsics.Arm public sealed unsafe class {TemplateName}UnaryOpTest__{TestName} { - private struct DataTable - { - private byte[] inArray1; - private byte[] outArray; - - private GCHandle inHandle1; - private GCHandle outHandle; - - private ulong alignment; - - public DataTable({Op1BaseType}[] inArray1, {RetBaseType}[] outArray, int alignment) - { - int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); - int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); - if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) - { - throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfoutArray: {sizeOfoutArray}"); - } - - this.inArray1 = new byte[alignment * 2]; - this.outArray = new byte[alignment * 2]; - - this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); - this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); - - this.alignment = (ulong)alignment; - - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); - } - - public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); - public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); - - public void Dispose() - { - inHandle1.Free(); - outHandle.Free(); - } - - private static unsafe void* Align(byte* buffer, ulong expectedAlignment) - { - return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); - } - } - private struct TestStruct { - public {Op1VectorType}<{Op1BaseType}> _fld1; + public Vector<{Op1BaseType}> _fld1; - public static TestStruct Create() + public static TestStruct Create(Vector<{Op1BaseType}> vec) { var testStruct = new TestStruct(); - - for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - + testStruct._fld1 = vec; return testStruct; } @@ -138,91 +86,76 @@ namespace JIT.HardwareIntrinsics.Arm { var result = {Isa}.{Method}(_fld1); - Unsafe.Write(testClass._dataTable.outArrayPtr, result); - testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + testClass.ValidateResult(_fld1, result); } } private static readonly int LargestVectorSize = {LargestVectorSize}; - private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); - private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof({Op1BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof({RetBaseType}); - private static {Op1BaseType}[] _maskData = new {Op1BaseType}[Op1ElementCount]; - private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; - - private {Op1VectorType}<{Op1BaseType}> _mask; - private {Op1VectorType}<{Op1BaseType}> _fld1; - private {Op1VectorType}<{Op1BaseType}> _falseFld; - - private DataTable _dataTable; + private Vector<{Op1BaseType}> _mask; + private Vector<{Op1BaseType}> _fld1; + private Vector<{Op1BaseType}> _falseFld; + private TestLibrary.Vectors.PinnedVector<{Op1BaseType}> _pinnedOp1; public {TemplateName}UnaryOpTest__{TestName}() { 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 < 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}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - - for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - _dataTable = new DataTable(_data1, new {RetBaseType}[RetElementCount], LargestVectorSize); + _mask = TestLibrary.Vectors.GetRandomMask<{Op1BaseType}>(); + _fld1 = TestLibrary.Vectors.GetRandomVector<{Op1BaseType}>(); + _falseFld = _fld1; + _pinnedOp1 = new TestLibrary.Vectors.PinnedVector<{Op1BaseType}>(_fld1, LargestVectorSize); } public bool IsSupported => {Isa}.IsSupported; - - public bool Succeeded { get; set; } + public bool Succeeded; public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = {Isa}.{Method}( - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr) - ); + var result = {Isa}.{Method}(_pinnedOp1.Value); - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + ValidateResult(_pinnedOp1.Value, result); } public void RunBasicScenario_Load() { - TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + if ({LoadIsa}.IsSupported) + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); + Vector<{Op1BaseType}> loadMask = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); - var result = {Isa}.{Method}( - {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray1Ptr)) - ); + var result = {Isa}.{Method}( + {LoadIsa}.LoadVector(loadMask, ({Op1BaseType}*)(_pinnedOp1.Ptr)) + ); - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + ValidateResult(_pinnedOp1.Value, result); + } } public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) }) - .Invoke(null, new object[] { - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr) - }); + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof(Vector<{Op1BaseType}>) }) + .Invoke(null, new object[] { _pinnedOp1.Value }); - Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); - ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + ValidateResult(_pinnedOp1.Value, (Vector<{RetBaseType}>)result); } public void RunLclVarScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); - var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); + var op1 = _pinnedOp1.Value; var result = {Isa}.{Method}(op1); - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(op1, _dataTable.outArrayPtr); + ValidateResult(op1, result); } public void RunClassFldScenario() @@ -231,26 +164,24 @@ namespace JIT.HardwareIntrinsics.Arm var result = {Isa}.{Method}(_fld1); - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_fld1, _dataTable.outArrayPtr); + ValidateResult(_fld1, result); } public void RunStructLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); - var test = TestStruct.Create(); + var test = TestStruct.Create(_fld1); var result = {Isa}.{Method}(test._fld1); - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(test._fld1, _dataTable.outArrayPtr); + ValidateResult(test._fld1, result); } public void RunStructFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); - var test = TestStruct.Create(); + var test = TestStruct.Create(_fld1); test.RunStructFldScenario(this); } @@ -258,89 +189,83 @@ namespace JIT.HardwareIntrinsics.Arm { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask - operation in trueValue"); ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld1); - + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in trueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld1); - + ConditionalSelectScenario_TrueValue(Vector<{Op1BaseType}>.Zero, _fld1, _fld1); + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in trueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld1); + ConditionalSelectScenario_TrueValue(Vector<{Op1BaseType}>.AllBitsSet, _fld1, _fld1); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask - operation in falseValue"); ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld1); - + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in falseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld1); - + ConditionalSelectScenario_FalseValue(Vector<{Op1BaseType}>.Zero, _fld1, _fld1); + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in falseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld1); + ConditionalSelectScenario_FalseValue(Vector<{Op1BaseType}>.AllBitsSet, _fld1, _fld1); } public void ConditionalSelect_FalseOp() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in trueValue"); ConditionalSelectScenario_TrueValue(_mask, _fld1, _falseFld); - + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in trueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _falseFld); - + ConditionalSelectScenario_TrueValue(Vector<{Op1BaseType}>.Zero, _fld1, _falseFld); + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in trueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _falseFld); + ConditionalSelectScenario_TrueValue(Vector<{Op1BaseType}>.AllBitsSet, _fld1, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in falseValue"); ConditionalSelectScenario_FalseValue(_mask, _fld1, _falseFld); - + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in falseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _falseFld); - + ConditionalSelectScenario_FalseValue(Vector<{Op1BaseType}>.Zero, _fld1, _falseFld); + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in falseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _falseFld); + ConditionalSelectScenario_FalseValue(Vector<{Op1BaseType}>.AllBitsSet, _fld1, _falseFld); } public void ConditionalSelect_ZeroOp() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in trueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, {Op1VectorType}<{Op1BaseType}>.Zero); - + ConditionalSelectScenario_TrueValue(_mask, _fld1, Vector<{Op1BaseType}>.Zero); + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in trueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, {Op1VectorType}<{Op1BaseType}>.Zero); - + ConditionalSelectScenario_TrueValue(Vector<{Op1BaseType}>.Zero, _fld1, Vector<{Op1BaseType}>.Zero); + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in trueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue(Vector<{Op1BaseType}>.AllBitsSet, _fld1, Vector<{Op1BaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in falseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, {Op1VectorType}<{Op1BaseType}>.Zero); - + ConditionalSelectScenario_FalseValue(_mask, _fld1, Vector<{Op1BaseType}>.Zero); + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in falseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, {Op1VectorType}<{Op1BaseType}>.Zero); - + ConditionalSelectScenario_FalseValue(Vector<{Op1BaseType}>.Zero, _fld1, Vector<{Op1BaseType}>.Zero); + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in falseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, {Op1VectorType}<{Op1BaseType}>.Zero); - } + ConditionalSelectScenario_FalseValue(Vector<{Op1BaseType}>.AllBitsSet, _fld1, Vector<{Op1BaseType}>.Zero); + } [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> falseOp) + private void ConditionalSelectScenario_TrueValue(Vector<{Op1BaseType}> mask, Vector<{Op1BaseType}> op1, Vector<{Op1BaseType}> falseOp) { var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1), falseOp); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateConditionalSelectResult_TrueValue(mask, op1, falseOp, _dataTable.outArrayPtr); + ValidateConditionalSelectResult(mask, op1, falseOp, result); } [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> trueOp) + private void ConditionalSelectScenario_FalseValue(Vector<{Op1BaseType}> mask, Vector<{Op1BaseType}> op1, Vector<{Op1BaseType}> trueOp) { var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op1)); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateConditionalSelectResult_FalseValue(mask, op1, trueOp, _dataTable.outArrayPtr); - } + ValidateConditionalSelectResult(mask, op1, trueOp, result, false); + } public void RunUnsupportedScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); - bool succeeded = false; - try { RunBasicScenario_UnsafeRead(); @@ -356,96 +281,68 @@ namespace JIT.HardwareIntrinsics.Arm } } - private void ValidateConditionalSelectResult_TrueValue({Op1VectorType}<{Op1BaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> leftOp, {Op1VectorType}<{Op1BaseType}> falseOp, void* output, [CallerMemberName] string method = "") + private void ValidateConditionalSelectResult( + Vector<{Op1BaseType}> maskOp, + Vector<{Op1BaseType}> left, + Vector<{Op1BaseType}> cond, + Vector<{RetBaseType}> output, + bool trueMode = true, + [CallerMemberName] string method = "") { {Op1BaseType}[] mask = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] left = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] falseVal = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] leftOp = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] condVal = new {Op1BaseType}[Op1ElementCount]; {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref mask[0]), maskOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref left[0]), leftOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, 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} + TestLibrary.Vectors.VectorToArray(ref mask, maskOp); + TestLibrary.Vectors.VectorToArray(ref leftOp, left); + TestLibrary.Vectors.VectorToArray(ref condVal, cond); + TestLibrary.Vectors.VectorToArray(ref result, output); - if (!succeeded) + {RetBaseType}[] expected = new {RetBaseType}[RetElementCount]; + for (var i = 0; i < RetElementCount; i++) { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); - TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); - TestLibrary.TestFramework.LogInformation($" falseOp: ({string.Join(", ", falseVal)})"); - TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); - TestLibrary.TestFramework.LogInformation(string.Empty); - - Succeeded = false; + if (trueMode) + { + expected[i] = (mask[i] != 0) ? {GetIterResult} : condVal[i]; + } + else + { + expected[i] = (mask[i] == 0) ? {GetIterResult} : condVal[i]; + } } - } - - private void ValidateConditionalSelectResult_FalseValue({Op1VectorType}<{Op1BaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> leftOp, {Op1VectorType}<{Op1BaseType}> trueOp, void* output, [CallerMemberName] string method = "") - { - {Op1BaseType}[] mask = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] left = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] trueVal = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref mask[0]), maskOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref left[0]), leftOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, 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; - - {TemplateValidationLogicForCndSel_FalseValue} - - if (!succeeded) + if (!expected.SequenceEqual(result)) { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>(Vector<{Op1BaseType}>, Vector<{Op1BaseType}>): {method} failed:"); TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); - TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); - TestLibrary.TestFramework.LogInformation($" trueOp: ({string.Join(", ", trueVal)})"); + TestLibrary.TestFramework.LogInformation($" leftOp: ({string.Join(", ", leftOp)})"); + TestLibrary.TestFramework.LogInformation($" cond: ({string.Join(", ", condVal)})"); + TestLibrary.TestFramework.LogInformation($"expected: ({string.Join(", ", expected)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); TestLibrary.TestFramework.LogInformation(string.Empty); Succeeded = false; } - } - - private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, void* result, [CallerMemberName] string method = "") - { - {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; - - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateResult(inArray1, outArray, method); } - private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + private void ValidateResult(Vector<{Op1BaseType}> leftOp, Vector<{RetBaseType}> result, [CallerMemberName] string method = "") { - {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {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<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); - - ValidateResult(inArray1, outArray, method); - } + {RetBaseType}[] expected = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] resultArr = new {RetBaseType}[RetElementCount]; - private void ValidateResult({Op1BaseType}[] firstOp, {RetBaseType}[] result, [CallerMemberName] string method = "") - { - bool succeeded = true; + TestLibrary.Vectors.VectorToArray(ref resultArr, result); - {TemplateValidationLogic} + for (int i = 0; i < resultArr.Length; i++) + { + expected[i] = {GetIterResult}; + } - if (!succeeded) + if (!expected.SequenceEqual(resultArr)) { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>): {method} failed:"); - TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>(Vector<{Op1BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" leftOp: ({string.Join(", ", leftOp)})"); + TestLibrary.TestFramework.LogInformation($"expected: ({string.Join(", ", expected)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); TestLibrary.TestFramework.LogInformation(string.Empty); diff --git a/src/tests/JIT/HardwareIntrinsics/General/Directory.Build.targets b/src/tests/JIT/HardwareIntrinsics/General/Directory.Build.targets index f9b37627ce70ab..ebed4cabf5e282 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Directory.Build.targets +++ b/src/tests/JIT/HardwareIntrinsics/General/Directory.Build.targets @@ -9,7 +9,7 @@ diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Program.Vector128_1.cs b/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Program.Vector128_1.cs index 5bd034ce1e0be5..ce7efa5c7e04a4 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Program.Vector128_1.cs +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Program.Vector128_1.cs @@ -5,8 +5,6 @@ using System.Collections.Generic; using Xunit; -[assembly:ActiveIssue("https://github.com/dotnet/runtime/issues/54122", TestPlatforms.Browser)] - namespace JIT.HardwareIntrinsics.General._Vector128_1 { public static partial class Program diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Program.Vector256_1.cs b/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Program.Vector256_1.cs index bfccc8223160a7..89ee9c201e1641 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Program.Vector256_1.cs +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Program.Vector256_1.cs @@ -5,8 +5,6 @@ using System.Collections.Generic; using Xunit; -[assembly:ActiveIssue("https://github.com/dotnet/runtime/issues/54122", TestPlatforms.Browser)] - namespace JIT.HardwareIntrinsics.General._Vector256_1 { public static partial class Program diff --git a/src/tests/JIT/Methodical/Arrays/misc/arrres.cs b/src/tests/JIT/Methodical/Arrays/misc/arrres.cs index 64391cf0feae36..f453c0ee4672cd 100644 --- a/src/tests/JIT/Methodical/Arrays/misc/arrres.cs +++ b/src/tests/JIT/Methodical/Arrays/misc/arrres.cs @@ -13,7 +13,7 @@ public class Test public bool m_die; private static Test[] s_arr = new Test[50]; - public Test(int indx) { _indx = indx; } + private Test(int indx) { _indx = indx; } internal virtual void CheckValid() { diff --git a/src/tests/JIT/Methodical/Boxing/callconv/instance.cs b/src/tests/JIT/Methodical/Boxing/callconv/instance.cs index 69f035950619f4..0c70cc18945bc0 100644 --- a/src/tests/JIT/Methodical/Boxing/callconv/instance.cs +++ b/src/tests/JIT/Methodical/Boxing/callconv/instance.cs @@ -38,7 +38,7 @@ protected override object Fibonacci2(object num, object flag) return N; } - public Test(object num) + private Test(object num) { _num = (float)(double)num; } diff --git a/src/tests/JIT/Methodical/structs/ExplicitLayout.cs b/src/tests/JIT/Methodical/structs/ExplicitLayout.cs index eafba1a5c8783e..2123f1d7f3c431 100644 --- a/src/tests/JIT/Methodical/structs/ExplicitLayout.cs +++ b/src/tests/JIT/Methodical/structs/ExplicitLayout.cs @@ -26,36 +26,67 @@ internal unsafe struct TestStruct } #pragma warning restore 618 + [StructLayout(LayoutKind.Explicit)] + public class ExplicitBase + { + [FieldOffset(8)] public object? m_objectField; + [FieldOffset(0)] public double m_doubleField; + + public double DoubleValue + { + get => m_doubleField; + set => m_doubleField = value; + } + } + + [StructLayout(LayoutKind.Explicit)] + public class EmptyExplicitClassDerivingFromExplicitClass : ExplicitBase + { + } + + public class AutoDerivingFromEmptyExplicitClass : EmptyExplicitClassDerivingFromExplicitClass + { + string MyStringField; + + public AutoDerivingFromEmptyExplicitClass(string fieldValue = "Default Value") + { + MyStringField = fieldValue; + } + + public string GetMyStringField() + { + return MyStringField; + } + } + public class Program { [Fact] [OuterLoop] - public static int TestEntrypoint() + public static void ExplicitLayoutStruct() { - int returnVal = 100; - TestStruct t = new TestStruct(); t.Guid1 = Guid.NewGuid(); t.Guid2 = t.Guid1; - if (t.Guid1 != t.Guid2) - { - Console.WriteLine("FAIL self-copy"); - returnVal = -1; - } + Assert.Equal(t.Guid1, t.Guid2); TestStruct t2 = new TestStruct(); Guid newGuid = Guid.NewGuid(); t2.Guid1 = newGuid; t2.Guid2 = newGuid; - if (t2.Guid1 != t2.Guid2) - { - Console.WriteLine("FAIL other-copy"); - returnVal = -1; - } + Assert.Equal(t2.Guid1, t2.Guid2); + } + + [Fact] + public static void EmptyExplicitClass() + { + AutoDerivingFromEmptyExplicitClass emptyDirectBase = new("AutoDerivingFromEmptyExplicitClass"); + + emptyDirectBase.DoubleValue = 17.0; - return returnVal; + Assert.Equal("AutoDerivingFromEmptyExplicitClass", emptyDirectBase.GetMyStringField()); } } } diff --git a/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/harness-helpers.cs b/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/harness-helpers.cs index 7560e3755cf40b..5d7c80fa1a94e7 100644 --- a/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/harness-helpers.cs +++ b/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/harness-helpers.cs @@ -25,14 +25,14 @@ public TestHarnessHelpers(bool bigInput, [System.Runtime.CompilerServices.Caller expectedCountLetter = new int[] { 302923, 301375, 198136, 197566 }; expectedCountPairs = new int[] { 91779, 91253, 91225, 90837, 60096, 60030, 59889, 59795, 59756, 59713, 59572, 59557, 39203, 39190, 39081, 39023 }; expectedCountFragments = new int[] { 11765, 3572, 380, 7, 7 }; - resourceName = $"{Path.GetFileNameWithoutExtension(csFileName)}.knucleotide-input-big.txt"; + resourceName = $"{Path.GetFileNameWithoutExtension(csFileName).Replace('-', '_')}.knucleotide-input-big.txt"; } else { expectedCountLetter = new int[] { 1576, 1480, 974, 970 }; expectedCountPairs = new int[] { 496, 480, 470, 420, 316, 315, 310, 302, 298, 292, 273, 272, 202, 201, 185, 167 }; expectedCountFragments = new int[] { 54, 24, 4, 0, 0 }; - resourceName = $"{Path.GetFileNameWithoutExtension(csFileName)}.knucleotide-input.txt"; + resourceName = $"{Path.GetFileNameWithoutExtension(csFileName).Replace('-', '_')}.knucleotide-input.txt"; } expectedFrequencies = new int[][] { expectedCountLetter, expectedCountPairs }; } diff --git a/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/k-nucleotide-9.cs b/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/k-nucleotide-9.cs index 89659ef89ee962..6aab158c4a77d8 100644 --- a/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/k-nucleotide-9.cs +++ b/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/k-nucleotide-9.cs @@ -8,7 +8,7 @@ /* The Computer Language Benchmarks Game http://benchmarksgame.alioth.debian.org/ - + submitted by Josh Goldfoot Modified to reduce memory and do more in parallel by Anthony Lloyd */ diff --git a/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/harness-helpers.cs b/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/harness-helpers.cs index a5dc268d1b2e88..6a88cfb68d0e15 100644 --- a/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/harness-helpers.cs +++ b/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/harness-helpers.cs @@ -20,12 +20,12 @@ public TestHarnessHelpers(bool bigInput, [System.Runtime.CompilerServices.Caller if (bigInput) { ExpectedLength = 136381; - resourceName = $"{Path.GetFileNameWithoutExtension(csFileName)}.regexdna-input25000.txt"; + resourceName = $"{Path.GetFileNameWithoutExtension(csFileName).Replace('-', '_')}.regexdna-input25000.txt"; } else { ExpectedLength = 152; - resourceName = $"{Path.GetFileNameWithoutExtension(csFileName)}.regexdna-input25.txt"; + resourceName = $"{Path.GetFileNameWithoutExtension(csFileName).Replace('-', '_')}.regexdna-input25.txt"; } } diff --git a/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-1.cs b/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-1.cs index b367b74c5494c3..e7d4daed822819 100644 --- a/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-1.cs +++ b/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-1.cs @@ -8,8 +8,8 @@ /* The Computer Language Benchmarks Game http://benchmarksgame.alioth.debian.org/ - * - * regex-dna program contributed by Isaac Gouy + * + * regex-dna program contributed by Isaac Gouy * converted from regex-dna program * */ diff --git a/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-5.cs b/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-5.cs index 7fd68c8c21b518..3bc1278af689fa 100644 --- a/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-5.cs +++ b/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-5.cs @@ -8,7 +8,7 @@ /* The Computer Language Benchmarks Game http://benchmarksgame.alioth.debian.org/ - + Regex-Redux by Josh Goldfoot order variants by execution time by Anthony Lloyd */ diff --git a/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/harness-helpers.cs b/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/harness-helpers.cs index 78532b10f43d4b..7c2082625d6e7a 100644 --- a/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/harness-helpers.cs +++ b/src/tests/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/harness-helpers.cs @@ -22,13 +22,13 @@ public TestHarnessHelpers(bool bigInput, [System.Runtime.CompilerServices.Caller { FileLength = 254245; CheckSum = "61-A4-CC-6D-15-8D-26-77-88-93-4F-E2-29-A2-8D-FB"; - resourceName = $"{Path.GetFileNameWithoutExtension(csFileName)}.revcomp-input25000.txt"; + resourceName = $"{Path.GetFileNameWithoutExtension(csFileName).Replace('-', '_')}.revcomp-input25000.txt"; } else { FileLength = 333; CheckSum = "62-45-8E-09-2E-89-A0-69-8C-17-F5-D8-C7-63-5B-50"; - resourceName = $"{Path.GetFileNameWithoutExtension(csFileName)}.revcomp-input25.txt"; + resourceName = $"{Path.GetFileNameWithoutExtension(csFileName).Replace('-', '_')}.revcomp-input25.txt"; } } diff --git a/src/tests/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs b/src/tests/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs index c26093ecfb245b..de03962d7d9c5a 100644 --- a/src/tests/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs +++ b/src/tests/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs @@ -67,7 +67,8 @@ private static void PrintUsage() [Fact] public static int TestEntryPoint() { - return Test(Array.Empty()); + Bench(0, -1); + return Pass; } [MethodImpl(MethodImplOptions.NoInlining)] @@ -148,7 +149,7 @@ public static void Bench(int iters, int which) float ymin = YC - Range; float ymax = YC + Range; float step = Range / 1000f; // This will render one million pixels - float warm = Range / 100f; // To warm up, just render 10000 pixels :-) + float warm = Range / 50f; // To warm up, just render 2500 pixels :-) Algorithms.FractalRenderer.Render[] renderers = new Algorithms.FractalRenderer.Render[24]; // Warm up each renderer if (!s_silent) @@ -179,6 +180,10 @@ public static void Bench(int iters, int which) { Console.WriteLine(" Run Type : Min Max Average Std-Dev"); } + + // iters == 0: just do warmup runs + if (iters == 0) return; + for (int i = firstRenderer; i <= lastRenderer; i++) { long totalTime = 0; diff --git a/src/tests/JIT/Regression/CLR-x86-JIT/V1-M09/b13621/b13621.cs b/src/tests/JIT/Regression/CLR-x86-JIT/V1-M09/b13621/b13621.cs index 55a0e969f674a2..76841e69d2fc5e 100644 --- a/src/tests/JIT/Regression/CLR-x86-JIT/V1-M09/b13621/b13621.cs +++ b/src/tests/JIT/Regression/CLR-x86-JIT/V1-M09/b13621/b13621.cs @@ -32,7 +32,7 @@ public static void TestEntryPoint() } } - public RootMem(int i) + private RootMem(int i) { if (i > 0) { diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106338/Runtime_106338.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106338/Runtime_106338.cs index 450c002a5d9479..b3d4667c0750d0 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_106338/Runtime_106338.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106338/Runtime_106338.cs @@ -8,21 +8,74 @@ // Debug: Outputs 1600094603 // Release: Outputs 1600094604 using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics.X86; using Xunit; public class Runtime_106338 { + [MethodImpl(MethodImplOptions.NoInlining)] + static float CastToFloatDirect(long val) => (float)val; + + [MethodImpl(MethodImplOptions.NoInlining)] + static float CastToFloatDirect(ulong val) => (float)val; + + [MethodImpl(MethodImplOptions.NoInlining)] + static float CastToFloatThroughDouble(long val) => (float)(double)val; + + [MethodImpl(MethodImplOptions.NoInlining)] + static float CastToFloatThroughDouble(ulong val) => (float)(double)val; + [Fact] [SkipOnMono("https://github.com/dotnet/runtime/issues/100368", TestPlatforms.Any)] public static void TestEntryPoint() { - ulong vr10 = 16105307123914158031UL; - float vr11 = 4294967295U | vr10; - uint result = BitConverter.SingleToUInt32Bits(vr11); + ulong vr10 = 0xDF818B7F_FFFFFFFF; + float vr11 = vr10; + float vr12 = (float)(double)vr10; + + // These results will be const folded + uint resultDirect = BitConverter.SingleToUInt32Bits(vr11); + uint resultIntermediate = BitConverter.SingleToUInt32Bits(vr12); // Expected to cast ulong -> float directly - Assert.Equal(1600094603U, result); + Assert.Equal(1600094603U, resultDirect); + + // Expected to preserve ulong -> double intermediate cast + Assert.Equal(1600094604U, resultIntermediate); + + // Check that run-time computed values match + resultDirect = BitConverter.SingleToUInt32Bits(CastToFloatDirect(vr10)); + resultIntermediate = BitConverter.SingleToUInt32Bits(CastToFloatThroughDouble(vr10)); + + Assert.Equal(1600094603U, resultDirect); + Assert.Equal(1600094604U, resultIntermediate); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368", TestPlatforms.Any)] + public static void TestEntryPointSigned() + { + long vr10 = 0x002FFFFF_DFFFFFFF; + float vr11 = vr10; + float vr12 = (float)(double)vr10; + + // These results will be const folded + uint resultDirect = BitConverter.SingleToUInt32Bits(vr11); + uint resultIntermediate = BitConverter.SingleToUInt32Bits(vr12); + + // Expected to cast long -> float directly + Assert.Equal(1514143743U, resultDirect); + + // Expected to preserve long -> double intermediate cast + Assert.Equal(1514143744U, resultIntermediate); + + // Check that run-time computed values match + resultDirect = BitConverter.SingleToUInt32Bits(CastToFloatDirect(vr10)); + resultIntermediate = BitConverter.SingleToUInt32Bits(CastToFloatThroughDouble(vr10)); + + Assert.Equal(1514143743U, resultDirect); + Assert.Equal(1514143744U, resultIntermediate); } } \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_116125/Runtime_116125.cs b/src/tests/JIT/Regression/JitBlue/Runtime_116125/Runtime_116125.cs new file mode 100644 index 00000000000000..86094be387b5f2 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_116125/Runtime_116125.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. + +// Generated by Fuzzlyn v3.1 on 2025-05-29 20:01:16 +// Run on X64 Windows +// Seed: 14412340127944514498-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 53.8 KiB to 0.7 KiB in 00:02:59 +// Debug: Prints 1 line(s) +// Release: Prints 0 line(s) + +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_116125 +{ + [Fact] + public static void TestEntryPoint() + { + ushort y = 0; + Problem(0, ref y); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Problem(ulong x, ref ushort y) + { + if (x / ((0UL & y) | 1) <= 0) + { + + } + else + { + throw new InvalidOperationException(); + } + } +} diff --git a/src/tests/async/reflection/reflectionSimple.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_116125/Runtime_116125.csproj similarity index 100% rename from src/tests/async/reflection/reflectionSimple.csproj rename to src/tests/JIT/Regression/JitBlue/Runtime_116125/Runtime_116125.csproj diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_116159/Runtime_116159.cs b/src/tests/JIT/Regression/JitBlue/Runtime_116159/Runtime_116159.cs new file mode 100644 index 00000000000000..aee209ac6cee71 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_116159/Runtime_116159.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Generated by Fuzzlyn v3.1 on 2025-05-30 09:55:02 +// Run on Arm64 MacOS +// Seed: 17657029378323677877-vectort,vector64,vector128,armadvsimd,armadvsimdarm64,armaes,armarmbase,armarmbasearm64,armcrc32,armcrc32arm64,armdp,armrdm,armrdmarm64,armsha1,armsha256 +// Reduced from 183.5 KiB to 0.6 KiB in 00:00:39 +// Debug: Prints 0 line(s) +// Release: Prints 1 line(s) + +using System; +using Xunit; + +public class Runtime_116159 +{ + public static long[] s_3 = new long[] + { + 0 + }; + public static int s_6; + public static ulong[] s_9; + + [Fact] + public static void TestEntryPoint() + { + if (1 <= s_3[0]) + { + s_9 = new ulong[] + { + 0 + }; + } + else + { + if (long.MinValue > s_3[0]) + { + throw new Exception(); + } + } + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_116159/Runtime_116159.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_116159/Runtime_116159.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_116159/Runtime_116159.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_116657/Runtime_116657.cs b/src/tests/JIT/Regression/JitBlue/Runtime_116657/Runtime_116657.cs new file mode 100644 index 00000000000000..33b54e315e771d --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_116657/Runtime_116657.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_116657 +{ + [Fact] + public static void TestEntryPoint() + { + ulong x = 0x7ffc000000000000; + double result = Problem(ref x); + Assert.Equal(0, result); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static unsafe double Problem(ref ulong x) + { + if ((x & 0x7ffc000000000000) != 0x7ffc000000000000) + { + fixed (void* p = &x) + return *(double*)p; + } + return 0; + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_116657/Runtime_116657.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_116657/Runtime_116657.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_116657/Runtime_116657.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_116888/Runtime_116888.cs b/src/tests/JIT/Regression/JitBlue/Runtime_116888/Runtime_116888.cs new file mode 100644 index 00000000000000..2094e08f0a0e01 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_116888/Runtime_116888.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Found by Antigen +// Reduced from 342.86 KB to 1.33 KB. + +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using System.Runtime.Intrinsics.X86; +using System.Numerics; +using Xunit; + +public class TestClass +{ + public struct S1 + { + } + public struct S2 + { + } + static Vector s_v_ulong_45 = Vector.AllBitsSet; + static S1 s_s1_51 = new S1(); + S1 s1_101 = new S1(); + S2 s2_102 = new S2(); + private static List toPrint = new List(); + public S2 Method14(ref S1 p_s1_448, S2 p_s2_449, out S2 p_s2_450, S1 p_s1_451, out S1 p_s1_452, Vector p_v_ulong_453, out S1 p_s1_454) + { + unchecked + { + return s2_102; + } + } + + private void Method0() + { + unchecked + { + S1 s1_2842 = new S1(); + S2 s2_2843 = new S2(); + s2_2843 = Method14(ref s_s1_51, s2_102, out s2_102, s1_101, out s_s1_51, Sve.CreateTrueMaskUInt64(SveMaskPattern.LargestMultipleOf4) + s_v_ulong_45 + s_v_ulong_45- s_v_ulong_45 * s_v_ulong_45, out s1_2842); + return; + } + } + + [Fact] + public static void TestEntryPoint() + { + if (Sve.IsSupported) + { + new TestClass().Method0(); + } + return; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_116888/Runtime_116888.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_116888/Runtime_116888.csproj new file mode 100644 index 00000000000000..532bf97e96111e --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_116888/Runtime_116888.csproj @@ -0,0 +1,14 @@ + + + + true + None + True + $(NoWarn);SYSLIB5003 + + + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_117377/Runtime_117377.cs b/src/tests/JIT/Regression/JitBlue/Runtime_117377/Runtime_117377.cs new file mode 100644 index 00000000000000..c6f63025b22620 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_117377/Runtime_117377.cs @@ -0,0 +1,46 @@ +// 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.2 on 2025-07-07 15:44:07 +// Run on X64 Windows +// Seed: 13630635548352241444-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 23.1 KiB to 0.7 KiB in 00:01:26 +// Hits JIT assert for Release: +// Assertion failed 'unreached' in 'S1:M4():byte:this' during 'Morph - Global' (IL size 58; hash 0x43f4d8e9; FullOpts) +// +// File: D:\a\_work\1\s\src\coreclr\jit\simd.h Line: 1142 +// + +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using Xunit; + +public class Runtime_117377 +{ + static Vector256 s_1; + + [Fact] + public static void TestEntryPoint() + { + (new S1()).M4(); + } + + struct S1 + { + public byte F4; + + public byte M4() + { + if (Avx512F.VL.IsSupported) + { + var vr3 = Vector256.CreateScalar(0U); + var vr5 = Vector256.Create(0); + var vr6 = Vector256.CreateScalar(85122339U); + var vr4 = Avx512F.VL.RotateLeftVariable(vr5, vr6); + var vr1 = Avx512F.VL.CompareGreaterThanOrEqual(vr3, vr4); + s_1 = Avx2.AndNot(vr1, s_1); + } + return F4; + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_117377/Runtime_117377.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_117377/Runtime_117377.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_117377/Runtime_117377.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.cs b/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.cs new file mode 100644 index 00000000000000..7ca27eb30a35eb --- /dev/null +++ b/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/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.csproj new file mode 100644 index 00000000000000..1c287f51f440e2 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.csproj @@ -0,0 +1,10 @@ + + + True + + true + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.cs b/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.cs new file mode 100644 index 00000000000000..9a91aaf7a759ce --- /dev/null +++ b/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/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_117794/Runtime_117794.cs b/src/tests/JIT/Regression/JitBlue/Runtime_117794/Runtime_117794.cs new file mode 100644 index 00000000000000..a922db2e81cbdc --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_117794/Runtime_117794.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.Intrinsics; +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_117794 +{ + [Fact] + public static void TestEntryPoint() + { + Assert.Equal(Vector128.Create(0u, 0, 1, 1), M0(Vector128.AllBitsSet, Vector128.Create(0u, 0, 2, 2))); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Vector128 M0(Vector128 v, Vector128 w) => Vector128.ConditionalSelect( + Vector128.GreaterThan(w, Vector128.Zero), + (v & Vector128.One.AsUInt64()).AsUInt32(), + Vector128.Zero + ); +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_117794/Runtime_117794.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_117794/Runtime_117794.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_117794/Runtime_117794.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_118143/Runtime_118143.cs b/src/tests/JIT/Regression/JitBlue/Runtime_118143/Runtime_118143.cs new file mode 100644 index 00000000000000..4a4f7281937f60 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_118143/Runtime_118143.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. + +using System; +using System.Buffers.Text; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Threading; +using Xunit; + +public class Runtime_118143 +{ + [Fact] + public static void TestEntryPoint() + { + for (int i = 0; i < 300; i++) + { + RunBase64Test(); + Thread.Sleep(1); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void RunBase64Test() + { + byte[] input = new byte[64]; + byte[] output = new byte[Base64.GetMaxEncodedToUtf8Length(input.Length)]; + byte[] expected = Convert.FromHexString( + "5957466859574668595746685957466859574668595746685957466859574668595746685957466859574668" + + "5957466859574668595746685957466859574668595746685957466859574668595746685957466859513D3D"); + input.AsSpan().Fill((byte)'a'); + Base64.EncodeToUtf8(input, output, out _, out _); + if (!output.SequenceEqual(expected)) + throw new InvalidOperationException("Invalid Base64 output"); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_118143/Runtime_118143.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_118143/Runtime_118143.csproj new file mode 100644 index 00000000000000..39f03c7a329d59 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_118143/Runtime_118143.csproj @@ -0,0 +1,13 @@ + + + True + + true + + + + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_118377/Runtime_118377.cs b/src/tests/JIT/Regression/JitBlue/Runtime_118377/Runtime_118377.cs new file mode 100644 index 00000000000000..c49e208881cd20 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_118377/Runtime_118377.cs @@ -0,0 +1,51 @@ +// 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-08-05 00:20:11 +// Run on Arm64 Linux +// Seed: 7831934182807398228-vectort,vector64,vector128,armadvsimd,armadvsimdarm64,armaes,armarmbase,armarmbasearm64,armcrc32,armcrc32arm64,armdp,armrdm,armrdmarm64,armsha1,armsha256,armsve,armsve2 +// Reduced from 61.3 KiB to 1.3 KiB in 00:00:54 +// Debug: Outputs <14533768479604701151, 1> +// Release: Outputs <14533768479604701151, 0> + +using System; +using System.Runtime.CompilerServices; +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using Xunit; + +public class Runtime_118377 +{ + public static ulong s_4; + public static ulong F0 = 1; + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Vector M4() + { + var vr3 = Sve.CreateWhileLessThanMask64Bit(0, 0); + var vr5 = Vector.Create(s_4); + var vr1 = Sve.CreateBreakPropagateMask(vr3, vr5); + var vr7 = Vector.Create(0); + return Sve.Add(vr1, vr7); + } + + [Fact] + public static void TestEntryPoint() + { + if (Sve.IsSupported) + { + var vr4 = F0; + var vr0 = Vector.Create(vr4); + var vr8 = Vector128.CreateScalar(14533768479604701152UL).AsVector(); + var vr10 = F0; + var vr9 = Vector.Create(vr10); + var vr6 = Sve.AbsoluteDifference(vr8, vr9); + var vr11 = M4(); + Vector var2 = Sve.ConditionalSelect(vr0, vr6, vr11); + Console.WriteLine(var2); + Assert.Equal(14533768479604701151UL, var2[0]); + Assert.Equal(1UL, var2[1]); + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_118377/Runtime_118377.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_118377/Runtime_118377.csproj new file mode 100644 index 00000000000000..532bf97e96111e --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_118377/Runtime_118377.csproj @@ -0,0 +1,14 @@ + + + + true + None + True + $(NoWarn);SYSLIB5003 + + + + + + + diff --git a/src/tests/JIT/interpreter/CMakeLists.txt b/src/tests/JIT/interpreter/CMakeLists.txt new file mode 100644 index 00000000000000..8370c4824a523b --- /dev/null +++ b/src/tests/JIT/interpreter/CMakeLists.txt @@ -0,0 +1,11 @@ +project (pinvoke) + +include_directories(${INC_PLATFORM_DIR}) + +set(SOURCES pinvoke.cpp) + +# add the executable +add_library (pinvoke SHARED ${SOURCES}) + +# add the install targets +install (TARGETS pinvoke DESTINATION bin) diff --git a/src/tests/JIT/interpreter/Interpreter.cs b/src/tests/JIT/interpreter/Interpreter.cs index 6930cbae213e52..90516f0466a737 100644 --- a/src/tests/JIT/interpreter/Interpreter.cs +++ b/src/tests/JIT/interpreter/Interpreter.cs @@ -3,7 +3,10 @@ using System; using System.Numerics; +using System.Runtime.Intrinsics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Threading; public interface ITest { @@ -605,6 +608,51 @@ static void TestCallingConvention12JitToInterpreter(bool init) } } + [MethodImpl(MethodImplOptions.NoInlining)] + static void TestCallingConvention13(int a, int b, int c, int d, int e, int f, int g, int h, TestStruct4ii s) + { + Console.WriteLine("TestCallingConvention13: a = {0}, b = {1}, c = {2}, d = {3}, e = {4}, f = {5}, g = {6}, h = {7}, s = ({8}, {9}, {10}, {11})", a, b, c, d, e, f, g, h, s.a, s.b, s.c, s.d); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void TestCallingConvention13Rev(int a, int b, int c, int d, int e, int f, int g, int h, TestStruct4ii s) + { + Console.Write("TestCallingConvention13Rev: a = "); + Console.Write(a); + Console.Write(", b = "); + Console.Write(b); + Console.Write(", c = "); + Console.Write(c); + Console.Write(", d = "); + Console.Write(d); + Console.Write(", e = "); + Console.Write(e); + Console.Write(", f = "); + Console.Write(f); + Console.Write(", g = "); + Console.Write(g); + Console.Write(", h = "); + Console.Write(h); + Console.Write(", s = ("); + Console.Write(s.a); + Console.Write(", "); + Console.Write(s.b); + Console.Write(", "); + Console.Write(s.c); + Console.Write(", "); + Console.Write(s.d); + Console.WriteLine(")"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void TestCallingConvention13JitToInterpreter(bool init) + { + if (!init) + { + TestCallingConvention13Rev(1, 2, 3, 4, 5, 6, 7, 8, new TestStruct4ii { a = 9, b = 10, c = 11, d = 12 }); + } + } + // This method is invoked before we start interpretting anything, so the methods invoked in it will be jitted. // This is necessary for the calling convention tests that test calls from the interpreter to the JITted code // to actually test things. @@ -655,6 +703,7 @@ static void EnsureCallingConventionTestTargetMethodsAreJitted() Console.WriteLine(s11.c); TestCallingConvention12(1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 10, 11, 12); + TestCallingConvention13(1, 2, 3, 4, 5, 6, 7, 8, new TestStruct4ii { a = 9, b = 10, c = 11, d = 12 }); TestCallingConvention0JitToInterpreter(true); TestCallingConvention1JitToInterpreter(true); @@ -669,6 +718,7 @@ static void EnsureCallingConventionTestTargetMethodsAreJitted() TestCallingConvention10JitToInterpreter(true); TestCallingConvention11JitToInterpreter(true); TestCallingConvention12JitToInterpreter(true); + TestCallingConvention13JitToInterpreter(true); } static int Main(string[] args) @@ -698,6 +748,7 @@ public static void RunInterpreterTests() TestCallingConvention10JitToInterpreter(false); TestCallingConvention11JitToInterpreter(false); TestCallingConvention12JitToInterpreter(false); + TestCallingConvention13JitToInterpreter(false); TestCallingConvention0(1, 2.0f, 3, 4.0, 5, 6.0); @@ -779,6 +830,7 @@ public static void RunInterpreterTests() Console.WriteLine(s11.c); TestCallingConvention12(1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 10, 11, 12); + TestCallingConvention13(1, 2, 3, 4, 5, 6, 7, 8, new TestStruct4ii { a = 9, b = 10, c = 11, d = 12 }); // Console.WriteLine("Run interp tests"); Console.WriteLine("Sum"); @@ -814,9 +866,15 @@ public static void RunInterpreterTests() // Unchecked to ensure that the divide-by-zero here doesn't throw since we're using it to generate a NaN unchecked { + Console.WriteLine("TestConvOvf"); if (!TestConvOvf(1, 2, 3, 4, 1.0 / 0.0, -32, 1234567890)) Environment.FailFast(null); + Console.WriteLine("TestConvOvfUn"); + if (!TestConvOvfUn(1, 2, 3, uint.MaxValue, ulong.MaxValue)) + Environment.FailFast(null); + + Console.WriteLine("TestConvBoundaries"); if (!TestConvBoundaries( 32767.999999999996, 32768.00000000001, 2147483647.9999998, 2147483648.0000005 @@ -877,6 +935,10 @@ public static void RunInterpreterTests() if (!TestDelegate()) Environment.FailFast(null); + Console.WriteLine("TestIntrinsics"); + if (!TestIntrinsics()) + Environment.FailFast(null); + Console.WriteLine("TestCalli"); if (!TestCalli()) Environment.FailFast(null); @@ -889,17 +951,45 @@ public static void RunInterpreterTests() if (!TestPreciseInitCctors()) Environment.FailFast(null); - Console.WriteLine("Empty string length: {0}", string.Empty.Length); + Console.WriteLine("TestThreading_Interlocked_CompareExchange"); + if (!TestThreading_Interlocked_CompareExchange()) + Environment.FailFast(null); + + Console.WriteLine("TestRuntimeHelpers_IsReferenceOrContainsReferences"); + if (!TestRuntimeHelpers_IsReferenceOrContainsReferences()) + Environment.FailFast(null); + + Console.WriteLine("TestMemoryMarshal_GetArrayDataReference"); + if (!TestMemoryMarshal_GetArrayDataReference()) + Environment.FailFast(null); + + Console.WriteLine("Empty string length: {0}", string.Empty.Length); - Console.WriteLine("BitConverter.IsLittleEndian: {0}", BitConverter.IsLittleEndian); + Console.WriteLine("BitConverter.IsLittleEndian: {0}", BitConverter.IsLittleEndian); - Console.WriteLine("IntPtr.Zero: {0}, UIntPtr.Zero: {1}", IntPtr.Zero, UIntPtr.Zero); + Console.WriteLine("IntPtr.Zero: {0}, UIntPtr.Zero: {1}", IntPtr.Zero, UIntPtr.Zero); + Console.WriteLine("TestPInvoke"); + if (!TestPInvoke()) + Environment.FailFast(null); + + // For stackwalking validation System.GC.Collect(); Console.WriteLine("All tests passed successfully!"); } + public static bool TestIntrinsics() + { + Console.WriteLine("Vector128.IsHardwareAccelerated="); + Console.WriteLine(Vector128.IsHardwareAccelerated); + Console.WriteLine("X86Base.IsSupported="); + Console.WriteLine(System.Runtime.Intrinsics.X86.X86Base.IsSupported); + Console.WriteLine("ArmBase.IsSupported="); + Console.WriteLine(System.Runtime.Intrinsics.Arm.ArmBase.IsSupported); + return true; + } + public static void TestExceptionHandling() { TestTryFinally(); @@ -1567,6 +1657,43 @@ public static bool TestConvOvf(float r4, double r8, int i4, long i8, double nan, return true; } + public static bool TestConvOvfUn(ushort u2, uint u4, ulong u8, uint hugeUint, ulong hugeUlong) + { + checked + { + byte a = (byte)u2, + b = (byte)u4, + c = (byte)u8; + + if (a != u2) + return false; + if (b != u4) + return false; + if (c != u8) + return false; + + try + { + a = (byte)hugeUint; + return false; + } + catch (OverflowException) + { + } + + try + { + b = (byte)hugeUlong; + return false; + } + catch (OverflowException) + { + } + } + + return true; + } + public static bool TestConvBoundaries(double inRangeShort, double outOfRangeShort, double inRangeInt, double outOfRangeInt) { // In unchecked mode, the interpreter saturates on float->int conversions if the value is out of range @@ -1932,7 +2059,7 @@ public static T[] TestNewArr(int len) public static T[,,] TestNewMDArr(int len) { - return new T[len,len-1,len-2]; + return new T[len, len - 1, len - 2]; } public static object Box(T value) @@ -1948,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; @@ -1964,7 +2096,7 @@ public static void TriggerCctorClass() } public static void TriggerCctorMethod() - {} + { } } class MyClass @@ -2261,6 +2393,99 @@ static object BoxedSubtraction(object lhs, object rhs) return (int)lhs - (int)rhs; } + [DllImport("pinvoke", CallingConvention = CallingConvention.Cdecl)] + public static extern int sumTwoInts(int x, int y); + [DllImport("pinvoke", CallingConvention = CallingConvention.Cdecl)] + public static extern double sumTwoDoubles(double x, double y); + [DllImport("pinvoke", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public static extern int writeToStdout(string s); + [DllImport("missingLibrary", CallingConvention = CallingConvention.Cdecl)] + public static extern void missingPInvoke(); + [DllImport("missingLibrary", CallingConvention = CallingConvention.Cdecl)] + public static extern void missingPInvokeWithMarshaling(string s); + + public static bool TestPInvoke() + { + if (sumTwoInts(1, 2) != 3) + return false; + + double summed = sumTwoDoubles(1, 2); + if (summed != 3) + return false; + + // Test marshaling wrappers + writeToStdout("Hello world from pinvoke.dll!writeToStdout\n"); + + /* fails, with output: + Assert failure(PID 32748 [0x00007fec], Thread: 24256 [0x5ec0]): pMD == codeInfo.GetMethodDesc() + + CORECLR! AppendExceptionStackFrame + 0x331 (0x00007ff9`85879b71) + SYSTEM.PRIVATE.CORELIB! + 0x0 (0x00007ff9`80d91f30) + SYSTEM.PRIVATE.CORELIB! + 0x0 (0x00007ff9`80d926b7) + SYSTEM.PRIVATE.CORELIB! + 0x0 (0x00007ff9`80d92289) + CORECLR! CallDescrWorkerInternal + 0x83 (0x00007ff9`859811c3) + CORECLR! CallDescrWorkerWithHandler + 0x130 (0x00007ff9`854755c0) + CORECLR! DispatchCallSimple + 0x26C (0x00007ff9`8547655c) + CORECLR! DispatchManagedException + 0x388 (0x00007ff9`85872998) + CORECLR! DispatchManagedException + 0x67 (0x00007ff9`858725a7) + CORECLR! UnwindAndContinueRethrowHelperAfterCatch + 0x1F8 (0x00007ff9`851be5e8) + File: Z:\runtime\src\coreclr\vm\exceptionhandling.cpp:3032 + Image: Z:\runtime\artifacts\tests\coreclr\windows.x64.Checked\Tests\Core_Root\corerun.exe + + pMD is TestPInvoke (correct) and codeInfo.GetMethodDesc() is Main (wrong) + */ + /* + bool caught = false; + try { + Console.WriteLine("calling missingPInvoke"); + missingPInvoke(); + return false; + } catch (DllNotFoundException) { + Console.WriteLine("caught #1"); + caught = true; + } + + if (!caught) + return false; + */ + + /* fails, with output: + calling missingPInvokeWithMarshaling + caught #2 + + Assert failure(PID 59772 [0x0000e97c], Thread: 24864 [0x6120]): ohThrowable + + CORECLR! PreStubWorker$catch$10 + 0x93 (0x00007ff9`580972b3) + CORECLR! CallSettingFrame_LookupContinuationIndex + 0x20 (0x00007ff9`57f32e70) + CORECLR! _FrameHandler4::CxxCallCatchBlock + 0x1DE (0x00007ff9`57f1e83e) + NTDLL! RtlCaptureContext2 + 0x4A6 (0x00007ffa`b7e46606) + CORECLR! PreStubWorker + 0x4F8 (0x00007ff9`5789dd78) + CORECLR! ThePreStub + 0x55 (0x00007ff9`57ec29c5) + CORECLR! CallJittedMethodRetVoid + 0x14 (0x00007ff9`57ec0f34) + CORECLR! InvokeCompiledMethod + 0x5D7 (0x00007ff9`57afaf67) + CORECLR! InterpExecMethod + 0x84BB (0x00007ff9`57af68cb) + CORECLR! ExecuteInterpretedMethod + 0x11B (0x00007ff9`5789c77b) + File: Z:\runtime\src\coreclr\vm\prestub.cpp:1965 + Image: Z:\runtime\artifacts\tests\coreclr\windows.x64.Checked\Tests\Core_Root\corerun.exe + */ + /* + bool caught2 = false; + try { + Console.WriteLine("calling missingPInvokeWithMarshaling"); + missingPInvokeWithMarshaling("test"); + return false; + } catch (DllNotFoundException) { + Console.WriteLine("caught #2"); + caught2 = true; + } + + if (!caught2) + return false; + */ + + return true; + } + public static bool TestArray() { // sbyte @@ -2798,4 +3023,72 @@ public static bool TestStaticVirtualGeneric_CodePointerCase() return true; } + + public static bool TestThreading_Interlocked_CompareExchange() + { + // Value type test + int location = 1; + int value = 2; + int comparand = 1; + int result = System.Threading.Interlocked.CompareExchange(ref location, value, comparand); + if (!(result == 1 && location == 2)) + return false; + + // Reference type test + object objLocation = "a"; + object objValue = "b"; + object objComparand = "a"; + object objResult = System.Threading.Interlocked.CompareExchange(ref objLocation, objValue, objComparand); + if (!(object.ReferenceEquals(objResult, objComparand) && object.ReferenceEquals(objLocation, objValue))) + return false; + + // Reference type test (fail) + objLocation = "a"; + objValue = "b"; + objComparand = "c"; + objResult = System.Threading.Interlocked.CompareExchange(ref objLocation, objValue, objComparand); + if (!(object.ReferenceEquals(objResult, objLocation) && object.ReferenceEquals(objLocation, "a"))) + return false; + + // Null reference test + objLocation = null; + objValue = "b"; + objComparand = null; + objResult = System.Threading.Interlocked.CompareExchange(ref objLocation, objValue, objComparand); + if (!(objResult is null && object.ReferenceEquals(objLocation, objValue))) + return false; + + return true; + } + + public static bool TestRuntimeHelpers_IsReferenceOrContainsReferences() + { + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + return false; + if (RuntimeHelpers.IsReferenceOrContainsReferences()) + return false; + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + return false; + return true; + } + + public static bool TestMemoryMarshal_GetArrayDataReference() + { + int[] arr = new int[1]; + ref int dataRef = ref MemoryMarshal.GetArrayDataReference(arr); + dataRef = 42; + if (arr[0] != 42) + return false; + + arr = null; + try + { + MemoryMarshal.GetArrayDataReference(arr); + return false; + } + catch (NullReferenceException) + { + return true; + } + } } diff --git a/src/tests/JIT/interpreter/Interpreter.csproj b/src/tests/JIT/interpreter/Interpreter.csproj index 98b0af809b2826..567503852c60ca 100644 --- a/src/tests/JIT/interpreter/Interpreter.csproj +++ b/src/tests/JIT/interpreter/Interpreter.csproj @@ -8,4 +8,7 @@ + + + diff --git a/src/tests/JIT/interpreter/InterpreterTester.csproj b/src/tests/JIT/interpreter/InterpreterTester.csproj index 4bb141749f2885..e654b46510baa1 100644 --- a/src/tests/JIT/interpreter/InterpreterTester.csproj +++ b/src/tests/JIT/interpreter/InterpreterTester.csproj @@ -13,6 +13,9 @@ + + + diff --git a/src/tests/JIT/interpreter/pinvoke.cpp b/src/tests/JIT/interpreter/pinvoke.cpp new file mode 100644 index 00000000000000..149a902e6110fa --- /dev/null +++ b/src/tests/JIT/interpreter/pinvoke.cpp @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "stdio.h" +#include +#include + +#define EXPORT_IT extern "C" DLL_EXPORT + +EXPORT_IT void writeToStdout (const char *str) +{ + puts(str); +} + +EXPORT_IT int sumTwoInts (int x, int y) +{ + return x + y; +} + +EXPORT_IT double sumTwoDoubles (double x, double y) +{ + return x + y; +} diff --git a/src/tests/JIT/opt/Compares/conditionalSimpleOps.cs b/src/tests/JIT/opt/Compares/conditionalSimpleOps.cs new file mode 100644 index 00000000000000..547962c693c911 --- /dev/null +++ b/src/tests/JIT/opt/Compares/conditionalSimpleOps.cs @@ -0,0 +1,291 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// unit test for the full range comparison optimization + +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public class ConditionalSimpleOpConstantTest +{ + [Theory] + [InlineData(12, 10)] + [InlineData(45, 5)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void shift_left(byte op1, int expected) + { + int result = op1 < 42 ? 10 : 5; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(12, -13)] + [InlineData(45, -25)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void shift_right_arithmetic(byte op1, int expected) + { + int result = op1 > 42 ? -25 : -13; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(12, 0x7FFF_FFF3)] + [InlineData(45, -25)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void shift_right_logic(byte op1, int expected) + { + int result = op1 < 42 ? 0x7FFF_FFF3 : -25; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(12, 0x7FFF_FFFF_FFFF_FFF3ul)] + [InlineData(45, 0xFFFF_FFFF_FFFF_FFE7ul)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void shift_right_logic_ulong(byte op1, ulong expected) + { + ulong result = op1 < 42 ? 0x7FFF_FFFF_FFFF_FFF3ul : 0xFFFF_FFFF_FFFF_FFE7ul; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(12, 0x7FFF_FFF3)] + [InlineData(45, 0xFFFF_FFE7)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void shift_right_logic_long_32(byte op1, long expected) + { + long result = op1 > 42 ? 0xFFFF_FFE7 : 0x7FFF_FFF3; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(12, 64)] + [InlineData(45, 0)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void pow2_or_zero(byte op1, int expected) + { + int result = op1 < 42 ? 64 : 0; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(12, long.MinValue)] + [InlineData(45, 0)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void pow2_or_zero_long(byte op1, long expected) + { + long result = op1 >= 42 ? 0 : long.MinValue; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(12, 0xFFFF_FFFF_8000_0000ul)] + [InlineData(45, 0ul)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void pow2_or_zero_ulong_32(byte op1, ulong expected) + { + ulong result = op1 < 42 ? 0xFFFF_FFFF_8000_0000ul : 0ul; + Assert.Equal(expected, result); + } +} + +public class ConditionalSimpleOpVariableTest +{ + [Theory] + [InlineData(11, 12)] + [InlineData(12, 13)] + [InlineData(45, 45)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void add_var(int a, int expected) + { + a = a < 42 ? a + 1 : a; + Assert.Equal(expected, a); + } + + [Theory] + [InlineData(11, 12)] + [InlineData(12, 13)] + [InlineData(45, 45)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void add_var_no_else(int a, int expected) + { + if (a < 42) + a++; + Assert.Equal(expected, a); + } + + [Theory] + [InlineData(11, 12)] + [InlineData(12, 13)] + [InlineData(45, 45)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void add_var_reversed(int a, int expected) + { + a = a > 42 ? a : ++a; + Assert.Equal(expected, a); + } + + [Theory] + [InlineData(12, 13)] + [InlineData(13, 13)] + [InlineData(45, 45)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void or_var(int a, int expected) + { + a = a < 42 ? a | 1 : a; + Assert.Equal(expected, a); + } + + [Theory] + [InlineData(12, 13)] + [InlineData(13, 13)] + [InlineData(45, 45)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void or_var_no_else(int a, int expected) + { + if (a < 42) + a = a | 1; + Assert.Equal(expected, a); + } + + [Theory] + [InlineData(11, 10)] + [InlineData(12, 11)] + [InlineData(45, 45)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void sub_var(int a, int expected) + { + a = a < 42 ? a - 1 : a; + Assert.Equal(expected, a); + } + + public static int globVar = 0; + [Theory] + [InlineData(11, 10)] + [InlineData(12, 11)] + [InlineData(45, 45)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void sub_var_globref(int a, int expected) + { + a = (a + globVar) < 42 ? a - 1 : a; + Assert.Equal(expected, a); + } + + [Theory] + [InlineData(11, 10)] + [InlineData(12, 11)] + [InlineData(45, 45)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void sub_var_globref_no_else(int a, int expected) + { + if ((a + globVar) < 42) + --a; + Assert.Equal(expected, a); + } + + [Theory] + [InlineData(12, 13)] + [InlineData(13, 12)] + [InlineData(45, 45)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void xor_var(int a, int expected) + { + a = a < 42 ? a ^ 1 : a; + Assert.Equal(expected, a); + } + + [Theory] + [InlineData(-12, -24)] + [InlineData(12, 24)] + [InlineData(43, 43)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void shift_left_var(int a, int expected) + { + long result = a > 42 ? a : a * 2; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(-12, -24)] + [InlineData(12, 24)] + [InlineData(43, 43)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void shift_left_var_no_else(int a, int expected) + { + long result = a; + if (a <= 42) + result *= 2; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(-12, -24)] + [InlineData(12, 24)] + [InlineData(43, 3)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void shift_left_var_no_else_different_var(long a, long expected) + { + long result = 3; + if (a <= 42) + result = a * 2; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(12, 6)] + [InlineData(-25, -13)] + [InlineData(45, 45)] + [InlineData(-4000_000_000_000l, -2000_000_000_000l)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void shift_right_arithmetic_var(long a, long expected) + { + long result = a > 42 ? a : a >> 1; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(43, 21)] + [InlineData(0x8000_0000, 0x4000_0000)] + [InlineData(12, 12)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void shift_right_logic_var(uint a, uint expected) + { + uint result = a > 42 ? a >> 1 : a; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(44, 0)] + [InlineData(43, 1)] + [InlineData(11, 0)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void and_or_zero_var(int a, int expected) + { + int result = a > 42 ? a & 1 : 0; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(44, 0)] + [InlineData(43, 0)] + [InlineData(11, 1)] + [InlineData(10, 0)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void and_or_zero_var_globref_reversed(uint a, uint expected) + { + uint result = (a ^ globVar) > 42 ? 0 : a & 1; + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(4, 16)] + [InlineData(6, 64)] + [InlineData(43, 0)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void pow2_or_zero_var(int a, int expected) + { + int result = a > 42 ? 0 : 1 << a; + Assert.Equal(expected, result); + } +} diff --git a/src/tests/JIT/opt/Compares/conditionalSimpleOps.csproj b/src/tests/JIT/opt/Compares/conditionalSimpleOps.csproj new file mode 100644 index 00000000000000..b042a45bea9216 --- /dev/null +++ b/src/tests/JIT/opt/Compares/conditionalSimpleOps.csproj @@ -0,0 +1,15 @@ + + + + true + + + None + True + + + + + + + diff --git a/src/tests/JIT/opt/Inline/tests/Inline_NewObj.cs b/src/tests/JIT/opt/Inline/tests/Inline_NewObj.cs index ad0a2233660c77..e8433f5822c628 100644 --- a/src/tests/JIT/opt/Inline/tests/Inline_NewObj.cs +++ b/src/tests/JIT/opt/Inline/tests/Inline_NewObj.cs @@ -9,7 +9,7 @@ public class MainApp_Inline { private int _v; - public MainApp_Inline(int i) + private MainApp_Inline(int i) { switch (i) { diff --git a/src/tests/JIT/opt/InstructionCombining/Cmn.cs b/src/tests/JIT/opt/InstructionCombining/Cmn.cs index 991a0c746d6f5f..f8e05ed9125a0d 100644 --- a/src/tests/JIT/opt/InstructionCombining/Cmn.cs +++ b/src/tests/JIT/opt/InstructionCombining/Cmn.cs @@ -50,31 +50,6 @@ public static int CheckCompareNegative() fail = true; } - if (!CmnExtendedB(1, 0xff)) - { - fail = true; - } - if (!CmnExtendedH(1, 0xffff)) - { - fail = true; - } - if (!CmnExtendedS(1, 0xffffffff)) - { - fail = true; - } - if (!CmnExtendedUB(-1, 0x101)) - { - fail = true; - } - if (!CmnExtendedUH(-1, 0x10001)) - { - fail = true; - } - if (!CmnExtendedUS(-1, 0x100000001)) - { - fail = true; - } - if (fail) { return 101; @@ -159,47 +134,5 @@ static bool CmnLargeShift64Bit(long a, long b) } return false; } - - [MethodImpl(MethodImplOptions.NoInlining)] - static bool CmnExtendedB(int a, int b) - { - //ARM64-FULL-LINE: cmn {{w[0-9]+}}, {{w[0-9]+}}, SXTB - return (a == -(sbyte)b); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - static bool CmnExtendedH(int a, int b) - { - //ARM64-FULL-LINE: cmn {{w[0-9]+}}, {{w[0-9]+}}, SXTH - return (a == -(short)b); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - static bool CmnExtendedS(long a, long b) - { - //ARM64-FULL-LINE: cmn {{x[0-9]+}}, {{w[0-9]+}}, SXTW - return (a == -(long)(int)b); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - static bool CmnExtendedUB(int a, int b) - { - //ARM64-FULL-LINE: cmn {{w[0-9]+}}, {{w[0-9]+}}, UXTB - return (a == -(byte)b); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - static bool CmnExtendedUH(int a, int b) - { - //ARM64-FULL-LINE: cmn {{w[0-9]+}}, {{w[0-9]+}}, UXTH - return (a == -(ushort)b); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - static bool CmnExtendedUS(long a, long b) - { - //ARM64-FULL-LINE: cmn {{x[0-9]+}}, {{w[0-9]+}}, UXTW - return (a == -(uint)b); - } } } diff --git a/src/tests/JIT/opt/ObjectStackAllocation/Runtime_111922v2.cs b/src/tests/JIT/opt/ObjectStackAllocation/Runtime_111922v2.cs new file mode 100644 index 00000000000000..ff4e42d5e33baf --- /dev/null +++ b/src/tests/JIT/opt/ObjectStackAllocation/Runtime_111922v2.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_111922v2 +{ + [Fact] + public static int Test() + { + LinkedList e = new LinkedList(); + LinkedList e1 = new LinkedList(); + e1.AddLast("b"); + e1.AddLast("a"); + + int sum = -80; + + for (int i = 0; i < 200; i++) + { + sum += Problem(i % 10 == 0 ? e : e1) ? 1 : 0; + Thread.Sleep(5); + } + + Console.WriteLine(sum); + return sum; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static bool Problem(IEnumerable e) + { + return e.Contains("a", StringComparer.OrdinalIgnoreCase); + } +} + + diff --git a/src/tests/JIT/opt/ObjectStackAllocation/Runtime_111922v2.csproj b/src/tests/JIT/opt/ObjectStackAllocation/Runtime_111922v2.csproj new file mode 100644 index 00000000000000..501217e4d86892 --- /dev/null +++ b/src/tests/JIT/opt/ObjectStackAllocation/Runtime_111922v2.csproj @@ -0,0 +1,9 @@ + + + None + True + + + + + diff --git a/src/tests/JIT/opt/SVE/EmbeddedLoads.cs b/src/tests/JIT/opt/SVE/EmbeddedLoads.cs index 45de9c21b8ab90..6573ae86e28777 100644 --- a/src/tests/JIT/opt/SVE/EmbeddedLoads.cs +++ b/src/tests/JIT/opt/SVE/EmbeddedLoads.cs @@ -46,7 +46,7 @@ static unsafe void CndSelectEmbeddedOp3LoadTrueMask(int[] array, Vector op1 //ARM6-FULL-LINE: ldnf1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/m, [{{x[0-9]+}}] fixed (int* arr_ptr = array) { - var result = Sve.ConditionalSelect(Sve.CreateTrueMaskInt32(), op1, Sve.LoadVectorNonFaulting(arr_ptr)); + var result = Sve.ConditionalSelect(Sve.CreateTrueMaskInt32(), op1, Sve.LoadVectorNonFaulting(Sve.CreateTrueMaskInt32(), arr_ptr)); Consume(result); } } @@ -56,7 +56,7 @@ static unsafe void CndSelectEmbeddedOp3LoadAllBits(int[] array, Vector op1) //ARM6-FULL-LINE: ldnf1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/m, [{{x[0-9]+}}] fixed (int* arr_ptr = array) { - var result = Sve.ConditionalSelect(Vector.AllBitsSet, op1, Sve.LoadVectorNonFaulting(arr_ptr)); + var result = Sve.ConditionalSelect(Vector.AllBitsSet, op1, Sve.LoadVectorNonFaulting(Vector.AllBitsSet, arr_ptr)); Consume(result); } } @@ -66,7 +66,7 @@ static unsafe void CndSelectEmbeddedOp3LoadFalseMask(int[] array, Vector op //ARM6-FULL-LINE: ldnf1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/m, [{{x[0-9]+}}] fixed (int* arr_ptr = array) { - var result = Sve.ConditionalSelect(Sve.CreateFalseMaskInt32(), op1, Sve.LoadVectorNonFaulting(arr_ptr)); + var result = Sve.ConditionalSelect(Sve.CreateFalseMaskInt32(), op1, Sve.LoadVectorNonFaulting(Sve.CreateFalseMaskInt32(), arr_ptr)); Consume(result); } } @@ -76,7 +76,7 @@ static unsafe void CndSelectEmbeddedOp3LoadZero(int[] array, Vector op1) { //ARM6-FULL-LINE: ldnf1w { {{z[0-9]+}}.s }, {{p[0-9]+}}/m, [{{x[0-9]+}}] fixed (int* arr_ptr = array) { - var result = Sve.ConditionalSelect(Vector.Zero, op1, Sve.LoadVectorNonFaulting(arr_ptr)); + var result = Sve.ConditionalSelect(Vector.Zero, op1, Sve.LoadVectorNonFaulting(Vector.Zero, arr_ptr)); Consume(result); } } diff --git a/src/tests/JIT/opt/SVE/PredicateInstructions.cs b/src/tests/JIT/opt/SVE/PredicateInstructions.cs index b1336674f1638b..287e90b30e4fe6 100644 --- a/src/tests/JIT/opt/SVE/PredicateInstructions.cs +++ b/src/tests/JIT/opt/SVE/PredicateInstructions.cs @@ -17,110 +17,164 @@ public static void TestPredicateInstructions() { if (Sve.IsSupported) { - ZipLow(); - ZipHigh(); - UnzipOdd(); - UnzipEven(); - TransposeOdd(); - TransposeEven(); - ReverseElement(); - And(); - BitwiseClear(); - Xor(); - Or(); - ConditionalSelect(); + Vector vecsb = Vector.Create(2); + Vector vecs = Vector.Create(2); + Vector vecus = Vector.Create(2); + Vector veci = Vector.Create(3); + Vector vecui = Vector.Create(5); + Vector vecl = Vector.Create(7); + + ZipLowMask(vecs, vecs); + ZipHighMask(vecui, vecui); + UnzipOddMask(vecs, vecs); + UnzipEvenMask(vecsb, vecsb); + TransposeEvenMask(vecl, vecl); + TransposeOddMask(vecs, vecs); + ReverseElementMask(vecs, vecs); + AndMask(vecs, vecs); + BitwiseClearMask(vecs, vecs); + XorMask(veci, veci); + OrMask(vecs, vecs); + ConditionalSelectMask(veci, veci, veci); + + UnzipEvenZipLowMask(vecs, vecs); + TransposeEvenAndMask(vecs, vecs, vecs); + } } + // These should use the predicate variants. + // Sve intrinsics that return masks (Compare) or use mask arguments (CreateBreakAfterMask) are used + // to ensure masks are used. + + [MethodImpl(MethodImplOptions.NoInlining)] - static Vector ZipLow() + static Vector ZipLowMask(Vector a, Vector b) { - return Sve.ZipLow(Vector.Zero, Sve.CreateTrueMaskInt16()); + //ARM64-FULL-LINE: zip1 {{p[0-9]+}}.h, {{p[0-9]+}}.h, {{p[0-9]+}}.h + return Sve.ZipLow(Sve.CompareGreaterThan(a, b), Sve.CompareEqual(a, b)); } [MethodImpl(MethodImplOptions.NoInlining)] - static Vector ZipHigh() + static Vector ZipHighMask(Vector a, Vector b) { - return Sve.ZipHigh(Sve.CreateTrueMaskUInt32(), Sve.CreateTrueMaskUInt32()); + //ARM64-FULL-LINE: zip2 {{p[0-9]+}}.s, {{p[0-9]+}}.s, {{p[0-9]+}}.s + return Sve.CreateBreakAfterMask(Sve.ZipHigh(Sve.CompareGreaterThan(a, b), Sve.CompareEqual(a, b)), Sve.CreateTrueMaskUInt32()); } [MethodImpl(MethodImplOptions.NoInlining)] - static Vector UnzipEven() + static Vector UnzipEvenMask(Vector a, Vector b) { - return Sve.UnzipEven(Sve.CreateTrueMaskSByte(), Vector.Zero); + //ARM64-FULL-LINE: uzp1 {{p[0-9]+}}.b, {{p[0-9]+}}.b, {{p[0-9]+}}.b + return Sve.UnzipEven(Sve.CompareGreaterThan(a, b), Sve.CompareEqual(a, b)); } [MethodImpl(MethodImplOptions.NoInlining)] - static Vector UnzipOdd() + static Vector UnzipOddMask(Vector a, Vector b) { - return Sve.UnzipOdd(Sve.CreateTrueMaskInt16(), Sve.CreateFalseMaskInt16()); + //ARM64-FULL-LINE: uzp2 {{p[0-9]+}}.h, {{p[0-9]+}}.h, {{p[0-9]+}}.h + return Sve.CreateBreakAfterMask(Sve.UnzipOdd(Sve.CompareGreaterThan(a, b), Sve.CompareEqual(a, b)), Sve.CreateTrueMaskInt16()); } [MethodImpl(MethodImplOptions.NoInlining)] - static Vector TransposeEven() + static Vector TransposeEvenMask(Vector a, Vector b) { - return Sve.TransposeEven(Sve.CreateFalseMaskInt64(), Sve.CreateTrueMaskInt64()); + //ARM64-FULL-LINE: trn1 {{p[0-9]+}}.d, {{p[0-9]+}}.d, {{p[0-9]+}}.d + return Sve.CreateBreakAfterMask(Sve.TransposeEven(Sve.CompareGreaterThan(a, b), Sve.CompareEqual(a, b)), Sve.CreateFalseMaskInt64()); } [MethodImpl(MethodImplOptions.NoInlining)] - static Vector TransposeOdd() + static Vector TransposeOddMask(Vector a, Vector b) { - return Sve.TransposeOdd(Vector.Zero, Sve.CreateTrueMaskInt16()); + //ARM64-FULL-LINE: trn2 {{p[0-9]+}}.h, {{p[0-9]+}}.h, {{p[0-9]+}}.h + return Sve.TransposeOdd(Sve.CompareGreaterThan(a, b), Sve.CompareEqual(a, b)); } [MethodImpl(MethodImplOptions.NoInlining)] - static Vector ReverseElement() + static Vector ReverseElementMask(Vector a, Vector b) { - return Sve.ReverseElement(Sve.CreateTrueMaskInt16()); + //ARM64-FULL-LINE: rev {{p[0-9]+}}.h, {{p[0-9]+}}.h + return Sve.CreateBreakAfterMask(Sve.ReverseElement(Sve.CompareGreaterThan(a, b)), Sve.CreateFalseMaskInt16()); } [MethodImpl(MethodImplOptions.NoInlining)] - static Vector And() + static Vector AndMask(Vector a, Vector b) { - return Sve.ConditionalSelect( - Sve.CreateTrueMaskInt16(), - Sve.And(Sve.CreateTrueMaskInt16(), Sve.CreateTrueMaskInt16()), - Vector.Zero - ); + //ARM64-FULL-LINE: and {{p[0-9]+}}.b, {{p[0-9]+}}/z, {{p[0-9]+}}.b, {{p[0-9]+}}.b + return Sve.CreateBreakAfterMask( + Sve.ConditionalSelect( + Sve.CreateTrueMaskInt16(), + Sve.And(Sve.CompareGreaterThan(a, b), Sve.CompareEqual(a, b)), + Vector.Zero), + Sve.CreateFalseMaskInt16()); } [MethodImpl(MethodImplOptions.NoInlining)] - static Vector BitwiseClear() + static Vector BitwiseClearMask(Vector a, Vector b) { + //ARM64-FULL-LINE: bic {{p[0-9]+}}.b, {{p[0-9]+}}/z, {{p[0-9]+}}.b, {{p[0-9]+}}.b return Sve.ConditionalSelect( - Sve.CreateFalseMaskInt16(), - Sve.BitwiseClear(Sve.CreateTrueMaskInt16(), Sve.CreateTrueMaskInt16()), - Vector.Zero - ); + Sve.CreateTrueMaskInt16(), + Sve.BitwiseClear(Sve.CompareGreaterThan(a, b), Sve.CompareEqual(a, b)), + Vector.Zero); } [MethodImpl(MethodImplOptions.NoInlining)] - static Vector Xor() + static Vector XorMask(Vector a, Vector b) { - return Sve.ConditionalSelect( - Sve.CreateTrueMaskInt32(), - Sve.Xor(Sve.CreateTrueMaskInt32(), Sve.CreateTrueMaskInt32()), - Vector.Zero - ); + //ARM64-FULL-LINE: eor {{p[0-9]+}}.b, {{p[0-9]+}}/z, {{p[0-9]+}}.b, {{p[0-9]+}}.b + return Sve.CreateBreakAfterMask( + Sve.ConditionalSelect( + Sve.CreateTrueMaskInt32(), + Sve.Xor(Sve.CompareGreaterThan(a, b), Sve.CompareEqual(a, b)), + Vector.Zero), + Sve.CreateFalseMaskInt32()); } [MethodImpl(MethodImplOptions.NoInlining)] - static Vector Or() + static Vector OrMask(Vector a, Vector b) { + //ARM64-FULL-LINE: orr {{p[0-9]+}}.b, {{p[0-9]+}}/z, {{p[0-9]+}}.b, {{p[0-9]+}}.b return Sve.ConditionalSelect( - Sve.CreateTrueMaskInt16(), - Sve.Or(Sve.CreateTrueMaskInt16(), Sve.CreateTrueMaskInt16()), - Vector.Zero - ); + Sve.CreateTrueMaskInt16(), + Sve.Or(Sve.CompareGreaterThan(a, b), Sve.CompareEqual(a, b)), + Vector.Zero); } [MethodImpl(MethodImplOptions.NoInlining)] - static Vector ConditionalSelect() + static Vector ConditionalSelectMask(Vector v, Vector a, Vector b) { - return Sve.ConditionalSelect( - Vector.Zero, - Sve.CreateFalseMaskInt32(), - Sve.CreateTrueMaskInt32() - ); + // Use a passed in vector for the mask to prevent optimising away the select + //ARM64-FULL-LINE: sel {{p[0-9]+}}.b, {{p[0-9]+}}, {{p[0-9]+}}.b, {{p[0-9]+}}.b + return Sve.CreateBreakAfterMask( + Sve.ConditionalSelect(v, Sve.CompareGreaterThan(a, b), Sve.CompareEqual(a, b)), + Sve.CreateFalseMaskInt32()); + } + + // These have multiple uses of the predicate variants + + [MethodImpl(MethodImplOptions.NoInlining)] + static Vector UnzipEvenZipLowMask(Vector a, Vector b) + { + //ARM64-FULL-LINE: zip1 {{p[0-9]+}}.h, {{p[0-9]+}}.h, {{p[0-9]+}}.h + //ARM64-FULL-LINE: uzp1 {{p[0-9]+}}.h, {{p[0-9]+}}.h, {{p[0-9]+}}.h + return Sve.CreateBreakAfterMask( + Sve.UnzipEven( + Sve.ZipLow(Sve.CompareGreaterThan(a, b), Sve.CompareEqual(a, b)), + Sve.CompareLessThan(a, b)), + Sve.CreateTrueMaskInt16()); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Vector TransposeEvenAndMask(Vector v, Vector a, Vector b) + { + //ARM64-FULL-LINE: and {{p[0-9]+}}.b, {{p[0-9]+}}/z, {{p[0-9]+}}.b, {{p[0-9]+}}.b + //ARM64-FULL-LINE: trn1 {{p[0-9]+}}.h, {{p[0-9]+}}.h, {{p[0-9]+}}.h + return Sve.TransposeEven( + Sve.CompareGreaterThan(a, b), + Sve.ConditionalSelect( + Sve.CreateTrueMaskInt16(), + Sve.And(Sve.CompareGreaterThan(a, b), Sve.CompareEqual(a, b)), + Sve.CompareLessThan(a, b))); } -} \ No newline at end of file +} diff --git a/src/tests/Loader/classloader/DefaultInterfaceMethods/constrainedcall/constrained2.ilproj b/src/tests/Loader/classloader/DefaultInterfaceMethods/constrainedcall/constrained2.ilproj index 439059eb517c92..e0fc0740de6f58 100644 --- a/src/tests/Loader/classloader/DefaultInterfaceMethods/constrainedcall/constrained2.ilproj +++ b/src/tests/Loader/classloader/DefaultInterfaceMethods/constrainedcall/constrained2.ilproj @@ -1,4 +1,8 @@ + + + true + diff --git a/src/tests/Loader/classloader/DefaultInterfaceMethods/constrainedcall/constrained2_gm.ilproj b/src/tests/Loader/classloader/DefaultInterfaceMethods/constrainedcall/constrained2_gm.ilproj index c36a90952e1d22..ea1de7ddf0d4fd 100644 --- a/src/tests/Loader/classloader/DefaultInterfaceMethods/constrainedcall/constrained2_gm.ilproj +++ b/src/tests/Loader/classloader/DefaultInterfaceMethods/constrainedcall/constrained2_gm.ilproj @@ -1,4 +1,8 @@ + + + true + diff --git a/src/tests/Loader/classloader/DefaultInterfaceMethods/constrainedcall/constrainedcall.ilproj b/src/tests/Loader/classloader/DefaultInterfaceMethods/constrainedcall/constrainedcall.ilproj index 9777726ad29a5d..5cf4faecf03a79 100644 --- a/src/tests/Loader/classloader/DefaultInterfaceMethods/constrainedcall/constrainedcall.ilproj +++ b/src/tests/Loader/classloader/DefaultInterfaceMethods/constrainedcall/constrainedcall.ilproj @@ -1,4 +1,8 @@ + + + true + diff --git a/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.cs b/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.cs index daa35af75c7502..0171c97429de56 100644 --- a/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.cs +++ b/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.cs @@ -22,6 +22,45 @@ public static void Explicit_Fails() }); } + [Fact] + public static void ExplicitSize_FailsInSequential() + { + Console.WriteLine($"{nameof(ExplicitSize_FailsInSequential)}..."); + + Assert.Throws(() => { var t = typeof(ExplicitSize); }); + + Assert.Throws(() => + { + return new ExplicitSize(); + }); + } + + [Fact] + public static void ExplicitSize_FailsInAuto() + { + Console.WriteLine($"{nameof(ExplicitSize_FailsInAuto)}..."); + + Assert.Throws(() => { var t = typeof(ExplicitSizeAuto); }); + + Assert.Throws(() => + { + return sizeof(ExplicitSizeAuto); + }); + } + + [Fact] + public static void ExplicitSize_FailsInGeneric() + { + Console.WriteLine($"{nameof(ExplicitSize_FailsInGeneric)}..."); + + Assert.Throws(() => { var t = typeof(ExplicitSizeGeneric); }); + + Assert.Throws(() => + { + return new ExplicitSizeGeneric(); + }); + } + [Fact] public static void ZeroLength_Fails() { diff --git a/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.csproj b/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.csproj index 098ebbb26a691a..c9e8dc0015fade 100644 --- a/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.csproj +++ b/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.csproj @@ -5,6 +5,7 @@ true false + 0 diff --git a/src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.il b/src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.il index 47e3e0a53d725a..ca71640f41fc37 100644 --- a/src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.il +++ b/src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.il @@ -14,6 +14,39 @@ .field [0] public valuetype [System.Runtime]System.Guid Guid } +.class public sequential ansi sealed beforefieldinit ExplicitSize + extends [System.Runtime]System.ValueType +{ + .custom instance void [System.Runtime]System.Runtime.CompilerServices.InlineArrayAttribute::.ctor(int32) = ( + 01 00 01 00 00 00 00 00 + ) + + .size 256 + .field [0] public valuetype [System.Runtime]System.Guid Guid +} + +.class public auto ansi sealed beforefieldinit ExplicitSizeAuto + extends [System.Runtime]System.ValueType +{ + .custom instance void [System.Runtime]System.Runtime.CompilerServices.InlineArrayAttribute::.ctor(int32) = ( + 01 00 01 00 00 00 00 00 + ) + + .size 256 + .field [0] public valuetype [System.Runtime]System.Guid Guid +} + +.class public auto ansi sealed beforefieldinit ExplicitSizeGeneric`1 + extends [System.Runtime]System.ValueType +{ + .custom instance void [System.Runtime]System.Runtime.CompilerServices.InlineArrayAttribute::.ctor(int32) = ( + 01 00 01 00 00 00 00 00 + ) + + .size 256 + .field [0] public valuetype [System.Runtime]System.Guid Guid +} + .class public sequential ansi sealed beforefieldinit ZeroLength extends [System.Runtime]System.ValueType { diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/InterfaceVariance/ComplexHierarchyPositive.cs b/src/tests/Loader/classloader/StaticVirtualMethods/InterfaceVariance/ComplexHierarchyPositive.cs index c3c579a4f6c4d1..8e2c861a4e9359 100644 --- a/src/tests/Loader/classloader/StaticVirtualMethods/InterfaceVariance/ComplexHierarchyPositive.cs +++ b/src/tests/Loader/classloader/StaticVirtualMethods/InterfaceVariance/ComplexHierarchyPositive.cs @@ -79,14 +79,14 @@ public static void TestEntryPoint() static void TestTheFooString(string expected) where T : IFoo, new() { - Console.WriteLine($"TestTheFooString {typeof(T).Name} {typeof(T).Name} {expected}"); + Console.WriteLine($"TestTheFooString {typeof(T).Name} {typeof(U).Name} {expected}"); Assert.Equal(expected, GetTheFooString()); Assert.Equal(expected, GetTheFooStringInstance()); } static void TestTheBarString(string expected) where T : IBar, new() { - Console.WriteLine($"TestTheBarString {typeof(T).Name} {typeof(T).Name} {expected}"); + Console.WriteLine($"TestTheBarString {typeof(T).Name} {typeof(U).Name} {expected}"); Assert.Equal(expected, GetTheBarString()); Assert.Equal(expected, GetTheBarStringInstance()); } diff --git a/src/tests/Loader/classloader/Statics/Regressions/SelfReferentialStatics/SelfReferentialStatics.cs b/src/tests/Loader/classloader/Statics/Regressions/SelfReferentialStatics/SelfReferentialStatics.cs new file mode 100644 index 00000000000000..75ad64151e46fd --- /dev/null +++ b/src/tests/Loader/classloader/Statics/Regressions/SelfReferentialStatics/SelfReferentialStatics.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Immutable; +using System.Collections.ObjectModel; +using System.Globalization; +using Xunit; + +public class SelfReferentialStatics +{ + public interface IExample + { + public static Example DefaultExample { get; } = new(); + } + public struct Example : IExample { } + + public struct MyStruct + { + static ImmutableArray One; + } + + public struct Foo + { + public static readonly Foo Empty = default; + } + + public readonly struct StructureWithComplexStaticField + { + private readonly int _value; + + private StructureWithComplexStaticField(int value) + { + _value = value; + } + + public static readonly ReadOnlyMemory StaticField = + new StructureWithComplexStaticField[] { new(0), new(1), new(2), new(3) }; + + public override string ToString() => _value.ToString(CultureInfo.InvariantCulture); + } + + + public struct Bar + { + public static readonly Foo Baz; + public Bar(string message) => System.Console.WriteLine(message); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/118472")] + public static void TestEntryPoint() + { + var example = IExample.DefaultExample; + + new Bar("Should print"); + Console.WriteLine(typeof(StructureWithComplexStaticField).FullName); + Console.WriteLine(new Foo()); + Console.WriteLine(example.GetType()); + Console.WriteLine(new MyStruct()); + Console.WriteLine("Worked"); + } +} diff --git a/src/tests/Loader/classloader/Statics/Regressions/SelfReferentialStatics/SelfReferentialStatics.csproj b/src/tests/Loader/classloader/Statics/Regressions/SelfReferentialStatics/SelfReferentialStatics.csproj new file mode 100644 index 00000000000000..efc38a9429de55 --- /dev/null +++ b/src/tests/Loader/classloader/Statics/Regressions/SelfReferentialStatics/SelfReferentialStatics.csproj @@ -0,0 +1,8 @@ + + + true + + + + + diff --git a/src/tests/Regressions/coreclr/16354/notimplemented.ilproj b/src/tests/Regressions/coreclr/16354/notimplemented.ilproj index 66165d6484cdb1..6960c9f6da06f6 100644 --- a/src/tests/Regressions/coreclr/16354/notimplemented.ilproj +++ b/src/tests/Regressions/coreclr/16354/notimplemented.ilproj @@ -5,7 +5,9 @@ false - + + + true diff --git a/src/tests/Regressions/coreclr/GitHub_117393/CMakeLists.txt b/src/tests/Regressions/coreclr/GitHub_117393/CMakeLists.txt new file mode 100644 index 00000000000000..e50bf224c6fed4 --- /dev/null +++ b/src/tests/Regressions/coreclr/GitHub_117393/CMakeLists.txt @@ -0,0 +1,10 @@ +project (nativetest117393) +include_directories( ${INC_PLATFORM_DIR} ) +set(SOURCES nativetest117393.cpp) + +# add the shared library +add_library (nativetest117393 SHARED ${SOURCES}) +target_link_libraries(nativetest117393 PRIVATE ${LINK_LIBRARIES_ADDITIONAL}) + +# add the install targets +install (TARGETS nativetest117393 DESTINATION bin) diff --git a/src/tests/Regressions/coreclr/GitHub_117393/nativetest117393.cpp b/src/tests/Regressions/coreclr/GitHub_117393/nativetest117393.cpp new file mode 100644 index 00000000000000..45d124ddf851c4 --- /dev/null +++ b/src/tests/Regressions/coreclr/GitHub_117393/nativetest117393.cpp @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include <../../Interop/common/xplatform.h> +#include <../../Interop/common/ComHelpers.h> +#include "platformdefines.h" + +#ifdef _WIN32 +#pragma warning(push) +#pragma warning(disable:4265 4577) +#include +#pragma warning(pop) +#else // _WIN32 +#include +#endif // _WIN32 + +// #include + +// Interface ID for ITest +// {92BAA992-DB5A-4ADD-977B-B22838EE91FD} +static const GUID IID_ITest = +{ 0x92baa992, 0xdb5a, 0x4add, { 0x97, 0x7b, 0xb2, 0x28, 0x38, 0xee, 0x91, 0xfd } }; + +// Interface definition for ITest +MIDL_INTERFACE("92BAA992-DB5A-4ADD-977B-B22838EE91FD") +ITest : public IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE Test() = 0; +}; + +void NativeTestThread(IUnknown* pUnknown) +{ + ITest* pITest = nullptr; + pUnknown->QueryInterface(IID_ITest, reinterpret_cast(&pITest)); + // This tests causes the QueryInterface to fail, so we don't release the pITest +} + +#ifndef _WIN32 +void* NativeTestThreadUnix(void* pUnknown) +{ + NativeTestThread((IUnknown*)pUnknown); + return NULL; +} + +#define AbortIfFail(st) if (st != 0) abort() + +#endif // !_WIN32 + +extern "C" DLL_EXPORT void TestFromNativeThread(IUnknown* pUnknown) +{ +#ifdef _WIN32 + std::thread t1(NativeTestThread, pUnknown); + t1.join(); +#else // _WIN32 + // For Unix, we need to use pthreads to create the thread so that we can set its stack size. + // We need to set the stack size due to the very small (80kB) default stack size on MUSL + // based Linux distros. + pthread_attr_t attr; + int st = pthread_attr_init(&attr); + AbortIfFail(st); + + // set stack size to 1.5MB + st = pthread_attr_setstacksize(&attr, 0x180000); + AbortIfFail(st); + + pthread_t t; + st = pthread_create(&t, &attr, NativeTestThreadUnix, (void*)pUnknown); + AbortIfFail(st); + + st = pthread_join(t, NULL); + AbortIfFail(st); +#endif // _WIN32 +} diff --git a/src/tests/Regressions/coreclr/GitHub_117393/test117393.cs b/src/tests/Regressions/coreclr/GitHub_117393/test117393.cs new file mode 100644 index 00000000000000..c7f93f19577f03 --- /dev/null +++ b/src/tests/Regressions/coreclr/GitHub_117393/test117393.cs @@ -0,0 +1,70 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Xunit; + +namespace Test117393 +{ + class TestObject : ICustomQueryInterface + { + public CustomQueryInterfaceResult GetInterface(ref Guid iid, out IntPtr ppv) + { + // Induce NullReferenceException + string s = null; + Console.WriteLine(s.Length); + ppv = IntPtr.Zero; + return CustomQueryInterfaceResult.Failed; + } + } + + class TestWrappers : ComWrappers + { + protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) + { + // Unknown type + count = 0; + return null; + } + + protected override object? CreateObject(IntPtr externalComObject, CreateObjectFlags flags) + { + return null; + } + + protected override void ReleaseObjects(IEnumerable objects) + { + } + } + + public class Program + { + [DllImport("nativetest117393")] + private static extern void TestFromNativeThread(IntPtr pUnknown); + + [Fact] + public static void TestEntryPoint() + { + bool reportedUnhandledException = false; + UnhandledExceptionEventHandler handler = (sender, e) => + { + reportedUnhandledException = true; + }; + + var cw = new TestWrappers(); + TestObject obj = new TestObject(); + // Create a managed object wrapper for the Demo object. + // Note the returned COM interface will always be for IUnknown. + IntPtr ccwUnknown = cw.GetOrCreateComInterfaceForObject(obj, CreateComInterfaceFlags.None); + AppDomain.CurrentDomain.UnhandledException += handler; + TestFromNativeThread(ccwUnknown); + AppDomain.CurrentDomain.UnhandledException -= handler; + Marshal.Release(ccwUnknown); + + Assert.False(reportedUnhandledException, "There should be no unhandled exception on the secondary thread"); + } + } +} diff --git a/src/tests/Regressions/coreclr/GitHub_117393/test117393.csproj b/src/tests/Regressions/coreclr/GitHub_117393/test117393.csproj new file mode 100644 index 00000000000000..db98ffa8f50551 --- /dev/null +++ b/src/tests/Regressions/coreclr/GitHub_117393/test117393.csproj @@ -0,0 +1,13 @@ + + + + true + 1 + + + + + + + + diff --git a/src/tests/async/byref-param/byref-param.cs b/src/tests/async/byref-param/byref-param.cs new file mode 100644 index 00000000000000..6676f2051dbfbe --- /dev/null +++ b/src/tests/async/byref-param/byref-param.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading.Tasks; +using Xunit; + +public class Async2ByrefParam +{ + [Fact] + public static int TestEntryPoint() + { + return Test().GetAwaiter().GetResult(); + } + + private static async Task Test() + { + return await HasByrefParam(out int val) + val; + } + + private static Task HasByrefParam(out int foo) + { + foo = 47; + return Task.FromResult(53); + } +} diff --git a/src/tests/async/byref-param/byref-param.csproj b/src/tests/async/byref-param/byref-param.csproj new file mode 100644 index 00000000000000..9367a79b2edbb1 --- /dev/null +++ b/src/tests/async/byref-param/byref-param.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/tests/async/inst-unbox-thunks/inst-unbox-thunks.cs b/src/tests/async/inst-unbox-thunks/inst-unbox-thunks.cs new file mode 100644 index 00000000000000..8a727672443835 --- /dev/null +++ b/src/tests/async/inst-unbox-thunks/inst-unbox-thunks.cs @@ -0,0 +1,186 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using Xunit; + +public class InstUnBoxThunks +{ + interface I0 + { + Task M0(); + Task M1(object a0, object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8); + } + + struct Struct0 : I0 + { + public async Task M0() + { + await Task.Yield(); + return "hi"; + } + + public async Task M1(object a0, object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8) + { + await Task.Yield(); + return "hello"; + } + } + + static I0 o00; + static async Task CallStruct0M0() + { + o00 = new Struct0(); + return await o00.M0(); + } + + static I0 o01; + static async Task CallStruct0M1() + { + o01 = new Struct0(); + return await o01.M1(default, default, default, default, default, default, default, default, default); + } + + struct Struct1 : I0 + { + public async Task M0() + { + await Task.Yield(); + return typeof(T).ToString(); + } + + public async Task M1(object a0, object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8) + { + await Task.Yield(); + return typeof(T).ToString(); + } + } + + static I0 o10; + static async Task CallStruct1M0() + { + o10 = new Struct1(); + return await o10.M0(); + } + + static I0 o11; + static async Task CallStruct1M1() + { + o11 = new Struct1(); + return await o11.M1(default, default, default, default, default, default, default, default, default); + } + + class Box where U : I0 + { + public U f; + } + + static async Task CallStruct1M0Field(Box arg) where T : I0 + { + return await arg.f.M0(); + } + + static async Task CallStruct1M1Field(Box arg) where T : I0 + { + return await arg.f.M1(default, default, default, default, default, default, default, default, default); + } + + static Box> b1 = new(); + static async Task CallStruct1M0b() + { + b1.f = new Struct1(); + return await CallStruct1M0Field(b1); + } + + static Box> b2 = new(); + static async Task CallStruct1M1b() + { + b2.f = new Struct1(); + return await CallStruct1M1Field(b2); + } + + + [Fact] + public static void NoArgUnbox() + { + Assert.Equal("hi", CallStruct0M0().Result); + } + + [Fact] + public static void ManyArgUnbox() + { + Assert.Equal("hello", CallStruct0M1().Result); + } + + [Fact] + public static void NoArgGenericUnbox() + { + Assert.Equal("System.String", CallStruct1M0().Result); + } + + [Fact] + public static void ManyArgGenericUnbox() + { + Assert.Equal("System.String", CallStruct1M1().Result); + } + + [Fact] + public static void NoArgGenericInstantiating() + { + Assert.Equal("System.String", CallStruct1M0b().Result); + } + + [Fact] + public static void ManyArgGenericInstantiating() + { + Assert.Equal("System.String", CallStruct1M1b().Result); + } + + interface I2 + { + Task M0(); + Task M1(object a0, object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8); + } + + class Class2 : I2 + { + public async Task M0() + { + await Task.Yield(); + return typeof(T).ToString(); + } + + public async Task M1(object a0, object a1, object a2, object a3, object a4, object a5, object a6, object a7, object a8) + { + await Task.Yield(); + return typeof(T).ToString(); + } + } + + static I2 o2; + static async Task CallClass2M0() + { + o2 = new Class2(); + return await o2.M0(); + } + + static async Task CallClass2M1() + { + o2 = new Class2(); + return await o2.M1(default, default, default, default, default, default, default, default, default); + } + + [Fact] + public static void NoArgGVM() + { + Assert.Equal("System.String", CallClass2M0().Result); + } + + [Fact] + public static void ManyArgGVM() + { + Assert.Equal("System.String", CallClass2M1().Result); + } +} diff --git a/src/tests/async/inst-unbox-thunks/inst-unbox-thunks.csproj b/src/tests/async/inst-unbox-thunks/inst-unbox-thunks.csproj new file mode 100644 index 00000000000000..9367a79b2edbb1 --- /dev/null +++ b/src/tests/async/inst-unbox-thunks/inst-unbox-thunks.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/tests/async/reflection/reflection-simple.cs b/src/tests/async/reflection/reflection-simple.cs new file mode 100644 index 00000000000000..7c446df5c7839a --- /dev/null +++ b/src/tests/async/reflection/reflection-simple.cs @@ -0,0 +1,238 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Linq.Expressions; +using System.Reflection; +using System.Reflection.Emit; +using System.Threading.Tasks; +using Xunit; + +public class Async2Reflection +{ + [Fact] + public static void MethodInfo_Invoke_TaskReturning() + { + var mi = typeof(Async2Reflection).GetMethod("Foo", BindingFlags.Static | BindingFlags.NonPublic)!; + Task r = (Task)mi.Invoke(null, null)!; + + dynamic d = new Async2Reflection(); + + Assert.Equal(100, (int)(r.Result + d.Bar().Result)); + } + +#pragma warning disable SYSLIB5007 // 'System.Runtime.CompilerServices.AsyncHelpers' is for evaluation purposes only + [Fact] + public static void MethodInfo_Invoke_AsyncHelper() + { + var mi = typeof(System.Runtime.CompilerServices.AsyncHelpers).GetMethod("Await", BindingFlags.Static | BindingFlags.Public, new Type[] { typeof(Task) })!; + Assert.NotNull(mi); + Assert.Throws(() => mi.Invoke(null, new object[] { FooTask() })); + + // Sadly the following does not throw and results in UB + // We cannot completely prevent putting a token of an Async method into IL stream. + // CONSIDER: perhaps JIT could throw? + // + // dynamic d = FooTask(); + // System.Runtime.CompilerServices.AsyncHelpers.Await(d); + } +#pragma warning restore SYSLIB5007 + + private static async Task Foo() + { + await Task.Yield(); + return 90; + } + + private static async Task FooTask() + { + await Task.Yield(); + } + + private async Task Bar() + { + await Task.Yield(); + return 10; + } + +[Fact] + public static void AwaitTaskReturningExpressionLambda() + { + var expr1 = (Expression>>)(() => Task.FromResult(42)); + var del = expr1.Compile(); + Assert.Equal(42, del().Result); + + AwaitF(42, del).GetAwaiter().GetResult(); + } + + static async Task AwaitF(T expected, Func> f) + { + var res = await f.Invoke(); + Assert.Equal(expected, res); + } + + public interface IExample + { + Task TaskReturning(); + T TReturning(); + } + + public class ExampleClass : IExample + { + public Task TaskReturning() + { + return null; + } + + public Task TReturning() + { + return null; + } + } + + public struct ExampleStruct : IExample + { + public Task TaskReturning() + { + return null; + } + + public Task TReturning() + { + return null; + } + } + + [Fact] + public static void GetInterfaceMap() + { + Type interfaceType = typeof(IExample); + Type classType = typeof(ExampleClass); + + InterfaceMapping map = classType.GetInterfaceMap(interfaceType); + + Assert.Equal(2, map.InterfaceMethods.Length); + Assert.Equal("System.Threading.Tasks.Task TaskReturning() --> System.Threading.Tasks.Task TaskReturning()", + $"{map.InterfaceMethods[0]?.ToString()} --> {map.TargetMethods[0]?.ToString()}"); + + Assert.Equal("System.Threading.Tasks.Task TReturning() --> System.Threading.Tasks.Task TReturning()", + $"{map.InterfaceMethods[1]?.ToString()} --> {map.TargetMethods[1]?.ToString()}"); + + Type structType = typeof(ExampleStruct); + + map = structType.GetInterfaceMap(interfaceType); + Assert.Equal(2, map.InterfaceMethods.Length); + Assert.Equal("System.Threading.Tasks.Task TaskReturning() --> System.Threading.Tasks.Task TaskReturning()", + $"{map.InterfaceMethods[0]?.ToString()} --> {map.TargetMethods[0]?.ToString()}"); + + Assert.Equal("System.Threading.Tasks.Task TReturning() --> System.Threading.Tasks.Task TReturning()", + $"{map.InterfaceMethods[1]?.ToString()} --> {map.TargetMethods[1]?.ToString()}"); + } + + [Fact] + public static void TypeBuilder_DefineMethod() + { + // we will be compiling a dynamic vesion of this method + // + // public async static Task StaticMethod(Task arg) + // { + // await arg; + // } + + // Define a dynamic assembly and module + AssemblyName assemblyName = new AssemblyName("DynamicAssembly"); + AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule"); + + // Define a type + TypeBuilder typeBuilder = moduleBuilder.DefineType("DynamicType", TypeAttributes.Public); + + // Define a method + MethodBuilder methodBuilder = typeBuilder.DefineMethod( + "DynamicMethod", + MethodAttributes.Public | MethodAttributes.Static, + typeof(Task), + new Type[] { typeof(Task) }); + + // Set `MethodImpl.Async` flag + methodBuilder.SetImplementationFlags(MethodImplAttributes.Async); + + // { + // Await(arg_0); + // ret; + // } + ILGenerator ilGenerator = methodBuilder.GetILGenerator(); + ilGenerator.Emit(OpCodes.Ldarg_0); +#pragma warning disable SYSLIB5007 // 'System.Runtime.CompilerServices.AsyncHelpers' is for evaluation purposes only + var mi = typeof(System.Runtime.CompilerServices.AsyncHelpers).GetMethod("Await", BindingFlags.Static | BindingFlags.Public, new Type[] { typeof(Task) })!; +#pragma warning restore SYSLIB5007 + ilGenerator.EmitCall(OpCodes.Call, mi, new Type[] { typeof(Task) }); + ilGenerator.Emit(OpCodes.Ret); + + // Create the type and invoke the method + Type dynamicType = typeBuilder.CreateType(); + MethodInfo dynamicMethod = dynamicType.GetMethod("DynamicMethod"); + var del = dynamicMethod.CreateDelegate>(); + + // the following should not crash + del(Task.CompletedTask); + del(FooTask()); + } + + public class PrivateAsync1 + { + public static int s; + private static async Task a_task1(int i) + { + s++; + if (i == 0) + { + await Task.Yield(); + return default; + } + + return await Accessors2.accessor(null, i - 1); + } + } + + public class PrivateAsync2 + { + public static int s; + private static async Task a_task2(int i) + { + s++; + if (i == 0) + { + await Task.Yield(); + return default; + } + + return await Accessors1.accessor(null, i - 1); + } + } + + public class Accessors1 + { + [UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = "a_task1")] + public extern static Task accessor(PrivateAsync1 o, int i); + } + + public class Accessors2 + { + [UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = "a_task2")] + public extern static Task accessor(PrivateAsync2 o, int i); + } + + [Fact] + public static void UnsafeAccessors() + { + Accessors2.accessor(null, 7).GetAwaiter().GetResult(); + Assert.Equal(4, PrivateAsync1.s); + Assert.Equal(4, PrivateAsync2.s); + + Accessors1.accessor(null, 7).GetAwaiter().GetResult(); + Assert.Equal(8, PrivateAsync1.s); + Assert.Equal(8, PrivateAsync2.s); + } +} diff --git a/src/tests/async/reflection/reflection-simple.csproj b/src/tests/async/reflection/reflection-simple.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/async/reflection/reflection-simple.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/tests/async/reflection/reflectionSimple.cs b/src/tests/async/reflection/reflectionSimple.cs deleted file mode 100644 index 108de11aab2488..00000000000000 --- a/src/tests/async/reflection/reflectionSimple.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Reflection; -using System.Threading.Tasks; -using Xunit; - -public class Async2Reflection -{ - [Fact] - public static void TestEntryPoint() - { - var mi = typeof(Async2Reflection).GetMethod("Foo", BindingFlags.Static | BindingFlags.NonPublic)!; - Task r = (Task)mi.Invoke(null, null)!; - - dynamic d = new Async2Reflection(); - - Assert.Equal(100, (int)(r.Result + d.Bar().Result)); - } - - private static async Task Foo() - { - await Task.Yield(); - return 90; - } - - private async Task Bar() - { - await Task.Yield(); - return 10; - } -} diff --git a/src/tests/async/shared-generic/shared-generic.cs b/src/tests/async/shared-generic/shared-generic.cs index c75abab84bb410..007cbf1f0cc382 100644 --- a/src/tests/async/shared-generic/shared-generic.cs +++ b/src/tests/async/shared-generic/shared-generic.cs @@ -79,6 +79,31 @@ private static async Task Async2EntryPoint(Type t, T value) Assert.Equal(value, await GenericClass.StaticReturnClassTypeAsync1(value)); Assert.Equal(value, await GenericClass.StaticReturnMethodTypeAsync1(value)); } + + [Fact] + public static void TestInterface() + { + TestInterfaceAsync(new JsonDeserializer()).GetAwaiter().GetResult(); + } + + private static async Task TestInterfaceAsync(ITypeDeserializer deserializer) + { + Assert.Equal("abc", await deserializer.ReadString()); + } + + private struct ArrayReader + { + } + + private interface ITypeDeserializer + { + Task ReadString(); + } + + private class JsonDeserializer : ITypeDeserializer + { + Task ITypeDeserializer.ReadString() => Task.FromResult("abc"); + } } public class GenericClass diff --git a/src/tests/async/synchronization-context/synchronization-context.cs b/src/tests/async/synchronization-context/synchronization-context.cs new file mode 100644 index 00000000000000..d1b053cd7ebf0a --- /dev/null +++ b/src/tests/async/synchronization-context/synchronization-context.cs @@ -0,0 +1,219 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +public class Async2SynchronizationContext +{ + [Fact] + public static void TestSyncContextContinue() + { + SynchronizationContext prevContext = SynchronizationContext.Current; + try + { + SynchronizationContext.SetSynchronizationContext(new MySyncContext()); + TestSyncContextContinueAsync().GetAwaiter().GetResult(); + } + finally + { + SynchronizationContext.SetSynchronizationContext(prevContext); + } + } + + private static async Task TestSyncContextContinueAsync() + { + MySyncContext context = (MySyncContext)SynchronizationContext.Current; + await WrappedYieldToThreadPool(suspend: false); + Assert.Same(context, SynchronizationContext.Current); + + await WrappedYieldToThreadPool(suspend: true); + Assert.Same(context, SynchronizationContext.Current); + + await WrappedYieldToThreadPool(suspend: true).ConfigureAwait(true); + Assert.Same(context, SynchronizationContext.Current); + + await WrappedYieldToThreadPool(suspend: false).ConfigureAwait(false); + Assert.Same(context, SynchronizationContext.Current); + + // Currently disabled since ConfigureAwait does not become a runtime async call, + // and this has a race condition until it does (where the callee finishes before + // we check IsCompleted on the awaiter). + //await WrappedYieldToThreadPool(suspend: true).ConfigureAwait(false); + //Assert.Null(SynchronizationContext.Current); + + await WrappedYieldToThreadWithCustomSyncContext(); + Assert.Null(SynchronizationContext.Current); + } + + private static async Task WrappedYieldToThreadPool(bool suspend) + { + if (suspend) + { + await Task.Yield(); + } + } + + private static async Task WrappedYieldToThreadWithCustomSyncContext() + { + Assert.Null(SynchronizationContext.Current); + await new YieldToThreadWithCustomSyncContext(); + Assert.True(SynchronizationContext.Current is MySyncContext { }); + } + + private class MySyncContext : SynchronizationContext + { + public override void Post(SendOrPostCallback d, object state) + { + ThreadPool.UnsafeQueueUserWorkItem(_ => + { + SynchronizationContext prevContext = Current; + try + { + SetSynchronizationContext(this); + d(state); + } + finally + { + SetSynchronizationContext(prevContext); + } + }, null); + } + } + + private struct YieldToThreadWithCustomSyncContext : ICriticalNotifyCompletion + { + public YieldToThreadWithCustomSyncContext GetAwaiter() => this; + + public void UnsafeOnCompleted(Action continuation) + { + new Thread(state => + { + SynchronizationContext.SetSynchronizationContext(new MySyncContext()); + continuation(); + }).Start(); + } + + public void OnCompleted(Action continuation) + { + throw new NotImplementedException(); + } + + public bool IsCompleted => false; + + public void GetResult() { } + } + + [Fact] + public static void TestSyncContextSaveRestore() + { + SynchronizationContext prevContext = SynchronizationContext.Current; + try + { + SynchronizationContext.SetSynchronizationContext(new SyncContextWithoutRestore()); + TestSyncContextSaveRestoreAsync().GetAwaiter().GetResult(); + } + finally + { + SynchronizationContext.SetSynchronizationContext(prevContext); + } + } + + private static async Task TestSyncContextSaveRestoreAsync() + { + Assert.True(SynchronizationContext.Current is SyncContextWithoutRestore); + await ClearSyncContext(); + Assert.True(SynchronizationContext.Current is SyncContextWithoutRestore); + } + + private static async Task ClearSyncContext() + { + SynchronizationContext.SetSynchronizationContext(null); + } + + [Fact] + public static void TestSyncContextNotRestored() + { + SynchronizationContext prevContext = SynchronizationContext.Current; + try + { + SynchronizationContext.SetSynchronizationContext(new SyncContextWithoutRestore()); + TestSyncContextNotRestoredAsync().GetAwaiter().GetResult(); + } + finally + { + SynchronizationContext.SetSynchronizationContext(prevContext); + } + } + + private static async Task TestSyncContextNotRestoredAsync() + { + Assert.True(SynchronizationContext.Current is SyncContextWithoutRestore); + await SuspendThenClearSyncContext(); + Assert.Null(SynchronizationContext.Current); + } + + private static async Task SuspendThenClearSyncContext() + { + Assert.True(SynchronizationContext.Current is SyncContextWithoutRestore); + SyncContextWithoutRestore syncCtx = (SyncContextWithoutRestore)SyncContextWithoutRestore.Current; + Assert.Equal(0, syncCtx.NumPosts); + + await Task.Yield(); + Assert.Null(SynchronizationContext.Current); + Assert.Equal(1, syncCtx.NumPosts); + } + + private class SyncContextWithoutRestore : SynchronizationContext + { + public int NumPosts; + + public override void Post(SendOrPostCallback d, object state) + { + NumPosts++; + ThreadPool.UnsafeQueueUserWorkItem(_ => + { + d(state); + }, null); + } + } + + [Fact] + public static void TestContinueOnCorrectSyncContext() + { + SynchronizationContext prevContext = SynchronizationContext.Current; + try + { + TestContinueOnCorrectSyncContextAsync().GetAwaiter().GetResult(); + } + finally + { + SynchronizationContext.SetSynchronizationContext(prevContext); + } + } + + private static async Task TestContinueOnCorrectSyncContextAsync() + { + MySyncContext context1 = new MySyncContext(); + MySyncContext context2 = new MySyncContext(); + + SynchronizationContext.SetSynchronizationContext(context1); + await SetContext(context2, suspend: false); + Assert.True(SynchronizationContext.Current == context1); + + await SetContext(context2, suspend: true); + Assert.True(SynchronizationContext.Current == context1); + } + + private static async Task SetContext(SynchronizationContext context, bool suspend) + { + SynchronizationContext.SetSynchronizationContext(context); + + if (suspend) + await Task.Yield(); + } +} diff --git a/src/tests/async/synchronization-context/synchronization-context.csproj b/src/tests/async/synchronization-context/synchronization-context.csproj new file mode 100644 index 00000000000000..1ae294349c376f --- /dev/null +++ b/src/tests/async/synchronization-context/synchronization-context.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/tests/baseservices/compilerservices/UnsafeAccessors/UnsafeAccessorsTests.csproj b/src/tests/baseservices/compilerservices/UnsafeAccessors/UnsafeAccessorsTests.csproj index 71db192cc50085..96bd91d1a0a7c8 100644 --- a/src/tests/baseservices/compilerservices/UnsafeAccessors/UnsafeAccessorsTests.csproj +++ b/src/tests/baseservices/compilerservices/UnsafeAccessors/UnsafeAccessorsTests.csproj @@ -3,6 +3,9 @@ true true + + true + true diff --git a/src/tests/baseservices/exceptions/RaiseAppDomainUnhandledExceptionEvent/RaiseEvent.cs b/src/tests/baseservices/exceptions/RaiseAppDomainUnhandledExceptionEvent/RaiseEvent.cs index 94f5e4f7422ddc..aeff4dbd63771a 100644 --- a/src/tests/baseservices/exceptions/RaiseAppDomainUnhandledExceptionEvent/RaiseEvent.cs +++ b/src/tests/baseservices/exceptions/RaiseAppDomainUnhandledExceptionEvent/RaiseEvent.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using TestLibrary; using Xunit; @@ -19,7 +20,14 @@ public HandlerRegistration(UnhandledExceptionEventHandler handler) public void Dispose() { AppDomain.CurrentDomain.UnhandledException -= _handler; + + // See usage of s_crashingThreadId in the ExceptionHandling class. + // This is to ensure that the static field is reset after the test. + GetCrashingThreadId(null) = 0; } + + [UnsafeAccessor(UnsafeAccessorKind.StaticField, Name = "s_crashingThreadId")] + private static extern ref ulong GetCrashingThreadId([UnsafeAccessorType("System.AppContext")]object? obj); } [ThreadStatic] diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/COOL/rethrow.cs b/src/tests/baseservices/exceptions/regressions/V1/SEH/COOL/rethrow.cs index 059a893d41879d..4c5eafe3136904 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/COOL/rethrow.cs +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/COOL/rethrow.cs @@ -53,7 +53,7 @@ public UserException4(int id) : base(id) public class RethrowException { private int ThreadId; - public RethrowException(int id){ + private RethrowException(int id){ ThreadId = id; } diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.cs b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.cs index 288c2ce8fc8d83..bc7a917f69b4c7 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.cs +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.cs @@ -41,7 +41,7 @@ public UserException4(int id){ public class HandlerException { private int ThreadId; - public HandlerException(int id){ + private HandlerException(int id){ ThreadId = id; } diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.cs b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.cs index d0d39c4321c068..c7112b85949446 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.cs +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.cs @@ -16,7 +16,7 @@ public UserException(int id){ public class MultipleException { private int ThreadId; - public MultipleException(int id){ + private MultipleException(int id){ ThreadId = id; } diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.cs b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.cs index cb5348312812fc..3f0af2599433ac 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.cs +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.cs @@ -41,7 +41,7 @@ public UserException4(int id){ public class NestedException { private int ThreadId; - public NestedException(int id){ + private NestedException(int id){ ThreadId = id; } diff --git a/src/tests/baseservices/exceptions/unhandled/unhandled.cs b/src/tests/baseservices/exceptions/unhandled/unhandled.cs index ff0827cc53ea10..a8724a68e8ff5c 100644 --- a/src/tests/baseservices/exceptions/unhandled/unhandled.cs +++ b/src/tests/baseservices/exceptions/unhandled/unhandled.cs @@ -48,11 +48,15 @@ static void Main(string[] args) { throw new Exception("Test"); } - if (args[0] == "mainhardware") + else if (args[0] == "mainhardware") { string s = null; Console.WriteLine(s.Length); // This will cause a NullReferenceException } + else if (args[0] == "mainthreadinterrupted") + { + throw new ThreadInterruptedException("Test"); + } else if (args[0] == "foreign") { InvokeCallbackOnNewThread(&ThrowException); @@ -79,6 +83,12 @@ static void Main(string[] args) t.Start(); t.Join(); } + else if (args[0] == "secondarythreadinterrupted") + { + Thread t = new Thread(() => throw new ThreadInterruptedException("Test")); + t.Start(); + t.Join(); + } } } } diff --git a/src/tests/baseservices/exceptions/unhandled/unhandledTester.cs b/src/tests/baseservices/exceptions/unhandled/unhandledTester.cs index 20ef23a6bfc52c..bc47610eca153e 100644 --- a/src/tests/baseservices/exceptions/unhandled/unhandledTester.cs +++ b/src/tests/baseservices/exceptions/unhandled/unhandledTester.cs @@ -109,6 +109,13 @@ static void RunExternalProcess(string unhandledType, string assembly) throw new Exception("Missing Unhandled exception header"); } } + if (unhandledType == "mainthreadinterrupted" || unhandledType == "secondarythreadinterrupted") + { + if (lines[0] != "Unhandled exception. System.Threading.ThreadInterruptedException: Test") + { + throw new Exception("Missing Unhandled exception header"); + } + } else if (unhandledType == "foreign") { if (!lines[0].StartsWith("Unhandled exception. System.DllNotFoundException:") && @@ -149,8 +156,10 @@ public static void TestEntryPoint() { RunExternalProcess("main", "unhandled.dll"); RunExternalProcess("mainhardware", "unhandled.dll"); + RunExternalProcess("mainthreadinterrupted", "unhandled.dll"); RunExternalProcess("secondary", "unhandled.dll"); RunExternalProcess("secondaryhardware", "unhandled.dll"); + RunExternalProcess("secondarythreadinterrupted", "unhandled.dll"); RunExternalProcess("foreign", "unhandled.dll"); File.Delete(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dependencytodelete.dll")); RunExternalProcess("missingdependency", "unhandledmissingdependency.dll"); diff --git a/src/tests/baseservices/threading/regressions/115178/115178.cs b/src/tests/baseservices/threading/regressions/115178/115178.cs index 0ad7a004945eab..0367f81c70df70 100644 --- a/src/tests/baseservices/threading/regressions/115178/115178.cs +++ b/src/tests/baseservices/threading/regressions/115178/115178.cs @@ -16,8 +16,6 @@ as a result of internal interrupt handling. public class Test_wait_interrupted_user_apc { - public static bool Run115178Test => TestLibrary.Utilities.IsWindows; - [DllImport("kernel32.dll")] private static extern IntPtr GetCurrentProcess(); @@ -165,9 +163,11 @@ private static void RunTestUsingTimedWait() stopwatch.Stop(); - if (stopwatch.ElapsedMilliseconds < 2000) + long elapsedMilliseconds = stopwatch.ElapsedMilliseconds; + if (elapsedMilliseconds < 1970) { - Console.WriteLine($"Error waiting on event, wait returned too early."); + // Wait uses low resolution timer, test includes a margin of 30ms to account for timer resolution differences. + Console.WriteLine($"Error waiting on event, wait returned too early. Waited {elapsedMilliseconds} ms, expected at least 1970 ms."); result = 5; } @@ -283,12 +283,18 @@ private static void RunTestInterruptInfiniteWait() GC.KeepAlive(callback); } - [ConditionalFact(nameof(Run115178Test))] + [ConditionalFact(typeof(TestLibrary.Utilities), nameof(TestLibrary.Utilities.IsWindows))] public static int TestEntryPoint() { RunTestUsingInfiniteWait(); RunTestUsingTimedWait(); - RunTestInterruptInfiniteWait(); + + // Thread.Interrupt is not implemented on NativeAOT - https://github.com/dotnet/runtime/issues/69919 + if (!TestLibrary.Utilities.IsNativeAot) + { + RunTestInterruptInfiniteWait(); + } + return result; } } diff --git a/src/tests/build.proj b/src/tests/build.proj index 8499575b01c257..ca195bf8041862 100644 --- a/src/tests/build.proj +++ b/src/tests/build.proj @@ -263,6 +263,7 @@ /p:TargetOS=$(TargetOS) /p:TargetArchitecture=$(TargetArchitecture) /p:Configuration=$(Configuration) /p:CrossBuild=$(CrossBuild) <_ConfigurationProperties Condition="'$(UseLocalAppHostPack)' == 'true'">$(_ConfigurationProperties) -p:EnableAppHostPackDownload=false -p:EnableTargetingPackDownload=false -p:EnableRuntimePackDownload=false <_ForceRestore Condition="'$(_ForceRestore)' == 'true'">-f - "$(DotNetTool)" restore $(_ForceRestore) -r $(RuntimeIdentifier) $(RestoreProj) $(PackageVersionArg) /p:SetTFMForRestore=true $(_ConfigurationProperties) + "$(DotNetTool)" restore $(_ForceRestore) -r $(RuntimeIdentifier) $(RestoreProj) $(PackageVersionArg) /p:SetTFMForRestore=true /p:RuntimeIdentifier=$(RuntimeIdentifier) $(_ConfigurationProperties) @@ -442,10 +443,10 @@ - - diff --git a/src/tests/issues.targets b/src/tests/issues.targets index be44cbbe0ab078..0319289be41862 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -30,9 +30,6 @@ https://github.com/dotnet/runtime/issues/83658 - - https://github.com/dotnet/runtime/issues/116060 - https://github.com/dotnet/runtime/issues/5933 @@ -543,51 +540,9 @@ Not compatible with crossgen2 - - https://github.com/dotnet/runtime/issues/109200 - - - https://github.com/dotnet/runtime/issues/109200 - - - https://github.com/dotnet/runtime/issues/109201 - - - https://github.com/dotnet/runtime/issues/108255 - - - https://github.com/dotnet/runtime/issues/108255 - - - https://github.com/dotnet/runtime/issues/109202 - - - https://github.com/dotnet/runtime/issues/108255 - - - https://github.com/dotnet/runtime/issues/108255 - - - https://github.com/dotnet/runtime/issues/108255 - - - https://github.com/dotnet/runtime/issues/109309 - - - https://github.com/dotnet/runtime/issues/109309 - - - https://github.com/dotnet/runtime/issues/109310 - https://github.com/dotnet/runtime/issues/109311 - - https://github.com/dotnet/runtime/issues/109312 - - - https://github.com/dotnet/runtime/issues/109313 - https://github.com/dotnet/runtime/issues/109314 @@ -989,15 +944,6 @@ https://github.com/dotnet/runtimelab/issues/155: Reflection.Emit - - - - - - - - - @@ -1771,8 +1717,11 @@ https://github.com/dotnet/runtime/issues/98628 - - NYI on Mono + + https://github.com/dotnet/runtime/issues/47624 + + + Test issue. The test relies on overriding the process return code. @@ -2731,16 +2680,6 @@ https://github.com/dotnet/runtime/issues/54867 - - https://github.com/dotnet/runtime/issues/54122 - - - https://github.com/dotnet/runtime/issues/54122 - - - https://github.com/dotnet/runtime/issues/54122 - - Function mismatch diff --git a/src/tests/nativeaot/SmokeTests/AttributeTrimming/AttributeTrimming.cs b/src/tests/nativeaot/SmokeTests/AttributeTrimming/AttributeTrimming.cs new file mode 100644 index 00000000000000..863b2708f1b6bc --- /dev/null +++ b/src/tests/nativeaot/SmokeTests/AttributeTrimming/AttributeTrimming.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. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; + +[Type] +class Program +{ + [Method] + static int Main() + { + // Sanity check: we don't currently expect attributes on types to be optimized away + if (GetTypeSecretly(nameof(TypeAttribute)) == null) + throw new Exception("Type"); + + // Main should be reflection visible + if (MethodBase.GetCurrentMethod().Name != nameof(Main)) + throw new Exception("Name"); + +#if !DEBUG + // But we should have optimized out the attributes on it + if (GetTypeSecretly(nameof(MethodAttribute)) != null) + throw new Exception("Method"); +#endif + + return 100; + } + + [UnconditionalSuppressMessage("Trimming", "IL2057", Justification = "That's the point")] + static Type GetTypeSecretly(string name) => Type.GetType(name); +} + +class MethodAttribute : Attribute; +class TypeAttribute : Attribute; diff --git a/src/tests/nativeaot/SmokeTests/AttributeTrimming/AttributeTrimming.csproj b/src/tests/nativeaot/SmokeTests/AttributeTrimming/AttributeTrimming.csproj new file mode 100644 index 00000000000000..e4650db0af37db --- /dev/null +++ b/src/tests/nativeaot/SmokeTests/AttributeTrimming/AttributeTrimming.csproj @@ -0,0 +1,12 @@ + + + Exe + 0 + true + true + false + + + + + diff --git a/src/tests/nativeaot/SmokeTests/DynamicGenerics/DynamicGenerics.main.cs b/src/tests/nativeaot/SmokeTests/DynamicGenerics/DynamicGenerics.main.cs index c1b59061534fcb..257e6d07ad783c 100644 --- a/src/tests/nativeaot/SmokeTests/DynamicGenerics/DynamicGenerics.main.cs +++ b/src/tests/nativeaot/SmokeTests/DynamicGenerics/DynamicGenerics.main.cs @@ -152,11 +152,11 @@ public static int Main(string[] args) #if UNIVERSAL_GENERICS new CoreFXTestLibrary.Internal.TestInfo("B279085.TestB279085Repro", () => global::B279085.TestB279085Repro(), null), #endif +new CoreFXTestLibrary.Internal.TestInfo("GitHub118072.RunTest", () => global::GitHub118072.RunTest(), null), new CoreFXTestLibrary.Internal.TestInfo("GenericVirtualMethods.TestCalls", () => global::GenericVirtualMethods.TestCalls(), null), new CoreFXTestLibrary.Internal.TestInfo("GenericVirtualMethods.TestLdFtnToGetStaticMethodOnGenericType", () => global::GenericVirtualMethods.TestLdFtnToGetStaticMethodOnGenericType(), null), new CoreFXTestLibrary.Internal.TestInfo("GenericVirtualMethods.TestLdFtnToInstanceGenericMethod", () => global::GenericVirtualMethods.TestLdFtnToInstanceGenericMethod(), null), -// https://github.com/dotnet/corert/issues/3460 -//new CoreFXTestLibrary.Internal.TestInfo("GenericVirtualMethods.TestGenericExceptionType", () => global::GenericVirtualMethods.TestGenericExceptionType(), null), +new CoreFXTestLibrary.Internal.TestInfo("GenericVirtualMethods.TestGenericExceptionType", () => global::GenericVirtualMethods.TestGenericExceptionType(), null), new CoreFXTestLibrary.Internal.TestInfo("GenericVirtualMethods.TestCoAndContraVariantCalls", () => global::GenericVirtualMethods.TestCoAndContraVariantCalls(), null) }; bool passed = CoreFXTestLibrary.Internal.Runner.RunTests(tests, args); diff --git a/src/tests/nativeaot/SmokeTests/DynamicGenerics/Github118072.cs b/src/tests/nativeaot/SmokeTests/DynamicGenerics/Github118072.cs new file mode 100644 index 00000000000000..e490ffbfd02024 --- /dev/null +++ b/src/tests/nativeaot/SmokeTests/DynamicGenerics/Github118072.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Reflection; +using System.Runtime.CompilerServices; + +using CoreFXTestLibrary; + +class GitHub118072 +{ + [MethodImpl(MethodImplOptions.NoInlining)] + static MethodInfo GetMI1() => typeof(GitHub118072).GetMethod(nameof(CallMethod1)); + [MethodImpl(MethodImplOptions.NoInlining)] + static MethodInfo GetMI2() => typeof(GitHub118072).GetMethod(nameof(CallMethod2)); + [MethodImpl(MethodImplOptions.NoInlining)] + static MethodInfo GetMI3() => typeof(GitHub118072).GetMethod(nameof(CallMethod1)); + [MethodImpl(MethodImplOptions.NoInlining)] + static MethodInfo GetMI4() => typeof(GitHub118072).GetMethod(nameof(CallMethod2)); + + [TestMethod] + public static void RunTest() + { + GetMI1().MakeGenericMethod(typeof(object)).Invoke(null, []); + FlushCache(); + GetMI2().MakeGenericMethod(typeof(object)).Invoke(null, []); + FlushCache(); + GetMI3().MakeGenericMethod(typeof(object)).Invoke(null, []); + FlushCache(); + GetMI4().MakeGenericMethod(typeof(object)).Invoke(null, []); + + static void FlushCache() + { + // Make sure the cached type loader contexts are flushed + for (int j = 0; j < 10; j++) + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + } + } + + public static string CallMethod1() => default(MyStruct).Method(); + + public static string CallMethod2() => default(MyStruct).Method(); + + struct MyStruct + { + public string Method() => typeof(T).Name; + } + + class MyClass { } +} diff --git a/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Program.cs b/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Program.cs index 3083d9f6c583cf..f13e6404e431ec 100644 --- a/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Program.cs +++ b/src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Program.cs @@ -21,8 +21,8 @@ static int Main() Console.WriteLine("****************************************************"); long lowerBound, upperBound; - lowerBound = 1200 * 1024; // ~1.2 MB - upperBound = 1600 * 1024; // ~1.6 MB + lowerBound = 1100 * 1024; // ~1.1 MB + upperBound = 1500 * 1024; // ~1.5 MB if (fileSize < lowerBound || fileSize > upperBound) { diff --git a/src/tests/nativeaot/SmokeTests/PInvoke/PInvoke.cs b/src/tests/nativeaot/SmokeTests/PInvoke/PInvoke.cs index d1edfff6c4eb23..253eee5f396ec6 100644 --- a/src/tests/nativeaot/SmokeTests/PInvoke/PInvoke.cs +++ b/src/tests/nativeaot/SmokeTests/PInvoke/PInvoke.cs @@ -12,13 +12,6 @@ using System.Runtime.InteropServices; using System.Text; -// Make sure the interop data are present even without reflection -namespace System.Runtime.CompilerServices -{ - [AttributeUsage(AttributeTargets.All)] - internal class __BlockAllReflectionAttribute : Attribute { } -} - // Name of namespace matches the name of the assembly on purpose to // ensure that we can handle this (mostly an issue for C++ code generation). namespace PInvokeTests diff --git a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs index a0ee00a5e7ac21..10a21b4d59e236 100644 --- a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs +++ b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs @@ -76,6 +76,8 @@ private static int Main() Test105034Regression.Run(); TestMethodsNeededFromNativeLayout.Run(); TestFieldAndParamMetadata.Run(); + TestActivationWithoutConstructor.Run(); + TestNestedMakeGeneric.Run(); // // Mostly functionality tests @@ -859,6 +861,60 @@ public static void Run() } } + class TestActivationWithoutConstructor + { + public static void Run() + { + { + object o = Activator.CreateInstance(typeof(StructForCreateInstanceDirect<>).MakeGenericType(GetTheType())); + if (!o.ToString().Contains(nameof(StructForCreateInstanceDirect<>))) + throw new Exception(); + } + + { + object o = CreateInstance(typeof(StructForCreateInstanceIndirect<>).MakeGenericType(GetTheType())); + if (!o.ToString().Contains(nameof(StructForCreateInstanceIndirect<>))) + throw new Exception(); + + static object CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type t) + => Activator.CreateInstance(t); + } + + { + object o = RuntimeHelpers.GetUninitializedObject(typeof(StructForGetUninitializedObject<>).MakeGenericType(GetTheType())); + if (!o.ToString().Contains(nameof(StructForGetUninitializedObject<>))) + throw new Exception(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Type GetTheType() => typeof(Atom); + } + + class Atom; + + struct StructForCreateInstanceDirect where T : class; + struct StructForCreateInstanceIndirect where T : class; + struct StructForGetUninitializedObject where T : class; + } + + class TestNestedMakeGeneric + { + class Outie where T : class; + class Innie where T : class; + class Atom; + + public static void Run() + { + Type inner = typeof(Innie<>).MakeGenericType(GetAtom()); + Type outer = typeof(Outie<>).MakeGenericType(inner); + + Console.WriteLine(Activator.CreateInstance(outer)); + + [MethodImpl(MethodImplOptions.NoInlining)] + static Type GetAtom() => typeof(Atom); + } + } + class TestCreateDelegate { internal class Greeter diff --git a/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/DeadCodeElimination.cs b/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/DeadCodeElimination.cs index 166fd3fb89fda6..7a58963a2788fd 100644 --- a/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/DeadCodeElimination.cs +++ b/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/DeadCodeElimination.cs @@ -7,6 +7,10 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +[assembly: TypeMap("Foo", typeof(DeadCodeElimination.TestInteropMapTrimming.ConditionalTypeMapEntry), typeof(DeadCodeElimination.TestInteropMapTrimming.TypeMapTrimTarget))] +[assembly: TypeMap("Bar", typeof(DeadCodeElimination.TestInteropMapTrimming.UnconditionalTypeMapEntry))] +[assembly: TypeMapAssociation(typeof(DeadCodeElimination.TestInteropMapTrimming.SourceType), typeof(DeadCodeElimination.TestInteropMapTrimming.ProxyType))] + class DeadCodeElimination { public static int Run() @@ -34,6 +38,9 @@ public static int Run() TestGetMethodOptimization.Run(); TestTypeOfCodegenBranchElimination.Run(); TestInvisibleGenericsTrimming.Run(); + TestTypeHandlesInGenericDictionaries.Run(); + TestMetadataMethodTables.Run(); + TestInteropMapTrimming.Run(); return 100; } @@ -1130,6 +1137,194 @@ public static void Run() } } + class TestTypeHandlesInGenericDictionaries + { + class InvisibleType1; + class InvisibleType2; + class VisibleType1; + + [MethodImpl(MethodImplOptions.NoInlining)] + static void GenericMethod(object o, string expectedNameOfV) + { + if (o is T) + Console.WriteLine("Yes"); + + if (o.GetType() == typeof(U)) + Console.WriteLine("Yes"); + + if (typeof(V).Name != expectedNameOfV) + throw new Exception(); + } + + public static void Run() + { + GenericMethod(new object(), nameof(VisibleType1)); + + ThrowIfPresent(typeof(TestTypeHandlesInGenericDictionaries), nameof(InvisibleType1)); +#if !DEBUG + ThrowIfPresent(typeof(TestTypeHandlesInGenericDictionaries), nameof(InvisibleType2)); +#endif + } + } + + class TestMetadataMethodTables + { + class NotReferenced1; + + class UnallocatedClass + { + [MethodImpl(MethodImplOptions.NoInlining)] + private NotReferenced1 GetNotReferenced() => new NotReferenced1(); + public override string ToString() => GetNotReferenced().ToString(); + } + + struct ImplicitlyAllocatedStruct + { + public override string ToString() => nameof(ImplicitlyAllocatedStruct); + } + + class NotReferenced2; + + class UnallocatedClassInGenericDictionary + { + [MethodImpl(MethodImplOptions.NoInlining)] + private NotReferenced2 GetNotReferenced() => new NotReferenced2(); + public override string ToString() => GetNotReferenced().ToString(); + } + + struct ImplicitlyAllocatedStructInGenericDictionary + { + public override string ToString() => nameof(ImplicitlyAllocatedStructInGenericDictionary<>); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Type GetTheT() => typeof(T); + + public static void Run() + { +#if !DEBUG + // typeof of a class shouldn't be considered allocation + { + [MethodImpl(MethodImplOptions.NoInlining)] + static Type GetUnallocatedClass() => typeof(UnallocatedClass); + + bool didThrow = false; + try + { + RuntimeHelpers.GetUninitializedObject(GetUnallocatedClass()); + } + catch (NotSupportedException) + { + didThrow = true; + } + + if (!didThrow) + throw new Exception(); + + ThrowIfPresent(typeof(TestMetadataMethodTables), nameof(NotReferenced1)); + if (GetUnallocatedClass().Name != nameof(UnallocatedClass)) + throw new Exception(); + } + + // same if it's in a generic dictionary + { + bool didThrow = false; + try + { + RuntimeHelpers.GetUninitializedObject(GetTheT()); + } + catch (NotSupportedException) + { + didThrow = true; + } + + if (!didThrow) + throw new Exception(); + + ThrowIfPresent(typeof(TestMetadataMethodTables), nameof(NotReferenced2)); + if (GetTheT().Name != nameof(UnallocatedClassInGenericDictionary)) + throw new Exception(); + } + + // typeof of a valuetype unfortunately needs to be (e.g. due to RuntimeHelpers.Box) + { + [MethodImpl(MethodImplOptions.NoInlining)] + static Type GetImplicitlyAllocatedStruct() => typeof(ImplicitlyAllocatedStruct); + + object o = RuntimeHelpers.GetUninitializedObject(GetImplicitlyAllocatedStruct()); + if (o.ToString() != nameof(ImplicitlyAllocatedStruct)) + throw new Exception(); + + if (GetImplicitlyAllocatedStruct().Name != nameof(ImplicitlyAllocatedStruct)) + throw new Exception(); + } + + // same in a generic dictionary + { + object o = RuntimeHelpers.GetUninitializedObject(GetTheT>()); + if (o.ToString() != nameof(ImplicitlyAllocatedStructInGenericDictionary<>)) + throw new Exception(); + + if (GetTheT>().Name != nameof(ImplicitlyAllocatedStructInGenericDictionary<>) + "`1") + throw new Exception(); + } +#endif + } + } + + internal class TestInteropMapTrimming + { + internal class Universe; + + internal class ConditionalTypeMapEntry; + internal class UnconditionalTypeMapEntry; + internal class TypeMapTrimTarget; + + internal class SourceType; + internal class ProxyType; + + [MethodImpl(MethodImplOptions.NoInlining)] + static object GetUnknown() => null; + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Consume(object o) { } + + public static void Run() + { + var map = TypeMapping.GetOrCreateExternalTypeMapping(); + + { + if (GetUnknown() is TypeMapTrimTarget) + { + Console.WriteLine("Unexpected!"); + } + + var mappedType = map["Foo"]; + ThrowIfUsableMethodTable(mappedType); + if (mappedType.Name != nameof(ConditionalTypeMapEntry)) + throw new Exception(); + } + + { + var mappedType = map["Bar"]; + ThrowIfUsableMethodTable(mappedType); + if (mappedType.Name != nameof(UnconditionalTypeMapEntry)) + throw new Exception(); + } + + var proxyMap = TypeMapping.GetOrCreateProxyTypeMapping(); + + { + Consume(new SourceType()); + + var mappedType = proxyMap[typeof(SourceType)]; + ThrowIfUsableMethodTable(mappedType); + if (mappedType.Name != nameof(ProxyType)) + throw new Exception(); + } + } + } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern", Justification = "That's the point")] private static Type GetTypeSecretly(Type testType, string typeName) => testType.GetNestedType(typeName, BindingFlags.NonPublic | BindingFlags.Public); @@ -1142,14 +1337,19 @@ private static void ThrowIfPresent(Type testType, string typeName) } } - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2072:UnrecognizedReflectionPattern", - Justification = "That's the point")] private static void ThrowIfPresentWithUsableMethodTable(Type testType, string typeName) { Type t = GetTypeSecretly(testType, typeName); if (t == null) return; + ThrowIfUsableMethodTable(t); + } + + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2067:UnrecognizedReflectionPattern", + Justification = "That's the point")] + private static void ThrowIfUsableMethodTable(Type t) + { try { RuntimeHelpers.GetUninitializedObject(t); diff --git a/src/tests/nativeaot/SmokeTests/UnitTests/Devirtualization.cs b/src/tests/nativeaot/SmokeTests/UnitTests/Devirtualization.cs index f376cbbca16b1c..b855012fdef18c 100644 --- a/src/tests/nativeaot/SmokeTests/UnitTests/Devirtualization.cs +++ b/src/tests/nativeaot/SmokeTests/UnitTests/Devirtualization.cs @@ -13,6 +13,7 @@ internal static int Run() { TestDevirtualizationIntoAbstract.Run(); RegressionBug73076.Run(); + RegressionBug117249.Run(); RegressionGenericHierarchy.Run(); DevirtualizationCornerCaseTests.Run(); DevirtualizeIntoUnallocatedGenericType.Run(); @@ -88,6 +89,77 @@ public static void Run() } } + class RegressionBug117249 + { + enum IntEnum1; + + enum IntEnum2; + + enum IntEnum3; + + static bool s_executed; + + [MethodImpl(MethodImplOptions.NoInlining)] + static object GetIntInstance() => new int[] { 1, 2, 3, 4 }; + + [MethodImpl(MethodImplOptions.NoInlining)] + static void SetStatic() => s_executed = true; + + [MethodImpl(MethodImplOptions.NoInlining)] + static IEnumerable GetIntEnums3() + { + yield return (IntEnum3)100; + Environment.GetEnvironmentVariable("ABC"); + yield return (IntEnum3)200; + Environment.GetEnvironmentVariable("ABC"); + yield return (IntEnum3)300; + Environment.GetEnvironmentVariable("ABC"); + yield return (IntEnum3)400; + } + + public static void Run() + { + Console.WriteLine("One"); + + { + int sum = 0; + foreach (var v in (IEnumerable)GetIntInstance()) + sum += (int)v; + + if (sum != 10) + throw new Exception(); + } + + Console.WriteLine("Two"); + + { + if (GetIntInstance() is IntEnum2[]) + SetStatic(); + + if (!s_executed) + throw new Exception(); + } + + Console.WriteLine("Three"); + + { + int sum = 0; + foreach (var v in (IEnumerable)GetIntInstance()) + sum += (int)v; + + if (sum != 10) + throw new Exception(); + + sum = 0; + foreach (var v in GetIntEnums3()) + sum += (int)v; + + if (sum != 1000) + throw new Exception(); + } + } + } + class RegressionGenericHierarchy { class Base diff --git a/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs b/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs index 5521646cd1fb7f..5850a7343e1201 100644 --- a/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs +++ b/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs @@ -60,6 +60,7 @@ internal static int Run() Test104913Regression.Run(); Test105397Regression.Run(); Test105880Regression.Run(); + TestInterfaceGenericCornerCase.Run(); Test115442Regression.Run(); TestInvokeMemberCornerCaseInGenerics.Run(); TestRefAny.Run(); @@ -3686,6 +3687,85 @@ public static void Run() } } + class TestInterfaceGenericCornerCase + { + interface IFoo + { + string Print(T x); + + string PrintGeneric(T x); + } + + class Conversion where T : IFoo, new() where U : class + { + public string Print() + { + string result = new T().Print(default); + + Func f = new T().Print; + if (f(default) != result) + throw new Exception(); + + return result; + } + + public string PrintGeneric() + { + string result = new T().PrintGeneric(default); + + Func f = new T().PrintGeneric; + if (f(default) != result) + throw new Exception(); + + return result; + } + } + + struct MyStruct : IFoo, IFoo + { + public string Print(Derived x) => "Derived"; + public string Print(object x) => "Object"; + + public string PrintGeneric(Derived x) => $"<{(typeof(U) == typeof(object) ? "O" : "X")}>Derived"; + public string PrintGeneric(object x) => $"<{(typeof(U) == typeof(object) ? "O" : "X")}>Object"; + } + + class Base; + class Derived : Base; + + public static void Run() + { + var conversion = new Conversion(); + if (conversion.Print() != "Object") + throw new Exception(); + if (conversion.PrintGeneric() != "Object") + throw new Exception(); + + if (PrintDynamic(typeof(Derived)) != "Derived") + throw new Exception(); + if (PrintGenericDynamic(typeof(Derived)) != "Derived") + throw new Exception(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static string PrintDynamic(Type p) + { + var t = typeof(Conversion<,>).MakeGenericType(typeof(MyStruct), p); + var g = Activator.CreateInstance(t); + var mi = (MethodInfo)t.GetMemberWithSameMetadataDefinitionAs(typeof(Conversion<,>).GetMethod(nameof(Conversion.Print))); + return (string)mi.Invoke(g, []); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static string PrintGenericDynamic(Type p) + { + var t = typeof(Conversion<,>).MakeGenericType(typeof(MyStruct), p); + var g = Activator.CreateInstance(t); + var mi = ((MethodInfo)t.GetMemberWithSameMetadataDefinitionAs(typeof(Conversion<,>).GetMethod(nameof(Conversion.PrintGeneric)))).MakeGenericMethod(typeof(object)); + return (string)mi.Invoke(g, []); + } + } + class Test115442Regression { public readonly struct TypeBuilder diff --git a/src/tests/nativeaot/SmokeTests/UnitTests/Main.cs b/src/tests/nativeaot/SmokeTests/UnitTests/Main.cs index 6befca8e6eb968..32b52c089cacff 100644 --- a/src/tests/nativeaot/SmokeTests/UnitTests/Main.cs +++ b/src/tests/nativeaot/SmokeTests/UnitTests/Main.cs @@ -11,6 +11,7 @@ success &= RunTest(Threading.Run); success &= RunTest(Devirtualization.Run); success &= RunTest(StackTraces.Run); +success &= RunTest(Ordering.Run); return success ? 100 : 1; diff --git a/src/tests/nativeaot/SmokeTests/UnitTests/Ordering.cs b/src/tests/nativeaot/SmokeTests/UnitTests/Ordering.cs new file mode 100644 index 00000000000000..147ab917b9d779 --- /dev/null +++ b/src/tests/nativeaot/SmokeTests/UnitTests/Ordering.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +class Ordering +{ + internal static unsafe int Run() + { + // Method addresses are not observable in WASM + if (OperatingSystem.IsWasi() || OperatingSystem.IsBrowser()) + return 100; + + var keys = new nint[] + { + (nint)(delegate*)&Method4, + (nint)(delegate*)&Method3, + (nint)(delegate*)&Method2, + (nint)(delegate*)&Method1, + (nint)(delegate*)&Method0, + }; + + var items = new int[] { 4, 3, 2, 1, 0 }; + + Array.Sort(keys, items); + + // the order specified in the order.txt file + var expectedOrder = new int[] { 2, 1, 3, 0, 4 }; + + for (int i = 0; i < items.Length; i++) + if (items[i] != expectedOrder[i]) + throw new Exception(i.ToString()); + + return 100; + } + + static Guid Method0() => new Guid(0xb20e3a5f, 0x4aad, 0x4225, 0x98, 0x26, 0xac, 0xe8, 0xe0, 0xf7, 0x64, 0x56); + static Guid Method1() => new Guid(0x13464316, 0xb19c, 0x4e1c, 0x95, 0x2e, 0x22, 0xb4, 0xa, 0x21, 0x7d, 0xd5); + static Guid Method2() => new Guid(0x510f2c1e, 0x7715, 0x4aee, 0x8d, 0xd5, 0x16, 0xf8, 0xd5, 0x70, 0x5, 0x90); + static Guid Method3() => new Guid(0x4cc6e597, 0x875e, 0x4cb0, 0x90, 0x88, 0xcb, 0x4e, 0xd8, 0x8, 0x91, 0xb8); + static Guid Method4() => new Guid(0x2d2e2b87, 0x75f5, 0x4c16, 0x93, 0xa9, 0xbe, 0xbd, 0x6b, 0x58, 0xbd, 0xd6); +} diff --git a/src/tests/nativeaot/SmokeTests/UnitTests/UnitTests.csproj b/src/tests/nativeaot/SmokeTests/UnitTests/UnitTests.csproj index c47e329890b2fd..a9d21f93d4eacc 100644 --- a/src/tests/nativeaot/SmokeTests/UnitTests/UnitTests.csproj +++ b/src/tests/nativeaot/SmokeTests/UnitTests/UnitTests.csproj @@ -10,6 +10,8 @@ true false + + order.txt @@ -17,6 +19,7 @@ + diff --git a/src/tests/nativeaot/SmokeTests/UnitTests/order.txt b/src/tests/nativeaot/SmokeTests/UnitTests/order.txt new file mode 100644 index 00000000000000..34df1741aebc15 --- /dev/null +++ b/src/tests/nativeaot/SmokeTests/UnitTests/order.txt @@ -0,0 +1,5 @@ +UnitTests_Ordering__Method2 +UnitTests_Ordering__Method1 +UnitTests_Ordering__Method3 +UnitTests_Ordering__Method0 +UnitTests_Ordering__Method4 diff --git a/src/tests/profiler/assembly/ALCTest.csproj b/src/tests/profiler/assembly/ALCTest.csproj index 44da138cc58fb2..f20fc4207d6ea1 100644 --- a/src/tests/profiler/assembly/ALCTest.csproj +++ b/src/tests/profiler/assembly/ALCTest.csproj @@ -9,8 +9,6 @@ runincontext loads even framework assemblies into the unloadable context, locals in this loop prevent unloading --> true - - true diff --git a/src/tests/profiler/dynamicoptimization/DynamicOptimization.csproj b/src/tests/profiler/dynamicoptimization/DynamicOptimization.csproj index 9841ec2522716b..71fb82bbd5279c 100644 --- a/src/tests/profiler/dynamicoptimization/DynamicOptimization.csproj +++ b/src/tests/profiler/dynamicoptimization/DynamicOptimization.csproj @@ -9,8 +9,6 @@ runincontext loads even framework assemblies into the unloadable context, locals in this loop prevent unloading --> true - - true true diff --git a/src/tests/profiler/native/rejitprofiler/rejitprofiler.cpp b/src/tests/profiler/native/rejitprofiler/rejitprofiler.cpp index b93d3bc6926c9b..604d8cee30ceb4 100644 --- a/src/tests/profiler/native/rejitprofiler/rejitprofiler.cpp +++ b/src/tests/profiler/native/rejitprofiler/rejitprofiler.cpp @@ -95,13 +95,19 @@ HRESULT ReJITProfiler::Shutdown() _profInfo10 = nullptr; } - int expectedRejitCount = -1; + int expectedRejitCount; auto it = _inlinings.find(_targetFuncId); if (it != _inlinings.end()) { // The number of inliners are expected to ReJIT, plus the method itself expectedRejitCount = (int)((*it).second->size() + 1); } + else + { + // No inlinings happened, which can occur in composite R2R mode on some targets. + // This is fine as long as we rejitted the target method itself. + expectedRejitCount = 1; + } INFO(L" rejit count=" << _rejits << L" expected rejit count=" << expectedRejitCount); @@ -320,7 +326,8 @@ HRESULT STDMETHODCALLTYPE ReJITProfiler::GetReJITParameters(ModuleID moduleId, m { SHUTDOWNGUARD(); - INFO(L"Starting to build IL for method " << GetFunctionIDName(GetFunctionIDFromToken(moduleId, methodId, false))); + String functionName = GetFunctionIDName(GetFunctionIDFromToken(moduleId, methodId, false)); + INFO(L"Starting to build IL for method " << functionName); COMPtrHolder pUnk; HRESULT hr = _profInfo10->GetModuleMetaData(moduleId, ofWrite, IID_IMetaDataEmit2, &pUnk); if (FAILED(hr)) @@ -340,10 +347,18 @@ HRESULT STDMETHODCALLTYPE ReJITProfiler::GetReJITParameters(ModuleID moduleId, m } - const WCHAR *wszNewUserDefinedString = WCHAR("Hello from profiler rejit!"); + String newUserDefinedString = String(WCHAR("Hello from profiler rejit method '")); + newUserDefinedString += functionName; + newUserDefinedString += WCHAR("'! "); mdString tokmdsUserDefined = mdTokenNil; - hr = pTargetEmit->DefineUserString(wszNewUserDefinedString, - (ULONG)wcslen(wszNewUserDefinedString), + + // There's no portable way to convert a String to LPCWSTR so just make a manual copy on the stack. + char16_t buf[4096] = { 0 }; + for (size_t i = 0, c = newUserDefinedString.Length(); i < c; i++) + buf[i] = (char16_t)newUserDefinedString[i]; + + hr = pTargetEmit->DefineUserString((LPCWSTR)(void *)buf, + (ULONG)newUserDefinedString.Length(), &tokmdsUserDefined); if (FAILED(hr)) { @@ -427,28 +442,39 @@ HRESULT STDMETHODCALLTYPE ReJITProfiler::ReJITError(ModuleID moduleId, mdMethodD void ReJITProfiler::AddInlining(FunctionID inliner, FunctionID inlinee) { - shared_ptr> inliners; - auto result = _inlinings.find(inlinee); - if (result == _inlinings.end()) + String calleeName = GetFunctionIDName(inlinee); + String moduleName = GetModuleIDName(GetModuleIDForFunction(inlinee)); + + // Depending on various things it's possible the JIT will inline code during our test run that isn't part of the + // rejit test module. For example if part of the BCL didn't get crossgen'd or the crossgen'd code isn't used. + // We don't care about those inlinings, so we won't track them. This makes the test more reliable. + if (EndsWith(moduleName, String(WCHAR("rejit.dll")))) { - auto p = make_pair(inlinee, make_shared>()); - inliners = p.second; - _inlinings.insert(p); + shared_ptr> inliners; + auto result = _inlinings.find(inlinee); + if (result == _inlinings.end()) + { + auto p = make_pair(inlinee, make_shared>()); + inliners = p.second; + _inlinings.insert(p); + } + else + { + inliners = (*result).second; + } + + auto it = inliners->find(inliner); + if (it == inliners->end()) + { + inliners->insert(inliner); + } + + INFO(L"Inlining in test module! Inliner=" << GetFunctionIDName(inliner) << L" Inlinee=" << calleeName << L" module=" << moduleName); } else { - inliners = (*result).second; + INFO(L"Inlining in non-test module! Inliner=" << GetFunctionIDName(inliner) << L" Inlinee=" << calleeName << L" module=" << moduleName); } - - auto it = inliners->find(inliner); - if (it == inliners->end()) - { - inliners->insert(inliner); - } - - String calleeName = GetFunctionIDName(inlinee); - String moduleName = GetModuleIDName(GetModuleIDForFunction(inlinee)); - INFO(L"Inlining occurred! Inliner=" << GetFunctionIDName(inliner) << L" Inlinee=" << calleeName << L" Inlinee module name=" << moduleName); } FunctionID ReJITProfiler::GetFunctionIDFromToken(ModuleID module, mdMethodDef token, bool invalidArgNotFailure) diff --git a/src/tests/profiler/native/transitions/transitions.cpp b/src/tests/profiler/native/transitions/transitions.cpp index 3966c887440e9a..7abc549d8c53a2 100644 --- a/src/tests/profiler/native/transitions/transitions.cpp +++ b/src/tests/profiler/native/transitions/transitions.cpp @@ -60,7 +60,7 @@ HRESULT Transitions::Shutdown() printf("Test failed _failures=%d _pinvoke=%s _reversePinvoke=%s\n", _failures.load(), boolFmt(successPinvoke), boolFmt(successReversePinvoke)); } - + fflush(stdout); return S_OK; } diff --git a/src/tests/profiler/rejit/rejit.cs b/src/tests/profiler/rejit/rejit.cs index b9ea65ffccde8e..fc69720d270786 100644 --- a/src/tests/profiler/rejit/rejit.cs +++ b/src/tests/profiler/rejit/rejit.cs @@ -10,6 +10,15 @@ class RejitWithInlining //: ProfilerTest { static readonly Guid ReJitProfilerGuid = new Guid("66F7A9DF-8858-4A32-9CFF-3AD0787E0186"); + static System.Text.StringBuilder OutputBuilder = new (); + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static void TestWriteLine(string s) + { + OutputBuilder.AppendLine(s); + Console.WriteLine(s); + } + [MethodImplAttribute(MethodImplOptions.NoInlining)] private static int MaxInlining() { @@ -20,18 +29,41 @@ private static int MaxInlining() TriggerReJIT(); + OutputBuilder.Clear(); + // TriggerInliningChain triggers a ReJIT, now this time we should call // in to the ReJITted code TriggerDirectInlining(); CallMethodWithoutInlining(); TriggerInliningChain(); + string matchString = "Hello from profiler rejit method 'InlineeTarget'!"; + int numRejittedTargets = OutputBuilder.ToString().Split(matchString).Length; + if (numRejittedTargets != 4) + { + Console.WriteLine("ReJIT did not update all instances of InlineeTarget!"); + return 1234; + } + TriggerRevert(); + OutputBuilder.Clear(); + TriggerDirectInlining(); CallMethodWithoutInlining(); TriggerInliningChain(); + if (OutputBuilder.ToString().Contains(matchString)) + { + Console.WriteLine("ReJIT revert of InlineeTarget was not complete!"); + return 1235; + } + + // Currently there will still be some 'Hello from profiler rejit method' messages left + // in the output in certain configurations. This is because the test profiler does not revert all + // the methods that it modified - reverts are not symmetric with rejits. + // See https://github.com/dotnet/runtime/issues/117823 + return 100; } @@ -50,7 +82,7 @@ private static void TriggerRevert() [MethodImplAttribute(MethodImplOptions.NoInlining)] private static void TriggerInliningChain() { - Console.WriteLine("TriggerInlining"); + TestWriteLine("TriggerInliningChain"); // Test Inlining through another method InlineeChain1(); } @@ -58,34 +90,40 @@ private static void TriggerInliningChain() [MethodImplAttribute(MethodImplOptions.NoInlining)] private static void TriggerDirectInlining() { - Console.WriteLine("TriggerDirectInlining"); + TestWriteLine("TriggerDirectInlining"); InlineeTarget(); } [MethodImplAttribute(MethodImplOptions.NoInlining)] private static void CallMethodWithoutInlining() { - Console.WriteLine("CallMethodWithoutInlining"); - Action callMethod = InlineeTarget; - callMethod(); + TestWriteLine("CallMethodWithoutInlining"); + Action callMethod = InlineeTarget; + callMethod("CallMethodWithoutInlining"); } [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] private static void InlineeChain1() { - Console.WriteLine("Inline.InlineeChain1"); + TestWriteLine(" Inline.InlineeChain1"); InlineeTarget(); } [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] - public static void InlineeTarget() + public static void InlineeTarget([CallerMemberName] string callerMemberName = null) { - Console.WriteLine("Inline.InlineeTarget"); + var sb = new System.Text.StringBuilder(); + sb.Append(" Inline.InlineeTarget"); + sb.Append(' '); + sb.Append('('); + sb.Append(callerMemberName); + sb.Append(')'); + TestWriteLine(sb.ToString()); } public static int RunTest(string[] args) { - Console.WriteLine("maxinlining"); + TestWriteLine("maxinlining"); return MaxInlining(); } @@ -108,7 +146,7 @@ public class SeparateClassNeverLoaded [MethodImplAttribute(MethodImplOptions.NoInlining)] private static void TriggerInliningChain() { - Console.WriteLine("TriggerInlining"); + RejitWithInlining.TestWriteLine("TriggerInlining"); // Test Inlining through another method InlineeChain1(); } @@ -116,14 +154,14 @@ private static void TriggerInliningChain() [MethodImplAttribute(MethodImplOptions.NoInlining)] private static void TriggerDirectInlining() { - Console.WriteLine("TriggerDirectInlining"); + RejitWithInlining.TestWriteLine("TriggerDirectInlining"); RejitWithInlining.InlineeTarget(); } [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] private static void InlineeChain1() { - Console.WriteLine("Inline.InlineeChain1"); + RejitWithInlining.TestWriteLine("Inline.InlineeChain1"); RejitWithInlining.InlineeTarget(); } } diff --git a/src/tools/StressLogAnalyzer/src/InterestingStringFinder.cs b/src/tools/StressLogAnalyzer/src/InterestingStringFinder.cs index 4fbb8047358878..515d530d492000 100644 --- a/src/tools/StressLogAnalyzer/src/InterestingStringFinder.cs +++ b/src/tools/StressLogAnalyzer/src/InterestingStringFinder.cs @@ -25,7 +25,7 @@ internal sealed class InterestingStringFinder(Target target, StressLogHeader.Mod {"GC_HEAP RELOCATING Objects in heap within range [%p %p) by -0x%x bytes\n", WellKnownString.PLUG_MOVE }, {"%d gc thread waiting...", WellKnownString.THREAD_WAIT }, {"%d gc thread waiting... Done", WellKnownString.THREAD_WAIT_DONE }, - {"*GC* %d(gen0:%d)(%d)(alloc: %zd)(%s)(%d)(%d)", WellKnownString.GCSTART }, + {"*GC* %d(gen0:%d)(%d) (alloced for %.3fms, g0 %zd (b: %zd, %zd/h) (%.3fmb/ms), g3 %zd (%.3fmb/ms), g4 %zd (%.3fmb/ms))(%s)(%d)(%d)", WellKnownString.GCSTART }, {"*EGC* %zd(gen0:%zd)(%zd)(%d)(%s)(%s)(%s)(ml: %d->%d)\n", WellKnownString.GCEND }, {"---- Mark Phase on heap %d condemning %d ----", WellKnownString.MARK_START }, {"---- Plan Phase on heap %d ---- Condemned generation %d, promotion: %d", WellKnownString.PLAN_START }, diff --git a/src/tools/StressLogAnalyzer/src/Program.cs b/src/tools/StressLogAnalyzer/src/Program.cs index 88690222f9cbe1..4012f137e97673 100644 --- a/src/tools/StressLogAnalyzer/src/Program.cs +++ b/src/tools/StressLogAnalyzer/src/Program.cs @@ -56,8 +56,8 @@ private static unsafe int ReadFromMemoryMappedLog(ulong address, Span buff public static async Task Main(string[] args) { - CommandLineConfiguration configuration = new(CreateRootCommand()); - ParseResult parsedArguments = configuration.Parse(args); + RootCommand rootCommand = CreateRootCommand(); + ParseResult parsedArguments = rootCommand.Parse(args); while (true) { @@ -79,11 +79,12 @@ public static async Task Main(string[] args) { // Parse the remaining string as new arguments for the analyzer. FileInfo inputFileArgument = parsedArguments.GetValue(InputFileArgument)!; - parsedArguments = configuration.Parse($"\"{inputFileArgument.FullName}\" {command[1..]}"); + parsedArguments = rootCommand.Parse($"\"{inputFileArgument.FullName}\" {command[1..]}"); break; } } - }; + } + ; } private static readonly Argument InputFileArgument = new Argument("log file") @@ -492,6 +493,7 @@ ContractDescriptorTarget CreateTarget() => ContractDescriptorTarget.Create( GetDescriptor(contractVersion), [TargetPointer.Null, new TargetPointer(header->memoryBase + (nuint)((byte*)&header->moduleTable - (byte*)header))], (address, buffer) => ReadFromMemoryMappedLog(address, buffer, header), + (address, buffer) => throw new NotImplementedException("StressLogAnalyzer does not provide WriteToTarget implementation"), (threadId, contextFlags, bufferToFill) => throw new NotImplementedException("StressLogAnalyzer does not provide GetTargetThreadContext implementation"), true, nuint.Size); @@ -518,7 +520,7 @@ private static ContractDescriptorParser.ContractDescriptor GetDescriptor(int str { Baseline = BaseContractDescriptor.Baseline, Version = BaseContractDescriptor.Version, - Contracts = new(){ { "StressLog", stressLogVersion } }, + Contracts = new() { { "StressLog", stressLogVersion } }, Types = BaseContractDescriptor.Types, Globals = BaseContractDescriptor.Globals, }; @@ -540,7 +542,8 @@ private static ContractDescriptorParser.ContractDescriptor GetDescriptor(int str "Logs": 24, "TickFrequency": 48, "StartTimestamp": 56, - "ModuleOffset": 72 + "ModuleOffset": 72, + "Modules": 80 }, "StressLogModuleDesc": { "!": 16, diff --git a/src/tools/illink/.editorconfig b/src/tools/illink/.editorconfig index e7988b173c83c3..da62d145532377 100644 --- a/src/tools/illink/.editorconfig +++ b/src/tools/illink/.editorconfig @@ -6,9 +6,6 @@ file_header_template = Copyright (c) .NET Foundation and contributors. All right ### Code Style Analyzers -# Spacing around keywords -dotnet_diagnostic.SA1000.severity = none - # Access modifier must be declared dotnet_diagnostic.SA1400.severity = none diff --git a/src/tools/illink/external/Mono.Options/Options.cs b/src/tools/illink/external/Mono.Options/Options.cs index b89840c83b6c25..cf1e5b1f54d047 100644 --- a/src/tools/illink/external/Mono.Options/Options.cs +++ b/src/tools/illink/external/Mono.Options/Options.cs @@ -192,1623 +192,1745 @@ namespace NDesk.Options namespace Mono.Options #endif { - static class StringCoda { - - public static IEnumerable WrappedLines (string self, params int[] widths) - { - IEnumerable w = widths; - return WrappedLines (self, w); - } - - public static IEnumerable WrappedLines (string self, IEnumerable widths) - { - if (widths == null) - throw new ArgumentNullException ("widths"); - return CreateWrappedLinesIterator (self, widths); - } - - private static IEnumerable CreateWrappedLinesIterator (string self, IEnumerable widths) - { - if (string.IsNullOrEmpty (self)) { - yield return string.Empty; - yield break; - } - using (IEnumerator ewidths = widths.GetEnumerator ()) { - bool? hw = null; - int width = GetNextWidth (ewidths, int.MaxValue, ref hw); - int start = 0, end; - do { - end = GetLineEnd (start, width, self); - char c = self [end-1]; - if (char.IsWhiteSpace (c)) - --end; - bool needContinuation = end != self.Length && !IsEolChar (c); - string continuation = ""; - if (needContinuation) { - --end; - continuation = "-"; - } - string line = self.Substring (start, end - start) + continuation; - yield return line; - start = end; - if (char.IsWhiteSpace (c)) - ++start; - width = GetNextWidth (ewidths, width, ref hw); - } while (start < self.Length); - } - } - - private static int GetNextWidth (IEnumerator ewidths, int curWidth, ref bool? eValid) - { - if (!eValid.HasValue || (eValid.HasValue && eValid.Value)) { - curWidth = (eValid = ewidths.MoveNext ()).Value ? ewidths.Current : curWidth; - // '.' is any character, - is for a continuation - const string minWidth = ".-"; - if (curWidth < minWidth.Length) - throw new ArgumentOutOfRangeException ("widths", - string.Format ("Element must be >= {0}, was {1}.", minWidth.Length, curWidth)); - return curWidth; - } - // no more elements, use the last element. - return curWidth; - } - - private static bool IsEolChar (char c) - { - return !char.IsLetterOrDigit (c); - } - - private static int GetLineEnd (int start, int length, string description) - { - int end = System.Math.Min (start + length, description.Length); - int sep = -1; - for (int i = start; i < end; ++i) { - if (description [i] == '\n') - return i+1; - if (IsEolChar (description [i])) - sep = i+1; - } - if (sep == -1 || end == description.Length) - return end; - return sep; - } - } - - public class OptionValueCollection : IList, IList { - - List values = new List (); - OptionContext c; - - internal OptionValueCollection (OptionContext c) - { - this.c = c; - } - - #region ICollection - void ICollection.CopyTo (Array array, int index) {(values as ICollection).CopyTo (array, index);} - bool ICollection.IsSynchronized {get {return (values as ICollection).IsSynchronized;}} - object ICollection.SyncRoot {get {return (values as ICollection).SyncRoot;}} - #endregion - - #region ICollection - public void Add (string item) {values.Add (item);} - public void Clear () {values.Clear ();} - public bool Contains (string item) {return values.Contains (item);} - public void CopyTo (string[] array, int arrayIndex) {values.CopyTo (array, arrayIndex);} - public bool Remove (string item) {return values.Remove (item);} - public int Count {get {return values.Count;}} - public bool IsReadOnly {get {return false;}} - #endregion - - #region IEnumerable - IEnumerator IEnumerable.GetEnumerator () {return values.GetEnumerator ();} - #endregion - - #region IEnumerable - public IEnumerator GetEnumerator () {return values.GetEnumerator ();} - #endregion - - #region IList - int IList.Add (object value) {return (values as IList).Add (value);} - bool IList.Contains (object value) {return (values as IList).Contains (value);} - int IList.IndexOf (object value) {return (values as IList).IndexOf (value);} - void IList.Insert (int index, object value) {(values as IList).Insert (index, value);} - void IList.Remove (object value) {(values as IList).Remove (value);} - void IList.RemoveAt (int index) {(values as IList).RemoveAt (index);} - bool IList.IsFixedSize {get {return false;}} - object IList.this [int index] {get {return this [index];} set {(values as IList)[index] = value;}} - #endregion - - #region IList - public int IndexOf (string item) {return values.IndexOf (item);} - public void Insert (int index, string item) {values.Insert (index, item);} - public void RemoveAt (int index) {values.RemoveAt (index);} - - private void AssertValid (int index) - { - if (c.Option == null) - throw new InvalidOperationException ("OptionContext.Option is null."); - if (index >= c.Option.MaxValueCount) - throw new ArgumentOutOfRangeException ("index"); - if (c.Option.OptionValueType == OptionValueType.Required && - index >= values.Count) - throw new OptionException (string.Format ( - c.OptionSet.MessageLocalizer ("Missing required value for option '{0}'."), c.OptionName), - c.OptionName); - } - - public string this [int index] { - get { - AssertValid (index); - return index >= values.Count ? null : values [index]; - } - set { - values [index] = value; - } - } - #endregion - - public List ToList () - { - return new List (values); - } - - public string[] ToArray () - { - return values.ToArray (); - } - - public override string ToString () - { - return string.Join (", ", values.ToArray ()); - } - } - - public class OptionContext { - private Option option; - private string name; - private int index; - private OptionSet set; - private OptionValueCollection c; - - public OptionContext (OptionSet set) - { - this.set = set; - this.c = new OptionValueCollection (this); - } - - public Option Option { - get {return option;} - set {option = value;} - } - - public string OptionName { - get {return name;} - set {name = value;} - } - - public int OptionIndex { - get {return index;} - set {index = value;} - } - - public OptionSet OptionSet { - get {return set;} - } - - public OptionValueCollection OptionValues { - get {return c;} - } - } - - public enum OptionValueType { - None, - Optional, - Required, - } - - public abstract class Option { - string prototype, description; - string[] names; - OptionValueType type; - int count; - string[] separators; - bool hidden; - - protected Option (string prototype, string description) - : this (prototype, description, 1, false) - { - } - - protected Option (string prototype, string description, int maxValueCount) - : this (prototype, description, maxValueCount, false) - { - } - - protected Option (string prototype, string description, int maxValueCount, bool hidden) - { - if (prototype == null) - throw new ArgumentNullException ("prototype"); - if (prototype.Length == 0) - throw new ArgumentException ("Cannot be the empty string.", "prototype"); - if (maxValueCount < 0) - throw new ArgumentOutOfRangeException ("maxValueCount"); - - this.prototype = prototype; - this.description = description; - this.count = maxValueCount; - this.names = (this is OptionSet.Category) - // append GetHashCode() so that "duplicate" categories have distinct - // names, e.g. adding multiple "" categories should be valid. - ? [prototype + this.GetHashCode ()] - : prototype.Split ('|'); - - if (this is OptionSet.Category || this is CommandOption) - return; - - this.type = ParsePrototype (); - this.hidden = hidden; - - if (this.count == 0 && type != OptionValueType.None) - throw new ArgumentException ( - "Cannot provide maxValueCount of 0 for OptionValueType.Required or " + - "OptionValueType.Optional.", - "maxValueCount"); - if (this.type == OptionValueType.None && maxValueCount > 1) - throw new ArgumentException ( - string.Format ("Cannot provide maxValueCount of {0} for OptionValueType.None.", maxValueCount), - "maxValueCount"); - if (Array.IndexOf (names, "<>") >= 0 && - ((names.Length == 1 && this.type != OptionValueType.None) || - (names.Length > 1 && this.MaxValueCount > 1))) - throw new ArgumentException ( - "The default option handler '<>' cannot require values.", - "prototype"); - } - - public string Prototype {get {return prototype;}} - public string Description {get {return description;}} - public OptionValueType OptionValueType {get {return type;}} - public int MaxValueCount {get {return count;}} - public bool Hidden {get {return hidden;}} - - public string[] GetNames () - { - return (string[]) names.Clone (); - } - - public string[] GetValueSeparators () - { - if (separators == null) - return new string [0]; - return (string[]) separators.Clone (); - } - - protected static T Parse (string value, OptionContext c) - { - Type tt = typeof (T); + static class StringCoda + { + + public static IEnumerable WrappedLines(string self, params int[] widths) + { + IEnumerable w = widths; + return WrappedLines(self, w); + } + + public static IEnumerable WrappedLines(string self, IEnumerable widths) + { + if (widths == null) + throw new ArgumentNullException("widths"); + return CreateWrappedLinesIterator(self, widths); + } + + private static IEnumerable CreateWrappedLinesIterator(string self, IEnumerable widths) + { + if (string.IsNullOrEmpty(self)) + { + yield return string.Empty; + yield break; + } + using (IEnumerator ewidths = widths.GetEnumerator()) + { + bool? hw = null; + int width = GetNextWidth(ewidths, int.MaxValue, ref hw); + int start = 0, end; + do + { + end = GetLineEnd(start, width, self); + char c = self[end - 1]; + if (char.IsWhiteSpace(c)) + --end; + bool needContinuation = end != self.Length && !IsEolChar(c); + string continuation = ""; + if (needContinuation) + { + --end; + continuation = "-"; + } + string line = self.Substring(start, end - start) + continuation; + yield return line; + start = end; + if (char.IsWhiteSpace(c)) + ++start; + width = GetNextWidth(ewidths, width, ref hw); + } while (start < self.Length); + } + } + + private static int GetNextWidth(IEnumerator ewidths, int curWidth, ref bool? eValid) + { + if (!eValid.HasValue || (eValid.HasValue && eValid.Value)) + { + curWidth = (eValid = ewidths.MoveNext()).Value ? ewidths.Current : curWidth; + // '.' is any character, - is for a continuation + const string minWidth = ".-"; + if (curWidth < minWidth.Length) + throw new ArgumentOutOfRangeException("widths", + string.Format("Element must be >= {0}, was {1}.", minWidth.Length, curWidth)); + return curWidth; + } + // no more elements, use the last element. + return curWidth; + } + + private static bool IsEolChar(char c) + { + return !char.IsLetterOrDigit(c); + } + + private static int GetLineEnd(int start, int length, string description) + { + int end = System.Math.Min(start + length, description.Length); + int sep = -1; + for (int i = start; i < end; ++i) + { + if (description[i] == '\n') + return i + 1; + if (IsEolChar(description[i])) + sep = i + 1; + } + if (sep == -1 || end == description.Length) + return end; + return sep; + } + } + + public class OptionValueCollection : IList, IList + { + + List values = new List(); + OptionContext c; + + internal OptionValueCollection(OptionContext c) + { + this.c = c; + } + + #region ICollection + void ICollection.CopyTo(Array array, int index) { (values as ICollection).CopyTo(array, index); } + bool ICollection.IsSynchronized { get { return (values as ICollection).IsSynchronized; } } + object ICollection.SyncRoot { get { return (values as ICollection).SyncRoot; } } + #endregion + + #region ICollection + public void Add(string item) { values.Add(item); } + public void Clear() { values.Clear(); } + public bool Contains(string item) { return values.Contains(item); } + public void CopyTo(string[] array, int arrayIndex) { values.CopyTo(array, arrayIndex); } + public bool Remove(string item) { return values.Remove(item); } + public int Count { get { return values.Count; } } + public bool IsReadOnly { get { return false; } } + #endregion + + #region IEnumerable + IEnumerator IEnumerable.GetEnumerator() { return values.GetEnumerator(); } + #endregion + + #region IEnumerable + public IEnumerator GetEnumerator() { return values.GetEnumerator(); } + #endregion + + #region IList + int IList.Add(object value) { return (values as IList).Add(value); } + bool IList.Contains(object value) { return (values as IList).Contains(value); } + int IList.IndexOf(object value) { return (values as IList).IndexOf(value); } + void IList.Insert(int index, object value) { (values as IList).Insert(index, value); } + void IList.Remove(object value) { (values as IList).Remove(value); } + void IList.RemoveAt(int index) { (values as IList).RemoveAt(index); } + bool IList.IsFixedSize { get { return false; } } + object IList.this[int index] { get { return this[index]; } set { (values as IList)[index] = value; } } + #endregion + + #region IList + public int IndexOf(string item) { return values.IndexOf(item); } + public void Insert(int index, string item) { values.Insert(index, item); } + public void RemoveAt(int index) { values.RemoveAt(index); } + + private void AssertValid(int index) + { + if (c.Option == null) + throw new InvalidOperationException("OptionContext.Option is null."); + if (index >= c.Option.MaxValueCount) + throw new ArgumentOutOfRangeException("index"); + if (c.Option.OptionValueType == OptionValueType.Required && + index >= values.Count) + throw new OptionException(string.Format( + c.OptionSet.MessageLocalizer("Missing required value for option '{0}'."), c.OptionName), + c.OptionName); + } + + public string this[int index] + { + get + { + AssertValid(index); + return index >= values.Count ? null : values[index]; + } + set + { + values[index] = value; + } + } + #endregion + + public List ToList() + { + return new List(values); + } + + public string[] ToArray() + { + return values.ToArray(); + } + + public override string ToString() + { + return string.Join(", ", values.ToArray()); + } + } + + public class OptionContext + { + private Option option; + private string name; + private int index; + private OptionSet set; + private OptionValueCollection c; + + public OptionContext(OptionSet set) + { + this.set = set; + this.c = new OptionValueCollection(this); + } + + public Option Option + { + get { return option; } + set { option = value; } + } + + public string OptionName + { + get { return name; } + set { name = value; } + } + + public int OptionIndex + { + get { return index; } + set { index = value; } + } + + public OptionSet OptionSet + { + get { return set; } + } + + public OptionValueCollection OptionValues + { + get { return c; } + } + } + + public enum OptionValueType + { + None, + Optional, + Required, + } + + public abstract class Option + { + string prototype, description; + string[] names; + OptionValueType type; + int count; + string[] separators; + bool hidden; + + protected Option(string prototype, string description) + : this(prototype, description, 1, false) + { + } + + protected Option(string prototype, string description, int maxValueCount) + : this(prototype, description, maxValueCount, false) + { + } + + protected Option(string prototype, string description, int maxValueCount, bool hidden) + { + if (prototype == null) + throw new ArgumentNullException("prototype"); + if (prototype.Length == 0) + throw new ArgumentException("Cannot be the empty string.", "prototype"); + if (maxValueCount < 0) + throw new ArgumentOutOfRangeException("maxValueCount"); + + this.prototype = prototype; + this.description = description; + this.count = maxValueCount; + this.names = (this is OptionSet.Category) + // append GetHashCode() so that "duplicate" categories have distinct + // names, e.g. adding multiple "" categories should be valid. + ? [prototype + this.GetHashCode()] + : prototype.Split('|'); + + if (this is OptionSet.Category || this is CommandOption) + return; + + this.type = ParsePrototype(); + this.hidden = hidden; + + if (this.count == 0 && type != OptionValueType.None) + throw new ArgumentException( + "Cannot provide maxValueCount of 0 for OptionValueType.Required or " + + "OptionValueType.Optional.", + "maxValueCount"); + if (this.type == OptionValueType.None && maxValueCount > 1) + throw new ArgumentException( + string.Format("Cannot provide maxValueCount of {0} for OptionValueType.None.", maxValueCount), + "maxValueCount"); + if (Array.IndexOf(names, "<>") >= 0 && + ((names.Length == 1 && this.type != OptionValueType.None) || + (names.Length > 1 && this.MaxValueCount > 1))) + throw new ArgumentException( + "The default option handler '<>' cannot require values.", + "prototype"); + } + + public string Prototype { get { return prototype; } } + public string Description { get { return description; } } + public OptionValueType OptionValueType { get { return type; } } + public int MaxValueCount { get { return count; } } + public bool Hidden { get { return hidden; } } + + public string[] GetNames() + { + return (string[])names.Clone(); + } + + public string[] GetValueSeparators() + { + if (separators == null) + return new string[0]; + return (string[])separators.Clone(); + } + + protected static T Parse(string value, OptionContext c) + { + Type tt = typeof(T); #if PCL - TypeInfo ti = tt.GetTypeInfo (); + TypeInfo ti = tt.GetTypeInfo(); #else - Type ti = tt; + Type ti = tt; #endif - bool nullable = - ti.IsValueType && - ti.IsGenericType && - !ti.IsGenericTypeDefinition && - ti.GetGenericTypeDefinition () == typeof (Nullable<>); + bool nullable = + ti.IsValueType && + ti.IsGenericType && + !ti.IsGenericTypeDefinition && + ti.GetGenericTypeDefinition() == typeof(Nullable<>); #if PCL - Type targetType = nullable ? tt.GenericTypeArguments [0] : tt; + Type targetType = nullable ? tt.GenericTypeArguments [0] : tt; #else - Type targetType = nullable ? tt.GetGenericArguments () [0] : tt; + Type targetType = nullable ? tt.GetGenericArguments()[0] : tt; #endif - T t = default (T); - try { - if (value != null) { + T t = default(T); + try + { + if (value != null) + { #if PCL - if (targetType.GetTypeInfo ().IsEnum) - t = (T) Enum.Parse (targetType, value, true); - else - t = (T) Convert.ChangeType (value, targetType); + if (targetType.GetTypeInfo().IsEnum) + t = (T)Enum.Parse(targetType, value, true); + else + t = (T)Convert.ChangeType(value, targetType); #else - TypeConverter conv = TypeDescriptor.GetConverter (targetType); - t = (T) conv.ConvertFromString (value); + TypeConverter conv = TypeDescriptor.GetConverter(targetType); + t = (T)conv.ConvertFromString(value); #endif - } - } - catch (Exception e) { - throw new OptionException ( - string.Format ( - c.OptionSet.MessageLocalizer ("Could not convert string `{0}' to type {1} for option `{2}'."), - value, targetType.Name, c.OptionName), - c.OptionName, e); - } - return t; - } - - internal string[] Names {get {return names;}} - internal string[] ValueSeparators {get {return separators;}} - - static readonly char[] NameTerminator = new char[]{'=', ':'}; - - private OptionValueType ParsePrototype () - { - char type = '\0'; - List seps = new List (); - for (int i = 0; i < names.Length; ++i) { - string name = names [i]; - if (name.Length == 0) - throw new ArgumentException ("Empty option names are not supported.", "prototype"); - - int end = name.IndexOfAny (NameTerminator); - if (end == -1) - continue; - names [i] = name.Substring (0, end); - if (type == '\0' || type == name [end]) - type = name [end]; - else - throw new ArgumentException ( - string.Format ("Conflicting option types: '{0}' vs. '{1}'.", type, name [end]), - "prototype"); - AddSeparators (name, end, seps); - } - - if (type == '\0') - return OptionValueType.None; - - if (count <= 1 && seps.Count != 0) - throw new ArgumentException ( - string.Format ("Cannot provide key/value separators for Options taking {0} value(s).", count), - "prototype"); - if (count > 1) { - if (seps.Count == 0) - this.separators = new string[]{":", "="}; - else if (seps.Count == 1 && seps [0].Length == 0) - this.separators = null; - else - this.separators = seps.ToArray (); - } - - return type == '=' ? OptionValueType.Required : OptionValueType.Optional; - } - - private static void AddSeparators (string name, int end, ICollection seps) - { - int start = -1; - for (int i = end+1; i < name.Length; ++i) { - switch (name [i]) { - case '{': - if (start != -1) - throw new ArgumentException ( - string.Format ("Ill-formed name/value separator found in \"{0}\".", name), - "prototype"); - start = i+1; - break; - case '}': - if (start == -1) - throw new ArgumentException ( - string.Format ("Ill-formed name/value separator found in \"{0}\".", name), - "prototype"); - seps.Add (name.Substring (start, i-start)); - start = -1; - break; - default: - if (start == -1) - seps.Add (name [i].ToString ()); - break; - } - } - if (start != -1) - throw new ArgumentException ( - string.Format ("Ill-formed name/value separator found in \"{0}\".", name), - "prototype"); - } - - public void Invoke (OptionContext c) - { - OnParseComplete (c); - c.OptionName = null; - c.Option = null; - c.OptionValues.Clear (); - } - - protected abstract void OnParseComplete (OptionContext c); - - internal void InvokeOnParseComplete (OptionContext c) - { - OnParseComplete (c); - } - - public override string ToString () - { - return Prototype; - } - } - - public abstract class ArgumentSource { - - protected ArgumentSource () - { - } - - public abstract string[] GetNames (); - public abstract string Description { get; } - public abstract bool GetArguments (string value, out IEnumerable replacement); + } + } + catch (Exception e) + { + throw new OptionException( + string.Format( + c.OptionSet.MessageLocalizer("Could not convert string `{0}' to type {1} for option `{2}'."), + value, targetType.Name, c.OptionName), + c.OptionName, e); + } + return t; + } + + internal string[] Names { get { return names; } } + internal string[] ValueSeparators { get { return separators; } } + + static readonly char[] NameTerminator = new char[] { '=', ':' }; + + private OptionValueType ParsePrototype() + { + char type = '\0'; + List seps = new List(); + for (int i = 0; i < names.Length; ++i) + { + string name = names[i]; + if (name.Length == 0) + throw new ArgumentException("Empty option names are not supported.", "prototype"); + + int end = name.IndexOfAny(NameTerminator); + if (end == -1) + continue; + names[i] = name.Substring(0, end); + if (type == '\0' || type == name[end]) + type = name[end]; + else + throw new ArgumentException( + string.Format("Conflicting option types: '{0}' vs. '{1}'.", type, name[end]), + "prototype"); + AddSeparators(name, end, seps); + } + + if (type == '\0') + return OptionValueType.None; + + if (count <= 1 && seps.Count != 0) + throw new ArgumentException( + string.Format("Cannot provide key/value separators for Options taking {0} value(s).", count), + "prototype"); + if (count > 1) + { + if (seps.Count == 0) + this.separators = new string[] { ":", "=" }; + else if (seps.Count == 1 && seps[0].Length == 0) + this.separators = null; + else + this.separators = seps.ToArray(); + } + + return type == '=' ? OptionValueType.Required : OptionValueType.Optional; + } + + private static void AddSeparators(string name, int end, ICollection seps) + { + int start = -1; + for (int i = end + 1; i < name.Length; ++i) + { + switch (name[i]) + { + case '{': + if (start != -1) + throw new ArgumentException( + string.Format("Ill-formed name/value separator found in \"{0}\".", name), + "prototype"); + start = i + 1; + break; + case '}': + if (start == -1) + throw new ArgumentException( + string.Format("Ill-formed name/value separator found in \"{0}\".", name), + "prototype"); + seps.Add(name.Substring(start, i - start)); + start = -1; + break; + default: + if (start == -1) + seps.Add(name[i].ToString()); + break; + } + } + if (start != -1) + throw new ArgumentException( + string.Format("Ill-formed name/value separator found in \"{0}\".", name), + "prototype"); + } + + public void Invoke(OptionContext c) + { + OnParseComplete(c); + c.OptionName = null; + c.Option = null; + c.OptionValues.Clear(); + } + + protected abstract void OnParseComplete(OptionContext c); + + internal void InvokeOnParseComplete(OptionContext c) + { + OnParseComplete(c); + } + + public override string ToString() + { + return Prototype; + } + } + + public abstract class ArgumentSource + { + + protected ArgumentSource() + { + } + + public abstract string[] GetNames(); + public abstract string Description { get; } + public abstract bool GetArguments(string value, out IEnumerable replacement); #if !PCL || NETSTANDARD1_3 - public static IEnumerable GetArgumentsFromFile (string file) - { - return GetArguments (File.OpenText (file), true); - } + public static IEnumerable GetArgumentsFromFile(string file) + { + return GetArguments(File.OpenText(file), true); + } #endif - public static IEnumerable GetArguments (TextReader reader) - { - return GetArguments (reader, false); - } - - // Cribbed from mcs/driver.cs:LoadArgs(string) - static IEnumerable GetArguments (TextReader reader, bool close) - { - try { - StringBuilder arg = new StringBuilder (); - - string line; - while ((line = reader.ReadLine ()) != null) { - int t = line.Length; - - for (int i = 0; i < t; i++) { - char c = line [i]; - - if (c == '"' || c == '\'') { - char end = c; - - for (i++; i < t; i++){ - c = line [i]; - - if (c == end) - break; - arg.Append (c); - } - } else if (c == ' ') { - if (arg.Length > 0) { - yield return arg.ToString (); - arg.Length = 0; - } - } else - arg.Append (c); - } - if (arg.Length > 0) { - yield return arg.ToString (); - arg.Length = 0; - } - } - } - finally { - if (close) - reader.Dispose (); - } - } - } + public static IEnumerable GetArguments(TextReader reader) + { + return GetArguments(reader, false); + } + + // Cribbed from mcs/driver.cs:LoadArgs(string) + static IEnumerable GetArguments(TextReader reader, bool close) + { + try + { + StringBuilder arg = new StringBuilder(); + + string line; + while ((line = reader.ReadLine()) != null) + { + int t = line.Length; + + for (int i = 0; i < t; i++) + { + char c = line[i]; + + if (c == '"' || c == '\'') + { + char end = c; + + for (i++; i < t; i++) + { + c = line[i]; + + if (c == end) + break; + arg.Append(c); + } + } + else if (c == ' ') + { + if (arg.Length > 0) + { + yield return arg.ToString(); + arg.Length = 0; + } + } + else + arg.Append(c); + } + if (arg.Length > 0) + { + yield return arg.ToString(); + arg.Length = 0; + } + } + } + finally + { + if (close) + reader.Dispose(); + } + } + } #if !PCL || NETSTANDARD1_3 - public class ResponseFileSource : ArgumentSource { - - public override string[] GetNames () - { - return new string[]{"@file"}; - } - - public override string Description { - get {return "Read response file for more options.";} - } - - public override bool GetArguments (string value, out IEnumerable replacement) - { - if (string.IsNullOrEmpty (value) || !value.StartsWith ("@")) { - replacement = null; - return false; - } - replacement = ArgumentSource.GetArgumentsFromFile (value.Substring (1)); - return true; - } - } + public class ResponseFileSource : ArgumentSource + { + + public override string[] GetNames() + { + return new string[] { "@file" }; + } + + public override string Description + { + get { return "Read response file for more options."; } + } + + public override bool GetArguments(string value, out IEnumerable replacement) + { + if (string.IsNullOrEmpty(value) || !value.StartsWith("@")) + { + replacement = null; + return false; + } + replacement = ArgumentSource.GetArgumentsFromFile(value.Substring(1)); + return true; + } + } #endif #if !PCL - [Serializable] + [Serializable] #endif - public class OptionException : Exception { - private string option; - - public OptionException () - { - } - - public OptionException (string message, string optionName) - : base (message) - { - this.option = optionName; - } - - public OptionException (string message, string optionName, Exception innerException) - : base (message, innerException) - { - this.option = optionName; - } + public class OptionException : Exception + { + private string option; + + public OptionException() + { + } + + public OptionException(string message, string optionName) + : base(message) + { + this.option = optionName; + } + + public OptionException(string message, string optionName, Exception innerException) + : base(message, innerException) + { + this.option = optionName; + } #if !PCL - protected OptionException (SerializationInfo info, StreamingContext context) - : base (info, context) - { - this.option = info.GetString ("OptionName"); - } + protected OptionException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + this.option = info.GetString("OptionName"); + } #endif - public string OptionName { - get {return this.option;} - } + public string OptionName + { + get { return this.option; } + } #if !PCL && !NET #pragma warning disable 618 // SecurityPermissionAttribute is obsolete - [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)] + [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)] #pragma warning restore 618 - public override void GetObjectData (SerializationInfo info, StreamingContext context) - { - base.GetObjectData (info, context); - info.AddValue ("OptionName", option); - } + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + info.AddValue("OptionName", option); + } #endif - } - - public delegate void OptionAction (TKey key, TValue value); - - public class OptionSet : KeyedCollection - { - public OptionSet () - : this (null) - { - } - - public OptionSet (MessageLocalizerConverter localizer) - { - this.roSources = new ReadOnlyCollection (sources); - this.localizer = localizer; - if (this.localizer == null) { - this.localizer = delegate (string f) { - return f; - }; - } - } - - MessageLocalizerConverter localizer; - - public MessageLocalizerConverter MessageLocalizer { - get {return localizer;} - internal set {localizer = value;} - } - - List sources = new List (); - ReadOnlyCollection roSources; - - public ReadOnlyCollection ArgumentSources { - get {return roSources;} - } - - - protected override string GetKeyForItem (Option item) - { - if (item == null) - throw new ArgumentNullException ("option"); - if (item.Names != null && item.Names.Length > 0) - return item.Names [0]; - // This should never happen, as it's invalid for Option to be - // constructed w/o any names. - throw new InvalidOperationException ("Option has no names!"); - } - - [Obsolete ("Use KeyedCollection.this[string]")] - protected Option GetOptionForName (string option) - { - if (option == null) - throw new ArgumentNullException ("option"); - try { - return base [option]; - } - catch (KeyNotFoundException) { - return null; - } - } - - protected override void InsertItem (int index, Option item) - { - base.InsertItem (index, item); - AddImpl (item); - } - - protected override void RemoveItem (int index) - { - Option p = Items [index]; - base.RemoveItem (index); - // KeyedCollection.RemoveItem() handles the 0th item - for (int i = 1; i < p.Names.Length; ++i) { - Dictionary.Remove (p.Names [i]); - } - } - - protected override void SetItem (int index, Option item) - { - base.SetItem (index, item); - AddImpl (item); - } - - private void AddImpl (Option option) - { - if (option == null) - throw new ArgumentNullException ("option"); - List added = new List (option.Names.Length); - try { - // KeyedCollection.InsertItem/SetItem handle the 0th name. - for (int i = 1; i < option.Names.Length; ++i) { - Dictionary.Add (option.Names [i], option); - added.Add (option.Names [i]); - } - } - catch (Exception) { - foreach (string name in added) - Dictionary.Remove (name); - throw; - } - } - - public OptionSet Add (string header) - { - if (header == null) - throw new ArgumentNullException ("header"); - Add (new Category (header)); - return this; - } - - internal sealed class Category : Option { - - // Prototype starts with '=' because this is an invalid prototype - // (see Option.ParsePrototype(), and thus it'll prevent Category - // instances from being accidentally used as normal options. - public Category (string description) - : base ("=:Category:= " + description, description) - { - } - - protected override void OnParseComplete (OptionContext c) - { - throw new NotSupportedException ("Category.OnParseComplete should not be invoked."); - } - } - - - public new OptionSet Add (Option option) - { - base.Add (option); - return this; - } - - sealed class ActionOption : Option { - Action action; - - public ActionOption (string prototype, string description, int count, Action action) - : this (prototype, description, count, action, false) - { - } - - public ActionOption (string prototype, string description, int count, Action action, bool hidden) - : base (prototype, description, count, hidden) - { - if (action == null) - throw new ArgumentNullException ("action"); - this.action = action; - } - - protected override void OnParseComplete (OptionContext c) - { - action (c.OptionValues); - } - } - - public OptionSet Add (string prototype, Action action) - { - return Add (prototype, null, action); - } - - public OptionSet Add (string prototype, string description, Action action) - { - return Add (prototype, description, action, false); - } - - public OptionSet Add (string prototype, string description, Action action, bool hidden) - { - if (action == null) - throw new ArgumentNullException ("action"); - Option p = new ActionOption (prototype, description, 1, - delegate (OptionValueCollection v) { action (v [0]); }, hidden); - base.Add (p); - return this; - } - - public OptionSet Add (string prototype, OptionAction action) - { - return Add (prototype, null, action); - } - - public OptionSet Add (string prototype, string description, OptionAction action) - { - return Add (prototype, description, action, false); - } - - public OptionSet Add (string prototype, string description, OptionAction action, bool hidden) { - if (action == null) - throw new ArgumentNullException ("action"); - Option p = new ActionOption (prototype, description, 2, - delegate (OptionValueCollection v) {action (v [0], v [1]);}, hidden); - base.Add (p); - return this; - } - - sealed class ActionOption : Option { - Action action; - - public ActionOption (string prototype, string description, Action action) - : base (prototype, description, 1) - { - if (action == null) - throw new ArgumentNullException ("action"); - this.action = action; - } - - protected override void OnParseComplete (OptionContext c) - { - action (Parse (c.OptionValues [0], c)); - } - } - - sealed class ActionOption : Option { - OptionAction action; - - public ActionOption (string prototype, string description, OptionAction action) - : base (prototype, description, 2) - { - if (action == null) - throw new ArgumentNullException ("action"); - this.action = action; - } - - protected override void OnParseComplete (OptionContext c) - { - action ( - Parse (c.OptionValues [0], c), - Parse (c.OptionValues [1], c)); - } - } - - public OptionSet Add (string prototype, Action action) - { - return Add (prototype, null, action); - } - - public OptionSet Add (string prototype, string description, Action action) - { - return Add (new ActionOption (prototype, description, action)); - } - - public OptionSet Add (string prototype, OptionAction action) - { - return Add (prototype, null, action); - } - - public OptionSet Add (string prototype, string description, OptionAction action) - { - return Add (new ActionOption (prototype, description, action)); - } - - public OptionSet Add (ArgumentSource source) - { - if (source == null) - throw new ArgumentNullException ("source"); - sources.Add (source); - return this; - } - - protected virtual OptionContext CreateOptionContext () - { - return new OptionContext (this); - } - - public List Parse (IEnumerable arguments) - { - if (arguments == null) - throw new ArgumentNullException ("arguments"); - OptionContext c = CreateOptionContext (); - c.OptionIndex = -1; - bool process = true; - List unprocessed = new List (); - Option def = Contains ("<>") ? this ["<>"] : null; - ArgumentEnumerator ae = new ArgumentEnumerator (arguments); - foreach (string argument in ae) { - ++c.OptionIndex; - if (argument == "--") { - process = false; - continue; - } - if (!process) { - Unprocessed (unprocessed, def, c, argument); - continue; - } - if (AddSource (ae, argument)) - continue; - if (!Parse (argument, c)) - Unprocessed (unprocessed, def, c, argument); - } - if (c.Option != null) - c.Option.Invoke (c); - return unprocessed; - } - - class ArgumentEnumerator : IEnumerable { - List> sources = new List> (); - - public ArgumentEnumerator (IEnumerable arguments) - { - sources.Add (arguments.GetEnumerator ()); - } - - public void Add (IEnumerable arguments) - { - sources.Add (arguments.GetEnumerator ()); - } - - public IEnumerator GetEnumerator () - { - do { - IEnumerator c = sources [sources.Count-1]; - if (c.MoveNext ()) - yield return c.Current; - else { - c.Dispose (); - sources.RemoveAt (sources.Count-1); - } - } while (sources.Count > 0); - } - - IEnumerator IEnumerable.GetEnumerator () - { - return GetEnumerator (); - } - } - - bool AddSource (ArgumentEnumerator ae, string argument) - { - foreach (ArgumentSource source in sources) { - IEnumerable replacement; - if (!source.GetArguments (argument, out replacement)) - continue; - ae.Add (replacement); - return true; - } - return false; - } - - private static bool Unprocessed (ICollection extra, Option def, OptionContext c, string argument) - { - if (def == null) { - extra.Add (argument); - return false; - } - c.OptionValues.Add (argument); - c.Option = def; - c.Option.Invoke (c); - return false; - } - - private readonly Regex ValueOption = new Regex ( - @"^(?--|-|/)(?[^:=]+)((?[:=])(?.*))?$"); - - protected bool GetOptionParts (string argument, out string flag, out string name, out string sep, out string value) - { - if (argument == null) - throw new ArgumentNullException ("argument"); - - flag = name = sep = value = null; - Match m = ValueOption.Match (argument); - if (!m.Success) { - return false; - } - flag = m.Groups ["flag"].Value; - name = m.Groups ["name"].Value; - if (m.Groups ["sep"].Success && m.Groups ["value"].Success) { - sep = m.Groups ["sep"].Value; - value = m.Groups ["value"].Value; - } - return true; - } - - protected virtual bool Parse (string argument, OptionContext c) - { - if (c.Option != null) { - ParseValue (argument, c); - return true; - } - - string f, n, s, v; - if (!GetOptionParts (argument, out f, out n, out s, out v)) - return false; - - Option p; - if (Contains (n)) { - p = this [n]; - c.OptionName = f + n; - c.Option = p; - switch (p.OptionValueType) { - case OptionValueType.None: - c.OptionValues.Add (n); - c.Option.Invoke (c); - break; - case OptionValueType.Optional: - case OptionValueType.Required: - ParseValue (v, c); - break; - } - return true; - } - // no match; is it a bool option? - if (ParseBool (argument, n, c)) - return true; - // is it a bundled option? - if (ParseBundledValue (f, string.Concat (n + s + v), c)) - return true; - - return false; - } - - private void ParseValue (string option, OptionContext c) - { - if (option != null) - foreach (string o in c.Option.ValueSeparators != null - ? option.Split (c.Option.ValueSeparators, c.Option.MaxValueCount - c.OptionValues.Count, StringSplitOptions.None) - : new string[]{option}) { - c.OptionValues.Add (o); - } - if (c.OptionValues.Count == c.Option.MaxValueCount || - c.Option.OptionValueType == OptionValueType.Optional) - c.Option.Invoke (c); - else if (c.OptionValues.Count > c.Option.MaxValueCount) { - throw new OptionException (localizer (string.Format ( - "Error: Found {0} option values when expecting {1}.", - c.OptionValues.Count, c.Option.MaxValueCount)), - c.OptionName); - } - } - - private bool ParseBool (string option, string n, OptionContext c) - { - Option p; - string rn; - if (n.Length >= 1 && (n [n.Length-1] == '+' || n [n.Length-1] == '-') && - Contains ((rn = n.Substring (0, n.Length-1)))) { - p = this [rn]; - string v = n [n.Length-1] == '+' ? option : null; - c.OptionName = option; - c.Option = p; - c.OptionValues.Add (v); - p.Invoke (c); - return true; - } - return false; - } - - private bool ParseBundledValue (string f, string n, OptionContext c) - { - if (f != "-") - return false; - for (int i = 0; i < n.Length; ++i) { - Option p; - string opt = f + n [i].ToString (); - string rn = n [i].ToString (); - if (!Contains (rn)) { - if (i == 0) - return false; - throw new OptionException (string.Format (localizer ( - "Cannot use unregistered option '{0}' in bundle '{1}'."), rn, f + n), null); - } - p = this [rn]; - switch (p.OptionValueType) { - case OptionValueType.None: - Invoke (c, opt, n, p); - break; - case OptionValueType.Optional: - case OptionValueType.Required: { - string v = n.Substring (i+1); - c.Option = p; - c.OptionName = opt; - ParseValue (v.Length != 0 ? v : null, c); - return true; - } - default: - throw new InvalidOperationException ("Unknown OptionValueType: " + p.OptionValueType); - } - } - return true; - } - - private static void Invoke (OptionContext c, string name, string value, Option option) - { - c.OptionName = name; - c.Option = option; - c.OptionValues.Add (value); - option.Invoke (c); - } - - private const int OptionWidth = 29; - private const int Description_FirstWidth = 80 - OptionWidth; - private const int Description_RemWidth = 80 - OptionWidth - 2; - - static readonly string CommandHelpIndentStart = new string (' ', OptionWidth); - static readonly string CommandHelpIndentRemaining = new string (' ', OptionWidth + 2); - - public void WriteOptionDescriptions (TextWriter o) - { - foreach (Option p in this) { - int written = 0; - - if (p.Hidden) - continue; - - Category c = p as Category; - if (c != null) { - WriteDescription (o, p.Description, "", 80, 80); - continue; - } - CommandOption co = p as CommandOption; - if (co != null) { - WriteCommandDescription (o, co.Command); - continue; - } - - if (!WriteOptionPrototype (o, p, ref written)) - continue; - - if (written < OptionWidth) - o.Write (new string (' ', OptionWidth - written)); - else { - o.WriteLine (); - o.Write (new string (' ', OptionWidth)); - } - - WriteDescription (o, p.Description, new string (' ', OptionWidth+2), - Description_FirstWidth, Description_RemWidth); - } - - foreach (ArgumentSource s in sources) { - string[] names = s.GetNames (); - if (names == null || names.Length == 0) - continue; - - int written = 0; - - Write (o, ref written, " "); - Write (o, ref written, names [0]); - for (int i = 1; i < names.Length; ++i) { - Write (o, ref written, ", "); - Write (o, ref written, names [i]); - } - - if (written < OptionWidth) - o.Write (new string (' ', OptionWidth - written)); - else { - o.WriteLine (); - o.Write (new string (' ', OptionWidth)); - } - - WriteDescription (o, s.Description, new string (' ', OptionWidth+2), - Description_FirstWidth, Description_RemWidth); - } - } - - internal void WriteCommandDescription (TextWriter o, Command c) - { - var name = new string (' ', 8) + c.Name; - if (name.Length < OptionWidth - 1) { - WriteDescription (o, name + new string (' ', OptionWidth - name.Length) + c.Help, CommandHelpIndentRemaining, 80, Description_RemWidth); - } else { - WriteDescription (o, name, "", 80, 80); - WriteDescription (o, CommandHelpIndentStart + c.Help, CommandHelpIndentRemaining, 80, Description_RemWidth); - } - } - - void WriteDescription (TextWriter o, string value, string prefix, int firstWidth, int remWidth) - { - bool indent = false; - foreach (string line in GetLines (localizer (GetDescription (value)), firstWidth, remWidth)) { - if (indent) - o.Write (prefix); - o.WriteLine (line); - indent = true; - } - } - - bool WriteOptionPrototype (TextWriter o, Option p, ref int written) - { - string[] names = p.Names; - - int i = GetNextOptionIndex (names, 0); - if (i == names.Length) - return false; - - if (names [i].Length == 1) { - Write (o, ref written, " -"); - Write (o, ref written, names [0]); - } - else { - Write (o, ref written, " --"); - Write (o, ref written, names [0]); - } - - for ( i = GetNextOptionIndex (names, i+1); - i < names.Length; i = GetNextOptionIndex (names, i+1)) { - Write (o, ref written, ", "); - Write (o, ref written, names [i].Length == 1 ? "-" : "--"); - Write (o, ref written, names [i]); - } - - if (p.OptionValueType == OptionValueType.Optional || - p.OptionValueType == OptionValueType.Required) { - if (p.OptionValueType == OptionValueType.Optional) { - Write (o, ref written, localizer ("[")); - } - Write (o, ref written, localizer ("=" + GetArgumentName (0, p.MaxValueCount, p.Description))); - string sep = p.ValueSeparators != null && p.ValueSeparators.Length > 0 - ? p.ValueSeparators [0] - : " "; - for (int c = 1; c < p.MaxValueCount; ++c) { - Write (o, ref written, localizer (sep + GetArgumentName (c, p.MaxValueCount, p.Description))); - } - if (p.OptionValueType == OptionValueType.Optional) { - Write (o, ref written, localizer ("]")); - } - } - return true; - } - - static int GetNextOptionIndex (string[] names, int i) - { - while (i < names.Length && names [i] == "<>") { - ++i; - } - return i; - } - - static void Write (TextWriter o, ref int n, string s) - { - n += s.Length; - o.Write (s); - } - - private static string GetArgumentName (int index, int maxIndex, string description) - { - if (description == null) - return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1); - string[] nameStart; - if (maxIndex == 1) - nameStart = new string[]{"{0:", "{"}; - else - nameStart = new string[]{"{" + index + ":"}; - for (int i = 0; i < nameStart.Length; ++i) { - int start, j = 0; - do { - start = description.IndexOf (nameStart [i], j); - } while (start >= 0 && j != 0 ? description [j++ - 1] == '{' : false); - if (start == -1) - continue; - int end = description.IndexOf ("}", start); - if (end == -1) - continue; - return description.Substring (start + nameStart [i].Length, end - start - nameStart [i].Length); - } - return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1); - } - - private static string GetDescription (string description) - { - if (description == null) - return string.Empty; - StringBuilder sb = new StringBuilder (description.Length); - int start = -1; - for (int i = 0; i < description.Length; ++i) { - switch (description [i]) { - case '{': - if (i == start) { - sb.Append ('{'); - start = -1; - } - else if (start < 0) - start = i + 1; - break; - case '}': - if (start < 0) { - if ((i+1) == description.Length || description [i+1] != '}') - throw new InvalidOperationException ("Invalid option description: " + description); - ++i; - sb.Append ("}"); - } - else { - sb.Append (description.Substring (start, i - start)); - start = -1; - } - break; - case ':': - if (start < 0) - goto default; - start = i + 1; - break; - default: - if (start < 0) - sb.Append (description [i]); - break; - } - } - return sb.ToString (); - } - - private static IEnumerable GetLines (string description, int firstWidth, int remWidth) - { - return StringCoda.WrappedLines (description, firstWidth, remWidth); - } - } - - public class Command - { - public string Name {get;} - public string Help {get;} - - public OptionSet Options {get; set;} - public Action> Run {get; set;} - - public CommandSet CommandSet {get; internal set;} - - public Command (string name, string help = null) - { - if (string.IsNullOrEmpty (name)) - throw new ArgumentNullException (nameof (name)); - - Name = name; - Help = help; - } - - public virtual int Invoke (IEnumerable arguments) - { - var rest = Options?.Parse (arguments) ?? arguments; - Run?.Invoke (rest); - return 0; - } - } - - class CommandOption : Option - { - public Command Command {get;} - - // Prototype starts with '=' because this is an invalid prototype - // (see Option.ParsePrototype(), and thus it'll prevent Category - // instances from being accidentally used as normal options. - public CommandOption (Command command, bool hidden = false) - : base ("=:Command:= " + command?.Name, command?.Name, maxValueCount: 0, hidden: hidden) - { - if (command == null) - throw new ArgumentNullException (nameof (command)); - Command = command; - } - - protected override void OnParseComplete (OptionContext c) - { - throw new NotSupportedException ("CommandOption.OnParseComplete should not be invoked."); - } - } - - class HelpOption : Option - { - Option option; - CommandSet commands; - - public HelpOption (CommandSet commands, Option d) - : base (d.Prototype, d.Description, d.MaxValueCount, d.Hidden) - { - this.commands = commands; - this.option = d; - } - - protected override void OnParseComplete (OptionContext c) - { - commands.showHelp = true; - - option?.InvokeOnParseComplete (c); - } - } - - class CommandOptionSet : OptionSet - { - CommandSet commands; - - public CommandOptionSet (CommandSet commands, MessageLocalizerConverter localizer) - : base (localizer) - { - this.commands = commands; - } - - protected override void SetItem (int index, Option item) - { - if (ShouldWrapOption (item)) { - base.SetItem (index, new HelpOption (commands, item)); - return; - } - base.SetItem (index, item); - } - - bool ShouldWrapOption (Option item) - { - if (item == null) - return false; - var help = item as HelpOption; - if (help != null) - return false; - foreach (var n in item.Names) { - if (n == "help") - return true; - } - return false; - } - - protected override void InsertItem (int index, Option item) - { - if (ShouldWrapOption (item)) { - base.InsertItem (index, new HelpOption (commands, item)); - return; - } - base.InsertItem (index, item); - } - } - - public class CommandSet : KeyedCollection - { - readonly OptionSet options; - readonly TextWriter outWriter; - readonly TextWriter errorWriter; - readonly string suite; - - HelpCommand help; - - internal bool showHelp; - - internal OptionSet Options => options; + } + + public delegate void OptionAction(TKey key, TValue value); + + public class OptionSet : KeyedCollection + { + public OptionSet() + : this(null) + { + } + + public OptionSet(MessageLocalizerConverter localizer) + { + this.roSources = new ReadOnlyCollection(sources); + this.localizer = localizer; + if (this.localizer == null) + { + this.localizer = delegate (string f) + { + return f; + }; + } + } + + MessageLocalizerConverter localizer; + + public MessageLocalizerConverter MessageLocalizer + { + get { return localizer; } + internal set { localizer = value; } + } + + List sources = new List(); + ReadOnlyCollection roSources; + + public ReadOnlyCollection ArgumentSources + { + get { return roSources; } + } + + + protected override string GetKeyForItem(Option item) + { + if (item == null) + throw new ArgumentNullException("option"); + if (item.Names != null && item.Names.Length > 0) + return item.Names[0]; + // This should never happen, as it's invalid for Option to be + // constructed w/o any names. + throw new InvalidOperationException("Option has no names!"); + } + + [Obsolete("Use KeyedCollection.this[string]")] + protected Option GetOptionForName(string option) + { + if (option == null) + throw new ArgumentNullException("option"); + try + { + return base[option]; + } + catch (KeyNotFoundException) + { + return null; + } + } + + protected override void InsertItem(int index, Option item) + { + base.InsertItem(index, item); + AddImpl(item); + } + + protected override void RemoveItem(int index) + { + Option p = Items[index]; + base.RemoveItem(index); + // KeyedCollection.RemoveItem() handles the 0th item + for (int i = 1; i < p.Names.Length; ++i) + { + Dictionary.Remove(p.Names[i]); + } + } + + protected override void SetItem(int index, Option item) + { + base.SetItem(index, item); + AddImpl(item); + } + + private void AddImpl(Option option) + { + if (option == null) + throw new ArgumentNullException("option"); + List added = new List(option.Names.Length); + try + { + // KeyedCollection.InsertItem/SetItem handle the 0th name. + for (int i = 1; i < option.Names.Length; ++i) + { + Dictionary.Add(option.Names[i], option); + added.Add(option.Names[i]); + } + } + catch (Exception) + { + foreach (string name in added) + Dictionary.Remove(name); + throw; + } + } + + public OptionSet Add(string header) + { + if (header == null) + throw new ArgumentNullException("header"); + Add(new Category(header)); + return this; + } + + internal sealed class Category : Option + { + + // Prototype starts with '=' because this is an invalid prototype + // (see Option.ParsePrototype(), and thus it'll prevent Category + // instances from being accidentally used as normal options. + public Category(string description) + : base("=:Category:= " + description, description) + { + } + + protected override void OnParseComplete(OptionContext c) + { + throw new NotSupportedException("Category.OnParseComplete should not be invoked."); + } + } + + + public new OptionSet Add(Option option) + { + base.Add(option); + return this; + } + + sealed class ActionOption : Option + { + Action action; + + public ActionOption(string prototype, string description, int count, Action action) + : this(prototype, description, count, action, false) + { + } + + public ActionOption(string prototype, string description, int count, Action action, bool hidden) + : base(prototype, description, count, hidden) + { + if (action == null) + throw new ArgumentNullException("action"); + this.action = action; + } + + protected override void OnParseComplete(OptionContext c) + { + action(c.OptionValues); + } + } + + public OptionSet Add(string prototype, Action action) + { + return Add(prototype, null, action); + } + + public OptionSet Add(string prototype, string description, Action action) + { + return Add(prototype, description, action, false); + } + + public OptionSet Add(string prototype, string description, Action action, bool hidden) + { + if (action == null) + throw new ArgumentNullException("action"); + Option p = new ActionOption(prototype, description, 1, + delegate (OptionValueCollection v) { action(v[0]); }, hidden); + base.Add(p); + return this; + } + + public OptionSet Add(string prototype, OptionAction action) + { + return Add(prototype, null, action); + } + + public OptionSet Add(string prototype, string description, OptionAction action) + { + return Add(prototype, description, action, false); + } + + public OptionSet Add(string prototype, string description, OptionAction action, bool hidden) + { + if (action == null) + throw new ArgumentNullException("action"); + Option p = new ActionOption(prototype, description, 2, + delegate (OptionValueCollection v) { action(v[0], v[1]); }, hidden); + base.Add(p); + return this; + } + + sealed class ActionOption : Option + { + Action action; + + public ActionOption(string prototype, string description, Action action) + : base(prototype, description, 1) + { + if (action == null) + throw new ArgumentNullException("action"); + this.action = action; + } + + protected override void OnParseComplete(OptionContext c) + { + action(Parse(c.OptionValues[0], c)); + } + } + + sealed class ActionOption : Option + { + OptionAction action; + + public ActionOption(string prototype, string description, OptionAction action) + : base(prototype, description, 2) + { + if (action == null) + throw new ArgumentNullException("action"); + this.action = action; + } + + protected override void OnParseComplete(OptionContext c) + { + action( + Parse(c.OptionValues[0], c), + Parse(c.OptionValues[1], c)); + } + } + + public OptionSet Add(string prototype, Action action) + { + return Add(prototype, null, action); + } + + public OptionSet Add(string prototype, string description, Action action) + { + return Add(new ActionOption(prototype, description, action)); + } + + public OptionSet Add(string prototype, OptionAction action) + { + return Add(prototype, null, action); + } + + public OptionSet Add(string prototype, string description, OptionAction action) + { + return Add(new ActionOption(prototype, description, action)); + } + + public OptionSet Add(ArgumentSource source) + { + if (source == null) + throw new ArgumentNullException("source"); + sources.Add(source); + return this; + } + + protected virtual OptionContext CreateOptionContext() + { + return new OptionContext(this); + } + + public List Parse(IEnumerable arguments) + { + if (arguments == null) + throw new ArgumentNullException("arguments"); + OptionContext c = CreateOptionContext(); + c.OptionIndex = -1; + bool process = true; + List unprocessed = new List(); + Option def = Contains("<>") ? this["<>"] : null; + ArgumentEnumerator ae = new ArgumentEnumerator(arguments); + foreach (string argument in ae) + { + ++c.OptionIndex; + if (argument == "--") + { + process = false; + continue; + } + if (!process) + { + Unprocessed(unprocessed, def, c, argument); + continue; + } + if (AddSource(ae, argument)) + continue; + if (!Parse(argument, c)) + Unprocessed(unprocessed, def, c, argument); + } + if (c.Option != null) + c.Option.Invoke(c); + return unprocessed; + } + + class ArgumentEnumerator : IEnumerable + { + List> sources = new List>(); + + public ArgumentEnumerator(IEnumerable arguments) + { + sources.Add(arguments.GetEnumerator()); + } + + public void Add(IEnumerable arguments) + { + sources.Add(arguments.GetEnumerator()); + } + + public IEnumerator GetEnumerator() + { + do + { + IEnumerator c = sources[sources.Count - 1]; + if (c.MoveNext()) + yield return c.Current; + else + { + c.Dispose(); + sources.RemoveAt(sources.Count - 1); + } + } while (sources.Count > 0); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + bool AddSource(ArgumentEnumerator ae, string argument) + { + foreach (ArgumentSource source in sources) + { + IEnumerable replacement; + if (!source.GetArguments(argument, out replacement)) + continue; + ae.Add(replacement); + return true; + } + return false; + } + + private static bool Unprocessed(ICollection extra, Option def, OptionContext c, string argument) + { + if (def == null) + { + extra.Add(argument); + return false; + } + c.OptionValues.Add(argument); + c.Option = def; + c.Option.Invoke(c); + return false; + } + + private readonly Regex ValueOption = new Regex( + @"^(?--|-|/)(?[^:=]+)((?[:=])(?.*))?$"); + + protected bool GetOptionParts(string argument, out string flag, out string name, out string sep, out string value) + { + if (argument == null) + throw new ArgumentNullException("argument"); + + flag = name = sep = value = null; + Match m = ValueOption.Match(argument); + if (!m.Success) + { + return false; + } + flag = m.Groups["flag"].Value; + name = m.Groups["name"].Value; + if (m.Groups["sep"].Success && m.Groups["value"].Success) + { + sep = m.Groups["sep"].Value; + value = m.Groups["value"].Value; + } + return true; + } + + protected virtual bool Parse(string argument, OptionContext c) + { + if (c.Option != null) + { + ParseValue(argument, c); + return true; + } + + string f, n, s, v; + if (!GetOptionParts(argument, out f, out n, out s, out v)) + return false; + + Option p; + if (Contains(n)) + { + p = this[n]; + c.OptionName = f + n; + c.Option = p; + switch (p.OptionValueType) + { + case OptionValueType.None: + c.OptionValues.Add(n); + c.Option.Invoke(c); + break; + case OptionValueType.Optional: + case OptionValueType.Required: + ParseValue(v, c); + break; + } + return true; + } + // no match; is it a bool option? + if (ParseBool(argument, n, c)) + return true; + // is it a bundled option? + if (ParseBundledValue(f, string.Concat(n + s + v), c)) + return true; + + return false; + } + + private void ParseValue(string option, OptionContext c) + { + if (option != null) + foreach (string o in c.Option.ValueSeparators != null + ? option.Split(c.Option.ValueSeparators, c.Option.MaxValueCount - c.OptionValues.Count, StringSplitOptions.None) + : new string[] { option }) + { + c.OptionValues.Add(o); + } + if (c.OptionValues.Count == c.Option.MaxValueCount || + c.Option.OptionValueType == OptionValueType.Optional) + c.Option.Invoke(c); + else if (c.OptionValues.Count > c.Option.MaxValueCount) + { + throw new OptionException(localizer(string.Format( + "Error: Found {0} option values when expecting {1}.", + c.OptionValues.Count, c.Option.MaxValueCount)), + c.OptionName); + } + } + + private bool ParseBool(string option, string n, OptionContext c) + { + Option p; + string rn; + if (n.Length >= 1 && (n[n.Length - 1] == '+' || n[n.Length - 1] == '-') && + Contains((rn = n.Substring(0, n.Length - 1)))) + { + p = this[rn]; + string v = n[n.Length - 1] == '+' ? option : null; + c.OptionName = option; + c.Option = p; + c.OptionValues.Add(v); + p.Invoke(c); + return true; + } + return false; + } + + private bool ParseBundledValue(string f, string n, OptionContext c) + { + if (f != "-") + return false; + for (int i = 0; i < n.Length; ++i) + { + Option p; + string opt = f + n[i].ToString(); + string rn = n[i].ToString(); + if (!Contains(rn)) + { + if (i == 0) + return false; + throw new OptionException(string.Format(localizer( + "Cannot use unregistered option '{0}' in bundle '{1}'."), rn, f + n), null); + } + p = this[rn]; + switch (p.OptionValueType) + { + case OptionValueType.None: + Invoke(c, opt, n, p); + break; + case OptionValueType.Optional: + case OptionValueType.Required: + { + string v = n.Substring(i + 1); + c.Option = p; + c.OptionName = opt; + ParseValue(v.Length != 0 ? v : null, c); + return true; + } + default: + throw new InvalidOperationException("Unknown OptionValueType: " + p.OptionValueType); + } + } + return true; + } + + private static void Invoke(OptionContext c, string name, string value, Option option) + { + c.OptionName = name; + c.Option = option; + c.OptionValues.Add(value); + option.Invoke(c); + } + + private const int OptionWidth = 29; + private const int Description_FirstWidth = 80 - OptionWidth; + private const int Description_RemWidth = 80 - OptionWidth - 2; + + static readonly string CommandHelpIndentStart = new string(' ', OptionWidth); + static readonly string CommandHelpIndentRemaining = new string(' ', OptionWidth + 2); + + public void WriteOptionDescriptions(TextWriter o) + { + foreach (Option p in this) + { + int written = 0; + + if (p.Hidden) + continue; + + Category c = p as Category; + if (c != null) + { + WriteDescription(o, p.Description, "", 80, 80); + continue; + } + CommandOption co = p as CommandOption; + if (co != null) + { + WriteCommandDescription(o, co.Command); + continue; + } + + if (!WriteOptionPrototype(o, p, ref written)) + continue; + + if (written < OptionWidth) + o.Write(new string(' ', OptionWidth - written)); + else + { + o.WriteLine(); + o.Write(new string(' ', OptionWidth)); + } + + WriteDescription(o, p.Description, new string(' ', OptionWidth + 2), + Description_FirstWidth, Description_RemWidth); + } + + foreach (ArgumentSource s in sources) + { + string[] names = s.GetNames(); + if (names == null || names.Length == 0) + continue; + + int written = 0; + + Write(o, ref written, " "); + Write(o, ref written, names[0]); + for (int i = 1; i < names.Length; ++i) + { + Write(o, ref written, ", "); + Write(o, ref written, names[i]); + } + + if (written < OptionWidth) + o.Write(new string(' ', OptionWidth - written)); + else + { + o.WriteLine(); + o.Write(new string(' ', OptionWidth)); + } + + WriteDescription(o, s.Description, new string(' ', OptionWidth + 2), + Description_FirstWidth, Description_RemWidth); + } + } + + internal void WriteCommandDescription(TextWriter o, Command c) + { + var name = new string(' ', 8) + c.Name; + if (name.Length < OptionWidth - 1) + { + WriteDescription(o, name + new string(' ', OptionWidth - name.Length) + c.Help, CommandHelpIndentRemaining, 80, Description_RemWidth); + } + else + { + WriteDescription(o, name, "", 80, 80); + WriteDescription(o, CommandHelpIndentStart + c.Help, CommandHelpIndentRemaining, 80, Description_RemWidth); + } + } + + void WriteDescription(TextWriter o, string value, string prefix, int firstWidth, int remWidth) + { + bool indent = false; + foreach (string line in GetLines(localizer(GetDescription(value)), firstWidth, remWidth)) + { + if (indent) + o.Write(prefix); + o.WriteLine(line); + indent = true; + } + } + + bool WriteOptionPrototype(TextWriter o, Option p, ref int written) + { + string[] names = p.Names; + + int i = GetNextOptionIndex(names, 0); + if (i == names.Length) + return false; + + if (names[i].Length == 1) + { + Write(o, ref written, " -"); + Write(o, ref written, names[0]); + } + else + { + Write(o, ref written, " --"); + Write(o, ref written, names[0]); + } + + for (i = GetNextOptionIndex(names, i + 1); + i < names.Length; i = GetNextOptionIndex(names, i + 1)) + { + Write(o, ref written, ", "); + Write(o, ref written, names[i].Length == 1 ? "-" : "--"); + Write(o, ref written, names[i]); + } + + if (p.OptionValueType == OptionValueType.Optional || + p.OptionValueType == OptionValueType.Required) + { + if (p.OptionValueType == OptionValueType.Optional) + { + Write(o, ref written, localizer("[")); + } + Write(o, ref written, localizer("=" + GetArgumentName(0, p.MaxValueCount, p.Description))); + string sep = p.ValueSeparators != null && p.ValueSeparators.Length > 0 + ? p.ValueSeparators[0] + : " "; + for (int c = 1; c < p.MaxValueCount; ++c) + { + Write(o, ref written, localizer(sep + GetArgumentName(c, p.MaxValueCount, p.Description))); + } + if (p.OptionValueType == OptionValueType.Optional) + { + Write(o, ref written, localizer("]")); + } + } + return true; + } + + static int GetNextOptionIndex(string[] names, int i) + { + while (i < names.Length && names[i] == "<>") + { + ++i; + } + return i; + } + + static void Write(TextWriter o, ref int n, string s) + { + n += s.Length; + o.Write(s); + } + + private static string GetArgumentName(int index, int maxIndex, string description) + { + if (description == null) + return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1); + string[] nameStart; + if (maxIndex == 1) + nameStart = new string[] { "{0:", "{" }; + else + nameStart = new string[] { "{" + index + ":" }; + for (int i = 0; i < nameStart.Length; ++i) + { + int start, j = 0; + do + { + start = description.IndexOf(nameStart[i], j); + } while (start >= 0 && j != 0 ? description[j++ - 1] == '{' : false); + if (start == -1) + continue; + int end = description.IndexOf("}", start); + if (end == -1) + continue; + return description.Substring(start + nameStart[i].Length, end - start - nameStart[i].Length); + } + return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1); + } + + private static string GetDescription(string description) + { + if (description == null) + return string.Empty; + StringBuilder sb = new StringBuilder(description.Length); + int start = -1; + for (int i = 0; i < description.Length; ++i) + { + switch (description[i]) + { + case '{': + if (i == start) + { + sb.Append('{'); + start = -1; + } + else if (start < 0) + start = i + 1; + break; + case '}': + if (start < 0) + { + if ((i + 1) == description.Length || description[i + 1] != '}') + throw new InvalidOperationException("Invalid option description: " + description); + ++i; + sb.Append("}"); + } + else + { + sb.Append(description.Substring(start, i - start)); + start = -1; + } + break; + case ':': + if (start < 0) + goto default; + start = i + 1; + break; + default: + if (start < 0) + sb.Append(description[i]); + break; + } + } + return sb.ToString(); + } + + private static IEnumerable GetLines(string description, int firstWidth, int remWidth) + { + return StringCoda.WrappedLines(description, firstWidth, remWidth); + } + } + + public class Command + { + public string Name { get; } + public string Help { get; } + + public OptionSet Options { get; set; } + public Action> Run { get; set; } + + public CommandSet CommandSet { get; internal set; } + + public Command(string name, string help = null) + { + if (string.IsNullOrEmpty(name)) + throw new ArgumentNullException(nameof(name)); + + Name = name; + Help = help; + } + + public virtual int Invoke(IEnumerable arguments) + { + var rest = Options?.Parse(arguments) ?? arguments; + Run?.Invoke(rest); + return 0; + } + } + + class CommandOption : Option + { + public Command Command { get; } + + // Prototype starts with '=' because this is an invalid prototype + // (see Option.ParsePrototype(), and thus it'll prevent Category + // instances from being accidentally used as normal options. + public CommandOption(Command command, bool hidden = false) + : base("=:Command:= " + command?.Name, command?.Name, maxValueCount: 0, hidden: hidden) + { + if (command == null) + throw new ArgumentNullException(nameof(command)); + Command = command; + } + + protected override void OnParseComplete(OptionContext c) + { + throw new NotSupportedException("CommandOption.OnParseComplete should not be invoked."); + } + } + + class HelpOption : Option + { + Option option; + CommandSet commands; + + public HelpOption(CommandSet commands, Option d) + : base(d.Prototype, d.Description, d.MaxValueCount, d.Hidden) + { + this.commands = commands; + this.option = d; + } + + protected override void OnParseComplete(OptionContext c) + { + commands.showHelp = true; + + option?.InvokeOnParseComplete(c); + } + } + + class CommandOptionSet : OptionSet + { + CommandSet commands; + + public CommandOptionSet(CommandSet commands, MessageLocalizerConverter localizer) + : base(localizer) + { + this.commands = commands; + } + + protected override void SetItem(int index, Option item) + { + if (ShouldWrapOption(item)) + { + base.SetItem(index, new HelpOption(commands, item)); + return; + } + base.SetItem(index, item); + } + + bool ShouldWrapOption(Option item) + { + if (item == null) + return false; + var help = item as HelpOption; + if (help != null) + return false; + foreach (var n in item.Names) + { + if (n == "help") + return true; + } + return false; + } + + protected override void InsertItem(int index, Option item) + { + if (ShouldWrapOption(item)) + { + base.InsertItem(index, new HelpOption(commands, item)); + return; + } + base.InsertItem(index, item); + } + } + + public class CommandSet : KeyedCollection + { + readonly OptionSet options; + readonly TextWriter outWriter; + readonly TextWriter errorWriter; + readonly string suite; + + HelpCommand help; + + internal bool showHelp; + + internal OptionSet Options => options; #if !PCL || NETSTANDARD1_3 - public CommandSet(string suite, MessageLocalizerConverter localizer = null) - : this(suite, Console.Out, Console.Error, localizer) - { - } + public CommandSet(string suite, MessageLocalizerConverter localizer = null) + : this(suite, Console.Out, Console.Error, localizer) + { + } #endif - - public CommandSet (string suite, TextWriter output, TextWriter error, MessageLocalizerConverter localizer = null) - { - if (suite == null) - throw new ArgumentNullException (nameof (suite)); - if (output == null) - throw new ArgumentNullException (nameof (output)); - if (error == null) - throw new ArgumentNullException (nameof (error)); - - this.suite = suite; - options = new CommandOptionSet (this, localizer); - outWriter = output; - errorWriter = error; - } - - public string Suite => suite; - public TextWriter Out => outWriter; - public TextWriter Error => errorWriter; - public MessageLocalizerConverter MessageLocalizer => options.MessageLocalizer; - - protected override string GetKeyForItem (Command item) - { - return item?.Name; - } - - public new CommandSet Add (Command value) - { - if (value == null) - throw new ArgumentNullException (nameof (value)); - AddCommand (value); - options.Add (new CommandOption (value)); - return this; - } - - void AddCommand (Command value) - { - if (value.CommandSet != null && value.CommandSet != this) { - throw new ArgumentException ("Command instances can only be added to a single CommandSet.", nameof (value)); - } - value.CommandSet = this; - if (value.Options != null) { - value.Options.MessageLocalizer = options.MessageLocalizer; - } - - base.Add (value); - - help = help ?? value as HelpCommand; - } - - public CommandSet Add (string header) - { - options.Add (header); - return this; - } - - public CommandSet Add (Option option) - { - options.Add (option); - return this; - } - - public CommandSet Add (string prototype, Action action) - { - options.Add (prototype, action); - return this; - } - - public CommandSet Add (string prototype, string description, Action action) - { - options.Add (prototype, description, action); - return this; - } - - public CommandSet Add (string prototype, string description, Action action, bool hidden) - { - options.Add (prototype, description, action, hidden); - return this; - } - - public CommandSet Add (string prototype, OptionAction action) - { - options.Add (prototype, action); - return this; - } - - public CommandSet Add (string prototype, string description, OptionAction action) - { - options.Add (prototype, description, action); - return this; - } - - public CommandSet Add (string prototype, string description, OptionAction action, bool hidden) - { - options.Add (prototype, description, action, hidden); - return this; - } - - public CommandSet Add (string prototype, Action action) - { - options.Add (prototype, null, action); - return this; - } - - public CommandSet Add (string prototype, string description, Action action) - { - options.Add (prototype, description, action); - return this; - } - - public CommandSet Add (string prototype, OptionAction action) - { - options.Add (prototype, action); - return this; - } - - public CommandSet Add (string prototype, string description, OptionAction action) - { - options.Add (prototype, description, action); - return this; - } - - public CommandSet Add (ArgumentSource source) - { - options.Add (source); - return this; - } - - public int Run (IEnumerable arguments) - { - if (arguments == null) - throw new ArgumentNullException (nameof (arguments)); - - this.showHelp = false; - if (help == null) { - help = new HelpCommand (); - AddCommand (help); - } - Action setHelp = v => showHelp = v != null; - if (!options.Contains ("help")) { - options.Add ("help", "", setHelp, hidden: true); - } - if (!options.Contains ("?")) { - options.Add ("?", "", setHelp, hidden: true); - } - var extra = options.Parse (arguments); - if (extra.Count == 0) { - if (showHelp) { - return help.Invoke (extra); - } - Out.WriteLine (options.MessageLocalizer ($"Use `{Suite} help` for usage.")); - return 1; - } - var command = Contains (extra [0]) ? this [extra [0]] : null; - if (command == null) { - help.WriteUnknownCommand (extra [0]); - return 1; - } - extra.RemoveAt (0); - if (showHelp) { - if (command.Options?.Contains ("help") ?? true) { - extra.Add ("--help"); - return command.Invoke (extra); - } - command.Options.WriteOptionDescriptions (Out); - return 0; - } - return command.Invoke (extra); - } - } - - public class HelpCommand : Command - { - public HelpCommand () - : base ("help", help: "Show this message and exit") - { - } - - public override int Invoke (IEnumerable arguments) - { - var extra = new List (arguments ?? new string [0]); - var _ = CommandSet.Options.MessageLocalizer; - if (extra.Count == 0) { - CommandSet.Options.WriteOptionDescriptions (CommandSet.Out); - return 0; - } - var command = CommandSet.Contains (extra [0]) - ? CommandSet [extra [0]] - : null; - if (command == this || extra [0] == "--help") { - CommandSet.Out.WriteLine (_ ($"Usage: {CommandSet.Suite} COMMAND [OPTIONS]")); - CommandSet.Out.WriteLine (_ ($"Use `{CommandSet.Suite} help COMMAND` for help on a specific command.")); - CommandSet.Out.WriteLine (); - CommandSet.Out.WriteLine (_ ($"Available commands:")); - CommandSet.Out.WriteLine (); - foreach (var c in CommandSet) { - CommandSet.Options.WriteCommandDescription (CommandSet.Out, c); - } - return 0; - } - if (command == null) { - WriteUnknownCommand (extra [0]); - return 1; - } - if (command.Options != null) { - command.Options.WriteOptionDescriptions (CommandSet.Out); - return 0; - } - return command.Invoke (new [] { "--help" }); - } - - internal void WriteUnknownCommand (string unknownCommand) - { - CommandSet.Error.WriteLine (CommandSet.Options.MessageLocalizer ($"{CommandSet.Suite}: Unknown command: {unknownCommand}")); - CommandSet.Error.WriteLine (CommandSet.Options.MessageLocalizer ($"{CommandSet.Suite}: Use `{CommandSet.Suite} help` for usage.")); - } - } + + public CommandSet(string suite, TextWriter output, TextWriter error, MessageLocalizerConverter localizer = null) + { + if (suite == null) + throw new ArgumentNullException(nameof(suite)); + if (output == null) + throw new ArgumentNullException(nameof(output)); + if (error == null) + throw new ArgumentNullException(nameof(error)); + + this.suite = suite; + options = new CommandOptionSet(this, localizer); + outWriter = output; + errorWriter = error; + } + + public string Suite => suite; + public TextWriter Out => outWriter; + public TextWriter Error => errorWriter; + public MessageLocalizerConverter MessageLocalizer => options.MessageLocalizer; + + protected override string GetKeyForItem(Command item) + { + return item?.Name; + } + + public new CommandSet Add(Command value) + { + if (value == null) + throw new ArgumentNullException(nameof(value)); + AddCommand(value); + options.Add(new CommandOption(value)); + return this; + } + + void AddCommand(Command value) + { + if (value.CommandSet != null && value.CommandSet != this) + { + throw new ArgumentException("Command instances can only be added to a single CommandSet.", nameof(value)); + } + value.CommandSet = this; + if (value.Options != null) + { + value.Options.MessageLocalizer = options.MessageLocalizer; + } + + base.Add(value); + + help = help ?? value as HelpCommand; + } + + public CommandSet Add(string header) + { + options.Add(header); + return this; + } + + public CommandSet Add(Option option) + { + options.Add(option); + return this; + } + + public CommandSet Add(string prototype, Action action) + { + options.Add(prototype, action); + return this; + } + + public CommandSet Add(string prototype, string description, Action action) + { + options.Add(prototype, description, action); + return this; + } + + public CommandSet Add(string prototype, string description, Action action, bool hidden) + { + options.Add(prototype, description, action, hidden); + return this; + } + + public CommandSet Add(string prototype, OptionAction action) + { + options.Add(prototype, action); + return this; + } + + public CommandSet Add(string prototype, string description, OptionAction action) + { + options.Add(prototype, description, action); + return this; + } + + public CommandSet Add(string prototype, string description, OptionAction action, bool hidden) + { + options.Add(prototype, description, action, hidden); + return this; + } + + public CommandSet Add(string prototype, Action action) + { + options.Add(prototype, null, action); + return this; + } + + public CommandSet Add(string prototype, string description, Action action) + { + options.Add(prototype, description, action); + return this; + } + + public CommandSet Add(string prototype, OptionAction action) + { + options.Add(prototype, action); + return this; + } + + public CommandSet Add(string prototype, string description, OptionAction action) + { + options.Add(prototype, description, action); + return this; + } + + public CommandSet Add(ArgumentSource source) + { + options.Add(source); + return this; + } + + public int Run(IEnumerable arguments) + { + if (arguments == null) + throw new ArgumentNullException(nameof(arguments)); + + this.showHelp = false; + if (help == null) + { + help = new HelpCommand(); + AddCommand(help); + } + Action setHelp = v => showHelp = v != null; + if (!options.Contains("help")) + { + options.Add("help", "", setHelp, hidden: true); + } + if (!options.Contains("?")) + { + options.Add("?", "", setHelp, hidden: true); + } + var extra = options.Parse(arguments); + if (extra.Count == 0) + { + if (showHelp) + { + return help.Invoke(extra); + } + Out.WriteLine(options.MessageLocalizer($"Use `{Suite} help` for usage.")); + return 1; + } + var command = Contains(extra[0]) ? this[extra[0]] : null; + if (command == null) + { + help.WriteUnknownCommand(extra[0]); + return 1; + } + extra.RemoveAt(0); + if (showHelp) + { + if (command.Options?.Contains("help") ?? true) + { + extra.Add("--help"); + return command.Invoke(extra); + } + command.Options.WriteOptionDescriptions(Out); + return 0; + } + return command.Invoke(extra); + } + } + + public class HelpCommand : Command + { + public HelpCommand() + : base("help", help: "Show this message and exit") + { + } + + public override int Invoke(IEnumerable arguments) + { + var extra = new List(arguments ?? new string[0]); + var _ = CommandSet.Options.MessageLocalizer; + if (extra.Count == 0) + { + CommandSet.Options.WriteOptionDescriptions(CommandSet.Out); + return 0; + } + var command = CommandSet.Contains(extra[0]) + ? CommandSet[extra[0]] + : null; + if (command == this || extra[0] == "--help") + { + CommandSet.Out.WriteLine(_($"Usage: {CommandSet.Suite} COMMAND [OPTIONS]")); + CommandSet.Out.WriteLine(_($"Use `{CommandSet.Suite} help COMMAND` for help on a specific command.")); + CommandSet.Out.WriteLine(); + CommandSet.Out.WriteLine(_($"Available commands:")); + CommandSet.Out.WriteLine(); + foreach (var c in CommandSet) + { + CommandSet.Options.WriteCommandDescription(CommandSet.Out, c); + } + return 0; + } + if (command == null) + { + WriteUnknownCommand(extra[0]); + return 1; + } + if (command.Options != null) + { + command.Options.WriteOptionDescriptions(CommandSet.Out); + return 0; + } + return command.Invoke(new[] { "--help" }); + } + + internal void WriteUnknownCommand(string unknownCommand) + { + CommandSet.Error.WriteLine(CommandSet.Options.MessageLocalizer($"{CommandSet.Suite}: Unknown command: {unknownCommand}")); + CommandSet.Error.WriteLine(CommandSet.Options.MessageLocalizer($"{CommandSet.Suite}: Use `{CommandSet.Suite} help` for usage.")); + } + } } diff --git a/src/tools/illink/src/ILLink.CodeFix/DynamicallyAccessedMembersCodeFixProvider.cs b/src/tools/illink/src/ILLink.CodeFix/DynamicallyAccessedMembersCodeFixProvider.cs index 194ec530ff86e9..f644fec90ea3be 100644 --- a/src/tools/illink/src/ILLink.CodeFix/DynamicallyAccessedMembersCodeFixProvider.cs +++ b/src/tools/illink/src/ILLink.CodeFix/DynamicallyAccessedMembersCodeFixProvider.cs @@ -30,22 +30,22 @@ private static ImmutableArray GetSupportedDiagnostics() diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsMethodReturnType)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsField)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsThisParameter)); - // diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsGenericParameter)); + // diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsGenericParameter)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsMethodReturnType)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsField)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter)); - // diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsGenericParameter)); + // diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsGenericParameter)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsParameter)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsMethodReturnType)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsField)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsThisParameter)); - // diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsGenericParameter)); + // diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsGenericParameter)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsMethodReturnType)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsField)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsThisParameter)); - // diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsGenericParameter)); + // diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsGenericParameter)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsParameter)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsField)); @@ -53,8 +53,8 @@ private static ImmutableArray GetSupportedDiagnostics() diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides)); - // diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnImplicitThisBetweenOverrides)); - // diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnGenericParameterBetweenOverrides)); + // diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchOnImplicitThisBetweenOverrides)); + // diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DynamicallyAccessedMembersMismatchOnGenericParameterBetweenOverrides)); return diagDescriptorsArrayBuilder.ToImmutable(); } @@ -68,16 +68,16 @@ private static ImmutableArray GetSupportedDiagnostics() private static string FullyQualifiedAttributeName => DynamicallyAccessedMembersAnalyzer.FullyQualifiedDynamicallyAccessedMembersAttribute; private static readonly string[] AttributeOnReturn = { - DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter.AsString (), + DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter.AsString(), DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsMethodReturnType.AsString(), - DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsField.AsString (), - DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter.AsString (), - DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides.AsString () + DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsField.AsString(), + DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter.AsString(), + DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides.AsString() }; private static readonly string[] AttributeOnGeneric = { DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsParameter.AsString(), - DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType.AsString (), + DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType.AsString(), DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsField.AsString(), DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsThisParameter.AsString(), DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter.AsString(), diff --git a/src/tools/illink/src/ILLink.CodeFix/UnconditionalSuppressMessageCodeFixProvider.cs b/src/tools/illink/src/ILLink.CodeFix/UnconditionalSuppressMessageCodeFixProvider.cs index 92c0d5e4b9620f..85186bde8a8644 100644 --- a/src/tools/illink/src/ILLink.CodeFix/UnconditionalSuppressMessageCodeFixProvider.cs +++ b/src/tools/illink/src/ILLink.CodeFix/UnconditionalSuppressMessageCodeFixProvider.cs @@ -55,7 +55,7 @@ protected override SyntaxNode[] GetAttributeArguments(ISymbol? attributableSymbo var suppressionJustification = syntaxGenerator.AttributeArgument(Justification, syntaxGenerator.LiteralExpression("")); - // [UnconditionalSuppressWarning (category, id, Justification = "")] + // [UnconditionalSuppressWarning(category, id, Justification = "")] return [ruleCategory, ruleId, suppressionJustification]; } } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/FeatureChecksValue.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/FeatureChecksValue.cs index 59e9ad93140ac8..0c300365065df2 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/FeatureChecksValue.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/FeatureChecksValue.cs @@ -7,7 +7,7 @@ namespace ILLink.RoslynAnalyzer.DataFlow { // Represents the feature conditions checked in a conditional expression, // such as - // Debug.Assert (RuntimeFeatures.IsDynamicCodeSupported) + // Debug.Assert(RuntimeFeatures.IsDynamicCodeSupported) // or // if (!RuntimeFeatures.IsDynamicCodeSupported) // For now, this is only designed to track the built-in "features"/"capabilities" diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs index 9a4b3484bd213c..3b87c62452fd28 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs @@ -63,8 +63,9 @@ protected LocalDataFlowAnalysis( OperationBlock = operationBlock; } - public void InterproceduralAnalyze() + public bool InterproceduralAnalyze() { + bool succeeded = true; ValueSetLattice methodGroupLattice = default; DictionaryLattice, MaybeLattice> hoistedLocalLattice = default; var interproceduralStateLattice = new InterproceduralStateLattice( @@ -75,8 +76,8 @@ public void InterproceduralAnalyze() if (OperationBlock is IAttributeOperation attribute) { - AnalyzeAttribute(Context.OwningSymbol, attribute); - return; + succeeded &= AnalyzeAttribute(Context.OwningSymbol, attribute); + return succeeded; } Debug.Assert(Context.OwningSymbol is not IMethodSymbol methodSymbol || @@ -91,29 +92,31 @@ public void InterproceduralAnalyze() Debug.Assert(!oldInterproceduralState.Methods.IsUnknown()); foreach (var method in oldInterproceduralState.Methods.GetKnownValues()) { - AnalyzeMethod(method, ref interproceduralState); + succeeded &= AnalyzeMethod(method, ref interproceduralState); } } + return succeeded; } - private void AnalyzeAttribute(ISymbol owningSymbol, IAttributeOperation attribute) + private bool AnalyzeAttribute(ISymbol owningSymbol, IAttributeOperation attribute) { var cfg = Context.GetControlFlowGraph(attribute); var lValueFlowCaptures = LValueFlowCapturesProvider.CreateLValueFlowCaptures(cfg); var visitor = GetVisitor(owningSymbol, cfg, lValueFlowCaptures, default); - Fixpoint(new ControlFlowGraphProxy(cfg), visitor); + return Fixpoint(new ControlFlowGraphProxy(cfg), visitor); } - private void AnalyzeMethod(MethodBodyValue method, ref InterproceduralState interproceduralState) + private bool AnalyzeMethod(MethodBodyValue method, ref InterproceduralState interproceduralState) { var cfg = method.ControlFlowGraph; var lValueFlowCaptures = LValueFlowCapturesProvider.CreateLValueFlowCaptures(cfg); var visitor = GetVisitor(method.OwningSymbol, cfg, lValueFlowCaptures, interproceduralState); - Fixpoint(new ControlFlowGraphProxy(cfg), visitor); + bool succeeded = Fixpoint(new ControlFlowGraphProxy(cfg), visitor); // The interprocedural state struct is stored as a field of the visitor and modified // in-place there, but we also need those modifications to be reflected here. interproceduralState = visitor.InterproceduralState; + return succeeded; } protected abstract TTransfer GetVisitor( diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs index e1f8eacbf7957e..db1ae85bf19385 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs @@ -171,7 +171,7 @@ public abstract TValue HandleMethodCall( public override TValue VisitLocalReference(ILocalReferenceOperation operation, LocalDataFlowState state) { - return GetLocal(operation, state); + return GetLocal(operation.Local, state); } private TValue ProcessBinderCall(IOperation operation, string methodName, LocalDataFlowState state) @@ -199,21 +199,19 @@ public override TValue VisitDynamicMemberReference(IDynamicMemberReferenceOperat public override TValue VisitDynamicIndexerAccess(IDynamicIndexerAccessOperation operation, LocalDataFlowState state) => ProcessBinderCall(operation, operation.GetValueUsageInfo(OwningSymbol).HasFlag(ValueUsageInfo.Write) ? "SetIndex" : "GetIndex", state); - private bool IsReferenceToCapturedVariable(ILocalReferenceOperation localReference) + private bool IsCapturedVariable(ILocalSymbol local) { - var local = localReference.Local; - if (local.IsConst) return false; Debug.Assert(local.ContainingSymbol is IMethodSymbol or IFieldSymbol, // backing field for property initializers - $"{local.ContainingSymbol.GetType()}: {localReference.Syntax.GetLocation().GetLineSpan()}"); + $"{local.ContainingSymbol.GetType()}: {local.Locations[0].GetLineSpan()}"); return !ReferenceEquals(local.ContainingSymbol, OwningSymbol); } - private TValue GetLocal(ILocalReferenceOperation operation, LocalDataFlowState state) + private TValue GetLocal(ILocalSymbol symbol, LocalDataFlowState state) { - var local = new LocalKey(operation.Local); - if (IsReferenceToCapturedVariable(operation)) + var local = new LocalKey(symbol); + if (IsCapturedVariable(symbol)) InterproceduralState.TrackHoistedLocal(local); // Get the value from the hoisted locals, if it's tracked there. @@ -223,10 +221,10 @@ private TValue GetLocal(ILocalReferenceOperation operation, LocalDataFlowState state, bool merge = false) + private void SetLocal(ILocalSymbol localSymbol, TValue value, LocalDataFlowState state, bool merge = false) { - var local = new LocalKey(operation.Local); - if (IsReferenceToCapturedVariable(operation)) + var local = new LocalKey(localSymbol); + if (IsCapturedVariable(localSymbol)) InterproceduralState.TrackHoistedLocal(local); // Update the value stored in the hoisted locals, if it's tracked there. @@ -239,7 +237,23 @@ private void SetLocal(ILocalReferenceOperation operation, TValue value, LocalDat state.Set(local, newValue); } - private TValue ProcessSingleTargetAssignment(IOperation targetOperation, IAssignmentOperation operation, LocalDataFlowState state, bool merge) + private TValue ProcessSingleTargetAssignment( + IOperation targetOperation, + IAssignmentOperation operation, + LocalDataFlowState state, + bool merge + ) + { + return ProcessSingleTargetAssignment(targetOperation, operation.Value, operation, state, merge); + } + + private TValue ProcessSingleTargetAssignment( + IOperation targetOperation, + IOperation valueOperation, + IOperation assignmentOperation, + LocalDataFlowState state, + bool merge + ) { switch (targetOperation) { @@ -253,8 +267,8 @@ private TValue ProcessSingleTargetAssignment(IOperation targetOperation, IAssign IParameterReferenceOperation parameterRef => GetParameterTargetValue(parameterRef.Parameter), _ => throw new InvalidOperationException() }; - TValue value = Visit(operation.Value, state); - HandleAssignment(value, targetValue, operation, in current.Context); + TValue value = Visit(valueOperation, state); + HandleAssignment(value, targetValue, assignmentOperation, in current.Context); return value; } @@ -266,7 +280,7 @@ private TValue ProcessSingleTargetAssignment(IOperation targetOperation, IAssign // correctly detect whether it is used for reading or writing inside of VisitPropertyReference. // https://github.com/dotnet/roslyn/issues/25057 TValue instanceValue = Visit(propertyRef.Instance, state); - TValue value = Visit(operation.Value, state); + TValue value = Visit(valueOperation, state); IMethodSymbol? setMethod = propertyRef.Property.GetSetMethod(); if (setMethod == null || @@ -287,7 +301,7 @@ private TValue ProcessSingleTargetAssignment(IOperation targetOperation, IAssign var current = state.Current; TValue targetValue = GetBackingFieldTargetValue(propertyRef, in current.Context); - HandleAssignment(value, targetValue, operation, in current.Context); + HandleAssignment(value, targetValue, assignmentOperation, in current.Context); return value; } @@ -297,7 +311,7 @@ private TValue ProcessSingleTargetAssignment(IOperation targetOperation, IAssign arguments.Add(Visit(val, state)); arguments.Add(value); - HandleMethodCallHelper(setMethod, instanceValue, arguments.ToImmutableArray(), operation, state); + HandleMethodCallHelper(setMethod, instanceValue, arguments.ToImmutableArray(), assignmentOperation, state); // The return value of a property set expression is the value, // even though a property setter has no return value. return value; @@ -308,14 +322,14 @@ private TValue ProcessSingleTargetAssignment(IOperation targetOperation, IAssign // not a call to an event accessor method. There is no Roslyn API to access the field, // so just visit the instance and the value. https://github.com/dotnet/roslyn/issues/40103 Visit(eventRef.Instance, state); - return Visit(operation.Value, state); + return Visit(valueOperation, state); } case IImplicitIndexerReferenceOperation indexerRef: { // An implicit reference to an indexer where the argument is a System.Index TValue instanceValue = Visit(indexerRef.Instance, state); TValue indexArgumentValue = Visit(indexerRef.Argument, state); - TValue value = Visit(operation.Value, state); + TValue value = Visit(valueOperation, state); var property = (IPropertySymbol)indexerRef.IndexerSymbol; @@ -331,15 +345,23 @@ private TValue ProcessSingleTargetAssignment(IOperation targetOperation, IAssign break; } - HandleMethodCallHelper(setMethod, instanceValue, argumentsBuilder.ToImmutableArray(), operation, state); + HandleMethodCallHelper(setMethod, instanceValue, argumentsBuilder.ToImmutableArray(), assignmentOperation, state); return value; } // TODO: when setting a property in an attribute, target is an IPropertyReference. case ILocalReferenceOperation localRef: { - TValue value = Visit(operation.Value, state); - SetLocal(localRef, value, state, merge); + TValue value = Visit(valueOperation, state); + SetLocal(localRef.Local, value, state, merge); + return value; + } + case IDeclarationPatternOperation declPattern: + { + if (declPattern.DeclaredSymbol is not ILocalSymbol declaredSymbol) + break; + var value = Visit(valueOperation, state); + SetLocal(declaredSymbol, value, state, merge); return value; } case IArrayElementReferenceOperation arrayElementRef: @@ -349,22 +371,22 @@ private TValue ProcessSingleTargetAssignment(IOperation targetOperation, IAssign TValue arrayRef = Visit(arrayElementRef.ArrayReference, state); TValue index = Visit(arrayElementRef.Indices[0], state); - TValue value = Visit(operation.Value, state); - HandleArrayElementWrite(arrayRef, index, value, operation, merge: merge); + TValue value = Visit(valueOperation, state); + HandleArrayElementWrite(arrayRef, index, value, assignmentOperation, merge: merge); return value; } case IInlineArrayAccessOperation inlineArrayAccess: { TValue arrayRef = Visit(inlineArrayAccess.Instance, state); TValue index = Visit(inlineArrayAccess.Argument, state); - TValue value = Visit(operation.Value, state); - HandleArrayElementWrite(arrayRef, index, value, operation, merge: merge); + TValue value = Visit(valueOperation, state); + HandleArrayElementWrite(arrayRef, index, value, assignmentOperation, merge: merge); return value; } case IDiscardOperation: // Assignments like "_ = SomeMethod();" don't need dataflow tracking. // Seems like this can't happen with a flow capture operation. - Debug.Assert(operation.Target is not IFlowCaptureReferenceOperation); + Debug.Assert(targetOperation is not IFlowCaptureReferenceOperation); break; case IInstanceReferenceOperation: // Assignment to 'this' is not tracked currently. @@ -389,7 +411,7 @@ private TValue ProcessSingleTargetAssignment(IOperation targetOperation, IAssign UnexpectedOperationHandler.Handle(targetOperation); break; } - return Visit(operation.Value, state); + return Visit(valueOperation, state); } public override TValue VisitSimpleAssignment(ISimpleAssignmentOperation operation, LocalDataFlowState state) @@ -397,6 +419,37 @@ public override TValue VisitSimpleAssignment(ISimpleAssignmentOperation operatio return ProcessAssignment(operation, state); } + public override TValue VisitIsPattern(IIsPatternOperation operation, LocalDataFlowState state) + { + if (operation.Pattern is IDeclarationPatternOperation declarationPattern) + { + // A declaration pattern is like an assignment to a local + return ProcessSingleTargetAssignment( + declarationPattern, + operation.Value, + operation, + state, + merge: false + ); + } + return base.VisitIsPattern(operation, state); + } + + public override TValue VisitPropertySubpattern(IPropertySubpatternOperation propPattern, LocalDataFlowState state) + { + if (propPattern.Pattern is IDeclarationPatternOperation declPattern) + { + return ProcessSingleTargetAssignment( + declPattern, + propPattern.Member, + propPattern, + state, + merge: false + ); + } + return base.VisitPropertySubpattern(propPattern, state); + } + public override TValue VisitCompoundAssignment(ICompoundAssignmentOperation operation, LocalDataFlowState state) { return ProcessAssignment(operation, state); @@ -498,7 +551,7 @@ public override TValue VisitFlowCaptureReference(IFlowCaptureReferenceOperation // LValueFlowCaptureProvider doesn't take into account IsInitialization = true, // so it doesn't properly detect this as an l-value capture. // Context: https://github.com/dotnet/roslyn/issues/60757 - // Debug.Assert (IsLValueFlowCapture (operation.Id)); + // Debug.Assert(IsLValueFlowCapture(operation.Id)); Debug.Assert(operation.GetValueUsageInfo(OwningSymbol).HasFlag(ValueUsageInfo.Write), $"{operation.Syntax.GetLocation().GetLineSpan()}"); Debug.Assert(operation.GetValueUsageInfo(OwningSymbol).HasFlag(ValueUsageInfo.Reference), @@ -513,7 +566,7 @@ public override TValue VisitFlowCaptureReference(IFlowCaptureReferenceOperation // where the variable is declared before being passed as an out param, for example: // string s; - // Method (out s, b ? 0 : 1); + // Method(out s, b ? 0 : 1); // The second argument is necessary to create multiple branches so that the compiler // turns both arguments into flow capture references, instead of just passing a local @@ -522,8 +575,8 @@ public override TValue VisitFlowCaptureReference(IFlowCaptureReferenceOperation // This can also happen for a deconstruction assignments, where the write is not to a byref. // Once the analyzer implements support for deconstruction assignments (https://github.com/dotnet/linker/issues/3158), // we can try enabling this assert to ensure that this case is only hit for byrefs. - // Debug.Assert (operation.GetValueUsageInfo (OwningSymbol).HasFlag (ValueUsageInfo.Reference), - // $"{operation.Syntax.GetLocation ().GetLineSpan ()}"); + // Debug.Assert(operation.GetValueUsageInfo(OwningSymbol).HasFlag(ValueUsageInfo.Reference), + // $"{operation.Syntax.GetLocation().GetLineSpan()}"); return TopValue; } @@ -644,8 +697,8 @@ public override TValue VisitPropertyReference(IPropertyReferenceOperation operat // Property references may be passed as ref/out parameters. // Enable this assert once we have support for deconstruction assignments. // https://github.com/dotnet/linker/issues/3158 - // Debug.Assert (operation.GetValueUsageInfo (OwningSymbol).HasFlag (ValueUsageInfo.Reference), - // $"{operation.Syntax.GetLocation ().GetLineSpan ()}"); + // Debug.Assert(operation.GetValueUsageInfo(OwningSymbol).HasFlag(ValueUsageInfo.Reference), + // $"{operation.Syntax.GetLocation().GetLineSpan()}"); return TopValue; } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalStateLattice.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalStateLattice.cs index 7da3d83f3114ad..f08380b08798fd 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalStateLattice.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalStateLattice.cs @@ -45,12 +45,6 @@ public struct LocalState : IEquatable> // are tracked as part of the dictionary of values, keyed by LocalKey. public DefaultValueDictionary> CapturedReferences; - public LocalState(TValue defaultValue) - : this(new DefaultValueDictionary(defaultValue), - new DefaultValueDictionary>(default(ValueSet))) - { - } - public LocalState(DefaultValueDictionary dictionary, DefaultValueDictionary> capturedReferences) { Dictionary = dictionary; diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DiagnosticDescriptors.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DiagnosticDescriptors.cs index 345805f28a6b3d..db8ad1f61ba35b 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DiagnosticDescriptors.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DiagnosticDescriptors.cs @@ -52,8 +52,8 @@ public static DiagnosticDescriptor GetDiagnosticDescriptor(DiagnosticId diagnost } return new DiagnosticDescriptor(diagnosticId.AsString(), - lrsTitle!, - lrsMessage!, + lrsTitle, + lrsMessage, diagnosticCategory ?? diagnosticId.GetDiagnosticCategory(), diagnosticSeverity, isEnabledByDefault, diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs index 7391b1809abc69..31284d48b17d10 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs @@ -57,9 +57,11 @@ public static ImmutableArray GetSupportedDiagnostics() diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.UnrecognizedTypeNameInTypeGetType)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.UnrecognizedParameterInMethodCreateInstance)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.ParametersOfAssemblyCreateInstanceCannotBeAnalyzed)); + diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.TypeNameIsNotAssemblyQualified)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.ReturnValueDoesNotMatchFeatureGuards)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.InvalidFeatureGuard)); diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.TypeMapGroupTypeCannotBeStaticallyDetermined)); + diagDescriptorsArrayBuilder.Add(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.DataflowAnalysisDidNotConverge)); foreach (var requiresAnalyzer in RequiresAnalyzers.Value) { @@ -109,8 +111,17 @@ public override void Initialize(AnalysisContext context) foreach (var operationBlock in context.OperationBlocks) { TrimDataFlowAnalysis trimDataFlowAnalysis = new(context, dataFlowAnalyzerContext, operationBlock); - trimDataFlowAnalysis.InterproceduralAnalyze(); + bool success = trimDataFlowAnalysis.InterproceduralAnalyze(); trimDataFlowAnalysis.ReportDiagnostics(context.ReportDiagnostic); + if (!success) + { + context.ReportDiagnostic( + Diagnostic.Create(DiagnosticDescriptors.GetDiagnosticDescriptor( + DiagnosticId.DataflowAnalysisDidNotConverge, + diagnosticSeverity: DiagnosticSeverity.Warning), + operationBlock.Syntax.GetLocation(), + operationBlock.FindContainingSymbol(context.OwningSymbol).GetDisplayName())); + } } }); @@ -130,13 +141,14 @@ public override void Initialize(AnalysisContext context) var location = GetPrimaryLocation(type.Locations); + var typeNameResolver = new TypeNameResolver(context.Compilation); if (type.BaseType is INamedTypeSymbol baseType) - GenericArgumentDataFlow.ProcessGenericArgumentDataFlow(location, baseType, context.ReportDiagnostic); + GenericArgumentDataFlow.ProcessGenericArgumentDataFlow(typeNameResolver, location, baseType, context.ReportDiagnostic); foreach (var interfaceType in type.Interfaces) - GenericArgumentDataFlow.ProcessGenericArgumentDataFlow(location, interfaceType, context.ReportDiagnostic); + GenericArgumentDataFlow.ProcessGenericArgumentDataFlow(typeNameResolver, location, interfaceType, context.ReportDiagnostic); - DynamicallyAccessedMembersTypeHierarchy.ApplyDynamicallyAccessedMembersToTypeHierarchy(location, type, context.ReportDiagnostic); + DynamicallyAccessedMembersTypeHierarchy.ApplyDynamicallyAccessedMembersToTypeHierarchy(typeNameResolver, location, type, context.ReportDiagnostic); }, SymbolKind.NamedType); context.RegisterSymbolAction(context => { diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersTypeHierarchy.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersTypeHierarchy.cs index 9241fa563b6251..12f78644a68c35 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersTypeHierarchy.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersTypeHierarchy.cs @@ -10,16 +10,20 @@ namespace ILLink.RoslynAnalyzer { - internal sealed class DynamicallyAccessedMembersTypeHierarchy + sealed class DynamicallyAccessedMembersTypeHierarchy { - public static void ApplyDynamicallyAccessedMembersToTypeHierarchy(Location typeLocation, INamedTypeSymbol type, Action reportDiagnostic) + public static void ApplyDynamicallyAccessedMembersToTypeHierarchy( + TypeNameResolver typeNameResolver, + Location typeLocation, + INamedTypeSymbol type, + Action reportDiagnostic) { var annotation = FlowAnnotations.GetTypeAnnotation(type); // We need to apply annotations to this type, and its base/interface types (recursively) // But the annotations on base/interfaces may already be applied so we don't need to apply those // again (and should avoid doing so as it would produce extra warnings). - var reflectionAccessAnalyzer = new ReflectionAccessAnalyzer(reportDiagnostic, type); + var reflectionAccessAnalyzer = new ReflectionAccessAnalyzer(reportDiagnostic, typeNameResolver, type); if (type.BaseType is INamedTypeSymbol baseType) { var baseAnnotation = FlowAnnotations.GetTypeAnnotation(baseType); diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/ILLink.RoslynAnalyzer.csproj b/src/tools/illink/src/ILLink.RoslynAnalyzer/ILLink.RoslynAnalyzer.csproj index bc410523d5d716..49b09a3c07510b 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/ILLink.RoslynAnalyzer.csproj +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/ILLink.RoslynAnalyzer.csproj @@ -8,6 +8,9 @@ false Latest $(NoWarn);CS8524 + + $(NoWarn);CS0436 cs true + true + + + + + + + + + + + + + + true + System.Reflection.Metadata.SR + diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/ISymbolExtensions.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/ISymbolExtensions.cs index 023712a7af2a2d..51f4feff43f5e9 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/ISymbolExtensions.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/ISymbolExtensions.cs @@ -61,7 +61,7 @@ internal static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypes if (!TryGetAttribute(symbol, DynamicallyAccessedMembersAnalyzer.DynamicallyAccessedMembersAttribute, out var dynamicallyAccessedMembers)) return DynamicallyAccessedMemberTypes.None; - return (DynamicallyAccessedMemberTypes)dynamicallyAccessedMembers!.ConstructorArguments[0].Value!; + return (DynamicallyAccessedMemberTypes)dynamicallyAccessedMembers.ConstructorArguments[0].Value!; } internal static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesOnReturnType(this IMethodSymbol methodSymbol) diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/MSBuildPropertyOptionNames.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/MSBuildPropertyOptionNames.cs index e86d0b9d8486e2..51a5645b4318c6 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/MSBuildPropertyOptionNames.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/MSBuildPropertyOptionNames.cs @@ -9,5 +9,7 @@ public static class MSBuildPropertyOptionNames public const string IncludeAllContentForSelfExtract = nameof(IncludeAllContentForSelfExtract); public const string EnableTrimAnalyzer = nameof(EnableTrimAnalyzer); public const string EnableAotAnalyzer = nameof(EnableAotAnalyzer); + public const string VerifyReferenceAotCompatibility = nameof(VerifyReferenceAotCompatibility); + public const string VerifyReferenceTrimCompatibility = nameof(VerifyReferenceTrimCompatibility); } } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs index 444c0ff3ff7a0f..b501fe4e6480a5 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs @@ -36,6 +36,7 @@ public abstract class RequiresAnalyzerBase : DiagnosticAnalyzer private protected virtual ImmutableArray<(Action Action, SyntaxKind[] SyntaxKind)> ExtraSyntaxNodeActions { get; } = ImmutableArray<(Action Action, SyntaxKind[] SyntaxKind)>.Empty; private protected virtual ImmutableArray<(Action Action, SymbolKind[] SymbolKind)> ExtraSymbolActions { get; } = ImmutableArray<(Action Action, SymbolKind[] SymbolKind)>.Empty; + private protected virtual ImmutableArray> ExtraCompilationActions { get; } = ImmutableArray>.Empty; public override void Initialize(AnalysisContext context) { @@ -127,6 +128,9 @@ public override void Initialize(AnalysisContext context) foreach (var extraSyntaxNodeAction in ExtraSyntaxNodeActions) context.RegisterSyntaxNodeAction(extraSyntaxNodeAction.Action, extraSyntaxNodeAction.SyntaxKind); + // Register the implicit base constructor analysis for all analyzers + context.RegisterSymbolAction(AnalyzeImplicitBaseCtor, SymbolKind.NamedType); + foreach (var extraSymbolAction in ExtraSymbolActions) context.RegisterSymbolAction(extraSymbolAction.Action, extraSymbolAction.SymbolKind); @@ -165,6 +169,9 @@ void CheckMatchingAttributesInInterfaces( } } }); + + foreach (var extraCompilationAction in ExtraCompilationActions) + context.RegisterCompilationAction(extraCompilationAction); } internal void CheckAndCreateRequiresDiagnostic( @@ -193,6 +200,33 @@ internal void CheckAndCreateRequiresDiagnostic( CreateRequiresDiagnostic(member, requiresAttribute, diagnosticContext); } + private void AnalyzeImplicitBaseCtor(SymbolAnalysisContext context) + { + var typeSymbol = (INamedTypeSymbol)context.Symbol; + + if (typeSymbol.TypeKind != TypeKind.Class || typeSymbol.BaseType == null) + return; + + if (typeSymbol.InstanceConstructors.Length != 1 || !typeSymbol.InstanceConstructors[0].IsImplicitlyDeclared) + return; + + var implicitCtor = typeSymbol.InstanceConstructors[0]; + + var baseCtor = typeSymbol.BaseType.InstanceConstructors.FirstOrDefault(ctor => ctor.Parameters.IsEmpty); + if (baseCtor == null) + return; + + var diagnosticContext = new DiagnosticContext( + typeSymbol.Locations[0], + context.ReportDiagnostic); + + CheckAndCreateRequiresDiagnostic( + baseCtor, + implicitCtor, + ImmutableArray.Empty, + diagnosticContext); + } + [Flags] protected enum DiagnosticTargets { @@ -386,5 +420,38 @@ ImmutableArray arguments { return false; } + + protected void CheckReferencedAssemblies( + CompilationAnalysisContext context, + string msbuildPropertyName, + string assemblyMetadataName, + DiagnosticDescriptor diagnosticDescriptor) + { + var options = context.Options; + if (!IsAnalyzerEnabled(options)) + return; + + if (!options.IsMSBuildPropertyValueTrue(msbuildPropertyName)) + return; + + foreach (var reference in context.Compilation.References) + { + var refAssembly = context.Compilation.GetAssemblyOrModuleSymbol(reference) as IAssemblySymbol; + if (refAssembly is null) + continue; + + var assemblyMetadata = refAssembly.GetAttributes().FirstOrDefault(attr => + attr.AttributeClass?.Name == "AssemblyMetadataAttribute" && + attr.ConstructorArguments.Length == 2 && + attr.ConstructorArguments[0].Value?.ToString() == assemblyMetadataName && + string.Equals(attr.ConstructorArguments[1].Value?.ToString(), "True", StringComparison.OrdinalIgnoreCase)); + + if (assemblyMetadata is null) + { + var diag = Diagnostic.Create(diagnosticDescriptor, Location.None, refAssembly.Name); + context.ReportDiagnostic(diag); + } + } + } } } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAssemblyFilesAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAssemblyFilesAnalyzer.cs index 8a831db0718dd9..90d1cedd466876 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAssemblyFilesAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAssemblyFilesAnalyzer.cs @@ -142,7 +142,7 @@ protected override string GetMessageFromAttribute(AttributeData requiresAttribut { message = requiresAttribute.ConstructorArguments[0].Value?.ToString() ?? ""; if (!string.IsNullOrEmpty(message)) - message = $" {message}{(message!.TrimEnd().EndsWith(".") ? "" : ".")}"; + message = $" {message}{(message.TrimEnd().EndsWith(".") ? "" : ".")}"; } return message; } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresDynamicCodeAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresDynamicCodeAnalyzer.cs index 8e089da80d58ea..a8b6714fb8a282 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresDynamicCodeAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresDynamicCodeAnalyzer.cs @@ -23,9 +23,10 @@ public sealed class RequiresDynamicCodeAnalyzer : RequiresAnalyzerBase private static readonly DiagnosticDescriptor s_requiresDynamicCodeOnEntryPoint = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.RequiresDynamicCodeOnEntryPoint); private static readonly DiagnosticDescriptor s_requiresDynamicCodeRule = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.RequiresDynamicCode); private static readonly DiagnosticDescriptor s_requiresDynamicCodeAttributeMismatch = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.RequiresDynamicCodeAttributeMismatch); + private static readonly DiagnosticDescriptor s_referenceNotMarkedIsAotCompatibleRule = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.ReferenceNotMarkedIsAotCompatible); public override ImmutableArray SupportedDiagnostics => - ImmutableArray.Create(s_requiresDynamicCodeRule, s_requiresDynamicCodeAttributeMismatch, s_requiresDynamicCodeOnStaticCtor, s_requiresDynamicCodeOnEntryPoint); + ImmutableArray.Create(s_requiresDynamicCodeRule, s_requiresDynamicCodeAttributeMismatch, s_requiresDynamicCodeOnStaticCtor, s_requiresDynamicCodeOnEntryPoint, s_referenceNotMarkedIsAotCompatibleRule); private protected override string RequiresAttributeName => RequiresDynamicCodeAttribute; @@ -163,6 +164,16 @@ private protected override bool IsRequiresCheck(IPropertySymbol propertySymbol, return SymbolEqualityComparer.Default.Equals(propertySymbol, isDynamicCodeSupportedProperty); } + private protected override ImmutableArray> ExtraCompilationActions => + ImmutableArray.Create>((context) => + { + CheckReferencedAssemblies( + context, + MSBuildPropertyOptionNames.VerifyReferenceAotCompatibility, + "IsAotCompatible", + s_referenceNotMarkedIsAotCompatibleRule); + }); + protected override bool VerifyAttributeArguments(AttributeData attribute) => attribute.ConstructorArguments.Length >= 1 && attribute.ConstructorArguments is [{ Type.SpecialType: SpecialType.System_String }, ..]; diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs index 7189f424441b1f..cf2e83f4b8f872 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs @@ -22,8 +22,14 @@ public static bool DoesMemberRequire(this ISymbol member, string requiresAttribu return true; // Also check the containing type - if (member.IsStatic || member.IsConstructor()) - return member.ContainingType.TryGetAttribute(requiresAttribute, out requiresAttributeData); + if ((member.IsStatic || member.IsConstructor()) && member.ContainingType.TryGetAttribute(requiresAttribute, out requiresAttributeData)) + { + if (!ExcludeStatics(requiresAttributeData)) + return true; + + if (member.IsConstructor()) + return true; + } return false; } @@ -33,6 +39,18 @@ public static bool IsInRequiresScope(this ISymbol member, string attributeName) return member.IsInRequiresScope(attributeName, out _); } + private static bool ExcludeStatics(AttributeData attributeData) + { + foreach (var namedArg in attributeData.NamedArguments) + { + if (namedArg.Key == "ExcludeStatics" && namedArg.Value.Value is bool b) + { + return b; + } + } + return false; + } + // TODO: Consider sharing with ILLink IsInRequiresScope method /// /// True if the source of a call is considered to be annotated with the Requires... attribute @@ -58,7 +76,13 @@ public static bool IsInRequiresScope(this ISymbol member, string attributeName, } if (member.ContainingType is ITypeSymbol containingType && containingType.TryGetAttribute(attributeName, out requiresAttribute)) - return true; + { + if (!ExcludeStatics(requiresAttribute)) + return true; + + if (!member.IsStatic) + return true; + } if (member is IMethodSymbol { AssociatedSymbol: { } associated } && associated.TryGetAttribute(attributeName, out requiresAttribute)) return true; diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs index be50cb92f5a66b..09d2625d56b0aa 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs @@ -25,32 +25,10 @@ public sealed class RequiresUnreferencedCodeAnalyzer : RequiresAnalyzerBase private static readonly DiagnosticDescriptor s_requiresUnreferencedCodeOnStaticCtor = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.RequiresUnreferencedCodeOnStaticConstructor); private static readonly DiagnosticDescriptor s_requiresUnreferencedCodeOnEntryPoint = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.RequiresUnreferencedCodeOnEntryPoint); - private static readonly DiagnosticDescriptor s_typeDerivesFromRucClassRule = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.RequiresUnreferencedCodeOnBaseClass); - - private Action typeDerivesFromRucBase - { - get - { - return symbolAnalysisContext => - { - if (symbolAnalysisContext.Symbol is INamedTypeSymbol typeSymbol && !typeSymbol.HasAttribute(RequiresUnreferencedCodeAttribute) - && typeSymbol.BaseType is INamedTypeSymbol baseType - && baseType.TryGetAttribute(RequiresUnreferencedCodeAttribute, out var requiresUnreferencedCodeAttribute)) - { - var diag = Diagnostic.Create(s_typeDerivesFromRucClassRule, - typeSymbol.Locations[0], - typeSymbol, - baseType.GetDisplayName(), - GetMessageFromAttribute(requiresUnreferencedCodeAttribute), - GetUrlFromAttribute(requiresUnreferencedCodeAttribute)); - symbolAnalysisContext.ReportDiagnostic(diag); - } - }; - } - } + private static readonly DiagnosticDescriptor s_referenceNotMarkedIsTrimmableRule = DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.ReferenceNotMarkedIsTrimmable); public override ImmutableArray SupportedDiagnostics => - ImmutableArray.Create(s_makeGenericMethodRule, s_makeGenericTypeRule, s_requiresUnreferencedCodeRule, s_requiresUnreferencedCodeAttributeMismatch, s_typeDerivesFromRucClassRule, s_requiresUnreferencedCodeOnStaticCtor, s_requiresUnreferencedCodeOnEntryPoint); + ImmutableArray.Create(s_makeGenericMethodRule, s_makeGenericTypeRule, s_requiresUnreferencedCodeRule, s_requiresUnreferencedCodeAttributeMismatch, s_requiresUnreferencedCodeOnStaticCtor, s_requiresUnreferencedCodeOnEntryPoint, s_referenceNotMarkedIsTrimmableRule); private protected override string RequiresAttributeName => RequiresUnreferencedCodeAttribute; @@ -99,8 +77,16 @@ protected override bool CreateSpecialIncompatibleMembersDiagnostic( return false; } - private protected override ImmutableArray<(Action Action, SymbolKind[] SymbolKind)> ExtraSymbolActions => - ImmutableArray.Create<(Action Action, SymbolKind[] SymbolKind)>((typeDerivesFromRucBase, new SymbolKind[] { SymbolKind.NamedType })); + + private protected override ImmutableArray> ExtraCompilationActions => + ImmutableArray.Create>((context) => + { + CheckReferencedAssemblies( + context, + MSBuildPropertyOptionNames.VerifyReferenceTrimCompatibility, + "IsTrimmable", + s_referenceNotMarkedIsTrimmableRule); + }); protected override bool VerifyAttributeArguments(AttributeData attribute) => RequiresUnreferencedCodeUtils.VerifyRequiresUnreferencedCodeAttributeArguments(attribute); diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/GenericArgumentDataFlow.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/GenericArgumentDataFlow.cs index 280d81b876e08f..95879fa90f91f6 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/GenericArgumentDataFlow.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/GenericArgumentDataFlow.cs @@ -12,37 +12,38 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis { internal static class GenericArgumentDataFlow { - public static void ProcessGenericArgumentDataFlow(Location location, INamedTypeSymbol type, Action reportDiagnostic) + public static void ProcessGenericArgumentDataFlow(TypeNameResolver typeNameResolver, Location location, INamedTypeSymbol type, Action? reportDiagnostic) { while (type is { IsGenericType: true }) { - ProcessGenericArgumentDataFlow(location, type.TypeArguments, type.TypeParameters, reportDiagnostic); + ProcessGenericArgumentDataFlow(typeNameResolver, location, type.TypeArguments, type.TypeParameters, reportDiagnostic); type = type.ContainingType; } } - public static void ProcessGenericArgumentDataFlow(Location location, IMethodSymbol method, Action reportDiagnostic) + public static void ProcessGenericArgumentDataFlow(TypeNameResolver typeNameResolver, Location location, IMethodSymbol method, Action? reportDiagnostic) { - ProcessGenericArgumentDataFlow(location, method.TypeArguments, method.TypeParameters, reportDiagnostic); + ProcessGenericArgumentDataFlow(typeNameResolver, location, method.TypeArguments, method.TypeParameters, reportDiagnostic); - ProcessGenericArgumentDataFlow(location, method.ContainingType, reportDiagnostic); + ProcessGenericArgumentDataFlow(typeNameResolver, location, method.ContainingType, reportDiagnostic); } - public static void ProcessGenericArgumentDataFlow(Location location, IFieldSymbol field, Action reportDiagnostic) + public static void ProcessGenericArgumentDataFlow(TypeNameResolver typeNameResolver, Location location, IFieldSymbol field, Action? reportDiagnostic) { - ProcessGenericArgumentDataFlow(location, field.ContainingType, reportDiagnostic); + ProcessGenericArgumentDataFlow(typeNameResolver, location, field.ContainingType, reportDiagnostic); } - public static void ProcessGenericArgumentDataFlow(Location location, IPropertySymbol property, Action reportDiagnostic) + public static void ProcessGenericArgumentDataFlow(TypeNameResolver typeNameResolver, Location location, IPropertySymbol property, Action reportDiagnostic) { - ProcessGenericArgumentDataFlow(location, property.ContainingType, reportDiagnostic); + ProcessGenericArgumentDataFlow(typeNameResolver, location, property.ContainingType, reportDiagnostic); } private static void ProcessGenericArgumentDataFlow( + TypeNameResolver typeNameResolver, Location location, ImmutableArray typeArguments, ImmutableArray typeParameters, - Action reportDiagnostic) + Action? reportDiagnostic) { var diagnosticContext = new DiagnosticContext(location, reportDiagnostic); for (int i = 0; i < typeArguments.Length; i++) @@ -53,14 +54,14 @@ private static void ProcessGenericArgumentDataFlow( if (genericParameterValue.DynamicallyAccessedMemberTypes != DynamicallyAccessedMemberTypes.None) { SingleValue genericArgumentValue = SingleValueExtensions.FromTypeSymbol(typeArgument)!; - var reflectionAccessAnalyzer = new ReflectionAccessAnalyzer(reportDiagnostic, typeHierarchyType: null); - var requireDynamicallyAccessedMembersAction = new RequireDynamicallyAccessedMembersAction(diagnosticContext, reflectionAccessAnalyzer); + var reflectionAccessAnalyzer = new ReflectionAccessAnalyzer(reportDiagnostic, typeNameResolver, typeHierarchyType: null); + var requireDynamicallyAccessedMembersAction = new RequireDynamicallyAccessedMembersAction(typeNameResolver, location, reportDiagnostic, reflectionAccessAnalyzer); requireDynamicallyAccessedMembersAction.Invoke(genericArgumentValue, genericParameterValue); } // Recursively process generic argument data flow on the generic argument if it itself is generic if (typeArgument is INamedTypeSymbol namedTypeArgument && namedTypeArgument.IsGenericType) - ProcessGenericArgumentDataFlow(location, namedTypeArgument, reportDiagnostic); + ProcessGenericArgumentDataFlow(typeNameResolver, location, namedTypeArgument, reportDiagnostic); } } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/HandleCallAction.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/HandleCallAction.cs index 8089fd4714686c..9785d00ca34425 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/HandleCallAction.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/HandleCallAction.cs @@ -28,6 +28,7 @@ internal partial struct HandleCallAction private ValueSetLattice _multiValueLattice; public HandleCallAction( + TypeNameResolver typeNameResolver, Location location, ISymbol owningSymbol, IOperation operation, @@ -39,8 +40,8 @@ public HandleCallAction( _isNewObj = operation.Kind == OperationKind.ObjectCreation; _diagnosticContext = new DiagnosticContext(location, reportDiagnostic); _annotations = FlowAnnotations.Instance; - _reflectionAccessAnalyzer = new(reportDiagnostic, typeHierarchyType: null); - _requireDynamicallyAccessedMembersAction = new(_diagnosticContext, _reflectionAccessAnalyzer); + _reflectionAccessAnalyzer = new(reportDiagnostic, typeNameResolver, typeHierarchyType: null); + _requireDynamicallyAccessedMembersAction = new(typeNameResolver, location, reportDiagnostic, _reflectionAccessAnalyzer); _multiValueLattice = multiValueLattice; } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodProxy.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodProxy.cs index 8c2c60964f89a4..68d3ccefcc4ef5 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodProxy.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodProxy.cs @@ -31,7 +31,7 @@ internal readonly partial struct MethodProxy internal partial bool HasGenericParameters() => Method.IsGenericMethod; - internal partial bool HasGenericParametersCount(int genericParameterCount) => Method.TypeParameters.Length == genericParameterCount; + internal partial bool HasGenericArgumentsCount(int genericArgumentCount) => Method.TypeArguments.Length == genericArgumentCount; internal partial ImmutableArray GetGenericParameters() { diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ReflectionAccessAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ReflectionAccessAnalyzer.cs index 516f46c1a5daea..e27c79d03506cd 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ReflectionAccessAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ReflectionAccessAnalyzer.cs @@ -12,15 +12,22 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis { - internal readonly struct ReflectionAccessAnalyzer + readonly struct ReflectionAccessAnalyzer { - private readonly Action? _reportDiagnostic; - private readonly INamedTypeSymbol? _typeHierarchyType; + readonly Action? _reportDiagnostic; - public ReflectionAccessAnalyzer(Action? reportDiagnostic, INamedTypeSymbol? typeHierarchyType) + readonly INamedTypeSymbol? _typeHierarchyType; + + readonly TypeNameResolver _typeNameResolver; + + public ReflectionAccessAnalyzer( + Action? reportDiagnostic, + TypeNameResolver typeNameResolver, + INamedTypeSymbol? typeHierarchyType) { _reportDiagnostic = reportDiagnostic; _typeHierarchyType = typeHierarchyType; + _typeNameResolver = typeNameResolver; } #pragma warning disable CA1822 // Mark members as static - the other partial implementations might need to be instance methods @@ -42,10 +49,10 @@ internal void GetReflectionAccessDiagnostics(Location location, ITypeSymbol type break; /* Skip Type and InterfaceImplementation marking since doesnt seem relevant for diagnostic generation case ITypeSymbol nestedType: - MarkType (location, nestedType); + MarkType(location, nestedType); break; case InterfaceImplementation interfaceImplementation: - MarkInterfaceImplementation (location, interfaceImplementation, dependencyKind); + MarkInterfaceImplementation(location, interfaceImplementation, dependencyKind); break; */ case IEventSymbol @event: @@ -212,5 +219,10 @@ private void GetDiagnosticsForField(Location location, IFieldSymbol fieldSymbol) diagnosticContext.AddDiagnostic(DiagnosticId.DynamicallyAccessedMembersFieldAccessedViaReflection, fieldSymbol.GetDisplayName()); } } + + internal bool TryResolveTypeNameAndMark(string typeName, in DiagnosticContext diagnosticContext, bool needsAssemblyName, [NotNullWhen(true)] out ITypeSymbol? type) + { + return _typeNameResolver.TryResolveTypeName(typeName, diagnosticContext, out type, needsAssemblyName); + } } } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs index 1106b6424278d1..e8bc38a03dcc98 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs @@ -1,40 +1,56 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Reflection.Metadata; +using Microsoft.CodeAnalysis; using ILLink.RoslynAnalyzer.TrimAnalysis; using ILLink.Shared.TypeSystemProxy; +using System.Collections.Immutable; namespace ILLink.Shared.TrimAnalysis { internal partial struct RequireDynamicallyAccessedMembersAction { - private readonly ReflectionAccessAnalyzer _reflectionAccessAnalyzer; + readonly Location _location; + readonly Action? _reportDiagnostic; + readonly ReflectionAccessAnalyzer _reflectionAccessAnalyzer; + readonly TypeNameResolver _typeNameResolver; #pragma warning disable CA1822 // Mark members as static - the other partial implementations might need to be instance methods #pragma warning disable IDE0060 // Unused parameters - should be removed once methods are actually implemented public RequireDynamicallyAccessedMembersAction( - DiagnosticContext diagnosticContext, + TypeNameResolver typeNameResolver, + Location location, + Action? reportDiagnostic, ReflectionAccessAnalyzer reflectionAccessAnalyzer) { - _diagnosticContext = diagnosticContext; + _typeNameResolver = typeNameResolver; + _location = location; + _reportDiagnostic = reportDiagnostic; _reflectionAccessAnalyzer = reflectionAccessAnalyzer; + _diagnosticContext = new(location, reportDiagnostic); } public partial bool TryResolveTypeNameAndMark(string typeName, bool needsAssemblyName, out TypeProxy type) { - // TODO: Implement type name resolution to type symbol - // https://github.com/dotnet/runtime/issues/95118 + var diagnosticContext = new DiagnosticContext(_location, _reportDiagnostic); + if (_reflectionAccessAnalyzer.TryResolveTypeNameAndMark(typeName, diagnosticContext, needsAssemblyName, out ITypeSymbol? foundType)) + { + if (foundType is INamedTypeSymbol namedType && namedType.IsGenericType) + GenericArgumentDataFlow.ProcessGenericArgumentDataFlow(_typeNameResolver, _location, namedType, _reportDiagnostic); - // Important corner cases: - // IL2105 (see it's occurences in the tests) - non-assembly qualified type name which doesn't resolve warns - // - will need to figure out what analyzer should do around this. + type = new TypeProxy(foundType); + return true; + } type = default; return false; } private partial void MarkTypeForDynamicallyAccessedMembers(in TypeProxy type, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) => - _reflectionAccessAnalyzer.GetReflectionAccessDiagnostics(_diagnosticContext.Location, type.Type, dynamicallyAccessedMemberTypes); + _reflectionAccessAnalyzer.GetReflectionAccessDiagnostics(_location, type.Type, dynamicallyAccessedMemberTypes); } } diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs index db8b724521fe4f..4f5c6f06baa777 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs @@ -54,7 +54,7 @@ public TrimAnalysisAssignmentPattern Merge( public void ReportDiagnostics(DataFlowAnalyzerContext context, Action reportDiagnostic) { - var diagnosticContext = new DiagnosticContext(Operation.Syntax.GetLocation(), reportDiagnostic); + var location = Operation.Syntax.GetLocation(); if (context.EnableTrimAnalyzer && !OwningSymbol.IsInRequiresUnreferencedCodeAttributeScope(out _) && !FeatureContext.IsEnabled(RequiresUnreferencedCodeAnalyzer.FullyQualifiedRequiresUnreferencedCodeAttribute)) @@ -68,8 +68,9 @@ public void ReportDiagnostics(DataFlowAnalyzerContext context, Action reportDiagnostic) { var location = Operation.Syntax.GetLocation(); - var reflectionAccessAnalyzer = new ReflectionAccessAnalyzer(reportDiagnostic, typeHierarchyType: null); + var typeNameResolver = new TypeNameResolver(context.Compilation); + var reflectionAccessAnalyzer = new ReflectionAccessAnalyzer(reportDiagnostic, typeNameResolver, typeHierarchyType: null); if (context.EnableTrimAnalyzer && !OwningSymbol.IsInRequiresUnreferencedCodeAttributeScope(out _) && !FeatureContext.IsEnabled(RequiresUnreferencedCodeAnalyzer.FullyQualifiedRequiresUnreferencedCodeAttribute)) diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs index fe26d2a7593ff8..baa9daffcbccac 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs @@ -43,6 +43,8 @@ internal sealed class TrimAnalysisVisitor : LocalDataFlowVisitor< private FeatureChecksVisitor _featureChecksVisitor; + readonly TypeNameResolver _typeNameResolver; + public TrimAnalysisVisitor( Compilation compilation, LocalStateAndContextLattice, FeatureContextLattice> lattice, @@ -57,6 +59,7 @@ public TrimAnalysisVisitor( _multiValueLattice = lattice.LocalStateLattice.Lattice.ValueLattice; TrimAnalysisPatterns = trimAnalysisPatterns; _featureChecksVisitor = new FeatureChecksVisitor(dataFlowAnalyzerContext); + _typeNameResolver = new TypeNameResolver(compilation); } public override FeatureChecksValue GetConditionValue(IOperation branchValueOperation, StateValue state) @@ -134,8 +137,18 @@ public override MultiValue VisitConversion(IConversionOperation operation, State public override MultiValue VisitParameterReference(IParameterReferenceOperation paramRef, StateValue state) { + IParameterSymbol parameter = paramRef.Parameter; + + if (parameter.ContainingSymbol is not IMethodSymbol) + { + // TODO: Extension members allows parameters to be on types, rather than methods. + // For example: `extension(ref T value) { }` will enumerate `value` where + // the containing symbol is a `NonErrorNamedTypeSymbol` + return TopValue; + } + // Reading from a parameter always returns the same annotated value. We don't track modifications. - return GetParameterTargetValue(paramRef.Parameter); + return GetParameterTargetValue(parameter); } public override MultiValue VisitInstanceReference(IInstanceReferenceOperation instanceRef, StateValue state) @@ -331,7 +344,7 @@ public override MultiValue HandleMethodCall( // Especially with DAM on type, this can lead to incorrectly analyzed code (as in unknown type which leads // to noise). ILLink has the same problem currently: https://github.com/dotnet/linker/issues/1952 - HandleCall(operation, OwningSymbol, calledMethod, instance, arguments, Location.None, null, _multiValueLattice, out MultiValue methodReturnValue); + HandleCall(_typeNameResolver, operation, OwningSymbol, calledMethod, instance, arguments, Location.None, null, _multiValueLattice, out MultiValue methodReturnValue); // This will copy the values if necessary TrimAnalysisPatterns.Add(new TrimAnalysisMethodCallPattern( @@ -359,6 +372,7 @@ public override MultiValue HandleMethodCall( } internal static void HandleCall( + TypeNameResolver typeNameResolver, IOperation operation, ISymbol owningSymbol, IMethodSymbol calledMethod, @@ -369,7 +383,7 @@ internal static void HandleCall( ValueSetLattice multiValueLattice, out MultiValue methodReturnValue) { - var handleCallAction = new HandleCallAction(location, owningSymbol, operation, multiValueLattice, reportDiagnostic); + var handleCallAction = new HandleCallAction(typeNameResolver, location, owningSymbol, operation, multiValueLattice, reportDiagnostic); MethodProxy method = new(calledMethod); var intrinsicId = Intrinsics.GetIntrinsicIdForMethod(method); if (!handleCallAction.Invoke(method, instance, arguments, intrinsicId, out methodReturnValue)) diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TypeNameResolver.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TypeNameResolver.cs new file mode 100644 index 00000000000000..77400e898a5529 --- /dev/null +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TypeNameResolver.cs @@ -0,0 +1,154 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Reflection.Metadata; +using Microsoft.CodeAnalysis; +using ILLink.RoslynAnalyzer.TrimAnalysis; +using ILLink.Shared.TypeSystemProxy; +using System.Collections.Immutable; + +namespace ILLink.Shared.TrimAnalysis +{ + internal struct TypeNameResolver + { + readonly Compilation _compilation; + + static readonly TypeNameParseOptions s_typeNameParseOptions = new() { MaxNodes = int.MaxValue }; + + public TypeNameResolver(Compilation compilation) + { + _compilation = compilation; + } + + public bool TryResolveTypeName( + string typeNameString, + in DiagnosticContext diagnosticContext, + out ITypeSymbol? type, + bool needsAssemblyName) + { + type = null; + if (!TypeName.TryParse(typeNameString.AsSpan(), out TypeName? typeName, s_typeNameParseOptions)) + return false; + + if (needsAssemblyName && !IsFullyQualified(typeName)) + { + diagnosticContext.AddDiagnostic(DiagnosticId.TypeNameIsNotAssemblyQualified, typeNameString); + return false; + } + + type = ResolveTypeName(_compilation.Assembly, typeName); + return type != null; + + static bool IsFullyQualified(TypeName typeName) + { + if (typeName.AssemblyName is null) + return false; + + if (typeName.IsArray || typeName.IsPointer || typeName.IsByRef) + return IsFullyQualified(typeName.GetElementType()); + + if (typeName.IsConstructedGenericType) + { + foreach (var arg in typeName.GetGenericArguments()) + { + if (!IsFullyQualified(arg)) + return false; + } + } + + return true; + } + } + + ITypeSymbol? ResolveTypeName(IAssemblySymbol assembly, TypeName typeName) + { + if (typeName.IsSimple) + return GetSimpleType(assembly, typeName); + + if (typeName.IsConstructedGenericType) + return GetGenericType(assembly, typeName); + + if (typeName.IsArray || typeName.IsPointer || typeName.IsByRef) + { + if (ResolveTypeName(assembly, typeName.GetElementType()) is not ITypeSymbol type) + return null; + + if (typeName.IsArray) + return typeName.IsSZArray ? _compilation.CreateArrayTypeSymbol(type) : _compilation.CreateArrayTypeSymbol(type, typeName.GetArrayRank()); + + // Roslyn doesn't have a representation for byref types + // (the byrefness is considered part of the symbol, not its type) + if (typeName.IsByRef) + return null; + + if (typeName.IsPointer) + return _compilation.CreatePointerTypeSymbol(type); + + Debug.Fail("Unreachable"); + return null; + } + + return null; + } + + private ITypeSymbol? GetSimpleType(IAssemblySymbol assembly, TypeName typeName) + { + IAssemblySymbol module = assembly; + if (typeName.AssemblyName is AssemblyNameInfo assemblyName) + { + if (ResolveAssembly(assemblyName) is not IAssemblySymbol resolvedAssembly) + return null; + module = resolvedAssembly; + } + + if (GetSimpleTypeFromModule(typeName, module) is ITypeSymbol type) + return type; + + // The analyzer doesn't see the core library, so can't fall back to lookup up types in corelib. + return null; + } + + private static ITypeSymbol? GetSimpleTypeFromModule(TypeName typeName, IAssemblySymbol module) + { + string fullName = TypeName.Unescape(typeName.FullName); + return module.GetTypeByMetadataName(fullName); + } + + private ITypeSymbol? GetGenericType(IAssemblySymbol assembly, TypeName typeName) + { + if (ResolveTypeName(assembly, typeName.GetGenericTypeDefinition()) is not INamedTypeSymbol typeDefinition) + return null; + + ImmutableArray typeArguments = typeName.GetGenericArguments(); + ITypeSymbol[] instantiation = new ITypeSymbol[typeArguments.Length]; + for (int i = 0; i < typeArguments.Length; i++) + { + if (ResolveTypeName(assembly, typeArguments[i]) is not ITypeSymbol type) + return null; + instantiation[i] = type; + } + return typeDefinition.Construct(instantiation); + } + + IAssemblySymbol? ResolveAssembly(AssemblyNameInfo? assemblyName) + { + if (assemblyName is null) + return null; + + if (_compilation.Assembly.Name == assemblyName.Name) + return _compilation.Assembly; + + foreach (var metadataReference in _compilation.References) + { + if (_compilation.GetAssemblyOrModuleSymbol(metadataReference) is not IAssemblySymbol asmSym) + continue; + if (asmSym.Name == assemblyName.Name) + return asmSym; + } + return null; + } + } +} diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/build/Microsoft.NET.ILLink.Analyzers.props b/src/tools/illink/src/ILLink.RoslynAnalyzer/build/Microsoft.NET.ILLink.Analyzers.props index 3284f19567179d..18ae6cb8fd5e8b 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/build/Microsoft.NET.ILLink.Analyzers.props +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/build/Microsoft.NET.ILLink.Analyzers.props @@ -1,8 +1,10 @@ - - - - + + + + + + diff --git a/src/tools/illink/src/ILLink.Shared/DataFlow/ForwardDataFlowAnalysis.cs b/src/tools/illink/src/ILLink.Shared/DataFlow/ForwardDataFlowAnalysis.cs index a6db2e022b945b..ccf7831deb5810 100644 --- a/src/tools/illink/src/ILLink.Shared/DataFlow/ForwardDataFlowAnalysis.cs +++ b/src/tools/illink/src/ILLink.Shared/DataFlow/ForwardDataFlowAnalysis.cs @@ -214,7 +214,7 @@ successor.ConditionKind is ConditionKind.WhenTrue // This just runs a dataflow algorithm until convergence. It doesn't cache any results, // allowing each particular kind of analysis to decide what is worth saving. - public void Fixpoint(TControlFlowGraph cfg, TTransfer transfer) + public bool Fixpoint(TControlFlowGraph cfg, TTransfer transfer) { TraceStart(cfg); @@ -244,11 +244,15 @@ public void Fixpoint(TControlFlowGraph cfg, TTransfer transfer) }; bool changed = true; - while (changed) + const int MaxIterations = 10_000; + int iterations = 0; + while (changed && iterations < MaxIterations) { changed = false; foreach (var block in cfg.Blocks) { + if (++iterations >= MaxIterations) + break; TraceVisitBlock(block); @@ -348,13 +352,13 @@ public void Fixpoint(TControlFlowGraph cfg, TTransfer transfer) // Catch/filter regions get the initial state from the exception state of the corresponding try region. // This is already accounted for in the non-exceptional control flow state of the catch block above, // so we can just use the state we already computed, for both try and catch regions. - exceptionState!.Value = lattice.Meet(exceptionState!.Value, currentState); + exceptionState!.Value = lattice.Meet(exceptionState.Value, currentState); if (isFinallyBlock) { // Exceptions could also be thrown from inside a finally that was entered due to a previous exception. // So the exception state must also include values from the exceptional finally state (computed above). - exceptionState!.Value = lattice.Meet(exceptionState!.Value, exceptionFinallyState!.Value); + exceptionState.Value = lattice.Meet(exceptionState.Value, exceptionFinallyState!.Value); } } @@ -408,7 +412,7 @@ public void Fixpoint(TControlFlowGraph cfg, TTransfer transfer) // Filters can't contain try/catch/filters. Debug.Assert(enclosingTryOrCatch.Kind != RegionKind.Filter); Box tryOrCatchExceptionState = cfgState.GetExceptionState(enclosingTryOrCatch); - tryOrCatchExceptionState.Value = lattice.Meet(tryOrCatchExceptionState!.Value, exceptionState!.Value); + tryOrCatchExceptionState.Value = lattice.Meet(tryOrCatchExceptionState.Value, exceptionState!.Value); tryOrCatchOrFilterRegion = enclosingTryOrCatch; } } @@ -417,6 +421,8 @@ public void Fixpoint(TControlFlowGraph cfg, TTransfer transfer) } } + return !changed || iterations >= MaxIterations; + void FlowStateThroughExitedFinallys( IControlFlowGraph.ControlFlowBranch predecessor, ref TValue predecessorState) diff --git a/src/tools/illink/src/ILLink.Shared/DiagnosticId.cs b/src/tools/illink/src/ILLink.Shared/DiagnosticId.cs index 68f96275ff718c..dba2ccee7ad288 100644 --- a/src/tools/illink/src/ILLink.Shared/DiagnosticId.cs +++ b/src/tools/illink/src/ILLink.Shared/DiagnosticId.cs @@ -173,7 +173,7 @@ public enum DiagnosticId DynamicallyAccessedMembersOnMethodReturnValueCanOnlyApplyToTypesOrStrings = 2106, MethodsAreAssociatedWithStateMachine = 2107, InvalidScopeInUnconditionalSuppressMessage = 2108, - RequiresUnreferencedCodeOnBaseClass = 2109, + _unused_RequiresUnreferencedCodeOnBaseClass = 2109, DynamicallyAccessedMembersFieldAccessedViaReflection = 2110, DynamicallyAccessedMembersMethodAccessedViaReflection = 2111, DynamicallyAccessedMembersOnTypeReferencesMemberWithRequiresUnreferencedCode = 2112, @@ -189,6 +189,8 @@ public enum DiagnosticId TypeNameIsNotAssemblyQualified = 2122, RequiresUnreferencedCodeOnEntryPoint = 2123, TypeMapGroupTypeCannotBeStaticallyDetermined = 2124, + ReferenceNotMarkedIsTrimmable = 2125, + DataflowAnalysisDidNotConverge = 2126, _EndTrimAnalysisWarningsSentinel, // Single-file diagnostic ids. @@ -208,6 +210,7 @@ public enum DiagnosticId CorrectnessOfAbstractDelegatesCannotBeGuaranteed = 3055, RequiresDynamicCodeOnStaticConstructor = 3056, RequiresDynamicCodeOnEntryPoint = 3057, + ReferenceNotMarkedIsAotCompatible = 3058, _EndAotAnalysisWarningsSentinel, // Feature guard diagnostic ids. diff --git a/src/tools/illink/src/ILLink.Shared/RequiresDynamicCodeAttribute.cs b/src/tools/illink/src/ILLink.Shared/RequiresDynamicCodeAttribute.cs new file mode 100644 index 00000000000000..34768f4d9bb61c --- /dev/null +++ b/src/tools/illink/src/ILLink.Shared/RequiresDynamicCodeAttribute.cs @@ -0,0 +1,58 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#if INCLUDE_EXPECTATIONS +using Mono.Linker.Tests.Cases.Expectations.Assertions; +#endif + +#nullable enable + +namespace System.Diagnostics.CodeAnalysis +{ + /// + /// Indicates that the specified method requires the ability to generate new code at runtime, + /// for example through . + /// + /// + /// This allows tools to understand which methods are unsafe to call when compiling ahead of time. + /// +#if INCLUDE_EXPECTATIONS + [SkipKeptItemsValidation] +#endif + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class, Inherited = false)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class RequiresDynamicCodeAttribute : Attribute + { + /// + /// Initializes a new instance of the class + /// with the specified message. + /// + /// + /// A message that contains information about the usage of dynamic code. + /// + public RequiresDynamicCodeAttribute(string message) + { + Message = message; + } + + /// + /// Indicates whether the attribute should apply to static members. + /// + public bool ExcludeStatics { get; set; } + + /// + /// Gets a message that contains information about the usage of dynamic code. + /// + public string Message { get; } + + /// + /// Gets or sets an optional URL that contains more information about the method, + /// why it requires dynamic code, and what options a consumer has to deal with it. + /// + public string? Url { get; set; } + } +} diff --git a/src/tools/illink/src/ILLink.Shared/RequiresUnreferencedCodeAttribute.cs b/src/tools/illink/src/ILLink.Shared/RequiresUnreferencedCodeAttribute.cs new file mode 100644 index 00000000000000..5c2c9ce96d7266 --- /dev/null +++ b/src/tools/illink/src/ILLink.Shared/RequiresUnreferencedCodeAttribute.cs @@ -0,0 +1,59 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#if INCLUDE_EXPECTATIONS +using Mono.Linker.Tests.Cases.Expectations.Assertions; +#endif + +#nullable enable + +namespace System.Diagnostics.CodeAnalysis +{ + /// + /// Indicates that the specified method requires dynamic access to code that is not referenced + /// statically, for example through . + /// + /// + /// This allows tools to understand which methods are unsafe to call when removing unreferenced + /// code from an application. + /// +#if INCLUDE_EXPECTATIONS + [SkipKeptItemsValidation] +#endif + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class, Inherited = false)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class RequiresUnreferencedCodeAttribute : Attribute + { + /// + /// Initializes a new instance of the class + /// with the specified message. + /// + /// + /// A message that contains information about the usage of unreferenced code. + /// + public RequiresUnreferencedCodeAttribute(string message) + { + Message = message; + } + + /// + /// Indicates whether the attribute should apply to static members. + /// + public bool ExcludeStatics { get; set; } + + /// + /// Gets a message that contains information about the usage of unreferenced code. + /// + public string Message { get; } + + /// + /// Gets or sets an optional URL that contains more information about the method, + /// why it requires unreferenced code, and what options a consumer has to deal with it. + /// + public string? Url { get; set; } + } +} diff --git a/src/tools/illink/src/ILLink.Shared/SharedStrings.resx b/src/tools/illink/src/ILLink.Shared/SharedStrings.resx index 40c921ca706cde..04cd8c6e4f7c43 100644 --- a/src/tools/illink/src/ILLink.Shared/SharedStrings.resx +++ b/src/tools/illink/src/ILLink.Shared/SharedStrings.resx @@ -1239,4 +1239,22 @@ Type name is not assembly qualified. + + Referenced assembly is not marked as trimmable. + + + Referenced assembly '{0}' is not built with `true` and may not be compatible with trimming. + + + Referenced assembly is not marked as AOT-compatible. + + + Referenced assembly '{0}' is not built with `true` and may not be compatible with AOT. + + + Trim dataflow analysis took too long to complete. Trim safety cannot be guaranteed. + + + Trim dataflow analysis of member '{0}' took too long to complete. Trim safety cannot be guaranteed. + diff --git a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs index 7e40ba2aa88c95..97b807ad3e70d7 100644 --- a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs +++ b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs @@ -184,8 +184,8 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers } break; - // System.Reflection.MethodBase.GetMethodFromHandle (RuntimeMethodHandle handle) - // System.Reflection.MethodBase.GetMethodFromHandle (RuntimeMethodHandle handle, RuntimeTypeHandle declaringType) + // System.Reflection.MethodBase.GetMethodFromHandle(RuntimeMethodHandle handle) + // System.Reflection.MethodBase.GetMethodFromHandle(RuntimeMethodHandle handle, RuntimeTypeHandle declaringType) case IntrinsicId.MethodBase_GetMethodFromHandle: { if (argumentValues[0].IsEmpty()) @@ -233,8 +233,8 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers throw new NotImplementedException("These intrinsics should be handled by the specific implementation: " + intrinsicId); // - // GetInterface (String) - // GetInterface (String, bool) + // GetInterface(String) + // GetInterface(String, bool) // case IntrinsicId.Type_GetInterface: { @@ -351,7 +351,7 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.Runtime.CompilerServices.RuntimeHelpers // - // RunClassConstructor (RuntimeTypeHandle type) + // RunClassConstructor(RuntimeTypeHandle type) // case IntrinsicId.RuntimeHelpers_RunClassConstructor: if (argumentValues[0].IsEmpty()) @@ -383,13 +383,13 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers break; // - // GetConstructors (BindingFlags) - // GetMethods (BindingFlags) - // GetFields (BindingFlags) - // GetEvents (BindingFlags) - // GetProperties (BindingFlags) - // GetNestedTypes (BindingFlags) - // GetMembers (BindingFlags) + // GetConstructors(BindingFlags) + // GetMethods(BindingFlags) + // GetFields(BindingFlags) + // GetEvents(BindingFlags) + // GetProperties(BindingFlags) + // GetNestedTypes(BindingFlags) + // GetMembers(BindingFlags) // case IntrinsicId.Type_GetConstructors__BindingFlags: case IntrinsicId.Type_GetMethods__BindingFlags: @@ -442,17 +442,17 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers break; // - // GetField (string) - // GetField (string, BindingFlags) - // GetEvent (string) - // GetEvent (string, BindingFlags) - // GetProperty (string) - // GetProperty (string, BindingFlags) - // GetProperty (string, Type) - // GetProperty (string, Type[]) - // GetProperty (string, Type, Type[]) - // GetProperty (string, Type, Type[], ParameterModifier[]) - // GetProperty (string, BindingFlags, Binder, Type, Type[], ParameterModifier[]) + // GetField(string) + // GetField(string, BindingFlags) + // GetEvent(string) + // GetEvent(string, BindingFlags) + // GetProperty(string) + // GetProperty(string, BindingFlags) + // GetProperty(string, Type) + // GetProperty(string, Type[]) + // GetProperty(string, Type, Type[]) + // GetProperty(string, Type, Type[], ParameterModifier[]) + // GetProperty(string, BindingFlags, Binder, Type, Type[], ParameterModifier[]) // case IntrinsicId.Type_GetField: case IntrinsicId.Type_GetProperty: @@ -519,9 +519,9 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers break; // - // GetMember (String) - // GetMember (String, BindingFlags) - // GetMember (String, MemberTypes, BindingFlags) + // GetMember(String) + // GetMember(String, BindingFlags) + // GetMember(String, MemberTypes, BindingFlags) // case IntrinsicId.Type_GetMember: { @@ -573,17 +573,18 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers break; // - // GetMethod (string) - // GetMethod (string, BindingFlags) - // GetMethod (string, Type[]) - // GetMethod (string, Type[], ParameterModifier[]) - // GetMethod (string, BindingFlags, Type[]) - // GetMethod (string, BindingFlags, Binder, Type[], ParameterModifier[]) - // GetMethod (string, BindingFlags, Binder, CallingConventions, Type[], ParameterModifier[]) - // GetMethod (string, int, Type[]) - // GetMethod (string, int, Type[], ParameterModifier[]?) - // GetMethod (string, int, BindingFlags, Binder?, Type[], ParameterModifier[]?) - // GetMethod (string, int, BindingFlags, Binder?, CallingConventions, Type[], ParameterModifier[]?) + // GetMethod(string) + // GetMethod(string, BindingFlags) + // GetMethod(string, Type[]) + // GetMethod(string, Type[], ParameterModifier[]) + // GetMethod(string, BindingFlags, Type[]) + // GetMethod(string, BindingFlags, Binder, Type[], ParameterModifier[]) + // GetMethod(string, BindingFlags, Binder, CallingConventions, Type[], ParameterModifier[]) + // GetMethod(string, int, Type[]) + // GetMethod(string, int, Type[], ParameterModifier[]?) + // GetMethod(string, int, BindingFlags, Type[]) + // GetMethod(string, int, BindingFlags, Binder?, Type[], ParameterModifier[]?) + // GetMethod(string, int, BindingFlags, Binder?, CallingConventions, Type[], ParameterModifier[]?) // case IntrinsicId.Type_GetMethod: { @@ -663,8 +664,8 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers break; // - // GetNestedType (string) - // GetNestedType (string, BindingFlags) + // GetNestedType(string) + // GetNestedType(string, BindingFlags) // case IntrinsicId.Type_GetNestedType: { @@ -746,10 +747,10 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.Reflection.RuntimeReflectionExtensions // - // static GetRuntimeEvent (this Type type, string name) - // static GetRuntimeField (this Type type, string name) - // static GetRuntimeMethod (this Type type, string name, Type[] parameters) - // static GetRuntimeProperty (this Type type, string name) + // static GetRuntimeEvent(this Type type, string name) + // static GetRuntimeField(this Type type, string name) + // static GetRuntimeMethod(this Type type, string name, Type[] parameters) + // static GetRuntimeProperty(this Type type, string name) // case IntrinsicId.RuntimeReflectionExtensions_GetRuntimeEvent: case IntrinsicId.RuntimeReflectionExtensions_GetRuntimeField: @@ -832,7 +833,7 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.Linq.Expressions.Expression // - // static New (Type) + // static New(Type) // case IntrinsicId.Expression_New: { @@ -854,7 +855,7 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.Linq.Expressions.Expression // - // static Property (Expression, MethodInfo) + // static Property(Expression, MethodInfo) // case IntrinsicId.Expression_Property when calledMethod.HasParameterOfType((ParameterIndex)1, "System.Reflection.MethodInfo"): { @@ -890,8 +891,8 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.Linq.Expressions.Expression // - // static Field (Expression, Type, String) - // static Property (Expression, Type, String) + // static Field(Expression, Type, String) + // static Property(Expression, Type, String) // case IntrinsicId.Expression_Field: case IntrinsicId.Expression_Property: @@ -946,7 +947,7 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.Linq.Expressions.Expression // - // static Call (Type, String, Type[], Expression[]) + // static Call(Type, String, Type[], Expression[]) // case IntrinsicId.Expression_Call: { @@ -1032,12 +1033,12 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.Type // - // GetType (string) - // GetType (string, Boolean) - // GetType (string, Boolean, Boolean) - // GetType (string, Func, Func) - // GetType (string, Func, Func, Boolean) - // GetType (string, Func, Func, Boolean, Boolean) + // GetType(string) + // GetType(string, Boolean) + // GetType(string, Boolean, Boolean) + // GetType(string, Func, Func) + // GetType(string, Func, Func, Boolean) + // GetType(string, Func, Func, Boolean, Boolean) // case IntrinsicId.Type_GetType: { @@ -1093,7 +1094,7 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.Type // - // Type MakeGenericType (params Type[] typeArguments) + // Type MakeGenericType(params Type[] typeArguments) // case IntrinsicId.Type_MakeGenericType: if (instanceValue.IsEmpty() || argumentValues[0].IsEmpty()) @@ -1275,10 +1276,10 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers break; // - // GetConstructor (Type[]) - // GetConstructor (BindingFlags, Type[]) - // GetConstructor (BindingFlags, Binder, Type[], ParameterModifier []) - // GetConstructor (BindingFlags, Binder, CallingConventions, Type[], ParameterModifier []) + // GetConstructor(Type[]) + // GetConstructor(BindingFlags, Type[]) + // GetConstructor(BindingFlags, Binder, Type[], ParameterModifier []) + // GetConstructor(BindingFlags, Binder, CallingConventions, Type[], ParameterModifier []) // case IntrinsicId.Type_GetConstructor: { @@ -1337,7 +1338,7 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.Reflection.MethodInfo // - // MakeGenericMethod (Type[] typeArguments) + // MakeGenericMethod(Type[] typeArguments) // case IntrinsicId.MethodInfo_MakeGenericMethod: { @@ -1373,12 +1374,12 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.Activator // - // static CreateInstance (System.Type type) - // static CreateInstance (System.Type type, bool nonPublic) - // static CreateInstance (System.Type type, params object?[]? args) - // static CreateInstance (System.Type type, object?[]? args, object?[]? activationAttributes) - // static CreateInstance (System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture) - // static CreateInstance (System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture, object?[]? activationAttributes) { throw null; } + // static CreateInstance(System.Type type) + // static CreateInstance(System.Type type, bool nonPublic) + // static CreateInstance(System.Type type, params object?[]? args) + // static CreateInstance(System.Type type, object?[]? args, object?[]? activationAttributes) + // static CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture) + // static CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture, object?[]? activationAttributes) { throw null; } // case IntrinsicId.Activator_CreateInstance__Type: { @@ -1462,9 +1463,9 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.Activator // - // static CreateInstance (string assemblyName, string typeName) - // static CreateInstance (string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture, object?[]? activationAttributes) - // static CreateInstance (string assemblyName, string typeName, object?[]? activationAttributes) + // static CreateInstance(string assemblyName, string typeName) + // static CreateInstance(string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture, object?[]? activationAttributes) + // static CreateInstance(string assemblyName, string typeName, object?[]? activationAttributes) // case IntrinsicId.Activator_CreateInstance__AssemblyName_TypeName: ProcessCreateInstanceByName(calledMethod, argumentValues); @@ -1473,9 +1474,9 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.Activator // - // static CreateInstanceFrom (string assemblyFile, string typeName) - // static CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) - // static CreateInstanceFrom (string assemblyFile, string typeName, object? []? activationAttributes) + // static CreateInstanceFrom(string assemblyFile, string typeName) + // static CreateInstanceFrom(string assemblyFile, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) + // static CreateInstanceFrom(string assemblyFile, string typeName, object? []? activationAttributes) // case IntrinsicId.Activator_CreateInstanceFrom: ProcessCreateInstanceByName(calledMethod, argumentValues); @@ -1484,21 +1485,21 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.AppDomain // - // CreateInstance (string assemblyName, string typeName) - // CreateInstance (string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) - // CreateInstance (string assemblyName, string typeName, object? []? activationAttributes) + // CreateInstance(string assemblyName, string typeName) + // CreateInstance(string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) + // CreateInstance(string assemblyName, string typeName, object? []? activationAttributes) // - // CreateInstanceAndUnwrap (string assemblyName, string typeName) - // CreateInstanceAndUnwrap (string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) - // CreateInstanceAndUnwrap (string assemblyName, string typeName, object? []? activationAttributes) + // CreateInstanceAndUnwrap(string assemblyName, string typeName) + // CreateInstanceAndUnwrap(string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) + // CreateInstanceAndUnwrap(string assemblyName, string typeName, object? []? activationAttributes) // - // CreateInstanceFrom (string assemblyFile, string typeName) - // CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) - // CreateInstanceFrom (string assemblyFile, string typeName, object? []? activationAttributes) + // CreateInstanceFrom(string assemblyFile, string typeName) + // CreateInstanceFrom(string assemblyFile, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) + // CreateInstanceFrom(string assemblyFile, string typeName, object? []? activationAttributes) // - // CreateInstanceFromAndUnwrap (string assemblyFile, string typeName) - // CreateInstanceFromAndUnwrap (string assemblyFile, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) - // CreateInstanceFromAndUnwrap (string assemblyFile, string typeName, object? []? activationAttributes) + // CreateInstanceFromAndUnwrap(string assemblyFile, string typeName) + // CreateInstanceFromAndUnwrap(string assemblyFile, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) + // CreateInstanceFromAndUnwrap(string assemblyFile, string typeName, object? []? activationAttributes) // case IntrinsicId.AppDomain_CreateInstance: case IntrinsicId.AppDomain_CreateInstanceAndUnwrap: @@ -1510,9 +1511,9 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers // // System.Reflection.Assembly // - // CreateInstance (string typeName) - // CreateInstance (string typeName, bool ignoreCase) - // CreateInstance (string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder? binder, object []? args, CultureInfo? culture, object []? activationAttributes) + // CreateInstance(string typeName) + // CreateInstance(string typeName, bool ignoreCase) + // CreateInstance(string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder? binder, object []? args, CultureInfo? culture, object []? activationAttributes) // case IntrinsicId.Assembly_CreateInstance: // For now always fail since we don't track assemblies (dotnet/linker/issues/1947) diff --git a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/Intrinsics.cs b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/Intrinsics.cs index 7e8bc4bb4b1f50..773ebe28896068 100644 --- a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/Intrinsics.cs +++ b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/Intrinsics.cs @@ -14,20 +14,20 @@ public static IntrinsicId GetIntrinsicIdForMethod(MethodProxy calledMethod) { return calledMethod.Name switch { - // static System.Reflection.IntrospectionExtensions.GetTypeInfo (Type type) + // static System.Reflection.IntrospectionExtensions.GetTypeInfo(Type type) "GetTypeInfo" when calledMethod.IsDeclaredOnType("System.Reflection.IntrospectionExtensions") => IntrinsicId.IntrospectionExtensions_GetTypeInfo, - // System.Reflection.TypeInfo.AsType () + // System.Reflection.TypeInfo.AsType() "AsType" when calledMethod.IsDeclaredOnType("System.Reflection.TypeInfo") => IntrinsicId.TypeInfo_AsType, - // System.Type.GetTypeInfo (Type type) + // System.Type.GetTypeInfo(Type type) "GetTypeFromHandle" when calledMethod.IsDeclaredOnType("System.Type") => IntrinsicId.Type_GetTypeFromHandle, // System.Type.TypeHandle getter "get_TypeHandle" when calledMethod.IsDeclaredOnType("System.Type") => IntrinsicId.Type_get_TypeHandle, - // static System.Reflection.MethodBase.GetMethodFromHandle (RuntimeMethodHandle handle) - // static System.Reflection.MethodBase.GetMethodFromHandle (RuntimeMethodHandle handle, RuntimeTypeHandle declaringType) + // static System.Reflection.MethodBase.GetMethodFromHandle(RuntimeMethodHandle handle) + // static System.Reflection.MethodBase.GetMethodFromHandle(RuntimeMethodHandle handle, RuntimeTypeHandle declaringType) "GetMethodFromHandle" when calledMethod.IsDeclaredOnType("System.Reflection.MethodBase") && calledMethod.HasParameterOfType((ParameterIndex)0, "System.RuntimeMethodHandle") && (calledMethod.HasMetadataParametersCount(1) || calledMethod.HasMetadataParametersCount(2)) @@ -36,192 +36,192 @@ public static IntrinsicId GetIntrinsicIdForMethod(MethodProxy calledMethod) // System.Reflection.MethodBase.MethodHandle getter "get_MethodHandle" when calledMethod.IsDeclaredOnType("System.Reflection.MethodBase") => IntrinsicId.MethodBase_get_MethodHandle, - // static System.Type.MakeGenericType (Type [] typeArguments) + // static System.Type.MakeGenericType(Type[] typeArguments) "MakeGenericType" when calledMethod.IsDeclaredOnType("System.Type") => IntrinsicId.Type_MakeGenericType, - // static System.Reflection.RuntimeReflectionExtensions.GetMethodInfo (this Delegate del) + // static System.Reflection.RuntimeReflectionExtensions.GetMethodInfo(this Delegate del) "GetMethodInfo" when calledMethod.IsDeclaredOnType("System.Reflection.RuntimeReflectionExtensions") && calledMethod.HasParameterOfType((ParameterIndex)0, "System.Delegate") => IntrinsicId.RuntimeReflectionExtensions_GetMethodInfo, - // static System.Reflection.RuntimeReflectionExtensions.GetRuntimeEvent (this Type type, string name) + // static System.Reflection.RuntimeReflectionExtensions.GetRuntimeEvent(this Type type, string name) "GetRuntimeEvent" when calledMethod.IsDeclaredOnType("System.Reflection.RuntimeReflectionExtensions") && calledMethod.HasParameterOfType((ParameterIndex)0, "System.Type") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") => IntrinsicId.RuntimeReflectionExtensions_GetRuntimeEvent, - // static System.Reflection.RuntimeReflectionExtensions.GetRuntimeField (this Type type, string name) + // static System.Reflection.RuntimeReflectionExtensions.GetRuntimeField(this Type type, string name) "GetRuntimeField" when calledMethod.IsDeclaredOnType("System.Reflection.RuntimeReflectionExtensions") && calledMethod.HasParameterOfType((ParameterIndex)0, "System.Type") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.,String") => IntrinsicId.RuntimeReflectionExtensions_GetRuntimeField, - // static System.Reflection.RuntimeReflectionExtensions.GetRuntimeMethod (this Type type, string name, Type[] parameters) + // static System.Reflection.RuntimeReflectionExtensions.GetRuntimeMethod(this Type type, string name, Type[] parameters) "GetRuntimeMethod" when calledMethod.IsDeclaredOnType("System.Reflection.RuntimeReflectionExtensions") && calledMethod.HasParameterOfType((ParameterIndex)0, "System.Type") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") => IntrinsicId.RuntimeReflectionExtensions_GetRuntimeMethod, - // static System.Reflection.RuntimeReflectionExtensions.GetRuntimeProperty (this Type type, string name) + // static System.Reflection.RuntimeReflectionExtensions.GetRuntimeProperty(this Type type, string name) "GetRuntimeProperty" when calledMethod.IsDeclaredOnType("System.Reflection.RuntimeReflectionExtensions") && calledMethod.HasParameterOfType((ParameterIndex)0, "System.Type") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") => IntrinsicId.RuntimeReflectionExtensions_GetRuntimeProperty, - // static System.Linq.Expressions.Expression.Call (Type, String, Type[], Expression[]) + // static System.Linq.Expressions.Expression.Call(Type, String, Type[], Expression[]) "Call" when calledMethod.IsDeclaredOnType("System.Linq.Expressions.Expression") && calledMethod.HasParameterOfType((ParameterIndex)0, "System.Type") && calledMethod.HasMetadataParametersCount(4) => IntrinsicId.Expression_Call, - // static System.Linq.Expressions.Expression.Field (Expression, Type, String) + // static System.Linq.Expressions.Expression.Field(Expression, Type, String) "Field" when calledMethod.IsDeclaredOnType("System.Linq.Expressions.Expression") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.Type") && calledMethod.HasMetadataParametersCount(3) => IntrinsicId.Expression_Field, - // static System.Linq.Expressions.Expression.Property (Expression, Type, String) - // static System.Linq.Expressions.Expression.Property (Expression, MethodInfo) + // static System.Linq.Expressions.Expression.Property(Expression, Type, String) + // static System.Linq.Expressions.Expression.Property(Expression, MethodInfo) "Property" when calledMethod.IsDeclaredOnType("System.Linq.Expressions.Expression") && ((calledMethod.HasParameterOfType((ParameterIndex)1, "System.Type") && calledMethod.HasMetadataParametersCount(3)) || (calledMethod.HasParameterOfType((ParameterIndex)1, "System.Reflection.MethodInfo") && calledMethod.HasMetadataParametersCount(2))) => IntrinsicId.Expression_Property, - // static System.Linq.Expressions.Expression.New (Type) + // static System.Linq.Expressions.Expression.New(Type) "New" when calledMethod.IsDeclaredOnType("System.Linq.Expressions.Expression") && calledMethod.HasParameterOfType((ParameterIndex)0, "System.Type") && calledMethod.HasMetadataParametersCount(1) => IntrinsicId.Expression_New, - // static Array System.Enum.GetValues (Type) + // static Array System.Enum.GetValues(Type) "GetValues" when calledMethod.IsDeclaredOnType("System.Enum") && calledMethod.HasParameterOfType((ParameterIndex)0, "System.Type") && calledMethod.HasMetadataParametersCount(1) => IntrinsicId.Enum_GetValues, - // static int System.Runtime.InteropServices.Marshal.SizeOf (Type) + // static int System.Runtime.InteropServices.Marshal.SizeOf(Type) "SizeOf" when calledMethod.IsDeclaredOnType("System.Runtime.InteropServices.Marshal") && calledMethod.HasParameterOfType((ParameterIndex)0, "System.Type") && calledMethod.HasMetadataParametersCount(1) => IntrinsicId.Marshal_SizeOf, - // static int System.Runtime.InteropServices.Marshal.OffsetOf (Type, string) + // static int System.Runtime.InteropServices.Marshal.OffsetOf(Type, string) "OffsetOf" when calledMethod.IsDeclaredOnType("System.Runtime.InteropServices.Marshal") && calledMethod.HasParameterOfType((ParameterIndex)0, "System.Type") && calledMethod.HasMetadataParametersCount(2) => IntrinsicId.Marshal_OffsetOf, - // static object System.Runtime.InteropServices.Marshal.PtrToStructure (IntPtr, Type) + // static object System.Runtime.InteropServices.Marshal.PtrToStructure(IntPtr, Type) "PtrToStructure" when calledMethod.IsDeclaredOnType("System.Runtime.InteropServices.Marshal") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.Type") && calledMethod.HasMetadataParametersCount(2) => IntrinsicId.Marshal_PtrToStructure, - // static void System.Runtime.InteropServices.Marshal.DestroyStructure (IntPtr, Type) + // static void System.Runtime.InteropServices.Marshal.DestroyStructure(IntPtr, Type) "DestroyStructure" when calledMethod.IsDeclaredOnType("System.Runtime.InteropServices.Marshal") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.Type") && calledMethod.HasMetadataParametersCount(2) => IntrinsicId.Marshal_DestroyStructure, - // static Delegate System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer (IntPtr, Type) + // static Delegate System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(IntPtr, Type) "GetDelegateForFunctionPointer" when calledMethod.IsDeclaredOnType("System.Runtime.InteropServices.Marshal") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.Type") && calledMethod.HasMetadataParametersCount(2) => IntrinsicId.Marshal_GetDelegateForFunctionPointer, - // static System.Type.GetType (string) - // static System.Type.GetType (string, Boolean) - // static System.Type.GetType (string, Boolean, Boolean) - // static System.Type.GetType (string, Func, Func) - // static System.Type.GetType (string, Func, Func, Boolean) - // static System.Type.GetType (string, Func, Func, Boolean, Boolean) + // static System.Type.GetType(string) + // static System.Type.GetType(string, Boolean) + // static System.Type.GetType(string, Boolean, Boolean) + // static System.Type.GetType(string, Func, Func) + // static System.Type.GetType(string, Func, Func, Boolean) + // static System.Type.GetType(string, Func, Func, Boolean, Boolean) "GetType" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasParameterOfType((ParameterIndex)0, "System.String") => IntrinsicId.Type_GetType, - // System.Type.GetConstructor (Type[]) - // System.Type.GetConstructor (BindingFlags, Type[]) - // System.Type.GetConstructor (BindingFlags, Binder, Type[], ParameterModifier []) - // System.Type.GetConstructor (BindingFlags, Binder, CallingConventions, Type[], ParameterModifier []) + // System.Type.GetConstructor Type[]) + // System.Type.GetConstructor BindingFlags, Type[]) + // System.Type.GetConstructor BindingFlags, Binder, Type[], ParameterModifier []) + // System.Type.GetConstructor BindingFlags, Binder, CallingConventions, Type[], ParameterModifier []) "GetConstructor" when calledMethod.IsDeclaredOnType("System.Type") && !calledMethod.IsStatic() => IntrinsicId.Type_GetConstructor, - // System.Type.GetConstructors (BindingFlags) + // System.Type.GetConstructors(BindingFlags) "GetConstructors" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.Reflection.BindingFlags") && calledMethod.HasMetadataParametersCount(1) && !calledMethod.IsStatic() => IntrinsicId.Type_GetConstructors__BindingFlags, - // System.Type.GetMethod (string) - // System.Type.GetMethod (string, BindingFlags) - // System.Type.GetMethod (string, Type[]) - // System.Type.GetMethod (string, Type[], ParameterModifier[]) - // System.Type.GetMethod (string, BindingFlags, Type[]) - // System.Type.GetMethod (string, BindingFlags, Binder, Type[], ParameterModifier[]) - // System.Type.GetMethod (string, BindingFlags, Binder, CallingConventions, Type[], ParameterModifier[]) - // System.Type.GetMethod (string, int, Type[]) - // System.Type.GetMethod (string, int, Type[], ParameterModifier[]?) - // System.Type.GetMethod (string, int, BindingFlags, Binder?, Type[], ParameterModifier[]?) - // System.Type.GetMethod (string, int, BindingFlags, Binder?, CallingConventions, Type[], ParameterModifier[]?) + // System.Type.GetMethod(string) + // System.Type.GetMethod(string, BindingFlags) + // System.Type.GetMethod(string, Type[]) + // System.Type.GetMethod(string, Type[], ParameterModifier[]) + // System.Type.GetMethod(string, BindingFlags, Type[]) + // System.Type.GetMethod(string, BindingFlags, Binder, Type[], ParameterModifier[]) + // System.Type.GetMethod(string, BindingFlags, Binder, CallingConventions, Type[], ParameterModifier[]) + // System.Type.GetMethod(string, int, Type[]) + // System.Type.GetMethod(string, int, Type[], ParameterModifier[]?) + // System.Type.GetMethod(string, int, BindingFlags, Binder?, Type[], ParameterModifier[]?) + // System.Type.GetMethod(string, int, BindingFlags, Binder?, CallingConventions, Type[], ParameterModifier[]?) "GetMethod" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasImplicitThis() && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") => IntrinsicId.Type_GetMethod, - // System.Type.GetMethods (BindingFlags) + // System.Type.GetMethods(BindingFlags) "GetMethods" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasImplicitThis() && calledMethod.HasMetadataParametersCount(1) && calledMethod.HasParameterOfType((ParameterIndex)1, "System.Reflection.BindingFlags") => IntrinsicId.Type_GetMethods__BindingFlags, - // System.Type.GetField (string) - // System.Type.GetField (string, BindingFlags) + // System.Type.GetField(string) + // System.Type.GetField(string, BindingFlags) "GetField" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasImplicitThis() && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") => IntrinsicId.Type_GetField, - // System.Type.GetFields (BindingFlags) + // System.Type.GetFields(BindingFlags) "GetFields" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasImplicitThis() && calledMethod.HasMetadataParametersCount(1) && calledMethod.HasParameterOfType((ParameterIndex)1, "System.Reflection.BindingFlags") => IntrinsicId.Type_GetFields__BindingFlags, - // System.Type.GetEvent (string) - // System.Type.GetEvent (string, BindingFlags) + // System.Type.GetEvent(string) + // System.Type.GetEvent(string, BindingFlags) "GetEvent" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasImplicitThis() && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") => IntrinsicId.Type_GetEvent, - // System.Type.GetEvents (BindingFlags) + // System.Type.GetEvents(BindingFlags) "GetEvents" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasImplicitThis() && calledMethod.HasMetadataParametersCount(1) && calledMethod.HasParameterOfType((ParameterIndex)1, "System.Reflection.BindingFlags") => IntrinsicId.Type_GetEvents__BindingFlags, - // System.Type.GetNestedType (string) - // System.Type.GetNestedType (string, BindingFlags) + // System.Type.GetNestedType(string) + // System.Type.GetNestedType(string, BindingFlags) "GetNestedType" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasImplicitThis() && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") => IntrinsicId.Type_GetNestedType, - // System.Type.GetNestedTypes (BindingFlags) + // System.Type.GetNestedTypes(BindingFlags) "GetNestedTypes" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasImplicitThis() && calledMethod.HasMetadataParametersCount(1) && calledMethod.HasParameterOfType((ParameterIndex)1, "System.Reflection.BindingFlags") => IntrinsicId.Type_GetNestedTypes__BindingFlags, - // System.Type.GetMember (String) - // System.Type.GetMember (String, BindingFlags) - // System.Type.GetMember (String, MemberTypes, BindingFlags) + // System.Type.GetMember(string) + // System.Type.GetMember(string, BindingFlags) + // System.Type.GetMember(string, MemberTypes, BindingFlags) "GetMember" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasImplicitThis() && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") @@ -230,15 +230,15 @@ public static IntrinsicId GetIntrinsicIdForMethod(MethodProxy calledMethod) (calledMethod.HasMetadataParametersCount(3) && calledMethod.HasParameterOfType((ParameterIndex)3, "System.Reflection.BindingFlags"))) => IntrinsicId.Type_GetMember, - // System.Type.GetMembers (BindingFlags) + // System.Type.GetMembers(BindingFlags) "GetMembers" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasImplicitThis() && calledMethod.HasMetadataParametersCount(1) && calledMethod.HasParameterOfType((ParameterIndex)1, "System.Reflection.BindingFlags") => IntrinsicId.Type_GetMembers__BindingFlags, - // System.Type.GetInterface (string) - // System.Type.GetInterface (string, bool) + // System.Type.GetInterface(string) + // System.Type.GetInterface(string, bool) "GetInterface" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasImplicitThis() && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") @@ -269,26 +269,26 @@ public static IntrinsicId GetIntrinsicIdForMethod(MethodProxy calledMethod) && !calledMethod.HasMetadataParameters() => IntrinsicId.Type_get_BaseType, - // System.Type.GetProperty (string) - // System.Type.GetProperty (string, BindingFlags) - // System.Type.GetProperty (string, Type) - // System.Type.GetProperty (string, Type[]) - // System.Type.GetProperty (string, Type, Type[]) - // System.Type.GetProperty (string, Type, Type[], ParameterModifier[]) - // System.Type.GetProperty (string, BindingFlags, Binder, Type, Type[], ParameterModifier[]) + // System.Type.GetProperty(string) + // System.Type.GetProperty(string, BindingFlags) + // System.Type.GetProperty(string, Type) + // System.Type.GetProperty(string, Type[]) + // System.Type.GetProperty(string, Type, Type[]) + // System.Type.GetProperty(string, Type, Type[], ParameterModifier[]) + // System.Type.GetProperty(string, BindingFlags, Binder, Type, Type[], ParameterModifier[]) "GetProperty" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasImplicitThis() && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") => IntrinsicId.Type_GetProperty, - // System.Type.GetProperties (BindingFlags) + // System.Type.GetProperties(BindingFlags) "GetProperties" when calledMethod.IsDeclaredOnType("System.Type") && calledMethod.HasImplicitThis() && calledMethod.HasParameterOfType((ParameterIndex)1, "System.Reflection.BindingFlags") && calledMethod.HasMetadataParametersCount(1) => IntrinsicId.Type_GetProperties__BindingFlags, - // static System.Object.GetType () + // static System.Object.GetType() "GetType" when calledMethod.IsDeclaredOnType("System.Object") => IntrinsicId.Object_GetType, @@ -299,76 +299,76 @@ public static IntrinsicId GetIntrinsicIdForMethod(MethodProxy calledMethod) "Empty" when calledMethod.IsDeclaredOnType("System.Array") => IntrinsicId.Array_Empty, - // static System.Array.CreateInstance (System.Type type, int length) + // static System.Array.CreateInstance(System.Type type, int length) "CreateInstance" when calledMethod.IsDeclaredOnType("System.Array") && calledMethod.HasMetadataParametersCount(2) && calledMethod.HasParameterOfType((ParameterIndex)1, "System.Int32") => IntrinsicId.Array_CreateInstance, - // static System.Activator.CreateInstance (System.Type type) - // static System.Activator.CreateInstance (System.Type type, bool nonPublic) - // static System.Activator.CreateInstance (System.Type type, params object?[]? args) - // static System.Activator.CreateInstance (System.Type type, object?[]? args, object?[]? activationAttributes) - // static System.Activator.CreateInstance (System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture) - // static System.Activator.CreateInstance (System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture, object?[]? activationAttributes) { throw null; } + // static System.Activator.CreateInstance(System.Type type) + // static System.Activator.CreateInstance(System.Type type, bool nonPublic) + // static System.Activator.CreateInstance(System.Type type, params object?[]? args) + // static System.Activator.CreateInstance(System.Type type, object?[]? args, object?[]? activationAttributes) + // static System.Activator.CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture) + // static System.Activator.CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture, object?[]? activationAttributes) { throw null; } "CreateInstance" when calledMethod.IsDeclaredOnType("System.Activator") && !calledMethod.HasGenericParameters() && calledMethod.HasParameterOfType((ParameterIndex)0, "System.Type") => IntrinsicId.Activator_CreateInstance__Type, - // static System.Activator.CreateInstance (string assemblyName, string typeName) - // static System.Activator.CreateInstance (string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture, object?[]? activationAttributes) - // static System.Activator.CreateInstance (string assemblyName, string typeName, object?[]? activationAttributes) + // static System.Activator.CreateInstance(string assemblyName, string typeName) + // static System.Activator.CreateInstance(string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture, object?[]? activationAttributes) + // static System.Activator.CreateInstance(string assemblyName, string typeName, object?[]? activationAttributes) "CreateInstance" when calledMethod.IsDeclaredOnType("System.Activator") && !calledMethod.HasGenericParameters() && calledMethod.HasParameterOfType((ParameterIndex)0, "System.String") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") => IntrinsicId.Activator_CreateInstance__AssemblyName_TypeName, - // static System.Activator.CreateInstanceFrom (string assemblyFile, string typeName) - // static System.Activator.CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) - // static System.Activator.CreateInstanceFrom (string assemblyFile, string typeName, object? []? activationAttributes) + // static System.Activator.CreateInstanceFrom(string assemblyFile, string typeName) + // static System.Activator.CreateInstanceFrom(string assemblyFile, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) + // static System.Activator.CreateInstanceFrom(string assemblyFile, string typeName, object? []? activationAttributes) "CreateInstanceFrom" when calledMethod.IsDeclaredOnType("System.Activator") && !calledMethod.HasGenericParameters() && calledMethod.HasParameterOfType((ParameterIndex)0, "System.String") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") => IntrinsicId.Activator_CreateInstanceFrom, - // System.AppDomain.CreateInstance (string assemblyName, string typeName) - // System.AppDomain.CreateInstance (string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) - // System.AppDomain.CreateInstance (string assemblyName, string typeName, object? []? activationAttributes) + // System.AppDomain.CreateInstance(string assemblyName, string typeName) + // System.AppDomain.CreateInstance(string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) + // System.AppDomain.CreateInstance(string assemblyName, string typeName, object? []? activationAttributes) "CreateInstance" when calledMethod.IsDeclaredOnType("System.AppDomain") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") && calledMethod.HasParameterOfType((ParameterIndex)2, "System.String") => IntrinsicId.AppDomain_CreateInstance, - // System.AppDomain.CreateInstanceAndUnwrap (string assemblyName, string typeName) - // System.AppDomain.CreateInstanceAndUnwrap (string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) - // System.AppDomain.CreateInstanceAndUnwrap (string assemblyName, string typeName, object? []? activationAttributes) + // System.AppDomain.CreateInstanceAndUnwrap(string assemblyName, string typeName) + // System.AppDomain.CreateInstanceAndUnwrap(string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) + // System.AppDomain.CreateInstanceAndUnwrap(string assemblyName, string typeName, object? []? activationAttributes) "CreateInstanceAndUnwrap" when calledMethod.IsDeclaredOnType("System.AppDomain") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") && calledMethod.HasParameterOfType((ParameterIndex)2, "System.String") => IntrinsicId.AppDomain_CreateInstanceAndUnwrap, - // System.AppDomain.CreateInstanceFrom (string assemblyFile, string typeName) - // System.AppDomain.CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) - // System.AppDomain.CreateInstanceFrom (string assemblyFile, string typeName, object? []? activationAttributes) + // System.AppDomain.CreateInstanceFrom(string assemblyFile, string typeName) + // System.AppDomain.CreateInstanceFrom(string assemblyFile, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) + // System.AppDomain.CreateInstanceFrom(string assemblyFile, string typeName, object? []? activationAttributes) "CreateInstanceFrom" when calledMethod.IsDeclaredOnType("System.AppDomain") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") && calledMethod.HasParameterOfType((ParameterIndex)2, "System.String") => IntrinsicId.AppDomain_CreateInstanceFrom, - // System.AppDomain.CreateInstanceFromAndUnwrap (string assemblyFile, string typeName) - // System.AppDomain.CreateInstanceFromAndUnwrap (string assemblyFile, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) - // System.AppDomain.CreateInstanceFromAndUnwrap (string assemblyFile, string typeName, object? []? activationAttributes) + // System.AppDomain.CreateInstanceFromAndUnwrap(string assemblyFile, string typeName) + // System.AppDomain.CreateInstanceFromAndUnwrap(string assemblyFile, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object? []? args, System.Globalization.CultureInfo? culture, object? []? activationAttributes) + // System.AppDomain.CreateInstanceFromAndUnwrap(string assemblyFile, string typeName, object? []? activationAttributes) "CreateInstanceFromAndUnwrap" when calledMethod.IsDeclaredOnType("System.AppDomain") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") && calledMethod.HasParameterOfType((ParameterIndex)2, "System.String") => IntrinsicId.AppDomain_CreateInstanceFromAndUnwrap, - // System.Reflection.Assembly.CreateInstance (string typeName) - // System.Reflection.Assembly.CreateInstance (string typeName, bool ignoreCase) - // System.Reflection.Assembly.CreateInstance (string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder? binder, object []? args, CultureInfo? culture, object []? activationAttributes) + // System.Reflection.Assembly.CreateInstance(string typeName) + // System.Reflection.Assembly.CreateInstance(string typeName, bool ignoreCase) + // System.Reflection.Assembly.CreateInstance(string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder? binder, object []? args, CultureInfo? culture, object []? activationAttributes) "CreateInstance" when calledMethod.IsDeclaredOnType("System.Reflection.Assembly") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") => IntrinsicId.Assembly_CreateInstance, @@ -377,13 +377,13 @@ public static IntrinsicId GetIntrinsicIdForMethod(MethodProxy calledMethod) "get_Location" when calledMethod.IsDeclaredOnType("System.Reflection.Assembly") => IntrinsicId.Assembly_get_Location, - // System.Reflection.Assembly.GetFile (string) + // System.Reflection.Assembly.GetFile(string) "GetFile" when calledMethod.IsDeclaredOnType("System.Reflection.Assembly") && calledMethod.HasParameterOfType((ParameterIndex)1, "System.String") => IntrinsicId.Assembly_GetFile, - // System.Reflection.Assembly.GetFiles () - // System.Reflection.Assembly.GetFiles (bool) + // System.Reflection.Assembly.GetFiles() + // System.Reflection.Assembly.GetFiles(bool) "GetFiles" when calledMethod.IsDeclaredOnType("System.Reflection.Assembly") && (calledMethod.HasMetadataParametersCount(0) || calledMethod.HasParameterOfType((ParameterIndex)1, "System.Boolean")) => IntrinsicId.Assembly_GetFiles, @@ -396,12 +396,12 @@ public static IntrinsicId GetIntrinsicIdForMethod(MethodProxy calledMethod) "get_EscapedCodeBase" when calledMethod.IsDeclaredOnType("System.Reflection.AssemblyName") => IntrinsicId.AssemblyName_get_EscapedCodeBase, - // System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (RuntimeTypeHandle type) + // System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(RuntimeTypeHandle type) "RunClassConstructor" when calledMethod.IsDeclaredOnType("System.Runtime.CompilerServices.RuntimeHelpers") && calledMethod.HasParameterOfType((ParameterIndex)0, "System.RuntimeTypeHandle") => IntrinsicId.RuntimeHelpers_RunClassConstructor, - // System.Reflection.MethodInfo.MakeGenericMethod (Type[] typeArguments) + // System.Reflection.MethodInfo.MakeGenericMethod(Type[] typeArguments) "MakeGenericMethod" when calledMethod.IsDeclaredOnType("System.Reflection.MethodInfo") && calledMethod.HasImplicitThis() && calledMethod.HasMetadataParametersCount(1) @@ -419,16 +419,16 @@ public static IntrinsicId GetIntrinsicIdForMethod(MethodProxy calledMethod) && calledMethod.HasMetadataParametersCount(0) => IntrinsicId.Delegate_get_Method, - // static System.Runtime.InteropServices.TypeMapping.GetOrCreateExternalTypeMapping () + // static System.Runtime.InteropServices.TypeMapping.GetOrCreateExternalTypeMapping() "GetOrCreateExternalTypeMapping" when calledMethod.IsDeclaredOnType("System.Runtime.InteropServices.TypeMapping") && calledMethod.IsStatic() - && calledMethod.HasGenericParametersCount(1) + && calledMethod.HasGenericArgumentsCount(1) => IntrinsicId.TypeMapping_GetOrCreateExternalTypeMapping, - // static System.Runtime.InteropServices.TypeMapping.GetOrCreateProxyTypeMapping () + // static System.Runtime.InteropServices.TypeMapping.GetOrCreateProxyTypeMapping() "GetOrCreateProxyTypeMapping" when calledMethod.IsDeclaredOnType("System.Runtime.InteropServices.TypeMapping") && calledMethod.IsStatic() - && calledMethod.HasGenericParametersCount(1) + && calledMethod.HasGenericArgumentsCount(1) => IntrinsicId.TypeMapping_GetOrCreateProxyTypeMapping, _ => IntrinsicId.None, diff --git a/src/tools/illink/src/ILLink.Shared/TypeSystemProxy/MethodProxy.cs b/src/tools/illink/src/ILLink.Shared/TypeSystemProxy/MethodProxy.cs index 11732846da0487..f68ec2740eaaa6 100644 --- a/src/tools/illink/src/ILLink.Shared/TypeSystemProxy/MethodProxy.cs +++ b/src/tools/illink/src/ILLink.Shared/TypeSystemProxy/MethodProxy.cs @@ -54,8 +54,8 @@ namespace ILLink.Shared.TypeSystemProxy internal bool HasParameterOfType(ParameterIndex parameterIndex, string fullTypeName) => (int)parameterIndex < GetParametersCount() && GetParameter(parameterIndex).IsTypeOf(fullTypeName); internal partial bool HasGenericParameters(); - internal partial bool HasGenericParametersCount(int genericParameterCount); internal partial ImmutableArray GetGenericParameters(); + internal partial bool HasGenericArgumentsCount(int genericArgumentCount); internal partial bool IsConstructor(); internal partial bool IsStatic(); internal partial bool HasImplicitThis(); diff --git a/src/tools/illink/src/ILLink.Tasks/build/Microsoft.NET.ILLink.targets b/src/tools/illink/src/ILLink.Tasks/build/Microsoft.NET.ILLink.targets index eceaebf36f48a0..655cb28bb1c529 100644 --- a/src/tools/illink/src/ILLink.Tasks/build/Microsoft.NET.ILLink.targets +++ b/src/tools/illink/src/ILLink.Tasks/build/Microsoft.NET.ILLink.targets @@ -25,6 +25,10 @@ Copyright (c) .NET Foundation. All rights reserved. <_Parameter1>IsTrimmable <_Parameter2>True + + <_Parameter1>IsAotCompatible + <_Parameter2>True + <_UseManagedNtlm Condition="'$(_UseManagedNtlm)' == '' and $(RuntimeIdentifier.StartsWith('linux-bionic'))">true diff --git a/src/tools/illink/src/analyzer/LinkerAnalyzerCore/DependencyGraph.cs b/src/tools/illink/src/analyzer/LinkerAnalyzerCore/DependencyGraph.cs index 539e2cbf8c25dd..4bb024d5d909d1 100644 --- a/src/tools/illink/src/analyzer/LinkerAnalyzerCore/DependencyGraph.cs +++ b/src/tools/illink/src/analyzer/LinkerAnalyzerCore/DependencyGraph.cs @@ -69,12 +69,12 @@ void Load(FileStream fileStream) switch (reader.NodeType) { case XmlNodeType.Element: - // Console.WriteLine (reader.Name); + // Console.WriteLine(reader.Name); if (reader.Name == "edge" && reader.IsStartElement()) { string b = reader.GetAttribute("b"); string e = reader.GetAttribute("e"); - //Console.WriteLine ("edge value " + b + " --> " + e); + //Console.WriteLine("edge value " + b + " --> " + e); if (e != b) { @@ -85,13 +85,13 @@ void Load(FileStream fileStream) if (!end.parentIndexes.Contains(begin.index)) { end.parentIndexes.Add(begin.index); - //Console.WriteLine (" end parent index: {0}", end.parentIndexes); + //Console.WriteLine(" end parent index: {0}", end.parentIndexes); } } } break; default: - //Console.WriteLine ("node: " + reader.NodeType); + //Console.WriteLine("node: " + reader.NodeType); break; } } @@ -115,7 +115,7 @@ public VertexData Vertex(string vertexName, bool create = false) counts[prefix] = count + 1; else counts[prefix] = 1; - //Console.WriteLine ("prefix " + prefix + " count " + counts[prefix]); + //Console.WriteLine("prefix " + prefix + " count " + counts[prefix]); if (prefix == "TypeDef") { Types.Add(vertex); diff --git a/src/tools/illink/src/linker/CompatibilitySuppressions.xml b/src/tools/illink/src/linker/CompatibilitySuppressions.xml index 58644dc9d4a19e..6740a9ba35ac59 100644 --- a/src/tools/illink/src/linker/CompatibilitySuppressions.xml +++ b/src/tools/illink/src/linker/CompatibilitySuppressions.xml @@ -705,6 +705,10 @@ CP0002 M:Mono.Linker.AnnotationStore.GetDefaultInterfaceImplementations(Mono.Cecil.MethodDefinition) + + CP0002 + M:Mono.Linker.AnnotationStore.GetEntryPointAssembly + CP0002 M:Mono.Linker.AnnotationStore.GetLinkerAttributes``1(Mono.Cecil.IMemberDefinition) @@ -817,6 +821,10 @@ CP0002 M:Mono.Linker.AnnotationStore.SetAppliedPreserve(Mono.Cecil.TypeDefinition,Mono.Linker.TypePreserve) + + CP0002 + M:Mono.Linker.AnnotationStore.SetEntryPointAssembly(Mono.Cecil.AssemblyDefinition) + CP0002 M:Mono.Linker.AnnotationStore.SetMembersPreserve(Mono.Cecil.ExportedType,Mono.Linker.TypePreserveMembers) @@ -1521,6 +1529,18 @@ CP0002 M:Mono.Linker.Steps.SubStepsDispatcher.Process(Mono.Linker.LinkContext) + + CP0002 + M:Mono.Linker.LinkContext.get_DisableGeneratedCodeHeuristics + ref/net10.0/illink.dll + lib/net10.0/illink.dll + + + CP0002 + M:Mono.Linker.LinkContext.set_DisableGeneratedCodeHeuristics(System.Boolean) + ref/net10.0/illink.dll + lib/net10.0/illink.dll + CP0008 T:Mono.Linker.LinkContext diff --git a/src/tools/illink/src/linker/Linker.Dataflow/CompilerGeneratedState.cs b/src/tools/illink/src/linker/Linker.Dataflow/CompilerGeneratedState.cs index 56133bce64f42d..47d5c5c075a2b0 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/CompilerGeneratedState.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/CompilerGeneratedState.cs @@ -22,8 +22,8 @@ public class CompilerGeneratedState readonly record struct TypeArgumentInfo( /// The method which calls the ctor for the given type MethodDefinition CreatingMethod, - /// Attributes for the type, pulled from the creators type arguments - IReadOnlyList? OriginalAttributes); + /// Generic parameters of the creator used as type arguments for the type + IList? OriginalAttributes); readonly Dictionary _compilerGeneratedMethodToUserCodeMethod; @@ -180,8 +180,8 @@ void ProcessMethod(MethodDefinition method) // Find calls to state machine constructors that occur outside the type if (referencedMethod.IsConstructor && referencedMethod.DeclaringType is var generatedType && - // Don't consider calls in the same type, like inside a static constructor - method.DeclaringType != generatedType && + // Don't consider calls in the same/nested type, like inside a static constructor + !IsSameOrNestedType(method.DeclaringType, generatedType) && CompilerGeneratedNames.IsLambdaDisplayClass(generatedType.Name)) { // fill in null for now, attribute providers will be filled in later @@ -219,8 +219,8 @@ referencedMethod.DeclaringType is var generatedType && continue; if (field.DeclaringType is var generatedType && - // Don't consider field accesses in the same type, like inside a static constructor - method.DeclaringType != generatedType && + // Don't consider field accesses in the same/nested type, like inside a static constructor + !IsSameOrNestedType(method.DeclaringType, generatedType) && CompilerGeneratedNames.IsLambdaDisplayClass(generatedType.Name)) { if (!generatedTypeToTypeArgs.TryAdd(generatedType, new TypeArgumentInfo(method, null))) @@ -253,6 +253,19 @@ referencedMethod.DeclaringType is var generatedType && // Fill in null for argument providers now, the real providers will be filled in later generatedTypeToTypeArgs[stateMachineType] = new TypeArgumentInfo(method, null); } + + static bool IsSameOrNestedType(TypeDefinition type, TypeDefinition potentialOuterType) + { + do + { + if (type == potentialOuterType) + return true; + + type = type.DeclaringType; + } while (type != null); + + return false; + } } // Look for state machine methods, and methods which call local functions. @@ -354,15 +367,15 @@ referencedMethod.DeclaringType is var generatedType && /// Attempts to reverse the process of the compiler's alpha renaming. So if the original code was /// something like this: /// - /// void M<T> () { - /// Action a = () => { Console.WriteLine (typeof (T)); }; + /// void M<T>() { + /// Action a = () => { Console.WriteLine(typeof(T)); }; /// } /// /// The compiler will generate a nested class like this: /// /// class <>c__DisplayClass0<T> { - /// public void <M>b__0 () { - /// Console.WriteLine (typeof (T)); + /// public void <M>b__0() { + /// Console.WriteLine(typeof(T)); /// } /// } /// @@ -386,7 +399,7 @@ static void MapGeneratedTypeTypeParameters( var method = typeInfo.CreatingMethod; if (method.Body is { } body) { - var typeArgs = new ICustomAttributeProvider[generatedType.GenericParameters.Count]; + var typeArgs = new GenericParameter[generatedType.GenericParameters.Count]; var typeRef = ScanForInit(generatedType, body, context); if (typeRef is null) { @@ -397,7 +410,7 @@ static void MapGeneratedTypeTypeParameters( { var typeArg = typeRef.GenericArguments[i]; // Start with the existing parameters, in case we can't find the mapped one - ICustomAttributeProvider userAttrs = generatedType.GenericParameters[i]; + GenericParameter userAttrs = generatedType.GenericParameters[i]; // The type parameters of the state machine types are alpha renames of the // the method parameters, so the type ref should always be a GenericParameter. However, // in the case of nesting, there may be multiple renames, so if the parameter is a method @@ -518,10 +531,19 @@ public bool TryGetCompilerGeneratedCalleesForUserMethod(MethodDefinition method, /// Gets the attributes on the "original" method of a generated type, i.e. the /// attributes on the corresponding type parameters from the owning method. /// - public IReadOnlyList? GetGeneratedTypeAttributes(TypeDefinition generatedType) + public IList? GetGeneratedTypeAttributes(TypeDefinition generatedType) { Debug.Assert(CompilerGeneratedNames.IsStateMachineOrDisplayClass(generatedType.Name)); + // Avoid the heuristics for .NET10+, where DynamicallyAccessedMembers flows to generated code + // because it is annotated with CompilerLoweringPreserveAttribute. + if (_context.DisableGeneratedCodeHeuristics && generatedType.Module.Assembly.GetTargetFrameworkVersion() >= new Version(10, 0)) + { + // Still run the logic for coverage to help us find bugs, but don't use the result. + GetCompilerGeneratedStateForType(generatedType); + return null; + } + var typeToCache = GetCompilerGeneratedStateForType(generatedType); if (typeToCache is null) return null; diff --git a/src/tools/illink/src/linker/Linker.Dataflow/FlowAnnotations.cs b/src/tools/illink/src/linker/Linker.Dataflow/FlowAnnotations.cs index 4c3edaaeacf991..92347f0b8c7392 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/FlowAnnotations.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/FlowAnnotations.cs @@ -446,10 +446,10 @@ TypeAnnotations BuildTypeAnnotations(TypeDefinition type) DynamicallyAccessedMemberTypes[]? typeGenericParameterAnnotations = null; if (type.HasGenericParameters) { - var attrs = GetGeneratedTypeAttributes(type); + var attrs = GetGeneratedTypeAttributes(type) ?? type.GenericParameters; for (int genericParameterIndex = 0; genericParameterIndex < type.GenericParameters.Count; genericParameterIndex++) { - var provider = attrs?[genericParameterIndex] ?? type.GenericParameters[genericParameterIndex]; + var provider = attrs[genericParameterIndex]; var annotation = GetMemberTypesForDynamicallyAccessedMembersAttribute(type, providerIfNotMember: provider); if (annotation != DynamicallyAccessedMemberTypes.None) { @@ -462,7 +462,7 @@ TypeAnnotations BuildTypeAnnotations(TypeDefinition type) return new TypeAnnotations(type, typeAnnotation, annotatedMethods.ToArray(), annotatedFields.ToArray(), typeGenericParameterAnnotations); } - private IReadOnlyList? GetGeneratedTypeAttributes(TypeDefinition typeDef) + private IList? GetGeneratedTypeAttributes(TypeDefinition typeDef) { if (!CompilerGeneratedNames.IsStateMachineOrDisplayClass(typeDef.Name)) { @@ -597,8 +597,8 @@ void ValidateMethodParametersHaveNoAnnotations(DynamicallyAccessedMemberTypes[] var annotation = parameterAnnotations[parameterIndex]; if (annotation != DynamicallyAccessedMemberTypes.None) LogValidationWarning( - ov.Override.GetParameter((ParameterIndex)parameterIndex).GetCustomAttributeProvider()!, - ov.Base.GetParameter((ParameterIndex)parameterIndex).GetCustomAttributeProvider()!, + ov.Override.GetParameter((ParameterIndex)parameterIndex).GetCustomAttributeProvider(), + ov.Base.GetParameter((ParameterIndex)parameterIndex).GetCustomAttributeProvider(), ov); } } diff --git a/src/tools/illink/src/linker/Linker.Dataflow/HandleCallAction.cs b/src/tools/illink/src/linker/Linker.Dataflow/HandleCallAction.cs index c65eb681fb289a..0b283623e047cc 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/HandleCallAction.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/HandleCallAction.cs @@ -195,6 +195,27 @@ private partial bool TryHandleIntrinsic( } break; + case IntrinsicId.TypeMapping_GetOrCreateExternalTypeMapping: + case IntrinsicId.TypeMapping_GetOrCreateProxyTypeMapping: + { + GenericInstanceMethod method = ((GenericInstanceMethod)calledMethod.Method); + if (method.GenericArguments[0].ContainsGenericParameter) + { + _diagnosticContext.AddDiagnostic(DiagnosticId.TypeMapGroupTypeCannotBeStaticallyDetermined, method.GenericArguments[0].FullName); + return true; + } + + if (intrinsicId == IntrinsicId.TypeMapping_GetOrCreateExternalTypeMapping) + { + _markStep.TypeMapHandler.ProcessExternalTypeMapGroupSeen(_callingMethodDefinition, method.GenericArguments[0]); + } + else + { + _markStep.TypeMapHandler.ProcessProxyTypeMapGroupSeen(_callingMethodDefinition, method.GenericArguments[0]); + } + } + break; + // Note about Activator.CreateInstance // There are 2 interesting cases: // - The generic argument for T is either specific type or annotated - in that case generic instantiation will handle this diff --git a/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs b/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs index 0ac227d3ea4c5c..e420eca03d4358 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs @@ -54,15 +54,15 @@ protected MethodBodyScanner(LinkContext context) this.InterproceduralStateLattice = new InterproceduralStateLattice(default, default, context); } - protected virtual void WarnAboutInvalidILInMethod(MethodBody method, int ilOffset) + protected virtual void WarnAboutInvalidILInMethod(MethodIL methodIL, int ilOffset) { } - private void CheckForInvalidStack(Stack stack, int depthRequired, MethodBody method, int ilOffset) + private void CheckForInvalidStack(Stack stack, int depthRequired, MethodIL methodIL, int ilOffset) { if (stack.Count < depthRequired) { - WarnAboutInvalidILInMethod(method, ilOffset); + WarnAboutInvalidILInMethod(methodIL, ilOffset); while (stack.Count < depthRequired) stack.Push(new StackSlot()); // Push dummy values to avoid crashes. // Analysis of this method will be incorrect. @@ -74,19 +74,19 @@ private static void PushUnknown(Stack stack) stack.Push(new StackSlot()); } - private void PushUnknownAndWarnAboutInvalidIL(Stack stack, MethodBody methodBody, int offset) + private void PushUnknownAndWarnAboutInvalidIL(Stack stack, MethodIL methodIL, int offset) { - WarnAboutInvalidILInMethod(methodBody, offset); + WarnAboutInvalidILInMethod(methodIL, offset); PushUnknown(stack); } - private StackSlot PopUnknown(Stack stack, int count, MethodBody method, int ilOffset) + private StackSlot PopUnknown(Stack stack, int count, MethodIL methodIL, int ilOffset) { if (count < 1) throw new InvalidOperationException(); StackSlot topOfStack = default; - CheckForInvalidStack(stack, count, method, ilOffset); + CheckForInvalidStack(stack, count, methodIL, ilOffset); for (int i = 0; i < count; ++i) { @@ -190,7 +190,7 @@ public int MoveNext(Instruction op) } [Conditional("DEBUG")] - static void ValidateNoReferenceToReference(LocalVariableStore locals, MethodDefinition method, int ilOffset) + static void ValidateNoReferenceToReference(LocalVariableStore locals, MethodIL method, int ilOffset) { foreach (var keyValuePair in locals) { @@ -202,9 +202,9 @@ static void ValidateNoReferenceToReference(LocalVariableStore locals, MethodDefi { string displayName = $"local variable V_{localReference.LocalDefinition.Index}"; throw new LinkerFatalErrorException(MessageContainer.CreateErrorMessage( - $"""In method {method.FullName}, local variable V_{localVariable.Index} references {displayName} of type {localReference.ReferencedType.GetDisplayName()} which is a reference. Dataflow tracking has failed.""", + $"""In method {method.Method.FullName}, local variable V_{localVariable.Index} references {displayName} of type {localReference.ReferencedType.GetDisplayName()} which is a reference. Dataflow tracking has failed.""", (int)DiagnosticId.LinkerUnexpectedError, - origin: new MessageOrigin(method, ilOffset))); + origin: new MessageOrigin(method.Method, ilOffset))); } } } @@ -276,9 +276,9 @@ public virtual void InterproceduralScan(MethodIL startingMethodIL) var calleeMethods = compilerGeneratedCallees.OfType(); // https://github.com/dotnet/linker/issues/2845 // Disabled asserts due to a bug - // Debug.Assert (interproceduralState.Count == 1 + calleeMethods.Count ()); + // Debug.Assert(interproceduralState.Count == 1 + calleeMethods.Count()); // foreach (var method in calleeMethods) - // Debug.Assert (interproceduralState.Any (kvp => kvp.Key.Method == method)); + // Debug.Assert(interproceduralState.Any(kvp => kvp.Key.Method == method)); } else { @@ -357,7 +357,7 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro case Code.Shr: case Code.Shr_Un: case Code.Ceq: - PopUnknown(currentStack, 2, methodBody, operation.Offset); + PopUnknown(currentStack, 2, methodIL, operation.Offset); PushUnknown(currentStack); break; @@ -445,8 +445,8 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro case Code.Ldloc_S: case Code.Ldloca: case Code.Ldloca_S: - ScanLdloc(operation, currentStack, methodIL, locals); - ValidateNoReferenceToReference(locals, methodBody.Method, operation.Offset); + ScanLdloc(methodIL, operation, currentStack, locals); + ValidateNoReferenceToReference(locals, methodIL, operation.Offset); break; case Code.Ldstr: @@ -516,7 +516,7 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro case Code.Box: case Code.Neg: case Code.Not: - PopUnknown(currentStack, 1, methodBody, operation.Offset); + PopUnknown(currentStack, 1, methodIL, operation.Offset); PushUnknown(currentStack); break; @@ -531,12 +531,12 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro case Code.Ldsfld: case Code.Ldflda: case Code.Ldsflda: - ScanLdfld(operation, currentStack, methodBody, ref interproceduralState); + ScanLdfld(methodIL, operation, currentStack, ref interproceduralState); break; case Code.Newarr: { - StackSlot count = PopUnknown(currentStack, 1, methodBody, operation.Offset); + StackSlot count = PopUnknown(currentStack, 1, methodIL, operation.Offset); currentStack.Push(new StackSlot(ArrayValue.Create(count.Value, (TypeReference)operation.Operand))); } break; @@ -550,7 +550,7 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro case Code.Stelem_R8: case Code.Stelem_Any: case Code.Stelem_Ref: - ScanStelem(operation, currentStack, methodBody, curBasicBlock); + ScanStelem(operation, currentStack, methodIL, curBasicBlock); break; case Code.Ldelem_I: @@ -566,21 +566,21 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro case Code.Ldelem_Any: case Code.Ldelem_Ref: case Code.Ldelema: - ScanLdelem(operation, currentStack, methodBody, curBasicBlock); + ScanLdelem(operation, currentStack, methodIL, curBasicBlock); break; case Code.Cpblk: case Code.Initblk: - PopUnknown(currentStack, 3, methodBody, operation.Offset); + PopUnknown(currentStack, 3, methodIL, operation.Offset); break; case Code.Stfld: case Code.Stsfld: - ScanStfld(operation, currentStack, thisMethod, methodBody, locals, ref interproceduralState); + ScanStfld(methodIL, operation, currentStack, locals, ref interproceduralState); break; case Code.Cpobj: - PopUnknown(currentStack, 2, methodBody, operation.Offset); + PopUnknown(currentStack, 2, methodIL, operation.Offset); break; case Code.Stind_I: @@ -592,18 +592,18 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro case Code.Stind_R8: case Code.Stind_Ref: case Code.Stobj: - ScanIndirectStore(operation, currentStack, methodBody, locals, curBasicBlock, ref interproceduralState); - ValidateNoReferenceToReference(locals, methodBody.Method, operation.Offset); + ScanIndirectStore(methodIL, operation, currentStack, locals, curBasicBlock, ref interproceduralState); + ValidateNoReferenceToReference(locals, methodIL, operation.Offset); break; case Code.Initobj: case Code.Pop: - PopUnknown(currentStack, 1, methodBody, operation.Offset); + PopUnknown(currentStack, 1, methodIL, operation.Offset); break; case Code.Starg: case Code.Starg_S: - ScanStarg(operation, currentStack, thisMethod, methodBody); + ScanStarg(methodIL, operation, currentStack); break; case Code.Stloc: @@ -612,8 +612,8 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro case Code.Stloc_1: case Code.Stloc_2: case Code.Stloc_3: - ScanStloc(operation, currentStack, methodIL, locals, curBasicBlock); - ValidateNoReferenceToReference(locals, methodBody.Method, operation.Offset); + ScanStloc(methodIL, operation, currentStack, locals, curBasicBlock); + ValidateNoReferenceToReference(locals, methodIL, operation.Offset); break; case Code.Constrained: @@ -628,7 +628,7 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro case Code.Brfalse_S: case Code.Brtrue: case Code.Brtrue_S: - PopUnknown(currentStack, 1, methodBody, operation.Offset); + PopUnknown(currentStack, 1, methodIL, operation.Offset); NewKnownStack(knownStacks, ((Instruction)operation.Operand).Offset, currentStack); break; @@ -637,15 +637,15 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro var signature = (CallSite)operation.Operand; if (signature.HasThis && !signature.ExplicitThis) { - PopUnknown(currentStack, 1, methodBody, operation.Offset); + PopUnknown(currentStack, 1, methodIL, operation.Offset); } // Pop arguments if (signature.Parameters.Count > 0) - PopUnknown(currentStack, signature.Parameters.Count, methodBody, operation.Offset); + PopUnknown(currentStack, signature.Parameters.Count, methodIL, operation.Offset); // Pop function pointer - PopUnknown(currentStack, 1, methodBody, operation.Offset); + PopUnknown(currentStack, 1, methodIL, operation.Offset); if (!signature.ReturnsVoid()) PushUnknown(currentStack); @@ -656,8 +656,8 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro case Code.Callvirt: case Code.Newobj: TrackNestedFunctionReference((MethodReference)operation.Operand, ref interproceduralState); - HandleCall(methodBody, operation, currentStack, locals, ref interproceduralState, curBasicBlock); - ValidateNoReferenceToReference(locals, methodBody.Method, operation.Offset); + HandleCall(methodIL, operation, currentStack, locals, ref interproceduralState, curBasicBlock); + ValidateNoReferenceToReference(locals, methodIL, operation.Offset); break; case Code.Jmp: @@ -690,17 +690,17 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro if (currentStack.Count != (hasReturnValue ? 1 : 0)) { - WarnAboutInvalidILInMethod(methodBody, operation.Offset); + WarnAboutInvalidILInMethod(methodIL, operation.Offset); } if (hasReturnValue) { - StackSlot retStackSlot = PopUnknown(currentStack, 1, methodBody, operation.Offset); + StackSlot retStackSlot = PopUnknown(currentStack, 1, methodIL, operation.Offset); // If the return value is a reference, treat it as the value itself for now // We can handle ref return values better later MultiValue retValue = DereferenceValue(retStackSlot.Value, locals, ref interproceduralState); - var methodReturnValue = GetReturnValue(methodBody.Method); - HandleReturnValue(thisMethod, methodReturnValue, operation, retValue); - ValidateNoReferenceToReference(locals, methodBody.Method, operation.Offset); + var methodReturnValue = GetReturnValue(methodIL); + HandleReturnValue(methodIL, methodReturnValue, operation, retValue); + ValidateNoReferenceToReference(locals, methodIL, operation.Offset); } ClearStack(ref currentStack); break; @@ -708,7 +708,7 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro case Code.Switch: { - PopUnknown(currentStack, 1, methodBody, operation.Offset); + PopUnknown(currentStack, 1, methodIL, operation.Offset); Instruction[] targets = (Instruction[])operation.Operand; foreach (Instruction target in targets) { @@ -737,7 +737,7 @@ protected virtual void Scan(MethodIL methodIL, ref InterproceduralState interpro case Code.Blt_S: case Code.Blt_Un: case Code.Blt_Un_S: - PopUnknown(currentStack, 2, methodBody, operation.Offset); + PopUnknown(currentStack, 2, methodIL, operation.Offset); NewKnownStack(knownStacks, ((Instruction)operation.Operand).Offset, currentStack); break; } @@ -765,7 +765,7 @@ private static void ScanExceptionInformation(Dictionary> k protected abstract SingleValue GetMethodParameterValue(ParameterProxy parameter); - protected abstract MethodReturnValue GetReturnValue(MethodDefinition method); + protected abstract MethodReturnValue GetReturnValue(MethodIL method); private void ScanLdarg(Instruction operation, Stack currentStack, MethodDefinition thisMethod) { @@ -787,31 +787,30 @@ private void ScanLdarg(Instruction operation, Stack currentStack, Met } private void ScanStarg( + MethodIL methodIL, Instruction operation, - Stack currentStack, - MethodDefinition thisMethod, - MethodBody methodBody) + Stack currentStack) { - var valueToStore = PopUnknown(currentStack, 1, methodBody, operation.Offset); - ParameterIndex paramNum = ParameterHelpers.GetParameterIndex(thisMethod, operation); - ParameterProxy param = new(thisMethod, paramNum); + var valueToStore = PopUnknown(currentStack, 1, methodIL, operation.Offset); + ParameterIndex paramNum = ParameterHelpers.GetParameterIndex(methodIL.Method, operation); + ParameterProxy param = new(methodIL.Method, paramNum); var targetValue = GetMethodParameterValue(param); if (targetValue is MethodParameterValue targetParameterValue) - HandleStoreParameter(thisMethod, targetParameterValue, operation, valueToStore.Value, null); + HandleStoreParameter(methodIL, targetParameterValue, operation, valueToStore.Value, null); // If the targetValue is MethodThisValue do nothing - it should never happen really, and if it does, there's nothing we can track there } private void ScanLdloc( + MethodIL methodIL, Instruction operation, Stack currentStack, - MethodIL methodIL, LocalVariableStore locals) { VariableDefinition localDef = GetLocalDef(operation, methodIL.Variables); if (localDef == null) { - PushUnknownAndWarnAboutInvalidIL(currentStack, methodIL.Body, operation.Offset); + PushUnknownAndWarnAboutInvalidIL(currentStack, methodIL, operation.Offset); return; } @@ -874,17 +873,17 @@ void ScanLdtoken(Instruction operation, Stack currentStack) } private void ScanStloc( + MethodIL methodIL, Instruction operation, Stack currentStack, - MethodIL methodIL, LocalVariableStore locals, int curBasicBlock) { - StackSlot valueToStore = PopUnknown(currentStack, 1, methodIL.Body, operation.Offset); + StackSlot valueToStore = PopUnknown(currentStack, 1, methodIL, operation.Offset); VariableDefinition localDef = GetLocalDef(operation, methodIL.Variables); if (localDef == null) { - WarnAboutInvalidILInMethod(methodIL.Body, operation.Offset); + WarnAboutInvalidILInMethod(methodIL, operation.Offset); return; } @@ -892,17 +891,17 @@ private void ScanStloc( } private void ScanIndirectStore( + MethodIL methodIL, Instruction operation, Stack currentStack, - MethodBody methodBody, LocalVariableStore locals, int curBasicBlock, ref InterproceduralState ipState) { - StackSlot valueToStore = PopUnknown(currentStack, 1, methodBody, operation.Offset); - StackSlot destination = PopUnknown(currentStack, 1, methodBody, operation.Offset); + StackSlot valueToStore = PopUnknown(currentStack, 1, methodIL, operation.Offset); + StackSlot destination = PopUnknown(currentStack, 1, methodIL, operation.Offset); - StoreInReference(destination.Value, valueToStore.Value, methodBody.Method, operation, locals, curBasicBlock, ref ipState, null); + StoreInReference(destination.Value, valueToStore.Value, methodIL, operation, locals, curBasicBlock, ref ipState, null); } /// @@ -914,7 +913,7 @@ private void ScanIndirectStore( /// The instruction causing the store /// For assignment due to a call to a method with out params, the index of the out parameter. /// Throws if is not a valid target for an indirect store. - protected void StoreInReference(MultiValue target, MultiValue source, MethodDefinition method, Instruction operation, LocalVariableStore locals, int curBasicBlock, ref InterproceduralState ipState, int? parameterIndex) + protected void StoreInReference(MultiValue target, MultiValue source, MethodIL methodIL, Instruction operation, LocalVariableStore locals, int curBasicBlock, ref InterproceduralState ipState, int? parameterIndex) { foreach (var value in target.AsEnumerable()) { @@ -925,25 +924,25 @@ protected void StoreInReference(MultiValue target, MultiValue source, MethodDefi break; case FieldReferenceValue fieldReference when GetFieldValue(fieldReference.Field).AsSingleValue() is FieldValue fieldValue: - HandleStoreField(method, fieldValue, operation, source, parameterIndex); + HandleStoreField(methodIL, fieldValue, operation, source, parameterIndex); break; case ParameterReferenceValue parameterReference when GetMethodParameterValue(parameterReference.Parameter) is MethodParameterValue parameterValue: - HandleStoreParameter(method, parameterValue, operation, source, parameterIndex); + HandleStoreParameter(methodIL, parameterValue, operation, source, parameterIndex); break; case MethodReturnValue methodReturnValue: // Ref returns don't have special ReferenceValue values, so assume if the target here is a MethodReturnValue then it must be a ref return value - HandleReturnValue(method, methodReturnValue, operation, source); + HandleReturnValue(methodIL, methodReturnValue, operation, source); break; case FieldValue fieldValue: - HandleStoreField(method, fieldValue, operation, DereferenceValue(source, locals, ref ipState), parameterIndex); + HandleStoreField(methodIL, fieldValue, operation, DereferenceValue(source, locals, ref ipState), parameterIndex); break; case IValueWithStaticType valueWithStaticType: if (valueWithStaticType.StaticType is not null && _context.Annotations.FlowAnnotations.IsTypeInterestingForDataflow(valueWithStaticType.StaticType.Value.Type)) throw new LinkerFatalErrorException(MessageContainer.CreateErrorMessage( $"Unhandled StoreReference call. Unhandled attempt to store a value in {value} of type {value.GetType()}.", (int)DiagnosticId.LinkerUnexpectedError, - origin: new MessageOrigin(method, operation.Offset))); + origin: new MessageOrigin(methodIL.Method, operation.Offset))); // This should only happen for pointer derefs, which can't point to interesting types break; default: @@ -958,14 +957,14 @@ when GetMethodParameterValue(parameterReference.Parameter) is MethodParameterVal protected abstract MultiValue GetFieldValue(FieldReference field); private void ScanLdfld( + MethodIL methodIL, Instruction operation, Stack currentStack, - MethodBody methodBody, ref InterproceduralState interproceduralState) { Code code = operation.OpCode.Code; if (code == Code.Ldfld || code == Code.Ldflda) - PopUnknown(currentStack, 1, methodBody, operation.Offset); + PopUnknown(currentStack, 1, methodIL, operation.Offset); bool isByRef = code == Code.Ldflda || code == Code.Ldsflda; @@ -992,29 +991,28 @@ private void ScanLdfld( currentStack.Push(new StackSlot(value)); } - protected virtual void HandleStoreField(MethodDefinition method, FieldValue field, Instruction operation, MultiValue valueToStore, int? parameterIndex) + protected virtual void HandleStoreField(MethodIL methodIL, FieldValue field, Instruction operation, MultiValue valueToStore, int? parameterIndex) { } - protected virtual void HandleStoreParameter(MethodDefinition method, MethodParameterValue parameter, Instruction operation, MultiValue valueToStore, int? parameterIndex) + protected virtual void HandleStoreParameter(MethodIL methodIL, MethodParameterValue parameter, Instruction operation, MultiValue valueToStore, int? parameterIndex) { } - protected virtual void HandleReturnValue(MethodDefinition method, MethodReturnValue thisParameter, Instruction operation, MultiValue valueToReturn) + protected virtual void HandleReturnValue(MethodIL method, MethodReturnValue thisParameter, Instruction operation, MultiValue valueToReturn) { } private void ScanStfld( + MethodIL methodIL, Instruction operation, Stack currentStack, - MethodDefinition thisMethod, - MethodBody methodBody, LocalVariableStore locals, ref InterproceduralState interproceduralState) { - StackSlot valueToStoreSlot = PopUnknown(currentStack, 1, methodBody, operation.Offset); + StackSlot valueToStoreSlot = PopUnknown(currentStack, 1, methodIL, operation.Offset); if (operation.OpCode.Code == Code.Stfld) - PopUnknown(currentStack, 1, methodBody, operation.Offset); + PopUnknown(currentStack, 1, methodIL, operation.Offset); FieldDefinition? field = _context.TryResolve((FieldReference)operation.Operand); if (field != null) @@ -1035,7 +1033,7 @@ private void ScanStfld( // Incomplete handling of ref fields -- if we're storing a reference to a value, pretend it's just the value MultiValue valueToStore = DereferenceValue(valueToStoreSlot.Value, locals, ref interproceduralState); - HandleStoreField(thisMethod, fieldValue, operation, valueToStore, null); + HandleStoreField(methodIL, fieldValue, operation, valueToStore, null); } } } @@ -1054,7 +1052,7 @@ private static VariableDefinition GetLocalDef(Instruction operation, Collection< private ValueNodeList PopCallArguments( Stack currentStack, MethodReference methodCalled, - MethodBody containingMethodBody, + MethodIL containingMethodIL, bool isNewObj, int ilOffset) { int countToPop = 0; @@ -1065,7 +1063,7 @@ private ValueNodeList PopCallArguments( ValueNodeList methodParams = new ValueNodeList(countToPop); for (int iParam = 0; iParam < countToPop; ++iParam) { - StackSlot slot = PopUnknown(currentStack, 1, containingMethodBody, ilOffset); + StackSlot slot = PopUnknown(currentStack, 1, containingMethodIL, ilOffset); methodParams.Add(slot.Value); } @@ -1120,7 +1118,7 @@ internal MultiValue DereferenceValue(MultiValue maybeReferenceValue, LocalVariab /// Assigns a MethodParameterValue to the location of each parameter passed by reference. (i.e. assigns the value to x when passing `ref x` as a parameter) /// protected void AssignRefAndOutParameters( - MethodBody callingMethodBody, + MethodIL callingMethodIL, MethodReference calledMethod, ValueNodeList methodArguments, Instruction operation, @@ -1136,7 +1134,7 @@ protected void AssignRefAndOutParameters( if (parameter.GetReferenceKind() is not (ReferenceKind.Ref or ReferenceKind.Out)) continue; var newByRefValue = _context.Annotations.FlowAnnotations.GetMethodParameterValue(parameter); - StoreInReference(methodArguments[(int)parameter.Index], newByRefValue, callingMethodBody.Method, operation, locals, curBasicBlock, ref ipState, parameter.Index.Index); + StoreInReference(methodArguments[(int)parameter.Index], newByRefValue, callingMethodIL, operation, locals, curBasicBlock, ref ipState, parameter.Index.Index); } } else @@ -1149,13 +1147,13 @@ protected void AssignRefAndOutParameters( var (argument, refKind) = argumentRefKinds[index]; if (refKind is not (ReferenceKind.Ref or ReferenceKind.Out)) continue; - StoreInReference(argument, UnknownValue.Instance, callingMethodBody.Method, operation, locals, curBasicBlock, ref ipState, index); + StoreInReference(argument, UnknownValue.Instance, callingMethodIL, operation, locals, curBasicBlock, ref ipState, index); } } } private void HandleCall( - MethodBody callingMethodBody, + MethodIL callingMethodIL, Instruction operation, Stack currentStack, LocalVariableStore locals, @@ -1166,12 +1164,12 @@ private void HandleCall( bool isNewObj = operation.OpCode.Code == Code.Newobj; - ValueNodeList methodArguments = PopCallArguments(currentStack, calledMethod, callingMethodBody, isNewObj, operation.Offset); + ValueNodeList methodArguments = PopCallArguments(currentStack, calledMethod, callingMethodIL, isNewObj, operation.Offset); var dereferencedMethodParams = new List(); foreach (var argument in methodArguments) dereferencedMethodParams.Add(DereferenceValue(argument, locals, ref interproceduralState)); MultiValue methodReturnValue = HandleCall( - callingMethodBody, + callingMethodIL, calledMethod, operation, new ValueNodeList(dereferencedMethodParams)); @@ -1179,7 +1177,7 @@ private void HandleCall( if (isNewObj || !calledMethod.ReturnsVoid()) currentStack.Push(new StackSlot(methodReturnValue)); - AssignRefAndOutParameters(callingMethodBody, calledMethod, methodArguments, operation, locals, curBasicBlock, ref interproceduralState); + AssignRefAndOutParameters(callingMethodIL, calledMethod, methodArguments, operation, locals, curBasicBlock, ref interproceduralState); foreach (var param in methodArguments) { @@ -1200,7 +1198,7 @@ private void HandleCall( public TypeDefinition? ResolveToTypeDefinition(TypeReference typeReference) => typeReference.ResolveToTypeDefinition(_context); public abstract MultiValue HandleCall( - MethodBody callingMethodBody, + MethodIL callingMethodIL, MethodReference calledMethod, Instruction operation, ValueNodeList methodParams); @@ -1222,12 +1220,12 @@ private static void MarkArrayValuesAsUnknown(ArrayValue arrValue, int curBasicBl private void ScanStelem( Instruction operation, Stack currentStack, - MethodBody methodBody, + MethodIL methodIL, int curBasicBlock) { - StackSlot valueToStore = PopUnknown(currentStack, 1, methodBody, operation.Offset); - StackSlot indexToStoreAt = PopUnknown(currentStack, 1, methodBody, operation.Offset); - StackSlot arrayToStoreIn = PopUnknown(currentStack, 1, methodBody, operation.Offset); + StackSlot valueToStore = PopUnknown(currentStack, 1, methodIL, operation.Offset); + StackSlot indexToStoreAt = PopUnknown(currentStack, 1, methodIL, operation.Offset); + StackSlot arrayToStoreIn = PopUnknown(currentStack, 1, methodIL, operation.Offset); int? indexToStoreAtInt = indexToStoreAt.Value.AsConstInt(); foreach (var array in arrayToStoreIn.Value.AsEnumerable()) { @@ -1253,11 +1251,11 @@ private void ScanStelem( private void ScanLdelem( Instruction operation, Stack currentStack, - MethodBody methodBody, + MethodIL methodIL, int curBasicBlock) { - StackSlot indexToLoadFrom = PopUnknown(currentStack, 1, methodBody, operation.Offset); - StackSlot arrayToLoadFrom = PopUnknown(currentStack, 1, methodBody, operation.Offset); + StackSlot indexToLoadFrom = PopUnknown(currentStack, 1, methodIL, operation.Offset); + StackSlot arrayToLoadFrom = PopUnknown(currentStack, 1, methodIL, operation.Offset); bool isByRef = operation.OpCode.Code == Code.Ldelema; diff --git a/src/tools/illink/src/linker/Linker.Dataflow/MethodProxy.cs b/src/tools/illink/src/linker/Linker.Dataflow/MethodProxy.cs index f01af50a061552..fe2a65bf683270 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/MethodProxy.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/MethodProxy.cs @@ -66,7 +66,7 @@ internal partial ParameterProxyEnumerable GetParameters() internal partial bool HasGenericParameters() => Method.HasGenericParameters; - internal partial bool HasGenericParametersCount(int genericParameterCount) => Method.GenericParameters.Count == genericParameterCount; + internal partial bool HasGenericArgumentsCount(int genericArgumentCount) => Method is GenericInstanceMethod generic && generic.GenericArguments.Count == genericArgumentCount; internal partial ImmutableArray GetGenericParameters() { diff --git a/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs b/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs index a4c77237e317fc..ef2ac6fe837a00 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs @@ -74,7 +74,7 @@ protected override void Scan(MethodIL methodIL, ref InterproceduralState interpr base.Scan(methodIL, ref interproceduralState); } - protected override void WarnAboutInvalidILInMethod(MethodBody method, int ilOffset) + protected override void WarnAboutInvalidILInMethod(MethodIL methodIl, int ilOffset) { // Serves as a debug helper to make sure valid IL is not considered invalid. // @@ -93,7 +93,7 @@ MethodParameterValue GetMethodParameterValue(ParameterProxy parameter, Dynamical protected override MultiValue GetFieldValue(FieldReference field) => _annotations.GetFieldValue(field); - protected override MethodReturnValue GetReturnValue(MethodDefinition method) => _annotations.GetMethodReturnValue(method, isNewObj: false); + protected override MethodReturnValue GetReturnValue(MethodIL methodIL) => _annotations.GetMethodReturnValue(methodIL.Method, isNewObj: false); private void HandleStoreValueWithDynamicallyAccessedMembers(ValueWithDynamicallyAccessedMembers targetValue, Instruction operation, MultiValue sourceValue, int? parameterIndex) { @@ -104,24 +104,24 @@ private void HandleStoreValueWithDynamicallyAccessedMembers(ValueWithDynamically } } - protected override void HandleStoreField(MethodDefinition method, FieldValue field, Instruction operation, MultiValue valueToStore, int? parameterIndex) + protected override void HandleStoreField(MethodIL methodIL, FieldValue field, Instruction operation, MultiValue valueToStore, int? parameterIndex) => HandleStoreValueWithDynamicallyAccessedMembers(field, operation, valueToStore, parameterIndex); - protected override void HandleStoreParameter(MethodDefinition method, MethodParameterValue parameter, Instruction operation, MultiValue valueToStore, int? parameterIndex) + protected override void HandleStoreParameter(MethodIL methodIL, MethodParameterValue parameter, Instruction operation, MultiValue valueToStore, int? parameterIndex) => HandleStoreValueWithDynamicallyAccessedMembers(parameter, operation, valueToStore, parameterIndex); - protected override void HandleReturnValue(MethodDefinition method, MethodReturnValue returnValue, Instruction operation, MultiValue valueToStore) + protected override void HandleReturnValue(MethodIL methodIL, MethodReturnValue returnValue, Instruction operation, MultiValue valueToStore) => HandleStoreValueWithDynamicallyAccessedMembers(returnValue, operation, valueToStore, null); - public override MultiValue HandleCall(MethodBody callingMethodBody, MethodReference calledMethod, Instruction operation, ValueNodeList methodParams) + public override MultiValue HandleCall(MethodIL callingMethodIL, MethodReference calledMethod, Instruction operation, ValueNodeList methodParams) { - var reflectionProcessed = _markStep.ProcessReflectionDependency(callingMethodBody, operation); + var reflectionProcessed = _markStep.ProcessReflectionDependency(callingMethodIL.Body, operation); if (reflectionProcessed) { return UnknownValue.Instance; } - Debug.Assert(callingMethodBody.Method == _origin.Provider); + Debug.Assert(callingMethodIL.Method == _origin.Provider); var calledMethodDefinition = _context.TryResolve(calledMethod); if (calledMethodDefinition == null) { @@ -218,6 +218,12 @@ static bool IsComInterop(IMarshalInfoProvider marshalInfoProvider, TypeReference if (nativeType == NativeType.None) { + if (parameterType.IsPointer) + { + // Pointer types are passed without marshalling + return false; + } + // Resolve will look at the element type var parameterTypeDef = context.TryResolve(parameterType); diff --git a/src/tools/illink/src/linker/Linker.Steps/LinkAttributesParser.cs b/src/tools/illink/src/linker/Linker.Steps/LinkAttributesParser.cs index 53019523f9573c..6b03933b8abcf7 100644 --- a/src/tools/illink/src/linker/Linker.Steps/LinkAttributesParser.cs +++ b/src/tools/illink/src/linker/Linker.Steps/LinkAttributesParser.cs @@ -137,9 +137,9 @@ static string FormatCustomAttribute(CustomAttribute ca) // // public sealed class RemoveAttributeInstancesAttribute : Attribute // { - // public RemoveAttributeInstancesAttribute () {} - // public RemoveAttributeInstancesAttribute (object values) {} // For legacy uses - // public RemoveAttributeInstancesAttribute (params object[] values) {} + // public RemoveAttributeInstancesAttribute() {} + // public RemoveAttributeInstancesAttribute(object values) {} // For legacy uses + // public RemoveAttributeInstancesAttribute(params object[] values) {} // } // const MethodAttributes ctorAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Final; diff --git a/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs b/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs index 8a3d6e98d0f314..26768b75b2ae90 100644 --- a/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs +++ b/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs @@ -75,6 +75,8 @@ protected LinkContext Context // method body scanner. readonly Dictionary _compilerGeneratedMethodRequiresScanner; + TypeMapHandler _typeMapHandler; + MarkStepContext? _markContext; MarkStepContext MarkContext { @@ -96,6 +98,8 @@ internal DynamicallyAccessedMembersTypeHierarchy DynamicallyAccessedMembersTypeH } } + internal TypeMapHandler TypeMapHandler => _typeMapHandler; + #if DEBUG static readonly DependencyKind[] _entireTypeReasons = new DependencyKind[] { DependencyKind.AccessedViaReflection, @@ -227,6 +231,7 @@ public MarkStep() _pending_isinst_instr = new List<(TypeDefinition, MethodBody, Instruction)>(); _entireTypesMarked = new HashSet(); _compilerGeneratedMethodRequiresScanner = new Dictionary(); + _typeMapHandler = new TypeMapHandler(); } public AnnotationStore Annotations => Context.Annotations; @@ -250,6 +255,13 @@ protected virtual void Initialize() InitializeCorelibAttributeXml(); Context.Pipeline.InitializeMarkHandlers(Context, MarkContext); + if (Annotations.GetEntryPointAssembly() is AssemblyDefinition entryPoint) + { + _typeMapHandler = new TypeMapHandler(entryPoint); + } + + _typeMapHandler.Initialize(Context, this); + ProcessMarkedPending(); } @@ -1162,7 +1174,7 @@ void LazyMarkCustomAttributes(ICustomAttributeProvider provider) } } - protected virtual void MarkCustomAttribute(CustomAttribute ca, in DependencyInfo reason, MessageOrigin origin) + protected internal virtual void MarkCustomAttribute(CustomAttribute ca, in DependencyInfo reason, MessageOrigin origin) { Annotations.Mark(ca, reason); MarkMethod(ca.Constructor, new DependencyInfo(DependencyKind.AttributeConstructor, ca), origin); @@ -1540,7 +1552,7 @@ protected override void ProcessExtra() // This can happen when the compiler emits typerefs into IL which aren't strictly necessary per ECMA 335. foreach (TypeReference typeReference in assembly.MainModule.GetTypeReferences()) { - if (!Visited!.Add(typeReference)) + if (!Visited.Add(typeReference)) continue; markingHelpers.MarkForwardedScope(typeReference, new MessageOrigin(assembly)); } @@ -1726,6 +1738,18 @@ void ReportWarningsForReflectionAccess(in MessageOrigin origin, MethodDefinition isReflectionAccessCoveredByRUC = Annotations.ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode(method, out requiresUnreferencedCode); break; + case DependencyKind.AttributeConstructor: + // Attribute constructors for the System.Runtime.InteropServices.TypeMap*Attribute types should not + // enforce RUC as directly accessing the attributes themselves is not valid. + // They should only be accessed via the type-map APIs. + // Additionally, there's no way to suppress the warnings for the linker. + // By suppressing them here, they become analyzer-only, which is the expected behavior. + isReflectionAccessCoveredByRUC = Annotations.ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode(method, out requiresUnreferencedCode); + if (origin.Provider is AssemblyDefinition && TypeMapHandler.IsTypeMapAttributeType(method.DeclaringType)) + { + isReflectionAccessCoveredByRUC = false; + } + break; default: // If the method being accessed has warnings suppressed due to Requires attributes, // we need to issue a warning for the reflection access. This is true even for instance @@ -1789,7 +1813,7 @@ static bool IsDeclaredWithinType(IMemberDefinition member, TypeDefinition type) Context.LogWarning(origin, id, type.GetDisplayName(), ((MemberReference)member).GetDisplayName(), // The cast is valid since it has to be a method or field MessageFormat.FormatRequiresAttributeMessageArg(requiresUnreferencedCodeAttribute!.Message), - MessageFormat.FormatRequiresAttributeMessageArg(requiresUnreferencedCodeAttribute!.Url)); + MessageFormat.FormatRequiresAttributeMessageArg(requiresUnreferencedCodeAttribute.Url)); } bool isReflectionAccessCoveredByDAM = Annotations.FlowAnnotations.ShouldWarnWhenAccessedForReflection(member); @@ -1886,7 +1910,7 @@ void ProcessAnalysisAnnotationsForField(FieldDefinition field, DependencyKind de return; if (Annotations.ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode(field, out RequiresUnreferencedCodeAttribute? requiresUnreferencedCodeAttribute)) - ReportRequiresUnreferencedCode(field.GetDisplayName(), requiresUnreferencedCodeAttribute!, new DiagnosticContext(origin, diagnosticsEnabled: true, Context)); + ReportRequiresUnreferencedCode(field.GetDisplayName(), requiresUnreferencedCodeAttribute, new DiagnosticContext(origin, diagnosticsEnabled: true, Context)); switch (dependencyKind) { @@ -1952,12 +1976,18 @@ protected internal virtual void MarkTypeVisibleToReflection(TypeReference type, // If a type is visible to reflection, we need to stop doing optimization that could cause observable difference // in reflection APIs. This includes APIs like MakeGenericType (where variant castability of the produced type // could be incorrect) or IsAssignableFrom (where assignability of unconstructed types might change). - Annotations.MarkRelevantToVariantCasting(definition); + MarkRelevantToVariantCasting(definition); Annotations.MarkReflectionUsed(definition); MarkImplicitlyUsedFields(definition, origin); } } + internal void MarkRelevantToVariantCasting(TypeDefinition type) + { + _typeMapHandler.ProcessType(type); + Annotations.MarkRelevantToVariantCasting(type); + } + internal void MarkMethodVisibleToReflection(MethodReference method, in DependencyInfo reason, in MessageOrigin origin) { MarkMethod(method, reason, origin); @@ -2092,7 +2122,11 @@ internal void MarkStaticConstructorVisibleToReflection(TypeDefinition type, in D // Also don't warn when the type is marked due to an assembly being rooted. if (!(reason.Source is IMemberDefinition sourceMemberDefinition && sourceMemberDefinition.DeclaringType == type) && reason.Kind is not DependencyKind.TypeInAssembly) - Context.LogWarning(origin, DiagnosticId.AttributeIsReferencedButTrimmerRemoveAllInstances, type.GetDisplayName()); + { + // Don't warn for type map attribute types. They're marked as "remove attributes" but we explicitly keep the ones needed. + if (!TypeMapHandler.IsTypeMapAttributeType(type)) + Context.LogWarning(origin, DiagnosticId.AttributeIsReferencedButTrimmerRemoveAllInstances, type.GetDisplayName()); + } } if (CheckProcessed(type)) @@ -2118,17 +2152,6 @@ internal void MarkStaticConstructorVisibleToReflection(TypeDefinition type, in D MarkCustomAttributes(type, new DependencyInfo(DependencyKind.CustomAttribute, type), typeOrigin); MarkSecurityDeclarations(type, new DependencyInfo(DependencyKind.CustomAttribute, type), typeOrigin); - if (Context.TryResolve(type.BaseType) is TypeDefinition baseType && - !Annotations.HasLinkerAttribute(type) && - Annotations.TryGetLinkerAttribute(baseType, out RequiresUnreferencedCodeAttribute? effectiveRequiresUnreferencedCode)) - { - - string arg1 = MessageFormat.FormatRequiresAttributeMessageArg(effectiveRequiresUnreferencedCode.Message); - string arg2 = MessageFormat.FormatRequiresAttributeUrlArg(effectiveRequiresUnreferencedCode.Url); - Context.LogWarning(typeOrigin, DiagnosticId.RequiresUnreferencedCodeOnBaseClass, type.GetDisplayName(), type.BaseType.GetDisplayName(), arg1, arg2); - } - - if (type.IsMulticastDelegate()) { MarkMulticastDelegate(type, typeOrigin); @@ -2904,7 +2927,7 @@ void MarkGenericArguments(IGenericInstance instance, MessageOrigin origin) if (argumentTypeDef == null) continue; - Annotations.MarkRelevantToVariantCasting(argumentTypeDef); + MarkRelevantToVariantCasting(argumentTypeDef); if (parameter?.HasDefaultConstructorConstraint == true) MarkDefaultConstructor(argumentTypeDef, new DependencyInfo(DependencyKind.DefaultCtorForNewConstrainedGenericArgument, instance), origin); @@ -3113,7 +3136,7 @@ void MarkMethodCollection(IList methods, in DependencyInfo rea if (reference.Name == ".ctor" && Context.TryResolve(arrayType) is TypeDefinition typeDefinition) { - Annotations.MarkRelevantToVariantCasting(typeDefinition); + MarkRelevantToVariantCasting(typeDefinition); } return null; } @@ -3489,6 +3512,8 @@ protected virtual void MarkRequirementsForInstantiatedTypes(TypeDefinition type) Annotations.MarkInstantiated(type); + _typeMapHandler.ProcessType(type); + var typeOrigin = new MessageOrigin(type); MarkInterfaceImplementations(type); @@ -3501,6 +3526,8 @@ protected virtual void MarkRequirementsForInstantiatedTypes(TypeDefinition type) MarkImplicitlyUsedFields(type, typeOrigin); + _typeMapHandler.ProcessInstantiated(type); + DoAdditionalInstantiatedTypeProcessing(type); } @@ -3955,7 +3982,7 @@ protected virtual void MarkInstruction(Instruction instruction, MethodDefinition case Code.Newarr: if (Context.TryResolve(operand) is TypeDefinition typeDefinition) { - Annotations.MarkRelevantToVariantCasting(typeDefinition); + MarkRelevantToVariantCasting(typeDefinition); } break; case Code.Isinst: @@ -3972,6 +3999,8 @@ protected virtual void MarkInstruction(Instruction instruction, MethodDefinition if (type.IsInterface) break; + _typeMapHandler.ProcessType(type); + if (!Annotations.IsInstantiated(type)) { _pending_isinst_instr.Add((type, method.Body, instruction)); @@ -4016,7 +4045,7 @@ protected internal virtual bool ProcessReflectionDependency(MethodBody body, Ins } // - // Tries to mark additional dependencies used in reflection like calls (e.g. typeof (MyClass).GetField ("fname")) + // Tries to mark additional dependencies used in reflection like calls (e.g. typeof(MyClass).GetField("fname")) // protected virtual void MarkReflectionLikeDependencies(MethodIL methodIL, bool requiresReflectionMethodBodyScanner, MessageOrigin origin) { @@ -4033,13 +4062,19 @@ protected virtual void MarkReflectionLikeDependencies(MethodIL methodIL, bool re { case MethodDefinition nestedFunction: if (nestedFunction.Body is MethodBody nestedBody) - requiresReflectionMethodBodyScanner |= MarkAndCheckRequiresReflectionMethodBodyScanner(Context.GetMethodIL(nestedBody), origin); + { + var nestedOrigin = new MessageOrigin(nestedFunction); + requiresReflectionMethodBodyScanner |= MarkAndCheckRequiresReflectionMethodBodyScanner(Context.GetMethodIL(nestedBody), nestedOrigin); + } break; case TypeDefinition stateMachineType: foreach (var method in stateMachineType.Methods) { if (method.Body is MethodBody stateMachineBody) - requiresReflectionMethodBodyScanner |= MarkAndCheckRequiresReflectionMethodBodyScanner(Context.GetMethodIL(stateMachineBody), origin); + { + var stateMachineOrigin = new MessageOrigin(method); + requiresReflectionMethodBodyScanner |= MarkAndCheckRequiresReflectionMethodBodyScanner(Context.GetMethodIL(stateMachineBody), stateMachineOrigin); + } } break; default: diff --git a/src/tools/illink/src/linker/Linker.Steps/OutputStep.cs b/src/tools/illink/src/linker/Linker.Steps/OutputStep.cs index 5c5b24749f1951..779fbcdc3ec355 100644 --- a/src/tools/illink/src/linker/Linker.Steps/OutputStep.cs +++ b/src/tools/illink/src/linker/Linker.Steps/OutputStep.cs @@ -100,6 +100,7 @@ protected virtual void WriteAssembly(AssemblyDefinition assembly, string directo module.Attributes |= ModuleAttributes.ILOnly; module.Attributes ^= ModuleAttributes.ILLibrary; module.Architecture = TargetArchitecture.I386; // I386+ILOnly which ultimately translates to AnyCPU + module.Characteristics |= ModuleCharacteristics.NoSEH; } } diff --git a/src/tools/illink/src/linker/Linker.Steps/RootAssemblyInputStep.cs b/src/tools/illink/src/linker/Linker.Steps/RootAssemblyInputStep.cs index b40c8b02269995..23acf2e0bf8cbf 100644 --- a/src/tools/illink/src/linker/Linker.Steps/RootAssemblyInputStep.cs +++ b/src/tools/illink/src/linker/Linker.Steps/RootAssemblyInputStep.cs @@ -54,6 +54,7 @@ protected override void Process() Annotations.Mark(ep.DeclaringType, di, origin); Annotations.AddPreservedMethod(ep.DeclaringType, ep); + Annotations.SetEntryPointAssembly(assembly); break; case AssemblyRootMode.VisibleMembers: var preserve_visible = TypePreserveMembers.Visible; diff --git a/src/tools/illink/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs b/src/tools/illink/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs index 2bee7a9ead4aa0..5c97985f0e0886 100644 --- a/src/tools/illink/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs +++ b/src/tools/illink/src/linker/Linker.Steps/UnreachableBlocksOptimizer.cs @@ -530,7 +530,7 @@ public bool RewriteBody() if (!md.HasMetadataParameters() && CanInlineInstanceCall(instrs, i)) { processor.Replace(i - 1, Instruction.Create(OpCodes.Nop)); - processor.Replace(i, result.GetPrototype()!); + processor.Replace(i, result.GetPrototype()); changed = true; } diff --git a/src/tools/illink/src/linker/Linker/Annotations.cs b/src/tools/illink/src/linker/Linker/Annotations.cs index bba602d9a6dcab..1518bd5407c088 100644 --- a/src/tools/illink/src/linker/Linker/Annotations.cs +++ b/src/tools/illink/src/linker/Linker/Annotations.cs @@ -71,6 +71,7 @@ public partial class AnnotationStore protected readonly HashSet indirectly_called = new HashSet(); protected readonly HashSet types_relevant_to_variant_casting = new HashSet(); readonly HashSet reflection_used = new(); + AssemblyDefinition? entry_assembly; public AnnotationStore(LinkContext context) { @@ -601,6 +602,17 @@ public bool TryGetLinkerAttribute(IMemberDefinition member, [NotNullWhen(retu return attribute != null; } + public AssemblyDefinition? GetEntryPointAssembly() + { + return entry_assembly; + } + + public void SetEntryPointAssembly(AssemblyDefinition asmDef) + { + Debug.Assert(entry_assembly is null); + entry_assembly = asmDef; + } + /// /// Determines if method is within a declared RUC scope - this typically means that trim analysis /// warnings should be suppressed in such a method. @@ -614,7 +626,13 @@ internal bool IsInRequiresUnreferencedCodeScope(MethodDefinition method, [NotNul return true; if (method.DeclaringType is not null && TryGetLinkerAttribute(method.DeclaringType, out attribute)) - return true; + { + if (!attribute.ExcludeStatics) + return true; + + if (!method.IsStatic) + return true; + } attribute = null; return false; @@ -664,7 +682,13 @@ internal bool DoesMethodRequireUnreferencedCode(MethodDefinition originalMethod, if ((method.IsStatic || method.IsConstructor) && method.DeclaringType is not null && TryGetLinkerAttribute(method.DeclaringType, out attribute)) - return true; + { + if (!attribute.ExcludeStatics) + return true; + + if (method.IsConstructor) + return true; + } } while (context.CompilerGeneratedState.TryGetOwningMethodForCompilerGeneratedMember(method, out method)); attribute = null; @@ -679,7 +703,7 @@ internal bool DoesFieldRequireUnreferencedCode(FieldDefinition field, [NotNullWh return false; } - return TryGetLinkerAttribute(field.DeclaringType, out attribute); + return TryGetLinkerAttribute(field.DeclaringType, out attribute) && !attribute.ExcludeStatics; } /// diff --git a/src/tools/illink/src/linker/Linker/AssemblyDefinitionExtensions.cs b/src/tools/illink/src/linker/Linker/AssemblyDefinitionExtensions.cs index 124270ba853b43..4b316e881b9e1f 100644 --- a/src/tools/illink/src/linker/Linker/AssemblyDefinitionExtensions.cs +++ b/src/tools/illink/src/linker/Linker/AssemblyDefinitionExtensions.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using Mono.Cecil; namespace Mono.Linker @@ -16,5 +17,29 @@ public static class AssemblyDefinitionExtensions } return null; } + + public static Version? GetTargetFrameworkVersion(this AssemblyDefinition assembly) + { + foreach (var attr in assembly.CustomAttributes) + { + if (attr.AttributeType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute" && attr.HasConstructorArguments) + { + var tfm = attr.ConstructorArguments[0].Value as string; + if (!string.IsNullOrEmpty(tfm)) + { + // Try to extract the version from the TFM string, e.g. ".NETCoreApp,Version=v8.0" + var versionPrefix = "Version=v"; + var idx = tfm.IndexOf(versionPrefix); + if (idx >= 0) + { + var versionStr = tfm.Substring(idx + versionPrefix.Length); + if (Version.TryParse(versionStr, out var version)) + return version; + } + } + } + } + return null; + } } } diff --git a/src/tools/illink/src/linker/Linker/DependencyInfo.cs b/src/tools/illink/src/linker/Linker/DependencyInfo.cs index 127a75fbc2c193..0f3e02ee145819 100644 --- a/src/tools/illink/src/linker/Linker/DependencyInfo.cs +++ b/src/tools/illink/src/linker/Linker/DependencyInfo.cs @@ -145,6 +145,8 @@ public enum DependencyKind DynamicallyAccessedMemberOnType = 88, // type with DynamicallyAccessedMembers annotations (including those inherited from base types and interfaces) UnsafeAccessorTarget = 89, // the member is referenced via UnsafeAccessor attribute + + TypeMapEntry = 90, // external or proxy type map entry } public readonly struct DependencyInfo : IEquatable diff --git a/src/tools/illink/src/linker/Linker/Driver.cs b/src/tools/illink/src/linker/Linker/Driver.cs index fe5f1abfb3c6ac..7d2cc9006b4b93 100644 --- a/src/tools/illink/src/linker/Linker/Driver.cs +++ b/src/tools/illink/src/linker/Linker/Driver.cs @@ -459,6 +459,12 @@ protected int SetupContext(ILogger? customLogger = null) continue; + case "--disable-generated-code-heuristics": + if (!GetBoolParam(token, l => context.DisableGeneratedCodeHeuristics = l)) + return -1; + + continue; + case "--ignore-descriptors": if (!GetBoolParam(token, l => context.IgnoreDescriptors = l)) return -1; diff --git a/src/tools/illink/src/linker/Linker/DynamicDependency.cs b/src/tools/illink/src/linker/Linker/DynamicDependency.cs index eebaa096d2fc9b..8bf34c9f446877 100644 --- a/src/tools/illink/src/linker/Linker/DynamicDependency.cs +++ b/src/tools/illink/src/linker/Linker/DynamicDependency.cs @@ -70,7 +70,7 @@ public DynamicDependency(DynamicallyAccessedMemberTypes memberTypes, string type // Don't honor the Condition until we have figured out the behavior for DynamicDependencyAttribute: // https://github.com/dotnet/linker/issues/1231 - // if (!ShouldProcess (context, customAttribute)) + // if (!ShouldProcess(context, customAttribute)) // return null; var dynamicDependency = GetDynamicDependency(customAttribute); diff --git a/src/tools/illink/src/linker/Linker/LinkContext.cs b/src/tools/illink/src/linker/Linker/LinkContext.cs index 64b2ebdacafc67..d6423e6dd23437 100644 --- a/src/tools/illink/src/linker/Linker/LinkContext.cs +++ b/src/tools/illink/src/linker/Linker/LinkContext.cs @@ -119,6 +119,8 @@ public Pipeline Pipeline public bool DisableOperatorDiscovery { get; set; } + public bool DisableGeneratedCodeHeuristics { get; set; } + /// /// Option to not special case EventSource. /// Currently, values are hard-coded and does not have a command line option to control diff --git a/src/tools/illink/src/linker/Linker/LinkerAttributesInformation.cs b/src/tools/illink/src/linker/Linker/LinkerAttributesInformation.cs index 1aa5abe6a0c217..c343ff3a1ede44 100644 --- a/src/tools/illink/src/linker/Linker/LinkerAttributesInformation.cs +++ b/src/tools/illink/src/linker/Linker/LinkerAttributesInformation.cs @@ -120,20 +120,28 @@ public IEnumerable GetAttributes() where T : Attribute if (customAttribute.HasConstructorArguments && customAttribute.ConstructorArguments[0].Value is string message) { - var ruca = new RequiresUnreferencedCodeAttribute(message); + string? url = null; + bool excludeStatics = false; if (customAttribute.HasProperties) { foreach (var prop in customAttribute.Properties) { if (prop.Name == "Url") { - ruca.Url = prop.Argument.Value as string; - break; + url = prop.Argument.Value as string; + } + else if (prop.Name == "ExcludeStatics" && prop.Argument.Value is true) + { + excludeStatics = true; } } } - return ruca; + return new RequiresUnreferencedCodeAttribute(message) + { + Url = url, + ExcludeStatics = excludeStatics + }; } context.LogWarning((IMemberDefinition)provider, DiagnosticId.AttributeDoesntHaveTheRequiredNumberOfParameters, typeof(RequiresUnreferencedCodeAttribute).FullName ?? ""); diff --git a/src/tools/illink/src/linker/Linker/TypeMapHandler.cs b/src/tools/illink/src/linker/Linker/TypeMapHandler.cs new file mode 100644 index 00000000000000..8cbc8fb301f37f --- /dev/null +++ b/src/tools/illink/src/linker/Linker/TypeMapHandler.cs @@ -0,0 +1,265 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using ILLink.Shared.TrimAnalysis; +using Mono.Cecil; +using Mono.CompilerServices.SymbolWriter; +using Mono.Linker.Steps; + +using CustomAttributeWithOrigin = (Mono.Cecil.CustomAttribute Attribute, Mono.Cecil.AssemblyDefinition Origin); + +namespace Mono.Linker +{ + sealed class TypeMapHandler + { + readonly TypeMapResolver _lazyTypeMapResolver; + + // [trim target: [type map group: custom attributes with assembly origin]] + readonly Dictionary>> _unmarkedExternalTypeMapEntries = []; + + // [source type: [type map group: custom attributes]] + readonly Dictionary>> _unmarkedProxyTypeMapEntries = []; + + // CustomAttributes that we want to mark when the type mapping APIs are used. + // [type map group: custom attributes] + Dictionary> _pendingExternalTypeMapEntries = []; + Dictionary> _pendingProxyTypeMapEntries = []; + HashSet _referencedExternalTypeMaps = []; + HashSet _referencedProxyTypeMaps = []; + + LinkContext _context = null!; + MarkStep _markStep = null!; + + public TypeMapHandler() + { + _lazyTypeMapResolver = new TypeMapResolver(new HashSet()); + } + + public TypeMapHandler(AssemblyDefinition entryPointAssembly) + { + HashSet assemblies = [AssemblyNameReference.Parse(entryPointAssembly.FullName)]; + foreach (var attr in entryPointAssembly.CustomAttributes) + { + if (attr.AttributeType is not GenericInstanceType + { + Namespace: "System.Runtime.InteropServices", + GenericArguments: [_] + }) + { + continue; // Only interested in System.Runtime.InteropServices attributes + } + + if (attr.AttributeType.Name != "TypeMapAssemblyTarget`1" + || attr.ConstructorArguments[0].Value is not string str) + { + // Invalid attribute, skip it. + // Let the runtime handle the failure. + continue; + } + + assemblies.Add(AssemblyNameReference.Parse(str)); + } + + _lazyTypeMapResolver = new TypeMapResolver(assemblies); + } + + public void Initialize(LinkContext context, MarkStep markStep) + { + _context = context; + _markStep = markStep; + _lazyTypeMapResolver.Resolve(context, this); + } + + public void ProcessExternalTypeMapGroupSeen(MethodDefinition callingMethod, TypeReference typeMapGroup) + { + _referencedExternalTypeMaps.Add(typeMapGroup); + if (!_pendingExternalTypeMapEntries.Remove(typeMapGroup, out List? pendingEntries)) + { + return; + } + + foreach (var entry in pendingEntries) + { + MarkTypeMapAttribute(entry, new DependencyInfo(DependencyKind.TypeMapEntry, callingMethod)); + } + } + + public void ProcessProxyTypeMapGroupSeen(MethodDefinition callingMethod, TypeReference typeMapGroup) + { + _referencedProxyTypeMaps.Add(typeMapGroup); + if (!_pendingProxyTypeMapEntries.Remove(typeMapGroup, out List? pendingEntries)) + { + return; + } + + foreach (var entry in pendingEntries) + { + MarkTypeMapAttribute(entry, new DependencyInfo(DependencyKind.TypeMapEntry, callingMethod)); + } + } + + void MarkTypeMapAttribute(CustomAttributeWithOrigin entry, DependencyInfo info) + { + _markStep.MarkCustomAttribute(entry.Attribute, info, new MessageOrigin(entry.Origin)); + + // Mark the target type as instantiated + TypeReference targetType = (TypeReference)entry.Attribute.ConstructorArguments[1].Value; + if (targetType is not null && _context.Resolve(targetType) is TypeDefinition targetTypeDef) + _context.Annotations.MarkInstantiated(targetTypeDef); + } + + public void ProcessType(TypeDefinition definition) + { + RecordTargetTypeSeen(definition, _unmarkedExternalTypeMapEntries, _referencedExternalTypeMaps, _pendingExternalTypeMapEntries); + } + + void RecordTargetTypeSeen( + TypeDefinition targetType, + Dictionary>> unmarkedTypeMapAttributes, + HashSet referenceTypeMapGroups, + Dictionary> typeMapAttributesPendingUniverseMarking) + { + if (unmarkedTypeMapAttributes.Remove(targetType, out Dictionary>? entries)) + { + foreach (var (typeMapGroup, attributes) in entries) + { + + if (referenceTypeMapGroups.Contains(typeMapGroup)) + { + foreach (var attr in attributes) + { + MarkTypeMapAttribute(attr, new DependencyInfo(DependencyKind.TypeMapEntry, targetType)); + } + } + else if (!typeMapAttributesPendingUniverseMarking.TryGetValue(typeMapGroup, out List? value)) + { + typeMapAttributesPendingUniverseMarking[typeMapGroup] = [.. attributes]; + } + else + { + value.AddRange(attributes); + } + } + } + } + + public void ProcessInstantiated(TypeDefinition definition) + { + RecordTargetTypeSeen(definition, _unmarkedProxyTypeMapEntries, _referencedProxyTypeMaps, _pendingProxyTypeMapEntries); + } + + void AddExternalTypeMapEntry(TypeReference group, CustomAttributeWithOrigin attr) + { + if (attr.Attribute.ConstructorArguments is [_, _, { Value: TypeReference trimTarget }]) + { + RecordTypeMapEntry(attr, group, trimTarget, _unmarkedExternalTypeMapEntries); + return; + } + if (attr.Attribute.ConstructorArguments is [_, { Value: TypeReference }]) + { + // There's no trim target, so include the attribute unconditionally. + RecordTypeMapEntry(attr, group, null, _unmarkedExternalTypeMapEntries); + return; + } + // Invalid attribute, skip it. + // Let the runtime handle the failure. + } + + void AddProxyTypeMapEntry(TypeReference group, CustomAttributeWithOrigin attr) + { + if (attr.Attribute.ConstructorArguments is [{ Value: TypeReference sourceType }, _]) + { + // This is a TypeMapAssociationAttribute, which has a single type argument. + RecordTypeMapEntry(attr, group, sourceType, _unmarkedProxyTypeMapEntries); + return; + } + // Invalid attribute, skip it. + // Let the runtime handle the failure. + } + + void RecordTypeMapEntry(CustomAttributeWithOrigin attr, TypeReference group, TypeReference? trimTarget, Dictionary>> unmarkedEntryList) + { + if (trimTarget is null) + { + // If there's no trim target, we can just mark the attribute. + MarkTypeMapAttribute(attr, new DependencyInfo(DependencyKind.TypeMapEntry, null)); + return; + } + + TypeDefinition? typeDef = _context.Resolve(trimTarget); + if (typeDef is null) + { + return; // Couldn't find the type we were asked about. + } + + if (_context.Annotations.IsMarked(typeDef)) + { + MarkTypeMapAttribute(attr, new DependencyInfo(DependencyKind.TypeMapEntry, trimTarget)); + } + else + { + if (!unmarkedEntryList.TryGetValue(typeDef, out Dictionary>? entries)) + { + entries = new() { + { group, [] } + }; + unmarkedEntryList[typeDef] = entries; + } + + if (!entries.TryGetValue(group, out List? attrs)) + { + entries[group] = [attr]; + } + else + { + attrs.Add(attr); + } + } + } + + public static bool IsTypeMapAttributeType(TypeDefinition type) + { + return type is { Namespace: "System.Runtime.InteropServices", Name: "TypeMapAttribute`1" or "TypeMapAssociationAttribute`1" or "TypeMapAssemblyTargetAttribute`1" }; + } + + class TypeMapResolver(IReadOnlySet assemblies) + { + public void Resolve(LinkContext context, TypeMapHandler manager) + { + foreach (AssemblyNameReference assemblyName in assemblies) + { + if (context.TryResolve(assemblyName) is not AssemblyDefinition assembly) + { + // If we cannot find the assembly, skip it. + // We'll fail at runtime as expected. + continue; + } + foreach (CustomAttribute attr in assembly.CustomAttributes) + { + if (attr.AttributeType is not GenericInstanceType + { + Namespace: "System.Runtime.InteropServices", + GenericArguments: [TypeReference typeMapGroup] + }) + { + continue; // Only interested in System.Runtime.InteropServices attributes + } + + if (attr.AttributeType.Name is "TypeMapAttribute`1") + { + manager.AddExternalTypeMapEntry(typeMapGroup, (attr, assembly)); + } + else if (attr.AttributeType.Name is "TypeMapAssociationAttribute`1") + { + manager.AddProxyTypeMapEntry(typeMapGroup, (attr, assembly)); + } + } + } + } + } + } +} diff --git a/src/tools/illink/src/linker/Linker/TypeNameResolver.cs b/src/tools/illink/src/linker/Linker/TypeNameResolver.cs index 747bb486afd78f..af0e1a27c58226 100644 --- a/src/tools/illink/src/linker/Linker/TypeNameResolver.cs +++ b/src/tools/illink/src/linker/Linker/TypeNameResolver.cs @@ -5,10 +5,9 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Mono.Cecil; - +using AssemblyNameInfo = System.Reflection.Metadata.AssemblyNameInfo; using TypeName = System.Reflection.Metadata.TypeName; using TypeNameParseOptions = System.Reflection.Metadata.TypeNameParseOptions; -using AssemblyNameInfo = System.Reflection.Metadata.AssemblyNameInfo; #nullable enable @@ -100,7 +99,7 @@ public bool TryResolveTypeName( Debug.Assert(typeName.IsSimple); TypeName topLevelTypeName = typeName; while (topLevelTypeName.IsNested) - topLevelTypeName = topLevelTypeName.DeclaringType!; + topLevelTypeName = topLevelTypeName.DeclaringType; Debug.Assert(topLevelTypeName.AssemblyName == typeName.AssemblyName); TypeDefinition? resolvedType = GetSimpleTypeFromModule(typeName, assembly.MainModule); @@ -133,7 +132,7 @@ public bool TryResolveTypeName( { if (typeName.IsNested) { - TypeDefinition? type = GetSimpleTypeFromModule(typeName.DeclaringType!, module); + TypeDefinition? type = GetSimpleTypeFromModule(typeName.DeclaringType, module); if (type == null) return null; return GetNestedType(type, TypeName.Unescape(typeName.Name)); diff --git a/src/tools/illink/src/linker/Mono.Linker.csproj b/src/tools/illink/src/linker/Mono.Linker.csproj index af73b43ef4cdcf..35293cd7078a82 100644 --- a/src/tools/illink/src/linker/Mono.Linker.csproj +++ b/src/tools/illink/src/linker/Mono.Linker.csproj @@ -21,6 +21,8 @@ Major false $(NoWarn);NU5131 + + $(NoWarn);CS0436 $(TargetsForTfmSpecificContentInPackage);_AddReferenceAssemblyToPackage $(DefineConstants);ILLINK true diff --git a/src/tools/illink/src/tlens/README.md b/src/tools/illink/src/tlens/README.md index 0a1066c9c03e9e..9c967034a18b5d 100644 --- a/src/tools/illink/src/tlens/README.md +++ b/src/tools/illink/src/tlens/README.md @@ -44,12 +44,12 @@ Consider following example where `tlens` can show suggestion for the code to be ```c# interface IOperation { - void Run (); + void Run(); } class CommonOperation : IOperation { - void IOperation.Run () + void IOperation.Run() { // Pulls complex dependencies } @@ -57,12 +57,12 @@ class CommonOperation : IOperation class RareOperation : IOperation { - void IOperation.Run () + void IOperation.Run() { // Pulls complex dependencies } - public void Run (IOperation operation) + public void Run(IOperation operation) { operation.Run(); } @@ -70,10 +70,10 @@ class RareOperation : IOperation class App { - public static void Main () + public static void Main() { - var rare = new RareOperation (); - rare.Run (rare); + var rare = new RareOperation(); + rare.Run(rare); } } ``` diff --git a/src/tools/illink/src/tlens/TLens/Driver.cs b/src/tools/illink/src/tlens/TLens/Driver.cs index 65b1c2cdb8a6c8..691be2d55c5284 100644 --- a/src/tools/illink/src/tlens/TLens/Driver.cs +++ b/src/tools/illink/src/tlens/TLens/Driver.cs @@ -25,32 +25,32 @@ static int Main(string[] args) var options = new OptionSet { { "l|lens=", "{NAME} of the lens to use. Default subset is used if not specified.", l => { - var lens = LensesCollection.GetLensByName (l); + var lens = LensesCollection.GetLensByName(l); if (lens != null) - analyzers.Add (lens); + analyzers.Add(lens); else { - Console.WriteLine ($"Error: Lens name '{l}' does not exist."); + Console.WriteLine($"Error: Lens name '{l}' does not exist."); error = true; } }}, { "d|dir=", "Additional location {PATH} to look for assembly references.", l => { - if (!Directory.Exists (l)) { - Console.WriteLine ($"Error: Directory '{l}' does not exist."); + if (!Directory.Exists(l)) { + Console.WriteLine($"Error: Directory '{l}' does not exist."); error = true; } else { - dirs.Add (Path.GetFullPath (l)); + dirs.Add(Path.GetFullPath(l)); } }}, { "all-lenses", "Uses all lenses available.", - l => analyzers.AddRange (LensesCollection.AllAnalyzers) }, + l => analyzers.AddRange(LensesCollection.AllAnalyzers) }, { "h|help", "Show this message and exit.", v => showUsage = v != null }, { "limit=", "Maximum number of findings reported by lens (defaults to 30).", - l => runner.MaxAnalyzerResults = int.Parse (l) }, + l => runner.MaxAnalyzerResults = int.Parse(l) }, }; List files; diff --git a/src/tools/illink/src/tlens/TLens/LensesCollection.cs b/src/tools/illink/src/tlens/TLens/LensesCollection.cs index fadc8200894927..b3ba2c7ee6adc1 100644 --- a/src/tools/illink/src/tlens/TLens/LensesCollection.cs +++ b/src/tools/illink/src/tlens/TLens/LensesCollection.cs @@ -39,32 +39,32 @@ public Analyzer CreateAnalyzer() // static readonly LensAnalyzerDetails[] all = [ - new LensAnalyzerDetails ("duplicated-code", - "Methods which are possible duplicates", typeof (DuplicatedCodeAnalyzer)), - new LensAnalyzerDetails ("fields-init", - "Constructors re-initializing fields to default values", typeof (RedundantFieldInitializationAnalyzer)), - new LensAnalyzerDetails ("fields-unread", - "Fields that are set but never read", typeof (UnnecessaryFieldsAssignmentAnalyzer)), - new LensAnalyzerDetails ("ifaces-dispatch", - "Interfaces which are called sparsely", typeof (InterfaceDispatchAnalyzer)), - new LensAnalyzerDetails ("ifaces-types", - "Interfaces with implementation but no type reference", typeof (InterfaceTypeCheckAnalyzers)), - new LensAnalyzerDetails ("inverted-ctors", - "Constructors calling same type constructor with default values", typeof (InverterCtorsChainAnalyzer)), - new LensAnalyzerDetails ("large-arrays", - "Methods creating large arrays", typeof (LargeStaticArraysAnalyzer)) { DefaultSet = true }, - new LensAnalyzerDetails ("large-cctors", - "Types with large static contructor", typeof (LargeStaticCtorAnalyzer)), - new LensAnalyzerDetails ("large-strings", - "Methods using large strings literals", typeof (LargeStringsAnalyzer)) { DefaultSet = true }, - new LensAnalyzerDetails ("operator-null", - "User operators used for null check", typeof (UserOperatorCalledForNullCheckAnalyzer)), - new LensAnalyzerDetails ("single-calls", - "Methods called sparsely", typeof (LimitedMethodCalls)), - new LensAnalyzerDetails ("single-construction", - "Types with limited number of constructions", typeof (TypeInstatiationAnalyzer)) { DefaultSet = true }, - new LensAnalyzerDetails ("unused-param", - "Methods with unused parameters", typeof (UnusedParametersAnalyzer)), + new LensAnalyzerDetails("duplicated-code", + "Methods which are possible duplicates", typeof(DuplicatedCodeAnalyzer)), + new LensAnalyzerDetails("fields-init", + "Constructors re-initializing fields to default values", typeof(RedundantFieldInitializationAnalyzer)), + new LensAnalyzerDetails("fields-unread", + "Fields that are set but never read", typeof(UnnecessaryFieldsAssignmentAnalyzer)), + new LensAnalyzerDetails("ifaces-dispatch", + "Interfaces which are called sparsely", typeof(InterfaceDispatchAnalyzer)), + new LensAnalyzerDetails("ifaces-types", + "Interfaces with implementation but no type reference", typeof(InterfaceTypeCheckAnalyzers)), + new LensAnalyzerDetails("inverted-ctors", + "Constructors calling same type constructor with default values", typeof(InverterCtorsChainAnalyzer)), + new LensAnalyzerDetails("large-arrays", + "Methods creating large arrays", typeof(LargeStaticArraysAnalyzer)) { DefaultSet = true }, + new LensAnalyzerDetails("large-cctors", + "Types with large static contructor", typeof(LargeStaticCtorAnalyzer)), + new LensAnalyzerDetails("large-strings", + "Methods using large strings literals", typeof(LargeStringsAnalyzer)) { DefaultSet = true }, + new LensAnalyzerDetails("operator-null", + "User operators used for null check", typeof(UserOperatorCalledForNullCheckAnalyzer)), + new LensAnalyzerDetails("single-calls", + "Methods called sparsely", typeof(LimitedMethodCalls)), + new LensAnalyzerDetails("single-construction", + "Types with limited number of constructions", typeof(TypeInstatiationAnalyzer)) { DefaultSet = true }, + new LensAnalyzerDetails("unused-param", + "Methods with unused parameters", typeof(UnusedParametersAnalyzer)), ]; public static IEnumerable All => all; diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests.Generator/TestCaseGenerator.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests.Generator/TestCaseGenerator.cs index 8b6549a4900108..8246733d896bcd 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests.Generator/TestCaseGenerator.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests.Generator/TestCaseGenerator.cs @@ -71,12 +71,12 @@ public static string GenerateClassHeader(string suiteName, bool newTestSuite) namespace {TestNamespace}{suiteNamespacePart} {{ - public sealed partial class {suiteClassName}Tests : LinkerTestBase - {{ + public sealed partial class {suiteClassName}Tests : LinkerTestBase + {{ "; if (newTestSuite) header += $@" - protected override string TestSuiteName => ""{suiteName}""; + protected override string TestSuiteName => ""{suiteName}""; "; return header; } @@ -84,18 +84,18 @@ public sealed partial class {suiteClassName}Tests : LinkerTestBase public static string GenerateFact(string testCase) { return $@" - [Fact] - public Task {testCase} () - {{ - return RunTest (allowMissingWarnings: true); - }} + [Fact] + public Task {testCase}() + {{ + return RunTest(allowMissingWarnings: true); + }} "; } public static string GenerateClassFooter() { return $@" - }} + }} }} "; } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs index 50258259939eb7..eb88652e62a252 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs @@ -52,6 +52,12 @@ public Task AttributeFieldDataflow() return RunTest(nameof(AttributeFieldDataflow)); } + [Fact] + public Task AttributePrimaryConstructorDataflow() + { + return RunTest(); + } + [Fact] public Task AttributePropertyDataflow() { @@ -88,6 +94,18 @@ public Task CompilerGeneratedTypes() return RunTest(); } + [Fact] + public Task CompilerGeneratedTypesNet90() + { + return RunTest(); + } + + [Fact] + public Task CompilerGeneratedTypesReleaseNet90() + { + return RunTest(); + } + [Fact] public Task CompilerGeneratedTypesRelease() { @@ -276,7 +294,6 @@ public Task LocalDataFlow() return RunTest(nameof(LocalDataFlow)); } - [Fact] public Task ExceptionalDataFlow() { diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersAnalyzerTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersAnalyzerTests.cs index d402cbf41ee071..2db6ae9f47800f 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersAnalyzerTests.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersAnalyzerTests.cs @@ -29,31 +29,31 @@ static Task VerifyDynamicallyAccessedMembersAnalyzer( public Task NoWarningsIfAnalyzerIsNotEnabled() { var TargetParameterWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Foo - { - } - - class C - { - public static void Main() - { - M(typeof(Foo)); - } - - private static void NeedsPublicMethodsOnParameter( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type parameter) - { - } - - private static void M(Type type) - { - NeedsPublicMethodsOnParameter(type); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Foo + { + } + + class C + { + public static void Main() + { + M(typeof(Foo)); + } + + private static void NeedsPublicMethodsOnParameter( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type parameter) + { + } + + private static void M(Type type) + { + NeedsPublicMethodsOnParameter(type); + } + } + """; return VerifyCS.VerifyAnalyzerAsync(TargetParameterWithAnnotations, consoleApplication: false); } @@ -62,37 +62,37 @@ private static void M(Type type) public Task SourceParameterDoesNotMatchTargetParameterAnnotations() { var TargetParameterWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Foo - { - } - - class C - { - public static void Main() - { - M(typeof(Foo)); - } - private static void NeedsPublicMethodsOnParameter( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type parameter) - { - } - - private static void M(Type type) - { - NeedsPublicMethodsOnParameter(type); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Foo + { + } + + class C + { + public static void Main() + { + M(typeof(Foo)); + } + private static void NeedsPublicMethodsOnParameter( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type parameter) + { + } + + private static void M(Type type) + { + NeedsPublicMethodsOnParameter(type); + } + } + """; // (21,3): warning IL2067: 'parameter' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethodsOnParameter(Type)'. // The parameter 'type' of method 'C.M(Type)' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetParameterWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsParameter) - .WithSpan(21, 3, 21, 38) - .WithSpan(19, 24, 19, 33) + .WithSpan(21, 9, 21, 44) + .WithSpan(19, 27, 19, 36) .WithArguments("parameter", "C.NeedsPublicMethodsOnParameter(Type)", "type", @@ -104,35 +104,35 @@ private static void M(Type type) public Task SourceParameterDoesNotMatchTargetMethodReturnTypeAnnotations() { var TargetMethodReturnTypeWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Foo - { - } - - class C - { - public static void Main() - { - M(typeof(Foo)); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type M(Type type) - { - return type; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Foo + { + } + + class C + { + public static void Main() + { + M(typeof(Foo)); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type M(Type type) + { + return type; + } + } + """; // (18,10): warning IL2068: 'C.M(Type)' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. // The parameter 'type' of method 'C.M(Type)' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetMethodReturnTypeWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsMethodReturnType) - .WithSpan(18, 10, 18, 14) - .WithSpan(16, 24, 16, 33) + .WithSpan(18, 16, 18, 20) + .WithSpan(16, 27, 16, 36) .WithArguments("C.M(Type)", "type", "C.M(Type)", @@ -143,37 +143,37 @@ private static Type M(Type type) public Task SourceParameterDoesNotMatchTargetFieldAnnotations() { var TargetFieldWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Foo - { - } - - class C - { - public static void Main() - { - M(typeof(Foo)); - } - - private static void M(Type type) - { - f = type; - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f = typeof(Foo); - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Foo + { + } + + class C + { + public static void Main() + { + M(typeof(Foo)); + } + + private static void M(Type type) + { + f = type; + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f = typeof(Foo); + } + """; // (17,3): warning IL2069: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. // The parameter 'type' of method 'C.M(Type)' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetFieldWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsField) - .WithSpan(17, 3, 17, 11) - .WithSpan(15, 24, 15, 33) + .WithSpan(17, 9, 17, 17) + .WithSpan(15, 27, 15, 36) .WithArguments("C.f", "type", "C.M(Type)", @@ -184,25 +184,25 @@ private static void M(Type type) public Task SourceParameterDoesNotMatchTargetMethodAnnotations() { var TargetMethodWithAnnotations = $$""" - using System; - - public class Foo - { - } - - class C - { - public static void Main() - { - M(typeof(Foo)); - } - - private static void M(Type type) - { - type.GetMethod("Bar"); - } - } - """; + using System; + + public class Foo + { + } + + class C + { + public static void Main() + { + M(typeof(Foo)); + } + + private static void M(Type type) + { + type.GetMethod("Bar"); + } + } + """; // The warning will be generated once dataflow is able to handle GetMethod intrinsic // (16,3): warning IL2070: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. @@ -210,8 +210,8 @@ private static void M(Type type) // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetMethodWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsThisParameter) - .WithSpan(16, 3, 16, 24) - .WithSpan(14, 24, 14, 33) + .WithSpan(16, 9, 16, 30) + .WithSpan(14, 27, 14, 36) .WithArguments("System.Type.GetMethod(String)", "type", "C.M(Type)", @@ -224,39 +224,37 @@ private static void M(Type type) public Task SourceMethodReturnTypeDoesNotMatchTargetParameterAnnotations() { var TargetParameterWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class T - { - } - - class C - { - public static void Main() - { - NeedsPublicMethodsOnParameter(GetT()); - } - - private static void NeedsPublicMethodsOnParameter( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - - private static Type GetT() - { - return typeof(T); - } - } - """; - - // (12,3): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethodsOnParameter(Type)'. - // The return value of method 'C.GetT()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + using System; + using System.Diagnostics.CodeAnalysis; + + public class T + { + } + + class C + { + public static void Main() + { + NeedsPublicMethodsOnParameter(GetT()); + } + + private static void NeedsPublicMethodsOnParameter( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + + private static Type GetT() + { + return typeof(T); + } + } + """; + + // (12,9): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethodsOnParameter(Type)'. The return value of method 'C.GetT()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetParameterWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) - .WithSpan(12, 3, 12, 40) - .WithSpan(20, 2, 23, 3) + .WithSpan(12, 9, 12, 46) + .WithSpan(20, 5, 23, 6) .WithArguments("type", "C.NeedsPublicMethodsOnParameter(Type)", "C.GetT()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); } @@ -264,40 +262,38 @@ private static Type GetT() public Task SourceMethodReturnTypeDoesNotMatchTargetMethodReturnTypeAnnotations() { var TargetMethodReturnTypeWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Foo - { - } - - class C - { - public static void Main() - { - M(); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type M() - { - return GetFoo(); - } - - private static Type GetFoo() - { - return typeof(Foo); - } - } - """; - - // (18,10): warning IL2073: 'C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. - // The return value of method 'C.GetT()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + using System; + using System.Diagnostics.CodeAnalysis; + + public class Foo + { + } + + class C + { + public static void Main() + { + M(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type M() + { + return GetFoo(); + } + + private static Type GetFoo() + { + return typeof(Foo); + } + } + """; + + // (18,16): warning IL2073: 'C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. The return value of method 'C.GetT()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetMethodReturnTypeWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsMethodReturnType) - .WithSpan(18, 10, 18, 18) - .WithSpan(21, 2, 24, 3) + .WithSpan(18, 16, 18, 24) + .WithSpan(21, 5, 24, 6) .WithArguments("C.M()", "C.GetFoo()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); } @@ -305,37 +301,35 @@ private static Type GetFoo() public Task SourceMethodReturnTypeDoesNotMatchTargetFieldAnnotations() { var TargetFieldWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Foo - { - } - - class C - { - public static void Main() - { - f = M(); - } - - private static Type M() - { - return typeof(Foo); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f; - } - """; - - // (12,3): warning IL2074: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. - // The return value of method 'C.M()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + using System; + using System.Diagnostics.CodeAnalysis; + + public class Foo + { + } + + class C + { + public static void Main() + { + f = M(); + } + + private static Type M() + { + return typeof(Foo); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; + } + """; + + // (12,9): warning IL2074: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. The return value of method 'C.M()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetFieldWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsField) - .WithSpan(12, 3, 12, 10) - .WithSpan(15, 2, 18, 3) + .WithSpan(12, 9, 12, 16) + .WithSpan(15, 5, 18, 6) .WithArguments("C.f", "C.M()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); @@ -345,37 +339,36 @@ private static Type M() public Task SourceMethodReturnTypeDoesNotMatchTargetMethod() { var TargetMethodWithAnnotations = $$""" - using System; - - public class Foo - { - } - - class C - { - public static void Main() - { - GetFoo().GetMethod("Bar"); - - } - - private static Type GetFoo () - { - return typeof (Foo); - } - } - """; + using System; + + public class Foo + { + } + + class C + { + public static void Main() + { + GetFoo().GetMethod("Bar"); + + } + + private static Type GetFoo() + { + return typeof(Foo); + } + } + """; // The warning will be generated once dataflow is able to handle GetMethod intrinsic - // (11,3): warning IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. - // The return value of method 'C.GetT()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + // (11,9): warning IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. The return value of method 'C.GetT()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetMethodWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter) - .WithSpan(11, 3, 11, 28) - .WithSpan(15, 2, 18, 3) + .WithSpan(11, 9, 11, 34) + .WithSpan(15, 5, 18, 6) .WithArguments("System.Type.GetMethod(String)", "C.GetFoo()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); } + #endregion #region SourceField @@ -383,36 +376,36 @@ private static Type GetFoo () public Task SourceFieldDoesNotMatchTargetParameterAnnotations() { var TargetParameterWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class Foo - { - } + public class Foo + { + } - class C - { - private static Type f = typeof(Foo); + class C + { + private static Type f = typeof(Foo); - public static void Main() - { - NeedsPublicMethods(f); - } + public static void Main() + { + NeedsPublicMethods(f); + } - private static void NeedsPublicMethods( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - } - """; + private static void NeedsPublicMethods( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + } + """; // (14,3): warning IL2077: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethods(Type)'. // The field 'C.f' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetParameterWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsParameter) - .WithSpan(14, 3, 14, 24) - .WithSpan(10, 22, 10, 37) + .WithSpan(14, 9, 14, 30) + .WithSpan(10, 25, 10, 40) .WithArguments("type", "C.NeedsPublicMethods(Type)", "C.f", @@ -423,37 +416,37 @@ private static void NeedsPublicMethods( public Task SourceFieldDoesNotMatchTargetMethodReturnTypeAnnotations() { var TargetMethodReturnTypeWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Foo - { - } - - class C - { - private static Type f = typeof(Foo); - - public static void Main() - { - M(); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type M() - { - return f; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Foo + { + } + + class C + { + private static Type f = typeof(Foo); + + public static void Main() + { + M(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type M() + { + return f; + } + } + """; // (20,10): warning IL2078: 'C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. // The field 'C.f' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetMethodReturnTypeWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsMethodReturnType) - .WithSpan(20, 10, 20, 11) - .WithSpan(10, 22, 10, 37) + .WithSpan(20, 16, 20, 17) + .WithSpan(10, 25, 10, 40) .WithArguments("C.M()", "C.f", "'DynamicallyAccessedMemberTypes.PublicMethods'")); } @@ -462,33 +455,33 @@ private static Type M() public Task SourceFieldDoesNotMatchTargetFieldAnnotations() { var TargetFieldWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Foo - { - } - - class C - { - private static Type f1 = typeof(Foo); - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f2 = typeof(Foo); - - public static void Main() - { - f2 = f1; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Foo + { + } + + class C + { + private static Type f1 = typeof(Foo); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f2 = typeof(Foo); + + public static void Main() + { + f2 = f1; + } + } + """; // (17,3): warning IL2079: value stored in field 'C.f2' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. // The field 'C.f1' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetFieldWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsField) - .WithSpan(17, 3, 17, 10) - .WithSpan(10, 22, 10, 38) + .WithSpan(17, 9, 17, 16) + .WithSpan(10, 25, 10, 41) .WithArguments("C.f2", "C.f1", "'DynamicallyAccessedMemberTypes.PublicMethods'")); @@ -498,22 +491,22 @@ public static void Main() public Task SourceFieldDoesNotMatchTargetMethodAnnotations() { var TargetMethodWithAnnotations = $$""" - using System; - - public class Foo - { - } - - class C - { - private static Type f = typeof(Foo); - - public static void Main() - { - f.GetMethod("Bar"); - } - } - """; + using System; + + public class Foo + { + } + + class C + { + private static Type f = typeof(Foo); + + public static void Main() + { + f.GetMethod("Bar"); + } + } + """; // The warning will be generated once dataflow is able to handle GetMethod intrinsic // (13,3): warning IL2080: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. @@ -521,8 +514,8 @@ public static void Main() // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetMethodWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsThisParameter) - .WithSpan(13, 3, 13, 21) - .WithSpan(9, 22, 9, 37) + .WithSpan(13, 9, 13, 27) + .WithSpan(9, 25, 9, 40) .WithArguments("System.Type.GetMethod(String)", "C.f", "'DynamicallyAccessedMemberTypes.PublicMethods'")); @@ -544,182 +537,182 @@ public static string GetSystemTypeBase() namespace System { - public class TestSystemTypeBase : Type - { - public override Assembly Assembly => throw new NotImplementedException (); - - public override string AssemblyQualifiedName => throw new NotImplementedException (); - - public override Type BaseType => throw new NotImplementedException (); - - public override string FullName => throw new NotImplementedException (); - - public override Guid GUID => throw new NotImplementedException (); - - public override Module Module => throw new NotImplementedException (); - - public override string Namespace => throw new NotImplementedException (); - - public override Type UnderlyingSystemType => throw new NotImplementedException (); - - public override string Name => throw new NotImplementedException (); - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors - | DynamicallyAccessedMemberTypes.NonPublicConstructors)] - public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr) - { - throw new NotImplementedException (); - } - - public override object[] GetCustomAttributes (bool inherit) - { - throw new NotImplementedException (); - } - - public override object[] GetCustomAttributes (Type attributeType, bool inherit) - { - throw new NotImplementedException (); - } - - public override Type GetElementType () - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents - | DynamicallyAccessedMemberTypes.NonPublicEvents)] - public override EventInfo GetEvent (string name, BindingFlags bindingAttr) - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] - public override EventInfo[] GetEvents (BindingFlags bindingAttr) - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] - public override FieldInfo GetField (string name, BindingFlags bindingAttr) - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields - | DynamicallyAccessedMemberTypes.NonPublicFields)] - public override FieldInfo[] GetFields (BindingFlags bindingAttr) - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] - public override Type GetInterface (string name, bool ignoreCase) - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] - public override Type[] GetInterfaces () - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)0x1FFF)] - public override MemberInfo[] GetMembers (BindingFlags bindingAttr) - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] - public override MethodInfo[] GetMethods (BindingFlags bindingAttr) - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] - public override Type GetNestedType (string name, BindingFlags bindingAttr) - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] - public override Type[] GetNestedTypes (BindingFlags bindingAttr) - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] - public override PropertyInfo[] GetProperties (BindingFlags bindingAttr) - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] - public override object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) - { - throw new NotImplementedException (); - } - - public override bool IsDefined (Type attributeType, bool inherit) - { - throw new NotImplementedException (); - } - - protected override TypeAttributes GetAttributeFlagsImpl () - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors - | DynamicallyAccessedMemberTypes.NonPublicConstructors)] - protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] - protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) - { - throw new NotImplementedException (); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] - protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) - { - throw new NotImplementedException (); - } - - protected override bool HasElementTypeImpl () - { - throw new NotImplementedException (); - } - - protected override bool IsArrayImpl () - { - throw new NotImplementedException (); - } - - protected override bool IsByRefImpl () - { - throw new NotImplementedException (); - } - - protected override bool IsCOMObjectImpl () - { - throw new NotImplementedException (); - } - - protected override bool IsPointerImpl () - { - throw new NotImplementedException (); - } - - protected override bool IsPrimitiveImpl () - { - throw new NotImplementedException (); - } - } + public class TestSystemTypeBase : Type + { + public override Assembly Assembly => throw new NotImplementedException(); + + public override string AssemblyQualifiedName => throw new NotImplementedException(); + + public override Type BaseType => throw new NotImplementedException(); + + public override string FullName => throw new NotImplementedException(); + + public override Guid GUID => throw new NotImplementedException(); + + public override Module Module => throw new NotImplementedException(); + + public override string Namespace => throw new NotImplementedException(); + + public override Type UnderlyingSystemType => throw new NotImplementedException(); + + public override string Name => throw new NotImplementedException(); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors + | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + public override object[] GetCustomAttributes(bool inherit) + { + throw new NotImplementedException(); + } + + public override object[] GetCustomAttributes(Type attributeType, bool inherit) + { + throw new NotImplementedException(); + } + + public override Type GetElementType() + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] + public override EventInfo GetEvent(string name, BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] + public override EventInfo[] GetEvents(BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] + public override FieldInfo GetField(string name, BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields + | DynamicallyAccessedMemberTypes.NonPublicFields)] + public override FieldInfo[] GetFields(BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] + public override Type GetInterface(string name, bool ignoreCase) + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] + public override Type[] GetInterfaces() + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)0x1FFF)] + public override MemberInfo[] GetMembers(BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] + public override MethodInfo[] GetMethods(BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] + public override Type GetNestedType(string name, BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] + public override Type[] GetNestedTypes(BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] + public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] + public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) + { + throw new NotImplementedException(); + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + throw new NotImplementedException(); + } + + protected override TypeAttributes GetAttributeFlagsImpl() + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors + | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] + protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) + { + throw new NotImplementedException(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] + protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) + { + throw new NotImplementedException(); + } + + protected override bool HasElementTypeImpl() + { + throw new NotImplementedException(); + } + + protected override bool IsArrayImpl() + { + throw new NotImplementedException(); + } + + protected override bool IsByRefImpl() + { + throw new NotImplementedException(); + } + + protected override bool IsCOMObjectImpl() + { + throw new NotImplementedException(); + } + + protected override bool IsPointerImpl() + { + throw new NotImplementedException(); + } + + protected override bool IsPrimitiveImpl() + { + throw new NotImplementedException(); + } + } } """; } @@ -728,36 +721,36 @@ protected override bool IsPrimitiveImpl () public Task SourceMethodDoesNotMatchTargetParameterAnnotations() { var TargetParameterWithAnnotations = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - private void M1() - { - M2(this); - } - - private static void M2( - [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - } - } - """; - - // (198,4): warning IL2082: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + private void M1() + { + M2(this); + } + + private static void M2( + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + } + } + """; + + // (198,13): warning IL2082: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(string.Concat(GetSystemTypeBase(), TargetParameterWithAnnotations), consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter) - .WithSpan(198, 4, 198, 12) - .WithSpan(196, 3, 199, 4) + .WithSpan(198, 13, 198, 21) + .WithSpan(196, 9, 199, 10) .WithArguments("type", "System.C.M2(Type)", "System.C.M1()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); } @@ -765,81 +758,80 @@ private static void M2( public Task ConversionOperation() { var ConversionOperation = $$""" - namespace System - { - class ConvertsToType - { - public static implicit operator Type(ConvertsToType value) => typeof (ConvertsToType); - } - - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - private void M1() - { - M2(new ConvertsToType()); - } - - private static void M2( - [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - } - } - """; + namespace System + { + class ConvertsToType + { + public static implicit operator Type(ConvertsToType value) => typeof(ConvertsToType); + } + + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + private void M1() + { + M2(new ConvertsToType()); + } + + private static void M2( + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + } + } + """; return VerifyDynamicallyAccessedMembersAnalyzer(string.Concat(GetSystemTypeBase(), ConversionOperation), consoleApplication: false, - // (203,4): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. The return value of method 'System.ConvertsToType.implicit operator Type(ConvertsToType)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. + // (203,13): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. The return value of method 'System.ConvertsToType.implicit operator Type(ConvertsToType)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) - .WithSpan(203, 4, 203, 28) - .WithSpan(191, 3, 191, 89) + .WithSpan(203, 13, 203, 37) + .WithSpan(191, 9, 191, 94) .WithArguments("type", "System.C.M2(Type)", "System.ConvertsToType.implicit operator Type(ConvertsToType)", "'DynamicallyAccessedMemberTypes.PublicMethods'")); } - [Fact] public Task ConversionOperationAnnotationDoesNotMatch() { var AnnotatedConversionOperation = $$""" - namespace System - { - class ConvertsToType - { - [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] - public static implicit operator Type(ConvertsToType value) => null; - } - - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - private void M1() - { - M2(new ConvertsToType()); - } - - private static void M2( - [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - } - } - """; + namespace System + { + class ConvertsToType + { + [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] + public static implicit operator Type(ConvertsToType value) => null; + } + + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + private void M1() + { + M2(new ConvertsToType()); + } + + private static void M2( + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + } + } + """; return VerifyDynamicallyAccessedMembersAnalyzer(string.Concat(GetSystemTypeBase(), AnnotatedConversionOperation), consoleApplication: false, - // (205,4): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. The return value of method 'System.ConvertsToType.implicit operator Type(ConvertsToType)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. + // (205,13): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. The return value of method 'System.ConvertsToType.implicit operator Type(ConvertsToType)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) - .WithSpan(205, 4, 205, 28) + .WithSpan(205, 13, 205, 37) .WithArguments("type", "System.C.M2(Type)", "System.ConvertsToType.implicit operator Type(ConvertsToType)", "'DynamicallyAccessedMemberTypes.PublicMethods'")); } @@ -847,35 +839,35 @@ private static void M2( public Task ConversionOperationAnnotationMatches() { var AnnotatedConversionOperation = $$""" - namespace System - { - class ConvertsToType - { - [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] - public static implicit operator Type(ConvertsToType value) => null; - } - - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - private void M1() - { - M2(new ConvertsToType()); - } - - private static void M2( - [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - } - } - """; + namespace System + { + class ConvertsToType + { + [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] + public static implicit operator Type(ConvertsToType value) => null; + } + + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + private void M1() + { + M2(new ConvertsToType()); + } + + private static void M2( + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + } + } + """; return VerifyDynamicallyAccessedMembersAnalyzer(string.Concat(GetSystemTypeBase(), AnnotatedConversionOperation), consoleApplication: false); } @@ -885,32 +877,32 @@ private static void M2( public Task SourceMethodDoesNotMatchTargetMethodReturnTypeAnnotations() { var TargetMethodReturnTypeWithAnnotations = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M(); - } - - [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] - private Type M() - { - return this; - } - } - } - """; - - // (200,11): warning IL2083: 'System.C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M(); + } + + [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] + private Type M() + { + return this; + } + } + } + """; + + // (200,20): warning IL2083: 'System.C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. // The implicit 'this' argument of method 'System.C.M()' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(string.Concat(GetSystemTypeBase(), TargetMethodReturnTypeWithAnnotations), consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsMethodReturnType) - .WithSpan(200, 11, 200, 15) - .WithSpan(196, 3, 201, 4) + .WithSpan(200, 20, 200, 24) + .WithSpan(196, 9, 201, 10) .WithArguments("System.C.M()", "System.C.M()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); } @@ -918,34 +910,34 @@ private Type M() public Task SourceMethodDoesNotMatchTargetFieldAnnotations() { var TargetFieldWithAnnotations = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M(); - } - - private void M() - { - f = this; - } - - [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f; - } - } - """; - - // (198,4): warning IL2084: value stored in field 'System.C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M(); + } + + private void M() + { + f = this; + } + + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; + } + } + """; + + // (198,13): warning IL2084: value stored in field 'System.C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. // The implicit 'this' argument of method 'System.C.M()' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(string.Concat(GetSystemTypeBase(), TargetFieldWithAnnotations), consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsField) - .WithSpan(198, 4, 198, 12) - .WithSpan(196, 3, 199, 4) + .WithSpan(198, 13, 198, 21) + .WithSpan(196, 9, 199, 10) .WithArguments("System.C.f", "System.C.M()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); @@ -955,30 +947,30 @@ private void M() public Task SourceMethodDoesNotMatchTargetMethodAnnotations() { var TargetMethodWithAnnotations = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M(); - } - - private void M() - { - this.GetMethods(); - } - } - } - """; - - // (198,4): warning IL2085: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'. + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M(); + } + + private void M() + { + this.GetMethods(); + } + } + } + """; + + // (198,13): warning IL2085: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'. // The implicit 'this' argument of method 'System.C.M()' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(string.Concat(GetSystemTypeBase(), TargetMethodWithAnnotations), consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsThisParameter) - .WithSpan(198, 4, 198, 21) - .WithSpan(196, 3, 199, 4) + .WithSpan(198, 13, 198, 30) + .WithSpan(196, 9, 199, 10) .WithArguments("System.Type.GetMethods()", "System.C.M()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); } #endregion @@ -987,35 +979,35 @@ private void M() public Task SourceGenericParameterDoesNotMatchTargetParameterAnnotations() { var TargetParameterWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M2(); - } - - private static void M1( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - - private static void M2() - { - M1(typeof(T)); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M2(); + } + + private static void M1( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + + private static void M2() + { + M1(typeof(T)); + } + } + """; // (18,3): warning IL2087: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.M1(Type)'. // The generic parameter 'T' of 'C.M2()' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetParameterWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsParameter) - .WithSpan(18, 3, 18, 16) - .WithSpan(16, 25, 16, 26) + .WithSpan(18, 9, 18, 22) + .WithSpan(16, 28, 16, 29) .WithArguments("type", "C.M1(Type)", "T", "C.M2()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); } @@ -1023,31 +1015,31 @@ private static void M2() public Task SourceGenericParameterDoesNotMatchTargetMethodReturnTypeAnnotations() { var TargetMethodReturnTypeWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M(); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - private static Type M() - { - return typeof(T); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + private static Type M() + { + return typeof(T); + } + } + """; // (14,10): warning IL2088: 'C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' requirements. // The generic parameter 'T' of 'C.M()' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetMethodReturnTypeWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType) - .WithSpan(14, 10, 14, 19) - .WithSpan(12, 24, 12, 25) + .WithSpan(14, 16, 14, 25) + .WithSpan(12, 27, 12, 28) .WithArguments("C.M()", "T", "C.M()", "'DynamicallyAccessedMemberTypes.PublicConstructors'")); } @@ -1055,33 +1047,33 @@ private static Type M() public Task SourceGenericParameterDoesNotMatchTargetFieldAnnotations() { var TargetFieldWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M(); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f; - - private static void M() - { - f = typeof(T); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; + + private static void M() + { + f = typeof(T); + } + } + """; // (16,3): warning IL2089: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. // The generic parameter 'T' of 'C.M()' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetFieldWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsField) - .WithSpan(16, 3, 16, 16) - .WithSpan(14, 24, 14, 25) + .WithSpan(16, 9, 16, 22) + .WithSpan(14, 27, 14, 28) .WithArguments("C.f", "T", "C.M()", @@ -1092,33 +1084,33 @@ private static void M() public Task SourceGenericParameterDoesNotMatchTargetGenericParameterAnnotations() { var TargetGenericParameterWithAnnotations = $$""" - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M2(); - } - - private static void M1<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() - { - } - - private static void M2() - { - M1(); - } - } - """; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M2(); + } + + private static void M1<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() + { + } + + private static void M2() + { + M1(); + } + } + """; // (16,3): warning IL2091: 'T' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' // in 'C.M1()'. The generic parameter 'S' of 'C.M2()' does not have matching annotations. // The source value must declare at least the same requirements as those declared on the target location it is assigned to. return VerifyDynamicallyAccessedMembersAnalyzer(TargetGenericParameterWithAnnotations, consoleApplication: false, VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter) - .WithSpan(16, 3, 16, 10) - .WithSpan(14, 25, 14, 26) + .WithSpan(16, 9, 16, 16) + .WithSpan(14, 28, 14, 29) .WithArguments("T", "C.M1()", "S", "C.M2()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); } @@ -1126,25 +1118,25 @@ private static void M2() public Task SourceTypeofFlowsIntoTargetParameterAnnotations() { var TargetParameterWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Foo - { - } - - class C - { - public static void Main() - { - M(typeof(Foo)); - } - - private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Foo + { + } + + class C + { + public static void Main() + { + M(typeof(Foo)); + } + + private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + } + """; return VerifyDynamicallyAccessedMembersAnalyzer(TargetParameterWithAnnotations, consoleApplication: false); } @@ -1152,27 +1144,27 @@ private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes public Task SourceTypeofFlowsIntoTargetMethodReturnTypeAnnotation() { var TargetMethodReturnTypeWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Foo - { - } - - class C - { - public static void Main() - { - M(); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type M() - { - return typeof(Foo); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Foo + { + } + + class C + { + public static void Main() + { + M(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type M() + { + return typeof(Foo); + } + } + """; return VerifyDynamicallyAccessedMembersAnalyzer(TargetMethodReturnTypeWithAnnotations, consoleApplication: false); } @@ -1181,27 +1173,27 @@ private static Type M() public Task SourceParameterFlowsInfoTargetMethodReturnTypeAnnotations() { var TargetMethodReturnTypeWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Foo - { - } - - class C - { - public static void Main() - { - M(typeof(Foo)); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - return type; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Foo + { + } + + class C + { + public static void Main() + { + M(typeof(Foo)); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + return type; + } + } + """; return VerifyDynamicallyAccessedMembersAnalyzer(TargetMethodReturnTypeWithAnnotations, consoleApplication: false); } @@ -1210,29 +1202,29 @@ private static Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes public Task SourceParameterFlowsIntoTargetFieldAnnotations() { var TargetFieldWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Foo - { - } - - class C - { - public static void Main() - { - M(typeof(Foo)); - } - - private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - f = type; - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f = typeof(Foo); - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Foo + { + } + + class C + { + public static void Main() + { + M(typeof(Foo)); + } + + private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + f = type; + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f = typeof(Foo); + } + """; return VerifyDynamicallyAccessedMembersAnalyzer(TargetFieldWithAnnotations, consoleApplication: false); } @@ -1241,26 +1233,26 @@ private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes public Task SourceParameterFlowsIntoTargetMethodAnnotations() { var TargetMethodWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Foo - { - } - - class C - { - public static void Main() - { - M(typeof(Foo)); - } - - private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - type.GetMethod("Bar"); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Foo + { + } + + class C + { + public static void Main() + { + M(typeof(Foo)); + } + + private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + type.GetMethod("Bar"); + } + } + """; return VerifyDynamicallyAccessedMembersAnalyzer(TargetMethodWithAnnotations, consoleApplication: false); } @@ -1269,123 +1261,123 @@ private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes public Task MethodArgumentIsInvalidOperation() { var Source = """ - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - class C - { - public static void Main() - { - RequireAll(type); - } + class C + { + public static void Main() + { + RequireAll(type); + } - static void RequireAll([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type t) {} - } - """; + static void RequireAll([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type t) {} + } + """; return VerifyDynamicallyAccessedMembersAnalyzer(Source, consoleApplication: false, - // (8,14): error CS0103: The name 'type' does not exist in the current context - DiagnosticResult.CompilerError("CS0103").WithSpan(8, 14, 8, 18).WithArguments("type")); + // (8,20): error CS0103: The name 'type' does not exist in the current context + DiagnosticResult.CompilerError("CS0103").WithSpan(8, 20, 8, 24).WithArguments("type")); } [Fact] public Task MethodReturnIsInvalidOperation() { var Source = """ - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - class C - { - public static void Main() - { - GetTypeWithAll (); - } + class C + { + public static void Main() + { + GetTypeWithAll(); + } - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] - static Type GetTypeWithAll() => type; - } - """; + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + static Type GetTypeWithAll() => type; + } + """; return VerifyDynamicallyAccessedMembersAnalyzer(Source, consoleApplication: false, - // (12,34): error CS0103: The name 'type' does not exist in the current context - DiagnosticResult.CompilerError("CS0103").WithSpan(12, 34, 12, 38).WithArguments("type"), - // (12,34): warning IL2063: Value returned from method 'C.GetTypeWithAll()' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements. - VerifyCS.Diagnostic(DiagnosticId.MethodReturnValueCannotBeStaticallyDetermined).WithSpan(12, 34, 12, 38).WithArguments("C.GetTypeWithAll()")); + // (12,37): error CS0103: The name 'type' does not exist in the current context + DiagnosticResult.CompilerError("CS0103").WithSpan(12, 37, 12, 41).WithArguments("type"), + // (12,37): warning IL2063: Value returned from method 'C.GetTypeWithAll()' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic(DiagnosticId.MethodReturnValueCannotBeStaticallyDetermined).WithSpan(12, 37, 12, 41).WithArguments("C.GetTypeWithAll()")); } [Fact] public Task AssignmentSourceIsInvalidOperation() { var Source = """ - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - class C - { - public static void Main() - { - fieldRequiresAll = type; - } + class C + { + public static void Main() + { + fieldRequiresAll = type; + } - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] - static Type fieldRequiresAll; - } - """; + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + static Type fieldRequiresAll; + } + """; return VerifyDynamicallyAccessedMembersAnalyzer(Source, consoleApplication: false, - // (8,22): error CS0103: The name 'type' does not exist in the current context - DiagnosticResult.CompilerError("CS0103").WithSpan(8, 22, 8, 26).WithArguments("type"), - // (8,3): warning IL2064: Value assigned to C.fieldRequiresAll can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements. - VerifyCS.Diagnostic(DiagnosticId.FieldValueCannotBeStaticallyDetermined).WithSpan(8, 3, 8, 26).WithArguments("C.fieldRequiresAll")); + // (8,28): error CS0103: The name 'type' does not exist in the current context + DiagnosticResult.CompilerError("CS0103").WithSpan(8, 28, 8, 32).WithArguments("type"), + // (8,9): warning IL2064: Value assigned to C.fieldRequiresAll can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic(DiagnosticId.FieldValueCannotBeStaticallyDetermined).WithSpan(8, 9, 8, 32).WithArguments("C.fieldRequiresAll")); } [Fact] public Task AssignmentTargetIsInvalidOperation() { var Source = """ - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - class C - { - public static void Main() - { - type = GetTypeWithAll(); - } + class C + { + public static void Main() + { + type = GetTypeWithAll(); + } - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] - static Type GetTypeWithAll() => null; - } - """; + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + static Type GetTypeWithAll() => null; + } + """; return VerifyDynamicallyAccessedMembersAnalyzer(Source, consoleApplication: false, // (8,9): error CS0103: The name 'type' does not exist in the current context - DiagnosticResult.CompilerError("CS0103").WithSpan(8, 3, 8, 7).WithArguments("type")); + DiagnosticResult.CompilerError("CS0103").WithSpan(8, 9, 8, 13).WithArguments("type")); } [Fact] public Task AssignmentTargetIsCapturedInvalidOperation() { var Source = """ - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - class C - { - public static void Main() - { - type ??= GetTypeWithAll(); - } + class C + { + public static void Main() + { + type ??= GetTypeWithAll(); + } - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] - static Type GetTypeWithAll() => null; - } - """; + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + static Type GetTypeWithAll() => null; + } + """; return VerifyDynamicallyAccessedMembersAnalyzer(Source, consoleApplication: false, - // (8,3): error CS0103: The name 'type' does not exist in the current context - DiagnosticResult.CompilerError("CS0103").WithSpan(8, 3, 8, 7).WithArguments("type")); + // (8,9): error CS0103: The name 'type' does not exist in the current context + DiagnosticResult.CompilerError("CS0103").WithSpan(8, 9, 8, 13).WithArguments("type")); } [Fact] @@ -1393,17 +1385,17 @@ public Task AssignmentTargetHasNestedInvalidOperation() { // The assignment target is an IBinaryOperation whose right-hand side is an IInvalidOperation. var Source = $$""" - int a, b = 0; - a + = 3; - """; + int a, b = 0; + a + = 3; + """; return VerifyDynamicallyAccessedMembersAnalyzer(Source, consoleApplication: true, - // (2,6): error CS1525: Invalid expression term '=' - DiagnosticResult.CompilerError("CS1525").WithSpan(2, 6, 2, 7).WithArguments("="), - // (2,2): error CS0165: Use of unassigned local variable 'a' - DiagnosticResult.CompilerError("CS0165").WithSpan(2, 2, 2, 3).WithArguments("a"), - // (1,9): warning CS0219: The variable 'b' is assigned but its value is never used - DiagnosticResult.CompilerWarning("CS0219").WithSpan(1, 9, 1, 10).WithArguments("b") + // (2,9): error CS1525: Invalid expression term '=' + DiagnosticResult.CompilerError("CS1525").WithSpan(2, 9, 2, 10).WithArguments("="), + // (2,5): error CS0165: Use of unassigned local variable 'a' + DiagnosticResult.CompilerError("CS0165").WithSpan(2, 5, 2, 6).WithArguments("a"), + // (1,12): warning CS0219: The variable 'b' is assigned but its value is never used + DiagnosticResult.CompilerWarning("CS0219").WithSpan(1, 12, 1, 13).WithArguments("b") ); } @@ -1411,25 +1403,31 @@ public Task AssignmentTargetHasNestedInvalidOperation() public Task CRefGenericParameterAnalysis() { var Source = """ - using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.CodeAnalysis; - class C - { - /// - /// - /// - /// - /// - static CRequires Value => new CRequires (); - } + class C + { + /// + /// + /// + /// + /// + static CRequires Value => new CRequires); + } - class CRequires<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TInner> { public static bool IsIt => false; } - """; + class CRequires<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TInner> { public static bool IsIt => false; } + """; // The actual usage (ctor call) should warn, about missing annotation, but the cref should not. return VerifyDynamicallyAccessedMembersAnalyzer(Source, consoleApplication: false, - // (10,36): warning IL2091: 'TInner' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in 'CRequires'. The generic parameter 'TOuter' of 'C' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter).WithSpan(10, 36, 10, 60).WithSpan(3, 9, 3, 15).WithArguments("TInner", "CRequires", "TOuter", "C", "'DynamicallyAccessedMemberTypes.PublicMethods'")); + // (10,60): error CS1526: A new expression requires an argument list or (), [], or {} after type + DiagnosticResult.CompilerError("CS1526").WithSpan(10, 60, 10, 61), + // (10,60): error CS1002: ; expected + DiagnosticResult.CompilerError("CS1002").WithSpan(10, 60, 10, 61), + // (10,60): error CS1519: Invalid token ')' in a member declaration + DiagnosticResult.CompilerError("CS1519").WithSpan(10, 60, 10, 61).WithArguments(")"), + // (10,39): warning IL2091: 'TInner' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in 'CRequires'. The generic parameter 'TOuter' of 'C' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter).WithSpan(10, 39, 10, 60).WithSpan(3, 9, 3, 15).WithArguments("TInner", "CRequires", "TOuter", "C", "'DynamicallyAccessedMemberTypes.PublicMethods'")); } [Fact] @@ -1437,10 +1435,10 @@ public Task MethodParameterWithoutLocationAnalysis() { // The implicit main method has parameters var Source = """ - using System; - foreach (var arg in args) - Console.WriteLine (arg); - """; + using System; + foreach (var arg in args) + Console.WriteLine(arg); + """; return VerifyDynamicallyAccessedMembersAnalyzer(Source, consoleApplication: true); } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersCodeFixTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersCodeFixTests.cs index 78dbe6db801053..6d40c1cb536f05 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersCodeFixTests.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersCodeFixTests.cs @@ -45,43 +45,43 @@ static Task VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2067_MismatchParamTargetsParam() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - class C - { - static void M(Type t) { - M2(t); - } + class C + { + static void M(Type t) { + M2(t); + } - static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type t) {} - } - """; + static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type t) {} + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - class C - { - static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type t) { - M2(t); - } + class C + { + static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type t) { + M2(t); + } - static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type t) {} - } - """; + static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type t) {} + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(7,3): warning IL2067: 't' argument does not satisfy 'DynamicallyAccessedMemberTypes.All' in call to 'C.M2(Type)'. - // The parameter 't' of method 'C.M(Type)' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsParameter) - .WithSpan(7, 3, 7, 8) - .WithSpan(6, 16, 6, 22) + // /0/Test0.cs(7,3): warning IL2067: 't' argument does not satisfy 'DynamicallyAccessedMemberTypes.All' in call to 'C.M2(Type)'. + // The parameter 't' of method 'C.M(Type)' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsParameter) + .WithSpan(7, 9, 7, 14) + .WithSpan(6, 19, 6, 25) .WithArguments("t", "C.M2(Type)", "t", @@ -95,47 +95,47 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2067_MismatchParamTargetsParam_WithReturn() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - class C - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] - static string M(Type t) { - M2(t); - return "Foo"; - } + class C + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] + static string M(Type t) { + M2(t); + return "Foo, test"; + } - static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) {} - } - """; + static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) {} + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - class C - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] - static string M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { - M2(t); - return "Foo"; - } + class C + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] + static string M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { + M2(t); + return "Foo, test"; + } - static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) {} - } - """; + static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) {} + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(7,3): warning IL2067: 't' argument does not satisfy 'DynamicallyAccessedMemberTypes.All' in call to 'C.M2(Type)'. - // The parameter 't' of method 'C.M(Type)' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsParameter) - .WithSpan(8, 3, 8, 8) - .WithSpan(7, 18, 7, 24) + // /0/Test0.cs(7,3): warning IL2067: 't' argument does not satisfy 'DynamicallyAccessedMemberTypes.All' in call to 'C.M2(Type)'. + // The parameter 't' of method 'C.M(Type)' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsParameter) + .WithSpan(8, 9, 8, 14) + .WithSpan(7, 21, 7, 27) .WithArguments("t", "C.M2(Type)", "t", @@ -149,25 +149,25 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2067_TwoAttributesTurnsOffDiagnostic() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - static void M(Type t) { - M2(t); - } - - static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)] Type t) {} - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + static void M(Type t) { + M2(t); + } + + static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)] Type t) {} + } + """; var diag = new[] { - // /0/Test0.cs(7,3): warning IL2067: 't' argument does not satisfy 'DynamicallyAccessedMemberTypes.All' in call to 'C.M2(Type)'. - // The parameter 't' of method 'C.M(Type)' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsParameter) - .WithSpan(7, 3, 7, 8) - .WithSpan(6, 16, 6, 22) + // /0/Test0.cs(7,3): warning IL2067: 't' argument does not satisfy 'DynamicallyAccessedMemberTypes.All' in call to 'C.M2(Type)'. + // The parameter 't' of method 'C.M(Type)' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsParameter) + .WithSpan(7, 9, 7, 14) + .WithSpan(6, 19, 6, 25) .WithArguments("t", "C.M2(Type)", "t", @@ -181,27 +181,27 @@ static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Public public async Task CodeFix_IL2067_AttributeTurnsOffCodeFix() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - class C - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] - static string M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { - M2(t); - return "Foo"; - } + class C + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] + static string M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { + M2(t); + return "Foo, test"; + } - static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) {} - } - """; + static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) {} + } + """; var diag = new[] { - // /0/Test0.cs(7,3): warning IL2067: 't' argument does not satisfy 'DynamicallyAccessedMemberTypes.All' in call to 'C.M2(Type)'. - // The parameter 't' of method 'C.M(Type)' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsParameter) - .WithSpan(8, 3, 8, 8) + // /0/Test0.cs(7,3): warning IL2067: 't' argument does not satisfy 'DynamicallyAccessedMemberTypes.All' in call to 'C.M2(Type)'. + // The parameter 't' of method 'C.M(Type)' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsParameter) + .WithSpan(8, 9, 8, 14) .WithArguments("t", "C.M2(Type)", "t", @@ -215,40 +215,40 @@ static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Public public async Task CodeFix_IL2068_MismatchParamTargetsMethodReturn() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] - Type M(Type t) { - return t; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + Type M(Type t) { + return t; + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] - Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type t) { - return t; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type t) { + return t; + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(8,10): warning IL2068: 'C.M(Type)' method return value does not satisfy 'DynamicallyAccessedMemberTypes.All' requirements. The parameter 't' of method 'C.M(Type)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsMethodReturnType) - .WithSpan (8, 10, 8, 11) - .WithSpan (7, 9, 7, 15) - .WithArguments ("C.M(Type)", + // /0/Test0.cs(8,10): warning IL2068: 'C.M(Type)' method return value does not satisfy 'DynamicallyAccessedMemberTypes.All' requirements. The parameter 't' of method 'C.M(Type)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsMethodReturnType) + .WithSpan(8, 16, 8, 17) + .WithSpan(7, 12, 7, 18) + .WithArguments("C.M(Type)", "t", "C.M(Type)", "'DynamicallyAccessedMemberTypes.All'") @@ -260,22 +260,22 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2068_ArgumentTurnsOffCodeFix_None() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] - Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.None)] Type t) { - return t; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.None)] Type t) { + return t; + } + } + """; var diag = new[] { - // /0/Test0.cs(8,10): warning IL2068: 'C.M(Type)' method return value does not satisfy 'DynamicallyAccessedMemberTypes.All' requirements. The parameter 't' of method 'C.M(Type)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsMethodReturnType) - .WithSpan (8, 10, 8, 11) - .WithArguments ("C.M(Type)", + // /0/Test0.cs(8,10): warning IL2068: 'C.M(Type)' method return value does not satisfy 'DynamicallyAccessedMemberTypes.All' requirements. The parameter 't' of method 'C.M(Type)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsMethodReturnType) + .WithSpan(8, 16, 8, 17) + .WithArguments("C.M(Type)", "t", "C.M(Type)", "'DynamicallyAccessedMemberTypes.All'") @@ -287,57 +287,57 @@ Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.None)] Type t) public async Task CodeFix_IL2069_MismatchParamTargetsField_PublicMethods() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M(typeof(C)); - } - - private static void M(Type type) - { - f = type; - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f = typeof(C); - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M(typeof(C)); + } + + private static void M(Type type) + { + f = type; + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f = typeof(C); + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M(typeof(C)); - } - - private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - f = type; - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f = typeof(C); - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M(typeof(C)); + } + + private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + f = type; + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f = typeof(C); + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(13,3): warning IL2069: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. - //The parameter 'type' of method 'C.M(Type)' does not have matching annotations. - //The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsField) - .WithSpan(13, 3, 13, 11) - .WithSpan(11, 24, 11, 33) - .WithArguments ("C.f", + // /0/Test0.cs(13,3): warning IL2069: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + //The parameter 'type' of method 'C.M(Type)' does not have matching annotations. + //The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsField) + .WithSpan(13, 9, 13, 17) + .WithSpan(11, 27, 11, 36) + .WithArguments("C.f", "type", "C.M(Type)", "'DynamicallyAccessedMemberTypes.PublicMethods'") @@ -349,45 +349,45 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2070_MismatchParamTargetsThisParam_PublicMethods() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M(typeof(C)); - } - static void M(Type t) - { - t.GetMethods(); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M(typeof(C)); + } + static void M(Type t) + { + t.GetMethods(); + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M(typeof(C)); - } - static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) - { - t.GetMethods(); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M(typeof(C)); + } + static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + t.GetMethods(); + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(12,3): warning IL2070: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'. The parameter 't' of method 'C.M(Type)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsThisParameter) - .WithSpan(12, 3, 12, 17) - .WithSpan(10, 16, 10, 22) + // /0/Test0.cs(12,3): warning IL2070: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'. The parameter 't' of method 'C.M(Type)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsThisParameter) + .WithSpan(12, 9, 12, 23) + .WithSpan(10, 19, 10, 25) .WithArguments("System.Type.GetMethods()", "t", "C.M(Type)", @@ -400,61 +400,61 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2070_NonPublicMethods() { var test = $$""" - using System; - using System.Reflection; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M(typeof(C)); - } - static void M(Type t) - { - t.GetMethods(BindingFlags.NonPublic); - } - } - """; + using System; + using System.Reflection; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M(typeof(C)); + } + static void M(Type t) + { + t.GetMethods(BindingFlags.NonPublic); + } + } + """; var fixtest = $$""" - using System; - using System.Reflection; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M(typeof(C)); - } - static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) - { - t.GetMethods(BindingFlags.NonPublic); - } - } - """; + using System; + using System.Reflection; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M(typeof(C)); + } + static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) + { + t.GetMethods(BindingFlags.NonPublic); + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(13,3): warning IL2070: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Type.GetMethods(BindingFlags)'. - // The parameter 't' of method 'C.M(Type)' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsThisParameter) - .WithSpan(13, 3, 13, 39) - .WithSpan(11, 16, 11, 22) + // /0/Test0.cs(13,3): warning IL2070: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Type.GetMethods(BindingFlags)'. + // The parameter 't' of method 'C.M(Type)' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsThisParameter) + .WithSpan(13, 9, 13, 45) + .WithSpan(11, 19, 11, 25) .WithArguments("System.Type.GetMethods(BindingFlags)", "t", "C.M(Type)", "'DynamicallyAccessedMemberTypes.NonPublicMethods'") }, fixedExpected: new[] { - // /0/Test0.cs(9,3): warning IL2111: Method 'C.M(Type)' with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. - // Trimmer can't guarantee availability of the requirements of the method. - VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMethodAccessedViaReflection) - .WithSpan (9, 3, 9, 15) - .WithArguments ("C.M(Type)") + // /0/Test0.cs(9,3): warning IL2111: Method 'C.M(Type)' with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. + // Trimmer can't guarantee availability of the requirements of the method. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMethodAccessedViaReflection) + .WithSpan(9, 9, 9, 21) + .WithArguments("C.M(Type)") }); } @@ -462,55 +462,55 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2070_GetMethodsInArg() { var test = $$""" - using System.Reflection; - using System.Diagnostics.CodeAnalysis; - - namespace System - { - static class C - { - static void Main(Type t) - { - DoSomethingWithMethods(t.GetMethods()); - } - - static void DoSomethingWithMethods(MethodInfo[] m) - { - } - } - } - """; + using System.Reflection; + using System.Diagnostics.CodeAnalysis; + + namespace System + { + static class C + { + static void Main(Type t) + { + DoSomethingWithMethods(t.GetMethods()); + } + + static void DoSomethingWithMethods(MethodInfo[] m) + { + } + } + } + """; var fixtest = """ - using System.Reflection; - using System.Diagnostics.CodeAnalysis; - - namespace System - { - static class C - { - static void Main([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) - { - DoSomethingWithMethods(t.GetMethods()); - } - - static void DoSomethingWithMethods(MethodInfo[] m) - { - } - } - } - """; + using System.Reflection; + using System.Diagnostics.CodeAnalysis; + + namespace System + { + static class C + { + static void Main([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + DoSomethingWithMethods(t.GetMethods()); + } + + static void DoSomethingWithMethods(MethodInfo[] m) + { + } + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(10,27): warning IL2070: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'. - // The parameter 't' of method 'System.C.Main(Type)' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsThisParameter) - .WithSpan(10, 27, 10, 41) - .WithSpan(8, 20, 8, 26) + // /0/Test0.cs(10,27): warning IL2070: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'. + // The parameter 't' of method 'System.C.Main(Type)' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsThisParameter) + .WithSpan(10, 36, 10, 50) + .WithSpan(8, 26, 8, 32) .WithArguments("System.Type.GetMethods()", "t", "System.C.Main(Type)", @@ -523,62 +523,62 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2072_MismatchMethodReturnTargetsParam() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - NeedsPublicMethodsOnParameter(GetC()); - } - - private static void NeedsPublicMethodsOnParameter( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - - private static Type GetC() - { - return typeof(C); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + NeedsPublicMethodsOnParameter(GetC()); + } + + private static void NeedsPublicMethodsOnParameter( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + + private static Type GetC() + { + return typeof(C); + } + } + """; var fixtest = """ - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - NeedsPublicMethodsOnParameter(GetC()); - } - - private static void NeedsPublicMethodsOnParameter( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type GetC() - { - return typeof(C); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + NeedsPublicMethodsOnParameter(GetC()); + } + + private static void NeedsPublicMethodsOnParameter( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type GetC() + { + return typeof(C); + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(8,3): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethodsOnParameter(Type)'. - // The return value of method 'C.GetT()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) - .WithSpan(8, 3, 8, 40) - .WithSpan(16, 2, 19, 3) + // /0/Test0.cs(8,3): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethodsOnParameter(Type)'. + // The return value of method 'C.GetT()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) + .WithSpan(8, 9, 8, 46) + .WithSpan(16, 5, 19, 6) .WithArguments("type", "C.NeedsPublicMethodsOnParameter(Type)", "C.GetC()", @@ -591,62 +591,62 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2072_MismatchMethodReturnTargetsParam_WithAttributes() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - NeedsPublicMethodsOnParameter(GetC(typeof(C))); - } - - private static void NeedsPublicMethodsOnParameter( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) - { - } - - private static Type GetC([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) - { - return t; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + NeedsPublicMethodsOnParameter(GetC(typeof(C))); + } + + private static void NeedsPublicMethodsOnParameter( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + } + + private static Type GetC([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + return t; + } + } + """; var fixtest = """ - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - NeedsPublicMethodsOnParameter(GetC(typeof(C))); - } - - private static void NeedsPublicMethodsOnParameter( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) - { - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type GetC([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) - { - return t; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + NeedsPublicMethodsOnParameter(GetC(typeof(C))); + } + + private static void NeedsPublicMethodsOnParameter( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type GetC([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + return t; + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(8,3): warning IL2072: 't' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethodsOnParameter(Type)'. - // The return value of method 'C.GetC(Type)' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) - .WithSpan(8, 3, 8, 49) - .WithSpan(16, 2, 19, 3) + // /0/Test0.cs(8,3): warning IL2072: 't' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethodsOnParameter(Type)'. + // The return value of method 'C.GetC(Type)' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) + .WithSpan(8, 9, 8, 55) + .WithSpan(16, 5, 19, 6) .WithArguments("t", "C.NeedsPublicMethodsOnParameter(Type)", "C.GetC(Type)", @@ -659,34 +659,34 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2072_AttributeTurnsOffCodeFix_None() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - NeedsPublicMethodsOnParameter(GetC()); - } - - private static void NeedsPublicMethodsOnParameter( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.None)] - private static Type GetC() - { - return typeof(C); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + NeedsPublicMethodsOnParameter(GetC()); + } + + private static void NeedsPublicMethodsOnParameter( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.None)] + private static Type GetC() + { + return typeof(C); + } + } + """; var diag = new[] { - // /0/Test0.cs(8,3): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethodsOnParameter(Type)'. - // The return value of method 'C.GetT()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) - .WithSpan(8, 3, 8, 40) + // /0/Test0.cs(8,3): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethodsOnParameter(Type)'. + // The return value of method 'C.GetT()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) + .WithSpan(8, 9, 8, 46) .WithArguments("type", "C.NeedsPublicMethodsOnParameter(Type)", "C.GetC()", @@ -699,34 +699,34 @@ private static Type GetC() public async Task CodeFix_IL2072_AttributeTurnsOffCodeFix() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - NeedsPublicMethodsOnParameter(GetT()); - } - - private static void NeedsPublicMethodsOnParameter( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] - private static Type GetT() - { - return typeof(C); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + NeedsPublicMethodsOnParameter(GetT()); + } + + private static void NeedsPublicMethodsOnParameter( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] + private static Type GetT() + { + return typeof(C); + } + } + """; var diag = new[] { - // /0/Test0.cs(8,3): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethodsOnParameter(Type)'. - // The return value of method 'C.GetT()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) - .WithSpan(8, 3, 8, 40) + // /0/Test0.cs(8,3): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethodsOnParameter(Type)'. + // The return value of method 'C.GetT()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) + .WithSpan(8, 9, 8, 46) .WithArguments("type", "C.NeedsPublicMethodsOnParameter(Type)", "C.GetT()", @@ -739,46 +739,46 @@ private static Type GetT() public async Task CodeFix_IL2073_MismatchMethodReturnTargetsMethodReturn() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C { - Type Main(Type t) { - return t; - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - Type M() { - return Main(typeof(C)); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C { + Type Main(Type t) { + return t; + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + Type M() { + return Main(typeof(C)); + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - Type Main([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { - return t; - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - Type M() { - return Main(typeof(C)); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + Type Main([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { + return t; + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + Type M() { + return Main(typeof(C)); + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(11,10): warning IL2073: 'C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. - // The return value of method 'C.Main(Type)' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsMethodReturnType) - .WithSpan(11, 10, 11, 25) - .WithSpan(5, 2, 7, 3) + // /0/Test0.cs(11,10): warning IL2073: 'C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The return value of method 'C.Main(Type)' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsMethodReturnType) + .WithSpan(11, 16, 11, 31) + .WithSpan(5, 5, 7, 6) .WithArguments("C.M()", "C.Main(Type)", "'DynamicallyAccessedMemberTypes.PublicMethods'") @@ -790,46 +790,46 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2073_MismatchMethodReturnTargetsMethodReturn_WithAttribute() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C { - Type Main([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { - return t; - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { - return Main(t); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C { + Type Main([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { + return t; + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { + return Main(t); + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - Type Main([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { - return t; - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { - return Main(t); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + Type Main([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { + return t; + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { + return Main(t); + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(11,10): warning IL2073: 'C.M(Type)' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. - // The return value of method 'C.Main(Type)' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsMethodReturnType) - .WithSpan(11, 10, 11, 17) - .WithSpan(5, 2, 7, 3) + // /0/Test0.cs(11,10): warning IL2073: 'C.M(Type)' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The return value of method 'C.Main(Type)' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsMethodReturnType) + .WithSpan(11, 16, 11, 23) + .WithSpan(5, 5, 7, 6) .WithArguments("C.M(Type)", "C.Main(Type)", "'DynamicallyAccessedMemberTypes.PublicMethods'") @@ -841,56 +841,56 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2074_MismatchMethodReturnTargetsField() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - f = M(); - } - - private static Type M() - { - return typeof(C); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f; - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + f = M(); + } + + private static Type M() + { + return typeof(C); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - f = M(); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type M() - { - return typeof(C); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f; - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + f = M(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type M() + { + return typeof(C); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(8,3): warning IL2074: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. - // The return value of method 'C.M()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsField) - .WithSpan(8, 3, 8, 10) - .WithSpan(11, 2, 14, 3) + // /0/Test0.cs(8,3): warning IL2074: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The return value of method 'C.M()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsField) + .WithSpan(8, 9, 8, 16) + .WithSpan(11, 5, 14, 6) .WithArguments("C.f", "C.M()", "'DynamicallyAccessedMemberTypes.PublicMethods'") @@ -903,51 +903,51 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2075_MethodReturnTargetsParam_PublicMethods() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - GetC().GetMethod("Foo"); - } - - private static Type GetC () - { - return typeof (C); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + GetC().GetMethod("Foo"); + } + + private static Type GetC() + { + return typeof(C); + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - GetC().GetMethod("Foo"); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type GetC () - { - return typeof (C); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + GetC().GetMethod("Foo"); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type GetC() + { + return typeof(C); + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(8,3): warning IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. - //The return value of method 'C.GetFoo()' does not have matching annotations. - //The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter) - .WithSpan(8, 3, 8, 26) - .WithSpan(11, 2, 14, 3) - .WithArguments ("System.Type.GetMethod(String)", + // /0/Test0.cs(8,3): warning IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. + //The return value of method 'C.GetFoo()' does not have matching annotations. + //The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter) + .WithSpan(8, 9, 8, 32) + .WithSpan(11, 5, 14, 6) + .WithArguments("System.Type.GetMethod(String)", "C.GetC()", "'DynamicallyAccessedMemberTypes.PublicMethods'") }, @@ -958,52 +958,52 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2075_MethodAttributeLeavesOnCodeFix() { var test = $$""" - namespace System - { - class C : TestSystemTypeBase - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - public static void Main() - { - GetC().GetMethod("Foo"); - } - - private static Type GetC () - { - return typeof(int); - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + public static void Main() + { + GetC().GetMethod("Foo"); + } + + private static Type GetC() + { + return typeof(int); + } + } + } + """; var fixtest = $$""" - namespace System - { - class C : TestSystemTypeBase - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - public static void Main() - { - GetC().GetMethod("Foo"); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type GetC () - { - return typeof(int); - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + public static void Main() + { + GetC().GetMethod("Foo"); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type GetC() + { + return typeof(int); + } + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), test), fixedSource: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), fixtest), baselineExpected: new[] { - // /0/Test0.cs(8,3): warning IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. - //The return value of method 'C.GetFoo()' does not have matching annotations. - //The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter) - .WithSpan(194, 4, 194, 27) - .WithSpan(197, 3, 200, 4) + // /0/Test0.cs(8,3): warning IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. + //The return value of method 'C.GetFoo()' does not have matching annotations. + //The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter) + .WithSpan(194, 13, 194, 36) + .WithSpan(197, 9, 200, 10) .WithArguments("System.Type.GetMethod(String)", "System.C.GetC()", "'DynamicallyAccessedMemberTypes.PublicMethods'") @@ -1015,52 +1015,52 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2075_MethodAttributeLeavesOnCodeFix_Reverse() { var test = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - GetC().GetMethod("Foo"); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - private static Type GetC () - { - return typeof(int); - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + GetC().GetMethod("Foo"); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + private static Type GetC() + { + return typeof(int); + } + } + } + """; var fixtest = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - GetC().GetMethod("Foo"); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type GetC () - { - return typeof(int); - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + GetC().GetMethod("Foo"); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type GetC() + { + return typeof(int); + } + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), test), fixedSource: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), fixtest), baselineExpected: new[] { - // /0/Test0.cs(8,3): warning IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. - //The return value of method 'C.GetFoo()' does not have matching annotations. - //The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter) - .WithSpan(193, 4, 193, 27) - .WithSpan(196, 3, 200, 4) + // /0/Test0.cs(8,3): warning IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. + //The return value of method 'C.GetFoo()' does not have matching annotations. + //The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter) + .WithSpan(193, 13, 193, 36) + .WithSpan(196, 9, 200, 10) .WithArguments("System.Type.GetMethod(String)", "System.C.GetC()", "'DynamicallyAccessedMemberTypes.PublicMethods'") @@ -1069,57 +1069,57 @@ await VerifyDynamicallyAccessedMembersCodeFix( } [Fact] - public async Task CodeFix_IL2075_ReutrnAttributeLeavesOnCodeFix() + public async Task CodeFix_IL2075_ReturnAttributeLeavesOnCodeFix() { var test = $$$""" - namespace System - { - class C : TestSystemTypeBase - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - public static string Main() - { - GetC().GetMethod("Foo"); - return "Foo"; - } - - private static Type GetC () - { - return typeof(int); - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + public static string Main() + { + GetC().GetMethod("Foo"); + return "Foo, test"; + } + + private static Type GetC() + { + return typeof(int); + } + } + } + """; var fixtest = $$""" - namespace System - { - class C : TestSystemTypeBase - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - public static string Main() - { - GetC().GetMethod("Foo"); - return "Foo"; - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type GetC () - { - return typeof(int); - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + public static string Main() + { + GetC().GetMethod("Foo"); + return "Foo, test"; + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type GetC() + { + return typeof(int); + } + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), test), fixedSource: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), fixtest), baselineExpected: new[] { - // /0/Test0.cs(8,3): warning IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. - //The return value of method 'C.GetFoo()' does not have matching annotations. - //The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter) - .WithSpan(194, 4, 194, 27) - .WithSpan(198, 3, 201, 4) + // /0/Test0.cs(8,3): warning IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. + //The return value of method 'C.GetFoo()' does not have matching annotations. + //The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter) + .WithSpan(194, 13, 194, 36) + .WithSpan(198, 9, 201, 10) .WithArguments("System.Type.GetMethod(String)", "System.C.GetC()", "'DynamicallyAccessedMemberTypes.PublicMethods'") @@ -1131,54 +1131,54 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2077_MismatchFieldTargetsParam() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - private static Type f = typeof(C); - - public static void Main() - { - NeedsPublicMethods(f); - } - - private static void NeedsPublicMethods( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + private static Type f = typeof(C); + + public static void Main() + { + NeedsPublicMethods(f); + } + + private static void NeedsPublicMethods( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f = typeof(C); - - public static void Main() - { - NeedsPublicMethods(f); - } - - private static void NeedsPublicMethods( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f = typeof(C); + + public static void Main() + { + NeedsPublicMethods(f); + } + + private static void NeedsPublicMethods( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(10,3): warning IL2077: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethods(Type)'. - // The field 'C.f' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsParameter) - .WithSpan(10, 3, 10, 24) - .WithSpan(6, 22, 6, 35) + // /0/Test0.cs(10,3): warning IL2077: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethods(Type)'. + // The field 'C.f' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsParameter) + .WithSpan(10, 9, 10, 30) + .WithSpan(6, 25, 6, 38) .WithArguments("type", "C.NeedsPublicMethods(Type)", "C.f", @@ -1192,31 +1192,31 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2077_AttributeTurnsOffCodeFix() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] - private static Type f = typeof(C); - - public static void Main() - { - NeedsPublicMethods(f); - } - - private static void NeedsPublicMethods( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] + private static Type f = typeof(C); + + public static void Main() + { + NeedsPublicMethods(f); + } + + private static void NeedsPublicMethods( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + } + """; var diag = new[] { - // /0/Test0.cs(11,3): warning IL2077: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethods(Type)'. - // The field 'C.f' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsParameter) - .WithSpan(11, 3, 11, 24) + // /0/Test0.cs(11,3): warning IL2077: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethods(Type)'. + // The field 'C.f' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsParameter) + .WithSpan(11, 9, 11, 30) .WithArguments("type", "C.NeedsPublicMethods(Type)", "C.f", @@ -1227,46 +1227,46 @@ private static void NeedsPublicMethods( public async Task CodeFix_IL2078_MismatchFieldTargetsMethodReturn() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - public static Type Main() - { - return f; - } - - private static Type f; - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + public static Type Main() + { + return f; + } + + private static Type f; + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - public static Type Main() - { - return f; - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f; - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + public static Type Main() + { + return f; + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(9,10): warning IL2078: 'C.Main()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. - // The field 'C.f' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsMethodReturnType) - .WithSpan(9, 10, 9, 11) - .WithSpan(12, 22, 12, 23) + // /0/Test0.cs(9,10): warning IL2078: 'C.Main()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The field 'C.f' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsMethodReturnType) + .WithSpan(9, 16, 9, 17) + .WithSpan(12, 25, 12, 26) .WithArguments("C.Main()", "C.f", "'DynamicallyAccessedMemberTypes.PublicMethods'") @@ -1278,27 +1278,27 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2078_AttributeTurnsOffCodeFix() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - public static Type Main() - { - return f; - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - private static Type f; - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + public static Type Main() + { + return f; + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + private static Type f; + } + """; var diag = new[] { - // /0/Test0.cs(9,10): warning IL2078: 'C.Main()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. - // The field 'C.f' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsMethodReturnType) - .WithSpan(9, 10, 9, 11) + // /0/Test0.cs(9,10): warning IL2078: 'C.Main()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The field 'C.f' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsMethodReturnType) + .WithSpan(9, 16, 9, 17) .WithArguments("C.Main()", "C.f", "'DynamicallyAccessedMemberTypes.PublicMethods'")}; @@ -1309,49 +1309,49 @@ public static Type Main() public async Task CodeFix_IL2079_MismatchFieldTargetsField() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - private static Type f1 = typeof(C); - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f2 = typeof(C); - - public static void Main() - { - f2 = f1; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + private static Type f1 = typeof(C); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f2 = typeof(C); + + public static void Main() + { + f2 = f1; + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f1 = typeof(C); - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f2 = typeof(C); - - public static void Main() - { - f2 = f1; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f1 = typeof(C); + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f2 = typeof(C); + + public static void Main() + { + f2 = f1; + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(13,3): warning IL2079: value stored in field 'C.f2' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. - // The field 'C.f1' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsField) - .WithSpan(13, 3, 13, 10) - .WithSpan(6, 22, 6, 36) + // /0/Test0.cs(13,3): warning IL2079: value stored in field 'C.f2' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The field 'C.f1' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsField) + .WithSpan(13, 9, 13, 16) + .WithSpan(6, 25, 6, 39) .WithArguments("C.f2", "C.f1", "'DynamicallyAccessedMemberTypes.PublicMethods'") @@ -1363,29 +1363,29 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2079_AttributeTurnsOffCodeFix() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - private static Type f1 = typeof(C); - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f2 = typeof(C); - - public static void Main() - { - f2 = f1; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + private static Type f1 = typeof(C); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f2 = typeof(C); + + public static void Main() + { + f2 = f1; + } + } + """; var diag = new[] { - // /0/Test0.cs(14,3): warning IL2079: value stored in field 'C.f2' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. - // The field 'C.f1' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsField) - .WithSpan(14, 3, 14, 10) + // /0/Test0.cs(14,3): warning IL2079: value stored in field 'C.f2' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The field 'C.f1' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsField) + .WithSpan(14, 9, 14, 16) .WithArguments("C.f2", "C.f1", "'DynamicallyAccessedMemberTypes.PublicMethods'") @@ -1397,44 +1397,44 @@ public static void Main() public async Task CodeFix_IL2080_MismatchFieldTargetsPrivateParam_PublicMethods() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - private static Type f = typeof(C); - - public static void Main() - { - f.GetMethod("Foo"); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + private static Type f = typeof(C); + + public static void Main() + { + f.GetMethod("Foo"); + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f = typeof(C); - - public static void Main() - { - f.GetMethod("Foo"); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f = typeof(C); + + public static void Main() + { + f.GetMethod("Foo"); + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(10,3): warning IL2080: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. - // The field 'C.f' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsThisParameter) - .WithSpan(10, 3, 10, 21) - .WithSpan(6, 22, 6, 35) + // /0/Test0.cs(10,3): warning IL2080: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. + // The field 'C.f' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsThisParameter) + .WithSpan(10, 9, 10, 27) + .WithSpan(6, 25, 6, 38) .WithArguments("System.Type.GetMethod(String)", "C.f", "'DynamicallyAccessedMemberTypes.PublicMethods'") @@ -1446,44 +1446,44 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2080_MismatchFieldTargetsPublicParam_PublicMethods() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static Type f = typeof(C); - - public static void Main() - { - f.GetMethod("Foo"); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static Type f = typeof(C); + + public static void Main() + { + f.GetMethod("Foo"); + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - public static Type f = typeof(C); - - public static void Main() - { - f.GetMethod("Foo"); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + public static Type f = typeof(C); + + public static void Main() + { + f.GetMethod("Foo"); + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(10,3): warning IL2080: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. - // The field 'C.f' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsThisParameter) - .WithSpan(10, 3, 10, 21) - .WithSpan(6, 21, 6, 34) + // /0/Test0.cs(10,3): warning IL2080: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. + // The field 'C.f' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsThisParameter) + .WithSpan(10, 9, 10, 27) + .WithSpan(6, 24, 6, 37) .WithArguments("System.Type.GetMethod(String)", "C.f", "'DynamicallyAccessedMemberTypes.PublicMethods'") @@ -1495,26 +1495,26 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2080_AttributeTurnsOffCodeFix() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - public static Type f = typeof(C); - - public static void Main() - { - f.GetMethod("Foo"); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + public static Type f = typeof(C); + + public static void Main() + { + f.GetMethod("Foo"); + } + } + """; var diag = new[] { - // /0/Test0.cs(11,3): warning IL2080: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. - // The field 'C.f' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsThisParameter) - .WithSpan(11, 3, 11, 21) + // /0/Test0.cs(11,3): warning IL2080: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. + // The field 'C.f' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsThisParameter) + .WithSpan(11, 9, 11, 27) .WithArguments("System.Type.GetMethod(String)", "C.f", "'DynamicallyAccessedMemberTypes.PublicMethods'") @@ -1526,69 +1526,69 @@ public static void Main() public async Task CodeFix_IL2082_MismatchThisParamTargetsParam() { var test = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - private void M1() - { - M2(this); - } - - private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) - { - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + private void M1() + { + M2(this); + } + + private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + } + } + } + """; var fixtest = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private void M1() - { - M2(this); - } - - private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) - { - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private void M1() + { + M2(this); + } + + private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + } + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), test), fixedSource: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), fixtest), baselineExpected: new[] { - // /0/Test0.cs(198,4): warning IL2082: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. - // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter) - .WithSpan(198, 4, 198, 12) - .WithSpan(196, 3, 199, 4) + // /0/Test0.cs(198,4): warning IL2082: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. + // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter) + .WithSpan(198, 13, 198, 21) + .WithSpan(196, 9, 199, 10) .WithArguments("t", "System.C.M2(Type)", "System.C.M1()", "'DynamicallyAccessedMemberTypes.PublicMethods'") }, fixedExpected: new[] { - // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined - // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. - VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) - .WithSpan(193, 4, 193, 16) + // /0/Test0.cs(193,13): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined + // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) + .WithSpan(193, 13, 193, 25) .WithArguments("System.C.M1()") }); } @@ -1597,73 +1597,73 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2082_ReturnKeepsOnCodeFix() { var test = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private string M1() - { - M2(this); - return "Foo"; - } - - private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) - { - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private string M1() + { + M2(this); + return "Foo, test"; + } + + private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + } + } + } + """; var fixtest = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private string M1() - { - M2(this); - return "Foo"; - } - - private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) - { - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private string M1() + { + M2(this); + return "Foo, test"; + } + + private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + } + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), test), fixedSource: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), fixtest), baselineExpected: new[] { - // /0/Test0.cs(198,4): warning IL2082: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. - // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter) - .WithSpan(199, 4, 199, 12) - .WithSpan(196, 3, 201, 4) + // /0/Test0.cs(198,4): warning IL2082: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. + // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter) + .WithSpan(199, 13, 199, 21) + .WithSpan(196, 9, 201, 10) .WithArguments("t", "System.C.M2(Type)", "System.C.M1()", "'DynamicallyAccessedMemberTypes.PublicMethods'") }, fixedExpected: new[] { - // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined - // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. - VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) - .WithSpan(193, 4, 193, 16) + // /0/Test0.cs(193,13): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined + // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) + .WithSpan(193, 13, 193, 25) .WithArguments("System.C.M1()") }); } @@ -1672,73 +1672,73 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2082_ParamAttributeKeepsOnCodeFix() { var test = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1("Foo"); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - private string M1([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] string s) - { - M2(this); - return s; - } - - private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) - { - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1("Foo, test"); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + private string M1([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] string s) + { + M2(this); + return s; + } + + private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + } + } + } + """; var fixtest = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1("Foo"); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private string M1([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] string s) - { - M2(this); - return s; - } - - private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) - { - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1("Foo, test"); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private string M1([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] string s) + { + M2(this); + return s; + } + + private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + } + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), test), fixedSource: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), fixtest), baselineExpected: new[] { - // /0/Test0.cs(198,4): warning IL2082: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. - // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter) - .WithSpan(199, 4, 199, 12) - .WithSpan(196, 3, 201, 4) + // /0/Test0.cs(198,4): warning IL2082: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. + // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter) + .WithSpan(199, 13, 199, 21) + .WithSpan(196, 9, 201, 10) .WithArguments("t", "System.C.M2(Type)", "System.C.M1(String)", "'DynamicallyAccessedMemberTypes.PublicMethods'") }, fixedExpected: new[] { - // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined - // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. - VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) - .WithSpan(193, 4, 193, 21) + // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1(String)' can not be statically determined + // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) + .WithSpan(193, 13, 193, 36) .WithArguments("System.C.M1(String)") }); } @@ -1747,41 +1747,41 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2082_AttributeTurnsOffCodeFix() { var test = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - private void M1() - { - M2(this); - } - - private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) - { - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + private void M1() + { + M2(this); + } + + private static void M2([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + } + } + } + """; var diag = new[] { - // /0/Test0.cs(199,4): warning IL2082: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. - // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter) - .WithSpan(199, 4, 199, 12) + // /0/Test0.cs(199,4): warning IL2082: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. + // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter) + .WithSpan(199, 13, 199, 21) .WithArguments("t", "System.C.M2(Type)", "System.C.M1()", "'DynamicallyAccessedMemberTypes.PublicMethods'"), - // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined - // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. - VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) - .WithSpan(193, 4, 193, 16) + // /0/Test0.cs(193,13): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined + // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) + .WithSpan(193, 13, 193, 25) .WithArguments("System.C.M1()") }; await VerifyDynamicallyAccessedMembersCodeFix(string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), test), @@ -1792,60 +1792,60 @@ await VerifyDynamicallyAccessedMembersCodeFix(string.Concat(DynamicallyAccessedM public async Task CodeFix_IL2083_MismatchThisParamTargetsMethodReturn() { var test = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private Type M1() - { - return this; - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private Type M1() + { + return this; + } + } + } + """; var fixtest = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private Type M1() - { - return this; - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private Type M1() + { + return this; + } + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), test), fixedSource: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), fixtest), baselineExpected: new[] { - // /0/Test0.cs(199,11): warning IL2083: 'System.C.M1()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsMethodReturnType) - .WithSpan(199, 11, 199, 15) - .WithSpan(196, 3, 200, 4) + // /0/Test0.cs(199,11): warning IL2083: 'System.C.M1()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsMethodReturnType) + .WithSpan(199, 20, 199, 24) + .WithSpan(196, 9, 200, 10) .WithArguments("System.C.M1()", "System.C.M1()", "'DynamicallyAccessedMemberTypes.PublicMethods'") }, fixedExpected: new[] { - // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined - // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. - VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) - .WithSpan(193, 4, 193, 16) + // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined + // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) + .WithSpan(193, 13, 193, 25) .WithArguments("System.C.M1()") }); } @@ -1854,62 +1854,62 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2083_ParamAttributeKeepsCodeFix() { var test = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1("Foo"); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private Type M1([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] string s) - { - s.AsSpan(); - return this; - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1("Foo, test"); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private Type M1([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] string s) + { + s.AsSpan(); + return this; + } + } + } + """; var fixtest = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1("Foo"); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private Type M1([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] string s) - { - s.AsSpan(); - return this; - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1("Foo, test"); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private Type M1([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] string s) + { + s.AsSpan(); + return this; + } + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), test), fixedSource: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), fixtest), baselineExpected: new[] { - // /0/Test0.cs(199,11): warning IL2083: 'System.C.M1()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsMethodReturnType) - .WithSpan(200, 11, 200, 15) - .WithSpan(196, 3, 201, 4) + // /0/Test0.cs(199,11): warning IL2083: 'System.C.M1()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsMethodReturnType) + .WithSpan(200, 20, 200, 24) + .WithSpan(196, 9, 201, 10) .WithArguments("System.C.M1(String)", "System.C.M1(String)", "'DynamicallyAccessedMemberTypes.PublicMethods'") }, fixedExpected: new[] { - // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined - // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. - VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) - .WithSpan(193, 4, 193, 21) + // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined + // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) + .WithSpan(193, 13, 193, 36) .WithArguments("System.C.M1(String)") }); } @@ -1918,35 +1918,35 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2083_AttributeTurnsOffCodeFix() { var test = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] - private Type M1() - { - return this; - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] + private Type M1() + { + return this; + } + } + } + """; var diag = new[] { - // /0/Test0.cs(200,11): warning IL2083: 'System.C.M1()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsMethodReturnType) - .WithSpan(200, 11, 200, 15) + // /0/Test0.cs(200,11): warning IL2083: 'System.C.M1()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsMethodReturnType) + .WithSpan(200, 20, 200, 24) .WithArguments("System.C.M1()", "System.C.M1()", "'DynamicallyAccessedMemberTypes.PublicMethods'"), - // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined - // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. - VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) - .WithSpan(193, 4, 193, 16) + // /0/Test0.cs(193,13): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined + // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) + .WithSpan(193, 13, 193, 25) .WithArguments("System.C.M1()") }; await VerifyDynamicallyAccessedMembersCodeFix(string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), test), @@ -1958,66 +1958,66 @@ await VerifyDynamicallyAccessedMembersCodeFix(string.Concat(DynamicallyAccessedM public async Task CodeFix_IL2084_MismatchThisParamTargetsField() { var test = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M(); - } - - private void M() - { - f = this; - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f; - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M(); + } + + private void M() + { + f = this; + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; + } + } + """; var fixtest = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M(); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private void M() - { - f = this; - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f; - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private void M() + { + f = this; + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), test), fixedSource: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), fixtest), baselineExpected: new[] { - // /0/Test0.cs(198,4): warning IL2084: value stored in field 'System.C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. - // The implicit 'this' argument of method 'System.C.M()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsField) - .WithSpan(198, 4, 198, 12) - .WithSpan(196, 3, 199, 4) + // /0/Test0.cs(198,4): warning IL2084: value stored in field 'System.C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The implicit 'this' argument of method 'System.C.M()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsField) + .WithSpan(198, 13, 198, 21) + .WithSpan(196, 9, 199, 10) .WithArguments("System.C.f", "System.C.M()", "'DynamicallyAccessedMemberTypes.PublicMethods'") }, fixedExpected: new[] { - // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M()' can not be statically determined - // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. - VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) - .WithSpan(193, 4, 193, 15) + // /0/Test0.cs(193,13): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M()' can not be statically determined + // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) + .WithSpan(193, 13, 193, 24) .WithArguments("System.C.M()") }); } @@ -2026,70 +2026,70 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2085_MismatchThisParamTargetsThisParam() { var test = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - private void M1() - { - this.M2(); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private void M2() - { - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + private void M1() + { + this.M2(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private void M2() + { + } + } + } + """; var fixtest = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private void M1() - { - this.M2(); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private void M2() - { - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private void M1() + { + this.M2(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private void M2() + { + } + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), test), fixedSource: string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), fixtest), baselineExpected: new[] { - // /0/Test0.cs(198,4): warning IL2085: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2()'. - // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsThisParameter) - .WithSpan(198, 4, 198, 13) - .WithSpan(196, 3, 199, 4) + // /0/Test0.cs(198,4): warning IL2085: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2()'. + // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsThisParameter) + .WithSpan(198, 13, 198, 22) + .WithSpan(196, 9, 199, 10) .WithArguments("System.C.M2()", "System.C.M1()", "'DynamicallyAccessedMemberTypes.PublicMethods'") }, fixedExpected: new[] { - // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined - // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. - VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) - .WithSpan(193, 4, 193, 16) + // /0/Test0.cs(193,13): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined + // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) + .WithSpan(193, 13, 193, 25) .WithArguments("System.C.M1()") }); } @@ -2098,41 +2098,41 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2085_AttributeTurnsOffCodeFix() { var test = $$""" - namespace System - { - class C : TestSystemTypeBase - { - public static void Main() - { - new C().M1(); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] - private void M1() - { - this.M2(); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private void M2() - { - } - } - } - """; + namespace System + { + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] + private void M1() + { + this.M2(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private void M2() + { + } + } + } + """; var diag = new[] { - // /0/Test0.cs(199,4): warning IL2085: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2()'. - // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsThisParameter) - .WithSpan(199, 4, 199, 13) + // /0/Test0.cs(199,4): warning IL2085: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2()'. + // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsThisParameter) + .WithSpan(199, 13, 199, 22) .WithArguments("System.C.M2()", "System.C.M1()", "'DynamicallyAccessedMemberTypes.PublicMethods'"), - // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined - // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. - VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) - .WithSpan(193, 4, 193, 16) + // /0/Test0.cs(193,4): warning IL2065: Value passed to implicit 'this' parameter of method 'System.C.M1()' can not be statically determined + // and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic(DiagnosticId.ImplicitThisCannotBeStaticallyDetermined) + .WithSpan(193, 13, 193, 25) .WithArguments("System.C.M1()") }; await VerifyDynamicallyAccessedMembersCodeFix(string.Concat(DynamicallyAccessedMembersAnalyzerTests.GetSystemTypeBase(), test), @@ -2143,59 +2143,59 @@ await VerifyDynamicallyAccessedMembersCodeFix(string.Concat(DynamicallyAccessedM public async Task CodeFix_IL2087_MismatchTypeArgumentTargetsParameter() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M2(); - } - - private static void M1( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - - private static void M2() - { - M1(typeof(T)); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M2(); + } + + private static void M1( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + + private static void M2() + { + M1(typeof(T)); + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M2(); - } - - private static void M1( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) - { - } - - private static void M2<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() - { - M1(typeof(T)); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M2(); + } + + private static void M1( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + + private static void M2<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() + { + M1(typeof(T)); + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(18,3): warning IL2087: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.M1(Type)'. - // The generic parameter 'T' of 'C.M2()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsParameter) - .WithSpan(18, 3, 18, 16) - .WithSpan(16, 25, 16, 26) + // /0/Test0.cs(18,3): warning IL2087: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.M1(Type)'. + // The generic parameter 'T' of 'C.M2()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsParameter) + .WithSpan(18, 9, 18, 22) + .WithSpan(16, 28, 16, 29) .WithArguments("type", "C.M1(Type)", "T", @@ -2209,51 +2209,51 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2088_MismatchTypeArgumentTargetsMethodReturnType() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M(); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - private static Type M() - { - return typeof(T); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + private static Type M() + { + return typeof(T); + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M(); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - private static Type M<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>() - { - return typeof(T); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + private static Type M<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>() + { + return typeof(T); + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(14,10): warning IL2088: 'C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' requirements. - // The generic parameter 'T' of 'C.M()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType) - .WithSpan(14, 10, 14, 19) - .WithSpan(12, 24, 12, 25) + // /0/Test0.cs(14,10): warning IL2088: 'C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' requirements. + // The generic parameter 'T' of 'C.M()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType) + .WithSpan(14, 16, 14, 25) + .WithSpan(12, 27, 12, 28) .WithArguments("C.M()", "T", "C.M()", @@ -2266,29 +2266,29 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2088_AttributeTurnsOffCodeFix() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M(); - } - - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - private static Type M<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() - { - return typeof(T); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + private static Type M<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() + { + return typeof(T); + } + } + """; var diag = new[] { - // /0/Test0.cs(14,10): warning IL2088: 'C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' requirements. - // The generic parameter 'T' of 'C.M()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType) - .WithSpan(14, 10, 14, 19) + // /0/Test0.cs(14,10): warning IL2088: 'C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' requirements. + // The generic parameter 'T' of 'C.M()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType) + .WithSpan(14, 16, 14, 25) .WithArguments("C.M()", "T", "C.M()", @@ -2301,43 +2301,43 @@ public static void Main() public async Task CodeFix_IL2089_MismatchTypeArgumentTargetsField() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - f = typeof(T); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f; - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + f = typeof(T); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() - { - f = typeof(T); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f; - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() + { + f = typeof(T); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(8,3): warning IL2089: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. The generic parameter 'T' of 'C.Main()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsField) - .WithSpan(8, 3, 8, 16) - .WithSpan(6, 26, 6, 27) + // /0/Test0.cs(8,3): warning IL2089: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. The generic parameter 'T' of 'C.Main()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsField) + .WithSpan(8, 9, 8, 22) + .WithSpan(6, 29, 6, 30) .WithArguments("C.f", "T", "C.Main()", @@ -2350,24 +2350,24 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2089_AttributeTurnsOffCodeFix() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] T>() - { - f = typeof(T); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type f; - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] T>() + { + f = typeof(T); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; + } + """; var diag = new[] { - // /0/Test0.cs(8,3): warning IL2089: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. The generic parameter 'T' of 'C.Main()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsField) - .WithSpan(8, 3, 8, 16) + // /0/Test0.cs(8,3): warning IL2089: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. The generic parameter 'T' of 'C.Main()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsField) + .WithSpan(8, 9, 8, 22) .WithArguments("C.f", "T", "C.Main()", @@ -2381,38 +2381,38 @@ class C public async Task CodeFix_IL2090_MismatchTypeArgumentTargetsThisParameter() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C { - - void M() - { - typeof(T).GetMethods(); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C { + + void M() + { + typeof(T).GetMethods(); + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T> { - - void M() - { - typeof(T).GetMethods(); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T> { + + void M() + { + typeof(T).GetMethods(); + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(8,3): warning IL2090: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'. - // The generic parameter 'T' of 'C' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsThisParameter) - .WithSpan(8, 3, 8, 25) + // /0/Test0.cs(8,3): warning IL2090: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'. + // The generic parameter 'T' of 'C' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsThisParameter) + .WithSpan(8, 9, 8, 31) .WithSpan(4, 9, 4, 10) .WithArguments("System.Type.GetMethods()", "T", @@ -2425,23 +2425,23 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2090_AttributeTurnsOffCodeFix() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - class C<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T> { + class C<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T> { - void M() - { - typeof(T).GetMethods(); - } - } - """; + void M() + { + typeof(T).GetMethods(); + } + } + """; var diag = new[] { - // /0/Test0.cs(8,3): warning IL2090: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'. - // The generic parameter 'T' of 'C' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsThisParameter) - .WithSpan(8, 3, 8, 25) + // /0/Test0.cs(8,3): warning IL2090: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'. + // The generic parameter 'T' of 'C' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsThisParameter) + .WithSpan(8, 9, 8, 31) .WithArguments("System.Type.GetMethods()", "T", "C", @@ -2454,23 +2454,23 @@ void M() public async Task CodeFix_IL2090_AttributeTurnsOffCodeFix_None() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - class C<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.None)] T> { + class C<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.None)] T> { - void M() - { - typeof(T).GetMethods(); - } - } - """; + void M() + { + typeof(T).GetMethods(); + } + } + """; var diag = new[] { - // /0/Test0.cs(8,3): warning IL2090: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'. - // The generic parameter 'T' of 'C' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsThisParameter) - .WithSpan(8, 3, 8, 25) + // /0/Test0.cs(8,3): warning IL2090: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'. + // The generic parameter 'T' of 'C' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsThisParameter) + .WithSpan(8, 9, 8, 31) .WithArguments("System.Type.GetMethods()", "T", "C", @@ -2483,55 +2483,55 @@ void M() public async Task CodeFix_IL2091_MismatchTypeTargetsGenericParameter() { var test = $$""" - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M2(); - } - - private static void M1<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() - { - } - - private static void M2() - { - M1(); - } - } - """; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M2(); + } + + private static void M1<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() + { + } + + private static void M2() + { + M1(); + } + } + """; var fixtest = $$""" - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M2(); - } - - private static void M1<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() - { - } - - private static void M2<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] S>() - { - M1(); - } - } - """; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M2(); + } + + private static void M1<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() + { + } + + private static void M2<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] S>() + { + M1(); + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(16,3): warning IL2091: 'T' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in 'C.M1()'. - // The generic parameter 'S' of 'C.M2()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter) - .WithSpan(16, 3, 16, 10) - .WithSpan(14, 25, 14, 26) + // /0/Test0.cs(16,3): warning IL2091: 'T' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in 'C.M1()'. + // The generic parameter 'S' of 'C.M2()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter) + .WithSpan(16, 9, 16, 16) + .WithSpan(14, 28, 14, 29) .WithArguments("T", "C.M1()", "S", @@ -2545,31 +2545,31 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2091_AttributeTurnsOffCodeFix() { var test = $$""" - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - M2(); - } - - private static void M1<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() - { - } - - private static void M2<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.None)] S>() - { - M1(); - } - } - """; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + M2(); + } + + private static void M1<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() + { + } + + private static void M2<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.None)] S>() + { + M1(); + } + } + """; var diag = new[] { - // /0/Test0.cs(16,3): warning IL2091: 'T' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in 'C.M1()'. - // The generic parameter 'S' of 'C.M2()' does not have matching annotations. - // The source value must declare at least the same requirements as those declared on the target location it is assigned to. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter) - .WithSpan(16, 3, 16, 10) + // /0/Test0.cs(16,3): warning IL2091: 'T' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in 'C.M1()'. + // The generic parameter 'S' of 'C.M2()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter) + .WithSpan(16, 9, 16, 16) .WithArguments("T", "C.M1()", "S", @@ -2583,46 +2583,46 @@ public static void Main() public async Task CodeFix_IL2092_MismatchMethodParamBtOverride_NonPublicMethods() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Base - { - public virtual void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} - } - - public class C : Base - { - public override void M(Type t) {} - - public static void Main() { - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Base + { + public virtual void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} + } + + public class C : Base + { + public override void M(Type t) {} + + public static void Main() { + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Base - { - public virtual void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} - } - - public class C : Base - { - public override void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} - - public static void Main() { - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Base + { + public virtual void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} + } + + public class C : Base + { + public override void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} + + public static void Main() { + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix(test, fixtest, new[] { - // /0/Test0.cs(11,30): warning IL2092: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter 't' of method 'C.M(Type)' - // don't match overridden parameter 't' of method 'Base.M(Type)'. - // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides) - .WithSpan(11, 30, 11, 31) - .WithSpan(11, 30, 11, 31) + // /0/Test0.cs(11,30): warning IL2092: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter 't' of method 'C.M(Type)' + // don't match overridden parameter 't' of method 'Base.M(Type)'. + // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides) + .WithSpan(11, 33, 11, 34) + .WithSpan(11, 33, 11, 34) .WithArguments("t", "C.M(Type)", "t", @@ -2634,51 +2634,51 @@ await VerifyDynamicallyAccessedMembersCodeFix(test, fixtest, new[] { public async Task CodeFix_IL2092_MismatchMethodParamBtOverride_NonPublicMethods_Reverse() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class Base - { - public virtual void M(Type t) {} - } + public class Base + { + public virtual void M(Type t) {} + } - public class C : Base - { - public override void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} + public class C : Base + { + public override void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} - public static void Main() { + public static void Main() { - } - } - """; + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class Base - { - public virtual void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} - } + public class Base + { + public virtual void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} + } - public class C : Base - { - public override void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} + public class C : Base + { + public override void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} - public static void Main() { + public static void Main() { - } - } - """; + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(11,108): warning IL2092: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter 't' of method 'C.M(Type)' - // don't match overridden parameter 't' of method 'Base.M(Type)'. - // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides) - .WithSpan(11, 108, 11, 109) - .WithSpan(6, 29, 6, 30) + // /0/Test0.cs(11,108): warning IL2092: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter 't' of method 'C.M(Type)' + // don't match overridden parameter 't' of method 'Base.M(Type)'. + // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides) + .WithSpan(11, 111, 11, 112) + .WithSpan(6, 32, 6, 33) .WithArguments("t", "C.M(Type)", "t", @@ -2691,29 +2691,29 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2092_BothAttributesTurnOffCodeFix() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class Base - { - public virtual void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) {} - } + public class Base + { + public virtual void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) {} + } - public class C : Base - { - public override void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} + public class C : Base + { + public override void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} - public static void Main() { + public static void Main() { - } - } - """; + } + } + """; var diag = new[] { - // /0/Test0.cs(11,108): warning IL2092: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter 't' of method 'C.M(Type)' - // don't match overridden parameter 't' of method 'Base.M(Type)'. - // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides) - .WithSpan(11, 108, 11, 109) + // /0/Test0.cs(11,108): warning IL2092: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter 't' of method 'C.M(Type)' + // don't match overridden parameter 't' of method 'Base.M(Type)'. + // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides) + .WithSpan(11, 111, 11, 112) .WithArguments("t", "C.M(Type)", "t", @@ -2726,30 +2726,30 @@ public static void Main() { public async Task CodeFix_IL2092_TwoAttributesTurnOffCodeFix() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class Base - { - public virtual void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)] Type t) {} - } + public class Base + { + public virtual void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)] Type t) {} + } - public class C : Base - { - public override void M(Type t) {} + public class C : Base + { + public override void M(Type t) {} - public static void Main() { + public static void Main() { - } - } - """; + } + } + """; var diag = new[] { - // /0/Test0.cs(11,108): warning IL2092: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter 't' of method 'C.M(Type)' - // don't match overridden parameter 't' of method 'Base.M(Type)'. - // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides) - .WithSpan(11, 30, 11, 31) - .WithSpan(11, 30, 11, 31) + // /0/Test0.cs(11,108): warning IL2092: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter 't' of method 'C.M(Type)' + // don't match overridden parameter 't' of method 'Base.M(Type)'. + // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides) + .WithSpan(11, 33, 11, 34) + .WithSpan(11, 33, 11, 34) .WithArguments("t", "C.M(Type)", "t", @@ -2762,29 +2762,29 @@ public static void Main() { public async Task CodeFix_IL2092_BothAttributesTurnOffCodeFix_None() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class Base - { - public virtual void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.None)] Type t) {} - } + public class Base + { + public virtual void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.None)] Type t) {} + } - public class C : Base - { - public override void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} + public class C : Base + { + public override void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) {} - public static void Main() { + public static void Main() { - } - } - """; + } + } + """; var diag = new[] { - // /0/Test0.cs(11,108): warning IL2092: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter 't' of method 'C.M(Type)' - // don't match overridden parameter 't' of method 'Base.M(Type)'. - // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides) - .WithSpan(11, 108, 11, 109) + // /0/Test0.cs(11,108): warning IL2092: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter 't' of method 'C.M(Type)' + // don't match overridden parameter 't' of method 'Base.M(Type)'. + // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides) + .WithSpan(11, 111, 11, 112) .WithArguments("t", "C.M(Type)", "t", @@ -2797,60 +2797,60 @@ public static void Main() { public async Task CodeFix_IL2093_MismatchOnMethodReturnValueBetweenOverrides() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Base - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - public virtual Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { - return t; - } - } - - public class C : Base - { - public override Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { - return t; - } - - public static void Main() { - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Base + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + public virtual Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { + return t; + } + } + + public class C : Base + { + public override Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { + return t; + } + + public static void Main() { + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Base - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - public virtual Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { - return t; - } - } - - public class C : Base - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - public override Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { - return t; - } - - public static void Main() { - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Base + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + public virtual Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { + return t; + } + } + + public class C : Base + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + public override Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { + return t; + } + + public static void Main() { + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(14,23): warning IL2093: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the return value of method 'C.M(Type)' - // don't match overridden return value of method 'Base.M(Type)'. - // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides) - .WithSpan(14, 23, 14, 24) - .WithSpan(14, 23, 14, 24) + // /0/Test0.cs(14,23): warning IL2093: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the return value of method 'C.M(Type)' + // don't match overridden return value of method 'Base.M(Type)'. + // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides) + .WithSpan(14, 26, 14, 27) + .WithSpan(14, 26, 14, 27) .WithArguments("C.M(Type)", "Base.M(Type)") }, @@ -2861,60 +2861,60 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2093_MismatchOnMethodReturnValueBetweenOverrides_Reversed() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Base - { - public virtual Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { - return t; - } - } - - public class C : Base - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - public override Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { - return t; - } - - public static void Main() { - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Base + { + public virtual Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { + return t; + } + } + + public class C : Base + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + public override Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { + return t; + } + + public static void Main() { + } + } + """; var fixtest = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Base - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - public virtual Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { - return t; - } - } - - public class C : Base - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - public override Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { - return t; - } - - public static void Main() { - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Base + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + public virtual Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { + return t; + } + } + + public class C : Base + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + public override Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { + return t; + } + + public static void Main() { + } + } + """; await VerifyDynamicallyAccessedMembersCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(14,23): warning IL2093: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the return value of method 'C.M(Type)' - // don't match overridden return value of method 'Base.M(Type)'. - // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides) - .WithSpan(14, 23, 14, 24) - .WithSpan(6, 22, 6, 23) + // /0/Test0.cs(14,23): warning IL2093: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the return value of method 'C.M(Type)' + // don't match overridden return value of method 'Base.M(Type)'. + // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides) + .WithSpan(14, 26, 14, 27) + .WithSpan(6, 25, 6, 26) .WithArguments("C.M(Type)", "Base.M(Type)") }, @@ -2925,34 +2925,34 @@ await VerifyDynamicallyAccessedMembersCodeFix( public async Task CodeFix_IL2093_BothAttributesTurnOffCodeFix() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Base - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - public virtual Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { - return t; - } - } - - public class C : Base - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - public override Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { - return t; - } - - public static void Main() { - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Base + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + public virtual Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { + return t; + } + } + + public class C : Base + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + public override Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { + return t; + } + + public static void Main() { + } + } + """; var diag = new[] { - // /0/Test0.cs(15,23): warning IL2093: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the return value of method 'C.M(Type)' - // don't match overridden return value of method 'Base.M(Type)'. - // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides) - .WithSpan(15, 23, 15, 24) + // /0/Test0.cs(15,23): warning IL2093: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the return value of method 'C.M(Type)' + // don't match overridden return value of method 'Base.M(Type)'. + // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides) + .WithSpan(15, 26, 15, 27) .WithArguments("C.M(Type)", "Base.M(Type)") }; @@ -2963,34 +2963,34 @@ public static void Main() { public async Task CodeFix_IL2093_AttributesTurnOffCodeFix_None() { var test = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class Base - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.None)] - public virtual Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { - return t; - } - } - - public class C : Base - { - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - public override Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { - return t; - } - - public static void Main() { - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class Base + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.None)] + public virtual Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { + return t; + } + } + + public class C : Base + { + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] + public override Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type t) { + return t; + } + + public static void Main() { + } + } + """; var diag = new[] { - // /0/Test0.cs(15,23): warning IL2093: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the return value of method 'C.M(Type)' - // don't match overridden return value of method 'Base.M(Type)'. - // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. - VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides) - .WithSpan(15, 23, 15, 24) + // /0/Test0.cs(15,23): warning IL2093: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the return value of method 'C.M(Type)' + // don't match overridden return value of method 'Base.M(Type)'. + // All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. + VerifyCS.Diagnostic(DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides) + .WithSpan(15, 26, 15, 27) .WithArguments("C.M(Type)", "Base.M(Type)") }; diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ILLink.RoslynAnalyzer.Tests.csproj b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ILLink.RoslynAnalyzer.Tests.csproj index 8323dd02f82afd..184616fc012c10 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ILLink.RoslynAnalyzer.Tests.csproj +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ILLink.RoslynAnalyzer.Tests.csproj @@ -37,16 +37,12 @@ - - - - - + + + diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceAotCompatibilityTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceAotCompatibilityTests.cs new file mode 100644 index 00000000000000..e52afef7b692d2 --- /dev/null +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceAotCompatibilityTests.cs @@ -0,0 +1,76 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading.Tasks; +using ILLink.Shared; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; +using Xunit; +using System.IO; +using VerifyCS = ILLink.RoslynAnalyzer.Tests.CSharpCodeFixVerifier< + ILLink.RoslynAnalyzer.RequiresDynamicCodeAnalyzer, + ILLink.CodeFix.RequiresDynamicCodeCodeFixProvider>; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using ILLink.CodeFix; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public class ReferenceAotCompatibilityTests + { + [Fact] + public async Task EmitsWarningForReferenceWithoutIsAotCompatible_WhenPropertyEnabled() + { + var referencedSource = "public class ReferencedClass { }"; + var testSource = "public class MainClass { ReferencedClass c; }"; + + var test = ReferenceCompatibilityTestUtils.CreateTestWithReference( + testSource, referencedSource); + test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", Microsoft.CodeAnalysis.Text.SourceText.From($""" + is_global = true + build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.EnableAotAnalyzer} = true + build_property.VerifyReferenceAotCompatibility = true + """))); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DiagnosticId.ReferenceNotMarkedIsAotCompatible).WithArguments("ReferencedAssembly")); + await test.RunAsync(); + } + + [Fact] + public async Task DoesNotEmitWarning_WhenVerifyReferenceAotCompatibilityDisabled() + { + var referencedSource = "public class ReferencedClass { }"; + var testSource = "public class MainClass { ReferencedClass c; }"; + + var test = ReferenceCompatibilityTestUtils.CreateTestWithReference( + testSource, referencedSource); + test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", Microsoft.CodeAnalysis.Text.SourceText.From($""" + is_global = true + build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.EnableAotAnalyzer} = true + build_property.VerifyReferenceAotCompatibility = false + """))); + await test.RunAsync(); + } + + [Fact] + public async Task DoesNotEmitWarning_WhenReferenceMarkedIsAotCompatible() + { + var referencedSource = """ + [assembly: System.Reflection.AssemblyMetadata("IsAotCompatible", "True")] + public class ReferencedClass { } + """; + var testSource = "public class MainClass { ReferencedClass c; }"; + + var test = ReferenceCompatibilityTestUtils.CreateTestWithReference( + testSource, referencedSource); + test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", Microsoft.CodeAnalysis.Text.SourceText.From($""" + is_global = true + build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.EnableAotAnalyzer} = true + build_property.VerifyReferenceAotCompatibility = true + """))); + await test.RunAsync(); + } + } +} diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceCompatibilityTestUtils.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceCompatibilityTestUtils.cs new file mode 100644 index 00000000000000..a5169775cc45bc --- /dev/null +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceCompatibilityTestUtils.cs @@ -0,0 +1,55 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading.Tasks; +using ILLink.Shared; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; +using Xunit; +using System.IO; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public class ReferenceCompatibilityTestUtils + { + public static CSharpCodeFixVerifier.Test CreateTestWithReference(string mainSource, string referenceSource) + where TAnalyzer : DiagnosticAnalyzer, new() + where TCodeFix : Microsoft.CodeAnalysis.CodeFixes.CodeFixProvider, new() + { + var referencedMetadata = CreateReferencedMetadata(referenceSource); + var test = new CSharpCodeFixVerifier.Test + { + TestCode = mainSource + }; + test.SolutionTransforms.Add((solution, projectId) => + { + var project = solution.GetProject(projectId); + if (project is null) + return solution; + project = project.AddMetadataReference(referencedMetadata); + return project.Solution; + }); + return test; + + static MetadataReference CreateReferencedMetadata(string referencedSource) + { + var refs = SourceGenerators.Tests.LiveReferencePack.GetMetadataReferences(); + var referencedCompilation = CSharpCompilation.Create( + "ReferencedAssembly", + new[] { SyntaxFactory.ParseSyntaxTree(referencedSource) }, + refs, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + var referencedImage = new MemoryStream(); + referencedCompilation.Emit(referencedImage); + referencedImage.Position = 0; + return MetadataReference.CreateFromStream(referencedImage); + } + } + } +} diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceTrimCompatibilityTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceTrimCompatibilityTests.cs new file mode 100644 index 00000000000000..0a0951e51afc77 --- /dev/null +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/ReferenceTrimCompatibilityTests.cs @@ -0,0 +1,78 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading.Tasks; +using ILLink.Shared; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; +using Xunit; +using System.IO; +using ILLink.CodeFix; +using VerifyCS = ILLink.RoslynAnalyzer.Tests.CSharpCodeFixVerifier< + ILLink.RoslynAnalyzer.RequiresUnreferencedCodeAnalyzer, + ILLink.CodeFix.RequiresUnreferencedCodeCodeFixProvider>; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public class ReferenceTrimCompatibilityTests + { + [Fact] + public async Task EmitsWarningForReferenceWithoutIsTrimmable_WhenPropertyEnabled() + { + var referencedSource = "public class ReferencedClass { }"; + var testSource = "public class MainClass { ReferencedClass c; }"; + + var test = ReferenceCompatibilityTestUtils.CreateTestWithReference( + testSource, referencedSource); + test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", Microsoft.CodeAnalysis.Text.SourceText.From($""" + is_global = true + build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.EnableTrimAnalyzer} = true + build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.VerifyReferenceTrimCompatibility} = true + """))); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DiagnosticId.ReferenceNotMarkedIsTrimmable).WithArguments("ReferencedAssembly")); + await test.RunAsync(); + } + + [Fact] + public async Task DoesNotEmitWarning_WhenVerifyReferenceTrimCompatibilityDisabled() + { + var referencedSource = "public class ReferencedClass { }"; + var testSource = "public class MainClass { ReferencedClass c; }"; + + var test = ReferenceCompatibilityTestUtils.CreateTestWithReference( + testSource, referencedSource); + test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", Microsoft.CodeAnalysis.Text.SourceText.From($""" + is_global = true + build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.EnableTrimAnalyzer} = true + build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.VerifyReferenceTrimCompatibility} = false + """))); + + await test.RunAsync(); + } + + [Fact] + public async Task DoesNotEmitWarning_WhenReferenceMarkedIsTrimmable() + { + var referencedSource = """ + [assembly: System.Reflection.AssemblyMetadata("IsTrimmable", "True")] + public class ReferencedClass { } + """; + var testSource = "public class MainClass { ReferencedClass c; }"; + + var test = ReferenceCompatibilityTestUtils.CreateTestWithReference( + testSource, referencedSource); + test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", Microsoft.CodeAnalysis.Text.SourceText.From($""" + is_global = true + build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.EnableTrimAnalyzer} = true + build_property.{ILLink.RoslynAnalyzer.MSBuildPropertyOptionNames.VerifyReferenceTrimCompatibility} = true + """))); + + await test.RunAsync(); + } + } +} diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs index b97719b9d6e5b7..d5b0d230742e69 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs @@ -66,63 +66,63 @@ static Task VerifyRequiresAssemblyFilesCodeFix( public Task NoDynamicallyAccessedMembersWarningsIfOnlySingleFileAnalyzerIsEnabled() { var TargetParameterWithAnnotations = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - public static void Main() - { - MethodCallPattern(typeof(int)); - AssignmentPattern(typeof(int)); - ReflectionAccessPattern(); - FieldAccessPattern(); - GenericRequirement(); - } - - private static void NeedsPublicMethodsOnParameter( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type parameter) - { - } - - private static void MethodCallPattern(Type type) - { - NeedsPublicMethodsOnParameter(type); - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - private static Type NeedsPublicMethosOnField; - - private static void AssignmentPattern(Type type) - { - NeedsPublicMethosOnField = type; - } - - private static void ReflectionAccessPattern() - { - Action action = NeedsPublicMethodsOnParameter; - } - - private static void FieldAccessPattern() - { - var i = BeforeFieldInit.StaticField; - } - - [RequiresUnreferencedCode("BeforeFieldInit")] - class BeforeFieldInit { - public static int StaticField = 0; - } - - private static void GenericRequirement() - { - new NeedsPublicMethodsOnTypeParameter(); - } - - class NeedsPublicMethodsOnTypeParameter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T> - { - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + public static void Main() + { + MethodCallPattern(typeof(int)); + AssignmentPattern(typeof(int)); + ReflectionAccessPattern(); + FieldAccessPattern(); + GenericRequirement(); + } + + private static void NeedsPublicMethodsOnParameter( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type parameter) + { + } + + private static void MethodCallPattern(Type type) + { + NeedsPublicMethodsOnParameter(type); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type NeedsPublicMethosOnField; + + private static void AssignmentPattern(Type type) + { + NeedsPublicMethosOnField = type; + } + + private static void ReflectionAccessPattern() + { + Action action = NeedsPublicMethodsOnParameter; + } + + private static void FieldAccessPattern() + { + var i = BeforeFieldInit.StaticField; + } + + [RequiresUnreferencedCode("BeforeFieldInit")] + class BeforeFieldInit { + public static int StaticField = 0; + } + + private static void GenericRequirement() + { + new NeedsPublicMethodsOnTypeParameter(); + } + + class NeedsPublicMethodsOnTypeParameter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T> + { + } + } + """; return VerifyRequiresAssemblyFilesAnalyzer(TargetParameterWithAnnotations); } @@ -130,123 +130,123 @@ class NeedsPublicMethodsOnTypeParameter<[DynamicallyAccessedMembers(DynamicallyA public Task SimpleDiagnosticOnEvent() { var TestRequiresAssemblyFieldsOnEvent = $$""" - #nullable enable - using System.Diagnostics.CodeAnalysis; - - class C - { - [RequiresAssemblyFiles] - event System.EventHandler? E; - - void M() - { - E += (sender, e) => { }; - var evt = E; - } - } - """; + #nullable enable + using System.Diagnostics.CodeAnalysis; + + class C + { + [RequiresAssemblyFiles] + event System.EventHandler? E; + + void M() + { + E += (sender, e) => { }; + var evt = E; + } + } + """; return VerifyRequiresAssemblyFilesAnalyzer(TestRequiresAssemblyFieldsOnEvent, - // (11,17): warning IL3002: Using member 'C.E' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(11, 3, 11, 26).WithArguments("C.E.add", "", "")); + // (11,9): warning IL3002: Using member 'C.E.add' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(11, 9, 11, 32).WithArguments("C.E.add", "", "")); } [Fact] public Task SimpleDiagnosticOnProperty() { var TestRequiresAssemblyFilesOnProperty = $$""" - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - - class C - { - [RequiresAssemblyFiles] - bool P { get; set; } - - void M() - { - P = false; - List b = new List { P }; - } - } - """; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + + class C + { + [RequiresAssemblyFiles] + bool P { get; set; } + + void M() + { + P = false; + List b = new List { P }; + } + } + """; return VerifyRequiresAssemblyFilesAnalyzer(TestRequiresAssemblyFilesOnProperty, - // (11,3): warning IL3002: Using member 'C.P' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(11, 3, 11, 12).WithArguments("C.P.set", "", ""), - // (12,35): warning IL3002: Using member 'C.P' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(12, 35, 12, 36).WithArguments("C.P.get", "", "")); + // (11,9): warning IL3002: Using member 'C.P.set' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(11, 9, 11, 18).WithArguments("C.P.set", "", ""), + // (12,41): warning IL3002: Using member 'C.P.get' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(12, 41, 12, 42).WithArguments("C.P.get", "", "")); } [Fact] public Task CallDangerousMethodInsideProperty() { var TestRequiresAssemblyFilesOnMethodInsideProperty = $$""" - using System.Diagnostics.CodeAnalysis; - - class C - { - bool @field; - - [RequiresAssemblyFiles] - bool P { - get { - return @field; - } - set { - CallDangerousMethod (); - @field = value; - } - } - - [RequiresAssemblyFiles] - void CallDangerousMethod () {} - - void M () - { - P = false; - } - } - """; + using System.Diagnostics.CodeAnalysis; + + class C + { + bool @field; + + [RequiresAssemblyFiles] + bool P { + get { + return @field; + } + set { + CallDangerousMethod(); + @field = value; + } + } + + [RequiresAssemblyFiles] + void CallDangerousMethod() {} + + void M() + { + P = false; + } + } + """; return VerifyRequiresAssemblyFilesAnalyzer(TestRequiresAssemblyFilesOnMethodInsideProperty, - // (23,3): warning IL3002: Using member 'C.P' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(23, 3, 23, 12).WithArguments("C.P.set", "", "")); + // (23,9): warning IL3002: Using member 'C.P.set' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(23, 9, 23, 18).WithArguments("C.P.set", "", "")); } [Fact] public Task RequiresAssemblyFilesWithUrlOnly() { var TestRequiresAssemblyFilesWithMessageAndUrl = $$""" - using System.Diagnostics.CodeAnalysis; - - class C - { - [RequiresAssemblyFiles (Url = "https://helpurl")] - void M1() - { - } - - void M2() - { - M1(); - } - } - """; + using System.Diagnostics.CodeAnalysis; + + class C + { + [RequiresAssemblyFiles(Url = "https://helpurl")] + void M1() + { + } + + void M2() + { + M1(); + } + } + """; return VerifyRequiresAssemblyFilesAnalyzer(TestRequiresAssemblyFilesWithMessageAndUrl, - // (12,3): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. https://helpurl - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(12, 3, 12, 5).WithArguments("C.M1()", "", " https://helpurl")); + // (12,9): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. https://helpurl + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(12, 9, 12, 11).WithArguments("C.M1()", "", " https://helpurl")); } [Fact] public Task NoDiagnosticIfMethodNotCalled() { var TestNoDiagnosticIfMethodNotCalled = $$""" - using System.Diagnostics.CodeAnalysis; - - class C - { - [RequiresAssemblyFiles] - void M() { } - } - """; + using System.Diagnostics.CodeAnalysis; + + class C + { + [RequiresAssemblyFiles] + void M() { } + } + """; return VerifyRequiresAssemblyFilesAnalyzer(TestNoDiagnosticIfMethodNotCalled); } @@ -254,68 +254,68 @@ void M() { } public Task NoDiagnosticIsProducedIfCallerIsAnnotated() { var TestNoDiagnosticIsProducedIfCallerIsAnnotated = $$""" - using System.Diagnostics.CodeAnalysis; - - class C - { - void M1() - { - M2(); - } - - [RequiresAssemblyFiles ("Warn from M2")] - void M2() - { - M3(); - } - - [RequiresAssemblyFiles ("Warn from M3")] - void M3() - { - } - } - """; + using System.Diagnostics.CodeAnalysis; + + class C + { + void M1() + { + M2(); + } + + [RequiresAssemblyFiles("Warn from M2")] + void M2() + { + M3(); + } + + [RequiresAssemblyFiles("Warn from M3")] + void M3() + { + } + } + """; return VerifyRequiresAssemblyFilesAnalyzer(TestNoDiagnosticIsProducedIfCallerIsAnnotated, - // (7,3): warning IL3002: Using member 'C.M2()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. Warn from M2. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(7, 3, 7, 5).WithArguments("C.M2()", " Warn from M2.", "")); + // (7,9): warning IL3002: Using member 'C.M2()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. Warn from M2. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(7, 9, 7, 11).WithArguments("C.M2()", " Warn from M2.", "")); } [Fact] public Task GetExecutingAssemblyLocation() { const string src = $$""" - using System.Reflection; - class C - { - public string M() => Assembly.GetExecutingAssembly().Location; - } - """; + using System.Reflection; + class C + { + public string M() => Assembly.GetExecutingAssembly().Location; + } + """; return VerifyRequiresAssemblyFilesAnalyzer(src, // (5,26): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. - VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan(4, 23, 4, 63).WithArguments("System.Reflection.Assembly.Location.get")); + VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan(4, 26, 4, 66).WithArguments("System.Reflection.Assembly.Location.get")); } [Fact] public Task GetAssemblyLocationViaAssemblyProperties() { var src = $$""" - using System.Reflection; - class C - { - public void M() - { - var a = Assembly.GetExecutingAssembly(); - _ = a.Location; - // below methods are marked as obsolete in 5.0 - // _ = a.CodeBase; - // _ = a.EscapedCodeBase; - } - } - """; + using System.Reflection; + class C + { + public void M() + { + var a = Assembly.GetExecutingAssembly(); + _ = a.Location; + // below methods are marked as obsolete in 5.0 + // _ = a.CodeBase; + // _ = a.EscapedCodeBase; + } + } + """; return VerifyRequiresAssemblyFilesAnalyzer(src, - // (7,7): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. - VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan(7, 7, 7, 17).WithArguments("System.Reflection.Assembly.Location.get") + // (7,13): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. + VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan(7, 13, 7, 23).WithArguments("System.Reflection.Assembly.Location.get") ); } @@ -323,22 +323,22 @@ public void M() public Task CallKnownDangerousAssemblyMethods() { var src = $$""" - using System.Reflection; - class C - { - public void M() - { - var a = Assembly.GetExecutingAssembly(); - _ = a.GetFile("/some/file/path"); - _ = a.GetFiles(); - } - } - """; + using System.Reflection; + class C + { + public void M() + { + var a = Assembly.GetExecutingAssembly(); + _ = a.GetFile("/some/file/path"); + _ = a.GetFiles(); + } + } + """; return VerifyRequiresAssemblyFilesAnalyzer(src, - // (7,7): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest. - VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan(7, 7, 7, 16).WithArguments("System.Reflection.Assembly.GetFile(String)"), - // (8,7): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest. - VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan(8, 7, 8, 17).WithArguments("System.Reflection.Assembly.GetFiles()") + // (7,13): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest. + VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan(7, 13, 7, 22).WithArguments("System.Reflection.Assembly.GetFile(String)"), + // (8,13): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest. + VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan(8, 13, 8, 23).WithArguments("System.Reflection.Assembly.GetFiles()") ); } @@ -346,26 +346,26 @@ public void M() public Task CallKnownDangerousAssemblyNameAttributes() { var src = $$""" - using System.Reflection; - class C - { - public void M() - { - var a = Assembly.GetExecutingAssembly().GetName(); - _ = a.CodeBase; - _ = a.EscapedCodeBase; - } - } - """; + using System.Reflection; + class C + { + public void M() + { + var a = Assembly.GetExecutingAssembly().GetName(); + _ = a.CodeBase; + _ = a.EscapedCodeBase; + } + } + """; return VerifyRequiresAssemblyFilesAnalyzer(src, - // (7,7): warning SYSLIB0044: 'AssemblyName.CodeBase' is obsolete: 'AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported.' - DiagnosticResult.CompilerWarning("SYSLIB0044").WithSpan(7, 7, 7, 17).WithArguments("System.Reflection.AssemblyName.CodeBase", "AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported."), - // (8,7): warning SYSLIB0044: 'AssemblyName.EscapedCodeBase' is obsolete: 'AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported.' - DiagnosticResult.CompilerWarning("SYSLIB0044").WithSpan(8, 7, 8, 24).WithArguments("System.Reflection.AssemblyName.EscapedCodeBase", "AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported."), - // (7,7): warning IL3000: 'System.Reflection.AssemblyName.CodeBase' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. - VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan(7, 7, 7, 17).WithArguments("System.Reflection.AssemblyName.CodeBase.get"), - // (8,7): warning IL3000: 'System.Reflection.AssemblyName.EscapedCodeBase' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. - VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan(8, 7, 8, 24).WithArguments("System.Reflection.AssemblyName.EscapedCodeBase.get") + // (7,13): warning SYSLIB0044: 'AssemblyName.CodeBase' is obsolete: 'AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported.' + DiagnosticResult.CompilerWarning("SYSLIB0044").WithSpan(7, 13, 7, 23).WithArguments("System.Reflection.AssemblyName.CodeBase", "AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported."), + // (8,13): warning SYSLIB0044: 'AssemblyName.EscapedCodeBase' is obsolete: 'AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported.' + DiagnosticResult.CompilerWarning("SYSLIB0044").WithSpan(8, 13, 8, 30).WithArguments("System.Reflection.AssemblyName.EscapedCodeBase", "AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported."), + // (7,13): warning IL3000: 'System.Reflection.AssemblyName.CodeBase' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. + VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan(7, 13, 7, 23).WithArguments("System.Reflection.AssemblyName.CodeBase.get"), + // (8,13): warning IL3000: 'System.Reflection.AssemblyName.EscapedCodeBase' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. + VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan(8, 13, 8, 30).WithArguments("System.Reflection.AssemblyName.EscapedCodeBase.get") ); } @@ -375,22 +375,22 @@ public Task GetAssemblyLocationFalsePositive() // This is an OK use of Location and GetFile since these assemblies were loaded from // a file, but the analyzer is conservative var src = $$""" - using System.Reflection; - class C - { - public void M() - { - var a = Assembly.LoadFrom("/some/path/not/in/bundle"); - _ = a.Location; - _ = a.GetFiles(); - } - } - """; + using System.Reflection; + class C + { + public void M() + { + var a = Assembly.LoadFrom("/some/path/not/in/bundle"); + _ = a.Location; + _ = a.GetFiles(); + } + } + """; return VerifyRequiresAssemblyFilesAnalyzer(src, - // (7,7): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. - VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan(7, 7, 7, 17).WithArguments("System.Reflection.Assembly.Location.get"), - // (8,7): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest. - VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan(8, 7, 8, 17).WithArguments("System.Reflection.Assembly.GetFiles()") + // (7,13): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. + VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan(7, 13, 7, 23).WithArguments("System.Reflection.Assembly.Location.get"), + // (8,13): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest. + VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan(8, 13, 8, 23).WithArguments("System.Reflection.Assembly.GetFiles()") ); } @@ -398,15 +398,15 @@ public void M() public Task PublishSingleFileIsNotSet() { var src = $$""" - using System.Reflection; - class C - { - public void M() - { - var a = Assembly.GetExecutingAssembly().Location; - } - } - """; + using System.Reflection; + class C + { + public void M() + { + var a = Assembly.GetExecutingAssembly().Location; + } + } + """; // If 'PublishSingleFile' is not set to true, no diagnostics should be produced by the analyzer. This will // effectively verify that the number of produced diagnostics matches the number of expected ones (zero). return VerifyCS.VerifyAnalyzerAsync(src, consoleApplication: false); @@ -416,21 +416,21 @@ public void M() public Task SupressWarningsWithRequiresAssemblyFiles() { const string src = $$""" - using System.Reflection; - using System.Diagnostics.CodeAnalysis; - class C - { - [RequiresAssemblyFiles] - public void M() - { - var a = Assembly.GetExecutingAssembly(); - _ = a.Location; - var b = Assembly.GetExecutingAssembly(); - _ = b.GetFile("/some/file/path"); - _ = b.GetFiles(); - } - } - """; + using System.Reflection; + using System.Diagnostics.CodeAnalysis; + class C + { + [RequiresAssemblyFiles] + public void M() + { + var a = Assembly.GetExecutingAssembly(); + _ = a.Location; + var b = Assembly.GetExecutingAssembly(); + _ = b.GetFile("/some/file/path"); + _ = b.GetFiles(); + } + } + """; return VerifyRequiresAssemblyFilesAnalyzer(src); } @@ -439,69 +439,69 @@ public void M() public Task RequiresAssemblyFilesDiagnosticFix() { var test = $$""" - using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresAssemblyFiles("message")] - public int M1() => 0; - int M2() => M1(); - } - class D - { - public int M3(C c) => c.M1(); - public class E - { - public int M4(C c) => c.M1(); - } - } - public class E - { - public class F - { - public int M5(C c) => c.M1(); - } - } - """; + using System.Diagnostics.CodeAnalysis; + public class C + { + [RequiresAssemblyFiles("message")] + public int M1() => 0; + int M2() => M1(); + } + class D + { + public int M3(C c) => c.M1(); + public class E + { + public int M4(C c) => c.M1(); + } + } + public class E + { + public class F + { + public int M5(C c) => c.M1(); + } + } + """; var fixtest = $$""" - using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresAssemblyFiles("message")] - public int M1() => 0; - [RequiresAssemblyFiles("Calls C.M1()")] - int M2() => M1(); - } - class D - { - [RequiresAssemblyFiles("Calls C.M1()")] - public int M3(C c) => c.M1(); - public class E - { - [RequiresAssemblyFiles("Calls C.M1()")] - public int M4(C c) => c.M1(); - } - } - public class E - { - public class F - { - [RequiresAssemblyFiles()] - public int M5(C c) => c.M1(); - } - } - """; + using System.Diagnostics.CodeAnalysis; + public class C + { + [RequiresAssemblyFiles("message")] + public int M1() => 0; + [RequiresAssemblyFiles("Calls C.M1()")] + int M2() => M1(); + } + class D + { + [RequiresAssemblyFiles("Calls C.M1()")] + public int M3(C c) => c.M1(); + public class E + { + [RequiresAssemblyFiles("Calls C.M1()")] + public int M4(C c) => c.M1(); + } + } + public class E + { + public class F + { + [RequiresAssemblyFiles()] + public int M5(C c) => c.M1(); + } + } + """; return VerifyRequiresAssemblyFilesCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(6,14): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(6, 14, 6, 16).WithArguments("C.M1()", " message.", ""), - // /0/Test0.cs(10,24): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(10, 24, 10, 28).WithArguments("C.M1()", " message.", ""), - // /0/Test0.cs(13,25): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(13, 25, 13, 29).WithArguments("C.M1()", " message.", ""), - // /0/Test0.cs(20,25): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(20, 25, 20, 29).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(6,17): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(6, 17, 6, 19).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(10,27): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(10, 27, 10, 31).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(13,31): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(13, 31, 13, 35).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(20,31): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(20, 31, 20, 35).WithArguments("C.M1()", " message.", "") }, fixedExpected: Array.Empty()); } @@ -510,41 +510,41 @@ public class F public Task FixInSingleFileSpecialCases() { var test = $$""" - using System.Reflection; - using System.Diagnostics.CodeAnalysis; - public class C - { - public static Assembly assembly = Assembly.LoadFrom("/some/path/not/in/bundle"); - public string M1() => assembly.Location; - public void M2() { - _ = assembly.GetFiles(); - } - } - """; + using System.Reflection; + using System.Diagnostics.CodeAnalysis; + public class C + { + public static Assembly assembly = Assembly.LoadFrom("/some/path/not/in/bundle"); + public string M1() => assembly.Location; + public void M2() { + _ = assembly.GetFiles(); + } + } + """; var fixtest = $$""" - using System.Reflection; - using System.Diagnostics.CodeAnalysis; - public class C - { - public static Assembly assembly = Assembly.LoadFrom("/some/path/not/in/bundle"); - - [RequiresAssemblyFiles()] - public string M1() => assembly.Location; - - [RequiresAssemblyFiles()] - public void M2() { - _ = assembly.GetFiles(); - } - } - """; + using System.Reflection; + using System.Diagnostics.CodeAnalysis; + public class C + { + public static Assembly assembly = Assembly.LoadFrom("/some/path/not/in/bundle"); + + [RequiresAssemblyFiles()] + public string M1() => assembly.Location; + + [RequiresAssemblyFiles()] + public void M2() { + _ = assembly.GetFiles(); + } + } + """; return VerifyRequiresAssemblyFilesCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(6,24): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. - VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan (6, 24, 6, 41).WithArguments ("System.Reflection.Assembly.Location.get", "", ""), - // /0/Test0.cs(8,7): warning IL3001: 'System.Reflection.Assembly.GetFiles()' will throw for assemblies embedded in a single-file app - VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan (8, 7, 8, 24).WithArguments("System.Reflection.Assembly.GetFiles()", "", ""), + // /0/Test0.cs(6,27): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. + VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan(6, 27, 6, 44).WithArguments("System.Reflection.Assembly.Location.get"), + // /0/Test0.cs(8,13): warning IL3001: 'System.Reflection.Assembly.GetFiles()' will throw for assemblies embedded in a single-file app + VerifyCS.Diagnostic(DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan(8, 13, 8, 30).WithArguments("System.Reflection.Assembly.GetFiles()"), }, fixedExpected: Array.Empty()); } @@ -553,36 +553,36 @@ public void M2() { public Task FixInPropertyDecl() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresAssemblyFiles("message")] - public int M1() => 0; + public class C + { + [RequiresAssemblyFiles("message")] + public int M1() => 0; - int M2 => M1(); - } - """; + int M2 => M1(); + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresAssemblyFiles("message")] - public int M1() => 0; - - [RequiresAssemblyFiles("Calls C.M1()")] - int M2 => M1(); - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresAssemblyFiles("message")] + public int M1() => 0; + + [RequiresAssemblyFiles("Calls C.M1()")] + int M2 => M1(); + } + """; return VerifyRequiresAssemblyFilesCodeFix( source: src, fixedSource: fix, baselineExpected: new[] { - // /0/Test0.cs(9,12): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(9, 12, 9, 14).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(9,15): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(9, 15, 9, 17).WithArguments("C.M1()", " message.", "") }, fixedExpected: Array.Empty()); } @@ -591,47 +591,47 @@ public class C public Task FixInPropertyAccessor() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresAssemblyFilesAttribute("message")] - public int M1() => 0; - - public int field; - - private int M2 { - get { return M1(); } - set { field = M1(); } - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresAssemblyFilesAttribute("message")] + public int M1() => 0; + + public int field; + + private int M2 { + get { return M1(); } + set { field = M1(); } + } + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresAssemblyFilesAttribute("message")] - public int M1() => 0; + public class C + { + [RequiresAssemblyFilesAttribute("message")] + public int M1() => 0; - public int field; + public int field; - private int M2 { - [RequiresAssemblyFiles("Calls C.M1()")] - get { return M1(); } + private int M2 { + [RequiresAssemblyFiles("Calls C.M1()")] + get { return M1(); } - [RequiresAssemblyFiles("Calls C.M1()")] - set { field = M1(); } - } - } - """; + [RequiresAssemblyFiles("Calls C.M1()")] + set { field = M1(); } + } + } + """; var diag = new[] { - // /0/Test0.cs(12,16): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(12, 16, 12, 18).WithArguments("C.M1()", " message.", ""), - // /0/Test0.cs(13,17): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(13, 17, 13, 19).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(12,22): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(12, 22, 12, 24).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(13,23): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(13, 23, 13, 25).WithArguments("C.M1()", " message.", "") }; return VerifyRequiresAssemblyFilesCodeFix(src, fix, diag, Array.Empty()); } @@ -640,24 +640,24 @@ private int M2 { public Task FixInField() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - class C - { - public static Lazy _default = new Lazy(InitC); - public static C Default => _default.Value; - - [RequiresAssemblyFiles] - public static C InitC() { - C cObject = new C(); - return cObject; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + class C + { + public static Lazy _default = new Lazy(InitC); + public static C Default => _default.Value; + + [RequiresAssemblyFiles] + public static C InitC() { + C cObject = new C(); + return cObject; + } + } + """; var diag = new[] { - // /0/Test0.cs(5,47): warning IL3002: Using member 'C.InitC()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. - VerifyCS.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (5, 47, 5, 52).WithArguments ("C.InitC()", "", ""), + // /0/Test0.cs(5,50): warning IL3002: Using member 'C.InitC()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(5, 50, 5, 55).WithArguments("C.InitC()", "", ""), }; return VerifyRequiresAssemblyFilesCodeFix(src, src, diag, diag); } @@ -666,45 +666,45 @@ public static C InitC() { public Task FixInLocalFunc() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresAssemblyFiles("message")] - public int M1() => 0; - - Action M2() - { - void Wrapper () => M1(); - return Wrapper; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresAssemblyFiles("message")] + public int M1() => 0; + + Action M2() + { + void Wrapper() => M1(); + return Wrapper; + } + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresAssemblyFiles("message")] - public int M1() => 0; - - [RequiresAssemblyFiles("Calls Wrapper()")] - Action M2() - { - [RequiresAssemblyFiles("Calls C.M1()")] void Wrapper () => M1(); - return Wrapper; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresAssemblyFiles("message")] + public int M1() => 0; + + [RequiresAssemblyFiles("Calls Wrapper()")] + Action M2() + { + [RequiresAssemblyFiles("Calls C.M1()")] void Wrapper() => M1(); + return Wrapper; + } + } + """; // Roslyn currently doesn't simplify the attribute name properly, see https://github.com/dotnet/roslyn/issues/52039 return VerifyRequiresAssemblyFilesCodeFix( source: src, fixedSource: fix, baselineExpected: new[] { - // /0/Test0.cs(11,22): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(11, 22, 11, 24).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(11,27): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(11, 27, 11, 29).WithArguments("C.M1()", " message.", "") }, fixedExpected: Array.Empty(), numberOfIterations: 2); @@ -714,36 +714,36 @@ Action M2() public Task FixInCtor() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresAssemblyFiles("message")] - public int M1() => 0; + public class C + { + [RequiresAssemblyFiles("message")] + public int M1() => 0; - public C () => M1(); - } - """; + public C() => M1(); + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresAssemblyFiles("message")] - public int M1() => 0; - - [RequiresAssemblyFiles()] - public C () => M1(); - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresAssemblyFiles("message")] + public int M1() => 0; + + [RequiresAssemblyFiles()] + public C() => M1(); + } + """; return VerifyRequiresAssemblyFilesCodeFix( source: src, fixedSource: fix, baselineExpected: new[] { - // /0/Test0.cs(9,17): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(9, 17, 9, 19).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(9,19): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(9, 19, 9, 21).WithArguments("C.M1()", " message.", "") }, fixedExpected: Array.Empty()); } @@ -752,50 +752,50 @@ public class C public Task FixInEvent() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresAssemblyFiles("message")] - public int M1() => 0; - - public event EventHandler E1 - { - add - { - var a = M1(); - } - remove { } - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresAssemblyFiles("message")] + public int M1() => 0; + + public event EventHandler E1 + { + add + { + var a = M1(); + } + remove { } + } + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresAssemblyFiles("message")] - public int M1() => 0; - - public event EventHandler E1 - { - [RequiresAssemblyFiles()] - add - { - var a = M1(); - } - remove { } - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresAssemblyFiles("message")] + public int M1() => 0; + + public event EventHandler E1 + { + [RequiresAssemblyFiles()] + add + { + var a = M1(); + } + remove { } + } + } + """; return VerifyRequiresAssemblyFilesCodeFix( source: src, fixedSource: fix, baselineExpected: new[] { - // /0/Test0.cs(13,12): warning IL3002: Using method 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(13, 12, 13, 14).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(13,21): warning IL3002: Using method 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(13, 21, 13, 23).WithArguments("C.M1()", " message.", "") }, fixedExpected: Array.Empty()); } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresCapabilityTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresCapabilityTests.cs index ec1b99aef0f068..581e022524762e 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresCapabilityTests.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresCapabilityTests.cs @@ -34,6 +34,12 @@ public Task RequiresAttributeMismatch() return RunTest(nameof(RequiresAttributeMismatch)); } + [Fact] + public Task RequiresExcludeStatics() + { + return RunTest(); + } + [Fact] public Task RequiresCapabilityFromCopiedAssembly() { @@ -82,6 +88,12 @@ public Task RequiresOnAttributeCtor() return RunTest(nameof(RequiresOnAttributeCtor)); } + [Fact] + public Task RequiresOnBaseClass() + { + return RunTest(nameof(RequiresOnBaseClass)); + } + [Fact] public Task RequiresOnClass() { diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresDynamicCodeAnalyzerTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresDynamicCodeAnalyzerTests.cs index 97ac1f3ec2060c..ac3706f82e00ee 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresDynamicCodeAnalyzerTests.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresDynamicCodeAnalyzerTests.cs @@ -22,18 +22,18 @@ public class RequiresDynamicCodeAnalyzerTests namespace System.Diagnostics.CodeAnalysis { - [AttributeUsage (AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)] - public sealed class RequiresDynamicCodeAttribute : Attribute - { - public RequiresDynamicCodeAttribute (string message) - { - Message = message; - } - - public string Message { get; } - - public string? Url { get; set; } - } + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)] + public sealed class RequiresDynamicCodeAttribute : Attribute + { + public RequiresDynamicCodeAttribute(string message) + { + Message = message; + } + + public string Message { get; } + + public string? Url { get; set; } + } }"; static async Task VerifyRequiresDynamicCodeAnalyzer( @@ -79,81 +79,81 @@ static Task VerifyRequiresDynamicCodeCodeFix( public async Task SimpleDiagnosticFix() { var test = $$""" - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresDynamicCodeAttribute("message")] - public int M1() => 0; - - int M2() => M1(); - } - class D - { - public int M3(C c) => c.M1(); - - public class E - { - public int M4(C c) => c.M1(); - } - } - public class E - { - public class F - { - public int M5(C c) => c.M1(); - } - } - """; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresDynamicCodeAttribute("message")] + public int M1() => 0; + + int M2() => M1(); + } + class D + { + public int M3(C c) => c.M1(); + + public class E + { + public int M4(C c) => c.M1(); + } + } + public class E + { + public class F + { + public int M5(C c) => c.M1(); + } + } + """; var fixtest = $$""" - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresDynamicCodeAttribute("message")] - public int M1() => 0; - - [RequiresDynamicCode("Calls C.M1()")] - int M2() => M1(); - } - class D - { - [RequiresDynamicCode("Calls C.M1()")] - public int M3(C c) => c.M1(); - - public class E - { - [RequiresDynamicCode("Calls C.M1()")] - public int M4(C c) => c.M1(); - } - } - public class E - { - public class F - { - [RequiresDynamicCode()] - public int M5(C c) => c.M1(); - } - } - """; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresDynamicCodeAttribute("message")] + public int M1() => 0; + + [RequiresDynamicCode("Calls C.M1()")] + int M2() => M1(); + } + class D + { + [RequiresDynamicCode("Calls C.M1()")] + public int M3(C c) => c.M1(); + + public class E + { + [RequiresDynamicCode("Calls C.M1()")] + public int M4(C c) => c.M1(); + } + } + public class E + { + public class F + { + [RequiresDynamicCode()] + public int M5(C c) => c.M1(); + } + } + """; await VerifyRequiresDynamicCodeCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(8,14): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(8, 14, 8, 16).WithArguments("C.M1()", " message.", ""), - // /0/Test0.cs(12,24): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(12, 24, 12, 28).WithArguments("C.M1()", " message.", ""), - // /0/Test0.cs(16,25): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(16, 25, 16, 29).WithArguments("C.M1()", " message.", ""), - // /0/Test0.cs(23,25): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(23, 25, 23, 29).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(8,17): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(8, 17, 8, 19).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(12,27): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(12, 27, 12, 31).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(16,31): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(16, 31, 16, 35).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(23,28): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(23, 31, 23, 35).WithArguments("C.M1()", " message.", "") }, fixedExpected: new[] { - // /0/Test0.cs(26,10): error CS7036: There is no argument given that corresponds to the required formal parameter 'message' of 'RequiresDynamicCodeAttribute.RequiresDynamicCodeAttribute(string)' - DiagnosticResult.CompilerError("CS7036").WithSpan(26, 10, 26, 31).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute.RequiresDynamicCodeAttribute(string)"), + // /0/Test0.cs(26,10): error CS7036: There is no argument given that corresponds to the required formal parameter 'message' of 'RequiresDynamicCodeAttribute.RequiresDynamicCodeAttribute(string)' + DiagnosticResult.CompilerError("CS7036").WithSpan(26, 10, 26, 31).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute.RequiresDynamicCodeAttribute(string)"), }); } @@ -162,23 +162,23 @@ await VerifyRequiresDynamicCodeCodeFix( public Task FixInLambda() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresDynamicCodeAttribute("message")] - public int M1() => 0; - - Action M2() - { - return () => M1(); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresDynamicCodeAttribute("message")] + public int M1() => 0; + + Action M2() + { + return () => M1(); + } + } + """; var diag = new[] { - // /0/Test0.cs(11,16): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(11, 16, 11, 18).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(11,22): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(11, 22, 11, 24).WithArguments("C.M1()", " message.", "") }; // No fix available inside a lambda, requires manual code change since attribute cannot // be applied @@ -189,45 +189,45 @@ Action M2() public Task FixInLocalFunc() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresDynamicCodeAttribute("message")] - public int M1() => 0; - - Action M2() - { - void Wrapper () => M1(); - return Wrapper; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresDynamicCodeAttribute("message")] + public int M1() => 0; + + Action M2() + { + void Wrapper() => M1(); + return Wrapper; + } + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresDynamicCodeAttribute("message")] - public int M1() => 0; - - [RequiresDynamicCode("Calls Wrapper()")] - Action M2() - { - [RequiresDynamicCode("Calls C.M1()")] void Wrapper () => M1(); - return Wrapper; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresDynamicCodeAttribute("message")] + public int M1() => 0; + + [RequiresDynamicCode("Calls Wrapper()")] + Action M2() + { + [RequiresDynamicCode("Calls C.M1()")] void Wrapper() => M1(); + return Wrapper; + } + } + """; // Roslyn currently doesn't simplify the attribute name properly, see https://github.com/dotnet/roslyn/issues/52039 return VerifyRequiresDynamicCodeCodeFix( source: src, fixedSource: fix, baselineExpected: new[] { - // /0/Test0.cs(11,22): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(11, 22, 11, 24).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(11,27): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(11, 27, 11, 29).WithArguments("C.M1()", " message.", "") }, fixedExpected: Array.Empty(), // The default iterations for the codefix is the number of diagnostics (1 in this case) @@ -240,41 +240,41 @@ Action M2() public Task FixInCtor() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresDynamicCodeAttribute("message")] - public static int M1() => 0; + public class C + { + [RequiresDynamicCodeAttribute("message")] + public static int M1() => 0; - public C() => M1(); - } - """; + public C() => M1(); + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresDynamicCodeAttribute("message")] - public static int M1() => 0; - - [RequiresDynamicCode()] - public C() => M1(); - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresDynamicCodeAttribute("message")] + public static int M1() => 0; + + [RequiresDynamicCode()] + public C() => M1(); + } + """; // Roslyn currently doesn't simplify the attribute name properly, see https://github.com/dotnet/roslyn/issues/52039 return VerifyRequiresDynamicCodeCodeFix( source: src, fixedSource: fix, baselineExpected: new[] { - // /0/Test0.cs(9,16): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(9, 16, 9, 18).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(9,19): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(9, 19, 9, 21).WithArguments("C.M1()", " message.", "") }, fixedExpected: new[] { - // /0/Test0.cs(9,6): error CS7036: There is no argument given that corresponds to the required formal parameter 'message' of 'RequiresDynamicCodeAttribute.RequiresDynamicCodeAttribute(string)' - DiagnosticResult.CompilerError("CS7036").WithSpan(9, 6, 9, 27).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute.RequiresDynamicCodeAttribute(string)") + // /0/Test0.cs(9,6): error CS7036: There is no argument given that corresponds to the required formal parameter 'message' of 'RequiresDynamicCodeAttribute.RequiresDynamicCodeAttribute(string)' + DiagnosticResult.CompilerError("CS7036").WithSpan(9, 6, 9, 27).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute.RequiresDynamicCodeAttribute(string)") }); } @@ -282,20 +282,20 @@ public class C public Task FixInPropertyDecl() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresDynamicCodeAttribute("message")] - public int M1() => 0; + public class C + { + [RequiresDynamicCodeAttribute("message")] + public int M1() => 0; - int M2 => M1(); - } - """; + int M2 => M1(); + } + """; var diag = new[] { - // /0/Test0.cs(9,12): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(9, 12, 9, 14).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(9,15): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(9, 15, 9, 17).WithArguments("C.M1()", " message.", "") }; // Can't apply RDC on properties at the moment return VerifyRequiresDynamicCodeCodeFix(src, src, diag, diag); @@ -305,47 +305,47 @@ public class C public Task FixInPropertyAccessor() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresDynamicCodeAttribute("message")] - public int M1() => 0; - - public int field; - - private int M2 { - get { return M1(); } - set { field = M1(); } - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresDynamicCodeAttribute("message")] + public int M1() => 0; + + public int field; + + private int M2 { + get { return M1(); } + set { field = M1(); } + } + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresDynamicCodeAttribute("message")] - public int M1() => 0; + public class C + { + [RequiresDynamicCodeAttribute("message")] + public int M1() => 0; - public int field; + public int field; - private int M2 { - [RequiresDynamicCode("Calls C.M1()")] - get { return M1(); } + private int M2 { + [RequiresDynamicCode("Calls C.M1()")] + get { return M1(); } - [RequiresDynamicCode("Calls C.M1()")] - set { field = M1(); } - } - } - """; + [RequiresDynamicCode("Calls C.M1()")] + set { field = M1(); } + } + } + """; var diag = new[] { - // /0/Test0.cs(12,16): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(12, 16, 12, 18).WithArguments("C.M1()", " message.", ""), - // /0/Test0.cs(13,17): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(13, 17, 13, 19).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(12,22): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(12, 22, 12, 24).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(13,23): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(13, 23, 13, 25).WithArguments("C.M1()", " message.", "") }; return VerifyRequiresDynamicCodeCodeFix(src, fix, diag, Array.Empty()); } @@ -354,39 +354,39 @@ private int M2 { public Task FixInClass() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresDynamicCodeAttribute("message")] - static int M1() => 0; + public class C + { + [RequiresDynamicCodeAttribute("message")] + static int M1() => 0; - static int Field = M1(); - } - """; + static int Field = M1(); + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - [RequiresDynamicCode()] - public class C - { - [RequiresDynamicCodeAttribute("message")] - static int M1() => 0; - - static int Field = M1(); - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + [RequiresDynamicCode()] + public class C + { + [RequiresDynamicCodeAttribute("message")] + static int M1() => 0; + + static int Field = M1(); + } + """; return VerifyRequiresDynamicCodeCodeFix(src, fix, baselineExpected: new[] { - // /0/Test0.cs(9,21,9,25): warning IL2026: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(9, 21, 9, 23).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(9,24,9,26): warning IL2026: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(9, 24, 9, 26).WithArguments("C.M1()", " message.", ""), }, fixedExpected: new[] { - // /0/Test0.cs(4,2): error CS7036: There is no argument given that corresponds to the required parameter 'message' of 'RequiresDynamicCodeAttribute.RequiresDynamicCodeAttribute(string)' - DiagnosticResult.CompilerError("CS7036").WithSpan(4, 2, 4, 23).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute.RequiresDynamicCodeAttribute(string)"), + // /0/Test0.cs(4,2): error CS7036: There is no argument given that corresponds to the required parameter 'message' of 'RequiresDynamicCodeAttribute.RequiresDynamicCodeAttribute(string)' + DiagnosticResult.CompilerError("CS7036").WithSpan(4, 2, 4, 23).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute.RequiresDynamicCodeAttribute(string)"), }); } @@ -394,12 +394,12 @@ public class C public Task MakeGenericTypeWithAllKnownTypes() { const string src = $$""" - class C - { - public void M() => typeof(Gen<>).MakeGenericType(typeof(object)); - } - class Gen { } - """; + class C + { + public void M() => typeof(Gen<>).MakeGenericType(typeof(object)); + } + class Gen { } + """; return VerifyRequiresDynamicCodeAnalyzer(src); } @@ -408,12 +408,12 @@ class Gen { } public Task MakeGenericTypeWithAllKnownTypesInGenericContext() { const string src = $$""" - class C - { - public void M() => typeof(Gen<>).MakeGenericType(typeof(T)); - } - class Gen { } - """; + class C + { + public void M() => typeof(Gen<>).MakeGenericType(typeof(T)); + } + class Gen { } + """; return VerifyRequiresDynamicCodeAnalyzer(src); } @@ -422,14 +422,14 @@ class Gen { } public Task MakeGenericTypeWithConstraint() { const string src = $$""" - using System; - class C - { - public void M() => typeof(Gen<>).MakeGenericType(GetObject()); - static Type GetObject() => typeof(object); - } - class Gen where T : class { } - """; + using System; + class C + { + public void M() => typeof(Gen<>).MakeGenericType(GetObject()); + static Type GetObject() => typeof(object); + } + class Gen where T : class { } + """; return VerifyRequiresDynamicCodeAnalyzer(src); } @@ -438,48 +438,48 @@ class Gen where T : class { } public Task MakeGenericTypeWithUnknownDefinition() { const string src = $$""" - using System; - class C - { - public void M() => GetDefinition().MakeGenericType(typeof(object)); - static Type GetDefinition() => typeof(Gen<>); - } - class Gen { } - """; + using System; + class C + { + public void M() => GetDefinition().MakeGenericType(typeof(object)); + static Type GetDefinition() => typeof(Gen<>); + } + class Gen { } + """; return VerifyRequiresDynamicCodeAnalyzer(src, - // (4,21): warning IL3050: Using member 'System.Type.MakeGenericType(params Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(4, 21, 4, 52).WithArguments("System.Type.MakeGenericType(params Type[])", " The native code for this instantiation might not be available at runtime.", "")); + // (4,24): warning IL3050: Using member 'System.Type.MakeGenericType(params Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(4, 24, 4, 55).WithArguments("System.Type.MakeGenericType(params Type[])", " The native code for this instantiation might not be available at runtime.", "")); } [Fact] public Task MakeGenericTypeWithUnknownArgument() { const string src = $$""" - using System; - class C - { - public void M() => typeof(Gen<>).MakeGenericType(GetObject()); - static Type GetObject() => typeof(object); - } - class Gen { } - """; + using System; + class C + { + public void M() => typeof(Gen<>).MakeGenericType(GetObject()); + static Type GetObject() => typeof(object); + } + class Gen { } + """; return VerifyRequiresDynamicCodeAnalyzer(src, - // (4,21): warning IL3050: Using member 'System.Type.MakeGenericType(params Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(4, 21, 4, 50).WithArguments("System.Type.MakeGenericType(params Type[])", " The native code for this instantiation might not be available at runtime.", "")); + // (4,24): warning IL3050: Using member 'System.Type.MakeGenericType(params Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(4, 24, 4, 53).WithArguments("System.Type.MakeGenericType(params Type[])", " The native code for this instantiation might not be available at runtime.", "")); } [Fact] public Task MakeGenericMethodWithAllKnownTypes() { const string src = $$""" - class C - { - public void M() => typeof(C).GetMethod(nameof(N)).MakeGenericMethod(typeof(object)); - public void N() { } - } - """; + class C + { + public void M() => typeof(C).GetMethod(nameof(N)).MakeGenericMethod(typeof(object)); + public void N() { } + } + """; return VerifyRequiresDynamicCodeAnalyzer(src); } @@ -488,12 +488,12 @@ public void N() { } public Task MakeGenericMethodWithAllKnownTypesInGenericContext() { const string src = $$""" - class C - { - public void M() => typeof(C).GetMethod(nameof(N)).MakeGenericMethod(typeof(T)); - public void N() { } - } - """; + class C + { + public void M() => typeof(C).GetMethod(nameof(N)).MakeGenericMethod(typeof(T)); + public void N() { } + } + """; return VerifyRequiresDynamicCodeAnalyzer(src); } @@ -502,14 +502,14 @@ public void N() { } public Task MakeGenericMethodWithConstraint() { const string src = $$""" - using System; - class C - { - public void M() => typeof(C).GetMethod(nameof(N)).MakeGenericMethod(GetObject()); - public void N() where T : class { } - static Type GetObject() => typeof(object); - } - """; + using System; + class C + { + public void M() => typeof(C).GetMethod(nameof(N)).MakeGenericMethod(GetObject()); + public void N() where T : class { } + static Type GetObject() => typeof(object); + } + """; return VerifyRequiresDynamicCodeAnalyzer(src); } @@ -518,36 +518,36 @@ public void N() where T : class { } public Task MakeGenericMethodWithUnknownDefinition() { const string src = $$""" - using System.Reflection; - class C - { - public void M() => GetMethodInfo().MakeGenericMethod(typeof(object)); - public void N() { } - public MethodInfo GetMethodInfo() => typeof(C).GetMethod(nameof(N)); - } - """; + using System.Reflection; + class C + { + public void M() => GetMethodInfo().MakeGenericMethod(typeof(object)); + public void N() { } + public MethodInfo GetMethodInfo() => typeof(C).GetMethod(nameof(N)); + } + """; return VerifyRequiresDynamicCodeAnalyzer(src, - // (4,21): warning IL3050: Using member 'System.Reflection.MethodInfo.MakeGenericMethod(params Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(4, 21, 4, 54).WithArguments("System.Reflection.MethodInfo.MakeGenericMethod(params Type[])", " The native code for this instantiation might not be available at runtime.", "")); + // (4,24): warning IL3050: Using member 'System.Reflection.MethodInfo.MakeGenericMethod(params Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(4, 24, 4, 57).WithArguments("System.Reflection.MethodInfo.MakeGenericMethod(params Type[])", " The native code for this instantiation might not be available at runtime.", "")); } [Fact] public Task MakeGenericMethodWithUnknownArgument() { const string src = $$""" - using System; - class C - { - public void M() => typeof(C).GetMethod(nameof(N)).MakeGenericMethod(GetObject()); - public void N() { } - static Type GetObject() => typeof(object); - } - """; + using System; + class C + { + public void M() => typeof(C).GetMethod(nameof(N)).MakeGenericMethod(GetObject()); + public void N() { } + static Type GetObject() => typeof(object); + } + """; return VerifyRequiresDynamicCodeAnalyzer(src, - // (4,21): warning IL3050: Using member 'System.Reflection.MethodInfo.MakeGenericMethod(params Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. - VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(4, 21, 4, 69).WithArguments("System.Reflection.MethodInfo.MakeGenericMethod(params Type[])", " The native code for this instantiation might not be available at runtime.", "")); + // (4,24): warning IL3050: Using member 'System.Reflection.MethodInfo.MakeGenericMethod(params Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(4, 24, 4, 72).WithArguments("System.Reflection.MethodInfo.MakeGenericMethod(params Type[])", " The native code for this instantiation might not be available at runtime.", "")); } } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs index 4f034204392aa9..b0cf31595cd40e 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs @@ -61,41 +61,41 @@ static Task VerifyRequiresUnreferencedCodeCodeFix( public async Task WarningInArgument() { var test = $$""" - using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresUnreferencedCode("message")] - public int M1() => 0; - public void M2(int x) - { - } - public void M3() => M2(M1()); - } - """; + using System.Diagnostics.CodeAnalysis; + public class C + { + [RequiresUnreferencedCode("message")] + public int M1() => 0; + public void M2(int x) + { + } + public void M3() => M2(M1()); + } + """; var fixtest = $$""" - using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresUnreferencedCode("message")] - public int M1() => 0; - public void M2(int x) - { - } - - [RequiresUnreferencedCode()] - public void M3() => M2(M1()); - } - """; + using System.Diagnostics.CodeAnalysis; + public class C + { + [RequiresUnreferencedCode("message")] + public int M1() => 0; + public void M2(int x) + { + } + + [RequiresUnreferencedCode()] + public void M3() => M2(M1()); + } + """; await VerifyRequiresUnreferencedCodeCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(9,25): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(9, 25, 9, 27).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(9,28): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(9, 28, 9, 30).WithArguments("C.M1()", " message.", ""), }, fixedExpected: new[] { - // /0/Test0.cs(10,3): error CS7036: There is no argument given that corresponds to the required formal parameter 'message' of 'RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)' - DiagnosticResult.CompilerError("CS7036").WithSpan(10, 6, 10, 32).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)"), + // /0/Test0.cs(10,3): error CS7036: There is no argument given that corresponds to the required formal parameter 'message' of 'RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)' + DiagnosticResult.CompilerError("CS7036").WithSpan(10, 6, 10, 32).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)"), }); } @@ -103,81 +103,81 @@ await VerifyRequiresUnreferencedCodeCodeFix( public async Task SimpleDiagnosticFix() { var test = $$""" - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - public int M1() => 0; - - int M2() => M1(); - } - class D - { - public int M3(C c) => c.M1(); - - public class E - { - public int M4(C c) => c.M1(); - } - } - public class E - { - public class F - { - public int M5(C c) => c.M1(); - } - } - """; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; + + int M2() => M1(); + } + class D + { + public int M3(C c) => c.M1(); + + public class E + { + public int M4(C c) => c.M1(); + } + } + public class E + { + public class F + { + public int M5(C c) => c.M1(); + } + } + """; var fixtest = $$""" - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - public int M1() => 0; - - [RequiresUnreferencedCode("Calls C.M1()")] - int M2() => M1(); - } - class D - { - [RequiresUnreferencedCode("Calls C.M1()")] - public int M3(C c) => c.M1(); - - public class E - { - [RequiresUnreferencedCode("Calls C.M1()")] - public int M4(C c) => c.M1(); - } - } - public class E - { - public class F - { - [RequiresUnreferencedCode()] - public int M5(C c) => c.M1(); - } - } - """; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; + + [RequiresUnreferencedCode("Calls C.M1()")] + int M2() => M1(); + } + class D + { + [RequiresUnreferencedCode("Calls C.M1()")] + public int M3(C c) => c.M1(); + + public class E + { + [RequiresUnreferencedCode("Calls C.M1()")] + public int M4(C c) => c.M1(); + } + } + public class E + { + public class F + { + [RequiresUnreferencedCode()] + public int M5(C c) => c.M1(); + } + } + """; await VerifyRequiresUnreferencedCodeCodeFix( source: test, fixedSource: fixtest, baselineExpected: new[] { - // /0/Test0.cs(8,14): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (8, 14, 8, 16).WithArguments ("C.M1()", " message.", ""), - // /0/Test0.cs(12,24): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan (12, 24, 12, 28).WithArguments("C.M1()", " message.", ""), - // /0/Test0.cs(16,25): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (16, 25, 16, 29).WithArguments ("C.M1()", " message.", ""), - // /0/Test0.cs(23,25): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (23, 25, 23, 29).WithArguments ("C.M1()", " message.", "") + // /0/Test0.cs(8,17): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(8, 17, 8, 19).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(12,27): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(12, 27, 12, 31).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(16,31): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(16, 31, 16, 35).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(23,28): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(23, 31, 23, 35).WithArguments("C.M1()", " message.", "") }, fixedExpected: new[] { - // /0/Test0.cs(26,10): error CS7036: There is no argument given that corresponds to the required formal parameter 'message' of 'RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)' - DiagnosticResult.CompilerError("CS7036").WithSpan(26, 10, 26, 36).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)"), + // /0/Test0.cs(26,10): error CS7036: There is no argument given that corresponds to the required formal parameter 'message' of 'RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)' + DiagnosticResult.CompilerError("CS7036").WithSpan(26, 10, 26, 36).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)"), }); } @@ -185,23 +185,23 @@ await VerifyRequiresUnreferencedCodeCodeFix( public Task FixInLambda() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - public int M1() => 0; - - Action M2() - { - return () => M1(); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; + + Action M2() + { + return () => M1(); + } + } + """; var diag = new[] { - // /0/Test0.cs(11,16): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(11, 16, 11, 18).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(11,22): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(11, 22, 11, 24).WithArguments("C.M1()", " message.", "") }; // No fix available inside a lambda, requires manual code change since attribute cannot // be applied @@ -212,45 +212,45 @@ Action M2() public Task FixInLocalFunc() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - public int M1() => 0; - - Action M2() - { - void Wrapper () => M1(); - return Wrapper; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; + + Action M2() + { + void Wrapper() => M1(); + return Wrapper; + } + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - public int M1() => 0; - - [RequiresUnreferencedCode("Calls Wrapper()")] - Action M2() - { - [RequiresUnreferencedCode("Calls C.M1()")] void Wrapper () => M1(); - return Wrapper; - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; + + [RequiresUnreferencedCode("Calls Wrapper()")] + Action M2() + { + [RequiresUnreferencedCode("Calls C.M1()")] void Wrapper() => M1(); + return Wrapper; + } + } + """; // Roslyn currently doesn't simplify the attribute name properly, see https://github.com/dotnet/roslyn/issues/52039 return VerifyRequiresUnreferencedCodeCodeFix( source: src, fixedSource: fix, baselineExpected: new[] { - // /0/Test0.cs(11,22): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(11, 22, 11, 24).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(11,27): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(11, 27, 11, 29).WithArguments("C.M1()", " message.", "") }, fixedExpected: Array.Empty(), // The default iterations for the codefix is the number of diagnostics (1 in this case) @@ -263,41 +263,41 @@ Action M2() public Task FixInCtor() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - public static int M1() => 0; + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public static int M1() => 0; - public C() => M1(); - } - """; + public C() => M1(); + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - public static int M1() => 0; - - [RequiresUnreferencedCode()] - public C() => M1(); - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public static int M1() => 0; + + [RequiresUnreferencedCode()] + public C() => M1(); + } + """; // Roslyn currently doesn't simplify the attribute name properly, see https://github.com/dotnet/roslyn/issues/52039 return VerifyRequiresUnreferencedCodeCodeFix( source: src, fixedSource: fix, baselineExpected: new[] { - // /0/Test0.cs(9,16): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(9, 16, 9, 18).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(9,19): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(9, 19, 9, 21).WithArguments("C.M1()", " message.", "") }, fixedExpected: new[] { - // /0/Test0.cs(9,3): error CS7036: There is no argument given that corresponds to the required formal parameter 'message' of 'RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)' - DiagnosticResult.CompilerError ("CS7036").WithSpan (9, 6, 9, 32).WithArguments ("message", "System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)") + // /0/Test0.cs(9,3): error CS7036: There is no argument given that corresponds to the required formal parameter 'message' of 'RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)' + DiagnosticResult.CompilerError("CS7036").WithSpan(9, 6, 9, 32).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)") }); } @@ -305,20 +305,20 @@ public class C public Task FixInPropertyDecl() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - public int M1() => 0; + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; - int M2 => M1(); - } - """; + int M2 => M1(); + } + """; var diag = new[] { - // /0/Test0.cs(10,15): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(9, 12, 9, 14).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(9,15): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(9, 15, 9, 17).WithArguments("C.M1()", " message.", "") }; // Can't apply RUC on properties at the moment return VerifyRequiresUnreferencedCodeCodeFix(src, src, diag, diag); @@ -328,47 +328,47 @@ public class C public Task FixInPropertyAccessor() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - public int M1() => 0; - - public int field; - - private int M2 { - get { return M1(); } - set { field = M1(); } - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; + + public int field; + + private int M2 { + get { return M1(); } + set { field = M1(); } + } + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - public int M1() => 0; + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; - public int field; + public int field; - private int M2 { - [RequiresUnreferencedCode("Calls C.M1()")] - get { return M1(); } + private int M2 { + [RequiresUnreferencedCode("Calls C.M1()")] + get { return M1(); } - [RequiresUnreferencedCode("Calls C.M1()")] - set { field = M1(); } - } - } - """; + [RequiresUnreferencedCode("Calls C.M1()")] + set { field = M1(); } + } + } + """; var diag = new[] { - // /0/Test0.cs(12,16): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(12, 16, 12, 18).WithArguments("C.M1()", " message.", ""), - // /0/Test0.cs(13,17): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(13, 17, 13, 19).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(12,22): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(12, 22, 12, 24).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(13,23): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(13, 23, 13, 25).WithArguments("C.M1()", " message.", "") }; return VerifyRequiresUnreferencedCodeCodeFix(src, fix, diag, Array.Empty()); } @@ -377,39 +377,39 @@ private int M2 { public Task FixInClass() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - static int M1() => 0; + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + static int M1() => 0; - static int Field = M1(); - } - """; + static int Field = M1(); + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - [RequiresUnreferencedCode()] - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - static int M1() => 0; - - static int Field = M1(); - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + [RequiresUnreferencedCode()] + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + static int M1() => 0; + + static int Field = M1(); + } + """; return VerifyRequiresUnreferencedCodeCodeFix(src, fix, baselineExpected: new[] { - // /0/Test0.cs(9,21): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(9, 21, 9, 23).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(9,24): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(9, 24, 9, 26).WithArguments("C.M1()", " message.", "") }, fixedExpected: new[] { - // /0/Test0.cs(4,2): error CS7036: There is no argument given that corresponds to the required parameter 'message' of 'RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)' - DiagnosticResult.CompilerError("CS7036").WithSpan(4, 2, 4, 28).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)"), + // /0/Test0.cs(4,2): error CS7036: There is no argument given that corresponds to the required parameter 'message' of 'RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)' + DiagnosticResult.CompilerError("CS7036").WithSpan(4, 2, 4, 28).WithArguments("message", "System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute.RequiresUnreferencedCodeAttribute(string)"), }); } @@ -417,50 +417,50 @@ public class C public Task TestMakeGenericMethodUsage() { var source = $$""" - using System.Diagnostics.CodeAnalysis; - using System.Reflection; - - class C - { - static void M1 (MethodInfo methodInfo) - { - methodInfo.MakeGenericMethod (typeof (C)); - } - - [RequiresUnreferencedCode ("Message from RUC")] - static void M2 (MethodInfo methodInfo) - { - methodInfo.MakeGenericMethod (typeof (C)); - } - } - """; + using System.Diagnostics.CodeAnalysis; + using System.Reflection; + + class C + { + static void M1(MethodInfo methodInfo) + { + methodInfo.MakeGenericMethod(typeof(C)); + } + + [RequiresUnreferencedCode("Message from RUC")] + static void M2(MethodInfo methodInfo) + { + methodInfo.MakeGenericMethod(typeof(C)); + } + } + """; return VerifyRequiresUnreferencedCodeAnalyzer(source, - // (8,3): warning IL2060: Call to 'System.Reflection.MethodInfo.MakeGenericMethod(params Type[])' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic method. - VerifyCS.Diagnostic(DiagnosticId.MakeGenericMethod).WithSpan(8, 3, 8, 44).WithArguments("System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")); + // (8,9): warning IL2060: Call to 'System.Reflection.MethodInfo.MakeGenericMethod(params Type[])' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic method. + VerifyCS.Diagnostic(DiagnosticId.MakeGenericMethod).WithSpan(8, 9, 8, 48).WithArguments("System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")); } [Fact] public Task TestMakeGenericTypeUsage() { var source = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - class C - { - static void M1 (Type t) - { - typeof (Nullable<>).MakeGenericType (typeof (C)); - } - - [RequiresUnreferencedCode ("Message from RUC")] - static void M2 (Type t) - { - typeof (Nullable<>).MakeGenericType (typeof (C)); - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + class C + { + static void M1(Type t) + { + typeof(Nullable<>).MakeGenericType(typeof(C)); + } + + [RequiresUnreferencedCode("Message from RUC")] + static void M2(Type t) + { + typeof(Nullable<>).MakeGenericType(typeof(C)); + } + } + """; return VerifyRequiresUnreferencedCodeAnalyzer(source); } @@ -469,14 +469,14 @@ static void M2 (Type t) public Task VerifyThatAnalysisOfFieldsDoesNotNullRef() { var source = $$""" - using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.CodeAnalysis; - [DynamicallyAccessedMembers (field)] - class C - { - public const DynamicallyAccessedMemberTypes field = DynamicallyAccessedMemberTypes.PublicMethods; - } - """; + [DynamicallyAccessedMembers(field)] + class C + { + public const DynamicallyAccessedMemberTypes field = DynamicallyAccessedMemberTypes.PublicMethods; + } + """; return VerifyRequiresUnreferencedCodeAnalyzer(source); } @@ -485,14 +485,14 @@ class C public Task TestPropertyAssignmentInAssemblyAttribute() { var source = $$""" - using System; - [assembly: MyAttribute (Value = 5)] - - class MyAttribute : Attribute - { - public int Value { get; set; } - } - """; + using System; + [assembly: MyAttribute(Value = 5)] + + class MyAttribute : Attribute + { + public int Value { get; set; } + } + """; return VerifyRequiresUnreferencedCodeAnalyzer(source); } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestCaseCompilation.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestCaseCompilation.cs index 2b45fa3159c3d7..d5b21354db6f30 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestCaseCompilation.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestCaseCompilation.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.IO; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -43,11 +44,31 @@ public static (CompilationWithAnalyzers Compilation, SemanticModel SemanticModel additionalReferences ??= Array.Empty(); var sources = new List() { src }; sources.AddRange(additionalSources ?? Array.Empty()); + TestCaseUtils.GetDirectoryPaths(out string rootSourceDirectory); + var testDir = Path.GetDirectoryName(rootSourceDirectory)!; + var srcDir = Path.Combine(Path.GetDirectoryName(testDir)!, "src"); + var sharedDir = Path.Combine(srcDir, "ILLink.Shared"); + var commonSourcePaths = new List() + { + Path.Combine(testDir, + "Mono.Linker.Tests.Cases.Expectations", + "Support", + "DynamicallyAccessedMembersAttribute.cs"), + Path.Combine(sharedDir, "RequiresUnreferencedCodeAttribute.cs"), + Path.Combine(sharedDir, "RequiresDynamicCodeAttribute.cs"), + }; + + sources.AddRange(commonSourcePaths.Select(p => CSharpSyntaxTree.ParseText(File.ReadAllText(p), path: p))); var comp = CSharpCompilation.Create( - assemblyName: Guid.NewGuid().ToString("N"), + assemblyName: "test", syntaxTrees: sources, references: SourceGenerators.Tests.LiveReferencePack.GetMetadataReferences().Add(mdRef).AddRange(additionalReferences), - new CSharpCompilationOptions(consoleApplication ? OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary)); + new CSharpCompilationOptions(consoleApplication ? OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary, + specificDiagnosticOptions: new Dictionary + { + // Allow the polyfilled DynamicallyAccessedMembersAttribute to take precedence over the one in corelib. + { "CS0436", ReportDiagnostic.Suppress } + })); var analyzerOptions = new AnalyzerOptions( additionalFiles: additionalFiles?.ToImmutableArray() ?? ImmutableArray.Empty, new SimpleAnalyzerOptions(globalAnalyzerOptions)); diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs index 7de145d1423032..baa3a5b96831b0 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs @@ -58,7 +58,7 @@ public static async Task RunTestFile(string suiteName, string testName, bool all testCaseDir = testSuiteDir; testPath = Path.Combine(testSuiteDir, $"{testName}.cs"); } - Assert.True(File.Exists(testPath)); + Assert.True(File.Exists(testPath), $"{testPath} should exist"); var tree = SyntaxFactory.ParseSyntaxTree( SourceText.From(File.OpenRead(testPath), Encoding.UTF8), path: testPath); diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs index 899a3b4a6bbe36..655fcf13b9aeb2 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs @@ -386,7 +386,7 @@ private bool LogContains(AttributeSyntax attribute, IReadOnlyList di findText = LinkerTestBase.GetStringFromExpression(args["#0"], _semanticModel); // If the text starts with `warning IL...` then it probably follows the pattern - // 'warning : :' + // 'warning : :' // We don't want to repeat the location in the error message for the analyzer, so // it's better to just trim here. We've already filtered by diagnostic location so // the text location shouldn't matter diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/UnconditionalSuppressMessageCodeFixTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/UnconditionalSuppressMessageCodeFixTests.cs index f4399633ca4151..7813a902709d8b 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/UnconditionalSuppressMessageCodeFixTests.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/UnconditionalSuppressMessageCodeFixTests.cs @@ -20,18 +20,18 @@ public class UnconditionalSuppressMessageCodeFixTests namespace System.Diagnostics.CodeAnalysis { - [AttributeUsage (AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)] - public sealed class RequiresDynamicCodeAttribute : Attribute - { - public RequiresDynamicCodeAttribute (string message) - { - Message = message; - } - - public string Message { get; } - - public string? Url { get; set; } - } + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)] + public sealed class RequiresDynamicCodeAttribute : Attribute + { + public RequiresDynamicCodeAttribute(string message) + { + Message = message; + } + + public string Message { get; } + + public string? Url { get; set; } + } }"; static Task VerifyUnconditionalSuppressMessageCodeFixWithRUC( @@ -118,8 +118,8 @@ public class C test, fixtest, baselineExpected: new[] { - // /0/Test0.cs(7,17): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCSUSM.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan (7, 17, 7, 19).WithArguments ("C.M1()", " message.", ""), + // /0/Test0.cs(7,17): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCSUSM.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(7, 17, 7, 19).WithArguments("C.M1()", " message.", ""), }, fixedExpected: Array.Empty()); } @@ -148,8 +148,8 @@ public class C test, fixtest, baselineExpected: new[] { - // /0/Test0.cs(7,17): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCSUSM.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (7, 17, 7, 19).WithArguments ("C.M1()", " message.", "") + // /0/Test0.cs(7,17): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCSUSM.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(7, 17, 7, 19).WithArguments("C.M1()", " message.", "") }, fixedExpected: Array.Empty()); } @@ -178,8 +178,8 @@ public class C test, fixtest, baselineExpected: new[] { - // /0/Test0.cs(7,17): warning IL3050: Members annotated with 'RequiresDynamicCodeAttribute' require dynamic access otherwise can break functionality when trimming application code. message. - VerifyCSUSM.Diagnostic (DiagnosticId.RequiresDynamicCode).WithSpan (7, 17, 7, 19).WithArguments ("C.M1()", " message.", "") + // /0/Test0.cs(7,17): warning IL3050: Members annotated with 'RequiresDynamicCodeAttribute' require dynamic access otherwise can break functionality when trimming application code. message. + VerifyCSUSM.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(7, 17, 7, 19).WithArguments("C.M1()", " message.", "") }, fixedExpected: Array.Empty()); } @@ -219,10 +219,10 @@ public void M2() { test, fixtest, baselineExpected: new[] { - // /0/Test0.cs(7,27): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. - VerifyCSUSM.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan (7, 27, 7, 44).WithArguments ("System.Reflection.Assembly.Location.get", "", ""), - // /0/Test0.cs(9,13): warning IL3001: 'System.Reflection.Assembly.GetFiles()' will throw for assemblies embedded in a single-file app - VerifyCSUSM.Diagnostic(DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan (9, 13, 9, 30).WithArguments("System.Reflection.Assembly.GetFiles()", "", ""), + // /0/Test0.cs(7,27): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'. + VerifyCSUSM.Diagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile).WithSpan(7, 27, 7, 44).WithArguments("System.Reflection.Assembly.Location.get", "", ""), + // /0/Test0.cs(9,13): warning IL3001: 'System.Reflection.Assembly.GetFiles()' will throw for assemblies embedded in a single-file app + VerifyCSUSM.Diagnostic(DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan(9, 13, 9, 30).WithArguments("System.Reflection.Assembly.GetFiles()", "", ""), }, fixedExpected: Array.Empty()); } @@ -257,8 +257,8 @@ public class C src, fix, baselineExpected: new[] { - // /0/Test0.cs(10,15): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCSUSM.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan(10, 15, 10, 17).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(10,15): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCSUSM.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(10, 15, 10, 17).WithArguments("C.M1()", " message.", "") }, fixedExpected: Array.Empty()); } @@ -267,47 +267,47 @@ public class C public Task FixInPropertyAccessor() { var src = $$""" - using System; - using System.Diagnostics.CodeAnalysis; - - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - public int M1() => 0; - - public int field; - - private int M2 { - get { return M1(); } - set { field = M1(); } - } - } - """; + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; + + public int field; + + private int M2 { + get { return M1(); } + set { field = M1(); } + } + } + """; var fix = $$""" - using System; - using System.Diagnostics.CodeAnalysis; + using System; + using System.Diagnostics.CodeAnalysis; - public class C - { - [RequiresUnreferencedCodeAttribute("message")] - public int M1() => 0; + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; - public int field; + public int field; - private int M2 { - [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "")] - get { return M1(); } + private int M2 { + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "")] + get { return M1(); } - [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "")] - set { field = M1(); } - } - } - """; + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "")] + set { field = M1(); } + } + } + """; var diag = new[] { - // /0/Test0.cs(12,16): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCSUSM.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(12, 16, 12, 18).WithArguments("C.M1()", " message.", ""), - // /0/Test0.cs(13,17): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCSUSM.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(13, 17, 13, 19).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(12,22): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCSUSM.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(12, 22, 12, 24).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(13,23): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCSUSM.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(13, 23, 13, 25).WithArguments("C.M1()", " message.", "") }; return VerifyUnconditionalSuppressMessageCodeFixWithRUC(src, fix, diag, Array.Empty()); } @@ -348,8 +348,8 @@ public static C InitC() { src, fixtest, baselineExpected: new[] { - // /0/Test0.cs(6,50): warning IL3002: Using member 'C.InitC()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. - VerifyCSUSM.Diagnostic (DiagnosticId.RequiresAssemblyFiles).WithSpan (6, 50, 6, 55).WithArguments ("C.InitC()", "", ""), + // /0/Test0.cs(6,50): warning IL3002: Using member 'C.InitC()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. + VerifyCSUSM.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(6, 50, 6, 55).WithArguments("C.InitC()", "", ""), }, fixedExpected: Array.Empty()); } @@ -368,7 +368,7 @@ public class C Action M2() { - void Wrapper () => M1(); + void Wrapper() => M1(); return Wrapper; } }"; @@ -383,7 +383,7 @@ public class C Action M2() { - [UnconditionalSuppressMessage(""Trimming"", ""IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code"", Justification = """")] void Wrapper () => M1(); + [UnconditionalSuppressMessage(""Trimming"", ""IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code"", Justification = """")] void Wrapper() => M1(); return Wrapper; } }"; @@ -392,8 +392,8 @@ Action M2() src, fix, baselineExpected: new[] { - // /0/Test0.cs(12,28): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCSUSM.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan(12, 28, 12, 30).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(12,27): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCSUSM.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(12, 27, 12, 29).WithArguments("C.M1()", " message.", "") }, fixedExpected: Array.Empty()); } @@ -410,7 +410,7 @@ public class C [RequiresUnreferencedCodeAttribute(""message"")] public int M1() => 0; - public C () => M1(); + public C() => M1(); }"; var fix = @" using System; @@ -422,14 +422,14 @@ public class C public int M1() => 0; [UnconditionalSuppressMessage(""Trimming"", ""IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code"", Justification = """")] - public C () => M1(); + public C() => M1(); }"; return VerifyUnconditionalSuppressMessageCodeFixWithRUC( src, fix, baselineExpected: new[] { - // /0/Test0.cs(10,15): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCSUSM.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan(10, 20, 10, 22).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(10,19): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCSUSM.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(10, 19, 10, 21).WithArguments("C.M1()", " message.", "") }, fixedExpected: Array.Empty()); } @@ -478,8 +478,8 @@ public event EventHandler E1 src, fix, baselineExpected: new[] { - // /0/Test0.cs(14,21): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. - VerifyCSUSM.Diagnostic (DiagnosticId.RequiresUnreferencedCode).WithSpan(14, 21, 14, 23).WithArguments("C.M1()", " message.", "") + // /0/Test0.cs(14,21): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCSUSM.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(14, 21, 14, 23).WithArguments("C.M1()", " message.", "") }, fixedExpected: Array.Empty()); } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AdvancedTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AdvancedTests.g.cs index 217047462a7ffc..8cd232bd2ca4d0 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AdvancedTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AdvancedTests.g.cs @@ -4,26 +4,26 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class AdvancedTests : LinkerTestBase - { + public sealed partial class AdvancedTests : LinkerTestBase + { - [Fact] - public Task DeadCodeElimination1 () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task DeadCodeElimination1() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task FieldThatOnlyGetsSetIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task FieldThatOnlyGetsSetIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task TypeCheckRemovalDisabled () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task TypeCheckRemovalDisabled() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.CscTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.CscTests.g.cs index 028ec904acd518..156c00f6416a87 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.CscTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.CscTests.g.cs @@ -4,118 +4,118 @@ namespace ILLink.RoslynAnalyzer.Tests.Attributes { - public sealed partial class CscTests : LinkerTestBase - { - - protected override string TestSuiteName => "Attributes.Csc"; - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeArrayOnAttributeCtorOnType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnAssemblyOtherTypesInAttributeAssemblyUsed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnEvent () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnProperty () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnEvent () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnProperty () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnEvent () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnProperty () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OnlyTypeUsedInAssemblyWithReferenceIsTypeOnAttributeCtorOnType () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class CscTests : LinkerTestBase + { + + protected override string TestSuiteName => "Attributes.Csc"; + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeArrayOnAttributeCtorOnType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnAssemblyOtherTypesInAttributeAssemblyUsed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnEvent() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnProperty() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnEvent() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnProperty() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnEvent() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnProperty() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyWithReferenceIsTypeOnAttributeCtorOnType() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.Debugger.KeepDebugMembersTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.Debugger.KeepDebugMembersTests.g.cs index 0975be65225014..87612434301815 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.Debugger.KeepDebugMembersTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.Debugger.KeepDebugMembersTests.g.cs @@ -4,94 +4,94 @@ namespace ILLink.RoslynAnalyzer.Tests.Attributes.Debugger { - public sealed partial class KeepDebugMembersTests : LinkerTestBase - { - - protected override string TestSuiteName => "Attributes.Debugger.KeepDebugMembers"; - - [Fact] - public Task DebuggerDisplayAttributeOnAssemblyUsingTarget () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnAssemblyUsingTargetOnUnusedType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInOtherAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInSameAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameOfGenericTypeInOtherAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameOfNestedTypeInOtherAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnGenerics () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnTypeThatIsNotUsed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnTypeWithNonExistentMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayOnTypeWithCallToExtensionMethodOnFieldType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayOnTypeWithCallToMethodOnFieldType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerTypeProxyAttributeOnAssemblyUsingTarget () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerTypeProxyAttributeOnType () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class KeepDebugMembersTests : LinkerTestBase + { + + protected override string TestSuiteName => "Attributes.Debugger.KeepDebugMembers"; + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTarget() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetOnUnusedType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInOtherAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInSameAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameOfGenericTypeInOtherAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameOfNestedTypeInOtherAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnGenerics() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnTypeThatIsNotUsed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnTypeWithNonExistentMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayOnTypeWithCallToExtensionMethodOnFieldType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayOnTypeWithCallToMethodOnFieldType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerTypeProxyAttributeOnAssemblyUsingTarget() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerTypeProxyAttributeOnType() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.DebuggerTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.DebuggerTests.g.cs index 70f89bf10ac802..6f9f3d0ee5775c 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.DebuggerTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.DebuggerTests.g.cs @@ -4,58 +4,58 @@ namespace ILLink.RoslynAnalyzer.Tests.Attributes { - public sealed partial class DebuggerTests : LinkerTestBase - { - - protected override string TestSuiteName => "Attributes.Debugger"; - - [Fact] - public Task DebuggerDisplayAttributeOnAssemblyUsingTarget () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnAssemblyUsingTargetOnUnusedType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInOtherAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnTypeCopy () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerDisplayAttributeOnTypeThatIsNotUsed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerTypeProxyAttributeOnAssemblyUsingTarget () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DebuggerTypeProxyAttributeOnType () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class DebuggerTests : LinkerTestBase + { + + protected override string TestSuiteName => "Attributes.Debugger"; + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTarget() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetOnUnusedType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInOtherAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnTypeCopy() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnTypeThatIsNotUsed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerTypeProxyAttributeOnAssemblyUsingTarget() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerTypeProxyAttributeOnType() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.NoSecurityTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.NoSecurityTests.g.cs index 7eb7eff2af9a71..16b49bd46f52f8 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.NoSecurityTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.NoSecurityTests.g.cs @@ -4,28 +4,28 @@ namespace ILLink.RoslynAnalyzer.Tests.Attributes { - public sealed partial class NoSecurityTests : LinkerTestBase - { + public sealed partial class NoSecurityTests : LinkerTestBase + { - protected override string TestSuiteName => "Attributes.NoSecurity"; + protected override string TestSuiteName => "Attributes.NoSecurity"; - [Fact] - public Task CoreLibrarySecurityAttributeTypesAreRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CoreLibrarySecurityAttributeTypesAreRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task SecurityAttributesOnUsedMethodAreRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task SecurityAttributesOnUsedMethodAreRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task SecurityAttributesOnUsedTypeAreRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task SecurityAttributesOnUsedTypeAreRemoved() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.OnlyKeepUsedTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.OnlyKeepUsedTests.g.cs index 893331bcc141b9..6b2cca5d61b32a 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.OnlyKeepUsedTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.OnlyKeepUsedTests.g.cs @@ -4,196 +4,196 @@ namespace ILLink.RoslynAnalyzer.Tests.Attributes { - public sealed partial class OnlyKeepUsedTests : LinkerTestBase - { - - protected override string TestSuiteName => "Attributes.OnlyKeepUsed"; - - [Fact] - public Task AttributeDefinedAndUsedInOtherAssemblyIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeUsedByAttributeIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanLinkCoreLibrariesWithOnlyKeepUsedAttributes () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ComAttributesArePreserved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ContextStaticIsPreservedOnField () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CoreLibraryUnusedAssemblyAttributesAreRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CoreLibraryUsedAssemblyAttributesAreKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task FixedLengthArrayAttributesArePreserved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MethodWithUnmanagedConstraint () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NullableOnConstraintsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NullableOnConstraintsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ThreadStaticIsPreservedOnField () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedAttributeOnGenericParameterIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedAttributeOnReturnTypeIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedAttributePreservedViaLinkXmlIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedAttributeTypeOnAssemblyIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedAttributeTypeOnEventIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedAttributeTypeOnMethodIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedAttributeTypeOnModuleIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedAttributeTypeOnParameterIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedAttributeTypeOnPropertyIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedAttributeTypeOnTypeIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedAttributeWithTypeForwarderIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedDerivedAttributeType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedAttributeTypeOnAssemblyIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedAttributeTypeOnEventIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedAttributeTypeOnMethodIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedAttributeTypeOnModuleIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedAttributeTypeOnParameterIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedAttributeTypeOnPropertyIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedAttributeTypeOnTypeIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class OnlyKeepUsedTests : LinkerTestBase + { + + protected override string TestSuiteName => "Attributes.OnlyKeepUsed"; + + [Fact] + public Task AttributeDefinedAndUsedInOtherAssemblyIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeUsedByAttributeIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanLinkCoreLibrariesWithOnlyKeepUsedAttributes() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ComAttributesArePreserved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ContextStaticIsPreservedOnField() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CoreLibraryUnusedAssemblyAttributesAreRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CoreLibraryUsedAssemblyAttributesAreKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task FixedLengthArrayAttributesArePreserved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MethodWithUnmanagedConstraint() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NullableOnConstraintsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NullableOnConstraintsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ThreadStaticIsPreservedOnField() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAttributeOnGenericParameterIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAttributeOnReturnTypeIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAttributePreservedViaLinkXmlIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAttributeTypeOnAssemblyIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAttributeTypeOnEventIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAttributeTypeOnMethodIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAttributeTypeOnModuleIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAttributeTypeOnParameterIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAttributeTypeOnPropertyIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAttributeTypeOnTypeIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAttributeWithTypeForwarderIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedDerivedAttributeType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedAttributeTypeOnAssemblyIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedAttributeTypeOnEventIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedAttributeTypeOnMethodIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedAttributeTypeOnModuleIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedAttributeTypeOnParameterIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedAttributeTypeOnPropertyIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedAttributeTypeOnTypeIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.StructLayoutTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.StructLayoutTests.g.cs index 603e80d6743da2..2fcd7216700034 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.StructLayoutTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.StructLayoutTests.g.cs @@ -4,34 +4,34 @@ namespace ILLink.RoslynAnalyzer.Tests.Attributes { - public sealed partial class StructLayoutTests : LinkerTestBase - { + public sealed partial class StructLayoutTests : LinkerTestBase + { - protected override string TestSuiteName => "Attributes.StructLayout"; + protected override string TestSuiteName => "Attributes.StructLayout"; - [Fact] - public Task AutoClass () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task AutoClass() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task ExplicitClass () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task ExplicitClass() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task SequentialClass () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task SequentialClass() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UnusedTypeWithSequentialLayoutIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UnusedTypeWithSequentialLayoutIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AttributesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AttributesTests.g.cs index dc69ebb930a723..53a48052a45301 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AttributesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AttributesTests.g.cs @@ -4,178 +4,178 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class AttributesTests : LinkerTestBase - { - - protected override string TestSuiteName => "Attributes"; - - [Fact] - public Task AssemblyAttributeAccessesMembers () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AssemblyAttributeIsRemovedIfOnlyTypesUsedInAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AssemblyAttributeKeptInComplexCase () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeOnAssemblyIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeOnAssemblyIsKeptIfDeclarationIsSkipped () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeOnParameterInUsedMethodIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeOnPreservedTypeIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeOnPreservedTypeWithTypeUsedInConstructorIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeOnPreservedTypeWithTypeUsedInDifferentNamespaceIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeOnPreservedTypeWithTypeUsedInFieldIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeOnPreservedTypeWithTypeUsedInPropertySetterIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeOnPreservedTypeWithUsedSetter () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeOnUsedFieldIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeOnUsedMethodIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeOnUsedPropertyIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task BoxedValues () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CoreLibraryAssemblyAttributesAreKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task FixedLengthArrayAttributesArePreserved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericAttributes () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task IVTUnused () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task IVTUnusedKeptWhenKeepingUsedAttributesOnly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task IVTUsed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MarshalAsCustomMarshaler () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MarshalAsCustomMarshalerInterface () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SecurityAttributesOnUsedMethodAreKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SecurityAttributesOnUsedTypeAreKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TypeUsedInObjectArrayConstructorArgumentOnAttributeIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TypeWithDynamicInterfaceCastableImplementationAttributeIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class AttributesTests : LinkerTestBase + { + + protected override string TestSuiteName => "Attributes"; + + [Fact] + public Task AssemblyAttributeAccessesMembers() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AssemblyAttributeIsRemovedIfOnlyTypesUsedInAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AssemblyAttributeKeptInComplexCase() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnAssemblyIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnAssemblyIsKeptIfDeclarationIsSkipped() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnParameterInUsedMethodIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnPreservedTypeIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnPreservedTypeWithTypeUsedInConstructorIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnPreservedTypeWithTypeUsedInDifferentNamespaceIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnPreservedTypeWithTypeUsedInFieldIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnPreservedTypeWithTypeUsedInPropertySetterIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnPreservedTypeWithUsedSetter() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnUsedFieldIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnUsedMethodIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnUsedPropertyIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task BoxedValues() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CoreLibraryAssemblyAttributesAreKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task FixedLengthArrayAttributesArePreserved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericAttributes() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task IVTUnused() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task IVTUnusedKeptWhenKeepingUsedAttributesOnly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task IVTUsed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MarshalAsCustomMarshaler() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MarshalAsCustomMarshalerInterface() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SecurityAttributesOnUsedMethodAreKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SecurityAttributesOnUsedTypeAreKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypeUsedInObjectArrayConstructorArgumentOnAttributeIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypeWithDynamicInterfaceCastableImplementationAttributeIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeatures.ETWTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeatures.ETWTests.g.cs index a820bbcfb0754f..595fd02114321c 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeatures.ETWTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeatures.ETWTests.g.cs @@ -4,22 +4,22 @@ namespace ILLink.RoslynAnalyzer.Tests.BCLFeatures { - public sealed partial class ETWTests : LinkerTestBase - { + public sealed partial class ETWTests : LinkerTestBase + { - protected override string TestSuiteName => "BCLFeatures.ETW"; + protected override string TestSuiteName => "BCLFeatures.ETW"; - [Fact] - public Task CustomEventSource () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CustomEventSource() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CustomLibraryEventSource () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CustomLibraryEventSource() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeaturesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeaturesTests.g.cs index 490fe5b7eaf96c..52e57e2a31b817 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeaturesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeaturesTests.g.cs @@ -4,16 +4,16 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class BCLFeaturesTests : LinkerTestBase - { + public sealed partial class BCLFeaturesTests : LinkerTestBase + { - protected override string TestSuiteName => "BCLFeatures"; + protected override string TestSuiteName => "BCLFeatures"; - [Fact] - public Task SerializationCtors () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task SerializationCtors() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs index 76a31b14d9561c..506ecf61be904f 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs @@ -4,178 +4,178 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class BasicTests : LinkerTestBase - { - - protected override string TestSuiteName => "Basic"; - - [Fact] - public Task ComplexNestedClassesHasUnusedRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DelegateBeginInvokeEndInvokePair () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InitializerForArrayIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InstantiatedTypeWithOverridesFromObject () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceMethodImplementedOnBaseClassDoesNotGetStripped () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LinkerHandlesRefFields () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MultiLevelNestedClassesAllRemovedWhenNonUsed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NestedDelegateInvokeMethodsPreserved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NeverInstantiatedTypeWithOverridesFromObject () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UninvokedInterfaceMemberGetsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedClassGetsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedDelegateGetsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedEnumGetsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedEventGetsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedFieldGetsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedFieldsOfStructsAreKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedMethodGetsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedNestedClassGetsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedPropertyGetsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedPropertySetterRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedEnumIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedEventIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedEventOnInterfaceIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedEventOnInterfaceIsRemovedWhenUsedFromClass () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedGenericInterfaceIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedInterfaceIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedPropertyIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedStructIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class BasicTests : LinkerTestBase + { + + protected override string TestSuiteName => "Basic"; + + [Fact] + public Task ComplexNestedClassesHasUnusedRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DelegateBeginInvokeEndInvokePair() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InitializerForArrayIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InstantiatedTypeWithOverridesFromObject() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceMethodImplementedOnBaseClassDoesNotGetStripped() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LinkerHandlesRefFields() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MultiLevelNestedClassesAllRemovedWhenNonUsed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NestedDelegateInvokeMethodsPreserved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithOverridesFromObject() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UninvokedInterfaceMemberGetsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedClassGetsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedDelegateGetsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedEnumGetsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedEventGetsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedFieldGetsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedFieldsOfStructsAreKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedMethodGetsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedNestedClassGetsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedPropertyGetsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedPropertySetterRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedEnumIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedEventIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedEventOnInterfaceIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedEventOnInterfaceIsRemovedWhenUsedFromClass() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedGenericInterfaceIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedInterfaceIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedPropertyIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedStructIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CodegenAnnotationTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CodegenAnnotationTests.g.cs index 46bf2126ad7fd4..c253b855f99cb6 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CodegenAnnotationTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CodegenAnnotationTests.g.cs @@ -4,16 +4,16 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class CodegenAnnotationTests : LinkerTestBase - { + public sealed partial class CodegenAnnotationTests : LinkerTestBase + { - protected override string TestSuiteName => "CodegenAnnotation"; + protected override string TestSuiteName => "CodegenAnnotation"; - [Fact] - public Task ReflectionBlockedTest () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task ReflectionBlockedTest() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLine.MvidTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLine.MvidTests.g.cs index 8236d814f1b6b6..2b5dfbefe86d09 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLine.MvidTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLine.MvidTests.g.cs @@ -4,34 +4,34 @@ namespace ILLink.RoslynAnalyzer.Tests.CommandLine { - public sealed partial class MvidTests : LinkerTestBase - { + public sealed partial class MvidTests : LinkerTestBase + { - protected override string TestSuiteName => "CommandLine.Mvid"; + protected override string TestSuiteName => "CommandLine.Mvid"; - [Fact] - public Task DefaultMvidBehavior () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task DefaultMvidBehavior() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task DeterministicMvidWorks () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task DeterministicMvidWorks() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task NewMvidWorks () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task NewMvidWorks() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task RetainMvid () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task RetainMvid() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLineTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLineTests.g.cs index 8e11b1a6ccaf24..3b312a92cd329a 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLineTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLineTests.g.cs @@ -4,46 +4,46 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class CommandLineTests : LinkerTestBase - { - - protected override string TestSuiteName => "CommandLine"; - - [Fact] - public Task AddCustomStep () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CustomStepApplyPreserve () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CustomStepData () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DuplicateRootAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InvalidArguments () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ResponseFilesWork () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class CommandLineTests : LinkerTestBase + { + + protected override string TestSuiteName => "CommandLine"; + + [Fact] + public Task AddCustomStep() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CustomStepApplyPreserve() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CustomStepData() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DuplicateRootAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InvalidArguments() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ResponseFilesWork() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ComponentModelTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ComponentModelTests.g.cs index 41dce7a9349ac1..23d36e5ce40ebd 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ComponentModelTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ComponentModelTests.g.cs @@ -4,28 +4,28 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class ComponentModelTests : LinkerTestBase - { + public sealed partial class ComponentModelTests : LinkerTestBase + { - protected override string TestSuiteName => "ComponentModel"; + protected override string TestSuiteName => "ComponentModel"; - [Fact] - public Task CustomTypeConvertor () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CustomTypeConvertor() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task TypeConverterOnMembers () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task TypeConverterOnMembers() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task TypeDescriptionProviderAttributeOnType () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task TypeDescriptionProviderAttributeOnType() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CoreLinkTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CoreLinkTests.g.cs index 06270991798430..310074052e0217 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CoreLinkTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CoreLinkTests.g.cs @@ -4,76 +4,76 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class CoreLinkTests : LinkerTestBase - { + public sealed partial class CoreLinkTests : LinkerTestBase + { - protected override string TestSuiteName => "CoreLink"; + protected override string TestSuiteName => "CoreLink"; - [Fact] - public Task CanOverrideIsTrimmableAttribute () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CanOverrideIsTrimmableAttribute() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CanUseIsTrimmableAttribute () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CanUseIsTrimmableAttribute() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CopyOfCoreLibrariesKeepsUnusedTypes () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CopyOfCoreLibrariesKeepsUnusedTypes() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task DelegateAndMulticastDelegateKeepInstantiatedReqs () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task DelegateAndMulticastDelegateKeepInstantiatedReqs() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task InstantiatedStructWithOverridesFromObject () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task InstantiatedStructWithOverridesFromObject() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task InstantiatedTypeWithOverridesFromObject () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task InstantiatedTypeWithOverridesFromObject() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task InvalidIsTrimmableAttribute () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task InvalidIsTrimmableAttribute() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task LinkingOfCoreLibrariesRemovesUnusedMethods () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task LinkingOfCoreLibrariesRemovesUnusedMethods() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task LinkingOfCoreLibrariesRemovesUnusedTypes () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task LinkingOfCoreLibrariesRemovesUnusedTypes() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task NeverInstantiatedTypeWithOverridesFromObject () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task NeverInstantiatedTypeWithOverridesFromObject() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task NoSecurityPlusOnlyKeepUsedRemovesAllSecurityAttributesFromCoreLibraries () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task NoSecurityPlusOnlyKeepUsedRemovesAllSecurityAttributesFromCoreLibraries() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CppCLITests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CppCLITests.g.cs index fd89497c6f13d1..4cd63bdf285736 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CppCLITests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CppCLITests.g.cs @@ -4,22 +4,22 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class CppCLITests : LinkerTestBase - { + public sealed partial class CppCLITests : LinkerTestBase + { - protected override string TestSuiteName => "CppCLI"; + protected override string TestSuiteName => "CppCLI"; - [Fact] - public Task CppCLIAssemblyIsAnalyzed () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CppCLIAssemblyIsAnalyzed() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task NonCopyActionWarnOnCppCLI () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task NonCopyActionWarnOnCppCLI() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs index a50e4dfd16075e..dc1ff8cb67c8ea 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs @@ -4,56 +4,56 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class DataFlowTests : LinkerTestBase - { - - [Fact] - public Task ExponentialDataFlow () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericParameterDataFlowMarking () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceImplementedThroughBaseValidation () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MethodByRefParameterDataFlow () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ModifierDataFlow () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task StaticInterfaceMethodDataflow () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TypeInfoIntrinsics () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnsafeDataFlow () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class DataFlowTests : LinkerTestBase + { + + [Fact] + public Task ExponentialDataFlow() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericParameterDataFlowMarking() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceImplementedThroughBaseValidation() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MethodByRefParameterDataFlow() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ModifierDataFlow() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task StaticInterfaceMethodDataflow() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypeInfoIntrinsics() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnsafeDataFlow() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DynamicDependenciesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DynamicDependenciesTests.g.cs index 0f707a45ec06a5..89fdfaa11820ca 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DynamicDependenciesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DynamicDependenciesTests.g.cs @@ -4,118 +4,118 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class DynamicDependenciesTests : LinkerTestBase - { - - protected override string TestSuiteName => "DynamicDependencies"; - - [Fact] - public Task DynamicDependencyField () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyFromAttributeXml () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyFromAttributeXmlOnNonReferencedAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyFromCopiedAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyKeptOption () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyMemberSignatureWildcard () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyMemberTypes () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyMethodInAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyMethodInNonReferencedAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyMethodInNonReferencedAssemblyChained () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyMethodInNonReferencedAssemblyChainedReference () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyMethodInNonReferencedAssemblyWithEmbeddedXml () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyMethodInNonReferencedAssemblyWithSweptReferences () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyOnForwardedType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyOnUnusedMethodInNonReferencedAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyOnUnusedMethodInNonReferencedAssemblyWithCopyUsedAction () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class DynamicDependenciesTests : LinkerTestBase + { + + protected override string TestSuiteName => "DynamicDependencies"; + + [Fact] + public Task DynamicDependencyField() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyFromAttributeXml() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyFromAttributeXmlOnNonReferencedAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyFromCopiedAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyKeptOption() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMemberSignatureWildcard() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMemberTypes() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethodInAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethodInNonReferencedAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethodInNonReferencedAssemblyChained() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethodInNonReferencedAssemblyChainedReference() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethodInNonReferencedAssemblyWithEmbeddedXml() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethodInNonReferencedAssemblyWithSweptReferences() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyOnForwardedType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyOnUnusedMethodInNonReferencedAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyOnUnusedMethodInNonReferencedAssemblyWithCopyUsedAction() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ExtensibilityTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ExtensibilityTests.g.cs index cd8ff52be10b30..259478c47f4011 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ExtensibilityTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ExtensibilityTests.g.cs @@ -4,70 +4,70 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class ExtensibilityTests : LinkerTestBase - { + public sealed partial class ExtensibilityTests : LinkerTestBase + { - protected override string TestSuiteName => "Extensibility"; + protected override string TestSuiteName => "Extensibility"; - [Fact] - public Task CustomStepCanFixAbstractMethods () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CustomStepCanFixAbstractMethods() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CustomStepCanPreserveMethodsAfterMark () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CustomStepCanPreserveMethodsAfterMark() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CustomStepCanPreserveMethodsBeforeMark () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CustomStepCanPreserveMethodsBeforeMark() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CustomStepCanResolveTypesAfterSweep () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CustomStepCanResolveTypesAfterSweep() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CustomStepsCanShareState () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CustomStepsCanShareState() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CustomWarningUsage () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CustomWarningUsage() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task MarkHandlerUsage () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task MarkHandlerUsage() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task MarkSubStepsDispatcherUsage () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task MarkSubStepsDispatcherUsage() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task SubStepDispatcherFields () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task SubStepDispatcherFields() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task SubStepDispatcherUsage () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task SubStepDispatcherUsage() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FeatureSettingsTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FeatureSettingsTests.g.cs index c381e22ffb3365..1ba066973bf6d9 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FeatureSettingsTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FeatureSettingsTests.g.cs @@ -4,34 +4,34 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class FeatureSettingsTests : LinkerTestBase - { + public sealed partial class FeatureSettingsTests : LinkerTestBase + { - protected override string TestSuiteName => "FeatureSettings"; + protected override string TestSuiteName => "FeatureSettings"; - [Fact] - public Task FeatureDescriptors () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task FeatureDescriptors() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task FeatureSubstitutions () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task FeatureSubstitutions() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task FeatureSubstitutionsInvalid () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task FeatureSubstitutionsInvalid() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task FeatureSubstitutionsNested () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task FeatureSubstitutionsNested() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FunctionPointersTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FunctionPointersTests.g.cs index 37dc04ddb8c4fd..c8ae211cee4d21 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FunctionPointersTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FunctionPointersTests.g.cs @@ -4,22 +4,22 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class FunctionPointersTests : LinkerTestBase - { + public sealed partial class FunctionPointersTests : LinkerTestBase + { - protected override string TestSuiteName => "FunctionPointers"; + protected override string TestSuiteName => "FunctionPointers"; - [Fact] - public Task CanCompileInterfaceWithFunctionPointerParameter () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CanCompileInterfaceWithFunctionPointerParameter() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CanCompileMethodWithFunctionPointerParameter () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CanCompileMethodWithFunctionPointerParameter() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/GenericsTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/GenericsTests.g.cs index 373e72a087b5f7..065c4b9bb96b60 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/GenericsTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/GenericsTests.g.cs @@ -4,104 +4,104 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class GenericsTests : LinkerTestBase - { - - [Fact] - public Task ArrayVariantCasting () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ByRefLike () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CorrectOverloadedMethodGetsStrippedInGenericClass () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DerivedClassWithMethodOfSameNameAsBaseButDifferentNumberOfGenericParametersUnusedBaseWillGetStripped () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInstanceInterfaceMethodImplementedWithDifferentGenericArgumentNameDoesNotGetStripped () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MdArrayVariantCasting () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MethodWithParameterWhichHasGenericParametersAndOverrideUsesADifferentNameForGenericParameter () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MethodWithParameterWhichHasGenericParametersAndOverrideUsesADifferentNameForGenericParameterNestedCase () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MethodWithParameterWhichHasGenericParametersAndOverrideUsesADifferentNameForGenericParameterNestedCase2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NewConstraintOnClass () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OverrideWithAnotherVirtualMethodOfSameNameWithDifferentParameterType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnresolvedGenerics () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedOverloadedGenericMethodInGenericClassIsNotStripped () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedOverloadedGenericMethodInstanceInGenericClassIsNotStripped () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedOverloadedGenericMethodWithNoParametersIsNotStripped () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task VariantCasting () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class GenericsTests : LinkerTestBase + { + + [Fact] + public Task ArrayVariantCasting() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ByRefLike() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CorrectOverloadedMethodGetsStrippedInGenericClass() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DerivedClassWithMethodOfSameNameAsBaseButDifferentNumberOfGenericParametersUnusedBaseWillGetStripped() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInstanceInterfaceMethodImplementedWithDifferentGenericArgumentNameDoesNotGetStripped() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MdArrayVariantCasting() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MethodWithParameterWhichHasGenericParametersAndOverrideUsesADifferentNameForGenericParameter() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MethodWithParameterWhichHasGenericParametersAndOverrideUsesADifferentNameForGenericParameterNestedCase() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MethodWithParameterWhichHasGenericParametersAndOverrideUsesADifferentNameForGenericParameterNestedCase2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NewConstraintOnClass() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OverrideWithAnotherVirtualMethodOfSameNameWithDifferentParameterType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnresolvedGenerics() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedOverloadedGenericMethodInGenericClassIsNotStripped() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedOverloadedGenericMethodInstanceInGenericClassIsNotStripped() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedOverloadedGenericMethodWithNoParametersIsNotStripped() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task VariantCasting() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NoKeptCtor.OverrideRemovalTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NoKeptCtor.OverrideRemovalTests.g.cs index 5a63e7af55e7f8..021323244f6e5a 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NoKeptCtor.OverrideRemovalTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NoKeptCtor.OverrideRemovalTests.g.cs @@ -4,64 +4,64 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.AbstractClasses.NoKeptCtor { - public sealed partial class OverrideRemovalTests : LinkerTestBase - { + public sealed partial class OverrideRemovalTests : LinkerTestBase + { - protected override string TestSuiteName => "Inheritance.AbstractClasses.NoKeptCtor.OverrideRemoval"; + protected override string TestSuiteName => "Inheritance.AbstractClasses.NoKeptCtor.OverrideRemoval"; - [Fact] - public Task CanDisableOverrideRemoval () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CanDisableOverrideRemoval() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task OverrideOfAbstractIsKept () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task OverrideOfAbstractIsKept() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task OverrideOfAbstractIsKeptNonEmpty () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task OverrideOfAbstractIsKeptNonEmpty() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task OverrideOfVirtualCanBeRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task OverrideOfVirtualCanBeRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task OverrideOfVirtualCanBeRemoved2 () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task OverrideOfVirtualCanBeRemoved2() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task OverrideOfVirtualCanBeRemoved3 () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task OverrideOfVirtualCanBeRemoved3() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task OverrideThatAlsoFulfilsInterface () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task OverrideThatAlsoFulfilsInterface() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task PreservesOverriddenMethodOverrideOfUsedVirtualStillRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task PreservesOverriddenMethodOverrideOfUsedVirtualStillRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task PreservesOverriddenMethodOverrideOfUsedVirtualStillRemoved2 () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task PreservesOverriddenMethodOverrideOfUsedVirtualStillRemoved2() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NotKeptCtorTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NotKeptCtorTests.g.cs index 7b3464d10f4d26..0667abb1ed7714 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NotKeptCtorTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NotKeptCtorTests.g.cs @@ -4,46 +4,46 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.AbstractClasses { - public sealed partial class NotKeptCtorTests : LinkerTestBase - { - - protected override string TestSuiteName => "Inheritance.AbstractClasses.NotKeptCtor"; - - [Fact] - public Task NeverInstantiatedTypeWithBaseInCopiedAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NeverInstantiatedTypeWithBaseInCopiedAssembly2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NeverInstantiatedTypeWithBaseInCopiedAssembly3 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NeverInstantiatedTypeWithBaseInCopiedAssembly4 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NeverInstantiatedTypeWithBaseInCopiedAssembly5 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NeverInstantiatedTypeWithBaseInCopiedAssembly6 () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class NotKeptCtorTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.AbstractClasses.NotKeptCtor"; + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly3() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly4() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly5() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly6() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClassesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClassesTests.g.cs index 0c5c86f4eb06b4..c40e82652c95ec 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClassesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClassesTests.g.cs @@ -4,70 +4,70 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance { - public sealed partial class AbstractClassesTests : LinkerTestBase - { + public sealed partial class AbstractClassesTests : LinkerTestBase + { - protected override string TestSuiteName => "Inheritance.AbstractClasses"; + protected override string TestSuiteName => "Inheritance.AbstractClasses"; - [Fact] - public Task TypeWithBaseInCopiedAssembly () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task TypeWithBaseInCopiedAssembly() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task TypeWithBaseInCopiedAssembly2 () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task TypeWithBaseInCopiedAssembly2() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task TypeWithBaseInCopiedAssembly3 () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task TypeWithBaseInCopiedAssembly3() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task TypeWithBaseInCopiedAssembly4 () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task TypeWithBaseInCopiedAssembly4() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task TypeWithBaseInCopiedAssembly5 () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task TypeWithBaseInCopiedAssembly5() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task TypeWithBaseInCopiedAssembly6 () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task TypeWithBaseInCopiedAssembly6() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UnusedAbstractMethodRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UnusedAbstractMethodRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UnusedVirtualMethodRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UnusedVirtualMethodRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UsedOverrideOfAbstractMethodIsKept () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UsedOverrideOfAbstractMethodIsKept() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UsedOverrideOfVirtualMethodIsKept () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UsedOverrideOfVirtualMethodIsKept() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Complex.NoKeptCtorTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Complex.NoKeptCtorTests.g.cs index 17bde96cc57041..d806d6b9648598 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Complex.NoKeptCtorTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Complex.NoKeptCtorTests.g.cs @@ -4,22 +4,22 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Complex { - public sealed partial class NoKeptCtorTests : LinkerTestBase - { + public sealed partial class NoKeptCtorTests : LinkerTestBase + { - protected override string TestSuiteName => "Inheritance.Complex.NoKeptCtor"; + protected override string TestSuiteName => "Inheritance.Complex.NoKeptCtor"; - [Fact] - public Task OverrideOfAbstractAndInterfaceMethodWhenInterfaceRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task OverrideOfAbstractAndInterfaceMethodWhenInterfaceRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task OverrideOfAbstractAndInterfaceMethodWhenInterfaceRemoved2 () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task OverrideOfAbstractAndInterfaceMethodWhenInterfaceRemoved2() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.BaseProvidesInterfaceEdgeCaseTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.BaseProvidesInterfaceEdgeCaseTests.g.cs index 541aeee031dedd..ce9e82a81c242a 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.BaseProvidesInterfaceEdgeCaseTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.BaseProvidesInterfaceEdgeCaseTests.g.cs @@ -4,16 +4,16 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces { - public sealed partial class BaseProvidesInterfaceEdgeCaseTests : LinkerTestBase - { + public sealed partial class BaseProvidesInterfaceEdgeCaseTests : LinkerTestBase + { - protected override string TestSuiteName => "Inheritance.Interfaces.BaseProvidesInterfaceEdgeCase"; + protected override string TestSuiteName => "Inheritance.Interfaces.BaseProvidesInterfaceEdgeCase"; - [Fact] - public Task BaseProvidesInterfaceMethodCircularReference () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task BaseProvidesInterfaceMethodCircularReference() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.DefaultInterfaceMethodsTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.DefaultInterfaceMethodsTests.g.cs index 19189bfcd01705..b12c24c773c6d1 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.DefaultInterfaceMethodsTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.DefaultInterfaceMethodsTests.g.cs @@ -4,76 +4,76 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces { - public sealed partial class DefaultInterfaceMethodsTests : LinkerTestBase - { + public sealed partial class DefaultInterfaceMethodsTests : LinkerTestBase + { - protected override string TestSuiteName => "Inheritance.Interfaces.DefaultInterfaceMethods"; + protected override string TestSuiteName => "Inheritance.Interfaces.DefaultInterfaceMethods"; - [Fact] - public Task DefaultInterfaceMethodCallIntoClass () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task DefaultInterfaceMethodCallIntoClass() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task DimProvidedByRecursiveInterface () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task DimProvidedByRecursiveInterface() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task GenericDefaultInterfaceMethods () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task GenericDefaultInterfaceMethods() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task InterfaceWithAttributeOnImplementation () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task InterfaceWithAttributeOnImplementation() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task MostSpecificDefaultImplementationKeptInstance () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task MostSpecificDefaultImplementationKeptInstance() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task MostSpecificDefaultImplementationKeptStatic () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task MostSpecificDefaultImplementationKeptStatic() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task MultipleDimsProvidedByRecursiveInterface () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task MultipleDimsProvidedByRecursiveInterface() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task SimpleDefaultInterfaceMethod () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task SimpleDefaultInterfaceMethod() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task StaticDefaultInterfaceMethodOnStruct () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task StaticDefaultInterfaceMethodOnStruct() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task StaticDimProvidedByUnreferencedIfaceInHierarchy () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task StaticDimProvidedByUnreferencedIfaceInHierarchy() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UnusedDefaultInterfaceImplementation () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UnusedDefaultInterfaceImplementation() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.BaseProvidesInterfaceMemberTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.BaseProvidesInterfaceMemberTests.g.cs index 80d525848b2153..56cb79b535609c 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.BaseProvidesInterfaceMemberTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.BaseProvidesInterfaceMemberTests.g.cs @@ -4,184 +4,184 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces.OnReferenceType { - public sealed partial class BaseProvidesInterfaceMemberTests : LinkerTestBase - { - - protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType.BaseProvidesInterfaceMember"; - - [Fact] - public Task GenericInterfaceWithEvent () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithGenericBaseMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithGenericBaseMethodWithExplicit () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithGenericMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithGenericMethod2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithGenericMethod3 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithMethod2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithMethod3 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithMethodComplex () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithMethodComplex2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithMethodManyBaseInterfaces () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithMethodManyBases () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithMethodManyBases2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithMethodManyBases3 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithMethodManyVariations () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithMethodNested () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithMethodOnNoInstanceCtor () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithMethodOnNoInstanceCtor2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithPropertyGetter () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithPropertyGetter2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithPropertySetter () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericInterfaceWithPropertySetter2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceRemovedWhenMethodUsedDirectly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SimpleEvent () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SimpleMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SimpleMethodOnNoInstanceCtor () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SimpleMethodOnNoInstanceCtor2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SimpleProperty () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class BaseProvidesInterfaceMemberTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType.BaseProvidesInterfaceMember"; + + [Fact] + public Task GenericInterfaceWithEvent() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithGenericBaseMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithGenericBaseMethodWithExplicit() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithGenericMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithGenericMethod2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithGenericMethod3() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethod2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethod3() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodComplex() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodComplex2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodManyBaseInterfaces() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodManyBases() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodManyBases2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodManyBases3() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodManyVariations() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodNested() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodOnNoInstanceCtor() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodOnNoInstanceCtor2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithPropertyGetter() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithPropertyGetter2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithPropertySetter() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithPropertySetter2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceRemovedWhenMethodUsedDirectly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SimpleEvent() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SimpleMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SimpleMethodOnNoInstanceCtor() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SimpleMethodOnNoInstanceCtor2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SimpleProperty() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoInstanceCtorTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoInstanceCtorTests.g.cs index c363a76e7abce9..c245d2a0a06c6f 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoInstanceCtorTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoInstanceCtorTests.g.cs @@ -4,52 +4,52 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces.OnReferenceType { - public sealed partial class NoInstanceCtorTests : LinkerTestBase - { - - protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType.NoInstanceCtor"; - - [Fact] - public Task NoInstanceCtorAndAssemblyPreserveAll () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NoInstanceCtorAndTypePreserveAll () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NoInstanceCtorAndTypePreserveFields () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NoInstanceCtorAndTypePreserveFieldsWithInterfacesMarked () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NoInstanceCtorAndTypePreserveMethods () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NoInstanceCtorAndTypePreserveMethodsWithInterfacesMarked () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NoInstanceCtorAndTypePreserveNone () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class NoInstanceCtorTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType.NoInstanceCtor"; + + [Fact] + public Task NoInstanceCtorAndAssemblyPreserveAll() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NoInstanceCtorAndTypePreserveAll() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NoInstanceCtorAndTypePreserveFields() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NoInstanceCtorAndTypePreserveFieldsWithInterfacesMarked() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NoInstanceCtorAndTypePreserveMethods() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NoInstanceCtorAndTypePreserveMethodsWithInterfacesMarked() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NoInstanceCtorAndTypePreserveNone() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorButInterfaceNeededTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorButInterfaceNeededTests.g.cs index 92418533bf13db..664f3d06fb2f5c 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorButInterfaceNeededTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorButInterfaceNeededTests.g.cs @@ -4,148 +4,148 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces.OnReferenceType { - public sealed partial class NoKeptCtorButInterfaceNeededTests : LinkerTestBase - { - - protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType.NoKeptCtorButInterfaceNeeded"; - - [Fact] - public Task ArrayWithIndexAssignedToReturnValue () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task FieldDowncastedToInterface () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericTypeWithConstraint () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericTypeWithConstraint2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericTypeWithConstraint3 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceOnMultipleBases () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LocalAndNestedInterfaces () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LocalArrayPassedAsParameter () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LocalDowncastedToInterface () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LocalPassedAsParameter () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LocalPassedAsParameterToGeneric () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LocalPassedAsParameterToGenericWithConstraint () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LocalPassedAsParameterToGenericWithConstraint2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NestedInterfaces1 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NestedInterfaces2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NestedInterfaces3 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NestedInterfacesWithExplicit1 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NestedInterfacesWithExplicitAndNormal1 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ParameterAndLocal () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ParameterOutAndLocal () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ParameterRefAndLocal () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReturnValueDowncastedToInterface () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class NoKeptCtorButInterfaceNeededTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType.NoKeptCtorButInterfaceNeeded"; + + [Fact] + public Task ArrayWithIndexAssignedToReturnValue() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task FieldDowncastedToInterface() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericTypeWithConstraint() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericTypeWithConstraint2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericTypeWithConstraint3() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceOnMultipleBases() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LocalAndNestedInterfaces() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LocalArrayPassedAsParameter() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LocalDowncastedToInterface() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LocalPassedAsParameter() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LocalPassedAsParameterToGeneric() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LocalPassedAsParameterToGenericWithConstraint() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LocalPassedAsParameterToGenericWithConstraint2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NestedInterfaces1() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NestedInterfaces2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NestedInterfaces3() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NestedInterfacesWithExplicit1() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NestedInterfacesWithExplicitAndNormal1() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ParameterAndLocal() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ParameterOutAndLocal() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ParameterRefAndLocal() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReturnValueDowncastedToInterface() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorTests.g.cs index 042e0d0fa1ecdf..164840d835d7c4 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorTests.g.cs @@ -4,124 +4,124 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces.OnReferenceType { - public sealed partial class NoKeptCtorTests : LinkerTestBase - { - - protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType.NoKeptCtor"; - - [Fact] - public Task ComInterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DynamicDependencyPreservesInterfaceMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ExplicitInterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task GenericWithConstraintDoesNotCauseOtherTypesToKeepInterface () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsedWithCctor () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceFromCopiedAssemblyCanBeRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethodMultiple () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LocalDowncastDoesNotCuaseOtherTypesToKeepInterface () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ObjectHardCastedToInterface () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyPreservesInterfaceMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeHasExplicitInterfaceMethodPreservedViaXml () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeHasExplicitInterfacePropertyPreservedViaXml () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeHasInterfaceMethodPreservedViaXml () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeWithPreserveFields () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeWithPreserveMethods () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeWithPreserveMethodsAndInterfaceTypeMarked () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class NoKeptCtorTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType.NoKeptCtor"; + + [Fact] + public Task ComInterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyPreservesInterfaceMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ExplicitInterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericWithConstraintDoesNotCauseOtherTypesToKeepInterface() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsedWithCctor() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceFromCopiedAssemblyCanBeRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethodMultiple() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LocalDowncastDoesNotCuaseOtherTypesToKeepInterface() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ObjectHardCastedToInterface() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyPreservesInterfaceMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeHasExplicitInterfaceMethodPreservedViaXml() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeHasExplicitInterfacePropertyPreservedViaXml() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeHasInterfaceMethodPreservedViaXml() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveFields() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveMethods() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveMethodsAndInterfaceTypeMarked() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceTypeTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceTypeTests.g.cs index d87fcc06d688fe..1d09a7c1895c5a 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceTypeTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceTypeTests.g.cs @@ -4,184 +4,184 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces { - public sealed partial class OnReferenceTypeTests : LinkerTestBase - { - - protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType"; - - [Fact] - public Task ClassImplementingInterfaceMethodsNested () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ClassImplementingInterfaceMethodsNested2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ClassImplemtingInterfaceMethodsThroughBaseClass2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ClassImplemtingInterfaceMethodsThroughBaseClass3 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ClassImplemtingInterfaceMethodsThroughBaseClass4 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ClassImplemtingInterfaceMethodsThroughBaseClass5 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ClassImplemtingInterfaceMethodsThroughBaseClass6 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ClassUsedFromConcreteTypeHasInterfaceMethodRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ClassUsedFromConcreteTypeHasInterfaceMethodRemoved2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ClassUsedFromInterfaceHasInterfaceMethodKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ExplicitInterfaceMethodWhichCreatesInstanceOfParentType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceMarkOrderingDoesNotMatter () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceMarkOrderingDoesNotMatter2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceMarkOrderingDoesNotMatter3 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceNeededOnUnrelatedInterfaceList () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceTypeInOtherUsedOnlyByCopiedAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceTypeInOtherUsedOnlyByCopiedAssemblyExplicit () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceTypeOnlyUsedHasInterfacesRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceUsedOnlyAsConstraintIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceWithInterfaceFromOtherAssemblyWhenExplicitMethodUsed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ObjectCastedToSecondInterfaceHasMemberRemovedButInterfaceKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TypeGetsMarkedThatImplementsAlreadyMarkedInterfaceMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedComInterfaceIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedComInterfaceIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedExplicitInterfaceHasMethodPreservedViaXml () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedExplicitInterfaceIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedGenericInterfaceIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedInterfaceHasMethodPreservedViaXml () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedInterfaceTypeIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class OnReferenceTypeTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType"; + + [Fact] + public Task ClassImplementingInterfaceMethodsNested() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ClassImplementingInterfaceMethodsNested2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ClassImplemtingInterfaceMethodsThroughBaseClass2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ClassImplemtingInterfaceMethodsThroughBaseClass3() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ClassImplemtingInterfaceMethodsThroughBaseClass4() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ClassImplemtingInterfaceMethodsThroughBaseClass5() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ClassImplemtingInterfaceMethodsThroughBaseClass6() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ClassUsedFromConcreteTypeHasInterfaceMethodRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ClassUsedFromConcreteTypeHasInterfaceMethodRemoved2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ClassUsedFromInterfaceHasInterfaceMethodKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ExplicitInterfaceMethodWhichCreatesInstanceOfParentType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceMarkOrderingDoesNotMatter() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceMarkOrderingDoesNotMatter2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceMarkOrderingDoesNotMatter3() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceNeededOnUnrelatedInterfaceList() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceTypeInOtherUsedOnlyByCopiedAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceTypeInOtherUsedOnlyByCopiedAssemblyExplicit() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceTypeOnlyUsedHasInterfacesRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceUsedOnlyAsConstraintIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceWithInterfaceFromOtherAssemblyWhenExplicitMethodUsed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ObjectCastedToSecondInterfaceHasMemberRemovedButInterfaceKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypeGetsMarkedThatImplementsAlreadyMarkedInterfaceMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedComInterfaceIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedComInterfaceIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedExplicitInterfaceHasMethodPreservedViaXml() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedExplicitInterfaceIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedGenericInterfaceIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedInterfaceHasMethodPreservedViaXml() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedInterfaceTypeIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueType.NoKeptCtorTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueType.NoKeptCtorTests.g.cs index fc3a399179e487..df5a3bf3301475 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueType.NoKeptCtorTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueType.NoKeptCtorTests.g.cs @@ -4,34 +4,34 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces.OnValueType { - public sealed partial class NoKeptCtorTests : LinkerTestBase - { + public sealed partial class NoKeptCtorTests : LinkerTestBase + { - protected override string TestSuiteName => "Inheritance.Interfaces.OnValueType.NoKeptCtor"; + protected override string TestSuiteName => "Inheritance.Interfaces.OnValueType.NoKeptCtor"; - [Fact] - public Task InterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsed () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task InterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsed() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task InterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsedWithCctor () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task InterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsedWithCctor() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task InterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethod () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task InterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethod() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task InterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethodMultiple () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task InterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethodMultiple() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueTypeTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueTypeTests.g.cs index 6a2d53990c80e1..cbaedf1d6b723d 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueTypeTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueTypeTests.g.cs @@ -4,70 +4,70 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces { - public sealed partial class OnValueTypeTests : LinkerTestBase - { + public sealed partial class OnValueTypeTests : LinkerTestBase + { - protected override string TestSuiteName => "Inheritance.Interfaces.OnValueType"; + protected override string TestSuiteName => "Inheritance.Interfaces.OnValueType"; - [Fact] - public Task StructImplementingInterfaceMethodsNested () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task StructImplementingInterfaceMethodsNested() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task StructImplementingInterfaceMethodsNested2 () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task StructImplementingInterfaceMethodsNested2() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task StructUsedFromConcreteTypeHasInterfaceMethodRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task StructUsedFromConcreteTypeHasInterfaceMethodRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task StructUsedFromConcreteTypeHasInterfaceMethodRemoved2 () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task StructUsedFromConcreteTypeHasInterfaceMethodRemoved2() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task StructUsedFromInterfaceHasInterfaceMethodKept () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task StructUsedFromInterfaceHasInterfaceMethodKept() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task StructWithNestedStructImplementingInterface () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task StructWithNestedStructImplementingInterface() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UnusedExplicitInterfaceHasMethodPreservedViaXml () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UnusedExplicitInterfaceHasMethodPreservedViaXml() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UnusedExplicitInterfaceIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UnusedExplicitInterfaceIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UnusedInterfaceHasMethodPreservedViaXml () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UnusedInterfaceHasMethodPreservedViaXml() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UnusedInterfaceTypeIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UnusedInterfaceTypeIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.RecursiveInterfacesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.RecursiveInterfacesTests.g.cs index 35cc0b65c0417b..87ef911ccc0b28 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.RecursiveInterfacesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.RecursiveInterfacesTests.g.cs @@ -4,34 +4,34 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces { - public sealed partial class RecursiveInterfacesTests : LinkerTestBase - { + public sealed partial class RecursiveInterfacesTests : LinkerTestBase + { - protected override string TestSuiteName => "Inheritance.Interfaces.RecursiveInterfaces"; + protected override string TestSuiteName => "Inheritance.Interfaces.RecursiveInterfaces"; - [Fact] - public Task GenericInterfaceImplementedRecursively () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task GenericInterfaceImplementedRecursively() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task InterfaceImplementedRecursively () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task InterfaceImplementedRecursively() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task OverrideOfRecursiveInterfaceIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task OverrideOfRecursiveInterfaceIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task RecursiveInterfaceKept () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task RecursiveInterfaceKept() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.StaticInterfaceMethodsTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.StaticInterfaceMethodsTests.g.cs index 531c0cb0d7d08a..afacf94703e332 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.StaticInterfaceMethodsTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.StaticInterfaceMethodsTests.g.cs @@ -4,32 +4,32 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces { - public sealed partial class StaticInterfaceMethodsTests : LinkerTestBase - { + public sealed partial class StaticInterfaceMethodsTests : LinkerTestBase + { - [Fact] - public Task InstanceMethodsWithOverridesSwept () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task InstanceMethodsWithOverridesSwept() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task OverrideInCopyAssembly () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task OverrideInCopyAssembly() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task OverrideInSaveAssembly () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task OverrideInSaveAssembly() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task VarianceBasic () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task VarianceBasic() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.InterfacesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.InterfacesTests.g.cs index 07680c1c9d5e6a..7b20f91cb7f566 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.InterfacesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.InterfacesTests.g.cs @@ -4,46 +4,46 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance { - public sealed partial class InterfacesTests : LinkerTestBase - { - - protected override string TestSuiteName => "Inheritance.Interfaces"; - - [Fact] - public Task CanDisableUnusedInterfaces () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceImplementedThroughBaseInterface () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceOnUninstantiatedTypeRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceVariants () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceVariantsGeneric () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceWithoutNewSlot () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class InterfacesTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces"; + + [Fact] + public Task CanDisableUnusedInterfaces() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceImplementedThroughBaseInterface() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceOnUninstantiatedTypeRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceVariants() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceVariantsGeneric() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceWithoutNewSlot() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethods.NotKeptCtorTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethods.NotKeptCtorTests.g.cs index bf67ff17ef482a..d54a4afa9be4dc 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethods.NotKeptCtorTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethods.NotKeptCtorTests.g.cs @@ -4,16 +4,16 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance.VirtualMethods { - public sealed partial class NotKeptCtorTests : LinkerTestBase - { + public sealed partial class NotKeptCtorTests : LinkerTestBase + { - protected override string TestSuiteName => "Inheritance.VirtualMethods.NotKeptCtor"; + protected override string TestSuiteName => "Inheritance.VirtualMethods.NotKeptCtor"; - [Fact] - public Task NeverInstantiatedTypeWithBaseInCopiedAssembly () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethodsTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethodsTests.g.cs index 8a7aab5c61b398..a8371a3f397432 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethodsTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethodsTests.g.cs @@ -4,70 +4,70 @@ namespace ILLink.RoslynAnalyzer.Tests.Inheritance { - public sealed partial class VirtualMethodsTests : LinkerTestBase - { + public sealed partial class VirtualMethodsTests : LinkerTestBase + { - protected override string TestSuiteName => "Inheritance.VirtualMethods"; + protected override string TestSuiteName => "Inheritance.VirtualMethods"; - [Fact] - public Task BaseIsInSkipAssembly () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task BaseIsInSkipAssembly() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task HarderToDetectUnusedVirtualMethodGetsRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task HarderToDetectUnusedVirtualMethodGetsRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task NeverInstantiatedTypeWithBaseInCopiedAssembly () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task OverrideOfAbstractInUnmarkedClassIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task OverrideOfAbstractInUnmarkedClassIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UnusedTypeWithOverrideOfVirtualMethodIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UnusedTypeWithOverrideOfVirtualMethodIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UnusedVirtualMethodRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UnusedVirtualMethodRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UsedOverrideOfVirtualMethodIsKept () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UsedOverrideOfVirtualMethodIsKept() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UsedTypeWithOverrideOfVirtualMethodHasOverrideKept () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UsedTypeWithOverrideOfVirtualMethodHasOverrideKept() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task VirtualMethodGetsPreservedIfBaseMethodGetsInvoked () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task VirtualMethodGetsPreservedIfBaseMethodGetsInvoked() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task VirtualMethodGetsStrippedIfImplementingMethodGetsInvokedDirectly () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task VirtualMethodGetsStrippedIfImplementingMethodGetsInvokedDirectly() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/InteropTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/InteropTests.g.cs index 7d83d81ef1e3ce..1ec6531b4cc36d 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/InteropTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/InteropTests.g.cs @@ -4,16 +4,16 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class InteropTests : LinkerTestBase - { + public sealed partial class InteropTests : LinkerTestBase + { - protected override string TestSuiteName => "Interop"; + protected override string TestSuiteName => "Interop"; - [Fact] - public Task ByteArrayCom () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task ByteArrayCom() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LibrariesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LibrariesTests.g.cs index 03c76d0f1ee9de..efb3db6a2cdc4a 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LibrariesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LibrariesTests.g.cs @@ -4,88 +4,88 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class LibrariesTests : LinkerTestBase - { - - protected override string TestSuiteName => "Libraries"; - - [Fact] - public Task CanLinkPublicApisOfLibrary () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CopyUsedAssemblyWithMainEntryRoot () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CopyUsedAssemblyWithPublicRoots () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DefaultLibraryLinkBehavior () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LibraryWithUnresolvedInterfaces () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task RootAllLibraryBehavior () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task RootAllLibraryCopyBehavior () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task RootLibrary () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task RootLibraryInternalsWithIVT () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task RootLibraryVisibleAndDescriptor () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task RootLibraryVisibleForwarders () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task RootLibraryVisibleForwardersWithoutReference () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UserAssemblyActionWorks () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class LibrariesTests : LinkerTestBase + { + + protected override string TestSuiteName => "Libraries"; + + [Fact] + public Task CanLinkPublicApisOfLibrary() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CopyUsedAssemblyWithMainEntryRoot() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CopyUsedAssemblyWithPublicRoots() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DefaultLibraryLinkBehavior() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LibraryWithUnresolvedInterfaces() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task RootAllLibraryBehavior() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task RootAllLibraryCopyBehavior() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task RootLibrary() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task RootLibraryInternalsWithIVT() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task RootLibraryVisibleAndDescriptor() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task RootLibraryVisibleForwarders() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task RootLibraryVisibleForwardersWithoutReference() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UserAssemblyActionWorks() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkAttributesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkAttributesTests.g.cs index 909529f78229c3..242a95982f2615 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkAttributesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkAttributesTests.g.cs @@ -4,56 +4,56 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class LinkAttributesTests : LinkerTestBase - { - - [Fact] - public Task AssemblyLevelLinkerAttributeRemoval () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task EmbeddedLinkAttributesInReferencedAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task EmbeddedLinkAttributesInReferencedAssembly_AssemblyLevel () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task FeatureAttributeRemovalInCopyAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LinkAttributeErrorCases () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LinkerAttributeRemovalAndPreserveAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OverrideAttributeRemoval () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TypedArgumentsErrors () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class LinkAttributesTests : LinkerTestBase + { + + [Fact] + public Task AssemblyLevelLinkerAttributeRemoval() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkAttributesInReferencedAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkAttributesInReferencedAssembly_AssemblyLevel() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task FeatureAttributeRemovalInCopyAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LinkAttributeErrorCases() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LinkerAttributeRemovalAndPreserveAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OverrideAttributeRemoval() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypedArgumentsErrors() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkXmlTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkXmlTests.g.cs index 689072942e5bb0..b0c78fffd489ed 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkXmlTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkXmlTests.g.cs @@ -4,226 +4,226 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class LinkXmlTests : LinkerTestBase - { - - protected override string TestSuiteName => "LinkXml"; - - [Fact] - public Task AssemblyWithPreserveAll () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanPreserveAnExportedType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanPreserveExportedTypesUsingRegex () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanPreserveNamespace () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanPreserveTypesUsingRegex () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task EmbeddedLinkXmlFromCopyAssemblyIsProcessed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task EmbeddedLinkXmlPreservesAdditionalAssemblyWithOverriddenMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task EmbeddedLinkXmlUnresolvedReferencesAreReported () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LinkXmlErrorCases () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveIndividualMembersOfNonRequiredType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveSecondLevelMethodsOfNonRequiredType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TypeWithPreserveFieldsHasBackingFieldsOfPropertiesRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedAssemblyWithNoDefinedPreserveHasAllTypesPreserved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedEventPreservedByLinkXmlIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedFieldPreservedByLinkXmlIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedGenericTypeWithPreserveAllHasAllMembersPreserved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedInterfaceTypeOnTypeWithPreserveAllIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedInterfaceTypeOnTypeWithPreserveNothingIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedMethodPreservedByLinkXmlIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedNestedTypePreservedByLinkXmlIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedNonRequiredTypeIsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedPropertyPreservedByLinkXmlIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeDeclarationPreservedByLinkXmlIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeIsPresservedWhenEntireAssemblyIsPreserved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypePreservedByLinkXmlIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypePreservedByLinkXmlWithCommentIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeWithNoDefinedPreserveHasAllMembersPreserved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeWithPreserveAllHasAllMembersPreserved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeWithPreserveFieldsHasMethodsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeWithPreserveMethodsHasFieldsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeWithPreserveNothingAndPreserveMembers () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedTypeWithPreserveNothingHasMembersRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedNonRequiredExportedTypeIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedNonRequiredExportedTypeIsKeptWhenRooted () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedNonRequiredTypeIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedNonRequiredTypeIsKeptWithSingleMethod () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class LinkXmlTests : LinkerTestBase + { + + protected override string TestSuiteName => "LinkXml"; + + [Fact] + public Task AssemblyWithPreserveAll() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanPreserveAnExportedType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanPreserveExportedTypesUsingRegex() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanPreserveNamespace() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanPreserveTypesUsingRegex() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlFromCopyAssemblyIsProcessed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlPreservesAdditionalAssemblyWithOverriddenMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlUnresolvedReferencesAreReported() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LinkXmlErrorCases() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveIndividualMembersOfNonRequiredType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveSecondLevelMethodsOfNonRequiredType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypeWithPreserveFieldsHasBackingFieldsOfPropertiesRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAssemblyWithNoDefinedPreserveHasAllTypesPreserved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedEventPreservedByLinkXmlIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedFieldPreservedByLinkXmlIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedGenericTypeWithPreserveAllHasAllMembersPreserved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedInterfaceTypeOnTypeWithPreserveAllIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedInterfaceTypeOnTypeWithPreserveNothingIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedMethodPreservedByLinkXmlIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedNestedTypePreservedByLinkXmlIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedNonRequiredTypeIsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedPropertyPreservedByLinkXmlIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeDeclarationPreservedByLinkXmlIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeIsPresservedWhenEntireAssemblyIsPreserved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypePreservedByLinkXmlIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypePreservedByLinkXmlWithCommentIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithNoDefinedPreserveHasAllMembersPreserved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveAllHasAllMembersPreserved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveFieldsHasMethodsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveMethodsHasFieldsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveNothingAndPreserveMembers() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveNothingHasMembersRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedNonRequiredExportedTypeIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedNonRequiredExportedTypeIsKeptWhenRooted() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedNonRequiredTypeIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedNonRequiredTypeIsKeptWithSingleMethod() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinqExpressionsTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinqExpressionsTests.g.cs index b3f6765c4e201d..72d95d766445fe 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinqExpressionsTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinqExpressionsTests.g.cs @@ -4,46 +4,46 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class LinqExpressionsTests : LinkerTestBase - { - - protected override string TestSuiteName => "LinqExpressions"; - - [Fact] - public Task CanDisableOperatorDiscovery () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanPreserveCustomOperators () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanPreserveNullableCustomOperators () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanRemoveMethodsNamedLikeCustomOperators () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanRemoveOperatorsWhenNotUsingLinqExpressions () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CustomOperatorsWithUnusedArgumentTypes () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class LinqExpressionsTests : LinkerTestBase + { + + protected override string TestSuiteName => "LinqExpressions"; + + [Fact] + public Task CanDisableOperatorDiscovery() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanPreserveCustomOperators() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanPreserveNullableCustomOperators() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanRemoveMethodsNamedLikeCustomOperators() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanRemoveOperatorsWhenNotUsingLinqExpressions() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CustomOperatorsWithUnusedArgumentTypes() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LoggingTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LoggingTests.g.cs index b5b68c0396102c..6c23cd96c0bdae 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LoggingTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LoggingTests.g.cs @@ -4,22 +4,22 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class LoggingTests : LinkerTestBase - { + public sealed partial class LoggingTests : LinkerTestBase + { - protected override string TestSuiteName => "Logging"; + protected override string TestSuiteName => "Logging"; - [Fact] - public Task CommonLogs () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CommonLogs() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task SourceLines () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task SourceLines() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/MetadataTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/MetadataTests.g.cs index 9e958d384e9c52..e6c1dba134e596 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/MetadataTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/MetadataTests.g.cs @@ -4,52 +4,52 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class MetadataTests : LinkerTestBase - { - - protected override string TestSuiteName => "Metadata"; - - [Fact] - public Task DebuggerDisplayNamesAreKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NamesAreKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NamesAreRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task RootAllAssemblyNamesAreKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task RootDescriptorNamesAreKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task RootLibraryAssemblyNamesAreKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task RootVisibleAssemblyNamesAreKept () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class MetadataTests : LinkerTestBase + { + + protected override string TestSuiteName => "Metadata"; + + [Fact] + public Task DebuggerDisplayNamesAreKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NamesAreKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NamesAreRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task RootAllAssemblyNamesAreKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task RootDescriptorNamesAreKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task RootLibraryAssemblyNamesAreKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task RootVisibleAssemblyNamesAreKept() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/PreserveDependenciesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/PreserveDependenciesTests.g.cs index 6643506028e531..9e03c3d390463c 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/PreserveDependenciesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/PreserveDependenciesTests.g.cs @@ -4,100 +4,100 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class PreserveDependenciesTests : LinkerTestBase - { - - protected override string TestSuiteName => "PreserveDependencies"; - - [Fact] - public Task PreserveDependencyDeprecated () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyErrorCases () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyField () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyFromCopiedAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyKeptOption () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyMemberSignatureWildcard () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyMethodInAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyMethodInNonReferencedAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyMethodInNonReferencedAssemblyChained () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyMethodInNonReferencedAssemblyChainedReference () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyMethodInNonReferencedAssemblyWithEmbeddedXml () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyOnUnusedMethodInNonReferencedAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyOnUnusedMethodInNonReferencedAssemblyWithCopyUsedAction () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task PreserveDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class PreserveDependenciesTests : LinkerTestBase + { + + protected override string TestSuiteName => "PreserveDependencies"; + + [Fact] + public Task PreserveDependencyDeprecated() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyErrorCases() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyField() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyFromCopiedAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyKeptOption() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMemberSignatureWildcard() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMethodInAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMethodInNonReferencedAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMethodInNonReferencedAssemblyChained() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMethodInNonReferencedAssemblyChainedReference() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMethodInNonReferencedAssemblyWithEmbeddedXml() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyOnUnusedMethodInNonReferencedAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyOnUnusedMethodInNonReferencedAssemblyWithCopyUsedAction() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/References.DependenciesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/References.DependenciesTests.g.cs index 9b507cc19bbd5a..0d636806fdc360 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/References.DependenciesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/References.DependenciesTests.g.cs @@ -4,16 +4,16 @@ namespace ILLink.RoslynAnalyzer.Tests.References { - public sealed partial class DependenciesTests : LinkerTestBase - { + public sealed partial class DependenciesTests : LinkerTestBase + { - protected override string TestSuiteName => "References.Dependencies"; + protected override string TestSuiteName => "References.Dependencies"; - [Fact] - public Task ReferenceWithEntryPoint_Lib () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task ReferenceWithEntryPoint_Lib() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/References.IndividualTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/References.IndividualTests.g.cs index dd5eb24e1a0ca8..bb0445b8cb777f 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/References.IndividualTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/References.IndividualTests.g.cs @@ -4,16 +4,16 @@ namespace ILLink.RoslynAnalyzer.Tests.References { - public sealed partial class IndividualTests : LinkerTestBase - { + public sealed partial class IndividualTests : LinkerTestBase + { - protected override string TestSuiteName => "References.Individual"; + protected override string TestSuiteName => "References.Individual"; - [Fact] - public Task CanSkipUnresolved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CanSkipUnresolved() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReferencesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReferencesTests.g.cs index dc32f972824b72..adf7c618825ef8 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReferencesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReferencesTests.g.cs @@ -4,88 +4,88 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class ReferencesTests : LinkerTestBase - { - - protected override string TestSuiteName => "References"; - - [Fact] - public Task AssemblyOnlyUsedByUsingSaveAction () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AssemblyOnlyUsedByUsingSaveActionWithSymbols () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AssemblyOnlyUsedByUsingWithCsc () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AssemblyReferenceIsRemovedWhenUnused () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CopyAreKeptFully () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CopyUsedAreKeptFully () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CopyWithLinkedWillHaveAttributeDepsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CopyWithLinkedWillHaveMethodDepsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MissingReferenceInUnusedCodePath () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MissingReferenceInUsedCodePath () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferencesAreRemovedWhenAllUsagesAreRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithEntryPoint () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UserAssembliesAreLinkedByDefault () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class ReferencesTests : LinkerTestBase + { + + protected override string TestSuiteName => "References"; + + [Fact] + public Task AssemblyOnlyUsedByUsingSaveAction() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AssemblyOnlyUsedByUsingSaveActionWithSymbols() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AssemblyOnlyUsedByUsingWithCsc() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AssemblyReferenceIsRemovedWhenUnused() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CopyAreKeptFully() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CopyUsedAreKeptFully() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CopyWithLinkedWillHaveAttributeDepsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CopyWithLinkedWillHaveMethodDepsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MissingReferenceInUnusedCodePath() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MissingReferenceInUsedCodePath() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferencesAreRemovedWhenAllUsagesAreRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithEntryPoint() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UserAssembliesAreLinkedByDefault() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReflectionTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReflectionTests.g.cs index 4e66e2225c1516..59a9a24c47527b 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReflectionTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReflectionTests.g.cs @@ -4,74 +4,74 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class ReflectionTests : LinkerTestBase - { + public sealed partial class ReflectionTests : LinkerTestBase + { - [Fact] - public Task AssemblyImportedViaReflection () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task AssemblyImportedViaReflection() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task AssemblyImportedViaReflectionWithDerivedType () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task AssemblyImportedViaReflectionWithDerivedType() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task AssemblyImportedViaReflectionWithReference () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task AssemblyImportedViaReflectionWithReference() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task AsType () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task AsType() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CoreLibMessages () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CoreLibMessages() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task IsAssignableFrom () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task IsAssignableFrom() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task ParametersUsedViaReflection () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task ParametersUsedViaReflection() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task TypeMap () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task TypeMap() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UnderlyingSystemType () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UnderlyingSystemType() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UnsafeAccessor () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UnsafeAccessor() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task UsedViaReflectionIntegrationTest () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UsedViaReflectionIntegrationTest() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReproTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReproTests.g.cs index 2cd0c64c2fc3c7..4d233404cbb596 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReproTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReproTests.g.cs @@ -4,16 +4,16 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class ReproTests : LinkerTestBase - { + public sealed partial class ReproTests : LinkerTestBase + { - protected override string TestSuiteName => "Repro"; + protected override string TestSuiteName => "Repro"; - [Fact] - public Task Program () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task Program() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ResourcesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ResourcesTests.g.cs index 00e80e2cafaaaa..9864a0eee25c57 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ResourcesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ResourcesTests.g.cs @@ -4,76 +4,76 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class ResourcesTests : LinkerTestBase - { + public sealed partial class ResourcesTests : LinkerTestBase + { - protected override string TestSuiteName => "Resources"; + protected override string TestSuiteName => "Resources"; - [Fact] - public Task EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfActionIsCopy () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfActionIsCopy() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfNameDoesNotMatchAnAssembly () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfNameDoesNotMatchAnAssembly() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task EmbeddedLinkXmlFileInReferencedAssemblyIsProcessedIfActionIsLink () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task EmbeddedLinkXmlFileInReferencedAssemblyIsProcessedIfActionIsLink() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task EmbeddedLinkXmlFileIsNotProcessedIfNameDoesNotMatchAnAssembly () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task EmbeddedLinkXmlFileIsNotProcessedIfNameDoesNotMatchAnAssembly() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task EmbeddedLinkXmlFileIsNotProcessedWithIgnoreDescriptors () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task EmbeddedLinkXmlFileIsNotProcessedWithIgnoreDescriptors() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task EmbeddedLinkXmlFileIsNotProcessedWithIgnoreDescriptorsAndRemoved () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task EmbeddedLinkXmlFileIsNotProcessedWithIgnoreDescriptorsAndRemoved() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task EmbeddedLinkXmlFileIsProcessed () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task EmbeddedLinkXmlFileIsProcessed() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task EmbeddedLinkXmlFileIsProcessedAndKept () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task EmbeddedLinkXmlFileIsProcessedAndKept() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task EmbeddedLinkXmlFileIsProcessedIfNameMatchesAnAssembly () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task EmbeddedLinkXmlFileIsProcessedIfNameMatchesAnAssembly() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task EmbeddedLinkXmlFileWithTypePreserve () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task EmbeddedLinkXmlFileWithTypePreserve() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task NonLinkerEmbeddedResourceHasNoImpact () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task NonLinkerEmbeddedResourceHasNoImpact() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SealerTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SealerTests.g.cs index 0978942460b92b..949a15088c04c3 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SealerTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SealerTests.g.cs @@ -4,22 +4,22 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class SealerTests : LinkerTestBase - { + public sealed partial class SealerTests : LinkerTestBase + { - protected override string TestSuiteName => "Sealer"; + protected override string TestSuiteName => "Sealer"; - [Fact] - public Task MethodsDevirtualization () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task MethodsDevirtualization() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task TypesCanBeSealed () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task TypesCanBeSealed() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SerializationTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SerializationTests.g.cs index 127f40aa292599..55274cd48ca096 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SerializationTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SerializationTests.g.cs @@ -4,52 +4,52 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class SerializationTests : LinkerTestBase - { - - protected override string TestSuiteName => "Serialization"; - - [Fact] - public Task CanDisableSerializationDiscovery () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DataContractJsonSerialization () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DataContractSerialization () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DataContractSerializationUnused () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SerializationTypeRecursion () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task XmlSerialization () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task XmlSerializationUnused () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class SerializationTests : LinkerTestBase + { + + protected override string TestSuiteName => "Serialization"; + + [Fact] + public Task CanDisableSerializationDiscovery() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DataContractJsonSerialization() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DataContractSerialization() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DataContractSerializationUnused() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SerializationTypeRecursion() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task XmlSerialization() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task XmlSerializationUnused() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SingleFileTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SingleFileTests.g.cs index 62820e50c50b46..3a9d8b91c47a28 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SingleFileTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SingleFileTests.g.cs @@ -4,16 +4,16 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class SingleFileTests : LinkerTestBase - { + public sealed partial class SingleFileTests : LinkerTestBase + { - protected override string TestSuiteName => "SingleFile"; + protected override string TestSuiteName => "SingleFile"; - [Fact] - public Task SingleFileIntrinsics () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task SingleFileIntrinsics() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Statics.DisableBeforeFieldInitTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Statics.DisableBeforeFieldInitTests.g.cs index ff80319a1edb6f..93239d188c8255 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Statics.DisableBeforeFieldInitTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Statics.DisableBeforeFieldInitTests.g.cs @@ -4,16 +4,16 @@ namespace ILLink.RoslynAnalyzer.Tests.Statics { - public sealed partial class DisableBeforeFieldInitTests : LinkerTestBase - { + public sealed partial class DisableBeforeFieldInitTests : LinkerTestBase + { - protected override string TestSuiteName => "Statics.DisableBeforeFieldInit"; + protected override string TestSuiteName => "Statics.DisableBeforeFieldInit"; - [Fact] - public Task UnusedStaticFieldInitializer () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task UnusedStaticFieldInitializer() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/StaticsTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/StaticsTests.g.cs index 86e48c54209986..2f3dfeb8d6b53e 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/StaticsTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/StaticsTests.g.cs @@ -4,46 +4,46 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class StaticsTests : LinkerTestBase - { - - protected override string TestSuiteName => "Statics"; - - [Fact] - public Task ExplicitStaticCtor () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MixedStaticFieldInitializerAndCtor () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task StaticFieldInitializer () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedStaticConstructorGetsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedStaticFieldInitializer () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedStaticMethodGetsRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class StaticsTests : LinkerTestBase + { + + protected override string TestSuiteName => "Statics"; + + [Fact] + public Task ExplicitStaticCtor() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MixedStaticFieldInitializerAndCtor() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task StaticFieldInitializer() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedStaticConstructorGetsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedStaticFieldInitializer() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedStaticMethodGetsRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SubstitutionsTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SubstitutionsTests.g.cs index 93116fcb7541ba..35ec9a25061fa4 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SubstitutionsTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SubstitutionsTests.g.cs @@ -4,92 +4,92 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class SubstitutionsTests : LinkerTestBase - { - - [Fact] - public Task EmbeddedMethodSubstitutionsInReferencedAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task EmbeddedSubstitutions () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task EmbeddedSubstitutionsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task EmbeddedSubstitutionsNotProcessedWithIgnoreSubstitutions () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task EmbeddedSubstitutionsNotProcessedWithIgnoreSubstitutionsAndRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task FeatureGuardSubstitutionsDisabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task RemoveBody () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ResourceSubstitutions () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task StubBody () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task StubBodyInvalidSyntax () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task StubBodyUnsafe () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task StubBodyWithStaticCtor () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task StubBodyWithValue () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SubstitutionsErrorCases () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class SubstitutionsTests : LinkerTestBase + { + + [Fact] + public Task EmbeddedMethodSubstitutionsInReferencedAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedSubstitutions() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedSubstitutionsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedSubstitutionsNotProcessedWithIgnoreSubstitutions() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedSubstitutionsNotProcessedWithIgnoreSubstitutionsAndRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task FeatureGuardSubstitutionsDisabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task RemoveBody() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ResourceSubstitutions() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task StubBody() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task StubBodyInvalidSyntax() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task StubBodyUnsafe() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task StubBodyWithStaticCtor() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task StubBodyWithValue() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SubstitutionsErrorCases() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SymbolsTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SymbolsTests.g.cs index e208772d48f08a..3f688ebecd5a3e 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SymbolsTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SymbolsTests.g.cs @@ -4,232 +4,232 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class SymbolsTests : LinkerTestBase - { - - protected override string TestSuiteName => "Symbols"; - - [Fact] - public Task AssemblyWithDefaultSymbols () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AssemblyWithDefaultSymbolsAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferencesWithMixedSymbolTypes () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferencesWithMixedSymbolTypesAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferencesWithMixedSymbolTypesWithMdbAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithEmbeddedPdb () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithEmbeddedPdbAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithEmbeddedPdbAndSymbolLinkingEnabledAndDeterministicMvid () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithEmbeddedPdbAndSymbolLinkingEnabledAndNewMvid () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithEmbeddedPdbCopyAction () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithEmbeddedPdbCopyActionAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithEmbeddedPdbDeleteAction () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithEmbeddedPdbDeleteActionAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithMdb () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithMdbAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithMdbAndSymbolLinkingEnabledAndDeterministicMvid () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithMdbAndSymbolLinkingEnabledAndNewMvid () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithMdbCopyAction () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithMdbCopyActionAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithMdbDeleteAction () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithMdbDeleteActionAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPdb () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPdbAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPdbAndSymbolLinkingEnabledAndDeterministicMvid () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPdbAndSymbolLinkingEnabledAndNewMvid () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPdbCopyAction () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPdbCopyActionAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPdbDeleteAction () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPdbDeleteActionAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPortablePdb () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPortablePdbAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPortablePdbAndSymbolLinkingEnabledAndDeterministicMvid () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPortablePdbAndSymbolLinkingEnabledAndNewMvid () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPortablePdbCopyAction () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPortablePdbCopyActionAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPortablePdbDeleteAction () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReferenceWithPortablePdbDeleteActionAndSymbolLinkingEnabled () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class SymbolsTests : LinkerTestBase + { + + protected override string TestSuiteName => "Symbols"; + + [Fact] + public Task AssemblyWithDefaultSymbols() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AssemblyWithDefaultSymbolsAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferencesWithMixedSymbolTypes() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferencesWithMixedSymbolTypesAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferencesWithMixedSymbolTypesWithMdbAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithEmbeddedPdb() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithEmbeddedPdbAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithEmbeddedPdbAndSymbolLinkingEnabledAndDeterministicMvid() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithEmbeddedPdbAndSymbolLinkingEnabledAndNewMvid() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithEmbeddedPdbCopyAction() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithEmbeddedPdbCopyActionAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithEmbeddedPdbDeleteAction() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithEmbeddedPdbDeleteActionAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithMdb() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithMdbAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithMdbAndSymbolLinkingEnabledAndDeterministicMvid() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithMdbAndSymbolLinkingEnabledAndNewMvid() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithMdbCopyAction() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithMdbCopyActionAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithMdbDeleteAction() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithMdbDeleteActionAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPdb() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPdbAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPdbAndSymbolLinkingEnabledAndDeterministicMvid() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPdbAndSymbolLinkingEnabledAndNewMvid() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPdbCopyAction() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPdbCopyActionAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPdbDeleteAction() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPdbDeleteActionAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPortablePdb() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPortablePdbAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPortablePdbAndSymbolLinkingEnabledAndDeterministicMvid() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPortablePdbAndSymbolLinkingEnabledAndNewMvid() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPortablePdbCopyAction() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPortablePdbCopyActionAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPortablePdbDeleteAction() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithPortablePdbDeleteActionAndSymbolLinkingEnabled() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TestFrameworkTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TestFrameworkTests.g.cs index 744a6f3841ccc8..66b2eb3e70409a 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TestFrameworkTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TestFrameworkTests.g.cs @@ -4,106 +4,106 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class TestFrameworkTests : LinkerTestBase - { - - protected override string TestSuiteName => "TestFramework"; - - [Fact] - public Task CanCheckInitializersByIndex () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanCompileILAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanCompileReferencesUsingTypes () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanCompileReferencesWithResources () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanCompileReferencesWithResourcesWithCsc () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanCompileReferencesWithResourcesWithMcs () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanCompileTestCaseWithCsc () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanCompileTestCaseWithDebugPdbs () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanCompileTestCaseWithMcs () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanSandboxDependenciesUsingType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanVerifyInterfacesOnTypesInAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ILVerificationWorks () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task VerifyAttributesInAssemblyWorks () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task VerifyAttributesInAssemblyWorksWithStrings () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task VerifyDefineAttributeBehavior () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task VerifyResourceInAssemblyAttributesBehavior () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class TestFrameworkTests : LinkerTestBase + { + + protected override string TestSuiteName => "TestFramework"; + + [Fact] + public Task CanCheckInitializersByIndex() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanCompileILAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanCompileReferencesUsingTypes() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanCompileReferencesWithResources() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanCompileReferencesWithResourcesWithCsc() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanCompileReferencesWithResourcesWithMcs() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanCompileTestCaseWithCsc() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanCompileTestCaseWithDebugPdbs() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanCompileTestCaseWithMcs() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanSandboxDependenciesUsingType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanVerifyInterfacesOnTypesInAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ILVerificationWorks() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task VerifyAttributesInAssemblyWorks() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task VerifyAttributesInAssemblyWorksWithStrings() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task VerifyDefineAttributeBehavior() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task VerifyResourceInAssemblyAttributesBehavior() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TopLevelStatementsTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TopLevelStatementsTests.g.cs index 492352328447d2..385d01cf9e469a 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TopLevelStatementsTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TopLevelStatementsTests.g.cs @@ -4,14 +4,14 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class TopLevelStatementsTests : LinkerTestBase - { + public sealed partial class TopLevelStatementsTests : LinkerTestBase + { - [Fact] - public Task BasicKeptValidation () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task BasicKeptValidation() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.DependencyRecorderTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.DependencyRecorderTests.g.cs index 5545d319686169..a04c70479f6984 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.DependencyRecorderTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.DependencyRecorderTests.g.cs @@ -4,16 +4,16 @@ namespace ILLink.RoslynAnalyzer.Tests.Tracing { - public sealed partial class DependencyRecorderTests : LinkerTestBase - { + public sealed partial class DependencyRecorderTests : LinkerTestBase + { - protected override string TestSuiteName => "Tracing.DependencyRecorder"; + protected override string TestSuiteName => "Tracing.DependencyRecorder"; - [Fact] - public Task BasicDependencies () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task BasicDependencies() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.IndividualTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.IndividualTests.g.cs index 93a89fe9a13b38..af3da42b21d2ac 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.IndividualTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.IndividualTests.g.cs @@ -4,34 +4,34 @@ namespace ILLink.RoslynAnalyzer.Tests.Tracing { - public sealed partial class IndividualTests : LinkerTestBase - { + public sealed partial class IndividualTests : LinkerTestBase + { - protected override string TestSuiteName => "Tracing.Individual"; + protected override string TestSuiteName => "Tracing.Individual"; - [Fact] - public Task CanDumpDependenciesToUncompressedDgml () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CanDumpDependenciesToUncompressedDgml() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CanDumpDependenciesToUncompressedXml () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CanDumpDependenciesToUncompressedXml() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CanEnableDependenciesDump () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CanEnableDependenciesDump() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CanEnableReducedTracing () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CanEnableReducedTracing() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TypeForwardingTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TypeForwardingTests.g.cs index d2b9d1ccb12aeb..fe1f556a88fcb3 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TypeForwardingTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TypeForwardingTests.g.cs @@ -4,262 +4,262 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class TypeForwardingTests : LinkerTestBase - { - - protected override string TestSuiteName => "TypeForwarding"; - - [Fact] - public Task AttributeArgumentForwarded () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeArgumentForwardedWithCopyAction () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeEnumArgumentForwarded () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributeEnumArgumentForwardedCopyUsedWithSweptForwarder () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task AttributesScopeUpdated () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MissingTargetReference () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MultiForwardedTypesWithCopyUsed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MultiForwardedTypesWithLink () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NestedTypeForwarder () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SecurityAttributeScope () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TypeForwardedIsUpdatedForMissingType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TypeForwarderOnlyAssembliesRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TypeForwarderOnlyAssemblyCanBePreservedViaLinkXml () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TypeForwardersModifiers () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TypeForwardersRewrite () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedForwarderWithAssemblyCopyIsKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedForwarderWithAssemblyCopyUsed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedForwarderWithAssemblyLinked () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UnusedForwarderWithAssemblyLinkedAndFacadeCopy () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedAndUnusedForwarderReferencedFromCopyUsedAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedAndUnusedForwarderWithAssemblyCopy () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderAndUnusedReference () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderInCopyAssemblyKeptByPreserveDependency () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderInCopyAssemblyKeptByUsedCustomAttribute () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderInCopyAssemblyKeptByUsedField () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderInCopyAssemblyKeptByUsedInterface () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderInCopyAssemblyKeptByUsedMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderInCopyAssemblyKeptByUsedNestedType () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderInCopyAssemblyKeptByUsedProperty () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderInCopyAssemblyKeptByUsedTypeAsGenericArg () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderInGenericIsDynamicallyAccessedWithAssemblyCopyUsed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderIsDynamicallyAccessedWithAssemblyCopyUsed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderIsRemovedWhenLink () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderWithAssemblyCopy () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderWithAssemblyCopyUsed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderWithAssemblyCopyUsedAndForwarderLibraryKept () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedForwarderWithAssemblyCopyUsedAndUnusedReference () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedTransitiveForwarderInCopyAssemblyIsDynamicallyAccessed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedTransitiveForwarderInCopyUsedAssemblyIsDynamicallyAccessed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedTransitiveForwarderIsDynamicallyAccessed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedTransitiveForwarderIsResolvedAndFacadeRemoved () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UsedTransitiveForwarderIsResolvedAndFacadeRemovedInCopyAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class TypeForwardingTests : LinkerTestBase + { + + protected override string TestSuiteName => "TypeForwarding"; + + [Fact] + public Task AttributeArgumentForwarded() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeArgumentForwardedWithCopyAction() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeEnumArgumentForwarded() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributeEnumArgumentForwardedCopyUsedWithSweptForwarder() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task AttributesScopeUpdated() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MissingTargetReference() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MultiForwardedTypesWithCopyUsed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MultiForwardedTypesWithLink() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NestedTypeForwarder() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SecurityAttributeScope() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypeForwardedIsUpdatedForMissingType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypeForwarderOnlyAssembliesRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypeForwarderOnlyAssemblyCanBePreservedViaLinkXml() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypeForwardersModifiers() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypeForwardersRewrite() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedForwarderWithAssemblyCopyIsKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedForwarderWithAssemblyCopyUsed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedForwarderWithAssemblyLinked() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UnusedForwarderWithAssemblyLinkedAndFacadeCopy() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedAndUnusedForwarderReferencedFromCopyUsedAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedAndUnusedForwarderWithAssemblyCopy() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderAndUnusedReference() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByPreserveDependency() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedCustomAttribute() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedField() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedInterface() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedNestedType() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedProperty() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedTypeAsGenericArg() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInGenericIsDynamicallyAccessedWithAssemblyCopyUsed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderIsDynamicallyAccessedWithAssemblyCopyUsed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderIsRemovedWhenLink() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderWithAssemblyCopy() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderWithAssemblyCopyUsed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderWithAssemblyCopyUsedAndForwarderLibraryKept() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderWithAssemblyCopyUsedAndUnusedReference() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedTransitiveForwarderInCopyAssemblyIsDynamicallyAccessed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedTransitiveForwarderInCopyUsedAssemblyIsDynamicallyAccessed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedTransitiveForwarderIsDynamicallyAccessed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedTransitiveForwarderIsResolvedAndFacadeRemoved() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UsedTransitiveForwarderIsResolvedAndFacadeRemovedInCopyAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBlockTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBlockTests.g.cs index 6d961d2c269e78..f9ce05416fcc8d 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBlockTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBlockTests.g.cs @@ -4,122 +4,122 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class UnreachableBlockTests : LinkerTestBase - { - - [Fact] - public Task BodiesWithSubstitutions () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ComplexConditions () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ComplexConditionsOptimized () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DataFlowRelated () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DeadVariables () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task EndScopeOnMethoEnd () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InstanceMethodSubstitutions () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MethodArgumentPropagation () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MethodWithParametersSubstitutions () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MultiStageRemoval () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReplacedJumpTarget () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ReplacedReturns () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ResultInliningNotPossible () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SimpleConditionalProperty () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SizeOfInConditions () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TryCatchBlocks () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TryFinallyBlocks () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task UninitializedLocals () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task WorksWithDynamicAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class UnreachableBlockTests : LinkerTestBase + { + + [Fact] + public Task BodiesWithSubstitutions() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ComplexConditions() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ComplexConditionsOptimized() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DataFlowRelated() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DeadVariables() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task EndScopeOnMethoEnd() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InstanceMethodSubstitutions() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MethodArgumentPropagation() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MethodWithParametersSubstitutions() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MultiStageRemoval() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReplacedJumpTarget() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ReplacedReturns() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ResultInliningNotPossible() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SimpleConditionalProperty() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SizeOfInConditions() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TryCatchBlocks() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TryFinallyBlocks() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task UninitializedLocals() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task WorksWithDynamicAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBodyTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBodyTests.g.cs index 076dbdbd0673f9..a34af627fda627 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBodyTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBodyTests.g.cs @@ -4,196 +4,196 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class UnreachableBodyTests : LinkerTestBase - { - - protected override string TestSuiteName => "UnreachableBody"; - - [Fact] - public Task BodyWithManyVariables () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task BodyWithManyVariablesWithSymbols () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanDisableLazyBodyMarking () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DoesNotApplyToCopiedAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DoesNotApplyToCopiedAssembly2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ExplicitInstructionCheck () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InterfaceMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LinkedOtherIncludedLibrary () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task LinkedOtherIncludedLibraryNoInstanceCtor () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MixOfMethods () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NotWorthConvertingEmpty () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NotWorthConvertingReturnDouble () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NotWorthConvertingReturnFalse () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NotWorthConvertingReturnFloat () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NotWorthConvertingReturnInt () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NotWorthConvertingReturnLong () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NotWorthConvertingReturnNull () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NotWorthConvertingReturnTrue () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OverrideOfAbstractAndInterfaceMethodCalledFromLocal () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OverrideOfAbstractAndInterfaceMethodCalledFromLocal2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OverrideOfAbstractAndInterfaceMethodCalledFromLocal3 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OverrideOfAbstractAndInterfaceMethodWhenInterfaceRemoved2 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OverrideOfAbstractIsStubbed () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OverrideOfAbstractIsStubbedWithUnusedInterface () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task OverrideOfAVirtual () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SimpleGetter () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SimpleMethod () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SimpleSetter () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task WorksWithDynamicDependency () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task WorksWithLinkXml () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task WorksWithPreserveDependency () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class UnreachableBodyTests : LinkerTestBase + { + + protected override string TestSuiteName => "UnreachableBody"; + + [Fact] + public Task BodyWithManyVariables() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task BodyWithManyVariablesWithSymbols() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanDisableLazyBodyMarking() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DoesNotApplyToCopiedAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DoesNotApplyToCopiedAssembly2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ExplicitInstructionCheck() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LinkedOtherIncludedLibrary() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LinkedOtherIncludedLibraryNoInstanceCtor() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MixOfMethods() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingEmpty() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnDouble() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnFalse() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnFloat() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnInt() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnLong() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnNull() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnTrue() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractAndInterfaceMethodCalledFromLocal() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractAndInterfaceMethodCalledFromLocal2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractAndInterfaceMethodCalledFromLocal3() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractAndInterfaceMethodWhenInterfaceRemoved2() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractIsStubbed() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractIsStubbedWithUnusedInterface() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAVirtual() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SimpleGetter() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SimpleMethod() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SimpleSetter() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task WorksWithDynamicDependency() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task WorksWithLinkXml() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task WorksWithPreserveDependency() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.DependenciesTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.DependenciesTests.g.cs index 6bb97b39338d03..be20e6b8abd48e 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.DependenciesTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.DependenciesTests.g.cs @@ -4,22 +4,22 @@ namespace ILLink.RoslynAnalyzer.Tests.Warnings { - public sealed partial class DependenciesTests : LinkerTestBase - { + public sealed partial class DependenciesTests : LinkerTestBase + { - protected override string TestSuiteName => "Warnings.Dependencies"; + protected override string TestSuiteName => "Warnings.Dependencies"; - [Fact] - public Task TriggerWarnings_Lib () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task TriggerWarnings_Lib() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task TriggerWarnings_TrimmableLib () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task TriggerWarnings_TrimmableLib() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.IndividualTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.IndividualTests.g.cs index 06ac6ebc2e8bf8..02688a7c205033 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.IndividualTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.IndividualTests.g.cs @@ -4,34 +4,34 @@ namespace ILLink.RoslynAnalyzer.Tests.Warnings { - public sealed partial class IndividualTests : LinkerTestBase - { + public sealed partial class IndividualTests : LinkerTestBase + { - protected override string TestSuiteName => "Warnings.Individual"; + protected override string TestSuiteName => "Warnings.Individual"; - [Fact] - public Task CanGenerateWarningSuppressionFileCSharp () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CanGenerateWarningSuppressionFileCSharp() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CanGenerateWarningSuppressionFileXml () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CanGenerateWarningSuppressionFileXml() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task CustomStepWithWarnings () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task CustomStepWithWarnings() + { + return RunTest(allowMissingWarnings: true); + } - [Fact] - public Task WarningsAreSorted () - { - return RunTest (allowMissingWarnings: true); - } + [Fact] + public Task WarningsAreSorted() + { + return RunTest(allowMissingWarnings: true); + } - } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.WarningSuppressionTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.WarningSuppressionTests.g.cs index ba9c98121fba3c..33d2b4739a619e 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.WarningSuppressionTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.WarningSuppressionTests.g.cs @@ -4,128 +4,128 @@ namespace ILLink.RoslynAnalyzer.Tests.Warnings { - public sealed partial class WarningSuppressionTests : LinkerTestBase - { - - [Fact] - public Task AddSuppressionsBeforeAttributeRemoval () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DetectRedundantSuppressionsFeatureSubstitutions () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DetectRedundantSuppressionsFromXML () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DetectRedundantSuppressionsInAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DetectRedundantSuppressionsInCompilerGeneratedCode () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DetectRedundantSuppressionsInMembersAndTypes () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DetectRedundantSuppressionsInMembersAndTypesUsingTarget () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DetectRedundantSuppressionsInModule () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DetectRedundantSuppressionsSingleWarn () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task DetectRedundantSuppressionsTrimmedMembersTarget () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ModuleSuppressionWithMemberScopeNullTarget () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ModuleSuppressionWithModuleScopeNullTarget () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task ModuleSuppressionWithNullScopeNullTarget () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SuppressWarningsInAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SuppressWarningsInCopyAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SuppressWarningsInMembersAndTypes () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SuppressWarningsInModule () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SuppressWarningsUsingTargetViaXmlMono () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task SuppressWarningsUsingTargetViaXmlNetCore () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task TargettedModuleSuppressionWithUnmatchedScope () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class WarningSuppressionTests : LinkerTestBase + { + + [Fact] + public Task AddSuppressionsBeforeAttributeRemoval() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DetectRedundantSuppressionsFeatureSubstitutions() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DetectRedundantSuppressionsFromXML() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DetectRedundantSuppressionsInAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DetectRedundantSuppressionsInCompilerGeneratedCode() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DetectRedundantSuppressionsInMembersAndTypes() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DetectRedundantSuppressionsInMembersAndTypesUsingTarget() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DetectRedundantSuppressionsInModule() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DetectRedundantSuppressionsSingleWarn() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task DetectRedundantSuppressionsTrimmedMembersTarget() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ModuleSuppressionWithMemberScopeNullTarget() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ModuleSuppressionWithModuleScopeNullTarget() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task ModuleSuppressionWithNullScopeNullTarget() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SuppressWarningsInAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SuppressWarningsInCopyAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SuppressWarningsInMembersAndTypes() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SuppressWarningsInModule() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SuppressWarningsUsingTargetViaXmlMono() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task SuppressWarningsUsingTargetViaXmlNetCore() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TargettedModuleSuppressionWithUnmatchedScope() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/WarningsTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/WarningsTests.g.cs index f9cd3f2cf8e263..f348c293c53b0d 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/WarningsTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/WarningsTests.g.cs @@ -4,116 +4,116 @@ namespace ILLink.RoslynAnalyzer.Tests { - public sealed partial class WarningsTests : LinkerTestBase - { - - [Fact] - public Task CanDisableWarnAsError () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanDisableWarnings () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanNotSingleWarnPerAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanNotWarnAsErrorForDisabledVersion () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanSetWarningVersion0 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanSetWarningVersion5 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanSetWarningVersion9999 () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanSingleWarn () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanSingleWarnPerAssembly () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanSingleWarnWithIndividualWarnAsError () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanSingleWarnWithNoWarn () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanSingleWarnWithWarnAsError () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanWarnAsError () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task CanWarnAsErrorGlobal () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task InvalidWarningVersion () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task MultipleMethodsUseSameAsyncStateMachine () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task NoWarnRegardlessOfWarnAsError () - { - return RunTest (allowMissingWarnings: true); - } - - [Fact] - public Task WarningsFromTrimmableAssembliesCanSurviveSingleWarn () - { - return RunTest (allowMissingWarnings: true); - } - - } + public sealed partial class WarningsTests : LinkerTestBase + { + + [Fact] + public Task CanDisableWarnAsError() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanDisableWarnings() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanNotSingleWarnPerAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanNotWarnAsErrorForDisabledVersion() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanSetWarningVersion0() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanSetWarningVersion5() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanSetWarningVersion9999() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanSingleWarn() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanSingleWarnPerAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanSingleWarnWithIndividualWarnAsError() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanSingleWarnWithNoWarn() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanSingleWarnWithWarnAsError() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanWarnAsError() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task CanWarnAsErrorGlobal() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task InvalidWarningVersion() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MultipleMethodsUseSameAsyncStateMachine() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task NoWarnRegardlessOfWarnAsError() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task WarningsFromTrimmableAssembliesCanSurviveSingleWarn() + { + return RunTest(allowMissingWarnings: true); + } + + } } diff --git a/src/tools/illink/test/ILLink.Tasks.Tests/CombineLinkerXmlFilesTests.cs b/src/tools/illink/test/ILLink.Tasks.Tests/CombineLinkerXmlFilesTests.cs index 3a1b0e1ee70250..82961ae31e5124 100644 --- a/src/tools/illink/test/ILLink.Tasks.Tests/CombineLinkerXmlFilesTests.cs +++ b/src/tools/illink/test/ILLink.Tasks.Tests/CombineLinkerXmlFilesTests.cs @@ -32,8 +32,8 @@ public void TestCombineLinkerXmlFiles() "doc2.xml"); var xmlFiles = new ITaskItem[] { - new TaskItem ("doc1.xml"), - new TaskItem ("doc2.xml"), + new TaskItem("doc1.xml"), + new TaskItem("doc2.xml"), }; var combiner = new CombineLinkerXmlFiles() diff --git a/src/tools/illink/test/ILLink.Tasks.Tests/ILLink.Tasks.Tests.cs b/src/tools/illink/test/ILLink.Tasks.Tests/ILLink.Tasks.Tests.cs index d555f0332bb5da..5e0380845930cb 100644 --- a/src/tools/illink/test/ILLink.Tasks.Tests/ILLink.Tasks.Tests.cs +++ b/src/tools/illink/test/ILLink.Tasks.Tests/ILLink.Tasks.Tests.cs @@ -20,38 +20,38 @@ public class TaskArgumentTests public static IEnumerable AssemblyPathsCases => new List { new object [] { new ITaskItem [] { - new TaskItem ("Assembly.dll", new Dictionary { { "trimmode", "copy" } }) + new TaskItem("Assembly.dll", new Dictionary { { "trimmode", "copy" } }) } }, new object [] { new ITaskItem [] { - new TaskItem ("Assembly.dll", new Dictionary { { "TrimMode", "Copy" } }) + new TaskItem("Assembly.dll", new Dictionary { { "TrimMode", "Copy" } }) } }, new object [] { new ITaskItem [] { - new TaskItem ("path with/spaces/Assembly.dll") + new TaskItem("path with/spaces/Assembly.dll") } }, new object [] { new ITaskItem [] { - // same path - new TaskItem ("path/to/Assembly1.dll"), - new TaskItem ("path/to/Assembly2.dll") + // same path + new TaskItem("path/to/Assembly1.dll"), + new TaskItem("path/to/Assembly2.dll") } }, new object [] { new ITaskItem [] { - // same assembly - new TaskItem ("path/to/Assembly.dll"), - new TaskItem ("path/to/Assembly.dll") + // same assembly + new TaskItem("path/to/Assembly.dll"), + new TaskItem("path/to/Assembly.dll") } }, new object [] { new ITaskItem [] { - // same assembly name, different paths - new TaskItem ("path1/Assembly.dll"), - new TaskItem ("path2/Assembly.dll") + // same assembly name, different paths + new TaskItem("path1/Assembly.dll"), + new TaskItem("path2/Assembly.dll") } } }; @@ -79,7 +79,7 @@ public void TrimModeAssemblyPaths(string trimMode) { var assemblyPaths = new ITaskItem[] { new TaskItem("Assembly1.dll", new Dictionary {{ "IsTrimmable", "true" }}), - new TaskItem("Assembly2.dll", new Dictionary ()), + new TaskItem("Assembly2.dll", new Dictionary()), new TaskItem("Assembly3.dll", new Dictionary {{ "IsTrimmable", "false" }}), }; var task = new MockTask() @@ -251,14 +251,14 @@ public static IEnumerable PerAssemblyOptimizationsCases() { yield return new object[] { new ITaskItem [] { - new TaskItem ("path/to/Assembly.dll", new Dictionary { + new TaskItem("path/to/Assembly.dll", new Dictionary { { optimization, "True" } }) } }; yield return new object[] { new ITaskItem [] { - new TaskItem ("path/to/Assembly.dll", new Dictionary { + new TaskItem("path/to/Assembly.dll", new Dictionary { { optimization, "False" } }) } @@ -267,11 +267,11 @@ public static IEnumerable PerAssemblyOptimizationsCases() // complex case with multiple optimizations, assemblies yield return new object[] { new ITaskItem [] { - new TaskItem ("path/to/Assembly1.dll", new Dictionary { + new TaskItem("path/to/Assembly1.dll", new Dictionary { { "Sealer", "True" }, { "BeforeFieldInit", "False" } }), - new TaskItem ("path/to/Assembly2.dll", new Dictionary { + new TaskItem("path/to/Assembly2.dll", new Dictionary { { "Sealer", "False" }, { "BeforeFieldInit", "True" } }) @@ -310,15 +310,15 @@ public void TestPerAssemblyOptimizations(ITaskItem[] assemblyPaths) new object[] { true, new ITaskItem [] { - new TaskItem ("AssemblyTrue.dll", new Dictionary { { "TrimmerSingleWarn", "true" } } ), - new TaskItem ("AssemblyFalse.dll", new Dictionary { { "TrimmerSingleWarn", "false" } } ) + new TaskItem("AssemblyTrue.dll", new Dictionary { { "TrimmerSingleWarn", "true" } } ), + new TaskItem("AssemblyFalse.dll", new Dictionary { { "TrimmerSingleWarn", "false" } } ) }, }, new object [] { false, new ITaskItem [] { - new TaskItem ("AssemblyTrue.dll", new Dictionary { { "TrimmerSingleWarn", "true" } } ), - new TaskItem ("AssemblyFalse.dll", new Dictionary { { "TrimmerSingleWarn", "false" } } ) + new TaskItem("AssemblyTrue.dll", new Dictionary { { "TrimmerSingleWarn", "true" } } ), + new TaskItem("AssemblyFalse.dll", new Dictionary { { "TrimmerSingleWarn", "false" } } ) } } }; @@ -349,7 +349,7 @@ public void TestInvalidPerAssemblyOptimizations() var task = new MockTask() { AssemblyPaths = new ITaskItem[] { - new TaskItem ("path/to/Assembly.dll", new Dictionary { + new TaskItem("path/to/Assembly.dll", new Dictionary { { "Sealer", "invalid" } }) } @@ -462,24 +462,24 @@ public void TestWarningsAsErrors(bool treatWarningsAsErrors, string? warningsAsE public static IEnumerable CustomDataCases => new List { new object [] { new ITaskItem [] { - new TaskItem ("DataName", new Dictionary { { "Value", "DataValue" } }) + new TaskItem("DataName", new Dictionary { { "Value", "DataValue" } }) }, }, new object [] { new ITaskItem [] { - new TaskItem ("DataName", new Dictionary { { "Value", "DataValue" } }), - new TaskItem ("DataName", new Dictionary { { "Value", "DataValue2" } }) + new TaskItem("DataName", new Dictionary { { "Value", "DataValue" } }), + new TaskItem("DataName", new Dictionary { { "Value", "DataValue2" } }) }, }, new object [] { new ITaskItem [] { - new TaskItem ("DataName1", new Dictionary { { "Value", "DataValue1" } }), - new TaskItem ("DataName2", new Dictionary { { "Value", "DataValue2" } }) + new TaskItem("DataName1", new Dictionary { { "Value", "DataValue1" } }), + new TaskItem("DataName2", new Dictionary { { "Value", "DataValue2" } }) }, }, new object [] { new ITaskItem [] { - new TaskItem ("DataName", new Dictionary { { "Value", "data value with spaces" } }) + new TaskItem("DataName", new Dictionary { { "Value", "data value with spaces" } }) }, }, }; @@ -506,19 +506,19 @@ public void TestCustomData(ITaskItem[] customData) public static IEnumerable FeatureSettingsCases => new List { new object [] { new ITaskItem [] { - new TaskItem ("FeatureName", new Dictionary { { "Value", "true" } }) + new TaskItem("FeatureName", new Dictionary { { "Value", "true" } }) }, }, new object [] { new ITaskItem [] { - new TaskItem ("FeatureName", new Dictionary { { "Value", "true" } }), - new TaskItem ("FeatureName", new Dictionary { { "Value", "false" } }) + new TaskItem("FeatureName", new Dictionary { { "Value", "true" } }), + new TaskItem("FeatureName", new Dictionary { { "Value", "false" } }) }, }, new object [] { new ITaskItem [] { - new TaskItem ("FeatureName1", new Dictionary { { "value", "true" } }), - new TaskItem ("FeatureName2", new Dictionary { { "value", "false" } }), + new TaskItem("FeatureName1", new Dictionary { { "value", "true" } }), + new TaskItem("FeatureName2", new Dictionary { { "value", "false" } }), }, }, }; @@ -731,14 +731,14 @@ public void TestInvalidDefaultAction() public static IEnumerable CustomStepsCases => new List { new object [] { new ITaskItem [] { - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockCustomStep" } }) }, }, new object [] { new ITaskItem [] { - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockCustomStep" }, { "BeforeStep", "MarkStep" } }) @@ -746,7 +746,7 @@ public void TestInvalidDefaultAction() }, new object [] { new ITaskItem [] { - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "type", "ILLink.Tasks.Tests.MockCustomStep" }, { "beforebtep", "MarkStep" } }) @@ -754,7 +754,7 @@ public void TestInvalidDefaultAction() }, new object [] { new ITaskItem [] { - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockCustomStep" }, { "AfterStep", "MarkStep" } }) @@ -762,11 +762,11 @@ public void TestInvalidDefaultAction() }, new object [] { new ITaskItem [] { - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockCustomStep" }, { "BeforeStep", "MarkStep" } }), - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockCustomStep" }, { "AfterStep", "MarkStep" } }) @@ -815,7 +815,7 @@ public void TestCustomSteps(ITaskItem[] customSteps) public void TestCustomStepsWithBeforeAndAfterSteps() { var customSteps = new ITaskItem[] { - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockCustomStep" }, { "BeforeStep", "MarkStep" }, { "AfterStep", "MarkStep" } @@ -832,40 +832,40 @@ public void TestCustomStepsWithBeforeAndAfterSteps() public void TestCustomStepOrdering() { var customSteps = new ITaskItem[] { - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockCustomStep" }, { "BeforeStep", "MarkStep" } }), - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockCustomStep2" }, { "BeforeStep", "MarkStep" } }), - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockCustomStep3" }, { "AfterStep", "MarkStep" } }), - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockCustomStep4" }, { "AfterStep", "MarkStep" } }), - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockCustomStep5" }, }), - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockCustomStep6" }, }), - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockMarkHandler" } }), - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockMarkHandler2" }, { "BeforeStep", "MockMarkHandler" } }), - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockMarkHandler3" }, { "AfterStep", "MockMarkHandler2" } }), - new TaskItem (Assembly.GetExecutingAssembly ().Location, new Dictionary { + new TaskItem(Assembly.GetExecutingAssembly().Location, new Dictionary { { "Type", "ILLink.Tasks.Tests.MockMarkHandler4" } }), }; @@ -901,7 +901,7 @@ public void TestCustomStepOrdering() public void TestCustomStepsMissingType() { var customSteps = new ITaskItem[] { - new TaskItem (Assembly.GetExecutingAssembly ().Location) + new TaskItem(Assembly.GetExecutingAssembly().Location) }; var task = new MockTask() { diff --git a/src/tools/illink/test/ILLink.Tasks.Tests/Mock.cs b/src/tools/illink/test/ILLink.Tasks.Tests/Mock.cs index 15dc51a72ac047..c4198109552f8b 100644 --- a/src/tools/illink/test/ILLink.Tasks.Tests/Mock.cs +++ b/src/tools/illink/test/ILLink.Tasks.Tests/Mock.cs @@ -185,7 +185,7 @@ public Dictionary GetCustomData() protected override List CreateDefaultResolvers() { return new List() { - new RootAssemblyInput (null, AssemblyRootMode.EntryPoint) + new RootAssemblyInput(null, AssemblyRootMode.EntryPoint) }; } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseInAssemblyAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseInAssemblyAttribute.cs index 5c04e7d7c54bb3..bef3e150273c45 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseInAssemblyAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseInAssemblyAttribute.cs @@ -10,6 +10,6 @@ public abstract class BaseInAssemblyAttribute : BaseExpectedLinkedBehaviorAttrib /// This property can override that by setting only the platforms /// which are expected to preserve the desired behavior. /// - public Tool Tool { get; set; } = Tool.TrimmerAnalyzerAndNativeAot; + public Tool Tool { get; set; } = Tool.All; } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/IgnoreTestCaseAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/IgnoreTestCaseAttribute.cs index 474f3c72b2a469..5b13edb42098a0 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/IgnoreTestCaseAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/IgnoreTestCaseAttribute.cs @@ -14,6 +14,6 @@ public IgnoreTestCaseAttribute(string reason) ArgumentNullException.ThrowIfNull(reason); } - public Tool IgnoredBy { get; set; } = Tool.TrimmerAnalyzerAndNativeAot; + public Tool IgnoredBy { get; set; } = Tool.All; } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttribute.cs index 05c2818b38badf..b7c08829cc1270 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttribute.cs @@ -13,6 +13,6 @@ public class KeptAttribute : BaseExpectedLinkedBehaviorAttribute /// This property can override that by setting only the platforms /// which are expected to keep the target. /// - public Tool By { get; set; } = Tool.TrimmerAnalyzerAndNativeAot; + public Tool By { get; set; } = Tool.All; } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/LogContainsAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/LogContainsAttribute.cs index eba0f7bffa8797..dc706341e633c7 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/LogContainsAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/LogContainsAttribute.cs @@ -21,6 +21,6 @@ public LogContainsAttribute(string message, bool regexMatch = false) /// Property used by the result checkers of trimmer and analyzers to determine whether /// the tool should have produced the specified warning on the annotated member. /// - public Tool ProducedBy { get; set; } = Tool.TrimmerAnalyzerAndNativeAot; + public Tool ProducedBy { get; set; } = Tool.All; } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/LogDoesNotContainAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/LogDoesNotContainAttribute.cs index 07c2cd5ddab7c6..f6b6860bc73dc7 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/LogDoesNotContainAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/LogDoesNotContainAttribute.cs @@ -21,6 +21,6 @@ public LogDoesNotContainAttribute(string message, bool regexMatch = false) /// Property used by the result checkers of trimmer and analyzers to determine whether /// the tool should have produced the specified warning on the annotated member. /// - public Tool ProducedBy { get; set; } = Tool.TrimmerAnalyzerAndNativeAot; + public Tool ProducedBy { get; set; } = Tool.All; } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedOverrideAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedOverrideAttribute.cs index 4b630f40fbaf68..1b1fa671c11df7 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedOverrideAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedOverrideAttribute.cs @@ -8,7 +8,7 @@ namespace Mono.Linker.Tests.Cases.Expectations.Assertions /// /// Used to ensure that a method should remove an 'override' annotation for a method in the supplied base type. /// Fails in tests if the method has the override method in the linked assembly, - /// or if the override is not found in the original assembly + /// or if the override is not found in the original assembly /// /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs index eb98c8f16a06e7..8b264d36b9c1b3 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs @@ -10,6 +10,6 @@ public class SkipKeptItemsValidationAttribute : BaseExpectedLinkedBehaviorAttrib { public SkipKeptItemsValidationAttribute() { } - public Tool By { get; set; } = Tool.TrimmerAnalyzerAndNativeAot; + public Tool By { get; set; } = Tool.All; } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/Tool.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/Tool.cs index 2482d85697eefc..81d270471aa948 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/Tool.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/Tool.cs @@ -17,6 +17,6 @@ public enum Tool Trimmer = 1, Analyzer = 2, NativeAot = 4, - TrimmerAnalyzerAndNativeAot = Trimmer | Analyzer | NativeAot + All = Trimmer | Analyzer | NativeAot } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Helpers/PlatformAssemblies.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Helpers/PlatformAssemblies.cs index 45b4ae863e9429..2fa8bbc73c2d47 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Helpers/PlatformAssemblies.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Helpers/PlatformAssemblies.cs @@ -8,7 +8,7 @@ public static class PlatformAssemblies #if NET public const string CoreLib = "System.Private.CoreLib.dll"; #else - public const string CoreLib = "mscorlib.dll"; + public const string CoreLib = "mscorlib.dll"; #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/GenerateTargetFrameworkAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/GenerateTargetFrameworkAttribute.cs new file mode 100644 index 00000000000000..ec08453d104ae6 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/GenerateTargetFrameworkAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + public sealed class GenerateTargetFrameworkAttribute : BaseMetadataAttribute + { + public readonly bool Value; + + public GenerateTargetFrameworkAttribute(bool value) + { + Value = value; + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerArgumentAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerArgumentAttribute.cs index ce15de47bfed0f..4e461de65ac799 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerArgumentAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerArgumentAttribute.cs @@ -8,7 +8,7 @@ namespace Mono.Linker.Tests.Cases.Expectations.Metadata /// /// Used to define arguments to pass to ILLink. - /// + /// /// Don't use this attribute to setup single character flags. These flags do a poor job of communicating their purpose /// and although we need to continue to support the usages that exist today, that doesn't mean we need to make our tests harder to read /// diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj index b65c85abb00f5a..6211174e391459 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj @@ -1,5 +1,11 @@ + + + $(NoWarn);CS0436 + + + diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Support/DynamicallyAccessedMembersAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Support/DynamicallyAccessedMembersAttribute.cs new file mode 100644 index 00000000000000..fda78a81108e97 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Support/DynamicallyAccessedMembersAttribute.cs @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace System.Diagnostics.CodeAnalysis +{ + using System.Runtime.CompilerServices; + + [SkipKeptItemsValidation] + [CompilerLoweringPreserve] + [AttributeUsage( + AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter | + AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method | + AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct, + Inherited = false)] + public sealed class DynamicallyAccessedMembersAttribute : Attribute + { + public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes) + { + MemberTypes = memberTypes; + } + + public DynamicallyAccessedMemberTypes MemberTypes { get; } + } +} + +namespace System.Runtime.CompilerServices +{ + [SkipKeptItemsValidation] + [AttributeUsage(AttributeTargets.Class, Inherited = false)] + public class CompilerLoweringPreserveAttribute : Attribute + + { + public CompilerLoweringPreserveAttribute() { } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Support/RemoveAttributeInstancesAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Support/RemoveAttributeInstancesAttribute.cs index 5fcec406159296..e66d6ac6f8ef3d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Support/RemoveAttributeInstancesAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Support/RemoveAttributeInstancesAttribute.cs @@ -6,7 +6,7 @@ namespace Mono.Linker { /// - /// This attribute name will be the name hardcoded in illink which will remove all + /// This attribute name will be the name hardcoded in illink which will remove all /// attribute usages but not the attribute definition /// [AttributeUsage( diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnTypeWithNonExistentMethod.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnTypeWithNonExistentMethod.cs index c830da9e542fd4..a84ca2a74de008 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnTypeWithNonExistentMethod.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnTypeWithNonExistentMethod.cs @@ -19,10 +19,10 @@ public static void Main() class Bar { #if !FLAG - public int Method () - { - return 1; - } + public int Method() + { + return 1; + } #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/AssemblyAttributeAccessesMembers.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/AssemblyAttributeAccessesMembers.cs index a7c1b8e6ef7f70..e81cc60806168e 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/AssemblyAttributeAccessesMembers.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/AssemblyAttributeAccessesMembers.cs @@ -57,8 +57,8 @@ public class AccessesMembersAttribute : Attribute { [Kept] public AccessesMembersAttribute( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/BoxedValues.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/BoxedValues.cs index 84b6f0d718b7d1..d0a9d34587234c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/BoxedValues.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/BoxedValues.cs @@ -6,12 +6,12 @@ namespace Mono.Linker.Tests.Cases.Attributes public class BoxedValues { // mcs bug - // [TestAttribute ((object)typeof (Enum_2))] - // [Kept] - // [KeptAttributeAttribute (typeof (TestAttribute))] - // public void Test_1 () - // { - // } + // [TestAttribute((object)typeof(Enum_2))] + // [Kept] + // [KeptAttributeAttribute(typeof(TestAttribute))] + // public void Test_1() + // { + // } [TestAttribute(TestProperty = Enum_2.B)] [Kept] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/CoreLibraryAssemblyAttributesAreKept.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/CoreLibraryAssemblyAttributesAreKept.cs index 3bb24d962aee9d..3ed67c91b7dccd 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/CoreLibraryAssemblyAttributesAreKept.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/CoreLibraryAssemblyAttributesAreKept.cs @@ -14,8 +14,8 @@ namespace Mono.Linker.Tests.Cases.Attributes [KeptAttributeInAssembly(PlatformAssemblies.CoreLib, typeof(AssemblyDescriptionAttribute))] [KeptAttributeInAssembly(PlatformAssemblies.CoreLib, typeof(AssemblyCompanyAttribute))] #if !NET - [KeptAttributeInAssembly ("System.dll", typeof (AssemblyDescriptionAttribute))] - [KeptAttributeInAssembly ("System.dll", typeof (AssemblyCompanyAttribute))] + [KeptAttributeInAssembly("System.dll", typeof(AssemblyDescriptionAttribute))] + [KeptAttributeInAssembly("System.dll", typeof(AssemblyCompanyAttribute))] #endif public class CoreLibraryAssemblyAttributesAreKept { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/Dependencies/IVTUnused_Lib.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/Dependencies/IVTUnused_Lib.cs index 93a680a2858962..ce385c26e037b6 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/Dependencies/IVTUnused_Lib.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/Dependencies/IVTUnused_Lib.cs @@ -1,6 +1,6 @@ #if IVT -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo ("missing")] -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo ("test-with-key, PublicKey=00240000")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("missing")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("test-with-key, PublicKey=00240000")] #endif namespace Mono.Linker.Tests.Cases.Attributes.Dependencies; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/Dependencies/IVTUsed_Lib.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/Dependencies/IVTUsed_Lib.cs index 23ad8bb5d55c6f..6bb275254764f9 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/Dependencies/IVTUsed_Lib.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/Dependencies/IVTUsed_Lib.cs @@ -2,7 +2,7 @@ using System.Runtime.CompilerServices; #if IVT -[assembly: InternalsVisibleTo ("test")] +[assembly: InternalsVisibleTo("test")] #endif namespace Mono.Linker.Tests.Cases.Attributes.Dependencies diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUnusedAssemblyAttributesAreRemoved.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUnusedAssemblyAttributesAreRemoved.cs index 6f592be389e31d..527a0297d8f984 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUnusedAssemblyAttributesAreRemoved.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUnusedAssemblyAttributesAreRemoved.cs @@ -11,7 +11,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed [SetupLinkerArgument("--used-attrs-only", "true")] [RemovedAttributeInAssembly(PlatformAssemblies.CoreLib, typeof(AssemblyDescriptionAttribute))] #if !NET - [RemovedAttributeInAssembly ("System.dll", typeof (AssemblyDescriptionAttribute))] + [RemovedAttributeInAssembly("System.dll", typeof(AssemblyDescriptionAttribute))] #endif public class CoreLibraryUnusedAssemblyAttributesAreRemoved { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUsedAssemblyAttributesAreKept.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUsedAssemblyAttributesAreKept.cs index 1dd85b6be709d0..9fa964d1d6f646 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUsedAssemblyAttributesAreKept.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUsedAssemblyAttributesAreKept.cs @@ -11,7 +11,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed [SetupLinkerArgument("--used-attrs-only", "true")] [KeptAttributeInAssembly(PlatformAssemblies.CoreLib, typeof(AssemblyDescriptionAttribute))] #if !NET - [KeptAttributeInAssembly ("System.dll", typeof (AssemblyDescriptionAttribute))] + [KeptAttributeInAssembly("System.dll", typeof(AssemblyDescriptionAttribute))] #endif public class CoreLibraryUsedAssemblyAttributesAreKept { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UnusedAttributeOnGenericParameterIsRemoved.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UnusedAttributeOnGenericParameterIsRemoved.cs index 36376ce290846c..c5f3850a7060cc 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UnusedAttributeOnGenericParameterIsRemoved.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UnusedAttributeOnGenericParameterIsRemoved.cs @@ -13,8 +13,8 @@ public class UnusedAttributeOnGenericParameterIsRemoved static void Main() { #if IL_ASSEMBLY_AVAILABLE - var tmp = new Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed.Dependencies.GenericType (8).Method (); - var tmp2 = new Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed.Dependencies.TypeWithGenericMethod ().GenericMethod (9); + var tmp = new Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed.Dependencies.GenericType(8).Method(); + var tmp2 = new Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed.Dependencies.TypeWithGenericMethod().GenericMethod(9); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UnusedAttributeOnReturnTypeIsRemoved.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UnusedAttributeOnReturnTypeIsRemoved.cs index 34270bfb764ebb..159f45ad6a4b73 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UnusedAttributeOnReturnTypeIsRemoved.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UnusedAttributeOnReturnTypeIsRemoved.cs @@ -14,9 +14,9 @@ public class UnusedAttributeOnReturnTypeIsRemoved static void Main() { #if IL_ASSEMBLY_AVAILABLE - var tmp = new Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed.Dependencies.AssemblyWithUnusedAttributeOnReturnParameterDefinition ().Method (1); - var tmp2 = new Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed.Dependencies.AssemblyWithUnusedAttributeOnReturnParameterDefinition ().MethodWithoutParameters (); - var tmp3 = new Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed.Dependencies.AssemblyWithUnusedAttributeOnReturnParameterDefinition ().MethodWithoutParametersNonNestedAttribute (); + var tmp = new Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed.Dependencies.AssemblyWithUnusedAttributeOnReturnParameterDefinition().Method(1); + var tmp2 = new Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed.Dependencies.AssemblyWithUnusedAttributeOnReturnParameterDefinition().MethodWithoutParameters(); + var tmp3 = new Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed.Dependencies.AssemblyWithUnusedAttributeOnReturnParameterDefinition().MethodWithoutParametersNonNestedAttribute(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/Dependencies/CustomStepDummy.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/Dependencies/CustomStepDummy.cs index 8e03eb21656ed3..2ca98c18f4c7b2 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/Dependencies/CustomStepDummy.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/Dependencies/CustomStepDummy.cs @@ -4,11 +4,11 @@ namespace CustomStep { - public class CustomStepDummy : IStep - { - public void Process (LinkContext context) - { - context.LogMessage (MessageContainer.CreateInfoMessage ("Custom step added.")); - } - } + public class CustomStepDummy : IStep + { + public void Process(LinkContext context) + { + context.LogMessage(MessageContainer.CreateInfoMessage("Custom step added.")); + } + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/Dependencies/CustomStepUser.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/Dependencies/CustomStepUser.cs index b74c218c901647..37a0b62fcd02bb 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/Dependencies/CustomStepUser.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/Dependencies/CustomStepUser.cs @@ -4,12 +4,12 @@ namespace CustomStep { - public class CustomStepUser : IStep - { - public void Process (LinkContext context) - { - if (context.TryGetCustomData ("NewKey", out var value)) - context.LogMessage (MessageContainer.CreateInfoMessage ("Custom step added with custom data of " + value)); - } - } + public class CustomStepUser : IStep + { + public void Process(LinkContext context) + { + if (context.TryGetCustomData("NewKey", out var value)) + context.LogMessage(MessageContainer.CreateInfoMessage("Custom step added with custom data of " + value)); + } + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/ComponentModel/TypeDescriptionProviderAttributeOnType.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/ComponentModel/TypeDescriptionProviderAttributeOnType.cs index e190e4cfc4332a..e92a008367a529 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/ComponentModel/TypeDescriptionProviderAttributeOnType.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/ComponentModel/TypeDescriptionProviderAttributeOnType.cs @@ -50,8 +50,8 @@ public class InterfaceTypeConverter : TypeConverter { [Kept] public static IInterface CreateVisual( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type visualType) { try diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/CppCLI/Dependencies/CallCppCLIFromManaged.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/CppCLI/Dependencies/CallCppCLIFromManaged.cs index 7b72517864ecc2..00cc1125baaeac 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/CppCLI/Dependencies/CallCppCLIFromManaged.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/CppCLI/Dependencies/CallCppCLIFromManaged.cs @@ -5,11 +5,11 @@ namespace Mono.Linker.Tests.Cases.CppCLI.Dependencies { - public static class CallCppCLIFromManaged - { - public static void TriggerWarning () - { - TestClass.TriggerWarningFromCppCLI (); - } - } + public static class CallCppCLIFromManaged + { + public static void TriggerWarning() + { + TestClass.TriggerWarningFromCppCLI(); + } + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ArrayDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ArrayDataFlow.cs index b9b2defc6a44b2..a5af781781f8cc 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ArrayDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ArrayDataFlow.cs @@ -592,7 +592,7 @@ static void TestNullCoalescingAssignmentComplex() } // ILLink only incidentally matches the analyzer behavior here. - [UnexpectedWarning("IL2062", nameof(DataFlowTypeExtensions.RequiresAll), Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/linker/issues/2737")] + [UnexpectedWarning("IL2062", nameof(DataFlowTypeExtensions.RequiresAll), Tool.All, "https://github.com/dotnet/linker/issues/2737")] [ExpectedWarning("IL2072", nameof(GetUnknownType), nameof(DataFlowTypeExtensions.RequiresAll), Tool.None, "https://github.com/dotnet/linker/issues/2737")] [ExpectedWarning("IL2072", nameof(GetTypeWithPublicConstructors), nameof(DataFlowTypeExtensions.RequiresAll), Tool.None, "https://github.com/dotnet/linker/issues/2737")] static void TestNullCoalescingAssignmentToEmptyComplex() @@ -654,15 +654,15 @@ static void TestInlineArrayElementReferenceAssignment(bool b = true) } // Inline array references are not allowed in conditionals, unlike array references. - // static void TestInlineArrayElementAssignment (bool b = true) + // static void TestInlineArrayElementAssignment(bool b = true) // { - // var arr1 = new InlineTypeArray (); - // arr1[0] = GetUnknownType (); - // var arr2 = new InlineTypeArray (); - // arr2[0] = GetTypeWithPublicConstructors (); - // (b ? arr1 : arr2)[0] = GetWithPublicMethods (); - // arr1[0].RequiresAll (); - // arr2[0].RequiresAll (); + // var arr1 = new InlineTypeArray(); + // arr1[0] = GetUnknownType(); + // var arr2 = new InlineTypeArray(); + // arr2[0] = GetTypeWithPublicConstructors(); + // (b ? arr1 : arr2)[0] = GetWithPublicMethods(); + // arr1[0].RequiresAll(); + // arr2[0].RequiresAll(); // } [ExpectedWarning("IL2087", nameof(T), nameof(DataFlowTypeExtensions.RequiresAll))] @@ -707,7 +707,7 @@ public static void Test() { TestArrayElementAssignment(); TestInlineArrayElementReferenceAssignment(); - // TestInlineArrayElementAssignment (); + // TestInlineArrayElementAssignment(); TestNullCoalesce(); TestNullCoalescingAssignment(); } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs index 65d1f234896c37..e7f33dab71a0a1 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs @@ -58,7 +58,7 @@ static void TestConstructors() RequireNothing(type); } - [ExpectedWarning("IL2122", "Type 'System.Invalid.TypeName' is not assembly qualified. " + "Type name strings used for dynamically accessing a type should be assembly qualified.", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2122", "Type 'System.Invalid.TypeName' is not assembly qualified. Type name strings used for dynamically accessing a type should be assembly qualified.")] static void TestUnqualifiedTypeNameWarns() { RequirePublicConstructors("System.Invalid.TypeName"); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs index 5e73d4bc708bec..557fd8fbfefcc8 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs @@ -6,15 +6,17 @@ using System.Reflection; using Mono.Linker.Tests.Cases.DataFlow; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; [assembly: KeptAttributeAttribute(typeof(AttributeConstructorDataflow.KeepsPublicPropertiesAttribute))] -[assembly: ExpectedWarning("IL2026", "--ClassWithKeptPublicProperties--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/2273")] +[assembly: ExpectedWarning("IL2026", "--ClassWithKeptPublicProperties--")] [assembly: AttributeConstructorDataflow.KeepsPublicProperties(typeof(AttributeConstructorDataflow.ClassWithKeptPublicProperties))] namespace Mono.Linker.Tests.Cases.DataFlow { [Kept] [ExpectedNoWarnings] + [SetupIlcWholeProgramAnalysis] class AttributeConstructorDataflow { [KeptAttributeAttribute(typeof(KeepsPublicConstructorAttribute))] @@ -25,11 +27,12 @@ class AttributeConstructorDataflow [KeepsPublicMethods("Mono.Linker.Tests.Cases.DataFlow.AttributeConstructorDataflow+ClassWithKeptPublicMethods, test")] [KeepsPublicFields(null, null)] [TypeArray(new Type[] { typeof(AttributeConstructorDataflow) })] - [ExpectedWarning("IL2026", "--ClassWithKeptPublicMethods--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/2273")] + [ExpectedWarning("IL2026", "--ClassWithKeptPublicMethods--")] public static void Main() { typeof(AttributeConstructorDataflow).GetMethod("Main").GetCustomAttribute(typeof(KeepsPublicConstructorAttribute)); typeof(AttributeConstructorDataflow).GetMethod("Main").GetCustomAttribute(typeof(KeepsPublicMethodsAttribute)); + Assembly.GetEntryAssembly().GetCustomAttributes(); AllOnSelf.Test(); AnnotationOnTypeArray.Test(); } @@ -53,8 +56,8 @@ class KeepsPublicMethodsAttribute : Attribute { [Kept] public KeepsPublicMethodsAttribute( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] string type) { } @@ -84,8 +87,8 @@ public class KeepsPublicPropertiesAttribute : Attribute { [Kept] public KeepsPublicPropertiesAttribute( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type) { } @@ -141,8 +144,8 @@ class KeepsAllAttribute : Attribute { [Kept] public KeepsAllAttribute( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type) { } @@ -172,8 +175,8 @@ class AttributeRequiresTypeArrayAttribute : Attribute [Kept] [ExpectedWarning("IL2098")] public AttributeRequiresTypeArrayAttribute( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type[] types) { RequirePublicFields(types); @@ -182,8 +185,8 @@ public AttributeRequiresTypeArrayAttribute( [Kept] [ExpectedWarning("IL2098")] static void RequirePublicFields( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type[] types) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs index b28748d72facee..7a50cce7174b4a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs @@ -5,11 +5,13 @@ using System.Diagnostics.CodeAnalysis; using System.Reflection; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.DataFlow { [Kept] [ExpectedNoWarnings] + [SetupIlcWholeProgramAnalysis] class AttributeFieldDataflow { public static void Main() @@ -40,7 +42,7 @@ public static void TestKeepsPublicMethods() [Kept] [KeptAttributeAttribute(typeof(KeepsPublicMethodsAttribute))] - [ExpectedWarning("IL2026", "--ClassWithKeptPublicMethods--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "--ClassWithKeptPublicMethods--")] [KeepsPublicMethods(TypeName = "Mono.Linker.Tests.Cases.DataFlow.AttributeFieldDataflow+ClassWithKeptPublicMethods, test")] public static void TestKeepsPublicMethodsString() { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePrimaryConstructorDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePrimaryConstructorDataflow.cs new file mode 100644 index 00000000000000..87343f8835005e --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePrimaryConstructorDataflow.cs @@ -0,0 +1,33 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using Mono.Linker.Tests.Cases.DataFlow; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [Kept] + [ExpectedNoWarnings] + class AttributePrimaryConstructorDataflow + { + public static void Main() + { + new PrimaryConstructor(typeof(int)).UseField(); + } + + [Kept] + [KeptMember(".ctor(System.Type)")] + class PrimaryConstructor( + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t + ) + { + [Kept] + public void UseField() => t.RequiresPublicMethods(); + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs index 14ecc1445c4ace..b3c301044eafa8 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs @@ -5,11 +5,13 @@ using System.Diagnostics.CodeAnalysis; using System.Reflection; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.DataFlow { [Kept] [ExpectedNoWarnings] + [SetupIlcWholeProgramAnalysis] class AttributePropertyDataflow { public static void Main() @@ -56,8 +58,7 @@ public static void TestKeepsPublicMethods() [Kept] [KeptAttributeAttribute(typeof(KeepsPublicMethodsAttribute))] - // Trimmer/NativeAot only for now - [ExpectedWarning("IL2026", "--ClassWithKeptPublicMethodsKeptByName--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "--ClassWithKeptPublicMethodsKeptByName--")] [KeepsPublicMethods(TypeName = "Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+AttributesOnMethod+ClassWithKeptPublicMethodsKeptByName, test")] public static void TestKeepsPublicMethodsByName() { @@ -213,8 +214,7 @@ class AttributeWithConditionalExpression { [Kept] [KeptAttributeAttribute(typeof(KeepsPublicMethodsAttribute))] - // Trimmer/NativeAot only for now - [ExpectedWarning("IL2026", "--ClassWithKeptPublicMethods--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "--ClassWithKeptPublicMethods--")] [KeepsPublicMethods(TypeName = 1 + 1 == 2 ? "Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+AttributeWithConditionalExpression+ClassWithKeptPublicMethodsKeptByName, test" : null)] public static void Test() { @@ -226,7 +226,7 @@ public static void Test() // where the owning symbol is not a method. [Kept] [KeptAttributeAttribute(typeof(KeepsPublicMethodsAttribute))] - [ExpectedWarning("IL2026", "--ClassWithKeptPublicMethods--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "--ClassWithKeptPublicMethods--")] [KeepsPublicMethods(TypeName = 1 + 1 == 2 ? "Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+AttributeWithConditionalExpression+ClassWithKeptPublicMethodsKeptByName, test" : null)] public static int field; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs index f2b183aab7c893..89fa5d418b4cc8 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs @@ -5,8 +5,8 @@ using System.Diagnostics.CodeAnalysis; using System.Reflection; using Mono.Linker.Tests.Cases.Expectations.Assertions; -using Mono.Linker.Tests.Cases.Expectations.Metadata; using Mono.Linker.Tests.Cases.Expectations.Helpers; +using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.DataFlow { @@ -49,7 +49,7 @@ public static void Main() [ExpectedWarning("IL2077", nameof(ByRefDataflow) + "." + nameof(MethodWithRefParameter) + "(Type&)", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/2406")] [ExpectedWarning("IL2077", nameof(ByRefDataflow) + "." + nameof(MethodWithRefParameter) + "(ref Type)", Tool.Analyzer, "https://github.com/dotnet/linker/issues/2406")] [ExpectedWarning("IL2069", [nameof(s_typeWithPublicParameterlessConstructor), "parameter 'type'", nameof(MethodWithRefParameter)], Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/101955")] - // MethodWithRefParameter (ref x) + // MethodWithRefParameter(ref x) [ExpectedWarning("IL2077", nameof(ByRefDataflow) + "." + nameof(MethodWithRefParameter) + "(Type&)", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/2406")] [ExpectedWarning("IL2077", nameof(ByRefDataflow) + "." + nameof(MethodWithRefParameter) + "(ref Type)", Tool.Analyzer, "https://github.com/dotnet/linker/issues/2406")] public static void PassRefToField() @@ -169,11 +169,11 @@ class MultipleOutRefsToField [Kept] static void TwoOutRefs( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] out Type publicMethods, - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] out Type publicProperties) { publicMethods = null; @@ -215,11 +215,11 @@ static void TestFieldAssignment(bool b = true) [ExpectedWarning("IL2072", nameof(publicPropertiesParameter), nameof(GetUnknownType))] static void TestParameterAssignment( bool b = true, - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type publicMethodsParameter = null, - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type publicPropertiesParameter = null) { (b ? ref publicMethodsParameter : ref publicPropertiesParameter) = GetUnknownType(); @@ -280,8 +280,8 @@ static void TestNullCoalescingAssignmentComplex(bool b = true) [ExpectedWarning("IL2074", nameof(_publicPropertiesField), nameof(GetUnknownType))] static void TestDataFlowOnRightHandOfAssignment( bool b = true, - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type type = null) + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type = null) { (b ? ref _publicMethodsField : ref _publicPropertiesField) = (type = GetUnknownType()); } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypes.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypes.cs index 1af43fcd0487b7..ec801d05682e3e 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypes.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypes.cs @@ -7,6 +7,8 @@ using System.Reflection; using System.Threading.Tasks; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; +using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.DataFlow { @@ -14,6 +16,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow [ExpectedNoWarnings] [SkipKeptItemsValidation] + [Define("INCLUDE_UNEXPECTED_LOWERING_WARNINGS")] // https://github.com/dotnet/roslyn/issues/79333 + [Define("DEBUG")] + [SetupLinkerArgument("--disable-generated-code-heuristics")] public class CompilerGeneratedTypes { public static void Main() @@ -43,6 +48,8 @@ public static void Main() CapturingLocalFunctionInsideIterator(); LambdaInsideAsync(); LocalFunctionInsideAsync(); + NestedAsyncLambda.Test(); + NestedAsyncLocalFunction.Test(); NestedStaticLambda.Test(); } @@ -66,6 +73,9 @@ private static void IteratorTypeMismatch() _ = Local(); [ExpectedWarning("IL2090", nameof(DynamicallyAccessedMemberTypes.PublicProperties), CompilerGeneratedCode = true)] +#if INCLUDE_UNEXPECTED_LOWERING_WARNINGS + [UnexpectedWarning("IL2090", "T", "PublicMethods", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] +#endif static IEnumerable Local<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() { foreach (var m in typeof(T).GetMethods()) @@ -83,6 +93,10 @@ private static void LocalIterator() { foreach (var m in Local()) { } +#if INCLUDE_UNEXPECTED_LOWERING_WARNINGS + [UnexpectedWarning("IL2090", "T1", "PublicMethods", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] + [UnexpectedWarning("IL2090", "T2", "PublicProperties", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] +#endif static IEnumerable Local< [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T1, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T2>() @@ -104,6 +118,11 @@ private static void IteratorCapture() void Local1<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T1>() { _ = Local2(); + +#if INCLUDE_UNEXPECTED_LOWERING_WARNINGS + [UnexpectedWarning("IL2090", "T1", "PublicMethods", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] + [UnexpectedWarning("IL2090", "T2", "PublicProperties", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] +#endif IEnumerable Local2<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T2>() { foreach (var m in typeof(T1).GetMethods()) @@ -121,9 +140,18 @@ private static void IteratorCapture() private static void NestedIterators() { Local1(); + +#if INCLUDE_UNEXPECTED_LOWERING_WARNINGS + [UnexpectedWarning("IL2091", "T1", "PublicMethods", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] +#endif IEnumerable Local1<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T1>() { foreach (var o in Local2()) { yield return o; } + +#if INCLUDE_UNEXPECTED_LOWERING_WARNINGS + [UnexpectedWarning("IL2090", "T1", "PublicMethods", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] + [UnexpectedWarning("IL2090", "T2", "PublicProperties", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] +#endif IEnumerable Local2<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T2>() { foreach (var m in typeof(T1).GetMethods()) @@ -141,10 +169,21 @@ private static void NestedIterators() private static void IteratorInsideClosure() { Outer(); + +#if INCLUDE_UNEXPECTED_LOWERING_WARNINGS + [UnexpectedWarning("IL2091", "T1", "PublicMethods", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] + [UnexpectedWarning("IL2091", "T1", "PublicMethods", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] + [UnexpectedWarning("IL2091", "T1", "PublicMethods", Tool.Trimmer, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] + [UnexpectedWarning("IL2091", "T1", "PublicMethods", Tool.Trimmer, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] +#endif IEnumerable Outer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T1>() { int x = 0; foreach (var o in Inner()) yield return o; + +#if INCLUDE_UNEXPECTED_LOWERING_WARNINGS + [UnexpectedWarning("IL2090", "T2", "PublicProperties", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] +#endif IEnumerable Inner<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T2>() { x++; @@ -158,6 +197,12 @@ private static void IteratorInsideClosureMismatch() { Outer(); +#if INCLUDE_UNEXPECTED_LOWERING_WARNINGS + [UnexpectedWarning("IL2091", "T1", "PublicProperties", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] + [UnexpectedWarning("IL2091", "T1", "PublicProperties", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] + [UnexpectedWarning("IL2091", "T1", "PublicProperties", Tool.Trimmer, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] + [UnexpectedWarning("IL2091", "T1", "PublicProperties", Tool.Trimmer, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] +#endif IEnumerable Outer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T1>() { int x = 0; @@ -178,6 +223,9 @@ private static void IteratorInsideClosureMismatch() private static void Async() { Local().Wait(); +#if INCLUDE_UNEXPECTED_LOWERING_WARNINGS + [UnexpectedWarning("IL2090", "T", "PublicMethods", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] +#endif async Task Local<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() { await Task.Delay(0); @@ -191,6 +239,11 @@ private static void AsyncCapture() void Local1<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T1>() { Local2().Wait(); + +#if INCLUDE_UNEXPECTED_LOWERING_WARNINGS + [UnexpectedWarning("IL2090", "T1", "PublicMethods", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] + [UnexpectedWarning("IL2090", "T2", "PublicProperties", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] +#endif async Task Local2<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T2>() { await Task.Delay(0); @@ -201,11 +254,14 @@ private static void AsyncCapture() } } - [ExpectedWarning("IL2090", nameof(DynamicallyAccessedMemberTypes.PublicProperties), CompilerGeneratedCode = true)] private static void AsyncTypeMismatch() { _ = Local(); + [ExpectedWarning("IL2090", "T", nameof(DynamicallyAccessedMemberTypes.PublicProperties), CompilerGeneratedCode = true)] +#if INCLUDE_UNEXPECTED_LOWERING_WARNINGS + [UnexpectedWarning("IL2090", "T", "PublicMethods", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] +#endif static async Task Local<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() { await Task.Delay(0); @@ -222,6 +278,10 @@ private static void AsyncInsideClosure() { int x = 0; Inner().Wait(); + +#if INCLUDE_UNEXPECTED_LOWERING_WARNINGS + [UnexpectedWarning("IL2090", "T2", "PublicProperties", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] +#endif async Task Inner<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T2>() { await Task.Delay(0); @@ -365,6 +425,50 @@ void LocalFunction() LocalFunction(); } + class NestedAsyncLambda + { + public static async void Test<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() + { + var outer = async () => + { + var inner = + [ExpectedWarning("IL2090", "T", nameof(DynamicallyAccessedMemberTypes.PublicProperties))] + () => + { + _ = typeof(T).GetMethods(); + _ = typeof(T).GetProperties(); + }; + + inner(); + }; + + outer().Wait(); + } + } + + class NestedAsyncLocalFunction + { + public static void Test<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() + { + Local1(); + +#if INCLUDE_UNEXPECTED_LOWERING_WARNINGS + [UnexpectedWarning("IL2091", "T", nameof(DynamicallyAccessedMemberTypes.PublicMethods), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/roslyn/issues/79333", CompilerGeneratedCode = true)] +#endif + static async Task Local1() + { + Local2(); + + [ExpectedWarning("IL2090", "T", nameof(DynamicallyAccessedMemberTypes.PublicProperties))] + static void Local2() + { + _ = typeof(T).GetMethods(); + _ = typeof(T).GetProperties(); + }; + }; + } + } + class NestedStaticLambda { public static class Container<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T> diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypesNet90.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypesNet90.cs new file mode 100644 index 00000000000000..56cede0ed472aa --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypesNet90.cs @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [ExpectedNoWarnings] + [SkipKeptItemsValidation] + [SetupCompileArgument("/main:Mono.Linker.Tests.Cases.DataFlow.CompilerGeneratedTypesNet90")] + [SandboxDependency("CompilerGeneratedTypes.cs")] + // Without a TargetFramework attribute, the linker uses the pre-.NET10 behavior + // which uses heuristics to understand compiler-generated types. + [GenerateTargetFrameworkAttribute(false)] + class CompilerGeneratedTypesNet90 + { + // This test just links the CompilerGeneratedTypes test without setting the + // TargetFramework attribute, to test the pre-.NET10 behavior of the linker's + // compiler-generated state machine handling. + public static void Main() + { + CompilerGeneratedTypes.Main(); + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypesRelease.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypesRelease.cs index c35f5c2e14b07b..9f3c73d74f9708 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypesRelease.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypesRelease.cs @@ -11,6 +11,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow [SetupCompileArgument("/optimize+")] [SetupCompileArgument("/main:Mono.Linker.Tests.Cases.DataFlow.CompilerGeneratedTypesRelease")] [SandboxDependency("CompilerGeneratedTypes.cs")] + [Define("INCLUDE_UNEXPECTED_LOWERING_WARNINGS")] // https://github.com/dotnet/roslyn/issues/79333 + [SetupLinkerArgument("--disable-generated-code-heuristics")] class CompilerGeneratedTypesRelease { // This test just links the CompilerGeneratedTypes test in the Release configuration, to test diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypesReleaseNet90.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypesReleaseNet90.cs new file mode 100644 index 00000000000000..9e9c4890d38a20 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypesReleaseNet90.cs @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [ExpectedNoWarnings] + [SkipKeptItemsValidation] + [SetupCompileArgument("/optimize+")] + [SetupCompileArgument("/main:Mono.Linker.Tests.Cases.DataFlow.CompilerGeneratedTypesReleaseNet90")] + [SandboxDependency("CompilerGeneratedTypes.cs")] + // Without a TargetFramework attribute, the linker uses the pre-.NET10 behavior + // which uses heuristics to understand compiler-generated types + [GenerateTargetFrameworkAttribute(false)] + class CompilerGeneratedTypesReleaseNet90 + { + // This test just links the CompilerGeneratedTypes test in the Release configuration + // without setting the TargetFramework attribute, to test the pre-.NET10 behavior of + // the linker's compiler-generated state machine handling. + public static void Main() + { + CompilerGeneratedTypes.Main(); + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs index 1bfa672aef84a7..ca563d40dd8467 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs @@ -4,9 +4,11 @@ using System; using System.Diagnostics.CodeAnalysis; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.DataFlow { + [SetupIlcWholeProgramAnalysis] [ExpectedNoWarnings] [UnconditionalSuppressMessage("AOT", "IL3050", Justification = "Applying DAM PublicMethods on an array will mark Array.CreateInstance which has RDC on it")] [KeptAttributeAttribute(typeof(UnconditionalSuppressMessageAttribute))] @@ -175,7 +177,7 @@ static void TestArrayInAttributeParameter() { // Have to access the method through reflection, otherwise NativeAOT will remove all attributes on it // since they're not accessible. - typeof(ComplexTypeHandling).GetMethod(nameof(TestArrayInAttributeParameterImpl), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).Invoke(null, new object[] { }); + typeof(ComplexTypeHandling).GetMethod(nameof(TestArrayInAttributeParameterImpl), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetCustomAttributes(false); } [Kept] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructedTypesDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructedTypesDataFlow.cs index b2dd55515449e7..1a2093ca284866 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructedTypesDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructedTypesDataFlow.cs @@ -58,8 +58,8 @@ static void DeconstructVariablePropertyReference((Type type, object instance) in } record TypeAndInstance( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - [property: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + [property: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type, object instance); @@ -97,14 +97,14 @@ static void DeconstructClassWithAnnotation(TypeAndInstanceManual value) } record TypeAndInstanceRecordManual( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - [property: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + [property: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type, object instance) { // The generated property getter doesn't have the same attributes??? // The attributes are only propagated to the generated .ctor - so suppressing the warning the this.type doesn't have the matching annotations - //[UnconditionalSuppressMessage ("", "IL2072")] + //[UnconditionalSuppressMessage("", "IL2072")] public void Deconstruct([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] out Type type, out object instance) => (type, instance) = (this.type, this.instance); } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/DataflowFailsToConverge.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/DataflowFailsToConverge.cs new file mode 100644 index 00000000000000..508a44f7460ef4 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/DataflowFailsToConverge.cs @@ -0,0 +1,10027 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + public class DataflowFailsToConverge + { + public static void Main() + { + System.Console.WriteLine(MyDictionary["1"]); + } + + [ExpectedWarning("IL2126", "MyDictionary", Tool.Analyzer, "Analyzer only warning")] + public static Dictionary MyDictionary { get; } = new() + { + ["1"] = "1", + ["2"] = "2", + ["3"] = "3", + ["4"] = "4", + ["5"] = "5", + ["6"] = "6", + ["7"] = "7", + ["8"] = "8", + ["9"] = "9", + ["10"] = "10", + ["11"] = "11", + ["12"] = "12", + ["13"] = "13", + ["14"] = "14", + ["15"] = "15", + ["16"] = "16", + ["17"] = "17", + ["18"] = "18", + ["19"] = "19", + ["20"] = "20", + ["21"] = "21", + ["22"] = "22", + ["23"] = "23", + ["24"] = "24", + ["25"] = "25", + ["26"] = "26", + ["27"] = "27", + ["28"] = "28", + ["29"] = "29", + ["30"] = "30", + ["31"] = "31", + ["32"] = "32", + ["33"] = "33", + ["34"] = "34", + ["35"] = "35", + ["36"] = "36", + ["37"] = "37", + ["38"] = "38", + ["39"] = "39", + ["40"] = "40", + ["41"] = "41", + ["42"] = "42", + ["43"] = "43", + ["44"] = "44", + ["45"] = "45", + ["46"] = "46", + ["47"] = "47", + ["48"] = "48", + ["49"] = "49", + ["50"] = "50", + ["51"] = "51", + ["52"] = "52", + ["53"] = "53", + ["54"] = "54", + ["55"] = "55", + ["56"] = "56", + ["57"] = "57", + ["58"] = "58", + ["59"] = "59", + ["60"] = "60", + ["61"] = "61", + ["62"] = "62", + ["63"] = "63", + ["64"] = "64", + ["65"] = "65", + ["66"] = "66", + ["67"] = "67", + ["68"] = "68", + ["69"] = "69", + ["70"] = "70", + ["71"] = "71", + ["72"] = "72", + ["73"] = "73", + ["74"] = "74", + ["75"] = "75", + ["76"] = "76", + ["77"] = "77", + ["78"] = "78", + ["79"] = "79", + ["80"] = "80", + ["81"] = "81", + ["82"] = "82", + ["83"] = "83", + ["84"] = "84", + ["85"] = "85", + ["86"] = "86", + ["87"] = "87", + ["88"] = "88", + ["89"] = "89", + ["90"] = "90", + ["91"] = "91", + ["92"] = "92", + ["93"] = "93", + ["94"] = "94", + ["95"] = "95", + ["96"] = "96", + ["97"] = "97", + ["98"] = "98", + ["99"] = "99", + ["100"] = "100", + ["101"] = "1", + ["102"] = "2", + ["103"] = "3", + ["104"] = "4", + ["105"] = "5", + ["106"] = "6", + ["107"] = "7", + ["108"] = "8", + ["109"] = "9", + ["110"] = "10", + ["111"] = "11", + ["112"] = "12", + ["113"] = "13", + ["114"] = "14", + ["115"] = "15", + ["116"] = "16", + ["117"] = "17", + ["118"] = "18", + ["119"] = "19", + ["120"] = "20", + ["121"] = "21", + ["122"] = "22", + ["123"] = "23", + ["124"] = "24", + ["125"] = "25", + ["126"] = "26", + ["127"] = "27", + ["128"] = "28", + ["129"] = "29", + ["130"] = "30", + ["131"] = "31", + ["132"] = "32", + ["133"] = "33", + ["134"] = "34", + ["135"] = "35", + ["136"] = "36", + ["137"] = "37", + ["138"] = "38", + ["139"] = "39", + ["140"] = "40", + ["141"] = "41", + ["142"] = "42", + ["143"] = "43", + ["144"] = "44", + ["145"] = "45", + ["146"] = "46", + ["147"] = "47", + ["148"] = "48", + ["149"] = "49", + ["150"] = "50", + ["151"] = "51", + ["152"] = "52", + ["153"] = "53", + ["154"] = "54", + ["155"] = "55", + ["156"] = "56", + ["157"] = "57", + ["158"] = "58", + ["159"] = "59", + ["160"] = "60", + ["161"] = "61", + ["162"] = "62", + ["163"] = "63", + ["164"] = "64", + ["165"] = "65", + ["166"] = "66", + ["167"] = "67", + ["168"] = "68", + ["169"] = "69", + ["170"] = "70", + ["171"] = "71", + ["172"] = "72", + ["173"] = "73", + ["174"] = "74", + ["175"] = "75", + ["176"] = "76", + ["177"] = "77", + ["178"] = "78", + ["179"] = "79", + ["180"] = "80", + ["181"] = "81", + ["182"] = "82", + ["183"] = "83", + ["184"] = "84", + ["185"] = "85", + ["186"] = "86", + ["187"] = "87", + ["188"] = "88", + ["189"] = "89", + ["190"] = "90", + ["191"] = "91", + ["192"] = "92", + ["193"] = "93", + ["194"] = "94", + ["195"] = "95", + ["196"] = "96", + ["197"] = "97", + ["198"] = "98", + ["199"] = "99", + ["200"] = "100", + ["201"] = "1", + ["202"] = "2", + ["203"] = "3", + ["204"] = "4", + ["205"] = "5", + ["206"] = "6", + ["207"] = "7", + ["208"] = "8", + ["209"] = "9", + ["210"] = "10", + ["211"] = "11", + ["212"] = "12", + ["213"] = "13", + ["214"] = "14", + ["215"] = "15", + ["216"] = "16", + ["217"] = "17", + ["218"] = "18", + ["219"] = "19", + ["220"] = "20", + ["221"] = "21", + ["222"] = "22", + ["223"] = "23", + ["224"] = "24", + ["225"] = "25", + ["226"] = "26", + ["227"] = "27", + ["228"] = "28", + ["229"] = "29", + ["230"] = "30", + ["231"] = "31", + ["232"] = "32", + ["233"] = "33", + ["234"] = "34", + ["235"] = "35", + ["236"] = "36", + ["237"] = "37", + ["238"] = "38", + ["239"] = "39", + ["240"] = "40", + ["241"] = "41", + ["242"] = "42", + ["243"] = "43", + ["244"] = "44", + ["245"] = "45", + ["246"] = "46", + ["247"] = "47", + ["248"] = "48", + ["249"] = "49", + ["250"] = "50", + ["251"] = "51", + ["252"] = "52", + ["253"] = "53", + ["254"] = "54", + ["255"] = "55", + ["256"] = "56", + ["257"] = "57", + ["258"] = "58", + ["259"] = "59", + ["260"] = "60", + ["261"] = "61", + ["262"] = "62", + ["263"] = "63", + ["264"] = "64", + ["265"] = "65", + ["266"] = "66", + ["267"] = "67", + ["268"] = "68", + ["269"] = "69", + ["270"] = "70", + ["271"] = "71", + ["272"] = "72", + ["273"] = "73", + ["274"] = "74", + ["275"] = "75", + ["276"] = "76", + ["277"] = "77", + ["278"] = "78", + ["279"] = "79", + ["280"] = "80", + ["281"] = "81", + ["282"] = "82", + ["283"] = "83", + ["284"] = "84", + ["285"] = "85", + ["286"] = "86", + ["287"] = "87", + ["288"] = "88", + ["289"] = "89", + ["290"] = "90", + ["291"] = "91", + ["292"] = "92", + ["293"] = "93", + ["294"] = "94", + ["295"] = "95", + ["296"] = "96", + ["297"] = "97", + ["298"] = "98", + ["299"] = "99", + ["300"] = "100", + ["301"] = "1", + ["302"] = "2", + ["303"] = "3", + ["304"] = "4", + ["305"] = "5", + ["306"] = "6", + ["307"] = "7", + ["308"] = "8", + ["309"] = "9", + ["310"] = "10", + ["311"] = "11", + ["312"] = "12", + ["313"] = "13", + ["314"] = "14", + ["315"] = "15", + ["316"] = "16", + ["317"] = "17", + ["318"] = "18", + ["319"] = "19", + ["320"] = "20", + ["321"] = "21", + ["322"] = "22", + ["323"] = "23", + ["324"] = "24", + ["325"] = "25", + ["326"] = "26", + ["327"] = "27", + ["328"] = "28", + ["329"] = "29", + ["330"] = "30", + ["331"] = "31", + ["332"] = "32", + ["333"] = "33", + ["334"] = "34", + ["335"] = "35", + ["336"] = "36", + ["337"] = "37", + ["338"] = "38", + ["339"] = "39", + ["340"] = "40", + ["341"] = "41", + ["342"] = "42", + ["343"] = "43", + ["344"] = "44", + ["345"] = "45", + ["346"] = "46", + ["347"] = "47", + ["348"] = "48", + ["349"] = "49", + ["350"] = "50", + ["351"] = "51", + ["352"] = "52", + ["353"] = "53", + ["354"] = "54", + ["355"] = "55", + ["356"] = "56", + ["357"] = "57", + ["358"] = "58", + ["359"] = "59", + ["360"] = "60", + ["361"] = "61", + ["362"] = "62", + ["363"] = "63", + ["364"] = "64", + ["365"] = "65", + ["366"] = "66", + ["367"] = "67", + ["368"] = "68", + ["369"] = "69", + ["370"] = "70", + ["371"] = "71", + ["372"] = "72", + ["373"] = "73", + ["374"] = "74", + ["375"] = "75", + ["376"] = "76", + ["377"] = "77", + ["378"] = "78", + ["379"] = "79", + ["380"] = "80", + ["381"] = "81", + ["382"] = "82", + ["383"] = "83", + ["384"] = "84", + ["385"] = "85", + ["386"] = "86", + ["387"] = "87", + ["388"] = "88", + ["389"] = "89", + ["390"] = "90", + ["391"] = "91", + ["392"] = "92", + ["393"] = "93", + ["394"] = "94", + ["395"] = "95", + ["396"] = "96", + ["397"] = "97", + ["398"] = "98", + ["399"] = "99", + ["400"] = "100", + ["401"] = "1", + ["402"] = "2", + ["403"] = "3", + ["404"] = "4", + ["405"] = "5", + ["406"] = "6", + ["407"] = "7", + ["408"] = "8", + ["409"] = "9", + ["410"] = "10", + ["411"] = "11", + ["412"] = "12", + ["413"] = "13", + ["414"] = "14", + ["415"] = "15", + ["416"] = "16", + ["417"] = "17", + ["418"] = "18", + ["419"] = "19", + ["420"] = "20", + ["421"] = "21", + ["422"] = "22", + ["423"] = "23", + ["424"] = "24", + ["425"] = "25", + ["426"] = "26", + ["427"] = "27", + ["428"] = "28", + ["429"] = "29", + ["430"] = "30", + ["431"] = "31", + ["432"] = "32", + ["433"] = "33", + ["434"] = "34", + ["435"] = "35", + ["436"] = "36", + ["437"] = "37", + ["438"] = "38", + ["439"] = "39", + ["440"] = "40", + ["441"] = "41", + ["442"] = "42", + ["443"] = "43", + ["444"] = "44", + ["445"] = "45", + ["446"] = "46", + ["447"] = "47", + ["448"] = "48", + ["449"] = "49", + ["450"] = "50", + ["451"] = "51", + ["452"] = "52", + ["453"] = "53", + ["454"] = "54", + ["455"] = "55", + ["456"] = "56", + ["457"] = "57", + ["458"] = "58", + ["459"] = "59", + ["460"] = "60", + ["461"] = "61", + ["462"] = "62", + ["463"] = "63", + ["464"] = "64", + ["465"] = "65", + ["466"] = "66", + ["467"] = "67", + ["468"] = "68", + ["469"] = "69", + ["470"] = "70", + ["471"] = "71", + ["472"] = "72", + ["473"] = "73", + ["474"] = "74", + ["475"] = "75", + ["476"] = "76", + ["477"] = "77", + ["478"] = "78", + ["479"] = "79", + ["480"] = "80", + ["481"] = "81", + ["482"] = "82", + ["483"] = "83", + ["484"] = "84", + ["485"] = "85", + ["486"] = "86", + ["487"] = "87", + ["488"] = "88", + ["489"] = "89", + ["490"] = "90", + ["491"] = "91", + ["492"] = "92", + ["493"] = "93", + ["494"] = "94", + ["495"] = "95", + ["496"] = "96", + ["497"] = "97", + ["498"] = "98", + ["499"] = "99", + ["500"] = "100", + ["501"] = "1", + ["502"] = "2", + ["503"] = "3", + ["504"] = "4", + ["505"] = "5", + ["506"] = "6", + ["507"] = "7", + ["508"] = "8", + ["509"] = "9", + ["510"] = "10", + ["511"] = "11", + ["512"] = "12", + ["513"] = "13", + ["514"] = "14", + ["515"] = "15", + ["516"] = "16", + ["517"] = "17", + ["518"] = "18", + ["519"] = "19", + ["520"] = "20", + ["521"] = "21", + ["522"] = "22", + ["523"] = "23", + ["524"] = "24", + ["525"] = "25", + ["526"] = "26", + ["527"] = "27", + ["528"] = "28", + ["529"] = "29", + ["530"] = "30", + ["531"] = "31", + ["532"] = "32", + ["533"] = "33", + ["534"] = "34", + ["535"] = "35", + ["536"] = "36", + ["537"] = "37", + ["538"] = "38", + ["539"] = "39", + ["540"] = "40", + ["541"] = "41", + ["542"] = "42", + ["543"] = "43", + ["544"] = "44", + ["545"] = "45", + ["546"] = "46", + ["547"] = "47", + ["548"] = "48", + ["549"] = "49", + ["550"] = "50", + ["551"] = "51", + ["552"] = "52", + ["553"] = "53", + ["554"] = "54", + ["555"] = "55", + ["556"] = "56", + ["557"] = "57", + ["558"] = "58", + ["559"] = "59", + ["560"] = "60", + ["561"] = "61", + ["562"] = "62", + ["563"] = "63", + ["564"] = "64", + ["565"] = "65", + ["566"] = "66", + ["567"] = "67", + ["568"] = "68", + ["569"] = "69", + ["570"] = "70", + ["571"] = "71", + ["572"] = "72", + ["573"] = "73", + ["574"] = "74", + ["575"] = "75", + ["576"] = "76", + ["577"] = "77", + ["578"] = "78", + ["579"] = "79", + ["580"] = "80", + ["581"] = "81", + ["582"] = "82", + ["583"] = "83", + ["584"] = "84", + ["585"] = "85", + ["586"] = "86", + ["587"] = "87", + ["588"] = "88", + ["589"] = "89", + ["590"] = "90", + ["591"] = "91", + ["592"] = "92", + ["593"] = "93", + ["594"] = "94", + ["595"] = "95", + ["596"] = "96", + ["597"] = "97", + ["598"] = "98", + ["599"] = "99", + ["600"] = "100", + ["601"] = "1", + ["602"] = "2", + ["603"] = "3", + ["604"] = "4", + ["605"] = "5", + ["606"] = "6", + ["607"] = "7", + ["608"] = "8", + ["609"] = "9", + ["610"] = "10", + ["611"] = "11", + ["612"] = "12", + ["613"] = "13", + ["614"] = "14", + ["615"] = "15", + ["616"] = "16", + ["617"] = "17", + ["618"] = "18", + ["619"] = "19", + ["620"] = "20", + ["621"] = "21", + ["622"] = "22", + ["623"] = "23", + ["624"] = "24", + ["625"] = "25", + ["626"] = "26", + ["627"] = "27", + ["628"] = "28", + ["629"] = "29", + ["630"] = "30", + ["631"] = "31", + ["632"] = "32", + ["633"] = "33", + ["634"] = "34", + ["635"] = "35", + ["636"] = "36", + ["637"] = "37", + ["638"] = "38", + ["639"] = "39", + ["640"] = "40", + ["641"] = "41", + ["642"] = "42", + ["643"] = "43", + ["644"] = "44", + ["645"] = "45", + ["646"] = "46", + ["647"] = "47", + ["648"] = "48", + ["649"] = "49", + ["650"] = "50", + ["651"] = "51", + ["652"] = "52", + ["653"] = "53", + ["654"] = "54", + ["655"] = "55", + ["656"] = "56", + ["657"] = "57", + ["658"] = "58", + ["659"] = "59", + ["660"] = "60", + ["661"] = "61", + ["662"] = "62", + ["663"] = "63", + ["664"] = "64", + ["665"] = "65", + ["666"] = "66", + ["667"] = "67", + ["668"] = "68", + ["669"] = "69", + ["670"] = "70", + ["671"] = "71", + ["672"] = "72", + ["673"] = "73", + ["674"] = "74", + ["675"] = "75", + ["676"] = "76", + ["677"] = "77", + ["678"] = "78", + ["679"] = "79", + ["680"] = "80", + ["681"] = "81", + ["682"] = "82", + ["683"] = "83", + ["684"] = "84", + ["685"] = "85", + ["686"] = "86", + ["687"] = "87", + ["688"] = "88", + ["689"] = "89", + ["690"] = "90", + ["691"] = "91", + ["692"] = "92", + ["693"] = "93", + ["694"] = "94", + ["695"] = "95", + ["696"] = "96", + ["697"] = "97", + ["698"] = "98", + ["699"] = "99", + ["700"] = "100", + ["701"] = "1", + ["702"] = "2", + ["703"] = "3", + ["704"] = "4", + ["705"] = "5", + ["706"] = "6", + ["707"] = "7", + ["708"] = "8", + ["709"] = "9", + ["710"] = "10", + ["711"] = "11", + ["712"] = "12", + ["713"] = "13", + ["714"] = "14", + ["715"] = "15", + ["716"] = "16", + ["717"] = "17", + ["718"] = "18", + ["719"] = "19", + ["720"] = "20", + ["721"] = "21", + ["722"] = "22", + ["723"] = "23", + ["724"] = "24", + ["725"] = "25", + ["726"] = "26", + ["727"] = "27", + ["728"] = "28", + ["729"] = "29", + ["730"] = "30", + ["731"] = "31", + ["732"] = "32", + ["733"] = "33", + ["734"] = "34", + ["735"] = "35", + ["736"] = "36", + ["737"] = "37", + ["738"] = "38", + ["739"] = "39", + ["740"] = "40", + ["741"] = "41", + ["742"] = "42", + ["743"] = "43", + ["744"] = "44", + ["745"] = "45", + ["746"] = "46", + ["747"] = "47", + ["748"] = "48", + ["749"] = "49", + ["750"] = "50", + ["751"] = "51", + ["752"] = "52", + ["753"] = "53", + ["754"] = "54", + ["755"] = "55", + ["756"] = "56", + ["757"] = "57", + ["758"] = "58", + ["759"] = "59", + ["760"] = "60", + ["761"] = "61", + ["762"] = "62", + ["763"] = "63", + ["764"] = "64", + ["765"] = "65", + ["766"] = "66", + ["767"] = "67", + ["768"] = "68", + ["769"] = "69", + ["770"] = "70", + ["771"] = "71", + ["772"] = "72", + ["773"] = "73", + ["774"] = "74", + ["775"] = "75", + ["776"] = "76", + ["777"] = "77", + ["778"] = "78", + ["779"] = "79", + ["780"] = "80", + ["781"] = "81", + ["782"] = "82", + ["783"] = "83", + ["784"] = "84", + ["785"] = "85", + ["786"] = "86", + ["787"] = "87", + ["788"] = "88", + ["789"] = "89", + ["790"] = "90", + ["791"] = "91", + ["792"] = "92", + ["793"] = "93", + ["794"] = "94", + ["795"] = "95", + ["796"] = "96", + ["797"] = "97", + ["798"] = "98", + ["799"] = "99", + ["800"] = "100", + ["801"] = "1", + ["802"] = "2", + ["803"] = "3", + ["804"] = "4", + ["805"] = "5", + ["806"] = "6", + ["807"] = "7", + ["808"] = "8", + ["809"] = "9", + ["810"] = "10", + ["811"] = "11", + ["812"] = "12", + ["813"] = "13", + ["814"] = "14", + ["815"] = "15", + ["816"] = "16", + ["817"] = "17", + ["818"] = "18", + ["819"] = "19", + ["820"] = "20", + ["821"] = "21", + ["822"] = "22", + ["823"] = "23", + ["824"] = "24", + ["825"] = "25", + ["826"] = "26", + ["827"] = "27", + ["828"] = "28", + ["829"] = "29", + ["830"] = "30", + ["831"] = "31", + ["832"] = "32", + ["833"] = "33", + ["834"] = "34", + ["835"] = "35", + ["836"] = "36", + ["837"] = "37", + ["838"] = "38", + ["839"] = "39", + ["840"] = "40", + ["841"] = "41", + ["842"] = "42", + ["843"] = "43", + ["844"] = "44", + ["845"] = "45", + ["846"] = "46", + ["847"] = "47", + ["848"] = "48", + ["849"] = "49", + ["850"] = "50", + ["851"] = "51", + ["852"] = "52", + ["853"] = "53", + ["854"] = "54", + ["855"] = "55", + ["856"] = "56", + ["857"] = "57", + ["858"] = "58", + ["859"] = "59", + ["860"] = "60", + ["861"] = "61", + ["862"] = "62", + ["863"] = "63", + ["864"] = "64", + ["865"] = "65", + ["866"] = "66", + ["867"] = "67", + ["868"] = "68", + ["869"] = "69", + ["870"] = "70", + ["871"] = "71", + ["872"] = "72", + ["873"] = "73", + ["874"] = "74", + ["875"] = "75", + ["876"] = "76", + ["877"] = "77", + ["878"] = "78", + ["879"] = "79", + ["880"] = "80", + ["881"] = "81", + ["882"] = "82", + ["883"] = "83", + ["884"] = "84", + ["885"] = "85", + ["886"] = "86", + ["887"] = "87", + ["888"] = "88", + ["889"] = "89", + ["890"] = "90", + ["891"] = "91", + ["892"] = "92", + ["893"] = "93", + ["894"] = "94", + ["895"] = "95", + ["896"] = "96", + ["897"] = "97", + ["898"] = "98", + ["899"] = "99", + ["900"] = "100", + ["901"] = "1", + ["902"] = "2", + ["903"] = "3", + ["904"] = "4", + ["905"] = "5", + ["906"] = "6", + ["907"] = "7", + ["908"] = "8", + ["909"] = "9", + ["910"] = "10", + ["911"] = "11", + ["912"] = "12", + ["913"] = "13", + ["914"] = "14", + ["915"] = "15", + ["916"] = "16", + ["917"] = "17", + ["918"] = "18", + ["919"] = "19", + ["920"] = "20", + ["921"] = "21", + ["922"] = "22", + ["923"] = "23", + ["924"] = "24", + ["925"] = "25", + ["926"] = "26", + ["927"] = "27", + ["928"] = "28", + ["929"] = "29", + ["930"] = "30", + ["931"] = "31", + ["932"] = "32", + ["933"] = "33", + ["934"] = "34", + ["935"] = "35", + ["936"] = "36", + ["937"] = "37", + ["938"] = "38", + ["939"] = "39", + ["940"] = "40", + ["941"] = "41", + ["942"] = "42", + ["943"] = "43", + ["944"] = "44", + ["945"] = "45", + ["946"] = "46", + ["947"] = "47", + ["948"] = "48", + ["949"] = "49", + ["950"] = "50", + ["951"] = "51", + ["952"] = "52", + ["953"] = "53", + ["954"] = "54", + ["955"] = "55", + ["956"] = "56", + ["957"] = "57", + ["958"] = "58", + ["959"] = "59", + ["960"] = "60", + ["961"] = "61", + ["962"] = "62", + ["963"] = "63", + ["964"] = "64", + ["965"] = "65", + ["966"] = "66", + ["967"] = "67", + ["968"] = "68", + ["969"] = "69", + ["970"] = "70", + ["971"] = "71", + ["972"] = "72", + ["973"] = "73", + ["974"] = "74", + ["975"] = "75", + ["976"] = "76", + ["977"] = "77", + ["978"] = "78", + ["979"] = "79", + ["980"] = "80", + ["981"] = "81", + ["982"] = "82", + ["983"] = "83", + ["984"] = "84", + ["985"] = "85", + ["986"] = "86", + ["987"] = "87", + ["988"] = "88", + ["989"] = "89", + ["990"] = "90", + ["991"] = "91", + ["992"] = "92", + ["993"] = "93", + ["994"] = "94", + ["995"] = "95", + ["996"] = "96", + ["997"] = "97", + ["998"] = "98", + ["999"] = "99", + ["1000"] = "99", + ["1001"] = "1", + ["1002"] = "2", + ["1003"] = "3", + ["1004"] = "4", + ["1005"] = "5", + ["1006"] = "6", + ["1007"] = "7", + ["1008"] = "8", + ["1009"] = "9", + ["1000"] = "10", + ["1011"] = "11", + ["1012"] = "12", + ["1013"] = "13", + ["1014"] = "14", + ["1015"] = "15", + ["1016"] = "16", + ["1017"] = "17", + ["1018"] = "18", + ["1019"] = "19", + ["1020"] = "20", + ["1021"] = "21", + ["1022"] = "22", + ["1023"] = "23", + ["1024"] = "24", + ["1025"] = "25", + ["1026"] = "26", + ["1027"] = "27", + ["1028"] = "28", + ["1029"] = "29", + ["1030"] = "30", + ["1031"] = "31", + ["1032"] = "32", + ["1033"] = "33", + ["1034"] = "34", + ["1035"] = "35", + ["1036"] = "36", + ["1037"] = "37", + ["1038"] = "38", + ["1039"] = "39", + ["1040"] = "40", + ["1041"] = "41", + ["1042"] = "42", + ["1043"] = "43", + ["1044"] = "44", + ["1045"] = "45", + ["1046"] = "46", + ["1047"] = "47", + ["1048"] = "48", + ["1049"] = "49", + ["1050"] = "50", + ["1051"] = "51", + ["1052"] = "52", + ["1053"] = "53", + ["1054"] = "54", + ["1055"] = "55", + ["1056"] = "56", + ["1057"] = "57", + ["1058"] = "58", + ["1059"] = "59", + ["1060"] = "60", + ["1061"] = "61", + ["1062"] = "62", + ["1063"] = "63", + ["1064"] = "64", + ["1065"] = "65", + ["1066"] = "66", + ["1067"] = "67", + ["1068"] = "68", + ["1069"] = "69", + ["1070"] = "70", + ["1071"] = "71", + ["1072"] = "72", + ["1073"] = "73", + ["1074"] = "74", + ["1075"] = "75", + ["1076"] = "76", + ["1077"] = "77", + ["1078"] = "78", + ["1079"] = "79", + ["1080"] = "80", + ["1081"] = "81", + ["1082"] = "82", + ["1083"] = "83", + ["1084"] = "84", + ["1085"] = "85", + ["1086"] = "86", + ["1087"] = "87", + ["1088"] = "88", + ["1089"] = "89", + ["1090"] = "90", + ["1091"] = "91", + ["1092"] = "92", + ["1093"] = "93", + ["1094"] = "94", + ["1095"] = "95", + ["1096"] = "96", + ["1097"] = "97", + ["1098"] = "98", + ["1099"] = "99", + ["1100"] = "100", + ["1101"] = "1", + ["1102"] = "2", + ["1103"] = "3", + ["1104"] = "4", + ["1105"] = "5", + ["1106"] = "6", + ["1107"] = "7", + ["1108"] = "8", + ["1109"] = "9", + ["1110"] = "10", + ["1111"] = "11", + ["1112"] = "12", + ["1113"] = "13", + ["1114"] = "14", + ["1115"] = "15", + ["1116"] = "16", + ["1117"] = "17", + ["1118"] = "18", + ["1119"] = "19", + ["1120"] = "20", + ["1121"] = "21", + ["1122"] = "22", + ["1123"] = "23", + ["1124"] = "24", + ["1125"] = "25", + ["1126"] = "26", + ["1127"] = "27", + ["1128"] = "28", + ["1129"] = "29", + ["1130"] = "30", + ["1131"] = "31", + ["1132"] = "32", + ["1133"] = "33", + ["1134"] = "34", + ["1135"] = "35", + ["1136"] = "36", + ["1137"] = "37", + ["1138"] = "38", + ["1139"] = "39", + ["1140"] = "40", + ["1141"] = "41", + ["1142"] = "42", + ["1143"] = "43", + ["1144"] = "44", + ["1145"] = "45", + ["1146"] = "46", + ["1147"] = "47", + ["1148"] = "48", + ["1149"] = "49", + ["1150"] = "50", + ["1151"] = "51", + ["1152"] = "52", + ["1153"] = "53", + ["1154"] = "54", + ["1155"] = "55", + ["1156"] = "56", + ["1157"] = "57", + ["1158"] = "58", + ["1159"] = "59", + ["1160"] = "60", + ["1161"] = "61", + ["1162"] = "62", + ["1163"] = "63", + ["1164"] = "64", + ["1165"] = "65", + ["1166"] = "66", + ["1167"] = "67", + ["1168"] = "68", + ["1169"] = "69", + ["1170"] = "70", + ["1171"] = "71", + ["1172"] = "72", + ["1173"] = "73", + ["1174"] = "74", + ["1175"] = "75", + ["1176"] = "76", + ["1177"] = "77", + ["1178"] = "78", + ["1179"] = "79", + ["1180"] = "80", + ["1181"] = "81", + ["1182"] = "82", + ["1183"] = "83", + ["1184"] = "84", + ["1185"] = "85", + ["1186"] = "86", + ["1187"] = "87", + ["1188"] = "88", + ["1189"] = "89", + ["1190"] = "90", + ["1191"] = "91", + ["1192"] = "92", + ["1193"] = "93", + ["1194"] = "94", + ["1195"] = "95", + ["1196"] = "96", + ["1197"] = "97", + ["1198"] = "98", + ["1199"] = "99", + ["1200"] = "100", + ["1201"] = "1", + ["1202"] = "2", + ["1203"] = "3", + ["1204"] = "4", + ["1205"] = "5", + ["1206"] = "6", + ["1207"] = "7", + ["1208"] = "8", + ["1209"] = "9", + ["1210"] = "10", + ["1211"] = "11", + ["1212"] = "12", + ["1213"] = "13", + ["1214"] = "14", + ["1215"] = "15", + ["1216"] = "16", + ["1217"] = "17", + ["1218"] = "18", + ["1219"] = "19", + ["1220"] = "20", + ["1221"] = "21", + ["1222"] = "22", + ["1223"] = "23", + ["1224"] = "24", + ["1225"] = "25", + ["1226"] = "26", + ["1227"] = "27", + ["1228"] = "28", + ["1229"] = "29", + ["1230"] = "30", + ["1231"] = "31", + ["1232"] = "32", + ["1233"] = "33", + ["1234"] = "34", + ["1235"] = "35", + ["1236"] = "36", + ["1237"] = "37", + ["1238"] = "38", + ["1239"] = "39", + ["1240"] = "40", + ["1241"] = "41", + ["1242"] = "42", + ["1243"] = "43", + ["1244"] = "44", + ["1245"] = "45", + ["1246"] = "46", + ["1247"] = "47", + ["1248"] = "48", + ["1249"] = "49", + ["1250"] = "50", + ["1251"] = "51", + ["1252"] = "52", + ["1253"] = "53", + ["1254"] = "54", + ["1255"] = "55", + ["1256"] = "56", + ["1257"] = "57", + ["1258"] = "58", + ["1259"] = "59", + ["1260"] = "60", + ["1261"] = "61", + ["1262"] = "62", + ["1263"] = "63", + ["1264"] = "64", + ["1265"] = "65", + ["1266"] = "66", + ["1267"] = "67", + ["1268"] = "68", + ["1269"] = "69", + ["1270"] = "70", + ["1271"] = "71", + ["1272"] = "72", + ["1273"] = "73", + ["1274"] = "74", + ["1275"] = "75", + ["1276"] = "76", + ["1277"] = "77", + ["1278"] = "78", + ["1279"] = "79", + ["1280"] = "80", + ["1281"] = "81", + ["1282"] = "82", + ["1283"] = "83", + ["1284"] = "84", + ["1285"] = "85", + ["1286"] = "86", + ["1287"] = "87", + ["1288"] = "88", + ["1289"] = "89", + ["1290"] = "90", + ["1291"] = "91", + ["1292"] = "92", + ["1293"] = "93", + ["1294"] = "94", + ["1295"] = "95", + ["1296"] = "96", + ["1297"] = "97", + ["1298"] = "98", + ["1299"] = "99", + ["1300"] = "100", + ["1301"] = "1", + ["1302"] = "2", + ["1303"] = "3", + ["1304"] = "4", + ["1305"] = "5", + ["1306"] = "6", + ["1307"] = "7", + ["1308"] = "8", + ["1309"] = "9", + ["1310"] = "10", + ["1311"] = "11", + ["1312"] = "12", + ["1313"] = "13", + ["1314"] = "14", + ["1315"] = "15", + ["1316"] = "16", + ["1317"] = "17", + ["1318"] = "18", + ["1319"] = "19", + ["1320"] = "20", + ["1321"] = "21", + ["1322"] = "22", + ["1323"] = "23", + ["1324"] = "24", + ["1325"] = "25", + ["1326"] = "26", + ["1327"] = "27", + ["1328"] = "28", + ["1329"] = "29", + ["1330"] = "30", + ["1331"] = "31", + ["1332"] = "32", + ["1333"] = "33", + ["1334"] = "34", + ["1335"] = "35", + ["1336"] = "36", + ["1337"] = "37", + ["1338"] = "38", + ["1339"] = "39", + ["1340"] = "40", + ["1341"] = "41", + ["1342"] = "42", + ["1343"] = "43", + ["1344"] = "44", + ["1345"] = "45", + ["1346"] = "46", + ["1347"] = "47", + ["1348"] = "48", + ["1349"] = "49", + ["1350"] = "50", + ["1351"] = "51", + ["1352"] = "52", + ["1353"] = "53", + ["1354"] = "54", + ["1355"] = "55", + ["1356"] = "56", + ["1357"] = "57", + ["1358"] = "58", + ["1359"] = "59", + ["1360"] = "60", + ["1361"] = "61", + ["1362"] = "62", + ["1363"] = "63", + ["1364"] = "64", + ["1365"] = "65", + ["1366"] = "66", + ["1367"] = "67", + ["1368"] = "68", + ["1369"] = "69", + ["1370"] = "70", + ["1371"] = "71", + ["1372"] = "72", + ["1373"] = "73", + ["1374"] = "74", + ["1375"] = "75", + ["1376"] = "76", + ["1377"] = "77", + ["1378"] = "78", + ["1379"] = "79", + ["1380"] = "80", + ["1381"] = "81", + ["1382"] = "82", + ["1383"] = "83", + ["1384"] = "84", + ["1385"] = "85", + ["1386"] = "86", + ["1387"] = "87", + ["1388"] = "88", + ["1389"] = "89", + ["1390"] = "90", + ["1391"] = "91", + ["1392"] = "92", + ["1393"] = "93", + ["1394"] = "94", + ["1395"] = "95", + ["1396"] = "96", + ["1397"] = "97", + ["1398"] = "98", + ["1399"] = "99", + ["1400"] = "100", + ["1401"] = "1", + ["1402"] = "2", + ["1403"] = "3", + ["1404"] = "4", + ["1405"] = "5", + ["1406"] = "6", + ["1407"] = "7", + ["1408"] = "8", + ["1409"] = "9", + ["1410"] = "10", + ["1411"] = "11", + ["1412"] = "12", + ["1413"] = "13", + ["1414"] = "14", + ["1415"] = "15", + ["1416"] = "16", + ["1417"] = "17", + ["1418"] = "18", + ["1419"] = "19", + ["1420"] = "20", + ["1421"] = "21", + ["1422"] = "22", + ["1423"] = "23", + ["1424"] = "24", + ["1425"] = "25", + ["1426"] = "26", + ["1427"] = "27", + ["1428"] = "28", + ["1429"] = "29", + ["1430"] = "30", + ["1431"] = "31", + ["1432"] = "32", + ["1433"] = "33", + ["1434"] = "34", + ["1435"] = "35", + ["1436"] = "36", + ["1437"] = "37", + ["1438"] = "38", + ["1439"] = "39", + ["1440"] = "40", + ["1441"] = "41", + ["1442"] = "42", + ["1443"] = "43", + ["1444"] = "44", + ["1445"] = "45", + ["1446"] = "46", + ["1447"] = "47", + ["1448"] = "48", + ["1449"] = "49", + ["1450"] = "50", + ["1451"] = "51", + ["1452"] = "52", + ["1453"] = "53", + ["1454"] = "54", + ["1455"] = "55", + ["1456"] = "56", + ["1457"] = "57", + ["1458"] = "58", + ["1459"] = "59", + ["1460"] = "60", + ["1461"] = "61", + ["1462"] = "62", + ["1463"] = "63", + ["1464"] = "64", + ["1465"] = "65", + ["1466"] = "66", + ["1467"] = "67", + ["1468"] = "68", + ["1469"] = "69", + ["1470"] = "70", + ["1471"] = "71", + ["1472"] = "72", + ["1473"] = "73", + ["1474"] = "74", + ["1475"] = "75", + ["1476"] = "76", + ["1477"] = "77", + ["1478"] = "78", + ["1479"] = "79", + ["1480"] = "80", + ["1481"] = "81", + ["1482"] = "82", + ["1483"] = "83", + ["1484"] = "84", + ["1485"] = "85", + ["1486"] = "86", + ["1487"] = "87", + ["1488"] = "88", + ["1489"] = "89", + ["1490"] = "90", + ["1491"] = "91", + ["1492"] = "92", + ["1493"] = "93", + ["1494"] = "94", + ["1495"] = "95", + ["1496"] = "96", + ["1497"] = "97", + ["1498"] = "98", + ["1499"] = "99", + ["1500"] = "100", + ["1501"] = "1", + ["1502"] = "2", + ["1503"] = "3", + ["1504"] = "4", + ["1505"] = "5", + ["1506"] = "6", + ["1507"] = "7", + ["1508"] = "8", + ["1509"] = "9", + ["1510"] = "10", + ["1511"] = "11", + ["1512"] = "12", + ["1513"] = "13", + ["1514"] = "14", + ["1515"] = "15", + ["1516"] = "16", + ["1517"] = "17", + ["1518"] = "18", + ["1519"] = "19", + ["1520"] = "20", + ["1521"] = "21", + ["1522"] = "22", + ["1523"] = "23", + ["1524"] = "24", + ["1525"] = "25", + ["1526"] = "26", + ["1527"] = "27", + ["1528"] = "28", + ["1529"] = "29", + ["1530"] = "30", + ["1531"] = "31", + ["1532"] = "32", + ["1533"] = "33", + ["1534"] = "34", + ["1535"] = "35", + ["1536"] = "36", + ["1537"] = "37", + ["1538"] = "38", + ["1539"] = "39", + ["1540"] = "40", + ["1541"] = "41", + ["1542"] = "42", + ["1543"] = "43", + ["1544"] = "44", + ["1545"] = "45", + ["1546"] = "46", + ["1547"] = "47", + ["1548"] = "48", + ["1549"] = "49", + ["1550"] = "50", + ["1551"] = "51", + ["1552"] = "52", + ["1553"] = "53", + ["1554"] = "54", + ["1555"] = "55", + ["1556"] = "56", + ["1557"] = "57", + ["1558"] = "58", + ["1559"] = "59", + ["1560"] = "60", + ["1561"] = "61", + ["1562"] = "62", + ["1563"] = "63", + ["1564"] = "64", + ["1565"] = "65", + ["1566"] = "66", + ["1567"] = "67", + ["1568"] = "68", + ["1569"] = "69", + ["1570"] = "70", + ["1571"] = "71", + ["1572"] = "72", + ["1573"] = "73", + ["1574"] = "74", + ["1575"] = "75", + ["1576"] = "76", + ["1577"] = "77", + ["1578"] = "78", + ["1579"] = "79", + ["1580"] = "80", + ["1581"] = "81", + ["1582"] = "82", + ["1583"] = "83", + ["1584"] = "84", + ["1585"] = "85", + ["1586"] = "86", + ["1587"] = "87", + ["1588"] = "88", + ["1589"] = "89", + ["1590"] = "90", + ["1591"] = "91", + ["1592"] = "92", + ["1593"] = "93", + ["1594"] = "94", + ["1595"] = "95", + ["1596"] = "96", + ["1597"] = "97", + ["1598"] = "98", + ["1599"] = "99", + ["1600"] = "100", + ["1601"] = "1", + ["1602"] = "2", + ["1603"] = "3", + ["1604"] = "4", + ["1605"] = "5", + ["1606"] = "6", + ["1607"] = "7", + ["1608"] = "8", + ["1609"] = "9", + ["1610"] = "10", + ["1611"] = "11", + ["1612"] = "12", + ["1613"] = "13", + ["1614"] = "14", + ["1615"] = "15", + ["1616"] = "16", + ["1617"] = "17", + ["1618"] = "18", + ["1619"] = "19", + ["1620"] = "20", + ["1621"] = "21", + ["1622"] = "22", + ["1623"] = "23", + ["1624"] = "24", + ["1625"] = "25", + ["1626"] = "26", + ["1627"] = "27", + ["1628"] = "28", + ["1629"] = "29", + ["1630"] = "30", + ["1631"] = "31", + ["1632"] = "32", + ["1633"] = "33", + ["1634"] = "34", + ["1635"] = "35", + ["1636"] = "36", + ["1637"] = "37", + ["1638"] = "38", + ["1639"] = "39", + ["1640"] = "40", + ["1641"] = "41", + ["1642"] = "42", + ["1643"] = "43", + ["1644"] = "44", + ["1645"] = "45", + ["1646"] = "46", + ["1647"] = "47", + ["1648"] = "48", + ["1649"] = "49", + ["1650"] = "50", + ["1651"] = "51", + ["1652"] = "52", + ["1653"] = "53", + ["1654"] = "54", + ["1655"] = "55", + ["1656"] = "56", + ["1657"] = "57", + ["1658"] = "58", + ["1659"] = "59", + ["1660"] = "60", + ["1661"] = "61", + ["1662"] = "62", + ["1663"] = "63", + ["1664"] = "64", + ["1665"] = "65", + ["1666"] = "66", + ["1667"] = "67", + ["1668"] = "68", + ["1669"] = "69", + ["1670"] = "70", + ["1671"] = "71", + ["1672"] = "72", + ["1673"] = "73", + ["1674"] = "74", + ["1675"] = "75", + ["1676"] = "76", + ["1677"] = "77", + ["1678"] = "78", + ["1679"] = "79", + ["1680"] = "80", + ["1681"] = "81", + ["1682"] = "82", + ["1683"] = "83", + ["1684"] = "84", + ["1685"] = "85", + ["1686"] = "86", + ["1687"] = "87", + ["1688"] = "88", + ["1689"] = "89", + ["1690"] = "90", + ["1691"] = "91", + ["1692"] = "92", + ["1693"] = "93", + ["1694"] = "94", + ["1695"] = "95", + ["1696"] = "96", + ["1697"] = "97", + ["1698"] = "98", + ["1699"] = "99", + ["1700"] = "100", + ["1701"] = "1", + ["1702"] = "2", + ["1703"] = "3", + ["1704"] = "4", + ["1705"] = "5", + ["1706"] = "6", + ["1707"] = "7", + ["1708"] = "8", + ["1709"] = "9", + ["1710"] = "10", + ["1711"] = "11", + ["1712"] = "12", + ["1713"] = "13", + ["1714"] = "14", + ["1715"] = "15", + ["1716"] = "16", + ["1717"] = "17", + ["1718"] = "18", + ["1719"] = "19", + ["1720"] = "20", + ["1721"] = "21", + ["1722"] = "22", + ["1723"] = "23", + ["1724"] = "24", + ["1725"] = "25", + ["1726"] = "26", + ["1727"] = "27", + ["1728"] = "28", + ["1729"] = "29", + ["1730"] = "30", + ["1731"] = "31", + ["1732"] = "32", + ["1733"] = "33", + ["1734"] = "34", + ["1735"] = "35", + ["1736"] = "36", + ["1737"] = "37", + ["1738"] = "38", + ["1739"] = "39", + ["1740"] = "40", + ["1741"] = "41", + ["1742"] = "42", + ["1743"] = "43", + ["1744"] = "44", + ["1745"] = "45", + ["1746"] = "46", + ["1747"] = "47", + ["1748"] = "48", + ["1749"] = "49", + ["1750"] = "50", + ["1751"] = "51", + ["1752"] = "52", + ["1753"] = "53", + ["1754"] = "54", + ["1755"] = "55", + ["1756"] = "56", + ["1757"] = "57", + ["1758"] = "58", + ["1759"] = "59", + ["1760"] = "60", + ["1761"] = "61", + ["1762"] = "62", + ["1763"] = "63", + ["1764"] = "64", + ["1765"] = "65", + ["1766"] = "66", + ["1767"] = "67", + ["1768"] = "68", + ["1769"] = "69", + ["1770"] = "70", + ["1771"] = "71", + ["1772"] = "72", + ["1773"] = "73", + ["1774"] = "74", + ["1775"] = "75", + ["1776"] = "76", + ["1777"] = "77", + ["1778"] = "78", + ["1779"] = "79", + ["1780"] = "80", + ["1781"] = "81", + ["1782"] = "82", + ["1783"] = "83", + ["1784"] = "84", + ["1785"] = "85", + ["1786"] = "86", + ["1787"] = "87", + ["1788"] = "88", + ["1789"] = "89", + ["1790"] = "90", + ["1791"] = "91", + ["1792"] = "92", + ["1793"] = "93", + ["1794"] = "94", + ["1795"] = "95", + ["1796"] = "96", + ["1797"] = "97", + ["1798"] = "98", + ["1799"] = "99", + ["1800"] = "100", + ["1801"] = "1", + ["1802"] = "2", + ["1803"] = "3", + ["1804"] = "4", + ["1805"] = "5", + ["1806"] = "6", + ["1807"] = "7", + ["1808"] = "8", + ["1809"] = "9", + ["1810"] = "10", + ["1811"] = "11", + ["1812"] = "12", + ["1813"] = "13", + ["1814"] = "14", + ["1815"] = "15", + ["1816"] = "16", + ["1817"] = "17", + ["1818"] = "18", + ["1819"] = "19", + ["1820"] = "20", + ["1821"] = "21", + ["1822"] = "22", + ["1823"] = "23", + ["1824"] = "24", + ["1825"] = "25", + ["1826"] = "26", + ["1827"] = "27", + ["1828"] = "28", + ["1829"] = "29", + ["1830"] = "30", + ["1831"] = "31", + ["1832"] = "32", + ["1833"] = "33", + ["1834"] = "34", + ["1835"] = "35", + ["1836"] = "36", + ["1837"] = "37", + ["1838"] = "38", + ["1839"] = "39", + ["1840"] = "40", + ["1841"] = "41", + ["1842"] = "42", + ["1843"] = "43", + ["1844"] = "44", + ["1845"] = "45", + ["1846"] = "46", + ["1847"] = "47", + ["1848"] = "48", + ["1849"] = "49", + ["1850"] = "50", + ["1851"] = "51", + ["1852"] = "52", + ["1853"] = "53", + ["1854"] = "54", + ["1855"] = "55", + ["1856"] = "56", + ["1857"] = "57", + ["1858"] = "58", + ["1859"] = "59", + ["1860"] = "60", + ["1861"] = "61", + ["1862"] = "62", + ["1863"] = "63", + ["1864"] = "64", + ["1865"] = "65", + ["1866"] = "66", + ["1867"] = "67", + ["1868"] = "68", + ["1869"] = "69", + ["1870"] = "70", + ["1871"] = "71", + ["1872"] = "72", + ["1873"] = "73", + ["1874"] = "74", + ["1875"] = "75", + ["1876"] = "76", + ["1877"] = "77", + ["1878"] = "78", + ["1879"] = "79", + ["1880"] = "80", + ["1881"] = "81", + ["1882"] = "82", + ["1883"] = "83", + ["1884"] = "84", + ["1885"] = "85", + ["1886"] = "86", + ["1887"] = "87", + ["1888"] = "88", + ["1889"] = "89", + ["1890"] = "90", + ["1891"] = "91", + ["1892"] = "92", + ["1893"] = "93", + ["1894"] = "94", + ["1895"] = "95", + ["1896"] = "96", + ["1897"] = "97", + ["1898"] = "98", + ["1899"] = "99", + ["1900"] = "100", + ["1901"] = "1", + ["1902"] = "2", + ["1903"] = "3", + ["1904"] = "4", + ["1905"] = "5", + ["1906"] = "6", + ["1907"] = "7", + ["1908"] = "8", + ["1909"] = "9", + ["1910"] = "10", + ["1911"] = "11", + ["1912"] = "12", + ["1913"] = "13", + ["1914"] = "14", + ["1915"] = "15", + ["1916"] = "16", + ["1917"] = "17", + ["1918"] = "18", + ["1919"] = "19", + ["1920"] = "20", + ["1921"] = "21", + ["1922"] = "22", + ["1923"] = "23", + ["1924"] = "24", + ["1925"] = "25", + ["1926"] = "26", + ["1927"] = "27", + ["1928"] = "28", + ["1929"] = "29", + ["1930"] = "30", + ["1931"] = "31", + ["1932"] = "32", + ["1933"] = "33", + ["1934"] = "34", + ["1935"] = "35", + ["1936"] = "36", + ["1937"] = "37", + ["1938"] = "38", + ["1939"] = "39", + ["1940"] = "40", + ["1941"] = "41", + ["1942"] = "42", + ["1943"] = "43", + ["1944"] = "44", + ["1945"] = "45", + ["1946"] = "46", + ["1947"] = "47", + ["1948"] = "48", + ["1949"] = "49", + ["1950"] = "50", + ["1951"] = "51", + ["1952"] = "52", + ["1953"] = "53", + ["1954"] = "54", + ["1955"] = "55", + ["1956"] = "56", + ["1957"] = "57", + ["1958"] = "58", + ["1959"] = "59", + ["1960"] = "60", + ["1961"] = "61", + ["1962"] = "62", + ["1963"] = "63", + ["1964"] = "64", + ["1965"] = "65", + ["1966"] = "66", + ["1967"] = "67", + ["1968"] = "68", + ["1969"] = "69", + ["1970"] = "70", + ["1971"] = "71", + ["1972"] = "72", + ["1973"] = "73", + ["1974"] = "74", + ["1975"] = "75", + ["1976"] = "76", + ["1977"] = "77", + ["1978"] = "78", + ["1979"] = "79", + ["1980"] = "80", + ["1981"] = "81", + ["1982"] = "82", + ["1983"] = "83", + ["1984"] = "84", + ["1985"] = "85", + ["1986"] = "86", + ["1987"] = "87", + ["1988"] = "88", + ["1989"] = "89", + ["1990"] = "90", + ["1991"] = "91", + ["1992"] = "92", + ["1993"] = "93", + ["1994"] = "94", + ["1995"] = "95", + ["1996"] = "96", + ["1997"] = "97", + ["1998"] = "98", + ["1999"] = "99", + ["2000"] = "99", + ["2001"] = "1", + ["2002"] = "2", + ["2003"] = "3", + ["2004"] = "4", + ["2005"] = "5", + ["2006"] = "6", + ["2007"] = "7", + ["2008"] = "8", + ["2009"] = "9", + ["2000"] = "10", + ["2011"] = "11", + ["2012"] = "12", + ["2013"] = "13", + ["2014"] = "14", + ["2015"] = "15", + ["2016"] = "16", + ["2017"] = "17", + ["2018"] = "18", + ["2019"] = "19", + ["2020"] = "20", + ["2021"] = "21", + ["2022"] = "22", + ["2023"] = "23", + ["2024"] = "24", + ["2025"] = "25", + ["2026"] = "26", + ["2027"] = "27", + ["2028"] = "28", + ["2029"] = "29", + ["2030"] = "30", + ["2031"] = "31", + ["2032"] = "32", + ["2033"] = "33", + ["2034"] = "34", + ["2035"] = "35", + ["2036"] = "36", + ["2037"] = "37", + ["2038"] = "38", + ["2039"] = "39", + ["2040"] = "40", + ["2041"] = "41", + ["2042"] = "42", + ["2043"] = "43", + ["2044"] = "44", + ["2045"] = "45", + ["2046"] = "46", + ["2047"] = "47", + ["2048"] = "48", + ["2049"] = "49", + ["2050"] = "50", + ["2051"] = "51", + ["2052"] = "52", + ["2053"] = "53", + ["2054"] = "54", + ["2055"] = "55", + ["2056"] = "56", + ["2057"] = "57", + ["2058"] = "58", + ["2059"] = "59", + ["2060"] = "60", + ["2061"] = "61", + ["2062"] = "62", + ["2063"] = "63", + ["2064"] = "64", + ["2065"] = "65", + ["2066"] = "66", + ["2067"] = "67", + ["2068"] = "68", + ["2069"] = "69", + ["2070"] = "70", + ["2071"] = "71", + ["2072"] = "72", + ["2073"] = "73", + ["2074"] = "74", + ["2075"] = "75", + ["2076"] = "76", + ["2077"] = "77", + ["2078"] = "78", + ["2079"] = "79", + ["2080"] = "80", + ["2081"] = "81", + ["2082"] = "82", + ["2083"] = "83", + ["2084"] = "84", + ["2085"] = "85", + ["2086"] = "86", + ["2087"] = "87", + ["2088"] = "88", + ["2089"] = "89", + ["2090"] = "90", + ["2091"] = "91", + ["2092"] = "92", + ["2093"] = "93", + ["2094"] = "94", + ["2095"] = "95", + ["2096"] = "96", + ["2097"] = "97", + ["2098"] = "98", + ["2099"] = "99", + ["2100"] = "100", + ["2101"] = "1", + ["2102"] = "2", + ["2103"] = "3", + ["2104"] = "4", + ["2105"] = "5", + ["2106"] = "6", + ["2107"] = "7", + ["2108"] = "8", + ["2109"] = "9", + ["2110"] = "10", + ["2111"] = "11", + ["2112"] = "12", + ["2113"] = "13", + ["2114"] = "14", + ["2115"] = "15", + ["2116"] = "16", + ["2117"] = "17", + ["2118"] = "18", + ["2119"] = "19", + ["2120"] = "20", + ["2121"] = "21", + ["2122"] = "22", + ["2123"] = "23", + ["2124"] = "24", + ["2125"] = "25", + ["2126"] = "26", + ["2127"] = "27", + ["2128"] = "28", + ["2129"] = "29", + ["2130"] = "30", + ["2131"] = "31", + ["2132"] = "32", + ["2133"] = "33", + ["2134"] = "34", + ["2135"] = "35", + ["2136"] = "36", + ["2137"] = "37", + ["2138"] = "38", + ["2139"] = "39", + ["2140"] = "40", + ["2141"] = "41", + ["2142"] = "42", + ["2143"] = "43", + ["2144"] = "44", + ["2145"] = "45", + ["2146"] = "46", + ["2147"] = "47", + ["2148"] = "48", + ["2149"] = "49", + ["2150"] = "50", + ["2151"] = "51", + ["2152"] = "52", + ["2153"] = "53", + ["2154"] = "54", + ["2155"] = "55", + ["2156"] = "56", + ["2157"] = "57", + ["2158"] = "58", + ["2159"] = "59", + ["2160"] = "60", + ["2161"] = "61", + ["2162"] = "62", + ["2163"] = "63", + ["2164"] = "64", + ["2165"] = "65", + ["2166"] = "66", + ["2167"] = "67", + ["2168"] = "68", + ["2169"] = "69", + ["2170"] = "70", + ["2171"] = "71", + ["2172"] = "72", + ["2173"] = "73", + ["2174"] = "74", + ["2175"] = "75", + ["2176"] = "76", + ["2177"] = "77", + ["2178"] = "78", + ["2179"] = "79", + ["2180"] = "80", + ["2181"] = "81", + ["2182"] = "82", + ["2183"] = "83", + ["2184"] = "84", + ["2185"] = "85", + ["2186"] = "86", + ["2187"] = "87", + ["2188"] = "88", + ["2189"] = "89", + ["2190"] = "90", + ["2191"] = "91", + ["2192"] = "92", + ["2193"] = "93", + ["2194"] = "94", + ["2195"] = "95", + ["2196"] = "96", + ["2197"] = "97", + ["2198"] = "98", + ["2199"] = "99", + ["2200"] = "100", + ["2201"] = "1", + ["2202"] = "2", + ["2203"] = "3", + ["2204"] = "4", + ["2205"] = "5", + ["2206"] = "6", + ["2207"] = "7", + ["2208"] = "8", + ["2209"] = "9", + ["2210"] = "10", + ["2211"] = "11", + ["2212"] = "12", + ["2213"] = "13", + ["2214"] = "14", + ["2215"] = "15", + ["2216"] = "16", + ["2217"] = "17", + ["2218"] = "18", + ["2219"] = "19", + ["2220"] = "20", + ["2221"] = "21", + ["2222"] = "22", + ["2223"] = "23", + ["2224"] = "24", + ["2225"] = "25", + ["2226"] = "26", + ["2227"] = "27", + ["2228"] = "28", + ["2229"] = "29", + ["2230"] = "30", + ["2231"] = "31", + ["2232"] = "32", + ["2233"] = "33", + ["2234"] = "34", + ["2235"] = "35", + ["2236"] = "36", + ["2237"] = "37", + ["2238"] = "38", + ["2239"] = "39", + ["2240"] = "40", + ["2241"] = "41", + ["2242"] = "42", + ["2243"] = "43", + ["2244"] = "44", + ["2245"] = "45", + ["2246"] = "46", + ["2247"] = "47", + ["2248"] = "48", + ["2249"] = "49", + ["2250"] = "50", + ["2251"] = "51", + ["2252"] = "52", + ["2253"] = "53", + ["2254"] = "54", + ["2255"] = "55", + ["2256"] = "56", + ["2257"] = "57", + ["2258"] = "58", + ["2259"] = "59", + ["2260"] = "60", + ["2261"] = "61", + ["2262"] = "62", + ["2263"] = "63", + ["2264"] = "64", + ["2265"] = "65", + ["2266"] = "66", + ["2267"] = "67", + ["2268"] = "68", + ["2269"] = "69", + ["2270"] = "70", + ["2271"] = "71", + ["2272"] = "72", + ["2273"] = "73", + ["2274"] = "74", + ["2275"] = "75", + ["2276"] = "76", + ["2277"] = "77", + ["2278"] = "78", + ["2279"] = "79", + ["2280"] = "80", + ["2281"] = "81", + ["2282"] = "82", + ["2283"] = "83", + ["2284"] = "84", + ["2285"] = "85", + ["2286"] = "86", + ["2287"] = "87", + ["2288"] = "88", + ["2289"] = "89", + ["2290"] = "90", + ["2291"] = "91", + ["2292"] = "92", + ["2293"] = "93", + ["2294"] = "94", + ["2295"] = "95", + ["2296"] = "96", + ["2297"] = "97", + ["2298"] = "98", + ["2299"] = "99", + ["2300"] = "100", + ["2301"] = "1", + ["2302"] = "2", + ["2303"] = "3", + ["2304"] = "4", + ["2305"] = "5", + ["2306"] = "6", + ["2307"] = "7", + ["2308"] = "8", + ["2309"] = "9", + ["2310"] = "10", + ["2311"] = "11", + ["2312"] = "12", + ["2313"] = "13", + ["2314"] = "14", + ["2315"] = "15", + ["2316"] = "16", + ["2317"] = "17", + ["2318"] = "18", + ["2319"] = "19", + ["2320"] = "20", + ["2321"] = "21", + ["2322"] = "22", + ["2323"] = "23", + ["2324"] = "24", + ["2325"] = "25", + ["2326"] = "26", + ["2327"] = "27", + ["2328"] = "28", + ["2329"] = "29", + ["2330"] = "30", + ["2331"] = "31", + ["2332"] = "32", + ["2333"] = "33", + ["2334"] = "34", + ["2335"] = "35", + ["2336"] = "36", + ["2337"] = "37", + ["2338"] = "38", + ["2339"] = "39", + ["2340"] = "40", + ["2341"] = "41", + ["2342"] = "42", + ["2343"] = "43", + ["2344"] = "44", + ["2345"] = "45", + ["2346"] = "46", + ["2347"] = "47", + ["2348"] = "48", + ["2349"] = "49", + ["2350"] = "50", + ["2351"] = "51", + ["2352"] = "52", + ["2353"] = "53", + ["2354"] = "54", + ["2355"] = "55", + ["2356"] = "56", + ["2357"] = "57", + ["2358"] = "58", + ["2359"] = "59", + ["2360"] = "60", + ["2361"] = "61", + ["2362"] = "62", + ["2363"] = "63", + ["2364"] = "64", + ["2365"] = "65", + ["2366"] = "66", + ["2367"] = "67", + ["2368"] = "68", + ["2369"] = "69", + ["2370"] = "70", + ["2371"] = "71", + ["2372"] = "72", + ["2373"] = "73", + ["2374"] = "74", + ["2375"] = "75", + ["2376"] = "76", + ["2377"] = "77", + ["2378"] = "78", + ["2379"] = "79", + ["2380"] = "80", + ["2381"] = "81", + ["2382"] = "82", + ["2383"] = "83", + ["2384"] = "84", + ["2385"] = "85", + ["2386"] = "86", + ["2387"] = "87", + ["2388"] = "88", + ["2389"] = "89", + ["2390"] = "90", + ["2391"] = "91", + ["2392"] = "92", + ["2393"] = "93", + ["2394"] = "94", + ["2395"] = "95", + ["2396"] = "96", + ["2397"] = "97", + ["2398"] = "98", + ["2399"] = "99", + ["2400"] = "100", + ["2401"] = "1", + ["2402"] = "2", + ["2403"] = "3", + ["2404"] = "4", + ["2405"] = "5", + ["2406"] = "6", + ["2407"] = "7", + ["2408"] = "8", + ["2409"] = "9", + ["2410"] = "10", + ["2411"] = "11", + ["2412"] = "12", + ["2413"] = "13", + ["2414"] = "14", + ["2415"] = "15", + ["2416"] = "16", + ["2417"] = "17", + ["2418"] = "18", + ["2419"] = "19", + ["2420"] = "20", + ["2421"] = "21", + ["2422"] = "22", + ["2423"] = "23", + ["2424"] = "24", + ["2425"] = "25", + ["2426"] = "26", + ["2427"] = "27", + ["2428"] = "28", + ["2429"] = "29", + ["2430"] = "30", + ["2431"] = "31", + ["2432"] = "32", + ["2433"] = "33", + ["2434"] = "34", + ["2435"] = "35", + ["2436"] = "36", + ["2437"] = "37", + ["2438"] = "38", + ["2439"] = "39", + ["2440"] = "40", + ["2441"] = "41", + ["2442"] = "42", + ["2443"] = "43", + ["2444"] = "44", + ["2445"] = "45", + ["2446"] = "46", + ["2447"] = "47", + ["2448"] = "48", + ["2449"] = "49", + ["2450"] = "50", + ["2451"] = "51", + ["2452"] = "52", + ["2453"] = "53", + ["2454"] = "54", + ["2455"] = "55", + ["2456"] = "56", + ["2457"] = "57", + ["2458"] = "58", + ["2459"] = "59", + ["2460"] = "60", + ["2461"] = "61", + ["2462"] = "62", + ["2463"] = "63", + ["2464"] = "64", + ["2465"] = "65", + ["2466"] = "66", + ["2467"] = "67", + ["2468"] = "68", + ["2469"] = "69", + ["2470"] = "70", + ["2471"] = "71", + ["2472"] = "72", + ["2473"] = "73", + ["2474"] = "74", + ["2475"] = "75", + ["2476"] = "76", + ["2477"] = "77", + ["2478"] = "78", + ["2479"] = "79", + ["2480"] = "80", + ["2481"] = "81", + ["2482"] = "82", + ["2483"] = "83", + ["2484"] = "84", + ["2485"] = "85", + ["2486"] = "86", + ["2487"] = "87", + ["2488"] = "88", + ["2489"] = "89", + ["2490"] = "90", + ["2491"] = "91", + ["2492"] = "92", + ["2493"] = "93", + ["2494"] = "94", + ["2495"] = "95", + ["2496"] = "96", + ["2497"] = "97", + ["2498"] = "98", + ["2499"] = "99", + ["2500"] = "100", + ["2501"] = "1", + ["2502"] = "2", + ["2503"] = "3", + ["2504"] = "4", + ["2505"] = "5", + ["2506"] = "6", + ["2507"] = "7", + ["2508"] = "8", + ["2509"] = "9", + ["2510"] = "10", + ["2511"] = "11", + ["2512"] = "12", + ["2513"] = "13", + ["2514"] = "14", + ["2515"] = "15", + ["2516"] = "16", + ["2517"] = "17", + ["2518"] = "18", + ["2519"] = "19", + ["2520"] = "20", + ["2521"] = "21", + ["2522"] = "22", + ["2523"] = "23", + ["2524"] = "24", + ["2525"] = "25", + ["2526"] = "26", + ["2527"] = "27", + ["2528"] = "28", + ["2529"] = "29", + ["2530"] = "30", + ["2531"] = "31", + ["2532"] = "32", + ["2533"] = "33", + ["2534"] = "34", + ["2535"] = "35", + ["2536"] = "36", + ["2537"] = "37", + ["2538"] = "38", + ["2539"] = "39", + ["2540"] = "40", + ["2541"] = "41", + ["2542"] = "42", + ["2543"] = "43", + ["2544"] = "44", + ["2545"] = "45", + ["2546"] = "46", + ["2547"] = "47", + ["2548"] = "48", + ["2549"] = "49", + ["2550"] = "50", + ["2551"] = "51", + ["2552"] = "52", + ["2553"] = "53", + ["2554"] = "54", + ["2555"] = "55", + ["2556"] = "56", + ["2557"] = "57", + ["2558"] = "58", + ["2559"] = "59", + ["2560"] = "60", + ["2561"] = "61", + ["2562"] = "62", + ["2563"] = "63", + ["2564"] = "64", + ["2565"] = "65", + ["2566"] = "66", + ["2567"] = "67", + ["2568"] = "68", + ["2569"] = "69", + ["2570"] = "70", + ["2571"] = "71", + ["2572"] = "72", + ["2573"] = "73", + ["2574"] = "74", + ["2575"] = "75", + ["2576"] = "76", + ["2577"] = "77", + ["2578"] = "78", + ["2579"] = "79", + ["2580"] = "80", + ["2581"] = "81", + ["2582"] = "82", + ["2583"] = "83", + ["2584"] = "84", + ["2585"] = "85", + ["2586"] = "86", + ["2587"] = "87", + ["2588"] = "88", + ["2589"] = "89", + ["2590"] = "90", + ["2591"] = "91", + ["2592"] = "92", + ["2593"] = "93", + ["2594"] = "94", + ["2595"] = "95", + ["2596"] = "96", + ["2597"] = "97", + ["2598"] = "98", + ["2599"] = "99", + ["2600"] = "100", + ["2601"] = "1", + ["2602"] = "2", + ["2603"] = "3", + ["2604"] = "4", + ["2605"] = "5", + ["2606"] = "6", + ["2607"] = "7", + ["2608"] = "8", + ["2609"] = "9", + ["2610"] = "10", + ["2611"] = "11", + ["2612"] = "12", + ["2613"] = "13", + ["2614"] = "14", + ["2615"] = "15", + ["2616"] = "16", + ["2617"] = "17", + ["2618"] = "18", + ["2619"] = "19", + ["2620"] = "20", + ["2621"] = "21", + ["2622"] = "22", + ["2623"] = "23", + ["2624"] = "24", + ["2625"] = "25", + ["2626"] = "26", + ["2627"] = "27", + ["2628"] = "28", + ["2629"] = "29", + ["2630"] = "30", + ["2631"] = "31", + ["2632"] = "32", + ["2633"] = "33", + ["2634"] = "34", + ["2635"] = "35", + ["2636"] = "36", + ["2637"] = "37", + ["2638"] = "38", + ["2639"] = "39", + ["2640"] = "40", + ["2641"] = "41", + ["2642"] = "42", + ["2643"] = "43", + ["2644"] = "44", + ["2645"] = "45", + ["2646"] = "46", + ["2647"] = "47", + ["2648"] = "48", + ["2649"] = "49", + ["2650"] = "50", + ["2651"] = "51", + ["2652"] = "52", + ["2653"] = "53", + ["2654"] = "54", + ["2655"] = "55", + ["2656"] = "56", + ["2657"] = "57", + ["2658"] = "58", + ["2659"] = "59", + ["2660"] = "60", + ["2661"] = "61", + ["2662"] = "62", + ["2663"] = "63", + ["2664"] = "64", + ["2665"] = "65", + ["2666"] = "66", + ["2667"] = "67", + ["2668"] = "68", + ["2669"] = "69", + ["2670"] = "70", + ["2671"] = "71", + ["2672"] = "72", + ["2673"] = "73", + ["2674"] = "74", + ["2675"] = "75", + ["2676"] = "76", + ["2677"] = "77", + ["2678"] = "78", + ["2679"] = "79", + ["2680"] = "80", + ["2681"] = "81", + ["2682"] = "82", + ["2683"] = "83", + ["2684"] = "84", + ["2685"] = "85", + ["2686"] = "86", + ["2687"] = "87", + ["2688"] = "88", + ["2689"] = "89", + ["2690"] = "90", + ["2691"] = "91", + ["2692"] = "92", + ["2693"] = "93", + ["2694"] = "94", + ["2695"] = "95", + ["2696"] = "96", + ["2697"] = "97", + ["2698"] = "98", + ["2699"] = "99", + ["2700"] = "100", + ["2701"] = "1", + ["2702"] = "2", + ["2703"] = "3", + ["2704"] = "4", + ["2705"] = "5", + ["2706"] = "6", + ["2707"] = "7", + ["2708"] = "8", + ["2709"] = "9", + ["2710"] = "10", + ["2711"] = "11", + ["2712"] = "12", + ["2713"] = "13", + ["2714"] = "14", + ["2715"] = "15", + ["2716"] = "16", + ["2717"] = "17", + ["2718"] = "18", + ["2719"] = "19", + ["2720"] = "20", + ["2721"] = "21", + ["2722"] = "22", + ["2723"] = "23", + ["2724"] = "24", + ["2725"] = "25", + ["2726"] = "26", + ["2727"] = "27", + ["2728"] = "28", + ["2729"] = "29", + ["2730"] = "30", + ["2731"] = "31", + ["2732"] = "32", + ["2733"] = "33", + ["2734"] = "34", + ["2735"] = "35", + ["2736"] = "36", + ["2737"] = "37", + ["2738"] = "38", + ["2739"] = "39", + ["2740"] = "40", + ["2741"] = "41", + ["2742"] = "42", + ["2743"] = "43", + ["2744"] = "44", + ["2745"] = "45", + ["2746"] = "46", + ["2747"] = "47", + ["2748"] = "48", + ["2749"] = "49", + ["2750"] = "50", + ["2751"] = "51", + ["2752"] = "52", + ["2753"] = "53", + ["2754"] = "54", + ["2755"] = "55", + ["2756"] = "56", + ["2757"] = "57", + ["2758"] = "58", + ["2759"] = "59", + ["2760"] = "60", + ["2761"] = "61", + ["2762"] = "62", + ["2763"] = "63", + ["2764"] = "64", + ["2765"] = "65", + ["2766"] = "66", + ["2767"] = "67", + ["2768"] = "68", + ["2769"] = "69", + ["2770"] = "70", + ["2771"] = "71", + ["2772"] = "72", + ["2773"] = "73", + ["2774"] = "74", + ["2775"] = "75", + ["2776"] = "76", + ["2777"] = "77", + ["2778"] = "78", + ["2779"] = "79", + ["2780"] = "80", + ["2781"] = "81", + ["2782"] = "82", + ["2783"] = "83", + ["2784"] = "84", + ["2785"] = "85", + ["2786"] = "86", + ["2787"] = "87", + ["2788"] = "88", + ["2789"] = "89", + ["2790"] = "90", + ["2791"] = "91", + ["2792"] = "92", + ["2793"] = "93", + ["2794"] = "94", + ["2795"] = "95", + ["2796"] = "96", + ["2797"] = "97", + ["2798"] = "98", + ["2799"] = "99", + ["2800"] = "100", + ["2801"] = "1", + ["2802"] = "2", + ["2803"] = "3", + ["2804"] = "4", + ["2805"] = "5", + ["2806"] = "6", + ["2807"] = "7", + ["2808"] = "8", + ["2809"] = "9", + ["2810"] = "10", + ["2811"] = "11", + ["2812"] = "12", + ["2813"] = "13", + ["2814"] = "14", + ["2815"] = "15", + ["2816"] = "16", + ["2817"] = "17", + ["2818"] = "18", + ["2819"] = "19", + ["2820"] = "20", + ["2821"] = "21", + ["2822"] = "22", + ["2823"] = "23", + ["2824"] = "24", + ["2825"] = "25", + ["2826"] = "26", + ["2827"] = "27", + ["2828"] = "28", + ["2829"] = "29", + ["2830"] = "30", + ["2831"] = "31", + ["2832"] = "32", + ["2833"] = "33", + ["2834"] = "34", + ["2835"] = "35", + ["2836"] = "36", + ["2837"] = "37", + ["2838"] = "38", + ["2839"] = "39", + ["2840"] = "40", + ["2841"] = "41", + ["2842"] = "42", + ["2843"] = "43", + ["2844"] = "44", + ["2845"] = "45", + ["2846"] = "46", + ["2847"] = "47", + ["2848"] = "48", + ["2849"] = "49", + ["2850"] = "50", + ["2851"] = "51", + ["2852"] = "52", + ["2853"] = "53", + ["2854"] = "54", + ["2855"] = "55", + ["2856"] = "56", + ["2857"] = "57", + ["2858"] = "58", + ["2859"] = "59", + ["2860"] = "60", + ["2861"] = "61", + ["2862"] = "62", + ["2863"] = "63", + ["2864"] = "64", + ["2865"] = "65", + ["2866"] = "66", + ["2867"] = "67", + ["2868"] = "68", + ["2869"] = "69", + ["2870"] = "70", + ["2871"] = "71", + ["2872"] = "72", + ["2873"] = "73", + ["2874"] = "74", + ["2875"] = "75", + ["2876"] = "76", + ["2877"] = "77", + ["2878"] = "78", + ["2879"] = "79", + ["2880"] = "80", + ["2881"] = "81", + ["2882"] = "82", + ["2883"] = "83", + ["2884"] = "84", + ["2885"] = "85", + ["2886"] = "86", + ["2887"] = "87", + ["2888"] = "88", + ["2889"] = "89", + ["2890"] = "90", + ["2891"] = "91", + ["2892"] = "92", + ["2893"] = "93", + ["2894"] = "94", + ["2895"] = "95", + ["2896"] = "96", + ["2897"] = "97", + ["2898"] = "98", + ["2899"] = "99", + ["2900"] = "100", + ["2901"] = "1", + ["2902"] = "2", + ["2903"] = "3", + ["2904"] = "4", + ["2905"] = "5", + ["2906"] = "6", + ["2907"] = "7", + ["2908"] = "8", + ["2909"] = "9", + ["2910"] = "10", + ["2911"] = "11", + ["2912"] = "12", + ["2913"] = "13", + ["2914"] = "14", + ["2915"] = "15", + ["2916"] = "16", + ["2917"] = "17", + ["2918"] = "18", + ["2919"] = "19", + ["2920"] = "20", + ["2921"] = "21", + ["2922"] = "22", + ["2923"] = "23", + ["2924"] = "24", + ["2925"] = "25", + ["2926"] = "26", + ["2927"] = "27", + ["2928"] = "28", + ["2929"] = "29", + ["2930"] = "30", + ["2931"] = "31", + ["2932"] = "32", + ["2933"] = "33", + ["2934"] = "34", + ["2935"] = "35", + ["2936"] = "36", + ["2937"] = "37", + ["2938"] = "38", + ["2939"] = "39", + ["2940"] = "40", + ["2941"] = "41", + ["2942"] = "42", + ["2943"] = "43", + ["2944"] = "44", + ["2945"] = "45", + ["2946"] = "46", + ["2947"] = "47", + ["2948"] = "48", + ["2949"] = "49", + ["2950"] = "50", + ["2951"] = "51", + ["2952"] = "52", + ["2953"] = "53", + ["2954"] = "54", + ["2955"] = "55", + ["2956"] = "56", + ["2957"] = "57", + ["2958"] = "58", + ["2959"] = "59", + ["2960"] = "60", + ["2961"] = "61", + ["2962"] = "62", + ["2963"] = "63", + ["2964"] = "64", + ["2965"] = "65", + ["2966"] = "66", + ["2967"] = "67", + ["2968"] = "68", + ["2969"] = "69", + ["2970"] = "70", + ["2971"] = "71", + ["2972"] = "72", + ["2973"] = "73", + ["2974"] = "74", + ["2975"] = "75", + ["2976"] = "76", + ["2977"] = "77", + ["2978"] = "78", + ["2979"] = "79", + ["2980"] = "80", + ["2981"] = "81", + ["2982"] = "82", + ["2983"] = "83", + ["2984"] = "84", + ["2985"] = "85", + ["2986"] = "86", + ["2987"] = "87", + ["2988"] = "88", + ["2989"] = "89", + ["2990"] = "90", + ["2991"] = "91", + ["2992"] = "92", + ["2993"] = "93", + ["2994"] = "94", + ["2995"] = "95", + ["2996"] = "96", + ["2997"] = "97", + ["2998"] = "98", + ["2999"] = "99", + ["3000"] = "99", + ["3001"] = "1", + ["3002"] = "2", + ["3003"] = "3", + ["3004"] = "4", + ["3005"] = "5", + ["3006"] = "6", + ["3007"] = "7", + ["3008"] = "8", + ["3009"] = "9", + ["3000"] = "10", + ["3011"] = "11", + ["3012"] = "12", + ["3013"] = "13", + ["3014"] = "14", + ["3015"] = "15", + ["3016"] = "16", + ["3017"] = "17", + ["3018"] = "18", + ["3019"] = "19", + ["3020"] = "20", + ["3021"] = "21", + ["3022"] = "22", + ["3023"] = "23", + ["3024"] = "24", + ["3025"] = "25", + ["3026"] = "26", + ["3027"] = "27", + ["3028"] = "28", + ["3029"] = "29", + ["3030"] = "30", + ["3031"] = "31", + ["3032"] = "32", + ["3033"] = "33", + ["3034"] = "34", + ["3035"] = "35", + ["3036"] = "36", + ["3037"] = "37", + ["3038"] = "38", + ["3039"] = "39", + ["3040"] = "40", + ["3041"] = "41", + ["3042"] = "42", + ["3043"] = "43", + ["3044"] = "44", + ["3045"] = "45", + ["3046"] = "46", + ["3047"] = "47", + ["3048"] = "48", + ["3049"] = "49", + ["3050"] = "50", + ["3051"] = "51", + ["3052"] = "52", + ["3053"] = "53", + ["3054"] = "54", + ["3055"] = "55", + ["3056"] = "56", + ["3057"] = "57", + ["3058"] = "58", + ["3059"] = "59", + ["3060"] = "60", + ["3061"] = "61", + ["3062"] = "62", + ["3063"] = "63", + ["3064"] = "64", + ["3065"] = "65", + ["3066"] = "66", + ["3067"] = "67", + ["3068"] = "68", + ["3069"] = "69", + ["3070"] = "70", + ["3071"] = "71", + ["3072"] = "72", + ["3073"] = "73", + ["3074"] = "74", + ["3075"] = "75", + ["3076"] = "76", + ["3077"] = "77", + ["3078"] = "78", + ["3079"] = "79", + ["3080"] = "80", + ["3081"] = "81", + ["3082"] = "82", + ["3083"] = "83", + ["3084"] = "84", + ["3085"] = "85", + ["3086"] = "86", + ["3087"] = "87", + ["3088"] = "88", + ["3089"] = "89", + ["3090"] = "90", + ["3091"] = "91", + ["3092"] = "92", + ["3093"] = "93", + ["3094"] = "94", + ["3095"] = "95", + ["3096"] = "96", + ["3097"] = "97", + ["3098"] = "98", + ["3099"] = "99", + ["3100"] = "100", + ["3101"] = "1", + ["3102"] = "2", + ["3103"] = "3", + ["3104"] = "4", + ["3105"] = "5", + ["3106"] = "6", + ["3107"] = "7", + ["3108"] = "8", + ["3109"] = "9", + ["3110"] = "10", + ["3111"] = "11", + ["3112"] = "12", + ["3113"] = "13", + ["3114"] = "14", + ["3115"] = "15", + ["3116"] = "16", + ["3117"] = "17", + ["3118"] = "18", + ["3119"] = "19", + ["3120"] = "20", + ["3121"] = "21", + ["3122"] = "22", + ["3123"] = "23", + ["3124"] = "24", + ["3125"] = "25", + ["3126"] = "26", + ["3127"] = "27", + ["3128"] = "28", + ["3129"] = "29", + ["3130"] = "30", + ["3131"] = "31", + ["3132"] = "32", + ["3133"] = "33", + ["3134"] = "34", + ["3135"] = "35", + ["3136"] = "36", + ["3137"] = "37", + ["3138"] = "38", + ["3139"] = "39", + ["3140"] = "40", + ["3141"] = "41", + ["3142"] = "42", + ["3143"] = "43", + ["3144"] = "44", + ["3145"] = "45", + ["3146"] = "46", + ["3147"] = "47", + ["3148"] = "48", + ["3149"] = "49", + ["3150"] = "50", + ["3151"] = "51", + ["3152"] = "52", + ["3153"] = "53", + ["3154"] = "54", + ["3155"] = "55", + ["3156"] = "56", + ["3157"] = "57", + ["3158"] = "58", + ["3159"] = "59", + ["3160"] = "60", + ["3161"] = "61", + ["3162"] = "62", + ["3163"] = "63", + ["3164"] = "64", + ["3165"] = "65", + ["3166"] = "66", + ["3167"] = "67", + ["3168"] = "68", + ["3169"] = "69", + ["3170"] = "70", + ["3171"] = "71", + ["3172"] = "72", + ["3173"] = "73", + ["3174"] = "74", + ["3175"] = "75", + ["3176"] = "76", + ["3177"] = "77", + ["3178"] = "78", + ["3179"] = "79", + ["3180"] = "80", + ["3181"] = "81", + ["3182"] = "82", + ["3183"] = "83", + ["3184"] = "84", + ["3185"] = "85", + ["3186"] = "86", + ["3187"] = "87", + ["3188"] = "88", + ["3189"] = "89", + ["3190"] = "90", + ["3191"] = "91", + ["3192"] = "92", + ["3193"] = "93", + ["3194"] = "94", + ["3195"] = "95", + ["3196"] = "96", + ["3197"] = "97", + ["3198"] = "98", + ["3199"] = "99", + ["3200"] = "100", + ["3201"] = "1", + ["3202"] = "2", + ["3203"] = "3", + ["3204"] = "4", + ["3205"] = "5", + ["3206"] = "6", + ["3207"] = "7", + ["3208"] = "8", + ["3209"] = "9", + ["3210"] = "10", + ["3211"] = "11", + ["3212"] = "12", + ["3213"] = "13", + ["3214"] = "14", + ["3215"] = "15", + ["3216"] = "16", + ["3217"] = "17", + ["3218"] = "18", + ["3219"] = "19", + ["3220"] = "20", + ["3221"] = "21", + ["3222"] = "22", + ["3223"] = "23", + ["3224"] = "24", + ["3225"] = "25", + ["3226"] = "26", + ["3227"] = "27", + ["3228"] = "28", + ["3229"] = "29", + ["3230"] = "30", + ["3231"] = "31", + ["3232"] = "32", + ["3233"] = "33", + ["3234"] = "34", + ["3235"] = "35", + ["3236"] = "36", + ["3237"] = "37", + ["3238"] = "38", + ["3239"] = "39", + ["3240"] = "40", + ["3241"] = "41", + ["3242"] = "42", + ["3243"] = "43", + ["3244"] = "44", + ["3245"] = "45", + ["3246"] = "46", + ["3247"] = "47", + ["3248"] = "48", + ["3249"] = "49", + ["3250"] = "50", + ["3251"] = "51", + ["3252"] = "52", + ["3253"] = "53", + ["3254"] = "54", + ["3255"] = "55", + ["3256"] = "56", + ["3257"] = "57", + ["3258"] = "58", + ["3259"] = "59", + ["3260"] = "60", + ["3261"] = "61", + ["3262"] = "62", + ["3263"] = "63", + ["3264"] = "64", + ["3265"] = "65", + ["3266"] = "66", + ["3267"] = "67", + ["3268"] = "68", + ["3269"] = "69", + ["3270"] = "70", + ["3271"] = "71", + ["3272"] = "72", + ["3273"] = "73", + ["3274"] = "74", + ["3275"] = "75", + ["3276"] = "76", + ["3277"] = "77", + ["3278"] = "78", + ["3279"] = "79", + ["3280"] = "80", + ["3281"] = "81", + ["3282"] = "82", + ["3283"] = "83", + ["3284"] = "84", + ["3285"] = "85", + ["3286"] = "86", + ["3287"] = "87", + ["3288"] = "88", + ["3289"] = "89", + ["3290"] = "90", + ["3291"] = "91", + ["3292"] = "92", + ["3293"] = "93", + ["3294"] = "94", + ["3295"] = "95", + ["3296"] = "96", + ["3297"] = "97", + ["3298"] = "98", + ["3299"] = "99", + ["3300"] = "100", + ["3301"] = "1", + ["3302"] = "2", + ["3303"] = "3", + ["3304"] = "4", + ["3305"] = "5", + ["3306"] = "6", + ["3307"] = "7", + ["3308"] = "8", + ["3309"] = "9", + ["3310"] = "10", + ["3311"] = "11", + ["3312"] = "12", + ["3313"] = "13", + ["3314"] = "14", + ["3315"] = "15", + ["3316"] = "16", + ["3317"] = "17", + ["3318"] = "18", + ["3319"] = "19", + ["3320"] = "20", + ["3321"] = "21", + ["3322"] = "22", + ["3323"] = "23", + ["3324"] = "24", + ["3325"] = "25", + ["3326"] = "26", + ["3327"] = "27", + ["3328"] = "28", + ["3329"] = "29", + ["3330"] = "30", + ["3331"] = "31", + ["3332"] = "32", + ["3333"] = "33", + ["3334"] = "34", + ["3335"] = "35", + ["3336"] = "36", + ["3337"] = "37", + ["3338"] = "38", + ["3339"] = "39", + ["3340"] = "40", + ["3341"] = "41", + ["3342"] = "42", + ["3343"] = "43", + ["3344"] = "44", + ["3345"] = "45", + ["3346"] = "46", + ["3347"] = "47", + ["3348"] = "48", + ["3349"] = "49", + ["3350"] = "50", + ["3351"] = "51", + ["3352"] = "52", + ["3353"] = "53", + ["3354"] = "54", + ["3355"] = "55", + ["3356"] = "56", + ["3357"] = "57", + ["3358"] = "58", + ["3359"] = "59", + ["3360"] = "60", + ["3361"] = "61", + ["3362"] = "62", + ["3363"] = "63", + ["3364"] = "64", + ["3365"] = "65", + ["3366"] = "66", + ["3367"] = "67", + ["3368"] = "68", + ["3369"] = "69", + ["3370"] = "70", + ["3371"] = "71", + ["3372"] = "72", + ["3373"] = "73", + ["3374"] = "74", + ["3375"] = "75", + ["3376"] = "76", + ["3377"] = "77", + ["3378"] = "78", + ["3379"] = "79", + ["3380"] = "80", + ["3381"] = "81", + ["3382"] = "82", + ["3383"] = "83", + ["3384"] = "84", + ["3385"] = "85", + ["3386"] = "86", + ["3387"] = "87", + ["3388"] = "88", + ["3389"] = "89", + ["3390"] = "90", + ["3391"] = "91", + ["3392"] = "92", + ["3393"] = "93", + ["3394"] = "94", + ["3395"] = "95", + ["3396"] = "96", + ["3397"] = "97", + ["3398"] = "98", + ["3399"] = "99", + ["3400"] = "100", + ["3401"] = "1", + ["3402"] = "2", + ["3403"] = "3", + ["3404"] = "4", + ["3405"] = "5", + ["3406"] = "6", + ["3407"] = "7", + ["3408"] = "8", + ["3409"] = "9", + ["3410"] = "10", + ["3411"] = "11", + ["3412"] = "12", + ["3413"] = "13", + ["3414"] = "14", + ["3415"] = "15", + ["3416"] = "16", + ["3417"] = "17", + ["3418"] = "18", + ["3419"] = "19", + ["3420"] = "20", + ["3421"] = "21", + ["3422"] = "22", + ["3423"] = "23", + ["3424"] = "24", + ["3425"] = "25", + ["3426"] = "26", + ["3427"] = "27", + ["3428"] = "28", + ["3429"] = "29", + ["3430"] = "30", + ["3431"] = "31", + ["3432"] = "32", + ["3433"] = "33", + ["3434"] = "34", + ["3435"] = "35", + ["3436"] = "36", + ["3437"] = "37", + ["3438"] = "38", + ["3439"] = "39", + ["3440"] = "40", + ["3441"] = "41", + ["3442"] = "42", + ["3443"] = "43", + ["3444"] = "44", + ["3445"] = "45", + ["3446"] = "46", + ["3447"] = "47", + ["3448"] = "48", + ["3449"] = "49", + ["3450"] = "50", + ["3451"] = "51", + ["3452"] = "52", + ["3453"] = "53", + ["3454"] = "54", + ["3455"] = "55", + ["3456"] = "56", + ["3457"] = "57", + ["3458"] = "58", + ["3459"] = "59", + ["3460"] = "60", + ["3461"] = "61", + ["3462"] = "62", + ["3463"] = "63", + ["3464"] = "64", + ["3465"] = "65", + ["3466"] = "66", + ["3467"] = "67", + ["3468"] = "68", + ["3469"] = "69", + ["3470"] = "70", + ["3471"] = "71", + ["3472"] = "72", + ["3473"] = "73", + ["3474"] = "74", + ["3475"] = "75", + ["3476"] = "76", + ["3477"] = "77", + ["3478"] = "78", + ["3479"] = "79", + ["3480"] = "80", + ["3481"] = "81", + ["3482"] = "82", + ["3483"] = "83", + ["3484"] = "84", + ["3485"] = "85", + ["3486"] = "86", + ["3487"] = "87", + ["3488"] = "88", + ["3489"] = "89", + ["3490"] = "90", + ["3491"] = "91", + ["3492"] = "92", + ["3493"] = "93", + ["3494"] = "94", + ["3495"] = "95", + ["3496"] = "96", + ["3497"] = "97", + ["3498"] = "98", + ["3499"] = "99", + ["3500"] = "100", + ["3501"] = "1", + ["3502"] = "2", + ["3503"] = "3", + ["3504"] = "4", + ["3505"] = "5", + ["3506"] = "6", + ["3507"] = "7", + ["3508"] = "8", + ["3509"] = "9", + ["3510"] = "10", + ["3511"] = "11", + ["3512"] = "12", + ["3513"] = "13", + ["3514"] = "14", + ["3515"] = "15", + ["3516"] = "16", + ["3517"] = "17", + ["3518"] = "18", + ["3519"] = "19", + ["3520"] = "20", + ["3521"] = "21", + ["3522"] = "22", + ["3523"] = "23", + ["3524"] = "24", + ["3525"] = "25", + ["3526"] = "26", + ["3527"] = "27", + ["3528"] = "28", + ["3529"] = "29", + ["3530"] = "30", + ["3531"] = "31", + ["3532"] = "32", + ["3533"] = "33", + ["3534"] = "34", + ["3535"] = "35", + ["3536"] = "36", + ["3537"] = "37", + ["3538"] = "38", + ["3539"] = "39", + ["3540"] = "40", + ["3541"] = "41", + ["3542"] = "42", + ["3543"] = "43", + ["3544"] = "44", + ["3545"] = "45", + ["3546"] = "46", + ["3547"] = "47", + ["3548"] = "48", + ["3549"] = "49", + ["3550"] = "50", + ["3551"] = "51", + ["3552"] = "52", + ["3553"] = "53", + ["3554"] = "54", + ["3555"] = "55", + ["3556"] = "56", + ["3557"] = "57", + ["3558"] = "58", + ["3559"] = "59", + ["3560"] = "60", + ["3561"] = "61", + ["3562"] = "62", + ["3563"] = "63", + ["3564"] = "64", + ["3565"] = "65", + ["3566"] = "66", + ["3567"] = "67", + ["3568"] = "68", + ["3569"] = "69", + ["3570"] = "70", + ["3571"] = "71", + ["3572"] = "72", + ["3573"] = "73", + ["3574"] = "74", + ["3575"] = "75", + ["3576"] = "76", + ["3577"] = "77", + ["3578"] = "78", + ["3579"] = "79", + ["3580"] = "80", + ["3581"] = "81", + ["3582"] = "82", + ["3583"] = "83", + ["3584"] = "84", + ["3585"] = "85", + ["3586"] = "86", + ["3587"] = "87", + ["3588"] = "88", + ["3589"] = "89", + ["3590"] = "90", + ["3591"] = "91", + ["3592"] = "92", + ["3593"] = "93", + ["3594"] = "94", + ["3595"] = "95", + ["3596"] = "96", + ["3597"] = "97", + ["3598"] = "98", + ["3599"] = "99", + ["3600"] = "100", + ["3601"] = "1", + ["3602"] = "2", + ["3603"] = "3", + ["3604"] = "4", + ["3605"] = "5", + ["3606"] = "6", + ["3607"] = "7", + ["3608"] = "8", + ["3609"] = "9", + ["3610"] = "10", + ["3611"] = "11", + ["3612"] = "12", + ["3613"] = "13", + ["3614"] = "14", + ["3615"] = "15", + ["3616"] = "16", + ["3617"] = "17", + ["3618"] = "18", + ["3619"] = "19", + ["3620"] = "20", + ["3621"] = "21", + ["3622"] = "22", + ["3623"] = "23", + ["3624"] = "24", + ["3625"] = "25", + ["3626"] = "26", + ["3627"] = "27", + ["3628"] = "28", + ["3629"] = "29", + ["3630"] = "30", + ["3631"] = "31", + ["3632"] = "32", + ["3633"] = "33", + ["3634"] = "34", + ["3635"] = "35", + ["3636"] = "36", + ["3637"] = "37", + ["3638"] = "38", + ["3639"] = "39", + ["3640"] = "40", + ["3641"] = "41", + ["3642"] = "42", + ["3643"] = "43", + ["3644"] = "44", + ["3645"] = "45", + ["3646"] = "46", + ["3647"] = "47", + ["3648"] = "48", + ["3649"] = "49", + ["3650"] = "50", + ["3651"] = "51", + ["3652"] = "52", + ["3653"] = "53", + ["3654"] = "54", + ["3655"] = "55", + ["3656"] = "56", + ["3657"] = "57", + ["3658"] = "58", + ["3659"] = "59", + ["3660"] = "60", + ["3661"] = "61", + ["3662"] = "62", + ["3663"] = "63", + ["3664"] = "64", + ["3665"] = "65", + ["3666"] = "66", + ["3667"] = "67", + ["3668"] = "68", + ["3669"] = "69", + ["3670"] = "70", + ["3671"] = "71", + ["3672"] = "72", + ["3673"] = "73", + ["3674"] = "74", + ["3675"] = "75", + ["3676"] = "76", + ["3677"] = "77", + ["3678"] = "78", + ["3679"] = "79", + ["3680"] = "80", + ["3681"] = "81", + ["3682"] = "82", + ["3683"] = "83", + ["3684"] = "84", + ["3685"] = "85", + ["3686"] = "86", + ["3687"] = "87", + ["3688"] = "88", + ["3689"] = "89", + ["3690"] = "90", + ["3691"] = "91", + ["3692"] = "92", + ["3693"] = "93", + ["3694"] = "94", + ["3695"] = "95", + ["3696"] = "96", + ["3697"] = "97", + ["3698"] = "98", + ["3699"] = "99", + ["3700"] = "100", + ["3701"] = "1", + ["3702"] = "2", + ["3703"] = "3", + ["3704"] = "4", + ["3705"] = "5", + ["3706"] = "6", + ["3707"] = "7", + ["3708"] = "8", + ["3709"] = "9", + ["3710"] = "10", + ["3711"] = "11", + ["3712"] = "12", + ["3713"] = "13", + ["3714"] = "14", + ["3715"] = "15", + ["3716"] = "16", + ["3717"] = "17", + ["3718"] = "18", + ["3719"] = "19", + ["3720"] = "20", + ["3721"] = "21", + ["3722"] = "22", + ["3723"] = "23", + ["3724"] = "24", + ["3725"] = "25", + ["3726"] = "26", + ["3727"] = "27", + ["3728"] = "28", + ["3729"] = "29", + ["3730"] = "30", + ["3731"] = "31", + ["3732"] = "32", + ["3733"] = "33", + ["3734"] = "34", + ["3735"] = "35", + ["3736"] = "36", + ["3737"] = "37", + ["3738"] = "38", + ["3739"] = "39", + ["3740"] = "40", + ["3741"] = "41", + ["3742"] = "42", + ["3743"] = "43", + ["3744"] = "44", + ["3745"] = "45", + ["3746"] = "46", + ["3747"] = "47", + ["3748"] = "48", + ["3749"] = "49", + ["3750"] = "50", + ["3751"] = "51", + ["3752"] = "52", + ["3753"] = "53", + ["3754"] = "54", + ["3755"] = "55", + ["3756"] = "56", + ["3757"] = "57", + ["3758"] = "58", + ["3759"] = "59", + ["3760"] = "60", + ["3761"] = "61", + ["3762"] = "62", + ["3763"] = "63", + ["3764"] = "64", + ["3765"] = "65", + ["3766"] = "66", + ["3767"] = "67", + ["3768"] = "68", + ["3769"] = "69", + ["3770"] = "70", + ["3771"] = "71", + ["3772"] = "72", + ["3773"] = "73", + ["3774"] = "74", + ["3775"] = "75", + ["3776"] = "76", + ["3777"] = "77", + ["3778"] = "78", + ["3779"] = "79", + ["3780"] = "80", + ["3781"] = "81", + ["3782"] = "82", + ["3783"] = "83", + ["3784"] = "84", + ["3785"] = "85", + ["3786"] = "86", + ["3787"] = "87", + ["3788"] = "88", + ["3789"] = "89", + ["3790"] = "90", + ["3791"] = "91", + ["3792"] = "92", + ["3793"] = "93", + ["3794"] = "94", + ["3795"] = "95", + ["3796"] = "96", + ["3797"] = "97", + ["3798"] = "98", + ["3799"] = "99", + ["3800"] = "100", + ["3801"] = "1", + ["3802"] = "2", + ["3803"] = "3", + ["3804"] = "4", + ["3805"] = "5", + ["3806"] = "6", + ["3807"] = "7", + ["3808"] = "8", + ["3809"] = "9", + ["3810"] = "10", + ["3811"] = "11", + ["3812"] = "12", + ["3813"] = "13", + ["3814"] = "14", + ["3815"] = "15", + ["3816"] = "16", + ["3817"] = "17", + ["3818"] = "18", + ["3819"] = "19", + ["3820"] = "20", + ["3821"] = "21", + ["3822"] = "22", + ["3823"] = "23", + ["3824"] = "24", + ["3825"] = "25", + ["3826"] = "26", + ["3827"] = "27", + ["3828"] = "28", + ["3829"] = "29", + ["3830"] = "30", + ["3831"] = "31", + ["3832"] = "32", + ["3833"] = "33", + ["3834"] = "34", + ["3835"] = "35", + ["3836"] = "36", + ["3837"] = "37", + ["3838"] = "38", + ["3839"] = "39", + ["3840"] = "40", + ["3841"] = "41", + ["3842"] = "42", + ["3843"] = "43", + ["3844"] = "44", + ["3845"] = "45", + ["3846"] = "46", + ["3847"] = "47", + ["3848"] = "48", + ["3849"] = "49", + ["3850"] = "50", + ["3851"] = "51", + ["3852"] = "52", + ["3853"] = "53", + ["3854"] = "54", + ["3855"] = "55", + ["3856"] = "56", + ["3857"] = "57", + ["3858"] = "58", + ["3859"] = "59", + ["3860"] = "60", + ["3861"] = "61", + ["3862"] = "62", + ["3863"] = "63", + ["3864"] = "64", + ["3865"] = "65", + ["3866"] = "66", + ["3867"] = "67", + ["3868"] = "68", + ["3869"] = "69", + ["3870"] = "70", + ["3871"] = "71", + ["3872"] = "72", + ["3873"] = "73", + ["3874"] = "74", + ["3875"] = "75", + ["3876"] = "76", + ["3877"] = "77", + ["3878"] = "78", + ["3879"] = "79", + ["3880"] = "80", + ["3881"] = "81", + ["3882"] = "82", + ["3883"] = "83", + ["3884"] = "84", + ["3885"] = "85", + ["3886"] = "86", + ["3887"] = "87", + ["3888"] = "88", + ["3889"] = "89", + ["3890"] = "90", + ["3891"] = "91", + ["3892"] = "92", + ["3893"] = "93", + ["3894"] = "94", + ["3895"] = "95", + ["3896"] = "96", + ["3897"] = "97", + ["3898"] = "98", + ["3899"] = "99", + ["3900"] = "100", + ["3901"] = "1", + ["3902"] = "2", + ["3903"] = "3", + ["3904"] = "4", + ["3905"] = "5", + ["3906"] = "6", + ["3907"] = "7", + ["3908"] = "8", + ["3909"] = "9", + ["3910"] = "10", + ["3911"] = "11", + ["3912"] = "12", + ["3913"] = "13", + ["3914"] = "14", + ["3915"] = "15", + ["3916"] = "16", + ["3917"] = "17", + ["3918"] = "18", + ["3919"] = "19", + ["3920"] = "20", + ["3921"] = "21", + ["3922"] = "22", + ["3923"] = "23", + ["3924"] = "24", + ["3925"] = "25", + ["3926"] = "26", + ["3927"] = "27", + ["3928"] = "28", + ["3929"] = "29", + ["3930"] = "30", + ["3931"] = "31", + ["3932"] = "32", + ["3933"] = "33", + ["3934"] = "34", + ["3935"] = "35", + ["3936"] = "36", + ["3937"] = "37", + ["3938"] = "38", + ["3939"] = "39", + ["3940"] = "40", + ["3941"] = "41", + ["3942"] = "42", + ["3943"] = "43", + ["3944"] = "44", + ["3945"] = "45", + ["3946"] = "46", + ["3947"] = "47", + ["3948"] = "48", + ["3949"] = "49", + ["3950"] = "50", + ["3951"] = "51", + ["3952"] = "52", + ["3953"] = "53", + ["3954"] = "54", + ["3955"] = "55", + ["3956"] = "56", + ["3957"] = "57", + ["3958"] = "58", + ["3959"] = "59", + ["3960"] = "60", + ["3961"] = "61", + ["3962"] = "62", + ["3963"] = "63", + ["3964"] = "64", + ["3965"] = "65", + ["3966"] = "66", + ["3967"] = "67", + ["3968"] = "68", + ["3969"] = "69", + ["3970"] = "70", + ["3971"] = "71", + ["3972"] = "72", + ["3973"] = "73", + ["3974"] = "74", + ["3975"] = "75", + ["3976"] = "76", + ["3977"] = "77", + ["3978"] = "78", + ["3979"] = "79", + ["3980"] = "80", + ["3981"] = "81", + ["3982"] = "82", + ["3983"] = "83", + ["3984"] = "84", + ["3985"] = "85", + ["3986"] = "86", + ["3987"] = "87", + ["3988"] = "88", + ["3989"] = "89", + ["3990"] = "90", + ["3991"] = "91", + ["3992"] = "92", + ["3993"] = "93", + ["3994"] = "94", + ["3995"] = "95", + ["3996"] = "96", + ["3997"] = "97", + ["3998"] = "98", + ["3999"] = "99", + ["4000"] = "99", + ["4001"] = "1", + ["4002"] = "2", + ["4003"] = "3", + ["4004"] = "4", + ["4005"] = "5", + ["4006"] = "6", + ["4007"] = "7", + ["4008"] = "8", + ["4009"] = "9", + ["4000"] = "10", + ["4011"] = "11", + ["4012"] = "12", + ["4013"] = "13", + ["4014"] = "14", + ["4015"] = "15", + ["4016"] = "16", + ["4017"] = "17", + ["4018"] = "18", + ["4019"] = "19", + ["4020"] = "20", + ["4021"] = "21", + ["4022"] = "22", + ["4023"] = "23", + ["4024"] = "24", + ["4025"] = "25", + ["4026"] = "26", + ["4027"] = "27", + ["4028"] = "28", + ["4029"] = "29", + ["4030"] = "30", + ["4031"] = "31", + ["4032"] = "32", + ["4033"] = "33", + ["4034"] = "34", + ["4035"] = "35", + ["4036"] = "36", + ["4037"] = "37", + ["4038"] = "38", + ["4039"] = "39", + ["4040"] = "40", + ["4041"] = "41", + ["4042"] = "42", + ["4043"] = "43", + ["4044"] = "44", + ["4045"] = "45", + ["4046"] = "46", + ["4047"] = "47", + ["4048"] = "48", + ["4049"] = "49", + ["4050"] = "50", + ["4051"] = "51", + ["4052"] = "52", + ["4053"] = "53", + ["4054"] = "54", + ["4055"] = "55", + ["4056"] = "56", + ["4057"] = "57", + ["4058"] = "58", + ["4059"] = "59", + ["4060"] = "60", + ["4061"] = "61", + ["4062"] = "62", + ["4063"] = "63", + ["4064"] = "64", + ["4065"] = "65", + ["4066"] = "66", + ["4067"] = "67", + ["4068"] = "68", + ["4069"] = "69", + ["4070"] = "70", + ["4071"] = "71", + ["4072"] = "72", + ["4073"] = "73", + ["4074"] = "74", + ["4075"] = "75", + ["4076"] = "76", + ["4077"] = "77", + ["4078"] = "78", + ["4079"] = "79", + ["4080"] = "80", + ["4081"] = "81", + ["4082"] = "82", + ["4083"] = "83", + ["4084"] = "84", + ["4085"] = "85", + ["4086"] = "86", + ["4087"] = "87", + ["4088"] = "88", + ["4089"] = "89", + ["4090"] = "90", + ["4091"] = "91", + ["4092"] = "92", + ["4093"] = "93", + ["4094"] = "94", + ["4095"] = "95", + ["4096"] = "96", + ["4097"] = "97", + ["4098"] = "98", + ["4099"] = "99", + ["4100"] = "100", + ["4101"] = "1", + ["4102"] = "2", + ["4103"] = "3", + ["4104"] = "4", + ["4105"] = "5", + ["4106"] = "6", + ["4107"] = "7", + ["4108"] = "8", + ["4109"] = "9", + ["4110"] = "10", + ["4111"] = "11", + ["4112"] = "12", + ["4113"] = "13", + ["4114"] = "14", + ["4115"] = "15", + ["4116"] = "16", + ["4117"] = "17", + ["4118"] = "18", + ["4119"] = "19", + ["4120"] = "20", + ["4121"] = "21", + ["4122"] = "22", + ["4123"] = "23", + ["4124"] = "24", + ["4125"] = "25", + ["4126"] = "26", + ["4127"] = "27", + ["4128"] = "28", + ["4129"] = "29", + ["4130"] = "30", + ["4131"] = "31", + ["4132"] = "32", + ["4133"] = "33", + ["4134"] = "34", + ["4135"] = "35", + ["4136"] = "36", + ["4137"] = "37", + ["4138"] = "38", + ["4139"] = "39", + ["4140"] = "40", + ["4141"] = "41", + ["4142"] = "42", + ["4143"] = "43", + ["4144"] = "44", + ["4145"] = "45", + ["4146"] = "46", + ["4147"] = "47", + ["4148"] = "48", + ["4149"] = "49", + ["4150"] = "50", + ["4151"] = "51", + ["4152"] = "52", + ["4153"] = "53", + ["4154"] = "54", + ["4155"] = "55", + ["4156"] = "56", + ["4157"] = "57", + ["4158"] = "58", + ["4159"] = "59", + ["4160"] = "60", + ["4161"] = "61", + ["4162"] = "62", + ["4163"] = "63", + ["4164"] = "64", + ["4165"] = "65", + ["4166"] = "66", + ["4167"] = "67", + ["4168"] = "68", + ["4169"] = "69", + ["4170"] = "70", + ["4171"] = "71", + ["4172"] = "72", + ["4173"] = "73", + ["4174"] = "74", + ["4175"] = "75", + ["4176"] = "76", + ["4177"] = "77", + ["4178"] = "78", + ["4179"] = "79", + ["4180"] = "80", + ["4181"] = "81", + ["4182"] = "82", + ["4183"] = "83", + ["4184"] = "84", + ["4185"] = "85", + ["4186"] = "86", + ["4187"] = "87", + ["4188"] = "88", + ["4189"] = "89", + ["4190"] = "90", + ["4191"] = "91", + ["4192"] = "92", + ["4193"] = "93", + ["4194"] = "94", + ["4195"] = "95", + ["4196"] = "96", + ["4197"] = "97", + ["4198"] = "98", + ["4199"] = "99", + ["4200"] = "100", + ["4201"] = "1", + ["4202"] = "2", + ["4203"] = "3", + ["4204"] = "4", + ["4205"] = "5", + ["4206"] = "6", + ["4207"] = "7", + ["4208"] = "8", + ["4209"] = "9", + ["4210"] = "10", + ["4211"] = "11", + ["4212"] = "12", + ["4213"] = "13", + ["4214"] = "14", + ["4215"] = "15", + ["4216"] = "16", + ["4217"] = "17", + ["4218"] = "18", + ["4219"] = "19", + ["4220"] = "20", + ["4221"] = "21", + ["4222"] = "22", + ["4223"] = "23", + ["4224"] = "24", + ["4225"] = "25", + ["4226"] = "26", + ["4227"] = "27", + ["4228"] = "28", + ["4229"] = "29", + ["4230"] = "30", + ["4231"] = "31", + ["4232"] = "32", + ["4233"] = "33", + ["4234"] = "34", + ["4235"] = "35", + ["4236"] = "36", + ["4237"] = "37", + ["4238"] = "38", + ["4239"] = "39", + ["4240"] = "40", + ["4241"] = "41", + ["4242"] = "42", + ["4243"] = "43", + ["4244"] = "44", + ["4245"] = "45", + ["4246"] = "46", + ["4247"] = "47", + ["4248"] = "48", + ["4249"] = "49", + ["4250"] = "50", + ["4251"] = "51", + ["4252"] = "52", + ["4253"] = "53", + ["4254"] = "54", + ["4255"] = "55", + ["4256"] = "56", + ["4257"] = "57", + ["4258"] = "58", + ["4259"] = "59", + ["4260"] = "60", + ["4261"] = "61", + ["4262"] = "62", + ["4263"] = "63", + ["4264"] = "64", + ["4265"] = "65", + ["4266"] = "66", + ["4267"] = "67", + ["4268"] = "68", + ["4269"] = "69", + ["4270"] = "70", + ["4271"] = "71", + ["4272"] = "72", + ["4273"] = "73", + ["4274"] = "74", + ["4275"] = "75", + ["4276"] = "76", + ["4277"] = "77", + ["4278"] = "78", + ["4279"] = "79", + ["4280"] = "80", + ["4281"] = "81", + ["4282"] = "82", + ["4283"] = "83", + ["4284"] = "84", + ["4285"] = "85", + ["4286"] = "86", + ["4287"] = "87", + ["4288"] = "88", + ["4289"] = "89", + ["4290"] = "90", + ["4291"] = "91", + ["4292"] = "92", + ["4293"] = "93", + ["4294"] = "94", + ["4295"] = "95", + ["4296"] = "96", + ["4297"] = "97", + ["4298"] = "98", + ["4299"] = "99", + ["4300"] = "100", + ["4301"] = "1", + ["4302"] = "2", + ["4303"] = "3", + ["4304"] = "4", + ["4305"] = "5", + ["4306"] = "6", + ["4307"] = "7", + ["4308"] = "8", + ["4309"] = "9", + ["4310"] = "10", + ["4311"] = "11", + ["4312"] = "12", + ["4313"] = "13", + ["4314"] = "14", + ["4315"] = "15", + ["4316"] = "16", + ["4317"] = "17", + ["4318"] = "18", + ["4319"] = "19", + ["4320"] = "20", + ["4321"] = "21", + ["4322"] = "22", + ["4323"] = "23", + ["4324"] = "24", + ["4325"] = "25", + ["4326"] = "26", + ["4327"] = "27", + ["4328"] = "28", + ["4329"] = "29", + ["4330"] = "30", + ["4331"] = "31", + ["4332"] = "32", + ["4333"] = "33", + ["4334"] = "34", + ["4335"] = "35", + ["4336"] = "36", + ["4337"] = "37", + ["4338"] = "38", + ["4339"] = "39", + ["4340"] = "40", + ["4341"] = "41", + ["4342"] = "42", + ["4343"] = "43", + ["4344"] = "44", + ["4345"] = "45", + ["4346"] = "46", + ["4347"] = "47", + ["4348"] = "48", + ["4349"] = "49", + ["4350"] = "50", + ["4351"] = "51", + ["4352"] = "52", + ["4353"] = "53", + ["4354"] = "54", + ["4355"] = "55", + ["4356"] = "56", + ["4357"] = "57", + ["4358"] = "58", + ["4359"] = "59", + ["4360"] = "60", + ["4361"] = "61", + ["4362"] = "62", + ["4363"] = "63", + ["4364"] = "64", + ["4365"] = "65", + ["4366"] = "66", + ["4367"] = "67", + ["4368"] = "68", + ["4369"] = "69", + ["4370"] = "70", + ["4371"] = "71", + ["4372"] = "72", + ["4373"] = "73", + ["4374"] = "74", + ["4375"] = "75", + ["4376"] = "76", + ["4377"] = "77", + ["4378"] = "78", + ["4379"] = "79", + ["4380"] = "80", + ["4381"] = "81", + ["4382"] = "82", + ["4383"] = "83", + ["4384"] = "84", + ["4385"] = "85", + ["4386"] = "86", + ["4387"] = "87", + ["4388"] = "88", + ["4389"] = "89", + ["4390"] = "90", + ["4391"] = "91", + ["4392"] = "92", + ["4393"] = "93", + ["4394"] = "94", + ["4395"] = "95", + ["4396"] = "96", + ["4397"] = "97", + ["4398"] = "98", + ["4399"] = "99", + ["4400"] = "100", + ["4401"] = "1", + ["4402"] = "2", + ["4403"] = "3", + ["4404"] = "4", + ["4405"] = "5", + ["4406"] = "6", + ["4407"] = "7", + ["4408"] = "8", + ["4409"] = "9", + ["4410"] = "10", + ["4411"] = "11", + ["4412"] = "12", + ["4413"] = "13", + ["4414"] = "14", + ["4415"] = "15", + ["4416"] = "16", + ["4417"] = "17", + ["4418"] = "18", + ["4419"] = "19", + ["4420"] = "20", + ["4421"] = "21", + ["4422"] = "22", + ["4423"] = "23", + ["4424"] = "24", + ["4425"] = "25", + ["4426"] = "26", + ["4427"] = "27", + ["4428"] = "28", + ["4429"] = "29", + ["4430"] = "30", + ["4431"] = "31", + ["4432"] = "32", + ["4433"] = "33", + ["4434"] = "34", + ["4435"] = "35", + ["4436"] = "36", + ["4437"] = "37", + ["4438"] = "38", + ["4439"] = "39", + ["4440"] = "40", + ["4441"] = "41", + ["4442"] = "42", + ["4443"] = "43", + ["4444"] = "44", + ["4445"] = "45", + ["4446"] = "46", + ["4447"] = "47", + ["4448"] = "48", + ["4449"] = "49", + ["4450"] = "50", + ["4451"] = "51", + ["4452"] = "52", + ["4453"] = "53", + ["4454"] = "54", + ["4455"] = "55", + ["4456"] = "56", + ["4457"] = "57", + ["4458"] = "58", + ["4459"] = "59", + ["4460"] = "60", + ["4461"] = "61", + ["4462"] = "62", + ["4463"] = "63", + ["4464"] = "64", + ["4465"] = "65", + ["4466"] = "66", + ["4467"] = "67", + ["4468"] = "68", + ["4469"] = "69", + ["4470"] = "70", + ["4471"] = "71", + ["4472"] = "72", + ["4473"] = "73", + ["4474"] = "74", + ["4475"] = "75", + ["4476"] = "76", + ["4477"] = "77", + ["4478"] = "78", + ["4479"] = "79", + ["4480"] = "80", + ["4481"] = "81", + ["4482"] = "82", + ["4483"] = "83", + ["4484"] = "84", + ["4485"] = "85", + ["4486"] = "86", + ["4487"] = "87", + ["4488"] = "88", + ["4489"] = "89", + ["4490"] = "90", + ["4491"] = "91", + ["4492"] = "92", + ["4493"] = "93", + ["4494"] = "94", + ["4495"] = "95", + ["4496"] = "96", + ["4497"] = "97", + ["4498"] = "98", + ["4499"] = "99", + ["4500"] = "100", + ["4501"] = "1", + ["4502"] = "2", + ["4503"] = "3", + ["4504"] = "4", + ["4505"] = "5", + ["4506"] = "6", + ["4507"] = "7", + ["4508"] = "8", + ["4509"] = "9", + ["4510"] = "10", + ["4511"] = "11", + ["4512"] = "12", + ["4513"] = "13", + ["4514"] = "14", + ["4515"] = "15", + ["4516"] = "16", + ["4517"] = "17", + ["4518"] = "18", + ["4519"] = "19", + ["4520"] = "20", + ["4521"] = "21", + ["4522"] = "22", + ["4523"] = "23", + ["4524"] = "24", + ["4525"] = "25", + ["4526"] = "26", + ["4527"] = "27", + ["4528"] = "28", + ["4529"] = "29", + ["4530"] = "30", + ["4531"] = "31", + ["4532"] = "32", + ["4533"] = "33", + ["4534"] = "34", + ["4535"] = "35", + ["4536"] = "36", + ["4537"] = "37", + ["4538"] = "38", + ["4539"] = "39", + ["4540"] = "40", + ["4541"] = "41", + ["4542"] = "42", + ["4543"] = "43", + ["4544"] = "44", + ["4545"] = "45", + ["4546"] = "46", + ["4547"] = "47", + ["4548"] = "48", + ["4549"] = "49", + ["4550"] = "50", + ["4551"] = "51", + ["4552"] = "52", + ["4553"] = "53", + ["4554"] = "54", + ["4555"] = "55", + ["4556"] = "56", + ["4557"] = "57", + ["4558"] = "58", + ["4559"] = "59", + ["4560"] = "60", + ["4561"] = "61", + ["4562"] = "62", + ["4563"] = "63", + ["4564"] = "64", + ["4565"] = "65", + ["4566"] = "66", + ["4567"] = "67", + ["4568"] = "68", + ["4569"] = "69", + ["4570"] = "70", + ["4571"] = "71", + ["4572"] = "72", + ["4573"] = "73", + ["4574"] = "74", + ["4575"] = "75", + ["4576"] = "76", + ["4577"] = "77", + ["4578"] = "78", + ["4579"] = "79", + ["4580"] = "80", + ["4581"] = "81", + ["4582"] = "82", + ["4583"] = "83", + ["4584"] = "84", + ["4585"] = "85", + ["4586"] = "86", + ["4587"] = "87", + ["4588"] = "88", + ["4589"] = "89", + ["4590"] = "90", + ["4591"] = "91", + ["4592"] = "92", + ["4593"] = "93", + ["4594"] = "94", + ["4595"] = "95", + ["4596"] = "96", + ["4597"] = "97", + ["4598"] = "98", + ["4599"] = "99", + ["4600"] = "100", + ["4601"] = "1", + ["4602"] = "2", + ["4603"] = "3", + ["4604"] = "4", + ["4605"] = "5", + ["4606"] = "6", + ["4607"] = "7", + ["4608"] = "8", + ["4609"] = "9", + ["4610"] = "10", + ["4611"] = "11", + ["4612"] = "12", + ["4613"] = "13", + ["4614"] = "14", + ["4615"] = "15", + ["4616"] = "16", + ["4617"] = "17", + ["4618"] = "18", + ["4619"] = "19", + ["4620"] = "20", + ["4621"] = "21", + ["4622"] = "22", + ["4623"] = "23", + ["4624"] = "24", + ["4625"] = "25", + ["4626"] = "26", + ["4627"] = "27", + ["4628"] = "28", + ["4629"] = "29", + ["4630"] = "30", + ["4631"] = "31", + ["4632"] = "32", + ["4633"] = "33", + ["4634"] = "34", + ["4635"] = "35", + ["4636"] = "36", + ["4637"] = "37", + ["4638"] = "38", + ["4639"] = "39", + ["4640"] = "40", + ["4641"] = "41", + ["4642"] = "42", + ["4643"] = "43", + ["4644"] = "44", + ["4645"] = "45", + ["4646"] = "46", + ["4647"] = "47", + ["4648"] = "48", + ["4649"] = "49", + ["4650"] = "50", + ["4651"] = "51", + ["4652"] = "52", + ["4653"] = "53", + ["4654"] = "54", + ["4655"] = "55", + ["4656"] = "56", + ["4657"] = "57", + ["4658"] = "58", + ["4659"] = "59", + ["4660"] = "60", + ["4661"] = "61", + ["4662"] = "62", + ["4663"] = "63", + ["4664"] = "64", + ["4665"] = "65", + ["4666"] = "66", + ["4667"] = "67", + ["4668"] = "68", + ["4669"] = "69", + ["4670"] = "70", + ["4671"] = "71", + ["4672"] = "72", + ["4673"] = "73", + ["4674"] = "74", + ["4675"] = "75", + ["4676"] = "76", + ["4677"] = "77", + ["4678"] = "78", + ["4679"] = "79", + ["4680"] = "80", + ["4681"] = "81", + ["4682"] = "82", + ["4683"] = "83", + ["4684"] = "84", + ["4685"] = "85", + ["4686"] = "86", + ["4687"] = "87", + ["4688"] = "88", + ["4689"] = "89", + ["4690"] = "90", + ["4691"] = "91", + ["4692"] = "92", + ["4693"] = "93", + ["4694"] = "94", + ["4695"] = "95", + ["4696"] = "96", + ["4697"] = "97", + ["4698"] = "98", + ["4699"] = "99", + ["4700"] = "100", + ["4701"] = "1", + ["4702"] = "2", + ["4703"] = "3", + ["4704"] = "4", + ["4705"] = "5", + ["4706"] = "6", + ["4707"] = "7", + ["4708"] = "8", + ["4709"] = "9", + ["4710"] = "10", + ["4711"] = "11", + ["4712"] = "12", + ["4713"] = "13", + ["4714"] = "14", + ["4715"] = "15", + ["4716"] = "16", + ["4717"] = "17", + ["4718"] = "18", + ["4719"] = "19", + ["4720"] = "20", + ["4721"] = "21", + ["4722"] = "22", + ["4723"] = "23", + ["4724"] = "24", + ["4725"] = "25", + ["4726"] = "26", + ["4727"] = "27", + ["4728"] = "28", + ["4729"] = "29", + ["4730"] = "30", + ["4731"] = "31", + ["4732"] = "32", + ["4733"] = "33", + ["4734"] = "34", + ["4735"] = "35", + ["4736"] = "36", + ["4737"] = "37", + ["4738"] = "38", + ["4739"] = "39", + ["4740"] = "40", + ["4741"] = "41", + ["4742"] = "42", + ["4743"] = "43", + ["4744"] = "44", + ["4745"] = "45", + ["4746"] = "46", + ["4747"] = "47", + ["4748"] = "48", + ["4749"] = "49", + ["4750"] = "50", + ["4751"] = "51", + ["4752"] = "52", + ["4753"] = "53", + ["4754"] = "54", + ["4755"] = "55", + ["4756"] = "56", + ["4757"] = "57", + ["4758"] = "58", + ["4759"] = "59", + ["4760"] = "60", + ["4761"] = "61", + ["4762"] = "62", + ["4763"] = "63", + ["4764"] = "64", + ["4765"] = "65", + ["4766"] = "66", + ["4767"] = "67", + ["4768"] = "68", + ["4769"] = "69", + ["4770"] = "70", + ["4771"] = "71", + ["4772"] = "72", + ["4773"] = "73", + ["4774"] = "74", + ["4775"] = "75", + ["4776"] = "76", + ["4777"] = "77", + ["4778"] = "78", + ["4779"] = "79", + ["4780"] = "80", + ["4781"] = "81", + ["4782"] = "82", + ["4783"] = "83", + ["4784"] = "84", + ["4785"] = "85", + ["4786"] = "86", + ["4787"] = "87", + ["4788"] = "88", + ["4789"] = "89", + ["4790"] = "90", + ["4791"] = "91", + ["4792"] = "92", + ["4793"] = "93", + ["4794"] = "94", + ["4795"] = "95", + ["4796"] = "96", + ["4797"] = "97", + ["4798"] = "98", + ["4799"] = "99", + ["4800"] = "100", + ["4801"] = "1", + ["4802"] = "2", + ["4803"] = "3", + ["4804"] = "4", + ["4805"] = "5", + ["4806"] = "6", + ["4807"] = "7", + ["4808"] = "8", + ["4809"] = "9", + ["4810"] = "10", + ["4811"] = "11", + ["4812"] = "12", + ["4813"] = "13", + ["4814"] = "14", + ["4815"] = "15", + ["4816"] = "16", + ["4817"] = "17", + ["4818"] = "18", + ["4819"] = "19", + ["4820"] = "20", + ["4821"] = "21", + ["4822"] = "22", + ["4823"] = "23", + ["4824"] = "24", + ["4825"] = "25", + ["4826"] = "26", + ["4827"] = "27", + ["4828"] = "28", + ["4829"] = "29", + ["4830"] = "30", + ["4831"] = "31", + ["4832"] = "32", + ["4833"] = "33", + ["4834"] = "34", + ["4835"] = "35", + ["4836"] = "36", + ["4837"] = "37", + ["4838"] = "38", + ["4839"] = "39", + ["4840"] = "40", + ["4841"] = "41", + ["4842"] = "42", + ["4843"] = "43", + ["4844"] = "44", + ["4845"] = "45", + ["4846"] = "46", + ["4847"] = "47", + ["4848"] = "48", + ["4849"] = "49", + ["4850"] = "50", + ["4851"] = "51", + ["4852"] = "52", + ["4853"] = "53", + ["4854"] = "54", + ["4855"] = "55", + ["4856"] = "56", + ["4857"] = "57", + ["4858"] = "58", + ["4859"] = "59", + ["4860"] = "60", + ["4861"] = "61", + ["4862"] = "62", + ["4863"] = "63", + ["4864"] = "64", + ["4865"] = "65", + ["4866"] = "66", + ["4867"] = "67", + ["4868"] = "68", + ["4869"] = "69", + ["4870"] = "70", + ["4871"] = "71", + ["4872"] = "72", + ["4873"] = "73", + ["4874"] = "74", + ["4875"] = "75", + ["4876"] = "76", + ["4877"] = "77", + ["4878"] = "78", + ["4879"] = "79", + ["4880"] = "80", + ["4881"] = "81", + ["4882"] = "82", + ["4883"] = "83", + ["4884"] = "84", + ["4885"] = "85", + ["4886"] = "86", + ["4887"] = "87", + ["4888"] = "88", + ["4889"] = "89", + ["4890"] = "90", + ["4891"] = "91", + ["4892"] = "92", + ["4893"] = "93", + ["4894"] = "94", + ["4895"] = "95", + ["4896"] = "96", + ["4897"] = "97", + ["4898"] = "98", + ["4899"] = "99", + ["4900"] = "100", + ["4901"] = "1", + ["4902"] = "2", + ["4903"] = "3", + ["4904"] = "4", + ["4905"] = "5", + ["4906"] = "6", + ["4907"] = "7", + ["4908"] = "8", + ["4909"] = "9", + ["4910"] = "10", + ["4911"] = "11", + ["4912"] = "12", + ["4913"] = "13", + ["4914"] = "14", + ["4915"] = "15", + ["4916"] = "16", + ["4917"] = "17", + ["4918"] = "18", + ["4919"] = "19", + ["4920"] = "20", + ["4921"] = "21", + ["4922"] = "22", + ["4923"] = "23", + ["4924"] = "24", + ["4925"] = "25", + ["4926"] = "26", + ["4927"] = "27", + ["4928"] = "28", + ["4929"] = "29", + ["4930"] = "30", + ["4931"] = "31", + ["4932"] = "32", + ["4933"] = "33", + ["4934"] = "34", + ["4935"] = "35", + ["4936"] = "36", + ["4937"] = "37", + ["4938"] = "38", + ["4939"] = "39", + ["4940"] = "40", + ["4941"] = "41", + ["4942"] = "42", + ["4943"] = "43", + ["4944"] = "44", + ["4945"] = "45", + ["4946"] = "46", + ["4947"] = "47", + ["4948"] = "48", + ["4949"] = "49", + ["4950"] = "50", + ["4951"] = "51", + ["4952"] = "52", + ["4953"] = "53", + ["4954"] = "54", + ["4955"] = "55", + ["4956"] = "56", + ["4957"] = "57", + ["4958"] = "58", + ["4959"] = "59", + ["4960"] = "60", + ["4961"] = "61", + ["4962"] = "62", + ["4963"] = "63", + ["4964"] = "64", + ["4965"] = "65", + ["4966"] = "66", + ["4967"] = "67", + ["4968"] = "68", + ["4969"] = "69", + ["4970"] = "70", + ["4971"] = "71", + ["4972"] = "72", + ["4973"] = "73", + ["4974"] = "74", + ["4975"] = "75", + ["4976"] = "76", + ["4977"] = "77", + ["4978"] = "78", + ["4979"] = "79", + ["4980"] = "80", + ["4981"] = "81", + ["4982"] = "82", + ["4983"] = "83", + ["4984"] = "84", + ["4985"] = "85", + ["4986"] = "86", + ["4987"] = "87", + ["4988"] = "88", + ["4989"] = "89", + ["4990"] = "90", + ["4991"] = "91", + ["4992"] = "92", + ["4993"] = "93", + ["4994"] = "94", + ["4995"] = "95", + ["4996"] = "96", + ["4997"] = "97", + ["4998"] = "98", + ["4999"] = "99", + ["5000"] = "99", + ["5001"] = "1", + ["5002"] = "2", + ["5003"] = "3", + ["5004"] = "4", + ["5005"] = "5", + ["5006"] = "6", + ["5007"] = "7", + ["5008"] = "8", + ["5009"] = "9", + ["5000"] = "10", + ["5011"] = "11", + ["5012"] = "12", + ["5013"] = "13", + ["5014"] = "14", + ["5015"] = "15", + ["5016"] = "16", + ["5017"] = "17", + ["5018"] = "18", + ["5019"] = "19", + ["5020"] = "20", + ["5021"] = "21", + ["5022"] = "22", + ["5023"] = "23", + ["5024"] = "24", + ["5025"] = "25", + ["5026"] = "26", + ["5027"] = "27", + ["5028"] = "28", + ["5029"] = "29", + ["5030"] = "30", + ["5031"] = "31", + ["5032"] = "32", + ["5033"] = "33", + ["5034"] = "34", + ["5035"] = "35", + ["5036"] = "36", + ["5037"] = "37", + ["5038"] = "38", + ["5039"] = "39", + ["5040"] = "40", + ["5041"] = "41", + ["5042"] = "42", + ["5043"] = "43", + ["5044"] = "44", + ["5045"] = "45", + ["5046"] = "46", + ["5047"] = "47", + ["5048"] = "48", + ["5049"] = "49", + ["5050"] = "50", + ["5051"] = "51", + ["5052"] = "52", + ["5053"] = "53", + ["5054"] = "54", + ["5055"] = "55", + ["5056"] = "56", + ["5057"] = "57", + ["5058"] = "58", + ["5059"] = "59", + ["5060"] = "60", + ["5061"] = "61", + ["5062"] = "62", + ["5063"] = "63", + ["5064"] = "64", + ["5065"] = "65", + ["5066"] = "66", + ["5067"] = "67", + ["5068"] = "68", + ["5069"] = "69", + ["5070"] = "70", + ["5071"] = "71", + ["5072"] = "72", + ["5073"] = "73", + ["5074"] = "74", + ["5075"] = "75", + ["5076"] = "76", + ["5077"] = "77", + ["5078"] = "78", + ["5079"] = "79", + ["5080"] = "80", + ["5081"] = "81", + ["5082"] = "82", + ["5083"] = "83", + ["5084"] = "84", + ["5085"] = "85", + ["5086"] = "86", + ["5087"] = "87", + ["5088"] = "88", + ["5089"] = "89", + ["5090"] = "90", + ["5091"] = "91", + ["5092"] = "92", + ["5093"] = "93", + ["5094"] = "94", + ["5095"] = "95", + ["5096"] = "96", + ["5097"] = "97", + ["5098"] = "98", + ["5099"] = "99", + ["5100"] = "100", + ["5101"] = "1", + ["5102"] = "2", + ["5103"] = "3", + ["5104"] = "4", + ["5105"] = "5", + ["5106"] = "6", + ["5107"] = "7", + ["5108"] = "8", + ["5109"] = "9", + ["5110"] = "10", + ["5111"] = "11", + ["5112"] = "12", + ["5113"] = "13", + ["5114"] = "14", + ["5115"] = "15", + ["5116"] = "16", + ["5117"] = "17", + ["5118"] = "18", + ["5119"] = "19", + ["5120"] = "20", + ["5121"] = "21", + ["5122"] = "22", + ["5123"] = "23", + ["5124"] = "24", + ["5125"] = "25", + ["5126"] = "26", + ["5127"] = "27", + ["5128"] = "28", + ["5129"] = "29", + ["5130"] = "30", + ["5131"] = "31", + ["5132"] = "32", + ["5133"] = "33", + ["5134"] = "34", + ["5135"] = "35", + ["5136"] = "36", + ["5137"] = "37", + ["5138"] = "38", + ["5139"] = "39", + ["5140"] = "40", + ["5141"] = "41", + ["5142"] = "42", + ["5143"] = "43", + ["5144"] = "44", + ["5145"] = "45", + ["5146"] = "46", + ["5147"] = "47", + ["5148"] = "48", + ["5149"] = "49", + ["5150"] = "50", + ["5151"] = "51", + ["5152"] = "52", + ["5153"] = "53", + ["5154"] = "54", + ["5155"] = "55", + ["5156"] = "56", + ["5157"] = "57", + ["5158"] = "58", + ["5159"] = "59", + ["5160"] = "60", + ["5161"] = "61", + ["5162"] = "62", + ["5163"] = "63", + ["5164"] = "64", + ["5165"] = "65", + ["5166"] = "66", + ["5167"] = "67", + ["5168"] = "68", + ["5169"] = "69", + ["5170"] = "70", + ["5171"] = "71", + ["5172"] = "72", + ["5173"] = "73", + ["5174"] = "74", + ["5175"] = "75", + ["5176"] = "76", + ["5177"] = "77", + ["5178"] = "78", + ["5179"] = "79", + ["5180"] = "80", + ["5181"] = "81", + ["5182"] = "82", + ["5183"] = "83", + ["5184"] = "84", + ["5185"] = "85", + ["5186"] = "86", + ["5187"] = "87", + ["5188"] = "88", + ["5189"] = "89", + ["5190"] = "90", + ["5191"] = "91", + ["5192"] = "92", + ["5193"] = "93", + ["5194"] = "94", + ["5195"] = "95", + ["5196"] = "96", + ["5197"] = "97", + ["5198"] = "98", + ["5199"] = "99", + ["5200"] = "100", + ["5201"] = "1", + ["5202"] = "2", + ["5203"] = "3", + ["5204"] = "4", + ["5205"] = "5", + ["5206"] = "6", + ["5207"] = "7", + ["5208"] = "8", + ["5209"] = "9", + ["5210"] = "10", + ["5211"] = "11", + ["5212"] = "12", + ["5213"] = "13", + ["5214"] = "14", + ["5215"] = "15", + ["5216"] = "16", + ["5217"] = "17", + ["5218"] = "18", + ["5219"] = "19", + ["5220"] = "20", + ["5221"] = "21", + ["5222"] = "22", + ["5223"] = "23", + ["5224"] = "24", + ["5225"] = "25", + ["5226"] = "26", + ["5227"] = "27", + ["5228"] = "28", + ["5229"] = "29", + ["5230"] = "30", + ["5231"] = "31", + ["5232"] = "32", + ["5233"] = "33", + ["5234"] = "34", + ["5235"] = "35", + ["5236"] = "36", + ["5237"] = "37", + ["5238"] = "38", + ["5239"] = "39", + ["5240"] = "40", + ["5241"] = "41", + ["5242"] = "42", + ["5243"] = "43", + ["5244"] = "44", + ["5245"] = "45", + ["5246"] = "46", + ["5247"] = "47", + ["5248"] = "48", + ["5249"] = "49", + ["5250"] = "50", + ["5251"] = "51", + ["5252"] = "52", + ["5253"] = "53", + ["5254"] = "54", + ["5255"] = "55", + ["5256"] = "56", + ["5257"] = "57", + ["5258"] = "58", + ["5259"] = "59", + ["5260"] = "60", + ["5261"] = "61", + ["5262"] = "62", + ["5263"] = "63", + ["5264"] = "64", + ["5265"] = "65", + ["5266"] = "66", + ["5267"] = "67", + ["5268"] = "68", + ["5269"] = "69", + ["5270"] = "70", + ["5271"] = "71", + ["5272"] = "72", + ["5273"] = "73", + ["5274"] = "74", + ["5275"] = "75", + ["5276"] = "76", + ["5277"] = "77", + ["5278"] = "78", + ["5279"] = "79", + ["5280"] = "80", + ["5281"] = "81", + ["5282"] = "82", + ["5283"] = "83", + ["5284"] = "84", + ["5285"] = "85", + ["5286"] = "86", + ["5287"] = "87", + ["5288"] = "88", + ["5289"] = "89", + ["5290"] = "90", + ["5291"] = "91", + ["5292"] = "92", + ["5293"] = "93", + ["5294"] = "94", + ["5295"] = "95", + ["5296"] = "96", + ["5297"] = "97", + ["5298"] = "98", + ["5299"] = "99", + ["5300"] = "100", + ["5301"] = "1", + ["5302"] = "2", + ["5303"] = "3", + ["5304"] = "4", + ["5305"] = "5", + ["5306"] = "6", + ["5307"] = "7", + ["5308"] = "8", + ["5309"] = "9", + ["5310"] = "10", + ["5311"] = "11", + ["5312"] = "12", + ["5313"] = "13", + ["5314"] = "14", + ["5315"] = "15", + ["5316"] = "16", + ["5317"] = "17", + ["5318"] = "18", + ["5319"] = "19", + ["5320"] = "20", + ["5321"] = "21", + ["5322"] = "22", + ["5323"] = "23", + ["5324"] = "24", + ["5325"] = "25", + ["5326"] = "26", + ["5327"] = "27", + ["5328"] = "28", + ["5329"] = "29", + ["5330"] = "30", + ["5331"] = "31", + ["5332"] = "32", + ["5333"] = "33", + ["5334"] = "34", + ["5335"] = "35", + ["5336"] = "36", + ["5337"] = "37", + ["5338"] = "38", + ["5339"] = "39", + ["5340"] = "40", + ["5341"] = "41", + ["5342"] = "42", + ["5343"] = "43", + ["5344"] = "44", + ["5345"] = "45", + ["5346"] = "46", + ["5347"] = "47", + ["5348"] = "48", + ["5349"] = "49", + ["5350"] = "50", + ["5351"] = "51", + ["5352"] = "52", + ["5353"] = "53", + ["5354"] = "54", + ["5355"] = "55", + ["5356"] = "56", + ["5357"] = "57", + ["5358"] = "58", + ["5359"] = "59", + ["5360"] = "60", + ["5361"] = "61", + ["5362"] = "62", + ["5363"] = "63", + ["5364"] = "64", + ["5365"] = "65", + ["5366"] = "66", + ["5367"] = "67", + ["5368"] = "68", + ["5369"] = "69", + ["5370"] = "70", + ["5371"] = "71", + ["5372"] = "72", + ["5373"] = "73", + ["5374"] = "74", + ["5375"] = "75", + ["5376"] = "76", + ["5377"] = "77", + ["5378"] = "78", + ["5379"] = "79", + ["5380"] = "80", + ["5381"] = "81", + ["5382"] = "82", + ["5383"] = "83", + ["5384"] = "84", + ["5385"] = "85", + ["5386"] = "86", + ["5387"] = "87", + ["5388"] = "88", + ["5389"] = "89", + ["5390"] = "90", + ["5391"] = "91", + ["5392"] = "92", + ["5393"] = "93", + ["5394"] = "94", + ["5395"] = "95", + ["5396"] = "96", + ["5397"] = "97", + ["5398"] = "98", + ["5399"] = "99", + ["5400"] = "100", + ["5401"] = "1", + ["5402"] = "2", + ["5403"] = "3", + ["5404"] = "4", + ["5405"] = "5", + ["5406"] = "6", + ["5407"] = "7", + ["5408"] = "8", + ["5409"] = "9", + ["5410"] = "10", + ["5411"] = "11", + ["5412"] = "12", + ["5413"] = "13", + ["5414"] = "14", + ["5415"] = "15", + ["5416"] = "16", + ["5417"] = "17", + ["5418"] = "18", + ["5419"] = "19", + ["5420"] = "20", + ["5421"] = "21", + ["5422"] = "22", + ["5423"] = "23", + ["5424"] = "24", + ["5425"] = "25", + ["5426"] = "26", + ["5427"] = "27", + ["5428"] = "28", + ["5429"] = "29", + ["5430"] = "30", + ["5431"] = "31", + ["5432"] = "32", + ["5433"] = "33", + ["5434"] = "34", + ["5435"] = "35", + ["5436"] = "36", + ["5437"] = "37", + ["5438"] = "38", + ["5439"] = "39", + ["5440"] = "40", + ["5441"] = "41", + ["5442"] = "42", + ["5443"] = "43", + ["5444"] = "44", + ["5445"] = "45", + ["5446"] = "46", + ["5447"] = "47", + ["5448"] = "48", + ["5449"] = "49", + ["5450"] = "50", + ["5451"] = "51", + ["5452"] = "52", + ["5453"] = "53", + ["5454"] = "54", + ["5455"] = "55", + ["5456"] = "56", + ["5457"] = "57", + ["5458"] = "58", + ["5459"] = "59", + ["5460"] = "60", + ["5461"] = "61", + ["5462"] = "62", + ["5463"] = "63", + ["5464"] = "64", + ["5465"] = "65", + ["5466"] = "66", + ["5467"] = "67", + ["5468"] = "68", + ["5469"] = "69", + ["5470"] = "70", + ["5471"] = "71", + ["5472"] = "72", + ["5473"] = "73", + ["5474"] = "74", + ["5475"] = "75", + ["5476"] = "76", + ["5477"] = "77", + ["5478"] = "78", + ["5479"] = "79", + ["5480"] = "80", + ["5481"] = "81", + ["5482"] = "82", + ["5483"] = "83", + ["5484"] = "84", + ["5485"] = "85", + ["5486"] = "86", + ["5487"] = "87", + ["5488"] = "88", + ["5489"] = "89", + ["5490"] = "90", + ["5491"] = "91", + ["5492"] = "92", + ["5493"] = "93", + ["5494"] = "94", + ["5495"] = "95", + ["5496"] = "96", + ["5497"] = "97", + ["5498"] = "98", + ["5499"] = "99", + ["5500"] = "100", + ["5501"] = "1", + ["5502"] = "2", + ["5503"] = "3", + ["5504"] = "4", + ["5505"] = "5", + ["5506"] = "6", + ["5507"] = "7", + ["5508"] = "8", + ["5509"] = "9", + ["5510"] = "10", + ["5511"] = "11", + ["5512"] = "12", + ["5513"] = "13", + ["5514"] = "14", + ["5515"] = "15", + ["5516"] = "16", + ["5517"] = "17", + ["5518"] = "18", + ["5519"] = "19", + ["5520"] = "20", + ["5521"] = "21", + ["5522"] = "22", + ["5523"] = "23", + ["5524"] = "24", + ["5525"] = "25", + ["5526"] = "26", + ["5527"] = "27", + ["5528"] = "28", + ["5529"] = "29", + ["5530"] = "30", + ["5531"] = "31", + ["5532"] = "32", + ["5533"] = "33", + ["5534"] = "34", + ["5535"] = "35", + ["5536"] = "36", + ["5537"] = "37", + ["5538"] = "38", + ["5539"] = "39", + ["5540"] = "40", + ["5541"] = "41", + ["5542"] = "42", + ["5543"] = "43", + ["5544"] = "44", + ["5545"] = "45", + ["5546"] = "46", + ["5547"] = "47", + ["5548"] = "48", + ["5549"] = "49", + ["5550"] = "50", + ["5551"] = "51", + ["5552"] = "52", + ["5553"] = "53", + ["5554"] = "54", + ["5555"] = "55", + ["5556"] = "56", + ["5557"] = "57", + ["5558"] = "58", + ["5559"] = "59", + ["5560"] = "60", + ["5561"] = "61", + ["5562"] = "62", + ["5563"] = "63", + ["5564"] = "64", + ["5565"] = "65", + ["5566"] = "66", + ["5567"] = "67", + ["5568"] = "68", + ["5569"] = "69", + ["5570"] = "70", + ["5571"] = "71", + ["5572"] = "72", + ["5573"] = "73", + ["5574"] = "74", + ["5575"] = "75", + ["5576"] = "76", + ["5577"] = "77", + ["5578"] = "78", + ["5579"] = "79", + ["5580"] = "80", + ["5581"] = "81", + ["5582"] = "82", + ["5583"] = "83", + ["5584"] = "84", + ["5585"] = "85", + ["5586"] = "86", + ["5587"] = "87", + ["5588"] = "88", + ["5589"] = "89", + ["5590"] = "90", + ["5591"] = "91", + ["5592"] = "92", + ["5593"] = "93", + ["5594"] = "94", + ["5595"] = "95", + ["5596"] = "96", + ["5597"] = "97", + ["5598"] = "98", + ["5599"] = "99", + ["5600"] = "100", + ["5601"] = "1", + ["5602"] = "2", + ["5603"] = "3", + ["5604"] = "4", + ["5605"] = "5", + ["5606"] = "6", + ["5607"] = "7", + ["5608"] = "8", + ["5609"] = "9", + ["5610"] = "10", + ["5611"] = "11", + ["5612"] = "12", + ["5613"] = "13", + ["5614"] = "14", + ["5615"] = "15", + ["5616"] = "16", + ["5617"] = "17", + ["5618"] = "18", + ["5619"] = "19", + ["5620"] = "20", + ["5621"] = "21", + ["5622"] = "22", + ["5623"] = "23", + ["5624"] = "24", + ["5625"] = "25", + ["5626"] = "26", + ["5627"] = "27", + ["5628"] = "28", + ["5629"] = "29", + ["5630"] = "30", + ["5631"] = "31", + ["5632"] = "32", + ["5633"] = "33", + ["5634"] = "34", + ["5635"] = "35", + ["5636"] = "36", + ["5637"] = "37", + ["5638"] = "38", + ["5639"] = "39", + ["5640"] = "40", + ["5641"] = "41", + ["5642"] = "42", + ["5643"] = "43", + ["5644"] = "44", + ["5645"] = "45", + ["5646"] = "46", + ["5647"] = "47", + ["5648"] = "48", + ["5649"] = "49", + ["5650"] = "50", + ["5651"] = "51", + ["5652"] = "52", + ["5653"] = "53", + ["5654"] = "54", + ["5655"] = "55", + ["5656"] = "56", + ["5657"] = "57", + ["5658"] = "58", + ["5659"] = "59", + ["5660"] = "60", + ["5661"] = "61", + ["5662"] = "62", + ["5663"] = "63", + ["5664"] = "64", + ["5665"] = "65", + ["5666"] = "66", + ["5667"] = "67", + ["5668"] = "68", + ["5669"] = "69", + ["5670"] = "70", + ["5671"] = "71", + ["5672"] = "72", + ["5673"] = "73", + ["5674"] = "74", + ["5675"] = "75", + ["5676"] = "76", + ["5677"] = "77", + ["5678"] = "78", + ["5679"] = "79", + ["5680"] = "80", + ["5681"] = "81", + ["5682"] = "82", + ["5683"] = "83", + ["5684"] = "84", + ["5685"] = "85", + ["5686"] = "86", + ["5687"] = "87", + ["5688"] = "88", + ["5689"] = "89", + ["5690"] = "90", + ["5691"] = "91", + ["5692"] = "92", + ["5693"] = "93", + ["5694"] = "94", + ["5695"] = "95", + ["5696"] = "96", + ["5697"] = "97", + ["5698"] = "98", + ["5699"] = "99", + ["5700"] = "100", + ["5701"] = "1", + ["5702"] = "2", + ["5703"] = "3", + ["5704"] = "4", + ["5705"] = "5", + ["5706"] = "6", + ["5707"] = "7", + ["5708"] = "8", + ["5709"] = "9", + ["5710"] = "10", + ["5711"] = "11", + ["5712"] = "12", + ["5713"] = "13", + ["5714"] = "14", + ["5715"] = "15", + ["5716"] = "16", + ["5717"] = "17", + ["5718"] = "18", + ["5719"] = "19", + ["5720"] = "20", + ["5721"] = "21", + ["5722"] = "22", + ["5723"] = "23", + ["5724"] = "24", + ["5725"] = "25", + ["5726"] = "26", + ["5727"] = "27", + ["5728"] = "28", + ["5729"] = "29", + ["5730"] = "30", + ["5731"] = "31", + ["5732"] = "32", + ["5733"] = "33", + ["5734"] = "34", + ["5735"] = "35", + ["5736"] = "36", + ["5737"] = "37", + ["5738"] = "38", + ["5739"] = "39", + ["5740"] = "40", + ["5741"] = "41", + ["5742"] = "42", + ["5743"] = "43", + ["5744"] = "44", + ["5745"] = "45", + ["5746"] = "46", + ["5747"] = "47", + ["5748"] = "48", + ["5749"] = "49", + ["5750"] = "50", + ["5751"] = "51", + ["5752"] = "52", + ["5753"] = "53", + ["5754"] = "54", + ["5755"] = "55", + ["5756"] = "56", + ["5757"] = "57", + ["5758"] = "58", + ["5759"] = "59", + ["5760"] = "60", + ["5761"] = "61", + ["5762"] = "62", + ["5763"] = "63", + ["5764"] = "64", + ["5765"] = "65", + ["5766"] = "66", + ["5767"] = "67", + ["5768"] = "68", + ["5769"] = "69", + ["5770"] = "70", + ["5771"] = "71", + ["5772"] = "72", + ["5773"] = "73", + ["5774"] = "74", + ["5775"] = "75", + ["5776"] = "76", + ["5777"] = "77", + ["5778"] = "78", + ["5779"] = "79", + ["5780"] = "80", + ["5781"] = "81", + ["5782"] = "82", + ["5783"] = "83", + ["5784"] = "84", + ["5785"] = "85", + ["5786"] = "86", + ["5787"] = "87", + ["5788"] = "88", + ["5789"] = "89", + ["5790"] = "90", + ["5791"] = "91", + ["5792"] = "92", + ["5793"] = "93", + ["5794"] = "94", + ["5795"] = "95", + ["5796"] = "96", + ["5797"] = "97", + ["5798"] = "98", + ["5799"] = "99", + ["5800"] = "100", + ["5801"] = "1", + ["5802"] = "2", + ["5803"] = "3", + ["5804"] = "4", + ["5805"] = "5", + ["5806"] = "6", + ["5807"] = "7", + ["5808"] = "8", + ["5809"] = "9", + ["5810"] = "10", + ["5811"] = "11", + ["5812"] = "12", + ["5813"] = "13", + ["5814"] = "14", + ["5815"] = "15", + ["5816"] = "16", + ["5817"] = "17", + ["5818"] = "18", + ["5819"] = "19", + ["5820"] = "20", + ["5821"] = "21", + ["5822"] = "22", + ["5823"] = "23", + ["5824"] = "24", + ["5825"] = "25", + ["5826"] = "26", + ["5827"] = "27", + ["5828"] = "28", + ["5829"] = "29", + ["5830"] = "30", + ["5831"] = "31", + ["5832"] = "32", + ["5833"] = "33", + ["5834"] = "34", + ["5835"] = "35", + ["5836"] = "36", + ["5837"] = "37", + ["5838"] = "38", + ["5839"] = "39", + ["5840"] = "40", + ["5841"] = "41", + ["5842"] = "42", + ["5843"] = "43", + ["5844"] = "44", + ["5845"] = "45", + ["5846"] = "46", + ["5847"] = "47", + ["5848"] = "48", + ["5849"] = "49", + ["5850"] = "50", + ["5851"] = "51", + ["5852"] = "52", + ["5853"] = "53", + ["5854"] = "54", + ["5855"] = "55", + ["5856"] = "56", + ["5857"] = "57", + ["5858"] = "58", + ["5859"] = "59", + ["5860"] = "60", + ["5861"] = "61", + ["5862"] = "62", + ["5863"] = "63", + ["5864"] = "64", + ["5865"] = "65", + ["5866"] = "66", + ["5867"] = "67", + ["5868"] = "68", + ["5869"] = "69", + ["5870"] = "70", + ["5871"] = "71", + ["5872"] = "72", + ["5873"] = "73", + ["5874"] = "74", + ["5875"] = "75", + ["5876"] = "76", + ["5877"] = "77", + ["5878"] = "78", + ["5879"] = "79", + ["5880"] = "80", + ["5881"] = "81", + ["5882"] = "82", + ["5883"] = "83", + ["5884"] = "84", + ["5885"] = "85", + ["5886"] = "86", + ["5887"] = "87", + ["5888"] = "88", + ["5889"] = "89", + ["5890"] = "90", + ["5891"] = "91", + ["5892"] = "92", + ["5893"] = "93", + ["5894"] = "94", + ["5895"] = "95", + ["5896"] = "96", + ["5897"] = "97", + ["5898"] = "98", + ["5899"] = "99", + ["5900"] = "100", + ["5901"] = "1", + ["5902"] = "2", + ["5903"] = "3", + ["5904"] = "4", + ["5905"] = "5", + ["5906"] = "6", + ["5907"] = "7", + ["5908"] = "8", + ["5909"] = "9", + ["5910"] = "10", + ["5911"] = "11", + ["5912"] = "12", + ["5913"] = "13", + ["5914"] = "14", + ["5915"] = "15", + ["5916"] = "16", + ["5917"] = "17", + ["5918"] = "18", + ["5919"] = "19", + ["5920"] = "20", + ["5921"] = "21", + ["5922"] = "22", + ["5923"] = "23", + ["5924"] = "24", + ["5925"] = "25", + ["5926"] = "26", + ["5927"] = "27", + ["5928"] = "28", + ["5929"] = "29", + ["5930"] = "30", + ["5931"] = "31", + ["5932"] = "32", + ["5933"] = "33", + ["5934"] = "34", + ["5935"] = "35", + ["5936"] = "36", + ["5937"] = "37", + ["5938"] = "38", + ["5939"] = "39", + ["5940"] = "40", + ["5941"] = "41", + ["5942"] = "42", + ["5943"] = "43", + ["5944"] = "44", + ["5945"] = "45", + ["5946"] = "46", + ["5947"] = "47", + ["5948"] = "48", + ["5949"] = "49", + ["5950"] = "50", + ["5951"] = "51", + ["5952"] = "52", + ["5953"] = "53", + ["5954"] = "54", + ["5955"] = "55", + ["5956"] = "56", + ["5957"] = "57", + ["5958"] = "58", + ["5959"] = "59", + ["5960"] = "60", + ["5961"] = "61", + ["5962"] = "62", + ["5963"] = "63", + ["5964"] = "64", + ["5965"] = "65", + ["5966"] = "66", + ["5967"] = "67", + ["5968"] = "68", + ["5969"] = "69", + ["5970"] = "70", + ["5971"] = "71", + ["5972"] = "72", + ["5973"] = "73", + ["5974"] = "74", + ["5975"] = "75", + ["5976"] = "76", + ["5977"] = "77", + ["5978"] = "78", + ["5979"] = "79", + ["5980"] = "80", + ["5981"] = "81", + ["5982"] = "82", + ["5983"] = "83", + ["5984"] = "84", + ["5985"] = "85", + ["5986"] = "86", + ["5987"] = "87", + ["5988"] = "88", + ["5989"] = "89", + ["5990"] = "90", + ["5991"] = "91", + ["5992"] = "92", + ["5993"] = "93", + ["5994"] = "94", + ["5995"] = "95", + ["5996"] = "96", + ["5997"] = "97", + ["5998"] = "98", + ["5999"] = "99", + ["6000"] = "99", + ["6001"] = "1", + ["6002"] = "2", + ["6003"] = "3", + ["6004"] = "4", + ["6005"] = "5", + ["6006"] = "6", + ["6007"] = "7", + ["6008"] = "8", + ["6009"] = "9", + ["6000"] = "10", + ["6011"] = "11", + ["6012"] = "12", + ["6013"] = "13", + ["6014"] = "14", + ["6015"] = "15", + ["6016"] = "16", + ["6017"] = "17", + ["6018"] = "18", + ["6019"] = "19", + ["6020"] = "20", + ["6021"] = "21", + ["6022"] = "22", + ["6023"] = "23", + ["6024"] = "24", + ["6025"] = "25", + ["6026"] = "26", + ["6027"] = "27", + ["6028"] = "28", + ["6029"] = "29", + ["6030"] = "30", + ["6031"] = "31", + ["6032"] = "32", + ["6033"] = "33", + ["6034"] = "34", + ["6035"] = "35", + ["6036"] = "36", + ["6037"] = "37", + ["6038"] = "38", + ["6039"] = "39", + ["6040"] = "40", + ["6041"] = "41", + ["6042"] = "42", + ["6043"] = "43", + ["6044"] = "44", + ["6045"] = "45", + ["6046"] = "46", + ["6047"] = "47", + ["6048"] = "48", + ["6049"] = "49", + ["6050"] = "50", + ["6051"] = "51", + ["6052"] = "52", + ["6053"] = "53", + ["6054"] = "54", + ["6055"] = "55", + ["6056"] = "56", + ["6057"] = "57", + ["6058"] = "58", + ["6059"] = "59", + ["6060"] = "60", + ["6061"] = "61", + ["6062"] = "62", + ["6063"] = "63", + ["6064"] = "64", + ["6065"] = "65", + ["6066"] = "66", + ["6067"] = "67", + ["6068"] = "68", + ["6069"] = "69", + ["6070"] = "70", + ["6071"] = "71", + ["6072"] = "72", + ["6073"] = "73", + ["6074"] = "74", + ["6075"] = "75", + ["6076"] = "76", + ["6077"] = "77", + ["6078"] = "78", + ["6079"] = "79", + ["6080"] = "80", + ["6081"] = "81", + ["6082"] = "82", + ["6083"] = "83", + ["6084"] = "84", + ["6085"] = "85", + ["6086"] = "86", + ["6087"] = "87", + ["6088"] = "88", + ["6089"] = "89", + ["6090"] = "90", + ["6091"] = "91", + ["6092"] = "92", + ["6093"] = "93", + ["6094"] = "94", + ["6095"] = "95", + ["6096"] = "96", + ["6097"] = "97", + ["6098"] = "98", + ["6099"] = "99", + ["6100"] = "100", + ["6101"] = "1", + ["6102"] = "2", + ["6103"] = "3", + ["6104"] = "4", + ["6105"] = "5", + ["6106"] = "6", + ["6107"] = "7", + ["6108"] = "8", + ["6109"] = "9", + ["6110"] = "10", + ["6111"] = "11", + ["6112"] = "12", + ["6113"] = "13", + ["6114"] = "14", + ["6115"] = "15", + ["6116"] = "16", + ["6117"] = "17", + ["6118"] = "18", + ["6119"] = "19", + ["6120"] = "20", + ["6121"] = "21", + ["6122"] = "22", + ["6123"] = "23", + ["6124"] = "24", + ["6125"] = "25", + ["6126"] = "26", + ["6127"] = "27", + ["6128"] = "28", + ["6129"] = "29", + ["6130"] = "30", + ["6131"] = "31", + ["6132"] = "32", + ["6133"] = "33", + ["6134"] = "34", + ["6135"] = "35", + ["6136"] = "36", + ["6137"] = "37", + ["6138"] = "38", + ["6139"] = "39", + ["6140"] = "40", + ["6141"] = "41", + ["6142"] = "42", + ["6143"] = "43", + ["6144"] = "44", + ["6145"] = "45", + ["6146"] = "46", + ["6147"] = "47", + ["6148"] = "48", + ["6149"] = "49", + ["6150"] = "50", + ["6151"] = "51", + ["6152"] = "52", + ["6153"] = "53", + ["6154"] = "54", + ["6155"] = "55", + ["6156"] = "56", + ["6157"] = "57", + ["6158"] = "58", + ["6159"] = "59", + ["6160"] = "60", + ["6161"] = "61", + ["6162"] = "62", + ["6163"] = "63", + ["6164"] = "64", + ["6165"] = "65", + ["6166"] = "66", + ["6167"] = "67", + ["6168"] = "68", + ["6169"] = "69", + ["6170"] = "70", + ["6171"] = "71", + ["6172"] = "72", + ["6173"] = "73", + ["6174"] = "74", + ["6175"] = "75", + ["6176"] = "76", + ["6177"] = "77", + ["6178"] = "78", + ["6179"] = "79", + ["6180"] = "80", + ["6181"] = "81", + ["6182"] = "82", + ["6183"] = "83", + ["6184"] = "84", + ["6185"] = "85", + ["6186"] = "86", + ["6187"] = "87", + ["6188"] = "88", + ["6189"] = "89", + ["6190"] = "90", + ["6191"] = "91", + ["6192"] = "92", + ["6193"] = "93", + ["6194"] = "94", + ["6195"] = "95", + ["6196"] = "96", + ["6197"] = "97", + ["6198"] = "98", + ["6199"] = "99", + ["6200"] = "100", + ["6201"] = "1", + ["6202"] = "2", + ["6203"] = "3", + ["6204"] = "4", + ["6205"] = "5", + ["6206"] = "6", + ["6207"] = "7", + ["6208"] = "8", + ["6209"] = "9", + ["6210"] = "10", + ["6211"] = "11", + ["6212"] = "12", + ["6213"] = "13", + ["6214"] = "14", + ["6215"] = "15", + ["6216"] = "16", + ["6217"] = "17", + ["6218"] = "18", + ["6219"] = "19", + ["6220"] = "20", + ["6221"] = "21", + ["6222"] = "22", + ["6223"] = "23", + ["6224"] = "24", + ["6225"] = "25", + ["6226"] = "26", + ["6227"] = "27", + ["6228"] = "28", + ["6229"] = "29", + ["6230"] = "30", + ["6231"] = "31", + ["6232"] = "32", + ["6233"] = "33", + ["6234"] = "34", + ["6235"] = "35", + ["6236"] = "36", + ["6237"] = "37", + ["6238"] = "38", + ["6239"] = "39", + ["6240"] = "40", + ["6241"] = "41", + ["6242"] = "42", + ["6243"] = "43", + ["6244"] = "44", + ["6245"] = "45", + ["6246"] = "46", + ["6247"] = "47", + ["6248"] = "48", + ["6249"] = "49", + ["6250"] = "50", + ["6251"] = "51", + ["6252"] = "52", + ["6253"] = "53", + ["6254"] = "54", + ["6255"] = "55", + ["6256"] = "56", + ["6257"] = "57", + ["6258"] = "58", + ["6259"] = "59", + ["6260"] = "60", + ["6261"] = "61", + ["6262"] = "62", + ["6263"] = "63", + ["6264"] = "64", + ["6265"] = "65", + ["6266"] = "66", + ["6267"] = "67", + ["6268"] = "68", + ["6269"] = "69", + ["6270"] = "70", + ["6271"] = "71", + ["6272"] = "72", + ["6273"] = "73", + ["6274"] = "74", + ["6275"] = "75", + ["6276"] = "76", + ["6277"] = "77", + ["6278"] = "78", + ["6279"] = "79", + ["6280"] = "80", + ["6281"] = "81", + ["6282"] = "82", + ["6283"] = "83", + ["6284"] = "84", + ["6285"] = "85", + ["6286"] = "86", + ["6287"] = "87", + ["6288"] = "88", + ["6289"] = "89", + ["6290"] = "90", + ["6291"] = "91", + ["6292"] = "92", + ["6293"] = "93", + ["6294"] = "94", + ["6295"] = "95", + ["6296"] = "96", + ["6297"] = "97", + ["6298"] = "98", + ["6299"] = "99", + ["6300"] = "100", + ["6301"] = "1", + ["6302"] = "2", + ["6303"] = "3", + ["6304"] = "4", + ["6305"] = "5", + ["6306"] = "6", + ["6307"] = "7", + ["6308"] = "8", + ["6309"] = "9", + ["6310"] = "10", + ["6311"] = "11", + ["6312"] = "12", + ["6313"] = "13", + ["6314"] = "14", + ["6315"] = "15", + ["6316"] = "16", + ["6317"] = "17", + ["6318"] = "18", + ["6319"] = "19", + ["6320"] = "20", + ["6321"] = "21", + ["6322"] = "22", + ["6323"] = "23", + ["6324"] = "24", + ["6325"] = "25", + ["6326"] = "26", + ["6327"] = "27", + ["6328"] = "28", + ["6329"] = "29", + ["6330"] = "30", + ["6331"] = "31", + ["6332"] = "32", + ["6333"] = "33", + ["6334"] = "34", + ["6335"] = "35", + ["6336"] = "36", + ["6337"] = "37", + ["6338"] = "38", + ["6339"] = "39", + ["6340"] = "40", + ["6341"] = "41", + ["6342"] = "42", + ["6343"] = "43", + ["6344"] = "44", + ["6345"] = "45", + ["6346"] = "46", + ["6347"] = "47", + ["6348"] = "48", + ["6349"] = "49", + ["6350"] = "50", + ["6351"] = "51", + ["6352"] = "52", + ["6353"] = "53", + ["6354"] = "54", + ["6355"] = "55", + ["6356"] = "56", + ["6357"] = "57", + ["6358"] = "58", + ["6359"] = "59", + ["6360"] = "60", + ["6361"] = "61", + ["6362"] = "62", + ["6363"] = "63", + ["6364"] = "64", + ["6365"] = "65", + ["6366"] = "66", + ["6367"] = "67", + ["6368"] = "68", + ["6369"] = "69", + ["6370"] = "70", + ["6371"] = "71", + ["6372"] = "72", + ["6373"] = "73", + ["6374"] = "74", + ["6375"] = "75", + ["6376"] = "76", + ["6377"] = "77", + ["6378"] = "78", + ["6379"] = "79", + ["6380"] = "80", + ["6381"] = "81", + ["6382"] = "82", + ["6383"] = "83", + ["6384"] = "84", + ["6385"] = "85", + ["6386"] = "86", + ["6387"] = "87", + ["6388"] = "88", + ["6389"] = "89", + ["6390"] = "90", + ["6391"] = "91", + ["6392"] = "92", + ["6393"] = "93", + ["6394"] = "94", + ["6395"] = "95", + ["6396"] = "96", + ["6397"] = "97", + ["6398"] = "98", + ["6399"] = "99", + ["6400"] = "100", + ["6401"] = "1", + ["6402"] = "2", + ["6403"] = "3", + ["6404"] = "4", + ["6405"] = "5", + ["6406"] = "6", + ["6407"] = "7", + ["6408"] = "8", + ["6409"] = "9", + ["6410"] = "10", + ["6411"] = "11", + ["6412"] = "12", + ["6413"] = "13", + ["6414"] = "14", + ["6415"] = "15", + ["6416"] = "16", + ["6417"] = "17", + ["6418"] = "18", + ["6419"] = "19", + ["6420"] = "20", + ["6421"] = "21", + ["6422"] = "22", + ["6423"] = "23", + ["6424"] = "24", + ["6425"] = "25", + ["6426"] = "26", + ["6427"] = "27", + ["6428"] = "28", + ["6429"] = "29", + ["6430"] = "30", + ["6431"] = "31", + ["6432"] = "32", + ["6433"] = "33", + ["6434"] = "34", + ["6435"] = "35", + ["6436"] = "36", + ["6437"] = "37", + ["6438"] = "38", + ["6439"] = "39", + ["6440"] = "40", + ["6441"] = "41", + ["6442"] = "42", + ["6443"] = "43", + ["6444"] = "44", + ["6445"] = "45", + ["6446"] = "46", + ["6447"] = "47", + ["6448"] = "48", + ["6449"] = "49", + ["6450"] = "50", + ["6451"] = "51", + ["6452"] = "52", + ["6453"] = "53", + ["6454"] = "54", + ["6455"] = "55", + ["6456"] = "56", + ["6457"] = "57", + ["6458"] = "58", + ["6459"] = "59", + ["6460"] = "60", + ["6461"] = "61", + ["6462"] = "62", + ["6463"] = "63", + ["6464"] = "64", + ["6465"] = "65", + ["6466"] = "66", + ["6467"] = "67", + ["6468"] = "68", + ["6469"] = "69", + ["6470"] = "70", + ["6471"] = "71", + ["6472"] = "72", + ["6473"] = "73", + ["6474"] = "74", + ["6475"] = "75", + ["6476"] = "76", + ["6477"] = "77", + ["6478"] = "78", + ["6479"] = "79", + ["6480"] = "80", + ["6481"] = "81", + ["6482"] = "82", + ["6483"] = "83", + ["6484"] = "84", + ["6485"] = "85", + ["6486"] = "86", + ["6487"] = "87", + ["6488"] = "88", + ["6489"] = "89", + ["6490"] = "90", + ["6491"] = "91", + ["6492"] = "92", + ["6493"] = "93", + ["6494"] = "94", + ["6495"] = "95", + ["6496"] = "96", + ["6497"] = "97", + ["6498"] = "98", + ["6499"] = "99", + ["6500"] = "100", + ["6501"] = "1", + ["6502"] = "2", + ["6503"] = "3", + ["6504"] = "4", + ["6505"] = "5", + ["6506"] = "6", + ["6507"] = "7", + ["6508"] = "8", + ["6509"] = "9", + ["6510"] = "10", + ["6511"] = "11", + ["6512"] = "12", + ["6513"] = "13", + ["6514"] = "14", + ["6515"] = "15", + ["6516"] = "16", + ["6517"] = "17", + ["6518"] = "18", + ["6519"] = "19", + ["6520"] = "20", + ["6521"] = "21", + ["6522"] = "22", + ["6523"] = "23", + ["6524"] = "24", + ["6525"] = "25", + ["6526"] = "26", + ["6527"] = "27", + ["6528"] = "28", + ["6529"] = "29", + ["6530"] = "30", + ["6531"] = "31", + ["6532"] = "32", + ["6533"] = "33", + ["6534"] = "34", + ["6535"] = "35", + ["6536"] = "36", + ["6537"] = "37", + ["6538"] = "38", + ["6539"] = "39", + ["6540"] = "40", + ["6541"] = "41", + ["6542"] = "42", + ["6543"] = "43", + ["6544"] = "44", + ["6545"] = "45", + ["6546"] = "46", + ["6547"] = "47", + ["6548"] = "48", + ["6549"] = "49", + ["6550"] = "50", + ["6551"] = "51", + ["6552"] = "52", + ["6553"] = "53", + ["6554"] = "54", + ["6555"] = "55", + ["6556"] = "56", + ["6557"] = "57", + ["6558"] = "58", + ["6559"] = "59", + ["6560"] = "60", + ["6561"] = "61", + ["6562"] = "62", + ["6563"] = "63", + ["6564"] = "64", + ["6565"] = "65", + ["6566"] = "66", + ["6567"] = "67", + ["6568"] = "68", + ["6569"] = "69", + ["6570"] = "70", + ["6571"] = "71", + ["6572"] = "72", + ["6573"] = "73", + ["6574"] = "74", + ["6575"] = "75", + ["6576"] = "76", + ["6577"] = "77", + ["6578"] = "78", + ["6579"] = "79", + ["6580"] = "80", + ["6581"] = "81", + ["6582"] = "82", + ["6583"] = "83", + ["6584"] = "84", + ["6585"] = "85", + ["6586"] = "86", + ["6587"] = "87", + ["6588"] = "88", + ["6589"] = "89", + ["6590"] = "90", + ["6591"] = "91", + ["6592"] = "92", + ["6593"] = "93", + ["6594"] = "94", + ["6595"] = "95", + ["6596"] = "96", + ["6597"] = "97", + ["6598"] = "98", + ["6599"] = "99", + ["6600"] = "100", + ["6601"] = "1", + ["6602"] = "2", + ["6603"] = "3", + ["6604"] = "4", + ["6605"] = "5", + ["6606"] = "6", + ["6607"] = "7", + ["6608"] = "8", + ["6609"] = "9", + ["6610"] = "10", + ["6611"] = "11", + ["6612"] = "12", + ["6613"] = "13", + ["6614"] = "14", + ["6615"] = "15", + ["6616"] = "16", + ["6617"] = "17", + ["6618"] = "18", + ["6619"] = "19", + ["6620"] = "20", + ["6621"] = "21", + ["6622"] = "22", + ["6623"] = "23", + ["6624"] = "24", + ["6625"] = "25", + ["6626"] = "26", + ["6627"] = "27", + ["6628"] = "28", + ["6629"] = "29", + ["6630"] = "30", + ["6631"] = "31", + ["6632"] = "32", + ["6633"] = "33", + ["6634"] = "34", + ["6635"] = "35", + ["6636"] = "36", + ["6637"] = "37", + ["6638"] = "38", + ["6639"] = "39", + ["6640"] = "40", + ["6641"] = "41", + ["6642"] = "42", + ["6643"] = "43", + ["6644"] = "44", + ["6645"] = "45", + ["6646"] = "46", + ["6647"] = "47", + ["6648"] = "48", + ["6649"] = "49", + ["6650"] = "50", + ["6651"] = "51", + ["6652"] = "52", + ["6653"] = "53", + ["6654"] = "54", + ["6655"] = "55", + ["6656"] = "56", + ["6657"] = "57", + ["6658"] = "58", + ["6659"] = "59", + ["6660"] = "60", + ["6661"] = "61", + ["6662"] = "62", + ["6663"] = "63", + ["6664"] = "64", + ["6665"] = "65", + ["6666"] = "66", + ["6667"] = "67", + ["6668"] = "68", + ["6669"] = "69", + ["6670"] = "70", + ["6671"] = "71", + ["6672"] = "72", + ["6673"] = "73", + ["6674"] = "74", + ["6675"] = "75", + ["6676"] = "76", + ["6677"] = "77", + ["6678"] = "78", + ["6679"] = "79", + ["6680"] = "80", + ["6681"] = "81", + ["6682"] = "82", + ["6683"] = "83", + ["6684"] = "84", + ["6685"] = "85", + ["6686"] = "86", + ["6687"] = "87", + ["6688"] = "88", + ["6689"] = "89", + ["6690"] = "90", + ["6691"] = "91", + ["6692"] = "92", + ["6693"] = "93", + ["6694"] = "94", + ["6695"] = "95", + ["6696"] = "96", + ["6697"] = "97", + ["6698"] = "98", + ["6699"] = "99", + ["6700"] = "100", + ["6701"] = "1", + ["6702"] = "2", + ["6703"] = "3", + ["6704"] = "4", + ["6705"] = "5", + ["6706"] = "6", + ["6707"] = "7", + ["6708"] = "8", + ["6709"] = "9", + ["6710"] = "10", + ["6711"] = "11", + ["6712"] = "12", + ["6713"] = "13", + ["6714"] = "14", + ["6715"] = "15", + ["6716"] = "16", + ["6717"] = "17", + ["6718"] = "18", + ["6719"] = "19", + ["6720"] = "20", + ["6721"] = "21", + ["6722"] = "22", + ["6723"] = "23", + ["6724"] = "24", + ["6725"] = "25", + ["6726"] = "26", + ["6727"] = "27", + ["6728"] = "28", + ["6729"] = "29", + ["6730"] = "30", + ["6731"] = "31", + ["6732"] = "32", + ["6733"] = "33", + ["6734"] = "34", + ["6735"] = "35", + ["6736"] = "36", + ["6737"] = "37", + ["6738"] = "38", + ["6739"] = "39", + ["6740"] = "40", + ["6741"] = "41", + ["6742"] = "42", + ["6743"] = "43", + ["6744"] = "44", + ["6745"] = "45", + ["6746"] = "46", + ["6747"] = "47", + ["6748"] = "48", + ["6749"] = "49", + ["6750"] = "50", + ["6751"] = "51", + ["6752"] = "52", + ["6753"] = "53", + ["6754"] = "54", + ["6755"] = "55", + ["6756"] = "56", + ["6757"] = "57", + ["6758"] = "58", + ["6759"] = "59", + ["6760"] = "60", + ["6761"] = "61", + ["6762"] = "62", + ["6763"] = "63", + ["6764"] = "64", + ["6765"] = "65", + ["6766"] = "66", + ["6767"] = "67", + ["6768"] = "68", + ["6769"] = "69", + ["6770"] = "70", + ["6771"] = "71", + ["6772"] = "72", + ["6773"] = "73", + ["6774"] = "74", + ["6775"] = "75", + ["6776"] = "76", + ["6777"] = "77", + ["6778"] = "78", + ["6779"] = "79", + ["6780"] = "80", + ["6781"] = "81", + ["6782"] = "82", + ["6783"] = "83", + ["6784"] = "84", + ["6785"] = "85", + ["6786"] = "86", + ["6787"] = "87", + ["6788"] = "88", + ["6789"] = "89", + ["6790"] = "90", + ["6791"] = "91", + ["6792"] = "92", + ["6793"] = "93", + ["6794"] = "94", + ["6795"] = "95", + ["6796"] = "96", + ["6797"] = "97", + ["6798"] = "98", + ["6799"] = "99", + ["6800"] = "100", + ["6801"] = "1", + ["6802"] = "2", + ["6803"] = "3", + ["6804"] = "4", + ["6805"] = "5", + ["6806"] = "6", + ["6807"] = "7", + ["6808"] = "8", + ["6809"] = "9", + ["6810"] = "10", + ["6811"] = "11", + ["6812"] = "12", + ["6813"] = "13", + ["6814"] = "14", + ["6815"] = "15", + ["6816"] = "16", + ["6817"] = "17", + ["6818"] = "18", + ["6819"] = "19", + ["6820"] = "20", + ["6821"] = "21", + ["6822"] = "22", + ["6823"] = "23", + ["6824"] = "24", + ["6825"] = "25", + ["6826"] = "26", + ["6827"] = "27", + ["6828"] = "28", + ["6829"] = "29", + ["6830"] = "30", + ["6831"] = "31", + ["6832"] = "32", + ["6833"] = "33", + ["6834"] = "34", + ["6835"] = "35", + ["6836"] = "36", + ["6837"] = "37", + ["6838"] = "38", + ["6839"] = "39", + ["6840"] = "40", + ["6841"] = "41", + ["6842"] = "42", + ["6843"] = "43", + ["6844"] = "44", + ["6845"] = "45", + ["6846"] = "46", + ["6847"] = "47", + ["6848"] = "48", + ["6849"] = "49", + ["6850"] = "50", + ["6851"] = "51", + ["6852"] = "52", + ["6853"] = "53", + ["6854"] = "54", + ["6855"] = "55", + ["6856"] = "56", + ["6857"] = "57", + ["6858"] = "58", + ["6859"] = "59", + ["6860"] = "60", + ["6861"] = "61", + ["6862"] = "62", + ["6863"] = "63", + ["6864"] = "64", + ["6865"] = "65", + ["6866"] = "66", + ["6867"] = "67", + ["6868"] = "68", + ["6869"] = "69", + ["6870"] = "70", + ["6871"] = "71", + ["6872"] = "72", + ["6873"] = "73", + ["6874"] = "74", + ["6875"] = "75", + ["6876"] = "76", + ["6877"] = "77", + ["6878"] = "78", + ["6879"] = "79", + ["6880"] = "80", + ["6881"] = "81", + ["6882"] = "82", + ["6883"] = "83", + ["6884"] = "84", + ["6885"] = "85", + ["6886"] = "86", + ["6887"] = "87", + ["6888"] = "88", + ["6889"] = "89", + ["6890"] = "90", + ["6891"] = "91", + ["6892"] = "92", + ["6893"] = "93", + ["6894"] = "94", + ["6895"] = "95", + ["6896"] = "96", + ["6897"] = "97", + ["6898"] = "98", + ["6899"] = "99", + ["6900"] = "100", + ["6901"] = "1", + ["6902"] = "2", + ["6903"] = "3", + ["6904"] = "4", + ["6905"] = "5", + ["6906"] = "6", + ["6907"] = "7", + ["6908"] = "8", + ["6909"] = "9", + ["6910"] = "10", + ["6911"] = "11", + ["6912"] = "12", + ["6913"] = "13", + ["6914"] = "14", + ["6915"] = "15", + ["6916"] = "16", + ["6917"] = "17", + ["6918"] = "18", + ["6919"] = "19", + ["6920"] = "20", + ["6921"] = "21", + ["6922"] = "22", + ["6923"] = "23", + ["6924"] = "24", + ["6925"] = "25", + ["6926"] = "26", + ["6927"] = "27", + ["6928"] = "28", + ["6929"] = "29", + ["6930"] = "30", + ["6931"] = "31", + ["6932"] = "32", + ["6933"] = "33", + ["6934"] = "34", + ["6935"] = "35", + ["6936"] = "36", + ["6937"] = "37", + ["6938"] = "38", + ["6939"] = "39", + ["6940"] = "40", + ["6941"] = "41", + ["6942"] = "42", + ["6943"] = "43", + ["6944"] = "44", + ["6945"] = "45", + ["6946"] = "46", + ["6947"] = "47", + ["6948"] = "48", + ["6949"] = "49", + ["6950"] = "50", + ["6951"] = "51", + ["6952"] = "52", + ["6953"] = "53", + ["6954"] = "54", + ["6955"] = "55", + ["6956"] = "56", + ["6957"] = "57", + ["6958"] = "58", + ["6959"] = "59", + ["6960"] = "60", + ["6961"] = "61", + ["6962"] = "62", + ["6963"] = "63", + ["6964"] = "64", + ["6965"] = "65", + ["6966"] = "66", + ["6967"] = "67", + ["6968"] = "68", + ["6969"] = "69", + ["6970"] = "70", + ["6971"] = "71", + ["6972"] = "72", + ["6973"] = "73", + ["6974"] = "74", + ["6975"] = "75", + ["6976"] = "76", + ["6977"] = "77", + ["6978"] = "78", + ["6979"] = "79", + ["6980"] = "80", + ["6981"] = "81", + ["6982"] = "82", + ["6983"] = "83", + ["6984"] = "84", + ["6985"] = "85", + ["6986"] = "86", + ["6987"] = "87", + ["6988"] = "88", + ["6989"] = "89", + ["6990"] = "90", + ["6991"] = "91", + ["6992"] = "92", + ["6993"] = "93", + ["6994"] = "94", + ["6995"] = "95", + ["6996"] = "96", + ["6997"] = "97", + ["6998"] = "98", + ["6999"] = "99", + ["7000"] = "99", + ["7001"] = "1", + ["7002"] = "2", + ["7003"] = "3", + ["7004"] = "4", + ["7005"] = "5", + ["7006"] = "6", + ["7007"] = "7", + ["7008"] = "8", + ["7009"] = "9", + ["7000"] = "10", + ["7011"] = "11", + ["7012"] = "12", + ["7013"] = "13", + ["7014"] = "14", + ["7015"] = "15", + ["7016"] = "16", + ["7017"] = "17", + ["7018"] = "18", + ["7019"] = "19", + ["7020"] = "20", + ["7021"] = "21", + ["7022"] = "22", + ["7023"] = "23", + ["7024"] = "24", + ["7025"] = "25", + ["7026"] = "26", + ["7027"] = "27", + ["7028"] = "28", + ["7029"] = "29", + ["7030"] = "30", + ["7031"] = "31", + ["7032"] = "32", + ["7033"] = "33", + ["7034"] = "34", + ["7035"] = "35", + ["7036"] = "36", + ["7037"] = "37", + ["7038"] = "38", + ["7039"] = "39", + ["7040"] = "40", + ["7041"] = "41", + ["7042"] = "42", + ["7043"] = "43", + ["7044"] = "44", + ["7045"] = "45", + ["7046"] = "46", + ["7047"] = "47", + ["7048"] = "48", + ["7049"] = "49", + ["7050"] = "50", + ["7051"] = "51", + ["7052"] = "52", + ["7053"] = "53", + ["7054"] = "54", + ["7055"] = "55", + ["7056"] = "56", + ["7057"] = "57", + ["7058"] = "58", + ["7059"] = "59", + ["7060"] = "60", + ["7061"] = "61", + ["7062"] = "62", + ["7063"] = "63", + ["7064"] = "64", + ["7065"] = "65", + ["7066"] = "66", + ["7067"] = "67", + ["7068"] = "68", + ["7069"] = "69", + ["7070"] = "70", + ["7071"] = "71", + ["7072"] = "72", + ["7073"] = "73", + ["7074"] = "74", + ["7075"] = "75", + ["7076"] = "76", + ["7077"] = "77", + ["7078"] = "78", + ["7079"] = "79", + ["7080"] = "80", + ["7081"] = "81", + ["7082"] = "82", + ["7083"] = "83", + ["7084"] = "84", + ["7085"] = "85", + ["7086"] = "86", + ["7087"] = "87", + ["7088"] = "88", + ["7089"] = "89", + ["7090"] = "90", + ["7091"] = "91", + ["7092"] = "92", + ["7093"] = "93", + ["7094"] = "94", + ["7095"] = "95", + ["7096"] = "96", + ["7097"] = "97", + ["7098"] = "98", + ["7099"] = "99", + ["7100"] = "100", + ["7101"] = "1", + ["7102"] = "2", + ["7103"] = "3", + ["7104"] = "4", + ["7105"] = "5", + ["7106"] = "6", + ["7107"] = "7", + ["7108"] = "8", + ["7109"] = "9", + ["7110"] = "10", + ["7111"] = "11", + ["7112"] = "12", + ["7113"] = "13", + ["7114"] = "14", + ["7115"] = "15", + ["7116"] = "16", + ["7117"] = "17", + ["7118"] = "18", + ["7119"] = "19", + ["7120"] = "20", + ["7121"] = "21", + ["7122"] = "22", + ["7123"] = "23", + ["7124"] = "24", + ["7125"] = "25", + ["7126"] = "26", + ["7127"] = "27", + ["7128"] = "28", + ["7129"] = "29", + ["7130"] = "30", + ["7131"] = "31", + ["7132"] = "32", + ["7133"] = "33", + ["7134"] = "34", + ["7135"] = "35", + ["7136"] = "36", + ["7137"] = "37", + ["7138"] = "38", + ["7139"] = "39", + ["7140"] = "40", + ["7141"] = "41", + ["7142"] = "42", + ["7143"] = "43", + ["7144"] = "44", + ["7145"] = "45", + ["7146"] = "46", + ["7147"] = "47", + ["7148"] = "48", + ["7149"] = "49", + ["7150"] = "50", + ["7151"] = "51", + ["7152"] = "52", + ["7153"] = "53", + ["7154"] = "54", + ["7155"] = "55", + ["7156"] = "56", + ["7157"] = "57", + ["7158"] = "58", + ["7159"] = "59", + ["7160"] = "60", + ["7161"] = "61", + ["7162"] = "62", + ["7163"] = "63", + ["7164"] = "64", + ["7165"] = "65", + ["7166"] = "66", + ["7167"] = "67", + ["7168"] = "68", + ["7169"] = "69", + ["7170"] = "70", + ["7171"] = "71", + ["7172"] = "72", + ["7173"] = "73", + ["7174"] = "74", + ["7175"] = "75", + ["7176"] = "76", + ["7177"] = "77", + ["7178"] = "78", + ["7179"] = "79", + ["7180"] = "80", + ["7181"] = "81", + ["7182"] = "82", + ["7183"] = "83", + ["7184"] = "84", + ["7185"] = "85", + ["7186"] = "86", + ["7187"] = "87", + ["7188"] = "88", + ["7189"] = "89", + ["7190"] = "90", + ["7191"] = "91", + ["7192"] = "92", + ["7193"] = "93", + ["7194"] = "94", + ["7195"] = "95", + ["7196"] = "96", + ["7197"] = "97", + ["7198"] = "98", + ["7199"] = "99", + ["7200"] = "100", + ["7201"] = "1", + ["7202"] = "2", + ["7203"] = "3", + ["7204"] = "4", + ["7205"] = "5", + ["7206"] = "6", + ["7207"] = "7", + ["7208"] = "8", + ["7209"] = "9", + ["7210"] = "10", + ["7211"] = "11", + ["7212"] = "12", + ["7213"] = "13", + ["7214"] = "14", + ["7215"] = "15", + ["7216"] = "16", + ["7217"] = "17", + ["7218"] = "18", + ["7219"] = "19", + ["7220"] = "20", + ["7221"] = "21", + ["7222"] = "22", + ["7223"] = "23", + ["7224"] = "24", + ["7225"] = "25", + ["7226"] = "26", + ["7227"] = "27", + ["7228"] = "28", + ["7229"] = "29", + ["7230"] = "30", + ["7231"] = "31", + ["7232"] = "32", + ["7233"] = "33", + ["7234"] = "34", + ["7235"] = "35", + ["7236"] = "36", + ["7237"] = "37", + ["7238"] = "38", + ["7239"] = "39", + ["7240"] = "40", + ["7241"] = "41", + ["7242"] = "42", + ["7243"] = "43", + ["7244"] = "44", + ["7245"] = "45", + ["7246"] = "46", + ["7247"] = "47", + ["7248"] = "48", + ["7249"] = "49", + ["7250"] = "50", + ["7251"] = "51", + ["7252"] = "52", + ["7253"] = "53", + ["7254"] = "54", + ["7255"] = "55", + ["7256"] = "56", + ["7257"] = "57", + ["7258"] = "58", + ["7259"] = "59", + ["7260"] = "60", + ["7261"] = "61", + ["7262"] = "62", + ["7263"] = "63", + ["7264"] = "64", + ["7265"] = "65", + ["7266"] = "66", + ["7267"] = "67", + ["7268"] = "68", + ["7269"] = "69", + ["7270"] = "70", + ["7271"] = "71", + ["7272"] = "72", + ["7273"] = "73", + ["7274"] = "74", + ["7275"] = "75", + ["7276"] = "76", + ["7277"] = "77", + ["7278"] = "78", + ["7279"] = "79", + ["7280"] = "80", + ["7281"] = "81", + ["7282"] = "82", + ["7283"] = "83", + ["7284"] = "84", + ["7285"] = "85", + ["7286"] = "86", + ["7287"] = "87", + ["7288"] = "88", + ["7289"] = "89", + ["7290"] = "90", + ["7291"] = "91", + ["7292"] = "92", + ["7293"] = "93", + ["7294"] = "94", + ["7295"] = "95", + ["7296"] = "96", + ["7297"] = "97", + ["7298"] = "98", + ["7299"] = "99", + ["7300"] = "100", + ["7301"] = "1", + ["7302"] = "2", + ["7303"] = "3", + ["7304"] = "4", + ["7305"] = "5", + ["7306"] = "6", + ["7307"] = "7", + ["7308"] = "8", + ["7309"] = "9", + ["7310"] = "10", + ["7311"] = "11", + ["7312"] = "12", + ["7313"] = "13", + ["7314"] = "14", + ["7315"] = "15", + ["7316"] = "16", + ["7317"] = "17", + ["7318"] = "18", + ["7319"] = "19", + ["7320"] = "20", + ["7321"] = "21", + ["7322"] = "22", + ["7323"] = "23", + ["7324"] = "24", + ["7325"] = "25", + ["7326"] = "26", + ["7327"] = "27", + ["7328"] = "28", + ["7329"] = "29", + ["7330"] = "30", + ["7331"] = "31", + ["7332"] = "32", + ["7333"] = "33", + ["7334"] = "34", + ["7335"] = "35", + ["7336"] = "36", + ["7337"] = "37", + ["7338"] = "38", + ["7339"] = "39", + ["7340"] = "40", + ["7341"] = "41", + ["7342"] = "42", + ["7343"] = "43", + ["7344"] = "44", + ["7345"] = "45", + ["7346"] = "46", + ["7347"] = "47", + ["7348"] = "48", + ["7349"] = "49", + ["7350"] = "50", + ["7351"] = "51", + ["7352"] = "52", + ["7353"] = "53", + ["7354"] = "54", + ["7355"] = "55", + ["7356"] = "56", + ["7357"] = "57", + ["7358"] = "58", + ["7359"] = "59", + ["7360"] = "60", + ["7361"] = "61", + ["7362"] = "62", + ["7363"] = "63", + ["7364"] = "64", + ["7365"] = "65", + ["7366"] = "66", + ["7367"] = "67", + ["7368"] = "68", + ["7369"] = "69", + ["7370"] = "70", + ["7371"] = "71", + ["7372"] = "72", + ["7373"] = "73", + ["7374"] = "74", + ["7375"] = "75", + ["7376"] = "76", + ["7377"] = "77", + ["7378"] = "78", + ["7379"] = "79", + ["7380"] = "80", + ["7381"] = "81", + ["7382"] = "82", + ["7383"] = "83", + ["7384"] = "84", + ["7385"] = "85", + ["7386"] = "86", + ["7387"] = "87", + ["7388"] = "88", + ["7389"] = "89", + ["7390"] = "90", + ["7391"] = "91", + ["7392"] = "92", + ["7393"] = "93", + ["7394"] = "94", + ["7395"] = "95", + ["7396"] = "96", + ["7397"] = "97", + ["7398"] = "98", + ["7399"] = "99", + ["7400"] = "100", + ["7401"] = "1", + ["7402"] = "2", + ["7403"] = "3", + ["7404"] = "4", + ["7405"] = "5", + ["7406"] = "6", + ["7407"] = "7", + ["7408"] = "8", + ["7409"] = "9", + ["7410"] = "10", + ["7411"] = "11", + ["7412"] = "12", + ["7413"] = "13", + ["7414"] = "14", + ["7415"] = "15", + ["7416"] = "16", + ["7417"] = "17", + ["7418"] = "18", + ["7419"] = "19", + ["7420"] = "20", + ["7421"] = "21", + ["7422"] = "22", + ["7423"] = "23", + ["7424"] = "24", + ["7425"] = "25", + ["7426"] = "26", + ["7427"] = "27", + ["7428"] = "28", + ["7429"] = "29", + ["7430"] = "30", + ["7431"] = "31", + ["7432"] = "32", + ["7433"] = "33", + ["7434"] = "34", + ["7435"] = "35", + ["7436"] = "36", + ["7437"] = "37", + ["7438"] = "38", + ["7439"] = "39", + ["7440"] = "40", + ["7441"] = "41", + ["7442"] = "42", + ["7443"] = "43", + ["7444"] = "44", + ["7445"] = "45", + ["7446"] = "46", + ["7447"] = "47", + ["7448"] = "48", + ["7449"] = "49", + ["7450"] = "50", + ["7451"] = "51", + ["7452"] = "52", + ["7453"] = "53", + ["7454"] = "54", + ["7455"] = "55", + ["7456"] = "56", + ["7457"] = "57", + ["7458"] = "58", + ["7459"] = "59", + ["7460"] = "60", + ["7461"] = "61", + ["7462"] = "62", + ["7463"] = "63", + ["7464"] = "64", + ["7465"] = "65", + ["7466"] = "66", + ["7467"] = "67", + ["7468"] = "68", + ["7469"] = "69", + ["7470"] = "70", + ["7471"] = "71", + ["7472"] = "72", + ["7473"] = "73", + ["7474"] = "74", + ["7475"] = "75", + ["7476"] = "76", + ["7477"] = "77", + ["7478"] = "78", + ["7479"] = "79", + ["7480"] = "80", + ["7481"] = "81", + ["7482"] = "82", + ["7483"] = "83", + ["7484"] = "84", + ["7485"] = "85", + ["7486"] = "86", + ["7487"] = "87", + ["7488"] = "88", + ["7489"] = "89", + ["7490"] = "90", + ["7491"] = "91", + ["7492"] = "92", + ["7493"] = "93", + ["7494"] = "94", + ["7495"] = "95", + ["7496"] = "96", + ["7497"] = "97", + ["7498"] = "98", + ["7499"] = "99", + ["7500"] = "100", + ["7501"] = "1", + ["7502"] = "2", + ["7503"] = "3", + ["7504"] = "4", + ["7505"] = "5", + ["7506"] = "6", + ["7507"] = "7", + ["7508"] = "8", + ["7509"] = "9", + ["7510"] = "10", + ["7511"] = "11", + ["7512"] = "12", + ["7513"] = "13", + ["7514"] = "14", + ["7515"] = "15", + ["7516"] = "16", + ["7517"] = "17", + ["7518"] = "18", + ["7519"] = "19", + ["7520"] = "20", + ["7521"] = "21", + ["7522"] = "22", + ["7523"] = "23", + ["7524"] = "24", + ["7525"] = "25", + ["7526"] = "26", + ["7527"] = "27", + ["7528"] = "28", + ["7529"] = "29", + ["7530"] = "30", + ["7531"] = "31", + ["7532"] = "32", + ["7533"] = "33", + ["7534"] = "34", + ["7535"] = "35", + ["7536"] = "36", + ["7537"] = "37", + ["7538"] = "38", + ["7539"] = "39", + ["7540"] = "40", + ["7541"] = "41", + ["7542"] = "42", + ["7543"] = "43", + ["7544"] = "44", + ["7545"] = "45", + ["7546"] = "46", + ["7547"] = "47", + ["7548"] = "48", + ["7549"] = "49", + ["7550"] = "50", + ["7551"] = "51", + ["7552"] = "52", + ["7553"] = "53", + ["7554"] = "54", + ["7555"] = "55", + ["7556"] = "56", + ["7557"] = "57", + ["7558"] = "58", + ["7559"] = "59", + ["7560"] = "60", + ["7561"] = "61", + ["7562"] = "62", + ["7563"] = "63", + ["7564"] = "64", + ["7565"] = "65", + ["7566"] = "66", + ["7567"] = "67", + ["7568"] = "68", + ["7569"] = "69", + ["7570"] = "70", + ["7571"] = "71", + ["7572"] = "72", + ["7573"] = "73", + ["7574"] = "74", + ["7575"] = "75", + ["7576"] = "76", + ["7577"] = "77", + ["7578"] = "78", + ["7579"] = "79", + ["7580"] = "80", + ["7581"] = "81", + ["7582"] = "82", + ["7583"] = "83", + ["7584"] = "84", + ["7585"] = "85", + ["7586"] = "86", + ["7587"] = "87", + ["7588"] = "88", + ["7589"] = "89", + ["7590"] = "90", + ["7591"] = "91", + ["7592"] = "92", + ["7593"] = "93", + ["7594"] = "94", + ["7595"] = "95", + ["7596"] = "96", + ["7597"] = "97", + ["7598"] = "98", + ["7599"] = "99", + ["7600"] = "100", + ["7601"] = "1", + ["7602"] = "2", + ["7603"] = "3", + ["7604"] = "4", + ["7605"] = "5", + ["7606"] = "6", + ["7607"] = "7", + ["7608"] = "8", + ["7609"] = "9", + ["7610"] = "10", + ["7611"] = "11", + ["7612"] = "12", + ["7613"] = "13", + ["7614"] = "14", + ["7615"] = "15", + ["7616"] = "16", + ["7617"] = "17", + ["7618"] = "18", + ["7619"] = "19", + ["7620"] = "20", + ["7621"] = "21", + ["7622"] = "22", + ["7623"] = "23", + ["7624"] = "24", + ["7625"] = "25", + ["7626"] = "26", + ["7627"] = "27", + ["7628"] = "28", + ["7629"] = "29", + ["7630"] = "30", + ["7631"] = "31", + ["7632"] = "32", + ["7633"] = "33", + ["7634"] = "34", + ["7635"] = "35", + ["7636"] = "36", + ["7637"] = "37", + ["7638"] = "38", + ["7639"] = "39", + ["7640"] = "40", + ["7641"] = "41", + ["7642"] = "42", + ["7643"] = "43", + ["7644"] = "44", + ["7645"] = "45", + ["7646"] = "46", + ["7647"] = "47", + ["7648"] = "48", + ["7649"] = "49", + ["7650"] = "50", + ["7651"] = "51", + ["7652"] = "52", + ["7653"] = "53", + ["7654"] = "54", + ["7655"] = "55", + ["7656"] = "56", + ["7657"] = "57", + ["7658"] = "58", + ["7659"] = "59", + ["7660"] = "60", + ["7661"] = "61", + ["7662"] = "62", + ["7663"] = "63", + ["7664"] = "64", + ["7665"] = "65", + ["7666"] = "66", + ["7667"] = "67", + ["7668"] = "68", + ["7669"] = "69", + ["7670"] = "70", + ["7671"] = "71", + ["7672"] = "72", + ["7673"] = "73", + ["7674"] = "74", + ["7675"] = "75", + ["7676"] = "76", + ["7677"] = "77", + ["7678"] = "78", + ["7679"] = "79", + ["7680"] = "80", + ["7681"] = "81", + ["7682"] = "82", + ["7683"] = "83", + ["7684"] = "84", + ["7685"] = "85", + ["7686"] = "86", + ["7687"] = "87", + ["7688"] = "88", + ["7689"] = "89", + ["7690"] = "90", + ["7691"] = "91", + ["7692"] = "92", + ["7693"] = "93", + ["7694"] = "94", + ["7695"] = "95", + ["7696"] = "96", + ["7697"] = "97", + ["7698"] = "98", + ["7699"] = "99", + ["7700"] = "100", + ["7701"] = "1", + ["7702"] = "2", + ["7703"] = "3", + ["7704"] = "4", + ["7705"] = "5", + ["7706"] = "6", + ["7707"] = "7", + ["7708"] = "8", + ["7709"] = "9", + ["7710"] = "10", + ["7711"] = "11", + ["7712"] = "12", + ["7713"] = "13", + ["7714"] = "14", + ["7715"] = "15", + ["7716"] = "16", + ["7717"] = "17", + ["7718"] = "18", + ["7719"] = "19", + ["7720"] = "20", + ["7721"] = "21", + ["7722"] = "22", + ["7723"] = "23", + ["7724"] = "24", + ["7725"] = "25", + ["7726"] = "26", + ["7727"] = "27", + ["7728"] = "28", + ["7729"] = "29", + ["7730"] = "30", + ["7731"] = "31", + ["7732"] = "32", + ["7733"] = "33", + ["7734"] = "34", + ["7735"] = "35", + ["7736"] = "36", + ["7737"] = "37", + ["7738"] = "38", + ["7739"] = "39", + ["7740"] = "40", + ["7741"] = "41", + ["7742"] = "42", + ["7743"] = "43", + ["7744"] = "44", + ["7745"] = "45", + ["7746"] = "46", + ["7747"] = "47", + ["7748"] = "48", + ["7749"] = "49", + ["7750"] = "50", + ["7751"] = "51", + ["7752"] = "52", + ["7753"] = "53", + ["7754"] = "54", + ["7755"] = "55", + ["7756"] = "56", + ["7757"] = "57", + ["7758"] = "58", + ["7759"] = "59", + ["7760"] = "60", + ["7761"] = "61", + ["7762"] = "62", + ["7763"] = "63", + ["7764"] = "64", + ["7765"] = "65", + ["7766"] = "66", + ["7767"] = "67", + ["7768"] = "68", + ["7769"] = "69", + ["7770"] = "70", + ["7771"] = "71", + ["7772"] = "72", + ["7773"] = "73", + ["7774"] = "74", + ["7775"] = "75", + ["7776"] = "76", + ["7777"] = "77", + ["7778"] = "78", + ["7779"] = "79", + ["7780"] = "80", + ["7781"] = "81", + ["7782"] = "82", + ["7783"] = "83", + ["7784"] = "84", + ["7785"] = "85", + ["7786"] = "86", + ["7787"] = "87", + ["7788"] = "88", + ["7789"] = "89", + ["7790"] = "90", + ["7791"] = "91", + ["7792"] = "92", + ["7793"] = "93", + ["7794"] = "94", + ["7795"] = "95", + ["7796"] = "96", + ["7797"] = "97", + ["7798"] = "98", + ["7799"] = "99", + ["7800"] = "100", + ["7801"] = "1", + ["7802"] = "2", + ["7803"] = "3", + ["7804"] = "4", + ["7805"] = "5", + ["7806"] = "6", + ["7807"] = "7", + ["7808"] = "8", + ["7809"] = "9", + ["7810"] = "10", + ["7811"] = "11", + ["7812"] = "12", + ["7813"] = "13", + ["7814"] = "14", + ["7815"] = "15", + ["7816"] = "16", + ["7817"] = "17", + ["7818"] = "18", + ["7819"] = "19", + ["7820"] = "20", + ["7821"] = "21", + ["7822"] = "22", + ["7823"] = "23", + ["7824"] = "24", + ["7825"] = "25", + ["7826"] = "26", + ["7827"] = "27", + ["7828"] = "28", + ["7829"] = "29", + ["7830"] = "30", + ["7831"] = "31", + ["7832"] = "32", + ["7833"] = "33", + ["7834"] = "34", + ["7835"] = "35", + ["7836"] = "36", + ["7837"] = "37", + ["7838"] = "38", + ["7839"] = "39", + ["7840"] = "40", + ["7841"] = "41", + ["7842"] = "42", + ["7843"] = "43", + ["7844"] = "44", + ["7845"] = "45", + ["7846"] = "46", + ["7847"] = "47", + ["7848"] = "48", + ["7849"] = "49", + ["7850"] = "50", + ["7851"] = "51", + ["7852"] = "52", + ["7853"] = "53", + ["7854"] = "54", + ["7855"] = "55", + ["7856"] = "56", + ["7857"] = "57", + ["7858"] = "58", + ["7859"] = "59", + ["7860"] = "60", + ["7861"] = "61", + ["7862"] = "62", + ["7863"] = "63", + ["7864"] = "64", + ["7865"] = "65", + ["7866"] = "66", + ["7867"] = "67", + ["7868"] = "68", + ["7869"] = "69", + ["7870"] = "70", + ["7871"] = "71", + ["7872"] = "72", + ["7873"] = "73", + ["7874"] = "74", + ["7875"] = "75", + ["7876"] = "76", + ["7877"] = "77", + ["7878"] = "78", + ["7879"] = "79", + ["7880"] = "80", + ["7881"] = "81", + ["7882"] = "82", + ["7883"] = "83", + ["7884"] = "84", + ["7885"] = "85", + ["7886"] = "86", + ["7887"] = "87", + ["7888"] = "88", + ["7889"] = "89", + ["7890"] = "90", + ["7891"] = "91", + ["7892"] = "92", + ["7893"] = "93", + ["7894"] = "94", + ["7895"] = "95", + ["7896"] = "96", + ["7897"] = "97", + ["7898"] = "98", + ["7899"] = "99", + ["7900"] = "100", + ["7901"] = "1", + ["7902"] = "2", + ["7903"] = "3", + ["7904"] = "4", + ["7905"] = "5", + ["7906"] = "6", + ["7907"] = "7", + ["7908"] = "8", + ["7909"] = "9", + ["7910"] = "10", + ["7911"] = "11", + ["7912"] = "12", + ["7913"] = "13", + ["7914"] = "14", + ["7915"] = "15", + ["7916"] = "16", + ["7917"] = "17", + ["7918"] = "18", + ["7919"] = "19", + ["7920"] = "20", + ["7921"] = "21", + ["7922"] = "22", + ["7923"] = "23", + ["7924"] = "24", + ["7925"] = "25", + ["7926"] = "26", + ["7927"] = "27", + ["7928"] = "28", + ["7929"] = "29", + ["7930"] = "30", + ["7931"] = "31", + ["7932"] = "32", + ["7933"] = "33", + ["7934"] = "34", + ["7935"] = "35", + ["7936"] = "36", + ["7937"] = "37", + ["7938"] = "38", + ["7939"] = "39", + ["7940"] = "40", + ["7941"] = "41", + ["7942"] = "42", + ["7943"] = "43", + ["7944"] = "44", + ["7945"] = "45", + ["7946"] = "46", + ["7947"] = "47", + ["7948"] = "48", + ["7949"] = "49", + ["7950"] = "50", + ["7951"] = "51", + ["7952"] = "52", + ["7953"] = "53", + ["7954"] = "54", + ["7955"] = "55", + ["7956"] = "56", + ["7957"] = "57", + ["7958"] = "58", + ["7959"] = "59", + ["7960"] = "60", + ["7961"] = "61", + ["7962"] = "62", + ["7963"] = "63", + ["7964"] = "64", + ["7965"] = "65", + ["7966"] = "66", + ["7967"] = "67", + ["7968"] = "68", + ["7969"] = "69", + ["7970"] = "70", + ["7971"] = "71", + ["7972"] = "72", + ["7973"] = "73", + ["7974"] = "74", + ["7975"] = "75", + ["7976"] = "76", + ["7977"] = "77", + ["7978"] = "78", + ["7979"] = "79", + ["7980"] = "80", + ["7981"] = "81", + ["7982"] = "82", + ["7983"] = "83", + ["7984"] = "84", + ["7985"] = "85", + ["7986"] = "86", + ["7987"] = "87", + ["7988"] = "88", + ["7989"] = "89", + ["7990"] = "90", + ["7991"] = "91", + ["7992"] = "92", + ["7993"] = "93", + ["7994"] = "94", + ["7995"] = "95", + ["7996"] = "96", + ["7997"] = "97", + ["7998"] = "98", + ["7999"] = "99", + ["8000"] = "99", + ["8001"] = "1", + ["8002"] = "2", + ["8003"] = "3", + ["8004"] = "4", + ["8005"] = "5", + ["8006"] = "6", + ["8007"] = "7", + ["8008"] = "8", + ["8009"] = "9", + ["8000"] = "10", + ["8011"] = "11", + ["8012"] = "12", + ["8013"] = "13", + ["8014"] = "14", + ["8015"] = "15", + ["8016"] = "16", + ["8017"] = "17", + ["8018"] = "18", + ["8019"] = "19", + ["8020"] = "20", + ["8021"] = "21", + ["8022"] = "22", + ["8023"] = "23", + ["8024"] = "24", + ["8025"] = "25", + ["8026"] = "26", + ["8027"] = "27", + ["8028"] = "28", + ["8029"] = "29", + ["8030"] = "30", + ["8031"] = "31", + ["8032"] = "32", + ["8033"] = "33", + ["8034"] = "34", + ["8035"] = "35", + ["8036"] = "36", + ["8037"] = "37", + ["8038"] = "38", + ["8039"] = "39", + ["8040"] = "40", + ["8041"] = "41", + ["8042"] = "42", + ["8043"] = "43", + ["8044"] = "44", + ["8045"] = "45", + ["8046"] = "46", + ["8047"] = "47", + ["8048"] = "48", + ["8049"] = "49", + ["8050"] = "50", + ["8051"] = "51", + ["8052"] = "52", + ["8053"] = "53", + ["8054"] = "54", + ["8055"] = "55", + ["8056"] = "56", + ["8057"] = "57", + ["8058"] = "58", + ["8059"] = "59", + ["8060"] = "60", + ["8061"] = "61", + ["8062"] = "62", + ["8063"] = "63", + ["8064"] = "64", + ["8065"] = "65", + ["8066"] = "66", + ["8067"] = "67", + ["8068"] = "68", + ["8069"] = "69", + ["8070"] = "70", + ["8071"] = "71", + ["8072"] = "72", + ["8073"] = "73", + ["8074"] = "74", + ["8075"] = "75", + ["8076"] = "76", + ["8077"] = "77", + ["8078"] = "78", + ["8079"] = "79", + ["8080"] = "80", + ["8081"] = "81", + ["8082"] = "82", + ["8083"] = "83", + ["8084"] = "84", + ["8085"] = "85", + ["8086"] = "86", + ["8087"] = "87", + ["8088"] = "88", + ["8089"] = "89", + ["8090"] = "90", + ["8091"] = "91", + ["8092"] = "92", + ["8093"] = "93", + ["8094"] = "94", + ["8095"] = "95", + ["8096"] = "96", + ["8097"] = "97", + ["8098"] = "98", + ["8099"] = "99", + ["8100"] = "100", + ["8101"] = "1", + ["8102"] = "2", + ["8103"] = "3", + ["8104"] = "4", + ["8105"] = "5", + ["8106"] = "6", + ["8107"] = "7", + ["8108"] = "8", + ["8109"] = "9", + ["8110"] = "10", + ["8111"] = "11", + ["8112"] = "12", + ["8113"] = "13", + ["8114"] = "14", + ["8115"] = "15", + ["8116"] = "16", + ["8117"] = "17", + ["8118"] = "18", + ["8119"] = "19", + ["8120"] = "20", + ["8121"] = "21", + ["8122"] = "22", + ["8123"] = "23", + ["8124"] = "24", + ["8125"] = "25", + ["8126"] = "26", + ["8127"] = "27", + ["8128"] = "28", + ["8129"] = "29", + ["8130"] = "30", + ["8131"] = "31", + ["8132"] = "32", + ["8133"] = "33", + ["8134"] = "34", + ["8135"] = "35", + ["8136"] = "36", + ["8137"] = "37", + ["8138"] = "38", + ["8139"] = "39", + ["8140"] = "40", + ["8141"] = "41", + ["8142"] = "42", + ["8143"] = "43", + ["8144"] = "44", + ["8145"] = "45", + ["8146"] = "46", + ["8147"] = "47", + ["8148"] = "48", + ["8149"] = "49", + ["8150"] = "50", + ["8151"] = "51", + ["8152"] = "52", + ["8153"] = "53", + ["8154"] = "54", + ["8155"] = "55", + ["8156"] = "56", + ["8157"] = "57", + ["8158"] = "58", + ["8159"] = "59", + ["8160"] = "60", + ["8161"] = "61", + ["8162"] = "62", + ["8163"] = "63", + ["8164"] = "64", + ["8165"] = "65", + ["8166"] = "66", + ["8167"] = "67", + ["8168"] = "68", + ["8169"] = "69", + ["8170"] = "70", + ["8171"] = "71", + ["8172"] = "72", + ["8173"] = "73", + ["8174"] = "74", + ["8175"] = "75", + ["8176"] = "76", + ["8177"] = "77", + ["8178"] = "78", + ["8179"] = "79", + ["8180"] = "80", + ["8181"] = "81", + ["8182"] = "82", + ["8183"] = "83", + ["8184"] = "84", + ["8185"] = "85", + ["8186"] = "86", + ["8187"] = "87", + ["8188"] = "88", + ["8189"] = "89", + ["8190"] = "90", + ["8191"] = "91", + ["8192"] = "92", + ["8193"] = "93", + ["8194"] = "94", + ["8195"] = "95", + ["8196"] = "96", + ["8197"] = "97", + ["8198"] = "98", + ["8199"] = "99", + ["8200"] = "100", + ["8201"] = "1", + ["8202"] = "2", + ["8203"] = "3", + ["8204"] = "4", + ["8205"] = "5", + ["8206"] = "6", + ["8207"] = "7", + ["8208"] = "8", + ["8209"] = "9", + ["8210"] = "10", + ["8211"] = "11", + ["8212"] = "12", + ["8213"] = "13", + ["8214"] = "14", + ["8215"] = "15", + ["8216"] = "16", + ["8217"] = "17", + ["8218"] = "18", + ["8219"] = "19", + ["8220"] = "20", + ["8221"] = "21", + ["8222"] = "22", + ["8223"] = "23", + ["8224"] = "24", + ["8225"] = "25", + ["8226"] = "26", + ["8227"] = "27", + ["8228"] = "28", + ["8229"] = "29", + ["8230"] = "30", + ["8231"] = "31", + ["8232"] = "32", + ["8233"] = "33", + ["8234"] = "34", + ["8235"] = "35", + ["8236"] = "36", + ["8237"] = "37", + ["8238"] = "38", + ["8239"] = "39", + ["8240"] = "40", + ["8241"] = "41", + ["8242"] = "42", + ["8243"] = "43", + ["8244"] = "44", + ["8245"] = "45", + ["8246"] = "46", + ["8247"] = "47", + ["8248"] = "48", + ["8249"] = "49", + ["8250"] = "50", + ["8251"] = "51", + ["8252"] = "52", + ["8253"] = "53", + ["8254"] = "54", + ["8255"] = "55", + ["8256"] = "56", + ["8257"] = "57", + ["8258"] = "58", + ["8259"] = "59", + ["8260"] = "60", + ["8261"] = "61", + ["8262"] = "62", + ["8263"] = "63", + ["8264"] = "64", + ["8265"] = "65", + ["8266"] = "66", + ["8267"] = "67", + ["8268"] = "68", + ["8269"] = "69", + ["8270"] = "70", + ["8271"] = "71", + ["8272"] = "72", + ["8273"] = "73", + ["8274"] = "74", + ["8275"] = "75", + ["8276"] = "76", + ["8277"] = "77", + ["8278"] = "78", + ["8279"] = "79", + ["8280"] = "80", + ["8281"] = "81", + ["8282"] = "82", + ["8283"] = "83", + ["8284"] = "84", + ["8285"] = "85", + ["8286"] = "86", + ["8287"] = "87", + ["8288"] = "88", + ["8289"] = "89", + ["8290"] = "90", + ["8291"] = "91", + ["8292"] = "92", + ["8293"] = "93", + ["8294"] = "94", + ["8295"] = "95", + ["8296"] = "96", + ["8297"] = "97", + ["8298"] = "98", + ["8299"] = "99", + ["8300"] = "100", + ["8301"] = "1", + ["8302"] = "2", + ["8303"] = "3", + ["8304"] = "4", + ["8305"] = "5", + ["8306"] = "6", + ["8307"] = "7", + ["8308"] = "8", + ["8309"] = "9", + ["8310"] = "10", + ["8311"] = "11", + ["8312"] = "12", + ["8313"] = "13", + ["8314"] = "14", + ["8315"] = "15", + ["8316"] = "16", + ["8317"] = "17", + ["8318"] = "18", + ["8319"] = "19", + ["8320"] = "20", + ["8321"] = "21", + ["8322"] = "22", + ["8323"] = "23", + ["8324"] = "24", + ["8325"] = "25", + ["8326"] = "26", + ["8327"] = "27", + ["8328"] = "28", + ["8329"] = "29", + ["8330"] = "30", + ["8331"] = "31", + ["8332"] = "32", + ["8333"] = "33", + ["8334"] = "34", + ["8335"] = "35", + ["8336"] = "36", + ["8337"] = "37", + ["8338"] = "38", + ["8339"] = "39", + ["8340"] = "40", + ["8341"] = "41", + ["8342"] = "42", + ["8343"] = "43", + ["8344"] = "44", + ["8345"] = "45", + ["8346"] = "46", + ["8347"] = "47", + ["8348"] = "48", + ["8349"] = "49", + ["8350"] = "50", + ["8351"] = "51", + ["8352"] = "52", + ["8353"] = "53", + ["8354"] = "54", + ["8355"] = "55", + ["8356"] = "56", + ["8357"] = "57", + ["8358"] = "58", + ["8359"] = "59", + ["8360"] = "60", + ["8361"] = "61", + ["8362"] = "62", + ["8363"] = "63", + ["8364"] = "64", + ["8365"] = "65", + ["8366"] = "66", + ["8367"] = "67", + ["8368"] = "68", + ["8369"] = "69", + ["8370"] = "70", + ["8371"] = "71", + ["8372"] = "72", + ["8373"] = "73", + ["8374"] = "74", + ["8375"] = "75", + ["8376"] = "76", + ["8377"] = "77", + ["8378"] = "78", + ["8379"] = "79", + ["8380"] = "80", + ["8381"] = "81", + ["8382"] = "82", + ["8383"] = "83", + ["8384"] = "84", + ["8385"] = "85", + ["8386"] = "86", + ["8387"] = "87", + ["8388"] = "88", + ["8389"] = "89", + ["8390"] = "90", + ["8391"] = "91", + ["8392"] = "92", + ["8393"] = "93", + ["8394"] = "94", + ["8395"] = "95", + ["8396"] = "96", + ["8397"] = "97", + ["8398"] = "98", + ["8399"] = "99", + ["8400"] = "100", + ["8401"] = "1", + ["8402"] = "2", + ["8403"] = "3", + ["8404"] = "4", + ["8405"] = "5", + ["8406"] = "6", + ["8407"] = "7", + ["8408"] = "8", + ["8409"] = "9", + ["8410"] = "10", + ["8411"] = "11", + ["8412"] = "12", + ["8413"] = "13", + ["8414"] = "14", + ["8415"] = "15", + ["8416"] = "16", + ["8417"] = "17", + ["8418"] = "18", + ["8419"] = "19", + ["8420"] = "20", + ["8421"] = "21", + ["8422"] = "22", + ["8423"] = "23", + ["8424"] = "24", + ["8425"] = "25", + ["8426"] = "26", + ["8427"] = "27", + ["8428"] = "28", + ["8429"] = "29", + ["8430"] = "30", + ["8431"] = "31", + ["8432"] = "32", + ["8433"] = "33", + ["8434"] = "34", + ["8435"] = "35", + ["8436"] = "36", + ["8437"] = "37", + ["8438"] = "38", + ["8439"] = "39", + ["8440"] = "40", + ["8441"] = "41", + ["8442"] = "42", + ["8443"] = "43", + ["8444"] = "44", + ["8445"] = "45", + ["8446"] = "46", + ["8447"] = "47", + ["8448"] = "48", + ["8449"] = "49", + ["8450"] = "50", + ["8451"] = "51", + ["8452"] = "52", + ["8453"] = "53", + ["8454"] = "54", + ["8455"] = "55", + ["8456"] = "56", + ["8457"] = "57", + ["8458"] = "58", + ["8459"] = "59", + ["8460"] = "60", + ["8461"] = "61", + ["8462"] = "62", + ["8463"] = "63", + ["8464"] = "64", + ["8465"] = "65", + ["8466"] = "66", + ["8467"] = "67", + ["8468"] = "68", + ["8469"] = "69", + ["8470"] = "70", + ["8471"] = "71", + ["8472"] = "72", + ["8473"] = "73", + ["8474"] = "74", + ["8475"] = "75", + ["8476"] = "76", + ["8477"] = "77", + ["8478"] = "78", + ["8479"] = "79", + ["8480"] = "80", + ["8481"] = "81", + ["8482"] = "82", + ["8483"] = "83", + ["8484"] = "84", + ["8485"] = "85", + ["8486"] = "86", + ["8487"] = "87", + ["8488"] = "88", + ["8489"] = "89", + ["8490"] = "90", + ["8491"] = "91", + ["8492"] = "92", + ["8493"] = "93", + ["8494"] = "94", + ["8495"] = "95", + ["8496"] = "96", + ["8497"] = "97", + ["8498"] = "98", + ["8499"] = "99", + ["8500"] = "100", + ["8501"] = "1", + ["8502"] = "2", + ["8503"] = "3", + ["8504"] = "4", + ["8505"] = "5", + ["8506"] = "6", + ["8507"] = "7", + ["8508"] = "8", + ["8509"] = "9", + ["8510"] = "10", + ["8511"] = "11", + ["8512"] = "12", + ["8513"] = "13", + ["8514"] = "14", + ["8515"] = "15", + ["8516"] = "16", + ["8517"] = "17", + ["8518"] = "18", + ["8519"] = "19", + ["8520"] = "20", + ["8521"] = "21", + ["8522"] = "22", + ["8523"] = "23", + ["8524"] = "24", + ["8525"] = "25", + ["8526"] = "26", + ["8527"] = "27", + ["8528"] = "28", + ["8529"] = "29", + ["8530"] = "30", + ["8531"] = "31", + ["8532"] = "32", + ["8533"] = "33", + ["8534"] = "34", + ["8535"] = "35", + ["8536"] = "36", + ["8537"] = "37", + ["8538"] = "38", + ["8539"] = "39", + ["8540"] = "40", + ["8541"] = "41", + ["8542"] = "42", + ["8543"] = "43", + ["8544"] = "44", + ["8545"] = "45", + ["8546"] = "46", + ["8547"] = "47", + ["8548"] = "48", + ["8549"] = "49", + ["8550"] = "50", + ["8551"] = "51", + ["8552"] = "52", + ["8553"] = "53", + ["8554"] = "54", + ["8555"] = "55", + ["8556"] = "56", + ["8557"] = "57", + ["8558"] = "58", + ["8559"] = "59", + ["8560"] = "60", + ["8561"] = "61", + ["8562"] = "62", + ["8563"] = "63", + ["8564"] = "64", + ["8565"] = "65", + ["8566"] = "66", + ["8567"] = "67", + ["8568"] = "68", + ["8569"] = "69", + ["8570"] = "70", + ["8571"] = "71", + ["8572"] = "72", + ["8573"] = "73", + ["8574"] = "74", + ["8575"] = "75", + ["8576"] = "76", + ["8577"] = "77", + ["8578"] = "78", + ["8579"] = "79", + ["8580"] = "80", + ["8581"] = "81", + ["8582"] = "82", + ["8583"] = "83", + ["8584"] = "84", + ["8585"] = "85", + ["8586"] = "86", + ["8587"] = "87", + ["8588"] = "88", + ["8589"] = "89", + ["8590"] = "90", + ["8591"] = "91", + ["8592"] = "92", + ["8593"] = "93", + ["8594"] = "94", + ["8595"] = "95", + ["8596"] = "96", + ["8597"] = "97", + ["8598"] = "98", + ["8599"] = "99", + ["8600"] = "100", + ["8601"] = "1", + ["8602"] = "2", + ["8603"] = "3", + ["8604"] = "4", + ["8605"] = "5", + ["8606"] = "6", + ["8607"] = "7", + ["8608"] = "8", + ["8609"] = "9", + ["8610"] = "10", + ["8611"] = "11", + ["8612"] = "12", + ["8613"] = "13", + ["8614"] = "14", + ["8615"] = "15", + ["8616"] = "16", + ["8617"] = "17", + ["8618"] = "18", + ["8619"] = "19", + ["8620"] = "20", + ["8621"] = "21", + ["8622"] = "22", + ["8623"] = "23", + ["8624"] = "24", + ["8625"] = "25", + ["8626"] = "26", + ["8627"] = "27", + ["8628"] = "28", + ["8629"] = "29", + ["8630"] = "30", + ["8631"] = "31", + ["8632"] = "32", + ["8633"] = "33", + ["8634"] = "34", + ["8635"] = "35", + ["8636"] = "36", + ["8637"] = "37", + ["8638"] = "38", + ["8639"] = "39", + ["8640"] = "40", + ["8641"] = "41", + ["8642"] = "42", + ["8643"] = "43", + ["8644"] = "44", + ["8645"] = "45", + ["8646"] = "46", + ["8647"] = "47", + ["8648"] = "48", + ["8649"] = "49", + ["8650"] = "50", + ["8651"] = "51", + ["8652"] = "52", + ["8653"] = "53", + ["8654"] = "54", + ["8655"] = "55", + ["8656"] = "56", + ["8657"] = "57", + ["8658"] = "58", + ["8659"] = "59", + ["8660"] = "60", + ["8661"] = "61", + ["8662"] = "62", + ["8663"] = "63", + ["8664"] = "64", + ["8665"] = "65", + ["8666"] = "66", + ["8667"] = "67", + ["8668"] = "68", + ["8669"] = "69", + ["8670"] = "70", + ["8671"] = "71", + ["8672"] = "72", + ["8673"] = "73", + ["8674"] = "74", + ["8675"] = "75", + ["8676"] = "76", + ["8677"] = "77", + ["8678"] = "78", + ["8679"] = "79", + ["8680"] = "80", + ["8681"] = "81", + ["8682"] = "82", + ["8683"] = "83", + ["8684"] = "84", + ["8685"] = "85", + ["8686"] = "86", + ["8687"] = "87", + ["8688"] = "88", + ["8689"] = "89", + ["8690"] = "90", + ["8691"] = "91", + ["8692"] = "92", + ["8693"] = "93", + ["8694"] = "94", + ["8695"] = "95", + ["8696"] = "96", + ["8697"] = "97", + ["8698"] = "98", + ["8699"] = "99", + ["8700"] = "100", + ["8701"] = "1", + ["8702"] = "2", + ["8703"] = "3", + ["8704"] = "4", + ["8705"] = "5", + ["8706"] = "6", + ["8707"] = "7", + ["8708"] = "8", + ["8709"] = "9", + ["8710"] = "10", + ["8711"] = "11", + ["8712"] = "12", + ["8713"] = "13", + ["8714"] = "14", + ["8715"] = "15", + ["8716"] = "16", + ["8717"] = "17", + ["8718"] = "18", + ["8719"] = "19", + ["8720"] = "20", + ["8721"] = "21", + ["8722"] = "22", + ["8723"] = "23", + ["8724"] = "24", + ["8725"] = "25", + ["8726"] = "26", + ["8727"] = "27", + ["8728"] = "28", + ["8729"] = "29", + ["8730"] = "30", + ["8731"] = "31", + ["8732"] = "32", + ["8733"] = "33", + ["8734"] = "34", + ["8735"] = "35", + ["8736"] = "36", + ["8737"] = "37", + ["8738"] = "38", + ["8739"] = "39", + ["8740"] = "40", + ["8741"] = "41", + ["8742"] = "42", + ["8743"] = "43", + ["8744"] = "44", + ["8745"] = "45", + ["8746"] = "46", + ["8747"] = "47", + ["8748"] = "48", + ["8749"] = "49", + ["8750"] = "50", + ["8751"] = "51", + ["8752"] = "52", + ["8753"] = "53", + ["8754"] = "54", + ["8755"] = "55", + ["8756"] = "56", + ["8757"] = "57", + ["8758"] = "58", + ["8759"] = "59", + ["8760"] = "60", + ["8761"] = "61", + ["8762"] = "62", + ["8763"] = "63", + ["8764"] = "64", + ["8765"] = "65", + ["8766"] = "66", + ["8767"] = "67", + ["8768"] = "68", + ["8769"] = "69", + ["8770"] = "70", + ["8771"] = "71", + ["8772"] = "72", + ["8773"] = "73", + ["8774"] = "74", + ["8775"] = "75", + ["8776"] = "76", + ["8777"] = "77", + ["8778"] = "78", + ["8779"] = "79", + ["8780"] = "80", + ["8781"] = "81", + ["8782"] = "82", + ["8783"] = "83", + ["8784"] = "84", + ["8785"] = "85", + ["8786"] = "86", + ["8787"] = "87", + ["8788"] = "88", + ["8789"] = "89", + ["8790"] = "90", + ["8791"] = "91", + ["8792"] = "92", + ["8793"] = "93", + ["8794"] = "94", + ["8795"] = "95", + ["8796"] = "96", + ["8797"] = "97", + ["8798"] = "98", + ["8799"] = "99", + ["8800"] = "100", + ["8801"] = "1", + ["8802"] = "2", + ["8803"] = "3", + ["8804"] = "4", + ["8805"] = "5", + ["8806"] = "6", + ["8807"] = "7", + ["8808"] = "8", + ["8809"] = "9", + ["8810"] = "10", + ["8811"] = "11", + ["8812"] = "12", + ["8813"] = "13", + ["8814"] = "14", + ["8815"] = "15", + ["8816"] = "16", + ["8817"] = "17", + ["8818"] = "18", + ["8819"] = "19", + ["8820"] = "20", + ["8821"] = "21", + ["8822"] = "22", + ["8823"] = "23", + ["8824"] = "24", + ["8825"] = "25", + ["8826"] = "26", + ["8827"] = "27", + ["8828"] = "28", + ["8829"] = "29", + ["8830"] = "30", + ["8831"] = "31", + ["8832"] = "32", + ["8833"] = "33", + ["8834"] = "34", + ["8835"] = "35", + ["8836"] = "36", + ["8837"] = "37", + ["8838"] = "38", + ["8839"] = "39", + ["8840"] = "40", + ["8841"] = "41", + ["8842"] = "42", + ["8843"] = "43", + ["8844"] = "44", + ["8845"] = "45", + ["8846"] = "46", + ["8847"] = "47", + ["8848"] = "48", + ["8849"] = "49", + ["8850"] = "50", + ["8851"] = "51", + ["8852"] = "52", + ["8853"] = "53", + ["8854"] = "54", + ["8855"] = "55", + ["8856"] = "56", + ["8857"] = "57", + ["8858"] = "58", + ["8859"] = "59", + ["8860"] = "60", + ["8861"] = "61", + ["8862"] = "62", + ["8863"] = "63", + ["8864"] = "64", + ["8865"] = "65", + ["8866"] = "66", + ["8867"] = "67", + ["8868"] = "68", + ["8869"] = "69", + ["8870"] = "70", + ["8871"] = "71", + ["8872"] = "72", + ["8873"] = "73", + ["8874"] = "74", + ["8875"] = "75", + ["8876"] = "76", + ["8877"] = "77", + ["8878"] = "78", + ["8879"] = "79", + ["8880"] = "80", + ["8881"] = "81", + ["8882"] = "82", + ["8883"] = "83", + ["8884"] = "84", + ["8885"] = "85", + ["8886"] = "86", + ["8887"] = "87", + ["8888"] = "88", + ["8889"] = "89", + ["8890"] = "90", + ["8891"] = "91", + ["8892"] = "92", + ["8893"] = "93", + ["8894"] = "94", + ["8895"] = "95", + ["8896"] = "96", + ["8897"] = "97", + ["8898"] = "98", + ["8899"] = "99", + ["8900"] = "100", + ["8901"] = "1", + ["8902"] = "2", + ["8903"] = "3", + ["8904"] = "4", + ["8905"] = "5", + ["8906"] = "6", + ["8907"] = "7", + ["8908"] = "8", + ["8909"] = "9", + ["8910"] = "10", + ["8911"] = "11", + ["8912"] = "12", + ["8913"] = "13", + ["8914"] = "14", + ["8915"] = "15", + ["8916"] = "16", + ["8917"] = "17", + ["8918"] = "18", + ["8919"] = "19", + ["8920"] = "20", + ["8921"] = "21", + ["8922"] = "22", + ["8923"] = "23", + ["8924"] = "24", + ["8925"] = "25", + ["8926"] = "26", + ["8927"] = "27", + ["8928"] = "28", + ["8929"] = "29", + ["8930"] = "30", + ["8931"] = "31", + ["8932"] = "32", + ["8933"] = "33", + ["8934"] = "34", + ["8935"] = "35", + ["8936"] = "36", + ["8937"] = "37", + ["8938"] = "38", + ["8939"] = "39", + ["8940"] = "40", + ["8941"] = "41", + ["8942"] = "42", + ["8943"] = "43", + ["8944"] = "44", + ["8945"] = "45", + ["8946"] = "46", + ["8947"] = "47", + ["8948"] = "48", + ["8949"] = "49", + ["8950"] = "50", + ["8951"] = "51", + ["8952"] = "52", + ["8953"] = "53", + ["8954"] = "54", + ["8955"] = "55", + ["8956"] = "56", + ["8957"] = "57", + ["8958"] = "58", + ["8959"] = "59", + ["8960"] = "60", + ["8961"] = "61", + ["8962"] = "62", + ["8963"] = "63", + ["8964"] = "64", + ["8965"] = "65", + ["8966"] = "66", + ["8967"] = "67", + ["8968"] = "68", + ["8969"] = "69", + ["8970"] = "70", + ["8971"] = "71", + ["8972"] = "72", + ["8973"] = "73", + ["8974"] = "74", + ["8975"] = "75", + ["8976"] = "76", + ["8977"] = "77", + ["8978"] = "78", + ["8979"] = "79", + ["8980"] = "80", + ["8981"] = "81", + ["8982"] = "82", + ["8983"] = "83", + ["8984"] = "84", + ["8985"] = "85", + ["8986"] = "86", + ["8987"] = "87", + ["8988"] = "88", + ["8989"] = "89", + ["8990"] = "90", + ["8991"] = "91", + ["8992"] = "92", + ["8993"] = "93", + ["8994"] = "94", + ["8995"] = "95", + ["8996"] = "96", + ["8997"] = "97", + ["8998"] = "98", + ["8999"] = "99", + ["9000"] = "99", + ["9001"] = "1", + ["9002"] = "2", + ["9003"] = "3", + ["9004"] = "4", + ["9005"] = "5", + ["9006"] = "6", + ["9007"] = "7", + ["9008"] = "8", + ["9009"] = "9", + ["9000"] = "10", + ["9011"] = "11", + ["9012"] = "12", + ["9013"] = "13", + ["9014"] = "14", + ["9015"] = "15", + ["9016"] = "16", + ["9017"] = "17", + ["9018"] = "18", + ["9019"] = "19", + ["9020"] = "20", + ["9021"] = "21", + ["9022"] = "22", + ["9023"] = "23", + ["9024"] = "24", + ["9025"] = "25", + ["9026"] = "26", + ["9027"] = "27", + ["9028"] = "28", + ["9029"] = "29", + ["9030"] = "30", + ["9031"] = "31", + ["9032"] = "32", + ["9033"] = "33", + ["9034"] = "34", + ["9035"] = "35", + ["9036"] = "36", + ["9037"] = "37", + ["9038"] = "38", + ["9039"] = "39", + ["9040"] = "40", + ["9041"] = "41", + ["9042"] = "42", + ["9043"] = "43", + ["9044"] = "44", + ["9045"] = "45", + ["9046"] = "46", + ["9047"] = "47", + ["9048"] = "48", + ["9049"] = "49", + ["9050"] = "50", + ["9051"] = "51", + ["9052"] = "52", + ["9053"] = "53", + ["9054"] = "54", + ["9055"] = "55", + ["9056"] = "56", + ["9057"] = "57", + ["9058"] = "58", + ["9059"] = "59", + ["9060"] = "60", + ["9061"] = "61", + ["9062"] = "62", + ["9063"] = "63", + ["9064"] = "64", + ["9065"] = "65", + ["9066"] = "66", + ["9067"] = "67", + ["9068"] = "68", + ["9069"] = "69", + ["9070"] = "70", + ["9071"] = "71", + ["9072"] = "72", + ["9073"] = "73", + ["9074"] = "74", + ["9075"] = "75", + ["9076"] = "76", + ["9077"] = "77", + ["9078"] = "78", + ["9079"] = "79", + ["9080"] = "80", + ["9081"] = "81", + ["9082"] = "82", + ["9083"] = "83", + ["9084"] = "84", + ["9085"] = "85", + ["9086"] = "86", + ["9087"] = "87", + ["9088"] = "88", + ["9089"] = "89", + ["9090"] = "90", + ["9091"] = "91", + ["9092"] = "92", + ["9093"] = "93", + ["9094"] = "94", + ["9095"] = "95", + ["9096"] = "96", + ["9097"] = "97", + ["9098"] = "98", + ["9099"] = "99", + ["9100"] = "100", + ["9101"] = "1", + ["9102"] = "2", + ["9103"] = "3", + ["9104"] = "4", + ["9105"] = "5", + ["9106"] = "6", + ["9107"] = "7", + ["9108"] = "8", + ["9109"] = "9", + ["9110"] = "10", + ["9111"] = "11", + ["9112"] = "12", + ["9113"] = "13", + ["9114"] = "14", + ["9115"] = "15", + ["9116"] = "16", + ["9117"] = "17", + ["9118"] = "18", + ["9119"] = "19", + ["9120"] = "20", + ["9121"] = "21", + ["9122"] = "22", + ["9123"] = "23", + ["9124"] = "24", + ["9125"] = "25", + ["9126"] = "26", + ["9127"] = "27", + ["9128"] = "28", + ["9129"] = "29", + ["9130"] = "30", + ["9131"] = "31", + ["9132"] = "32", + ["9133"] = "33", + ["9134"] = "34", + ["9135"] = "35", + ["9136"] = "36", + ["9137"] = "37", + ["9138"] = "38", + ["9139"] = "39", + ["9140"] = "40", + ["9141"] = "41", + ["9142"] = "42", + ["9143"] = "43", + ["9144"] = "44", + ["9145"] = "45", + ["9146"] = "46", + ["9147"] = "47", + ["9148"] = "48", + ["9149"] = "49", + ["9150"] = "50", + ["9151"] = "51", + ["9152"] = "52", + ["9153"] = "53", + ["9154"] = "54", + ["9155"] = "55", + ["9156"] = "56", + ["9157"] = "57", + ["9158"] = "58", + ["9159"] = "59", + ["9160"] = "60", + ["9161"] = "61", + ["9162"] = "62", + ["9163"] = "63", + ["9164"] = "64", + ["9165"] = "65", + ["9166"] = "66", + ["9167"] = "67", + ["9168"] = "68", + ["9169"] = "69", + ["9170"] = "70", + ["9171"] = "71", + ["9172"] = "72", + ["9173"] = "73", + ["9174"] = "74", + ["9175"] = "75", + ["9176"] = "76", + ["9177"] = "77", + ["9178"] = "78", + ["9179"] = "79", + ["9180"] = "80", + ["9181"] = "81", + ["9182"] = "82", + ["9183"] = "83", + ["9184"] = "84", + ["9185"] = "85", + ["9186"] = "86", + ["9187"] = "87", + ["9188"] = "88", + ["9189"] = "89", + ["9190"] = "90", + ["9191"] = "91", + ["9192"] = "92", + ["9193"] = "93", + ["9194"] = "94", + ["9195"] = "95", + ["9196"] = "96", + ["9197"] = "97", + ["9198"] = "98", + ["9199"] = "99", + ["9200"] = "100", + ["9201"] = "1", + ["9202"] = "2", + ["9203"] = "3", + ["9204"] = "4", + ["9205"] = "5", + ["9206"] = "6", + ["9207"] = "7", + ["9208"] = "8", + ["9209"] = "9", + ["9210"] = "10", + ["9211"] = "11", + ["9212"] = "12", + ["9213"] = "13", + ["9214"] = "14", + ["9215"] = "15", + ["9216"] = "16", + ["9217"] = "17", + ["9218"] = "18", + ["9219"] = "19", + ["9220"] = "20", + ["9221"] = "21", + ["9222"] = "22", + ["9223"] = "23", + ["9224"] = "24", + ["9225"] = "25", + ["9226"] = "26", + ["9227"] = "27", + ["9228"] = "28", + ["9229"] = "29", + ["9230"] = "30", + ["9231"] = "31", + ["9232"] = "32", + ["9233"] = "33", + ["9234"] = "34", + ["9235"] = "35", + ["9236"] = "36", + ["9237"] = "37", + ["9238"] = "38", + ["9239"] = "39", + ["9240"] = "40", + ["9241"] = "41", + ["9242"] = "42", + ["9243"] = "43", + ["9244"] = "44", + ["9245"] = "45", + ["9246"] = "46", + ["9247"] = "47", + ["9248"] = "48", + ["9249"] = "49", + ["9250"] = "50", + ["9251"] = "51", + ["9252"] = "52", + ["9253"] = "53", + ["9254"] = "54", + ["9255"] = "55", + ["9256"] = "56", + ["9257"] = "57", + ["9258"] = "58", + ["9259"] = "59", + ["9260"] = "60", + ["9261"] = "61", + ["9262"] = "62", + ["9263"] = "63", + ["9264"] = "64", + ["9265"] = "65", + ["9266"] = "66", + ["9267"] = "67", + ["9268"] = "68", + ["9269"] = "69", + ["9270"] = "70", + ["9271"] = "71", + ["9272"] = "72", + ["9273"] = "73", + ["9274"] = "74", + ["9275"] = "75", + ["9276"] = "76", + ["9277"] = "77", + ["9278"] = "78", + ["9279"] = "79", + ["9280"] = "80", + ["9281"] = "81", + ["9282"] = "82", + ["9283"] = "83", + ["9284"] = "84", + ["9285"] = "85", + ["9286"] = "86", + ["9287"] = "87", + ["9288"] = "88", + ["9289"] = "89", + ["9290"] = "90", + ["9291"] = "91", + ["9292"] = "92", + ["9293"] = "93", + ["9294"] = "94", + ["9295"] = "95", + ["9296"] = "96", + ["9297"] = "97", + ["9298"] = "98", + ["9299"] = "99", + ["9300"] = "100", + ["9301"] = "1", + ["9302"] = "2", + ["9303"] = "3", + ["9304"] = "4", + ["9305"] = "5", + ["9306"] = "6", + ["9307"] = "7", + ["9308"] = "8", + ["9309"] = "9", + ["9310"] = "10", + ["9311"] = "11", + ["9312"] = "12", + ["9313"] = "13", + ["9314"] = "14", + ["9315"] = "15", + ["9316"] = "16", + ["9317"] = "17", + ["9318"] = "18", + ["9319"] = "19", + ["9320"] = "20", + ["9321"] = "21", + ["9322"] = "22", + ["9323"] = "23", + ["9324"] = "24", + ["9325"] = "25", + ["9326"] = "26", + ["9327"] = "27", + ["9328"] = "28", + ["9329"] = "29", + ["9330"] = "30", + ["9331"] = "31", + ["9332"] = "32", + ["9333"] = "33", + ["9334"] = "34", + ["9335"] = "35", + ["9336"] = "36", + ["9337"] = "37", + ["9338"] = "38", + ["9339"] = "39", + ["9340"] = "40", + ["9341"] = "41", + ["9342"] = "42", + ["9343"] = "43", + ["9344"] = "44", + ["9345"] = "45", + ["9346"] = "46", + ["9347"] = "47", + ["9348"] = "48", + ["9349"] = "49", + ["9350"] = "50", + ["9351"] = "51", + ["9352"] = "52", + ["9353"] = "53", + ["9354"] = "54", + ["9355"] = "55", + ["9356"] = "56", + ["9357"] = "57", + ["9358"] = "58", + ["9359"] = "59", + ["9360"] = "60", + ["9361"] = "61", + ["9362"] = "62", + ["9363"] = "63", + ["9364"] = "64", + ["9365"] = "65", + ["9366"] = "66", + ["9367"] = "67", + ["9368"] = "68", + ["9369"] = "69", + ["9370"] = "70", + ["9371"] = "71", + ["9372"] = "72", + ["9373"] = "73", + ["9374"] = "74", + ["9375"] = "75", + ["9376"] = "76", + ["9377"] = "77", + ["9378"] = "78", + ["9379"] = "79", + ["9380"] = "80", + ["9381"] = "81", + ["9382"] = "82", + ["9383"] = "83", + ["9384"] = "84", + ["9385"] = "85", + ["9386"] = "86", + ["9387"] = "87", + ["9388"] = "88", + ["9389"] = "89", + ["9390"] = "90", + ["9391"] = "91", + ["9392"] = "92", + ["9393"] = "93", + ["9394"] = "94", + ["9395"] = "95", + ["9396"] = "96", + ["9397"] = "97", + ["9398"] = "98", + ["9399"] = "99", + ["9400"] = "100", + ["9401"] = "1", + ["9402"] = "2", + ["9403"] = "3", + ["9404"] = "4", + ["9405"] = "5", + ["9406"] = "6", + ["9407"] = "7", + ["9408"] = "8", + ["9409"] = "9", + ["9410"] = "10", + ["9411"] = "11", + ["9412"] = "12", + ["9413"] = "13", + ["9414"] = "14", + ["9415"] = "15", + ["9416"] = "16", + ["9417"] = "17", + ["9418"] = "18", + ["9419"] = "19", + ["9420"] = "20", + ["9421"] = "21", + ["9422"] = "22", + ["9423"] = "23", + ["9424"] = "24", + ["9425"] = "25", + ["9426"] = "26", + ["9427"] = "27", + ["9428"] = "28", + ["9429"] = "29", + ["9430"] = "30", + ["9431"] = "31", + ["9432"] = "32", + ["9433"] = "33", + ["9434"] = "34", + ["9435"] = "35", + ["9436"] = "36", + ["9437"] = "37", + ["9438"] = "38", + ["9439"] = "39", + ["9440"] = "40", + ["9441"] = "41", + ["9442"] = "42", + ["9443"] = "43", + ["9444"] = "44", + ["9445"] = "45", + ["9446"] = "46", + ["9447"] = "47", + ["9448"] = "48", + ["9449"] = "49", + ["9450"] = "50", + ["9451"] = "51", + ["9452"] = "52", + ["9453"] = "53", + ["9454"] = "54", + ["9455"] = "55", + ["9456"] = "56", + ["9457"] = "57", + ["9458"] = "58", + ["9459"] = "59", + ["9460"] = "60", + ["9461"] = "61", + ["9462"] = "62", + ["9463"] = "63", + ["9464"] = "64", + ["9465"] = "65", + ["9466"] = "66", + ["9467"] = "67", + ["9468"] = "68", + ["9469"] = "69", + ["9470"] = "70", + ["9471"] = "71", + ["9472"] = "72", + ["9473"] = "73", + ["9474"] = "74", + ["9475"] = "75", + ["9476"] = "76", + ["9477"] = "77", + ["9478"] = "78", + ["9479"] = "79", + ["9480"] = "80", + ["9481"] = "81", + ["9482"] = "82", + ["9483"] = "83", + ["9484"] = "84", + ["9485"] = "85", + ["9486"] = "86", + ["9487"] = "87", + ["9488"] = "88", + ["9489"] = "89", + ["9490"] = "90", + ["9491"] = "91", + ["9492"] = "92", + ["9493"] = "93", + ["9494"] = "94", + ["9495"] = "95", + ["9496"] = "96", + ["9497"] = "97", + ["9498"] = "98", + ["9499"] = "99", + ["9500"] = "100", + ["9501"] = "1", + ["9502"] = "2", + ["9503"] = "3", + ["9504"] = "4", + ["9505"] = "5", + ["9506"] = "6", + ["9507"] = "7", + ["9508"] = "8", + ["9509"] = "9", + ["9510"] = "10", + ["9511"] = "11", + ["9512"] = "12", + ["9513"] = "13", + ["9514"] = "14", + ["9515"] = "15", + ["9516"] = "16", + ["9517"] = "17", + ["9518"] = "18", + ["9519"] = "19", + ["9520"] = "20", + ["9521"] = "21", + ["9522"] = "22", + ["9523"] = "23", + ["9524"] = "24", + ["9525"] = "25", + ["9526"] = "26", + ["9527"] = "27", + ["9528"] = "28", + ["9529"] = "29", + ["9530"] = "30", + ["9531"] = "31", + ["9532"] = "32", + ["9533"] = "33", + ["9534"] = "34", + ["9535"] = "35", + ["9536"] = "36", + ["9537"] = "37", + ["9538"] = "38", + ["9539"] = "39", + ["9540"] = "40", + ["9541"] = "41", + ["9542"] = "42", + ["9543"] = "43", + ["9544"] = "44", + ["9545"] = "45", + ["9546"] = "46", + ["9547"] = "47", + ["9548"] = "48", + ["9549"] = "49", + ["9550"] = "50", + ["9551"] = "51", + ["9552"] = "52", + ["9553"] = "53", + ["9554"] = "54", + ["9555"] = "55", + ["9556"] = "56", + ["9557"] = "57", + ["9558"] = "58", + ["9559"] = "59", + ["9560"] = "60", + ["9561"] = "61", + ["9562"] = "62", + ["9563"] = "63", + ["9564"] = "64", + ["9565"] = "65", + ["9566"] = "66", + ["9567"] = "67", + ["9568"] = "68", + ["9569"] = "69", + ["9570"] = "70", + ["9571"] = "71", + ["9572"] = "72", + ["9573"] = "73", + ["9574"] = "74", + ["9575"] = "75", + ["9576"] = "76", + ["9577"] = "77", + ["9578"] = "78", + ["9579"] = "79", + ["9580"] = "80", + ["9581"] = "81", + ["9582"] = "82", + ["9583"] = "83", + ["9584"] = "84", + ["9585"] = "85", + ["9586"] = "86", + ["9587"] = "87", + ["9588"] = "88", + ["9589"] = "89", + ["9590"] = "90", + ["9591"] = "91", + ["9592"] = "92", + ["9593"] = "93", + ["9594"] = "94", + ["9595"] = "95", + ["9596"] = "96", + ["9597"] = "97", + ["9598"] = "98", + ["9599"] = "99", + ["9600"] = "100", + ["9601"] = "1", + ["9602"] = "2", + ["9603"] = "3", + ["9604"] = "4", + ["9605"] = "5", + ["9606"] = "6", + ["9607"] = "7", + ["9608"] = "8", + ["9609"] = "9", + ["9610"] = "10", + ["9611"] = "11", + ["9612"] = "12", + ["9613"] = "13", + ["9614"] = "14", + ["9615"] = "15", + ["9616"] = "16", + ["9617"] = "17", + ["9618"] = "18", + ["9619"] = "19", + ["9620"] = "20", + ["9621"] = "21", + ["9622"] = "22", + ["9623"] = "23", + ["9624"] = "24", + ["9625"] = "25", + ["9626"] = "26", + ["9627"] = "27", + ["9628"] = "28", + ["9629"] = "29", + ["9630"] = "30", + ["9631"] = "31", + ["9632"] = "32", + ["9633"] = "33", + ["9634"] = "34", + ["9635"] = "35", + ["9636"] = "36", + ["9637"] = "37", + ["9638"] = "38", + ["9639"] = "39", + ["9640"] = "40", + ["9641"] = "41", + ["9642"] = "42", + ["9643"] = "43", + ["9644"] = "44", + ["9645"] = "45", + ["9646"] = "46", + ["9647"] = "47", + ["9648"] = "48", + ["9649"] = "49", + ["9650"] = "50", + ["9651"] = "51", + ["9652"] = "52", + ["9653"] = "53", + ["9654"] = "54", + ["9655"] = "55", + ["9656"] = "56", + ["9657"] = "57", + ["9658"] = "58", + ["9659"] = "59", + ["9660"] = "60", + ["9661"] = "61", + ["9662"] = "62", + ["9663"] = "63", + ["9664"] = "64", + ["9665"] = "65", + ["9666"] = "66", + ["9667"] = "67", + ["9668"] = "68", + ["9669"] = "69", + ["9670"] = "70", + ["9671"] = "71", + ["9672"] = "72", + ["9673"] = "73", + ["9674"] = "74", + ["9675"] = "75", + ["9676"] = "76", + ["9677"] = "77", + ["9678"] = "78", + ["9679"] = "79", + ["9680"] = "80", + ["9681"] = "81", + ["9682"] = "82", + ["9683"] = "83", + ["9684"] = "84", + ["9685"] = "85", + ["9686"] = "86", + ["9687"] = "87", + ["9688"] = "88", + ["9689"] = "89", + ["9690"] = "90", + ["9691"] = "91", + ["9692"] = "92", + ["9693"] = "93", + ["9694"] = "94", + ["9695"] = "95", + ["9696"] = "96", + ["9697"] = "97", + ["9698"] = "98", + ["9699"] = "99", + ["9700"] = "100", + ["9701"] = "1", + ["9702"] = "2", + ["9703"] = "3", + ["9704"] = "4", + ["9705"] = "5", + ["9706"] = "6", + ["9707"] = "7", + ["9708"] = "8", + ["9709"] = "9", + ["9710"] = "10", + ["9711"] = "11", + ["9712"] = "12", + ["9713"] = "13", + ["9714"] = "14", + ["9715"] = "15", + ["9716"] = "16", + ["9717"] = "17", + ["9718"] = "18", + ["9719"] = "19", + ["9720"] = "20", + ["9721"] = "21", + ["9722"] = "22", + ["9723"] = "23", + ["9724"] = "24", + ["9725"] = "25", + ["9726"] = "26", + ["9727"] = "27", + ["9728"] = "28", + ["9729"] = "29", + ["9730"] = "30", + ["9731"] = "31", + ["9732"] = "32", + ["9733"] = "33", + ["9734"] = "34", + ["9735"] = "35", + ["9736"] = "36", + ["9737"] = "37", + ["9738"] = "38", + ["9739"] = "39", + ["9740"] = "40", + ["9741"] = "41", + ["9742"] = "42", + ["9743"] = "43", + ["9744"] = "44", + ["9745"] = "45", + ["9746"] = "46", + ["9747"] = "47", + ["9748"] = "48", + ["9749"] = "49", + ["9750"] = "50", + ["9751"] = "51", + ["9752"] = "52", + ["9753"] = "53", + ["9754"] = "54", + ["9755"] = "55", + ["9756"] = "56", + ["9757"] = "57", + ["9758"] = "58", + ["9759"] = "59", + ["9760"] = "60", + ["9761"] = "61", + ["9762"] = "62", + ["9763"] = "63", + ["9764"] = "64", + ["9765"] = "65", + ["9766"] = "66", + ["9767"] = "67", + ["9768"] = "68", + ["9769"] = "69", + ["9770"] = "70", + ["9771"] = "71", + ["9772"] = "72", + ["9773"] = "73", + ["9774"] = "74", + ["9775"] = "75", + ["9776"] = "76", + ["9777"] = "77", + ["9778"] = "78", + ["9779"] = "79", + ["9780"] = "80", + ["9781"] = "81", + ["9782"] = "82", + ["9783"] = "83", + ["9784"] = "84", + ["9785"] = "85", + ["9786"] = "86", + ["9787"] = "87", + ["9788"] = "88", + ["9789"] = "89", + ["9790"] = "90", + ["9791"] = "91", + ["9792"] = "92", + ["9793"] = "93", + ["9794"] = "94", + ["9795"] = "95", + ["9796"] = "96", + ["9797"] = "97", + ["9798"] = "98", + ["9799"] = "99", + ["9800"] = "100", + ["9801"] = "1", + ["9802"] = "2", + ["9803"] = "3", + ["9804"] = "4", + ["9805"] = "5", + ["9806"] = "6", + ["9807"] = "7", + ["9808"] = "8", + ["9809"] = "9", + ["9810"] = "10", + ["9811"] = "11", + ["9812"] = "12", + ["9813"] = "13", + ["9814"] = "14", + ["9815"] = "15", + ["9816"] = "16", + ["9817"] = "17", + ["9818"] = "18", + ["9819"] = "19", + ["9820"] = "20", + ["9821"] = "21", + ["9822"] = "22", + ["9823"] = "23", + ["9824"] = "24", + ["9825"] = "25", + ["9826"] = "26", + ["9827"] = "27", + ["9828"] = "28", + ["9829"] = "29", + ["9830"] = "30", + ["9831"] = "31", + ["9832"] = "32", + ["9833"] = "33", + ["9834"] = "34", + ["9835"] = "35", + ["9836"] = "36", + ["9837"] = "37", + ["9838"] = "38", + ["9839"] = "39", + ["9840"] = "40", + ["9841"] = "41", + ["9842"] = "42", + ["9843"] = "43", + ["9844"] = "44", + ["9845"] = "45", + ["9846"] = "46", + ["9847"] = "47", + ["9848"] = "48", + ["9849"] = "49", + ["9850"] = "50", + ["9851"] = "51", + ["9852"] = "52", + ["9853"] = "53", + ["9854"] = "54", + ["9855"] = "55", + ["9856"] = "56", + ["9857"] = "57", + ["9858"] = "58", + ["9859"] = "59", + ["9860"] = "60", + ["9861"] = "61", + ["9862"] = "62", + ["9863"] = "63", + ["9864"] = "64", + ["9865"] = "65", + ["9866"] = "66", + ["9867"] = "67", + ["9868"] = "68", + ["9869"] = "69", + ["9870"] = "70", + ["9871"] = "71", + ["9872"] = "72", + ["9873"] = "73", + ["9874"] = "74", + ["9875"] = "75", + ["9876"] = "76", + ["9877"] = "77", + ["9878"] = "78", + ["9879"] = "79", + ["9880"] = "80", + ["9881"] = "81", + ["9882"] = "82", + ["9883"] = "83", + ["9884"] = "84", + ["9885"] = "85", + ["9886"] = "86", + ["9887"] = "87", + ["9888"] = "88", + ["9889"] = "89", + ["9890"] = "90", + ["9891"] = "91", + ["9892"] = "92", + ["9893"] = "93", + ["9894"] = "94", + ["9895"] = "95", + ["9896"] = "96", + ["9897"] = "97", + ["9898"] = "98", + ["9899"] = "99", + ["9900"] = "100", + ["9901"] = "1", + ["9902"] = "2", + ["9903"] = "3", + ["9904"] = "4", + ["9905"] = "5", + ["9906"] = "6", + ["9907"] = "7", + ["9908"] = "8", + ["9909"] = "9", + ["9910"] = "10", + ["9911"] = "11", + ["9912"] = "12", + ["9913"] = "13", + ["9914"] = "14", + ["9915"] = "15", + ["9916"] = "16", + ["9917"] = "17", + ["9918"] = "18", + ["9919"] = "19", + ["9920"] = "20", + ["9921"] = "21", + ["9922"] = "22", + ["9923"] = "23", + ["9924"] = "24", + ["9925"] = "25", + ["9926"] = "26", + ["9927"] = "27", + ["9928"] = "28", + ["9929"] = "29", + ["9930"] = "30", + ["9931"] = "31", + ["9932"] = "32", + ["9933"] = "33", + ["9934"] = "34", + ["9935"] = "35", + ["9936"] = "36", + ["9937"] = "37", + ["9938"] = "38", + ["9939"] = "39", + ["9940"] = "40", + ["9941"] = "41", + ["9942"] = "42", + ["9943"] = "43", + ["9944"] = "44", + ["9945"] = "45", + ["9946"] = "46", + ["9947"] = "47", + ["9948"] = "48", + ["9949"] = "49", + ["9950"] = "50", + ["9951"] = "51", + ["9952"] = "52", + ["9953"] = "53", + ["9954"] = "54", + ["9955"] = "55", + ["9956"] = "56", + ["9957"] = "57", + ["9958"] = "58", + ["9959"] = "59", + ["9960"] = "60", + ["9961"] = "61", + ["9962"] = "62", + ["9963"] = "63", + ["9964"] = "64", + ["9965"] = "65", + ["9966"] = "66", + ["9967"] = "67", + ["9968"] = "68", + ["9969"] = "69", + ["9970"] = "70", + ["9971"] = "71", + ["9972"] = "72", + ["9973"] = "73", + ["9974"] = "74", + ["9975"] = "75", + ["9976"] = "76", + ["9977"] = "77", + ["9978"] = "78", + ["9979"] = "79", + ["9980"] = "80", + ["9981"] = "81", + ["9982"] = "82", + ["9983"] = "83", + ["9984"] = "84", + ["9985"] = "85", + ["9986"] = "86", + ["9987"] = "87", + ["9988"] = "88", + ["9989"] = "89", + ["9990"] = "90", + ["9991"] = "91", + ["9992"] = "92", + ["9993"] = "93", + ["9994"] = "94", + ["9995"] = "95", + ["9996"] = "96", + ["9997"] = "97", + ["9998"] = "98", + ["9999"] = "99" + }; + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/DynamicObjects.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/DynamicObjects.cs index dd268bec92a9dd..054b57c08762ef 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/DynamicObjects.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/DynamicObjects.cs @@ -59,24 +59,24 @@ static void MethodWithDynamicParameter(dynamic arg) // Roslyn codegen no longer produces a call to Binder.InvokeConstructor. // [ExpectedSharedWarning ("IL2026", "Microsoft.CSharp.RuntimeBinder.Binder.InvokeConstructor")] // [ExpectedWarning ("IL3050", "System.Runtime.CompilerServices.CallSite", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/94427")] - // static void ObjectCreationDynamicArgument () + // static void ObjectCreationDynamicArgument() // { - // dynamic dynamicObject = "Some string"; - // var x = new ClassWithDynamicCtor (dynamicObject); + // dynamic dynamicObject = "Some string"; + // var x = new ClassWithDynamicCtor(dynamicObject); // } // class ClassWithDynamicCtor // { - // public ClassWithDynamicCtor (dynamic arg) - // { - // } + // public ClassWithDynamicCtor(dynamic arg) + // { + // } // } public static void Test() { DynamicArgument(); DynamicParameter(); - // ObjectCreationDynamicArgument (); + // ObjectCreationDynamicArgument(); } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExceptionalDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExceptionalDataFlow.cs index d434db1fd3fca9..bb3706a8c509ec 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExceptionalDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExceptionalDataFlow.cs @@ -545,7 +545,7 @@ public static void CatchInTry() [ExpectedWarning("IL2072", nameof(RequireAll2) + "(Type)", nameof(GetWithPublicMethods) + "()")] [ExpectedWarning("IL2072", nameof(RequireAll2) + "(Type)", nameof(GetWithPublicFields) + "()")] // The bug was producing this warning: - // [ExpectedSharedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicConstructors) + "()")] + // [ExpectedSharedWarning("IL2072", nameof(RequireAll2) + "(Type)", nameof(GetWithPublicConstructors) + "()")] // Trimmer merges branches going forward. [ExpectedWarning("IL2072", nameof(RequireAll1) + "(Type)", nameof(GetWithPublicMethods) + "()", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/117157")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExponentialDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExponentialDataFlow.cs index badd61dd4b4a0b..d1669023705be7 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExponentialDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExponentialDataFlow.cs @@ -123,26 +123,26 @@ class GenericTypeWithRequires< public static void Test() { Type[] types = new Type[20] { - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int), - typeof (int) + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int), + typeof(int) }; if (Condition) types[0] = typeof(T); if (Condition) types[1] = typeof(T); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureGuardAttributeDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureGuardAttributeDataFlow.cs index 7b5a4c4841310d..a1f20d06c9a8ef 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureGuardAttributeDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureGuardAttributeDataFlow.cs @@ -2,9 +2,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Runtime.CompilerServices; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using ILLink.RoslynAnalyzer; using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Cases.Expectations.Helpers; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs index a5383715ea0e2a..9a635d9a6acf78 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs @@ -4,8 +4,8 @@ using System; using System.Diagnostics.CodeAnalysis; using Mono.Linker.Tests.Cases.Expectations.Assertions; -using Mono.Linker.Tests.Cases.Expectations.Metadata; using Mono.Linker.Tests.Cases.Expectations.Helpers; +using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.DataFlow { @@ -262,7 +262,7 @@ public static void Test() } private static void RequirePublicMethods( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] string s) { } @@ -335,7 +335,7 @@ class UnsupportedType [ExpectedWarning("IL2098")] static void RequirePublicFields( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] UnsupportedType unsupportedTypeInstance) { } @@ -367,7 +367,7 @@ public StringRef(ref string s) [ExpectedWarning("IL2098")] static void RequirePublicFields( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] ref string s) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs index a6902efc2062d8..e18798ba61d412 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs @@ -49,6 +49,11 @@ public static void Main() TestNoWarningsInRUCMethod(); TestNoWarningsInRUCType(); TestGenericParameterFlowsToNestedType.Test(); + + TestInstanceMethodOnValueType(); + TestValueTypeBox(); + TestMkrefAny(); + TestInArray(); } static void TestSingleGenericParameterOnType() @@ -214,7 +219,6 @@ static void TestDerivedTypeWithOpenGenericOnBaseWithRUCOnBase() new DerivedTypeWithOpenGenericOnBaseWithRUCOnBase(); } - [ExpectedWarning("IL2109", nameof(BaseTypeWithOpenGenericDAMTAndRUC))] [ExpectedWarning("IL2091", nameof(BaseTypeWithOpenGenericDAMTAndRUC))] [ExpectedWarning("IL2091", nameof(IGenericInterfaceTypeWithRequirements))] class DerivedTypeWithOpenGenericOnBaseWithRUCOnBase : BaseTypeWithOpenGenericDAMTAndRUC, IGenericInterfaceTypeWithRequirements @@ -714,7 +718,7 @@ public static void StaticPartialInstantiation() } [ExpectedWarning("IL2091", - [nameof (TOuter), + [nameof(TOuter), "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter", "TMethods", "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.StaticRequiresMultipleGenericParams()"], Tool.Analyzer, "")] @@ -852,6 +856,58 @@ static void TestNoWarningsInRUCType() rucType.VirtualMethodRequiresPublicMethods(); } + [ExpectedWarning("IL2091", "RequiresParameterlessCtor", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning("IL2091", "RequiresParameterlessCtor", Tool.Trimmer, "")] + [ExpectedWarning("IL2091", "RequiresParameterlessCtor", Tool.Trimmer, "")] + static void TestInstanceMethodOnValueType() + { + default(RequiresParameterlessCtor).Do(); + } + + [ExpectedWarning("IL2091", "RequiresParameterlessCtor", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning("IL2091", "RequiresParameterlessCtor", Tool.Trimmer, "")] + [ExpectedWarning("IL2091", "RequiresParameterlessCtor", Tool.Trimmer, "")] + [ExpectedWarning("IL2091", "IRequireParameterlessCtor", Tool.Trimmer, "")] + [ExpectedWarning("IL2091", "IRequireParameterlessCtor", Tool.Trimmer, "")] + static void TestValueTypeBox() + { + if (default(RequiresParameterlessCtor) is IRequireParameterlessCtor i) + { + i.Do(); + } + } + + [ExpectedWarning("IL2091", "RequiresParameterlessCtor", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning("IL2091", "RequiresParameterlessCtor", Tool.Trimmer, "")] + [ExpectedWarning("IL2091", "RequiresParameterlessCtor", Tool.Trimmer, "")] + static void TestMkrefAny() + { + RequiresParameterlessCtor val = default; + TypedReference tr = __makeref(val); + // This is a potential box operation, e.g. TypedReference.ToObject(tr); + } + + [ExpectedWarning("IL2091", "RequiresParameterlessCtor", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning("IL2091", "RequiresParameterlessCtor", Tool.Trimmer, "")] + static void TestInArray() + { + var arr = new RequiresParameterlessCtor[1]; + // This is a potential box operation, e.g. arr.GetValue(0) + } + + interface IRequireParameterlessCtor<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T> + { + T Do(); + } + + struct RequiresParameterlessCtor<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T> : IRequireParameterlessCtor + { + public T Do() + { + return Activator.CreateInstance(); + } + } + class TestGenericParameterFlowsToNestedType { class Generic diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs index 5b49a771bf2eb1..7515952791d474 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs @@ -1412,7 +1412,7 @@ class AnnotatedString { static void MethodWithAnnotatedParameter([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] string typeName) { } - [ExpectedWarning("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "TypeWithRUCMethod.PrivateRUCMethod")] static void AnnotatedParameter() { MethodWithAnnotatedParameter("Mono.Linker.Tests.Cases.DataFlow.GenericParameterWarningLocation+MethodBody+TypeWithPrivateMethods`1[[" @@ -1420,7 +1420,7 @@ static void AnnotatedParameter() + "]], test"); } - [ExpectedWarning("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "TypeWithRUCMethod.PrivateRUCMethod")] [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] static string AnnotatedReturnValue() { @@ -1432,7 +1432,7 @@ static string AnnotatedReturnValue() [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] static string _annotatedField; - [ExpectedWarning("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "TypeWithRUCMethod.PrivateRUCMethod")] static void AnnotatedField() { _annotatedField = "Mono.Linker.Tests.Cases.DataFlow.GenericParameterWarningLocation+MethodBody+TypeWithPrivateMethods`1[[" @@ -1450,7 +1450,7 @@ public static void Test() class TypeGetType { - [ExpectedWarning("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "TypeWithRUCMethod.PrivateRUCMethod")] static void SpecificType() { Type.GetType("Mono.Linker.Tests.Cases.DataFlow.GenericParameterWarningLocation+MethodBody+TypeWithPrivateMethods`1[[" diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs index e4d4d807f355e5..aa0da37bbeeef5 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs @@ -170,8 +170,8 @@ public void Method1() { } [RequiresUnreferencedCode("--Method2--")] public void Method2() { } - [ExpectedWarning("IL2026", "--Method1--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] - [ExpectedWarning("IL2026", "--Method2--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "--Method1--")] + [ExpectedWarning("IL2026", "--Method2--")] public static void Test() { Type.GetType("Mono.Linker.Tests.Cases.DataFlow." + nameof(GetTypeDataFlow) + "+" + nameof(TypeWithWarnings)).RequiresPublicMethods(); @@ -185,7 +185,7 @@ class OverConstTypeName [RequiresUnreferencedCode("--Method1--")] public void Method1() { } - [ExpectedWarning("IL2026", "--Method1--", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "--Method1--")] public static void Test() { Type.GetType(s_ConstTypeName).RequiresPublicMethods(); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/IReflectDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/IReflectDataflow.cs index 0269e758967253..d4917e93c84179 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/IReflectDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/IReflectDataflow.cs @@ -142,8 +142,8 @@ class MyReflectOverType : MyReflect [Kept] public MyReflectOverType( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] Type type) { _underlyingType = type; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlow.cs index c50d8b97c6be0e..d15e18f44662b0 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlow.cs @@ -28,12 +28,14 @@ public static void Main() TestBranchMergeSwitch(); TestBranchMergeTry(); TestBranchMergeCatch(); + TestIsPattern(); + TestRecursivePattern(); // The remaining tests illustrate current limitations of the analysis // that we might be able to lift in the future. // These are overly conservative (extraneous warnings) - // https://github.com/dotnet/linker/issues/2550 + // https://github.com/dotnet/linker/issues/2550 TestBranchGoto(); TestBranchIf(); TestBranchIfElse(); @@ -54,6 +56,43 @@ public static void Main() TestBackwardEdgeWithLdElem(); } + [ExpectedWarning( + "IL2072", + nameof(GetWithPublicMethods), + nameof(DataFlowStringExtensions.RequiresPublicFields) + )] + public static void TestIsPattern() + { + if (GetWithPublicMethods() is string str) + { + str.RequiresPublicFields(); // warn + } + + if (GetWithPublicMethods() is string str2) + { + str2.RequiresPublicMethods(); // no warn + } + } + + [ExpectedWarning( + "IL2072", + nameof(PropertyWithPublicMethods) + "." + nameof(PropertyWithPublicMethods.PublicProperty), + nameof(DataFlowStringExtensions.RequiresPublicFields) + )] + public static void TestRecursivePattern() + { + var propertyWithPublicMethods = new PropertyWithPublicMethods(); + if (propertyWithPublicMethods is { PublicProperty: string str }) + { + str.RequiresPublicFields(); // warn + } + + if (propertyWithPublicMethods is { PublicProperty: string str2 }) + { + str2.RequiresPublicMethods(); // no warn + } + } + [ExpectedWarning("IL2072", "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicMethods()", nameof(DataFlowStringExtensions) + "." + nameof(DataFlowStringExtensions.RequiresPublicFields) + "(String)")] @@ -493,5 +532,11 @@ public static string GetWithPublicConstructors() { return null; } + + public class PropertyWithPublicMethods + { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + public string PublicProperty { get; set; } + } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs index b400e7abf8512a..cfa1e751c5d245 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs @@ -1,13 +1,17 @@ using System; using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.Reflection; +using System.Runtime.CompilerServices; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.DataFlow { [SkipKeptItemsValidation] [ExpectedNoWarnings] [UnconditionalSuppressMessage("AOT", "IL3050", Justification = "These tests are not targetted at AOT scenarios")] + [SandboxDependency("Dependencies/TestSystemTypeBase.cs")] public class MakeGenericDataFlow { public static void Main() @@ -41,6 +45,9 @@ public static void Test() TestWithMultipleArgumentsWithRequirements(); + MakeGenericWithThis.Test(); + MakeGenericWithFields.Test(); + MakeGenericWithObjectGetType.Test(); NewConstraint.Test(); StructConstraint.Test(); UnmanagedConstraint.Test(); @@ -174,6 +181,189 @@ class GenericWithMultipleArgumentsWithRequirements< { } + class MakeGenericWithThis + { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] + static TypeDerived fieldAnnotated; + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + static TypeDerived fieldMisannotated; + static TypeDerived fieldUnannotated; + + [ExpectedWarning("IL2065", "MakeGenericFromThis_Annotated()")] + [ExpectedWarning("IL2065", "MakeGenericFromThis_Misannotated()")] + public static void Test() + { + new TypeDerived().MakeGenericFromThis_Annotated(); + new TypeDerived().MakeGenericFromThis_Unannotated(); + new TypeDerived().MakeGenericFromThis_Misannotated(); + } + + class TypeDerived : TestSystemTypeBase + { + [ExpectedWarning("IL2086", "GenericWithPublicFieldsArgument", "'this'")] + public void MakeGenericFromThis_Unannotated() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(this); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] + public void MakeGenericFromThis_Annotated() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(this); + } + + [ExpectedWarning("IL2086", "GenericWithPublicFieldsArgument", "'this'")] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + public void MakeGenericFromThis_Misannotated() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(this); + } + } + } + + class MakeGenericWithFields + { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] + static Type AnnotatedField; + static Type UnannotatedField; + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + static Type MisannotatedField; + + public static void Test() + { + TestAnnotated(); + TestUnannotated(); + TestMisannotated(); + } + + public static void TestAnnotated() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(AnnotatedField); + } + + [ExpectedWarning("IL2081", "GenericWithPublicFieldsArgument", nameof(UnannotatedField))] + public static void TestUnannotated() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(UnannotatedField); + } + + [ExpectedWarning("IL2081", "GenericWithPublicFieldsArgument", nameof(MisannotatedField))] + public static void TestMisannotated() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(MisannotatedField); + } + } + + class MakeGenericWithObjectGetType + { + static AnnotatedType s_annotatedType = new(); + static UnannotatedType s_unannotatedType = new(); + static MisannotatedType s_misannotatedType = new(); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] + class AnnotatedType + { + public void MakeGenericFromThis() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(this.GetType()); + } + } + + class UnannotatedType + { + [ExpectedWarning("IL2076", "GenericWithPublicFieldsArgument", "System.Object.GetType()")] + public void MakeGenericFromThis() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(this.GetType()); + } + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + class MisannotatedType + { + [ExpectedWarning("IL2076", "GenericWithPublicFieldsArgument", "System.Object.GetType()")] + public void MakeGenericWithThis() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(this.GetType()); + } + } + + + public static void Test() + { + MakeGenericFromNewObject_Annotated(); + MakeGenericFromNewObject_Unannotated(); + MakeGenericFromNewObject_Misannotated(); + MakeGenericFromParameters_Annotated(new AnnotatedType()); + MakeGenericFromParameters_Unannotated(new UnannotatedType()); + MakeGenericFromParameters_Misannotated(new MisannotatedType()); + MakeGenericFromField_Annotated(); + MakeGenericFromField_Unannotated(); + MakeGenericFromField_Misannotated(); + MakeGenericFromThis_Annotated(); + MakeGenericFromThis_Unannotated(); + MakeGenericFromThis_Misannotated(); + } + + static void MakeGenericFromThis_Annotated() + { + new AnnotatedType().MakeGenericFromThis(); + } + static void MakeGenericFromThis_Unannotated() + { + new UnannotatedType().MakeGenericFromThis(); + } + static void MakeGenericFromThis_Misannotated() + { + new MisannotatedType().MakeGenericWithThis(); + } + + static void MakeGenericFromNewObject_Annotated() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(new AnnotatedType().GetType()); + } + [ExpectedWarning("IL2076", "GenericWithPublicFieldsArgument", "System.Object.GetType()")] + static void MakeGenericFromNewObject_Unannotated() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(new UnannotatedType().GetType()); + } + [ExpectedWarning("IL2076", "GenericWithPublicFieldsArgument", "System.Object.GetType()")] + static void MakeGenericFromNewObject_Misannotated() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(new MisannotatedType().GetType()); + } + + static void MakeGenericFromParameters_Annotated(AnnotatedType annotatedType) + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(annotatedType.GetType()); + } + [ExpectedWarning("IL2076", "GenericWithPublicFieldsArgument", "System.Object.GetType()")] + static void MakeGenericFromParameters_Unannotated(UnannotatedType unannotatedType) + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(unannotatedType.GetType()); + } + [ExpectedWarning("IL2076", "GenericWithPublicFieldsArgument", "System.Object.GetType()")] + static void MakeGenericFromParameters_Misannotated(MisannotatedType misannotatedType) + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(misannotatedType.GetType()); + } + + static void MakeGenericFromField_Annotated() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(s_annotatedType.GetType()); + } + [ExpectedWarning("IL2076", "GenericWithPublicFieldsArgument", "System.Object.GetType()")] + static void MakeGenericFromField_Unannotated() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(s_unannotatedType.GetType()); + } + [ExpectedWarning("IL2076", "GenericWithPublicFieldsArgument", "System.Object.GetType()")] + static void MakeGenericFromField_Misannotated() + { + typeof(GenericWithPublicFieldsArgument<>).MakeGenericType(s_misannotatedType.GetType()); + } + } + class NewConstraint { class GenericWithNewConstraint where T : new() diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs index 883073760552c7..c0b6ebc50acb08 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs @@ -93,7 +93,7 @@ private PublicParameterlessConstructorType(int i, int j) { } // Not implied by the DynamicallyAccessedMemberTypes logic, but // explicit cctors would be kept by ILLink. // [Kept] - // static PublicParameterlessConstructorType () { } + // static PublicParameterlessConstructorType() { } public void Method1() { } public bool Property1 { get; set; } @@ -166,7 +166,7 @@ private PublicConstructorsType(int i, int j) { } // Not implied by the DynamicallyAccessedMemberTypes logic, but // explicit cctors would be kept by ILLink. // [Kept] - // static PublicConstructorsType () { } + // static PublicConstructorsType() { } public void Method1() { } public bool Property1 { get; set; } @@ -205,7 +205,7 @@ private PublicConstructorsWithInheritedType(int i, int j) { } // Not implied by the DynamicallyAccessedMemberTypes logic, but // explicit cctors would be kept by ILLink. // [Kept] - // static PublicConstructorsType () { } + // static PublicConstructorsType() { } public void Method1() { } public bool Property1 { get; set; } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefParameterDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefParameterDataFlow.cs index cf45a836c757ee..095127d5a194c1 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefParameterDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefParameterDataFlow.cs @@ -59,7 +59,7 @@ public static void Main() // The type.GetMethods call generates a warning because we're not able to correctly track the value of the "this". // (there's a ldind.ref insruction here which we currently don't handle and the "this" becomes unknown) - [UnexpectedWarning("IL2065", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/linker/issues/2158")] + [UnexpectedWarning("IL2065", Tool.All, "https://github.com/dotnet/linker/issues/2158")] static void TestAssignStaticToAnnotatedRefParameter([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] ref Type type) { type = typeof(TestTypeWithRequires); @@ -72,7 +72,7 @@ static void TestAssignStaticToAnnotatedRefParameter([DynamicallyAccessedMembers( // The type.GetMethods call generates a warning because we're not able to correctly track the value of the "this". // (there's a ldind.ref insruction here which we currently don't handle and the "this" becomes unknown) - [UnexpectedWarning("IL2065", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/linker/issues/2158")] + [UnexpectedWarning("IL2065", Tool.All, "https://github.com/dotnet/linker/issues/2158")] static void TestAssignParameterToAnnotatedRefParameter( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] ref Type type, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type typeWithFields) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs index 8710898fbaced3..9e9d50d193ccb8 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs @@ -247,7 +247,7 @@ class UnsupportedType [ExpectedWarning("IL2098", nameof(UnsupportedType))] static void RequirePublicMethods( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] UnsupportedType unsupportedTypeInstance) { RequirePublicFields(unsupportedTypeInstance); @@ -255,7 +255,7 @@ static void RequirePublicMethods( [ExpectedWarning("IL2098", nameof(UnsupportedType))] static void RequirePublicFields( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] UnsupportedType unsupportedTypeInstance) { } @@ -270,7 +270,7 @@ static void TestUnsupportedType() [ExpectedWarning("IL2098")] static void RequirePublicMethods( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type[] types) { RequirePublicFields(types); @@ -278,7 +278,7 @@ static void RequirePublicMethods( [ExpectedWarning("IL2098")] static void RequirePublicFields( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type[] types) { } @@ -293,7 +293,7 @@ static void TestTypeArray() [ExpectedWarning("IL2098")] static unsafe void RequirePublicMethods( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type* typePtr) { RequirePublicFields(typePtr); @@ -301,7 +301,7 @@ static unsafe void RequirePublicMethods( [ExpectedWarning("IL2098")] static unsafe void RequirePublicFields( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type* typePtr) { } @@ -316,7 +316,7 @@ static unsafe void TestTypePointer() [ExpectedWarning("IL2098")] static void RequirePublicMethods( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T t) where T : Type { RequirePublicFields(t); @@ -324,7 +324,7 @@ static void RequirePublicMethods( [ExpectedWarning("IL2098")] static void RequirePublicFields( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T t) where T : Type { } @@ -339,7 +339,7 @@ static void TestTypeGenericParameter() [ExpectedWarning("IL2098")] static void RequirePublicMethods( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] ref string stringRef) { RequirePublicFields(ref stringRef); @@ -347,7 +347,7 @@ static void RequirePublicMethods( [ExpectedWarning("IL2098")] static void RequirePublicFields( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] ref string stringRef) { } @@ -375,14 +375,14 @@ class AnnotationOnByRefParameter [ExpectedWarning("IL2067")] [ExpectedWarning("IL2067", Tool.NativeAot | Tool.Trimmer, "https://github.com/dotnet/runtime/issues/101734")] static void RequirePublicMethods( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] ref Type typeRef) { RequirePublicFields(ref typeRef); } static void RequirePublicFields( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] ref Type typeRef) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs index 58b7afba28008b..03c88ec3341fff 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs @@ -51,7 +51,7 @@ Type ReturnPublicParameterlessConstructor( Type publicParameterlessConstructorType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type publicConstructorsType, - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type nonPublicConstructorsType) { switch (GetHashCode()) @@ -209,7 +209,7 @@ static UnsupportedType GetWithPublicMethods() [ExpectedWarning("IL2098")] static void RequirePublicFields( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] UnsupportedType unsupportedTypeInstance) { } @@ -234,7 +234,7 @@ class StringRefReturnValue [ExpectedWarning("IL2098")] static void RequirePublicFields( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] ref string s) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs index a414a22aa87b5e..a6f5be0ba15bda 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs @@ -93,9 +93,9 @@ class AnnotationOnUnsupportedThisParameter class UnsupportedType { // The AttributeTargets don't support constructors. - // [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - // public UnsupportedType () { - // RequirePublicFields (this); + // [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + // public UnsupportedType() { + // RequirePublicFields(this); // } [ExpectedWarning("IL2041")] @@ -119,7 +119,7 @@ public static void StaticMethod() [ExpectedWarning("IL2098")] static void RequirePublicFields( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] UnsupportedType unsupportedTypeInstance) { } @@ -129,14 +129,14 @@ static void TestMethodThisParameter() t.GetMethod("foo"); } - // static void TestConstructorThisParameter () { - // new UnsupportedType (); + // static void TestConstructorThisParameter() { + // new UnsupportedType(); // } public static void Test() { TestMethodThisParameter(); - // TestConstructorThisParameter (); + // TestConstructorThisParameter(); UnsupportedType.StaticMethod(); } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ModifierDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ModifierDataFlow.cs index fd7cb70adb249e..a40d9c2652f6e4 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ModifierDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ModifierDataFlow.cs @@ -53,13 +53,13 @@ public static void Main() WriteVolatileType(); WriteVolatileTypeArray(); #if IL_ASSEMBLY_AVAILABLE - Library.ModifierDataFlow.WriteModReqType (); - Library.ModifierDataFlow.WriteMultipleModReqType (); - Library.ModifierDataFlow.WriteModOptType (); - Library.ModifierDataFlow.WriteModReqModOptType (); - Library.ModifierDataFlow.WriteModOptModReqType (); - Library.ModifierDataFlow.WriteModReqArrayType (); - Library.ModifierDataFlow.WriteArrayModReqType (); + Library.ModifierDataFlow.WriteModReqType(); + Library.ModifierDataFlow.WriteMultipleModReqType(); + Library.ModifierDataFlow.WriteModOptType(); + Library.ModifierDataFlow.WriteModReqModOptType(); + Library.ModifierDataFlow.WriteModOptModReqType(); + Library.ModifierDataFlow.WriteModReqArrayType(); + Library.ModifierDataFlow.WriteArrayModReqType(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs index 67ae15ab46fbfb..1ec35b521c33bc 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs @@ -110,7 +110,7 @@ public class RequiresOnNullableMakeGenericType [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] static Type FieldWithMethods; [Kept] - [UnexpectedWarning("IL2080", nameof(UnannotatedField), Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/93800")] + [UnexpectedWarning("IL2080", nameof(UnannotatedField), Tool.All, "https://github.com/dotnet/runtime/issues/93800")] static void Field() { typeof(Nullable<>).MakeGenericType(UnannotatedField).GetMethods(); @@ -118,11 +118,11 @@ static void Field() } [Kept] - [UnexpectedWarning("IL2090", nameof(unannotated), Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/93800")] + [UnexpectedWarning("IL2090", nameof(unannotated), Tool.All, "https://github.com/dotnet/runtime/issues/93800")] static void Parameter( Type unannotated, [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type annotated) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type annotated) { typeof(Nullable<>).MakeGenericType(unannotated).GetMethods(); typeof(Nullable<>).MakeGenericType(annotated).GetMethods(); @@ -140,7 +140,7 @@ static void TypeParameter< } [Kept] - [UnexpectedWarning("IL2075", nameof(GetUnannotated), Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/93800")] + [UnexpectedWarning("IL2075", nameof(GetUnannotated), Tool.All, "https://github.com/dotnet/runtime/issues/93800")] static void ReturnValue() { typeof(Nullable<>).MakeGenericType(GetUnannotated()).GetMethods(); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs index 8adf581c6c5031..6b469c873b7272 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs @@ -905,7 +905,7 @@ class StringRefProperty [ExpectedWarning("IL2098")] static void RequirePublicFields( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] ref string s) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/StaticInterfaceMethodDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/StaticInterfaceMethodDataflow.cs index eb2ad808cd501b..d2836f4a063d94 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/StaticInterfaceMethodDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/StaticInterfaceMethodDataflow.cs @@ -126,7 +126,7 @@ public static void AbstractMethod() { } [Kept] static void DamOnParam( [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeInfoIntrinsics.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeInfoIntrinsics.cs index 3f7b97531f256c..6cbf4c23455fa4 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeInfoIntrinsics.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeInfoIntrinsics.cs @@ -28,15 +28,15 @@ public class TypeInfoIntrinsics public static void Main() { #if IL_ASSEMBLY_AVAILABLE - Library.TypeInfoCalls.TestGetConstructors(typeof(string).GetTypeInfo()); - Library.TypeInfoCalls.TestGetMethods(typeof(string).GetTypeInfo()); - Library.TypeInfoCalls.TestGetFields(typeof(string).GetTypeInfo()); - Library.TypeInfoCalls.TestGetProperties(typeof(string).GetTypeInfo()); - Library.TypeInfoCalls.TestGetEvents(typeof(string).GetTypeInfo()); - Library.TypeInfoCalls.TestGetNestedTypes(typeof(string).GetTypeInfo()); - Library.TypeInfoCalls.TestGetField(typeof(string).GetTypeInfo()); - Library.TypeInfoCalls.TestGetProperty(typeof(string).GetTypeInfo()); - Library.TypeInfoCalls.TestGetEvent(typeof(string).GetTypeInfo()); + Library.TypeInfoCalls.TestGetConstructors(typeof(string).GetTypeInfo()); + Library.TypeInfoCalls.TestGetMethods(typeof(string).GetTypeInfo()); + Library.TypeInfoCalls.TestGetFields(typeof(string).GetTypeInfo()); + Library.TypeInfoCalls.TestGetProperties(typeof(string).GetTypeInfo()); + Library.TypeInfoCalls.TestGetEvents(typeof(string).GetTypeInfo()); + Library.TypeInfoCalls.TestGetNestedTypes(typeof(string).GetTypeInfo()); + Library.TypeInfoCalls.TestGetField(typeof(string).GetTypeInfo()); + Library.TypeInfoCalls.TestGetProperty(typeof(string).GetTypeInfo()); + Library.TypeInfoCalls.TestGetEvent(typeof(string).GetTypeInfo()); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs index 2e00aba0028307..df982c1d58e7bb 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs @@ -60,7 +60,7 @@ class AttributeWithRequirements : Attribute { [Kept] public AttributeWithRequirements( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) { } @@ -124,8 +124,8 @@ class EmptyType [Kept] static void RequirePublicMethods( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs index bd25308b6b9908..c27537d9eeb6ac 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs @@ -41,7 +41,7 @@ public static void Main() RequirePublicMethods(typeof(ImplementationClass)); RequirePublicMethods(typeof(IBaseImplementedInterface)); RequirePublicMethods(typeof(BaseImplementsInterfaceViaDerived)); - RequirePublicMethods(typeof(DerivedWithInterfaceImplementedByBase)); + RequirePublicMethodsAndConstructor(typeof(DerivedWithInterfaceImplementedByBase)); RequirePublicMethods(typeof(VirtualMethodHierarchyDataflowAnnotationValidationTypeTestBase)); RequirePublicMethods(typeof(VirtualMethodHierarchyDataflowAnnotationValidationTypeTestDerived)); RequirePublicMethods(typeof(ITwoInterfacesImplementedByOneMethod_One)); @@ -59,6 +59,10 @@ static void RequirePublicMethods([DynamicallyAccessedMembers(DynamicallyAccessed { } + static void RequirePublicMethodsAndConstructor([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) + { + } + class BaseClass { // === Return values === @@ -76,12 +80,12 @@ class BaseClass // === Method parameters === // This does not check complicated inheritance cases as that is already validated by the return values public virtual void SingleParameterBaseWithDerivedWithout( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type p) { } public virtual void SingleParameterBaseWithDerivedWith_( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type p) { } @@ -90,15 +94,15 @@ public virtual void SingleParameterBaseWithoutDerivedWith_(Type p) { } public virtual void SingleParameterBaseWithoutDerivedWithout(Type p) { } public virtual void SingleParameterBaseWithDerivedWithDifferent( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type p) { } public virtual void MultipleParametersBaseWithDerivedWithout( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type p1BaseWithDerivedWithout, Type p2BaseWithoutDerivedWithout, - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type p3BaseWithDerivedWithout) { } @@ -109,18 +113,18 @@ public virtual void MultipleParametersBaseWithoutDerivedWith( { } public virtual void MultipleParametersBaseWithDerivedWithMatch( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type p1BaseWithDerivedWith, Type p2BaseWithoutDerivedWithout, - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type p3BaseWithDerivedWith) { } public virtual void MultipleParametersBaseWithDerivedWithMismatch( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type p1BaseWithDerivedWithMismatch, Type p2BaseWithoutDerivedWith, - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type p3BaseWithDerivedWithMatch, Type p4NoAnnotations) { } @@ -176,7 +180,7 @@ public override void SingleParameterBaseWithDerivedWithout(Type p) { } [LogDoesNotContain("DerivedClass.SingleParameterBaseWithDerivedWith_")] public override void SingleParameterBaseWithDerivedWith_( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type p) { } @@ -185,7 +189,7 @@ public override void SingleParameterBaseWithDerivedWith_( "don't match overridden parameter 'p' of method 'Mono.Linker.Tests.Cases.DataFlow.VirtualMethodHierarchyDataflowAnnotationValidation.BaseClass.SingleParameterBaseWithoutDerivedWith_(Type)'. " + "All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.")] public override void SingleParameterBaseWithoutDerivedWith_( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type p) { } @@ -197,7 +201,7 @@ public override void SingleParameterBaseWithoutDerivedWithout(Type p) { } "don't match overridden parameter 'p' of method 'Mono.Linker.Tests.Cases.DataFlow.VirtualMethodHierarchyDataflowAnnotationValidation.BaseClass.SingleParameterBaseWithDerivedWithDifferent(Type)'. " + "All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.")] public override void SingleParameterBaseWithDerivedWithDifferent( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type p) { } @@ -215,19 +219,19 @@ public override void MultipleParametersBaseWithDerivedWithout( [LogDoesNotContain(".*'p2BaseWithoutDerivedWithout'.*DerivedClass.*MultipleParametersBaseWithoutDerivedWith.*", regexMatch: true)] [LogContains(".*'p3BaseWithoutDerivedWith'.*DerivedClass.*MultipleParametersBaseWithoutDerivedWith.*", regexMatch: true)] public override void MultipleParametersBaseWithoutDerivedWith( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type p1BaseWithoutDerivedWith, Type p2BaseWithoutDerivedWithout, - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type p3BaseWithoutDerivedWith) { } [LogDoesNotContain("DerivedClass.MultipleParametersBaseWithDerivedWithMatch")] public override void MultipleParametersBaseWithDerivedWithMatch( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type p1BaseWithDerivedWith, Type p2BaseWithoutDerivedWithout, - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type p3BaseWithDerivedWith) { } @@ -236,11 +240,11 @@ public override void MultipleParametersBaseWithDerivedWithMatch( [LogDoesNotContain(".*'p3BaseWithDerivedWithMatch'.*DerivedClass.*MultipleParametersBaseWithDerivedWithMismatch.*", regexMatch: true)] [LogDoesNotContain(".*'p4NoAnnotations'.*DerivedClass.*MultipleParametersBaseWithDerivedWithMismatch.*", regexMatch: true)] public override void MultipleParametersBaseWithDerivedWithMismatch( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type p1BaseWithDerivedWithMismatch, - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type p2BaseWithoutDerivedWith, - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type p3BaseWithDerivedWithMatch, Type p4NoAnnotations) { } @@ -359,7 +363,7 @@ class DerivedOverNoAnnotations : BaseWithNoAnnotations // === Method parameters === [LogContains("DerivedOverNoAnnotations.SingleParameterBaseWithoutDerivedWith_")] public override void SingleParameterBaseWithoutDerivedWith_( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type p) { } @@ -393,12 +397,12 @@ abstract class BaseWithAnnotations // === Method parameters === public virtual void SingleParameterBaseWithDerivedWithout( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type p) { } public virtual void SingleParameterBaseWithDerivedWith_( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type p) { } @@ -433,7 +437,7 @@ public override void SingleParameterBaseWithDerivedWithout(Type p) { } [LogDoesNotContain("DerivedWithNoAnnotations.SingleParameterBaseWithDerivedWith_")] public override void SingleParameterBaseWithDerivedWith_( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type p) { } @@ -468,13 +472,13 @@ interface IBase // === Method parameters === void SingleParameterBaseWithImplementationWith_( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type p); void SingleParameterBaseWithoutImplementationWith_(Type p); void SingleParameterBaseWithImplementationWithout( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type p); void SingleParameterBaseWithoutImplementationWithout(Type p); @@ -526,7 +530,7 @@ abstract class ImplementationClass : IDerived // === Method parameters === [LogDoesNotContain("ImplementationClass.SingleParameterBaseWithImplementationWith_")] public void SingleParameterBaseWithImplementationWith_( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type p) { } @@ -535,7 +539,7 @@ public void SingleParameterBaseWithImplementationWithout(Type p) { } [LogContains("ImplementationClass.SingleParameterBaseWithoutImplementationWith_")] public void SingleParameterBaseWithoutImplementationWith_( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type p) { } @@ -870,252 +874,252 @@ public override void Param(Type t) { } public override Type Return() => typeof(int); } - public static void Test () - { - // https://github.com/dotnet/linker/issues/3133 - // Access the interfaces as well - otherwise NativeAOT can decide - // to not look for overrides since it knows it's making a direct access - // to a method and it doesn't need to know about the base method - // which leads to some warnings not being generated. - // The goal of this test is to validate the generated diagnostics - // so we're forcing the checks to happen with this. - typeof (Library.IAnnotatedMethods).RequiresAll (); - typeof (Library.IUnannotatedMethods).RequiresAll (); - - typeof (ImplIUnannotatedMethodsMismatch).RequiresPublicMethods (); - typeof (ImplIAnnotatedMethodsMismatch).RequiresPublicMethods (); - typeof (DerivedFromAnnotatedMismatch).RequiresPublicMethods (); - typeof (DerivedFromUnannotatedMismatch).RequiresPublicMethods (); - typeof (ImplIUnannotatedMethodsMatch).RequiresPublicMethods (); - typeof (ImplIAnnotatedMethodsMatch).RequiresPublicMethods (); - typeof (DerivedFromAnnotatedMatch).RequiresPublicMethods (); - typeof (DerivedFromUnannotatedMatch).RequiresPublicMethods (); - } - } - - // This is mostly for Native AOT - in that compiler it matters how a method - // is referenced as it will take a different code path to do some of these validations - // The above tests all rely on reflection marking so this test also uses direct calls - class DirectCall - { - abstract class Base - { - [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - public abstract Type NonGenericAbstract ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type); - - [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - public virtual Type NonGenericVirtual ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) => type; - - public abstract void GenericAbstract<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> (); - - public virtual void GenericVirtual<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () { } - - public abstract Type UnannotatedAbstract (Type type); - - public abstract void UnannotatedGenericAbstract (); - } - - class Derived : Base - { - [ExpectedWarning ("IL2092")] - [ExpectedWarning ("IL2093")] - public override Type NonGenericAbstract ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] Type type) => null; - - [ExpectedWarning ("IL2092")] - [ExpectedWarning ("IL2093")] - [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] - public override Type NonGenericVirtual (Type type) => null; - - [ExpectedWarning ("IL2095")] - public override void GenericAbstract () { } - - [ExpectedWarning ("IL2095")] - public override void GenericVirtual<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] T> () { } - - [ExpectedWarning ("IL2092")] - [ExpectedWarning ("IL2093")] - [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - public override Type UnannotatedAbstract ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] Type type) => null; - - [ExpectedWarning ("IL2095")] - public override void UnannotatedGenericAbstract<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] T> () { } - } - - interface IBaseWithDefault - { - void DefaultMethod (Type type); - } - - interface IDerivedWithDefault : IBaseWithDefault - { - [ExpectedWarning ("IL2092")] - [UnexpectedWarning ("IL2092", Tool.Analyzer, "https://github.com/dotnet/linker/issues/3121")] - void IBaseWithDefault.DefaultMethod ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) { } - } - - class ImplDerivedWithDefault : IDerivedWithDefault - { - } - - interface IGvmBase - { - Type UnannotatedGvm (Type type); - Type UnannotatedGvmCalledThroughBase (Type type); - - [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - static abstract Type AnnotatedStaticGvm<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] T> ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] Type type); - - static virtual Type UnannotatedStaticGvm (Type type) => null; - } - - class ImplIGvmBase : IGvmBase - { - // NativeAOT doesn't validate overrides when it can resolve them as direct calls - [ExpectedWarning ("IL2092", Tool.Trimmer | Tool.Analyzer, "")] - [ExpectedWarning ("IL2093", Tool.Trimmer | Tool.Analyzer, "")] - [ExpectedWarning ("IL2095", Tool.Trimmer | Tool.Analyzer, "")] - [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - public Type UnannotatedGvm<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) => null; - - [ExpectedWarning ("IL2092")] - [ExpectedWarning ("IL2093")] - [ExpectedWarning ("IL2095")] - [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - public Type UnannotatedGvmCalledThroughBase<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) => null; - - [ExpectedWarning ("IL2092")] - [ExpectedWarning ("IL2093")] - [ExpectedWarning ("IL2095")] - public static Type AnnotatedStaticGvm (Type type) => null; - - [ExpectedWarning ("IL2092")] - [ExpectedWarning ("IL2093")] - [ExpectedWarning ("IL2095")] - [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - public static Type UnannotatedStaticGvm<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] T> ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] Type type) => null; - } - - static void CallStaticGvm () where TGvmBase : IGvmBase - { - TGvmBase.AnnotatedStaticGvm (typeof (string)); - TGvmBase.UnannotatedStaticGvm (typeof (string)); - } - - public static void Test () - { - Base instance = new Derived (); - instance.NonGenericAbstract (typeof (string)); - instance.NonGenericVirtual (typeof (string)); - instance.GenericAbstract (); - instance.GenericVirtual (); - instance.UnannotatedAbstract (typeof (string)); - instance.UnannotatedGenericAbstract (); - - ((IBaseWithDefault) (new ImplDerivedWithDefault ())).DefaultMethod (typeof (string)); - - ImplIGvmBase impl = new ImplIGvmBase (); - impl.UnannotatedGvm (typeof (string)); - - IGvmBase ibase = (IGvmBase) impl; - ibase.UnannotatedGvmCalledThroughBase (typeof (string)); - - CallStaticGvm (); - } - } - - class RequiresAndDynamicallyAccessedMembersValidation - { - // These tests have both DynamicallyAccessedMembers annotations and Requires annotations. - // This is to reproduce a bug where the virtual method annotations would be validated due to - // the presence of DynamicallyAccessedMembers, but the logic for checking Requires annotations - // was incorrect. The bug didn't manifest with just Requires annotations because the methods wouldn't - // be validated at all for Requires on type. - - class BaseMethodWithRequires - { - [RequiresUnreferencedCode (nameof (MethodWithRequires))] - [RequiresDynamicCode (nameof (MethodWithRequires))] - public virtual void MethodWithRequires ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type t) {} - } - - [RequiresUnreferencedCode (nameof (DerivedTypeWithRequires_BaseMethodWithRequires))] - [RequiresDynamicCode (nameof (DerivedTypeWithRequires_BaseMethodWithRequires))] - class DerivedTypeWithRequires_BaseMethodWithRequires : BaseMethodWithRequires - { - public override void MethodWithRequires ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type t) {} - } - - [ExpectedWarning ("IL2026", nameof (DerivedTypeWithRequires_BaseMethodWithRequires))] - [ExpectedWarning ("IL2026", nameof (DerivedTypeWithRequires_BaseMethodWithRequires.MethodWithRequires))] - [ExpectedWarning ("IL3050", nameof (DerivedTypeWithRequires_BaseMethodWithRequires), Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL3050", nameof (DerivedTypeWithRequires_BaseMethodWithRequires.MethodWithRequires), Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - static void Test_DerivedTypeWithRequires_BaseMethodWithRequires () - { - new DerivedTypeWithRequires_BaseMethodWithRequires ().MethodWithRequires (typeof (int)); - } - - class BaseMethodWithoutRequires - { - public virtual void MethodWithoutRequires ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type t) {} - } - - [RequiresUnreferencedCode (nameof (DerivedTypeWithRequires_BaseMethodWithoutRequires))] - class DerivedTypeWithRequires_BaseMethodWithoutRequires : BaseMethodWithoutRequires - { - public override void MethodWithoutRequires ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type t) {} - } - - [ExpectedWarning ("IL2026", nameof (DerivedTypeWithRequires_BaseMethodWithoutRequires))] - static void Test_DerivedTypeWithRequires_BaseMethodWithoutRequires () - { - new DerivedTypeWithRequires_BaseMethodWithoutRequires ().MethodWithoutRequires (typeof (int)); - } - - public static void Test () - { - Test_DerivedTypeWithRequires_BaseMethodWithRequires (); - Test_DerivedTypeWithRequires_BaseMethodWithoutRequires (); - } - } - - class InstantiatedGeneric - { - class GenericBase { - [ExpectedWarning ("IL2106")] - [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - public virtual T ReturnValue () => default; - } - - class InstantiatedDerived : GenericBase { - public override Type ReturnValue () => null; - } - - public static void Test () - { - new InstantiatedDerived ().ReturnValue (); - } - } - - class AnnotationOnUnsupportedType - { - class UnsupportedType { - [ExpectedWarning ("IL2041")] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - public virtual void UnsupportedAnnotationMismatch () { } - } - - class DerivedUnsupportedType : UnsupportedType { - [ExpectedWarning ("IL2041")] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] - public override void UnsupportedAnnotationMismatch () { } - } - - public static void Test () - { - new DerivedUnsupportedType ().UnsupportedAnnotationMismatch (); - } - } - } + public static void Test () + { + // https://github.com/dotnet/linker/issues/3133 + // Access the interfaces as well - otherwise NativeAOT can decide + // to not look for overrides since it knows it's making a direct access + // to a method and it doesn't need to know about the base method + // which leads to some warnings not being generated. + // The goal of this test is to validate the generated diagnostics + // so we're forcing the checks to happen with this. + typeof (Library.IAnnotatedMethods).RequiresAll (); + typeof (Library.IUnannotatedMethods).RequiresAll (); + + typeof (ImplIUnannotatedMethodsMismatch).RequiresPublicMethods (); + typeof (ImplIAnnotatedMethodsMismatch).RequiresPublicMethods (); + typeof (DerivedFromAnnotatedMismatch).RequiresPublicMethods (); + typeof (DerivedFromUnannotatedMismatch).RequiresPublicMethods (); + typeof (ImplIUnannotatedMethodsMatch).RequiresPublicMethods (); + typeof (ImplIAnnotatedMethodsMatch).RequiresPublicMethods (); + typeof (DerivedFromAnnotatedMatch).RequiresPublicMethods (); + typeof (DerivedFromUnannotatedMatch).RequiresPublicMethods (); + } + } + + // This is mostly for Native AOT - in that compiler it matters how a method + // is referenced as it will take a different code path to do some of these validations + // The above tests all rely on reflection marking so this test also uses direct calls + class DirectCall + { + abstract class Base + { + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + public abstract Type NonGenericAbstract ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type); + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + public virtual Type NonGenericVirtual ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) => type; + + public abstract void GenericAbstract<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> (); + + public virtual void GenericVirtual<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () { } + + public abstract Type UnannotatedAbstract (Type type); + + public abstract void UnannotatedGenericAbstract (); + } + + class Derived : Base + { + [ExpectedWarning ("IL2092")] + [ExpectedWarning ("IL2093")] + public override Type NonGenericAbstract ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] Type type) => null; + + [ExpectedWarning ("IL2092")] + [ExpectedWarning ("IL2093")] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] + public override Type NonGenericVirtual (Type type) => null; + + [ExpectedWarning ("IL2095")] + public override void GenericAbstract () { } + + [ExpectedWarning ("IL2095")] + public override void GenericVirtual<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] T> () { } + + [ExpectedWarning ("IL2092")] + [ExpectedWarning ("IL2093")] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + public override Type UnannotatedAbstract ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] Type type) => null; + + [ExpectedWarning ("IL2095")] + public override void UnannotatedGenericAbstract<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] T> () { } + } + + interface IBaseWithDefault + { + void DefaultMethod (Type type); + } + + interface IDerivedWithDefault : IBaseWithDefault + { + [ExpectedWarning ("IL2092")] + [UnexpectedWarning ("IL2092", Tool.Analyzer, "https://github.com/dotnet/linker/issues/3121")] + void IBaseWithDefault.DefaultMethod ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) { } + } + + class ImplDerivedWithDefault : IDerivedWithDefault + { + } + + interface IGvmBase + { + Type UnannotatedGvm (Type type); + Type UnannotatedGvmCalledThroughBase (Type type); + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + static abstract Type AnnotatedStaticGvm<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] T> ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] Type type); + + static virtual Type UnannotatedStaticGvm (Type type) => null; + } + + class ImplIGvmBase : IGvmBase + { + // NativeAOT doesn't validate overrides when it can resolve them as direct calls + [ExpectedWarning ("IL2092", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2093", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2095", Tool.Trimmer | Tool.Analyzer, "")] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + public Type UnannotatedGvm<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) => null; + + [ExpectedWarning ("IL2092")] + [ExpectedWarning ("IL2093")] + [ExpectedWarning ("IL2095")] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + public Type UnannotatedGvmCalledThroughBase<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) => null; + + [ExpectedWarning ("IL2092")] + [ExpectedWarning ("IL2093")] + [ExpectedWarning ("IL2095")] + public static Type AnnotatedStaticGvm (Type type) => null; + + [ExpectedWarning ("IL2092")] + [ExpectedWarning ("IL2093")] + [ExpectedWarning ("IL2095")] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + public static Type UnannotatedStaticGvm<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] T> ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] Type type) => null; + } + + static void CallStaticGvm () where TGvmBase : IGvmBase + { + TGvmBase.AnnotatedStaticGvm (typeof (string)); + TGvmBase.UnannotatedStaticGvm (typeof (string)); + } + + public static void Test () + { + Base instance = new Derived (); + instance.NonGenericAbstract (typeof (string)); + instance.NonGenericVirtual (typeof (string)); + instance.GenericAbstract (); + instance.GenericVirtual (); + instance.UnannotatedAbstract (typeof (string)); + instance.UnannotatedGenericAbstract (); + + ((IBaseWithDefault) (new ImplDerivedWithDefault ())).DefaultMethod (typeof (string)); + + ImplIGvmBase impl = new ImplIGvmBase (); + impl.UnannotatedGvm (typeof (string)); + + IGvmBase ibase = (IGvmBase) impl; + ibase.UnannotatedGvmCalledThroughBase (typeof (string)); + + CallStaticGvm (); + } + } + + class RequiresAndDynamicallyAccessedMembersValidation + { + // These tests have both DynamicallyAccessedMembers annotations and Requires annotations. + // This is to reproduce a bug where the virtual method annotations would be validated due to + // the presence of DynamicallyAccessedMembers, but the logic for checking Requires annotations + // was incorrect. The bug didn't manifest with just Requires annotations because the methods wouldn't + // be validated at all for Requires on type. + + class BaseMethodWithRequires + { + [RequiresUnreferencedCode (nameof (MethodWithRequires))] + [RequiresDynamicCode (nameof (MethodWithRequires))] + public virtual void MethodWithRequires ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type t) {} + } + + [RequiresUnreferencedCode (nameof (DerivedTypeWithRequires_BaseMethodWithRequires))] + [RequiresDynamicCode (nameof (DerivedTypeWithRequires_BaseMethodWithRequires))] + class DerivedTypeWithRequires_BaseMethodWithRequires : BaseMethodWithRequires + { + public override void MethodWithRequires ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type t) {} + } + + [ExpectedWarning ("IL2026", nameof (DerivedTypeWithRequires_BaseMethodWithRequires))] + [ExpectedWarning ("IL2026", nameof (DerivedTypeWithRequires_BaseMethodWithRequires.MethodWithRequires))] + [ExpectedWarning ("IL3050", nameof (DerivedTypeWithRequires_BaseMethodWithRequires), Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL3050", nameof (DerivedTypeWithRequires_BaseMethodWithRequires.MethodWithRequires), Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + static void Test_DerivedTypeWithRequires_BaseMethodWithRequires () + { + new DerivedTypeWithRequires_BaseMethodWithRequires ().MethodWithRequires (typeof (int)); + } + + class BaseMethodWithoutRequires + { + public virtual void MethodWithoutRequires ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type t) {} + } + + [RequiresUnreferencedCode (nameof (DerivedTypeWithRequires_BaseMethodWithoutRequires))] + class DerivedTypeWithRequires_BaseMethodWithoutRequires : BaseMethodWithoutRequires + { + public override void MethodWithoutRequires ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type t) {} + } + + [ExpectedWarning ("IL2026", nameof (DerivedTypeWithRequires_BaseMethodWithoutRequires))] + static void Test_DerivedTypeWithRequires_BaseMethodWithoutRequires () + { + new DerivedTypeWithRequires_BaseMethodWithoutRequires ().MethodWithoutRequires (typeof (int)); + } + + public static void Test () + { + Test_DerivedTypeWithRequires_BaseMethodWithRequires (); + Test_DerivedTypeWithRequires_BaseMethodWithoutRequires (); + } + } + + class InstantiatedGeneric + { + class GenericBase { + [ExpectedWarning ("IL2106")] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + public virtual T ReturnValue () => default; + } + + class InstantiatedDerived : GenericBase { + public override Type ReturnValue () => null; + } + + public static void Test () + { + new InstantiatedDerived ().ReturnValue (); + } + } + + class AnnotationOnUnsupportedType + { + class UnsupportedType { + [ExpectedWarning ("IL2041")] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + public virtual void UnsupportedAnnotationMismatch () { } + } + + class DerivedUnsupportedType : UnsupportedType { + [ExpectedWarning ("IL2041")] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + public override void UnsupportedAnnotationMismatch () { } + } + + public static void Test () + { + new DerivedUnsupportedType ().UnsupportedAnnotationMismatch (); + } + } + } } namespace System diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/Dependencies/DynamicDependencyFromAttributeXmlOnNonReferencedAssemblyLibrary.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/Dependencies/DynamicDependencyFromAttributeXmlOnNonReferencedAssemblyLibrary.cs index a4b24d50a459fc..0d5ac45ded4113 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/Dependencies/DynamicDependencyFromAttributeXmlOnNonReferencedAssemblyLibrary.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/Dependencies/DynamicDependencyFromAttributeXmlOnNonReferencedAssemblyLibrary.cs @@ -4,7 +4,7 @@ namespace Mono.Linker.Tests.Cases.DynamicDependencies.Dependencies { #if METHOD - public class DynamicDependencyFromAttributeXmlOnNonReferencedAssemblyLibrary_Method + public class DynamicDependencyFromAttributeXmlOnNonReferencedAssemblyLibrary_Method #else public class DynamicDependencyFromAttributeXmlOnNonReferencedAssemblyLibrary_Field #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/Dependencies/FacadeAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/Dependencies/FacadeAssembly.cs index 128a6cbdbfba84..9d824d7f7f71e7 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/Dependencies/FacadeAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/Dependencies/FacadeAssembly.cs @@ -3,5 +3,5 @@ using System.Runtime.CompilerServices; -[assembly: TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.DynamicDependencies.Dependencies.ImplementationLibrary))] -[assembly: TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.DynamicDependencies.Dependencies.ImplementationLibraryGenericType<,>))] +[assembly: TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.DynamicDependencies.Dependencies.ImplementationLibrary))] +[assembly: TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.DynamicDependencies.Dependencies.ImplementationLibraryGenericType<,>))] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXml.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXml.cs index 001eab391d662d..3182afffeab990 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXml.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXml.cs @@ -10,7 +10,7 @@ namespace Mono.Linker.Tests.Cases.DynamicDependencies #if NET [SetupLinkAttributesFile("DynamicDependencyFromAttributeXml.netcore.Attributes.xml")] #else - [SetupLinkAttributesFile ("DynamicDependencyFromAttributeXml.mono.Attributes.xml")] + [SetupLinkAttributesFile("DynamicDependencyFromAttributeXml.mono.Attributes.xml")] #endif [IgnoreLinkAttributes(false)] [SetupLinkerArgument("--enable-opt", "unreachablebodies", "missing.dll")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXmlOnNonReferencedAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXmlOnNonReferencedAssembly.cs index c70f116c29e3f1..70aa297f3eb6f4 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXmlOnNonReferencedAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXmlOnNonReferencedAssembly.cs @@ -15,7 +15,7 @@ namespace Mono.Linker.Tests.Cases.DynamicDependencies #if NET [SetupLinkAttributesFile("DynamicDependencyFromAttributeXmlOnNonReferencedAssembly.netcore.Attributes.xml")] #else - [SetupLinkAttributesFile ("DynamicDependencyFromAttributeXmlOnNonReferencedAssembly.mono.Attributes.xml")] + [SetupLinkAttributesFile("DynamicDependencyFromAttributeXmlOnNonReferencedAssembly.mono.Attributes.xml")] #endif public class DynamicDependencyFromAttributeXmlOnNonReferencedAssembly { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethod.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethod.cs index 33bc1797a85485..25275722088438 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethod.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethod.cs @@ -18,7 +18,7 @@ public static void Main() B.Broken(); B.Conditional(); #if NATIVEAOT - ReferenceViaReflection.Test (); + ReferenceViaReflection.Test(); #endif } @@ -182,42 +182,42 @@ internal void ConditionalTest() } } #if NATIVEAOT - abstract class ReferenceViaReflection - { - [Kept] - [DynamicDependency (nameof (TargetMethodViaReflection))] - public static void SourceMethodViaReflection () { } - - [Kept] - private static void TargetMethodViaReflection () { } - - - [Kept] - public static void Test () - { - var i = new Impl (); // Avoid removal of non-implemented abstract methods - - typeof (ReferenceViaReflection).RequiresPublicMethods (); - typeof (AbstractMethods).RequiresPublicMethods (); - } - - [KeptMember (".ctor()")] - private abstract class AbstractMethods - { - [Kept] - [DynamicDependency (nameof (TargetMethod))] - public abstract void SourceAbstractViaReflection (); - - [Kept] - private static void TargetMethod () { } - } - - [KeptMember (".ctor()")] - private class Impl : AbstractMethods - { - [Kept] - public override void SourceAbstractViaReflection () { } - } - } + abstract class ReferenceViaReflection + { + [Kept] + [DynamicDependency(nameof(TargetMethodViaReflection))] + public static void SourceMethodViaReflection() { } + + [Kept] + private static void TargetMethodViaReflection() { } + + + [Kept] + public static void Test() + { + var i = new Impl(); // Avoid removal of non-implemented abstract methods + + typeof(ReferenceViaReflection).RequiresPublicMethods(); + typeof(AbstractMethods).RequiresPublicMethods(); + } + + [KeptMember(".ctor()")] + private abstract class AbstractMethods + { + [Kept] + [DynamicDependency(nameof(TargetMethod))] + public abstract void SourceAbstractViaReflection(); + + [Kept] + private static void TargetMethod() { } + } + + [KeptMember(".ctor()")] + private class Impl : AbstractMethods + { + [Kept] + public override void SourceAbstractViaReflection() { } + } + } #endif } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethodInNonReferencedAssemblyWithSweptReferences.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethodInNonReferencedAssemblyWithSweptReferences.cs index e549e38cfa4183..05b2ed72ef9a45 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethodInNonReferencedAssemblyWithSweptReferences.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethodInNonReferencedAssemblyWithSweptReferences.cs @@ -10,7 +10,7 @@ namespace Mono.Linker.Tests.Cases.DynamicDependencies [SetupCompileBefore("reference.dll", new[] { "Dependencies/AssemblyDependency.cs" }, addAsReference: false)] [SetupCompileBefore("library.dll", new[] { "Dependencies/AssemblyDependencyWithMultipleReferences.cs" }, new[] { "reference.dll", "unusedreference.dll" }, addAsReference: false)] // TODO: keep library even if type is not found in it (https://github.com/dotnet/linker/issues/1795) - // [KeptAssembly ("library")] + // [KeptAssembly("library")] public class DynamicDependencyMethodInNonReferencedAssemblyWithSweptReferences { public static void Main() diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/CustomStepCanFixAbstractMethods.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/CustomStepCanFixAbstractMethods.cs index fdeb48d2961445..1ba3b41ef63d1e 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/CustomStepCanFixAbstractMethods.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/CustomStepCanFixAbstractMethods.cs @@ -1,6 +1,6 @@ -using Mono.Linker.Tests.Cases.Extensibility.Dependencies; using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Cases.Expectations.Metadata; +using Mono.Linker.Tests.Cases.Extensibility.Dependencies; namespace Mono.Linker.Tests.Cases.Extensibility { @@ -29,7 +29,7 @@ static void TestReflectionAccessToOtherAssembly() // to be created through reflection instead of a direct call to the constructor, otherwise we build the // TypeMapInfo cache too early for the custom step. - // var type = typeof (InterfaceImplementation); + // var type = typeof(InterfaceImplementation); var type = typeof(InterfaceImplementationInOtherAssembly); InterfaceType instance = (InterfaceType)System.Activator.CreateInstance(type); InterfaceType.UseInstance(instance); @@ -46,7 +46,7 @@ static void TestReflectionAccess() [Kept] [KeptMember(".ctor()")] [KeptInterface(typeof(InterfaceType))] - // [CreatedMember ("AbstractMethod()")] // https://github.com/dotnet/runtime/issues/104266 + // [CreatedMember("AbstractMethod()")] // https://github.com/dotnet/runtime/issues/104266 class InterfaceImplementationAccessedViaReflection : InterfaceType { } @@ -61,7 +61,7 @@ static void TestDirectAccess() [Kept] [KeptMember(".ctor()")] [KeptInterface(typeof(InterfaceType))] - // [CreatedMember ("AbstractMethod()")] // https://github.com/dotnet/runtime/issues/104266 + // [CreatedMember("AbstractMethod()")] // https://github.com/dotnet/runtime/issues/104266 class InterfaceImplementation : InterfaceType { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomMarkHandler.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomMarkHandler.cs index 7f257dc49c99de..7090ea5e3be80c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomMarkHandler.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomMarkHandler.cs @@ -6,46 +6,46 @@ public class CustomMarkHandler : IMarkHandler { - LinkContext _context; - - public void Initialize (LinkContext context, MarkContext markContext) - { - _context = context; - markContext.RegisterMarkAssemblyAction (assembly => DiscoverTypesInAssembly (assembly)); - markContext.RegisterMarkTypeAction (type => DiscoverMethodsInType (type)); - markContext.RegisterMarkMethodAction (method => DiscoverMethodsOnDeclaringType (method)); - } - - void MarkTypeFoo (TypeDefinition type) - { - if (type.Name == "DiscoveredTypeForAssembly") - _context.Annotations.Mark (type); - - if (!type.HasNestedTypes) - return; - - foreach (var nested in type.NestedTypes) - MarkTypeFoo (nested); - } - - void DiscoverTypesInAssembly (AssemblyDefinition assembly) - { - foreach (var type in assembly.MainModule.Types) - MarkTypeFoo (type); - } - - void DiscoverMethodsInType (TypeDefinition type) - { - foreach (var method in type.Methods) { - if (method.Name == $"DiscoveredMethodForType_{type.Name}") - _context.Annotations.Mark (method); - } - } - - void DiscoverMethodsOnDeclaringType (MethodDefinition method) - { - foreach (var otherMethod in method.DeclaringType.Methods) - if (otherMethod.Name == $"DiscoveredMethodForMethod_{method.Name}") - _context.Annotations.Mark (otherMethod); - } + LinkContext _context; + + public void Initialize(LinkContext context, MarkContext markContext) + { + _context = context; + markContext.RegisterMarkAssemblyAction(assembly => DiscoverTypesInAssembly(assembly)); + markContext.RegisterMarkTypeAction(type => DiscoverMethodsInType(type)); + markContext.RegisterMarkMethodAction(method => DiscoverMethodsOnDeclaringType(method)); + } + + void MarkTypeFoo(TypeDefinition type) + { + if (type.Name == "DiscoveredTypeForAssembly") + _context.Annotations.Mark(type); + + if (!type.HasNestedTypes) + return; + + foreach (var nested in type.NestedTypes) + MarkTypeFoo(nested); + } + + void DiscoverTypesInAssembly(AssemblyDefinition assembly) + { + foreach (var type in assembly.MainModule.Types) + MarkTypeFoo(type); + } + + void DiscoverMethodsInType(TypeDefinition type) + { + foreach (var method in type.Methods) { + if (method.Name == $"DiscoveredMethodForType_{type.Name}") + _context.Annotations.Mark(method); + } + } + + void DiscoverMethodsOnDeclaringType(MethodDefinition method) + { + foreach (var otherMethod in method.DeclaringType.Methods) + if (otherMethod.Name == $"DiscoveredMethodForMethod_{method.Name}") + _context.Annotations.Mark(otherMethod); + } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomStepsWithSharedState.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomStepsWithSharedState.cs index 8b6ba1d769bc88..f4804866f90ec5 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomStepsWithSharedState.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomStepsWithSharedState.cs @@ -4,58 +4,58 @@ public class SharedAnnotation { - public bool Mark { get; set; } + public bool Mark { get; set; } - public static void Set (LinkContext context, MethodDefinition method, SharedAnnotation value) - { - context.Annotations.SetCustomAnnotation (nameof (SharedAnnotation), method, value); - } + public static void Set(LinkContext context, MethodDefinition method, SharedAnnotation value) + { + context.Annotations.SetCustomAnnotation(nameof(SharedAnnotation), method, value); + } - public static SharedAnnotation Get (LinkContext context, MethodDefinition method) { - return context.Annotations.GetCustomAnnotation (nameof (SharedAnnotation), method) as SharedAnnotation; - } + public static SharedAnnotation Get(LinkContext context, MethodDefinition method) { + return context.Annotations.GetCustomAnnotation(nameof(SharedAnnotation), method) as SharedAnnotation; + } } public class SharedStateHandler1 : IMarkHandler { - LinkContext context; - - public void Initialize (LinkContext context, MarkContext markContext) - { - this.context = context; - markContext.RegisterMarkTypeAction (ProcessType); - } - - public void ProcessType (TypeDefinition type) - { - if (!type.HasMethods) - return; - - foreach (var method in type.Methods) { - if (method.Name == "MarkedMethod") - SharedAnnotation.Set (context, method, new SharedAnnotation () { Mark = true }); - } - } + LinkContext context; + + public void Initialize(LinkContext context, MarkContext markContext) + { + this.context = context; + markContext.RegisterMarkTypeAction(ProcessType); + } + + public void ProcessType(TypeDefinition type) + { + if (!type.HasMethods) + return; + + foreach (var method in type.Methods) { + if (method.Name == "MarkedMethod") + SharedAnnotation.Set(context, method, new SharedAnnotation() { Mark = true }); + } + } } public class SharedStateHandler2 : IMarkHandler { - LinkContext context; - - public void Initialize (LinkContext context, MarkContext markContext) - { - this.context = context; - markContext.RegisterMarkTypeAction (ProcessType); - } - - public void ProcessType (TypeDefinition type) - { - if (!type.HasMethods) - return; - - foreach (var method in type.Methods) { - if (SharedAnnotation.Get (context, method) is SharedAnnotation annotation && annotation.Mark) - context.Annotations.Mark (method); - } - } + LinkContext context; + + public void Initialize(LinkContext context, MarkContext markContext) + { + this.context = context; + markContext.RegisterMarkTypeAction(ProcessType); + } + + public void ProcessType(TypeDefinition type) + { + if (!type.HasMethods) + return; + + foreach (var method in type.Methods) { + if (SharedAnnotation.Get(context, method) is SharedAnnotation annotation && annotation.Mark) + context.Annotations.Mark(method); + } + } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomSubStep.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomSubStep.cs index b03eab25ecfb1f..30648b0faa54dd 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomSubStep.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomSubStep.cs @@ -4,10 +4,10 @@ class CustomSubStep : BaseSubStep { - public override SubStepTargets Targets => SubStepTargets.Type; + public override SubStepTargets Targets => SubStepTargets.Type; - public override void ProcessType (TypeDefinition type) - { - Annotations.Mark (type); - } + public override void ProcessType(TypeDefinition type) + { + Annotations.Mark(type); + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomSubStepFields.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomSubStepFields.cs index 6bb52cc5c05353..152a0a6ba74308 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomSubStepFields.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomSubStepFields.cs @@ -4,10 +4,10 @@ class CustomSubStep : BaseSubStep { - public override SubStepTargets Targets => SubStepTargets.Field; + public override SubStepTargets Targets => SubStepTargets.Field; - public override void ProcessField (FieldDefinition field) - { - Annotations.Mark (field); - } + public override void ProcessField(FieldDefinition field) + { + Annotations.Mark(field); + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomWarning.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomWarning.cs index 9b35ce0d4f6a41..e933d717c7d6de 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomWarning.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/CustomWarning.cs @@ -6,17 +6,17 @@ public class CustomWarning : IMarkHandler { - LinkContext _context; + LinkContext _context; - public void Initialize (LinkContext context, MarkContext markContext) - { - _context = context; - markContext.RegisterMarkTypeAction (type => WarnOnKnownType (type)); - } + public void Initialize(LinkContext context, MarkContext markContext) + { + _context = context; + markContext.RegisterMarkTypeAction(type => WarnOnKnownType(type)); + } - void WarnOnKnownType (TypeDefinition type ) - { - if (type.Name == "KnownTypeThatShouldWarn") - _context.LogMessage (MessageContainer.CreateCustomWarningMessage (_context, "custom warning on type", 6200, new MessageOrigin (type), WarnVersion.ILLink5)); - } + void WarnOnKnownType(TypeDefinition type ) + { + if (type.Name == "KnownTypeThatShouldWarn") + _context.LogMessage(MessageContainer.CreateCustomWarningMessage(_context, "custom warning on type", 6200, new MessageOrigin(type), WarnVersion.ILLink5)); + } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/FixAbstractMethods.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/FixAbstractMethods.cs index 99b936b64117a4..146334a81e9588 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/FixAbstractMethods.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/FixAbstractMethods.cs @@ -7,37 +7,37 @@ public class FixAbstractMethods : IMarkHandler { - LinkContext _context; + LinkContext _context; - public void Initialize (LinkContext context, MarkContext markContext) - { - _context = context; - markContext.RegisterMarkTypeAction (type => ProcessType (type)); - } + public void Initialize(LinkContext context, MarkContext markContext) + { + _context = context; + markContext.RegisterMarkTypeAction(type => ProcessType(type)); + } - void ProcessType (TypeDefinition type) - { - if (!type.Name.Contains ("InterfaceImplementation")) - return; + void ProcessType(TypeDefinition type) + { + if (!type.Name.Contains("InterfaceImplementation")) + return; - Assert (!type.IsAbstract && type.HasInterfaces); - var iface = type.Interfaces[0]; - Assert (iface.InterfaceType.Name == "InterfaceType"); - var interfaceType = iface.InterfaceType.Resolve (); - var method = interfaceType.Methods[0]; - Assert (method.Name == "AbstractMethod"); + Assert(!type.IsAbstract && type.HasInterfaces); + var iface = type.Interfaces[0]; + Assert(iface.InterfaceType.Name == "InterfaceType"); + var interfaceType = iface.InterfaceType.Resolve(); + var method = interfaceType.Methods[0]; + Assert(method.Name == "AbstractMethod"); - var newMethod = new MethodDefinition (method.Name, (method.Attributes | MethodAttributes.Final) & ~MethodAttributes.Abstract, method.ReturnType); - Assert (!method.HasParameters); - var ilProcessor = newMethod.Body.GetILProcessor (); - ilProcessor.Append (ilProcessor.Create (Mono.Cecil.Cil.OpCodes.Ret)); + var newMethod = new MethodDefinition(method.Name, (method.Attributes | MethodAttributes.Final) & ~MethodAttributes.Abstract, method.ReturnType); + Assert(!method.HasParameters); + var ilProcessor = newMethod.Body.GetILProcessor(); + ilProcessor.Append(ilProcessor.Create(Mono.Cecil.Cil.OpCodes.Ret)); - type.Methods.Add (newMethod); - } + type.Methods.Add(newMethod); + } - static void Assert (bool b) - { - if (!b) - throw new Exception (); - } + static void Assert(bool b) + { + if (!b) + throw new Exception(); + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/InterfaceType.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/InterfaceType.cs index 9c1105ca4d57d6..0172175c0c2d6a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/InterfaceType.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/InterfaceType.cs @@ -6,13 +6,13 @@ namespace Mono.Linker.Tests.Cases.Extensibility.Dependencies public interface InterfaceType { #if INCLUDE_ABSTRACT_METHOD - public abstract void AbstractMethod (); + public abstract void AbstractMethod(); #endif public static void UseInstance(InterfaceType instance) { #if INCLUDE_ABSTRACT_METHOD - instance.AbstractMethod (); + instance.AbstractMethod(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/MyDispatcher.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/MyDispatcher.cs index fff1fc9881c440..a89c3e60d23a58 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/MyDispatcher.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/MyDispatcher.cs @@ -4,13 +4,13 @@ public class MyDispatcher : SubStepsDispatcher { - public MyDispatcher () - : base (GetSubSteps ()) - { - } + public MyDispatcher() + : base(GetSubSteps()) + { + } - static IEnumerable GetSubSteps () - { - yield return new CustomSubStep (); - } + static IEnumerable GetSubSteps() + { + yield return new CustomSubStep(); + } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/MyMarkSubStepsDispatcher.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/MyMarkSubStepsDispatcher.cs index 9dab0d3feeec6c..87bc02ce424869 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/MyMarkSubStepsDispatcher.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/MyMarkSubStepsDispatcher.cs @@ -5,18 +5,18 @@ public class MyMarkSubStepsDispatcher : MarkSubStepsDispatcher { - public MyMarkSubStepsDispatcher () - : base (GetSubSteps ()) - { - } + public MyMarkSubStepsDispatcher() + : base(GetSubSteps()) + { + } - public override void Initialize (LinkContext context, MarkContext markContext) - { - base.Initialize (context, markContext); - } + public override void Initialize(LinkContext context, MarkContext markContext) + { + base.Initialize(context, markContext); + } - static IEnumerable GetSubSteps () - { - yield return new CustomSubStep (); - } + static IEnumerable GetSubSteps() + { + yield return new CustomSubStep(); + } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/PreserveMethodsSubStep.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/PreserveMethodsSubStep.cs index f67df3119724e4..1b2004a371a9c8 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/PreserveMethodsSubStep.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/PreserveMethodsSubStep.cs @@ -5,38 +5,38 @@ class PreserveMethodsSubStep : BaseStep { - protected override void Process () - { - foreach (var assembly in Context.GetAssemblies ()) { - foreach (var type in assembly.MainModule.Types) - ProcessType (type); - } - } - - void ProcessType (TypeDefinition type) - { - if (type.HasNestedTypes) { - foreach (var nested in type.NestedTypes) - ProcessType (nested); - } - - - foreach (var method in type.Methods) { - if (method.Name == "PreservedForType") - Annotations.AddPreservedMethod (type, method); - - ProcessMethod (method); - } - } - - public void ProcessMethod (MethodDefinition method) - { - if (method.Name == "MarkedMethod") - Annotations.Mark (method); - - foreach (var m in method.DeclaringType.Methods) { - if (m.Name == $"PreservedForMethod_{method.Name}") - Annotations.AddPreservedMethod (method, m); - } - } + protected override void Process() + { + foreach (var assembly in Context.GetAssemblies()) { + foreach (var type in assembly.MainModule.Types) + ProcessType(type); + } + } + + void ProcessType(TypeDefinition type) + { + if (type.HasNestedTypes) { + foreach (var nested in type.NestedTypes) + ProcessType(nested); + } + + + foreach (var method in type.Methods) { + if (method.Name == "PreservedForType") + Annotations.AddPreservedMethod(type, method); + + ProcessMethod(method); + } + } + + public void ProcessMethod(MethodDefinition method) + { + if (method.Name == "MarkedMethod") + Annotations.Mark(method); + + foreach (var m in method.DeclaringType.Methods) { + if (m.Name == $"PreservedForMethod_{method.Name}") + Annotations.AddPreservedMethod(method, m); + } + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/ResolveTypesSubStep.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/ResolveTypesSubStep.cs index 9327d2152dee1a..a7970314750a5f 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/ResolveTypesSubStep.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/Dependencies/ResolveTypesSubStep.cs @@ -5,30 +5,30 @@ class ResolveTypesSubStep : BaseStep { - protected override void Process () - { - foreach (var assembly in Context.GetAssemblies ()) { - foreach (var type in assembly.MainModule.Types) - ProcessType (type); - } - } + protected override void Process() + { + foreach (var assembly in Context.GetAssemblies()) { + foreach (var type in assembly.MainModule.Types) + ProcessType(type); + } + } - void ProcessType (TypeDefinition type) - { - if (type.HasNestedTypes) { - foreach (var nested in type.NestedTypes) - ProcessType (nested); - } + void ProcessType(TypeDefinition type) + { + if (type.HasNestedTypes) { + foreach (var nested in type.NestedTypes) + ProcessType(nested); + } - if (type.Name == "TypeWithFields") { - foreach (var field in type.Fields) - ProcessField (field); - } - } + if (type.Name == "TypeWithFields") { + foreach (var field in type.Fields) + ProcessField(field); + } + } - public void ProcessField (FieldDefinition field) - { - if (field.FieldType.Resolve () == null) - throw new Exception($"Unresolved field type {field.FieldType} for field {field}!"); - } + public void ProcessField(FieldDefinition field) + { + if (field.FieldType.Resolve() == null) + throw new Exception($"Unresolved field type {field.FieldType} for field {field}!"); + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Generics/NewConstraintOnClass.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Generics/NewConstraintOnClass.cs index 6f60a6100995cd..6ecbdd662604cc 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Generics/NewConstraintOnClass.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Generics/NewConstraintOnClass.cs @@ -130,7 +130,6 @@ public static void Test() namespace System.Runtime.CompilerServices { - // NativeAOT test infra filters out System.* members from validation for now [Kept(By = Tool.Trimmer)] [KeptMember(".ctor()", By = Tool.Trimmer)] public partial class IsUnmanagedAttribute diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/DimProvidedByRecursiveInterface.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/DimProvidedByRecursiveInterface.cs index 2ba25566d453e6..ba43a9abdd2686 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/DimProvidedByRecursiveInterface.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/DimProvidedByRecursiveInterface.cs @@ -12,22 +12,22 @@ namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.DefaultInterfaceMethods [SkipILVerify] #if IL_ASSEMBLY_AVAILABLE - [KeptMemberInAssembly ("library.dll", typeof(Program.IFoo), "Method()")] - [KeptTypeInAssembly ("library.dll", typeof(Program.IBar))] - [KeptMemberInAssembly ("library.dll", typeof(Program.IBar), "Program.IFoo.Method()")] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.IBar), "library.dll", typeof (Program.IFoo))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.MyFoo), "library.dll", typeof (Program.IBaz))] - [KeptTypeInAssembly ("library.dll", typeof(Program.IBaz))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.IBaz), "library.dll", typeof (Program.IBar))] - [KeptMemberInAssembly ("library.dll", typeof(Program), "CallMethod(Program/IFoo)")] + [KeptMemberInAssembly("library.dll", typeof(Program.IFoo), "Method()")] + [KeptTypeInAssembly("library.dll", typeof(Program.IBar))] + [KeptMemberInAssembly("library.dll", typeof(Program.IBar), "Program.IFoo.Method()")] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.IBar), "library.dll", typeof(Program.IFoo))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.MyFoo), "library.dll", typeof(Program.IBaz))] + [KeptTypeInAssembly("library.dll", typeof(Program.IBaz))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.IBaz), "library.dll", typeof(Program.IBar))] + [KeptMemberInAssembly("library.dll", typeof(Program), "CallMethod(Program/IFoo)")] #endif class DimProvidedByRecursiveInterface { static void Main() { #if IL_ASSEMBLY_AVAILABLE - Program.IFoo foo = new Program.MyFoo (); - Program.CallMethod(foo); + Program.IFoo foo = new Program.MyFoo(); + Program.CallMethod(foo); #endif } } @@ -37,31 +37,31 @@ static void Main() // public static class Program // { -// [Kept] -// interface IFoo -// { -// void Method(); -// } +// [Kept] +// interface IFoo +// { +// void Method(); +// } -// [Kept] -// interface IBar : IFoo -// { -// [Kept] -// void IFoo.Method() { } -// } +// [Kept] +// interface IBar : IFoo +// { +// [Kept] +// void IFoo.Method() { } +// } -// [Kept] -// interface IBaz: IBar /* not IFoo */ -// { -// } +// [Kept] +// interface IBaz: IBar /* not IFoo */ +// { +// } -// [Kept] -// [KeptInterface(typeof(IBaz))] -// class MyFoo : IBaz /* not IBar, not IFoo */ -// { } +// [Kept] +// [KeptInterface(typeof(IBaz))] +// class MyFoo : IBaz /* not IBar, not IFoo */ +// { } -// static void CallMethod(IFoo foo) -// { -// foo.Method(); -// } +// static void CallMethod(IFoo foo) +// { +// foo.Method(); +// } // } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/InterfaceWithAttributeOnImplementation.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/InterfaceWithAttributeOnImplementation.cs index 5a7edcdc42d17b..cb237acb8a4d55 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/InterfaceWithAttributeOnImplementation.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/InterfaceWithAttributeOnImplementation.cs @@ -12,7 +12,7 @@ class InterfaceWithAttributeOnImplementation static void Main() { #if IL_ASSEMBLY_AVAILABLE - ((IMyInterface)new MyClass ()).Frob (); + ((IMyInterface)new MyClass()).Frob(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/MultipleDimsProvidedByRecursiveInterface.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/MultipleDimsProvidedByRecursiveInterface.cs index 1210f73d7b34ad..e6c2055b133160 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/MultipleDimsProvidedByRecursiveInterface.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/MultipleDimsProvidedByRecursiveInterface.cs @@ -12,36 +12,36 @@ namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.DefaultInterfaceMethods [SkipILVerify] #if IL_ASSEMBLY_AVAILABLE - // Both DIMs on I01 and I00 should be kept because one is not more specific than another. - [KeptMemberInAssembly ("library.dll", typeof(Program.I0), "Method()")] - [KeptTypeInAssembly ("library.dll", typeof(Program.I00))] - [KeptMemberInAssembly ("library.dll", typeof(Program.I00), "Program.I0.Method()")] - // Bug: DIM resolution doesn't look at recursive interfaces - //[KeptMemberInAssembly ("library.dll", typeof(Program.I01), "Program.I0.Method()")] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.I00), "library.dll", typeof (Program.I0))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.MyFoo), "library.dll", typeof (Program.I000))] - [KeptTypeInAssembly ("library.dll", typeof(Program.I000))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.I000), "library.dll", typeof (Program.I00))] - // Bug: DIM resolution doesn't look at recursive interfaces - //[KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.MyFoo), "library.dll", typeof (Program.I010))] - //[KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.I010), "library.dll", typeof (Program.I01))] - //[KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.I01), "library.dll", typeof (Program.I0))] + // Both DIMs on I01 and I00 should be kept because one is not more specific than another. + [KeptMemberInAssembly("library.dll", typeof(Program.I0), "Method()")] + [KeptTypeInAssembly("library.dll", typeof(Program.I00))] + [KeptMemberInAssembly("library.dll", typeof(Program.I00), "Program.I0.Method()")] + // Bug: DIM resolution doesn't look at recursive interfaces + //[KeptMemberInAssembly("library.dll", typeof(Program.I01), "Program.I0.Method()")] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.I00), "library.dll", typeof(Program.I0))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.MyFoo), "library.dll", typeof(Program.I000))] + [KeptTypeInAssembly("library.dll", typeof(Program.I000))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.I000), "library.dll", typeof(Program.I00))] + // Bug: DIM resolution doesn't look at recursive interfaces + //[KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.MyFoo), "library.dll", typeof(Program.I010))] + //[KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.I010), "library.dll", typeof(Program.I01))] + //[KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.I01), "library.dll", typeof(Program.I0))] #endif class MultipleDimsProvidedByRecursiveInterface { static void Main() { #if IL_ASSEMBLY_AVAILABLE - Program.I0 foo = new Program.MyFoo (); - CallMethod(foo); + Program.I0 foo = new Program.MyFoo(); + CallMethod(foo); #endif } #if IL_ASSEMBLY_AVAILABLE - [Kept] - static void CallMethod(Program.I0 foo) - { - foo.Method(); - } + [Kept] + static void CallMethod(Program.I0 foo) + { + foo.Method(); + } #endif } } @@ -50,39 +50,39 @@ static void CallMethod(Program.I0 foo) // public static class Program // { -// [Kept] -// interface I0 -// { -// void Method(); -// } +// [Kept] +// interface I0 +// { +// void Method(); +// } -// [Kept] -// interface I00 : I0 -// { -// [Kept] -// void I0.Method() { } -// } +// [Kept] +// interface I00 : I0 +// { +// [Kept] +// void I0.Method() { } +// } -// [Kept] -// interface I000: I00 /* not I0 */ -// { -// } +// [Kept] +// interface I000: I00 /* not I0 */ +// { +// } -// [Kept] -// interface I01 : I0 -// { -// [Kept] -// void I0.Method() { } -// } +// [Kept] +// interface I01 : I0 +// { +// [Kept] +// void I0.Method() { } +// } -// [Kept] -// interface I010: I01 /* not I0 */ -// { -// } +// [Kept] +// interface I010: I01 /* not I0 */ +// { +// } -// [Kept] -// [KeptInterface(typeof(I000))] -// class MyFoo : I000, I010 -// { } +// [Kept] +// [KeptInterface(typeof(I000))] +// class MyFoo : I000, I010 +// { } // } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/StaticDimProvidedByUnreferencedIfaceInHierarchy.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/StaticDimProvidedByUnreferencedIfaceInHierarchy.cs index 78425e248a49b1..7d894eb292d588 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/StaticDimProvidedByUnreferencedIfaceInHierarchy.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/DefaultInterfaceMethods/StaticDimProvidedByUnreferencedIfaceInHierarchy.cs @@ -12,23 +12,23 @@ namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.DefaultInterfaceMethods [SkipILVerify] #if IL_ASSEMBLY_AVAILABLE - [KeptMemberInAssembly ("library.dll", typeof(Program), "CallMethod<#1>()")] - [KeptTypeInAssembly ("library.dll", typeof(Program.IBase))] - [KeptMemberInAssembly ("library.dll", typeof(Program.IBase), "Method()")] - [KeptTypeInAssembly ("library.dll", typeof(Program.I4))] - [KeptTypeInAssembly ("library.dll", typeof(Program.I2))] - [KeptMemberInAssembly ("library.dll", typeof(Program.I2), "Program.IBase.Method()")] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.I2), "library.dll", typeof (Program.IBase))] - [KeptTypeInAssembly ("library.dll", typeof(Program.I3))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.I3), "library.dll", typeof (Program.I2))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.I4), "library.dll", typeof (Program.I3))] + [KeptMemberInAssembly("library.dll", typeof(Program), "CallMethod<#1>()")] + [KeptTypeInAssembly("library.dll", typeof(Program.IBase))] + [KeptMemberInAssembly("library.dll", typeof(Program.IBase), "Method()")] + [KeptTypeInAssembly("library.dll", typeof(Program.I4))] + [KeptTypeInAssembly("library.dll", typeof(Program.I2))] + [KeptMemberInAssembly("library.dll", typeof(Program.I2), "Program.IBase.Method()")] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.I2), "library.dll", typeof(Program.IBase))] + [KeptTypeInAssembly("library.dll", typeof(Program.I3))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.I3), "library.dll", typeof(Program.I2))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.I4), "library.dll", typeof(Program.I3))] #endif class StaticDimProvidedByUnreferencedIfaceInHierarchy { static void Main() { #if IL_ASSEMBLY_AVAILABLE - Program.CallMethod(); + Program.CallMethod(); #endif } } @@ -38,32 +38,32 @@ static void Main() // public static class Program // { -// [Kept] -// interface IBase -// { -// [Kept] -// static abstract void Method(); -// } +// [Kept] +// interface IBase +// { +// [Kept] +// static abstract void Method(); +// } -// [Kept] -// [KeptInterface(typeof(IBase)] -// interface I2 : IBase -// { -// [Kept] -// static void IBase.Method() { } -// } +// [Kept] +// [KeptInterface(typeof(IBase)] +// interface I2 : IBase +// { +// [Kept] +// static void IBase.Method() { } +// } -// [Kept] -// [KeptInterface(typeof(I2)] -// interface I3 : I2 { } +// [Kept] +// [KeptInterface(typeof(I2)] +// interface I3 : I2 { } -// [Kept] -// [KeptInterface(typeof(I3)] -// interface I4 : I3 { } +// [Kept] +// [KeptInterface(typeof(I3)] +// interface I4 : I3 { } -// [Kept] -// static void CallMethod() where T : IBase -// { -// T.Method(); -// } +// [Kept] +// static void CallMethod() where T : IBase +// { +// T.Method(); +// } // } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceImplementedThroughBaseInterface.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceImplementedThroughBaseInterface.cs index 786181d2c0f219..3c008ad2ef82a5 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceImplementedThroughBaseInterface.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/InterfaceImplementedThroughBaseInterface.cs @@ -20,7 +20,7 @@ namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces [SkipILVerify] #if IL_ASSEMBLY_AVAILABLE - [KeptMemberInAssembly ("library.dll", typeof(C), "IBase.M()")] + [KeptMemberInAssembly("library.dll", typeof(C), "IBase.M()")] #endif [KeptMember(".ctor()")] public class InterfaceImplementedThroughBaseInterface diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/NoInstanceCtor/NoInstanceCtorAndTypePreserveFieldsWithInterfacesMarked.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/NoInstanceCtor/NoInstanceCtorAndTypePreserveFieldsWithInterfacesMarked.cs index 1b05f7275518d9..19a80a761e0bce 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/NoInstanceCtor/NoInstanceCtorAndTypePreserveFieldsWithInterfacesMarked.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/NoInstanceCtor/NoInstanceCtorAndTypePreserveFieldsWithInterfacesMarked.cs @@ -31,7 +31,7 @@ public class NoInstanceCtorAndTypePreserveFieldsWithInterfacesMarked public static void Main() { #if IL_ASSEMBLY_COMPILED - var tmp = typeof (Mono.Linker.Tests.Cases.Inheritance.Interfaces.OnReferenceType.NoInstanceCtor.Dependencies.NoInstanceCtorAndAssemblyPreserveAll_Lib.IFoo).ToString (); + var tmp = typeof(Mono.Linker.Tests.Cases.Inheritance.Interfaces.OnReferenceType.NoInstanceCtor.Dependencies.NoInstanceCtorAndAssemblyPreserveAll_Lib.IFoo).ToString(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/NoInstanceCtor/NoInstanceCtorAndTypePreserveMethodsWithInterfacesMarked.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/NoInstanceCtor/NoInstanceCtorAndTypePreserveMethodsWithInterfacesMarked.cs index b94e4c4ea498fd..88ea83bb4587d4 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/NoInstanceCtor/NoInstanceCtorAndTypePreserveMethodsWithInterfacesMarked.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/NoInstanceCtor/NoInstanceCtorAndTypePreserveMethodsWithInterfacesMarked.cs @@ -31,7 +31,7 @@ public static void Main() { // We'll mark one interface in code and one via xml, the end result should be the same #if IL_ASSEMBLY_COMPILED - var tmp = typeof (Mono.Linker.Tests.Cases.Inheritance.Interfaces.OnReferenceType.NoInstanceCtor.Dependencies.NoInstanceCtorAndAssemblyPreserveAll_Lib.IFoo).ToString (); + var tmp = typeof(Mono.Linker.Tests.Cases.Inheritance.Interfaces.OnReferenceType.NoInstanceCtor.Dependencies.NoInstanceCtorAndAssemblyPreserveAll_Lib.IFoo).ToString(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/GenericInterfaceImplementedRecursively.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/GenericInterfaceImplementedRecursively.cs index b62d53e0992ed3..17f21597136428 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/GenericInterfaceImplementedRecursively.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/GenericInterfaceImplementedRecursively.cs @@ -17,13 +17,13 @@ namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.RecursiveInterfaces [SetupCompileBefore("library.dll", new[] { "Dependencies/GenericInterfaceImplementedRecursively.il" })] [SkipILVerify] #if IL_ASSEMBLY_AVAILABLE - [KeptTypeInAssembly ("library.dll", typeof(Program.IBase<>))] - [KeptTypeInAssembly ("library.dll", typeof(Program.IMiddle<>))] - [KeptInterfaceOnTypeInAssembly ("library.dll", "Program/IMiddle`1", "library.dll", "Program/IBase`1")] - [KeptTypeInAssembly ("library.dll", typeof(Program.IDerived<>))] - [KeptInterfaceOnTypeInAssembly ("library.dll", "Program/IDerived`1", "library.dll", "Program/IMiddle`1")] - [KeptTypeInAssembly ("library.dll", typeof(Program.C))] - [KeptInterfaceOnTypeInAssembly ("library.dll", "Program/C", "library.dll", "Program/IDerived`1")] + [KeptTypeInAssembly("library.dll", typeof(Program.IBase<>))] + [KeptTypeInAssembly("library.dll", typeof(Program.IMiddle<>))] + [KeptInterfaceOnTypeInAssembly("library.dll", "Program/IMiddle`1", "library.dll", "Program/IBase`1")] + [KeptTypeInAssembly("library.dll", typeof(Program.IDerived<>))] + [KeptInterfaceOnTypeInAssembly("library.dll", "Program/IDerived`1", "library.dll", "Program/IMiddle`1")] + [KeptTypeInAssembly("library.dll", typeof(Program.C))] + [KeptInterfaceOnTypeInAssembly("library.dll", "Program/C", "library.dll", "Program/IDerived`1")] #endif /// /// This test case is to verify that the linker will keep all the metadata necessary for C to implement IBase when an interfaceImpl isn't directly on C. @@ -34,8 +34,8 @@ public static void Main() { #if IL_ASSEMBLY_AVAILABLE - Program.IBase _ = null; - _ = new Program.C(); + Program.IBase _ = null; + _ = new Program.C(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/InterfaceImplementedRecursively.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/InterfaceImplementedRecursively.cs index f3f819447761a5..3be089bf915dc9 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/InterfaceImplementedRecursively.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/InterfaceImplementedRecursively.cs @@ -17,13 +17,13 @@ namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.RecursiveInterfaces [SetupCompileBefore("library.dll", new[] { "Dependencies/InterfaceImplementedRecursively.il" })] [SkipILVerify] #if IL_ASSEMBLY_AVAILABLE - [KeptTypeInAssembly ("library.dll", typeof(Program.IBase))] - [KeptTypeInAssembly ("library.dll", typeof(Program.IMiddle))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.IMiddle), "library.dll", typeof (Program.IBase))] - [KeptTypeInAssembly ("library.dll", typeof(Program.IDerived))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.IDerived), "library.dll", typeof (Program.IMiddle))] - [KeptTypeInAssembly ("library.dll", typeof(Program.C))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Program.C), "library.dll", typeof (Program.IDerived))] + [KeptTypeInAssembly("library.dll", typeof(Program.IBase))] + [KeptTypeInAssembly("library.dll", typeof(Program.IMiddle))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.IMiddle), "library.dll", typeof(Program.IBase))] + [KeptTypeInAssembly("library.dll", typeof(Program.IDerived))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.IDerived), "library.dll", typeof(Program.IMiddle))] + [KeptTypeInAssembly("library.dll", typeof(Program.C))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Program.C), "library.dll", typeof(Program.IDerived))] #endif /// /// This test case is to verify that the linker will keep all the metadata necessary for C to implement IBase when an interfaceImpl isn't directly on C. @@ -34,8 +34,8 @@ public static void Main() { #if IL_ASSEMBLY_AVAILABLE - Program.IBase b = null; - object c = new Program.C(); + Program.IBase b = null; + object c = new Program.C(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/OverrideOfRecursiveInterfaceIsRemoved.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/OverrideOfRecursiveInterfaceIsRemoved.cs index 0c9b36eb5d5a9d..55d16c74d0448b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/OverrideOfRecursiveInterfaceIsRemoved.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/OverrideOfRecursiveInterfaceIsRemoved.cs @@ -36,8 +36,8 @@ public class OverrideOfRecursiveInterfaceIsRemoved public static void Main() { #if IL_ASSEMBLY_AVAILABLE - Program.MyTest(); - _ = typeof(Program.IBaseUnused); + Program.MyTest(); + _ = typeof(Program.IBaseUnused); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/RecursiveInterfaceKept.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/RecursiveInterfaceKept.cs index eddc6efae8879f..99b5191ff514c4 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/RecursiveInterfaceKept.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/RecursiveInterfaces/RecursiveInterfaceKept.cs @@ -15,21 +15,21 @@ namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.RecursiveInterfaces [SetupCompileBefore("library.dll", new[] { "Dependencies/RecursiveInterfaceTwoImplementationPaths.il" })] [SkipILVerify] #if IL_ASSEMBLY_AVAILABLE - [KeptTypeInAssembly ("library.dll", typeof(Library.MyClass))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Library.MyClass), "library.dll", typeof (Library.I0100))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Library.I0100), "library.dll", typeof (Library.I010))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Library.I010), "library.dll", typeof (Library.I01))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (Library.I01), "library.dll", typeof (Library.I0))] - [RemovedTypeInAssembly("library.dll", typeof(Library.I00))] - [RemovedTypeInAssembly("library.dll", typeof(Library.I000))] - [RemovedInterfaceOnTypeInAssembly("library.dll", typeof (Library.MyClass), "library.dll", typeof (Library.I000))] + [KeptTypeInAssembly("library.dll", typeof(Library.MyClass))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Library.MyClass), "library.dll", typeof(Library.I0100))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Library.I0100), "library.dll", typeof(Library.I010))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Library.I010), "library.dll", typeof(Library.I01))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(Library.I01), "library.dll", typeof(Library.I0))] + [RemovedTypeInAssembly("library.dll", typeof(Library.I00))] + [RemovedTypeInAssembly("library.dll", typeof(Library.I000))] + [RemovedInterfaceOnTypeInAssembly("library.dll", typeof(Library.MyClass), "library.dll", typeof(Library.I000))] #endif public class RecursiveInterfaceKept { public static void Main() { #if IL_ASSEMBLY_AVAILABLE - Library.I0 _ = new Library.MyClass(); + Library.I0 _ = new Library.MyClass(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/Dependencies/CustomStepSaveAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/Dependencies/CustomStepSaveAssembly.cs index 031e4d69752b4b..a3558707c22661 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/Dependencies/CustomStepSaveAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/Dependencies/CustomStepSaveAssembly.cs @@ -5,9 +5,9 @@ public class CustomStepSaveAssembly : BaseStep { - protected override void ProcessAssembly (AssemblyDefinition assembly) + protected override void ProcessAssembly(AssemblyDefinition assembly) { if (assembly.Name.Name == "test") - Context.Annotations.SetAction (assembly, AssemblyAction.Save); + Context.Annotations.SetAction(assembly, AssemblyAction.Save); } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/InstanceMethodsWithOverridesSwept.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/InstanceMethodsWithOverridesSwept.cs index 54da4573175738..79563e1391dfad 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/InstanceMethodsWithOverridesSwept.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/InstanceMethodsWithOverridesSwept.cs @@ -22,38 +22,38 @@ namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.StaticInterfaceMethods [SetupCompileBefore("library.dll", new string[] { "Dependencies/InstanceMethods.il" })] [Kept] #if IL_ASSEMBLY_AVAILABLE - [KeptTypeInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodAccessedViaInterface))] - [KeptTypeInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodAccessedDirectly))] - [KeptTypeInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodAccessedViaReflection))] - [KeptTypeInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodKeptByDynamicDependency))] - [KeptTypeInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodCalledDirectlyAndInterfaceUnreferenced))] - [KeptTypeInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodCalledDirectlyAndRecursiveInterfaceUnreferenced))] - [KeptTypeInAssembly ("library.dll", typeof (InstanceMethods.IInt))] - [KeptTypeInAssembly ("library.dll", typeof (InstanceMethods.IIntUnreferenced))] // Kept only because of the .override on the public implementation method - [KeptTypeInAssembly ("library.dll", typeof (InstanceMethods.IIntBase))] - [KeptTypeInAssembly ("library.dll", typeof (InstanceMethods.IIntDerived))] - [KeptTypeInAssembly ("library.dll", typeof (InstanceMethods.IGeneric<>))] - [KeptTypeInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodCalledDirectlyAndTwoGenericInterfacesUnreferenced))] - [KeptMemberInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodAccessedViaInterface), ["GetInt()"])] - [KeptMemberInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodAccessedDirectly), ["GetInt()"])] - [KeptMemberInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodAccessedViaReflection), ["GetInt()"])] - [KeptMemberInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodKeptByDynamicDependency), ["GetInt()"])] - [KeptMemberInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodCalledDirectlyAndInterfaceUnreferenced), ["GetInt()"])] - [KeptMemberInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodCalledDirectlyAndRecursiveInterfaceUnreferenced), ["GetInt()"])] - [KeptMemberInAssembly ("library.dll", typeof (InstanceMethods.IInt), ["GetInt()"])] - [KeptMemberInAssembly ("library.dll", typeof (InstanceMethods.IIntUnreferenced), ["GetInt()"])] - [KeptMemberInAssembly ("library.dll", typeof (InstanceMethods.IIntBase), ["GetInt()"])] - [KeptMemberInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodCalledDirectlyAndTwoGenericInterfacesUnreferenced), ["GetIntInt()"])] - [KeptMemberInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodCalledDirectlyAndTwoGenericInterfacesUnreferenced), ["GetIntFloat()"])] // Could be removed - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodAccessedViaInterface), "library.dll", typeof (InstanceMethods.IInt))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodAccessedDirectly), "library.dll", typeof (InstanceMethods.IInt))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodAccessedViaReflection), "library.dll", typeof (InstanceMethods.IInt))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodKeptByDynamicDependency), "library.dll", typeof (InstanceMethods.IInt))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodCalledDirectlyAndInterfaceUnreferenced), "library.dll", typeof (InstanceMethods.IIntUnreferenced))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (InstanceMethods.TypeWithMethodCalledDirectlyAndRecursiveInterfaceUnreferenced), "library.dll", typeof (InstanceMethods.IIntDerived))] - [KeptInterfaceOnTypeInAssembly ("library.dll", typeof (InstanceMethods.IIntDerived), "library.dll", typeof (InstanceMethods.IIntBase))] - [KeptInterfaceOnTypeInAssembly ("library.dll", "InstanceMethods/TypeWithMethodCalledDirectlyAndTwoGenericInterfacesUnreferenced", "library.dll", "InstanceMethods/IGeneric`1")] - [KeptInterfaceOnTypeInAssembly ("library.dll", "InstanceMethods/TypeWithMethodCalledDirectlyAndTwoGenericInterfacesUnreferenced", "library.dll", "InstanceMethods/IGeneric`1")] + [KeptTypeInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodAccessedViaInterface))] + [KeptTypeInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodAccessedDirectly))] + [KeptTypeInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodAccessedViaReflection))] + [KeptTypeInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodKeptByDynamicDependency))] + [KeptTypeInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodCalledDirectlyAndInterfaceUnreferenced))] + [KeptTypeInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodCalledDirectlyAndRecursiveInterfaceUnreferenced))] + [KeptTypeInAssembly("library.dll", typeof(InstanceMethods.IInt))] + [KeptTypeInAssembly("library.dll", typeof(InstanceMethods.IIntUnreferenced))] // Kept only because of the .override on the public implementation method + [KeptTypeInAssembly("library.dll", typeof(InstanceMethods.IIntBase))] + [KeptTypeInAssembly("library.dll", typeof(InstanceMethods.IIntDerived))] + [KeptTypeInAssembly("library.dll", typeof(InstanceMethods.IGeneric<>))] + [KeptTypeInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodCalledDirectlyAndTwoGenericInterfacesUnreferenced))] + [KeptMemberInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodAccessedViaInterface), ["GetInt()"])] + [KeptMemberInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodAccessedDirectly), ["GetInt()"])] + [KeptMemberInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodAccessedViaReflection), ["GetInt()"])] + [KeptMemberInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodKeptByDynamicDependency), ["GetInt()"])] + [KeptMemberInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodCalledDirectlyAndInterfaceUnreferenced), ["GetInt()"])] + [KeptMemberInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodCalledDirectlyAndRecursiveInterfaceUnreferenced), ["GetInt()"])] + [KeptMemberInAssembly("library.dll", typeof(InstanceMethods.IInt), ["GetInt()"])] + [KeptMemberInAssembly("library.dll", typeof(InstanceMethods.IIntUnreferenced), ["GetInt()"])] + [KeptMemberInAssembly("library.dll", typeof(InstanceMethods.IIntBase), ["GetInt()"])] + [KeptMemberInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodCalledDirectlyAndTwoGenericInterfacesUnreferenced), ["GetIntInt()"])] + [KeptMemberInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodCalledDirectlyAndTwoGenericInterfacesUnreferenced), ["GetIntFloat()"])] // Could be removed + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodAccessedViaInterface), "library.dll", typeof(InstanceMethods.IInt))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodAccessedDirectly), "library.dll", typeof(InstanceMethods.IInt))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodAccessedViaReflection), "library.dll", typeof(InstanceMethods.IInt))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodKeptByDynamicDependency), "library.dll", typeof(InstanceMethods.IInt))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodCalledDirectlyAndInterfaceUnreferenced), "library.dll", typeof(InstanceMethods.IIntUnreferenced))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(InstanceMethods.TypeWithMethodCalledDirectlyAndRecursiveInterfaceUnreferenced), "library.dll", typeof(InstanceMethods.IIntDerived))] + [KeptInterfaceOnTypeInAssembly("library.dll", typeof(InstanceMethods.IIntDerived), "library.dll", typeof(InstanceMethods.IIntBase))] + [KeptInterfaceOnTypeInAssembly("library.dll", "InstanceMethods/TypeWithMethodCalledDirectlyAndTwoGenericInterfacesUnreferenced", "library.dll", "InstanceMethods/IGeneric`1")] + [KeptInterfaceOnTypeInAssembly("library.dll", "InstanceMethods/TypeWithMethodCalledDirectlyAndTwoGenericInterfacesUnreferenced", "library.dll", "InstanceMethods/IGeneric`1")] #endif public class InstanceMethodsWithOverridesSwept { @@ -61,17 +61,17 @@ public class InstanceMethodsWithOverridesSwept public static void Main() { #if IL_ASSEMBLY_AVAILABLE - InstanceMethods.Test (); - typeof (InstanceMethods.TypeWithMethodAccessedViaReflection).GetMethod ("GetInt").Invoke (null, null); - new InstanceMethods.TypeWithMethodCalledDirectlyAndInterfaceUnreferenced ().GetInt (); - new InstanceMethods.TypeWithMethodCalledDirectlyAndRecursiveInterfaceUnreferenced ().GetInt (); - new InstanceMethods.TypeWithMethodCalledDirectlyAndTwoGenericInterfacesUnreferenced ().GetIntInt (); + InstanceMethods.Test(); + typeof(InstanceMethods.TypeWithMethodAccessedViaReflection).GetMethod("GetInt").Invoke(null, null); + new InstanceMethods.TypeWithMethodCalledDirectlyAndInterfaceUnreferenced().GetInt(); + new InstanceMethods.TypeWithMethodCalledDirectlyAndRecursiveInterfaceUnreferenced().GetInt(); + new InstanceMethods.TypeWithMethodCalledDirectlyAndTwoGenericInterfacesUnreferenced().GetIntInt(); #endif KeepTypeThroughDynamicDependency(); } #if IL_ASSEMBLY_AVAILABLE - [DynamicDependency ("GetInt()", typeof (InstanceMethods.TypeWithMethodKeptByDynamicDependency))] + [DynamicDependency("GetInt()", typeof(InstanceMethods.TypeWithMethodKeptByDynamicDependency))] #endif [Kept] public static void KeepTypeThroughDynamicDependency() diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/OverrideInCopyAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/OverrideInCopyAssembly.cs index 6f7dd19342f9c5..57a420e2822051 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/OverrideInCopyAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/OverrideInCopyAssembly.cs @@ -13,12 +13,12 @@ namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.StaticInterfaceMethods [SetupLinkerAction("link", "library")] [SetupLinkerAction("copy", "test")] /// - /// Regression test for issue: https://github.com/dotnet/runtime/issues/81746 - /// OverridesStaticInterfaceMethods.Method() (and Property.set/get) has an entry in .overrides pointing to IStaticAbstractMethods.Method. - /// IStaticAbstractMethods.Method() isn't referenced anywhere else and isn't otherwise needed. - /// Usually the interface method could be removed, and the pointer to it in the .overrides metadata would be removed - /// However, since OverridesStaticInterfaceMethods is in a 'copy' assembly, the .overrides metadata isn't swept. If we remove the method from the interface, - /// we have a "dangling reference" which makes the metadata invalid. + /// Regression test for issue: https://github.com/dotnet/runtime/issues/81746 + /// OverridesStaticInterfaceMethods.Method() (and Property.set/get) has an entry in .overrides pointing to IStaticAbstractMethods.Method. + /// IStaticAbstractMethods.Method() isn't referenced anywhere else and isn't otherwise needed. + /// Usually the interface method could be removed, and the pointer to it in the .overrides metadata would be removed + /// However, since OverridesStaticInterfaceMethods is in a 'copy' assembly, the .overrides metadata isn't swept. If we remove the method from the interface, + /// we have a "dangling reference" which makes the metadata invalid. /// static class OverrideInCopyAssembly { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/OverrideInSaveAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/OverrideInSaveAssembly.cs index 27d972ae9d677b..4bdae0d44fea9a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/OverrideInSaveAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/OverrideInSaveAssembly.cs @@ -15,12 +15,12 @@ namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.StaticInterfaceMethods [SetupCompileBefore("library.dll", new[] { "Dependencies/Library.cs" })] [SetupLinkerAction("link", "library")] /// - /// Regression test for issue: https://github.com/dotnet/runtime/issues/86242 - /// OverridesStaticInterfaceMethods.Method() (and Property.set/get) has an entry in .overrides pointing to IStaticAbstractMethods.Method. - /// IStaticAbstractMethods.Method() isn't referenced anywhere else and isn't otherwise needed. - /// Usually the interface method could be removed, and the pointer to it in the .overrides metadata would be removed - /// However, since OverridesStaticInterfaceMethods is in a 'save' assembly, the .overrides metadata isn't swept. If we remove the method from the interface, - /// we have a "dangling reference" which makes the metadata invalid. + /// Regression test for issue: https://github.com/dotnet/runtime/issues/86242 + /// OverridesStaticInterfaceMethods.Method() (and Property.set/get) has an entry in .overrides pointing to IStaticAbstractMethods.Method. + /// IStaticAbstractMethods.Method() isn't referenced anywhere else and isn't otherwise needed. + /// Usually the interface method could be removed, and the pointer to it in the .overrides metadata would be removed + /// However, since OverridesStaticInterfaceMethods is in a 'save' assembly, the .overrides metadata isn't swept. If we remove the method from the interface, + /// we have a "dangling reference" which makes the metadata invalid. /// static class OverrideInSaveAssembly { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/StaticAbstractInterfaceMethods.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/StaticAbstractInterfaceMethods.cs index cb20950059c1de..62f3a720afd2af 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/StaticAbstractInterfaceMethods.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/StaticInterfaceMethods/StaticAbstractInterfaceMethods.cs @@ -331,7 +331,7 @@ public class UnusedMethods : IStaticAndInstanceMethods //Bug //[Kept] - //[KeptOverride (typeof (IStaticAndInstanceMethods))] + //[KeptOverride(typeof(IStaticAndInstanceMethods))] static int IStaticAndInstanceMethods.StaticMethodExplicitImpl() => 0; public int InstanceMethod() => 0; @@ -474,7 +474,7 @@ public static void Test() [KeptInterface(typeof(IInheritsFromMultipleBases))] [KeptInterface(typeof(IBase1))] [KeptInterface(typeof(IBase2))] - // [RemovedInterface (typeof (IUnusedInterface))] + // [RemovedInterface(typeof(IUnusedInterface))] public class ImplementsIInheritsFromTwoBases : IInheritsFromMultipleBases { [Kept] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/VirtualMethodGetsStrippedIfImplementingMethodGetsInvokedDirectly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/VirtualMethodGetsStrippedIfImplementingMethodGetsInvokedDirectly.cs index befb5fd257a9ea..57fd2912ea511c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/VirtualMethodGetsStrippedIfImplementingMethodGetsInvokedDirectly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Inheritance.VirtualMethods/VirtualMethodGetsStrippedIfImplementingMethodGetsInvokedDirectly.cs @@ -26,7 +26,7 @@ class A : B { // Bug: https://github.com/dotnet/linker/issues/3078 // ILLink should mark for DirectCall as well as OverrideOnInstantiatedType, not just OverrideOnInstantiatedType - //[KeptBy (typeof(A), nameof(Foo), DependencyKind.DirectCall)] + //[KeptBy(typeof(A), nameof(Foo), DependencyKind.DirectCall)] [KeptBy(typeof(A), "OverrideOnInstantiatedType")] public override void Foo() { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/Dependencies/RootAllLibrary.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/Dependencies/RootAllLibrary.cs index b07212a04e1cd8..f779848dbe8b57 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/Dependencies/RootAllLibrary.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/Dependencies/RootAllLibrary.cs @@ -8,7 +8,7 @@ using Mono.Linker.Tests.Cases.Libraries.Dependencies; #if RootAllLibrary -[assembly: TypeForwardedTo (typeof (RootAllLibrary_ExportedType))] +[assembly: TypeForwardedTo(typeof(RootAllLibrary_ExportedType))] #endif namespace Mono.Linker.Tests.Cases.Libraries.Dependencies diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/RootLibraryInternalsWithIVT.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/RootLibraryInternalsWithIVT.cs index 1f63d79b9a99f0..dce9aca3084f58 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/RootLibraryInternalsWithIVT.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/RootLibraryInternalsWithIVT.cs @@ -3,9 +3,9 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; #if RootLibraryInternalsWithIVT -[assembly: InternalsVisibleToAttribute ("somename")] +[assembly: InternalsVisibleToAttribute("somename")] -[assembly: KeptAttributeAttribute (typeof (InternalsVisibleToAttribute))] +[assembly: KeptAttributeAttribute(typeof(InternalsVisibleToAttribute))] #endif namespace Mono.Linker.Tests.Cases.Libraries @@ -49,11 +49,11 @@ private void UnusedPrivateMethod() } #if RootLibraryInternalsWithIVT - [Kept] - internal interface InternalIface - { - [Kept] - void Foo (); - } + [Kept] + internal interface InternalIface + { + [Kept] + void Foo(); + } #endif } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/RootLibraryVisibleForwarders.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/RootLibraryVisibleForwarders.cs index 70e8c9f5999c03..1f03bd3bcf2b12 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/RootLibraryVisibleForwarders.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/RootLibraryVisibleForwarders.cs @@ -3,7 +3,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; #if RootLibraryVisibleForwarders -[assembly: TypeForwardedTo (typeof (ExternalPublic))] +[assembly: TypeForwardedTo(typeof(ExternalPublic))] #endif namespace Mono.Linker.Tests.Cases.Libraries diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/RootLibraryVisibleForwardersWithoutReference.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/RootLibraryVisibleForwardersWithoutReference.cs index a6546b342b385c..3335bfc2676a88 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/RootLibraryVisibleForwardersWithoutReference.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Libraries/RootLibraryVisibleForwardersWithoutReference.cs @@ -3,7 +3,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; #if RootLibraryVisibleForwarders -[assembly: TypeForwardedTo (typeof (ExternalPublic))] +[assembly: TypeForwardedTo(typeof(ExternalPublic))] #endif namespace Mono.Linker.Tests.Cases.Libraries diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkerAttributeRemoval.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkerAttributeRemoval.cs index 2fd85337b158d5..9a0e94df4b8917 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkerAttributeRemoval.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkerAttributeRemoval.cs @@ -18,8 +18,8 @@ namespace Mono.Linker.Tests.Cases.LinkAttributes [SetupCompileBefore("copyattribute.dll", new[] { "Dependencies/LinkerAttributeRemovalAttributeFromCopyAssembly.cs" })] [SetupLinkerAction("copy", "copyattribute")] #if !NET - [Reference ("System.dll")] - [SetupCompileBefore ("copyassembly.dll", new[] { "Dependencies/LinkerAttributeRemovalCopyAssembly.cs" }, references: new[] { "System.dll", "attribute.dll" })] + [Reference("System.dll")] + [SetupCompileBefore("copyassembly.dll", new[] { "Dependencies/LinkerAttributeRemovalCopyAssembly.cs" }, references: new[] { "System.dll", "attribute.dll" })] #else [SetupCompileBefore("copyassembly.dll", new[] { "Dependencies/LinkerAttributeRemovalCopyAssembly.cs" }, references: new[] { "attribute.dll" })] #endif @@ -51,7 +51,7 @@ namespace Mono.Linker.Tests.Cases.LinkAttributes [KeptTypeInAssembly("LinkerAttributeRemovalEmbeddedAndLazyLoad.dll", typeof(TypeWithEmbeddedAttributeToBeRemoved))] // This needs to fixed with lazy loading assembly refactoring - currently the assembly="*" only applies to assemblies in initial closure // The attribute should be removed and not kept as it is now - // [RemovedAttributeInAssembly ("LinkerAttributeRemovalEmbeddedAndLazyLoad.dll", typeof (EmbeddedAttributeToBeRemoved), typeof (TypeWithEmbeddedAttributeToBeRemoved))] + // [RemovedAttributeInAssembly("LinkerAttributeRemovalEmbeddedAndLazyLoad.dll", typeof(EmbeddedAttributeToBeRemoved), typeof(TypeWithEmbeddedAttributeToBeRemoved))] [KeptAttributeInAssembly("LinkerAttributeRemovalEmbeddedAndLazyLoad", typeof(EmbeddedAttributeToBeRemoved), typeof(TypeWithEmbeddedAttributeToBeRemoved))] [LogContains("IL2045: Mono.Linker.Tests.Cases.LinkAttributes.Dependencies.TypeOnCopyAssemblyWithAttributeUsage.TypeOnCopyAssemblyWithAttributeUsage(): Attribute 'Mono.Linker.Tests.Cases.LinkAttributes.Dependencies.TestAttributeReferencedAsTypeFromCopyAssemblyAttribute'")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkerAttributeRemovalConditional.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkerAttributeRemovalConditional.cs index 9d6cee63052043..b9b2b10635b504 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkerAttributeRemovalConditional.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkerAttributeRemovalConditional.cs @@ -124,7 +124,7 @@ public TestConditionalRemoveAttribute(string key, string value) { } - // Any usage with 100 key is removed + // Any usage with 100 key is removed // Any usage with "remove1" key is removed public TestConditionalRemoveAttribute(object key, char value, int ivalue) { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/OverrideAttributeRemoval.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/OverrideAttributeRemoval.cs index 9ccb6aa533e811..8725352b440f48 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/OverrideAttributeRemoval.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/OverrideAttributeRemoval.cs @@ -29,8 +29,8 @@ public static void Main() [return: KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] private string methodWithCustomAttribute( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] string parameterWithCustomAttribute) { return "this is a return value"; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/OverrideAttributeRemoval.xml b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/OverrideAttributeRemoval.xml index 3991969c573718..a3feb692a02cc3 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/OverrideAttributeRemoval.xml +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/OverrideAttributeRemoval.xml @@ -1,5 +1,8 @@ + + + diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/Dependencies/CanPreserveAnExportedType_Forwarder.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/Dependencies/CanPreserveAnExportedType_Forwarder.cs index cb6f81e481d6fe..183e26ada80b6d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/Dependencies/CanPreserveAnExportedType_Forwarder.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/Dependencies/CanPreserveAnExportedType_Forwarder.cs @@ -1,3 +1,3 @@ using System; -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.LinkXml.Dependencies.CanPreserveAnExportedType_Library))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.LinkXml.Dependencies.CanPreserveAnExportedType_Library))] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/Dependencies/UsedNonRequiredExportedTypeIsKeptWhenRooted_fwd.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/Dependencies/UsedNonRequiredExportedTypeIsKeptWhenRooted_fwd.cs index d323e7e63ebd90..f6f174fdb43e61 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/Dependencies/UsedNonRequiredExportedTypeIsKeptWhenRooted_fwd.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/Dependencies/UsedNonRequiredExportedTypeIsKeptWhenRooted_fwd.cs @@ -1,4 +1,4 @@ using System.Runtime.CompilerServices; using Mono.Linker.Tests.Cases.LinkXml; -[assembly: TypeForwardedTo (typeof (UsedNonRequiredExportedTypeIsKeptWhenRooted_Used))] +[assembly: TypeForwardedTo(typeof(UsedNonRequiredExportedTypeIsKeptWhenRooted_Used))] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/Dependencies/UsedNonRequiredExportedTypeIsKept_fwd.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/Dependencies/UsedNonRequiredExportedTypeIsKept_fwd.cs index ebda6ce2b6cbc8..e7f37e39ee30a4 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/Dependencies/UsedNonRequiredExportedTypeIsKept_fwd.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/Dependencies/UsedNonRequiredExportedTypeIsKept_fwd.cs @@ -1,6 +1,6 @@ using System.Runtime.CompilerServices; using Mono.Linker.Tests.Cases.LinkXml; -[assembly: TypeForwardedTo (typeof (UsedNonRequiredExportedTypeIsKept_Used1))] -[assembly: TypeForwardedTo (typeof (UsedNonRequiredExportedTypeIsKept_Used2))] -[assembly: TypeForwardedTo (typeof (UsedNonRequiredExportedTypeIsKept_Used3))] +[assembly: TypeForwardedTo(typeof(UsedNonRequiredExportedTypeIsKept_Used1))] +[assembly: TypeForwardedTo(typeof(UsedNonRequiredExportedTypeIsKept_Used2))] +[assembly: TypeForwardedTo(typeof(UsedNonRequiredExportedTypeIsKept_Used3))] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Logging/Dependencies/LogStep.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Logging/Dependencies/LogStep.cs index 96799b5c0d19d5..bd0e205feb4b8f 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Logging/Dependencies/LogStep.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Logging/Dependencies/LogStep.cs @@ -4,18 +4,18 @@ namespace Log { - public class LogStep : IStep - { - public void Process (LinkContext context) - { - var msgError = MessageContainer.CreateCustomErrorMessage ("Error", 6001); - var msgWarning = MessageContainer.CreateCustomWarningMessage (context, "Warning", 6002, origin: new MessageOrigin ("logtest", 1, 1), version: WarnVersion.Latest); - var msgInfo = MessageContainer.CreateInfoMessage ("Info"); - var msgDiagnostics = MessageContainer.CreateDiagnosticMessage ("Diagnostics"); - context.LogMessage (msgError); - context.LogMessage (msgWarning); - context.LogMessage (msgInfo); - context.LogMessage (msgDiagnostics); - } - } + public class LogStep : IStep + { + public void Process(LinkContext context) + { + var msgError = MessageContainer.CreateCustomErrorMessage("Error", 6001); + var msgWarning = MessageContainer.CreateCustomWarningMessage(context, "Warning", 6002, origin: new MessageOrigin("logtest", 1, 1), version: WarnVersion.Latest); + var msgInfo = MessageContainer.CreateInfoMessage("Info"); + var msgDiagnostics = MessageContainer.CreateDiagnosticMessage("Diagnostics"); + context.LogMessage(msgError); + context.LogMessage(msgWarning); + context.LogMessage(msgInfo); + context.LogMessage(msgDiagnostics); + } + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj b/src/tools/illink/test/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj index 94ce936df32b09..c2f17e501e555c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj @@ -66,4 +66,10 @@ + + + + + + diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyDeprecated.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyDeprecated.cs index f6e7ef0992f7b2..97d01b65659295 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyDeprecated.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyDeprecated.cs @@ -32,10 +32,10 @@ void Method2(out sbyte arg) [Kept] [PreserveDependency("Dependency1()", "Mono.Linker.Tests.Cases.PreserveDependencies.D")] - [PreserveDependency("Dependency2`1 ( T[] , System.Int32 ) ", "Mono.Linker.Tests.Cases.PreserveDependencies.D")] + [PreserveDependency("Dependency2`1(T[],System.Int32)", "Mono.Linker.Tests.Cases.PreserveDependencies.D")] [PreserveDependency(".ctor()", "Mono.Linker.Tests.Cases.PreserveDependencies.D")] // To avoid lazy body marking stubbing [PreserveDependency("field", "Mono.Linker.Tests.Cases.PreserveDependencies.D")] - [PreserveDependency("NextOne (Mono.Linker.Tests.Cases.PreserveDependencies.PreserveDependencyDeprecated+Nested&)", "Mono.Linker.Tests.Cases.PreserveDependencies.PreserveDependencyDeprecated+Nested")] + [PreserveDependency("NextOne(Mono.Linker.Tests.Cases.PreserveDependencies.PreserveDependencyDeprecated+Nested&)", "Mono.Linker.Tests.Cases.PreserveDependencies.PreserveDependencyDeprecated+Nested")] [PreserveDependency(".cctor()", "Mono.Linker.Tests.Cases.PreserveDependencies.PreserveDependencyDeprecated+Nested")] // Dependency on a property itself should be expressed as a dependency on one or both accessor methods [PreserveDependency("get_Property()", "Mono.Linker.Tests.Cases.PreserveDependencies.D")] @@ -46,7 +46,7 @@ public static void Method() [Kept] [PreserveDependency("field")] - [PreserveDependency("Method2 (System.SByte&)")] + [PreserveDependency("Method2(System.SByte&)")] [ExpectedWarning("IL2033")] public static void SameContext() { @@ -55,7 +55,7 @@ public static void SameContext() [Kept] [PreserveDependency("MissingType", "Mono.Linker.Tests.Cases.PreserveDependencies.MissingType")] [PreserveDependency("MissingMethod", "Mono.Linker.Tests.Cases.PreserveDependencies.D")] - [PreserveDependency("Dependency2`1 (T, System.Int32, System.Object)", "Mono.Linker.Tests.Cases.PreserveDependencies.D")] + [PreserveDependency("Dependency2`1(T, System.Int32, System.Object)", "Mono.Linker.Tests.Cases.PreserveDependencies.D")] [PreserveDependency("")] [PreserveDependency(".ctor()", "Mono.Linker.Tests.Cases.PreserveDependencies.PreserveDependencyDeprecated+NestedStruct")] [PreserveDependency(".cctor()", "Mono.Linker.Tests.Cases.PreserveDependencies.D")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyMethod.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyMethod.cs index 4a5e43fef5c796..335b5d75b8c66f 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyMethod.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyMethod.cs @@ -40,10 +40,10 @@ void Method2(out sbyte arg) [Kept] [PreserveDependency("Dependency1()", "Mono.Linker.Tests.Cases.PreserveDependencies.C")] - [PreserveDependency("Dependency2`1 ( T[] , System.Int32 ) ", "Mono.Linker.Tests.Cases.PreserveDependencies.C")] + [PreserveDependency("Dependency2`1(T[],System.Int32)", "Mono.Linker.Tests.Cases.PreserveDependencies.C")] [PreserveDependency(".ctor()", "Mono.Linker.Tests.Cases.PreserveDependencies.C")] // To avoid lazy body marking stubbing [PreserveDependency("field", "Mono.Linker.Tests.Cases.PreserveDependencies.C")] - [PreserveDependency("NextOne (Mono.Linker.Tests.Cases.PreserveDependencies.PreserveDependencyMethod+Nested&)", "Mono.Linker.Tests.Cases.PreserveDependencies.PreserveDependencyMethod+Nested")] + [PreserveDependency("NextOne(Mono.Linker.Tests.Cases.PreserveDependencies.PreserveDependencyMethod+Nested&)", "Mono.Linker.Tests.Cases.PreserveDependencies.PreserveDependencyMethod+Nested")] [PreserveDependency(".cctor()", "Mono.Linker.Tests.Cases.PreserveDependencies.PreserveDependencyMethod+Nested")] // Dependency on a property itself should be expressed as a dependency on one or both accessor methods [PreserveDependency("get_Property()", "Mono.Linker.Tests.Cases.PreserveDependencies.C")] @@ -53,7 +53,7 @@ public static void Method() [Kept] [PreserveDependency("field")] - [PreserveDependency("Method2 (System.SByte&)")] + [PreserveDependency("Method2(System.SByte&)")] public static void SameContext() { } @@ -61,7 +61,7 @@ public static void SameContext() [Kept] [PreserveDependency("MissingType", "Mono.Linker.Tests.Cases.PreserveDependencies.MissingType")] [PreserveDependency("MissingMethod", "Mono.Linker.Tests.Cases.PreserveDependencies.C")] - [PreserveDependency("Dependency2`1 (T, System.Int32, System.Object)", "Mono.Linker.Tests.Cases.PreserveDependencies.C")] + [PreserveDependency("Dependency2`1(T, System.Int32, System.Object)", "Mono.Linker.Tests.Cases.PreserveDependencies.C")] [PreserveDependency("")] [PreserveDependency(".ctor()", "Mono.Linker.Tests.Cases.PreserveDependencies.PreserveDependencyMethod+NestedStruct")] [PreserveDependency(".cctor()", "Mono.Linker.Tests.Cases.PreserveDependencies.C")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/References/Dependencies/CustomMarkHandlerSaveAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/References/Dependencies/CustomMarkHandlerSaveAssembly.cs index c95bd8b54ba842..f25670a0b998a8 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/References/Dependencies/CustomMarkHandlerSaveAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/References/Dependencies/CustomMarkHandlerSaveAssembly.cs @@ -5,11 +5,11 @@ public class CustomMarkHandlerSaveAssembly : IMarkHandler { - public void Initialize (LinkContext context, MarkContext markContext) + public void Initialize(LinkContext context, MarkContext markContext) { - markContext.RegisterMarkAssemblyAction (assembly => { + markContext.RegisterMarkAssemblyAction(assembly => { if (assembly.Name.Name == "saved") - context.Annotations.SetAction (assembly, AssemblyAction.Save); + context.Annotations.SetAction(assembly, AssemblyAction.Save); }); } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs index 31ea1e2ef941ea..8cd6abcd436d19 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs @@ -623,8 +623,8 @@ private static void TestNullArgsOnKnownType() [Kept] private static void TestNullArgsOnAnnotatedType( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor), - KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] Type type) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor), + KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] Type type) { Activator.CreateInstance(type, BindingFlags.Public | BindingFlags.Instance, null, null, CultureInfo.InvariantCulture); } @@ -632,8 +632,8 @@ private static void TestNullArgsOnAnnotatedType( [Kept] [ExpectedWarning("IL2067", nameof(DynamicallyAccessedMemberTypes) + "." + nameof(DynamicallyAccessedMemberTypes.NonPublicConstructors))] private static void TestNullArgsNonPublicOnly( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor), - KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] Type type) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor), + KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] Type type) { Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Instance, null, null, CultureInfo.InvariantCulture); } @@ -641,8 +641,8 @@ private static void TestNullArgsNonPublicOnly( [Kept] [ExpectedNoWarnings] private static void TestNullArgsNonPublicWithNonPublicAnnotation( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.NonPublicConstructors), - KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] Type type) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.NonPublicConstructors), + KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] Type type) { Activator.CreateInstance(type, nonPublic: true); } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/AssemblyImportedViaReflectionWithSweptReferences.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/AssemblyImportedViaReflectionWithSweptReferences.cs index fc19570f4abd14..029171f6bbc3b3 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/AssemblyImportedViaReflectionWithSweptReferences.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/AssemblyImportedViaReflectionWithSweptReferences.cs @@ -11,7 +11,7 @@ namespace Mono.Linker.Tests.Cases.Reflection [SetupCompileBefore("reference.dll", new[] { "Dependencies/AssemblyDependency.cs" }, addAsReference: false)] [SetupCompileBefore("library.dll", new[] { "Dependencies/AssemblyDependencyWithMultipleReferences.cs" }, new[] { "reference.dll", "unusedreference.dll" }, addAsReference: false)] // TODO: keep library even if type is not found in it (https://github.com/dotnet/linker/issues/1795) - // [KeptAssembly ("library")] + // [KeptAssembly("library")] public class AssemblyImportedViaReflectionWithSweptReferences { public static void Main() diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ConstructorUsedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ConstructorUsedViaReflection.cs index c8a8baee286d2a..c47145551875de 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ConstructorUsedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ConstructorUsedViaReflection.cs @@ -281,7 +281,7 @@ static void TestWithBindingFlagsAndTypes_EmptyTypes_DataFlow( [Kept] [ExpectedWarning("IL2070", nameof(Type.GetConstructor))] static void TestWithBindingFlagsAndTypes_NonEmptyTypes_DataFlow( - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] Type type) { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/Dependencies/CoreLibEmulator.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/Dependencies/CoreLibEmulator.cs index 2c83bab3d128e5..d18bf88ac03cfc 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/Dependencies/CoreLibEmulator.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/Dependencies/CoreLibEmulator.cs @@ -11,12 +11,12 @@ public class CoreLibEmulator public static void Test() { #if INCLUDE_CORELIB_IMPL - Type t = new Type(); - t.GetConstructor (BindingFlags.Default, null, new Type[] {}, null); - t.GetMethod ("name", new Type[] {}); - t.GetProperty ("name", new Type[] {}); - t.GetField ("name"); - t.GetEvent ("name"); + Type t = new Type(); + t.GetConstructor(BindingFlags.Default, null, new Type[] {}, null); + t.GetMethod("name", new Type[] {}); + t.GetProperty("name", new Type[] {}); + t.GetField("name"); + t.GetEvent("name"); #endif } } @@ -25,38 +25,38 @@ public static void Test() #if INCLUDE_CORELIB_IMPL namespace System { - public class Type - { - public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) => GetConstructor (bindingAttr, binder, CallingConventions.Any, types, modifiers); - - public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) - { - return null; - } - - public MethodInfo GetMethod (string name, Type [] types) => GetMethod (name, types, null); - public MethodInfo GetMethod (string name, Type [] types, ParameterModifier [] modifiers) - { - return null; - } - - public PropertyInfo GetProperty (string name, Type [] types) => GetProperty (name, null, types); - public PropertyInfo GetProperty (string name, Type returnType, Type [] types) - { - return null; - } - - public FieldInfo GetField (string name) => GetField (name, BindingFlags.Default); - public FieldInfo GetField (string name, BindingFlags bindingAttr) - { - return null; - } - - public EventInfo GetEvent (string name) => GetEvent (name, BindingFlags.Default); - public EventInfo GetEvent (string name, BindingFlags bindingAttr) - { - return null; - } - } + public class Type + { + public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) => GetConstructor(bindingAttr, binder, CallingConventions.Any, types, modifiers); + + public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) + { + return null; + } + + public MethodInfo GetMethod(string name, Type [] types) => GetMethod(name, types, null); + public MethodInfo GetMethod(string name, Type [] types, ParameterModifier [] modifiers) + { + return null; + } + + public PropertyInfo GetProperty(string name, Type [] types) => GetProperty(name, null, types); + public PropertyInfo GetProperty(string name, Type returnType, Type [] types) + { + return null; + } + + public FieldInfo GetField(string name) => GetField(name, BindingFlags.Default); + public FieldInfo GetField(string name, BindingFlags bindingAttr) + { + return null; + } + + public EventInfo GetEvent(string name) => GetEvent(name, BindingFlags.Default); + public EventInfo GetEvent(string name, BindingFlags bindingAttr) + { + return null; + } + } } #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/EventHanderTypeGetInvokeMethod.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/EventHanderTypeGetInvokeMethod.cs index b92f9ec71a6695..223186b5fd03d9 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/EventHanderTypeGetInvokeMethod.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/EventHanderTypeGetInvokeMethod.cs @@ -7,91 +7,95 @@ namespace Mono.Linker.Tests.Cases.Reflection { - [ExpectedNoWarnings] - // Necessary to allow trimming unused EventInfo methods, - // making the test behavior more consistent with ILC. - [SetupLinkerTrimMode ("link")] - public class EventHanderTypeGetInvokeMethod - { - public static void Main () - { - EventDelegate.Test (); - NonDelegate.Test (); - } + [ExpectedNoWarnings] + // Necessary to allow trimming unused EventInfo methods, + // making the test behavior more consistent with ILC. + [SetupLinkerTrimMode("link")] + public class EventHanderTypeGetInvokeMethod + { + public static void Main() + { + EventDelegate.Test(); + NonDelegate.Test(); + } - class EventDelegate - { - [Kept] - [KeptBackingField] - [KeptEventAddMethod] - [KeptEventRemoveMethod] - public static event EventHandler MyEvent; + class EventDelegate + { + [Kept] + [KeptBackingField] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + public static event EventHandler MyEvent; - [Kept] - public static void Test () - { - var eventInfo = typeof (EventDelegate).GetEvent (nameof (MyEvent)); - var invoke = eventInfo.EventHandlerType.GetMethod ("Invoke"); - } - } + [Kept] + public static void Test() + { + var eventInfo = typeof(EventDelegate).GetEvent(nameof(MyEvent)); + var invoke = eventInfo.EventHandlerType.GetMethod("Invoke"); + } + } - class NonDelegate - { - [Kept] - [KeptBaseType (typeof (EventInfo))] - [KeptMember (".ctor()")] - class CustomEventInfo : EventInfo - { - [Kept] - public override Type EventHandlerType { - [Kept] - get => typeof (NonDelegate); - } + class NonDelegate + { + [Kept] + [KeptBaseType(typeof(EventInfo))] + [KeptMember(".ctor()")] + class CustomEventInfo : EventInfo + { + [Kept] + public override Type EventHandlerType + { + [Kept] + get => typeof(NonDelegate); + } - // ILLink keeps more methods on MemberInfo due for stack trace support, - // but differences in this class are not important for this testcase. + // ILLink keeps more methods on MemberInfo due for stack trace support, + // but differences in this class are not important for this testcase. - [Kept (By = Tool.Trimmer)] - public override bool IsDefined (Type type, bool inherit) => throw null; - public override object[] GetCustomAttributes (bool inherit) => throw null; - [Kept (By = Tool.Trimmer)] - public override object[] GetCustomAttributes (Type attributeType, bool inherit) => throw null; - [Kept (By = Tool.Trimmer)] - public override string Name { - [Kept (By = Tool.Trimmer)] - get => throw null; - } - [Kept (By = Tool.Trimmer)] - public override Type ReflectedType { - [Kept (By = Tool.Trimmer)] - get => throw null; - } - [Kept (By = Tool.Trimmer)] - public override Type DeclaringType { - [Kept (By = Tool.Trimmer)] - get => throw null; - } - [Kept (By = Tool.Trimmer)] - public override MethodInfo GetAddMethod (bool nonPublic) => throw null; - public override MethodInfo GetRemoveMethod (bool nonPublic) => throw null; - public override MethodInfo GetRaiseMethod (bool nonPublic) => throw null; - public override EventAttributes Attributes => throw null; - } + [Kept(By = Tool.Trimmer)] + public override bool IsDefined(Type type, bool inherit) => throw null; + public override object[] GetCustomAttributes(bool inherit) => throw null; + [Kept(By = Tool.Trimmer)] + public override object[] GetCustomAttributes(Type attributeType, bool inherit) => throw null; + [Kept(By = Tool.Trimmer)] + public override string Name + { + [Kept(By = Tool.Trimmer)] + get => throw null; + } + [Kept(By = Tool.Trimmer)] + public override Type ReflectedType + { + [Kept(By = Tool.Trimmer)] + get => throw null; + } + [Kept(By = Tool.Trimmer)] + public override Type DeclaringType + { + [Kept(By = Tool.Trimmer)] + get => throw null; + } + [Kept(By = Tool.Trimmer)] + public override MethodInfo GetAddMethod(bool nonPublic) => throw null; + public override MethodInfo GetRemoveMethod(bool nonPublic) => throw null; + public override MethodInfo GetRaiseMethod(bool nonPublic) => throw null; + public override EventAttributes Attributes => throw null; + } - // Strictly speaking this should be kept, but trimmer doesn't see through the custom event info. - // See discussion at https://github.com/dotnet/runtime/issues/114113. - [RequiresUnreferencedCode (nameof (Invoke))] - public void Invoke () - { - } + // Strictly speaking this should be kept, but trimmer doesn't see through the custom event info. + // See discussion at https://github.com/dotnet/runtime/issues/114113. + [RequiresUnreferencedCode(nameof(Invoke))] + public void Invoke() + { + } - [Kept] - [ExpectedWarning ("IL2075", nameof (Type.GetMethod), Tool.Analyzer, - "ILLink/ILC intrinsic handling assumes EventHandlerType is a delegate: https://github.com/dotnet/runtime/issues/114113")] - public static void Test () - { - new CustomEventInfo ().EventHandlerType.GetMethod ("Invoke"); - } - } - } + [Kept] + [ExpectedWarning("IL2075", nameof(Type.GetMethod), Tool.Analyzer, + "ILLink/ILC intrinsic handling assumes EventHandlerType is a delegate: https://github.com/dotnet/runtime/issues/114113")] + public static void Test() + { + new CustomEventInfo().EventHandlerType.GetMethod("Invoke"); + } + } + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MemberUsedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MemberUsedViaReflection.cs index bf8d0ccb6a4cbf..9199acc2ca1cd9 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MemberUsedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MemberUsedViaReflection.cs @@ -112,13 +112,13 @@ static void TestDataFlowType() } [Kept] - private static void TestDataFlowWithAnnotation([KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.PublicFields | - DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicNestedTypes)] Type type) + private static void TestDataFlowWithAnnotation([KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | + DynamicallyAccessedMemberTypes.PublicEvents | + DynamicallyAccessedMemberTypes.PublicFields | + DynamicallyAccessedMemberTypes.PublicMethods | + DynamicallyAccessedMemberTypes.PublicProperties | + DynamicallyAccessedMemberTypes.PublicNestedTypes)] Type type) { var members = type.GetMember("PrefixLookup*", BindingFlags.Public | BindingFlags.Static); } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MembersUsedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MembersUsedViaReflection.cs index 0f9db0c03a4276..1e6be694e47bdd 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MembersUsedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MembersUsedViaReflection.cs @@ -71,13 +71,13 @@ static void TestDataFlowType() } [Kept] - private static void TestDataFlowWithAnnotation([KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.PublicFields | - DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicNestedTypes)] Type type) + private static void TestDataFlowWithAnnotation([KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | + DynamicallyAccessedMemberTypes.PublicEvents | + DynamicallyAccessedMemberTypes.PublicFields | + DynamicallyAccessedMemberTypes.PublicMethods | + DynamicallyAccessedMemberTypes.PublicProperties | + DynamicallyAccessedMemberTypes.PublicNestedTypes)] Type type) { var properties = type.GetMembers(BindingFlags.Public | BindingFlags.Static); } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MethodUsedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MethodUsedViaReflection.cs index dfb126e8a57192..bdd8ee9feba73a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MethodUsedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MethodUsedViaReflection.cs @@ -30,6 +30,7 @@ public static void Main() GetMethod_Name_BindingAttr_Types.TestNameBindingFlagsAndTypes(); GetMethod_Name_GenericParameterCount_Types.TestNameWithIntAndType(); GetMethod_Name_GenericParameterCount_Types_Modifiers.TestNameWithIntAndTypeAndModifiers(); + GetMethod_Name_GenericParameterCount_BindingAttr_Types.TestNameWithIntAndBindingFlagsAndTypes(); GetMethod_Name_GenericParameterCount_BindingAttr_Binder_Types_Modifiers.TestNameWithIntAndBindingFlags(); GetMethod_Name_GenericParameterCount_BindingAttr_Binder_Types_Modifiers_PrivateBinding.TestNameWithIntAndPrivateBindingFlags(); GetMethod_Name_GenericParameterCount_BindingAttr_Binder_CallConvention_Types_Modifiers.TestNameWithIntBindingFlagsCallingConventionParameter(); @@ -486,6 +487,42 @@ public static void TestNameWithIntAndTypeAndModifiers() } } + // GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, Type[] types) + [Kept] + class GetMethod_Name_GenericParameterCount_BindingAttr_Types + { + private static int OnlyCalledViaReflection() + { + return 42; + } + private int OnlyCalledViaReflection(int foo) + { + return 43; + } + [Kept] + public int OnlyCalledViaReflection(int foo, int bar) + { + return 44; + } + [Kept] + public static int OnlyCalledViaReflection(int foo, int bar, int baz) + { + return 45; + } + [Kept] + public static int OnlyCalledViaReflection(string foo, string bar) + { + return 46; + } + + [Kept] + public static void TestNameWithIntAndBindingFlagsAndTypes() + { + var method = typeof(GetMethod_Name_GenericParameterCount_BindingAttr_Types).GetMethod("OnlyCalledViaReflection", 1, BindingFlags.Public, new Type[] { typeof(int) }); + method.Invoke(null, new object[] { }); + } + } + // GetMethod(string name, int genericParameterCount, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) [Kept] class GetMethod_Name_GenericParameterCount_BindingAttr_Binder_Types_Modifiers diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ObjectGetType.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ObjectGetType.cs index 4cee43eb033dfe..59f7da0e2cabec 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ObjectGetType.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ObjectGetType.cs @@ -2,9 +2,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Reflection; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Reflection; using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Cases.Expectations.Helpers; @@ -1373,12 +1373,15 @@ public void Method() { } [Kept] static AnnotatedBase GetInstance() => new Derived(); + [Kept] + static AnnotatedBase GetDerivedWithInterfaceInstance() => new DerivedWithInterface(); + [Kept] public static void Test() { Type t = GetInstance().GetType(); t.RequiresAll(); - var t2 = typeof(DerivedWithInterface); + var t2 = GetDerivedWithInterfaceInstance().GetType(); } } @@ -1530,7 +1533,7 @@ class Target } [Kept] - [UnexpectedWarning("IL2072", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/93720")] + [UnexpectedWarning("IL2072", Tool.All, "https://github.com/dotnet/runtime/issues/93720")] static void TestIsInstOf(object o) { if (o is Target t) @@ -1540,7 +1543,7 @@ static void TestIsInstOf(object o) } [Kept] - [ExpectedWarning("IL2072", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/93720")] + [ExpectedWarning("IL2072", Tool.All, "https://github.com/dotnet/runtime/issues/93720")] static void TestIsInstOfMismatch(object o) { if (o is Target t) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeDelegator.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeDelegator.cs index 24e98461a0db2a..b48d985ff8b8f8 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeDelegator.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeDelegator.cs @@ -54,8 +54,8 @@ static void TestNoValue() [Kept] [ExpectedWarning("IL2067", nameof(DataFlowTypeExtensions.RequiresPublicFields))] static void TestDataFlowPropagation( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type typeWithPublicMethods = null) { var typeDelegator = new System.Reflection.TypeDelegator(typeWithPublicMethods); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs index 02c8f5373b67e0..eb28b22136631a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs @@ -18,17 +18,19 @@ namespace Mono.Linker.Tests.Cases.Reflection public class TypeHierarchyReflectionWarnings { [ExpectedWarning("IL2026", "--AnnotatedRUCPublicMethods--")] + [ExpectedWarning("IL2026", "DerivedFromAnnotatedPublicParameterlessConstructor()")] + [ExpectedWarning("IL2026", "AnnotatedPublicParameterlessConstructor()")] public static void Main() { annotatedBase.GetType().RequiresPublicMethods(); var baseType = annotatedBaseSharedByNestedTypes.GetType(); baseType.RequiresPublicNestedTypes(); baseType.RequiresPublicMethods(); - var derivedType = typeof(DerivedWithNestedTypes); + var derivedType = new DerivedWithNestedTypes(); // Reference to the derived type should apply base annotations - var t1 = typeof(DerivedFromAnnotatedBase); - var t2 = typeof(AnnotatedDerivedFromAnnotatedBase); - var t3 = typeof(AnnotatedAllDerivedFromAnnotatedBase); + var t1 = new DerivedFromAnnotatedBase(); + var t2 = new AnnotatedDerivedFromAnnotatedBase(); + var t3 = new AnnotatedAllDerivedFromAnnotatedBase(); annotatedDerivedFromBase.GetType().RequiresPublicMethods(); annotatedPublicNestedTypes.GetType().RequiresPublicNestedTypes(); derivedFromAnnotatedDerivedFromBase.GetType().RequiresPublicFields(); @@ -42,8 +44,8 @@ public static void Main() annotatedAll.GetType().RequiresAll(); var t4 = typeof(DerivedFromAnnotatedAll1); var t5 = typeof(DerivedFromAnnotatedAll2); - var t6 = typeof(DerivedFromAnnotatedAllWithInterface); - var t7 = typeof(DerivedFromAnnotatedPublicParameterlessConstructor); + var t6 = new DerivedFromAnnotatedAllWithInterface(); + var t7 = new DerivedFromAnnotatedPublicParameterlessConstructor(); annotatedRUCPublicMethods.GetType().RequiresPublicMethods(); // Instantiate these types just so things are considered reachable @@ -55,6 +57,10 @@ public static void Main() _ = new AnnotatedInterfaces(); _ = new AnnotatedPublicNestedTypes(); _ = new AnnotatedRUCPublicMethods(); + _ = new AnnotatedAll(); + _ = new AnnotatedPublicParameterlessConstructor(); + _ = new AnnotatedBase(); + _ = new AnnotatedBaseSharedByNestedTypes(); // Check that this field doesn't produce a warning even if it is kept // for some non-reflection access. @@ -122,8 +128,8 @@ public void RUCMethod() { } [Kept] [ExpectedWarning("IL2114", nameof(AnnotatedAll), nameof(DAMMethod))] public void DAMMethod( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t ) { } @@ -184,8 +190,8 @@ public void RUCMethod() { } [Kept] [ExpectedWarning("IL2114", nameof(AnnotatedPublicMethods), nameof(DAMMethod))] public void DAMMethod( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t ) { } @@ -199,8 +205,8 @@ Type t [Kept] [ExpectedWarning("IL2114", nameof(AnnotatedPublicMethods), nameof(DAMVirtualMethod))] public virtual void DAMVirtualMethod( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type ) { } @@ -358,6 +364,7 @@ public void RUCMethod() { } } [KeptBaseType(typeof(AnnotatedBase))] + [KeptMember(".ctor()")] class DerivedFromAnnotatedBase : AnnotatedBase { [Kept] @@ -369,6 +376,7 @@ public void RUCMethod() { } [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [KeptBaseType(typeof(AnnotatedBase))] + [KeptMember(".ctor()")] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields)] // No warning for public methods on base type because that annotation is already // inherited from the base type. @@ -595,6 +603,7 @@ public void RUCMethod() { } } [KeptBaseType(typeof(AnnotatedBaseSharedByNestedTypes))] + [KeptMember(".ctor()")] // Nested types that share the outer class base type can produce warnings about base methods of the annotated type. [ExpectedWarning("IL2113", "--RUC on AnnotatedBaseSharedByNestedTypes.RUCMethod--")] class DerivedWithNestedTypes : AnnotatedBaseSharedByNestedTypes diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs index 0c06f9f8915a39..f6074ab80d487c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchySuppressions.cs @@ -27,15 +27,21 @@ public static void Main() // derived types to access annotated methods without any warnings: derivedFromSuppressed.GetType().GetMethod("RUCDerivedMethod"); + _ = new Unsuppressed(); + _ = new Suppressed(); _ = new AnnotatedAllSuppressed(); + _ = new DerivedFromUnsuppressed1(); + _ = new DerivedFromSuppressed1(); + _ = new SuppressedOnDerived1(); + _ = new SuppressedBaseWarningsOnDerived(); } [Kept] static void UseDerivedTypes() { - var t = typeof(DerivedFromUnsuppressed2); - var t2 = typeof(DerivedFromSuppressed2); - var t3 = typeof(SuppressedOnDerived2); + _ = new DerivedFromUnsuppressed2(); + _ = new DerivedFromSuppressed2(); + _ = new SuppressedOnDerived2(); } [Kept] @@ -49,20 +55,21 @@ static void UseDerivedTypes() [Kept] static void RequireMethods( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) { } [Kept] static void RequireAll( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type) { } [Kept] [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [KeptMember(".ctor()")] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] class Unsuppressed { @@ -74,6 +81,7 @@ public void RUCMethod() { } } [Kept] + [KeptMember(".ctor()")] [KeptBaseType(typeof(Unsuppressed))] class DerivedFromUnsuppressed1 : Unsuppressed { @@ -85,6 +93,7 @@ public void DerivedRUCMethod() { } } [Kept] + [KeptMember(".ctor()")] [KeptBaseType(typeof(Unsuppressed))] class DerivedFromUnsuppressed2 : Unsuppressed { @@ -98,6 +107,7 @@ public void DerivedRUCMethod() { } [Kept] [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [KeptAttributeAttribute(typeof(UnconditionalSuppressMessageAttribute))] + [KeptMember(".ctor()")] [UnconditionalSuppressMessage("TrimAnalysis", "IL2112")] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] class Suppressed @@ -110,6 +120,7 @@ public void RUCMethod() { } [Kept] [KeptBaseType(typeof(Suppressed))] + [KeptMember(".ctor()")] class DerivedFromSuppressed1 : Suppressed { [Kept] @@ -121,6 +132,7 @@ public void RUCDerivedMethod() { } [Kept] [KeptBaseType(typeof(Suppressed))] + [KeptMember(".ctor()")] class DerivedFromSuppressed2 : Suppressed { [Kept] @@ -132,6 +144,7 @@ public void RUCDerivedMethod() { } [Kept] [KeptBaseType(typeof(Unsuppressed))] + [KeptMember(".ctor()")] class SuppressedOnDerived1 : Unsuppressed { [Kept] @@ -144,6 +157,7 @@ public void DerivedRUCMethod() { } [Kept] [KeptBaseType(typeof(Unsuppressed))] + [KeptMember(".ctor()")] class SuppressedOnDerived2 : Unsuppressed { [Kept] @@ -156,6 +170,7 @@ public void DerivedRUCMethod() { } [Kept] [KeptBaseType(typeof(Unsuppressed))] + [KeptMember(".ctor()")] class SuppressedBaseWarningsOnDerived : Unsuppressed { [Kept] @@ -189,8 +204,8 @@ public static void RUCMethod() { } [KeptAttributeAttribute(typeof(UnconditionalSuppressMessageAttribute))] [UnconditionalSuppressMessage("TrimAnalysis", "IL2114")] public void DAMTMethod( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t ) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeMap.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeMap.cs index e948810bfbb9ab..9e7d3537861fbc 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeMap.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeMap.cs @@ -4,29 +4,46 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using Mono.Linker; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; using Mono.Linker.Tests.Cases.Reflection; +[assembly: KeptAttributeAttribute(typeof(TypeMapAttribute), By = Tool.Trimmer)] +[assembly: KeptAttributeAttribute(typeof(TypeMapAssociationAttribute), By = Tool.Trimmer)] [assembly: TypeMap("TrimTargetIsTarget", typeof(TargetAndTrimTarget), typeof(TargetAndTrimTarget))] [assembly: TypeMap("TrimTargetIsUnrelated", typeof(TargetType), typeof(TrimTarget))] -[assembly: TypeMap("TrimTargetIsAllocatedNoTypeCheckClass", typeof(TargetType2), typeof(AllocatedNoTypeCheckClass))] -[assembly: TypeMap("TrimTargetIsAllocatedNoTypeCheckStruct", typeof(TargetType3), typeof(AllocatedNoTypeCheckStruct))] -[assembly: TypeMap("TrimTargetIsUnreferenced", typeof(UnreferencedTargetType), typeof(UnreferencedTrimTarget))] +[assembly: TypeMap(nameof(AllocatedNoTypeCheckClassTarget), typeof(AllocatedNoTypeCheckClassTarget), typeof(AllocatedNoTypeCheckClass))] +[assembly: TypeMap(nameof(AlloctedNoTypeCheckStructTarget), typeof(AlloctedNoTypeCheckStructTarget), typeof(AllocatedNoTypeCheckStruct))] +[assembly: TypeMap(nameof(UnreferencedTargetType), typeof(UnreferencedTargetType), typeof(UnreferencedTrimTarget))] +[assembly: TypeMap("TypeMapEntryOnly", typeof(TypeMapEntryOnly))] +[assembly: TypeMap(nameof(UnboxedOnlyTarget), typeof(UnboxedOnlyTarget), typeof(UnboxedOnly))] +[assembly: TypeMap("TypedRefSource", typeof(MakeRefTargetType), typeof(MakeRef))] +[assembly: TypeMap("TypedRefTarget", typeof(RefValueTargetType), typeof(RefValue))] +[assembly: TypeMap("Constrained", typeof(ConstrainedTarget), typeof(Constrained))] +[assembly: TypeMap("ConstrainedStatic", typeof(ConstraintedStaticTarget), typeof(ConstrainedStatic))] +[assembly: TypeMap("Ldobj", typeof(LdobjTarget), typeof(LdobjType))] +[assembly: TypeMap("ArrayElement", typeof(ArrayElementTarget), typeof(ArrayElement))] +[assembly: TypeMap("TrimTargetIsAllocatedNoTypeCheckNoBoxStruct", typeof(ConstructedNoTypeCheckOrBoxTarget), typeof(ConstructedNoTypeCheckNoBoxStruct))] [assembly: TypeMapAssociation(typeof(SourceClass), typeof(ProxyType))] -[assembly: TypeMapAssociation(typeof(TypeCheckOnlyClass), typeof(ProxyType2))] -[assembly: TypeMapAssociation(typeof(AllocatedNoBoxStructType), typeof(ProxyType3))] +[assembly: TypeMapAssociation(typeof(TypeCheckOnlyClass), typeof(TypeCheckOnlyProxy))] +[assembly: TypeMapAssociation(typeof(AllocatedNoBoxStructType), typeof(AllocatedNoBoxProxy))] [assembly: TypeMapAssociation(typeof(I), typeof(IImpl))] [assembly: TypeMapAssociation(typeof(IInterfaceWithDynamicImpl), typeof(IDynamicImpl))] +[assembly: TypeMapAssociation(typeof(ArrayElement), typeof(ArrayElementProxy))] [assembly: TypeMap("UnusedName", typeof(UnusedTargetType), typeof(TrimTarget))] [assembly: TypeMapAssociation(typeof(UnusedSourceClass), typeof(UnusedProxyType))] +[assembly: TypeMap("ClassWithStaticMethod", typeof(TargetType4), typeof(ClassWithStaticMethod))] +[assembly: TypeMap("ClassWithStaticMethodAndField", typeof(TargetType5), typeof(ClassWithStaticMethodAndField))] namespace Mono.Linker.Tests.Cases.Reflection { [Kept] - [IgnoreTestCase("Trimmer support is currently not implemented", IgnoredBy = Tool.Trimmer)] + [SetupCompileArgument("/unsafe")] class TypeMap { [Kept] @@ -34,22 +51,14 @@ class TypeMap public static void Main(string[] args) { object t = Activator.CreateInstance(Type.GetType(args[1])); - if (t is TargetAndTrimTarget) - { - Console.WriteLine("Type deriving from TargetAndTrimTarget instantiated."); - } - else if (t is TrimTarget) - { - Console.WriteLine("Type deriving from TrimTarget instantiated."); - } - else if (t is IInterfaceWithDynamicImpl d) + CheckTargetAndTrimTarget(t); + CheckTrimTarget(t); + CheckTypeCheckOnlyClass(t); + Unbox(t); + if (t is IInterfaceWithDynamicImpl d) { d.Method(); } - else if (t is TypeCheckOnlyClass typeCheckOnlyClass) - { - Console.WriteLine("Type deriving from TypeCheckOnlyClass instantiated."); - } Console.WriteLine("Hash code of SourceClass instance: " + new SourceClass().GetHashCode()); Console.WriteLine("Hash code of UsedClass instance: " + new UsedClass().GetHashCode()); @@ -64,6 +73,114 @@ public static void Main(string[] args) AllocatedNoBoxStructType allocatedNoBoxStructType = new AllocatedNoBoxStructType(Random.Shared.Next()); Console.WriteLine("AllocatedNoBoxStructType value: " + allocatedNoBoxStructType.Value); Console.WriteLine(proxyMap[typeof(AllocatedNoBoxStructType)]); + ClassWithStaticMethod.StaticMethod(); + + Console.WriteLine(ClassWithStaticMethodAndField.StaticMethod()); + + unsafe + { + delegate* staticMethodPtr = &ClassWithStaticMethod.StaticMethod; + staticMethodPtr(); + } + + MakeRef s = default; + + TypedReference r = __makeref(s); + + RefValue t2 = __refvalue(r, RefValue); + + ConstrainedCall(default); + + static void ConstrainedCall<[KeptGenericParamAttributes(GenericParameterAttributes.DefaultConstructorConstraint | GenericParameterAttributes.NotNullableValueTypeConstraint)] T>(T t) where T : struct, IInterface + { + t.Method(); + } + + ConstrainedStaticCall(default); + + static void ConstrainedStaticCall(T t) where T : IStaticInterface + { + T.Method(); + } + + unsafe + { + LdobjType* ptr = (LdobjType*)NativeMemory.AllocZeroed((nuint)sizeof(LdobjType)); + LdobjType val = *ptr; + Console.WriteLine(val.Value); + NativeMemory.Free(ptr); + } + + Console.WriteLine(new ArrayElement[1]); + + Console.WriteLine(new ConstructedNoTypeCheckNoBoxStruct(42).Value); + } + + [Kept] + private static void CheckTargetAndTrimTarget(object o) + { + if (o is TargetAndTrimTarget) + { + Console.WriteLine("Type deriving from TargetAndTrimTarget instantiated."); + } + } + + [Kept] + [ExpectedInstructionSequence([ + "nop", + "ldarg.0", + "pop", + "ldnull", + "ldnull", + "cgt.un", + "stloc.0", + "ldloc.0", + "brfalse.s il_18", + "nop", + "ldstr 'Type deriving from TypeCheckOnlyClass instantiated.'", + "call System.Void System.Console::WriteLine(System.String)", + "nop", + "nop", + "ret", + ])] + private static void CheckTypeCheckOnlyClass(object o) + { + if (o is TypeCheckOnlyClass) + { + Console.WriteLine("Type deriving from TypeCheckOnlyClass instantiated."); + } + } + + [Kept] + [ExpectedInstructionSequence([ + "nop", + "ldarg.0", + "pop", + "ldnull", + "ldnull", + "cgt.un", + "stloc.0", + "ldloc.0", + "brfalse.s il_18", + "nop", + "ldstr 'Type deriving from TrimTarget instantiated.'", + "call System.Void System.Console::WriteLine(System.String)", + "nop", + "nop", + "ret" + ])] + private static void CheckTrimTarget(object o) + { + if (o is TrimTarget) + { + Console.WriteLine("Type deriving from TrimTarget instantiated."); + } + } + + [Kept] + private static UnboxedOnly Unbox(object o) + { + return (UnboxedOnly) o; } [Kept] @@ -74,7 +191,7 @@ private static IReadOnlyDictionary GetExternalTypeMap() } } - [Kept(By = Tool.Trimmer)] + [Kept] class UsedTypeMap; [Kept] @@ -97,6 +214,7 @@ class SourceClass; [Kept] class ProxyType; + [Kept] class UnusedTypeMap; class UnusedTargetType; class UnusedSourceClass; @@ -137,15 +255,134 @@ class AllocatedNoTypeCheckClass; struct AllocatedNoTypeCheckStruct; [Kept] - class TargetType2; + class TypeMapEntryOnly; [Kept] - class TargetType3; + class AllocatedNoTypeCheckClassTarget; [Kept] + class AlloctedNoTypeCheckStructTarget; + + [Kept(By = Tool.NativeAot)] // Kept by NativeAot by the scanner. It is not kept during codegen. class TypeCheckOnlyClass; - class ProxyType2; + class TargetType4; + + [Kept] + class ClassWithStaticMethod + { + [Kept] + public static void StaticMethod() { } + } + + class TargetType5; + + [Kept] + class ClassWithStaticMethodAndField + { + [Kept] + private static int i; + [Kept] + public static int StaticMethod() => i; + } + + [Kept] + class UnboxedOnlyTarget; + + [Kept] + struct UnboxedOnly; + + [Kept] + class MakeRefTargetType; + + [Kept] + class RefValueTargetType; + + [Kept] + struct MakeRef; + + [Kept] + struct RefValue; + + [Kept(By = Tool.Trimmer)] // NativeAOT can devirtualize the constrained call, so it can remove the interface entirely. + class ConstrainedTarget; + + [Kept(By = Tool.Trimmer)] + interface IInterface + { + [Kept(By = Tool.Trimmer)] + void Method(); + } + + [Kept] + [KeptInterface(typeof(IInterface), By = Tool.Trimmer)] + struct Constrained : IInterface + { + [Kept] + void IInterface.Method() + { + Console.WriteLine("Constrained.Method called"); + } + } + + [Kept(By = Tool.Trimmer)] // NativeAot can devirtualize the constrained call, so it can remove the interface entirely. + class ConstraintedStaticTarget; + + [Kept(By = Tool.Trimmer)] + interface IStaticInterface + { + [Kept(By = Tool.Trimmer)] + static abstract void Method(); + } + + [Kept] + [KeptInterface(typeof(IStaticInterface), By = Tool.Trimmer)] + struct ConstrainedStatic : IStaticInterface + { + [Kept] + static void IStaticInterface.Method() + { + Console.WriteLine("Constrained.Method called"); + } + } + + [Kept(By = Tool.Trimmer)] // If LdobjType is never boxed or unboxed, it can be removed by NativeAot. + class LdobjTarget; + + [Kept(By = Tool.Trimmer)] + struct LdobjType + { + [Kept(By = Tool.Trimmer)] + public int Value; + } + + [Kept] + class ArrayElementTarget; + + [Kept] + class ArrayElementProxy; + + [Kept] + struct ArrayElement; + + [Kept(By = Tool.Trimmer)] // If ConstructedNoTypeCheckNoBoxStruct is never boxed or unboxed, it can be removed by NativeAot. + class ConstructedNoTypeCheckOrBoxTarget; + + [Kept] + struct ConstructedNoTypeCheckNoBoxStruct + { + [Kept] + public ConstructedNoTypeCheckNoBoxStruct(int i) + { + Value = i; + } + + [Kept] + [KeptBackingField] + public int Value { [Kept] get; } + } + + class TypeCheckOnlyProxy; [Kept] struct AllocatedNoBoxStructType @@ -157,19 +394,22 @@ public AllocatedNoBoxStructType(int value) } [Kept] + [KeptBackingField] public int Value { [Kept] get; } } [Kept] - class ProxyType3; + class AllocatedNoBoxProxy; } -// Polyfill for the type map types until we use an LKG runtime that has it. +// Polyfill for the type map types until we use an LKG runtime that has them with an updated LinkAttributes XML. namespace System.Runtime.InteropServices { [Kept(By = Tool.Trimmer)] [KeptBaseType(typeof(Attribute), By = Tool.Trimmer)] [KeptAttributeAttribute(typeof(AttributeUsageAttribute), By = Tool.Trimmer)] + [KeptAttributeAttribute(typeof(RemoveAttributeInstancesAttribute), By = Tool.Trimmer)] + [RemoveAttributeInstances] [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] public sealed class TypeMapAttribute : Attribute { @@ -185,6 +425,8 @@ public TypeMapAttribute(string value, Type target, Type trimTarget) { } [Kept(By = Tool.Trimmer)] [KeptBaseType(typeof(Attribute), By = Tool.Trimmer)] [KeptAttributeAttribute(typeof(AttributeUsageAttribute), By = Tool.Trimmer)] + [KeptAttributeAttribute(typeof(RemoveAttributeInstancesAttribute), By = Tool.Trimmer)] + [RemoveAttributeInstances] [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] public sealed class TypeMapAssociationAttribute : Attribute { @@ -200,7 +442,7 @@ public static class TypeMapping [RequiresUnreferencedCode("Interop types may be removed by trimming")] public static IReadOnlyDictionary GetOrCreateExternalTypeMapping() { - throw new NotImplementedException(); + throw new NotImplementedException($"External type map for {typeof(TTypeMapGroup).Name}"); } [Kept(By = Tool.Trimmer)] @@ -208,7 +450,7 @@ public static IReadOnlyDictionary GetOrCreateExternalTypeMapping GetOrCreateProxyTypeMapping() { - throw new NotImplementedException(); + throw new NotImplementedException($"Proxy type map for {typeof(TTypeMapGroup).Name}"); } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs index 639481c0a69054..f666cadeb650f5 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs @@ -86,7 +86,7 @@ public static void TestEmptyString() public class Full { } [Kept] - [ExpectedWarning("IL2026", nameof(Full), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", nameof(Full))] public static void TestFullString() { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Full, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; @@ -101,7 +101,7 @@ public static void TestFullString() public class Generic { } [Kept] - [ExpectedWarning("IL2026", "Generic", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "Generic")] public static void TestGenericString() { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Generic`1, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; @@ -121,7 +121,7 @@ public class GenericInstantiation { } public class GenericArgument { } [Kept] - [ExpectedWarning("IL2026", "GenericInstantiation", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "GenericInstantiation")] public static void TestGenericInstantiation() { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericInstantiation`1[[Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericArgument]]"; @@ -141,7 +141,7 @@ public class GenericInstantiationFullString { } public class GenericArgumentFullString { } [Kept] - [ExpectedWarning("IL2026", "GenericInstantiationFullString", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "GenericInstantiationFullString")] public static void TestGenericInstantiationFullString() { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericInstantiationFullString`1[" @@ -158,7 +158,7 @@ public static void TestGenericInstantiationFullString() public class GenericInstantiationOverCoreLib { } [Kept] - [ExpectedWarning("IL2026", "GenericInstantiationOverCoreLib", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "GenericInstantiationOverCoreLib", Tool.Trimmer | Tool.NativeAot, "Analyzer can't resolve type names from corelib")] public static void TestGenericInstantiationOverCoreLib() { // Note: the argument type should not be assembly-qualified for this test, which is checking that @@ -175,7 +175,7 @@ public static void TestGenericInstantiationOverCoreLib() public class FullConst { } [Kept] - [ExpectedWarning("IL2026", nameof(FullConst), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", nameof(FullConst))] public static void TestFullStringConst() { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+FullConst, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; @@ -190,7 +190,7 @@ public static void TestFullStringConst() public class TypeAsmName { } [Kept] - [ExpectedWarning("IL2026", nameof(TypeAsmName), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", nameof(TypeAsmName))] public static void TestTypeAsmName() { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+TypeAsmName, test"; @@ -205,7 +205,7 @@ public static void TestTypeAsmName() public class AType { } [Kept] - [ExpectedWarning("IL2026", nameof(AType), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", nameof(AType))] public static void TestType() { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AType"; @@ -322,7 +322,7 @@ class N3 } [Kept] - [ExpectedWarning("IL2026", "N3", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "N3")] static void TestDeeplyNested() { var typeKept = Type.GetType("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Nested1+N2+N3"); @@ -353,8 +353,8 @@ class TypeFromBranchA { } class TypeFromBranchB { } [Kept] - [ExpectedWarning("IL2026", nameof(TypeFromBranchA), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] - [ExpectedWarning("IL2026", nameof(TypeFromBranchB), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", nameof(TypeFromBranchA))] + [ExpectedWarning("IL2026", nameof(TypeFromBranchB))] static void TestTypeFromBranch(int b) { string name = null; @@ -424,7 +424,7 @@ static void TestTypeUsingCaseUnknownByTheLinker2() public class OverloadWith3Parameters { } [Kept] - [ExpectedWarning("IL2026", nameof(OverloadWith3Parameters), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", nameof(OverloadWith3Parameters))] static void TestTypeOverloadWith3Parameters() { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+OverloadWith3Parameters"; @@ -436,11 +436,11 @@ static void TestTypeOverloadWith3Parameters() [Kept] [KeptMember(".ctor()")] [KeptAttributeAttribute(typeof(RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode(nameof(OverloadWith3Parameters))] + [RequiresUnreferencedCode(nameof(OverloadWith4Parameters))] public class OverloadWith4Parameters { } [Kept] - [ExpectedWarning("IL2026", nameof(OverloadWith4Parameters), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", nameof(OverloadWith4Parameters))] static void TestTypeOverloadWith4Parameters() { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+OverloadWith4Parameters"; @@ -465,11 +465,11 @@ static void TestTypeOverloadWith5ParametersWithIgnoreCase() [Kept] [KeptMember(".ctor()")] [KeptAttributeAttribute(typeof(RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode(nameof(OverloadWith3Parameters))] + [RequiresUnreferencedCode(nameof(OverloadWith5ParametersWithIgnoreCase))] public class OverloadWith5ParametersWithoutIgnoreCase { } [Kept] - [ExpectedWarning("IL2026", nameof(OverloadWith5ParametersWithoutIgnoreCase), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", nameof(OverloadWith5ParametersWithIgnoreCase))] static void TestTypeOverloadWith5ParametersWithoutIgnoreCase() { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+OverloadWith5ParametersWithoutIgnoreCase"; @@ -525,7 +525,7 @@ static void TestUnknownIgnoreCase5Params(int num) [Kept] [KeptMember(".ctor()")] [KeptAttributeAttribute(typeof(RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode(nameof(OverloadWith3Parameters))] + [RequiresUnreferencedCode("GenericTypeWithAnnotations_OuterType")] public class GenericTypeWithAnnotations_OuterType< [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicProperties)] T> @@ -534,7 +534,7 @@ public class GenericTypeWithAnnotations_OuterType< [Kept] [KeptAttributeAttribute(typeof(RequiresUnreferencedCodeAttribute))] - [RequiresUnreferencedCode(nameof(OverloadWith3Parameters))] + [RequiresUnreferencedCode(nameof(GenericTypeWithAnnotations_InnerType))] public class GenericTypeWithAnnotations_InnerType { [Kept] @@ -545,9 +545,9 @@ private static void PrivateMethod() { } } [Kept] - [ExpectedWarning("IL2026", "GenericTypeWithAnnotations_OuterType", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] - [ExpectedWarning("IL2026", nameof(GenericTypeWithAnnotations_InnerType), "PrivateProperty.get", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] - [ExpectedWarning("IL2026", nameof(GenericTypeWithAnnotations_InnerType), "PrivateProperty.set", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2026", "GenericTypeWithAnnotations_OuterType")] + [ExpectedWarning("IL2026", nameof(GenericTypeWithAnnotations_InnerType), "PrivateProperty.get")] + [ExpectedWarning("IL2026", nameof(GenericTypeWithAnnotations_InnerType), "PrivateProperty.set")] static void TestGenericTypeWithAnnotations() { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericTypeWithAnnotations_OuterType`1[" @@ -571,7 +571,7 @@ interface ITest [KeptInterface(typeof(ITest))] class BaseType : ITest { - [Kept] + [Kept(By = Tool.Trimmer)] public void Method() { } } @@ -580,7 +580,7 @@ public void Method() { } [KeptInterface(typeof(ITest))] class DerivedType : BaseType, ITest { - [Kept] + [Kept(By = Tool.Trimmer)] public void Method() { } } @@ -620,28 +620,28 @@ static void TestEscapedTypeName() class AssemblyTypeResolutionBehavior { [Kept] - [ExpectedWarning("IL2122", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2122")] static void TestRequireTypeInSameAssemblyAsGetType() { RequireHelper.RequireType("Mono.Linker.Tests.Cases.Reflection.Dependencies.TypeDefinedInSameAssemblyAsGetType"); } [Kept] - [ExpectedWarning("IL2122", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2122")] static void TestRequireTypeInSameAssemblyAsCallToRequireType() { RequireHelper.RequireType("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AssemblyTypeResolutionBehavior+TypeDefinedInSameAssemblyAsCallToRequireType"); } [Kept] - [ExpectedWarning("IL2122", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2122")] static void TestRequireTypeWithNonAssemblyQualifiedGenericArguments() { RequireHelper.RequireType("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AssemblyTypeResolutionBehavior+Generic`1[[System.Int32]], test"); } [Kept] - [ExpectedWarning("IL2122", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2122")] static void TestRequireTypeWithNonAssemblyQualifiedArrayType() { RequireHelper.RequireType("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AssemblyTypeResolutionBehavior+Generic`1[" @@ -650,7 +650,7 @@ static void TestRequireTypeWithNonAssemblyQualifiedArrayType() } [Kept] - [ExpectedWarning("IL2122", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2122")] static void TestRequireTypeWithNonAssemblyQualifiedPointerType() { RequireHelper.RequireType("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AssemblyTypeResolutionBehavior+Generic`1[" @@ -659,7 +659,7 @@ static void TestRequireTypeWithNonAssemblyQualifiedPointerType() } [Kept] - [ExpectedWarning("IL2122", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning("IL2122")] static void TestRequireTypeWithNonAssemblyQualifiedByRefType() { RequireHelper.RequireType("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AssemblyTypeResolutionBehavior+Generic`1[" diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs index b7c626f55be8d3..32ce9323112ec1 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs @@ -119,7 +119,9 @@ public static void Main() typeof(IBaseWithoutRequires).RequiresPublicMethods(); typeof(ImplementationClassWithRequires).RequiresPublicMethods(); typeof(ImplementationClassWithoutRequires).RequiresPublicMethods(); + new ExplicitImplementationClassWithRequires(); // we need to see this one as constructed too typeof(ExplicitImplementationClassWithRequires).RequiresPublicMethods(); + new ExplicitImplementationClassWithoutRequires(); // we need to see this one as constructed too typeof(ExplicitImplementationClassWithoutRequires).RequiresPublicMethods(); typeof(ImplementationClassWithoutRequiresInSource).RequiresPublicMethods(); typeof(ImplementationClassWithRequiresInSource).RequiresPublicMethods(); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs new file mode 100644 index 00000000000000..57b01bb7611fd9 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs @@ -0,0 +1,239 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.RequiresCapability +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + class RequiresExcludeStatics + { + public static void Main() + { + ClassWithRequires.Test(); + DerivedWithRequiresExcludeStatics.Test(); + DerivedWithoutRequires.Test(); + TestDerivedWithRequires(); + TestAttributeWithRequires(); + GenericWithRequires.Test(); + } + + [RequiresUnreferencedCode("--ClassWithRequires--", ExcludeStatics = true)] + [RequiresDynamicCode("--ClassWithRequires--", ExcludeStatics = true)] + class ClassWithRequires + { + [ExpectedWarning("IL2026", "--Requires--")] + [ExpectedWarning("IL3050", "--Requires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + static ClassWithRequires() + { + Requires(); + } + + [ExpectedWarning("IL2026", "--Requires--")] + [ExpectedWarning("IL3050", "--Requires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + static void StaticMethod() => Requires(); + + [RequiresUnreferencedCode("--AnnotatedStaticMethod--")] + [RequiresDynamicCode("--AnnotatedStaticMethod--")] + static void AnnotatedStaticMethod() => Requires(); + + [RequiresUnreferencedCode("--AnnotatedStaticMethodExcludeStatics--", ExcludeStatics = true)] + [RequiresDynamicCode("--AnnotatedStaticMethodExcludeStatics--", ExcludeStatics = true)] + static void AnnotatedStaticMethodExcludeStatics() => Requires(); + + void InstanceMethod() => Requires(); + + static int StaticField; + + int InstanceField; + + static bool StaticProperty + { + [ExpectedWarning("IL2026", "--Requires--")] + [ExpectedWarning("IL3050", "--Requires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + get + { + Requires(); + return true; + } + [ExpectedWarning("IL2026", "--Requires--")] + [ExpectedWarning("IL3050", "--Requires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + set + { + Requires(); + } + } + + bool InstanceProperty + { + get + { + Requires(); + return true; + } + set + { + Requires(); + } + } + + class Nested + { + [ExpectedWarning("IL2026", "--Requires--")] + [ExpectedWarning("IL3050", "--Requires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + public static void StaticMethod() => Requires(); + + [ExpectedWarning("IL2026", "--Requires--")] + [ExpectedWarning("IL3050", "--Requires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + public void InstanceMethod() => Requires(); + } + + [ExpectedWarning("IL2026", "ClassWithRequires.ClassWithRequires()")] + [ExpectedWarning("IL3050", "ClassWithRequires.ClassWithRequires()", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + [ExpectedWarning("IL2026", "--AnnotatedStaticMethod--")] + [ExpectedWarning("IL3050", "--AnnotatedStaticMethod--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + [ExpectedWarning("IL2026", "--AnnotatedStaticMethodExcludeStatics--")] + [ExpectedWarning("IL3050", "--AnnotatedStaticMethodExcludeStatics--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + public static void Test() + { + StaticMethod(); + StaticField = 42; + _ = StaticProperty; + StaticProperty = true; + + AnnotatedStaticMethod(); + AnnotatedStaticMethodExcludeStatics(); + + var instance = new ClassWithRequires(); + instance.InstanceMethod(); + instance.InstanceField = 42; + _ = instance.InstanceProperty; + instance.InstanceProperty = true; + + Nested.StaticMethod(); + var nestedInstance = new Nested(); + nestedInstance.InstanceMethod(); + } + } + + [RequiresUnreferencedCode("--BaseWithRequires--")] + [RequiresDynamicCode("--BaseWithRequires--")] + class BaseWithRequires + { + protected static void StaticMethod() => Requires(); + } + + [RequiresUnreferencedCode("--DerivedWithRequiresExcludeStatics--", ExcludeStatics = true)] + [RequiresDynamicCode("--DerivedWithRequiresExcludeStatics--", ExcludeStatics = true)] + class DerivedWithRequiresExcludeStatics : BaseWithRequires + { + [ExpectedWarning("IL2026", "--Requires--")] + [ExpectedWarning("IL3050", "--Requires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + static void DerivedStaticMethod() => Requires(); + + [ExpectedWarning("IL2026", "StaticMethod", "--BaseWithRequires--")] + [ExpectedWarning("IL3050", "StaticMethod", "--BaseWithRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + public static void Test() + { + StaticMethod(); + DerivedStaticMethod(); + } + } + + [ExpectedWarning("IL2026", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning("IL2026", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning("IL3050", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.Analyzer, "NativeAOT Specific warning")] + [ExpectedWarning("IL3050", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] + class DerivedWithoutRequires : BaseWithRequires + { + [ExpectedWarning("IL2026", "--Requires--")] + [ExpectedWarning("IL3050", "--Requires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + static void DerivedStaticMethod() => Requires(); + + [ExpectedWarning("IL2026", "StaticMethod", "--BaseWithRequires--")] + [ExpectedWarning("IL3050", "StaticMethod", "--BaseWithRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + public static void Test() + { + StaticMethod(); + DerivedStaticMethod(); + + // Instantiate for linker test consistency + new DerivedWithoutRequires(); + } + } + + [RequiresUnreferencedCode("--BaseWithRequiresExcludeStatics--", ExcludeStatics = true)] + [RequiresDynamicCode("--BaseWithRequiresExcludeStatics--", ExcludeStatics = true)] + class BaseWithRequiresExcludeStatics + { + [ExpectedWarning("IL2026", "--Requires--")] + [ExpectedWarning("IL3050", "--Requires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + public static void StaticMethod() => Requires(); + } + + [RequiresUnreferencedCode("--DerivedWithRequiresExcludeStatics--")] + [RequiresDynamicCode("--DerivedWithRequiresExcludeStatics--")] + class DerivedWithRequires : BaseWithRequiresExcludeStatics + { + public static void DerivedStaticMethod() => Requires(); + } + + [ExpectedWarning("IL2026", "DerivedWithRequires")] + [ExpectedWarning("IL3050", "DerivedWithRequires", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + static void TestDerivedWithRequires() + { + DerivedWithRequires.StaticMethod(); + DerivedWithRequires.DerivedStaticMethod(); + } + + [RequiresUnreferencedCode("--AttributeWithRequires--", ExcludeStatics = true)] + [RequiresDynamicCode("--AttributeWithRequires--", ExcludeStatics = true)] + class AttributeWithRequiresAttribute : Attribute + { + } + + [ExpectedWarning("IL2026", "--AttributeWithRequires--", Tool.Analyzer | Tool.Trimmer, "https://github.com/dotnet/runtime/issues/117899")] + [ExpectedWarning("IL3050", "--AttributeWithRequires--", Tool.Analyzer, "NativeAOT Specific warning, https://github.com/dotnet/runtime/issues/117899")] + [AttributeWithRequires] + static void TestAttributeWithRequires() + { + } + + [RequiresUnreferencedCode("--GenericWithRequires--", ExcludeStatics = true)] + [RequiresDynamicCode("--GenericWithRequires--", ExcludeStatics = true)] + class GenericWithRequires + { + class Requires<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T> + { + } + + [UnexpectedWarning("IL2091", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/113249")] + static Requires StaticField; + + [UnexpectedWarning("IL2091", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/113249")] + Requires InstanceField; + + [ExpectedWarning("IL2091", "PublicFields", "Requires")] + [ExpectedWarning("IL2091", "PublicFields", "Requires")] + [ExpectedWarning("IL2026", "--GenericWithRequires--")] + [ExpectedWarning("IL3050", "--GenericWithRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific warning")] + public static void Test() + { + StaticField = new Requires(); + var instance = new GenericWithRequires(); + instance.InstanceField = new Requires(); + } + } + + [RequiresUnreferencedCode("--Requires--")] + [RequiresDynamicCode("--Requires--")] + static void Requires() + { + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs index 867647ae550d82..d953a2a3e7454c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs @@ -86,7 +86,7 @@ static IEnumerable TestReflectionAccess() [ExpectedWarning("IL3002", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] [ExpectedWarning("IL3050", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] #else - // In release mode, the compiler optimizes away the unused Action (and reference to MethodWithRequires) + // In release mode, the compiler optimizes away the unused Action (and reference to MethodWithRequires) #endif [ExpectedWarning("IL2026", "--MethodWithRequires--", Tool.Analyzer, "")] [ExpectedWarning("IL3002", "--MethodWithRequires--", Tool.Analyzer, "")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttribute.cs index e91f18174b32f0..6654a03a21bd89 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttribute.cs @@ -64,18 +64,18 @@ public bool PropertyWhichRequires } } - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - class GenericTypeWithAttributedParameter<[AttributeWhichRequires] T> - { - public static void TestMethod () { } - } - - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - static void GenericMethodWithAttributedParameter<[AttributeWhichRequires] T> () { } + [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + class GenericTypeWithAttributedParameter<[AttributeWhichRequires] T> + { + public static void TestMethod () { } + } + + [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + static void GenericMethodWithAttributedParameter<[AttributeWhichRequires] T> () { } static void TestRequiresOnAttributeOnGenericParameter() { @@ -83,47 +83,47 @@ static void TestRequiresOnAttributeOnGenericParameter() GenericMethodWithAttributedParameter(); } - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [AttributeWhichRequires] - [AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)] - class TypeWithAttributeWhichRequires - { - } - - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [AttributeWhichRequires] - [AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)] - static void MethodWithAttributeWhichRequires () { } - - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [AttributeWhichRequires] - [AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)] - static int _fieldWithAttributeWhichRequires; - - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [AttributeWhichRequires] - [AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)] - static bool PropertyWithAttributeWhichRequires { get; set; } + [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [AttributeWhichRequires] + [AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)] + class TypeWithAttributeWhichRequires + { + } + + [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [AttributeWhichRequires] + [AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)] + static void MethodWithAttributeWhichRequires () { } + + [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [AttributeWhichRequires] + [AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)] + static int _fieldWithAttributeWhichRequires; + + [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [AttributeWhichRequires] + [AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)] + static bool PropertyWithAttributeWhichRequires { get; set; } [AttributeWhichRequires] [AttributeWhichRequiresOnProperty(PropertyWhichRequires = true)] @@ -132,13 +132,13 @@ static void MethodWithAttributeWhichRequires () { } [RequiresDynamicCode("--MethodWhichRequiresWithAttributeWhichRequires--")] static void MethodWhichRequiresWithAttributeWhichRequires() { } - [ExpectedWarning ("IL2026", "--MethodWhichRequiresWithAttributeWhichRequires--")] - [ExpectedWarning ("IL3002", "--MethodWhichRequiresWithAttributeWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - [ExpectedWarning ("IL3050", "--MethodWhichRequiresWithAttributeWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] - static void TestMethodWhichRequiresWithAttributeWhichRequires () - { - MethodWhichRequiresWithAttributeWhichRequires (); - } + [ExpectedWarning ("IL2026", "--MethodWhichRequiresWithAttributeWhichRequires--")] + [ExpectedWarning ("IL3002", "--MethodWhichRequiresWithAttributeWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + [ExpectedWarning ("IL3050", "--MethodWhichRequiresWithAttributeWhichRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT-specific warning")] + static void TestMethodWhichRequiresWithAttributeWhichRequires () + { + MethodWhichRequiresWithAttributeWhichRequires (); + } class RequiresTriggeredByAttributeUsage { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnBaseClass.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnBaseClass.cs new file mode 100644 index 00000000000000..3c35f02e8c60de --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnBaseClass.cs @@ -0,0 +1,51 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.RequiresCapability +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + class RequiresOnBaseClass + { + + public static void Main() + { + DerivedFromBaseWithRUC.StaticMethod(); + DerivedFromBaseWithRDC.StaticMethod(); + + new DerivedFromBaseWithRDC(); + new DerivedFromBaseWithRUC(); + } + + class DerivedFromBaseWithRUC : BaseWithRUC + { + [ExpectedWarning("IL2026")] + public DerivedFromBaseWithRUC() + { + } + + public static void StaticMethod() { } + } + + [RequiresUnreferencedCode(nameof(BaseWithRUC))] + class BaseWithRUC { } + + class DerivedFromBaseWithRDC : BaseWithRDC + { + [ExpectedWarning("IL3050", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific Warning")] + public DerivedFromBaseWithRDC() + { } + + public static void StaticMethod() { } + } + + [RequiresDynamicCode(nameof(BaseWithRDC))] + class BaseWithRDC { } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs index d7aeb8c85c57e7..714bf9a2598fc2 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs @@ -36,6 +36,10 @@ public static void Main() AttributeParametersAndProperties.Test(); MembersOnClassWithRequires.Test(); ConstFieldsOnClassWithRequires.Test(); + + // Instantiate classes so linker warnings match analyzer warnings + new TestUnconditionalSuppressMessage(); + new DerivedWithoutRequiresOnType(); } [RequiresUnreferencedCode("Message for --ClassWithRequires--")] @@ -82,6 +86,8 @@ public static void TestSuppressions(Type[] types) void LocalFunction(int a) { } LocalFunction(2); + + AttributedMethod(); } // The attribute would generate warning, but it is suppressed due to the Requires on the type @@ -96,7 +102,6 @@ class RequiresOnMethod public static void MethodWithRequires() { } } - [ExpectedWarning("IL2109", "RequiresOnClass.DerivedWithoutRequires", "RequiresOnClass.ClassWithRequires", "--ClassWithRequires--")] private class DerivedWithoutRequires : ClassWithRequires { // This method contains implicit call to ClassWithRequires.ctor() @@ -118,14 +123,19 @@ public static void ShouldntWarn(object objectToCast) } } - // In order to generate IL2109 the nested class would also need to be annotated with Requires - // otherwise we threat the nested class as safe - private class DerivedWithoutRequires2 : ClassWithRequires.NestedClass + private class DerivedFromNestedInRequiresClass : ClassWithRequires.NestedClass { + // In order to generate IL2026 the nested class would also need to be annotated with Requires + // otherwise we treat the nested class as safe + public DerivedFromNestedInRequiresClass() { } + public static void StaticMethod() { } } - [UnconditionalSuppressMessage("trim", "IL2109")] + [ExpectedWarning("IL2026", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning("IL2026", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning("IL3050", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.Analyzer, "NativeAOT Specific warning")] + [ExpectedWarning("IL3050", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] class TestUnconditionalSuppressMessage : ClassWithRequires { public static void StaticMethodInTestSuppressionClass() { } @@ -303,11 +313,10 @@ private class DerivedWithRequires2 : ClassWithRequires { public static void StaticMethodInInheritedClass() { } - // A nested class is not considered a static method nor constructor therefore RequiresUnreferencedCode doesn't apply - // and this warning is not suppressed - [ExpectedWarning("IL2109", "RequiresOnClass.DerivedWithRequires2.DerivedNestedClass", "--ClassWithRequires--")] public class DerivedNestedClass : ClassWithRequires { + // A nested class is not considered a static method nor constructor therefore RequiresUnreferencedCode doesn't apply + // and this warning is not suppressed // This method contains implicit call to ClassWithRequires.ctor() [ExpectedWarning("IL2026")] [ExpectedWarning("IL3050", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific Warnings")] @@ -338,7 +347,10 @@ class BaseWithRequiresOnType public virtual void Method() { } } - [ExpectedWarning("IL2109", nameof(BaseWithRequiresOnType))] + [ExpectedWarning("IL2026", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.Analyzer, "")] + [ExpectedWarning("IL2026", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning("IL3050", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RDC", Tool.Analyzer, "NativeAOT Specific warning")] + [ExpectedWarning("IL3050", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RDC", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] class DerivedWithoutRequiresOnType : BaseWithRequiresOnType { public override void Method() { } @@ -409,7 +421,7 @@ static void TestRequiresInParentClassAccesedByStaticMethod() [ExpectedWarning("IL2026", "RequiresOnClass.ClassWithRequires.StaticMethod()", "--ClassWithRequires--")] [ExpectedWarning("IL3050", "RequiresOnClass.ClassWithRequires.StaticMethod()", "--ClassWithRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific Warnings")] - // Although we suppress the warning from RequiresOnMethod.MethodWithRequires () we still get a warning because we call CallRequiresMethod() which is an static method on a type with RUC + // Although we suppress the warning from RequiresOnMethod.MethodWithRequires() we still get a warning because we call CallRequiresMethod() which is an static method on a type with RUC [ExpectedWarning("IL2026", "RequiresOnClass.ClassWithRequires.CallMethodWithRequires()", "--ClassWithRequires--")] [ExpectedWarning("IL3050", "RequiresOnClass.ClassWithRequires.CallMethodWithRequires()", "--ClassWithRequires--", Tool.Analyzer | Tool.NativeAot, "NativeAOT Specific Warnings")] [ExpectedWarning("IL2026", "ClassWithRequires.Instance", "--ClassWithRequires--")] @@ -425,7 +437,8 @@ static void TestRequiresOnBaseButNotOnDerived() DerivedWithoutRequires.NestedClass.CallMethodWithRequires(); DerivedWithoutRequires.ShouldntWarn(null); DerivedWithoutRequires.Instance.ToString(); - DerivedWithoutRequires2.StaticMethod(); + DerivedFromNestedInRequiresClass.StaticMethod(); + new DerivedFromNestedInRequiresClass(); } [ExpectedWarning("IL2026", "RequiresOnClass.DerivedWithRequires.StaticMethodInInheritedClass()", "--DerivedWithRequires--")] @@ -480,7 +493,7 @@ static void TestStaticConstructorCalls() TestStaticCtorMarkingTriggeredOnSecondAccessWrite(); TestStaticRequiresFieldAccessSuppressedByRequiresOnMethod(); TestStaticCtorMarkingIsTriggeredByFieldAccessRead(); - //TestStaticCtorTriggeredByMethodCall (); + //TestStaticCtorTriggeredByMethodCall(); TestStaticCtorTriggeredByCtorCall(); TestInstanceFieldCallDontWarn(); } @@ -605,7 +618,6 @@ class BaseWithRequires public BaseWithRequires() { } } - [ExpectedWarning("IL2109", "ReflectionAccessOnCtor.DerivedWithoutRequires", "ReflectionAccessOnCtor.BaseWithRequires")] class DerivedWithoutRequires : BaseWithRequires { [ExpectedWarning("IL2026", "--BaseWithRequires--")] // The body has direct call to the base.ctor() @@ -694,7 +706,10 @@ class WithRequiresOnlyInstanceFields public int InstanceField; } - [ExpectedWarning("IL2109", "ReflectionAccessOnField.DerivedWithoutRequires", "ReflectionAccessOnField.WithRequires")] + [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "")] + [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "NativeAOT Specific warning")] + [ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] class DerivedWithoutRequires : WithRequires { public static int DerivedStaticField; @@ -832,6 +847,9 @@ public static void Test() TestDAMOnTypeAccessInRUCScope(new DAMAnnotatedClassAccessedFromRUCScope()); TestDAMAccessOnOpenGeneric(); TestDAMAccessOnInstantiatedGeneric(); + + // Instantiate for linker test consistency + new DerivedWithoutRequires(); } } @@ -855,7 +873,10 @@ class DerivedRequires : WithRequires private event EventHandler DerivedPrivateInstanceEvent; } - [ExpectedWarning("IL2109", "ReflectionAccessOnEvents.DerivedWithoutRequires", "ReflectionAccessOnEvents.WithRequires")] + [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "")] + [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "NativeAOT Specific warning")] + [ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] class DerivedWithoutRequires : WithRequires { public static event EventHandler DerivedStaticEvent; @@ -899,8 +920,8 @@ static void ReflectOverAllEvents() [ExpectedWarning("IL3050", nameof(WithRequires), "InstanceEvent.add", Tool.NativeAot, "")] [ExpectedWarning("IL2026", nameof(WithRequires), "InstanceEvent.remove")] [ExpectedWarning("IL3050", nameof(WithRequires), "InstanceEvent.remove", Tool.NativeAot, "")] - [UnexpectedWarning("IL2026", nameof(WithRequires), "StaticEvent.add", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/102525")] - [UnexpectedWarning("IL2026", nameof(WithRequires), "StaticEvent.remove", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/102525")] + [UnexpectedWarning("IL2026", nameof(WithRequires), "StaticEvent.add", Tool.All, "https://github.com/dotnet/runtime/issues/102525")] + [UnexpectedWarning("IL2026", nameof(WithRequires), "StaticEvent.remove", Tool.All, "https://github.com/dotnet/runtime/issues/102525")] [UnexpectedWarning("IL3050", nameof(WithRequires), "StaticEvent.add", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/102525")] [UnexpectedWarning("IL3050", nameof(WithRequires), "StaticEvent.remove", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/102525")] [ExpectedWarning("IL2026", nameof(DerivedRequires), "DerivedStaticEvent.add")] @@ -944,8 +965,8 @@ static void RequiresAllEvents([DynamicallyAccessedMembers(DynamicallyAccessedMem [ExpectedWarning("IL3050", nameof(WithRequires), "InstanceEvent.add", Tool.NativeAot, "")] [ExpectedWarning("IL2026", nameof(WithRequires), "InstanceEvent.remove")] [ExpectedWarning("IL3050", nameof(WithRequires), "InstanceEvent.remove", Tool.NativeAot, "")] - [UnexpectedWarning("IL2026", nameof(WithRequires), "StaticEvent.add", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/102525")] - [UnexpectedWarning("IL2026", nameof(WithRequires), "StaticEvent.remove", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/102525")] + [UnexpectedWarning("IL2026", nameof(WithRequires), "StaticEvent.add", Tool.All, "https://github.com/dotnet/runtime/issues/102525")] + [UnexpectedWarning("IL2026", nameof(WithRequires), "StaticEvent.remove", Tool.All, "https://github.com/dotnet/runtime/issues/102525")] [UnexpectedWarning("IL3050", nameof(WithRequires), "StaticEvent.add", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/102525")] [UnexpectedWarning("IL3050", nameof(WithRequires), "StaticEvent.remove", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/102525")] [ExpectedWarning("IL2026", nameof(DerivedRequires), "DerivedStaticEvent.add")] @@ -985,8 +1006,8 @@ static void RequiresPublicEvents() [ExpectedWarning("IL3050", nameof(WithRequires), "InstanceEvent.add", Tool.NativeAot, "")] [ExpectedWarning("IL2026", nameof(WithRequires), "InstanceEvent.remove")] [ExpectedWarning("IL3050", nameof(WithRequires), "InstanceEvent.remove", Tool.NativeAot, "")] - [UnexpectedWarning("IL2026", nameof(WithRequires), "StaticEvent.add", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/102525")] - [UnexpectedWarning("IL2026", nameof(WithRequires), "StaticEvent.remove", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/102525")] + [UnexpectedWarning("IL2026", nameof(WithRequires), "StaticEvent.add", Tool.All, "https://github.com/dotnet/runtime/issues/102525")] + [UnexpectedWarning("IL2026", nameof(WithRequires), "StaticEvent.remove", Tool.All, "https://github.com/dotnet/runtime/issues/102525")] [UnexpectedWarning("IL3050", nameof(WithRequires), "StaticEvent.add", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/102525")] [UnexpectedWarning("IL3050", nameof(WithRequires), "StaticEvent.remove", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/102525")] [ExpectedWarning("IL2026", nameof(DerivedRequires), "DerivedStaticEvent.add")] @@ -1031,6 +1052,9 @@ public static void Test() DerivedRequiresPublicEvents(); DerivedRequiresNonPublicEvents(); DerivedRequiresAllEvents(); + + // Instantiate for linker test consistency + new DerivedWithoutRequires(); } } @@ -1052,7 +1076,10 @@ class WithRequiresOnlyInstanceProperties public int InstanceProperty { get; set; } } - [ExpectedWarning("IL2109", "ReflectionAccessOnProperties.DerivedWithoutRequires", "ReflectionAccessOnProperties.WithRequires")] + [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "")] + [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "NativeAOT Specific warning")] + [ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] class DerivedWithoutRequires : WithRequires { public static int DerivedStaticProperty { get; set; } @@ -1220,6 +1247,9 @@ public static void Test() TestDirectReflectionAccess(); TestDynamicDependencyAccess(); TestDAMOnTypeAccess(new DAMAnnotatedClass()); + + // Instantiate for linker test consistency + new DerivedWithoutRequires(); } } @@ -1322,7 +1352,6 @@ public class ClassWithRequires { public static RequiresAll field; - // Instance fields get generic warnings but static fields don't. [UnexpectedWarning("IL2091", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/108523")] public RequiresAll instanceField; @@ -1363,14 +1392,14 @@ public class ClassWithAttribute } // This warning should ideally be suppressed by the RUC on the type: - [UnexpectedWarning("IL2091", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/108523")] + [UnexpectedWarning("IL2091", Tool.All, "https://github.com/dotnet/runtime/issues/108523")] [RequiresUnreferencedCode("--GenericClassWithWarningWithRequires--")] public class GenericClassWithWarningWithRequires : RequiresAll { } // This warning should ideally be suppressed by the RUC on the type: - [UnexpectedWarning("IL2091", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/108523")] + [UnexpectedWarning("IL2091", Tool.All, "https://github.com/dotnet/runtime/issues/108523")] [RequiresUnreferencedCode("--ClassWithWarningWithRequires--")] public class ClassWithWarningWithRequires : RequiresAll { @@ -1386,13 +1415,13 @@ public ClassWithWarningOnGenericArgumentConstructor() } } - [UnexpectedWarning("IL2026", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/108507")] + [UnexpectedWarning("IL2026", Tool.All, "https://github.com/dotnet/runtime/issues/108507")] [RequiresUnreferencedCode("--ClassWithWarningOnGenericArgumentConstructorWithRequires--")] class ClassWithWarningOnGenericArgumentConstructorWithRequires : RequiresNew { } - [UnexpectedWarning("IL2091", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/runtime/issues/108523")] + [UnexpectedWarning("IL2091", Tool.All, "https://github.com/dotnet/runtime/issues/108523")] [RequiresUnreferencedCode("--GenericAnnotatedWithWarningWithRequires--")] public class GenericAnnotatedWithWarningWithRequires<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] TFields> : RequiresAll { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresWithCopyAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresWithCopyAssembly.cs index 5df006878f67a8..229193048fb202 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresWithCopyAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresWithCopyAssembly.cs @@ -23,7 +23,7 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability [LogDoesNotContain("--UnusedVirtualMethod2--")] [LogDoesNotContain("--IUnusedInterface.UnusedMethod--")] [LogDoesNotContain("--UnusedImplementationClass.UnusedMethod--")] - // [LogDoesNotContain ("UnusedVirtualMethod2")] // https://github.com/dotnet/linker/issues/2106 + // [LogDoesNotContain("UnusedVirtualMethod2")] // https://github.com/dotnet/linker/issues/2106 [ExpectedNoWarnings] class RequiresWithCopyAssembly diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/TestFeatures.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/TestFeatures.cs index 942c9f3586dd34..90961bfe1ee552 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/TestFeatures.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/TestFeatures.cs @@ -3,10 +3,10 @@ namespace ILLink.RoslynAnalyzer { - public class TestFeatures - { - public static bool IsUnreferencedCodeSupported => true; + public class TestFeatures + { + public static bool IsUnreferencedCodeSupported => true; - public static bool IsAssemblyFilesSupported => true; - } + public static bool IsAssemblyFilesSupported => true; + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutions.cs index 16731f697fa9f5..4ae4d36e72d643 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutions.cs @@ -2,9 +2,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Runtime.CompilerServices; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using ILLink.RoslynAnalyzer; using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Cases.Expectations.Helpers; @@ -17,10 +17,10 @@ namespace Mono.Linker.Tests.Cases.Substitutions [SetupCompileResource("FeatureGuardSubstitutions.xml", "ILLink.Substitutions.xml")] [IgnoreSubstitutions(false)] #if NATIVEAOT - // ILC has different constant propagation behavior than ILLink, and we don't have - // the test infrastructure to check for different IL sequences between ILLink/ILC. - // Just validate the warning behavior instead. - [SkipKeptItemsValidation] + // ILC has different constant propagation behavior than ILLink, and we don't have + // the test infrastructure to check for different IL sequences between ILLink/ILC. + // Just validate the warning behavior instead. + [SkipKeptItemsValidation] #else // Tell linker to treat RequiresDynamicCodeAttribute as a disabled feature: [SetupLinkerArgument("--feature", "System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutionsDisabled.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutionsDisabled.cs index 4418137cd0f104..25a941233724aa 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutionsDisabled.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutionsDisabled.cs @@ -2,9 +2,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Runtime.CompilerServices; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using ILLink.RoslynAnalyzer; using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Cases.Expectations.Helpers; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbAndSymbolLinkingEnabled.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbAndSymbolLinkingEnabled.cs index 07b8f73b7f088a..cfbcb5a42862ef 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbAndSymbolLinkingEnabled.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbAndSymbolLinkingEnabled.cs @@ -11,7 +11,7 @@ namespace Mono.Linker.Tests.Cases.Symbols [SetupLinkerLinkSymbols("true")] #if WIN32 - [KeptSymbols ("LibraryWithPdb.dll")] + [KeptSymbols("LibraryWithPdb.dll")] #else [RemovedSymbols("LibraryWithPdb.dll")] #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbAndSymbolLinkingEnabledAndDeterministicMvid.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbAndSymbolLinkingEnabledAndDeterministicMvid.cs index 5b268930439833..a8f728356e097c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbAndSymbolLinkingEnabledAndDeterministicMvid.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbAndSymbolLinkingEnabledAndDeterministicMvid.cs @@ -12,7 +12,7 @@ namespace Mono.Linker.Tests.Cases.Symbols [SetupLinkerArgument("--deterministic", "true")] #if WIN32 - [KeptSymbols ("LibraryWithPdb.dll")] + [KeptSymbols("LibraryWithPdb.dll")] #else [RemovedSymbols("LibraryWithPdb.dll")] #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbAndSymbolLinkingEnabledAndNewMvid.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbAndSymbolLinkingEnabledAndNewMvid.cs index 6e47df80969f0f..080629f410b6a7 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbAndSymbolLinkingEnabledAndNewMvid.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbAndSymbolLinkingEnabledAndNewMvid.cs @@ -12,7 +12,7 @@ namespace Mono.Linker.Tests.Cases.Symbols [SetupLinkerArgument("--new-mvid", "true")] #if WIN32 - [KeptSymbols ("LibraryWithPdb.dll")] + [KeptSymbols("LibraryWithPdb.dll")] #else [RemovedSymbols("LibraryWithPdb.dll")] #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbCopyActionAndSymbolLinkingEnabled.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbCopyActionAndSymbolLinkingEnabled.cs index 14d007bd6192cc..c3300d85260bf6 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbCopyActionAndSymbolLinkingEnabled.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferenceWithPdbCopyActionAndSymbolLinkingEnabled.cs @@ -11,7 +11,7 @@ namespace Mono.Linker.Tests.Cases.Symbols // typeforwarders). However, saving the native PDB is only // supported on windows. // Commented because the testcase is already ignored above. - // [IgnoreTestCase ("Only supported on Windows")] + // [IgnoreTestCase("Only supported on Windows")] #endif [TestCaseRequirements(TestRunCharacteristics.TargetingNetFramework, "Only supported on Windows on .NET Framework.")] [Reference("Dependencies/LibraryWithPdb/LibraryWithPdb.dll")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferencesWithMixedSymbolTypesAndSymbolLinkingEnabled.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferencesWithMixedSymbolTypesAndSymbolLinkingEnabled.cs index 3979630e21a472..8efc716a413b8f 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferencesWithMixedSymbolTypesAndSymbolLinkingEnabled.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferencesWithMixedSymbolTypesAndSymbolLinkingEnabled.cs @@ -18,7 +18,7 @@ namespace Mono.Linker.Tests.Cases.Symbols [KeptSymbols("test.exe")] #if WIN32 - [KeptSymbols ("LibraryWithPdb.dll")] + [KeptSymbols("LibraryWithPdb.dll")] #else [RemovedSymbols("LibraryWithPdb.dll")] #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferencesWithMixedSymbolTypesWithMdbAndSymbolLinkingEnabled.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferencesWithMixedSymbolTypesWithMdbAndSymbolLinkingEnabled.cs index d3b2a7374e3a7b..a01aa0e80981a0 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferencesWithMixedSymbolTypesWithMdbAndSymbolLinkingEnabled.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Symbols/ReferencesWithMixedSymbolTypesWithMdbAndSymbolLinkingEnabled.cs @@ -26,7 +26,7 @@ namespace Mono.Linker.Tests.Cases.Symbols [KeptSymbols("test.exe")] [KeptSymbols("LibraryWithMdb.dll")] #if WIN32 - [KeptSymbols ("LibraryWithPdb.dll")] + [KeptSymbols("LibraryWithPdb.dll")] #else [RemovedSymbols("LibraryWithPdb.dll")] #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileILAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileILAssembly.cs index 5f4613e2f64474..692dfdd5a98fd8 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileILAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileILAssembly.cs @@ -13,7 +13,7 @@ public class CanCompileILAssembly static void Main() { #if IL_ASSEMBLY_AVAILABLE - Console.WriteLine (new Mono.Linker.Tests.Cases.TestFramework.Dependencies.ILAssemblySample ().GiveMeAValue ()); + Console.WriteLine(new Mono.Linker.Tests.Cases.TestFramework.Dependencies.ILAssemblySample().GiveMeAValue()); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileTestCaseWithCsc.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileTestCaseWithCsc.cs index ed39a9e6ecf8da..2c28cfdabfc20b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileTestCaseWithCsc.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileTestCaseWithCsc.cs @@ -22,7 +22,7 @@ class CanCompileTestCaseWithCsc static void Main() { #if VERIFY_DEFINE_WORKS - UsedByDefine (); + UsedByDefine(); #endif // Use something from System.dll so that we can verify the reference attribute works var timer = new System.Timers.Timer(); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileTestCaseWithMcs.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileTestCaseWithMcs.cs index 8b02442abac100..781eb2b662a899 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileTestCaseWithMcs.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileTestCaseWithMcs.cs @@ -23,7 +23,7 @@ class CanCompileTestCaseWithMcs static void Main() { #if VERIFY_DEFINE_WORKS - UsedByDefine (); + UsedByDefine(); #endif // Use something from System.dll so that we can verify the reference attribute works var timer = new System.Timers.Timer(); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/ILVerificationWorks.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/ILVerificationWorks.cs index 25d74d58d316bf..ce7b12e782521d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/ILVerificationWorks.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/ILVerificationWorks.cs @@ -19,7 +19,7 @@ public class ILVerificationWorks public static void Main() { #if IL_ASSEMBLY_AVAILABLE - System.Console.WriteLine (new Mono.Linker.Tests.Cases.TestFramework.Dependencies.AssemblyWithInvalidIL ().GiveMeAValue ()); + System.Console.WriteLine(new Mono.Linker.Tests.Cases.TestFramework.Dependencies.AssemblyWithInvalidIL().GiveMeAValue()); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/VerifyDefineAttributeBehavior.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/VerifyDefineAttributeBehavior.cs index 6d4a6ce3e06f5c..2df3732ccc98d8 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/VerifyDefineAttributeBehavior.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TestFramework/VerifyDefineAttributeBehavior.cs @@ -14,7 +14,7 @@ public class VerifyDefineAttributeBehavior static void Main() { #if SOME_DEFINE - MethodThatIsUsedIfDefineIsWorkingProperly (); + MethodThatIsUsedIfDefineIsWorkingProperly(); #endif } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TopLevelStatements/BasicDataFlow/Program.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TopLevelStatements/BasicDataFlow/Program.cs index 02bd9606aae6d0..57f0d09ab4ff22 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TopLevelStatements/BasicDataFlow/Program.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TopLevelStatements/BasicDataFlow/Program.cs @@ -16,8 +16,8 @@ [Kept] static void RequirePublicFields( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type t) + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type t) { } class TopLevelClass @@ -32,7 +32,7 @@ class TopLevelClass [Kept] static void RequirePublicFields( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type t) + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type t) { } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TopLevelStatements/Directory.Build.props b/src/tools/illink/test/Mono.Linker.Tests.Cases/TopLevelStatements/Directory.Build.props index 1264c7538d3ed8..10b25c9f4ebc6a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TopLevelStatements/Directory.Build.props +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TopLevelStatements/Directory.Build.props @@ -7,4 +7,8 @@ Exe + + + + diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TopLevelStatements/InvalidAnnotations/Program.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TopLevelStatements/InvalidAnnotations/Program.cs index a13b8b49b24001..9c960fdff702f7 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TopLevelStatements/InvalidAnnotations/Program.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TopLevelStatements/InvalidAnnotations/Program.cs @@ -17,8 +17,8 @@ static void Test() [ExpectedWarning("IL2098", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/101215")] [Kept] static void RequireAll( - [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] UnsupportedType f) + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] UnsupportedType f) { } [Kept] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwarded.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwarded.cs index 9ee1fd8cb18b82..7149adb933b81d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwarded.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/AttributeArgumentForwarded.cs @@ -82,12 +82,12 @@ public static void Test_Field_ArrayOfPointerTypeRef() } // This hits Roslyn bug https://github.com/dotnet/roslyn/issues/48765 - //[Kept] - //[KeptAttributeAttribute (typeof (TestTypeAttribute))] - //[TestType (TestField = new object[] { typeof (delegate*) })] - //public static void Test_Field_ArrayOfFunctionPointer () - //{ - //} + // [Kept] + // [KeptAttributeAttribute(typeof(TestTypeAttribute))] + // [TestType(TestField = new object[] { typeof(delegate*) })] + // public static void Test_Field_ArrayOfFunctionPointer() + // { + // } } [KeptBaseType(typeof(Attribute))] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/AnotherLibraryForwarder.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/AnotherLibraryForwarder.cs index 74b83ed7a975b5..310e86035e956d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/AnotherLibraryForwarder.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/AnotherLibraryForwarder.cs @@ -1,3 +1,3 @@ using System; -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.AnotherLibrary<>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.AnotherLibrary<>))] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/AnotherLibraryReferenceImplementation.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/AnotherLibraryReferenceImplementation.cs index e9aadc2e26ca21..6a2a1314934309 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/AnotherLibraryReferenceImplementation.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/AnotherLibraryReferenceImplementation.cs @@ -1,9 +1,9 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding.Dependencies { #if INCLUDE_REFERENCE_IMPL - public class AnotherLibrary - { - public string Prop { get; set; } - } + public class AnotherLibrary + { + public string Prop { get; set; } + } #endif } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/AttributeWithEnumArgument.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/AttributeWithEnumArgument.cs index e9637be558cc38..e69d8d5f2fdce9 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/AttributeWithEnumArgument.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/AttributeWithEnumArgument.cs @@ -3,7 +3,7 @@ using Mono.Linker.Tests.Cases.TypeForwarding.Dependencies; #if INCLUDE_FORWARDER -[assembly: TypeForwardedTo (typeof (UsedToReferenceForwarderAssembly))] +[assembly: TypeForwardedTo(typeof(UsedToReferenceForwarderAssembly))] #endif namespace Mono.Linker.Tests.Cases.TypeForwarding.Dependencies diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwardedNestedTypeLibrary.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwardedNestedTypeLibrary.cs index be363bd6ddefdb..36921cbfd92c58 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwardedNestedTypeLibrary.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwardedNestedTypeLibrary.cs @@ -3,7 +3,7 @@ #if INCLUDE_FORWARDERS -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ForwardedNestedTypeLibrary))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ForwardedNestedTypeLibrary))] #endif #if INCLUDE_REFERENCE_IMPL @@ -11,14 +11,14 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding.Dependencies; public class ForwardedNestedTypeLibrary { - public class NestedOne - { - public class NestedTwo - { - public class NestedThree - { - } - } - } + public class NestedOne + { + public class NestedTwo + { + public class NestedThree + { + } + } + } } #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary.cs index 57aee6ea8daa19..7938fa75681472 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary.cs @@ -1,7 +1,7 @@ using System; -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationStruct))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationStruct))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibraryAttribute))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibraryImp))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibraryInterface))] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibraryWithUnusedReference.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibraryWithUnusedReference.cs index b6037e99b93b49..46bbe2572be31e 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibraryWithUnusedReference.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibraryWithUnusedReference.cs @@ -1,4 +1,4 @@ using System; -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.UnusedImplementationLibrary))] \ No newline at end of file +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.UnusedImplementationLibrary))] \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary_2.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary_2.cs index 85af68d19fa394..ea84556f022a3b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary_2.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary_2.cs @@ -1,4 +1,4 @@ using System; -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.AnotherLibrary<>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.AnotherLibrary<>))] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary_3.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary_3.cs index d7aea07d7eed43..83cf3bc12c5093 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary_3.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ForwarderLibrary_3.cs @@ -1,11 +1,11 @@ using System; -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary3A))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary3B))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary3A))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary3B))] namespace Mono.Linker.Tests.Cases.TypeForwarding.Dependencies { - public class RealClassInForwarder3 - { - } + public class RealClassInForwarder3 + { + } } \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ImplementationLibrary.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ImplementationLibrary.cs index 4501cbb4b72c63..505246a160c67f 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ImplementationLibrary.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ImplementationLibrary.cs @@ -1,6 +1,6 @@ using System; -//[assembly: AssemblyVersion ("2.0")] +//[assembly: AssemblyVersion("2.0")] namespace Mono.Linker.Tests.Cases.TypeForwarding.Dependencies { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ImplementationLibrary_3.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ImplementationLibrary_3.cs index 29223748b63b92..1d46ba76b07546 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ImplementationLibrary_3.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ImplementationLibrary_3.cs @@ -3,11 +3,11 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding.Dependencies { - public class ImplementationLibrary3A - { - } + public class ImplementationLibrary3A + { + } - public class ImplementationLibrary3B - { - } + public class ImplementationLibrary3B + { + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/MyEnumForwarder.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/MyEnumForwarder.cs index 03d4cf48420b43..550237260454cb 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/MyEnumForwarder.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/MyEnumForwarder.cs @@ -1,7 +1,7 @@ using System.Runtime.CompilerServices; using Mono.Linker.Tests.Cases.TypeForwarding.Dependencies; -[assembly: TypeForwardedTo (typeof (MyEnum))] +[assembly: TypeForwardedTo(typeof(MyEnum))] namespace Mono.Linker.Tests.Cases.TypeForwarding.Dependencies { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationLibrary.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationLibrary.cs index 0f99b22a744bcd..8c782971173d78 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationLibrary.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationLibrary.cs @@ -9,51 +9,51 @@ public class ReferenceImplementationLibrary } #if INCLUDE_REFERENCE_IMPL - public interface ImplementationLibraryInterface - { - public int GetDefaultImplementation () - { - return 42; - } - } - - public class ImplementationLibraryImp : ImplementationLibraryInterface - { - } - - public class ImplementationLibrary { - public class ImplementationLibraryNestedType - { - public static int PropertyOnNestedType { get; set; } - } - - public class ForwardedNestedType - { - } - - public static int someField = 0; - - public string GetSomeValue () - { - return null; - } - } - - public class AnotherImplementationClass - { - public class ForwardedNestedType - { - } - } - - [AttributeUsage (AttributeTargets.All)] - public class ImplementationLibraryAttribute : Attribute - { - } - - public struct ImplementationStruct - { - public int Field; - } + public interface ImplementationLibraryInterface + { + public int GetDefaultImplementation() + { + return 42; + } + } + + public class ImplementationLibraryImp : ImplementationLibraryInterface + { + } + + public class ImplementationLibrary { + public class ImplementationLibraryNestedType + { + public static int PropertyOnNestedType { get; set; } + } + + public class ForwardedNestedType + { + } + + public static int someField = 0; + + public string GetSomeValue() + { + return null; + } + } + + public class AnotherImplementationClass + { + public class ForwardedNestedType + { + } + } + + [AttributeUsage(AttributeTargets.All)] + public class ImplementationLibraryAttribute : Attribute + { + } + + public struct ImplementationStruct + { + public int Field; + } #endif } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationUsedAndUnusedLibrary.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationUsedAndUnusedLibrary.cs index ce8f6f698832d2..209d6976af459a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationUsedAndUnusedLibrary.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationUsedAndUnusedLibrary.cs @@ -1,13 +1,13 @@ namespace Mono.Linker.Tests.Cases.TypeForwarding.Dependencies { #if INCLUDE_REFERENCE_IMPL - public class ImplementationLibrary - { - public string GetSomeValue () => null; - } + public class ImplementationLibrary + { + public string GetSomeValue() => null; + } - public class UnusedImplementationLibrary - { - } + public class UnusedImplementationLibrary + { + } #endif } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/TypeForwardedIsUpdatedForMissingTypeFwd.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/TypeForwardedIsUpdatedForMissingTypeFwd.cs index 7145725e44cd72..5a47a8b0984e33 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/TypeForwardedIsUpdatedForMissingTypeFwd.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/TypeForwardedIsUpdatedForMissingTypeFwd.cs @@ -1 +1 @@ -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.C1))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.C1))] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/TypeForwardersModifiersLibFwd.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/TypeForwardersModifiersLibFwd.cs index 374028aad4e7cf..657596c8069e00 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/TypeForwardersModifiersLibFwd.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/TypeForwardersModifiersLibFwd.cs @@ -1 +1 @@ -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (C))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(C))] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/TypeForwardersRewriteForwarders.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/TypeForwardersRewriteForwarders.cs index cb79a2f0da8e21..6fbce770290597 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/TypeForwardersRewriteForwarders.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/TypeForwardersRewriteForwarders.cs @@ -1,4 +1,4 @@ -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.C))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.G<>))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.I))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo (typeof (Mono.Linker.Tests.Cases.TypeForwarding.S))] \ No newline at end of file +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.C))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.G<>))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.I))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Mono.Linker.Tests.Cases.TypeForwarding.S))] \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/MissingTargetReference.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/MissingTargetReference.cs index fdc56fa3dec4e6..c7568ca3d7f8fc 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/MissingTargetReference.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/MissingTargetReference.cs @@ -17,7 +17,7 @@ public class MissingTargetReference public static void Main() { #if IL_ASSEMBLY_AVAILABLE - Console.WriteLine (new DummyClass ()); + Console.WriteLine(new DummyClass()); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/SecurityAttributeScope.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/SecurityAttributeScope.cs index 2bbdbedc4cadbc..7ffe36146161b0 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/SecurityAttributeScope.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/SecurityAttributeScope.cs @@ -28,7 +28,7 @@ public class SecurityAttributeScope public static void Main() { #if IL_ASSEMBLY_AVAILABLE - new LibraryWithSecurityAttributes().OnAMethod (); + new LibraryWithSecurityAttributes().OnAMethod(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/TypeForwardersModifiers.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/TypeForwardersModifiers.cs index 131e265ac47376..9a2c3efea03478 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/TypeForwardersModifiers.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/TypeForwardersModifiers.cs @@ -21,7 +21,7 @@ class TypeForwardersModifiers static void Main() { #if IL_ASSEMBLY_AVAILABLE - TestClass.TestAll (); + TestClass.TestAll(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInGenericIsDynamicallyAccessedWithAssemblyCopyUsed.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInGenericIsDynamicallyAccessedWithAssemblyCopyUsed.cs index 1a36b72863b8bc..721a87e32b3b3d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInGenericIsDynamicallyAccessedWithAssemblyCopyUsed.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderInGenericIsDynamicallyAccessedWithAssemblyCopyUsed.cs @@ -34,7 +34,7 @@ static void Main() [Kept] static void PointToTypeInFacade( - [KeptAttributeAttribute (typeof(DynamicallyAccessedMembersAttribute))] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] string typeName) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderIsDynamicallyAccessedWithAssemblyCopyUsed.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderIsDynamicallyAccessedWithAssemblyCopyUsed.cs index 595541b55a12bd..5892a61d167cde 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderIsDynamicallyAccessedWithAssemblyCopyUsed.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedForwarderIsDynamicallyAccessedWithAssemblyCopyUsed.cs @@ -28,7 +28,7 @@ static void Main() [Kept] static void PointToTypeInFacade( - [KeptAttributeAttribute (typeof(DynamicallyAccessedMembersAttribute))] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] string typeName) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyAssemblyIsDynamicallyAccessed.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyAssemblyIsDynamicallyAccessed.cs index 286e6d73cea125..e3467f91711886 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyAssemblyIsDynamicallyAccessed.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyAssemblyIsDynamicallyAccessed.cs @@ -32,7 +32,7 @@ static void Main() [Kept] static void PointToTypeInFacade( - [KeptAttributeAttribute (typeof(DynamicallyAccessedMembersAttribute))] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] string typeName) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyUsedAssemblyIsDynamicallyAccessed.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyUsedAssemblyIsDynamicallyAccessed.cs index 293dcb89970af7..682c04815c1ff5 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyUsedAssemblyIsDynamicallyAccessed.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderInCopyUsedAssemblyIsDynamicallyAccessed.cs @@ -32,7 +32,7 @@ static void Main() [Kept] static void PointToTypeInFacade( - [KeptAttributeAttribute (typeof(DynamicallyAccessedMembersAttribute))] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] string typeName) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderIsDynamicallyAccessed.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderIsDynamicallyAccessed.cs index 6aacb8a1b97aac..8ab27190c746ed 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderIsDynamicallyAccessed.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/UsedTransitiveForwarderIsDynamicallyAccessed.cs @@ -30,7 +30,7 @@ static void Main() [Kept] static void PointToTypeInFacade( - [KeptAttributeAttribute (typeof(DynamicallyAccessedMembersAttribute))] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] string typeName) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/CompilerGeneratedCodeSubstitutions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/CompilerGeneratedCodeSubstitutions.cs index 52e81acf19b234..084e5d7181c91a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/CompilerGeneratedCodeSubstitutions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/CompilerGeneratedCodeSubstitutions.cs @@ -180,7 +180,7 @@ static IEnumerable TestBranchWithYieldAfter() } [ExpectedWarning("IL2026", "--UsedMethod--", CompilerGeneratedCode = true)] - [UnexpectedWarning("IL2026", "--RemovedMethod--", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/linker/issues/3087", CompilerGeneratedCode = true)] + [UnexpectedWarning("IL2026", "--RemovedMethod--", Tool.All, "https://github.com/dotnet/linker/issues/3087", CompilerGeneratedCode = true)] static IEnumerable TestBranchWithYieldBefore() { if (AlwaysFalse) @@ -224,7 +224,7 @@ static async Task TestBranchWithNormalCall() } [ExpectedWarning("IL2026", "--UsedMethod--", CompilerGeneratedCode = true)] - [UnexpectedWarning("IL2026", "--RemovedMethod--", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/linker/issues/3087", CompilerGeneratedCode = true)] + [UnexpectedWarning("IL2026", "--RemovedMethod--", Tool.All, "https://github.com/dotnet/linker/issues/3087", CompilerGeneratedCode = true)] static async Task TestBranchWithNormalCallAfterWAwait() { if (AlwaysFalse) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/ComplexConditions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/ComplexConditions.cs index 7e3dfc63d87068..1d2c2e107fe6bc 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/ComplexConditions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/ComplexConditions.cs @@ -22,7 +22,7 @@ public static void Main() [Kept] #if !NET - [ExpectBodyModified] + [ExpectBodyModified] #else [ExpectedInstructionSequence(new[] { "nop", @@ -55,7 +55,7 @@ static void Test_1(object type) [Kept] #if !NET - [ExpectBodyModified] + [ExpectBodyModified] #else [ExpectedInstructionSequence(new[] { "nop", diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/EndScopeOnMethoEnd.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/EndScopeOnMethoEnd.cs index 30e8778562ca48..37c21de319b250 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/EndScopeOnMethoEnd.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/EndScopeOnMethoEnd.cs @@ -14,8 +14,8 @@ public static void Main() { #if IL_ASSEMBLY_AVAILABLE // For now just have a method where the try/finally is the last thing in the method (no instruction after the - // end of finally - Roslyn doesn't seem to produce such method body. - Mono.Linker.Tests.Cases.UnreachableBlock.Dependencies.EndScopeOnMethod.TryFinally (); + // end of finally - Roslyn doesn't seem to produce such method body. + Mono.Linker.Tests.Cases.UnreachableBlock.Dependencies.EndScopeOnMethod.TryFinally(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/MethodWithParametersSubstitutions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/MethodWithParametersSubstitutions.cs index e386d3b03eae8f..3f73fb94b364b0 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/MethodWithParametersSubstitutions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/MethodWithParametersSubstitutions.cs @@ -24,7 +24,7 @@ public static void Main() TestMethodWithComplexParams_4(); TestMethodWithComplexParams_5(); instance.TestMethodWithMultipleInParamsInstance(); - // TestMethodWithOutParam (); + // TestMethodWithOutParam(); TestMethodWithRefParam(); TestMethodWithMultipleRefParams(); TestMethodWithValueParamAndConstReturn_NoSubstitutions(); @@ -195,27 +195,27 @@ void MethodWithMultipleInParamsInstance_NeverReached() { } // CodeRewriterStep actually fails when asked to rewrite method body with an out parameter. // So no point in testing that the substitution works or not. - //[Kept] static bool _isEnabledWithOutParamField; - - //[Kept] - //static bool IsEnabledWithOutParam (out int param) - //{ - // param = 0; - // return _isEnabledWithOutParamField; - //} - - //[Kept] - //[LogDoesNotContain("IsEnabledWithOutParam")] - //static void TestMethodWithOutParam () - //{ - // if (IsEnabledWithOutParam (out var _)) - // MethodWithOutParam_Reached1 (); - // else - // MethodWithOutParam_Reached2 (); - //} - - //[Kept] static void MethodWithOutParam_Reached1 () { } - //[Kept] static void MethodWithOutParam_Reached2 () { } + // [Kept] static bool _isEnabledWithOutParamField; + + // [Kept] + // static bool IsEnabledWithOutParam(out int param) + // { + // param = 0; + // return _isEnabledWithOutParamField; + // } + + // [Kept] + // [LogDoesNotContain("IsEnabledWithOutParam")] + // static void TestMethodWithOutParam() + // { + // if (IsEnabledWithOutParam(out var _)) + // MethodWithOutParam_Reached1(); + // else + // MethodWithOutParam_Reached2(); + // } + + // [Kept] static void MethodWithOutParam_Reached1() { } + // [Kept] static void MethodWithOutParam_Reached2() { } static bool _isEnabledWithRefParamField; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/SizeOfInConditions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/SizeOfInConditions.cs index a2b82f7781bf92..c44690e0bf6a8b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/SizeOfInConditions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/SizeOfInConditions.cs @@ -7,7 +7,7 @@ namespace Mono.Linker.Tests.Cases.UnreachableBlock #if NET [SetupLinkerSubstitutionFile("SizeOfInConditions.netcore.xml")] #else - [SetupLinkerSubstitutionFile ("SizeOfInConditions.net_4_x.xml")] + [SetupLinkerSubstitutionFile("SizeOfInConditions.net_4_x.xml")] #endif [SetupCompileArgument("/unsafe")] [SetupLinkerArgument("--enable-opt", "ipconstprop")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/UninitializedLocals.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/UninitializedLocals.cs index bfc3a2600e825c..1d3363d46da65f 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/UninitializedLocals.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/UninitializedLocals.cs @@ -22,8 +22,8 @@ public class UninitializedLocals public static void Main() { #if IL_ASSEMBLY_AVAILABLE - Mono.Linker.Tests.Cases.UnreachableBlock.Dependencies.ClassA.Method_1 (); - Mono.Linker.Tests.Cases.UnreachableBlock.Dependencies.ClassA.Method_2 (); + Mono.Linker.Tests.Cases.UnreachableBlock.Dependencies.ClassA.Method_1(); + Mono.Linker.Tests.Cases.UnreachableBlock.Dependencies.ClassA.Method_2(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/DoesNotApplyToCopiedAssembly2.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/DoesNotApplyToCopiedAssembly2.cs index 1c0d5ca0cc0d6b..7144647a374e62 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/DoesNotApplyToCopiedAssembly2.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/DoesNotApplyToCopiedAssembly2.cs @@ -16,16 +16,16 @@ public class DoesNotApplyToCopiedAssembly2 public static void Main() { #if OTHER_INCLUDED - UsedToMarkMethod (null); + UsedToMarkMethod(null); #endif } #if OTHER_INCLUDED - [Kept] - static void UsedToMarkMethod (Mono.Linker.Tests.Cases.UnreachableBody.Dependencies.OtherAssemblyNoInstanceCtor.Foo f) - { - f.Method (); - } + [Kept] + static void UsedToMarkMethod(Mono.Linker.Tests.Cases.UnreachableBody.Dependencies.OtherAssemblyNoInstanceCtor.Foo f) + { + f.Method(); + } #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibrary.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibrary.cs index 0b4007a66a4136..49defd3721fe03 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibrary.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibrary.cs @@ -7,7 +7,7 @@ namespace Mono.Linker.Tests.Cases.UnreachableBody #if NET [SetupLinkerArgument("-a", "other2.dll")] #else - [SetupLinkerArgument ("-r", "other2")] + [SetupLinkerArgument("-r", "other2")] #endif [SetupCompileBefore("other2.dll", new[] { typeof(OtherAssembly) })] [KeptMemberInAssembly("other2.dll", typeof(OtherAssembly.Foo), "Method()")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibraryNoInstanceCtor.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibraryNoInstanceCtor.cs index 2d34f11024f30c..0a9af1a1a63e3c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibraryNoInstanceCtor.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibraryNoInstanceCtor.cs @@ -8,7 +8,7 @@ namespace Mono.Linker.Tests.Cases.UnreachableBody #if NET [SetupLinkerArgument("-a", "other.dll", "visible")] #else - [SetupLinkerArgument ("-r", "other")] + [SetupLinkerArgument("-r", "other")] #endif [SetupCompileBefore("other.dll", new[] { "Dependencies/OtherAssemblyNoInstanceCtor.il" })] [KeptMemberInAssembly("other.dll", "Mono.Linker.Tests.Cases.UnreachableBody.Dependencies.OtherAssemblyNoInstanceCtor/Foo", "Method()")] @@ -20,16 +20,16 @@ public class LinkedOtherIncludedLibraryNoInstanceCtor public static void Main() { #if OTHER_INCLUDED - UsedToMarkMethod (null); + UsedToMarkMethod(null); #endif } #if OTHER_INCLUDED - [Kept] - static void UsedToMarkMethod (Mono.Linker.Tests.Cases.UnreachableBody.Dependencies.OtherAssemblyNoInstanceCtor.Foo f) - { - f.Method (); - } + [Kept] + static void UsedToMarkMethod(Mono.Linker.Tests.Cases.UnreachableBody.Dependencies.OtherAssemblyNoInstanceCtor.Foo f) + { + f.Method(); + } #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/CanDisableWarningsByCategory.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/CanDisableWarningsByCategory.cs index 82a2f73372455a..53188a07c65fee 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/CanDisableWarningsByCategory.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/CanDisableWarningsByCategory.cs @@ -11,7 +11,7 @@ namespace Mono.Linker.Tests.Cases.Warnings [SkipKeptItemsValidation] [SetupLinkerArgument("--notrimwarn")] #if NATIVEAOT - [SetupLinkerArgument ("--noaotwarn")] + [SetupLinkerArgument("--noaotwarn")] #endif public class CanDisableWarningsByCategory { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/CanWarnAsErrorGlobal.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/CanWarnAsErrorGlobal.cs index ecfa2deb8c8dfe..da3be9e2d4494a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/CanWarnAsErrorGlobal.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/CanWarnAsErrorGlobal.cs @@ -24,16 +24,16 @@ public static void Main() } #if IN_TEST_BUILD - public class CanWarnAsError - { - class HelperClass - { - private int helperField = 0; - int HelperMethod () - { - return 0; - } - } - } + public class CanWarnAsError + { + class HelperClass + { + private int helperField = 0; + int HelperMethod() + { + return 0; + } + } + } #endif } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Dependencies/CustomStep.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Dependencies/CustomStep.cs index 7c6edad55ec8ed..326af86ef8cfa0 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Dependencies/CustomStep.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Dependencies/CustomStep.cs @@ -7,35 +7,35 @@ namespace CustomStep { - public class CustomStep : IStep - { - public void Process (LinkContext context) - { - var warningMessage = MessageContainer.CreateCustomWarningMessage ( - context: context, - text: "Warning", - code: 6001, - origin: new MessageOrigin (fileName: "CustomStep.cs"), - version: WarnVersion.Latest); + public class CustomStep : IStep + { + public void Process(LinkContext context) + { + var warningMessage = MessageContainer.CreateCustomWarningMessage( + context: context, + text: "Warning", + code: 6001, + origin: new MessageOrigin(fileName: "CustomStep.cs"), + version: WarnVersion.Latest); - context.LogMessage (warningMessage); - } - } + context.LogMessage(warningMessage); + } + } - public class CustomStepWithInvalidWarningCode : IStep - { - public void Process (LinkContext context) - { - // All codes in the range [1000-6000] are reserved for trimming, single-file and nativeAOT - // errors and warnings and should not be used by external parties. - var invalidWarningMessage = MessageContainer.CreateCustomWarningMessage ( - context: context, - text: "Warning", - code: 2500, - origin: new MessageOrigin (fileName: "CustomStep.cs"), - version: WarnVersion.Latest); + public class CustomStepWithInvalidWarningCode : IStep + { + public void Process(LinkContext context) + { + // All codes in the range [1000-6000] are reserved for trimming, single-file and nativeAOT + // errors and warnings and should not be used by external parties. + var invalidWarningMessage = MessageContainer.CreateCustomWarningMessage( + context: context, + text: "Warning", + code: 2500, + origin: new MessageOrigin(fileName: "CustomStep.cs"), + version: WarnVersion.Latest); - context.LogMessage (invalidWarningMessage); - } - } + context.LogMessage(invalidWarningMessage); + } + } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileCSharp.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileCSharp.cs index c58571c859e04b..b44ec756b41c9f 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileCSharp.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileCSharp.cs @@ -9,8 +9,8 @@ namespace Mono.Linker.Tests.Cases.Warnings.Individual { [SetupLinkerTrimMode("skip")] #if !NET - [Reference ("System.Core.dll")] - [SetupCompileBefore ("library.dll", new[] { typeof (TriggerWarnings_Lib) }, new[] { "System.Core.dll" })] + [Reference("System.Core.dll")] + [SetupCompileBefore("library.dll", new[] { typeof(TriggerWarnings_Lib) }, new[] { "System.Core.dll" })] #else [SetupCompileBefore("library.dll", new[] { typeof(TriggerWarnings_Lib) })] #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileXml.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileXml.cs index 0924de5ad991c4..82306bba13b6a3 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileXml.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileXml.cs @@ -6,7 +6,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.Individual { [SetupLinkerTrimMode("skip")] #if !NET - [SetupCompileBefore ("library.dll", new[] { typeof (TriggerWarnings_Lib) }, new[] { "System.Core.dll" })] + [SetupCompileBefore("library.dll", new[] { typeof(TriggerWarnings_Lib) }, new[] { "System.Core.dll" })] #else [SetupCompileBefore("library.dll", new[] { typeof(TriggerWarnings_Lib) })] #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/WarningsAreSorted.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/WarningsAreSorted.cs index f1ad9eaa1113d6..55f0fc0548560c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/WarningsAreSorted.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/WarningsAreSorted.cs @@ -13,7 +13,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.Individual [SkipRemainingErrorsValidation] [SetupLinkerTrimMode("skip")] #if !NET - [SetupCompileBefore ("library.dll", new[] { typeof (TriggerWarnings_Lib) }, new[] { "System.Core.dll" })] + [SetupCompileBefore("library.dll", new[] { typeof(TriggerWarnings_Lib) }, new[] { "System.Core.dll" })] #else [SetupCompileBefore("library.dll", new[] { typeof(TriggerWarnings_Lib) })] #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/MultipleMethodsUseSameAsyncStateMachine.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/MultipleMethodsUseSameAsyncStateMachine.cs index 8bfb22b953552d..9e7cc8e7375add 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/MultipleMethodsUseSameAsyncStateMachine.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/MultipleMethodsUseSameAsyncStateMachine.cs @@ -20,7 +20,7 @@ class MultipleMethodsUseSameAsyncStateMachine public static void Main() { #if IL_ASSEMBLY_AVAILABLE - Dependencies.MultipleMethodsUseSameAsyncStateMachine.M(); + Dependencies.MultipleMethodsUseSameAsyncStateMachine.M(); #endif } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInAssembly.cs index 3f478301d6a7fc..2452a6e49ee98d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInAssembly.cs @@ -8,7 +8,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression { #if !NET - [Mono.Linker.Tests.Cases.Expectations.Metadata.Reference ("System.Core.dll")] + [Mono.Linker.Tests.Cases.Expectations.Metadata.Reference("System.Core.dll")] #endif [SkipKeptItemsValidation] [LogDoesNotContain("TriggerUnrecognizedPattern()")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCompilerGeneratedCode.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCompilerGeneratedCode.cs index 9dc1f72216a658..1facb506c2acf2 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCompilerGeneratedCode.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCompilerGeneratedCode.cs @@ -589,7 +589,7 @@ void LocalFunction() } // The suppression on the lambda is ignored - [UnexpectedWarning("IL2026", Tool.TrimmerAnalyzerAndNativeAot, "https://github.com/dotnet/roslyn/issues/59746 https://github.com/dotnet/roslyn/issues/82956", CompilerGeneratedCode = true)] + [UnexpectedWarning("IL2026", Tool.All, "https://github.com/dotnet/roslyn/issues/59746 https://github.com/dotnet/roslyn/issues/82956", CompilerGeneratedCode = true)] [UnexpectedWarning("IL2121", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/82956", CompilerGeneratedCode = true)] static void TestLocalFunctionInLambda() { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCopyAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCopyAssembly.cs index 6e488e9696f0f1..0619aef770dc3d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCopyAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCopyAssembly.cs @@ -8,7 +8,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression { #if !NET - [Reference ("System.Core.dll")] + [Reference("System.Core.dll")] #endif [SetupLinkerAction("copy", "test")] [SkipKeptItemsValidation] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypes.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypes.cs index 6cd7366d4096b3..c11ae832f80be5 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypes.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypes.cs @@ -7,7 +7,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression { #if !NET - [Mono.Linker.Tests.Cases.Expectations.Metadata.Reference ("System.Core.dll")] + [Mono.Linker.Tests.Cases.Expectations.Metadata.Reference("System.Core.dll")] #endif [SkipKeptItemsValidation] [LogDoesNotContain("TriggerUnrecognizedPattern()")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypesUsingTarget.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypesUsingTarget.cs index cbae89ba77f881..c045717227a4f5 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypesUsingTarget.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypesUsingTarget.cs @@ -13,7 +13,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression { #if !NET - [Mono.Linker.Tests.Cases.Expectations.Metadata.Reference ("System.Core.dll")] + [Mono.Linker.Tests.Cases.Expectations.Metadata.Reference("System.Core.dll")] #endif [SkipKeptItemsValidation] [LogDoesNotContain("TriggerUnrecognizedPattern()")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInModule.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInModule.cs index a0ee1f51b696c7..26d6571a564472 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInModule.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInModule.cs @@ -10,7 +10,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression { #if !NET - [Mono.Linker.Tests.Cases.Expectations.Metadata.Reference ("System.Core.dll")] + [Mono.Linker.Tests.Cases.Expectations.Metadata.Reference("System.Core.dll")] #endif [SkipKeptItemsValidation] [LogDoesNotContain("TriggerUnrecognizedPattern()")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsViaXml.xml b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsViaXml.xml index 00227a178475bd..e7d95da2da4289 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsViaXml.xml +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsViaXml.xml @@ -8,10 +8,6 @@ IL2026 - - ILLink - IL2109 - diff --git a/src/tools/illink/test/Mono.Linker.Tests/Mono.Linker.Tests.csproj b/src/tools/illink/test/Mono.Linker.Tests/Mono.Linker.Tests.csproj index 2d7890e6002420..ca8657356dc8b3 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/Mono.Linker.Tests.csproj +++ b/src/tools/illink/test/Mono.Linker.Tests/Mono.Linker.Tests.csproj @@ -48,6 +48,12 @@ $(TargetFramework) + + $(TargetFrameworkMoniker) + + + $(TargetFrameworkMonikerDisplayName) + $(MicrosoftDotNetCecilVersion) diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs index 55bc29499cbeb3..e924f613003a72 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.Linq; using System.Text; @@ -149,15 +150,10 @@ protected virtual IEnumerable VerifyTypeDefinition(TypeDefinition origin if (linked == null) yield break; - // Compiler generated members can't be annotated with `Kept` attributes directly - // For some of them we have special attributes (backing fields for example), but it's impractical to define - // special attributes for all types of compiler generated members (there are quite a few of them and they're - // going to change/increase over time). - // So we're effectively disabling Kept validation on compiler generated members - // Note that we still want to go "inside" each such member, as it might have additional attributes + // Note that we still want to go "inside" each skipped type, as it might have additional attributes // we do want to validate. There's no specific use case right now, but I can easily imagine one // for more detailed testing of for example custom attributes on local functions, or similar. - if (!IsCompilerGeneratedMember(original)) + if (!SkipKeptItemsValidation(original)) yield return $"Type `{original}' should have been removed"; } @@ -202,9 +198,9 @@ IEnumerable VerifyKeptByAttributes(ICustomAttributeProvider src, string IEnumerable VerifyKeptByAttribute(string keptAttributeProviderName, CustomAttribute attribute) { - // public KeptByAttribute (string dependencyProvider, string reason) { } - // public KeptByAttribute (Type dependencyProvider, string reason) { } - // public KeptByAttribute (Type dependencyProvider, string memberName, string reason) { } + // public KeptByAttribute(string dependencyProvider, string reason) { } + // public KeptByAttribute(Type dependencyProvider, string reason) { } + // public KeptByAttribute(Type dependencyProvider, string memberName, string reason) { } Assert.AreEqual(nameof(KeptByAttribute), attribute.AttributeType.Name); @@ -214,8 +210,8 @@ IEnumerable VerifyKeptByAttribute(string keptAttributeProviderName, Cust expectedDependency.Marked = true; if (attribute.ConstructorArguments.Count == 2) { - // public KeptByAttribute (string dependencyProvider, string reason) { } - // public KeptByAttribute (Type dependencyProvider, string reason) { } + // public KeptByAttribute(string dependencyProvider, string reason) { } + // public KeptByAttribute(Type dependencyProvider, string reason) { } if (attribute.ConstructorArguments[0].Type.IsTypeOf()) expectedDependency.Source = (string)attribute.ConstructorArguments[0].Value; else if (attribute.ConstructorArguments[0].Type.IsTypeOf()) @@ -227,7 +223,7 @@ IEnumerable VerifyKeptByAttribute(string keptAttributeProviderName, Cust } else if (attribute.ConstructorArguments.Count == 3) { - // public KeptByAttribute (Type dependencyProvider, string memberName, string reason) { } + // public KeptByAttribute(Type dependencyProvider, string memberName, string reason) { } if (!attribute.ConstructorArguments[0].Type.IsTypeOf()) throw new NotImplementedException("Unexpected KeptByAttribute ctor variant"); var type = (TypeDefinition)attribute.ConstructorArguments[0].Value; @@ -259,8 +255,7 @@ protected virtual IEnumerable VerifyTypeDefinitionKept(TypeDefinition or yield break; } - // Skip verification of type metadata for compiler generated types (we don't currently need it yet) - if (!IsCompilerGeneratedMember(original)) + if (!SkipKeptItemsValidation(original)) { foreach (var err in VerifyKeptByAttributes(original, linked)) yield return err; @@ -270,9 +265,9 @@ protected virtual IEnumerable VerifyTypeDefinitionKept(TypeDefinition or foreach (var err in VerifyInterfaces(original, linked)) yield return err; - foreach (var err in VerifyPseudoAttributes(original, linked)) + foreach (var err in VerifyPseudoAttributes(original, linked)) yield return err; - foreach (var err in VerifyGenericParameters(original, linked, compilerGenerated: false)) + foreach (var err in VerifyGenericParameters(original, linked, skipKeptItemsValidation: false)) yield return err; foreach (var err in VerifyCustomAttributes(original, linked)) yield return err; @@ -445,23 +440,22 @@ static string FormatBaseOrInterfaceAttributeValue(CustomAttribute attr) IEnumerable VerifyField(FieldDefinition src, FieldDefinition linked) { - bool compilerGenerated = IsCompilerGeneratedMember(src); - bool expectedKept = ShouldBeKept(src) || - (compilerGenerated ? !IsBackingField(src) : false); + bool skipKeptItemsValidation = SkipKeptItemsValidation(src); + bool expectedKept = ShouldBeKept(src); if (!expectedKept) { - if (linked != null) + if (linked != null && !skipKeptItemsValidation) yield return $"Field `{src}' should have been removed"; yield break; } - foreach (var err in VerifyFieldKept(src, linked, compilerGenerated)) + foreach (var err in VerifyFieldKept(src, linked, skipKeptItemsValidation)) yield return err; } - IEnumerable VerifyFieldKept(FieldDefinition src, FieldDefinition linked, bool compilerGenerated) + IEnumerable VerifyFieldKept(FieldDefinition src, FieldDefinition linked, bool skipKeptItemsValidation) { if (linked == null) { @@ -475,7 +469,7 @@ IEnumerable VerifyFieldKept(FieldDefinition src, FieldDefinition linked, foreach (var err in VerifyKeptByAttributes(src, linked)) yield return err; VerifyPseudoAttributes(src, linked); - if (!compilerGenerated) + if (!skipKeptItemsValidation) foreach (var err in VerifyCustomAttributes(src, linked)) yield return err; } @@ -485,12 +479,12 @@ IEnumerable VerifyProperty(PropertyDefinition src, PropertyDefinition li foreach (var err in VerifyMemberBackingField(src, linkedType)) yield return err; - bool compilerGenerated = IsCompilerGeneratedMember(src); - bool expectedKept = ShouldBeKept(src) || compilerGenerated; + bool skipKeptItemsValidation = SkipKeptItemsValidation(src); + bool expectedKept = ShouldBeKept(src); if (!expectedKept) { - if (linked != null) + if (linked != null && !skipKeptItemsValidation) yield return $"Property `{src}' should have been removed"; yield break; @@ -509,7 +503,7 @@ IEnumerable VerifyProperty(PropertyDefinition src, PropertyDefinition li yield return err; foreach (var err in VerifyPseudoAttributes(src, linked)) yield return err; - if (!compilerGenerated) + if (!skipKeptItemsValidation) foreach (var err in VerifyCustomAttributes(src, linked)) yield return err; } @@ -519,12 +513,12 @@ IEnumerable VerifyEvent(EventDefinition src, EventDefinition linked, Typ foreach (var err in VerifyMemberBackingField(src, linkedType)) yield return err; - bool compilerGenerated = IsCompilerGeneratedMember(src); - bool expectedKept = ShouldBeKept(src) || compilerGenerated; + bool skipKeptItemsValidation = SkipKeptItemsValidation(src); + bool expectedKept = ShouldBeKept(src); if (!expectedKept) { - if (linked != null) + if (linked != null && !skipKeptItemsValidation) yield return $"Event `{src}' should have been removed"; yield break; @@ -538,7 +532,7 @@ IEnumerable VerifyEvent(EventDefinition src, EventDefinition linked, Typ if (src.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(KeptEventAddMethodAttribute))) { - foreach (var err in VerifyMethodInternal(src.AddMethod, linked.AddMethod, true, compilerGenerated)) + foreach (var err in VerifyMethodInternal(src.AddMethod, linked.AddMethod, true, skipKeptItemsValidation)) yield return err; verifiedEventMethods.Add(src.AddMethod.FullName); linkedMembers.Remove(src.AddMethod.FullName); @@ -546,7 +540,7 @@ IEnumerable VerifyEvent(EventDefinition src, EventDefinition linked, Typ if (src.CustomAttributes.Any(attr => attr.AttributeType.Name == nameof(KeptEventRemoveMethodAttribute))) { - foreach (var err in VerifyMethodInternal(src.RemoveMethod, linked.RemoveMethod, true, compilerGenerated)) + foreach (var err in VerifyMethodInternal(src.RemoveMethod, linked.RemoveMethod, true, skipKeptItemsValidation)) yield return err; verifiedEventMethods.Add(src.RemoveMethod.FullName); linkedMembers.Remove(src.RemoveMethod.FullName); @@ -556,37 +550,36 @@ IEnumerable VerifyEvent(EventDefinition src, EventDefinition linked, Typ yield return err; foreach (var err in VerifyPseudoAttributes(src, linked)) yield return err; - if (!compilerGenerated) + if (!skipKeptItemsValidation) foreach (var err in VerifyCustomAttributes(src, linked)) yield return err; } IEnumerable VerifyMethod(MethodDefinition src, MethodDefinition linked) { - bool compilerGenerated = IsCompilerGeneratedMember(src); + bool skipKeptItemsValidation = SkipKeptItemsValidation(src); bool expectedKept = ShouldMethodBeKept(src); - foreach (var err in VerifyMethodInternal(src, linked, expectedKept, compilerGenerated)) + foreach (var err in VerifyMethodInternal(src, linked, expectedKept, skipKeptItemsValidation)) yield return err; } - IEnumerable VerifyMethodInternal(MethodDefinition src, MethodDefinition linked, bool expectedKept, bool compilerGenerated) + IEnumerable VerifyMethodInternal(MethodDefinition src, MethodDefinition linked, bool expectedKept, bool skipKeptItemsValidation) { if (!expectedKept) { if (linked == null) yield break; - // Similar to comment on types, compiler-generated methods can't be annotated with Kept attribute directly - // so we're not going to validate kept/remove on them. Note that we're still going to go validate "into" them - // to check for other properties (like parameter name presence/removal for example) - if (!compilerGenerated) + // Note that we're still going to go validate "into" skipped methods to check for other properties + // (like parameter name presence/removal for example) + if (!skipKeptItemsValidation) yield return $"Method `{src.FullName}' should have been removed"; } foreach (var err in VerifyOverrides(src, linked)) yield return err; - foreach (var err in VerifyMethodKept(src, linked, compilerGenerated)) + foreach (var err in VerifyMethodKept(src, linked, skipKeptItemsValidation: skipKeptItemsValidation)) yield return err; } @@ -616,13 +609,13 @@ IEnumerable VerifyMemberBackingField(IMemberDefinition src, TypeDefiniti yield break; } - foreach (var err in VerifyFieldKept(srcField, linkedType?.Fields.FirstOrDefault(l => srcField.Name == l.Name), compilerGenerated: true)) + foreach (var err in VerifyFieldKept(srcField, linkedType?.Fields.FirstOrDefault(l => srcField.Name == l.Name), skipKeptItemsValidation: true)) yield return err; verifiedGeneratedFields.Add(srcField.FullName); linkedMembers.Remove(srcField.FullName); } - protected virtual IEnumerable VerifyMethodKept(MethodDefinition src, MethodDefinition linked, bool compilerGenerated) + protected virtual IEnumerable VerifyMethodKept(MethodDefinition src, MethodDefinition linked, bool skipKeptItemsValidation) { if (linked == null) { @@ -632,9 +625,9 @@ protected virtual IEnumerable VerifyMethodKept(MethodDefinition src, Met foreach (var err in VerifyPseudoAttributes(src, linked)) yield return err; - foreach (var err in VerifyGenericParameters(src, linked, compilerGenerated)) + foreach (var err in VerifyGenericParameters(src, linked, skipKeptItemsValidation)) yield return err; - if (!compilerGenerated) + if (!skipKeptItemsValidation) { foreach (var err in VerifyCustomAttributes(src, linked)) yield return err; @@ -642,7 +635,7 @@ protected virtual IEnumerable VerifyMethodKept(MethodDefinition src, Met yield return err; } - foreach (var err in VerifyParameters(src, linked, compilerGenerated)) + foreach (var err in VerifyParameters(src, linked, skipKeptItemsValidation)) yield return err; foreach (var err in VerifySecurityAttributes(src, linked)) yield return err; @@ -857,14 +850,14 @@ IEnumerable VerifyReferences(AssemblyDefinition original, AssemblyDefini .ToHashSet(); /* - - The test case will always need to have at least 1 reference. - - Forcing all tests to define their expected references seems tedious + - The test case will always need to have at least 1 reference. + - Forcing all tests to define their expected references seems tedious - Given the above, let's assume that when no [KeptReference] attributes are present, - the test case does not want to make any assertions regarding references. + Given the above, let's assume that when no [KeptReference] attributes are present, + the test case does not want to make any assertions regarding references. - Once 1 kept reference attribute is used, the test will need to define all of of it's expected references - */ + Once 1 kept reference attribute is used, the test will need to define all of of it's expected references + */ if (expected.Count == 0) yield break; @@ -1013,7 +1006,7 @@ IEnumerable VerifyPrivateImplementationDetails(TypeDefinition original, yield return $"Could not locate original private implementation details method {methodName}"; var linkedMethod = linkedImplementationDetails.Methods.FirstOrDefault(m => m.Name == methodName); - foreach (var erro in VerifyMethodKept(originalMethod, linkedMethod, compilerGenerated: true)) + foreach (var erro in VerifyMethodKept(originalMethod, linkedMethod, skipKeptItemsValidation: true)) yield return erro; linkedMembers.Remove(linkedMethod.FullName); } @@ -1090,7 +1083,7 @@ protected virtual IEnumerable VerifyArrayInitializers(MethodDefinition s IEnumerable VerifyInitializerField(FieldDefinition src, FieldDefinition linked) { - foreach (var err in VerifyFieldKept(src, linked, compilerGenerated: true)) + foreach (var err in VerifyFieldKept(src, linked, skipKeptItemsValidation: true)) yield return err; verifiedGeneratedFields.Add(linked.FullName); linkedMembers.Remove(linked.FullName); @@ -1160,6 +1153,12 @@ protected virtual IEnumerable FilterLinkedAttributes(ICustomAttributePro if (linked is AssemblyDefinition) continue; break; + + // TargetFrameworkAttribute is generated for most testcases, so don't check this. + case "System.Runtime.Versioning.TargetFrameworkAttribute": + if (linked is AssemblyDefinition) + continue; + break; } yield return attr.AttributeType.FullName; @@ -1196,7 +1195,7 @@ IEnumerable VerifyFixedBufferFields(TypeDefinition src, TypeDefinition l yield return $"Could not locate original compiler generated FixedElementField on {originalCompilerGeneratedBufferType}"; var linkedField = linkedCompilerGeneratedBufferType?.Fields.FirstOrDefault(); - foreach (var err in VerifyFieldKept(originalElementField, linkedField, compilerGenerated: true)) + foreach (var err in VerifyFieldKept(originalElementField, linkedField, skipKeptItemsValidation: true)) yield return err; verifiedGeneratedFields.Add(originalElementField.FullName); linkedMembers.Remove(linkedField.FullName); @@ -1231,7 +1230,7 @@ IEnumerable VerifyDelegateBackingFields(TypeDefinition src, TypeDefiniti yield return $"Invalid expected delegate backing field {expectedFieldName} in {src}. This member was not in the unlinked assembly"; var linkedField = linkedNestedType?.Fields.FirstOrDefault(f => f.Name == expectedFieldName); - foreach (var err in VerifyFieldKept(originalField, linkedField, compilerGenerated: true)) + foreach (var err in VerifyFieldKept(originalField, linkedField, skipKeptItemsValidation: true)) yield return err; verifiedGeneratedFields.Add(linkedField.FullName); linkedMembers.Remove(linkedField.FullName); @@ -1243,7 +1242,7 @@ IEnumerable VerifyDelegateBackingFields(TypeDefinition src, TypeDefiniti } } - IEnumerable VerifyGenericParameters(IGenericParameterProvider src, IGenericParameterProvider linked, bool compilerGenerated) + IEnumerable VerifyGenericParameters(IGenericParameterProvider src, IGenericParameterProvider linked, bool skipKeptItemsValidation) { Assert.AreEqual(src.HasGenericParameters, linked.HasGenericParameters); if (src.HasGenericParameters) @@ -1258,7 +1257,7 @@ IEnumerable VerifyGenericParameters(IGenericParameterProvider src, IGene foreach (var err in VerifyGenericParameterAttributes(srcp, lnkp)) yield return err; - if (!compilerGenerated) + if (!skipKeptItemsValidation) { foreach (var err in VerifyCustomAttributes(srcp, lnkp)) yield return err; @@ -1353,7 +1352,7 @@ IEnumerable VerifyGenericParameterAttributes(GenericParameter src, Gener yield return $"Mismatch in generic parameter attributes on {src} of {src.Owner}. Expected: {expectedAttributes}, Output: {linkedAttributes}"; } - IEnumerable VerifyParameters(IMethodSignature src, IMethodSignature linked, bool compilerGenerated) + IEnumerable VerifyParameters(IMethodSignature src, IMethodSignature linked, bool skipKeptItemsValidation) { if (src.HasParameters != linked.HasParameters) yield return $"Mismatch in parameters. {src} has parameters: {src.HasParameters}, {linked} has parameters: {linked.HasParameters}"; @@ -1364,7 +1363,7 @@ IEnumerable VerifyParameters(IMethodSignature src, IMethodSignature link var srcp = src.Parameters[i]; var lnkp = linked.Parameters[i]; - if (!compilerGenerated) + if (!skipKeptItemsValidation) { foreach (var err in VerifyCustomAttributes(srcp, lnkp)) yield return err; diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ILCompiler.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ILCompiler.cs index 4cdd7467506b21..84760a8cf5d8fa 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ILCompiler.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ILCompiler.cs @@ -54,8 +54,8 @@ private static string BuildArguments(CompilerOptions options) args.Append(options.OutputPath.ExtensionWithDot == ".dll" ? "-dll" : "-exe"); args.Append($" -out:{options.OutputPath.InQuotes()}"); #else - args.Append (options.OutputPath.ExtensionWithDot == ".dll" ? "/dll" : "/exe"); - args.Append ($" /out:{options.OutputPath.InQuotes ()}"); + args.Append(options.OutputPath.ExtensionWithDot == ".dll" ? "/dll" : "/exe"); + args.Append($" /out:{options.OutputPath.InQuotes()}"); #endif args.Append($" {options.SourceFiles.Aggregate(string.Empty, (buff, file) => $"{buff} {file.InQuotes()}")}"); return args.ToString(); @@ -74,7 +74,7 @@ protected virtual NPath LocateIlasm() throw new InvalidOperationException("ilasm not found at " + ilasmPath); #else - return Environment.OSVersion.Platform == PlatformID.Win32NT ? LocateIlasmOnWindows () : "ilasm".ToNPath (); + return Environment.OSVersion.Platform == PlatformID.Win32NT ? LocateIlasmOnWindows() : "ilasm".ToNPath(); #endif } diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ILVerification/ILChecker.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ILVerification/ILChecker.cs index 66ffdfc9f24915..9f0b8fa5952dc9 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ILVerification/ILChecker.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ILVerification/ILChecker.cs @@ -176,7 +176,7 @@ protected virtual ILVerifier CreateILVerifier(NPath directory) return new ILVerifier(new[] { directory, - typeof (object).Assembly.Location.ToNPath ().Parent + typeof(object).Assembly.Location.ToNPath().Parent }, "System.Private.CoreLib"); } diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs index 828d3ee4924c34..6fc186db7d2564 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs @@ -135,17 +135,17 @@ public virtual void Check(TrimmedTestCaseResult linkResult) _originalsResolver.Dispose(); _linkedResolver.Dispose(); } + } - bool HasActiveSkipKeptItemsValidationAttribute(ICustomAttributeProvider provider) + internal static bool HasActiveSkipKeptItemsValidationAttribute(IMemberDefinition provider) + { + if (TryGetCustomAttribute(provider, nameof(SkipKeptItemsValidationAttribute), out var attribute)) { - if (TryGetCustomAttribute(provider, nameof(SkipKeptItemsValidationAttribute), out var attribute)) - { - object by = attribute.GetPropertyValue(nameof(SkipKeptItemsValidationAttribute.By)); - return by is null ? true : ((Tool)by).HasFlag(Tool.Trimmer); - } - - return false; + object by = attribute.GetPropertyValue(nameof(SkipKeptItemsValidationAttribute.By)); + return by is null ? true : ((Tool)by).HasFlag(Tool.Trimmer); } + + return false; } protected virtual void VerifyILOfOtherAssemblies(TrimmedTestCaseResult linkResult) @@ -1148,7 +1148,6 @@ void VerifyLoggedMessages(AssemblyDefinition original, TrimmingTestLogger logger int? unexpectedWarningCodeNumber = unexpectedWarningCode == null ? null : int.Parse(unexpectedWarningCode.Substring(2)); - MessageContainer? unexpectedWarningMessage = null; foreach (var mc in unmatchedMessages) { if (mc.Category != MessageCategory.Warning) @@ -1161,13 +1160,7 @@ void VerifyLoggedMessages(AssemblyDefinition original, TrimmingTestLogger logger if (attrProvider is IMemberDefinition attrMember && (mc.Origin?.Provider is IMemberDefinition member) && member.FullName.Contains(attrMember.FullName) != true) continue; - unexpectedWarningMessage = mc; - break; - } - - if (unexpectedWarningMessage is not null) - { - unexpectedMessageWarnings.Add($"Unexpected warning found: {unexpectedWarningMessage}"); + unexpectedMessageWarnings.Add($"Unexpected warning found: {mc}"); } } @@ -1415,7 +1408,7 @@ static bool HasAttribute(ICustomAttributeProvider caProvider, string attributeNa } #nullable enable - static bool TryGetCustomAttribute(ICustomAttributeProvider caProvider, string attributeName, [NotNullWhen(true)] out CustomAttribute? customAttribute) + internal static bool TryGetCustomAttribute(ICustomAttributeProvider caProvider, string attributeName, [NotNullWhen(true)] out CustomAttribute? customAttribute) { if (caProvider is AssemblyDefinition assembly && assembly.EntryPoint != null) { diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs index 87fc9f898955a3..4ce4b210d6675b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs @@ -127,7 +127,7 @@ static string GetReferenceDir() string runtimeDir = Path.GetDirectoryName(typeof(object).Assembly.Location); string ncaVersion = Path.GetFileName(runtimeDir); var dotnetDir = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(runtimeDir))); - string candidatePath = Path.Combine(dotnetDir, "packs", "Microsoft.NETCore.App.Ref", ncaVersion, "ref", PathUtilities.TFMDirectoryName); + string candidatePath = Path.Combine(dotnetDir, "packs", "Microsoft.NETCore.App.Ref", ncaVersion, "ref", PathUtilities.TargetFramework); if (Directory.Exists(candidatePath)) return candidatePath; @@ -144,13 +144,27 @@ static string GetReferenceDir() if (candidatePath == null) throw new InvalidOperationException($"Could not determine ref pack path. Based on runtime directory {runtimeDir}."); - candidatePath = Path.Combine(candidatePath, "ref", PathUtilities.TFMDirectoryName); + candidatePath = Path.Combine(candidatePath, "ref", PathUtilities.TargetFramework); if (Directory.Exists(candidatePath)) return candidatePath; throw new InvalidOperationException($"Could not determine ref pack path. Computed path {candidatePath} doesn't exist."); } + public IEnumerable GetCommonSourceFiles() + { + yield return _testCase.RootCasesDirectory.Parent + .Combine("Mono.Linker.Tests.Cases.Expectations") + .Combine("Support") + .Combine("DynamicallyAccessedMembersAttribute.cs"); + + var sharedDir = _testCase.RootCasesDirectory.Parent.Parent + .Combine("src") + .Combine("ILLink.Shared"); + yield return sharedDir.Combine("RequiresDynamicCodeAttribute.cs"); + yield return sharedDir.Combine("RequiresUnreferencedCodeAttribute.cs"); + } + public virtual IEnumerable GetCommonReferencedAssemblies(NPath workingDirectory) { yield return workingDirectory.Combine("Mono.Linker.Tests.Cases.Expectations.dll").ToString(); @@ -245,6 +259,11 @@ public virtual IEnumerable GetSetupCompileAssembliesAfter() .Select(CreateSetupCompileAssemblyInfo); } + public bool GetGenerateTargetFrameworkAttribute() + { + return GetOptionAttributeValue(nameof(GenerateTargetFrameworkAttribute), true); + } + private SetupCompileInfo CreateSetupCompileAssemblyInfo(CustomAttribute attribute) { var ctorArguments = attribute.ConstructorArguments; diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs index 53a1946af7495d..0cdbb6c6b44299 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs @@ -36,7 +36,7 @@ public TestCaseCompiler(TestCaseSandbox sandbox, TestCaseCompilationMetadataProv _metadataProvider = metadataProvider; } - public NPath CompileTestIn(NPath outputDirectory, string outputName, IEnumerable sourceFiles, string[] commonReferences, string[] mainAssemblyReferences, IEnumerable defines, NPath[] resources, string[] additionalArguments) + public NPath CompileTestIn(NPath outputDirectory, string outputName, IEnumerable sourceFiles, string[] commonReferences, string[] mainAssemblyReferences, IEnumerable defines, NPath[] resources, bool generateTargetFrameworkAttribute, string[] additionalArguments) { var originalCommonReferences = commonReferences.Select(r => r.ToNPath()).ToArray(); var originalDefines = defines?.ToArray() ?? Array.Empty(); @@ -44,7 +44,13 @@ public NPath CompileTestIn(NPath outputDirectory, string outputName, IEnumerable Prepare(outputDirectory); var removeFromLinkerInputAssemblies = new List(); - var compiledReferences = CompileBeforeTestCaseAssemblies(outputDirectory, originalCommonReferences, originalDefines, removeFromLinkerInputAssemblies).ToArray(); + var compiledReferences = CompileBeforeTestCaseAssemblies( + outputDirectory, + originalCommonReferences, + originalDefines, + removeFromLinkerInputAssemblies, + generateTargetFrameworkAttribute) + .ToArray(); var allTestCaseReferences = originalCommonReferences .Concat(compiledReferences) .Concat(mainAssemblyReferences.Select(r => r.ToNPath())) @@ -56,6 +62,7 @@ public NPath CompileTestIn(NPath outputDirectory, string outputName, IEnumerable allTestCaseReferences, originalDefines, resources, + generateTargetFrameworkAttribute, additionalArguments); var testAssembly = CompileAssembly(options); @@ -65,7 +72,12 @@ public NPath CompileTestIn(NPath outputDirectory, string outputName, IEnumerable // behavior of skipping the after test compile if (outputDirectory != _sandbox.ExpectationsDirectory) { - CompileAfterTestCaseAssemblies(outputDirectory, originalCommonReferences, originalDefines, removeFromLinkerInputAssemblies); + CompileAfterTestCaseAssemblies( + outputDirectory, + originalCommonReferences, + originalDefines, + removeFromLinkerInputAssemblies, + generateTargetFrameworkAttribute); foreach (var assemblyToRemove in removeFromLinkerInputAssemblies) assemblyToRemove.DeleteIfExists(); @@ -78,7 +90,7 @@ protected virtual void Prepare(NPath outputDirectory) { } - protected virtual CompilerOptions CreateOptionsForTestCase(NPath outputPath, NPath[] sourceFiles, NPath[] references, string[] defines, NPath[] resources, string[] additionalArguments) + protected virtual CompilerOptions CreateOptionsForTestCase(NPath outputPath, NPath[] sourceFiles, NPath[] references, string[] defines, NPath[] resources, bool generateTargetFrameworkAttribute, string[] additionalArguments) { return new CompilerOptions { @@ -88,11 +100,12 @@ protected virtual CompilerOptions CreateOptionsForTestCase(NPath outputPath, NPa Defines = defines.Concat(_metadataProvider.GetDefines()).ToArray(), Resources = resources, AdditionalArguments = additionalArguments, - CompilerToUse = _metadataProvider.GetCSharpCompilerToUse() + CompilerToUse = _metadataProvider.GetCSharpCompilerToUse(), + GenerateTargetFrameworkAttribute = generateTargetFrameworkAttribute }; } - protected virtual CompilerOptions CreateOptionsForSupportingAssembly(SetupCompileInfo setupCompileInfo, NPath outputDirectory, NPath[] sourceFiles, NPath[] references, string[] defines, NPath[] resources) + protected virtual CompilerOptions CreateOptionsForSupportingAssembly(SetupCompileInfo setupCompileInfo, NPath outputDirectory, NPath[] sourceFiles, NPath[] references, string[] defines, NPath[] resources, bool generateTargetFrameworkAttribute) { var allDefines = defines.Concat(setupCompileInfo.Defines ?? Array.Empty()).ToArray(); var allReferences = references.Concat(setupCompileInfo.References?.Select(p => MakeSupportingAssemblyReferencePathAbsolute(outputDirectory, p)) ?? Array.Empty()).ToArray(); @@ -105,11 +118,12 @@ protected virtual CompilerOptions CreateOptionsForSupportingAssembly(SetupCompil Defines = allDefines, Resources = resources, AdditionalArguments = additionalArguments, - CompilerToUse = setupCompileInfo.CompilerToUse?.ToLower() + CompilerToUse = setupCompileInfo.CompilerToUse?.ToLower(), + GenerateTargetFrameworkAttribute = generateTargetFrameworkAttribute }; } - private IEnumerable CompileBeforeTestCaseAssemblies(NPath outputDirectory, NPath[] references, string[] defines, List removeFromLinkerInputAssemblies) + private IEnumerable CompileBeforeTestCaseAssemblies(NPath outputDirectory, NPath[] references, string[] defines, List removeFromLinkerInputAssemblies, bool generateTargetFrameworkAttribute) { foreach (var setupCompileInfo in _metadataProvider.GetSetupCompileAssembliesBefore()) { @@ -130,7 +144,8 @@ private IEnumerable CompileBeforeTestCaseAssemblies(NPath outputDirectory CollectSetupBeforeSourcesFiles(setupCompileInfo), references, defines, - CollectSetupBeforeResourcesFiles(setupCompileInfo)); + CollectSetupBeforeResourcesFiles(setupCompileInfo), + generateTargetFrameworkAttribute); var output = CompileAssembly(options); if (setupCompileInfo.RemoveFromLinkerInput) @@ -141,7 +156,7 @@ private IEnumerable CompileBeforeTestCaseAssemblies(NPath outputDirectory } } - private void CompileAfterTestCaseAssemblies(NPath outputDirectory, NPath[] references, string[] defines, List removeFromLinkerInputAssemblies) + private void CompileAfterTestCaseAssemblies(NPath outputDirectory, NPath[] references, string[] defines, List removeFromLinkerInputAssemblies, bool generateTargetFrameworkAttribute) { foreach (var setupCompileInfo in _metadataProvider.GetSetupCompileAssembliesAfter()) { @@ -151,7 +166,8 @@ private void CompileAfterTestCaseAssemblies(NPath outputDirectory, NPath[] refer CollectSetupAfterSourcesFiles(setupCompileInfo), references, defines, - CollectSetupAfterResourcesFiles(setupCompileInfo)); + CollectSetupAfterResourcesFiles(setupCompileInfo), + generateTargetFrameworkAttribute); var output = CompileAssembly(options); if (setupCompileInfo.RemoveFromLinkerInput) @@ -179,15 +195,15 @@ private NPath[] CollectSetupAfterResourcesFiles(SetupCompileInfo info) return _sandbox.AfterReferenceResourceDirectoryFor(info.OutputName).Files().ToArray(); } - private static NPath[] CollectSourceFilesFrom(NPath directory) + private NPath[] CollectSourceFilesFrom(NPath directory) { - var sourceFiles = directory.Files("*.cs").ToArray(); - if (sourceFiles.Length > 0) - return sourceFiles; + var sourceFiles = directory.Files("*.cs"); + if (sourceFiles.Any()) + return sourceFiles.Concat(_metadataProvider.GetCommonSourceFiles()).ToArray(); - sourceFiles = directory.Files("*.il").ToArray(); - if (sourceFiles.Length > 0) - return sourceFiles; + sourceFiles = directory.Files("*.il"); + if (sourceFiles.Any()) + return sourceFiles.ToArray(); throw new FileNotFoundException($"Didn't find any sources files in {directory}"); } @@ -236,7 +252,7 @@ protected virtual NPath CompileCSharpAssemblyWithDefaultCompiler(CompilerOptions #if NET return CompileCSharpAssemblyWithRoslyn(options); #else - return CompileCSharpAssemblyWithCsc (options); + return CompileCSharpAssemblyWithCsc(options); #endif } @@ -298,9 +314,21 @@ protected virtual NPath CompileCSharpAssemblyWithRoslyn(CompilerOptions options) var syntaxTrees = options.SourceFiles.Select(p => CSharpSyntaxTree.ParseText( text: p.ReadAllText(), - options: parseOptions + options: parseOptions, + path: p.ToString(), + Encoding.UTF8 ) - ); + ).ToList(); + + if (options.GenerateTargetFrameworkAttribute) + { + syntaxTrees.Add(CSharpSyntaxTree.ParseText( + text: GenerateTargetFrameworkAttributeSource(), + options: parseOptions, + path: "AssemblyInfo.g.cs", + Encoding.UTF8 + )); + } var compilation = CSharpCompilation.Create( assemblyName: options.OutputPath.FileNameWithoutExtension, @@ -346,7 +374,7 @@ protected virtual NPath CompileCSharpAssemblyWithCsc(CompilerOptions options) #if NET return CompileCSharpAssemblyWithRoslyn(options); #else - return CompileCSharpAssemblyWithExternalCompiler (LocateCscExecutable (), options, "/shared "); + return CompileCSharpAssemblyWithExternalCompiler(LocateCscExecutable(), options, "/shared "); #endif } @@ -429,5 +457,14 @@ protected NPath CompileIlAssembly(CompilerOptions options) { return _ilCompiler.Compile(options); } + + private string GenerateTargetFrameworkAttributeSource() + { + var tfm = PathUtilities.TargetFrameworkMoniker; + var tfmDisplayName = PathUtilities.TargetFrameworkMonikerDisplayName; + return $""" + [assembly: System.Runtime.Versioning.TargetFramework("{tfm}", FrameworkDisplayName = "{tfmDisplayName}")] + """; + } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs index 5596a9a71c846d..fa425b330d3d08 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs @@ -71,8 +71,8 @@ public virtual void RootAssemblyVisible(string fileName) Append(fileName); Append("visible"); #else - Append ("-r"); - Append (fileName); + Append("-r"); + Append(fileName); #endif } @@ -225,8 +225,8 @@ public virtual void ProcessOptions(TestCaseLinkerOptions options) IgnoreLinkAttributes(options.IgnoreLinkAttributes); #if !NET - if (!string.IsNullOrEmpty (options.Il8n)) - AddIl8n (options.Il8n); + if (!string.IsNullOrEmpty options.Il8n)) + AddIl8n(options.Il8n); #endif if (!string.IsNullOrEmpty(options.LinkSymbols)) diff --git a/src/tools/illink/test/Mono.Linker.Tests/Tests/DocumentationSignatureParserTests.cs b/src/tools/illink/test/Mono.Linker.Tests/Tests/DocumentationSignatureParserTests.cs index 78c39b88c75e54..c126c9504b002c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/Tests/DocumentationSignatureParserTests.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/Tests/DocumentationSignatureParserTests.cs @@ -194,7 +194,7 @@ public static void M(List a) } [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32,)")] - //[ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32,)")] + //[ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.M(System.Int32,)")] // there's no way to reference this, since the parsing logic doesn't like it. public static void M(int abo, __arglist) { @@ -254,9 +254,9 @@ public int this[int i] public static implicit operator bool(A a) => false; // C# will not generate a return type for this method, but we will. - // [ExpectGeneratedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Implicit(Mono.Linker.Tests.DocumentationSignatureParserTests.A)~System.Boolean")] - // [ExpectExactlyResolvedDocumentationSignature ("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Implicit(Mono.Linker.Tests.DocumentationSignatureParserTests.A)~System.Boolean")] - //public static int op_Implicit (A a) => 0; + // [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Implicit(Mono.Linker.Tests.DocumentationSignatureParserTests.A)~System.Boolean")] + // [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_Implicit(Mono.Linker.Tests.DocumentationSignatureParserTests.A)~System.Boolean")] + //public static int op_Implicit(A a) => 0; [ExpectGeneratedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_UnaryPlus(Mono.Linker.Tests.DocumentationSignatureParserTests.A)")] [ExpectExactlyResolvedDocumentationSignature("M:Mono.Linker.Tests.DocumentationSignatureParserTests.A.op_UnaryPlus(Mono.Linker.Tests.DocumentationSignatureParserTests.A)")] diff --git a/src/tools/illink/test/Trimming.Tests.Shared/AssemblyChecker.cs b/src/tools/illink/test/Trimming.Tests.Shared/AssemblyChecker.cs index e14d6007524580..7f4ccb879b5559 100644 --- a/src/tools/illink/test/Trimming.Tests.Shared/AssemblyChecker.cs +++ b/src/tools/illink/test/Trimming.Tests.Shared/AssemblyChecker.cs @@ -2,33 +2,58 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using Mono.Cecil; +using Mono.Linker.Tests.Extensions; +using Mono.Linker.Tests.Cases.Expectations.Assertions; namespace Mono.Linker.Tests.TestCasesRunner { public partial class AssemblyChecker { - static bool IsCompilerGeneratedMemberName(string memberName) + static bool SkipKeptItemsValidation(IMemberDefinition member) { - return memberName.Length > 0 && memberName[0] == '<'; - } + // Skip verification of type metadata for compiler generated members (we don't currently need it yet) - static bool IsCompilerGeneratedMember(IMemberDefinition member) - { - // Top-level methods are generated with names like - // <
$>g__MethodName|0_1(). While the names are generated by - // the compiler, don't consider the method to be compiler-generated - // for the purpose of Kept validation, because they are attributable - // in source like any other method. - if (member is MethodDefinition method && method.Name.Contains("
$")) - return false; + // Compiler generated members can't be annotated with `Kept` attributes directly + // For some of them we have special attributes (backing fields for example), but it's impractical to define + // special attributes for all types of compiler generated members (there are quite a few of them and they're + // going to change/increase over time). + // So we're effectively disabling Kept validation on compiler generated members - if (IsCompilerGeneratedMemberName(member.Name)) + if (IsCompilerGeneratedMember(member)) return true; - if (member.DeclaringType != null) - return IsCompilerGeneratedMember(member.DeclaringType); + do + { + if (ResultChecker.HasActiveSkipKeptItemsValidationAttribute(member)) + return true; + } + while ((member = member.DeclaringType) != null); return false; + + static bool IsCompilerGeneratedMember(IMemberDefinition member) + { + // Top-level methods are generated with names like + // <
$>g__MethodName|0_1(). While the names are generated by + // the compiler, don't consider the method to be compiler-generated + // for the purpose of Kept validation, because they are attributable + // in source like any other method. + if (member is MethodDefinition method && method.Name.Contains("
$")) + return false; + + if (IsCompilerGeneratedMemberName(member.Name)) + return true; + + if (member.DeclaringType != null) + return IsCompilerGeneratedMember(member.DeclaringType); + + return false; + } + + static bool IsCompilerGeneratedMemberName(string memberName) + { + return memberName.Length > 0 && memberName[0] == '<'; + } } static bool IsDelegateBackingFieldsType(TypeDefinition type) => type.Name == "<>O"; diff --git a/src/tools/illink/test/Trimming.Tests.Shared/CompilerOptions.cs b/src/tools/illink/test/Trimming.Tests.Shared/CompilerOptions.cs index d5f0174771cdd2..96eddf4b46a346 100644 --- a/src/tools/illink/test/Trimming.Tests.Shared/CompilerOptions.cs +++ b/src/tools/illink/test/Trimming.Tests.Shared/CompilerOptions.cs @@ -16,5 +16,6 @@ public class CompilerOptions public NPath[] Resources; public string[] AdditionalArguments; public string CompilerToUse; + public bool GenerateTargetFrameworkAttribute; } } diff --git a/src/tools/illink/test/Trimming.Tests.Shared/PathUtilities.cs b/src/tools/illink/test/Trimming.Tests.Shared/PathUtilities.cs index 111e40a191b661..732b85599aef84 100644 --- a/src/tools/illink/test/Trimming.Tests.Shared/PathUtilities.cs +++ b/src/tools/illink/test/Trimming.Tests.Shared/PathUtilities.cs @@ -11,7 +11,11 @@ namespace Mono.Linker.Tests.TestCasesRunner { public static class PathUtilities { - public static string TFMDirectoryName => (string)AppContext.GetData("Mono.Linker.Tests.TargetFramework")!; + public static string TargetFramework => (string)AppContext.GetData("Mono.Linker.Tests.TargetFramework")!; + + public static string TargetFrameworkMoniker => (string)AppContext.GetData("Mono.Linker.Tests.TargetFrameworkMoniker")!; + + public static string TargetFrameworkMonikerDisplayName => (string)AppContext.GetData("Mono.Linker.Tests.TargetFrameworkMonikerDisplayName")!; public static string GetTestsSourceRootDirectory([CallerFilePath] string? thisFile = null) => Path.GetFullPath((string)AppContext.GetData("Mono.Linker.Tests.LinkerTestDir")!); @@ -21,7 +25,7 @@ public static string GetTestAssemblyRoot(string assemblyName) string artifactsBinDirectory = (string)AppContext.GetData("Mono.Linker.Tests.ArtifactsBinDir")!; string configuration = (string)AppContext.GetData("Mono.Linker.Tests.Configuration")!; - return Path.GetFullPath(Path.Combine(artifactsBinDirectory, assemblyName, configuration, TFMDirectoryName)); + return Path.GetFullPath(Path.Combine(artifactsBinDirectory, assemblyName, configuration, TargetFramework)); } } } diff --git a/src/tools/illink/test/Trimming.Tests.Shared/TestRunner.cs b/src/tools/illink/test/Trimming.Tests.Shared/TestRunner.cs index d59da9842793ce..6173d9fc125355 100644 --- a/src/tools/illink/test/Trimming.Tests.Shared/TestRunner.cs +++ b/src/tools/illink/test/Trimming.Tests.Shared/TestRunner.cs @@ -70,7 +70,9 @@ private ManagedCompilationResult Compile(TestCaseSandbox sandbox, TestCaseCompil { var inputCompiler = _factory.CreateCompiler(sandbox, metadataProvider); var expectationsCompiler = _factory.CreateCompiler(sandbox, metadataProvider); - var sourceFiles = sandbox.SourceFiles.Select(s => s.ToString()).ToArray(); + var testSourceFiles = sandbox.SourceFiles.Select(s => s.ToString()); + var commonSourceFiles = metadataProvider.GetCommonSourceFiles(); + var sourceFiles = testSourceFiles.Concat(commonSourceFiles.Select(s => s.ToString())).ToArray(); var assemblyName = metadataProvider.GetAssemblyName(); @@ -81,6 +83,7 @@ private ManagedCompilationResult Compile(TestCaseSandbox sandbox, TestCaseCompil var expectationsCommonReferences = metadataProvider.GetCommonReferencedAssemblies(sandbox.ExpectationsDirectory).ToArray(); var expectationsMainAssemblyReferences = metadataProvider.GetReferencedAssemblies(sandbox.ExpectationsDirectory).ToArray(); + var generateTargetFrameworkAttribute = metadataProvider.GetGenerateTargetFrameworkAttribute(); var additionalDefines = GetAdditionalDefines(); var inputTask = Task.Run(() => inputCompiler.CompileTestIn( @@ -91,6 +94,7 @@ private ManagedCompilationResult Compile(TestCaseSandbox sandbox, TestCaseCompil mainAssemblyReferences, additionalDefines?.ToArray(), resources, + generateTargetFrameworkAttribute, additionalArguments)); var expectationsDefines = new string[] { "INCLUDE_EXPECTATIONS" }; @@ -105,6 +109,7 @@ private ManagedCompilationResult Compile(TestCaseSandbox sandbox, TestCaseCompil expectationsMainAssemblyReferences, expectationsDefines, resources, + generateTargetFrameworkAttribute, additionalArguments)); NPath? inputAssemblyPath = null;